aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CREDITS10
-rw-r--r--Documentation/00-INDEX4
-rw-r--r--Documentation/ABI/testing/debugfs-kmemtrace71
-rw-r--r--Documentation/ABI/testing/debugfs-pktcdvd6
-rw-r--r--Documentation/ABI/testing/sysfs-class-regulator57
-rw-r--r--Documentation/DMA-mapping.txt18
-rw-r--r--Documentation/DocBook/Makefile11
-rw-r--r--Documentation/DocBook/kernel-api.tmpl2
-rw-r--r--Documentation/DocBook/writing-an-alsa-driver.tmpl8
-rw-r--r--Documentation/RCU/listRCU.txt6
-rw-r--r--Documentation/RCU/rcu.txt2
-rw-r--r--Documentation/RCU/rculist_nulls.txt4
-rw-r--r--Documentation/blockdev/00-INDEX2
-rw-r--r--Documentation/blockdev/mflash.txt84
-rw-r--r--Documentation/cgroups/00-INDEX18
-rw-r--r--Documentation/cgroups/cgroups.txt10
-rw-r--r--Documentation/cgroups/cpuacct.txt18
-rw-r--r--Documentation/cgroups/cpusets.txt12
-rw-r--r--Documentation/cgroups/devices.txt2
-rw-r--r--Documentation/cgroups/memcg_test.txt2
-rw-r--r--Documentation/cgroups/memory.txt55
-rw-r--r--Documentation/cgroups/resource_counter.txt27
-rw-r--r--Documentation/devices.txt127
-rw-r--r--Documentation/fb/uvesafb.txt7
-rw-r--r--Documentation/feature-removal-schedule.txt19
-rw-r--r--Documentation/filesystems/00-INDEX2
-rw-r--r--Documentation/filesystems/caching/backend-api.txt658
-rw-r--r--Documentation/filesystems/caching/cachefiles.txt501
-rw-r--r--Documentation/filesystems/caching/fscache.txt333
-rw-r--r--Documentation/filesystems/caching/netfs-api.txt778
-rw-r--r--Documentation/filesystems/caching/object.txt313
-rw-r--r--Documentation/filesystems/caching/operations.txt213
-rw-r--r--Documentation/filesystems/exofs.txt176
-rw-r--r--Documentation/filesystems/ext3.txt14
-rw-r--r--Documentation/filesystems/knfsd-stats.txt159
-rw-r--r--Documentation/filesystems/nfs41-server.txt161
-rw-r--r--Documentation/filesystems/nilfs2.txt200
-rw-r--r--Documentation/filesystems/pohmelfs/design_notes.txt70
-rw-r--r--Documentation/filesystems/pohmelfs/info.txt86
-rw-r--r--Documentation/filesystems/pohmelfs/network_protocol.txt227
-rw-r--r--Documentation/filesystems/udf.txt2
-rw-r--r--Documentation/hwmon/g760a36
-rw-r--r--Documentation/ia64/kvm.txt2
-rw-r--r--Documentation/infiniband/ipoib.txt45
-rw-r--r--Documentation/input/rotary-encoder.txt101
-rw-r--r--Documentation/isdn/README.gigaset52
-rw-r--r--Documentation/kbuild/makefiles.txt83
-rw-r--r--Documentation/kernel-parameters.txt516
-rw-r--r--Documentation/kprobes.txt38
-rw-r--r--Documentation/laptops/acer-wmi.txt10
-rw-r--r--Documentation/laptops/thinkpad-acpi.txt144
-rw-r--r--Documentation/md.txt37
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt2
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/upm-nand.txt39
-rw-r--r--Documentation/powerpc/dts-bindings/gpio/led.txt46
-rw-r--r--Documentation/scheduler/sched-rt-group.txt2
-rw-r--r--Documentation/scsi/aacraid.txt15
-rw-r--r--Documentation/slow-work.txt174
-rw-r--r--Documentation/sound/alsa/soc/jack.txt71
-rw-r--r--Documentation/sparse.txt8
-rw-r--r--Documentation/sysctl/net.txt2
-rw-r--r--Documentation/sysctl/vm.txt28
-rw-r--r--Documentation/sysrq.txt2
-rw-r--r--Documentation/tomoyo.txt55
-rw-r--r--Documentation/trace/ftrace.txt (renamed from Documentation/ftrace.txt)1134
-rw-r--r--Documentation/trace/kmemtrace.txt126
-rw-r--r--Documentation/trace/mmiotrace.txt (renamed from Documentation/tracers/mmiotrace.txt)0
-rw-r--r--Documentation/trace/tracepoints.txt (renamed from Documentation/tracepoints.txt)21
-rw-r--r--Documentation/video4linux/pxa_camera.txt125
-rw-r--r--Documentation/video4linux/v4l2-framework.txt21
-rw-r--r--Documentation/vm/00-INDEX2
-rw-r--r--Documentation/vm/active_mm.txt83
-rw-r--r--Documentation/vm/numa_memory_policy.txt3
-rw-r--r--Documentation/vm/page_migration3
-rw-r--r--Documentation/vm/unevictable-lru.txt1041
-rw-r--r--Documentation/x86/x86_64/fake-numa-for-cpusets5
-rw-r--r--MAINTAINERS1680
-rw-r--r--Makefile19
-rw-r--r--arch/Kconfig4
-rw-r--r--arch/alpha/include/asm/ftrace.h1
-rw-r--r--arch/alpha/include/asm/hardirq.h13
-rw-r--r--arch/arm/boot/compressed/misc.c5
-rw-r--r--arch/arm/configs/magician_defconfig6
-rw-r--r--arch/arm/configs/omap_ldp_defconfig24
-rw-r--r--arch/arm/configs/pcm037_defconfig23
-rw-r--r--arch/arm/configs/realview-smp_defconfig24
-rw-r--r--arch/arm/configs/realview_defconfig24
-rw-r--r--arch/arm/include/asm/sizes.h1
-rw-r--r--arch/arm/mach-at91/include/mach/board.h2
-rw-r--r--arch/arm/mach-at91/pm.c8
-rw-r--r--arch/arm/mach-davinci/board-evm.c4
-rw-r--r--arch/arm/mach-davinci/include/mach/nand.h80
-rw-r--r--arch/arm/mach-davinci/usb.c4
-rw-r--r--arch/arm/mach-gemini/include/mach/system.h2
-rw-r--r--arch/arm/mach-iop13xx/setup.c8
-rw-r--r--arch/arm/mach-iop13xx/tpmi.c10
-rw-r--r--arch/arm/mach-kirkwood/common.c10
-rw-r--r--arch/arm/mach-mmp/include/mach/system.h2
-rw-r--r--arch/arm/mach-mx1/Makefile3
-rw-r--r--arch/arm/mach-mx1/devices.c2
-rw-r--r--arch/arm/mach-mx1/ksym_mx1.c18
-rw-r--r--arch/arm/mach-mx1/mx1_camera_fiq.S35
-rw-r--r--arch/arm/mach-mx3/clock.c2
-rw-r--r--arch/arm/mach-mx3/pcm037.c23
-rw-r--r--arch/arm/mach-netx/include/mach/netx-regs.h2
-rw-r--r--arch/arm/mach-omap1/Kconfig2
-rw-r--r--arch/arm/mach-omap1/clock.c21
-rw-r--r--arch/arm/mach-omap2/Makefile2
-rw-r--r--arch/arm/mach-omap2/board-ldp.c47
-rw-r--r--arch/arm/mach-omap2/board-overo.c65
-rw-r--r--arch/arm/mach-omap2/usb-musb.c8
-rw-r--r--arch/arm/mach-orion5x/common.c6
-rw-r--r--arch/arm/mach-pxa/Kconfig9
-rw-r--r--arch/arm/mach-pxa/Makefile1
-rw-r--r--arch/arm/mach-pxa/cm-x2xx.c2
-rw-r--r--arch/arm/mach-pxa/colibri-pxa300.c11
-rw-r--r--arch/arm/mach-pxa/colibri-pxa320.c10
-rw-r--r--arch/arm/mach-pxa/colibri-pxa3xx.c35
-rw-r--r--arch/arm/mach-pxa/csb701.c5
-rw-r--r--arch/arm/mach-pxa/e740.c2
-rw-r--r--arch/arm/mach-pxa/e750.c2
-rw-r--r--arch/arm/mach-pxa/e800.c2
-rw-r--r--arch/arm/mach-pxa/em-x270.c86
-rw-r--r--arch/arm/mach-pxa/include/mach/colibri.h7
-rw-r--r--arch/arm/mach-pxa/include/mach/magician.h4
-rw-r--r--arch/arm/mach-pxa/include/mach/palmld.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/palmt5.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/palmte2.h68
-rw-r--r--arch/arm/mach-pxa/include/mach/palmtx.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa2xx_spi.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx_nand.h3
-rw-r--r--arch/arm/mach-pxa/magician.c85
-rw-r--r--arch/arm/mach-pxa/mioa701.c6
-rw-r--r--arch/arm/mach-pxa/palmld.c36
-rw-r--r--arch/arm/mach-pxa/palmt5.c35
-rw-r--r--arch/arm/mach-pxa/palmte2.c466
-rw-r--r--arch/arm/mach-pxa/palmtx.c35
-rw-r--r--arch/arm/mach-pxa/tosa.c2
-rw-r--r--arch/arm/mach-realview/core.c17
-rw-r--r--arch/arm/mach-realview/localtimer.c1
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c3
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c3
-rw-r--r--arch/arm/mach-s3c2412/mach-jive.c3
-rw-r--r--arch/arm/mm/abort-ev6.S4
-rw-r--r--arch/arm/mm/cache-feroceon-l2.c9
-rw-r--r--arch/arm/mm/mmu.c11
-rw-r--r--arch/arm/plat-iop/adma.c8
-rw-r--r--arch/arm/plat-mxc/include/mach/i2c.h25
-rw-r--r--arch/arm/plat-mxc/include/mach/memory.h8
-rw-r--r--arch/arm/plat-mxc/include/mach/mx1_camera.h35
-rw-r--r--arch/arm/plat-s3c/dev-i2c0.c7
-rw-r--r--arch/arm/plat-s3c/dev-i2c1.c7
-rw-r--r--arch/arm/plat-s3c/include/plat/iic.h33
-rw-r--r--arch/arm/vfp/entry.S23
-rw-r--r--arch/arm/vfp/vfphw.S12
-rw-r--r--arch/arm/vfp/vfpmodule.c6
-rw-r--r--arch/avr32/Kconfig20
-rw-r--r--arch/avr32/Makefile1
-rw-r--r--arch/avr32/boards/atngw100/evklcd10x.c50
-rw-r--r--arch/avr32/boards/atngw100/setup.c7
-rw-r--r--arch/avr32/boards/atstk1000/atstk1002.c6
-rw-r--r--arch/avr32/boards/atstk1000/atstk1003.c6
-rw-r--r--arch/avr32/boards/atstk1000/atstk1004.c6
-rw-r--r--arch/avr32/boards/favr-32/setup.c9
-rw-r--r--arch/avr32/boards/hammerhead/flash.c4
-rw-r--r--arch/avr32/boards/hammerhead/setup.c6
-rw-r--r--arch/avr32/boards/merisc/Kconfig5
-rw-r--r--arch/avr32/boards/merisc/Makefile1
-rw-r--r--arch/avr32/boards/merisc/display.c65
-rw-r--r--arch/avr32/boards/merisc/flash.c139
-rw-r--r--arch/avr32/boards/merisc/merisc.h18
-rw-r--r--arch/avr32/boards/merisc/merisc_sysfs.c65
-rw-r--r--arch/avr32/boards/merisc/setup.c297
-rw-r--r--arch/avr32/boards/mimc200/setup.c8
-rw-r--r--arch/avr32/configs/merisc_defconfig1237
-rw-r--r--arch/avr32/include/asm/ftrace.h1
-rw-r--r--arch/avr32/include/asm/hardirq.h11
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c120
-rw-r--r--arch/avr32/mach-at32ap/include/mach/at32ap700x.h52
-rw-r--r--arch/avr32/mach-at32ap/include/mach/board.h24
-rw-r--r--arch/blackfin/Kconfig6
-rw-r--r--arch/blackfin/include/asm/bfin5xx_spi.h5
-rw-r--r--arch/blackfin/include/asm/ftrace.h1
-rw-r--r--arch/blackfin/kernel/process.c2
-rw-r--r--arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h10
-rw-r--r--arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h36
-rw-r--r--arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h37
-rw-r--r--arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h10
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h117
-rw-r--r--arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/cris/Kconfig6
-rw-r--r--arch/cris/arch-v10/kernel/irq.c2
-rw-r--r--arch/cris/arch-v32/Kconfig2
-rw-r--r--arch/cris/arch-v32/boot/compressed/Makefile6
-rw-r--r--arch/cris/arch-v32/drivers/Kconfig2
-rw-r--r--arch/cris/arch-v32/kernel/irq.c2
-rw-r--r--arch/cris/arch-v32/kernel/smp.c10
-rw-r--r--arch/cris/arch-v32/mach-fs/Kconfig2
-rw-r--r--arch/cris/arch-v32/mm/tlb.c2
-rw-r--r--arch/cris/include/asm/ftrace.h1
-rw-r--r--arch/cris/include/asm/ioctls.h5
-rw-r--r--arch/cris/include/asm/rs485.h8
-rw-r--r--arch/cris/include/asm/termios.h1
-rw-r--r--arch/cris/kernel/setup.c2
-rw-r--r--arch/cris/mm/init.c3
-rw-r--r--arch/frv/include/asm/Kbuild (renamed from include/asm-frv/Kbuild)0
-rw-r--r--arch/frv/include/asm/atomic.h (renamed from include/asm-frv/atomic.h)0
-rw-r--r--arch/frv/include/asm/auxvec.h (renamed from include/asm-frv/auxvec.h)0
-rw-r--r--arch/frv/include/asm/ax88796.h (renamed from include/asm-frv/ax88796.h)0
-rw-r--r--arch/frv/include/asm/bitops.h (renamed from include/asm-frv/bitops.h)0
-rw-r--r--arch/frv/include/asm/bug.h (renamed from include/asm-frv/bug.h)0
-rw-r--r--arch/frv/include/asm/bugs.h (renamed from include/asm-frv/bugs.h)0
-rw-r--r--arch/frv/include/asm/busctl-regs.h (renamed from include/asm-frv/busctl-regs.h)0
-rw-r--r--arch/frv/include/asm/byteorder.h (renamed from include/asm-frv/byteorder.h)0
-rw-r--r--arch/frv/include/asm/cache.h (renamed from include/asm-frv/cache.h)0
-rw-r--r--arch/frv/include/asm/cacheflush.h (renamed from include/asm-frv/cacheflush.h)0
-rw-r--r--arch/frv/include/asm/checksum.h (renamed from include/asm-frv/checksum.h)0
-rw-r--r--arch/frv/include/asm/cpu-irqs.h (renamed from include/asm-frv/cpu-irqs.h)0
-rw-r--r--arch/frv/include/asm/cpumask.h (renamed from include/asm-frv/cpumask.h)0
-rw-r--r--arch/frv/include/asm/cputime.h (renamed from include/asm-frv/cputime.h)0
-rw-r--r--arch/frv/include/asm/current.h (renamed from include/asm-frv/current.h)0
-rw-r--r--arch/frv/include/asm/delay.h (renamed from include/asm-frv/delay.h)0
-rw-r--r--arch/frv/include/asm/device.h (renamed from include/asm-frv/device.h)0
-rw-r--r--arch/frv/include/asm/div64.h (renamed from include/asm-frv/div64.h)0
-rw-r--r--arch/frv/include/asm/dm9000.h (renamed from include/asm-frv/dm9000.h)0
-rw-r--r--arch/frv/include/asm/dma-mapping.h (renamed from include/asm-frv/dma-mapping.h)0
-rw-r--r--arch/frv/include/asm/dma.h (renamed from include/asm-frv/dma.h)0
-rw-r--r--arch/frv/include/asm/elf.h (renamed from include/asm-frv/elf.h)0
-rw-r--r--arch/frv/include/asm/emergency-restart.h (renamed from include/asm-frv/emergency-restart.h)0
-rw-r--r--arch/frv/include/asm/errno.h (renamed from include/asm-frv/errno.h)0
-rw-r--r--arch/frv/include/asm/fb.h (renamed from include/asm-frv/fb.h)0
-rw-r--r--arch/frv/include/asm/fcntl.h (renamed from include/asm-frv/fcntl.h)0
-rw-r--r--arch/frv/include/asm/fpu.h (renamed from include/asm-frv/fpu.h)0
-rw-r--r--arch/frv/include/asm/ftrace.h1
-rw-r--r--arch/frv/include/asm/futex.h (renamed from include/asm-frv/futex.h)0
-rw-r--r--arch/frv/include/asm/gdb-stub.h (renamed from include/asm-frv/gdb-stub.h)0
-rw-r--r--arch/frv/include/asm/gpio-regs.h (renamed from include/asm-frv/gpio-regs.h)0
-rw-r--r--arch/frv/include/asm/hardirq.h (renamed from include/asm-frv/hardirq.h)0
-rw-r--r--arch/frv/include/asm/highmem.h (renamed from include/asm-frv/highmem.h)0
-rw-r--r--arch/frv/include/asm/hw_irq.h (renamed from include/asm-frv/hw_irq.h)0
-rw-r--r--arch/frv/include/asm/init.h (renamed from include/asm-frv/init.h)0
-rw-r--r--arch/frv/include/asm/io.h (renamed from include/asm-frv/io.h)0
-rw-r--r--arch/frv/include/asm/ioctl.h (renamed from include/asm-frv/ioctl.h)0
-rw-r--r--arch/frv/include/asm/ioctls.h (renamed from include/asm-frv/ioctls.h)0
-rw-r--r--arch/frv/include/asm/ipcbuf.h (renamed from include/asm-frv/ipcbuf.h)0
-rw-r--r--arch/frv/include/asm/irc-regs.h (renamed from include/asm-frv/irc-regs.h)0
-rw-r--r--arch/frv/include/asm/irq.h (renamed from include/asm-frv/irq.h)0
-rw-r--r--arch/frv/include/asm/irq_regs.h (renamed from include/asm-frv/irq_regs.h)0
-rw-r--r--arch/frv/include/asm/kdebug.h (renamed from include/asm-frv/kdebug.h)0
-rw-r--r--arch/frv/include/asm/kmap_types.h (renamed from include/asm-frv/kmap_types.h)0
-rw-r--r--arch/frv/include/asm/linkage.h (renamed from include/asm-frv/linkage.h)0
-rw-r--r--arch/frv/include/asm/local.h (renamed from include/asm-frv/local.h)0
-rw-r--r--arch/frv/include/asm/math-emu.h (renamed from include/asm-frv/math-emu.h)0
-rw-r--r--arch/frv/include/asm/mb-regs.h (renamed from include/asm-frv/mb-regs.h)0
-rw-r--r--arch/frv/include/asm/mb86943a.h (renamed from include/asm-frv/mb86943a.h)0
-rw-r--r--arch/frv/include/asm/mb93091-fpga-irqs.h (renamed from include/asm-frv/mb93091-fpga-irqs.h)0
-rw-r--r--arch/frv/include/asm/mb93093-fpga-irqs.h (renamed from include/asm-frv/mb93093-fpga-irqs.h)0
-rw-r--r--arch/frv/include/asm/mb93493-irqs.h (renamed from include/asm-frv/mb93493-irqs.h)0
-rw-r--r--arch/frv/include/asm/mb93493-regs.h (renamed from include/asm-frv/mb93493-regs.h)0
-rw-r--r--arch/frv/include/asm/mc146818rtc.h (renamed from include/asm-frv/mc146818rtc.h)0
-rw-r--r--arch/frv/include/asm/mem-layout.h (renamed from include/asm-frv/mem-layout.h)0
-rw-r--r--arch/frv/include/asm/mman.h (renamed from include/asm-frv/mman.h)0
-rw-r--r--arch/frv/include/asm/mmu.h (renamed from include/asm-frv/mmu.h)0
-rw-r--r--arch/frv/include/asm/mmu_context.h (renamed from include/asm-frv/mmu_context.h)0
-rw-r--r--arch/frv/include/asm/module.h (renamed from include/asm-frv/module.h)0
-rw-r--r--arch/frv/include/asm/msgbuf.h (renamed from include/asm-frv/msgbuf.h)0
-rw-r--r--arch/frv/include/asm/mutex.h (renamed from include/asm-frv/mutex.h)0
-rw-r--r--arch/frv/include/asm/page.h (renamed from include/asm-frv/page.h)0
-rw-r--r--arch/frv/include/asm/param.h (renamed from include/asm-frv/param.h)0
-rw-r--r--arch/frv/include/asm/pci.h (renamed from include/asm-frv/pci.h)0
-rw-r--r--arch/frv/include/asm/percpu.h (renamed from include/asm-frv/percpu.h)0
-rw-r--r--arch/frv/include/asm/pgalloc.h (renamed from include/asm-frv/pgalloc.h)0
-rw-r--r--arch/frv/include/asm/pgtable.h (renamed from include/asm-frv/pgtable.h)6
-rw-r--r--arch/frv/include/asm/poll.h (renamed from include/asm-frv/poll.h)0
-rw-r--r--arch/frv/include/asm/posix_types.h (renamed from include/asm-frv/posix_types.h)0
-rw-r--r--arch/frv/include/asm/processor.h (renamed from include/asm-frv/processor.h)0
-rw-r--r--arch/frv/include/asm/ptrace.h (renamed from include/asm-frv/ptrace.h)0
-rw-r--r--arch/frv/include/asm/registers.h (renamed from include/asm-frv/registers.h)0
-rw-r--r--arch/frv/include/asm/resource.h (renamed from include/asm-frv/resource.h)0
-rw-r--r--arch/frv/include/asm/scatterlist.h (renamed from include/asm-frv/scatterlist.h)0
-rw-r--r--arch/frv/include/asm/sections.h (renamed from include/asm-frv/sections.h)0
-rw-r--r--arch/frv/include/asm/segment.h (renamed from include/asm-frv/segment.h)0
-rw-r--r--arch/frv/include/asm/sembuf.h (renamed from include/asm-frv/sembuf.h)0
-rw-r--r--arch/frv/include/asm/serial-regs.h (renamed from include/asm-frv/serial-regs.h)0
-rw-r--r--arch/frv/include/asm/serial.h (renamed from include/asm-frv/serial.h)0
-rw-r--r--arch/frv/include/asm/setup.h (renamed from include/asm-frv/setup.h)0
-rw-r--r--arch/frv/include/asm/shmbuf.h (renamed from include/asm-frv/shmbuf.h)0
-rw-r--r--arch/frv/include/asm/shmparam.h (renamed from include/asm-frv/shmparam.h)0
-rw-r--r--arch/frv/include/asm/sigcontext.h (renamed from include/asm-frv/sigcontext.h)0
-rw-r--r--arch/frv/include/asm/siginfo.h (renamed from include/asm-frv/siginfo.h)0
-rw-r--r--arch/frv/include/asm/signal.h (renamed from include/asm-frv/signal.h)0
-rw-r--r--arch/frv/include/asm/smp.h (renamed from include/asm-frv/smp.h)0
-rw-r--r--arch/frv/include/asm/socket.h (renamed from include/asm-frv/socket.h)0
-rw-r--r--arch/frv/include/asm/sockios.h (renamed from include/asm-frv/sockios.h)0
-rw-r--r--arch/frv/include/asm/spinlock.h (renamed from include/asm-frv/spinlock.h)0
-rw-r--r--arch/frv/include/asm/spr-regs.h (renamed from include/asm-frv/spr-regs.h)0
-rw-r--r--arch/frv/include/asm/stat.h (renamed from include/asm-frv/stat.h)0
-rw-r--r--arch/frv/include/asm/statfs.h (renamed from include/asm-frv/statfs.h)0
-rw-r--r--arch/frv/include/asm/string.h (renamed from include/asm-frv/string.h)0
-rw-r--r--arch/frv/include/asm/suspend.h (renamed from include/asm-frv/suspend.h)0
-rw-r--r--arch/frv/include/asm/swab.h (renamed from include/asm-frv/swab.h)0
-rw-r--r--arch/frv/include/asm/system.h (renamed from include/asm-frv/system.h)0
-rw-r--r--arch/frv/include/asm/termbits.h (renamed from include/asm-frv/termbits.h)0
-rw-r--r--arch/frv/include/asm/termios.h (renamed from include/asm-frv/termios.h)0
-rw-r--r--arch/frv/include/asm/thread_info.h (renamed from include/asm-frv/thread_info.h)6
-rw-r--r--arch/frv/include/asm/timer-regs.h (renamed from include/asm-frv/timer-regs.h)0
-rw-r--r--arch/frv/include/asm/timex.h (renamed from include/asm-frv/timex.h)0
-rw-r--r--arch/frv/include/asm/tlb.h (renamed from include/asm-frv/tlb.h)0
-rw-r--r--arch/frv/include/asm/tlbflush.h (renamed from include/asm-frv/tlbflush.h)0
-rw-r--r--arch/frv/include/asm/topology.h (renamed from include/asm-frv/topology.h)0
-rw-r--r--arch/frv/include/asm/types.h (renamed from include/asm-frv/types.h)0
-rw-r--r--arch/frv/include/asm/uaccess.h (renamed from include/asm-frv/uaccess.h)0
-rw-r--r--arch/frv/include/asm/ucontext.h (renamed from include/asm-frv/ucontext.h)0
-rw-r--r--arch/frv/include/asm/unaligned.h (renamed from include/asm-frv/unaligned.h)0
-rw-r--r--arch/frv/include/asm/unistd.h (renamed from include/asm-frv/unistd.h)0
-rw-r--r--arch/frv/include/asm/user.h (renamed from include/asm-frv/user.h)0
-rw-r--r--arch/frv/include/asm/vga.h (renamed from include/asm-frv/vga.h)0
-rw-r--r--arch/frv/include/asm/virtconvert.h (renamed from include/asm-frv/virtconvert.h)0
-rw-r--r--arch/frv/include/asm/xor.h (renamed from include/asm-frv/xor.h)0
-rw-r--r--arch/frv/mm/tlb-miss.S1
-rw-r--r--arch/h8300/include/asm/ftrace.h1
-rw-r--r--arch/h8300/kernel/timer/tpu.c2
-rw-r--r--arch/ia64/Kconfig3
-rw-r--r--arch/ia64/include/asm/ftrace.h28
-rw-r--r--arch/ia64/include/asm/hardirq.h10
-rw-r--r--arch/ia64/include/asm/unistd.h4
-rw-r--r--arch/ia64/kernel/Makefile5
-rw-r--r--arch/ia64/kernel/entry.S102
-rw-r--r--arch/ia64/kernel/ftrace.c206
-rw-r--r--arch/ia64/kernel/ia64_ksyms.c6
-rw-r--r--arch/ia64/kernel/pci-dma.c6
-rw-r--r--arch/ia64/kernel/pci-swiotlb.c2
-rw-r--r--arch/ia64/sn/pci/pci_dma.c2
-rw-r--r--arch/m68k/include/asm/bootinfo.h381
-rw-r--r--arch/m68k/include/asm/bootinfo_mm.h378
-rw-r--r--arch/m68k/include/asm/bootinfo_no.h2
-rw-r--r--arch/m68k/include/asm/bug.h31
-rw-r--r--arch/m68k/include/asm/bug_mm.h29
-rw-r--r--arch/m68k/include/asm/bug_no.h4
-rw-r--r--arch/m68k/include/asm/bugs.h21
-rw-r--r--arch/m68k/include/asm/bugs_mm.h14
-rw-r--r--arch/m68k/include/asm/bugs_no.h16
-rw-r--r--arch/m68k/include/asm/cache.h14
-rw-r--r--arch/m68k/include/asm/cache_mm.h11
-rw-r--r--arch/m68k/include/asm/cache_no.h12
-rw-r--r--arch/m68k/include/asm/current.h31
-rw-r--r--arch/m68k/include/asm/current_mm.h6
-rw-r--r--arch/m68k/include/asm/current_no.h24
-rw-r--r--arch/m68k/include/asm/div64.h37
-rw-r--r--arch/m68k/include/asm/div64_mm.h28
-rw-r--r--arch/m68k/include/asm/dma-mapping.h113
-rw-r--r--arch/m68k/include/asm/dma-mapping_mm.h112
-rw-r--r--arch/m68k/include/asm/dma-mapping_no.h6
-rw-r--r--arch/m68k/include/asm/elf.h120
-rw-r--r--arch/m68k/include/asm/elf_mm.h119
-rw-r--r--arch/m68k/include/asm/elf_no.h110
-rw-r--r--arch/m68k/include/asm/fb.h41
-rw-r--r--arch/m68k/include/asm/fb_mm.h34
-rw-r--r--arch/m68k/include/asm/fb_no.h12
-rw-r--r--arch/m68k/include/asm/fpu.h22
-rw-r--r--arch/m68k/include/asm/fpu_mm.h21
-rw-r--r--arch/m68k/include/asm/fpu_no.h21
-rw-r--r--arch/m68k/include/asm/ftrace.h1
-rw-r--r--arch/m68k/include/asm/hw_irq.h9
-rw-r--r--arch/m68k/include/asm/hw_irq_mm.h6
-rw-r--r--arch/m68k/include/asm/hw_irq_no.h4
-rw-r--r--arch/m68k/include/asm/kmap_types.h26
-rw-r--r--arch/m68k/include/asm/kmap_types_mm.h21
-rw-r--r--arch/m68k/include/asm/kmap_types_no.h21
-rw-r--r--arch/m68k/include/asm/m532xsim.h1
-rw-r--r--arch/m68k/include/asm/mc146818rtc.h31
-rw-r--r--arch/m68k/include/asm/mc146818rtc_mm.h26
-rw-r--r--arch/m68k/include/asm/mc146818rtc_no.h9
-rw-r--r--arch/m68k/include/asm/mcfpci.h119
-rw-r--r--arch/m68k/include/asm/mmu.h14
-rw-r--r--arch/m68k/include/asm/mmu_context.h176
-rw-r--r--arch/m68k/include/asm/mmu_context_mm.h154
-rw-r--r--arch/m68k/include/asm/mmu_context_no.h33
-rw-r--r--arch/m68k/include/asm/mmu_mm.h7
-rw-r--r--arch/m68k/include/asm/mmu_no.h10
-rw-r--r--arch/m68k/include/asm/module.h51
-rw-r--r--arch/m68k/include/asm/module_mm.h39
-rw-r--r--arch/m68k/include/asm/module_no.h11
-rw-r--r--arch/m68k/include/asm/page_offset.h12
-rw-r--r--arch/m68k/include/asm/page_offset_mm.h8
-rw-r--r--arch/m68k/include/asm/page_offset_no.h5
-rw-r--r--arch/m68k/include/asm/pci.h17
-rw-r--r--arch/m68k/include/asm/pci_mm.h12
-rw-r--r--arch/m68k/include/asm/pci_no.h29
-rw-r--r--arch/m68k/include/asm/pgalloc.h20
-rw-r--r--arch/m68k/include/asm/pgalloc_mm.h19
-rw-r--r--arch/m68k/include/asm/pgalloc_no.h8
-rw-r--r--arch/m68k/include/asm/pgtable_no.h2
-rw-r--r--arch/m68k/include/asm/rtc.h7
-rw-r--r--arch/m68k/include/asm/scatterlist.h26
-rw-r--r--arch/m68k/include/asm/scatterlist_mm.h23
-rw-r--r--arch/m68k/include/asm/scatterlist_no.h22
-rw-r--r--arch/m68k/include/asm/segment.h64
-rw-r--r--arch/m68k/include/asm/segment_mm.h57
-rw-r--r--arch/m68k/include/asm/segment_no.h51
-rw-r--r--arch/m68k/include/asm/timex.h21
-rw-r--r--arch/m68k/include/asm/timex_mm.h18
-rw-r--r--arch/m68k/include/asm/timex_no.h23
-rw-r--r--arch/m68k/include/asm/tlbflush.h268
-rw-r--r--arch/m68k/include/asm/tlbflush_mm.h219
-rw-r--r--arch/m68k/include/asm/tlbflush_no.h55
-rw-r--r--arch/m68k/include/asm/ucontext.h33
-rw-r--r--arch/m68k/include/asm/ucontext_mm.h30
-rw-r--r--arch/m68k/include/asm/ucontext_no.h32
-rw-r--r--arch/m68k/include/asm/unaligned.h26
-rw-r--r--arch/m68k/include/asm/unaligned_mm.h13
-rw-r--r--arch/m68k/include/asm/unaligned_no.h25
-rw-r--r--arch/m68k/kernel/time.c18
-rw-r--r--arch/m68knommu/Makefile14
-rw-r--r--arch/m68knommu/kernel/dma.c8
-rw-r--r--arch/m68knommu/kernel/irq.c2
-rw-r--r--arch/m68knommu/mm/init.c6
-rw-r--r--arch/m68knommu/platform/5249/config.c11
-rw-r--r--arch/m68knommu/platform/5307/config.c8
-rw-r--r--arch/m68knommu/platform/5407/config.c8
-rw-r--r--arch/m68knommu/platform/coldfire/Makefile2
-rw-r--r--arch/m68knommu/platform/coldfire/clk.c40
-rw-r--r--arch/microblaze/Kconfig141
-rw-r--r--arch/microblaze/Kconfig.debug26
-rw-r--r--arch/microblaze/Makefile69
-rw-r--r--arch/microblaze/boot/Makefile17
-rw-r--r--arch/microblaze/configs/nommu_defconfig804
-rw-r--r--arch/microblaze/include/asm/Kbuild26
-rw-r--r--arch/microblaze/include/asm/atomic.h123
-rw-r--r--arch/microblaze/include/asm/auxvec.h1
-rw-r--r--arch/microblaze/include/asm/bitops.h27
-rw-r--r--arch/microblaze/include/asm/bug.h15
-rw-r--r--arch/microblaze/include/asm/bugs.h17
-rw-r--r--arch/microblaze/include/asm/byteorder.h6
-rw-r--r--arch/microblaze/include/asm/cache.h45
-rw-r--r--arch/microblaze/include/asm/cacheflush.h85
-rw-r--r--arch/microblaze/include/asm/checksum.h98
-rw-r--r--arch/microblaze/include/asm/clinkage.h1
-rw-r--r--arch/microblaze/include/asm/cpuinfo.h102
-rw-r--r--arch/microblaze/include/asm/cputable.h1
-rw-r--r--arch/microblaze/include/asm/cputime.h (renamed from include/asm-mn10300/cputime.h)0
-rw-r--r--arch/microblaze/include/asm/current.h21
-rw-r--r--arch/microblaze/include/asm/delay.h72
-rw-r--r--arch/microblaze/include/asm/device.h21
-rw-r--r--arch/microblaze/include/asm/div64.h (renamed from arch/m68k/include/asm/div64_no.h)0
-rw-r--r--arch/microblaze/include/asm/dma-mapping.h129
-rw-r--r--arch/microblaze/include/asm/dma.h16
-rw-r--r--arch/microblaze/include/asm/elf.h30
-rw-r--r--arch/microblaze/include/asm/emergency-restart.h (renamed from include/asm-mn10300/emergency-restart.h)0
-rw-r--r--arch/microblaze/include/asm/entry.h35
-rw-r--r--arch/microblaze/include/asm/errno.h (renamed from include/asm-mn10300/errno.h)0
-rw-r--r--arch/microblaze/include/asm/exceptions.h96
-rw-r--r--arch/microblaze/include/asm/fcntl.h (renamed from include/asm-mn10300/fcntl.h)0
-rw-r--r--arch/microblaze/include/asm/flat.h90
-rw-r--r--arch/microblaze/include/asm/ftrace.h1
-rw-r--r--arch/microblaze/include/asm/futex.h (renamed from include/asm-mn10300/futex.h)0
-rw-r--r--arch/microblaze/include/asm/gpio.h56
-rw-r--r--arch/microblaze/include/asm/hardirq.h29
-rw-r--r--arch/microblaze/include/asm/hw_irq.h1
-rw-r--r--arch/microblaze/include/asm/io.h208
-rw-r--r--arch/microblaze/include/asm/ioctl.h (renamed from include/asm-mn10300/ioctl.h)0
-rw-r--r--arch/microblaze/include/asm/ioctls.h91
-rw-r--r--arch/microblaze/include/asm/ipc.h (renamed from include/asm-mn10300/ipc.h)0
-rw-r--r--arch/microblaze/include/asm/ipcbuf.h36
-rw-r--r--arch/microblaze/include/asm/irq.h47
-rw-r--r--arch/microblaze/include/asm/irq_regs.h1
-rw-r--r--arch/microblaze/include/asm/irqflags.h123
-rw-r--r--arch/microblaze/include/asm/kdebug.h1
-rw-r--r--arch/microblaze/include/asm/kmap_types.h29
-rw-r--r--arch/microblaze/include/asm/linkage.h15
-rw-r--r--arch/microblaze/include/asm/lmb.h17
-rw-r--r--arch/microblaze/include/asm/local.h (renamed from include/asm-mn10300/local.h)0
-rw-r--r--arch/microblaze/include/asm/mman.h25
-rw-r--r--arch/microblaze/include/asm/mmu.h19
-rw-r--r--arch/microblaze/include/asm/mmu_context.h21
-rw-r--r--arch/microblaze/include/asm/module.h37
-rw-r--r--arch/microblaze/include/asm/msgbuf.h31
-rw-r--r--arch/microblaze/include/asm/mutex.h1
-rw-r--r--arch/microblaze/include/asm/namei.h22
-rw-r--r--arch/microblaze/include/asm/of_device.h45
-rw-r--r--arch/microblaze/include/asm/of_platform.h64
-rw-r--r--arch/microblaze/include/asm/page.h140
-rw-r--r--arch/microblaze/include/asm/param.h30
-rw-r--r--arch/microblaze/include/asm/pci-bridge.h1
-rw-r--r--arch/microblaze/include/asm/pci.h1
-rw-r--r--arch/microblaze/include/asm/percpu.h (renamed from include/asm-mn10300/percpu.h)0
-rw-r--r--arch/microblaze/include/asm/pgalloc.h14
-rw-r--r--arch/microblaze/include/asm/pgtable.h54
-rw-r--r--arch/microblaze/include/asm/poll.h (renamed from include/asm-mn10300/poll.h)0
-rw-r--r--arch/microblaze/include/asm/posix_types.h73
-rw-r--r--arch/microblaze/include/asm/processor.h93
-rw-r--r--arch/microblaze/include/asm/prom.h313
-rw-r--r--arch/microblaze/include/asm/ptrace.h68
-rw-r--r--arch/microblaze/include/asm/pvr.h209
-rw-r--r--arch/microblaze/include/asm/registers.h33
-rw-r--r--arch/microblaze/include/asm/resource.h (renamed from include/asm-mn10300/resource.h)0
-rw-r--r--arch/microblaze/include/asm/scatterlist.h28
-rw-r--r--arch/microblaze/include/asm/sections.h25
-rw-r--r--arch/microblaze/include/asm/segment.h43
-rw-r--r--arch/microblaze/include/asm/selfmod.h24
-rw-r--r--arch/microblaze/include/asm/sembuf.h34
-rw-r--r--arch/microblaze/include/asm/serial.h14
-rw-r--r--arch/microblaze/include/asm/setup.h44
-rw-r--r--arch/microblaze/include/asm/shmbuf.h42
-rw-r--r--arch/microblaze/include/asm/shmparam.h6
-rw-r--r--arch/microblaze/include/asm/sigcontext.h20
-rw-r--r--arch/microblaze/include/asm/siginfo.h15
-rw-r--r--arch/microblaze/include/asm/signal.h165
-rw-r--r--arch/microblaze/include/asm/socket.h69
-rw-r--r--arch/microblaze/include/asm/sockios.h23
-rw-r--r--arch/microblaze/include/asm/stat.h73
-rw-r--r--arch/microblaze/include/asm/statfs.h (renamed from include/asm-mn10300/statfs.h)0
-rw-r--r--arch/microblaze/include/asm/string.h24
-rw-r--r--arch/microblaze/include/asm/swab.h8
-rw-r--r--arch/microblaze/include/asm/syscalls.h45
-rw-r--r--arch/microblaze/include/asm/system.h91
-rw-r--r--arch/microblaze/include/asm/termbits.h203
-rw-r--r--arch/microblaze/include/asm/termios.h88
-rw-r--r--arch/microblaze/include/asm/thread_info.h159
-rw-r--r--arch/microblaze/include/asm/timex.h18
-rw-r--r--arch/microblaze/include/asm/tlb.h16
-rw-r--r--arch/microblaze/include/asm/tlbflush.h20
-rw-r--r--arch/microblaze/include/asm/topology.h11
-rw-r--r--arch/microblaze/include/asm/types.h38
-rw-r--r--arch/microblaze/include/asm/uaccess.h134
-rw-r--r--arch/microblaze/include/asm/ucontext.h22
-rw-r--r--arch/microblaze/include/asm/unaligned.h22
-rw-r--r--arch/microblaze/include/asm/unistd.h421
-rw-r--r--arch/microblaze/include/asm/user.h1
-rw-r--r--arch/microblaze/include/asm/vga.h1
-rw-r--r--arch/microblaze/include/asm/xor.h (renamed from include/asm-mn10300/xor.h)0
-rw-r--r--arch/microblaze/kernel/Makefile19
-rw-r--r--arch/microblaze/kernel/asm-offsets.c115
-rw-r--r--arch/microblaze/kernel/cpu/Makefile8
-rw-r--r--arch/microblaze/kernel/cpu/cache.c258
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c101
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-static.c144
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo.c86
-rw-r--r--arch/microblaze/kernel/cpu/mb.c148
-rw-r--r--arch/microblaze/kernel/cpu/pvr.c81
-rw-r--r--arch/microblaze/kernel/early_printk.c107
-rw-r--r--arch/microblaze/kernel/entry-nommu.S596
-rw-r--r--arch/microblaze/kernel/exceptions.c124
-rw-r--r--arch/microblaze/kernel/head.S56
-rw-r--r--arch/microblaze/kernel/heartbeat.c67
-rw-r--r--arch/microblaze/kernel/hw_exception_handler.S458
-rw-r--r--arch/microblaze/kernel/init_task.c29
-rw-r--r--arch/microblaze/kernel/intc.c172
-rw-r--r--arch/microblaze/kernel/irq.c104
-rw-r--r--arch/microblaze/kernel/microblaze_ksyms.c47
-rw-r--r--arch/microblaze/kernel/module.c151
-rw-r--r--arch/microblaze/kernel/of_device.c113
-rw-r--r--arch/microblaze/kernel/of_platform.c201
-rw-r--r--arch/microblaze/kernel/process.c186
-rw-r--r--arch/microblaze/kernel/prom.c1146
-rw-r--r--arch/microblaze/kernel/prom_parse.c1025
-rw-r--r--arch/microblaze/kernel/ptrace.c181
-rw-r--r--arch/microblaze/kernel/selfmod.c81
-rw-r--r--arch/microblaze/kernel/setup.c199
-rw-r--r--arch/microblaze/kernel/signal.c537
-rw-r--r--arch/microblaze/kernel/sys_microblaze.c225
-rw-r--r--arch/microblaze/kernel/syscall_table.S365
-rw-r--r--arch/microblaze/kernel/timer.c262
-rw-r--r--arch/microblaze/kernel/traps.c107
-rw-r--r--arch/microblaze/kernel/vmlinux.lds.S163
-rw-r--r--arch/microblaze/lib/Makefile13
-rw-r--r--arch/microblaze/lib/checksum.c163
-rw-r--r--arch/microblaze/lib/fastcopy.S662
-rw-r--r--arch/microblaze/lib/memcpy.c161
-rw-r--r--arch/microblaze/lib/memmove.c175
-rw-r--r--arch/microblaze/lib/memset.c82
-rw-r--r--arch/microblaze/lib/uaccess.c41
-rw-r--r--arch/microblaze/mm/Makefile5
-rw-r--r--arch/microblaze/mm/init.c201
-rw-r--r--arch/microblaze/platform/Kconfig.platform85
-rw-r--r--arch/microblaze/platform/Makefile6
-rw-r--r--arch/microblaze/platform/generic/Kconfig.auto62
-rw-r--r--arch/microblaze/platform/generic/Makefile3
-rw-r--r--arch/microblaze/platform/generic/system.dts332
-rw-r--r--arch/microblaze/platform/platform.c31
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips/alchemy/common/platform.c30
-rw-r--r--arch/mips/alchemy/devboards/pb1200/platform.c4
-rw-r--r--arch/mips/include/asm/ftrace.h1
-rw-r--r--arch/mips/include/asm/mach-rc32434/gpio.h3
-rw-r--r--arch/mips/include/asm/txx9/ndfmc.h30
-rw-r--r--arch/mips/include/asm/txx9/rbtx4939.h9
-rw-r--r--arch/mips/include/asm/txx9/tx4938.h1
-rw-r--r--arch/mips/include/asm/txx9/tx4939.h2
-rw-r--r--arch/mips/nxp/pnx833x/common/platform.c12
-rw-r--r--arch/mips/nxp/pnx8550/common/platform.c8
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_usb.c8
-rw-r--r--arch/mips/rb532/devices.c19
-rw-r--r--arch/mips/sgi-ip27/ip27-smp.c2
-rw-r--r--arch/mips/txx9/generic/setup.c21
-rw-r--r--arch/mips/txx9/generic/setup_tx4938.c21
-rw-r--r--arch/mips/txx9/generic/setup_tx4939.c17
-rw-r--r--arch/mips/txx9/rbtx4938/setup.c2
-rw-r--r--arch/mips/txx9/rbtx4939/setup.c161
-rw-r--r--arch/mn10300/Kconfig2
-rw-r--r--arch/mn10300/Makefile40
-rw-r--r--arch/mn10300/include/asm/Kbuild (renamed from include/asm-mn10300/Kbuild)0
-rw-r--r--arch/mn10300/include/asm/atomic.h (renamed from include/asm-mn10300/atomic.h)0
-rw-r--r--arch/mn10300/include/asm/auxvec.h (renamed from include/asm-mn10300/auxvec.h)0
-rw-r--r--arch/mn10300/include/asm/bitops.h (renamed from include/asm-mn10300/bitops.h)0
-rw-r--r--arch/mn10300/include/asm/bug.h (renamed from include/asm-mn10300/bug.h)0
-rw-r--r--arch/mn10300/include/asm/bugs.h (renamed from include/asm-mn10300/bugs.h)0
-rw-r--r--arch/mn10300/include/asm/busctl-regs.h (renamed from include/asm-mn10300/busctl-regs.h)0
-rw-r--r--arch/mn10300/include/asm/byteorder.h (renamed from include/asm-mn10300/byteorder.h)0
-rw-r--r--arch/mn10300/include/asm/cache.h (renamed from include/asm-mn10300/cache.h)2
-rw-r--r--arch/mn10300/include/asm/cacheflush.h (renamed from include/asm-mn10300/cacheflush.h)0
-rw-r--r--arch/mn10300/include/asm/checksum.h (renamed from include/asm-mn10300/checksum.h)0
-rw-r--r--arch/mn10300/include/asm/cpu-regs.h (renamed from include/asm-mn10300/cpu-regs.h)0
-rw-r--r--arch/mn10300/include/asm/cputime.h1
-rw-r--r--arch/mn10300/include/asm/current.h (renamed from include/asm-mn10300/current.h)0
-rw-r--r--arch/mn10300/include/asm/delay.h (renamed from include/asm-mn10300/delay.h)0
-rw-r--r--arch/mn10300/include/asm/device.h (renamed from include/asm-mn10300/device.h)0
-rw-r--r--arch/mn10300/include/asm/div64.h (renamed from include/asm-mn10300/div64.h)0
-rw-r--r--arch/mn10300/include/asm/dma-mapping.h (renamed from include/asm-mn10300/dma-mapping.h)0
-rw-r--r--arch/mn10300/include/asm/dma.h (renamed from include/asm-mn10300/dma.h)0
-rw-r--r--arch/mn10300/include/asm/dmactl-regs.h (renamed from include/asm-mn10300/dmactl-regs.h)0
-rw-r--r--arch/mn10300/include/asm/elf.h (renamed from include/asm-mn10300/elf.h)0
-rw-r--r--arch/mn10300/include/asm/emergency-restart.h1
-rw-r--r--arch/mn10300/include/asm/errno.h1
-rw-r--r--arch/mn10300/include/asm/exceptions.h (renamed from include/asm-mn10300/exceptions.h)0
-rw-r--r--arch/mn10300/include/asm/fb.h (renamed from include/asm-mn10300/fb.h)0
-rw-r--r--arch/mn10300/include/asm/fcntl.h1
-rw-r--r--arch/mn10300/include/asm/fpu.h (renamed from include/asm-mn10300/fpu.h)0
-rw-r--r--arch/mn10300/include/asm/frame.inc (renamed from include/asm-mn10300/frame.inc)0
-rw-r--r--arch/mn10300/include/asm/ftrace.h1
-rw-r--r--arch/mn10300/include/asm/futex.h1
-rw-r--r--arch/mn10300/include/asm/gdb-stub.h (renamed from include/asm-mn10300/gdb-stub.h)0
-rw-r--r--arch/mn10300/include/asm/hardirq.h (renamed from include/asm-mn10300/hardirq.h)0
-rw-r--r--arch/mn10300/include/asm/highmem.h (renamed from include/asm-mn10300/highmem.h)0
-rw-r--r--arch/mn10300/include/asm/hw_irq.h (renamed from include/asm-mn10300/hw_irq.h)0
-rw-r--r--arch/mn10300/include/asm/intctl-regs.h (renamed from include/asm-mn10300/intctl-regs.h)0
-rw-r--r--arch/mn10300/include/asm/io.h (renamed from include/asm-mn10300/io.h)0
-rw-r--r--arch/mn10300/include/asm/ioctl.h1
-rw-r--r--arch/mn10300/include/asm/ioctls.h (renamed from include/asm-mn10300/ioctls.h)0
-rw-r--r--arch/mn10300/include/asm/ipc.h1
-rw-r--r--arch/mn10300/include/asm/ipcbuf.h (renamed from include/asm-mn10300/ipcbuf.h)0
-rw-r--r--arch/mn10300/include/asm/irq.h (renamed from include/asm-mn10300/irq.h)2
-rw-r--r--arch/mn10300/include/asm/irq_regs.h (renamed from include/asm-mn10300/irq_regs.h)0
-rw-r--r--arch/mn10300/include/asm/kdebug.h (renamed from include/asm-mn10300/kdebug.h)0
-rw-r--r--arch/mn10300/include/asm/kmap_types.h (renamed from include/asm-mn10300/kmap_types.h)0
-rw-r--r--arch/mn10300/include/asm/kprobes.h (renamed from include/asm-mn10300/kprobes.h)0
-rw-r--r--arch/mn10300/include/asm/linkage.h (renamed from include/asm-mn10300/linkage.h)0
-rw-r--r--arch/mn10300/include/asm/local.h1
-rw-r--r--arch/mn10300/include/asm/mc146818rtc.h (renamed from include/asm-mn10300/mc146818rtc.h)0
-rw-r--r--arch/mn10300/include/asm/mman.h (renamed from include/asm-mn10300/mman.h)0
-rw-r--r--arch/mn10300/include/asm/mmu.h (renamed from include/asm-mn10300/mmu.h)0
-rw-r--r--arch/mn10300/include/asm/mmu_context.h (renamed from include/asm-mn10300/mmu_context.h)0
-rw-r--r--arch/mn10300/include/asm/module.h (renamed from include/asm-mn10300/module.h)0
-rw-r--r--arch/mn10300/include/asm/msgbuf.h (renamed from include/asm-mn10300/msgbuf.h)0
-rw-r--r--arch/mn10300/include/asm/mutex.h (renamed from include/asm-mn10300/mutex.h)0
-rw-r--r--arch/mn10300/include/asm/nmi.h (renamed from include/asm-mn10300/nmi.h)0
-rw-r--r--arch/mn10300/include/asm/page.h (renamed from include/asm-mn10300/page.h)0
-rw-r--r--arch/mn10300/include/asm/page_offset.h (renamed from include/asm-mn10300/page_offset.h)0
-rw-r--r--arch/mn10300/include/asm/param.h (renamed from include/asm-mn10300/param.h)0
-rw-r--r--arch/mn10300/include/asm/pci.h (renamed from include/asm-mn10300/pci.h)0
-rw-r--r--arch/mn10300/include/asm/percpu.h1
-rw-r--r--arch/mn10300/include/asm/pgalloc.h (renamed from include/asm-mn10300/pgalloc.h)0
-rw-r--r--arch/mn10300/include/asm/pgtable.h (renamed from include/asm-mn10300/pgtable.h)0
-rw-r--r--arch/mn10300/include/asm/pio-regs.h (renamed from include/asm-mn10300/pio-regs.h)0
-rw-r--r--arch/mn10300/include/asm/poll.h1
-rw-r--r--arch/mn10300/include/asm/posix_types.h (renamed from include/asm-mn10300/posix_types.h)0
-rw-r--r--arch/mn10300/include/asm/processor.h (renamed from include/asm-mn10300/processor.h)0
-rw-r--r--arch/mn10300/include/asm/ptrace.h (renamed from include/asm-mn10300/ptrace.h)0
-rw-r--r--arch/mn10300/include/asm/reset-regs.h (renamed from include/asm-mn10300/reset-regs.h)0
-rw-r--r--arch/mn10300/include/asm/resource.h1
-rw-r--r--arch/mn10300/include/asm/rtc-regs.h (renamed from include/asm-mn10300/rtc-regs.h)0
-rw-r--r--arch/mn10300/include/asm/rtc.h (renamed from include/asm-mn10300/rtc.h)0
-rw-r--r--arch/mn10300/include/asm/scatterlist.h (renamed from include/asm-mn10300/scatterlist.h)0
-rw-r--r--arch/mn10300/include/asm/sections.h (renamed from include/asm-mn10300/sections.h)0
-rw-r--r--arch/mn10300/include/asm/sembuf.h (renamed from include/asm-mn10300/sembuf.h)0
-rw-r--r--arch/mn10300/include/asm/serial-regs.h (renamed from include/asm-mn10300/serial-regs.h)0
-rw-r--r--arch/mn10300/include/asm/serial.h (renamed from include/asm-mn10300/serial.h)2
-rw-r--r--arch/mn10300/include/asm/setup.h (renamed from include/asm-mn10300/setup.h)0
-rw-r--r--arch/mn10300/include/asm/shmbuf.h (renamed from include/asm-mn10300/shmbuf.h)0
-rw-r--r--arch/mn10300/include/asm/shmparam.h (renamed from include/asm-mn10300/shmparam.h)0
-rw-r--r--arch/mn10300/include/asm/sigcontext.h (renamed from include/asm-mn10300/sigcontext.h)0
-rw-r--r--arch/mn10300/include/asm/siginfo.h (renamed from include/asm-mn10300/siginfo.h)0
-rw-r--r--arch/mn10300/include/asm/signal.h (renamed from include/asm-mn10300/signal.h)0
-rw-r--r--arch/mn10300/include/asm/smp.h (renamed from include/asm-mn10300/smp.h)0
-rw-r--r--arch/mn10300/include/asm/socket.h (renamed from include/asm-mn10300/socket.h)0
-rw-r--r--arch/mn10300/include/asm/sockios.h (renamed from include/asm-mn10300/sockios.h)0
-rw-r--r--arch/mn10300/include/asm/spinlock.h (renamed from include/asm-mn10300/spinlock.h)0
-rw-r--r--arch/mn10300/include/asm/stat.h (renamed from include/asm-mn10300/stat.h)0
-rw-r--r--arch/mn10300/include/asm/statfs.h1
-rw-r--r--arch/mn10300/include/asm/string.h (renamed from include/asm-mn10300/string.h)0
-rw-r--r--arch/mn10300/include/asm/swab.h (renamed from include/asm-mn10300/swab.h)0
-rw-r--r--arch/mn10300/include/asm/system.h (renamed from include/asm-mn10300/system.h)0
-rw-r--r--arch/mn10300/include/asm/termbits.h (renamed from include/asm-mn10300/termbits.h)0
-rw-r--r--arch/mn10300/include/asm/termios.h (renamed from include/asm-mn10300/termios.h)0
-rw-r--r--arch/mn10300/include/asm/thread_info.h (renamed from include/asm-mn10300/thread_info.h)0
-rw-r--r--arch/mn10300/include/asm/timer-regs.h (renamed from include/asm-mn10300/timer-regs.h)0
-rw-r--r--arch/mn10300/include/asm/timex.h (renamed from include/asm-mn10300/timex.h)2
-rw-r--r--arch/mn10300/include/asm/tlb.h (renamed from include/asm-mn10300/tlb.h)0
-rw-r--r--arch/mn10300/include/asm/tlbflush.h (renamed from include/asm-mn10300/tlbflush.h)0
-rw-r--r--arch/mn10300/include/asm/topology.h (renamed from include/asm-mn10300/topology.h)0
-rw-r--r--arch/mn10300/include/asm/types.h (renamed from include/asm-mn10300/types.h)0
-rw-r--r--arch/mn10300/include/asm/uaccess.h (renamed from include/asm-mn10300/uaccess.h)0
-rw-r--r--arch/mn10300/include/asm/ucontext.h (renamed from include/asm-mn10300/ucontext.h)0
-rw-r--r--arch/mn10300/include/asm/unaligned.h (renamed from include/asm-mn10300/unaligned.h)0
-rw-r--r--arch/mn10300/include/asm/unistd.h (renamed from include/asm-mn10300/unistd.h)0
-rw-r--r--arch/mn10300/include/asm/user.h (renamed from include/asm-mn10300/user.h)0
-rw-r--r--arch/mn10300/include/asm/vga.h (renamed from include/asm-mn10300/vga.h)0
-rw-r--r--arch/mn10300/include/asm/xor.h1
-rw-r--r--arch/mn10300/kernel/entry.S2
-rw-r--r--arch/mn10300/kernel/gdb-io-serial-low.S2
-rw-r--r--arch/mn10300/kernel/gdb-io-serial.c2
-rw-r--r--arch/mn10300/kernel/gdb-io-ttysm-low.S2
-rw-r--r--arch/mn10300/kernel/gdb-io-ttysm.c2
-rw-r--r--arch/mn10300/kernel/gdb-stub.c4
-rw-r--r--arch/mn10300/kernel/head.S2
-rw-r--r--arch/mn10300/kernel/irq.c2
-rw-r--r--arch/mn10300/kernel/mn10300-serial-low.S4
-rw-r--r--arch/mn10300/kernel/mn10300-serial.c2
-rw-r--r--arch/mn10300/kernel/mn10300-watchdog.c2
-rw-r--r--arch/mn10300/kernel/setup.c2
-rw-r--r--arch/mn10300/kernel/traps.c2
-rw-r--r--arch/mn10300/oprofile/Kconfig23
-rw-r--r--arch/mn10300/proc-mn103e010/include/proc/cache.h (renamed from include/asm-mn10300/proc-mn103e010/cache.h)0
-rw-r--r--arch/mn10300/proc-mn103e010/include/proc/clock.h (renamed from include/asm-mn10300/proc-mn103e010/clock.h)2
-rw-r--r--arch/mn10300/proc-mn103e010/include/proc/irq.h (renamed from include/asm-mn10300/proc-mn103e010/irq.h)0
-rw-r--r--arch/mn10300/proc-mn103e010/include/proc/proc.h (renamed from include/asm-mn10300/proc-mn103e010/proc.h)0
-rw-r--r--arch/mn10300/unit-asb2303/include/unit/clock.h (renamed from include/asm-mn10300/unit-asb2303/clock.h)0
-rw-r--r--arch/mn10300/unit-asb2303/include/unit/leds.h (renamed from include/asm-mn10300/unit-asb2303/leds.h)0
-rw-r--r--arch/mn10300/unit-asb2303/include/unit/serial.h (renamed from include/asm-mn10300/unit-asb2303/serial.h)2
-rw-r--r--arch/mn10300/unit-asb2303/include/unit/smc91111.h (renamed from include/asm-mn10300/unit-asb2303/smc91111.h)0
-rw-r--r--arch/mn10300/unit-asb2303/include/unit/timex.h (renamed from include/asm-mn10300/unit-asb2303/timex.h)2
-rw-r--r--arch/mn10300/unit-asb2303/leds.c2
-rw-r--r--arch/mn10300/unit-asb2303/smc91111.c2
-rw-r--r--arch/mn10300/unit-asb2305/include/unit/clock.h (renamed from include/asm-mn10300/unit-asb2305/clock.h)0
-rw-r--r--arch/mn10300/unit-asb2305/include/unit/leds.h (renamed from include/asm-mn10300/unit-asb2305/leds.h)0
-rw-r--r--arch/mn10300/unit-asb2305/include/unit/serial.h (renamed from include/asm-mn10300/unit-asb2305/serial.h)2
-rw-r--r--arch/mn10300/unit-asb2305/include/unit/timex.h (renamed from include/asm-mn10300/unit-asb2305/timex.h)2
-rw-r--r--arch/mn10300/unit-asb2305/leds.c2
-rw-r--r--arch/mn10300/unit-asb2305/unit-init.c2
-rw-r--r--arch/parisc/Kconfig12
-rw-r--r--arch/parisc/Makefile4
-rw-r--r--arch/parisc/include/asm/atomic.h18
-rw-r--r--arch/parisc/include/asm/cacheflush.h3
-rw-r--r--arch/parisc/include/asm/elf.h10
-rw-r--r--arch/parisc/include/asm/ftrace.h25
-rw-r--r--arch/parisc/include/asm/page.h13
-rw-r--r--arch/parisc/include/asm/pdc.h4
-rw-r--r--arch/parisc/include/asm/pgtable.h15
-rw-r--r--arch/parisc/include/asm/smp.h3
-rw-r--r--arch/parisc/kernel/Makefile15
-rw-r--r--arch/parisc/kernel/entry.S60
-rw-r--r--arch/parisc/kernel/firmware.c6
-rw-r--r--arch/parisc/kernel/ftrace.c185
-rw-r--r--arch/parisc/kernel/irq.c4
-rw-r--r--arch/parisc/kernel/module.c18
-rw-r--r--arch/parisc/kernel/parisc_ksyms.c5
-rw-r--r--arch/parisc/kernel/process.c29
-rw-r--r--arch/parisc/kernel/processor.c13
-rw-r--r--arch/parisc/kernel/smp.c21
-rw-r--r--arch/parisc/kernel/stacktrace.c63
-rw-r--r--arch/parisc/kernel/syscall.S58
-rw-r--r--arch/parisc/kernel/time.c9
-rw-r--r--arch/parisc/kernel/traps.c5
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S2
-rw-r--r--arch/parisc/mm/init.c7
-rw-r--r--arch/powerpc/Kconfig5
-rw-r--r--arch/powerpc/boot/dts/ksi8560.dts4
-rw-r--r--arch/powerpc/boot/dts/pq2fads.dts20
-rw-r--r--arch/powerpc/boot/dts/sbc8548.dts4
-rw-r--r--arch/powerpc/boot/dts/sbc8560.dts4
-rw-r--r--arch/powerpc/boot/dts/socrates.dts9
-rw-r--r--arch/powerpc/boot/dts/stx_gp3_8560.dts4
-rw-r--r--arch/powerpc/boot/dts/tqm8540.dts4
-rw-r--r--arch/powerpc/boot/dts/tqm8541.dts4
-rw-r--r--arch/powerpc/boot/dts/tqm8548-bigflash.dts7
-rw-r--r--arch/powerpc/boot/dts/tqm8548.dts7
-rw-r--r--arch/powerpc/boot/dts/tqm8555.dts4
-rw-r--r--arch/powerpc/boot/dts/tqm8560.dts4
-rw-r--r--arch/powerpc/configs/pseries_defconfig2
-rw-r--r--arch/powerpc/include/asm/lppaca.h2
-rw-r--r--arch/powerpc/include/asm/mmzone.h1
-rw-r--r--arch/powerpc/include/asm/mpic.h12
-rw-r--r--arch/powerpc/include/asm/parport.h2
-rw-r--r--arch/powerpc/include/asm/ps3.h3
-rw-r--r--arch/powerpc/include/asm/ps3fb.h1
-rw-r--r--arch/powerpc/include/asm/pte-common.h6
-rw-r--r--arch/powerpc/include/asm/reg.h30
-rw-r--r--arch/powerpc/include/asm/reg_booke.h30
-rw-r--r--arch/powerpc/include/asm/rtas.h3
-rw-r--r--arch/powerpc/include/asm/sfp-machine.h6
-rw-r--r--arch/powerpc/include/asm/systbl.h3
-rw-r--r--arch/powerpc/include/asm/unistd.h4
-rw-r--r--arch/powerpc/kernel/dma.c2
-rw-r--r--arch/powerpc/kernel/fpu.S5
-rw-r--r--arch/powerpc/kernel/ftrace.c10
-rw-r--r--arch/powerpc/kernel/irq.c4
-rw-r--r--arch/powerpc/kernel/lparcfg.c16
-rw-r--r--arch/powerpc/kernel/misc_64.S8
-rw-r--r--arch/powerpc/kernel/of_platform.c2
-rw-r--r--arch/powerpc/kernel/prom_init.c18
-rw-r--r--arch/powerpc/kernel/ptrace32.c15
-rw-r--r--arch/powerpc/kernel/setup-common.c1
-rw-r--r--arch/powerpc/kernel/time.c16
-rw-r--r--arch/powerpc/platforms/Kconfig2
-rw-r--r--arch/powerpc/platforms/cell/iommu.c2
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c4
-rw-r--r--arch/powerpc/platforms/ps3/os-area.c2
-rw-r--r--arch/powerpc/platforms/ps3/platform.h2
-rw-r--r--arch/powerpc/platforms/ps3/setup.c2
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c2
-rw-r--r--arch/powerpc/platforms/ps3/time.c26
-rw-r--r--arch/powerpc/sysdev/bestcomm/Kconfig4
-rw-r--r--arch/powerpc/sysdev/fsl_lbc.c2
-rw-r--r--arch/powerpc/sysdev/mpic.c34
-rw-r--r--arch/s390/Kconfig1
-rw-r--r--arch/s390/include/asm/smp.h6
-rw-r--r--arch/sh/Kconfig28
-rw-r--r--arch/sh/boards/board-ap325rxa.c58
-rw-r--r--arch/sh/boards/board-urquell.c34
-rw-r--r--arch/sh/boards/mach-migor/setup.c4
-rw-r--r--arch/sh/configs/ap325rxa_defconfig70
-rw-r--r--arch/sh/configs/cayman_defconfig235
-rw-r--r--arch/sh/configs/dreamcast_defconfig71
-rw-r--r--arch/sh/configs/edosk7705_defconfig29
-rw-r--r--arch/sh/configs/edosk7760_defconfig78
-rw-r--r--arch/sh/configs/espt_defconfig39
-rw-r--r--arch/sh/configs/hp6xx_defconfig54
-rw-r--r--arch/sh/configs/landisk_defconfig97
-rw-r--r--arch/sh/configs/lboxre2_defconfig69
-rw-r--r--arch/sh/configs/magicpanelr2_defconfig73
-rw-r--r--arch/sh/configs/microdev_defconfig74
-rw-r--r--arch/sh/configs/migor_defconfig82
-rw-r--r--arch/sh/configs/polaris_defconfig31
-rw-r--r--arch/sh/configs/r7780mp_defconfig91
-rw-r--r--arch/sh/configs/r7785rp_defconfig96
-rw-r--r--arch/sh/configs/rsk7201_defconfig57
-rw-r--r--arch/sh/configs/rsk7203_defconfig94
-rw-r--r--arch/sh/configs/rts7751r2d1_defconfig83
-rw-r--r--arch/sh/configs/rts7751r2dplus_defconfig83
-rw-r--r--arch/sh/configs/sdk7780_defconfig78
-rw-r--r--arch/sh/configs/se7206_defconfig82
-rw-r--r--arch/sh/configs/se7343_defconfig89
-rw-r--r--arch/sh/configs/se7619_defconfig55
-rw-r--r--arch/sh/configs/se7705_defconfig75
-rw-r--r--arch/sh/configs/se7712_defconfig79
-rw-r--r--arch/sh/configs/se7721_defconfig82
-rw-r--r--arch/sh/configs/se7722_defconfig76
-rw-r--r--arch/sh/configs/se7750_defconfig71
-rw-r--r--arch/sh/configs/se7751_defconfig74
-rw-r--r--arch/sh/configs/se7780_defconfig78
-rw-r--r--arch/sh/configs/sh03_defconfig79
-rw-r--r--arch/sh/configs/sh7710voipgw_defconfig69
-rw-r--r--arch/sh/configs/sh7763rdp_defconfig82
-rw-r--r--arch/sh/configs/sh7785lcr_32bit_defconfig42
-rw-r--r--arch/sh/configs/sh7785lcr_defconfig90
-rw-r--r--arch/sh/configs/shmin_defconfig73
-rw-r--r--arch/sh/configs/shx3_defconfig99
-rw-r--r--arch/sh/configs/snapgear_defconfig62
-rw-r--r--arch/sh/configs/systemh_defconfig54
-rw-r--r--arch/sh/configs/titan_defconfig101
-rw-r--r--arch/sh/configs/ul2_defconfig93
-rw-r--r--arch/sh/configs/urquell_defconfig45
-rw-r--r--arch/sh/drivers/dma/Kconfig20
-rw-r--r--arch/sh/drivers/pci/ops-sh7785lcr.c14
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c16
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.h2
-rw-r--r--arch/sh/drivers/pci/pci.c3
-rw-r--r--arch/sh/include/asm/dma-mapping.h36
-rw-r--r--arch/sh/include/asm/mmu.h35
-rw-r--r--arch/sh/include/asm/processor_32.h13
-rw-r--r--arch/sh/include/asm/ptrace.h8
-rw-r--r--arch/sh/include/asm/scatterlist.h11
-rw-r--r--arch/sh/include/asm/system.h1
-rw-r--r--arch/sh/include/asm/system_32.h170
-rw-r--r--arch/sh/include/asm/topology.h7
-rw-r--r--arch/sh/include/asm/unistd_32.h4
-rw-r--r--arch/sh/include/asm/unistd_64.h4
-rw-r--r--arch/sh/include/cpu-sh4/cpu/sh7786.h214
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S85
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c5
-rw-r--r--arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c185
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7786.c14
-rw-r--r--arch/sh/kernel/idle.c2
-rw-r--r--arch/sh/kernel/io_trapped.c13
-rw-r--r--arch/sh/kernel/process_32.c14
-rw-r--r--arch/sh/kernel/ptrace_32.c6
-rw-r--r--arch/sh/kernel/setup.c5
-rw-r--r--arch/sh/kernel/syscalls_32.S2
-rw-r--r--arch/sh/kernel/syscalls_64.S2
-rw-r--r--arch/sh/kernel/traps_32.c2
-rw-r--r--arch/sh/mm/Kconfig12
-rw-r--r--arch/sh/mm/consistent.c31
-rw-r--r--arch/sparc/include/asm/mmzone.h2
-rw-r--r--arch/sparc/include/asm/parport.h5
-rw-r--r--arch/sparc/include/asm/unistd.h4
-rw-r--r--arch/sparc/kernel/head_64.S2
-rw-r--r--arch/sparc/kernel/of_device_64.c3
-rw-r--r--arch/sparc/kernel/pci_fire.c4
-rw-r--r--arch/sparc/kernel/pci_psycho.c8
-rw-r--r--arch/sparc/kernel/pci_sabre.c8
-rw-r--r--arch/sparc/kernel/pci_sun4v.c14
-rw-r--r--arch/sparc/kernel/power.c2
-rw-r--r--arch/sparc/kernel/systbls_32.S2
-rw-r--r--arch/sparc/kernel/systbls_64.S4
-rw-r--r--arch/sparc/mm/init_64.c8
-rw-r--r--arch/um/drivers/ubd_kern.c12
-rw-r--r--arch/um/include/asm/ftrace.h1
-rw-r--r--arch/x86/Kconfig16
-rw-r--r--arch/x86/boot/Makefile3
-rw-r--r--arch/x86/boot/compressed/Makefile1
-rw-r--r--arch/x86/boot/video-vga.c33
-rw-r--r--arch/x86/include/asm/apic.h3
-rw-r--r--arch/x86/include/asm/cacheflush.h5
-rw-r--r--[-rwxr-xr-x]arch/x86/include/asm/cpu_debug.h0
-rw-r--r--arch/x86/include/asm/cpufeature.h1
-rw-r--r--arch/x86/include/asm/cpumask.h18
-rw-r--r--arch/x86/include/asm/dma-mapping.h6
-rw-r--r--arch/x86/include/asm/fixmap.h6
-rw-r--r--arch/x86/include/asm/ftrace.h7
-rw-r--r--arch/x86/include/asm/io.h6
-rw-r--r--arch/x86/include/asm/io_apic.h11
-rw-r--r--arch/x86/include/asm/paravirt.h4
-rw-r--r--arch/x86/include/asm/pci.h41
-rw-r--r--arch/x86/include/asm/pci_32.h34
-rw-r--r--arch/x86/include/asm/pci_64.h22
-rw-r--r--arch/x86/include/asm/processor.h9
-rw-r--r--arch/x86/include/asm/ptrace-abi.h3
-rw-r--r--arch/x86/include/asm/required-features.h2
-rw-r--r--arch/x86/include/asm/sigcontext.h6
-rw-r--r--arch/x86/include/asm/smp.h13
-rw-r--r--arch/x86/include/asm/thread_info.h9
-rw-r--r--arch/x86/include/asm/topology.h87
-rw-r--r--arch/x86/include/asm/xen/page.h3
-rw-r--r--arch/x86/include/asm/xsave.h3
-rw-r--r--arch/x86/kernel/Makefile3
-rw-r--r--arch/x86/kernel/acpi/boot.c65
-rw-r--r--arch/x86/kernel/alternative.c29
-rw-r--r--arch/x86/kernel/amd_iommu.c7
-rw-r--r--arch/x86/kernel/apic/apic.c76
-rw-r--r--arch/x86/kernel/apic/apic_flat_64.c4
-rw-r--r--arch/x86/kernel/apic/bigsmp_32.c16
-rw-r--r--arch/x86/kernel/apic/es7000_32.c17
-rw-r--r--arch/x86/kernel/apic/io_apic.c143
-rw-r--r--arch/x86/kernel/apic/nmi.c11
-rw-r--r--arch/x86/kernel/apic/numaq_32.c11
-rw-r--r--arch/x86/kernel/apic/probe_32.c3
-rw-r--r--arch/x86/kernel/apic/summit_32.c21
-rw-r--r--arch/x86/kernel/apm_32.c248
-rw-r--r--arch/x86/kernel/cpu/addon_cpuid_features.c1
-rw-r--r--arch/x86/kernel/cpu/common.c13
-rw-r--r--[-rwxr-xr-x]arch/x86/kernel/cpu/cpu_debug.c0
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c93
-rw-r--r--arch/x86/kernel/cpu/cpufreq/longhaul.c7
-rw-r--r--arch/x86/kernel/cpu/cpufreq/p4-clockmod.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.c13
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-ich.c2
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c24
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_64.c10
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd_64.c6
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_intel_64.c2
-rw-r--r--arch/x86/kernel/cpu/mtrr/generic.c3
-rw-r--r--arch/x86/kernel/cpu/proc.c6
-rw-r--r--arch/x86/kernel/dumpstack.c6
-rw-r--r--arch/x86/kernel/ftrace.c195
-rw-r--r--arch/x86/kernel/irq.c2
-rw-r--r--arch/x86/kernel/kprobes.c17
-rw-r--r--arch/x86/kernel/microcode_amd.c43
-rw-r--r--arch/x86/kernel/microcode_core.c127
-rw-r--r--arch/x86/kernel/microcode_intel.c83
-rw-r--r--arch/x86/kernel/mpparse.c7
-rw-r--r--arch/x86/kernel/pci-dma.c8
-rw-r--r--arch/x86/kernel/pci-nommu.c2
-rw-r--r--arch/x86/kernel/process.c25
-rw-r--r--arch/x86/kernel/ptrace.c8
-rw-r--r--arch/x86/kernel/reboot.c8
-rw-r--r--arch/x86/kernel/setup_percpu.c16
-rw-r--r--arch/x86/kernel/signal.c2
-rw-r--r--arch/x86/kernel/smpboot.c70
-rw-r--r--arch/x86/kernel/tlb_uv.c9
-rw-r--r--arch/x86/kernel/xsave.c2
-rw-r--r--arch/x86/kvm/Kconfig3
-rw-r--r--arch/x86/mm/Makefile2
-rw-r--r--arch/x86/mm/gup.c16
-rw-r--r--arch/x86/mm/highmem_32.c1
-rw-r--r--arch/x86/mm/init_32.c35
-rw-r--r--arch/x86/mm/init_64.c37
-rw-r--r--arch/x86/mm/iomap_32.c4
-rw-r--r--arch/x86/mm/ioremap.c23
-rw-r--r--arch/x86/mm/mmio-mod.c19
-rw-r--r--arch/x86/mm/numa.c67
-rw-r--r--arch/x86/mm/numa_64.c111
-rw-r--r--arch/x86/mm/pat.c2
-rw-r--r--arch/x86/mm/pgtable.c3
-rw-r--r--arch/x86/mm/srat_64.c30
-rw-r--r--arch/x86/oprofile/op_model_p4.c2
-rw-r--r--arch/x86/pci/i386.c46
-rw-r--r--arch/x86/power/Makefile5
-rw-r--r--arch/x86/xen/enlighten.c89
-rw-r--r--arch/x86/xen/mmu.c118
-rw-r--r--arch/x86/xen/mmu.h3
-rw-r--r--arch/x86/xen/smp.c10
-rw-r--r--arch/x86/xen/xen-ops.h2
-rw-r--r--arch/xtensa/Kconfig184
-rw-r--r--arch/xtensa/Makefile15
-rw-r--r--arch/xtensa/configs/s6105_defconfig530
-rw-r--r--arch/xtensa/include/asm/cacheflush.h10
-rw-r--r--arch/xtensa/include/asm/dma.h3
-rw-r--r--arch/xtensa/include/asm/flat.h12
-rw-r--r--arch/xtensa/include/asm/ftrace.h1
-rw-r--r--arch/xtensa/include/asm/gpio.h56
-rw-r--r--arch/xtensa/include/asm/io.h9
-rw-r--r--arch/xtensa/include/asm/irq.h7
-rw-r--r--arch/xtensa/include/asm/mmu.h5
-rw-r--r--arch/xtensa/include/asm/mmu_context.h9
-rw-r--r--arch/xtensa/include/asm/nommu.h3
-rw-r--r--arch/xtensa/include/asm/nommu_context.h25
-rw-r--r--arch/xtensa/include/asm/page.h14
-rw-r--r--arch/xtensa/include/asm/pgtable.h13
-rw-r--r--arch/xtensa/include/asm/platform.h11
-rw-r--r--arch/xtensa/include/asm/processor.h8
-rw-r--r--arch/xtensa/kernel/entry.S3
-rw-r--r--arch/xtensa/kernel/head.S5
-rw-r--r--arch/xtensa/kernel/irq.c14
-rw-r--r--arch/xtensa/kernel/platform.c2
-rw-r--r--arch/xtensa/kernel/setup.c7
-rw-r--r--arch/xtensa/kernel/time.c131
-rw-r--r--arch/xtensa/kernel/traps.c16
-rw-r--r--arch/xtensa/kernel/vectors.S4
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S3
-rw-r--r--arch/xtensa/mm/Makefile3
-rw-r--r--arch/xtensa/mm/init.c78
-rw-r--r--arch/xtensa/mm/misc.S2
-rw-r--r--arch/xtensa/mm/mmu.c70
-rw-r--r--arch/xtensa/platforms/s6105/Makefile3
-rw-r--r--arch/xtensa/platforms/s6105/device.c67
-rw-r--r--arch/xtensa/platforms/s6105/include/platform/gpio.h27
-rw-r--r--arch/xtensa/platforms/s6105/include/platform/hardware.h11
-rw-r--r--arch/xtensa/platforms/s6105/include/platform/serial.h8
-rw-r--r--arch/xtensa/platforms/s6105/setup.c61
-rw-r--r--arch/xtensa/platforms/xt2000/include/platform/hardware.h1
-rw-r--r--arch/xtensa/variants/s6000/Makefile3
-rw-r--r--arch/xtensa/variants/s6000/gpio.c71
-rw-r--r--arch/xtensa/variants/s6000/include/variant/core.h431
-rw-r--r--arch/xtensa/variants/s6000/include/variant/hardware.h259
-rw-r--r--arch/xtensa/variants/s6000/include/variant/irq.h9
-rw-r--r--arch/xtensa/variants/s6000/include/variant/tie-asm.h304
-rw-r--r--arch/xtensa/variants/s6000/include/variant/tie.h191
-rw-r--r--arch/xtensa/variants/s6000/irq.c74
-rw-r--r--block/Kconfig16
-rw-r--r--block/Makefile1
-rw-r--r--block/blk-core.c101
-rw-r--r--block/blk-merge.c29
-rw-r--r--block/blk-settings.c2
-rw-r--r--block/blk-softirq.c2
-rw-r--r--block/blk-sysfs.c44
-rw-r--r--block/blk.h16
-rw-r--r--block/cfq-iosched.c206
-rw-r--r--block/elevator.c44
-rw-r--r--crypto/async_tx/async_tx.c6
-rw-r--r--crypto/async_tx/async_xor.c7
-rw-r--r--crypto/shash.c3
-rw-r--r--crypto/xor.c2
-rw-r--r--drivers/acpi/Kconfig150
-rw-r--r--drivers/acpi/Makefile52
-rw-r--r--drivers/acpi/acpica/Makefile4
-rw-r--r--drivers/acpi/acpica/acglobal.h11
-rw-r--r--drivers/acpi/acpica/achware.h12
-rw-r--r--drivers/acpi/acpica/aclocal.h60
-rw-r--r--drivers/acpi/acpica/acmacros.h4
-rw-r--r--drivers/acpi/acpica/acobject.h1
-rw-r--r--drivers/acpi/acpica/acpredef.h41
-rw-r--r--drivers/acpi/acpica/actables.h9
-rw-r--r--drivers/acpi/acpica/acutils.h15
-rw-r--r--drivers/acpi/acpica/dsinit.c16
-rw-r--r--drivers/acpi/acpica/dsmthdat.c2
-rw-r--r--drivers/acpi/acpica/dsobject.c6
-rw-r--r--drivers/acpi/acpica/dsopcode.c32
-rw-r--r--drivers/acpi/acpica/dsutils.c2
-rw-r--r--drivers/acpi/acpica/dswexec.c5
-rw-r--r--drivers/acpi/acpica/evevent.c18
-rw-r--r--drivers/acpi/acpica/evgpe.c7
-rw-r--r--drivers/acpi/acpica/evgpeblk.c70
-rw-r--r--drivers/acpi/acpica/evmisc.c16
-rw-r--r--drivers/acpi/acpica/evregion.c5
-rw-r--r--drivers/acpi/acpica/evrgnini.c22
-rw-r--r--drivers/acpi/acpica/evxface.c3
-rw-r--r--drivers/acpi/acpica/evxfevnt.c24
-rw-r--r--drivers/acpi/acpica/evxfregn.c3
-rw-r--r--drivers/acpi/acpica/exconfig.c17
-rw-r--r--drivers/acpi/acpica/exconvrt.c11
-rw-r--r--drivers/acpi/acpica/exdump.c59
-rw-r--r--drivers/acpi/acpica/exfield.c29
-rw-r--r--drivers/acpi/acpica/exfldio.c14
-rw-r--r--drivers/acpi/acpica/exmisc.c14
-rw-r--r--drivers/acpi/acpica/exoparg1.c13
-rw-r--r--drivers/acpi/acpica/exoparg2.c2
-rw-r--r--drivers/acpi/acpica/exoparg3.c7
-rw-r--r--drivers/acpi/acpica/exprep.c2
-rw-r--r--drivers/acpi/acpica/exregion.c4
-rw-r--r--drivers/acpi/acpica/exresnte.c8
-rw-r--r--drivers/acpi/acpica/exresolv.c9
-rw-r--r--drivers/acpi/acpica/exresop.c23
-rw-r--r--drivers/acpi/acpica/exstore.c18
-rw-r--r--drivers/acpi/acpica/exstoren.c29
-rw-r--r--drivers/acpi/acpica/exutils.c2
-rw-r--r--drivers/acpi/acpica/hwacpi.c9
-rw-r--r--drivers/acpi/acpica/hwgpe.c21
-rw-r--r--drivers/acpi/acpica/hwregs.c322
-rw-r--r--drivers/acpi/acpica/hwsleep.c130
-rw-r--r--drivers/acpi/acpica/hwvalid.c257
-rw-r--r--drivers/acpi/acpica/hwxface.c279
-rw-r--r--drivers/acpi/acpica/nsaccess.c54
-rw-r--r--drivers/acpi/acpica/nsalloc.c24
-rw-r--r--drivers/acpi/acpica/nsdump.c24
-rw-r--r--drivers/acpi/acpica/nseval.c2
-rw-r--r--drivers/acpi/acpica/nsinit.c19
-rw-r--r--drivers/acpi/acpica/nsload.c4
-rw-r--r--drivers/acpi/acpica/nsobject.c18
-rw-r--r--drivers/acpi/acpica/nsparse.c10
-rw-r--r--drivers/acpi/acpica/nspredef.c38
-rw-r--r--drivers/acpi/acpica/nssearch.c14
-rw-r--r--drivers/acpi/acpica/nsutils.c27
-rw-r--r--drivers/acpi/acpica/nswalk.c12
-rw-r--r--drivers/acpi/acpica/nsxfeval.c39
-rw-r--r--drivers/acpi/acpica/rscalc.c7
-rw-r--r--drivers/acpi/acpica/rscreate.c15
-rw-r--r--drivers/acpi/acpica/tbfadt.c363
-rw-r--r--drivers/acpi/acpica/tbinstal.c82
-rw-r--r--drivers/acpi/acpica/tbutils.c106
-rw-r--r--drivers/acpi/acpica/tbxface.c71
-rw-r--r--drivers/acpi/acpica/tbxfroot.c4
-rw-r--r--drivers/acpi/acpica/utcopy.c30
-rw-r--r--drivers/acpi/acpica/utdelete.c6
-rw-r--r--drivers/acpi/acpica/uteval.c98
-rw-r--r--drivers/acpi/acpica/utglobal.c17
-rw-r--r--drivers/acpi/acpica/utlock.c175
-rw-r--r--drivers/acpi/acpica/utmisc.c3
-rw-r--r--drivers/acpi/acpica/utmutex.c23
-rw-r--r--drivers/acpi/acpica/utobject.c11
-rw-r--r--drivers/acpi/battery.c29
-rw-r--r--drivers/acpi/bus.c15
-rw-r--r--drivers/acpi/button.c77
-rw-r--r--drivers/acpi/debug.c19
-rw-r--r--drivers/acpi/dock.c3
-rw-r--r--drivers/acpi/ec.c39
-rw-r--r--drivers/acpi/fan.c20
-rw-r--r--drivers/acpi/glue.c6
-rw-r--r--drivers/acpi/internal.h43
-rw-r--r--drivers/acpi/numa.c46
-rw-r--r--drivers/acpi/osl.c6
-rw-r--r--drivers/acpi/pci_irq.c18
-rw-r--r--drivers/acpi/pci_link.c147
-rw-r--r--drivers/acpi/pci_slot.c5
-rw-r--r--drivers/acpi/power.c12
-rw-r--r--drivers/acpi/proc.c20
-rw-r--r--drivers/acpi/processor_core.c45
-rw-r--r--drivers/acpi/processor_idle.c127
-rw-r--r--drivers/acpi/processor_perflib.c46
-rw-r--r--drivers/acpi/processor_thermal.c22
-rw-r--r--drivers/acpi/processor_throttling.c8
-rw-r--r--drivers/acpi/sbs.c41
-rw-r--r--drivers/acpi/scan.c125
-rw-r--r--drivers/acpi/sleep.c13
-rw-r--r--drivers/acpi/sleep.h3
-rw-r--r--drivers/acpi/system.c64
-rw-r--r--drivers/acpi/tables.c30
-rw-r--r--drivers/acpi/thermal.c599
-rw-r--r--drivers/acpi/video.c366
-rw-r--r--drivers/acpi/video_detect.c3
-rw-r--r--drivers/acpi/wakeup.c39
-rw-r--r--drivers/ata/Kconfig2
-rw-r--r--drivers/ata/ahci.c84
-rw-r--r--drivers/ata/ata_piix.c7
-rw-r--r--drivers/ata/libata-core.c4
-rw-r--r--drivers/ata/pata_cs5520.c4
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c2
-rw-r--r--drivers/ata/pata_octeon_cf.c6
-rw-r--r--drivers/ata/pdc_adma.c4
-rw-r--r--drivers/ata/sata_inic162x.c4
-rw-r--r--drivers/ata/sata_mv.c497
-rw-r--r--drivers/ata/sata_qstor.c10
-rw-r--r--drivers/ata/sata_sil24.c10
-rw-r--r--drivers/ata/sata_via.c2
-rw-r--r--drivers/ata/sata_vsc.c4
-rw-r--r--drivers/atm/he.c2
-rw-r--r--drivers/atm/lanai.c4
-rw-r--r--drivers/atm/solos-pci.c2
-rw-r--r--drivers/base/iommu.c7
-rw-r--r--drivers/base/isa.c2
-rw-r--r--drivers/base/node.c2
-rw-r--r--drivers/base/sys.c2
-rw-r--r--drivers/block/DAC960.c12
-rw-r--r--drivers/block/Kconfig17
-rw-r--r--drivers/block/Makefile1
-rw-r--r--drivers/block/aoe/aoecmd.c23
-rw-r--r--drivers/block/cciss.c123
-rw-r--r--drivers/block/cciss.h2
-rw-r--r--drivers/block/cciss_cmd.h23
-rw-r--r--drivers/block/hd.c2
-rw-r--r--drivers/block/loop.c7
-rw-r--r--drivers/block/mg_disk.c1005
-rw-r--r--drivers/block/sx8.c6
-rw-r--r--drivers/block/umem.c4
-rw-r--r--drivers/block/xsysace.c34
-rw-r--r--drivers/char/agp/intel-agp.c3
-rw-r--r--drivers/char/applicom.c1
-rw-r--r--drivers/char/bsr.c2
-rw-r--r--drivers/char/cyclades.c2
-rw-r--r--drivers/char/esp.c2
-rw-r--r--drivers/char/hw_random/timeriomem-rng.c39
-rw-r--r--drivers/char/isicom.c1
-rw-r--r--drivers/char/moxa.c9
-rw-r--r--drivers/char/mxser.c1
-rw-r--r--drivers/char/rio/rio_linux.c2
-rw-r--r--drivers/char/riscom8.c2
-rw-r--r--drivers/char/specialix.c1
-rw-r--r--drivers/char/sysrq.c3
-rw-r--r--drivers/clocksource/sh_cmt.c3
-rw-r--r--drivers/crypto/hifn_795x.c2
-rw-r--r--drivers/crypto/ixp4xx_crypto.c184
-rw-r--r--drivers/dma/Kconfig11
-rw-r--r--drivers/dma/dmaengine.c60
-rw-r--r--drivers/dma/dmatest.c307
-rw-r--r--drivers/dma/dw_dmac.c333
-rw-r--r--drivers/dma/dw_dmac_regs.h7
-rw-r--r--drivers/dma/fsldma.c1
-rw-r--r--drivers/dma/ioat.c8
-rw-r--r--drivers/dma/ioat_dma.c1
-rw-r--r--drivers/dma/iop-adma.c1
-rw-r--r--drivers/dma/ipu/ipu_idmac.c371
-rw-r--r--drivers/dma/ipu/ipu_irq.c2
-rw-r--r--drivers/dma/mv_xor.c1
-rw-r--r--drivers/edac/edac_core.h12
-rw-r--r--drivers/edac/edac_device.c2
-rw-r--r--drivers/edac/edac_mc.c2
-rw-r--r--drivers/edac/edac_pci.c2
-rw-r--r--drivers/firmware/dcdbas.c2
-rw-r--r--drivers/gpio/Kconfig6
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c5
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c2
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h4
-rw-r--r--drivers/gpu/drm/i915/i915_opregion.c65
-rw-r--r--drivers/hid/Kconfig42
-rw-r--r--drivers/hid/Makefile7
-rw-r--r--drivers/hid/hid-a4tech.c2
-rw-r--r--drivers/hid/hid-apple.c26
-rw-r--r--drivers/hid/hid-belkin.c2
-rw-r--r--drivers/hid/hid-cherry.c2
-rw-r--r--drivers/hid/hid-chicony.c2
-rw-r--r--drivers/hid/hid-core.c37
-rw-r--r--drivers/hid/hid-cypress.c2
-rw-r--r--drivers/hid/hid-drff.c188
-rw-r--r--drivers/hid/hid-dummy.c78
-rw-r--r--drivers/hid/hid-ezkey.c2
-rw-r--r--drivers/hid/hid-gaff.c2
-rw-r--r--drivers/hid/hid-gyration.c2
-rw-r--r--drivers/hid/hid-ids.h10
-rw-r--r--drivers/hid/hid-kensington.c63
-rw-r--r--drivers/hid/hid-kye.c69
-rw-r--r--drivers/hid/hid-lg.c2
-rw-r--r--drivers/hid/hid-microsoft.c2
-rw-r--r--drivers/hid/hid-monterey.c2
-rw-r--r--drivers/hid/hid-ntrig.c2
-rw-r--r--drivers/hid/hid-petalynx.c2
-rw-r--r--drivers/hid/hid-pl.c52
-rw-r--r--drivers/hid/hid-samsung.c2
-rw-r--r--drivers/hid/hid-sony.c2
-rw-r--r--drivers/hid/hid-sunplus.c2
-rw-r--r--drivers/hid/hid-tmff.c2
-rw-r--r--drivers/hid/hid-topseed.c2
-rw-r--r--drivers/hid/hid-zpff.c2
-rw-r--r--drivers/hid/hidraw.c17
-rw-r--r--drivers/hid/usbhid/hid-core.c475
-rw-r--r--drivers/hid/usbhid/hiddev.c22
-rw-r--r--drivers/hid/usbhid/usbhid.h14
-rw-r--r--drivers/hwmon/Kconfig32
-rw-r--r--drivers/hwmon/Makefile3
-rw-r--r--drivers/hwmon/asus_atk0110.c1009
-rw-r--r--drivers/hwmon/f75375s.c4
-rw-r--r--drivers/hwmon/g760a.c272
-rw-r--r--drivers/hwmon/hp_accel.c1
-rw-r--r--drivers/hwmon/lm95241.c112
-rw-r--r--drivers/hwmon/sht15.c692
-rw-r--r--drivers/i2c/algos/Kconfig4
-rw-r--r--drivers/i2c/algos/Makefile1
-rw-r--r--drivers/i2c/algos/i2c-algo-pca.c2
-rw-r--r--drivers/i2c/algos/i2c-algo-sgi.c179
-rw-r--r--drivers/i2c/busses/Kconfig26
-rw-r--r--drivers/i2c/busses/Makefile2
-rw-r--r--drivers/i2c/busses/i2c-imx.c624
-rw-r--r--drivers/i2c/busses/i2c-mpc.c322
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c77
-rw-r--r--drivers/i2c/busses/i2c-s6000.c407
-rw-r--r--drivers/i2c/busses/i2c-s6000.h79
-rw-r--r--drivers/i2c/i2c-core.c3
-rw-r--r--drivers/ide/at91_ide.c91
-rw-r--r--drivers/ide/cs5520.c2
-rw-r--r--drivers/ide/falconide.c13
-rw-r--r--drivers/ide/ide-acpi.c5
-rw-r--r--drivers/ide/ide-atapi.c38
-rw-r--r--drivers/ide/ide-cd.c288
-rw-r--r--drivers/ide/ide-disk.c70
-rw-r--r--drivers/ide/ide-disk_proc.c6
-rw-r--r--drivers/ide/ide-dma-sff.c9
-rw-r--r--drivers/ide/ide-h8300.c101
-rw-r--r--drivers/ide/ide-io-std.c75
-rw-r--r--drivers/ide/ide-io.c13
-rw-r--r--drivers/ide/ide-ioctls.c14
-rw-r--r--drivers/ide/ide-iops.c20
-rw-r--r--drivers/ide/ide-lib.c28
-rw-r--r--drivers/ide/ide-park.c3
-rw-r--r--drivers/ide/ide-pm.c3
-rw-r--r--drivers/ide/ide-probe.c18
-rw-r--r--drivers/ide/ide-proc.c4
-rw-r--r--drivers/ide/ide-taskfile.c97
-rw-r--r--drivers/ide/ns87415.c34
-rw-r--r--drivers/ide/q40ide.c14
-rw-r--r--drivers/ide/scc_pata.c71
-rw-r--r--drivers/ide/setup-pci.c2
-rw-r--r--drivers/ide/tx4938ide.c89
-rw-r--r--drivers/ide/tx4939ide.c110
-rw-r--r--drivers/idle/i7300_idle.c2
-rw-r--r--drivers/ieee1394/pcilynx.c2
-rw-r--r--drivers/infiniband/core/cma.c45
-rw-r--r--drivers/infiniband/hw/amso1100/c2.c4
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.c10
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.h6
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch.c11
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch.h5
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c116
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.h3
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_qp.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c8
-rw-r--r--drivers/infiniband/hw/mlx4/main.c3
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c8
-rw-r--r--drivers/infiniband/hw/nes/nes.c8
-rw-r--r--drivers/infiniband/hw/nes/nes.h4
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c22
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.h1
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c389
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.h2
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c52
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c25
-rw-r--r--drivers/input/Kconfig2
-rw-r--r--drivers/input/input.c13
-rw-r--r--drivers/input/keyboard/atkbd.c135
-rw-r--r--drivers/input/keyboard/bf54x-keys.c4
-rw-r--r--drivers/input/keyboard/hilkbd.c140
-rw-r--r--drivers/input/keyboard/sh_keysc.c17
-rw-r--r--drivers/input/misc/Kconfig23
-rw-r--r--drivers/input/misc/Makefile28
-rw-r--r--drivers/input/misc/ati_remote2.c277
-rw-r--r--drivers/input/misc/rb532_button.c120
-rw-r--r--drivers/input/misc/rotary_encoder.c221
-rw-r--r--drivers/input/mouse/Kconfig11
-rw-r--r--drivers/input/mouse/Makefile9
-rw-r--r--drivers/input/mouse/gpio_mouse.c2
-rw-r--r--drivers/input/mouse/hgpk.c2
-rw-r--r--drivers/input/mouse/maplemouse.c147
-rw-r--r--drivers/input/mouse/pc110pad.c5
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h8
-rw-r--r--drivers/input/touchscreen/Kconfig58
-rw-r--r--drivers/input/touchscreen/Makefile3
-rw-r--r--drivers/input/touchscreen/ad7877.c844
-rw-r--r--drivers/input/touchscreen/ad7879.c782
-rw-r--r--drivers/input/touchscreen/ads7846.c2
-rw-r--r--drivers/input/touchscreen/mainstone-wm97xx.c3
-rw-r--r--drivers/input/touchscreen/migor_ts.c23
-rw-r--r--drivers/input/touchscreen/ucb1400_ts.c5
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c13
-rw-r--r--drivers/input/touchscreen/zylonite-wm97xx.c240
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c4
-rw-r--r--drivers/isdn/gigaset/interface.c58
-rw-r--r--drivers/isdn/mISDN/Kconfig10
-rw-r--r--drivers/isdn/mISDN/l1oip_codec.c2
-rw-r--r--drivers/leds/Kconfig81
-rw-r--r--drivers/leds/Makefile7
-rw-r--r--drivers/leds/led-class.c21
-rw-r--r--drivers/leds/led-triggers.c10
-rw-r--r--drivers/leds/leds-bd2802.c765
-rw-r--r--drivers/leds/leds-dac124s085.c150
-rw-r--r--drivers/leds/leds-gpio.c225
-rw-r--r--drivers/leds/leds-h1940.c2
-rw-r--r--drivers/leds/leds-pca9532.c6
-rw-r--r--drivers/leds/leds-pwm.c153
-rw-r--r--drivers/leds/leds-rb532.c77
-rw-r--r--drivers/leds/leds-s3c24xx.c7
-rw-r--r--drivers/leds/leds.h4
-rw-r--r--drivers/leds/ledtrig-default-on.c2
-rw-r--r--drivers/leds/ledtrig-gpio.c239
-rw-r--r--drivers/leds/ledtrig-heartbeat.c4
-rw-r--r--drivers/leds/ledtrig-ide-disk.c3
-rw-r--r--drivers/leds/ledtrig-timer.c2
-rw-r--r--drivers/md/Kconfig31
-rw-r--r--drivers/md/Makefile16
-rw-r--r--drivers/md/bitmap.c49
-rw-r--r--drivers/md/bitmap.h (renamed from include/linux/raid/bitmap.h)0
-rw-r--r--drivers/md/dm-bio-list.h10
-rw-r--r--drivers/md/dm-bio-record.h26
-rw-r--r--drivers/md/dm-crypt.c6
-rw-r--r--drivers/md/dm-exception-store.c252
-rw-r--r--drivers/md/dm-exception-store.h58
-rw-r--r--drivers/md/dm-io.c5
-rw-r--r--drivers/md/dm-ioctl.c21
-rw-r--r--drivers/md/dm-kcopyd.c23
-rw-r--r--drivers/md/dm-linear.c1
-rw-r--r--drivers/md/dm-log.c75
-rw-r--r--drivers/md/dm-path-selector.c21
-rw-r--r--drivers/md/dm-raid1.c50
-rw-r--r--drivers/md/dm-snap-persistent.c153
-rw-r--r--drivers/md/dm-snap-transient.c86
-rw-r--r--drivers/md/dm-snap.c384
-rw-r--r--drivers/md/dm-snap.h105
-rw-r--r--drivers/md/dm-table.c85
-rw-r--r--drivers/md/dm-target.c104
-rw-r--r--drivers/md/dm.c297
-rw-r--r--drivers/md/dm.h3
-rw-r--r--drivers/md/faulty.c19
-rw-r--r--drivers/md/linear.c25
-rw-r--r--drivers/md/linear.h (renamed from include/linux/raid/linear.h)2
-rw-r--r--drivers/md/md.c615
-rw-r--r--drivers/md/md.h (renamed from include/linux/raid/md_k.h)66
-rw-r--r--drivers/md/mktables.c14
-rw-r--r--drivers/md/multipath.c17
-rw-r--r--drivers/md/multipath.h (renamed from include/linux/raid/multipath.h)2
-rw-r--r--drivers/md/raid0.c66
-rw-r--r--drivers/md/raid0.h (renamed from include/linux/raid/raid0.h)2
-rw-r--r--drivers/md/raid1.c44
-rw-r--r--drivers/md/raid1.h (renamed from include/linux/raid/raid1.h)2
-rw-r--r--drivers/md/raid10.c42
-rw-r--r--drivers/md/raid10.h (renamed from include/linux/raid/raid10.h)2
-rw-r--r--drivers/md/raid5.c1494
-rw-r--r--drivers/md/raid5.h (renamed from include/linux/raid/raid5.h)110
-rw-r--r--drivers/md/raid6algos.c21
-rw-r--r--drivers/md/raid6altivec.uc4
-rw-r--r--drivers/md/raid6int.uc4
-rw-r--r--drivers/md/raid6mmx.c4
-rw-r--r--drivers/md/raid6recov.c13
-rw-r--r--drivers/md/raid6sse1.c4
-rw-r--r--drivers/md/raid6sse2.c4
-rw-r--r--drivers/md/raid6test/Makefile2
-rw-r--r--drivers/md/raid6test/test.c2
-rw-r--r--drivers/md/raid6x86.h2
-rw-r--r--drivers/media/common/tuners/Kconfig2
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c2
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig4
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c63
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h75
-rw-r--r--drivers/media/dvb/dvb-usb/ce6230.c8
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h4
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c2
-rw-r--r--drivers/media/dvb/frontends/Kconfig9
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c12
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c2
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx.c816
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx.h90
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx_priv.h70
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c2
-rw-r--r--drivers/media/dvb/ttpci/Kconfig23
-rw-r--r--drivers/media/dvb/ttpci/Makefile9
-rw-r--r--drivers/media/dvb/ttpci/av7110.c16
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c35
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.h3
-rw-r--r--drivers/media/dvb/ttpci/fdump.c44
-rw-r--r--drivers/media/radio/dsbr100.c88
-rw-r--r--drivers/media/radio/radio-aimslab.c12
-rw-r--r--drivers/media/radio/radio-aztech.c12
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c12
-rw-r--r--drivers/media/radio/radio-gemtek.c11
-rw-r--r--drivers/media/radio/radio-maestro.c12
-rw-r--r--drivers/media/radio/radio-maxiradio.c12
-rw-r--r--drivers/media/radio/radio-mr800.c85
-rw-r--r--drivers/media/radio/radio-rtrack2.c12
-rw-r--r--drivers/media/radio/radio-sf16fmi.c12
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c12
-rw-r--r--drivers/media/radio/radio-si470x.c9
-rw-r--r--drivers/media/radio/radio-terratec.c12
-rw-r--r--drivers/media/radio/radio-trust.c12
-rw-r--r--drivers/media/radio/radio-typhoon.c12
-rw-r--r--drivers/media/radio/radio-zoltrix.c12
-rw-r--r--drivers/media/video/Kconfig15
-rw-r--r--drivers/media/video/Makefile4
-rw-r--r--drivers/media/video/adv7170.c19
-rw-r--r--drivers/media/video/adv7175.c17
-rw-r--r--drivers/media/video/au0828/Kconfig1
-rw-r--r--drivers/media/video/au0828/au0828-cards.c19
-rw-r--r--drivers/media/video/au0828/au0828-core.c9
-rw-r--r--drivers/media/video/au0828/au0828-i2c.c72
-rw-r--r--drivers/media/video/au0828/au0828-reg.h35
-rw-r--r--drivers/media/video/au0828/au0828-video.c12
-rw-r--r--drivers/media/video/au0828/au0828.h1
-rw-r--r--drivers/media/video/bt819.c15
-rw-r--r--drivers/media/video/bt856.c11
-rw-r--r--drivers/media/video/bt866.c11
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c70
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c27
-rw-r--r--drivers/media/video/bt8xx/bttvp.h2
-rw-r--r--drivers/media/video/cafe_ccic.c2
-rw-r--r--drivers/media/video/cs5345.c11
-rw-r--r--drivers/media/video/cs53l32a.c9
-rw-r--r--drivers/media/video/cx18/cx18-audio.c9
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c70
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h5
-rw-r--r--drivers/media/video/cx18/cx18-driver.c4
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c2
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c6
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c14
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c12
-rw-r--r--drivers/media/video/cx18/cx18-video.c16
-rw-r--r--drivers/media/video/cx231xx/Kconfig35
-rw-r--r--drivers/media/video/cx231xx/Makefile14
-rw-r--r--drivers/media/video/cx231xx/cx231xx-audio.c586
-rw-r--r--drivers/media/video/cx231xx/cx231xx-avcore.c2581
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c914
-rw-r--r--drivers/media/video/cx231xx/cx231xx-conf-reg.h494
-rw-r--r--drivers/media/video/cx231xx/cx231xx-core.c1200
-rw-r--r--drivers/media/video/cx231xx/cx231xx-dvb.c559
-rw-r--r--drivers/media/video/cx231xx/cx231xx-i2c.c555
-rw-r--r--drivers/media/video/cx231xx/cx231xx-input.c246
-rw-r--r--drivers/media/video/cx231xx/cx231xx-pcb-cfg.c795
-rw-r--r--drivers/media/video/cx231xx/cx231xx-pcb-cfg.h231
-rw-r--r--drivers/media/video/cx231xx/cx231xx-reg.h1564
-rw-r--r--drivers/media/video/cx231xx/cx231xx-vbi.c701
-rw-r--r--drivers/media/video/cx231xx/cx231xx-vbi.h65
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c2434
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h779
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c5
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c16
-rw-r--r--drivers/media/video/cx23885/cx23885.h2
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c66
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c185
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h1
-rw-r--r--drivers/media/video/cx25840/cx25840-firmware.c11
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c2
-rw-r--r--drivers/media/video/cx88/cx88-cards.c17
-rw-r--r--drivers/media/video/cx88/cx88-core.c2
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c2
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c2
-rw-r--r--drivers/media/video/cx88/cx88-video.c27
-rw-r--r--drivers/media/video/cx88/cx88.h2
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c150
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c12
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c71
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c83
-rw-r--r--drivers/media/video/em28xx/em28xx.h10
-rw-r--r--drivers/media/video/gspca/gspca.c1
-rw-r--r--drivers/media/video/gspca/gspca.h1
-rw-r--r--drivers/media/video/gspca/m5602/Makefile3
-rw-r--r--drivers/media/video/gspca/m5602/m5602_bridge.h8
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c36
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.c77
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.h61
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c570
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.h239
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.c114
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.h98
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c173
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.h134
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c154
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.h94
-rw-r--r--drivers/media/video/gspca/m5602/m5602_sensor.h17
-rw-r--r--drivers/media/video/gspca/sq905.c6
-rw-r--r--drivers/media/video/gspca/vc032x.c403
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c9
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c17
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c18
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c17
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c16
-rw-r--r--drivers/media/video/ivtv/ivtv-routing.c66
-rw-r--r--drivers/media/video/ks0127.c21
-rw-r--r--drivers/media/video/m52790.c7
-rw-r--r--drivers/media/video/meye.c2
-rw-r--r--drivers/media/video/msp3400-driver.c40
-rw-r--r--drivers/media/video/msp3400-driver.h3
-rw-r--r--drivers/media/video/msp3400-kthreads.c6
-rw-r--r--drivers/media/video/mt9m001.c2
-rw-r--r--drivers/media/video/mt9t031.c21
-rw-r--r--drivers/media/video/mx1_camera.c827
-rw-r--r--drivers/media/video/mx3_camera.c2
-rw-r--r--drivers/media/video/mxb.c144
-rw-r--r--drivers/media/video/ov772x.c65
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.c8
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c7
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.c12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c9
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c11
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c14
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.c8
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.c12
-rw-r--r--drivers/media/video/pwc/Kconfig2
-rw-r--r--drivers/media/video/pxa_camera.c511
-rw-r--r--drivers/media/video/s2255drv.c8
-rw-r--r--drivers/media/video/saa7110.c17
-rw-r--r--drivers/media/video/saa7115.c61
-rw-r--r--drivers/media/video/saa7127.c11
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c41
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c13
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c6
-rw-r--r--drivers/media/video/saa7134/saa7134.h2
-rw-r--r--drivers/media/video/saa717x.c25
-rw-r--r--drivers/media/video/saa7185.c9
-rw-r--r--drivers/media/video/saa7191.c10
-rw-r--r--drivers/media/video/soc_camera.c6
-rw-r--r--drivers/media/video/tda9840.c1
-rw-r--r--drivers/media/video/tea6415c.c6
-rw-r--r--drivers/media/video/tea6420.c18
-rw-r--r--drivers/media/video/tuner-core.c81
-rw-r--r--drivers/media/video/tvaudio.c44
-rw-r--r--drivers/media/video/tvp5150.c40
-rw-r--r--drivers/media/video/upd64031a.c11
-rw-r--r--drivers/media/video/upd64083.c9
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c5
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c10
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c14
-rw-r--r--drivers/media/video/uvc/Kconfig2
-rw-r--r--drivers/media/video/v4l1-compat.c9
-rw-r--r--drivers/media/video/v4l2-common.c62
-rw-r--r--drivers/media/video/v4l2-dev.c11
-rw-r--r--drivers/media/video/v4l2-ioctl.c34
-rw-r--r--drivers/media/video/v4l2-subdev.c128
-rw-r--r--drivers/media/video/vino.c33
-rw-r--r--drivers/media/video/vp27smpx.c2
-rw-r--r--drivers/media/video/vpx3220.c23
-rw-r--r--drivers/media/video/w9968cf.c5
-rw-r--r--drivers/media/video/w9968cf.h2
-rw-r--r--drivers/media/video/wm8775.c9
-rw-r--r--drivers/media/video/zoran/zoran.h4
-rw-r--r--drivers/media/video/zoran/zoran_card.c12
-rw-r--r--drivers/media/video/zoran/zoran_device.c22
-rw-r--r--drivers/media/video/zoran/zoran_driver.c26
-rw-r--r--drivers/media/video/zr364xx.c1
-rw-r--r--drivers/memstick/host/jmb38x_ms.c2
-rw-r--r--drivers/message/fusion/mptbase.c8
-rw-r--r--drivers/message/fusion/mptsas.c5
-rw-r--r--drivers/message/i2o/memory.c6
-rw-r--r--drivers/message/i2o/pci.c4
-rw-r--r--drivers/mfd/Kconfig3
-rw-r--r--drivers/mfd/da903x.c2
-rw-r--r--drivers/mfd/htc-pasic3.c169
-rw-r--r--drivers/mfd/pcf50633-core.c1
-rw-r--r--drivers/mfd/t7l66xb.c4
-rw-r--r--drivers/mfd/tc6393xb.c2
-rw-r--r--drivers/mfd/twl4030-core.c2
-rw-r--r--drivers/mfd/twl4030-irq.c2
-rw-r--r--drivers/mfd/wm8350-core.c39
-rw-r--r--drivers/misc/Kconfig6
-rw-r--r--drivers/misc/eeprom/at24.c8
-rw-r--r--drivers/misc/eeprom/at25.c5
-rw-r--r--drivers/misc/sgi-xp/xpc.h254
-rw-r--r--drivers/misc/sgi-xp/xpc_channel.c138
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c128
-rw-r--r--drivers/misc/sgi-xp/xpc_partition.c20
-rw-r--r--drivers/misc/sgi-xp/xpc_sn2.c164
-rw-r--r--drivers/misc/sgi-xp/xpc_uv.c257
-rw-r--r--drivers/misc/tifm_7xx1.c2
-rw-r--r--drivers/mmc/card/block.c2
-rw-r--r--drivers/mmc/core/bus.c8
-rw-r--r--drivers/mmc/core/core.c118
-rw-r--r--drivers/mmc/core/debugfs.c67
-rw-r--r--drivers/mmc/core/mmc.c2
-rw-r--r--drivers/mmc/core/sd.c21
-rw-r--r--drivers/mmc/core/sdio_cis.c8
-rw-r--r--drivers/mmc/core/sdio_ops.c8
-rw-r--r--drivers/mmc/host/Kconfig31
-rw-r--r--drivers/mmc/host/Makefile2
-rw-r--r--drivers/mmc/host/atmel-mci.c2
-rw-r--r--drivers/mmc/host/imxmmc.c19
-rw-r--r--drivers/mmc/host/mmc_spi.c228
-rw-r--r--drivers/mmc/host/mvsdio.c885
-rw-r--r--drivers/mmc/host/mvsdio.h190
-rw-r--r--drivers/mmc/host/omap_hsmmc.c360
-rw-r--r--drivers/mmc/host/sdhci-of.c309
-rw-r--r--drivers/mmc/host/sdhci-pci.c4
-rw-r--r--drivers/mmc/host/sdhci.c319
-rw-r--r--drivers/mmc/host/sdhci.h112
-rw-r--r--drivers/mmc/host/tmio_mmc.c6
-rw-r--r--drivers/mmc/host/tmio_mmc.h3
-rw-r--r--drivers/mmc/host/wbsd.c2
-rw-r--r--drivers/mtd/Makefile2
-rw-r--r--drivers/mtd/ar7part.c6
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c8
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c11
-rw-r--r--drivers/mtd/chips/jedec_probe.c16
-rw-r--r--drivers/mtd/chips/map_ram.c17
-rw-r--r--drivers/mtd/chips/map_rom.c17
-rw-r--r--drivers/mtd/cmdlinepart.c6
-rw-r--r--drivers/mtd/devices/doc2000.c1
-rw-r--r--drivers/mtd/devices/doc2001.c1
-rw-r--r--drivers/mtd/devices/doc2001plus.c1
-rw-r--r--drivers/mtd/devices/docecc.c1
-rw-r--r--drivers/mtd/devices/m25p80.c19
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c18
-rw-r--r--drivers/mtd/devices/mtdram.c14
-rw-r--r--drivers/mtd/inftlmount.c1
-rw-r--r--drivers/mtd/internal.h17
-rw-r--r--drivers/mtd/maps/Kconfig12
-rw-r--r--drivers/mtd/maps/Makefile2
-rw-r--r--drivers/mtd/maps/omap_nor.c2
-rw-r--r--drivers/mtd/maps/physmap.c1
-rw-r--r--drivers/mtd/maps/physmap_of.c1
-rw-r--r--drivers/mtd/maps/plat-ram.c1
-rw-r--r--drivers/mtd/maps/pxa2xx-flash.c2
-rw-r--r--drivers/mtd/maps/rbtx4939-flash.c208
-rw-r--r--drivers/mtd/maps/sa1100-flash.c2
-rw-r--r--drivers/mtd/maps/sharpsl-flash.c116
-rw-r--r--drivers/mtd/mtd_blkdevs.c4
-rw-r--r--drivers/mtd/mtdbdi.c43
-rw-r--r--drivers/mtd/mtdchar.c111
-rw-r--r--drivers/mtd/mtdconcat.c47
-rw-r--r--drivers/mtd/mtdcore.c208
-rw-r--r--drivers/mtd/mtdoops.c16
-rw-r--r--drivers/mtd/mtdpart.c31
-rw-r--r--drivers/mtd/nand/Kconfig21
-rw-r--r--drivers/mtd/nand/Makefile3
-rw-r--r--drivers/mtd/nand/bf5xx_nand.c18
-rw-r--r--drivers/mtd/nand/cafe_nand.c1
-rw-r--r--drivers/mtd/nand/davinci_nand.c570
-rw-r--r--drivers/mtd/nand/diskonchip.c2
-rw-r--r--drivers/mtd/nand/fsl_upm.c119
-rw-r--r--drivers/mtd/nand/mxc_nand.c1
-rw-r--r--drivers/mtd/nand/nand_base.c129
-rw-r--r--drivers/mtd/nand/plat_nand.c2
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c119
-rw-r--r--drivers/mtd/nand/sh_flctl.c18
-rw-r--r--drivers/mtd/nand/socrates_nand.c325
-rw-r--r--drivers/mtd/nand/txx9ndfmc.c428
-rw-r--r--drivers/mtd/nftlcore.c3
-rw-r--r--drivers/mtd/ofpart.c7
-rw-r--r--drivers/mtd/onenand/omap2.c6
-rw-r--r--drivers/mtd/onenand/onenand_base.c145
-rw-r--r--drivers/mtd/tests/mtd_oobtest.c24
-rw-r--r--drivers/mtd/tests/mtd_readtest.c2
-rw-r--r--drivers/mtd/ubi/cdev.c11
-rw-r--r--drivers/net/8139cp.c10
-rw-r--r--drivers/net/Kconfig25
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/acenic.c4
-rw-r--r--drivers/net/amd8111e.c2
-rw-r--r--drivers/net/atl1c/atl1c_main.c4
-rw-r--r--drivers/net/atl1e/atl1e_main.c4
-rw-r--r--drivers/net/atlx/atl1.c2
-rw-r--r--drivers/net/atlx/atl2.c4
-rw-r--r--drivers/net/b44.c22
-rw-r--r--drivers/net/benet/be_main.c4
-rw-r--r--drivers/net/bnx2.c357
-rw-r--r--drivers/net/bnx2.h71
-rw-r--r--drivers/net/bnx2_fw.h4378
-rw-r--r--drivers/net/bnx2_fw2.h4547
-rw-r--r--drivers/net/bnx2x_main.c6
-rw-r--r--drivers/net/cassini.c6
-rw-r--r--drivers/net/chelsio/cxgb2.c6
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c6
-rw-r--r--drivers/net/dl2k.c2
-rw-r--r--drivers/net/e100.c2
-rw-r--r--drivers/net/e1000/e1000_main.c42
-rw-r--r--drivers/net/e1000e/netdev.c12
-rw-r--r--drivers/net/enic/enic_main.c8
-rw-r--r--drivers/net/eql.c2
-rw-r--r--drivers/net/fec.c1
-rw-r--r--drivers/net/forcedeth.c7
-rw-r--r--drivers/net/hp100.c2
-rw-r--r--drivers/net/ibm_newemac/core.c2
-rw-r--r--drivers/net/igb/igb_main.c167
-rw-r--r--drivers/net/igbvf/Makefile38
-rw-r--r--drivers/net/igbvf/defines.h125
-rw-r--r--drivers/net/igbvf/ethtool.c540
-rw-r--r--drivers/net/igbvf/igbvf.h335
-rw-r--r--drivers/net/igbvf/mbx.c350
-rw-r--r--drivers/net/igbvf/mbx.h75
-rw-r--r--drivers/net/igbvf/netdev.c2919
-rw-r--r--drivers/net/igbvf/regs.h108
-rw-r--r--drivers/net/igbvf/vf.c398
-rw-r--r--drivers/net/igbvf/vf.h265
-rw-r--r--drivers/net/ioc3-eth.c6
-rw-r--r--drivers/net/ipg.c4
-rw-r--r--drivers/net/ixgb/ixgb_main.c8
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c12
-rw-r--r--drivers/net/jme.c12
-rw-r--r--drivers/net/mlx4/main.c8
-rw-r--r--drivers/net/mlx4/port.c5
-rw-r--r--drivers/net/mv643xx_eth.c4
-rw-r--r--drivers/net/myri10ge/myri10ge.c8
-rw-r--r--drivers/net/myri_code.h5006
-rw-r--r--drivers/net/myri_sbus.c37
-rw-r--r--drivers/net/netxen/netxen_nic_main.c8
-rw-r--r--drivers/net/niu.c7
-rw-r--r--drivers/net/ns83820.c4
-rw-r--r--drivers/net/pcmcia/axnet_cs.c9
-rw-r--r--drivers/net/qla3xxx.c8
-rw-r--r--drivers/net/qlge/qlge_main.c8
-rw-r--r--drivers/net/r6040.c5
-rw-r--r--drivers/net/r8169.c10
-rw-r--r--drivers/net/s2io.c6
-rw-r--r--drivers/net/sb1250-mac.c2
-rw-r--r--drivers/net/sc92031.c4
-rw-r--r--drivers/net/sis190.c2
-rw-r--r--drivers/net/sis900.c2
-rw-r--r--drivers/net/skfp/h/hwmtm.h2
-rw-r--r--drivers/net/skge.c8
-rw-r--r--drivers/net/sky2.c6
-rw-r--r--drivers/net/smc91x.h2
-rw-r--r--drivers/net/smsc911x.c3
-rw-r--r--drivers/net/smsc9420.c2
-rw-r--r--drivers/net/sungem.c4
-rw-r--r--drivers/net/tehuti.c8
-rw-r--r--drivers/net/tehuti.h9
-rw-r--r--drivers/net/tg3.c22
-rw-r--r--drivers/net/tlan.c2
-rw-r--r--drivers/net/tokenring/lanstreamer.c2
-rw-r--r--drivers/net/tulip/dmfe.c2
-rw-r--r--drivers/net/tulip/uli526x.c2
-rw-r--r--drivers/net/tulip/winbond-840.c2
-rw-r--r--drivers/net/typhoon.c2
-rw-r--r--drivers/net/usb/usbnet.c2
-rw-r--r--drivers/net/via-rhine.c2
-rw-r--r--drivers/net/virtio_net.c10
-rw-r--r--drivers/net/vxge/vxge-main.c1
-rw-r--r--drivers/net/wan/farsync.c2
-rw-r--r--drivers/net/wan/wanxl.c8
-rw-r--r--drivers/net/wireless/adm8211.c4
-rw-r--r--drivers/net/wireless/ath5k/base.c2
-rw-r--r--drivers/net/wireless/ath9k/pci.c4
-rw-r--r--drivers/net/wireless/b43/dma.c20
-rw-r--r--drivers/net/wireless/b43legacy/dma.c20
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c4
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c6
-rw-r--r--drivers/net/wireless/libertas/cmd.c2
-rw-r--r--drivers/net/wireless/p54/p54pci.c4
-rw-r--r--drivers/net/wireless/prism54/islpci_hotplug.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c2
-rw-r--r--drivers/oprofile/buffer_sync.c20
-rw-r--r--drivers/oprofile/buffer_sync.h4
-rw-r--r--drivers/oprofile/cpu_buffer.c5
-rw-r--r--drivers/oprofile/oprof.c9
-rw-r--r--drivers/parisc/asp.c2
-rw-r--r--drivers/parisc/ccio-dma.c16
-rw-r--r--drivers/parisc/dino.c7
-rw-r--r--drivers/parisc/eisa.c2
-rw-r--r--drivers/parisc/eisa_enumerator.c4
-rw-r--r--drivers/parisc/iosapic.c2
-rw-r--r--drivers/parisc/led.c26
-rw-r--r--drivers/parisc/superio.c3
-rw-r--r--drivers/parport/parport_cs.c3
-rw-r--r--drivers/parport/parport_pc.c57
-rw-r--r--drivers/parport/parport_serial.c20
-rw-r--r--drivers/pci/access.c3
-rw-r--r--drivers/pci/bus.c2
-rw-r--r--drivers/pci/dmar.c82
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c14
-rw-r--r--drivers/pci/intel-iommu.c362
-rw-r--r--drivers/pci/intr_remapping.c84
-rw-r--r--drivers/pci/iov.c1
-rw-r--r--drivers/pci/pci-acpi.c4
-rw-r--r--drivers/pci/pci-driver.c3
-rw-r--r--drivers/pci/pci-sysfs.c6
-rw-r--r--drivers/pci/pci.c6
-rw-r--r--drivers/pci/probe.c2
-rw-r--r--drivers/pci/quirks.c62
-rw-r--r--drivers/pci/setup-bus.c2
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x255.c2
-rw-r--r--drivers/platform/x86/Kconfig35
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/acer-wmi.c35
-rw-r--r--drivers/platform/x86/dell-wmi.c210
-rw-r--r--drivers/platform/x86/fujitsu-laptop.c60
-rw-r--r--drivers/platform/x86/hp-wmi.c25
-rw-r--r--drivers/platform/x86/intel_menlow.c29
-rw-r--r--drivers/platform/x86/panasonic-laptop.c37
-rw-r--r--drivers/platform/x86/sony-laptop.c559
-rw-r--r--drivers/platform/x86/tc1100-wmi.c7
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c737
-rw-r--r--drivers/platform/x86/wmi.c15
-rw-r--r--drivers/pnp/card.c2
-rw-r--r--drivers/pnp/core.c2
-rw-r--r--drivers/pnp/pnpacpi/core.c23
-rw-r--r--drivers/power/bq27x00_battery.c2
-rw-r--r--drivers/power/pcf50633-charger.c88
-rw-r--r--drivers/power/pda_power.c89
-rw-r--r--drivers/power/power_supply_sysfs.c2
-rw-r--r--drivers/rapidio/rio-scan.c4
-rw-r--r--drivers/regulator/Kconfig13
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/bq24022.c3
-rw-r--r--drivers/regulator/core.c386
-rw-r--r--drivers/regulator/da903x.c3
-rw-r--r--drivers/regulator/fixed.c3
-rw-r--r--drivers/regulator/pcf50633-regulator.c3
-rw-r--r--drivers/regulator/twl4030-regulator.c500
-rw-r--r--drivers/regulator/virtual.c14
-rw-r--r--drivers/regulator/wm8350-regulator.c57
-rw-r--r--drivers/regulator/wm8400-regulator.c36
-rw-r--r--drivers/rtc/Kconfig31
-rw-r--r--drivers/rtc/Makefile4
-rw-r--r--drivers/rtc/rtc-generic.c84
-rw-r--r--drivers/rtc/rtc-parisc.c86
-rw-r--r--drivers/rtc/rtc-ppc.c69
-rw-r--r--drivers/rtc/rtc-ps3.c104
-rw-r--r--drivers/rtc/rtc-sh.c36
-rw-r--r--drivers/scsi/3w-9xxx.c16
-rw-r--r--drivers/scsi/3w-xxxx.h2
-rw-r--r--drivers/scsi/BusLogic.c6
-rw-r--r--drivers/scsi/Kconfig21
-rw-r--r--drivers/scsi/Makefile1
-rw-r--r--drivers/scsi/a100u2w.c2
-rw-r--r--drivers/scsi/a2091.c6
-rw-r--r--drivers/scsi/a2091.h3
-rw-r--r--drivers/scsi/a3000.c6
-rw-r--r--drivers/scsi/a3000.h3
-rw-r--r--drivers/scsi/aacraid/aachba.c48
-rw-r--r--drivers/scsi/aacraid/aacraid.h9
-rw-r--r--drivers/scsi/aacraid/comminit.c14
-rw-r--r--drivers/scsi/aacraid/commsup.c10
-rw-r--r--drivers/scsi/aacraid/linit.c18
-rw-r--r--drivers/scsi/advansys.c1731
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_core.c12
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_inline.h32
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h102
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm_pci.c12
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_pci.c8
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_inline.h5
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h104
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm_pci.c4
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_pci.c10
-rw-r--r--drivers/scsi/aic7xxx/aiclib.h4
-rw-r--r--drivers/scsi/aic94xx/aic94xx_init.c8
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c4
-rw-r--r--drivers/scsi/atp870u.c2
-rw-r--r--drivers/scsi/cxgb3i/Kbuild4
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i.h10
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.c275
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.h6
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_init.c31
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_iscsi.c129
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.c101
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.h13
-rw-r--r--drivers/scsi/dpt_i2o.c8
-rw-r--r--drivers/scsi/eata.c2
-rw-r--r--drivers/scsi/fcoe/Makefile8
-rw-r--r--drivers/scsi/fcoe/fc_transport_fcoe.c443
-rw-r--r--drivers/scsi/fcoe/fcoe.c1878
-rw-r--r--drivers/scsi/fcoe/fcoe.h75
-rw-r--r--drivers/scsi/fcoe/fcoe_sw.c561
-rw-r--r--drivers/scsi/fcoe/libfcoe.c2216
-rw-r--r--drivers/scsi/gdth.c6
-rw-r--r--drivers/scsi/hptiop.c4
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c126
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h16
-rw-r--r--drivers/scsi/initio.c2
-rw-r--r--drivers/scsi/ipr.c2
-rw-r--r--drivers/scsi/ips.c4
-rw-r--r--drivers/scsi/lasi700.c2
-rw-r--r--drivers/scsi/libfc/fc_fcp.c10
-rw-r--r--drivers/scsi/libfc/fc_lport.c11
-rw-r--r--drivers/scsi/libiscsi.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c2
-rw-r--r--drivers/scsi/megaraid.c6
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c6
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c6
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c10
-rw-r--r--drivers/scsi/mvsas.c10
-rw-r--r--drivers/scsi/nsp32.c2
-rw-r--r--drivers/scsi/osd/osd_initiator.c42
-rw-r--r--drivers/scsi/osd/osd_uld.c6
-rw-r--r--drivers/scsi/ql1040_fw.h2130
-rw-r--r--drivers/scsi/ql12160_fw.h1811
-rw-r--r--drivers/scsi/ql1280_fw.h2048
-rw-r--r--drivers/scsi/qla1280.c120
-rw-r--r--drivers/scsi/qla1280.h6
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c295
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h136
-rw-r--r--drivers/scsi/qla2xxx/qla_dfs.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h42
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h25
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c136
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c37
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c32
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c238
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c12
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c266
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c103
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h4
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c8
-rw-r--r--drivers/scsi/qlogicpti.c63
-rw-r--r--drivers/scsi/qlogicpti_asm.c1160
-rw-r--r--drivers/scsi/scsi.c4
-rw-r--r--drivers/scsi/scsi_lib.c17
-rw-r--r--drivers/scsi/scsi_priv.h3
-rw-r--r--drivers/scsi/scsi_wait_scan.c2
-rw-r--r--drivers/scsi/sd.c6
-rw-r--r--drivers/scsi/ses.c2
-rw-r--r--drivers/scsi/sg.c37
-rw-r--r--drivers/scsi/sni_53c710.c2
-rw-r--r--drivers/scsi/sr.c9
-rw-r--r--drivers/scsi/stex.c750
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.h6
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.h12
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_malloc.c2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_misc.h18
-rw-r--r--drivers/serial/8250_pci.c412
-rw-r--r--drivers/serial/8250_pnp.c7
-rw-r--r--drivers/serial/Kconfig55
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/atmel_serial.c9
-rw-r--r--drivers/serial/bfin_5xx.c297
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c14
-rw-r--r--drivers/serial/crisv10.c79
-rw-r--r--drivers/serial/crisv10.h2
-rw-r--r--drivers/serial/icom.c14
-rw-r--r--drivers/serial/jsm/jsm_driver.c9
-rw-r--r--drivers/serial/jsm/jsm_neo.c14
-rw-r--r--drivers/serial/jsm/jsm_tty.c23
-rw-r--r--drivers/serial/max3100.c927
-rw-r--r--drivers/serial/mcf.c2
-rw-r--r--drivers/serial/pmac_zilog.c15
-rw-r--r--drivers/serial/sunsu.c2
-rw-r--r--drivers/serial/ucc_uart.c1
-rw-r--r--drivers/sh/intc.c95
-rw-r--r--drivers/sn/ioc3.c4
-rw-r--r--drivers/spi/pxa2xx_spi.c98
-rw-r--r--drivers/spi/spi.c22
-rw-r--r--drivers/spi/spi_bfin5xx.c645
-rw-r--r--drivers/spi/spi_imx.c5
-rw-r--r--drivers/staging/Kconfig26
-rw-r--r--drivers/staging/Makefile11
-rw-r--r--drivers/staging/agnx/agnx.h14
-rw-r--r--drivers/staging/agnx/debug.h21
-rw-r--r--drivers/staging/agnx/pci.c79
-rw-r--r--drivers/staging/agnx/phy.c32
-rw-r--r--drivers/staging/agnx/rf.c23
-rw-r--r--drivers/staging/agnx/sta.c21
-rw-r--r--drivers/staging/agnx/sta.h2
-rw-r--r--drivers/staging/agnx/table.c12
-rw-r--r--drivers/staging/agnx/xmit.c216
-rw-r--r--drivers/staging/altpciechdma/altpciechdma.c88
-rw-r--r--drivers/staging/android/binder.c18
-rw-r--r--drivers/staging/android/ram_console.c8
-rw-r--r--drivers/staging/asus_oled/asus_oled.c149
-rw-r--r--drivers/staging/at76_usb/TODO9
-rw-r--r--drivers/staging/at76_usb/at76_usb.c21
-rw-r--r--drivers/staging/at76_usb/at76_usb.h87
-rw-r--r--drivers/staging/b3dfg/Kconfig9
-rw-r--r--drivers/staging/b3dfg/Makefile1
-rw-r--r--drivers/staging/b3dfg/TODO4
-rw-r--r--drivers/staging/b3dfg/b3dfg.c1119
-rw-r--r--drivers/staging/comedi/Kconfig18
-rw-r--r--drivers/staging/comedi/comedi.h83
-rw-r--r--drivers/staging/comedi/comedi_compat32.c128
-rw-r--r--drivers/staging/comedi/comedi_fops.c293
-rw-r--r--drivers/staging/comedi/comedi_fops.h1
-rw-r--r--drivers/staging/comedi/comedi_ksyms.c12
-rw-r--r--drivers/staging/comedi/comedi_rt.h9
-rw-r--r--drivers/staging/comedi/comedidev.h202
-rw-r--r--drivers/staging/comedi/comedilib.h114
-rw-r--r--drivers/staging/comedi/drivers.c187
-rw-r--r--drivers/staging/comedi/drivers/8253.h420
-rw-r--r--drivers/staging/comedi/drivers/8255.c442
-rw-r--r--drivers/staging/comedi/drivers/8255.h57
-rw-r--r--drivers/staging/comedi/drivers/Makefile113
-rw-r--r--drivers/staging/comedi/drivers/acl7225b.c149
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c1047
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h73
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c2032
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h74
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c1020
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h46
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c5363
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h271
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c861
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h47
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c3588
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h76
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c848
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h43
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c2049
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h57
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c1038
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h44
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c203
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h27
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h476
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.c3062
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.h462
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_eeprom.c1158
-rw-r--r--drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h457
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c1265
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h71
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c600
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h123
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c285
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h63
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c3045
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h165
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c542
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h64
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c1105
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h119
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c780
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h94
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c460
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h70
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c579
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h81
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c549
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h61
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c2697
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h241
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c3642
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h187
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c742
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h94
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c1691
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h62
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_035.c5
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1032.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1500.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1516.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1564.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_16xx.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1710.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2016.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2032.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2200.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3001.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3120.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3200.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3300.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3501.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3xxx.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_all.c18
-rw-r--r--drivers/staging/comedi/drivers/adl_pci6208.c391
-rw-r--r--drivers/staging/comedi/drivers/adl_pci7296.c174
-rw-r--r--drivers/staging/comedi/drivers/adl_pci7432.c202
-rw-r--r--drivers/staging/comedi/drivers/adl_pci8164.c512
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9111.c1391
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c2100
-rw-r--r--drivers/staging/comedi/drivers/adq12b.c394
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1710.c1568
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1723.c465
-rw-r--r--drivers/staging/comedi/drivers/adv_pci_dio.c1077
-rw-r--r--drivers/staging/comedi/drivers/aio_aio12_8.c226
-rw-r--r--drivers/staging/comedi/drivers/aio_iiro_16.c177
-rw-r--r--drivers/staging/comedi/drivers/am9513.h79
-rw-r--r--drivers/staging/comedi/drivers/amcc_s5933.h172
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.c1483
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236.c654
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc263.c431
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci224.c1545
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci230.c2977
-rw-r--r--drivers/staging/comedi/drivers/c6xdigio.c517
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c976
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas.c1831
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas64.c4222
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidda.c841
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidio.c294
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdas.c484
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdda.c474
-rw-r--r--drivers/staging/comedi/drivers/comedi_bond.c56
-rw-r--r--drivers/staging/comedi/drivers/comedi_fc.c14
-rw-r--r--drivers/staging/comedi/drivers/comedi_fc.h18
-rw-r--r--drivers/staging/comedi/drivers/comedi_parport.c44
-rw-r--r--drivers/staging/comedi/drivers/comedi_rt_timer.c728
-rw-r--r--drivers/staging/comedi/drivers/comedi_test.c80
-rw-r--r--drivers/staging/comedi/drivers/contec_pci_dio.c230
-rw-r--r--drivers/staging/comedi/drivers/daqboard2000.c877
-rw-r--r--drivers/staging/comedi/drivers/das08.c1068
-rw-r--r--drivers/staging/comedi/drivers/das08.h78
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c488
-rw-r--r--drivers/staging/comedi/drivers/das16.c1730
-rw-r--r--drivers/staging/comedi/drivers/das16m1.c765
-rw-r--r--drivers/staging/comedi/drivers/das1800.c1758
-rw-r--r--drivers/staging/comedi/drivers/das6402.c354
-rw-r--r--drivers/staging/comedi/drivers/das800.c894
-rw-r--r--drivers/staging/comedi/drivers/dmm32at.c1081
-rw-r--r--drivers/staging/comedi/drivers/dt2801.c697
-rw-r--r--drivers/staging/comedi/drivers/dt2811.c604
-rw-r--r--drivers/staging/comedi/drivers/dt2814.c383
-rw-r--r--drivers/staging/comedi/drivers/dt2815.c264
-rw-r--r--drivers/staging/comedi/drivers/dt2817.c178
-rw-r--r--drivers/staging/comedi/drivers/dt282x.c1471
-rw-r--r--drivers/staging/comedi/drivers/dt3000.c983
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c40
-rw-r--r--drivers/staging/comedi/drivers/fl512.c186
-rw-r--r--drivers/staging/comedi/drivers/gsc_hpdi.c1060
-rw-r--r--drivers/staging/comedi/drivers/icp_multi.c392
-rw-r--r--drivers/staging/comedi/drivers/icp_multi.h19
-rw-r--r--drivers/staging/comedi/drivers/ii_pci20kc.c612
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.c976
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.h681
-rw-r--r--drivers/staging/comedi/drivers/ke_counter.c254
-rw-r--r--drivers/staging/comedi/drivers/me4000.c296
-rw-r--r--drivers/staging/comedi/drivers/me4000.h268
-rw-r--r--drivers/staging/comedi/drivers/me_daq.c55
-rw-r--r--drivers/staging/comedi/drivers/mite.c63
-rw-r--r--drivers/staging/comedi/drivers/mite.h68
-rw-r--r--drivers/staging/comedi/drivers/mpc624.c386
-rw-r--r--drivers/staging/comedi/drivers/mpc8260cpm.c169
-rw-r--r--drivers/staging/comedi/drivers/multiq3.c333
-rw-r--r--drivers/staging/comedi/drivers/ni_6527.c489
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c809
-rw-r--r--drivers/staging/comedi/drivers/ni_660x.c1324
-rw-r--r--drivers/staging/comedi/drivers/ni_670x.c337
-rw-r--r--drivers/staging/comedi/drivers/ni_at_a2150.c909
-rw-r--r--drivers/staging/comedi/drivers/ni_at_ao.c454
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c513
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio16d.c860
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c841
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c598
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c2005
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.h85
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_cs.c573
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c5862
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c551
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c1302
-rw-r--r--drivers/staging/comedi/drivers/ni_pcimio.c1788
-rw-r--r--drivers/staging/comedi/drivers/ni_stc.h1498
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.c1691
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.h163
-rw-r--r--drivers/staging/comedi/drivers/ni_tio_internal.h774
-rw-r--r--drivers/staging/comedi/drivers/ni_tiocmd.c523
-rw-r--r--drivers/staging/comedi/drivers/pcl711.c623
-rw-r--r--drivers/staging/comedi/drivers/pcl724.c222
-rw-r--r--drivers/staging/comedi/drivers/pcl725.c111
-rw-r--r--drivers/staging/comedi/drivers/pcl726.c377
-rw-r--r--drivers/staging/comedi/drivers/pcl730.c168
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c1605
-rw-r--r--drivers/staging/comedi/drivers/pcl816.c1251
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c1988
-rw-r--r--drivers/staging/comedi/drivers/pcm3724.c307
-rw-r--r--drivers/staging/comedi/drivers/pcm3730.c152
-rw-r--r--drivers/staging/comedi/drivers/pcmad.c173
-rw-r--r--drivers/staging/comedi/drivers/pcmda12.c306
-rw-r--r--drivers/staging/comedi/drivers/pcmmio.c1333
-rw-r--r--drivers/staging/comedi/drivers/pcmuio.c1101
-rw-r--r--drivers/staging/comedi/drivers/plx9052.h86
-rw-r--r--drivers/staging/comedi/drivers/plx9080.h80
-rw-r--r--drivers/staging/comedi/drivers/poc.c247
-rw-r--r--drivers/staging/comedi/drivers/quatech_daqp_cs.c1363
-rw-r--r--drivers/staging/comedi/drivers/rtd520.c277
-rw-r--r--drivers/staging/comedi/drivers/rtd520.h676
-rw-r--r--drivers/staging/comedi/drivers/rti800.c458
-rw-r--r--drivers/staging/comedi/drivers/rti802.c151
-rw-r--r--drivers/staging/comedi/drivers/s526.c977
-rw-r--r--drivers/staging/comedi/drivers/s626.c2538
-rw-r--r--drivers/staging/comedi/drivers/s626.h1226
-rw-r--r--drivers/staging/comedi/drivers/serial2002.c870
-rw-r--r--drivers/staging/comedi/drivers/skel.c624
-rw-r--r--drivers/staging/comedi/drivers/ssv_dnp.c311
-rw-r--r--drivers/staging/comedi/drivers/unioxx5.c515
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c304
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c2028
-rw-r--r--drivers/staging/comedi/interrupt.h9
-rw-r--r--drivers/staging/comedi/kcomedilib/data.c22
-rw-r--r--drivers/staging/comedi/kcomedilib/dio.c18
-rw-r--r--drivers/staging/comedi/kcomedilib/get.c132
-rw-r--r--drivers/staging/comedi/kcomedilib/kcomedilib_main.c138
-rw-r--r--drivers/staging/comedi/kcomedilib/ksyms.c4
-rw-r--r--drivers/staging/comedi/pci_ids.h2
-rw-r--r--drivers/staging/comedi/proc.c17
-rw-r--r--drivers/staging/comedi/range.c35
-rw-r--r--drivers/staging/comedi/rt.c29
-rw-r--r--drivers/staging/comedi/rt_pend_tq.c8
-rw-r--r--drivers/staging/dst/Kconfig67
-rw-r--r--drivers/staging/dst/Makefile3
-rw-r--r--drivers/staging/dst/crypto.c731
-rw-r--r--drivers/staging/dst/dcore.c995
-rw-r--r--drivers/staging/dst/export.c657
-rw-r--r--drivers/staging/dst/state.c839
-rw-r--r--drivers/staging/dst/thread_pool.c345
-rw-r--r--drivers/staging/dst/trans.c335
-rw-r--r--drivers/staging/echo/bit_operations.h30
-rw-r--r--drivers/staging/echo/echo.c42
-rw-r--r--drivers/staging/echo/echo.h2
-rw-r--r--drivers/staging/echo/fir.h28
-rw-r--r--drivers/staging/echo/mmx.h408
-rw-r--r--drivers/staging/epl/Benchmark.h12
-rw-r--r--drivers/staging/epl/Debug.h48
-rw-r--r--drivers/staging/epl/Edrv8139.c108
-rw-r--r--drivers/staging/epl/EdrvFec.h6
-rw-r--r--drivers/staging/epl/EdrvFec5282.h340
-rw-r--r--drivers/staging/epl/EdrvSim.h4
-rw-r--r--drivers/staging/epl/Epl.h139
-rw-r--r--drivers/staging/epl/EplAmi.h121
-rw-r--r--drivers/staging/epl/EplApiGeneric.c188
-rw-r--r--drivers/staging/epl/EplApiLinuxKernel.c105
-rw-r--r--drivers/staging/epl/EplApiProcessImage.c31
-rw-r--r--drivers/staging/epl/EplDll.h50
-rw-r--r--drivers/staging/epl/EplDllCal.h2
-rw-r--r--drivers/staging/epl/EplDllk.c134
-rw-r--r--drivers/staging/epl/EplDllkCal.c14
-rw-r--r--drivers/staging/epl/EplDlluCal.c6
-rw-r--r--drivers/staging/epl/EplErrorHandlerk.c36
-rw-r--r--drivers/staging/epl/EplEvent.h8
-rw-r--r--drivers/staging/epl/EplEventk.c24
-rw-r--r--drivers/staging/epl/EplEventu.c25
-rw-r--r--drivers/staging/epl/EplFrame.h166
-rw-r--r--drivers/staging/epl/EplIdentu.c26
-rw-r--r--drivers/staging/epl/EplInc.h23
-rw-r--r--drivers/staging/epl/EplInstDef.h60
-rw-r--r--drivers/staging/epl/EplNmt.h2
-rw-r--r--drivers/staging/epl/EplNmtCnu.c39
-rw-r--r--drivers/staging/epl/EplNmtMnu.c121
-rw-r--r--drivers/staging/epl/EplNmtk.c30
-rw-r--r--drivers/staging/epl/EplNmtkCal.c2
-rw-r--r--drivers/staging/epl/EplNmtu.c22
-rw-r--r--drivers/staging/epl/EplNmtuCal.c2
-rw-r--r--drivers/staging/epl/EplObd.c444
-rw-r--r--drivers/staging/epl/EplObd.h58
-rw-r--r--drivers/staging/epl/EplObdMacro.h40
-rw-r--r--drivers/staging/epl/EplObdkCal.c1
-rw-r--r--drivers/staging/epl/EplObdu.c69
-rw-r--r--drivers/staging/epl/EplObduCal.c75
-rw-r--r--drivers/staging/epl/EplObjDef.h208
-rw-r--r--drivers/staging/epl/EplPdo.h6
-rw-r--r--drivers/staging/epl/EplPdok.c73
-rw-r--r--drivers/staging/epl/EplPdou.c34
-rw-r--r--drivers/staging/epl/EplSdo.h24
-rw-r--r--drivers/staging/epl/EplSdoAsndu.c26
-rw-r--r--drivers/staging/epl/EplSdoAsySequ.c72
-rw-r--r--drivers/staging/epl/EplSdoComu.c153
-rw-r--r--drivers/staging/epl/EplSdoUdpu.c163
-rw-r--r--drivers/staging/epl/EplStatusu.c19
-rw-r--r--drivers/staging/epl/EplTarget.h109
-rw-r--r--drivers/staging/epl/EplTimer.h3
-rw-r--r--drivers/staging/epl/EplTimeruLinuxKernel.c26
-rw-r--r--drivers/staging/epl/EplTimeruNull.c312
-rw-r--r--drivers/staging/epl/EplTimeruWin32.c513
-rw-r--r--drivers/staging/epl/SharedBuff.c111
-rw-r--r--drivers/staging/epl/SharedBuff.h17
-rw-r--r--drivers/staging/epl/ShbIpc-LinuxKernel.c48
-rw-r--r--drivers/staging/epl/ShbIpc-Win32.c1202
-rw-r--r--drivers/staging/epl/ShbIpc.h26
-rw-r--r--drivers/staging/epl/TimerHighReskX86.c34
-rw-r--r--drivers/staging/epl/VirtualEthernetLinux.c5
-rw-r--r--drivers/staging/epl/amix86.c316
-rw-r--r--drivers/staging/epl/demo_main.c84
-rw-r--r--drivers/staging/epl/edrv.h22
-rw-r--r--drivers/staging/epl/global.h1253
-rw-r--r--drivers/staging/epl/kernel/EplDllk.h24
-rw-r--r--drivers/staging/epl/kernel/EplDllkCal.h14
-rw-r--r--drivers/staging/epl/kernel/EplErrorHandlerk.h20
-rw-r--r--drivers/staging/epl/kernel/EplEventk.h28
-rw-r--r--drivers/staging/epl/kernel/EplNmtk.h25
-rw-r--r--drivers/staging/epl/kernel/EplNmtkCal.h89
-rw-r--r--drivers/staging/epl/kernel/EplObdk.h122
-rw-r--r--drivers/staging/epl/kernel/EplObdkCal.h89
-rw-r--r--drivers/staging/epl/kernel/EplPdok.h12
-rw-r--r--drivers/staging/epl/kernel/EplPdokCal.h13
-rw-r--r--drivers/staging/epl/kernel/EplTimerHighResk.h43
-rw-r--r--drivers/staging/epl/kernel/EplTimerk.h36
-rw-r--r--drivers/staging/epl/kernel/VirtualEthernet.h16
-rw-r--r--drivers/staging/epl/proc_fs.c23
-rw-r--r--drivers/staging/epl/user/EplCfgMau.h80
-rw-r--r--drivers/staging/epl/user/EplDllu.h14
-rw-r--r--drivers/staging/epl/user/EplDlluCal.h15
-rw-r--r--drivers/staging/epl/user/EplEventu.h28
-rw-r--r--drivers/staging/epl/user/EplIdentu.h34
-rw-r--r--drivers/staging/epl/user/EplLedu.h32
-rw-r--r--drivers/staging/epl/user/EplNmtCnu.h32
-rw-r--r--drivers/staging/epl/user/EplNmtMnu.h42
-rw-r--r--drivers/staging/epl/user/EplNmtu.h38
-rw-r--r--drivers/staging/epl/user/EplNmtuCal.h17
-rw-r--r--drivers/staging/epl/user/EplObdu.h83
-rw-r--r--drivers/staging/epl/user/EplObduCal.h94
-rw-r--r--drivers/staging/epl/user/EplPdou.h22
-rw-r--r--drivers/staging/epl/user/EplSdoAsndu.h33
-rw-r--r--drivers/staging/epl/user/EplSdoAsySequ.h41
-rw-r--r--drivers/staging/epl/user/EplSdoComu.h48
-rw-r--r--drivers/staging/epl/user/EplSdoUdpu.h34
-rw-r--r--drivers/staging/epl/user/EplStatusu.h32
-rw-r--r--drivers/staging/epl/user/EplTimeru.h38
-rw-r--r--drivers/staging/et131x/et1310_rx.c3
-rw-r--r--drivers/staging/frontier/README53
-rw-r--r--drivers/staging/frontier/alphatrack.c383
-rw-r--r--drivers/staging/frontier/alphatrack.h80
-rw-r--r--drivers/staging/frontier/frontier_compat.h63
-rw-r--r--drivers/staging/frontier/surface_sysfs.h100
-rw-r--r--drivers/staging/frontier/tranzport.c685
-rw-r--r--drivers/staging/go7007/Kconfig4
-rw-r--r--drivers/staging/go7007/go7007-v4l2.c1
-rw-r--r--drivers/staging/go7007/s2250-board.c7
-rw-r--r--drivers/staging/heci/Kconfig6
-rw-r--r--drivers/staging/heci/Makefile9
-rw-r--r--drivers/staging/heci/TODO6
-rw-r--r--drivers/staging/heci/heci.h176
-rw-r--r--drivers/staging/heci/heci_data_structures.h530
-rw-r--r--drivers/staging/heci/heci_init.c1077
-rw-r--r--drivers/staging/heci/heci_interface.c485
-rw-r--r--drivers/staging/heci/heci_interface.h170
-rw-r--r--drivers/staging/heci/heci_main.c1564
-rw-r--r--drivers/staging/heci/heci_version.h54
-rw-r--r--drivers/staging/heci/interrupt.c1553
-rw-r--r--drivers/staging/heci/io_heci.c847
-rw-r--r--drivers/staging/line6/Kconfig21
-rw-r--r--drivers/staging/line6/Makefile15
-rw-r--r--drivers/staging/line6/audio.c72
-rw-r--r--drivers/staging/line6/audio.h24
-rw-r--r--drivers/staging/line6/capture.c372
-rw-r--r--drivers/staging/line6/capture.h32
-rw-r--r--drivers/staging/line6/config.h48
-rw-r--r--drivers/staging/line6/control.c840
-rw-r--r--drivers/staging/line6/control.h187
-rw-r--r--drivers/staging/line6/driver.c1102
-rw-r--r--drivers/staging/line6/driver.h204
-rw-r--r--drivers/staging/line6/dumprequest.c151
-rw-r--r--drivers/staging/line6/dumprequest.h90
-rw-r--r--drivers/staging/line6/midi.c422
-rw-r--r--drivers/staging/line6/midi.h87
-rw-r--r--drivers/staging/line6/midibuf.c262
-rw-r--r--drivers/staging/line6/midibuf.h39
-rw-r--r--drivers/staging/line6/pcm.c301
-rw-r--r--drivers/staging/line6/pcm.h222
-rw-r--r--drivers/staging/line6/playback.c427
-rw-r--r--drivers/staging/line6/playback.h30
-rw-r--r--drivers/staging/line6/pod.c1151
-rw-r--r--drivers/staging/line6/pod.h204
-rw-r--r--drivers/staging/line6/revision.h4
-rw-r--r--drivers/staging/line6/toneport.c241
-rw-r--r--drivers/staging/line6/toneport.h45
-rw-r--r--drivers/staging/line6/usbdefs.h74
-rw-r--r--drivers/staging/line6/variax.c546
-rw-r--r--drivers/staging/line6/variax.h108
-rw-r--r--drivers/staging/me4000/me4000.c193
-rw-r--r--drivers/staging/meilhaus/me0600_device.c4
-rw-r--r--drivers/staging/meilhaus/me0600_dio.c18
-rw-r--r--drivers/staging/meilhaus/me0600_ext_irq.c8
-rw-r--r--drivers/staging/meilhaus/me0600_optoi.c14
-rw-r--r--drivers/staging/meilhaus/me0600_relay.c14
-rw-r--r--drivers/staging/meilhaus/me0600_ttli.c12
-rw-r--r--drivers/staging/meilhaus/me0900_device.c4
-rw-r--r--drivers/staging/meilhaus/me0900_di.c12
-rw-r--r--drivers/staging/meilhaus/me0900_do.c14
-rw-r--r--drivers/staging/meilhaus/me1000_device.c8
-rw-r--r--drivers/staging/meilhaus/me1000_dio.c4
-rw-r--r--drivers/staging/meilhaus/me1400_device.c4
-rw-r--r--drivers/staging/meilhaus/me1400_ext_irq.c7
-rw-r--r--drivers/staging/meilhaus/me1600_ao.c70
-rw-r--r--drivers/staging/meilhaus/me1600_ao.h4
-rw-r--r--drivers/staging/meilhaus/me1600_device.c8
-rw-r--r--drivers/staging/meilhaus/me4600_ai.c157
-rw-r--r--drivers/staging/meilhaus/me4600_ai.h4
-rw-r--r--drivers/staging/meilhaus/me4600_ao.c191
-rw-r--r--drivers/staging/meilhaus/me4600_ao.h4
-rw-r--r--drivers/staging/meilhaus/me4600_device.c4
-rw-r--r--drivers/staging/meilhaus/me4600_di.c14
-rw-r--r--drivers/staging/meilhaus/me4600_dio.c16
-rw-r--r--drivers/staging/meilhaus/me4600_do.c16
-rw-r--r--drivers/staging/meilhaus/me4600_ext_irq.c21
-rw-r--r--drivers/staging/meilhaus/me6000_ao.c146
-rw-r--r--drivers/staging/meilhaus/me6000_ao.h4
-rw-r--r--drivers/staging/meilhaus/me6000_device.c4
-rw-r--r--drivers/staging/meilhaus/me6000_dio.c16
-rw-r--r--drivers/staging/meilhaus/me8100_device.c4
-rw-r--r--drivers/staging/meilhaus/me8100_di.c24
-rw-r--r--drivers/staging/meilhaus/me8100_do.c16
-rw-r--r--drivers/staging/meilhaus/me8200_device.c4
-rw-r--r--drivers/staging/meilhaus/me8200_di.c58
-rw-r--r--drivers/staging/meilhaus/me8200_dio.c16
-rw-r--r--drivers/staging/meilhaus/me8200_do.c26
-rw-r--r--drivers/staging/meilhaus/me8254.c14
-rw-r--r--drivers/staging/meilhaus/me8255.c4
-rw-r--r--drivers/staging/meilhaus/mecirc_buf.h16
-rw-r--r--drivers/staging/meilhaus/medevice.c14
-rw-r--r--drivers/staging/meilhaus/medlist.c6
-rw-r--r--drivers/staging/meilhaus/medlock.c4
-rw-r--r--drivers/staging/meilhaus/medummy.c84
-rw-r--r--drivers/staging/meilhaus/memain.c34
-rw-r--r--drivers/staging/meilhaus/meslist.c6
-rw-r--r--drivers/staging/meilhaus/meslock.c2
-rw-r--r--drivers/staging/meilhaus/mesubdevice.c12
-rw-r--r--drivers/staging/meilhaus/metempl_device.c4
-rw-r--r--drivers/staging/meilhaus/metempl_sub.c10
-rw-r--r--drivers/staging/mimio/Kconfig2
-rw-r--r--drivers/staging/otus/80211core/amsdu.c145
-rw-r--r--drivers/staging/otus/80211core/cmmsta.c5
-rw-r--r--drivers/staging/otus/80211core/coid.c8
-rw-r--r--drivers/staging/otus/80211core/cwm.c6
-rw-r--r--drivers/staging/otus/TODO9
-rw-r--r--drivers/staging/otus/hal/hpani.c46
-rw-r--r--drivers/staging/otus/hal/hpmain.c101
-rw-r--r--drivers/staging/otus/hal/hpreg.c9
-rw-r--r--drivers/staging/otus/hal/hprw.c30
-rw-r--r--drivers/staging/otus/hal/hpusb.c11
-rw-r--r--drivers/staging/otus/ioctl.c4789
-rw-r--r--drivers/staging/otus/usbdrv.c12
-rw-r--r--drivers/staging/otus/wwrap.c6
-rw-r--r--drivers/staging/otus/zdcompat.h7
-rw-r--r--drivers/staging/p9auth/Kconfig9
-rw-r--r--drivers/staging/p9auth/Makefile1
-rw-r--r--drivers/staging/p9auth/p9auth.c383
-rw-r--r--drivers/staging/panel/Kconfig2
-rw-r--r--drivers/staging/phison/Kconfig5
-rw-r--r--drivers/staging/phison/Makefile1
-rw-r--r--drivers/staging/phison/phison.c106
-rw-r--r--drivers/staging/pohmelfs/Kconfig28
-rw-r--r--drivers/staging/pohmelfs/Makefile3
-rw-r--r--drivers/staging/pohmelfs/config.c478
-rw-r--r--drivers/staging/pohmelfs/crypto.c880
-rw-r--r--drivers/staging/pohmelfs/dir.c1093
-rw-r--r--drivers/staging/pohmelfs/inode.c1976
-rw-r--r--drivers/staging/pohmelfs/lock.c182
-rw-r--r--drivers/staging/pohmelfs/mcache.c171
-rw-r--r--drivers/staging/pohmelfs/net.c1247
-rw-r--r--drivers/staging/pohmelfs/netfs.h932
-rw-r--r--drivers/staging/pohmelfs/path_entry.c114
-rw-r--r--drivers/staging/pohmelfs/trans.c715
-rw-r--r--drivers/staging/rspiusb/rspiusb.c5
-rw-r--r--drivers/staging/rt2860/2860_main_dev.c50
-rw-r--r--drivers/staging/rt2860/Makefile1
-rw-r--r--drivers/staging/rt2860/TODO4
-rw-r--r--drivers/staging/rt2860/common/cmm_data.c27
-rw-r--r--drivers/staging/rt2860/common/cmm_data_2860.c144
-rw-r--r--drivers/staging/rt2860/common/cmm_info.c6
-rw-r--r--drivers/staging/rt2860/common/cmm_sync.c2
-rw-r--r--drivers/staging/rt2860/common/cmm_wpa.c40
-rw-r--r--drivers/staging/rt2860/common/mlme.c289
-rw-r--r--drivers/staging/rt2860/common/rtmp_init.c157
-rw-r--r--drivers/staging/rt2860/common/spectrum.c2
-rw-r--r--drivers/staging/rt2860/config.mk4
-rw-r--r--drivers/staging/rt2860/oid.h2
-rw-r--r--drivers/staging/rt2860/rt2860.h22
-rw-r--r--drivers/staging/rt2860/rt28xx.h4
-rw-r--r--drivers/staging/rt2860/rt_ate.c18
-rw-r--r--drivers/staging/rt2860/rt_ate.h6
-rw-r--r--drivers/staging/rt2860/rt_config.h2
-rw-r--r--drivers/staging/rt2860/rt_linux.c29
-rw-r--r--drivers/staging/rt2860/rt_linux.h49
-rw-r--r--drivers/staging/rt2860/rt_main_dev.c149
-rw-r--r--drivers/staging/rt2860/rt_profile.c2
-rw-r--r--drivers/staging/rt2860/rtmp.h61
-rw-r--r--drivers/staging/rt2860/rtmp_def.h29
-rw-r--r--drivers/staging/rt2860/sta/assoc.c23
-rw-r--r--drivers/staging/rt2860/sta/connect.c45
-rw-r--r--drivers/staging/rt2860/sta/dls.c4
-rw-r--r--drivers/staging/rt2860/sta/rtmp_data.c29
-rw-r--r--drivers/staging/rt2860/sta/sync.c16
-rw-r--r--drivers/staging/rt2860/sta/wpa.c10
-rw-r--r--drivers/staging/rt2860/sta_ioctl.c96
-rw-r--r--drivers/staging/rt2860/wpa.h1
-rw-r--r--drivers/staging/rt2870/2870_main_dev.c67
-rw-r--r--drivers/staging/rt2870/TODO9
-rw-r--r--drivers/staging/rt2870/common/2870_rtmp_init.c35
-rw-r--r--drivers/staging/rt2870/common/cmm_data.c3
-rw-r--r--drivers/staging/rt2870/common/rtmp_init.c2
-rw-r--r--drivers/staging/rt2870/common/rtusb_io.c3
-rw-r--r--drivers/staging/rt2870/common/spectrum.c2
-rw-r--r--drivers/staging/rt2870/rt2870.h7
-rw-r--r--drivers/staging/rt2870/rt_linux.c2
-rw-r--r--drivers/staging/rt2870/rt_linux.h12
-rw-r--r--drivers/staging/rt2870/sta_ioctl.c2
-rw-r--r--drivers/staging/rt3070/2870_main_dev.c1627
-rw-r--r--drivers/staging/rt3070/Kconfig6
-rw-r--r--drivers/staging/rt3070/Makefile47
-rw-r--r--drivers/staging/rt3070/action.h68
-rw-r--r--drivers/staging/rt3070/aironet.h210
-rw-r--r--drivers/staging/rt3070/ap.h557
-rw-r--r--drivers/staging/rt3070/chlist.h1253
-rw-r--r--drivers/staging/rt3070/common/2870_rtmp_init.c1762
-rw-r--r--drivers/staging/rt3070/common/action.c1038
-rw-r--r--drivers/staging/rt3070/common/ba_action.c1810
-rw-r--r--drivers/staging/rt3070/common/cmm_data.c2827
-rw-r--r--drivers/staging/rt3070/common/cmm_data_2870.c980
-rw-r--r--drivers/staging/rt3070/common/cmm_info.c3395
-rw-r--r--drivers/staging/rt3070/common/cmm_sanity.c1669
-rw-r--r--drivers/staging/rt3070/common/cmm_sync.c711
-rw-r--r--drivers/staging/rt3070/common/cmm_wpa.c1606
-rw-r--r--drivers/staging/rt3070/common/dfs.c441
-rw-r--r--drivers/staging/rt3070/common/eeprom.c1498
-rw-r--r--drivers/staging/rt3070/common/md5.c1427
-rw-r--r--drivers/staging/rt3070/common/mlme.c9136
-rw-r--r--drivers/staging/rt3070/common/netif_block.c136
-rw-r--r--drivers/staging/rt3070/common/rtmp_init.c4197
-rw-r--r--drivers/staging/rt3070/common/rtmp_tkip.c1613
-rw-r--r--drivers/staging/rt3070/common/rtmp_wep.c508
-rw-r--r--drivers/staging/rt3070/common/rtusb_bulk.c1382
-rw-r--r--drivers/staging/rt3070/common/rtusb_data.c218
-rw-r--r--drivers/staging/rt3070/common/rtusb_io.c1908
-rw-r--r--drivers/staging/rt3070/common/spectrum.c1876
-rw-r--r--drivers/staging/rt3070/dfs.h100
-rw-r--r--drivers/staging/rt3070/firmware.h558
-rw-r--r--drivers/staging/rt3070/leap.h215
-rw-r--r--drivers/staging/rt3070/link_list.h134
-rw-r--r--drivers/staging/rt3070/md4.h42
-rw-r--r--drivers/staging/rt3070/md5.h107
-rw-r--r--drivers/staging/rt3070/mlme.h1468
-rw-r--r--drivers/staging/rt3070/netif_block.h58
-rw-r--r--drivers/staging/rt3070/oid.h1142
-rw-r--r--drivers/staging/rt3070/rt2870.h756
-rw-r--r--drivers/staging/rt3070/rt28xx.h2725
-rw-r--r--drivers/staging/rt3070/rt_ate.c6506
-rw-r--r--drivers/staging/rt3070/rt_ate.h294
-rw-r--r--drivers/staging/rt3070/rt_config.h121
-rw-r--r--drivers/staging/rt3070/rt_linux.c1063
-rw-r--r--drivers/staging/rt3070/rt_linux.h887
-rw-r--r--drivers/staging/rt3070/rt_main_dev.c1800
-rw-r--r--drivers/staging/rt3070/rt_profile.c2041
-rw-r--r--drivers/staging/rt3070/rtmp.h7728
-rw-r--r--drivers/staging/rt3070/rtmp_ckipmic.h113
-rw-r--r--drivers/staging/rt3070/rtmp_def.h1559
-rw-r--r--drivers/staging/rt3070/rtmp_type.h95
-rw-r--r--drivers/staging/rt3070/spectrum.h322
-rw-r--r--drivers/staging/rt3070/spectrum_def.h95
-rw-r--r--drivers/staging/rt3070/sta/aironet.c1312
-rw-r--r--drivers/staging/rt3070/sta/assoc.c2060
-rw-r--r--drivers/staging/rt3070/sta/auth.c475
-rw-r--r--drivers/staging/rt3070/sta/auth_rsp.c167
-rw-r--r--drivers/staging/rt3070/sta/connect.c2857
-rw-r--r--drivers/staging/rt3070/sta/dls.c2170
-rw-r--r--drivers/staging/rt3070/sta/rtmp_data.c2637
-rw-r--r--drivers/staging/rt3070/sta/sanity.c420
-rw-r--r--drivers/staging/rt3070/sta/sync.c1755
-rw-r--r--drivers/staging/rt3070/sta/wpa.c2099
-rw-r--r--drivers/staging/rt3070/sta_ioctl.c7203
-rw-r--r--drivers/staging/rt3070/wpa.h356
-rw-r--r--drivers/staging/rtl8187se/dot11d.h202
-rw-r--r--drivers/staging/rtl8187se/ieee80211/dot11d.c492
-rw-r--r--drivers/staging/rtl8187se/ieee80211/dot11d.h204
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c4
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c2
-rw-r--r--drivers/staging/rtl8187se/r8180_dm.c3450
-rw-r--r--drivers/staging/rtl8187se/r8180_dm.h82
-rw-r--r--drivers/staging/rtl8187se/r8180_wx.c12
-rw-r--r--drivers/staging/serqt_usb/Kconfig9
-rw-r--r--drivers/staging/serqt_usb/Makefile1
-rw-r--r--drivers/staging/serqt_usb/TODO8
-rw-r--r--drivers/staging/serqt_usb/serqt_usb.c2656
-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.h86
-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.h1038
-rw-r--r--drivers/staging/slicoss/slicinc.h185
-rw-r--r--drivers/staging/slicoss/slicoss.c2917
-rw-r--r--drivers/staging/stlc45xx/Kconfig8
-rw-r--r--drivers/staging/stlc45xx/Makefile1
-rw-r--r--drivers/staging/stlc45xx/stlc45xx.c2606
-rw-r--r--drivers/staging/stlc45xx/stlc45xx.h283
-rw-r--r--drivers/staging/stlc45xx/stlc45xx_lmac.h434
-rw-r--r--drivers/staging/sxg/Kconfig2
-rw-r--r--drivers/staging/sxg/Makefile4
-rw-r--r--drivers/staging/sxg/saharadbgdownload.h4854
-rw-r--r--drivers/staging/sxg/sxg.c2893
-rw-r--r--drivers/staging/sxg/sxg.h919
-rw-r--r--drivers/staging/sxg/sxg_ethtool.c328
-rw-r--r--drivers/staging/sxg/sxg_os.h100
-rw-r--r--drivers/staging/sxg/sxgdbg.h129
-rw-r--r--drivers/staging/sxg/sxghif.h1110
-rw-r--r--drivers/staging/sxg/sxghw.h1564
-rw-r--r--drivers/staging/sxg/sxgphycode-1.2.h130
-rw-r--r--drivers/staging/sxg/sxgphycode.h349
-rw-r--r--drivers/staging/uc2322/Kconfig10
-rw-r--r--drivers/staging/uc2322/Makefile1
-rw-r--r--drivers/staging/uc2322/TODO7
-rw-r--r--drivers/staging/uc2322/aten2011.c2452
-rw-r--r--drivers/staging/usbip/stub_rx.c4
-rw-r--r--drivers/staging/usbip/vhci_sysfs.c3
-rw-r--r--drivers/staging/winbond/bss_f.h63
-rw-r--r--drivers/staging/winbond/bssdscpt.h164
-rw-r--r--drivers/staging/winbond/common.h27
-rw-r--r--drivers/staging/winbond/core.h7
-rw-r--r--drivers/staging/winbond/ds_tkip.h37
-rw-r--r--drivers/staging/winbond/gl_80211.h126
-rw-r--r--drivers/staging/winbond/ioctls.h678
-rw-r--r--drivers/staging/winbond/mds.c26
-rw-r--r--drivers/staging/winbond/mds_s.h24
-rw-r--r--drivers/staging/winbond/mlme_mib.h84
-rw-r--r--drivers/staging/winbond/mlmetxrx.c2
-rw-r--r--drivers/staging/winbond/mto.c24
-rw-r--r--drivers/staging/winbond/mto.h12
-rw-r--r--drivers/staging/winbond/mto_f.h13
-rw-r--r--drivers/staging/winbond/os_common.h2
-rw-r--r--drivers/staging/winbond/phy_calibration.c28
-rw-r--r--drivers/staging/winbond/phy_calibration.h2
-rw-r--r--drivers/staging/winbond/reg.c81
-rw-r--r--drivers/staging/winbond/sme_api.h3
-rw-r--r--drivers/staging/winbond/sme_s.h236
-rw-r--r--drivers/staging/winbond/wb35_ver.h30
-rw-r--r--drivers/staging/winbond/wb35reg.c41
-rw-r--r--drivers/staging/winbond/wb35reg_f.h70
-rw-r--r--drivers/staging/winbond/wb35rx.c43
-rw-r--r--drivers/staging/winbond/wb35rx_f.h6
-rw-r--r--drivers/staging/winbond/wb35rx_s.h8
-rw-r--r--drivers/staging/winbond/wb35tx.c54
-rw-r--r--drivers/staging/winbond/wb35tx_f.h8
-rw-r--r--drivers/staging/winbond/wb35tx_s.h6
-rw-r--r--drivers/staging/winbond/wbhal.c50
-rw-r--r--drivers/staging/winbond/wbhal_f.h94
-rw-r--r--drivers/staging/winbond/wbhal_s.h87
-rw-r--r--drivers/staging/winbond/wbusb.c20
-rw-r--r--drivers/staging/winbond/wbusb_s.h16
-rw-r--r--drivers/staging/wlan-ng/README4
-rw-r--r--drivers/staging/wlan-ng/hfa384x.h2638
-rw-r--r--drivers/staging/wlan-ng/hfa384x_usb.c2295
-rw-r--r--drivers/staging/wlan-ng/p80211conv.c377
-rw-r--r--drivers/staging/wlan-ng/p80211conv.h131
-rw-r--r--drivers/staging/wlan-ng/p80211hdr.h146
-rw-r--r--drivers/staging/wlan-ng/p80211ioctl.h46
-rw-r--r--drivers/staging/wlan-ng/p80211meta.h110
-rw-r--r--drivers/staging/wlan-ng/p80211metadef.h544
-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.h424
-rw-r--r--drivers/staging/wlan-ng/p80211mgmt.h441
-rw-r--r--drivers/staging/wlan-ng/p80211msg.h48
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.c411
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.h218
-rw-r--r--drivers/staging/wlan-ng/p80211req.c235
-rw-r--r--drivers/staging/wlan-ng/p80211req.h17
-rw-r--r--drivers/staging/wlan-ng/p80211types.h505
-rw-r--r--drivers/staging/wlan-ng/p80211wep.c24
-rw-r--r--drivers/staging/wlan-ng/p80211wext.c1214
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.c899
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.h69
-rw-r--r--drivers/staging/wlan-ng/prism2mib.c905
-rw-r--r--drivers/staging/wlan-ng/prism2sta.c1561
-rw-r--r--drivers/staging/wlan-ng/prism2usb.c158
-rw-r--r--drivers/staging/wlan-ng/wlan_compat.h193
-rw-r--r--drivers/thermal/thermal_sys.c356
-rw-r--r--drivers/usb/atm/ueagle-atm.c2
-rw-r--r--drivers/usb/class/cdc-acm.c9
-rw-r--r--drivers/usb/gadget/Kconfig2
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c14
-rw-r--r--drivers/usb/host/ehci-hcd.c2
-rw-r--r--drivers/usb/host/ehci-pci.c2
-rw-r--r--drivers/usb/host/ehci-ps3.c2
-rw-r--r--drivers/usb/host/ohci-at91.c4
-rw-r--r--drivers/usb/host/ohci-ps3.c2
-rw-r--r--drivers/usb/otg/nop-usb-xceiv.c4
-rw-r--r--drivers/usb/serial/ChangeLog.history2
-rw-r--r--drivers/usb/serial/Kconfig4
-rw-r--r--drivers/usb/serial/pl2303.c1
-rw-r--r--drivers/usb/serial/pl2303.h4
-rw-r--r--drivers/usb/serial/symbolserial.c67
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c26
-rw-r--r--drivers/usb/storage/isd200.c239
-rw-r--r--drivers/usb/wusbcore/security.c2
-rw-r--r--drivers/uwb/Kconfig4
-rw-r--r--drivers/uwb/whci.c8
-rw-r--r--drivers/video/Kconfig9
-rw-r--r--drivers/video/aty/radeon_base.c4
-rw-r--r--drivers/video/backlight/Kconfig18
-rw-r--r--drivers/video/backlight/Makefile2
-rw-r--r--drivers/video/backlight/backlight.c3
-rw-r--r--drivers/video/backlight/jornada720_bl.c161
-rw-r--r--drivers/video/backlight/jornada720_lcd.c153
-rw-r--r--drivers/video/backlight/lcd.c3
-rw-r--r--drivers/video/backlight/mbp_nvidia_bl.c191
-rw-r--r--drivers/video/backlight/pwm_bl.c4
-rw-r--r--drivers/video/cirrusfb.c4
-rw-r--r--drivers/video/console/fbcon.c55
-rw-r--r--drivers/video/efifb.c7
-rw-r--r--drivers/video/fbmem.c19
-rw-r--r--drivers/video/fsl-diu-fb.c34
-rw-r--r--drivers/video/intelfb/intelfb.h2
-rw-r--r--drivers/video/intelfb/intelfb_i2c.c1
-rw-r--r--drivers/video/intelfb/intelfbdrv.c1
-rw-r--r--drivers/video/intelfb/intelfbhw.c5
-rw-r--r--drivers/video/mx3fb.c56
-rw-r--r--drivers/video/s3fb.c6
-rw-r--r--drivers/video/sa1100fb.c15
-rw-r--r--drivers/video/sa1100fb.h7
-rw-r--r--drivers/video/sis/sis_main.c2
-rw-r--r--drivers/video/skeletonfb.c8
-rw-r--r--drivers/video/tdfxfb.c267
-rw-r--r--drivers/video/uvesafb.c35
-rw-r--r--drivers/video/vfb.c11
-rw-r--r--drivers/w1/masters/ds1wm.c58
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c6
-rw-r--r--drivers/watchdog/i6300esb.c155
-rw-r--r--drivers/watchdog/ks8695_wdt.c6
-rw-r--r--drivers/watchdog/omap_wdt.c6
-rw-r--r--drivers/watchdog/orion5x_wdt.c57
-rw-r--r--drivers/watchdog/wdrtas.c13
-rw-r--r--drivers/xen/Kconfig2
-rw-r--r--drivers/xen/cpu_hotplug.c44
-rw-r--r--drivers/xen/manage.c5
-rw-r--r--firmware/.gitignore1
-rw-r--r--firmware/Makefile34
-rw-r--r--firmware/README.AddingFirmware34
-rw-r--r--firmware/WHENCE105
-rw-r--r--firmware/advansys/3550.bin.ihex317
-rw-r--r--firmware/advansys/38C0800.bin.ihex336
-rw-r--r--firmware/advansys/38C1600.bin.ihex398
-rw-r--r--firmware/advansys/mcode.bin.ihex147
-rw-r--r--firmware/av7110/Boot.S109
-rw-r--r--firmware/av7110/bootcode.bin.ihex15
-rw-r--r--firmware/bnx2/bnx2-mips-06-4.6.16.fw.ihex5805
-rw-r--r--firmware/bnx2/bnx2-mips-09-4.6.17.fw.ihex5816
-rw-r--r--firmware/bnx2/bnx2-rv2p-06-4.6.16.fw.ihex441
-rw-r--r--firmware/bnx2/bnx2-rv2p-09-4.6.15.fw.ihex490
-rw-r--r--firmware/ihex2fw.c (renamed from scripts/ihex2fw.c)0
-rw-r--r--firmware/myricom/lanai.bin.ihex4771
-rw-r--r--firmware/qlogic/1040.bin.ihex2111
-rw-r--r--firmware/qlogic/12160.bin.ihex1771
-rw-r--r--firmware/qlogic/1280.bin.ihex2008
-rw-r--r--firmware/qlogic/isp1000.bin.ihex1158
-rw-r--r--firmware/yamaha/yss225_registers.bin.ihex998
-rw-r--r--fs/Kconfig34
-rw-r--r--fs/Makefile4
-rw-r--r--fs/afs/Kconfig8
-rw-r--r--fs/afs/Makefile3
-rw-r--r--fs/afs/cache.c503
-rw-r--r--fs/afs/cache.h15
-rw-r--r--fs/afs/cell.c16
-rw-r--r--fs/afs/file.c220
-rw-r--r--fs/afs/inode.c31
-rw-r--r--fs/afs/internal.h53
-rw-r--r--fs/afs/main.c27
-rw-r--r--fs/afs/mntpt.c4
-rw-r--r--fs/afs/netdevices.c3
-rw-r--r--fs/afs/vlocation.c25
-rw-r--r--fs/afs/volume.c14
-rw-r--r--fs/afs/write.c21
-rw-r--r--fs/befs/debug.c1
-rw-r--r--fs/befs/super.c1
-rw-r--r--fs/bio.c3
-rw-r--r--fs/btrfs/async-thread.c7
-rw-r--r--fs/btrfs/ctree.c312
-rw-r--r--fs/btrfs/ctree.h84
-rw-r--r--fs/btrfs/delayed-ref.c1
-rw-r--r--fs/btrfs/disk-io.c8
-rw-r--r--fs/btrfs/extent-tree.c398
-rw-r--r--fs/btrfs/extent_io.c16
-rw-r--r--fs/btrfs/extent_map.c1
-rw-r--r--fs/btrfs/free-space-cache.c530
-rw-r--r--fs/btrfs/free-space-cache.h44
-rw-r--r--fs/btrfs/inode.c5
-rw-r--r--fs/btrfs/locking.c4
-rw-r--r--fs/btrfs/super.c54
-rw-r--r--fs/btrfs/transaction.c7
-rw-r--r--fs/btrfs/tree-log.c12
-rw-r--r--fs/btrfs/volumes.c41
-rw-r--r--fs/btrfs/volumes.h2
-rw-r--r--fs/buffer.c38
-rw-r--r--fs/cachefiles/Kconfig39
-rw-r--r--fs/cachefiles/Makefile18
-rw-r--r--fs/cachefiles/bind.c286
-rw-r--r--fs/cachefiles/daemon.c755
-rw-r--r--fs/cachefiles/interface.c449
-rw-r--r--fs/cachefiles/internal.h360
-rw-r--r--fs/cachefiles/key.c159
-rw-r--r--fs/cachefiles/main.c106
-rw-r--r--fs/cachefiles/namei.c771
-rw-r--r--fs/cachefiles/proc.c134
-rw-r--r--fs/cachefiles/rdwr.c879
-rw-r--r--fs/cachefiles/security.c116
-rw-r--r--fs/cachefiles/xattr.c291
-rw-r--r--fs/compat.c4
-rw-r--r--fs/compat_ioctl.c2
-rw-r--r--fs/debugfs/inode.c16
-rw-r--r--fs/direct-io.c2
-rw-r--r--fs/exofs/BUGS3
-rw-r--r--fs/exofs/Kbuild16
-rw-r--r--fs/exofs/Kconfig13
-rw-r--r--fs/exofs/common.h184
-rw-r--r--fs/exofs/dir.c672
-rw-r--r--fs/exofs/exofs.h180
-rw-r--r--fs/exofs/file.c87
-rw-r--r--fs/exofs/inode.c1303
-rw-r--r--fs/exofs/namei.c342
-rw-r--r--fs/exofs/osd.c153
-rw-r--r--fs/exofs/super.c584
-rw-r--r--fs/exofs/symlink.c57
-rw-r--r--fs/ext2/inode.c44
-rw-r--r--fs/ext3/Kconfig19
-rw-r--r--fs/ext3/file.c4
-rw-r--r--fs/ext3/inode.c26
-rw-r--r--fs/ext3/namei.c6
-rw-r--r--fs/ext3/super.c8
-rw-r--r--fs/ext4/Kconfig2
-rw-r--r--fs/ext4/extents.c2
-rw-r--r--fs/ext4/inode.c8
-rw-r--r--fs/ext4/super.c9
-rw-r--r--fs/file_table.c1
-rw-r--r--fs/fs-writeback.c2
-rw-r--r--fs/fscache/Kconfig56
-rw-r--r--fs/fscache/Makefile19
-rw-r--r--fs/fscache/cache.c415
-rw-r--r--fs/fscache/cookie.c500
-rw-r--r--fs/fscache/fsdef.c144
-rw-r--r--fs/fscache/histogram.c109
-rw-r--r--fs/fscache/internal.h380
-rw-r--r--fs/fscache/main.c124
-rw-r--r--fs/fscache/netfs.c103
-rw-r--r--fs/fscache/object.c810
-rw-r--r--fs/fscache/operation.c459
-rw-r--r--fs/fscache/page.c816
-rw-r--r--fs/fscache/proc.c68
-rw-r--r--fs/fscache/stats.c212
-rw-r--r--fs/fuse/dir.c1
-rw-r--r--fs/fuse/file.c58
-rw-r--r--fs/hfs/inode.c4
-rw-r--r--fs/hfs/mdb.c1
-rw-r--r--fs/jbd/commit.c28
-rw-r--r--fs/jbd/revoke.c24
-rw-r--r--fs/jbd/transaction.c2
-rw-r--r--fs/jbd2/commit.c13
-rw-r--r--fs/jffs2/acl.c4
-rw-r--r--fs/jffs2/malloc.c6
-rw-r--r--fs/libfs.c16
-rw-r--r--fs/lockd/svclock.c13
-rw-r--r--fs/nfs/Kconfig8
-rw-r--r--fs/nfs/Makefile1
-rw-r--r--fs/nfs/client.c14
-rw-r--r--fs/nfs/file.c40
-rw-r--r--fs/nfs/fscache-index.c337
-rw-r--r--fs/nfs/fscache.c523
-rw-r--r--fs/nfs/fscache.h220
-rw-r--r--fs/nfs/inode.c14
-rw-r--r--fs/nfs/internal.h4
-rw-r--r--fs/nfs/iostat.h18
-rw-r--r--fs/nfs/read.c27
-rw-r--r--fs/nfs/super.c47
-rw-r--r--fs/nfsd/Kconfig1
-rw-r--r--fs/nfsd/nfs3proc.c10
-rw-r--r--fs/nfsd/nfs4callback.c47
-rw-r--r--fs/nfsd/nfs4proc.c246
-rw-r--r--fs/nfsd/nfs4recover.c74
-rw-r--r--fs/nfsd/nfs4state.c1196
-rw-r--r--fs/nfsd/nfs4xdr.c633
-rw-r--r--fs/nfsd/nfsctl.c38
-rw-r--r--fs/nfsd/nfsproc.c3
-rw-r--r--fs/nfsd/nfssvc.c88
-rw-r--r--fs/nfsd/vfs.c37
-rw-r--r--fs/nilfs2/Makefile5
-rw-r--r--fs/nilfs2/alloc.c504
-rw-r--r--fs/nilfs2/alloc.h72
-rw-r--r--fs/nilfs2/bmap.c788
-rw-r--r--fs/nilfs2/bmap.h244
-rw-r--r--fs/nilfs2/bmap_union.h42
-rw-r--r--fs/nilfs2/btnode.c316
-rw-r--r--fs/nilfs2/btnode.h58
-rw-r--r--fs/nilfs2/btree.c2269
-rw-r--r--fs/nilfs2/btree.h117
-rw-r--r--fs/nilfs2/cpfile.c925
-rw-r--r--fs/nilfs2/cpfile.h45
-rw-r--r--fs/nilfs2/dat.c430
-rw-r--r--fs/nilfs2/dat.h52
-rw-r--r--fs/nilfs2/dir.c711
-rw-r--r--fs/nilfs2/direct.c436
-rw-r--r--fs/nilfs2/direct.h78
-rw-r--r--fs/nilfs2/file.c160
-rw-r--r--fs/nilfs2/gcdat.c84
-rw-r--r--fs/nilfs2/gcinode.c288
-rw-r--r--fs/nilfs2/ifile.c150
-rw-r--r--fs/nilfs2/ifile.h53
-rw-r--r--fs/nilfs2/inode.c785
-rw-r--r--fs/nilfs2/ioctl.c654
-rw-r--r--fs/nilfs2/mdt.c563
-rw-r--r--fs/nilfs2/mdt.h125
-rw-r--r--fs/nilfs2/namei.c474
-rw-r--r--fs/nilfs2/nilfs.h313
-rw-r--r--fs/nilfs2/page.c540
-rw-r--r--fs/nilfs2/page.h76
-rw-r--r--fs/nilfs2/recovery.c917
-rw-r--r--fs/nilfs2/sb.h102
-rw-r--r--fs/nilfs2/segbuf.c439
-rw-r--r--fs/nilfs2/segbuf.h201
-rw-r--r--fs/nilfs2/seglist.h85
-rw-r--r--fs/nilfs2/segment.c2977
-rw-r--r--fs/nilfs2/segment.h243
-rw-r--r--fs/nilfs2/sufile.c558
-rw-r--r--fs/nilfs2/sufile.h125
-rw-r--r--fs/nilfs2/super.c1326
-rw-r--r--fs/nilfs2/the_nilfs.c641
-rw-r--r--fs/nilfs2/the_nilfs.h298
-rw-r--r--fs/ocfs2/alloc.c57
-rw-r--r--fs/ocfs2/alloc.h3
-rw-r--r--fs/ocfs2/aops.c23
-rw-r--r--fs/ocfs2/cluster/heartbeat.c96
-rw-r--r--fs/ocfs2/cluster/heartbeat.h3
-rw-r--r--fs/ocfs2/cluster/nodemanager.c9
-rw-r--r--fs/ocfs2/dir.c2806
-rw-r--r--fs/ocfs2/dir.h57
-rw-r--r--fs/ocfs2/dlm/dlmcommon.h58
-rw-r--r--fs/ocfs2/dlm/dlmdebug.c87
-rw-r--r--fs/ocfs2/dlm/dlmdomain.c29
-rw-r--r--fs/ocfs2/dlm/dlmmaster.c387
-rw-r--r--fs/ocfs2/dlm/dlmthread.c20
-rw-r--r--fs/ocfs2/dlmglue.c46
-rw-r--r--fs/ocfs2/dlmglue.h2
-rw-r--r--fs/ocfs2/export.c84
-rw-r--r--fs/ocfs2/file.c8
-rw-r--r--fs/ocfs2/inode.c48
-rw-r--r--fs/ocfs2/inode.h5
-rw-r--r--fs/ocfs2/journal.c173
-rw-r--r--fs/ocfs2/journal.h77
-rw-r--r--fs/ocfs2/localalloc.c86
-rw-r--r--fs/ocfs2/namei.c250
-rw-r--r--fs/ocfs2/ocfs2.h76
-rw-r--r--fs/ocfs2/ocfs2_fs.h136
-rw-r--r--fs/ocfs2/ocfs2_lockid.h4
-rw-r--r--fs/ocfs2/suballoc.c254
-rw-r--r--fs/ocfs2/suballoc.h4
-rw-r--r--fs/ocfs2/super.c188
-rw-r--r--fs/ocfs2/xattr.c8
-rw-r--r--fs/ocfs2/xattr.h2
-rw-r--r--fs/partitions/check.c4
-rw-r--r--fs/proc/nommu.c2
-rw-r--r--fs/proc/task_mmu.c4
-rw-r--r--fs/proc/task_nommu.c4
-rw-r--r--fs/ramfs/inode.c19
-rw-r--r--fs/read_write.c14
-rw-r--r--fs/romfs/Kconfig48
-rw-r--r--fs/romfs/Makefile9
-rw-r--r--fs/romfs/inode.c665
-rw-r--r--fs/romfs/internal.h47
-rw-r--r--fs/romfs/mmap-nommu.c75
-rw-r--r--fs/romfs/storage.c261
-rw-r--r--fs/romfs/super.c653
-rw-r--r--fs/splice.c28
-rw-r--r--fs/squashfs/export.c1
-rw-r--r--fs/super.c41
-rw-r--r--fs/ubifs/Kconfig4
-rw-r--r--fs/ubifs/budget.c37
-rw-r--r--fs/ubifs/debug.c6
-rw-r--r--fs/ubifs/file.c16
-rw-r--r--fs/ubifs/find.c12
-rw-r--r--fs/ubifs/gc.c428
-rw-r--r--fs/ubifs/journal.c7
-rw-r--r--fs/ubifs/key.h6
-rw-r--r--fs/ubifs/log.c5
-rw-r--r--fs/ubifs/lpt_commit.c34
-rw-r--r--fs/ubifs/recovery.c70
-rw-r--r--fs/ubifs/replay.c2
-rw-r--r--fs/ubifs/sb.c36
-rw-r--r--fs/ubifs/shrinker.c6
-rw-r--r--fs/ubifs/super.c37
-rw-r--r--fs/ubifs/tnc.c2
-rw-r--r--fs/ubifs/ubifs-media.h30
-rw-r--r--fs/ubifs/ubifs.h13
-rw-r--r--fs/udf/balloc.c150
-rw-r--r--fs/udf/dir.c14
-rw-r--r--fs/udf/directory.c38
-rw-r--r--fs/udf/ecma_167.h416
-rw-r--r--fs/udf/ialloc.c9
-rw-r--r--fs/udf/inode.c213
-rw-r--r--fs/udf/misc.c29
-rw-r--r--fs/udf/namei.c86
-rw-r--r--fs/udf/osta_udf.h22
-rw-r--r--fs/udf/partition.c2
-rw-r--r--fs/udf/super.c605
-rw-r--r--fs/udf/truncate.c44
-rw-r--r--fs/udf/udf_i.h6
-rw-r--r--fs/udf/udf_sb.h9
-rw-r--r--fs/udf/udfdecl.h57
-rw-r--r--fs/udf/udfend.h28
-rw-r--r--fs/udf/udftime.c6
-rw-r--r--fs/udf/unicode.c62
-rw-r--r--fs/xfs/Makefile1
-rw-r--r--fs/xfs/linux-2.6/mutex.h25
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c39
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c9
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c107
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c33
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h13
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c18
-rw-r--r--fs/xfs/linux-2.6/xfs_quotaops.c157
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c137
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c78
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.h10
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h32
-rw-r--r--fs/xfs/quota/xfs_dquot.c28
-rw-r--r--fs/xfs/quota/xfs_dquot.h18
-rw-r--r--fs/xfs/quota/xfs_qm.c212
-rw-r--r--fs/xfs/quota/xfs_qm.h26
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c1
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c190
-rw-r--r--fs/xfs/quota/xfs_quota_priv.h40
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c16
-rw-r--r--fs/xfs/support/debug.c1
-rw-r--r--fs/xfs/support/uuid.c71
-rw-r--r--fs/xfs/support/uuid.h4
-rw-r--r--fs/xfs/xfs_ag.h4
-rw-r--r--fs/xfs/xfs_alloc.c26
-rw-r--r--fs/xfs/xfs_alloc.h6
-rw-r--r--fs/xfs/xfs_attr_leaf.c58
-rw-r--r--fs/xfs/xfs_bmap.c76
-rw-r--r--fs/xfs/xfs_bmap.h6
-rw-r--r--fs/xfs/xfs_btree.c4
-rw-r--r--fs/xfs/xfs_btree.h2
-rw-r--r--fs/xfs/xfs_da_btree.c2
-rw-r--r--fs/xfs/xfs_da_btree.h9
-rw-r--r--fs/xfs/xfs_dfrag.c68
-rw-r--r--fs/xfs/xfs_dinode.h4
-rw-r--r--fs/xfs/xfs_dir2.c2
-rw-r--r--fs/xfs/xfs_dir2_block.c7
-rw-r--r--fs/xfs/xfs_dir2_data.h2
-rw-r--r--fs/xfs/xfs_dir2_leaf.c17
-rw-r--r--fs/xfs/xfs_dir2_node.c2
-rw-r--r--fs/xfs/xfs_dir2_sf.c13
-rw-r--r--fs/xfs/xfs_extfree_item.h6
-rw-r--r--fs/xfs/xfs_filestream.c9
-rw-r--r--fs/xfs/xfs_fsops.c2
-rw-r--r--fs/xfs/xfs_ialloc.c12
-rw-r--r--fs/xfs/xfs_ialloc_btree.c2
-rw-r--r--fs/xfs/xfs_ialloc_btree.h22
-rw-r--r--fs/xfs/xfs_iget.c23
-rw-r--r--fs/xfs/xfs_inode.h2
-rw-r--r--fs/xfs/xfs_inode_item.h2
-rw-r--r--fs/xfs/xfs_iomap.c61
-rw-r--r--fs/xfs/xfs_iomap.h5
-rw-r--r--fs/xfs/xfs_itable.c9
-rw-r--r--fs/xfs/xfs_log.c145
-rw-r--r--fs/xfs/xfs_log.h3
-rw-r--r--fs/xfs/xfs_log_priv.h3
-rw-r--r--fs/xfs/xfs_log_recover.c308
-rw-r--r--fs/xfs/xfs_mount.c253
-rw-r--r--fs/xfs/xfs_mount.h21
-rw-r--r--fs/xfs/xfs_qmops.c1
-rw-r--r--fs/xfs/xfs_quota.h3
-rw-r--r--fs/xfs/xfs_rtalloc.c10
-rw-r--r--fs/xfs/xfs_rtalloc.h8
-rw-r--r--fs/xfs/xfs_trans.h24
-rw-r--r--fs/xfs/xfs_trans_ail.c4
-rw-r--r--fs/xfs/xfs_trans_item.c2
-rw-r--r--fs/xfs/xfs_trans_space.h2
-rw-r--r--fs/xfs/xfs_types.h8
-rw-r--r--fs/xfs/xfs_utils.c2
-rw-r--r--fs/xfs/xfs_vnodeops.c413
-rw-r--r--fs/xfs/xfs_vnodeops.h3
-rw-r--r--include/acpi/acexcep.h6
-rw-r--r--include/acpi/acpi_bus.h19
-rw-r--r--include/acpi/acpi_drivers.h33
-rw-r--r--include/acpi/acpiosxf.h4
-rw-r--r--include/acpi/acpixf.h18
-rw-r--r--include/acpi/actbl.h74
-rw-r--r--include/acpi/actbl1.h6
-rw-r--r--include/acpi/actypes.h18
-rw-r--r--include/acpi/processor.h4
-rw-r--r--include/acpi/video.h11
-rw-r--r--include/asm-generic/percpu.h52
-rw-r--r--include/asm-generic/siginfo.h2
-rw-r--r--include/asm-generic/vmlinux.lds.h29
-rw-r--r--include/asm-m32r/ftrace.h1
-rw-r--r--include/asm-mn10300/.gitignore2
-rw-r--r--include/drm/drm_pciids.h2
-rw-r--r--include/linux/acpi.h1
-rw-r--r--include/linux/async_tx.h9
-rw-r--r--include/linux/ata.h41
-rw-r--r--include/linux/backing-dev.h12
-rw-r--r--include/linux/bio.h19
-rw-r--r--include/linux/blkdev.h57
-rw-r--r--include/linux/blktrace_api.h5
-rw-r--r--include/linux/capability.h23
-rw-r--r--include/linux/cgroup.h5
-rw-r--r--include/linux/compat.h4
-rw-r--r--include/linux/compiler.h13
-rw-r--r--include/linux/connector.h4
-rw-r--r--include/linux/debug_locks.h8
-rw-r--r--include/linux/debugfs.h8
-rw-r--r--include/linux/device-mapper.h4
-rw-r--r--include/linux/dm-dirty-log.h13
-rw-r--r--include/linux/dma-mapping.h2
-rw-r--r--include/linux/dma_remapping.h1
-rw-r--r--include/linux/dmaengine.h30
-rw-r--r--include/linux/dmar.h11
-rw-r--r--include/linux/ds1wm.h12
-rw-r--r--include/linux/dst.h587
-rw-r--r--include/linux/dw_dmac.h19
-rw-r--r--include/linux/elevator.h1
-rw-r--r--include/linux/ext3_fs.h1
-rw-r--r--include/linux/fb.h8
-rw-r--r--include/linux/fdtable.h4
-rw-r--r--include/linux/fiemap.h2
-rw-r--r--include/linux/fs.h46
-rw-r--r--include/linux/fscache-cache.h505
-rw-r--r--include/linux/fscache.h618
-rw-r--r--include/linux/fsl_devices.h22
-rw-r--r--include/linux/ftrace.h223
-rw-r--r--include/linux/ftrace_irq.h2
-rw-r--r--include/linux/gfp.h1
-rw-r--r--include/linux/hardirq.h75
-rw-r--r--include/linux/hdreg.h66
-rw-r--r--include/linux/hid.h23
-rw-r--r--include/linux/highmem.h29
-rw-r--r--include/linux/hrtimer.h5
-rw-r--r--include/linux/i2c-algo-sgi.h26
-rw-r--r--include/linux/i2c-id.h38
-rw-r--r--include/linux/i2c.h6
-rw-r--r--include/linux/i2c/s6000.h10
-rw-r--r--include/linux/i2c/twl4030.h47
-rw-r--r--include/linux/ide.h151
-rw-r--r--include/linux/init_task.h15
-rw-r--r--include/linux/intel-iommu.h15
-rw-r--r--include/linux/interrupt.h81
-rw-r--r--include/linux/iommu.h13
-rw-r--r--include/linux/ipc_namespace.h65
-rw-r--r--include/linux/irq.h19
-rw-r--r--include/linux/irqflags.h8
-rw-r--r--include/linux/irqreturn.h2
-rw-r--r--include/linux/jbd.h7
-rw-r--r--include/linux/kallsyms.h15
-rw-r--r--include/linux/kernel.h150
-rw-r--r--include/linux/key.h1
-rw-r--r--include/linux/kmod.h11
-rw-r--r--include/linux/kprobes.h52
-rw-r--r--include/linux/leds-bd2802.h26
-rw-r--r--include/linux/leds.h4
-rw-r--r--include/linux/leds_pwm.h21
-rw-r--r--include/linux/libata.h2
-rw-r--r--include/linux/lockd/xdr.h12
-rw-r--r--include/linux/lockd/xdr4.h10
-rw-r--r--include/linux/memory.h6
-rw-r--r--include/linux/mfd/ds1wm.h6
-rw-r--r--include/linux/mfd/htc-pasic3.h1
-rw-r--r--include/linux/mfd/pcf50633/core.h2
-rw-r--r--include/linux/mfd/pcf50633/mbc.h1
-rw-r--r--include/linux/mfd/wm8350/core.h2
-rw-r--r--include/linux/mg_disk.h206
-rw-r--r--include/linux/mmc/host.h5
-rw-r--r--include/linux/mmzone.h6
-rw-r--r--include/linux/module.h68
-rw-r--r--include/linux/moduleparam.h10
-rw-r--r--include/linux/mtd/mtd.h21
-rw-r--r--include/linux/mtd/nand.h4
-rw-r--r--include/linux/mtd/partitions.h12
-rw-r--r--include/linux/nfs.h1
-rw-r--r--include/linux/nfs4.h138
-rw-r--r--include/linux/nfs_fs.h13
-rw-r--r--include/linux/nfs_fs_sb.h11
-rw-r--r--include/linux/nfs_iostat.h12
-rw-r--r--include/linux/nfsd/cache.h8
-rw-r--r--include/linux/nfsd/nfsd.h225
-rw-r--r--include/linux/nfsd/nfsfh.h7
-rw-r--r--include/linux/nfsd/state.h84
-rw-r--r--include/linux/nfsd/stats.h9
-rw-r--r--include/linux/nfsd/xdr4.h129
-rw-r--r--include/linux/nilfs2_fs.h801
-rw-r--r--include/linux/page-flags.h40
-rw-r--r--include/linux/pagemap.h5
-rw-r--r--include/linux/parport_pc.h11
-rw-r--r--include/linux/pci.h5
-rw-r--r--include/linux/pci_ids.h28
-rw-r--r--include/linux/pda_power.h2
-rw-r--r--include/linux/percpu.h52
-rw-r--r--include/linux/power_supply.h2
-rw-r--r--include/linux/pwm.h2
-rw-r--r--include/linux/raid/md.h81
-rw-r--r--include/linux/raid/md_u.h35
-rw-r--r--include/linux/raid/pq.h (renamed from drivers/md/raid6.h)28
-rw-r--r--include/linux/raid/xor.h2
-rw-r--r--include/linux/rcuclassic.h16
-rw-r--r--include/linux/rcupdate.h1
-rw-r--r--include/linux/rcupreempt.h53
-rw-r--r--include/linux/rcutree.h27
-rw-r--r--include/linux/regulator/bq24022.h3
-rw-r--r--include/linux/regulator/consumer.h6
-rw-r--r--include/linux/regulator/driver.h81
-rw-r--r--include/linux/regulator/fixed.h3
-rw-r--r--include/linux/regulator/machine.h12
-rw-r--r--include/linux/ring_buffer.h38
-rw-r--r--include/linux/rotary_encoder.h13
-rw-r--r--include/linux/sched.h30
-rw-r--r--include/linux/security.h24
-rw-r--r--include/linux/serial_core.h5
-rw-r--r--include/linux/serial_max3100.h52
-rw-r--r--include/linux/sht15.h24
-rw-r--r--include/linux/slab_def.h68
-rw-r--r--include/linux/slob_def.h9
-rw-r--r--include/linux/slow-work.h95
-rw-r--r--include/linux/slub_def.h49
-rw-r--r--include/linux/smp.h7
-rw-r--r--include/linux/sonypi.h8
-rw-r--r--include/linux/spi/ad7879.h35
-rw-r--r--include/linux/spi/spi.h6
-rw-r--r--include/linux/string.h16
-rw-r--r--include/linux/stringify.h4
-rw-r--r--include/linux/sunrpc/svc.h16
-rw-r--r--include/linux/sunrpc/xdr.h42
-rw-r--r--include/linux/syscalls.h64
-rw-r--r--include/linux/thermal.h48
-rw-r--r--include/linux/timeriomem-rng.h2
-rw-r--r--include/linux/topology.h11
-rw-r--r--include/linux/trace_clock.h19
-rw-r--r--include/linux/tracepoint.h116
-rw-r--r--include/linux/tty_driver.h3
-rw-r--r--include/linux/usb/serial.h7
-rw-r--r--include/linux/usb/wusb.h3
-rw-r--r--include/linux/videodev2.h5
-rw-r--r--include/linux/writeback.h2
-rw-r--r--include/media/msp3400.h4
-rw-r--r--include/media/ov772x.h35
-rw-r--r--include/media/saa7146.h2
-rw-r--r--include/media/tvaudio.h19
-rw-r--r--include/media/v4l2-common.h141
-rw-r--r--include/media/v4l2-i2c-drv-legacy.h152
-rw-r--r--include/media/v4l2-i2c-drv.h6
-rw-r--r--include/media/v4l2-subdev.h115
-rw-r--r--include/net/netfilter/nf_conntrack_expect.h5
-rw-r--r--include/scsi/fc/fc_fip.h237
-rw-r--r--include/scsi/fc_transport_fcoe.h54
-rw-r--r--include/scsi/libfc.h45
-rw-r--r--include/scsi/libfcoe.h227
-rw-r--r--include/scsi/scsi_scan.h11
-rw-r--r--include/trace/block.h70
-rw-r--r--include/trace/irq.h9
-rw-r--r--include/trace/irq_event_types.h55
-rw-r--r--include/trace/kmemtrace.h63
-rw-r--r--include/trace/lockdep.h9
-rw-r--r--include/trace/lockdep_event_types.h44
-rw-r--r--include/trace/power.h32
-rw-r--r--include/trace/sched.h49
-rw-r--r--include/trace/sched_event_types.h337
-rw-r--r--include/trace/skb.h4
-rw-r--r--include/trace/syscall.h35
-rw-r--r--include/trace/trace_event_types.h5
-rw-r--r--include/trace/trace_events.h5
-rw-r--r--include/trace/workqueue.h25
-rw-r--r--include/video/cyblafb.h175
-rw-r--r--include/video/tdfx.h26
-rw-r--r--init/Kconfig42
-rw-r--r--init/do_mounts.h1
-rw-r--r--init/do_mounts_md.c5
-rw-r--r--init/initramfs.c5
-rw-r--r--init/main.c5
-rw-r--r--ipc/Makefile1
-rw-r--r--ipc/mq_sysctl.c116
-rw-r--r--ipc/mqueue.c256
-rw-r--r--ipc/msgutil.c19
-rw-r--r--ipc/namespace.c39
-rw-r--r--ipc/util.c9
-rw-r--r--ipc/util.h18
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/audit.c9
-rw-r--r--kernel/audit_tree.c2
-rw-r--r--kernel/auditfilter.c16
-rw-r--r--kernel/auditsc.c33
-rw-r--r--kernel/exit.c5
-rw-r--r--kernel/extable.c48
-rw-r--r--kernel/fork.c21
-rw-r--r--kernel/futex.c7
-rw-r--r--kernel/hrtimer.c55
-rw-r--r--kernel/hung_task.c217
-rw-r--r--kernel/irq/devres.c16
-rw-r--r--kernel/irq/handle.c56
-rw-r--r--kernel/irq/manage.c189
-rw-r--r--kernel/irq/numa_migrate.c1
-rw-r--r--kernel/kallsyms.c19
-rw-r--r--kernel/kmod.c10
-rw-r--r--kernel/kprobes.c298
-rw-r--r--kernel/kthread.c26
-rw-r--r--kernel/lockdep.c38
-rw-r--r--kernel/module.c274
-rw-r--r--kernel/mutex.c3
-rw-r--r--kernel/panic.c123
-rw-r--r--kernel/params.c26
-rw-r--r--kernel/posix-cpu-timers.c9
-rw-r--r--kernel/power/disk.c12
-rw-r--r--kernel/power/user.c9
-rw-r--r--kernel/printk.c7
-rw-r--r--kernel/ptrace.c25
-rw-r--r--kernel/rcuclassic.c23
-rw-r--r--kernel/rcupdate.c44
-rw-r--r--kernel/rcupreempt.c48
-rw-r--r--kernel/rcutree.c20
-rw-r--r--kernel/rcutree.h10
-rw-r--r--kernel/rcutree_trace.c2
-rw-r--r--kernel/relay.c4
-rw-r--r--kernel/sched.c227
-rw-r--r--kernel/sched_clock.c12
-rw-r--r--kernel/sched_cpupri.c5
-rw-r--r--kernel/sched_rt.c15
-rw-r--r--kernel/slow-work.c640
-rw-r--r--kernel/smp.c432
-rw-r--r--kernel/softirq.c36
-rw-r--r--kernel/softlockup.c100
-rw-r--r--kernel/sys.c24
-rw-r--r--kernel/sysctl.c63
-rw-r--r--kernel/timer.c7
-rw-r--r--kernel/trace/Kconfig134
-rw-r--r--kernel/trace/Makefile13
-rw-r--r--kernel/trace/blktrace.c (renamed from block/blktrace.c)812
-rw-r--r--kernel/trace/events.c14
-rw-r--r--kernel/trace/ftrace.c1133
-rw-r--r--kernel/trace/kmemtrace.c464
-rw-r--r--kernel/trace/ring_buffer.c693
-rw-r--r--kernel/trace/trace.c3059
-rw-r--r--kernel/trace/trace.h321
-rw-r--r--kernel/trace/trace_boot.c36
-rw-r--r--kernel/trace/trace_branch.c278
-rw-r--r--kernel/trace/trace_clock.c109
-rw-r--r--kernel/trace/trace_event_profile.c31
-rw-r--r--kernel/trace/trace_event_types.h173
-rw-r--r--kernel/trace/trace_events.c828
-rw-r--r--kernel/trace/trace_events_filter.c433
-rw-r--r--kernel/trace/trace_events_stage_1.h39
-rw-r--r--kernel/trace/trace_events_stage_2.h176
-rw-r--r--kernel/trace/trace_events_stage_3.h281
-rw-r--r--kernel/trace/trace_export.c102
-rw-r--r--kernel/trace/trace_functions.c369
-rw-r--r--kernel/trace/trace_functions_graph.c570
-rw-r--r--kernel/trace/trace_hw_branches.c185
-rw-r--r--kernel/trace/trace_irqsoff.c54
-rw-r--r--kernel/trace/trace_mmiotrace.c45
-rw-r--r--kernel/trace/trace_nop.c6
-rw-r--r--kernel/trace/trace_output.c1017
-rw-r--r--kernel/trace/trace_output.h71
-rw-r--r--kernel/trace/trace_power.c194
-rw-r--r--kernel/trace/trace_printk.c270
-rw-r--r--kernel/trace/trace_sched_switch.c27
-rw-r--r--kernel/trace/trace_sched_wakeup.c102
-rw-r--r--kernel/trace/trace_selftest.c169
-rw-r--r--kernel/trace/trace_stack.c19
-rw-r--r--kernel/trace/trace_stat.c326
-rw-r--r--kernel/trace/trace_stat.h31
-rw-r--r--kernel/trace/trace_syscalls.c250
-rw-r--r--kernel/trace/trace_sysprof.c23
-rw-r--r--kernel/trace/trace_workqueue.c288
-rw-r--r--kernel/tracepoint.c7
-rw-r--r--kernel/workqueue.c52
-rw-r--r--lib/Kconfig3
-rw-r--r--lib/Kconfig.debug38
-rw-r--r--lib/debug_locks.c2
-rw-r--r--lib/debugobjects.c127
-rw-r--r--lib/decompress_bunzip2.c1
-rw-r--r--lib/decompress_inflate.c1
-rw-r--r--lib/decompress_unlzma.c1
-rw-r--r--lib/locking-selftest.c4
-rw-r--r--lib/swiotlb.c2
-rw-r--r--lib/vsprintf.c993
-rw-r--r--mm/Kconfig2
-rw-r--r--mm/allocpercpu.c2
-rw-r--r--mm/backing-dev.c10
-rw-r--r--mm/failslab.c1
-rw-r--r--mm/filemap.c23
-rw-r--r--mm/memcontrol.c2
-rw-r--r--mm/migrate.c10
-rw-r--r--mm/page_alloc.c8
-rw-r--r--mm/pdflush.c47
-rw-r--r--mm/quicklist.c2
-rw-r--r--mm/readahead.c40
-rw-r--r--mm/shmem.c27
-rw-r--r--mm/slab.c71
-rw-r--r--mm/slob.c31
-rw-r--r--mm/slub.c77
-rw-r--r--mm/swap.c4
-rw-r--r--mm/truncate.c10
-rw-r--r--mm/util.c32
-rw-r--r--mm/vmscan.c12
-rw-r--r--net/802/fddi.c2
-rw-r--r--net/Kconfig2
-rw-r--r--net/ipv6/Kconfig18
-rw-r--r--net/ipv6/netfilter/ip6_tables.c2
-rw-r--r--net/ipv6/xfrm6_output.c1
-rw-r--r--net/mac80211/Kconfig2
-rw-r--r--net/netfilter/Kconfig4
-rw-r--r--net/netfilter/nf_conntrack_expect.c30
-rw-r--r--net/phonet/Kconfig2
-rw-r--r--net/socket.c6
-rw-r--r--net/sunrpc/Kconfig2
-rw-r--r--net/sunrpc/svc.c6
-rw-r--r--net/sunrpc/svc_xprt.c127
-rw-r--r--net/sunrpc/svcsock.c35
-rw-r--r--net/wimax/Kconfig2
-rw-r--r--samples/tracepoints/tp-samples-trace.h8
-rw-r--r--samples/tracepoints/tracepoint-sample.c24
-rw-r--r--scripts/.gitignore1
-rw-r--r--scripts/Makefile3
-rw-r--r--scripts/Makefile.build13
-rw-r--r--scripts/Makefile.headersinst2
-rw-r--r--scripts/gen_initramfs_list.sh2
-rwxr-xr-xscripts/get_maintainer.pl515
-rwxr-xr-xscripts/headerdep.pl2
-rw-r--r--scripts/kallsyms.c57
-rw-r--r--scripts/kconfig/kxgettext.c4
-rw-r--r--scripts/mod/modpost.c8
-rw-r--r--scripts/package/buildtar4
-rwxr-xr-xscripts/recordmcount.pl37
-rwxr-xr-xscripts/setlocalversion2
-rw-r--r--scripts/tracing/power.pl (renamed from scripts/trace/power.pl)0
-rw-r--r--security/commoncap.c1
-rw-r--r--security/keys/request_key.c9
-rw-r--r--security/security.c2
-rw-r--r--security/tomoyo/common.c13
-rw-r--r--security/tomoyo/common.h10
-rw-r--r--security/tomoyo/domain.c92
-rw-r--r--security/tomoyo/file.c2
-rw-r--r--security/tomoyo/realpath.c2
-rw-r--r--security/tomoyo/realpath.h2
-rw-r--r--security/tomoyo/tomoyo.c2
-rw-r--r--security/tomoyo/tomoyo.h2
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c15
-rw-r--r--sound/atmel/abdac.c4
-rw-r--r--sound/atmel/ac97c.c128
-rw-r--r--sound/atmel/ac97c.h14
-rw-r--r--sound/core/oss/mixer_oss.c8
-rw-r--r--sound/isa/Kconfig10
-rw-r--r--sound/isa/opl3sa2.c1
-rw-r--r--sound/isa/wavefront/wavefront_fx.c16
-rw-r--r--sound/isa/wavefront/yss225.c2739
-rw-r--r--sound/oss/pss.c2
-rw-r--r--sound/pci/ad1889.c4
-rw-r--r--sound/pci/ali5451/ali5451.c4
-rw-r--r--sound/pci/als300.c4
-rw-r--r--sound/pci/als4000.c4
-rw-r--r--sound/pci/au88x0/au88x0.c4
-rw-r--r--sound/pci/aw2/aw2-alsa.c4
-rw-r--r--sound/pci/azt3328.c4
-rw-r--r--sound/pci/ca0106/ca0106_main.c4
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c4
-rw-r--r--sound/pci/emu10k1/emu10k1x.c4
-rw-r--r--sound/pci/es1938.c4
-rw-r--r--sound/pci/es1968.c4
-rw-r--r--sound/pci/hda/hda_intel.c8
-rw-r--r--sound/pci/hda/patch_analog.c2
-rw-r--r--sound/pci/hda/patch_realtek.c5
-rw-r--r--sound/pci/hda/patch_sigmatel.c20
-rw-r--r--sound/pci/ice1712/ice1712.c4
-rw-r--r--sound/pci/maestro3.c4
-rw-r--r--sound/pci/mixart/mixart.c2
-rw-r--r--sound/pci/pcxhr/pcxhr.c2
-rw-r--r--sound/pci/sis7019.c2
-rw-r--r--sound/pci/sonicvibes.c4
-rw-r--r--sound/pci/trident/trident_main.c4
-rw-r--r--sound/ppc/powermac.c2
-rw-r--r--sound/sh/aica.c2
-rw-r--r--sound/soc/blackfin/Kconfig2
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c4
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c4
-rw-r--r--sound/soc/codecs/ak4535.c3
-rw-r--r--sound/soc/codecs/twl4030.c61
-rw-r--r--sound/soc/codecs/twl4030.h1
-rw-r--r--sound/soc/codecs/wm9705.c37
-rw-r--r--sound/soc/fsl/fsl_dma.c29
-rw-r--r--sound/soc/fsl/fsl_ssi.c99
-rw-r--r--sound/soc/omap/omap-mcbsp.c11
-rw-r--r--sound/soc/omap/omap-pcm.c2
-rw-r--r--sound/soc/pxa/Kconfig10
-rw-r--r--sound/soc/pxa/Makefile2
-rw-r--r--sound/soc/pxa/magician.c560
-rw-r--r--sound/soc/pxa/pxa-ssp.c12
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c4
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c2
-rw-r--r--sound/soc/soc-core.c20
-rw-r--r--sound/sparc/cs4231.c28
-rw-r--r--sound/usb/usbaudio.c255
-rw-r--r--usr/Kconfig15
-rw-r--r--usr/Makefile3
3560 files changed, 480885 insertions, 127026 deletions
diff --git a/CREDITS b/CREDITS
index 9a93e3e26d7..2520ba620ff 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1412,8 +1412,8 @@ P: 1024D/77D4FC9B F5C5 1C20 1DFC DEC3 3107 54A4 2332 ADFC 77D4 FC9B
D: National Language Support
D: Linux Internationalization Project
D: German Localization for Linux and GNU software
-S: Kriemhildring 12a
-S: 65795 Hattersheim am Main
+S: Auf der Fittel 18
+S: 53347 Alfter
S: Germany
N: Christoph Hellwig
@@ -3580,6 +3580,12 @@ N: Dirk Verworner
D: Co-author of German book ``Linux-Kernel-Programmierung''
D: Co-founder of Berlin Linux User Group
+N: Riku Voipio
+E: riku.voipio@iki.fi
+D: Author of PCA9532 LED and Fintek f75375s hwmon driver
+D: Some random ARM board patches
+S: Finland
+
N: Patrick Volkerding
E: volkerdi@ftp.cdrom.com
D: Produced the Slackware distribution, updated the SVGAlib
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 2a39aeba146..d05737aaa84 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -86,6 +86,8 @@ cachetlb.txt
- describes the cache/TLB flushing interfaces Linux uses.
cdrom/
- directory with information on the CD-ROM drivers that Linux has.
+cgroups/
+ - cgroups features, including cpusets and memory controller.
connector/
- docs on the netlink based userspace<->kernel space communication mod.
console/
@@ -98,8 +100,6 @@ cpu-load.txt
- document describing how CPU load statistics are collected.
cpuidle/
- info on CPU_IDLE, CPU idle state management subsystem.
-cpusets.txt
- - documents the cpusets feature; assign CPUs and Mem to a set of tasks.
cputopology.txt
- documentation on how CPU topology info is exported via sysfs.
cris/
diff --git a/Documentation/ABI/testing/debugfs-kmemtrace b/Documentation/ABI/testing/debugfs-kmemtrace
new file mode 100644
index 00000000000..5e6a92a02d8
--- /dev/null
+++ b/Documentation/ABI/testing/debugfs-kmemtrace
@@ -0,0 +1,71 @@
+What: /sys/kernel/debug/kmemtrace/
+Date: July 2008
+Contact: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
+Description:
+
+In kmemtrace-enabled kernels, the following files are created:
+
+/sys/kernel/debug/kmemtrace/
+ cpu<n> (0400) Per-CPU tracing data, see below. (binary)
+ total_overruns (0400) Total number of bytes which were dropped from
+ cpu<n> files because of full buffer condition,
+ non-binary. (text)
+ abi_version (0400) Kernel's kmemtrace ABI version. (text)
+
+Each per-CPU file should be read according to the relay interface. That is,
+the reader should set affinity to that specific CPU and, as currently done by
+the userspace application (though there are other methods), use poll() with
+an infinite timeout before every read(). Otherwise, erroneous data may be
+read. The binary data has the following _core_ format:
+
+ Event ID (1 byte) Unsigned integer, one of:
+ 0 - represents an allocation (KMEMTRACE_EVENT_ALLOC)
+ 1 - represents a freeing of previously allocated memory
+ (KMEMTRACE_EVENT_FREE)
+ Type ID (1 byte) Unsigned integer, one of:
+ 0 - this is a kmalloc() / kfree()
+ 1 - this is a kmem_cache_alloc() / kmem_cache_free()
+ 2 - this is a __get_free_pages() et al.
+ Event size (2 bytes) Unsigned integer representing the
+ size of this event. Used to extend
+ kmemtrace. Discard the bytes you
+ don't know about.
+ Sequence number (4 bytes) Signed integer used to reorder data
+ logged on SMP machines. Wraparound
+ must be taken into account, although
+ it is unlikely.
+ Caller address (8 bytes) Return address to the caller.
+ Pointer to mem (8 bytes) Pointer to target memory area. Can be
+ NULL, but not all such calls might be
+ recorded.
+
+In case of KMEMTRACE_EVENT_ALLOC events, the next fields follow:
+
+ Requested bytes (8 bytes) Total number of requested bytes,
+ unsigned, must not be zero.
+ Allocated bytes (8 bytes) Total number of actually allocated
+ bytes, unsigned, must not be lower
+ than requested bytes.
+ Requested flags (4 bytes) GFP flags supplied by the caller.
+ Target CPU (4 bytes) Signed integer, valid for event id 1.
+ If equal to -1, target CPU is the same
+ as origin CPU, but the reverse might
+ not be true.
+
+The data is made available in the same endianness the machine has.
+
+Other event ids and type ids may be defined and added. Other fields may be
+added by increasing event size, but see below for details.
+Every modification to the ABI, including new id definitions, are followed
+by bumping the ABI version by one.
+
+Adding new data to the packet (features) is done at the end of the mandatory
+data:
+ Feature size (2 byte)
+ Feature ID (1 byte)
+ Feature data (Feature size - 3 bytes)
+
+
+Users:
+ kmemtrace-user - git://repo.or.cz/kmemtrace-user.git
+
diff --git a/Documentation/ABI/testing/debugfs-pktcdvd b/Documentation/ABI/testing/debugfs-pktcdvd
index bf9c16b64c3..cf11736acb7 100644
--- a/Documentation/ABI/testing/debugfs-pktcdvd
+++ b/Documentation/ABI/testing/debugfs-pktcdvd
@@ -1,4 +1,4 @@
-What: /debug/pktcdvd/pktcdvd[0-7]
+What: /sys/kernel/debug/pktcdvd/pktcdvd[0-7]
Date: Oct. 2006
KernelVersion: 2.6.20
Contact: Thomas Maier <balagi@justmail.de>
@@ -10,10 +10,10 @@ debugfs interface
The pktcdvd module (packet writing driver) creates
these files in debugfs:
-/debug/pktcdvd/pktcdvd[0-7]/
+/sys/kernel/debug/pktcdvd/pktcdvd[0-7]/
info (0444) Lots of driver statistics and infos.
Example:
-------
-cat /debug/pktcdvd/pktcdvd0/info
+cat /sys/kernel/debug/pktcdvd/pktcdvd0/info
diff --git a/Documentation/ABI/testing/sysfs-class-regulator b/Documentation/ABI/testing/sysfs-class-regulator
index 873ef1fc156..e091fa87379 100644
--- a/Documentation/ABI/testing/sysfs-class-regulator
+++ b/Documentation/ABI/testing/sysfs-class-regulator
@@ -4,8 +4,8 @@ KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description:
Some regulator directories will contain a field called
- state. This reports the regulator enable status, for
- regulators which can report that value.
+ state. This reports the regulator enable control, for
+ regulators which can report that input value.
This will be one of the following strings:
@@ -14,16 +14,54 @@ Description:
'unknown'
'enabled' means the regulator output is ON and is supplying
- power to the system.
+ power to the system (assuming no error prevents it).
'disabled' means the regulator output is OFF and is not
- supplying power to the system..
+ supplying power to the system (unless some non-Linux
+ control has enabled it).
'unknown' means software cannot determine the state, or
the reported state is invalid.
NOTE: this field can be used in conjunction with microvolts
- and microamps to determine regulator output levels.
+ or microamps to determine configured regulator output levels.
+
+
+What: /sys/class/regulator/.../status
+Description:
+ Some regulator directories will contain a field called
+ "status". This reports the current regulator status, for
+ regulators which can report that output value.
+
+ This will be one of the following strings:
+
+ off
+ on
+ error
+ fast
+ normal
+ idle
+ standby
+
+ "off" means the regulator is not supplying power to the
+ system.
+
+ "on" means the regulator is supplying power to the system,
+ and the regulator can't report a detailed operation mode.
+
+ "error" indicates an out-of-regulation status such as being
+ disabled due to thermal shutdown, or voltage being unstable
+ because of problems with the input power supply.
+
+ "fast", "normal", "idle", and "standby" are all detailed
+ regulator operation modes (described elsewhere). They
+ imply "on", but provide more detail.
+
+ Note that regulator status is a function of many inputs,
+ not limited to control inputs from Linux. For example,
+ the actual load presented may trigger "error" status; or
+ a regulator may be enabled by another user, even though
+ Linux did not enable it.
What: /sys/class/regulator/.../type
@@ -58,7 +96,7 @@ Description:
Some regulator directories will contain a field called
microvolts. This holds the regulator output voltage setting
measured in microvolts (i.e. E-6 Volts), for regulators
- which can report that voltage.
+ which can report the control input for voltage.
NOTE: This value should not be used to determine the regulator
output voltage level as this value is the same regardless of
@@ -73,7 +111,7 @@ Description:
Some regulator directories will contain a field called
microamps. This holds the regulator output current limit
setting measured in microamps (i.e. E-6 Amps), for regulators
- which can report that current.
+ which can report the control input for a current limit.
NOTE: This value should not be used to determine the regulator
output current level as this value is the same regardless of
@@ -87,7 +125,7 @@ Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description:
Some regulator directories will contain a field called
opmode. This holds the current regulator operating mode,
- for regulators which can report it.
+ for regulators which can report that control input value.
The opmode value can be one of the following strings:
@@ -101,7 +139,8 @@ Description:
NOTE: This value should not be used to determine the regulator
output operating mode as this value is the same regardless of
- whether the regulator is enabled or disabled.
+ whether the regulator is enabled or disabled. A "status"
+ attribute may be available to determine the actual mode.
What: /sys/class/regulator/.../min_microvolts
diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt
index b2a4d6d244d..01f24e94bdb 100644
--- a/Documentation/DMA-mapping.txt
+++ b/Documentation/DMA-mapping.txt
@@ -136,7 +136,7 @@ exactly why.
The standard 32-bit addressing PCI device would do something like
this:
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING
"mydev: No suitable DMA available.\n");
goto ignore_this_device;
@@ -155,9 +155,9 @@ all 64-bits when accessing streaming DMA:
int using_dac;
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
using_dac = 1;
- } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
using_dac = 0;
} else {
printk(KERN_WARNING
@@ -170,14 +170,14 @@ the case would look like this:
int using_dac, consistent_using_dac;
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
using_dac = 1;
consistent_using_dac = 1;
- pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
- } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+ } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
using_dac = 0;
consistent_using_dac = 0;
- pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
} else {
printk(KERN_WARNING
"mydev: No suitable DMA available.\n");
@@ -192,7 +192,7 @@ check the return value from pci_set_consistent_dma_mask().
Finally, if your device can only drive the low 24-bits of
address during PCI bus mastering you might do something like:
- if (pci_set_dma_mask(pdev, DMA_24BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(24))) {
printk(KERN_WARNING
"mydev: 24-bit DMA addressing not available.\n");
goto ignore_this_device;
@@ -213,7 +213,7 @@ most specific mask.
Here is pseudo-code showing how this might be done:
- #define PLAYBACK_ADDRESS_BITS DMA_32BIT_MASK
+ #define PLAYBACK_ADDRESS_BITS DMA_BIT_MASK(32)
#define RECORD_ADDRESS_BITS 0x00ffffff
struct my_sound_card *card;
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index a3a83d38f96..8918a32c6b3 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -31,7 +31,7 @@ PS_METHOD = $(prefer-db2x)
###
# The targets that may be used.
-PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs
+PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs
BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
xmldocs: $(BOOKS)
@@ -213,11 +213,12 @@ silent_gen_xml = :
dochelp:
@echo ' Linux kernel internal documentation in different formats:'
@echo ' htmldocs - HTML'
- @echo ' installmandocs - install man pages generated by mandocs'
- @echo ' mandocs - man pages'
@echo ' pdfdocs - PDF'
@echo ' psdocs - Postscript'
@echo ' xmldocs - XML DocBook'
+ @echo ' mandocs - man pages'
+ @echo ' installmandocs - install man pages generated by mandocs'
+ @echo ' cleandocs - clean all generated DocBook files'
###
# Temporary files left by various tools
@@ -235,6 +236,10 @@ clean-files := $(DOCBOOKS) \
clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) man
+cleandocs:
+ $(Q)rm -f $(call objectify, $(clean-files))
+ $(Q)rm -rf $(call objectify, $(clean-dirs))
+
# Declare the contents of the .PHONY variable as phony. We keep that
# information in a variable se we can use it in if_changed and friends.
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 58c194572c7..d6ac5d61820 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -259,7 +259,7 @@ X!Earch/x86/kernel/mca_32.c
!Eblock/blk-tag.c
!Iblock/blk-tag.c
!Eblock/blk-integrity.c
-!Iblock/blktrace.c
+!Ikernel/trace/blktrace.c
!Iblock/genhd.c
!Eblock/genhd.c
</chapter>
diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl
index 46b08fef374..7a2e0e98986 100644
--- a/Documentation/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl
@@ -1137,8 +1137,8 @@
if (err < 0)
return err;
/* check PCI availability (28bit DMA) */
- if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
printk(KERN_ERR "error to set 28bit mask DMA\n");
pci_disable_device(pci);
return -ENXIO;
@@ -1252,8 +1252,8 @@
err = pci_enable_device(pci);
if (err < 0)
return err;
- if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
printk(KERN_ERR "error to set 28bit mask DMA\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/Documentation/RCU/listRCU.txt b/Documentation/RCU/listRCU.txt
index 1fd175368a8..4349c1487e9 100644
--- a/Documentation/RCU/listRCU.txt
+++ b/Documentation/RCU/listRCU.txt
@@ -118,7 +118,7 @@ Following are the RCU equivalents for these two functions:
list_for_each_entry(e, list, list) {
if (!audit_compare_rule(rule, &e->rule)) {
list_del_rcu(&e->list);
- call_rcu(&e->rcu, audit_free_rule, e);
+ call_rcu(&e->rcu, audit_free_rule);
return 0;
}
}
@@ -206,7 +206,7 @@ RCU ("read-copy update") its name. The RCU code is as follows:
ne->rule.action = newaction;
ne->rule.file_count = newfield_count;
list_replace_rcu(e, ne);
- call_rcu(&e->rcu, audit_free_rule, e);
+ call_rcu(&e->rcu, audit_free_rule);
return 0;
}
}
@@ -283,7 +283,7 @@ flag under the spinlock as follows:
list_del_rcu(&e->list);
e->deleted = 1;
spin_unlock(&e->lock);
- call_rcu(&e->rcu, audit_free_rule, e);
+ call_rcu(&e->rcu, audit_free_rule);
return 0;
}
}
diff --git a/Documentation/RCU/rcu.txt b/Documentation/RCU/rcu.txt
index 95821a29ae4..7aa2002ade7 100644
--- a/Documentation/RCU/rcu.txt
+++ b/Documentation/RCU/rcu.txt
@@ -81,7 +81,7 @@ o I hear that RCU needs work in order to support realtime kernels?
This work is largely completed. Realtime-friendly RCU can be
enabled via the CONFIG_PREEMPT_RCU kernel configuration parameter.
However, work is in progress for enabling priority boosting of
- preempted RCU read-side critical sections.This is needed if you
+ preempted RCU read-side critical sections. This is needed if you
have CPU-bound realtime threads.
o Where can I find more information on RCU?
diff --git a/Documentation/RCU/rculist_nulls.txt b/Documentation/RCU/rculist_nulls.txt
index 239f542d48b..6389dec3345 100644
--- a/Documentation/RCU/rculist_nulls.txt
+++ b/Documentation/RCU/rculist_nulls.txt
@@ -21,7 +21,7 @@ if (obj) {
/*
* Because a writer could delete object, and a writer could
* reuse these object before the RCU grace period, we
- * must check key after geting the reference on object
+ * must check key after getting the reference on object
*/
if (obj->key != key) { // not the object we expected
put_ref(obj);
@@ -117,7 +117,7 @@ a race (some writer did a delete and/or a move of an object
to another chain) checking the final 'nulls' value if
the lookup met the end of chain. If final 'nulls' value
is not the slot number, then we must restart the lookup at
-the begining. If the object was moved to same chain,
+the beginning. If the object was moved to the same chain,
then the reader doesnt care : It might eventually
scan the list again without harm.
diff --git a/Documentation/blockdev/00-INDEX b/Documentation/blockdev/00-INDEX
index 86f054c4701..c08df56dd91 100644
--- a/Documentation/blockdev/00-INDEX
+++ b/Documentation/blockdev/00-INDEX
@@ -8,6 +8,8 @@ cpqarray.txt
- info on using Compaq's SMART2 Intelligent Disk Array Controllers.
floppy.txt
- notes and driver options for the floppy disk driver.
+mflash.txt
+ - info on mGine m(g)flash driver for linux.
nbd.txt
- info on a TCP implementation of a network block device.
paride.txt
diff --git a/Documentation/blockdev/mflash.txt b/Documentation/blockdev/mflash.txt
new file mode 100644
index 00000000000..1f610ecf698
--- /dev/null
+++ b/Documentation/blockdev/mflash.txt
@@ -0,0 +1,84 @@
+This document describes m[g]flash support in linux.
+
+Contents
+ 1. Overview
+ 2. Reserved area configuration
+ 3. Example of mflash platform driver registration
+
+1. Overview
+
+Mflash and gflash are embedded flash drive. The only difference is mflash is
+MCP(Multi Chip Package) device. These two device operate exactly same way.
+So the rest mflash repersents mflash and gflash altogether.
+
+Internally, mflash has nand flash and other hardware logics and supports
+2 different operation (ATA, IO) modes. ATA mode doesn't need any new
+driver and currently works well under standard IDE subsystem. Actually it's
+one chip SSD. IO mode is ATA-like custom mode for the host that doesn't have
+IDE interface.
+
+Followings are brief descriptions about IO mode.
+A. IO mode based on ATA protocol and uses some custom command. (read confirm,
+write confirm)
+B. IO mode uses SRAM bus interface.
+C. IO mode supports 4kB boot area, so host can boot from mflash.
+
+2. Reserved area configuration
+If host boot from mflash, usually needs raw area for boot loader image. All of
+the mflash's block device operation will be taken this value as start offset.
+Note that boot loader's size of reserved area and kernel configuration value
+must be same.
+
+3. Example of mflash platform driver registration
+Working mflash is very straight forward. Adding platform device stuff to board
+configuration file is all. Here is some pseudo example.
+
+static struct mg_drv_data mflash_drv_data = {
+ /* If you want to polling driver set to 1 */
+ .use_polling = 0,
+ /* device attribution */
+ .dev_attr = MG_BOOT_DEV
+};
+
+static struct resource mg_mflash_rsc[] = {
+ /* Base address of mflash */
+ [0] = {
+ .start = 0x08000000,
+ .end = 0x08000000 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM
+ },
+ /* mflash interrupt pin */
+ [1] = {
+ .start = IRQ_GPIO(84),
+ .end = IRQ_GPIO(84),
+ .flags = IORESOURCE_IRQ
+ },
+ /* mflash reset pin */
+ [2] = {
+ .start = 43,
+ .end = 43,
+ .name = MG_RST_PIN,
+ .flags = IORESOURCE_IO
+ },
+ /* mflash reset-out pin
+ * If you use mflash as storage device (i.e. other than MG_BOOT_DEV),
+ * should assign this */
+ [3] = {
+ .start = 51,
+ .end = 51,
+ .name = MG_RSTOUT_PIN,
+ .flags = IORESOURCE_IO
+ }
+};
+
+static struct platform_device mflash_dev = {
+ .name = MG_DEV_NAME,
+ .id = -1,
+ .dev = {
+ .platform_data = &mflash_drv_data,
+ },
+ .num_resources = ARRAY_SIZE(mg_mflash_rsc),
+ .resource = mg_mflash_rsc
+};
+
+platform_device_register(&mflash_dev);
diff --git a/Documentation/cgroups/00-INDEX b/Documentation/cgroups/00-INDEX
new file mode 100644
index 00000000000..3f58fa3d6d0
--- /dev/null
+++ b/Documentation/cgroups/00-INDEX
@@ -0,0 +1,18 @@
+00-INDEX
+ - this file
+cgroups.txt
+ - Control Groups definition, implementation details, examples and API.
+cpuacct.txt
+ - CPU Accounting Controller; account CPU usage for groups of tasks.
+cpusets.txt
+ - documents the cpusets feature; assign CPUs and Mem to a set of tasks.
+devices.txt
+ - Device Whitelist Controller; description, interface and security.
+freezer-subsystem.txt
+ - checkpointing; rationale to not use signals, interface.
+memcg_test.txt
+ - Memory Resource Controller; implementation details.
+memory.txt
+ - Memory Resource Controller; design, accounting, interface, testing.
+resource_counter.txt
+ - Resource Counter API.
diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt
index 4ea852345a4..6eb1a97e88c 100644
--- a/Documentation/cgroups/cgroups.txt
+++ b/Documentation/cgroups/cgroups.txt
@@ -56,7 +56,7 @@ hierarchy, and a set of subsystems; each subsystem has system-specific
state attached to each cgroup in the hierarchy. Each hierarchy has
an instance of the cgroup virtual filesystem associated with it.
-At any one time there may be multiple active hierachies of task
+At any one time there may be multiple active hierarchies of task
cgroups. Each hierarchy is a partition of all tasks in the system.
User level code may create and destroy cgroups by name in an
@@ -124,10 +124,10 @@ following lines:
/ \
Prof (15%) students (5%)
-Browsers like firefox/lynx go into the WWW network class, while (k)nfsd go
+Browsers like Firefox/Lynx go into the WWW network class, while (k)nfsd go
into NFS network class.
-At the same time firefox/lynx will share an appropriate CPU/Memory class
+At the same time Firefox/Lynx will share an appropriate CPU/Memory class
depending on who launched it (prof/student).
With the ability to classify tasks differently for different resources
@@ -325,7 +325,7 @@ and then start a subshell 'sh' in that cgroup:
Creating, modifying, using the cgroups can be done through the cgroup
virtual filesystem.
-To mount a cgroup hierarchy will all available subsystems, type:
+To mount a cgroup hierarchy with all available subsystems, type:
# mount -t cgroup xxx /dev/cgroup
The "xxx" is not interpreted by the cgroup code, but will appear in
@@ -539,7 +539,7 @@ always handled well.
void post_clone(struct cgroup_subsys *ss, struct cgroup *cgrp)
(cgroup_mutex held by caller)
-Called at the end of cgroup_clone() to do any paramater
+Called at the end of cgroup_clone() to do any parameter
initialization which might be required before a task could attach. For
example in cpusets, no task may attach before 'cpus' and 'mems' are set
up.
diff --git a/Documentation/cgroups/cpuacct.txt b/Documentation/cgroups/cpuacct.txt
index bb775fbe43d..8b930946c52 100644
--- a/Documentation/cgroups/cpuacct.txt
+++ b/Documentation/cgroups/cpuacct.txt
@@ -30,3 +30,21 @@ The above steps create a new group g1 and move the current shell
process (bash) into it. CPU time consumed by this bash and its children
can be obtained from g1/cpuacct.usage and the same is accumulated in
/cgroups/cpuacct.usage also.
+
+cpuacct.stat file lists a few statistics which further divide the
+CPU time obtained by the cgroup into user and system times. Currently
+the following statistics are supported:
+
+user: Time spent by tasks of the cgroup in user mode.
+system: Time spent by tasks of the cgroup in kernel mode.
+
+user and system are in USER_HZ unit.
+
+cpuacct controller uses percpu_counter interface to collect user and
+system times. This has two side effects:
+
+- It is theoretically possible to see wrong values for user and system times.
+ This is because percpu_counter_read() on 32bit systems isn't safe
+ against concurrent writes.
+- It is possible to see slightly outdated values for user and system times
+ due to the batch processing nature of percpu_counter.
diff --git a/Documentation/cgroups/cpusets.txt b/Documentation/cgroups/cpusets.txt
index 0611e9528c7..f9ca389dddf 100644
--- a/Documentation/cgroups/cpusets.txt
+++ b/Documentation/cgroups/cpusets.txt
@@ -131,7 +131,7 @@ Cpusets extends these two mechanisms as follows:
- The hierarchy of cpusets can be mounted at /dev/cpuset, for
browsing and manipulation from user space.
- A cpuset may be marked exclusive, which ensures that no other
- cpuset (except direct ancestors and descendents) may contain
+ cpuset (except direct ancestors and descendants) may contain
any overlapping CPUs or Memory Nodes.
- You can list all the tasks (by pid) attached to any cpuset.
@@ -226,7 +226,7 @@ nodes with memory--using the cpuset_track_online_nodes() hook.
--------------------------------
If a cpuset is cpu or mem exclusive, no other cpuset, other than
-a direct ancestor or descendent, may share any of the same CPUs or
+a direct ancestor or descendant, may share any of the same CPUs or
Memory Nodes.
A cpuset that is mem_exclusive *or* mem_hardwall is "hardwalled",
@@ -427,7 +427,7 @@ child cpusets have this flag enabled.
When doing this, you don't usually want to leave any unpinned tasks in
the top cpuset that might use non-trivial amounts of CPU, as such tasks
may be artificially constrained to some subset of CPUs, depending on
-the particulars of this flag setting in descendent cpusets. Even if
+the particulars of this flag setting in descendant cpusets. Even if
such a task could use spare CPU cycles in some other CPUs, the kernel
scheduler might not consider the possibility of load balancing that
task to that underused CPU.
@@ -531,9 +531,9 @@ be idle.
Of course it takes some searching cost to find movable tasks and/or
idle CPUs, the scheduler might not search all CPUs in the domain
-everytime. In fact, in some architectures, the searching ranges on
+every time. In fact, in some architectures, the searching ranges on
events are limited in the same socket or node where the CPU locates,
-while the load balance on tick searchs all.
+while the load balance on tick searches all.
For example, assume CPU Z is relatively far from CPU X. Even if CPU Z
is idle while CPU X and the siblings are busy, scheduler can't migrate
@@ -601,7 +601,7 @@ its new cpuset, then the task will continue to use whatever subset
of MPOL_BIND nodes are still allowed in the new cpuset. If the task
was using MPOL_BIND and now none of its MPOL_BIND nodes are allowed
in the new cpuset, then the task will be essentially treated as if it
-was MPOL_BIND bound to the new cpuset (even though its numa placement,
+was MPOL_BIND bound to the new cpuset (even though its NUMA placement,
as queried by get_mempolicy(), doesn't change). If a task is moved
from one cpuset to another, then the kernel will adjust the tasks
memory placement, as above, the next time that the kernel attempts
diff --git a/Documentation/cgroups/devices.txt b/Documentation/cgroups/devices.txt
index 7cc6e6a6067..57ca4c89fe5 100644
--- a/Documentation/cgroups/devices.txt
+++ b/Documentation/cgroups/devices.txt
@@ -42,7 +42,7 @@ suffice, but we can decide the best way to adequately restrict
movement as people get some experience with this. We may just want
to require CAP_SYS_ADMIN, which at least is a separate bit from
CAP_MKNOD. We may want to just refuse moving to a cgroup which
-isn't a descendent of the current one. Or we may want to use
+isn't a descendant of the current one. Or we may want to use
CAP_MAC_ADMIN, since we really are trying to lock down root.
CAP_SYS_ADMIN is needed to modify the whitelist or move another
diff --git a/Documentation/cgroups/memcg_test.txt b/Documentation/cgroups/memcg_test.txt
index 8a11caf417a..72db89ed060 100644
--- a/Documentation/cgroups/memcg_test.txt
+++ b/Documentation/cgroups/memcg_test.txt
@@ -356,7 +356,7 @@ Under below explanation, we assume CONFIG_MEM_RES_CTRL_SWAP=y.
(Shell-B)
# move all tasks in /cgroup/test to /cgroup
# /sbin/swapoff -a
- # rmdir /test/cgroup
+ # rmdir /cgroup/test
# kill malloc task.
Of course, tmpfs v.s. swapoff test should be tested, too.
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
index e1501964df1..1a608877b14 100644
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -6,15 +6,14 @@ used here with the memory controller that is used in hardware.
Salient features
-a. Enable control of both RSS (mapped) and Page Cache (unmapped) pages
+a. Enable control of Anonymous, Page Cache (mapped and unmapped) and
+ Swap Cache memory pages.
b. The infrastructure allows easy addition of other types of memory to control
c. Provides *zero overhead* for non memory controller users
d. Provides a double LRU: global memory pressure causes reclaim from the
global LRU; a cgroup on hitting a limit, reclaims from the per
cgroup LRU
-NOTE: Swap Cache (unmapped) is not accounted now.
-
Benefits and Purpose of the memory controller
The memory controller isolates the memory behaviour of a group of tasks
@@ -290,34 +289,44 @@ will be charged as a new owner of it.
moved to the parent. If you want to avoid that, force_empty will be useful.
5.2 stat file
- memory.stat file includes following statistics (now)
- cache - # of pages from page-cache and shmem.
- rss - # of pages from anonymous memory.
- pgpgin - # of event of charging
- pgpgout - # of event of uncharging
- active_anon - # of pages on active lru of anon, shmem.
- inactive_anon - # of pages on active lru of anon, shmem
- active_file - # of pages on active lru of file-cache
- inactive_file - # of pages on inactive lru of file cache
- unevictable - # of pages cannot be reclaimed.(mlocked etc)
-
- Below is depend on CONFIG_DEBUG_VM.
- inactive_ratio - VM inernal parameter. (see mm/page_alloc.c)
- recent_rotated_anon - VM internal parameter. (see mm/vmscan.c)
- recent_rotated_file - VM internal parameter. (see mm/vmscan.c)
- recent_scanned_anon - VM internal parameter. (see mm/vmscan.c)
- recent_scanned_file - VM internal parameter. (see mm/vmscan.c)
-
- Memo:
+
+memory.stat file includes following statistics
+
+cache - # of bytes of page cache memory.
+rss - # of bytes of anonymous and swap cache memory.
+pgpgin - # of pages paged in (equivalent to # of charging events).
+pgpgout - # of pages paged out (equivalent to # of uncharging events).
+active_anon - # of bytes of anonymous and swap cache memory on active
+ lru list.
+inactive_anon - # of bytes of anonymous memory and swap cache memory on
+ inactive lru list.
+active_file - # of bytes of file-backed memory on active lru list.
+inactive_file - # of bytes of file-backed memory on inactive lru list.
+unevictable - # of bytes of memory that cannot be reclaimed (mlocked etc).
+
+The following additional stats are dependent on CONFIG_DEBUG_VM.
+
+inactive_ratio - VM internal parameter. (see mm/page_alloc.c)
+recent_rotated_anon - VM internal parameter. (see mm/vmscan.c)
+recent_rotated_file - VM internal parameter. (see mm/vmscan.c)
+recent_scanned_anon - VM internal parameter. (see mm/vmscan.c)
+recent_scanned_file - VM internal parameter. (see mm/vmscan.c)
+
+Memo:
recent_rotated means recent frequency of lru rotation.
recent_scanned means recent # of scans to lru.
showing for better debug please see the code for meanings.
+Note:
+ Only anonymous and swap cache memory is listed as part of 'rss' stat.
+ This should not be confused with the true 'resident set size' or the
+ amount of physical memory used by the cgroup. Per-cgroup rss
+ accounting is not done yet.
5.3 swappiness
Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
- Following cgroup's swapiness can't be changed.
+ Following cgroups' swapiness can't be changed.
- root cgroup (uses /proc/sys/vm/swappiness).
- a cgroup which uses hierarchy and it has child cgroup.
- a cgroup which uses hierarchy and not the root of hierarchy.
diff --git a/Documentation/cgroups/resource_counter.txt b/Documentation/cgroups/resource_counter.txt
index f196ac1d7d2..95b24d766ea 100644
--- a/Documentation/cgroups/resource_counter.txt
+++ b/Documentation/cgroups/resource_counter.txt
@@ -47,13 +47,18 @@ to work with it.
2. Basic accounting routines
- a. void res_counter_init(struct res_counter *rc)
+ a. void res_counter_init(struct res_counter *rc,
+ struct res_counter *rc_parent)
Initializes the resource counter. As usual, should be the first
routine called for a new counter.
- b. int res_counter_charge[_locked]
- (struct res_counter *rc, unsigned long val)
+ The struct res_counter *parent can be used to define a hierarchical
+ child -> parent relationship directly in the res_counter structure,
+ NULL can be used to define no relationship.
+
+ c. int res_counter_charge(struct res_counter *rc, unsigned long val,
+ struct res_counter **limit_fail_at)
When a resource is about to be allocated it has to be accounted
with the appropriate resource counter (controller should determine
@@ -67,15 +72,25 @@ to work with it.
* if the charging is performed first, then it should be uncharged
on error path (if the one is called).
- c. void res_counter_uncharge[_locked]
+ If the charging fails and a hierarchical dependency exists, the
+ limit_fail_at parameter is set to the particular res_counter element
+ where the charging failed.
+
+ d. int res_counter_charge_locked
+ (struct res_counter *rc, unsigned long val)
+
+ The same as res_counter_charge(), but it must not acquire/release the
+ res_counter->lock internally (it must be called with res_counter->lock
+ held).
+
+ e. void res_counter_uncharge[_locked]
(struct res_counter *rc, unsigned long val)
When a resource is released (freed) it should be de-accounted
from the resource counter it was accounted to. This is called
"uncharging".
- The _locked routines imply that the res_counter->lock is taken.
-
+ The _locked routines imply that the res_counter->lock is taken.
2.1 Other accounting routines
diff --git a/Documentation/devices.txt b/Documentation/devices.txt
index 62254d4510c..53d64d38234 100644
--- a/Documentation/devices.txt
+++ b/Documentation/devices.txt
@@ -1,9 +1,9 @@
LINUX ALLOCATED DEVICES (2.6+ version)
- Maintained by Torben Mathiasen <device@lanana.org>
+ Maintained by Alan Cox <device@lanana.org>
- Last revised: 29 November 2006
+ Last revised: 6th April 2009
This list is the Linux Device List, the official registry of allocated
device numbers and /dev directory nodes for the Linux operating
@@ -67,6 +67,11 @@ up to date. Due to the number of registrations I have to maintain it
in "batch mode", so there is likely additional registrations that
haven't been listed yet.
+Fourth, remember that Linux now has extensive support for dynamic allocation
+of device numbering and can use sysfs and udev to handle the naming needs.
+There are still some exceptions in the serial and boot device area. Before
+asking for a device number make sure you actually need one.
+
Finally, sometimes I have to play "namespace police." Please don't be
offended. I often get submissions for /dev names that would be bound
to cause conflicts down the road. I am trying to avoid getting in a
@@ -101,7 +106,7 @@ Your cooperation is appreciated.
0 = /dev/ram0 First RAM disk
1 = /dev/ram1 Second RAM disk
...
- 250 = /dev/initrd Initial RAM disk {2.6}
+ 250 = /dev/initrd Initial RAM disk
Older kernels had /dev/ramdisk (1, 1) here.
/dev/initrd refers to a RAM disk which was preloaded
@@ -340,7 +345,7 @@ Your cooperation is appreciated.
14 = /dev/touchscreen/ucb1x00 UCB 1x00 touchscreen
15 = /dev/touchscreen/mk712 MK712 touchscreen
128 = /dev/beep Fancy beep device
- 129 = /dev/modreq Kernel module load request {2.6}
+ 129 =
130 = /dev/watchdog Watchdog timer port
131 = /dev/temperature Machine internal temperature
132 = /dev/hwtrap Hardware fault trap
@@ -350,10 +355,10 @@ Your cooperation is appreciated.
139 = /dev/openprom SPARC OpenBoot PROM
140 = /dev/relay8 Berkshire Products Octal relay card
141 = /dev/relay16 Berkshire Products ISO-16 relay card
- 142 = /dev/msr x86 model-specific registers {2.6}
+ 142 =
143 = /dev/pciconf PCI configuration space
144 = /dev/nvram Non-volatile configuration RAM
- 145 = /dev/hfmodem Soundcard shortwave modem control {2.6}
+ 145 = /dev/hfmodem Soundcard shortwave modem control
146 = /dev/graphics Linux/SGI graphics device
147 = /dev/opengl Linux/SGI OpenGL pipe
148 = /dev/gfx Linux/SGI graphics effects device
@@ -435,6 +440,9 @@ Your cooperation is appreciated.
228 = /dev/hpet HPET driver
229 = /dev/fuse Fuse (virtual filesystem in user-space)
230 = /dev/midishare MidiShare driver
+ 231 = /dev/snapshot System memory snapshot device
+ 232 = /dev/kvm Kernel-based virtual machine (hardware virtualization extensions)
+ 233 = /dev/kmview View-OS A process with a view
240-254 Reserved for local use
255 Reserved for MISC_DYNAMIC_MINOR
@@ -466,10 +474,7 @@ Your cooperation is appreciated.
The device names specified are proposed -- if there
are "standard" names for these devices, please let me know.
- 12 block MSCDEX CD-ROM callback support {2.6}
- 0 = /dev/dos_cd0 First MSCDEX CD-ROM
- 1 = /dev/dos_cd1 Second MSCDEX CD-ROM
- ...
+ 12 block
13 char Input core
0 = /dev/input/js0 First joystick
@@ -498,7 +503,7 @@ Your cooperation is appreciated.
2 = /dev/midi00 First MIDI port
3 = /dev/dsp Digital audio
4 = /dev/audio Sun-compatible digital audio
- 6 = /dev/sndstat Sound card status information {2.6}
+ 6 =
7 = /dev/audioctl SPARC audio control device
8 = /dev/sequencer2 Sequencer -- alternate device
16 = /dev/mixer1 Second soundcard mixer control
@@ -510,14 +515,7 @@ Your cooperation is appreciated.
34 = /dev/midi02 Third MIDI port
50 = /dev/midi03 Fourth MIDI port
- 14 block BIOS harddrive callback support {2.6}
- 0 = /dev/dos_hda First BIOS harddrive whole disk
- 64 = /dev/dos_hdb Second BIOS harddrive whole disk
- 128 = /dev/dos_hdc Third BIOS harddrive whole disk
- 192 = /dev/dos_hdd Fourth BIOS harddrive whole disk
-
- Partitions are handled in the same way as IDE disks
- (see major number 3).
+ 14 block
15 char Joystick
0 = /dev/js0 First analog joystick
@@ -535,14 +533,14 @@ Your cooperation is appreciated.
16 block GoldStar CD-ROM
0 = /dev/gscd GoldStar CD-ROM
- 17 char Chase serial card
+ 17 char OBSOLETE (was Chase serial card)
0 = /dev/ttyH0 First Chase port
1 = /dev/ttyH1 Second Chase port
...
17 block Optics Storage CD-ROM
0 = /dev/optcd Optics Storage CD-ROM
- 18 char Chase serial card - alternate devices
+ 18 char OBSOLETE (was Chase serial card - alternate devices)
0 = /dev/cuh0 Callout device for ttyH0
1 = /dev/cuh1 Callout device for ttyH1
...
@@ -644,8 +642,7 @@ Your cooperation is appreciated.
2 = /dev/sbpcd2 Panasonic CD-ROM controller 0 unit 2
3 = /dev/sbpcd3 Panasonic CD-ROM controller 0 unit 3
- 26 char Quanta WinVision frame grabber {2.6}
- 0 = /dev/wvisfgrab Quanta WinVision frame grabber
+ 26 char
26 block Second Matsushita (Panasonic/SoundBlaster) CD-ROM
0 = /dev/sbpcd4 Panasonic CD-ROM controller 1 unit 0
@@ -872,7 +869,7 @@ Your cooperation is appreciated.
and "user level packet I/O." This board is also
accessible as a standard networking "eth" device.
- 38 block Reserved for Linux/AP+
+ 38 block OBSOLETE (was Linux/AP+)
39 char ML-16P experimental I/O board
0 = /dev/ml16pa-a0 First card, first analog channel
@@ -892,29 +889,16 @@ Your cooperation is appreciated.
50 = /dev/ml16pb-c1 Second card, second counter/timer
51 = /dev/ml16pb-c2 Second card, third counter/timer
...
- 39 block Reserved for Linux/AP+
+ 39 block
- 40 char Matrox Meteor frame grabber {2.6}
- 0 = /dev/mmetfgrab Matrox Meteor frame grabber
+ 40 char
- 40 block Syquest EZ135 parallel port removable drive
- 0 = /dev/eza Parallel EZ135 drive, whole disk
-
- This device is obsolete and will be removed in a
- future version of Linux. It has been replaced with
- the parallel port IDE disk driver at major number 45.
- Partitions are handled in the same way as IDE disks
- (see major number 3).
+ 40 block
41 char Yet Another Micro Monitor
0 = /dev/yamm Yet Another Micro Monitor
- 41 block MicroSolutions BackPack parallel port CD-ROM
- 0 = /dev/bpcd BackPack CD-ROM
-
- This device is obsolete and will be removed in a
- future version of Linux. It has been replaced with
- the parallel port ATAPI CD-ROM driver at major number 46.
+ 41 block
42 char Demo/sample use
@@ -1681,13 +1665,7 @@ Your cooperation is appreciated.
disks (see major number 3) except that the limit on
partitions is 15.
- 93 char IBM Smart Capture Card frame grabber {2.6}
- 0 = /dev/iscc0 First Smart Capture Card
- 1 = /dev/iscc1 Second Smart Capture Card
- ...
- 128 = /dev/isccctl0 First Smart Capture Card control
- 129 = /dev/isccctl1 Second Smart Capture Card control
- ...
+ 93 char
93 block NAND Flash Translation Layer filesystem
0 = /dev/nftla First NFTL layer
@@ -1695,10 +1673,7 @@ Your cooperation is appreciated.
...
240 = /dev/nftlp 16th NTFL layer
- 94 char miroVIDEO DC10/30 capture/playback device {2.6}
- 0 = /dev/dcxx0 First capture card
- 1 = /dev/dcxx1 Second capture card
- ...
+ 94 char
94 block IBM S/390 DASD block storage
0 = /dev/dasda First DASD device, major
@@ -1791,11 +1766,7 @@ Your cooperation is appreciated.
...
15 = /dev/amiraid/ar?p15 15th partition
-102 char Philips SAA5249 Teletext signal decoder {2.6}
- 0 = /dev/tlk0 First Teletext decoder
- 1 = /dev/tlk1 Second Teletext decoder
- 2 = /dev/tlk2 Third Teletext decoder
- 3 = /dev/tlk3 Fourth Teletext decoder
+102 char
102 block Compressed block device
0 = /dev/cbd/a First compressed block device, whole device
@@ -1916,10 +1887,7 @@ Your cooperation is appreciated.
DAC960 (see major number 48) except that the limit on
partitions is 15.
-111 char Philips SAA7146-based audio/video card {2.6}
- 0 = /dev/av0 First A/V card
- 1 = /dev/av1 Second A/V card
- ...
+111 char
111 block Compaq Next Generation Drive Array, eighth controller
0 = /dev/cciss/c7d0 First logical drive, whole disk
@@ -2079,8 +2047,8 @@ Your cooperation is appreciated.
...
119 char VMware virtual network control
- 0 = /dev/vmnet0 1st virtual network
- 1 = /dev/vmnet1 2nd virtual network
+ 0 = /dev/vnet0 1st virtual network
+ 1 = /dev/vnet1 2nd virtual network
...
120-127 char LOCAL/EXPERIMENTAL USE
@@ -2450,7 +2418,7 @@ Your cooperation is appreciated.
2 = /dev/raw/raw2 Second raw I/O device
...
-163 char UNASSIGNED (was Radio Tech BIM-XXX-RS232 radio modem - see 51)
+163 char
164 char Chase Research AT/PCI-Fast serial card
0 = /dev/ttyCH0 AT/PCI-Fast board 0, port 0
@@ -2542,6 +2510,12 @@ Your cooperation is appreciated.
1 = /dev/clanvi1 Second cLAN adapter
...
+179 block MMC block devices
+ 0 = /dev/mmcblk0 First SD/MMC card
+ 1 = /dev/mmcblk0p1 First partition on first MMC card
+ 8 = /dev/mmcblk1 Second SD/MMC card
+ ...
+
179 char CCube DVXChip-based PCI products
0 = /dev/dvxirq0 First DVX device
1 = /dev/dvxirq1 Second DVX device
@@ -2560,6 +2534,9 @@ Your cooperation is appreciated.
96 = /dev/usb/hiddev0 1st USB HID device
...
111 = /dev/usb/hiddev15 16th USB HID device
+ 112 = /dev/usb/auer0 1st auerswald ISDN device
+ ...
+ 127 = /dev/usb/auer15 16th auerswald ISDN device
128 = /dev/usb/brlvgr0 First Braille Voyager device
...
131 = /dev/usb/brlvgr3 Fourth Braille Voyager device
@@ -2810,6 +2787,20 @@ Your cooperation is appreciated.
...
190 = /dev/ttyUL3 Xilinx uartlite - port 3
191 = /dev/xvc0 Xen virtual console - port 0
+ 192 = /dev/ttyPZ0 pmac_zilog - port 0
+ ...
+ 195 = /dev/ttyPZ3 pmac_zilog - port 3
+ 196 = /dev/ttyTX0 TX39/49 serial port 0
+ ...
+ 204 = /dev/ttyTX7 TX39/49 serial port 7
+ 205 = /dev/ttySC0 SC26xx serial port 0
+ 206 = /dev/ttySC1 SC26xx serial port 1
+ 207 = /dev/ttySC2 SC26xx serial port 2
+ 208 = /dev/ttySC3 SC26xx serial port 3
+ 209 = /dev/ttyMAX0 MAX3100 serial port 0
+ 210 = /dev/ttyMAX1 MAX3100 serial port 1
+ 211 = /dev/ttyMAX2 MAX3100 serial port 2
+ 212 = /dev/ttyMAX3 MAX3100 serial port 3
205 char Low-density serial ports (alternate device)
0 = /dev/culu0 Callout device for ttyLU0
@@ -3145,6 +3136,14 @@ Your cooperation is appreciated.
1 = /dev/blockrom1 Second ROM card's translation layer interface
...
+259 block Block Extended Major
+ Used dynamically to hold additional partition minor
+ numbers and allow large numbers of partitions per device
+
+259 char FPGA configuration interfaces
+ 0 = /dev/icap0 First Xilinx internal configuration
+ 1 = /dev/icap1 Second Xilinx internal configuration
+
260 char OSD (Object-based-device) SCSI Device
0 = /dev/osd0 First OSD Device
1 = /dev/osd1 Second OSD Device
diff --git a/Documentation/fb/uvesafb.txt b/Documentation/fb/uvesafb.txt
index 7ac3c4078ff..eefdd91d298 100644
--- a/Documentation/fb/uvesafb.txt
+++ b/Documentation/fb/uvesafb.txt
@@ -59,7 +59,8 @@ Accepted options:
ypan Enable display panning using the VESA protected mode
interface. The visible screen is just a window of the
video memory, console scrolling is done by changing the
- start of the window. Available on x86 only.
+ start of the window. This option is available on x86
+ only and is the default option on that architecture.
ywrap Same as ypan, but assumes your gfx board can wrap-around
the video memory (i.e. starts reading from top if it
@@ -67,7 +68,7 @@ ywrap Same as ypan, but assumes your gfx board can wrap-around
Available on x86 only.
redraw Scroll by redrawing the affected part of the screen, this
- is the safe (and slow) default.
+ is the default on non-x86.
(If you're using uvesafb as a module, the above three options are
used a parameter of the scroll option, e.g. scroll=ypan.)
@@ -182,7 +183,7 @@ from the Video BIOS if you set pixclock to 0 in fb_var_screeninfo.
--
Michal Januszewski <spock@gentoo.org>
- Last updated: 2007-06-16
+ Last updated: 2009-03-30
Documentation of the uvesafb options is loosely based on vesafb.txt.
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index a23361e80c6..de491a3e231 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -283,13 +283,6 @@ Who: Glauber Costa <gcosta@redhat.com>
---------------------------
-What: remove HID compat support
-When: 2.6.29
-Why: needed only as a temporary solution until distros fix themselves up
-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
@@ -361,7 +354,8 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl>
---------------------------
-What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client()
+What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client(),
+ i2c_adapter->client_register(), i2c_adapter->client_unregister
When: 2.6.30
Check: i2c_attach_client i2c_detach_client
Why: Deprecated by the new (standard) device driver binding model. Use
@@ -434,3 +428,12 @@ Why: In 2.6.27, the semantics of /sys/bus/pci/slots was redefined to
After a reasonable transition period, we will remove the legacy
fakephp interface.
Who: Alex Chiang <achiang@hp.com>
+
+---------------------------
+
+What: i2c-voodoo3 driver
+When: October 2009
+Why: Superseded by tdfxfb. I2C/DDC support used to live in a separate
+ driver but this caused driver conflicts.
+Who: Jean Delvare <khali@linux-fr.org>
+ Krzysztof Helt <krzysztof.h1@wp.pl>
diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
index 52cd611277a..8dd6db76171 100644
--- a/Documentation/filesystems/00-INDEX
+++ b/Documentation/filesystems/00-INDEX
@@ -68,6 +68,8 @@ ncpfs.txt
- info on Novell Netware(tm) filesystem using NCP protocol.
nfsroot.txt
- short guide on setting up a diskless box with NFS root filesystem.
+nilfs2.txt
+ - info and mount options for the NILFS2 filesystem.
ntfs.txt
- info and mount options for the NTFS filesystem (Windows NT).
ocfs2.txt
diff --git a/Documentation/filesystems/caching/backend-api.txt b/Documentation/filesystems/caching/backend-api.txt
new file mode 100644
index 00000000000..382d52cdaf2
--- /dev/null
+++ b/Documentation/filesystems/caching/backend-api.txt
@@ -0,0 +1,658 @@
+ ==========================
+ FS-CACHE CACHE BACKEND API
+ ==========================
+
+The FS-Cache system provides an API by which actual caches can be supplied to
+FS-Cache for it to then serve out to network filesystems and other interested
+parties.
+
+This API is declared in <linux/fscache-cache.h>.
+
+
+====================================
+INITIALISING AND REGISTERING A CACHE
+====================================
+
+To start off, a cache definition must be initialised and registered for each
+cache the backend wants to make available. For instance, CacheFS does this in
+the fill_super() operation on mounting.
+
+The cache definition (struct fscache_cache) should be initialised by calling:
+
+ void fscache_init_cache(struct fscache_cache *cache,
+ struct fscache_cache_ops *ops,
+ const char *idfmt,
+ ...);
+
+Where:
+
+ (*) "cache" is a pointer to the cache definition;
+
+ (*) "ops" is a pointer to the table of operations that the backend supports on
+ this cache; and
+
+ (*) "idfmt" is a format and printf-style arguments for constructing a label
+ for the cache.
+
+
+The cache should then be registered with FS-Cache by passing a pointer to the
+previously initialised cache definition to:
+
+ int fscache_add_cache(struct fscache_cache *cache,
+ struct fscache_object *fsdef,
+ const char *tagname);
+
+Two extra arguments should also be supplied:
+
+ (*) "fsdef" which should point to the object representation for the FS-Cache
+ master index in this cache. Netfs primary index entries will be created
+ here. FS-Cache keeps the caller's reference to the index object if
+ successful and will release it upon withdrawal of the cache.
+
+ (*) "tagname" which, if given, should be a text string naming this cache. If
+ this is NULL, the identifier will be used instead. For CacheFS, the
+ identifier is set to name the underlying block device and the tag can be
+ supplied by mount.
+
+This function may return -ENOMEM if it ran out of memory or -EEXIST if the tag
+is already in use. 0 will be returned on success.
+
+
+=====================
+UNREGISTERING A CACHE
+=====================
+
+A cache can be withdrawn from the system by calling this function with a
+pointer to the cache definition:
+
+ void fscache_withdraw_cache(struct fscache_cache *cache);
+
+In CacheFS's case, this is called by put_super().
+
+
+========
+SECURITY
+========
+
+The cache methods are executed one of two contexts:
+
+ (1) that of the userspace process that issued the netfs operation that caused
+ the cache method to be invoked, or
+
+ (2) that of one of the processes in the FS-Cache thread pool.
+
+In either case, this may not be an appropriate context in which to access the
+cache.
+
+The calling process's fsuid, fsgid and SELinux security identities may need to
+be masqueraded for the duration of the cache driver's access to the cache.
+This is left to the cache to handle; FS-Cache makes no effort in this regard.
+
+
+===================================
+CONTROL AND STATISTICS PRESENTATION
+===================================
+
+The cache may present data to the outside world through FS-Cache's interfaces
+in sysfs and procfs - the former for control and the latter for statistics.
+
+A sysfs directory called /sys/fs/fscache/<cachetag>/ is created if CONFIG_SYSFS
+is enabled. This is accessible through the kobject struct fscache_cache::kobj
+and is for use by the cache as it sees fit.
+
+
+========================
+RELEVANT DATA STRUCTURES
+========================
+
+ (*) Index/Data file FS-Cache representation cookie:
+
+ struct fscache_cookie {
+ struct fscache_object_def *def;
+ struct fscache_netfs *netfs;
+ void *netfs_data;
+ ...
+ };
+
+ The fields that might be of use to the backend describe the object
+ definition, the netfs definition and the netfs's data for this cookie.
+ The object definition contain functions supplied by the netfs for loading
+ and matching index entries; these are required to provide some of the
+ cache operations.
+
+
+ (*) In-cache object representation:
+
+ struct fscache_object {
+ int debug_id;
+ enum {
+ FSCACHE_OBJECT_RECYCLING,
+ ...
+ } state;
+ spinlock_t lock
+ struct fscache_cache *cache;
+ struct fscache_cookie *cookie;
+ ...
+ };
+
+ Structures of this type should be allocated by the cache backend and
+ passed to FS-Cache when requested by the appropriate cache operation. In
+ the case of CacheFS, they're embedded in CacheFS's internal object
+ structures.
+
+ The debug_id is a simple integer that can be used in debugging messages
+ that refer to a particular object. In such a case it should be printed
+ using "OBJ%x" to be consistent with FS-Cache.
+
+ Each object contains a pointer to the cookie that represents the object it
+ is backing. An object should retired when put_object() is called if it is
+ in state FSCACHE_OBJECT_RECYCLING. The fscache_object struct should be
+ initialised by calling fscache_object_init(object).
+
+
+ (*) FS-Cache operation record:
+
+ struct fscache_operation {
+ atomic_t usage;
+ struct fscache_object *object;
+ unsigned long flags;
+ #define FSCACHE_OP_EXCLUSIVE
+ void (*processor)(struct fscache_operation *op);
+ void (*release)(struct fscache_operation *op);
+ ...
+ };
+
+ FS-Cache has a pool of threads that it uses to give CPU time to the
+ various asynchronous operations that need to be done as part of driving
+ the cache. These are represented by the above structure. The processor
+ method is called to give the op CPU time, and the release method to get
+ rid of it when its usage count reaches 0.
+
+ An operation can be made exclusive upon an object by setting the
+ appropriate flag before enqueuing it with fscache_enqueue_operation(). If
+ an operation needs more processing time, it should be enqueued again.
+
+
+ (*) FS-Cache retrieval operation record:
+
+ struct fscache_retrieval {
+ struct fscache_operation op;
+ struct address_space *mapping;
+ struct list_head *to_do;
+ ...
+ };
+
+ A structure of this type is allocated by FS-Cache to record retrieval and
+ allocation requests made by the netfs. This struct is then passed to the
+ backend to do the operation. The backend may get extra refs to it by
+ calling fscache_get_retrieval() and refs may be discarded by calling
+ fscache_put_retrieval().
+
+ A retrieval operation can be used by the backend to do retrieval work. To
+ do this, the retrieval->op.processor method pointer should be set
+ appropriately by the backend and fscache_enqueue_retrieval() called to
+ submit it to the thread pool. CacheFiles, for example, uses this to queue
+ page examination when it detects PG_lock being cleared.
+
+ The to_do field is an empty list available for the cache backend to use as
+ it sees fit.
+
+
+ (*) FS-Cache storage operation record:
+
+ struct fscache_storage {
+ struct fscache_operation op;
+ pgoff_t store_limit;
+ ...
+ };
+
+ A structure of this type is allocated by FS-Cache to record outstanding
+ writes to be made. FS-Cache itself enqueues this operation and invokes
+ the write_page() method on the object at appropriate times to effect
+ storage.
+
+
+================
+CACHE OPERATIONS
+================
+
+The cache backend provides FS-Cache with a table of operations that can be
+performed on the denizens of the cache. These are held in a structure of type:
+
+ struct fscache_cache_ops
+
+ (*) Name of cache provider [mandatory]:
+
+ const char *name
+
+ This isn't strictly an operation, but should be pointed at a string naming
+ the backend.
+
+
+ (*) Allocate a new object [mandatory]:
+
+ struct fscache_object *(*alloc_object)(struct fscache_cache *cache,
+ struct fscache_cookie *cookie)
+
+ This method is used to allocate a cache object representation to back a
+ cookie in a particular cache. fscache_object_init() should be called on
+ the object to initialise it prior to returning.
+
+ This function may also be used to parse the index key to be used for
+ multiple lookup calls to turn it into a more convenient form. FS-Cache
+ will call the lookup_complete() method to allow the cache to release the
+ form once lookup is complete or aborted.
+
+
+ (*) Look up and create object [mandatory]:
+
+ void (*lookup_object)(struct fscache_object *object)
+
+ This method is used to look up an object, given that the object is already
+ allocated and attached to the cookie. This should instantiate that object
+ in the cache if it can.
+
+ The method should call fscache_object_lookup_negative() as soon as
+ possible if it determines the object doesn't exist in the cache. If the
+ object is found to exist and the netfs indicates that it is valid then
+ fscache_obtained_object() should be called once the object is in a
+ position to have data stored in it. Similarly, fscache_obtained_object()
+ should also be called once a non-present object has been created.
+
+ If a lookup error occurs, fscache_object_lookup_error() should be called
+ to abort the lookup of that object.
+
+
+ (*) Release lookup data [mandatory]:
+
+ void (*lookup_complete)(struct fscache_object *object)
+
+ This method is called to ask the cache to release any resources it was
+ using to perform a lookup.
+
+
+ (*) Increment object refcount [mandatory]:
+
+ struct fscache_object *(*grab_object)(struct fscache_object *object)
+
+ This method is called to increment the reference count on an object. It
+ may fail (for instance if the cache is being withdrawn) by returning NULL.
+ It should return the object pointer if successful.
+
+
+ (*) Lock/Unlock object [mandatory]:
+
+ void (*lock_object)(struct fscache_object *object)
+ void (*unlock_object)(struct fscache_object *object)
+
+ These methods are used to exclusively lock an object. It must be possible
+ to schedule with the lock held, so a spinlock isn't sufficient.
+
+
+ (*) Pin/Unpin object [optional]:
+
+ int (*pin_object)(struct fscache_object *object)
+ void (*unpin_object)(struct fscache_object *object)
+
+ These methods are used to pin an object into the cache. Once pinned an
+ object cannot be reclaimed to make space. Return -ENOSPC if there's not
+ enough space in the cache to permit this.
+
+
+ (*) Update object [mandatory]:
+
+ int (*update_object)(struct fscache_object *object)
+
+ This is called to update the index entry for the specified object. The
+ new information should be in object->cookie->netfs_data. This can be
+ obtained by calling object->cookie->def->get_aux()/get_attr().
+
+
+ (*) Discard object [mandatory]:
+
+ void (*drop_object)(struct fscache_object *object)
+
+ This method is called to indicate that an object has been unbound from its
+ cookie, and that the cache should release the object's resources and
+ retire it if it's in state FSCACHE_OBJECT_RECYCLING.
+
+ This method should not attempt to release any references held by the
+ caller. The caller will invoke the put_object() method as appropriate.
+
+
+ (*) Release object reference [mandatory]:
+
+ void (*put_object)(struct fscache_object *object)
+
+ This method is used to discard a reference to an object. The object may
+ be freed when all the references to it are released.
+
+
+ (*) Synchronise a cache [mandatory]:
+
+ void (*sync)(struct fscache_cache *cache)
+
+ This is called to ask the backend to synchronise a cache with its backing
+ device.
+
+
+ (*) Dissociate a cache [mandatory]:
+
+ void (*dissociate_pages)(struct fscache_cache *cache)
+
+ This is called to ask a cache to perform any page dissociations as part of
+ cache withdrawal.
+
+
+ (*) Notification that the attributes on a netfs file changed [mandatory]:
+
+ int (*attr_changed)(struct fscache_object *object);
+
+ This is called to indicate to the cache that certain attributes on a netfs
+ file have changed (for example the maximum size a file may reach). The
+ cache can read these from the netfs by calling the cookie's get_attr()
+ method.
+
+ The cache may use the file size information to reserve space on the cache.
+ It should also call fscache_set_store_limit() to indicate to FS-Cache the
+ highest byte it's willing to store for an object.
+
+ This method may return -ve if an error occurred or the cache object cannot
+ be expanded. In such a case, the object will be withdrawn from service.
+
+ This operation is run asynchronously from FS-Cache's thread pool, and
+ storage and retrieval operations from the netfs are excluded during the
+ execution of this operation.
+
+
+ (*) Reserve cache space for an object's data [optional]:
+
+ int (*reserve_space)(struct fscache_object *object, loff_t size);
+
+ This is called to request that cache space be reserved to hold the data
+ for an object and the metadata used to track it. Zero size should be
+ taken as request to cancel a reservation.
+
+ This should return 0 if successful, -ENOSPC if there isn't enough space
+ available, or -ENOMEM or -EIO on other errors.
+
+ The reservation may exceed the current size of the object, thus permitting
+ future expansion. If the amount of space consumed by an object would
+ exceed the reservation, it's permitted to refuse requests to allocate
+ pages, but not required. An object may be pruned down to its reservation
+ size if larger than that already.
+
+
+ (*) Request page be read from cache [mandatory]:
+
+ int (*read_or_alloc_page)(struct fscache_retrieval *op,
+ struct page *page,
+ gfp_t gfp)
+
+ This is called to attempt to read a netfs page from the cache, or to
+ reserve a backing block if not. FS-Cache will have done as much checking
+ as it can before calling, but most of the work belongs to the backend.
+
+ If there's no page in the cache, then -ENODATA should be returned if the
+ backend managed to reserve a backing block; -ENOBUFS or -ENOMEM if it
+ didn't.
+
+ If there is suitable data in the cache, then a read operation should be
+ queued and 0 returned. When the read finishes, fscache_end_io() should be
+ called.
+
+ The fscache_mark_pages_cached() should be called for the page if any cache
+ metadata is retained. This will indicate to the netfs that the page needs
+ explicit uncaching. This operation takes a pagevec, thus allowing several
+ pages to be marked at once.
+
+ The retrieval record pointed to by op should be retained for each page
+ queued and released when I/O on the page has been formally ended.
+ fscache_get/put_retrieval() are available for this purpose.
+
+ The retrieval record may be used to get CPU time via the FS-Cache thread
+ pool. If this is desired, the op->op.processor should be set to point to
+ the appropriate processing routine, and fscache_enqueue_retrieval() should
+ be called at an appropriate point to request CPU time. For instance, the
+ retrieval routine could be enqueued upon the completion of a disk read.
+ The to_do field in the retrieval record is provided to aid in this.
+
+ If an I/O error occurs, fscache_io_error() should be called and -ENOBUFS
+ returned if possible or fscache_end_io() called with a suitable error
+ code..
+
+
+ (*) Request pages be read from cache [mandatory]:
+
+ int (*read_or_alloc_pages)(struct fscache_retrieval *op,
+ struct list_head *pages,
+ unsigned *nr_pages,
+ gfp_t gfp)
+
+ This is like the read_or_alloc_page() method, except it is handed a list
+ of pages instead of one page. Any pages on which a read operation is
+ started must be added to the page cache for the specified mapping and also
+ to the LRU. Such pages must also be removed from the pages list and
+ *nr_pages decremented per page.
+
+ If there was an error such as -ENOMEM, then that should be returned; else
+ if one or more pages couldn't be read or allocated, then -ENOBUFS should
+ be returned; else if one or more pages couldn't be read, then -ENODATA
+ should be returned. If all the pages are dispatched then 0 should be
+ returned.
+
+
+ (*) Request page be allocated in the cache [mandatory]:
+
+ int (*allocate_page)(struct fscache_retrieval *op,
+ struct page *page,
+ gfp_t gfp)
+
+ This is like the read_or_alloc_page() method, except that it shouldn't
+ read from the cache, even if there's data there that could be retrieved.
+ It should, however, set up any internal metadata required such that
+ the write_page() method can write to the cache.
+
+ If there's no backing block available, then -ENOBUFS should be returned
+ (or -ENOMEM if there were other problems). If a block is successfully
+ allocated, then the netfs page should be marked and 0 returned.
+
+
+ (*) Request pages be allocated in the cache [mandatory]:
+
+ int (*allocate_pages)(struct fscache_retrieval *op,
+ struct list_head *pages,
+ unsigned *nr_pages,
+ gfp_t gfp)
+
+ This is an multiple page version of the allocate_page() method. pages and
+ nr_pages should be treated as for the read_or_alloc_pages() method.
+
+
+ (*) Request page be written to cache [mandatory]:
+
+ int (*write_page)(struct fscache_storage *op,
+ struct page *page);
+
+ This is called to write from a page on which there was a previously
+ successful read_or_alloc_page() call or similar. FS-Cache filters out
+ pages that don't have mappings.
+
+ This method is called asynchronously from the FS-Cache thread pool. It is
+ not required to actually store anything, provided -ENODATA is then
+ returned to the next read of this page.
+
+ If an error occurred, then a negative error code should be returned,
+ otherwise zero should be returned. FS-Cache will take appropriate action
+ in response to an error, such as withdrawing this object.
+
+ If this method returns success then FS-Cache will inform the netfs
+ appropriately.
+
+
+ (*) Discard retained per-page metadata [mandatory]:
+
+ void (*uncache_page)(struct fscache_object *object, struct page *page)
+
+ This is called when a netfs page is being evicted from the pagecache. The
+ cache backend should tear down any internal representation or tracking it
+ maintains for this page.
+
+
+==================
+FS-CACHE UTILITIES
+==================
+
+FS-Cache provides some utilities that a cache backend may make use of:
+
+ (*) Note occurrence of an I/O error in a cache:
+
+ void fscache_io_error(struct fscache_cache *cache)
+
+ This tells FS-Cache that an I/O error occurred in the cache. After this
+ has been called, only resource dissociation operations (object and page
+ release) will be passed from the netfs to the cache backend for the
+ specified cache.
+
+ This does not actually withdraw the cache. That must be done separately.
+
+
+ (*) Invoke the retrieval I/O completion function:
+
+ void fscache_end_io(struct fscache_retrieval *op, struct page *page,
+ int error);
+
+ This is called to note the end of an attempt to retrieve a page. The
+ error value should be 0 if successful and an error otherwise.
+
+
+ (*) Set highest store limit:
+
+ void fscache_set_store_limit(struct fscache_object *object,
+ loff_t i_size);
+
+ This sets the limit FS-Cache imposes on the highest byte it's willing to
+ try and store for a netfs. Any page over this limit is automatically
+ rejected by fscache_read_alloc_page() and co with -ENOBUFS.
+
+
+ (*) Mark pages as being cached:
+
+ void fscache_mark_pages_cached(struct fscache_retrieval *op,
+ struct pagevec *pagevec);
+
+ This marks a set of pages as being cached. After this has been called,
+ the netfs must call fscache_uncache_page() to unmark the pages.
+
+
+ (*) Perform coherency check on an object:
+
+ enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
+ const void *data,
+ uint16_t datalen);
+
+ This asks the netfs to perform a coherency check on an object that has
+ just been looked up. The cookie attached to the object will determine the
+ netfs to use. data and datalen should specify where the auxiliary data
+ retrieved from the cache can be found.
+
+ One of three values will be returned:
+
+ (*) FSCACHE_CHECKAUX_OKAY
+
+ The coherency data indicates the object is valid as is.
+
+ (*) FSCACHE_CHECKAUX_NEEDS_UPDATE
+
+ The coherency data needs updating, but otherwise the object is
+ valid.
+
+ (*) FSCACHE_CHECKAUX_OBSOLETE
+
+ The coherency data indicates that the object is obsolete and should
+ be discarded.
+
+
+ (*) Initialise a freshly allocated object:
+
+ void fscache_object_init(struct fscache_object *object);
+
+ This initialises all the fields in an object representation.
+
+
+ (*) Indicate the destruction of an object:
+
+ void fscache_object_destroyed(struct fscache_cache *cache);
+
+ This must be called to inform FS-Cache that an object that belonged to a
+ cache has been destroyed and deallocated. This will allow continuation
+ of the cache withdrawal process when it is stopped pending destruction of
+ all the objects.
+
+
+ (*) Indicate negative lookup on an object:
+
+ void fscache_object_lookup_negative(struct fscache_object *object);
+
+ This is called to indicate to FS-Cache that a lookup process for an object
+ found a negative result.
+
+ This changes the state of an object to permit reads pending on lookup
+ completion to go off and start fetching data from the netfs server as it's
+ known at this point that there can't be any data in the cache.
+
+ This may be called multiple times on an object. Only the first call is
+ significant - all subsequent calls are ignored.
+
+
+ (*) Indicate an object has been obtained:
+
+ void fscache_obtained_object(struct fscache_object *object);
+
+ This is called to indicate to FS-Cache that a lookup process for an object
+ produced a positive result, or that an object was created. This should
+ only be called once for any particular object.
+
+ This changes the state of an object to indicate:
+
+ (1) if no call to fscache_object_lookup_negative() has been made on
+ this object, that there may be data available, and that reads can
+ now go and look for it; and
+
+ (2) that writes may now proceed against this object.
+
+
+ (*) Indicate that object lookup failed:
+
+ void fscache_object_lookup_error(struct fscache_object *object);
+
+ This marks an object as having encountered a fatal error (usually EIO)
+ and causes it to move into a state whereby it will be withdrawn as soon
+ as possible.
+
+
+ (*) Get and release references on a retrieval record:
+
+ void fscache_get_retrieval(struct fscache_retrieval *op);
+ void fscache_put_retrieval(struct fscache_retrieval *op);
+
+ These two functions are used to retain a retrieval record whilst doing
+ asynchronous data retrieval and block allocation.
+
+
+ (*) Enqueue a retrieval record for processing.
+
+ void fscache_enqueue_retrieval(struct fscache_retrieval *op);
+
+ This enqueues a retrieval record for processing by the FS-Cache thread
+ pool. One of the threads in the pool will invoke the retrieval record's
+ op->op.processor callback function. This function may be called from
+ within the callback function.
+
+
+ (*) List of object state names:
+
+ const char *fscache_object_states[];
+
+ For debugging purposes, this may be used to turn the state that an object
+ is in into a text string for display purposes.
diff --git a/Documentation/filesystems/caching/cachefiles.txt b/Documentation/filesystems/caching/cachefiles.txt
new file mode 100644
index 00000000000..c78a49b7bba
--- /dev/null
+++ b/Documentation/filesystems/caching/cachefiles.txt
@@ -0,0 +1,501 @@
+ ===============================================
+ CacheFiles: CACHE ON ALREADY MOUNTED FILESYSTEM
+ ===============================================
+
+Contents:
+
+ (*) Overview.
+
+ (*) Requirements.
+
+ (*) Configuration.
+
+ (*) Starting the cache.
+
+ (*) Things to avoid.
+
+ (*) Cache culling.
+
+ (*) Cache structure.
+
+ (*) Security model and SELinux.
+
+ (*) A note on security.
+
+ (*) Statistical information.
+
+ (*) Debugging.
+
+
+========
+OVERVIEW
+========
+
+CacheFiles is a caching backend that's meant to use as a cache a directory on
+an already mounted filesystem of a local type (such as Ext3).
+
+CacheFiles uses a userspace daemon to do some of the cache management - such as
+reaping stale nodes and culling. This is called cachefilesd and lives in
+/sbin.
+
+The filesystem and data integrity of the cache are only as good as those of the
+filesystem providing the backing services. Note that CacheFiles does not
+attempt to journal anything since the journalling interfaces of the various
+filesystems are very specific in nature.
+
+CacheFiles creates a misc character device - "/dev/cachefiles" - that is used
+to communication with the daemon. Only one thing may have this open at once,
+and whilst it is open, a cache is at least partially in existence. The daemon
+opens this and sends commands down it to control the cache.
+
+CacheFiles is currently limited to a single cache.
+
+CacheFiles attempts to maintain at least a certain percentage of free space on
+the filesystem, shrinking the cache by culling the objects it contains to make
+space if necessary - see the "Cache Culling" section. This means it can be
+placed on the same medium as a live set of data, and will expand to make use of
+spare space and automatically contract when the set of data requires more
+space.
+
+
+============
+REQUIREMENTS
+============
+
+The use of CacheFiles and its daemon requires the following features to be
+available in the system and in the cache filesystem:
+
+ - dnotify.
+
+ - extended attributes (xattrs).
+
+ - openat() and friends.
+
+ - bmap() support on files in the filesystem (FIBMAP ioctl).
+
+ - The use of bmap() to detect a partial page at the end of the file.
+
+It is strongly recommended that the "dir_index" option is enabled on Ext3
+filesystems being used as a cache.
+
+
+=============
+CONFIGURATION
+=============
+
+The cache is configured by a script in /etc/cachefilesd.conf. These commands
+set up cache ready for use. The following script commands are available:
+
+ (*) brun <N>%
+ (*) bcull <N>%
+ (*) bstop <N>%
+ (*) frun <N>%
+ (*) fcull <N>%
+ (*) fstop <N>%
+
+ Configure the culling limits. Optional. See the section on culling
+ The defaults are 7% (run), 5% (cull) and 1% (stop) respectively.
+
+ The commands beginning with a 'b' are file space (block) limits, those
+ beginning with an 'f' are file count limits.
+
+ (*) dir <path>
+
+ Specify the directory containing the root of the cache. Mandatory.
+
+ (*) tag <name>
+
+ Specify a tag to FS-Cache to use in distinguishing multiple caches.
+ Optional. The default is "CacheFiles".
+
+ (*) debug <mask>
+
+ Specify a numeric bitmask to control debugging in the kernel module.
+ Optional. The default is zero (all off). The following values can be
+ OR'd into the mask to collect various information:
+
+ 1 Turn on trace of function entry (_enter() macros)
+ 2 Turn on trace of function exit (_leave() macros)
+ 4 Turn on trace of internal debug points (_debug())
+
+ This mask can also be set through sysfs, eg:
+
+ echo 5 >/sys/modules/cachefiles/parameters/debug
+
+
+==================
+STARTING THE CACHE
+==================
+
+The cache is started by running the daemon. The daemon opens the cache device,
+configures the cache and tells it to begin caching. At that point the cache
+binds to fscache and the cache becomes live.
+
+The daemon is run as follows:
+
+ /sbin/cachefilesd [-d]* [-s] [-n] [-f <configfile>]
+
+The flags are:
+
+ (*) -d
+
+ Increase the debugging level. This can be specified multiple times and
+ is cumulative with itself.
+
+ (*) -s
+
+ Send messages to stderr instead of syslog.
+
+ (*) -n
+
+ Don't daemonise and go into background.
+
+ (*) -f <configfile>
+
+ Use an alternative configuration file rather than the default one.
+
+
+===============
+THINGS TO AVOID
+===============
+
+Do not mount other things within the cache as this will cause problems. The
+kernel module contains its own very cut-down path walking facility that ignores
+mountpoints, but the daemon can't avoid them.
+
+Do not create, rename or unlink files and directories in the cache whilst the
+cache is active, as this may cause the state to become uncertain.
+
+Renaming files in the cache might make objects appear to be other objects (the
+filename is part of the lookup key).
+
+Do not change or remove the extended attributes attached to cache files by the
+cache as this will cause the cache state management to get confused.
+
+Do not create files or directories in the cache, lest the cache get confused or
+serve incorrect data.
+
+Do not chmod files in the cache. The module creates things with minimal
+permissions to prevent random users being able to access them directly.
+
+
+=============
+CACHE CULLING
+=============
+
+The cache may need culling occasionally to make space. This involves
+discarding objects from the cache that have been used less recently than
+anything else. Culling is based on the access time of data objects. Empty
+directories are culled if not in use.
+
+Cache culling is done on the basis of the percentage of blocks and the
+percentage of files available in the underlying filesystem. There are six
+"limits":
+
+ (*) brun
+ (*) frun
+
+ If the amount of free space and the number of available files in the cache
+ rises above both these limits, then culling is turned off.
+
+ (*) bcull
+ (*) fcull
+
+ If the amount of available space or the number of available files in the
+ cache falls below either of these limits, then culling is started.
+
+ (*) bstop
+ (*) fstop
+
+ If the amount of available space or the number of available files in the
+ cache falls below either of these limits, then no further allocation of
+ disk space or files is permitted until culling has raised things above
+ these limits again.
+
+These must be configured thusly:
+
+ 0 <= bstop < bcull < brun < 100
+ 0 <= fstop < fcull < frun < 100
+
+Note that these are percentages of available space and available files, and do
+_not_ appear as 100 minus the percentage displayed by the "df" program.
+
+The userspace daemon scans the cache to build up a table of cullable objects.
+These are then culled in least recently used order. A new scan of the cache is
+started as soon as space is made in the table. Objects will be skipped if
+their atimes have changed or if the kernel module says it is still using them.
+
+
+===============
+CACHE STRUCTURE
+===============
+
+The CacheFiles module will create two directories in the directory it was
+given:
+
+ (*) cache/
+
+ (*) graveyard/
+
+The active cache objects all reside in the first directory. The CacheFiles
+kernel module moves any retired or culled objects that it can't simply unlink
+to the graveyard from which the daemon will actually delete them.
+
+The daemon uses dnotify to monitor the graveyard directory, and will delete
+anything that appears therein.
+
+
+The module represents index objects as directories with the filename "I..." or
+"J...". Note that the "cache/" directory is itself a special index.
+
+Data objects are represented as files if they have no children, or directories
+if they do. Their filenames all begin "D..." or "E...". If represented as a
+directory, data objects will have a file in the directory called "data" that
+actually holds the data.
+
+Special objects are similar to data objects, except their filenames begin
+"S..." or "T...".
+
+
+If an object has children, then it will be represented as a directory.
+Immediately in the representative directory are a collection of directories
+named for hash values of the child object keys with an '@' prepended. Into
+this directory, if possible, will be placed the representations of the child
+objects:
+
+ INDEX INDEX INDEX DATA FILES
+ ========= ========== ================================= ================
+ cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400
+ cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...DB1ry
+ cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...N22ry
+ cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...FP1ry
+
+
+If the key is so long that it exceeds NAME_MAX with the decorations added on to
+it, then it will be cut into pieces, the first few of which will be used to
+make a nest of directories, and the last one of which will be the objects
+inside the last directory. The names of the intermediate directories will have
+'+' prepended:
+
+ J1223/@23/+xy...z/+kl...m/Epqr
+
+
+Note that keys are raw data, and not only may they exceed NAME_MAX in size,
+they may also contain things like '/' and NUL characters, and so they may not
+be suitable for turning directly into a filename.
+
+To handle this, CacheFiles will use a suitably printable filename directly and
+"base-64" encode ones that aren't directly suitable. The two versions of
+object filenames indicate the encoding:
+
+ OBJECT TYPE PRINTABLE ENCODED
+ =============== =============== ===============
+ Index "I..." "J..."
+ Data "D..." "E..."
+ Special "S..." "T..."
+
+Intermediate directories are always "@" or "+" as appropriate.
+
+
+Each object in the cache has an extended attribute label that holds the object
+type ID (required to distinguish special objects) and the auxiliary data from
+the netfs. The latter is used to detect stale objects in the cache and update
+or retire them.
+
+
+Note that CacheFiles will erase from the cache any file it doesn't recognise or
+any file of an incorrect type (such as a FIFO file or a device file).
+
+
+==========================
+SECURITY MODEL AND SELINUX
+==========================
+
+CacheFiles is implemented to deal properly with the LSM security features of
+the Linux kernel and the SELinux facility.
+
+One of the problems that CacheFiles faces is that it is generally acting on
+behalf of a process, and running in that process's context, and that includes a
+security context that is not appropriate for accessing the cache - either
+because the files in the cache are inaccessible to that process, or because if
+the process creates a file in the cache, that file may be inaccessible to other
+processes.
+
+The way CacheFiles works is to temporarily change the security context (fsuid,
+fsgid and actor security label) that the process acts as - without changing the
+security context of the process when it the target of an operation performed by
+some other process (so signalling and suchlike still work correctly).
+
+
+When the CacheFiles module is asked to bind to its cache, it:
+
+ (1) Finds the security label attached to the root cache directory and uses
+ that as the security label with which it will create files. By default,
+ this is:
+
+ cachefiles_var_t
+
+ (2) Finds the security label of the process which issued the bind request
+ (presumed to be the cachefilesd daemon), which by default will be:
+
+ cachefilesd_t
+
+ and asks LSM to supply a security ID as which it should act given the
+ daemon's label. By default, this will be:
+
+ cachefiles_kernel_t
+
+ SELinux transitions the daemon's security ID to the module's security ID
+ based on a rule of this form in the policy.
+
+ type_transition <daemon's-ID> kernel_t : process <module's-ID>;
+
+ For instance:
+
+ type_transition cachefilesd_t kernel_t : process cachefiles_kernel_t;
+
+
+The module's security ID gives it permission to create, move and remove files
+and directories in the cache, to find and access directories and files in the
+cache, to set and access extended attributes on cache objects, and to read and
+write files in the cache.
+
+The daemon's security ID gives it only a very restricted set of permissions: it
+may scan directories, stat files and erase files and directories. It may
+not read or write files in the cache, and so it is precluded from accessing the
+data cached therein; nor is it permitted to create new files in the cache.
+
+
+There are policy source files available in:
+
+ http://people.redhat.com/~dhowells/fscache/cachefilesd-0.8.tar.bz2
+
+and later versions. In that tarball, see the files:
+
+ cachefilesd.te
+ cachefilesd.fc
+ cachefilesd.if
+
+They are built and installed directly by the RPM.
+
+If a non-RPM based system is being used, then copy the above files to their own
+directory and run:
+
+ make -f /usr/share/selinux/devel/Makefile
+ semodule -i cachefilesd.pp
+
+You will need checkpolicy and selinux-policy-devel installed prior to the
+build.
+
+
+By default, the cache is located in /var/fscache, but if it is desirable that
+it should be elsewhere, than either the above policy files must be altered, or
+an auxiliary policy must be installed to label the alternate location of the
+cache.
+
+For instructions on how to add an auxiliary policy to enable the cache to be
+located elsewhere when SELinux is in enforcing mode, please see:
+
+ /usr/share/doc/cachefilesd-*/move-cache.txt
+
+When the cachefilesd rpm is installed; alternatively, the document can be found
+in the sources.
+
+
+==================
+A NOTE ON SECURITY
+==================
+
+CacheFiles makes use of the split security in the task_struct. It allocates
+its own task_security structure, and redirects current->act_as to point to it
+when it acts on behalf of another process, in that process's context.
+
+The reason it does this is that it calls vfs_mkdir() and suchlike rather than
+bypassing security and calling inode ops directly. Therefore the VFS and LSM
+may deny the CacheFiles access to the cache data because under some
+circumstances the caching code is running in the security context of whatever
+process issued the original syscall on the netfs.
+
+Furthermore, should CacheFiles create a file or directory, the security
+parameters with that object is created (UID, GID, security label) would be
+derived from that process that issued the system call, thus potentially
+preventing other processes from accessing the cache - including CacheFiles's
+cache management daemon (cachefilesd).
+
+What is required is to temporarily override the security of the process that
+issued the system call. We can't, however, just do an in-place change of the
+security data as that affects the process as an object, not just as a subject.
+This means it may lose signals or ptrace events for example, and affects what
+the process looks like in /proc.
+
+So CacheFiles makes use of a logical split in the security between the
+objective security (task->sec) and the subjective security (task->act_as). The
+objective security holds the intrinsic security properties of a process and is
+never overridden. This is what appears in /proc, and is what is used when a
+process is the target of an operation by some other process (SIGKILL for
+example).
+
+The subjective security holds the active security properties of a process, and
+may be overridden. This is not seen externally, and is used whan a process
+acts upon another object, for example SIGKILLing another process or opening a
+file.
+
+LSM hooks exist that allow SELinux (or Smack or whatever) to reject a request
+for CacheFiles to run in a context of a specific security label, or to create
+files and directories with another security label.
+
+
+=======================
+STATISTICAL INFORMATION
+=======================
+
+If FS-Cache is compiled with the following option enabled:
+
+ CONFIG_CACHEFILES_HISTOGRAM=y
+
+then it will gather certain statistics and display them through a proc file.
+
+ (*) /proc/fs/cachefiles/histogram
+
+ cat /proc/fs/cachefiles/histogram
+ JIFS SECS LOOKUPS MKDIRS CREATES
+ ===== ===== ========= ========= =========
+
+ This shows the breakdown of the number of times each amount of time
+ between 0 jiffies and HZ-1 jiffies a variety of tasks took to run. The
+ columns are as follows:
+
+ COLUMN TIME MEASUREMENT
+ ======= =======================================================
+ LOOKUPS Length of time to perform a lookup on the backing fs
+ MKDIRS Length of time to perform a mkdir on the backing fs
+ CREATES Length of time to perform a create on the backing fs
+
+ Each row shows the number of events that took a particular range of times.
+ Each step is 1 jiffy in size. The JIFS column indicates the particular
+ jiffy range covered, and the SECS field the equivalent number of seconds.
+
+
+=========
+DEBUGGING
+=========
+
+If CONFIG_CACHEFILES_DEBUG is enabled, the CacheFiles facility can have runtime
+debugging enabled by adjusting the value in:
+
+ /sys/module/cachefiles/parameters/debug
+
+This is a bitmask of debugging streams to enable:
+
+ BIT VALUE STREAM POINT
+ ======= ======= =============================== =======================
+ 0 1 General Function entry trace
+ 1 2 Function exit trace
+ 2 4 General
+
+The appropriate set of values should be OR'd together and the result written to
+the control file. For example:
+
+ echo $((1|4|8)) >/sys/module/cachefiles/parameters/debug
+
+will turn on all function entry debugging.
diff --git a/Documentation/filesystems/caching/fscache.txt b/Documentation/filesystems/caching/fscache.txt
new file mode 100644
index 00000000000..9e94b9491d8
--- /dev/null
+++ b/Documentation/filesystems/caching/fscache.txt
@@ -0,0 +1,333 @@
+ ==========================
+ General Filesystem Caching
+ ==========================
+
+========
+OVERVIEW
+========
+
+This facility is a general purpose cache for network filesystems, though it
+could be used for caching other things such as ISO9660 filesystems too.
+
+FS-Cache mediates between cache backends (such as CacheFS) and network
+filesystems:
+
+ +---------+
+ | | +--------------+
+ | NFS |--+ | |
+ | | | +-->| CacheFS |
+ +---------+ | +----------+ | | /dev/hda5 |
+ | | | | +--------------+
+ +---------+ +-->| | |
+ | | | |--+
+ | AFS |----->| FS-Cache |
+ | | | |--+
+ +---------+ +-->| | |
+ | | | | +--------------+
+ +---------+ | +----------+ | | |
+ | | | +-->| CacheFiles |
+ | ISOFS |--+ | /var/cache |
+ | | +--------------+
+ +---------+
+
+Or to look at it another way, FS-Cache is a module that provides a caching
+facility to a network filesystem such that the cache is transparent to the
+user:
+
+ +---------+
+ | |
+ | Server |
+ | |
+ +---------+
+ | NETWORK
+ ~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ |
+ | +----------+
+ V | |
+ +---------+ | |
+ | | | |
+ | NFS |----->| FS-Cache |
+ | | | |--+
+ +---------+ | | | +--------------+ +--------------+
+ | | | | | | | |
+ V +----------+ +-->| CacheFiles |-->| Ext3 |
+ +---------+ | /var/cache | | /dev/sda6 |
+ | | +--------------+ +--------------+
+ | VFS | ^ ^
+ | | | |
+ +---------+ +--------------+ |
+ | KERNEL SPACE | |
+ ~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~|~~~~
+ | USER SPACE | |
+ V | |
+ +---------+ +--------------+
+ | | | |
+ | Process | | cachefilesd |
+ | | | |
+ +---------+ +--------------+
+
+
+FS-Cache does not follow the idea of completely loading every netfs file
+opened in its entirety into a cache before permitting it to be accessed and
+then serving the pages out of that cache rather than the netfs inode because:
+
+ (1) It must be practical to operate without a cache.
+
+ (2) The size of any accessible file must not be limited to the size of the
+ cache.
+
+ (3) The combined size of all opened files (this includes mapped libraries)
+ must not be limited to the size of the cache.
+
+ (4) The user should not be forced to download an entire file just to do a
+ one-off access of a small portion of it (such as might be done with the
+ "file" program).
+
+It instead serves the cache out in PAGE_SIZE chunks as and when requested by
+the netfs('s) using it.
+
+
+FS-Cache provides the following facilities:
+
+ (1) More than one cache can be used at once. Caches can be selected
+ explicitly by use of tags.
+
+ (2) Caches can be added / removed at any time.
+
+ (3) The netfs is provided with an interface that allows either party to
+ withdraw caching facilities from a file (required for (2)).
+
+ (4) The interface to the netfs returns as few errors as possible, preferring
+ rather to let the netfs remain oblivious.
+
+ (5) Cookies are used to represent indices, files and other objects to the
+ netfs. The simplest cookie is just a NULL pointer - indicating nothing
+ cached there.
+
+ (6) The netfs is allowed to propose - dynamically - any index hierarchy it
+ desires, though it must be aware that the index search function is
+ recursive, stack space is limited, and indices can only be children of
+ indices.
+
+ (7) Data I/O is done direct to and from the netfs's pages. The netfs
+ indicates that page A is at index B of the data-file represented by cookie
+ C, and that it should be read or written. The cache backend may or may
+ not start I/O on that page, but if it does, a netfs callback will be
+ invoked to indicate completion. The I/O may be either synchronous or
+ asynchronous.
+
+ (8) Cookies can be "retired" upon release. At this point FS-Cache will mark
+ them as obsolete and the index hierarchy rooted at that point will get
+ recycled.
+
+ (9) The netfs provides a "match" function for index searches. In addition to
+ saying whether a match was made or not, this can also specify that an
+ entry should be updated or deleted.
+
+(10) As much as possible is done asynchronously.
+
+
+FS-Cache maintains a virtual indexing tree in which all indices, files, objects
+and pages are kept. Bits of this tree may actually reside in one or more
+caches.
+
+ FSDEF
+ |
+ +------------------------------------+
+ | |
+ NFS AFS
+ | |
+ +--------------------------+ +-----------+
+ | | | |
+ homedir mirror afs.org redhat.com
+ | | |
+ +------------+ +---------------+ +----------+
+ | | | | | |
+ 00001 00002 00007 00125 vol00001 vol00002
+ | | | | |
+ +---+---+ +-----+ +---+ +------+------+ +-----+----+
+ | | | | | | | | | | | | |
+PG0 PG1 PG2 PG0 XATTR PG0 PG1 DIRENT DIRENT DIRENT R/W R/O Bak
+ | |
+ PG0 +-------+
+ | |
+ 00001 00003
+ |
+ +---+---+
+ | | |
+ PG0 PG1 PG2
+
+In the example above, you can see two netfs's being backed: NFS and AFS. These
+have different index hierarchies:
+
+ (*) The NFS primary index contains per-server indices. Each server index is
+ indexed by NFS file handles to get data file objects. Each data file
+ objects can have an array of pages, but may also have further child
+ objects, such as extended attributes and directory entries. Extended
+ attribute objects themselves have page-array contents.
+
+ (*) The AFS primary index contains per-cell indices. Each cell index contains
+ per-logical-volume indices. Each of volume index contains up to three
+ indices for the read-write, read-only and backup mirrors of those volumes.
+ Each of these contains vnode data file objects, each of which contains an
+ array of pages.
+
+The very top index is the FS-Cache master index in which individual netfs's
+have entries.
+
+Any index object may reside in more than one cache, provided it only has index
+children. Any index with non-index object children will be assumed to only
+reside in one cache.
+
+
+The netfs API to FS-Cache can be found in:
+
+ Documentation/filesystems/caching/netfs-api.txt
+
+The cache backend API to FS-Cache can be found in:
+
+ Documentation/filesystems/caching/backend-api.txt
+
+A description of the internal representations and object state machine can be
+found in:
+
+ Documentation/filesystems/caching/object.txt
+
+
+=======================
+STATISTICAL INFORMATION
+=======================
+
+If FS-Cache is compiled with the following options enabled:
+
+ CONFIG_FSCACHE_STATS=y
+ CONFIG_FSCACHE_HISTOGRAM=y
+
+then it will gather certain statistics and display them through a number of
+proc files.
+
+ (*) /proc/fs/fscache/stats
+
+ This shows counts of a number of events that can happen in FS-Cache:
+
+ CLASS EVENT MEANING
+ ======= ======= =======================================================
+ Cookies idx=N Number of index cookies allocated
+ dat=N Number of data storage cookies allocated
+ spc=N Number of special cookies allocated
+ Objects alc=N Number of objects allocated
+ nal=N Number of object allocation failures
+ avl=N Number of objects that reached the available state
+ ded=N Number of objects that reached the dead state
+ ChkAux non=N Number of objects that didn't have a coherency check
+ ok=N Number of objects that passed a coherency check
+ upd=N Number of objects that needed a coherency data update
+ obs=N Number of objects that were declared obsolete
+ Pages mrk=N Number of pages marked as being cached
+ unc=N Number of uncache page requests seen
+ Acquire n=N Number of acquire cookie requests seen
+ nul=N Number of acq reqs given a NULL parent
+ noc=N Number of acq reqs rejected due to no cache available
+ ok=N Number of acq reqs succeeded
+ nbf=N Number of acq reqs rejected due to error
+ oom=N Number of acq reqs failed on ENOMEM
+ Lookups n=N Number of lookup calls made on cache backends
+ neg=N Number of negative lookups made
+ pos=N Number of positive lookups made
+ crt=N Number of objects created by lookup
+ Updates n=N Number of update cookie requests seen
+ nul=N Number of upd reqs given a NULL parent
+ run=N Number of upd reqs granted CPU time
+ Relinqs n=N Number of relinquish cookie requests seen
+ nul=N Number of rlq reqs given a NULL parent
+ wcr=N Number of rlq reqs waited on completion of creation
+ AttrChg n=N Number of attribute changed requests seen
+ ok=N Number of attr changed requests queued
+ nbf=N Number of attr changed rejected -ENOBUFS
+ oom=N Number of attr changed failed -ENOMEM
+ run=N Number of attr changed ops given CPU time
+ Allocs n=N Number of allocation requests seen
+ ok=N Number of successful alloc reqs
+ wt=N Number of alloc reqs that waited on lookup completion
+ nbf=N Number of alloc reqs rejected -ENOBUFS
+ ops=N Number of alloc reqs submitted
+ owt=N Number of alloc reqs waited for CPU time
+ Retrvls n=N Number of retrieval (read) requests seen
+ ok=N Number of successful retr reqs
+ wt=N Number of retr reqs that waited on lookup completion
+ nod=N Number of retr reqs returned -ENODATA
+ nbf=N Number of retr reqs rejected -ENOBUFS
+ int=N Number of retr reqs aborted -ERESTARTSYS
+ oom=N Number of retr reqs failed -ENOMEM
+ ops=N Number of retr reqs submitted
+ owt=N Number of retr reqs waited for CPU time
+ Stores n=N Number of storage (write) requests seen
+ ok=N Number of successful store reqs
+ agn=N Number of store reqs on a page already pending storage
+ nbf=N Number of store reqs rejected -ENOBUFS
+ oom=N Number of store reqs failed -ENOMEM
+ ops=N Number of store reqs submitted
+ run=N Number of store reqs granted CPU time
+ Ops pend=N Number of times async ops added to pending queues
+ run=N Number of times async ops given CPU time
+ enq=N Number of times async ops queued for processing
+ dfr=N Number of async ops queued for deferred release
+ rel=N Number of async ops released
+ gc=N Number of deferred-release async ops garbage collected
+
+
+ (*) /proc/fs/fscache/histogram
+
+ cat /proc/fs/fscache/histogram
+ JIFS SECS OBJ INST OP RUNS OBJ RUNS RETRV DLY RETRIEVLS
+ ===== ===== ========= ========= ========= ========= =========
+
+ This shows the breakdown of the number of times each amount of time
+ between 0 jiffies and HZ-1 jiffies a variety of tasks took to run. The
+ columns are as follows:
+
+ COLUMN TIME MEASUREMENT
+ ======= =======================================================
+ OBJ INST Length of time to instantiate an object
+ OP RUNS Length of time a call to process an operation took
+ OBJ RUNS Length of time a call to process an object event took
+ RETRV DLY Time between an requesting a read and lookup completing
+ RETRIEVLS Time between beginning and end of a retrieval
+
+ Each row shows the number of events that took a particular range of times.
+ Each step is 1 jiffy in size. The JIFS column indicates the particular
+ jiffy range covered, and the SECS field the equivalent number of seconds.
+
+
+=========
+DEBUGGING
+=========
+
+If CONFIG_FSCACHE_DEBUG is enabled, the FS-Cache facility can have runtime
+debugging enabled by adjusting the value in:
+
+ /sys/module/fscache/parameters/debug
+
+This is a bitmask of debugging streams to enable:
+
+ BIT VALUE STREAM POINT
+ ======= ======= =============================== =======================
+ 0 1 Cache management Function entry trace
+ 1 2 Function exit trace
+ 2 4 General
+ 3 8 Cookie management Function entry trace
+ 4 16 Function exit trace
+ 5 32 General
+ 6 64 Page handling Function entry trace
+ 7 128 Function exit trace
+ 8 256 General
+ 9 512 Operation management Function entry trace
+ 10 1024 Function exit trace
+ 11 2048 General
+
+The appropriate set of values should be OR'd together and the result written to
+the control file. For example:
+
+ echo $((1|8|64)) >/sys/module/fscache/parameters/debug
+
+will turn on all function entry debugging.
diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt
new file mode 100644
index 00000000000..4db125b3a5c
--- /dev/null
+++ b/Documentation/filesystems/caching/netfs-api.txt
@@ -0,0 +1,778 @@
+ ===============================
+ FS-CACHE NETWORK FILESYSTEM API
+ ===============================
+
+There's an API by which a network filesystem can make use of the FS-Cache
+facilities. This is based around a number of principles:
+
+ (1) Caches can store a number of different object types. There are two main
+ object types: indices and files. The first is a special type used by
+ FS-Cache to make finding objects faster and to make retiring of groups of
+ objects easier.
+
+ (2) Every index, file or other object is represented by a cookie. This cookie
+ may or may not have anything associated with it, but the netfs doesn't
+ need to care.
+
+ (3) Barring the top-level index (one entry per cached netfs), the index
+ hierarchy for each netfs is structured according the whim of the netfs.
+
+This API is declared in <linux/fscache.h>.
+
+This document contains the following sections:
+
+ (1) Network filesystem definition
+ (2) Index definition
+ (3) Object definition
+ (4) Network filesystem (un)registration
+ (5) Cache tag lookup
+ (6) Index registration
+ (7) Data file registration
+ (8) Miscellaneous object registration
+ (9) Setting the data file size
+ (10) Page alloc/read/write
+ (11) Page uncaching
+ (12) Index and data file update
+ (13) Miscellaneous cookie operations
+ (14) Cookie unregistration
+ (15) Index and data file invalidation
+ (16) FS-Cache specific page flags.
+
+
+=============================
+NETWORK FILESYSTEM DEFINITION
+=============================
+
+FS-Cache needs a description of the network filesystem. This is specified
+using a record of the following structure:
+
+ struct fscache_netfs {
+ uint32_t version;
+ const char *name;
+ struct fscache_cookie *primary_index;
+ ...
+ };
+
+This first two fields should be filled in before registration, and the third
+will be filled in by the registration function; any other fields should just be
+ignored and are for internal use only.
+
+The fields are:
+
+ (1) The name of the netfs (used as the key in the toplevel index).
+
+ (2) The version of the netfs (if the name matches but the version doesn't, the
+ entire in-cache hierarchy for this netfs will be scrapped and begun
+ afresh).
+
+ (3) The cookie representing the primary index will be allocated according to
+ another parameter passed into the registration function.
+
+For example, kAFS (linux/fs/afs/) uses the following definitions to describe
+itself:
+
+ struct fscache_netfs afs_cache_netfs = {
+ .version = 0,
+ .name = "afs",
+ };
+
+
+================
+INDEX DEFINITION
+================
+
+Indices are used for two purposes:
+
+ (1) To aid the finding of a file based on a series of keys (such as AFS's
+ "cell", "volume ID", "vnode ID").
+
+ (2) To make it easier to discard a subset of all the files cached based around
+ a particular key - for instance to mirror the removal of an AFS volume.
+
+However, since it's unlikely that any two netfs's are going to want to define
+their index hierarchies in quite the same way, FS-Cache tries to impose as few
+restraints as possible on how an index is structured and where it is placed in
+the tree. The netfs can even mix indices and data files at the same level, but
+it's not recommended.
+
+Each index entry consists of a key of indeterminate length plus some auxilliary
+data, also of indeterminate length.
+
+There are some limits on indices:
+
+ (1) Any index containing non-index objects should be restricted to a single
+ cache. Any such objects created within an index will be created in the
+ first cache only. The cache in which an index is created can be
+ controlled by cache tags (see below).
+
+ (2) The entry data must be atomically journallable, so it is limited to about
+ 400 bytes at present. At least 400 bytes will be available.
+
+ (3) The depth of the index tree should be judged with care as the search
+ function is recursive. Too many layers will run the kernel out of stack.
+
+
+=================
+OBJECT DEFINITION
+=================
+
+To define an object, a structure of the following type should be filled out:
+
+ struct fscache_cookie_def
+ {
+ uint8_t name[16];
+ uint8_t type;
+
+ struct fscache_cache_tag *(*select_cache)(
+ const void *parent_netfs_data,
+ const void *cookie_netfs_data);
+
+ uint16_t (*get_key)(const void *cookie_netfs_data,
+ void *buffer,
+ uint16_t bufmax);
+
+ void (*get_attr)(const void *cookie_netfs_data,
+ uint64_t *size);
+
+ uint16_t (*get_aux)(const void *cookie_netfs_data,
+ void *buffer,
+ uint16_t bufmax);
+
+ enum fscache_checkaux (*check_aux)(void *cookie_netfs_data,
+ const void *data,
+ uint16_t datalen);
+
+ void (*get_context)(void *cookie_netfs_data, void *context);
+
+ void (*put_context)(void *cookie_netfs_data, void *context);
+
+ void (*mark_pages_cached)(void *cookie_netfs_data,
+ struct address_space *mapping,
+ struct pagevec *cached_pvec);
+
+ void (*now_uncached)(void *cookie_netfs_data);
+ };
+
+This has the following fields:
+
+ (1) The type of the object [mandatory].
+
+ This is one of the following values:
+
+ (*) FSCACHE_COOKIE_TYPE_INDEX
+
+ This defines an index, which is a special FS-Cache type.
+
+ (*) FSCACHE_COOKIE_TYPE_DATAFILE
+
+ This defines an ordinary data file.
+
+ (*) Any other value between 2 and 255
+
+ This defines an extraordinary object such as an XATTR.
+
+ (2) The name of the object type (NUL terminated unless all 16 chars are used)
+ [optional].
+
+ (3) A function to select the cache in which to store an index [optional].
+
+ This function is invoked when an index needs to be instantiated in a cache
+ during the instantiation of a non-index object. Only the immediate index
+ parent for the non-index object will be queried. Any indices above that
+ in the hierarchy may be stored in multiple caches. This function does not
+ need to be supplied for any non-index object or any index that will only
+ have index children.
+
+ If this function is not supplied or if it returns NULL then the first
+ cache in the parent's list will be chosed, or failing that, the first
+ cache in the master list.
+
+ (4) A function to retrieve an object's key from the netfs [mandatory].
+
+ This function will be called with the netfs data that was passed to the
+ cookie acquisition function and the maximum length of key data that it may
+ provide. It should write the required key data into the given buffer and
+ return the quantity it wrote.
+
+ (5) A function to retrieve attribute data from the netfs [optional].
+
+ This function will be called with the netfs data that was passed to the
+ cookie acquisition function. It should return the size of the file if
+ this is a data file. The size may be used to govern how much cache must
+ be reserved for this file in the cache.
+
+ If the function is absent, a file size of 0 is assumed.
+
+ (6) A function to retrieve auxilliary data from the netfs [optional].
+
+ This function will be called with the netfs data that was passed to the
+ cookie acquisition function and the maximum length of auxilliary data that
+ it may provide. It should write the auxilliary data into the given buffer
+ and return the quantity it wrote.
+
+ If this function is absent, the auxilliary data length will be set to 0.
+
+ The length of the auxilliary data buffer may be dependent on the key
+ length. A netfs mustn't rely on being able to provide more than 400 bytes
+ for both.
+
+ (7) A function to check the auxilliary data [optional].
+
+ This function will be called to check that a match found in the cache for
+ this object is valid. For instance with AFS it could check the auxilliary
+ data against the data version number returned by the server to determine
+ whether the index entry in a cache is still valid.
+
+ If this function is absent, it will be assumed that matching objects in a
+ cache are always valid.
+
+ If present, the function should return one of the following values:
+
+ (*) FSCACHE_CHECKAUX_OKAY - the entry is okay as is
+ (*) FSCACHE_CHECKAUX_NEEDS_UPDATE - the entry requires update
+ (*) FSCACHE_CHECKAUX_OBSOLETE - the entry should be deleted
+
+ This function can also be used to extract data from the auxilliary data in
+ the cache and copy it into the netfs's structures.
+
+ (8) A pair of functions to manage contexts for the completion callback
+ [optional].
+
+ The cache read/write functions are passed a context which is then passed
+ to the I/O completion callback function. To ensure this context remains
+ valid until after the I/O completion is called, two functions may be
+ provided: one to get an extra reference on the context, and one to drop a
+ reference to it.
+
+ If the context is not used or is a type of object that won't go out of
+ scope, then these functions are not required. These functions are not
+ required for indices as indices may not contain data. These functions may
+ be called in interrupt context and so may not sleep.
+
+ (9) A function to mark a page as retaining cache metadata [optional].
+
+ This is called by the cache to indicate that it is retaining in-memory
+ information for this page and that the netfs should uncache the page when
+ it has finished. This does not indicate whether there's data on the disk
+ or not. Note that several pages at once may be presented for marking.
+
+ The PG_fscache bit is set on the pages before this function would be
+ called, so the function need not be provided if this is sufficient.
+
+ This function is not required for indices as they're not permitted data.
+
+(10) A function to unmark all the pages retaining cache metadata [mandatory].
+
+ This is called by FS-Cache to indicate that a backing store is being
+ unbound from a cookie and that all the marks on the pages should be
+ cleared to prevent confusion. Note that the cache will have torn down all
+ its tracking information so that the pages don't need to be explicitly
+ uncached.
+
+ This function is not required for indices as they're not permitted data.
+
+
+===================================
+NETWORK FILESYSTEM (UN)REGISTRATION
+===================================
+
+The first step is to declare the network filesystem to the cache. This also
+involves specifying the layout of the primary index (for AFS, this would be the
+"cell" level).
+
+The registration function is:
+
+ int fscache_register_netfs(struct fscache_netfs *netfs);
+
+It just takes a pointer to the netfs definition. It returns 0 or an error as
+appropriate.
+
+For kAFS, registration is done as follows:
+
+ ret = fscache_register_netfs(&afs_cache_netfs);
+
+The last step is, of course, unregistration:
+
+ void fscache_unregister_netfs(struct fscache_netfs *netfs);
+
+
+================
+CACHE TAG LOOKUP
+================
+
+FS-Cache permits the use of more than one cache. To permit particular index
+subtrees to be bound to particular caches, the second step is to look up cache
+representation tags. This step is optional; it can be left entirely up to
+FS-Cache as to which cache should be used. The problem with doing that is that
+FS-Cache will always pick the first cache that was registered.
+
+To get the representation for a named tag:
+
+ struct fscache_cache_tag *fscache_lookup_cache_tag(const char *name);
+
+This takes a text string as the name and returns a representation of a tag. It
+will never return an error. It may return a dummy tag, however, if it runs out
+of memory; this will inhibit caching with this tag.
+
+Any representation so obtained must be released by passing it to this function:
+
+ void fscache_release_cache_tag(struct fscache_cache_tag *tag);
+
+The tag will be retrieved by FS-Cache when it calls the object definition
+operation select_cache().
+
+
+==================
+INDEX REGISTRATION
+==================
+
+The third step is to inform FS-Cache about part of an index hierarchy that can
+be used to locate files. This is done by requesting a cookie for each index in
+the path to the file:
+
+ struct fscache_cookie *
+ fscache_acquire_cookie(struct fscache_cookie *parent,
+ const struct fscache_object_def *def,
+ void *netfs_data);
+
+This function creates an index entry in the index represented by parent,
+filling in the index entry by calling the operations pointed to by def.
+
+Note that this function never returns an error - all errors are handled
+internally. It may, however, return NULL to indicate no cookie. It is quite
+acceptable to pass this token back to this function as the parent to another
+acquisition (or even to the relinquish cookie, read page and write page
+functions - see below).
+
+Note also that no indices are actually created in a cache until a non-index
+object needs to be created somewhere down the hierarchy. Furthermore, an index
+may be created in several different caches independently at different times.
+This is all handled transparently, and the netfs doesn't see any of it.
+
+For example, with AFS, a cell would be added to the primary index. This index
+entry would have a dependent inode containing a volume location index for the
+volume mappings within this cell:
+
+ cell->cache =
+ fscache_acquire_cookie(afs_cache_netfs.primary_index,
+ &afs_cell_cache_index_def,
+ cell);
+
+Then when a volume location was accessed, it would be entered into the cell's
+index and an inode would be allocated that acts as a volume type and hash chain
+combination:
+
+ vlocation->cache =
+ fscache_acquire_cookie(cell->cache,
+ &afs_vlocation_cache_index_def,
+ vlocation);
+
+And then a particular flavour of volume (R/O for example) could be added to
+that index, creating another index for vnodes (AFS inode equivalents):
+
+ volume->cache =
+ fscache_acquire_cookie(vlocation->cache,
+ &afs_volume_cache_index_def,
+ volume);
+
+
+======================
+DATA FILE REGISTRATION
+======================
+
+The fourth step is to request a data file be created in the cache. This is
+identical to index cookie acquisition. The only difference is that the type in
+the object definition should be something other than index type.
+
+ vnode->cache =
+ fscache_acquire_cookie(volume->cache,
+ &afs_vnode_cache_object_def,
+ vnode);
+
+
+=================================
+MISCELLANEOUS OBJECT REGISTRATION
+=================================
+
+An optional step is to request an object of miscellaneous type be created in
+the cache. This is almost identical to index cookie acquisition. The only
+difference is that the type in the object definition should be something other
+than index type. Whilst the parent object could be an index, it's more likely
+it would be some other type of object such as a data file.
+
+ xattr->cache =
+ fscache_acquire_cookie(vnode->cache,
+ &afs_xattr_cache_object_def,
+ xattr);
+
+Miscellaneous objects might be used to store extended attributes or directory
+entries for example.
+
+
+==========================
+SETTING THE DATA FILE SIZE
+==========================
+
+The fifth step is to set the physical attributes of the file, such as its size.
+This doesn't automatically reserve any space in the cache, but permits the
+cache to adjust its metadata for data tracking appropriately:
+
+ int fscache_attr_changed(struct fscache_cookie *cookie);
+
+The cache will return -ENOBUFS if there is no backing cache or if there is no
+space to allocate any extra metadata required in the cache. The attributes
+will be accessed with the get_attr() cookie definition operation.
+
+Note that attempts to read or write data pages in the cache over this size may
+be rebuffed with -ENOBUFS.
+
+This operation schedules an attribute adjustment to happen asynchronously at
+some point in the future, and as such, it may happen after the function returns
+to the caller. The attribute adjustment excludes read and write operations.
+
+
+=====================
+PAGE READ/ALLOC/WRITE
+=====================
+
+And the sixth step is to store and retrieve pages in the cache. There are
+three functions that are used to do this.
+
+Note:
+
+ (1) A page should not be re-read or re-allocated without uncaching it first.
+
+ (2) A read or allocated page must be uncached when the netfs page is released
+ from the pagecache.
+
+ (3) A page should only be written to the cache if previous read or allocated.
+
+This permits the cache to maintain its page tracking in proper order.
+
+
+PAGE READ
+---------
+
+Firstly, the netfs should ask FS-Cache to examine the caches and read the
+contents cached for a particular page of a particular file if present, or else
+allocate space to store the contents if not:
+
+ typedef
+ void (*fscache_rw_complete_t)(struct page *page,
+ void *context,
+ int error);
+
+ int fscache_read_or_alloc_page(struct fscache_cookie *cookie,
+ struct page *page,
+ fscache_rw_complete_t end_io_func,
+ void *context,
+ gfp_t gfp);
+
+The cookie argument must specify a cookie for an object that isn't an index,
+the page specified will have the data loaded into it (and is also used to
+specify the page number), and the gfp argument is used to control how any
+memory allocations made are satisfied.
+
+If the cookie indicates the inode is not cached:
+
+ (1) The function will return -ENOBUFS.
+
+Else if there's a copy of the page resident in the cache:
+
+ (1) The mark_pages_cached() cookie operation will be called on that page.
+
+ (2) The function will submit a request to read the data from the cache's
+ backing device directly into the page specified.
+
+ (3) The function will return 0.
+
+ (4) When the read is complete, end_io_func() will be invoked with:
+
+ (*) The netfs data supplied when the cookie was created.
+
+ (*) The page descriptor.
+
+ (*) The context argument passed to the above function. This will be
+ maintained with the get_context/put_context functions mentioned above.
+
+ (*) An argument that's 0 on success or negative for an error code.
+
+ If an error occurs, it should be assumed that the page contains no usable
+ data.
+
+ end_io_func() will be called in process context if the read is results in
+ an error, but it might be called in interrupt context if the read is
+ successful.
+
+Otherwise, if there's not a copy available in cache, but the cache may be able
+to store the page:
+
+ (1) The mark_pages_cached() cookie operation will be called on that page.
+
+ (2) A block may be reserved in the cache and attached to the object at the
+ appropriate place.
+
+ (3) The function will return -ENODATA.
+
+This function may also return -ENOMEM or -EINTR, in which case it won't have
+read any data from the cache.
+
+
+PAGE ALLOCATE
+-------------
+
+Alternatively, if there's not expected to be any data in the cache for a page
+because the file has been extended, a block can simply be allocated instead:
+
+ int fscache_alloc_page(struct fscache_cookie *cookie,
+ struct page *page,
+ gfp_t gfp);
+
+This is similar to the fscache_read_or_alloc_page() function, except that it
+never reads from the cache. It will return 0 if a block has been allocated,
+rather than -ENODATA as the other would. One or the other must be performed
+before writing to the cache.
+
+The mark_pages_cached() cookie operation will be called on the page if
+successful.
+
+
+PAGE WRITE
+----------
+
+Secondly, if the netfs changes the contents of the page (either due to an
+initial download or if a user performs a write), then the page should be
+written back to the cache:
+
+ int fscache_write_page(struct fscache_cookie *cookie,
+ struct page *page,
+ gfp_t gfp);
+
+The cookie argument must specify a data file cookie, the page specified should
+contain the data to be written (and is also used to specify the page number),
+and the gfp argument is used to control how any memory allocations made are
+satisfied.
+
+The page must have first been read or allocated successfully and must not have
+been uncached before writing is performed.
+
+If the cookie indicates the inode is not cached then:
+
+ (1) The function will return -ENOBUFS.
+
+Else if space can be allocated in the cache to hold this page:
+
+ (1) PG_fscache_write will be set on the page.
+
+ (2) The function will submit a request to write the data to cache's backing
+ device directly from the page specified.
+
+ (3) The function will return 0.
+
+ (4) When the write is complete PG_fscache_write is cleared on the page and
+ anyone waiting for that bit will be woken up.
+
+Else if there's no space available in the cache, -ENOBUFS will be returned. It
+is also possible for the PG_fscache_write bit to be cleared when no write took
+place if unforeseen circumstances arose (such as a disk error).
+
+Writing takes place asynchronously.
+
+
+MULTIPLE PAGE READ
+------------------
+
+A facility is provided to read several pages at once, as requested by the
+readpages() address space operation:
+
+ int fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
+ struct address_space *mapping,
+ struct list_head *pages,
+ int *nr_pages,
+ fscache_rw_complete_t end_io_func,
+ void *context,
+ gfp_t gfp);
+
+This works in a similar way to fscache_read_or_alloc_page(), except:
+
+ (1) Any page it can retrieve data for is removed from pages and nr_pages and
+ dispatched for reading to the disk. Reads of adjacent pages on disk may
+ be merged for greater efficiency.
+
+ (2) The mark_pages_cached() cookie operation will be called on several pages
+ at once if they're being read or allocated.
+
+ (3) If there was an general error, then that error will be returned.
+
+ Else if some pages couldn't be allocated or read, then -ENOBUFS will be
+ returned.
+
+ Else if some pages couldn't be read but were allocated, then -ENODATA will
+ be returned.
+
+ Otherwise, if all pages had reads dispatched, then 0 will be returned, the
+ list will be empty and *nr_pages will be 0.
+
+ (4) end_io_func will be called once for each page being read as the reads
+ complete. It will be called in process context if error != 0, but it may
+ be called in interrupt context if there is no error.
+
+Note that a return of -ENODATA, -ENOBUFS or any other error does not preclude
+some of the pages being read and some being allocated. Those pages will have
+been marked appropriately and will need uncaching.
+
+
+==============
+PAGE UNCACHING
+==============
+
+To uncache a page, this function should be called:
+
+ void fscache_uncache_page(struct fscache_cookie *cookie,
+ struct page *page);
+
+This function permits the cache to release any in-memory representation it
+might be holding for this netfs page. This function must be called once for
+each page on which the read or write page functions above have been called to
+make sure the cache's in-memory tracking information gets torn down.
+
+Note that pages can't be explicitly deleted from the a data file. The whole
+data file must be retired (see the relinquish cookie function below).
+
+Furthermore, note that this does not cancel the asynchronous read or write
+operation started by the read/alloc and write functions, so the page
+invalidation and release functions must use:
+
+ bool fscache_check_page_write(struct fscache_cookie *cookie,
+ struct page *page);
+
+to see if a page is being written to the cache, and:
+
+ void fscache_wait_on_page_write(struct fscache_cookie *cookie,
+ struct page *page);
+
+to wait for it to finish if it is.
+
+
+==========================
+INDEX AND DATA FILE UPDATE
+==========================
+
+To request an update of the index data for an index or other object, the
+following function should be called:
+
+ void fscache_update_cookie(struct fscache_cookie *cookie);
+
+This function will refer back to the netfs_data pointer stored in the cookie by
+the acquisition function to obtain the data to write into each revised index
+entry. The update method in the parent index definition will be called to
+transfer the data.
+
+Note that partial updates may happen automatically at other times, such as when
+data blocks are added to a data file object.
+
+
+===============================
+MISCELLANEOUS COOKIE OPERATIONS
+===============================
+
+There are a number of operations that can be used to control cookies:
+
+ (*) Cookie pinning:
+
+ int fscache_pin_cookie(struct fscache_cookie *cookie);
+ void fscache_unpin_cookie(struct fscache_cookie *cookie);
+
+ These operations permit data cookies to be pinned into the cache and to
+ have the pinning removed. They are not permitted on index cookies.
+
+ The pinning function will return 0 if successful, -ENOBUFS in the cookie
+ isn't backed by a cache, -EOPNOTSUPP if the cache doesn't support pinning,
+ -ENOSPC if there isn't enough space to honour the operation, -ENOMEM or
+ -EIO if there's any other problem.
+
+ (*) Data space reservation:
+
+ int fscache_reserve_space(struct fscache_cookie *cookie, loff_t size);
+
+ This permits a netfs to request cache space be reserved to store up to the
+ given amount of a file. It is permitted to ask for more than the current
+ size of the file to allow for future file expansion.
+
+ If size is given as zero then the reservation will be cancelled.
+
+ The function will return 0 if successful, -ENOBUFS in the cookie isn't
+ backed by a cache, -EOPNOTSUPP if the cache doesn't support reservations,
+ -ENOSPC if there isn't enough space to honour the operation, -ENOMEM or
+ -EIO if there's any other problem.
+
+ Note that this doesn't pin an object in a cache; it can still be culled to
+ make space if it's not in use.
+
+
+=====================
+COOKIE UNREGISTRATION
+=====================
+
+To get rid of a cookie, this function should be called.
+
+ void fscache_relinquish_cookie(struct fscache_cookie *cookie,
+ int retire);
+
+If retire is non-zero, then the object will be marked for recycling, and all
+copies of it will be removed from all active caches in which it is present.
+Not only that but all child objects will also be retired.
+
+If retire is zero, then the object may be available again when next the
+acquisition function is called. Retirement here will overrule the pinning on a
+cookie.
+
+One very important note - relinquish must NOT be called for a cookie unless all
+the cookies for "child" indices, objects and pages have been relinquished
+first.
+
+
+================================
+INDEX AND DATA FILE INVALIDATION
+================================
+
+There is no direct way to invalidate an index subtree or a data file. To do
+this, the caller should relinquish and retire the cookie they have, and then
+acquire a new one.
+
+
+===========================
+FS-CACHE SPECIFIC PAGE FLAG
+===========================
+
+FS-Cache makes use of a page flag, PG_private_2, for its own purpose. This is
+given the alternative name PG_fscache.
+
+PG_fscache is used to indicate that the page is known by the cache, and that
+the cache must be informed if the page is going to go away. It's an indication
+to the netfs that the cache has an interest in this page, where an interest may
+be a pointer to it, resources allocated or reserved for it, or I/O in progress
+upon it.
+
+The netfs can use this information in methods such as releasepage() to
+determine whether it needs to uncache a page or update it.
+
+Furthermore, if this bit is set, releasepage() and invalidatepage() operations
+will be called on a page to get rid of it, even if PG_private is not set. This
+allows caching to attempted on a page before read_cache_pages() to be called
+after fscache_read_or_alloc_pages() as the former will try and release pages it
+was given under certain circumstances.
+
+This bit does not overlap with such as PG_private. This means that FS-Cache
+can be used with a filesystem that uses the block buffering code.
+
+There are a number of operations defined on this flag:
+
+ int PageFsCache(struct page *page);
+ void SetPageFsCache(struct page *page)
+ void ClearPageFsCache(struct page *page)
+ int TestSetPageFsCache(struct page *page)
+ int TestClearPageFsCache(struct page *page)
+
+These functions are bit test, bit set, bit clear, bit test and set and bit
+test and clear operations on PG_fscache.
diff --git a/Documentation/filesystems/caching/object.txt b/Documentation/filesystems/caching/object.txt
new file mode 100644
index 00000000000..e8b0a35d8fe
--- /dev/null
+++ b/Documentation/filesystems/caching/object.txt
@@ -0,0 +1,313 @@
+ ====================================================
+ IN-KERNEL CACHE OBJECT REPRESENTATION AND MANAGEMENT
+ ====================================================
+
+By: David Howells <dhowells@redhat.com>
+
+Contents:
+
+ (*) Representation
+
+ (*) Object management state machine.
+
+ - Provision of cpu time.
+ - Locking simplification.
+
+ (*) The set of states.
+
+ (*) The set of events.
+
+
+==============
+REPRESENTATION
+==============
+
+FS-Cache maintains an in-kernel representation of each object that a netfs is
+currently interested in. Such objects are represented by the fscache_cookie
+struct and are referred to as cookies.
+
+FS-Cache also maintains a separate in-kernel representation of the objects that
+a cache backend is currently actively caching. Such objects are represented by
+the fscache_object struct. The cache backends allocate these upon request, and
+are expected to embed them in their own representations. These are referred to
+as objects.
+
+There is a 1:N relationship between cookies and objects. A cookie may be
+represented by multiple objects - an index may exist in more than one cache -
+or even by no objects (it may not be cached).
+
+Furthermore, both cookies and objects are hierarchical. The two hierarchies
+correspond, but the cookies tree is a superset of the union of the object trees
+of multiple caches:
+
+ NETFS INDEX TREE : CACHE 1 : CACHE 2
+ : :
+ : +-----------+ :
+ +----------->| IObject | :
+ +-----------+ | : +-----------+ :
+ | ICookie |-------+ : | :
+ +-----------+ | : | : +-----------+
+ | +------------------------------>| IObject |
+ | : | : +-----------+
+ | : V : |
+ | : +-----------+ : |
+ V +----------->| IObject | : |
+ +-----------+ | : +-----------+ : |
+ | ICookie |-------+ : | : V
+ +-----------+ | : | : +-----------+
+ | +------------------------------>| IObject |
+ +-----+-----+ : | : +-----------+
+ | | : | : |
+ V | : V : |
+ +-----------+ | : +-----------+ : |
+ | ICookie |------------------------->| IObject | : |
+ +-----------+ | : +-----------+ : |
+ | V : | : V
+ | +-----------+ : | : +-----------+
+ | | ICookie |-------------------------------->| IObject |
+ | +-----------+ : | : +-----------+
+ V | : V : |
+ +-----------+ | : +-----------+ : |
+ | DCookie |------------------------->| DObject | : |
+ +-----------+ | : +-----------+ : |
+ | : : |
+ +-------+-------+ : : |
+ | | : : |
+ V V : : V
+ +-----------+ +-----------+ : : +-----------+
+ | DCookie | | DCookie |------------------------>| DObject |
+ +-----------+ +-----------+ : : +-----------+
+ : :
+
+In the above illustration, ICookie and IObject represent indices and DCookie
+and DObject represent data storage objects. Indices may have representation in
+multiple caches, but currently, non-index objects may not. Objects of any type
+may also be entirely unrepresented.
+
+As far as the netfs API goes, the netfs is only actually permitted to see
+pointers to the cookies. The cookies themselves and any objects attached to
+those cookies are hidden from it.
+
+
+===============================
+OBJECT MANAGEMENT STATE MACHINE
+===============================
+
+Within FS-Cache, each active object is managed by its own individual state
+machine. The state for an object is kept in the fscache_object struct, in
+object->state. A cookie may point to a set of objects that are in different
+states.
+
+Each state has an action associated with it that is invoked when the machine
+wakes up in that state. There are four logical sets of states:
+
+ (1) Preparation: states that wait for the parent objects to become ready. The
+ representations are hierarchical, and it is expected that an object must
+ be created or accessed with respect to its parent object.
+
+ (2) Initialisation: states that perform lookups in the cache and validate
+ what's found and that create on disk any missing metadata.
+
+ (3) Normal running: states that allow netfs operations on objects to proceed
+ and that update the state of objects.
+
+ (4) Termination: states that detach objects from their netfs cookies, that
+ delete objects from disk, that handle disk and system errors and that free
+ up in-memory resources.
+
+
+In most cases, transitioning between states is in response to signalled events.
+When a state has finished processing, it will usually set the mask of events in
+which it is interested (object->event_mask) and relinquish the worker thread.
+Then when an event is raised (by calling fscache_raise_event()), if the event
+is not masked, the object will be queued for processing (by calling
+fscache_enqueue_object()).
+
+
+PROVISION OF CPU TIME
+---------------------
+
+The work to be done by the various states is given CPU time by the threads of
+the slow work facility (see Documentation/slow-work.txt). This is used in
+preference to the workqueue facility because:
+
+ (1) Threads may be completely occupied for very long periods of time by a
+ particular work item. These state actions may be doing sequences of
+ synchronous, journalled disk accesses (lookup, mkdir, create, setxattr,
+ getxattr, truncate, unlink, rmdir, rename).
+
+ (2) Threads may do little actual work, but may rather spend a lot of time
+ sleeping on I/O. This means that single-threaded and 1-per-CPU-threaded
+ workqueues don't necessarily have the right numbers of threads.
+
+
+LOCKING SIMPLIFICATION
+----------------------
+
+Because only one worker thread may be operating on any particular object's
+state machine at once, this simplifies the locking, particularly with respect
+to disconnecting the netfs's representation of a cache object (fscache_cookie)
+from the cache backend's representation (fscache_object) - which may be
+requested from either end.
+
+
+=================
+THE SET OF STATES
+=================
+
+The object state machine has a set of states that it can be in. There are
+preparation states in which the object sets itself up and waits for its parent
+object to transit to a state that allows access to its children:
+
+ (1) State FSCACHE_OBJECT_INIT.
+
+ Initialise the object and wait for the parent object to become active. In
+ the cache, it is expected that it will not be possible to look an object
+ up from the parent object, until that parent object itself has been looked
+ up.
+
+There are initialisation states in which the object sets itself up and accesses
+disk for the object metadata:
+
+ (2) State FSCACHE_OBJECT_LOOKING_UP.
+
+ Look up the object on disk, using the parent as a starting point.
+ FS-Cache expects the cache backend to probe the cache to see whether this
+ object is represented there, and if it is, to see if it's valid (coherency
+ management).
+
+ The cache should call fscache_object_lookup_negative() to indicate lookup
+ failure for whatever reason, and should call fscache_obtained_object() to
+ indicate success.
+
+ At the completion of lookup, FS-Cache will let the netfs go ahead with
+ read operations, no matter whether the file is yet cached. If not yet
+ cached, read operations will be immediately rejected with ENODATA until
+ the first known page is uncached - as to that point there can be no data
+ to be read out of the cache for that file that isn't currently also held
+ in the pagecache.
+
+ (3) State FSCACHE_OBJECT_CREATING.
+
+ Create an object on disk, using the parent as a starting point. This
+ happens if the lookup failed to find the object, or if the object's
+ coherency data indicated what's on disk is out of date. In this state,
+ FS-Cache expects the cache to create
+
+ The cache should call fscache_obtained_object() if creation completes
+ successfully, fscache_object_lookup_negative() otherwise.
+
+ At the completion of creation, FS-Cache will start processing write
+ operations the netfs has queued for an object. If creation failed, the
+ write ops will be transparently discarded, and nothing recorded in the
+ cache.
+
+There are some normal running states in which the object spends its time
+servicing netfs requests:
+
+ (4) State FSCACHE_OBJECT_AVAILABLE.
+
+ A transient state in which pending operations are started, child objects
+ are permitted to advance from FSCACHE_OBJECT_INIT state, and temporary
+ lookup data is freed.
+
+ (5) State FSCACHE_OBJECT_ACTIVE.
+
+ The normal running state. In this state, requests the netfs makes will be
+ passed on to the cache.
+
+ (6) State FSCACHE_OBJECT_UPDATING.
+
+ The state machine comes here to update the object in the cache from the
+ netfs's records. This involves updating the auxiliary data that is used
+ to maintain coherency.
+
+And there are terminal states in which an object cleans itself up, deallocates
+memory and potentially deletes stuff from disk:
+
+ (7) State FSCACHE_OBJECT_LC_DYING.
+
+ The object comes here if it is dying because of a lookup or creation
+ error. This would be due to a disk error or system error of some sort.
+ Temporary data is cleaned up, and the parent is released.
+
+ (8) State FSCACHE_OBJECT_DYING.
+
+ The object comes here if it is dying due to an error, because its parent
+ cookie has been relinquished by the netfs or because the cache is being
+ withdrawn.
+
+ Any child objects waiting on this one are given CPU time so that they too
+ can destroy themselves. This object waits for all its children to go away
+ before advancing to the next state.
+
+ (9) State FSCACHE_OBJECT_ABORT_INIT.
+
+ The object comes to this state if it was waiting on its parent in
+ FSCACHE_OBJECT_INIT, but its parent died. The object will destroy itself
+ so that the parent may proceed from the FSCACHE_OBJECT_DYING state.
+
+(10) State FSCACHE_OBJECT_RELEASING.
+(11) State FSCACHE_OBJECT_RECYCLING.
+
+ The object comes to one of these two states when dying once it is rid of
+ all its children, if it is dying because the netfs relinquished its
+ cookie. In the first state, the cached data is expected to persist, and
+ in the second it will be deleted.
+
+(12) State FSCACHE_OBJECT_WITHDRAWING.
+
+ The object transits to this state if the cache decides it wants to
+ withdraw the object from service, perhaps to make space, but also due to
+ error or just because the whole cache is being withdrawn.
+
+(13) State FSCACHE_OBJECT_DEAD.
+
+ The object transits to this state when the in-memory object record is
+ ready to be deleted. The object processor shouldn't ever see an object in
+ this state.
+
+
+THE SET OF EVENTS
+-----------------
+
+There are a number of events that can be raised to an object state machine:
+
+ (*) FSCACHE_OBJECT_EV_UPDATE
+
+ The netfs requested that an object be updated. The state machine will ask
+ the cache backend to update the object, and the cache backend will ask the
+ netfs for details of the change through its cookie definition ops.
+
+ (*) FSCACHE_OBJECT_EV_CLEARED
+
+ This is signalled in two circumstances:
+
+ (a) when an object's last child object is dropped and
+
+ (b) when the last operation outstanding on an object is completed.
+
+ This is used to proceed from the dying state.
+
+ (*) FSCACHE_OBJECT_EV_ERROR
+
+ This is signalled when an I/O error occurs during the processing of some
+ object.
+
+ (*) FSCACHE_OBJECT_EV_RELEASE
+ (*) FSCACHE_OBJECT_EV_RETIRE
+
+ These are signalled when the netfs relinquishes a cookie it was using.
+ The event selected depends on whether the netfs asks for the backing
+ object to be retired (deleted) or retained.
+
+ (*) FSCACHE_OBJECT_EV_WITHDRAW
+
+ This is signalled when the cache backend wants to withdraw an object.
+ This means that the object will have to be detached from the netfs's
+ cookie.
+
+Because the withdrawing releasing/retiring events are all handled by the object
+state machine, it doesn't matter if there's a collision with both ends trying
+to sever the connection at the same time. The state machine can just pick
+which one it wants to honour, and that effects the other.
diff --git a/Documentation/filesystems/caching/operations.txt b/Documentation/filesystems/caching/operations.txt
new file mode 100644
index 00000000000..b6b070c57cb
--- /dev/null
+++ b/Documentation/filesystems/caching/operations.txt
@@ -0,0 +1,213 @@
+ ================================
+ ASYNCHRONOUS OPERATIONS HANDLING
+ ================================
+
+By: David Howells <dhowells@redhat.com>
+
+Contents:
+
+ (*) Overview.
+
+ (*) Operation record initialisation.
+
+ (*) Parameters.
+
+ (*) Procedure.
+
+ (*) Asynchronous callback.
+
+
+========
+OVERVIEW
+========
+
+FS-Cache has an asynchronous operations handling facility that it uses for its
+data storage and retrieval routines. Its operations are represented by
+fscache_operation structs, though these are usually embedded into some other
+structure.
+
+This facility is available to and expected to be be used by the cache backends,
+and FS-Cache will create operations and pass them off to the appropriate cache
+backend for completion.
+
+To make use of this facility, <linux/fscache-cache.h> should be #included.
+
+
+===============================
+OPERATION RECORD INITIALISATION
+===============================
+
+An operation is recorded in an fscache_operation struct:
+
+ struct fscache_operation {
+ union {
+ struct work_struct fast_work;
+ struct slow_work slow_work;
+ };
+ unsigned long flags;
+ fscache_operation_processor_t processor;
+ ...
+ };
+
+Someone wanting to issue an operation should allocate something with this
+struct embedded in it. They should initialise it by calling:
+
+ void fscache_operation_init(struct fscache_operation *op,
+ fscache_operation_release_t release);
+
+with the operation to be initialised and the release function to use.
+
+The op->flags parameter should be set to indicate the CPU time provision and
+the exclusivity (see the Parameters section).
+
+The op->fast_work, op->slow_work and op->processor flags should be set as
+appropriate for the CPU time provision (see the Parameters section).
+
+FSCACHE_OP_WAITING may be set in op->flags prior to each submission of the
+operation and waited for afterwards.
+
+
+==========
+PARAMETERS
+==========
+
+There are a number of parameters that can be set in the operation record's flag
+parameter. There are three options for the provision of CPU time in these
+operations:
+
+ (1) The operation may be done synchronously (FSCACHE_OP_MYTHREAD). A thread
+ may decide it wants to handle an operation itself without deferring it to
+ another thread.
+
+ This is, for example, used in read operations for calling readpages() on
+ the backing filesystem in CacheFiles. Although readpages() does an
+ asynchronous data fetch, the determination of whether pages exist is done
+ synchronously - and the netfs does not proceed until this has been
+ determined.
+
+ If this option is to be used, FSCACHE_OP_WAITING must be set in op->flags
+ before submitting the operation, and the operating thread must wait for it
+ to be cleared before proceeding:
+
+ wait_on_bit(&op->flags, FSCACHE_OP_WAITING,
+ fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+
+
+ (2) The operation may be fast asynchronous (FSCACHE_OP_FAST), in which case it
+ will be given to keventd to process. Such an operation is not permitted
+ to sleep on I/O.
+
+ This is, for example, used by CacheFiles to copy data from a backing fs
+ page to a netfs page after the backing fs has read the page in.
+
+ If this option is used, op->fast_work and op->processor must be
+ initialised before submitting the operation:
+
+ INIT_WORK(&op->fast_work, do_some_work);
+
+
+ (3) The operation may be slow asynchronous (FSCACHE_OP_SLOW), in which case it
+ will be given to the slow work facility to process. Such an operation is
+ permitted to sleep on I/O.
+
+ This is, for example, used by FS-Cache to handle background writes of
+ pages that have just been fetched from a remote server.
+
+ If this option is used, op->slow_work and op->processor must be
+ initialised before submitting the operation:
+
+ fscache_operation_init_slow(op, processor)
+
+
+Furthermore, operations may be one of two types:
+
+ (1) Exclusive (FSCACHE_OP_EXCLUSIVE). Operations of this type may not run in
+ conjunction with any other operation on the object being operated upon.
+
+ An example of this is the attribute change operation, in which the file
+ being written to may need truncation.
+
+ (2) Shareable. Operations of this type may be running simultaneously. It's
+ up to the operation implementation to prevent interference between other
+ operations running at the same time.
+
+
+=========
+PROCEDURE
+=========
+
+Operations are used through the following procedure:
+
+ (1) The submitting thread must allocate the operation and initialise it
+ itself. Normally this would be part of a more specific structure with the
+ generic op embedded within.
+
+ (2) The submitting thread must then submit the operation for processing using
+ one of the following two functions:
+
+ int fscache_submit_op(struct fscache_object *object,
+ struct fscache_operation *op);
+
+ int fscache_submit_exclusive_op(struct fscache_object *object,
+ struct fscache_operation *op);
+
+ The first function should be used to submit non-exclusive ops and the
+ second to submit exclusive ones. The caller must still set the
+ FSCACHE_OP_EXCLUSIVE flag.
+
+ If successful, both functions will assign the operation to the specified
+ object and return 0. -ENOBUFS will be returned if the object specified is
+ permanently unavailable.
+
+ The operation manager will defer operations on an object that is still
+ undergoing lookup or creation. The operation will also be deferred if an
+ operation of conflicting exclusivity is in progress on the object.
+
+ If the operation is asynchronous, the manager will retain a reference to
+ it, so the caller should put their reference to it by passing it to:
+
+ void fscache_put_operation(struct fscache_operation *op);
+
+ (3) If the submitting thread wants to do the work itself, and has marked the
+ operation with FSCACHE_OP_MYTHREAD, then it should monitor
+ FSCACHE_OP_WAITING as described above and check the state of the object if
+ necessary (the object might have died whilst the thread was waiting).
+
+ When it has finished doing its processing, it should call
+ fscache_put_operation() on it.
+
+ (4) The operation holds an effective lock upon the object, preventing other
+ exclusive ops conflicting until it is released. The operation can be
+ enqueued for further immediate asynchronous processing by adjusting the
+ CPU time provisioning option if necessary, eg:
+
+ op->flags &= ~FSCACHE_OP_TYPE;
+ op->flags |= ~FSCACHE_OP_FAST;
+
+ and calling:
+
+ void fscache_enqueue_operation(struct fscache_operation *op)
+
+ This can be used to allow other things to have use of the worker thread
+ pools.
+
+
+=====================
+ASYNCHRONOUS CALLBACK
+=====================
+
+When used in asynchronous mode, the worker thread pool will invoke the
+processor method with a pointer to the operation. This should then get at the
+container struct by using container_of():
+
+ static void fscache_write_op(struct fscache_operation *_op)
+ {
+ struct fscache_storage *op =
+ container_of(_op, struct fscache_storage, op);
+ ...
+ }
+
+The caller holds a reference on the operation, and will invoke
+fscache_put_operation() when the processor function returns. The processor
+function is at liberty to call fscache_enqueue_operation() or to take extra
+references.
diff --git a/Documentation/filesystems/exofs.txt b/Documentation/filesystems/exofs.txt
new file mode 100644
index 00000000000..0ced74c2f73
--- /dev/null
+++ b/Documentation/filesystems/exofs.txt
@@ -0,0 +1,176 @@
+===============================================================================
+WHAT IS EXOFS?
+===============================================================================
+
+exofs is a file system that uses an OSD and exports the API of a normal Linux
+file system. Users access exofs like any other local file system, and exofs
+will in turn issue commands to the local OSD initiator.
+
+OSD is a new T10 command set that views storage devices not as a large/flat
+array of sectors but as a container of objects, each having a length, quota,
+time attributes and more. Each object is addressed by a 64bit ID, and is
+contained in a 64bit ID partition. Each object has associated attributes
+attached to it, which are integral part of the object and provide metadata about
+the object. The standard defines some common obligatory attributes, but user
+attributes can be added as needed.
+
+===============================================================================
+ENVIRONMENT
+===============================================================================
+
+To use this file system, you need to have an object store to run it on. You
+may download a target from:
+http://open-osd.org
+
+See Documentation/scsi/osd.txt for how to setup a working osd environment.
+
+===============================================================================
+USAGE
+===============================================================================
+
+1. Download and compile exofs and open-osd initiator:
+ You need an external Kernel source tree or kernel headers from your
+ distribution. (anything based on 2.6.26 or later).
+
+ a. download open-osd including exofs source using:
+ [parent-directory]$ git clone git://git.open-osd.org/open-osd.git
+
+ b. Build the library module like this:
+ [parent-directory]$ make -C KSRC=$(KER_DIR) open-osd
+
+ This will build both the open-osd initiator as well as the exofs kernel
+ module. Use whatever parameters you compiled your Kernel with and
+ $(KER_DIR) above pointing to the Kernel you compile against. See the file
+ open-osd/top-level-Makefile for an example.
+
+2. Get the OSD initiator and target set up properly, and login to the target.
+ See Documentation/scsi/osd.txt for farther instructions. Also see ./do-osd
+ for example script that does all these steps.
+
+3. Insmod the exofs.ko module:
+ [exofs]$ insmod exofs.ko
+
+4. Make sure the directory where you want to mount exists. If not, create it.
+ (For example, mkdir /mnt/exofs)
+
+5. At first run you will need to invoke the mkfs.exofs application
+
+ As an example, this will create the file system on:
+ /dev/osd0 partition ID 65536
+
+ mkfs.exofs --pid=65536 --format /dev/osd0
+
+ The --format is optional if not specified no OSD_FORMAT will be
+ preformed and a clean file system will be created in the specified pid,
+ in the available space of the target. (Use --format=size_in_meg to limit
+ the total LUN space available)
+
+ If pid already exist it will be deleted and a new one will be created in it's
+ place. Be careful.
+
+ An exofs lives inside a single OSD partition. You can create multiple exofs
+ filesystems on the same device using multiple pids.
+
+ (run mkfs.exofs without any parameters for usage help message)
+
+6. Mount the file system.
+
+ For example, to mount /dev/osd0, partition ID 0x10000 on /mnt/exofs:
+
+ mount -t exofs -o pid=65536 /dev/osd0 /mnt/exofs/
+
+7. For reference (See do-exofs example script):
+ do-exofs start - an example of how to perform the above steps.
+ do-exofs stop - an example of how to unmount the file system.
+ do-exofs format - an example of how to format and mkfs a new exofs.
+
+8. Extra compilation flags (uncomment in fs/exofs/Kbuild):
+ CONFIG_EXOFS_DEBUG - for debug messages and extra checks.
+
+===============================================================================
+exofs mount options
+===============================================================================
+Similar to any mount command:
+ mount -t exofs -o exofs_options /dev/osdX mount_exofs_directory
+
+Where:
+ -t exofs: specifies the exofs file system
+
+ /dev/osdX: X is a decimal number. /dev/osdX was created after a successful
+ login into an OSD target.
+
+ mount_exofs_directory: The directory to mount the file system on
+
+ exofs specific options: Options are separated by commas (,)
+ pid=<integer> - The partition number to mount/create as
+ container of the filesystem.
+ This option is mandatory
+ to=<integer> - Timeout in ticks for a single command
+ default is (60 * HZ) [for debugging only]
+
+===============================================================================
+DESIGN
+===============================================================================
+
+* The file system control block (AKA on-disk superblock) resides in an object
+ with a special ID (defined in common.h).
+ Information included in the file system control block is used to fill the
+ in-memory superblock structure at mount time. This object is created before
+ the file system is used by mkexofs.c It contains information such as:
+ - The file system's magic number
+ - The next inode number to be allocated
+
+* Each file resides in its own object and contains the data (and it will be
+ possible to extend the file over multiple objects, though this has not been
+ implemented yet).
+
+* A directory is treated as a file, and essentially contains a list of <file
+ name, inode #> pairs for files that are found in that directory. The object
+ IDs correspond to the files' inode numbers and will be allocated according to
+ a bitmap (stored in a separate object). Now they are allocated using a
+ counter.
+
+* Each file's control block (AKA on-disk inode) is stored in its object's
+ attributes. This applies to both regular files and other types (directories,
+ device files, symlinks, etc.).
+
+* Credentials are generated per object (inode and superblock) when they is
+ created in memory (read off disk or created). The credential works for all
+ operations and is used as long as the object remains in memory.
+
+* Async OSD operations are used whenever possible, but the target may execute
+ them out of order. The operations that concern us are create, delete,
+ readpage, writepage, update_inode, and truncate. The following pairs of
+ operations should execute in the order written, and we need to prevent them
+ from executing in reverse order:
+ - The following are handled with the OBJ_CREATED and OBJ_2BCREATED
+ flags. OBJ_CREATED is set when we know the object exists on the OSD -
+ in create's callback function, and when we successfully do a read_inode.
+ OBJ_2BCREATED is set in the beginning of the create function, so we
+ know that we should wait.
+ - create/delete: delete should wait until the object is created
+ on the OSD.
+ - create/readpage: readpage should be able to return a page
+ full of zeroes in this case. If there was a write already
+ en-route (i.e. create, writepage, readpage) then the page
+ would be locked, and so it would really be the same as
+ create/writepage.
+ - create/writepage: if writepage is called for a sync write, it
+ should wait until the object is created on the OSD.
+ Otherwise, it should just return.
+ - create/truncate: truncate should wait until the object is
+ created on the OSD.
+ - create/update_inode: update_inode should wait until the
+ object is created on the OSD.
+ - Handled by VFS locks:
+ - readpage/delete: shouldn't happen because of page lock.
+ - writepage/delete: shouldn't happen because of page lock.
+ - readpage/writepage: shouldn't happen because of page lock.
+
+===============================================================================
+LICENSE/COPYRIGHT
+===============================================================================
+The exofs file system is based on ext2 v0.5b (distributed with the Linux kernel
+version 2.6.10). All files include the original copyrights, and the license
+is GPL version 2 (only version 2, as is true for the Linux kernel). The
+Linux kernel can be downloaded from www.kernel.org.
diff --git a/Documentation/filesystems/ext3.txt b/Documentation/filesystems/ext3.txt
index e5f3833a6ef..570f9bd9be2 100644
--- a/Documentation/filesystems/ext3.txt
+++ b/Documentation/filesystems/ext3.txt
@@ -14,6 +14,11 @@ Options
When mounting an ext3 filesystem, the following option are accepted:
(*) == default
+ro Mount filesystem read only. Note that ext3 will replay
+ the journal (and thus write to the partition) even when
+ mounted "read only". Mount options "ro,noload" can be
+ used to prevent writes to the filesystem.
+
journal=update Update the ext3 file system's journal to the current
format.
@@ -27,7 +32,9 @@ journal_dev=devnum When the external journal device's major/minor numbers
identified through its new major/minor numbers encoded
in devnum.
-noload Don't load the journal on mounting.
+noload Don't load the journal on mounting. Note that this forces
+ mount of inconsistent filesystem, which can lead to
+ various problems.
data=journal All data are committed into the journal prior to being
written into the main file system.
@@ -92,9 +99,12 @@ nocheck
debug Extra debugging information is sent to syslog.
-errors=remount-ro(*) Remount the filesystem read-only on an error.
+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.
+ (These mount options override the errors behavior
+ specified in the superblock, which can be
+ configured using tune2fs.)
data_err=ignore(*) Just print an error message if an error occurs
in a file data buffer in ordered mode.
diff --git a/Documentation/filesystems/knfsd-stats.txt b/Documentation/filesystems/knfsd-stats.txt
new file mode 100644
index 00000000000..64ced5149d3
--- /dev/null
+++ b/Documentation/filesystems/knfsd-stats.txt
@@ -0,0 +1,159 @@
+
+Kernel NFS Server Statistics
+============================
+
+This document describes the format and semantics of the statistics
+which the kernel NFS server makes available to userspace. These
+statistics are available in several text form pseudo files, each of
+which is described separately below.
+
+In most cases you don't need to know these formats, as the nfsstat(8)
+program from the nfs-utils distribution provides a helpful command-line
+interface for extracting and printing them.
+
+All the files described here are formatted as a sequence of text lines,
+separated by newline '\n' characters. Lines beginning with a hash
+'#' character are comments intended for humans and should be ignored
+by parsing routines. All other lines contain a sequence of fields
+separated by whitespace.
+
+/proc/fs/nfsd/pool_stats
+------------------------
+
+This file is available in kernels from 2.6.30 onwards, if the
+/proc/fs/nfsd filesystem is mounted (it almost always should be).
+
+The first line is a comment which describes the fields present in
+all the other lines. The other lines present the following data as
+a sequence of unsigned decimal numeric fields. One line is shown
+for each NFS thread pool.
+
+All counters are 64 bits wide and wrap naturally. There is no way
+to zero these counters, instead applications should do their own
+rate conversion.
+
+pool
+ The id number of the NFS thread pool to which this line applies.
+ This number does not change.
+
+ Thread pool ids are a contiguous set of small integers starting
+ at zero. The maximum value depends on the thread pool mode, but
+ currently cannot be larger than the number of CPUs in the system.
+ Note that in the default case there will be a single thread pool
+ which contains all the nfsd threads and all the CPUs in the system,
+ and thus this file will have a single line with a pool id of "0".
+
+packets-arrived
+ Counts how many NFS packets have arrived. More precisely, this
+ is the number of times that the network stack has notified the
+ sunrpc server layer that new data may be available on a transport
+ (e.g. an NFS or UDP socket or an NFS/RDMA endpoint).
+
+ Depending on the NFS workload patterns and various network stack
+ effects (such as Large Receive Offload) which can combine packets
+ on the wire, this may be either more or less than the number
+ of NFS calls received (which statistic is available elsewhere).
+ However this is a more accurate and less workload-dependent measure
+ of how much CPU load is being placed on the sunrpc server layer
+ due to NFS network traffic.
+
+sockets-enqueued
+ Counts how many times an NFS transport is enqueued to wait for
+ an nfsd thread to service it, i.e. no nfsd thread was considered
+ available.
+
+ The circumstance this statistic tracks indicates that there was NFS
+ network-facing work to be done but it couldn't be done immediately,
+ thus introducing a small delay in servicing NFS calls. The ideal
+ rate of change for this counter is zero; significantly non-zero
+ values may indicate a performance limitation.
+
+ This can happen either because there are too few nfsd threads in the
+ thread pool for the NFS workload (the workload is thread-limited),
+ or because the NFS workload needs more CPU time than is available in
+ the thread pool (the workload is CPU-limited). In the former case,
+ configuring more nfsd threads will probably improve the performance
+ of the NFS workload. In the latter case, the sunrpc server layer is
+ already choosing not to wake idle nfsd threads because there are too
+ many nfsd threads which want to run but cannot, so configuring more
+ nfsd threads will make no difference whatsoever. The overloads-avoided
+ statistic (see below) can be used to distinguish these cases.
+
+threads-woken
+ Counts how many times an idle nfsd thread is woken to try to
+ receive some data from an NFS transport.
+
+ This statistic tracks the circumstance where incoming
+ network-facing NFS work is being handled quickly, which is a good
+ thing. The ideal rate of change for this counter will be close
+ to but less than the rate of change of the packets-arrived counter.
+
+overloads-avoided
+ Counts how many times the sunrpc server layer chose not to wake an
+ nfsd thread, despite the presence of idle nfsd threads, because
+ too many nfsd threads had been recently woken but could not get
+ enough CPU time to actually run.
+
+ This statistic counts a circumstance where the sunrpc layer
+ heuristically avoids overloading the CPU scheduler with too many
+ runnable nfsd threads. The ideal rate of change for this counter
+ is zero. Significant non-zero values indicate that the workload
+ is CPU limited. Usually this is associated with heavy CPU usage
+ on all the CPUs in the nfsd thread pool.
+
+ If a sustained large overloads-avoided rate is detected on a pool,
+ the top(1) utility should be used to check for the following
+ pattern of CPU usage on all the CPUs associated with the given
+ nfsd thread pool.
+
+ - %us ~= 0 (as you're *NOT* running applications on your NFS server)
+
+ - %wa ~= 0
+
+ - %id ~= 0
+
+ - %sy + %hi + %si ~= 100
+
+ If this pattern is seen, configuring more nfsd threads will *not*
+ improve the performance of the workload. If this patten is not
+ seen, then something more subtle is wrong.
+
+threads-timedout
+ Counts how many times an nfsd thread triggered an idle timeout,
+ i.e. was not woken to handle any incoming network packets for
+ some time.
+
+ This statistic counts a circumstance where there are more nfsd
+ threads configured than can be used by the NFS workload. This is
+ a clue that the number of nfsd threads can be reduced without
+ affecting performance. Unfortunately, it's only a clue and not
+ a strong indication, for a couple of reasons:
+
+ - Currently the rate at which the counter is incremented is quite
+ slow; the idle timeout is 60 minutes. Unless the NFS workload
+ remains constant for hours at a time, this counter is unlikely
+ to be providing information that is still useful.
+
+ - It is usually a wise policy to provide some slack,
+ i.e. configure a few more nfsds than are currently needed,
+ to allow for future spikes in load.
+
+
+Note that incoming packets on NFS transports will be dealt with in
+one of three ways. An nfsd thread can be woken (threads-woken counts
+this case), or the transport can be enqueued for later attention
+(sockets-enqueued counts this case), or the packet can be temporarily
+deferred because the transport is currently being used by an nfsd
+thread. This last case is not very interesting and is not explicitly
+counted, but can be inferred from the other counters thus:
+
+packets-deferred = packets-arrived - ( sockets-enqueued + threads-woken )
+
+
+More
+----
+Descriptions of the other statistics file should go here.
+
+
+Greg Banks <gnb@sgi.com>
+26 Mar 2009
diff --git a/Documentation/filesystems/nfs41-server.txt b/Documentation/filesystems/nfs41-server.txt
new file mode 100644
index 00000000000..05d81cbcb2e
--- /dev/null
+++ b/Documentation/filesystems/nfs41-server.txt
@@ -0,0 +1,161 @@
+NFSv4.1 Server Implementation
+
+Server support for minorversion 1 can be controlled using the
+/proc/fs/nfsd/versions control file. The string output returned
+by reading this file will contain either "+4.1" or "-4.1"
+correspondingly.
+
+Currently, server support for minorversion 1 is disabled by default.
+It can be enabled at run time by writing the string "+4.1" to
+the /proc/fs/nfsd/versions control file. Note that to write this
+control file, the nfsd service must be taken down. Use your user-mode
+nfs-utils to set this up; see rpc.nfsd(8)
+
+The NFSv4 minorversion 1 (NFSv4.1) implementation in nfsd is based
+on the latest NFSv4.1 Internet Draft:
+http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-29
+
+From the many new features in NFSv4.1 the current implementation
+focuses on the mandatory-to-implement NFSv4.1 Sessions, providing
+"exactly once" semantics and better control and throttling of the
+resources allocated for each client.
+
+Other NFSv4.1 features, Parallel NFS operations in particular,
+are still under development out of tree.
+See http://wiki.linux-nfs.org/wiki/index.php/PNFS_prototype_design
+for more information.
+
+The table below, taken from the NFSv4.1 document, lists
+the operations that are mandatory to implement (REQ), optional
+(OPT), and NFSv4.0 operations that are required not to implement (MNI)
+in minor version 1. The first column indicates the operations that
+are not supported yet by the linux server implementation.
+
+The OPTIONAL features identified and their abbreviations are as follows:
+ pNFS Parallel NFS
+ FDELG File Delegations
+ DDELG Directory Delegations
+
+The following abbreviations indicate the linux server implementation status.
+ I Implemented NFSv4.1 operations.
+ NS Not Supported.
+ NS* unimplemented optional feature.
+ P pNFS features implemented out of tree.
+ PNS pNFS features that are not supported yet (out of tree).
+
+Operations
+
+ +----------------------+------------+--------------+----------------+
+ | Operation | REQ, REC, | Feature | Definition |
+ | | OPT, or | (REQ, REC, | |
+ | | MNI | or OPT) | |
+ +----------------------+------------+--------------+----------------+
+ | ACCESS | REQ | | Section 18.1 |
+NS | BACKCHANNEL_CTL | REQ | | Section 18.33 |
+NS | BIND_CONN_TO_SESSION | REQ | | Section 18.34 |
+ | CLOSE | REQ | | Section 18.2 |
+ | COMMIT | REQ | | Section 18.3 |
+ | CREATE | REQ | | Section 18.4 |
+I | CREATE_SESSION | REQ | | Section 18.36 |
+NS*| DELEGPURGE | OPT | FDELG (REQ) | Section 18.5 |
+ | DELEGRETURN | OPT | FDELG, | Section 18.6 |
+ | | | DDELG, pNFS | |
+ | | | (REQ) | |
+NS | DESTROY_CLIENTID | REQ | | Section 18.50 |
+I | DESTROY_SESSION | REQ | | Section 18.37 |
+I | EXCHANGE_ID | REQ | | Section 18.35 |
+NS | FREE_STATEID | REQ | | Section 18.38 |
+ | GETATTR | REQ | | Section 18.7 |
+P | GETDEVICEINFO | OPT | pNFS (REQ) | Section 18.40 |
+P | GETDEVICELIST | OPT | pNFS (OPT) | Section 18.41 |
+ | GETFH | REQ | | Section 18.8 |
+NS*| GET_DIR_DELEGATION | OPT | DDELG (REQ) | Section 18.39 |
+P | LAYOUTCOMMIT | OPT | pNFS (REQ) | Section 18.42 |
+P | LAYOUTGET | OPT | pNFS (REQ) | Section 18.43 |
+P | LAYOUTRETURN | OPT | pNFS (REQ) | Section 18.44 |
+ | LINK | OPT | | Section 18.9 |
+ | LOCK | REQ | | Section 18.10 |
+ | LOCKT | REQ | | Section 18.11 |
+ | LOCKU | REQ | | Section 18.12 |
+ | LOOKUP | REQ | | Section 18.13 |
+ | LOOKUPP | REQ | | Section 18.14 |
+ | NVERIFY | REQ | | Section 18.15 |
+ | OPEN | REQ | | Section 18.16 |
+NS*| OPENATTR | OPT | | Section 18.17 |
+ | OPEN_CONFIRM | MNI | | N/A |
+ | OPEN_DOWNGRADE | REQ | | Section 18.18 |
+ | PUTFH | REQ | | Section 18.19 |
+ | PUTPUBFH | REQ | | Section 18.20 |
+ | PUTROOTFH | REQ | | Section 18.21 |
+ | READ | REQ | | Section 18.22 |
+ | READDIR | REQ | | Section 18.23 |
+ | READLINK | OPT | | Section 18.24 |
+NS | RECLAIM_COMPLETE | REQ | | Section 18.51 |
+ | RELEASE_LOCKOWNER | MNI | | N/A |
+ | REMOVE | REQ | | Section 18.25 |
+ | RENAME | REQ | | Section 18.26 |
+ | RENEW | MNI | | N/A |
+ | RESTOREFH | REQ | | Section 18.27 |
+ | SAVEFH | REQ | | Section 18.28 |
+ | SECINFO | REQ | | Section 18.29 |
+NS | SECINFO_NO_NAME | REC | pNFS files | Section 18.45, |
+ | | | layout (REQ) | Section 13.12 |
+I | SEQUENCE | REQ | | Section 18.46 |
+ | SETATTR | REQ | | Section 18.30 |
+ | SETCLIENTID | MNI | | N/A |
+ | SETCLIENTID_CONFIRM | MNI | | N/A |
+NS | SET_SSV | REQ | | Section 18.47 |
+NS | TEST_STATEID | REQ | | Section 18.48 |
+ | VERIFY | REQ | | Section 18.31 |
+NS*| WANT_DELEGATION | OPT | FDELG (OPT) | Section 18.49 |
+ | WRITE | REQ | | Section 18.32 |
+
+Callback Operations
+
+ +-------------------------+-----------+-------------+---------------+
+ | Operation | REQ, REC, | Feature | Definition |
+ | | OPT, or | (REQ, REC, | |
+ | | MNI | or OPT) | |
+ +-------------------------+-----------+-------------+---------------+
+ | CB_GETATTR | OPT | FDELG (REQ) | Section 20.1 |
+P | CB_LAYOUTRECALL | OPT | pNFS (REQ) | Section 20.3 |
+NS*| CB_NOTIFY | OPT | DDELG (REQ) | Section 20.4 |
+P | CB_NOTIFY_DEVICEID | OPT | pNFS (OPT) | Section 20.12 |
+NS*| CB_NOTIFY_LOCK | OPT | | Section 20.11 |
+NS*| CB_PUSH_DELEG | OPT | FDELG (OPT) | Section 20.5 |
+ | CB_RECALL | OPT | FDELG, | Section 20.2 |
+ | | | DDELG, pNFS | |
+ | | | (REQ) | |
+NS*| CB_RECALL_ANY | OPT | FDELG, | Section 20.6 |
+ | | | DDELG, pNFS | |
+ | | | (REQ) | |
+NS | CB_RECALL_SLOT | REQ | | Section 20.8 |
+NS*| CB_RECALLABLE_OBJ_AVAIL | OPT | DDELG, pNFS | Section 20.7 |
+ | | | (REQ) | |
+I | CB_SEQUENCE | OPT | FDELG, | Section 20.9 |
+ | | | DDELG, pNFS | |
+ | | | (REQ) | |
+NS*| CB_WANTS_CANCELLED | OPT | FDELG, | Section 20.10 |
+ | | | DDELG, pNFS | |
+ | | | (REQ) | |
+ +-------------------------+-----------+-------------+---------------+
+
+Implementation notes:
+
+EXCHANGE_ID:
+* only SP4_NONE state protection supported
+* implementation ids are ignored
+
+CREATE_SESSION:
+* backchannel attributes are ignored
+* backchannel security parameters are ignored
+
+SEQUENCE:
+* no support for dynamic slot table renegotiation (optional)
+
+nfsv4.1 COMPOUND rules:
+The following cases aren't supported yet:
+* Enforcing of NFS4ERR_NOT_ONLY_OP for: BIND_CONN_TO_SESSION, CREATE_SESSION,
+ DESTROY_CLIENTID, DESTROY_SESSION, EXCHANGE_ID.
+* DESTROY_SESSION MUST be the final operation in the COMPOUND request.
+
diff --git a/Documentation/filesystems/nilfs2.txt b/Documentation/filesystems/nilfs2.txt
new file mode 100644
index 00000000000..55c4300abfc
--- /dev/null
+++ b/Documentation/filesystems/nilfs2.txt
@@ -0,0 +1,200 @@
+NILFS2
+------
+
+NILFS2 is a log-structured file system (LFS) supporting continuous
+snapshotting. In addition to versioning capability of the entire file
+system, users can even restore files mistakenly overwritten or
+destroyed just a few seconds ago. Since NILFS2 can keep consistency
+like conventional LFS, it achieves quick recovery after system
+crashes.
+
+NILFS2 creates a number of checkpoints every few seconds or per
+synchronous write basis (unless there is no change). Users can select
+significant versions among continuously created checkpoints, and can
+change them into snapshots which will be preserved until they are
+changed back to checkpoints.
+
+There is no limit on the number of snapshots until the volume gets
+full. Each snapshot is mountable as a read-only file system
+concurrently with its writable mount, and this feature is convenient
+for online backup.
+
+The userland tools are included in nilfs-utils package, which is
+available from the following download page. At least "mkfs.nilfs2",
+"mount.nilfs2", "umount.nilfs2", and "nilfs_cleanerd" (so called
+cleaner or garbage collector) are required. Details on the tools are
+described in the man pages included in the package.
+
+Project web page: http://www.nilfs.org/en/
+Download page: http://www.nilfs.org/en/download.html
+Git tree web page: http://www.nilfs.org/git/
+NILFS mailing lists: http://www.nilfs.org/mailman/listinfo/users
+
+Caveats
+=======
+
+Features which NILFS2 does not support yet:
+
+ - atime
+ - extended attributes
+ - POSIX ACLs
+ - quotas
+ - writable snapshots
+ - remote backup (CDP)
+ - data integrity
+ - defragmentation
+
+Mount options
+=============
+
+NILFS2 supports the following mount options:
+(*) == default
+
+barrier=on(*) This enables/disables barriers. barrier=off disables
+ it, barrier=on enables it.
+errors=continue(*) Keep going on a filesystem error.
+errors=remount-ro Remount the filesystem read-only on an error.
+errors=panic Panic and halt the machine if an error occurs.
+cp=n Specify the checkpoint-number of the snapshot to be
+ mounted. Checkpoints and snapshots are listed by lscp
+ user command. Only the checkpoints marked as snapshot
+ are mountable with this option. Snapshot is read-only,
+ so a read-only mount option must be specified together.
+order=relaxed(*) Apply relaxed order semantics that allows modified data
+ blocks to be written to disk without making a
+ checkpoint if no metadata update is going. This mode
+ is equivalent to the ordered data mode of the ext3
+ filesystem except for the updates on data blocks still
+ conserve atomicity. This will improve synchronous
+ write performance for overwriting.
+order=strict Apply strict in-order semantics that preserves sequence
+ of all file operations including overwriting of data
+ blocks. That means, it is guaranteed that no
+ overtaking of events occurs in the recovered file
+ system after a crash.
+
+NILFS2 usage
+============
+
+To use nilfs2 as a local file system, simply:
+
+ # mkfs -t nilfs2 /dev/block_device
+ # mount -t nilfs2 /dev/block_device /dir
+
+This will also invoke the cleaner through the mount helper program
+(mount.nilfs2).
+
+Checkpoints and snapshots are managed by the following commands.
+Their manpages are included in the nilfs-utils package above.
+
+ lscp list checkpoints or snapshots.
+ mkcp make a checkpoint or a snapshot.
+ chcp change an existing checkpoint to a snapshot or vice versa.
+ rmcp invalidate specified checkpoint(s).
+
+To mount a snapshot,
+
+ # mount -t nilfs2 -r -o cp=<cno> /dev/block_device /snap_dir
+
+where <cno> is the checkpoint number of the snapshot.
+
+To unmount the NILFS2 mount point or snapshot, simply:
+
+ # umount /dir
+
+Then, the cleaner daemon is automatically shut down by the umount
+helper program (umount.nilfs2).
+
+Disk format
+===========
+
+A nilfs2 volume is equally divided into a number of segments except
+for the super block (SB) and segment #0. A segment is the container
+of logs. Each log is composed of summary information blocks, payload
+blocks, and an optional super root block (SR):
+
+ ______________________________________________________
+ | |SB| | Segment | Segment | Segment | ... | Segment | |
+ |_|__|_|____0____|____1____|____2____|_____|____N____|_|
+ 0 +1K +4K +8M +16M +24M +(8MB x N)
+ . . (Typical offsets for 4KB-block)
+ . .
+ .______________________.
+ | log | log |... | log |
+ |__1__|__2__|____|__m__|
+ . .
+ . .
+ . .
+ .______________________________.
+ | Summary | Payload blocks |SR|
+ |_blocks__|_________________|__|
+
+The payload blocks are organized per file, and each file consists of
+data blocks and B-tree node blocks:
+
+ |<--- File-A --->|<--- File-B --->|
+ _______________________________________________________________
+ | Data blocks | B-tree blocks | Data blocks | B-tree blocks | ...
+ _|_____________|_______________|_____________|_______________|_
+
+
+Since only the modified blocks are written in the log, it may have
+files without data blocks or B-tree node blocks.
+
+The organization of the blocks is recorded in the summary information
+blocks, which contains a header structure (nilfs_segment_summary), per
+file structures (nilfs_finfo), and per block structures (nilfs_binfo):
+
+ _________________________________________________________________________
+ | Summary | finfo | binfo | ... | binfo | finfo | binfo | ... | binfo |...
+ |_blocks__|___A___|_(A,1)_|_____|(A,Na)_|___B___|_(B,1)_|_____|(B,Nb)_|___
+
+
+The logs include regular files, directory files, symbolic link files
+and several meta data files. The mata data files are the files used
+to maintain file system meta data. The current version of NILFS2 uses
+the following meta data files:
+
+ 1) Inode file (ifile) -- Stores on-disk inodes
+ 2) Checkpoint file (cpfile) -- Stores checkpoints
+ 3) Segment usage file (sufile) -- Stores allocation state of segments
+ 4) Data address translation file -- Maps virtual block numbers to usual
+ (DAT) block numbers. This file serves to
+ make on-disk blocks relocatable.
+
+The following figure shows a typical organization of the logs:
+
+ _________________________________________________________________________
+ | Summary | regular file | file | ... | ifile | cpfile | sufile | DAT |SR|
+ |_blocks__|_or_directory_|_______|_____|_______|________|________|_____|__|
+
+
+To stride over segment boundaries, this sequence of files may be split
+into multiple logs. The sequence of logs that should be treated as
+logically one log, is delimited with flags marked in the segment
+summary. The recovery code of nilfs2 looks this boundary information
+to ensure atomicity of updates.
+
+The super root block is inserted for every checkpoints. It includes
+three special inodes, inodes for the DAT, cpfile, and sufile. Inodes
+of regular files, directories, symlinks and other special files, are
+included in the ifile. The inode of ifile itself is included in the
+corresponding checkpoint entry in the cpfile. Thus, the hierarchy
+among NILFS2 files can be depicted as follows:
+
+ Super block (SB)
+ |
+ v
+ Super root block (the latest cno=xx)
+ |-- DAT
+ |-- sufile
+ `-- cpfile
+ |-- ifile (cno=c1)
+ |-- ifile (cno=c2) ---- file (ino=i1)
+ : : |-- file (ino=i2)
+ `-- ifile (cno=xx) |-- file (ino=i3)
+ : :
+ `-- file (ino=yy)
+ ( regular file, directory, or symlink )
+
+For detail on the format of each file, please see include/linux/nilfs2_fs.h.
diff --git a/Documentation/filesystems/pohmelfs/design_notes.txt b/Documentation/filesystems/pohmelfs/design_notes.txt
new file mode 100644
index 00000000000..6d6db60d567
--- /dev/null
+++ b/Documentation/filesystems/pohmelfs/design_notes.txt
@@ -0,0 +1,70 @@
+POHMELFS: Parallel Optimized Host Message Exchange Layered File System.
+
+ Evgeniy Polyakov <zbr@ioremap.net>
+
+Homepage: http://www.ioremap.net/projects/pohmelfs
+
+POHMELFS first began as a network filesystem with coherent local data and
+metadata caches but is now evolving into a parallel distributed filesystem.
+
+Main features of this FS include:
+ * Locally coherent cache for data and metadata with (potentially) byte-range locks.
+ Since all Linux filesystems lock the whole inode during writing, algorithm
+ is very simple and does not use byte-ranges, although they are sent in
+ locking messages.
+ * Completely async processing of all events except creation of hard and symbolic
+ links, and rename events.
+ Object creation and data reading and writing are processed asynchronously.
+ * Flexible object architecture optimized for network processing.
+ Ability to create long paths to objects and remove arbitrarily huge
+ directories with a single network command.
+ (like removing the whole kernel tree via a single network command).
+ * Very high performance.
+ * Fast and scalable multithreaded userspace server. Being in userspace it works
+ with any underlying filesystem and still is much faster than async in-kernel NFS one.
+ * Client is able to switch between different servers (if one goes down, client
+ automatically reconnects to second and so on).
+ * Transactions support. Full failover for all operations.
+ Resending transactions to different servers on timeout or error.
+ * Read request (data read, directory listing, lookup requests) balancing between multiple servers.
+ * Write requests are replicated to multiple servers and completed only when all of them are acked.
+ * Ability to add and/or remove servers from the working set at run-time.
+ * Strong authentification and possible data encryption in network channel.
+ * Extended attributes support.
+
+POHMELFS is based on transactions, which are potentially long-standing objects that live
+in the client's memory. Each transaction contains all the information needed to process a given
+command (or set of commands, which is frequently used during data writing: single transactions
+can contain creation and data writing commands). Transactions are committed by all the servers
+to which they are sent and, in case of failures, are eventually resent or dropped with an error.
+For example, reading will return an error if no servers are available.
+
+POHMELFS uses a asynchronous approach to data processing. Courtesy of transactions, it is
+possible to detach replies from requests and, if the command requires data to be received, the
+caller sleeps waiting for it. Thus, it is possible to issue multiple read commands to different
+servers and async threads will pick up replies in parallel, find appropriate transactions in the
+system and put the data where it belongs (like the page or inode cache).
+
+The main feature of POHMELFS is writeback data and the metadata cache.
+Only a few non-performance critical operations use the write-through cache and
+are synchronous: hard and symbolic link creation, and object rename. Creation,
+removal of objects and data writing are asynchronous and are sent to
+the server during system writeback. Only one writer at a time is allowed for any
+given inode, which is guarded by an appropriate locking protocol.
+Because of this feature, POHMELFS is extremely fast at metadata intensive
+workloads and can fully utilize the bandwidth to the servers when doing bulk
+data transfers.
+
+POHMELFS clients operate with a working set of servers and are capable of balancing read-only
+operations (like lookups or directory listings) between them.
+Administrators can add or remove servers from the set at run-time via special commands (described
+in Documentation/pohmelfs/info.txt file). Writes are replicated to all servers.
+
+POHMELFS is capable of full data channel encryption and/or strong crypto hashing.
+One can select any kernel supported cipher, encryption mode, hash type and operation mode
+(hmac or digest). It is also possible to use both or neither (default). Crypto configuration
+is checked during mount time and, if the server does not support it, appropriate capabilities
+will be disabled or mount will fail (if 'crypto_fail_unsupported' mount option is specified).
+Crypto performance heavily depends on the number of crypto threads, which asynchronously perform
+crypto operations and send the resulting data to server or submit it up the stack. This number
+can be controlled via a mount option.
diff --git a/Documentation/filesystems/pohmelfs/info.txt b/Documentation/filesystems/pohmelfs/info.txt
new file mode 100644
index 00000000000..4e3d5015708
--- /dev/null
+++ b/Documentation/filesystems/pohmelfs/info.txt
@@ -0,0 +1,86 @@
+POHMELFS usage information.
+
+Mount options:
+idx=%u
+ Each mountpoint is associated with a special index via this option.
+ Administrator can add or remove servers from the given index, so all mounts,
+ which were attached to it, are updated.
+ Default it is 0.
+
+trans_scan_timeout=%u
+ This timeout, expressed in milliseconds, specifies time to scan transaction
+ trees looking for stale requests, which have to be resent, or if number of
+ retries exceed specified limit, dropped with error.
+ Default is 5 seconds.
+
+drop_scan_timeout=%u
+ Internal timeout, expressed in milliseconds, which specifies how frequently
+ inodes marked to be dropped are freed. It also specifies how frequently
+ the system checks that servers have to be added or removed from current working set.
+ Default is 1 second.
+
+wait_on_page_timeout=%u
+ Number of milliseconds to wait for reply from remote server for data reading command.
+ If this timeout is exceeded, reading returns an error.
+ Default is 5 seconds.
+
+trans_retries=%u
+ This is the number of times that a transaction will be resent to a server that did
+ not answer for the last @trans_scan_timeout milliseconds.
+ When the number of resends exceeds this limit, the transaction is completed with error.
+ Default is 5 resends.
+
+crypto_thread_num=%u
+ Number of crypto processing threads. Threads are used both for RX and TX traffic.
+ Default is 2, or no threads if crypto operations are not supported.
+
+trans_max_pages=%u
+ Maximum number of pages in a single transaction. This parameter also controls
+ the number of pages, allocated for crypto processing (each crypto thread has
+ pool of pages, the number of which is equal to 'trans_max_pages'.
+ Default is 100 pages.
+
+crypto_fail_unsupported
+ If specified, mount will fail if the server does not support requested crypto operations.
+ By default mount will disable non-matching crypto operations.
+
+mcache_timeout=%u
+ Maximum number of milliseconds to wait for the mcache objects to be processed.
+ Mcache includes locks (given lock should be granted by server), attributes (they should be
+ fully received in the given timeframe).
+ Default is 5 seconds.
+
+Usage examples.
+
+Add (or remove if it already exists) server server1.net:1025 into the working set with index $idx
+with appropriate hash algorithm and key file and cipher algorithm, mode and key file:
+$cfg -a server1.net -p 1025 -i $idx -K $hash_key -k $cipher_key
+
+Mount filesystem with given index $idx to /mnt mountpoint.
+Client will connect to all servers specified in the working set via previous command:
+mount -t pohmel -o idx=$idx q /mnt
+
+One can add or remove servers from working set after mounting too.
+
+
+Server installation.
+
+Creating a server, which listens at port 1025 and 0.0.0.0 address.
+Working root directory (note, that server chroots there, so you have to have appropriate permissions)
+is set to /mnt, server will negotiate hash/cipher with client, in case client requested it, there
+are appropriate key files.
+Number of working threads is set to 10.
+
+# ./fserver -a 0.0.0.0 -p 1025 -r /mnt -w 10 -K hash_key -k cipher_key
+
+ -A 6 - listen on ipv6 address. Default: Disabled.
+ -r root - path to root directory. Default: /tmp.
+ -a addr - listen address. Default: 0.0.0.0.
+ -p port - listen port. Default: 1025.
+ -w workers - number of workers per connected client. Default: 1.
+ -K file - hash key size. Default: none.
+ -k file - cipher key size. Default: none.
+ -h - this help.
+
+Number of worker threads specifies how many workers will be created for each client.
+Bulk single-client transafers usually are better handled with smaller number (like 1-3).
diff --git a/Documentation/filesystems/pohmelfs/network_protocol.txt b/Documentation/filesystems/pohmelfs/network_protocol.txt
new file mode 100644
index 00000000000..40ea6c295af
--- /dev/null
+++ b/Documentation/filesystems/pohmelfs/network_protocol.txt
@@ -0,0 +1,227 @@
+POHMELFS network protocol.
+
+Basic structure used in network communication is following command:
+
+struct netfs_cmd
+{
+ __u16 cmd; /* Command number */
+ __u16 csize; /* Attached crypto information size */
+ __u16 cpad; /* Attached padding size */
+ __u16 ext; /* External flags */
+ __u32 size; /* Size of the attached data */
+ __u32 trans; /* Transaction id */
+ __u64 id; /* Object ID to operate on. Used for feedback.*/
+ __u64 start; /* Start of the object. */
+ __u64 iv; /* IV sequence */
+ __u8 data[0];
+};
+
+Commands can be embedded into transaction command (which in turn has own command),
+so one can extend protocol as needed without breaking backward compatibility as long
+as old commands are supported. All string lengths include tail 0 byte.
+
+All commans are transfered over the network in big-endian. CPU endianess is used at the end peers.
+
+@cmd - command number, which specifies command to be processed. Following
+ commands are used currently:
+
+ NETFS_READDIR = 1, /* Read directory for given inode number */
+ NETFS_READ_PAGE, /* Read data page from the server */
+ NETFS_WRITE_PAGE, /* Write data page to the server */
+ NETFS_CREATE, /* Create directory entry */
+ NETFS_REMOVE, /* Remove directory entry */
+ NETFS_LOOKUP, /* Lookup single object */
+ NETFS_LINK, /* Create a link */
+ NETFS_TRANS, /* Transaction */
+ NETFS_OPEN, /* Open intent */
+ NETFS_INODE_INFO, /* Metadata cache coherency synchronization message */
+ NETFS_PAGE_CACHE, /* Page cache invalidation message */
+ NETFS_READ_PAGES, /* Read multiple contiguous pages in one go */
+ NETFS_RENAME, /* Rename object */
+ NETFS_CAPABILITIES, /* Capabilities of the client, for example supported crypto */
+ NETFS_LOCK, /* Distributed lock message */
+ NETFS_XATTR_SET, /* Set extended attribute */
+ NETFS_XATTR_GET, /* Get extended attribute */
+
+@ext - external flags. Used by different commands to specify some extra arguments
+ like partial size of the embedded objects or creation flags.
+
+@size - size of the attached data. For NETFS_READ_PAGE and NETFS_READ_PAGES no data is attached,
+ but size of the requested data is incorporated here. It does not include size of the command
+ header (struct netfs_cmd) itself.
+
+@id - id of the object this command operates on. Each command can use it for own purpose.
+
+@start - start of the object this command operates on. Each command can use it for own purpose.
+
+@csize, @cpad - size and padding size of the (attached if needed) crypto information.
+
+Command specifications.
+
+@NETFS_READDIR
+This command is used to sync content of the remote dir to the client.
+
+@ext - length of the path to object.
+@size - the same.
+@id - local inode number of the directory to read.
+@start - zero.
+
+
+@NETFS_READ_PAGE
+This command is used to read data from remote server.
+Data size does not exceed local page cache size.
+
+@id - inode number.
+@start - first byte offset.
+@size - number of bytes to read plus length of the path to object.
+@ext - object path length.
+
+
+@NETFS_CREATE
+Used to create object.
+It does not require that all directories on top of the object were
+already created, it will create them automatically. Each object has
+associated @netfs_path_entry data structure, which contains creation
+mode (permissions and type) and length of the name as long as name itself.
+
+@start - 0
+@size - size of the all data structures needed to create a path
+@id - local inode number
+@ext - 0
+
+
+@NETFS_REMOVE
+Used to remove object.
+
+@ext - length of the path to object.
+@size - the same.
+@id - local inode number.
+@start - zero.
+
+
+@NETFS_LOOKUP
+Lookup information about object on server.
+
+@ext - length of the path to object.
+@size - the same.
+@id - local inode number of the directory to look object in.
+@start - local inode number of the object to look at.
+
+
+@NETFS_LINK
+Create hard of symlink.
+Command is sent as "object_path|target_path".
+
+@size - size of the above string.
+@id - parent local inode number.
+@start - 1 for symlink, 0 for hardlink.
+@ext - size of the "object_path" above.
+
+
+@NETFS_TRANS
+Transaction header.
+
+@size - incorporates all embedded command sizes including theirs header sizes.
+@start - transaction generation number - unique id used to find transaction.
+@ext - transaction flags. Unused at the moment.
+@id - 0.
+
+
+@NETFS_OPEN
+Open intent for given transaction.
+
+@id - local inode number.
+@start - 0.
+@size - path length to the object.
+@ext - open flags (O_RDWR and so on).
+
+
+@NETFS_INODE_INFO
+Metadata update command.
+It is sent to servers when attributes of the object are changed and received
+when data or metadata were updated. It operates with the following structure:
+
+struct netfs_inode_info
+{
+ unsigned int mode;
+ unsigned int nlink;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int blocksize;
+ unsigned int padding;
+ __u64 ino;
+ __u64 blocks;
+ __u64 rdev;
+ __u64 size;
+ __u64 version;
+};
+
+It effectively mirrors stat(2) returned data.
+
+
+@ext - path length to the object.
+@size - the same plus size of the netfs_inode_info structure.
+@id - local inode number.
+@start - 0.
+
+
+@NETFS_PAGE_CACHE
+Command is only received by clients. It contains information about
+page to be marked as not up-to-date.
+
+@id - client's inode number.
+@start - last byte of the page to be invalidated. If it is not equal to
+ current inode size, it will be vmtruncated().
+@size - 0
+@ext - 0
+
+
+@NETFS_READ_PAGES
+Used to read multiple contiguous pages in one go.
+
+@start - first byte of the contiguous region to read.
+@size - contains of two fields: lower 8 bits are used to represent page cache shift
+ used by client, another 3 bytes are used to get number of pages.
+@id - local inode number.
+@ext - path length to the object.
+
+
+@NETFS_RENAME
+Used to rename object.
+Attached data is formed into following string: "old_path|new_path".
+
+@id - local inode number.
+@start - parent inode number.
+@size - length of the above string.
+@ext - length of the old path part.
+
+
+@NETFS_CAPABILITIES
+Used to exchange crypto capabilities with server.
+If crypto capabilities are not supported by server, then client will disable it
+or fail (if 'crypto_fail_unsupported' mount options was specified).
+
+@id - superblock index. Used to specify crypto information for group of servers.
+@size - size of the attached capabilities structure.
+@start - 0.
+@size - 0.
+@scsize - 0.
+
+@NETFS_LOCK
+Used to send lock request/release messages. Although it sends byte range request
+and is capable of flushing pages based on that, it is not used, since all Linux
+filesystems lock the whole inode.
+
+@id - lock generation number.
+@start - start of the locked range.
+@size - size of the locked range.
+@ext - lock type: read/write. Not used actually. 15'th bit is used to determine,
+ if it is lock request (1) or release (0).
+
+@NETFS_XATTR_SET
+@NETFS_XATTR_GET
+Used to set/get extended attributes for given inode.
+@id - attribute generation number or xattr setting type
+@start - size of the attribute (request or attached)
+@size - name length, path len and data size for given attribute
+@ext - path length for given object
diff --git a/Documentation/filesystems/udf.txt b/Documentation/filesystems/udf.txt
index fde829a756e..902b95d0ee5 100644
--- a/Documentation/filesystems/udf.txt
+++ b/Documentation/filesystems/udf.txt
@@ -24,6 +24,8 @@ The following mount options are supported:
gid= Set the default group.
umask= Set the default umask.
+ mode= Set the default file permissions.
+ dmode= Set the default directory permissions.
uid= Set the default user.
bs= Set the block size.
unhide Show otherwise hidden files.
diff --git a/Documentation/hwmon/g760a b/Documentation/hwmon/g760a
new file mode 100644
index 00000000000..e032eeb7562
--- /dev/null
+++ b/Documentation/hwmon/g760a
@@ -0,0 +1,36 @@
+Kernel driver g760a
+===================
+
+Supported chips:
+ * Global Mixed-mode Technology Inc. G760A
+ Prefix: 'g760a'
+ Datasheet: Publicly available at the GMT website
+ http://www.gmt.com.tw/datasheet/g760a.pdf
+
+Author: Herbert Valerio Riedel <hvr@gnu.org>
+
+Description
+-----------
+
+The GMT G760A Fan Speed PWM Controller is connected directly to a fan
+and performs closed-loop control of the fan speed.
+
+The fan speed is programmed by setting the period via 'pwm1' of two
+consecutive speed pulses. The period is defined in terms of clock
+cycle counts of an assumed 32kHz clock source.
+
+Setting a period of 0 stops the fan; setting the period to 255 sets
+fan to maximum speed.
+
+The measured fan rotation speed returned via 'fan1_input' is derived
+from the measured speed pulse period by assuming again a 32kHz clock
+source and a 2 pulse-per-revolution fan.
+
+The 'alarms' file provides access to the two alarm bits provided by
+the G760A chip's status register: Bit 0 is set when the actual fan
+speed differs more than 20% with respect to the programmed fan speed;
+bit 1 is set when fan speed is below 1920 RPM.
+
+The g760a driver will not update its values more frequently than every
+other second; reading them more often will do no harm, but will return
+'old' values.
diff --git a/Documentation/ia64/kvm.txt b/Documentation/ia64/kvm.txt
index 84f7cb3d5be..ffb5c80bec3 100644
--- a/Documentation/ia64/kvm.txt
+++ b/Documentation/ia64/kvm.txt
@@ -42,7 +42,7 @@ Note: For step 2, please make sure that host page size == TARGET_PAGE_SIZE of qe
hg clone http://xenbits.xensource.com/ext/efi-vfirmware.hg
you can get the firmware's binary in the directory of efi-vfirmware.hg/binaries.
- (3) Rename the firware you owned to Flash.fd, and copy it to /usr/local/share/qemu
+ (3) Rename the firmware you owned to Flash.fd, and copy it to /usr/local/share/qemu
4. Boot up Linux or Windows guests:
4.1 Create or install a image for guest boot. If you have xen experience, it should be easy.
diff --git a/Documentation/infiniband/ipoib.txt b/Documentation/infiniband/ipoib.txt
index 864ff328378..6d40f00b358 100644
--- a/Documentation/infiniband/ipoib.txt
+++ b/Documentation/infiniband/ipoib.txt
@@ -24,6 +24,49 @@ Partitions and P_Keys
The P_Key for any interface is given by the "pkey" file, and the
main interface for a subinterface is in "parent."
+Datagram vs Connected modes
+
+ The IPoIB driver supports two modes of operation: datagram and
+ connected. The mode is set and read through an interface's
+ /sys/class/net/<intf name>/mode file.
+
+ In datagram mode, the IB UD (Unreliable Datagram) transport is used
+ and so the interface MTU has is equal to the IB L2 MTU minus the
+ IPoIB encapsulation header (4 bytes). For example, in a typical IB
+ fabric with a 2K MTU, the IPoIB MTU will be 2048 - 4 = 2044 bytes.
+
+ In connected mode, the IB RC (Reliable Connected) transport is used.
+ Connected mode is to takes advantage of the connected nature of the
+ IB transport and allows an MTU up to the maximal IP packet size of
+ 64K, which reduces the number of IP packets needed for handling
+ large UDP datagrams, TCP segments, etc and increases the performance
+ for large messages.
+
+ In connected mode, the interface's UD QP is still used for multicast
+ and communication with peers that don't support connected mode. In
+ this case, RX emulation of ICMP PMTU packets is used to cause the
+ networking stack to use the smaller UD MTU for these neighbours.
+
+Stateless offloads
+
+ If the IB HW supports IPoIB stateless offloads, IPoIB advertises
+ TCP/IP checksum and/or Large Send (LSO) offloading capability to the
+ network stack.
+
+ Large Receive (LRO) offloading is also implemented and may be turned
+ on/off using ethtool calls. Currently LRO is supported only for
+ checksum offload capable devices.
+
+ Stateless offloads are supported only in datagram mode.
+
+Interrupt moderation
+
+ If the underlying IB device supports CQ event moderation, one can
+ use ethtool to set interrupt mitigation parameters and thus reduce
+ the overhead incurred by handling interrupts. The main code path of
+ IPoIB doesn't use events for TX completion signaling so only RX
+ moderation is supported.
+
Debugging Information
By compiling the IPoIB driver with CONFIG_INFINIBAND_IPOIB_DEBUG set
@@ -55,3 +98,5 @@ References
http://ietf.org/rfc/rfc4391.txt
IP over InfiniBand (IPoIB) Architecture (RFC 4392)
http://ietf.org/rfc/rfc4392.txt
+ IP over InfiniBand: Connected Mode (RFC 4755)
+ http://ietf.org/rfc/rfc4755.txt
diff --git a/Documentation/input/rotary-encoder.txt b/Documentation/input/rotary-encoder.txt
new file mode 100644
index 00000000000..435102a26d9
--- /dev/null
+++ b/Documentation/input/rotary-encoder.txt
@@ -0,0 +1,101 @@
+rotary-encoder - a generic driver for GPIO connected devices
+Daniel Mack <daniel@caiaq.de>, Feb 2009
+
+0. Function
+-----------
+
+Rotary encoders are devices which are connected to the CPU or other
+peripherals with two wires. The outputs are phase-shifted by 90 degrees
+and by triggering on falling and rising edges, the turn direction can
+be determined.
+
+The phase diagram of these two outputs look like this:
+
+ _____ _____ _____
+ | | | | | |
+ Channel A ____| |_____| |_____| |____
+
+ : : : : : : : : : : : :
+ __ _____ _____ _____
+ | | | | | | |
+ Channel B |_____| |_____| |_____| |__
+
+ : : : : : : : : : : : :
+ Event a b c d a b c d a b c d
+
+ |<-------->|
+ one step
+
+
+For more information, please see
+ http://en.wikipedia.org/wiki/Rotary_encoder
+
+
+1. Events / state machine
+-------------------------
+
+a) Rising edge on channel A, channel B in low state
+ This state is used to recognize a clockwise turn
+
+b) Rising edge on channel B, channel A in high state
+ When entering this state, the encoder is put into 'armed' state,
+ meaning that there it has seen half the way of a one-step transition.
+
+c) Falling edge on channel A, channel B in high state
+ This state is used to recognize a counter-clockwise turn
+
+d) Falling edge on channel B, channel A in low state
+ Parking position. If the encoder enters this state, a full transition
+ should have happend, unless it flipped back on half the way. The
+ 'armed' state tells us about that.
+
+2. Platform requirements
+------------------------
+
+As there is no hardware dependent call in this driver, the platform it is
+used with must support gpiolib. Another requirement is that IRQs must be
+able to fire on both edges.
+
+
+3. Board integration
+--------------------
+
+To use this driver in your system, register a platform_device with the
+name 'rotary-encoder' and associate the IRQs and some specific platform
+data with it.
+
+struct rotary_encoder_platform_data is declared in
+include/linux/rotary-encoder.h and needs to be filled with the number of
+steps the encoder has and can carry information about externally inverted
+signals (because of used invertig buffer or other reasons).
+
+Because GPIO to IRQ mapping is platform specific, this information must
+be given in seperately to the driver. See the example below.
+
+---------<snip>---------
+
+/* board support file example */
+
+#include <linux/input.h>
+#include <linux/rotary_encoder.h>
+
+#define GPIO_ROTARY_A 1
+#define GPIO_ROTARY_B 2
+
+static struct rotary_encoder_platform_data my_rotary_encoder_info = {
+ .steps = 24,
+ .axis = ABS_X,
+ .gpio_a = GPIO_ROTARY_A,
+ .gpio_b = GPIO_ROTARY_B,
+ .inverted_a = 0,
+ .inverted_b = 0,
+};
+
+static struct platform_device rotary_encoder_device = {
+ .name = "rotary-encoder",
+ .id = 0,
+ .dev = {
+ .platform_data = &my_rotary_encoder_info,
+ }
+};
+
diff --git a/Documentation/isdn/README.gigaset b/Documentation/isdn/README.gigaset
index 55b2852904a..02c0e9341dd 100644
--- a/Documentation/isdn/README.gigaset
+++ b/Documentation/isdn/README.gigaset
@@ -61,24 +61,28 @@ GigaSet 307x Device Driver
---------------------
2.1. Modules
-------
- To get the device working, you have to load the proper kernel module. You
- can do this using
- modprobe modulename
- where modulename is ser_gigaset (M101), usb_gigaset (M105), or
- bas_gigaset (direct USB connection to the base).
+ For the devices to work, the proper kernel modules have to be loaded.
+ This normally happens automatically when the system detects the USB
+ device (base, M105) or when the line discipline is attached (M101). It
+ can also be triggered manually using the modprobe(8) command, for example
+ for troubleshooting or to pass module parameters.
The module ser_gigaset provides a serial line discipline N_GIGASET_M101
- which drives the device through the regular serial line driver. To use it,
- run the Gigaset M101 daemon "gigasetm101d" (also available from
- http://sourceforge.net/projects/gigaset307x/) with the device file of the
- RS232 port to the M101 as an argument, for example:
- gigasetm101d /dev/ttyS1
- This will open the device file, set its line discipline to N_GIGASET_M101,
- and then sleep in the background, keeping the device open so that the
- line discipline remains active. To deactivate it, kill the daemon, for
- example with
- killall gigasetm101d
- before disconnecting the device.
+ which drives the device through the regular serial line driver. It must
+ be attached to the serial line to which the M101 is connected with the
+ ldattach(8) command (requires util-linux-ng release 2.14 or later), for
+ example:
+ ldattach GIGASET_M101 /dev/ttyS1
+ This will open the device file, attach the line discipline to it, and
+ then sleep in the background, keeping the device open so that the line
+ discipline remains active. To deactivate it, kill the daemon, for example
+ with
+ killall ldattach
+ before disconnecting the device. To have this happen automatically at
+ system startup/shutdown on an LSB compatible system, create and activate
+ an appropriate LSB startup script /etc/init.d/gigaset. (The init name
+ 'gigaset' is officially assigned to this project by LANANA.)
+ Alternatively, just add the 'ldattach' command line to /etc/rc.local.
2.2. Device nodes for user space programs
------------------------------------
@@ -194,10 +198,11 @@ GigaSet 307x Device Driver
operation (for wireless access to the base), but are needed for access
to the M105's own configuration mode (registration to the base, baudrate
and line format settings, device status queries) via the gigacontr
- utility. Their use is disabled in the driver by default for safety
- reasons but can be enabled by setting the kernel configuration option
- "Support for undocumented USB requests" (GIGASET_UNDOCREQ) to "Y" and
- recompiling.
+ utility. Their use is controlled by the kernel configuration option
+ "Support for undocumented USB requests" (CONFIG_GIGASET_UNDOCREQ). If you
+ encounter error code -ENOTTY when trying to use some features of the
+ M105, try setting that option to "y" via 'make {x,menu}config' and
+ recompiling the driver.
3. Troubleshooting
@@ -228,6 +233,13 @@ GigaSet 307x Device Driver
Solution:
Select Unimodem mode for all DECT data adapters. (see section 2.4.)
+ Problem:
+ You want to configure your USB DECT data adapter (M105) but gigacontr
+ reports an error: "/dev/ttyGU0: Inappropriate ioctl for device".
+ Solution:
+ Recompile the usb_gigaset driver with the kernel configuration option
+ CONFIG_GIGASET_UNDOCREQ set to 'y'. (see section 2.6.)
+
3.2. Telling the driver to provide more information
----------------------------------------------
Building the driver with the "Gigaset debugging" kernel configuration
diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index 51104f9194a..d4b05672f9f 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -40,10 +40,16 @@ This document describes the Linux kernel Makefiles.
--- 6.7 Custom kbuild commands
--- 6.8 Preprocessing linker scripts
- === 7 Kbuild Variables
- === 8 Makefile language
- === 9 Credits
- === 10 TODO
+ === 7 Kbuild syntax for exported headers
+ --- 7.1 header-y
+ --- 7.2 objhdr-y
+ --- 7.3 destination-y
+ --- 7.4 unifdef-y (deprecated)
+
+ === 8 Kbuild Variables
+ === 9 Makefile language
+ === 10 Credits
+ === 11 TODO
=== 1 Overview
@@ -1143,8 +1149,69 @@ When kbuild executes, the following steps are followed (roughly):
The kbuild infrastructure for *lds file are used in several
architecture-specific files.
+=== 7 Kbuild syntax for exported headers
+
+The kernel include a set of headers that is exported to userspace.
+Many headers can be exported as-is but other headers requires a
+minimal pre-processing before they are ready for user-space.
+The pre-processing does:
+- drop kernel specific annotations
+- drop include of compiler.h
+- drop all sections that is kernel internat (guarded by ifdef __KERNEL__)
+
+Each relevant directory contain a file name "Kbuild" which specify the
+headers to be exported.
+See subsequent chapter for the syntax of the Kbuild file.
+
+ --- 7.1 header-y
+
+ header-y specify header files to be exported.
+
+ Example:
+ #include/linux/Kbuild
+ header-y += usb/
+ header-y += aio_abi.h
+
+ The convention is to list one file per line and
+ preferably in alphabetic order.
+
+ header-y also specify which subdirectories to visit.
+ A subdirectory is identified by a trailing '/' which
+ can be seen in the example above for the usb subdirectory.
+
+ Subdirectories are visited before their parent directories.
+
+ --- 7.2 objhdr-y
+
+ objhdr-y specifies generated files to be exported.
+ Generated files are special as they need to be looked
+ up in another directory when doing 'make O=...' builds.
+
+ Example:
+ #include/linux/Kbuild
+ objhdr-y += version.h
+
+ --- 7.3 destination-y
+
+ When an architecture have a set of exported headers that needs to be
+ exported to a different directory destination-y is used.
+ destination-y specify the destination directory for all exported
+ headers in the file where it is present.
+
+ Example:
+ #arch/xtensa/platforms/s6105/include/platform/Kbuild
+ destination-y := include/linux
+
+ In the example above all exported headers in the Kbuild file
+ will be located in the directory "include/linux" when exported.
+
+
+ --- 7.4 unifdef-y (deprecated)
+
+ unifdef-y is deprecated. A direct replacement is header-y.
+
-=== 7 Kbuild Variables
+=== 8 Kbuild Variables
The top Makefile exports the following variables:
@@ -1206,7 +1273,7 @@ The top Makefile exports the following variables:
INSTALL_MOD_STRIP will used as the option(s) to the strip command.
-=== 8 Makefile language
+=== 9 Makefile language
The kernel Makefiles are designed to be run with GNU Make. The Makefiles
use only the documented features of GNU Make, but they do use many
@@ -1225,14 +1292,14 @@ time the left-hand side is used.
There are some cases where "=" is appropriate. Usually, though, ":="
is the right choice.
-=== 9 Credits
+=== 10 Credits
Original version made by Michael Elizabeth Chastain, <mailto:mec@shout.net>
Updates by Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
Updates by Sam Ravnborg <sam@ravnborg.org>
Language QA by Jan Engelhardt <jengelh@gmx.de>
-=== 10 TODO
+=== 11 TODO
- Describe how kbuild supports shipped files with _shipped.
- Generating offset header files.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 240257dd423..6172e4360f6 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -50,6 +50,7 @@ parameter is applicable:
ISAPNP ISA PnP code is enabled.
ISDN Appropriate ISDN support is enabled.
JOY Appropriate joystick support is enabled.
+ KMEMTRACE kmemtrace is enabled.
LIBATA Libata driver is enabled
LP Printer support is enabled.
LOOP Loopback device support is enabled.
@@ -152,60 +153,6 @@ and is between 256 and 4096 characters. It is defined in the file
1,0: use 1st APIC table
default: 0
- acpi_sleep= [HW,ACPI] Sleep options
- Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig,
- old_ordering, s4_nonvs }
- See Documentation/power/video.txt for information on
- s3_bios and s3_mode.
- s3_beep is for debugging; it makes the PC's speaker beep
- as soon as the kernel's real-mode entry point is called.
- s4_nohwsig prevents ACPI hardware signature from being
- used during resume from hibernation.
- old_ordering causes the ACPI 1.0 ordering of the _PTS
- control method, with respect to putting devices into
- low power states, to be enforced (the ACPI 2.0 ordering
- of _PTS is used by default).
- s4_nonvs prevents the kernel from saving/restoring the
- ACPI NVS memory during hibernation.
-
- acpi_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode
- Format: { level | edge | high | low }
-
- acpi_irq_balance [HW,ACPI]
- ACPI will balance active IRQs
- default in APIC mode
-
- acpi_irq_nobalance [HW,ACPI]
- ACPI will not move active IRQs (default)
- default in PIC mode
-
- acpi_irq_pci= [HW,ACPI] If irq_balance, clear listed IRQs for
- use by PCI
- Format: <irq>,<irq>...
-
- acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA
- Format: <irq>,<irq>...
-
- acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT
-
- acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS
- Format: To spoof as Windows 98: ="Microsoft Windows"
-
- acpi_osi= [HW,ACPI] Modify list of supported OS interface strings
- acpi_osi="string1" # add string1 -- only one string
- acpi_osi="!string2" # remove built-in string2
- acpi_osi= # disable all strings
-
- acpi_serialize [HW,ACPI] force serialization of AML methods
-
- acpi_skip_timer_override [HW,ACPI]
- Recognize and ignore IRQ0/pin2 Interrupt Override.
- For broken nForce2 BIOS resulting in XT-PIC timer.
- acpi_use_timer_override [HW,ACPI]
- Use timer override. For some broken Nvidia NF5 boards
- that require a timer override, but don't have
- HPET
-
acpi_backlight= [HW,ACPI]
acpi_backlight=vendor
acpi_backlight=video
@@ -213,11 +160,6 @@ and is between 256 and 4096 characters. It is defined in the file
(e.g. thinkpad_acpi, sony_acpi, etc.) instead
of the ACPI video.ko driver.
- acpi_display_output= [HW,ACPI]
- acpi_display_output=vendor
- acpi_display_output=video
- See above.
-
acpi.debug_layer= [HW,ACPI,ACPI_DEBUG]
acpi.debug_level= [HW,ACPI,ACPI_DEBUG]
Format: <int>
@@ -246,6 +188,41 @@ and is between 256 and 4096 characters. It is defined in the file
unusable. The "log_buf_len" parameter may be useful
if you need to capture more output.
+ acpi_display_output= [HW,ACPI]
+ acpi_display_output=vendor
+ acpi_display_output=video
+ See above.
+
+ acpi_irq_balance [HW,ACPI]
+ ACPI will balance active IRQs
+ default in APIC mode
+
+ acpi_irq_nobalance [HW,ACPI]
+ ACPI will not move active IRQs (default)
+ default in PIC mode
+
+ acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA
+ Format: <irq>,<irq>...
+
+ acpi_irq_pci= [HW,ACPI] If irq_balance, clear listed IRQs for
+ use by PCI
+ Format: <irq>,<irq>...
+
+ acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT
+
+ acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS
+ Format: To spoof as Windows 98: ="Microsoft Windows"
+
+ acpi_osi= [HW,ACPI] Modify list of supported OS interface strings
+ acpi_osi="string1" # add string1 -- only one string
+ acpi_osi="!string2" # remove built-in string2
+ acpi_osi= # disable all strings
+
+ acpi_pm_good [X86-32,X86-64]
+ Override the pmtimer bug detection: force the kernel
+ to assume that this machine's pmtimer latches its value
+ and always returns good values.
+
acpi.power_nocheck= [HW,ACPI]
Format: 1/0 enable/disable the check of power state.
On some bogus BIOS the _PSC object/_STA object of
@@ -254,26 +231,21 @@ and is between 256 and 4096 characters. It is defined in the file
power state again in power transition.
1 : disable the power state check
- acpi_pm_good [X86-32,X86-64]
- Override the pmtimer bug detection: force the kernel
- to assume that this machine's pmtimer latches its value
- and always returns good values.
-
- agp= [AGP]
- { off | try_unsupported }
- off: disable AGP support
- try_unsupported: try to drive unsupported chipsets
- (may crash computer or cause data corruption)
-
- enable_timer_pin_1 [i386,x86-64]
- Enable PIN 1 of APIC timer
- Can be useful to work around chipset bugs
- (in particular on some ATI chipsets).
- The kernel tries to set a reasonable default.
-
- disable_timer_pin_1 [i386,x86-64]
- Disable PIN 1 of APIC timer
- Can be useful to work around chipset bugs.
+ acpi_enforce_resources= [ACPI]
+ { strict | lax | no }
+ Check for resource conflicts between native drivers
+ and ACPI OperationRegions (SystemIO and SystemMemory
+ only). IO ports and memory declared in ACPI might be
+ used by the ACPI subsystem in arbitrary AML code and
+ can interfere with legacy drivers.
+ strict (default): access to resources claimed by ACPI
+ is denied; legacy drivers trying to access reserved
+ resources will fail to bind to device using them.
+ lax: access to resources claimed by ACPI is allowed;
+ legacy drivers trying to access reserved resources
+ will bind successfully but a warning message is logged.
+ no: ACPI OperationRegions are not marked as reserved,
+ no further checks are performed.
ad1848= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>,<type>
@@ -288,6 +260,12 @@ and is between 256 and 4096 characters. It is defined in the file
Format: <io>,<irq>,<dma>,<mss_io>,<mpu_io>,<mpu_irq>
See also header of sound/oss/aedsp16.c.
+ agp= [AGP]
+ { off | try_unsupported }
+ off: disable AGP support
+ try_unsupported: try to drive unsupported chipsets
+ (may crash computer or cause data corruption)
+
aha152x= [HW,SCSI]
See Documentation/scsi/aha152x.txt.
@@ -415,12 +393,6 @@ and is between 256 and 4096 characters. It is defined in the file
possible to determine what the correct size should be.
This option provides an override for these situations.
- security= [SECURITY] Choose a security module to enable at boot.
- If this boot parameter is not specified, only the first
- security module asking for security registration will be
- loaded. An invalid security module name will be treated
- as if no module has been chosen.
-
capability.disable=
[SECURITY] Disable capabilities. This would normally
be used only if an alternative security model is to be
@@ -492,24 +464,6 @@ and is between 256 and 4096 characters. It is defined in the file
Range: 0 - 8192
Default: 64
- dma_debug=off If the kernel is compiled with DMA_API_DEBUG support
- this option disables the debugging code at boot.
-
- dma_debug_entries=<number>
- This option allows to tune the number of preallocated
- entries for DMA-API debugging code. One entry is
- required per DMA-API allocation. Use this if the
- DMA-API debugging code disables itself because the
- architectural default is too low.
-
- hpet= [X86-32,HPET] option to control HPET usage
- Format: { enable (default) | disable | force |
- verbose }
- disable: disable HPET and use PIT instead
- force: allow force enabled of undocumented chips (ICH4,
- VIA, nVidia)
- verbose: show contents of HPET registers during setup
-
com20020= [HW,NET] ARCnet - COM20020 chipset
Format:
<io>[,<irq>[,<nodeID>[,<backplane>[,<ckp>[,<timeout>]]]]]
@@ -553,23 +507,6 @@ and is between 256 and 4096 characters. It is defined in the file
console=brl,ttyS0
For now, only VisioBraille is supported.
- earlycon= [KNL] Output early console device and options.
- uart[8250],io,<addr>[,options]
- uart[8250],mmio,<addr>[,options]
- Start an early, polled-mode console on the 8250/16550
- UART at the specified I/O port or MMIO address.
- The options are the same as for ttyS, above.
-
- no_console_suspend
- [HW] Never suspend the console
- Disable suspending of consoles during suspend and
- hibernate operations. Once disabled, debugging
- messages can reach various consoles while the rest
- of the system is being put to sleep (ie, while
- debugging driver suspend/resume hooks). This may
- not work reliably with all consoles, but is known
- to work with serial and VGA consoles.
-
coredump_filter=
[KNL] Change the default value for
/proc/<pid>/coredump_filter.
@@ -617,36 +554,22 @@ and is between 256 and 4096 characters. It is defined in the file
debug_objects [KNL] Enable object debugging
+ no_debug_objects
+ [KNL] Disable object debugging
+
debugpat [X86] Enable PAT debugging
decnet.addr= [HW,NET]
Format: <area>[,<node>]
See also Documentation/networking/decnet.txt.
- vt.default_blu= [VT]
- Format: <blue0>,<blue1>,<blue2>,...,<blue15>
- Change the default blue palette of the console.
- This is a 16-member array composed of values
- ranging from 0-255.
-
- vt.default_grn= [VT]
- Format: <green0>,<green1>,<green2>,...,<green15>
- Change the default green palette of the console.
- This is a 16-member array composed of values
- ranging from 0-255.
-
- vt.default_red= [VT]
- Format: <red0>,<red1>,<red2>,...,<red15>
- Change the default red palette of the console.
- This is a 16-member array composed of values
- ranging from 0-255.
-
- vt.default_utf8=
- [VT]
- Format=<0|1>
- Set system-wide default UTF-8 mode for all tty's.
- Default is 1, i.e. UTF-8 mode is enabled for all
- newly opened terminals.
+ default_hugepagesz=
+ [same as hugepagesz=] The size of the default
+ HugeTLB page size. This is the size represented by
+ the legacy /proc/ hugepages APIs, used for SHM, and
+ default size when mounting hugetlbfs filesystems.
+ Defaults to the default architecture's huge page size
+ if not specified.
dhash_entries= [KNL]
Set number of hash buckets for dentry cache.
@@ -659,27 +582,9 @@ and is between 256 and 4096 characters. It is defined in the file
Documentation/serial/digiepca.txt.
disable_mtrr_cleanup [X86]
- enable_mtrr_cleanup [X86]
The kernel tries to adjust MTRR layout from continuous
to discrete, to make X server driver able to add WB
- entry later. This parameter enables/disables that.
-
- mtrr_chunk_size=nn[KMG] [X86]
- used for mtrr cleanup. It is largest continous chunk
- that could hold holes aka. UC entries.
-
- mtrr_gran_size=nn[KMG] [X86]
- Used for mtrr cleanup. It is granularity of mtrr block.
- Default is 1.
- Large value could prevent small alignment from
- using up MTRRs.
-
- mtrr_spare_reg_nr=n [X86]
- Format: <integer>
- Range: 0,7 : spare reg number
- Default : 1
- Used for mtrr cleanup. It is spare mtrr entries number.
- Set to 2 or more if your graphical card needs more.
+ entry later. This parameter disables that.
disable_mtrr_trim [X86, Intel and AMD only]
By default the kernel will trim any uncacheable
@@ -687,12 +592,38 @@ and is between 256 and 4096 characters. It is defined in the file
MTRR settings. This parameter disables that behavior,
possibly causing your machine to run very slowly.
+ disable_timer_pin_1 [i386,x86-64]
+ Disable PIN 1 of APIC timer
+ Can be useful to work around chipset bugs.
+
dmasound= [HW,OSS] Sound subsystem buffers
+ dma_debug=off If the kernel is compiled with DMA_API_DEBUG support,
+ this option disables the debugging code at boot.
+
+ dma_debug_entries=<number>
+ This option allows to tune the number of preallocated
+ entries for DMA-API debugging code. One entry is
+ required per DMA-API allocation. Use this if the
+ DMA-API debugging code disables itself because the
+ architectural default is too low.
+
dscc4.setup= [NET]
dtc3181e= [HW,SCSI]
+ 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
+
+ earlycon= [KNL] Output early console device and options.
+ uart[8250],io,<addr>[,options]
+ uart[8250],mmio,<addr>[,options]
+ Start an early, polled-mode console on the 8250/16550
+ UART at the specified I/O port or MMIO address.
+ The options are the same as for ttyS, above.
+
earlyprintk= [X86-32,X86-64,SH,BLACKFIN]
earlyprintk=vga
earlyprintk=serial[,ttySn[,baudrate]]
@@ -734,6 +665,17 @@ and is between 256 and 4096 characters. It is defined in the file
pass this option to capture kernel.
See Documentation/kdump/kdump.txt for details.
+ enable_mtrr_cleanup [X86]
+ The kernel tries to adjust MTRR layout from continuous
+ to discrete, to make X server driver able to add WB
+ entry later. This parameter enables that.
+
+ enable_timer_pin_1 [i386,x86-64]
+ Enable PIN 1 of APIC timer
+ Can be useful to work around chipset bugs
+ (in particular on some ATI chipsets).
+ The kernel tries to set a reasonable default.
+
enforcing [SELINUX] Set initial enforcing status.
Format: {"0" | "1"}
See security/selinux/Kconfig help text.
@@ -821,6 +763,16 @@ and is between 256 and 4096 characters. It is defined in the file
hisax= [HW,ISDN]
See Documentation/isdn/README.HiSax.
+ hlt [BUGS=ARM,SH]
+
+ hpet= [X86-32,HPET] option to control HPET usage
+ Format: { enable (default) | disable | force |
+ verbose }
+ disable: disable HPET and use PIT instead
+ force: allow force enabled of undocumented chips (ICH4,
+ VIA, nVidia)
+ verbose: show contents of HPET registers during setup
+
hugepages= [HW,X86-32,IA-64] HugeTLB pages to allocate at boot.
hugepagesz= [HW,IA-64,PPC,X86-64] The size of the HugeTLB pages.
On x86-64 and powerpc, this option can be specified
@@ -830,15 +782,6 @@ and is between 256 and 4096 characters. It is defined in the file
(when the CPU supports the "pdpe1gb" cpuinfo flag)
Note that 1GB pages can only be allocated at boot time
using hugepages= and not freed afterwards.
- default_hugepagesz=
- [same as hugepagesz=] The size of the default
- HugeTLB page size. This is the size represented by
- the legacy /proc/ hugepages APIs, used for SHM, and
- default size when mounting hugetlbfs filesystems.
- Defaults to the default architecture's huge page size
- if not specified.
-
- hlt [BUGS=ARM,SH]
hvc_iucv= [S390] Number of z/VM IUCV hypervisor console (HVC)
terminal devices. Valid values: 0..8
@@ -899,6 +842,9 @@ and is between 256 and 4096 characters. It is defined in the file
idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed
See Documentation/ide/ide.txt.
+ ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
+ Claim all unknown PCI IDE storage controllers.
+
idle= [X86]
Format: idle=poll, idle=mwait, idle=halt, idle=nomwait
Poll forces a polling idle loop that can slightly
@@ -914,9 +860,6 @@ and is between 256 and 4096 characters. It is defined in the file
In such case C2/C3 won't be used again.
idle=nomwait: Disable mwait for CPU C-states
- ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
- Claim all unknown PCI IDE storage controllers.
-
ignore_loglevel [KNL]
Ignore loglevel setting - this will print /all/
kernel messages to the console. Useful for debugging.
@@ -950,25 +893,6 @@ and is between 256 and 4096 characters. It is defined in the file
inport.irq= [HW] Inport (ATI XL and Microsoft) busmouse driver
Format: <irq>
- inttest= [IA64]
-
- iomem= Disable strict checking of access to MMIO memory
- strict regions from userspace.
- relaxed
-
- iommu= [x86]
- off
- force
- noforce
- biomerge
- panic
- nopanic
- merge
- nomerge
- forcesac
- soft
-
-
intel_iommu= [DMAR] Intel IOMMU driver (DMAR) option
on
Enable intel iommu driver.
@@ -992,6 +916,28 @@ and is between 256 and 4096 characters. It is defined in the file
result in a hardware IOTLB flush operation as opposed
to batching them for performance.
+ inttest= [IA64]
+
+ iomem= Disable strict checking of access to MMIO memory
+ strict regions from userspace.
+ relaxed
+
+ iommu= [x86]
+ off
+ force
+ noforce
+ biomerge
+ panic
+ nopanic
+ merge
+ nomerge
+ forcesac
+ soft
+
+ io7= [HW] IO7 for Marvel based alpha systems
+ See comment before marvel_specify_io7 in
+ arch/alpha/kernel/core_marvel.c.
+
io_delay= [X86-32,X86-64] I/O delay method
0x80
Standard port 0x80 based delay
@@ -1002,10 +948,6 @@ and is between 256 and 4096 characters. It is defined in the file
none
No delay
- io7= [HW] IO7 for Marvel based alpha systems
- See comment before marvel_specify_io7 in
- arch/alpha/kernel/core_marvel.c.
-
ip= [IP_PNP]
See Documentation/filesystems/nfsroot.txt.
@@ -1016,12 +958,6 @@ and is between 256 and 4096 characters. It is defined in the file
ips= [HW,SCSI] Adaptec / IBM ServeRAID controller
See header of drivers/scsi/ips.c.
- ports= [IP_VS_FTP] IPVS ftp helper module
- Default is 21.
- Up to 8 (IP_VS_APP_MAX_PORTS) ports
- may be specified.
- Format: <port>,<port>....
-
irqfixup [HW]
When an interrupt is not handled search all handlers
for it. Intended to get systems with badly broken
@@ -1062,6 +998,8 @@ and is between 256 and 4096 characters. It is defined in the file
js= [HW,JOY] Analog joystick
See Documentation/input/joystick.txt.
+ keepinitrd [HW,ARM]
+
kernelcore=nn[KMG] [KNL,X86-32,IA-64,PPC,X86-64] This parameter
specifies the amount of memory usable by the kernel
for non-movable allocations. The requested amount is
@@ -1078,20 +1016,14 @@ and is between 256 and 4096 characters. It is defined in the file
use the HighMem zone if it exists, and the Normal
zone if it does not.
- movablecore=nn[KMG] [KNL,X86-32,IA-64,PPC,X86-64] This parameter
- is similar to kernelcore except it specifies the
- amount of memory used for migratable allocations.
- If both kernelcore and movablecore is specified,
- then kernelcore will be at *least* the specified
- value but may be more. If movablecore on its own
- is specified, the administrator must be careful
- that the amount of memory usable for all allocations
- is not too small.
-
- keepinitrd [HW,ARM]
+ kmemtrace.enable= [KNL,KMEMTRACE] Format: { yes | no }
+ Controls whether kmemtrace is enabled
+ at boot-time.
- kstack=N [X86-32,X86-64] Print N words from the kernel stack
- in oops dumps.
+ kmemtrace.subbufs=n [KNL,KMEMTRACE] Overrides the number of
+ subbufs kmemtrace's relay channel has. Set this
+ higher than default (KMEMTRACE_N_SUBBUFS in code) if
+ you experience buffer overruns.
kgdboc= [HW] kgdb over consoles.
Requires a tty driver that supports console polling.
@@ -1102,6 +1034,9 @@ and is between 256 and 4096 characters. It is defined in the file
Configure the RouterBoard 532 series on-chip
Ethernet adapter MAC address.
+ kstack=N [X86-32,X86-64] Print N words from the kernel stack
+ in oops dumps.
+
l2cr= [PPC]
l3cr= [PPC]
@@ -1247,9 +1182,8 @@ and is between 256 and 4096 characters. It is defined in the file
(machvec) in a generic kernel.
Example: machvec=hpzx1_swiotlb
- max_loop= [LOOP] Maximum number of loopback devices that can
- be mounted
- Format: <1-256>
+ max_addr=nn[KMG] [KNL,BOOT,ia64] All physical memory greater
+ than or equal to this physical address is ignored.
maxcpus= [SMP] Maximum number of processors that an SMP kernel
should make use of. maxcpus=n : n >= 0 limits the
@@ -1257,8 +1191,9 @@ and is between 256 and 4096 characters. It is defined in the file
it is equivalent to "nosmp", which also disables
the IO APIC.
- max_addr=nn[KMG] [KNL,BOOT,ia64] All physical memory greater than
- or equal to this physical address is ignored.
+ max_loop= [LOOP] Maximum number of loopback devices that can
+ be mounted
+ Format: <1-256>
max_luns= [SCSI] Maximum number of LUNs to probe.
Should be between 1 and 2^32-1.
@@ -1385,6 +1320,16 @@ and is between 256 and 4096 characters. It is defined in the file
mousedev.yres= [MOUSE] Vertical screen resolution, used for devices
reporting absolute coordinates, such as tablets
+ movablecore=nn[KMG] [KNL,X86-32,IA-64,PPC,X86-64] This parameter
+ is similar to kernelcore except it specifies the
+ amount of memory used for migratable allocations.
+ If both kernelcore and movablecore is specified,
+ then kernelcore will be at *least* the specified
+ value but may be more. If movablecore on its own
+ is specified, the administrator must be careful
+ that the amount of memory usable for all allocations
+ is not too small.
+
mpu401= [HW,OSS]
Format: <io>,<irq>
@@ -1406,6 +1351,23 @@ and is between 256 and 4096 characters. It is defined in the file
[HW] Make the MicroTouch USB driver use raw coordinates
('y', default) or cooked coordinates ('n')
+ mtrr_chunk_size=nn[KMG] [X86]
+ used for mtrr cleanup. It is largest continous chunk
+ that could hold holes aka. UC entries.
+
+ mtrr_gran_size=nn[KMG] [X86]
+ Used for mtrr cleanup. It is granularity of mtrr block.
+ Default is 1.
+ Large value could prevent small alignment from
+ using up MTRRs.
+
+ mtrr_spare_reg_nr=n [X86]
+ Format: <integer>
+ Range: 0,7 : spare reg number
+ Default : 1
+ Used for mtrr cleanup. It is spare mtrr entries number.
+ Set to 2 or more if your graphical card needs more.
+
n2= [NET] SDL Inc. RISCom/N2 synchronous serial card
NCR_D700= [HW,SCSI]
@@ -1466,11 +1428,13 @@ and is between 256 and 4096 characters. It is defined in the file
0 - turn nmi_watchdog off
1 - use the IO-APIC timer for the NMI watchdog
2 - use the local APIC for the NMI watchdog using
- a performance counter. Note: This will use one performance
- counter and the local APIC's performance vector.
- When panic is specified panic when an NMI watchdog timeout occurs.
- This is useful when you use a panic=... timeout and need the box
- quickly up again.
+ a performance counter. Note: This will use one
+ performance counter and the local APIC's performance
+ vector.
+ When panic is specified, panic when an NMI watchdog
+ timeout occurs.
+ This is useful when you use a panic=... timeout and
+ need the box quickly up again.
Instead of 1 and 2 it is possible to use the following
symbolic names: lapic and ioapic
Example: nmi_watchdog=2 or nmi_watchdog=panic,lapic
@@ -1479,6 +1443,16 @@ and is between 256 and 4096 characters. It is defined in the file
emulation library even if a 387 maths coprocessor
is present.
+ no_console_suspend
+ [HW] Never suspend the console
+ Disable suspending of consoles during suspend and
+ hibernate operations. Once disabled, debugging
+ messages can reach various consoles while the rest
+ of the system is being put to sleep (ie, while
+ debugging driver suspend/resume hooks). This may
+ not work reliably with all consoles, but is known
+ to work with serial and VGA consoles.
+
noaliencache [MM, NUMA, SLAB] Disables the allocation of alien
caches in the slab allocator. Saves per-node memory,
but will impact performance.
@@ -1493,6 +1467,8 @@ and is between 256 and 4096 characters. It is defined in the file
nocache [ARM]
+ noclflush [BUGS=X86] Don't use the CLFLUSH instruction
+
nodelayacct [KNL] Disable per-task delay accounting
nodisconnect [HW,SCSI,M68K] Disables SCSI disconnects.
@@ -1521,9 +1497,9 @@ and is between 256 and 4096 characters. It is defined in the file
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,SH]
+ nohlt [BUGS=ARM,SH] Tells the kernel that the sleep(SH) or
+ wfi(ARM) instruction doesn't work correctly and not to
+ use it. This is also useful when using JTAG debugger.
no-hlt [BUGS=X86-32] Tells the kernel that the hlt
instruction doesn't work correctly and not to
@@ -1544,6 +1520,8 @@ and is between 256 and 4096 characters. It is defined in the file
Valid arguments: on, off
Default: on
+ noiotrap [SH] Disables trapped I/O port accesses.
+
noirqdebug [X86-32] Disables the code which attempts to detect and
disable unhandled interrupt sources.
@@ -1563,12 +1541,6 @@ and is between 256 and 4096 characters. It is defined in the file
nolapic_timer [X86-32,APIC] Do not use the local APIC timer.
- nox2apic [X86-64,APIC] Do not enable x2APIC mode.
-
- x2apic_phys [X86-64,APIC] Use x2apic physical mode instead of
- default x2apic cluster mode on platforms
- supporting x2apic.
-
noltlbs [PPC] Do not use large page/tlb entries for kernel
lowmem mapping on PPC40x.
@@ -1579,6 +1551,9 @@ and is between 256 and 4096 characters. It is defined in the file
nomfgpt [X86-32] Disable Multi-Function General Purpose
Timer usage (for AMD Geode machines).
+ norandmaps Don't use address space randomization. Equivalent to
+ echo 0 > /proc/sys/kernel/randomize_va_space
+
noreplace-paravirt [X86-32,PV_OPS] Don't patch paravirt_ops
noreplace-smp [X86-32,SMP] Don't replace SMP instructions
@@ -1603,7 +1578,7 @@ and is between 256 and 4096 characters. It is defined in the file
nosoftlockup [KNL] Disable the soft-lockup detector.
noswapaccount [KNL] Disable accounting of swap in memory resource
- controller. (See Documentation/controllers/memory.txt)
+ controller. (See Documentation/cgroups/memory.txt)
nosync [HW,M68K] Disables sync negotiation for all devices.
@@ -1617,13 +1592,13 @@ and is between 256 and 4096 characters. It is defined in the file
purges which is reported from either PAL_VM_SUMMARY or
SAL PALO.
+ nr_uarts= [SERIAL] maximum number of UARTs to be registered.
+
numa_zonelist_order= [KNL, BOOT] Select zonelist order for NUMA.
one of ['zone', 'node', 'default'] can be specified
This can be set from sysctl after boot.
See Documentation/sysctl/vm.txt for details.
- nr_uarts= [SERIAL] maximum number of UARTs to be registered.
-
ohci1394_dma=early [HW] enable debugging via the ohci1394 driver.
See Documentation/debugging-via-ohci1394.txt for more
info.
@@ -1872,6 +1847,14 @@ and is between 256 and 4096 characters. It is defined in the file
printk.time= Show timing data prefixed to each printk message line
Format: <bool> (1/Y/y=enable, 0/N/n=disable)
+ processor.max_cstate= [HW,ACPI]
+ Limit processor to maximum C-state
+ max_cstate=9 overrides any DMI blacklist limit.
+
+ processor.nocst [HW,ACPI]
+ Ignore the _CST method to determine C-states,
+ instead using the legacy FADT method
+
profile= [KNL] Enable kernel profiling via /proc/profile
Format: [schedule,]<number>
Param: "schedule" - profile schedule points.
@@ -1881,14 +1864,6 @@ and is between 256 and 4096 characters. It is defined in the file
Requires CONFIG_SCHEDSTATS
Param: "kvm" - profile VM exits.
- processor.max_cstate= [HW,ACPI]
- Limit processor to maximum C-state
- max_cstate=9 overrides any DMI blacklist limit.
-
- processor.nocst [HW,ACPI]
- Ignore the _CST method to determine C-states,
- instead using the legacy FADT method
-
prompt_ramdisk= [RAM] List of RAM disks to prompt for floppy disk
before loading.
See Documentation/blockdev/ramdisk.txt.
@@ -1953,7 +1928,7 @@ and is between 256 and 4096 characters. It is defined in the file
relax_domain_level=
[KNL, SMP] Set scheduler's default relax_domain_level.
- See Documentation/cpusets.txt.
+ See Documentation/cgroups/cpusets.txt.
reserve= [KNL,BUGS] Force the kernel to ignore some iomem area
@@ -2042,7 +2017,13 @@ and is between 256 and 4096 characters. It is defined in the file
allowing boot to proceed. none ignores them, expecting
user space to do the scan.
- selinux [SELINUX] Disable or enable SELinux at boot time.
+ security= [SECURITY] Choose a security module to enable at boot.
+ If this boot parameter is not specified, only the first
+ security module asking for security registration will be
+ loaded. An invalid security module name will be treated
+ as if no module has been chosen.
+
+ selinux= [SELINUX] Disable or enable SELinux at boot time.
Format: { "0" | "1" }
See security/selinux/Kconfig help text.
0 -- disable.
@@ -2362,6 +2343,8 @@ and is between 256 and 4096 characters. It is defined in the file
tp720= [HW,PS2]
+ trace_buf_size=nn[KMG] [ftrace] will set tracing buffer size.
+
trix= [HW,OSS] MediaTrix AudioTrix Pro
Format:
<io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq>
@@ -2464,9 +2447,6 @@ and is between 256 and 4096 characters. It is defined in the file
medium is write-protected).
Example: quirks=0419:aaf5:rl,0421:0433:rc
- add_efi_memmap [EFI; x86-32,X86-64] Include EFI memory map in
- kernel's map of available physical RAM.
-
vdso= [X86-32,SH,x86-64]
vdso=2: enable compat VDSO (default with COMPAT_VDSO)
vdso=1: enable VDSO (default)
@@ -2505,6 +2485,31 @@ and is between 256 and 4096 characters. It is defined in the file
vmpoff= [KNL,S390] Perform z/VM CP command after power off.
Format: <command>
+ vt.default_blu= [VT]
+ Format: <blue0>,<blue1>,<blue2>,...,<blue15>
+ Change the default blue palette of the console.
+ This is a 16-member array composed of values
+ ranging from 0-255.
+
+ vt.default_grn= [VT]
+ Format: <green0>,<green1>,<green2>,...,<green15>
+ Change the default green palette of the console.
+ This is a 16-member array composed of values
+ ranging from 0-255.
+
+ vt.default_red= [VT]
+ Format: <red0>,<red1>,<red2>,...,<red15>
+ Change the default red palette of the console.
+ This is a 16-member array composed of values
+ ranging from 0-255.
+
+ vt.default_utf8=
+ [VT]
+ Format=<0|1>
+ Set system-wide default UTF-8 mode for all tty's.
+ Default is 1, i.e. UTF-8 mode is enabled for all
+ newly opened terminals.
+
waveartist= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>
@@ -2517,6 +2522,10 @@ and is between 256 and 4096 characters. It is defined in the file
wdt= [WDT] Watchdog
See Documentation/watchdog/wdt.txt.
+ x2apic_phys [X86-64,APIC] Use x2apic physical mode instead of
+ default x2apic cluster mode on platforms
+ supporting x2apic.
+
xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks.
xd_geo= See header of drivers/block/xd.c.
@@ -2524,9 +2533,6 @@ and is between 256 and 4096 characters. It is defined in the file
Format:
<irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
- norandmaps Don't use address space randomization. Equivalent to
- echo 0 > /proc/sys/kernel/randomize_va_space
-
______________________________________________________________________
TODO:
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 48b3de90eb1..1e7a769a10f 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -212,7 +212,9 @@ hit, Kprobes calls kp->pre_handler. After the probed instruction
is single-stepped, Kprobe calls kp->post_handler. If a fault
occurs during execution of kp->pre_handler or kp->post_handler,
or during single-stepping of the probed instruction, Kprobes calls
-kp->fault_handler. Any or all handlers can be NULL.
+kp->fault_handler. Any or all handlers can be NULL. If kp->flags
+is set KPROBE_FLAG_DISABLED, that kp will be registered but disabled,
+so, it's handlers aren't hit until calling enable_kprobe(kp).
NOTE:
1. With the introduction of the "symbol_name" field to struct kprobe,
@@ -363,6 +365,26 @@ probes) in the specified array, they clear the addr field of those
incorrect probes. However, other probes in the array are
unregistered correctly.
+4.7 disable_*probe
+
+#include <linux/kprobes.h>
+int disable_kprobe(struct kprobe *kp);
+int disable_kretprobe(struct kretprobe *rp);
+int disable_jprobe(struct jprobe *jp);
+
+Temporarily disables the specified *probe. You can enable it again by using
+enable_*probe(). You must specify the probe which has been registered.
+
+4.8 enable_*probe
+
+#include <linux/kprobes.h>
+int enable_kprobe(struct kprobe *kp);
+int enable_kretprobe(struct kretprobe *rp);
+int enable_jprobe(struct jprobe *jp);
+
+Enables *probe which has been disabled by disable_*probe(). You must specify
+the probe which has been registered.
+
5. Kprobes Features and Limitations
Kprobes allows multiple probes at the same address. Currently,
@@ -500,10 +522,14 @@ the probe. If the probed function belongs to a module, the module name
is also specified. Following columns show probe status. If the probe is on
a virtual address that is no longer valid (module init sections, module
virtual addresses that correspond to modules that've been unloaded),
-such probes are marked with [GONE].
+such probes are marked with [GONE]. If the probe is temporarily disabled,
+such probes are marked with [DISABLED].
-/debug/kprobes/enabled: Turn kprobes ON/OFF
+/debug/kprobes/enabled: Turn kprobes ON/OFF forcibly.
-Provides a knob to globally turn registered kprobes ON or OFF. By default,
-all kprobes are enabled. By echoing "0" to this file, all registered probes
-will be disarmed, till such time a "1" is echoed to this file.
+Provides a knob to globally and forcibly turn registered kprobes ON or OFF.
+By default, all kprobes are enabled. By echoing "0" to this file, all
+registered probes will be disarmed, till such time a "1" is echoed to this
+file. Note that this knob just disarms and arms all kprobes and doesn't
+change each probe's disabling state. This means that disabled kprobes (marked
+[DISABLED]) will be not enabled if you turn ON all kprobes by this knob.
diff --git a/Documentation/laptops/acer-wmi.txt b/Documentation/laptops/acer-wmi.txt
index 2b3a6b5260b..5ee2a02b3b4 100644
--- a/Documentation/laptops/acer-wmi.txt
+++ b/Documentation/laptops/acer-wmi.txt
@@ -1,9 +1,9 @@
Acer Laptop WMI Extras Driver
http://code.google.com/p/aceracpi
-Version 0.2
-18th August 2008
+Version 0.3
+4th April 2009
-Copyright 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
+Copyright 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk>
acer-wmi is a driver to allow you to control various parts of your Acer laptop
hardware under Linux which are exposed via ACPI-WMI.
@@ -36,6 +36,10 @@ not possible in kernel space from a 64 bit OS.
Supported Hardware
******************
+NOTE: The Acer Aspire One is not supported hardware. It cannot work with
+acer-wmi until Acer fix their ACPI-WMI implementation on them, so has been
+blacklisted until that happens.
+
Please see the website for the current list of known working hardare:
http://code.google.com/p/aceracpi/wiki/SupportedHardware
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 41bc99fa188..3d7650768bb 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -20,7 +20,8 @@ moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel
kernel 2.6.29 and release 0.22.
The driver is named "thinkpad-acpi". In some places, like module
-names, "thinkpad_acpi" is used because of userspace issues.
+names and log messages, "thinkpad_acpi" is used because of userspace
+issues.
"tpacpi" is used as a shorthand where "thinkpad-acpi" would be too
long due to length limitations on some Linux kernel versions.
@@ -37,7 +38,7 @@ detailed description):
- ThinkLight on and off
- limited docking and undocking
- UltraBay eject
- - CMOS control
+ - CMOS/UCMS control
- LED control
- ACPI sounds
- temperature sensors
@@ -46,6 +47,7 @@ detailed description):
- Volume control
- Fan control and monitoring: fan speed, fan enable/disable
- WAN enable and disable
+ - UWB enable and disable
A compatibility table by model and feature is maintained on the web
site, http://ibm-acpi.sf.net/. I appreciate any success or failure
@@ -53,7 +55,7 @@ reports, especially if they add to or correct the compatibility table.
Please include the following information in your report:
- ThinkPad model name
- - a copy of your DSDT, from /proc/acpi/dsdt
+ - a copy of your ACPI tables, using the "acpidump" utility
- a copy of the output of dmidecode, with serial numbers
and UUIDs masked off
- which driver features work and which don't
@@ -66,17 +68,18 @@ Installation
------------
If you are compiling this driver as included in the Linux kernel
-sources, simply enable the CONFIG_THINKPAD_ACPI option, and optionally
-enable the CONFIG_THINKPAD_ACPI_BAY option if you want the
-thinkpad-specific bay functionality.
+sources, look for the CONFIG_THINKPAD_ACPI Kconfig option.
+It is located on the menu path: "Device Drivers" -> "X86 Platform
+Specific Device Drivers" -> "ThinkPad ACPI Laptop Extras".
+
Features
--------
The driver exports two different interfaces to userspace, which can be
used to access the features it provides. One is a legacy procfs-based
-interface, which will be removed at some time in the distant future.
-The other is a new sysfs-based interface which is not complete yet.
+interface, which will be removed at some time in the future. The other
+is a new sysfs-based interface which is not complete yet.
The procfs interface creates the /proc/acpi/ibm directory. There is a
file under that directory for each feature it supports. The procfs
@@ -111,15 +114,17 @@ The version of thinkpad-acpi's sysfs interface is exported by the driver
as a driver attribute (see below).
Sysfs driver attributes are on the driver's sysfs attribute space,
-for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and
+for 2.6.23+ this is /sys/bus/platform/drivers/thinkpad_acpi/ and
/sys/bus/platform/drivers/thinkpad_hwmon/
Sysfs device attributes are on the thinkpad_acpi device sysfs attribute
-space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/.
+space, for 2.6.23+ this is /sys/devices/platform/thinkpad_acpi/.
Sysfs device attributes for the sensors and fan are on the
thinkpad_hwmon device's sysfs attribute space, but you should locate it
-looking for a hwmon device with the name attribute of "thinkpad".
+looking for a hwmon device with the name attribute of "thinkpad", or
+better yet, through libsensors.
+
Driver version
--------------
@@ -129,6 +134,7 @@ sysfs driver attribute: version
The driver name and version. No commands can be written to this file.
+
Sysfs interface version
-----------------------
@@ -160,6 +166,7 @@ expect that an attribute might not be there, and deal with it properly
(an attribute not being there *is* a valid way to make it clear that a
feature is not available in sysfs).
+
Hot keys
--------
@@ -172,17 +179,14 @@ system. Enabling the hotkey functionality of thinkpad-acpi signals the
firmware that such a driver is present, and modifies how the ThinkPad
firmware will behave in many situations.
-The driver enables the hot key feature automatically when loaded. The
-feature can later be disabled and enabled back at runtime. The driver
-will also restore the hot key feature to its previous state and mask
-when it is unloaded.
+The driver enables the HKEY ("hot key") event reporting automatically
+when loaded, and disables it when it is removed.
-When the hotkey feature is enabled and the hot key mask is set (see
-below), the driver will report HKEY events in the following format:
+The driver will report HKEY events in the following format:
ibm/hotkey HKEY 00000080 0000xxxx
-Some of these events refer to hot key presses, but not all.
+Some of these events refer to hot key presses, but not all of them.
The driver will generate events over the input layer for hot keys and
radio switches, and over the ACPI netlink layer for other events. The
@@ -214,13 +218,17 @@ procfs notes:
The following commands can be written to the /proc/acpi/ibm/hotkey file:
- echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
- echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys
echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
... any other 8-hex-digit mask ...
echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
+The following commands have been deprecated and will cause the kernel
+to log a warning:
+
+ echo enable > /proc/acpi/ibm/hotkey -- does nothing
+ echo disable > /proc/acpi/ibm/hotkey -- returns an error
+
The procfs interface does not support NVRAM polling control. So as to
maintain maximum bug-to-bug compatibility, it does not report any masks,
nor does it allow one to manipulate the hot key mask when the firmware
@@ -229,12 +237,9 @@ does not support masks at all, even if NVRAM polling is in use.
sysfs notes:
hotkey_bios_enabled:
- Returns the status of the hot keys feature when
- thinkpad-acpi was loaded. Upon module unload, the hot
- key feature status will be restored to this value.
+ DEPRECATED, WILL BE REMOVED SOON.
- 0: hot keys were disabled
- 1: hot keys were enabled (unusual)
+ Returns 0.
hotkey_bios_mask:
Returns the hot keys mask when thinkpad-acpi was loaded.
@@ -242,13 +247,10 @@ sysfs notes:
to this value.
hotkey_enable:
- Enables/disables the hot keys feature in the ACPI
- firmware, and reports current status of the hot keys
- feature. Has no effect on the NVRAM hot key polling
- functionality.
+ DEPRECATED, WILL BE REMOVED SOON.
- 0: disables the hot keys feature / feature disabled
- 1: enables the hot keys feature / feature enabled
+ 0: returns -EPERM
+ 1: does nothing
hotkey_mask:
bit mask to enable driver-handling (and depending on
@@ -618,6 +620,7 @@ For Lenovo models *with* ACPI backlight control:
and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process
these keys on userspace somehow (e.g. by calling xbacklight).
+
Bluetooth
---------
@@ -628,6 +631,9 @@ sysfs rfkill class: switch "tpacpi_bluetooth_sw"
This feature shows the presence and current state of a ThinkPad
Bluetooth device in the internal ThinkPad CDC slot.
+If the ThinkPad supports it, the Bluetooth state is stored in NVRAM,
+so it is kept across reboots and power-off.
+
Procfs notes:
If Bluetooth is installed, the following commands can be used:
@@ -652,6 +658,7 @@ Sysfs notes:
rfkill controller switch "tpacpi_bluetooth_sw": refer to
Documentation/rfkill.txt for details.
+
Video output control -- /proc/acpi/ibm/video
--------------------------------------------
@@ -693,11 +700,8 @@ Fn-F7 from working. This also disables the video output switching
features of this driver, as it uses the same ACPI methods as
Fn-F7. Video switching on the console should still work.
-UPDATE: There's now a patch for the X.org Radeon driver which
-addresses this issue. Some people are reporting success with the patch
-while others are still having problems. For more information:
+UPDATE: refer to https://bugs.freedesktop.org/show_bug.cgi?id=2000
-https://bugs.freedesktop.org/show_bug.cgi?id=2000
ThinkLight control
------------------
@@ -720,10 +724,11 @@ The ThinkLight sysfs interface is documented by the LED class
documentation, in Documentation/leds-class.txt. The ThinkLight LED name
is "tpacpi::thinklight".
-Due to limitations in the sysfs LED class, if the status of the thinklight
+Due to limitations in the sysfs LED class, if the status of the ThinkLight
cannot be read or if it is unknown, thinkpad-acpi will report it as "off".
It is impossible to know if the status returned through sysfs is valid.
+
Docking / undocking -- /proc/acpi/ibm/dock
------------------------------------------
@@ -784,6 +789,7 @@ the only docking stations currently supported are the X-series
UltraBase docks and "dumb" port replicators like the Mini Dock (the
latter don't need any ACPI support, actually).
+
UltraBay eject -- /proc/acpi/ibm/bay
------------------------------------
@@ -847,8 +853,9 @@ supported. Use "eject2" instead of "eject" for the second bay.
Note: the UltraBay eject support on the 600e/x, A22p and A3x is
EXPERIMENTAL and may not work as expected. USE WITH CAUTION!
-CMOS control
-------------
+
+CMOS/UCMS control
+-----------------
procfs: /proc/acpi/ibm/cmos
sysfs device attribute: cmos_command
@@ -882,6 +889,7 @@ The cmos command interface is prone to firmware split-brain problems, as
in newer ThinkPads it is just a compatibility layer. Do not use it, it is
exported just as a debug tool.
+
LED control
-----------
@@ -893,6 +901,17 @@ some older ThinkPad models, it is possible to query the status of the
LED indicators as well. Newer ThinkPads cannot query the real status
of the LED indicators.
+Because misuse of the LEDs could induce an unaware user to perform
+dangerous actions (like undocking or ejecting a bay device while the
+buses are still active), or mask an important alarm (such as a nearly
+empty battery, or a broken battery), access to most LEDs is
+restricted.
+
+Unrestricted access to all LEDs requires that thinkpad-acpi be
+compiled with the CONFIG_THINKPAD_ACPI_UNSAFE_LEDS option enabled.
+Distributions must never enable this option. Individual users that
+are aware of the consequences are welcome to enabling it.
+
procfs notes:
The available commands are:
@@ -939,6 +958,7 @@ ThinkPad indicator LED should blink in hardware accelerated mode, use the
"timer" trigger, and leave the delay_on and delay_off parameters set to
zero (to request hardware acceleration autodetection).
+
ACPI sounds -- /proc/acpi/ibm/beep
----------------------------------
@@ -968,6 +988,7 @@ X40:
16 - one medium-pitched beep repeating constantly, stop with 17
17 - stop 16
+
Temperature sensors
-------------------
@@ -1115,6 +1136,7 @@ registers contain the current battery capacity, etc. If you experiment
with this, do send me your results (including some complete dumps with
a description of the conditions when they were taken.)
+
LCD brightness control
----------------------
@@ -1124,10 +1146,9 @@ sysfs backlight device "thinkpad_screen"
This feature allows software control of the LCD brightness on ThinkPad
models which don't have a hardware brightness slider.
-It has some limitations: the LCD backlight cannot be actually turned on or
-off by this interface, and in many ThinkPad models, the "dim while on
-battery" functionality will be enabled by the BIOS when this interface is
-used, and cannot be controlled.
+It has some limitations: the LCD backlight cannot be actually turned
+on or off by this interface, it just controls the backlight brightness
+level.
On IBM (and some of the earlier Lenovo) ThinkPads, the backlight control
has eight brightness levels, ranging from 0 to 7. Some of the levels
@@ -1136,10 +1157,15 @@ display backlight brightness control methods have 16 levels, ranging
from 0 to 15.
There are two interfaces to the firmware for direct brightness control,
-EC and CMOS. To select which one should be used, use the
+EC and UCMS (or CMOS). To select which one should be used, use the
brightness_mode module parameter: brightness_mode=1 selects EC mode,
-brightness_mode=2 selects CMOS mode, brightness_mode=3 selects both EC
-and CMOS. The driver tries to auto-detect which interface to use.
+brightness_mode=2 selects UCMS mode, brightness_mode=3 selects EC
+mode with NVRAM backing (so that brightness changes are remembered
+across shutdown/reboot).
+
+The driver tries to select which interface to use from a table of
+defaults for each ThinkPad model. If it makes a wrong choice, please
+report this as a bug, so that we can fix it.
When display backlight brightness controls are available through the
standard ACPI interface, it is best to use it instead of this direct
@@ -1201,6 +1227,7 @@ WARNING:
and maybe reduce the life of the backlight lamps by needlessly kicking
its level up and down at every change.
+
Volume control -- /proc/acpi/ibm/volume
---------------------------------------
@@ -1217,6 +1244,11 @@ distinct. The unmute the volume after the mute command, use either the
up or down command (the level command will not unmute the volume).
The current volume level and mute state is shown in the file.
+The ALSA mixer interface to this feature is still missing, but patches
+to add it exist. That problem should be addressed in the not so
+distant future.
+
+
Fan control and monitoring: fan speed, fan enable/disable
---------------------------------------------------------
@@ -1383,8 +1415,11 @@ procfs: /proc/acpi/ibm/wan
sysfs device attribute: wwan_enable (deprecated)
sysfs rfkill class: switch "tpacpi_wwan_sw"
-This feature shows the presence and current state of a W-WAN (Sierra
-Wireless EV-DO) device.
+This feature shows the presence and current state of the built-in
+Wireless WAN device.
+
+If the ThinkPad supports it, the WWAN state is stored in NVRAM,
+so it is kept across reboots and power-off.
It was tested on a Lenovo ThinkPad X60. It should probably work on other
ThinkPad models which come with this module installed.
@@ -1413,6 +1448,7 @@ Sysfs notes:
rfkill controller switch "tpacpi_wwan_sw": refer to
Documentation/rfkill.txt for details.
+
EXPERIMENTAL: UWB
-----------------
@@ -1431,6 +1467,7 @@ Sysfs notes:
rfkill controller switch "tpacpi_uwb_sw": refer to
Documentation/rfkill.txt for details.
+
Multiple Commands, Module Parameters
------------------------------------
@@ -1445,6 +1482,7 @@ for example:
modprobe thinkpad_acpi hotkey=enable,0xffff video=auto_disable
+
Enabling debugging output
-------------------------
@@ -1457,8 +1495,15 @@ will enable all debugging output classes. It takes a bitmask, so
to enable more than one output class, just add their values.
Debug bitmask Description
+ 0x8000 Disclose PID of userspace programs
+ accessing some functions of the driver
0x0001 Initialization and probing
0x0002 Removal
+ 0x0004 RF Transmitter control (RFKILL)
+ (bluetooth, WWAN, UWB...)
+ 0x0008 HKEY event interface, hotkeys
+ 0x0010 Fan control
+ 0x0020 Backlight brightness
There is also a kernel build option to enable more debugging
information, which may be necessary to debug driver problems.
@@ -1467,6 +1512,7 @@ The level of debugging information output by the driver can be changed
at runtime through sysfs, using the driver attribute debug_level. The
attribute takes the same bitmask as the debug module parameter above.
+
Force loading of module
-----------------------
@@ -1505,3 +1551,7 @@ Sysfs interface changelog:
0x020200: Add poll()/select() support to the following attributes:
hotkey_radio_sw, wakeup_hotunplug_complete, wakeup_reason
+
+0x020300: hotkey enable/disable support removed, attributes
+ hotkey_bios_enabled and hotkey_enable deprecated and
+ marked for removal.
diff --git a/Documentation/md.txt b/Documentation/md.txt
index 1da9d1b1793..4edd39ec7db 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -164,15 +164,19 @@ All md devices contain:
raid_disks
a text file with a simple number indicating the number of devices
in a fully functional array. If this is not yet known, the file
- will be empty. If an array is being resized (not currently
- possible) this will contain the larger of the old and new sizes.
- Some raid level (RAID1) allow this value to be set while the
- array is active. This will reconfigure the array. Otherwise
- it can only be set while assembling an array.
+ will be empty. If an array is being resized this will contain
+ the new number of devices.
+ Some raid levels allow this value to be set while the array is
+ active. This will reconfigure the array. Otherwise it can only
+ be set while assembling an array.
+ A change to this attribute will not be permitted if it would
+ reduce the size of the array. To reduce the number of drives
+ in an e.g. raid5, the array size must first be reduced by
+ setting the 'array_size' attribute.
chunk_size
- This is the size if bytes for 'chunks' and is only relevant to
- raid levels that involve striping (1,4,5,6,10). The address space
+ This is the size in bytes for 'chunks' and is only relevant to
+ raid levels that involve striping (0,4,5,6,10). The address space
of the array is conceptually divided into chunks and consecutive
chunks are striped onto neighbouring devices.
The size should be at least PAGE_SIZE (4k) and should be a power
@@ -183,6 +187,20 @@ All md devices contain:
simply a number that is interpretted differently by different
levels. It can be written while assembling an array.
+ array_size
+ This can be used to artificially constrain the available space in
+ the array to be less than is actually available on the combined
+ devices. Writing a number (in Kilobytes) which is less than
+ the available size will set the size. Any reconfiguration of the
+ array (e.g. adding devices) will not cause the size to change.
+ Writing the word 'default' will cause the effective size of the
+ array to be whatever size is actually available based on
+ 'level', 'chunk_size' and 'component_size'.
+
+ This can be used to reduce the size of the array before reducing
+ the number of devices in a raid4/5/6, or to support external
+ metadata formats which mandate such clipping.
+
reshape_position
This is either "none" or a sector number within the devices of
the array where "reshape" is up to. If this is set, the three
@@ -207,6 +225,11 @@ All md devices contain:
about the array. It can be 0.90 (traditional format), 1.0, 1.1,
1.2 (newer format in varying locations) or "none" indicating that
the kernel isn't managing metadata at all.
+ Alternately it can be "external:" followed by a string which
+ is set by user-space. This indicates that metadata is managed
+ by a user-space program. Any device failure or other event that
+ requires a metadata update will cause array activity to be
+ suspended until the event is acknowledged.
resync_start
The point at which resync should start. If no resync is needed,
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt
index 6c238f59b2a..249db3a15d1 100644
--- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt
@@ -1,6 +1,6 @@
* Uploaded QE firmware
- If a new firwmare has been uploaded to the QE (usually by the
+ If a new firmware has been uploaded to the QE (usually by the
boot loader), then a 'firmware' child node should be added to the QE
node. This node provides information on the uploaded firmware that
device drivers may need.
diff --git a/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt b/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt
index 84a04d5eb8e..a48b2cadc7f 100644
--- a/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt
@@ -5,9 +5,21 @@ Required properties:
- reg : should specify localbus chip select and size used for the chip.
- fsl,upm-addr-offset : UPM pattern offset for the address latch.
- fsl,upm-cmd-offset : UPM pattern offset for the command latch.
-- gpios : may specify optional GPIO connected to the Ready-Not-Busy pin.
-Example:
+Optional properties:
+- fsl,upm-wait-flags : add chip-dependent short delays after running the
+ UPM pattern (0x1), after writing a data byte (0x2) or after
+ writing out a buffer (0x4).
+- fsl,upm-addr-line-cs-offsets : address offsets for multi-chip support.
+ The corresponding address lines are used to select the chip.
+- gpios : may specify optional GPIOs connected to the Ready-Not-Busy pins
+ (R/B#). For multi-chip devices, "n" GPIO definitions are required
+ according to the number of chips.
+- chip-delay : chip dependent delay for transfering data from array to
+ read registers (tR). Required if property "gpios" is not used
+ (R/B# pins not connected).
+
+Examples:
upm@1,0 {
compatible = "fsl,upm-nand";
@@ -26,3 +38,26 @@ upm@1,0 {
};
};
};
+
+upm@3,0 {
+ #address-cells = <0>;
+ #size-cells = <0>;
+ compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
+ reg = <3 0x0 0x800>;
+ fsl,upm-addr-offset = <0x10>;
+ fsl,upm-cmd-offset = <0x08>;
+ /* Multi-chip NAND device */
+ fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
+ fsl,upm-wait-flags = <0x5>;
+ chip-delay = <25>; // in micro-seconds
+
+ nand@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "fs";
+ reg = <0x00000000 0x10000000>;
+ };
+ };
+};
diff --git a/Documentation/powerpc/dts-bindings/gpio/led.txt b/Documentation/powerpc/dts-bindings/gpio/led.txt
index ff51f4c0fa9..4fe14deedc0 100644
--- a/Documentation/powerpc/dts-bindings/gpio/led.txt
+++ b/Documentation/powerpc/dts-bindings/gpio/led.txt
@@ -1,15 +1,43 @@
-LED connected to GPIO
+LEDs connected to GPIO lines
Required properties:
-- compatible : should be "gpio-led".
-- label : (optional) the label for this LED. If omitted, the label is
+- compatible : should be "gpio-leds".
+
+Each LED is represented as a sub-node of the gpio-leds device. Each
+node's name represents the name of the corresponding LED.
+
+LED sub-node properties:
+- gpios : Should specify the LED's GPIO, see "Specifying GPIO information
+ for devices" in Documentation/powerpc/booting-without-of.txt. Active
+ low LEDs should be indicated using flags in the GPIO specifier.
+- label : (optional) The label for this LED. If omitted, the label is
taken from the node name (excluding the unit address).
-- gpios : should specify LED GPIO.
+- linux,default-trigger : (optional) This parameter, if present, is a
+ string defining the trigger assigned to the LED. Current triggers are:
+ "backlight" - LED will act as a back-light, controlled by the framebuffer
+ system
+ "default-on" - LED will turn on
+ "heartbeat" - LED "double" flashes at a load average based rate
+ "ide-disk" - LED indicates disk activity
+ "timer" - LED flashes at a fixed, configurable rate
-Example:
+Examples:
-led@0 {
- compatible = "gpio-led";
- label = "hdd";
- gpios = <&mcu_pio 0 1>;
+leds {
+ compatible = "gpio-leds";
+ hdd {
+ label = "IDE Activity";
+ gpios = <&mcu_pio 0 1>; /* Active low */
+ linux,default-trigger = "ide-disk";
+ };
};
+
+run-control {
+ compatible = "gpio-leds";
+ red {
+ gpios = <&mpc8572 6 0>;
+ };
+ green {
+ gpios = <&mpc8572 7 0>;
+ };
+}
diff --git a/Documentation/scheduler/sched-rt-group.txt b/Documentation/scheduler/sched-rt-group.txt
index 3ef339f491e..5ba4d3fc625 100644
--- a/Documentation/scheduler/sched-rt-group.txt
+++ b/Documentation/scheduler/sched-rt-group.txt
@@ -126,7 +126,7 @@ This uses the /cgroup virtual file system and "/cgroup/<cgroup>/cpu.rt_runtime_u
to control the CPU time reserved for each control group instead.
For more information on working with control groups, you should read
-Documentation/cgroups.txt as well.
+Documentation/cgroups/cgroups.txt as well.
Group settings are checked against the following limits in order to keep the configuration
schedulable:
diff --git a/Documentation/scsi/aacraid.txt b/Documentation/scsi/aacraid.txt
index ddace3afc83..30f643f611b 100644
--- a/Documentation/scsi/aacraid.txt
+++ b/Documentation/scsi/aacraid.txt
@@ -60,17 +60,9 @@ Supported Cards/Chipsets
9005:0285:9005:02d5 Adaptec ASR-2405 (Voodoo40 Lite)
9005:0285:9005:02d6 Adaptec ASR-2445 (Voodoo44 Lite)
9005:0285:9005:02d7 Adaptec ASR-2805 (Voodoo80 Lite)
- 9005:0285:9005:02d8 Adaptec 5405G (Voodoo40 PM)
- 9005:0285:9005:02d9 Adaptec 5445G (Voodoo44 PM)
- 9005:0285:9005:02da Adaptec 5805G (Voodoo80 PM)
- 9005:0285:9005:02db Adaptec 5085G (Voodoo08 PM)
- 9005:0285:9005:02dc Adaptec 51245G (Voodoo124 PM)
- 9005:0285:9005:02dd Adaptec 51645G (Voodoo164 PM)
- 9005:0285:9005:02de Adaptec 52445G (Voodoo244 PM)
- 9005:0285:9005:02df Adaptec ASR-2045G (Voodoo04 Lite PM)
- 9005:0285:9005:02e0 Adaptec ASR-2405G (Voodoo40 Lite PM)
- 9005:0285:9005:02e1 Adaptec ASR-2445G (Voodoo44 Lite PM)
- 9005:0285:9005:02e2 Adaptec ASR-2805G (Voodoo80 Lite PM)
+ 9005:0285:9005:02d8 Adaptec 5405Z (Voodoo40 BLBU)
+ 9005:0285:9005:02d9 Adaptec 5445Z (Voodoo44 BLBU)
+ 9005:0285:9005:02da Adaptec 5805Z (Voodoo80 BLBU)
1011:0046:9005:0364 Adaptec 5400S (Mustang)
1011:0046:9005:0365 Adaptec 5400S (Mustang)
9005:0287:9005:0800 Adaptec Themisto (Jupiter)
@@ -140,6 +132,7 @@ Deanna Bonds (non-DASD support, PAE fibs and 64 bit,
where fibs that go to the hardware are consistently called hw_fibs and
not just fibs like the name of the driver tracking structure)
Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas. Performance tuning, card failover and bug mitigations.
+Achim Leubner <Achim_Leubner@adaptec.com>
Original Driver
-------------------------
diff --git a/Documentation/slow-work.txt b/Documentation/slow-work.txt
new file mode 100644
index 00000000000..ebc50f808ea
--- /dev/null
+++ b/Documentation/slow-work.txt
@@ -0,0 +1,174 @@
+ ====================================
+ SLOW WORK ITEM EXECUTION THREAD POOL
+ ====================================
+
+By: David Howells <dhowells@redhat.com>
+
+The slow work item execution thread pool is a pool of threads for performing
+things that take a relatively long time, such as making mkdir calls.
+Typically, when processing something, these items will spend a lot of time
+blocking a thread on I/O, thus making that thread unavailable for doing other
+work.
+
+The standard workqueue model is unsuitable for this class of work item as that
+limits the owner to a single thread or a single thread per CPU. For some
+tasks, however, more threads - or fewer - are required.
+
+There is just one pool per system. It contains no threads unless something
+wants to use it - and that something must register its interest first. When
+the pool is active, the number of threads it contains is dynamic, varying
+between a maximum and minimum setting, depending on the load.
+
+
+====================
+CLASSES OF WORK ITEM
+====================
+
+This pool support two classes of work items:
+
+ (*) Slow work items.
+
+ (*) Very slow work items.
+
+The former are expected to finish much quicker than the latter.
+
+An operation of the very slow class may do a batch combination of several
+lookups, mkdirs, and a create for instance.
+
+An operation of the ordinarily slow class may, for example, write stuff or
+expand files, provided the time taken to do so isn't too long.
+
+Operations of both types may sleep during execution, thus tying up the thread
+loaned to it.
+
+
+THREAD-TO-CLASS ALLOCATION
+--------------------------
+
+Not all the threads in the pool are available to work on very slow work items.
+The number will be between one and one fewer than the number of active threads.
+This is configurable (see the "Pool Configuration" section).
+
+All the threads are available to work on ordinarily slow work items, but a
+percentage of the threads will prefer to work on very slow work items.
+
+The configuration ensures that at least one thread will be available to work on
+very slow work items, and at least one thread will be available that won't work
+on very slow work items at all.
+
+
+=====================
+USING SLOW WORK ITEMS
+=====================
+
+Firstly, a module or subsystem wanting to make use of slow work items must
+register its interest:
+
+ int ret = slow_work_register_user();
+
+This will return 0 if successful, or a -ve error upon failure.
+
+
+Slow work items may then be set up by:
+
+ (1) Declaring a slow_work struct type variable:
+
+ #include <linux/slow-work.h>
+
+ struct slow_work myitem;
+
+ (2) Declaring the operations to be used for this item:
+
+ struct slow_work_ops myitem_ops = {
+ .get_ref = myitem_get_ref,
+ .put_ref = myitem_put_ref,
+ .execute = myitem_execute,
+ };
+
+ [*] For a description of the ops, see section "Item Operations".
+
+ (3) Initialising the item:
+
+ slow_work_init(&myitem, &myitem_ops);
+
+ or:
+
+ vslow_work_init(&myitem, &myitem_ops);
+
+ depending on its class.
+
+A suitably set up work item can then be enqueued for processing:
+
+ int ret = slow_work_enqueue(&myitem);
+
+This will return a -ve error if the thread pool is unable to gain a reference
+on the item, 0 otherwise.
+
+
+The items are reference counted, so there ought to be no need for a flush
+operation. When all a module's slow work items have been processed, and the
+module has no further interest in the facility, it should unregister its
+interest:
+
+ slow_work_unregister_user();
+
+
+===============
+ITEM OPERATIONS
+===============
+
+Each work item requires a table of operations of type struct slow_work_ops.
+All members are required:
+
+ (*) Get a reference on an item:
+
+ int (*get_ref)(struct slow_work *work);
+
+ This allows the thread pool to attempt to pin an item by getting a
+ reference on it. This function should return 0 if the reference was
+ granted, or a -ve error otherwise. If an error is returned,
+ slow_work_enqueue() will fail.
+
+ The reference is held whilst the item is queued and whilst it is being
+ executed. The item may then be requeued with the same reference held, or
+ the reference will be released.
+
+ (*) Release a reference on an item:
+
+ void (*put_ref)(struct slow_work *work);
+
+ This allows the thread pool to unpin an item by releasing the reference on
+ it. The thread pool will not touch the item again once this has been
+ called.
+
+ (*) Execute an item:
+
+ void (*execute)(struct slow_work *work);
+
+ This should perform the work required of the item. It may sleep, it may
+ perform disk I/O and it may wait for locks.
+
+
+==================
+POOL CONFIGURATION
+==================
+
+The slow-work thread pool has a number of configurables:
+
+ (*) /proc/sys/kernel/slow-work/min-threads
+
+ The minimum number of threads that should be in the pool whilst it is in
+ use. This may be anywhere between 2 and max-threads.
+
+ (*) /proc/sys/kernel/slow-work/max-threads
+
+ The maximum number of threads that should in the pool. This may be
+ anywhere between min-threads and 255 or NR_CPUS * 2, whichever is greater.
+
+ (*) /proc/sys/kernel/slow-work/vslow-percentage
+
+ The percentage of active threads in the pool that may be used to execute
+ very slow work items. This may be between 1 and 99. The resultant number
+ is bounded to between 1 and one fewer than the number of active threads.
+ This ensures there is always at least one thread that can process very
+ slow work items, and always at least one thread that won't.
diff --git a/Documentation/sound/alsa/soc/jack.txt b/Documentation/sound/alsa/soc/jack.txt
new file mode 100644
index 00000000000..fcf82a41729
--- /dev/null
+++ b/Documentation/sound/alsa/soc/jack.txt
@@ -0,0 +1,71 @@
+ASoC jack detection
+===================
+
+ALSA has a standard API for representing physical jacks to user space,
+the kernel side of which can be seen in include/sound/jack.h. ASoC
+provides a version of this API adding two additional features:
+
+ - It allows more than one jack detection method to work together on one
+ user visible jack. In embedded systems it is common for multiple
+ to be present on a single jack but handled by separate bits of
+ hardware.
+
+ - Integration with DAPM, allowing DAPM endpoints to be updated
+ automatically based on the detected jack status (eg, turning off the
+ headphone outputs if no headphones are present).
+
+This is done by splitting the jacks up into three things working
+together: the jack itself represented by a struct snd_soc_jack, sets of
+snd_soc_jack_pins representing DAPM endpoints to update and blocks of
+code providing jack reporting mechanisms.
+
+For example, a system may have a stereo headset jack with two reporting
+mechanisms, one for the headphone and one for the microphone. Some
+systems won't be able to use their speaker output while a headphone is
+connected and so will want to make sure to update both speaker and
+headphone when the headphone jack status changes.
+
+The jack - struct snd_soc_jack
+==============================
+
+This represents a physical jack on the system and is what is visible to
+user space. The jack itself is completely passive, it is set up by the
+machine driver and updated by jack detection methods.
+
+Jacks are created by the machine driver calling snd_soc_jack_new().
+
+snd_soc_jack_pin
+================
+
+These represent a DAPM pin to update depending on some of the status
+bits supported by the jack. Each snd_soc_jack has zero or more of these
+which are updated automatically. They are created by the machine driver
+and associated with the jack using snd_soc_jack_add_pins(). The status
+of the endpoint may configured to be the opposite of the jack status if
+required (eg, enabling a built in microphone if a microphone is not
+connected via a jack).
+
+Jack detection methods
+======================
+
+Actual jack detection is done by code which is able to monitor some
+input to the system and update a jack by calling snd_soc_jack_report(),
+specifying a subset of bits to update. The jack detection code should
+be set up by the machine driver, taking configuration for the jack to
+update and the set of things to report when the jack is connected.
+
+Often this is done based on the status of a GPIO - a handler for this is
+provided by the snd_soc_jack_add_gpio() function. Other methods are
+also available, for example integrated into CODECs. One example of
+CODEC integrated jack detection can be see in the WM8350 driver.
+
+Each jack may have multiple reporting mechanisms, though it will need at
+least one to be useful.
+
+Machine drivers
+===============
+
+These are all hooked together by the machine driver depending on the
+system hardware. The machine driver will set up the snd_soc_jack and
+the list of pins to update then set up one or more jack detection
+mechanisms to update that jack based on their current status.
diff --git a/Documentation/sparse.txt b/Documentation/sparse.txt
index 42f43fa59f2..34c76a55bc0 100644
--- a/Documentation/sparse.txt
+++ b/Documentation/sparse.txt
@@ -42,6 +42,14 @@ sure that bitwise types don't get mixed up (little-endian vs big-endian
vs cpu-endian vs whatever), and there the constant "0" really _is_
special.
+__bitwise__ - to be used for relatively compact stuff (gfp_t, etc.) that
+is mostly warning-free and is supposed to stay that way. Warnings will
+be generated without __CHECK_ENDIAN__.
+
+__bitwise - noisy stuff; in particular, __le*/__be* are that. We really
+don't want to drown in noise unless we'd explicitly asked for it.
+
+
Getting sparse
~~~~~~~~~~~~~~
diff --git a/Documentation/sysctl/net.txt b/Documentation/sysctl/net.txt
index a34d55b6544..df38ef046f8 100644
--- a/Documentation/sysctl/net.txt
+++ b/Documentation/sysctl/net.txt
@@ -95,7 +95,7 @@ of struct cmsghdr structures with appended data.
There is only one file in this directory.
unix_dgram_qlen limits the max number of datagrams queued in Unix domain
-socket's buffer. It will not take effect unless PF_UNIX flag is spicified.
+socket's buffer. It will not take effect unless PF_UNIX flag is specified.
3. /proc/sys/net/ipv4 - IPV4 settings
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
index 3197fc83bc5..97c4b328432 100644
--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -39,6 +39,8 @@ Currently, these files are in /proc/sys/vm:
- nr_hugepages
- nr_overcommit_hugepages
- nr_pdflush_threads
+- nr_pdflush_threads_min
+- nr_pdflush_threads_max
- nr_trim_pages (only if CONFIG_MMU=n)
- numa_zonelist_order
- oom_dump_tasks
@@ -463,6 +465,32 @@ The default value is 0.
==============================================================
+nr_pdflush_threads_min
+
+This value controls the minimum number of pdflush threads.
+
+At boot time, the kernel will create and maintain 'nr_pdflush_threads_min'
+threads for the kernel's lifetime.
+
+The default value is 2. The minimum value you can specify is 1, and
+the maximum value is the current setting of 'nr_pdflush_threads_max'.
+
+See 'nr_pdflush_threads_max' below for more information.
+
+==============================================================
+
+nr_pdflush_threads_max
+
+This value controls the maximum number of pdflush threads that can be
+created. The pdflush algorithm will create a new pdflush thread (up to
+this maximum) if no pdflush threads have been available for >= 1 second.
+
+The default value is 8. The minimum value you can specify is the
+current value of 'nr_pdflush_threads_min' and the
+maximum is 1000.
+
+==============================================================
+
overcommit_memory:
This value contains a flag that enables memory overcommitment.
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt
index afa2946892d..cf42b820ff9 100644
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -115,6 +115,8 @@ On all - write a character to /proc/sysrq-trigger. e.g.:
'x' - Used by xmon interface on ppc/powerpc platforms.
+'z' - Dump the ftrace buffer
+
'0'-'9' - Sets the console log level, controlling which kernel messages
will be printed to your console. ('0', for example would make
it so that only emergency messages like PANICs or OOPSes would
diff --git a/Documentation/tomoyo.txt b/Documentation/tomoyo.txt
new file mode 100644
index 00000000000..b3a232cae7f
--- /dev/null
+++ b/Documentation/tomoyo.txt
@@ -0,0 +1,55 @@
+--- What is TOMOYO? ---
+
+TOMOYO is a name-based MAC extension (LSM module) for the Linux kernel.
+
+LiveCD-based tutorials are available at
+http://tomoyo.sourceforge.jp/en/1.6.x/1st-step/ubuntu8.04-live/
+http://tomoyo.sourceforge.jp/en/1.6.x/1st-step/centos5-live/ .
+Though these tutorials use non-LSM version of TOMOYO, they are useful for you
+to know what TOMOYO is.
+
+--- How to enable TOMOYO? ---
+
+Build the kernel with CONFIG_SECURITY_TOMOYO=y and pass "security=tomoyo" on
+kernel's command line.
+
+Please see http://tomoyo.sourceforge.jp/en/2.2.x/ for details.
+
+--- Where is documentation? ---
+
+User <-> Kernel interface documentation is available at
+http://tomoyo.sourceforge.jp/en/2.2.x/policy-reference.html .
+
+Materials we prepared for seminars and symposiums are available at
+http://sourceforge.jp/projects/tomoyo/docs/?category_id=532&language_id=1 .
+Below lists are chosen from three aspects.
+
+What is TOMOYO?
+ TOMOYO Linux Overview
+ http://sourceforge.jp/projects/tomoyo/docs/lca2009-takeda.pdf
+ TOMOYO Linux: pragmatic and manageable security for Linux
+ http://sourceforge.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf
+ TOMOYO Linux: A Practical Method to Understand and Protect Your Own Linux Box
+ http://sourceforge.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf
+
+What can TOMOYO do?
+ Deep inside TOMOYO Linux
+ http://sourceforge.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf
+ The role of "pathname based access control" in security.
+ http://sourceforge.jp/projects/tomoyo/docs/lfj2008-bof.pdf
+
+History of TOMOYO?
+ Realities of Mainlining
+ http://sourceforge.jp/projects/tomoyo/docs/lfj2008.pdf
+
+--- What is future plan? ---
+
+We believe that inode based security and name based security are complementary
+and both should be used together. But unfortunately, so far, we cannot enable
+multiple LSM modules at the same time. We feel sorry that you have to give up
+SELinux/SMACK/AppArmor etc. when you want to use TOMOYO.
+
+We hope that LSM becomes stackable in future. Meanwhile, you can use non-LSM
+version of TOMOYO, available at http://tomoyo.sourceforge.jp/en/1.6.x/ .
+LSM version of TOMOYO is a subset of non-LSM version of TOMOYO. We are planning
+to port non-LSM version's functionalities to LSM versions.
diff --git a/Documentation/ftrace.txt b/Documentation/trace/ftrace.txt
index 803b1318b13..fd9a3e69381 100644
--- a/Documentation/ftrace.txt
+++ b/Documentation/trace/ftrace.txt
@@ -15,31 +15,31 @@ Introduction
Ftrace is an internal tracer designed to help out developers and
designers of systems to find what is going on inside the kernel.
-It can be used for debugging or analyzing latencies and performance
-issues that take place outside of user-space.
+It can be used for debugging or analyzing latencies and
+performance issues that take place outside of user-space.
Although ftrace is the function tracer, it also includes an
-infrastructure that allows for other types of tracing. Some of the
-tracers that are currently in ftrace include a tracer to trace
-context switches, the time it takes for a high priority task to
-run after it was woken up, the time interrupts are disabled, and
-more (ftrace allows for tracer plugins, which means that the list of
-tracers can always grow).
+infrastructure that allows for other types of tracing. Some of
+the tracers that are currently in ftrace include a tracer to
+trace context switches, the time it takes for a high priority
+task to run after it was woken up, the time interrupts are
+disabled, and more (ftrace allows for tracer plugins, which
+means that the list of tracers can always grow).
The File System
---------------
-Ftrace uses the debugfs file system to hold the control files as well
-as the files to display output.
+Ftrace uses the debugfs file system to hold the control files as
+well as the files to display output.
To mount the debugfs system:
# mkdir /debug
# mount -t debugfs nodev /debug
-(Note: it is more common to mount at /sys/kernel/debug, but for simplicity
- this document will use /debug)
+( Note: it is more common to mount at /sys/kernel/debug, but for
+ simplicity this document will use /debug)
That's it! (assuming that you have ftrace configured into your kernel)
@@ -50,90 +50,124 @@ of ftrace. Here is a list of some of the key files:
Note: all time values are in microseconds.
- current_tracer: This is used to set or display the current tracer
- that is configured.
-
- available_tracers: This holds the different types of tracers that
- have been compiled into the kernel. The tracers
- listed here can be configured by echoing their name
- into current_tracer.
-
- tracing_enabled: This sets or displays whether the current_tracer
- is activated and tracing or not. Echo 0 into this
- file to disable the tracer or 1 to enable it.
-
- trace: This file holds the output of the trace in a human readable
- format (described below).
-
- latency_trace: This file shows the same trace but the information
- is organized more to display possible latencies
- in the system (described below).
-
- trace_pipe: The output is the same as the "trace" file but this
- file is meant to be streamed with live tracing.
- Reads from this file will block until new data
- is retrieved. Unlike the "trace" and "latency_trace"
- files, this file is a consumer. This means reading
- from this file causes sequential reads to display
- more current data. Once data is read from this
- file, it is consumed, and will not be read
- again with a sequential read. The "trace" and
- "latency_trace" files are static, and if the
- tracer is not adding more data, they will display
- the same information every time they are read.
-
- trace_options: This file lets the user control the amount of data
- that is displayed in one of the above output
- files.
-
- trace_max_latency: Some of the tracers record the max latency.
- For example, the time interrupts are disabled.
- This time is saved in this file. The max trace
- will also be stored, and displayed by either
- "trace" or "latency_trace". A new max trace will
- only be recorded if the latency is greater than
- the value in this file. (in microseconds)
-
- buffer_size_kb: This sets or displays the number of kilobytes each CPU
- buffer can hold. The tracer buffers are the same size
- for each CPU. The displayed number is the size of the
- CPU buffer and not total size of all buffers. The
- trace buffers are allocated in pages (blocks of memory
- that the kernel uses for allocation, usually 4 KB in size).
- If the last page allocated has room for more bytes
- than requested, the rest of the page will be used,
- making the actual allocation bigger than requested.
- (Note, the size may not be a multiple of the page size due
- to buffer managment overhead.)
-
- This can only be updated when the current_tracer
- is set to "nop".
-
- tracing_cpumask: This is a mask that lets the user only trace
- on specified CPUS. The format is a hex string
- representing the CPUS.
-
- set_ftrace_filter: When dynamic ftrace is configured in (see the
- section below "dynamic ftrace"), the code is dynamically
- modified (code text rewrite) to disable calling of the
- function profiler (mcount). This lets tracing be configured
- in with practically no overhead in performance. This also
- has a side effect of enabling or disabling specific functions
- to be traced. Echoing names of functions into this file
- will limit the trace to only those functions.
-
- set_ftrace_notrace: This has an effect opposite to that of
- set_ftrace_filter. Any function that is added here will not
- be traced. If a function exists in both set_ftrace_filter
- and set_ftrace_notrace, the function will _not_ be traced.
-
- set_ftrace_pid: Have the function tracer only trace a single thread.
-
- available_filter_functions: This lists the functions that ftrace
- has processed and can trace. These are the function
- names that you can pass to "set_ftrace_filter" or
- "set_ftrace_notrace". (See the section "dynamic ftrace"
- below for more details.)
+ current_tracer:
+
+ This is used to set or display the current tracer
+ that is configured.
+
+ available_tracers:
+
+ This holds the different types of tracers that
+ have been compiled into the kernel. The
+ tracers listed here can be configured by
+ echoing their name into current_tracer.
+
+ tracing_enabled:
+
+ This sets or displays whether the current_tracer
+ is activated and tracing or not. Echo 0 into this
+ file to disable the tracer or 1 to enable it.
+
+ trace:
+
+ This file holds the output of the trace in a human
+ readable format (described below).
+
+ latency_trace:
+
+ This file shows the same trace but the information
+ is organized more to display possible latencies
+ in the system (described below).
+
+ trace_pipe:
+
+ The output is the same as the "trace" file but this
+ file is meant to be streamed with live tracing.
+ Reads from this file will block until new data
+ is retrieved. Unlike the "trace" and "latency_trace"
+ files, this file is a consumer. This means reading
+ from this file causes sequential reads to display
+ more current data. Once data is read from this
+ file, it is consumed, and will not be read
+ again with a sequential read. The "trace" and
+ "latency_trace" files are static, and if the
+ tracer is not adding more data, they will display
+ the same information every time they are read.
+
+ trace_options:
+
+ This file lets the user control the amount of data
+ that is displayed in one of the above output
+ files.
+
+ tracing_max_latency:
+
+ Some of the tracers record the max latency.
+ For example, the time interrupts are disabled.
+ This time is saved in this file. The max trace
+ will also be stored, and displayed by either
+ "trace" or "latency_trace". A new max trace will
+ only be recorded if the latency is greater than
+ the value in this file. (in microseconds)
+
+ buffer_size_kb:
+
+ This sets or displays the number of kilobytes each CPU
+ buffer can hold. The tracer buffers are the same size
+ for each CPU. The displayed number is the size of the
+ CPU buffer and not total size of all buffers. The
+ trace buffers are allocated in pages (blocks of memory
+ that the kernel uses for allocation, usually 4 KB in size).
+ If the last page allocated has room for more bytes
+ than requested, the rest of the page will be used,
+ making the actual allocation bigger than requested.
+ ( Note, the size may not be a multiple of the page size
+ due to buffer managment overhead. )
+
+ This can only be updated when the current_tracer
+ is set to "nop".
+
+ tracing_cpumask:
+
+ This is a mask that lets the user only trace
+ on specified CPUS. The format is a hex string
+ representing the CPUS.
+
+ set_ftrace_filter:
+
+ When dynamic ftrace is configured in (see the
+ section below "dynamic ftrace"), the code is dynamically
+ modified (code text rewrite) to disable calling of the
+ function profiler (mcount). This lets tracing be configured
+ in with practically no overhead in performance. This also
+ has a side effect of enabling or disabling specific functions
+ to be traced. Echoing names of functions into this file
+ will limit the trace to only those functions.
+
+ set_ftrace_notrace:
+
+ This has an effect opposite to that of
+ set_ftrace_filter. Any function that is added here will not
+ be traced. If a function exists in both set_ftrace_filter
+ and set_ftrace_notrace, the function will _not_ be traced.
+
+ set_ftrace_pid:
+
+ Have the function tracer only trace a single thread.
+
+ set_graph_function:
+
+ Set a "trigger" function where tracing should start
+ with the function graph tracer (See the section
+ "dynamic ftrace" for more details).
+
+ available_filter_functions:
+
+ This lists the functions that ftrace
+ has processed and can trace. These are the function
+ names that you can pass to "set_ftrace_filter" or
+ "set_ftrace_notrace". (See the section "dynamic ftrace"
+ below for more details.)
The Tracers
@@ -141,36 +175,66 @@ The Tracers
Here is the list of current tracers that may be configured.
- function - function tracer that uses mcount to trace all functions.
+ "function"
+
+ Function call tracer to trace all kernel functions.
+
+ "function_graph_tracer"
+
+ Similar to the function tracer except that the
+ function tracer probes the functions on their entry
+ whereas the function graph tracer traces on both entry
+ and exit of the functions. It then provides the ability
+ to draw a graph of function calls similar to C code
+ source.
- sched_switch - traces the context switches between tasks.
+ "sched_switch"
- irqsoff - traces the areas that disable interrupts and saves
- the trace with the longest max latency.
- See tracing_max_latency. When a new max is recorded,
- it replaces the old trace. It is best to view this
- trace via the latency_trace file.
+ Traces the context switches and wakeups between tasks.
- preemptoff - Similar to irqsoff but traces and records the amount of
- time for which preemption is disabled.
+ "irqsoff"
- preemptirqsoff - Similar to irqsoff and preemptoff, but traces and
- records the largest time for which irqs and/or preemption
- is disabled.
+ Traces the areas that disable interrupts and saves
+ the trace with the longest max latency.
+ See tracing_max_latency. When a new max is recorded,
+ it replaces the old trace. It is best to view this
+ trace via the latency_trace file.
- wakeup - Traces and records the max latency that it takes for
- the highest priority task to get scheduled after
- it has been woken up.
+ "preemptoff"
- nop - This is not a tracer. To remove all tracers from tracing
- simply echo "nop" into current_tracer.
+ Similar to irqsoff but traces and records the amount of
+ time for which preemption is disabled.
+
+ "preemptirqsoff"
+
+ Similar to irqsoff and preemptoff, but traces and
+ records the largest time for which irqs and/or preemption
+ is disabled.
+
+ "wakeup"
+
+ Traces and records the max latency that it takes for
+ the highest priority task to get scheduled after
+ it has been woken up.
+
+ "hw-branch-tracer"
+
+ Uses the BTS CPU feature on x86 CPUs to traces all
+ branches executed.
+
+ "nop"
+
+ This is the "trace nothing" tracer. To remove all
+ tracers from tracing simply echo "nop" into
+ current_tracer.
Examples of using the tracer
----------------------------
-Here are typical examples of using the tracers when controlling them only
-with the debugfs interface (without using any user-land utilities).
+Here are typical examples of using the tracers when controlling
+them only with the debugfs interface (without using any
+user-land utilities).
Output format:
--------------
@@ -187,16 +251,16 @@ Here is an example of the output format of the file "trace"
bash-4251 [01] 10152.583855: _atomic_dec_and_lock <-dput
--------
-A header is printed with the tracer name that is represented by the trace.
-In this case the tracer is "function". Then a header showing the format. Task
-name "bash", the task PID "4251", the CPU that it was running on
-"01", the timestamp in <secs>.<usecs> format, the function name that was
-traced "path_put" and the parent function that called this function
-"path_walk". The timestamp is the time at which the function was
-entered.
+A header is printed with the tracer name that is represented by
+the trace. In this case the tracer is "function". Then a header
+showing the format. Task name "bash", the task PID "4251", the
+CPU that it was running on "01", the timestamp in <secs>.<usecs>
+format, the function name that was traced "path_put" and the
+parent function that called this function "path_walk". The
+timestamp is the time at which the function was entered.
-The sched_switch tracer also includes tracing of task wakeups and
-context switches.
+The sched_switch tracer also includes tracing of task wakeups
+and context switches.
ksoftirqd/1-7 [01] 1453.070013: 7:115:R + 2916:115:S
ksoftirqd/1-7 [01] 1453.070013: 7:115:R + 10:115:S
@@ -205,8 +269,8 @@ context switches.
kondemand/1-2916 [01] 1453.070013: 2916:115:S ==> 7:115:R
ksoftirqd/1-7 [01] 1453.070013: 7:115:S ==> 0:140:R
-Wake ups are represented by a "+" and the context switches are shown as
-"==>". The format is:
+Wake ups are represented by a "+" and the context switches are
+shown as "==>". The format is:
Context switches:
@@ -220,19 +284,20 @@ Wake ups are represented by a "+" and the context switches are shown as
<pid>:<prio>:<state> + <pid>:<prio>:<state>
-The prio is the internal kernel priority, which is the inverse of the
-priority that is usually displayed by user-space tools. Zero represents
-the highest priority (99). Prio 100 starts the "nice" priorities with
-100 being equal to nice -20 and 139 being nice 19. The prio "140" is
-reserved for the idle task which is the lowest priority thread (pid 0).
+The prio is the internal kernel priority, which is the inverse
+of the priority that is usually displayed by user-space tools.
+Zero represents the highest priority (99). Prio 100 starts the
+"nice" priorities with 100 being equal to nice -20 and 139 being
+nice 19. The prio "140" is reserved for the idle task which is
+the lowest priority thread (pid 0).
Latency trace format
--------------------
-For traces that display latency times, the latency_trace file gives
-somewhat more information to see why a latency happened. Here is a typical
-trace.
+For traces that display latency times, the latency_trace file
+gives somewhat more information to see why a latency happened.
+Here is a typical trace.
# tracer: irqsoff
#
@@ -259,20 +324,20 @@ irqsoff latency trace v1.1.5 on 2.6.26-rc8
<idle>-0 0d.s1 98us : trace_hardirqs_on (do_softirq)
+This shows that the current tracer is "irqsoff" tracing the time
+for which interrupts were disabled. It gives the trace version
+and the version of the kernel upon which this was executed on
+(2.6.26-rc8). Then it displays the max latency in microsecs (97
+us). The number of trace entries displayed and the total number
+recorded (both are three: #3/3). The type of preemption that was
+used (PREEMPT). VP, KP, SP, and HP are always zero and are
+reserved for later use. #P is the number of online CPUS (#P:2).
-This shows that the current tracer is "irqsoff" tracing the time for which
-interrupts were disabled. It gives the trace version and the version
-of the kernel upon which this was executed on (2.6.26-rc8). Then it displays
-the max latency in microsecs (97 us). The number of trace entries displayed
-and the total number recorded (both are three: #3/3). The type of
-preemption that was used (PREEMPT). VP, KP, SP, and HP are always zero
-and are reserved for later use. #P is the number of online CPUS (#P:2).
-
-The task is the process that was running when the latency occurred.
-(swapper pid: 0).
+The task is the process that was running when the latency
+occurred. (swapper pid: 0).
-The start and stop (the functions in which the interrupts were disabled and
-enabled respectively) that caused the latencies:
+The start and stop (the functions in which the interrupts were
+disabled and enabled respectively) that caused the latencies:
apic_timer_interrupt is where the interrupts were disabled.
do_softirq is where they were enabled again.
@@ -308,12 +373,12 @@ The above is mostly meaningful for kernel developers.
latency_trace file is relative to the start of the trace.
delay: This is just to help catch your eye a bit better. And
- needs to be fixed to be only relative to the same CPU.
- The marks are determined by the difference between this
- current trace and the next trace.
- '!' - greater than preempt_mark_thresh (default 100)
- '+' - greater than 1 microsecond
- ' ' - less than or equal to 1 microsecond.
+ needs to be fixed to be only relative to the same CPU.
+ The marks are determined by the difference between this
+ current trace and the next trace.
+ '!' - greater than preempt_mark_thresh (default 100)
+ '+' - greater than 1 microsecond
+ ' ' - less than or equal to 1 microsecond.
The rest is the same as the 'trace' file.
@@ -321,14 +386,15 @@ The above is mostly meaningful for kernel developers.
trace_options
-------------
-The trace_options file is used to control what gets printed in the trace
-output. To see what is available, simply cat the file:
+The trace_options file is used to control what gets printed in
+the trace output. To see what is available, simply cat the file:
cat /debug/tracing/trace_options
print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \
- noblock nostacktrace nosched-tree nouserstacktrace nosym-userobj
+ noblock nostacktrace nosched-tree nouserstacktrace nosym-userobj
-To disable one of the options, echo in the option prepended with "no".
+To disable one of the options, echo in the option prepended with
+"no".
echo noprint-parent > /debug/tracing/trace_options
@@ -338,8 +404,8 @@ To enable an option, leave off the "no".
Here are the available options:
- print-parent - On function traces, display the calling function
- as well as the function being traced.
+ print-parent - On function traces, display the calling (parent)
+ function as well as the function being traced.
print-parent:
bash-4000 [01] 1477.606694: simple_strtoul <-strict_strtoul
@@ -348,15 +414,16 @@ Here are the available options:
bash-4000 [01] 1477.606694: simple_strtoul
- sym-offset - Display not only the function name, but also the offset
- in the function. For example, instead of seeing just
- "ktime_get", you will see "ktime_get+0xb/0x20".
+ sym-offset - Display not only the function name, but also the
+ offset in the function. For example, instead of
+ seeing just "ktime_get", you will see
+ "ktime_get+0xb/0x20".
sym-offset:
bash-4000 [01] 1477.606694: simple_strtoul+0x6/0xa0
- sym-addr - this will also display the function address as well as
- the function name.
+ sym-addr - this will also display the function address as well
+ as the function name.
sym-addr:
bash-4000 [01] 1477.606694: simple_strtoul <c0339346>
@@ -366,35 +433,41 @@ Here are the available options:
bash 4000 1 0 00000000 00010a95 [58127d26] 1720.415ms \
(+0.000ms): simple_strtoul (strict_strtoul)
- raw - This will display raw numbers. This option is best for use with
- user applications that can translate the raw numbers better than
- having it done in the kernel.
+ raw - This will display raw numbers. This option is best for
+ use with user applications that can translate the raw
+ numbers better than having it done in the kernel.
- hex - Similar to raw, but the numbers will be in a hexadecimal format.
+ hex - Similar to raw, but the numbers will be in a hexadecimal
+ format.
bin - This will print out the formats in raw binary.
block - TBD (needs update)
- stacktrace - This is one of the options that changes the trace itself.
- When a trace is recorded, so is the stack of functions.
- This allows for back traces of trace sites.
+ stacktrace - This is one of the options that changes the trace
+ itself. When a trace is recorded, so is the stack
+ of functions. This allows for back traces of
+ trace sites.
- userstacktrace - This option changes the trace.
- It records a stacktrace of the current userspace thread.
+ userstacktrace - This option changes the trace. It records a
+ stacktrace of the current userspace thread.
- sym-userobj - when user stacktrace are enabled, look up which object the
- address belongs to, and print a relative address
- This is especially useful when ASLR is on, otherwise you don't
- get a chance to resolve the address to object/file/line after the app is no
- longer running
+ sym-userobj - when user stacktrace are enabled, look up which
+ object the address belongs to, and print a
+ relative address. This is especially useful when
+ ASLR is on, otherwise you don't get a chance to
+ resolve the address to object/file/line after
+ the app is no longer running
- The lookup is performed when you read trace,trace_pipe,latency_trace. Example:
+ The lookup is performed when you read
+ trace,trace_pipe,latency_trace. Example:
a.out-1623 [000] 40874.465068: /root/a.out[+0x480] <-/root/a.out[+0
x494] <- /root/a.out[+0x4a8] <- /lib/libc-2.7.so[+0x1e1a6]
- sched-tree - TBD (any users??)
+ sched-tree - trace all tasks that are on the runqueue, at
+ every scheduling event. Will add overhead if
+ there's a lot of tasks running at once.
sched_switch
@@ -431,18 +504,19 @@ of how to use it.
[...]
-As we have discussed previously about this format, the header shows
-the name of the trace and points to the options. The "FUNCTION"
-is a misnomer since here it represents the wake ups and context
-switches.
+As we have discussed previously about this format, the header
+shows the name of the trace and points to the options. The
+"FUNCTION" is a misnomer since here it represents the wake ups
+and context switches.
-The sched_switch file only lists the wake ups (represented with '+')
-and context switches ('==>') with the previous task or current task
-first followed by the next task or task waking up. The format for both
-of these is PID:KERNEL-PRIO:TASK-STATE. Remember that the KERNEL-PRIO
-is the inverse of the actual priority with zero (0) being the highest
-priority and the nice values starting at 100 (nice -20). Below is
-a quick chart to map the kernel priority to user land priorities.
+The sched_switch file only lists the wake ups (represented with
+'+') and context switches ('==>') with the previous task or
+current task first followed by the next task or task waking up.
+The format for both of these is PID:KERNEL-PRIO:TASK-STATE.
+Remember that the KERNEL-PRIO is the inverse of the actual
+priority with zero (0) being the highest priority and the nice
+values starting at 100 (nice -20). Below is a quick chart to map
+the kernel priority to user land priorities.
Kernel priority: 0 to 99 ==> user RT priority 99 to 0
Kernel priority: 100 to 139 ==> user nice -20 to 19
@@ -463,10 +537,10 @@ The task states are:
ftrace_enabled
--------------
-The following tracers (listed below) give different output depending
-on whether or not the sysctl ftrace_enabled is set. To set ftrace_enabled,
-one can either use the sysctl function or set it via the proc
-file system interface.
+The following tracers (listed below) give different output
+depending on whether or not the sysctl ftrace_enabled is set. To
+set ftrace_enabled, one can either use the sysctl function or
+set it via the proc file system interface.
sysctl kernel.ftrace_enabled=1
@@ -474,12 +548,12 @@ file system interface.
echo 1 > /proc/sys/kernel/ftrace_enabled
-To disable ftrace_enabled simply replace the '1' with '0' in
-the above commands.
+To disable ftrace_enabled simply replace the '1' with '0' in the
+above commands.
-When ftrace_enabled is set the tracers will also record the functions
-that are within the trace. The descriptions of the tracers
-will also show an example with ftrace enabled.
+When ftrace_enabled is set the tracers will also record the
+functions that are within the trace. The descriptions of the
+tracers will also show an example with ftrace enabled.
irqsoff
@@ -487,17 +561,18 @@ irqsoff
When interrupts are disabled, the CPU can not react to any other
external event (besides NMIs and SMIs). This prevents the timer
-interrupt from triggering or the mouse interrupt from letting the
-kernel know of a new mouse event. The result is a latency with the
-reaction time.
+interrupt from triggering or the mouse interrupt from letting
+the kernel know of a new mouse event. The result is a latency
+with the reaction time.
-The irqsoff tracer tracks the time for which interrupts are disabled.
-When a new maximum latency is hit, the tracer saves the trace leading up
-to that latency point so that every time a new maximum is reached, the old
-saved trace is discarded and the new trace is saved.
+The irqsoff tracer tracks the time for which interrupts are
+disabled. When a new maximum latency is hit, the tracer saves
+the trace leading up to that latency point so that every time a
+new maximum is reached, the old saved trace is discarded and the
+new trace is saved.
-To reset the maximum, echo 0 into tracing_max_latency. Here is an
-example:
+To reset the maximum, echo 0 into tracing_max_latency. Here is
+an example:
# echo irqsoff > /debug/tracing/current_tracer
# echo 0 > /debug/tracing/tracing_max_latency
@@ -532,10 +607,11 @@ irqsoff latency trace v1.1.5 on 2.6.26
Here we see that that we had a latency of 12 microsecs (which is
-very good). The _write_lock_irq in sys_setpgid disabled interrupts.
-The difference between the 12 and the displayed timestamp 14us occurred
-because the clock was incremented between the time of recording the max
-latency and the time of recording the function that had that latency.
+very good). The _write_lock_irq in sys_setpgid disabled
+interrupts. The difference between the 12 and the displayed
+timestamp 14us occurred because the clock was incremented
+between the time of recording the max latency and the time of
+recording the function that had that latency.
Note the above example had ftrace_enabled not set. If we set the
ftrace_enabled, we get a much larger output:
@@ -586,24 +662,24 @@ irqsoff latency trace v1.1.5 on 2.6.26-rc8
Here we traced a 50 microsecond latency. But we also see all the
-functions that were called during that time. Note that by enabling
-function tracing, we incur an added overhead. This overhead may
-extend the latency times. But nevertheless, this trace has provided
-some very helpful debugging information.
+functions that were called during that time. Note that by
+enabling function tracing, we incur an added overhead. This
+overhead may extend the latency times. But nevertheless, this
+trace has provided some very helpful debugging information.
preemptoff
----------
-When preemption is disabled, we may be able to receive interrupts but
-the task cannot be preempted and a higher priority task must wait
-for preemption to be enabled again before it can preempt a lower
-priority task.
+When preemption is disabled, we may be able to receive
+interrupts but the task cannot be preempted and a higher
+priority task must wait for preemption to be enabled again
+before it can preempt a lower priority task.
The preemptoff tracer traces the places that disable preemption.
-Like the irqsoff tracer, it records the maximum latency for which preemption
-was disabled. The control of preemptoff tracer is much like the irqsoff
-tracer.
+Like the irqsoff tracer, it records the maximum latency for
+which preemption was disabled. The control of preemptoff tracer
+is much like the irqsoff tracer.
# echo preemptoff > /debug/tracing/current_tracer
# echo 0 > /debug/tracing/tracing_max_latency
@@ -637,11 +713,12 @@ preemptoff latency trace v1.1.5 on 2.6.26-rc8
sshd-4261 0d.s1 30us : trace_preempt_on (__do_softirq)
-This has some more changes. Preemption was disabled when an interrupt
-came in (notice the 'h'), and was enabled while doing a softirq.
-(notice the 's'). But we also see that interrupts have been disabled
-when entering the preempt off section and leaving it (the 'd').
-We do not know if interrupts were enabled in the mean time.
+This has some more changes. Preemption was disabled when an
+interrupt came in (notice the 'h'), and was enabled while doing
+a softirq. (notice the 's'). But we also see that interrupts
+have been disabled when entering the preempt off section and
+leaving it (the 'd'). We do not know if interrupts were enabled
+in the mean time.
# tracer: preemptoff
#
@@ -700,28 +777,30 @@ preemptoff latency trace v1.1.5 on 2.6.26-rc8
sshd-4261 0d.s1 64us : trace_preempt_on (__do_softirq)
-The above is an example of the preemptoff trace with ftrace_enabled
-set. Here we see that interrupts were disabled the entire time.
-The irq_enter code lets us know that we entered an interrupt 'h'.
-Before that, the functions being traced still show that it is not
-in an interrupt, but we can see from the functions themselves that
-this is not the case.
+The above is an example of the preemptoff trace with
+ftrace_enabled set. Here we see that interrupts were disabled
+the entire time. The irq_enter code lets us know that we entered
+an interrupt 'h'. Before that, the functions being traced still
+show that it is not in an interrupt, but we can see from the
+functions themselves that this is not the case.
-Notice that __do_softirq when called does not have a preempt_count.
-It may seem that we missed a preempt enabling. What really happened
-is that the preempt count is held on the thread's stack and we
-switched to the softirq stack (4K stacks in effect). The code
-does not copy the preempt count, but because interrupts are disabled,
-we do not need to worry about it. Having a tracer like this is good
-for letting people know what really happens inside the kernel.
+Notice that __do_softirq when called does not have a
+preempt_count. It may seem that we missed a preempt enabling.
+What really happened is that the preempt count is held on the
+thread's stack and we switched to the softirq stack (4K stacks
+in effect). The code does not copy the preempt count, but
+because interrupts are disabled, we do not need to worry about
+it. Having a tracer like this is good for letting people know
+what really happens inside the kernel.
preemptirqsoff
--------------
-Knowing the locations that have interrupts disabled or preemption
-disabled for the longest times is helpful. But sometimes we would
-like to know when either preemption and/or interrupts are disabled.
+Knowing the locations that have interrupts disabled or
+preemption disabled for the longest times is helpful. But
+sometimes we would like to know when either preemption and/or
+interrupts are disabled.
Consider the following code:
@@ -741,11 +820,13 @@ The preemptoff tracer will record the total length of
call_function_with_irqs_and_preemption_off() and
call_function_with_preemption_off().
-But neither will trace the time that interrupts and/or preemption
-is disabled. This total time is the time that we can not schedule.
-To record this time, use the preemptirqsoff tracer.
+But neither will trace the time that interrupts and/or
+preemption is disabled. This total time is the time that we can
+not schedule. To record this time, use the preemptirqsoff
+tracer.
-Again, using this trace is much like the irqsoff and preemptoff tracers.
+Again, using this trace is much like the irqsoff and preemptoff
+tracers.
# echo preemptirqsoff > /debug/tracing/current_tracer
# echo 0 > /debug/tracing/tracing_max_latency
@@ -781,9 +862,10 @@ preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8
The trace_hardirqs_off_thunk is called from assembly on x86 when
-interrupts are disabled in the assembly code. Without the function
-tracing, we do not know if interrupts were enabled within the preemption
-points. We do see that it started with preemption enabled.
+interrupts are disabled in the assembly code. Without the
+function tracing, we do not know if interrupts were enabled
+within the preemption points. We do see that it started with
+preemption enabled.
Here is a trace with ftrace_enabled set:
@@ -871,40 +953,42 @@ preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8
sshd-4261 0d.s1 105us : trace_preempt_on (__do_softirq)
-This is a very interesting trace. It started with the preemption of
-the ls task. We see that the task had the "need_resched" bit set
-via the 'N' in the trace. Interrupts were disabled before the spin_lock
-at the beginning of the trace. We see that a schedule took place to run
-sshd. When the interrupts were enabled, we took an interrupt.
-On return from the interrupt handler, the softirq ran. We took another
-interrupt while running the softirq as we see from the capital 'H'.
+This is a very interesting trace. It started with the preemption
+of the ls task. We see that the task had the "need_resched" bit
+set via the 'N' in the trace. Interrupts were disabled before
+the spin_lock at the beginning of the trace. We see that a
+schedule took place to run sshd. When the interrupts were
+enabled, we took an interrupt. On return from the interrupt
+handler, the softirq ran. We took another interrupt while
+running the softirq as we see from the capital 'H'.
wakeup
------
-In a Real-Time environment it is very important to know the wakeup
-time it takes for the highest priority task that is woken up to the
-time that it executes. This is also known as "schedule latency".
-I stress the point that this is about RT tasks. It is also important
-to know the scheduling latency of non-RT tasks, but the average
-schedule latency is better for non-RT tasks. Tools like
-LatencyTop are more appropriate for such measurements.
+In a Real-Time environment it is very important to know the
+wakeup time it takes for the highest priority task that is woken
+up to the time that it executes. This is also known as "schedule
+latency". I stress the point that this is about RT tasks. It is
+also important to know the scheduling latency of non-RT tasks,
+but the average schedule latency is better for non-RT tasks.
+Tools like LatencyTop are more appropriate for such
+measurements.
Real-Time environments are interested in the worst case latency.
-That is the longest latency it takes for something to happen, and
-not the average. We can have a very fast scheduler that may only
-have a large latency once in a while, but that would not work well
-with Real-Time tasks. The wakeup tracer was designed to record
-the worst case wakeups of RT tasks. Non-RT tasks are not recorded
-because the tracer only records one worst case and tracing non-RT
-tasks that are unpredictable will overwrite the worst case latency
-of RT tasks.
-
-Since this tracer only deals with RT tasks, we will run this slightly
-differently than we did with the previous tracers. Instead of performing
-an 'ls', we will run 'sleep 1' under 'chrt' which changes the
-priority of the task.
+That is the longest latency it takes for something to happen,
+and not the average. We can have a very fast scheduler that may
+only have a large latency once in a while, but that would not
+work well with Real-Time tasks. The wakeup tracer was designed
+to record the worst case wakeups of RT tasks. Non-RT tasks are
+not recorded because the tracer only records one worst case and
+tracing non-RT tasks that are unpredictable will overwrite the
+worst case latency of RT tasks.
+
+Since this tracer only deals with RT tasks, we will run this
+slightly differently than we did with the previous tracers.
+Instead of performing an 'ls', we will run 'sleep 1' under
+'chrt' which changes the priority of the task.
# echo wakeup > /debug/tracing/current_tracer
# echo 0 > /debug/tracing/tracing_max_latency
@@ -934,17 +1018,16 @@ wakeup latency trace v1.1.5 on 2.6.26-rc8
<idle>-0 1d..4 4us : schedule (cpu_idle)
+Running this on an idle system, we see that it only took 4
+microseconds to perform the task switch. Note, since the trace
+marker in the schedule is before the actual "switch", we stop
+the tracing when the recorded task is about to schedule in. This
+may change if we add a new marker at the end of the scheduler.
-Running this on an idle system, we see that it only took 4 microseconds
-to perform the task switch. Note, since the trace marker in the
-schedule is before the actual "switch", we stop the tracing when
-the recorded task is about to schedule in. This may change if
-we add a new marker at the end of the scheduler.
-
-Notice that the recorded task is 'sleep' with the PID of 4901 and it
-has an rt_prio of 5. This priority is user-space priority and not
-the internal kernel priority. The policy is 1 for SCHED_FIFO and 2
-for SCHED_RR.
+Notice that the recorded task is 'sleep' with the PID of 4901
+and it has an rt_prio of 5. This priority is user-space priority
+and not the internal kernel priority. The policy is 1 for
+SCHED_FIFO and 2 for SCHED_RR.
Doing the same with chrt -r 5 and ftrace_enabled set.
@@ -1001,24 +1084,25 @@ ksoftirq-7 1d..6 49us : _spin_unlock (tracing_record_cmdline)
ksoftirq-7 1d..6 49us : sub_preempt_count (_spin_unlock)
ksoftirq-7 1d..4 50us : schedule (__cond_resched)
-The interrupt went off while running ksoftirqd. This task runs at
-SCHED_OTHER. Why did not we see the 'N' set early? This may be
-a harmless bug with x86_32 and 4K stacks. On x86_32 with 4K stacks
-configured, the interrupt and softirq run with their own stack.
-Some information is held on the top of the task's stack (need_resched
-and preempt_count are both stored there). The setting of the NEED_RESCHED
-bit is done directly to the task's stack, but the reading of the
-NEED_RESCHED is done by looking at the current stack, which in this case
-is the stack for the hard interrupt. This hides the fact that NEED_RESCHED
-has been set. We do not see the 'N' until we switch back to the task's
+The interrupt went off while running ksoftirqd. This task runs
+at SCHED_OTHER. Why did not we see the 'N' set early? This may
+be a harmless bug with x86_32 and 4K stacks. On x86_32 with 4K
+stacks configured, the interrupt and softirq run with their own
+stack. Some information is held on the top of the task's stack
+(need_resched and preempt_count are both stored there). The
+setting of the NEED_RESCHED bit is done directly to the task's
+stack, but the reading of the NEED_RESCHED is done by looking at
+the current stack, which in this case is the stack for the hard
+interrupt. This hides the fact that NEED_RESCHED has been set.
+We do not see the 'N' until we switch back to the task's
assigned stack.
function
--------
This tracer is the function tracer. Enabling the function tracer
-can be done from the debug file system. Make sure the ftrace_enabled is
-set; otherwise this tracer is a nop.
+can be done from the debug file system. Make sure the
+ftrace_enabled is set; otherwise this tracer is a nop.
# sysctl kernel.ftrace_enabled=1
# echo function > /debug/tracing/current_tracer
@@ -1048,14 +1132,15 @@ set; otherwise this tracer is a nop.
[...]
-Note: function tracer uses ring buffers to store the above entries.
-The newest data may overwrite the oldest data. Sometimes using echo to
-stop the trace is not sufficient because the tracing could have overwritten
-the data that you wanted to record. For this reason, it is sometimes better to
-disable tracing directly from a program. This allows you to stop the
-tracing at the point that you hit the part that you are interested in.
-To disable the tracing directly from a C program, something like following
-code snippet can be used:
+Note: function tracer uses ring buffers to store the above
+entries. The newest data may overwrite the oldest data.
+Sometimes using echo to stop the trace is not sufficient because
+the tracing could have overwritten the data that you wanted to
+record. For this reason, it is sometimes better to disable
+tracing directly from a program. This allows you to stop the
+tracing at the point that you hit the part that you are
+interested in. To disable the tracing directly from a C program,
+something like following code snippet can be used:
int trace_fd;
[...]
@@ -1070,10 +1155,10 @@ int main(int argc, char *argv[]) {
}
Note: Here we hard coded the path name. The debugfs mount is not
-guaranteed to be at /debug (and is more commonly at /sys/kernel/debug).
-For simple one time traces, the above is sufficent. For anything else,
-a search through /proc/mounts may be needed to find where the debugfs
-file-system is mounted.
+guaranteed to be at /debug (and is more commonly at
+/sys/kernel/debug). For simple one time traces, the above is
+sufficent. For anything else, a search through /proc/mounts may
+be needed to find where the debugfs file-system is mounted.
Single thread tracing
@@ -1152,49 +1237,297 @@ int main (int argc, char **argv)
return 0;
}
+
+hw-branch-tracer (x86 only)
+---------------------------
+
+This tracer uses the x86 last branch tracing hardware feature to
+collect a branch trace on all cpus with relatively low overhead.
+
+The tracer uses a fixed-size circular buffer per cpu and only
+traces ring 0 branches. The trace file dumps that buffer in the
+following format:
+
+# tracer: hw-branch-tracer
+#
+# CPU# TO <- FROM
+ 0 scheduler_tick+0xb5/0x1bf <- task_tick_idle+0x5/0x6
+ 2 run_posix_cpu_timers+0x2b/0x72a <- run_posix_cpu_timers+0x25/0x72a
+ 0 scheduler_tick+0x139/0x1bf <- scheduler_tick+0xed/0x1bf
+ 0 scheduler_tick+0x17c/0x1bf <- scheduler_tick+0x148/0x1bf
+ 2 run_posix_cpu_timers+0x9e/0x72a <- run_posix_cpu_timers+0x5e/0x72a
+ 0 scheduler_tick+0x1b6/0x1bf <- scheduler_tick+0x1aa/0x1bf
+
+
+The tracer may be used to dump the trace for the oops'ing cpu on
+a kernel oops into the system log. To enable this,
+ftrace_dump_on_oops must be set. To set ftrace_dump_on_oops, one
+can either use the sysctl function or set it via the proc system
+interface.
+
+ sysctl kernel.ftrace_dump_on_oops=1
+
+or
+
+ echo 1 > /proc/sys/kernel/ftrace_dump_on_oops
+
+
+Here's an example of such a dump after a null pointer
+dereference in a kernel module:
+
+[57848.105921] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
+[57848.106019] IP: [<ffffffffa0000006>] open+0x6/0x14 [oops]
+[57848.106019] PGD 2354e9067 PUD 2375e7067 PMD 0
+[57848.106019] Oops: 0002 [#1] SMP
+[57848.106019] last sysfs file: /sys/devices/pci0000:00/0000:00:1e.0/0000:20:05.0/local_cpus
+[57848.106019] Dumping ftrace buffer:
+[57848.106019] ---------------------------------
+[...]
+[57848.106019] 0 chrdev_open+0xe6/0x165 <- cdev_put+0x23/0x24
+[57848.106019] 0 chrdev_open+0x117/0x165 <- chrdev_open+0xfa/0x165
+[57848.106019] 0 chrdev_open+0x120/0x165 <- chrdev_open+0x11c/0x165
+[57848.106019] 0 chrdev_open+0x134/0x165 <- chrdev_open+0x12b/0x165
+[57848.106019] 0 open+0x0/0x14 [oops] <- chrdev_open+0x144/0x165
+[57848.106019] 0 page_fault+0x0/0x30 <- open+0x6/0x14 [oops]
+[57848.106019] 0 error_entry+0x0/0x5b <- page_fault+0x4/0x30
+[57848.106019] 0 error_kernelspace+0x0/0x31 <- error_entry+0x59/0x5b
+[57848.106019] 0 error_sti+0x0/0x1 <- error_kernelspace+0x2d/0x31
+[57848.106019] 0 page_fault+0x9/0x30 <- error_sti+0x0/0x1
+[57848.106019] 0 do_page_fault+0x0/0x881 <- page_fault+0x1a/0x30
+[...]
+[57848.106019] 0 do_page_fault+0x66b/0x881 <- is_prefetch+0x1ee/0x1f2
+[57848.106019] 0 do_page_fault+0x6e0/0x881 <- do_page_fault+0x67a/0x881
+[57848.106019] 0 oops_begin+0x0/0x96 <- do_page_fault+0x6e0/0x881
+[57848.106019] 0 trace_hw_branch_oops+0x0/0x2d <- oops_begin+0x9/0x96
+[...]
+[57848.106019] 0 ds_suspend_bts+0x2a/0xe3 <- ds_suspend_bts+0x1a/0xe3
+[57848.106019] ---------------------------------
+[57848.106019] CPU 0
+[57848.106019] Modules linked in: oops
+[57848.106019] Pid: 5542, comm: cat Tainted: G W 2.6.28 #23
+[57848.106019] RIP: 0010:[<ffffffffa0000006>] [<ffffffffa0000006>] open+0x6/0x14 [oops]
+[57848.106019] RSP: 0018:ffff880235457d48 EFLAGS: 00010246
+[...]
+
+
+function graph tracer
+---------------------------
+
+This tracer is similar to the function tracer except that it
+probes a function on its entry and its exit. This is done by
+using a dynamically allocated stack of return addresses in each
+task_struct. On function entry the tracer overwrites the return
+address of each function traced to set a custom probe. Thus the
+original return address is stored on the stack of return address
+in the task_struct.
+
+Probing on both ends of a function leads to special features
+such as:
+
+- measure of a function's time execution
+- having a reliable call stack to draw function calls graph
+
+This tracer is useful in several situations:
+
+- you want to find the reason of a strange kernel behavior and
+ need to see what happens in detail on any areas (or specific
+ ones).
+
+- you are experiencing weird latencies but it's difficult to
+ find its origin.
+
+- you want to find quickly which path is taken by a specific
+ function
+
+- you just want to peek inside a working kernel and want to see
+ what happens there.
+
+# tracer: function_graph
+#
+# CPU DURATION FUNCTION CALLS
+# | | | | | | |
+
+ 0) | sys_open() {
+ 0) | do_sys_open() {
+ 0) | getname() {
+ 0) | kmem_cache_alloc() {
+ 0) 1.382 us | __might_sleep();
+ 0) 2.478 us | }
+ 0) | strncpy_from_user() {
+ 0) | might_fault() {
+ 0) 1.389 us | __might_sleep();
+ 0) 2.553 us | }
+ 0) 3.807 us | }
+ 0) 7.876 us | }
+ 0) | alloc_fd() {
+ 0) 0.668 us | _spin_lock();
+ 0) 0.570 us | expand_files();
+ 0) 0.586 us | _spin_unlock();
+
+
+There are several columns that can be dynamically
+enabled/disabled. You can use every combination of options you
+want, depending on your needs.
+
+- The cpu number on which the function executed is default
+ enabled. It is sometimes better to only trace one cpu (see
+ tracing_cpu_mask file) or you might sometimes see unordered
+ function calls while cpu tracing switch.
+
+ hide: echo nofuncgraph-cpu > /debug/tracing/trace_options
+ show: echo funcgraph-cpu > /debug/tracing/trace_options
+
+- The duration (function's time of execution) is displayed on
+ the closing bracket line of a function or on the same line
+ than the current function in case of a leaf one. It is default
+ enabled.
+
+ hide: echo nofuncgraph-duration > /debug/tracing/trace_options
+ show: echo funcgraph-duration > /debug/tracing/trace_options
+
+- The overhead field precedes the duration field in case of
+ reached duration thresholds.
+
+ hide: echo nofuncgraph-overhead > /debug/tracing/trace_options
+ show: echo funcgraph-overhead > /debug/tracing/trace_options
+ depends on: funcgraph-duration
+
+ ie:
+
+ 0) | up_write() {
+ 0) 0.646 us | _spin_lock_irqsave();
+ 0) 0.684 us | _spin_unlock_irqrestore();
+ 0) 3.123 us | }
+ 0) 0.548 us | fput();
+ 0) + 58.628 us | }
+
+ [...]
+
+ 0) | putname() {
+ 0) | kmem_cache_free() {
+ 0) 0.518 us | __phys_addr();
+ 0) 1.757 us | }
+ 0) 2.861 us | }
+ 0) ! 115.305 us | }
+ 0) ! 116.402 us | }
+
+ + means that the function exceeded 10 usecs.
+ ! means that the function exceeded 100 usecs.
+
+
+- The task/pid field displays the thread cmdline and pid which
+ executed the function. It is default disabled.
+
+ hide: echo nofuncgraph-proc > /debug/tracing/trace_options
+ show: echo funcgraph-proc > /debug/tracing/trace_options
+
+ ie:
+
+ # tracer: function_graph
+ #
+ # CPU TASK/PID DURATION FUNCTION CALLS
+ # | | | | | | | | |
+ 0) sh-4802 | | d_free() {
+ 0) sh-4802 | | call_rcu() {
+ 0) sh-4802 | | __call_rcu() {
+ 0) sh-4802 | 0.616 us | rcu_process_gp_end();
+ 0) sh-4802 | 0.586 us | check_for_new_grace_period();
+ 0) sh-4802 | 2.899 us | }
+ 0) sh-4802 | 4.040 us | }
+ 0) sh-4802 | 5.151 us | }
+ 0) sh-4802 | + 49.370 us | }
+
+
+- The absolute time field is an absolute timestamp given by the
+ system clock since it started. A snapshot of this time is
+ given on each entry/exit of functions
+
+ hide: echo nofuncgraph-abstime > /debug/tracing/trace_options
+ show: echo funcgraph-abstime > /debug/tracing/trace_options
+
+ ie:
+
+ #
+ # TIME CPU DURATION FUNCTION CALLS
+ # | | | | | | | |
+ 360.774522 | 1) 0.541 us | }
+ 360.774522 | 1) 4.663 us | }
+ 360.774523 | 1) 0.541 us | __wake_up_bit();
+ 360.774524 | 1) 6.796 us | }
+ 360.774524 | 1) 7.952 us | }
+ 360.774525 | 1) 9.063 us | }
+ 360.774525 | 1) 0.615 us | journal_mark_dirty();
+ 360.774527 | 1) 0.578 us | __brelse();
+ 360.774528 | 1) | reiserfs_prepare_for_journal() {
+ 360.774528 | 1) | unlock_buffer() {
+ 360.774529 | 1) | wake_up_bit() {
+ 360.774529 | 1) | bit_waitqueue() {
+ 360.774530 | 1) 0.594 us | __phys_addr();
+
+
+You can put some comments on specific functions by using
+trace_printk() For example, if you want to put a comment inside
+the __might_sleep() function, you just have to include
+<linux/ftrace.h> and call trace_printk() inside __might_sleep()
+
+trace_printk("I'm a comment!\n")
+
+will produce:
+
+ 1) | __might_sleep() {
+ 1) | /* I'm a comment! */
+ 1) 1.449 us | }
+
+
+You might find other useful features for this tracer in the
+following "dynamic ftrace" section such as tracing only specific
+functions or tasks.
+
dynamic ftrace
--------------
If CONFIG_DYNAMIC_FTRACE is set, the system will run with
virtually no overhead when function tracing is disabled. The way
this works is the mcount function call (placed at the start of
-every kernel function, produced by the -pg switch in gcc), starts
-of pointing to a simple return. (Enabling FTRACE will include the
--pg switch in the compiling of the kernel.)
+every kernel function, produced by the -pg switch in gcc),
+starts of pointing to a simple return. (Enabling FTRACE will
+include the -pg switch in the compiling of the kernel.)
At compile time every C file object is run through the
recordmcount.pl script (located in the scripts directory). This
script will process the C object using objdump to find all the
-locations in the .text section that call mcount. (Note, only
-the .text section is processed, since processing other sections
-like .init.text may cause races due to those sections being freed).
+locations in the .text section that call mcount. (Note, only the
+.text section is processed, since processing other sections like
+.init.text may cause races due to those sections being freed).
-A new section called "__mcount_loc" is created that holds references
-to all the mcount call sites in the .text section. This section is
-compiled back into the original object. The final linker will add
-all these references into a single table.
+A new section called "__mcount_loc" is created that holds
+references to all the mcount call sites in the .text section.
+This section is compiled back into the original object. The
+final linker will add all these references into a single table.
On boot up, before SMP is initialized, the dynamic ftrace code
-scans this table and updates all the locations into nops. It also
-records the locations, which are added to the available_filter_functions
-list. Modules are processed as they are loaded and before they are
-executed. When a module is unloaded, it also removes its functions from
-the ftrace function list. This is automatic in the module unload
-code, and the module author does not need to worry about it.
-
-When tracing is enabled, kstop_machine is called to prevent races
-with the CPUS executing code being modified (which can cause the
-CPU to do undesireable things), and the nops are patched back
-to calls. But this time, they do not call mcount (which is just
-a function stub). They now call into the ftrace infrastructure.
+scans this table and updates all the locations into nops. It
+also records the locations, which are added to the
+available_filter_functions list. Modules are processed as they
+are loaded and before they are executed. When a module is
+unloaded, it also removes its functions from the ftrace function
+list. This is automatic in the module unload code, and the
+module author does not need to worry about it.
+
+When tracing is enabled, kstop_machine is called to prevent
+races with the CPUS executing code being modified (which can
+cause the CPU to do undesireable things), and the nops are
+patched back to calls. But this time, they do not call mcount
+(which is just a function stub). They now call into the ftrace
+infrastructure.
One special side-effect to the recording of the functions being
traced is that we can now selectively choose which functions we
-wish to trace and which ones we want the mcount calls to remain as
-nops.
+wish to trace and which ones we want the mcount calls to remain
+as nops.
-Two files are used, one for enabling and one for disabling the tracing
-of specified functions. They are:
+Two files are used, one for enabling and one for disabling the
+tracing of specified functions. They are:
set_ftrace_filter
@@ -1202,8 +1535,8 @@ and
set_ftrace_notrace
-A list of available functions that you can add to these files is listed
-in:
+A list of available functions that you can add to these files is
+listed in:
available_filter_functions
@@ -1240,8 +1573,8 @@ hrtimer_interrupt
sys_nanosleep
-Perhaps this is not enough. The filters also allow simple wild cards.
-Only the following are currently available
+Perhaps this is not enough. The filters also allow simple wild
+cards. Only the following are currently available
<match>* - will match functions that begin with <match>
*<match> - will match functions that end with <match>
@@ -1251,9 +1584,9 @@ These are the only wild cards which are supported.
<match>*<match> will not work.
-Note: It is better to use quotes to enclose the wild cards, otherwise
- the shell may expand the parameters into names of files in the local
- directory.
+Note: It is better to use quotes to enclose the wild cards,
+ otherwise the shell may expand the parameters into names
+ of files in the local directory.
# echo 'hrtimer_*' > /debug/tracing/set_ftrace_filter
@@ -1299,7 +1632,8 @@ This is because the '>' and '>>' act just like they do in bash.
To rewrite the filters, use '>'
To append to the filters, use '>>'
-To clear out a filter so that all functions will be recorded again:
+To clear out a filter so that all functions will be recorded
+again:
# echo > /debug/tracing/set_ftrace_filter
# cat /debug/tracing/set_ftrace_filter
@@ -1331,7 +1665,8 @@ hrtimer_get_res
hrtimer_init_sleeper
-The set_ftrace_notrace prevents those functions from being traced.
+The set_ftrace_notrace prevents those functions from being
+traced.
# echo '*preempt*' '*lock*' > /debug/tracing/set_ftrace_notrace
@@ -1353,13 +1688,75 @@ Produces:
We can see that there's no more lock or preempt tracing.
+
+Dynamic ftrace with the function graph tracer
+---------------------------------------------
+
+Although what has been explained above concerns both the
+function tracer and the function-graph-tracer, there are some
+special features only available in the function-graph tracer.
+
+If you want to trace only one function and all of its children,
+you just have to echo its name into set_graph_function:
+
+ echo __do_fault > set_graph_function
+
+will produce the following "expanded" trace of the __do_fault()
+function:
+
+ 0) | __do_fault() {
+ 0) | filemap_fault() {
+ 0) | find_lock_page() {
+ 0) 0.804 us | find_get_page();
+ 0) | __might_sleep() {
+ 0) 1.329 us | }
+ 0) 3.904 us | }
+ 0) 4.979 us | }
+ 0) 0.653 us | _spin_lock();
+ 0) 0.578 us | page_add_file_rmap();
+ 0) 0.525 us | native_set_pte_at();
+ 0) 0.585 us | _spin_unlock();
+ 0) | unlock_page() {
+ 0) 0.541 us | page_waitqueue();
+ 0) 0.639 us | __wake_up_bit();
+ 0) 2.786 us | }
+ 0) + 14.237 us | }
+ 0) | __do_fault() {
+ 0) | filemap_fault() {
+ 0) | find_lock_page() {
+ 0) 0.698 us | find_get_page();
+ 0) | __might_sleep() {
+ 0) 1.412 us | }
+ 0) 3.950 us | }
+ 0) 5.098 us | }
+ 0) 0.631 us | _spin_lock();
+ 0) 0.571 us | page_add_file_rmap();
+ 0) 0.526 us | native_set_pte_at();
+ 0) 0.586 us | _spin_unlock();
+ 0) | unlock_page() {
+ 0) 0.533 us | page_waitqueue();
+ 0) 0.638 us | __wake_up_bit();
+ 0) 2.793 us | }
+ 0) + 14.012 us | }
+
+You can also expand several functions at once:
+
+ echo sys_open > set_graph_function
+ echo sys_close >> set_graph_function
+
+Now if you want to go back to trace all functions you can clear
+this special filter via:
+
+ echo > set_graph_function
+
+
trace_pipe
----------
-The trace_pipe outputs the same content as the trace file, but the effect
-on the tracing is different. Every read from trace_pipe is consumed.
-This means that subsequent reads will be different. The trace
-is live.
+The trace_pipe outputs the same content as the trace file, but
+the effect on the tracing is different. Every read from
+trace_pipe is consumed. This means that subsequent reads will be
+different. The trace is live.
# echo function > /debug/tracing/current_tracer
# cat /debug/tracing/trace_pipe > /tmp/trace.out &
@@ -1387,38 +1784,45 @@ is live.
bash-4043 [00] 41.267111: select_task_rq_rt <-try_to_wake_up
-Note, reading the trace_pipe file will block until more input is added.
-By changing the tracer, trace_pipe will issue an EOF. We needed
-to set the function tracer _before_ we "cat" the trace_pipe file.
+Note, reading the trace_pipe file will block until more input is
+added. By changing the tracer, trace_pipe will issue an EOF. We
+needed to set the function tracer _before_ we "cat" the
+trace_pipe file.
trace entries
-------------
-Having too much or not enough data can be troublesome in diagnosing
-an issue in the kernel. The file buffer_size_kb is used to modify
-the size of the internal trace buffers. The number listed
-is the number of entries that can be recorded per CPU. To know
-the full size, multiply the number of possible CPUS with the
-number of entries.
+Having too much or not enough data can be troublesome in
+diagnosing an issue in the kernel. The file buffer_size_kb is
+used to modify the size of the internal trace buffers. The
+number listed is the number of entries that can be recorded per
+CPU. To know the full size, multiply the number of possible CPUS
+with the number of entries.
# cat /debug/tracing/buffer_size_kb
1408 (units kilobytes)
-Note, to modify this, you must have tracing completely disabled. To do that,
-echo "nop" into the current_tracer. If the current_tracer is not set
-to "nop", an EINVAL error will be returned.
+Note, to modify this, you must have tracing completely disabled.
+To do that, echo "nop" into the current_tracer. If the
+current_tracer is not set to "nop", an EINVAL error will be
+returned.
# echo nop > /debug/tracing/current_tracer
# echo 10000 > /debug/tracing/buffer_size_kb
# cat /debug/tracing/buffer_size_kb
10000 (units kilobytes)
-The number of pages which will be allocated is limited to a percentage
-of available memory. Allocating too much will produce an error.
+The number of pages which will be allocated is limited to a
+percentage of available memory. Allocating too much will produce
+an error.
# echo 1000000000000 > /debug/tracing/buffer_size_kb
-bash: echo: write error: Cannot allocate memory
# cat /debug/tracing/buffer_size_kb
85
+-----------
+
+More details can be found in the source code, in the
+kernel/tracing/*.c files.
diff --git a/Documentation/trace/kmemtrace.txt b/Documentation/trace/kmemtrace.txt
new file mode 100644
index 00000000000..a956d9b7f94
--- /dev/null
+++ b/Documentation/trace/kmemtrace.txt
@@ -0,0 +1,126 @@
+ kmemtrace - Kernel Memory Tracer
+
+ by Eduard - Gabriel Munteanu
+ <eduard.munteanu@linux360.ro>
+
+I. Introduction
+===============
+
+kmemtrace helps kernel developers figure out two things:
+1) how different allocators (SLAB, SLUB etc.) perform
+2) how kernel code allocates memory and how much
+
+To do this, we trace every allocation and export information to the userspace
+through the relay interface. We export things such as the number of requested
+bytes, the number of bytes actually allocated (i.e. including internal
+fragmentation), whether this is a slab allocation or a plain kmalloc() and so
+on.
+
+The actual analysis is performed by a userspace tool (see section III for
+details on where to get it from). It logs the data exported by the kernel,
+processes it and (as of writing this) can provide the following information:
+- the total amount of memory allocated and fragmentation per call-site
+- the amount of memory allocated and fragmentation per allocation
+- total memory allocated and fragmentation in the collected dataset
+- number of cross-CPU allocation and frees (makes sense in NUMA environments)
+
+Moreover, it can potentially find inconsistent and erroneous behavior in
+kernel code, such as using slab free functions on kmalloc'ed memory or
+allocating less memory than requested (but not truly failed allocations).
+
+kmemtrace also makes provisions for tracing on some arch and analysing the
+data on another.
+
+II. Design and goals
+====================
+
+kmemtrace was designed to handle rather large amounts of data. Thus, it uses
+the relay interface to export whatever is logged to userspace, which then
+stores it. Analysis and reporting is done asynchronously, that is, after the
+data is collected and stored. By design, it allows one to log and analyse
+on different machines and different arches.
+
+As of writing this, the ABI is not considered stable, though it might not
+change much. However, no guarantees are made about compatibility yet. When
+deemed stable, the ABI should still allow easy extension while maintaining
+backward compatibility. This is described further in Documentation/ABI.
+
+Summary of design goals:
+ - allow logging and analysis to be done across different machines
+ - be fast and anticipate usage in high-load environments (*)
+ - be reasonably extensible
+ - make it possible for GNU/Linux distributions to have kmemtrace
+ included in their repositories
+
+(*) - one of the reasons Pekka Enberg's original userspace data analysis
+ tool's code was rewritten from Perl to C (although this is more than a
+ simple conversion)
+
+
+III. Quick usage guide
+======================
+
+1) Get a kernel that supports kmemtrace and build it accordingly (i.e. enable
+CONFIG_KMEMTRACE).
+
+2) Get the userspace tool and build it:
+$ git-clone git://repo.or.cz/kmemtrace-user.git # current repository
+$ cd kmemtrace-user/
+$ ./autogen.sh
+$ ./configure
+$ make
+
+3) Boot the kmemtrace-enabled kernel if you haven't, preferably in the
+'single' runlevel (so that relay buffers don't fill up easily), and run
+kmemtrace:
+# '$' does not mean user, but root here.
+$ mount -t debugfs none /sys/kernel/debug
+$ mount -t proc none /proc
+$ cd path/to/kmemtrace-user/
+$ ./kmemtraced
+Wait a bit, then stop it with CTRL+C.
+$ cat /sys/kernel/debug/kmemtrace/total_overruns # Check if we didn't
+ # overrun, should
+ # be zero.
+$ (Optionally) [Run kmemtrace_check separately on each cpu[0-9]*.out file to
+ check its correctness]
+$ ./kmemtrace-report
+
+Now you should have a nice and short summary of how the allocator performs.
+
+IV. FAQ and known issues
+========================
+
+Q: 'cat /sys/kernel/debug/kmemtrace/total_overruns' is non-zero, how do I fix
+this? Should I worry?
+A: If it's non-zero, this affects kmemtrace's accuracy, depending on how
+large the number is. You can fix it by supplying a higher
+'kmemtrace.subbufs=N' kernel parameter.
+---
+
+Q: kmemtrace_check reports errors, how do I fix this? Should I worry?
+A: This is a bug and should be reported. It can occur for a variety of
+reasons:
+ - possible bugs in relay code
+ - possible misuse of relay by kmemtrace
+ - timestamps being collected unorderly
+Or you may fix it yourself and send us a patch.
+---
+
+Q: kmemtrace_report shows many errors, how do I fix this? Should I worry?
+A: This is a known issue and I'm working on it. These might be true errors
+in kernel code, which may have inconsistent behavior (e.g. allocating memory
+with kmem_cache_alloc() and freeing it with kfree()). Pekka Enberg pointed
+out this behavior may work with SLAB, but may fail with other allocators.
+
+It may also be due to lack of tracing in some unusual allocator functions.
+
+We don't want bug reports regarding this issue yet.
+---
+
+V. See also
+===========
+
+Documentation/kernel-parameters.txt
+Documentation/ABI/testing/debugfs-kmemtrace
+
diff --git a/Documentation/tracers/mmiotrace.txt b/Documentation/trace/mmiotrace.txt
index 5731c67abc5..5731c67abc5 100644
--- a/Documentation/tracers/mmiotrace.txt
+++ b/Documentation/trace/mmiotrace.txt
diff --git a/Documentation/tracepoints.txt b/Documentation/trace/tracepoints.txt
index 6f0a044f5b5..c0e1ceed75a 100644
--- a/Documentation/tracepoints.txt
+++ b/Documentation/trace/tracepoints.txt
@@ -45,8 +45,8 @@ In include/trace/subsys.h :
#include <linux/tracepoint.h>
DECLARE_TRACE(subsys_eventname,
- TPPROTO(int firstarg, struct task_struct *p),
- TPARGS(firstarg, p));
+ TP_PROTO(int firstarg, struct task_struct *p),
+ TP_ARGS(firstarg, p));
In subsys/file.c (where the tracing statement must be added) :
@@ -66,10 +66,10 @@ Where :
- subsys is the name of your subsystem.
- eventname is the name of the event to trace.
-- TPPROTO(int firstarg, struct task_struct *p) is the prototype of the
+- TP_PROTO(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
+- TP_ARGS(firstarg, p) are the parameters names, same as found in the
prototype.
Connecting a function (probe) to a tracepoint is done by providing a
@@ -103,13 +103,14 @@ used to export the defined tracepoints.
* Probe / tracepoint example
-See the example provided in samples/tracepoints/src
+See the example provided in samples/tracepoints
-Compile them with your kernel.
+Compile them with your kernel. They are built during 'make' (not
+'make modules') when CONFIG_SAMPLE_TRACEPOINTS=m.
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
+modprobe tracepoint-sample (insmod order is not important)
+modprobe tracepoint-probe-sample
+cat /proc/tracepoint-sample (returns an expected error)
+rmmod tracepoint-sample tracepoint-probe-sample
dmesg
diff --git a/Documentation/video4linux/pxa_camera.txt b/Documentation/video4linux/pxa_camera.txt
new file mode 100644
index 00000000000..b1137f9a53e
--- /dev/null
+++ b/Documentation/video4linux/pxa_camera.txt
@@ -0,0 +1,125 @@
+ PXA-Camera Host Driver
+ ======================
+
+Constraints
+-----------
+ a) Image size for YUV422P format
+ All YUV422P images are enforced to have width x height % 16 = 0.
+ This is due to DMA constraints, which transfers only planes of 8 byte
+ multiples.
+
+
+Global video workflow
+---------------------
+ a) QCI stopped
+ Initialy, the QCI interface is stopped.
+ When a buffer is queued (pxa_videobuf_ops->buf_queue), the QCI starts.
+
+ b) QCI started
+ More buffers can be queued while the QCI is started without halting the
+ capture. The new buffers are "appended" at the tail of the DMA chain, and
+ smoothly captured one frame after the other.
+
+ Once a buffer is filled in the QCI interface, it is marked as "DONE" and
+ removed from the active buffers list. It can be then requeud or dequeued by
+ userland application.
+
+ Once the last buffer is filled in, the QCI interface stops.
+
+
+DMA usage
+---------
+ a) DMA flow
+ - first buffer queued for capture
+ Once a first buffer is queued for capture, the QCI is started, but data
+ transfer is not started. On "End Of Frame" interrupt, the irq handler
+ starts the DMA chain.
+ - capture of one videobuffer
+ The DMA chain starts transfering data into videobuffer RAM pages.
+ When all pages are transfered, the DMA irq is raised on "ENDINTR" status
+ - finishing one videobuffer
+ The DMA irq handler marks the videobuffer as "done", and removes it from
+ the active running queue
+ Meanwhile, the next videobuffer (if there is one), is transfered by DMA
+ - finishing the last videobuffer
+ On the DMA irq of the last videobuffer, the QCI is stopped.
+
+ b) DMA prepared buffer will have this structure
+
+ +------------+-----+---------------+-----------------+
+ | desc-sg[0] | ... | desc-sg[last] | finisher/linker |
+ +------------+-----+---------------+-----------------+
+
+ This structure is pointed by dma->sg_cpu.
+ The descriptors are used as follows :
+ - desc-sg[i]: i-th descriptor, transfering the i-th sg
+ element to the video buffer scatter gather
+ - finisher: has ddadr=DADDR_STOP, dcmd=ENDIRQEN
+ - linker: has ddadr= desc-sg[0] of next video buffer, dcmd=0
+
+ For the next schema, let's assume d0=desc-sg[0] .. dN=desc-sg[N],
+ "f" stands for finisher and "l" for linker.
+ A typical running chain is :
+
+ Videobuffer 1 Videobuffer 2
+ +---------+----+---+ +----+----+----+---+
+ | d0 | .. | dN | l | | d0 | .. | dN | f |
+ +---------+----+-|-+ ^----+----+----+---+
+ | |
+ +----+
+
+ After the chaining is finished, the chain looks like :
+
+ Videobuffer 1 Videobuffer 2 Videobuffer 3
+ +---------+----+---+ +----+----+----+---+ +----+----+----+---+
+ | d0 | .. | dN | l | | d0 | .. | dN | l | | d0 | .. | dN | f |
+ +---------+----+-|-+ ^----+----+----+-|-+ ^----+----+----+---+
+ | | | |
+ +----+ +----+
+ new_link
+
+ c) DMA hot chaining timeslice issue
+
+ As DMA chaining is done while DMA _is_ running, the linking may be done
+ while the DMA jumps from one Videobuffer to another. On the schema, that
+ would be a problem if the following sequence is encountered :
+
+ - DMA chain is Videobuffer1 + Videobuffer2
+ - pxa_videobuf_queue() is called to queue Videobuffer3
+ - DMA controller finishes Videobuffer2, and DMA stops
+ =>
+ Videobuffer 1 Videobuffer 2
+ +---------+----+---+ +----+----+----+---+
+ | d0 | .. | dN | l | | d0 | .. | dN | f |
+ +---------+----+-|-+ ^----+----+----+-^-+
+ | | |
+ +----+ +-- DMA DDADR loads DDADR_STOP
+
+ - pxa_dma_add_tail_buf() is called, the Videobuffer2 "finisher" is
+ replaced by a "linker" to Videobuffer3 (creation of new_link)
+ - pxa_videobuf_queue() finishes
+ - the DMA irq handler is called, which terminates Videobuffer2
+ - Videobuffer3 capture is not scheduled on DMA chain (as it stopped !!!)
+
+ Videobuffer 1 Videobuffer 2 Videobuffer 3
+ +---------+----+---+ +----+----+----+---+ +----+----+----+---+
+ | d0 | .. | dN | l | | d0 | .. | dN | l | | d0 | .. | dN | f |
+ +---------+----+-|-+ ^----+----+----+-|-+ ^----+----+----+---+
+ | | | |
+ +----+ +----+
+ new_link
+ DMA DDADR still is DDADR_STOP
+
+ - pxa_camera_check_link_miss() is called
+ This checks if the DMA is finished and a buffer is still on the
+ pcdev->capture list. If that's the case, the capture will be restarted,
+ and Videobuffer3 is scheduled on DMA chain.
+ - the DMA irq handler finishes
+
+ Note: if DMA stops just after pxa_camera_check_link_miss() reads DDADR()
+ value, we have the guarantee that the DMA irq handler will be called back
+ when the DMA will finish the buffer, and pxa_camera_check_link_miss() will
+ be called again, to reschedule Videobuffer3.
+
+--
+Author: Robert Jarzmik <robert.jarzmik@free.fr>
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index a31177390e5..854808b67fa 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -90,7 +90,7 @@ up before calling v4l2_device_register then it will be untouched. If dev is
NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register.
The first 'dev' argument is normally the struct device pointer of a pci_dev,
-usb_device or platform_device. It is rare for dev to be NULL, but it happens
+usb_interface or platform_device. It is rare for dev to be NULL, but it happens
with ISA devices or when one device creates multiple PCI devices, thus making
it impossible to associate v4l2_dev with a particular parent.
@@ -351,17 +351,6 @@ And this to go from an i2c_client to a v4l2_subdev struct:
struct v4l2_subdev *sd = i2c_get_clientdata(client);
-Finally you need to make a command function to make driver->command()
-call the right subdev_ops functions:
-
-static int subdev_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
-If driver->command is never used then you can leave this out. Eventually the
-driver->command usage should be removed from v4l.
-
Make sure to call v4l2_device_unregister_subdev(sd) when the remove() callback
is called. This will unregister the sub-device from the bridge driver. It is
safe to call this even if the sub-device was never registered.
@@ -375,14 +364,12 @@ from the remove() callback ensures that this is always done correctly.
The bridge driver also has some helper functions it can use:
-struct v4l2_subdev *sd = v4l2_i2c_new_subdev(adapter, "module_foo", "chipid", 0x36);
+struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter,
+ "module_foo", "chipid", 0x36);
This loads the given module (can be NULL if no module needs to be loaded) and
calls i2c_new_device() with the given i2c_adapter and chip/address arguments.
-If all goes well, then it registers the subdev with the v4l2_device. It gets
-the v4l2_device by calling i2c_get_adapdata(adapter), so you should make sure
-to call i2c_set_adapdata(adapter, v4l2_device) when you setup the i2c_adapter
-in your driver.
+If all goes well, then it registers the subdev with the v4l2_device.
You can also use v4l2_i2c_new_probed_subdev() which is very similar to
v4l2_i2c_new_subdev(), except that it has an array of possible I2C addresses
diff --git a/Documentation/vm/00-INDEX b/Documentation/vm/00-INDEX
index 2131b00b63f..2f77ced35df 100644
--- a/Documentation/vm/00-INDEX
+++ b/Documentation/vm/00-INDEX
@@ -1,5 +1,7 @@
00-INDEX
- this file.
+active_mm.txt
+ - An explanation from Linus about tsk->active_mm vs tsk->mm.
balance
- various information on memory balancing.
hugetlbpage.txt
diff --git a/Documentation/vm/active_mm.txt b/Documentation/vm/active_mm.txt
new file mode 100644
index 00000000000..4ee1f643d89
--- /dev/null
+++ b/Documentation/vm/active_mm.txt
@@ -0,0 +1,83 @@
+List: linux-kernel
+Subject: Re: active_mm
+From: Linus Torvalds <torvalds () transmeta ! com>
+Date: 1999-07-30 21:36:24
+
+Cc'd to linux-kernel, because I don't write explanations all that often,
+and when I do I feel better about more people reading them.
+
+On Fri, 30 Jul 1999, David Mosberger wrote:
+>
+> Is there a brief description someplace on how "mm" vs. "active_mm" in
+> the task_struct are supposed to be used? (My apologies if this was
+> discussed on the mailing lists---I just returned from vacation and
+> wasn't able to follow linux-kernel for a while).
+
+Basically, the new setup is:
+
+ - we have "real address spaces" and "anonymous address spaces". The
+ difference is that an anonymous address space doesn't care about the
+ user-level page tables at all, so when we do a context switch into an
+ anonymous address space we just leave the previous address space
+ active.
+
+ The obvious use for a "anonymous address space" is any thread that
+ doesn't need any user mappings - all kernel threads basically fall into
+ this category, but even "real" threads can temporarily say that for
+ some amount of time they are not going to be interested in user space,
+ and that the scheduler might as well try to avoid wasting time on
+ switching the VM state around. Currently only the old-style bdflush
+ sync does that.
+
+ - "tsk->mm" points to the "real address space". For an anonymous process,
+ tsk->mm will be NULL, for the logical reason that an anonymous process
+ really doesn't _have_ a real address space at all.
+
+ - however, we obviously need to keep track of which address space we
+ "stole" for such an anonymous user. For that, we have "tsk->active_mm",
+ which shows what the currently active address space is.
+
+ The rule is that for a process with a real address space (ie tsk->mm is
+ non-NULL) the active_mm obviously always has to be the same as the real
+ one.
+
+ For a anonymous process, tsk->mm == NULL, and tsk->active_mm is the
+ "borrowed" mm while the anonymous process is running. When the
+ anonymous process gets scheduled away, the borrowed address space is
+ returned and cleared.
+
+To support all that, the "struct mm_struct" now has two counters: a
+"mm_users" counter that is how many "real address space users" there are,
+and a "mm_count" counter that is the number of "lazy" users (ie anonymous
+users) plus one if there are any real users.
+
+Usually there is at least one real user, but it could be that the real
+user exited on another CPU while a lazy user was still active, so you do
+actually get cases where you have a address space that is _only_ used by
+lazy users. That is often a short-lived state, because once that thread
+gets scheduled away in favour of a real thread, the "zombie" mm gets
+released because "mm_users" becomes zero.
+
+Also, a new rule is that _nobody_ ever has "init_mm" as a real MM any
+more. "init_mm" should be considered just a "lazy context when no other
+context is available", and in fact it is mainly used just at bootup when
+no real VM has yet been created. So code that used to check
+
+ if (current->mm == &init_mm)
+
+should generally just do
+
+ if (!current->mm)
+
+instead (which makes more sense anyway - the test is basically one of "do
+we have a user context", and is generally done by the page fault handler
+and things like that).
+
+Anyway, I put a pre-patch-2.3.13-1 on ftp.kernel.org just a moment ago,
+because it slightly changes the interfaces to accomodate the alpha (who
+would have thought it, but the alpha actually ends up having one of the
+ugliest context switch codes - unlike the other architectures where the MM
+and register state is separate, the alpha PALcode joins the two, and you
+need to switch both together).
+
+(From http://marc.info/?l=linux-kernel&m=93337278602211&w=2)
diff --git a/Documentation/vm/numa_memory_policy.txt b/Documentation/vm/numa_memory_policy.txt
index 6aaaeb38730..be45dbb9d7f 100644
--- a/Documentation/vm/numa_memory_policy.txt
+++ b/Documentation/vm/numa_memory_policy.txt
@@ -8,7 +8,8 @@ The current memory policy support was added to Linux 2.6 around May 2004. This
document attempts to describe the concepts and APIs of the 2.6 memory policy
support.
-Memory policies should not be confused with cpusets (Documentation/cpusets.txt)
+Memory policies should not be confused with cpusets
+(Documentation/cgroups/cpusets.txt)
which is an administrative mechanism for restricting the nodes from which
memory may be allocated by a set of processes. Memory policies are a
programming interface that a NUMA-aware application can take advantage of. When
diff --git a/Documentation/vm/page_migration b/Documentation/vm/page_migration
index d5fdfd34bba..6513fe2d90b 100644
--- a/Documentation/vm/page_migration
+++ b/Documentation/vm/page_migration
@@ -37,7 +37,8 @@ locations.
Larger installations usually partition the system using cpusets into
sections of nodes. Paul Jackson has equipped cpusets with the ability to
-move pages when a task is moved to another cpuset (See ../cpusets.txt).
+move pages when a task is moved to another cpuset (See
+Documentation/cgroups/cpusets.txt).
Cpusets allows the automation of process locality. If a task is moved to
a new cpuset then also all its pages are moved with it so that the
performance of the process does not sink dramatically. Also the pages
diff --git a/Documentation/vm/unevictable-lru.txt b/Documentation/vm/unevictable-lru.txt
index 0706a7282a8..2d70d0d9510 100644
--- a/Documentation/vm/unevictable-lru.txt
+++ b/Documentation/vm/unevictable-lru.txt
@@ -1,588 +1,691 @@
-
-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
+ ==============================
+ UNEVICTABLE LRU INFRASTRUCTURE
+ ==============================
+
+========
+CONTENTS
+========
+
+ (*) The Unevictable LRU
+
+ - The unevictable page list.
+ - Memory control group interaction.
+ - Marking address spaces unevictable.
+ - Detecting Unevictable Pages.
+ - vmscan's handling of unevictable pages.
+
+ (*) mlock()'d pages.
+
+ - History.
+ - Basic management.
+ - mlock()/mlockall() system call handling.
+ - Filtering special vmas.
+ - munlock()/munlockall() system call handling.
+ - Migrating mlocked pages.
+ - mmap(MAP_LOCKED) system call handling.
+ - munmap()/exit()/exec() system call handling.
+ - try_to_unmap().
+ - try_to_munlock() reverse map scan.
+ - Page reclaim in shrink_*_list().
+
+
+============
+INTRODUCTION
+============
+
+This document describes the Linux memory manager's "Unevictable LRU"
+infrastructure and the use of this 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?".
+
+
+===================
+THE UNEVICTABLE LRU
+===================
+
+The Unevictable LRU facility 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
+memory x86_64 systems.
+
+To illustrate this with an example, a non-NUMA 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 list addresses the following classes of unevictable pages:
+
+ (*) Those owned by ramfs.
+
+ (*) Those mapped into SHM_LOCK'd shared memory regions.
+
+ (*) Those mapped into VM_LOCKED [mlock()ed] VMAs.
+
+The infrastructure may also 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 PAGE 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.
+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 list is compile-time 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]
+ (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 elsewhere 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
+ itself.
-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 list does not differentiate between file-backed and anonymous,
+swap-backed pages. This differentiation is only important while the pages are,
+in fact, evictable.
-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 list benefits from the "arrayification" of the per-zone LRU
+lists and statistics originally proposed and posted by Christoph Lameter.
-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. This allows us to prevent the 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.
-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.
+MEMORY CONTROL GROUP INTERACTION
+--------------------------------
-Unevictable LRU and Memory Controller Interaction
+The unevictable LRU facility interacts with the memory control group [aka
+memory controller; see Documentation/cgroups/memory.txt] by extending the
+lru_list enum.
+
+The memory controller data structure automatically gets a per-zone unevictable
+list as a result of the "arrayification" of the per-zone LRU lists (one per
+lru_list enum element). The memory controller tracks the movement of pages to
+and from the unevictable list.
-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
+effects:
+
+ (1) 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.
+
+ (2) 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.
+
+
+MARKING ADDRESS SPACES UNEVICTABLE
+----------------------------------
+
+For facilities such as ramfs none of the pages attached to the address space
+may be evicted. To prevent eviction of any such pages, the AS_UNEVICTABLE
+address space flag is provided, and this can be manipulated by a filesystem
+using a number of wrapper functions:
+
+ (*) void mapping_set_unevictable(struct address_space *mapping);
+
+ Mark the address space as being completely unevictable.
+
+ (*) void mapping_clear_unevictable(struct address_space *mapping);
+
+ Mark the address space as being evictable.
+
+ (*) int mapping_unevictable(struct address_space *mapping);
+
+ Query the address space, and return true if it is completely
+ unevictable.
+
+These are currently used in two places in the kernel:
+
+ (1) By ramfs to mark the address spaces of its inodes when they are created,
+ and this mark remains for the life of the inode.
+
+ (2) By SYSV SHM to mark SHM_LOCK'd address spaces until SHM_UNLOCK is called.
+
+ Note that SHM_LOCK is not required to page in the locked pages if they're
+ swapped out; the application must touch the pages manually if it wants to
+ ensure they're in memory.
+
+
+DETECTING UNEVICTABLE PAGES
+---------------------------
+
+The function page_evictable() in vmscan.c determines whether a page is
+evictable or not using the query function outlined above [see section "Marking
+address spaces unevictable"] to check the AS_UNEVICTABLE flag.
+
+For address spaces that are so marked after being populated (as SHM regions
+might be), the lock action (eg: SHM_LOCK) can be lazy, and need not populate
+the page tables for the region as does, for example, mlock(), nor need it make
+any special effort to push any pages in the SHM_LOCK'd area to the unevictable
+list. Instead, vmscan will do this if and when it encounters the pages during
+a reclamation scan.
+
+On an unlock action (such as SHM_UNLOCK), the unlocker (eg: shmctl()) must scan
+the pages in the region and "rescue" them from the unevictable list if no other
+condition is keeping them unevictable. If an unevictable region is destroyed,
+the pages are also "rescued" from the unevictable list in the process of
+freeing them.
+
+page_evictable() also checks for mlocked pages by testing an additional page
+flag, PG_mlocked (as wrapped by PageMlocked()). 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.
+VM_LOCKED VMAs.
-Unevictable Pages and Vmscan [shrink_*_list()]
+VMSCAN'S HANDLING OF UNEVICTABLE PAGES
+--------------------------------------
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
+list at mlock() or mmap() time, vmscan will not encounter the pages until they
+have become evictable again (via munlock() for example) 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 PG_mlocked. 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.
+map in try_to_unmap(). If try_to_unmap() returns SWAP_MLOCK,
+shrink_page_list() will cull the page at that point.
-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().
+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 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
+=============
+MLOCKED PAGES
+=============
-The "Unevictable Mlocked Pages" infrastructure is based on work originally
+The unevictable page list is also useful for mlock(), in addition to ramfs and
+SYSV SHM. Note that mlock() is only available in CONFIG_MMU=y situations; in
+NOMMU situations, all mappings are effectively mlocked.
+
+
+HISTORY
+-------
+
+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() when attempting to
- reclaim a page in a VM_LOCKED vma via try_to_unmap().
-
-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
+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, and 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.
+
+
+BASIC MANAGEMENT
+----------------
+
+mlocked pages - pages mapped into a VM_LOCKED VMA - are a class of unevictable
+pages. When such a page has been "noticed" by the memory management subsystem,
+the page is marked with the PG_mlocked flag. This can be manipulated using the
+PageMlocked() functions.
+
+A PG_mlocked page will be placed on the unevictable list when it is added to
+the LRU. Such 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 mmapping a region with the
+ MAP_LOCKED flag;
+
+ (3) mmapping a region in a task that has called mlockall() with the MCL_FUTURE
+ flag
+
+ (4) in the fault path, if mlocked pages are "culled" in the fault path,
+ and when a VM_LOCKED stack segment is expanded; or
+
+ (5) as mentioned above, in vmscan:shrink_page_list() when attempting to
+ reclaim a page in a VM_LOCKED VMA via try_to_unmap()
+
+all of which result in the VM_LOCKED flag being set for the VMA if it doesn't
+already have it set.
+
+mlocked pages become unlocked and rescued from the unevictable list when:
+
+ (1) mapped in a range unlocked via the munlock()/munlockall() system calls;
+
+ (2) munmap()'d 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 mmapped file;
+ or
+
+ (4) before a page is COW'd in a VM_LOCKED VMA.
+
+
+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(),
+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
+is used for both mlocking and munlocking 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, and mlock_fixup() simply returns.
+
+If the VMA passes some filtering as described in "Filtering Special 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 okay. 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.
+migrated out from under us, while we're trying to mlock it. To detect this,
+__mlock_vma_pages_range() checks 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.
+In the worst case, this will result in a 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() will call 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() need do nothing
+more.
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
+at that time. If the isolate_lru_page() succeeds, mlock_vma_page() will put
+back the page - by calling putback_lru_page() - which will notice that the page
+is now mlocked and divert the page to the zone's unevictable 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.
+it later if and when it attempts to reclaim the page.
-Mlocked Pages: Filtering Special Vmas
+FILTERING SPECIAL VMAS
+----------------------
-mlock_fixup() filters several classes of "special" vmas:
+mlock_fixup() filters several classes of "special" VMAs:
-1) vmas with VM_IO|VM_PFNMAP set are skipped entirely. The pages behind
+1) VMAs with VM_IO or 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
+ 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
+ neither 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 or VM_RESERVED are generally userspace 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
+ 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
+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
+munlock(), munmap() or task exit. Neither does mlock_fixup() account these
+VMAs against the task's "locked_vm".
+
+
+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 munlocked 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--
+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
+Because the VMA access protections could have been changed to PROT_NONE after
faulting in and mlocking pages, get_user_pages() was unreliable for visiting
-these pages for munlocking. Because we don't want to leave pages mlocked(),
+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.
+fetching the pages - all of which should be resident as a result of previous
+mlocking.
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.
+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
+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
+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
+This is fine, because we'll catch it later if and if vmscan tries to reclaim
+the page. This should be relatively rare.
+
+
+MIGRATING MLOCKED PAGES
+-----------------------
+
+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 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
+PG_mlocked and PG_unevictable 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 and 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.
+
+To complete 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.
+
+
+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()
+that a region of memory be mlocked supplying the MAP_LOCKED flag to 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.
+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.
+mlock_vma_pages_range() filters VMAs like mlock_fixup(), as described above in
+"Filtering Special 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
+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
+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,
+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.
+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
+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.
+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
+munmap() handler and task address space call tear down function
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
+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()
+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.
-
+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.]
+try_to_unmap()
+--------------
-Pages can, of course, be mapped into multiple vmas. Some of these vmas may
+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.
+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 munlocking 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 section "vmscan's handling of unevictable pages". To handle this situation,
+try_to_unmap() checks 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.
-
-When munlock_vma_page()--see "Mlocked Pages: munlock()/munlockall()
-System Call Handling" above--tries to munlock a page, it needs 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().
+migration, with the argument page locked and isolated from the LRU. 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_anon() attempts to acquire in read mode the mmap semphore of
+ the mm_struct to which the VMA belongs. If this is successful, it will
+ mlock the page via mlock_vma_page() - we wouldn't have gotten to
+ try_to_unmap_anon() 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_anon() will
+ return SWAP_AGAIN.
+
+ (*) try_to_unmap_file() - linear mappings
+
+ Unmapping of a mapped file page works the same as for anonymous mappings,
+ except that the scan visits all VMAs that map the page's index/page offset
+ in the page's mapping's reverse map priority search tree. It also visits
+ 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_file() 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.
+
+ 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) will be 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.
+
+
+try_to_munlock() REVERSE MAP SCAN
+---------------------------------
+
+ [!] TODO/FIXME: a better name might be page_mlocked() - analogous to the
+ page_referenced() reverse map walker.
+
+When munlock_vma_page() [see section "munlock()/munlockall() System Call
+Handling" above] tries to munlock a page, it needs 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
+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.
-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.
-
-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.
+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 page's
+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() might be called a great many times when munlocking a
+large region or tearing down a large address space that has been mlocked via
+mlockall(), overall this is a fairly rare event.
+
+
+PAGE RECLAIM IN shrink_*_list()
+-------------------------------
+
+shrink_active_list() culls any obviously unevictable pages - i.e.
+!page_evictable(page, NULL) - diverting these to the unevictable 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.
+ (1) ramfs pages that have been placed on the LRU lists when first allocated.
+
+ (2) SHM_LOCK'd 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_LOCK'ing
+ the segment.
-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) Mlocked pages that could not be isolated from the lru and moved to the
- unevictable list in mlock_vma_page().
+ (4) 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.
-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 diverts any unevictable pages that it finds on the
+inactive lists to the appropriate zone's unevictable list.
-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_inactive_list() should only see SHM_LOCK'd pages that became SHM_LOCK'd
+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(). Pages mapped into
-VM_LOCKED vmas but without PG_mlocked set will make it all the way to
+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.
diff --git a/Documentation/x86/x86_64/fake-numa-for-cpusets b/Documentation/x86/x86_64/fake-numa-for-cpusets
index 33bb5665599..0f11d9becb0 100644
--- a/Documentation/x86/x86_64/fake-numa-for-cpusets
+++ b/Documentation/x86/x86_64/fake-numa-for-cpusets
@@ -7,7 +7,8 @@ you can create fake NUMA nodes that represent contiguous chunks of memory and
assign them to cpusets and their attached tasks. This is a way of limiting the
amount of system memory that are available to a certain class of tasks.
-For more information on the features of cpusets, see Documentation/cpusets.txt.
+For more information on the features of cpusets, see
+Documentation/cgroups/cpusets.txt.
There are a number of different configurations you can use for your needs. For
more information on the numa=fake command line option and its various ways of
configuring fake nodes, see Documentation/x86/x86_64/boot-options.txt.
@@ -32,7 +33,7 @@ A machine may be split as follows with "numa=fake=4*512," as reported by dmesg:
On node 3 totalpages: 131072
Now following the instructions for mounting the cpusets filesystem from
-Documentation/cpusets.txt, you can assign fake nodes (i.e. contiguous memory
+Documentation/cgroups/cpusets.txt, you can assign fake nodes (i.e. contiguous memory
address spaces) to individual cpusets:
[root@xroads /]# mkdir exampleset
diff --git a/MAINTAINERS b/MAINTAINERS
index ebaf77ebd8b..0cb20d82169 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -72,7 +72,6 @@ M: Mail patches to
L: Mailing list that is relevant to this area
W: Web-page with status/info
T: SCM tree type and location. Type is one of: git, hg, quilt.
-F: Applicable files and/or directories
S: Status, one of the following:
Supported: Someone is actually paid to look after this.
@@ -85,23 +84,40 @@ S: Status, one of the following:
it has been replaced by a better system and you
should be using that.
+F: Files and directories with wildcard patterns.
+ A trailing slash includes all files and subdirectory files.
+ F: drivers/net/ all files in and below drivers/net
+ F: drivers/net/* all files in drivers/net, but not below
+ F: */net/* all files in "any top level directory"/net
+ One pattern per line. Multiple F: lines acceptable.
+X: Files and directories that are NOT maintained, same rules as F:
+ Files exclusions are tested before file matches.
+ Can be useful for excluding a specific subdirectory, for instance:
+ F: net/
+ X: net/ipv6/
+ matches all files in and below net excluding net/ipv6/
+
3C505 NETWORK DRIVER
P: Philip Blundell
M: philb@gnu.org
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/3c505*
3C59X NETWORK DRIVER
P: Steffen Klassert
M: klassert@mathematik.tu-chemnitz.de
L: netdev@vger.kernel.org
S: Maintained
+F: Documentation/networking/vortex.txt
+F: drivers/net/3c59x.c
3CR990 NETWORK DRIVER
P: David Dillow
M: dave@thedillows.org
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/typhoon*
3W-9XXX SATA-RAID CONTROLLER DRIVER
P: Adam Radford
@@ -109,6 +125,7 @@ M: linuxraid@amcc.com
L: linux-scsi@vger.kernel.org
W: http://www.amcc.com
S: Supported
+F: drivers/scsi/3w-9xxx*
3W-XXXX ATA-RAID CONTROLLER DRIVER
P: Adam Radford
@@ -116,35 +133,43 @@ M: linuxraid@amcc.com
L: linux-scsi@vger.kernel.org
W: http://www.amcc.com
S: Supported
+F: drivers/scsi/3w-xxxx*
53C700 AND 53C700-66 SCSI DRIVER
P: James E.J. Bottomley
M: James.Bottomley@HansenPartnership.com
L: linux-scsi@vger.kernel.org
S: Maintained
+F: drivers/scsi/53c700*
6PACK NETWORK DRIVER FOR AX.25
P: Andreas Koensgen
M: ajk@iehk.rwth-aachen.de
L: linux-hams@vger.kernel.org
S: Maintained
+F: drivers/net/hamradio/6pack.c
8169 10/100/1000 GIGABIT ETHERNET DRIVER
P: Francois Romieu
M: romieu@fr.zoreil.com
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/r8169.c
8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
L: linux-serial@vger.kernel.org
W: http://serial.sourceforge.net
S: Orphan
+F: drivers/serial/8250*
+F: include/linux/serial_8250.h
8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
P: Paul Gortmaker
M: p_gortmaker@yahoo.com
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/*8390*
+F: drivers/net/ax88796.c
9P FILE SYSTEM
P: Eric Van Hensbergen
@@ -155,14 +180,17 @@ P: Latchesar Ionkov
M: lucho@ionkov.net
L: v9fs-developer@lists.sourceforge.net
W: http://swik.net/v9fs
-T: git kernel.org:/pub/scm/linux/kernel/ericvh/v9fs.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/ericvh/v9fs.git
S: Maintained
+F: Documentation/filesystems/9p.txt
+F: fs/9p/
A2232 SERIAL BOARD DRIVER
P: Enver Haase
M: A2232@gmx.net
L: linux-m68k@lists.linux-m68k.org
S: Maintained
+F: drivers/char/ser_a2232*
AACRAID SCSI RAID DRIVER
P: Adaptec OEM Raid Solutions
@@ -170,24 +198,29 @@ M: aacraid@adaptec.com
L: linux-scsi@vger.kernel.org
W: http://www.adaptec.com/
S: Supported
+F: Documentation/scsi/aacraid.txt
+F: drivers/scsi/aacraid/
ABIT UGURU 1,2 HARDWARE MONITOR DRIVER
P: Hans de Goede
M: j.w.r.degoede@hhs.nl
L: lm-sensors@lm-sensors.org
S: Maintained
+F: drivers/hwmon/abituguru.c
ABIT UGURU 3 HARDWARE MONITOR DRIVER
P: Alistair John Strachan
M: alistair@devzero.co.uk
L: lm-sensors@lm-sensors.org
S: Maintained
+F: drivers/hwmon/abituguru3.c
ACENIC DRIVER
P: Jes Sorensen
M: jes@trained-monkey.org
L: linux-acenic@sunsite.dk
S: Maintained
+F: drivers/net/acenic*
ACER WMI LAPTOP EXTRAS
P: Carlos Corbacho
@@ -195,14 +228,18 @@ M: carlos@strangeworlds.co.uk
L: aceracpi@googlegroups.com (subscribers-only)
W: http://code.google.com/p/aceracpi
S: Maintained
+F: drivers/platform/x86/acer-wmi.c
ACPI
P: Len Brown
M: lenb@kernel.org
L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/
-T: git kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
S: Supported
+F: drivers/acpi/
+F: drivers/pnp/pnpacpi/
+F: include/linux/acpi.h
ACPI BATTERY DRIVERS
P: Alexey Starikovskiy
@@ -210,6 +247,8 @@ M: astarikovskiy@suse.de
L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/
S: Supported
+F: drivers/acpi/battery.c
+F: drivers/acpi/*sbs*
ACPI EC DRIVER
P: Alexey Starikovskiy
@@ -217,6 +256,7 @@ M: astarikovskiy@suse.de
L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/
S: Supported
+F: drivers/acpi/ec.c
ACPI FAN DRIVER
P: Zhang Rui
@@ -224,12 +264,14 @@ M: rui.zhang@intel.com
L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/
S: Supported
+F: drivers/acpi/fan.c
ACPI PCI HOTPLUG DRIVER
P: Kristen Carlson Accardi
M: kristen.c.accardi@intel.com
L: linux-pci@vger.kernel.org
S: Supported
+F: drivers/pci/hotplug/acpi*
ACPI THERMAL DRIVER
P: Zhang Rui
@@ -237,6 +279,7 @@ M: rui.zhang@intel.com
L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/
S: Supported
+F: drivers/acpi/*thermal*
ACPI VIDEO DRIVER
P: Zhang Rui
@@ -244,6 +287,7 @@ M: rui.zhang@intel.com
L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/
S: Supported
+F: drivers/acpi/video.c
ACPI WMI DRIVER
P: Carlos Corbacho
@@ -251,6 +295,7 @@ M: carlos@strangeworlds.co.uk
L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/
S: Maintained
+F: drivers/platform/x86/wmi.c
AD1889 ALSA SOUND DRIVER
P: Kyle McMartin
@@ -260,77 +305,99 @@ M: T-Bone@parisc-linux.org
W: http://wiki.parisc-linux.org/AD1889
L: linux-parisc@vger.kernel.org
S: Maintained
+F: sound/pci/ad1889.*
ADM1025 HARDWARE MONITOR DRIVER
P: Jean Delvare
M: khali@linux-fr.org
L: lm-sensors@lm-sensors.org
S: Maintained
+F: Documentation/hwmon/adm1025
+F: drivers/hwmon/adm1025.c
ADM1029 HARDWARE MONITOR DRIVER
P: Corentin Labbe
M: corentin.labbe@geomatys.fr
L: lm-sensors@lm-sensors.org
S: Maintained
+F: drivers/hwmon/adm1029.c
ADM8211 WIRELESS DRIVER
P: Michael Wu
M: flamingice@sourmilk.net
L: linux-wireless@vger.kernel.org
W: http://linuxwireless.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git
S: Maintained
+F: drivers/net/wireless/adm8211.*
ADT746X FAN DRIVER
P: Colin Leroy
M: colin@colino.net
S: Maintained
+F: drivers/macintosh/therm_adt746x.c
ADVANSYS SCSI DRIVER
P: Matthew Wilcox
M: matthew@wil.cx
L: linux-scsi@vger.kernel.org
S: Maintained
+F: Documentation/scsi/advansys.txt
+F: drivers/scsi/advansys.c
AEDSP16 DRIVER
P: Riccardo Facchetti
M: fizban@tin.it
S: Maintained
+F: sound/oss/aedsp16.c
AFFS FILE SYSTEM
P: Roman Zippel
M: zippel@linux-m68k.org
S: Maintained
+F: Documentation/filesystems/affs.txt
+F: fs/affs/
AFS FILESYSTEM & AF_RXRPC SOCKET DOMAIN
P: David Howells
M: dhowells@redhat.com
L: linux-afs@lists.infradead.org
S: Supported
+F: fs/afs/
+F: include/net/af_rxrpc.h
+F: net/rxrpc/af_rxrpc.c
AGPGART DRIVER
P: David Airlie
M: airlied@linux.ie
-T: git kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6.git
S: Maintained
+F: drivers/char/agp/
+F: include/linux/agp*
AHA152X SCSI DRIVER
P: Juergen E. Fischer
-M: Juergen Fischer <fischer@norbit.de>
+M: fischer@norbit.de
L: linux-scsi@vger.kernel.org
S: Maintained
+F: drivers/scsi/aha152x*
+F: drivers/scsi/pcmcia/aha152x*
AIC7XXX / AIC79XX SCSI DRIVER
P: Hannes Reinecke
M: hare@suse.de
L: linux-scsi@vger.kernel.org
S: Maintained
+F: drivers/scsi/aic7xxx/
+F: drivers/scsi/aic7xxx_old/
AIO
P: Benjamin LaHaise
M: bcrl@kvack.org
L: linux-aio@kvack.org
S: Supported
+F: fs/aio.c
+F: include/linux/*aio*.h
ALCATEL SPEEDTOUCH USB DRIVER
P: Duncan Sands
@@ -338,17 +405,22 @@ M: duncan.sands@free.fr
L: linux-usb@vger.kernel.org
W: http://www.linux-usb.org/SpeedTouch/
S: Maintained
+F: drivers/usb/atm/speedtch.c
+F: drivers/usb/atm/usbatm.c
ALCHEMY AU1XX0 MMC DRIVER
P: Manuel Lauss
M: manuel.lauss@gmail.com
S: Maintained
+F: drivers/mmc/host/au1xmmc.c
ALI1563 I2C DRIVER
P: Rudolf Marek
M: r.marek@assembler.cz
L: linux-i2c@vger.kernel.org
S: Maintained
+F: Documentation/i2c/busses/i2c-ali1563
+F: drivers/i2c/busses/i2c-ali1563.c
ALPHA PORT
P: Richard Henderson
@@ -358,31 +430,41 @@ P: Ivan Kokshaysky
M: ink@jurassic.park.msu.ru
S: Maintained for 2.4; PCI support for 2.6.
L: linux-alpha@vger.kernel.org
+F: arch/alpha/
AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
P: Thomas Dahlmann
M: thomas.dahlmann@amd.com
L: linux-geode@lists.infradead.org (moderated for non-subscribers)
S: Supported
+F: drivers/usb/gadget/amd5536udc.*
AMD GEODE PROCESSOR/CHIPSET SUPPORT
P: Jordan Crouse
L: linux-geode@lists.infradead.org (moderated for non-subscribers)
W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
S: Supported
+F: arch/x86/kernel/geode_32.c
+F: drivers/char/hw_random/geode-rng.c
+F: drivers/crypto/geode*
+F: drivers/video/geode/
+F: arch/x86/include/asm/geode.h
AMD IOMMU (AMD-VI)
P: Joerg Roedel
M: joerg.roedel@amd.com
L: iommu@lists.linux-foundation.org
-T: git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu.git
S: Supported
+F: arch/x86/kernel/amd_iommu*.c
+F: arch/x86/include/asm/amd_iommu*.h
AMD MICROCODE UPDATE SUPPORT
-P: Andreas Herrmann
-M: andeas.herrmann3@amd.com
-L: amd64-microcode@amd64.org
-S: Supported
+P: Andreas Herrmann
+M: andreas.herrmann3@amd.com
+L: amd64-microcode@amd64.org
+S: Supported
+F: arch/x86/kernel/microcode_amd.c
AMS (Apple Motion Sensor) DRIVER
P: Stelian Pop
@@ -390,6 +472,7 @@ M: stelian@popies.net
P: Michael Hanselmann
M: linux-kernel@hansmi.ch
S: Supported
+F: drivers/hwmon/ams/
AMSO1100 RNIC DRIVER
P: Tom Tucker
@@ -398,6 +481,7 @@ P: Steve Wise
M: swise@opengridcomputing.com
L: general@lists.openfabrics.org
S: Maintained
+F: drivers/infiniband/hw/amso1100/
AOA (Apple Onboard Audio) ALSA DRIVER
P: Johannes Berg
@@ -405,6 +489,7 @@ M: johannes@sipsolutions.net
L: linuxppc-dev@ozlabs.org
L: alsa-devel@alsa-project.org (subscribers-only)
S: Maintained
+F: sound/aoa/
APM DRIVER
P: Stephen Rothwell
@@ -412,48 +497,63 @@ M: sfr@canb.auug.org.au
L: linux-laptop@vger.kernel.org
W: http://www.canb.auug.org.au/~sfr/
S: Supported
+F: arch/x86/kernel/apm_32.c
+F: include/linux/apm_bios.h
APPLE BCM5974 MULTITOUCH DRIVER
P: Henrik Rydberg
M: rydberg@euromail.se
L: linux-input@vger.kernel.org
S: Maintained
+F: drivers/input/mouse/bcm5974.c
APPLE SMC DRIVER
P: Nicolas Boichat
M: nicolas@boichat.ch
L: mactel-linux-devel@lists.sourceforge.net
S: Maintained
+F: drivers/hwmon/applesmc.c
APPLETALK NETWORK LAYER
P: Arnaldo Carvalho de Melo
M: acme@ghostprotocols.net
S: Maintained
+F: drivers/net/appletalk/
+F: net/appletalk/
APPLETOUCH TOUCHPAD DRIVER
P: Johannes Berg
M: johannes@sipsolutions.net
L: linux-input@vger.kernel.org
S: Maintained
+F: Documentation/input/appletouch.txt
+F: drivers/input/mouse/appletouch.c
ARC FRAMEBUFFER DRIVER
P: Jaya Kumar
M: jayalk@intworks.biz
S: Maintained
+F: drivers/video/arcfb.c
+F: drivers/video/fb_defio.c
ARM MFM AND FLOPPY DRIVERS
P: Ian Molton
M: spyro@f2s.com
S: Maintained
+F: arch/arm/lib/floppydma.S
+F: arch/arm/include/asm/floppy.h
ARM PRIMECELL MMCI PL180/1 DRIVER
S: Orphan
+F: drivers/mmc/host/mmci.*
ARM/ADI ROADRUNNER MACHINE SUPPORT
P: Lennert Buytenhek
M: kernel@wantstofly.org
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
+F: arch/arm/mach-ixp23xx/
+F: arch/arm/mach-ixp23xx/include/mach/
ARM/ADS SPHERE MACHINE SUPPORT
P: Lennert Buytenhek
@@ -507,7 +607,7 @@ ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE
P: Paulius Zaleckas
M: paulius.zaleckas@teltonika.lt
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-T: git gitorious.org/linux-gemini/mainline.git
+T: git git://gitorious.org/linux-gemini/mainline.git
S: Maintained
ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6)
@@ -636,17 +736,17 @@ P: Dirk Opfer
M: dirk@opfer-online.de
S: Maintained
-ARM/PALMTX,PALMT5,PALMLD SUPPORT
+ARM/PALMTX,PALMT5,PALMLD,PALMTE2 SUPPORT
P: Marek Vasut
M: marek.vasut@gmail.com
W: http://hackndev.com
S: Maintained
ARM/PALMZ72 SUPPORT
-P: Sergey Lapin
-M: slapin@ossfans.org
-W: http://hackndev.com
-S: Maintained
+P: Sergey Lapin
+M: slapin@ossfans.org
+W: http://hackndev.com
+S: Maintained
ARM/PLEB SUPPORT
P: Peter Chubb
@@ -707,16 +807,17 @@ L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
ARM/NUVOTON W90X900 ARM ARCHITECTURE
-P: Wan ZongShun
-M: mcuos.com@gmail.com
-L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-W: http://www.mcuos.com
-S: Maintained
+P: Wan ZongShun
+M: mcuos.com@gmail.com
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+W: http://www.mcuos.com
+S: Maintained
ARPD SUPPORT
P: Jonathan Layes
L: netdev@vger.kernel.org
S: Maintained
+F: net/ipv4/arp.c
ASUS ACPI EXTRAS DRIVER
P: Corentin Chary
@@ -727,12 +828,15 @@ L: acpi4asus-user@lists.sourceforge.net
W: http://sourceforge.net/projects/acpi4asus
W: http://xf.iksaif.net/acpi4asus
S: Maintained
+F: arch/x86/kernel/acpi/boot.c
+F: drivers/platform/x86/asus_acpi.c
ASUS ASB100 HARDWARE MONITOR DRIVER
P: Mark M. Hoffman
M: mhoffman@lightlink.com
L: lm-sensors@lm-sensors.org
S: Maintained
+F: drivers/hwmon/asb100.c
ASUS LAPTOP EXTRAS DRIVER
P: Corentin Chary
@@ -741,6 +845,7 @@ L: acpi4asus-user@lists.sourceforge.net
W: http://sourceforge.net/projects/acpi4asus
W: http://xf.iksaif.net/acpi4asus
S: Maintained
+F: drivers/platform/x86/asus-laptop.c
ASYNCHRONOUS TRANSFERS/TRANSFORMS (IOAT) API
P: Dan Williams
@@ -750,12 +855,19 @@ M: maciej.sosnowski@intel.com
L: linux-kernel@vger.kernel.org
W: http://sourceforge.net/projects/xscaleiop
S: Supported
+F: Documentation/crypto/async-tx-api.txt
+F: crypto/async_tx/
+F: drivers/dma/
+F: include/linux/dmaengine.h
+F: include/linux/async_tx.h
ATA OVER ETHERNET (AOE) DRIVER
P: Ed L. Cashin
M: ecashin@coraid.com
W: http://www.coraid.com/support/linux
S: Supported
+F: Documentation/aoe/
+F: drivers/block/aoe/
ATHEROS ATH5K WIRELESS DRIVER
P: Jiri Slaby
@@ -769,6 +881,7 @@ M: me@bobcopeland.com
L: linux-wireless@vger.kernel.org
L: ath5k-devel@lists.ath5k.org
S: Maintained
+F: drivers/net/wireless/ath5k/
ATHEROS ATH9K WIRELESS DRIVER
P: Luis R. Rodriguez
@@ -778,6 +891,7 @@ M: jmalinen@atheros.com
L: linux-wireless@vger.kernel.org
L: ath9k-devel@lists.ath9k.org
S: Supported
+F: drivers/net/wireless/ath9k/
ATHEROS AR9170 WIRELESS DRIVER
P: Christian Lamparter
@@ -791,6 +905,7 @@ ATI_REMOTE2 DRIVER
P: Ville Syrjala
M: syrjala@sci.fi
S: Maintained
+F: drivers/input/misc/ati_remote2.c
ATLX ETHERNET DRIVERS
P: Jay Cliburn
@@ -803,6 +918,7 @@ L: atl1-devel@lists.sourceforge.net
W: http://sourceforge.net/projects/atl1
W: http://atl1.sourceforge.net
S: Maintained
+F: drivers/net/atlx/
ATM
P: Chas Williams
@@ -811,6 +927,8 @@ L: linux-atm-general@lists.sourceforge.net (subscribers-only)
L: netdev@vger.kernel.org
W: http://linux-atm.sourceforge.net
S: Maintained
+F: drivers/atm/
+F: include/linux/atm*
ATMEL AT91 MCI DRIVER
P: Nicolas Ferre
@@ -819,28 +937,34 @@ L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
W: http://www.atmel.com/products/AT91/
W: http://www.at91.com/
S: Maintained
+F: drivers/mmc/host/at91_mci.c
ATMEL AT91 / AT32 SERIAL DRIVER
P: Haavard Skinnemoen
M: hskinnemoen@atmel.com
L: linux-kernel@vger.kernel.org
S: Supported
+F: drivers/serial/atmel_serial.c
ATMEL LCDFB DRIVER
P: Nicolas Ferre
M: nicolas.ferre@atmel.com
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
+F: drivers/video/atmel_lcdfb.c
+F: include/video/atmel_lcdc.h
ATMEL MACB ETHERNET DRIVER
P: Haavard Skinnemoen
M: hskinnemoen@atmel.com
S: Supported
+F: drivers/net/macb.*
ATMEL SPI DRIVER
P: Haavard Skinnemoen
M: hskinnemoen@atmel.com
S: Supported
+F: drivers/spi/atmel_spi.*
ATMEL USBA UDC DRIVER
P: Haavard Skinnemoen
@@ -848,6 +972,7 @@ M: hskinnemoen@atmel.com
L: kernel@avr32linux.org
W: http://avr32linux.org/twiki/bin/view/Main/AtmelUsbDeviceDriver
S: Supported
+F: drivers/usb/gadget/atmel_usba_udc.*
ATMEL WIRELESS DRIVER
P: Simon Kelley
@@ -856,6 +981,7 @@ L: linux-wireless@vger.kernel.org
W: http://www.thekelleys.org.uk/atmel
W: http://atmelwlandriver.sourceforge.net/
S: Maintained
+F: drivers/net/wireless/atmel*
AUDIT SUBSYSTEM
P: Al Viro
@@ -864,8 +990,10 @@ P: Eric Paris
M: eparis@redhat.com
L: linux-audit@redhat.com (subscribers-only)
W: http://people.redhat.com/sgrubb/audit/
-T: git git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current.git
S: Maintained
+F: include/linux/audit.h
+F: kernel/audit*
AUXILIARY DISPLAY DRIVERS
P: Miguel Ojeda Sandonis
@@ -874,6 +1002,8 @@ L: linux-kernel@vger.kernel.org
W: http://miguelojeda.es/auxdisplay.htm
W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm
S: Maintained
+F: drivers/auxdisplay/
+F: include/linux/cfag12864b.h
AVR32 ARCHITECTURE
P: Haavard Skinnemoen
@@ -882,11 +1012,13 @@ W: http://www.atmel.com/products/AVR32/
W: http://avr32linux.org/
W: http://avrfreaks.net/
S: Supported
+F: arch/avr32/
AVR32/AT32AP MACHINE SUPPORT
P: Haavard Skinnemoen
M: hskinnemoen@atmel.com
S: Supported
+F: arch/avr32/mach-at32ap/
AX.25 NETWORK LAYER
P: Ralf Baechle
@@ -894,6 +1026,9 @@ M: ralf@linux-mips.org
L: linux-hams@vger.kernel.org
W: http://www.linux-ax25.org/
S: Maintained
+F: include/linux/ax25.h
+F: include/net/ax25.h
+F: net/ax25/
B43 WIRELESS DRIVER
P: Michael Buesch
@@ -903,6 +1038,7 @@ M: stefano.brivio@polimi.it
L: linux-wireless@vger.kernel.org
W: http://linuxwireless.org/en/users/Drivers/b43
S: Maintained
+F: drivers/net/wireless/b43/
B43LEGACY WIRELESS DRIVER
P: Larry Finger
@@ -912,11 +1048,14 @@ M: stefano.brivio@polimi.it
L: linux-wireless@vger.kernel.org
W: http://linuxwireless.org/en/users/Drivers/b43
S: Maintained
+F: drivers/net/wireless/b43legacy/
BACKLIGHT CLASS/SUBSYSTEM
P: Richard Purdie
M: rpurdie@rpsys.net
S: Maintained
+F: drivers/video/backlight/
+F: include/linux/backlight.h
BAYCOM/HDLCDRV DRIVERS FOR AX.25
P: Thomas Sailer
@@ -924,18 +1063,24 @@ M: t.sailer@alumni.ethz.ch
L: linux-hams@vger.kernel.org
W: http://www.baycom.org/~tom/ham/ham.html
S: Maintained
+F: drivers/net/hamradio/baycom*
BEFS FILE SYSTEM
P: Sergey S. Kostyliov
M: rathamahata@php4.ru
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/filesystems/befs.txt
+F: fs/befs/
BFS FILE SYSTEM
P: Tigran A. Aivazian
M: tigran@aivazian.fsnet.co.uk
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/filesystems/bfs.txt
+F: fs/bfs/
+F: include/linux/bfs_fs.h
BLACKFIN ARCHITECTURE
P: Bryan Wu
@@ -943,6 +1088,7 @@ M: cooloney@kernel.org
L: uclinux-dist-devel@blackfin.uclinux.org
W: http://blackfin.uclinux.org
S: Supported
+F: arch/blackfin/
BLACKFIN EMAC DRIVER
P: Bryan Wu
@@ -950,6 +1096,7 @@ M: cooloney@kernel.org
L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
W: http://blackfin.uclinux.org
S: Supported
+F: drivers/net/bfin_mac.*
BLACKFIN RTC DRIVER
P: Mike Frysinger
@@ -957,6 +1104,7 @@ M: vapier.adi@gmail.com
L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
W: http://blackfin.uclinux.org
S: Supported
+F: drivers/rtc/rtc-bfin.c
BLACKFIN SERIAL DRIVER
P: Sonic Zhang
@@ -964,6 +1112,7 @@ M: sonic.zhang@analog.com
L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
W: http://blackfin.uclinux.org
S: Supported
+F: drivers/serial/bfin_5xx.c
BLACKFIN WATCHDOG DRIVER
P: Mike Frysinger
@@ -971,6 +1120,7 @@ M: vapier.adi@gmail.com
L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
W: http://blackfin.uclinux.org
S: Supported
+F: drivers/watchdog/bfin_wdt.c
BLACKFIN I2C TWI DRIVER
P: Sonic Zhang
@@ -978,19 +1128,22 @@ M: sonic.zhang@analog.com
L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
W: http://blackfin.uclinux.org/
S: Supported
+F: drivers/i2c/busses/i2c-bfin-twi.c
BLOCK LAYER
P: Jens Axboe
M: axboe@kernel.dk
L: linux-kernel@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
S: Maintained
+F: block/
BLOCK2MTD DRIVER
P: Joern Engel
M: joern@lazybastard.org
L: linux-mtd@lists.infradead.org
S: Maintained
+F: drivers/mtd/devices/block2mtd.c
BLUETOOTH DRIVERS
P: Marcel Holtmann
@@ -998,14 +1151,17 @@ M: marcel@holtmann.org
L: linux-bluetooth@vger.kernel.org
W: http://www.bluez.org/
S: Maintained
+F: drivers/bluetooth/
BLUETOOTH SUBSYSTEM
P: Marcel Holtmann
M: marcel@holtmann.org
L: linux-bluetooth@vger.kernel.org
W: http://www.bluez.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git
S: Maintained
+F: net/bluetooth/
+F: include/net/bluetooth/
BONDING DRIVER
P: Jay Vosburgh
@@ -1013,24 +1169,30 @@ M: fubar@us.ibm.com
L: bonding-devel@lists.sourceforge.net
W: http://sourceforge.net/projects/bonding/
S: Supported
+F: drivers/net/bonding/
+F: include/linux/if_bonding.h
BROADCOM B44 10/100 ETHERNET DRIVER
P: Gary Zambrano
M: zambrano@broadcom.com
L: netdev@vger.kernel.org
S: Supported
+F: drivers/net/b44.*
BROADCOM BNX2 GIGABIT ETHERNET DRIVER
P: Michael Chan
M: mchan@broadcom.com
L: netdev@vger.kernel.org
S: Supported
+F: drivers/net/bnx2.*
+F: drivers/net/bnx2_*
BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER
P: Eilon Greenstein
M: eilong@broadcom.com
L: netdev@vger.kernel.org
S: Supported
+F: drivers/net/bnx2x*
BROADCOM TG3 GIGABIT ETHERNET DRIVER
P: Matt Carlson
@@ -1039,41 +1201,51 @@ P: Michael Chan
M: mchan@broadcom.com
L: netdev@vger.kernel.org
S: Supported
+F: drivers/net/tg3.*
BSG (block layer generic sg v4 driver)
P: FUJITA Tomonori
M: fujita.tomonori@lab.ntt.co.jp
L: linux-scsi@vger.kernel.org
S: Supported
+F: block/bsg.c
+F: include/linux/bsg.h
BT8XXGPIO DRIVER
P: Michael Buesch
M: mb@bu3sch.de
W: http://bu3sch.de/btgpio.php
S: Maintained
+F: drivers/gpio/bt8xxgpio.c
BTRFS FILE SYSTEM
P: Chris Mason
M: chris.mason@oracle.com
L: linux-btrfs@vger.kernel.org
W: http://btrfs.wiki.kernel.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/mason/btrfs-unstable.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable.git
S: Maintained
+F: Documentation/filesystems/btrfs.txt
+F: fs/btrfs/
BTTV VIDEO4LINUX DRIVER
P: Mauro Carvalho Chehab
M: mchehab@infradead.org
L: linux-media@vger.kernel.org
W: http://linuxtv.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
+F: Documentation/video4linux/bttv/
+F: drivers/media/video/bt8xx/bttv*
CAFE CMOS INTEGRATED CAMERA CONTROLLER DRIVER
P: Jonathan Corbet
M: corbet@lwn.net
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
+F: Documentation/video4linux/cafe_ccic
+F: drivers/media/video/cafe_ccic*
CALGARY x86-64 IOMMU
P: Muli Ben-Yehuda
@@ -1083,6 +1255,10 @@ M: jdmason@kudzu.us
L: linux-kernel@vger.kernel.org
L: discuss@x86-64.org
S: Maintained
+F: arch/x86/kernel/pci-calgary_64.c
+F: arch/x86/kernel/tce_64.c
+F: arch/x86/include/asm/calgary.h
+F: arch/x86/include/asm/tce.h
CAN NETWORK LAYER
P: Urs Thuermann
@@ -1092,6 +1268,9 @@ M: oliver.hartkopp@volkswagen.de
L: socketcan-core@lists.berlios.de (subscribers-only)
W: http://developer.berlios.de/projects/socketcan/
S: Maintained
+F: drivers/net/can/
+F: include/linux/can/
+F: include/linux/can.h
CELL BROADBAND ENGINE ARCHITECTURE
P: Arnd Bergmann
@@ -1100,12 +1279,23 @@ L: linuxppc-dev@ozlabs.org
L: cbe-oss-dev@ozlabs.org
W: http://www.ibm.com/developerworks/power/cell/
S: Supported
+F: arch/powerpc/include/asm/cell*.h
+F: arch/powerpc/include/asm/lv1call.h
+F: arch/powerpc/include/asm/ps3*.h
+F: arch/powerpc/include/asm/spu*.h
+F: arch/powerpc/oprofile/*cell*
+F: arch/powerpc/platforms/cell/
+F: arch/powerpc/platforms/ps3/
CERTIFIED WIRELESS USB (WUSB) SUBSYSTEM:
P: David Vrabel
M: david.vrabel@csr.com
L: linux-usb@vger.kernel.org
S: Supported
+F: Documentation/usb/WUSB-Design-overview.txt
+F: Documentation/usb/wusb-cbaf
+F: drivers/usb/wusbcore/
+F: include/linux/usb/wusb*
CFAG12864B LCD DRIVER
P: Miguel Ojeda Sandonis
@@ -1114,6 +1304,8 @@ L: linux-kernel@vger.kernel.org
W: http://miguelojeda.es/auxdisplay.htm
W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm
S: Maintained
+F: drivers/auxdisplay/cfag12864b.c
+F: include/linux/cfag12864b.h
CFAG12864BFB LCD FRAMEBUFFER DRIVER
P: Miguel Ojeda Sandonis
@@ -1122,18 +1314,25 @@ L: linux-kernel@vger.kernel.org
W: http://miguelojeda.es/auxdisplay.htm
W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm
S: Maintained
+F: drivers/auxdisplay/cfag12864bfb.c
+F: include/linux/cfag12864b.h
CFG80211 and NL80211
P: Johannes Berg
M: johannes@sipsolutions.net
L: linux-wireless@vger.kernel.org
S: Maintained
+F: include/linux/nl80211.h
+F: include/net/cfg80211.h
+F: net/wireless/*
+X: net/wireless/wext*
CHECKPATCH
P: Andy Whitcroft
M: apw@canonical.com
L: linux-kernel@vger.kernel.org
S: Supported
+F: scripts/checkpatch.pl
CISCO 10G ETHERNET DRIVER
P: Scott Feldman
@@ -1141,24 +1340,28 @@ M: scofeldm@cisco.com
P: Joe Eykholt
M: jeykholt@cisco.com
S: Supported
+F: drivers/net/enic/
CIRRUS LOGIC EP93XX ETHERNET DRIVER
P: Lennert Buytenhek
M: kernel@wantstofly.org
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/arm/ep93xx_eth.c
CIRRUS LOGIC EP93XX OHCI USB HOST DRIVER
P: Lennert Buytenhek
M: kernel@wantstofly.org
L: linux-usb@vger.kernel.org
S: Maintained
+F: drivers/usb/host/ohci-ep93xx.c
CIRRUS LOGIC CS4270 SOUND DRIVER
P: Timur Tabi
M: timur@freescale.com
L: alsa-devel@alsa-project.org
S: Supported
+F: sound/soc/codecs/cs4270*
CIRRUS LOGIC CS4280/CS461x SOUNDDRIVER
P: Cirrus Logic Corporation (kernel 2.2 driver)
@@ -1166,6 +1369,8 @@ M: Cirrus Logic Corporation, Thomas Woller <twoller@crystal.cirrus.com>
P: Nils Faerber (port to kernel 2.4)
M: Nils Faerber <nils@kernelconcepts.de>
S: Maintained
+F: Documentation/input/cs461x.txt
+F: sound/pci/cs46xx/
CODA FILE SYSTEM
P: Jan Harkes
@@ -1174,6 +1379,9 @@ M: coda@cs.cmu.edu
L: codalist@coda.cs.cmu.edu
W: http://www.coda.cs.cmu.edu/
S: Maintained
+F: Documentation/filesystems/coda.txt
+F: fs/coda/
+F: include/linux/coda*.h
COMMON INTERNET FILE SYSTEM (CIFS)
P: Steve French
@@ -1181,8 +1389,10 @@ M: sfrench@samba.org
L: linux-cifs-client@lists.samba.org
L: samba-technical@lists.samba.org
W: http://linux-cifs.samba.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
S: Supported
+F: Documentation/filesystems/cifs.txt
+F: fs/cifs/
COMPACTPCI HOTPLUG CORE
P: Scott Murray
@@ -1190,6 +1400,7 @@ M: scottm@somanetworks.com
M: scott@spiteful.org
L: linux-pci@vger.kernel.org
S: Supported
+F: drivers/pci/hotplug/cpci_hotplug*
COMPACTPCI HOTPLUG ZIATECH ZT5550 DRIVER
P: Scott Murray
@@ -1197,6 +1408,7 @@ M: scottm@somanetworks.com
M: scott@spiteful.org
L: linux-pci@vger.kernel.org
S: Supported
+F: drivers/pci/hotplug/cpcihp_zt5550.*
COMPACTPCI HOTPLUG GENERIC DRIVER
P: Scott Murray
@@ -1204,17 +1416,21 @@ M: scottm@somanetworks.com
M: scott@spiteful.org
L: linux-pci@vger.kernel.org
S: Supported
+F: drivers/pci/hotplug/cpcihp_generic.c
COMPAL LAPTOP SUPPORT
P: Cezary Jackiewicz
M: cezary.jackiewicz@gmail.com
S: Maintained
+F: drivers/platform/x86/compal-laptop.c
COMPUTONE INTELLIPORT MULTIPORT CARD
P: Michael H. Warfield
M: mhw@wittsend.com
W: http://www.wittsend.com/computone.html
S: Maintained
+F: Documentation/serial/computone.txt
+F: drivers/char/ip2/
CONEXANT ACCESSRUNNER USB DRIVER
P: Simon Arlott
@@ -1222,12 +1438,15 @@ M: cxacru@fire.lp0.eu
L: accessrunner-general@lists.sourceforge.net
W: http://accessrunner.sourceforge.net/
S: Maintained
+F: drivers/usb/atm/cxacru.c
CONFIGFS
P: Joel Becker
M: joel.becker@oracle.com
L: linux-kernel@vger.kernel.org
S: Supported
+F: fs/configfs/
+F: include/linux/configfs.h
CONTROL GROUPS (CGROUPS)
P: Paul Menage
@@ -1236,31 +1455,41 @@ P: Li Zefan
M: lizf@cn.fujitsu.com
L: containers@lists.linux-foundation.org
S: Maintained
+F: include/linux/cgroup*
+F: kernel/cgroup*
CORETEMP HARDWARE MONITORING DRIVER
P: Rudolf Marek
M: r.marek@assembler.cz
L: lm-sensors@lm-sensors.org
S: Maintained
+F: Documentation/hwmon/coretemp
+F: drivers/hwmon/coretemp.c
COSA/SRP SYNC SERIAL DRIVER
P: Jan "Yenya" Kasprzak
M: kas@fi.muni.cz
W: http://www.fi.muni.cz/~kas/cosa/
S: Maintained
+F: drivers/net/wan/cosa*
CPU FREQUENCY DRIVERS
P: Dave Jones
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
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git
S: Maintained
+F: arch/x86/kernel/cpu/cpufreq/
+F: drivers/cpufreq/
+F: include/linux/cpufreq.h
CPUID/MSR DRIVER
P: H. Peter Anvin
M: hpa@zytor.com
S: Maintained
+F: arch/x86/kernel/cpuid.c
+F: arch/x86/kernel/msr.c
CPUSETS
P: Paul Menage
@@ -1269,10 +1498,15 @@ L: linux-kernel@vger.kernel.org
W: http://www.bullopensource.org/cpuset/
W: http://oss.sgi.com/projects/cpusets/
S: Supported
+F: Documentation/cgroups/cpusets.txt
+F: include/linux/cpuset.h
+F: kernel/cpuset.c
CRAMFS FILESYSTEM
W: http://sourceforge.net/projects/cramfs/
S: Orphan
+F: Documentation/filesystems/cramfs.txt
+F: fs/cramfs/
CRIS PORT
P: Mikael Starvik
@@ -1282,6 +1516,7 @@ M: jesper.nilsson@axis.com
L: dev-etrax@axis.com
W: http://developer.axis.com
S: Maintained
+F: arch/cris/
CRYPTO API
P: Herbert Xu
@@ -1289,8 +1524,13 @@ M: herbert@gondor.apana.org.au
P: David S. Miller
M: davem@davemloft.net
L: linux-crypto@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
S: Maintained
+F: Documentation/crypto/
+F: arch/*/crypto/
+F: crypto/
+F: drivers/crypto/
+F: include/crypto/
CRYPTOGRAPHIC RANDOM NUMBER GENERATOR
P: Neil Horman
@@ -1302,16 +1542,21 @@ CS5535 Audio ALSA driver
P: Jaya Kumar
M: jayakumar.alsa@gmail.com
S: Maintained
+F: sound/pci/cs5535audio/
CX18 VIDEO4LINUX DRIVER
-P: Hans Verkuil, Andy Walls
-M: hverkuil@xs4all.nl, awalls@radix.net
+P: Hans Verkuil
+M: hverkuil@xs4all.nl
+P: Andy Walls
+M: awalls@radix.net
L: ivtv-devel@ivtvdriver.org
L: ivtv-users@ivtvdriver.org
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
W: http://linuxtv.org
S: Maintained
+F: Documentation/video4linux/cx18.txt
+F: drivers/media/video/cx18/
CXGB3 ETHERNET DRIVER (CXGB3)
P: Divy Le Ray
@@ -1319,6 +1564,7 @@ M: divy@chelsio.com
L: netdev@vger.kernel.org
W: http://www.chelsio.com
S: Supported
+F: drivers/net/cxgb3/
CXGB3 IWARP RNIC DRIVER (IW_CXGB3)
P: Steve Wise
@@ -1326,32 +1572,32 @@ M: swise@chelsio.com
L: general@lists.openfabrics.org
W: http://www.openfabrics.org
S: Supported
+F: drivers/infiniband/hw/cxgb3/
CYBERPRO FB DRIVER
P: Russell King
M: rmk@arm.linux.org.uk
W: http://www.arm.linux.org.uk/
S: Maintained
-
-CYBLAFB FRAMEBUFFER DRIVER
-P: Knut Petersen
-M: Knut_Petersen@t-online.de
-L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
-S: Maintained
+F: drivers/video/cyber2000fb.*
CYCLADES 2X SYNC CARD DRIVER
P: Arnaldo Carvalho de Melo
M: acme@ghostprotocols.net
W: http://oops.ghostprotocols.net:81/blog
S: Maintained
+F: drivers/net/wan/cycx*
CYCLADES ASYNC MUX DRIVER
W: http://www.cyclades.com/
S: Orphan
+F: drivers/char/cyclades.c
+F: include/linux/cyclades.h
CYCLADES PC300 DRIVER
W: http://www.cyclades.com/
S: Orphan
+F: drivers/net/wan/pc300*
DAMA SLAVE for AX.25
P: Joerg Reuter
@@ -1360,12 +1606,21 @@ W: http://yaina.de/jreuter/
W: http://www.qsl.net/dl1bke/
L: linux-hams@vger.kernel.org
S: Maintained
+F: net/ax25/af_ax25.c
+F: net/ax25/ax25_dev.c
+F: net/ax25/ax25_ds_*
+F: net/ax25/ax25_in.c
+F: net/ax25/ax25_out.c
+F: net/ax25/ax25_timer.c
+F: net/ax25/sysctl_net_ax25.c
DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER
P: Tobias Ringstrom
M: tori@unhappy.mine.nu
L: netdev@vger.kernel.org
S: Maintained
+F: Documentation/networking/dmfe.txt
+F: drivers/net/tulip/dmfe.c
DC390/AM53C974 SCSI driver
P: Kurt Garloff
@@ -1374,6 +1629,7 @@ W: http://www.garloff.de/kurt/linux/dc390/
P: Guennadi Liakhovetski
M: g.liakhovetski@gmx.de
S: Maintained
+F: drivers/scsi/tmscsim.*
DC395x SCSI driver
P: Oliver Neukum
@@ -1386,6 +1642,8 @@ W: http://twibble.org/dist/dc395x/
L: dc395x@twibble.org
L: http://lists.twibble.org/mailman/listinfo/dc395x/
S: Maintained
+F: Documentation/scsi/dc395x.txt
+F: drivers/scsi/dc395x.*
DCCP PROTOCOL
P: Arnaldo Carvalho de Melo
@@ -1393,6 +1651,9 @@ M: acme@ghostprotocols.net
L: dccp@vger.kernel.org
W: http://linux-net.osdl.org/index.php/DCCP
S: Maintained
+F: include/linux/dccp.h
+F: include/linux/tfrc.h
+F: net/dccp/
DECnet NETWORK LAYER
P: Christine Caulfield
@@ -1400,27 +1661,40 @@ M: christine.caulfield@googlemail.com
W: http://linux-decnet.sourceforge.net
L: linux-decnet-user@lists.sourceforge.net
S: Maintained
+F: Documentation/networking/decnet.txt
+F: net/decnet/
DEFXX FDDI NETWORK DRIVER
P: Maciej W. Rozycki
M: macro@linux-mips.org
S: Maintained
+F: drivers/net/defxx.*
DELL LAPTOP DRIVER
P: Matthew Garrett
M: mjg59@srcf.ucam.org
S: Maintained
+F: drivers/platform/x86/dell-laptop.c
DELL LAPTOP SMM DRIVER
P: Massimo Dal Zotto
M: dz@debian.org
W: http://www.debian.org/~dz/i8k/
S: Maintained
+F: drivers/char/i8k.c
+F: include/linux/i8k.h
DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas)
P: Doug Warzecha
M: Douglas_Warzecha@dell.com
S: Maintained
+F: Documentation/dcdbas.txt
+F: drivers/firmware/dcdbas.*
+
+DELL WMI EXTRAS DRIVER
+P: Matthew Garrett
+M: mjg59@srcf.ucam.org
+S: Maintained
DEVICE NUMBER REGISTRY
P: Torben Mathiasen
@@ -1434,6 +1708,10 @@ P: Alasdair Kergon
L: dm-devel@redhat.com
W: http://sources.redhat.com/dm
S: Maintained
+F: Documentation/device-mapper/
+F: drivers/md/dm*
+F: include/linux/device-mapper.h
+F: include/linux/dm-*.h
DIGI INTL. EPCA DRIVER
P: Digi International, Inc
@@ -1441,12 +1719,18 @@ M: Eng.Linux@digi.com
L: Eng.Linux@digi.com
W: http://www.digi.com
S: Orphan
+F: Documentation/serial/digiepca.txt
+F: drivers/char/epca*
+F: drivers/char/digi*
DIRECTORY NOTIFICATION (DNOTIFY)
P: Stephen Rothwell
M: sfr@canb.auug.org.au
L: linux-kernel@vger.kernel.org
S: Supported
+F: Documentation/filesystems/dnotify.txt
+F: fs/notify/dnotify/
+F: include/linux/dnotify.h
DISK GEOMETRY AND PARTITION HANDLING
P: Andries Brouwer
@@ -1461,6 +1745,9 @@ P: Jan Kara
M: jack@suse.cz
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/filesystems/quota.txt
+F: fs/quota/
+F: include/linux/quota*.h
DISTRIBUTED LOCK MANAGER (DLM)
P: Christine Caulfield
@@ -1469,8 +1756,9 @@ P: David Teigland
M: teigland@redhat.com
L: cluster-devel@redhat.com
W: http://sources.redhat.com/cluster/
-T: git kernel.org:/pub/scm/linux/kernel/git/teigland/dlm.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm.git
S: Supported
+F: fs/dlm/
DMA GENERIC OFFLOAD ENGINE SUBSYSTEM
P: Maciej Sosnowski
@@ -1479,12 +1767,16 @@ P: Dan Williams
M: dan.j.williams@intel.com
L: linux-kernel@vger.kernel.org
S: Supported
+F: drivers/dma/
+F: include/linux/dma*
DME1737 HARDWARE MONITOR DRIVER
P: Juerg Haefliger
M: juergh@gmail.com
L: lm-sensors@lm-sensors.org
S: Maintained
+F: Documentation/hwmon/dme1737
+F: drivers/hwmon/dme1737.c
DOCBOOK FOR DOCUMENTATION
P: Randy Dunlap
@@ -1496,18 +1788,22 @@ P: Shaohua Li
M: shaohua.li@intel.com
L: linux-acpi@vger.kernel.org
S: Supported
+F: drivers/acpi/dock.c
-DOCUMENTATION (/Documentation directory)
+DOCUMENTATION
P: Randy Dunlap
M: rdunlap@xenotime.net
L: linux-doc@vger.kernel.org
S: Maintained
+F: Documentation/
DOUBLETALK DRIVER
P: James R. Van Zandt
M: jrv@vanzandt.mv.com
L: blinux-list@redhat.com
S: Maintained
+F: drivers/char/dtlk.c
+F: include/linux/dtlk.h
DPT_I2O SCSI RAID DRIVER
P: Adaptec OEM Raid Solutions
@@ -1515,6 +1811,8 @@ M: aacraid@adaptec.com
L: linux-scsi@vger.kernel.org
W: http://www.adaptec.com/
S: Maintained
+F: drivers/scsi/dpt*
+F: drivers/scsi/dpt/
DRIVER CORE, KOBJECTS, AND SYSFS
P: Greg Kroah-Hartman
@@ -1522,49 +1820,55 @@ M: gregkh@suse.de
L: linux-kernel@vger.kernel.org
T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
S: Supported
+F: Documentation/kobject.txt
+F: drivers/base/
+F: fs/sysfs/
+F: include/linux/kobj*
+F: lib/kobj*
DRM DRIVERS
P: David Airlie
M: airlied@linux.ie
L: dri-devel@lists.sourceforge.net
-T: git kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6.git
S: Maintained
+F: drivers/gpu/drm/
DSCC4 DRIVER
P: Francois Romieu
M: romieu@fr.zoreil.com
L: netdev@vger.kernel.org
S: Maintained
-
-DVB SUBSYSTEM AND DRIVERS
-P: LinuxTV.org Project
-M: linux-media@vger.kernel.org
-L: linux-dvb@linuxtv.org (subscription required)
-W: http://linuxtv.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
-S: Maintained
+F: drivers/net/wan/dscc4.c
DZ DECSTATION DZ11 SERIAL DRIVER
P: Maciej W. Rozycki
M: macro@linux-mips.org
S: Maintained
+F: drivers/serial/dz.*
EATA-DMA SCSI DRIVER
P: Michael Neuffer
-L: linux-eata@i-connect.net, linux-scsi@vger.kernel.org
+M: mike@i-Connect.Net
+L: linux-eata@i-connect.net
+L: linux-scsi@vger.kernel.org
S: Maintained
+F: drivers/scsi/eata*
EATA ISA/EISA/PCI SCSI DRIVER
P: Dario Ballabio
M: ballabio_dario@emc.com
L: linux-scsi@vger.kernel.org
S: Maintained
+F: drivers/scsi/eata.c
EATA-PIO SCSI DRIVER
P: Michael Neuffer
M: mike@i-Connect.Net
-L: linux-eata@i-connect.net, linux-scsi@vger.kernel.org
+L: linux-eata@i-connect.net
+L: linux-scsi@vger.kernel.org
S: Maintained
+F: drivers/scsi/eata_pio.*
EBTABLES
P: Bart De Schuymer
@@ -1573,87 +1877,105 @@ L: ebtables-user@lists.sourceforge.net
L: ebtables-devel@lists.sourceforge.net
W: http://ebtables.sourceforge.net/
S: Maintained
+F: include/linux/netfilter_bridge/ebt_*.h
+F: net/bridge/netfilter/ebt*.c
ECRYPT FILE SYSTEM
-P: Tyler Hicks, Dustin Kirkland
-M: tyhicks@linux.vnet.ibm.com, kirkland@canonical.com
+P: Tyler Hicks
+M: tyhicks@linux.vnet.ibm.com
+M: Dustin Kirkland
+P: kirkland@canonical.com
L: ecryptfs-devel@lists.launchpad.net
W: https://launchpad.net/ecryptfs
S: Supported
+F: Documentation/filesystems/ecryptfs.txt
+F: fs/ecryptfs/
EDAC-CORE
P: Doug Thompson
M: dougthompson@xmission.com
-L: bluesmoke-devel@lists.sourceforge.net
+L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
W: bluesmoke.sourceforge.net
S: Supported
+F: Documentation/edac.txt
+F: drivers/edac/edac_*
+F: include/linux/edac.h
EDAC-E752X
P: Mark Gross
P: Doug Thompson
M: mark.gross@intel.com
M: dougthompson@xmission.com
-L: bluesmoke-devel@lists.sourceforge.net
+L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
W: bluesmoke.sourceforge.net
S: Maintained
+F: drivers/edac/e752x_edac.c
EDAC-E7XXX
P: Doug Thompson
M: dougthompson@xmission.com
-L: bluesmoke-devel@lists.sourceforge.net
+L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
W: bluesmoke.sourceforge.net
S: Maintained
+F: drivers/edac/e7xxx_edac.c
EDAC-I82443BXGX
P: Tim Small
M: tim@buttersideup.com
-L: bluesmoke-devel@lists.sourceforge.net
+L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
W: bluesmoke.sourceforge.net
S: Maintained
+F: drivers/edac/i82443bxgx_edac.c
EDAC-I3000
P: Jason Uhlenkott
M: juhlenko@akamai.com
-L: bluesmoke-devel@lists.sourceforge.net
+L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
W: bluesmoke.sourceforge.net
S: Maintained
+F: drivers/edac/i3000_edac.c
EDAC-I5000
P: Doug Thompson
M: dougthompson@xmission.com
-L: bluesmoke-devel@lists.sourceforge.net
+L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
W: bluesmoke.sourceforge.net
S: Maintained
+F: drivers/edac/i5000_edac.c
EDAC-I5400
P: Mauro Carvalho Chehab
M: mchehab@redhat.com
-L: bluesmoke-devel@lists.sourceforge.net
+L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
W: bluesmoke.sourceforge.net
S: Maintained
+F: drivers/edac/i5400_edac.c
EDAC-I82975X
P: Ranganathan Desikan
P: Arvind R.
M: rdesikan@jetzbroadband.com
M: arvind@acarlab.com
-L: bluesmoke-devel@lists.sourceforge.net
+L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
W: bluesmoke.sourceforge.net
S: Maintained
+F: drivers/edac/i82975x_edac.c
EDAC-PASEMI
P: Egor Martovetsky
M: egor@pasemi.com
-L: bluesmoke-devel@lists.sourceforge.net
+L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
W: bluesmoke.sourceforge.net
S: Maintained
+F: drivers/edac/pasemi_edac.c
EDAC-R82600
P: Tim Small
M: tim@buttersideup.com
-L: bluesmoke-devel@lists.sourceforge.net
+L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
W: bluesmoke.sourceforge.net
S: Maintained
+F: drivers/edac/r82600_edac.c
EEEPC LAPTOP EXTRAS DRIVER
P: Corentin Chary
@@ -1661,10 +1983,12 @@ M: corentincj@iksaif.net
L: acpi4asus-user@lists.sourceforge.net
W: http://sourceforge.net/projects/acpi4asus
S: Maintained
+F: drivers/platform/x86/eeepc-laptop.c
EFS FILESYSTEM
W: http://aeschi.ch.eu.org/efs/
S: Orphan
+F: fs/efs/
EHCA (IBM GX bus InfiniBand adapter) DRIVER
P: Hoang-Nam Nguyen
@@ -1673,6 +1997,7 @@ P: Christoph Raisch
M: raisch@de.ibm.com
L: general@lists.openfabrics.org
S: Supported
+F: drivers/infiniband/hw/ehca/
EMBEDDED LINUX
P: Paul Gortmaker
@@ -1688,22 +2013,29 @@ M: james.smart@emulex.com
L: linux-scsi@vger.kernel.org
W: http://sourceforge.net/projects/lpfcxxxx
S: Supported
+F: drivers/scsi/lpfc/
EPSON 1355 FRAMEBUFFER DRIVER
P: Christopher Hoover
-M: ch@murgatroid.com, ch@hpl.hp.com
+M: ch@murgatroid.com
+P: Christopher Hoover
+M: ch@hpl.hp.com
S: Maintained
+F: drivers/video/epson1355fb.c
EPSON S1D13XXX FRAMEBUFFER DRIVER
P: Kristoffer Ericson
M: kristoffer.ericson@gmail.com
S: Maintained
+F: drivers/video/s1d13xxxfb.c
+F: include/video/s1d13xxxfb.h
ETHEREXPRESS-16 NETWORK DRIVER
P: Philip Blundell
M: philb@gnu.org
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/eexpress.*
ETHERNET BRIDGE
P: Stephen Hemminger
@@ -1711,81 +2043,126 @@ M: shemminger@linux-foundation.org
L: bridge@lists.linux-foundation.org
W: http://www.linux-foundation.org/en/Net:Bridge
S: Maintained
+F: include/linux/netfilter_bridge/
+F: net/bridge/
ETHERTEAM 16I DRIVER
P: Mika Kuoppala
M: miku@iki.fi
S: Maintained
+F: drivers/net/eth16i.c
EXT2 FILE SYSTEM
L: linux-ext4@vger.kernel.org
S: Maintained
+F: Documentation/filesystems/ext2.txt
+F: fs/ext2/
+F: include/linux/ext2*
EXT3 FILE SYSTEM
-P: Stephen Tweedie, Andrew Morton
-M: sct@redhat.com, akpm@linux-foundation.org, adilger@sun.com
+P: Stephen Tweedie
+M: sct@redhat.com
+P: Andrew Morton
+M: akpm@linux-foundation.org
+P: Andreas Dilger
+M: adilger@sun.com
L: linux-ext4@vger.kernel.org
S: Maintained
+F: Documentation/filesystems/ext3.txt
+F: fs/ext3/
+F: include/linux/ext3*
EXT4 FILE SYSTEM
P: Theodore Ts'o
-M: tytso@mit.edu, adilger@sun.com
+M: tytso@mit.edu
+P: Andreas Dilger
+M: adilger@sun.com
L: linux-ext4@vger.kernel.org
W: http://ext4.wiki.kernel.org
S: Maintained
+F: Documentation/filesystems/ext4.txt
+F: fs/ext4/
F71805F HARDWARE MONITORING DRIVER
P: Jean Delvare
M: khali@linux-fr.org
L: lm-sensors@lm-sensors.org
S: Maintained
+F: Documentation/hwmon/f71805f
+F: drivers/hwmon/f71805f.c
FARSYNC SYNCHRONOUS DRIVER
P: Kevin Curtis
M: kevin.curtis@farsite.co.uk
W: http://www.farsite.co.uk/
S: Supported
+F: drivers/net/wan/farsync.*
FAULT INJECTION SUPPORT
P: Akinobu Mita
M: akinobu.mita@gmail.com
S: Supported
+F: Documentation/fault-injection/
+F: lib/fault-inject.c
FILE LOCKING (flock() and fcntl()/lockf())
P: Matthew Wilcox
M: matthew@wil.cx
L: linux-fsdevel@vger.kernel.org
S: Maintained
+F: include/linux/fcntl.h
+F: include/linux/fs.h
+F: fs/fcntl.c
+F: fs/locks.c
FILESYSTEMS (VFS and infrastructure)
P: Alexander Viro
M: viro@zeniv.linux.org.uk
L: linux-fsdevel@vger.kernel.org
S: Maintained
+F: fs/*
+
+FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER
+P: Riku Voipio
+M: riku.vipio@iki.fi
+L: lm-sensors@lm-sensors.org
+S: Maintained
+F: drivers/hwmon/f75375s.c
+F: include/linux/f75375s.h
-FIREWIRE SUBSYSTEM (drivers/firewire, <linux/firewire*.h>)
-P: Kristian Hoegsberg, Stefan Richter
-M: krh@redhat.com, stefanr@s5r6.in-berlin.de
+FIREWIRE SUBSYSTEM
+P: Kristian Hoegsberg
+M: krh@redhat.com
+P: Stefan Richter
+M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
S: Maintained
+F: drivers/firewire/
+F: include/linux/firewire*.h
FIRMWARE LOADER (request_firmware)
L: linux-kernel@vger.kernel.org
S: Orphan
+F: Documentation/firmware_class/
+F: drivers/base/firmware*.c
+F: include/linux/firmware.h
FPU EMULATOR
P: Bill Metzenthen
-M: billm@suburbia.net
-W: http://suburbia.net/~billm/floating-point/emulator/
+M: billm@melbpc.org.au
+W: http://floatingpoint.sourceforge.net/emulator/index.html
S: Maintained
+F: arch/x86/math-emu/
FRAME RELAY DLCI/FRAD (Sangoma drivers too)
P: Mike McLagan
M: mike.mclagan@linux.org
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/wan/dlci.c
+F: drivers/net/wan/sdla.c
FRAMEBUFFER LAYER
P: Antonino Daplas
@@ -1793,6 +2170,9 @@ M: adaplas@gmail.com
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
W: http://linux-fbdev.sourceforge.net/
S: Maintained
+F: Documentation/fb/
+F: drivers/video/fb*
+F: include/linux/fb.h
FREESCALE DMA DRIVER
P: Li Yang
@@ -1802,6 +2182,7 @@ M: zw@zh-kernel.org
L: linuxppc-embedded@ozlabs.org
L: linux-kernel@vger.kernel.org
S: Maintained
+F: drivers/dma/fsldma.*
FREESCALE I2C CPM DRIVER
P: Jochen Friedrich
@@ -1809,6 +2190,7 @@ M: jochen@scram.de
L: linuxppc-dev@ozlabs.org
L: linux-i2c@vger.kernel.org
S: Maintained
+F: drivers/i2c/busses/i2c-cpm.c
FREESCALE IMX / MXC FRAMEBUFFER DRIVER
P: Sascha Hauer
@@ -1816,6 +2198,8 @@ M: kernel@pengutronix.de
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
+F: arch/arm/plat-mxc/include/mach/imxfb.h
+F: drivers/video/imxfb.c
FREESCALE SOC FS_ENET DRIVER
P: Pantelis Antoniou
@@ -1825,12 +2209,16 @@ M: vbordug@ru.mvista.com
L: linuxppc-dev@ozlabs.org
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/fs_enet/
+F: include/linux/fs_enet_pd.h
FREESCALE QUICC ENGINE LIBRARY
P: Timur Tabi
M: timur@freescale.com
L: linuxppc-dev@ozlabs.org
S: Supported
+F: arch/powerpc/sysdev/qe_lib/
+F: arch/powerpc/include/asm/*qe.h
FREESCALE HIGHSPEED USB DEVICE DRIVER
P: Li Yang
@@ -1838,6 +2226,7 @@ M: leoli@freescale.com
L: linux-usb@vger.kernel.org
L: linuxppc-dev@ozlabs.org
S: Maintained
+F: drivers/usb/gadget/fsl_usb2_udc.c
FREESCALE QUICC ENGINE UCC ETHERNET DRIVER
P: Li Yang
@@ -1845,12 +2234,14 @@ M: leoli@freescale.com
L: netdev@vger.kernel.org
L: linuxppc-dev@ozlabs.org
S: Maintained
+F: drivers/net/ucc_geth*
FREESCALE QUICC ENGINE UCC UART DRIVER
P: Timur Tabi
M: timur@freescale.com
L: linuxppc-dev@ozlabs.org
S: Supported
+F: drivers/serial/ucc_uart.c
FREESCALE SOC SOUND DRIVERS
P: Timur Tabi
@@ -1858,12 +2249,15 @@ M: timur@freescale.com
L: alsa-devel@alsa-project.org
L: linuxppc-dev@ozlabs.org
S: Supported
+F: sound/soc/fsl/fsl*
+F: sound/soc/fsl/mpc8610_hpcd.c
FREEVXFS FILESYSTEM
P: Christoph Hellwig
M: hch@infradead.org
W: ftp://ftp.openlinux.org/pub/people/hch/vxfs
S: Maintained
+F: fs/freevxfs/
FREEZER
P: Pavel Machek
@@ -1872,22 +2266,32 @@ P: Rafael J. Wysocki
M: rjw@sisk.pl
L: linux-pm@lists.linux-foundation.org
S: Supported
+F: Documentation/power/freezing-of-tasks.txt
+F: include/linux/freezer.h
+F: kernel/freezer.c
FTRACE
P: Steven Rostedt
M: rostedt@goodmis.org
S: Maintained
+F: Documentation/ftrace.txt
+F: arch/*/*/*/ftrace.h
+F: arch/*/kernel/ftrace.c
+F: include/*/ftrace.h
+F: kernel/trace/
FUJITSU FR-V (FRV) PORT
P: David Howells
M: dhowells@redhat.com
S: Maintained
+F: arch/frv/
FUJITSU LAPTOP EXTRAS
P: Jonathan Woithe
M: jwoithe@physics.adelaide.edu.au
L: linux-acpi@vger.kernel.org
S: Maintained
+F: drivers/platform/x86/fujitsu-laptop.c
FUSE: FILESYSTEM IN USERSPACE
P: Miklos Szeredi
@@ -1895,12 +2299,15 @@ M: miklos@szeredi.hu
L: fuse-devel@lists.sourceforge.net
W: http://fuse.sourceforge.net/
S: Maintained
+F: fs/fuse/
+F: include/linux/fuse.h
FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
P: Rik Faith
M: faith@cs.unc.edu
L: linux-scsi@vger.kernel.org
S: Odd Fixes (e.g., new signatures)
+F: drivers/scsi/fdomain.*
GDT SCSI DISK ARRAY CONTROLLER DRIVER
P: Achim Leubner
@@ -1908,26 +2315,39 @@ M: achim_leubner@adaptec.com
L: linux-scsi@vger.kernel.org
W: http://www.icp-vortex.com/
S: Supported
+F: drivers/scsi/gdt*
GENERIC GPIO I2C DRIVER
P: Haavard Skinnemoen
M: hskinnemoen@atmel.com
S: Supported
+F: drivers/i2c/busses/i2c-gpio.c
+F: include/linux/i2c-gpio.h
GENERIC HDLC (WAN) DRIVERS
P: Krzysztof Halasa
M: khc@pm.waw.pl
W: http://www.kernel.org/pub/linux/utils/net/hdlc/
S: Maintained
+F: drivers/net/wan/c101.c
+F: drivers/net/wan/hd6457*
+F: drivers/net/wan/hdlc*
+F: drivers/net/wan/n2.c
+F: drivers/net/wan/pc300too.c
+F: drivers/net/wan/pci200syn.c
+F: drivers/net/wan/wanxl*
GFS2 FILE SYSTEM
P: Steven Whitehouse
M: swhiteho@redhat.com
L: cluster-devel@redhat.com
W: http://sources.redhat.com/cluster/
-T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes.git
-T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw.git
S: Supported
+F: Documentation/filesystems/gfs2*.txt
+F: fs/gfs2/
+F: include/linux/gfs2_ondisk.h
GIGASET ISDN DRIVERS
P: Hansjoerg Lipp
@@ -1937,6 +2357,9 @@ M: tilman@imap.cc
L: gigaset307x-common@lists.sourceforge.net
W: http://gigaset307x.sourceforge.net/
S: Maintained
+F: Documentation/isdn/README.gigaset
+F: drivers/isdn/gigaset/
+F: include/linux/gigaset_dev.h
HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
P: Frank Seidel
@@ -1944,6 +2367,7 @@ M: frank@f-seidel.de
L: lm-sensors@lm-sensors.org
W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
S: Maintained
+F: drivers/hwmon/hdaps.c
HYPERVISOR VIRTUAL CONSOLE DRIVER
L: linuxppc-dev@ozlabs.org
@@ -1955,51 +2379,61 @@ GSPCA FINEPIX SUBDRIVER
P: Frank Zago
M: frank@zago.net
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
+F: drivers/media/video/gspca/finepix.c
GSPCA M5602 SUBDRIVER
P: Erik Andren
M: erik.andren@gmail.com
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
+F: drivers/media/video/gspca/m5602/
GSPCA PAC207 SONIXB SUBDRIVER
P: Hans de Goede
M: hdegoede@redhat.com
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
+F: drivers/media/video/gspca/pac207.c
GSPCA T613 SUBDRIVER
P: Leandro Costantino
M: lcostantino@gmail.com
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
+F: drivers/media/video/gspca/t613.c
GSPCA USB WEBCAM DRIVER
P: Jean-Francois Moine
M: moinejf@free.fr
W: http://moinejf.free.fr
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
+F: drivers/media/video/gspca/
HARDWARE MONITORING
L: lm-sensors@lm-sensors.org
W: http://www.lm-sensors.org/
S: Orphan
+F: drivers/hwmon/
HARDWARE RANDOM NUMBER GENERATOR CORE
S: Orphan
+F: Documentation/hw_random.txt
+F: drivers/char/hw_random/
+F: include/linux/hw_random.h
HARMONY SOUND DRIVER
P: Kyle McMartin
M: kyle@mcmartin.ca
L: linux-parisc@vger.kernel.org
S: Maintained
+F: sound/parisc/harmony.*
HAYES ESP SERIAL DRIVER
P: Andrew J. Robinson
@@ -2007,30 +2441,33 @@ M: arobinso@nyx.net
L: linux-kernel@vger.kernel.org
W: http://www.nyx.net/~arobinso
S: Maintained
-
-HEWLETT-PACKARD FIBRE CHANNEL 64-bit/66MHz PCI non-intelligent HBA
-P: Chirag Kantharia
-M: chirag.kantharia@hp.com
-L: iss_storagedev@hp.com
-S: Maintained
+F: Documentation/serial/hayes-esp.txt
+F: drivers/char/esp.c
HEWLETT-PACKARD SMART2 RAID DRIVER
P: Chirag Kantharia
M: chirag.kantharia@hp.com
L: iss_storagedev@hp.com
S: Maintained
+F: Documentation/blockdev/cpqarray.txt
+F: drivers/block/cpqarray.*
HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss)
P: Mike Miller
M: mike.miller@hp.com
L: iss_storagedev@hp.com
S: Supported
+F: Documentation/blockdev/cciss.txt
+F: drivers/block/cciss*
+F: include/linux/cciss_ioctl.h
HFS FILESYSTEM
P: Roman Zippel
M: zippel@linux-m68k.org
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/filesystems/hfs.txt
+F: fs/hfs/
HGA FRAMEBUFFER DRIVER
P: Ferenc Bakonyi
@@ -2038,6 +2475,7 @@ M: fero@drama.obuda.kando.hu
L: linux-nvidia@lists.surfsouth.com
W: http://drama.obuda.kando.hu/~fero/cgi-bin/hgafb.shtml
S: Maintained
+F: drivers/video/hgafb.c
HIBERNATION (aka Software Suspend, aka swsusp)
P: Pavel Machek
@@ -2046,19 +2484,32 @@ P: Rafael J. Wysocki
M: rjw@sisk.pl
L: linux-pm@lists.linux-foundation.org
S: Supported
+F: arch/x86/power/
+F: drivers/base/power/
+F: kernel/power/
+F: include/linux/suspend.h
+F: include/linux/freezer.h
+F: include/linux/pm.h
+F: include/asm-*/suspend*.h
+F: arch/*/include/asm/suspend*.h
HID CORE LAYER
P: Jiri Kosina
M: jkosina@suse.cz
L: linux-input@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/jikos/hid.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git
S: Maintained
+F: drivers/hid/
+F: include/linux/hid*
HIGH-RESOLUTION TIMERS, CLOCKEVENTS, DYNTICKS
P: Thomas Gleixner
M: tglx@linutronix.de
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/timers/
+F: kernel/hrtimer.c
+F: include/linux/hrtimer.h
HIGH-SPEED SCC DRIVER FOR AX.25
P: Klaus Kudielka
@@ -2066,18 +2517,25 @@ M: klaus.kudielka@ieee.org
L: linux-hams@vger.kernel.org
W: http://www.nt.tuwien.ac.at/~kkudielk/Linux/
S: Maintained
+F: drivers/net/hamradio/dmascc.c
+F: drivers/net/hamradio/scc.c
HIGHPOINT ROCKETRAID 3xxx RAID DRIVER
P: HighPoint Linux Team
M: linux@highpoint-tech.com
W: http://www.highpoint-tech.com
S: Supported
+F: Documentation/scsi/hptiop.txt
+F: drivers/scsi/hptiop.c
HIPPI
P: Jes Sorensen
M: jes@trained-monkey.org
L: linux-hippi@sunsite.dk
S: Maintained
+F: include/linux/hippidevice.h
+F: include/linux/if_hippi.h
+F: net/802/hippi.c
HOST AP DRIVER
P: Jouni Malinen
@@ -2086,65 +2544,79 @@ L: hostap@shmoo.com (subscribers-only)
L: linux-wireless@vger.kernel.org
W: http://hostap.epitest.fi/
S: Maintained
+F: drivers/net/wireless/hostap/
HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER
P: Carlos Corbacho
M: carlos@strangeworlds.co.uk
S: Odd Fixes
+F: drivers/platform/x86/tc1100-wmi.c
HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series
P: Jaroslav Kysela
M: perex@perex.cz
S: Maintained
+F: drivers/net/hp100.*
-HPET: High Precision Event Timers driver (drivers/char/hpet.c)
+HPET: High Precision Event Timers driver
P: Clemens Ladisch
M: clemens@ladisch.de
S: Maintained
+F: Documentation/timers/hpet.txt
+F: drivers/char/hpet.c
+F: include/linux/hpet.h
HPET: i386
P: Venkatesh Pallipadi (Venki)
M: venkatesh.pallipadi@intel.com
S: Maintained
+F: arch/x86/kernel/hpet.c
+F: arch/x86/include/asm/hpet.h
HPET: x86_64
P: Vojtech Pavlik
M: vojtech@suse.cz
S: Maintained
-HPET: ACPI hpet.c
+HPET: ACPI
P: Bob Picco
M: bob.picco@hp.com
S: Maintained
+F: drivers/char/hpet.c
HPFS FILESYSTEM
P: Mikulas Patocka
M: mikulas@artax.karlin.mff.cuni.cz
W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
S: Maintained
+F: fs/hpfs/
-HSO 3G Modem Driver (hso.c)
-P: Denis Joseph Barrow
-M: d.barow@option.com
+HSO 3G MODEM DRIVER
+P: Jan Dumon
+M: j.dumon@option.com
W: http://www.pharscape.org
S: Maintained
+F: drivers/net/usb/hso.c
HTCPEN TOUCHSCREEN DRIVER
P: Pau Oliva Fora
M: pof@eslack.org
L: linux-input@vger.kernel.org
S: Maintained
+F: drivers/input/touchscreen/htcpen.c
HUGETLB FILESYSTEM
P: William Irwin
M: wli@holomorphy.com
S: Maintained
+F: fs/hugetlbfs/
I2C/SMBUS STUB DRIVER
P: Mark M. Hoffman
M: mhoffman@lightlink.com
L: linux-i2c@vger.kernel.org
S: Maintained
+F: drivers/i2c/busses/i2c-stub.c
I2C SUBSYSTEM
P: Jean Delvare (PC drivers, core)
@@ -2155,24 +2627,31 @@ L: linux-i2c@vger.kernel.org
W: http://i2c.wiki.kernel.org/
T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/
S: Maintained
+F: Documentation/i2c/
+F: drivers/i2c/
+F: include/linux/i2c.h
+F: include/linux/i2c-dev.h
+F: include/linux/i2c-id.h
I2C-TINY-USB DRIVER
P: Till Harbaum
M: till@harbaum.org
L: linux-i2c@vger.kernel.org
-T: http://www.harbaum.org/till/i2c_tiny_usb
+W: http://www.harbaum.org/till/i2c_tiny_usb
S: Maintained
+F: drivers/i2c/busses/i2c-tiny-usb.c
i386 BOOT CODE
P: H. Peter Anvin
M: hpa@zytor.com
L: Linux-Kernel@vger.kernel.org
S: Maintained
+F: arch/x86/boot/
i386 SETUP CODE / CPU ERRATA WORKAROUNDS
P: H. Peter Anvin
M: hpa@zytor.com
-T: git.kernel.org:/pub/scm/linux/kernel/git/hpa/linux-2.6-x86setup.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/hpa/linux-2.6-x86setup.git
S: Maintained
IA64 (Itanium) PLATFORM
@@ -2180,19 +2659,22 @@ P: Tony Luck
M: tony.luck@intel.com
L: linux-ia64@vger.kernel.org
W: http://www.ia64-linux.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6.git
S: Maintained
+F: arch/ia64/
IBM MCA SCSI SUBSYSTEM DRIVER
P: Michael Lang
M: langa2@kph.uni-mainz.de
W: http://www.uni-mainz.de/~langm000/linux.html
S: Maintained
+F: drivers/scsi/ibmmca.c
IBM Power Linux RAID adapter
P: Brian King
M: brking@us.ibm.com
S: Supported
+F: drivers/scsi/ipr.*
IBM ServeRAID RAID DRIVER
P: Jack Hammer
@@ -2200,6 +2682,7 @@ P: Dave Jeffery
M: ipslinux@adaptec.com
W: http://www.developer.ibm.com/welcome/netfinity/serveraid.html
S: Supported
+F: drivers/scsi/ips.*
IDE SUBSYSTEM
P: Bartlomiej Zolnierkiewicz
@@ -2207,45 +2690,55 @@ M: bzolnier@gmail.com
L: linux-ide@vger.kernel.org
T: quilt kernel.org/pub/linux/kernel/people/bart/pata-2.6/
S: Maintained
+F: Documentation/ide/
+F: drivers/ide/
+F: include/linux/ide.h
IDE/ATAPI DRIVERS
P: Borislav Petkov
M: petkovbb@gmail.com
L: linux-ide@vger.kernel.org
S: Maintained
+F: Documentation/cdrom/ide-cd
+F: drivers/ide/ide-cd*
IDLE-I7300
P: Andy Henroid
M: andrew.d.henroid@intel.com
L: linux-pm@lists.linux-foundation.org
S: Supported
+F: drivers/idle/i7300_idle.c
-IEEE 1394 SUBSYSTEM (drivers/ieee1394)
+IEEE 1394 SUBSYSTEM
P: Ben Collins
M: ben.collins@ubuntu.com
P: Stefan Richter
M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
S: Maintained
+F: drivers/ieee1394/
-IEEE 1394 RAW I/O DRIVER (raw1394)
+IEEE 1394 RAW I/O DRIVER
P: Dan Dennedy
M: dan@dennedy.org
P: Stefan Richter
M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
S: Maintained
+F: drivers/ieee1394/raw1394*
INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
P: Mimi Zohar
M: zohar@us.ibm.com
S: Supported
+F: security/integrity/ima/
IMS TWINTURBO FRAMEBUFFER DRIVER
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Orphan
+F: drivers/video/imsttfb.c
INFINIBAND SUBSYSTEM
P: Roland Dreier
@@ -2256,8 +2749,11 @@ P: Hal Rosenstock
M: hal.rosenstock@gmail.com
L: general@lists.openfabrics.org (moderated for non-subscribers)
W: http://www.openib.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git
S: Supported
+F: Documentation/infiniband/
+F: drivers/infiniband/
+F: include/linux/if_infiniband.h
INOTIFY
P: John McCutchan
@@ -2266,26 +2762,33 @@ P: Robert Love
M: rlove@rlove.org
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/filesystems/inotify.txt
+F: fs/notify/inotify/
+F: include/linux/inotify.h
INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN) DRIVERS
P: Dmitry Torokhov
M: dmitry.torokhov@gmail.com
M: dtor@mail.ru
L: linux-input@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/dtor/input.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git
S: Maintained
+F: drivers/input/
INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
P: Sylvain Meyer
M: sylvain.meyer@worldonline.fr
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
+F: Documentation/fb/intelfb.txt
+F: drivers/video/intelfb/
INTEL 810/815 FRAMEBUFFER DRIVER
P: Antonino Daplas
M: adaplas@gmail.com
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
+F: drivers/video/i810/
INTEL MENLOW THERMAL DRIVER
P: Sujith Thomas
@@ -2293,46 +2796,61 @@ M: sujith.thomas@intel.com
L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/
S: Supported
+F: drivers/platform/x86/intel_menlow.c
INTEL IA32 MICROCODE UPDATE SUPPORT
P: Tigran Aivazian
M: tigran@aivazian.fsnet.co.uk
S: Maintained
+F: arch/x86/kernel/microcode_core.c
+F: arch/x86/kernel/microcode_intel.c
INTEL I/OAT DMA DRIVER
P: Maciej Sosnowski
M: maciej.sosnowski@intel.com
L: linux-kernel@vger.kernel.org
S: Supported
+F: drivers/dma/ioat*
INTEL IOMMU (VT-d)
P: David Woodhouse
M: dwmw2@infradead.org
L: iommu@lists.linux-foundation.org
-T: git://git.infradead.org/iommu-2.6.git
+T: git git://git.infradead.org/iommu-2.6.git
S: Supported
+F: drivers/pci/intel-iommu.c
+F: include/linux/intel-iommu.h
INTEL IOP-ADMA DMA DRIVER
P: Dan Williams
M: dan.j.williams@intel.com
L: linux-kernel@vger.kernel.org
S: Supported
+F: drivers/dma/iop-adma.c
INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
P: Krzysztof Halasa
M: khc@pm.waw.pl
S: Maintained
+F: arch/arm/mach-ixp4xx/include/mach/qmgr.h
+F: arch/arm/mach-ixp4xx/include/mach/npe.h
+F: arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
+F: arch/arm/mach-ixp4xx/ixp4xx_npe.c
+F: drivers/net/arm/ixp4xx_eth.c
+F: drivers/net/wan/ixp4xx_hss.c
INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT
P: Deepak Saxena
M: dsaxena@plexity.net
S: Maintained
+F: drivers/char/hw_random/ixp4xx-rng.c
INTEL IXP2000 ETHERNET DRIVER
P: Lennert Buytenhek
M: kernel@wantstofly.org
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/ixp2000/
INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/ixgb/ixgbe)
P: Jeff Kirsher
@@ -2348,6 +2866,12 @@ M: john.ronciak@intel.com
L: e1000-devel@lists.sourceforge.net
W: http://e1000.sourceforge.net/
S: Supported
+F: drivers/net/e100.c
+F: drivers/net/e1000/
+F: drivers/net/e1000e/
+F: drivers/net/igb/
+F: drivers/net/ixgb/
+F: drivers/net/ixgbe/
INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
P: Zhu Yi
@@ -2361,6 +2885,8 @@ L: ipw2100-devel@lists.sourceforge.net
W: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
W: http://ipw2100.sourceforge.net
S: Supported
+F: Documentation/networking/README.ipw2100
+F: drivers/net/wireless/ipw2x00/ipw2100.*
INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
P: Zhu Yi
@@ -2374,6 +2900,8 @@ L: ipw2100-devel@lists.sourceforge.net
W: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
W: http://ipw2200.sourceforge.net
S: Supported
+F: Documentation/networking/README.ipw2200
+F: drivers/net/wireless/ipw2x00/ipw2200.*
INTEL WIRELESS WIMAX CONNECTION 2400
P: Inaky Perez-Gonzalez
@@ -2382,6 +2910,9 @@ M: linux-wimax@intel.com
L: wimax@linuxwimax.org
S: Supported
W: http://linuxwimax.org
+F: Documentation/wimax/README.i2400m
+F: drivers/net/wimax/i2400m/
+F: include/linux/wimax/i2400m.h
INTEL WIRELESS WIFI LINK (iwlwifi)
P: Zhu Yi
@@ -2391,25 +2922,29 @@ M: reinette.chatre@intel.com
L: linux-wireless@vger.kernel.org
L: ipw3945-devel@lists.sourceforge.net
W: http://intellinuxwireless.org
-T: git kernel.org:/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git
S: Supported
+F: drivers/net/wireless/iwlwifi/
IOC3 ETHERNET DRIVER
P: Ralf Baechle
M: ralf@linux-mips.org
L: linux-mips@linux-mips.org
S: Maintained
+F: drivers/net/ioc3-eth.c
IOC3 SERIAL DRIVER
P: Pat Gefre
M: pfg@sgi.com
L: linux-mips@linux-mips.org
S: Maintained
+F: drivers/serial/ioc3_serial.c
IP MASQUERADING
P: Juanjo Ciarlante
M: jjciarla@raiz.uncu.edu.ar
S: Maintained
+F: net/ipv4/netfilter/ipt_MASQUERADE.c
IP1000A 10/100/1000 GIGABIT ETHERNET DRIVER
P: Francois Romieu
@@ -2420,6 +2955,7 @@ P: Jesse Huang
M: jesse@icplus.com.tw
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/ipg.c
IPATH DRIVER
P: Ralph Campbell
@@ -2427,6 +2963,7 @@ M: infinipath@qlogic.com
L: general@lists.openfabrics.org
T: git git://git.qlogic.com/ipath-linux-2.6
S: Supported
+F: drivers/infiniband/hw/ipath/
IPMI SUBSYSTEM
P: Corey Minyard
@@ -2434,6 +2971,9 @@ M: minyard@acm.org
L: openipmi-developer@lists.sourceforge.net
W: http://openipmi.sourceforge.net/
S: Supported
+F: Documentation/IPMI.txt
+F: drivers/char/ipmi/
+F: include/linux/ipmi*
IPS SCSI RAID DRIVER
P: Adaptec OEM Raid Solutions
@@ -2441,6 +2981,7 @@ M: aacraid@adaptec.com
L: linux-scsi@vger.kernel.org
W: http://www.adaptec.com/
S: Maintained
+F: drivers/scsi/ips*
IPVS
P: Wensong Zhang
@@ -2452,6 +2993,8 @@ M: ja@ssi.bg
L: netdev@vger.kernel.org
L: lvs-devel@vger.kernel.org
S: Maintained
+F: Documentation/networking/ipvs-sysctl.txt
+F: net/netfilter/ipvs/
IPWIRELESS DRIVER
P: Jiri Kosina
@@ -2459,13 +3002,17 @@ M: jkosina@suse.cz
P: David Sterba
M: dsterba@suse.cz
S: Maintained
-T: git://git.kernel.org/pub/scm/linux/kernel/git/jikos/ipwireless_cs.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/ipwireless_cs.git
+F: drivers/char/pcmcia/ipwireless/
IPX NETWORK LAYER
P: Arnaldo Carvalho de Melo
M: acme@ghostprotocols.net
L: netdev@vger.kernel.org
S: Maintained
+F: include/linux/ipx.h
+F: include/net/ipx.h
+F: net/ipx/
IRDA SUBSYSTEM
P: Samuel Ortiz
@@ -2473,27 +3020,40 @@ M: samuel@sortiz.org
L: irda-users@lists.sourceforge.net (subscribers-only)
W: http://irda.sourceforge.net/
S: Maintained
+F: Documentation/networking/irda.txt
+F: drivers/net/irda/
+F: include/net/irda/
+F: net/irda/
ISAPNP
P: Jaroslav Kysela
M: perex@perex.cz
S: Maintained
+F: Documentation/isapnp.txt
+F: drivers/pnp/isapnp/
+F: include/linux/isapnp.h
ISCSI
P: Mike Christie
M: michaelc@cs.wisc.edu
L: open-iscsi@googlegroups.com
W: www.open-iscsi.org
-T: git kernel.org:/pub/scm/linux/kernel/mnc/linux-2.6-iscsi.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mnc/linux-2.6-iscsi.git
S: Maintained
+F: drivers/scsi/*iscsi*
+F: include/scsi/*iscsi*
ISDN SUBSYSTEM
P: Karsten Keil
M: isdn@linux-pingi.de
L: isdn4linux@listserv.isdn4linux.de (subscribers-only)
W: http://www.isdn4linux.de
-T: git kernel.org:/pub/scm/linux/kernel/kkeil/isdn-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kkeil/isdn-2.6.git
S: Maintained
+F: Documentation/isdn/
+F: drivers/isdn/
+F: include/linux/isdn.h
+F: include/linux/isdn/
ISDN SUBSYSTEM (Eicon active card driver)
P: Armin Schindler
@@ -2501,6 +3061,7 @@ M: mac@melware.de
L: isdn4linux@listserv.isdn4linux.de (subscribers-only)
W: http://www.melware.de
S: Maintained
+F: drivers/isdn/hardware/eicon/
IVTV VIDEO4LINUX DRIVER
P: Hans Verkuil
@@ -2508,23 +3069,29 @@ M: hverkuil@xs4all.nl
L: ivtv-devel@ivtvdriver.org
L: ivtv-users@ivtvdriver.org
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
W: http://www.ivtvdriver.org
S: Maintained
+F: Documentation/video4linux/*.ivtv
+F: drivers/media/video/ivtv/
+F: include/linux/ivtv*
JFS FILESYSTEM
P: Dave Kleikamp
M: shaggy@austin.ibm.com
L: jfs-discussion@lists.sourceforge.net
W: http://jfs.sourceforge.net/
-T: git kernel.org:/pub/scm/linux/kernel/git/shaggy/jfs-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/shaggy/jfs-2.6.git
S: Supported
+F: Documentation/filesystems/jfs.txt
+F: fs/jfs/
JME NETWORK DRIVER
P: Guo-Fu Tseng
M: cooldavid@cooldavid.org
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/jme.*
JOURNALLING FLASH FILE SYSTEM V2 (JFFS2)
P: David Woodhouse
@@ -2532,24 +3099,36 @@ M: dwmw2@infradead.org
L: linux-mtd@lists.infradead.org
W: http://www.linux-mtd.infradead.org/doc/jffs2.html
S: Maintained
+F: fs/jffs2/
+F: include/linux/jffs2.h
+F: include/mtd/jffs2-user.h
JOURNALLING LAYER FOR BLOCK DEVICES (JBD)
-P: Stephen Tweedie, Andrew Morton
-M: sct@redhat.com, akpm@linux-foundation.org
+P: Stephen Tweedie
+M: sct@redhat.com
+P: Andrew Morton
+M: akpm@linux-foundation.org
L: linux-ext4@vger.kernel.org
S: Maintained
+F: fs/jbd*/
+F: include/linux/ext*jbd*.h
+F: include/linux/jbd*.h
K8TEMP HARDWARE MONITORING DRIVER
P: Rudolf Marek
M: r.marek@assembler.cz
L: lm-sensors@lm-sensors.org
S: Maintained
+F: Documentation/hwmon/k8temp
+F: drivers/hwmon/k8temp.c
KCONFIG
P: Roman Zippel
M: zippel@linux-m68k.org
L: linux-kbuild@vger.kernel.org
S: Maintained
+F: Documentation/kbuild/kconfig-language.txt
+F: scripts/kconfig/
KDUMP
P: Vivek Goyal
@@ -2560,26 +3139,32 @@ L: kexec@lists.infradead.org
L: linux-kernel@vger.kernel.org
W: http://lse.sourceforge.net/kdump/
S: Maintained
+F: Documentation/kdump/
KERNEL AUTOMOUNTER (AUTOFS)
P: H. Peter Anvin
M: hpa@zytor.com
L: autofs@linux.kernel.org
S: Odd Fixes
+F: fs/autofs/
KERNEL AUTOMOUNTER v4 (AUTOFS4)
P: Ian Kent
M: raven@themaw.net
L: autofs@linux.kernel.org
S: Maintained
+F: fs/autofs4/
-KERNEL BUILD (kbuild: Makefile, scripts/Makefile.*)
+KERNEL BUILD
P: Sam Ravnborg
M: sam@ravnborg.org
-T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild-next.git
-T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild-fixes.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fixes.git
L: linux-kbuild@vger.kernel.org
S: Maintained
+F: Documentation/kbuild/
+F: Makefile
+F: scripts/Makefile.*
KERNEL JANITORS
P: Several
@@ -2595,6 +3180,13 @@ M: neilb@suse.de
L: linux-nfs@vger.kernel.org
W: http://nfs.sourceforge.net/
S: Supported
+F: fs/nfsd/
+F: include/linux/nfsd/
+F: fs/lockd/
+F: fs/nfs_common/
+F: net/sunrpc/
+F: include/linux/lockd/
+F: include/linux/sunrpc/
KERNEL VIRTUAL MACHINE (KVM)
P: Avi Kivity
@@ -2602,6 +3194,11 @@ M: avi@redhat.com
L: kvm@vger.kernel.org
W: http://kvm.qumranet.com
S: Supported
+F: Documentation/*/kvm.txt
+F: arch/*/kvm/
+F: arch/*/include/asm/kvm*
+F: include/linux/kvm*
+F: virt/kvm/
KERNEL VIRTUAL MACHINE (KVM) FOR AMD-V
P: Joerg Roedel
@@ -2609,6 +3206,9 @@ M: joerg.roedel@amd.com
L: kvm@vger.kernel.org
W: http://kvm.qumranet.com
S: Supported
+F: arch/x86/include/asm/svm.h
+F: arch/x86/kvm/kvm_svm.h
+F: arch/x86/kvm/svm.c
KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC
P: Hollis Blanchard
@@ -2616,6 +3216,8 @@ M: hollisb@us.ibm.com
L: kvm-ppc@vger.kernel.org
W: http://kvm.qumranet.com
S: Supported
+F: arch/powerpc/include/asm/kvm*
+F: arch/powerpc/kvm/
KERNEL VIRTUAL MACHINE For Itanium (KVM/IA64)
P: Xiantao Zhang
@@ -2623,6 +3225,9 @@ M: xiantao.zhang@intel.com
L: kvm-ia64@vger.kernel.org
W: http://kvm.qumranet.com
S: Supported
+F: Documentation/ia64/kvm.txt
+F: arch/ia64/include/asm/kvm*
+F: arch/ia64/kvm/
KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
P: Carsten Otte
@@ -2633,6 +3238,9 @@ M: linux390@de.ibm.com
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
+F: Documentation/s390/kvm.txt
+F: arch/s390/include/asm/kvm*
+F: arch/s390/kvm/
KEXEC
P: Eric Biederman
@@ -2641,12 +3249,28 @@ W: http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/
L: linux-kernel@vger.kernel.org
L: kexec@lists.infradead.org
S: Maintained
+F: include/linux/kexec.h
+F: kernel/kexec.c
KGDB
P: Jason Wessel
M: jason.wessel@windriver.com
L: kgdb-bugreport@lists.sourceforge.net
S: Maintained
+F: Documentation/DocBook/kgdb.tmpl
+F: drivers/misc/kgdbts.c
+F: drivers/serial/kgdboc.c
+F: include/linux/kgdb.h
+F: kernel/kgdb.c
+
+KMEMTRACE
+P: Eduard - Gabriel Munteanu
+M: eduard.munteanu@linux360.ro
+L: linux-kernel@vger.kernel.org
+S: Maintained
+F: Documentation/vm/kmemtrace.txt
+F: include/trace/kmemtrace.h
+F: kernel/trace/kmemtrace.c
KPROBES
P: Ananth N Mavinakayanahalli
@@ -2659,6 +3283,9 @@ P: Masami Hiramatsu
M: mhiramat@redhat.com
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/kprobes.txt
+F: include/linux/kprobes.h
+F: kernel/kprobes.c
KS0108 LCD CONTROLLER DRIVER
P: Miguel Ojeda Sandonis
@@ -2667,21 +3294,31 @@ L: linux-kernel@vger.kernel.org
W: http://miguelojeda.es/auxdisplay.htm
W: http://jair.lab.fi.uva.es/~migojed/auxdisplay.htm
S: Maintained
+F: Documentation/auxdisplay/ks0108
+F: drivers/auxdisplay/ks0108.c
+F: include/linux/ks0108.h
LAPB module
L: linux-x25@vger.kernel.org
S: Orphan
+F: Documentation/networking/lapb-module.txt
+F: include/*/lapb.h
+F: net/lapb/
LASI 53c700 driver for PARISC
P: James E.J. Bottomley
M: James.Bottomley@HansenPartnership.com
L: linux-scsi@vger.kernel.org
S: Maintained
+F: Documentation/scsi/53c700.txt
+F: drivers/scsi/53c700*
LED SUBSYSTEM
P: Richard Purdie
M: rpurdie@rpsys.net
S: Maintained
+F: drivers/leds/
+F: include/linux/leds.h
LEGO USB Tower driver
P: Juergen Stuber
@@ -2689,6 +3326,7 @@ M: starblue@users.sourceforge.net
L: legousb-devel@lists.sourceforge.net
W: http://legousb.sourceforge.net/
S: Maintained
+F: drivers/usb/misc/legousbtower.c
LGUEST
P: Rusty Russell
@@ -2696,6 +3334,11 @@ M: rusty@rustcorp.com.au
L: lguest@ozlabs.org
W: http://lguest.ozlabs.org/
S: Maintained
+F: Documentation/lguest/
+F: arch/x86/lguest/
+F: drivers/lguest/
+F: include/linux/lguest*.h
+F: arch/x86/include/asm/lguest*.h
LINUX FOR IBM pSERIES (RS/6000)
P: Paul Mackerras
@@ -2703,12 +3346,6 @@ M: paulus@au.ibm.com
W: http://www.ibm.com/linux/ltc/projects/ppc
S: Supported
-LINUX FOR NCR VOYAGER
-P: James Bottomley
-M: James.Bottomley@HansenPartnership.com
-W: http://www.hansenpartnership.com/voyager
-S: Maintained
-
LINUX FOR POWERPC (32-BIT AND 64-BIT)
P: Benjamin Herrenschmidt
M: benh@kernel.crashing.org
@@ -2716,7 +3353,7 @@ P: Paul Mackerras
M: paulus@samba.org
W: http://www.penguinppc.org/
L: linuxppc-dev@ozlabs.org
-T: git kernel.org:/pub/scm/linux/kernel/git/benh/powerpc.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git
S: Supported
LINUX FOR POWER MACINTOSH
@@ -2741,7 +3378,7 @@ P: Matt Porter
M: mporter@kernel.crashing.org
W: http://www.penguinppc.org/
L: linuxppc-dev@ozlabs.org
-T: git kernel.org:/pub/scm/linux/kernel/git/jwboyer/powerpc.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc.git
S: Maintained
LINUX FOR POWERPC EMBEDDED XILINX VIRTEX
@@ -2778,30 +3415,39 @@ LINUX SECURITY MODULE (LSM) FRAMEWORK
P: Chris Wright
M: chrisw@sous-sol.org
L: linux-security-module@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/chrisw/lsm-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/chrisw/lsm-2.6.git
S: Supported
LLC (802.2)
P: Arnaldo Carvalho de Melo
M: acme@ghostprotocols.net
S: Maintained
+F: include/linux/llc.h
+F: include/net/llc*
+F: net/llc/
LIS3LV02D ACCELEROMETER DRIVER
P: Eric Piel
M: eric.piel@tremplin-utc.net
S: Maintained
+F: Documentation/hwmon/lis3lv02d
+F: drivers/hwmon/lis3lv02d.*
LM83 HARDWARE MONITOR DRIVER
P: Jean Delvare
M: khali@linux-fr.org
L: lm-sensors@lm-sensors.org
S: Maintained
+F: Documentation/hwmon/lm83
+F: drivers/hwmon/lm83.c
LM90 HARDWARE MONITOR DRIVER
P: Jean Delvare
M: khali@linux-fr.org
L: lm-sensors@lm-sensors.org
S: Maintained
+F: Documentation/hwmon/lm90
+F: drivers/hwmon/lm90.c
LOCKDEP AND LOCKSTAT
P: Peter Zijlstra
@@ -2809,8 +3455,12 @@ M: peterz@infradead.org
P: Ingo Molnar
M: mingo@redhat.com
L: linux-kernel@vger.kernel.org
-T: git://git.kernel.org/pub/scm/linux/kernel/git/peterz/linux-2.6-lockdep.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/peterz/linux-2.6-lockdep.git
S: Maintained
+F: Documentation/lockdep*.txt
+F: Documentation/lockstat.txt
+F: include/linux/lockdep.h
+F: kernel/lockdep*
LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP/Vista Dynamic Disks)
P: Richard Russon (FlatCap)
@@ -2818,6 +3468,8 @@ M: ldm@flatcap.org
L: linux-ntfs-dev@lists.sourceforge.net
W: http://www.linux-ntfs.org/content/view/19/37/
S: Maintained
+F: Documentation/ldm.txt
+F: fs/partitions/ldm.*
LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
P: Eric Moore
@@ -2827,12 +3479,14 @@ L: DL-MPTFusionLinux@lsi.com
L: linux-scsi@vger.kernel.org
W: http://www.lsilogic.com/support
S: Supported
+F: drivers/message/fusion/
LSILOGIC/SYMBIOS/NCR 53C8XX and 53C1010 PCI-SCSI drivers
P: Matthew Wilcox
M: matthew@wil.cx
L: linux-scsi@vger.kernel.org
S: Maintained
+F: drivers/scsi/sym53c8xx_2/
LTP (Linux Test Project)
P: Subrata Modak
@@ -2841,7 +3495,7 @@ P: Mike Frysinger
M: vapier@gentoo.org
L: ltp-list@lists.sourceforge.net (subscribers-only)
W: http://ltp.sourceforge.net/
-T: git kernel.org/pub/scm/linux/kernel/git/galak/ltp.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/ltp.git
S: Maintained
M32R ARCHITECTURE
@@ -2851,6 +3505,8 @@ L: linux-m32r@ml.linux-m32r.org
L: linux-m32r-ja@ml.linux-m32r.org (in Japanese)
W: http://www.linux-m32r.org/
S: Maintained
+F: arch/m32r/
+F: include/asm-m32r/
M68K ARCHITECTURE
P: Geert Uytterhoeven
@@ -2859,8 +3515,10 @@ P: Roman Zippel
M: zippel@linux-m68k.org
L: linux-m68k@lists.linux-m68k.org
W: http://www.linux-m68k.org/
-T: git git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git
S: Maintained
+F: arch/m68k/
+F: drivers/zorro/
M68K ON APPLE MACINTOSH
P: Joshua Thompson
@@ -2868,20 +3526,25 @@ M: funaho@jurai.org
W: http://www.mac.linux-m68k.org/
L: linux-m68k@lists.linux-m68k.org
S: Maintained
+F: arch/m68k/mac/
M68K ON HP9000/300
P: Philip Blundell
M: philb@gnu.org
W: http://www.tazenda.demon.co.uk/phil/linux-hp
S: Maintained
+F: arch/m68k/hp300/
MAC80211
P: Johannes Berg
M: johannes@sipsolutions.net
L: linux-wireless@vger.kernel.org
W: http://linuxwireless.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
S: Maintained
+F: Documentation/networking/mac80211-injection.txt
+F: include/net/mac80211.h
+F: net/mac80211/
MAC80211 PID RATE CONTROL
P: Stefano Brivio
@@ -2890,14 +3553,17 @@ P: Mattias Nissler
M: mattias.nissler@gmx.de
L: linux-wireless@vger.kernel.org
W: http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/PID
-T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
S: Maintained
+F: net/mac80211/rc80211_pid*
MACVLAN DRIVER
P: Patrick McHardy
M: kaber@trash.net
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/macvlan.c
+F: include/linux/if_macvlan.h
MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
P: Michael Kerrisk
@@ -2911,12 +3577,21 @@ P: Dan Williams
M: dcbw@redhat.com
L: libertas-dev@lists.infradead.org
S: Maintained
+F: drivers/net/wireless/libertas/
MARVELL MV643XX ETHERNET DRIVER
P: Lennert Buytenhek
M: buytenh@marvell.com
L: netdev@vger.kernel.org
S: Supported
+F: drivers/net/mv643xx_eth.*
+F: include/linux/mv643xx.h
+
+MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
+P: Nicolas Pitre
+M: nico@cam.org
+L: linux-kernel@vger.kernel.org
+S: Maintained
MARVELL YUKON / SYSKONNECT DRIVER
P: Mirko Lindner
@@ -2931,12 +3606,31 @@ P: Petr Vandrovec
M: vandrove@vc.cvut.cz
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
+F: drivers/video/matrox/matroxfb_*
+F: include/linux/matroxfb.h
MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
P: Hans J. Koch
M: hjk@linutronix.de
L: lm-sensors@lm-sensors.org
S: Maintained
+F: Documentation/hwmon/max6650
+F: drivers/hwmon/max6650.c
+
+MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
+P: Mauro Carvalho Chehab
+M: mchehab@infradead.org
+P: LinuxTV.org Project
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+S: Maintained
+F: Documentation/dvb/
+F: Documentation/video4linux/
+F: drivers/media/
+F: include/media/
+F: include/linux/dvb/
+F: include/linux/videodev*.h
MEGARAID SCSI DRIVERS
P: Neela Syam Kolli
@@ -2944,12 +3638,17 @@ M: megaraidlinux@lsi.com
L: linux-scsi@vger.kernel.org
W: http://megaraid.lsilogic.com
S: Maintained
+F: Documentation/scsi/megaraid.txt
+F: drivers/scsi/megaraid.*
+F: drivers/scsi/megaraid/
MEMORY MANAGEMENT
L: linux-mm@kvack.org
L: linux-kernel@vger.kernel.org
W: http://www.linux-mm.org
S: Maintained
+F: include/linux/mm.h
+F: mm/
MEMORY RESOURCE CONTROLLER
P: Balbir Singh
@@ -2961,6 +3660,7 @@ M: kamezawa.hiroyu@jp.fujitsu.com
L: linux-mm@kvack.org
L: linux-kernel@vger.kernel.org
S: Maintained
+F: mm/memcontrol.c
MEMORY TECHNOLOGY DEVICES (MTD)
P: David Woodhouse
@@ -2969,55 +3669,84 @@ W: http://www.linux-mtd.infradead.org/
L: linux-mtd@lists.infradead.org
T: git git://git.infradead.org/mtd-2.6.git
S: Maintained
+F: drivers/mtd/
+F: include/linux/mtd/
+F: include/mtd/
+
+MICROBLAZE ARCHITECTURE
+P: Michal Simek
+M: monstr@monstr.eu
+L: microblaze-uclinux@itee.uq.edu.au
+W: http://www.monstr.eu/fdt/
+T: git git://git.monstr.eu/linux-2.6-microblaze.git
+S: Supported
+F: arch/microblaze/
MICROTEK X6 SCANNER
P: Oliver Neukum
M: oliver@neukum.name
S: Maintained
+F: drivers/usb/image/microtek.*
MIPS
P: Ralf Baechle
M: ralf@linux-mips.org
W: http://www.linux-mips.org/
L: linux-mips@linux-mips.org
-T: git www.linux-mips.org:/pub/scm/linux.git
+T: git git://git.linux-mips.org/pub/scm/linux.git
S: Supported
+F: Documentation/mips/
+F: arch/mips/
MISCELLANEOUS MCA-SUPPORT
P: James Bottomley
M: James.Bottomley@HansenPartnership.com
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/ia64/mca.txt
+F: Documentation/mca.txt
+F: drivers/mca/
+F: include/linux/mca*
MODULE SUPPORT
P: Rusty Russell
M: rusty@rustcorp.com.au
L: linux-kernel@vger.kernel.org
S: Maintained
+F: include/linux/module.h
+F: kernel/module.c
MOTION EYE VAIO PICTUREBOOK CAMERA DRIVER
P: Stelian Pop
M: stelian@popies.net
W: http://popies.net/meye/
S: Maintained
+F: Documentation/video4linux/meye.txt
+F: drivers/media/video/meye.*
+F: include/linux/meye.h
MOTOROLA IMX MMC/SD HOST CONTROLLER INTERFACE DRIVER
P: Pavel Pisa
M: ppisa@pikron.com
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
+F: drivers/mmc/host/imxmmc.*
MOUSE AND MISC DEVICES [GENERAL]
P: Alessandro Rubini
M: rubini@ipvvis.unipv.it
L: linux-kernel@vger.kernel.org
S: Maintained
+F: drivers/input/mouse/
+F: include/linux/gpio_mouse.h
MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD
P: Jiri Slaby
M: jirislaby@gmail.com
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/serial/moxa-smartio
+F: drivers/char/mxser.*
MSI LAPTOP SUPPORT
P: Lennart Poettering
@@ -3025,42 +3754,54 @@ M: mzxreary@0pointer.de
W: https://tango.0pointer.de/mailman/listinfo/s270-linux
W: http://0pointer.de/lennart/tchibo.html
S: Maintained
+F: drivers/platform/x86/msi-laptop.c
MULTIFUNCTION DEVICES (MFD)
P: Samuel Ortiz
-M: sameo@openedhand.com
+M: sameo@linux.intel.com
L: linux-kernel@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git
S: Supported
+F: drivers/mfd/
MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM
P: Pierre Ossman
-M: drzeus-mmc@drzeus.cx
+M: pierre@ossman.eu
L: linux-kernel@vger.kernel.org
S: Maintained
+F: drivers/mmc/
+F: include/linux/mmc/
MULTIMEDIA CARD (MMC) ETC. OVER SPI
P: David Brownell
M: dbrownell@users.sourceforge.net
L: linux-kernel@vger.kernel.org
S: Odd Fixes
+F: drivers/mmc/host/mmc_spi.c
+F: include/linux/spi/mmc_spi.h
MULTISOUND SOUND DRIVER
P: Andrew Veliath
M: andrewtv@usa.net
S: Maintained
+F: Documentation/sound/oss/MultiSound
+F: sound/oss/msnd*
MULTITECH MULTIPORT CARD (ISICOM)
P: Jiri Slaby
M: jirislaby@gmail.com
L: linux-kernel@vger.kernel.org
S: Maintained
+F: drivers/char/isicom.c
+F: include/linux/isicom.h
MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
P: Felipe Balbi
M: felipe.balbi@nokia.com
L: linux-usb@vger.kernel.org
-T: git gitorious.org:/musb/mainline.git
+T: git git://gitorious.org/musb/mainline.git
S: Maintained
+F: drivers/usb/musb/
MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE)
P: Andrew Gallatin
@@ -3070,23 +3811,27 @@ M: brice@myri.com
L: netdev@vger.kernel.org
W: http://www.myri.com/scs/download-Myri10GE.html
S: Supported
+F: drivers/net/myri10ge/
NATSEMI ETHERNET DRIVER (DP8381x)
P: Tim Hockin
M: thockin@hockin.org
S: Maintained
+F: drivers/net/natsemi.c
NCP FILESYSTEM
P: Petr Vandrovec
M: vandrove@vc.cvut.cz
L: linware@sh.cvut.cz
S: Maintained
+F: fs/ncpfs/
NCR DUAL 700 SCSI DRIVER (MICROCHANNEL)
P: James E.J. Bottomley
M: James.Bottomley@HansenPartnership.com
L: linux-scsi@vger.kernel.org
S: Maintained
+F: drivers/scsi/NCR_D700.*
NETEFFECT IWARP RNIC DRIVER (IW_NES)
P: Faisal Latif
@@ -3103,6 +3848,7 @@ P: Stephen Hemminger
M: shemminger@linux-foundation.org
L: netem@lists.linux-foundation.org
S: Maintained
+F: net/sched/sch_netem.c
NETERION (S2IO) 10GbE DRIVER (xframe/vxge)
P: Ramkrishna Vepa
@@ -3119,6 +3865,8 @@ L: netdev@vger.kernel.org
W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/Linux?Anonymous
W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/X3100Linux?Anonymous
S: Supported
+F: Documentation/networking/s2io.txt
+F: drivers/net/s2io*
NETFILTER/IPTABLES/IPCHAINS
P: Rusty Russell
@@ -3134,6 +3882,12 @@ L: coreteam@netfilter.org
W: http://www.netfilter.org/
W: http://www.iptables.org/
S: Supported
+F: include/linux/netfilter*
+F: include/linux/netfilter/
+F: include/net/netfilter/
+F: net/*/netfilter.c
+F: net/*/netfilter/
+F: net/netfilter/
NETLABEL
P: Paul Moore
@@ -3141,6 +3895,9 @@ M: paul.moore@hp.com
W: http://netlabel.sf.net
L: netdev@vger.kernel.org
S: Supported
+F: Documentation/netlabel/
+F: include/net/netlabel.h
+F: net/netlabel/
NETROM NETWORK LAYER
P: Ralf Baechle
@@ -3148,18 +3905,25 @@ M: ralf@linux-mips.org
L: linux-hams@vger.kernel.org
W: http://www.linux-ax25.org/
S: Maintained
+F: include/linux/netrom.h
+F: include/net/netrom.h
+F: net/netrom/
NETWORK BLOCK DEVICE (NBD)
P: Paul Clements
M: Paul.Clements@steeleye.com
S: Maintained
+F: Documentation/blockdev/nbd.txt
+F: drivers/block/nbd.c
+F: include/linux/nbd.h
NETWORK DEVICE DRIVERS
P: Jeff Garzik
M: jgarzik@pobox.com
L: netdev@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
S: Maintained
+F: drivers/net/
NETWORKING [GENERAL]
P: Networking Team
@@ -3167,6 +3931,8 @@ M: netdev@vger.kernel.org
L: netdev@vger.kernel.org
W: http://linux-net.osdl.org/
S: Maintained
+F: net/
+F: include/net/
NETWORKING [IPv4/IPv6]
P: David S. Miller
@@ -3182,8 +3948,11 @@ M: yoshfuji@linux-ipv6.org
P: Patrick McHardy
M: kaber@trash.net
L: netdev@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
S: Maintained
+F: net/ipv4/
+F: net/ipv6/
+F: include/net/ip*
NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK)
P: Paul Moore
@@ -3195,8 +3964,11 @@ NETWORKING [WIRELESS]
P: John W. Linville
M: linville@tuxdriver.com
L: linux-wireless@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
S: Maintained
+F: net/wireless/
+F: include/net/ieee80211*
+F: include/net/wireless.h
NETXEN (1/10) GbE SUPPORT
P: Dhananjay Phadke
@@ -3204,6 +3976,7 @@ M: dhananjay@netxen.com
L: netdev@vger.kernel.org
W: http://www.netxen.com
S: Supported
+F: drivers/net/netxen/
NFS, SUNRPC, AND LOCKD CLIENTS
P: Trond Myklebust
@@ -3212,6 +3985,13 @@ L: linux-nfs@vger.kernel.org
W: http://client.linux-nfs.org
T: git git://git.linux-nfs.org/pub/linux/nfs-2.6.git
S: Maintained
+F: fs/lockd/
+F: fs/nfs/
+F: fs/nfs_common/
+F: net/sunrpc/
+F: include/linux/lockd/
+F: include/linux/nfs*
+F: include/linux/sunrpc/
NI5010 NETWORK DRIVER
P: Jan-Pascal van Best
@@ -3220,12 +4000,25 @@ P: Andreas Mohr
M: andi@lisas.de
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/ni5010.*
+
+NILFS2 FILESYSTEM
+P: KONISHI Ryusuke
+M: konishi.ryusuke@lab.ntt.co.jp
+L: users@nilfs.org
+W: http://www.nilfs.org/en/
+S: Supported
+F: Documentation/filesystems/nilfs2.txt
+F: fs/nilfs2/
+F: include/linux/nilfs2_fs.h
NINJA SCSI-3 / NINJA SCSI-32Bi (16bit/CardBus) PCMCIA SCSI HOST ADAPTER DRIVER
P: YOKOTA Hiroshi
M: yokota@netlab.is.tsukuba.ac.jp
W: http://www.netlab.is.tsukuba.ac.jp/~yokota/izumi/ninja/
S: Maintained
+F: Documentation/scsi/NinjaSCSI.txt
+F: drivers/scsi/pcmcia/nsp_*
NINJA SCSI-32Bi/UDE PCI/CARDBUS SCSI HOST ADAPTER DRIVER
P: GOTO Masanori
@@ -3234,6 +4027,8 @@ P: YOKOTA Hiroshi
M: yokota@netlab.is.tsukuba.ac.jp
W: http://www.netlab.is.tsukuba.ac.jp/~yokota/izumi/ninja/
S: Maintained
+F: Documentation/scsi/NinjaSCSI.txt
+F: drivers/scsi/nsp32*
NTFS FILESYSTEM
P: Anton Altaparmakov
@@ -3241,43 +4036,55 @@ M: aia21@cantab.net
L: linux-ntfs-dev@lists.sourceforge.net
L: linux-kernel@vger.kernel.org
W: http://www.linux-ntfs.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git
S: Maintained
+F: Documentation/filesystems/ntfs.txt
+F: fs/ntfs/
NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER
P: Antonino Daplas
M: adaplas@gmail.com
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
+F: drivers/video/riva/
+F: drivers/video/nvidia/
OMFS FILESYSTEM
P: Bob Copeland
M: me@bobcopeland.com
L: linux-karma-devel@lists.sourceforge.net
S: Maintained
+F: Documentation/filesystems/omfs.txt
+F: fs/omfs/
OMNIKEY CARDMAN 4000 DRIVER
P: Harald Welte
M: laforge@gnumonks.org
S: Maintained
+F: drivers/char/pcmcia/cm4000_cs.c
+F: include/linux/cm4000_cs.h
OMNIKEY CARDMAN 4040 DRIVER
P: Harald Welte
M: laforge@gnumonks.org
S: Maintained
+F: drivers/char/pcmcia/cm4040_cs.*
OMNIVISION OV7670 SENSOR DRIVER
P: Jonathan Corbet
M: corbet@lwn.net
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
+F: drivers/media/video/ov7670.c
ONENAND FLASH DRIVER
P: Kyungmin Park
M: kyungmin.park@samsung.com
L: linux-mtd@lists.infradead.org
S: Maintained
+F: drivers/mtd/onenand/
+F: include/linux/mtd/onenand*.h
ONSTREAM SCSI TAPE DRIVER
P: Willem Riede
@@ -3285,18 +4092,25 @@ M: osst@riede.org
L: osst-users@lists.sourceforge.net
L: linux-scsi@vger.kernel.org
S: Maintained
+F: drivers/scsi/osst*
+F: drivers/scsi/st*
OPENCORES I2C BUS DRIVER
P: Peter Korsgaard
M: jacmet@sunsite.dk
L: linux-i2c@vger.kernel.org
S: Maintained
+F: Documentation/i2c/busses/i2c-ocores
+F: drivers/i2c/busses/i2c-ocores.c
OPROFILE
P: Robert Richter
M: robert.richter@amd.com
L: oprofile-list@lists.sf.net
S: Maintained
+F: arch/*/oprofile/
+F: drivers/oprofile/
+F: include/linux/oprofile.h
ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
P: Mark Fasheh
@@ -3307,6 +4121,9 @@ L: ocfs2-devel@oss.oracle.com (moderated for non-subscribers)
W: http://oss.oracle.com/projects/ocfs2/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2.git
S: Supported
+F: Documentation/filesystems/ocfs2.txt
+F: Documentation/filesystems/dlmfs.txt
+F: fs/ocfs2/
ORINOCO DRIVER
P: Pavel Roskin
@@ -3318,6 +4135,7 @@ L: orinoco-users@lists.sourceforge.net
L: orinoco-devel@lists.sourceforge.net
W: http://www.nongnu.org/orinoco/
S: Maintained
+F: drivers/net/wireless/orinoco/
OSD LIBRARY
P: Boaz Harrosh
@@ -3326,7 +4144,7 @@ P: Benny Halevy
M: bhalevy@panasas.com
L: osd-dev@open-osd.org
W: http://open-osd.org
-T: git://git.open-osd.org/open-osd.git
+T: git git://git.open-osd.org/open-osd.git
S: Maintained
P54 WIRELESS DRIVER
@@ -3334,25 +4152,29 @@ P: Michael Wu
M: flamingice@sourmilk.net
L: linux-wireless@vger.kernel.org
W: http://prism54.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git
S: Maintained
+F: drivers/net/wireless/p54/
PA SEMI ETHERNET DRIVER
P: Olof Johansson
M: olof@lixom.net
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/pasemi_mac.*
PA SEMI SMBUS DRIVER
P: Olof Johansson
M: olof@lixom.net
L: linux-i2c@vger.kernel.org
S: Maintained
+F: drivers/i2c/busses/i2c-pasemi.c
PANASONIC LAPTOP ACPI EXTRAS DRIVER
P: Harald Welte
M: laforge@gnumonks.org
S: Maintained
+F: drivers/platform/x86/panasonic-laptop.c
PANASONIC MN10300/AM33 PORT
P: David Howells
@@ -3362,10 +4184,16 @@ M: yasutake.koichi@jp.panasonic.com
L: linux-am33-list@redhat.com (moderated for non-subscribers)
W: ftp://ftp.redhat.com/pub/redhat/gnupro/AM33/
S: Maintained
+F: Documentation/mn10300/
+F: arch/mn10300/
PARALLEL PORT SUPPORT
L: linux-parport@lists.infradead.org (subscribers-only)
S: Orphan
+F: drivers/parport/
+F: include/linux/parport*.h
+F: drivers/char/ppdev.c
+F: include/linux/ppdev.h
PARAVIRT_OPS INTERFACE
P: Jeremy Fitzhardinge
@@ -3379,6 +4207,9 @@ M: rusty@rustcorp.com.au
L: virtualization@lists.osdl.org
L: linux-kernel@vger.kernel.org
S: Supported
+F: Documentation/ia64/paravirt_ops.txt
+F: arch/*/kernel/paravirt*
+F: arch/*/include/asm/paravirt.h
PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES
P: Tim Waugh
@@ -3386,6 +4217,8 @@ M: tim@cyberelk.net
L: linux-parport@lists.infradead.org (subscribers-only)
W: http://www.torque.net/linux-pp.html
S: Maintained
+F: Documentation/blockdev/paride.txt
+F: drivers/block/paride/
PARISC ARCHITECTURE
P: Kyle McMartin
@@ -3394,19 +4227,31 @@ P: Helge Deller
M: deller@gmx.de
L: linux-parisc@vger.kernel.org
W: http://www.parisc-linux.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
S: Maintained
+F: arch/parisc/
+F: drivers/parisc/
PC87360 HARDWARE MONITORING DRIVER
P: Jim Cromie
M: jim.cromie@gmail.com
L: lm-sensors@lm-sensors.org
S: Maintained
+F: Documentation/hwmon/pc87360
+F: drivers/hwmon/pc87360.c
PC8736x GPIO DRIVER
P: Jim Cromie
M: jim.cromie@gmail.com
S: Maintained
+F: drivers/char/pc8736x_gpio.c
+
+PCA9532 LED DRIVER
+P: Riku Voipio
+M: riku.voipio@iki.fi
+S: Maintained
+F: drivers/leds/leds-pca9532.c
+F: include/linux/leds-pca9532.h
PCI ERROR RECOVERY
P: Linas Vepstas
@@ -3414,63 +4259,82 @@ M: linas@austin.ibm.com
L: linux-kernel@vger.kernel.org
L: linux-pci@vger.kernel.org
S: Supported
+F: Documentation/PCI/pci-error-recovery.txt
+F: Documentation/powerpc/eeh-pci-error-recovery.txt
PCI SUBSYSTEM
P: Jesse Barnes
M: jbarnes@virtuousgeek.org
L: linux-kernel@vger.kernel.org
L: linux-pci@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
S: Supported
+F: Documentation/PCI/
+F: drivers/pci/
+F: include/linux/pci*
PCIE HOTPLUG DRIVER
P: Kristen Carlson Accardi
M: kristen.c.accardi@intel.com
L: linux-pci@vger.kernel.org
S: Supported
+F: drivers/pci/pcie/
PCMCIA SUBSYSTEM
P: Linux PCMCIA Team
L: linux-pcmcia@lists.infradead.org
W: http://lists.infradead.org/mailman/listinfo/linux-pcmcia
-T: git kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
S: Maintained
+F: Documentation/pcmcia/
+F: drivers/pcmcia/
+F: include/pcmcia/
PCNET32 NETWORK DRIVER
P: Don Fry
M: pcnet32@verizon.net
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/pcnet32.c
PER-TASK DELAY ACCOUNTING
P: Balbir Singh
M: balbir@linux.vnet.ibm.com
L: linux-kernel@vger.kernel.org
S: Maintained
+F: include/linux/delayacct.h
+F: kernel/delayacct.c
PERSONALITY HANDLING
P: Christoph Hellwig
M: hch@infradead.org
L: linux-abi-devel@lists.sourceforge.net
S: Maintained
+F: include/linux/personality.h
PHRAM MTD DRIVER
P: Joern Engel
M: joern@lazybastard.org
L: linux-mtd@lists.infradead.org
S: Maintained
+F: drivers/mtd/devices/phram.c
PKTCDVD DRIVER
P: Peter Osterlund
M: petero2@telia.com
L: linux-kernel@vger.kernel.org
S: Maintained
+F: drivers/block/pktcdvd.c
+F: include/linux/pktcdvd.h
POSIX CLOCKS and TIMERS
P: Thomas Gleixner
M: tglx@linutronix.de
L: linux-kernel@vger.kernel.org
S: Supported
+F: fs/timerfd.c
+F: include/linux/timer*
+F: kernel/*timer*
POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS
P: Anton Vorontsov
@@ -3478,8 +4342,10 @@ M: cbou@mail.ru
P: David Woodhouse
M: dwmw2@infradead.org
L: linux-kernel@vger.kernel.org
-T: git git.infradead.org/battery-2.6.git
+T: git git://git.infradead.org/battery-2.6.git
S: Maintained
+F: include/linux/power_supply.h
+F: drivers/power/power_supply*
PNP SUPPORT
P: Adam Belay
@@ -3487,33 +4353,42 @@ M: abelay@mit.edu
P: Bjorn Helgaas
M: bjorn.helgaas@hp.com
S: Maintained
+F: drivers/pnp/
PNXxxxx I2C DRIVER
P: Vitaly Wool
M: vitalywool@gmail.com
L: linux-i2c@vger.kernel.org
S: Maintained
+F: drivers/i2c/busses/i2c-pnx.c
PPP PROTOCOL DRIVERS AND COMPRESSORS
P: Paul Mackerras
M: paulus@samba.org
L: linux-ppp@vger.kernel.org
S: Maintained
+F: drivers/net/ppp_*
PPP OVER ATM (RFC 2364)
P: Mitchell Blank Jr
M: mitch@sfgoth.com
S: Maintained
+F: net/atm/pppoatm.c
+F: include/linux/atmppp.h
PPP OVER ETHERNET
P: Michal Ostrowski
M: mostrows@earthlink.net
S: Maintained
+F: drivers/net/pppoe.c
+F: drivers/net/pppox.c
PPP OVER L2TP
P: James Chapman
M: jchapman@katalix.com
S: Maintained
+F: drivers/net/pppol2tp.c
+F: include/linux/if_pppol2tp.h
PREEMPTIBLE KERNEL
P: Robert Love
@@ -3522,6 +4397,8 @@ L: linux-kernel@vger.kernel.org
L: kpreempt-tech@lists.sourceforge.net
W: ftp://ftp.kernel.org/pub/linux/kernel/people/rml/preempt-kernel
S: Supported
+F: Documentation/preempt-locking.txt
+F: include/linux/preempt.h
PRISM54 WIRELESS DRIVER
P: Luis R. Rodriguez
@@ -3529,6 +4406,7 @@ M: mcgrof@gmail.com
L: linux-wireless@vger.kernel.org
W: http://prism54.org
S: Maintained
+F: drivers/net/wireless/prism54/
PROMISE DC4030 CACHING DISK CONTROLLER DRIVER
P: Peter Denison
@@ -3541,6 +4419,7 @@ P: Mikael Pettersson
M: mikpe@it.uu.se
L: linux-ide@vger.kernel.org
S: Maintained
+F: drivers/ata/sata_promise.*
PS3 NETWORK SUPPORT
P: Masakazu Mokuno
@@ -3548,6 +4427,7 @@ M: mokuno@sm.sony.co.jp
L: netdev@vger.kernel.org
L: cbe-oss-dev@ozlabs.org
S: Supported
+F: drivers/net/ps3_gelic_net.*
PS3 PLATFORM SUPPORT
P: Geoff Levand
@@ -3555,6 +4435,13 @@ M: geoffrey.levand@am.sony.com
L: linuxppc-dev@ozlabs.org
L: cbe-oss-dev@ozlabs.org
S: Supported
+F: arch/powerpc/boot/ps3*
+F: arch/powerpc/include/asm/lv1call.h
+F: arch/powerpc/include/asm/ps3*.h
+F: arch/powerpc/platforms/ps3/
+F: drivers/*/ps3*
+F: drivers/ps3/
+F: drivers/usb/host/*ps3.c
PS3VRAM DRIVER
P: Jim Paris
@@ -3568,8 +4455,10 @@ M: isely@pobox.com
L: pvrusb2@isely.net (subscribers-only)
L: linux-media@vger.kernel.org
W: http://www.isely.net/pvrusb2/
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
+F: Documentation/video4linux/README.pvrusb2
+F: drivers/media/video/pvrusb2/
PXA2xx/PXA3xx SUPPORT
P: Eric Miao
@@ -3578,6 +4467,12 @@ P: Russell King
M: linux@arm.linux.org.uk
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
+F: arch/arm/mach-pxa/
+F: drivers/pcmcia/pxa2xx*
+F: drivers/spi/pxa2xx*
+F: drivers/usb/gadget/pxa2*
+F: include/sound/pxa2xx-lib.h
+F: sound/soc/pxa/pxa2xx*
PXA168 SUPPORT
P: Eric Miao
@@ -3585,14 +4480,14 @@ M: eric.miao@marvell.com
P: Jason Chagas
M: jason.chagas@marvell.com
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-T: git kernel.org:/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
S: Supported
PXA910 SUPPORT
P: Eric Miao
M: eric.miao@marvell.com
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-T: git kernel.org:/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
S: Supported
PXA MMCI DRIVER
@@ -3609,12 +4504,16 @@ P: Andrew Vasquez
M: linux-driver@qlogic.com
L: linux-scsi@vger.kernel.org
S: Supported
+F: Documentation/scsi/LICENSE.qla2xxx
+F: drivers/scsi/qla2xxx/
QLOGIC QLA3XXX NETWORK DRIVER
P: Ron Mercer
M: linux-driver@qlogic.com
L: netdev@vger.kernel.org
S: Supported
+F: Documentation/networking/LICENSE.qla3xxx
+F: drivers/net/qla3xxx.*
QLOGIC QLGE 10Gb ETHERNET DRIVER
P: Ron Mercer
@@ -3622,6 +4521,7 @@ M: linux-driver@qlogic.com
M: ron.mercer@qlogic.com
L: netdev@vger.kernel.org
S: Supported
+F: drivers/net/qlge/
QNX4 FILESYSTEM
P: Anders Larsen
@@ -3629,18 +4529,24 @@ M: al@alarsen.net
L: linux-kernel@vger.kernel.org
W: http://www.alarsen.net/linux/qnx4fs/
S: Maintained
+F: fs/qnx4/
+F: include/linux/qnx4_fs.h
+F: include/linux/qnxtypes.h
RADEON FRAMEBUFFER DISPLAY DRIVER
P: Benjamin Herrenschmidt
M: benh@kernel.crashing.org
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
+F: drivers/video/aty/radeon*
+F: include/linux/radeonfb.h
RAGE128 FRAMEBUFFER DISPLAY DRIVER
P: Paul Mackerras
M: paulus@samba.org
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
+F: drivers/video/aty/aty128fb.c
RALINK RT2X00 WIRELESS LAN DRIVER
P: rt2x00 project
@@ -3648,36 +4554,43 @@ L: linux-wireless@vger.kernel.org
L: users@rt2x00.serialmonkey.com
W: http://rt2x00.serialmonkey.com/
S: Maintained
-T: git kernel.org:/pub/scm/linux/kernel/git/ivd/rt2x00.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/ivd/rt2x00.git
F: drivers/net/wireless/rt2x00/
RAMDISK RAM BLOCK DEVICE DRIVER
P: Nick Piggin
M: npiggin@suse.de
S: Maintained
+F: Documentation/blockdev/ramdisk.txt
+F: drivers/block/brd.c
RANDOM NUMBER DRIVER
P: Matt Mackall
M: mpm@selenic.com
S: Maintained
+F: drivers/char/random.c
RAPIDIO SUBSYSTEM
P: Matt Porter
M: mporter@kernel.crashing.org
L: linux-kernel@vger.kernel.org
S: Maintained
+F: drivers/rapidio/
RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
P: Corey Thomas
M: coreythomas@charter.net
L: linux-wireless@vger.kernel.org
S: Maintained
+F: drivers/net/wireless/ray*
RCUTORTURE MODULE
P: Josh Triplett
M: josh@freedesktop.org
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/RCU/torture.txt
+F: kernel/rcutorture.c
RDC R-321X SoC
P: Florian Fainelli
@@ -3690,12 +4603,14 @@ P: Florian Fainelli
M: florian.fainelli@telecomint.eu
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/r6040.c
RDS - RELIABLE DATAGRAM SOCKETS
P: Andy Grover
M: andy.grover@oracle.com
L: rds-devel@oss.oracle.com
S: Supported
+F: net/rds/
READ-COPY UPDATE (RCU)
P: Dipankar Sarma
@@ -3703,37 +4618,54 @@ M: dipankar@in.ibm.com
W: http://www.rdrop.com/users/paulmck/rclock/
L: linux-kernel@vger.kernel.org
S: Supported
+F: Documentation/RCU/rcu.txt
+F: Documentation/RCU/rcuref.txt
+F: include/linux/rcupdate.h
+F: include/linux/srcu.h
+F: kernel/rcupdate.c
REAL TIME CLOCK DRIVER
P: Paul Gortmaker
M: p_gortmaker@yahoo.com
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/rtc.txt
+F: drivers/rtc/
+F: include/linux/rtc.h
REAL TIME CLOCK (RTC) SUBSYSTEM
P: Alessandro Zummo
M: a.zummo@towertech.it
L: rtc-linux@googlegroups.com
S: Maintained
+F: Documentation/rtc.txt
+F: drivers/rtc/
+F: include/linux/rtc.h
REISERFS FILE SYSTEM
L: reiserfs-devel@vger.kernel.org
S: Supported
+F: fs/reiserfs/
RFKILL
P: Ivo van Doorn
M: IvDoorn@gmail.com
L: netdev@vger.kernel.org
S: Maintained
-F: net/rfkill
+F Documentation/rfkill.txt
+F: net/rfkill/
RISCOM8 DRIVER
S: Orphan
+F: Documentation/serial/riscom8.txt
+F: drivers/char/riscom8*
ROCKETPORT DRIVER
P: Comtrol Corp.
W: http://www.comtrol.com
S: Maintained
+F: Documentation/serial/rocket.txt
+F: drivers/char/rocket*
ROSE NETWORK LAYER
P: Ralf Baechle
@@ -3741,32 +4673,38 @@ M: ralf@linux-mips.org
L: linux-hams@vger.kernel.org
W: http://www.linux-ax25.org/
S: Maintained
+F: include/linux/rose.h
+F: include/net/rose.h
+F: net/rose/
RTL8180 WIRELESS DRIVER
P: John W. Linville
M: linville@tuxdriver.com
L: linux-wireless@vger.kernel.org
W: http://linuxwireless.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-testing.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
S: Maintained
+F: drivers/net/wireless/rtl818*
RTL8187 WIRELESS DRIVER
-P: Herton Ronaldo Krzesinski
-M: herton@mandriva.com.br
-P: Hin-Tak Leung
-M htl10@users.sourceforge.net
-P: Larry Finger
-M: Larry.Finger@lwfinger.net
-L: linux-wireless@vger.kernel.org
-W: http://linuxwireless.org/
-T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-testing.git
-S: Maintained
+P: Herton Ronaldo Krzesinski
+M: herton@mandriva.com.br
+P: Hin-Tak Leung
+M: htl10@users.sourceforge.net
+P: Larry Finger
+M: Larry.Finger@lwfinger.net
+L: linux-wireless@vger.kernel.org
+W: http://linuxwireless.org/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
+S: Maintained
+F: drivers/net/wireless/rtl818x/rtl8187*
S3 SAVAGE FRAMEBUFFER DRIVER
P: Antonino Daplas
M: adaplas@gmail.com
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
+F: drivers/video/savage/
S390
P: Martin Schwidefsky
@@ -3777,6 +4715,7 @@ M: linux390@de.ibm.com
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
+F: arch/s390/
S390 NETWORK DRIVERS
P: Ursula Braun
@@ -3787,6 +4726,7 @@ M: linux390@de.ibm.com
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
+F: drivers/s390/net/
S390 ZCRYPT DRIVER
P: Felix Beck
@@ -3796,6 +4736,7 @@ M: ralph.wuerthner@de.ibm.com
M: linux390@de.ibm.com
L: linux-s390@vger.kernel.org
S: Supported
+F: drivers/s390/crypto/
S390 ZFCP DRIVER
P: Christof Schmitt
@@ -3806,6 +4747,8 @@ M: linux390@de.ibm.com
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
+F: Documentation/s390/zfcpdump.txt
+F: drivers/s390/scsi/zfcp_*
S390 IUCV NETWORK LAYER
P: Ursula Braun
@@ -3814,6 +4757,9 @@ M: linux390@de.ibm.com
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
+F: drivers/s390/net/*iucv*
+F: include/net/iucv/
+F: net/iucv/
S3C24XX SD/MMC Driver
P: Ben Dooks
@@ -3821,27 +4767,34 @@ M: ben-linux@fluff.org
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
L: linux-kernel@vger.kernel.org
S: Supported
+F: drivers/mmc/host/s3cmci.*
SAA7146 VIDEO4LINUX-2 DRIVER
P: Michael Hunold
M: michael@mihu.de
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
W: http://www.mihu.de/linux/saa7146
S: Maintained
+F: drivers/media/common/saa7146*
+F: drivers/media/video/*7146*
+F: include/media/*7146*
SC1200 WDT DRIVER
P: Zwane Mwaikambo
M: zwane@arm.linux.org.uk
S: Maintained
+F: drivers/watchdog/sc1200wdt.c
SCHEDULER
P: Ingo Molnar
M: mingo@elte.hu
-P: Robert Love [the preemptible kernel bits]
-M: rml@tech9.net
+P: Peter Zijlstra
+M: peterz@infradead.org
L: linux-kernel@vger.kernel.org
S: Maintained
+F: kernel/sched*
+F: include/linux/sched.h
SCSI CDROM DRIVER
P: Jens Axboe
@@ -3849,6 +4802,7 @@ M: axboe@kernel.dk
L: linux-scsi@vger.kernel.org
W: http://www.kernel.dk
S: Maintained
+F: drivers/scsi/sr*
SCSI SG DRIVER
P: Doug Gilbert
@@ -3856,21 +4810,27 @@ M: dgilbert@interlog.com
L: linux-scsi@vger.kernel.org
W: http://www.torque.net/sg
S: Maintained
+F: drivers/scsi/sg.c
+F: include/scsi/sg.h
SCSI SUBSYSTEM
P: James E.J. Bottomley
M: James.Bottomley@HansenPartnership.com
L: linux-scsi@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
-T: git kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6.git
-T: git kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-pending-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-pending-2.6.git
S: Maintained
+F: drivers/scsi/
+F: include/scsi/
SCSI TAPE DRIVER
P: Kai Mäkisara
M: Kai.Makisara@kolumbus.fi
L: linux-scsi@vger.kernel.org
S: Maintained
+F: Documentation/scsi/st.txt
+F: drivers/scsi/st*
SCTP PROTOCOL
P: Vlad Yasevich
@@ -3880,43 +4840,65 @@ M: sri@us.ibm.com
L: linux-sctp@vger.kernel.org
W: http://lksctp.sourceforge.net
S: Supported
+F: Documentation/networking/sctp.txt
+F: include/linux/sctp.h
+F: include/net/sctp/
+F: net/sctp/
SCx200 CPU SUPPORT
P: Jim Cromie
M: jim.cromie@gmail.com
S: Odd Fixes
+F: Documentation/i2c/busses/scx200_acb
+F: arch/x86/kernel/scx200_32.c
+F: drivers/watchdog/scx200_wdt.c
+F: drivers/i2c/busses/scx200*
+F: drivers/mtd/maps/scx200_docflash.c
+F: include/linux/scx200.h
SCx200 GPIO DRIVER
P: Jim Cromie
M: jim.cromie@gmail.com
S: Maintained
+F: drivers/char/scx200_gpio.c
+F: include/linux/scx200_gpio.h
SCx200 HRT CLOCKSOURCE DRIVER
P: Jim Cromie
M: jim.cromie@gmail.com
S: Maintained
+F: drivers/clocksource/scx200_hrt.c
SDRICOH_CS MMC/SD HOST CONTROLLER INTERFACE DRIVER
P: Sascha Sommer
M: saschasommer@freenet.de
L: sdricohcs-devel@lists.sourceforge.net (subscribers-only)
S: Maintained
+F: drivers/mmc/host/sdricoh_cs.c
SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER
P: Pierre Ossman
-M: drzeus-sdhci@drzeus.cx
-L: sdhci-devel@list.drzeus.cx
+M: pierre@ossman.eu
+L: sdhci-devel@lists.ossman.eu
+S: Maintained
+
+SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF)
+P: Anton Vorontsov
+M: avorontsov@ru.mvista.com
+L: linuxppc-dev@ozlabs.org
+L: sdhci-devel@lists.ossman.eu
S: Maintained
+F: drivers/mmc/host/sdhci.*
SECURITY SUBSYSTEM
-F: security/
P: James Morris
M: jmorris@namei.org
L: linux-kernel@vger.kernel.org
L: linux-security-module@vger.kernel.org (suggested Cc:)
-T: git kernel.org:pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
+T: git git://www.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
W: http://security.wiki.kernel.org/
S: Supported
+F: security/
SECURITY CONTACT
P: Security Officers
@@ -3931,31 +4913,39 @@ M: jmorris@namei.org
P: Eric Paris
M: eparis@parisplace.org
L: linux-kernel@vger.kernel.org (kernel issues)
-L: selinux@tycho.nsa.gov (subscribers-only, general discussion)
+L: selinux@tycho.nsa.gov (subscribers-only, general discussion)
W: http://selinuxproject.org
-T: git kernel.org:pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
S: Supported
+F: include/linux/selinux*
+F: security/selinux/
SENSABLE PHANTOM
P: Jiri Slaby
M: jirislaby@gmail.com
S: Maintained
+F: drivers/misc/phantom.c
+F: include/linux/phantom.h
SERIAL ATA (SATA) SUBSYSTEM
P: Jeff Garzik
M: jgarzik@pobox.com
L: linux-ide@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
S: Supported
+F: drivers/ata/
+F: include/linux/ata.h
+F: include/linux/libata.h
SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER
P: Sathya Perla
M: sathyap@serverengines.com
-P: Subbu Seetharaman
-M: subbus@serverengines.com
-L: netdev@vger.kernel.org
-W: http://www.serverengines.com
-S: Supported
+P: Subbu Seetharaman
+M: subbus@serverengines.com
+L: netdev@vger.kernel.org
+W: http://www.serverengines.com
+S: Supported
+F: drivers/net/benet/
SFC NETWORK DRIVER
P: Steve Hodgson
@@ -3963,17 +4953,22 @@ P: Ben Hutchings
P: Robert Stonehouse
M: linux-net-drivers@solarflare.com
S: Supported
+F: drivers/net/sfc/
SGI GRU DRIVER
P: Jack Steiner
M: steiner@sgi.com
S: Maintained
+F: drivers/misc/sgi-gru/
SGI SN-IA64 (Altix) SERIAL CONSOLE DRIVER
P: Pat Gefre
M: pfg@sgi.com
L: linux-ia64@vger.kernel.org
S: Supported
+F: Documentation/ia64/serial.txt
+F: drivers/serial/ioc?_serial.c
+F: include/linux/ioc?.h
SGI VISUAL WORKSTATION 320 AND 540
P: Andrey Panin
@@ -3981,11 +4976,13 @@ M: pazke@donpac.ru
L: linux-visws-devel@lists.sf.net
W: http://linux-visws.sf.net
S: Maintained for 2.6.
+F: Documentation/sgi-visws.txt
SGI XP/XPC/XPNET DRIVER
-P: Dean Nelson
-M: dcn@sgi.com
+P: Robin Holt
+M: holt@sgi.com
S: Maintained
+F: drivers/misc/sgi-xp/
SHARP LH SUPPORT (LH7952X & LH7A40X)
P: Marc Singer
@@ -3993,12 +4990,18 @@ M: elf@buici.com
W: http://projects.buici.com/arm
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
+F: Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen
+F: arch/arm/mach-lh7a40x/
+F: drivers/serial/serial_lh7a40x.c
+F: drivers/usb/gadget/lh7a40*
+F: drivers/usb/host/ohci-lh7a40*
SHPC HOTPLUG DRIVER
P: Kristen Carlson Accardi
M: kristen.c.accardi@intel.com
L: linux-pci@vger.kernel.org
S: Supported
+F: drivers/pci/hotplug/shpchp*
SIMTEC EB110ATX (Chalice CATS)
P: Ben Dooks
@@ -4006,6 +5009,7 @@ P: Vincent Sanders
M: support@simtec.co.uk
W: http://www.simtec.co.uk/products/EB110ATX/
S: Supported
+F: arch/arm/mach-ebsa110/
SIMTEC EB2410ITX (BAST)
P: Ben Dooks
@@ -4013,12 +5017,16 @@ P: Vincent Sanders
M: support@simtec.co.uk
W: http://www.simtec.co.uk/products/EB2410ITX/
S: Supported
+F: arch/arm/mach-s3c2410/
+F: drivers/*/*s3c2410*
+F: drivers/*/*/*s3c2410*
SIS 190 ETHERNET DRIVER
P: Francois Romieu
M: romieu@fr.zoreil.com
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/sis190.c
SIS 900/7016 FAST ETHERNET DRIVER
P: Daniele Venzano
@@ -4026,30 +5034,39 @@ M: venza@brownhat.org
W: http://www.brownhat.org/sis900.html
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/sis900.*
SIS 96X I2C/SMBUS DRIVER
P: Mark M. Hoffman
M: mhoffman@lightlink.com
L: linux-i2c@vger.kernel.org
S: Maintained
+F: Documentation/i2c/busses/i2c-sis96x
+F: drivers/i2c/busses/i2c-sis96x.c
SIS FRAMEBUFFER DRIVER
P: Thomas Winischhofer
M: thomas@winischhofer.net
W: http://www.winischhofer.net/linuxsisvga.shtml
S: Maintained
+F: Documentation/fb/sisfb.txt
+F: drivers/video/sis/
+F: include/video/sisfb.h
SIS USB2VGA DRIVER
P: Thomas Winischhofer
M: thomas@winischhofer.net
W: http://www.winischhofer.at/linuxsisusbvga.shtml
S: Maintained
+F: drivers/usb/misc/sisusbvga/
SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
P: Stephen Hemminger
M: shemminger@linux-foundation.org
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/skge.*
+F: drivers/net/sky2.*
SLAB ALLOCATOR
P: Christoph Lameter
@@ -4060,34 +5077,43 @@ P: Matt Mackall
M: mpm@selenic.com
L: linux-mm@kvack.org
S: Maintained
+F: include/linux/sl?b*.h
+F: mm/sl?b.c
SMC91x ETHERNET DRIVER
P: Nicolas Pitre
M: nico@cam.org
S: Maintained
+F: drivers/net/smc91x.*
SMSC47B397 HARDWARE MONITOR DRIVER
P: Mark M. Hoffman
M: mhoffman@lightlink.com
L: lm-sensors@lm-sensors.org
S: Maintained
+F: Documentation/hwmon/smsc47b397
+F: drivers/hwmon/smsc47b397.c
SMSC911x ETHERNET DRIVER
P: Steve Glendinning
M: steve.glendinning@smsc.com
L: netdev@vger.kernel.org
S: Supported
+F: include/linux/smsc911x.h
+F: drivers/net/smsc911x.*
SMSC9420 PCI ETHERNET DRIVER
P: Steve Glendinning
M: steve.glendinning@smsc.com
L: netdev@vger.kernel.org
S: Supported
+F: drivers/net/smsc9420.*
SMX UIO Interface
P: Ben Nizette
M: bn@niasdigital.com
S: Maintained
+F: drivers/uio/uio_smx.c
SN-IA64 (Itanium) SUB-PLATFORM
P: Jes Sorensen
@@ -4096,36 +5122,45 @@ L: linux-altix@sgi.com
L: linux-ia64@vger.kernel.org
W: http://www.sgi.com/altix
S: Maintained
+F: arch/ia64/sn/
SOC-CAMERA V4L2 SUBSYSTEM
P: Guennadi Liakhovetski
M: g.liakhovetski@gmx.de
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
+F: include/media/v4l2*
+F: drivers/media/video/v4l2*
SOEKRIS NET48XX LED SUPPORT
P: Chris Boot
M: bootc@bootc.net
S: Maintained
+F: drivers/leds/leds-net48xx.c
SOFTWARE RAID (Multiple Disks) SUPPORT
P: Neil Brown
M: neilb@suse.de
L: linux-raid@vger.kernel.org
S: Supported
+F: drivers/md/
+F: include/linux/raid/
SONIC NETWORK DRIVER
P: Thomas Bogendoerfer
M: tsbogend@alpha.franken.de
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/sonic.*
SONICS SILICON BACKPLANE DRIVER (SSB)
P: Michael Buesch
M: mb@bu3sch.de
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/ssb/
+F: include/linux/ssb/
SONY VAIO CONTROL DEVICE DRIVER
P: Mattia Dongili
@@ -4133,6 +5168,10 @@ M: malattia@linux.it
L: linux-acpi@vger.kernel.org
W: http://www.linux.it/~malattia/wiki/index.php/Sony_drivers
S: Maintained
+F: Documentation/laptops/sony-laptop.txt
+F: drivers/char/sonypi.c
+F: drivers/platform/x86/sony-laptop.c
+F: include/linux/sony-laptop.h
SONY MEMORYSTICK CARD SUPPORT
P: Alex Dubov
@@ -4140,6 +5179,7 @@ M: oakad@yahoo.com
L: linux-kernel@vger.kernel.org
W: http://tifmxx.berlios.de/
S: Maintained
+F: drivers/memstick/host/tifm_ms.c
SOUND
P: Jaroslav Kysela
@@ -4148,36 +5188,44 @@ P: Takashi Iwai
M: tiwai@suse.de
L: alsa-devel@alsa-project.org (subscribers-only)
S: Maintained
+F: sound/
SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC)
P: Liam Girdwood
M: lrg@slimlogic.co.uk
P: Mark Brown
M: broonie@opensource.wolfsonmicro.com
-T: git opensource.wolfsonmicro.com/linux-2.6-asoc
+T: git git://opensource.wolfsonmicro.com/linux-2.6-asoc
L: alsa-devel@alsa-project.org (subscribers-only)
W: http://alsa-project.org/main/index.php/ASoC
S: Supported
+F: sound/soc/
SPARC + UltraSPARC (sparc/sparc64)
P: David S. Miller
M: davem@davemloft.net
L: sparclinux@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6.git
-T: git kernel.org:/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
S: Maintained
+F: arch/sparc/
SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
P: Roger Wolff
M: R.E.Wolff@BitWizard.nl
-L: linux-kernel@vger.kernel.org ?
+L: linux-kernel@vger.kernel.org
S: Supported
+F: Documentation/serial/specialix.txt
+F: drivers/char/specialix*
SPI SUBSYSTEM
P: David Brownell
M: dbrownell@users.sourceforge.net
L: spi-devel-general@lists.sourceforge.net
S: Maintained
+F: Documentation/spi/
+F: drivers/spi/
+F: include/linux/spi/
SPIDERNET NETWORK DRIVER for CELL
P: Ishizaki Kou
@@ -4186,6 +5234,8 @@ P: Jens Osterkamp
M: jens@de.ibm.com
L: netdev@vger.kernel.org
S: Supported
+F: Documentation/networking/spider_net.txt
+F: drivers/net/spider_net*
SPU FILE SYSTEM
P: Jeremy Kerr
@@ -4194,6 +5244,8 @@ L: linuxppc-dev@ozlabs.org
L: cbe-oss-dev@ozlabs.org
W: http://www.ibm.com/developerworks/power/cell/
S: Supported
+F: Documentation/filesystems/spufs.txt
+F: arch/powerpc/platforms/cell/spufs/
SQUASHFS FILE SYSTEM
P: Phillip Lougher
@@ -4201,12 +5253,15 @@ M: phillip@lougher.demon.co.uk
L: squashfs-devel@lists.sourceforge.net (subscribers-only)
W: http://squashfs.org.uk
S: Maintained
+F: Documentation/filesystems/squashfs.txt
+F: fs/squashfs/
SRM (Alpha) environment access
P: Jan-Benedict Glaw
M: jbglaw@lug-owl.de
L: linux-kernel@vger.kernel.org
S: Maintained
+F: arch/alpha/kernel/srm_env.c
STABLE BRANCH
P: Greg Kroah-Hartman
@@ -4222,35 +5277,46 @@ M: gregkh@suse.de
L: linux-kernel@vger.kernel.org
T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
S: Maintained
+F: drivers/staging/
STARFIRE/DURALAN NETWORK DRIVER
P: Ion Badulescu
M: ionut@cs.columbia.edu
S: Maintained
+F: drivers/net/starfire*
STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
W: http://mosquitonet.Stanford.EDU/strip.html
S: Orphan
+F: drivers/net/wireless/strip.c
+F: include/linux/if_strip.h
STRADIS MPEG-2 DECODER DRIVER
P: Nathan Laredo
M: laredo@gnu.org
W: http://www.stradis.com/
S: Maintained
+F: drivers/media/video/stradis.c
SUN3/3X
P: Sam Creasey
M: sammy@sammy.net
W: http://sammy.net/sun3/
S: Maintained
+F: arch/m68k/kernel/*sun3*
+F: arch/m68k/sun3*/
+F: arch/m68k/include/asm/sun3*
SUPERH
P: Paul Mundt
M: lethal@linux-sh.org
L: linux-sh@vger.kernel.org
W: http://www.linux-sh.org
-T: git kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git
S: Supported
+F: Documentation/sh/
+F: arch/sh/
+F: drivers/sh/
SUSPEND TO RAM
P: Len Brown
@@ -4261,29 +5327,48 @@ P: Rafael J. Wysocki
M: rjw@sisk.pl
L: linux-pm@lists.linux-foundation.org
S: Supported
+F: Documentation/power/
+F: arch/x86/kernel/acpi/
+F: drivers/base/power/
+F: kernel/power/
+F: include/linux/suspend.h
+F: include/linux/freezer.h
+F: include/linux/pm.h
+F: include/asm-*/suspend.h
SVGA HANDLING
P: Martin Mares
M: mj@ucw.cz
L: linux-video@atrey.karlin.mff.cuni.cz
S: Maintained
+F: Documentation/svga.txt
+F: arch/x86/boot/video*
SYSV FILESYSTEM
P: Christoph Hellwig
M: hch@infradead.org
S: Maintained
+F: Documentation/filesystems/sysv-fs.txt
+F: fs/sysv/
+F: include/linux/sysv_fs.h
TASKSTATS STATISTICS INTERFACE
P: Balbir Singh
M: balbir@linux.vnet.ibm.com
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/accounting/taskstats*
+F: include/linux/taskstats*
+F: kernel/taskstats.c
TC CLASSIFIER
P: Jamal Hadi Salim
M: hadi@cyberus.ca
L: netdev@vger.kernel.org
S: Maintained
+F: include/linux/pkt_cls.h
+F: include/net/pkt_cls.h
+F: net/sched/
TCP LOW PRIORITY MODULE
P: Wong Hoi Sing, Edison
@@ -4292,6 +5377,7 @@ P: Hung Hing Lun, Mike
M: hlhung3i@gmail.com
W: http://tcp-lp-mod.sourceforge.net/
S: Maintained
+F: net/ipv4/tcp_lp.c
TEHUTI ETHERNET DRIVER
P: Alexander Indenbaum
@@ -4300,16 +5386,19 @@ P: Andy Gospodarek
M: andy@greyhouse.net
L: netdev@vger.kernel.org
S: Supported
+F: drivers/net/tehuti*
Telecom Clock Driver for MCPL0010
P: Mark Gross
M: mark.gross@intel.com
S: Supported
+F: drivers/char/tlclk.c
TENSILICA XTENSA PORT (xtensa)
P: Chris Zankel
M: chris@zankel.net
S: Maintained
+F: arch/xtensa/
THINKPAD ACPI EXTRAS DRIVER
P: Henrique de Moraes Holschuh
@@ -4317,13 +5406,17 @@ M: ibm-acpi@hmh.eng.br
L: ibm-acpi-devel@lists.sourceforge.net
W: http://ibm-acpi.sourceforge.net
W: http://thinkwiki.org/wiki/Ibm-acpi
-T: git repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
+T: git git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
S: Maintained
+F: drivers/platform/x86/thinkpad_acpi.c
TI FLASH MEDIA INTERFACE DRIVER
P: Alex Dubov
M: oakad@yahoo.com
S: Maintained
+F: drivers/misc/tifm*
+F: drivers/mmc/host/tifm_sd.c
+F: include/linux/tifm.h
TI OMAP MMC INTERFACE DRIVER
P: Carlos Aguiar, Anderson Briglia and Syed Khasim
@@ -4331,11 +5424,13 @@ M: linux-omap@vger.kernel.org
W: http://linux.omap.com
W: http://www.muru.com/linux/omap/
S: Maintained
+F: drivers/mmc/host/omap.c
TI OMAP RANDOM NUMBER GENERATOR SUPPORT
P: Deepak Saxena
M: dsaxena@plexity.net
S: Maintained
+F: drivers/char/hw_random/omap-rng.c
TIPC NETWORK LAYER
P: Per Liden
@@ -4347,8 +5442,11 @@ M: allan.stephens@windriver.com
L: tipc-discussion@lists.sourceforge.net
W: http://tipc.sourceforge.net/
W: http://tipc.cslab.ericsson.net/
-T: git tipc.cslab.ericsson.net:/pub/git/tipc.git
+T: git git://tipc.cslab.ericsson.net/pub/git/tipc.git
S: Maintained
+F: include/linux/tipc*.h
+F: include/net/tipc/
+F: net/tipc/
TLAN NETWORK DRIVER
P: Samuel Chessman
@@ -4356,6 +5454,8 @@ M: chessman@tux.org
L: tlan-devel@lists.sourceforge.net (subscribers-only)
W: http://sourceforge.net/projects/tlan/
S: Maintained
+F: Documentation/networking/tlan.txt
+F: drivers/net/tlan.*
TOMOYO SECURITY MODULE
P: Kentaro Takeda
@@ -4369,12 +5469,11 @@ L: tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese)
W: http://tomoyo.sourceforge.jp/
T: quilt http://svn.sourceforge.jp/svnroot/tomoyo/trunk/2.2.x/tomoyo-lsm/patches/
S: Maintained
+F: security/tomoyo/
TOSHIBA ACPI EXTRAS DRIVER
-P: John Belmonte
-M: toshiba_acpi@memebeam.org
-W: http://memebeam.org/toys/ToshibaAcpiDriver
-S: Maintained
+S: Orphan
+F: drivers/platform/x86/toshiba_acpi.c
TOSHIBA SMM DRIVER
P: Jonathan Buzzard
@@ -4382,6 +5481,14 @@ M: jonathan@buzzard.org.uk
L: tlinux-users@tce.toshiba-dme.co.jp
W: http://www.buzzard.org.uk/toshiba/
S: Maintained
+F: drivers/char/toshiba.c
+F: include/linux/toshiba.h
+
+TMIO MMC DRIVER
+P: Ian Molton
+M: ian@mnementh.co.uk
+S: Maintained
+F: drivers/mmc/host/tmio_mmc.*
TPM DEVICE DRIVER
P: Debora Velarde
@@ -4394,12 +5501,13 @@ M: m.selhorst@sirrix.com
W: http://www.sirrix.com
L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
+F: drivers/char/tpm/
TRIVIAL PATCHES
P: Jiri Kosina
M: trivial@kernel.org
L: linux-kernel@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/jikos/trivial.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git
S: Maintained
TTY LAYER
@@ -4415,6 +5523,7 @@ P: Kyle McMartin
M: kyle@mcmartin.ca
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/tulip/
TUN/TAP driver
P: Maxim Krasnyansky
@@ -4422,17 +5531,22 @@ M: maxk@qualcomm.com
L: vtun@office.satix.net
W: http://vtun.sourceforge.net/tun
S: Maintained
+F: Documentation/networking/tuntap.txt
+F: arch/um/os-Linux/drivers/
TURBOCHANNEL SUBSYSTEM
P: Maciej W. Rozycki
M: macro@linux-mips.org
S: Maintained
+F: drivers/tc/
+F: include/linux/tc.h
U14-34F SCSI DRIVER
P: Dario Ballabio
M: ballabio_dario@emc.com
L: linux-scsi@vger.kernel.org
S: Maintained
+F: drivers/scsi/u14-34f.c
UBI FILE SYSTEM (UBIFS)
P: Artem Bityutskiy
@@ -4443,6 +5557,8 @@ L: linux-mtd@lists.infradead.org
T: git git://git.infradead.org/ubifs-2.6.git
W: http://www.linux-mtd.infradead.org/doc/ubifs.html
S: Maintained
+F: Documentation/filesystems/ubifs.txt
+F: fs/ubifs/
UCLINUX (AND M68KNOMMU)
P: Greg Ungerer
@@ -4450,6 +5566,7 @@ M: gerg@uclinux.org
W: http://www.uclinux.org/
L: uclinux-dev@uclinux.org (subscribers-only)
S: Maintained
+F: arch/m68knommu/
UCLINUX FOR RENESAS H8/300
P: Yoshinori Sato
@@ -4462,18 +5579,25 @@ P: Jan Kara
M: jack@suse.cz
W: http://linux-udf.sourceforge.net
S: Maintained
+F: Documentation/filesystems/udf.txt
+F: fs/udf/
UFS FILESYSTEM
P: Evgeniy Dushistov
M: dushistov@mail.ru
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/filesystems/ufs.txt
+F: fs/ufs/
ULTRA-WIDEBAND (UWB) SUBSYSTEM:
P: David Vrabel
M: david.vrabel@csr.com
L: linux-usb@vger.kernel.org
S: Supported
+F: drivers/uwb/*
+F: include/linux/uwb.h
+F: include/linux/uwb/
UNIFORM CDROM DRIVER
P: Jens Axboe
@@ -4481,6 +5605,9 @@ M: axboe@kernel.dk
L: linux-kernel@vger.kernel.org
W: http://www.kernel.dk
S: Maintained
+F: Documentation/cdrom/
+F: drivers/cdrom/cdrom.c
+F: include/linux/cdrom.h
UNSORTED BLOCK IMAGES (UBI)
P: Artem Bityutskiy
@@ -4489,12 +5616,17 @@ W: http://www.linux-mtd.infradead.org/
L: linux-mtd@lists.infradead.org
T: git git://git.infradead.org/ubi-2.6.git
S: Maintained
+F: drivers/mtd/ubi/
+F: include/linux/mtd/ubi.h
+F: include/mtd/ubi-user.h
USB ACM DRIVER
P: Oliver Neukum
M: oliver@neukum.name
L: linux-usb@vger.kernel.org
S: Maintained
+F: Documentation/usb/acm.txt
+F: drivers/usb/class/cdc-acm.*
USB BLOCK DRIVER (UB ub)
P: Pete Zaitcev
@@ -4502,6 +5634,7 @@ M: zaitcev@redhat.com
L: linux-kernel@vger.kernel.org
L: linux-usb@vger.kernel.org
S: Supported
+F: drivers/block/ub.c
USB CDC ETHERNET DRIVER
P: Greg Kroah-Hartman
@@ -4509,12 +5642,15 @@ M: greg@kroah.com
L: linux-usb@vger.kernel.org
S: Maintained
W: http://www.kroah.com/linux-usb/
+F: drivers/net/usb/cdc_*.c
+F: include/linux/usb/cdc.h
USB CYPRESS C67X00 DRIVER
P: Peter Korsgaard
M: jacmet@sunsite.dk
L: linux-usb@vger.kernel.org
S: Maintained
+F: drivers/usb/c67x00/
USB DAVICOM DM9601 DRIVER
P: Peter Korsgaard
@@ -4522,6 +5658,7 @@ M: jacmet@sunsite.dk
L: netdev@vger.kernel.org
W: http://www.linux-usb.org/usbnet
S: Maintained
+F: drivers/net/usb/dm9601.c
USB DIAMOND RIO500 DRIVER
P: Cesar Miquel
@@ -4529,21 +5666,25 @@ M: miquel@df.uba.ar
L: rio500-users@lists.sourceforge.net
W: http://rio500.sourceforge.net
S: Maintained
+F: drivers/usb/misc/rio500*
USB EHCI DRIVER
P: David Brownell
M: dbrownell@users.sourceforge.net
L: linux-usb@vger.kernel.org
S: Odd Fixes
+F: Documentation/usb/ehci.txt
+F: drivers/usb/host/ehci*
USB ET61X[12]51 DRIVER
P: Luca Risolia
M: luca.risolia@studio.unibo.it
L: linux-usb@vger.kernel.org
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
W: http://www.linux-projects.org
S: Maintained
+F: drivers/media/video/et61x251/
USB GADGET/PERIPHERAL SUBSYSTEM
P: David Brownell
@@ -4551,25 +5692,32 @@ M: dbrownell@users.sourceforge.net
L: linux-usb@vger.kernel.org
W: http://www.linux-usb.org/gadget
S: Maintained
+F: drivers/usb/gadget/
+F: include/linux/usb/gadget*
USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...)
P: Jiri Kosina
M: jkosina@suse.cz
L: linux-usb@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/jikos/hid.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git
S: Maintained
+F: Documentation/usb/hiddev.txt
+F: drivers/hid/usbhid/
USB ISP116X DRIVER
P: Olav Kongas
M: ok@artecdesign.ee
L: linux-usb@vger.kernel.org
S: Maintained
+F: drivers/usb/host/isp116x*
+F: include/linux/usb/isp116x.h
USB KAWASAKI LSI DRIVER
P: Oliver Neukum
M: oliver@neukum.name
L: linux-usb@vger.kernel.org
S: Maintained
+F: drivers/usb/serial/kl5kusb105.*
USB MASS STORAGE DRIVER
P: Matthew Dharm
@@ -4578,18 +5726,22 @@ L: linux-usb@vger.kernel.org
L: usb-storage@lists.one-eyed-alien.net
S: Maintained
W: http://www.one-eyed-alien.net/~mdharm/linux-usb/
+F: drivers/usb/storage/
USB OHCI DRIVER
P: David Brownell
M: dbrownell@users.sourceforge.net
L: linux-usb@vger.kernel.org
S: Odd Fixes
+F: Documentation/usb/ohci.txt
+F: drivers/usb/host/ohci*
USB OPTION-CARD DRIVER
P: Matthias Urlichs
M: smurf@smurf.noris.de
L: linux-usb@vger.kernel.org
S: Maintained
+F: drivers/usb/serial/option.c
USB OV511 DRIVER
P: Mark McClelland
@@ -4597,6 +5749,7 @@ M: mmcclell@bigfoot.com
L: linux-usb@vger.kernel.org
W: http://alpha.dyndns.org/ov511/
S: Maintained
+F: drivers/media/video/ov511.*
USB PEGASUS DRIVER
P: Petko Manolov
@@ -4605,12 +5758,14 @@ L: linux-usb@vger.kernel.org
L: netdev@vger.kernel.org
W: http://pegasus2.sourceforge.net/
S: Maintained
+F: drivers/net/usb/pegasus.*
USB PRINTER DRIVER (usblp)
P: Pete Zaitcev
M: zaitcev@redhat.com
L: linux-usb@vger.kernel.org
S: Supported
+F: drivers/usb/class/usblp.c
USB RTL8150 DRIVER
P: Petko Manolov
@@ -4619,6 +5774,7 @@ L: linux-usb@vger.kernel.org
L: netdev@vger.kernel.org
W: http://pegasus2.sourceforge.net/
S: Maintained
+F: drivers/net/usb/rtl8150.c
USB SE401 DRIVER
P: Jeroen Vreeken
@@ -4626,12 +5782,15 @@ M: pe1rxq@amsat.org
L: linux-usb@vger.kernel.org
W: http://www.chello.nl/~j.vreeken/se401/
S: Maintained
+F: Documentation/video4linux/se401.txt
+F: drivers/media/video/se401.*
USB SERIAL BELKIN F5U103 DRIVER
P: William Greathouse
M: wgreathouse@smva.com
L: linux-usb@vger.kernel.org
S: Maintained
+F: drivers/usb/serial/belkin_sa.*
USB SERIAL CYPRESS M8 DRIVER
P: Lonnie Mendez
@@ -4640,12 +5799,14 @@ L: linux-usb@vger.kernel.org
S: Maintained
W: http://geocities.com/i0xox0i
W: http://firstlight.net/cvs
+F: drivers/usb/serial/cypress_m8.*
USB SERIAL CYBERJACK DRIVER
P: Matthias Bruestle and Harald Welte
M: support@reiner-sct.com
W: http://www.reiner-sct.de/support/treiber_cyberjack.php
S: Maintained
+F: drivers/usb/serial/cyberjack.c
USB SERIAL DIGI ACCELEPORT DRIVER
P: Peter Berger and Al Borchers
@@ -4653,18 +5814,24 @@ M: pberger@brimson.com
M: alborchers@steinerpoint.com
L: linux-usb@vger.kernel.org
S: Maintained
+F: drivers/usb/serial/digi_acceleport.c
USB SERIAL DRIVER
P: Greg Kroah-Hartman
M: gregkh@suse.de
L: linux-usb@vger.kernel.org
S: Supported
+F: Documentation/usb/usb-serial.txt
+F: drivers/usb/serial/generic.c
+F: drivers/usb/serial/usb-serial.c
+F: include/linux/usb/serial.h
USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER
P: Gary Brubaker
M: xavyer@ix.netcom.com
L: linux-usb@vger.kernel.org
S: Maintained
+F: drivers/usb/serial/empeg.c
USB SERIAL KEYSPAN DRIVER
P: Greg Kroah-Hartman
@@ -4672,6 +5839,7 @@ M: greg@kroah.com
L: linux-usb@vger.kernel.org
W: http://www.kroah.com/linux/
S: Maintained
+F: drivers/usb/serial/*keyspan*
USB SERIAL WHITEHEAT DRIVER
P: Support Department
@@ -4679,21 +5847,25 @@ M: support@connecttech.com
L: linux-usb@vger.kernel.org
W: http://www.connecttech.com
S: Supported
+F: drivers/usb/serial/whiteheat*
USB SMSC95XX ETHERNET DRIVER
P: Steve Glendinning
M: steve.glendinning@smsc.com
L: netdev@vger.kernel.org
S: Supported
+F: drivers/net/usb/smsc95xx.*
USB SN9C1xx DRIVER
P: Luca Risolia
M: luca.risolia@studio.unibo.it
L: linux-usb@vger.kernel.org
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
W: http://www.linux-projects.org
S: Maintained
+F: Documentation/video4linux/sn9c102.txt
+F: drivers/media/video/sn9c102/
USB SUBSYSTEM
P: Greg Kroah-Hartman
@@ -4702,12 +5874,18 @@ L: linux-usb@vger.kernel.org
W: http://www.linux-usb.org
T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
S: Supported
+F: Documentation/usb/
+F: drivers/net/usb/
+F: drivers/usb/
+F: include/linux/usb.h
+F: include/linux/usb/
USB UHCI DRIVER
P: Alan Stern
M: stern@rowland.harvard.edu
L: linux-usb@vger.kernel.org
S: Maintained
+F: drivers/usb/host/uhci*
USB "USBNET" DRIVER FRAMEWORK
P: David Brownell
@@ -4715,39 +5893,47 @@ M: dbrownell@users.sourceforge.net
L: netdev@vger.kernel.org
W: http://www.linux-usb.org/usbnet
S: Maintained
+F: drivers/net/usb/usbnet.c
+F: include/linux/usb/usbnet.h
USB VIDEO CLASS
P: Laurent Pinchart
M: laurent.pinchart@skynet.be
L: linux-uvc-devel@lists.berlios.de (subscribers-only)
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
W: http://linux-uvc.berlios.de
S: Maintained
+F: drivers/media/video/uvc/
USB W996[87]CF DRIVER
P: Luca Risolia
M: luca.risolia@studio.unibo.it
L: linux-usb@vger.kernel.org
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
W: http://www.linux-projects.org
S: Maintained
+F: Documentation/video4linux/w9968cf.txt
+F: drivers/media/video/w996*
USB WIRELESS RNDIS DRIVER (rndis_wlan)
P: Jussi Kivilinna
M: jussi.kivilinna@mbnet.fi
L: linux-wireless@vger.kernel.org
S: Maintained
+F: drivers/net/wireless/rndis_wlan.c
USB ZC0301 DRIVER
P: Luca Risolia
M: luca.risolia@studio.unibo.it
L: linux-usb@vger.kernel.org
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
W: http://www.linux-projects.org
S: Maintained
+F: Documentation/video4linux/zc0301.txt
+F: drivers/media/video/zc0301/
USB ZD1201 DRIVER
P: Jeroen Vreeken
@@ -4755,15 +5941,18 @@ M: pe1rxq@amsat.org
L: linux-usb@vger.kernel.org
W: http://linux-lc100020.sourceforge.net
S: Maintained
+F: drivers/net/wireless/zd1201.*
USB ZR364XX DRIVER
P: Antoine Jacquet
M: royale@zerezo.com
L: linux-usb@vger.kernel.org
L: linux-media@vger.kernel.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
W: http://royale.zerezo.com/zr364xx/
S: Maintained
+F: Documentation/video4linux/zr364xx.txt
+F: drivers/media/video/zr364xx.c
USER-MODE LINUX (UML)
P: Jeff Dike
@@ -4772,6 +5961,10 @@ L: user-mode-linux-devel@lists.sourceforge.net
L: user-mode-linux-user@lists.sourceforge.net
W: http://user-mode-linux.sourceforge.net
S: Maintained
+F: Documentation/uml/
+F: arch/um/
+F: fs/hostfs/
+F: fs/hppfs/
USERSPACE I/O (UIO)
P: Hans J. Koch
@@ -4780,13 +5973,16 @@ P: Greg Kroah-Hartman
M: gregkh@suse.de
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/DocBook/uio-howto.tmpl
+F: drivers/uio/
+F: include/linux/uio*.h
UTIL-LINUX-NG PACKAGE
P: Karel Zak
M: kzak@redhat.com
L: util-linux-ng@vger.kernel.org
W: http://kernel.org/~kzak/util-linux-ng/
-T: git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git
+T: git git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git
S: Maintained
UVESAFB DRIVER
@@ -4795,23 +5991,30 @@ 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
+F: Documentation/fb/uvesafb.txt
+F: drivers/video/uvesafb.*
VFAT/FAT/MSDOS FILESYSTEM
P: OGAWA Hirofumi
M: hirofumi@mail.parknet.co.jp
L: linux-kernel@vger.kernel.org
S: Maintained
+F: Documentation/filesystems/vfat.txt
+F: fs/fat/
VIA RHINE NETWORK DRIVER
P: Roger Luethi
M: rl@hellgate.ch
S: Maintained
+F: drivers/net/via-rhine.c
VIAPRO SMBUS DRIVER
P: Jean Delvare
M: khali@linux-fr.org
L: linux-i2c@vger.kernel.org
S: Maintained
+F: Documentation/i2c/busses/i2c-viapro
+F: drivers/i2c/busses/i2c-viapro.c
VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER
P: Joseph Chan
@@ -4820,26 +6023,23 @@ P: Scott Fang
M: ScottFang@viatech.com.cn
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
+F: drivers/video/via/
VIA VELOCITY NETWORK DRIVER
P: Francois Romieu
M: romieu@fr.zoreil.com
L: netdev@vger.kernel.org
S: Maintained
-
-VIDEO FOR LINUX (V4L)
-P: Mauro Carvalho Chehab
-M: mchehab@infradead.org
-L: linux-media@vger.kernel.org
-W: http://linuxtv.org
-T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
-S: Maintained
+F: drivers/net/via-velocity.*
VLAN (802.1Q)
P: Patrick McHardy
M: kaber@trash.net
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/macvlan.c
+F: include/linux/if_*vlan.h
+F: net/8021q/
VOLTAGE AND CURRENT REGULATOR FRAMEWORK
P: Liam Girdwood
@@ -4847,50 +6047,65 @@ M: lrg@slimlogic.co.uk
P: Mark Brown
M: broonie@opensource.wolfsonmicro.com
W: http://opensource.wolfsonmicro.com/node/15
-W: http://www.slimlogic.co.uk/?page_id=5
-T: git kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git
+W: http://www.slimlogic.co.uk/?p=48
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git
S: Supported
+F: drivers/regulator/
+F: include/linux/regulator/
VT1211 HARDWARE MONITOR DRIVER
P: Juerg Haefliger
M: juergh@gmail.com
L: lm-sensors@lm-sensors.org
S: Maintained
+F: Documentation/hwmon/vt1211
+F: drivers/hwmon/vt1211.c
VT8231 HARDWARE MONITOR DRIVER
P: Roger Lucas
M: vt8231@hiddenengine.co.uk
L: lm-sensors@lm-sensors.org
S: Maintained
+F: drivers/hwmon/vt8231.c
W1 DALLAS'S 1-WIRE BUS
P: Evgeniy Polyakov
M: johnpol@2ka.mipt.ru
S: Maintained
+F: Documentation/w1/
+F: drivers/w1/
W83791D HARDWARE MONITORING DRIVER
P: Marc Hulsman
M: m.hulsman@tudelft.nl
L: lm-sensors@lm-sensors.org
S: Maintained
+F: Documentation/hwmon/w83791d
+F: drivers/hwmon/w83791d.c
W83793 HARDWARE MONITORING DRIVER
P: Rudolf Marek
M: r.marek@assembler.cz
L: lm-sensors@lm-sensors.org
S: Maintained
+F: Documentation/hwmon/w83793
+F: drivers/hwmon/w83793.c
W83L51xD SD/MMC CARD INTERFACE DRIVER
P: Pierre Ossman
-M: drzeus-wbsd@drzeus.cx
+M: pierre@ossman.eu
L: linux-kernel@vger.kernel.org
S: Maintained
+F: drivers/mmc/host/wbsd.*
WATCHDOG DEVICE DRIVERS
P: Wim Van Sebroeck
M: wim@iguana.be
-T: git kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog.git
S: Maintained
+F: Documentation/watchdog/
+F: drivers/watchdog/
+F: include/linux/watchdog.h
WAVELAN NETWORK DRIVER & WIRELESS EXTENSIONS
P: Jean Tourrilhes
@@ -4898,12 +6113,15 @@ M: jt@hpl.hp.com
L: linux-wireless@vger.kernel.org
W: http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
S: Maintained
+F: Documentation/networking/wavelan.txt
+F: drivers/net/wireless/wavelan*
WD7000 SCSI DRIVER
P: Miroslav Zagorac
M: zaga@fly.cc.fer.hr
L: linux-scsi@vger.kernel.org
S: Maintained
+F: drivers/scsi/wd7000.c
WIMAX STACK
P: Inaky Perez-Gonzalez
@@ -4917,11 +6135,14 @@ WIMEDIA LLC PROTOCOL (WLP) SUBSYSTEM
P: David Vrabel
M: david.vrabel@csr.com
S: Maintained
+F: include/linux/wlp.h
+F: drivers/uwb/wlp/
WISTRON LAPTOP BUTTON DRIVER
P: Miloslav Trmac
M: mitr@volny.cz
S: Maintained
+F: drivers/input/misc/wistron_btns.c
WL3501 WIRELESS PCMCIA CARD DRIVER
P: Arnaldo Carvalho de Melo
@@ -4929,6 +6150,7 @@ M: acme@ghostprotocols.net
L: linux-wireless@vger.kernel.org
W: http://oops.ghostprotocols.net:81/blog
S: Maintained
+F: drivers/net/wireless/wl3501*
WM97XX TOUCHSCREEN DRIVERS
P: Mark Brown
@@ -4939,12 +6161,17 @@ L: linux-input@vger.kernel.org
T: git git://opensource.wolfsonmicro.com/linux-2.6-touch
W: http://opensource.wolfsonmicro.com/node/7
S: Supported
+F: drivers/input/touchscreen/*wm97*
+F: include/linux/wm97xx.h
X.25 NETWORK LAYER
P: Henner Eisen
M: eis@baty.hanse.de
L: linux-x25@vger.kernel.org
S: Maintained
+F: Documentation/networking/x25*
+F: include/net/x25*
+F: net/x25/
X86 ARCHITECTURE (32-BIT AND 64-BIT)
P: Thomas Gleixner
@@ -4955,8 +6182,10 @@ P: H. Peter Anvin
M: hpa@zytor.com
M: x86@kernel.org
L: linux-kernel@vger.kernel.org
-T: git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
S: Maintained
+F: Documentation/x86/
+F: arch/x86/
XEN HYPERVISOR INTERFACE
P: Jeremy Fitzhardinge
@@ -4966,15 +6195,23 @@ M: chrisw@sous-sol.org
L: virtualization@lists.osdl.org
L: xen-devel@lists.xensource.com
S: Supported
+F: arch/x86/xen/
+F: drivers/*/xen-*front.c
+F: drivers/xen/
+F: arch/x86/include/asm/xen/
+F: include/xen/
XFS FILESYSTEM
P: Silicon Graphics Inc
-P: Bill O'Donnell
+P: Felix Blyakher
+M: felixb@sgi.com
M: xfs-masters@oss.sgi.com
L: xfs@oss.sgi.com
W: http://oss.sgi.com/projects/xfs
-T: git://oss.sgi.com/xfs/xfs.git
+T: git git://oss.sgi.com/xfs/xfs.git
S: Supported
+F: Documentation/filesystems/xfs.txt
+F: fs/xfs/
XILINX SYSTEMACE DRIVER
P: Grant Likely
@@ -4982,24 +6219,30 @@ M: grant.likely@secretlab.ca
W: http://www.secretlab.ca/
L: linux-kernel@vger.kernel.org
S: Maintained
+F: drivers/block/xsysace.c
XILINX UARTLITE SERIAL DRIVER
P: Peter Korsgaard
M: jacmet@sunsite.dk
L: linux-serial@vger.kernel.org
S: Maintained
+F: drivers/serial/uartlite.c
YAM DRIVER FOR AX.25
P: Jean-Paul Roubelat
M: jpr@f6fbb.org
L: linux-hams@vger.kernel.org
S: Maintained
+F: drivers/net/hamradio/yam*
+F: include/linux/yam.h
YEALINK PHONE DRIVER
P: Henk Vergonet
M: Henk.Vergonet@gmail.com
L: usbb2k-api-dev@nongnu.org
S: Maintained
+F: Documentation/input/yealink.txt
+F: drivers/input/misc/yealink.*
Z8530 DRIVER FOR AX.25
P: Joerg Reuter
@@ -5008,6 +6251,9 @@ W: http://yaina.de/jreuter/
W: http://www.qsl.net/dl1bke/
L: linux-hams@vger.kernel.org
S: Maintained
+F: Documentation/networking/z8530drv.txt
+F: drivers/net/hamradio/*scc.c
+F: drivers/net/hamradio/z8530.h
ZD1211RW WIRELESS DRIVER
P: Daniel Drake
@@ -5018,6 +6264,7 @@ W: http://zd1211.ath.cx/wiki/DriverRewrite
L: linux-wireless@vger.kernel.org
L: zd1211-devs@lists.sourceforge.net (subscribers-only)
S: Maintained
+F: drivers/net/wireless/zd1211rw/
ZR36067 VIDEO FOR LINUX DRIVER
L: mjpeg-users@lists.sourceforge.net
@@ -5025,12 +6272,15 @@ L: linux-media@vger.kernel.org
W: http://mjpeg.sourceforge.net/driver-zoran/
T: Mercurial http://linuxtv.org/hg/v4l-dvb
S: Odd Fixes
+F: drivers/media/video/zoran/
ZS DECSTATION Z85C30 SERIAL DRIVER
P: Maciej W. Rozycki
M: macro@linux-mips.org
S: Maintained
+F: drivers/serial/zs.*
THE REST
P: Linus Torvalds
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
S: Buried alive in reporters
diff --git a/Makefile b/Makefile
index c6307b6d069..4f7e3ccde05 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
-SUBLEVEL = 29
-EXTRAVERSION =
+SUBLEVEL = 30
+EXTRAVERSION = -rc1
NAME = Temporary Tasmanian Devil
# *DOCUMENTATION*
@@ -169,7 +169,7 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
- -e s/sh.*/sh/ )
+ -e s/sh[234].*/sh/ )
# Cross compiling and selecting different set of gcc/bin-utils
# ---------------------------------------------------------------------------
@@ -210,6 +210,11 @@ ifeq ($(ARCH),sparc64)
SRCARCH := sparc
endif
+# Additional ARCH settings for sh
+ifeq ($(ARCH),sh64)
+ SRCARCH := sh
+endif
+
# Where to locate arch specific headers
hdr-arch := $(SRCARCH)
@@ -567,7 +572,7 @@ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
# disable pointer signed / unsigned warnings in gcc 4.0
KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
-# disable invalid "can't wrap" optimzations for signed / pointers
+# disable invalid "can't wrap" optimizations for signed / pointers
KBUILD_CFLAGS += $(call cc-option,-fwrapv)
# revert to pre-gcc-4.4 behaviour of .eh_frame
@@ -597,6 +602,10 @@ LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID)
LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID)
+ifeq ($(CONFIG_STRIP_ASM_SYMS),y)
+LDFLAGS_vmlinux += -X
+endif
+
# Default kernel image to build when no specific target is given.
# KBUILD_IMAGE may be overruled on the command line or
# set in the environment
@@ -1587,5 +1596,5 @@ PHONY += FORCE
FORCE:
# Declare the contents of the .PHONY variable as phony. We keep that
-# information in a variable se we can use it in if_changed and friends.
+# information in a variable so we can use it in if_changed and friends.
.PHONY: $(PHONY)
diff --git a/arch/Kconfig b/arch/Kconfig
index 830c16a2b80..78a35e9dc10 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -6,6 +6,7 @@ config OPROFILE
tristate "OProfile system profiling (EXPERIMENTAL)"
depends on PROFILING
depends on HAVE_OPROFILE
+ depends on TRACING_SUPPORT
select TRACING
select RING_BUFFER
help
@@ -108,3 +109,6 @@ config HAVE_CLK
config HAVE_DMA_API_DEBUG
bool
+
+config HAVE_DEFAULT_NO_SPIN_MUTEXES
+ bool
diff --git a/arch/alpha/include/asm/ftrace.h b/arch/alpha/include/asm/ftrace.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/alpha/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/alpha/include/asm/hardirq.h b/arch/alpha/include/asm/hardirq.h
index d953e234daa..88971460fa6 100644
--- a/arch/alpha/include/asm/hardirq.h
+++ b/arch/alpha/include/asm/hardirq.h
@@ -14,17 +14,4 @@ typedef struct {
void ack_bad_irq(unsigned int irq);
-#define HARDIRQ_BITS 12
-
-/*
- * The hardirq mask has to be large enough to have
- * space for potentially nestable IRQ sources in the system
- * to nest on a single CPU. On Alpha, interrupts are masked at the CPU
- * by IPL as well as at the system level. We only have 8 IPLs (UNIX PALcode)
- * so we really only have 8 nestable IRQs, but allow some overhead
- */
-#if (1 << HARDIRQ_BITS) < 16
-#error HARDIRQ_BITS is too low!
-#endif
-
#endif /* _ALPHA_HARDIRQ_H */
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 393c8164131..9e6e512f011 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -18,7 +18,10 @@
unsigned int __machine_arch_type;
-#include <linux/string.h>
+#include <linux/compiler.h> /* for inline */
+#include <linux/types.h> /* for size_t */
+#include <linux/stddef.h> /* for NULL */
+#include <asm/string.h>
#ifdef STANDALONE_DEBUG
#define putstr printf
diff --git a/arch/arm/configs/magician_defconfig b/arch/arm/configs/magician_defconfig
index 82428c2f234..f56837f69ca 100644
--- a/arch/arm/configs/magician_defconfig
+++ b/arch/arm/configs/magician_defconfig
@@ -1183,7 +1183,11 @@ CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_DRV_SA1100=y
# CONFIG_RTC_DRV_PXA is not set
# CONFIG_DMADEVICES is not set
-# CONFIG_REGULATOR is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+CONFIG_REGULATOR_BQ24022=y
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
diff --git a/arch/arm/configs/omap_ldp_defconfig b/arch/arm/configs/omap_ldp_defconfig
index aa9d34feddc..679a4a3e265 100644
--- a/arch/arm/configs/omap_ldp_defconfig
+++ b/arch/arm/configs/omap_ldp_defconfig
@@ -474,14 +474,34 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
# CONFIG_ENC28J60 is not set
-CONFIG_SMC911X=y
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=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
diff --git a/arch/arm/configs/pcm037_defconfig b/arch/arm/configs/pcm037_defconfig
index 62747458647..6e37c77c476 100644
--- a/arch/arm/configs/pcm037_defconfig
+++ b/arch/arm/configs/pcm037_defconfig
@@ -465,12 +465,33 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_AX88796 is not set
CONFIG_SMC91X=y
# CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=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
diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig
index cd29824d791..21db4b3ec8f 100644
--- a/arch/arm/configs/realview-smp_defconfig
+++ b/arch/arm/configs/realview-smp_defconfig
@@ -496,13 +496,33 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_AX88796 is not set
CONFIG_SMC91X=y
# CONFIG_DM9000 is not set
-CONFIG_SMC911X=y
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=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
diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig
index 7e253f58ed1..9a75c30b910 100644
--- a/arch/arm/configs/realview_defconfig
+++ b/arch/arm/configs/realview_defconfig
@@ -490,13 +490,33 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_AX88796 is not set
CONFIG_SMC91X=y
# CONFIG_DM9000 is not set
-CONFIG_SMC911X=y
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=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
diff --git a/arch/arm/include/asm/sizes.h b/arch/arm/include/asm/sizes.h
index c10d1aa4b48..ada93a8fc2e 100644
--- a/arch/arm/include/asm/sizes.h
+++ b/arch/arm/include/asm/sizes.h
@@ -32,6 +32,7 @@
#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
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index 793fe7b25f3..e6afff849b8 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -87,7 +87,7 @@ extern void __init at91_add_device_eth(struct at91_eth_data *data);
/* USB Host */
struct at91_usbh_data {
u8 ports; /* number of ports on root hub */
- u8 vbus_pin[]; /* port power-control pin */
+ u8 vbus_pin[2]; /* port power-control pin */
};
extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 7ac812dc055..e26c4fe61fa 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -198,17 +198,17 @@ static int at91_pm_verify_clocks(void)
/* USB must not be using PLLB */
if (cpu_is_at91rm9200()) {
if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) {
- pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+ pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
return 0;
}
} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
- pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+ pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
return 0;
}
} else if (cpu_is_at91cap9()) {
if ((scsr & AT91CAP9_PMC_UHP) != 0) {
- pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+ pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
return 0;
}
}
@@ -223,7 +223,7 @@ static int at91_pm_verify_clocks(void)
css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
if (css != AT91_PMC_CSS_SLOW) {
- pr_debug("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
+ pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
return 0;
}
}
diff --git a/arch/arm/mach-davinci/board-evm.c b/arch/arm/mach-davinci/board-evm.c
index 38b6a9ce2a9..0b97a528902 100644
--- a/arch/arm/mach-davinci/board-evm.c
+++ b/arch/arm/mach-davinci/board-evm.c
@@ -118,7 +118,7 @@ static struct resource ide_resources[] = {
},
};
-static u64 ide_dma_mask = DMA_32BIT_MASK;
+static u64 ide_dma_mask = DMA_BIT_MASK(32);
static struct platform_device ide_dev = {
.name = "palm_bk3710",
@@ -127,7 +127,7 @@ static struct platform_device ide_dev = {
.num_resources = ARRAY_SIZE(ide_resources),
.dev = {
.dma_mask = &ide_dma_mask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
};
diff --git a/arch/arm/mach-davinci/include/mach/nand.h b/arch/arm/mach-davinci/include/mach/nand.h
new file mode 100644
index 00000000000..aa482841270
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/nand.h
@@ -0,0 +1,80 @@
+/*
+ * mach-davinci/nand.h
+ *
+ * Copyright © 2006 Texas Instruments.
+ *
+ * Ported to 2.6.23 Copyright © 2008 by
+ * Sander Huijsen <Shuijsen@optelecom-nkf.com>
+ * Troy Kisky <troy.kisky@boundarydevices.com>
+ * Dirk Behme <Dirk.Behme@gmail.com>
+ *
+ * --------------------------------------------------------------------------
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ARCH_ARM_DAVINCI_NAND_H
+#define __ARCH_ARM_DAVINCI_NAND_H
+
+#include <linux/mtd/nand.h>
+
+#define NRCSR_OFFSET 0x00
+#define AWCCR_OFFSET 0x04
+#define A1CR_OFFSET 0x10
+#define NANDFCR_OFFSET 0x60
+#define NANDFSR_OFFSET 0x64
+#define NANDF1ECC_OFFSET 0x70
+
+/* 4-bit ECC syndrome registers */
+#define NAND_4BIT_ECC_LOAD_OFFSET 0xbc
+#define NAND_4BIT_ECC1_OFFSET 0xc0
+#define NAND_4BIT_ECC2_OFFSET 0xc4
+#define NAND_4BIT_ECC3_OFFSET 0xc8
+#define NAND_4BIT_ECC4_OFFSET 0xcc
+#define NAND_ERR_ADD1_OFFSET 0xd0
+#define NAND_ERR_ADD2_OFFSET 0xd4
+#define NAND_ERR_ERRVAL1_OFFSET 0xd8
+#define NAND_ERR_ERRVAL2_OFFSET 0xdc
+
+/* NOTE: boards don't need to use these address bits
+ * for ALE/CLE unless they support booting from NAND.
+ * They're used unless platform data overrides them.
+ */
+#define MASK_ALE 0x08
+#define MASK_CLE 0x10
+
+struct davinci_nand_pdata { /* platform_data */
+ uint32_t mask_ale;
+ uint32_t mask_cle;
+
+ /* for packages using two chipselects */
+ uint32_t mask_chipsel;
+
+ /* board's default static partition info */
+ struct mtd_partition *parts;
+ unsigned nr_parts;
+
+ /* none == NAND_ECC_NONE (strongly *not* advised!!)
+ * soft == NAND_ECC_SOFT
+ * 1-bit == NAND_ECC_HW
+ * 4-bit == NAND_ECC_HW_SYNDROME (not on all chips)
+ */
+ nand_ecc_modes_t ecc_mode;
+
+ /* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */
+ unsigned options;
+};
+
+#endif /* __ARCH_ARM_DAVINCI_NAND_H */
diff --git a/arch/arm/mach-davinci/usb.c b/arch/arm/mach-davinci/usb.c
index 69680784448..2429b79f6da 100644
--- a/arch/arm/mach-davinci/usb.c
+++ b/arch/arm/mach-davinci/usb.c
@@ -64,7 +64,7 @@ static struct resource usb_resources[] = {
},
};
-static u64 usb_dmamask = DMA_32BIT_MASK;
+static u64 usb_dmamask = DMA_BIT_MASK(32);
static struct platform_device usb_dev = {
.name = "musb_hdrc",
@@ -72,7 +72,7 @@ static struct platform_device usb_dev = {
.dev = {
.platform_data = &usb_data,
.dma_mask = &usb_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.resource = usb_resources,
.num_resources = ARRAY_SIZE(usb_resources),
diff --git a/arch/arm/mach-gemini/include/mach/system.h b/arch/arm/mach-gemini/include/mach/system.h
index bbbd72767a0..4d9c1f87247 100644
--- a/arch/arm/mach-gemini/include/mach/system.h
+++ b/arch/arm/mach-gemini/include/mach/system.h
@@ -28,7 +28,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
__raw_writel(RESET_GLOBAL | RESET_CPU1,
IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_RESET);
diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c
index cfd4d2e6dac..bee42c609df 100644
--- a/arch/arm/mach-iop13xx/setup.c
+++ b/arch/arm/mach-iop13xx/setup.c
@@ -307,7 +307,7 @@ static struct resource iop13xx_adma_2_resources[] = {
}
};
-static u64 iop13xx_adma_dmamask = DMA_64BIT_MASK;
+static u64 iop13xx_adma_dmamask = DMA_BIT_MASK(64);
static struct iop_adma_platform_data iop13xx_adma_0_data = {
.hw_id = 0,
.pool_size = PAGE_SIZE,
@@ -331,7 +331,7 @@ static struct platform_device iop13xx_adma_0_channel = {
.resource = iop13xx_adma_0_resources,
.dev = {
.dma_mask = &iop13xx_adma_dmamask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *) &iop13xx_adma_0_data,
},
};
@@ -343,7 +343,7 @@ static struct platform_device iop13xx_adma_1_channel = {
.resource = iop13xx_adma_1_resources,
.dev = {
.dma_mask = &iop13xx_adma_dmamask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *) &iop13xx_adma_1_data,
},
};
@@ -355,7 +355,7 @@ static struct platform_device iop13xx_adma_2_channel = {
.resource = iop13xx_adma_2_resources,
.dev = {
.dma_mask = &iop13xx_adma_dmamask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *) &iop13xx_adma_2_data,
},
};
diff --git a/arch/arm/mach-iop13xx/tpmi.c b/arch/arm/mach-iop13xx/tpmi.c
index c6af1e1bee3..6fdad7a0425 100644
--- a/arch/arm/mach-iop13xx/tpmi.c
+++ b/arch/arm/mach-iop13xx/tpmi.c
@@ -151,7 +151,7 @@ static struct resource iop13xx_tpmi_3_resources[] = {
}
};
-u64 iop13xx_tpmi_mask = DMA_64BIT_MASK;
+u64 iop13xx_tpmi_mask = DMA_BIT_MASK(64);
static struct platform_device iop13xx_tpmi_0_device = {
.name = "iop-tpmi",
.id = 0,
@@ -159,7 +159,7 @@ static struct platform_device iop13xx_tpmi_0_device = {
.resource = iop13xx_tpmi_0_resources,
.dev = {
.dma_mask = &iop13xx_tpmi_mask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
},
};
@@ -170,7 +170,7 @@ static struct platform_device iop13xx_tpmi_1_device = {
.resource = iop13xx_tpmi_1_resources,
.dev = {
.dma_mask = &iop13xx_tpmi_mask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
},
};
@@ -181,7 +181,7 @@ static struct platform_device iop13xx_tpmi_2_device = {
.resource = iop13xx_tpmi_2_resources,
.dev = {
.dma_mask = &iop13xx_tpmi_mask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
},
};
@@ -192,7 +192,7 @@ static struct platform_device iop13xx_tpmi_3_device = {
.resource = iop13xx_tpmi_3_resources,
.dev = {
.dma_mask = &iop13xx_tpmi_mask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
},
};
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 3d2fae84651..16dc9ea0839 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -508,7 +508,7 @@ static struct mv_xor_platform_shared_data kirkwood_xor_shared_data = {
.dram = &kirkwood_mbus_dram_info,
};
-static u64 kirkwood_xor_dmamask = DMA_32BIT_MASK;
+static u64 kirkwood_xor_dmamask = DMA_BIT_MASK(32);
/*****************************************************************************
@@ -559,7 +559,7 @@ static struct platform_device kirkwood_xor00_channel = {
.resource = kirkwood_xor00_resources,
.dev = {
.dma_mask = &kirkwood_xor_dmamask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *)&kirkwood_xor00_data,
},
};
@@ -585,7 +585,7 @@ static struct platform_device kirkwood_xor01_channel = {
.resource = kirkwood_xor01_resources,
.dev = {
.dma_mask = &kirkwood_xor_dmamask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *)&kirkwood_xor01_data,
},
};
@@ -657,7 +657,7 @@ static struct platform_device kirkwood_xor10_channel = {
.resource = kirkwood_xor10_resources,
.dev = {
.dma_mask = &kirkwood_xor_dmamask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *)&kirkwood_xor10_data,
},
};
@@ -683,7 +683,7 @@ static struct platform_device kirkwood_xor11_channel = {
.resource = kirkwood_xor11_resources,
.dev = {
.dma_mask = &kirkwood_xor_dmamask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *)&kirkwood_xor11_data,
},
};
diff --git a/arch/arm/mach-mmp/include/mach/system.h b/arch/arm/mach-mmp/include/mach/system.h
index 001edfefec1..4f5b0e0ce6c 100644
--- a/arch/arm/mach-mmp/include/mach/system.h
+++ b/arch/arm/mach-mmp/include/mach/system.h
@@ -14,7 +14,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
cpu_reset(0);
}
diff --git a/arch/arm/mach-mx1/Makefile b/arch/arm/mach-mx1/Makefile
index 82f1309568e..7f86fe073ec 100644
--- a/arch/arm/mach-mx1/Makefile
+++ b/arch/arm/mach-mx1/Makefile
@@ -6,6 +6,9 @@
obj-y += generic.o clock.o devices.o
+# Support for CMOS sensor interface
+obj-$(CONFIG_MX1_VIDEO) += ksym_mx1.o mx1_camera_fiq.o
+
# Specific board support
obj-$(CONFIG_ARCH_MX1ADS) += mx1ads.o
obj-$(CONFIG_MACH_SCB9328) += scb9328.o \ No newline at end of file
diff --git a/arch/arm/mach-mx1/devices.c b/arch/arm/mach-mx1/devices.c
index 97f42d96d7a..76d1ffb4807 100644
--- a/arch/arm/mach-mx1/devices.c
+++ b/arch/arm/mach-mx1/devices.c
@@ -44,7 +44,7 @@ static struct resource imx_csi_resources[] = {
static u64 imx_csi_dmamask = 0xffffffffUL;
struct platform_device imx_csi_device = {
- .name = "imx-csi",
+ .name = "mx1-camera",
.id = 0, /* This is used to put cameras on this interface */
.dev = {
.dma_mask = &imx_csi_dmamask,
diff --git a/arch/arm/mach-mx1/ksym_mx1.c b/arch/arm/mach-mx1/ksym_mx1.c
new file mode 100644
index 00000000000..b09ee12a4ff
--- /dev/null
+++ b/arch/arm/mach-mx1/ksym_mx1.c
@@ -0,0 +1,18 @@
+/*
+ * Exported ksyms of ARCH_MX1
+ *
+ * Copyright (C) 2008, Darius Augulis <augulis.darius@gmail.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/platform_device.h>
+#include <linux/module.h>
+
+#include <mach/mx1_camera.h>
+
+/* IMX camera FIQ handler */
+EXPORT_SYMBOL(mx1_camera_sof_fiq_start);
+EXPORT_SYMBOL(mx1_camera_sof_fiq_end);
diff --git a/arch/arm/mach-mx1/mx1_camera_fiq.S b/arch/arm/mach-mx1/mx1_camera_fiq.S
new file mode 100644
index 00000000000..9c69aa65bf1
--- /dev/null
+++ b/arch/arm/mach-mx1/mx1_camera_fiq.S
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on linux/arch/arm/lib/floppydma.S
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+ .global mx1_camera_sof_fiq_end
+ .global mx1_camera_sof_fiq_start
+mx1_camera_sof_fiq_start:
+ @ enable dma
+ ldr r12, [r9]
+ orr r12, r12, #0x00000001
+ str r12, [r9]
+ @ unmask DMA interrupt
+ ldr r12, [r8]
+ bic r12, r12, r13
+ str r12, [r8]
+ @ disable SOF interrupt
+ ldr r12, [r10]
+ bic r12, r12, #0x00010000
+ str r12, [r10]
+ @ clear SOF flag
+ mov r12, #0x00010000
+ str r12, [r11]
+ @ return from FIQ
+ subs pc, lr, #4
+mx1_camera_sof_fiq_end:
diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c
index ca46f4801c3..9957a11533a 100644
--- a/arch/arm/mach-mx3/clock.c
+++ b/arch/arm/mach-mx3/clock.c
@@ -533,7 +533,7 @@ static struct clk_lookup lookups[] __initdata = {
_REGISTER_CLOCK(NULL, "kpp", kpp_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1)
_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2)
- _REGISTER_CLOCK("mx3-camera.0", "csi", csi_clk)
+ _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk)
_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c
index 5fce022114d..c3648eff513 100644
--- a/arch/arm/mach-mx3/pcm037.c
+++ b/arch/arm/mach-mx3/pcm037.c
@@ -24,7 +24,7 @@
#include <linux/mtd/plat-ram.h>
#include <linux/memory.h>
#include <linux/gpio.h>
-#include <linux/smc911x.h>
+#include <linux/smsc911x.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
@@ -70,7 +70,7 @@ static struct imxuart_platform_data uart_pdata = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct resource smc911x_resources[] = {
+static struct resource smsc911x_resources[] = {
[0] = {
.start = CS1_BASE_ADDR + 0x300,
.end = CS1_BASE_ADDR + 0x300 + SZ_64K - 1,
@@ -79,22 +79,25 @@ static struct resource smc911x_resources[] = {
[1] = {
.start = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
.end = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
- .flags = IORESOURCE_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
},
};
-static struct smc911x_platdata smc911x_info = {
- .flags = SMC911X_USE_32BIT,
- .irq_flags = IRQF_SHARED | IRQF_TRIGGER_LOW,
+static struct smsc911x_platform_config smsc911x_info = {
+ .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY |
+ SMSC911X_SAVE_MAC_ADDRESS,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
};
static struct platform_device pcm037_eth = {
- .name = "smc911x",
+ .name = "smsc911x",
.id = -1,
- .num_resources = ARRAY_SIZE(smc911x_resources),
- .resource = smc911x_resources,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
.dev = {
- .platform_data = &smc911x_info,
+ .platform_data = &smsc911x_info,
},
};
diff --git a/arch/arm/mach-netx/include/mach/netx-regs.h b/arch/arm/mach-netx/include/mach/netx-regs.h
index 08c60ff227b..5a03e7ccb01 100644
--- a/arch/arm/mach-netx/include/mach/netx-regs.h
+++ b/arch/arm/mach-netx/include/mach/netx-regs.h
@@ -80,7 +80,7 @@
#define NETX_PA_XPEC(no) (NETX_IO_PHYS + NETX_OFS_XPEC(no))
#define NETX_PA_VIC (NETX_IO_PHYS + NETX_OFS_VIC)
-/* virual addresses */
+/* virtual addresses */
#define NETX_VA_SYSTEM (NETX_IO_VIRT + NETX_OFS_SYSTEM)
#define NETX_VA_MEMCR (NETX_IO_VIRT + NETX_OFS_MEMCR)
#define NETX_VA_DPMAS (NETX_IO_VIRT + NETX_OFS_DPMAS)
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 3f325d3718a..cd8de89c5fa 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -109,7 +109,7 @@ config MACH_OMAP_PALMZ71
help
Support for the Palm Zire71 PDA. To boot the kernel,
you'll need a PalmOS compatible bootloader; check out
- http://hackndev.com/palm/z71 for more informations.
+ http://hackndev.com/palm/z71 for more information.
Say Y here if you have such a PDA, say N otherwise.
config MACH_OMAP_PALMTT
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index dafe4f71d15..336e51dc612 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -590,27 +590,28 @@ static void omap1_init_ext_clk(struct clk * clk)
static int omap1_clk_enable(struct clk *clk)
{
int ret = 0;
+
if (clk->usecount++ == 0) {
- if (likely(clk->parent)) {
+ if (clk->parent) {
ret = omap1_clk_enable(clk->parent);
-
- if (unlikely(ret != 0)) {
- clk->usecount--;
- return ret;
- }
+ if (ret)
+ goto err;
if (clk->flags & CLOCK_NO_IDLE_PARENT)
omap1_clk_deny_idle(clk->parent);
}
ret = clk->ops->enable(clk);
-
- if (unlikely(ret != 0) && clk->parent) {
- omap1_clk_disable(clk->parent);
- clk->usecount--;
+ if (ret) {
+ if (clk->parent)
+ omap1_clk_disable(clk->parent);
+ goto err;
}
}
+ return ret;
+err:
+ clk->usecount--;
return ret;
}
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index a2c3fcc27a2..c49d9bfa3ab 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -47,6 +47,8 @@ obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \
obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \
board-rx51-peripherals.o \
+ mmc-twl4030.o
+
# Platform specific device init code
ifeq ($(CONFIG_USB_MUSB_SOC),y)
obj-y += usb-musb.o
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index e096f776f99..da57b0fcda1 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -23,6 +23,7 @@
#include <linux/spi/ads7846.h>
#include <linux/i2c/twl4030.h>
#include <linux/io.h>
+#include <linux/smsc911x.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -41,12 +42,12 @@
#include "mmc-twl4030.h"
-#define LDP_SMC911X_CS 1
-#define LDP_SMC911X_GPIO 152
+#define LDP_SMSC911X_CS 1
+#define LDP_SMSC911X_GPIO 152
#define DEBUG_BASE 0x08000000
#define LDP_ETHR_START DEBUG_BASE
-static struct resource ldp_smc911x_resources[] = {
+static struct resource ldp_smsc911x_resources[] = {
[0] = {
.start = LDP_ETHR_START,
.end = LDP_ETHR_START + SZ_4K,
@@ -59,40 +60,50 @@ static struct resource ldp_smc911x_resources[] = {
},
};
-static struct platform_device ldp_smc911x_device = {
- .name = "smc911x",
+static struct smsc911x_platform_config ldp_smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device ldp_smsc911x_device = {
+ .name = "smsc911x",
.id = -1,
- .num_resources = ARRAY_SIZE(ldp_smc911x_resources),
- .resource = ldp_smc911x_resources,
+ .num_resources = ARRAY_SIZE(ldp_smsc911x_resources),
+ .resource = ldp_smsc911x_resources,
+ .dev = {
+ .platform_data = &ldp_smsc911x_config,
+ },
};
static struct platform_device *ldp_devices[] __initdata = {
- &ldp_smc911x_device,
+ &ldp_smsc911x_device,
};
-static inline void __init ldp_init_smc911x(void)
+static inline void __init ldp_init_smsc911x(void)
{
int eth_cs;
unsigned long cs_mem_base;
int eth_gpio = 0;
- eth_cs = LDP_SMC911X_CS;
+ eth_cs = LDP_SMSC911X_CS;
if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
- printk(KERN_ERR "Failed to request GPMC mem for smc911x\n");
+ printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n");
return;
}
- ldp_smc911x_resources[0].start = cs_mem_base + 0x0;
- ldp_smc911x_resources[0].end = cs_mem_base + 0xff;
+ ldp_smsc911x_resources[0].start = cs_mem_base + 0x0;
+ ldp_smsc911x_resources[0].end = cs_mem_base + 0xff;
udelay(100);
- eth_gpio = LDP_SMC911X_GPIO;
+ eth_gpio = LDP_SMSC911X_GPIO;
- ldp_smc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
+ ldp_smsc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
- if (gpio_request(eth_gpio, "smc911x irq") < 0) {
- printk(KERN_ERR "Failed to request GPIO%d for smc911x IRQ\n",
+ if (gpio_request(eth_gpio, "smsc911x irq") < 0) {
+ printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
eth_gpio);
return;
}
@@ -104,7 +115,7 @@ static void __init omap_ldp_init_irq(void)
omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
- ldp_init_smc911x();
+ ldp_init_smsc911x();
}
static struct omap_uart_config ldp_uart_config __initdata = {
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index b3f6e9d8180..b1f23bea863 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -57,6 +57,9 @@
#define GPMC_CS0_BASE 0x60
#define GPMC_CS_SIZE 0x30
+#define OVERO_SMSC911X_CS 5
+#define OVERO_SMSC911X_GPIO 176
+
#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
@@ -116,6 +119,67 @@ static void __init overo_ads7846_init(void)
static inline void __init overo_ads7846_init(void) { return; }
#endif
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+
+#include <linux/smsc911x.h>
+
+static struct resource overo_smsc911x_resources[] = {
+ {
+ .name = "smsc911x-memory",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct smsc911x_platform_config overo_smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT ,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device overo_smsc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(overo_smsc911x_resources),
+ .resource = &overo_smsc911x_resources,
+ .dev = {
+ .platform_data = &overo_smsc911x_config,
+ },
+};
+
+static inline void __init overo_init_smsc911x(void)
+{
+ unsigned long cs_mem_base;
+
+ if (gpmc_cs_request(OVERO_SMSC911X_CS, SZ_16M, &cs_mem_base) < 0) {
+ printk(KERN_ERR "Failed request for GPMC mem for smsc911x\n");
+ return;
+ }
+
+ overo_smsc911x_resources[0].start = cs_mem_base + 0x0;
+ overo_smsc911x_resources[0].end = cs_mem_base + 0xff;
+
+ if ((gpio_request(OVERO_SMSC911X_GPIO, "SMSC911X IRQ") == 0) &&
+ (gpio_direction_input(OVERO_SMSC911X_GPIO) == 0)) {
+ gpio_export(OVERO_SMSC911X_GPIO, 0);
+ } else {
+ printk(KERN_ERR "could not obtain gpio for SMSC911X IRQ\n");
+ return;
+ }
+
+ overo_smsc911x_resources[1].start = OMAP_GPIO_IRQ(OVERO_SMSC911X_GPIO);
+ overo_smsc911x_resources[1].end = 0;
+
+ platform_device_register(&overo_smsc911x_device);
+}
+
+#else
+static inline void __init overo_init_smsc911x(void) { return; }
+#endif
+
static struct mtd_partition overo_nand_partitions[] = {
{
.name = "xloader",
@@ -290,6 +354,7 @@ static void __init overo_init(void)
overo_flash_init();
usb_musb_init();
overo_ads7846_init();
+ overo_init_smsc911x();
if ((gpio_request(OVERO_GPIO_W2W_NRESET,
"OVERO_GPIO_W2W_NRESET") == 0) &&
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index fc74e913c41..34a56a136ef 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -131,14 +131,14 @@ static struct musb_hdrc_platform_data musb_plat = {
.power = 50, /* up to 100 mA */
};
-static u64 musb_dmamask = DMA_32BIT_MASK;
+static u64 musb_dmamask = DMA_BIT_MASK(32);
static struct platform_device musb_device = {
.name = "musb_hdrc",
.id = -1,
.dev = {
.dma_mask = &musb_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &musb_plat,
},
.num_resources = ARRAY_SIZE(musb_resources),
@@ -146,14 +146,14 @@ static struct platform_device musb_device = {
};
#ifdef CONFIG_NOP_USB_XCEIV
-static u64 nop_xceiv_dmamask = DMA_32BIT_MASK;
+static u64 nop_xceiv_dmamask = DMA_BIT_MASK(32);
static struct platform_device nop_xceiv_device = {
.name = "nop_usb_xceiv",
.id = -1,
.dev = {
.dma_mask = &nop_xceiv_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = NULL,
},
};
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 68cc3efae56..6af99ddabdf 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -463,7 +463,7 @@ static struct platform_device orion5x_xor_shared = {
.resource = orion5x_xor_shared_resources,
};
-static u64 orion5x_xor_dmamask = DMA_32BIT_MASK;
+static u64 orion5x_xor_dmamask = DMA_BIT_MASK(32);
static struct resource orion5x_xor0_resources[] = {
[0] = {
@@ -486,7 +486,7 @@ static struct platform_device orion5x_xor0_channel = {
.resource = orion5x_xor0_resources,
.dev = {
.dma_mask = &orion5x_xor_dmamask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *)&orion5x_xor0_data,
},
};
@@ -512,7 +512,7 @@ static struct platform_device orion5x_xor1_channel = {
.resource = orion5x_xor1_resources,
.dev = {
.dma_mask = &orion5x_xor_dmamask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *)&orion5x_xor1_data,
},
};
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 96a2006cb59..3e66d9099ea 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -343,6 +343,15 @@ config ARCH_PXA_PALM
bool "PXA based Palm PDAs"
select HAVE_PWM
+config MACH_PALMTE2
+ bool "Palm Tungsten|E2"
+ default y
+ depends on ARCH_PXA_PALM
+ select PXA25x
+ help
+ Say Y here if you intend to run this kernel on a Palm Tungsten|E2
+ handheld computer.
+
config MACH_PALMT5
bool "Palm Tungsten|T5"
default y
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index c80e1bac494..682dbf4e14b 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_MACH_E740) += e740.o
obj-$(CONFIG_MACH_E750) += e750.o
obj-$(CONFIG_MACH_E400) += e400.o
obj-$(CONFIG_MACH_E800) += e800.o
+obj-$(CONFIG_MACH_PALMTE2) += palmte2.o
obj-$(CONFIG_MACH_PALMT5) += palmt5.o
obj-$(CONFIG_MACH_PALMTX) += palmtx.o
obj-$(CONFIG_MACH_PALMLD) += palmld.o
diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c
index 117b5435f8d..b50ef39eabf 100644
--- a/arch/arm/mach-pxa/cm-x2xx.c
+++ b/arch/arm/mach-pxa/cm-x2xx.c
@@ -121,7 +121,7 @@ static inline void cmx2xx_init_dm9000(void) {}
/* UCB1400 touchscreen controller */
#if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
static struct platform_device cmx2xx_ts_device = {
- .name = "ucb1400_ts",
+ .name = "ucb1400_core",
.id = -1,
};
diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c
index 10c2eaf9323..7c9c34c19ae 100644
--- a/arch/arm/mach-pxa/colibri-pxa300.c
+++ b/arch/arm/mach-pxa/colibri-pxa300.c
@@ -15,7 +15,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
-#include <net/ax88796.h>
+#include <linux/interrupt.h>
#include <asm/mach-types.h>
#include <asm/sizes.h>
@@ -32,12 +32,13 @@
#if defined(CONFIG_AX88796)
#define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO26_GPIO)
+
/*
* Asix AX88796 Ethernet
*/
static struct ax_plat_data colibri_asix_platdata = {
- .flags = AXFLG_MAC_FROMDEV,
- .wordlength = 2
+ .flags = 0, /* defined later */
+ .wordlength = 2,
};
static struct resource colibri_asix_resource[] = {
@@ -49,7 +50,7 @@ static struct resource colibri_asix_resource[] = {
[1] = {
.start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
.end = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
- .flags = IORESOURCE_IRQ
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
}
};
@@ -70,8 +71,8 @@ static mfp_cfg_t colibri_pxa300_eth_pin_config[] __initdata = {
static void __init colibri_pxa300_init_eth(void)
{
+ colibri_pxa3xx_init_eth(&colibri_asix_platdata);
pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_eth_pin_config));
- set_irq_type(gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), IRQ_TYPE_EDGE_FALLING);
platform_device_register(&asix_device);
}
#else
diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c
index 55b74a7a615..a18d37b3c5e 100644
--- a/arch/arm/mach-pxa/colibri-pxa320.c
+++ b/arch/arm/mach-pxa/colibri-pxa320.c
@@ -15,7 +15,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
-#include <net/ax88796.h>
+#include <linux/interrupt.h>
#include <asm/mach-types.h>
#include <asm/sizes.h>
@@ -38,8 +38,8 @@
* Asix AX88796 Ethernet
*/
static struct ax_plat_data colibri_asix_platdata = {
- .flags = AXFLG_MAC_FROMDEV,
- .wordlength = 2
+ .flags = 0, /* defined later */
+ .wordlength = 2,
};
static struct resource colibri_asix_resource[] = {
@@ -51,7 +51,7 @@ static struct resource colibri_asix_resource[] = {
[1] = {
.start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
.end = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
- .flags = IORESOURCE_IRQ
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
}
};
@@ -72,8 +72,8 @@ static mfp_cfg_t colibri_pxa320_eth_pin_config[] __initdata = {
static void __init colibri_pxa320_init_eth(void)
{
+ colibri_pxa3xx_init_eth(&colibri_asix_platdata);
pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_eth_pin_config));
- set_irq_type(gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), IRQ_TYPE_EDGE_FALLING);
platform_device_register(&asix_device);
}
#else
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c
index 12d0afc54aa..ea34e34f8cd 100644
--- a/arch/arm/mach-pxa/colibri-pxa3xx.c
+++ b/arch/arm/mach-pxa/colibri-pxa3xx.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
+#include <linux/etherdevice.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <asm/sizes.h>
@@ -28,6 +29,40 @@
#include "generic.h"
#include "devices.h"
+#if defined(CONFIG_AX88796)
+#define ETHER_ADDR_LEN 6
+static u8 ether_mac_addr[ETHER_ADDR_LEN];
+
+void __init colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data)
+{
+ int i;
+ u64 serial = ((u64) system_serial_high << 32) | system_serial_low;
+
+ /*
+ * If the bootloader passed in a serial boot tag, which contains a
+ * valid ethernet MAC, pass it to the interface. Toradex ships the
+ * modules with their own bootloader which provides a valid MAC
+ * this way.
+ */
+
+ for (i = 0; i < ETHER_ADDR_LEN; i++) {
+ ether_mac_addr[i] = serial & 0xff;
+ serial >>= 8;
+ }
+
+ if (is_valid_ether_addr(ether_mac_addr)) {
+ plat_data->flags |= AXFLG_MAC_FROMPLATFORM;
+ plat_data->mac_addr = ether_mac_addr;
+ printk(KERN_INFO "%s(): taking MAC from serial boot tag\n",
+ __func__);
+ } else {
+ plat_data->flags |= AXFLG_MAC_FROMDEV;
+ printk(KERN_INFO "%s(): no valid serial boot tag found, "
+ "taking MAC from device\n", __func__);
+ }
+}
+#endif
+
#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
static int mmc_detect_pin;
diff --git a/arch/arm/mach-pxa/csb701.c b/arch/arm/mach-pxa/csb701.c
index 4a2a2952c37..5a221a49ea4 100644
--- a/arch/arm/mach-pxa/csb701.c
+++ b/arch/arm/mach-pxa/csb701.c
@@ -5,6 +5,8 @@
#include <linux/input.h>
#include <linux/leds.h>
+#include <asm/mach-types.h>
+
static struct gpio_keys_button csb701_buttons[] = {
{
.code = 0x7,
@@ -54,6 +56,9 @@ static struct platform_device *devices[] __initdata = {
static int __init csb701_init(void)
{
+ if (!machine_is_csb726())
+ return -ENODEV;
+
return platform_add_devices(devices, ARRAY_SIZE(devices));
}
diff --git a/arch/arm/mach-pxa/e740.c b/arch/arm/mach-pxa/e740.c
index 07500a04fd8..a36fc17f671 100644
--- a/arch/arm/mach-pxa/e740.c
+++ b/arch/arm/mach-pxa/e740.c
@@ -29,6 +29,7 @@
#include <mach/udc.h>
#include <mach/irda.h>
#include <mach/irqs.h>
+#include <mach/audio.h>
#include "generic.h"
#include "eseries.h"
@@ -197,6 +198,7 @@ static void __init e740_init(void)
eseries_get_tmio_gpios();
platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_udc_info(&e7xx_udc_mach_info);
+ pxa_set_ac97_info(NULL);
e7xx_irda_init();
pxa_set_ficp_info(&e7xx_ficp_platform_data);
}
diff --git a/arch/arm/mach-pxa/e750.c b/arch/arm/mach-pxa/e750.c
index 6126c04e02b..1d00110590e 100644
--- a/arch/arm/mach-pxa/e750.c
+++ b/arch/arm/mach-pxa/e750.c
@@ -28,6 +28,7 @@
#include <mach/udc.h>
#include <mach/irda.h>
#include <mach/irqs.h>
+#include <mach/audio.h>
#include "generic.h"
#include "eseries.h"
@@ -198,6 +199,7 @@ static void __init e750_init(void)
eseries_get_tmio_gpios();
platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_udc_info(&e7xx_udc_mach_info);
+ pxa_set_ac97_info(NULL);
e7xx_irda_init();
pxa_set_ficp_info(&e7xx_ficp_platform_data);
}
diff --git a/arch/arm/mach-pxa/e800.c b/arch/arm/mach-pxa/e800.c
index 74ab09812a7..9866c7b9e78 100644
--- a/arch/arm/mach-pxa/e800.c
+++ b/arch/arm/mach-pxa/e800.c
@@ -27,6 +27,7 @@
#include <mach/eseries-gpio.h>
#include <mach/udc.h>
#include <mach/irqs.h>
+#include <mach/audio.h>
#include "generic.h"
#include "eseries.h"
@@ -199,6 +200,7 @@ static void __init e800_init(void)
eseries_get_tmio_gpios();
platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_udc_info(&e800_udc_mach_info);
+ pxa_set_ac97_info(NULL);
}
MACHINE_START(E800, "Toshiba e800")
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index 920dfb8d36d..67611dadb44 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -25,8 +25,10 @@
#include <linux/regulator/machine.h>
#include <linux/spi/spi.h>
#include <linux/spi/tdo24m.h>
+#include <linux/spi/libertas_spi.h>
#include <linux/power_supply.h>
#include <linux/apm-emulation.h>
+#include <linux/delay.h>
#include <media/soc_camera.h>
@@ -62,6 +64,8 @@
#define GPIO93_CAM_RESET (93)
#define GPIO41_ETHIRQ (41)
#define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ)
+#define GPIO115_WLAN_PWEN (115)
+#define GPIO19_WLAN_STRAP (19)
static int mmc_cd;
static int nand_rb;
@@ -159,8 +163,8 @@ static unsigned long common_pin_config[] = {
GPIO57_SSP1_TXD,
/* SSP2 */
- GPIO19_SSP2_SCLK,
- GPIO14_SSP2_SFRM,
+ GPIO19_GPIO, /* SSP2 clock is used as GPIO for Libertas pin-strap */
+ GPIO14_GPIO,
GPIO89_SSP2_TXD,
GPIO88_SSP2_RXD,
@@ -648,20 +652,86 @@ static struct tdo24m_platform_data em_x270_tdo24m_pdata = {
.model = TDO35S,
};
+static struct pxa2xx_spi_master em_x270_spi_2_info = {
+ .num_chipselect = 1,
+ .enable_dma = 1,
+};
+
+static struct pxa2xx_spi_chip em_x270_libertas_chip = {
+ .rx_threshold = 1,
+ .tx_threshold = 1,
+ .timeout = 1000,
+};
+
+static unsigned long em_x270_libertas_pin_config[] = {
+ /* SSP2 */
+ GPIO19_SSP2_SCLK,
+ GPIO14_GPIO,
+ GPIO89_SSP2_TXD,
+ GPIO88_SSP2_RXD,
+};
+
+static int em_x270_libertas_setup(struct spi_device *spi)
+{
+ int err = gpio_request(GPIO115_WLAN_PWEN, "WLAN PWEN");
+ if (err)
+ return err;
+
+ gpio_direction_output(GPIO19_WLAN_STRAP, 1);
+ mdelay(100);
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_libertas_pin_config));
+
+ gpio_direction_output(GPIO115_WLAN_PWEN, 0);
+ mdelay(100);
+ gpio_set_value(GPIO115_WLAN_PWEN, 1);
+ mdelay(100);
+
+ spi->bits_per_word = 16;
+ spi_setup(spi);
+
+ return 0;
+}
+
+static int em_x270_libertas_teardown(struct spi_device *spi)
+{
+ gpio_set_value(GPIO115_WLAN_PWEN, 0);
+ gpio_free(GPIO115_WLAN_PWEN);
+
+ return 0;
+}
+
+struct libertas_spi_platform_data em_x270_libertas_pdata = {
+ .use_dummy_writes = 1,
+ .gpio_cs = 14,
+ .setup = em_x270_libertas_setup,
+ .teardown = em_x270_libertas_teardown,
+};
+
static struct spi_board_info em_x270_spi_devices[] __initdata = {
{
- .modalias = "tdo24m",
- .max_speed_hz = 1000000,
- .bus_num = 1,
- .chip_select = 0,
- .controller_data = &em_x270_tdo24m_chip,
- .platform_data = &em_x270_tdo24m_pdata,
+ .modalias = "tdo24m",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .controller_data = &em_x270_tdo24m_chip,
+ .platform_data = &em_x270_tdo24m_pdata,
+ },
+ {
+ .modalias = "libertas_spi",
+ .max_speed_hz = 13000000,
+ .bus_num = 2,
+ .irq = IRQ_GPIO(116),
+ .chip_select = 0,
+ .controller_data = &em_x270_libertas_chip,
+ .platform_data = &em_x270_libertas_pdata,
},
};
static void __init em_x270_init_spi(void)
{
pxa2xx_set_spi_info(1, &em_x270_spi_info);
+ pxa2xx_set_spi_info(2, &em_x270_spi_2_info);
spi_register_board_info(ARRAY_AND_SIZE(em_x270_spi_devices));
}
#else
diff --git a/arch/arm/mach-pxa/include/mach/colibri.h b/arch/arm/mach-pxa/include/mach/colibri.h
index 3f2a01d6a03..90230c6f992 100644
--- a/arch/arm/mach-pxa/include/mach/colibri.h
+++ b/arch/arm/mach-pxa/include/mach/colibri.h
@@ -1,5 +1,8 @@
#ifndef _COLIBRI_H_
#define _COLIBRI_H_
+
+#include <net/ax88796.h>
+
/*
* common settings for all modules
*/
@@ -16,6 +19,10 @@ extern void colibri_pxa3xx_init_lcd(int bl_pin);
static inline void colibri_pxa3xx_init_lcd(int) {}
#endif
+#if defined(CONFIG_AX88796)
+extern void colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data);
+#endif
+
/* physical memory regions */
#define COLIBRI_SDRAM_BASE 0xa0000000 /* SDRAM region */
diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h
index 82a399f3f9f..20ef37d4a9a 100644
--- a/arch/arm/mach-pxa/include/mach/magician.h
+++ b/arch/arm/mach-pxa/include/mach/magician.h
@@ -27,7 +27,7 @@
#define GPIO22_MAGICIAN_VIBRA_EN 22
#define GPIO26_MAGICIAN_GSM_POWER 26
#define GPIO27_MAGICIAN_USBC_PUEN 27
-#define GPIO30_MAGICIAN_nCHARGE_EN 30
+#define GPIO30_MAGICIAN_BQ24022_nCHARGE_EN 30
#define GPIO37_MAGICIAN_KEY_HANGUP 37
#define GPIO38_MAGICIAN_KEY_CONTACTS 38
#define GPIO40_MAGICIAN_GSM_OUT2 40
@@ -98,7 +98,7 @@
#define EGPIO_MAGICIAN_UNKNOWN_WAVEDEV_DLL MAGICIAN_EGPIO(2, 2)
#define EGPIO_MAGICIAN_FLASH_VPP MAGICIAN_EGPIO(2, 3)
#define EGPIO_MAGICIAN_BL_POWER2 MAGICIAN_EGPIO(2, 4)
-#define EGPIO_MAGICIAN_CHARGE_EN MAGICIAN_EGPIO(2, 5)
+#define EGPIO_MAGICIAN_BQ24022_ISET2 MAGICIAN_EGPIO(2, 5)
#define EGPIO_MAGICIAN_GSM_POWER MAGICIAN_EGPIO(2, 7)
/* input */
diff --git a/arch/arm/mach-pxa/include/mach/palmld.h b/arch/arm/mach-pxa/include/mach/palmld.h
index 7c295a48d78..fb13c82ad6d 100644
--- a/arch/arm/mach-pxa/include/mach/palmld.h
+++ b/arch/arm/mach-pxa/include/mach/palmld.h
@@ -87,6 +87,7 @@
#define PALMLD_IDE_SIZE 0x00100000
#define PALMLD_PHYS_IO_START 0x40000000
+#define PALMLD_STR_BASE 0xa0200000
/* BATTERY */
#define PALMLD_BAT_MAX_VOLTAGE 4000 /* 4.00V maximum voltage */
diff --git a/arch/arm/mach-pxa/include/mach/palmt5.h b/arch/arm/mach-pxa/include/mach/palmt5.h
index 94db2881f04..052bfe788ad 100644
--- a/arch/arm/mach-pxa/include/mach/palmt5.h
+++ b/arch/arm/mach-pxa/include/mach/palmt5.h
@@ -59,6 +59,7 @@
/* Various addresses */
#define PALMT5_PHYS_RAM_START 0xa0000000
#define PALMT5_PHYS_IO_START 0x40000000
+#define PALMT5_STR_BASE 0xa0200000
/* TOUCHSCREEN */
#define AC97_LINK_FRAME 21
diff --git a/arch/arm/mach-pxa/include/mach/palmte2.h b/arch/arm/mach-pxa/include/mach/palmte2.h
new file mode 100644
index 00000000000..12361341f9d
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmte2.h
@@ -0,0 +1,68 @@
+/*
+ * GPIOs and interrupts for Palm Tungsten|E2 Handheld Computer
+ *
+ * Author:
+ * Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.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.
+ *
+ */
+
+#ifndef _INCLUDE_PALMTE2_H_
+#define _INCLUDE_PALMTE2_H_
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMTE2_POWER_DETECT 9
+#define GPIO_NR_PALMTE2_HOTSYNC_BUTTON_N 4
+#define GPIO_NR_PALMTE2_EARPHONE_DETECT 15
+
+/* SD/MMC */
+#define GPIO_NR_PALMTE2_SD_DETECT_N 10
+#define GPIO_NR_PALMTE2_SD_POWER 55
+#define GPIO_NR_PALMTE2_SD_READONLY 51
+
+/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
+#define GPIO_NR_PALMTE2_IR_DISABLE 48
+
+/* USB */
+#define GPIO_NR_PALMTE2_USB_DETECT_N 35
+#define GPIO_NR_PALMTE2_USB_PULLUP 53
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMTE2_BL_POWER 56
+#define GPIO_NR_PALMTE2_LCD_POWER 37
+
+/* KEYS */
+#define GPIO_NR_PALMTE2_KEY_NOTES 5
+#define GPIO_NR_PALMTE2_KEY_TASKS 7
+#define GPIO_NR_PALMTE2_KEY_CALENDAR 11
+#define GPIO_NR_PALMTE2_KEY_CONTACTS 13
+#define GPIO_NR_PALMTE2_KEY_CENTER 14
+#define GPIO_NR_PALMTE2_KEY_LEFT 19
+#define GPIO_NR_PALMTE2_KEY_RIGHT 20
+#define GPIO_NR_PALMTE2_KEY_DOWN 21
+#define GPIO_NR_PALMTE2_KEY_UP 22
+
+/** HERE ARE INIT VALUES **/
+
+/* BACKLIGHT */
+#define PALMTE2_MAX_INTENSITY 0xFE
+#define PALMTE2_DEFAULT_INTENSITY 0x7E
+#define PALMTE2_LIMIT_MASK 0x7F
+#define PALMTE2_PRESCALER 0x3F
+#define PALMTE2_PERIOD_NS 3500
+
+/* BATTERY */
+#define PALMTE2_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */
+#define PALMTE2_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */
+#define PALMTE2_BAT_MAX_CURRENT 0 /* unknokn */
+#define PALMTE2_BAT_MIN_CURRENT 0 /* unknown */
+#define PALMTE2_BAT_MAX_CHARGE 1 /* unknown */
+#define PALMTE2_BAT_MIN_CHARGE 1 /* unknown */
+#define PALMTE2_MAX_LIFE_MINS 360 /* on-life in minutes */
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/palmtx.h b/arch/arm/mach-pxa/include/mach/palmtx.h
index 1e8bccbda51..9f7d62fb4cb 100644
--- a/arch/arm/mach-pxa/include/mach/palmtx.h
+++ b/arch/arm/mach-pxa/include/mach/palmtx.h
@@ -78,6 +78,8 @@
#define PALMTX_PHYS_RAM_START 0xa0000000
#define PALMTX_PHYS_IO_START 0x40000000
+#define PALMTX_STR_BASE 0xa0200000
+
#define PALMTX_PHYS_FLASH_START PXA_CS0_PHYS /* ChipSelect 0 */
#define PALMTX_PHYS_NAND_START PXA_CS1_PHYS /* ChipSelect 1 */
diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h b/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h
index 2206cb61a9f..b87cecd9bbd 100644
--- a/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h
+++ b/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h
@@ -38,6 +38,7 @@ struct pxa2xx_spi_chip {
u8 dma_burst_size;
u32 timeout;
u8 enable_loopback;
+ int gpio_cs;
void (*cs_control)(u32 command);
};
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h b/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
index eb35fca9aea..3478eae32d8 100644
--- a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
@@ -49,6 +49,9 @@ struct pxa3xx_nand_platform_data {
*/
int enable_arbiter;
+ /* allow platform code to keep OBM/bootloader defined NFC config */
+ int keep_config;
+
const struct mtd_partition *parts;
unsigned int nr_parts;
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index d46b36746be..c899bbd94dc 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -25,6 +25,8 @@
#include <linux/mtd/physmap.h>
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
+#include <linux/regulator/bq24022.h>
+#include <linux/regulator/machine.h>
#include <linux/usb/gpio_vbus.h>
#include <mach/hardware.h>
@@ -507,7 +509,6 @@ static struct resource pasic3_resources[] = {
};
static struct pasic3_platform_data pasic3_platform_data = {
- .bus_shift = 2,
.led_pdata = &pasic3_leds_info,
.clock_rate = 4000000,
};
@@ -553,33 +554,7 @@ static struct platform_device gpio_vbus = {
static int power_supply_init(struct device *dev)
{
- int ret;
-
- ret = gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
- if (ret)
- goto err_cs_ac;
- ret = gpio_request(EGPIO_MAGICIAN_CABLE_STATE_USB, "CABLE_STATE_USB");
- if (ret)
- goto err_cs_usb;
- ret = gpio_request(EGPIO_MAGICIAN_CHARGE_EN, "CHARGE_EN");
- if (ret)
- goto err_chg_en;
- ret = gpio_request(GPIO30_MAGICIAN_nCHARGE_EN, "nCHARGE_EN");
- if (!ret)
- ret = gpio_direction_output(GPIO30_MAGICIAN_nCHARGE_EN, 0);
- if (ret)
- goto err_nchg_en;
-
- return 0;
-
-err_nchg_en:
- gpio_free(EGPIO_MAGICIAN_CHARGE_EN);
-err_chg_en:
- gpio_free(EGPIO_MAGICIAN_CABLE_STATE_USB);
-err_cs_usb:
- gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
-err_cs_ac:
- return ret;
+ return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
}
static int magician_is_ac_online(void)
@@ -587,22 +562,8 @@ static int magician_is_ac_online(void)
return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
}
-static int magician_is_usb_online(void)
-{
- return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_USB);
-}
-
-static void magician_set_charge(int flags)
-{
- gpio_set_value(GPIO30_MAGICIAN_nCHARGE_EN, !flags);
- gpio_set_value(EGPIO_MAGICIAN_CHARGE_EN, flags);
-}
-
static void power_supply_exit(struct device *dev)
{
- gpio_free(GPIO30_MAGICIAN_nCHARGE_EN);
- gpio_free(EGPIO_MAGICIAN_CHARGE_EN);
- gpio_free(EGPIO_MAGICIAN_CABLE_STATE_USB);
gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
}
@@ -613,8 +574,6 @@ static char *magician_supplicants[] = {
static struct pda_power_pdata power_supply_info = {
.init = power_supply_init,
.is_ac_online = magician_is_ac_online,
- .is_usb_online = magician_is_usb_online,
- .set_charge = magician_set_charge,
.exit = power_supply_exit,
.supplied_to = magician_supplicants,
.num_supplicants = ARRAY_SIZE(magician_supplicants),
@@ -647,6 +606,43 @@ static struct platform_device power_supply = {
.num_resources = ARRAY_SIZE(power_supply_resources),
};
+/*
+ * Battery charger
+ */
+
+static struct regulator_consumer_supply bq24022_consumers[] = {
+ {
+ .dev = &gpio_vbus.dev,
+ .supply = "vbus_draw",
+ },
+ {
+ .dev = &power_supply.dev,
+ .supply = "ac_draw",
+ },
+};
+
+static struct regulator_init_data bq24022_init_data = {
+ .constraints = {
+ .max_uA = 500000,
+ .valid_ops_mask = REGULATOR_CHANGE_CURRENT,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers),
+ .consumer_supplies = bq24022_consumers,
+};
+
+static struct bq24022_mach_info bq24022_info = {
+ .gpio_nce = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
+ .gpio_iset2 = EGPIO_MAGICIAN_BQ24022_ISET2,
+ .init_data = &bq24022_init_data,
+};
+
+static struct platform_device bq24022 = {
+ .name = "bq24022",
+ .id = -1,
+ .dev = {
+ .platform_data = &bq24022_info,
+ },
+};
/*
* MMC/SD
@@ -757,6 +753,7 @@ static struct platform_device *devices[] __initdata = {
&egpio,
&backlight,
&pasic3,
+ &bq24022,
&gpio_vbus,
&power_supply,
&strataflash,
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index 97c93a7a285..9203b069b35 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -50,6 +50,7 @@
#include <mach/pxa27x-udc.h>
#include <mach/i2c.h>
#include <mach/camera.h>
+#include <mach/audio.h>
#include <media/soc_camera.h>
#include <mach/mioa701.h>
@@ -763,8 +764,6 @@ MIO_PARENT_DEV(mioa701_backlight, "pwm-backlight", &pxa27x_device_pwm0.dev,
&mioa701_backlight_data);
MIO_SIMPLE_DEV(mioa701_led, "leds-gpio", &gpio_led_info)
MIO_SIMPLE_DEV(pxa2xx_pcm, "pxa2xx-pcm", NULL)
-MIO_SIMPLE_DEV(pxa2xx_ac97, "pxa2xx-ac97", NULL)
-MIO_PARENT_DEV(mio_wm9713_codec, "wm9713-codec", &pxa2xx_ac97.dev, NULL)
MIO_SIMPLE_DEV(mioa701_sound, "mioa701-wm9713", NULL)
MIO_SIMPLE_DEV(mioa701_board, "mioa701-board", NULL)
MIO_SIMPLE_DEV(gpio_vbus, "gpio-vbus", &gpio_vbus_data);
@@ -774,8 +773,6 @@ static struct platform_device *devices[] __initdata = {
&mioa701_backlight,
&mioa701_led,
&pxa2xx_pcm,
- &pxa2xx_ac97,
- &mio_wm9713_codec,
&mioa701_sound,
&power_dev,
&strataflash,
@@ -818,6 +815,7 @@ static void __init mioa701_machine_init(void)
pxa_set_keypad_info(&mioa701_keypad_info);
wm97xx_bat_set_pdata(&mioa701_battery_data);
pxa_set_udc_info(&mioa701_udc_info);
+ pxa_set_ac97_info(NULL);
pm_power_off = mioa701_poweroff;
arm_pm_restart = mioa701_restart;
platform_add_devices(devices, ARRAY_SIZE(devices));
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c
index 8587477a9bb..ecf5910e39d 100644
--- a/arch/arm/mach-pxa/palmld.c
+++ b/arch/arm/mach-pxa/palmld.c
@@ -24,6 +24,7 @@
#include <linux/gpio.h>
#include <linux/wm97xx_batt.h>
#include <linux/power_supply.h>
+#include <linux/sysdev.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -68,10 +69,10 @@ static unsigned long palmld_pin_config[] __initdata = {
GPIO47_FICP_TXD,
/* MATRIX KEYPAD */
- GPIO100_KP_MKIN_0,
- GPIO101_KP_MKIN_1,
- GPIO102_KP_MKIN_2,
- GPIO97_KP_MKIN_3,
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
GPIO103_KP_MKOUT_0,
GPIO104_KP_MKOUT_1,
GPIO105_KP_MKOUT_2,
@@ -507,6 +508,33 @@ static struct pxafb_mach_info palmld_lcd_screen = {
};
/******************************************************************************
+ * Power management - standby
+ ******************************************************************************/
+#ifdef CONFIG_PM
+static u32 *addr __initdata;
+static u32 resume[3] __initdata = {
+ 0xe3a00101, /* mov r0, #0x40000000 */
+ 0xe380060f, /* orr r0, r0, #0x00f00000 */
+ 0xe590f008, /* ldr pc, [r0, #0x08] */
+};
+
+static int __init palmld_pm_init(void)
+{
+ int i;
+
+ /* this is where the bootloader jumps */
+ addr = phys_to_virt(PALMLD_STR_BASE);
+
+ for (i = 0; i < 3; i++)
+ addr[i] = resume[i];
+
+ return 0;
+}
+
+device_initcall(palmld_pm_init);
+#endif
+
+/******************************************************************************
* Machine init
******************************************************************************/
static struct platform_device *devices[] __initdata = {
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index 9521c7b3349..0680f1a575a 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -75,10 +75,10 @@ static unsigned long palmt5_pin_config[] __initdata = {
GPIO95_GPIO, /* usb power */
/* MATRIX KEYPAD */
- GPIO100_KP_MKIN_0,
- GPIO101_KP_MKIN_1,
- GPIO102_KP_MKIN_2,
- GPIO97_KP_MKIN_3,
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
GPIO103_KP_MKOUT_0,
GPIO104_KP_MKOUT_1,
GPIO105_KP_MKOUT_2,
@@ -450,6 +450,33 @@ static struct pxafb_mach_info palmt5_lcd_screen = {
};
/******************************************************************************
+ * Power management - standby
+ ******************************************************************************/
+#ifdef CONFIG_PM
+static u32 *addr __initdata;
+static u32 resume[3] __initdata = {
+ 0xe3a00101, /* mov r0, #0x40000000 */
+ 0xe380060f, /* orr r0, r0, #0x00f00000 */
+ 0xe590f008, /* ldr pc, [r0, #0x08] */
+};
+
+static int __init palmt5_pm_init(void)
+{
+ int i;
+
+ /* this is where the bootloader jumps */
+ addr = phys_to_virt(PALMT5_STR_BASE);
+
+ for (i = 0; i < 3; i++)
+ addr[i] = resume[i];
+
+ return 0;
+}
+
+device_initcall(palmt5_pm_init);
+#endif
+
+/******************************************************************************
* Machine init
******************************************************************************/
static struct platform_device *devices[] __initdata = {
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
new file mode 100644
index 00000000000..43fcf2e8688
--- /dev/null
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -0,0 +1,466 @@
+/*
+ * Hardware definitions for Palm Tungsten|E2
+ *
+ * Author:
+ * Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.com>
+ *
+ * Rewrite for mainline:
+ * Marek Vasut <marek.vasut@gmail.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.
+ *
+ * (find more info at www.hackndev.com)
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+#include <linux/wm97xx_batt.h>
+#include <linux/power_supply.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/audio.h>
+#include <mach/palmte2.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/irda.h>
+#include <mach/udc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmte2_pin_config[] __initdata = {
+ /* MMC */
+ GPIO6_MMC_CLK,
+ GPIO8_MMC_CS0,
+ GPIO10_GPIO, /* SD detect */
+ GPIO55_GPIO, /* SD power */
+ GPIO51_GPIO, /* SD r/o switch */
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
+ /* PWM */
+ GPIO16_PWM0_OUT,
+
+ /* USB */
+ GPIO15_GPIO, /* usb detect */
+ GPIO53_GPIO, /* usb power */
+
+ /* IrDA */
+ GPIO48_GPIO, /* ir disable */
+ GPIO46_FICP_RXD,
+ GPIO47_FICP_TXD,
+
+ /* LCD */
+ GPIO58_LCD_LDD_0,
+ GPIO59_LCD_LDD_1,
+ GPIO60_LCD_LDD_2,
+ GPIO61_LCD_LDD_3,
+ GPIO62_LCD_LDD_4,
+ GPIO63_LCD_LDD_5,
+ GPIO64_LCD_LDD_6,
+ GPIO65_LCD_LDD_7,
+ GPIO66_LCD_LDD_8,
+ GPIO67_LCD_LDD_9,
+ GPIO68_LCD_LDD_10,
+ GPIO69_LCD_LDD_11,
+ GPIO70_LCD_LDD_12,
+ GPIO71_LCD_LDD_13,
+ GPIO72_LCD_LDD_14,
+ GPIO73_LCD_LDD_15,
+ GPIO74_LCD_FCLK,
+ GPIO75_LCD_LCLK,
+ GPIO76_LCD_PCLK,
+ GPIO77_LCD_BIAS,
+
+ /* GPIO KEYS */
+ GPIO5_GPIO, /* notes */
+ GPIO7_GPIO, /* tasks */
+ GPIO11_GPIO, /* calendar */
+ GPIO13_GPIO, /* contacts */
+ GPIO14_GPIO, /* center */
+ GPIO19_GPIO, /* left */
+ GPIO20_GPIO, /* right */
+ GPIO21_GPIO, /* down */
+ GPIO22_GPIO, /* up */
+
+ /* MISC */
+ GPIO1_RST, /* reset */
+ GPIO4_GPIO, /* Hotsync button */
+ GPIO9_GPIO, /* power detect */
+ GPIO37_GPIO, /* LCD power */
+ GPIO56_GPIO, /* Backlight power */
+};
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+static int palmte2_mci_init(struct device *dev,
+ irq_handler_t palmte2_detect_int, void *data)
+{
+ int err = 0;
+
+ /* Setup an interrupt for detecting card insert/remove events */
+ err = gpio_request(GPIO_NR_PALMTE2_SD_DETECT_N, "SD IRQ");
+ if (err)
+ goto err;
+ err = gpio_direction_input(GPIO_NR_PALMTE2_SD_DETECT_N);
+ if (err)
+ goto err2;
+ err = request_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N),
+ palmte2_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "SD/MMC card detect", data);
+ if (err) {
+ printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
+ __func__);
+ goto err2;
+ }
+
+ err = gpio_request(GPIO_NR_PALMTE2_SD_POWER, "SD_POWER");
+ if (err)
+ goto err3;
+ err = gpio_direction_output(GPIO_NR_PALMTE2_SD_POWER, 0);
+ if (err)
+ goto err4;
+
+ err = gpio_request(GPIO_NR_PALMTE2_SD_READONLY, "SD_READONLY");
+ if (err)
+ goto err4;
+ err = gpio_direction_input(GPIO_NR_PALMTE2_SD_READONLY);
+ if (err)
+ goto err5;
+
+ printk(KERN_DEBUG "%s: irq registered\n", __func__);
+
+ return 0;
+
+err5:
+ gpio_free(GPIO_NR_PALMTE2_SD_READONLY);
+err4:
+ gpio_free(GPIO_NR_PALMTE2_SD_POWER);
+err3:
+ free_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N), data);
+err2:
+ gpio_free(GPIO_NR_PALMTE2_SD_DETECT_N);
+err:
+ return err;
+}
+
+static void palmte2_mci_exit(struct device *dev, void *data)
+{
+ gpio_free(GPIO_NR_PALMTE2_SD_READONLY);
+ gpio_free(GPIO_NR_PALMTE2_SD_POWER);
+ free_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N), data);
+ gpio_free(GPIO_NR_PALMTE2_SD_DETECT_N);
+}
+
+static void palmte2_mci_power(struct device *dev, unsigned int vdd)
+{
+ struct pxamci_platform_data *p_d = dev->platform_data;
+ gpio_set_value(GPIO_NR_PALMTE2_SD_POWER, p_d->ocr_mask & (1 << vdd));
+}
+
+static int palmte2_mci_get_ro(struct device *dev)
+{
+ return gpio_get_value(GPIO_NR_PALMTE2_SD_READONLY);
+}
+
+static struct pxamci_platform_data palmte2_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .setpower = palmte2_mci_power,
+ .get_ro = palmte2_mci_get_ro,
+ .init = palmte2_mci_init,
+ .exit = palmte2_mci_exit,
+};
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+static struct gpio_keys_button palmte2_pxa_buttons[] = {
+ {KEY_F1, GPIO_NR_PALMTE2_KEY_CONTACTS, 1, "Contacts" },
+ {KEY_F2, GPIO_NR_PALMTE2_KEY_CALENDAR, 1, "Calendar" },
+ {KEY_F3, GPIO_NR_PALMTE2_KEY_TASKS, 1, "Tasks" },
+ {KEY_F4, GPIO_NR_PALMTE2_KEY_NOTES, 1, "Notes" },
+ {KEY_ENTER, GPIO_NR_PALMTE2_KEY_CENTER, 1, "Center" },
+ {KEY_LEFT, GPIO_NR_PALMTE2_KEY_LEFT, 1, "Left" },
+ {KEY_RIGHT, GPIO_NR_PALMTE2_KEY_RIGHT, 1, "Right" },
+ {KEY_DOWN, GPIO_NR_PALMTE2_KEY_DOWN, 1, "Down" },
+ {KEY_UP, GPIO_NR_PALMTE2_KEY_UP, 1, "Up" },
+};
+
+static struct gpio_keys_platform_data palmte2_pxa_keys_data = {
+ .buttons = palmte2_pxa_buttons,
+ .nbuttons = ARRAY_SIZE(palmte2_pxa_buttons),
+};
+
+static struct platform_device palmte2_pxa_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte2_pxa_keys_data,
+ },
+};
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+static int palmte2_backlight_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_NR_PALMTE2_BL_POWER, "BL POWER");
+ if (ret)
+ goto err;
+ ret = gpio_direction_output(GPIO_NR_PALMTE2_BL_POWER, 0);
+ if (ret)
+ goto err2;
+ ret = gpio_request(GPIO_NR_PALMTE2_LCD_POWER, "LCD POWER");
+ if (ret)
+ goto err2;
+ ret = gpio_direction_output(GPIO_NR_PALMTE2_LCD_POWER, 0);
+ if (ret)
+ goto err3;
+
+ return 0;
+err3:
+ gpio_free(GPIO_NR_PALMTE2_LCD_POWER);
+err2:
+ gpio_free(GPIO_NR_PALMTE2_BL_POWER);
+err:
+ return ret;
+}
+
+static int palmte2_backlight_notify(int brightness)
+{
+ gpio_set_value(GPIO_NR_PALMTE2_BL_POWER, brightness);
+ gpio_set_value(GPIO_NR_PALMTE2_LCD_POWER, brightness);
+ return brightness;
+}
+
+static void palmte2_backlight_exit(struct device *dev)
+{
+ gpio_free(GPIO_NR_PALMTE2_BL_POWER);
+ gpio_free(GPIO_NR_PALMTE2_LCD_POWER);
+}
+
+static struct platform_pwm_backlight_data palmte2_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = PALMTE2_MAX_INTENSITY,
+ .dft_brightness = PALMTE2_MAX_INTENSITY,
+ .pwm_period_ns = PALMTE2_PERIOD_NS,
+ .init = palmte2_backlight_init,
+ .notify = palmte2_backlight_notify,
+ .exit = palmte2_backlight_exit,
+};
+
+static struct platform_device palmte2_backlight = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa25x_device_pwm0.dev,
+ .platform_data = &palmte2_backlight_data,
+ },
+};
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+static int palmte2_irda_startup(struct device *dev)
+{
+ int err;
+ err = gpio_request(GPIO_NR_PALMTE2_IR_DISABLE, "IR DISABLE");
+ if (err)
+ goto err;
+ err = gpio_direction_output(GPIO_NR_PALMTE2_IR_DISABLE, 1);
+ if (err)
+ gpio_free(GPIO_NR_PALMTE2_IR_DISABLE);
+err:
+ return err;
+}
+
+static void palmte2_irda_shutdown(struct device *dev)
+{
+ gpio_free(GPIO_NR_PALMTE2_IR_DISABLE);
+}
+
+static void palmte2_irda_transceiver_mode(struct device *dev, int mode)
+{
+ gpio_set_value(GPIO_NR_PALMTE2_IR_DISABLE, mode & IR_OFF);
+ pxa2xx_transceiver_mode(dev, mode);
+}
+
+static struct pxaficp_platform_data palmte2_ficp_platform_data = {
+ .startup = palmte2_irda_startup,
+ .shutdown = palmte2_irda_shutdown,
+ .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF,
+ .transceiver_mode = palmte2_irda_transceiver_mode,
+};
+
+/******************************************************************************
+ * UDC
+ ******************************************************************************/
+static struct pxa2xx_udc_mach_info palmte2_udc_info __initdata = {
+ .gpio_vbus = GPIO_NR_PALMTE2_USB_DETECT_N,
+ .gpio_vbus_inverted = 1,
+ .gpio_pullup = GPIO_NR_PALMTE2_USB_PULLUP,
+ .gpio_pullup_inverted = 0,
+};
+
+/******************************************************************************
+ * Power supply
+ ******************************************************************************/
+static int power_supply_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_NR_PALMTE2_POWER_DETECT, "CABLE_STATE_AC");
+ if (ret)
+ goto err1;
+ ret = gpio_direction_input(GPIO_NR_PALMTE2_POWER_DETECT);
+ if (ret)
+ goto err2;
+
+ return 0;
+
+err2:
+ gpio_free(GPIO_NR_PALMTE2_POWER_DETECT);
+err1:
+ return ret;
+}
+
+static int palmte2_is_ac_online(void)
+{
+ return gpio_get_value(GPIO_NR_PALMTE2_POWER_DETECT);
+}
+
+static void power_supply_exit(struct device *dev)
+{
+ gpio_free(GPIO_NR_PALMTE2_POWER_DETECT);
+}
+
+static char *palmte2_supplicants[] = {
+ "main-battery",
+};
+
+static struct pda_power_pdata power_supply_info = {
+ .init = power_supply_init,
+ .is_ac_online = palmte2_is_ac_online,
+ .exit = power_supply_exit,
+ .supplied_to = palmte2_supplicants,
+ .num_supplicants = ARRAY_SIZE(palmte2_supplicants),
+};
+
+static struct platform_device power_supply = {
+ .name = "pda-power",
+ .id = -1,
+ .dev = {
+ .platform_data = &power_supply_info,
+ },
+};
+
+/******************************************************************************
+ * WM97xx battery
+ ******************************************************************************/
+static struct wm97xx_batt_info wm97xx_batt_pdata = {
+ .batt_aux = WM97XX_AUX_ID3,
+ .temp_aux = WM97XX_AUX_ID2,
+ .charge_gpio = -1,
+ .max_voltage = PALMTE2_BAT_MAX_VOLTAGE,
+ .min_voltage = PALMTE2_BAT_MIN_VOLTAGE,
+ .batt_mult = 1000,
+ .batt_div = 414,
+ .temp_mult = 1,
+ .temp_div = 1,
+ .batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO,
+ .batt_name = "main-batt",
+};
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+static struct pxafb_mode_info palmte2_lcd_modes[] = {
+{
+ .pixclock = 77757,
+ .xres = 320,
+ .yres = 320,
+ .bpp = 16,
+
+ .left_margin = 28,
+ .right_margin = 7,
+ .upper_margin = 7,
+ .lower_margin = 5,
+
+ .hsync_len = 4,
+ .vsync_len = 1,
+},
+};
+
+static struct pxafb_mach_info palmte2_lcd_screen = {
+ .modes = palmte2_lcd_modes,
+ .num_modes = ARRAY_SIZE(palmte2_lcd_modes),
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static struct platform_device *devices[] __initdata = {
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+ &palmte2_pxa_keys,
+#endif
+ &palmte2_backlight,
+ &power_supply,
+};
+
+/* setup udc GPIOs initial state */
+static void __init palmte2_udc_init(void)
+{
+ if (!gpio_request(GPIO_NR_PALMTE2_USB_PULLUP, "UDC Vbus")) {
+ gpio_direction_output(GPIO_NR_PALMTE2_USB_PULLUP, 1);
+ gpio_free(GPIO_NR_PALMTE2_USB_PULLUP);
+ }
+}
+
+static void __init palmte2_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(palmte2_pin_config));
+
+ set_pxa_fb_info(&palmte2_lcd_screen);
+ pxa_set_mci_info(&palmte2_mci_platform_data);
+ palmte2_udc_init();
+ pxa_set_udc_info(&palmte2_udc_info);
+ pxa_set_ac97_info(NULL);
+ pxa_set_ficp_info(&palmte2_ficp_platform_data);
+ wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(PALMTE2, "Palm Tungsten|E2")
+ .phys_io = 0x40000000,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .boot_params = 0xa0000100,
+ .map_io = pxa_map_io,
+ .init_irq = pxa25x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = palmte2_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index b490c092461..59d0c1cba55 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -93,10 +93,10 @@ static unsigned long palmtx_pin_config[] __initdata = {
GPIO116_GPIO, /* wifi ready */
/* MATRIX KEYPAD */
- GPIO100_KP_MKIN_0,
- GPIO101_KP_MKIN_1,
- GPIO102_KP_MKIN_2,
- GPIO97_KP_MKIN_3,
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
GPIO103_KP_MKOUT_0,
GPIO104_KP_MKOUT_1,
GPIO105_KP_MKOUT_2,
@@ -459,6 +459,33 @@ static struct pxafb_mach_info palmtx_lcd_screen = {
};
/******************************************************************************
+ * Power management - standby
+ ******************************************************************************/
+#ifdef CONFIG_PM
+static u32 *addr __initdata;
+static u32 resume[3] __initdata = {
+ 0xe3a00101, /* mov r0, #0x40000000 */
+ 0xe380060f, /* orr r0, r0, #0x00f00000 */
+ 0xe590f008, /* ldr pc, [r0, #0x08] */
+};
+
+static int __init palmtx_pm_init(void)
+{
+ int i;
+
+ /* this is where the bootloader jumps */
+ addr = phys_to_virt(PALMTX_STR_BASE);
+
+ for (i = 0; i < 3; i++)
+ addr[i] = resume[i];
+
+ return 0;
+}
+
+device_initcall(palmtx_pm_init);
+#endif
+
+/******************************************************************************
* Machine init
******************************************************************************/
static struct platform_device *devices[] __initdata = {
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 6e8ade6ae33..afac5b6d3d7 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -45,6 +45,7 @@
#include <mach/udc.h>
#include <mach/tosa_bt.h>
#include <mach/pxa2xx_spi.h>
+#include <mach/audio.h>
#include <asm/mach/arch.h>
#include <mach/tosa.h>
@@ -914,6 +915,7 @@ static void __init tosa_init(void)
pxa_set_udc_info(&udc_info);
pxa_set_ficp_info(&tosa_ficp_platform_data);
pxa_set_i2c_info(NULL);
+ pxa_set_ac97_info(NULL);
platform_scoop_config = &tosa_pcmcia_config;
pxa2xx_set_spi_info(2, &pxa_ssp_master_info);
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index d6766685cfc..9ab947c14f2 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -28,7 +28,7 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/io.h>
-#include <linux/smc911x.h>
+#include <linux/smsc911x.h>
#include <linux/ata_platform.h>
#include <asm/clkdev.h>
@@ -128,14 +128,15 @@ int realview_flash_register(struct resource *res, u32 num)
return platform_device_register(&realview_flash_device);
}
-static struct smc911x_platdata realview_smc911x_platdata = {
- .flags = SMC911X_USE_32BIT,
- .irq_flags = IRQF_SHARED,
- .irq_polarity = 1,
+static struct smsc911x_platform_config smsc911x_config = {
+ .flags = SMSC911X_USE_32BIT,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
};
static struct platform_device realview_eth_device = {
- .name = "smc911x",
+ .name = "smsc911x",
.id = 0,
.num_resources = 2,
};
@@ -145,8 +146,8 @@ int realview_eth_register(const char *name, struct resource *res)
if (name)
realview_eth_device.name = name;
realview_eth_device.resource = res;
- if (strcmp(realview_eth_device.name, "smc911x") == 0)
- realview_eth_device.dev.platform_data = &realview_smc911x_platdata;
+ if (strcmp(realview_eth_device.name, "smsc911x") == 0)
+ realview_eth_device.dev.platform_data = &smsc911x_config;
return platform_device_register(&realview_eth_device);
}
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c
index 67d6d9cc68b..d0d39adf640 100644
--- a/arch/arm/mach-realview/localtimer.c
+++ b/arch/arm/mach-realview/localtimer.c
@@ -191,6 +191,7 @@ void __cpuinit local_timer_setup(void)
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);
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 01bd76725b9..4389c160f7d 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -409,8 +409,7 @@ static struct platform_device bast_sio = {
static struct s3c2410_platform_i2c __initdata bast_i2c_info = {
.flags = 0,
.slave_addr = 0x10,
- .bus_freq = 100*1000,
- .max_freq = 130*1000,
+ .frequency = 100*1000,
};
/* Asix AX88796 10/100 ethernet controller */
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 05a5e877b49..2b83f870771 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -340,8 +340,7 @@ static struct platform_device *n35_devices[] __initdata = {
static struct s3c2410_platform_i2c n30_i2ccfg = {
.flags = 0,
.slave_addr = 0x10,
- .bus_freq = 10*1000,
- .max_freq = 10*1000,
+ .frequency = 10*1000,
};
/* Lots of hardcoded stuff, but it sets up the hardware in a useful
diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c
index 72c266aee14..332bd3263ea 100644
--- a/arch/arm/mach-s3c2412/mach-jive.c
+++ b/arch/arm/mach-s3c2412/mach-jive.c
@@ -453,8 +453,7 @@ static struct spi_board_info __initdata jive_spi_devs[] = {
/* I2C bus and device configuration. */
static struct s3c2410_platform_i2c jive_i2c_cfg __initdata = {
- .max_freq = 80 * 1000,
- .bus_freq = 50 * 1000,
+ .frequency = 80 * 1000,
.flags = S3C_IICFLG_FILTER,
.sda_delay = 2,
};
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
index 94077fbd96b..6f7e70907e4 100644
--- a/arch/arm/mm/abort-ev6.S
+++ b/arch/arm/mm/abort-ev6.S
@@ -29,10 +29,10 @@ ENTRY(v6_early_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
/*
- * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR.
+ * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR (erratum 326103).
* The test below covers all the write situations, including Java bytecodes
*/
- bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
+ bic r1, r1, #1 << 11 @ clear bit 11 of FSR
tst r3, #PSR_J_BIT @ Java?
movne pc, lr
do_thumb_abort
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index d6dd83826f8..6e77c042d8e 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -115,6 +115,10 @@ static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
raw_local_irq_restore(flags);
}
+static inline void l2_inv_all(void)
+{
+ __asm__("mcr p15, 1, %0, c15, c11, 0" : : "r" (0));
+}
/*
* Linux primitives.
@@ -254,9 +258,7 @@ static void __init enable_dcache(void)
static void __init __invalidate_icache(void)
{
- int dummy;
-
- __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : "=r" (dummy));
+ __asm__("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
}
static int __init invalidate_and_disable_icache(void)
@@ -321,6 +323,7 @@ static void __init enable_l2(void)
d = flush_and_disable_dcache();
i = invalidate_and_disable_icache();
+ l2_inv_all();
write_extra_features(u | 0x00400000);
if (i)
enable_icache();
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index b438fc4fb77..e6344ece00c 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -828,6 +828,17 @@ void __init reserve_node_zero(pg_data_t *pgdat)
BOOTMEM_DEFAULT);
}
+ if (machine_is_palmld() || machine_is_palmtx()) {
+ reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
+ BOOTMEM_EXCLUSIVE);
+ reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
+ BOOTMEM_EXCLUSIVE);
+ }
+
+ if (machine_is_palmt5())
+ reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
+ BOOTMEM_EXCLUSIVE);
+
#ifdef CONFIG_SA1111
/*
* Because of the SA1111 DMA bug, we want to preserve our
diff --git a/arch/arm/plat-iop/adma.c b/arch/arm/plat-iop/adma.c
index f7242082161..3c127aabe21 100644
--- a/arch/arm/plat-iop/adma.c
+++ b/arch/arm/plat-iop/adma.c
@@ -119,7 +119,7 @@ static struct resource iop3xx_aau_resources[] = {
}
};
-static u64 iop3xx_adma_dmamask = DMA_32BIT_MASK;
+static u64 iop3xx_adma_dmamask = DMA_BIT_MASK(32);
static struct iop_adma_platform_data iop3xx_dma_0_data = {
.hw_id = DMA0_ID,
@@ -143,7 +143,7 @@ struct platform_device iop3xx_dma_0_channel = {
.resource = iop3xx_dma_0_resources,
.dev = {
.dma_mask = &iop3xx_adma_dmamask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *) &iop3xx_dma_0_data,
},
};
@@ -155,7 +155,7 @@ struct platform_device iop3xx_dma_1_channel = {
.resource = iop3xx_dma_1_resources,
.dev = {
.dma_mask = &iop3xx_adma_dmamask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *) &iop3xx_dma_1_data,
},
};
@@ -167,7 +167,7 @@ struct platform_device iop3xx_aau_channel = {
.resource = iop3xx_aau_resources,
.dev = {
.dma_mask = &iop3xx_adma_dmamask,
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = (void *) &iop3xx_aau_data,
},
};
diff --git a/arch/arm/plat-mxc/include/mach/i2c.h b/arch/arm/plat-mxc/include/mach/i2c.h
new file mode 100644
index 00000000000..4a5dc5c6d8e
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/i2c.h
@@ -0,0 +1,25 @@
+/*
+ * i2c.h - i.MX I2C driver header file
+ *
+ * Copyright (c) 2008, Darius Augulis <augulis.darius@gmail.com>
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __ASM_ARCH_I2C_H_
+#define __ASM_ARCH_I2C_H_
+
+/**
+ * struct imxi2c_platform_data - structure of platform data for MXC I2C driver
+ * @init: Initialise gpio's and other board specific things
+ * @exit: Free everything initialised by @init
+ * @bitrate: Bus speed measured in Hz
+ *
+ **/
+struct imxi2c_platform_data {
+ int (*init)(struct device *dev);
+ void (*exit)(struct device *dev);
+ int bitrate;
+};
+
+#endif /* __ASM_ARCH_I2C_H_ */
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
index e0783e61958..eca37d09f3f 100644
--- a/arch/arm/plat-mxc/include/mach/memory.h
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -24,4 +24,12 @@
#define PHYS_OFFSET UL(0x80000000)
#endif
+#if defined(CONFIG_MX1_VIDEO)
+/*
+ * Increase size of DMA-consistent memory region.
+ * This is required for i.MX camera driver to capture at least four VGA frames.
+ */
+#define CONSISTENT_DMA_SIZE SZ_4M
+#endif /* CONFIG_MX1_VIDEO */
+
#endif /* __ASM_ARCH_MXC_MEMORY_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx1_camera.h b/arch/arm/plat-mxc/include/mach/mx1_camera.h
new file mode 100644
index 00000000000..4fd6c70314b
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx1_camera.h
@@ -0,0 +1,35 @@
+/*
+ * mx1_camera.h - i.MX1/i.MXL camera driver header file
+ *
+ * Copyright (c) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ * Copyright (C) 2009, Darius Augulis <augulis.darius@gmail.com>
+ *
+ * Based on PXA camera.h file:
+ * Copyright (C) 2003, Intel Corporation
+ * Copyright (C) 2008, Guennadi Liakhovetski <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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_CAMERA_H_
+#define __ASM_ARCH_CAMERA_H_
+
+#define MX1_CAMERA_DATA_HIGH 1
+#define MX1_CAMERA_PCLK_RISING 2
+#define MX1_CAMERA_VSYNC_HIGH 4
+
+extern unsigned char mx1_camera_sof_fiq_start, mx1_camera_sof_fiq_end;
+
+/**
+ * struct mx1_camera_pdata - i.MX1/i.MXL camera platform data
+ * @mclk_10khz: master clock frequency in 10kHz units
+ * @flags: MX1 camera platform flags
+ */
+struct mx1_camera_pdata {
+ unsigned long mclk_10khz;
+ unsigned long flags;
+};
+
+#endif /* __ASM_ARCH_CAMERA_H_ */
diff --git a/arch/arm/plat-s3c/dev-i2c0.c b/arch/arm/plat-s3c/dev-i2c0.c
index fe327074037..428372868fb 100644
--- a/arch/arm/plat-s3c/dev-i2c0.c
+++ b/arch/arm/plat-s3c/dev-i2c0.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/plat-s3c/dev-i2c0.c
*
- * Copyright 2008 Simtec Electronics
+ * Copyright 2008,2009 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
@@ -50,9 +50,8 @@ struct platform_device s3c_device_i2c0 = {
static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
.flags = 0,
.slave_addr = 0x10,
- .bus_freq = 100*1000,
- .max_freq = 400*1000,
- .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
+ .frequency = 100*1000,
+ .sda_delay = 100,
};
void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
diff --git a/arch/arm/plat-s3c/dev-i2c1.c b/arch/arm/plat-s3c/dev-i2c1.c
index 2387fbf57af..8349c462788 100644
--- a/arch/arm/plat-s3c/dev-i2c1.c
+++ b/arch/arm/plat-s3c/dev-i2c1.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/plat-s3c/dev-i2c1.c
*
- * Copyright 2008 Simtec Electronics
+ * Copyright 2008,2009 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
@@ -47,9 +47,8 @@ static struct s3c2410_platform_i2c default_i2c_data1 __initdata = {
.flags = 0,
.bus_num = 1,
.slave_addr = 0x10,
- .bus_freq = 100*1000,
- .max_freq = 400*1000,
- .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
+ .frequency = 100*1000,
+ .sda_delay = 100,
};
void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
diff --git a/arch/arm/plat-s3c/include/plat/iic.h b/arch/arm/plat-s3c/include/plat/iic.h
index dc1dfcb9bc6..67450f11574 100644
--- a/arch/arm/plat-s3c/include/plat/iic.h
+++ b/arch/arm/plat-s3c/include/plat/iic.h
@@ -1,9 +1,9 @@
-/* arch/arm/mach-s3c2410/include/mach/iic.h
+/* arch/arm/plat-s3c/include/plat/iic.h
*
- * Copyright (c) 2004 Simtec Electronics
+ * Copyright 2004,2009 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
- * S3C2410 - I2C Controller platfrom_device info
+ * S3C - I2C Controller platform_device info
*
* 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
@@ -15,19 +15,24 @@
#define S3C_IICFLG_FILTER (1<<0) /* enable s3c2440 filter */
-/* Notes:
- * 1) All frequencies are expressed in Hz
- * 2) A value of zero is `do not care`
-*/
-
+/**
+ * struct s3c2410_platform_i2c - Platform data for s3c I2C.
+ * @bus_num: The bus number to use (if possible).
+ * @flags: Any flags for the I2C bus (E.g. S3C_IICFLK_FILTER).
+ * @slave_addr: The I2C address for the slave device (if enabled).
+ * @frequency: The desired frequency in Hz of the bus. This is
+ * guaranteed to not be exceeded. If the caller does
+ * not care, use zero and the driver will select a
+ * useful default.
+ * @sda_delay: The delay (in ns) applied to SDA edges.
+ * @cfg_gpio: A callback to configure the pins for I2C operation.
+ */
struct s3c2410_platform_i2c {
- int bus_num; /* bus number to use */
+ int bus_num;
unsigned int flags;
- unsigned int slave_addr; /* slave address for controller */
- unsigned long bus_freq; /* standard bus frequency */
- unsigned long max_freq; /* max frequency for the bus */
- unsigned long min_freq; /* min frequency for the bus */
- unsigned int sda_delay; /* pclks (s3c2440 only) */
+ unsigned int slave_addr;
+ unsigned long frequency;
+ unsigned int sda_delay;
void (*cfg_gpio)(struct platform_device *dev);
};
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
index ba592a9e6fb..a2bed62aec2 100644
--- a/arch/arm/vfp/entry.S
+++ b/arch/arm/vfp/entry.S
@@ -15,13 +15,16 @@
* r10 = thread_info structure
* lr = failure return
*/
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <asm/asm-offsets.h>
-#include <asm/assembler.h>
+#include <asm/thread_info.h>
#include <asm/vfpmacros.h>
+#include "../kernel/entry-header.S"
ENTRY(do_vfp)
+#ifdef CONFIG_PREEMPT
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ add r11, r4, #1 @ increment it
+ str r11, [r10, #TI_PREEMPT]
+#endif
enable_irq
ldr r4, .LCvfp
ldr r11, [r10, #TI_CPU] @ CPU number
@@ -30,6 +33,12 @@ ENTRY(do_vfp)
ENDPROC(do_vfp)
ENTRY(vfp_null_entry)
+#ifdef CONFIG_PREEMPT
+ get_thread_info r10
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ sub r11, r4, #1 @ decrement it
+ str r11, [r10, #TI_PREEMPT]
+#endif
mov pc, lr
ENDPROC(vfp_null_entry)
@@ -41,6 +50,12 @@ ENDPROC(vfp_null_entry)
__INIT
ENTRY(vfp_testing_entry)
+#ifdef CONFIG_PREEMPT
+ get_thread_info r10
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ sub r11, r4, #1 @ decrement it
+ str r11, [r10, #TI_PREEMPT]
+#endif
ldr r0, VFP_arch_address
str r5, [r0] @ known non-zero value
mov pc, r9 @ we have handled the fault
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index a5a4e57763c..83c4e384b16 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -137,6 +137,12 @@ check_for_exception:
VFPFMXR FPEXC, r1 @ restore FPEXC last
sub r2, r2, #4
str r2, [sp, #S_PC] @ retry the instruction
+#ifdef CONFIG_PREEMPT
+ get_thread_info r10
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ sub r11, r4, #1 @ decrement it
+ str r11, [r10, #TI_PREEMPT]
+#endif
mov pc, r9 @ we think we have handled things
@@ -155,6 +161,12 @@ look_for_VFP_exceptions:
@ not recognised by VFP
DBGSTR "not VFP"
+#ifdef CONFIG_PREEMPT
+ get_thread_info r10
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ sub r11, r4, #1 @ decrement it
+ str r11, [r10, #TI_PREEMPT]
+#endif
mov pc, lr
process_exception:
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 75457b30d81..01599c4ef72 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -266,7 +266,7 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
* on VFP subarch 1.
*/
vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr, regs);
- return;
+ goto exit;
}
/*
@@ -297,7 +297,7 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
* the FPEXC.FP2V bit is valid only if FPEXC.EX is 1.
*/
if (fpexc ^ (FPEXC_EX | FPEXC_FP2V))
- return;
+ goto exit;
/*
* The barrier() here prevents fpinst2 being read
@@ -310,6 +310,8 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
exceptions = vfp_emulate_instruction(trigger, orig_fpscr, regs);
if (exceptions)
vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
+ exit:
+ preempt_enable();
}
static void vfp_enable(void *unused)
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index 05fe3053dca..35e3bd9858d 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -127,13 +127,13 @@ config BOARD_HAMMERHEAD
select CPU_AT32AP7000
select USB_ARCH_HAS_HCD
help
- The Hammerhead platform is built around a AVR32 32-bit microcontroller from Atmel.
+ The Hammerhead platform is built around an AVR32 32-bit microcontroller from Atmel.
It offers versatile peripherals, such as ethernet, usb device, usb host etc.
- The board also incooperates a power supply and is a Power over Ethernet (PoE) Powered
+ The board also incorporates a power supply and is a Power over Ethernet (PoE) Powered
Device (PD).
- Additonally, a Cyclone III FPGA from Altera is integrated on the board. The FPGA is
+ Additionally, a Cyclone III FPGA from Altera is integrated on the board. The FPGA is
mapped into the 32-bit AVR memory bus. The FPGA offers two DDR2 SDRAM interfaces, which
will cover even the most exceptional need of memory bandwidth. Together with the onboard
video decoder the board is ready for video processing.
@@ -144,6 +144,19 @@ config BOARD_FAVR_32
bool "Favr-32 LCD-board"
select CPU_AT32AP7000
+config BOARD_MERISC
+ bool "Merisc board"
+ select CPU_AT32AP7000
+ help
+ Merisc is the family name for a range of AVR32-based boards.
+
+ The boards are designed to be used in a man-machine
+ interfacing environment, utilizing a touch-based graphical
+ user interface. They host a vast range of I/O peripherals as
+ well as a large SDRAM & Flash memory bank.
+
+ For more information see: http://www.martinsson.se/merisc
+
config BOARD_MIMC200
bool "MIMC200 CPU board"
select CPU_AT32AP7000
@@ -153,6 +166,7 @@ source "arch/avr32/boards/atstk1000/Kconfig"
source "arch/avr32/boards/atngw100/Kconfig"
source "arch/avr32/boards/hammerhead/Kconfig"
source "arch/avr32/boards/favr-32/Kconfig"
+source "arch/avr32/boards/merisc/Kconfig"
choice
prompt "Boot loader type"
diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile
index f3ef3bbf797..0b97e14f73f 100644
--- a/arch/avr32/Makefile
+++ b/arch/avr32/Makefile
@@ -35,6 +35,7 @@ core-$(CONFIG_BOARD_ATSTK1000) += arch/avr32/boards/atstk1000/
core-$(CONFIG_BOARD_ATNGW100) += arch/avr32/boards/atngw100/
core-$(CONFIG_BOARD_HAMMERHEAD) += arch/avr32/boards/hammerhead/
core-$(CONFIG_BOARD_FAVR_32) += arch/avr32/boards/favr-32/
+core-$(CONFIG_BOARD_MERISC) += arch/avr32/boards/merisc/
core-$(CONFIG_BOARD_MIMC200) += arch/avr32/boards/mimc200/
core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/
core-y += arch/avr32/kernel/
diff --git a/arch/avr32/boards/atngw100/evklcd10x.c b/arch/avr32/boards/atngw100/evklcd10x.c
index 8140b22b346..00337112c5a 100644
--- a/arch/avr32/boards/atngw100/evklcd10x.c
+++ b/arch/avr32/boards/atngw100/evklcd10x.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/linkage.h>
+#include <linux/gpio.h>
#include <linux/fb.h>
#include <linux/platform_device.h>
@@ -19,26 +20,26 @@
#include <asm/setup.h>
#include <mach/at32ap700x.h>
+#include <mach/portmux.h>
#include <mach/board.h>
+#include <sound/atmel-ac97c.h>
+
static struct ac97c_platform_data __initdata ac97c0_data = {
- .dma_rx_periph_id = 3,
- .dma_tx_periph_id = 4,
- .dma_controller_id = 0,
- .reset_pin = GPIO_PIN_PB(19),
+ .reset_pin = GPIO_PIN_PB(19),
};
#ifdef CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA
static struct fb_videomode __initdata tcg057vglad_modes[] = {
{
- .name = "640x480 @ 60",
- .refresh = 60,
+ .name = "640x480 @ 50",
+ .refresh = 50,
.xres = 640, .yres = 480,
.pixclock = KHZ2PICOS(25180),
- .left_margin = 64, .right_margin = 31,
- .upper_margin = 34, .lower_margin = 2,
- .hsync_len = 96, .vsync_len = 4,
+ .left_margin = 64, .right_margin = 96,
+ .upper_margin = 34, .lower_margin = 11,
+ .hsync_len = 64, .vsync_len = 15,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
@@ -69,14 +70,14 @@ static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = {
#elif CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA
static struct fb_videomode __initdata tcg057qvlad_modes[] = {
{
- .name = "320x240 @ 60",
- .refresh = 60,
+ .name = "320x240 @ 50",
+ .refresh = 50,
.xres = 320, .yres = 240,
.pixclock = KHZ2PICOS(6300),
- .left_margin = 52, .right_margin = 28,
- .upper_margin = 7, .lower_margin = 2,
- .hsync_len = 96, .vsync_len = 4,
+ .left_margin = 34, .right_margin = 46,
+ .upper_margin = 7, .lower_margin = 15,
+ .hsync_len = 64, .vsync_len = 12,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
@@ -144,12 +145,29 @@ static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = {
};
#endif
+static void atevklcd10x_lcdc_power_control(int on)
+{
+ gpio_set_value(GPIO_PIN_PB(15), on);
+}
+
static int __init atevklcd10x_init(void)
{
- at32_add_device_ac97c(0, &ac97c0_data);
+ /* PB15 is connected to the enable line on the boost regulator
+ * controlling the backlight for the LCD panel.
+ */
+ at32_select_gpio(GPIO_PIN_PB(15), AT32_GPIOF_OUTPUT);
+ gpio_request(GPIO_PIN_PB(15), "backlight");
+ gpio_direction_output(GPIO_PIN_PB(15), 0);
+
+ atevklcd10x_lcdc_data.atmel_lcdfb_power_control =
+ atevklcd10x_lcdc_power_control;
at32_add_device_lcdc(0, &atevklcd10x_lcdc_data,
- fbmem_start, fbmem_size, 1);
+ fbmem_start, fbmem_size,
+ ATMEL_LCDC_ALT_18BIT | ATMEL_LCDC_PE_DVAL);
+
+ at32_add_device_ac97c(0, &ac97c0_data, AC97C_BOTH);
+
return 0;
}
postcore_initcall(atevklcd10x_init);
diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c
index 05d3722fff1..5b022aad4bd 100644
--- a/arch/avr32/boards/atngw100/setup.c
+++ b/arch/avr32/boards/atngw100/setup.c
@@ -56,13 +56,8 @@ static struct spi_board_info spi0_board_info[] __initdata = {
static struct mci_platform_data __initdata mci0_data = {
.slot[0] = {
.bus_width = 4,
-#ifndef CONFIG_BOARD_ATNGW100_EVKLCD10X
.detect_pin = GPIO_PIN_PC(25),
.wp_pin = GPIO_PIN_PE(0),
-#else
- .detect_pin = GPIO_PIN_NONE,
- .wp_pin = GPIO_PIN_NONE,
-#endif
},
};
@@ -123,7 +118,7 @@ static void __init set_hw_addr(struct platform_device *pdev)
void __init setup_board(void)
{
- at32_map_usart(1, 0); /* USART 1: /dev/ttyS0, DB9 */
+ at32_map_usart(1, 0, 0); /* USART 1: /dev/ttyS0, DB9 */
at32_setup_serial_console(0);
}
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index 1f33a106905..2adc261c9e3 100644
--- a/arch/avr32/boards/atstk1000/atstk1002.c
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -252,12 +252,12 @@ static void __init atstk1002_setup_extdac(void)
void __init setup_board(void)
{
#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
- at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */
+ at32_map_usart(0, 1, 0); /* USART 0/B: /dev/ttyS1, IRDA */
#else
- at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */
+ at32_map_usart(1, 0, 0); /* USART 1/A: /dev/ttyS0, DB9 */
#endif
/* USART 2/unused: expansion connector */
- at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */
+ at32_map_usart(3, 2, 0); /* USART 3/C: /dev/ttyS2, DB9 */
at32_setup_serial_console(0);
}
diff --git a/arch/avr32/boards/atstk1000/atstk1003.c b/arch/avr32/boards/atstk1000/atstk1003.c
index b3a23c88bcf..ff7e2329882 100644
--- a/arch/avr32/boards/atstk1000/atstk1003.c
+++ b/arch/avr32/boards/atstk1000/atstk1003.c
@@ -115,12 +115,12 @@ static void __init atstk1003_setup_extdac(void)
void __init setup_board(void)
{
#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
- at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */
+ at32_map_usart(0, 1, 0); /* USART 0/B: /dev/ttyS1, IRDA */
#else
- at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */
+ at32_map_usart(1, 0, 0); /* USART 1/A: /dev/ttyS0, DB9 */
#endif
/* USART 2/unused: expansion connector */
- at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */
+ at32_map_usart(3, 2, 0); /* USART 3/C: /dev/ttyS2, DB9 */
at32_setup_serial_console(0);
}
diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c
index 29b35aca96c..69a9f0f08c6 100644
--- a/arch/avr32/boards/atstk1000/atstk1004.c
+++ b/arch/avr32/boards/atstk1000/atstk1004.c
@@ -120,12 +120,12 @@ static void __init atstk1004_setup_extdac(void)
void __init setup_board(void)
{
#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
- at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */
+ at32_map_usart(0, 1, 0); /* USART 0/B: /dev/ttyS1, IRDA */
#else
- at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */
+ at32_map_usart(1, 0, 0); /* USART 1/A: /dev/ttyS0, DB9 */
#endif
/* USART 2/unused: expansion connector */
- at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */
+ at32_map_usart(3, 2, 0); /* USART 3/C: /dev/ttyS2, DB9 */
at32_setup_serial_console(0);
}
diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c
index 745c408c2ac..46c9b0a224c 100644
--- a/arch/avr32/boards/favr-32/setup.c
+++ b/arch/avr32/boards/favr-32/setup.c
@@ -22,6 +22,8 @@
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
+#include <sound/atmel-abdac.h>
+
#include <video/atmel_lcdc.h>
#include <asm/setup.h>
@@ -41,6 +43,9 @@ unsigned long at32_board_osc_rates[3] = {
/* Initialized by bootloader-specific startup code. */
struct tag *bootloader_tags __initdata;
+static struct atmel_abdac_pdata __initdata abdac0_data = {
+};
+
struct eth_addr {
u8 addr[6];
};
@@ -245,7 +250,7 @@ static void __init favr32_setup_atmel_pwm_bl(void)
void __init setup_board(void)
{
- at32_map_usart(3, 0); /* USART 3 => /dev/ttyS0 */
+ at32_map_usart(3, 0, 0); /* USART 3 => /dev/ttyS0 */
at32_setup_serial_console(0);
}
@@ -326,7 +331,7 @@ static int __init favr32_init(void)
spi1_board_info[0].irq = gpio_to_irq(GPIO_PIN_PB(3));
- set_abdac_rate(at32_add_device_abdac(0));
+ set_abdac_rate(at32_add_device_abdac(0, &abdac0_data));
at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel);
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
diff --git a/arch/avr32/boards/hammerhead/flash.c b/arch/avr32/boards/hammerhead/flash.c
index 559bbcb03f9..776c3cb9b6e 100644
--- a/arch/avr32/boards/hammerhead/flash.c
+++ b/arch/avr32/boards/hammerhead/flash.c
@@ -280,13 +280,13 @@ static struct resource hh_fpga0_resource[] = {
},
};
-static u64 hh_fpga0_dma_mask = DMA_32BIT_MASK;
+static u64 hh_fpga0_dma_mask = DMA_BIT_MASK(32);
static struct platform_device hh_fpga0_device = {
.name = "hh_fpga",
.id = 0,
.dev = {
.dma_mask = &hh_fpga0_dma_mask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.resource = hh_fpga0_resource,
.num_resources = ARRAY_SIZE(hh_fpga0_resource),
diff --git a/arch/avr32/boards/hammerhead/setup.c b/arch/avr32/boards/hammerhead/setup.c
index 4d2fe82b202..dd009875a40 100644
--- a/arch/avr32/boards/hammerhead/setup.c
+++ b/arch/avr32/boards/hammerhead/setup.c
@@ -29,6 +29,8 @@
#include <mach/init.h>
#include <mach/portmux.h>
+#include <sound/atmel-ac97c.h>
+
#include "../../mach-at32ap/clock.h"
#include "flash.h"
@@ -163,7 +165,7 @@ static void __init set_hw_addr(struct platform_device *pdev)
void __init setup_board(void)
{
- at32_map_usart(1, 0); /* USART 1: /dev/ttyS0, DB9 */
+ at32_map_usart(1, 0, 0); /* USART 1: /dev/ttyS0, DB9 */
at32_setup_serial_console(0);
}
@@ -233,7 +235,7 @@ static int __init hammerhead_init(void)
i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));
#ifdef CONFIG_BOARD_HAMMERHEAD_SND
- at32_add_device_ac97c(0, &ac97c_data);
+ at32_add_device_ac97c(0, &ac97c_data, AC97C_BOTH);
#endif
/* Select the Touchscreen interrupt pin mode */
diff --git a/arch/avr32/boards/merisc/Kconfig b/arch/avr32/boards/merisc/Kconfig
new file mode 100644
index 00000000000..7e043275d5a
--- /dev/null
+++ b/arch/avr32/boards/merisc/Kconfig
@@ -0,0 +1,5 @@
+# Merisc customization
+
+if BOARD_MERISC
+
+endif # BOARD_MERISC
diff --git a/arch/avr32/boards/merisc/Makefile b/arch/avr32/boards/merisc/Makefile
new file mode 100644
index 00000000000..d24c78729bd
--- /dev/null
+++ b/arch/avr32/boards/merisc/Makefile
@@ -0,0 +1 @@
+obj-y += setup.o flash.o display.o merisc_sysfs.o
diff --git a/arch/avr32/boards/merisc/display.c b/arch/avr32/boards/merisc/display.c
new file mode 100644
index 00000000000..85a543cd4ab
--- /dev/null
+++ b/arch/avr32/boards/merisc/display.c
@@ -0,0 +1,65 @@
+/*
+ * Display setup code for the Merisc board
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <video/atmel_lcdc.h>
+#include <asm/setup.h>
+#include <mach/board.h>
+#include "merisc.h"
+
+static struct fb_videomode merisc_fb_videomode[] = {
+ {
+ .refresh = 44,
+ .xres = 640,
+ .yres = 480,
+ .left_margin = 96,
+ .right_margin = 96,
+ .upper_margin = 34,
+ .lower_margin = 8,
+ .hsync_len = 64,
+ .vsync_len = 64,
+ .name = "640x480 @ 44",
+ .pixclock = KHZ2PICOS(25180),
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+};
+
+static struct fb_monspecs merisc_fb_monspecs = {
+ .manufacturer = "Kyo",
+ .monitor = "TCG075VG2AD",
+ .modedb = merisc_fb_videomode,
+ .modedb_len = ARRAY_SIZE(merisc_fb_videomode),
+ .hfmin = 30000,
+ .hfmax = 33333,
+ .vfmin = 60,
+ .vfmax = 90,
+ .dclkmax = 30000000,
+};
+
+struct atmel_lcdfb_info merisc_lcdc_data = {
+ .default_bpp = 24,
+ .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
+ .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT
+ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
+ | ATMEL_LCDC_MEMOR_BIG),
+ .default_monspecs = &merisc_fb_monspecs,
+ .guard_time = 2,
+};
+
+static int __init merisc_display_init(void)
+{
+ at32_add_device_lcdc(0, &merisc_lcdc_data, fbmem_start,
+ fbmem_size, 0);
+
+ return 0;
+}
+device_initcall(merisc_display_init);
diff --git a/arch/avr32/boards/merisc/flash.c b/arch/avr32/boards/merisc/flash.c
new file mode 100644
index 00000000000..8e856fd6f01
--- /dev/null
+++ b/arch/avr32/boards/merisc/flash.c
@@ -0,0 +1,139 @@
+/*
+ * Merisc board-specific flash initialization
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <mach/smc.h>
+
+/* Will be translated to units of 14.3 ns, rounded up */
+static struct smc_timing flash_timing __initdata = {
+ .ncs_read_setup = 1 * 14,
+ .nrd_setup = 5 * 14,
+ .ncs_write_setup = 1 * 14,
+ .nwe_setup = 2 * 14,
+
+ .ncs_read_pulse = 12 * 14,
+ .nrd_pulse = 7 * 14,
+ .ncs_write_pulse = 8 * 14,
+ .nwe_pulse = 4 * 14,
+
+ .read_cycle = 14 * 14,
+ .write_cycle = 10 * 14,
+};
+
+static struct smc_config flash_config __initdata = {
+ .bus_width = 2,
+ .nrd_controlled = 1,
+ .nwe_controlled = 1,
+ .byte_write = 1,
+ .tdf_cycles = 3,
+};
+
+static struct mtd_partition flash_0_parts[] = {
+ {
+ .name = "boot",
+ .offset = 0x00000000,
+ .size = 0x00060000,
+ .mask_flags = 0,
+ },
+ {
+ .name = "kernel",
+ .offset = 0x00060000,
+ .size = 0x00200000,
+ .mask_flags = 0,
+ },
+ {
+ .name = "root",
+ .offset = 0x00260000,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct mtd_partition flash_1_parts[] = {
+ {
+ .name = "2ndflash",
+ .offset = 0x00000000,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct physmap_flash_data flash_data[] = {
+ {
+ .width = 2,
+ .nr_parts = ARRAY_SIZE(flash_0_parts),
+ .parts = flash_0_parts,
+ },
+ {
+ .width = 2,
+ .nr_parts = ARRAY_SIZE(flash_1_parts),
+ .parts = flash_1_parts,
+ }
+};
+
+static struct resource flash_resource[] = {
+ {
+ .start = 0x00000000,
+ .end = 0x03ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x04000000,
+ .end = 0x07ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device flash_device[] = {
+ {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = &flash_resource[0],
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &flash_data[0],
+ },
+ },
+ {
+ .name = "physmap-flash",
+ .id = 1,
+ .resource = &flash_resource[1],
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &flash_data[1],
+ },
+ },
+};
+
+static int __init merisc_flash_init(void)
+{
+ int ret;
+ smc_set_timing(&flash_config, &flash_timing);
+
+ ret = smc_set_configuration(0, &flash_config);
+ if (ret < 0) {
+ printk(KERN_ERR "Merisc: failed to set NOR flash timing #0\n");
+ return ret;
+ }
+
+ ret = smc_set_configuration(4, &flash_config);
+ if (ret < 0) {
+ printk(KERN_ERR "Merisc: failed to set NOR flash timing #1\n");
+ return ret;
+ }
+
+ platform_device_register(&flash_device[0]);
+ platform_device_register(&flash_device[1]);
+ return 0;
+}
+device_initcall(merisc_flash_init);
diff --git a/arch/avr32/boards/merisc/merisc.h b/arch/avr32/boards/merisc/merisc.h
new file mode 100644
index 00000000000..50ffb2f3fcb
--- /dev/null
+++ b/arch/avr32/boards/merisc/merisc.h
@@ -0,0 +1,18 @@
+/*
+ * Merisc exports
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * 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_AVR32_BOARDS_MERISC_MERISC_H
+#define __ARCH_AVR32_BOARDS_MERISC_MERISC_H
+
+const char *merisc_revision(void);
+const char *merisc_model(void);
+
+extern struct class merisc_class;
+
+#endif /* __ARCH_AVR32_BOARDS_MERISC_MERISC_H */
diff --git a/arch/avr32/boards/merisc/merisc_sysfs.c b/arch/avr32/boards/merisc/merisc_sysfs.c
new file mode 100644
index 00000000000..df431fdba9a
--- /dev/null
+++ b/arch/avr32/boards/merisc/merisc_sysfs.c
@@ -0,0 +1,65 @@
+/*
+ * Merisc sysfs exports
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/timer.h>
+#include <linux/err.h>
+#include <linux/ctype.h>
+#include "merisc.h"
+
+static ssize_t merisc_model_show(struct class *class, char *buf)
+{
+ ssize_t ret = 0;
+
+ sprintf(buf, "%s\n", merisc_model());
+ ret = strlen(buf) + 1;
+
+ return ret;
+}
+
+static ssize_t merisc_revision_show(struct class *class, char *buf)
+{
+ ssize_t ret = 0;
+
+ sprintf(buf, "%s\n", merisc_revision());
+ ret = strlen(buf) + 1;
+
+ return ret;
+}
+
+static struct class_attribute merisc_class_attrs[] = {
+ __ATTR(model, S_IRUGO, merisc_model_show, NULL),
+ __ATTR(revision, S_IRUGO, merisc_revision_show, NULL),
+ __ATTR_NULL,
+};
+
+struct class merisc_class = {
+ .name = "merisc",
+ .owner = THIS_MODULE,
+ .class_attrs = merisc_class_attrs,
+};
+
+static int __init merisc_sysfs_init(void)
+{
+ int status;
+
+ status = class_register(&merisc_class);
+ if (status < 0)
+ return status;
+
+ return 0;
+}
+
+postcore_initcall(merisc_sysfs_init);
diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c
new file mode 100644
index 00000000000..20b300cf105
--- /dev/null
+++ b/arch/avr32/boards/merisc/setup.c
@@ -0,0 +1,297 @@
+/*
+ * Board-specific setup code for the Merisc
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/leds.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/irq.h>
+#include <linux/fb.h>
+#include <linux/atmel-mci.h>
+
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/gpio.h>
+
+#include <mach/at32ap700x.h>
+#include <mach/board.h>
+#include <mach/init.h>
+#include <mach/portmux.h>
+
+#include "merisc.h"
+
+/* Holds the autodetected board model and revision */
+static int merisc_board_id;
+
+/* Initialized by bootloader-specific startup code. */
+struct tag *bootloader_tags __initdata;
+
+/* Oscillator frequencies. These are board specific */
+unsigned long at32_board_osc_rates[3] = {
+ [0] = 32768, /* 32.768 kHz on RTC osc */
+ [1] = 20000000, /* 20 MHz on osc0 */
+ [2] = 12000000, /* 12 MHz on osc1 */
+};
+
+struct eth_addr {
+ u8 addr[6];
+};
+
+static struct eth_addr __initdata hw_addr[2];
+static struct eth_platform_data __initdata eth_data[2];
+
+static int ads7846_get_pendown_state_PB26(void)
+{
+ return !gpio_get_value(GPIO_PIN_PB(26));
+}
+
+static int ads7846_get_pendown_state_PB28(void)
+{
+ return !gpio_get_value(GPIO_PIN_PB(28));
+}
+
+static struct ads7846_platform_data __initdata ads7846_data = {
+ .model = 7846,
+ .vref_delay_usecs = 100,
+ .vref_mv = 0,
+ .keep_vref_on = 0,
+ .settle_delay_usecs = 150,
+ .penirq_recheck_delay_usecs = 1,
+ .x_plate_ohms = 800,
+ .debounce_rep = 4,
+ .debounce_max = 10,
+ .debounce_tol = 50,
+ .get_pendown_state = ads7846_get_pendown_state_PB26,
+ .filter_init = NULL,
+ .filter = NULL,
+ .filter_cleanup = NULL,
+};
+
+static struct spi_board_info __initdata spi0_board_info[] = {
+ {
+ .modalias = "ads7846",
+ .max_speed_hz = 3250000,
+ .chip_select = 0,
+ .bus_num = 0,
+ .platform_data = &ads7846_data,
+ .mode = SPI_MODE_0,
+ },
+};
+
+static struct mci_platform_data __initdata mci0_data = {
+ .slot[0] = {
+ .bus_width = 4,
+ .detect_pin = GPIO_PIN_PE(19),
+ .wp_pin = GPIO_PIN_PE(20),
+ },
+};
+
+static int __init parse_tag_ethernet(struct tag *tag)
+{
+ int i;
+
+ i = tag->u.ethernet.mac_index;
+ if (i < ARRAY_SIZE(hw_addr)) {
+ memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
+ sizeof(hw_addr[i].addr));
+ }
+
+ return 0;
+}
+__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
+
+static void __init set_hw_addr(struct platform_device *pdev)
+{
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ const u8 *addr;
+ void __iomem *regs;
+ struct clk *pclk;
+
+ if (!res)
+ return;
+
+ if (pdev->id >= ARRAY_SIZE(hw_addr))
+ return;
+
+ addr = hw_addr[pdev->id].addr;
+ if (!is_valid_ether_addr(addr))
+ return;
+
+ regs = (void __iomem __force *)res->start;
+ pclk = clk_get(&pdev->dev, "pclk");
+ if (!pclk)
+ return;
+
+ clk_enable(pclk);
+ __raw_writel((addr[3] << 24) | (addr[2] << 16)
+ | (addr[1] << 8) | addr[0], regs + 0x98);
+ __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
+ clk_disable(pclk);
+ clk_put(pclk);
+}
+
+static struct i2c_gpio_platform_data i2c_gpio_data = {
+ .sda_pin = GPIO_PIN_PA(6),
+ .scl_pin = GPIO_PIN_PA(7),
+ .sda_is_open_drain = 1,
+ .scl_is_open_drain = 1,
+ .udelay = 2,
+};
+
+static struct platform_device i2c_gpio_device = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &i2c_gpio_data,
+ },
+};
+
+static struct i2c_board_info __initdata i2c_info[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51)
+ },
+};
+
+#ifdef CONFIG_LEDS_ATMEL_PWM
+static struct gpio_led stk_pwm_led[] = {
+ {
+ .name = "backlight",
+ .gpio = 0, /* PWM channel 0 (LCD backlight) */
+ },
+};
+
+static struct gpio_led_platform_data stk_pwm_led_data = {
+ .num_leds = ARRAY_SIZE(stk_pwm_led),
+ .leds = stk_pwm_led,
+};
+
+static struct platform_device stk_pwm_led_dev = {
+ .name = "leds-atmel-pwm",
+ .id = -1,
+ .dev = {
+ .platform_data = &stk_pwm_led_data,
+ },
+};
+#endif
+
+const char *merisc_model(void)
+{
+ switch (merisc_board_id) {
+ case 0:
+ case 1:
+ return "500-01";
+ case 2:
+ return "BT";
+ default:
+ return "Unknown";
+ }
+}
+
+const char *merisc_revision(void)
+{
+ switch (merisc_board_id) {
+ case 0:
+ return "B";
+ case 1:
+ return "D";
+ case 2:
+ return "A";
+ default:
+ return "Unknown";
+ }
+}
+
+static void detect_merisc_board_id(void)
+{
+ /* Board ID pins MUST be set as input or the board may be damaged */
+ at32_select_gpio(GPIO_PIN_PA(24), AT32_GPIOF_PULLUP);
+ at32_select_gpio(GPIO_PIN_PA(25), AT32_GPIOF_PULLUP);
+ at32_select_gpio(GPIO_PIN_PA(26), AT32_GPIOF_PULLUP);
+ at32_select_gpio(GPIO_PIN_PA(27), AT32_GPIOF_PULLUP);
+
+ merisc_board_id = !gpio_get_value(GPIO_PIN_PA(24)) +
+ !gpio_get_value(GPIO_PIN_PA(25)) * 2 +
+ !gpio_get_value(GPIO_PIN_PA(26)) * 4 +
+ !gpio_get_value(GPIO_PIN_PA(27)) * 8;
+}
+
+void __init setup_board(void)
+{
+ at32_map_usart(0, 0, 0);
+ at32_map_usart(1, 1, 0);
+ at32_map_usart(3, 3, 0);
+ at32_setup_serial_console(1);
+}
+
+static int __init merisc_init(void)
+{
+ detect_merisc_board_id();
+
+ printk(KERN_NOTICE "BOARD: Merisc %s revision %s\n", merisc_model(),
+ merisc_revision());
+
+ /* Reserve pins for SDRAM */
+ at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL | (1 << 26));
+
+ if (merisc_board_id >= 1)
+ at32_map_usart(2, 2, 0);
+
+ at32_add_device_usart(0);
+ at32_add_device_usart(1);
+ if (merisc_board_id >= 1)
+ at32_add_device_usart(2);
+ at32_add_device_usart(3);
+ set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
+
+ /* ADS7846 PENIRQ */
+ if (merisc_board_id == 0) {
+ ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB26;
+ at32_select_periph(GPIO_PIOB_BASE, 1 << 26,
+ GPIO_PERIPH_A, AT32_GPIOF_PULLUP);
+ spi0_board_info[0].irq = AT32_EXTINT(1);
+ } else {
+ ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB28;
+ at32_select_periph(GPIO_PIOB_BASE, 1 << 28, GPIO_PERIPH_A,
+ AT32_GPIOF_PULLUP);
+ spi0_board_info[0].irq = AT32_EXTINT(3);
+ }
+
+ /* ADS7846 busy pin */
+ at32_select_gpio(GPIO_PIN_PA(4), AT32_GPIOF_PULLUP);
+
+ at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
+
+ at32_add_device_mci(0, &mci0_data);
+
+#ifdef CONFIG_LEDS_ATMEL_PWM
+ at32_add_device_pwm((1 << 0) | (1 << 2));
+ platform_device_register(&stk_pwm_led_dev);
+#else
+ at32_add_device_pwm((1 << 2));
+#endif
+
+ at32_select_gpio(i2c_gpio_data.sda_pin,
+ AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
+ at32_select_gpio(i2c_gpio_data.scl_pin,
+ AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
+ platform_device_register(&i2c_gpio_device);
+
+ i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));
+
+ return 0;
+}
+postcore_initcall(merisc_init);
diff --git a/arch/avr32/boards/mimc200/setup.c b/arch/avr32/boards/mimc200/setup.c
index 2b58d61f0af..c1b2175b4fe 100644
--- a/arch/avr32/boards/mimc200/setup.c
+++ b/arch/avr32/boards/mimc200/setup.c
@@ -175,10 +175,10 @@ static void __init set_hw_addr(struct platform_device *pdev)
void __init setup_board(void)
{
- at32_map_usart(0, 0); /* USART 0: /dev/ttyS0 (TTL --> Altera) */
- at32_map_usart(1, 1); /* USART 1: /dev/ttyS1 (RS232) */
- at32_map_usart(2, 2); /* USART 2: /dev/ttyS2 (RS485) */
- at32_map_usart(3, 3); /* USART 3: /dev/ttyS3 (RS422 Multidrop) */
+ at32_map_usart(0, 0, 0); /* USART 0: /dev/ttyS0 (TTL --> Altera) */
+ at32_map_usart(1, 1, 0); /* USART 1: /dev/ttyS1 (RS232) */
+ at32_map_usart(2, 2, 0); /* USART 2: /dev/ttyS2 (RS485) */
+ at32_map_usart(3, 3, 0); /* USART 3: /dev/ttyS3 (RS422 Multidrop) */
}
static struct i2c_gpio_platform_data i2c_gpio_data = {
diff --git a/arch/avr32/configs/merisc_defconfig b/arch/avr32/configs/merisc_defconfig
new file mode 100644
index 00000000000..41554db4877
--- /dev/null
+++ b/arch/avr32/configs/merisc_defconfig
@@ -0,0 +1,1237 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc1
+# Wed Mar 25 14:06:15 2009
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_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 is not set
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_CLK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=1
+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_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP700X=y
+CONFIG_CPU_AT32AP7000=y
+# CONFIG_BOARD_ATSTK1000 is not set
+# CONFIG_BOARD_ATNGW100 is not set
+# CONFIG_BOARD_HAMMERHEAD is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MIMC200 is not set
+CONFIG_BOARD_MERISC=y
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+CONFIG_AP700X_32_BIT_SMC=y
+# CONFIG_AP700X_16_BIT_SMC is not set
+# CONFIG_AP700X_8_BIT_SMC is not set
+CONFIG_LOAD_ADDRESS=0x10000000
+CONFIG_ENTRY_ADDRESS=0x90000000
+CONFIG_PHYS_OFFSET=0x10000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_QUICKLIST=y
+# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
+# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_OWNERSHIP_TRACE is not set
+# CONFIG_NMI_DEBUGGING is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_CMDLINE=""
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+# CONFIG_IP_PIMSM_V2 is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 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_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+# CONFIG_CAN_DEBUG_DEVICES is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER 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_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+CONFIG_MTD_ABSENT=y
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_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=y
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE 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_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_PWM=y
+# CONFIG_ATMEL_TCLIB is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+CONFIG_ATMEL_SSC=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT 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 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_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=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 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_WACOM_W8001 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_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_AT32AP700X_WDT is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_ATMEL=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# 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=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_ATMELMCI=y
+CONFIG_MMC_ATMELMCI_DMA=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_ATMEL_PWM=y
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+# 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=y
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_AT32AP700X is not set
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_DMATEST is not set
+CONFIG_UIO=y
+# CONFIG_UIO_PDRV is not set
+# CONFIG_UIO_PDRV_GENIRQ is not set
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 is not set
+# CONFIG_STAGING 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_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
+
+#
+# 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 is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 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=y
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/avr32/include/asm/ftrace.h b/arch/avr32/include/asm/ftrace.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/avr32/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/avr32/include/asm/hardirq.h b/arch/avr32/include/asm/hardirq.h
index 267354356f6..015bc75ea79 100644
--- a/arch/avr32/include/asm/hardirq.h
+++ b/arch/avr32/include/asm/hardirq.h
@@ -20,15 +20,4 @@ void ack_bad_irq(unsigned int irq);
#endif /* __ASSEMBLY__ */
-#define HARDIRQ_BITS 12
-
-/*
- * The hardirq mask has to be large enough to have
- * space for potentially all IRQ sources in the system
- * nesting on a single CPU:
- */
-#if (1 << HARDIRQ_BITS) < NR_IRQS
-# error HARDIRQ_BITS is too low!
-#endif
-
#endif /* __ASM_AVR32_HARDIRQ_H */
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index 3fbfd1e32a9..eb9d4dc2e86 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -26,6 +26,9 @@
#include <mach/portmux.h>
#include <mach/sram.h>
+#include <sound/atmel-abdac.h>
+#include <sound/atmel-ac97c.h>
+
#include <video/atmel_lcdc.h>
#include "clock.h"
@@ -57,26 +60,26 @@
* don't ... tc, smc, pio, rtc, watchdog, pwm, ps2, and more.
*/
#define DEFINE_DEV(_name, _id) \
-static u64 _name##_id##_dma_mask = DMA_32BIT_MASK; \
+static u64 _name##_id##_dma_mask = DMA_BIT_MASK(32); \
static struct platform_device _name##_id##_device = { \
.name = #_name, \
.id = _id, \
.dev = { \
.dma_mask = &_name##_id##_dma_mask, \
- .coherent_dma_mask = DMA_32BIT_MASK, \
+ .coherent_dma_mask = DMA_BIT_MASK(32), \
}, \
.resource = _name##_id##_resource, \
.num_resources = ARRAY_SIZE(_name##_id##_resource), \
}
#define DEFINE_DEV_DATA(_name, _id) \
-static u64 _name##_id##_dma_mask = DMA_32BIT_MASK; \
+static u64 _name##_id##_dma_mask = DMA_BIT_MASK(32); \
static struct platform_device _name##_id##_device = { \
.name = #_name, \
.id = _id, \
.dev = { \
.dma_mask = &_name##_id##_dma_mask, \
.platform_data = &_name##_id##_data, \
- .coherent_dma_mask = DMA_32BIT_MASK, \
+ .coherent_dma_mask = DMA_BIT_MASK(32), \
}, \
.resource = _name##_id##_resource, \
.num_resources = ARRAY_SIZE(_name##_id##_resource), \
@@ -963,56 +966,68 @@ static struct resource atmel_usart3_resource[] = {
DEFINE_DEV_DATA(atmel_usart, 3);
DEV_CLK(usart, atmel_usart3, pba, 6);
-static inline void configure_usart0_pins(void)
+static inline void configure_usart0_pins(int flags)
{
u32 pin_mask = (1 << 8) | (1 << 9); /* RXD & TXD */
+ if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 6);
+ if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 7);
+ if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 10);
select_peripheral(PIOA, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);
}
-static inline void configure_usart1_pins(void)
+static inline void configure_usart1_pins(int flags)
{
u32 pin_mask = (1 << 17) | (1 << 18); /* RXD & TXD */
+ if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 19);
+ if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 20);
+ if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 16);
select_peripheral(PIOA, pin_mask, PERIPH_A, AT32_GPIOF_PULLUP);
}
-static inline void configure_usart2_pins(void)
+static inline void configure_usart2_pins(int flags)
{
u32 pin_mask = (1 << 26) | (1 << 27); /* RXD & TXD */
+ if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 30);
+ if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 29);
+ if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 28);
select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);
}
-static inline void configure_usart3_pins(void)
+static inline void configure_usart3_pins(int flags)
{
u32 pin_mask = (1 << 18) | (1 << 17); /* RXD & TXD */
+ if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 16);
+ if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 15);
+ if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 19);
select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);
}
static struct platform_device *__initdata at32_usarts[4];
-void __init at32_map_usart(unsigned int hw_id, unsigned int line)
+void __init at32_map_usart(unsigned int hw_id, unsigned int line, int flags)
{
struct platform_device *pdev;
switch (hw_id) {
case 0:
pdev = &atmel_usart0_device;
- configure_usart0_pins();
+ configure_usart0_pins(flags);
break;
case 1:
pdev = &atmel_usart1_device;
- configure_usart1_pins();
+ configure_usart1_pins(flags);
break;
case 2:
pdev = &atmel_usart2_device;
- configure_usart2_pins();
+ configure_usart2_pins(flags);
break;
case 3:
pdev = &atmel_usart3_device;
- configure_usart3_pins();
+ configure_usart3_pins(flags);
break;
default:
return;
@@ -1753,7 +1768,7 @@ at32_add_device_usba(unsigned int id, struct usba_platform_data *data)
if (platform_device_add_data(pdev, data, sizeof(usba_data)))
goto out_free_pdev;
- if (data->vbus_pin >= 0)
+ if (gpio_is_valid(data->vbus_pin))
at32_select_gpio(data->vbus_pin, 0);
usba0_pclk.dev = &pdev->dev;
@@ -1980,11 +1995,14 @@ static struct clk atmel_ac97c0_pclk = {
};
struct platform_device *__init
-at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data)
+at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,
+ unsigned int flags)
{
- struct platform_device *pdev;
- struct ac97c_platform_data _data;
- u32 pin_mask;
+ struct platform_device *pdev;
+ struct dw_dma_slave *rx_dws;
+ struct dw_dma_slave *tx_dws;
+ struct ac97c_platform_data _data;
+ u32 pin_mask;
if (id != 0)
return NULL;
@@ -1995,37 +2013,52 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data)
if (platform_device_add_resources(pdev, atmel_ac97c0_resource,
ARRAY_SIZE(atmel_ac97c0_resource)))
- goto fail;
+ goto out_free_resources;
if (!data) {
data = &_data;
memset(data, 0, sizeof(struct ac97c_platform_data));
- data->reset_pin = GPIO_PIN_NONE;
+ data->reset_pin = -ENODEV;
}
- data->dma_rx_periph_id = 3;
- data->dma_tx_periph_id = 4;
- data->dma_controller_id = 0;
+ rx_dws = &data->rx_dws;
+ tx_dws = &data->tx_dws;
+
+ /* Check if DMA slave interface for capture should be configured. */
+ if (flags & AC97C_CAPTURE) {
+ rx_dws->dma_dev = &dw_dmac0_device.dev;
+ rx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;
+ rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3);
+ rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+ }
+
+ /* Check if DMA slave interface for playback should be configured. */
+ if (flags & AC97C_PLAYBACK) {
+ tx_dws->dma_dev = &dw_dmac0_device.dev;
+ tx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;
+ tx_dws->cfg_hi = DWC_CFGH_DST_PER(4);
+ tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+ }
if (platform_device_add_data(pdev, data,
sizeof(struct ac97c_platform_data)))
- goto fail;
+ goto out_free_resources;
- pin_mask = (1 << 20) | (1 << 21); /* SDO & SYNC */
- pin_mask |= (1 << 22) | (1 << 23); /* SCLK & SDI */
+ /* SDO | SYNC | SCLK | SDI */
+ pin_mask = (1 << 20) | (1 << 21) | (1 << 22) | (1 << 23);
select_peripheral(PIOB, pin_mask, PERIPH_B, 0);
- /* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */
- if (data->reset_pin != GPIO_PIN_NONE)
- at32_select_gpio(data->reset_pin, 0);
+ if (gpio_is_valid(data->reset_pin))
+ at32_select_gpio(data->reset_pin, AT32_GPIOF_OUTPUT
+ | AT32_GPIOF_HIGH);
atmel_ac97c0_pclk.dev = &pdev->dev;
platform_device_add(pdev);
return pdev;
-fail:
+out_free_resources:
platform_device_put(pdev);
return NULL;
}
@@ -2053,21 +2086,34 @@ static struct clk abdac0_sample_clk = {
.index = 6,
};
-struct platform_device *__init at32_add_device_abdac(unsigned int id)
+struct platform_device *__init
+at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data)
{
- struct platform_device *pdev;
- u32 pin_mask;
+ struct platform_device *pdev;
+ struct dw_dma_slave *dws;
+ u32 pin_mask;
- if (id != 0)
+ if (id != 0 || !data)
return NULL;
- pdev = platform_device_alloc("abdac", id);
+ pdev = platform_device_alloc("atmel_abdac", id);
if (!pdev)
return NULL;
if (platform_device_add_resources(pdev, abdac0_resource,
ARRAY_SIZE(abdac0_resource)))
- goto err_add_resources;
+ goto out_free_resources;
+
+ dws = &data->dws;
+
+ dws->dma_dev = &dw_dmac0_device.dev;
+ dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT;
+ dws->cfg_hi = DWC_CFGH_DST_PER(2);
+ dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+
+ if (platform_device_add_data(pdev, data,
+ sizeof(struct atmel_abdac_pdata)))
+ goto out_free_resources;
pin_mask = (1 << 20) | (1 << 22); /* DATA1 & DATAN1 */
pin_mask |= (1 << 21) | (1 << 23); /* DATA0 & DATAN0 */
@@ -2080,7 +2126,7 @@ struct platform_device *__init at32_add_device_abdac(unsigned int id)
platform_device_add(pdev);
return pdev;
-err_add_resources:
+out_free_resources:
platform_device_put(pdev);
return NULL;
}
diff --git a/arch/avr32/mach-at32ap/include/mach/at32ap700x.h b/arch/avr32/mach-at32ap/include/mach/at32ap700x.h
index 5c4c971eed8..b9222bf895b 100644
--- a/arch/avr32/mach-at32ap/include/mach/at32ap700x.h
+++ b/arch/avr32/mach-at32ap/include/mach/at32ap700x.h
@@ -171,25 +171,49 @@
ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) | \
ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
-#define ATMEL_LCDC_PRI_15B_DATA ( \
- ATMEL_LCDC(PC, DATA0) | ATMEL_LCDC(PC, DATA1) | \
+#define ATMEL_LCDC_PRI_18B_DATA ( \
ATMEL_LCDC(PC, DATA2) | ATMEL_LCDC(PC, DATA3) | \
ATMEL_LCDC(PC, DATA4) | ATMEL_LCDC(PC, DATA5) | \
- ATMEL_LCDC(PD, DATA8) | ATMEL_LCDC(PD, DATA9) | \
+ ATMEL_LCDC(PD, DATA6) | ATMEL_LCDC(PD, DATA7) | \
ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) | \
- ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA16) | \
- ATMEL_LCDC(PD, DATA17) | ATMEL_LCDC(PD, DATA18) | \
- ATMEL_LCDC(PD, DATA19) | ATMEL_LCDC(PD, DATA20))
+ ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA13) | \
+ ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) | \
+ ATMEL_LCDC(PD, DATA18) | ATMEL_LCDC(PD, DATA19) | \
+ ATMEL_LCDC(PD, DATA20) | ATMEL_LCDC(PD, DATA21) | \
+ ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
-#define ATMEL_LCDC_ALT_15B_DATA ( \
- ATMEL_LCDC(PE, DATA0) | ATMEL_LCDC(PE, DATA1) | \
+#define ATMEL_LCDC_ALT_18B_DATA ( \
ATMEL_LCDC(PE, DATA2) | ATMEL_LCDC(PE, DATA3) | \
ATMEL_LCDC(PE, DATA4) | ATMEL_LCDC(PC, DATA5) | \
- ATMEL_LCDC(PE, DATA8) | ATMEL_LCDC(PE, DATA9) | \
+ ATMEL_LCDC(PD, DATA6) | ATMEL_LCDC(PD, DATA7) | \
ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) | \
- ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PE, DATA16) | \
- ATMEL_LCDC(PE, DATA17) | ATMEL_LCDC(PE, DATA18) | \
- ATMEL_LCDC(PE, DATA19) | ATMEL_LCDC(PE, DATA20))
+ ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PD, DATA13) | \
+ ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) | \
+ ATMEL_LCDC(PE, DATA18) | ATMEL_LCDC(PE, DATA19) | \
+ ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) | \
+ ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
+
+#define ATMEL_LCDC_PRI_15B_DATA ( \
+ ATMEL_LCDC(PC, DATA3) | ATMEL_LCDC(PC, DATA4) | \
+ ATMEL_LCDC(PC, DATA5) | ATMEL_LCDC(PD, DATA6) | \
+ ATMEL_LCDC(PD, DATA7) | \
+ ATMEL_LCDC(PD, DATA11) | ATMEL_LCDC(PD, DATA12) | \
+ ATMEL_LCDC(PD, DATA13) | ATMEL_LCDC(PD, DATA14) | \
+ ATMEL_LCDC(PD, DATA15) | \
+ ATMEL_LCDC(PD, DATA19) | ATMEL_LCDC(PD, DATA20) | \
+ ATMEL_LCDC(PD, DATA21) | ATMEL_LCDC(PD, DATA22) | \
+ ATMEL_LCDC(PD, DATA23))
+
+#define ATMEL_LCDC_ALT_15B_DATA ( \
+ ATMEL_LCDC(PE, DATA3) | ATMEL_LCDC(PE, DATA4) | \
+ ATMEL_LCDC(PC, DATA5) | ATMEL_LCDC(PD, DATA6) | \
+ ATMEL_LCDC(PD, DATA7) | \
+ ATMEL_LCDC(PE, DATA11) | ATMEL_LCDC(PE, DATA12) | \
+ ATMEL_LCDC(PD, DATA13) | ATMEL_LCDC(PD, DATA14) | \
+ ATMEL_LCDC(PD, DATA15) | \
+ ATMEL_LCDC(PE, DATA19) | ATMEL_LCDC(PE, DATA20) | \
+ ATMEL_LCDC(PE, DATA21) | ATMEL_LCDC(PD, DATA22) | \
+ ATMEL_LCDC(PD, DATA23))
#define ATMEL_LCDC_PRI_CONTROL ( \
ATMEL_LCDC(PC, CC) | ATMEL_LCDC(PC, DVAL) | \
@@ -207,6 +231,10 @@
#define ATMEL_LCDC_ALT_24BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_24B_DATA)
+#define ATMEL_LCDC_PRI_18BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_18B_DATA)
+
+#define ATMEL_LCDC_ALT_18BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_18B_DATA)
+
#define ATMEL_LCDC_PRI_15BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_15B_DATA)
#define ATMEL_LCDC_ALT_15BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_15B_DATA)
diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h
index cff8e84f78f..0b816428189 100644
--- a/arch/avr32/mach-at32ap/include/mach/board.h
+++ b/arch/avr32/mach-at32ap/include/mach/board.h
@@ -13,7 +13,7 @@
* in this array is chip-dependent.
*/
extern unsigned long at32_board_osc_rates[];
-
+
/*
* This used to add essential system devices, but this is now done
* automatically. Please don't use it in new board code.
@@ -26,12 +26,17 @@ static inline void __deprecated at32_add_system_devices(void)
#define ATMEL_MAX_UART 4
extern struct platform_device *atmel_default_console_device;
+/* Flags for selecting USART extra pins */
+#define ATMEL_USART_RTS 0x01
+#define ATMEL_USART_CTS 0x02
+#define ATMEL_USART_CLK 0x03
+
struct atmel_uart_data {
short use_dma_tx; /* use transmit DMA? */
short use_dma_rx; /* use receive DMA? */
void __iomem *regs; /* virtual base address, if any */
};
-void at32_map_usart(unsigned int hw_id, unsigned int line);
+void at32_map_usart(unsigned int hw_id, unsigned int line, int flags);
struct platform_device *at32_add_device_usart(unsigned int id);
struct eth_platform_data {
@@ -88,16 +93,15 @@ struct mci_platform_data;
struct platform_device *
at32_add_device_mci(unsigned int id, struct mci_platform_data *data);
-struct ac97c_platform_data {
- unsigned short dma_rx_periph_id;
- unsigned short dma_tx_periph_id;
- unsigned short dma_controller_id;
- int reset_pin;
-};
+struct ac97c_platform_data;
+struct platform_device *
+at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,
+ unsigned int flags);
+
+struct atmel_abdac_pdata;
struct platform_device *
-at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data);
+at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data);
-struct platform_device *at32_add_device_abdac(unsigned int id);
struct platform_device *at32_add_device_psif(unsigned int id);
struct cf_platform_data {
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 0c1f86e3e44..3640cdc38aa 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -777,7 +777,7 @@ config CACHELINE_ALIGNED_L1
default n if BF54x
depends on !BF531
help
- If enabled, cacheline_anligned data is linked
+ If enabled, cacheline_aligned data is linked
into L1 data memory. (less latency)
config SYSCALL_TAB_L1
@@ -957,7 +957,7 @@ config MPU
memory they do not own. This comes at a performance penalty
and is recommended only for debugging.
-comment "Asynchonous Memory Configuration"
+comment "Asynchronous Memory Configuration"
menu "EBIU_AMGCTL Global Control"
config C_AMCKEN
@@ -989,7 +989,7 @@ config C_B3PEN
default n
choice
- prompt"Enable Asynchonous Memory Banks"
+ prompt "Enable Asynchronous Memory Banks"
default C_AMBEN_ALL
config C_AMBEN
diff --git a/arch/blackfin/include/asm/bfin5xx_spi.h b/arch/blackfin/include/asm/bfin5xx_spi.h
index 0292d58f936..aaeb4df10d5 100644
--- a/arch/blackfin/include/asm/bfin5xx_spi.h
+++ b/arch/blackfin/include/asm/bfin5xx_spi.h
@@ -11,6 +11,8 @@
#ifndef _SPI_CHANNEL_H_
#define _SPI_CHANNEL_H_
+#define MIN_SPI_BAUD_VAL 2
+
#define SPI_READ 0
#define SPI_WRITE 1
@@ -122,6 +124,9 @@ struct bfin5xx_spi_chip {
u8 bits_per_word;
u8 cs_change_per_word;
u16 cs_chg_udelay; /* Some devices require 16-bit delays */
+ u32 cs_gpio;
+ /* Value to send if no TX value is supplied, usually 0x0 or 0xFFFF */
+ u16 idle_tx_val;
};
#endif /* _SPI_CHANNEL_H_ */
diff --git a/arch/blackfin/include/asm/ftrace.h b/arch/blackfin/include/asm/ftrace.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/blackfin/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index f49427293ca..e040e03335e 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -337,7 +337,7 @@ int _access_ok(unsigned long addr, unsigned long size)
if (addr >= memory_mtd_end && (addr + size) <= physical_mem_end)
return 1;
-#ifdef CONFIG_ROMFS_MTD_FS
+#ifdef CONFIG_ROMFS_ON_MTD
/* For XIP, allow user space to use pointers within the ROMFS. */
if (addr >= memory_mtd_start && (addr + size) <= memory_mtd_end)
return 1;
diff --git a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
index e21c1c3e4ec..0fb2ce5d840 100644
--- a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
@@ -53,9 +53,9 @@
#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
@@ -87,6 +87,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
@@ -125,6 +126,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
@@ -140,6 +142,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART0_RX,
+ IRQ_UART0_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART0_TX,
CH_UART0_RX,
@@ -154,6 +157,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC02000,
IRQ_UART1_RX,
+ IRQ_UART1_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART1_TX,
CH_UART1_RX,
diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
index e8c41fd842b..a625659dd67 100644
--- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
@@ -53,9 +53,9 @@
#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
@@ -87,6 +87,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
@@ -125,6 +126,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
@@ -140,6 +142,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART0_RX,
+ IRQ_UART0_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART0_TX,
CH_UART0_RX,
@@ -154,6 +157,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC02000,
IRQ_UART1_RX,
+ IRQ_UART1_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART1_TX,
CH_UART1_RX,
@@ -167,29 +171,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
};
#define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-
-#ifdef CONFIG_SERIAL_BFIN_UART0
- peripheral_request(P_UART0_TX, DRIVER_NAME);
- peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART1
- peripheral_request(P_UART1_TX, DRIVER_NAME);
- peripheral_request(P_UART1_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- if (uart->cts_pin >= 0) {
- gpio_request(uart->cts_pin, DRIVER_NAME);
- gpio_direction_input(uart->cts_pin);
- }
-
- if (uart->rts_pin >= 0) {
- gpio_request(uart->rts_pin, DRIVER_NAME);
- gpio_direction_output(uart->rts_pin, 0);
- }
-#endif
-}
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 5f517f53b0f..a3789d7ccf8 100644
--- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
@@ -53,9 +53,9 @@
#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
@@ -74,6 +74,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
@@ -116,6 +117,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
@@ -130,6 +132,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART_RX,
+ IRQ_UART_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART_TX,
CH_UART_RX,
@@ -142,23 +145,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
};
#define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-
-#ifdef CONFIG_SERIAL_BFIN_UART0
- peripheral_request(P_UART0_TX, DRIVER_NAME);
- peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- if (uart->cts_pin >= 0) {
- gpio_request(uart->cts_pin, DRIVER_NAME);
- gpio_direction_input(uart->cts_pin);
- }
- if (uart->rts_pin >= 0) {
- gpio_request(uart->rts_pin, DRIVER_NAME);
- gpio_direction_output(uart->rts_pin, 0);
- }
-#endif
-}
diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
index 9e34700844a..b86662fb9de 100644
--- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
@@ -53,9 +53,9 @@
#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
@@ -87,6 +87,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
@@ -99,7 +100,6 @@ struct bfin_serial_port {
struct work_struct tx_dma_workqueue;
#endif
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- struct timer_list cts_timer;
int cts_pin;
int rts_pin;
#endif
@@ -125,6 +125,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
@@ -140,6 +141,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART0_RX,
+ IRQ_UART0_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART0_TX,
CH_UART0_RX,
@@ -154,6 +156,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC02000,
IRQ_UART1_RX,
+ IRQ_UART1_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART1_TX,
CH_UART1_RX,
@@ -167,29 +170,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
};
#define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-
-#ifdef CONFIG_SERIAL_BFIN_UART0
- peripheral_request(P_UART0_TX, DRIVER_NAME);
- peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART1
- peripheral_request(P_UART1_TX, DRIVER_NAME);
- peripheral_request(P_UART1_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- if (uart->cts_pin >= 0) {
- gpio_request(uart->cts_pin, DRIVER_NAME);
- gpio_direction_input(uart->cts_pin);
- }
-
- if (uart->rts_pin >= 0) {
- gpio_request(uart->rts_pin, DRIVER_NAME);
- gpio_direction_output(uart->rts_pin, 0);
- }
-#endif
-}
diff --git a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
index 3c2811ebecd..c536551eb4b 100644
--- a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
@@ -53,9 +53,9 @@
#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
@@ -87,6 +87,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
@@ -125,6 +126,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
@@ -140,6 +142,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART0_RX,
+ IRQ_UART0_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART0_TX,
CH_UART0_RX,
@@ -154,6 +157,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC02000,
IRQ_UART1_RX,
+ IRQ_UART1_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART1_TX,
CH_UART1_RX,
diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
index c05e79cba25..2d1b5fa3cca 100644
--- a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
@@ -46,41 +46,27 @@
#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
#define UART_SET_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER_SET),v)
-#define UART_CLEAR_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER_CLEAR),v)
+#define UART_CLEAR_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER_CLEAR),v)
#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
#define UART_PUT_LSR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LSR),v)
#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
#define UART_CLEAR_LSR(uart) bfin_write16(((uart)->port.membase + OFFSET_LSR), -1)
#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
#define UART_PUT_MCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_MCR),v)
+#define UART_CLEAR_SCTS(uart) bfin_write16(((uart)->port.membase + OFFSET_MSR),SCTS)
#define UART_SET_DLAB(uart) /* MMRs not muxed on BF54x */
#define UART_CLEAR_DLAB(uart) /* MMRs not muxed on BF54x */
#define UART_GET_CTS(x) (UART_GET_MSR(x) & CTS)
-#define UART_SET_RTS(x) (UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS))
-#define UART_CLEAR_RTS(x) (UART_PUT_MCR(x, UART_GET_MCR(x) & ~MRTS))
+#define UART_DISABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) & ~(ARTS|MRTS))
+#define UART_ENABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS | ARTS)
#define UART_ENABLE_INTS(x, v) UART_SET_IER(x, v)
#define UART_DISABLE_INTS(x) UART_CLEAR_IER(x, 0xF)
-#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART2_CTSRTS)
-# define CONFIG_SERIAL_BFIN_CTSRTS
-
-# ifndef CONFIG_UART0_CTS_PIN
-# define CONFIG_UART0_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART0_RTS_PIN
-# define CONFIG_UART0_RTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART2_CTS_PIN
-# define CONFIG_UART2_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART2_RTS_PIN
-# define CONFIG_UART2_RTS_PIN -1
-# endif
+#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) || \
+ defined(CONFIG_BFIN_UART2_CTSRTS) || defined(CONFIG_BFIN_UART3_CTSRTS)
+# define CONFIG_SERIAL_BFIN_HARD_CTSRTS
#endif
#define BFIN_UART_TX_FIFO_SIZE 2
@@ -91,6 +77,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
int tx_count;
@@ -101,23 +88,24 @@ struct bfin_serial_port {
unsigned int rx_dma_channel;
struct work_struct tx_dma_workqueue;
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- struct timer_list cts_timer;
- int cts_pin;
- int rts_pin;
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ int scts;
+ int cts_pin;
+ int rts_pin;
#endif
};
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- int uart_cts_pin;
- int uart_rts_pin;
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ int uart_cts_pin;
+ int uart_rts_pin;
#endif
};
@@ -126,13 +114,14 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART0_RX,
+ IRQ_UART0_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART0_TX,
CH_UART0_RX,
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- CONFIG_UART0_CTS_PIN,
- CONFIG_UART0_RTS_PIN,
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ 0,
+ 0,
#endif
},
#endif
@@ -140,13 +129,14 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC02000,
IRQ_UART1_RX,
+ IRQ_UART1_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART1_TX,
CH_UART1_RX,
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- 0,
- 0,
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ GPIO_PE10,
+ GPIO_PE9,
#endif
},
#endif
@@ -154,13 +144,14 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC02100,
IRQ_UART2_RX,
+ IRQ_UART2_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART2_TX,
CH_UART2_RX,
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- CONFIG_UART2_CTS_PIN,
- CONFIG_UART2_RTS_PIN,
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ 0,
+ 0,
#endif
},
#endif
@@ -168,61 +159,17 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC03100,
IRQ_UART3_RX,
+ IRQ_UART3_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART3_TX,
CH_UART3_RX,
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- 0,
- 0,
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ GPIO_PB3,
+ GPIO_PB2,
#endif
},
#endif
};
#define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-#ifdef CONFIG_SERIAL_BFIN_UART0
- peripheral_request(P_UART0_TX, DRIVER_NAME);
- peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART1
- peripheral_request(P_UART1_TX, DRIVER_NAME);
- peripheral_request(P_UART1_RX, DRIVER_NAME);
-
-#ifdef CONFIG_BFIN_UART1_CTSRTS
- peripheral_request(P_UART1_RTS, DRIVER_NAME);
- peripheral_request(P_UART1_CTS, DRIVER_NAME);
-#endif
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART2
- peripheral_request(P_UART2_TX, DRIVER_NAME);
- peripheral_request(P_UART2_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART3
- peripheral_request(P_UART3_TX, DRIVER_NAME);
- peripheral_request(P_UART3_RX, DRIVER_NAME);
-
-#ifdef CONFIG_BFIN_UART3_CTSRTS
- peripheral_request(P_UART3_RTS, DRIVER_NAME);
- peripheral_request(P_UART3_CTS, DRIVER_NAME);
-#endif
-#endif
- SSYNC();
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- if (uart->cts_pin >= 0) {
- gpio_request(uart->cts_pin, DRIVER_NAME);
- gpio_direction_input(uart->cts_pin);
- }
-
- if (uart->rts_pin >= 0) {
- gpio_request(uart->rts_pin, DRIVER_NAME);
- gpio_direction_output(uart->rts_pin, 0);
- }
-#endif
-}
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 ca8c5f64520..a1b50878553 100644
--- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
@@ -53,9 +53,9 @@
#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
@@ -74,6 +74,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
@@ -116,6 +117,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
@@ -130,6 +132,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART_RX,
+ IRQ_UART_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART_TX,
CH_UART_RX,
@@ -142,23 +145,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
};
#define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-
-#ifdef CONFIG_SERIAL_BFIN_UART0
- peripheral_request(P_UART0_TX, DRIVER_NAME);
- peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- if (uart->cts_pin >= 0) {
- gpio_request(uart->cts_pin, DRIVER_NAME);
- gpio_direction_input(uart->cts_pin);
- }
- if (uart->rts_pin >= 0) {
- gpio_request(uart->rts_pin, DRIVER_NAME);
- gpio_direction_output(uart->rts_pin, 0);
- }
-#endif
-}
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 3462245fe9f..7adac388a77 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -438,7 +438,7 @@ config ETRAX_SERIAL_PORT0_DMA1_IN
help
Enables the DMA1 input channel for ser0 (ttyS0).
If you do not enable DMA, an interrupt for each character will be
- used when receiveing data.
+ used when receiving data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
@@ -565,7 +565,7 @@ config ETRAX_SERIAL_PORT2_DMA7_IN
help
Enables the DMA7 input channel for ser2 (ttyS2).
If you do not enable DMA, an interrupt for each character will be
- used when receiveing data.
+ used when receiving data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
@@ -604,7 +604,7 @@ config ETRAX_SERIAL_PORT3_DMA3_IN
help
Enables the DMA3 input channel for ser3 (ttyS3).
If you do not enable DMA, an interrupt for each character will be
- used when receiveing data.
+ used when receiving data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c
index 65ed803dae6..5d75f77f9c7 100644
--- a/arch/cris/arch-v10/kernel/irq.c
+++ b/arch/cris/arch-v10/kernel/irq.c
@@ -132,7 +132,7 @@ static void end_crisv10_irq(unsigned int irq)
{
}
-static struct hw_interrupt_type crisv10_irq_type = {
+static struct irq_chip crisv10_irq_type = {
.typename = "CRISv10",
.startup = startup_crisv10_irq,
.shutdown = shutdown_crisv10_irq,
diff --git a/arch/cris/arch-v32/Kconfig b/arch/cris/arch-v32/Kconfig
index 005ed2b3f7f..21bbd93be34 100644
--- a/arch/cris/arch-v32/Kconfig
+++ b/arch/cris/arch-v32/Kconfig
@@ -28,7 +28,7 @@ config ETRAX_NBR_LED_GRP_ONE
help
Select this if you want one Ethernet LED group. This LED group
can be used for one or more Ethernet interfaces. However, it is
- recomended that each Ethernet interface use a dedicated LED group.
+ recommended that each Ethernet interface use a dedicated LED group.
config ETRAX_NBR_LED_GRP_TWO
bool "Use two LED groups"
diff --git a/arch/cris/arch-v32/boot/compressed/Makefile b/arch/cris/arch-v32/boot/compressed/Makefile
index 5a1b31c99ea..e176b8b69d9 100644
--- a/arch/cris/arch-v32/boot/compressed/Makefile
+++ b/arch/cris/arch-v32/boot/compressed/Makefile
@@ -2,9 +2,9 @@
# arch/cris/arch-v32/boot/compressed/Makefile
#
-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)/$(src)/decompress.lds
+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)/$(src)/decompress.lds
OBJECTS = $(obj)/head.o $(obj)/misc.o
OBJCOPYFLAGS = -O binary --remove-section=.bss
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig
index 7a64fcef9d0..b9e328e688b 100644
--- a/arch/cris/arch-v32/drivers/Kconfig
+++ b/arch/cris/arch-v32/drivers/Kconfig
@@ -342,7 +342,7 @@ config ETRAX_SERIAL_PORT4_DMA9_IN
help
Enables the DMA9 input channel for ser4 (ttyS4).
If you do not enable DMA, an interrupt for each character will be
- used when receiveing data.
+ used when receiving data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c
index 295131fee71..df3925cb1c7 100644
--- a/arch/cris/arch-v32/kernel/irq.c
+++ b/arch/cris/arch-v32/kernel/irq.c
@@ -333,7 +333,7 @@ void set_affinity_crisv32_irq(unsigned int irq, const struct cpumask *dest)
spin_unlock_irqrestore(&irq_lock, flags);
}
-static struct hw_interrupt_type crisv32_irq_type = {
+static struct irq_chip crisv32_irq_type = {
.typename = "CRISv32",
.startup = startup_crisv32_irq,
.shutdown = shutdown_crisv32_irq,
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index f59a973c97e..d2a3ff8c4d3 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -97,9 +97,9 @@ void __devinit smp_prepare_boot_cpu(void)
SUPP_BANK_SEL(2);
SUPP_REG_WR(RW_MM_TLB_PGD, pgd);
- cpu_set(0, cpu_online_map);
+ set_cpu_online(0, true);
cpu_set(0, phys_cpu_present_map);
- cpu_set(0, cpu_possible_map);
+ set_cpu_possible(0, true);
}
void __init smp_cpus_done(unsigned int max_cpus)
@@ -231,7 +231,7 @@ void flush_tlb_common(struct mm_struct* mm, struct vm_area_struct* vma, unsigned
cpumask_t cpu_mask;
spin_lock_irqsave(&tlbstate_lock, flags);
- cpu_mask = (mm == FLUSH_ALL ? CPU_MASK_ALL : mm->cpu_vm_mask);
+ cpu_mask = (mm == FLUSH_ALL ? cpu_all_mask : *mm_cpumask(mm));
cpu_clear(smp_processor_id(), cpu_mask);
flush_mm = mm;
flush_vma = vma;
@@ -251,8 +251,8 @@ void flush_tlb_mm(struct mm_struct *mm)
__flush_tlb_mm(mm);
flush_tlb_common(mm, FLUSH_ALL, 0);
/* No more mappings in other CPUs */
- cpus_clear(mm->cpu_vm_mask);
- cpu_set(smp_processor_id(), mm->cpu_vm_mask);
+ cpumask_clear(mm_cpumask(mm));
+ cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
}
void flush_tlb_page(struct vm_area_struct *vma,
diff --git a/arch/cris/arch-v32/mach-fs/Kconfig b/arch/cris/arch-v32/mach-fs/Kconfig
index f6d74475f1c..774de82abef 100644
--- a/arch/cris/arch-v32/mach-fs/Kconfig
+++ b/arch/cris/arch-v32/mach-fs/Kconfig
@@ -59,7 +59,7 @@ config ETRAX_SDRAM_GRP1_CONFIG
depends on ETRAX_ARCH_V32
default "0"
help
- SDRAM configuration for group 1. The defult value is 0
+ SDRAM configuration for group 1. The default value is 0
because group 1 is not used in the default configuration,
described in the help for SDRAM_GRP0_CONFIG.
diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c
index 55ade36fe8a..6779bcb28ab 100644
--- a/arch/cris/arch-v32/mm/tlb.c
+++ b/arch/cris/arch-v32/mm/tlb.c
@@ -185,7 +185,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
/* Make sure there is a MMU context. */
spin_lock(&mmu_context_lock);
get_mmu_context(next);
- cpu_set(cpu, next->cpu_vm_mask);
+ cpumask_set_cpu(cpu, mm_cpumask(next));
spin_unlock(&mmu_context_lock);
/*
diff --git a/arch/cris/include/asm/ftrace.h b/arch/cris/include/asm/ftrace.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/cris/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/cris/include/asm/ioctls.h b/arch/cris/include/asm/ioctls.h
index 4f4e52531fa..35bbc181598 100644
--- a/arch/cris/include/asm/ioctls.h
+++ b/arch/cris/include/asm/ioctls.h
@@ -74,8 +74,9 @@
#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */
#define FIOQSIZE 0x5460
-#define TIOCSERSETRS485 0x5461 /* enable rs-485 */
-#define TIOCSERWRRS485 0x5462 /* write rs-485 */
+#define TIOCSERSETRS485 0x5461 /* enable rs-485 (deprecated) */
+#define TIOCSERWRRS485 0x5462 /* write rs-485 */
+#define TIOCSRS485 0x5463 /* enable rs-485 */
/* Used for packet mode */
#define TIOCPKT_DATA 0
diff --git a/arch/cris/include/asm/rs485.h b/arch/cris/include/asm/rs485.h
index c331c51b0c2..ad40f9fbcb8 100644
--- a/arch/cris/include/asm/rs485.h
+++ b/arch/cris/include/asm/rs485.h
@@ -1,15 +1,13 @@
/* RS-485 structures */
-/* RS-485 support */
-/* Used with ioctl() TIOCSERSETRS485 */
+/* Used with ioctl() TIOCSERSETRS485 for backward compatibility!
+ * XXX: Do not use it for new code!
+ */
struct rs485_control {
unsigned short rts_on_send;
unsigned short rts_after_sent;
unsigned long delay_rts_before_send;
unsigned short enabled;
-#ifdef __KERNEL__
- int disable_serial_loopback;
-#endif
};
/* Used with ioctl() TIOCSERWRRS485 */
diff --git a/arch/cris/include/asm/termios.h b/arch/cris/include/asm/termios.h
index b0124e6c2e4..1265109f4ce 100644
--- a/arch/cris/include/asm/termios.h
+++ b/arch/cris/include/asm/termios.h
@@ -4,6 +4,7 @@
#include <asm/termbits.h>
#include <asm/ioctls.h>
#include <asm/rs485.h>
+#include <linux/serial.h>
struct winsize {
unsigned short ws_row;
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c
index 04d48dd91dd..b712f4934c4 100644
--- a/arch/cris/kernel/setup.c
+++ b/arch/cris/kernel/setup.c
@@ -166,7 +166,7 @@ void __init setup_arch(char **cmdline_p)
static void *c_start(struct seq_file *m, loff_t *pos)
{
- return *pos < NR_CPUS ? (void *)(int)(*pos + 1): NULL;
+ return *pos < nr_cpu_ids ? (void *)(int)(*pos + 1) : NULL;
}
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c
index 2fdd212eb25..514f46a4b23 100644
--- a/arch/cris/mm/init.c
+++ b/arch/cris/mm/init.c
@@ -25,8 +25,7 @@ mem_init(void)
int codesize, reservedpages, datasize, initsize;
unsigned long tmp;
- if(!mem_map)
- BUG();
+ BUG_ON(!mem_map);
/* max/min_low_pfn was set by setup.c
* now we just copy it to some other necessary places...
diff --git a/include/asm-frv/Kbuild b/arch/frv/include/asm/Kbuild
index 0f8956def73..0f8956def73 100644
--- a/include/asm-frv/Kbuild
+++ b/arch/frv/include/asm/Kbuild
diff --git a/include/asm-frv/atomic.h b/arch/frv/include/asm/atomic.h
index 296c35cfb20..296c35cfb20 100644
--- a/include/asm-frv/atomic.h
+++ b/arch/frv/include/asm/atomic.h
diff --git a/include/asm-frv/auxvec.h b/arch/frv/include/asm/auxvec.h
index 07710778fa1..07710778fa1 100644
--- a/include/asm-frv/auxvec.h
+++ b/arch/frv/include/asm/auxvec.h
diff --git a/include/asm-frv/ax88796.h b/arch/frv/include/asm/ax88796.h
index 637e980393c..637e980393c 100644
--- a/include/asm-frv/ax88796.h
+++ b/arch/frv/include/asm/ax88796.h
diff --git a/include/asm-frv/bitops.h b/arch/frv/include/asm/bitops.h
index 287f6f697ce..287f6f697ce 100644
--- a/include/asm-frv/bitops.h
+++ b/arch/frv/include/asm/bitops.h
diff --git a/include/asm-frv/bug.h b/arch/frv/include/asm/bug.h
index 6b1b44d7102..6b1b44d7102 100644
--- a/include/asm-frv/bug.h
+++ b/arch/frv/include/asm/bug.h
diff --git a/include/asm-frv/bugs.h b/arch/frv/include/asm/bugs.h
index f2382be2b46..f2382be2b46 100644
--- a/include/asm-frv/bugs.h
+++ b/arch/frv/include/asm/bugs.h
diff --git a/include/asm-frv/busctl-regs.h b/arch/frv/include/asm/busctl-regs.h
index bb0ff4816e2..bb0ff4816e2 100644
--- a/include/asm-frv/busctl-regs.h
+++ b/arch/frv/include/asm/busctl-regs.h
diff --git a/include/asm-frv/byteorder.h b/arch/frv/include/asm/byteorder.h
index f29b7593e08..f29b7593e08 100644
--- a/include/asm-frv/byteorder.h
+++ b/arch/frv/include/asm/byteorder.h
diff --git a/include/asm-frv/cache.h b/arch/frv/include/asm/cache.h
index 2797163b8f4..2797163b8f4 100644
--- a/include/asm-frv/cache.h
+++ b/arch/frv/include/asm/cache.h
diff --git a/include/asm-frv/cacheflush.h b/arch/frv/include/asm/cacheflush.h
index 432a69e7f3d..432a69e7f3d 100644
--- a/include/asm-frv/cacheflush.h
+++ b/arch/frv/include/asm/cacheflush.h
diff --git a/include/asm-frv/checksum.h b/arch/frv/include/asm/checksum.h
index 269da09ff63..269da09ff63 100644
--- a/include/asm-frv/checksum.h
+++ b/arch/frv/include/asm/checksum.h
diff --git a/include/asm-frv/cpu-irqs.h b/arch/frv/include/asm/cpu-irqs.h
index 478f3498fcf..478f3498fcf 100644
--- a/include/asm-frv/cpu-irqs.h
+++ b/arch/frv/include/asm/cpu-irqs.h
diff --git a/include/asm-frv/cpumask.h b/arch/frv/include/asm/cpumask.h
index d999c20c84d..d999c20c84d 100644
--- a/include/asm-frv/cpumask.h
+++ b/arch/frv/include/asm/cpumask.h
diff --git a/include/asm-frv/cputime.h b/arch/frv/include/asm/cputime.h
index f6c373ad2b8..f6c373ad2b8 100644
--- a/include/asm-frv/cputime.h
+++ b/arch/frv/include/asm/cputime.h
diff --git a/include/asm-frv/current.h b/arch/frv/include/asm/current.h
index 86b027491b0..86b027491b0 100644
--- a/include/asm-frv/current.h
+++ b/arch/frv/include/asm/current.h
diff --git a/include/asm-frv/delay.h b/arch/frv/include/asm/delay.h
index 597b4ebf03b..597b4ebf03b 100644
--- a/include/asm-frv/delay.h
+++ b/arch/frv/include/asm/delay.h
diff --git a/include/asm-frv/device.h b/arch/frv/include/asm/device.h
index d8f9872b0e2..d8f9872b0e2 100644
--- a/include/asm-frv/device.h
+++ b/arch/frv/include/asm/device.h
diff --git a/include/asm-frv/div64.h b/arch/frv/include/asm/div64.h
index 6cd978cefb2..6cd978cefb2 100644
--- a/include/asm-frv/div64.h
+++ b/arch/frv/include/asm/div64.h
diff --git a/include/asm-frv/dm9000.h b/arch/frv/include/asm/dm9000.h
index f6f48fd9ec6..f6f48fd9ec6 100644
--- a/include/asm-frv/dm9000.h
+++ b/arch/frv/include/asm/dm9000.h
diff --git a/include/asm-frv/dma-mapping.h b/arch/frv/include/asm/dma-mapping.h
index b2898877c07..b2898877c07 100644
--- a/include/asm-frv/dma-mapping.h
+++ b/arch/frv/include/asm/dma-mapping.h
diff --git a/include/asm-frv/dma.h b/arch/frv/include/asm/dma.h
index 683c47d48a5..683c47d48a5 100644
--- a/include/asm-frv/dma.h
+++ b/arch/frv/include/asm/dma.h
diff --git a/include/asm-frv/elf.h b/arch/frv/include/asm/elf.h
index 7279ec07d62..7279ec07d62 100644
--- a/include/asm-frv/elf.h
+++ b/arch/frv/include/asm/elf.h
diff --git a/include/asm-frv/emergency-restart.h b/arch/frv/include/asm/emergency-restart.h
index 108d8c48e42..108d8c48e42 100644
--- a/include/asm-frv/emergency-restart.h
+++ b/arch/frv/include/asm/emergency-restart.h
diff --git a/include/asm-frv/errno.h b/arch/frv/include/asm/errno.h
index d010795ceef..d010795ceef 100644
--- a/include/asm-frv/errno.h
+++ b/arch/frv/include/asm/errno.h
diff --git a/include/asm-frv/fb.h b/arch/frv/include/asm/fb.h
index c7df3803099..c7df3803099 100644
--- a/include/asm-frv/fb.h
+++ b/arch/frv/include/asm/fb.h
diff --git a/include/asm-frv/fcntl.h b/arch/frv/include/asm/fcntl.h
index 46ab12db573..46ab12db573 100644
--- a/include/asm-frv/fcntl.h
+++ b/arch/frv/include/asm/fcntl.h
diff --git a/include/asm-frv/fpu.h b/arch/frv/include/asm/fpu.h
index d73c60b5664..d73c60b5664 100644
--- a/include/asm-frv/fpu.h
+++ b/arch/frv/include/asm/fpu.h
diff --git a/arch/frv/include/asm/ftrace.h b/arch/frv/include/asm/ftrace.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/frv/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/include/asm-frv/futex.h b/arch/frv/include/asm/futex.h
index 08b3d1da358..08b3d1da358 100644
--- a/include/asm-frv/futex.h
+++ b/arch/frv/include/asm/futex.h
diff --git a/include/asm-frv/gdb-stub.h b/arch/frv/include/asm/gdb-stub.h
index 24f9738670b..24f9738670b 100644
--- a/include/asm-frv/gdb-stub.h
+++ b/arch/frv/include/asm/gdb-stub.h
diff --git a/include/asm-frv/gpio-regs.h b/arch/frv/include/asm/gpio-regs.h
index 9edf5d5d4d3..9edf5d5d4d3 100644
--- a/include/asm-frv/gpio-regs.h
+++ b/arch/frv/include/asm/gpio-regs.h
diff --git a/include/asm-frv/hardirq.h b/arch/frv/include/asm/hardirq.h
index fc47515822a..fc47515822a 100644
--- a/include/asm-frv/hardirq.h
+++ b/arch/frv/include/asm/hardirq.h
diff --git a/include/asm-frv/highmem.h b/arch/frv/include/asm/highmem.h
index 68e4677fb9e..68e4677fb9e 100644
--- a/include/asm-frv/highmem.h
+++ b/arch/frv/include/asm/highmem.h
diff --git a/include/asm-frv/hw_irq.h b/arch/frv/include/asm/hw_irq.h
index 522ad37923d..522ad37923d 100644
--- a/include/asm-frv/hw_irq.h
+++ b/arch/frv/include/asm/hw_irq.h
diff --git a/include/asm-frv/init.h b/arch/frv/include/asm/init.h
index 8b15838de21..8b15838de21 100644
--- a/include/asm-frv/init.h
+++ b/arch/frv/include/asm/init.h
diff --git a/include/asm-frv/io.h b/arch/frv/include/asm/io.h
index ca7475e73b5..ca7475e73b5 100644
--- a/include/asm-frv/io.h
+++ b/arch/frv/include/asm/io.h
diff --git a/include/asm-frv/ioctl.h b/arch/frv/include/asm/ioctl.h
index b279fe06dfe..b279fe06dfe 100644
--- a/include/asm-frv/ioctl.h
+++ b/arch/frv/include/asm/ioctl.h
diff --git a/include/asm-frv/ioctls.h b/arch/frv/include/asm/ioctls.h
index d0c30e31fbd..d0c30e31fbd 100644
--- a/include/asm-frv/ioctls.h
+++ b/arch/frv/include/asm/ioctls.h
diff --git a/include/asm-frv/ipcbuf.h b/arch/frv/include/asm/ipcbuf.h
index b546f67e455..b546f67e455 100644
--- a/include/asm-frv/ipcbuf.h
+++ b/arch/frv/include/asm/ipcbuf.h
diff --git a/include/asm-frv/irc-regs.h b/arch/frv/include/asm/irc-regs.h
index afa30aeacc8..afa30aeacc8 100644
--- a/include/asm-frv/irc-regs.h
+++ b/arch/frv/include/asm/irc-regs.h
diff --git a/include/asm-frv/irq.h b/arch/frv/include/asm/irq.h
index 3a66ebd754b..3a66ebd754b 100644
--- a/include/asm-frv/irq.h
+++ b/arch/frv/include/asm/irq.h
diff --git a/include/asm-frv/irq_regs.h b/arch/frv/include/asm/irq_regs.h
index d22e83289ad..d22e83289ad 100644
--- a/include/asm-frv/irq_regs.h
+++ b/arch/frv/include/asm/irq_regs.h
diff --git a/include/asm-frv/kdebug.h b/arch/frv/include/asm/kdebug.h
index 6ece1b03766..6ece1b03766 100644
--- a/include/asm-frv/kdebug.h
+++ b/arch/frv/include/asm/kdebug.h
diff --git a/include/asm-frv/kmap_types.h b/arch/frv/include/asm/kmap_types.h
index f8e16b2a580..f8e16b2a580 100644
--- a/include/asm-frv/kmap_types.h
+++ b/arch/frv/include/asm/kmap_types.h
diff --git a/include/asm-frv/linkage.h b/arch/frv/include/asm/linkage.h
index 636c1bced7d..636c1bced7d 100644
--- a/include/asm-frv/linkage.h
+++ b/arch/frv/include/asm/linkage.h
diff --git a/include/asm-frv/local.h b/arch/frv/include/asm/local.h
index c27bdf04630..c27bdf04630 100644
--- a/include/asm-frv/local.h
+++ b/arch/frv/include/asm/local.h
diff --git a/include/asm-frv/math-emu.h b/arch/frv/include/asm/math-emu.h
index 0c8f731b218..0c8f731b218 100644
--- a/include/asm-frv/math-emu.h
+++ b/arch/frv/include/asm/math-emu.h
diff --git a/include/asm-frv/mb-regs.h b/arch/frv/include/asm/mb-regs.h
index 219e5f926f1..219e5f926f1 100644
--- a/include/asm-frv/mb-regs.h
+++ b/arch/frv/include/asm/mb-regs.h
diff --git a/include/asm-frv/mb86943a.h b/arch/frv/include/asm/mb86943a.h
index e87ef924bfb..e87ef924bfb 100644
--- a/include/asm-frv/mb86943a.h
+++ b/arch/frv/include/asm/mb86943a.h
diff --git a/include/asm-frv/mb93091-fpga-irqs.h b/arch/frv/include/asm/mb93091-fpga-irqs.h
index 19778c5ba9d..19778c5ba9d 100644
--- a/include/asm-frv/mb93091-fpga-irqs.h
+++ b/arch/frv/include/asm/mb93091-fpga-irqs.h
diff --git a/include/asm-frv/mb93093-fpga-irqs.h b/arch/frv/include/asm/mb93093-fpga-irqs.h
index 590266b1a6d..590266b1a6d 100644
--- a/include/asm-frv/mb93093-fpga-irqs.h
+++ b/arch/frv/include/asm/mb93093-fpga-irqs.h
diff --git a/include/asm-frv/mb93493-irqs.h b/arch/frv/include/asm/mb93493-irqs.h
index 82c7aeddd33..82c7aeddd33 100644
--- a/include/asm-frv/mb93493-irqs.h
+++ b/arch/frv/include/asm/mb93493-irqs.h
diff --git a/include/asm-frv/mb93493-regs.h b/arch/frv/include/asm/mb93493-regs.h
index 8a1f6aac8cf..8a1f6aac8cf 100644
--- a/include/asm-frv/mb93493-regs.h
+++ b/arch/frv/include/asm/mb93493-regs.h
diff --git a/include/asm-frv/mc146818rtc.h b/arch/frv/include/asm/mc146818rtc.h
index 90dfb7a633d..90dfb7a633d 100644
--- a/include/asm-frv/mc146818rtc.h
+++ b/arch/frv/include/asm/mc146818rtc.h
diff --git a/include/asm-frv/mem-layout.h b/arch/frv/include/asm/mem-layout.h
index 2947764fc0e..2947764fc0e 100644
--- a/include/asm-frv/mem-layout.h
+++ b/arch/frv/include/asm/mem-layout.h
diff --git a/include/asm-frv/mman.h b/arch/frv/include/asm/mman.h
index b4371e92868..b4371e92868 100644
--- a/include/asm-frv/mman.h
+++ b/arch/frv/include/asm/mman.h
diff --git a/include/asm-frv/mmu.h b/arch/frv/include/asm/mmu.h
index 86ca0e86e7d..86ca0e86e7d 100644
--- a/include/asm-frv/mmu.h
+++ b/arch/frv/include/asm/mmu.h
diff --git a/include/asm-frv/mmu_context.h b/arch/frv/include/asm/mmu_context.h
index c7daa395156..c7daa395156 100644
--- a/include/asm-frv/mmu_context.h
+++ b/arch/frv/include/asm/mmu_context.h
diff --git a/include/asm-frv/module.h b/arch/frv/include/asm/module.h
index 3d5c6360289..3d5c6360289 100644
--- a/include/asm-frv/module.h
+++ b/arch/frv/include/asm/module.h
diff --git a/include/asm-frv/msgbuf.h b/arch/frv/include/asm/msgbuf.h
index 97ceb55a06f..97ceb55a06f 100644
--- a/include/asm-frv/msgbuf.h
+++ b/arch/frv/include/asm/msgbuf.h
diff --git a/include/asm-frv/mutex.h b/arch/frv/include/asm/mutex.h
index 458c1f7fbc1..458c1f7fbc1 100644
--- a/include/asm-frv/mutex.h
+++ b/arch/frv/include/asm/mutex.h
diff --git a/include/asm-frv/page.h b/arch/frv/include/asm/page.h
index bd9c220094c..bd9c220094c 100644
--- a/include/asm-frv/page.h
+++ b/arch/frv/include/asm/page.h
diff --git a/include/asm-frv/param.h b/arch/frv/include/asm/param.h
index 6859dd503ed..6859dd503ed 100644
--- a/include/asm-frv/param.h
+++ b/arch/frv/include/asm/param.h
diff --git a/include/asm-frv/pci.h b/arch/frv/include/asm/pci.h
index 585d9b49949..585d9b49949 100644
--- a/include/asm-frv/pci.h
+++ b/arch/frv/include/asm/pci.h
diff --git a/include/asm-frv/percpu.h b/arch/frv/include/asm/percpu.h
index 2cad3f874de..2cad3f874de 100644
--- a/include/asm-frv/percpu.h
+++ b/arch/frv/include/asm/percpu.h
diff --git a/include/asm-frv/pgalloc.h b/arch/frv/include/asm/pgalloc.h
index 971e6addb00..971e6addb00 100644
--- a/include/asm-frv/pgalloc.h
+++ b/arch/frv/include/asm/pgalloc.h
diff --git a/include/asm-frv/pgtable.h b/arch/frv/include/asm/pgtable.h
index e16fdb1f4f4..33233011b1c 100644
--- a/include/asm-frv/pgtable.h
+++ b/arch/frv/include/asm/pgtable.h
@@ -71,10 +71,8 @@ static inline int pte_file(pte_t pte) { return 0; }
#define swapper_pg_dir ((pgd_t *) NULL)
#define pgtable_cache_init() do {} while (0)
-#define arch_enter_lazy_mmu_mode() do {} while (0)
-#define arch_leave_lazy_mmu_mode() do {} while (0)
-#define arch_enter_lazy_cpu_mode() do {} while (0)
-#define arch_leave_lazy_cpu_mode() do {} while (0)
+
+#include <asm-generic/pgtable.h>
#else /* !CONFIG_MMU */
/*****************************************************************************/
diff --git a/include/asm-frv/poll.h b/arch/frv/include/asm/poll.h
index 0d01479ccc5..0d01479ccc5 100644
--- a/include/asm-frv/poll.h
+++ b/arch/frv/include/asm/poll.h
diff --git a/include/asm-frv/posix_types.h b/arch/frv/include/asm/posix_types.h
index a9f1f5be063..a9f1f5be063 100644
--- a/include/asm-frv/posix_types.h
+++ b/arch/frv/include/asm/posix_types.h
diff --git a/include/asm-frv/processor.h b/arch/frv/include/asm/processor.h
index 3744f2e47f4..3744f2e47f4 100644
--- a/include/asm-frv/processor.h
+++ b/arch/frv/include/asm/processor.h
diff --git a/include/asm-frv/ptrace.h b/arch/frv/include/asm/ptrace.h
index cf6934012b6..cf6934012b6 100644
--- a/include/asm-frv/ptrace.h
+++ b/arch/frv/include/asm/ptrace.h
diff --git a/include/asm-frv/registers.h b/arch/frv/include/asm/registers.h
index 9666119fcf6..9666119fcf6 100644
--- a/include/asm-frv/registers.h
+++ b/arch/frv/include/asm/registers.h
diff --git a/include/asm-frv/resource.h b/arch/frv/include/asm/resource.h
index 5fc60548fd0..5fc60548fd0 100644
--- a/include/asm-frv/resource.h
+++ b/arch/frv/include/asm/resource.h
diff --git a/include/asm-frv/scatterlist.h b/arch/frv/include/asm/scatterlist.h
index 4bca8a28546..4bca8a28546 100644
--- a/include/asm-frv/scatterlist.h
+++ b/arch/frv/include/asm/scatterlist.h
diff --git a/include/asm-frv/sections.h b/arch/frv/include/asm/sections.h
index 17d0fb171bb..17d0fb171bb 100644
--- a/include/asm-frv/sections.h
+++ b/arch/frv/include/asm/sections.h
diff --git a/include/asm-frv/segment.h b/arch/frv/include/asm/segment.h
index e3616a6f941..e3616a6f941 100644
--- a/include/asm-frv/segment.h
+++ b/arch/frv/include/asm/segment.h
diff --git a/include/asm-frv/sembuf.h b/arch/frv/include/asm/sembuf.h
index 164b12786d6..164b12786d6 100644
--- a/include/asm-frv/sembuf.h
+++ b/arch/frv/include/asm/sembuf.h
diff --git a/include/asm-frv/serial-regs.h b/arch/frv/include/asm/serial-regs.h
index e1286bda00e..e1286bda00e 100644
--- a/include/asm-frv/serial-regs.h
+++ b/arch/frv/include/asm/serial-regs.h
diff --git a/include/asm-frv/serial.h b/arch/frv/include/asm/serial.h
index dbb82599868..dbb82599868 100644
--- a/include/asm-frv/serial.h
+++ b/arch/frv/include/asm/serial.h
diff --git a/include/asm-frv/setup.h b/arch/frv/include/asm/setup.h
index afd787ceede..afd787ceede 100644
--- a/include/asm-frv/setup.h
+++ b/arch/frv/include/asm/setup.h
diff --git a/include/asm-frv/shmbuf.h b/arch/frv/include/asm/shmbuf.h
index 4c6e711a477..4c6e711a477 100644
--- a/include/asm-frv/shmbuf.h
+++ b/arch/frv/include/asm/shmbuf.h
diff --git a/include/asm-frv/shmparam.h b/arch/frv/include/asm/shmparam.h
index ab711009cfa..ab711009cfa 100644
--- a/include/asm-frv/shmparam.h
+++ b/arch/frv/include/asm/shmparam.h
diff --git a/include/asm-frv/sigcontext.h b/arch/frv/include/asm/sigcontext.h
index 3b263f3cc96..3b263f3cc96 100644
--- a/include/asm-frv/sigcontext.h
+++ b/arch/frv/include/asm/sigcontext.h
diff --git a/include/asm-frv/siginfo.h b/arch/frv/include/asm/siginfo.h
index d3fd1ca4565..d3fd1ca4565 100644
--- a/include/asm-frv/siginfo.h
+++ b/arch/frv/include/asm/siginfo.h
diff --git a/include/asm-frv/signal.h b/arch/frv/include/asm/signal.h
index 2079197d483..2079197d483 100644
--- a/include/asm-frv/signal.h
+++ b/arch/frv/include/asm/signal.h
diff --git a/include/asm-frv/smp.h b/arch/frv/include/asm/smp.h
index 38349ec8b61..38349ec8b61 100644
--- a/include/asm-frv/smp.h
+++ b/arch/frv/include/asm/smp.h
diff --git a/include/asm-frv/socket.h b/arch/frv/include/asm/socket.h
index 57c3d4054e8..57c3d4054e8 100644
--- a/include/asm-frv/socket.h
+++ b/arch/frv/include/asm/socket.h
diff --git a/include/asm-frv/sockios.h b/arch/frv/include/asm/sockios.h
index 5dbdd13e6de..5dbdd13e6de 100644
--- a/include/asm-frv/sockios.h
+++ b/arch/frv/include/asm/sockios.h
diff --git a/include/asm-frv/spinlock.h b/arch/frv/include/asm/spinlock.h
index fe385f45d1f..fe385f45d1f 100644
--- a/include/asm-frv/spinlock.h
+++ b/arch/frv/include/asm/spinlock.h
diff --git a/include/asm-frv/spr-regs.h b/arch/frv/include/asm/spr-regs.h
index 01e6af5e99b..01e6af5e99b 100644
--- a/include/asm-frv/spr-regs.h
+++ b/arch/frv/include/asm/spr-regs.h
diff --git a/include/asm-frv/stat.h b/arch/frv/include/asm/stat.h
index ce56de9b37b..ce56de9b37b 100644
--- a/include/asm-frv/stat.h
+++ b/arch/frv/include/asm/stat.h
diff --git a/include/asm-frv/statfs.h b/arch/frv/include/asm/statfs.h
index 741f586045b..741f586045b 100644
--- a/include/asm-frv/statfs.h
+++ b/arch/frv/include/asm/statfs.h
diff --git a/include/asm-frv/string.h b/arch/frv/include/asm/string.h
index 5ed310f64b7..5ed310f64b7 100644
--- a/include/asm-frv/string.h
+++ b/arch/frv/include/asm/string.h
diff --git a/include/asm-frv/suspend.h b/arch/frv/include/asm/suspend.h
index 5fa7b5a6ee4..5fa7b5a6ee4 100644
--- a/include/asm-frv/suspend.h
+++ b/arch/frv/include/asm/suspend.h
diff --git a/include/asm-frv/swab.h b/arch/frv/include/asm/swab.h
index f305834b479..f305834b479 100644
--- a/include/asm-frv/swab.h
+++ b/arch/frv/include/asm/swab.h
diff --git a/include/asm-frv/system.h b/arch/frv/include/asm/system.h
index 7742ec000cc..7742ec000cc 100644
--- a/include/asm-frv/system.h
+++ b/arch/frv/include/asm/system.h
diff --git a/include/asm-frv/termbits.h b/arch/frv/include/asm/termbits.h
index 5568492b508..5568492b508 100644
--- a/include/asm-frv/termbits.h
+++ b/arch/frv/include/asm/termbits.h
diff --git a/include/asm-frv/termios.h b/arch/frv/include/asm/termios.h
index a62fb587237..a62fb587237 100644
--- a/include/asm-frv/termios.h
+++ b/arch/frv/include/asm/termios.h
diff --git a/include/asm-frv/thread_info.h b/arch/frv/include/asm/thread_info.h
index b7ac6bf2844..bb53ab753ff 100644
--- a/include/asm-frv/thread_info.h
+++ b/arch/frv/include/asm/thread_info.h
@@ -38,9 +38,9 @@ struct thread_info {
int preempt_count; /* 0 => preemptable, <0 => BUG */
mm_segment_t addr_limit; /* thread address space:
- 0-0xBFFFFFFF for user-thead
- 0-0xFFFFFFFF for kernel-thread
- */
+ * 0-0xBFFFFFFF for user-thead
+ * 0-0xFFFFFFFF for kernel-thread
+ */
struct restart_block restart_block;
__u8 supervisor_stack[0];
diff --git a/include/asm-frv/timer-regs.h b/arch/frv/include/asm/timer-regs.h
index 6c5a871ce5e..6c5a871ce5e 100644
--- a/include/asm-frv/timer-regs.h
+++ b/arch/frv/include/asm/timer-regs.h
diff --git a/include/asm-frv/timex.h b/arch/frv/include/asm/timex.h
index a89bddefdac..a89bddefdac 100644
--- a/include/asm-frv/timex.h
+++ b/arch/frv/include/asm/timex.h
diff --git a/include/asm-frv/tlb.h b/arch/frv/include/asm/tlb.h
index cd458eb6d75..cd458eb6d75 100644
--- a/include/asm-frv/tlb.h
+++ b/arch/frv/include/asm/tlb.h
diff --git a/include/asm-frv/tlbflush.h b/arch/frv/include/asm/tlbflush.h
index 7ac5eafc5d9..7ac5eafc5d9 100644
--- a/include/asm-frv/tlbflush.h
+++ b/arch/frv/include/asm/tlbflush.h
diff --git a/include/asm-frv/topology.h b/arch/frv/include/asm/topology.h
index 94272435270..94272435270 100644
--- a/include/asm-frv/topology.h
+++ b/arch/frv/include/asm/topology.h
diff --git a/include/asm-frv/types.h b/arch/frv/include/asm/types.h
index 613bf1e962f..613bf1e962f 100644
--- a/include/asm-frv/types.h
+++ b/arch/frv/include/asm/types.h
diff --git a/include/asm-frv/uaccess.h b/arch/frv/include/asm/uaccess.h
index 53650c958f4..53650c958f4 100644
--- a/include/asm-frv/uaccess.h
+++ b/arch/frv/include/asm/uaccess.h
diff --git a/include/asm-frv/ucontext.h b/arch/frv/include/asm/ucontext.h
index 8d8c0c94800..8d8c0c94800 100644
--- a/include/asm-frv/ucontext.h
+++ b/arch/frv/include/asm/ucontext.h
diff --git a/include/asm-frv/unaligned.h b/arch/frv/include/asm/unaligned.h
index 6c61c05b2e0..6c61c05b2e0 100644
--- a/include/asm-frv/unaligned.h
+++ b/arch/frv/include/asm/unaligned.h
diff --git a/include/asm-frv/unistd.h b/arch/frv/include/asm/unistd.h
index edcfaf5f041..edcfaf5f041 100644
--- a/include/asm-frv/unistd.h
+++ b/arch/frv/include/asm/unistd.h
diff --git a/include/asm-frv/user.h b/arch/frv/include/asm/user.h
index 82fa8fab64a..82fa8fab64a 100644
--- a/include/asm-frv/user.h
+++ b/arch/frv/include/asm/user.h
diff --git a/include/asm-frv/vga.h b/arch/frv/include/asm/vga.h
index a702c800a22..a702c800a22 100644
--- a/include/asm-frv/vga.h
+++ b/arch/frv/include/asm/vga.h
diff --git a/include/asm-frv/virtconvert.h b/arch/frv/include/asm/virtconvert.h
index 59788fa2a81..59788fa2a81 100644
--- a/include/asm-frv/virtconvert.h
+++ b/arch/frv/include/asm/virtconvert.h
diff --git a/include/asm-frv/xor.h b/arch/frv/include/asm/xor.h
index c82eb12a5b1..c82eb12a5b1 100644
--- a/include/asm-frv/xor.h
+++ b/arch/frv/include/asm/xor.h
diff --git a/arch/frv/mm/tlb-miss.S b/arch/frv/mm/tlb-miss.S
index 07643482cad..7f392bc651a 100644
--- a/arch/frv/mm/tlb-miss.S
+++ b/arch/frv/mm/tlb-miss.S
@@ -13,7 +13,6 @@
#include <linux/linkage.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/highmem.h>
#include <asm/spr-regs.h>
.section .text.tlbmiss
diff --git a/arch/h8300/include/asm/ftrace.h b/arch/h8300/include/asm/ftrace.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/h8300/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/h8300/kernel/timer/tpu.c b/arch/h8300/kernel/timer/tpu.c
index ad383caae19..e7c6e614a75 100644
--- a/arch/h8300/kernel/timer/tpu.c
+++ b/arch/h8300/kernel/timer/tpu.c
@@ -67,7 +67,7 @@ static struct irqaction tpu_irq = {
.flags = IRQF_DISABLED | IRQF_TIMER,
};
-const static int __initdata divide_rate[] = {
+static const 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)
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 153e727a6e8..294a3b13eca 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -22,6 +22,9 @@ config IA64
select HAVE_OPROFILE
select HAVE_KPROBES
select HAVE_KRETPROBES
+ select HAVE_FTRACE_MCOUNT_RECORD
+ select HAVE_DYNAMIC_FTRACE if (!ITANIUM)
+ select HAVE_FUNCTION_TRACER
select HAVE_DMA_ATTRS
select HAVE_KVM
select HAVE_ARCH_TRACEHOOK
diff --git a/arch/ia64/include/asm/ftrace.h b/arch/ia64/include/asm/ftrace.h
new file mode 100644
index 00000000000..d20db3c2a65
--- /dev/null
+++ b/arch/ia64/include/asm/ftrace.h
@@ -0,0 +1,28 @@
+#ifndef _ASM_IA64_FTRACE_H
+#define _ASM_IA64_FTRACE_H
+
+#ifdef CONFIG_FUNCTION_TRACER
+#define MCOUNT_INSN_SIZE 32 /* sizeof mcount call */
+
+#ifndef __ASSEMBLY__
+extern void _mcount(unsigned long pfs, unsigned long r1, unsigned long b0, unsigned long r0);
+#define mcount _mcount
+
+#include <asm/kprobes.h>
+/* In IA64, MCOUNT_ADDR is set in link time, so it's not a constant at compile time */
+#define MCOUNT_ADDR (((struct fnptr *)mcount)->ip)
+#define FTRACE_ADDR (((struct fnptr *)ftrace_caller)->ip)
+
+static inline unsigned long ftrace_call_adjust(unsigned long addr)
+{
+ /* second bundle, insn 2 */
+ return addr - 0x12;
+}
+
+struct dyn_arch_ftrace {
+};
+#endif
+
+#endif /* CONFIG_FUNCTION_TRACER */
+
+#endif /* _ASM_IA64_FTRACE_H */
diff --git a/arch/ia64/include/asm/hardirq.h b/arch/ia64/include/asm/hardirq.h
index 140e495b8e0..d514cd9edb4 100644
--- a/arch/ia64/include/asm/hardirq.h
+++ b/arch/ia64/include/asm/hardirq.h
@@ -20,16 +20,6 @@
#define local_softirq_pending() (local_cpu_data->softirq_pending)
-#define HARDIRQ_BITS 14
-
-/*
- * The hardirq mask has to be large enough to have space for potentially all IRQ sources
- * in the system nesting on a single CPU:
- */
-#if (1 << HARDIRQ_BITS) < NR_IRQS
-# error HARDIRQ_BITS is too low!
-#endif
-
extern void __iomem *ipi_base_addr;
void ack_bad_irq(unsigned int irq);
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
index 9015979ebe0..10a9eb05f74 100644
--- a/arch/ia64/include/asm/unistd.h
+++ b/arch/ia64/include/asm/unistd.h
@@ -308,11 +308,13 @@
#define __NR_dup3 1316
#define __NR_pipe2 1317
#define __NR_inotify_init1 1318
+#define __NR_preadv 1319
+#define __NR_pwritev 1320
#ifdef __KERNEL__
-#define NR_syscalls 295 /* length of syscall table */
+#define NR_syscalls 297 /* length of syscall table */
/*
* The following defines stop scripts/checksyscalls.sh from complaining about
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 5628e9a990a..6b7edcab0cb 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -2,6 +2,10 @@
# Makefile for the linux kernel.
#
+ifdef CONFIG_DYNAMIC_FTRACE
+CFLAGS_REMOVE_ftrace.o = -pg
+endif
+
extra-y := head.o init_task.o vmlinux.lds
obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \
@@ -28,6 +32,7 @@ obj-$(CONFIG_IA64_CYCLONE) += cyclone.o
obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
+obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index ccfdeee9d89..7bebac0e1d4 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -47,6 +47,7 @@
#include <asm/processor.h>
#include <asm/thread_info.h>
#include <asm/unistd.h>
+#include <asm/ftrace.h>
#include "minstate.h"
@@ -1404,6 +1405,105 @@ GLOBAL_ENTRY(unw_init_running)
br.ret.sptk.many rp
END(unw_init_running)
+#ifdef CONFIG_FUNCTION_TRACER
+#ifdef CONFIG_DYNAMIC_FTRACE
+GLOBAL_ENTRY(_mcount)
+ br ftrace_stub
+END(_mcount)
+
+.here:
+ br.ret.sptk.many b0
+
+GLOBAL_ENTRY(ftrace_caller)
+ alloc out0 = ar.pfs, 8, 0, 4, 0
+ mov out3 = r0
+ ;;
+ mov out2 = b0
+ add r3 = 0x20, r3
+ mov out1 = r1;
+ br.call.sptk.many b0 = ftrace_patch_gp
+ //this might be called from module, so we must patch gp
+ftrace_patch_gp:
+ movl gp=__gp
+ mov b0 = r3
+ ;;
+.global ftrace_call;
+ftrace_call:
+{
+ .mlx
+ nop.m 0x0
+ movl r3 = .here;;
+}
+ alloc loc0 = ar.pfs, 4, 4, 2, 0
+ ;;
+ mov loc1 = b0
+ mov out0 = b0
+ mov loc2 = r8
+ mov loc3 = r15
+ ;;
+ adds out0 = -MCOUNT_INSN_SIZE, out0
+ mov out1 = in2
+ mov b6 = r3
+
+ br.call.sptk.many b0 = b6
+ ;;
+ mov ar.pfs = loc0
+ mov b0 = loc1
+ mov r8 = loc2
+ mov r15 = loc3
+ br ftrace_stub
+ ;;
+END(ftrace_caller)
+
+#else
+GLOBAL_ENTRY(_mcount)
+ movl r2 = ftrace_stub
+ movl r3 = ftrace_trace_function;;
+ ld8 r3 = [r3];;
+ ld8 r3 = [r3];;
+ cmp.eq p7,p0 = r2, r3
+(p7) br.sptk.many ftrace_stub
+ ;;
+
+ alloc loc0 = ar.pfs, 4, 4, 2, 0
+ ;;
+ mov loc1 = b0
+ mov out0 = b0
+ mov loc2 = r8
+ mov loc3 = r15
+ ;;
+ adds out0 = -MCOUNT_INSN_SIZE, out0
+ mov out1 = in2
+ mov b6 = r3
+
+ br.call.sptk.many b0 = b6
+ ;;
+ mov ar.pfs = loc0
+ mov b0 = loc1
+ mov r8 = loc2
+ mov r15 = loc3
+ br ftrace_stub
+ ;;
+END(_mcount)
+#endif
+
+GLOBAL_ENTRY(ftrace_stub)
+ mov r3 = b0
+ movl r2 = _mcount_ret_helper
+ ;;
+ mov b6 = r2
+ mov b7 = r3
+ br.ret.sptk.many b6
+
+_mcount_ret_helper:
+ mov b0 = r42
+ mov r1 = r41
+ mov ar.pfs = r40
+ br b7
+END(ftrace_stub)
+
+#endif /* CONFIG_FUNCTION_TRACER */
+
.rodata
.align 8
.globl sys_call_table
@@ -1703,6 +1803,8 @@ sys_call_table:
data8 sys_dup3
data8 sys_pipe2
data8 sys_inotify_init1
+ data8 sys_preadv
+ data8 sys_pwritev // 1320
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
diff --git a/arch/ia64/kernel/ftrace.c b/arch/ia64/kernel/ftrace.c
new file mode 100644
index 00000000000..7fc8c961b1f
--- /dev/null
+++ b/arch/ia64/kernel/ftrace.c
@@ -0,0 +1,206 @@
+/*
+ * Dynamic function tracing support.
+ *
+ * Copyright (C) 2008 Shaohua Li <shaohua.li@intel.com>
+ *
+ * For licencing details, see COPYING.
+ *
+ * Defines low-level handling of mcount calls when the kernel
+ * is compiled with the -pg flag. When using dynamic ftrace, the
+ * mcount call-sites get patched lazily with NOP till they are
+ * enabled. All code mutation routines here take effect atomically.
+ */
+
+#include <linux/uaccess.h>
+#include <linux/ftrace.h>
+
+#include <asm/cacheflush.h>
+#include <asm/patch.h>
+
+/* In IA64, each function will be added below two bundles with -pg option */
+static unsigned char __attribute__((aligned(8)))
+ftrace_orig_code[MCOUNT_INSN_SIZE] = {
+ 0x02, 0x40, 0x31, 0x10, 0x80, 0x05, /* alloc r40=ar.pfs,12,8,0 */
+ 0xb0, 0x02, 0x00, 0x00, 0x42, 0x40, /* mov r43=r0;; */
+ 0x05, 0x00, 0xc4, 0x00, /* mov r42=b0 */
+ 0x11, 0x48, 0x01, 0x02, 0x00, 0x21, /* mov r41=r1 */
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
+ 0x08, 0x00, 0x00, 0x50 /* br.call.sptk.many b0 = _mcount;; */
+};
+
+struct ftrace_orig_insn {
+ u64 dummy1, dummy2, dummy3;
+ u64 dummy4:64-41+13;
+ u64 imm20:20;
+ u64 dummy5:3;
+ u64 sign:1;
+ u64 dummy6:4;
+};
+
+/* mcount stub will be converted below for nop */
+static unsigned char ftrace_nop_code[MCOUNT_INSN_SIZE] = {
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0x0 */
+ 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, /* mov r3=ip */
+ 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0 */
+ 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0x0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* nop.x 0x0;; */
+ 0x00, 0x00, 0x04, 0x00
+};
+
+static unsigned char *ftrace_nop_replace(void)
+{
+ return ftrace_nop_code;
+}
+
+/*
+ * mcount stub will be converted below for call
+ * Note: Just the last instruction is changed against nop
+ * */
+static unsigned char __attribute__((aligned(8)))
+ftrace_call_code[MCOUNT_INSN_SIZE] = {
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0x0 */
+ 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, /* mov r3=ip */
+ 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0 */
+ 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0x0 */
+ 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, /* brl.many .;;*/
+ 0xf8, 0xff, 0xff, 0xc8
+};
+
+struct ftrace_call_insn {
+ u64 dummy1, dummy2;
+ u64 dummy3:48;
+ u64 imm39_l:16;
+ u64 imm39_h:23;
+ u64 dummy4:13;
+ u64 imm20:20;
+ u64 dummy5:3;
+ u64 i:1;
+ u64 dummy6:4;
+};
+
+static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
+{
+ struct ftrace_call_insn *code = (void *)ftrace_call_code;
+ unsigned long offset = addr - (ip + 0x10);
+
+ code->imm39_l = offset >> 24;
+ code->imm39_h = offset >> 40;
+ code->imm20 = offset >> 4;
+ code->i = offset >> 63;
+ return ftrace_call_code;
+}
+
+static int
+ftrace_modify_code(unsigned long ip, unsigned char *old_code,
+ unsigned char *new_code, int do_check)
+{
+ unsigned char replaced[MCOUNT_INSN_SIZE];
+
+ /*
+ * Note: Due to modules and __init, code can
+ * disappear and change, we need to protect against faulting
+ * as well as code changing. We do this by using the
+ * probe_kernel_* functions.
+ *
+ * No real locking needed, this code is run through
+ * kstop_machine, or before SMP starts.
+ */
+
+ if (!do_check)
+ goto skip_check;
+
+ /* read the text we want to modify */
+ if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+ return -EFAULT;
+
+ /* Make sure it is what we expect it to be */
+ if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
+ return -EINVAL;
+
+skip_check:
+ /* replace the text with the new text */
+ if (probe_kernel_write(((void *)ip), new_code, MCOUNT_INSN_SIZE))
+ return -EPERM;
+ flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
+
+ return 0;
+}
+
+static int ftrace_make_nop_check(struct dyn_ftrace *rec, unsigned long addr)
+{
+ unsigned char __attribute__((aligned(8))) replaced[MCOUNT_INSN_SIZE];
+ unsigned long ip = rec->ip;
+
+ if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+ return -EFAULT;
+ if (rec->flags & FTRACE_FL_CONVERTED) {
+ struct ftrace_call_insn *call_insn, *tmp_call;
+
+ call_insn = (void *)ftrace_call_code;
+ tmp_call = (void *)replaced;
+ call_insn->imm39_l = tmp_call->imm39_l;
+ call_insn->imm39_h = tmp_call->imm39_h;
+ call_insn->imm20 = tmp_call->imm20;
+ call_insn->i = tmp_call->i;
+ if (memcmp(replaced, ftrace_call_code, MCOUNT_INSN_SIZE) != 0)
+ return -EINVAL;
+ return 0;
+ } else {
+ struct ftrace_orig_insn *call_insn, *tmp_call;
+
+ call_insn = (void *)ftrace_orig_code;
+ tmp_call = (void *)replaced;
+ call_insn->sign = tmp_call->sign;
+ call_insn->imm20 = tmp_call->imm20;
+ if (memcmp(replaced, ftrace_orig_code, MCOUNT_INSN_SIZE) != 0)
+ return -EINVAL;
+ return 0;
+ }
+}
+
+int ftrace_make_nop(struct module *mod,
+ struct dyn_ftrace *rec, unsigned long addr)
+{
+ int ret;
+ char *new;
+
+ ret = ftrace_make_nop_check(rec, addr);
+ if (ret)
+ return ret;
+ new = ftrace_nop_replace();
+ return ftrace_modify_code(rec->ip, NULL, new, 0);
+}
+
+int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+{
+ unsigned long ip = rec->ip;
+ unsigned char *old, *new;
+
+ old= ftrace_nop_replace();
+ new = ftrace_call_replace(ip, addr);
+ return ftrace_modify_code(ip, old, new, 1);
+}
+
+/* in IA64, _mcount can't directly call ftrace_stub. Only jump is ok */
+int ftrace_update_ftrace_func(ftrace_func_t func)
+{
+ unsigned long ip;
+ unsigned long addr = ((struct fnptr *)ftrace_call)->ip;
+
+ if (func == ftrace_stub)
+ return 0;
+ ip = ((struct fnptr *)func)->ip;
+
+ ia64_patch_imm64(addr + 2, ip);
+
+ flush_icache_range(addr, addr + 16);
+ return 0;
+}
+
+/* run from kstop_machine */
+int __init ftrace_dyn_arch_init(void *data)
+{
+ *(unsigned long *)data = 0;
+
+ return 0;
+}
diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
index 6da1f20d737..2d311864e35 100644
--- a/arch/ia64/kernel/ia64_ksyms.c
+++ b/arch/ia64/kernel/ia64_ksyms.c
@@ -112,3 +112,9 @@ EXPORT_SYMBOL_GPL(esi_call_phys);
#endif
extern char ia64_ivt[];
EXPORT_SYMBOL(ia64_ivt);
+
+#include <asm/ftrace.h>
+#ifdef CONFIG_FUNCTION_TRACER
+/* mcount is defined in assembly */
+EXPORT_SYMBOL(_mcount);
+#endif
diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c
index e4cb443bb98..eb987386f69 100644
--- a/arch/ia64/kernel/pci-dma.c
+++ b/arch/ia64/kernel/pci-dma.c
@@ -37,7 +37,7 @@ int force_iommu __read_mostly;
to i386. */
struct device fallback_dev = {
.init_name = "fallback device",
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
.dma_mask = &fallback_dev.coherent_dma_mask,
};
@@ -75,7 +75,7 @@ int iommu_dma_supported(struct device *dev, u64 mask)
/* Copied from i386. Doesn't make much sense, because it will
only work for pci_alloc_coherent.
The caller just has to use GFP_DMA in this case. */
- if (mask < DMA_24BIT_MASK)
+ if (mask < DMA_BIT_MASK(24))
return 0;
/* Tell the device to use SAC when IOMMU force is on. This
@@ -90,7 +90,7 @@ int iommu_dma_supported(struct device *dev, u64 mask)
SAC for these. Assume all masks <= 40 bits are of this
type. Normally this doesn't make any difference, but gives
more gentle handling of IOMMU overflow. */
- if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) {
+ if (iommu_sac_force && (mask >= DMA_BIT_MASK(40))) {
dev_info(dev, "Force SAC with mask %lx\n", mask);
return 0;
}
diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c
index 573f02c39a0..285aae8431c 100644
--- a/arch/ia64/kernel/pci-swiotlb.c
+++ b/arch/ia64/kernel/pci-swiotlb.c
@@ -16,7 +16,7 @@ EXPORT_SYMBOL(swiotlb);
static void *ia64_swiotlb_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp)
{
- if (dev->coherent_dma_mask != DMA_64BIT_MASK)
+ if (dev->coherent_dma_mask != DMA_BIT_MASK(64))
gfp |= GFP_DMA;
return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
}
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index 8c130e8f00e..d876423e4e7 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -349,7 +349,7 @@ static int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
u64 sn_dma_get_required_mask(struct device *dev)
{
- return DMA_64BIT_MASK;
+ return DMA_BIT_MASK(64);
}
EXPORT_SYMBOL_GPL(sn_dma_get_required_mask);
diff --git a/arch/m68k/include/asm/bootinfo.h b/arch/m68k/include/asm/bootinfo.h
index fedf3e32612..fb8a06b9ab6 100644
--- a/arch/m68k/include/asm/bootinfo.h
+++ b/arch/m68k/include/asm/bootinfo.h
@@ -1,5 +1,378 @@
-#ifdef __uClinux__
-#include "bootinfo_no.h"
-#else
-#include "bootinfo_mm.h"
+/*
+** asm/bootinfo.h -- Definition of the Linux/m68k boot information structure
+**
+** Copyright 1992 by Greg Harp
+**
+** 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.
+**
+** Created 09/29/92 by Greg Harp
+**
+** 5/2/94 Roman Hodek:
+** Added bi_atari part of the machine dependent union bi_un; for now it
+** contains just a model field to distinguish between TT and Falcon.
+** 26/7/96 Roman Zippel:
+** Renamed to setup.h; added some useful macros to allow gcc some
+** optimizations if possible.
+** 5/10/96 Geert Uytterhoeven:
+** Redesign of the boot information structure; renamed to bootinfo.h again
+** 27/11/96 Geert Uytterhoeven:
+** Backwards compatibility with bootinfo interface version 1.0
+*/
+
+#ifndef _M68K_BOOTINFO_H
+#define _M68K_BOOTINFO_H
+
+
+ /*
+ * Bootinfo definitions
+ *
+ * This is an easily parsable and extendable structure containing all
+ * information to be passed from the bootstrap to the kernel.
+ *
+ * This way I hope to keep all future changes back/forewards compatible.
+ * Thus, keep your fingers crossed...
+ *
+ * This structure is copied right after the kernel bss by the bootstrap
+ * routine.
+ */
+
+#ifndef __ASSEMBLY__
+
+struct bi_record {
+ unsigned short tag; /* tag ID */
+ unsigned short size; /* size of record (in bytes) */
+ unsigned long data[0]; /* data */
+};
+
+#endif /* __ASSEMBLY__ */
+
+
+ /*
+ * Tag Definitions
+ *
+ * Machine independent tags start counting from 0x0000
+ * Machine dependent tags start counting from 0x8000
+ */
+
+#define BI_LAST 0x0000 /* last record (sentinel) */
+#define BI_MACHTYPE 0x0001 /* machine type (u_long) */
+#define BI_CPUTYPE 0x0002 /* cpu type (u_long) */
+#define BI_FPUTYPE 0x0003 /* fpu type (u_long) */
+#define BI_MMUTYPE 0x0004 /* mmu type (u_long) */
+#define BI_MEMCHUNK 0x0005 /* memory chunk address and size */
+ /* (struct mem_info) */
+#define BI_RAMDISK 0x0006 /* ramdisk address and size */
+ /* (struct mem_info) */
+#define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */
+ /* (string) */
+
+ /*
+ * Amiga-specific tags
+ */
+
+#define BI_AMIGA_MODEL 0x8000 /* model (u_long) */
+#define BI_AMIGA_AUTOCON 0x8001 /* AutoConfig device */
+ /* (struct ConfigDev) */
+#define BI_AMIGA_CHIP_SIZE 0x8002 /* size of Chip RAM (u_long) */
+#define BI_AMIGA_VBLANK 0x8003 /* VBLANK frequency (u_char) */
+#define BI_AMIGA_PSFREQ 0x8004 /* power supply frequency (u_char) */
+#define BI_AMIGA_ECLOCK 0x8005 /* EClock frequency (u_long) */
+#define BI_AMIGA_CHIPSET 0x8006 /* native chipset present (u_long) */
+#define BI_AMIGA_SERPER 0x8007 /* serial port period (u_short) */
+
+ /*
+ * Atari-specific tags
+ */
+
+#define BI_ATARI_MCH_COOKIE 0x8000 /* _MCH cookie from TOS (u_long) */
+#define BI_ATARI_MCH_TYPE 0x8001 /* special machine type (u_long) */
+ /* (values are ATARI_MACH_* defines */
+
+/* mch_cookie values (upper word) */
+#define ATARI_MCH_ST 0
+#define ATARI_MCH_STE 1
+#define ATARI_MCH_TT 2
+#define ATARI_MCH_FALCON 3
+
+/* mch_type values */
+#define ATARI_MACH_NORMAL 0 /* no special machine type */
+#define ATARI_MACH_MEDUSA 1 /* Medusa 040 */
+#define ATARI_MACH_HADES 2 /* Hades 040 or 060 */
+#define ATARI_MACH_AB40 3 /* Afterburner040 on Falcon */
+
+ /*
+ * VME-specific tags
+ */
+
+#define BI_VME_TYPE 0x8000 /* VME sub-architecture (u_long) */
+#define BI_VME_BRDINFO 0x8001 /* VME board information (struct) */
+
+/* BI_VME_TYPE codes */
+#define VME_TYPE_TP34V 0x0034 /* Tadpole TP34V */
+#define VME_TYPE_MVME147 0x0147 /* Motorola MVME147 */
+#define VME_TYPE_MVME162 0x0162 /* Motorola MVME162 */
+#define VME_TYPE_MVME166 0x0166 /* Motorola MVME166 */
+#define VME_TYPE_MVME167 0x0167 /* Motorola MVME167 */
+#define VME_TYPE_MVME172 0x0172 /* Motorola MVME172 */
+#define VME_TYPE_MVME177 0x0177 /* Motorola MVME177 */
+#define VME_TYPE_BVME4000 0x4000 /* BVM Ltd. BVME4000 */
+#define VME_TYPE_BVME6000 0x6000 /* BVM Ltd. BVME6000 */
+
+/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on
+ * Motorola VME boards. Contains board number, Bug version, board
+ * configuration options, etc. See include/asm/mvme16xhw.h for details.
+ */
+
+
+ /*
+ * Macintosh-specific tags (all u_long)
+ */
+
+#define BI_MAC_MODEL 0x8000 /* Mac Gestalt ID (model type) */
+#define BI_MAC_VADDR 0x8001 /* Mac video base address */
+#define BI_MAC_VDEPTH 0x8002 /* Mac video depth */
+#define BI_MAC_VROW 0x8003 /* Mac video rowbytes */
+#define BI_MAC_VDIM 0x8004 /* Mac video dimensions */
+#define BI_MAC_VLOGICAL 0x8005 /* Mac video logical base */
+#define BI_MAC_SCCBASE 0x8006 /* Mac SCC base address */
+#define BI_MAC_BTIME 0x8007 /* Mac boot time */
+#define BI_MAC_GMTBIAS 0x8008 /* Mac GMT timezone offset */
+#define BI_MAC_MEMSIZE 0x8009 /* Mac RAM size (sanity check) */
+#define BI_MAC_CPUID 0x800a /* Mac CPU type (sanity check) */
+#define BI_MAC_ROMBASE 0x800b /* Mac system ROM base address */
+
+ /*
+ * Macintosh hardware profile data - unused, see macintosh.h for
+ * resonable type values
+ */
+
+#define BI_MAC_VIA1BASE 0x8010 /* Mac VIA1 base address (always present) */
+#define BI_MAC_VIA2BASE 0x8011 /* Mac VIA2 base address (type varies) */
+#define BI_MAC_VIA2TYPE 0x8012 /* Mac VIA2 type (VIA, RBV, OSS) */
+#define BI_MAC_ADBTYPE 0x8013 /* Mac ADB interface type */
+#define BI_MAC_ASCBASE 0x8014 /* Mac Apple Sound Chip base address */
+#define BI_MAC_SCSI5380 0x8015 /* Mac NCR 5380 SCSI (base address, multi) */
+#define BI_MAC_SCSIDMA 0x8016 /* Mac SCSI DMA (base address) */
+#define BI_MAC_SCSI5396 0x8017 /* Mac NCR 53C96 SCSI (base address, multi) */
+#define BI_MAC_IDETYPE 0x8018 /* Mac IDE interface type */
+#define BI_MAC_IDEBASE 0x8019 /* Mac IDE interface base address */
+#define BI_MAC_NUBUS 0x801a /* Mac Nubus type (none, regular, pseudo) */
+#define BI_MAC_SLOTMASK 0x801b /* Mac Nubus slots present */
+#define BI_MAC_SCCTYPE 0x801c /* Mac SCC serial type (normal, IOP) */
+#define BI_MAC_ETHTYPE 0x801d /* Mac builtin ethernet type (Sonic, MACE */
+#define BI_MAC_ETHBASE 0x801e /* Mac builtin ethernet base address */
+#define BI_MAC_PMU 0x801f /* Mac power management / poweroff hardware */
+#define BI_MAC_IOP_SWIM 0x8020 /* Mac SWIM floppy IOP */
+#define BI_MAC_IOP_ADB 0x8021 /* Mac ADB IOP */
+
+ /*
+ * Mac: compatibility with old booter data format (temporarily)
+ * Fields unused with the new bootinfo can be deleted now; instead of
+ * adding new fields the struct might be splitted into a hardware address
+ * part and a hardware type part
+ */
+
+#ifndef __ASSEMBLY__
+
+struct mac_booter_data
+{
+ unsigned long videoaddr;
+ unsigned long videorow;
+ unsigned long videodepth;
+ unsigned long dimensions;
+ unsigned long args;
+ unsigned long boottime;
+ unsigned long gmtbias;
+ unsigned long bootver;
+ unsigned long videological;
+ unsigned long sccbase;
+ unsigned long id;
+ unsigned long memsize;
+ unsigned long serialmf;
+ unsigned long serialhsk;
+ unsigned long serialgpi;
+ unsigned long printmf;
+ unsigned long printhsk;
+ unsigned long printgpi;
+ unsigned long cpuid;
+ unsigned long rombase;
+ unsigned long adbdelay;
+ unsigned long timedbra;
+};
+
+extern struct mac_booter_data
+ mac_bi_data;
+
#endif
+
+ /*
+ * Apollo-specific tags
+ */
+
+#define BI_APOLLO_MODEL 0x8000 /* model (u_long) */
+
+ /*
+ * HP300-specific tags
+ */
+
+#define BI_HP300_MODEL 0x8000 /* model (u_long) */
+#define BI_HP300_UART_SCODE 0x8001 /* UART select code (u_long) */
+#define BI_HP300_UART_ADDR 0x8002 /* phys. addr of UART (u_long) */
+
+ /*
+ * Stuff for bootinfo interface versioning
+ *
+ * At the start of kernel code, a 'struct bootversion' is located.
+ * bootstrap checks for a matching version of the interface before booting
+ * a kernel, to avoid user confusion if kernel and bootstrap don't work
+ * together :-)
+ *
+ * If incompatible changes are made to the bootinfo interface, the major
+ * number below should be stepped (and the minor reset to 0) for the
+ * appropriate machine. If a change is backward-compatible, the minor
+ * should be stepped. "Backwards-compatible" means that booting will work,
+ * but certain features may not.
+ */
+
+#define BOOTINFOV_MAGIC 0x4249561A /* 'BIV^Z' */
+#define MK_BI_VERSION(major,minor) (((major)<<16)+(minor))
+#define BI_VERSION_MAJOR(v) (((v) >> 16) & 0xffff)
+#define BI_VERSION_MINOR(v) ((v) & 0xffff)
+
+#ifndef __ASSEMBLY__
+
+struct bootversion {
+ unsigned short branch;
+ unsigned long magic;
+ struct {
+ unsigned long machtype;
+ unsigned long version;
+ } machversions[0];
+};
+
+#endif /* __ASSEMBLY__ */
+
+#define AMIGA_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define ATARI_BOOTI_VERSION MK_BI_VERSION( 2, 1 )
+#define MAC_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define MVME147_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define MVME16x_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define Q40_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define HP300_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+
+#ifdef BOOTINFO_COMPAT_1_0
+
+ /*
+ * Backwards compatibility with bootinfo interface version 1.0
+ */
+
+#define COMPAT_AMIGA_BOOTI_VERSION MK_BI_VERSION( 1, 0 )
+#define COMPAT_ATARI_BOOTI_VERSION MK_BI_VERSION( 1, 0 )
+#define COMPAT_MAC_BOOTI_VERSION MK_BI_VERSION( 1, 0 )
+
+#include <linux/zorro.h>
+
+#define COMPAT_NUM_AUTO 16
+
+struct compat_bi_Amiga {
+ int model;
+ int num_autocon;
+ struct ConfigDev autocon[COMPAT_NUM_AUTO];
+ unsigned long chip_size;
+ unsigned char vblank;
+ unsigned char psfreq;
+ unsigned long eclock;
+ unsigned long chipset;
+ unsigned long hw_present;
+};
+
+struct compat_bi_Atari {
+ unsigned long hw_present;
+ unsigned long mch_cookie;
+};
+
+#ifndef __ASSEMBLY__
+
+struct compat_bi_Macintosh
+{
+ unsigned long videoaddr;
+ unsigned long videorow;
+ unsigned long videodepth;
+ unsigned long dimensions;
+ unsigned long args;
+ unsigned long boottime;
+ unsigned long gmtbias;
+ unsigned long bootver;
+ unsigned long videological;
+ unsigned long sccbase;
+ unsigned long id;
+ unsigned long memsize;
+ unsigned long serialmf;
+ unsigned long serialhsk;
+ unsigned long serialgpi;
+ unsigned long printmf;
+ unsigned long printhsk;
+ unsigned long printgpi;
+ unsigned long cpuid;
+ unsigned long rombase;
+ unsigned long adbdelay;
+ unsigned long timedbra;
+};
+
+#endif
+
+struct compat_mem_info {
+ unsigned long addr;
+ unsigned long size;
+};
+
+#define COMPAT_NUM_MEMINFO 4
+
+#define COMPAT_CPUB_68020 0
+#define COMPAT_CPUB_68030 1
+#define COMPAT_CPUB_68040 2
+#define COMPAT_CPUB_68060 3
+#define COMPAT_FPUB_68881 5
+#define COMPAT_FPUB_68882 6
+#define COMPAT_FPUB_68040 7
+#define COMPAT_FPUB_68060 8
+
+#define COMPAT_CPU_68020 (1<<COMPAT_CPUB_68020)
+#define COMPAT_CPU_68030 (1<<COMPAT_CPUB_68030)
+#define COMPAT_CPU_68040 (1<<COMPAT_CPUB_68040)
+#define COMPAT_CPU_68060 (1<<COMPAT_CPUB_68060)
+#define COMPAT_CPU_MASK (31)
+#define COMPAT_FPU_68881 (1<<COMPAT_FPUB_68881)
+#define COMPAT_FPU_68882 (1<<COMPAT_FPUB_68882)
+#define COMPAT_FPU_68040 (1<<COMPAT_FPUB_68040)
+#define COMPAT_FPU_68060 (1<<COMPAT_FPUB_68060)
+#define COMPAT_FPU_MASK (0xfe0)
+
+#define COMPAT_CL_SIZE (256)
+
+struct compat_bootinfo {
+ unsigned long machtype;
+ unsigned long cputype;
+ struct compat_mem_info memory[COMPAT_NUM_MEMINFO];
+ int num_memory;
+ unsigned long ramdisk_size;
+ unsigned long ramdisk_addr;
+ char command_line[COMPAT_CL_SIZE];
+ union {
+ struct compat_bi_Amiga bi_ami;
+ struct compat_bi_Atari bi_ata;
+ struct compat_bi_Macintosh bi_mac;
+ } bi_un;
+};
+
+#define bi_amiga bi_un.bi_ami
+#define bi_atari bi_un.bi_ata
+#define bi_mac bi_un.bi_mac
+
+#endif /* BOOTINFO_COMPAT_1_0 */
+
+
+#endif /* _M68K_BOOTINFO_H */
diff --git a/arch/m68k/include/asm/bootinfo_mm.h b/arch/m68k/include/asm/bootinfo_mm.h
deleted file mode 100644
index fb8a06b9ab6..00000000000
--- a/arch/m68k/include/asm/bootinfo_mm.h
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
-** asm/bootinfo.h -- Definition of the Linux/m68k boot information structure
-**
-** Copyright 1992 by Greg Harp
-**
-** 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.
-**
-** Created 09/29/92 by Greg Harp
-**
-** 5/2/94 Roman Hodek:
-** Added bi_atari part of the machine dependent union bi_un; for now it
-** contains just a model field to distinguish between TT and Falcon.
-** 26/7/96 Roman Zippel:
-** Renamed to setup.h; added some useful macros to allow gcc some
-** optimizations if possible.
-** 5/10/96 Geert Uytterhoeven:
-** Redesign of the boot information structure; renamed to bootinfo.h again
-** 27/11/96 Geert Uytterhoeven:
-** Backwards compatibility with bootinfo interface version 1.0
-*/
-
-#ifndef _M68K_BOOTINFO_H
-#define _M68K_BOOTINFO_H
-
-
- /*
- * Bootinfo definitions
- *
- * This is an easily parsable and extendable structure containing all
- * information to be passed from the bootstrap to the kernel.
- *
- * This way I hope to keep all future changes back/forewards compatible.
- * Thus, keep your fingers crossed...
- *
- * This structure is copied right after the kernel bss by the bootstrap
- * routine.
- */
-
-#ifndef __ASSEMBLY__
-
-struct bi_record {
- unsigned short tag; /* tag ID */
- unsigned short size; /* size of record (in bytes) */
- unsigned long data[0]; /* data */
-};
-
-#endif /* __ASSEMBLY__ */
-
-
- /*
- * Tag Definitions
- *
- * Machine independent tags start counting from 0x0000
- * Machine dependent tags start counting from 0x8000
- */
-
-#define BI_LAST 0x0000 /* last record (sentinel) */
-#define BI_MACHTYPE 0x0001 /* machine type (u_long) */
-#define BI_CPUTYPE 0x0002 /* cpu type (u_long) */
-#define BI_FPUTYPE 0x0003 /* fpu type (u_long) */
-#define BI_MMUTYPE 0x0004 /* mmu type (u_long) */
-#define BI_MEMCHUNK 0x0005 /* memory chunk address and size */
- /* (struct mem_info) */
-#define BI_RAMDISK 0x0006 /* ramdisk address and size */
- /* (struct mem_info) */
-#define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */
- /* (string) */
-
- /*
- * Amiga-specific tags
- */
-
-#define BI_AMIGA_MODEL 0x8000 /* model (u_long) */
-#define BI_AMIGA_AUTOCON 0x8001 /* AutoConfig device */
- /* (struct ConfigDev) */
-#define BI_AMIGA_CHIP_SIZE 0x8002 /* size of Chip RAM (u_long) */
-#define BI_AMIGA_VBLANK 0x8003 /* VBLANK frequency (u_char) */
-#define BI_AMIGA_PSFREQ 0x8004 /* power supply frequency (u_char) */
-#define BI_AMIGA_ECLOCK 0x8005 /* EClock frequency (u_long) */
-#define BI_AMIGA_CHIPSET 0x8006 /* native chipset present (u_long) */
-#define BI_AMIGA_SERPER 0x8007 /* serial port period (u_short) */
-
- /*
- * Atari-specific tags
- */
-
-#define BI_ATARI_MCH_COOKIE 0x8000 /* _MCH cookie from TOS (u_long) */
-#define BI_ATARI_MCH_TYPE 0x8001 /* special machine type (u_long) */
- /* (values are ATARI_MACH_* defines */
-
-/* mch_cookie values (upper word) */
-#define ATARI_MCH_ST 0
-#define ATARI_MCH_STE 1
-#define ATARI_MCH_TT 2
-#define ATARI_MCH_FALCON 3
-
-/* mch_type values */
-#define ATARI_MACH_NORMAL 0 /* no special machine type */
-#define ATARI_MACH_MEDUSA 1 /* Medusa 040 */
-#define ATARI_MACH_HADES 2 /* Hades 040 or 060 */
-#define ATARI_MACH_AB40 3 /* Afterburner040 on Falcon */
-
- /*
- * VME-specific tags
- */
-
-#define BI_VME_TYPE 0x8000 /* VME sub-architecture (u_long) */
-#define BI_VME_BRDINFO 0x8001 /* VME board information (struct) */
-
-/* BI_VME_TYPE codes */
-#define VME_TYPE_TP34V 0x0034 /* Tadpole TP34V */
-#define VME_TYPE_MVME147 0x0147 /* Motorola MVME147 */
-#define VME_TYPE_MVME162 0x0162 /* Motorola MVME162 */
-#define VME_TYPE_MVME166 0x0166 /* Motorola MVME166 */
-#define VME_TYPE_MVME167 0x0167 /* Motorola MVME167 */
-#define VME_TYPE_MVME172 0x0172 /* Motorola MVME172 */
-#define VME_TYPE_MVME177 0x0177 /* Motorola MVME177 */
-#define VME_TYPE_BVME4000 0x4000 /* BVM Ltd. BVME4000 */
-#define VME_TYPE_BVME6000 0x6000 /* BVM Ltd. BVME6000 */
-
-/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on
- * Motorola VME boards. Contains board number, Bug version, board
- * configuration options, etc. See include/asm/mvme16xhw.h for details.
- */
-
-
- /*
- * Macintosh-specific tags (all u_long)
- */
-
-#define BI_MAC_MODEL 0x8000 /* Mac Gestalt ID (model type) */
-#define BI_MAC_VADDR 0x8001 /* Mac video base address */
-#define BI_MAC_VDEPTH 0x8002 /* Mac video depth */
-#define BI_MAC_VROW 0x8003 /* Mac video rowbytes */
-#define BI_MAC_VDIM 0x8004 /* Mac video dimensions */
-#define BI_MAC_VLOGICAL 0x8005 /* Mac video logical base */
-#define BI_MAC_SCCBASE 0x8006 /* Mac SCC base address */
-#define BI_MAC_BTIME 0x8007 /* Mac boot time */
-#define BI_MAC_GMTBIAS 0x8008 /* Mac GMT timezone offset */
-#define BI_MAC_MEMSIZE 0x8009 /* Mac RAM size (sanity check) */
-#define BI_MAC_CPUID 0x800a /* Mac CPU type (sanity check) */
-#define BI_MAC_ROMBASE 0x800b /* Mac system ROM base address */
-
- /*
- * Macintosh hardware profile data - unused, see macintosh.h for
- * resonable type values
- */
-
-#define BI_MAC_VIA1BASE 0x8010 /* Mac VIA1 base address (always present) */
-#define BI_MAC_VIA2BASE 0x8011 /* Mac VIA2 base address (type varies) */
-#define BI_MAC_VIA2TYPE 0x8012 /* Mac VIA2 type (VIA, RBV, OSS) */
-#define BI_MAC_ADBTYPE 0x8013 /* Mac ADB interface type */
-#define BI_MAC_ASCBASE 0x8014 /* Mac Apple Sound Chip base address */
-#define BI_MAC_SCSI5380 0x8015 /* Mac NCR 5380 SCSI (base address, multi) */
-#define BI_MAC_SCSIDMA 0x8016 /* Mac SCSI DMA (base address) */
-#define BI_MAC_SCSI5396 0x8017 /* Mac NCR 53C96 SCSI (base address, multi) */
-#define BI_MAC_IDETYPE 0x8018 /* Mac IDE interface type */
-#define BI_MAC_IDEBASE 0x8019 /* Mac IDE interface base address */
-#define BI_MAC_NUBUS 0x801a /* Mac Nubus type (none, regular, pseudo) */
-#define BI_MAC_SLOTMASK 0x801b /* Mac Nubus slots present */
-#define BI_MAC_SCCTYPE 0x801c /* Mac SCC serial type (normal, IOP) */
-#define BI_MAC_ETHTYPE 0x801d /* Mac builtin ethernet type (Sonic, MACE */
-#define BI_MAC_ETHBASE 0x801e /* Mac builtin ethernet base address */
-#define BI_MAC_PMU 0x801f /* Mac power management / poweroff hardware */
-#define BI_MAC_IOP_SWIM 0x8020 /* Mac SWIM floppy IOP */
-#define BI_MAC_IOP_ADB 0x8021 /* Mac ADB IOP */
-
- /*
- * Mac: compatibility with old booter data format (temporarily)
- * Fields unused with the new bootinfo can be deleted now; instead of
- * adding new fields the struct might be splitted into a hardware address
- * part and a hardware type part
- */
-
-#ifndef __ASSEMBLY__
-
-struct mac_booter_data
-{
- unsigned long videoaddr;
- unsigned long videorow;
- unsigned long videodepth;
- unsigned long dimensions;
- unsigned long args;
- unsigned long boottime;
- unsigned long gmtbias;
- unsigned long bootver;
- unsigned long videological;
- unsigned long sccbase;
- unsigned long id;
- unsigned long memsize;
- unsigned long serialmf;
- unsigned long serialhsk;
- unsigned long serialgpi;
- unsigned long printmf;
- unsigned long printhsk;
- unsigned long printgpi;
- unsigned long cpuid;
- unsigned long rombase;
- unsigned long adbdelay;
- unsigned long timedbra;
-};
-
-extern struct mac_booter_data
- mac_bi_data;
-
-#endif
-
- /*
- * Apollo-specific tags
- */
-
-#define BI_APOLLO_MODEL 0x8000 /* model (u_long) */
-
- /*
- * HP300-specific tags
- */
-
-#define BI_HP300_MODEL 0x8000 /* model (u_long) */
-#define BI_HP300_UART_SCODE 0x8001 /* UART select code (u_long) */
-#define BI_HP300_UART_ADDR 0x8002 /* phys. addr of UART (u_long) */
-
- /*
- * Stuff for bootinfo interface versioning
- *
- * At the start of kernel code, a 'struct bootversion' is located.
- * bootstrap checks for a matching version of the interface before booting
- * a kernel, to avoid user confusion if kernel and bootstrap don't work
- * together :-)
- *
- * If incompatible changes are made to the bootinfo interface, the major
- * number below should be stepped (and the minor reset to 0) for the
- * appropriate machine. If a change is backward-compatible, the minor
- * should be stepped. "Backwards-compatible" means that booting will work,
- * but certain features may not.
- */
-
-#define BOOTINFOV_MAGIC 0x4249561A /* 'BIV^Z' */
-#define MK_BI_VERSION(major,minor) (((major)<<16)+(minor))
-#define BI_VERSION_MAJOR(v) (((v) >> 16) & 0xffff)
-#define BI_VERSION_MINOR(v) ((v) & 0xffff)
-
-#ifndef __ASSEMBLY__
-
-struct bootversion {
- unsigned short branch;
- unsigned long magic;
- struct {
- unsigned long machtype;
- unsigned long version;
- } machversions[0];
-};
-
-#endif /* __ASSEMBLY__ */
-
-#define AMIGA_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define ATARI_BOOTI_VERSION MK_BI_VERSION( 2, 1 )
-#define MAC_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define MVME147_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define MVME16x_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define Q40_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define HP300_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-
-#ifdef BOOTINFO_COMPAT_1_0
-
- /*
- * Backwards compatibility with bootinfo interface version 1.0
- */
-
-#define COMPAT_AMIGA_BOOTI_VERSION MK_BI_VERSION( 1, 0 )
-#define COMPAT_ATARI_BOOTI_VERSION MK_BI_VERSION( 1, 0 )
-#define COMPAT_MAC_BOOTI_VERSION MK_BI_VERSION( 1, 0 )
-
-#include <linux/zorro.h>
-
-#define COMPAT_NUM_AUTO 16
-
-struct compat_bi_Amiga {
- int model;
- int num_autocon;
- struct ConfigDev autocon[COMPAT_NUM_AUTO];
- unsigned long chip_size;
- unsigned char vblank;
- unsigned char psfreq;
- unsigned long eclock;
- unsigned long chipset;
- unsigned long hw_present;
-};
-
-struct compat_bi_Atari {
- unsigned long hw_present;
- unsigned long mch_cookie;
-};
-
-#ifndef __ASSEMBLY__
-
-struct compat_bi_Macintosh
-{
- unsigned long videoaddr;
- unsigned long videorow;
- unsigned long videodepth;
- unsigned long dimensions;
- unsigned long args;
- unsigned long boottime;
- unsigned long gmtbias;
- unsigned long bootver;
- unsigned long videological;
- unsigned long sccbase;
- unsigned long id;
- unsigned long memsize;
- unsigned long serialmf;
- unsigned long serialhsk;
- unsigned long serialgpi;
- unsigned long printmf;
- unsigned long printhsk;
- unsigned long printgpi;
- unsigned long cpuid;
- unsigned long rombase;
- unsigned long adbdelay;
- unsigned long timedbra;
-};
-
-#endif
-
-struct compat_mem_info {
- unsigned long addr;
- unsigned long size;
-};
-
-#define COMPAT_NUM_MEMINFO 4
-
-#define COMPAT_CPUB_68020 0
-#define COMPAT_CPUB_68030 1
-#define COMPAT_CPUB_68040 2
-#define COMPAT_CPUB_68060 3
-#define COMPAT_FPUB_68881 5
-#define COMPAT_FPUB_68882 6
-#define COMPAT_FPUB_68040 7
-#define COMPAT_FPUB_68060 8
-
-#define COMPAT_CPU_68020 (1<<COMPAT_CPUB_68020)
-#define COMPAT_CPU_68030 (1<<COMPAT_CPUB_68030)
-#define COMPAT_CPU_68040 (1<<COMPAT_CPUB_68040)
-#define COMPAT_CPU_68060 (1<<COMPAT_CPUB_68060)
-#define COMPAT_CPU_MASK (31)
-#define COMPAT_FPU_68881 (1<<COMPAT_FPUB_68881)
-#define COMPAT_FPU_68882 (1<<COMPAT_FPUB_68882)
-#define COMPAT_FPU_68040 (1<<COMPAT_FPUB_68040)
-#define COMPAT_FPU_68060 (1<<COMPAT_FPUB_68060)
-#define COMPAT_FPU_MASK (0xfe0)
-
-#define COMPAT_CL_SIZE (256)
-
-struct compat_bootinfo {
- unsigned long machtype;
- unsigned long cputype;
- struct compat_mem_info memory[COMPAT_NUM_MEMINFO];
- int num_memory;
- unsigned long ramdisk_size;
- unsigned long ramdisk_addr;
- char command_line[COMPAT_CL_SIZE];
- union {
- struct compat_bi_Amiga bi_ami;
- struct compat_bi_Atari bi_ata;
- struct compat_bi_Macintosh bi_mac;
- } bi_un;
-};
-
-#define bi_amiga bi_un.bi_ami
-#define bi_atari bi_un.bi_ata
-#define bi_mac bi_un.bi_mac
-
-#endif /* BOOTINFO_COMPAT_1_0 */
-
-
-#endif /* _M68K_BOOTINFO_H */
diff --git a/arch/m68k/include/asm/bootinfo_no.h b/arch/m68k/include/asm/bootinfo_no.h
deleted file mode 100644
index c12e526f518..00000000000
--- a/arch/m68k/include/asm/bootinfo_no.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-/* Nothing for m68knommu */
diff --git a/arch/m68k/include/asm/bug.h b/arch/m68k/include/asm/bug.h
index 997e0944ebc..ef9a2e47352 100644
--- a/arch/m68k/include/asm/bug.h
+++ b/arch/m68k/include/asm/bug.h
@@ -1,5 +1,30 @@
-#ifdef __uClinux__
-#include "bug_no.h"
+#ifndef _M68K_BUG_H
+#define _M68K_BUG_H
+
+#ifdef CONFIG_MMU
+#ifdef CONFIG_BUG
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+#ifndef CONFIG_SUN3
+#define BUG() do { \
+ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+ __builtin_trap(); \
+} while (0)
#else
-#include "bug_mm.h"
+#define BUG() do { \
+ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+ panic("BUG!"); \
+} while (0)
+#endif
+#else
+#define BUG() do { \
+ __builtin_trap(); \
+} while (0)
+#endif
+
+#define HAVE_ARCH_BUG
+#endif
+#endif /* CONFIG_MMU */
+
+#include <asm-generic/bug.h>
+
#endif
diff --git a/arch/m68k/include/asm/bug_mm.h b/arch/m68k/include/asm/bug_mm.h
deleted file mode 100644
index e5b528deb8a..00000000000
--- a/arch/m68k/include/asm/bug_mm.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _M68K_BUG_H
-#define _M68K_BUG_H
-
-
-#ifdef CONFIG_BUG
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-#ifndef CONFIG_SUN3
-#define BUG() do { \
- printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
- __builtin_trap(); \
-} while (0)
-#else
-#define BUG() do { \
- printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
- panic("BUG!"); \
-} while (0)
-#endif
-#else
-#define BUG() do { \
- __builtin_trap(); \
-} while (0)
-#endif
-
-#define HAVE_ARCH_BUG
-#endif
-
-#include <asm-generic/bug.h>
-
-#endif
diff --git a/arch/m68k/include/asm/bug_no.h b/arch/m68k/include/asm/bug_no.h
deleted file mode 100644
index 70e7dc0af21..00000000000
--- a/arch/m68k/include/asm/bug_no.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef _M68KNOMMU_BUG_H
-#define _M68KNOMMU_BUG_H
-#include <asm-generic/bug.h>
-#endif
diff --git a/arch/m68k/include/asm/bugs.h b/arch/m68k/include/asm/bugs.h
index 01f047d784e..d06207b9ba5 100644
--- a/arch/m68k/include/asm/bugs.h
+++ b/arch/m68k/include/asm/bugs.h
@@ -1,5 +1,20 @@
-#ifdef __uClinux__
-#include "bugs_no.h"
+/*
+ * include/asm-m68k/bugs.h
+ *
+ * Copyright (C) 1994 Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ * void check_bugs(void);
+ */
+
+#ifdef CONFIG_MMU
+extern void check_bugs(void); /* in arch/m68k/kernel/setup.c */
#else
-#include "bugs_mm.h"
+static void check_bugs(void)
+{
+}
#endif
diff --git a/arch/m68k/include/asm/bugs_mm.h b/arch/m68k/include/asm/bugs_mm.h
deleted file mode 100644
index d0193559241..00000000000
--- a/arch/m68k/include/asm/bugs_mm.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * include/asm-m68k/bugs.h
- *
- * Copyright (C) 1994 Linus Torvalds
- */
-
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- * void check_bugs(void);
- */
-
-extern void check_bugs(void); /* in arch/m68k/kernel/setup.c */
diff --git a/arch/m68k/include/asm/bugs_no.h b/arch/m68k/include/asm/bugs_no.h
deleted file mode 100644
index 5f382dac3a6..00000000000
--- a/arch/m68k/include/asm/bugs_no.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * include/asm-m68k/bugs.h
- *
- * Copyright (C) 1994 Linus Torvalds
- */
-
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- * void check_bugs(void);
- */
-
-static void check_bugs(void)
-{
-}
diff --git a/arch/m68k/include/asm/cache.h b/arch/m68k/include/asm/cache.h
index 599c29bc8f4..fed3fd30de7 100644
--- a/arch/m68k/include/asm/cache.h
+++ b/arch/m68k/include/asm/cache.h
@@ -1,5 +1,11 @@
-#ifdef __uClinux__
-#include "cache_no.h"
-#else
-#include "cache_mm.h"
+/*
+ * include/asm-m68k/cache.h
+ */
+#ifndef __ARCH_M68K_CACHE_H
+#define __ARCH_M68K_CACHE_H
+
+/* bytes per L1 cache line */
+#define L1_CACHE_SHIFT 4
+#define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT)
+
#endif
diff --git a/arch/m68k/include/asm/cache_mm.h b/arch/m68k/include/asm/cache_mm.h
deleted file mode 100644
index fed3fd30de7..00000000000
--- a/arch/m68k/include/asm/cache_mm.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * include/asm-m68k/cache.h
- */
-#ifndef __ARCH_M68K_CACHE_H
-#define __ARCH_M68K_CACHE_H
-
-/* bytes per L1 cache line */
-#define L1_CACHE_SHIFT 4
-#define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT)
-
-#endif
diff --git a/arch/m68k/include/asm/cache_no.h b/arch/m68k/include/asm/cache_no.h
deleted file mode 100644
index 24e9eace5f8..00000000000
--- a/arch/m68k/include/asm/cache_no.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __ARCH_M68KNOMMU_CACHE_H
-#define __ARCH_M68KNOMMU_CACHE_H
-
-/* bytes per L1 cache line */
-#define L1_CACHE_BYTES 16 /* this need to be at least 1 */
-
-/* m68k-elf-gcc 2.95.2 doesn't like these */
-
-#define __cacheline_aligned
-#define ____cacheline_aligned
-
-#endif
diff --git a/arch/m68k/include/asm/current.h b/arch/m68k/include/asm/current.h
index 51b056dfaed..91fcc5358cf 100644
--- a/arch/m68k/include/asm/current.h
+++ b/arch/m68k/include/asm/current.h
@@ -1,5 +1,28 @@
-#ifdef __uClinux__
-#include "current_no.h"
+#ifndef _M68K_CURRENT_H
+#define _M68K_CURRENT_H
+
+#ifdef CONFIG_MMU
+
+register struct task_struct *current __asm__("%a2");
+
#else
-#include "current_mm.h"
-#endif
+
+/*
+ * Rather than dedicate a register (as the m68k source does), we
+ * just keep a global, we should probably just change it all to be
+ * current and lose _current_task.
+ */
+#include <linux/thread_info.h>
+
+struct task_struct;
+
+static inline struct task_struct *get_current(void)
+{
+ return(current_thread_info()->task);
+}
+
+#define current get_current()
+
+#endif /* CONFNIG_MMU */
+
+#endif /* !(_M68K_CURRENT_H) */
diff --git a/arch/m68k/include/asm/current_mm.h b/arch/m68k/include/asm/current_mm.h
deleted file mode 100644
index 8de8f8ceda6..00000000000
--- a/arch/m68k/include/asm/current_mm.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68K_CURRENT_H
-#define _M68K_CURRENT_H
-
-register struct task_struct *current __asm__("%a2");
-
-#endif /* !(_M68K_CURRENT_H) */
diff --git a/arch/m68k/include/asm/current_no.h b/arch/m68k/include/asm/current_no.h
deleted file mode 100644
index 53ee0f9f7ce..00000000000
--- a/arch/m68k/include/asm/current_no.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _M68KNOMMU_CURRENT_H
-#define _M68KNOMMU_CURRENT_H
-/*
- * current.h
- * (C) Copyright 2000, Lineo, David McCullough <davidm@uclinux.org>
- * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
- *
- * rather than dedicate a register (as the m68k source does), we
- * just keep a global, we should probably just change it all to be
- * current and lose _current_task.
- */
-
-#include <linux/thread_info.h>
-
-struct task_struct;
-
-static inline struct task_struct *get_current(void)
-{
- return(current_thread_info()->task);
-}
-
-#define current get_current()
-
-#endif /* _M68KNOMMU_CURRENT_H */
diff --git a/arch/m68k/include/asm/div64.h b/arch/m68k/include/asm/div64.h
index d211d9f5427..edb66148a71 100644
--- a/arch/m68k/include/asm/div64.h
+++ b/arch/m68k/include/asm/div64.h
@@ -1,5 +1,34 @@
-#ifdef __uClinux__
-#include "div64_no.h"
+#ifndef _M68K_DIV64_H
+#define _M68K_DIV64_H
+
+#ifdef CONFIG_MMU
+
+#include <linux/types.h>
+
+/* n = n / base; return rem; */
+
+#define do_div(n, base) ({ \
+ union { \
+ unsigned long n32[2]; \
+ unsigned long long n64; \
+ } __n; \
+ unsigned long __rem, __upper; \
+ \
+ __n.n64 = (n); \
+ if ((__upper = __n.n32[0])) { \
+ asm ("divul.l %2,%1:%0" \
+ : "=d" (__n.n32[0]), "=d" (__upper) \
+ : "d" (base), "0" (__n.n32[0])); \
+ } \
+ asm ("divu.l %2,%1:%0" \
+ : "=d" (__n.n32[1]), "=d" (__rem) \
+ : "d" (base), "1" (__upper), "0" (__n.n32[1])); \
+ (n) = __n.n64; \
+ __rem; \
+})
+
#else
-#include "div64_mm.h"
-#endif
+#include <asm-generic/div64.h>
+#endif /* CONFIG_MMU */
+
+#endif /* _M68K_DIV64_H */
diff --git a/arch/m68k/include/asm/div64_mm.h b/arch/m68k/include/asm/div64_mm.h
deleted file mode 100644
index 8243c931b5c..00000000000
--- a/arch/m68k/include/asm/div64_mm.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _M68K_DIV64_H
-#define _M68K_DIV64_H
-
-#include <linux/types.h>
-
-/* n = n / base; return rem; */
-
-#define do_div(n, base) ({ \
- union { \
- unsigned long n32[2]; \
- unsigned long long n64; \
- } __n; \
- unsigned long __rem, __upper; \
- \
- __n.n64 = (n); \
- if ((__upper = __n.n32[0])) { \
- asm ("divul.l %2,%1:%0" \
- : "=d" (__n.n32[0]), "=d" (__upper) \
- : "d" (base), "0" (__n.n32[0])); \
- } \
- asm ("divu.l %2,%1:%0" \
- : "=d" (__n.n32[1]), "=d" (__rem) \
- : "d" (base), "1" (__upper), "0" (__n.n32[1])); \
- (n) = __n.n64; \
- __rem; \
-})
-
-#endif /* _M68K_DIV64_H */
diff --git a/arch/m68k/include/asm/dma-mapping.h b/arch/m68k/include/asm/dma-mapping.h
index f4a4c7638f8..26f505488c1 100644
--- a/arch/m68k/include/asm/dma-mapping.h
+++ b/arch/m68k/include/asm/dma-mapping.h
@@ -1,5 +1,112 @@
-#ifdef __uClinux__
-#include "dma-mapping_no.h"
+#ifndef _M68K_DMA_MAPPING_H
+#define _M68K_DMA_MAPPING_H
+
+#include <asm/cache.h>
+
+struct scatterlist;
+
+#ifndef CONFIG_MMU_SUN3
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+ return 1;
+}
+
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+ return 0;
+}
+
+static inline int dma_get_cache_alignment(void)
+{
+ return 1 << L1_CACHE_SHIFT;
+}
+
+static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+extern void *dma_alloc_coherent(struct device *, size_t,
+ dma_addr_t *, gfp_t);
+extern void dma_free_coherent(struct device *, size_t,
+ void *, dma_addr_t);
+
+static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t flag)
+{
+ return dma_alloc_coherent(dev, size, handle, flag);
+}
+static inline void dma_free_noncoherent(struct device *dev, size_t size,
+ void *addr, dma_addr_t handle)
+{
+ dma_free_coherent(dev, size, addr, handle);
+}
+static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+ enum dma_data_direction dir)
+{
+ /* we use coherent allocation, so not much to do here. */
+}
+
+extern dma_addr_t dma_map_single(struct device *, void *, size_t,
+ enum dma_data_direction);
+static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
+ size_t size, enum dma_data_direction dir)
+{
+}
+
+extern dma_addr_t dma_map_page(struct device *, struct page *,
+ unsigned long, size_t size,
+ enum dma_data_direction);
+static inline void dma_unmap_page(struct device *dev, dma_addr_t address,
+ size_t size, enum dma_data_direction dir)
+{
+}
+
+extern int dma_map_sg(struct device *, struct scatterlist *, int,
+ enum dma_data_direction);
+static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nhwentries, enum dma_data_direction dir)
+{
+}
+
+extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t,
+ enum dma_data_direction);
+extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
+ enum dma_data_direction);
+
+static inline void dma_sync_single_range_for_device(struct device *dev,
+ dma_addr_t dma_handle, unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ /* just sync everything for now */
+ dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
+}
+
+static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+}
+
+static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+}
+
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+ dma_addr_t dma_handle, unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ /* just sync everything for now */
+ dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
+}
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
+{
+ return 0;
+}
+
#else
-#include "dma-mapping_mm.h"
+#include <asm-generic/dma-mapping-broken.h>
#endif
+
+#endif /* _M68K_DMA_MAPPING_H */
diff --git a/arch/m68k/include/asm/dma-mapping_mm.h b/arch/m68k/include/asm/dma-mapping_mm.h
deleted file mode 100644
index 26f505488c1..00000000000
--- a/arch/m68k/include/asm/dma-mapping_mm.h
+++ /dev/null
@@ -1,112 +0,0 @@
-#ifndef _M68K_DMA_MAPPING_H
-#define _M68K_DMA_MAPPING_H
-
-#include <asm/cache.h>
-
-struct scatterlist;
-
-#ifndef CONFIG_MMU_SUN3
-static inline int dma_supported(struct device *dev, u64 mask)
-{
- return 1;
-}
-
-static inline int dma_set_mask(struct device *dev, u64 mask)
-{
- return 0;
-}
-
-static inline int dma_get_cache_alignment(void)
-{
- return 1 << L1_CACHE_SHIFT;
-}
-
-static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr)
-{
- return 0;
-}
-
-extern void *dma_alloc_coherent(struct device *, size_t,
- dma_addr_t *, gfp_t);
-extern void dma_free_coherent(struct device *, size_t,
- void *, dma_addr_t);
-
-static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t *handle, gfp_t flag)
-{
- return dma_alloc_coherent(dev, size, handle, flag);
-}
-static inline void dma_free_noncoherent(struct device *dev, size_t size,
- void *addr, dma_addr_t handle)
-{
- dma_free_coherent(dev, size, addr, handle);
-}
-static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
- enum dma_data_direction dir)
-{
- /* we use coherent allocation, so not much to do here. */
-}
-
-extern dma_addr_t dma_map_single(struct device *, void *, size_t,
- enum dma_data_direction);
-static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
- size_t size, enum dma_data_direction dir)
-{
-}
-
-extern dma_addr_t dma_map_page(struct device *, struct page *,
- unsigned long, size_t size,
- enum dma_data_direction);
-static inline void dma_unmap_page(struct device *dev, dma_addr_t address,
- size_t size, enum dma_data_direction dir)
-{
-}
-
-extern int dma_map_sg(struct device *, struct scatterlist *, int,
- enum dma_data_direction);
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nhwentries, enum dma_data_direction dir)
-{
-}
-
-extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t,
- enum dma_data_direction);
-extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
- enum dma_data_direction);
-
-static inline void dma_sync_single_range_for_device(struct device *dev,
- dma_addr_t dma_handle, unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- /* just sync everything for now */
- dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
-}
-
-static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
-}
-
-static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir)
-{
-}
-
-static inline void dma_sync_single_range_for_cpu(struct device *dev,
- dma_addr_t dma_handle, unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- /* just sync everything for now */
- dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
-}
-
-static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
-{
- return 0;
-}
-
-#else
-#include <asm-generic/dma-mapping-broken.h>
-#endif
-
-#endif /* _M68K_DMA_MAPPING_H */
diff --git a/arch/m68k/include/asm/dma-mapping_no.h b/arch/m68k/include/asm/dma-mapping_no.h
deleted file mode 100644
index 1748f2bca94..00000000000
--- a/arch/m68k/include/asm/dma-mapping_no.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68KNOMMU_DMA_MAPPING_H
-#define _M68KNOMMU_DMA_MAPPING_H
-
-#include <asm-generic/dma-mapping-broken.h>
-
-#endif /* _M68KNOMMU_DMA_MAPPING_H */
diff --git a/arch/m68k/include/asm/elf.h b/arch/m68k/include/asm/elf.h
index 04ce488bc63..0b0f49eb876 100644
--- a/arch/m68k/include/asm/elf.h
+++ b/arch/m68k/include/asm/elf.h
@@ -1,5 +1,119 @@
-#ifdef __uClinux__
-#include "elf_no.h"
+#ifndef __ASMm68k_ELF_H
+#define __ASMm68k_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+/*
+ * 68k ELF relocation types
+ */
+#define R_68K_NONE 0
+#define R_68K_32 1
+#define R_68K_16 2
+#define R_68K_8 3
+#define R_68K_PC32 4
+#define R_68K_PC16 5
+#define R_68K_PC8 6
+#define R_68K_GOT32 7
+#define R_68K_GOT16 8
+#define R_68K_GOT8 9
+#define R_68K_GOT32O 10
+#define R_68K_GOT16O 11
+#define R_68K_GOT8O 12
+#define R_68K_PLT32 13
+#define R_68K_PLT16 14
+#define R_68K_PLT8 15
+#define R_68K_PLT32O 16
+#define R_68K_PLT16O 17
+#define R_68K_PLT8O 18
+#define R_68K_COPY 19
+#define R_68K_GLOB_DAT 20
+#define R_68K_JMP_SLOT 21
+#define R_68K_RELATIVE 22
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_m68kfp_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_68K)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2MSB
+#define ELF_ARCH EM_68K
+
+/* For SVR4/m68k the function pointer to be registered with `atexit' is
+ passed in %a1. Although my copy of the ABI has no such statement, it
+ is actually used on ASV. */
+#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0
+
+#define USE_ELF_CORE_DUMP
+#ifndef CONFIG_SUN3
+#define ELF_EXEC_PAGESIZE 4096
#else
-#include "elf_mm.h"
+#define ELF_EXEC_PAGESIZE 8192
+#endif
+
+/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
+ use of this is to invoke "./ld.so someprog" to test out a new version of
+ the loader. We need to make sure that it is out of the way of the program
+ that it will "exec", and that there is sufficient room for the brk. */
+
+#ifndef CONFIG_SUN3
+#define ELF_ET_DYN_BASE 0xD0000000UL
+#else
+#define ELF_ET_DYN_BASE 0x0D800000UL
+#endif
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs) \
+ /* Bleech. */ \
+ pr_reg[0] = regs->d1; \
+ pr_reg[1] = regs->d2; \
+ pr_reg[2] = regs->d3; \
+ pr_reg[3] = regs->d4; \
+ pr_reg[4] = regs->d5; \
+ pr_reg[7] = regs->a0; \
+ pr_reg[8] = regs->a1; \
+ pr_reg[9] = regs->a2; \
+ pr_reg[14] = regs->d0; \
+ pr_reg[15] = rdusp(); \
+ pr_reg[16] = regs->orig_d0; \
+ pr_reg[17] = regs->sr; \
+ pr_reg[18] = regs->pc; \
+ pr_reg[19] = (regs->format << 12) | regs->vector; \
+ { \
+ struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \
+ pr_reg[5] = sw->d6; \
+ pr_reg[6] = sw->d7; \
+ pr_reg[10] = sw->a3; \
+ pr_reg[11] = sw->a4; \
+ pr_reg[12] = sw->a5; \
+ pr_reg[13] = sw->a6; \
+ }
+
+/* This yields a mask that user programs can use to figure out what
+ instruction set this cpu supports. */
+
+#define ELF_HWCAP (0)
+
+/* This yields a string that ld.so will use to load implementation
+ specific libraries for optimization. This is more specific in
+ intent than poking at uname or /proc/cpuinfo. */
+
+#define ELF_PLATFORM (NULL)
+
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+
#endif
diff --git a/arch/m68k/include/asm/elf_mm.h b/arch/m68k/include/asm/elf_mm.h
deleted file mode 100644
index 0b0f49eb876..00000000000
--- a/arch/m68k/include/asm/elf_mm.h
+++ /dev/null
@@ -1,119 +0,0 @@
-#ifndef __ASMm68k_ELF_H
-#define __ASMm68k_ELF_H
-
-/*
- * ELF register definitions..
- */
-
-#include <asm/ptrace.h>
-#include <asm/user.h>
-
-/*
- * 68k ELF relocation types
- */
-#define R_68K_NONE 0
-#define R_68K_32 1
-#define R_68K_16 2
-#define R_68K_8 3
-#define R_68K_PC32 4
-#define R_68K_PC16 5
-#define R_68K_PC8 6
-#define R_68K_GOT32 7
-#define R_68K_GOT16 8
-#define R_68K_GOT8 9
-#define R_68K_GOT32O 10
-#define R_68K_GOT16O 11
-#define R_68K_GOT8O 12
-#define R_68K_PLT32 13
-#define R_68K_PLT16 14
-#define R_68K_PLT8 15
-#define R_68K_PLT32O 16
-#define R_68K_PLT16O 17
-#define R_68K_PLT8O 18
-#define R_68K_COPY 19
-#define R_68K_GLOB_DAT 20
-#define R_68K_JMP_SLOT 21
-#define R_68K_RELATIVE 22
-
-typedef unsigned long elf_greg_t;
-
-#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct user_m68kfp_struct elf_fpregset_t;
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ((x)->e_machine == EM_68K)
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS ELFCLASS32
-#define ELF_DATA ELFDATA2MSB
-#define ELF_ARCH EM_68K
-
-/* For SVR4/m68k the function pointer to be registered with `atexit' is
- passed in %a1. Although my copy of the ABI has no such statement, it
- is actually used on ASV. */
-#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0
-
-#define USE_ELF_CORE_DUMP
-#ifndef CONFIG_SUN3
-#define ELF_EXEC_PAGESIZE 4096
-#else
-#define ELF_EXEC_PAGESIZE 8192
-#endif
-
-/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
- use of this is to invoke "./ld.so someprog" to test out a new version of
- the loader. We need to make sure that it is out of the way of the program
- that it will "exec", and that there is sufficient room for the brk. */
-
-#ifndef CONFIG_SUN3
-#define ELF_ET_DYN_BASE 0xD0000000UL
-#else
-#define ELF_ET_DYN_BASE 0x0D800000UL
-#endif
-
-#define ELF_CORE_COPY_REGS(pr_reg, regs) \
- /* Bleech. */ \
- pr_reg[0] = regs->d1; \
- pr_reg[1] = regs->d2; \
- pr_reg[2] = regs->d3; \
- pr_reg[3] = regs->d4; \
- pr_reg[4] = regs->d5; \
- pr_reg[7] = regs->a0; \
- pr_reg[8] = regs->a1; \
- pr_reg[9] = regs->a2; \
- pr_reg[14] = regs->d0; \
- pr_reg[15] = rdusp(); \
- pr_reg[16] = regs->orig_d0; \
- pr_reg[17] = regs->sr; \
- pr_reg[18] = regs->pc; \
- pr_reg[19] = (regs->format << 12) | regs->vector; \
- { \
- struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \
- pr_reg[5] = sw->d6; \
- pr_reg[6] = sw->d7; \
- pr_reg[10] = sw->a3; \
- pr_reg[11] = sw->a4; \
- pr_reg[12] = sw->a5; \
- pr_reg[13] = sw->a6; \
- }
-
-/* This yields a mask that user programs can use to figure out what
- instruction set this cpu supports. */
-
-#define ELF_HWCAP (0)
-
-/* This yields a string that ld.so will use to load implementation
- specific libraries for optimization. This is more specific in
- intent than poking at uname or /proc/cpuinfo. */
-
-#define ELF_PLATFORM (NULL)
-
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
-
-#endif
diff --git a/arch/m68k/include/asm/elf_no.h b/arch/m68k/include/asm/elf_no.h
deleted file mode 100644
index b8046837f38..00000000000
--- a/arch/m68k/include/asm/elf_no.h
+++ /dev/null
@@ -1,110 +0,0 @@
-#ifndef __ASMm68k_ELF_H
-#define __ASMm68k_ELF_H
-
-/*
- * ELF register definitions..
- */
-
-#include <asm/ptrace.h>
-#include <asm/user.h>
-
-/*
- * 68k ELF relocation types
- */
-#define R_68K_NONE 0
-#define R_68K_32 1
-#define R_68K_16 2
-#define R_68K_8 3
-#define R_68K_PC32 4
-#define R_68K_PC16 5
-#define R_68K_PC8 6
-#define R_68K_GOT32 7
-#define R_68K_GOT16 8
-#define R_68K_GOT8 9
-#define R_68K_GOT32O 10
-#define R_68K_GOT16O 11
-#define R_68K_GOT8O 12
-#define R_68K_PLT32 13
-#define R_68K_PLT16 14
-#define R_68K_PLT8 15
-#define R_68K_PLT32O 16
-#define R_68K_PLT16O 17
-#define R_68K_PLT8O 18
-#define R_68K_COPY 19
-#define R_68K_GLOB_DAT 20
-#define R_68K_JMP_SLOT 21
-#define R_68K_RELATIVE 22
-
-typedef unsigned long elf_greg_t;
-
-#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct user_m68kfp_struct elf_fpregset_t;
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ((x)->e_machine == EM_68K)
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS ELFCLASS32
-#define ELF_DATA ELFDATA2MSB
-#define ELF_ARCH EM_68K
-
-/* For SVR4/m68k the function pointer to be registered with `atexit' is
- passed in %a1. Although my copy of the ABI has no such statement, it
- is actually used on ASV. */
-#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0
-
-#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE 4096
-
-/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
- use of this is to invoke "./ld.so someprog" to test out a new version of
- the loader. We need to make sure that it is out of the way of the program
- that it will "exec", and that there is sufficient room for the brk. */
-
-#define ELF_ET_DYN_BASE 0xD0000000UL
-
-#define ELF_CORE_COPY_REGS(pr_reg, regs) \
- /* Bleech. */ \
- pr_reg[0] = regs->d1; \
- pr_reg[1] = regs->d2; \
- pr_reg[2] = regs->d3; \
- pr_reg[3] = regs->d4; \
- pr_reg[4] = regs->d5; \
- pr_reg[7] = regs->a0; \
- pr_reg[8] = regs->a1; \
- pr_reg[14] = regs->d0; \
- pr_reg[15] = rdusp(); \
- pr_reg[16] = 0 /* regs->orig_d0 */; \
- pr_reg[17] = regs->sr; \
- pr_reg[18] = regs->pc; \
- /* pr_reg[19] = (regs->format << 12) | regs->vector; */ \
- { \
- struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \
- pr_reg[5] = sw->d6; \
- pr_reg[6] = sw->d7; \
- pr_reg[10] = sw->a3; \
- pr_reg[11] = sw->a4; \
- pr_reg[12] = sw->a5; \
- pr_reg[13] = sw->a6; \
- }
-
-/* This yields a mask that user programs can use to figure out what
- instruction set this cpu supports. */
-
-#define ELF_HWCAP (0)
-
-/* This yields a string that ld.so will use to load implementation
- specific libraries for optimization. This is more specific in
- intent than poking at uname or /proc/cpuinfo. */
-
-#define ELF_PLATFORM (NULL)
-
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
-
-#endif
diff --git a/arch/m68k/include/asm/fb.h b/arch/m68k/include/asm/fb.h
index 97bcaefd206..be4e4c6797e 100644
--- a/arch/m68k/include/asm/fb.h
+++ b/arch/m68k/include/asm/fb.h
@@ -1,5 +1,38 @@
-#ifdef __uClinux__
-#include "fb_no.h"
+#ifndef _ASM_FB_H_
+#define _ASM_FB_H_
+
+#include <linux/fb.h>
+#include <linux/fs.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_MMU
+#ifdef CONFIG_SUN3
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+ unsigned long off)
+{
+ pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE;
+}
#else
-#include "fb_mm.h"
-#endif
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+ unsigned long off)
+{
+ if (CPU_IS_020_OR_030)
+ pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
+ if (CPU_IS_040_OR_060) {
+ pgprot_val(vma->vm_page_prot) &= _CACHEMASK040;
+ /* Use no-cache mode, serialized */
+ pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S;
+ }
+}
+#endif /* CONFIG_SUN3 */
+#else
+#define fb_pgprotect(...) do {} while (0)
+#endif /* CONFIG_MMU */
+
+static inline int fb_is_primary_device(struct fb_info *info)
+{
+ return 0;
+}
+
+#endif /* _ASM_FB_H_ */
diff --git a/arch/m68k/include/asm/fb_mm.h b/arch/m68k/include/asm/fb_mm.h
deleted file mode 100644
index 380b97ae815..00000000000
--- a/arch/m68k/include/asm/fb_mm.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-
-#ifdef CONFIG_SUN3
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
-{
- pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE;
-}
-#else
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
-{
- if (CPU_IS_020_OR_030)
- pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
- if (CPU_IS_040_OR_060) {
- pgprot_val(vma->vm_page_prot) &= _CACHEMASK040;
- /* Use no-cache mode, serialized */
- pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S;
- }
-}
-#endif /* CONFIG_SUN3 */
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
- return 0;
-}
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/m68k/include/asm/fb_no.h b/arch/m68k/include/asm/fb_no.h
deleted file mode 100644
index c7df3803099..00000000000
--- a/arch/m68k/include/asm/fb_no.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-#include <linux/fb.h>
-
-#define fb_pgprotect(...) do {} while (0)
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
- return 0;
-}
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/m68k/include/asm/fpu.h b/arch/m68k/include/asm/fpu.h
index e19bc5ed9c3..ffb6b8cfc6d 100644
--- a/arch/m68k/include/asm/fpu.h
+++ b/arch/m68k/include/asm/fpu.h
@@ -1,5 +1,21 @@
-#ifdef __uClinux__
-#include "fpu_no.h"
+#ifndef __M68K_FPU_H
+#define __M68K_FPU_H
+
+
+/*
+ * MAX floating point unit state size (FSAVE/FRESTORE)
+ */
+
+#if defined(CONFIG_M68020) || defined(CONFIG_M68030)
+#define FPSTATESIZE (216)
+#elif defined(CONFIG_M68040)
+#define FPSTATESIZE (96)
+#elif defined(CONFIG_M68KFPU_EMU)
+#define FPSTATESIZE (28)
+#elif defined(CONFIG_M68060)
+#define FPSTATESIZE (12)
#else
-#include "fpu_mm.h"
+#define FPSTATESIZE (0)
#endif
+
+#endif /* __M68K_FPU_H */
diff --git a/arch/m68k/include/asm/fpu_mm.h b/arch/m68k/include/asm/fpu_mm.h
deleted file mode 100644
index ffb6b8cfc6d..00000000000
--- a/arch/m68k/include/asm/fpu_mm.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __M68K_FPU_H
-#define __M68K_FPU_H
-
-
-/*
- * MAX floating point unit state size (FSAVE/FRESTORE)
- */
-
-#if defined(CONFIG_M68020) || defined(CONFIG_M68030)
-#define FPSTATESIZE (216)
-#elif defined(CONFIG_M68040)
-#define FPSTATESIZE (96)
-#elif defined(CONFIG_M68KFPU_EMU)
-#define FPSTATESIZE (28)
-#elif defined(CONFIG_M68060)
-#define FPSTATESIZE (12)
-#else
-#define FPSTATESIZE (0)
-#endif
-
-#endif /* __M68K_FPU_H */
diff --git a/arch/m68k/include/asm/fpu_no.h b/arch/m68k/include/asm/fpu_no.h
deleted file mode 100644
index b16b2e4fca2..00000000000
--- a/arch/m68k/include/asm/fpu_no.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __M68KNOMMU_FPU_H
-#define __M68KNOMMU_FPU_H
-
-
-/*
- * MAX floating point unit state size (FSAVE/FRESTORE)
- */
-#if defined(CONFIG_M68020) || defined(CONFIG_M68030)
-#define FPSTATESIZE (216/sizeof(unsigned char))
-#elif defined(CONFIG_M68040)
-#define FPSTATESIZE (96/sizeof(unsigned char))
-#elif defined(CONFIG_M68KFPU_EMU)
-#define FPSTATESIZE (28/sizeof(unsigned char))
-#elif defined(CONFIG_M68060)
-#define FPSTATESIZE (12/sizeof(unsigned char))
-#else
-/* Assume no FP unit present then... */
-#define FPSTATESIZE (2) /* dummy size */
-#endif
-
-#endif /* __M68K_FPU_H */
diff --git a/arch/m68k/include/asm/ftrace.h b/arch/m68k/include/asm/ftrace.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/m68k/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/m68k/include/asm/hw_irq.h b/arch/m68k/include/asm/hw_irq.h
index e1952601589..eacef0951fb 100644
--- a/arch/m68k/include/asm/hw_irq.h
+++ b/arch/m68k/include/asm/hw_irq.h
@@ -1,5 +1,6 @@
-#ifdef __uClinux__
-#include "hw_irq_no.h"
-#else
-#include "hw_irq_mm.h"
+#ifndef __ASM_M68K_HW_IRQ_H
+#define __ASM_M68K_HW_IRQ_H
+
+/* Dummy include. */
+
#endif
diff --git a/arch/m68k/include/asm/hw_irq_mm.h b/arch/m68k/include/asm/hw_irq_mm.h
deleted file mode 100644
index eacef0951fb..00000000000
--- a/arch/m68k/include/asm/hw_irq_mm.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ASM_M68K_HW_IRQ_H
-#define __ASM_M68K_HW_IRQ_H
-
-/* Dummy include. */
-
-#endif
diff --git a/arch/m68k/include/asm/hw_irq_no.h b/arch/m68k/include/asm/hw_irq_no.h
deleted file mode 100644
index f3ec9e5ae04..00000000000
--- a/arch/m68k/include/asm/hw_irq_no.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __M68KNOMMU_HW_IRQ_H__
-#define __M68KNOMMU_HW_IRQ_H__
-
-#endif /* __M68KNOMMU_HW_IRQ_H__ */
diff --git a/arch/m68k/include/asm/kmap_types.h b/arch/m68k/include/asm/kmap_types.h
index 045d9fd122a..c843c63d380 100644
--- a/arch/m68k/include/asm/kmap_types.h
+++ b/arch/m68k/include/asm/kmap_types.h
@@ -1,5 +1,21 @@
-#ifdef __uClinux__
-#include "kmap_types_no.h"
-#else
-#include "kmap_types_mm.h"
-#endif
+#ifndef __ASM_M68K_KMAP_TYPES_H
+#define __ASM_M68K_KMAP_TYPES_H
+
+enum km_type {
+ KM_BOUNCE_READ,
+ KM_SKB_SUNRPC_DATA,
+ KM_SKB_DATA_SOFTIRQ,
+ KM_USER0,
+ KM_USER1,
+ KM_BIO_SRC_IRQ,
+ KM_BIO_DST_IRQ,
+ KM_PTE0,
+ KM_PTE1,
+ KM_IRQ0,
+ KM_IRQ1,
+ KM_SOFTIRQ0,
+ KM_SOFTIRQ1,
+ KM_TYPE_NR
+};
+
+#endif /* __ASM_M68K_KMAP_TYPES_H */
diff --git a/arch/m68k/include/asm/kmap_types_mm.h b/arch/m68k/include/asm/kmap_types_mm.h
deleted file mode 100644
index c843c63d380..00000000000
--- a/arch/m68k/include/asm/kmap_types_mm.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __ASM_M68K_KMAP_TYPES_H
-#define __ASM_M68K_KMAP_TYPES_H
-
-enum km_type {
- KM_BOUNCE_READ,
- KM_SKB_SUNRPC_DATA,
- KM_SKB_DATA_SOFTIRQ,
- KM_USER0,
- KM_USER1,
- KM_BIO_SRC_IRQ,
- KM_BIO_DST_IRQ,
- KM_PTE0,
- KM_PTE1,
- KM_IRQ0,
- KM_IRQ1,
- KM_SOFTIRQ0,
- KM_SOFTIRQ1,
- KM_TYPE_NR
-};
-
-#endif /* __ASM_M68K_KMAP_TYPES_H */
diff --git a/arch/m68k/include/asm/kmap_types_no.h b/arch/m68k/include/asm/kmap_types_no.h
deleted file mode 100644
index bfb6707575d..00000000000
--- a/arch/m68k/include/asm/kmap_types_no.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __ASM_M68K_KMAP_TYPES_H
-#define __ASM_M68K_KMAP_TYPES_H
-
-enum km_type {
- KM_BOUNCE_READ,
- KM_SKB_SUNRPC_DATA,
- KM_SKB_DATA_SOFTIRQ,
- KM_USER0,
- KM_USER1,
- KM_BIO_SRC_IRQ,
- KM_BIO_DST_IRQ,
- KM_PTE0,
- KM_PTE1,
- KM_IRQ0,
- KM_IRQ1,
- KM_SOFTIRQ0,
- KM_SOFTIRQ1,
- KM_TYPE_NR
-};
-
-#endif
diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h
index 1835fd20a82..ce603451b55 100644
--- a/arch/m68k/include/asm/m532xsim.h
+++ b/arch/m68k/include/asm/m532xsim.h
@@ -16,6 +16,7 @@
#define MCFINT_VECBASE 64
#define MCFINT_UART0 26 /* Interrupt number for UART0 */
#define MCFINT_UART1 27 /* Interrupt number for UART1 */
+#define MCFINT_UART2 28 /* Interrupt number for UART2 */
#define MCF_WTM_WCR MCF_REG16(0xFC098000)
diff --git a/arch/m68k/include/asm/mc146818rtc.h b/arch/m68k/include/asm/mc146818rtc.h
index fb90dcf7842..9f70a01f73d 100644
--- a/arch/m68k/include/asm/mc146818rtc.h
+++ b/arch/m68k/include/asm/mc146818rtc.h
@@ -1,5 +1,26 @@
-#ifdef __uClinux__
-#include "mc146818rtc_no.h"
-#else
-#include "mc146818rtc_mm.h"
-#endif
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+
+#ifdef CONFIG_ATARI
+/* RTC in Atari machines */
+
+#include <asm/atarihw.h>
+
+#define RTC_PORT(x) (TT_RTC_BAS + 2*(x))
+#define RTC_ALWAYS_BCD 0
+
+#define CMOS_READ(addr) ({ \
+atari_outb_p((addr),RTC_PORT(0)); \
+atari_inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+atari_outb_p((addr),RTC_PORT(0)); \
+atari_outb_p((val),RTC_PORT(1)); \
+})
+#endif /* CONFIG_ATARI */
+
+#endif /* _ASM_MC146818RTC_H */
diff --git a/arch/m68k/include/asm/mc146818rtc_mm.h b/arch/m68k/include/asm/mc146818rtc_mm.h
deleted file mode 100644
index 9f70a01f73d..00000000000
--- a/arch/m68k/include/asm/mc146818rtc_mm.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Machine dependent access functions for RTC registers.
- */
-#ifndef _ASM_MC146818RTC_H
-#define _ASM_MC146818RTC_H
-
-
-#ifdef CONFIG_ATARI
-/* RTC in Atari machines */
-
-#include <asm/atarihw.h>
-
-#define RTC_PORT(x) (TT_RTC_BAS + 2*(x))
-#define RTC_ALWAYS_BCD 0
-
-#define CMOS_READ(addr) ({ \
-atari_outb_p((addr),RTC_PORT(0)); \
-atari_inb_p(RTC_PORT(1)); \
-})
-#define CMOS_WRITE(val, addr) ({ \
-atari_outb_p((addr),RTC_PORT(0)); \
-atari_outb_p((val),RTC_PORT(1)); \
-})
-#endif /* CONFIG_ATARI */
-
-#endif /* _ASM_MC146818RTC_H */
diff --git a/arch/m68k/include/asm/mc146818rtc_no.h b/arch/m68k/include/asm/mc146818rtc_no.h
deleted file mode 100644
index 907a0481a14..00000000000
--- a/arch/m68k/include/asm/mc146818rtc_no.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Machine dependent access functions for RTC registers.
- */
-#ifndef _M68KNOMMU_MC146818RTC_H
-#define _M68KNOMMU_MC146818RTC_H
-
-/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
-
-#endif /* _M68KNOMMU_MC146818RTC_H */
diff --git a/arch/m68k/include/asm/mcfpci.h b/arch/m68k/include/asm/mcfpci.h
deleted file mode 100644
index f1507dd06ec..00000000000
--- a/arch/m68k/include/asm/mcfpci.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************/
-
-/*
- * mcfpci.h -- PCI bridge on ColdFire eval boards.
- *
- * (C) Copyright 2000, Greg Ungerer (gerg@snapgear.com)
- * (C) Copyright 2000, Lineo Inc. (www.lineo.com)
- */
-
-/****************************************************************************/
-#ifndef mcfpci_h
-#define mcfpci_h
-/****************************************************************************/
-
-
-#ifdef CONFIG_PCI
-
-/*
- * Address regions in the PCI address space are not mapped into the
- * normal memory space of the ColdFire. They must be accessed via
- * handler routines. This is easy for I/O space (inb/outb/etc) but
- * needs some code changes to support ordinary memory. Interrupts
- * also need to be vectored through the PCI handler first, then it
- * will call the actual driver sub-handlers.
- */
-
-/*
- * Un-define all the standard I/O access routines.
- */
-#undef inb
-#undef inw
-#undef inl
-#undef inb_p
-#undef inw_p
-#undef insb
-#undef insw
-#undef insl
-#undef outb
-#undef outw
-#undef outl
-#undef outb_p
-#undef outw_p
-#undef outsb
-#undef outsw
-#undef outsl
-
-#undef request_irq
-#undef free_irq
-
-#undef bus_to_virt
-#undef virt_to_bus
-
-
-/*
- * Re-direct all I/O memory accesses functions to PCI specific ones.
- */
-#define inb pci_inb
-#define inw pci_inw
-#define inl pci_inl
-#define inb_p pci_inb
-#define inw_p pci_inw
-#define insb pci_insb
-#define insw pci_insw
-#define insl pci_insl
-
-#define outb pci_outb
-#define outw pci_outw
-#define outl pci_outl
-#define outb_p pci_outb
-#define outw_p pci_outw
-#define outsb pci_outsb
-#define outsw pci_outsw
-#define outsl pci_outsl
-
-#define request_irq pci_request_irq
-#define free_irq pci_free_irq
-
-#define virt_to_bus pci_virt_to_bus
-#define bus_to_virt pci_bus_to_virt
-
-#define CONFIG_COMEMPCI 1
-
-
-/*
- * Prototypes of the real PCI functions (defined in bios32.c).
- */
-unsigned char pci_inb(unsigned int addr);
-unsigned short pci_inw(unsigned int addr);
-unsigned int pci_inl(unsigned int addr);
-void pci_insb(void *addr, void *buf, int len);
-void pci_insw(void *addr, void *buf, int len);
-void pci_insl(void *addr, void *buf, int len);
-
-void pci_outb(unsigned char val, unsigned int addr);
-void pci_outw(unsigned short val, unsigned int addr);
-void pci_outl(unsigned int val, unsigned int addr);
-void pci_outsb(void *addr, void *buf, int len);
-void pci_outsw(void *addr, void *buf, int len);
-void pci_outsl(void *addr, void *buf, int len);
-
-int pci_request_irq(unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
- unsigned long flags,
- const char *device,
- void *dev_id);
-void pci_free_irq(unsigned int irq, void *dev_id);
-
-void *pci_bmalloc(int size);
-void pci_bmfree(void *bmp, int len);
-void pci_copytoshmem(unsigned long bmp, void *src, int size);
-void pci_copyfromshmem(void *dst, unsigned long bmp, int size);
-unsigned long pci_virt_to_bus(volatile void *address);
-void *pci_bus_to_virt(unsigned long address);
-void pci_bmcpyto(void *dst, void *src, int len);
-void pci_bmcpyfrom(void *dst, void *src, int len);
-
-#endif /* CONFIG_PCI */
-/****************************************************************************/
-#endif /* mcfpci_h */
diff --git a/arch/m68k/include/asm/mmu.h b/arch/m68k/include/asm/mmu.h
index a81d3946675..8a11a63ee15 100644
--- a/arch/m68k/include/asm/mmu.h
+++ b/arch/m68k/include/asm/mmu.h
@@ -1,5 +1,13 @@
-#ifdef __uClinux__
-#include "mmu_no.h"
+#ifndef __MMU_H
+#define __MMU_H
+
+#ifdef CONFIG_MMU
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
#else
-#include "mmu_mm.h"
+typedef struct {
+ unsigned long end_brk;
+} mm_context_t;
+#endif
+
#endif
diff --git a/arch/m68k/include/asm/mmu_context.h b/arch/m68k/include/asm/mmu_context.h
index b440928fc6c..7d4341e55a9 100644
--- a/arch/m68k/include/asm/mmu_context.h
+++ b/arch/m68k/include/asm/mmu_context.h
@@ -1,5 +1,175 @@
-#ifdef __uClinux__
-#include "mmu_context_no.h"
+#ifndef __M68K_MMU_CONTEXT_H
+#define __M68K_MMU_CONTEXT_H
+
+#include <asm-generic/mm_hooks.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+static inline int init_new_context(struct task_struct *tsk,
+ struct mm_struct *mm)
+{
+ mm->context = virt_to_phys(mm->pgd);
+ return 0;
+}
+
+#define destroy_context(mm) do { } while(0)
+
+static inline void switch_mm_0230(struct mm_struct *mm)
+{
+ unsigned long crp[2] = {
+ 0x80000000 | _PAGE_TABLE, mm->context
+ };
+ unsigned long tmp;
+
+ asm volatile (".chip 68030");
+
+ /* flush MC68030/MC68020 caches (they are virtually addressed) */
+ asm volatile (
+ "movec %%cacr,%0;"
+ "orw %1,%0; "
+ "movec %0,%%cacr"
+ : "=d" (tmp) : "di" (FLUSH_I_AND_D));
+
+ /* Switch the root pointer. For a 030-only kernel,
+ * avoid flushing the whole ATC, we only need to
+ * flush the user entries. The 68851 does this by
+ * itself. Avoid a runtime check here.
+ */
+ asm volatile (
+#ifdef CPU_M68030_ONLY
+ "pmovefd %0,%%crp; "
+ "pflush #0,#4"
#else
-#include "mmu_context_mm.h"
+ "pmove %0,%%crp"
#endif
+ : : "m" (crp[0]));
+
+ asm volatile (".chip 68k");
+}
+
+static inline void switch_mm_0460(struct mm_struct *mm)
+{
+ asm volatile (".chip 68040");
+
+ /* flush address translation cache (user entries) */
+ asm volatile ("pflushan");
+
+ /* switch the root pointer */
+ asm volatile ("movec %0,%%urp" : : "r" (mm->context));
+
+ if (CPU_IS_060) {
+ unsigned long tmp;
+
+ /* clear user entries in the branch cache */
+ asm volatile (
+ "movec %%cacr,%0; "
+ "orl %1,%0; "
+ "movec %0,%%cacr"
+ : "=d" (tmp): "di" (0x00200000));
+ }
+
+ asm volatile (".chip 68k");
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
+{
+ if (prev != next) {
+ if (CPU_IS_020_OR_030)
+ switch_mm_0230(next);
+ else
+ switch_mm_0460(next);
+ }
+}
+
+#define deactivate_mm(tsk,mm) do { } while (0)
+
+static inline void activate_mm(struct mm_struct *prev_mm,
+ struct mm_struct *next_mm)
+{
+ next_mm->context = virt_to_phys(next_mm->pgd);
+
+ if (CPU_IS_020_OR_030)
+ switch_mm_0230(next_mm);
+ else
+ switch_mm_0460(next_mm);
+}
+
+#else /* CONFIG_SUN3 */
+#include <asm/sun3mmu.h>
+#include <linux/sched.h>
+
+extern unsigned long get_free_context(struct mm_struct *mm);
+extern void clear_context(unsigned long context);
+
+/* set the context for a new task to unmapped */
+static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ mm->context = SUN3_INVALID_CONTEXT;
+ return 0;
+}
+
+/* find the context given to this process, and if it hasn't already
+ got one, go get one for it. */
+static inline void get_mmu_context(struct mm_struct *mm)
+{
+ if(mm->context == SUN3_INVALID_CONTEXT)
+ mm->context = get_free_context(mm);
+}
+
+/* flush context if allocated... */
+static inline void destroy_context(struct mm_struct *mm)
+{
+ if(mm->context != SUN3_INVALID_CONTEXT)
+ clear_context(mm->context);
+}
+
+static inline void activate_context(struct mm_struct *mm)
+{
+ get_mmu_context(mm);
+ sun3_put_context(mm->context);
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
+{
+ activate_context(tsk->mm);
+}
+
+#define deactivate_mm(tsk,mm) do { } while (0)
+
+static inline void activate_mm(struct mm_struct *prev_mm,
+ struct mm_struct *next_mm)
+{
+ activate_context(next_mm);
+}
+
+#endif
+#else /* !CONFIG_MMU */
+
+static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ return 0;
+}
+
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
+{
+}
+
+#define destroy_context(mm) do { } while (0)
+#define deactivate_mm(tsk,mm) do { } while (0)
+
+static inline void activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
+{
+}
+
+#endif /* CONFIG_MMU */
+#endif /* __M68K_MMU_CONTEXT_H */
diff --git a/arch/m68k/include/asm/mmu_context_mm.h b/arch/m68k/include/asm/mmu_context_mm.h
deleted file mode 100644
index 894dacbcee1..00000000000
--- a/arch/m68k/include/asm/mmu_context_mm.h
+++ /dev/null
@@ -1,154 +0,0 @@
-#ifndef __M68K_MMU_CONTEXT_H
-#define __M68K_MMU_CONTEXT_H
-
-#include <asm-generic/mm_hooks.h>
-
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-{
-}
-
-#ifndef CONFIG_SUN3
-
-#include <asm/setup.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-
-static inline int init_new_context(struct task_struct *tsk,
- struct mm_struct *mm)
-{
- mm->context = virt_to_phys(mm->pgd);
- return 0;
-}
-
-#define destroy_context(mm) do { } while(0)
-
-static inline void switch_mm_0230(struct mm_struct *mm)
-{
- unsigned long crp[2] = {
- 0x80000000 | _PAGE_TABLE, mm->context
- };
- unsigned long tmp;
-
- asm volatile (".chip 68030");
-
- /* flush MC68030/MC68020 caches (they are virtually addressed) */
- asm volatile (
- "movec %%cacr,%0;"
- "orw %1,%0; "
- "movec %0,%%cacr"
- : "=d" (tmp) : "di" (FLUSH_I_AND_D));
-
- /* Switch the root pointer. For a 030-only kernel,
- * avoid flushing the whole ATC, we only need to
- * flush the user entries. The 68851 does this by
- * itself. Avoid a runtime check here.
- */
- asm volatile (
-#ifdef CPU_M68030_ONLY
- "pmovefd %0,%%crp; "
- "pflush #0,#4"
-#else
- "pmove %0,%%crp"
-#endif
- : : "m" (crp[0]));
-
- asm volatile (".chip 68k");
-}
-
-static inline void switch_mm_0460(struct mm_struct *mm)
-{
- asm volatile (".chip 68040");
-
- /* flush address translation cache (user entries) */
- asm volatile ("pflushan");
-
- /* switch the root pointer */
- asm volatile ("movec %0,%%urp" : : "r" (mm->context));
-
- if (CPU_IS_060) {
- unsigned long tmp;
-
- /* clear user entries in the branch cache */
- asm volatile (
- "movec %%cacr,%0; "
- "orl %1,%0; "
- "movec %0,%%cacr"
- : "=d" (tmp): "di" (0x00200000));
- }
-
- asm volatile (".chip 68k");
-}
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
-{
- if (prev != next) {
- if (CPU_IS_020_OR_030)
- switch_mm_0230(next);
- else
- switch_mm_0460(next);
- }
-}
-
-#define deactivate_mm(tsk,mm) do { } while (0)
-
-static inline void activate_mm(struct mm_struct *prev_mm,
- struct mm_struct *next_mm)
-{
- next_mm->context = virt_to_phys(next_mm->pgd);
-
- if (CPU_IS_020_OR_030)
- switch_mm_0230(next_mm);
- else
- switch_mm_0460(next_mm);
-}
-
-#else /* CONFIG_SUN3 */
-#include <asm/sun3mmu.h>
-#include <linux/sched.h>
-
-extern unsigned long get_free_context(struct mm_struct *mm);
-extern void clear_context(unsigned long context);
-
-/* set the context for a new task to unmapped */
-static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-{
- mm->context = SUN3_INVALID_CONTEXT;
- return 0;
-}
-
-/* find the context given to this process, and if it hasn't already
- got one, go get one for it. */
-static inline void get_mmu_context(struct mm_struct *mm)
-{
- if(mm->context == SUN3_INVALID_CONTEXT)
- mm->context = get_free_context(mm);
-}
-
-/* flush context if allocated... */
-static inline void destroy_context(struct mm_struct *mm)
-{
- if(mm->context != SUN3_INVALID_CONTEXT)
- clear_context(mm->context);
-}
-
-static inline void activate_context(struct mm_struct *mm)
-{
- get_mmu_context(mm);
- sun3_put_context(mm->context);
-}
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
-{
- activate_context(tsk->mm);
-}
-
-#define deactivate_mm(tsk,mm) do { } while (0)
-
-static inline void activate_mm(struct mm_struct *prev_mm,
- struct mm_struct *next_mm)
-{
- activate_context(next_mm);
-}
-
-#endif
-#endif
diff --git a/arch/m68k/include/asm/mmu_context_no.h b/arch/m68k/include/asm/mmu_context_no.h
deleted file mode 100644
index 9ccee4278c9..00000000000
--- a/arch/m68k/include/asm/mmu_context_no.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __M68KNOMMU_MMU_CONTEXT_H
-#define __M68KNOMMU_MMU_CONTEXT_H
-
-#include <asm/setup.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-#include <asm-generic/mm_hooks.h>
-
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-{
-}
-
-static inline int
-init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-{
- // mm->context = virt_to_phys(mm->pgd);
- return(0);
-}
-
-#define destroy_context(mm) do { } while(0)
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
-{
-}
-
-#define deactivate_mm(tsk,mm) do { } while (0)
-
-static inline void activate_mm(struct mm_struct *prev_mm,
- struct mm_struct *next_mm)
-{
-}
-
-#endif
diff --git a/arch/m68k/include/asm/mmu_mm.h b/arch/m68k/include/asm/mmu_mm.h
deleted file mode 100644
index ccd36d26615..00000000000
--- a/arch/m68k/include/asm/mmu_mm.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __MMU_H
-#define __MMU_H
-
-/* Default "unsigned long" context */
-typedef unsigned long mm_context_t;
-
-#endif
diff --git a/arch/m68k/include/asm/mmu_no.h b/arch/m68k/include/asm/mmu_no.h
deleted file mode 100644
index e2da1e6f09f..00000000000
--- a/arch/m68k/include/asm/mmu_no.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __M68KNOMMU_MMU_H
-#define __M68KNOMMU_MMU_H
-
-/* Copyright (C) 2002, David McCullough <davidm@snapgear.com> */
-
-typedef struct {
- unsigned long end_brk;
-} mm_context_t;
-
-#endif /* __M68KNOMMU_MMU_H */
diff --git a/arch/m68k/include/asm/module.h b/arch/m68k/include/asm/module.h
index 79b59d137dd..5f21e11071b 100644
--- a/arch/m68k/include/asm/module.h
+++ b/arch/m68k/include/asm/module.h
@@ -1,5 +1,48 @@
-#ifdef __uClinux__
-#include "module_no.h"
+#ifndef _ASM_M68K_MODULE_H
+#define _ASM_M68K_MODULE_H
+
+#ifdef CONFIG_MMU
+
+struct mod_arch_specific {
+ struct m68k_fixup_info *fixup_start, *fixup_end;
+};
+
+#define MODULE_ARCH_INIT { \
+ .fixup_start = __start_fixup, \
+ .fixup_end = __stop_fixup, \
+}
+
+
+enum m68k_fixup_type {
+ m68k_fixup_memoffset,
+ m68k_fixup_vnode_shift,
+};
+
+struct m68k_fixup_info {
+ enum m68k_fixup_type type;
+ void *addr;
+};
+
+#define m68k_fixup(type, addr) \
+ " .section \".m68k_fixup\",\"aw\"\n" \
+ " .long " #type "," #addr "\n" \
+ " .previous\n"
+
+extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
+
+struct module;
+extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
+ struct m68k_fixup_info *end);
+
#else
-#include "module_mm.h"
-#endif
+
+struct mod_arch_specific {
+};
+
+#endif /* CONFIG_MMU */
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+
+#endif /* _ASM_M68K_MODULE_H */
diff --git a/arch/m68k/include/asm/module_mm.h b/arch/m68k/include/asm/module_mm.h
deleted file mode 100644
index 382d20a6fc1..00000000000
--- a/arch/m68k/include/asm/module_mm.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef _ASM_M68K_MODULE_H
-#define _ASM_M68K_MODULE_H
-
-struct mod_arch_specific {
- struct m68k_fixup_info *fixup_start, *fixup_end;
-};
-
-#define MODULE_ARCH_INIT { \
- .fixup_start = __start_fixup, \
- .fixup_end = __stop_fixup, \
-}
-
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-
-
-enum m68k_fixup_type {
- m68k_fixup_memoffset,
- m68k_fixup_vnode_shift,
-};
-
-struct m68k_fixup_info {
- enum m68k_fixup_type type;
- void *addr;
-};
-
-#define m68k_fixup(type, addr) \
- " .section \".m68k_fixup\",\"aw\"\n" \
- " .long " #type "," #addr "\n" \
- " .previous\n"
-
-extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
-
-struct module;
-extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
- struct m68k_fixup_info *end);
-
-#endif /* _ASM_M68K_MODULE_H */
diff --git a/arch/m68k/include/asm/module_no.h b/arch/m68k/include/asm/module_no.h
deleted file mode 100644
index 2e45ab50b23..00000000000
--- a/arch/m68k/include/asm/module_no.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef ASM_M68KNOMMU_MODULE_H
-#define ASM_M68KNOMMU_MODULE_H
-
-struct mod_arch_specific {
-};
-
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-
-#endif /* ASM_M68KNOMMU_MODULE_H */
diff --git a/arch/m68k/include/asm/page_offset.h b/arch/m68k/include/asm/page_offset.h
index 66455c849fb..1780152d81d 100644
--- a/arch/m68k/include/asm/page_offset.h
+++ b/arch/m68k/include/asm/page_offset.h
@@ -1,5 +1,11 @@
-#ifdef __uClinux__
-#include "page_offset_no.h"
+/* This handles the memory map.. */
+
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+#define PAGE_OFFSET_RAW 0x00000000
#else
-#include "page_offset_mm.h"
+#define PAGE_OFFSET_RAW 0x0E000000
+#endif
+#else
+#define PAGE_OFFSET_RAW CONFIG_RAMBASE
#endif
diff --git a/arch/m68k/include/asm/page_offset_mm.h b/arch/m68k/include/asm/page_offset_mm.h
deleted file mode 100644
index 1cbdb7f30ac..00000000000
--- a/arch/m68k/include/asm/page_offset_mm.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-/* This handles the memory map.. */
-#ifndef CONFIG_SUN3
-#define PAGE_OFFSET_RAW 0x00000000
-#else
-#define PAGE_OFFSET_RAW 0x0E000000
-#endif
-
diff --git a/arch/m68k/include/asm/page_offset_no.h b/arch/m68k/include/asm/page_offset_no.h
deleted file mode 100644
index d4e73e0ba64..00000000000
--- a/arch/m68k/include/asm/page_offset_no.h
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-/* This handles the memory map.. */
-#define PAGE_OFFSET_RAW CONFIG_RAMBASE
-
diff --git a/arch/m68k/include/asm/pci.h b/arch/m68k/include/asm/pci.h
index dbea9537308..4ad0aea48ab 100644
--- a/arch/m68k/include/asm/pci.h
+++ b/arch/m68k/include/asm/pci.h
@@ -1,5 +1,12 @@
-#ifdef __uClinux__
-#include "pci_no.h"
-#else
-#include "pci_mm.h"
-#endif
+#ifndef _ASM_M68K_PCI_H
+#define _ASM_M68K_PCI_H
+
+#include <asm-generic/pci-dma-compat.h>
+
+/* The PCI address space does equal the physical memory
+ * address space. The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS (1)
+
+#endif /* _ASM_M68K_PCI_H */
diff --git a/arch/m68k/include/asm/pci_mm.h b/arch/m68k/include/asm/pci_mm.h
deleted file mode 100644
index 4ad0aea48ab..00000000000
--- a/arch/m68k/include/asm/pci_mm.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _ASM_M68K_PCI_H
-#define _ASM_M68K_PCI_H
-
-#include <asm-generic/pci-dma-compat.h>
-
-/* The PCI address space does equal the physical memory
- * address space. The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS (1)
-
-#endif /* _ASM_M68K_PCI_H */
diff --git a/arch/m68k/include/asm/pci_no.h b/arch/m68k/include/asm/pci_no.h
deleted file mode 100644
index 9abbc03c73e..00000000000
--- a/arch/m68k/include/asm/pci_no.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef M68KNOMMU_PCI_H
-#define M68KNOMMU_PCI_H
-
-#include <asm/pci_mm.h>
-
-#ifdef CONFIG_COMEMPCI
-/*
- * These are pretty much arbitary with the CoMEM implementation.
- * We have the whole address space to ourselves.
- */
-#define PCIBIOS_MIN_IO 0x100
-#define PCIBIOS_MIN_MEM 0x00010000
-
-#define pcibios_scan_all_fns(a, b) 0
-
-/*
- * Return whether the given PCI device DMA address mask can
- * be supported properly. For example, if your device can
- * only drive the low 24-bits during PCI bus mastering, then
- * you would pass 0x00ffffff as the mask to this function.
- */
-static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
-{
- return 1;
-}
-
-#endif /* CONFIG_COMEMPCI */
-
-#endif /* M68KNOMMU_PCI_H */
diff --git a/arch/m68k/include/asm/pgalloc.h b/arch/m68k/include/asm/pgalloc.h
index 059cb73e78f..c294aad8a90 100644
--- a/arch/m68k/include/asm/pgalloc.h
+++ b/arch/m68k/include/asm/pgalloc.h
@@ -1,5 +1,19 @@
-#ifdef __uClinux__
-#include "pgalloc_no.h"
+#ifndef M68K_PGALLOC_H
+#define M68K_PGALLOC_H
+
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_MMU
+#include <asm/virtconvert.h>
+#ifdef CONFIG_SUN3
+#include <asm/sun3_pgalloc.h>
#else
-#include "pgalloc_mm.h"
+#include <asm/motorola_pgalloc.h>
#endif
+
+extern void m68k_setup_node(int node);
+#endif
+
+#endif /* M68K_PGALLOC_H */
diff --git a/arch/m68k/include/asm/pgalloc_mm.h b/arch/m68k/include/asm/pgalloc_mm.h
deleted file mode 100644
index 4cb1a57ab76..00000000000
--- a/arch/m68k/include/asm/pgalloc_mm.h
+++ /dev/null
@@ -1,19 +0,0 @@
-
-#ifndef M68K_PGALLOC_H
-#define M68K_PGALLOC_H
-
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <asm/setup.h>
-#include <asm/virtconvert.h>
-
-
-#ifdef CONFIG_SUN3
-#include <asm/sun3_pgalloc.h>
-#else
-#include <asm/motorola_pgalloc.h>
-#endif
-
-extern void m68k_setup_node(int node);
-
-#endif /* M68K_PGALLOC_H */
diff --git a/arch/m68k/include/asm/pgalloc_no.h b/arch/m68k/include/asm/pgalloc_no.h
deleted file mode 100644
index d6352f671ec..00000000000
--- a/arch/m68k/include/asm/pgalloc_no.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _M68KNOMMU_PGALLOC_H
-#define _M68KNOMMU_PGALLOC_H
-
-#include <asm/setup.h>
-
-#define check_pgt_cache() do { } while (0)
-
-#endif /* _M68KNOMMU_PGALLOC_H */
diff --git a/arch/m68k/include/asm/pgtable_no.h b/arch/m68k/include/asm/pgtable_no.h
index 46251016e82..bf86b29fe64 100644
--- a/arch/m68k/include/asm/pgtable_no.h
+++ b/arch/m68k/include/asm/pgtable_no.h
@@ -67,4 +67,6 @@ extern unsigned int kobjsize(const void *objp);
#include <asm-generic/pgtable.h>
+#define check_pgt_cache() do { } while (0)
+
#endif /* _M68KNOMMU_PGTABLE_H */
diff --git a/arch/m68k/include/asm/rtc.h b/arch/m68k/include/asm/rtc.h
index 5d3e0385984..a4d08ea122e 100644
--- a/arch/m68k/include/asm/rtc.h
+++ b/arch/m68k/include/asm/rtc.h
@@ -36,13 +36,16 @@ static inline unsigned int get_rtc_time(struct rtc_time *time)
* RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
* by the RTC when initially set to a non-zero value.
*/
- mach_hwclk(0, time);
+ if (mach_hwclk)
+ mach_hwclk(0, time);
return RTC_24H;
}
static inline int set_rtc_time(struct rtc_time *time)
{
- return mach_hwclk(1, time);
+ if (mach_hwclk)
+ return mach_hwclk(1, time);
+ return -EINVAL;
}
static inline unsigned int get_rtc_ss(void)
diff --git a/arch/m68k/include/asm/scatterlist.h b/arch/m68k/include/asm/scatterlist.h
index b7e52863625..e27ad902b1c 100644
--- a/arch/m68k/include/asm/scatterlist.h
+++ b/arch/m68k/include/asm/scatterlist.h
@@ -1,5 +1,23 @@
-#ifdef __uClinux__
-#include "scatterlist_no.h"
-#else
-#include "scatterlist_mm.h"
+#ifndef _M68K_SCATTERLIST_H
+#define _M68K_SCATTERLIST_H
+
+#include <linux/types.h>
+
+struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
#endif
+ unsigned long page_link;
+ unsigned int offset;
+ unsigned int length;
+
+ dma_addr_t dma_address; /* A place to hang host-specific addresses at. */
+};
+
+/* This is bogus and should go away. */
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+#define sg_dma_address(sg) ((sg)->dma_address)
+#define sg_dma_len(sg) ((sg)->length)
+
+#endif /* !(_M68K_SCATTERLIST_H) */
diff --git a/arch/m68k/include/asm/scatterlist_mm.h b/arch/m68k/include/asm/scatterlist_mm.h
deleted file mode 100644
index d3a7a0edfec..00000000000
--- a/arch/m68k/include/asm/scatterlist_mm.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _M68K_SCATTERLIST_H
-#define _M68K_SCATTERLIST_H
-
-#include <linux/types.h>
-
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
- unsigned long sg_magic;
-#endif
- unsigned long page_link;
- unsigned int offset;
- unsigned int length;
-
- __u32 dma_address; /* A place to hang host-specific addresses at. */
-};
-
-/* This is bogus and should go away. */
-#define ISA_DMA_THRESHOLD (0x00ffffff)
-
-#define sg_dma_address(sg) ((sg)->dma_address)
-#define sg_dma_len(sg) ((sg)->length)
-
-#endif /* !(_M68K_SCATTERLIST_H) */
diff --git a/arch/m68k/include/asm/scatterlist_no.h b/arch/m68k/include/asm/scatterlist_no.h
deleted file mode 100644
index afc4788b0d2..00000000000
--- a/arch/m68k/include/asm/scatterlist_no.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _M68KNOMMU_SCATTERLIST_H
-#define _M68KNOMMU_SCATTERLIST_H
-
-#include <linux/mm.h>
-#include <asm/types.h>
-
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
- unsigned long sg_magic;
-#endif
- unsigned long page_link;
- unsigned int offset;
- dma_addr_t dma_address;
- unsigned int length;
-};
-
-#define sg_dma_address(sg) ((sg)->dma_address)
-#define sg_dma_len(sg) ((sg)->length)
-
-#define ISA_DMA_THRESHOLD (0xffffffff)
-
-#endif /* !(_M68KNOMMU_SCATTERLIST_H) */
diff --git a/arch/m68k/include/asm/segment.h b/arch/m68k/include/asm/segment.h
index 82583bc004b..ee959219fdf 100644
--- a/arch/m68k/include/asm/segment.h
+++ b/arch/m68k/include/asm/segment.h
@@ -1,5 +1,63 @@
-#ifdef __uClinux__
-#include "segment_no.h"
+#ifndef _M68K_SEGMENT_H
+#define _M68K_SEGMENT_H
+
+/* define constants */
+/* Address spaces (FC0-FC2) */
+#define USER_DATA (1)
+#ifndef __USER_DS
+#define __USER_DS (USER_DATA)
+#endif
+#define USER_PROGRAM (2)
+#define SUPER_DATA (5)
+#ifndef __KERNEL_DS
+#define __KERNEL_DS (SUPER_DATA)
+#endif
+#define SUPER_PROGRAM (6)
+#define CPU_SPACE (7)
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
+#define USER_DS MAKE_MM_SEG(__USER_DS)
+#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS)
+
+/*
+ * Get/set the SFC/DFC registers for MOVES instructions
+ */
+
+static inline mm_segment_t get_fs(void)
+{
+#ifdef CONFIG_MMU
+ mm_segment_t _v;
+ __asm__ ("movec %/dfc,%0":"=r" (_v.seg):);
+
+ return _v;
#else
-#include "segment_mm.h"
+ return USER_DS;
+#endif
+}
+
+static inline mm_segment_t get_ds(void)
+{
+ /* return the supervisor data space code */
+ return KERNEL_DS;
+}
+
+static inline void set_fs(mm_segment_t val)
+{
+#ifdef CONFIG_MMU
+ __asm__ __volatile__ ("movec %0,%/sfc\n\t"
+ "movec %0,%/dfc\n\t"
+ : /* no outputs */ : "r" (val.seg) : "memory");
#endif
+}
+
+#define segment_eq(a,b) ((a).seg == (b).seg)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _M68K_SEGMENT_H */
diff --git a/arch/m68k/include/asm/segment_mm.h b/arch/m68k/include/asm/segment_mm.h
deleted file mode 100644
index 7b0b2d3127f..00000000000
--- a/arch/m68k/include/asm/segment_mm.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef _M68K_SEGMENT_H
-#define _M68K_SEGMENT_H
-
-/* define constants */
-/* Address spaces (FC0-FC2) */
-#define USER_DATA (1)
-#ifndef __USER_DS
-#define __USER_DS (USER_DATA)
-#endif
-#define USER_PROGRAM (2)
-#define SUPER_DATA (5)
-#ifndef __KERNEL_DS
-#define __KERNEL_DS (SUPER_DATA)
-#endif
-#define SUPER_PROGRAM (6)
-#define CPU_SPACE (7)
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
-#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-#define USER_DS MAKE_MM_SEG(__USER_DS)
-#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS)
-
-/*
- * Get/set the SFC/DFC registers for MOVES instructions
- */
-
-static inline mm_segment_t get_fs(void)
-{
- mm_segment_t _v;
- __asm__ ("movec %/dfc,%0":"=r" (_v.seg):);
-
- return _v;
-}
-
-static inline mm_segment_t get_ds(void)
-{
- /* return the supervisor data space code */
- return KERNEL_DS;
-}
-
-static inline void set_fs(mm_segment_t val)
-{
- __asm__ __volatile__ ("movec %0,%/sfc\n\t"
- "movec %0,%/dfc\n\t"
- : /* no outputs */ : "r" (val.seg) : "memory");
-}
-
-#define segment_eq(a,b) ((a).seg == (b).seg)
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _M68K_SEGMENT_H */
diff --git a/arch/m68k/include/asm/segment_no.h b/arch/m68k/include/asm/segment_no.h
deleted file mode 100644
index 42318ebec7e..00000000000
--- a/arch/m68k/include/asm/segment_no.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _M68K_SEGMENT_H
-#define _M68K_SEGMENT_H
-
-/* define constants */
-/* Address spaces (FC0-FC2) */
-#define USER_DATA (1)
-#ifndef __USER_DS
-#define __USER_DS (USER_DATA)
-#endif
-#define USER_PROGRAM (2)
-#define SUPER_DATA (5)
-#ifndef __KERNEL_DS
-#define __KERNEL_DS (SUPER_DATA)
-#endif
-#define SUPER_PROGRAM (6)
-#define CPU_SPACE (7)
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
-#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-#define USER_DS MAKE_MM_SEG(__USER_DS)
-#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS)
-
-/*
- * Get/set the SFC/DFC registers for MOVES instructions
- */
-
-static inline mm_segment_t get_fs(void)
-{
- return USER_DS;
-}
-
-static inline mm_segment_t get_ds(void)
-{
- /* return the supervisor data space code */
- return KERNEL_DS;
-}
-
-static inline void set_fs(mm_segment_t val)
-{
-}
-
-#define segment_eq(a,b) ((a).seg == (b).seg)
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _M68K_SEGMENT_H */
diff --git a/arch/m68k/include/asm/timex.h b/arch/m68k/include/asm/timex.h
index 71976298057..b87f2f278f6 100644
--- a/arch/m68k/include/asm/timex.h
+++ b/arch/m68k/include/asm/timex.h
@@ -1,5 +1,18 @@
-#ifdef __uClinux__
-#include "timex_no.h"
-#else
-#include "timex_mm.h"
+/*
+ * linux/include/asm-m68k/timex.h
+ *
+ * m68k architecture timex specifications
+ */
+#ifndef _ASMm68k_TIMEX_H
+#define _ASMm68k_TIMEX_H
+
+#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+ return 0;
+}
+
#endif
diff --git a/arch/m68k/include/asm/timex_mm.h b/arch/m68k/include/asm/timex_mm.h
deleted file mode 100644
index b87f2f278f6..00000000000
--- a/arch/m68k/include/asm/timex_mm.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * linux/include/asm-m68k/timex.h
- *
- * m68k architecture timex specifications
- */
-#ifndef _ASMm68k_TIMEX_H
-#define _ASMm68k_TIMEX_H
-
-#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
-
-typedef unsigned long cycles_t;
-
-static inline cycles_t get_cycles(void)
-{
- return 0;
-}
-
-#endif
diff --git a/arch/m68k/include/asm/timex_no.h b/arch/m68k/include/asm/timex_no.h
deleted file mode 100644
index 109050f3fe9..00000000000
--- a/arch/m68k/include/asm/timex_no.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/include/asm-m68knommu/timex.h
- *
- * m68knommu architecture timex specifications
- */
-#ifndef _ASM_M68KNOMMU_TIMEX_H
-#define _ASM_M68KNOMMU_TIMEX_H
-
-#ifdef CONFIG_COLDFIRE
-#include <asm/coldfire.h>
-#define CLOCK_TICK_RATE MCF_CLK
-#else
-#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
-#endif
-
-typedef unsigned long cycles_t;
-
-static inline cycles_t get_cycles(void)
-{
- return 0;
-}
-
-#endif
diff --git a/arch/m68k/include/asm/tlbflush.h b/arch/m68k/include/asm/tlbflush.h
index b6f93b30951..a6b4ed4fc90 100644
--- a/arch/m68k/include/asm/tlbflush.h
+++ b/arch/m68k/include/asm/tlbflush.h
@@ -1,5 +1,267 @@
-#ifdef __uClinux__
-#include "tlbflush_no.h"
+#ifndef _M68K_TLBFLUSH_H
+#define _M68K_TLBFLUSH_H
+
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+
+#include <asm/current.h>
+
+static inline void flush_tlb_kernel_page(void *addr)
+{
+ if (CPU_IS_040_OR_060) {
+ mm_segment_t old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflush (%0)\n\t"
+ ".chip 68k"
+ : : "a" (addr));
+ set_fs(old_fs);
+ } else if (CPU_IS_020_OR_030)
+ __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
+}
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+ if (CPU_IS_040_OR_060)
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflushan\n\t"
+ ".chip 68k");
+ else if (CPU_IS_020_OR_030)
+ __asm__ __volatile__("pflush #0,#4");
+}
+
+static inline void __flush_tlb040_one(unsigned long addr)
+{
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflush (%0)\n\t"
+ ".chip 68k"
+ : : "a" (addr));
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+ if (CPU_IS_040_OR_060)
+ __flush_tlb040_one(addr);
+ else if (CPU_IS_020_OR_030)
+ __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+ if (CPU_IS_040_OR_060)
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflusha\n\t"
+ ".chip 68k");
+ else if (CPU_IS_020_OR_030)
+ __asm__ __volatile__("pflusha");
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+ if (mm == current->active_mm)
+ __flush_tlb();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+ if (vma->vm_mm == current->active_mm) {
+ mm_segment_t old_fs = get_fs();
+ set_fs(USER_DS);
+ __flush_tlb_one(addr);
+ set_fs(old_fs);
+ }
+}
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ if (vma->vm_mm == current->active_mm)
+ __flush_tlb();
+}
+
+static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+ flush_tlb_all();
+}
+
#else
-#include "tlbflush_mm.h"
+
+
+/* Reserved PMEGs. */
+extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
+extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];
+extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];
+extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
+
+/* Flush all userspace mappings one by one... (why no flush command,
+ sun?) */
+static inline void flush_tlb_all(void)
+{
+ unsigned long addr;
+ unsigned char ctx, oldctx;
+
+ oldctx = sun3_get_context();
+ for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {
+ for(ctx = 0; ctx < 8; ctx++) {
+ sun3_put_context(ctx);
+ sun3_put_segmap(addr, SUN3_INVALID_PMEG);
+ }
+ }
+
+ sun3_put_context(oldctx);
+ /* erase all of the userspace pmeg maps, we've clobbered them
+ all anyway */
+ for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) {
+ if(pmeg_alloc[addr] == 1) {
+ pmeg_alloc[addr] = 0;
+ pmeg_ctx[addr] = 0;
+ pmeg_vaddr[addr] = 0;
+ }
+ }
+
+}
+
+/* Clear user TLB entries within the context named in mm */
+static inline void flush_tlb_mm (struct mm_struct *mm)
+{
+ unsigned char oldctx;
+ unsigned char seg;
+ unsigned long i;
+
+ oldctx = sun3_get_context();
+ sun3_put_context(mm->context);
+
+ for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {
+ seg = sun3_get_segmap(i);
+ if(seg == SUN3_INVALID_PMEG)
+ continue;
+
+ sun3_put_segmap(i, SUN3_INVALID_PMEG);
+ pmeg_alloc[seg] = 0;
+ pmeg_ctx[seg] = 0;
+ pmeg_vaddr[seg] = 0;
+ }
+
+ sun3_put_context(oldctx);
+
+}
+
+/* Flush a single TLB page. In this case, we're limited to flushing a
+ single PMEG */
+static inline void flush_tlb_page (struct vm_area_struct *vma,
+ unsigned long addr)
+{
+ unsigned char oldctx;
+ unsigned char i;
+
+ oldctx = sun3_get_context();
+ sun3_put_context(vma->vm_mm->context);
+ addr &= ~SUN3_PMEG_MASK;
+ if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG)
+ {
+ pmeg_alloc[i] = 0;
+ pmeg_ctx[i] = 0;
+ pmeg_vaddr[i] = 0;
+ sun3_put_segmap (addr, SUN3_INVALID_PMEG);
+ }
+ sun3_put_context(oldctx);
+
+}
+/* Flush a range of pages from TLB. */
+
+static inline void flush_tlb_range (struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ struct mm_struct *mm = vma->vm_mm;
+ unsigned char seg, oldctx;
+
+ start &= ~SUN3_PMEG_MASK;
+
+ oldctx = sun3_get_context();
+ sun3_put_context(mm->context);
+
+ while(start < end)
+ {
+ if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG)
+ goto next;
+ if(pmeg_ctx[seg] == mm->context) {
+ pmeg_alloc[seg] = 0;
+ pmeg_ctx[seg] = 0;
+ pmeg_vaddr[seg] = 0;
+ }
+ sun3_put_segmap(start, SUN3_INVALID_PMEG);
+ next:
+ start += SUN3_PMEG_SIZE;
+ }
+}
+
+static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+ flush_tlb_all();
+}
+
+/* Flush kernel page from TLB. */
+static inline void flush_tlb_kernel_page (unsigned long addr)
+{
+ sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
+}
+
#endif
+
+#else /* !CONFIG_MMU */
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+ BUG();
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+ BUG();
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+ BUG();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+ BUG();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+ BUG();
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+{
+ BUG();
+}
+
+static inline void flush_tlb_kernel_page(unsigned long addr)
+{
+ BUG();
+}
+
+#endif /* CONFIG_MMU */
+
+#endif /* _M68K_TLBFLUSH_H */
diff --git a/arch/m68k/include/asm/tlbflush_mm.h b/arch/m68k/include/asm/tlbflush_mm.h
deleted file mode 100644
index acb6bf21a32..00000000000
--- a/arch/m68k/include/asm/tlbflush_mm.h
+++ /dev/null
@@ -1,219 +0,0 @@
-#ifndef _M68K_TLBFLUSH_H
-#define _M68K_TLBFLUSH_H
-
-
-#ifndef CONFIG_SUN3
-
-#include <asm/current.h>
-
-static inline void flush_tlb_kernel_page(void *addr)
-{
- if (CPU_IS_040_OR_060) {
- mm_segment_t old_fs = get_fs();
- set_fs(KERNEL_DS);
- __asm__ __volatile__(".chip 68040\n\t"
- "pflush (%0)\n\t"
- ".chip 68k"
- : : "a" (addr));
- set_fs(old_fs);
- } else if (CPU_IS_020_OR_030)
- __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
-}
-
-/*
- * flush all user-space atc entries.
- */
-static inline void __flush_tlb(void)
-{
- if (CPU_IS_040_OR_060)
- __asm__ __volatile__(".chip 68040\n\t"
- "pflushan\n\t"
- ".chip 68k");
- else if (CPU_IS_020_OR_030)
- __asm__ __volatile__("pflush #0,#4");
-}
-
-static inline void __flush_tlb040_one(unsigned long addr)
-{
- __asm__ __volatile__(".chip 68040\n\t"
- "pflush (%0)\n\t"
- ".chip 68k"
- : : "a" (addr));
-}
-
-static inline void __flush_tlb_one(unsigned long addr)
-{
- if (CPU_IS_040_OR_060)
- __flush_tlb040_one(addr);
- else if (CPU_IS_020_OR_030)
- __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
-}
-
-#define flush_tlb() __flush_tlb()
-
-/*
- * flush all atc entries (both kernel and user-space entries).
- */
-static inline void flush_tlb_all(void)
-{
- if (CPU_IS_040_OR_060)
- __asm__ __volatile__(".chip 68040\n\t"
- "pflusha\n\t"
- ".chip 68k");
- else if (CPU_IS_020_OR_030)
- __asm__ __volatile__("pflusha");
-}
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
- if (mm == current->active_mm)
- __flush_tlb();
-}
-
-static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
-{
- if (vma->vm_mm == current->active_mm) {
- mm_segment_t old_fs = get_fs();
- set_fs(USER_DS);
- __flush_tlb_one(addr);
- set_fs(old_fs);
- }
-}
-
-static inline void flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- if (vma->vm_mm == current->active_mm)
- __flush_tlb();
-}
-
-static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
- flush_tlb_all();
-}
-
-#else
-
-
-/* Reserved PMEGs. */
-extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
-extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];
-extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];
-extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
-
-/* Flush all userspace mappings one by one... (why no flush command,
- sun?) */
-static inline void flush_tlb_all(void)
-{
- unsigned long addr;
- unsigned char ctx, oldctx;
-
- oldctx = sun3_get_context();
- for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {
- for(ctx = 0; ctx < 8; ctx++) {
- sun3_put_context(ctx);
- sun3_put_segmap(addr, SUN3_INVALID_PMEG);
- }
- }
-
- sun3_put_context(oldctx);
- /* erase all of the userspace pmeg maps, we've clobbered them
- all anyway */
- for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) {
- if(pmeg_alloc[addr] == 1) {
- pmeg_alloc[addr] = 0;
- pmeg_ctx[addr] = 0;
- pmeg_vaddr[addr] = 0;
- }
- }
-
-}
-
-/* Clear user TLB entries within the context named in mm */
-static inline void flush_tlb_mm (struct mm_struct *mm)
-{
- unsigned char oldctx;
- unsigned char seg;
- unsigned long i;
-
- oldctx = sun3_get_context();
- sun3_put_context(mm->context);
-
- for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {
- seg = sun3_get_segmap(i);
- if(seg == SUN3_INVALID_PMEG)
- continue;
-
- sun3_put_segmap(i, SUN3_INVALID_PMEG);
- pmeg_alloc[seg] = 0;
- pmeg_ctx[seg] = 0;
- pmeg_vaddr[seg] = 0;
- }
-
- sun3_put_context(oldctx);
-
-}
-
-/* Flush a single TLB page. In this case, we're limited to flushing a
- single PMEG */
-static inline void flush_tlb_page (struct vm_area_struct *vma,
- unsigned long addr)
-{
- unsigned char oldctx;
- unsigned char i;
-
- oldctx = sun3_get_context();
- sun3_put_context(vma->vm_mm->context);
- addr &= ~SUN3_PMEG_MASK;
- if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG)
- {
- pmeg_alloc[i] = 0;
- pmeg_ctx[i] = 0;
- pmeg_vaddr[i] = 0;
- sun3_put_segmap (addr, SUN3_INVALID_PMEG);
- }
- sun3_put_context(oldctx);
-
-}
-/* Flush a range of pages from TLB. */
-
-static inline void flush_tlb_range (struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- struct mm_struct *mm = vma->vm_mm;
- unsigned char seg, oldctx;
-
- start &= ~SUN3_PMEG_MASK;
-
- oldctx = sun3_get_context();
- sun3_put_context(mm->context);
-
- while(start < end)
- {
- if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG)
- goto next;
- if(pmeg_ctx[seg] == mm->context) {
- pmeg_alloc[seg] = 0;
- pmeg_ctx[seg] = 0;
- pmeg_vaddr[seg] = 0;
- }
- sun3_put_segmap(start, SUN3_INVALID_PMEG);
- next:
- start += SUN3_PMEG_SIZE;
- }
-}
-
-static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
- flush_tlb_all();
-}
-
-/* Flush kernel page from TLB. */
-static inline void flush_tlb_kernel_page (unsigned long addr)
-{
- sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
-}
-
-#endif
-
-#endif /* _M68K_TLBFLUSH_H */
diff --git a/arch/m68k/include/asm/tlbflush_no.h b/arch/m68k/include/asm/tlbflush_no.h
deleted file mode 100644
index a470cfb803e..00000000000
--- a/arch/m68k/include/asm/tlbflush_no.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _M68KNOMMU_TLBFLUSH_H
-#define _M68KNOMMU_TLBFLUSH_H
-
-/*
- * Copyright (C) 2000 Lineo, David McCullough <davidm@uclinux.org>
- * Copyright (C) 2000-2002, Greg Ungerer <gerg@snapgear.com>
- */
-
-#include <asm/setup.h>
-
-/*
- * flush all user-space atc entries.
- */
-static inline void __flush_tlb(void)
-{
- BUG();
-}
-
-static inline void __flush_tlb_one(unsigned long addr)
-{
- BUG();
-}
-
-#define flush_tlb() __flush_tlb()
-
-/*
- * flush all atc entries (both kernel and user-space entries).
- */
-static inline void flush_tlb_all(void)
-{
- BUG();
-}
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
- BUG();
-}
-
-static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
-{
- BUG();
-}
-
-static inline void flush_tlb_range(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- BUG();
-}
-
-static inline void flush_tlb_kernel_page(unsigned long addr)
-{
- BUG();
-}
-
-#endif /* _M68KNOMMU_TLBFLUSH_H */
diff --git a/arch/m68k/include/asm/ucontext.h b/arch/m68k/include/asm/ucontext.h
index b53cd160c0b..e4e22669edc 100644
--- a/arch/m68k/include/asm/ucontext.h
+++ b/arch/m68k/include/asm/ucontext.h
@@ -1,5 +1,30 @@
-#ifdef __uClinux__
-#include "ucontext_no.h"
-#else
-#include "ucontext_mm.h"
+#ifndef _M68K_UCONTEXT_H
+#define _M68K_UCONTEXT_H
+
+typedef int greg_t;
+#define NGREG 18
+typedef greg_t gregset_t[NGREG];
+
+typedef struct fpregset {
+ int f_fpcntl[3];
+ int f_fpregs[8*3];
+} fpregset_t;
+
+struct mcontext {
+ int version;
+ gregset_t gregs;
+ fpregset_t fpregs;
+};
+
+#define MCONTEXT_VERSION 2
+
+struct ucontext {
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ struct mcontext uc_mcontext;
+ unsigned long uc_filler[80];
+ sigset_t uc_sigmask; /* mask last for extensibility */
+};
+
#endif
diff --git a/arch/m68k/include/asm/ucontext_mm.h b/arch/m68k/include/asm/ucontext_mm.h
deleted file mode 100644
index e4e22669edc..00000000000
--- a/arch/m68k/include/asm/ucontext_mm.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _M68K_UCONTEXT_H
-#define _M68K_UCONTEXT_H
-
-typedef int greg_t;
-#define NGREG 18
-typedef greg_t gregset_t[NGREG];
-
-typedef struct fpregset {
- int f_fpcntl[3];
- int f_fpregs[8*3];
-} fpregset_t;
-
-struct mcontext {
- int version;
- gregset_t gregs;
- fpregset_t fpregs;
-};
-
-#define MCONTEXT_VERSION 2
-
-struct ucontext {
- unsigned long uc_flags;
- struct ucontext *uc_link;
- stack_t uc_stack;
- struct mcontext uc_mcontext;
- unsigned long uc_filler[80];
- sigset_t uc_sigmask; /* mask last for extensibility */
-};
-
-#endif
diff --git a/arch/m68k/include/asm/ucontext_no.h b/arch/m68k/include/asm/ucontext_no.h
deleted file mode 100644
index 713a27f901c..00000000000
--- a/arch/m68k/include/asm/ucontext_no.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _M68KNOMMU_UCONTEXT_H
-#define _M68KNOMMU_UCONTEXT_H
-
-typedef int greg_t;
-#define NGREG 18
-typedef greg_t gregset_t[NGREG];
-
-typedef struct fpregset {
- int f_pcr;
- int f_psr;
- int f_fpiaddr;
- int f_fpregs[8][3];
-} fpregset_t;
-
-struct mcontext {
- int version;
- gregset_t gregs;
- fpregset_t fpregs;
-};
-
-#define MCONTEXT_VERSION 2
-
-struct ucontext {
- unsigned long uc_flags;
- struct ucontext *uc_link;
- stack_t uc_stack;
- struct mcontext uc_mcontext;
- unsigned long uc_filler[80];
- sigset_t uc_sigmask; /* mask last for extensibility */
-};
-
-#endif
diff --git a/arch/m68k/include/asm/unaligned.h b/arch/m68k/include/asm/unaligned.h
index c640bba3bdf..019caa740c2 100644
--- a/arch/m68k/include/asm/unaligned.h
+++ b/arch/m68k/include/asm/unaligned.h
@@ -1,5 +1,25 @@
-#ifdef __uClinux__
-#include "unaligned_no.h"
+#ifndef _ASM_M68K_UNALIGNED_H
+#define _ASM_M68K_UNALIGNED_H
+
+
+#ifdef CONFIG_COLDFIRE
+#include <linux/unaligned/be_struct.h>
+#include <linux/unaligned/le_byteshift.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned __get_unaligned_be
+#define put_unaligned __put_unaligned_be
+
#else
-#include "unaligned_mm.h"
+/*
+ * The m68k can do unaligned accesses itself.
+ */
+#include <linux/unaligned/access_ok.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned __get_unaligned_be
+#define put_unaligned __put_unaligned_be
+
#endif
+
+#endif /* _ASM_M68K_UNALIGNED_H */
diff --git a/arch/m68k/include/asm/unaligned_mm.h b/arch/m68k/include/asm/unaligned_mm.h
deleted file mode 100644
index 77698f2dc33..00000000000
--- a/arch/m68k/include/asm/unaligned_mm.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _ASM_M68K_UNALIGNED_H
-#define _ASM_M68K_UNALIGNED_H
-
-/*
- * The m68k can do unaligned accesses itself.
- */
-#include <linux/unaligned/access_ok.h>
-#include <linux/unaligned/generic.h>
-
-#define get_unaligned __get_unaligned_be
-#define put_unaligned __put_unaligned_be
-
-#endif /* _ASM_M68K_UNALIGNED_H */
diff --git a/arch/m68k/include/asm/unaligned_no.h b/arch/m68k/include/asm/unaligned_no.h
deleted file mode 100644
index eb1ea4cb9a5..00000000000
--- a/arch/m68k/include/asm/unaligned_no.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _ASM_M68KNOMMU_UNALIGNED_H
-#define _ASM_M68KNOMMU_UNALIGNED_H
-
-
-#ifdef CONFIG_COLDFIRE
-#include <linux/unaligned/be_struct.h>
-#include <linux/unaligned/le_byteshift.h>
-#include <linux/unaligned/generic.h>
-
-#define get_unaligned __get_unaligned_be
-#define put_unaligned __put_unaligned_be
-
-#else
-/*
- * The m68k can do unaligned accesses itself.
- */
-#include <linux/unaligned/access_ok.h>
-#include <linux/unaligned/generic.h>
-
-#define get_unaligned __get_unaligned_be
-#define put_unaligned __put_unaligned_be
-
-#endif
-
-#endif /* _ASM_M68KNOMMU_UNALIGNED_H */
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
index 7db41594d7b..54d980795fc 100644
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -18,6 +18,7 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/rtc.h>
+#include <linux/platform_device.h>
#include <asm/machdep.h>
#include <asm/io.h>
@@ -159,3 +160,20 @@ int do_settimeofday(struct timespec *tv)
}
EXPORT_SYMBOL(do_settimeofday);
+
+
+static int __init rtc_init(void)
+{
+ struct platform_device *pdev;
+
+ if (!mach_hwclk)
+ return -ENODEV;
+
+ pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
+}
+
+module_init(rtc_init);
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
index fd0fb303d88..ce404bc9ccb 100644
--- a/arch/m68knommu/Makefile
+++ b/arch/m68knommu/Makefile
@@ -88,18 +88,18 @@ export PLATFORM BOARD MODEL CPUCLASS
#
# Some CFLAG additions based on specific CPU type.
#
-cflags-$(CONFIG_M5206) := -m5200
-cflags-$(CONFIG_M5206e) := -m5200
-cflags-$(CONFIG_M520x) := -m5307
+cflags-$(CONFIG_M5206) := $(call cc-option,-mcpu=5206,-m5200)
+cflags-$(CONFIG_M5206e) := $(call cc-option,-m5206e,-m5200)
+cflags-$(CONFIG_M520x) := $(call cc-option,-mcpu=5208,-m5200)
cflags-$(CONFIG_M523x) := $(call cc-option,-mcpu=523x,-m5307)
-cflags-$(CONFIG_M5249) := -m5200
+cflags-$(CONFIG_M5249) := $(call cc-option,-mcpu=5249,-m5200)
cflags-$(CONFIG_M5271) := $(call cc-option,-mcpu=5271,-m5307)
-cflags-$(CONFIG_M5272) := -m5307
+cflags-$(CONFIG_M5272) := $(call cc-option,-mcpu=5271,-m5200)
cflags-$(CONFIG_M5275) := $(call cc-option,-mcpu=5275,-m5307)
cflags-$(CONFIG_M528x) := $(call cc-option,-m528x,-m5307)
-cflags-$(CONFIG_M5307) := -m5307
+cflags-$(CONFIG_M5307) := $(call cc-option,-m5307,-m5200)
cflags-$(CONFIG_M532x) := $(call cc-option,-mcpu=532x,-m5307)
-cflags-$(CONFIG_M5407) := -m5200
+cflags-$(CONFIG_M5407) := $(call cc-option,-m5407,-m5200)
cflags-$(CONFIG_M68328) := -m68000
cflags-$(CONFIG_M68EZ328) := -m68000
cflags-$(CONFIG_M68VZ328) := -m68000
diff --git a/arch/m68knommu/kernel/dma.c b/arch/m68knommu/kernel/dma.c
index e10eafc5278..93612580663 100644
--- a/arch/m68knommu/kernel/dma.c
+++ b/arch/m68knommu/kernel/dma.c
@@ -9,10 +9,11 @@
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/device.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int gfp)
+ dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
/* ignore region specifiers */
@@ -34,3 +35,8 @@ void dma_free_coherent(struct device *dev, size_t size,
{
free_pages((unsigned long)vaddr, get_order(size));
}
+
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+}
+
diff --git a/arch/m68knommu/kernel/irq.c b/arch/m68knommu/kernel/irq.c
index bba1bb48a21..56e0f4c55a6 100644
--- a/arch/m68knommu/kernel/irq.c
+++ b/arch/m68knommu/kernel/irq.c
@@ -23,7 +23,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
struct pt_regs *oldregs = set_irq_regs(regs);
irq_enter();
- __do_IRQ(irq);
+ generic_handle_irq(irq);
irq_exit();
set_irq_regs(oldregs);
diff --git a/arch/m68knommu/mm/init.c b/arch/m68knommu/mm/init.c
index 3bf249c53e4..7befc0c357e 100644
--- a/arch/m68knommu/mm/init.c
+++ b/arch/m68knommu/mm/init.c
@@ -111,11 +111,7 @@ void __init paging_init(void)
{
unsigned long zones_size[MAX_NR_ZONES] = {0, };
- zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT;
- zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
-#ifdef CONFIG_HIGHMEM
- zones_size[ZONE_HIGHMEM] = 0;
-#endif
+ zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
free_area_init(zones_size);
}
}
diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c
index d299f7b8768..9eab19d01eb 100644
--- a/arch/m68knommu/platform/5249/config.c
+++ b/arch/m68knommu/platform/5249/config.c
@@ -32,7 +32,8 @@ static struct mcf_platform_uart m5249_uart_platform[] = {
{
.mapbase = MCF_MBAR + MCFUART_BASE2,
.irq = 74,
- }
+ },
+ { },
};
static struct platform_device m5249_uart = {
@@ -50,12 +51,12 @@ static struct platform_device *m5249_devices[] __initdata = {
static void __init m5249_uart_init_line(int line, int irq)
{
if (line == 0) {
- writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
- writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+ writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
} else if (line == 1) {
- writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
- writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+ writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
}
}
diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c
index 724faf05852..44803bf70a6 100644
--- a/arch/m68knommu/platform/5307/config.c
+++ b/arch/m68knommu/platform/5307/config.c
@@ -65,12 +65,12 @@ static struct platform_device *m5307_devices[] __initdata = {
static void __init m5307_uart_init_line(int line, int irq)
{
if (line == 0) {
- writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
- writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+ writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
} else if (line == 1) {
- writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
- writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+ writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
}
}
diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c
index 648b8b77821..0ee8c1a200c 100644
--- a/arch/m68knommu/platform/5407/config.c
+++ b/arch/m68knommu/platform/5407/config.c
@@ -56,12 +56,12 @@ static struct platform_device *m5407_devices[] __initdata = {
static void __init m5407_uart_init_line(int line, int irq)
{
if (line == 0) {
- writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
- writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+ writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
} else if (line == 1) {
- writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
- writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+ writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
}
}
diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile
index 4f416a91a82..1bcb9372353 100644
--- a/arch/m68knommu/platform/coldfire/Makefile
+++ b/arch/m68knommu/platform/coldfire/Makefile
@@ -14,7 +14,7 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
-obj-$(CONFIG_COLDFIRE) += dma.o entry.o vectors.o
+obj-$(CONFIG_COLDFIRE) += clk.o dma.o entry.o vectors.o
obj-$(CONFIG_M5206) += timers.o
obj-$(CONFIG_M5206e) += timers.o
obj-$(CONFIG_M520x) += pit.o
diff --git a/arch/m68knommu/platform/coldfire/clk.c b/arch/m68knommu/platform/coldfire/clk.c
new file mode 100644
index 00000000000..7cdbf445b28
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/clk.c
@@ -0,0 +1,40 @@
+/***************************************************************************/
+
+/*
+ * clk.c -- general ColdFire CPU kernel clk handling
+ *
+ * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <asm/coldfire.h>
+
+/***************************************************************************/
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ return NULL;
+}
+
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+
+void clk_disable(struct clk *clk)
+{
+}
+
+void clk_put(struct clk *clk)
+{
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return MCF_CLK;
+}
+
+/***************************************************************************/
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
new file mode 100644
index 00000000000..8cc312b5d4d
--- /dev/null
+++ b/arch/microblaze/Kconfig
@@ -0,0 +1,141 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+
+mainmenu "Linux/Microblaze Kernel Configuration"
+
+config MICROBLAZE
+ def_bool y
+ select HAVE_LMB
+
+config SWAP
+ def_bool n
+
+config RWSEM_GENERIC_SPINLOCK
+ def_bool y
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+
+config ARCH_HAS_ILOG2_U32
+ def_bool n
+
+config ARCH_HAS_ILOG2_U64
+ def_bool n
+
+config GENERIC_FIND_NEXT_BIT
+ def_bool y
+
+config GENERIC_HWEIGHT
+ def_bool y
+
+config GENERIC_HARDIRQS
+ def_bool y
+
+config GENERIC_IRQ_PROBE
+ def_bool y
+
+config GENERIC_CALIBRATE_DELAY
+ def_bool y
+
+config GENERIC_TIME
+ def_bool y
+
+config GENERIC_TIME_VSYSCALL
+ def_bool n
+
+config GENERIC_CLOCKEVENTS
+ def_bool y
+
+config GENERIC_HARDIRQS_NO__DO_IRQ
+ def_bool y
+
+config PCI
+ depends on !MMU
+ def_bool n
+
+config NO_DMA
+ depends on !MMU
+ def_bool n
+
+source "init/Kconfig"
+
+source "kernel/Kconfig.freezer"
+
+source "arch/microblaze/platform/Kconfig.platform"
+
+menu "Processor type and features"
+
+source kernel/time/Kconfig
+
+source "kernel/Kconfig.preempt"
+
+source "kernel/Kconfig.hz"
+
+config MMU
+ def_bool n
+
+config NO_MMU
+ bool
+ depends on !MMU
+ default y
+
+comment "Boot options"
+
+config CMDLINE_BOOL
+ bool "Default bootloader kernel arguments"
+
+config CMDLINE
+ string "Default kernel command string"
+ depends on CMDLINE_BOOL
+ default "console=ttyUL0,115200"
+ help
+ On some architectures there is currently no way for the boot loader
+ to pass arguments to the kernel. For these architectures, you should
+ supply some command-line options at build time by entering them
+ here.
+
+config CMDLINE_FORCE
+ bool "Force default kernel command string"
+ depends on CMDLINE_BOOL
+ default n
+ help
+ Set this to have arguments from the default kernel command string
+ override those passed by the boot loader.
+
+config OF
+ def_bool y
+
+config OF_DEVICE
+ def_bool y
+
+config PROC_DEVICETREE
+ bool "Support for device tree in /proc"
+ depends on PROC_FS
+ help
+ This option adds a device-tree directory under /proc which contains
+ an image of the device tree that the kernel copies from Open
+ Firmware or other boot firmware. If unsure, say Y here.
+
+endmenu
+
+source "mm/Kconfig"
+
+menu "Exectuable file formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/microblaze/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
diff --git a/arch/microblaze/Kconfig.debug b/arch/microblaze/Kconfig.debug
new file mode 100644
index 00000000000..242cd35bdb4
--- /dev/null
+++ b/arch/microblaze/Kconfig.debug
@@ -0,0 +1,26 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config EARLY_PRINTK
+ bool "Early printk function for kernel"
+ default n
+ help
+ This option turns on/off early printk messages to console.
+ First Uartlite node is taken.
+
+config HEART_BEAT
+ bool "Heart beat function for kernel"
+ default n
+ help
+ This option turns on/off heart beat kernel functionality.
+ First GPIO node is taken.
+
+config DEBUG_BOOTMEM
+ depends on DEBUG_KERNEL
+ bool "Debug BOOTMEM initialization"
+
+endmenu
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile
new file mode 100644
index 00000000000..0dcbb983297
--- /dev/null
+++ b/arch/microblaze/Makefile
@@ -0,0 +1,69 @@
+UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
+
+# What CPU vesion are we building for, and crack it open
+# as major.minor.rev
+CPU_VER=$(subst ",,$(CONFIG_XILINX_MICROBLAZE0_HW_VER) )
+CPU_MAJOR=$(shell echo $(CPU_VER) | cut -d '.' -f 1)
+CPU_MINOR=$(shell echo $(CPU_VER) | cut -d '.' -f 2)
+CPU_REV=$(shell echo $(CPU_VER) | cut -d '.' -f 3)
+
+export CPU_VER CPU_MAJOR CPU_MINOR CPU_REV
+
+# Use cpu-related CONFIG_ vars to set compile options.
+
+# Work out HW multipler support. This is icky.
+# 1. Spartan2 has no HW multiplers.
+# 2. MicroBlaze v3.x always uses them, except in Spartan 2
+# 3. All other FPGa/CPU ver combos, we can trust the CONFIG_ settings
+ifeq (,$(findstring spartan2,$(CONFIG_XILINX_MICROBLAZE0_FAMILY)))
+ ifeq ($(CPU_MAJOR),3)
+ CPUFLAGS-1 += -mno-xl-soft-mul
+ else
+ # USE_HW_MUL can be 0, 1, or 2, defining a heirarchy of HW Mul support.
+ CPUFLAGS-$(subst 1,,$(CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL)) += -mxl-multiply-high
+ CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL) += -mno-xl-soft-mul
+ endif
+endif
+CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_DIV) += -mno-xl-soft-div
+CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_BARREL) += -mxl-barrel-shift
+CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_PCMP) += -mxl-pattern-compare
+
+CPUFLAGS-1 += $(call cc-option,-mcpu=v$(CPU_VER))
+
+# The various CONFIG_XILINX cpu features options are integers 0/1/2...
+# rather than bools y/n
+CFLAGS += $(CPUFLAGS-1)
+CFLAGS += $(CPUFLAGS-2)
+
+# r31 holds current when in kernel mode
+CFLAGS += -ffixed-r31
+
+LDFLAGS_BLOB := --format binary --oformat elf32-microblaze
+
+LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+
+head-y := arch/microblaze/kernel/head.o
+libs-y += arch/microblaze/lib/ $(LIBGCC)
+core-y += arch/microblaze/kernel/ arch/microblaze/mm/ \
+ arch/microblaze/platform/
+
+boot := arch/$(ARCH)/boot
+
+# defines filename extension depending memory management type
+ifeq ($(CONFIG_MMU),)
+MMUEXT := -nommu
+endif
+export MMUEXT
+
+all: linux.bin
+
+archclean:
+ $(Q)$(MAKE) $(clean)=$(boot)
+
+linux.bin linux.bin.gz: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+define archhelp
+ echo '* linux.bin - Create raw binary'
+ echo ' linux.bin.gz - Create compressed raw binary'
+endef
diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile
new file mode 100644
index 00000000000..844edf406d3
--- /dev/null
+++ b/arch/microblaze/boot/Makefile
@@ -0,0 +1,17 @@
+#
+# arch/microblaze/boot/Makefile
+#
+
+targets := linux.bin linux.bin.gz
+
+OBJCOPYFLAGS_linux.bin := -O binary
+
+$(obj)/linux.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+ @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+
+$(obj)/linux.bin.gz: $(obj)/linux.bin FORCE
+ $(call if_changed,gzip)
+ @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+
+clean-kernel += linux.bin linux.bin.gz
diff --git a/arch/microblaze/configs/nommu_defconfig b/arch/microblaze/configs/nommu_defconfig
new file mode 100644
index 00000000000..beb7ecd7279
--- /dev/null
+++ b/arch/microblaze/configs/nommu_defconfig
@@ -0,0 +1,804 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29
+# Tue Mar 24 10:23:20 2009
+#
+CONFIG_MICROBLAZE=y
+# CONFIG_SWAP is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_GENERIC_TIME_VSYSCALL is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+# CONFIG_PCI is not set
+# CONFIG_NO_DMA is not set
+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_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=1
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE 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 is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# Platform options
+#
+CONFIG_PLATFORM_GENERIC=y
+# CONFIG_SELFMOD is not set
+# CONFIG_OPT_LIB_FUNCTION is not set
+# CONFIG_ALLOW_EDIT_AUTO is not set
+CONFIG_KERNEL_BASE_ADDR=0x90000000
+CONFIG_XILINX_MICROBLAZE0_FAMILY="virtex5"
+CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1
+CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1
+CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1
+CONFIG_XILINX_MICROBLAZE0_USE_DIV=1
+CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=2
+CONFIG_XILINX_MICROBLAZE0_USE_FPU=2
+CONFIG_XILINX_MICROBLAZE0_HW_VER="7.10.d"
+
+#
+# Processor type and features
+#
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_MMU is not set
+CONFIG_NO_MMU=y
+
+#
+# Boot options
+#
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyUL0,115200"
+# CONFIG_CMDLINE_FORCE is not set
+CONFIG_OF=y
+CONFIG_OF_DEVICE=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+
+#
+# Exectuable file formats
+#
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP 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=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_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD 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=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_UCLINUX=y
+# 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
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_UARTLITE=y
+CONFIG_SERIAL_UARTLITE_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# 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
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_OBJECTS_SELFTEST=y
+CONFIG_DEBUG_OBJECTS_FREE=y
+CONFIG_DEBUG_OBJECTS_TIMERS=y
+CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_SG=y
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_HEART_BEAT=y
+# CONFIG_DEBUG_BOOTMEM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
new file mode 100644
index 00000000000..31820dfef56
--- /dev/null
+++ b/arch/microblaze/include/asm/Kbuild
@@ -0,0 +1,26 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += linkage.h
+header-y += msgbuf.h
+header-y += poll.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += socket.h
+header-y += sockios.h
+header-y += statfs.h
+header-y += stat.h
+header-y += termbits.h
+header-y += ucontext.h
+
+unifdef-y += cputable.h
+unifdef-y += elf.h
+unifdef-y += termios.h
diff --git a/arch/microblaze/include/asm/atomic.h b/arch/microblaze/include/asm/atomic.h
new file mode 100644
index 00000000000..a448d94ab72
--- /dev/null
+++ b/arch/microblaze/include/asm/atomic.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_ATOMIC_H
+#define _ASM_MICROBLAZE_ATOMIC_H
+
+#include <linux/types.h>
+#include <linux/compiler.h> /* likely */
+#include <asm/system.h> /* local_irq_XXX and friends */
+
+#define ATOMIC_INIT(i) { (i) }
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v, i) (((v)->counter) = (i))
+
+#define atomic_inc(v) (atomic_add_return(1, (v)))
+#define atomic_dec(v) (atomic_sub_return(1, (v)))
+
+#define atomic_add(i, v) (atomic_add_return(i, (v)))
+#define atomic_sub(i, v) (atomic_sub_return(i, (v)))
+
+#define atomic_inc_return(v) (atomic_add_return(1, (v)))
+#define atomic_dec_return(v) (atomic_sub_return(1, (v)))
+
+#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+#define atomic_inc_not_zero(v) (atomic_add_unless((v), 1, 0))
+
+#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
+
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+ int ret;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ ret = v->counter;
+ if (likely(ret == old))
+ v->counter = new;
+ local_irq_restore(flags);
+
+ return ret;
+}
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+
+ c = atomic_read(v);
+ while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
+ c = old;
+ return c != u;
+}
+
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ *addr &= ~mask;
+ local_irq_restore(flags);
+}
+
+/**
+ * atomic_add_return - add and return
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v and returns @i + @v
+ */
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+ unsigned long flags;
+ int val;
+
+ local_irq_save(flags);
+ val = v->counter;
+ v->counter = val += i;
+ local_irq_restore(flags);
+
+ return val;
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+ return atomic_add_return(-i, v);
+}
+
+/*
+ * Atomically test *v and decrement if it is greater than 0.
+ * The function returns the old value of *v minus 1.
+ */
+static inline int atomic_dec_if_positive(atomic_t *v)
+{
+ unsigned long flags;
+ int res;
+
+ local_irq_save(flags);
+ res = v->counter - 1;
+ if (res >= 0)
+ v->counter = res;
+ local_irq_restore(flags);
+
+ return res;
+}
+
+#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec() barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc() barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+#include <asm-generic/atomic.h>
+
+#endif /* _ASM_MICROBLAZE_ATOMIC_H */
diff --git a/arch/microblaze/include/asm/auxvec.h b/arch/microblaze/include/asm/auxvec.h
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/arch/microblaze/include/asm/auxvec.h
@@ -0,0 +1 @@
+
diff --git a/arch/microblaze/include/asm/bitops.h b/arch/microblaze/include/asm/bitops.h
new file mode 100644
index 00000000000..d6df1fd4e1e
--- /dev/null
+++ b/arch/microblaze/include/asm/bitops.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_BITOPS_H
+#define _ASM_MICROBLAZE_BITOPS_H
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ */
+
+#include <asm/byteorder.h> /* swab32 */
+#include <asm/system.h> /* save_flags */
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit() barrier()
+#define smp_mb__after_clear_bit() barrier()
+#include <asm-generic/bitops.h>
+#include <asm-generic/bitops/__fls.h>
+
+#endif /* _ASM_MICROBLAZE_BITOPS_H */
diff --git a/arch/microblaze/include/asm/bug.h b/arch/microblaze/include/asm/bug.h
new file mode 100644
index 00000000000..8eb2cdde11d
--- /dev/null
+++ b/arch/microblaze/include/asm/bug.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_BUG_H
+#define _ASM_MICROBLAZE_BUG_H
+
+#include <linux/kernel.h>
+#include <asm-generic/bug.h>
+
+#endif /* _ASM_MICROBLAZE_BUG_H */
diff --git a/arch/microblaze/include/asm/bugs.h b/arch/microblaze/include/asm/bugs.h
new file mode 100644
index 00000000000..f2c6593653f
--- /dev/null
+++ b/arch/microblaze/include/asm/bugs.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_BUGS_H
+#define _ASM_MICROBLAZE_BUGS_H
+
+static inline void check_bugs(void)
+{
+ /* nothing to do */
+}
+
+#endif /* _ASM_MICROBLAZE_BUGS_H */
diff --git a/arch/microblaze/include/asm/byteorder.h b/arch/microblaze/include/asm/byteorder.h
new file mode 100644
index 00000000000..ce9c58732ff
--- /dev/null
+++ b/arch/microblaze/include/asm/byteorder.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_MICROBLAZE_BYTEORDER_H
+#define _ASM_MICROBLAZE_BYTEORDER_H
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _ASM_MICROBLAZE_BYTEORDER_H */
diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h
new file mode 100644
index 00000000000..c4c64b43c07
--- /dev/null
+++ b/arch/microblaze/include/asm/cache.h
@@ -0,0 +1,45 @@
+/*
+ * Cache operations
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_CACHE_H
+#define _ASM_MICROBLAZE_CACHE_H
+
+#include <asm/registers.h>
+
+#define L1_CACHE_SHIFT 2
+/* word-granular cache in microblaze */
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
+#define SMP_CACHE_BYTES L1_CACHE_BYTES
+
+void _enable_icache(void);
+void _disable_icache(void);
+void _invalidate_icache(unsigned int addr);
+
+#define __enable_icache() _enable_icache()
+#define __disable_icache() _disable_icache()
+#define __invalidate_icache(addr) _invalidate_icache(addr)
+
+void _enable_dcache(void);
+void _disable_dcache(void);
+void _invalidate_dcache(unsigned int addr);
+
+#define __enable_dcache() _enable_dcache()
+#define __disable_dcache() _disable_dcache()
+#define __invalidate_dcache(addr) _invalidate_dcache(addr)
+
+/* FIXME - I don't think this is right */
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
+#define UNCACHED_SHADOW_MASK (CONFIG_XILINX_ERAM_SIZE)
+#endif
+
+#endif /* _ASM_MICROBLAZE_CACHE_H */
diff --git a/arch/microblaze/include/asm/cacheflush.h b/arch/microblaze/include/asm/cacheflush.h
new file mode 100644
index 00000000000..3300b785049
--- /dev/null
+++ b/arch/microblaze/include/asm/cacheflush.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ * based on v850 version which was
+ * Copyright (C) 2001,02,03 NEC Electronics Corporation
+ * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef _ASM_MICROBLAZE_CACHEFLUSH_H
+#define _ASM_MICROBLAZE_CACHEFLUSH_H
+
+/* Somebody depends on this; sigh... */
+#include <linux/mm.h>
+
+/*
+ * Cache handling functions.
+ * Microblaze has a write-through data cache, meaning that the data cache
+ * never needs to be flushed. The only flushing operations that are
+ * implemented are to invalidate the instruction cache. These are called
+ * after loading a user application into memory, we must invalidate the
+ * instruction cache to make sure we don't fetch old, bad code.
+ */
+
+/* FIXME for LL-temac driver */
+#define invalidate_dcache_range(start, end) \
+ __invalidate_dcache_range(start, end)
+
+#define flush_cache_all() __invalidate_cache_all()
+#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_range(vma, start, end) __invalidate_cache_all()
+#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
+
+#define flush_dcache_range(start, end) __invalidate_dcache_range(start, end)
+#define flush_dcache_page(page) do { } while (0)
+#define flush_dcache_mmap_lock(mapping) do { } while (0)
+#define flush_dcache_mmap_unlock(mapping) do { } while (0)
+
+#define flush_icache_range(start, len) __invalidate_icache_range(start, len)
+#define flush_icache_page(vma, pg) do { } while (0)
+
+#define flush_cache_vmap(start, end) do { } while (0)
+#define flush_cache_vunmap(start, end) do { } while (0)
+
+struct page;
+struct mm_struct;
+struct vm_area_struct;
+
+/* see arch/microblaze/kernel/cache.c */
+extern void __invalidate_icache_all(void);
+extern void __invalidate_icache_range(unsigned long start, unsigned long end);
+extern void __invalidate_icache_page(struct vm_area_struct *vma,
+ struct page *page);
+extern void __invalidate_icache_user_range(struct vm_area_struct *vma,
+ struct page *page,
+ unsigned long adr, int len);
+extern void __invalidate_cache_sigtramp(unsigned long addr);
+
+extern void __invalidate_dcache_all(void);
+extern void __invalidate_dcache_range(unsigned long start, unsigned long end);
+extern void __invalidate_dcache_page(struct vm_area_struct *vma,
+ struct page *page);
+extern void __invalidate_dcache_user_range(struct vm_area_struct *vma,
+ struct page *page,
+ unsigned long adr, int len);
+
+extern inline void __invalidate_cache_all(void)
+{
+ __invalidate_icache_all();
+ __invalidate_dcache_all();
+}
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+do { memcpy((dst), (src), (len)); \
+ flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \
+} while (0)
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+ memcpy((dst), (src), (len))
+
+#endif /* _ASM_MICROBLAZE_CACHEFLUSH_H */
diff --git a/arch/microblaze/include/asm/checksum.h b/arch/microblaze/include/asm/checksum.h
new file mode 100644
index 00000000000..92b30762ce5
--- /dev/null
+++ b/arch/microblaze/include/asm/checksum.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_CHECKSUM_H
+#define _ASM_MICROBLAZE_CHECKSUM_H
+
+#include <linux/in6.h>
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __wsum
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
+ unsigned short proto, __wsum sum)
+{
+ __asm__("add %0, %0, %1\n\t"
+ "addc %0, %0, %2\n\t"
+ "addc %0, %0, %3\n\t"
+ "addc %0, %0, r0\n\t"
+ : "+&d" (sum)
+ : "d" (saddr), "d" (daddr), "d" (len + proto));
+
+ return sum;
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+extern __wsum csum_partial(const void *buff, int len, __wsum sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern __wsum csum_partial_copy(const char *src, char *dst, int len, int sum);
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern __wsum csum_partial_copy_from_user(const char *src, char *dst,
+ int len, int sum, int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum) \
+ csum_partial_copy((src), (dst), (len), (sum))
+
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.
+ *
+ */
+extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
+
+/*
+ * Fold a partial checksum
+ */
+static inline __sum16 csum_fold(unsigned int sum)
+{
+ sum = (sum & 0xffff) + (sum >> 16);
+ sum = (sum & 0xffff) + (sum >> 16);
+ return ~sum;
+}
+
+static inline __sum16
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
+ unsigned short proto, __wsum sum)
+{
+ return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+extern __sum16 ip_compute_csum(const unsigned char *buff, int len);
+
+#endif /* _ASM_MICROBLAZE_CHECKSUM_H */
diff --git a/arch/microblaze/include/asm/clinkage.h b/arch/microblaze/include/asm/clinkage.h
new file mode 100644
index 00000000000..9e218435a55
--- /dev/null
+++ b/arch/microblaze/include/asm/clinkage.h
@@ -0,0 +1 @@
+#include <linux/linkage.h>
diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h
new file mode 100644
index 00000000000..52f28f6dc4e
--- /dev/null
+++ b/arch/microblaze/include/asm/cpuinfo.h
@@ -0,0 +1,102 @@
+/*
+ * Generic support for queying CPU info
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_CPUINFO_H
+#define _ASM_MICROBLAZE_CPUINFO_H
+
+#include <asm/prom.h>
+
+/* CPU Version and FPGA Family code conversion table type */
+struct cpu_ver_key {
+ const char *s;
+ const unsigned k;
+};
+
+extern const struct cpu_ver_key cpu_ver_lookup[];
+
+struct family_string_key {
+ const char *s;
+ const unsigned k;
+};
+
+extern const struct family_string_key family_string_lookup[];
+
+struct cpuinfo {
+ /* Core CPU configuration */
+ u32 use_instr;
+ u32 use_mult;
+ u32 use_fpu;
+ u32 use_exc;
+ u32 ver_code;
+ u32 mmu;
+
+ /* CPU caches */
+ u32 use_icache;
+ u32 icache_tagbits;
+ u32 icache_write;
+ u32 icache_line;
+ u32 icache_size;
+ unsigned long icache_base;
+ unsigned long icache_high;
+
+ u32 use_dcache;
+ u32 dcache_tagbits;
+ u32 dcache_write;
+ u32 dcache_line;
+ u32 dcache_size;
+ unsigned long dcache_base;
+ unsigned long dcache_high;
+
+ /* Bus connections */
+ u32 use_dopb;
+ u32 use_iopb;
+ u32 use_dlmb;
+ u32 use_ilmb;
+ u32 num_fsl;
+
+ /* CPU interrupt line info */
+ u32 irq_edge;
+ u32 irq_positive;
+
+ u32 area_optimised;
+
+ /* HW debug support */
+ u32 hw_debug;
+ u32 num_pc_brk;
+ u32 num_rd_brk;
+ u32 num_wr_brk;
+ u32 cpu_clock_freq; /* store real freq of cpu */
+ u32 freq_div_hz; /* store freq/HZ */
+
+ /* FPGA family */
+ u32 fpga_family_code;
+
+ /* User define */
+ u32 pvr_user1;
+ u32 pvr_user2;
+};
+
+extern struct cpuinfo cpuinfo;
+
+/* fwd declarations of the various CPUinfo populators */
+void setup_cpuinfo(void);
+
+void set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu);
+void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu);
+
+static inline unsigned int fcpu(struct device_node *cpu, char *n)
+{
+ int *val;
+ return (val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0;
+}
+
+#endif /* _ASM_MICROBLAZE_CPUINFO_H */
diff --git a/arch/microblaze/include/asm/cputable.h b/arch/microblaze/include/asm/cputable.h
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/arch/microblaze/include/asm/cputable.h
@@ -0,0 +1 @@
+
diff --git a/include/asm-mn10300/cputime.h b/arch/microblaze/include/asm/cputime.h
index 6d68ad7e0ea..6d68ad7e0ea 100644
--- a/include/asm-mn10300/cputime.h
+++ b/arch/microblaze/include/asm/cputime.h
diff --git a/arch/microblaze/include/asm/current.h b/arch/microblaze/include/asm/current.h
new file mode 100644
index 00000000000..8375ea991e2
--- /dev/null
+++ b/arch/microblaze/include/asm/current.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_CURRENT_H
+#define _ASM_MICROBLAZE_CURRENT_H
+
+# ifndef __ASSEMBLY__
+/*
+ * Dedicate r31 to keeping the current task pointer
+ */
+register struct task_struct *current asm("r31");
+
+# define get_current() current
+# endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_CURRENT_H */
diff --git a/arch/microblaze/include/asm/delay.h b/arch/microblaze/include/asm/delay.h
new file mode 100644
index 00000000000..05b7d39e439
--- /dev/null
+++ b/arch/microblaze/include/asm/delay.h
@@ -0,0 +1,72 @@
+/*
+ * include/asm-microblaze/delay.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2007 John Williams
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_MICROBLAZE_DELAY_H
+#define _ASM_MICROBLAZE_DELAY_H
+
+extern inline void __delay(unsigned long loops)
+{
+ asm volatile ("# __delay \n\t" \
+ "1: addi %0, %0, -1\t\n" \
+ "bneid %0, 1b \t\n" \
+ "nop \t\n"
+ : "=r" (loops)
+ : "0" (loops));
+}
+
+/*
+ * Note that 19 * 226 == 4294 ==~ 2^32 / 10^6, so
+ * loops = (4294 * usecs * loops_per_jiffy * HZ) / 2^32.
+ *
+ * The mul instruction gives us loops = (a * b) / 2^32.
+ * We choose a = usecs * 19 * HZ and b = loops_per_jiffy * 226
+ * because this lets us support a wide range of HZ and
+ * loops_per_jiffy values without either a or b overflowing 2^32.
+ * Thus we need usecs * HZ <= (2^32 - 1) / 19 = 226050910 and
+ * loops_per_jiffy <= (2^32 - 1) / 226 = 19004280
+ * (which corresponds to ~3800 bogomips at HZ = 100).
+ * -- paulus
+ */
+#define __MAX_UDELAY (226050910UL/HZ) /* maximum udelay argument */
+#define __MAX_NDELAY (4294967295UL/HZ) /* maximum ndelay argument */
+
+extern unsigned long loops_per_jiffy;
+
+extern inline void __udelay(unsigned int x)
+{
+
+ unsigned long long tmp =
+ (unsigned long long)x * (unsigned long long)loops_per_jiffy \
+ * 226LL;
+ unsigned loops = tmp >> 32;
+
+/*
+ __asm__("mulxuu %0,%1,%2" : "=r" (loops) :
+ "r" (x), "r" (loops_per_jiffy * 226));
+*/
+ __delay(loops);
+}
+
+extern void __bad_udelay(void); /* deliberately undefined */
+extern void __bad_ndelay(void); /* deliberately undefined */
+
+#define udelay(n) (__builtin_constant_p(n) ? \
+ ((n) > __MAX_UDELAY ? __bad_udelay() : __udelay((n) * (19 * HZ))) : \
+ __udelay((n) * (19 * HZ)))
+
+#define ndelay(n) (__builtin_constant_p(n) ? \
+ ((n) > __MAX_NDELAY ? __bad_ndelay() : __udelay((n) * HZ)) : \
+ __udelay((n) * HZ))
+
+#define muldiv(a, b, c) (((a)*(b))/(c))
+
+#endif /* _ASM_MICROBLAZE_DELAY_H */
diff --git a/arch/microblaze/include/asm/device.h b/arch/microblaze/include/asm/device.h
new file mode 100644
index 00000000000..c042830793e
--- /dev/null
+++ b/arch/microblaze/include/asm/device.h
@@ -0,0 +1,21 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License v2. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_DEVICE_H
+#define _ASM_MICROBLAZE_DEVICE_H
+
+struct device_node;
+
+struct dev_archdata {
+ /* Optional pointer to an OF device node */
+ struct device_node *of_node;
+};
+
+#endif /* _ASM_MICROBLAZE_DEVICE_H */
+
+
diff --git a/arch/m68k/include/asm/div64_no.h b/arch/microblaze/include/asm/div64.h
index 6cd978cefb2..6cd978cefb2 100644
--- a/arch/m68k/include/asm/div64_no.h
+++ b/arch/microblaze/include/asm/div64.h
diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h
new file mode 100644
index 00000000000..17336252a9b
--- /dev/null
+++ b/arch/microblaze/include/asm/dma-mapping.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_DMA_MAPPING_H
+#define _ASM_MICROBLAZE_DMA_MAPPING_H
+
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+#include <linux/bug.h>
+
+struct scatterlist;
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+
+/* FIXME */
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+ return 1;
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+ return 0;
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction)
+{
+ BUG();
+ return 0;
+}
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline void
+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline void
+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, int flag)
+{
+ return NULL; /* consistent_alloc(flag, size, dma_handle); */
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ BUG();
+}
+
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+
+ return virt_to_bus(ptr);
+}
+
+static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
+ size_t size,
+ enum dma_data_direction direction)
+{
+ switch (direction) {
+ case DMA_FROM_DEVICE:
+ flush_dcache_range((unsigned)dma_addr,
+ (unsigned)dma_addr + size);
+ /* Fall through */
+ case DMA_TO_DEVICE:
+ break;
+ default:
+ BUG();
+ }
+}
+
+#endif /* _ASM_MICROBLAZE_DMA_MAPPING_H */
diff --git a/arch/microblaze/include/asm/dma.h b/arch/microblaze/include/asm/dma.h
new file mode 100644
index 00000000000..0967fa04fc5
--- /dev/null
+++ b/arch/microblaze/include/asm/dma.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_DMA_H
+#define _ASM_MICROBLAZE_DMA_H
+
+/* we don't have dma address limit. define it as zero to be
+ * unlimited. */
+#define MAX_DMA_ADDRESS (0)
+
+#endif /* _ASM_MICROBLAZE_DMA_H */
diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h
new file mode 100644
index 00000000000..81337f24134
--- /dev/null
+++ b/arch/microblaze/include/asm/elf.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_ELF_H
+#define _ASM_MICROBLAZE_ELF_H
+
+/*
+ * Note there is no "official" ELF designation for Microblaze.
+ * I've snaffled the value from the microblaze binutils source code
+ * /binutils/microblaze/include/elf/microblaze.h
+ */
+#define EM_XILINX_MICROBLAZE 0xbaab
+#define ELF_ARCH EM_XILINX_MICROBLAZE
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_XILINX_MICROBLAZE)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS ELFCLASS32
+
+#endif /* _ASM_MICROBLAZE_ELF_H */
diff --git a/include/asm-mn10300/emergency-restart.h b/arch/microblaze/include/asm/emergency-restart.h
index 3711bd9d50b..3711bd9d50b 100644
--- a/include/asm-mn10300/emergency-restart.h
+++ b/arch/microblaze/include/asm/emergency-restart.h
diff --git a/arch/microblaze/include/asm/entry.h b/arch/microblaze/include/asm/entry.h
new file mode 100644
index 00000000000..7f57e42ee46
--- /dev/null
+++ b/arch/microblaze/include/asm/entry.h
@@ -0,0 +1,35 @@
+/*
+ * Definitions used by low-level trap handlers
+ *
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2007 - 2008 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_ENTRY_H
+#define _ASM_MICROBLAZE_ENTRY_H
+
+#include <asm/percpu.h>
+#include <asm/ptrace.h>
+
+/*
+ * These are per-cpu variables required in entry.S, among other
+ * places
+ */
+
+#define PER_CPU(var) per_cpu__##var
+
+# ifndef __ASSEMBLY__
+DECLARE_PER_CPU(unsigned int, KSP); /* Saved kernel stack pointer */
+DECLARE_PER_CPU(unsigned int, KM); /* Kernel/user mode */
+DECLARE_PER_CPU(unsigned int, ENTRY_SP); /* Saved SP on kernel entry */
+DECLARE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */
+DECLARE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */
+DECLARE_PER_CPU(unsigned int, SYSCALL_SAVE); /* Saved syscall number */
+# endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_ENTRY_H */
diff --git a/include/asm-mn10300/errno.h b/arch/microblaze/include/asm/errno.h
index 4c82b503d92..4c82b503d92 100644
--- a/include/asm-mn10300/errno.h
+++ b/arch/microblaze/include/asm/errno.h
diff --git a/arch/microblaze/include/asm/exceptions.h b/arch/microblaze/include/asm/exceptions.h
new file mode 100644
index 00000000000..4cdd2159f47
--- /dev/null
+++ b/arch/microblaze/include/asm/exceptions.h
@@ -0,0 +1,96 @@
+/*
+ * Preliminary support for HW exception handing for Microblaze
+ *
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_EXCEPTIONS_H
+#define _ASM_MICROBLAZE_EXCEPTIONS_H
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+/* Macros to enable and disable HW exceptions in the MSR */
+/* Define MSR enable bit for HW exceptions */
+#define HWEX_MSR_BIT (1 << 8)
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+#define __enable_hw_exceptions() \
+ __asm__ __volatile__ (" msrset r0, %0; \
+ nop;" \
+ : \
+ : "i" (HWEX_MSR_BIT) \
+ : "memory")
+
+#define __disable_hw_exceptions() \
+ __asm__ __volatile__ (" msrclr r0, %0; \
+ nop;" \
+ : \
+ : "i" (HWEX_MSR_BIT) \
+ : "memory")
+#else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+#define __enable_hw_exceptions() \
+ __asm__ __volatile__ (" \
+ mfs r12, rmsr; \
+ nop; \
+ ori r12, r12, %0; \
+ mts rmsr, r12; \
+ nop;" \
+ : \
+ : "i" (HWEX_MSR_BIT) \
+ : "memory", "r12")
+
+#define __disable_hw_exceptions() \
+ __asm__ __volatile__ (" \
+ mfs r12, rmsr; \
+ nop; \
+ andi r12, r12, ~%0; \
+ mts rmsr, r12; \
+ nop;" \
+ : \
+ : "i" (HWEX_MSR_BIT) \
+ : "memory", "r12")
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+
+asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
+ int fsr, int addr);
+
+#if defined(CONFIG_XMON)
+extern void xmon(struct pt_regs *regs);
+extern int xmon_bpt(struct pt_regs *regs);
+extern int xmon_sstep(struct pt_regs *regs);
+extern int xmon_iabr_match(struct pt_regs *regs);
+extern int xmon_dabr_match(struct pt_regs *regs);
+extern void (*xmon_fault_handler)(struct pt_regs *regs);
+
+void (*debugger)(struct pt_regs *regs) = xmon;
+int (*debugger_bpt)(struct pt_regs *regs) = xmon_bpt;
+int (*debugger_sstep)(struct pt_regs *regs) = xmon_sstep;
+int (*debugger_iabr_match)(struct pt_regs *regs) = xmon_iabr_match;
+int (*debugger_dabr_match)(struct pt_regs *regs) = xmon_dabr_match;
+void (*debugger_fault_handler)(struct pt_regs *regs);
+#elif defined(CONFIG_KGDB)
+void (*debugger)(struct pt_regs *regs);
+int (*debugger_bpt)(struct pt_regs *regs);
+int (*debugger_sstep)(struct pt_regs *regs);
+int (*debugger_iabr_match)(struct pt_regs *regs);
+int (*debugger_dabr_match)(struct pt_regs *regs);
+void (*debugger_fault_handler)(struct pt_regs *regs);
+#else
+#define debugger(regs) do { } while (0)
+#define debugger_bpt(regs) 0
+#define debugger_sstep(regs) 0
+#define debugger_iabr_match(regs) 0
+#define debugger_dabr_match(regs) 0
+#define debugger_fault_handler ((void (*)(struct pt_regs *))0)
+#endif
+
+#endif /*__ASSEMBLY__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_EXCEPTIONS_H */
diff --git a/include/asm-mn10300/fcntl.h b/arch/microblaze/include/asm/fcntl.h
index 46ab12db573..46ab12db573 100644
--- a/include/asm-mn10300/fcntl.h
+++ b/arch/microblaze/include/asm/fcntl.h
diff --git a/arch/microblaze/include/asm/flat.h b/arch/microblaze/include/asm/flat.h
new file mode 100644
index 00000000000..acf0da543ef
--- /dev/null
+++ b/arch/microblaze/include/asm/flat.h
@@ -0,0 +1,90 @@
+/*
+ * uClinux flat-format executables
+ *
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_FLAT_H
+#define _ASM_MICROBLAZE_FLAT_H
+
+#include <asm/unaligned.h>
+
+#define flat_stack_align(sp) /* nothing needed */
+#define flat_argvp_envp_on_stack() 0
+#define flat_old_ram_flag(flags) (flags)
+#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
+#define flat_set_persistent(relval, p) 0
+
+/*
+ * Microblaze works a little differently from other arches, because
+ * of the MICROBLAZE_64 reloc type. Here, a 32 bit address is split
+ * over two instructions, an 'imm' instruction which provides the top
+ * 16 bits, then the instruction "proper" which provides the low 16
+ * bits.
+ */
+
+/*
+ * Crack open a symbol reference and extract the address to be
+ * relocated. rp is a potentially unaligned pointer to the
+ * reference
+ */
+
+static inline unsigned long
+flat_get_addr_from_rp(unsigned long *rp, unsigned long relval,
+ unsigned long flags, unsigned long *persistent)
+{
+ unsigned long addr;
+ (void)flags;
+
+ /* Is it a split 64/32 reference? */
+ if (relval & 0x80000000) {
+ /* Grab the two halves of the reference */
+ unsigned long val_hi, val_lo;
+
+ val_hi = get_unaligned(rp);
+ val_lo = get_unaligned(rp+1);
+
+ /* Crack the address out */
+ addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff);
+ } else {
+ /* Get the address straight out */
+ addr = get_unaligned(rp);
+ }
+
+ return addr;
+}
+
+/*
+ * Insert an address into the symbol reference at rp. rp is potentially
+ * unaligned.
+ */
+
+static inline void
+flat_put_addr_at_rp(unsigned long *rp, unsigned long addr, unsigned long relval)
+{
+ /* Is this a split 64/32 reloc? */
+ if (relval & 0x80000000) {
+ /* Get the two "halves" */
+ unsigned long val_hi = get_unaligned(rp);
+ unsigned long val_lo = get_unaligned(rp + 1);
+
+ /* insert the address */
+ val_hi = (val_hi & 0xffff0000) | addr >> 16;
+ val_lo = (val_lo & 0xffff0000) | (addr & 0xffff);
+
+ /* store the two halves back into memory */
+ put_unaligned(val_hi, rp);
+ put_unaligned(val_lo, rp+1);
+ } else {
+ /* Put it straight in, no messing around */
+ put_unaligned(addr, rp);
+ }
+}
+
+#define flat_get_relocate_addr(rel) (rel & 0x7fffffff)
+
+#endif /* _ASM_MICROBLAZE_FLAT_H */
diff --git a/arch/microblaze/include/asm/ftrace.h b/arch/microblaze/include/asm/ftrace.h
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/arch/microblaze/include/asm/ftrace.h
@@ -0,0 +1 @@
+
diff --git a/include/asm-mn10300/futex.h b/arch/microblaze/include/asm/futex.h
index 0b745828f42..0b745828f42 100644
--- a/include/asm-mn10300/futex.h
+++ b/arch/microblaze/include/asm/futex.h
diff --git a/arch/microblaze/include/asm/gpio.h b/arch/microblaze/include/asm/gpio.h
new file mode 100644
index 00000000000..ea04632399d
--- /dev/null
+++ b/arch/microblaze/include/asm/gpio.h
@@ -0,0 +1,56 @@
+/*
+ * Generic GPIO API implementation for PowerPC.
+ *
+ * Copyright (c) 2007-2008 MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.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.
+ */
+
+#ifndef __ASM_POWERPC_GPIO_H
+#define __ASM_POWERPC_GPIO_H
+
+#include <linux/errno.h>
+#include <asm-generic/gpio.h>
+
+#ifdef CONFIG_GPIOLIB
+
+/*
+ * We don't (yet) implement inlined/rapid versions for on-chip gpios.
+ * Just call gpiolib.
+ */
+static inline int gpio_get_value(unsigned int gpio)
+{
+ return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned int gpio, int value)
+{
+ __gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned int gpio)
+{
+ return __gpio_cansleep(gpio);
+}
+
+/*
+ * Not implemented, yet.
+ */
+static inline int gpio_to_irq(unsigned int gpio)
+{
+ return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+ return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+#endif /* __ASM_POWERPC_GPIO_H */
diff --git a/arch/microblaze/include/asm/hardirq.h b/arch/microblaze/include/asm/hardirq.h
new file mode 100644
index 00000000000..0f2d6b013e1
--- /dev/null
+++ b/arch/microblaze/include/asm/hardirq.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_HARDIRQ_H
+#define _ASM_MICROBLAZE_HARDIRQ_H
+
+#include <linux/cache.h>
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <asm/current.h>
+#include <linux/ptrace.h>
+
+/* should be defined in each interrupt controller driver */
+extern unsigned int get_irq(struct pt_regs *regs);
+
+typedef struct {
+ unsigned int __softirq_pending;
+} ____cacheline_aligned irq_cpustat_t;
+
+void ack_bad_irq(unsigned int irq);
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+#endif /* _ASM_MICROBLAZE_HARDIRQ_H */
diff --git a/arch/microblaze/include/asm/hw_irq.h b/arch/microblaze/include/asm/hw_irq.h
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/arch/microblaze/include/asm/hw_irq.h
@@ -0,0 +1 @@
+
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h
new file mode 100644
index 00000000000..8b5853ee6b5
--- /dev/null
+++ b/arch/microblaze/include/asm/io.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_IO_H
+#define _ASM_MICROBLAZE_IO_H
+
+#include <asm/byteorder.h>
+#include <asm/page.h>
+#include <linux/types.h>
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+static inline unsigned char __raw_readb(const volatile void __iomem *addr)
+{
+ return *(volatile unsigned char __force *)addr;
+}
+static inline unsigned short __raw_readw(const volatile void __iomem *addr)
+{
+ return *(volatile unsigned short __force *)addr;
+}
+static inline unsigned int __raw_readl(const volatile void __iomem *addr)
+{
+ return *(volatile unsigned int __force *)addr;
+}
+static inline unsigned long __raw_readq(const volatile void __iomem *addr)
+{
+ return *(volatile unsigned long __force *)addr;
+}
+static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr)
+{
+ *(volatile unsigned char __force *)addr = v;
+}
+static inline void __raw_writew(unsigned short v, volatile void __iomem *addr)
+{
+ *(volatile unsigned short __force *)addr = v;
+}
+static inline void __raw_writel(unsigned int v, volatile void __iomem *addr)
+{
+ *(volatile unsigned int __force *)addr = v;
+}
+static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
+{
+ *(volatile unsigned long __force *)addr = v;
+}
+
+/*
+ * read (readb, readw, readl, readq) and write (writeb, writew,
+ * writel, writeq) accessors are for PCI and thus littel endian.
+ * Linux 2.4 for Microblaze had this wrong.
+ */
+static inline unsigned char readb(const volatile void __iomem *addr)
+{
+ return *(volatile unsigned char __force *)addr;
+}
+static inline unsigned short readw(const volatile void __iomem *addr)
+{
+ return le16_to_cpu(*(volatile unsigned short __force *)addr);
+}
+static inline unsigned int readl(const volatile void __iomem *addr)
+{
+ return le32_to_cpu(*(volatile unsigned int __force *)addr);
+}
+static inline void writeb(unsigned char v, volatile void __iomem *addr)
+{
+ *(volatile unsigned char __force *)addr = v;
+}
+static inline void writew(unsigned short v, volatile void __iomem *addr)
+{
+ *(volatile unsigned short __force *)addr = cpu_to_le16(v);
+}
+static inline void writel(unsigned int v, volatile void __iomem *addr)
+{
+ *(volatile unsigned int __force *)addr = cpu_to_le32(v);
+}
+
+/* ioread and iowrite variants. thease are for now same as __raw_
+ * variants of accessors. we might check for endianess in the feature
+ */
+#define ioread8(addr) __raw_readb((u8 *)(addr))
+#define ioread16(addr) __raw_readw((u16 *)(addr))
+#define ioread32(addr) __raw_readl((u32 *)(addr))
+#define iowrite8(v, addr) __raw_writeb((u8)(v), (u8 *)(addr))
+#define iowrite16(v, addr) __raw_writew((u16)(v), (u16 *)(addr))
+#define iowrite32(v, addr) __raw_writel((u32)(v), (u32 *)(addr))
+
+/* These are the definitions for the x86 IO instructions
+ * inb/inw/inl/outb/outw/outl, the "string" versions
+ * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions
+ * inb_p/inw_p/...
+ * The macros don't do byte-swapping.
+ */
+#define inb(port) readb((u8 *)((port)))
+#define outb(val, port) writeb((val), (u8 *)((unsigned long)(port)))
+#define inw(port) readw((u16 *)((port)))
+#define outw(val, port) writew((val), (u16 *)((unsigned long)(port)))
+#define inl(port) readl((u32 *)((port)))
+#define outl(val, port) writel((val), (u32 *)((unsigned long)(port)))
+
+#define inb_p(port) inb((port))
+#define outb_p(val, port) outb((val), (port))
+#define inw_p(port) inw((port))
+#define outw_p(val, port) outw((val), (port))
+#define inl_p(port) inl((port))
+#define outl_p(val, port) outl((val), (port))
+
+#define memset_io(a, b, c) memset((void *)(a), (b), (c))
+#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c))
+#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c))
+
+/**
+ * virt_to_phys - map virtual addresses to physical
+ * @address: address to remap
+ *
+ * The returned physical address is the physical (CPU) mapping for
+ * the memory address given. It is only valid to use this function on
+ * addresses directly mapped or allocated via kmalloc.
+ *
+ * This function does not give bus mappings for DMA transfers. In
+ * almost all conceivable cases a device driver should not be using
+ * this function
+ */
+static inline unsigned long __iomem virt_to_phys(volatile void *address)
+{
+ return __pa((unsigned long)address);
+}
+
+#define virt_to_bus virt_to_phys
+
+/**
+ * phys_to_virt - map physical address to virtual
+ * @address: address to remap
+ *
+ * The returned virtual address is a current CPU mapping for
+ * the memory address given. It is only valid to use this function on
+ * addresses that have a kernel mapping
+ *
+ * This function does not handle bus mappings for DMA transfers. In
+ * almost all conceivable cases a device driver should not be using
+ * this function
+ */
+static inline void *phys_to_virt(unsigned long address)
+{
+ return (void *)__va(address);
+}
+
+#define bus_to_virt(a) phys_to_virt(a)
+
+static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size,
+ unsigned long flags)
+{
+ return (void *)address;
+}
+
+#define ioremap(physaddr, size) ((void __iomem *)(unsigned long)(physaddr))
+#define iounmap(addr) ((void)0)
+#define ioremap_nocache(physaddr, size) ioremap(physaddr, size)
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p) __va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p) p
+
+/*
+ * Big Endian
+ */
+#define out_be32(a, v) __raw_writel((v), (void __iomem __force *)(a))
+#define out_be16(a, v) __raw_writew((v), (a))
+
+#define in_be32(a) __raw_readl((const void __iomem __force *)(a))
+#define in_be16(a) __raw_readw(a)
+
+/*
+ * Little endian
+ */
+
+#define out_le32(a, v) __raw_writel(__cpu_to_le32(v), (a));
+#define out_le16(a, v) __raw_writew(__cpu_to_le16(v), (a))
+
+#define in_le32(a) __le32_to_cpu(__raw_readl(a))
+#define in_le16(a) __le16_to_cpu(__raw_readw(a))
+
+/* Byte ops */
+#define out_8(a, v) __raw_writeb((v), (a))
+#define in_8(a) __raw_readb(a)
+
+/* FIXME */
+static inline void __iomem *ioport_map(unsigned long port, unsigned int len)
+{
+ return (void __iomem *) (port);
+}
+
+static inline void ioport_unmap(void __iomem *addr)
+{
+ /* Nothing to do */
+}
+
+#endif /* _ASM_MICROBLAZE_IO_H */
diff --git a/include/asm-mn10300/ioctl.h b/arch/microblaze/include/asm/ioctl.h
index b279fe06dfe..b279fe06dfe 100644
--- a/include/asm-mn10300/ioctl.h
+++ b/arch/microblaze/include/asm/ioctl.h
diff --git a/arch/microblaze/include/asm/ioctls.h b/arch/microblaze/include/asm/ioctls.h
new file mode 100644
index 00000000000..03582b24920
--- /dev/null
+++ b/arch/microblaze/include/asm/ioctls.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_IOCTLS_H
+#define _ASM_MICROBLAZE_IOCTLS_H
+
+#include <linux/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS 0x5401
+#define TCSETS 0x5402
+#define TCSETSW 0x5403
+#define TCSETSF 0x5404
+#define TCGETA 0x5405
+#define TCSETA 0x5406
+#define TCSETAW 0x5407
+#define TCSETAF 0x5408
+#define TCSBRK 0x5409
+#define TCXONC 0x540A
+#define TCFLSH 0x540B
+#define TIOCEXCL 0x540C
+#define TIOCNXCL 0x540D
+#define TIOCSCTTY 0x540E
+#define TIOCGPGRP 0x540F
+#define TIOCSPGRP 0x5410
+#define TIOCOUTQ 0x5411
+#define TIOCSTI 0x5412
+#define TIOCGWINSZ 0x5413
+#define TIOCSWINSZ 0x5414
+#define TIOCMGET 0x5415
+#define TIOCMBIS 0x5416
+#define TIOCMBIC 0x5417
+#define TIOCMSET 0x5418
+#define TIOCGSOFTCAR 0x5419
+#define TIOCSSOFTCAR 0x541A
+#define FIONREAD 0x541B
+#define TIOCINQ FIONREAD
+#define TIOCLINUX 0x541C
+#define TIOCCONS 0x541D
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TIOCPKT 0x5420
+#define FIONBIO 0x5421
+#define TIOCNOTTY 0x5422
+#define TIOCSETD 0x5423
+#define TIOCGETD 0x5424
+#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
+#define TIOCSBRK 0x5427 /* BSD compatibility */
+#define TIOCCBRK 0x5428 /* BSD compatibility */
+#define TIOCGSID 0x5429 /* Return the session ID of FD */
+/* Get Pty Number (of pty-mux device) */
+#define TIOCGPTN _IOR('T', 0x30, unsigned int)
+#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */
+
+#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
+#define FIOCLEX 0x5451
+#define FIOASYNC 0x5452
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
+#define TIOCSERGETLSR 0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
+
+#define FIOQSIZE 0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+
+#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+
+#endif /* _ASM_MICROBLAZE_IOCTLS_H */
diff --git a/include/asm-mn10300/ipc.h b/arch/microblaze/include/asm/ipc.h
index a46e3d9c2a3..a46e3d9c2a3 100644
--- a/include/asm-mn10300/ipc.h
+++ b/arch/microblaze/include/asm/ipc.h
diff --git a/arch/microblaze/include/asm/ipcbuf.h b/arch/microblaze/include/asm/ipcbuf.h
new file mode 100644
index 00000000000..b056fa42065
--- /dev/null
+++ b/arch/microblaze/include/asm/ipcbuf.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_IPCBUF_H
+#define _ASM_MICROBLAZE_IPCBUF_H
+
+/*
+ * The user_ipc_perm structure for microblaze architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm {
+ __kernel_key_t key;
+ __kernel_uid32_t uid;
+ __kernel_gid32_t gid;
+ __kernel_uid32_t cuid;
+ __kernel_gid32_t cgid;
+ __kernel_mode_t mode;
+ unsigned short __pad1;
+ unsigned short seq;
+ unsigned short __pad2;
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+#endif /* _ASM_MICROBLAZE_IPCBUF_H */
diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h
new file mode 100644
index 00000000000..db515deaa72
--- /dev/null
+++ b/arch/microblaze/include/asm/irq.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_IRQ_H
+#define _ASM_MICROBLAZE_IRQ_H
+
+#define NR_IRQS 32
+
+#include <linux/interrupt.h>
+
+extern unsigned int nr_irq;
+
+#define NO_IRQ (-1)
+
+static inline int irq_canonicalize(int irq)
+{
+ return irq;
+}
+
+struct pt_regs;
+extern void do_IRQ(struct pt_regs *regs);
+
+/* irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
+ * @device: Device node of the device whose interrupt is to be mapped
+ * @index: Index of the interrupt to map
+ *
+ * This function is a wrapper that chains of_irq_map_one() and
+ * irq_create_of_mapping() to make things easier to callers
+ */
+struct device_node;
+extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index);
+
+/** FIXME - not implement
+ * irq_dispose_mapping - Unmap an interrupt
+ * @virq: linux virq number of the interrupt to unmap
+ */
+static inline void irq_dispose_mapping(unsigned int virq)
+{
+ return;
+}
+
+#endif /* _ASM_MICROBLAZE_IRQ_H */
diff --git a/arch/microblaze/include/asm/irq_regs.h b/arch/microblaze/include/asm/irq_regs.h
new file mode 100644
index 00000000000..3dd9c0b7027
--- /dev/null
+++ b/arch/microblaze/include/asm/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/arch/microblaze/include/asm/irqflags.h b/arch/microblaze/include/asm/irqflags.h
new file mode 100644
index 00000000000..dea65645a4f
--- /dev/null
+++ b/arch/microblaze/include/asm/irqflags.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_IRQFLAGS_H
+#define _ASM_MICROBLAZE_IRQFLAGS_H
+
+#include <linux/irqflags.h>
+
+# if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+
+# define local_irq_save(flags) \
+ do { \
+ asm volatile ("# local_irq_save \n\t" \
+ "msrclr %0, %1 \n\t" \
+ "nop \n\t" \
+ : "=r"(flags) \
+ : "i"(MSR_IE) \
+ : "memory"); \
+ } while (0)
+
+# define local_irq_disable() \
+ do { \
+ asm volatile ("# local_irq_disable \n\t" \
+ "msrclr r0, %0 \n\t" \
+ "nop \n\t" \
+ : \
+ : "i"(MSR_IE) \
+ : "memory"); \
+ } while (0)
+
+# define local_irq_enable() \
+ do { \
+ asm volatile ("# local_irq_enable \n\t" \
+ "msrset r0, %0 \n\t" \
+ "nop \n\t" \
+ : \
+ : "i"(MSR_IE) \
+ : "memory"); \
+ } while (0)
+
+# else /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR == 0 */
+
+# define local_irq_save(flags) \
+ do { \
+ register unsigned tmp; \
+ asm volatile ("# local_irq_save \n\t" \
+ "mfs %0, rmsr \n\t" \
+ "nop \n\t" \
+ "andi %1, %0, %2 \n\t" \
+ "mts rmsr, %1 \n\t" \
+ "nop \n\t" \
+ : "=r"(flags), "=r" (tmp) \
+ : "i"(~MSR_IE) \
+ : "memory"); \
+ } while (0)
+
+# define local_irq_disable() \
+ do { \
+ register unsigned tmp; \
+ asm volatile ("# local_irq_disable \n\t" \
+ "mfs %0, rmsr \n\t" \
+ "nop \n\t" \
+ "andi %0, %0, %1 \n\t" \
+ "mts rmsr, %0 \n\t" \
+ "nop \n\t" \
+ : "=r"(tmp) \
+ : "i"(~MSR_IE) \
+ : "memory"); \
+ } while (0)
+
+# define local_irq_enable() \
+ do { \
+ register unsigned tmp; \
+ asm volatile ("# local_irq_enable \n\t" \
+ "mfs %0, rmsr \n\t" \
+ "nop \n\t" \
+ "ori %0, %0, %1 \n\t" \
+ "mts rmsr, %0 \n\t" \
+ "nop \n\t" \
+ : "=r"(tmp) \
+ : "i"(MSR_IE) \
+ : "memory"); \
+ } while (0)
+
+# endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+
+#define local_save_flags(flags) \
+ do { \
+ asm volatile ("# local_save_flags \n\t" \
+ "mfs %0, rmsr \n\t" \
+ "nop \n\t" \
+ : "=r"(flags) \
+ : \
+ : "memory"); \
+ } while (0)
+
+#define local_irq_restore(flags) \
+ do { \
+ asm volatile ("# local_irq_restore \n\t"\
+ "mts rmsr, %0 \n\t" \
+ "nop \n\t" \
+ : \
+ : "r"(flags) \
+ : "memory"); \
+ } while (0)
+
+static inline int irqs_disabled(void)
+{
+ unsigned long flags;
+
+ local_save_flags(flags);
+ return ((flags & MSR_IE) == 0);
+}
+
+#define raw_irqs_disabled irqs_disabled
+#define raw_irqs_disabled_flags(flags) ((flags) == 0)
+
+#endif /* _ASM_MICROBLAZE_IRQFLAGS_H */
diff --git a/arch/microblaze/include/asm/kdebug.h b/arch/microblaze/include/asm/kdebug.h
new file mode 100644
index 00000000000..6ece1b03766
--- /dev/null
+++ b/arch/microblaze/include/asm/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/arch/microblaze/include/asm/kmap_types.h b/arch/microblaze/include/asm/kmap_types.h
new file mode 100644
index 00000000000..4d7e222f5dd
--- /dev/null
+++ b/arch/microblaze/include/asm/kmap_types.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_KMAP_TYPES_H
+#define _ASM_MICROBLAZE_KMAP_TYPES_H
+
+enum km_type {
+ KM_BOUNCE_READ,
+ KM_SKB_SUNRPC_DATA,
+ KM_SKB_DATA_SOFTIRQ,
+ KM_USER0,
+ KM_USER1,
+ KM_BIO_SRC_IRQ,
+ KM_BIO_DST_IRQ,
+ KM_PTE0,
+ KM_PTE1,
+ KM_IRQ0,
+ KM_IRQ1,
+ KM_SOFTIRQ0,
+ KM_SOFTIRQ1,
+ KM_TYPE_NR,
+};
+
+#endif /* _ASM_MICROBLAZE_KMAP_TYPES_H */
diff --git a/arch/microblaze/include/asm/linkage.h b/arch/microblaze/include/asm/linkage.h
new file mode 100644
index 00000000000..3a8e36d057e
--- /dev/null
+++ b/arch/microblaze/include/asm/linkage.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_LINKAGE_H
+#define _ASM_MICROBLAZE_LINKAGE_H
+
+#define __ALIGN .align 4
+#define __ALIGN_STR ".align 4"
+
+#endif /* _ASM_MICROBLAZE_LINKAGE_H */
diff --git a/arch/microblaze/include/asm/lmb.h b/arch/microblaze/include/asm/lmb.h
new file mode 100644
index 00000000000..a0a0a929c29
--- /dev/null
+++ b/arch/microblaze/include/asm/lmb.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2008 Michal Simek <monstr@monstr.eu>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_LMB_H
+#define _ASM_MICROBLAZE_LMB_H
+
+/* LMB limit is OFF */
+#define LMB_REAL_LIMIT 0xFFFFFFFF
+
+#endif /* _ASM_MICROBLAZE_LMB_H */
+
+
diff --git a/include/asm-mn10300/local.h b/arch/microblaze/include/asm/local.h
index c11c530f74d..c11c530f74d 100644
--- a/include/asm-mn10300/local.h
+++ b/arch/microblaze/include/asm/local.h
diff --git a/arch/microblaze/include/asm/mman.h b/arch/microblaze/include/asm/mman.h
new file mode 100644
index 00000000000..4914b132944
--- /dev/null
+++ b/arch/microblaze/include/asm/mman.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_MMAN_H
+#define _ASM_MICROBLAZE_MMAN_H
+
+#include <asm-generic/mman.h>
+
+#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
+#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
+#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
+#define MAP_LOCKED 0x2000 /* pages are locked */
+#define MAP_NORESERVE 0x4000 /* don't check for reservations */
+#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
+#define MAP_NONBLOCK 0x10000 /* do not block on IO */
+
+#define MCL_CURRENT 1 /* lock all current mappings */
+#define MCL_FUTURE 2 /* lock all future mappings */
+
+#endif /* _ASM_MICROBLAZE_MMAN_H */
diff --git a/arch/microblaze/include/asm/mmu.h b/arch/microblaze/include/asm/mmu.h
new file mode 100644
index 00000000000..0e0431d6163
--- /dev/null
+++ b/arch/microblaze/include/asm/mmu.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_MMU_H
+#define _ASM_MICROBLAZE_MMU_H
+
+#ifndef __ASSEMBLY__
+typedef struct {
+ struct vm_list_struct *vmlist;
+ unsigned long end_brk;
+} mm_context_t;
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_MMU_H */
diff --git a/arch/microblaze/include/asm/mmu_context.h b/arch/microblaze/include/asm/mmu_context.h
new file mode 100644
index 00000000000..150ca01b74b
--- /dev/null
+++ b/arch/microblaze/include/asm/mmu_context.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_MMU_CONTEXT_H
+#define _ASM_MICROBLAZE_MMU_CONTEXT_H
+
+# define init_new_context(tsk, mm) ({ 0; })
+
+# define enter_lazy_tlb(mm, tsk) do {} while (0)
+# define change_mm_context(old, ctx, _pml4) do {} while (0)
+# define destroy_context(mm) do {} while (0)
+# define deactivate_mm(tsk, mm) do {} while (0)
+# define switch_mm(prev, next, tsk) do {} while (0)
+# define activate_mm(prev, next) do {} while (0)
+
+#endif /* _ASM_MICROBLAZE_MMU_CONTEXT_H */
diff --git a/arch/microblaze/include/asm/module.h b/arch/microblaze/include/asm/module.h
new file mode 100644
index 00000000000..914565a9031
--- /dev/null
+++ b/arch/microblaze/include/asm/module.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_MODULE_H
+#define _ASM_MICROBLAZE_MODULE_H
+
+/* Microblaze Relocations */
+#define R_MICROBLAZE_NONE 0
+#define R_MICROBLAZE_32 1
+#define R_MICROBLAZE_32_PCREL 2
+#define R_MICROBLAZE_64_PCREL 3
+#define R_MICROBLAZE_32_PCREL_LO 4
+#define R_MICROBLAZE_64 5
+#define R_MICROBLAZE_32_LO 6
+#define R_MICROBLAZE_SRO32 7
+#define R_MICROBLAZE_SRW32 8
+#define R_MICROBLAZE_64_NONE 9
+#define R_MICROBLAZE_32_SYM_OP_SYM 10
+/* Keep this the last entry. */
+#define R_MICROBLAZE_NUM 11
+
+struct mod_arch_specific {
+ int foo;
+};
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+
+typedef struct { volatile int counter; } module_t;
+
+#endif /* _ASM_MICROBLAZE_MODULE_H */
diff --git a/arch/microblaze/include/asm/msgbuf.h b/arch/microblaze/include/asm/msgbuf.h
new file mode 100644
index 00000000000..09dd9709721
--- /dev/null
+++ b/arch/microblaze/include/asm/msgbuf.h
@@ -0,0 +1,31 @@
+#ifndef _ASM_MICROBLAZE_MSGBUF_H
+#define _ASM_MICROBLAZE_MSGBUF_H
+
+/*
+ * The msqid64_ds structure for microblaze architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+ struct ipc64_perm msg_perm;
+ __kernel_time_t msg_stime; /* last msgsnd time */
+ unsigned long __unused1;
+ __kernel_time_t msg_rtime; /* last msgrcv time */
+ unsigned long __unused2;
+ __kernel_time_t msg_ctime; /* last change time */
+ unsigned long __unused3;
+ unsigned long msg_cbytes; /* current number of bytes on queue */
+ unsigned long msg_qnum; /* number of messages in queue */
+ unsigned long msg_qbytes; /* max number of bytes on queue */
+ __kernel_pid_t msg_lspid; /* pid of last msgsnd */
+ __kernel_pid_t msg_lrpid; /* last receive pid */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+#endif /* _ASM_MICROBLAZE_MSGBUF_H */
diff --git a/arch/microblaze/include/asm/mutex.h b/arch/microblaze/include/asm/mutex.h
new file mode 100644
index 00000000000..ff6101aa2c7
--- /dev/null
+++ b/arch/microblaze/include/asm/mutex.h
@@ -0,0 +1 @@
+#include <asm-generic/mutex-dec.h>
diff --git a/arch/microblaze/include/asm/namei.h b/arch/microblaze/include/asm/namei.h
new file mode 100644
index 00000000000..61d60b8a07d
--- /dev/null
+++ b/arch/microblaze/include/asm/namei.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_NAMEI_H
+#define _ASM_MICROBLAZE_NAMEI_H
+
+#ifdef __KERNEL__
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+#define __emul_prefix() NULL
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_MICROBLAZE_NAMEI_H */
diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h
new file mode 100644
index 00000000000..ba917cfaefe
--- /dev/null
+++ b/arch/microblaze/include/asm/of_device.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ *
+ * based on PowerPC of_device.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_OF_DEVICE_H
+#define _ASM_MICROBLAZE_OF_DEVICE_H
+#ifdef __KERNEL__
+
+#include <linux/device.h>
+#include <linux/of.h>
+
+/*
+ * The of_device is a kind of "base class" that is a superset of
+ * struct device for use by devices attached to an OF node and
+ * probed using OF properties.
+ */
+struct of_device {
+ struct device_node *node; /* to be obsoleted */
+ u64 dma_mask; /* DMA mask */
+ struct device dev; /* Generic device interface */
+};
+
+extern ssize_t of_device_get_modalias(struct of_device *ofdev,
+ char *str, ssize_t len);
+
+extern struct of_device *of_device_alloc(struct device_node *np,
+ const char *bus_id,
+ struct device *parent);
+
+extern int of_device_uevent(struct device *dev,
+ struct kobj_uevent_env *env);
+
+extern void of_device_make_bus_id(struct of_device *dev);
+
+/* This is just here during the transition */
+#include <linux/of_device.h>
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_OF_DEVICE_H */
diff --git a/arch/microblaze/include/asm/of_platform.h b/arch/microblaze/include/asm/of_platform.h
new file mode 100644
index 00000000000..187c0eedaec
--- /dev/null
+++ b/arch/microblaze/include/asm/of_platform.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.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.
+ */
+
+#ifndef _ASM_MICROBLAZE_OF_PLATFORM_H
+#define _ASM_MICROBLAZE_OF_PLATFORM_H
+
+/* This is just here during the transition */
+#include <linux/of_platform.h>
+
+/*
+ * The list of OF IDs below is used for matching bus types in the
+ * system whose devices are to be exposed as of_platform_devices.
+ *
+ * This is the default list valid for most platforms. This file provides
+ * functions who can take an explicit list if necessary though
+ *
+ * The search is always performed recursively looking for children of
+ * the provided device_node and recursively if such a children matches
+ * a bus type in the list
+ */
+
+static const struct of_device_id of_default_bus_ids[] = {
+ { .type = "soc", },
+ { .compatible = "soc", },
+ { .type = "plb5", },
+ { .type = "plb4", },
+ { .type = "opb", },
+ { .type = "simple", },
+ {},
+};
+
+/* Platform drivers register/unregister */
+static inline int of_register_platform_driver(struct of_platform_driver *drv)
+{
+ return of_register_driver(drv, &of_platform_bus_type);
+}
+static inline void of_unregister_platform_driver(struct of_platform_driver *drv)
+{
+ of_unregister_driver(drv);
+}
+
+/* Platform devices and busses creation */
+extern struct of_device *of_platform_device_create(struct device_node *np,
+ const char *bus_id,
+ struct device *parent);
+/* pseudo "matches" value to not do deep probe */
+#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
+
+extern int of_platform_bus_probe(struct device_node *root,
+ const struct of_device_id *matches,
+ struct device *parent);
+
+extern struct of_device *of_find_device_by_phandle(phandle ph);
+
+extern void of_instantiate_rtc(void);
+
+#endif /* _ASM_MICROBLAZE_OF_PLATFORM_H */
diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h
new file mode 100644
index 00000000000..7238dcfcc51
--- /dev/null
+++ b/arch/microblaze/include/asm/page.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ * Changes for MMU support:
+ * Copyright (C) 2007 Xilinx, Inc. All rights reserved.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_PAGE_H
+#define _ASM_MICROBLAZE_PAGE_H
+
+#include <linux/pfn.h>
+#include <asm/setup.h>
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT (12)
+#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
+#define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1)))
+
+/* align addr on a size boundary - adjust address up/down if needed */
+#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1)))
+#define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1)))
+
+/* align addr on a size boundary - adjust address up if needed */
+#define _ALIGN(addr, size) _ALIGN_UP(addr, size)
+
+/*
+ * PAGE_OFFSET -- the first address of the first page of memory. When not
+ * using MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ */
+extern unsigned int __page_offset;
+#define PAGE_OFFSET __page_offset
+
+#define copy_page(to, from) memcpy((to), (from), PAGE_SIZE)
+#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr) free_page(addr)
+
+#define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE)
+
+
+#define clear_user_page(pgaddr, vaddr, page) memset((pgaddr), 0, PAGE_SIZE)
+#define copy_user_page(vto, vfrom, vaddr, topg) \
+ memcpy((vto), (vfrom), PAGE_SIZE)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct page *pgtable_t;
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct { unsigned long ste[64]; } pmd_t;
+typedef struct { pmd_t pue[1]; } pud_t;
+typedef struct { pud_t pge[1]; } pgd_t;
+
+
+#define pte_val(x) ((x).pte)
+#define pgprot_val(x) ((x).pgprot)
+#define pmd_val(x) ((x).ste[0])
+#define pud_val(x) ((x).pue[0])
+#define pgd_val(x) ((x).pge[0])
+
+#define __pte(x) ((pte_t) { (x) })
+#define __pmd(x) ((pmd_t) { (x) })
+#define __pgd(x) ((pgd_t) { (x) })
+#define __pgprot(x) ((pgprot_t) { (x) })
+
+/**
+ * Conversions for virtual address, physical address, pfn, and struct
+ * page are defined in the following files.
+ *
+ * virt -+
+ * | asm-microblaze/page.h
+ * phys -+
+ * | linux/pfn.h
+ * pfn -+
+ * | asm-generic/memory_model.h
+ * page -+
+ *
+ */
+
+extern unsigned long max_low_pfn;
+extern unsigned long min_low_pfn;
+extern unsigned long max_pfn;
+
+#define __pa(vaddr) ((unsigned long) (vaddr))
+#define __va(paddr) ((void *) (paddr))
+
+#define phys_to_pfn(phys) (PFN_DOWN(phys))
+#define pfn_to_phys(pfn) (PFN_PHYS(pfn))
+
+#define virt_to_pfn(vaddr) (phys_to_pfn((__pa(vaddr))))
+#define pfn_to_virt(pfn) __va(pfn_to_phys((pfn)))
+
+#define virt_to_page(vaddr) (pfn_to_page(virt_to_pfn(vaddr)))
+#define page_to_virt(page) (pfn_to_virt(page_to_pfn(page)))
+
+#define page_to_phys(page) (pfn_to_phys(page_to_pfn(page)))
+#define page_to_bus(page) (page_to_phys(page))
+#define phys_to_page(paddr) (pfn_to_page(phys_to_pfn(paddr)))
+
+extern unsigned int memory_start;
+extern unsigned int memory_end;
+extern unsigned int memory_size;
+
+#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_mapnr)
+
+#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT)
+
+#else
+#define tophys(rd, rs) (addik rd, rs, 0)
+#define tovirt(rd, rs) (addik rd, rs, 0)
+#endif /* __ASSEMBLY__ */
+
+#define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr)))
+
+/* Convert between virtual and physical address for MMU. */
+/* Handle MicroBlaze processor with virtual memory. */
+#define __virt_to_phys(addr) addr
+#define __phys_to_virt(addr) addr
+
+#define TOPHYS(addr) __virt_to_phys(addr)
+
+#endif /* __KERNEL__ */
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/page.h>
+
+#endif /* _ASM_MICROBLAZE_PAGE_H */
diff --git a/arch/microblaze/include/asm/param.h b/arch/microblaze/include/asm/param.h
new file mode 100644
index 00000000000..8c538a49616
--- /dev/null
+++ b/arch/microblaze/include/asm/param.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_PARAM_H
+#define _ASM_MICROBLAZE_PARAM_H
+
+#ifdef __KERNEL__
+#define HZ CONFIG_HZ /* internal kernel timer frequency */
+#define USER_HZ 100 /* for user interfaces in "ticks" */
+#define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */
+#endif /* __KERNEL__ */
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define EXEC_PAGESIZE 4096
+
+#ifndef NOGROUP
+#define NOGROUP (-1)
+#endif
+
+#define MAXHOSTNAMELEN 64 /* max length of hostname */
+
+#endif /* _ASM_MICROBLAZE_PARAM_H */
diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
new file mode 100644
index 00000000000..7ad28f6f5f1
--- /dev/null
+++ b/arch/microblaze/include/asm/pci-bridge.h
@@ -0,0 +1 @@
+#include <linux/pci.h>
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h
new file mode 100644
index 00000000000..ca03794cf3f
--- /dev/null
+++ b/arch/microblaze/include/asm/pci.h
@@ -0,0 +1 @@
+#include <linux/io.h>
diff --git a/include/asm-mn10300/percpu.h b/arch/microblaze/include/asm/percpu.h
index 06a959d6723..06a959d6723 100644
--- a/include/asm-mn10300/percpu.h
+++ b/arch/microblaze/include/asm/percpu.h
diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h
new file mode 100644
index 00000000000..2a4b3548401
--- /dev/null
+++ b/arch/microblaze/include/asm/pgalloc.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_PGALLOC_H
+#define _ASM_MICROBLAZE_PGALLOC_H
+
+#define check_pgt_cache() do {} while (0)
+
+#endif /* _ASM_MICROBLAZE_PGALLOC_H */
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h
new file mode 100644
index 00000000000..4df31e46568
--- /dev/null
+++ b/arch/microblaze/include/asm/pgtable.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_PGTABLE_H
+#define _ASM_MICROBLAZE_PGTABLE_H
+
+#include <asm/setup.h>
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define pgd_present(pgd) (1) /* pages are always present on non MMU */
+#define pgd_none(pgd) (0)
+#define pgd_bad(pgd) (0)
+#define pgd_clear(pgdp)
+#define kern_addr_valid(addr) (1)
+#define pmd_offset(a, b) ((void *) 0)
+
+#define PAGE_NONE __pgprot(0) /* these mean nothing to non MMU */
+#define PAGE_SHARED __pgprot(0) /* these mean nothing to non MMU */
+#define PAGE_COPY __pgprot(0) /* these mean nothing to non MMU */
+#define PAGE_READONLY __pgprot(0) /* these mean nothing to non MMU */
+#define PAGE_KERNEL __pgprot(0) /* these mean nothing to non MMU */
+
+#define __swp_type(x) (0)
+#define __swp_offset(x) (0)
+#define __swp_entry(typ, off) ((swp_entry_t) { ((typ) | ((off) << 7)) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
+
+#ifndef __ASSEMBLY__
+static inline int pte_file(pte_t pte) { return 0; }
+#endif /* __ASSEMBLY__ */
+
+#define ZERO_PAGE(vaddr) ({ BUG(); NULL; })
+
+#define swapper_pg_dir ((pgd_t *) NULL)
+
+#define pgtable_cache_init() do {} while (0)
+
+#define arch_enter_lazy_cpu_mode() do {} while (0)
+
+#ifndef __ASSEMBLY__
+#include <asm-generic/pgtable.h>
+
+void setup_memory(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_PGTABLE_H */
diff --git a/include/asm-mn10300/poll.h b/arch/microblaze/include/asm/poll.h
index c98509d3149..c98509d3149 100644
--- a/include/asm-mn10300/poll.h
+++ b/arch/microblaze/include/asm/poll.h
diff --git a/arch/microblaze/include/asm/posix_types.h b/arch/microblaze/include/asm/posix_types.h
new file mode 100644
index 00000000000..b4df41c5dde
--- /dev/null
+++ b/arch/microblaze/include/asm/posix_types.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_POSIX_TYPES_H
+#define _ASM_MICROBLAZE_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc. Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long __kernel_ino_t;
+typedef unsigned int __kernel_mode_t;
+typedef unsigned int __kernel_nlink_t;
+typedef long __kernel_off_t;
+typedef int __kernel_pid_t;
+typedef unsigned int __kernel_ipc_pid_t;
+typedef unsigned int __kernel_uid_t;
+typedef unsigned int __kernel_gid_t;
+typedef unsigned long __kernel_size_t;
+typedef long __kernel_ssize_t;
+typedef int __kernel_ptrdiff_t;
+typedef long __kernel_time_t;
+typedef long __kernel_suseconds_t;
+typedef long __kernel_clock_t;
+typedef int __kernel_timer_t;
+typedef int __kernel_clockid_t;
+typedef int __kernel_daddr_t;
+typedef char *__kernel_caddr_t;
+typedef unsigned short __kernel_uid16_t;
+typedef unsigned short __kernel_gid16_t;
+typedef unsigned int __kernel_uid32_t;
+typedef unsigned int __kernel_gid32_t;
+
+typedef unsigned int __kernel_old_uid_t;
+typedef unsigned int __kernel_old_gid_t;
+typedef unsigned int __kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long __kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+ int val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+ int __val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef __FD_SET
+#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+
+#undef __FD_CLR
+#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+
+#undef __FD_ISSET
+#define __FD_ISSET(d, set) (!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d)))
+
+#undef __FD_ZERO
+#define __FD_ZERO(fdsetp) (memset(fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif /* _ASM_MICROBLAZE_POSIX_TYPES_H */
diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h
new file mode 100644
index 00000000000..d8e15434ba2
--- /dev/null
+++ b/arch/microblaze/include/asm/processor.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_PROCESSOR_H
+#define _ASM_MICROBLAZE_PROCESSOR_H
+
+#include <asm/ptrace.h>
+#include <asm/setup.h>
+#include <asm/registers.h>
+#include <asm/segment.h>
+
+# ifndef __ASSEMBLY__
+/* from kernel/cpu/mb.c */
+extern const struct seq_operations cpuinfo_op;
+
+# define cpu_relax() barrier()
+# define cpu_sleep() do {} while (0)
+# define prepare_to_copy(tsk) do {} while (0)
+
+# endif /* __ASSEMBLY__ */
+
+/*
+ * User space process size: memory size
+ *
+ * TASK_SIZE on MMU cpu is usually 1GB. However, on no-MMU arch, both
+ * user processes and the kernel is on the same memory region. They
+ * both share the memory space and that is limited by the amount of
+ * physical memory. thus, we set TASK_SIZE == amount of total memory.
+ */
+# define TASK_SIZE (0x81000000 - 0x80000000)
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+# define current_text_addr() ({ __label__ _l; _l: &&_l; })
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's. We won't be using it
+ */
+# define TASK_UNMAPPED_BASE 0
+
+/* definition in include/linux/sched.h */
+struct task_struct;
+
+/* thread_struct is gone. use thread_info instead. */
+struct thread_struct { };
+# define INIT_THREAD { }
+
+/* Do necessary setup to start up a newly executed thread. */
+static inline void start_thread(struct pt_regs *regs,
+ unsigned long pc,
+ unsigned long usp)
+{
+ regs->pc = pc;
+ regs->r1 = usp;
+ regs->kernel_mode = 0;
+}
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+/* Free all resources held by a thread. */
+static inline void exit_thread(void)
+{
+}
+
+extern unsigned long thread_saved_pc(struct task_struct *t);
+
+extern unsigned long get_wchan(struct task_struct *p);
+
+/*
+ * create a kernel thread without removing it from tasklists
+ */
+extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+
+# define task_pt_regs(tsk) \
+ (((struct pt_regs *)(THREAD_SIZE + task_stack_page(tsk))) - 1)
+
+# define KSTK_EIP(tsk) (0)
+# define KSTK_ESP(tsk) (0)
+
+#endif /* _ASM_MICROBLAZE_PROCESSOR_H */
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
new file mode 100644
index 00000000000..20f7b3a926e
--- /dev/null
+++ b/arch/microblaze/include/asm/prom.h
@@ -0,0 +1,313 @@
+/*
+ * Definitions for talking to the Open Firmware PROM on
+ * Power Macintosh computers.
+ *
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM 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; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MICROBLAZE_PROM_H
+#define _ASM_MICROBLAZE_PROM_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/platform_device.h>
+#include <asm/irq.h>
+#include <asm/atomic.h>
+
+#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
+#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
+
+#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l))
+#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
+#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
+
+/* Definitions used by the flattened device tree */
+#define OF_DT_HEADER 0xd00dfeed /* marker */
+#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
+#define OF_DT_END_NODE 0x2 /* End node */
+#define OF_DT_PROP 0x3 /* Property: name off, size, content */
+#define OF_DT_NOP 0x4 /* nop */
+#define OF_DT_END 0x9
+
+#define OF_DT_VERSION 0x10
+
+/*
+ * This is what gets passed to the kernel by prom_init or kexec
+ *
+ * The dt struct contains the device tree structure, full pathes and
+ * property contents. The dt strings contain a separate block with just
+ * the strings for the property names, and is fully page aligned and
+ * self contained in a page, so that it can be kept around by the kernel,
+ * each property name appears only once in this page (cheap compression)
+ *
+ * the mem_rsvmap contains a map of reserved ranges of physical memory,
+ * passing it here instead of in the device-tree itself greatly simplifies
+ * the job of everybody. It's just a list of u64 pairs (base/size) that
+ * ends when size is 0
+ */
+struct boot_param_header {
+ u32 magic; /* magic word OF_DT_HEADER */
+ u32 totalsize; /* total size of DT block */
+ u32 off_dt_struct; /* offset to structure */
+ u32 off_dt_strings; /* offset to strings */
+ u32 off_mem_rsvmap; /* offset to memory reserve map */
+ u32 version; /* format version */
+ u32 last_comp_version; /* last compatible version */
+ /* version 2 fields below */
+ u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
+ /* version 3 fields below */
+ u32 dt_strings_size; /* size of the DT strings block */
+ /* version 17 fields below */
+ u32 dt_struct_size; /* size of the DT structure block */
+};
+
+typedef u32 phandle;
+typedef u32 ihandle;
+
+struct property {
+ char *name;
+ int length;
+ void *value;
+ struct property *next;
+};
+
+struct device_node {
+ const char *name;
+ const char *type;
+ phandle node;
+ phandle linux_phandle;
+ char *full_name;
+
+ struct property *properties;
+ struct property *deadprops; /* removed properties */
+ struct device_node *parent;
+ struct device_node *child;
+ struct device_node *sibling;
+ struct device_node *next; /* next device of same type */
+ struct device_node *allnext; /* next in list of all nodes */
+ struct proc_dir_entry *pde; /* this node's proc directory */
+ struct kref kref;
+ unsigned long _flags;
+ void *data;
+};
+
+extern struct device_node *of_chosen;
+
+static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
+{
+ return test_bit(flag, &n->_flags);
+}
+
+static inline void of_node_set_flag(struct device_node *n, unsigned long flag)
+{
+ set_bit(flag, &n->_flags);
+}
+
+#define HAVE_ARCH_DEVTREE_FIXUPS
+
+static inline void set_node_proc_entry(struct device_node *dn,
+ struct proc_dir_entry *de)
+{
+ dn->pde = de;
+}
+
+extern struct device_node *allnodes; /* temporary while merging */
+extern rwlock_t devtree_lock; /* temporary while merging */
+
+extern struct device_node *of_find_all_nodes(struct device_node *prev);
+extern struct device_node *of_node_get(struct device_node *node);
+extern void of_node_put(struct device_node *node);
+
+/* For scanning the flat device-tree at boot time */
+extern int __init of_scan_flat_dt(int (*it)(unsigned long node,
+ const char *uname, int depth,
+ void *data),
+ void *data);
+extern void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
+ unsigned long *size);
+extern int __init
+ of_flat_dt_is_compatible(unsigned long node, const char *name);
+extern unsigned long __init of_get_flat_dt_root(void);
+
+/* For updating the device tree at runtime */
+extern void of_attach_node(struct device_node *);
+extern void of_detach_node(struct device_node *);
+
+/* Other Prototypes */
+extern void finish_device_tree(void);
+extern void unflatten_device_tree(void);
+extern int early_uartlite_console(void);
+extern void early_init_devtree(void *);
+extern int machine_is_compatible(const char *compat);
+extern void print_properties(struct device_node *node);
+extern int prom_n_intr_cells(struct device_node *np);
+extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
+extern int prom_add_property(struct device_node *np, struct property *prop);
+extern int prom_remove_property(struct device_node *np, struct property *prop);
+extern int prom_update_property(struct device_node *np,
+ struct property *newprop,
+ struct property *oldprop);
+
+extern struct resource *request_OF_resource(struct device_node *node,
+ int index, const char *name_postfix);
+extern int release_OF_resource(struct device_node *node, int index);
+
+/*
+ * OF address retreival & translation
+ */
+
+/* Helper to read a big number; size is in cells (not bytes) */
+static inline u64 of_read_number(const u32 *cell, int size)
+{
+ u64 r = 0;
+ while (size--)
+ r = (r << 32) | *(cell++);
+ return r;
+}
+
+/* Like of_read_number, but we want an unsigned long result */
+#define of_read_ulong(cell, size) of_read_number(cell, size)
+
+/* Translate an OF address block into a CPU physical address
+ */
+extern u64 of_translate_address(struct device_node *np, const u32 *addr);
+
+/* Extract an address from a device, returns the region size and
+ * the address space flags too. The PCI version uses a BAR number
+ * instead of an absolute index
+ */
+extern const u32 *of_get_address(struct device_node *dev, int index,
+ u64 *size, unsigned int *flags);
+extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
+ u64 *size, unsigned int *flags);
+
+/* Get an address as a resource. Note that if your address is
+ * a PIO address, the conversion will fail if the physical address
+ * can't be internally converted to an IO token with
+ * pci_address_to_pio(), that is because it's either called to early
+ * or it can't be matched to any host bridge IO space
+ */
+extern int of_address_to_resource(struct device_node *dev, int index,
+ struct resource *r);
+extern int of_pci_address_to_resource(struct device_node *dev, int bar,
+ struct resource *r);
+
+/* Parse the ibm,dma-window property of an OF node into the busno, phys and
+ * size parameters.
+ */
+void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
+ unsigned long *busno, unsigned long *phys, unsigned long *size);
+
+extern void kdump_move_device_tree(void);
+
+/* CPU OF node matching */
+struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
+
+/* Get the MAC address */
+extern const void *of_get_mac_address(struct device_node *np);
+
+/*
+ * OF interrupt mapping
+ */
+
+/* This structure is returned when an interrupt is mapped. The controller
+ * field needs to be put() after use
+ */
+
+#define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */
+
+struct of_irq {
+ struct device_node *controller; /* Interrupt controller node */
+ u32 size; /* Specifier size */
+ u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
+};
+
+/**
+ * of_irq_map_init - Initialize the irq remapper
+ * @flags: flags defining workarounds to enable
+ *
+ * Some machines have bugs in the device-tree which require certain workarounds
+ * to be applied. Call this before any interrupt mapping attempts to enable
+ * those workarounds.
+ */
+#define OF_IMAP_OLDWORLD_MAC 0x00000001
+#define OF_IMAP_NO_PHANDLE 0x00000002
+
+extern void of_irq_map_init(unsigned int flags);
+
+/**
+ * of_irq_map_raw - Low level interrupt tree parsing
+ * @parent: the device interrupt parent
+ * @intspec: interrupt specifier ("interrupts" property of the device)
+ * @ointsize: size of the passed in interrupt specifier
+ * @addr: address specifier (start of "reg" property of the device)
+ * @out_irq: structure of_irq filled by this function
+ *
+ * Returns 0 on success and a negative number on error
+ *
+ * This function is a low-level interrupt tree walking function. It
+ * can be used to do a partial walk with synthetized reg and interrupts
+ * properties, for example when resolving PCI interrupts when no device
+ * node exist for the parent.
+ *
+ */
+
+extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
+ u32 ointsize, const u32 *addr,
+ struct of_irq *out_irq);
+
+/**
+ * of_irq_map_one - Resolve an interrupt for a device
+ * @device: the device whose interrupt is to be resolved
+ * @index: index of the interrupt to resolve
+ * @out_irq: structure of_irq filled by this function
+ *
+ * This function resolves an interrupt, walking the tree, for a given
+ * device-tree node. It's the high level pendant to of_irq_map_raw().
+ * It also implements the workarounds for OldWolrd Macs.
+ */
+extern int of_irq_map_one(struct device_node *device, int index,
+ struct of_irq *out_irq);
+
+/**
+ * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * @pdev: the device whose interrupt is to be resolved
+ * @out_irq: structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+struct pci_dev;
+extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+
+extern int of_irq_to_resource(struct device_node *dev, int index,
+ struct resource *r);
+
+/**
+ * of_iomap - Maps the memory mapped IO for a given device_node
+ * @device: the device whose io range will be mapped
+ * @index: index of the io range
+ *
+ * Returns a pointer to the mapped memory
+ */
+extern void __iomem *of_iomap(struct device_node *device, int index);
+
+/*
+ * NB: This is here while we transition from using asm/prom.h
+ * to linux/of.h
+ */
+#include <linux/of.h>
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_PROM_H */
diff --git a/arch/microblaze/include/asm/ptrace.h b/arch/microblaze/include/asm/ptrace.h
new file mode 100644
index 00000000000..f1f03486428
--- /dev/null
+++ b/arch/microblaze/include/asm/ptrace.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_PTRACE_H
+#define _ASM_MICROBLAZE_PTRACE_H
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+typedef unsigned long microblaze_reg_t;
+
+struct pt_regs {
+ microblaze_reg_t r0;
+ microblaze_reg_t r1;
+ microblaze_reg_t r2;
+ microblaze_reg_t r3;
+ microblaze_reg_t r4;
+ microblaze_reg_t r5;
+ microblaze_reg_t r6;
+ microblaze_reg_t r7;
+ microblaze_reg_t r8;
+ microblaze_reg_t r9;
+ microblaze_reg_t r10;
+ microblaze_reg_t r11;
+ microblaze_reg_t r12;
+ microblaze_reg_t r13;
+ microblaze_reg_t r14;
+ microblaze_reg_t r15;
+ microblaze_reg_t r16;
+ microblaze_reg_t r17;
+ microblaze_reg_t r18;
+ microblaze_reg_t r19;
+ microblaze_reg_t r20;
+ microblaze_reg_t r21;
+ microblaze_reg_t r22;
+ microblaze_reg_t r23;
+ microblaze_reg_t r24;
+ microblaze_reg_t r25;
+ microblaze_reg_t r26;
+ microblaze_reg_t r27;
+ microblaze_reg_t r28;
+ microblaze_reg_t r29;
+ microblaze_reg_t r30;
+ microblaze_reg_t r31;
+ microblaze_reg_t pc;
+ microblaze_reg_t msr;
+ microblaze_reg_t ear;
+ microblaze_reg_t esr;
+ microblaze_reg_t fsr;
+ int kernel_mode;
+};
+
+#define kernel_mode(regs) ((regs)->kernel_mode)
+#define user_mode(regs) (!kernel_mode(regs))
+
+#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
+
+void show_regs(struct pt_regs *);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_PTRACE_H */
diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h
new file mode 100644
index 00000000000..66f1b30dd09
--- /dev/null
+++ b/arch/microblaze/include/asm/pvr.h
@@ -0,0 +1,209 @@
+/*
+ * Support for the MicroBlaze PVR (Processor Version Register)
+ *
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ * Copyright (C) 2007 - 2009 PetaLogix
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_PVR_H
+#define _ASM_MICROBLAZE_PVR_H
+
+#define PVR_MSR_BIT 0x400
+
+struct pvr_s {
+ unsigned pvr[16];
+};
+
+/* The following taken from Xilinx's standalone BSP pvr.h */
+
+/* Basic PVR mask */
+#define PVR0_PVR_FULL_MASK 0x80000000
+#define PVR0_USE_BARREL_MASK 0x40000000
+#define PVR0_USE_DIV_MASK 0x20000000
+#define PVR0_USE_HW_MUL_MASK 0x10000000
+#define PVR0_USE_FPU_MASK 0x08000000
+#define PVR0_USE_EXC_MASK 0x04000000
+#define PVR0_USE_ICACHE_MASK 0x02000000
+#define PVR0_USE_DCACHE_MASK 0x01000000
+#define PVR0_USE_MMU 0x00800000 /* new */
+#define PVR0_VERSION_MASK 0x0000FF00
+#define PVR0_USER1_MASK 0x000000FF
+
+/* User 2 PVR mask */
+#define PVR1_USER2_MASK 0xFFFFFFFF
+
+/* Configuration PVR masks */
+#define PVR2_D_OPB_MASK 0x80000000
+#define PVR2_D_LMB_MASK 0x40000000
+#define PVR2_I_OPB_MASK 0x20000000
+#define PVR2_I_LMB_MASK 0x10000000
+#define PVR2_INTERRUPT_IS_EDGE_MASK 0x08000000
+#define PVR2_EDGE_IS_POSITIVE_MASK 0x04000000
+#define PVR2_D_PLB_MASK 0x02000000 /* new */
+#define PVR2_I_PLB_MASK 0x01000000 /* new */
+#define PVR2_INTERCONNECT 0x00800000 /* new */
+#define PVR2_USE_EXTEND_FSL 0x00080000 /* new */
+#define PVR2_USE_FSL_EXC 0x00040000 /* new */
+#define PVR2_USE_MSR_INSTR 0x00020000
+#define PVR2_USE_PCMP_INSTR 0x00010000
+#define PVR2_AREA_OPTIMISED 0x00008000
+#define PVR2_USE_BARREL_MASK 0x00004000
+#define PVR2_USE_DIV_MASK 0x00002000
+#define PVR2_USE_HW_MUL_MASK 0x00001000
+#define PVR2_USE_FPU_MASK 0x00000800
+#define PVR2_USE_MUL64_MASK 0x00000400
+#define PVR2_USE_FPU2_MASK 0x00000200 /* new */
+#define PVR2_USE_IPLBEXC 0x00000100
+#define PVR2_USE_DPLBEXC 0x00000080
+#define PVR2_OPCODE_0x0_ILL_MASK 0x00000040
+#define PVR2_UNALIGNED_EXC_MASK 0x00000020
+#define PVR2_ILL_OPCODE_EXC_MASK 0x00000010
+#define PVR2_IOPB_BUS_EXC_MASK 0x00000008
+#define PVR2_DOPB_BUS_EXC_MASK 0x00000004
+#define PVR2_DIV_ZERO_EXC_MASK 0x00000002
+#define PVR2_FPU_EXC_MASK 0x00000001
+
+/* Debug and exception PVR masks */
+#define PVR3_DEBUG_ENABLED_MASK 0x80000000
+#define PVR3_NUMBER_OF_PC_BRK_MASK 0x1E000000
+#define PVR3_NUMBER_OF_RD_ADDR_BRK_MASK 0x00380000
+#define PVR3_NUMBER_OF_WR_ADDR_BRK_MASK 0x0000E000
+#define PVR3_FSL_LINKS_MASK 0x00000380
+
+/* ICache config PVR masks */
+#define PVR4_USE_ICACHE_MASK 0x80000000
+#define PVR4_ICACHE_ADDR_TAG_BITS_MASK 0x7C000000
+#define PVR4_ICACHE_USE_FSL_MASK 0x02000000
+#define PVR4_ICACHE_ALLOW_WR_MASK 0x01000000
+#define PVR4_ICACHE_LINE_LEN_MASK 0x00E00000
+#define PVR4_ICACHE_BYTE_SIZE_MASK 0x001F0000
+
+/* DCache config PVR masks */
+#define PVR5_USE_DCACHE_MASK 0x80000000
+#define PVR5_DCACHE_ADDR_TAG_BITS_MASK 0x7C000000
+#define PVR5_DCACHE_USE_FSL_MASK 0x02000000
+#define PVR5_DCACHE_ALLOW_WR_MASK 0x01000000
+#define PVR5_DCACHE_LINE_LEN_MASK 0x00E00000
+#define PVR5_DCACHE_BYTE_SIZE_MASK 0x001F0000
+
+/* ICache base address PVR mask */
+#define PVR6_ICACHE_BASEADDR_MASK 0xFFFFFFFF
+
+/* ICache high address PVR mask */
+#define PVR7_ICACHE_HIGHADDR_MASK 0xFFFFFFFF
+
+/* DCache base address PVR mask */
+#define PVR8_DCACHE_BASEADDR_MASK 0xFFFFFFFF
+
+/* DCache high address PVR mask */
+#define PVR9_DCACHE_HIGHADDR_MASK 0xFFFFFFFF
+
+/* Target family PVR mask */
+#define PVR10_TARGET_FAMILY_MASK 0xFF000000
+
+/* MMU descrtiption */
+#define PVR11_USE_MMU 0xC0000000
+#define PVR11_MMU_ITLB_SIZE 0x38000000
+#define PVR11_MMU_DTLB_SIZE 0x07000000
+#define PVR11_MMU_TLB_ACCESS 0x00C00000
+#define PVR11_MMU_ZONES 0x003C0000
+/* MSR Reset value PVR mask */
+#define PVR11_MSR_RESET_VALUE_MASK 0x000007FF
+
+
+/* PVR access macros */
+#define PVR_IS_FULL(pvr) (pvr.pvr[0] & PVR0_PVR_FULL_MASK)
+#define PVR_USE_BARREL(pvr) (pvr.pvr[0] & PVR0_USE_BARREL_MASK)
+#define PVR_USE_DIV(pvr) (pvr.pvr[0] & PVR0_USE_DIV_MASK)
+#define PVR_USE_HW_MUL(pvr) (pvr.pvr[0] & PVR0_USE_HW_MUL_MASK)
+#define PVR_USE_FPU(pvr) (pvr.pvr[0] & PVR0_USE_FPU_MASK)
+#define PVR_USE_FPU2(pvr) (pvr.pvr[2] & PVR2_USE_FPU2_MASK)
+#define PVR_USE_ICACHE(pvr) (pvr.pvr[0] & PVR0_USE_ICACHE_MASK)
+#define PVR_USE_DCACHE(pvr) (pvr.pvr[0] & PVR0_USE_DCACHE_MASK)
+#define PVR_VERSION(pvr) ((pvr.pvr[0] & PVR0_VERSION_MASK) >> 8)
+#define PVR_USER1(pvr) (pvr.pvr[0] & PVR0_USER1_MASK)
+#define PVR_USER2(pvr) (pvr.pvr[1] & PVR1_USER2_MASK)
+
+#define PVR_D_OPB(pvr) (pvr.pvr[2] & PVR2_D_OPB_MASK)
+#define PVR_D_LMB(pvr) (pvr.pvr[2] & PVR2_D_LMB_MASK)
+#define PVR_I_OPB(pvr) (pvr.pvr[2] & PVR2_I_OPB_MASK)
+#define PVR_I_LMB(pvr) (pvr.pvr[2] & PVR2_I_LMB_MASK)
+#define PVR_INTERRUPT_IS_EDGE(pvr) \
+ (pvr.pvr[2] & PVR2_INTERRUPT_IS_EDGE_MASK)
+#define PVR_EDGE_IS_POSITIVE(pvr) \
+ (pvr.pvr[2] & PVR2_EDGE_IS_POSITIVE_MASK)
+#define PVR_USE_MSR_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_MSR_INSTR)
+#define PVR_USE_PCMP_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_PCMP_INSTR)
+#define PVR_AREA_OPTIMISED(pvr) (pvr.pvr[2] & PVR2_AREA_OPTIMISED)
+#define PVR_USE_MUL64(pvr) (pvr.pvr[2] & PVR2_USE_MUL64_MASK)
+#define PVR_OPCODE_0x0_ILLEGAL(pvr) \
+ (pvr.pvr[2] & PVR2_OPCODE_0x0_ILL_MASK)
+#define PVR_UNALIGNED_EXCEPTION(pvr) \
+ (pvr.pvr[2] & PVR2_UNALIGNED_EXC_MASK)
+#define PVR_ILL_OPCODE_EXCEPTION(pvr) \
+ (pvr.pvr[2] & PVR2_ILL_OPCODE_EXC_MASK)
+#define PVR_IOPB_BUS_EXCEPTION(pvr) \
+ (pvr.pvr[2] & PVR2_IOPB_BUS_EXC_MASK)
+#define PVR_DOPB_BUS_EXCEPTION(pvr) \
+ (pvr.pvr[2] & PVR2_DOPB_BUS_EXC_MASK)
+#define PVR_DIV_ZERO_EXCEPTION(pvr) \
+ (pvr.pvr[2] & PVR2_DIV_ZERO_EXC_MASK)
+#define PVR_FPU_EXCEPTION(pvr) (pvr.pvr[2] & PVR2_FPU_EXC_MASK)
+#define PVR_FSL_EXCEPTION(pvr) (pvr.pvr[2] & PVR2_USE_EXTEND_FSL)
+
+#define PVR_DEBUG_ENABLED(pvr) (pvr.pvr[3] & PVR3_DEBUG_ENABLED_MASK)
+#define PVR_NUMBER_OF_PC_BRK(pvr) \
+ ((pvr.pvr[3] & PVR3_NUMBER_OF_PC_BRK_MASK) >> 25)
+#define PVR_NUMBER_OF_RD_ADDR_BRK(pvr) \
+ ((pvr.pvr[3] & PVR3_NUMBER_OF_RD_ADDR_BRK_MASK) >> 19)
+#define PVR_NUMBER_OF_WR_ADDR_BRK(pvr) \
+ ((pvr.pvr[3] & PVR3_NUMBER_OF_WR_ADDR_BRK_MASK) >> 13)
+#define PVR_FSL_LINKS(pvr) ((pvr.pvr[3] & PVR3_FSL_LINKS_MASK) >> 7)
+
+#define PVR_ICACHE_ADDR_TAG_BITS(pvr) \
+ ((pvr.pvr[4] & PVR4_ICACHE_ADDR_TAG_BITS_MASK) >> 26)
+#define PVR_ICACHE_USE_FSL(pvr) (pvr.pvr[4] & PVR4_ICACHE_USE_FSL_MASK)
+#define PVR_ICACHE_ALLOW_WR(pvr) (pvr.pvr[4] & PVR4_ICACHE_ALLOW_WR_MASK)
+#define PVR_ICACHE_LINE_LEN(pvr) \
+ (1 << ((pvr.pvr[4] & PVR4_ICACHE_LINE_LEN_MASK) >> 21))
+#define PVR_ICACHE_BYTE_SIZE(pvr) \
+ (1 << ((pvr.pvr[4] & PVR4_ICACHE_BYTE_SIZE_MASK) >> 16))
+
+#define PVR_DCACHE_ADDR_TAG_BITS(pvr) \
+ ((pvr.pvr[5] & PVR5_DCACHE_ADDR_TAG_BITS_MASK) >> 26)
+#define PVR_DCACHE_USE_FSL(pvr) (pvr.pvr[5] & PVR5_DCACHE_USE_FSL_MASK)
+#define PVR_DCACHE_ALLOW_WR(pvr) (pvr.pvr[5] & PVR5_DCACHE_ALLOW_WR_MASK)
+#define PVR_DCACHE_LINE_LEN(pvr) \
+ (1 << ((pvr.pvr[5] & PVR5_DCACHE_LINE_LEN_MASK) >> 21))
+#define PVR_DCACHE_BYTE_SIZE(pvr) \
+ (1 << ((pvr.pvr[5] & PVR5_DCACHE_BYTE_SIZE_MASK) >> 16))
+
+
+#define PVR_ICACHE_BASEADDR(pvr) (pvr.pvr[6] & PVR6_ICACHE_BASEADDR_MASK)
+#define PVR_ICACHE_HIGHADDR(pvr) (pvr.pvr[7] & PVR7_ICACHE_HIGHADDR_MASK)
+
+#define PVR_DCACHE_BASEADDR(pvr) (pvr.pvr[8] & PVR8_DCACHE_BASEADDR_MASK)
+#define PVR_DCACHE_HIGHADDR(pvr) (pvr.pvr[9] & PVR9_DCACHE_HIGHADDR_MASK)
+
+#define PVR_TARGET_FAMILY(pvr) ((pvr.pvr[10] & PVR10_TARGET_FAMILY_MASK) >> 24)
+
+#define PVR_MSR_RESET_VALUE(pvr) \
+ (pvr.pvr[11] & PVR11_MSR_RESET_VALUE_MASK)
+
+/* mmu */
+#define PVR_USE_MMU(pvr) ((pvr.pvr[11] & PVR11_USE_MMU) >> 30)
+#define PVR_MMU_ITLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_ITLB_SIZE)
+#define PVR_MMU_DTLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_DTLB_SIZE)
+#define PVR_MMU_TLB_ACCESS(pvr) (pvr.pvr[11] & PVR11_MMU_TLB_ACCESS)
+#define PVR_MMU_ZONES(pvr) (pvr.pvr[11] & PVR11_MMU_ZONES)
+
+
+int cpu_has_pvr(void);
+void get_pvr(struct pvr_s *pvr);
+
+#endif /* _ASM_MICROBLAZE_PVR_H */
diff --git a/arch/microblaze/include/asm/registers.h b/arch/microblaze/include/asm/registers.h
new file mode 100644
index 00000000000..834142d9356
--- /dev/null
+++ b/arch/microblaze/include/asm/registers.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_REGISTERS_H
+#define _ASM_MICROBLAZE_REGISTERS_H
+
+#define MSR_BE (1<<0) /* 0x001 */
+#define MSR_IE (1<<1) /* 0x002 */
+#define MSR_C (1<<2) /* 0x004 */
+#define MSR_BIP (1<<3) /* 0x008 */
+#define MSR_FSL (1<<4) /* 0x010 */
+#define MSR_ICE (1<<5) /* 0x020 */
+#define MSR_DZ (1<<6) /* 0x040 */
+#define MSR_DCE (1<<7) /* 0x080 */
+#define MSR_EE (1<<8) /* 0x100 */
+#define MSR_EIP (1<<9) /* 0x200 */
+#define MSR_CC (1<<31)
+
+/* Floating Point Status Register (FSR) Bits */
+#define FSR_IO (1<<4) /* Invalid operation */
+#define FSR_DZ (1<<3) /* Divide-by-zero */
+#define FSR_OF (1<<2) /* Overflow */
+#define FSR_UF (1<<1) /* Underflow */
+#define FSR_DO (1<<0) /* Denormalized operand error */
+
+#endif /* _ASM_MICROBLAZE_REGISTERS_H */
diff --git a/include/asm-mn10300/resource.h b/arch/microblaze/include/asm/resource.h
index 04bc4db8921..04bc4db8921 100644
--- a/include/asm-mn10300/resource.h
+++ b/arch/microblaze/include/asm/resource.h
diff --git a/arch/microblaze/include/asm/scatterlist.h b/arch/microblaze/include/asm/scatterlist.h
new file mode 100644
index 00000000000..08ff1d049b4
--- /dev/null
+++ b/arch/microblaze/include/asm/scatterlist.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_SCATTERLIST_H
+#define _ASM_MICROBLAZE_SCATTERLIST_H
+
+struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
+ dma_addr_t dma_address;
+ unsigned int offset;
+ unsigned int length;
+};
+
+#define sg_dma_address(sg) ((sg)->dma_address)
+#define sg_dma_len(sg) ((sg)->length)
+
+#define ISA_DMA_THRESHOLD (~0UL)
+
+#endif /* _ASM_MICROBLAZE_SCATTERLIST_H */
diff --git a/arch/microblaze/include/asm/sections.h b/arch/microblaze/include/asm/sections.h
new file mode 100644
index 00000000000..8434a43e542
--- /dev/null
+++ b/arch/microblaze/include/asm/sections.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_SECTIONS_H
+#define _ASM_MICROBLAZE_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+# ifndef __ASSEMBLY__
+extern char _ssbss[], _esbss[];
+extern unsigned long __ivt_start[], __ivt_end[];
+
+# ifdef CONFIG_MTD_UCLINUX
+extern char *_ebss;
+# endif
+
+extern u32 _fdt_start[], _fdt_end[];
+
+# endif /* !__ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_SECTIONS_H */
diff --git a/arch/microblaze/include/asm/segment.h b/arch/microblaze/include/asm/segment.h
new file mode 100644
index 00000000000..7f5dcc56eea
--- /dev/null
+++ b/arch/microblaze/include/asm/segment.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_SEGMENT_H
+#define _ASM_MICROBLAZE_SEGMENT_H
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
+
+/*
+ * On Microblaze the fs value is actually the top of the corresponding
+ * address space.
+ *
+ * The fs value determines whether argument validity checking should be
+ * performed or not. If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ *
+ * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal.
+ */
+# define KERNEL_DS ((mm_segment_t){0})
+# define USER_DS KERNEL_DS
+
+# define get_ds() (KERNEL_DS)
+# define get_fs() (current_thread_info()->addr_limit)
+# define set_fs(x) \
+ do { current_thread_info()->addr_limit = (x); } while (0)
+
+# define segment_eq(a, b) ((a).seg == (b).seg)
+
+# endif /* __ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_SEGMENT_H */
diff --git a/arch/microblaze/include/asm/selfmod.h b/arch/microblaze/include/asm/selfmod.h
new file mode 100644
index 00000000000..c42aff2e6cd
--- /dev/null
+++ b/arch/microblaze/include/asm/selfmod.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_SELFMOD_H
+#define _ASM_MICROBLAZE_SELFMOD_H
+
+/*
+ * BARRIER_BASE_ADDR is constant address for selfmod function.
+ * do not change this value - selfmod function is in
+ * arch/microblaze/kernel/selfmod.c: selfmod_function()
+ *
+ * last 16 bits is used for storing register offset
+ */
+
+#define BARRIER_BASE_ADDR 0x1234ff00
+
+void selfmod_function(const int *arr_fce, const unsigned int base);
+
+#endif /* _ASM_MICROBLAZE_SELFMOD_H */
diff --git a/arch/microblaze/include/asm/sembuf.h b/arch/microblaze/include/asm/sembuf.h
new file mode 100644
index 00000000000..b804ed71a57
--- /dev/null
+++ b/arch/microblaze/include/asm/sembuf.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_SEMBUF_H
+#define _ASM_MICROBLAZE_SEMBUF_H
+
+/*
+ * The semid64_ds structure for microblaze architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+ struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
+ __kernel_time_t sem_otime; /* last semop time */
+ unsigned long __unused1;
+ __kernel_time_t sem_ctime; /* last change time */
+ unsigned long __unused2;
+ unsigned long sem_nsems; /* no. of semaphores in array */
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+
+#endif /* _ASM_MICROBLAZE_SEMBUF_H */
diff --git a/arch/microblaze/include/asm/serial.h b/arch/microblaze/include/asm/serial.h
new file mode 100644
index 00000000000..39bfc8ce6af
--- /dev/null
+++ b/arch/microblaze/include/asm/serial.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_SERIAL_H
+#define _ASM_MICROBLAZE_SERIAL_H
+
+# define BASE_BAUD (1843200 / 16)
+
+#endif /* _ASM_MICROBLAZE_SERIAL_H */
diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h
new file mode 100644
index 00000000000..9b98e8e6aba
--- /dev/null
+++ b/arch/microblaze/include/asm/setup.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_SETUP_H
+#define _ASM_MICROBLAZE_SETUP_H
+
+#define COMMAND_LINE_SIZE 256
+
+# ifndef __ASSEMBLY__
+
+# ifdef __KERNEL__
+extern unsigned int boot_cpuid; /* move to smp.h */
+
+extern char cmd_line[COMMAND_LINE_SIZE];
+# endif/* __KERNEL__ */
+
+void early_printk(const char *fmt, ...);
+
+int setup_early_printk(char *opt);
+void disable_early_printk(void);
+
+void heartbeat(void);
+void setup_heartbeat(void);
+
+unsigned long long sched_clock(void);
+
+void time_init(void);
+void init_IRQ(void);
+void machine_early_init(const char *cmdline, unsigned int ram,
+ unsigned int fdt);
+
+void machine_restart(char *cmd);
+void machine_shutdown(void);
+void machine_halt(void);
+void machine_power_off(void);
+
+# endif /* __ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_SETUP_H */
diff --git a/arch/microblaze/include/asm/shmbuf.h b/arch/microblaze/include/asm/shmbuf.h
new file mode 100644
index 00000000000..f829c584361
--- /dev/null
+++ b/arch/microblaze/include/asm/shmbuf.h
@@ -0,0 +1,42 @@
+#ifndef _ASM_MICROBLAZE_SHMBUF_H
+#define _ASM_MICROBLAZE_SHMBUF_H
+
+/*
+ * The shmid64_ds structure for microblaze architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+ struct ipc64_perm shm_perm; /* operation perms */
+ size_t shm_segsz; /* size of segment (bytes) */
+ __kernel_time_t shm_atime; /* last attach time */
+ unsigned long __unused1;
+ __kernel_time_t shm_dtime; /* last detach time */
+ unsigned long __unused2;
+ __kernel_time_t shm_ctime; /* last change time */
+ unsigned long __unused3;
+ __kernel_pid_t shm_cpid; /* pid of creator */
+ __kernel_pid_t shm_lpid; /* pid of last operator */
+ unsigned long shm_nattch; /* no. of current attaches */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+struct shminfo64 {
+ unsigned long shmmax;
+ unsigned long shmmin;
+ unsigned long shmmni;
+ unsigned long shmseg;
+ unsigned long shmall;
+ unsigned long __unused1;
+ unsigned long __unused2;
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+#endif /* _ASM_MICROBLAZE_SHMBUF_H */
diff --git a/arch/microblaze/include/asm/shmparam.h b/arch/microblaze/include/asm/shmparam.h
new file mode 100644
index 00000000000..9f5fc2b3b6a
--- /dev/null
+++ b/arch/microblaze/include/asm/shmparam.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_MICROBLAZE_SHMPARAM_H
+#define _ASM_MICROBLAZE_SHMPARAM_H
+
+#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
+
+#endif /* _ASM_MICROBLAZE_SHMPARAM_H */
diff --git a/arch/microblaze/include/asm/sigcontext.h b/arch/microblaze/include/asm/sigcontext.h
new file mode 100644
index 00000000000..55873c80c91
--- /dev/null
+++ b/arch/microblaze/include/asm/sigcontext.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_SIGCONTEXT_H
+#define _ASM_MICROBLAZE_SIGCONTEXT_H
+
+/* FIXME should be linux/ptrace.h */
+#include <asm/ptrace.h>
+
+struct sigcontext {
+ struct pt_regs regs;
+ unsigned long oldmask;
+};
+
+#endif /* _ASM_MICROBLAZE_SIGCONTEXT_H */
diff --git a/arch/microblaze/include/asm/siginfo.h b/arch/microblaze/include/asm/siginfo.h
new file mode 100644
index 00000000000..f162911a8f5
--- /dev/null
+++ b/arch/microblaze/include/asm/siginfo.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_SIGINFO_H
+#define _ASM_MICROBLAZE_SIGINFO_H
+
+#include <linux/types.h>
+#include <asm-generic/siginfo.h>
+
+#endif /* _ASM_MICROBLAZE_SIGINFO_H */
diff --git a/arch/microblaze/include/asm/signal.h b/arch/microblaze/include/asm/signal.h
new file mode 100644
index 00000000000..9676fad3486
--- /dev/null
+++ b/arch/microblaze/include/asm/signal.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ * Yasushi SHOJI <yashi@atmark-techno.com>
+ * Tetsuya OHKAWA <tetsuya@atmark-techno.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_SIGNAL_H
+#define _ASM_MICROBLAZE_SIGNAL_H
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+/*
+#define SIGLOST 29
+*/
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP 0x00000001
+#define SA_NOCLDWAIT 0x00000002
+#define SA_SIGINFO 0x00000004
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+#define SA_RESTORER 0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+# ifndef __ASSEMBLY__
+# include <linux/types.h>
+# include <asm-generic/signal.h>
+
+/* Avoid too many header ordering problems. */
+struct siginfo;
+
+# ifdef __KERNEL__
+/*
+ * Most things should be clean enough to redefine this at will, if care
+ * is taken to make libc match.
+ */
+# define _NSIG 64
+# define _NSIG_BPW 32
+# define _NSIG_WORDS (_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t; /* at least 32 bits */
+
+typedef struct {
+ unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+struct old_sigaction {
+ __sighandler_t sa_handler;
+ old_sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+};
+
+struct sigaction {
+ __sighandler_t sa_handler;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+ sigset_t sa_mask; /* mask last for extensibility */
+};
+
+struct k_sigaction {
+ struct sigaction sa;
+};
+
+# include <asm/sigcontext.h>
+# undef __HAVE_ARCH_SIG_BITOPS
+
+# define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+# else /* !__KERNEL__ */
+
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+# define NSIG 32
+typedef unsigned long sigset_t;
+
+struct sigaction {
+ union {
+ __sighandler_t _sa_handler;
+ void (*_sa_sigaction)(int, struct siginfo *, void *);
+ } _u;
+ sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+};
+
+# define sa_handler _u._sa_handler
+# define sa_sigaction _u._sa_sigaction
+
+# endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+ void *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+# endif /* __ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_SIGNAL_H */
diff --git a/arch/microblaze/include/asm/socket.h b/arch/microblaze/include/asm/socket.h
new file mode 100644
index 00000000000..82593686031
--- /dev/null
+++ b/arch/microblaze/include/asm/socket.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_SOCKET_H
+#define _ASM_MICROBLAZE_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET 1
+
+#define SO_DEBUG 1
+#define SO_REUSEADDR 2
+#define SO_TYPE 3
+#define SO_ERROR 4
+#define SO_DONTROUTE 5
+#define SO_BROADCAST 6
+#define SO_SNDBUF 7
+#define SO_RCVBUF 8
+#define SO_SNDBUFFORCE 32
+#define SO_RCVBUFFORCE 33
+#define SO_KEEPALIVE 9
+#define SO_OOBINLINE 10
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
+#define SO_LINGER 13
+#define SO_BSDCOMPAT 14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED 16
+#define SO_PEERCRED 17
+#define SO_RCVLOWAT 18
+#define SO_SNDLOWAT 19
+#define SO_RCVTIMEO 20
+#define SO_SNDTIMEO 21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION 22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
+#define SO_SECURITY_ENCRYPTION_NETWORK 24
+
+#define SO_BINDTODEVICE 25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER 26
+#define SO_DETACH_FILTER 27
+
+#define SO_PEERNAME 28
+#define SO_TIMESTAMP 29
+#define SCM_TIMESTAMP SO_TIMESTAMP
+
+#define SO_ACCEPTCONN 30
+
+#define SO_PEERSEC 31
+#define SO_PASSSEC 34
+
+#define SO_TIMESTAMPNS 35
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+
+#define SO_MARK 36
+
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
+#endif /* _ASM_MICROBLAZE_SOCKET_H */
diff --git a/arch/microblaze/include/asm/sockios.h b/arch/microblaze/include/asm/sockios.h
new file mode 100644
index 00000000000..9fff57a701e
--- /dev/null
+++ b/arch/microblaze/include/asm/sockios.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_SOCKIOS_H
+#define _ASM_MICROBLAZE_SOCKIOS_H
+
+#include <linux/ioctl.h>
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
+#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
+
+#endif /* _ASM_MICROBLAZE_SOCKIOS_H */
diff --git a/arch/microblaze/include/asm/stat.h b/arch/microblaze/include/asm/stat.h
new file mode 100644
index 00000000000..5f18b8aed22
--- /dev/null
+++ b/arch/microblaze/include/asm/stat.h
@@ -0,0 +1,73 @@
+/*
+ * Microblaze stat structure
+ *
+ * Copyright (C) 2001,02,03 NEC Electronics Corporation
+ * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef _ASM_MICROBLAZE_STAT_H
+#define _ASM_MICROBLAZE_STAT_H
+
+#include <linux/posix_types.h>
+
+struct stat {
+ unsigned int st_dev;
+ unsigned long st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+ unsigned int st_uid;
+ unsigned int st_gid;
+ unsigned int st_rdev;
+ unsigned long st_size;
+ unsigned long st_blksize;
+ unsigned long st_blocks;
+ unsigned long st_atime;
+ unsigned long __unused1; /* unsigned long st_atime_nsec */
+ unsigned long st_mtime;
+ unsigned long __unused2; /* unsigned long st_mtime_nsec */
+ unsigned long st_ctime;
+ unsigned long __unused3; /* unsigned long st_ctime_nsec */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+struct stat64 {
+ unsigned long long st_dev;
+ unsigned long __unused1;
+
+ unsigned long long st_ino;
+
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned int st_uid;
+ unsigned int st_gid;
+
+ unsigned long long st_rdev;
+ unsigned long __unused3;
+
+ long long st_size;
+ unsigned long st_blksize;
+
+ unsigned long st_blocks; /* No. of 512-byte blocks allocated */
+ unsigned long __unused4; /* future possible st_blocks high bits */
+
+ unsigned long st_atime;
+ unsigned long st_atime_nsec;
+
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec;
+
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec;
+
+ unsigned long __unused8;
+};
+
+#endif /* _ASM_MICROBLAZE_STAT_H */
diff --git a/include/asm-mn10300/statfs.h b/arch/microblaze/include/asm/statfs.h
index 0b91fe198c2..0b91fe198c2 100644
--- a/include/asm-mn10300/statfs.h
+++ b/arch/microblaze/include/asm/statfs.h
diff --git a/arch/microblaze/include/asm/string.h b/arch/microblaze/include/asm/string.h
new file mode 100644
index 00000000000..f7728c90fc1
--- /dev/null
+++ b/arch/microblaze/include/asm/string.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_STRING_H
+#define _ASM_MICROBLAZE_STRING_H
+
+#ifndef __KERNEL__
+
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+
+extern void *memset(void *, int, __kernel_size_t);
+extern void *memcpy(void *, const void *, __kernel_size_t);
+extern void *memmove(void *, const void *, __kernel_size_t);
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_MICROBLAZE_STRING_H */
diff --git a/arch/microblaze/include/asm/swab.h b/arch/microblaze/include/asm/swab.h
new file mode 100644
index 00000000000..b375d7b65ad
--- /dev/null
+++ b/arch/microblaze/include/asm/swab.h
@@ -0,0 +1,8 @@
+#ifndef _ASM_MICROBLAZE_SWAB_H
+#define _ASM_MICROBLAZE_SWAB_H
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#define __SWAB_64_THRU_32__
+#endif
+
+#endif /* _ASM_MICROBLAZE_SWAB_H */
diff --git a/arch/microblaze/include/asm/syscalls.h b/arch/microblaze/include/asm/syscalls.h
new file mode 100644
index 00000000000..9cb4ff0edeb
--- /dev/null
+++ b/arch/microblaze/include/asm/syscalls.h
@@ -0,0 +1,45 @@
+#ifndef __ASM_MICROBLAZE_SYSCALLS_H
+#define __ASM_MICROBLAZE_SYSCALLS_H
+#ifdef __KERNEL__
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <linux/signal.h>
+
+/* FIXME will be removed */
+asmlinkage int sys_ipc(uint call, int first, int second,
+ int third, void *ptr, long fifth);
+
+struct pt_regs;
+asmlinkage int sys_vfork(struct pt_regs *regs);
+asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs);
+asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv,
+ char __user *__user *envp, struct pt_regs *regs);
+
+asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff);
+
+asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, off_t offset);
+
+/* from signal.c */
+asmlinkage int sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs);
+
+asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
+ struct pt_regs *regs);
+
+asmlinkage int sys_sigaction(int sig, const struct old_sigaction *act,
+ struct old_sigaction *oact);
+
+asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
+ struct pt_regs *regs);
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs);
+
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs);
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_MICROBLAZE_SYSCALLS_H */
diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h
new file mode 100644
index 00000000000..c4e308850b5
--- /dev/null
+++ b/arch/microblaze/include/asm/system.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_SYSTEM_H
+#define _ASM_MICROBLAZE_SYSTEM_H
+
+#include <asm/registers.h>
+#include <asm/setup.h>
+#include <asm/irqflags.h>
+
+struct task_struct;
+struct thread_info;
+
+extern struct task_struct *_switch_to(struct thread_info *prev,
+ struct thread_info *next);
+
+#define switch_to(prev, next, last) \
+ do { \
+ (last) = _switch_to(task_thread_info(prev), \
+ task_thread_info(next)); \
+ } while (0)
+
+#define smp_read_barrier_depends() do {} while (0)
+#define read_barrier_depends() do {} while (0)
+
+#define nop() asm volatile ("nop")
+#define mb() barrier()
+#define rmb() mb()
+#define wmb() mb()
+#define set_mb(var, value) do { var = value; mb(); } while (0)
+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() wmb()
+
+void show_trace(struct task_struct *task, unsigned long *stack);
+void __bad_xchg(volatile void *ptr, int size);
+
+static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
+ int size)
+{
+ unsigned long ret;
+ unsigned long flags;
+
+ switch (size) {
+ case 1:
+ local_irq_save(flags);
+ ret = *(volatile unsigned char *)ptr;
+ *(volatile unsigned char *)ptr = x;
+ local_irq_restore(flags);
+ break;
+
+ case 4:
+ local_irq_save(flags);
+ ret = *(volatile unsigned long *)ptr;
+ *(volatile unsigned long *)ptr = x;
+ local_irq_restore(flags);
+ break;
+ default:
+ __bad_xchg(ptr, size), ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+void disable_hlt(void);
+void enable_hlt(void);
+void default_idle(void);
+
+#define xchg(ptr, x) \
+ ((__typeof__(*(ptr))) __xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+
+void free_init_pages(char *what, unsigned long begin, unsigned long end);
+void free_initmem(void);
+extern char *klimit;
+extern void ret_from_fork(void);
+
+#ifdef CONFIG_DEBUG_FS
+extern struct dentry *of_debugfs_root;
+#endif
+
+#define arch_align_stack(x) (x)
+
+#endif /* _ASM_MICROBLAZE_SYSTEM_H */
diff --git a/arch/microblaze/include/asm/termbits.h b/arch/microblaze/include/asm/termbits.h
new file mode 100644
index 00000000000..a1b64bc4724
--- /dev/null
+++ b/arch/microblaze/include/asm/termbits.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_TERMBITS_H
+#define _ASM_MICROBLAZE_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 19
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+};
+
+struct ktermios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
+/* c_cc characters */
+
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+#define IUTF8 0040000
+
+/* c_oflag bits */
+
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define XTABS 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+
+/* c_cflag bit meaning */
+
+#define CBAUD 0010017
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+#define CBAUDEX 0010000
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define B500000 0010005
+#define B576000 0010006
+#define B921600 0010007
+#define BOTHER 0010000
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+#define CIBAUD 002003600000 /* input baud rate (not used) */
+#define CMSPAR 010000000000 /* mark or space (stick) parity */
+#define CRTSCTS 020000000000 /* flow control */
+
+#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
+
+/* c_lflag bits */
+
+#define ISIG 0000001
+#define ICANON 0000002
+#define XCASE 0000004
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define IEXTEN 0100000
+
+/* tcflow() and TCXONC use these */
+
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#endif /* _ASM_MICROBLAZE_TERMBITS_H */
diff --git a/arch/microblaze/include/asm/termios.h b/arch/microblaze/include/asm/termios.h
new file mode 100644
index 00000000000..102d7725866
--- /dev/null
+++ b/arch/microblaze/include/asm/termios.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_TERMIOS_H
+#define _ASM_MICROBLAZE_TERMIOS_H
+
+#include <linux/string.h>
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+#ifdef __KERNEL__
+/* intr=^C quit=^| erase=del kill=^U
+ eof=^D vtime=\0 vmin=\1 sxtc=\0
+ start=^Q stop=^S susp=^Z eol=\0
+ reprint=^R discard=^U werase=^W lnext=^V
+ eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+#endif
+
+/* Modem lines */
+
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* Line disciplines */
+
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+#define N_STRIP 4
+#define N_AX25 5
+#define N_X25 6 /* X.25 async */
+#define N_6PACK 7
+#define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964 9 /* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA 11 /* Linux IR - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards
+ about SMS messages */
+#define N_HDLC 13 /* synchronous HDLC */
+#define N_SYNC_PPP 14
+#define N_HCI 15 /* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+#include <asm-generic/termios.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_MICROBLAZE_TERMIOS_H */
diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h
new file mode 100644
index 00000000000..4c3943e3f40
--- /dev/null
+++ b/arch/microblaze/include/asm/thread_info.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_THREAD_INFO_H
+#define _ASM_MICROBLAZE_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+/* we have 8k stack */
+#define THREAD_SHIFT 13
+#define THREAD_SIZE (1 << THREAD_SHIFT)
+#define THREAD_SIZE_ORDER 1
+
+#ifndef __ASSEMBLY__
+# include <linux/types.h>
+# include <asm/processor.h>
+# include <asm/segment.h>
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants
+ * must also be changed
+ */
+
+struct cpu_context {
+ __u32 r1; /* stack pointer */
+ __u32 r2;
+ /* dedicated registers */
+ __u32 r13;
+ __u32 r14;
+ __u32 r15;
+ __u32 r16;
+ __u32 r17;
+ __u32 r18;
+ /* non-volatile registers */
+ __u32 r19;
+ __u32 r20;
+ __u32 r21;
+ __u32 r22;
+ __u32 r23;
+ __u32 r24;
+ __u32 r25;
+ __u32 r26;
+ __u32 r27;
+ __u32 r28;
+ __u32 r29;
+ __u32 r30;
+ /* r31 is used as current task pointer */
+ /* special purpose registers */
+ __u32 msr;
+ __u32 ear;
+ __u32 esr;
+ __u32 fsr;
+};
+
+struct thread_info {
+ struct task_struct *task; /* main task structure */
+ struct exec_domain *exec_domain; /* execution domain */
+ unsigned long flags; /* low level flags */
+ unsigned long status; /* thread-synchronous flags */
+ __u32 cpu; /* current CPU */
+ __s32 preempt_count; /* 0 => preemptable,< 0 => BUG*/
+ mm_segment_t addr_limit; /* thread address space */
+ struct restart_block restart_block;
+
+ struct cpu_context cpu_context;
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .task = &tsk, \
+ .exec_domain = &default_exec_domain, \
+ .flags = 0, \
+ .cpu = 0, \
+ .preempt_count = 1, \
+ .addr_limit = KERNEL_DS, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
+}
+
+#define init_thread_info (init_thread_union.thread_info)
+#define init_stack (init_thread_union.stack)
+
+/* how to get the thread information struct from C */
+static inline struct thread_info *current_thread_info(void)
+{
+ register unsigned long sp asm("r1");
+
+ return (struct thread_info *)(sp & ~(THREAD_SIZE-1));
+}
+
+/* thread information allocation */
+#endif /* __ASSEMBLY__ */
+
+#define PREEMPT_ACTIVE 0x10000000
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files may
+ * need to access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
+#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
+#define TIF_SIGPENDING 2 /* signal pending */
+#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
+/* restore singlestep on return to user mode */
+#define TIF_SINGLESTEP 4
+#define TIF_IRET 5 /* return with iret */
+#define TIF_MEMDIE 6
+#define TIF_FREEZE 14 /* Freezing for suspend */
+
+/* FIXME change in entry.S */
+#define TIF_KERNEL_TRACE 8 /* kernel trace active */
+
+/* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_POLLING_NRFLAG 16
+
+#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
+#define _TIF_IRET (1<<TIF_IRET)
+#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
+#define _TIF_KERNEL_TRACE (1 << TIF_KERNEL_TRACE)
+
+/* work to do on interrupt/exception return */
+#define _TIF_WORK_MASK 0x0000FFFE
+/* work to do on any return to u-space */
+#define _TIF_ALLWORK_MASK 0x0000FFFF
+
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ */
+/* FPU was used by this task this quantum (SMP) */
+#define TS_USEDFPU 0x0001
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_THREAD_INFO_H */
diff --git a/arch/microblaze/include/asm/timex.h b/arch/microblaze/include/asm/timex.h
new file mode 100644
index 00000000000..678525dc6d0
--- /dev/null
+++ b/arch/microblaze/include/asm/timex.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_TIMEX_H
+#define _ASM_MICROBLAZE_TIMEX_H
+
+#define CLOCK_TICK_RATE 1000 /* Timer input freq. */
+
+typedef unsigned long cycles_t;
+
+#define get_cycles() (0)
+
+#endif /* _ASM_TIMEX_H */
diff --git a/arch/microblaze/include/asm/tlb.h b/arch/microblaze/include/asm/tlb.h
new file mode 100644
index 00000000000..d1dfe379112
--- /dev/null
+++ b/arch/microblaze/include/asm/tlb.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_TLB_H
+#define _ASM_MICROBLAZE_TLB_H
+
+#define tlb_flush(tlb) do {} while (0)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_MICROBLAZE_TLB_H */
diff --git a/arch/microblaze/include/asm/tlbflush.h b/arch/microblaze/include/asm/tlbflush.h
new file mode 100644
index 00000000000..d7fe7629001
--- /dev/null
+++ b/arch/microblaze/include/asm/tlbflush.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_TLBFLUSH_H
+#define _ASM_MICROBLAZE_TLBFLUSH_H
+
+#define flush_tlb() BUG()
+#define flush_tlb_all() BUG()
+#define flush_tlb_mm(mm) BUG()
+#define flush_tlb_page(vma, addr) BUG()
+#define flush_tlb_range(mm, start, end) BUG()
+#define flush_tlb_pgtables(mm, start, end) BUG()
+#define flush_tlb_kernel_range(start, end) BUG()
+
+#endif /* _ASM_MICROBLAZE_TLBFLUSH_H */
diff --git a/arch/microblaze/include/asm/topology.h b/arch/microblaze/include/asm/topology.h
new file mode 100644
index 00000000000..96bcea5a992
--- /dev/null
+++ b/arch/microblaze/include/asm/topology.h
@@ -0,0 +1,11 @@
+#include <asm-generic/topology.h>
+
+#ifndef _ASM_MICROBLAZE_TOPOLOGY_H
+#define _ASM_MICROBLAZE_TOPOLOGY_H
+
+struct device_node;
+static inline int of_node_to_nid(struct device_node *device)
+{
+ return 0;
+}
+#endif /* _ASM_MICROBLAZE_TOPOLOGY_H */
diff --git a/arch/microblaze/include/asm/types.h b/arch/microblaze/include/asm/types.h
new file mode 100644
index 00000000000..bebc018318f
--- /dev/null
+++ b/arch/microblaze/include/asm/types.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_TYPES_H
+#define _ASM_MICROBLAZE_TYPES_H
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue. However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
+
+#include <asm-generic/int-ll64.h>
+
+# ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+# ifdef __KERNEL__
+# define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide. */
+
+typedef u32 dma_addr_t;
+
+# endif/* __KERNEL__ */
+# endif /* __ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_TYPES_H */
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h
new file mode 100644
index 00000000000..5a3ffc308e1
--- /dev/null
+++ b/arch/microblaze/include/asm/uaccess.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_UACCESS_H
+#define _ASM_MICROBLAZE_UACCESS_H
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h> /* RLIMIT_FSIZE */
+#include <linux/mm.h>
+
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/segment.h>
+#include <linux/string.h>
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+extern int ___range_ok(unsigned long addr, unsigned long size);
+
+#define __range_ok(addr, size) \
+ ___range_ok((unsigned long)(addr), (unsigned long)(size))
+
+#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0)
+#define __access_ok(add, size) (__range_ok((addr), (size)) == 0)
+
+extern inline int bad_user_access_length(void)
+{
+ return 0;
+}
+/* FIXME this is function for optimalization -> memcpy */
+#define __get_user(var, ptr) \
+ ({ \
+ int __gu_err = 0; \
+ switch (sizeof(*(ptr))) { \
+ case 1: \
+ case 2: \
+ case 4: \
+ (var) = *(ptr); \
+ break; \
+ case 8: \
+ memcpy((void *) &(var), (ptr), 8); \
+ break; \
+ default: \
+ (var) = 0; \
+ __gu_err = __get_user_bad(); \
+ break; \
+ } \
+ __gu_err; \
+ })
+
+#define __get_user_bad() (bad_user_access_length(), (-EFAULT))
+
+#define __put_user(var, ptr) \
+ ({ \
+ int __pu_err = 0; \
+ switch (sizeof(*(ptr))) { \
+ case 1: \
+ case 2: \
+ case 4: \
+ *(ptr) = (var); \
+ break; \
+ case 8: { \
+ typeof(*(ptr)) __pu_val = var; \
+ memcpy(ptr, &__pu_val, sizeof(__pu_val));\
+ } \
+ break; \
+ default: \
+ __pu_err = __put_user_bad(); \
+ break; \
+ } \
+ __pu_err; \
+ })
+
+#define __put_user_bad() (bad_user_access_length(), (-EFAULT))
+
+#define put_user(x, ptr) __put_user(x, ptr)
+#define get_user(x, ptr) __get_user(x, ptr)
+
+#define copy_to_user(to, from, n) (memcpy(to, from, n), 0)
+#define copy_from_user(to, from, n) (memcpy(to, from, n), 0)
+
+#define __copy_to_user(to, from, n) (copy_to_user(to, from, n))
+#define __copy_from_user(to, from, n) (copy_from_user(to, from, n))
+#define __copy_to_user_inatomic(to, from, n) (__copy_to_user(to, from, n))
+#define __copy_from_user_inatomic(to, from, n) (__copy_from_user(to, from, n))
+
+#define __clear_user(addr, n) (memset((void *)addr, 0, n), 0)
+
+static inline unsigned long clear_user(void *addr, unsigned long size)
+{
+ if (access_ok(VERIFY_WRITE, addr, size))
+ size = __clear_user(addr, size);
+ return size;
+}
+
+/* Returns 0 if exception not found and fixup otherwise. */
+extern unsigned long search_exception_table(unsigned long);
+
+
+extern long strncpy_from_user(char *dst, const char __user *src, long count);
+extern long strnlen_user(const char __user *src, long count);
+extern long __strncpy_from_user(char *dst, const char __user *src, long count);
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue. No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path. This means when everything is well,
+ * we don't even have to jump over them. Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+struct exception_table_entry {
+ unsigned long insn, fixup;
+};
+
+#endif /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_MICROBLAZE_UACCESS_H */
diff --git a/arch/microblaze/include/asm/ucontext.h b/arch/microblaze/include/asm/ucontext.h
new file mode 100644
index 00000000000..11f6bb3ae3a
--- /dev/null
+++ b/arch/microblaze/include/asm/ucontext.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_UCONTEXT_H
+#define _ASM_MICROBLAZE_UCONTEXT_H
+
+#include <asm/sigcontext.h>
+
+struct ucontext {
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ struct sigcontext uc_mcontext;
+ sigset_t uc_sigmask; /* mask last for extensibility */
+};
+
+#endif /* _ASM_MICROBLAZE_UCONTEXT_H */
diff --git a/arch/microblaze/include/asm/unaligned.h b/arch/microblaze/include/asm/unaligned.h
new file mode 100644
index 00000000000..9d66b640c91
--- /dev/null
+++ b/arch/microblaze/include/asm/unaligned.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_UNALIGNED_H
+#define _ASM_MICROBLAZE_UNALIGNED_H
+
+# ifdef __KERNEL__
+
+# include <linux/unaligned/access_ok.h>
+# include <linux/unaligned/generic.h>
+
+# define get_unaligned __get_unaligned_be
+# define put_unaligned __put_unaligned_be
+
+# endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_UNALIGNED_H */
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h
new file mode 100644
index 00000000000..d9d3903fde3
--- /dev/null
+++ b/arch/microblaze/include/asm/unistd.h
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_UNISTD_H
+#define _ASM_MICROBLAZE_UNISTD_H
+
+#define __NR_restart_syscall 0 /* ok */
+#define __NR_exit 1 /* ok */
+#define __NR_fork 2 /* not for no MMU - weird */
+#define __NR_read 3 /* ok */
+#define __NR_write 4 /* ok */
+#define __NR_open 5 /* openat */
+#define __NR_close 6 /* ok */
+#define __NR_waitpid 7 /* waitid */
+#define __NR_creat 8 /* openat */
+#define __NR_link 9 /* linkat */
+#define __NR_unlink 10 /* unlinkat */
+#define __NR_execve 11 /* ok */
+#define __NR_chdir 12 /* ok */
+#define __NR_time 13 /* obsolete -> sys_gettimeofday */
+#define __NR_mknod 14 /* mknodat */
+#define __NR_chmod 15 /* fchmodat */
+#define __NR_lchown 16 /* ok */
+#define __NR_break 17 /* don't know */
+#define __NR_oldstat 18 /* remove */
+#define __NR_lseek 19 /* ok */
+#define __NR_getpid 20 /* ok */
+#define __NR_mount 21 /* ok */
+#define __NR_umount 22 /* ok */ /* use only umount2 */
+#define __NR_setuid 23 /* ok */
+#define __NR_getuid 24 /* ok */
+#define __NR_stime 25 /* obsolete -> sys_settimeofday */
+#define __NR_ptrace 26 /* ok */
+#define __NR_alarm 27 /* obsolete -> sys_setitimer */
+#define __NR_oldfstat 28 /* remove */
+#define __NR_pause 29 /* obsolete -> sys_rt_sigtimedwait */
+#define __NR_utime 30 /* obsolete -> sys_utimesat */
+#define __NR_stty 31 /* remove */
+#define __NR_gtty 32 /* remove */
+#define __NR_access 33 /* faccessat */
+/* can be implemented by sys_setpriority */
+#define __NR_nice 34
+#define __NR_ftime 35 /* remove */
+#define __NR_sync 36 /* ok */
+#define __NR_kill 37 /* ok */
+#define __NR_rename 38 /* renameat */
+#define __NR_mkdir 39 /* mkdirat */
+#define __NR_rmdir 40 /* unlinkat */
+#define __NR_dup 41 /* ok */
+#define __NR_pipe 42 /* ok */
+#define __NR_times 43 /* ok */
+#define __NR_prof 44 /* remove */
+#define __NR_brk 45 /* ok -mmu, nommu specific */
+#define __NR_setgid 46 /* ok */
+#define __NR_getgid 47 /* ok */
+#define __NR_signal 48 /* obsolete -> sys_rt_sigaction */
+#define __NR_geteuid 49 /* ok */
+#define __NR_getegid 50 /* ok */
+#define __NR_acct 51 /* add it and then I can disable it */
+#define __NR_umount2 52 /* remove */
+#define __NR_lock 53 /* remove */
+#define __NR_ioctl 54 /* ok */
+#define __NR_fcntl 55 /* ok -> 64bit version*/
+#define __NR_mpx 56 /* remove */
+#define __NR_setpgid 57 /* ok */
+#define __NR_ulimit 58 /* remove */
+#define __NR_oldolduname 59 /* remove */
+#define __NR_umask 60 /* ok */
+#define __NR_chroot 61 /* ok */
+#define __NR_ustat 62 /* obsolete -> statfs64 */
+#define __NR_dup2 63 /* ok */
+#define __NR_getppid 64 /* ok */
+#define __NR_getpgrp 65 /* obsolete -> sys_getpgid */
+#define __NR_setsid 66 /* ok */
+#define __NR_sigaction 67 /* obsolete -> rt_sigaction */
+#define __NR_sgetmask 68 /* obsolete -> sys_rt_sigprocmask */
+#define __NR_ssetmask 69 /* obsolete ->sys_rt_sigprocmask */
+#define __NR_setreuid 70 /* ok */
+#define __NR_setregid 71 /* ok */
+#define __NR_sigsuspend 72 /* obsolete -> rt_sigsuspend */
+#define __NR_sigpending 73 /* obsolete -> sys_rt_sigpending */
+#define __NR_sethostname 74 /* ok */
+#define __NR_setrlimit 75 /* ok */
+#define __NR_getrlimit 76 /* ok Back compatible 2G limited rlimit */
+#define __NR_getrusage 77 /* ok */
+#define __NR_gettimeofday 78 /* ok */
+#define __NR_settimeofday 79 /* ok */
+#define __NR_getgroups 80 /* ok */
+#define __NR_setgroups 81 /* ok */
+#define __NR_select 82 /* obsolete -> sys_pselect7 */
+#define __NR_symlink 83 /* symlinkat */
+#define __NR_oldlstat 84 /* remove */
+#define __NR_readlink 85 /* obsolete -> sys_readlinkat */
+#define __NR_uselib 86 /* remove */
+#define __NR_swapon 87 /* ok */
+#define __NR_reboot 88 /* ok */
+#define __NR_readdir 89 /* remove ? */
+#define __NR_mmap 90 /* obsolete -> sys_mmap2 */
+#define __NR_munmap 91 /* ok - mmu and nommu */
+#define __NR_truncate 92 /* ok or truncate64 */
+#define __NR_ftruncate 93 /* ok or ftruncate64 */
+#define __NR_fchmod 94 /* ok */
+#define __NR_fchown 95 /* ok */
+#define __NR_getpriority 96 /* ok */
+#define __NR_setpriority 97 /* ok */
+#define __NR_profil 98 /* remove */
+#define __NR_statfs 99 /* ok or statfs64 */
+#define __NR_fstatfs 100 /* ok or fstatfs64 */
+#define __NR_ioperm 101 /* remove */
+#define __NR_socketcall 102 /* remove */
+#define __NR_syslog 103 /* ok */
+#define __NR_setitimer 104 /* ok */
+#define __NR_getitimer 105 /* ok */
+#define __NR_stat 106 /* remove */
+#define __NR_lstat 107 /* remove */
+#define __NR_fstat 108 /* remove */
+#define __NR_olduname 109 /* remove */
+#define __NR_iopl 110 /* remove */
+#define __NR_vhangup 111 /* ok */
+#define __NR_idle 112 /* remove */
+#define __NR_vm86old 113 /* remove */
+#define __NR_wait4 114 /* obsolete -> waitid */
+#define __NR_swapoff 115 /* ok */
+#define __NR_sysinfo 116 /* ok */
+#define __NR_ipc 117 /* remove - direct call */
+#define __NR_fsync 118 /* ok */
+#define __NR_sigreturn 119 /* obsolete -> sys_rt_sigreturn */
+#define __NR_clone 120 /* ok */
+#define __NR_setdomainname 121 /* ok */
+#define __NR_uname 122 /* remove */
+#define __NR_modify_ldt 123 /* remove */
+#define __NR_adjtimex 124 /* ok */
+#define __NR_mprotect 125 /* remove */
+#define __NR_sigprocmask 126 /* obsolete -> sys_rt_sigprocmask */
+#define __NR_create_module 127 /* remove */
+#define __NR_init_module 128 /* ok */
+#define __NR_delete_module 129 /* ok */
+#define __NR_get_kernel_syms 130 /* remove */
+#define __NR_quotactl 131 /* ok */
+#define __NR_getpgid 132 /* ok */
+#define __NR_fchdir 133 /* ok */
+#define __NR_bdflush 134 /* remove */
+#define __NR_sysfs 135 /* needed for busybox */
+#define __NR_personality 136 /* ok */
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_setfsuid 138 /* ok */
+#define __NR_setfsgid 139 /* ok */
+#define __NR__llseek 140 /* remove only lseek */
+#define __NR_getdents 141 /* ok or getdents64 */
+#define __NR__newselect 142 /* remove */
+#define __NR_flock 143 /* ok */
+#define __NR_msync 144 /* remove */
+#define __NR_readv 145 /* ok */
+#define __NR_writev 146 /* ok */
+#define __NR_getsid 147 /* ok */
+#define __NR_fdatasync 148 /* ok */
+#define __NR__sysctl 149 /* remove */
+#define __NR_mlock 150 /* ok - nommu or mmu */
+#define __NR_munlock 151 /* ok - nommu or mmu */
+#define __NR_mlockall 152 /* ok - nommu or mmu */
+#define __NR_munlockall 153 /* ok - nommu or mmu */
+#define __NR_sched_setparam 154 /* ok */
+#define __NR_sched_getparam 155 /* ok */
+#define __NR_sched_setscheduler 156 /* ok */
+#define __NR_sched_getscheduler 157 /* ok */
+#define __NR_sched_yield 158 /* ok */
+#define __NR_sched_get_priority_max 159 /* ok */
+#define __NR_sched_get_priority_min 160 /* ok */
+#define __NR_sched_rr_get_interval 161 /* ok */
+#define __NR_nanosleep 162 /* ok */
+#define __NR_mremap 163 /* ok - nommu or mmu */
+#define __NR_setresuid 164 /* ok */
+#define __NR_getresuid 165 /* ok */
+#define __NR_vm86 166 /* remove */
+#define __NR_query_module 167 /* ok */
+#define __NR_poll 168 /* obsolete -> sys_ppoll */
+#define __NR_nfsservctl 169 /* ok */
+#define __NR_setresgid 170 /* ok */
+#define __NR_getresgid 171 /* ok */
+#define __NR_prctl 172 /* ok */
+#define __NR_rt_sigreturn 173 /* ok */
+#define __NR_rt_sigaction 174 /* ok */
+#define __NR_rt_sigprocmask 175 /* ok */
+#define __NR_rt_sigpending 176 /* ok */
+#define __NR_rt_sigtimedwait 177 /* ok */
+#define __NR_rt_sigqueueinfo 178 /* ok */
+#define __NR_rt_sigsuspend 179 /* ok */
+#define __NR_pread64 180 /* ok */
+#define __NR_pwrite64 181 /* ok */
+#define __NR_chown 182 /* obsolete -> fchownat */
+#define __NR_getcwd 183 /* ok */
+#define __NR_capget 184 /* ok */
+#define __NR_capset 185 /* ok */
+#define __NR_sigaltstack 186 /* remove */
+#define __NR_sendfile 187 /* ok -> exist 64bit version*/
+#define __NR_getpmsg 188 /* remove */
+/* remove - some people actually want streams */
+#define __NR_putpmsg 189
+/* for noMMU - group with clone -> maybe remove */
+#define __NR_vfork 190
+#define __NR_ugetrlimit 191 /* remove - SuS compliant getrlimit */
+#define __NR_mmap2 192 /* ok */
+#define __NR_truncate64 193 /* ok */
+#define __NR_ftruncate64 194 /* ok */
+#define __NR_stat64 195 /* remove _ARCH_WANT_STAT64 */
+#define __NR_lstat64 196 /* remove _ARCH_WANT_STAT64 */
+#define __NR_fstat64 197 /* remove _ARCH_WANT_STAT64 */
+#define __NR_lchown32 198 /* ok - without 32 */
+#define __NR_getuid32 199 /* ok - without 32 */
+#define __NR_getgid32 200 /* ok - without 32 */
+#define __NR_geteuid32 201 /* ok - without 32 */
+#define __NR_getegid32 202 /* ok - without 32 */
+#define __NR_setreuid32 203 /* ok - without 32 */
+#define __NR_setregid32 204 /* ok - without 32 */
+#define __NR_getgroups32 205 /* ok - without 32 */
+#define __NR_setgroups32 206 /* ok - without 32 */
+#define __NR_fchown32 207 /* ok - without 32 */
+#define __NR_setresuid32 208 /* ok - without 32 */
+#define __NR_getresuid32 209 /* ok - without 32 */
+#define __NR_setresgid32 210 /* ok - without 32 */
+#define __NR_getresgid32 211 /* ok - without 32 */
+#define __NR_chown32 212 /* ok - without 32 -obsolete -> fchownat */
+#define __NR_setuid32 213 /* ok - without 32 */
+#define __NR_setgid32 214 /* ok - without 32 */
+#define __NR_setfsuid32 215 /* ok - without 32 */
+#define __NR_setfsgid32 216 /* ok - without 32 */
+#define __NR_pivot_root 217 /* ok */
+#define __NR_mincore 218 /* ok */
+#define __NR_madvise 219 /* ok */
+#define __NR_getdents64 220 /* ok */
+#define __NR_fcntl64 221 /* ok */
+/* 223 is unused */
+#define __NR_gettid 224 /* ok */
+#define __NR_readahead 225 /* ok */
+#define __NR_setxattr 226 /* ok */
+#define __NR_lsetxattr 227 /* ok */
+#define __NR_fsetxattr 228 /* ok */
+#define __NR_getxattr 229 /* ok */
+#define __NR_lgetxattr 230 /* ok */
+#define __NR_fgetxattr 231 /* ok */
+#define __NR_listxattr 232 /* ok */
+#define __NR_llistxattr 233 /* ok */
+#define __NR_flistxattr 234 /* ok */
+#define __NR_removexattr 235 /* ok */
+#define __NR_lremovexattr 236 /* ok */
+#define __NR_fremovexattr 237 /* ok */
+#define __NR_tkill 238 /* ok */
+#define __NR_sendfile64 239 /* ok */
+#define __NR_futex 240 /* ok */
+#define __NR_sched_setaffinity 241 /* ok */
+#define __NR_sched_getaffinity 242 /* ok */
+#define __NR_set_thread_area 243 /* remove */
+#define __NR_get_thread_area 244 /* remove */
+#define __NR_io_setup 245 /* ok */
+#define __NR_io_destroy 246 /* ok */
+#define __NR_io_getevents 247 /* ok */
+#define __NR_io_submit 248 /* ok */
+#define __NR_io_cancel 249 /* ok */
+#define __NR_fadvise64 250 /* remove -> sys_fadvise64_64 */
+/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */
+#define __NR_exit_group 252 /* ok */
+#define __NR_lookup_dcookie 253 /* ok */
+#define __NR_epoll_create 254 /* ok */
+#define __NR_epoll_ctl 255 /* ok */
+#define __NR_epoll_wait 256 /* obsolete -> sys_epoll_pwait */
+#define __NR_remap_file_pages 257 /* only for mmu */
+#define __NR_set_tid_address 258 /* ok */
+#define __NR_timer_create 259 /* ok */
+#define __NR_timer_settime (__NR_timer_create+1) /* 260 */ /* ok */
+#define __NR_timer_gettime (__NR_timer_create+2) /* 261 */ /* ok */
+#define __NR_timer_getoverrun (__NR_timer_create+3) /* 262 */ /* ok */
+#define __NR_timer_delete (__NR_timer_create+4) /* 263 */ /* ok */
+#define __NR_clock_settime (__NR_timer_create+5) /* 264 */ /* ok */
+#define __NR_clock_gettime (__NR_timer_create+6) /* 265 */ /* ok */
+#define __NR_clock_getres (__NR_timer_create+7) /* 266 */ /* ok */
+#define __NR_clock_nanosleep (__NR_timer_create+8) /* 267 */ /* ok */
+#define __NR_statfs64 268 /* ok */
+#define __NR_fstatfs64 269 /* ok */
+#define __NR_tgkill 270 /* ok */
+#define __NR_utimes 271 /* obsolete -> sys_futimesat */
+#define __NR_fadvise64_64 272 /* ok */
+#define __NR_vserver 273 /* ok */
+#define __NR_mbind 274 /* only for mmu */
+#define __NR_get_mempolicy 275 /* only for mmu */
+#define __NR_set_mempolicy 276 /* only for mmu */
+#define __NR_mq_open 277 /* ok */
+#define __NR_mq_unlink (__NR_mq_open+1) /* 278 */ /* ok */
+#define __NR_mq_timedsend (__NR_mq_open+2) /* 279 */ /* ok */
+#define __NR_mq_timedreceive (__NR_mq_open+3) /* 280 */ /* ok */
+#define __NR_mq_notify (__NR_mq_open+4) /* 281 */ /* ok */
+#define __NR_mq_getsetattr (__NR_mq_open+5) /* 282 */ /* ok */
+#define __NR_kexec_load 283 /* ok */
+#define __NR_waitid 284 /* ok */
+/* #define __NR_sys_setaltroot 285 */
+#define __NR_add_key 286 /* ok */
+#define __NR_request_key 287 /* ok */
+#define __NR_keyctl 288 /* ok */
+#define __NR_ioprio_set 289 /* ok */
+#define __NR_ioprio_get 290 /* ok */
+#define __NR_inotify_init 291 /* ok */
+#define __NR_inotify_add_watch 292 /* ok */
+#define __NR_inotify_rm_watch 293 /* ok */
+#define __NR_migrate_pages 294 /* mmu */
+#define __NR_openat 295 /* ok */
+#define __NR_mkdirat 296 /* ok */
+#define __NR_mknodat 297 /* ok */
+#define __NR_fchownat 298 /* ok */
+#define __NR_futimesat 299 /* obsolete -> sys_utimesat */
+#define __NR_fstatat64 300 /* stat64 */
+#define __NR_unlinkat 301 /* ok */
+#define __NR_renameat 302 /* ok */
+#define __NR_linkat 303 /* ok */
+#define __NR_symlinkat 304 /* ok */
+#define __NR_readlinkat 305 /* ok */
+#define __NR_fchmodat 306 /* ok */
+#define __NR_faccessat 307 /* ok */
+#define __NR_pselect6 308 /* obsolete -> sys_pselect7 */
+#define __NR_ppoll 309 /* ok */
+#define __NR_unshare 310 /* ok */
+#define __NR_set_robust_list 311 /* ok */
+#define __NR_get_robust_list 312 /* ok */
+#define __NR_splice 313 /* ok */
+#define __NR_sync_file_range 314 /* ok */
+#define __NR_tee 315 /* ok */
+#define __NR_vmsplice 316 /* ok */
+#define __NR_move_pages 317 /* mmu */
+#define __NR_getcpu 318 /* ok */
+#define __NR_epoll_pwait 319 /* ok */
+#define __NR_utimensat 320 /* ok */
+#define __NR_signalfd 321 /* ok */
+#define __NR_timerfd_create 322 /* ok */
+#define __NR_eventfd 323 /* ok */
+#define __NR_fallocate 324 /* ok */
+#define __NR_semtimedop 325 /* ok - semaphore group */
+#define __NR_timerfd_settime 326 /* ok */
+#define __NR_timerfd_gettime 327 /* ok */
+/* sysv ipc syscalls */
+#define __NR_semctl 328 /* ok */
+#define __NR_semget 329 /* ok */
+#define __NR_semop 330 /* ok */
+#define __NR_msgctl 331 /* ok */
+#define __NR_msgget 332 /* ok */
+#define __NR_msgrcv 333 /* ok */
+#define __NR_msgsnd 334 /* ok */
+#define __NR_shmat 335 /* ok */
+#define __NR_shmctl 336 /* ok */
+#define __NR_shmdt 337 /* ok */
+#define __NR_shmget 338 /* ok */
+
+
+#define __NR_signalfd4 339 /* new */
+#define __NR_eventfd2 340 /* new */
+#define __NR_epoll_create1 341 /* new */
+#define __NR_dup3 342 /* new */
+#define __NR_pipe2 343 /* new */
+#define __NR_inotify_init1 344 /* new */
+#define __NR_socket 345 /* new */
+#define __NR_socketpair 346 /* new */
+#define __NR_bind 347 /* new */
+#define __NR_listen 348 /* new */
+#define __NR_accept 349 /* new */
+#define __NR_connect 350 /* new */
+#define __NR_getsockname 351 /* new */
+#define __NR_getpeername 352 /* new */
+#define __NR_sendto 353 /* new */
+#define __NR_send 354 /* new */
+#define __NR_recvfrom 355 /* new */
+#define __NR_recv 356 /* new */
+#define __NR_setsockopt 357 /* new */
+#define __NR_getsockopt 358 /* new */
+#define __NR_shutdown 359 /* new */
+#define __NR_sendmsg 360 /* new */
+#define __NR_recvmsg 361 /* new */
+#define __NR_accept04 362 /* new */
+
+#define __NR_syscalls 363
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#define __ARCH_WANT_IPC_PARSE_VERSION
+/* #define __ARCH_WANT_OLD_READDIR */
+/* #define __ARCH_WANT_OLD_STAT */
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_SGETMASK
+#define __ARCH_WANT_SYS_SIGNAL
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+/* #define __ARCH_WANT_SYS_OLD_GETRLIMIT */
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
+/* #define __ARCH_WANT_SYS_RT_SIGSUSPEND */
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
+
+#endif /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_UNISTD_H */
diff --git a/arch/microblaze/include/asm/user.h b/arch/microblaze/include/asm/user.h
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/arch/microblaze/include/asm/user.h
@@ -0,0 +1 @@
+
diff --git a/arch/microblaze/include/asm/vga.h b/arch/microblaze/include/asm/vga.h
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/arch/microblaze/include/asm/vga.h
@@ -0,0 +1 @@
+
diff --git a/include/asm-mn10300/xor.h b/arch/microblaze/include/asm/xor.h
index c82eb12a5b1..c82eb12a5b1 100644
--- a/include/asm-mn10300/xor.h
+++ b/arch/microblaze/include/asm/xor.h
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
new file mode 100644
index 00000000000..da94bec4ecb
--- /dev/null
+++ b/arch/microblaze/kernel/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile
+#
+
+extra-y := head.o vmlinux.lds
+
+obj-y += exceptions.o \
+ hw_exception_handler.o init_task.o intc.o irq.o of_device.o \
+ of_platform.o process.o prom.o prom_parse.o ptrace.o \
+ setup.o signal.o sys_microblaze.o timer.o traps.o
+
+obj-y += cpu/
+
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-$(CONFIG_SELFMOD) += selfmod.o
+obj-$(CONFIG_HEART_BEAT) += heartbeat.o
+obj-$(CONFIG_MODULES) += microblaze_ksyms.o module.o
+
+obj-y += entry$(MMUEXT).o
diff --git a/arch/microblaze/kernel/asm-offsets.c b/arch/microblaze/kernel/asm-offsets.c
new file mode 100644
index 00000000000..38e1a2e8ad0
--- /dev/null
+++ b/arch/microblaze/kernel/asm-offsets.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/ptrace.h>
+#include <linux/hardirq.h>
+#include <linux/thread_info.h>
+#include <linux/kbuild.h>
+
+int main(int argc, char *argv[])
+{
+ /* struct pt_regs */
+ DEFINE(PT_SIZE, sizeof(struct pt_regs));
+ DEFINE(PT_MSR, offsetof(struct pt_regs, msr));
+ DEFINE(PT_EAR, offsetof(struct pt_regs, ear));
+ DEFINE(PT_ESR, offsetof(struct pt_regs, esr));
+ DEFINE(PT_FSR, offsetof(struct pt_regs, fsr));
+ DEFINE(PT_PC, offsetof(struct pt_regs, pc));
+ DEFINE(PT_R0, offsetof(struct pt_regs, r0));
+ DEFINE(PT_R1, offsetof(struct pt_regs, r1));
+ DEFINE(PT_R2, offsetof(struct pt_regs, r2));
+ DEFINE(PT_R3, offsetof(struct pt_regs, r3));
+ DEFINE(PT_R4, offsetof(struct pt_regs, r4));
+ DEFINE(PT_R5, offsetof(struct pt_regs, r5));
+ DEFINE(PT_R6, offsetof(struct pt_regs, r6));
+ DEFINE(PT_R7, offsetof(struct pt_regs, r7));
+ DEFINE(PT_R8, offsetof(struct pt_regs, r8));
+ DEFINE(PT_R9, offsetof(struct pt_regs, r9));
+ DEFINE(PT_R10, offsetof(struct pt_regs, r10));
+ DEFINE(PT_R11, offsetof(struct pt_regs, r11));
+ DEFINE(PT_R12, offsetof(struct pt_regs, r12));
+ DEFINE(PT_R13, offsetof(struct pt_regs, r13));
+ DEFINE(PT_R14, offsetof(struct pt_regs, r14));
+ DEFINE(PT_R15, offsetof(struct pt_regs, r15));
+ DEFINE(PT_R16, offsetof(struct pt_regs, r16));
+ DEFINE(PT_R17, offsetof(struct pt_regs, r17));
+ DEFINE(PT_R18, offsetof(struct pt_regs, r18));
+ DEFINE(PT_R19, offsetof(struct pt_regs, r19));
+ DEFINE(PT_R20, offsetof(struct pt_regs, r20));
+ DEFINE(PT_R21, offsetof(struct pt_regs, r21));
+ DEFINE(PT_R22, offsetof(struct pt_regs, r22));
+ DEFINE(PT_R23, offsetof(struct pt_regs, r23));
+ DEFINE(PT_R24, offsetof(struct pt_regs, r24));
+ DEFINE(PT_R25, offsetof(struct pt_regs, r25));
+ DEFINE(PT_R26, offsetof(struct pt_regs, r26));
+ DEFINE(PT_R27, offsetof(struct pt_regs, r27));
+ DEFINE(PT_R28, offsetof(struct pt_regs, r28));
+ DEFINE(PT_R29, offsetof(struct pt_regs, r29));
+ DEFINE(PT_R30, offsetof(struct pt_regs, r30));
+ DEFINE(PT_R31, offsetof(struct pt_regs, r31));
+ DEFINE(PT_MODE, offsetof(struct pt_regs, kernel_mode));
+ BLANK();
+
+ /* Magic offsets for PTRACE PEEK/POKE etc */
+ DEFINE(PT_TEXT_ADDR, sizeof(struct pt_regs) + 1);
+ DEFINE(PT_TEXT_LEN, sizeof(struct pt_regs) + 2);
+ DEFINE(PT_DATA_ADDR, sizeof(struct pt_regs) + 3);
+ BLANK();
+
+ /* struct task_struct */
+ DEFINE(TS_THREAD_INFO, offsetof(struct task_struct, stack));
+
+ /* struct thread_info */
+ DEFINE(TI_TASK, offsetof(struct thread_info, task));
+ DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
+ DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+ DEFINE(TI_STATUS, offsetof(struct thread_info, status));
+ DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+ DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
+ DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
+ DEFINE(TI_RESTART_BLOCK, offsetof(struct thread_info, restart_block));
+ DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context));
+ BLANK();
+
+ /* struct cpu_context */
+ DEFINE(CC_R1, offsetof(struct cpu_context, r1)); /* r1 */
+ DEFINE(CC_R2, offsetof(struct cpu_context, r2));
+ /* dedicated registers */
+ DEFINE(CC_R13, offsetof(struct cpu_context, r13));
+ DEFINE(CC_R14, offsetof(struct cpu_context, r14));
+ DEFINE(CC_R15, offsetof(struct cpu_context, r15));
+ DEFINE(CC_R16, offsetof(struct cpu_context, r16));
+ DEFINE(CC_R17, offsetof(struct cpu_context, r17));
+ DEFINE(CC_R18, offsetof(struct cpu_context, r18));
+ /* non-volatile registers */
+ DEFINE(CC_R19, offsetof(struct cpu_context, r19));
+ DEFINE(CC_R20, offsetof(struct cpu_context, r20));
+ DEFINE(CC_R21, offsetof(struct cpu_context, r21));
+ DEFINE(CC_R22, offsetof(struct cpu_context, r22));
+ DEFINE(CC_R23, offsetof(struct cpu_context, r23));
+ DEFINE(CC_R24, offsetof(struct cpu_context, r24));
+ DEFINE(CC_R25, offsetof(struct cpu_context, r25));
+ DEFINE(CC_R26, offsetof(struct cpu_context, r26));
+ DEFINE(CC_R27, offsetof(struct cpu_context, r27));
+ DEFINE(CC_R28, offsetof(struct cpu_context, r28));
+ DEFINE(CC_R29, offsetof(struct cpu_context, r29));
+ DEFINE(CC_R30, offsetof(struct cpu_context, r30));
+ /* special purpose registers */
+ DEFINE(CC_MSR, offsetof(struct cpu_context, msr));
+ DEFINE(CC_EAR, offsetof(struct cpu_context, ear));
+ DEFINE(CC_ESR, offsetof(struct cpu_context, esr));
+ DEFINE(CC_FSR, offsetof(struct cpu_context, fsr));
+ BLANK();
+
+ return 0;
+}
diff --git a/arch/microblaze/kernel/cpu/Makefile b/arch/microblaze/kernel/cpu/Makefile
new file mode 100644
index 00000000000..20646e54927
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/Makefile
@@ -0,0 +1,8 @@
+#
+# Build the appropriate CPU version support
+#
+
+EXTRA_CFLAGS += -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \
+ -DCPU_REV=$(CPU_REV)
+
+obj-y += cache.o cpuinfo.o cpuinfo-pvr-full.o cpuinfo-static.o mb.o pvr.o
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c
new file mode 100644
index 00000000000..be9fecca4f9
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/cache.c
@@ -0,0 +1,258 @@
+/*
+ * Cache control for MicroBlaze cache memories
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ *
+ * 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 <asm/cacheflush.h>
+#include <linux/cache.h>
+#include <asm/cpuinfo.h>
+
+/* Exported functions */
+
+void _enable_icache(void)
+{
+ if (cpuinfo.use_icache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+ __asm__ __volatile__ (" \
+ msrset r0, %0; \
+ nop; " \
+ : \
+ : "i" (MSR_ICE) \
+ : "memory");
+#else
+ __asm__ __volatile__ (" \
+ mfs r12, rmsr; \
+ nop; \
+ ori r12, r12, %0; \
+ mts rmsr, r12; \
+ nop; " \
+ : \
+ : "i" (MSR_ICE) \
+ : "memory", "r12");
+#endif
+ }
+}
+
+void _disable_icache(void)
+{
+ if (cpuinfo.use_icache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+ __asm__ __volatile__ (" \
+ msrclr r0, %0; \
+ nop; " \
+ : \
+ : "i" (MSR_ICE) \
+ : "memory");
+#else
+ __asm__ __volatile__ (" \
+ mfs r12, rmsr; \
+ nop; \
+ andi r12, r12, ~%0; \
+ mts rmsr, r12; \
+ nop; " \
+ : \
+ : "i" (MSR_ICE) \
+ : "memory", "r12");
+#endif
+ }
+}
+
+void _invalidate_icache(unsigned int addr)
+{
+ if (cpuinfo.use_icache) {
+ __asm__ __volatile__ (" \
+ wic %0, r0" \
+ : \
+ : "r" (addr));
+ }
+}
+
+void _enable_dcache(void)
+{
+ if (cpuinfo.use_dcache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+ __asm__ __volatile__ (" \
+ msrset r0, %0; \
+ nop; " \
+ : \
+ : "i" (MSR_DCE) \
+ : "memory");
+#else
+ __asm__ __volatile__ (" \
+ mfs r12, rmsr; \
+ nop; \
+ ori r12, r12, %0; \
+ mts rmsr, r12; \
+ nop; " \
+ : \
+ : "i" (MSR_DCE) \
+ : "memory", "r12");
+#endif
+ }
+}
+
+void _disable_dcache(void)
+{
+ if (cpuinfo.use_dcache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+ __asm__ __volatile__ (" \
+ msrclr r0, %0; \
+ nop; " \
+ : \
+ : "i" (MSR_DCE) \
+ : "memory");
+#else
+ __asm__ __volatile__ (" \
+ mfs r12, rmsr; \
+ nop; \
+ andi r12, r12, ~%0; \
+ mts rmsr, r12; \
+ nop; " \
+ : \
+ : "i" (MSR_DCE) \
+ : "memory", "r12");
+#endif
+ }
+}
+
+void _invalidate_dcache(unsigned int addr)
+{
+ if (cpuinfo.use_dcache)
+ __asm__ __volatile__ (" \
+ wdc %0, r0" \
+ : \
+ : "r" (addr));
+}
+
+void __invalidate_icache_all(void)
+{
+ unsigned int i;
+ unsigned flags;
+
+ if (cpuinfo.use_icache) {
+ local_irq_save(flags);
+ __disable_icache();
+
+ /* Just loop through cache size and invalidate, no need to add
+ CACHE_BASE address */
+ for (i = 0; i < cpuinfo.icache_size;
+ i += cpuinfo.icache_line)
+ __invalidate_icache(i);
+
+ __enable_icache();
+ local_irq_restore(flags);
+ }
+}
+
+void __invalidate_icache_range(unsigned long start, unsigned long end)
+{
+ unsigned int i;
+ unsigned flags;
+ unsigned int align;
+
+ if (cpuinfo.use_icache) {
+ /*
+ * No need to cover entire cache range,
+ * just cover cache footprint
+ */
+ end = min(start + cpuinfo.icache_size, end);
+ align = ~(cpuinfo.icache_line - 1);
+ start &= align; /* Make sure we are aligned */
+ /* Push end up to the next cache line */
+ end = ((end & align) + cpuinfo.icache_line);
+
+ local_irq_save(flags);
+ __disable_icache();
+
+ for (i = start; i < end; i += cpuinfo.icache_line)
+ __invalidate_icache(i);
+
+ __enable_icache();
+ local_irq_restore(flags);
+ }
+}
+
+void __invalidate_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+ __invalidate_icache_all();
+}
+
+void __invalidate_icache_user_range(struct vm_area_struct *vma,
+ struct page *page, unsigned long adr,
+ int len)
+{
+ __invalidate_icache_all();
+}
+
+void __invalidate_cache_sigtramp(unsigned long addr)
+{
+ __invalidate_icache_range(addr, addr + 8);
+}
+
+void __invalidate_dcache_all(void)
+{
+ unsigned int i;
+ unsigned flags;
+
+ if (cpuinfo.use_dcache) {
+ local_irq_save(flags);
+ __disable_dcache();
+
+ /*
+ * Just loop through cache size and invalidate,
+ * no need to add CACHE_BASE address
+ */
+ for (i = 0; i < cpuinfo.dcache_size;
+ i += cpuinfo.dcache_line)
+ __invalidate_dcache(i);
+
+ __enable_dcache();
+ local_irq_restore(flags);
+ }
+}
+
+void __invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+ unsigned int i;
+ unsigned flags;
+ unsigned int align;
+
+ if (cpuinfo.use_dcache) {
+ /*
+ * No need to cover entire cache range,
+ * just cover cache footprint
+ */
+ end = min(start + cpuinfo.dcache_size, end);
+ align = ~(cpuinfo.dcache_line - 1);
+ start &= align; /* Make sure we are aligned */
+ /* Push end up to the next cache line */
+ end = ((end & align) + cpuinfo.dcache_line);
+ local_irq_save(flags);
+ __disable_dcache();
+
+ for (i = start; i < end; i += cpuinfo.dcache_line)
+ __invalidate_dcache(i);
+
+ __enable_dcache();
+ local_irq_restore(flags);
+ }
+}
+
+void __invalidate_dcache_page(struct vm_area_struct *vma, struct page *page)
+{
+ __invalidate_dcache_all();
+}
+
+void __invalidate_dcache_user_range(struct vm_area_struct *vma,
+ struct page *page, unsigned long adr,
+ int len)
+{
+ __invalidate_dcache_all();
+}
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
new file mode 100644
index 00000000000..cf7424a6bb8
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
@@ -0,0 +1,101 @@
+/*
+ * Support for MicroBlaze PVR (processor version register)
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ *
+ * 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/string.h>
+#include <asm/pvr.h>
+#include <asm/cpuinfo.h>
+
+/*
+ * Helper macro to map between fields in our struct cpuinfo, and
+ * the PVR macros in pvr.h.
+ */
+
+#define CI(c, p) { ci->c = PVR_##p(pvr); }
+#define err_printk(x) \
+ early_printk("ERROR: Microblaze " x " - different for PVR and DTS\n");
+
+void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
+{
+ struct pvr_s pvr;
+ int temp; /* for saving temp value */
+ get_pvr(&pvr);
+
+ temp = PVR_USE_BARREL(pvr) | PVR_USE_MSR_INSTR(pvr) |\
+ PVR_USE_PCMP_INSTR(pvr) | PVR_USE_DIV(pvr);
+ if (ci->use_instr != temp)
+ err_printk("BARREL, MSR, PCMP or DIV");
+ ci->use_instr = temp;
+
+ temp = PVR_USE_HW_MUL(pvr) | PVR_USE_MUL64(pvr);
+ if (ci->use_mult != temp)
+ err_printk("HW_MUL");
+ ci->use_mult = temp;
+
+ temp = PVR_USE_FPU(pvr) | PVR_USE_FPU2(pvr);
+ if (ci->use_fpu != temp)
+ err_printk("HW_FPU");
+ ci->use_fpu = temp;
+
+ ci->use_exc = PVR_OPCODE_0x0_ILLEGAL(pvr) |\
+ PVR_UNALIGNED_EXCEPTION(pvr) |\
+ PVR_ILL_OPCODE_EXCEPTION(pvr) |\
+ PVR_IOPB_BUS_EXCEPTION(pvr) |\
+ PVR_DOPB_BUS_EXCEPTION(pvr) |\
+ PVR_DIV_ZERO_EXCEPTION(pvr) |\
+ PVR_FPU_EXCEPTION(pvr) |\
+ PVR_FSL_EXCEPTION(pvr);
+
+ CI(pvr_user1, USER1);
+ CI(pvr_user2, USER2);
+
+ CI(mmu, USE_MMU);
+
+ CI(ver_code, VERSION);
+
+ CI(use_icache, USE_ICACHE);
+ CI(icache_tagbits, ICACHE_ADDR_TAG_BITS);
+ CI(icache_write, ICACHE_ALLOW_WR);
+ CI(icache_line, ICACHE_LINE_LEN);
+ CI(icache_size, ICACHE_BYTE_SIZE);
+ CI(icache_base, ICACHE_BASEADDR);
+ CI(icache_high, ICACHE_HIGHADDR);
+
+ CI(use_dcache, USE_DCACHE);
+ CI(dcache_tagbits, DCACHE_ADDR_TAG_BITS);
+ CI(dcache_write, DCACHE_ALLOW_WR);
+ CI(dcache_line, DCACHE_LINE_LEN);
+ CI(dcache_size, DCACHE_BYTE_SIZE);
+ CI(dcache_base, DCACHE_BASEADDR);
+ CI(dcache_high, DCACHE_HIGHADDR);
+
+ CI(use_dopb, D_OPB);
+ CI(use_iopb, I_OPB);
+ CI(use_dlmb, D_LMB);
+ CI(use_ilmb, I_LMB);
+ CI(num_fsl, FSL_LINKS);
+
+ CI(irq_edge, INTERRUPT_IS_EDGE);
+ CI(irq_positive, EDGE_IS_POSITIVE);
+
+ CI(area_optimised, AREA_OPTIMISED);
+
+ CI(hw_debug, DEBUG_ENABLED);
+ CI(num_pc_brk, NUMBER_OF_PC_BRK);
+ CI(num_rd_brk, NUMBER_OF_RD_ADDR_BRK);
+ CI(num_wr_brk, NUMBER_OF_WR_ADDR_BRK);
+
+ CI(fpga_family_code, TARGET_FAMILY);
+
+ /* take timebase-frequency from DTS */
+ ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency");
+}
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c
new file mode 100644
index 00000000000..cfe44effdb7
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ *
+ * 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/init.h>
+#include <linux/string.h>
+#include <asm/cpuinfo.h>
+#include <asm/pvr.h>
+
+const static char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY;
+const static char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER;
+
+#define err_printk(x) \
+ early_printk("ERROR: Microblaze " x "- different for kernel and DTS\n");
+
+void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
+{
+ int i = 0;
+
+ ci->use_instr =
+ (fcpu(cpu, "xlnx,use-barrel") ? PVR0_USE_BARREL_MASK : 0) |
+ (fcpu(cpu, "xlnx,use-msr-instr") ? PVR2_USE_MSR_INSTR : 0) |
+ (fcpu(cpu, "xlnx,use-pcmp-instr") ? PVR2_USE_PCMP_INSTR : 0) |
+ (fcpu(cpu, "xlnx,use-div") ? PVR0_USE_DIV_MASK : 0);
+ if (CONFIG_XILINX_MICROBLAZE0_USE_BARREL)
+ i |= PVR0_USE_BARREL_MASK;
+ if (CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR)
+ i |= PVR2_USE_MSR_INSTR;
+ if (CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR)
+ i |= PVR2_USE_PCMP_INSTR;
+ if (CONFIG_XILINX_MICROBLAZE0_USE_DIV)
+ i |= PVR0_USE_DIV_MASK;
+ if (ci->use_instr != i)
+ err_printk("BARREL, MSR, PCMP or DIV");
+
+ ci->use_mult = fcpu(cpu, "xlnx,use-hw-mul");
+ if (ci->use_mult != CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL)
+ err_printk("HW_MUL");
+ ci->use_mult =
+ (ci->use_mult > 1 ?
+ (PVR2_USE_MUL64_MASK | PVR0_USE_HW_MUL_MASK) :
+ (ci->use_mult == 1 ? PVR0_USE_HW_MUL_MASK : 0));
+
+ ci->use_fpu = fcpu(cpu, "xlnx,use-fpu");
+ if (ci->use_fpu != CONFIG_XILINX_MICROBLAZE0_USE_FPU)
+ err_printk("HW_FPU");
+ ci->use_fpu = (ci->use_fpu > 1 ?
+ (PVR2_USE_FPU2_MASK | PVR0_USE_FPU_MASK) :
+ (ci->use_fpu == 1 ? PVR0_USE_FPU_MASK : 0));
+
+ ci->use_exc =
+ (fcpu(cpu, "xlnx,unaligned-exceptions") ?
+ PVR2_UNALIGNED_EXC_MASK : 0) |
+ (fcpu(cpu, "xlnx,ill-opcode-exception") ?
+ PVR2_ILL_OPCODE_EXC_MASK : 0) |
+ (fcpu(cpu, "xlnx,iopb-bus-exception") ?
+ PVR2_IOPB_BUS_EXC_MASK : 0) |
+ (fcpu(cpu, "xlnx,dopb-bus-exception") ?
+ PVR2_DOPB_BUS_EXC_MASK : 0) |
+ (fcpu(cpu, "xlnx,div-zero-exception") ?
+ PVR2_DIV_ZERO_EXC_MASK : 0) |
+ (fcpu(cpu, "xlnx,fpu-exception") ? PVR2_FPU_EXC_MASK : 0) |
+ (fcpu(cpu, "xlnx,fsl-exception") ? PVR2_USE_EXTEND_FSL : 0);
+
+ ci->use_icache = fcpu(cpu, "xlnx,use-icache");
+ ci->icache_tagbits = fcpu(cpu, "xlnx,addr-tag-bits");
+ ci->icache_write = fcpu(cpu, "xlnx,allow-icache-wr");
+ ci->icache_line = fcpu(cpu, "xlnx,icache-line-len") << 2;
+ if (!ci->icache_line) {
+ if (fcpu(cpu, "xlnx,icache-use-fsl"))
+ ci->icache_line = 4 << 2;
+ else
+ ci->icache_line = 1 << 2;
+ }
+ ci->icache_size = fcpu(cpu, "i-cache-size");
+ ci->icache_base = fcpu(cpu, "i-cache-baseaddr");
+ ci->icache_high = fcpu(cpu, "i-cache-highaddr");
+
+ ci->use_dcache = fcpu(cpu, "xlnx,use-dcache");
+ ci->dcache_tagbits = fcpu(cpu, "xlnx,dcache-addr-tag");
+ ci->dcache_write = fcpu(cpu, "xlnx,allow-dcache-wr");
+ ci->dcache_line = fcpu(cpu, "xlnx,dcache-line-len") << 2;
+ if (!ci->dcache_line) {
+ if (fcpu(cpu, "xlnx,dcache-use-fsl"))
+ ci->dcache_line = 4 << 2;
+ else
+ ci->dcache_line = 1 << 2;
+ }
+ ci->dcache_size = fcpu(cpu, "d-cache-size");
+ ci->dcache_base = fcpu(cpu, "d-cache-baseaddr");
+ ci->dcache_high = fcpu(cpu, "d-cache-highaddr");
+
+ ci->use_dopb = fcpu(cpu, "xlnx,d-opb");
+ ci->use_iopb = fcpu(cpu, "xlnx,i-opb");
+ ci->use_dlmb = fcpu(cpu, "xlnx,d-lmb");
+ ci->use_ilmb = fcpu(cpu, "xlnx,i-lmb");
+
+ ci->num_fsl = fcpu(cpu, "xlnx,fsl-links");
+ ci->irq_edge = fcpu(cpu, "xlnx,interrupt-is-edge");
+ ci->irq_positive = fcpu(cpu, "xlnx,edge-is-positive");
+ ci->area_optimised = 0;
+
+ ci->hw_debug = fcpu(cpu, "xlnx,debug-enabled");
+ ci->num_pc_brk = fcpu(cpu, "xlnx,number-of-pc-brk");
+ ci->num_rd_brk = fcpu(cpu, "xlnx,number-of-rd-addr-brk");
+ ci->num_wr_brk = fcpu(cpu, "xlnx,number-of-wr-addr-brk");
+
+ ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency");
+
+ ci->pvr_user1 = fcpu(cpu, "xlnx,pvr-user1");
+ ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2");
+
+ ci->mmu = fcpu(cpu, "xlnx,use-mmu");
+
+ ci->ver_code = 0;
+ ci->fpga_family_code = 0;
+
+ /* Do various fixups based on CPU version and FPGA family strings */
+
+ /* Resolved the CPU version code */
+ for (i = 0; cpu_ver_lookup[i].s != NULL; i++) {
+ if (strcmp(cpu_ver_lookup[i].s, cpu_ver_string) == 0)
+ ci->ver_code = cpu_ver_lookup[i].k;
+ }
+
+ /* Resolved the fpga family code */
+ for (i = 0; family_string_lookup[i].s != NULL; i++) {
+ if (strcmp(family_string_lookup[i].s, family_string) == 0)
+ ci->fpga_family_code = family_string_lookup[i].k;
+ }
+
+ /* FIXME - mb3 and spartan2 do not exist in PVR */
+ /* This is mb3 and on a non Spartan2 */
+ if (ci->ver_code == 0x20 && ci->fpga_family_code != 0xf0)
+ /* Hardware Multiplier in use */
+ ci->use_mult = 1;
+}
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
new file mode 100644
index 00000000000..4a740dfcf6d
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ *
+ * 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/slab.h>
+#include <asm/cpuinfo.h>
+#include <asm/pvr.h>
+
+const struct cpu_ver_key cpu_ver_lookup[] = {
+ /* These key value are as per MBV field in PVR0 */
+ {"5.00.a", 0x01},
+ {"5.00.b", 0x02},
+ {"5.00.c", 0x03},
+ {"6.00.a", 0x04},
+ {"6.00.b", 0x06},
+ {"7.00.a", 0x05},
+ {"7.00.b", 0x07},
+ {"7.10.a", 0x08},
+ {"7.10.b", 0x09},
+ {"7.10.c", 0x0a},
+ {"7.10.d", 0x0b},
+ /* FIXME There is no keycode defined in MBV for these versions */
+ {"2.10.a", 0x10},
+ {"3.00.a", 0x20},
+ {"4.00.a", 0x30},
+ {"4.00.b", 0x40},
+ {NULL, 0},
+};
+
+/*
+ * FIXME Not sure if the actual key is defined by Xilinx in the PVR
+ */
+const struct family_string_key family_string_lookup[] = {
+ {"virtex2", 0x4},
+ {"virtex2pro", 0x5},
+ {"spartan3", 0x6},
+ {"virtex4", 0x7},
+ {"virtex5", 0x8},
+ {"spartan3e", 0x9},
+ {"spartan3a", 0xa},
+ {"spartan3an", 0xb},
+ {"spartan3adsp", 0xc},
+ /* FIXME There is no key code defined for spartan2 */
+ {"spartan2", 0xf0},
+ {NULL, 0},
+};
+
+struct cpuinfo cpuinfo;
+
+void __init setup_cpuinfo(void)
+{
+ struct device_node *cpu = NULL;
+
+ cpu = (struct device_node *) of_find_node_by_type(NULL, "cpu");
+ if (!cpu)
+ printk(KERN_ERR "You don't have cpu!!!\n");
+
+ printk(KERN_INFO "%s: initialising\n", __func__);
+
+ switch (cpu_has_pvr()) {
+ case 0:
+ printk(KERN_WARNING
+ "%s: No PVR support. Using static CPU info from FDT\n",
+ __func__);
+ set_cpuinfo_static(&cpuinfo, cpu);
+ break;
+/* FIXME I found weird behavior with MB 7.00.a/b
+ * please do not use FULL PVR with MMU */
+ case 1:
+ printk(KERN_INFO "%s: Using full CPU PVR support\n",
+ __func__);
+ set_cpuinfo_static(&cpuinfo, cpu);
+ set_cpuinfo_pvr_full(&cpuinfo, cpu);
+ break;
+ default:
+ printk(KERN_WARNING "%s: Unsupported PVR setting\n", __func__);
+ set_cpuinfo_static(&cpuinfo, cpu);
+ }
+}
diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c
new file mode 100644
index 00000000000..3b6212bdc8d
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/mb.c
@@ -0,0 +1,148 @@
+/*
+ * CPU-version specific code
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006-2009 PetaLogix
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/cpu.h>
+#include <linux/initrd.h>
+
+#include <linux/bug.h>
+#include <asm/cpuinfo.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <asm/page.h>
+#include <linux/param.h>
+#include <asm/pvr.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+ int count = 0;
+ char *fpga_family = "Unknown";
+ char *cpu_ver = "Unknown";
+ int i;
+
+ /* Denormalised to get the fpga family string */
+ for (i = 0; family_string_lookup[i].s != NULL; i++) {
+ if (cpuinfo.fpga_family_code == family_string_lookup[i].k) {
+ fpga_family = (char *)family_string_lookup[i].s;
+ break;
+ }
+ }
+
+ /* Denormalised to get the hw version string */
+ for (i = 0; cpu_ver_lookup[i].s != NULL; i++) {
+ if (cpuinfo.ver_code == cpu_ver_lookup[i].k) {
+ cpu_ver = (char *)cpu_ver_lookup[i].s;
+ break;
+ }
+ }
+
+ count = seq_printf(m,
+ "CPU-Family: MicroBlaze\n"
+ "FPGA-Arch: %s\n"
+ "CPU-Ver: %s\n"
+ "CPU-MHz: %d.%02d\n"
+ "BogoMips: %lu.%02lu\n",
+ fpga_family,
+ cpu_ver,
+ cpuinfo.cpu_clock_freq /
+ 1000000,
+ cpuinfo.cpu_clock_freq %
+ 1000000,
+ loops_per_jiffy / (500000 / HZ),
+ (loops_per_jiffy / (5000 / HZ)) % 100);
+
+ count += seq_printf(m,
+ "HW:\n Shift:\t\t%s\n"
+ " MSR:\t\t%s\n"
+ " PCMP:\t\t%s\n"
+ " DIV:\t\t%s\n",
+ (cpuinfo.use_instr & PVR0_USE_BARREL_MASK) ? "yes" : "no",
+ (cpuinfo.use_instr & PVR2_USE_MSR_INSTR) ? "yes" : "no",
+ (cpuinfo.use_instr & PVR2_USE_PCMP_INSTR) ? "yes" : "no",
+ (cpuinfo.use_instr & PVR0_USE_DIV_MASK) ? "yes" : "no");
+
+ count += seq_printf(m,
+ " MMU:\t\t%x\n",
+ cpuinfo.mmu);
+
+ count += seq_printf(m,
+ " MUL:\t\t%s\n"
+ " FPU:\t\t%s\n",
+ (cpuinfo.use_mult & PVR2_USE_MUL64_MASK) ? "v2" :
+ (cpuinfo.use_mult & PVR0_USE_HW_MUL_MASK) ? "v1" : "no",
+ (cpuinfo.use_fpu & PVR2_USE_FPU2_MASK) ? "v2" :
+ (cpuinfo.use_fpu & PVR0_USE_FPU_MASK) ? "v1" : "no");
+
+ count += seq_printf(m,
+ " Exc:\t\t%s%s%s%s%s%s%s%s\n",
+ (cpuinfo.use_exc & PVR2_OPCODE_0x0_ILL_MASK) ? "op0x0 " : "",
+ (cpuinfo.use_exc & PVR2_UNALIGNED_EXC_MASK) ? "unal " : "",
+ (cpuinfo.use_exc & PVR2_ILL_OPCODE_EXC_MASK) ? "ill " : "",
+ (cpuinfo.use_exc & PVR2_IOPB_BUS_EXC_MASK) ? "iopb " : "",
+ (cpuinfo.use_exc & PVR2_DOPB_BUS_EXC_MASK) ? "dopb " : "",
+ (cpuinfo.use_exc & PVR2_DIV_ZERO_EXC_MASK) ? "zero " : "",
+ (cpuinfo.use_exc & PVR2_FPU_EXC_MASK) ? "fpu " : "",
+ (cpuinfo.use_exc & PVR2_USE_FSL_EXC) ? "fsl " : "");
+
+ if (cpuinfo.use_icache)
+ count += seq_printf(m,
+ "Icache:\t\t%ukB\n",
+ cpuinfo.icache_size >> 10);
+ else
+ count += seq_printf(m, "Icache:\t\tno\n");
+
+ if (cpuinfo.use_dcache)
+ count += seq_printf(m,
+ "Dcache:\t\t%ukB\n",
+ cpuinfo.dcache_size >> 10);
+ else
+ count += seq_printf(m, "Dcache:\t\tno\n");
+
+ count += seq_printf(m,
+ "HW-Debug:\t%s\n",
+ cpuinfo.hw_debug ? "yes" : "no");
+
+ count += seq_printf(m,
+ "PVR-USR1:\t%x\n"
+ "PVR-USR2:\t%x\n",
+ cpuinfo.pvr_user1,
+ cpuinfo.pvr_user2);
+
+ return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ int i = *pos;
+
+ return i < NR_CPUS ? (void *) (i + 1) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+const struct seq_operations cpuinfo_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = show_cpuinfo,
+};
diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c
new file mode 100644
index 00000000000..c9a4340ddd5
--- /dev/null
+++ b/arch/microblaze/kernel/cpu/pvr.c
@@ -0,0 +1,81 @@
+/*
+ * Support for MicroBlaze PVR (processor version register)
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ *
+ * 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/compiler.h>
+#include <asm/system.h>
+#include <asm/exceptions.h>
+#include <asm/pvr.h>
+
+/*
+ * Until we get an assembler that knows about the pvr registers,
+ * this horrible cruft will have to do.
+ * That hardcoded opcode is mfs r3, rpvrNN
+ */
+
+#define get_single_pvr(pvrid, val) \
+{ \
+ register unsigned tmp __asm__("r3"); \
+ tmp = 0x0; /* Prevent warning about unused */ \
+ __asm__ __volatile__ ( \
+ ".byte 0x94,0x60,0xa0, " #pvrid "\n\t" \
+ : "=r" (tmp) : : "memory"); \
+ val = tmp; \
+}
+
+/*
+ * Does the CPU support the PVR register?
+ * return value:
+ * 0: no PVR
+ * 1: simple PVR
+ * 2: full PVR
+ *
+ * This must work on all CPU versions, including those before the
+ * PVR was even an option.
+ */
+
+int cpu_has_pvr(void)
+{
+ unsigned flags;
+ unsigned pvr0;
+
+ local_save_flags(flags);
+
+ /* PVR bit in MSR tells us if there is any support */
+ if (!(flags & PVR_MSR_BIT))
+ return 0;
+
+ get_single_pvr(0x00, pvr0);
+ pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0);
+
+ if (pvr0 & PVR0_PVR_FULL_MASK)
+ return 1;
+
+ /* for partial PVR use static cpuinfo */
+ return 2;
+}
+
+void get_pvr(struct pvr_s *p)
+{
+ get_single_pvr(0, p->pvr[0]);
+ get_single_pvr(1, p->pvr[1]);
+ get_single_pvr(2, p->pvr[2]);
+ get_single_pvr(3, p->pvr[3]);
+ get_single_pvr(4, p->pvr[4]);
+ get_single_pvr(5, p->pvr[5]);
+ get_single_pvr(6, p->pvr[6]);
+ get_single_pvr(7, p->pvr[7]);
+ get_single_pvr(8, p->pvr[8]);
+ get_single_pvr(9, p->pvr[9]);
+ get_single_pvr(10, p->pvr[10]);
+ get_single_pvr(11, p->pvr[11]);
+}
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c
new file mode 100644
index 00000000000..62cc78993f4
--- /dev/null
+++ b/arch/microblaze/kernel/early_printk.c
@@ -0,0 +1,107 @@
+/*
+ * Early printk support for Microblaze.
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2003-2006 Yasushi SHOJI <yashi@atmark-techno.com>
+ *
+ * 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/console.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/io.h>
+#include <asm/processor.h>
+#include <linux/fcntl.h>
+#include <asm/setup.h>
+#include <asm/prom.h>
+
+static u32 early_console_initialized;
+static u32 base_addr;
+
+static void early_printk_putc(char c)
+{
+ /*
+ * Limit how many times we'll spin waiting for TX FIFO status.
+ * This will prevent lockups if the base address is incorrectly
+ * set, or any other issue on the UARTLITE.
+ * This limit is pretty arbitrary, unless we are at about 10 baud
+ * we'll never timeout on a working UART.
+ */
+
+ unsigned retries = 10000;
+ /* read status bit - 0x8 offset */
+ while (retries-- && (in_be32(base_addr + 8) & (1 << 3)))
+ ;
+
+ /* Only attempt the iowrite if we didn't timeout */
+ /* write to TX_FIFO - 0x4 offset */
+ if (retries)
+ out_be32(base_addr + 4, c & 0xff);
+}
+
+static void early_printk_write(struct console *unused,
+ const char *s, unsigned n)
+{
+ while (*s && n-- > 0) {
+ early_printk_putc(*s);
+ if (*s == '\n')
+ early_printk_putc('\r');
+ s++;
+ }
+}
+
+static struct console early_serial_console = {
+ .name = "earlyser",
+ .write = early_printk_write,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
+static struct console *early_console = &early_serial_console;
+
+void early_printk(const char *fmt, ...)
+{
+ char buf[512];
+ int n;
+ va_list ap;
+
+ if (early_console_initialized) {
+ va_start(ap, fmt);
+ n = vscnprintf(buf, 512, fmt, ap);
+ early_console->write(early_console, buf, n);
+ va_end(ap);
+ }
+}
+
+int __init setup_early_printk(char *opt)
+{
+ if (early_console_initialized)
+ return 1;
+
+ base_addr = early_uartlite_console();
+ if (base_addr) {
+ early_console_initialized = 1;
+ early_printk("early_printk_console is enabled at 0x%08x\n",
+ base_addr);
+
+ /* register_console(early_console); */
+
+ return 0;
+ } else
+ return 1;
+}
+
+void __init disable_early_printk(void)
+{
+ if (!early_console_initialized || !early_console)
+ return;
+ printk(KERN_WARNING "disabling early console\n");
+ unregister_console(early_console);
+ early_console_initialized = 0;
+}
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
new file mode 100644
index 00000000000..f24b1268baa
--- /dev/null
+++ b/arch/microblaze/kernel/entry-nommu.S
@@ -0,0 +1,596 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+#include <asm/entry.h>
+#include <asm/asm-offsets.h>
+#include <asm/registers.h>
+#include <asm/unistd.h>
+#include <asm/percpu.h>
+#include <asm/signal.h>
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+ .macro disable_irq
+ msrclr r0, MSR_IE
+ .endm
+
+ .macro enable_irq
+ msrset r0, MSR_IE
+ .endm
+
+ .macro clear_bip
+ msrclr r0, MSR_BIP
+ .endm
+#else
+ .macro disable_irq
+ mfs r11, rmsr
+ andi r11, r11, ~MSR_IE
+ mts rmsr, r11
+ .endm
+
+ .macro enable_irq
+ mfs r11, rmsr
+ ori r11, r11, MSR_IE
+ mts rmsr, r11
+ .endm
+
+ .macro clear_bip
+ mfs r11, rmsr
+ andi r11, r11, ~MSR_BIP
+ mts rmsr, r11
+ .endm
+#endif
+
+ENTRY(_interrupt)
+ swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */
+ swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */
+ lwi r11, r0, PER_CPU(KM) /* load mode indicator */
+ beqid r11, 1f
+ nop
+ brid 2f /* jump over */
+ addik r1, r1, (-PT_SIZE) /* room for pt_regs (delay slot) */
+1: /* switch to kernel stack */
+ lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */
+ lwi r1, r1, TS_THREAD_INFO /* get the thread info */
+ /* calculate kernel stack pointer */
+ addik r1, r1, THREAD_SIZE - PT_SIZE
+2:
+ swi r11, r1, PT_MODE /* store the mode */
+ lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */
+ swi r2, r1, PT_R2
+ swi r3, r1, PT_R3
+ swi r4, r1, PT_R4
+ swi r5, r1, PT_R5
+ swi r6, r1, PT_R6
+ swi r7, r1, PT_R7
+ swi r8, r1, PT_R8
+ swi r9, r1, PT_R9
+ swi r10, r1, PT_R10
+ swi r11, r1, PT_R11
+ swi r12, r1, PT_R12
+ swi r13, r1, PT_R13
+ swi r14, r1, PT_R14
+ swi r14, r1, PT_PC
+ swi r15, r1, PT_R15
+ swi r16, r1, PT_R16
+ swi r17, r1, PT_R17
+ swi r18, r1, PT_R18
+ swi r19, r1, PT_R19
+ swi r20, r1, PT_R20
+ swi r21, r1, PT_R21
+ swi r22, r1, PT_R22
+ swi r23, r1, PT_R23
+ swi r24, r1, PT_R24
+ swi r25, r1, PT_R25
+ swi r26, r1, PT_R26
+ swi r27, r1, PT_R27
+ swi r28, r1, PT_R28
+ swi r29, r1, PT_R29
+ swi r30, r1, PT_R30
+ swi r31, r1, PT_R31
+ /* special purpose registers */
+ mfs r11, rmsr
+ swi r11, r1, PT_MSR
+ mfs r11, rear
+ swi r11, r1, PT_EAR
+ mfs r11, resr
+ swi r11, r1, PT_ESR
+ mfs r11, rfsr
+ swi r11, r1, PT_FSR
+ /* reload original stack pointer and save it */
+ lwi r11, r0, PER_CPU(ENTRY_SP)
+ swi r11, r1, PT_R1
+ /* update mode indicator we are in kernel mode */
+ addik r11, r0, 1
+ swi r11, r0, PER_CPU(KM)
+ /* restore r31 */
+ lwi r31, r0, PER_CPU(CURRENT_SAVE)
+ /* prepare the link register, the argument and jump */
+ la r15, r0, ret_from_intr - 8
+ addk r6, r0, r15
+ braid do_IRQ
+ add r5, r0, r1
+
+ret_from_intr:
+ lwi r11, r1, PT_MODE
+ bneid r11, 3f
+
+ lwi r6, r31, TS_THREAD_INFO /* get thread info */
+ lwi r19, r6, TI_FLAGS /* get flags in thread info */
+ /* do an extra work if any bits are set */
+
+ andi r11, r19, _TIF_NEED_RESCHED
+ beqi r11, 1f
+ bralid r15, schedule
+ nop
+1: andi r11, r19, _TIF_SIGPENDING
+ beqid r11, no_intr_reshed
+ addk r5, r1, r0
+ addk r7, r0, r0
+ bralid r15, do_signal
+ addk r6, r0, r0
+
+no_intr_reshed:
+ /* save mode indicator */
+ lwi r11, r1, PT_MODE
+3:
+ swi r11, r0, PER_CPU(KM)
+
+ /* save r31 */
+ swi r31, r0, PER_CPU(CURRENT_SAVE)
+restore_context:
+ /* special purpose registers */
+ lwi r11, r1, PT_FSR
+ mts rfsr, r11
+ lwi r11, r1, PT_ESR
+ mts resr, r11
+ lwi r11, r1, PT_EAR
+ mts rear, r11
+ lwi r11, r1, PT_MSR
+ mts rmsr, r11
+
+ lwi r31, r1, PT_R31
+ lwi r30, r1, PT_R30
+ lwi r29, r1, PT_R29
+ lwi r28, r1, PT_R28
+ lwi r27, r1, PT_R27
+ lwi r26, r1, PT_R26
+ lwi r25, r1, PT_R25
+ lwi r24, r1, PT_R24
+ lwi r23, r1, PT_R23
+ lwi r22, r1, PT_R22
+ lwi r21, r1, PT_R21
+ lwi r20, r1, PT_R20
+ lwi r19, r1, PT_R19
+ lwi r18, r1, PT_R18
+ lwi r17, r1, PT_R17
+ lwi r16, r1, PT_R16
+ lwi r15, r1, PT_R15
+ lwi r14, r1, PT_PC
+ lwi r13, r1, PT_R13
+ lwi r12, r1, PT_R12
+ lwi r11, r1, PT_R11
+ lwi r10, r1, PT_R10
+ lwi r9, r1, PT_R9
+ lwi r8, r1, PT_R8
+ lwi r7, r1, PT_R7
+ lwi r6, r1, PT_R6
+ lwi r5, r1, PT_R5
+ lwi r4, r1, PT_R4
+ lwi r3, r1, PT_R3
+ lwi r2, r1, PT_R2
+ lwi r1, r1, PT_R1
+ rtid r14, 0
+ nop
+
+ENTRY(_reset)
+ brai 0;
+
+ENTRY(_user_exception)
+ swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */
+ swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */
+ lwi r11, r0, PER_CPU(KM) /* load mode indicator */
+ beqid r11, 1f /* Already in kernel mode? */
+ nop
+ brid 2f /* jump over */
+ addik r1, r1, (-PT_SIZE) /* Room for pt_regs (delay slot) */
+1: /* Switch to kernel stack */
+ lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */
+ lwi r1, r1, TS_THREAD_INFO /* get the thread info */
+ /* calculate kernel stack pointer */
+ addik r1, r1, THREAD_SIZE - PT_SIZE
+ swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */
+ lwi r11, r0, PER_CPU(KM) /* load mode indicator */
+2:
+ swi r11, r1, PT_MODE /* store the mode */
+ lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */
+ /* save them on stack */
+ swi r2, r1, PT_R2
+ swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */
+ swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */
+ swi r5, r1, PT_R5
+ swi r6, r1, PT_R6
+ swi r7, r1, PT_R7
+ swi r8, r1, PT_R8
+ swi r9, r1, PT_R9
+ swi r10, r1, PT_R10
+ swi r11, r1, PT_R11
+ /* r12: _always_ in clobber list; see unistd.h */
+ swi r12, r1, PT_R12
+ swi r13, r1, PT_R13
+ /* r14: _always_ in clobber list; see unistd.h */
+ swi r14, r1, PT_R14
+ /* but we want to return to the next inst. */
+ addik r14, r14, 0x4
+ swi r14, r1, PT_PC /* increment by 4 and store in pc */
+ swi r15, r1, PT_R15
+ swi r16, r1, PT_R16
+ swi r17, r1, PT_R17
+ swi r18, r1, PT_R18
+ swi r19, r1, PT_R19
+ swi r20, r1, PT_R20
+ swi r21, r1, PT_R21
+ swi r22, r1, PT_R22
+ swi r23, r1, PT_R23
+ swi r24, r1, PT_R24
+ swi r25, r1, PT_R25
+ swi r26, r1, PT_R26
+ swi r27, r1, PT_R27
+ swi r28, r1, PT_R28
+ swi r29, r1, PT_R29
+ swi r30, r1, PT_R30
+ swi r31, r1, PT_R31
+
+ disable_irq
+ nop /* make sure IE bit is in effect */
+ clear_bip /* once IE is in effect it is safe to clear BIP */
+ nop
+
+ /* special purpose registers */
+ mfs r11, rmsr
+ swi r11, r1, PT_MSR
+ mfs r11, rear
+ swi r11, r1, PT_EAR
+ mfs r11, resr
+ swi r11, r1, PT_ESR
+ mfs r11, rfsr
+ swi r11, r1, PT_FSR
+ /* reload original stack pointer and save it */
+ lwi r11, r0, PER_CPU(ENTRY_SP)
+ swi r11, r1, PT_R1
+ /* update mode indicator we are in kernel mode */
+ addik r11, r0, 1
+ swi r11, r0, PER_CPU(KM)
+ /* restore r31 */
+ lwi r31, r0, PER_CPU(CURRENT_SAVE)
+ /* re-enable interrupts now we are in kernel mode */
+ enable_irq
+
+ /* See if the system call number is valid. */
+ addi r11, r12, -__NR_syscalls
+ bgei r11, 1f /* return to user if not valid */
+ /* Figure out which function to use for this system call. */
+ /* Note Microblaze barrel shift is optional, so don't rely on it */
+ add r12, r12, r12 /* convert num -> ptr */
+ add r12, r12, r12
+ lwi r12, r12, sys_call_table /* Get function pointer */
+ la r15, r0, ret_to_user-8 /* set return address */
+ bra r12 /* Make the system call. */
+ bri 0 /* won't reach here */
+1:
+ brid ret_to_user /* jump to syscall epilogue */
+ addi r3, r0, -ENOSYS /* set errno in delay slot */
+
+/*
+ * Debug traps are like a system call, but entered via brki r14, 0x60
+ * All we need to do is send the SIGTRAP signal to current, ptrace and do_signal
+ * will handle the rest
+ */
+ENTRY(_debug_exception)
+ swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */
+ lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */
+ lwi r1, r1, TS_THREAD_INFO /* get the thread info */
+ addik r1, r1, THREAD_SIZE - PT_SIZE /* get the kernel stack */
+ swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */
+ lwi r11, r0, PER_CPU(KM) /* load mode indicator */
+//save_context:
+ swi r11, r1, PT_MODE /* store the mode */
+ lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */
+ /* save them on stack */
+ swi r2, r1, PT_R2
+ swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */
+ swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */
+ swi r5, r1, PT_R5
+ swi r6, r1, PT_R6
+ swi r7, r1, PT_R7
+ swi r8, r1, PT_R8
+ swi r9, r1, PT_R9
+ swi r10, r1, PT_R10
+ swi r11, r1, PT_R11
+ /* r12: _always_ in clobber list; see unistd.h */
+ swi r12, r1, PT_R12
+ swi r13, r1, PT_R13
+ /* r14: _always_ in clobber list; see unistd.h */
+ swi r14, r1, PT_R14
+ swi r14, r1, PT_PC /* Will return to interrupted instruction */
+ swi r15, r1, PT_R15
+ swi r16, r1, PT_R16
+ swi r17, r1, PT_R17
+ swi r18, r1, PT_R18
+ swi r19, r1, PT_R19
+ swi r20, r1, PT_R20
+ swi r21, r1, PT_R21
+ swi r22, r1, PT_R22
+ swi r23, r1, PT_R23
+ swi r24, r1, PT_R24
+ swi r25, r1, PT_R25
+ swi r26, r1, PT_R26
+ swi r27, r1, PT_R27
+ swi r28, r1, PT_R28
+ swi r29, r1, PT_R29
+ swi r30, r1, PT_R30
+ swi r31, r1, PT_R31
+
+ disable_irq
+ nop /* make sure IE bit is in effect */
+ clear_bip /* once IE is in effect it is safe to clear BIP */
+ nop
+
+ /* special purpose registers */
+ mfs r11, rmsr
+ swi r11, r1, PT_MSR
+ mfs r11, rear
+ swi r11, r1, PT_EAR
+ mfs r11, resr
+ swi r11, r1, PT_ESR
+ mfs r11, rfsr
+ swi r11, r1, PT_FSR
+ /* reload original stack pointer and save it */
+ lwi r11, r0, PER_CPU(ENTRY_SP)
+ swi r11, r1, PT_R1
+ /* update mode indicator we are in kernel mode */
+ addik r11, r0, 1
+ swi r11, r0, PER_CPU(KM)
+ /* restore r31 */
+ lwi r31, r0, PER_CPU(CURRENT_SAVE)
+ /* re-enable interrupts now we are in kernel mode */
+ enable_irq
+
+ addi r5, r0, SIGTRAP /* sending the trap signal */
+ add r6, r0, r31 /* to current */
+ bralid r15, send_sig
+ add r7, r0, r0 /* 3rd param zero */
+
+ /* Restore r3/r4 to work around how ret_to_user works */
+ lwi r3, r1, PT_R3
+ lwi r4, r1, PT_R4
+ bri ret_to_user
+
+ENTRY(_break)
+ bri 0
+
+/* struct task_struct *_switch_to(struct thread_info *prev,
+ struct thread_info *next); */
+ENTRY(_switch_to)
+ /* prepare return value */
+ addk r3, r0, r31
+
+ /* save registers in cpu_context */
+ /* use r11 and r12, volatile registers, as temp register */
+ addik r11, r5, TI_CPU_CONTEXT
+ swi r1, r11, CC_R1
+ swi r2, r11, CC_R2
+ /* skip volatile registers.
+ * they are saved on stack when we jumped to _switch_to() */
+ /* dedicated registers */
+ swi r13, r11, CC_R13
+ swi r14, r11, CC_R14
+ swi r15, r11, CC_R15
+ swi r16, r11, CC_R16
+ swi r17, r11, CC_R17
+ swi r18, r11, CC_R18
+ /* save non-volatile registers */
+ swi r19, r11, CC_R19
+ swi r20, r11, CC_R20
+ swi r21, r11, CC_R21
+ swi r22, r11, CC_R22
+ swi r23, r11, CC_R23
+ swi r24, r11, CC_R24
+ swi r25, r11, CC_R25
+ swi r26, r11, CC_R26
+ swi r27, r11, CC_R27
+ swi r28, r11, CC_R28
+ swi r29, r11, CC_R29
+ swi r30, r11, CC_R30
+ /* special purpose registers */
+ mfs r12, rmsr
+ swi r12, r11, CC_MSR
+ mfs r12, rear
+ swi r12, r11, CC_EAR
+ mfs r12, resr
+ swi r12, r11, CC_ESR
+ mfs r12, rfsr
+ swi r12, r11, CC_FSR
+
+ /* update r31, the current */
+ lwi r31, r6, TI_TASK
+ swi r31, r0, PER_CPU(CURRENT_SAVE)
+
+ /* get new process' cpu context and restore */
+ addik r11, r6, TI_CPU_CONTEXT
+
+ /* special purpose registers */
+ lwi r12, r11, CC_FSR
+ mts rfsr, r12
+ lwi r12, r11, CC_ESR
+ mts resr, r12
+ lwi r12, r11, CC_EAR
+ mts rear, r12
+ lwi r12, r11, CC_MSR
+ mts rmsr, r12
+ /* non-volatile registers */
+ lwi r30, r11, CC_R30
+ lwi r29, r11, CC_R29
+ lwi r28, r11, CC_R28
+ lwi r27, r11, CC_R27
+ lwi r26, r11, CC_R26
+ lwi r25, r11, CC_R25
+ lwi r24, r11, CC_R24
+ lwi r23, r11, CC_R23
+ lwi r22, r11, CC_R22
+ lwi r21, r11, CC_R21
+ lwi r20, r11, CC_R20
+ lwi r19, r11, CC_R19
+ /* dedicated registers */
+ lwi r18, r11, CC_R18
+ lwi r17, r11, CC_R17
+ lwi r16, r11, CC_R16
+ lwi r15, r11, CC_R15
+ lwi r14, r11, CC_R14
+ lwi r13, r11, CC_R13
+ /* skip volatile registers */
+ lwi r2, r11, CC_R2
+ lwi r1, r11, CC_R1
+
+ rtsd r15, 8
+ nop
+
+ENTRY(ret_from_fork)
+ addk r5, r0, r3
+ addk r6, r0, r1
+ brlid r15, schedule_tail
+ nop
+ swi r31, r1, PT_R31 /* save r31 in user context. */
+ /* will soon be restored to r31 in ret_to_user */
+ addk r3, r0, r0
+ brid ret_to_user
+ nop
+
+work_pending:
+ andi r11, r19, _TIF_NEED_RESCHED
+ beqi r11, 1f
+ bralid r15, schedule
+ nop
+1: andi r11, r19, _TIF_SIGPENDING
+ beqi r11, no_work_pending
+ addk r5, r1, r0
+ addik r7, r0, 1
+ bralid r15, do_signal
+ addk r6, r0, r0
+ bri no_work_pending
+
+ENTRY(ret_to_user)
+ disable_irq
+
+ swi r4, r1, PT_R4 /* return val */
+ swi r3, r1, PT_R3 /* return val */
+
+ lwi r6, r31, TS_THREAD_INFO /* get thread info */
+ lwi r19, r6, TI_FLAGS /* get flags in thread info */
+ bnei r19, work_pending /* do an extra work if any bits are set */
+no_work_pending:
+ disable_irq
+
+ /* save r31 */
+ swi r31, r0, PER_CPU(CURRENT_SAVE)
+ /* save mode indicator */
+ lwi r18, r1, PT_MODE
+ swi r18, r0, PER_CPU(KM)
+//restore_context:
+ /* special purpose registers */
+ lwi r18, r1, PT_FSR
+ mts rfsr, r18
+ lwi r18, r1, PT_ESR
+ mts resr, r18
+ lwi r18, r1, PT_EAR
+ mts rear, r18
+ lwi r18, r1, PT_MSR
+ mts rmsr, r18
+
+ lwi r31, r1, PT_R31
+ lwi r30, r1, PT_R30
+ lwi r29, r1, PT_R29
+ lwi r28, r1, PT_R28
+ lwi r27, r1, PT_R27
+ lwi r26, r1, PT_R26
+ lwi r25, r1, PT_R25
+ lwi r24, r1, PT_R24
+ lwi r23, r1, PT_R23
+ lwi r22, r1, PT_R22
+ lwi r21, r1, PT_R21
+ lwi r20, r1, PT_R20
+ lwi r19, r1, PT_R19
+ lwi r18, r1, PT_R18
+ lwi r17, r1, PT_R17
+ lwi r16, r1, PT_R16
+ lwi r15, r1, PT_R15
+ lwi r14, r1, PT_PC
+ lwi r13, r1, PT_R13
+ lwi r12, r1, PT_R12
+ lwi r11, r1, PT_R11
+ lwi r10, r1, PT_R10
+ lwi r9, r1, PT_R9
+ lwi r8, r1, PT_R8
+ lwi r7, r1, PT_R7
+ lwi r6, r1, PT_R6
+ lwi r5, r1, PT_R5
+ lwi r4, r1, PT_R4 /* return val */
+ lwi r3, r1, PT_R3 /* return val */
+ lwi r2, r1, PT_R2
+ lwi r1, r1, PT_R1
+
+ rtid r14, 0
+ nop
+
+sys_vfork_wrapper:
+ brid sys_vfork
+ addk r5, r1, r0
+
+sys_clone_wrapper:
+ brid sys_clone
+ addk r7, r1, r0
+
+sys_execve_wrapper:
+ brid sys_execve
+ addk r8, r1, r0
+
+sys_sigreturn_wrapper:
+ brid sys_sigreturn
+ addk r5, r1, r0
+
+sys_rt_sigreturn_wrapper:
+ brid sys_rt_sigreturn
+ addk r5, r1, r0
+
+sys_sigsuspend_wrapper:
+ brid sys_rt_sigsuspend
+ addk r6, r1, r0
+
+sys_rt_sigsuspend_wrapper:
+ brid sys_rt_sigsuspend
+ addk r7, r1, r0
+
+ /* Interrupt vector table */
+ .section .init.ivt, "ax"
+ .org 0x0
+ brai _reset
+ brai _user_exception
+ brai _interrupt
+ brai _break
+ brai _hw_exception_handler
+ .org 0x60
+ brai _debug_exception
+
+.section .rodata,"a"
+#include "syscall_table.S"
+
+syscall_table_size=(.-sys_call_table)
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
new file mode 100644
index 00000000000..4a8a4064c7e
--- /dev/null
+++ b/arch/microblaze/kernel/exceptions.c
@@ -0,0 +1,124 @@
+/*
+ * HW exception handling
+ *
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008 PetaLogix
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kallsyms.h>
+#include <linux/module.h>
+
+#include <asm/exceptions.h>
+#include <asm/entry.h> /* For KM CPU var */
+#include <asm/uaccess.h>
+#include <asm/errno.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+
+#define MICROBLAZE_ILL_OPCODE_EXCEPTION 0x02
+#define MICROBLAZE_IBUS_EXCEPTION 0x03
+#define MICROBLAZE_DBUS_EXCEPTION 0x04
+#define MICROBLAZE_DIV_ZERO_EXCEPTION 0x05
+#define MICROBLAZE_FPU_EXCEPTION 0x06
+#define MICROBLAZE_PRIVILEG_EXCEPTION 0x07
+
+static DEFINE_SPINLOCK(die_lock);
+
+void die(const char *str, struct pt_regs *fp, long err)
+{
+ console_verbose();
+ spin_lock_irq(&die_lock);
+ printk(KERN_WARNING "Oops: %s, sig: %ld\n", str, err);
+ show_regs(fp);
+ spin_unlock_irq(&die_lock);
+ /* do_exit() should take care of panic'ing from an interrupt
+ * context so we don't handle it here
+ */
+ do_exit(err);
+}
+
+void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
+{
+ siginfo_t info;
+
+ if (kernel_mode(regs)) {
+ debugger(regs);
+ die("Exception in kernel mode", regs, signr);
+ }
+ info.si_signo = signr;
+ info.si_errno = 0;
+ info.si_code = code;
+ info.si_addr = (void __user *) addr;
+ force_sig_info(signr, &info, current);
+}
+
+asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
+ int fsr, int addr)
+{
+#if 0
+ printk(KERN_WARNING "Exception %02x in %s mode, FSR=%08x PC=%08x ESR=%08x\n",
+ type, user_mode(regs) ? "user" : "kernel", fsr,
+ (unsigned int) regs->pc, (unsigned int) regs->esr);
+#endif
+
+ switch (type & 0x1F) {
+ case MICROBLAZE_ILL_OPCODE_EXCEPTION:
+ _exception(SIGILL, regs, ILL_ILLOPC, addr);
+ break;
+ case MICROBLAZE_IBUS_EXCEPTION:
+ if (user_mode(regs)) {
+ printk(KERN_WARNING "Instruction bus error exception in user mode.\n");
+ _exception(SIGBUS, regs, BUS_ADRERR, addr);
+ return;
+ }
+ printk(KERN_WARNING "Instruction bus error exception in kernel mode.\n");
+ die("bus exception", regs, SIGBUS);
+ break;
+ case MICROBLAZE_DBUS_EXCEPTION:
+ if (user_mode(regs)) {
+ printk(KERN_WARNING "Data bus error exception in user mode.\n");
+ _exception(SIGBUS, regs, BUS_ADRERR, addr);
+ return;
+ }
+ printk(KERN_WARNING "Data bus error exception in kernel mode.\n");
+ die("bus exception", regs, SIGBUS);
+ break;
+ case MICROBLAZE_DIV_ZERO_EXCEPTION:
+ printk(KERN_WARNING "Divide by zero exception\n");
+ _exception(SIGILL, regs, ILL_ILLOPC, addr);
+ break;
+
+ case MICROBLAZE_FPU_EXCEPTION:
+ /* IEEE FP exception */
+ /* I removed fsr variable and use code var for storing fsr */
+ if (fsr & FSR_IO)
+ fsr = FPE_FLTINV;
+ else if (fsr & FSR_OF)
+ fsr = FPE_FLTOVF;
+ else if (fsr & FSR_UF)
+ fsr = FPE_FLTUND;
+ else if (fsr & FSR_DZ)
+ fsr = FPE_FLTDIV;
+ else if (fsr & FSR_DO)
+ fsr = FPE_FLTRES;
+ _exception(SIGFPE, regs, fsr, addr);
+ break;
+
+ default:
+ printk(KERN_WARNING "Unexpected exception %02x "
+ "PC=%08x in %s mode\n", type, (unsigned int) addr,
+ kernel_mode(regs) ? "kernel" : "user");
+ }
+ return;
+}
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S
new file mode 100644
index 00000000000..319dc35fc92
--- /dev/null
+++ b/arch/microblaze/kernel/head.S
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/page.h>
+
+ .text
+ENTRY(_start)
+ mfs r1, rmsr
+ andi r1, r1, ~2
+ mts rmsr, r1
+
+/* save fdt to kernel location */
+/* r7 stores pointer to fdt blob */
+ beqi r7, no_fdt_arg
+ or r11, r0, r0 /* incremment */
+ ori r4, r0, TOPHYS(_fdt_start) /* save bram context */
+ ori r3, r0, (0x4000 - 4)
+_copy_fdt:
+ lw r12, r7, r11 /* r12 = r7 + r11 */
+ sw r12, r4, r11 /* addr[r4 + r11] = r12 */
+ addik r11, r11, 4 /* increment counting */
+ bgtid r3, _copy_fdt /* loop for all entries */
+ addik r3, r3, -4 /* descrement loop */
+no_fdt_arg:
+
+ /* Initialize small data anchors */
+ la r13, r0, _KERNEL_SDA_BASE_
+ la r2, r0, _KERNEL_SDA2_BASE_
+
+ /* Initialize stack pointer */
+ la r1, r0, init_thread_union + THREAD_SIZE - 4
+
+ /* Initialize r31 with current task address */
+ la r31, r0, init_task
+
+ /*
+ * Call platform dependent initialize function.
+ * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for
+ * the function.
+ */
+ la r8, r0, machine_early_init
+ brald r15, r8
+ nop
+
+ la r15, r0, machine_halt
+ braid start_kernel
+ nop
diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c
new file mode 100644
index 00000000000..1bdf20222b9
--- /dev/null
+++ b/arch/microblaze/kernel/heartbeat.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/io.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/prom.h>
+
+static unsigned int base_addr;
+
+void heartbeat(void)
+{
+ static unsigned int cnt, period, dist;
+
+ if (base_addr) {
+ if (cnt == 0 || cnt == dist)
+ out_be32(base_addr, 1);
+ else if (cnt == 7 || cnt == dist + 7)
+ out_be32(base_addr, 0);
+
+ if (++cnt > period) {
+ cnt = 0;
+ /*
+ * The hyperbolic function below modifies the heartbeat
+ * period length in dependency of the current (5min)
+ * load. It goes through the points f(0)=126, f(1)=86,
+ * f(5)=51, f(inf)->30.
+ */
+ period = ((672 << FSHIFT) / (5 * avenrun[0] +
+ (7 << FSHIFT))) + 30;
+ dist = period / 4;
+ }
+ }
+}
+
+void setup_heartbeat(void)
+{
+ struct device_node *gpio = NULL;
+ int j;
+ char *gpio_list[] = {
+ "xlnx,xps-gpio-1.00.a",
+ "xlnx,opb-gpio-1.00.a",
+ NULL
+ };
+
+ for (j = 0; gpio_list[j] != NULL; j++) {
+ gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]);
+ if (gpio)
+ break;
+ }
+
+ base_addr = *(int *) of_get_property(gpio, "reg", NULL);
+ base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
+ printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
+
+ if (*(int *) of_get_property(gpio, "xlnx,is-bidir", NULL))
+ out_be32(base_addr + 4, 0); /* GPIO is configured as output */
+}
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
new file mode 100644
index 00000000000..cf9486d9983
--- /dev/null
+++ b/arch/microblaze/kernel/hw_exception_handler.S
@@ -0,0 +1,458 @@
+/*
+ * Exception handling for Microblaze
+ *
+ * Rewriten interrupt handling
+ *
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ *
+ * uClinux customisation (C) 2005 John Williams
+ *
+ * MMU code derived from arch/ppc/kernel/head_4xx.S:
+ * Copyright (C) 1995-1996 Gary Thomas <gdt@linuxppc.org>
+ * Initial PowerPC version.
+ * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Rewritten for PReP
+ * Copyright (C) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Low-level exception handers, MMU support, and rewrite.
+ * Copyright (C) 1997 Dan Malek <dmalek@jlc.net>
+ * PowerPC 8xx modifications.
+ * Copyright (C) 1998-1999 TiVo, Inc.
+ * PowerPC 403GCX modifications.
+ * Copyright (C) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * PowerPC 403GCX/405GP modifications.
+ * Copyright 2000 MontaVista Software Inc.
+ * PPC405 modifications
+ * PowerPC 403GCX/405GP modifications.
+ * Author: MontaVista Software, Inc.
+ * frank_rowand@mvista.com or source@mvista.com
+ * debbie_chu@mvista.com
+ *
+ * Original code
+ * Copyright (C) 2004 Xilinx, 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.
+ */
+
+/*
+ * Here are the handlers which don't require enabling translation
+ * and calling other kernel code thus we can keep their design very simple
+ * and do all processing in real mode. All what they need is a valid current
+ * (that is an issue for the CONFIG_REGISTER_TASK_PTR case)
+ * This handlers use r3,r4,r5,r6 and optionally r[current] to work therefore
+ * these registers are saved/restored
+ * The handlers which require translation are in entry.S --KAA
+ *
+ * Microblaze HW Exception Handler
+ * - Non self-modifying exception handler for the following exception conditions
+ * - Unalignment
+ * - Instruction bus error
+ * - Data bus error
+ * - Illegal instruction opcode
+ * - Divide-by-zero
+ *
+ * Note we disable interrupts during exception handling, otherwise we will
+ * possibly get multiple re-entrancy if interrupt handles themselves cause
+ * exceptions. JW
+ */
+
+#include <asm/exceptions.h>
+#include <asm/unistd.h>
+#include <asm/page.h>
+
+#include <asm/entry.h>
+#include <asm/current.h>
+#include <linux/linkage.h>
+
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/asm-offsets.h>
+
+/* Helpful Macros */
+#define EX_HANDLER_STACK_SIZ (4*19)
+#define NUM_TO_REG(num) r ## num
+
+#define LWREG_NOP \
+ bri ex_handler_unhandled; \
+ nop;
+
+#define SWREG_NOP \
+ bri ex_handler_unhandled; \
+ nop;
+
+/* FIXME this is weird - for noMMU kernel is not possible to use brid
+ * instruction which can shorten executed time
+ */
+
+/* r3 is the source */
+#define R3_TO_LWREG_V(regnum) \
+ swi r3, r1, 4 * regnum; \
+ bri ex_handler_done;
+
+/* r3 is the source */
+#define R3_TO_LWREG(regnum) \
+ or NUM_TO_REG (regnum), r0, r3; \
+ bri ex_handler_done;
+
+/* r3 is the target */
+#define SWREG_TO_R3_V(regnum) \
+ lwi r3, r1, 4 * regnum; \
+ bri ex_sw_tail;
+
+/* r3 is the target */
+#define SWREG_TO_R3(regnum) \
+ or r3, r0, NUM_TO_REG (regnum); \
+ bri ex_sw_tail;
+
+.extern other_exception_handler /* Defined in exception.c */
+
+/*
+ * hw_exception_handler - Handler for exceptions
+ *
+ * Exception handler notes:
+ * - Handles all exceptions
+ * - Does not handle unaligned exceptions during load into r17, r1, r0.
+ * - Does not handle unaligned exceptions during store from r17 (cannot be
+ * done) and r1 (slows down common case)
+ *
+ * Relevant register structures
+ *
+ * EAR - |----|----|----|----|----|----|----|----|
+ * - < ## 32 bit faulting address ## >
+ *
+ * ESR - |----|----|----|----|----| - | - |-----|-----|
+ * - W S REG EXC
+ *
+ *
+ * STACK FRAME STRUCTURE (for NO_MMU)
+ * ---------------------------------
+ *
+ * +-------------+ + 0
+ * | MSR |
+ * +-------------+ + 4
+ * | r1 |
+ * | . |
+ * | . |
+ * | . |
+ * | . |
+ * | r18 |
+ * +-------------+ + 76
+ * | . |
+ * | . |
+ *
+ * NO_MMU kernel use the same r0_ram pointed space - look to vmlinux.lds.S
+ * which is used for storing register values - old style was, that value were
+ * stored in stack but in case of failure you lost information about register.
+ * Currently you can see register value in memory in specific place.
+ * In compare to with previous solution the speed should be the same.
+ *
+ * MMU exception handler has different handling compare to no MMU kernel.
+ * Exception handler use jump table for directing of what happen. For MMU kernel
+ * is this approach better because MMU relate exception are handled by asm code
+ * in this file. In compare to with MMU expect of unaligned exception
+ * is everything handled by C code.
+ */
+
+/*
+ * every of these handlers is entered having R3/4/5/6/11/current saved on stack
+ * and clobbered so care should be taken to restore them if someone is going to
+ * return from exception
+ */
+
+/* wrappers to restore state before coming to entry.S */
+
+.global _hw_exception_handler
+.section .text
+.align 4
+.ent _hw_exception_handler
+_hw_exception_handler:
+ addik r1, r1, -(EX_HANDLER_STACK_SIZ); /* Create stack frame */
+ swi r3, r1, PT_R3
+ swi r4, r1, PT_R4
+ swi r5, r1, PT_R5
+ swi r6, r1, PT_R6
+
+ mfs r5, rmsr;
+ nop
+ swi r5, r1, 0;
+ mfs r4, rbtr /* Save BTR before jumping to handler */
+ nop
+ mfs r3, resr
+ nop
+
+ andi r5, r3, 0x1000; /* Check ESR[DS] */
+ beqi r5, not_in_delay_slot; /* Branch if ESR[DS] not set */
+ mfs r17, rbtr; /* ESR[DS] set - return address in BTR */
+ nop
+not_in_delay_slot:
+ swi r17, r1, PT_R17
+
+ andi r5, r3, 0x1F; /* Extract ESR[EXC] */
+
+ /* Exceptions enabled here. This will allow nested exceptions */
+ mfs r6, rmsr;
+ nop
+ swi r6, r1, 0; /* RMSR_OFFSET */
+ ori r6, r6, 0x100; /* Turn ON the EE bit */
+ andi r6, r6, ~2; /* Disable interrupts */
+ mts rmsr, r6;
+ nop
+
+ xori r6, r5, 1; /* 00001 = Unaligned Exception */
+ /* Jump to unalignment exception handler */
+ beqi r6, handle_unaligned_ex;
+
+handle_other_ex: /* Handle Other exceptions here */
+ /* Save other volatiles before we make procedure calls below */
+ swi r7, r1, PT_R7
+ swi r8, r1, PT_R8
+ swi r9, r1, PT_R9
+ swi r10, r1, PT_R10
+ swi r11, r1, PT_R11
+ swi r12, r1, PT_R12
+ swi r14, r1, PT_R14
+ swi r15, r1, PT_R15
+ swi r18, r1, PT_R18
+
+ or r5, r1, r0
+ andi r6, r3, 0x1F; /* Load ESR[EC] */
+ lwi r7, r0, PER_CPU(KM) /* MS: saving current kernel mode to regs */
+ swi r7, r1, PT_MODE
+ mfs r7, rfsr
+ nop
+ addk r8, r17, r0; /* Load exception address */
+ bralid r15, full_exception; /* Branch to the handler */
+ nop;
+
+ /*
+ * Trigger execution of the signal handler by enabling
+ * interrupts and calling an invalid syscall.
+ */
+ mfs r5, rmsr;
+ nop
+ ori r5, r5, 2;
+ mts rmsr, r5; /* enable interrupt */
+ nop
+ addi r12, r0, __NR_syscalls;
+ brki r14, 0x08;
+ mfs r5, rmsr; /* disable interrupt */
+ nop
+ andi r5, r5, ~2;
+ mts rmsr, r5;
+ nop
+
+ lwi r7, r1, PT_R7
+ lwi r8, r1, PT_R8
+ lwi r9, r1, PT_R9
+ lwi r10, r1, PT_R10
+ lwi r11, r1, PT_R11
+ lwi r12, r1, PT_R12
+ lwi r14, r1, PT_R14
+ lwi r15, r1, PT_R15
+ lwi r18, r1, PT_R18
+
+ bri ex_handler_done; /* Complete exception handling */
+
+/* 0x01 - Unaligned data access exception
+ * This occurs when a word access is not aligned on a word boundary,
+ * or when a 16-bit access is not aligned on a 16-bit boundary.
+ * This handler perform the access, and returns, except for MMU when
+ * the unaligned address is last on a 4k page or the physical address is
+ * not found in the page table, in which case unaligned_data_trap is called.
+ */
+handle_unaligned_ex:
+ /* Working registers already saved: R3, R4, R5, R6
+ * R3 = ESR
+ * R4 = BTR
+ */
+ mfs r4, rear;
+ nop
+
+ andi r6, r3, 0x3E0; /* Mask and extract the register operand */
+ srl r6, r6; /* r6 >> 5 */
+ srl r6, r6;
+ srl r6, r6;
+ srl r6, r6;
+ srl r6, r6;
+ /* Store the register operand in a temporary location */
+ sbi r6, r0, TOPHYS(ex_reg_op);
+
+ andi r6, r3, 0x400; /* Extract ESR[S] */
+ bnei r6, ex_sw;
+ex_lw:
+ andi r6, r3, 0x800; /* Extract ESR[W] */
+ beqi r6, ex_lhw;
+ lbui r5, r4, 0; /* Exception address in r4 */
+ /* Load a word, byte-by-byte from destination address
+ and save it in tmp space */
+ sbi r5, r0, TOPHYS(ex_tmp_data_loc_0);
+ lbui r5, r4, 1;
+ sbi r5, r0, TOPHYS(ex_tmp_data_loc_1);
+ lbui r5, r4, 2;
+ sbi r5, r0, TOPHYS(ex_tmp_data_loc_2);
+ lbui r5, r4, 3;
+ sbi r5, r0, TOPHYS(ex_tmp_data_loc_3);
+ /* Get the destination register value into r3 */
+ lwi r3, r0, TOPHYS(ex_tmp_data_loc_0);
+ bri ex_lw_tail;
+ex_lhw:
+ lbui r5, r4, 0; /* Exception address in r4 */
+ /* Load a half-word, byte-by-byte from destination
+ address and save it in tmp space */
+ sbi r5, r0, TOPHYS(ex_tmp_data_loc_0);
+ lbui r5, r4, 1;
+ sbi r5, r0, TOPHYS(ex_tmp_data_loc_1);
+ /* Get the destination register value into r3 */
+ lhui r3, r0, TOPHYS(ex_tmp_data_loc_0);
+ex_lw_tail:
+ /* Get the destination register number into r5 */
+ lbui r5, r0, TOPHYS(ex_reg_op);
+ /* Form load_word jump table offset (lw_table + (8 * regnum)) */
+ la r6, r0, TOPHYS(lw_table);
+ addk r5, r5, r5;
+ addk r5, r5, r5;
+ addk r5, r5, r5;
+ addk r5, r5, r6;
+ bra r5;
+ex_lw_end: /* Exception handling of load word, ends */
+ex_sw:
+ /* Get the destination register number into r5 */
+ lbui r5, r0, TOPHYS(ex_reg_op);
+ /* Form store_word jump table offset (sw_table + (8 * regnum)) */
+ la r6, r0, TOPHYS(sw_table);
+ add r5, r5, r5;
+ add r5, r5, r5;
+ add r5, r5, r5;
+ add r5, r5, r6;
+ bra r5;
+ex_sw_tail:
+ mfs r6, resr;
+ nop
+ andi r6, r6, 0x800; /* Extract ESR[W] */
+ beqi r6, ex_shw;
+ /* Get the word - delay slot */
+ swi r3, r0, TOPHYS(ex_tmp_data_loc_0);
+ /* Store the word, byte-by-byte into destination address */
+ lbui r3, r0, TOPHYS(ex_tmp_data_loc_0);
+ sbi r3, r4, 0;
+ lbui r3, r0, TOPHYS(ex_tmp_data_loc_1);
+ sbi r3, r4, 1;
+ lbui r3, r0, TOPHYS(ex_tmp_data_loc_2);
+ sbi r3, r4, 2;
+ lbui r3, r0, TOPHYS(ex_tmp_data_loc_3);
+ sbi r3, r4, 3;
+ bri ex_handler_done;
+
+ex_shw:
+ /* Store the lower half-word, byte-by-byte into destination address */
+ swi r3, r0, TOPHYS(ex_tmp_data_loc_0);
+ lbui r3, r0, TOPHYS(ex_tmp_data_loc_2);
+ sbi r3, r4, 0;
+ lbui r3, r0, TOPHYS(ex_tmp_data_loc_3);
+ sbi r3, r4, 1;
+ex_sw_end: /* Exception handling of store word, ends. */
+
+ex_handler_done:
+ lwi r5, r1, 0 /* RMSR */
+ mts rmsr, r5
+ nop
+ lwi r3, r1, PT_R3
+ lwi r4, r1, PT_R4
+ lwi r5, r1, PT_R5
+ lwi r6, r1, PT_R6
+ lwi r17, r1, PT_R17
+
+ rted r17, 0
+ addik r1, r1, (EX_HANDLER_STACK_SIZ); /* Restore stack frame */
+
+.end _hw_exception_handler
+
+ex_handler_unhandled:
+/* FIXME add handle function for unhandled exception - dump register */
+ bri 0
+
+.section .text
+.align 4
+lw_table:
+lw_r0: R3_TO_LWREG (0);
+lw_r1: LWREG_NOP;
+lw_r2: R3_TO_LWREG (2);
+lw_r3: R3_TO_LWREG_V (3);
+lw_r4: R3_TO_LWREG_V (4);
+lw_r5: R3_TO_LWREG_V (5);
+lw_r6: R3_TO_LWREG_V (6);
+lw_r7: R3_TO_LWREG (7);
+lw_r8: R3_TO_LWREG (8);
+lw_r9: R3_TO_LWREG (9);
+lw_r10: R3_TO_LWREG (10);
+lw_r11: R3_TO_LWREG (11);
+lw_r12: R3_TO_LWREG (12);
+lw_r13: R3_TO_LWREG (13);
+lw_r14: R3_TO_LWREG (14);
+lw_r15: R3_TO_LWREG (15);
+lw_r16: R3_TO_LWREG (16);
+lw_r17: LWREG_NOP;
+lw_r18: R3_TO_LWREG (18);
+lw_r19: R3_TO_LWREG (19);
+lw_r20: R3_TO_LWREG (20);
+lw_r21: R3_TO_LWREG (21);
+lw_r22: R3_TO_LWREG (22);
+lw_r23: R3_TO_LWREG (23);
+lw_r24: R3_TO_LWREG (24);
+lw_r25: R3_TO_LWREG (25);
+lw_r26: R3_TO_LWREG (26);
+lw_r27: R3_TO_LWREG (27);
+lw_r28: R3_TO_LWREG (28);
+lw_r29: R3_TO_LWREG (29);
+lw_r30: R3_TO_LWREG (30);
+lw_r31: R3_TO_LWREG (31);
+
+sw_table:
+sw_r0: SWREG_TO_R3 (0);
+sw_r1: SWREG_NOP;
+sw_r2: SWREG_TO_R3 (2);
+sw_r3: SWREG_TO_R3_V (3);
+sw_r4: SWREG_TO_R3_V (4);
+sw_r5: SWREG_TO_R3_V (5);
+sw_r6: SWREG_TO_R3_V (6);
+sw_r7: SWREG_TO_R3 (7);
+sw_r8: SWREG_TO_R3 (8);
+sw_r9: SWREG_TO_R3 (9);
+sw_r10: SWREG_TO_R3 (10);
+sw_r11: SWREG_TO_R3 (11);
+sw_r12: SWREG_TO_R3 (12);
+sw_r13: SWREG_TO_R3 (13);
+sw_r14: SWREG_TO_R3 (14);
+sw_r15: SWREG_TO_R3 (15);
+sw_r16: SWREG_TO_R3 (16);
+sw_r17: SWREG_NOP;
+sw_r18: SWREG_TO_R3 (18);
+sw_r19: SWREG_TO_R3 (19);
+sw_r20: SWREG_TO_R3 (20);
+sw_r21: SWREG_TO_R3 (21);
+sw_r22: SWREG_TO_R3 (22);
+sw_r23: SWREG_TO_R3 (23);
+sw_r24: SWREG_TO_R3 (24);
+sw_r25: SWREG_TO_R3 (25);
+sw_r26: SWREG_TO_R3 (26);
+sw_r27: SWREG_TO_R3 (27);
+sw_r28: SWREG_TO_R3 (28);
+sw_r29: SWREG_TO_R3 (29);
+sw_r30: SWREG_TO_R3 (30);
+sw_r31: SWREG_TO_R3 (31);
+
+/* Temporary data structures used in the handler */
+.section .data
+.align 4
+ex_tmp_data_loc_0:
+ .byte 0
+ex_tmp_data_loc_1:
+ .byte 0
+ex_tmp_data_loc_2:
+ .byte 0
+ex_tmp_data_loc_3:
+ .byte 0
+ex_reg_op:
+ .byte 0
diff --git a/arch/microblaze/kernel/init_task.c b/arch/microblaze/kernel/init_task.c
new file mode 100644
index 00000000000..48eb9fb255f
--- /dev/null
+++ b/arch/microblaze/kernel/init_task.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init_task.h>
+#include <linux/fs.h>
+#include <linux/mqueue.h>
+
+#include <asm/pgtable.h>
+
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+struct mm_struct init_mm = INIT_MM(init_mm);
+EXPORT_SYMBOL(init_mm);
+
+union thread_union init_thread_union
+ __attribute__((__section__(".data.init_task"))) =
+{ INIT_THREAD_INFO(init_task) };
+
+struct task_struct init_task = INIT_TASK(init_task);
+EXPORT_SYMBOL(init_task);
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
new file mode 100644
index 00000000000..a69d3e3c2fd
--- /dev/null
+++ b/arch/microblaze/kernel/intc.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/page.h>
+#include <linux/io.h>
+
+#include <asm/prom.h>
+#include <asm/irq.h>
+
+#ifdef CONFIG_SELFMOD_INTC
+#include <asm/selfmod.h>
+#define INTC_BASE BARRIER_BASE_ADDR
+#else
+static unsigned int intc_baseaddr;
+#define INTC_BASE intc_baseaddr
+#endif
+
+unsigned int nr_irq;
+
+/* No one else should require these constants, so define them locally here. */
+#define ISR 0x00 /* Interrupt Status Register */
+#define IPR 0x04 /* Interrupt Pending Register */
+#define IER 0x08 /* Interrupt Enable Register */
+#define IAR 0x0c /* Interrupt Acknowledge Register */
+#define SIE 0x10 /* Set Interrupt Enable bits */
+#define CIE 0x14 /* Clear Interrupt Enable bits */
+#define IVR 0x18 /* Interrupt Vector Register */
+#define MER 0x1c /* Master Enable Register */
+
+#define MER_ME (1<<0)
+#define MER_HIE (1<<1)
+
+static void intc_enable_or_unmask(unsigned int irq)
+{
+ pr_debug("enable_or_unmask: %d\n", irq);
+ out_be32(INTC_BASE + SIE, 1 << irq);
+}
+
+static void intc_disable_or_mask(unsigned int irq)
+{
+ pr_debug("disable: %d\n", irq);
+ out_be32(INTC_BASE + CIE, 1 << irq);
+}
+
+static void intc_ack(unsigned int irq)
+{
+ pr_debug("ack: %d\n", irq);
+ out_be32(INTC_BASE + IAR, 1 << irq);
+}
+
+static void intc_mask_ack(unsigned int irq)
+{
+ unsigned long mask = 1 << irq;
+ pr_debug("disable_and_ack: %d\n", irq);
+ out_be32(INTC_BASE + CIE, mask);
+ out_be32(INTC_BASE + IAR, mask);
+}
+
+static void intc_end(unsigned int irq)
+{
+ unsigned long mask = 1 << irq;
+ pr_debug("end: %d\n", irq);
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ out_be32(INTC_BASE + SIE, mask);
+ /* ack level sensitive intr */
+ if (irq_desc[irq].status & IRQ_LEVEL)
+ out_be32(INTC_BASE + IAR, mask);
+ }
+}
+
+static struct irq_chip intc_dev = {
+ .name = "Xilinx INTC",
+ .unmask = intc_enable_or_unmask,
+ .mask = intc_disable_or_mask,
+ .ack = intc_ack,
+ .mask_ack = intc_mask_ack,
+ .end = intc_end,
+};
+
+unsigned int get_irq(struct pt_regs *regs)
+{
+ int irq;
+
+ /*
+ * NOTE: This function is the one that needs to be improved in
+ * order to handle multiple interrupt controllers. It currently
+ * is hardcoded to check for interrupts only on the first INTC.
+ */
+ irq = in_be32(INTC_BASE + IVR);
+ pr_debug("get_irq: %d\n", irq);
+
+ return irq;
+}
+
+void __init init_IRQ(void)
+{
+ u32 i, j, intr_type;
+ struct device_node *intc = NULL;
+#ifdef CONFIG_SELFMOD_INTC
+ unsigned int intc_baseaddr = 0;
+ static int arr_func[] = {
+ (int)&get_irq,
+ (int)&intc_enable_or_unmask,
+ (int)&intc_disable_or_mask,
+ (int)&intc_mask_ack,
+ (int)&intc_ack,
+ (int)&intc_end,
+ 0
+ };
+#endif
+ static char *intc_list[] = {
+ "xlnx,xps-intc-1.00.a",
+ "xlnx,opb-intc-1.00.c",
+ "xlnx,opb-intc-1.00.b",
+ "xlnx,opb-intc-1.00.a",
+ NULL
+ };
+
+ for (j = 0; intc_list[j] != NULL; j++) {
+ intc = of_find_compatible_node(NULL, NULL, intc_list[j]);
+ if (intc)
+ break;
+ }
+
+ intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL);
+ intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
+ nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL);
+
+ intr_type =
+ *(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL);
+ if (intr_type >= (1 << nr_irq))
+ printk(KERN_INFO " ERROR: Mishmash in king-of-intr param\n");
+
+#ifdef CONFIG_SELFMOD_INTC
+ selfmod_function((int *) arr_func, intc_baseaddr);
+#endif
+ printk(KERN_INFO "%s #0 at 0x%08x, num_irq=%d, edge=0x%x\n",
+ intc_list[j], intc_baseaddr, nr_irq, intr_type);
+
+ /*
+ * Disable all external interrupts until they are
+ * explicity requested.
+ */
+ out_be32(intc_baseaddr + IER, 0);
+
+ /* Acknowledge any pending interrupts just in case. */
+ out_be32(intc_baseaddr + IAR, 0xffffffff);
+
+ /* Turn on the Master Enable. */
+ out_be32(intc_baseaddr + MER, MER_HIE | MER_ME);
+
+ for (i = 0; i < nr_irq; ++i) {
+ if (intr_type & (0x00000001 << i)) {
+ set_irq_chip_and_handler_name(i, &intc_dev,
+ handle_edge_irq, intc_dev.name);
+ irq_desc[i].status &= ~IRQ_LEVEL;
+ } else {
+ set_irq_chip_and_handler_name(i, &intc_dev,
+ handle_level_irq, intc_dev.name);
+ irq_desc[i].status |= IRQ_LEVEL;
+ }
+ }
+}
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
new file mode 100644
index 00000000000..f688ee93e3b
--- /dev/null
+++ b/arch/microblaze/kernel/irq.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/hardirq.h>
+#include <linux/interrupt.h>
+#include <linux/irqflags.h>
+#include <linux/seq_file.h>
+#include <linux/kernel_stat.h>
+#include <linux/irq.h>
+
+#include <asm/prom.h>
+
+unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
+{
+ struct of_irq oirq;
+
+ if (of_irq_map_one(dev, index, &oirq))
+ return NO_IRQ;
+
+ return oirq.specifier[0];
+}
+EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
+
+/*
+ * '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);
+}
+
+static u32 concurrent_irq;
+
+void do_IRQ(struct pt_regs *regs)
+{
+ unsigned int irq;
+ struct pt_regs *old_regs = set_irq_regs(regs);
+
+ irq_enter();
+ irq = get_irq(regs);
+next_irq:
+ BUG_ON(irq == -1U);
+ generic_handle_irq(irq);
+
+ irq = get_irq(regs);
+ if (irq != -1U) {
+ pr_debug("next irq: %d\n", irq);
+ ++concurrent_irq;
+ goto next_irq;
+ }
+
+ irq_exit();
+ set_irq_regs(old_regs);
+}
+
+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_irq) {
+ spin_lock_irqsave(&irq_desc[i].lock, flags);
+ action = irq_desc[i].action;
+ if (!action)
+ 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].status &
+ IRQ_LEVEL ? "level" : "edge");
+ seq_printf(p, " %8s", irq_desc[i].chip->name);
+ seq_printf(p, " %s", action->name);
+
+ for (action = action->next; action; action = action->next)
+ seq_printf(p, ", %s", action->name);
+
+ seq_putc(p, '\n');
+skip:
+ spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ }
+ return 0;
+}
diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c
new file mode 100644
index 00000000000..5f71790e3c3
--- /dev/null
+++ b/arch/microblaze/kernel/microblaze_ksyms.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/cryptohash.h>
+#include <linux/delay.h>
+#include <linux/in6.h>
+#include <linux/syscalls.h>
+
+#include <asm/checksum.h>
+#include <linux/io.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <linux/uaccess.h>
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler... (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __ashldi3(void);
+EXPORT_SYMBOL(__ashldi3);
+extern void __ashrdi3(void);
+EXPORT_SYMBOL(__ashrdi3);
+extern void __divsi3(void);
+EXPORT_SYMBOL(__divsi3);
+extern void __lshrdi3(void);
+EXPORT_SYMBOL(__lshrdi3);
+extern void __modsi3(void);
+EXPORT_SYMBOL(__modsi3);
+extern void __mulsi3(void);
+EXPORT_SYMBOL(__mulsi3);
+extern void __muldi3(void);
+EXPORT_SYMBOL(__muldi3);
+extern void __ucmpdi2(void);
+EXPORT_SYMBOL(__ucmpdi2);
+extern void __udivsi3(void);
+EXPORT_SYMBOL(__udivsi3);
+extern void __umodsi3(void);
+EXPORT_SYMBOL(__umodsi3);
diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c
new file mode 100644
index 00000000000..51414171326
--- /dev/null
+++ b/arch/microblaze/kernel/module.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleloader.h>
+#include <linux/kernel.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+
+#include <asm/pgtable.h>
+
+void *module_alloc(unsigned long size)
+{
+ void *ret;
+ ret = (size == 0) ? NULL : vmalloc(size);
+ pr_debug("module_alloc (%08lx@%08lx)\n", size, (unsigned long int)ret);
+ return ret;
+}
+
+void module_free(struct module *module, void *region)
+{
+ pr_debug("module_free(%s,%08lx)\n", module->name,
+ (unsigned long)region);
+ vfree(region);
+}
+
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+ Elf_Shdr *sechdrs,
+ char *secstrings,
+ struct module *mod)
+{
+ return 0;
+}
+
+int apply_relocate(Elf32_Shdr *sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec, struct module *module)
+{
+ printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
+ module->name);
+ return -ENOEXEC;
+}
+
+int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec, struct module *module)
+{
+
+ unsigned int i;
+ Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
+ Elf32_Sym *sym;
+ unsigned long int *location;
+ unsigned long int locoffs;
+ unsigned long int value;
+#if __GNUC__ < 4
+ unsigned long int old_value;
+#endif
+
+ pr_debug("Applying add relocation section %u to %u\n",
+ relsec, sechdrs[relsec].sh_info);
+
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
+
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr +
+ rela[i].r_offset;
+ sym = (Elf32_Sym *)sechdrs[symindex].sh_addr +
+ ELF32_R_SYM(rela[i].r_info);
+ value = sym->st_value + rela[i].r_addend;
+
+ switch (ELF32_R_TYPE(rela[i].r_info)) {
+
+ /*
+ * Be careful! mb-gcc / mb-ld splits the relocs between the
+ * text and the reloc table. In general this means we must
+ * read the current contents of (*location), add any offset
+ * then store the result back in
+ */
+
+ case R_MICROBLAZE_32:
+#if __GNUC__ < 4
+ old_value = *location;
+ *location = value + old_value;
+
+ pr_debug("R_MICROBLAZE_32 (%08lx->%08lx)\n",
+ old_value, value);
+#else
+ *location = value;
+#endif
+ break;
+
+ case R_MICROBLAZE_64:
+#if __GNUC__ < 4
+ /* Split relocs only required/used pre gcc4.1.1 */
+ old_value = ((location[0] & 0x0000FFFF) << 16) |
+ (location[1] & 0x0000FFFF);
+ value += old_value;
+#endif
+ location[0] = (location[0] & 0xFFFF0000) |
+ (value >> 16);
+ location[1] = (location[1] & 0xFFFF0000) |
+ (value & 0xFFFF);
+#if __GNUC__ < 4
+ pr_debug("R_MICROBLAZE_64 (%08lx->%08lx)\n",
+ old_value, value);
+#endif
+ break;
+
+ case R_MICROBLAZE_64_PCREL:
+ locoffs = (location[0] & 0xFFFF) << 16 |
+ (location[1] & 0xFFFF);
+ value -= (unsigned long int)(location) + 4 +
+ locoffs;
+ location[0] = (location[0] & 0xFFFF0000) |
+ (value >> 16);
+ location[1] = (location[1] & 0xFFFF0000) |
+ (value & 0xFFFF);
+ pr_debug("R_MICROBLAZE_64_PCREL (%08lx)\n",
+ value);
+ break;
+
+ case R_MICROBLAZE_NONE:
+ pr_debug("R_MICROBLAZE_NONE\n");
+ break;
+
+ default:
+ printk(KERN_ERR "module %s: "
+ "Unknown relocation: %u\n",
+ module->name,
+ ELF32_R_TYPE(rela->r_info));
+ return -ENOEXEC;
+ }
+ }
+ return 0;
+}
+
+int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
+ struct module *module)
+{
+ return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+}
diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c
new file mode 100644
index 00000000000..9a0f7632c47
--- /dev/null
+++ b/arch/microblaze/kernel/of_device.c
@@ -0,0 +1,113 @@
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+
+#include <linux/errno.h>
+
+void of_device_make_bus_id(struct of_device *dev)
+{
+ static atomic_t bus_no_reg_magic;
+ struct device_node *node = dev->node;
+ const u32 *reg;
+ u64 addr;
+ int magic;
+
+ /*
+ * For MMIO, get the physical address
+ */
+ reg = of_get_property(node, "reg", NULL);
+ if (reg) {
+ addr = of_translate_address(node, reg);
+ if (addr != OF_BAD_ADDR) {
+ dev_set_name(&dev->dev, "%llx.%s",
+ (unsigned long long)addr, node->name);
+ return;
+ }
+ }
+
+ /*
+ * No BusID, use the node name and add a globally incremented
+ * counter (and pray...)
+ */
+ magic = atomic_add_return(1, &bus_no_reg_magic);
+ dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1);
+}
+EXPORT_SYMBOL(of_device_make_bus_id);
+
+struct of_device *of_device_alloc(struct device_node *np,
+ const char *bus_id,
+ struct device *parent)
+{
+ struct of_device *dev;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ dev->node = of_node_get(np);
+ dev->dev.dma_mask = &dev->dma_mask;
+ dev->dev.parent = parent;
+ dev->dev.release = of_release_dev;
+ dev->dev.archdata.of_node = np;
+
+ if (bus_id)
+ dev_set_name(&dev->dev, bus_id);
+ else
+ of_device_make_bus_id(dev);
+
+ return dev;
+}
+EXPORT_SYMBOL(of_device_alloc);
+
+int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct of_device *ofdev;
+ const char *compat;
+ int seen = 0, cplen, sl;
+
+ if (!dev)
+ return -ENODEV;
+
+ ofdev = to_of_device(dev);
+
+ if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name))
+ return -ENOMEM;
+
+ if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type))
+ return -ENOMEM;
+
+ /* Since the compatible field can contain pretty much anything
+ * it's not really legal to split it out with commas. We split it
+ * up using a number of environment variables instead. */
+
+ compat = of_get_property(ofdev->node, "compatible", &cplen);
+ while (compat && *compat && cplen > 0) {
+ if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
+ return -ENOMEM;
+
+ sl = strlen(compat) + 1;
+ compat += sl;
+ cplen -= sl;
+ seen++;
+ }
+
+ if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
+ return -ENOMEM;
+
+ /* modalias is trickier, we add it in 2 steps */
+ if (add_uevent_var(env, "MODALIAS="))
+ return -ENOMEM;
+ sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
+ sizeof(env->buf) - env->buflen);
+ if (sl >= (sizeof(env->buf) - env->buflen))
+ return -ENOMEM;
+ env->buflen += sl;
+
+ return 0;
+}
+EXPORT_SYMBOL(of_device_uevent);
diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c
new file mode 100644
index 00000000000..acf4574d0f1
--- /dev/null
+++ b/arch/microblaze/kernel/of_platform.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
+ * <benh@kernel.crashing.org>
+ * and Arnd Bergmann, IBM 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; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+
+#include <linux/errno.h>
+#include <linux/topology.h>
+#include <asm/atomic.h>
+
+struct bus_type of_platform_bus_type = {
+ .uevent = of_device_uevent,
+};
+EXPORT_SYMBOL(of_platform_bus_type);
+
+static int __init of_bus_driver_init(void)
+{
+ return of_bus_type_init(&of_platform_bus_type, "of_platform");
+}
+postcore_initcall(of_bus_driver_init);
+
+struct of_device *of_platform_device_create(struct device_node *np,
+ const char *bus_id,
+ struct device *parent)
+{
+ struct of_device *dev;
+
+ dev = of_device_alloc(np, bus_id, parent);
+ if (!dev)
+ return NULL;
+
+ dev->dma_mask = 0xffffffffUL;
+ dev->dev.bus = &of_platform_bus_type;
+
+ /* We do not fill the DMA ops for platform devices by default.
+ * This is currently the responsibility of the platform code
+ * to do such, possibly using a device notifier
+ */
+
+ if (of_device_register(dev) != 0) {
+ of_device_free(dev);
+ return NULL;
+ }
+
+ return dev;
+}
+EXPORT_SYMBOL(of_platform_device_create);
+
+/**
+ * of_platform_bus_create - Create an OF device for a bus node and all its
+ * children. Optionally recursively instanciate matching busses.
+ * @bus: device node of the bus to instanciate
+ * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
+ * disallow recursive creation of child busses
+ */
+static int of_platform_bus_create(const struct device_node *bus,
+ const struct of_device_id *matches,
+ struct device *parent)
+{
+ struct device_node *child;
+ struct of_device *dev;
+ int rc = 0;
+
+ for_each_child_of_node(bus, child) {
+ pr_debug(" create child: %s\n", child->full_name);
+ dev = of_platform_device_create(child, NULL, parent);
+ if (dev == NULL)
+ rc = -ENOMEM;
+ else if (!of_match_node(matches, child))
+ continue;
+ if (rc == 0) {
+ pr_debug(" and sub busses\n");
+ rc = of_platform_bus_create(child, matches, &dev->dev);
+ }
+ if (rc) {
+ of_node_put(child);
+ break;
+ }
+ }
+ return rc;
+}
+
+
+/**
+ * of_platform_bus_probe - Probe the device-tree for platform busses
+ * @root: parent of the first level to probe or NULL for the root of the tree
+ * @matches: match table, NULL to use the default
+ * @parent: parent to hook devices from, NULL for toplevel
+ *
+ * Note that children of the provided root are not instanciated as devices
+ * unless the specified root itself matches the bus list and is not NULL.
+ */
+
+int of_platform_bus_probe(struct device_node *root,
+ const struct of_device_id *matches,
+ struct device *parent)
+{
+ struct device_node *child;
+ struct of_device *dev;
+ int rc = 0;
+
+ if (matches == NULL)
+ matches = of_default_bus_ids;
+ if (matches == OF_NO_DEEP_PROBE)
+ return -EINVAL;
+ if (root == NULL)
+ root = of_find_node_by_path("/");
+ else
+ of_node_get(root);
+
+ pr_debug("of_platform_bus_probe()\n");
+ pr_debug(" starting at: %s\n", root->full_name);
+
+ /* Do a self check of bus type, if there's a match, create
+ * children
+ */
+ if (of_match_node(matches, root)) {
+ pr_debug(" root match, create all sub devices\n");
+ dev = of_platform_device_create(root, NULL, parent);
+ if (dev == NULL) {
+ rc = -ENOMEM;
+ goto bail;
+ }
+ pr_debug(" create all sub busses\n");
+ rc = of_platform_bus_create(root, matches, &dev->dev);
+ goto bail;
+ }
+ for_each_child_of_node(root, child) {
+ if (!of_match_node(matches, child))
+ continue;
+
+ pr_debug(" match: %s\n", child->full_name);
+ dev = of_platform_device_create(child, NULL, parent);
+ if (dev == NULL)
+ rc = -ENOMEM;
+ else
+ rc = of_platform_bus_create(child, matches, &dev->dev);
+ if (rc) {
+ of_node_put(child);
+ break;
+ }
+ }
+ bail:
+ of_node_put(root);
+ return rc;
+}
+EXPORT_SYMBOL(of_platform_bus_probe);
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+ return to_of_device(dev)->node == data;
+}
+
+struct of_device *of_find_device_by_node(struct device_node *np)
+{
+ struct device *dev;
+
+ dev = bus_find_device(&of_platform_bus_type,
+ NULL, np, of_dev_node_match);
+ if (dev)
+ return to_of_device(dev);
+ return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_node);
+
+static int of_dev_phandle_match(struct device *dev, void *data)
+{
+ phandle *ph = data;
+ return to_of_device(dev)->node->linux_phandle == *ph;
+}
+
+struct of_device *of_find_device_by_phandle(phandle ph)
+{
+ struct device *dev;
+
+ dev = bus_find_device(&of_platform_bus_type,
+ NULL, &ph, of_dev_phandle_match);
+ if (dev)
+ return to_of_device(dev);
+ return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_phandle);
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
new file mode 100644
index 00000000000..436f26ccbfa
--- /dev/null
+++ b/arch/microblaze/kernel/process.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/pm.h>
+#include <linux/tick.h>
+#include <linux/bitops.h>
+#include <asm/system.h>
+#include <asm/pgalloc.h>
+
+void show_regs(struct pt_regs *regs)
+{
+ printk(KERN_INFO " Registers dump: mode=%X\r\n", regs->kernel_mode);
+ printk(KERN_INFO " r1=%08lX, r2=%08lX, r3=%08lX, r4=%08lX\n",
+ regs->r1, regs->r2, regs->r3, regs->r4);
+ printk(KERN_INFO " r5=%08lX, r6=%08lX, r7=%08lX, r8=%08lX\n",
+ regs->r5, regs->r6, regs->r7, regs->r8);
+ printk(KERN_INFO " r9=%08lX, r10=%08lX, r11=%08lX, r12=%08lX\n",
+ regs->r9, regs->r10, regs->r11, regs->r12);
+ printk(KERN_INFO " r13=%08lX, r14=%08lX, r15=%08lX, r16=%08lX\n",
+ regs->r13, regs->r14, regs->r15, regs->r16);
+ printk(KERN_INFO " r17=%08lX, r18=%08lX, r19=%08lX, r20=%08lX\n",
+ regs->r17, regs->r18, regs->r19, regs->r20);
+ printk(KERN_INFO " r21=%08lX, r22=%08lX, r23=%08lX, r24=%08lX\n",
+ regs->r21, regs->r22, regs->r23, regs->r24);
+ printk(KERN_INFO " r25=%08lX, r26=%08lX, r27=%08lX, r28=%08lX\n",
+ regs->r25, regs->r26, regs->r27, regs->r28);
+ printk(KERN_INFO " r29=%08lX, r30=%08lX, r31=%08lX, rPC=%08lX\n",
+ regs->r29, regs->r30, regs->r31, regs->pc);
+ printk(KERN_INFO " msr=%08lX, ear=%08lX, esr=%08lX, fsr=%08lX\n",
+ regs->msr, regs->ear, regs->esr, regs->fsr);
+ while (1)
+ ;
+}
+
+void (*pm_idle)(void);
+void (*pm_power_off)(void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
+
+static int hlt_counter = 1;
+
+void disable_hlt(void)
+{
+ hlt_counter++;
+}
+EXPORT_SYMBOL(disable_hlt);
+
+void enable_hlt(void)
+{
+ hlt_counter--;
+}
+EXPORT_SYMBOL(enable_hlt);
+
+static int __init nohlt_setup(char *__unused)
+{
+ hlt_counter = 1;
+ return 1;
+}
+__setup("nohlt", nohlt_setup);
+
+static int __init hlt_setup(char *__unused)
+{
+ hlt_counter = 0;
+ return 1;
+}
+__setup("hlt", hlt_setup);
+
+void default_idle(void)
+{
+ if (!hlt_counter) {
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ smp_mb__after_clear_bit();
+ local_irq_disable();
+ while (!need_resched())
+ cpu_sleep();
+ local_irq_enable();
+ set_thread_flag(TIF_POLLING_NRFLAG);
+ } else
+ while (!need_resched())
+ cpu_relax();
+}
+
+void cpu_idle(void)
+{
+ set_thread_flag(TIF_POLLING_NRFLAG);
+
+ /* endless idle loop with no priority at all */
+ while (1) {
+ void (*idle)(void) = pm_idle;
+
+ if (!idle)
+ idle = default_idle;
+
+ tick_nohz_stop_sched_tick(1);
+ while (!need_resched())
+ idle();
+ tick_nohz_restart_sched_tick();
+
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ check_pgt_cache();
+ }
+}
+
+void flush_thread(void)
+{
+}
+
+int copy_thread(unsigned long clone_flags, unsigned long usp,
+ unsigned long unused,
+ struct task_struct *p, struct pt_regs *regs)
+{
+ struct pt_regs *childregs = task_pt_regs(p);
+ struct thread_info *ti = task_thread_info(p);
+
+ *childregs = *regs;
+ if (user_mode(regs))
+ childregs->r1 = usp;
+ else
+ childregs->r1 = ((unsigned long) ti) + THREAD_SIZE;
+
+ memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
+ ti->cpu_context.r1 = (unsigned long)childregs;
+ ti->cpu_context.msr = (unsigned long)childregs->msr;
+ ti->cpu_context.r15 = (unsigned long)ret_from_fork - 8;
+
+ if (clone_flags & CLONE_SETTLS)
+ ;
+
+ return 0;
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+ struct cpu_context *ctx =
+ &(((struct thread_info *)(tsk->stack))->cpu_context);
+
+ /* Check whether the thread is blocked in resume() */
+ if (in_sched_functions(ctx->r15))
+ return (unsigned long)ctx->r15;
+ else
+ return ctx->r14;
+}
+
+static void kernel_thread_helper(int (*fn)(void *), void *arg)
+{
+ fn(arg);
+ do_exit(-1);
+}
+
+int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+ struct pt_regs regs;
+ int ret;
+
+ memset(&regs, 0, sizeof(regs));
+ /* store them in non-volatile registers */
+ regs.r5 = (unsigned long)fn;
+ regs.r6 = (unsigned long)arg;
+ local_save_flags(regs.msr);
+ regs.pc = (unsigned long)kernel_thread_helper;
+ regs.kernel_mode = 1;
+
+ ret = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+ &regs, 0, NULL, NULL);
+
+ return ret;
+}
+
+unsigned long get_wchan(struct task_struct *p)
+{
+/* TBD (used by procfs) */
+ return 0;
+}
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
new file mode 100644
index 00000000000..34c48718061
--- /dev/null
+++ b/arch/microblaze/kernel/prom.c
@@ -0,0 +1,1146 @@
+/*
+ * Procedures for creating, accessing and interpreting the device tree.
+ *
+ * Paul Mackerras August 1996.
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
+ * {engebret|bergner}@us.ibm.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/stringify.h>
+#include <linux/delay.h>
+#include <linux/initrd.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/kexec.h>
+#include <linux/debugfs.h>
+#include <linux/irq.h>
+#include <linux/lmb.h>
+
+#include <asm/prom.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <linux/io.h>
+#include <asm/system.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+#include <asm/pci-bridge.h>
+
+static int __initdata dt_root_addr_cells;
+static int __initdata dt_root_size_cells;
+
+typedef u32 cell_t;
+
+static struct boot_param_header *initial_boot_params;
+
+/* export that to outside world */
+struct device_node *of_chosen;
+
+static inline char *find_flat_dt_string(u32 offset)
+{
+ return ((char *)initial_boot_params) +
+ initial_boot_params->off_dt_strings + offset;
+}
+
+/**
+ * This function is used to scan the flattened device-tree, it is
+ * used to extract the memory informations at boot before we can
+ * unflatten the tree
+ */
+int __init of_scan_flat_dt(int (*it)(unsigned long node,
+ const char *uname, int depth,
+ void *data),
+ void *data)
+{
+ unsigned long p = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+ int rc = 0;
+ int depth = -1;
+
+ do {
+ u32 tag = *((u32 *)p);
+ char *pathp;
+
+ p += 4;
+ if (tag == OF_DT_END_NODE) {
+ depth--;
+ continue;
+ }
+ if (tag == OF_DT_NOP)
+ continue;
+ if (tag == OF_DT_END)
+ break;
+ if (tag == OF_DT_PROP) {
+ u32 sz = *((u32 *)p);
+ p += 8;
+ if (initial_boot_params->version < 0x10)
+ p = _ALIGN(p, sz >= 8 ? 8 : 4);
+ p += sz;
+ p = _ALIGN(p, 4);
+ continue;
+ }
+ if (tag != OF_DT_BEGIN_NODE) {
+ printk(KERN_WARNING "Invalid tag %x scanning flattened"
+ " device tree !\n", tag);
+ return -EINVAL;
+ }
+ depth++;
+ pathp = (char *)p;
+ p = _ALIGN(p + strlen(pathp) + 1, 4);
+ if ((*pathp) == '/') {
+ char *lp, *np;
+ for (lp = NULL, np = pathp; *np; np++)
+ if ((*np) == '/')
+ lp = np+1;
+ if (lp != NULL)
+ pathp = lp;
+ }
+ rc = it(p, pathp, depth, data);
+ if (rc != 0)
+ break;
+ } while (1);
+
+ return rc;
+}
+
+unsigned long __init of_get_flat_dt_root(void)
+{
+ unsigned long p = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+
+ while (*((u32 *)p) == OF_DT_NOP)
+ p += 4;
+ BUG_ON(*((u32 *)p) != OF_DT_BEGIN_NODE);
+ p += 4;
+ return _ALIGN(p + strlen((char *)p) + 1, 4);
+}
+
+/**
+ * This function can be used within scan_flattened_dt callback to get
+ * access to properties
+ */
+void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
+ unsigned long *size)
+{
+ unsigned long p = node;
+
+ do {
+ u32 tag = *((u32 *)p);
+ u32 sz, noff;
+ const char *nstr;
+
+ p += 4;
+ if (tag == OF_DT_NOP)
+ continue;
+ if (tag != OF_DT_PROP)
+ return NULL;
+
+ sz = *((u32 *)p);
+ noff = *((u32 *)(p + 4));
+ p += 8;
+ if (initial_boot_params->version < 0x10)
+ p = _ALIGN(p, sz >= 8 ? 8 : 4);
+
+ nstr = find_flat_dt_string(noff);
+ if (nstr == NULL) {
+ printk(KERN_WARNING "Can't find property index"
+ " name !\n");
+ return NULL;
+ }
+ if (strcmp(name, nstr) == 0) {
+ if (size)
+ *size = sz;
+ return (void *)p;
+ }
+ p += sz;
+ p = _ALIGN(p, 4);
+ } while (1);
+}
+
+int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
+{
+ const char *cp;
+ unsigned long cplen, l;
+
+ cp = of_get_flat_dt_prop(node, "compatible", &cplen);
+ if (cp == NULL)
+ return 0;
+ while (cplen > 0) {
+ if (strncasecmp(cp, compat, strlen(compat)) == 0)
+ return 1;
+ l = strlen(cp) + 1;
+ cp += l;
+ cplen -= l;
+ }
+
+ return 0;
+}
+
+static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
+ unsigned long align)
+{
+ void *res;
+
+ *mem = _ALIGN(*mem, align);
+ res = (void *)*mem;
+ *mem += size;
+
+ return res;
+}
+
+static unsigned long __init unflatten_dt_node(unsigned long mem,
+ unsigned long *p,
+ struct device_node *dad,
+ struct device_node ***allnextpp,
+ unsigned long fpsize)
+{
+ struct device_node *np;
+ struct property *pp, **prev_pp = NULL;
+ char *pathp;
+ u32 tag;
+ unsigned int l, allocl;
+ int has_name = 0;
+ int new_format = 0;
+
+ tag = *((u32 *)(*p));
+ if (tag != OF_DT_BEGIN_NODE) {
+ printk("Weird tag at start of node: %x\n", tag);
+ return mem;
+ }
+ *p += 4;
+ pathp = (char *)*p;
+ l = allocl = strlen(pathp) + 1;
+ *p = _ALIGN(*p + l, 4);
+
+ /* version 0x10 has a more compact unit name here instead of the full
+ * path. we accumulate the full path size using "fpsize", we'll rebuild
+ * it later. We detect this because the first character of the name is
+ * not '/'.
+ */
+ if ((*pathp) != '/') {
+ new_format = 1;
+ if (fpsize == 0) {
+ /* root node: special case. fpsize accounts for path
+ * plus terminating zero. root node only has '/', so
+ * fpsize should be 2, but we want to avoid the first
+ * level nodes to have two '/' so we use fpsize 1 here
+ */
+ fpsize = 1;
+ allocl = 2;
+ } else {
+ /* account for '/' and path size minus terminal 0
+ * already in 'l'
+ */
+ fpsize += l;
+ allocl = fpsize;
+ }
+ }
+
+ np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
+ __alignof__(struct device_node));
+ if (allnextpp) {
+ memset(np, 0, sizeof(*np));
+ np->full_name = ((char *)np) + sizeof(struct device_node);
+ if (new_format) {
+ char *p2 = np->full_name;
+ /* rebuild full path for new format */
+ if (dad && dad->parent) {
+ strcpy(p2, dad->full_name);
+#ifdef DEBUG
+ if ((strlen(p2) + l + 1) != allocl) {
+ pr_debug("%s: p: %d, l: %d, a: %d\n",
+ pathp, (int)strlen(p2),
+ l, allocl);
+ }
+#endif
+ p2 += strlen(p2);
+ }
+ *(p2++) = '/';
+ memcpy(p2, pathp, l);
+ } else
+ memcpy(np->full_name, pathp, l);
+ prev_pp = &np->properties;
+ **allnextpp = np;
+ *allnextpp = &np->allnext;
+ if (dad != NULL) {
+ np->parent = dad;
+ /* we temporarily use the next field as `last_child'*/
+ if (dad->next == NULL)
+ dad->child = np;
+ else
+ dad->next->sibling = np;
+ dad->next = np;
+ }
+ kref_init(&np->kref);
+ }
+ while (1) {
+ u32 sz, noff;
+ char *pname;
+
+ tag = *((u32 *)(*p));
+ if (tag == OF_DT_NOP) {
+ *p += 4;
+ continue;
+ }
+ if (tag != OF_DT_PROP)
+ break;
+ *p += 4;
+ sz = *((u32 *)(*p));
+ noff = *((u32 *)((*p) + 4));
+ *p += 8;
+ if (initial_boot_params->version < 0x10)
+ *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
+
+ pname = find_flat_dt_string(noff);
+ if (pname == NULL) {
+ printk(KERN_INFO
+ "Can't find property name in list !\n");
+ break;
+ }
+ if (strcmp(pname, "name") == 0)
+ has_name = 1;
+ l = strlen(pname) + 1;
+ pp = unflatten_dt_alloc(&mem, sizeof(struct property),
+ __alignof__(struct property));
+ if (allnextpp) {
+ if (strcmp(pname, "linux,phandle") == 0) {
+ np->node = *((u32 *)*p);
+ if (np->linux_phandle == 0)
+ np->linux_phandle = np->node;
+ }
+ if (strcmp(pname, "ibm,phandle") == 0)
+ np->linux_phandle = *((u32 *)*p);
+ pp->name = pname;
+ pp->length = sz;
+ pp->value = (void *)*p;
+ *prev_pp = pp;
+ prev_pp = &pp->next;
+ }
+ *p = _ALIGN((*p) + sz, 4);
+ }
+ /* with version 0x10 we may not have the name property, recreate
+ * it here from the unit name if absent
+ */
+ if (!has_name) {
+ char *p1 = pathp, *ps = pathp, *pa = NULL;
+ int sz;
+
+ while (*p1) {
+ if ((*p1) == '@')
+ pa = p1;
+ if ((*p1) == '/')
+ ps = p1 + 1;
+ p1++;
+ }
+ if (pa < ps)
+ pa = p1;
+ sz = (pa - ps) + 1;
+ pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
+ __alignof__(struct property));
+ if (allnextpp) {
+ pp->name = "name";
+ pp->length = sz;
+ pp->value = pp + 1;
+ *prev_pp = pp;
+ prev_pp = &pp->next;
+ memcpy(pp->value, ps, sz - 1);
+ ((char *)pp->value)[sz - 1] = 0;
+ pr_debug("fixed up name for %s -> %s\n", pathp,
+ (char *)pp->value);
+ }
+ }
+ if (allnextpp) {
+ *prev_pp = NULL;
+ np->name = of_get_property(np, "name", NULL);
+ np->type = of_get_property(np, "device_type", NULL);
+
+ if (!np->name)
+ np->name = "<NULL>";
+ if (!np->type)
+ np->type = "<NULL>";
+ }
+ while (tag == OF_DT_BEGIN_NODE) {
+ mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
+ tag = *((u32 *)(*p));
+ }
+ if (tag != OF_DT_END_NODE) {
+ printk(KERN_INFO "Weird tag at end of node: %x\n", tag);
+ return mem;
+ }
+ *p += 4;
+ return mem;
+}
+
+/**
+ * unflattens the device-tree passed by the firmware, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used (this used to be done by finish_device_tree)
+ */
+void __init unflatten_device_tree(void)
+{
+ unsigned long start, mem, size;
+ struct device_node **allnextp = &allnodes;
+
+ pr_debug(" -> unflatten_device_tree()\n");
+
+ /* First pass, scan for size */
+ start = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+ size = unflatten_dt_node(0, &start, NULL, NULL, 0);
+ size = (size | 3) + 1;
+
+ pr_debug(" size is %lx, allocating...\n", size);
+
+ /* Allocate memory for the expanded device tree */
+ mem = lmb_alloc(size + 4, __alignof__(struct device_node));
+ mem = (unsigned long) __va(mem);
+
+ ((u32 *)mem)[size / 4] = 0xdeadbeef;
+
+ pr_debug(" unflattening %lx...\n", mem);
+
+ /* Second pass, do actual unflattening */
+ start = ((unsigned long)initial_boot_params) +
+ initial_boot_params->off_dt_struct;
+ unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
+ if (*((u32 *)start) != OF_DT_END)
+ printk(KERN_WARNING "Weird tag at end of tree: %08x\n",
+ *((u32 *)start));
+ if (((u32 *)mem)[size / 4] != 0xdeadbeef)
+ printk(KERN_WARNING "End of tree marker overwritten: %08x\n",
+ ((u32 *)mem)[size / 4]);
+ *allnextp = NULL;
+
+ /* Get pointer to OF "/chosen" node for use everywhere */
+ of_chosen = of_find_node_by_path("/chosen");
+ if (of_chosen == NULL)
+ of_chosen = of_find_node_by_path("/chosen@0");
+
+ pr_debug(" <- unflatten_device_tree()\n");
+}
+
+#define early_init_dt_scan_drconf_memory(node) 0
+
+static int __init early_init_dt_scan_cpus(unsigned long node,
+ const char *uname, int depth,
+ void *data)
+{
+ static int logical_cpuid;
+ char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+ const u32 *intserv;
+ int i, nthreads;
+ int found = 0;
+
+ /* We are scanning "cpu" nodes only */
+ if (type == NULL || strcmp(type, "cpu") != 0)
+ return 0;
+
+ /* Get physical cpuid */
+ intserv = of_get_flat_dt_prop(node, "reg", NULL);
+ nthreads = 1;
+
+ /*
+ * Now see if any of these threads match our boot cpu.
+ * NOTE: This must match the parsing done in smp_setup_cpu_maps.
+ */
+ for (i = 0; i < nthreads; i++) {
+ /*
+ * version 2 of the kexec param format adds the phys cpuid of
+ * booted proc.
+ */
+ if (initial_boot_params && initial_boot_params->version >= 2) {
+ if (intserv[i] ==
+ initial_boot_params->boot_cpuid_phys) {
+ found = 1;
+ break;
+ }
+ } else {
+ /*
+ * Check if it's the boot-cpu, set it's hw index now,
+ * unfortunately this format did not support booting
+ * off secondary threads.
+ */
+ if (of_get_flat_dt_prop(node,
+ "linux,boot-cpu", NULL) != NULL) {
+ found = 1;
+ break;
+ }
+ }
+
+#ifdef CONFIG_SMP
+ /* logical cpu id is always 0 on UP kernels */
+ logical_cpuid++;
+#endif
+ }
+
+ if (found) {
+ pr_debug("boot cpu: logical %d physical %d\n", logical_cpuid,
+ intserv[i]);
+ boot_cpuid = logical_cpuid;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+static void __init early_init_dt_check_for_initrd(unsigned long node)
+{
+ unsigned long l;
+ u32 *prop;
+
+ pr_debug("Looking for initrd properties... ");
+
+ prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l);
+ if (prop) {
+ initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4));
+
+ prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
+ if (prop) {
+ initrd_end = (unsigned long)
+ __va(of_read_ulong(prop, l/4));
+ initrd_below_start_ok = 1;
+ } else {
+ initrd_start = 0;
+ }
+ }
+
+ pr_debug("initrd_start=0x%lx initrd_end=0x%lx\n",
+ initrd_start, initrd_end);
+}
+#else
+static inline void early_init_dt_check_for_initrd(unsigned long node)
+{
+}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+static int __init early_init_dt_scan_chosen(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ unsigned long l;
+ char *p;
+
+ pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+
+ if (depth != 1 ||
+ (strcmp(uname, "chosen") != 0 &&
+ strcmp(uname, "chosen@0") != 0))
+ return 0;
+
+#ifdef CONFIG_KEXEC
+ lprop = (u64 *)of_get_flat_dt_prop(node,
+ "linux,crashkernel-base", NULL);
+ if (lprop)
+ crashk_res.start = *lprop;
+
+ lprop = (u64 *)of_get_flat_dt_prop(node,
+ "linux,crashkernel-size", NULL);
+ if (lprop)
+ crashk_res.end = crashk_res.start + *lprop - 1;
+#endif
+
+ early_init_dt_check_for_initrd(node);
+
+ /* Retreive command line */
+ p = of_get_flat_dt_prop(node, "bootargs", &l);
+ if (p != NULL && l > 0)
+ strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE));
+
+#ifdef CONFIG_CMDLINE
+ if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
+ strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+#endif /* CONFIG_CMDLINE */
+
+ pr_debug("Command line is: %s\n", cmd_line);
+
+ /* break now */
+ return 1;
+}
+
+static int __init early_init_dt_scan_root(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ u32 *prop;
+
+ if (depth != 0)
+ return 0;
+
+ prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
+ dt_root_size_cells = (prop == NULL) ? 1 : *prop;
+ pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
+
+ prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
+ dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
+ pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
+
+ /* break now */
+ return 1;
+}
+
+static u64 __init dt_mem_next_cell(int s, cell_t **cellp)
+{
+ cell_t *p = *cellp;
+
+ *cellp = p + s;
+ return of_read_number(p, s);
+}
+
+static int __init early_init_dt_scan_memory(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+ cell_t *reg, *endp;
+ unsigned long l;
+
+ /* Look for the ibm,dynamic-reconfiguration-memory node */
+/* if (depth == 1 &&
+ strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0)
+ return early_init_dt_scan_drconf_memory(node);
+*/
+ /* We are scanning "memory" nodes only */
+ if (type == NULL) {
+ /*
+ * The longtrail doesn't have a device_type on the
+ * /memory node, so look for the node called /memory@0.
+ */
+ if (depth != 1 || strcmp(uname, "memory@0") != 0)
+ return 0;
+ } else if (strcmp(type, "memory") != 0)
+ return 0;
+
+ reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l);
+ if (reg == NULL)
+ reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
+ if (reg == NULL)
+ return 0;
+
+ endp = reg + (l / sizeof(cell_t));
+
+ pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
+ uname, l, reg[0], reg[1], reg[2], reg[3]);
+
+ while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+ u64 base, size;
+
+ base = dt_mem_next_cell(dt_root_addr_cells, &reg);
+ size = dt_mem_next_cell(dt_root_size_cells, &reg);
+
+ if (size == 0)
+ continue;
+ pr_debug(" - %llx , %llx\n", (unsigned long long)base,
+ (unsigned long long)size);
+
+ lmb_add(base, size);
+ }
+ return 0;
+}
+
+#ifdef CONFIG_PHYP_DUMP
+/**
+ * phyp_dump_calculate_reserve_size() - reserve variable boot area 5% or arg
+ *
+ * Function to find the largest size we need to reserve
+ * during early boot process.
+ *
+ * It either looks for boot param and returns that OR
+ * returns larger of 256 or 5% rounded down to multiples of 256MB.
+ *
+ */
+static inline unsigned long phyp_dump_calculate_reserve_size(void)
+{
+ unsigned long tmp;
+
+ if (phyp_dump_info->reserve_bootvar)
+ return phyp_dump_info->reserve_bootvar;
+
+ /* divide by 20 to get 5% of value */
+ tmp = lmb_end_of_DRAM();
+ do_div(tmp, 20);
+
+ /* round it down in multiples of 256 */
+ tmp = tmp & ~0x0FFFFFFFUL;
+
+ return (tmp > PHYP_DUMP_RMR_END ? tmp : PHYP_DUMP_RMR_END);
+}
+
+/**
+ * phyp_dump_reserve_mem() - reserve all not-yet-dumped mmemory
+ *
+ * This routine may reserve memory regions in the kernel only
+ * if the system is supported and a dump was taken in last
+ * boot instance or if the hardware is supported and the
+ * scratch area needs to be setup. In other instances it returns
+ * without reserving anything. The memory in case of dump being
+ * active is freed when the dump is collected (by userland tools).
+ */
+static void __init phyp_dump_reserve_mem(void)
+{
+ unsigned long base, size;
+ unsigned long variable_reserve_size;
+
+ if (!phyp_dump_info->phyp_dump_configured) {
+ printk(KERN_ERR "Phyp-dump not supported on this hardware\n");
+ return;
+ }
+
+ if (!phyp_dump_info->phyp_dump_at_boot) {
+ printk(KERN_INFO "Phyp-dump disabled at boot time\n");
+ return;
+ }
+
+ variable_reserve_size = phyp_dump_calculate_reserve_size();
+
+ if (phyp_dump_info->phyp_dump_is_active) {
+ /* Reserve *everything* above RMR.Area freed by userland tools*/
+ base = variable_reserve_size;
+ size = lmb_end_of_DRAM() - base;
+
+ /* XXX crashed_ram_end is wrong, since it may be beyond
+ * the memory_limit, it will need to be adjusted. */
+ lmb_reserve(base, size);
+
+ phyp_dump_info->init_reserve_start = base;
+ phyp_dump_info->init_reserve_size = size;
+ } else {
+ size = phyp_dump_info->cpu_state_size +
+ phyp_dump_info->hpte_region_size +
+ variable_reserve_size;
+ base = lmb_end_of_DRAM() - size;
+ lmb_reserve(base, size);
+ phyp_dump_info->init_reserve_start = base;
+ phyp_dump_info->init_reserve_size = size;
+ }
+}
+#else
+static inline void __init phyp_dump_reserve_mem(void) {}
+#endif /* CONFIG_PHYP_DUMP && CONFIG_PPC_RTAS */
+
+#ifdef CONFIG_EARLY_PRINTK
+/* MS this is Microblaze specifig function */
+static int __init early_init_dt_scan_serial(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ unsigned long l;
+ char *p;
+ int *addr;
+
+ pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+
+/* find all serial nodes */
+ if (strncmp(uname, "serial", 6) != 0)
+ return 0;
+
+ early_init_dt_check_for_initrd(node);
+
+/* find compatible node with uartlite */
+ p = of_get_flat_dt_prop(node, "compatible", &l);
+ if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
+ (strncmp(p, "xlnx,opb-uartlite", 17) != 0))
+ return 0;
+
+ addr = of_get_flat_dt_prop(node, "reg", &l);
+ return *addr; /* return address */
+}
+
+/* this function is looking for early uartlite console - Microblaze specific */
+int __init early_uartlite_console(void)
+{
+ return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
+}
+#endif
+
+void __init early_init_devtree(void *params)
+{
+ pr_debug(" -> early_init_devtree(%p)\n", params);
+
+ /* Setup flat device-tree pointer */
+ initial_boot_params = params;
+
+#ifdef CONFIG_PHYP_DUMP
+ /* scan tree to see if dump occured during last boot */
+ of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL);
+#endif
+
+ /* Retrieve various informations from the /chosen node of the
+ * device-tree, including the platform type, initrd location and
+ * size, TCE reserve, and more ...
+ */
+ of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+
+ /* Scan memory nodes and rebuild LMBs */
+ lmb_init();
+ of_scan_flat_dt(early_init_dt_scan_root, NULL);
+ of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+
+ /* Save command line for /proc/cmdline and then parse parameters */
+ strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
+ parse_early_param();
+
+ lmb_analyze();
+
+ pr_debug("Phys. mem: %lx\n", (unsigned long) lmb_phys_mem_size());
+
+ pr_debug("Scanning CPUs ...\n");
+
+ /* Retreive CPU related informations from the flat tree
+ * (altivec support, boot CPU ID, ...)
+ */
+ of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
+
+ pr_debug(" <- early_init_devtree()\n");
+}
+
+/**
+ * Indicates whether the root node has a given value in its
+ * compatible property.
+ */
+int machine_is_compatible(const char *compat)
+{
+ struct device_node *root;
+ int rc = 0;
+
+ root = of_find_node_by_path("/");
+ if (root) {
+ rc = of_device_is_compatible(root, compat);
+ of_node_put(root);
+ }
+ return rc;
+}
+EXPORT_SYMBOL(machine_is_compatible);
+
+/*******
+ *
+ * New implementation of the OF "find" APIs, return a refcounted
+ * object, call of_node_put() when done. The device tree and list
+ * are protected by a rw_lock.
+ *
+ * Note that property management will need some locking as well,
+ * this isn't dealt with yet.
+ *
+ *******/
+
+/**
+ * of_find_node_by_phandle - Find a node given a phandle
+ * @handle: phandle of the node to find
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_phandle(phandle handle)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ for (np = allnodes; np != NULL; np = np->allnext)
+ if (np->linux_phandle == handle)
+ break;
+ of_node_get(np);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_node_by_phandle);
+
+/**
+ * of_find_all_nodes - Get next node in global list
+ * @prev: Previous node or NULL to start iteration
+ * of_node_put() will be called on it
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_all_nodes(struct device_node *prev)
+{
+ struct device_node *np;
+
+ read_lock(&devtree_lock);
+ np = prev ? prev->allnext : allnodes;
+ for (; np != NULL; np = np->allnext)
+ if (of_node_get(np))
+ break;
+ of_node_put(prev);
+ read_unlock(&devtree_lock);
+ return np;
+}
+EXPORT_SYMBOL(of_find_all_nodes);
+
+/**
+ * of_node_get - Increment refcount of a node
+ * @node: Node to inc refcount, NULL is supported to
+ * simplify writing of callers
+ *
+ * Returns node.
+ */
+struct device_node *of_node_get(struct device_node *node)
+{
+ if (node)
+ kref_get(&node->kref);
+ return node;
+}
+EXPORT_SYMBOL(of_node_get);
+
+static inline struct device_node *kref_to_device_node(struct kref *kref)
+{
+ return container_of(kref, struct device_node, kref);
+}
+
+/**
+ * of_node_release - release a dynamically allocated node
+ * @kref: kref element of the node to be released
+ *
+ * In of_node_put() this function is passed to kref_put()
+ * as the destructor.
+ */
+static void of_node_release(struct kref *kref)
+{
+ struct device_node *node = kref_to_device_node(kref);
+ struct property *prop = node->properties;
+
+ /* We should never be releasing nodes that haven't been detached. */
+ if (!of_node_check_flag(node, OF_DETACHED)) {
+ printk(KERN_INFO "WARNING: Bad of_node_put() on %s\n",
+ node->full_name);
+ dump_stack();
+ kref_init(&node->kref);
+ return;
+ }
+
+ if (!of_node_check_flag(node, OF_DYNAMIC))
+ return;
+
+ while (prop) {
+ struct property *next = prop->next;
+ kfree(prop->name);
+ kfree(prop->value);
+ kfree(prop);
+ prop = next;
+
+ if (!prop) {
+ prop = node->deadprops;
+ node->deadprops = NULL;
+ }
+ }
+ kfree(node->full_name);
+ kfree(node->data);
+ kfree(node);
+}
+
+/**
+ * of_node_put - Decrement refcount of a node
+ * @node: Node to dec refcount, NULL is supported to
+ * simplify writing of callers
+ *
+ */
+void of_node_put(struct device_node *node)
+{
+ if (node)
+ kref_put(&node->kref, of_node_release);
+}
+EXPORT_SYMBOL(of_node_put);
+
+/*
+ * Plug a device node into the tree and global list.
+ */
+void of_attach_node(struct device_node *np)
+{
+ unsigned long flags;
+
+ write_lock_irqsave(&devtree_lock, flags);
+ np->sibling = np->parent->child;
+ np->allnext = allnodes;
+ np->parent->child = np;
+ allnodes = np;
+ write_unlock_irqrestore(&devtree_lock, flags);
+}
+
+/*
+ * "Unplug" a node from the device tree. The caller must hold
+ * a reference to the node. The memory associated with the node
+ * is not freed until its refcount goes to zero.
+ */
+void of_detach_node(struct device_node *np)
+{
+ struct device_node *parent;
+ unsigned long flags;
+
+ write_lock_irqsave(&devtree_lock, flags);
+
+ parent = np->parent;
+ if (!parent)
+ goto out_unlock;
+
+ if (allnodes == np)
+ allnodes = np->allnext;
+ else {
+ struct device_node *prev;
+ for (prev = allnodes;
+ prev->allnext != np;
+ prev = prev->allnext)
+ ;
+ prev->allnext = np->allnext;
+ }
+
+ if (parent->child == np)
+ parent->child = np->sibling;
+ else {
+ struct device_node *prevsib;
+ for (prevsib = np->parent->child;
+ prevsib->sibling != np;
+ prevsib = prevsib->sibling)
+ ;
+ prevsib->sibling = np->sibling;
+ }
+
+ of_node_set_flag(np, OF_DETACHED);
+
+out_unlock:
+ write_unlock_irqrestore(&devtree_lock, flags);
+}
+
+/*
+ * Add a property to a node
+ */
+int prom_add_property(struct device_node *np, struct property *prop)
+{
+ struct property **next;
+ unsigned long flags;
+
+ prop->next = NULL;
+ write_lock_irqsave(&devtree_lock, flags);
+ next = &np->properties;
+ while (*next) {
+ if (strcmp(prop->name, (*next)->name) == 0) {
+ /* duplicate ! don't insert it */
+ write_unlock_irqrestore(&devtree_lock, flags);
+ return -1;
+ }
+ next = &(*next)->next;
+ }
+ *next = prop;
+ write_unlock_irqrestore(&devtree_lock, flags);
+
+#ifdef CONFIG_PROC_DEVICETREE
+ /* try to add to proc as well if it was initialized */
+ if (np->pde)
+ proc_device_tree_add_prop(np->pde, prop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+ return 0;
+}
+
+/*
+ * Remove a property from a node. Note that we don't actually
+ * remove it, since we have given out who-knows-how-many pointers
+ * to the data using get-property. Instead we just move the property
+ * to the "dead properties" list, so it won't be found any more.
+ */
+int prom_remove_property(struct device_node *np, struct property *prop)
+{
+ struct property **next;
+ unsigned long flags;
+ int found = 0;
+
+ write_lock_irqsave(&devtree_lock, flags);
+ next = &np->properties;
+ while (*next) {
+ if (*next == prop) {
+ /* found the node */
+ *next = prop->next;
+ prop->next = np->deadprops;
+ np->deadprops = prop;
+ found = 1;
+ break;
+ }
+ next = &(*next)->next;
+ }
+ write_unlock_irqrestore(&devtree_lock, flags);
+
+ if (!found)
+ return -ENODEV;
+
+#ifdef CONFIG_PROC_DEVICETREE
+ /* try to remove the proc node as well */
+ if (np->pde)
+ proc_device_tree_remove_prop(np->pde, prop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+ return 0;
+}
+
+/*
+ * Update a property in a node. Note that we don't actually
+ * remove it, since we have given out who-knows-how-many pointers
+ * to the data using get-property. Instead we just move the property
+ * to the "dead properties" list, and add the new property to the
+ * property list
+ */
+int prom_update_property(struct device_node *np,
+ struct property *newprop,
+ struct property *oldprop)
+{
+ struct property **next;
+ unsigned long flags;
+ int found = 0;
+
+ write_lock_irqsave(&devtree_lock, flags);
+ next = &np->properties;
+ while (*next) {
+ if (*next == oldprop) {
+ /* found the node */
+ newprop->next = oldprop->next;
+ *next = newprop;
+ oldprop->next = np->deadprops;
+ np->deadprops = oldprop;
+ found = 1;
+ break;
+ }
+ next = &(*next)->next;
+ }
+ write_unlock_irqrestore(&devtree_lock, flags);
+
+ if (!found)
+ return -ENODEV;
+
+#ifdef CONFIG_PROC_DEVICETREE
+ /* try to add to proc as well if it was initialized */
+ if (np->pde)
+ proc_device_tree_update_prop(np->pde, newprop, oldprop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+ return 0;
+}
+
+#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
+static struct debugfs_blob_wrapper flat_dt_blob;
+
+static int __init export_flat_device_tree(void)
+{
+ struct dentry *d;
+
+ flat_dt_blob.data = initial_boot_params;
+ flat_dt_blob.size = initial_boot_params->totalsize;
+
+ d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
+ of_debugfs_root, &flat_dt_blob);
+ if (!d)
+ return 1;
+
+ return 0;
+}
+device_initcall(export_flat_device_tree);
+#endif
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
new file mode 100644
index 00000000000..ae0352ecd5a
--- /dev/null
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -0,0 +1,1025 @@
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/pci_regs.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/etherdevice.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+
+#define PRu64 "%llx"
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS 4
+#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
+ (ns) > 0)
+
+static struct of_bus *of_match_bus(struct device_node *np);
+static int __of_address_to_resource(struct device_node *dev,
+ const u32 *addrp, u64 size, unsigned int flags,
+ struct resource *r);
+
+/* Debug utility */
+#ifdef DEBUG
+static void of_dump_addr(const char *s, const u32 *addr, int na)
+{
+ printk(KERN_INFO "%s", s);
+ while (na--)
+ printk(KERN_INFO " %08x", *(addr++));
+ printk(KERN_INFO "\n");
+}
+#else
+static void of_dump_addr(const char *s, const u32 *addr, int na) { }
+#endif
+
+/* Callbacks for bus specific translators */
+struct of_bus {
+ const char *name;
+ const char *addresses;
+ int (*match)(struct device_node *parent);
+ void (*count_cells)(struct device_node *child,
+ int *addrc, int *sizec);
+ u64 (*map)(u32 *addr, const u32 *range,
+ int na, int ns, int pna);
+ int (*translate)(u32 *addr, u64 offset, int na);
+ unsigned int (*get_flags)(const u32 *addr);
+};
+
+/*
+ * Default translator (generic bus)
+ */
+
+static void of_bus_default_count_cells(struct device_node *dev,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = of_n_addr_cells(dev);
+ if (sizec)
+ *sizec = of_n_size_cells(dev);
+}
+
+static u64 of_bus_default_map(u32 *addr, const u32 *range,
+ int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ cp = of_read_number(range, na);
+ s = of_read_number(range + na + pna, ns);
+ da = of_read_number(addr, na);
+
+ pr_debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
+ cp, s, da);
+
+ if (da < cp || da >= (cp + s))
+ return OF_BAD_ADDR;
+ return da - cp;
+}
+
+static int of_bus_default_translate(u32 *addr, u64 offset, int na)
+{
+ u64 a = of_read_number(addr, na);
+ memset(addr, 0, na * 4);
+ a += offset;
+ if (na > 1)
+ addr[na - 2] = a >> 32;
+ addr[na - 1] = a & 0xffffffffu;
+
+ return 0;
+}
+
+static unsigned int of_bus_default_get_flags(const u32 *addr)
+{
+ return IORESOURCE_MEM;
+}
+
+#ifdef CONFIG_PCI
+/*
+ * PCI bus specific translator
+ */
+
+static int of_bus_pci_match(struct device_node *np)
+{
+ /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
+ return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
+}
+
+static void of_bus_pci_count_cells(struct device_node *np,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = 3;
+ if (sizec)
+ *sizec = 2;
+}
+
+static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ /* Check address type match */
+ if ((addr[0] ^ range[0]) & 0x03000000)
+ return OF_BAD_ADDR;
+
+ /* Read address values, skipping high cell */
+ cp = of_read_number(range + 1, na - 1);
+ s = of_read_number(range + na + pna, ns);
+ da = of_read_number(addr + 1, na - 1);
+
+ pr_debug("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
+
+ if (da < cp || da >= (cp + s))
+ return OF_BAD_ADDR;
+ return da - cp;
+}
+
+static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
+{
+ return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static unsigned int of_bus_pci_get_flags(const u32 *addr)
+{
+ unsigned int flags = 0;
+ u32 w = addr[0];
+
+ switch ((w >> 24) & 0x03) {
+ case 0x01:
+ flags |= IORESOURCE_IO;
+ break;
+ case 0x02: /* 32 bits */
+ case 0x03: /* 64 bits */
+ flags |= IORESOURCE_MEM;
+ break;
+ }
+ if (w & 0x40000000)
+ flags |= IORESOURCE_PREFETCH;
+ return flags;
+}
+
+const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
+ unsigned int *flags)
+{
+ const u32 *prop;
+ unsigned int psize;
+ struct device_node *parent;
+ struct of_bus *bus;
+ int onesize, i, na, ns;
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return NULL;
+ bus = of_match_bus(parent);
+ if (strcmp(bus->name, "pci")) {
+ of_node_put(parent);
+ return NULL;
+ }
+ bus->count_cells(dev, &na, &ns);
+ of_node_put(parent);
+ if (!OF_CHECK_COUNTS(na, ns))
+ return NULL;
+
+ /* Get "reg" or "assigned-addresses" property */
+ prop = of_get_property(dev, bus->addresses, &psize);
+ if (prop == NULL)
+ return NULL;
+ psize /= 4;
+
+ onesize = na + ns;
+ for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+ if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
+ if (size)
+ *size = of_read_number(prop + na, ns);
+ if (flags)
+ *flags = bus->get_flags(prop);
+ return prop;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_pci_address);
+
+int of_pci_address_to_resource(struct device_node *dev, int bar,
+ struct resource *r)
+{
+ const u32 *addrp;
+ u64 size;
+ unsigned int flags;
+
+ addrp = of_get_pci_address(dev, bar, &size, &flags);
+ if (addrp == NULL)
+ return -EINVAL;
+ return __of_address_to_resource(dev, addrp, size, flags, r);
+}
+EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+
+static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
+{
+ return (((pin - 1) + slot) % 4) + 1;
+}
+
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
+{
+ struct device_node *dn, *ppnode;
+ struct pci_dev *ppdev;
+ u32 lspec;
+ u32 laddr[3];
+ u8 pin;
+ int rc;
+
+ /* Check if we have a device node, if yes, fallback to standard OF
+ * parsing
+ */
+ dn = pci_device_to_OF_node(pdev);
+ if (dn)
+ return of_irq_map_one(dn, 0, out_irq);
+
+ /* Ok, we don't, time to have fun. Let's start by building up an
+ * interrupt spec. we assume #interrupt-cells is 1, which is standard
+ * for PCI. If you do different, then don't use that routine.
+ */
+ rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+ if (rc != 0)
+ return rc;
+ /* No pin, exit */
+ if (pin == 0)
+ return -ENODEV;
+
+ /* Now we walk up the PCI tree */
+ lspec = pin;
+ for (;;) {
+ /* Get the pci_dev of our parent */
+ ppdev = pdev->bus->self;
+
+ /* Ouch, it's a host bridge... */
+ if (ppdev == NULL) {
+ struct pci_controller *host;
+ host = pci_bus_to_host(pdev->bus);
+ ppnode = host ? host->arch_data : NULL;
+ /* No node for host bridge ? give up */
+ if (ppnode == NULL)
+ return -EINVAL;
+ } else
+ /* We found a P2P bridge, check if it has a node */
+ ppnode = pci_device_to_OF_node(ppdev);
+
+ /* Ok, we have found a parent with a device-node, hand over to
+ * the OF parsing code.
+ * We build a unit address from the linux device to be used for
+ * resolution. Note that we use the linux bus number which may
+ * not match your firmware bus numbering.
+ * Fortunately, in most cases, interrupt-map-mask doesn't
+ * include the bus number as part of the matching.
+ * You should still be careful about that though if you intend
+ * to rely on this function (you ship a firmware that doesn't
+ * create device nodes for all PCI devices).
+ */
+ if (ppnode)
+ break;
+
+ /* We can only get here if we hit a P2P bridge with no node,
+ * let's do standard swizzling and try again
+ */
+ lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
+ pdev = ppdev;
+ }
+
+ laddr[0] = (pdev->bus->number << 16)
+ | (pdev->devfn << 8);
+ laddr[1] = laddr[2] = 0;
+ return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
+}
+EXPORT_SYMBOL_GPL(of_irq_map_pci);
+#endif /* CONFIG_PCI */
+
+/*
+ * ISA bus specific translator
+ */
+
+static int of_bus_isa_match(struct device_node *np)
+{
+ return !strcmp(np->name, "isa");
+}
+
+static void of_bus_isa_count_cells(struct device_node *child,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = 2;
+ if (sizec)
+ *sizec = 1;
+}
+
+static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ /* Check address type match */
+ if ((addr[0] ^ range[0]) & 0x00000001)
+ return OF_BAD_ADDR;
+
+ /* Read address values, skipping high cell */
+ cp = of_read_number(range + 1, na - 1);
+ s = of_read_number(range + na + pna, ns);
+ da = of_read_number(addr + 1, na - 1);
+
+ pr_debug("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
+
+ if (da < cp || da >= (cp + s))
+ return OF_BAD_ADDR;
+ return da - cp;
+}
+
+static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
+{
+ return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static unsigned int of_bus_isa_get_flags(const u32 *addr)
+{
+ unsigned int flags = 0;
+ u32 w = addr[0];
+
+ if (w & 1)
+ flags |= IORESOURCE_IO;
+ else
+ flags |= IORESOURCE_MEM;
+ return flags;
+}
+
+/*
+ * Array of bus specific translators
+ */
+
+static struct of_bus of_busses[] = {
+#ifdef CONFIG_PCI
+ /* PCI */
+ {
+ .name = "pci",
+ .addresses = "assigned-addresses",
+ .match = of_bus_pci_match,
+ .count_cells = of_bus_pci_count_cells,
+ .map = of_bus_pci_map,
+ .translate = of_bus_pci_translate,
+ .get_flags = of_bus_pci_get_flags,
+ },
+#endif /* CONFIG_PCI */
+ /* ISA */
+ {
+ .name = "isa",
+ .addresses = "reg",
+ .match = of_bus_isa_match,
+ .count_cells = of_bus_isa_count_cells,
+ .map = of_bus_isa_map,
+ .translate = of_bus_isa_translate,
+ .get_flags = of_bus_isa_get_flags,
+ },
+ /* Default */
+ {
+ .name = "default",
+ .addresses = "reg",
+ .match = NULL,
+ .count_cells = of_bus_default_count_cells,
+ .map = of_bus_default_map,
+ .translate = of_bus_default_translate,
+ .get_flags = of_bus_default_get_flags,
+ },
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(of_busses); i++)
+ if (!of_busses[i].match || of_busses[i].match(np))
+ return &of_busses[i];
+ BUG();
+ return NULL;
+}
+
+static int of_translate_one(struct device_node *parent, struct of_bus *bus,
+ struct of_bus *pbus, u32 *addr,
+ int na, int ns, int pna)
+{
+ const u32 *ranges;
+ unsigned int rlen;
+ int rone;
+ u64 offset = OF_BAD_ADDR;
+
+ /* Normally, an absence of a "ranges" property means we are
+ * crossing a non-translatable boundary, and thus the addresses
+ * below the current not cannot be converted to CPU physical ones.
+ * Unfortunately, while this is very clear in the spec, it's not
+ * what Apple understood, and they do have things like /uni-n or
+ * /ht nodes with no "ranges" property and a lot of perfectly
+ * useable mapped devices below them. Thus we treat the absence of
+ * "ranges" as equivalent to an empty "ranges" property which means
+ * a 1:1 translation at that level. It's up to the caller not to try
+ * to translate addresses that aren't supposed to be translated in
+ * the first place. --BenH.
+ */
+ ranges = of_get_property(parent, "ranges", (int *) &rlen);
+ if (ranges == NULL || rlen == 0) {
+ offset = of_read_number(addr, na);
+ memset(addr, 0, pna * 4);
+ pr_debug("OF: no ranges, 1:1 translation\n");
+ goto finish;
+ }
+
+ pr_debug("OF: walking ranges...\n");
+
+ /* Now walk through the ranges */
+ rlen /= 4;
+ rone = na + pna + ns;
+ for (; rlen >= rone; rlen -= rone, ranges += rone) {
+ offset = bus->map(addr, ranges, na, ns, pna);
+ if (offset != OF_BAD_ADDR)
+ break;
+ }
+ if (offset == OF_BAD_ADDR) {
+ pr_debug("OF: not found !\n");
+ return 1;
+ }
+ memcpy(addr, ranges + na, 4 * pna);
+
+ finish:
+ of_dump_addr("OF: parent translation for:", addr, pna);
+ pr_debug("OF: with offset: "PRu64"\n", offset);
+
+ /* Translate it into parent bus space */
+ return pbus->translate(addr, offset, pna);
+}
+
+/*
+ * Translate an address from the device-tree into a CPU physical address,
+ * this walks up the tree and applies the various bus mappings on the
+ * way.
+ *
+ * Note: We consider that crossing any level with #size-cells == 0 to mean
+ * that translation is impossible (that is we are not dealing with a value
+ * that can be mapped to a cpu physical address). This is not really specified
+ * that way, but this is traditionally the way IBM at least do things
+ */
+u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
+{
+ struct device_node *parent = NULL;
+ struct of_bus *bus, *pbus;
+ u32 addr[OF_MAX_ADDR_CELLS];
+ int na, ns, pna, pns;
+ u64 result = OF_BAD_ADDR;
+
+ pr_debug("OF: ** translation for device %s **\n", dev->full_name);
+
+ /* Increase refcount at current level */
+ of_node_get(dev);
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ goto bail;
+ bus = of_match_bus(parent);
+
+ /* Cound address cells & copy address locally */
+ bus->count_cells(dev, &na, &ns);
+ if (!OF_CHECK_COUNTS(na, ns)) {
+ printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+ dev->full_name);
+ goto bail;
+ }
+ memcpy(addr, in_addr, na * 4);
+
+ pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
+ bus->name, na, ns, parent->full_name);
+ of_dump_addr("OF: translating address:", addr, na);
+
+ /* Translate */
+ for (;;) {
+ /* Switch to parent bus */
+ of_node_put(dev);
+ dev = parent;
+ parent = of_get_parent(dev);
+
+ /* If root, we have finished */
+ if (parent == NULL) {
+ pr_debug("OF: reached root node\n");
+ result = of_read_number(addr, na);
+ break;
+ }
+
+ /* Get new parent bus and counts */
+ pbus = of_match_bus(parent);
+ pbus->count_cells(dev, &pna, &pns);
+ if (!OF_CHECK_COUNTS(pna, pns)) {
+ printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+ dev->full_name);
+ break;
+ }
+
+ pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
+ pbus->name, pna, pns, parent->full_name);
+
+ /* Apply bus translation */
+ if (of_translate_one(dev, bus, pbus, addr, na, ns, pna))
+ break;
+
+ /* Complete the move up one level */
+ na = pna;
+ ns = pns;
+ bus = pbus;
+
+ of_dump_addr("OF: one level translation:", addr, na);
+ }
+ bail:
+ of_node_put(parent);
+ of_node_put(dev);
+
+ return result;
+}
+EXPORT_SYMBOL(of_translate_address);
+
+const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
+ unsigned int *flags)
+{
+ const u32 *prop;
+ unsigned int psize;
+ struct device_node *parent;
+ struct of_bus *bus;
+ int onesize, i, na, ns;
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return NULL;
+ bus = of_match_bus(parent);
+ bus->count_cells(dev, &na, &ns);
+ of_node_put(parent);
+ if (!OF_CHECK_COUNTS(na, ns))
+ return NULL;
+
+ /* Get "reg" or "assigned-addresses" property */
+ prop = of_get_property(dev, bus->addresses, (int *) &psize);
+ if (prop == NULL)
+ return NULL;
+ psize /= 4;
+
+ onesize = na + ns;
+ for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+ if (i == index) {
+ if (size)
+ *size = of_read_number(prop + na, ns);
+ if (flags)
+ *flags = bus->get_flags(prop);
+ return prop;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_address);
+
+static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
+ u64 size, unsigned int flags,
+ struct resource *r)
+{
+ u64 taddr;
+
+ if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+ return -EINVAL;
+ taddr = of_translate_address(dev, addrp);
+ if (taddr == OF_BAD_ADDR)
+ return -EINVAL;
+ memset(r, 0, sizeof(struct resource));
+ if (flags & IORESOURCE_IO) {
+ unsigned long port;
+ port = -1; /* pci_address_to_pio(taddr); */
+ if (port == (unsigned long)-1)
+ return -EINVAL;
+ r->start = port;
+ r->end = port + size - 1;
+ } else {
+ r->start = taddr;
+ r->end = taddr + size - 1;
+ }
+ r->flags = flags;
+ r->name = dev->name;
+ return 0;
+}
+
+int of_address_to_resource(struct device_node *dev, int index,
+ struct resource *r)
+{
+ const u32 *addrp;
+ u64 size;
+ unsigned int flags;
+
+ addrp = of_get_address(dev, index, &size, &flags);
+ if (addrp == NULL)
+ return -EINVAL;
+ return __of_address_to_resource(dev, addrp, size, flags, r);
+}
+EXPORT_SYMBOL_GPL(of_address_to_resource);
+
+void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
+ unsigned long *busno, unsigned long *phys, unsigned long *size)
+{
+ const u32 *dma_window;
+ u32 cells;
+ const unsigned char *prop;
+
+ dma_window = dma_window_prop;
+
+ /* busno is always one cell */
+ *busno = *(dma_window++);
+
+ prop = of_get_property(dn, "ibm,#dma-address-cells", NULL);
+ if (!prop)
+ prop = of_get_property(dn, "#address-cells", NULL);
+
+ cells = prop ? *(u32 *)prop : of_n_addr_cells(dn);
+ *phys = of_read_number(dma_window, cells);
+
+ dma_window += cells;
+
+ prop = of_get_property(dn, "ibm,#dma-size-cells", NULL);
+ cells = prop ? *(u32 *)prop : of_n_size_cells(dn);
+ *size = of_read_number(dma_window, cells);
+}
+
+/*
+ * Interrupt remapper
+ */
+
+static unsigned int of_irq_workarounds;
+static struct device_node *of_irq_dflt_pic;
+
+static struct device_node *of_irq_find_parent(struct device_node *child)
+{
+ struct device_node *p;
+ const phandle *parp;
+
+ if (!of_node_get(child))
+ return NULL;
+
+ do {
+ parp = of_get_property(child, "interrupt-parent", NULL);
+ if (parp == NULL)
+ p = of_get_parent(child);
+ else {
+ if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
+ p = of_node_get(of_irq_dflt_pic);
+ else
+ p = of_find_node_by_phandle(*parp);
+ }
+ of_node_put(child);
+ child = p;
+ } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
+
+ return p;
+}
+
+/* This doesn't need to be called if you don't have any special workaround
+ * flags to pass
+ */
+void of_irq_map_init(unsigned int flags)
+{
+ of_irq_workarounds = flags;
+
+ /* OldWorld, don't bother looking at other things */
+ if (flags & OF_IMAP_OLDWORLD_MAC)
+ return;
+
+ /* If we don't have phandles, let's try to locate a default interrupt
+ * controller (happens when booting with BootX). We do a first match
+ * here, hopefully, that only ever happens on machines with one
+ * controller.
+ */
+ if (flags & OF_IMAP_NO_PHANDLE) {
+ struct device_node *np;
+
+ for (np = NULL; (np = of_find_all_nodes(np)) != NULL;) {
+ if (of_get_property(np, "interrupt-controller", NULL)
+ == NULL)
+ continue;
+ /* Skip /chosen/interrupt-controller */
+ if (strcmp(np->name, "chosen") == 0)
+ continue;
+ /* It seems like at least one person on this planet
+ * wants to use BootX on a machine with an AppleKiwi
+ * controller which happens to pretend to be an
+ * interrupt controller too.
+ */
+ if (strcmp(np->name, "AppleKiwi") == 0)
+ continue;
+ /* I think we found one ! */
+ of_irq_dflt_pic = np;
+ break;
+ }
+ }
+
+}
+
+int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
+ const u32 *addr, struct of_irq *out_irq)
+{
+ struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
+ const u32 *tmp, *imap, *imask;
+ u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
+ int imaplen, match, i;
+
+ pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],"
+ "ointsize=%d\n",
+ parent->full_name, intspec[0], intspec[1], ointsize);
+
+ ipar = of_node_get(parent);
+
+ /* First get the #interrupt-cells property of the current cursor
+ * that tells us how to interpret the passed-in intspec. If there
+ * is none, we are nice and just walk up the tree
+ */
+ do {
+ tmp = of_get_property(ipar, "#interrupt-cells", NULL);
+ if (tmp != NULL) {
+ intsize = *tmp;
+ break;
+ }
+ tnode = ipar;
+ ipar = of_irq_find_parent(ipar);
+ of_node_put(tnode);
+ } while (ipar);
+ if (ipar == NULL) {
+ pr_debug(" -> no parent found !\n");
+ goto fail;
+ }
+
+ pr_debug("of_irq_map_raw: ipar=%s, size=%d\n",
+ ipar->full_name, intsize);
+
+ if (ointsize != intsize)
+ return -EINVAL;
+
+ /* Look for this #address-cells. We have to implement the old linux
+ * trick of looking for the parent here as some device-trees rely on it
+ */
+ old = of_node_get(ipar);
+ do {
+ tmp = of_get_property(old, "#address-cells", NULL);
+ tnode = of_get_parent(old);
+ of_node_put(old);
+ old = tnode;
+ } while (old && tmp == NULL);
+ of_node_put(old);
+ old = NULL;
+ addrsize = (tmp == NULL) ? 2 : *tmp;
+
+ pr_debug(" -> addrsize=%d\n", addrsize);
+
+ /* Now start the actual "proper" walk of the interrupt tree */
+ while (ipar != NULL) {
+ /* Now check if cursor is an interrupt-controller and if it is
+ * then we are done
+ */
+ if (of_get_property(ipar, "interrupt-controller", NULL) !=
+ NULL) {
+ pr_debug(" -> got it !\n");
+ memcpy(out_irq->specifier, intspec,
+ intsize * sizeof(u32));
+ out_irq->size = intsize;
+ out_irq->controller = ipar;
+ of_node_put(old);
+ return 0;
+ }
+
+ /* Now look for an interrupt-map */
+ imap = of_get_property(ipar, "interrupt-map", &imaplen);
+ /* No interrupt map, check for an interrupt parent */
+ if (imap == NULL) {
+ pr_debug(" -> no map, getting parent\n");
+ newpar = of_irq_find_parent(ipar);
+ goto skiplevel;
+ }
+ imaplen /= sizeof(u32);
+
+ /* Look for a mask */
+ imask = of_get_property(ipar, "interrupt-map-mask", NULL);
+
+ /* If we were passed no "reg" property and we attempt to parse
+ * an interrupt-map, then #address-cells must be 0.
+ * Fail if it's not.
+ */
+ if (addr == NULL && addrsize != 0) {
+ pr_debug(" -> no reg passed in when needed !\n");
+ goto fail;
+ }
+
+ /* Parse interrupt-map */
+ match = 0;
+ while (imaplen > (addrsize + intsize + 1) && !match) {
+ /* Compare specifiers */
+ match = 1;
+ for (i = 0; i < addrsize && match; ++i) {
+ u32 mask = imask ? imask[i] : 0xffffffffu;
+ match = ((addr[i] ^ imap[i]) & mask) == 0;
+ }
+ for (; i < (addrsize + intsize) && match; ++i) {
+ u32 mask = imask ? imask[i] : 0xffffffffu;
+ match =
+ ((intspec[i-addrsize] ^ imap[i])
+ & mask) == 0;
+ }
+ imap += addrsize + intsize;
+ imaplen -= addrsize + intsize;
+
+ pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
+
+ /* Get the interrupt parent */
+ if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
+ newpar = of_node_get(of_irq_dflt_pic);
+ else
+ newpar =
+ of_find_node_by_phandle((phandle)*imap);
+ imap++;
+ --imaplen;
+
+ /* Check if not found */
+ if (newpar == NULL) {
+ pr_debug(" -> imap parent not found !\n");
+ goto fail;
+ }
+
+ /* Get #interrupt-cells and #address-cells of new
+ * parent
+ */
+ tmp = of_get_property(newpar, "#interrupt-cells", NULL);
+ if (tmp == NULL) {
+ pr_debug(" -> parent lacks "
+ "#interrupt-cells!\n");
+ goto fail;
+ }
+ newintsize = *tmp;
+ tmp = of_get_property(newpar, "#address-cells", NULL);
+ newaddrsize = (tmp == NULL) ? 0 : *tmp;
+
+ pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
+ newintsize, newaddrsize);
+
+ /* Check for malformed properties */
+ if (imaplen < (newaddrsize + newintsize))
+ goto fail;
+
+ imap += newaddrsize + newintsize;
+ imaplen -= newaddrsize + newintsize;
+
+ pr_debug(" -> imaplen=%d\n", imaplen);
+ }
+ if (!match)
+ goto fail;
+
+ of_node_put(old);
+ old = of_node_get(newpar);
+ addrsize = newaddrsize;
+ intsize = newintsize;
+ intspec = imap - intsize;
+ addr = intspec - addrsize;
+
+skiplevel:
+ /* Iterate again with new parent */
+ pr_debug(" -> new parent: %s\n",
+ newpar ? newpar->full_name : "<>");
+ of_node_put(ipar);
+ ipar = newpar;
+ newpar = NULL;
+ }
+fail:
+ of_node_put(ipar);
+ of_node_put(old);
+ of_node_put(newpar);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(of_irq_map_raw);
+
+int of_irq_map_one(struct device_node *device,
+ int index, struct of_irq *out_irq)
+{
+ struct device_node *p;
+ const u32 *intspec, *tmp, *addr;
+ u32 intsize, intlen;
+ int res;
+
+ pr_debug("of_irq_map_one: dev=%s, index=%d\n",
+ device->full_name, index);
+
+ /* Get the interrupts property */
+ intspec = of_get_property(device, "interrupts", (int *) &intlen);
+ if (intspec == NULL)
+ return -EINVAL;
+ intlen /= sizeof(u32);
+
+ pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen);
+
+ /* Get the reg property (if any) */
+ addr = of_get_property(device, "reg", NULL);
+
+ /* Look for the interrupt parent. */
+ p = of_irq_find_parent(device);
+ if (p == NULL)
+ return -EINVAL;
+
+ /* Get size of interrupt specifier */
+ tmp = of_get_property(p, "#interrupt-cells", NULL);
+ if (tmp == NULL) {
+ of_node_put(p);
+ return -EINVAL;
+ }
+ intsize = *tmp;
+
+ pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
+
+ /* Check index */
+ if ((index + 1) * intsize > intlen)
+ return -EINVAL;
+
+ /* Get new specifier and map it */
+ res = of_irq_map_raw(p, intspec + index * intsize, intsize,
+ addr, out_irq);
+ of_node_put(p);
+ return res;
+}
+EXPORT_SYMBOL_GPL(of_irq_map_one);
+
+/**
+ * Search the device tree for the best MAC address to use. 'mac-address' is
+ * checked first, because that is supposed to contain to "most recent" MAC
+ * address. If that isn't set, then 'local-mac-address' is checked next,
+ * because that is the default address. If that isn't set, then the obsolete
+ * 'address' is checked, just in case we're using an old device tree.
+ *
+ * Note that the 'address' property is supposed to contain a virtual address of
+ * the register set, but some DTS files have redefined that property to be the
+ * MAC address.
+ *
+ * All-zero MAC addresses are rejected, because those could be properties that
+ * exist in the device tree, but were not set by U-Boot. For example, the
+ * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
+ * addresses. Some older U-Boots only initialized 'local-mac-address'. In
+ * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
+ * but is all zeros.
+*/
+const void *of_get_mac_address(struct device_node *np)
+{
+ struct property *pp;
+
+ pp = of_find_property(np, "mac-address", NULL);
+ if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+ return pp->value;
+
+ pp = of_find_property(np, "local-mac-address", NULL);
+ if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+ return pp->value;
+
+ pp = of_find_property(np, "address", NULL);
+ if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+ return pp->value;
+
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_mac_address);
+
+int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
+{
+ struct of_irq out_irq;
+ int irq;
+ int res;
+
+ res = of_irq_map_one(dev, index, &out_irq);
+
+ /* Get irq for the device */
+ if (res) {
+ pr_debug("IRQ not found... code = %d", res);
+ return NO_IRQ;
+ }
+ /* Assuming single interrupt controller... */
+ irq = out_irq.specifier[0];
+
+ pr_debug("IRQ found = %d", irq);
+
+ /* Only dereference the resource if both the
+ * resource and the irq are valid. */
+ if (r && irq != NO_IRQ) {
+ r->start = r->end = irq;
+ r->flags = IORESOURCE_IRQ;
+ }
+
+ return irq;
+}
+EXPORT_SYMBOL_GPL(of_irq_to_resource);
+
+void __iomem *of_iomap(struct device_node *np, int index)
+{
+ struct resource res;
+
+ if (of_address_to_resource(np, index, &res))
+ return NULL;
+
+ return ioremap(res.start, 1 + res.end - res.start);
+}
+EXPORT_SYMBOL(of_iomap);
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c
new file mode 100644
index 00000000000..b86aa623e36
--- /dev/null
+++ b/arch/microblaze/kernel/ptrace.c
@@ -0,0 +1,181 @@
+/*
+ * `ptrace' system call
+ *
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2004-2007 John Williams <john.williams@petalogix.com>
+ *
+ * derived from arch/v850/kernel/ptrace.c
+ *
+ * Copyright (C) 2002,03 NEC Electronics Corporation
+ * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
+ *
+ * Derived from arch/mips/kernel/ptrace.c:
+ *
+ * Copyright (C) 1992 Ross Biro
+ * Copyright (C) Linus Torvalds
+ * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999 MIPS Technologies, 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/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/ptrace.h>
+#include <linux/signal.h>
+
+#include <linux/errno.h>
+#include <asm/processor.h>
+#include <linux/uaccess.h>
+#include <asm/asm-offsets.h>
+
+/* Returns the address where the register at REG_OFFS in P is stashed away. */
+static microblaze_reg_t *reg_save_addr(unsigned reg_offs,
+ struct task_struct *t)
+{
+ struct pt_regs *regs;
+
+ /*
+ * Three basic cases:
+ *
+ * (1) A register normally saved before calling the scheduler, is
+ * available in the kernel entry pt_regs structure at the top
+ * of the kernel stack. The kernel trap/irq exit path takes
+ * care to save/restore almost all registers for ptrace'd
+ * processes.
+ *
+ * (2) A call-clobbered register, where the process P entered the
+ * kernel via [syscall] trap, is not stored anywhere; that's
+ * OK, because such registers are not expected to be preserved
+ * when the trap returns anyway (so we don't actually bother to
+ * test for this case).
+ *
+ * (3) A few registers not used at all by the kernel, and so
+ * normally never saved except by context-switches, are in the
+ * context switch state.
+ */
+
+ /* Register saved during kernel entry (or not available). */
+ regs = task_pt_regs(t);
+
+ return (microblaze_reg_t *)((char *)regs + reg_offs);
+}
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+{
+ int rval;
+ unsigned long val = 0;
+ unsigned long copied;
+
+ switch (request) {
+ case PTRACE_PEEKTEXT: /* read word at location addr. */
+ case PTRACE_PEEKDATA:
+ pr_debug("PEEKTEXT/PEEKDATA at %08lX\n", addr);
+ copied = access_process_vm(child, addr, &val, sizeof(val), 0);
+ rval = -EIO;
+ if (copied != sizeof(val))
+ break;
+ rval = put_user(val, (unsigned long *)data);
+ break;
+
+ case PTRACE_POKETEXT: /* write the word at location addr. */
+ case PTRACE_POKEDATA:
+ pr_debug("POKETEXT/POKEDATA to %08lX\n", addr);
+ rval = 0;
+ if (access_process_vm(child, addr, &data, sizeof(data), 1)
+ == sizeof(data))
+ break;
+ rval = -EIO;
+ break;
+
+ /* Read/write the word at location ADDR in the registers. */
+ case PTRACE_PEEKUSR:
+ case PTRACE_POKEUSR:
+ pr_debug("PEEKUSR/POKEUSR : 0x%08lx\n", addr);
+ rval = 0;
+ if (addr >= PT_SIZE && request == PTRACE_PEEKUSR) {
+ /*
+ * Special requests that don't actually correspond
+ * to offsets in struct pt_regs.
+ */
+ if (addr == PT_TEXT_ADDR) {
+ val = child->mm->start_code;
+ } else if (addr == PT_DATA_ADDR) {
+ val = child->mm->start_data;
+ } else if (addr == PT_TEXT_LEN) {
+ val = child->mm->end_code
+ - child->mm->start_code;
+ } else {
+ rval = -EIO;
+ }
+ } else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
+ microblaze_reg_t *reg_addr = reg_save_addr(addr, child);
+ if (request == PTRACE_PEEKUSR)
+ val = *reg_addr;
+ else
+ *reg_addr = data;
+ } else
+ rval = -EIO;
+
+ if (rval == 0 && request == PTRACE_PEEKUSR)
+ rval = put_user(val, (unsigned long *)data);
+ break;
+ /* Continue and stop at next (return from) syscall */
+ case PTRACE_SYSCALL:
+ pr_debug("PTRACE_SYSCALL\n");
+ case PTRACE_SINGLESTEP:
+ pr_debug("PTRACE_SINGLESTEP\n");
+ /* Restart after a signal. */
+ case PTRACE_CONT:
+ pr_debug("PTRACE_CONT\n");
+ rval = -EIO;
+ if (!valid_signal(data))
+ break;
+
+ if (request == PTRACE_SYSCALL)
+ set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ else
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+
+ child->exit_code = data;
+ pr_debug("wakeup_process\n");
+ wake_up_process(child);
+ rval = 0;
+ break;
+
+ /*
+ * make the child exit. Best I can do is send it a sigkill.
+ * perhaps it should be put in the status that it wants to
+ * exit.
+ */
+ case PTRACE_KILL:
+ pr_debug("PTRACE_KILL\n");
+ rval = 0;
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
+ break;
+ child->exit_code = SIGKILL;
+ wake_up_process(child);
+ break;
+
+ case PTRACE_DETACH: /* detach a process that was attached. */
+ pr_debug("PTRACE_DETACH\n");
+ rval = ptrace_detach(child, data);
+ break;
+ default:
+ /* rval = ptrace_request(child, request, addr, data); noMMU */
+ rval = -EIO;
+ }
+ return rval;
+}
+
+void ptrace_disable(struct task_struct *child)
+{
+ /* nothing to do */
+}
diff --git a/arch/microblaze/kernel/selfmod.c b/arch/microblaze/kernel/selfmod.c
new file mode 100644
index 00000000000..89508bdc9f3
--- /dev/null
+++ b/arch/microblaze/kernel/selfmod.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009 PetaLogix
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/interrupt.h>
+#include <asm/selfmod.h>
+
+#undef DEBUG
+
+#if __GNUC__ > 3
+#error GCC 4 unsupported SELFMOD. Please disable SELFMOD from menuconfig.
+#endif
+
+#define OPCODE_IMM 0xB0000000
+#define OPCODE_LWI 0xE8000000
+#define OPCODE_LWI_MASK 0xEC000000
+#define OPCODE_RTSD 0xB60F0008 /* return from func: rtsd r15, 8 */
+#define OPCODE_ADDIK 0x30000000
+#define OPCODE_ADDIK_MASK 0xFC000000
+
+#define IMM_BASE (OPCODE_IMM | (BARRIER_BASE_ADDR >> 16))
+#define LWI_BASE (OPCODE_LWI | (BARRIER_BASE_ADDR & 0x0000ff00))
+#define LWI_BASE_MASK (OPCODE_LWI_MASK | (BARRIER_BASE_ADDR & 0x0000ff00))
+#define ADDIK_BASE (OPCODE_ADDIK | (BARRIER_BASE_ADDR & 0x0000ff00))
+#define ADDIK_BASE_MASK (OPCODE_ADDIK_MASK | (BARRIER_BASE_ADDR & 0x0000ff00))
+
+#define MODIFY_INSTR { \
+ pr_debug("%s: curr instr, (%d):0x%x, next(%d):0x%x\n", \
+ __func__, i, addr[i], i + 1, addr[i + 1]); \
+ addr[i] = OPCODE_IMM + (base >> 16); \
+ /* keep instruction opcode and add only last 16bits */ \
+ addr[i + 1] = (addr[i + 1] & 0xffff00ff) + (base & 0xffff); \
+ __invalidate_icache(addr[i]); \
+ __invalidate_icache(addr[i + 1]); \
+ pr_debug("%s: hack instr, (%d):0x%x, next(%d):0x%x\n", \
+ __func__, i, addr[i], i + 1, addr[i + 1]); }
+
+/* NOTE
+ * self-modified part of code for improvement of interrupt controller
+ * save instruction in interrupt rutine
+ */
+void selfmod_function(const int *arr_fce, const unsigned int base)
+{
+ unsigned int flags, i, j, *addr = NULL;
+
+ local_irq_save(flags);
+ __disable_icache();
+
+ /* zero terminated array */
+ for (j = 0; arr_fce[j] != 0; j++) {
+ /* get start address of function */
+ addr = (unsigned int *) arr_fce[j];
+ pr_debug("%s: func(%d) at 0x%x\n",
+ __func__, j, (unsigned int) addr);
+ for (i = 0; ; i++) {
+ pr_debug("%s: instruction code at %d: 0x%x\n",
+ __func__, i, addr[i]);
+ if (addr[i] == IMM_BASE) {
+ /* detecting of lwi (0xE8) or swi (0xF8) instr
+ * I can detect both opcode with one mask */
+ if ((addr[i + 1] & LWI_BASE_MASK) == LWI_BASE) {
+ MODIFY_INSTR;
+ } else /* detection addik for ack */
+ if ((addr[i + 1] & ADDIK_BASE_MASK) ==
+ ADDIK_BASE) {
+ MODIFY_INSTR;
+ }
+ } else if (addr[i] == OPCODE_RTSD) {
+ /* return from function means end of function */
+ pr_debug("%s: end of array %d\n", __func__, i);
+ break;
+ }
+ }
+ }
+ local_irq_restore(flags);
+} /* end of self-modified code */
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
new file mode 100644
index 00000000000..eb6b41758e2
--- /dev/null
+++ b/arch/microblaze/kernel/setup.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/cpu.h>
+#include <linux/initrd.h>
+#include <linux/console.h>
+#include <linux/debugfs.h>
+
+#include <asm/setup.h>
+#include <asm/sections.h>
+#include <asm/page.h>
+#include <linux/io.h>
+#include <linux/bug.h>
+#include <linux/param.h>
+#include <linux/cache.h>
+#include <asm/cacheflush.h>
+#include <asm/entry.h>
+#include <asm/cpuinfo.h>
+
+#include <asm/system.h>
+#include <asm/prom.h>
+#include <asm/pgtable.h>
+
+DEFINE_PER_CPU(unsigned int, KSP); /* Saved kernel stack pointer */
+DEFINE_PER_CPU(unsigned int, KM); /* Kernel/user mode */
+DEFINE_PER_CPU(unsigned int, ENTRY_SP); /* Saved SP on kernel entry */
+DEFINE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */
+DEFINE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */
+
+unsigned int boot_cpuid;
+char cmd_line[COMMAND_LINE_SIZE];
+
+void __init setup_arch(char **cmdline_p)
+{
+#ifdef CONFIG_CMDLINE_FORCE
+ strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+ strlcpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+#endif
+ *cmdline_p = cmd_line;
+
+ console_verbose();
+
+ unflatten_device_tree();
+
+ /* NOTE I think that this function is not necessary to call */
+ /* irq_early_init(); */
+ setup_cpuinfo();
+
+ __invalidate_icache_all();
+ __enable_icache();
+
+ __invalidate_dcache_all();
+ __enable_dcache();
+
+ panic_timeout = 120;
+
+ setup_memory();
+
+#if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER)
+ printk(KERN_NOTICE "Self modified code enable\n");
+#endif
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_XILINX_CONSOLE)
+ conswitchp = &xil_con;
+#elif defined(CONFIG_DUMMY_CONSOLE)
+ conswitchp = &dummy_con;
+#endif
+#endif
+}
+
+#ifdef CONFIG_MTD_UCLINUX
+/* Handle both romfs and cramfs types, without generating unnecessary
+ code (ie no point checking for CRAMFS if it's not even enabled) */
+inline unsigned get_romfs_len(unsigned *addr)
+{
+#ifdef CONFIG_ROMFS_FS
+ if (memcmp(&addr[0], "-rom1fs-", 8) == 0) /* romfs */
+ return be32_to_cpu(addr[2]);
+#endif
+
+#ifdef CONFIG_CRAMFS
+ if (addr[0] == le32_to_cpu(0x28cd3d45)) /* cramfs */
+ return le32_to_cpu(addr[1]);
+#endif
+ return 0;
+}
+#endif /* CONFIG_MTD_UCLINUX_EBSS */
+
+void __init machine_early_init(const char *cmdline, unsigned int ram,
+ unsigned int fdt)
+{
+ unsigned long *src, *dst = (unsigned long *)0x0;
+
+/* clearing bss section */
+ memset(__bss_start, 0, __bss_stop-__bss_start);
+ memset(_ssbss, 0, _esbss-_ssbss);
+
+ /*
+ * Copy command line passed from bootloader, or use default
+ * if none provided, or forced
+ */
+#ifndef CONFIG_CMDLINE_BOOL
+ if (cmdline && cmdline[0] != '\0')
+ strlcpy(cmd_line, cmdline, COMMAND_LINE_SIZE);
+#endif
+
+/* initialize device tree for usage in early_printk */
+ early_init_devtree((void *)_fdt_start);
+
+#ifdef CONFIG_EARLY_PRINTK
+ setup_early_printk(NULL);
+#endif
+
+ early_printk("Ramdisk addr 0x%08x, FDT 0x%08x\n", ram, fdt);
+ printk(KERN_NOTICE "Found FDT at 0x%08x\n", fdt);
+
+#ifdef CONFIG_MTD_UCLINUX
+ {
+ int size;
+ unsigned int romfs_base;
+ romfs_base = (ram ? ram : (unsigned int)&__init_end);
+ /* if CONFIG_MTD_UCLINUX_EBSS is defined, assume ROMFS is at the
+ * end of kernel, which is ROMFS_LOCATION defined above. */
+ size = PAGE_ALIGN(get_romfs_len((unsigned *)romfs_base));
+ early_printk("Found romfs @ 0x%08x (0x%08x)\n",
+ romfs_base, size);
+ early_printk("#### klimit %p ####\n", klimit);
+ BUG_ON(size < 0); /* What else can we do? */
+
+ /* Use memmove to handle likely case of memory overlap */
+ early_printk("Moving 0x%08x bytes from 0x%08x to 0x%08x\n",
+ size, romfs_base, (unsigned)&_ebss);
+ memmove(&_ebss, (int *)romfs_base, size);
+
+ /* update klimit */
+ klimit += PAGE_ALIGN(size);
+ early_printk("New klimit: 0x%08x\n", (unsigned)klimit);
+ }
+#endif
+
+ for (src = __ivt_start; src < __ivt_end; src++, dst++)
+ *dst = *src;
+
+ /* Initialize global data */
+ per_cpu(KM, 0) = 0x1; /* We start in kernel mode */
+ per_cpu(CURRENT_SAVE, 0) = (unsigned long)current;
+}
+
+#ifdef CONFIG_DEBUG_FS
+struct dentry *of_debugfs_root;
+
+static int microblaze_debugfs_init(void)
+{
+ of_debugfs_root = debugfs_create_dir("microblaze", NULL);
+
+ return of_debugfs_root == NULL;
+}
+arch_initcall(microblaze_debugfs_init);
+#endif
+
+void machine_restart(char *cmd)
+{
+ printk(KERN_NOTICE "Machine restart...\n");
+ dump_stack();
+ while (1)
+ ;
+}
+
+void machine_shutdown(void)
+{
+ printk(KERN_NOTICE "Machine shutdown...\n");
+ while (1)
+ ;
+}
+
+void machine_halt(void)
+{
+ printk(KERN_NOTICE "Machine halt...\n");
+ while (1)
+ ;
+}
+
+void machine_power_off(void)
+{
+ printk(KERN_NOTICE "Machine power off...\n");
+ while (1)
+ ;
+}
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
new file mode 100644
index 00000000000..3889cf45fa7
--- /dev/null
+++ b/arch/microblaze/kernel/signal.c
@@ -0,0 +1,537 @@
+/*
+ * Signal handling
+ *
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2003,2004 John Williams <jwilliams@itee.uq.edu.au>
+ * Copyright (C) 2001 NEC Corporation
+ * Copyright (C) 2001 Miles Bader <miles@gnu.org>
+ * Copyright (C) 1999,2000 Niibe Yutaka & Kaz Kojima
+ * Copyright (C) 1991,1992 Linus Torvalds
+ *
+ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
+ *
+ * This file was was derived from the sh version, arch/sh/kernel/signal.c
+ *
+ * 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/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/personality.h>
+#include <linux/percpu.h>
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/ucontext.h>
+#include <linux/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <linux/syscalls.h>
+#include <asm/cacheflush.h>
+#include <asm/syscalls.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int
+sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs)
+{
+ sigset_t saveset;
+
+ mask &= _BLOCKABLE;
+ spin_lock_irq(&current->sighand->siglock);
+ saveset = current->blocked;
+ siginitset(&current->blocked, mask);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ regs->r3 = -EINTR;
+ while (1) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ if (do_signal(regs, &saveset, 1))
+ return -EINTR;
+ }
+}
+
+asmlinkage int
+sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
+ struct pt_regs *regs)
+{
+ sigset_t saveset, newset;
+
+ /* XXX: Don't preclude handling different sized sigset_t's. */
+ if (sigsetsize != sizeof(sigset_t))
+ return -EINVAL;
+
+ if (copy_from_user(&newset, unewset, sizeof(newset)))
+ return -EFAULT;
+ sigdelsetmask(&newset, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ saveset = current->blocked;
+ current->blocked = newset;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ regs->r3 = -EINTR;
+ while (1) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ if (do_signal(regs, &saveset, 1))
+ return -EINTR;
+ }
+}
+
+asmlinkage int
+sys_sigaction(int sig, const struct old_sigaction *act,
+ struct old_sigaction *oact)
+{
+ struct k_sigaction new_ka, old_ka;
+ int ret;
+
+ if (act) {
+ old_sigset_t mask;
+ if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
+ __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+ return -EFAULT;
+ __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+ __get_user(mask, &act->sa_mask);
+ siginitset(&new_ka.sa.sa_mask, mask);
+ }
+
+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+ if (!ret && oact) {
+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+ return -EFAULT;
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+ }
+
+ return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
+ struct pt_regs *regs)
+{
+ return do_sigaltstack(uss, uoss, regs->r1);
+}
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+struct sigframe {
+ struct sigcontext sc;
+ unsigned long extramask[_NSIG_WORDS-1];
+ unsigned long tramp[2]; /* signal trampoline */
+};
+
+struct rt_sigframe {
+ struct siginfo info;
+ struct ucontext uc;
+ unsigned long tramp[2]; /* signal trampoline */
+};
+
+static int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *rval_p)
+{
+ unsigned int err = 0;
+
+#define COPY(x) {err |= __get_user(regs->x, &sc->regs.x); }
+ COPY(r0);
+ COPY(r1);
+ COPY(r2); COPY(r3); COPY(r4); COPY(r5);
+ COPY(r6); COPY(r7); COPY(r8); COPY(r9);
+ COPY(r10); COPY(r11); COPY(r12); COPY(r13);
+ COPY(r14); COPY(r15); COPY(r16); COPY(r17);
+ COPY(r18); COPY(r19); COPY(r20); COPY(r21);
+ COPY(r22); COPY(r23); COPY(r24); COPY(r25);
+ COPY(r26); COPY(r27); COPY(r28); COPY(r29);
+ COPY(r30); COPY(r31);
+ COPY(pc); COPY(ear); COPY(esr); COPY(fsr);
+#undef COPY
+
+ *rval_p = regs->r3;
+
+ return err;
+}
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs)
+{
+ struct sigframe *frame = (struct sigframe *)regs->r1;
+ sigset_t set;
+ int rval;
+
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+
+ if (__get_user(set.sig[0], &frame->sc.oldmask)
+ || (_NSIG_WORDS > 1
+ && __copy_from_user(&set.sig[1], &frame->extramask,
+ sizeof(frame->extramask))))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ if (restore_sigcontext(regs, &frame->sc, &rval))
+ goto badframe;
+ return rval;
+
+badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+{
+ struct rt_sigframe *frame = (struct rt_sigframe *)regs->r1;
+ sigset_t set;
+ stack_t st;
+ int rval;
+
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+
+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
+ goto badframe;
+
+ if (__copy_from_user((void *)&st, &frame->uc.uc_stack, sizeof(st)))
+ goto badframe;
+ /* It is more difficult to avoid calling this function than to
+ call it and ignore errors. */
+ do_sigaltstack(&st, NULL, regs->r1);
+
+ return rval;
+
+badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+/*
+ * Set up a signal frame.
+ */
+
+static int
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+ unsigned long mask)
+{
+ int err = 0;
+
+#define COPY(x) {err |= __put_user(regs->x, &sc->regs.x); }
+ COPY(r0);
+ COPY(r1);
+ COPY(r2); COPY(r3); COPY(r4); COPY(r5);
+ COPY(r6); COPY(r7); COPY(r8); COPY(r9);
+ COPY(r10); COPY(r11); COPY(r12); COPY(r13);
+ COPY(r14); COPY(r15); COPY(r16); COPY(r17);
+ COPY(r18); COPY(r19); COPY(r20); COPY(r21);
+ COPY(r22); COPY(r23); COPY(r24); COPY(r25);
+ COPY(r26); COPY(r27); COPY(r28); COPY(r29);
+ COPY(r30); COPY(r31);
+ COPY(pc); COPY(ear); COPY(esr); COPY(fsr);
+#undef COPY
+
+ err |= __put_user(mask, &sc->oldmask);
+
+ return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+ /* Default to using normal stack */
+ unsigned long sp = regs->r1;
+
+ if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
+ sp = current->sas_ss_sp + current->sas_ss_size;
+
+ return (void *)((sp - frame_size) & -8UL);
+}
+
+static void setup_frame(int sig, struct k_sigaction *ka,
+ sigset_t *set, struct pt_regs *regs)
+{
+ struct sigframe *frame;
+ int err = 0;
+ int signal;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ goto give_sigsegv;
+
+ signal = current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig;
+
+ err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
+
+ if (_NSIG_WORDS > 1) {
+ err |= __copy_to_user(frame->extramask, &set->sig[1],
+ sizeof(frame->extramask));
+ }
+
+ /* Set up to return from userspace. If provided, use a stub
+ already in userspace. */
+ /* minus 8 is offset to cater for "rtsd r15,8" offset */
+ if (ka->sa.sa_flags & SA_RESTORER) {
+ regs->r15 = ((unsigned long)ka->sa.sa_restorer)-8;
+ } else {
+ /* Note, these encodings are _big endian_! */
+
+ /* addi r12, r0, __NR_sigreturn */
+ err |= __put_user(0x31800000 | __NR_sigreturn ,
+ frame->tramp + 0);
+ /* brki r14, 0x8 */
+ err |= __put_user(0xb9cc0008, frame->tramp + 1);
+
+ /* Return from sighandler will jump to the tramp.
+ Negative 8 offset because return is rtsd r15, 8 */
+ regs->r15 = ((unsigned long)frame->tramp)-8;
+
+ __invalidate_cache_sigtramp((unsigned long)frame->tramp);
+ }
+
+ if (err)
+ goto give_sigsegv;
+
+ /* Set up registers for signal handler */
+ regs->r1 = (unsigned long) frame;
+ /* Signal handler args: */
+ regs->r5 = signal; /* Arg 0: signum */
+ regs->r6 = (unsigned long) &frame->sc; /* arg 1: sigcontext */
+
+ /* Offset of 4 to handle microblaze rtid r14, 0 */
+ regs->pc = (unsigned long)ka->sa.sa_handler;
+
+ set_fs(USER_DS);
+
+#ifdef DEBUG_SIG
+ printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
+ current->comm, current->pid, frame, regs->pc);
+#endif
+
+ return;
+
+give_sigsegv:
+ if (sig == SIGSEGV)
+ ka->sa.sa_handler = SIG_DFL;
+ force_sig(SIGSEGV, current);
+}
+
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *set, struct pt_regs *regs)
+{
+ struct rt_sigframe *frame;
+ int err = 0;
+ int signal;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ goto give_sigsegv;
+
+ signal = current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig;
+
+ err |= copy_siginfo_to_user(&frame->info, info);
+
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->uc.uc_flags);
+ err |= __put_user(0, &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->r1),
+ &frame->uc.uc_stack.ss_flags);
+ err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+ err |= setup_sigcontext(&frame->uc.uc_mcontext,
+ regs, set->sig[0]);
+ err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+ /* Set up to return from userspace. If provided, use a stub
+ already in userspace. */
+ /* minus 8 is offset to cater for "rtsd r15,8" */
+ if (ka->sa.sa_flags & SA_RESTORER) {
+ regs->r15 = ((unsigned long)ka->sa.sa_restorer)-8;
+ } else {
+ /* addi r12, r0, __NR_sigreturn */
+ err |= __put_user(0x31800000 | __NR_rt_sigreturn ,
+ frame->tramp + 0);
+ /* brki r14, 0x8 */
+ err |= __put_user(0xb9cc0008, frame->tramp + 1);
+
+ /* Return from sighandler will jump to the tramp.
+ Negative 8 offset because return is rtsd r15, 8 */
+ regs->r15 = ((unsigned long)frame->tramp)-8;
+
+ __invalidate_cache_sigtramp((unsigned long)frame->tramp);
+ }
+
+ if (err)
+ goto give_sigsegv;
+
+ /* Set up registers for signal handler */
+ regs->r1 = (unsigned long) frame;
+ /* Signal handler args: */
+ regs->r5 = signal; /* arg 0: signum */
+ regs->r6 = (unsigned long) &frame->info; /* arg 1: siginfo */
+ regs->r7 = (unsigned long) &frame->uc; /* arg2: ucontext */
+ /* Offset to handle microblaze rtid r14, 0 */
+ regs->pc = (unsigned long)ka->sa.sa_handler;
+
+ set_fs(USER_DS);
+
+#ifdef DEBUG_SIG
+ printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
+ current->comm, current->pid, frame, regs->pc);
+#endif
+
+ return;
+
+give_sigsegv:
+ if (sig == SIGSEGV)
+ ka->sa.sa_handler = SIG_DFL;
+ force_sig(SIGSEGV, current);
+}
+
+/* Handle restarting system calls */
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+ switch (regs->r3) {
+ case -ERESTART_RESTARTBLOCK:
+ case -ERESTARTNOHAND:
+ if (!has_handler)
+ goto do_restart;
+ regs->r3 = -EINTR;
+ break;
+ case -ERESTARTSYS:
+ if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+ regs->r3 = -EINTR;
+ break;
+ }
+ /* fallthrough */
+ case -ERESTARTNOINTR:
+do_restart:
+ /* offset of 4 bytes to re-execute trap (brki) instruction */
+ regs->pc -= 4;
+ break;
+ }
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
+{
+ /* Set up the stack frame */
+ if (ka->sa.sa_flags & SA_SIGINFO)
+ setup_rt_frame(sig, ka, info, oldset, regs);
+ else
+ setup_frame(sig, ka, oldset, regs);
+
+ if (ka->sa.sa_flags & SA_ONESHOT)
+ ka->sa.sa_handler = SIG_DFL;
+
+ if (!(ka->sa.sa_flags & SA_NODEFER)) {
+ spin_lock_irq(&current->sighand->siglock);
+ sigorsets(&current->blocked,
+ &current->blocked, &ka->sa.sa_mask);
+ sigaddset(&current->blocked, sig);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+ }
+}
+
+/*
+ * 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
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals that
+ * the kernel can handle, and then we build all the user-level signal handling
+ * stack-frames in one go after that.
+ */
+int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
+{
+ siginfo_t info;
+ int signr;
+ struct k_sigaction ka;
+#ifdef DEBUG_SIG
+ printk(KERN_INFO "do signal: %p %p %d\n", regs, oldset, in_syscall);
+ printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
+ regs->r12, current_thread_info()->flags);
+#endif
+ /*
+ * We want the common case to go fast, which
+ * is why we may in certain cases get here from
+ * kernel mode. Just return without doing anything
+ * if so.
+ */
+ if (kernel_mode(regs))
+ return 1;
+
+ if (!oldset)
+ oldset = &current->blocked;
+
+ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+ if (signr > 0) {
+ /* Whee! Actually deliver the signal. */
+ if (in_syscall)
+ handle_restart(regs, &ka, 1);
+ handle_signal(signr, &ka, &info, oldset, regs);
+ return 1;
+ }
+
+ if (in_syscall)
+ handle_restart(regs, NULL, 0);
+
+ /* Did we come from a system call? */
+ return 0;
+}
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
new file mode 100644
index 00000000000..ba0568c2cc1
--- /dev/null
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ *
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ * Yasushi SHOJI <yashi@atmark-techno.com>
+ * Tetsuya OHKAWA <tetsuya@atmark-techno.com>
+ *
+ * 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/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/syscalls.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/sys.h>
+#include <linux/ipc.h>
+#include <linux/utsname.h>
+#include <linux/file.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/unistd.h>
+
+#include <asm/syscalls.h>
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly. This will be remove with new toolchain.
+ */
+asmlinkage int
+sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth)
+{
+ int version, ret;
+
+ version = call >> 16; /* hack for backward compatibility */
+ call &= 0xffff;
+
+ ret = -EINVAL;
+ switch (call) {
+ case SEMOP:
+ ret = sys_semop(first, (struct sembuf *)ptr, second);
+ break;
+ case SEMGET:
+ ret = sys_semget(first, second, third);
+ break;
+ case SEMCTL:
+ {
+ union semun fourth;
+
+ if (!ptr)
+ break;
+ ret = (access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT)
+ || (get_user(fourth.__pad, (void **)ptr)) ;
+ if (ret)
+ break;
+ ret = sys_semctl(first, second, third, fourth);
+ break;
+ }
+ case MSGSND:
+ ret = sys_msgsnd(first, (struct msgbuf *) ptr, second, third);
+ break;
+ case MSGRCV:
+ switch (version) {
+ case 0: {
+ struct ipc_kludge tmp;
+
+ if (!ptr)
+ break;
+ ret = (access_ok(VERIFY_READ, ptr, sizeof(tmp))
+ ? 0 : -EFAULT) || copy_from_user(&tmp,
+ (struct ipc_kludge *) ptr, sizeof(tmp));
+ if (ret)
+ break;
+ ret = sys_msgrcv(first, tmp.msgp, second, tmp.msgtyp,
+ third);
+ break;
+ }
+ default:
+ ret = sys_msgrcv(first, (struct msgbuf *) ptr,
+ second, fifth, third);
+ break;
+ }
+ break;
+ case MSGGET:
+ ret = sys_msgget((key_t) first, second);
+ break;
+ case MSGCTL:
+ ret = sys_msgctl(first, second, (struct msqid_ds *) ptr);
+ break;
+ case SHMAT:
+ switch (version) {
+ default: {
+ ulong raddr;
+ ret = access_ok(VERIFY_WRITE, (ulong *) third,
+ sizeof(ulong)) ? 0 : -EFAULT;
+ if (ret)
+ break;
+ ret = do_shmat(first, (char *) ptr, second, &raddr);
+ if (ret)
+ break;
+ ret = put_user(raddr, (ulong *) third);
+ break;
+ }
+ case 1: /* iBCS2 emulator entry point */
+ if (!segment_eq(get_fs(), get_ds()))
+ break;
+ ret = do_shmat(first, (char *) ptr, second,
+ (ulong *) third);
+ break;
+ }
+ break;
+ case SHMDT:
+ ret = sys_shmdt((char *)ptr);
+ break;
+ case SHMGET:
+ ret = sys_shmget(first, second, third);
+ break;
+ case SHMCTL:
+ ret = sys_shmctl(first, second, (struct shmid_ds *) ptr);
+ break;
+ }
+ return -EINVAL;
+}
+
+asmlinkage int sys_vfork(struct pt_regs *regs)
+{
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r1,
+ regs, 0, NULL, NULL);
+}
+
+asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs)
+{
+ if (!stack)
+ stack = regs->r1;
+ return do_fork(flags, stack, regs, 0, NULL, NULL);
+}
+
+asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv,
+ char __user *__user *envp, struct pt_regs *regs)
+{
+ int error;
+ char *filename;
+
+ filename = getname(filenamei);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ goto out;
+ error = do_execve(filename, argv, envp, regs);
+ putname(filename);
+out:
+ return error;
+}
+
+asmlinkage unsigned long
+sys_mmap2(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ struct file *file = NULL;
+ int ret = -EBADF;
+
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ if (!(flags & MAP_ANONYMOUS)) {
+ file = fget(fd);
+ if (!file) {
+ printk(KERN_INFO "no fd in mmap\r\n");
+ goto out;
+ }
+ }
+
+ down_write(&current->mm->mmap_sem);
+ ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+ up_write(&current->mm->mmap_sem);
+ if (file)
+ fput(file);
+out:
+ return ret;
+}
+
+asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, off_t offset)
+{
+ int err = -EINVAL;
+
+ if (offset & ~PAGE_MASK) {
+ printk(KERN_INFO "no pagemask in mmap\r\n");
+ goto out;
+ }
+
+ err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+out:
+ return err;
+}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+ register const char *__a __asm__("r5") = filename;
+ register const void *__b __asm__("r6") = argv;
+ register const void *__c __asm__("r7") = envp;
+ register unsigned long __syscall __asm__("r12") = __NR_execve;
+ register unsigned long __ret __asm__("r3");
+ __asm__ __volatile__ ("brki r14, 0x8"
+ : "=r" (__ret), "=r" (__syscall)
+ : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)
+ : "r4", "r8", "r9",
+ "r10", "r11", "r14", "cc", "memory");
+ return __ret;
+}
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
new file mode 100644
index 00000000000..529b0dbf4fe
--- /dev/null
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -0,0 +1,365 @@
+ENTRY(sys_call_table)
+ .long sys_restart_syscall /* 0 - old "setup()" system call,
+ * used for restarting */
+ .long sys_exit
+ .long sys_ni_syscall /* was fork */
+ .long sys_read
+ .long sys_write
+ .long sys_open /* 5 */
+ .long sys_close
+ .long sys_waitpid
+ .long sys_creat
+ .long sys_link
+ .long sys_unlink /* 10 */
+ .long sys_execve_wrapper
+ .long sys_chdir
+ .long sys_time
+ .long sys_mknod
+ .long sys_chmod /* 15 */
+ .long sys_lchown
+ .long sys_ni_syscall /* old break syscall holder */
+ .long sys_ni_syscall /* old stat */
+ .long sys_lseek
+ .long sys_getpid /* 20 */
+ .long sys_mount
+ .long sys_oldumount
+ .long sys_setuid
+ .long sys_getuid
+ .long sys_stime /* 25 */
+ .long sys_ptrace
+ .long sys_alarm
+ .long sys_ni_syscall /* oldfstat */
+ .long sys_pause
+ .long sys_utime /* 30 */
+ .long sys_ni_syscall /* old stty syscall holder */
+ .long sys_ni_syscall /* old gtty syscall holder */
+ .long sys_access
+ .long sys_nice
+ .long sys_ni_syscall /* 35 - old ftime syscall holder */
+ .long sys_sync
+ .long sys_kill
+ .long sys_rename
+ .long sys_mkdir
+ .long sys_rmdir /* 40 */
+ .long sys_dup
+ .long sys_pipe
+ .long sys_times
+ .long sys_ni_syscall /* old prof syscall holder */
+ .long sys_brk /* 45 */
+ .long sys_setgid
+ .long sys_getgid
+ .long sys_signal
+ .long sys_geteuid
+ .long sys_getegid /* 50 */
+ .long sys_acct
+ .long sys_umount /* recycled never used phys() */
+ .long sys_ni_syscall /* old lock syscall holder */
+ .long sys_ioctl
+ .long sys_fcntl /* 55 */
+ .long sys_ni_syscall /* old mpx syscall holder */
+ .long sys_setpgid
+ .long sys_ni_syscall /* old ulimit syscall holder */
+ .long sys_ni_syscall /* olduname */
+ .long sys_umask /* 60 */
+ .long sys_chroot
+ .long sys_ustat
+ .long sys_dup2
+ .long sys_getppid
+ .long sys_getpgrp /* 65 */
+ .long sys_setsid
+ .long sys_sigaction
+ .long sys_sgetmask
+ .long sys_ssetmask
+ .long sys_setreuid /* 70 */
+ .long sys_setregid
+ .long sys_sigsuspend_wrapper
+ .long sys_sigpending
+ .long sys_sethostname
+ .long sys_setrlimit /* 75 */
+ .long sys_ni_syscall /* old_getrlimit */
+ .long sys_getrusage
+ .long sys_gettimeofday
+ .long sys_settimeofday
+ .long sys_getgroups /* 80 */
+ .long sys_setgroups
+ .long sys_ni_syscall /* old_select */
+ .long sys_symlink
+ .long sys_ni_syscall /* oldlstat */
+ .long sys_readlink /* 85 */
+ .long sys_uselib
+ .long sys_swapon
+ .long sys_reboot
+ .long sys_ni_syscall /* old_readdir */
+ .long sys_mmap /* 90 */ /* old_mmap */
+ .long sys_munmap
+ .long sys_truncate
+ .long sys_ftruncate
+ .long sys_fchmod
+ .long sys_fchown /* 95 */
+ .long sys_getpriority
+ .long sys_setpriority
+ .long sys_ni_syscall /* old profil syscall holder */
+ .long sys_statfs
+ .long sys_fstatfs /* 100 */
+ .long sys_ni_syscall /* ioperm */
+ .long sys_socketcall
+ .long sys_syslog /* operation with system console */
+ .long sys_setitimer
+ .long sys_getitimer /* 105 */
+ .long sys_newstat
+ .long sys_newlstat
+ .long sys_newfstat
+ .long sys_ni_syscall /* uname */
+ .long sys_ni_syscall /* 110 */ /* iopl */
+ .long sys_vhangup
+ .long sys_ni_syscall /* old "idle" system call */
+ .long sys_ni_syscall /* old sys_vm86old */
+ .long sys_wait4
+ .long sys_swapoff /* 115 */
+ .long sys_sysinfo
+ .long sys_ipc
+ .long sys_fsync
+ .long sys_sigreturn_wrapper
+ .long sys_clone_wrapper /* 120 */
+ .long sys_setdomainname
+ .long sys_newuname
+ .long sys_ni_syscall /* modify_ldt */
+ .long sys_adjtimex
+ .long sys_mprotect /* 125: sys_mprotect */
+ .long sys_sigprocmask
+ .long sys_ni_syscall /* old "create_module" */
+ .long sys_init_module
+ .long sys_delete_module
+ .long sys_ni_syscall /* 130: old "get_kernel_syms" */
+ .long sys_quotactl
+ .long sys_getpgid
+ .long sys_fchdir
+ .long sys_bdflush
+ .long sys_sysfs /* 135 */
+ .long sys_personality
+ .long sys_ni_syscall /* reserved for afs_syscall */
+ .long sys_setfsuid
+ .long sys_setfsgid
+ .long sys_llseek /* 140 */
+ .long sys_getdents
+ .long sys_select
+ .long sys_flock
+ .long sys_msync
+ .long sys_readv /* 145 */
+ .long sys_writev
+ .long sys_getsid
+ .long sys_fdatasync
+ .long sys_sysctl
+ .long sys_mlock /* 150: sys_mlock */
+ .long sys_munlock
+ .long sys_mlockall
+ .long sys_munlockall
+ .long sys_sched_setparam
+ .long sys_sched_getparam /* 155 */
+ .long sys_sched_setscheduler
+ .long sys_sched_getscheduler
+ .long sys_sched_yield
+ .long sys_sched_get_priority_max
+ .long sys_sched_get_priority_min /* 160 */
+ .long sys_sched_rr_get_interval
+ .long sys_nanosleep
+ .long sys_mremap
+ .long sys_setresuid
+ .long sys_getresuid /* 165 */
+ .long sys_ni_syscall /* sys_vm86 */
+ .long sys_ni_syscall /* Old sys_query_module */
+ .long sys_poll
+ .long sys_nfsservctl
+ .long sys_setresgid /* 170 */
+ .long sys_getresgid
+ .long sys_prctl
+ .long sys_rt_sigreturn_wrapper
+ .long sys_rt_sigaction
+ .long sys_rt_sigprocmask /* 175 */
+ .long sys_rt_sigpending
+ .long sys_rt_sigtimedwait
+ .long sys_rt_sigqueueinfo
+ .long sys_rt_sigsuspend_wrapper
+ .long sys_pread64 /* 180 */
+ .long sys_pwrite64
+ .long sys_chown
+ .long sys_getcwd
+ .long sys_capget
+ .long sys_capset /* 185 */
+ .long sys_ni_syscall /* sigaltstack */
+ .long sys_sendfile
+ .long sys_ni_syscall /* reserved for streams1 */
+ .long sys_ni_syscall /* reserved for streams2 */
+ .long sys_vfork_wrapper /* 190 */
+ .long sys_getrlimit
+ .long sys_mmap2 /* mmap2 */
+ .long sys_truncate64
+ .long sys_ftruncate64
+ .long sys_stat64 /* 195 */
+ .long sys_lstat64
+ .long sys_fstat64
+ .long sys_lchown
+ .long sys_getuid
+ .long sys_getgid /* 200 */
+ .long sys_geteuid
+ .long sys_getegid
+ .long sys_setreuid
+ .long sys_setregid
+ .long sys_getgroups /* 205 */
+ .long sys_setgroups
+ .long sys_fchown
+ .long sys_setresuid
+ .long sys_getresuid
+ .long sys_setresgid /* 210 */
+ .long sys_getresgid
+ .long sys_chown
+ .long sys_setuid
+ .long sys_setgid
+ .long sys_setfsuid /* 215 */
+ .long sys_setfsgid
+ .long sys_pivot_root
+ .long sys_mincore
+ .long sys_madvise
+ .long sys_getdents64 /* 220 */
+ .long sys_fcntl64
+ .long sys_ni_syscall /* reserved for TUX */
+ .long sys_ni_syscall
+ .long sys_gettid
+ .long sys_readahead /* 225 */
+ .long sys_setxattr
+ .long sys_lsetxattr
+ .long sys_fsetxattr
+ .long sys_getxattr
+ .long sys_lgetxattr /* 230 */
+ .long sys_fgetxattr
+ .long sys_listxattr
+ .long sys_llistxattr
+ .long sys_flistxattr
+ .long sys_removexattr /* 235 */
+ .long sys_lremovexattr
+ .long sys_fremovexattr
+ .long sys_tkill
+ .long sys_sendfile64
+ .long sys_futex /* 240 */
+ .long sys_sched_setaffinity
+ .long sys_sched_getaffinity
+ .long sys_ni_syscall /* set_thread_area */
+ .long sys_ni_syscall /* get_thread_area */
+ .long sys_io_setup /* 245 */
+ .long sys_io_destroy
+ .long sys_io_getevents
+ .long sys_io_submit
+ .long sys_io_cancel
+ .long sys_fadvise64 /* 250 */
+ .long sys_ni_syscall
+ .long sys_exit_group
+ .long sys_lookup_dcookie
+ .long sys_epoll_create
+ .long sys_epoll_ctl /* 255 */
+ .long sys_epoll_wait
+ .long sys_remap_file_pages
+ .long sys_set_tid_address
+ .long sys_timer_create
+ .long sys_timer_settime /* 260 */
+ .long sys_timer_gettime
+ .long sys_timer_getoverrun
+ .long sys_timer_delete
+ .long sys_clock_settime
+ .long sys_clock_gettime /* 265 */
+ .long sys_clock_getres
+ .long sys_clock_nanosleep
+ .long sys_statfs64
+ .long sys_fstatfs64
+ .long sys_tgkill /* 270 */
+ .long sys_utimes
+ .long sys_fadvise64_64
+ .long sys_ni_syscall /* sys_vserver */
+ .long sys_mbind
+ .long sys_get_mempolicy
+ .long sys_set_mempolicy
+ .long sys_mq_open
+ .long sys_mq_unlink
+ .long sys_mq_timedsend
+ .long sys_mq_timedreceive /* 280 */
+ .long sys_mq_notify
+ .long sys_mq_getsetattr
+ .long sys_kexec_load
+ .long sys_waitid
+ .long sys_ni_syscall /* 285 */ /* available */
+ .long sys_add_key
+ .long sys_request_key
+ .long sys_keyctl
+ .long sys_ioprio_set
+ .long sys_ioprio_get /* 290 */
+ .long sys_inotify_init
+ .long sys_inotify_add_watch
+ .long sys_inotify_rm_watch
+ .long sys_ni_syscall /* sys_migrate_pages */
+ .long sys_openat /* 295 */
+ .long sys_mkdirat
+ .long sys_mknodat
+ .long sys_fchownat
+ .long sys_ni_syscall
+ .long sys_fstatat64 /* 300 */
+ .long sys_unlinkat
+ .long sys_renameat
+ .long sys_linkat
+ .long sys_symlinkat
+ .long sys_readlinkat /* 305 */
+ .long sys_fchmodat
+ .long sys_faccessat
+ .long sys_ni_syscall /* pselect6 */
+ .long sys_ni_syscall /* sys_ppoll */
+ .long sys_unshare /* 310 */
+ .long sys_set_robust_list
+ .long sys_get_robust_list
+ .long sys_splice
+ .long sys_sync_file_range
+ .long sys_tee /* 315 */
+ .long sys_vmsplice
+ .long sys_move_pages
+ .long sys_getcpu
+ .long sys_epoll_pwait
+ .long sys_utimensat /* 320 */
+ .long sys_signalfd
+ .long sys_timerfd_create
+ .long sys_eventfd
+ .long sys_fallocate
+ .long sys_semtimedop /* 325 */
+ .long sys_timerfd_settime
+ .long sys_timerfd_gettime
+ .long sys_semctl
+ .long sys_semget
+ .long sys_semop /* 330 */
+ .long sys_msgctl
+ .long sys_msgget
+ .long sys_msgrcv
+ .long sys_msgsnd
+ .long sys_shmat /* 335 */
+ .long sys_shmctl
+ .long sys_shmdt
+ .long sys_shmget
+ .long sys_signalfd4 /* new syscall */
+ .long sys_eventfd2 /* 340 */
+ .long sys_epoll_create1
+ .long sys_dup3
+ .long sys_pipe2
+ .long sys_inotify_init1
+ .long sys_socket /* 345 */
+ .long sys_socketpair
+ .long sys_bind
+ .long sys_listen
+ .long sys_accept
+ .long sys_connect /* 350 */
+ .long sys_getsockname
+ .long sys_getpeername
+ .long sys_sendto
+ .long sys_send
+ .long sys_recvfrom /* 355 */
+ .long sys_recv
+ .long sys_setsockopt
+ .long sys_getsockopt
+ .long sys_shutdown
+ .long sys_sendmsg /* 360 */
+ .long sys_recvmsg
+ .long sys_ni_syscall
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
new file mode 100644
index 00000000000..05a497eefd7
--- /dev/null
+++ b/arch/microblaze/kernel/timer.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/interrupt.h>
+#include <linux/profile.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <asm/cpuinfo.h>
+#include <asm/setup.h>
+#include <asm/prom.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_SELFMOD_TIMER
+#include <asm/selfmod.h>
+#define TIMER_BASE BARRIER_BASE_ADDR
+#else
+static unsigned int timer_baseaddr;
+#define TIMER_BASE timer_baseaddr
+#endif
+
+#define TCSR0 (0x00)
+#define TLR0 (0x04)
+#define TCR0 (0x08)
+#define TCSR1 (0x10)
+#define TLR1 (0x14)
+#define TCR1 (0x18)
+
+#define TCSR_MDT (1<<0)
+#define TCSR_UDT (1<<1)
+#define TCSR_GENT (1<<2)
+#define TCSR_CAPT (1<<3)
+#define TCSR_ARHT (1<<4)
+#define TCSR_LOAD (1<<5)
+#define TCSR_ENIT (1<<6)
+#define TCSR_ENT (1<<7)
+#define TCSR_TINT (1<<8)
+#define TCSR_PWMA (1<<9)
+#define TCSR_ENALL (1<<10)
+
+static inline void microblaze_timer0_stop(void)
+{
+ out_be32(TIMER_BASE + TCSR0, in_be32(TIMER_BASE + TCSR0) & ~TCSR_ENT);
+}
+
+static inline void microblaze_timer0_start_periodic(unsigned long load_val)
+{
+ if (!load_val)
+ load_val = 1;
+ out_be32(TIMER_BASE + TLR0, load_val); /* loading value to timer reg */
+
+ /* load the initial value */
+ out_be32(TIMER_BASE + TCSR0, TCSR_LOAD);
+
+ /* see timer data sheet for detail
+ * !ENALL - don't enable 'em all
+ * !PWMA - disable pwm
+ * TINT - clear interrupt status
+ * ENT- enable timer itself
+ * EINT - enable interrupt
+ * !LOAD - clear the bit to let go
+ * ARHT - auto reload
+ * !CAPT - no external trigger
+ * !GENT - no external signal
+ * UDT - set the timer as down counter
+ * !MDT0 - generate mode
+ */
+ out_be32(TIMER_BASE + TCSR0,
+ TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT);
+}
+
+static inline void microblaze_timer0_start_oneshot(unsigned long load_val)
+{
+ if (!load_val)
+ load_val = 1;
+ out_be32(TIMER_BASE + TLR0, load_val); /* loading value to timer reg */
+
+ /* load the initial value */
+ out_be32(TIMER_BASE + TCSR0, TCSR_LOAD);
+
+ out_be32(TIMER_BASE + TCSR0,
+ TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT);
+}
+
+static int microblaze_timer_set_next_event(unsigned long delta,
+ struct clock_event_device *dev)
+{
+ pr_debug("%s: next event, delta %x\n", __func__, (u32)delta);
+ microblaze_timer0_start_oneshot(delta);
+ return 0;
+}
+
+static void microblaze_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ printk(KERN_INFO "%s: periodic\n", __func__);
+ microblaze_timer0_start_periodic(cpuinfo.freq_div_hz);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ printk(KERN_INFO "%s: oneshot\n", __func__);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ printk(KERN_INFO "%s: unused\n", __func__);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ printk(KERN_INFO "%s: shutdown\n", __func__);
+ microblaze_timer0_stop();
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ printk(KERN_INFO "%s: resume\n", __func__);
+ break;
+ }
+}
+
+static struct clock_event_device clockevent_microblaze_timer = {
+ .name = "microblaze_clockevent",
+ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
+ .shift = 24,
+ .rating = 300,
+ .set_next_event = microblaze_timer_set_next_event,
+ .set_mode = microblaze_timer_set_mode,
+};
+
+static inline void timer_ack(void)
+{
+ out_be32(TIMER_BASE + TCSR0, in_be32(TIMER_BASE + TCSR0));
+}
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_microblaze_timer;
+#ifdef CONFIG_HEART_BEAT
+ heartbeat();
+#endif
+ timer_ack();
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction timer_irqaction = {
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .name = "timer",
+ .dev_id = &clockevent_microblaze_timer,
+};
+
+static __init void microblaze_clockevent_init(void)
+{
+ clockevent_microblaze_timer.mult =
+ div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC,
+ clockevent_microblaze_timer.shift);
+ clockevent_microblaze_timer.max_delta_ns =
+ clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
+ clockevent_microblaze_timer.min_delta_ns =
+ clockevent_delta2ns(1, &clockevent_microblaze_timer);
+ clockevent_microblaze_timer.cpumask = cpumask_of(0);
+ clockevents_register_device(&clockevent_microblaze_timer);
+}
+
+static cycle_t microblaze_read(void)
+{
+ /* reading actual value of timer 1 */
+ return (cycle_t) (in_be32(TIMER_BASE + TCR1));
+}
+
+static struct clocksource clocksource_microblaze = {
+ .name = "microblaze_clocksource",
+ .rating = 300,
+ .read = microblaze_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 24, /* I can shift it */
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init microblaze_clocksource_init(void)
+{
+ clocksource_microblaze.mult =
+ clocksource_hz2mult(cpuinfo.cpu_clock_freq,
+ clocksource_microblaze.shift);
+ if (clocksource_register(&clocksource_microblaze))
+ panic("failed to register clocksource");
+
+ /* stop timer1 */
+ out_be32(TIMER_BASE + TCSR1, in_be32(TIMER_BASE + TCSR1) & ~TCSR_ENT);
+ /* start timer1 - up counting without interrupt */
+ out_be32(TIMER_BASE + TCSR1, TCSR_TINT|TCSR_ENT|TCSR_ARHT);
+ return 0;
+}
+
+void __init time_init(void)
+{
+ u32 irq, i = 0;
+ u32 timer_num = 1;
+ struct device_node *timer = NULL;
+#ifdef CONFIG_SELFMOD_TIMER
+ unsigned int timer_baseaddr = 0;
+ int arr_func[] = {
+ (int)&microblaze_read,
+ (int)&timer_interrupt,
+ (int)&microblaze_clocksource_init,
+ (int)&microblaze_timer_set_mode,
+ (int)&microblaze_timer_set_next_event,
+ 0
+ };
+#endif
+ char *timer_list[] = {
+ "xlnx,xps-timer-1.00.a",
+ "xlnx,opb-timer-1.00.b",
+ "xlnx,opb-timer-1.00.a",
+ NULL
+ };
+
+ for (i = 0; timer_list[i] != NULL; i++) {
+ timer = of_find_compatible_node(NULL, NULL, timer_list[i]);
+ if (timer)
+ break;
+ }
+
+ timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL);
+ timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
+ irq = *(int *) of_get_property(timer, "interrupts", NULL);
+ timer_num =
+ *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL);
+ if (timer_num) {
+ printk(KERN_EMERG "Please enable two timers in HW\n");
+ BUG();
+ }
+
+#ifdef CONFIG_SELFMOD_TIMER
+ selfmod_function((int *) arr_func, timer_baseaddr);
+#endif
+ printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
+ timer_list[i], timer_baseaddr, irq);
+
+ cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ;
+
+ setup_irq(irq, &timer_irqaction);
+#ifdef CONFIG_HEART_BEAT
+ setup_heartbeat();
+#endif
+ microblaze_clocksource_init();
+ microblaze_clockevent_init();
+}
diff --git a/arch/microblaze/kernel/traps.c b/arch/microblaze/kernel/traps.c
new file mode 100644
index 00000000000..fbdc533c61e
--- /dev/null
+++ b/arch/microblaze/kernel/traps.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/kallsyms.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/debug_locks.h>
+
+#include <asm/exceptions.h>
+#include <asm/system.h>
+
+void trap_init(void)
+{
+ __enable_hw_exceptions();
+}
+
+void __bad_xchg(volatile void *ptr, int size)
+{
+ printk(KERN_INFO "xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
+ __builtin_return_address(0), ptr, size);
+ BUG();
+}
+EXPORT_SYMBOL(__bad_xchg);
+
+static int kstack_depth_to_print = 24;
+
+static int __init kstack_setup(char *s)
+{
+ kstack_depth_to_print = strict_strtoul(s, 0, 0);
+
+ return 1;
+}
+__setup("kstack=", kstack_setup);
+
+void show_trace(struct task_struct *task, unsigned long *stack)
+{
+ unsigned long addr;
+
+ if (!stack)
+ stack = (unsigned long *)&stack;
+
+ printk(KERN_NOTICE "Call Trace: ");
+#ifdef CONFIG_KALLSYMS
+ printk(KERN_NOTICE "\n");
+#endif
+ while (!kstack_end(stack)) {
+ addr = *stack++;
+ /*
+ * If the address is either in the text segment of the
+ * kernel, or in the region which contains vmalloc'ed
+ * memory, it *may* be the address of a calling
+ * routine; if so, print it so that someone tracing
+ * down the cause of the crash will be able to figure
+ * out the call path that was taken.
+ */
+ if (kernel_text_address(addr))
+ print_ip_sym(addr);
+ }
+ printk(KERN_NOTICE "\n");
+
+ if (!task)
+ task = current;
+
+ debug_show_held_locks(task);
+}
+
+void show_stack(struct task_struct *task, unsigned long *sp)
+{
+ unsigned long *stack;
+ int i;
+
+ if (sp == NULL) {
+ if (task)
+ sp = (unsigned long *) ((struct thread_info *)
+ (task->stack))->cpu_context.r1;
+ else
+ sp = (unsigned long *)&sp;
+ }
+
+ stack = sp;
+
+ printk(KERN_INFO "\nStack:\n ");
+
+ for (i = 0; i < kstack_depth_to_print; i++) {
+ if (kstack_end(sp))
+ break;
+ if (i && ((i % 8) == 0))
+ printk("\n ");
+ printk("%08lx ", *sp++);
+ }
+ printk("\n");
+ show_trace(task, stack);
+}
+
+void dump_stack(void)
+{
+ show_stack(NULL, NULL);
+}
+EXPORT_SYMBOL(dump_stack);
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
new file mode 100644
index 00000000000..840385e5129
--- /dev/null
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
+OUTPUT_ARCH(microblaze)
+ENTRY(_start)
+
+#include <asm-generic/vmlinux.lds.h>
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+ . = CONFIG_KERNEL_BASE_ADDR;
+
+ .text : {
+ _text = . ;
+ _stext = . ;
+ *(.text .text.*)
+ *(.fixup)
+
+ *(.exitcall.exit)
+ SCHED_TEXT
+ LOCK_TEXT
+ KPROBES_TEXT
+ . = ALIGN (4) ;
+ _etext = . ;
+ }
+
+ . = ALIGN (4) ;
+ _fdt_start = . ; /* place for fdt blob */
+ . = . + 0x4000;
+ _fdt_end = . ;
+
+ . = ALIGN(16);
+ RODATA
+ . = ALIGN(16);
+ __ex_table : {
+ __start___ex_table = .;
+ *(__ex_table)
+ __stop___ex_table = .;
+ }
+
+ /*
+ * sdata2 section can go anywhere, but must be word aligned
+ * and SDA2_BASE must point to the middle of it
+ */
+ .sdata2 : {
+ _ssrw = .;
+ . = ALIGN(4096); /* page aligned when MMU used - origin 0x8 */
+ *(.sdata2)
+ . = ALIGN(8);
+ _essrw = .;
+ _ssrw_size = _essrw - _ssrw;
+ _KERNEL_SDA2_BASE_ = _ssrw + (_ssrw_size / 2);
+ }
+
+ _sdata = . ;
+ .data ALIGN (4096) : { /* page aligned when MMU used - origin 0x4 */
+ *(.data)
+ }
+ . = ALIGN(32);
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+ _edata = . ;
+
+ /* Reserve some low RAM for r0 based memory references */
+ . = ALIGN(0x4) ;
+ r0_ram = . ;
+ . = . + 4096; /* a page should be enough */
+
+ /* The initial task */
+ . = ALIGN(8192);
+ .data.init_task : { *(.data.init_task) }
+
+ /* Under the microblaze ABI, .sdata and .sbss must be contiguous */
+ . = ALIGN(8);
+ .sdata : {
+ _ssro = .;
+ *(.sdata)
+ }
+
+ .sbss : {
+ _ssbss = .;
+ *(.sbss)
+ _esbss = .;
+ _essro = .;
+ _ssro_size = _essro - _ssro ;
+ _KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2) ;
+ }
+
+ __init_begin = .;
+
+ . = ALIGN(4096);
+ .init.text : {
+ _sinittext = . ;
+ *(.init.text)
+ *(.exit.text)
+ *(.exit.data)
+ _einittext = .;
+ }
+
+ .init.data : { *(.init.data) }
+
+ . = ALIGN(4);
+ .init.ivt : {
+ __ivt_start = .;
+ *(.init.ivt)
+ __ivt_end = .;
+ }
+
+ .init.setup : {
+ __setup_start = .;
+ *(.init.setup)
+ __setup_end = .;
+ }
+
+ .initcall.init : {
+ __initcall_start = .;
+ INITCALLS
+ __initcall_end = .;
+ }
+
+ .con_initcall.init : {
+ __con_initcall_start = .;
+ *(.con_initcall.init)
+ __con_initcall_end = .;
+ }
+
+ __init_end_before_initramfs = .;
+
+ .init.ramfs ALIGN(4096) : {
+ __initramfs_start = .;
+ *(.init.ramfs)
+ __initramfs_end = .;
+ . = ALIGN(4);
+ LONG(0);
+/*
+ * FIXME this can break initramfs for MMU.
+ * Pad init.ramfs up to page boundary,
+ * so that __init_end == __bss_start. This will make image.elf
+ * consistent with the image.bin
+ */
+ /* . = ALIGN(4096); */
+ }
+ __init_end = .;
+
+ .bss ALIGN (4096) : { /* page aligned when MMU used */
+ __bss_start = . ;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN (4) ;
+ __bss_stop = . ;
+ _ebss = . ;
+ }
+ . = ALIGN(4096);
+ _end = .;
+}
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile
new file mode 100644
index 00000000000..d27126bf306
--- /dev/null
+++ b/arch/microblaze/lib/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile
+#
+
+lib-y := memset.o checksum.o
+
+ifeq ($(CONFIG_OPT_LIB_ASM),y)
+lib-y += fastcopy.o
+else
+lib-y += memcpy.o memmove.o
+endif
+
+lib-y += uaccess.o
diff --git a/arch/microblaze/lib/checksum.c b/arch/microblaze/lib/checksum.c
new file mode 100644
index 00000000000..809340070a1
--- /dev/null
+++ b/arch/microblaze/lib/checksum.c
@@ -0,0 +1,163 @@
+/*
+ *
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * IP/TCP/UDP checksumming routines
+ *
+ * Authors: Jorge Cwik, <jorge@laser.satlink.net>
+ * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ * Tom May, <ftom@netcom.com>
+ * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
+ * Lots of code moved from tcp.c and ip.c; see those files
+ * for more names.
+ *
+ * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek:
+ * Fixed some nasty bugs, causing some horrible crashes.
+ * A: At some points, the sum (%0) was used as
+ * length-counter instead of the length counter
+ * (%1). Thanks to Roman Hodek for pointing this out.
+ * B: GCC seems to mess up if one uses too many
+ * data-registers to hold input values and one tries to
+ * specify d0 and d1 as scratch registers. Letting gcc
+ * choose these registers itself solves the problem.
+ *
+ * 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.
+ */
+
+/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access
+ kills, so most of the assembly has to go. */
+
+#include <net/checksum.h>
+#include <asm/checksum.h>
+#include <linux/module.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+ /* add up 16-bit and 16-bit for 16+c bit */
+ x = (x & 0xffff) + (x >> 16);
+ /* add up carry.. */
+ x = (x & 0xffff) + (x >> 16);
+ return x;
+}
+
+static unsigned int do_csum(const unsigned char *buff, int len)
+{
+ int odd, count;
+ unsigned long result = 0;
+
+ if (len <= 0)
+ goto out;
+ odd = 1 & (unsigned long) buff;
+ if (odd) {
+ result = *buff;
+ len--;
+ buff++;
+ }
+ count = len >> 1; /* nr of 16-bit words.. */
+ if (count) {
+ if (2 & (unsigned long) buff) {
+ result += *(unsigned short *) buff;
+ count--;
+ len -= 2;
+ buff += 2;
+ }
+ count >>= 1; /* nr of 32-bit words.. */
+ if (count) {
+ unsigned long carry = 0;
+ do {
+ unsigned long w = *(unsigned long *) buff;
+ count--;
+ buff += 4;
+ result += carry;
+ result += w;
+ carry = (w > result);
+ } while (count);
+ result += carry;
+ result = (result & 0xffff) + (result >> 16);
+ }
+ if (len & 2) {
+ result += *(unsigned short *) buff;
+ buff += 2;
+ }
+ }
+ if (len & 1)
+ result += (*buff << 8);
+ result = from32to16(result);
+ if (odd)
+ result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+ return result;
+}
+
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.
+ */
+__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+ return (__force __sum16)~do_csum(iph, ihl*4);
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+__wsum csum_partial(const void *buff, int len, __wsum sum)
+{
+ unsigned int result = do_csum(buff, len);
+
+ /* add in old sum, and carry.. */
+ result += sum;
+ if (sum > result)
+ result += 1;
+ return result;
+}
+EXPORT_SYMBOL(csum_partial);
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+__sum16 ip_compute_csum(const unsigned char *buff, int len)
+{
+ return ~do_csum(buff, len);
+}
+EXPORT_SYMBOL(ip_compute_csum);
+
+/*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+__wsum
+csum_partial_copy_from_user(const char __user *src, char *dst, int len,
+ int sum, int *csum_err)
+{
+ if (csum_err)
+ *csum_err = 0;
+ memcpy(dst, src, len);
+ return csum_partial(dst, len, sum);
+}
+EXPORT_SYMBOL(csum_partial_copy_from_user);
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+__wsum
+csum_partial_copy(const char *src, char *dst, int len, int sum)
+{
+ memcpy(dst, src, len);
+ return csum_partial(dst, len, sum);
+}
+EXPORT_SYMBOL(csum_partial_copy);
diff --git a/arch/microblaze/lib/fastcopy.S b/arch/microblaze/lib/fastcopy.S
new file mode 100644
index 00000000000..02e3ab4eddf
--- /dev/null
+++ b/arch/microblaze/lib/fastcopy.S
@@ -0,0 +1,662 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2008 Jim Law - Iris LP All rights reserved.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ * Written by Jim Law <jlaw@irispower.com>
+ *
+ * intended to replace:
+ * memcpy in memcpy.c and
+ * memmove in memmove.c
+ * ... in arch/microblaze/lib
+ *
+ *
+ * assly_fastcopy.S
+ *
+ * Attempt at quicker memcpy and memmove for MicroBlaze
+ * Input : Operand1 in Reg r5 - destination address
+ * Operand2 in Reg r6 - source address
+ * Operand3 in Reg r7 - number of bytes to transfer
+ * Output: Result in Reg r3 - starting destinaition address
+ *
+ *
+ * Explanation:
+ * Perform (possibly unaligned) copy of a block of memory
+ * between mem locations with size of xfer spec'd in bytes
+ */
+
+#include <linux/linkage.h>
+
+ .globl memcpy
+ .ent memcpy
+
+memcpy:
+fast_memcpy_ascending:
+ /* move d to return register as value of function */
+ addi r3, r5, 0
+
+ addi r4, r0, 4 /* n = 4 */
+ cmpu r4, r4, r7 /* n = c - n (unsigned) */
+ blti r4, a_xfer_end /* if n < 0, less than one word to transfer */
+
+ /* transfer first 0~3 bytes to get aligned dest address */
+ andi r4, r5, 3 /* n = d & 3 */
+ /* if zero, destination already aligned */
+ beqi r4, a_dalign_done
+ /* n = 4 - n (yields 3, 2, 1 transfers for 1, 2, 3 addr offset) */
+ rsubi r4, r4, 4
+ rsub r7, r4, r7 /* c = c - n adjust c */
+
+a_xfer_first_loop:
+ /* if no bytes left to transfer, transfer the bulk */
+ beqi r4, a_dalign_done
+ lbui r11, r6, 0 /* h = *s */
+ sbi r11, r5, 0 /* *d = h */
+ addi r6, r6, 1 /* s++ */
+ addi r5, r5, 1 /* d++ */
+ brid a_xfer_first_loop /* loop */
+ addi r4, r4, -1 /* n-- (IN DELAY SLOT) */
+
+a_dalign_done:
+ addi r4, r0, 32 /* n = 32 */
+ cmpu r4, r4, r7 /* n = c - n (unsigned) */
+ /* if n < 0, less than one block to transfer */
+ blti r4, a_block_done
+
+a_block_xfer:
+ andi r4, r7, 0xffffffe0 /* n = c & ~31 */
+ rsub r7, r4, r7 /* c = c - n */
+
+ andi r9, r6, 3 /* t1 = s & 3 */
+ /* if temp != 0, unaligned transfers needed */
+ bnei r9, a_block_unaligned
+
+a_block_aligned:
+ lwi r9, r6, 0 /* t1 = *(s + 0) */
+ lwi r10, r6, 4 /* t2 = *(s + 4) */
+ lwi r11, r6, 8 /* t3 = *(s + 8) */
+ lwi r12, r6, 12 /* t4 = *(s + 12) */
+ swi r9, r5, 0 /* *(d + 0) = t1 */
+ swi r10, r5, 4 /* *(d + 4) = t2 */
+ swi r11, r5, 8 /* *(d + 8) = t3 */
+ swi r12, r5, 12 /* *(d + 12) = t4 */
+ lwi r9, r6, 16 /* t1 = *(s + 16) */
+ lwi r10, r6, 20 /* t2 = *(s + 20) */
+ lwi r11, r6, 24 /* t3 = *(s + 24) */
+ lwi r12, r6, 28 /* t4 = *(s + 28) */
+ swi r9, r5, 16 /* *(d + 16) = t1 */
+ swi r10, r5, 20 /* *(d + 20) = t2 */
+ swi r11, r5, 24 /* *(d + 24) = t3 */
+ swi r12, r5, 28 /* *(d + 28) = t4 */
+ addi r6, r6, 32 /* s = s + 32 */
+ addi r4, r4, -32 /* n = n - 32 */
+ bneid r4, a_block_aligned /* while (n) loop */
+ addi r5, r5, 32 /* d = d + 32 (IN DELAY SLOT) */
+ bri a_block_done
+
+a_block_unaligned:
+ andi r8, r6, 0xfffffffc /* as = s & ~3 */
+ add r6, r6, r4 /* s = s + n */
+ lwi r11, r8, 0 /* h = *(as + 0) */
+
+ addi r9, r9, -1
+ beqi r9, a_block_u1 /* t1 was 1 => 1 byte offset */
+ addi r9, r9, -1
+ beqi r9, a_block_u2 /* t1 was 2 => 2 byte offset */
+
+a_block_u3:
+ bslli r11, r11, 24 /* h = h << 24 */
+a_bu3_loop:
+ lwi r12, r8, 4 /* v = *(as + 4) */
+ bsrli r9, r12, 8 /* t1 = v >> 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 0 /* *(d + 0) = t1 */
+ bslli r11, r12, 24 /* h = v << 24 */
+ lwi r12, r8, 8 /* v = *(as + 8) */
+ bsrli r9, r12, 8 /* t1 = v >> 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 4 /* *(d + 4) = t1 */
+ bslli r11, r12, 24 /* h = v << 24 */
+ lwi r12, r8, 12 /* v = *(as + 12) */
+ bsrli r9, r12, 8 /* t1 = v >> 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 8 /* *(d + 8) = t1 */
+ bslli r11, r12, 24 /* h = v << 24 */
+ lwi r12, r8, 16 /* v = *(as + 16) */
+ bsrli r9, r12, 8 /* t1 = v >> 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 12 /* *(d + 12) = t1 */
+ bslli r11, r12, 24 /* h = v << 24 */
+ lwi r12, r8, 20 /* v = *(as + 20) */
+ bsrli r9, r12, 8 /* t1 = v >> 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 16 /* *(d + 16) = t1 */
+ bslli r11, r12, 24 /* h = v << 24 */
+ lwi r12, r8, 24 /* v = *(as + 24) */
+ bsrli r9, r12, 8 /* t1 = v >> 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 20 /* *(d + 20) = t1 */
+ bslli r11, r12, 24 /* h = v << 24 */
+ lwi r12, r8, 28 /* v = *(as + 28) */
+ bsrli r9, r12, 8 /* t1 = v >> 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 24 /* *(d + 24) = t1 */
+ bslli r11, r12, 24 /* h = v << 24 */
+ lwi r12, r8, 32 /* v = *(as + 32) */
+ bsrli r9, r12, 8 /* t1 = v >> 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 28 /* *(d + 28) = t1 */
+ bslli r11, r12, 24 /* h = v << 24 */
+ addi r8, r8, 32 /* as = as + 32 */
+ addi r4, r4, -32 /* n = n - 32 */
+ bneid r4, a_bu3_loop /* while (n) loop */
+ addi r5, r5, 32 /* d = d + 32 (IN DELAY SLOT) */
+ bri a_block_done
+
+a_block_u1:
+ bslli r11, r11, 8 /* h = h << 8 */
+a_bu1_loop:
+ lwi r12, r8, 4 /* v = *(as + 4) */
+ bsrli r9, r12, 24 /* t1 = v >> 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 0 /* *(d + 0) = t1 */
+ bslli r11, r12, 8 /* h = v << 8 */
+ lwi r12, r8, 8 /* v = *(as + 8) */
+ bsrli r9, r12, 24 /* t1 = v >> 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 4 /* *(d + 4) = t1 */
+ bslli r11, r12, 8 /* h = v << 8 */
+ lwi r12, r8, 12 /* v = *(as + 12) */
+ bsrli r9, r12, 24 /* t1 = v >> 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 8 /* *(d + 8) = t1 */
+ bslli r11, r12, 8 /* h = v << 8 */
+ lwi r12, r8, 16 /* v = *(as + 16) */
+ bsrli r9, r12, 24 /* t1 = v >> 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 12 /* *(d + 12) = t1 */
+ bslli r11, r12, 8 /* h = v << 8 */
+ lwi r12, r8, 20 /* v = *(as + 20) */
+ bsrli r9, r12, 24 /* t1 = v >> 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 16 /* *(d + 16) = t1 */
+ bslli r11, r12, 8 /* h = v << 8 */
+ lwi r12, r8, 24 /* v = *(as + 24) */
+ bsrli r9, r12, 24 /* t1 = v >> 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 20 /* *(d + 20) = t1 */
+ bslli r11, r12, 8 /* h = v << 8 */
+ lwi r12, r8, 28 /* v = *(as + 28) */
+ bsrli r9, r12, 24 /* t1 = v >> 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 24 /* *(d + 24) = t1 */
+ bslli r11, r12, 8 /* h = v << 8 */
+ lwi r12, r8, 32 /* v = *(as + 32) */
+ bsrli r9, r12, 24 /* t1 = v >> 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 28 /* *(d + 28) = t1 */
+ bslli r11, r12, 8 /* h = v << 8 */
+ addi r8, r8, 32 /* as = as + 32 */
+ addi r4, r4, -32 /* n = n - 32 */
+ bneid r4, a_bu1_loop /* while (n) loop */
+ addi r5, r5, 32 /* d = d + 32 (IN DELAY SLOT) */
+ bri a_block_done
+
+a_block_u2:
+ bslli r11, r11, 16 /* h = h << 16 */
+a_bu2_loop:
+ lwi r12, r8, 4 /* v = *(as + 4) */
+ bsrli r9, r12, 16 /* t1 = v >> 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 0 /* *(d + 0) = t1 */
+ bslli r11, r12, 16 /* h = v << 16 */
+ lwi r12, r8, 8 /* v = *(as + 8) */
+ bsrli r9, r12, 16 /* t1 = v >> 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 4 /* *(d + 4) = t1 */
+ bslli r11, r12, 16 /* h = v << 16 */
+ lwi r12, r8, 12 /* v = *(as + 12) */
+ bsrli r9, r12, 16 /* t1 = v >> 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 8 /* *(d + 8) = t1 */
+ bslli r11, r12, 16 /* h = v << 16 */
+ lwi r12, r8, 16 /* v = *(as + 16) */
+ bsrli r9, r12, 16 /* t1 = v >> 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 12 /* *(d + 12) = t1 */
+ bslli r11, r12, 16 /* h = v << 16 */
+ lwi r12, r8, 20 /* v = *(as + 20) */
+ bsrli r9, r12, 16 /* t1 = v >> 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 16 /* *(d + 16) = t1 */
+ bslli r11, r12, 16 /* h = v << 16 */
+ lwi r12, r8, 24 /* v = *(as + 24) */
+ bsrli r9, r12, 16 /* t1 = v >> 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 20 /* *(d + 20) = t1 */
+ bslli r11, r12, 16 /* h = v << 16 */
+ lwi r12, r8, 28 /* v = *(as + 28) */
+ bsrli r9, r12, 16 /* t1 = v >> 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 24 /* *(d + 24) = t1 */
+ bslli r11, r12, 16 /* h = v << 16 */
+ lwi r12, r8, 32 /* v = *(as + 32) */
+ bsrli r9, r12, 16 /* t1 = v >> 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 28 /* *(d + 28) = t1 */
+ bslli r11, r12, 16 /* h = v << 16 */
+ addi r8, r8, 32 /* as = as + 32 */
+ addi r4, r4, -32 /* n = n - 32 */
+ bneid r4, a_bu2_loop /* while (n) loop */
+ addi r5, r5, 32 /* d = d + 32 (IN DELAY SLOT) */
+
+a_block_done:
+ addi r4, r0, 4 /* n = 4 */
+ cmpu r4, r4, r7 /* n = c - n (unsigned) */
+ blti r4, a_xfer_end /* if n < 0, less than one word to transfer */
+
+a_word_xfer:
+ andi r4, r7, 0xfffffffc /* n = c & ~3 */
+ addi r10, r0, 0 /* offset = 0 */
+
+ andi r9, r6, 3 /* t1 = s & 3 */
+ /* if temp != 0, unaligned transfers needed */
+ bnei r9, a_word_unaligned
+
+a_word_aligned:
+ lw r9, r6, r10 /* t1 = *(s+offset) */
+ sw r9, r5, r10 /* *(d+offset) = t1 */
+ addi r4, r4,-4 /* n-- */
+ bneid r4, a_word_aligned /* loop */
+ addi r10, r10, 4 /* offset++ (IN DELAY SLOT) */
+
+ bri a_word_done
+
+a_word_unaligned:
+ andi r8, r6, 0xfffffffc /* as = s & ~3 */
+ lwi r11, r8, 0 /* h = *(as + 0) */
+ addi r8, r8, 4 /* as = as + 4 */
+
+ addi r9, r9, -1
+ beqi r9, a_word_u1 /* t1 was 1 => 1 byte offset */
+ addi r9, r9, -1
+ beqi r9, a_word_u2 /* t1 was 2 => 2 byte offset */
+
+a_word_u3:
+ bslli r11, r11, 24 /* h = h << 24 */
+a_wu3_loop:
+ lw r12, r8, r10 /* v = *(as + offset) */
+ bsrli r9, r12, 8 /* t1 = v >> 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ sw r9, r5, r10 /* *(d + offset) = t1 */
+ bslli r11, r12, 24 /* h = v << 24 */
+ addi r4, r4,-4 /* n = n - 4 */
+ bneid r4, a_wu3_loop /* while (n) loop */
+ addi r10, r10, 4 /* offset = ofset + 4 (IN DELAY SLOT) */
+
+ bri a_word_done
+
+a_word_u1:
+ bslli r11, r11, 8 /* h = h << 8 */
+a_wu1_loop:
+ lw r12, r8, r10 /* v = *(as + offset) */
+ bsrli r9, r12, 24 /* t1 = v >> 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ sw r9, r5, r10 /* *(d + offset) = t1 */
+ bslli r11, r12, 8 /* h = v << 8 */
+ addi r4, r4,-4 /* n = n - 4 */
+ bneid r4, a_wu1_loop /* while (n) loop */
+ addi r10, r10, 4 /* offset = ofset + 4 (IN DELAY SLOT) */
+
+ bri a_word_done
+
+a_word_u2:
+ bslli r11, r11, 16 /* h = h << 16 */
+a_wu2_loop:
+ lw r12, r8, r10 /* v = *(as + offset) */
+ bsrli r9, r12, 16 /* t1 = v >> 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ sw r9, r5, r10 /* *(d + offset) = t1 */
+ bslli r11, r12, 16 /* h = v << 16 */
+ addi r4, r4,-4 /* n = n - 4 */
+ bneid r4, a_wu2_loop /* while (n) loop */
+ addi r10, r10, 4 /* offset = ofset + 4 (IN DELAY SLOT) */
+
+a_word_done:
+ add r5, r5, r10 /* d = d + offset */
+ add r6, r6, r10 /* s = s + offset */
+ rsub r7, r10, r7 /* c = c - offset */
+
+a_xfer_end:
+a_xfer_end_loop:
+ beqi r7, a_done /* while (c) */
+ lbui r9, r6, 0 /* t1 = *s */
+ addi r6, r6, 1 /* s++ */
+ sbi r9, r5, 0 /* *d = t1 */
+ addi r7, r7, -1 /* c-- */
+ brid a_xfer_end_loop /* loop */
+ addi r5, r5, 1 /* d++ (IN DELAY SLOT) */
+
+a_done:
+ rtsd r15, 8
+ nop
+
+.end memcpy
+/*----------------------------------------------------------------------------*/
+ .globl memmove
+ .ent memmove
+
+memmove:
+ cmpu r4, r5, r6 /* n = s - d */
+ bgei r4,fast_memcpy_ascending
+
+fast_memcpy_descending:
+ /* move d to return register as value of function */
+ addi r3, r5, 0
+
+ add r5, r5, r7 /* d = d + c */
+ add r6, r6, r7 /* s = s + c */
+
+ addi r4, r0, 4 /* n = 4 */
+ cmpu r4, r4, r7 /* n = c - n (unsigned) */
+ blti r4,d_xfer_end /* if n < 0, less than one word to transfer */
+
+ /* transfer first 0~3 bytes to get aligned dest address */
+ andi r4, r5, 3 /* n = d & 3 */
+ /* if zero, destination already aligned */
+ beqi r4,d_dalign_done
+ rsub r7, r4, r7 /* c = c - n adjust c */
+
+d_xfer_first_loop:
+ /* if no bytes left to transfer, transfer the bulk */
+ beqi r4,d_dalign_done
+ addi r6, r6, -1 /* s-- */
+ addi r5, r5, -1 /* d-- */
+ lbui r11, r6, 0 /* h = *s */
+ sbi r11, r5, 0 /* *d = h */
+ brid d_xfer_first_loop /* loop */
+ addi r4, r4, -1 /* n-- (IN DELAY SLOT) */
+
+d_dalign_done:
+ addi r4, r0, 32 /* n = 32 */
+ cmpu r4, r4, r7 /* n = c - n (unsigned) */
+ /* if n < 0, less than one block to transfer */
+ blti r4, d_block_done
+
+d_block_xfer:
+ andi r4, r7, 0xffffffe0 /* n = c & ~31 */
+ rsub r7, r4, r7 /* c = c - n */
+
+ andi r9, r6, 3 /* t1 = s & 3 */
+ /* if temp != 0, unaligned transfers needed */
+ bnei r9, d_block_unaligned
+
+d_block_aligned:
+ addi r6, r6, -32 /* s = s - 32 */
+ addi r5, r5, -32 /* d = d - 32 */
+ lwi r9, r6, 28 /* t1 = *(s + 28) */
+ lwi r10, r6, 24 /* t2 = *(s + 24) */
+ lwi r11, r6, 20 /* t3 = *(s + 20) */
+ lwi r12, r6, 16 /* t4 = *(s + 16) */
+ swi r9, r5, 28 /* *(d + 28) = t1 */
+ swi r10, r5, 24 /* *(d + 24) = t2 */
+ swi r11, r5, 20 /* *(d + 20) = t3 */
+ swi r12, r5, 16 /* *(d + 16) = t4 */
+ lwi r9, r6, 12 /* t1 = *(s + 12) */
+ lwi r10, r6, 8 /* t2 = *(s + 8) */
+ lwi r11, r6, 4 /* t3 = *(s + 4) */
+ lwi r12, r6, 0 /* t4 = *(s + 0) */
+ swi r9, r5, 12 /* *(d + 12) = t1 */
+ swi r10, r5, 8 /* *(d + 8) = t2 */
+ swi r11, r5, 4 /* *(d + 4) = t3 */
+ addi r4, r4, -32 /* n = n - 32 */
+ bneid r4, d_block_aligned /* while (n) loop */
+ swi r12, r5, 0 /* *(d + 0) = t4 (IN DELAY SLOT) */
+ bri d_block_done
+
+d_block_unaligned:
+ andi r8, r6, 0xfffffffc /* as = s & ~3 */
+ rsub r6, r4, r6 /* s = s - n */
+ lwi r11, r8, 0 /* h = *(as + 0) */
+
+ addi r9, r9, -1
+ beqi r9,d_block_u1 /* t1 was 1 => 1 byte offset */
+ addi r9, r9, -1
+ beqi r9,d_block_u2 /* t1 was 2 => 2 byte offset */
+
+d_block_u3:
+ bsrli r11, r11, 8 /* h = h >> 8 */
+d_bu3_loop:
+ addi r8, r8, -32 /* as = as - 32 */
+ addi r5, r5, -32 /* d = d - 32 */
+ lwi r12, r8, 28 /* v = *(as + 28) */
+ bslli r9, r12, 24 /* t1 = v << 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 28 /* *(d + 28) = t1 */
+ bsrli r11, r12, 8 /* h = v >> 8 */
+ lwi r12, r8, 24 /* v = *(as + 24) */
+ bslli r9, r12, 24 /* t1 = v << 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 24 /* *(d + 24) = t1 */
+ bsrli r11, r12, 8 /* h = v >> 8 */
+ lwi r12, r8, 20 /* v = *(as + 20) */
+ bslli r9, r12, 24 /* t1 = v << 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 20 /* *(d + 20) = t1 */
+ bsrli r11, r12, 8 /* h = v >> 8 */
+ lwi r12, r8, 16 /* v = *(as + 16) */
+ bslli r9, r12, 24 /* t1 = v << 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 16 /* *(d + 16) = t1 */
+ bsrli r11, r12, 8 /* h = v >> 8 */
+ lwi r12, r8, 12 /* v = *(as + 12) */
+ bslli r9, r12, 24 /* t1 = v << 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 12 /* *(d + 112) = t1 */
+ bsrli r11, r12, 8 /* h = v >> 8 */
+ lwi r12, r8, 8 /* v = *(as + 8) */
+ bslli r9, r12, 24 /* t1 = v << 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 8 /* *(d + 8) = t1 */
+ bsrli r11, r12, 8 /* h = v >> 8 */
+ lwi r12, r8, 4 /* v = *(as + 4) */
+ bslli r9, r12, 24 /* t1 = v << 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 4 /* *(d + 4) = t1 */
+ bsrli r11, r12, 8 /* h = v >> 8 */
+ lwi r12, r8, 0 /* v = *(as + 0) */
+ bslli r9, r12, 24 /* t1 = v << 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 0 /* *(d + 0) = t1 */
+ addi r4, r4, -32 /* n = n - 32 */
+ bneid r4, d_bu3_loop /* while (n) loop */
+ bsrli r11, r12, 8 /* h = v >> 8 (IN DELAY SLOT) */
+ bri d_block_done
+
+d_block_u1:
+ bsrli r11, r11, 24 /* h = h >> 24 */
+d_bu1_loop:
+ addi r8, r8, -32 /* as = as - 32 */
+ addi r5, r5, -32 /* d = d - 32 */
+ lwi r12, r8, 28 /* v = *(as + 28) */
+ bslli r9, r12, 8 /* t1 = v << 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 28 /* *(d + 28) = t1 */
+ bsrli r11, r12, 24 /* h = v >> 24 */
+ lwi r12, r8, 24 /* v = *(as + 24) */
+ bslli r9, r12, 8 /* t1 = v << 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 24 /* *(d + 24) = t1 */
+ bsrli r11, r12, 24 /* h = v >> 24 */
+ lwi r12, r8, 20 /* v = *(as + 20) */
+ bslli r9, r12, 8 /* t1 = v << 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 20 /* *(d + 20) = t1 */
+ bsrli r11, r12, 24 /* h = v >> 24 */
+ lwi r12, r8, 16 /* v = *(as + 16) */
+ bslli r9, r12, 8 /* t1 = v << 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 16 /* *(d + 16) = t1 */
+ bsrli r11, r12, 24 /* h = v >> 24 */
+ lwi r12, r8, 12 /* v = *(as + 12) */
+ bslli r9, r12, 8 /* t1 = v << 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 12 /* *(d + 112) = t1 */
+ bsrli r11, r12, 24 /* h = v >> 24 */
+ lwi r12, r8, 8 /* v = *(as + 8) */
+ bslli r9, r12, 8 /* t1 = v << 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 8 /* *(d + 8) = t1 */
+ bsrli r11, r12, 24 /* h = v >> 24 */
+ lwi r12, r8, 4 /* v = *(as + 4) */
+ bslli r9, r12, 8 /* t1 = v << 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 4 /* *(d + 4) = t1 */
+ bsrli r11, r12, 24 /* h = v >> 24 */
+ lwi r12, r8, 0 /* v = *(as + 0) */
+ bslli r9, r12, 8 /* t1 = v << 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 0 /* *(d + 0) = t1 */
+ addi r4, r4, -32 /* n = n - 32 */
+ bneid r4, d_bu1_loop /* while (n) loop */
+ bsrli r11, r12, 24 /* h = v >> 24 (IN DELAY SLOT) */
+ bri d_block_done
+
+d_block_u2:
+ bsrli r11, r11, 16 /* h = h >> 16 */
+d_bu2_loop:
+ addi r8, r8, -32 /* as = as - 32 */
+ addi r5, r5, -32 /* d = d - 32 */
+ lwi r12, r8, 28 /* v = *(as + 28) */
+ bslli r9, r12, 16 /* t1 = v << 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 28 /* *(d + 28) = t1 */
+ bsrli r11, r12, 16 /* h = v >> 16 */
+ lwi r12, r8, 24 /* v = *(as + 24) */
+ bslli r9, r12, 16 /* t1 = v << 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 24 /* *(d + 24) = t1 */
+ bsrli r11, r12, 16 /* h = v >> 16 */
+ lwi r12, r8, 20 /* v = *(as + 20) */
+ bslli r9, r12, 16 /* t1 = v << 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 20 /* *(d + 20) = t1 */
+ bsrli r11, r12, 16 /* h = v >> 16 */
+ lwi r12, r8, 16 /* v = *(as + 16) */
+ bslli r9, r12, 16 /* t1 = v << 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 16 /* *(d + 16) = t1 */
+ bsrli r11, r12, 16 /* h = v >> 16 */
+ lwi r12, r8, 12 /* v = *(as + 12) */
+ bslli r9, r12, 16 /* t1 = v << 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 12 /* *(d + 112) = t1 */
+ bsrli r11, r12, 16 /* h = v >> 16 */
+ lwi r12, r8, 8 /* v = *(as + 8) */
+ bslli r9, r12, 16 /* t1 = v << 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 8 /* *(d + 8) = t1 */
+ bsrli r11, r12, 16 /* h = v >> 16 */
+ lwi r12, r8, 4 /* v = *(as + 4) */
+ bslli r9, r12, 16 /* t1 = v << 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 4 /* *(d + 4) = t1 */
+ bsrli r11, r12, 16 /* h = v >> 16 */
+ lwi r12, r8, 0 /* v = *(as + 0) */
+ bslli r9, r12, 16 /* t1 = v << 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ swi r9, r5, 0 /* *(d + 0) = t1 */
+ addi r4, r4, -32 /* n = n - 32 */
+ bneid r4, d_bu2_loop /* while (n) loop */
+ bsrli r11, r12, 16 /* h = v >> 16 (IN DELAY SLOT) */
+
+d_block_done:
+ addi r4, r0, 4 /* n = 4 */
+ cmpu r4, r4, r7 /* n = c - n (unsigned) */
+ blti r4,d_xfer_end /* if n < 0, less than one word to transfer */
+
+d_word_xfer:
+ andi r4, r7, 0xfffffffc /* n = c & ~3 */
+ rsub r5, r4, r5 /* d = d - n */
+ rsub r6, r4, r6 /* s = s - n */
+ rsub r7, r4, r7 /* c = c - n */
+
+ andi r9, r6, 3 /* t1 = s & 3 */
+ /* if temp != 0, unaligned transfers needed */
+ bnei r9, d_word_unaligned
+
+d_word_aligned:
+ addi r4, r4,-4 /* n-- */
+ lw r9, r6, r4 /* t1 = *(s+n) */
+ bneid r4, d_word_aligned /* loop */
+ sw r9, r5, r4 /* *(d+n) = t1 (IN DELAY SLOT) */
+
+ bri d_word_done
+
+d_word_unaligned:
+ andi r8, r6, 0xfffffffc /* as = s & ~3 */
+ lw r11, r8, r4 /* h = *(as + n) */
+
+ addi r9, r9, -1
+ beqi r9,d_word_u1 /* t1 was 1 => 1 byte offset */
+ addi r9, r9, -1
+ beqi r9,d_word_u2 /* t1 was 2 => 2 byte offset */
+
+d_word_u3:
+ bsrli r11, r11, 8 /* h = h >> 8 */
+d_wu3_loop:
+ addi r4, r4,-4 /* n = n - 4 */
+ lw r12, r8, r4 /* v = *(as + n) */
+ bslli r9, r12, 24 /* t1 = v << 24 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ sw r9, r5, r4 /* *(d + n) = t1 */
+ bneid r4, d_wu3_loop /* while (n) loop */
+ bsrli r11, r12, 8 /* h = v >> 8 (IN DELAY SLOT) */
+
+ bri d_word_done
+
+d_word_u1:
+ bsrli r11, r11, 24 /* h = h >> 24 */
+d_wu1_loop:
+ addi r4, r4,-4 /* n = n - 4 */
+ lw r12, r8, r4 /* v = *(as + n) */
+ bslli r9, r12, 8 /* t1 = v << 8 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ sw r9, r5, r4 /* *(d + n) = t1 */
+ bneid r4, d_wu1_loop /* while (n) loop */
+ bsrli r11, r12, 24 /* h = v >> 24 (IN DELAY SLOT) */
+
+ bri d_word_done
+
+d_word_u2:
+ bsrli r11, r11, 16 /* h = h >> 16 */
+d_wu2_loop:
+ addi r4, r4,-4 /* n = n - 4 */
+ lw r12, r8, r4 /* v = *(as + n) */
+ bslli r9, r12, 16 /* t1 = v << 16 */
+ or r9, r11, r9 /* t1 = h | t1 */
+ sw r9, r5, r4 /* *(d + n) = t1 */
+ bneid r4, d_wu2_loop /* while (n) loop */
+ bsrli r11, r12, 16 /* h = v >> 16 (IN DELAY SLOT) */
+
+d_word_done:
+
+d_xfer_end:
+d_xfer_end_loop:
+ beqi r7, a_done /* while (c) */
+ addi r6, r6, -1 /* s-- */
+ lbui r9, r6, 0 /* t1 = *s */
+ addi r5, r5, -1 /* d-- */
+ sbi r9, r5, 0 /* *d = t1 */
+ brid d_xfer_end_loop /* loop */
+ addi r7, r7, -1 /* c-- (IN DELAY SLOT) */
+
+d_done:
+ rtsd r15, 8
+ nop
+
+.end memmove
diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c
new file mode 100644
index 00000000000..5880119c448
--- /dev/null
+++ b/arch/microblaze/lib/memcpy.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2007 John Williams
+ *
+ * Reasonably optimised generic C-code for memcpy on Microblaze
+ * This is generic C code to do efficient, alignment-aware memcpy.
+ *
+ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
+ * http://www.embedded.com/showArticle.jhtml?articleID=19205567
+ *
+ * Attempts were made, unsuccesfully, to contact the original
+ * author of this code (Michael Morrow, Intel). Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+
+#include <linux/string.h>
+#include <asm/system.h>
+
+#ifdef __HAVE_ARCH_MEMCPY
+void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
+{
+ const char *src = v_src;
+ char *dst = v_dst;
+#ifndef CONFIG_OPT_LIB_FUNCTION
+ /* Simple, byte oriented memcpy. */
+ while (c--)
+ *dst++ = *src++;
+
+ return v_dst;
+#else
+ /* The following code tries to optimize the copy by using unsigned
+ * alignment. This will work fine if both source and destination are
+ * aligned on the same boundary. However, if they are aligned on
+ * different boundaries shifts will be necessary. This might result in
+ * bad performance on MicroBlaze systems without a barrel shifter.
+ */
+ const uint32_t *i_src;
+ uint32_t *i_dst;
+
+ if (c >= 4) {
+ unsigned value, buf_hold;
+
+ /* Align the dstination to a word boundry. */
+ /* This is done in an endian independant manner. */
+ switch ((unsigned long)dst & 3) {
+ case 1:
+ *dst++ = *src++;
+ --c;
+ case 2:
+ *dst++ = *src++;
+ --c;
+ case 3:
+ *dst++ = *src++;
+ --c;
+ }
+
+ i_dst = (void *)dst;
+
+ /* Choose a copy scheme based on the source */
+ /* alignment relative to dstination. */
+ switch ((unsigned long)src & 3) {
+ case 0x0: /* Both byte offsets are aligned */
+ i_src = (const void *)src;
+
+ for (; c >= 4; c -= 4)
+ *i_dst++ = *i_src++;
+
+ src = (const void *)i_src;
+ break;
+ case 0x1: /* Unaligned - Off by 1 */
+ /* Word align the source */
+ i_src = (const void *) ((unsigned)src & ~3);
+
+ /* Load the holding buffer */
+ buf_hold = *i_src++ << 8;
+
+ for (; c >= 4; c -= 4) {
+ value = *i_src++;
+ *i_dst++ = buf_hold | value >> 24;
+ buf_hold = value << 8;
+ }
+
+ /* Realign the source */
+ src = (const void *)i_src;
+ src -= 3;
+ break;
+ case 0x2: /* Unaligned - Off by 2 */
+ /* Word align the source */
+ i_src = (const void *) ((unsigned)src & ~3);
+
+ /* Load the holding buffer */
+ buf_hold = *i_src++ << 16;
+
+ for (; c >= 4; c -= 4) {
+ value = *i_src++;
+ *i_dst++ = buf_hold | value >> 16;
+ buf_hold = value << 16;
+ }
+
+ /* Realign the source */
+ src = (const void *)i_src;
+ src -= 2;
+ break;
+ case 0x3: /* Unaligned - Off by 3 */
+ /* Word align the source */
+ i_src = (const void *) ((unsigned)src & ~3);
+
+ /* Load the holding buffer */
+ buf_hold = *i_src++ << 24;
+
+ for (; c >= 4; c -= 4) {
+ value = *i_src++;
+ *i_dst++ = buf_hold | value >> 8;
+ buf_hold = value << 24;
+ }
+
+ /* Realign the source */
+ src = (const void *)i_src;
+ src -= 1;
+ break;
+ }
+ dst = (void *)i_dst;
+ }
+
+ /* Finish off any remaining bytes */
+ /* simple fast copy, ... unless a cache boundry is crossed */
+ switch (c) {
+ case 3:
+ *dst++ = *src++;
+ case 2:
+ *dst++ = *src++;
+ case 1:
+ *dst++ = *src++;
+ }
+
+ return v_dst;
+#endif
+}
+EXPORT_SYMBOL(memcpy);
+#endif /* __HAVE_ARCH_MEMCPY */
+
+void *cacheable_memcpy(void *d, const void *s, __kernel_size_t c)
+{
+ return memcpy(d, s, c);
+}
diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c
new file mode 100644
index 00000000000..d4e9f49a71f
--- /dev/null
+++ b/arch/microblaze/lib/memmove.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2007 John Williams
+ *
+ * Reasonably optimised generic C-code for memcpy on Microblaze
+ * This is generic C code to do efficient, alignment-aware memmove.
+ *
+ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
+ * http://www.embedded.com/showArticle.jhtml?articleID=19205567
+ *
+ * Attempts were made, unsuccesfully, to contact the original
+ * author of this code (Michael Morrow, Intel). Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#ifdef __HAVE_ARCH_MEMMOVE
+void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
+{
+ const char *src = v_src;
+ char *dst = v_dst;
+
+#ifdef CONFIG_OPT_LIB_FUNCTION
+ const uint32_t *i_src;
+ uint32_t *i_dst;
+#endif
+
+ if (!c)
+ return v_dst;
+
+ /* Use memcpy when source is higher than dest */
+ if (v_dst <= v_src)
+ return memcpy(v_dst, v_src, c);
+
+#ifndef CONFIG_OPT_LIB_FUNCTION
+ /* copy backwards, from end to beginning */
+ src += c;
+ dst += c;
+
+ /* Simple, byte oriented memmove. */
+ while (c--)
+ *--dst = *--src;
+
+ return v_dst;
+#else
+ /* The following code tries to optimize the copy by using unsigned
+ * alignment. This will work fine if both source and destination are
+ * aligned on the same boundary. However, if they are aligned on
+ * different boundaries shifts will be necessary. This might result in
+ * bad performance on MicroBlaze systems without a barrel shifter.
+ */
+ /* FIXME this part needs more test */
+ /* Do a descending copy - this is a bit trickier! */
+ dst += c;
+ src += c;
+
+ if (c >= 4) {
+ unsigned value, buf_hold;
+
+ /* Align the destination to a word boundry. */
+ /* This is done in an endian independant manner. */
+
+ switch ((unsigned long)dst & 3) {
+ case 3:
+ *--dst = *--src;
+ --c;
+ case 2:
+ *--dst = *--src;
+ --c;
+ case 1:
+ *--dst = *--src;
+ --c;
+ }
+
+ i_dst = (void *)dst;
+ /* Choose a copy scheme based on the source */
+ /* alignment relative to dstination. */
+ switch ((unsigned long)src & 3) {
+ case 0x0: /* Both byte offsets are aligned */
+
+ i_src = (const void *)src;
+
+ for (; c >= 4; c -= 4)
+ *--i_dst = *--i_src;
+
+ src = (const void *)i_src;
+ break;
+ case 0x1: /* Unaligned - Off by 1 */
+ /* Word align the source */
+ i_src = (const void *) (((unsigned)src + 4) & ~3);
+
+ /* Load the holding buffer */
+ buf_hold = *--i_src >> 24;
+
+ for (; c >= 4; c -= 4) {
+ value = *--i_src;
+ *--i_dst = buf_hold << 8 | value;
+ buf_hold = value >> 24;
+ }
+
+ /* Realign the source */
+ src = (const void *)i_src;
+ src += 1;
+ break;
+ case 0x2: /* Unaligned - Off by 2 */
+ /* Word align the source */
+ i_src = (const void *) (((unsigned)src + 4) & ~3);
+
+ /* Load the holding buffer */
+ buf_hold = *--i_src >> 16;
+
+ for (; c >= 4; c -= 4) {
+ value = *--i_src;
+ *--i_dst = buf_hold << 16 | value;
+ buf_hold = value >> 16;
+ }
+
+ /* Realign the source */
+ src = (const void *)i_src;
+ src += 2;
+ break;
+ case 0x3: /* Unaligned - Off by 3 */
+ /* Word align the source */
+ i_src = (const void *) (((unsigned)src + 4) & ~3);
+
+ /* Load the holding buffer */
+ buf_hold = *--i_src >> 8;
+
+ for (; c >= 4; c -= 4) {
+ value = *--i_src;
+ *--i_dst = buf_hold << 24 | value;
+ buf_hold = value >> 8;
+ }
+
+ /* Realign the source */
+ src = (const void *)i_src;
+ src += 3;
+ break;
+ }
+ dst = (void *)i_dst;
+ }
+
+ /* simple fast copy, ... unless a cache boundry is crossed */
+ /* Finish off any remaining bytes */
+ switch (c) {
+ case 4:
+ *--dst = *--src;
+ case 3:
+ *--dst = *--src;
+ case 2:
+ *--dst = *--src;
+ case 1:
+ *--dst = *--src;
+ }
+ return v_dst;
+#endif
+}
+EXPORT_SYMBOL(memmove);
+#endif /* __HAVE_ARCH_MEMMOVE */
diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c
new file mode 100644
index 00000000000..941dc8f94b0
--- /dev/null
+++ b/arch/microblaze/lib/memset.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2007 John Williams
+ *
+ * Reasonably optimised generic C-code for memset on Microblaze
+ * This is generic C code to do efficient, alignment-aware memcpy.
+ *
+ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
+ * http://www.embedded.com/showArticle.jhtml?articleID=19205567
+ *
+ * Attempts were made, unsuccesfully, to contact the original
+ * author of this code (Michael Morrow, Intel). Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#ifdef __HAVE_ARCH_MEMSET
+void *memset(void *v_src, int c, __kernel_size_t n)
+{
+
+ char *src = v_src;
+#ifdef CONFIG_OPT_LIB_FUNCTION
+ uint32_t *i_src;
+ uint32_t w32;
+#endif
+ /* Truncate c to 8 bits */
+ c = (c & 0xFF);
+
+#ifdef CONFIG_OPT_LIB_FUNCTION
+ /* Make a repeating word out of it */
+ w32 = c;
+ w32 |= w32 << 8;
+ w32 |= w32 << 16;
+
+ if (n >= 4) {
+ /* Align the destination to a word boundary */
+ /* This is done in an endian independant manner */
+ switch ((unsigned) src & 3) {
+ case 1:
+ *src++ = c;
+ --n;
+ case 2:
+ *src++ = c;
+ --n;
+ case 3:
+ *src++ = c;
+ --n;
+ }
+
+ i_src = (void *)src;
+
+ /* Do as many full-word copies as we can */
+ for (; n >= 4; n -= 4)
+ *i_src++ = w32;
+
+ src = (void *)i_src;
+ }
+#endif
+ /* Simple, byte oriented memset or the rest of count. */
+ while (n--)
+ *src++ = c;
+
+ return v_src;
+}
+EXPORT_SYMBOL(memset);
+#endif /* __HAVE_ARCH_MEMSET */
diff --git a/arch/microblaze/lib/uaccess.c b/arch/microblaze/lib/uaccess.c
new file mode 100644
index 00000000000..8eb9df5a26c
--- /dev/null
+++ b/arch/microblaze/lib/uaccess.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/string.h>
+#include <asm/uaccess.h>
+
+#include <asm/bug.h>
+
+long strnlen_user(const char __user *src, long count)
+{
+ return strlen(src) + 1;
+}
+
+#define __do_strncpy_from_user(dst, src, count, res) \
+ do { \
+ char *tmp; \
+ strncpy(dst, src, count); \
+ for (tmp = dst; *tmp && count > 0; tmp++, count--) \
+ ; \
+ res = (tmp - dst); \
+ } while (0)
+
+long __strncpy_from_user(char *dst, const char __user *src, long count)
+{
+ long res;
+ __do_strncpy_from_user(dst, src, count, res);
+ return res;
+}
+
+long strncpy_from_user(char *dst, const char __user *src, long count)
+{
+ long res = -EFAULT;
+ if (access_ok(VERIFY_READ, src, 1))
+ __do_strncpy_from_user(dst, src, count, res);
+ return res;
+}
diff --git a/arch/microblaze/mm/Makefile b/arch/microblaze/mm/Makefile
new file mode 100644
index 00000000000..bf9e4479a1f
--- /dev/null
+++ b/arch/microblaze/mm/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile
+#
+
+obj-y := init.o
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
new file mode 100644
index 00000000000..b0c8213cd6c
--- /dev/null
+++ b/arch/microblaze/mm/init.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/bootmem.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/lmb.h>
+#include <linux/mm.h> /* mem_init */
+#include <linux/initrd.h>
+#include <linux/pagemap.h>
+#include <linux/pfn.h>
+#include <linux/swap.h>
+
+#include <asm/page.h>
+#include <asm/mmu_context.h>
+#include <asm/pgalloc.h>
+#include <asm/sections.h>
+#include <asm/tlb.h>
+
+unsigned int __page_offset;
+/* EXPORT_SYMBOL(__page_offset); */
+
+char *klimit = _end;
+
+/*
+ * Initialize the bootmem system and give it all the memory we
+ * have available.
+ */
+unsigned int memory_start;
+unsigned int memory_end; /* due to mm/nommu.c */
+unsigned int memory_size;
+
+/*
+ * paging_init() sets up the page tables - in fact we've already done this.
+ */
+static void __init paging_init(void)
+{
+ int i;
+ unsigned long zones_size[MAX_NR_ZONES];
+
+ /*
+ * old: we can DMA to/from any address.put all page into ZONE_DMA
+ * We use only ZONE_NORMAL
+ */
+ zones_size[ZONE_NORMAL] = max_mapnr;
+
+ /* every other zones are empty */
+ for (i = 1; i < MAX_NR_ZONES; i++)
+ zones_size[i] = 0;
+
+ free_area_init(zones_size);
+}
+
+void __init setup_memory(void)
+{
+ int i;
+ unsigned long map_size;
+ u32 kernel_align_start, kernel_align_size;
+
+ /* Find main memory where is the kernel */
+ for (i = 0; i < lmb.memory.cnt; i++) {
+ memory_start = (u32) lmb.memory.region[i].base;
+ memory_end = (u32) lmb.memory.region[i].base
+ + (u32) lmb.memory.region[i].size;
+ if ((memory_start <= (u32)_text) &&
+ ((u32)_text <= memory_end)) {
+ memory_size = memory_end - memory_start;
+ PAGE_OFFSET = memory_start;
+ printk(KERN_INFO "%s: Main mem: 0x%x-0x%x, "
+ "size 0x%08x\n", __func__, memory_start,
+ memory_end, memory_size);
+ break;
+ }
+ }
+
+ if (!memory_start || !memory_end) {
+ panic("%s: Missing memory setting 0x%08x-0x%08x\n",
+ __func__, memory_start, memory_end);
+ }
+
+ /* reservation of region where is the kernel */
+ kernel_align_start = PAGE_DOWN((u32)_text);
+ /* ALIGN can be remove because _end in vmlinux.lds.S is align */
+ kernel_align_size = PAGE_UP((u32)klimit) - kernel_align_start;
+ lmb_reserve(kernel_align_start, kernel_align_size);
+ printk(KERN_INFO "%s: kernel addr=0x%08x-0x%08x size=0x%08x\n",
+ __func__, kernel_align_start, kernel_align_start
+ + kernel_align_size, kernel_align_size);
+
+ /*
+ * Kernel:
+ * start: base phys address of kernel - page align
+ * end: base phys address of kernel - page align
+ *
+ * min_low_pfn - the first page (mm/bootmem.c - node_boot_start)
+ * max_low_pfn
+ * max_mapnr - the first unused page (mm/bootmem.c - node_low_pfn)
+ * num_physpages - number of all pages
+ */
+
+ /* memory start is from the kernel end (aligned) to higher addr */
+ min_low_pfn = memory_start >> PAGE_SHIFT; /* minimum for allocation */
+ /* RAM is assumed contiguous */
+ num_physpages = max_mapnr = memory_size >> PAGE_SHIFT;
+ max_pfn = max_low_pfn = memory_end >> PAGE_SHIFT;
+
+ printk(KERN_INFO "%s: max_mapnr: %#lx\n", __func__, max_mapnr);
+ printk(KERN_INFO "%s: min_low_pfn: %#lx\n", __func__, min_low_pfn);
+ printk(KERN_INFO "%s: max_low_pfn: %#lx\n", __func__, max_low_pfn);
+
+ /*
+ * Find an area to use for the bootmem bitmap.
+ * We look for the first area which is at least
+ * 128kB in length (128kB is enough for a bitmap
+ * for 4GB of memory, using 4kB pages), plus 1 page
+ * (in case the address isn't page-aligned).
+ */
+ map_size = init_bootmem_node(NODE_DATA(0), PFN_UP(TOPHYS((u32)_end)),
+ min_low_pfn, max_low_pfn);
+
+ lmb_reserve(PFN_UP(TOPHYS((u32)_end)) << PAGE_SHIFT, map_size);
+
+ /* free bootmem is whole main memory */
+ free_bootmem(memory_start, memory_size);
+
+ /* reserve allocate blocks */
+ for (i = 0; i < lmb.reserved.cnt; i++) {
+ pr_debug("reserved %d - 0x%08x-0x%08x\n", i,
+ (u32) lmb.reserved.region[i].base,
+ (u32) lmb_size_bytes(&lmb.reserved, i));
+ reserve_bootmem(lmb.reserved.region[i].base,
+ lmb_size_bytes(&lmb.reserved, i) - 1, BOOTMEM_DEFAULT);
+ }
+ paging_init();
+}
+
+void free_init_pages(char *what, unsigned long begin, unsigned long end)
+{
+ unsigned long addr;
+
+ for (addr = begin; addr < end; addr += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(addr));
+ init_page_count(virt_to_page(addr));
+ memset((void *)addr, 0xcc, PAGE_SIZE);
+ free_page(addr);
+ totalram_pages++;
+ }
+ printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ int pages = 0;
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(start));
+ init_page_count(virt_to_page(start));
+ free_page(start);
+ totalram_pages++;
+ pages++;
+ }
+ printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
+}
+#endif
+
+void free_initmem(void)
+{
+ free_init_pages("unused kernel memory",
+ (unsigned long)(&__init_begin),
+ (unsigned long)(&__init_end));
+}
+
+/* FIXME from arch/powerpc/mm/mem.c*/
+void show_mem(void)
+{
+ printk(KERN_NOTICE "%s\n", __func__);
+}
+
+void __init mem_init(void)
+{
+ high_memory = (void *)__va(memory_end);
+ /* this will put all memory onto the freelists */
+ totalram_pages += free_all_bootmem();
+
+ printk(KERN_INFO "Memory: %luk/%luk available\n",
+ (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+ num_physpages << (PAGE_SHIFT-10));
+}
+
+/* Check against bounds of physical memory */
+int ___range_ok(unsigned long addr, unsigned long size)
+{
+ return ((addr < memory_start) ||
+ ((addr + size) > memory_end));
+}
diff --git a/arch/microblaze/platform/Kconfig.platform b/arch/microblaze/platform/Kconfig.platform
new file mode 100644
index 00000000000..8e9b4752d3f
--- /dev/null
+++ b/arch/microblaze/platform/Kconfig.platform
@@ -0,0 +1,85 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+# Platform selection Kconfig menu for MicroBlaze targets
+#
+
+menu "Platform options"
+choice
+ prompt "Platform"
+ default PLATFORM_MICROBLAZE_AUTO
+ help
+ Choose which hardware board/platform you are targeting.
+
+config PLATFORM_GENERIC
+ bool "Generic"
+ help
+ Choose this option for the Generic platform.
+
+endchoice
+
+config SELFMOD
+ bool "Use self modified code for intc/timer"
+ depends on EXPERIMENTAL && NO_MMU
+ default n
+ help
+ This choice enables self-modified code for interrupt controller
+ and timer.
+
+config SELFMOD_INTC
+ bool "Use self modified code for intc"
+ depends on SELFMOD
+ default y
+ help
+ This choice enables self-modified code for interrupt controller.
+
+config SELFMOD_TIMER
+ bool "Use self modified code for timer"
+ depends on SELFMOD
+ default y
+ help
+ This choice enables self-modified code for timer.
+
+config OPT_LIB_FUNCTION
+ bool "Optimalized lib function"
+ default y
+ help
+ Allows turn on optimalized library function (memcpy and memmove).
+ They are optimized by using word alignment. This will work
+ fine if both source and destination are aligned on the same
+ boundary. However, if they are aligned on different boundaries
+ shifts will be necessary. This might result in bad performance
+ on MicroBlaze systems without a barrel shifter.
+
+config OPT_LIB_ASM
+ bool "Optimalized lib function ASM"
+ depends on OPT_LIB_FUNCTION
+ default n
+ help
+ Allows turn on optimalized library function (memcpy and memmove).
+ Function are written in asm code.
+
+# This is still a bit broken - disabling for now JW 20070504
+config ALLOW_EDIT_AUTO
+ bool "Permit Display/edit of Kconfig.auto platform settings"
+ default n
+ help
+ Allows the editing of auto-generated platform settings from
+ the Kconfig.auto file. Obviously this does not change the
+ underlying hardware, so be very careful if you go editing
+ these settings.
+
+ Also, if you enable this, and edit various Kconfig.auto
+ settings, YOUR CHANGES WILL BE LOST if you then disable it
+ again. You have been warned!
+
+ If unsure, say no.
+
+comment "Automatic platform settings from Kconfig.auto"
+ depends on ALLOW_EDIT_AUTO
+
+if PLATFORM_GENERIC=y
+ source "arch/microblaze/platform/generic/Kconfig.auto"
+endif
+
+endmenu
diff --git a/arch/microblaze/platform/Makefile b/arch/microblaze/platform/Makefile
new file mode 100644
index 00000000000..ea1b75cc577
--- /dev/null
+++ b/arch/microblaze/platform/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for arch/microblaze/platform directory
+#
+#obj-$(CONFIG_PLATFORM_GENERIC) += generic/
+
+obj-y += platform.o
diff --git a/arch/microblaze/platform/generic/Kconfig.auto b/arch/microblaze/platform/generic/Kconfig.auto
new file mode 100644
index 00000000000..fbca22d9c8b
--- /dev/null
+++ b/arch/microblaze/platform/generic/Kconfig.auto
@@ -0,0 +1,62 @@
+#
+# (C) Copyright 2007 Michal Simek
+#
+# Michal SIMEK <monstr@monstr.eu>
+#
+# 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
+#
+
+# Definitions for MICROBLAZE0
+comment "Definitions for MICROBLAZE0"
+ depends on ALLOW_EDIT_AUTO
+
+config KERNEL_BASE_ADDR
+ hex "Physical address where Linux Kernel is"
+ default "0x90000000"
+ help
+ BASE Address for kernel
+
+config XILINX_MICROBLAZE0_FAMILY
+ string "Targetted FPGA family" if ALLOW_EDIT_AUTO
+ default "virtex5"
+
+config XILINX_MICROBLAZE0_USE_MSR_INSTR
+ int "USE_MSR_INSTR range (0:1)" if ALLOW_EDIT_AUTO
+ default 1
+
+config XILINX_MICROBLAZE0_USE_PCMP_INSTR
+ int "USE_PCMP_INSTR range (0:1)" if ALLOW_EDIT_AUTO
+ default 1
+
+config XILINX_MICROBLAZE0_USE_BARREL
+ int "USE_BARREL range (0:1)" if ALLOW_EDIT_AUTO
+ default 1
+
+config XILINX_MICROBLAZE0_USE_DIV
+ int "USE_DIV range (0:1)" if ALLOW_EDIT_AUTO
+ default 1
+
+config XILINX_MICROBLAZE0_USE_HW_MUL
+ int "USE_HW_MUL values (0=NONE, 1=MUL32, 2=MUL64)" if ALLOW_EDIT_AUTO
+ default 2
+
+config XILINX_MICROBLAZE0_USE_FPU
+ int "USE_FPU values (0=NONE, 1=BASIC, 2=EXTENDED)" if ALLOW_EDIT_AUTO
+ default 2
+
+config XILINX_MICROBLAZE0_HW_VER
+ string "Core version number" if ALLOW_EDIT_AUTO
+ default 7.10.d
diff --git a/arch/microblaze/platform/generic/Makefile b/arch/microblaze/platform/generic/Makefile
new file mode 100644
index 00000000000..9a8b1bd3fa6
--- /dev/null
+++ b/arch/microblaze/platform/generic/Makefile
@@ -0,0 +1,3 @@
+#
+# Empty Makefile to keep make clean happy
+#
diff --git a/arch/microblaze/platform/generic/system.dts b/arch/microblaze/platform/generic/system.dts
new file mode 100644
index 00000000000..29993f62b30
--- /dev/null
+++ b/arch/microblaze/platform/generic/system.dts
@@ -0,0 +1,332 @@
+/*
+ * Device Tree Generator version: 1.1
+ *
+ * (C) Copyright 2007-2008 Xilinx, Inc.
+ * (C) Copyright 2007-2009 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * 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
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 10.1.03 EDK_K_SP3.6
+ *
+ * XPS project directory: Xilinx-ML505-ll_temac-sgdma-MMU-FDT-edk101
+ */
+
+/dts-v1/;
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "xlnx,microblaze";
+ model = "testing";
+ DDR2_SDRAM: memory@90000000 {
+ device_type = "memory";
+ reg = < 0x90000000 0x10000000 >;
+ } ;
+ chosen {
+ bootargs = "console=ttyUL0,115200 highres=on";
+ linux,stdout-path = "/plb@0/serial@84000000";
+ } ;
+ cpus {
+ #address-cells = <1>;
+ #cpus = <0x1>;
+ #size-cells = <0>;
+ microblaze_0: cpu@0 {
+ clock-frequency = <125000000>;
+ compatible = "xlnx,microblaze-7.10.d";
+ d-cache-baseaddr = <0x90000000>;
+ d-cache-highaddr = <0x9fffffff>;
+ d-cache-line-size = <0x10>;
+ d-cache-size = <0x2000>;
+ device_type = "cpu";
+ i-cache-baseaddr = <0x90000000>;
+ i-cache-highaddr = <0x9fffffff>;
+ i-cache-line-size = <0x10>;
+ i-cache-size = <0x2000>;
+ model = "microblaze,7.10.d";
+ reg = <0>;
+ timebase-frequency = <125000000>;
+ xlnx,addr-tag-bits = <0xf>;
+ xlnx,allow-dcache-wr = <0x1>;
+ xlnx,allow-icache-wr = <0x1>;
+ xlnx,area-optimized = <0x0>;
+ xlnx,cache-byte-size = <0x2000>;
+ xlnx,d-lmb = <0x1>;
+ xlnx,d-opb = <0x0>;
+ xlnx,d-plb = <0x1>;
+ xlnx,data-size = <0x20>;
+ xlnx,dcache-addr-tag = <0xf>;
+ xlnx,dcache-always-used = <0x1>;
+ xlnx,dcache-byte-size = <0x2000>;
+ xlnx,dcache-line-len = <0x4>;
+ xlnx,dcache-use-fsl = <0x1>;
+ xlnx,debug-enabled = <0x1>;
+ xlnx,div-zero-exception = <0x1>;
+ xlnx,dopb-bus-exception = <0x0>;
+ xlnx,dynamic-bus-sizing = <0x1>;
+ xlnx,edge-is-positive = <0x1>;
+ xlnx,family = "virtex5";
+ xlnx,fpu-exception = <0x1>;
+ xlnx,fsl-data-size = <0x20>;
+ xlnx,fsl-exception = <0x0>;
+ xlnx,fsl-links = <0x0>;
+ xlnx,i-lmb = <0x1>;
+ xlnx,i-opb = <0x0>;
+ xlnx,i-plb = <0x1>;
+ xlnx,icache-always-used = <0x1>;
+ xlnx,icache-line-len = <0x4>;
+ xlnx,icache-use-fsl = <0x1>;
+ xlnx,ill-opcode-exception = <0x1>;
+ xlnx,instance = "microblaze_0";
+ xlnx,interconnect = <0x1>;
+ xlnx,interrupt-is-edge = <0x0>;
+ xlnx,iopb-bus-exception = <0x0>;
+ xlnx,mmu-dtlb-size = <0x4>;
+ xlnx,mmu-itlb-size = <0x2>;
+ xlnx,mmu-tlb-access = <0x3>;
+ xlnx,mmu-zones = <0x10>;
+ xlnx,number-of-pc-brk = <0x1>;
+ xlnx,number-of-rd-addr-brk = <0x0>;
+ xlnx,number-of-wr-addr-brk = <0x0>;
+ xlnx,opcode-0x0-illegal = <0x1>;
+ xlnx,pvr = <0x2>;
+ xlnx,pvr-user1 = <0x0>;
+ xlnx,pvr-user2 = <0x0>;
+ xlnx,reset-msr = <0x0>;
+ xlnx,sco = <0x0>;
+ xlnx,unaligned-exceptions = <0x1>;
+ xlnx,use-barrel = <0x1>;
+ xlnx,use-dcache = <0x1>;
+ xlnx,use-div = <0x1>;
+ xlnx,use-ext-brk = <0x1>;
+ xlnx,use-ext-nm-brk = <0x1>;
+ xlnx,use-extended-fsl-instr = <0x0>;
+ xlnx,use-fpu = <0x2>;
+ xlnx,use-hw-mul = <0x2>;
+ xlnx,use-icache = <0x1>;
+ xlnx,use-interrupt = <0x1>;
+ xlnx,use-mmu = <0x3>;
+ xlnx,use-msr-instr = <0x1>;
+ xlnx,use-pcmp-instr = <0x1>;
+ } ;
+ } ;
+ mb_plb: plb@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "xlnx,plb-v46-1.03.a", "simple-bus";
+ ranges ;
+ FLASH: flash@a0000000 {
+ bank-width = <2>;
+ compatible = "xlnx,xps-mch-emc-2.00.a", "cfi-flash";
+ reg = < 0xa0000000 0x2000000 >;
+ xlnx,family = "virtex5";
+ xlnx,include-datawidth-matching-0 = <0x1>;
+ xlnx,include-datawidth-matching-1 = <0x0>;
+ xlnx,include-datawidth-matching-2 = <0x0>;
+ xlnx,include-datawidth-matching-3 = <0x0>;
+ xlnx,include-negedge-ioregs = <0x0>;
+ xlnx,include-plb-ipif = <0x1>;
+ xlnx,include-wrbuf = <0x1>;
+ xlnx,max-mem-width = <0x10>;
+ xlnx,mch-native-dwidth = <0x20>;
+ xlnx,mch-plb-clk-period-ps = <0x1f40>;
+ xlnx,mch-splb-awidth = <0x20>;
+ xlnx,mch0-accessbuf-depth = <0x10>;
+ xlnx,mch0-protocol = <0x0>;
+ xlnx,mch0-rddatabuf-depth = <0x10>;
+ xlnx,mch1-accessbuf-depth = <0x10>;
+ xlnx,mch1-protocol = <0x0>;
+ xlnx,mch1-rddatabuf-depth = <0x10>;
+ xlnx,mch2-accessbuf-depth = <0x10>;
+ xlnx,mch2-protocol = <0x0>;
+ xlnx,mch2-rddatabuf-depth = <0x10>;
+ xlnx,mch3-accessbuf-depth = <0x10>;
+ xlnx,mch3-protocol = <0x0>;
+ xlnx,mch3-rddatabuf-depth = <0x10>;
+ xlnx,mem0-width = <0x10>;
+ xlnx,mem1-width = <0x20>;
+ xlnx,mem2-width = <0x20>;
+ xlnx,mem3-width = <0x20>;
+ xlnx,num-banks-mem = <0x1>;
+ xlnx,num-channels = <0x0>;
+ xlnx,priority-mode = <0x0>;
+ xlnx,synch-mem-0 = <0x0>;
+ xlnx,synch-mem-1 = <0x0>;
+ xlnx,synch-mem-2 = <0x0>;
+ xlnx,synch-mem-3 = <0x0>;
+ xlnx,synch-pipedelay-0 = <0x2>;
+ xlnx,synch-pipedelay-1 = <0x2>;
+ xlnx,synch-pipedelay-2 = <0x2>;
+ xlnx,synch-pipedelay-3 = <0x2>;
+ xlnx,tavdv-ps-mem-0 = <0x1adb0>;
+ xlnx,tavdv-ps-mem-1 = <0x3a98>;
+ xlnx,tavdv-ps-mem-2 = <0x3a98>;
+ xlnx,tavdv-ps-mem-3 = <0x3a98>;
+ xlnx,tcedv-ps-mem-0 = <0x1adb0>;
+ xlnx,tcedv-ps-mem-1 = <0x3a98>;
+ xlnx,tcedv-ps-mem-2 = <0x3a98>;
+ xlnx,tcedv-ps-mem-3 = <0x3a98>;
+ xlnx,thzce-ps-mem-0 = <0x88b8>;
+ xlnx,thzce-ps-mem-1 = <0x1b58>;
+ xlnx,thzce-ps-mem-2 = <0x1b58>;
+ xlnx,thzce-ps-mem-3 = <0x1b58>;
+ xlnx,thzoe-ps-mem-0 = <0x1b58>;
+ xlnx,thzoe-ps-mem-1 = <0x1b58>;
+ xlnx,thzoe-ps-mem-2 = <0x1b58>;
+ xlnx,thzoe-ps-mem-3 = <0x1b58>;
+ xlnx,tlzwe-ps-mem-0 = <0x88b8>;
+ xlnx,tlzwe-ps-mem-1 = <0x0>;
+ xlnx,tlzwe-ps-mem-2 = <0x0>;
+ xlnx,tlzwe-ps-mem-3 = <0x0>;
+ xlnx,twc-ps-mem-0 = <0x2af8>;
+ xlnx,twc-ps-mem-1 = <0x3a98>;
+ xlnx,twc-ps-mem-2 = <0x3a98>;
+ xlnx,twc-ps-mem-3 = <0x3a98>;
+ xlnx,twp-ps-mem-0 = <0x11170>;
+ xlnx,twp-ps-mem-1 = <0x2ee0>;
+ xlnx,twp-ps-mem-2 = <0x2ee0>;
+ xlnx,twp-ps-mem-3 = <0x2ee0>;
+ xlnx,xcl0-linesize = <0x4>;
+ xlnx,xcl0-writexfer = <0x1>;
+ xlnx,xcl1-linesize = <0x4>;
+ xlnx,xcl1-writexfer = <0x1>;
+ xlnx,xcl2-linesize = <0x4>;
+ xlnx,xcl2-writexfer = <0x1>;
+ xlnx,xcl3-linesize = <0x4>;
+ xlnx,xcl3-writexfer = <0x1>;
+ } ;
+ Hard_Ethernet_MAC: xps-ll-temac@81c00000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "xlnx,compound";
+ ethernet@81c00000 {
+ compatible = "xlnx,xps-ll-temac-1.01.b";
+ device_type = "network";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 5 2 >;
+ llink-connected = <&PIM3>;
+ local-mac-address = [ 02 00 00 00 00 00 ];
+ reg = < 0x81c00000 0x40 >;
+ xlnx,bus2core-clk-ratio = <0x1>;
+ xlnx,phy-type = <0x1>;
+ xlnx,phyaddr = <0x1>;
+ xlnx,rxcsum = <0x0>;
+ xlnx,rxfifo = <0x1000>;
+ xlnx,temac-type = <0x0>;
+ xlnx,txcsum = <0x0>;
+ xlnx,txfifo = <0x1000>;
+ } ;
+ } ;
+ IIC_EEPROM: i2c@81600000 {
+ compatible = "xlnx,xps-iic-2.00.a";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 6 2 >;
+ reg = < 0x81600000 0x10000 >;
+ xlnx,clk-freq = <0x7735940>;
+ xlnx,family = "virtex5";
+ xlnx,gpo-width = <0x1>;
+ xlnx,iic-freq = <0x186a0>;
+ xlnx,scl-inertial-delay = <0x0>;
+ xlnx,sda-inertial-delay = <0x0>;
+ xlnx,ten-bit-adr = <0x0>;
+ } ;
+ LEDs_8Bit: gpio@81400000 {
+ compatible = "xlnx,xps-gpio-1.00.a";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 7 2 >;
+ reg = < 0x81400000 0x10000 >;
+ xlnx,all-inputs = <0x0>;
+ xlnx,all-inputs-2 = <0x0>;
+ xlnx,dout-default = <0x0>;
+ xlnx,dout-default-2 = <0x0>;
+ xlnx,family = "virtex5";
+ xlnx,gpio-width = <0x8>;
+ xlnx,interrupt-present = <0x1>;
+ xlnx,is-bidir = <0x1>;
+ xlnx,is-bidir-2 = <0x1>;
+ xlnx,is-dual = <0x0>;
+ xlnx,tri-default = <0xffffffff>;
+ xlnx,tri-default-2 = <0xffffffff>;
+ } ;
+ RS232_Uart_1: serial@84000000 {
+ clock-frequency = <125000000>;
+ compatible = "xlnx,xps-uartlite-1.00.a";
+ current-speed = <115200>;
+ device_type = "serial";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 8 0 >;
+ port-number = <0>;
+ reg = < 0x84000000 0x10000 >;
+ xlnx,baudrate = <0x1c200>;
+ xlnx,data-bits = <0x8>;
+ xlnx,family = "virtex5";
+ xlnx,odd-parity = <0x0>;
+ xlnx,use-parity = <0x0>;
+ } ;
+ SysACE_CompactFlash: sysace@83600000 {
+ compatible = "xlnx,xps-sysace-1.00.a";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 4 2 >;
+ reg = < 0x83600000 0x10000 >;
+ xlnx,family = "virtex5";
+ xlnx,mem-width = <0x10>;
+ } ;
+ debug_module: debug@84400000 {
+ compatible = "xlnx,mdm-1.00.d";
+ reg = < 0x84400000 0x10000 >;
+ xlnx,family = "virtex5";
+ xlnx,interconnect = <0x1>;
+ xlnx,jtag-chain = <0x2>;
+ xlnx,mb-dbg-ports = <0x1>;
+ xlnx,uart-width = <0x8>;
+ xlnx,use-uart = <0x1>;
+ xlnx,write-fsl-ports = <0x0>;
+ } ;
+ mpmc@90000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "xlnx,mpmc-4.02.a";
+ PIM3: sdma@84600180 {
+ compatible = "xlnx,ll-dma-1.00.a";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 2 2 1 2 >;
+ reg = < 0x84600180 0x80 >;
+ } ;
+ } ;
+ xps_intc_0: interrupt-controller@81800000 {
+ #interrupt-cells = <0x2>;
+ compatible = "xlnx,xps-intc-1.00.a";
+ interrupt-controller ;
+ reg = < 0x81800000 0x10000 >;
+ xlnx,kind-of-intr = <0x100>;
+ xlnx,num-intr-inputs = <0x9>;
+ } ;
+ xps_timer_1: timer@83c00000 {
+ compatible = "xlnx,xps-timer-1.00.a";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 3 2 >;
+ reg = < 0x83c00000 0x10000 >;
+ xlnx,count-width = <0x20>;
+ xlnx,family = "virtex5";
+ xlnx,gen0-assert = <0x1>;
+ xlnx,gen1-assert = <0x1>;
+ xlnx,one-timer-only = <0x0>;
+ xlnx,trig0-assert = <0x1>;
+ xlnx,trig1-assert = <0x1>;
+ } ;
+ } ;
+} ;
diff --git a/arch/microblaze/platform/platform.c b/arch/microblaze/platform/platform.c
new file mode 100644
index 00000000000..56e0234fa34
--- /dev/null
+++ b/arch/microblaze/platform/platform.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2008 Michal Simek <monstr@monstr.eu>
+ *
+ * based on virtex.c file
+ *
+ * Copyright 2007 Secret Lab Technologies Ltd.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+static struct of_device_id xilinx_of_bus_ids[] __initdata = {
+ { .compatible = "simple-bus", },
+ { .compatible = "xlnx,plb-v46-1.00.a", },
+ { .compatible = "xlnx,opb-v20-1.10.c", },
+ { .compatible = "xlnx,opb-v20-1.10.b", },
+ { .compatible = "xlnx,compound", },
+ {}
+};
+
+static int __init microblaze_device_probe(void)
+{
+ of_platform_bus_probe(NULL, xilinx_of_bus_ids, NULL);
+ return 0;
+}
+device_initcall(microblaze_device_probe);
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index dc787190430..998e5db8cc0 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -134,7 +134,7 @@ config MACH_JAZZ
help
This a family of machines based on the MIPS R4030 chipset which was
used by several vendors to build RISC/os and Windows NT workstations.
- Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
+ Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
Olivetti M700-10 workstations.
config LASAT
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index 5c76c6448e0..117f99f7064 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -80,14 +80,14 @@ static struct resource au1xxx_usb_ohci_resources[] = {
};
/* The dmamask must be set for OHCI to work */
-static u64 ohci_dmamask = DMA_32BIT_MASK;
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1xxx_usb_ohci_device = {
.name = "au1xxx-ohci",
.id = 0,
.dev = {
.dma_mask = &ohci_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1xxx_usb_ohci_resources),
.resource = au1xxx_usb_ohci_resources,
@@ -109,14 +109,14 @@ static struct resource au1100_lcd_resources[] = {
}
};
-static u64 au1100_lcd_dmamask = DMA_32BIT_MASK;
+static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1100_lcd_device = {
.name = "au1100-lcd",
.id = 0,
.dev = {
.dma_mask = &au1100_lcd_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1100_lcd_resources),
.resource = au1100_lcd_resources,
@@ -138,14 +138,14 @@ static struct resource au1xxx_usb_ehci_resources[] = {
},
};
-static u64 ehci_dmamask = DMA_32BIT_MASK;
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1xxx_usb_ehci_device = {
.name = "au1xxx-ehci",
.id = 0,
.dev = {
.dma_mask = &ehci_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1xxx_usb_ehci_resources),
.resource = au1xxx_usb_ehci_resources,
@@ -165,14 +165,14 @@ static struct resource au1xxx_usb_gdt_resources[] = {
},
};
-static u64 udc_dmamask = DMA_32BIT_MASK;
+static u64 udc_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1xxx_usb_gdt_device = {
.name = "au1xxx-udc",
.id = 0,
.dev = {
.dma_mask = &udc_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1xxx_usb_gdt_resources),
.resource = au1xxx_usb_gdt_resources,
@@ -192,14 +192,14 @@ static struct resource au1xxx_usb_otg_resources[] = {
},
};
-static u64 uoc_dmamask = DMA_32BIT_MASK;
+static u64 uoc_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1xxx_usb_otg_device = {
.name = "au1xxx-uoc",
.id = 0,
.dev = {
.dma_mask = &uoc_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1xxx_usb_otg_resources),
.resource = au1xxx_usb_otg_resources,
@@ -218,20 +218,20 @@ static struct resource au1200_lcd_resources[] = {
}
};
-static u64 au1200_lcd_dmamask = DMA_32BIT_MASK;
+static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1200_lcd_device = {
.name = "au1200-lcd",
.id = 0,
.dev = {
.dma_mask = &au1200_lcd_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1200_lcd_resources),
.resource = au1200_lcd_resources,
};
-static u64 au1xxx_mmc_dmamask = DMA_32BIT_MASK;
+static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
extern struct au1xmmc_platform_data au1xmmc_platdata[2];
@@ -263,7 +263,7 @@ static struct platform_device au1200_mmc0_device = {
.id = 0,
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &au1xmmc_platdata[0],
},
.num_resources = ARRAY_SIZE(au1200_mmc0_resources),
@@ -299,7 +299,7 @@ static struct platform_device au1200_mmc1_device = {
.id = 1,
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &au1xmmc_platdata[1],
},
.num_resources = ARRAY_SIZE(au1200_mmc1_resources),
diff --git a/arch/mips/alchemy/devboards/pb1200/platform.c b/arch/mips/alchemy/devboards/pb1200/platform.c
index 0d68e1985ff..b93dff4a678 100644
--- a/arch/mips/alchemy/devboards/pb1200/platform.c
+++ b/arch/mips/alchemy/devboards/pb1200/platform.c
@@ -119,14 +119,14 @@ static struct resource ide_resources[] = {
}
};
-static u64 ide_dmamask = DMA_32BIT_MASK;
+static u64 ide_dmamask = DMA_BIT_MASK(32);
static struct platform_device ide_device = {
.name = "au1200-ide",
.id = 0,
.dev = {
.dma_mask = &ide_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(ide_resources),
.resource = ide_resources
diff --git a/arch/mips/include/asm/ftrace.h b/arch/mips/include/asm/ftrace.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/mips/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/mips/include/asm/mach-rc32434/gpio.h b/arch/mips/include/asm/mach-rc32434/gpio.h
index 3cb50d17b62..12ee8d51016 100644
--- a/arch/mips/include/asm/mach-rc32434/gpio.h
+++ b/arch/mips/include/asm/mach-rc32434/gpio.h
@@ -80,6 +80,9 @@ struct rb532_gpio_reg {
/* Compact Flash GPIO pin */
#define CF_GPIO_NUM 13
+/* S1 button GPIO (shared with UART0_SIN) */
+#define GPIO_BTN_S1 1
+
extern void rb532_gpio_set_ilevel(int bit, unsigned gpio);
extern void rb532_gpio_set_istat(int bit, unsigned gpio);
extern void rb532_gpio_set_func(unsigned gpio);
diff --git a/arch/mips/include/asm/txx9/ndfmc.h b/arch/mips/include/asm/txx9/ndfmc.h
new file mode 100644
index 00000000000..fa67f3df78f
--- /dev/null
+++ b/arch/mips/include/asm/txx9/ndfmc.h
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ *
+ * (C) Copyright TOSHIBA CORPORATION 2007
+ */
+#ifndef __ASM_TXX9_NDFMC_H
+#define __ASM_TXX9_NDFMC_H
+
+#define NDFMC_PLAT_FLAG_USE_BSPRT 0x01
+#define NDFMC_PLAT_FLAG_NO_RSTR 0x02
+#define NDFMC_PLAT_FLAG_HOLDADD 0x04
+#define NDFMC_PLAT_FLAG_DUMMYWRITE 0x08
+
+struct txx9ndfmc_platform_data {
+ unsigned int shift;
+ unsigned int gbus_clock;
+ unsigned int hold; /* hold time in nanosecond */
+ unsigned int spw; /* strobe pulse width in nanosecond */
+ unsigned int flags;
+ unsigned char ch_mask; /* available channel bitmask */
+ unsigned char wp_mask; /* write-protect bitmask */
+ unsigned char wide_mask; /* 16bit-nand bitmask */
+};
+
+void txx9_ndfmc_init(unsigned long baseaddr,
+ const struct txx9ndfmc_platform_data *plat_data);
+
+#endif /* __ASM_TXX9_NDFMC_H */
diff --git a/arch/mips/include/asm/txx9/rbtx4939.h b/arch/mips/include/asm/txx9/rbtx4939.h
index 1acf428c0b4..e517899794a 100644
--- a/arch/mips/include/asm/txx9/rbtx4939.h
+++ b/arch/mips/include/asm/txx9/rbtx4939.h
@@ -130,4 +130,13 @@
void rbtx4939_prom_init(void);
void rbtx4939_irq_setup(void);
+struct mtd_partition;
+struct map_info;
+struct rbtx4939_flash_data {
+ unsigned int width;
+ unsigned int nr_parts;
+ struct mtd_partition *parts;
+ void (*map_init)(struct map_info *map);
+};
+
#endif /* __ASM_TXX9_RBTX4939_H */
diff --git a/arch/mips/include/asm/txx9/tx4938.h b/arch/mips/include/asm/txx9/tx4938.h
index 0b068154054..cd8bc202175 100644
--- a/arch/mips/include/asm/txx9/tx4938.h
+++ b/arch/mips/include/asm/txx9/tx4938.h
@@ -291,6 +291,7 @@ int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot);
void tx4938_setup_pcierr_irq(void);
void tx4938_irq_init(void);
void tx4938_mtd_init(int ch);
+void tx4938_ndfmc_init(unsigned int hold, unsigned int spw);
struct tx4938ide_platform_info {
/*
diff --git a/arch/mips/include/asm/txx9/tx4939.h b/arch/mips/include/asm/txx9/tx4939.h
index 964ef7ede26..f02c50b3abf 100644
--- a/arch/mips/include/asm/txx9/tx4939.h
+++ b/arch/mips/include/asm/txx9/tx4939.h
@@ -542,5 +542,7 @@ int tx4939_irq(void);
void tx4939_mtd_init(int ch);
void tx4939_ata_init(void);
void tx4939_rtc_init(void);
+void tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
+ unsigned char ch_mask, unsigned char wide_mask);
#endif /* __ASM_TXX9_TX4939_H */
diff --git a/arch/mips/nxp/pnx833x/common/platform.c b/arch/mips/nxp/pnx833x/common/platform.c
index b1ccbcc18f7..01f8345a206 100644
--- a/arch/mips/nxp/pnx833x/common/platform.c
+++ b/arch/mips/nxp/pnx833x/common/platform.c
@@ -42,7 +42,7 @@
#include <irq-mapping.h>
#include <pnx833x.h>
-static u64 uart_dmamask = DMA_32BIT_MASK;
+static u64 uart_dmamask = DMA_BIT_MASK(32);
static struct resource pnx833x_uart_resources[] = {
[0] = {
@@ -101,14 +101,14 @@ static struct platform_device pnx833x_uart_device = {
.id = -1,
.dev = {
.dma_mask = &uart_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = pnx8xxx_ports,
},
.num_resources = ARRAY_SIZE(pnx833x_uart_resources),
.resource = pnx833x_uart_resources,
};
-static u64 ehci_dmamask = DMA_32BIT_MASK;
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
static struct resource pnx833x_usb_ehci_resources[] = {
[0] = {
@@ -128,7 +128,7 @@ static struct platform_device pnx833x_usb_ehci_device = {
.id = -1,
.dev = {
.dma_mask = &ehci_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(pnx833x_usb_ehci_resources),
.resource = pnx833x_usb_ehci_resources,
@@ -198,7 +198,7 @@ static struct platform_device pnx833x_i2c1_device = {
};
#endif
-static u64 ethernet_dmamask = DMA_32BIT_MASK;
+static u64 ethernet_dmamask = DMA_BIT_MASK(32);
static struct resource pnx833x_ethernet_resources[] = {
[0] = {
@@ -218,7 +218,7 @@ static struct platform_device pnx833x_ethernet_device = {
.id = -1,
.dev = {
.dma_mask = &ethernet_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(pnx833x_ethernet_resources),
.resource = pnx833x_ethernet_resources,
diff --git a/arch/mips/nxp/pnx8550/common/platform.c b/arch/mips/nxp/pnx8550/common/platform.c
index 21d2955359b..5264cc09a27 100644
--- a/arch/mips/nxp/pnx8550/common/platform.c
+++ b/arch/mips/nxp/pnx8550/common/platform.c
@@ -92,16 +92,16 @@ struct pnx8xxx_port pnx8xxx_ports[] = {
};
/* The dmamask must be set for OHCI to work */
-static u64 ohci_dmamask = DMA_32BIT_MASK;
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
-static u64 uart_dmamask = DMA_32BIT_MASK;
+static u64 uart_dmamask = DMA_BIT_MASK(32);
static struct platform_device pnx8550_usb_ohci_device = {
.name = "pnx8550-ohci",
.id = -1,
.dev = {
.dma_mask = &ohci_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources),
.resource = pnx8550_usb_ohci_resources,
@@ -112,7 +112,7 @@ static struct platform_device pnx8550_uart_device = {
.id = -1,
.dev = {
.dma_mask = &uart_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = pnx8xxx_ports,
},
.num_resources = ARRAY_SIZE(pnx8550_uart_resources),
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_usb.c b/arch/mips/pmc-sierra/msp71xx/msp_usb.c
index f7ca4f58233..0ee01e359dd 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_usb.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_usb.c
@@ -49,14 +49,14 @@ static struct resource msp_usbhost_resources [] = {
},
};
-static u64 msp_usbhost_dma_mask = DMA_32BIT_MASK;
+static u64 msp_usbhost_dma_mask = DMA_BIT_MASK(32);
static struct platform_device msp_usbhost_device = {
.name = "pmcmsp-ehci",
.id = 0,
.dev = {
.dma_mask = &msp_usbhost_dma_mask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(msp_usbhost_resources),
.resource = msp_usbhost_resources,
@@ -77,14 +77,14 @@ static struct resource msp_usbdev_resources [] = {
},
};
-static u64 msp_usbdev_dma_mask = DMA_32BIT_MASK;
+static u64 msp_usbdev_dma_mask = DMA_BIT_MASK(32);
static struct platform_device msp_usbdev_device = {
.name = "msp71xx_udc",
.id = 0,
.dev = {
.dma_mask = &msp_usbdev_dma_mask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(msp_usbdev_resources),
.resource = msp_usbdev_resources,
diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index 4a5f05b662a..9f40e1ff9b4 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -200,26 +200,9 @@ static struct platform_device rb532_led = {
.id = -1,
};
-static struct gpio_keys_button rb532_gpio_btn[] = {
- {
- .gpio = 1,
- .code = BTN_0,
- .desc = "S1",
- .active_low = 1,
- }
-};
-
-static struct gpio_keys_platform_data rb532_gpio_btn_data = {
- .buttons = rb532_gpio_btn,
- .nbuttons = ARRAY_SIZE(rb532_gpio_btn),
-};
-
static struct platform_device rb532_button = {
- .name = "gpio-keys",
+ .name = "rb532-button",
.id = -1,
- .dev = {
- .platform_data = &rb532_gpio_btn_data,
- }
};
static struct resource rb532_wdt_res[] = {
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index 5b47d6b6527..cbcd7eb83bd 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -221,7 +221,7 @@ static void __init ip27_smp_setup(void)
* Assumption to be fixed: we're always booted on logical / physical
* processor 0. While we're always running on logical processor 0
* this still means this is physical processor zero; it might for
- * example be disabled in the firwware.
+ * example be disabled in the firmware.
*/
alloc_cpupda(0, 0);
}
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index a13a08b8c9e..8a266c6a3f5 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -32,6 +32,7 @@
#include <asm/txx9/generic.h>
#include <asm/txx9/pci.h>
#include <asm/txx9tmr.h>
+#include <asm/txx9/ndfmc.h>
#ifdef CONFIG_CPU_TX49XX
#include <asm/txx9/tx4938.h>
#endif
@@ -691,6 +692,26 @@ void __init txx9_physmap_flash_init(int no, unsigned long addr,
#endif
}
+void __init txx9_ndfmc_init(unsigned long baseaddr,
+ const struct txx9ndfmc_platform_data *pdata)
+{
+#if defined(CONFIG_MTD_NAND_TXX9NDFMC) || \
+ defined(CONFIG_MTD_NAND_TXX9NDFMC_MODULE)
+ struct resource res = {
+ .start = baseaddr,
+ .end = baseaddr + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ };
+ struct platform_device *pdev = platform_device_alloc("txx9ndfmc", -1);
+
+ if (!pdev ||
+ platform_device_add_resources(pdev, &res, 1) ||
+ platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
+ platform_device_add(pdev))
+ platform_device_put(pdev);
+#endif
+}
+
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
static DEFINE_SPINLOCK(txx9_iocled_lock);
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c
index 25819ff1c35..f0844f891f0 100644
--- a/arch/mips/txx9/generic/setup_tx4938.c
+++ b/arch/mips/txx9/generic/setup_tx4938.c
@@ -23,6 +23,7 @@
#include <asm/txx9tmr.h>
#include <asm/txx9pio.h>
#include <asm/txx9/generic.h>
+#include <asm/txx9/ndfmc.h>
#include <asm/txx9/tx4938.h>
static void __init tx4938_wdr_init(void)
@@ -382,6 +383,26 @@ void __init tx4938_ata_init(unsigned int irq, unsigned int shift, int tune)
platform_device_put(pdev);
}
+void __init tx4938_ndfmc_init(unsigned int hold, unsigned int spw)
+{
+ struct txx9ndfmc_platform_data plat_data = {
+ .shift = 1,
+ .gbus_clock = txx9_gbus_clock,
+ .hold = hold,
+ .spw = spw,
+ .ch_mask = 1,
+ };
+ unsigned long baseaddr = TX4938_NDFMC_REG & 0xfffffffffULL;
+
+#ifdef __BIG_ENDIAN
+ baseaddr += 4;
+#endif
+ if ((__raw_readq(&tx4938_ccfgptr->pcfg) &
+ (TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL)) ==
+ TX4938_PCFG_NDF_SEL)
+ txx9_ndfmc_init(baseaddr, &plat_data);
+}
+
static void __init tx4938_stop_unused_modules(void)
{
__u64 pcfg, rst = 0, ckd = 0;
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
index 55440967b3a..7a25b573e9b 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -27,6 +27,7 @@
#include <asm/txx9irq.h>
#include <asm/txx9tmr.h>
#include <asm/txx9/generic.h>
+#include <asm/txx9/ndfmc.h>
#include <asm/txx9/tx4939.h>
static void __init tx4939_wdr_init(void)
@@ -457,6 +458,22 @@ void __init tx4939_rtc_init(void)
platform_device_register(&rtc_dev);
}
+void __init tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
+ unsigned char ch_mask, unsigned char wide_mask)
+{
+ struct txx9ndfmc_platform_data plat_data = {
+ .shift = 1,
+ .gbus_clock = txx9_gbus_clock,
+ .hold = hold,
+ .spw = spw,
+ .flags = NDFMC_PLAT_FLAG_NO_RSTR | NDFMC_PLAT_FLAG_HOLDADD |
+ NDFMC_PLAT_FLAG_DUMMYWRITE,
+ .ch_mask = ch_mask,
+ .wide_mask = wide_mask,
+ };
+ txx9_ndfmc_init(TX4939_NDFMC_REG & 0xfffffffffULL, &plat_data);
+}
+
static void __init tx4939_stop_unused_modules(void)
{
__u64 pcfg, rst = 0, ckd = 0;
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c
index 547ff2920bf..65d13df8878 100644
--- a/arch/mips/txx9/rbtx4938/setup.c
+++ b/arch/mips/txx9/rbtx4938/setup.c
@@ -352,6 +352,8 @@ static void __init rbtx4938_device_init(void)
rbtx4938_ne_init();
tx4938_wdt_init();
rbtx4938_mtd_init();
+ /* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
+ tx4938_ndfmc_init(10, 35);
tx4938_ata_init(RBTX4938_IRQ_IOC_ATA, 0, 1);
txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL);
}
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
index 656603b85b7..011e1e332f4 100644
--- a/arch/mips/txx9/rbtx4939/setup.c
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -16,6 +16,9 @@
#include <linux/leds.h>
#include <linux/interrupt.h>
#include <linux/smc91x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/map.h>
#include <asm/reboot.h>
#include <asm/txx9/generic.h>
#include <asm/txx9/pci.h>
@@ -282,6 +285,159 @@ static void rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
__rbtx4939_7segled_putc(pos, val);
}
+#if defined(CONFIG_MTD_RBTX4939) || defined(CONFIG_MTD_RBTX4939_MODULE)
+/* special mapping for boot rom */
+static unsigned long rbtx4939_flash_fixup_ofs(unsigned long ofs)
+{
+ u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
+ unsigned char shift;
+
+ if (bdipsw & 8) {
+ /* BOOT Mode: USER ROM1 / USER ROM2 */
+ shift = bdipsw & 3;
+ /* rotate A[23:22] */
+ return (ofs & ~0xc00000) | ((((ofs >> 22) + shift) & 3) << 22);
+ }
+#ifdef __BIG_ENDIAN
+ if (bdipsw == 0)
+ /* BOOT Mode: Monitor ROM */
+ ofs ^= 0x400000; /* swap A[22] */
+#endif
+ return ofs;
+}
+
+static map_word rbtx4939_flash_read16(struct map_info *map, unsigned long ofs)
+{
+ map_word r;
+
+ ofs = rbtx4939_flash_fixup_ofs(ofs);
+ r.x[0] = __raw_readw(map->virt + ofs);
+ return r;
+}
+
+static void rbtx4939_flash_write16(struct map_info *map, const map_word datum,
+ unsigned long ofs)
+{
+ ofs = rbtx4939_flash_fixup_ofs(ofs);
+ __raw_writew(datum.x[0], map->virt + ofs);
+ mb(); /* see inline_map_write() in mtd/map.h */
+}
+
+static void rbtx4939_flash_copy_from(struct map_info *map, void *to,
+ unsigned long from, ssize_t len)
+{
+ u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
+ unsigned char shift;
+ ssize_t curlen;
+
+ from += (unsigned long)map->virt;
+ if (bdipsw & 8) {
+ /* BOOT Mode: USER ROM1 / USER ROM2 */
+ shift = bdipsw & 3;
+ while (len) {
+ curlen = min_t(unsigned long, len,
+ 0x400000 - (from & (0x400000 - 1)));
+ memcpy(to,
+ (void *)((from & ~0xc00000) |
+ ((((from >> 22) + shift) & 3) << 22)),
+ curlen);
+ len -= curlen;
+ from += curlen;
+ to += curlen;
+ }
+ return;
+ }
+#ifdef __BIG_ENDIAN
+ if (bdipsw == 0) {
+ /* BOOT Mode: Monitor ROM */
+ while (len) {
+ curlen = min_t(unsigned long, len,
+ 0x400000 - (from & (0x400000 - 1)));
+ memcpy(to, (void *)(from ^ 0x400000), curlen);
+ len -= curlen;
+ from += curlen;
+ to += curlen;
+ }
+ return;
+ }
+#endif
+ memcpy(to, (void *)from, len);
+}
+
+static void rbtx4939_flash_map_init(struct map_info *map)
+{
+ map->read = rbtx4939_flash_read16;
+ map->write = rbtx4939_flash_write16;
+ map->copy_from = rbtx4939_flash_copy_from;
+}
+
+static void __init rbtx4939_mtd_init(void)
+{
+ static struct {
+ struct platform_device dev;
+ struct resource res;
+ struct rbtx4939_flash_data data;
+ } pdevs[4];
+ int i;
+ static char names[4][8];
+ static struct mtd_partition parts[4];
+ struct rbtx4939_flash_data *boot_pdata = &pdevs[0].data;
+ u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
+
+ if (bdipsw & 8) {
+ /* BOOT Mode: USER ROM1 / USER ROM2 */
+ boot_pdata->nr_parts = 4;
+ for (i = 0; i < boot_pdata->nr_parts; i++) {
+ sprintf(names[i], "img%d", 4 - i);
+ parts[i].name = names[i];
+ parts[i].size = 0x400000;
+ parts[i].offset = MTDPART_OFS_NXTBLK;
+ }
+ } else if (bdipsw == 0) {
+ /* BOOT Mode: Monitor ROM */
+ boot_pdata->nr_parts = 2;
+ strcpy(names[0], "big");
+ strcpy(names[1], "little");
+ for (i = 0; i < boot_pdata->nr_parts; i++) {
+ parts[i].name = names[i];
+ parts[i].size = 0x400000;
+ parts[i].offset = MTDPART_OFS_NXTBLK;
+ }
+ } else {
+ /* BOOT Mode: ROM Emulator */
+ boot_pdata->nr_parts = 2;
+ parts[0].name = "boot";
+ parts[0].offset = 0xc00000;
+ parts[0].size = 0x400000;
+ parts[1].name = "user";
+ parts[1].offset = 0;
+ parts[1].size = 0xc00000;
+ }
+ boot_pdata->parts = parts;
+ boot_pdata->map_init = rbtx4939_flash_map_init;
+
+ for (i = 0; i < ARRAY_SIZE(pdevs); i++) {
+ struct resource *r = &pdevs[i].res;
+ struct platform_device *dev = &pdevs[i].dev;
+
+ r->start = 0x1f000000 - i * 0x1000000;
+ r->end = r->start + 0x1000000 - 1;
+ r->flags = IORESOURCE_MEM;
+ pdevs[i].data.width = 2;
+ dev->num_resources = 1;
+ dev->resource = r;
+ dev->id = i;
+ dev->name = "rbtx4939-flash";
+ dev->dev.platform_data = &pdevs[i].data;
+ platform_device_register(dev);
+ }
+}
+#else
+static void __init rbtx4939_mtd_init(void)
+{
+}
+#endif
+
static void __init rbtx4939_arch_init(void)
{
rbtx4939_pci_setup();
@@ -333,6 +489,11 @@ static void __init rbtx4939_device_init(void)
platform_device_add_data(pdev, &smc_pdata, sizeof(smc_pdata)) ||
platform_device_add(pdev))
platform_device_put(pdev);
+ rbtx4939_mtd_init();
+ /* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
+ tx4939_ndfmc_init(10, 35,
+ (1 << 1) | (1 << 2),
+ (1 << 2)); /* ch1:8bit, ch2:16bit */
rbtx4939_led_setup();
tx4939_wdt_init();
tx4939_ata_init();
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index 41d16822e61..355926730e8 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -370,5 +370,3 @@ source "security/Kconfig"
source "crypto/Kconfig"
source "lib/Kconfig"
-
-source "arch/mn10300/oprofile/Kconfig"
diff --git a/arch/mn10300/Makefile b/arch/mn10300/Makefile
index 6673a28ec07..dd0c8ff52a6 100644
--- a/arch/mn10300/Makefile
+++ b/arch/mn10300/Makefile
@@ -94,42 +94,8 @@ ifdef CONFIG_DEBUG_INFO
KBUILD_AFLAGS += -Wa,--gdwarf2
endif
-###################################################################################################
#
-# juggle some symlinks in the MN10300 asm include dir
+# include the appropriate processor- and unit-specific headers
#
-# Update machine proc and unit symlinks if something which affects
-# them changed. We use .proc / .unit to indicate when they were
-# updated last, otherwise make uses the target directory mtime.
-#
-###################################################################################################
-
-# processor specific definitions
-include/asm-mn10300/.proc: $(wildcard include/config/proc/*.h) include/config/auto.conf
- @echo ' SYMLINK include/asm-mn10300/proc -> include/asm-mn10300/proc-$(PROCESSOR)'
-ifneq ($(KBUILD_SRC),)
- $(Q)mkdir -p include/asm-mn10300
- $(Q)ln -fsn $(srctree)/include/asm-mn10300/proc-$(PROCESSOR) include/asm-mn10300/proc
-else
- $(Q)ln -fsn proc-$(PROCESSOR) include/asm-mn10300/proc
-endif
- @touch $@
-
-CLEAN_FILES += include/asm-mn10300/proc include/asm-mn10300/.proc
-
-prepare: include/asm-mn10300/.proc
-
-# unit specific definitions
-include/asm-mn10300/.unit: $(wildcard include/config/unit/*.h) include/config/auto.conf
- @echo ' SYMLINK include/asm-mn10300/unit -> include/asm-mn10300/unit-$(UNIT)'
-ifneq ($(KBUILD_SRC),)
- $(Q)mkdir -p include/asm-mn10300
- $(Q)ln -fsn $(srctree)/include/asm-mn10300/unit-$(UNIT) include/asm-mn10300/unit
-else
- $(Q)ln -fsn unit-$(UNIT) include/asm-mn10300/unit
-endif
- @touch $@
-
-CLEAN_FILES += include/asm-mn10300/unit include/asm-mn10300/.unit
-
-prepare: include/asm-mn10300/.unit
+KBUILD_CPPFLAGS += -I$(srctree)/arch/mn10300/proc-$(PROCESSOR)/include
+KBUILD_CPPFLAGS += -I$(srctree)/arch/mn10300/unit-$(UNIT)/include
diff --git a/include/asm-mn10300/Kbuild b/arch/mn10300/include/asm/Kbuild
index c68e1680da0..c68e1680da0 100644
--- a/include/asm-mn10300/Kbuild
+++ b/arch/mn10300/include/asm/Kbuild
diff --git a/include/asm-mn10300/atomic.h b/arch/mn10300/include/asm/atomic.h
index bc064825f9b..bc064825f9b 100644
--- a/include/asm-mn10300/atomic.h
+++ b/arch/mn10300/include/asm/atomic.h
diff --git a/include/asm-mn10300/auxvec.h b/arch/mn10300/include/asm/auxvec.h
index 4fdb60b2ae3..4fdb60b2ae3 100644
--- a/include/asm-mn10300/auxvec.h
+++ b/arch/mn10300/include/asm/auxvec.h
diff --git a/include/asm-mn10300/bitops.h b/arch/mn10300/include/asm/bitops.h
index 0b610f482ab..0b610f482ab 100644
--- a/include/asm-mn10300/bitops.h
+++ b/arch/mn10300/include/asm/bitops.h
diff --git a/include/asm-mn10300/bug.h b/arch/mn10300/include/asm/bug.h
index 4fcf3384e25..4fcf3384e25 100644
--- a/include/asm-mn10300/bug.h
+++ b/arch/mn10300/include/asm/bug.h
diff --git a/include/asm-mn10300/bugs.h b/arch/mn10300/include/asm/bugs.h
index 31c8bc592b4..31c8bc592b4 100644
--- a/include/asm-mn10300/bugs.h
+++ b/arch/mn10300/include/asm/bugs.h
diff --git a/include/asm-mn10300/busctl-regs.h b/arch/mn10300/include/asm/busctl-regs.h
index 1632aef7340..1632aef7340 100644
--- a/include/asm-mn10300/busctl-regs.h
+++ b/arch/mn10300/include/asm/busctl-regs.h
diff --git a/include/asm-mn10300/byteorder.h b/arch/mn10300/include/asm/byteorder.h
index 5dd0bdd9fee..5dd0bdd9fee 100644
--- a/include/asm-mn10300/byteorder.h
+++ b/arch/mn10300/include/asm/byteorder.h
diff --git a/include/asm-mn10300/cache.h b/arch/mn10300/include/asm/cache.h
index 9e01122208a..e03cfa2e997 100644
--- a/include/asm-mn10300/cache.h
+++ b/arch/mn10300/include/asm/cache.h
@@ -13,7 +13,7 @@
#define _ASM_CACHE_H
#include <asm/cpu-regs.h>
-#include <asm/proc/cache.h>
+#include <proc/cache.h>
#ifndef __ASSEMBLY__
#define L1_CACHE_DISPARITY (L1_CACHE_NENTRIES * L1_CACHE_BYTES)
diff --git a/include/asm-mn10300/cacheflush.h b/arch/mn10300/include/asm/cacheflush.h
index 2db746a251f..2db746a251f 100644
--- a/include/asm-mn10300/cacheflush.h
+++ b/arch/mn10300/include/asm/cacheflush.h
diff --git a/include/asm-mn10300/checksum.h b/arch/mn10300/include/asm/checksum.h
index 9fb2a8d8826..9fb2a8d8826 100644
--- a/include/asm-mn10300/checksum.h
+++ b/arch/mn10300/include/asm/checksum.h
diff --git a/include/asm-mn10300/cpu-regs.h b/arch/mn10300/include/asm/cpu-regs.h
index 757e9b5388e..757e9b5388e 100644
--- a/include/asm-mn10300/cpu-regs.h
+++ b/arch/mn10300/include/asm/cpu-regs.h
diff --git a/arch/mn10300/include/asm/cputime.h b/arch/mn10300/include/asm/cputime.h
new file mode 100644
index 00000000000..6d68ad7e0ea
--- /dev/null
+++ b/arch/mn10300/include/asm/cputime.h
@@ -0,0 +1 @@
+#include <asm-generic/cputime.h>
diff --git a/include/asm-mn10300/current.h b/arch/mn10300/include/asm/current.h
index ca6027d8374..ca6027d8374 100644
--- a/include/asm-mn10300/current.h
+++ b/arch/mn10300/include/asm/current.h
diff --git a/include/asm-mn10300/delay.h b/arch/mn10300/include/asm/delay.h
index 34517b35939..34517b35939 100644
--- a/include/asm-mn10300/delay.h
+++ b/arch/mn10300/include/asm/delay.h
diff --git a/include/asm-mn10300/device.h b/arch/mn10300/include/asm/device.h
index f0a4c256403..f0a4c256403 100644
--- a/include/asm-mn10300/device.h
+++ b/arch/mn10300/include/asm/device.h
diff --git a/include/asm-mn10300/div64.h b/arch/mn10300/include/asm/div64.h
index 3a8329b3e86..3a8329b3e86 100644
--- a/include/asm-mn10300/div64.h
+++ b/arch/mn10300/include/asm/div64.h
diff --git a/include/asm-mn10300/dma-mapping.h b/arch/mn10300/include/asm/dma-mapping.h
index ccae8f6c632..ccae8f6c632 100644
--- a/include/asm-mn10300/dma-mapping.h
+++ b/arch/mn10300/include/asm/dma-mapping.h
diff --git a/include/asm-mn10300/dma.h b/arch/mn10300/include/asm/dma.h
index 098df2e617a..098df2e617a 100644
--- a/include/asm-mn10300/dma.h
+++ b/arch/mn10300/include/asm/dma.h
diff --git a/include/asm-mn10300/dmactl-regs.h b/arch/mn10300/include/asm/dmactl-regs.h
index 58a199da0f4..58a199da0f4 100644
--- a/include/asm-mn10300/dmactl-regs.h
+++ b/arch/mn10300/include/asm/dmactl-regs.h
diff --git a/include/asm-mn10300/elf.h b/arch/mn10300/include/asm/elf.h
index bf09f8bb392..bf09f8bb392 100644
--- a/include/asm-mn10300/elf.h
+++ b/arch/mn10300/include/asm/elf.h
diff --git a/arch/mn10300/include/asm/emergency-restart.h b/arch/mn10300/include/asm/emergency-restart.h
new file mode 100644
index 00000000000..3711bd9d50b
--- /dev/null
+++ b/arch/mn10300/include/asm/emergency-restart.h
@@ -0,0 +1 @@
+#include <asm-generic/emergency-restart.h>
diff --git a/arch/mn10300/include/asm/errno.h b/arch/mn10300/include/asm/errno.h
new file mode 100644
index 00000000000..4c82b503d92
--- /dev/null
+++ b/arch/mn10300/include/asm/errno.h
@@ -0,0 +1 @@
+#include <asm-generic/errno.h>
diff --git a/include/asm-mn10300/exceptions.h b/arch/mn10300/include/asm/exceptions.h
index fa16466ef3f..fa16466ef3f 100644
--- a/include/asm-mn10300/exceptions.h
+++ b/arch/mn10300/include/asm/exceptions.h
diff --git a/include/asm-mn10300/fb.h b/arch/mn10300/include/asm/fb.h
index 697b24a91e1..697b24a91e1 100644
--- a/include/asm-mn10300/fb.h
+++ b/arch/mn10300/include/asm/fb.h
diff --git a/arch/mn10300/include/asm/fcntl.h b/arch/mn10300/include/asm/fcntl.h
new file mode 100644
index 00000000000..46ab12db573
--- /dev/null
+++ b/arch/mn10300/include/asm/fcntl.h
@@ -0,0 +1 @@
+#include <asm-generic/fcntl.h>
diff --git a/include/asm-mn10300/fpu.h b/arch/mn10300/include/asm/fpu.h
index 64a2b83a7a6..64a2b83a7a6 100644
--- a/include/asm-mn10300/fpu.h
+++ b/arch/mn10300/include/asm/fpu.h
diff --git a/include/asm-mn10300/frame.inc b/arch/mn10300/include/asm/frame.inc
index 5b1949bdf03..5b1949bdf03 100644
--- a/include/asm-mn10300/frame.inc
+++ b/arch/mn10300/include/asm/frame.inc
diff --git a/arch/mn10300/include/asm/ftrace.h b/arch/mn10300/include/asm/ftrace.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/mn10300/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/mn10300/include/asm/futex.h b/arch/mn10300/include/asm/futex.h
new file mode 100644
index 00000000000..0b745828f42
--- /dev/null
+++ b/arch/mn10300/include/asm/futex.h
@@ -0,0 +1 @@
+#include <asm-generic/futex.h>
diff --git a/include/asm-mn10300/gdb-stub.h b/arch/mn10300/include/asm/gdb-stub.h
index e5a6368559a..e5a6368559a 100644
--- a/include/asm-mn10300/gdb-stub.h
+++ b/arch/mn10300/include/asm/gdb-stub.h
diff --git a/include/asm-mn10300/hardirq.h b/arch/mn10300/include/asm/hardirq.h
index 54d95011767..54d95011767 100644
--- a/include/asm-mn10300/hardirq.h
+++ b/arch/mn10300/include/asm/hardirq.h
diff --git a/include/asm-mn10300/highmem.h b/arch/mn10300/include/asm/highmem.h
index 90f2abb04bf..90f2abb04bf 100644
--- a/include/asm-mn10300/highmem.h
+++ b/arch/mn10300/include/asm/highmem.h
diff --git a/include/asm-mn10300/hw_irq.h b/arch/mn10300/include/asm/hw_irq.h
index 70619901098..70619901098 100644
--- a/include/asm-mn10300/hw_irq.h
+++ b/arch/mn10300/include/asm/hw_irq.h
diff --git a/include/asm-mn10300/intctl-regs.h b/arch/mn10300/include/asm/intctl-regs.h
index ba544c796c5..ba544c796c5 100644
--- a/include/asm-mn10300/intctl-regs.h
+++ b/arch/mn10300/include/asm/intctl-regs.h
diff --git a/include/asm-mn10300/io.h b/arch/mn10300/include/asm/io.h
index c1a4119e649..c1a4119e649 100644
--- a/include/asm-mn10300/io.h
+++ b/arch/mn10300/include/asm/io.h
diff --git a/arch/mn10300/include/asm/ioctl.h b/arch/mn10300/include/asm/ioctl.h
new file mode 100644
index 00000000000..b279fe06dfe
--- /dev/null
+++ b/arch/mn10300/include/asm/ioctl.h
@@ -0,0 +1 @@
+#include <asm-generic/ioctl.h>
diff --git a/include/asm-mn10300/ioctls.h b/arch/mn10300/include/asm/ioctls.h
index dcbfb452974..dcbfb452974 100644
--- a/include/asm-mn10300/ioctls.h
+++ b/arch/mn10300/include/asm/ioctls.h
diff --git a/arch/mn10300/include/asm/ipc.h b/arch/mn10300/include/asm/ipc.h
new file mode 100644
index 00000000000..a46e3d9c2a3
--- /dev/null
+++ b/arch/mn10300/include/asm/ipc.h
@@ -0,0 +1 @@
+#include <asm-generic/ipc.h>
diff --git a/include/asm-mn10300/ipcbuf.h b/arch/mn10300/include/asm/ipcbuf.h
index f6f63d44827..f6f63d44827 100644
--- a/include/asm-mn10300/ipcbuf.h
+++ b/arch/mn10300/include/asm/ipcbuf.h
diff --git a/include/asm-mn10300/irq.h b/arch/mn10300/include/asm/irq.h
index 53b38011690..25c045d16d1 100644
--- a/include/asm-mn10300/irq.h
+++ b/arch/mn10300/include/asm/irq.h
@@ -16,7 +16,7 @@
#include <asm/intctl-regs.h>
#include <asm/reset-regs.h>
-#include <asm/proc/irq.h>
+#include <proc/irq.h>
/* this number is used when no interrupt has been assigned */
#define NO_IRQ INT_MAX
diff --git a/include/asm-mn10300/irq_regs.h b/arch/mn10300/include/asm/irq_regs.h
index a848cd232eb..a848cd232eb 100644
--- a/include/asm-mn10300/irq_regs.h
+++ b/arch/mn10300/include/asm/irq_regs.h
diff --git a/include/asm-mn10300/kdebug.h b/arch/mn10300/include/asm/kdebug.h
index 0f47e112190..0f47e112190 100644
--- a/include/asm-mn10300/kdebug.h
+++ b/arch/mn10300/include/asm/kdebug.h
diff --git a/include/asm-mn10300/kmap_types.h b/arch/mn10300/include/asm/kmap_types.h
index 3398f9f3560..3398f9f3560 100644
--- a/include/asm-mn10300/kmap_types.h
+++ b/arch/mn10300/include/asm/kmap_types.h
diff --git a/include/asm-mn10300/kprobes.h b/arch/mn10300/include/asm/kprobes.h
index c800b590183..c800b590183 100644
--- a/include/asm-mn10300/kprobes.h
+++ b/arch/mn10300/include/asm/kprobes.h
diff --git a/include/asm-mn10300/linkage.h b/arch/mn10300/include/asm/linkage.h
index dda3002a5df..dda3002a5df 100644
--- a/include/asm-mn10300/linkage.h
+++ b/arch/mn10300/include/asm/linkage.h
diff --git a/arch/mn10300/include/asm/local.h b/arch/mn10300/include/asm/local.h
new file mode 100644
index 00000000000..c11c530f74d
--- /dev/null
+++ b/arch/mn10300/include/asm/local.h
@@ -0,0 +1 @@
+#include <asm-generic/local.h>
diff --git a/include/asm-mn10300/mc146818rtc.h b/arch/mn10300/include/asm/mc146818rtc.h
index df6bc6e0e8c..df6bc6e0e8c 100644
--- a/include/asm-mn10300/mc146818rtc.h
+++ b/arch/mn10300/include/asm/mc146818rtc.h
diff --git a/include/asm-mn10300/mman.h b/arch/mn10300/include/asm/mman.h
index b7986b65add..b7986b65add 100644
--- a/include/asm-mn10300/mman.h
+++ b/arch/mn10300/include/asm/mman.h
diff --git a/include/asm-mn10300/mmu.h b/arch/mn10300/include/asm/mmu.h
index 2d2d097e730..2d2d097e730 100644
--- a/include/asm-mn10300/mmu.h
+++ b/arch/mn10300/include/asm/mmu.h
diff --git a/include/asm-mn10300/mmu_context.h b/arch/mn10300/include/asm/mmu_context.h
index a9e2e34f69b..a9e2e34f69b 100644
--- a/include/asm-mn10300/mmu_context.h
+++ b/arch/mn10300/include/asm/mmu_context.h
diff --git a/include/asm-mn10300/module.h b/arch/mn10300/include/asm/module.h
index 5d7057d0149..5d7057d0149 100644
--- a/include/asm-mn10300/module.h
+++ b/arch/mn10300/include/asm/module.h
diff --git a/include/asm-mn10300/msgbuf.h b/arch/mn10300/include/asm/msgbuf.h
index 8b602450cc4..8b602450cc4 100644
--- a/include/asm-mn10300/msgbuf.h
+++ b/arch/mn10300/include/asm/msgbuf.h
diff --git a/include/asm-mn10300/mutex.h b/arch/mn10300/include/asm/mutex.h
index 84f5490c6fb..84f5490c6fb 100644
--- a/include/asm-mn10300/mutex.h
+++ b/arch/mn10300/include/asm/mutex.h
diff --git a/include/asm-mn10300/nmi.h b/arch/mn10300/include/asm/nmi.h
index f3671cbbc11..f3671cbbc11 100644
--- a/include/asm-mn10300/nmi.h
+++ b/arch/mn10300/include/asm/nmi.h
diff --git a/include/asm-mn10300/page.h b/arch/mn10300/include/asm/page.h
index 8288e124165..8288e124165 100644
--- a/include/asm-mn10300/page.h
+++ b/arch/mn10300/include/asm/page.h
diff --git a/include/asm-mn10300/page_offset.h b/arch/mn10300/include/asm/page_offset.h
index 8eb5b16ad86..8eb5b16ad86 100644
--- a/include/asm-mn10300/page_offset.h
+++ b/arch/mn10300/include/asm/page_offset.h
diff --git a/include/asm-mn10300/param.h b/arch/mn10300/include/asm/param.h
index 789b1df41fc..789b1df41fc 100644
--- a/include/asm-mn10300/param.h
+++ b/arch/mn10300/include/asm/param.h
diff --git a/include/asm-mn10300/pci.h b/arch/mn10300/include/asm/pci.h
index 0517b45313d..0517b45313d 100644
--- a/include/asm-mn10300/pci.h
+++ b/arch/mn10300/include/asm/pci.h
diff --git a/arch/mn10300/include/asm/percpu.h b/arch/mn10300/include/asm/percpu.h
new file mode 100644
index 00000000000..06a959d6723
--- /dev/null
+++ b/arch/mn10300/include/asm/percpu.h
@@ -0,0 +1 @@
+#include <asm-generic/percpu.h>
diff --git a/include/asm-mn10300/pgalloc.h b/arch/mn10300/include/asm/pgalloc.h
index ec057e1bd4c..ec057e1bd4c 100644
--- a/include/asm-mn10300/pgalloc.h
+++ b/arch/mn10300/include/asm/pgalloc.h
diff --git a/include/asm-mn10300/pgtable.h b/arch/mn10300/include/asm/pgtable.h
index 6dc30fc827c..6dc30fc827c 100644
--- a/include/asm-mn10300/pgtable.h
+++ b/arch/mn10300/include/asm/pgtable.h
diff --git a/include/asm-mn10300/pio-regs.h b/arch/mn10300/include/asm/pio-regs.h
index 96bc8182d0b..96bc8182d0b 100644
--- a/include/asm-mn10300/pio-regs.h
+++ b/arch/mn10300/include/asm/pio-regs.h
diff --git a/arch/mn10300/include/asm/poll.h b/arch/mn10300/include/asm/poll.h
new file mode 100644
index 00000000000..c98509d3149
--- /dev/null
+++ b/arch/mn10300/include/asm/poll.h
@@ -0,0 +1 @@
+#include <asm-generic/poll.h>
diff --git a/include/asm-mn10300/posix_types.h b/arch/mn10300/include/asm/posix_types.h
index 077567c3779..077567c3779 100644
--- a/include/asm-mn10300/posix_types.h
+++ b/arch/mn10300/include/asm/posix_types.h
diff --git a/include/asm-mn10300/processor.h b/arch/mn10300/include/asm/processor.h
index 73239271873..73239271873 100644
--- a/include/asm-mn10300/processor.h
+++ b/arch/mn10300/include/asm/processor.h
diff --git a/include/asm-mn10300/ptrace.h b/arch/mn10300/include/asm/ptrace.h
index 7b06cc623d8..7b06cc623d8 100644
--- a/include/asm-mn10300/ptrace.h
+++ b/arch/mn10300/include/asm/ptrace.h
diff --git a/include/asm-mn10300/reset-regs.h b/arch/mn10300/include/asm/reset-regs.h
index 174523d5013..174523d5013 100644
--- a/include/asm-mn10300/reset-regs.h
+++ b/arch/mn10300/include/asm/reset-regs.h
diff --git a/arch/mn10300/include/asm/resource.h b/arch/mn10300/include/asm/resource.h
new file mode 100644
index 00000000000..04bc4db8921
--- /dev/null
+++ b/arch/mn10300/include/asm/resource.h
@@ -0,0 +1 @@
+#include <asm-generic/resource.h>
diff --git a/include/asm-mn10300/rtc-regs.h b/arch/mn10300/include/asm/rtc-regs.h
index c42deefaec1..c42deefaec1 100644
--- a/include/asm-mn10300/rtc-regs.h
+++ b/arch/mn10300/include/asm/rtc-regs.h
diff --git a/include/asm-mn10300/rtc.h b/arch/mn10300/include/asm/rtc.h
index c295194cc70..c295194cc70 100644
--- a/include/asm-mn10300/rtc.h
+++ b/arch/mn10300/include/asm/rtc.h
diff --git a/include/asm-mn10300/scatterlist.h b/arch/mn10300/include/asm/scatterlist.h
index 67535901b9f..67535901b9f 100644
--- a/include/asm-mn10300/scatterlist.h
+++ b/arch/mn10300/include/asm/scatterlist.h
diff --git a/include/asm-mn10300/sections.h b/arch/mn10300/include/asm/sections.h
index 2b8c5160388..2b8c5160388 100644
--- a/include/asm-mn10300/sections.h
+++ b/arch/mn10300/include/asm/sections.h
diff --git a/include/asm-mn10300/sembuf.h b/arch/mn10300/include/asm/sembuf.h
index 301f3f9d8aa..301f3f9d8aa 100644
--- a/include/asm-mn10300/sembuf.h
+++ b/arch/mn10300/include/asm/sembuf.h
diff --git a/include/asm-mn10300/serial-regs.h b/arch/mn10300/include/asm/serial-regs.h
index 6498469e93a..6498469e93a 100644
--- a/include/asm-mn10300/serial-regs.h
+++ b/arch/mn10300/include/asm/serial-regs.h
diff --git a/include/asm-mn10300/serial.h b/arch/mn10300/include/asm/serial.h
index 99785a9dead..a29445cddd6 100644
--- a/include/asm-mn10300/serial.h
+++ b/arch/mn10300/include/asm/serial.h
@@ -33,4 +33,4 @@
#define RS_TABLE_SIZE
#endif
-#include <asm/unit/serial.h>
+#include <unit/serial.h>
diff --git a/include/asm-mn10300/setup.h b/arch/mn10300/include/asm/setup.h
index 08356c83228..08356c83228 100644
--- a/include/asm-mn10300/setup.h
+++ b/arch/mn10300/include/asm/setup.h
diff --git a/include/asm-mn10300/shmbuf.h b/arch/mn10300/include/asm/shmbuf.h
index 8f300cc35d6..8f300cc35d6 100644
--- a/include/asm-mn10300/shmbuf.h
+++ b/arch/mn10300/include/asm/shmbuf.h
diff --git a/include/asm-mn10300/shmparam.h b/arch/mn10300/include/asm/shmparam.h
index ab666ed1a07..ab666ed1a07 100644
--- a/include/asm-mn10300/shmparam.h
+++ b/arch/mn10300/include/asm/shmparam.h
diff --git a/include/asm-mn10300/sigcontext.h b/arch/mn10300/include/asm/sigcontext.h
index 4de3afff4ad..4de3afff4ad 100644
--- a/include/asm-mn10300/sigcontext.h
+++ b/arch/mn10300/include/asm/sigcontext.h
diff --git a/include/asm-mn10300/siginfo.h b/arch/mn10300/include/asm/siginfo.h
index 0815d29d82e..0815d29d82e 100644
--- a/include/asm-mn10300/siginfo.h
+++ b/arch/mn10300/include/asm/siginfo.h
diff --git a/include/asm-mn10300/signal.h b/arch/mn10300/include/asm/signal.h
index e98817cec5f..e98817cec5f 100644
--- a/include/asm-mn10300/signal.h
+++ b/arch/mn10300/include/asm/signal.h
diff --git a/include/asm-mn10300/smp.h b/arch/mn10300/include/asm/smp.h
index 4eb8c61b7da..4eb8c61b7da 100644
--- a/include/asm-mn10300/smp.h
+++ b/arch/mn10300/include/asm/smp.h
diff --git a/include/asm-mn10300/socket.h b/arch/mn10300/include/asm/socket.h
index fb5daf438ec..fb5daf438ec 100644
--- a/include/asm-mn10300/socket.h
+++ b/arch/mn10300/include/asm/socket.h
diff --git a/include/asm-mn10300/sockios.h b/arch/mn10300/include/asm/sockios.h
index b03043a1c56..b03043a1c56 100644
--- a/include/asm-mn10300/sockios.h
+++ b/arch/mn10300/include/asm/sockios.h
diff --git a/include/asm-mn10300/spinlock.h b/arch/mn10300/include/asm/spinlock.h
index 4bf9c8b169e..4bf9c8b169e 100644
--- a/include/asm-mn10300/spinlock.h
+++ b/arch/mn10300/include/asm/spinlock.h
diff --git a/include/asm-mn10300/stat.h b/arch/mn10300/include/asm/stat.h
index 63ff8371cf2..63ff8371cf2 100644
--- a/include/asm-mn10300/stat.h
+++ b/arch/mn10300/include/asm/stat.h
diff --git a/arch/mn10300/include/asm/statfs.h b/arch/mn10300/include/asm/statfs.h
new file mode 100644
index 00000000000..0b91fe198c2
--- /dev/null
+++ b/arch/mn10300/include/asm/statfs.h
@@ -0,0 +1 @@
+#include <asm-generic/statfs.h>
diff --git a/include/asm-mn10300/string.h b/arch/mn10300/include/asm/string.h
index 47dbd4346c3..47dbd4346c3 100644
--- a/include/asm-mn10300/string.h
+++ b/arch/mn10300/include/asm/string.h
diff --git a/include/asm-mn10300/swab.h b/arch/mn10300/include/asm/swab.h
index bd818a820ca..bd818a820ca 100644
--- a/include/asm-mn10300/swab.h
+++ b/arch/mn10300/include/asm/swab.h
diff --git a/include/asm-mn10300/system.h b/arch/mn10300/include/asm/system.h
index 8214fb7e7fe..8214fb7e7fe 100644
--- a/include/asm-mn10300/system.h
+++ b/arch/mn10300/include/asm/system.h
diff --git a/include/asm-mn10300/termbits.h b/arch/mn10300/include/asm/termbits.h
index eb2b0dc1f69..eb2b0dc1f69 100644
--- a/include/asm-mn10300/termbits.h
+++ b/arch/mn10300/include/asm/termbits.h
diff --git a/include/asm-mn10300/termios.h b/arch/mn10300/include/asm/termios.h
index dd7cf617e11..dd7cf617e11 100644
--- a/include/asm-mn10300/termios.h
+++ b/arch/mn10300/include/asm/termios.h
diff --git a/include/asm-mn10300/thread_info.h b/arch/mn10300/include/asm/thread_info.h
index 78a3881f3c1..78a3881f3c1 100644
--- a/include/asm-mn10300/thread_info.h
+++ b/arch/mn10300/include/asm/thread_info.h
diff --git a/include/asm-mn10300/timer-regs.h b/arch/mn10300/include/asm/timer-regs.h
index 1d883b7f94a..1d883b7f94a 100644
--- a/include/asm-mn10300/timer-regs.h
+++ b/arch/mn10300/include/asm/timer-regs.h
diff --git a/include/asm-mn10300/timex.h b/arch/mn10300/include/asm/timex.h
index 3944277dab6..8d031f9e117 100644
--- a/include/asm-mn10300/timex.h
+++ b/arch/mn10300/include/asm/timex.h
@@ -12,7 +12,7 @@
#define _ASM_TIMEX_H
#include <asm/hardirq.h>
-#include <asm/unit/timex.h>
+#include <unit/timex.h>
#define TICK_SIZE (tick_nsec / 1000)
diff --git a/include/asm-mn10300/tlb.h b/arch/mn10300/include/asm/tlb.h
index 65d232b9661..65d232b9661 100644
--- a/include/asm-mn10300/tlb.h
+++ b/arch/mn10300/include/asm/tlb.h
diff --git a/include/asm-mn10300/tlbflush.h b/arch/mn10300/include/asm/tlbflush.h
index e0239865abc..e0239865abc 100644
--- a/include/asm-mn10300/tlbflush.h
+++ b/arch/mn10300/include/asm/tlbflush.h
diff --git a/include/asm-mn10300/topology.h b/arch/mn10300/include/asm/topology.h
index 5428f333a02..5428f333a02 100644
--- a/include/asm-mn10300/topology.h
+++ b/arch/mn10300/include/asm/topology.h
diff --git a/include/asm-mn10300/types.h b/arch/mn10300/include/asm/types.h
index 7b9f01042fd..7b9f01042fd 100644
--- a/include/asm-mn10300/types.h
+++ b/arch/mn10300/include/asm/types.h
diff --git a/include/asm-mn10300/uaccess.h b/arch/mn10300/include/asm/uaccess.h
index 8a3a4dd5576..8a3a4dd5576 100644
--- a/include/asm-mn10300/uaccess.h
+++ b/arch/mn10300/include/asm/uaccess.h
diff --git a/include/asm-mn10300/ucontext.h b/arch/mn10300/include/asm/ucontext.h
index fcab5c1d8e1..fcab5c1d8e1 100644
--- a/include/asm-mn10300/ucontext.h
+++ b/arch/mn10300/include/asm/ucontext.h
diff --git a/include/asm-mn10300/unaligned.h b/arch/mn10300/include/asm/unaligned.h
index 0df671318ae..0df671318ae 100644
--- a/include/asm-mn10300/unaligned.h
+++ b/arch/mn10300/include/asm/unaligned.h
diff --git a/include/asm-mn10300/unistd.h b/arch/mn10300/include/asm/unistd.h
index 543a4f98695..543a4f98695 100644
--- a/include/asm-mn10300/unistd.h
+++ b/arch/mn10300/include/asm/unistd.h
diff --git a/include/asm-mn10300/user.h b/arch/mn10300/include/asm/user.h
index e1193908b78..e1193908b78 100644
--- a/include/asm-mn10300/user.h
+++ b/arch/mn10300/include/asm/user.h
diff --git a/include/asm-mn10300/vga.h b/arch/mn10300/include/asm/vga.h
index 0163e50a345..0163e50a345 100644
--- a/include/asm-mn10300/vga.h
+++ b/arch/mn10300/include/asm/vga.h
diff --git a/arch/mn10300/include/asm/xor.h b/arch/mn10300/include/asm/xor.h
new file mode 100644
index 00000000000..c82eb12a5b1
--- /dev/null
+++ b/arch/mn10300/include/asm/xor.h
@@ -0,0 +1 @@
+#include <asm-generic/xor.h>
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
index ceeaaaa359e..34ab5a29315 100644
--- a/arch/mn10300/kernel/entry.S
+++ b/arch/mn10300/kernel/entry.S
@@ -20,7 +20,7 @@
#include <asm/intctl-regs.h>
#include <asm/busctl-regs.h>
#include <asm/timer-regs.h>
-#include <asm/unit/leds.h>
+#include <unit/leds.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/errno.h>
diff --git a/arch/mn10300/kernel/gdb-io-serial-low.S b/arch/mn10300/kernel/gdb-io-serial-low.S
index c68dcd05220..4998b24f5d3 100644
--- a/arch/mn10300/kernel/gdb-io-serial-low.S
+++ b/arch/mn10300/kernel/gdb-io-serial-low.S
@@ -18,7 +18,7 @@
#include <asm/thread_info.h>
#include <asm/frame.inc>
#include <asm/intctl-regs.h>
-#include <asm/unit/serial.h>
+#include <unit/serial.h>
.text
diff --git a/arch/mn10300/kernel/gdb-io-serial.c b/arch/mn10300/kernel/gdb-io-serial.c
index 11584c51acd..ae663dc717e 100644
--- a/arch/mn10300/kernel/gdb-io-serial.c
+++ b/arch/mn10300/kernel/gdb-io-serial.c
@@ -22,7 +22,7 @@
#include <asm/gdb-stub.h>
#include <asm/exceptions.h>
#include <asm/serial-regs.h>
-#include <asm/unit/serial.h>
+#include <unit/serial.h>
/*
* initialise the GDB stub
diff --git a/arch/mn10300/kernel/gdb-io-ttysm-low.S b/arch/mn10300/kernel/gdb-io-ttysm-low.S
index 677c7876307..060b7cca735 100644
--- a/arch/mn10300/kernel/gdb-io-ttysm-low.S
+++ b/arch/mn10300/kernel/gdb-io-ttysm-low.S
@@ -18,7 +18,7 @@
#include <asm/cpu-regs.h>
#include <asm/frame.inc>
#include <asm/intctl-regs.h>
-#include <asm/unit/serial.h>
+#include <unit/serial.h>
#include "mn10300-serial.h"
.text
diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c
index e94c25e8ca0..a560bbc3137 100644
--- a/arch/mn10300/kernel/gdb-io-ttysm.c
+++ b/arch/mn10300/kernel/gdb-io-ttysm.c
@@ -20,7 +20,7 @@
#include <asm/system.h>
#include <asm/gdb-stub.h>
#include <asm/exceptions.h>
-#include <asm/unit/clock.h>
+#include <unit/clock.h>
#include "mn10300-serial.h"
#if defined(CONFIG_GDBSTUB_ON_TTYSM0)
diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c
index 0ea7482c152..41b11706c8e 100644
--- a/arch/mn10300/kernel/gdb-stub.c
+++ b/arch/mn10300/kernel/gdb-stub.c
@@ -136,8 +136,8 @@
#include <asm/cacheflush.h>
#include <asm/serial-regs.h>
#include <asm/busctl-regs.h>
-#include <asm/unit/leds.h>
-#include <asm/unit/serial.h>
+#include <unit/leds.h>
+#include <unit/serial.h>
/* define to use F7F7 rather than FF which is subverted by JTAG debugger */
#undef GDBSTUB_USE_F7F7_AS_BREAKPOINT
diff --git a/arch/mn10300/kernel/head.S b/arch/mn10300/kernel/head.S
index 606bd8c6758..8a8309fbe3c 100644
--- a/arch/mn10300/kernel/head.S
+++ b/arch/mn10300/kernel/head.S
@@ -17,7 +17,7 @@
#include <asm/pgtable.h>
#include <asm/frame.inc>
#include <asm/param.h>
-#include <asm/unit/serial.h>
+#include <unit/serial.h>
.section .text.head,"ax"
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index 50fdb5c16e0..4c3c58ef5cd 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -140,7 +140,7 @@ void __init init_IRQ(void)
int irq;
for (irq = 0; irq < NR_IRQS; irq++)
- if (irq_desc[irq].chip == &no_irq_type)
+ if (irq_desc[irq].chip == &no_irq_chip)
/* due to the PIC latching interrupt requests, even
* when the IRQ is disabled, IRQ_PENDING is superfluous
* and we can use handle_level_irq() for edge-triggered
diff --git a/arch/mn10300/kernel/mn10300-serial-low.S b/arch/mn10300/kernel/mn10300-serial-low.S
index ef3f4c1df2a..22448538822 100644
--- a/arch/mn10300/kernel/mn10300-serial-low.S
+++ b/arch/mn10300/kernel/mn10300-serial-low.S
@@ -18,8 +18,8 @@
#include <asm/cpu-regs.h>
#include <asm/frame.inc>
#include <asm/timer-regs.h>
-#include <asm/proc/cache.h>
-#include <asm/unit/timex.h>
+#include <proc/cache.h>
+#include <unit/timex.h>
#include "mn10300-serial.h"
#define SCxCTR 0x00
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c
index 59b9c4bf958..2fd59664d00 100644
--- a/arch/mn10300/kernel/mn10300-serial.c
+++ b/arch/mn10300/kernel/mn10300-serial.c
@@ -41,7 +41,7 @@ static const char serial_revdate[] = "2007-11-06";
#include <asm/irq.h>
#include <asm/bitops.h>
#include <asm/serial-regs.h>
-#include <asm/unit/timex.h>
+#include <unit/timex.h>
#include "mn10300-serial.h"
static inline __attribute__((format(printf, 1, 2)))
diff --git a/arch/mn10300/kernel/mn10300-watchdog.c b/arch/mn10300/kernel/mn10300-watchdog.c
index 2e370d88a87..f362d9d138f 100644
--- a/arch/mn10300/kernel/mn10300-watchdog.c
+++ b/arch/mn10300/kernel/mn10300-watchdog.c
@@ -25,7 +25,7 @@
#include <asm/div64.h>
#include <asm/smp.h>
#include <asm/gdb-stub.h>
-#include <asm/proc/clock.h>
+#include <proc/clock.h>
static DEFINE_SPINLOCK(watchdog_print_lock);
static unsigned int watchdog;
diff --git a/arch/mn10300/kernel/setup.c b/arch/mn10300/kernel/setup.c
index e1d88ab5100..71414e19fd1 100644
--- a/arch/mn10300/kernel/setup.c
+++ b/arch/mn10300/kernel/setup.c
@@ -30,7 +30,7 @@
#include <asm/setup.h>
#include <asm/io.h>
#include <asm/smp.h>
-#include <asm/proc/proc.h>
+#include <proc/proc.h>
#include <asm/busctl-regs.h>
#include <asm/fpu.h>
#include <asm/sections.h>
diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c
index fcb9a03d46a..681ad8c9e4f 100644
--- a/arch/mn10300/kernel/traps.c
+++ b/arch/mn10300/kernel/traps.c
@@ -37,7 +37,7 @@
#include <asm/cacheflush.h>
#include <asm/cpu-regs.h>
#include <asm/busctl-regs.h>
-#include <asm/unit/leds.h>
+#include <unit/leds.h>
#include <asm/fpu.h>
#include <asm/gdb-stub.h>
#include <asm/sections.h>
diff --git a/arch/mn10300/oprofile/Kconfig b/arch/mn10300/oprofile/Kconfig
deleted file mode 100644
index 19d37730b66..00000000000
--- a/arch/mn10300/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
-endmenu
-
diff --git a/include/asm-mn10300/proc-mn103e010/cache.h b/arch/mn10300/proc-mn103e010/include/proc/cache.h
index bdc1f9a59b4..bdc1f9a59b4 100644
--- a/include/asm-mn10300/proc-mn103e010/cache.h
+++ b/arch/mn10300/proc-mn103e010/include/proc/cache.h
diff --git a/include/asm-mn10300/proc-mn103e010/clock.h b/arch/mn10300/proc-mn103e010/include/proc/clock.h
index caf99835063..aa23e147d62 100644
--- a/include/asm-mn10300/proc-mn103e010/clock.h
+++ b/arch/mn10300/proc-mn103e010/include/proc/clock.h
@@ -11,7 +11,7 @@
#ifndef _ASM_PROC_CLOCK_H
#define _ASM_PROC_CLOCK_H
-#include <asm/unit/clock.h>
+#include <unit/clock.h>
#define MN10300_WDCLK MN10300_IOCLK
diff --git a/include/asm-mn10300/proc-mn103e010/irq.h b/arch/mn10300/proc-mn103e010/include/proc/irq.h
index aa6ee8f98b1..aa6ee8f98b1 100644
--- a/include/asm-mn10300/proc-mn103e010/irq.h
+++ b/arch/mn10300/proc-mn103e010/include/proc/irq.h
diff --git a/include/asm-mn10300/proc-mn103e010/proc.h b/arch/mn10300/proc-mn103e010/include/proc/proc.h
index 22a2b93f70b..22a2b93f70b 100644
--- a/include/asm-mn10300/proc-mn103e010/proc.h
+++ b/arch/mn10300/proc-mn103e010/include/proc/proc.h
diff --git a/include/asm-mn10300/unit-asb2303/clock.h b/arch/mn10300/unit-asb2303/include/unit/clock.h
index 8b450e920af..8b450e920af 100644
--- a/include/asm-mn10300/unit-asb2303/clock.h
+++ b/arch/mn10300/unit-asb2303/include/unit/clock.h
diff --git a/include/asm-mn10300/unit-asb2303/leds.h b/arch/mn10300/unit-asb2303/include/unit/leds.h
index 3a7543ea7b5..3a7543ea7b5 100644
--- a/include/asm-mn10300/unit-asb2303/leds.h
+++ b/arch/mn10300/unit-asb2303/include/unit/leds.h
diff --git a/include/asm-mn10300/unit-asb2303/serial.h b/arch/mn10300/unit-asb2303/include/unit/serial.h
index 0d55cf5896a..047566cd2e3 100644
--- a/include/asm-mn10300/unit-asb2303/serial.h
+++ b/arch/mn10300/unit-asb2303/include/unit/serial.h
@@ -13,7 +13,7 @@
#define _ASM_UNIT_SERIAL_H
#include <asm/cpu-regs.h>
-#include <asm/proc/irq.h>
+#include <proc/irq.h>
#include <linux/serial_reg.h>
#define SERIAL_PORT0_BASE_ADDRESS 0xA6FB0000
diff --git a/include/asm-mn10300/unit-asb2303/smc91111.h b/arch/mn10300/unit-asb2303/include/unit/smc91111.h
index dd456e9c513..dd456e9c513 100644
--- a/include/asm-mn10300/unit-asb2303/smc91111.h
+++ b/arch/mn10300/unit-asb2303/include/unit/smc91111.h
diff --git a/include/asm-mn10300/unit-asb2303/timex.h b/arch/mn10300/unit-asb2303/include/unit/timex.h
index 7e54b0cfdd0..f206b63c95b 100644
--- a/include/asm-mn10300/unit-asb2303/timex.h
+++ b/arch/mn10300/unit-asb2303/include/unit/timex.h
@@ -16,7 +16,7 @@
#endif /* __ASSEMBLY__ */
#include <asm/timer-regs.h>
-#include <asm/unit/clock.h>
+#include <unit/clock.h>
/*
* jiffies counter specifications
diff --git a/arch/mn10300/unit-asb2303/leds.c b/arch/mn10300/unit-asb2303/leds.c
index cd4bc78ccfc..c03839357a1 100644
--- a/arch/mn10300/unit-asb2303/leds.c
+++ b/arch/mn10300/unit-asb2303/leds.c
@@ -16,7 +16,7 @@
#include <asm/processor.h>
#include <asm/intctl-regs.h>
#include <asm/rtc-regs.h>
-#include <asm/unit/leds.h>
+#include <unit/leds.h>
#if 0
static const u8 asb2303_led_hex_tbl[16] = {
diff --git a/arch/mn10300/unit-asb2303/smc91111.c b/arch/mn10300/unit-asb2303/smc91111.c
index 30875dd6563..43c24643941 100644
--- a/arch/mn10300/unit-asb2303/smc91111.c
+++ b/arch/mn10300/unit-asb2303/smc91111.c
@@ -18,7 +18,7 @@
#include <asm/timex.h>
#include <asm/processor.h>
#include <asm/intctl-regs.h>
-#include <asm/unit/smc91111.h>
+#include <unit/smc91111.h>
static struct resource smc91c111_resources[] = {
[0] = {
diff --git a/include/asm-mn10300/unit-asb2305/clock.h b/arch/mn10300/unit-asb2305/include/unit/clock.h
index 7d514841ffd..7d514841ffd 100644
--- a/include/asm-mn10300/unit-asb2305/clock.h
+++ b/arch/mn10300/unit-asb2305/include/unit/clock.h
diff --git a/include/asm-mn10300/unit-asb2305/leds.h b/arch/mn10300/unit-asb2305/include/unit/leds.h
index bc471f617fd..bc471f617fd 100644
--- a/include/asm-mn10300/unit-asb2305/leds.h
+++ b/arch/mn10300/unit-asb2305/include/unit/leds.h
diff --git a/include/asm-mn10300/unit-asb2305/serial.h b/arch/mn10300/unit-asb2305/include/unit/serial.h
index 73d31d67bb7..3bfc9093878 100644
--- a/include/asm-mn10300/unit-asb2305/serial.h
+++ b/arch/mn10300/unit-asb2305/include/unit/serial.h
@@ -12,7 +12,7 @@
#define _ASM_UNIT_SERIAL_H
#include <asm/cpu/cpu-regs.h>
-#include <asm/proc/irq.h>
+#include <proc/irq.h>
#include <linux/serial_reg.h>
#define SERIAL_PORT0_BASE_ADDRESS 0xA6FB0000
diff --git a/include/asm-mn10300/unit-asb2305/timex.h b/arch/mn10300/unit-asb2305/include/unit/timex.h
index 10e1bfe3446..a71c49aa85e 100644
--- a/include/asm-mn10300/unit-asb2305/timex.h
+++ b/arch/mn10300/unit-asb2305/include/unit/timex.h
@@ -16,7 +16,7 @@
#endif /* __ASSEMBLY__ */
#include <asm/cpu/timer-regs.h>
-#include <asm/unit/clock.h>
+#include <unit/clock.h>
/*
* jiffies counter specifications
diff --git a/arch/mn10300/unit-asb2305/leds.c b/arch/mn10300/unit-asb2305/leds.c
index e99dcc9cee1..d345ff9042d 100644
--- a/arch/mn10300/unit-asb2305/leds.c
+++ b/arch/mn10300/unit-asb2305/leds.c
@@ -15,7 +15,7 @@
#include <asm/processor.h>
#include <asm/cpu/intctl-regs.h>
#include <asm/cpu/rtc-regs.h>
-#include <asm/unit/leds.h>
+#include <unit/leds.h>
static const u8 asb2305_led_hex_tbl[16] = {
0x80, 0xf2, 0x48, 0x60, 0x32, 0x24, 0x04, 0xf0,
diff --git a/arch/mn10300/unit-asb2305/unit-init.c b/arch/mn10300/unit-asb2305/unit-init.c
index 72812a9439a..1c452cc3f6e 100644
--- a/arch/mn10300/unit-asb2305/unit-init.c
+++ b/arch/mn10300/unit-asb2305/unit-init.c
@@ -18,7 +18,7 @@
#include <asm/cpu/intctl-regs.h>
#include <asm/cpu/rtc-regs.h>
#include <asm/cpu/serial-regs.h>
-#include <asm/unit/serial.h>
+#include <unit/serial.h>
/*
* initialise some of the unit hardware before gdbstub is set up
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index aacf11d3372..9038f39d9d7 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -9,9 +9,13 @@ config PARISC
def_bool y
select HAVE_IDE
select HAVE_OPROFILE
+ select HAVE_FUNCTION_TRACER if 64BIT
+ select HAVE_FUNCTION_GRAPH_TRACER if 64BIT
+ select HAVE_FUNCTION_TRACE_MCOUNT_TEST if 64BIT
select RTC_CLASS
- select RTC_DRV_PARISC
+ select RTC_DRV_GENERIC
select INIT_ALL_POSSIBLE
+ select BUG
help
The PA-RISC microprocessor is designed by Hewlett-Packard and used
in many of their workstations & servers (HP9000 700 and 800 series,
@@ -75,6 +79,9 @@ config GENERIC_HARDIRQS
config GENERIC_IRQ_PROBE
def_bool y
+config HAVE_LATENCYTOP_SUPPORT
+ def_bool y
+
config IRQ_PER_CPU
bool
default y
@@ -83,6 +90,9 @@ config IRQ_PER_CPU
config PM
bool
+config STACKTRACE_SUPPORT
+ def_bool y
+
config ISA_DMA_API
bool
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 0d428278356..da6f66901c9 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -56,7 +56,9 @@ cflags-y += -mdisable-fpregs
# Without this, "ld -r" results in .text sections that are too big
# (> 0x40000) for branches to reach stubs.
-cflags-y += -ffunction-sections
+ifndef CONFIG_FUNCTION_TRACER
+ cflags-y += -ffunction-sections
+endif
# select which processor to optimise for
cflags-$(CONFIG_PA7100) += -march=1.1 -mschedule=7100
diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h
index edbfe25c5fc..ada3e5364d8 100644
--- a/arch/parisc/include/asm/atomic.h
+++ b/arch/parisc/include/asm/atomic.h
@@ -25,7 +25,7 @@
* Since "a" is usually an address, use one spinlock per cacheline.
*/
# define ATOMIC_HASH_SIZE 4
-# define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) a)/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ]))
+# define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) (a))/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ]))
extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
@@ -222,13 +222,13 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
-#define atomic_add(i,v) ((void)(__atomic_add_return( ((int)i),(v))))
-#define atomic_sub(i,v) ((void)(__atomic_add_return(-((int)i),(v))))
+#define atomic_add(i,v) ((void)(__atomic_add_return( ((int)(i)),(v))))
+#define atomic_sub(i,v) ((void)(__atomic_add_return(-((int)(i)),(v))))
#define atomic_inc(v) ((void)(__atomic_add_return( 1,(v))))
#define atomic_dec(v) ((void)(__atomic_add_return( -1,(v))))
-#define atomic_add_return(i,v) (__atomic_add_return( ((int)i),(v)))
-#define atomic_sub_return(i,v) (__atomic_add_return(-((int)i),(v)))
+#define atomic_add_return(i,v) (__atomic_add_return( ((int)(i)),(v)))
+#define atomic_sub_return(i,v) (__atomic_add_return(-((int)(i)),(v)))
#define atomic_inc_return(v) (__atomic_add_return( 1,(v)))
#define atomic_dec_return(v) (__atomic_add_return( -1,(v)))
@@ -289,13 +289,13 @@ atomic64_read(const atomic64_t *v)
return v->counter;
}
-#define atomic64_add(i,v) ((void)(__atomic64_add_return( ((s64)i),(v))))
-#define atomic64_sub(i,v) ((void)(__atomic64_add_return(-((s64)i),(v))))
+#define atomic64_add(i,v) ((void)(__atomic64_add_return( ((s64)(i)),(v))))
+#define atomic64_sub(i,v) ((void)(__atomic64_add_return(-((s64)(i)),(v))))
#define atomic64_inc(v) ((void)(__atomic64_add_return( 1,(v))))
#define atomic64_dec(v) ((void)(__atomic64_add_return( -1,(v))))
-#define atomic64_add_return(i,v) (__atomic64_add_return( ((s64)i),(v)))
-#define atomic64_sub_return(i,v) (__atomic64_add_return(-((s64)i),(v)))
+#define atomic64_add_return(i,v) (__atomic64_add_return( ((s64)(i)),(v)))
+#define atomic64_sub_return(i,v) (__atomic64_add_return(-((s64)(i)),(v)))
#define atomic64_inc_return(v) (__atomic64_add_return( 1,(v)))
#define atomic64_dec_return(v) (__atomic64_add_return( -1,(v)))
diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h
index b7ca6dc7fdd..724395143f2 100644
--- a/arch/parisc/include/asm/cacheflush.h
+++ b/arch/parisc/include/asm/cacheflush.h
@@ -97,6 +97,9 @@ void mark_rodata_ro(void);
#ifdef CONFIG_PA8X00
/* Only pa8800, pa8900 needs this */
+
+#include <asm/kmap_types.h>
+
#define ARCH_HAS_KMAP
void kunmap_parisc(void *addr);
diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h
index 7fa675799e6..9c802eb4be8 100644
--- a/arch/parisc/include/asm/elf.h
+++ b/arch/parisc/include/asm/elf.h
@@ -168,6 +168,16 @@ typedef struct elf64_fdesc {
__u64 gp;
} Elf64_Fdesc;
+#ifdef __KERNEL__
+
+#ifdef CONFIG_64BIT
+#define Elf_Fdesc Elf64_Fdesc
+#else
+#define Elf_Fdesc Elf32_Fdesc
+#endif /*CONFIG_64BIT*/
+
+#endif /*__KERNEL__*/
+
/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
#define PT_HP_TLS (PT_LOOS + 0x0)
diff --git a/arch/parisc/include/asm/ftrace.h b/arch/parisc/include/asm/ftrace.h
new file mode 100644
index 00000000000..2fa05dd6aee
--- /dev/null
+++ b/arch/parisc/include/asm/ftrace.h
@@ -0,0 +1,25 @@
+#ifndef _ASM_PARISC_FTRACE_H
+#define _ASM_PARISC_FTRACE_H
+
+#ifndef __ASSEMBLY__
+extern void mcount(void);
+
+/*
+ * Stack of return addresses for functions of a thread.
+ * Used in struct thread_info
+ */
+struct ftrace_ret_stack {
+ unsigned long ret;
+ unsigned long func;
+ unsigned long long calltime;
+};
+
+/*
+ * Primary handler of a function return.
+ * It relays on ftrace_return_to_handler.
+ * Defined in entry.S
+ */
+extern void return_to_handler(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_PARISC_FTRACE_H */
diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h
index c3941f09a87..7bc5125d7d4 100644
--- a/arch/parisc/include/asm/page.h
+++ b/arch/parisc/include/asm/page.h
@@ -36,16 +36,7 @@ void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
*/
#define STRICT_MM_TYPECHECKS
#ifdef STRICT_MM_TYPECHECKS
-typedef struct { unsigned long pte;
-#if !defined(CONFIG_64BIT)
- unsigned long future_flags;
- /* XXX: it's possible to remove future_flags and change BITS_PER_PTE_ENTRY
- to 2, but then strangely the identical 32bit kernel boots on a
- c3000(pa20), but not any longer on a 715(pa11).
- Still investigating... HelgeD.
- */
-#endif
-} pte_t; /* either 32 or 64bit */
+typedef struct { unsigned long pte; } pte_t; /* either 32 or 64bit */
/* NOTE: even on 64 bits, these entries are __u32 because we allocate
* the pmd and pgd in ZONE_DMA (i.e. under 4GB) */
@@ -111,7 +102,7 @@ extern int npmem_ranges;
#define BITS_PER_PMD_ENTRY 2
#define BITS_PER_PGD_ENTRY 2
#else
-#define BITS_PER_PTE_ENTRY 3
+#define BITS_PER_PTE_ENTRY 2
#define BITS_PER_PMD_ENTRY 2
#define BITS_PER_PGD_ENTRY BITS_PER_PMD_ENTRY
#endif
diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h
index 430f1aeea0b..4ca510b3c6f 100644
--- a/arch/parisc/include/asm/pdc.h
+++ b/arch/parisc/include/asm/pdc.h
@@ -49,6 +49,8 @@
#define PDC_MODEL_CPU_ID 6 /* returns cpu-id (only newer machines!) */
#define PDC_MODEL_CAPABILITIES 7 /* returns OS32/OS64-flags */
/* Values for PDC_MODEL_CAPABILITIES non-equivalent virtual aliasing support */
+#define PDC_MODEL_OS64 (1 << 0)
+#define PDC_MODEL_OS32 (1 << 1)
#define PDC_MODEL_IOPDIR_FDC (1 << 2)
#define PDC_MODEL_NVA_MASK (3 << 4)
#define PDC_MODEL_NVA_SUPPORTED (0 << 4)
@@ -341,6 +343,8 @@
#ifdef __KERNEL__
+#include <asm/page.h> /* for __PAGE_OFFSET */
+
extern int pdc_type;
/* Values for pdc_type */
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index 470a4b88124..a27d2e200fb 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -50,11 +50,7 @@
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
/* This is the size of the initially mapped kernel memory */
-#ifdef CONFIG_64BIT
#define KERNEL_INITIAL_ORDER 24 /* 0 to 1<<24 = 16MB */
-#else
-#define KERNEL_INITIAL_ORDER 23 /* 0 to 1<<23 = 8MB */
-#endif
#define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER)
#if defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB)
@@ -91,16 +87,25 @@
/* Definitions for 1st level */
#define PGDIR_SHIFT (PMD_SHIFT + BITS_PER_PMD)
+#if (PGDIR_SHIFT + PAGE_SHIFT + PGD_ORDER - BITS_PER_PGD_ENTRY) > BITS_PER_LONG
+#define BITS_PER_PGD (BITS_PER_LONG - PGDIR_SHIFT)
+#else
#define BITS_PER_PGD (PAGE_SHIFT + PGD_ORDER - BITS_PER_PGD_ENTRY)
+#endif
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
#define PTRS_PER_PGD (1UL << BITS_PER_PGD)
#define USER_PTRS_PER_PGD PTRS_PER_PGD
+#ifdef CONFIG_64BIT
#define MAX_ADDRBITS (PGDIR_SHIFT + BITS_PER_PGD)
#define MAX_ADDRESS (1UL << MAX_ADDRBITS)
-
#define SPACEID_SHIFT (MAX_ADDRBITS - 32)
+#else
+#define MAX_ADDRBITS (BITS_PER_LONG)
+#define MAX_ADDRESS (1UL << MAX_ADDRBITS)
+#define SPACEID_SHIFT 0
+#endif
/* This calculates the number of initial pages we need for the initial
* page tables */
diff --git a/arch/parisc/include/asm/smp.h b/arch/parisc/include/asm/smp.h
index 6ef4b7867b1..21eb45a5262 100644
--- a/arch/parisc/include/asm/smp.h
+++ b/arch/parisc/include/asm/smp.h
@@ -29,7 +29,8 @@ extern void smp_send_reschedule(int cpu);
extern void smp_send_all_nop(void);
extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi(cpumask_t mask);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
#endif /* !ASSEMBLY */
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
index 016d3fc4111..67db0722e6c 100644
--- a/arch/parisc/kernel/Makefile
+++ b/arch/parisc/kernel/Makefile
@@ -11,10 +11,25 @@ obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \
process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \
topology.o
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o = -pg
+CFLAGS_REMOVE_cache.o = -pg
+CFLAGS_REMOVE_irq.o = -pg
+CFLAGS_REMOVE_pacache.o = -pg
+CFLAGS_REMOVE_perf.o = -pg
+CFLAGS_REMOVE_traps.o = -pg
+CFLAGS_REMOVE_unaligned.o = -pg
+CFLAGS_REMOVE_unwind.o = -pg
+endif
+
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_PA11) += pci-dma.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_64BIT) += binfmt_elf32.o sys_parisc32.o signal32.o
+obj-$(CONFIG_STACKTRACE)+= stacktrace.o
# only supported for PCX-W/U in 64-bit mode at the moment
obj-$(CONFIG_64BIT) += perf.o perf_asm.o
+obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 0db9fdcb770..ae3e70cd1e1 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -505,6 +505,18 @@
STREG \pte,0(\ptep)
.endm
+ /* bitshift difference between a PFN (based on kernel's PAGE_SIZE)
+ * to a CPU TLB 4k PFN (4k => 12 bits to shift) */
+ #define PAGE_ADD_SHIFT (PAGE_SHIFT-12)
+
+ /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
+ .macro convert_for_tlb_insert20 pte
+ extrd,u \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
+ 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
+ depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\
+ (63-58)+PAGE_ADD_SHIFT,\pte
+ .endm
+
/* Convert the pte and prot to tlb insertion values. How
* this happens is quite subtle, read below */
.macro make_insert_tlb spc,pte,prot
@@ -544,8 +556,7 @@
depi 1,12,1,\prot
/* Drop prot bits and convert to page addr for iitlbt and idtlbt */
- extrd,u \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58),64-PAGE_SHIFT,\pte
- depdi _PAGE_SIZE_ENCODING_DEFAULT,63,63-58,\pte
+ convert_for_tlb_insert20 \pte
.endm
/* Identical macro to make_insert_tlb above, except it
@@ -563,8 +574,8 @@
/* Get rid of prot bits and convert to page addr for iitlba */
- depi _PAGE_SIZE_ENCODING_DEFAULT,31,ASM_PFN_PTE_SHIFT,\pte
- extru \pte,24,25,\pte
+ depi 0,31,ASM_PFN_PTE_SHIFT,\pte
+ SHRREG \pte,(ASM_PFN_PTE_SHIFT-(31-26)),\pte
.endm
/* This is for ILP32 PA2.0 only. The TLB insertion needs
@@ -1244,10 +1255,9 @@ nadtlb_check_flush_20w:
depdi,z 7,7,3,prot
depdi 1,10,1,prot
- /* Get rid of prot bits and convert to page addr for idtlbt */
+ /* Drop prot bits from pte and convert to page addr for idtlbt */
+ convert_for_tlb_insert20 pte
- depdi 0,63,12,pte
- extrd,u pte,56,52,pte
idtlbt pte,prot
rfir
@@ -1337,8 +1347,8 @@ nadtlb_check_flush_11:
/* Get rid of prot bits and convert to page addr for idtlba */
- depi 0,31,12,pte
- extru pte,24,25,pte
+ depi 0,31,ASM_PFN_PTE_SHIFT,pte
+ SHRREG pte,(ASM_PFN_PTE_SHIFT-(31-26)),pte
mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */
mtsp spc,%sr1
@@ -1403,10 +1413,9 @@ nadtlb_check_flush_20:
depdi,z 7,7,3,prot
depdi 1,10,1,prot
- /* Get rid of prot bits and convert to page addr for idtlbt */
+ /* Drop prot bits from pte and convert to page addr for idtlbt */
+ convert_for_tlb_insert20 pte
- depdi 0,63,12,pte
- extrd,u pte,56,32,pte
idtlbt pte,prot
rfir
@@ -2176,6 +2185,33 @@ syscall_do_resched:
ENDPROC(syscall_exit)
+#ifdef CONFIG_FUNCTION_TRACER
+ .import ftrace_function_trampoline,code
+ENTRY(_mcount)
+ copy %r3, %arg2
+ b ftrace_function_trampoline
+ nop
+ENDPROC(_mcount)
+
+ENTRY(return_to_handler)
+ load32 return_trampoline, %rp
+ copy %ret0, %arg0
+ copy %ret1, %arg1
+ b ftrace_return_to_handler
+ nop
+return_trampoline:
+ copy %ret0, %rp
+ copy %r23, %ret0
+ copy %r24, %ret1
+
+.globl ftrace_stub
+ftrace_stub:
+ bv %r0(%rp)
+ nop
+ENDPROC(return_to_handler)
+#endif /* CONFIG_FUNCTION_TRACER */
+
+
get_register:
/*
* get_register is used by the non access tlb miss handlers to
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index f6d241238a7..4c247e02d9b 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -527,7 +527,11 @@ int pdc_model_capabilities(unsigned long *capabilities)
pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
convert_to_wide(pdc_result);
- *capabilities = pdc_result[0];
+ if (retval == PDC_OK) {
+ *capabilities = pdc_result[0];
+ } else {
+ *capabilities = PDC_MODEL_OS32;
+ }
spin_unlock_irqrestore(&pdc_lock, flags);
return retval;
diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
new file mode 100644
index 00000000000..9877372ffdb
--- /dev/null
+++ b/arch/parisc/kernel/ftrace.c
@@ -0,0 +1,185 @@
+/*
+ * Code for tracing calls in Linux kernel.
+ * Copyright (C) 2009 Helge Deller <deller@gmx.de>
+ *
+ * based on code for x86 which is:
+ * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
+ *
+ * future possible enhancements:
+ * - add CONFIG_DYNAMIC_FTRACE
+ * - add CONFIG_STACK_TRACER
+ */
+
+#include <linux/init.h>
+#include <linux/ftrace.h>
+
+#include <asm/sections.h>
+#include <asm/ftrace.h>
+
+
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+/* Add a function return address to the trace stack on thread info.*/
+static int push_return_trace(unsigned long ret, unsigned long long time,
+ unsigned long func, int *depth)
+{
+ int index;
+
+ if (!current->ret_stack)
+ return -EBUSY;
+
+ /* The return trace stack is full */
+ if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) {
+ atomic_inc(&current->trace_overrun);
+ return -EBUSY;
+ }
+
+ index = ++current->curr_ret_stack;
+ barrier();
+ current->ret_stack[index].ret = ret;
+ current->ret_stack[index].func = func;
+ current->ret_stack[index].calltime = time;
+ *depth = index;
+
+ return 0;
+}
+
+/* Retrieve a function return address to the trace stack on thread info.*/
+static void pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret)
+{
+ int index;
+
+ index = current->curr_ret_stack;
+
+ if (unlikely(index < 0)) {
+ ftrace_graph_stop();
+ WARN_ON(1);
+ /* Might as well panic, otherwise we have no where to go */
+ *ret = (unsigned long)
+ dereference_function_descriptor(&panic);
+ return;
+ }
+
+ *ret = current->ret_stack[index].ret;
+ trace->func = current->ret_stack[index].func;
+ trace->calltime = current->ret_stack[index].calltime;
+ trace->overrun = atomic_read(&current->trace_overrun);
+ trace->depth = index;
+ barrier();
+ current->curr_ret_stack--;
+
+}
+
+/*
+ * Send the trace to the ring-buffer.
+ * @return the original return address.
+ */
+unsigned long ftrace_return_to_handler(unsigned long retval0,
+ unsigned long retval1)
+{
+ struct ftrace_graph_ret trace;
+ unsigned long ret;
+
+ pop_return_trace(&trace, &ret);
+ trace.rettime = cpu_clock(raw_smp_processor_id());
+ ftrace_graph_return(&trace);
+
+ if (unlikely(!ret)) {
+ ftrace_graph_stop();
+ WARN_ON(1);
+ /* Might as well panic. What else to do? */
+ ret = (unsigned long)
+ dereference_function_descriptor(&panic);
+ }
+
+ /* HACK: we hand over the old functions' return values
+ in %r23 and %r24. Assembly in entry.S will take care
+ and move those to their final registers %ret0 and %ret1 */
+ asm( "copy %0, %%r23 \n\t"
+ "copy %1, %%r24 \n" : : "r" (retval0), "r" (retval1) );
+
+ return ret;
+}
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
+{
+ unsigned long old;
+ unsigned long long calltime;
+ struct ftrace_graph_ent trace;
+
+ if (unlikely(atomic_read(&current->tracing_graph_pause)))
+ return;
+
+ old = *parent;
+ *parent = (unsigned long)
+ dereference_function_descriptor(&return_to_handler);
+
+ if (unlikely(!__kernel_text_address(old))) {
+ ftrace_graph_stop();
+ *parent = old;
+ WARN_ON(1);
+ return;
+ }
+
+ calltime = cpu_clock(raw_smp_processor_id());
+
+ if (push_return_trace(old, calltime,
+ self_addr, &trace.depth) == -EBUSY) {
+ *parent = old;
+ return;
+ }
+
+ trace.func = self_addr;
+
+ /* Only trace if the calling function expects to */
+ if (!ftrace_graph_entry(&trace)) {
+ current->curr_ret_stack--;
+ *parent = old;
+ }
+}
+
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+
+void ftrace_function_trampoline(unsigned long parent,
+ unsigned long self_addr,
+ unsigned long org_sp_gr3)
+{
+ extern ftrace_func_t ftrace_trace_function;
+
+ if (function_trace_stop)
+ return;
+
+ if (ftrace_trace_function != ftrace_stub) {
+ ftrace_trace_function(parent, self_addr);
+ return;
+ }
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ if (ftrace_graph_entry && ftrace_graph_return) {
+ unsigned long sp;
+ unsigned long *parent_rp;
+
+ asm volatile ("copy %%r30, %0" : "=r"(sp));
+ /* sanity check: is stack pointer which we got from
+ assembler function in entry.S in a reasonable
+ range compared to current stack pointer? */
+ if ((sp - org_sp_gr3) > 0x400)
+ return;
+
+ /* calculate pointer to %rp in stack */
+ parent_rp = (unsigned long *) org_sp_gr3 - 0x10;
+ /* sanity check: parent_rp should hold parent */
+ if (*parent_rp != parent)
+ return;
+
+ prepare_ftrace_return(parent_rp, self_addr);
+ return;
+ }
+#endif
+}
+
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 1c740f5cbd6..4ea4229d765 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -311,12 +311,12 @@ unsigned long txn_alloc_addr(unsigned int virt_irq)
next_cpu++; /* assign to "next" CPU we want this bugger on */
/* validate entry */
- while ((next_cpu < NR_CPUS) &&
+ while ((next_cpu < nr_cpu_ids) &&
(!per_cpu(cpu_data, next_cpu).txn_addr ||
!cpu_online(next_cpu)))
next_cpu++;
- if (next_cpu >= NR_CPUS)
+ if (next_cpu >= nr_cpu_ids)
next_cpu = 0; /* nothing else, assign monarch */
return txn_affinity_addr(virt_irq, next_cpu);
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index 9013243cecc..ecd1c502444 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -61,9 +61,7 @@
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/bug.h>
-#include <linux/uaccess.h>
-#include <asm/sections.h>
#include <asm/unwind.h>
#if 0
@@ -115,8 +113,6 @@ struct got_entry {
Elf32_Addr addr;
};
-#define Elf_Fdesc Elf32_Fdesc
-
struct stub_entry {
Elf32_Word insns[2]; /* each stub entry has two insns */
};
@@ -125,8 +121,6 @@ struct got_entry {
Elf64_Addr addr;
};
-#define Elf_Fdesc Elf64_Fdesc
-
struct stub_entry {
Elf64_Word insns[4]; /* each stub entry has four insns */
};
@@ -916,15 +910,3 @@ void module_arch_cleanup(struct module *mod)
deregister_unwind_table(mod);
module_bug_cleanup(mod);
}
-
-#ifdef CONFIG_64BIT
-void *dereference_function_descriptor(void *ptr)
-{
- Elf64_Fdesc *desc = ptr;
- void *p;
-
- if (!probe_kernel_address(&desc->addr, p))
- ptr = p;
- return ptr;
-}
-#endif
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
index 0eecfbbc59c..df653663d3d 100644
--- a/arch/parisc/kernel/parisc_ksyms.c
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -153,5 +153,10 @@ EXPORT_SYMBOL(node_data);
EXPORT_SYMBOL(pfnnid_map);
#endif
+#ifdef CONFIG_FUNCTION_TRACER
+extern void _mcount(void);
+EXPORT_SYMBOL(_mcount);
+#endif
+
/* from pacache.S -- needed for copy_page */
EXPORT_SYMBOL(copy_user_page_asm);
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 8aa591ed912..6f69101f90b 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -46,14 +46,15 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/kallsyms.h>
+#include <linux/uaccess.h>
#include <asm/io.h>
#include <asm/asm-offsets.h>
#include <asm/pdc.h>
#include <asm/pdc_chassis.h>
#include <asm/pgalloc.h>
-#include <asm/uaccess.h>
#include <asm/unwind.h>
+#include <asm/sections.h>
/*
* The idle thread. There's no useful work to be
@@ -231,8 +232,8 @@ sys_clone(unsigned long clone_flags, unsigned long usp,
However, these last 3 args are only examined
if the proper flags are set. */
- int __user *child_tidptr;
- int __user *parent_tidptr;
+ int __user *parent_tidptr = (int __user *)regs->gr[24];
+ int __user *child_tidptr = (int __user *)regs->gr[22];
/* usp must be word aligned. This also prevents users from
* passing in the value 1 (which is the signal for a special
@@ -243,16 +244,6 @@ sys_clone(unsigned long clone_flags, unsigned long usp,
if (usp == 0)
usp = regs->gr[30];
- if (clone_flags & CLONE_PARENT_SETTID)
- parent_tidptr = (int __user *)regs->gr[24];
- else
- parent_tidptr = NULL;
-
- if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID))
- child_tidptr = (int __user *)regs->gr[22];
- else
- child_tidptr = NULL;
-
return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr);
}
@@ -400,3 +391,15 @@ get_wchan(struct task_struct *p)
} while (count++ < 16);
return 0;
}
+
+#ifdef CONFIG_64BIT
+void *dereference_function_descriptor(void *ptr)
+{
+ Elf64_Fdesc *desc = ptr;
+ void *p;
+
+ if (!probe_kernel_address(&desc->addr, p))
+ ptr = p;
+ return ptr;
+}
+#endif
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index ecb609342fe..e09d0f7fb6b 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -100,8 +100,8 @@ static int __cpuinit processor_probe(struct parisc_device *dev)
struct cpuinfo_parisc *p;
#ifdef CONFIG_SMP
- if (num_online_cpus() >= NR_CPUS) {
- printk(KERN_INFO "num_online_cpus() >= NR_CPUS\n");
+ if (num_online_cpus() >= nr_cpu_ids) {
+ printk(KERN_INFO "num_online_cpus() >= nr_cpu_ids\n");
return 1;
}
#else
@@ -214,7 +214,7 @@ static int __cpuinit processor_probe(struct parisc_device *dev)
*/
#ifdef CONFIG_SMP
if (cpuid) {
- cpu_set(cpuid, cpu_present_map);
+ set_cpu_present(cpuid, true);
cpu_up(cpuid);
}
#endif
@@ -364,6 +364,13 @@ show_cpuinfo (struct seq_file *m, void *v)
boot_cpu_data.cpu_hz / 1000000,
boot_cpu_data.cpu_hz % 1000000 );
+ seq_printf(m, "capabilities\t:");
+ if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS32)
+ seq_printf(m, " os32");
+ if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS64)
+ seq_printf(m, " os64");
+ seq_printf(m, "\n");
+
seq_printf(m, "model\t\t: %s\n"
"model name\t: %s\n",
boot_cpu_data.pdc.sys_model_name,
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 9995d7ed581..1fd0f0cec03 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -31,6 +31,7 @@
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/bitops.h>
+#include <linux/ftrace.h>
#include <asm/system.h>
#include <asm/atomic.h>
@@ -113,14 +114,14 @@ halt_processor(void)
{
/* REVISIT : redirect I/O Interrupts to another CPU? */
/* REVISIT : does PM *know* this CPU isn't available? */
- cpu_clear(smp_processor_id(), cpu_online_map);
+ set_cpu_online(smp_processor_id(), false);
local_irq_disable();
for (;;)
;
}
-irqreturn_t
+irqreturn_t __irq_entry
ipi_interrupt(int irq, void *dev_id)
{
int this_cpu = smp_processor_id();
@@ -214,11 +215,11 @@ ipi_send(int cpu, enum ipi_message_type op)
}
static void
-send_IPI_mask(cpumask_t mask, enum ipi_message_type op)
+send_IPI_mask(const struct cpumask *mask, enum ipi_message_type op)
{
int cpu;
- for_each_cpu_mask(cpu, mask)
+ for_each_cpu(cpu, mask)
ipi_send(cpu, op);
}
@@ -257,7 +258,7 @@ smp_send_all_nop(void)
send_IPI_allbutself(IPI_NOP);
}
-void arch_send_call_function_ipi(cpumask_t mask)
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
{
send_IPI_mask(mask, IPI_CALL_FUNC);
}
@@ -296,13 +297,14 @@ smp_cpu_init(int cpunum)
mb();
/* Well, support 2.4 linux scheme as well. */
- if (cpu_test_and_set(cpunum, cpu_online_map))
+ if (cpu_isset(cpunum, cpu_online_map))
{
extern void machine_halt(void); /* arch/parisc.../process.c */
printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum);
machine_halt();
}
+ set_cpu_online(cpunum, true);
/* Initialise the idle task for this CPU */
atomic_inc(&init_mm.mm_count);
@@ -424,8 +426,8 @@ void __init smp_prepare_boot_cpu(void)
/* Setup BSP mappings */
printk(KERN_INFO "SMP: bootstrap CPU ID is %d\n", bootstrap_processor);
- cpu_set(bootstrap_processor, cpu_online_map);
- cpu_set(bootstrap_processor, cpu_present_map);
+ set_cpu_online(bootstrap_processor, true);
+ set_cpu_present(bootstrap_processor, true);
}
@@ -436,8 +438,7 @@ void __init smp_prepare_boot_cpu(void)
*/
void __init smp_prepare_cpus(unsigned int max_cpus)
{
- cpus_clear(cpu_present_map);
- cpu_set(0, cpu_present_map);
+ init_cpu_present(cpumask_of(0));
parisc_max_cpus = max_cpus;
if (!max_cpus)
diff --git a/arch/parisc/kernel/stacktrace.c b/arch/parisc/kernel/stacktrace.c
new file mode 100644
index 00000000000..2fe914c5f53
--- /dev/null
+++ b/arch/parisc/kernel/stacktrace.c
@@ -0,0 +1,63 @@
+/*
+ * Stack trace management functions
+ *
+ * Copyright (C) 2009 Helge Deller <deller@gmx.de>
+ * based on arch/x86/kernel/stacktrace.c by Ingo Molnar <mingo@redhat.com>
+ * and parisc unwind functions by Randolph Chung <tausq@debian.org>
+ *
+ * TODO: Userspace stacktrace (CONFIG_USER_STACKTRACE_SUPPORT)
+ */
+#include <linux/module.h>
+#include <linux/stacktrace.h>
+
+#include <asm/unwind.h>
+
+static void dump_trace(struct task_struct *task, struct stack_trace *trace)
+{
+ struct unwind_frame_info info;
+
+ /* initialize unwind info */
+ if (task == current) {
+ unsigned long sp;
+ struct pt_regs r;
+HERE:
+ asm volatile ("copy %%r30, %0" : "=r"(sp));
+ memset(&r, 0, sizeof(struct pt_regs));
+ r.iaoq[0] = (unsigned long)&&HERE;
+ r.gr[2] = (unsigned long)__builtin_return_address(0);
+ r.gr[30] = sp;
+ unwind_frame_init(&info, task, &r);
+ } else {
+ unwind_frame_init_from_blocked_task(&info, task);
+ }
+
+ /* unwind stack and save entries in stack_trace struct */
+ trace->nr_entries = 0;
+ while (trace->nr_entries < trace->max_entries) {
+ if (unwind_once(&info) < 0 || info.ip == 0)
+ break;
+
+ if (__kernel_text_address(info.ip))
+ trace->entries[trace->nr_entries++] = info.ip;
+ }
+}
+
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace)
+{
+ dump_trace(current, trace);
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+EXPORT_SYMBOL_GPL(save_stack_trace);
+
+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+{
+ dump_trace(tsk, trace);
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 69b6eebc466..59fc1a43ec3 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -365,17 +365,51 @@ tracesys_sigexit:
/*********************************************************
- Light-weight-syscall code
+ 32/64-bit Light-Weight-Syscall ABI
- r20 - lws number
- r26,r25,r24,r23,r22 - Input registers
- r28 - Function return register
- r21 - Error code.
+ * - Indicates a hint for userspace inline asm
+ implementations.
- Scracth: Any of the above that aren't being
- currently used, including r1.
+ Syscall number (caller-saves)
+ - %r20
+ * In asm clobber.
- Return pointer: r31 (Not usable)
+ Argument registers (caller-saves)
+ - %r26, %r25, %r24, %r23, %r22
+ * In asm input.
+
+ Return registers (caller-saves)
+ - %r28 (return), %r21 (errno)
+ * In asm output.
+
+ Caller-saves registers
+ - %r1, %r27, %r29
+ - %r2 (return pointer)
+ - %r31 (ble link register)
+ * In asm clobber.
+
+ Callee-saves registers
+ - %r3-%r18
+ - %r30 (stack pointer)
+ * Not in asm clobber.
+
+ If userspace is 32-bit:
+ Callee-saves registers
+ - %r19 (32-bit PIC register)
+
+ Differences from 32-bit calling convention:
+ - Syscall number in %r20
+ - Additional argument register %r22 (arg4)
+ - Callee-saves %r19.
+
+ If userspace is 64-bit:
+ Callee-saves registers
+ - %r27 (64-bit PIC register)
+
+ Differences from 64-bit calling convention:
+ - Syscall number in %r20
+ - Additional argument register %r22 (arg4)
+ - Callee-saves %r27.
Error codes returned by entry path:
@@ -473,7 +507,8 @@ lws_compare_and_swap64:
b,n lws_compare_and_swap
#else
/* If we are not a 64-bit kernel, then we don't
- * implement having 64-bit input registers
+ * have 64-bit input registers, and calling
+ * the 64-bit LWS CAS returns ENOSYS.
*/
b,n lws_exit_nosys
#endif
@@ -635,12 +670,15 @@ END(sys_call_table64)
/*
All light-weight-syscall atomic operations
will use this set of locks
+
+ NOTE: The lws_lock_start symbol must be
+ at least 16-byte aligned for safe use
+ with ldcw.
*/
.section .data
.align PAGE_SIZE
ENTRY(lws_lock_start)
/* lws locks */
- .align 16
.rept 16
/* Keep locks aligned at 16-bytes */
.word 1
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index e75cae6072c..d4dd05674c6 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -24,6 +24,7 @@
#include <linux/profile.h>
#include <linux/clocksource.h>
#include <linux/platform_device.h>
+#include <linux/ftrace.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -53,7 +54,7 @@ static unsigned long clocktick __read_mostly; /* timer cycles per tick */
* held off for an arbitrarily long period of time by interrupts being
* disabled, so we may miss one or more ticks.
*/
-irqreturn_t timer_interrupt(int irq, void *dev_id)
+irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
{
unsigned long now;
unsigned long next_tick;
@@ -216,14 +217,14 @@ void __init start_cpu_itimer(void)
per_cpu(cpu_data, cpu).it_value = next_tick;
}
-static struct platform_device rtc_parisc_dev = {
- .name = "rtc-parisc",
+static struct platform_device rtc_generic_dev = {
+ .name = "rtc-generic",
.id = -1,
};
static int __init rtc_init(void)
{
- if (platform_device_register(&rtc_parisc_dev) < 0)
+ if (platform_device_register(&rtc_generic_dev) < 0)
printk(KERN_ERR "unable to register rtc device...\n");
/* not necessarily an error */
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index ba658d2086f..c32f5d6d778 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -247,6 +247,8 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
oops_in_progress = 1;
+ oops_enter();
+
/* Amuse the user in a SPARC fashion */
if (err) printk(
KERN_CRIT " _______________________________ \n"
@@ -293,6 +295,7 @@ KERN_CRIT " || ||\n");
panic("Fatal exception");
}
+ oops_exit();
do_exit(SIGSEGV);
}
@@ -494,7 +497,7 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o
panic(msg);
}
-void handle_interruption(int code, struct pt_regs *regs)
+void notrace handle_interruption(int code, struct pt_regs *regs)
{
unsigned long fault_address = 0;
unsigned long fault_space = 0;
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 1a3b6ccd362..fd2cc4fd2b6 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -54,6 +54,8 @@ SECTIONS
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT
+ KPROBES_TEXT
+ IRQENTRY_TEXT
*(.text.do_softirq)
*(.text.sys_exit)
*(.text.do_sigaltstack)
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 9d704d9831d..4356ceb1e36 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -456,6 +456,13 @@ void __init mem_init(void)
{
int codesize, reservedpages, datasize, initsize;
+ /* Do sanity checks on page table constants */
+ BUILD_BUG_ON(PTE_ENTRY_SIZE != sizeof(pte_t));
+ BUILD_BUG_ON(PMD_ENTRY_SIZE != sizeof(pmd_t));
+ BUILD_BUG_ON(PGD_ENTRY_SIZE != sizeof(pgd_t));
+ BUILD_BUG_ON(PAGE_SHIFT + BITS_PER_PTE + BITS_PER_PMD + BITS_PER_PGD
+ > BITS_PER_LONG);
+
high_memory = __va((max_pfn << PAGE_SHIFT));
#ifndef CONFIG_DISCONTIGMEM
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 45192dce65c..5b50e1ac617 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -316,7 +316,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE
config KEXEC
bool "kexec system call (EXPERIMENTAL)"
- depends on BOOK3S && EXPERIMENTAL
+ depends on PPC_BOOK3S && EXPERIMENTAL
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
@@ -346,7 +346,7 @@ config PHYP_DUMP
help
Hypervisor-assisted dump is meant to be a kdump replacement
offering robustness and speed not possible without system
- hypervisor assistence.
+ hypervisor assistance.
If unsure, say "N"
@@ -775,6 +775,7 @@ config LOWMEM_CAM_NUM_BOOL
Say N here unless you know what you are doing.
config LOWMEM_CAM_NUM
+ depends on FSL_BOOKE
int "Number of CAMs to use to map low memory" if LOWMEM_CAM_NUM_BOOL
default 3
diff --git a/arch/powerpc/boot/dts/ksi8560.dts b/arch/powerpc/boot/dts/ksi8560.dts
index 308fe7c29de..c9cfd374bff 100644
--- a/arch/powerpc/boot/dts/ksi8560.dts
+++ b/arch/powerpc/boot/dts/ksi8560.dts
@@ -57,14 +57,14 @@
bus-frequency = <0>; /* Fixed by bootwrapper */
memory-controller@2000 {
- compatible = "fsl,8540-memory-controller";
+ compatible = "fsl,mpc8540-memory-controller";
reg = <0x2000 0x1000>;
interrupt-parent = <&mpic>;
interrupts = <0x12 0x2>;
};
L2: l2-cache-controller@20000 {
- compatible = "fsl,8540-l2-cache-controller";
+ compatible = "fsl,mpc8540-l2-cache-controller";
reg = <0x20000 0x1000>;
cache-line-size = <0x20>; /* 32 bytes */
cache-size = <0x40000>; /* L2, 256K */
diff --git a/arch/powerpc/boot/dts/pq2fads.dts b/arch/powerpc/boot/dts/pq2fads.dts
index b2d61091b36..0bb66937674 100644
--- a/arch/powerpc/boot/dts/pq2fads.dts
+++ b/arch/powerpc/boot/dts/pq2fads.dts
@@ -17,6 +17,14 @@
#address-cells = <1>;
#size-cells = <1>;
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -45,7 +53,7 @@
#size-cells = <1>;
reg = <0xf0010100 0x60>;
- ranges = <0x0 0x0 0xfe000000 0x800000
+ ranges = <0x0 0x0 0xff800000 0x800000
0x1 0x0 0xf4500000 0x8000
0x8 0x0 0xf8200000 0x8000>;
@@ -71,7 +79,7 @@
};
};
- pci@f0010800 {
+ pci0: pci@f0010800 {
device_type = "pci";
reg = <0xf0010800 0x10c 0xf00101ac 0x8 0xf00101c4 0x8>;
compatible = "fsl,mpc8280-pci", "fsl,pq2-pci";
@@ -142,7 +150,7 @@
reg = <0x119f0 0x10 0x115f0 0x10>;
};
- serial@11a00 {
+ serial0: serial@11a00 {
device_type = "serial";
compatible = "fsl,mpc8280-scc-uart",
"fsl,cpm2-scc-uart";
@@ -153,7 +161,7 @@
fsl,cpm-command = <0x800000>;
};
- serial@11a20 {
+ serial1: serial@11a20 {
device_type = "serial";
compatible = "fsl,mpc8280-scc-uart",
"fsl,cpm2-scc-uart";
@@ -164,7 +172,7 @@
fsl,cpm-command = <0x4a00000>;
};
- ethernet@11320 {
+ enet0: ethernet@11320 {
device_type = "network";
compatible = "fsl,mpc8280-fcc-enet",
"fsl,cpm2-fcc-enet";
@@ -176,7 +184,7 @@
fsl,cpm-command = <0x16200300>;
};
- ethernet@11340 {
+ enet1: ethernet@11340 {
device_type = "network";
compatible = "fsl,mpc8280-fcc-enet",
"fsl,cpm2-fcc-enet";
diff --git a/arch/powerpc/boot/dts/sbc8548.dts b/arch/powerpc/boot/dts/sbc8548.dts
index 9c5079fec4f..b1f1416ac99 100644
--- a/arch/powerpc/boot/dts/sbc8548.dts
+++ b/arch/powerpc/boot/dts/sbc8548.dts
@@ -156,14 +156,14 @@
compatible = "simple-bus";
memory-controller@2000 {
- compatible = "fsl,8548-memory-controller";
+ compatible = "fsl,mpc8548-memory-controller";
reg = <0x2000 0x1000>;
interrupt-parent = <&mpic>;
interrupts = <0x12 0x2>;
};
L2: l2-cache-controller@20000 {
- compatible = "fsl,8548-l2-cache-controller";
+ compatible = "fsl,mpc8548-l2-cache-controller";
reg = <0x20000 0x1000>;
cache-line-size = <0x20>; // 32 bytes
cache-size = <0x80000>; // L2, 512K
diff --git a/arch/powerpc/boot/dts/sbc8560.dts b/arch/powerpc/boot/dts/sbc8560.dts
index b772405a9a0..c4564b81e47 100644
--- a/arch/powerpc/boot/dts/sbc8560.dts
+++ b/arch/powerpc/boot/dts/sbc8560.dts
@@ -61,14 +61,14 @@
clock-frequency = <0>;
memory-controller@2000 {
- compatible = "fsl,8560-memory-controller";
+ compatible = "fsl,mpc8560-memory-controller";
reg = <0x2000 0x1000>;
interrupt-parent = <&mpic>;
interrupts = <0x12 0x2>;
};
L2: l2-cache-controller@20000 {
- compatible = "fsl,8560-l2-cache-controller";
+ compatible = "fsl,mpc8560-l2-cache-controller";
reg = <0x20000 0x1000>;
cache-line-size = <0x20>; // 32 bytes
cache-size = <0x40000>; // L2, 256K
diff --git a/arch/powerpc/boot/dts/socrates.dts b/arch/powerpc/boot/dts/socrates.dts
index b8d0fc6f004..7a6ae75a1e5 100644
--- a/arch/powerpc/boot/dts/socrates.dts
+++ b/arch/powerpc/boot/dts/socrates.dts
@@ -52,6 +52,7 @@
soc8544@e0000000 {
#address-cells = <1>;
#size-cells = <1>;
+ device_type = "soc";
ranges = <0x00000000 0xe0000000 0x00100000>;
reg = <0xe0000000 0x00001000>; // CCSRBAR 1M
@@ -78,11 +79,11 @@
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
- compatible = "fsl-i2c";
+ compatible = "fsl,mpc8544-i2c", "fsl-i2c";
reg = <0x3000 0x100>;
interrupts = <43 2>;
interrupt-parent = <&mpic>;
- dfsrr;
+ fsl,preserve-clocking;
dtt@28 {
compatible = "winbond,w83782d";
@@ -110,11 +111,11 @@
#address-cells = <1>;
#size-cells = <0>;
cell-index = <1>;
- compatible = "fsl-i2c";
+ compatible = "fsl,mpc8544-i2c", "fsl-i2c";
reg = <0x3100 0x100>;
interrupts = <43 2>;
interrupt-parent = <&mpic>;
- dfsrr;
+ fsl,preserve-clocking;
};
enet0: ethernet@24000 {
diff --git a/arch/powerpc/boot/dts/stx_gp3_8560.dts b/arch/powerpc/boot/dts/stx_gp3_8560.dts
index 8b173957fb5..ea6b15152de 100644
--- a/arch/powerpc/boot/dts/stx_gp3_8560.dts
+++ b/arch/powerpc/boot/dts/stx_gp3_8560.dts
@@ -57,14 +57,14 @@
compatible = "fsl,mpc8560-immr", "simple-bus";
memory-controller@2000 {
- compatible = "fsl,8540-memory-controller";
+ compatible = "fsl,mpc8540-memory-controller";
reg = <0x2000 0x1000>;
interrupt-parent = <&mpic>;
interrupts = <18 2>;
};
L2: l2-cache-controller@20000 {
- compatible = "fsl,8540-l2-cache-controller";
+ compatible = "fsl,mpc8540-l2-cache-controller";
reg = <0x20000 0x1000>;
cache-line-size = <32>;
cache-size = <0x40000>; // L2, 256K
diff --git a/arch/powerpc/boot/dts/tqm8540.dts b/arch/powerpc/boot/dts/tqm8540.dts
index ac9413a29f9..231bae75663 100644
--- a/arch/powerpc/boot/dts/tqm8540.dts
+++ b/arch/powerpc/boot/dts/tqm8540.dts
@@ -59,14 +59,14 @@
compatible = "fsl,mpc8540-immr", "simple-bus";
memory-controller@2000 {
- compatible = "fsl,8540-memory-controller";
+ compatible = "fsl,mpc8540-memory-controller";
reg = <0x2000 0x1000>;
interrupt-parent = <&mpic>;
interrupts = <18 2>;
};
L2: l2-cache-controller@20000 {
- compatible = "fsl,8540-l2-cache-controller";
+ compatible = "fsl,mpc8540-l2-cache-controller";
reg = <0x20000 0x1000>;
cache-line-size = <32>;
cache-size = <0x40000>; // L2, 256K
diff --git a/arch/powerpc/boot/dts/tqm8541.dts b/arch/powerpc/boot/dts/tqm8541.dts
index c71bb5dd5e5..4356a1f0829 100644
--- a/arch/powerpc/boot/dts/tqm8541.dts
+++ b/arch/powerpc/boot/dts/tqm8541.dts
@@ -58,14 +58,14 @@
compatible = "fsl,mpc8541-immr", "simple-bus";
memory-controller@2000 {
- compatible = "fsl,8540-memory-controller";
+ compatible = "fsl,mpc8540-memory-controller";
reg = <0x2000 0x1000>;
interrupt-parent = <&mpic>;
interrupts = <18 2>;
};
L2: l2-cache-controller@20000 {
- compatible = "fsl,8540-l2-cache-controller";
+ compatible = "fsl,mpc8540-l2-cache-controller";
reg = <0x20000 0x1000>;
cache-line-size = <32>;
cache-size = <0x40000>; // L2, 256K
diff --git a/arch/powerpc/boot/dts/tqm8548-bigflash.dts b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
index 28b1a95257c..19aa72301c8 100644
--- a/arch/powerpc/boot/dts/tqm8548-bigflash.dts
+++ b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
@@ -397,10 +397,13 @@
upm@3,0 {
#address-cells = <0>;
#size-cells = <0>;
- compatible = "fsl,upm-nand";
+ compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
reg = <3 0x0 0x800>;
fsl,upm-addr-offset = <0x10>;
fsl,upm-cmd-offset = <0x08>;
+ /* Micron MT29F8G08FAB multi-chip device */
+ fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
+ fsl,upm-wait-flags = <0x5>;
chip-delay = <25>; // in micro-seconds
nand@0 {
@@ -409,7 +412,7 @@
partition@0 {
label = "fs";
- reg = <0x00000000 0x01000000>;
+ reg = <0x00000000 0x10000000>;
};
};
};
diff --git a/arch/powerpc/boot/dts/tqm8548.dts b/arch/powerpc/boot/dts/tqm8548.dts
index 826fb622cd3..49145a04fc6 100644
--- a/arch/powerpc/boot/dts/tqm8548.dts
+++ b/arch/powerpc/boot/dts/tqm8548.dts
@@ -397,10 +397,13 @@
upm@3,0 {
#address-cells = <0>;
#size-cells = <0>;
- compatible = "fsl,upm-nand";
+ compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
reg = <3 0x0 0x800>;
fsl,upm-addr-offset = <0x10>;
fsl,upm-cmd-offset = <0x08>;
+ /* Micron MT29F8G08FAB multi-chip device */
+ fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
+ fsl,upm-wait-flags = <0x5>;
chip-delay = <25>; // in micro-seconds
nand@0 {
@@ -409,7 +412,7 @@
partition@0 {
label = "fs";
- reg = <0x00000000 0x01000000>;
+ reg = <0x00000000 0x10000000>;
};
};
};
diff --git a/arch/powerpc/boot/dts/tqm8555.dts b/arch/powerpc/boot/dts/tqm8555.dts
index a133ded6ddd..06d366ebbda 100644
--- a/arch/powerpc/boot/dts/tqm8555.dts
+++ b/arch/powerpc/boot/dts/tqm8555.dts
@@ -58,14 +58,14 @@
compatible = "fsl,mpc8555-immr", "simple-bus";
memory-controller@2000 {
- compatible = "fsl,8540-memory-controller";
+ compatible = "fsl,mpc8540-memory-controller";
reg = <0x2000 0x1000>;
interrupt-parent = <&mpic>;
interrupts = <18 2>;
};
L2: l2-cache-controller@20000 {
- compatible = "fsl,8540-l2-cache-controller";
+ compatible = "fsl,mpc8540-l2-cache-controller";
reg = <0x20000 0x1000>;
cache-line-size = <32>;
cache-size = <0x40000>; // L2, 256K
diff --git a/arch/powerpc/boot/dts/tqm8560.dts b/arch/powerpc/boot/dts/tqm8560.dts
index 649e2e57626..feff915e049 100644
--- a/arch/powerpc/boot/dts/tqm8560.dts
+++ b/arch/powerpc/boot/dts/tqm8560.dts
@@ -60,14 +60,14 @@
compatible = "fsl,mpc8560-immr", "simple-bus";
memory-controller@2000 {
- compatible = "fsl,8540-memory-controller";
+ compatible = "fsl,mpc8540-memory-controller";
reg = <0x2000 0x1000>;
interrupt-parent = <&mpic>;
interrupts = <18 2>;
};
L2: l2-cache-controller@20000 {
- compatible = "fsl,8540-l2-cache-controller";
+ compatible = "fsl,mpc8540-l2-cache-controller";
reg = <0x20000 0x1000>;
cache-line-size = <32>;
cache-size = <0x40000>; // L2, 256K
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 61b10084971..f1889abb89b 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -95,7 +95,7 @@ CONFIG_CGROUP_CPUACCT=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_PROC_PID_CPUSET=y
-# CONFIG_RELAY is not set
+CONFIG_RELAY=y
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
index 68235f7e4a8..d2a65e8ca6a 100644
--- a/arch/powerpc/include/asm/lppaca.h
+++ b/arch/powerpc/include/asm/lppaca.h
@@ -125,7 +125,7 @@ struct lppaca {
// NOTE: This value will ALWAYS be zero for dedicated processors and
// will NEVER be zero for shared processors (ie, initialized to a 1).
volatile u32 yield_count; // PLIC increments each dispatchx00-x03
- u32 reserved6;
+ volatile u32 dispersion_count; // dispatch changed phys cpu x04-x07
volatile u64 cmo_faults; // CMO page fault count x08-x0F
volatile u64 cmo_fault_time; // CMO page fault time x10-x17
u8 reserved7[104]; // Reserved x18-x7F
diff --git a/arch/powerpc/include/asm/mmzone.h b/arch/powerpc/include/asm/mmzone.h
index 19f299b7e25..35acac90c8c 100644
--- a/arch/powerpc/include/asm/mmzone.h
+++ b/arch/powerpc/include/asm/mmzone.h
@@ -8,6 +8,7 @@
#define _ASM_MMZONE_H_
#ifdef __KERNEL__
+#include <linux/cpumask.h>
/*
* generic non-linear memory support:
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index c2ccca53b99..a002682f3a6 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -22,6 +22,14 @@
#define MPIC_GREG_FEATURE_1 0x00010
#define MPIC_GREG_GLOBAL_CONF_0 0x00020
#define MPIC_GREG_GCONF_RESET 0x80000000
+/* On the FSL mpic implementations the Mode field is expand to be
+ * 2 bits wide:
+ * 0b00 = pass through (interrupts routed to IRQ0)
+ * 0b01 = Mixed mode
+ * 0b10 = reserved
+ * 0b11 = External proxy / coreint
+ */
+#define MPIC_GREG_GCONF_COREINT 0x60000000
#define MPIC_GREG_GCONF_8259_PTHROU_DIS 0x20000000
#define MPIC_GREG_GCONF_NO_BIAS 0x10000000
#define MPIC_GREG_GCONF_BASE_MASK 0x000fffff
@@ -357,6 +365,8 @@ struct mpic
#define MPIC_BROKEN_FRR_NIRQS 0x00000800
/* Destination only supports a single CPU at a time */
#define MPIC_SINGLE_DEST_CPU 0x00001000
+/* Enable CoreInt delivery of interrupts */
+#define MPIC_ENABLE_COREINT 0x00002000
/* MPIC HW modification ID */
#define MPIC_REGSET_MASK 0xf0000000
@@ -470,6 +480,8 @@ extern void mpic_end_irq(unsigned int irq);
extern unsigned int mpic_get_one_irq(struct mpic *mpic);
/* This one gets from the primary mpic */
extern unsigned int mpic_get_irq(void);
+/* This one gets from the primary mpic via CoreInt*/
+extern unsigned int mpic_get_coreint_irq(void);
/* Fetch Machine Check interrupt from primary mpic */
extern unsigned int mpic_get_mcirq(void);
diff --git a/arch/powerpc/include/asm/parport.h b/arch/powerpc/include/asm/parport.h
index 414c50e2e88..94942d60ddf 100644
--- a/arch/powerpc/include/asm/parport.h
+++ b/arch/powerpc/include/asm/parport.h
@@ -29,7 +29,7 @@ static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
prop = of_get_property(np, "interrupts", NULL);
if (!prop)
continue;
- if (parport_pc_probe_port(io1, io2, prop[0], autodma, NULL) != NULL)
+ if (parport_pc_probe_port(io1, io2, prop[0], autodma, NULL, 0) != NULL)
count++;
}
return count;
diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index 67f1812698d..cdb6fd814de 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -50,6 +50,9 @@ enum ps3_param_av_multi_out {
enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void);
+extern u64 ps3_os_area_get_rtc_diff(void);
+extern void ps3_os_area_set_rtc_diff(u64 rtc_diff);
+
/* dma routines */
enum ps3_dma_page_size {
diff --git a/arch/powerpc/include/asm/ps3fb.h b/arch/powerpc/include/asm/ps3fb.h
index 90dbefb8cfc..e7233a84968 100644
--- a/arch/powerpc/include/asm/ps3fb.h
+++ b/arch/powerpc/include/asm/ps3fb.h
@@ -21,7 +21,6 @@
#include <linux/types.h>
#include <linux/ioctl.h>
-#include <linux/types.h>
/* ioctl */
#define PS3FB_IOCTL_SETMODE _IOW('r', 1, int) /* set video mode */
diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h
index d9740e88680..a7e210b6b48 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -151,9 +151,11 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
_PAGE_NO_CACHE)
#define PAGE_KERNEL_NCG __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
_PAGE_NO_CACHE | _PAGE_GUARDED)
-#define PAGE_KERNEL_X __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW | _PAGE_EXEC)
+#define PAGE_KERNEL_X __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW | _PAGE_EXEC | \
+ _PAGE_HWEXEC)
#define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO)
-#define PAGE_KERNEL_ROX __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO | _PAGE_EXEC)
+#define PAGE_KERNEL_ROX __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO | _PAGE_EXEC | \
+ _PAGE_HWEXEC)
/* Protection used for kernel text. We want the debuggers to be able to
* set breakpoints anywhere, so don't write protect the kernel text
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index c9ff1ec9747..e8018d540e8 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -143,6 +143,36 @@
#define FPSCR_NI 0x00000004 /* FPU non IEEE-Mode */
#define FPSCR_RN 0x00000003 /* FPU rounding control */
+/* Bit definitions for SPEFSCR. */
+#define SPEFSCR_SOVH 0x80000000 /* Summary integer overflow high */
+#define SPEFSCR_OVH 0x40000000 /* Integer overflow high */
+#define SPEFSCR_FGH 0x20000000 /* Embedded FP guard bit high */
+#define SPEFSCR_FXH 0x10000000 /* Embedded FP sticky bit high */
+#define SPEFSCR_FINVH 0x08000000 /* Embedded FP invalid operation high */
+#define SPEFSCR_FDBZH 0x04000000 /* Embedded FP div by zero high */
+#define SPEFSCR_FUNFH 0x02000000 /* Embedded FP underflow high */
+#define SPEFSCR_FOVFH 0x01000000 /* Embedded FP overflow high */
+#define SPEFSCR_FINXS 0x00200000 /* Embedded FP inexact sticky */
+#define SPEFSCR_FINVS 0x00100000 /* Embedded FP invalid op. sticky */
+#define SPEFSCR_FDBZS 0x00080000 /* Embedded FP div by zero sticky */
+#define SPEFSCR_FUNFS 0x00040000 /* Embedded FP underflow sticky */
+#define SPEFSCR_FOVFS 0x00020000 /* Embedded FP overflow sticky */
+#define SPEFSCR_MODE 0x00010000 /* Embedded FP mode */
+#define SPEFSCR_SOV 0x00008000 /* Integer summary overflow */
+#define SPEFSCR_OV 0x00004000 /* Integer overflow */
+#define SPEFSCR_FG 0x00002000 /* Embedded FP guard bit */
+#define SPEFSCR_FX 0x00001000 /* Embedded FP sticky bit */
+#define SPEFSCR_FINV 0x00000800 /* Embedded FP invalid operation */
+#define SPEFSCR_FDBZ 0x00000400 /* Embedded FP div by zero */
+#define SPEFSCR_FUNF 0x00000200 /* Embedded FP underflow */
+#define SPEFSCR_FOVF 0x00000100 /* Embedded FP overflow */
+#define SPEFSCR_FINXE 0x00000040 /* Embedded FP inexact enable */
+#define SPEFSCR_FINVE 0x00000020 /* Embedded FP invalid op. enable */
+#define SPEFSCR_FDBZE 0x00000010 /* Embedded FP div by zero enable */
+#define SPEFSCR_FUNFE 0x00000008 /* Embedded FP underflow enable */
+#define SPEFSCR_FOVFE 0x00000004 /* Embedded FP overflow enable */
+#define SPEFSCR_FRMC 0x00000003 /* Embedded FP rounding mode control */
+
/* Special Purpose Registers (SPRNs)*/
#define SPRN_CTR 0x009 /* Count Register */
#define SPRN_DSCR 0x11
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index a56f4d61aa7..601ddbc4600 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -423,36 +423,6 @@
#define SGR_NORMAL 0 /* Speculative fetching allowed. */
#define SGR_GUARDED 1 /* Speculative fetching disallowed. */
-/* Bit definitions for SPEFSCR. */
-#define SPEFSCR_SOVH 0x80000000 /* Summary integer overflow high */
-#define SPEFSCR_OVH 0x40000000 /* Integer overflow high */
-#define SPEFSCR_FGH 0x20000000 /* Embedded FP guard bit high */
-#define SPEFSCR_FXH 0x10000000 /* Embedded FP sticky bit high */
-#define SPEFSCR_FINVH 0x08000000 /* Embedded FP invalid operation high */
-#define SPEFSCR_FDBZH 0x04000000 /* Embedded FP div by zero high */
-#define SPEFSCR_FUNFH 0x02000000 /* Embedded FP underflow high */
-#define SPEFSCR_FOVFH 0x01000000 /* Embedded FP overflow high */
-#define SPEFSCR_FINXS 0x00200000 /* Embedded FP inexact sticky */
-#define SPEFSCR_FINVS 0x00100000 /* Embedded FP invalid op. sticky */
-#define SPEFSCR_FDBZS 0x00080000 /* Embedded FP div by zero sticky */
-#define SPEFSCR_FUNFS 0x00040000 /* Embedded FP underflow sticky */
-#define SPEFSCR_FOVFS 0x00020000 /* Embedded FP overflow sticky */
-#define SPEFSCR_MODE 0x00010000 /* Embedded FP mode */
-#define SPEFSCR_SOV 0x00008000 /* Integer summary overflow */
-#define SPEFSCR_OV 0x00004000 /* Integer overflow */
-#define SPEFSCR_FG 0x00002000 /* Embedded FP guard bit */
-#define SPEFSCR_FX 0x00001000 /* Embedded FP sticky bit */
-#define SPEFSCR_FINV 0x00000800 /* Embedded FP invalid operation */
-#define SPEFSCR_FDBZ 0x00000400 /* Embedded FP div by zero */
-#define SPEFSCR_FUNF 0x00000200 /* Embedded FP underflow */
-#define SPEFSCR_FOVF 0x00000100 /* Embedded FP overflow */
-#define SPEFSCR_FINXE 0x00000040 /* Embedded FP inexact enable */
-#define SPEFSCR_FINVE 0x00000020 /* Embedded FP invalid op. enable */
-#define SPEFSCR_FDBZE 0x00000010 /* Embedded FP div by zero enable */
-#define SPEFSCR_FUNFE 0x00000008 /* Embedded FP underflow enable */
-#define SPEFSCR_FOVFE 0x00000004 /* Embedded FP overflow enable */
-#define SPEFSCR_FRMC 0x00000003 /* Embedded FP rounding mode control */
-
/*
* The IBM-403 is an even more odd special case, as it is much
* older than the IBM-405 series. We put these down here incase someone
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 0aa0315fb7e..01c12339b30 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -68,7 +68,8 @@ struct rtas_t {
#define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */
#define RTAS_POWERMGM_EVENTS 0x20000000 /* set bit 2 */
#define RTAS_HOTPLUG_EVENTS 0x10000000 /* set bit 3 */
-#define RTAS_EVENT_SCAN_ALL_EVENTS 0xf0000000
+#define RTAS_IO_EVENTS 0x08000000 /* set bit 4 */
+#define RTAS_EVENT_SCAN_ALL_EVENTS 0xffffffff
/* RTAS event severity */
#define RTAS_SEVERITY_FATAL 0x5
diff --git a/arch/powerpc/include/asm/sfp-machine.h b/arch/powerpc/include/asm/sfp-machine.h
index 3d9f831c3c5..3a7a67a0d00 100644
--- a/arch/powerpc/include/asm/sfp-machine.h
+++ b/arch/powerpc/include/asm/sfp-machine.h
@@ -29,9 +29,9 @@
/* basic word size definitions */
#define _FP_W_TYPE_SIZE 32
-#define _FP_W_TYPE unsigned long
-#define _FP_WS_TYPE signed long
-#define _FP_I_TYPE long
+#define _FP_W_TYPE unsigned int
+#define _FP_WS_TYPE signed int
+#define _FP_I_TYPE int
#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index fe166491e9d..d98a30dfd41 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -322,3 +322,6 @@ SYSCALL_SPU(epoll_create1)
SYSCALL_SPU(dup3)
SYSCALL_SPU(pipe2)
SYSCALL(inotify_init1)
+SYSCALL(ni_syscall)
+COMPAT_SYS_SPU(preadv)
+COMPAT_SYS_SPU(pwritev)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index e07d0c76ed7..3f06f8ec81c 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -341,10 +341,12 @@
#define __NR_dup3 316
#define __NR_pipe2 317
#define __NR_inotify_init1 318
+#define __NR_preadv 320
+#define __NR_pwritev 321
#ifdef __KERNEL__
-#define __NR_syscalls 319
+#define __NR_syscalls 322
#define __NR__exit __NR_exit
#define NR_syscalls __NR_syscalls
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 1c5c8a6fc12..53c7788cba7 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -94,7 +94,7 @@ static int dma_direct_dma_supported(struct device *dev, u64 mask)
* done via some global so platforms can set the limit in case
* they have limited DMA windows
*/
- return mask >= DMA_32BIT_MASK;
+ return mask >= DMA_BIT_MASK(32);
#else
return 1;
#endif
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index a088c064ae4..2436df33c6f 100644
--- a/arch/powerpc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -145,6 +145,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
beq 1f
PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
li r3,MSR_FP|MSR_FE0|MSR_FE1
+#ifdef CONFIG_VSX
+BEGIN_FTR_SECTION
+ oris r3,r3,MSR_VSX@h
+END_FTR_SECTION_IFSET(CPU_FTR_VSX)
+#endif
andc r4,r4,r3 /* disable FP for previous task */
PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 5b5d16b2cac..70e2a736be1 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -293,7 +293,7 @@ __ftrace_make_nop(struct module *mod,
if (tramp & 0x8000)
tramp -= 0x10000;
- pr_debug(" %x ", tramp);
+ pr_debug(" %lx ", tramp);
if (tramp != addr) {
printk(KERN_ERR
@@ -557,7 +557,6 @@ extern void mod_return_to_handler(void);
void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
{
unsigned long old;
- unsigned long long calltime;
int faulted;
struct ftrace_graph_ent trace;
unsigned long return_hooker = (unsigned long)&return_to_handler;
@@ -565,7 +564,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
if (unlikely(atomic_read(&current->tracing_graph_pause)))
return;
-#if CONFIG_PPC64
+#ifdef CONFIG_PPC64
/* non core kernel code needs to save and restore the TOC */
if (REGION_ID(self_addr) != KERNEL_REGION_ID)
return_hooker = (unsigned long)&mod_return_to_handler;
@@ -606,10 +605,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
return;
}
- calltime = cpu_clock(raw_smp_processor_id());
-
- if (ftrace_push_return_trace(old, calltime,
- self_addr, &trace.depth) == -EBUSY) {
+ if (ftrace_push_return_trace(old, self_addr, &trace.depth) == -EBUSY) {
*parent = old;
return;
}
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 5576147e57b..8c1a4966867 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -672,11 +672,13 @@ unsigned int irq_create_mapping(struct irq_host *host,
return NO_IRQ;
}
}
- pr_debug("irq: -> obtained virq %d\n", virq);
if (irq_setup_virq(host, virq, hwirq))
return NO_IRQ;
+ printk(KERN_DEBUG "irq: irq %lu on host %s mapped to virtual irq %u\n",
+ hwirq, host->of_node ? host->of_node->full_name : "null", virq);
+
return virq;
}
EXPORT_SYMBOL_GPL(irq_create_mapping);
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 182e0f642f3..78b3f7840ad 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -434,6 +434,21 @@ static void pseries_cmo_data(struct seq_file *m)
seq_printf(m, "cmo_page_size=%lu\n", cmo_get_page_size());
}
+static void splpar_dispatch_data(struct seq_file *m)
+{
+ int cpu;
+ unsigned long dispatches = 0;
+ unsigned long dispatch_dispersions = 0;
+
+ for_each_possible_cpu(cpu) {
+ dispatches += lppaca[cpu].yield_count;
+ dispatch_dispersions += lppaca[cpu].dispersion_count;
+ }
+
+ seq_printf(m, "dispatches=%lu\n", dispatches);
+ seq_printf(m, "dispatch_dispersions=%lu\n", dispatch_dispersions);
+}
+
static int pseries_lparcfg_data(struct seq_file *m, void *v)
{
int partition_potential_processors;
@@ -460,6 +475,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
parse_ppp_data(m);
parse_mpp_data(m);
pseries_cmo_data(m);
+ splpar_dispatch_data(m);
seq_printf(m, "purr=%ld\n", get_purr());
} else { /* non SPLPAR case */
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index 3053fe5c62f..b9530b2395a 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -495,7 +495,15 @@ _GLOBAL(giveup_altivec)
stvx vr0,r4,r3
beq 1f
ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+#ifdef CONFIG_VSX
+BEGIN_FTR_SECTION
+ lis r3,(MSR_VEC|MSR_VSX)@h
+FTR_SECTION_ELSE
+ lis r3,MSR_VEC@h
+ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX)
+#else
lis r3,MSR_VEC@h
+#endif
andc r4,r4,r3 /* disable FP for previous task */
std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index 3f37a6e6277..87df428e358 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -76,7 +76,7 @@ struct of_device* of_platform_device_create(struct device_node *np,
return NULL;
dev->dma_mask = 0xffffffffUL;
- dev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+ dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
dev->dev.bus = &of_platform_bus_type;
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 2e026c0407d..2f0e64b5364 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -614,7 +614,7 @@ static unsigned char ibm_architecture_vec[] = {
W(0xffffffff), /* virt_base */
W(0xffffffff), /* virt_size */
W(0xffffffff), /* load_base */
- W(64), /* 128MB min RMA */
+ W(64), /* 64MB min RMA */
W(0xffffffff), /* full client load */
0, /* min RMA percentage of total RAM */
48, /* max log_2(hash table size) */
@@ -732,15 +732,17 @@ static void __init prom_send_capabilities(void)
root = call_prom("open", 1, 1, ADDR("/"));
if (root != 0) {
/* try calling the ibm,client-architecture-support method */
+ prom_printf("Calling ibm,client-architecture...");
if (call_prom_ret("call-method", 3, 2, &ret,
ADDR("ibm,client-architecture-support"),
root,
ADDR(ibm_architecture_vec)) == 0) {
/* the call exists... */
if (ret)
- prom_printf("WARNING: ibm,client-architecture"
+ prom_printf("\nWARNING: ibm,client-architecture"
"-support call FAILED!\n");
call_prom("close", 1, 0, root);
+ prom_printf(" done\n");
return;
}
call_prom("close", 1, 0, root);
@@ -1083,7 +1085,7 @@ static void __init prom_instantiate_rtas(void)
return;
}
- prom_printf("instantiating rtas at 0x%x ...", base);
+ prom_printf("instantiating rtas at 0x%x...", base);
if (call_prom_ret("call-method", 3, 2, &entry,
ADDR("instantiate-rtas"),
@@ -1495,7 +1497,7 @@ static int __init prom_find_machine_type(void)
return PLATFORM_GENERIC;
x = prom_getproplen(rtas, "ibm,hypertas-functions");
if (x != PROM_ERROR) {
- prom_printf("Hypertas detected, assuming LPAR !\n");
+ prom_debug("Hypertas detected, assuming LPAR !\n");
return PLATFORM_PSERIES_LPAR;
}
return PLATFORM_PSERIES;
@@ -1544,7 +1546,7 @@ static void __init prom_check_displays(void)
};
const unsigned char *clut;
- prom_printf("Looking for displays\n");
+ prom_debug("Looking for displays\n");
for (node = 0; prom_next_node(&node); ) {
memset(type, 0, sizeof(type));
prom_getprop(node, "device_type", type, sizeof(type));
@@ -1562,7 +1564,7 @@ static void __init prom_check_displays(void)
if (call_prom("package-to-path", 3, 1, node, path,
PROM_SCRATCH_SIZE-10) == PROM_ERROR)
continue;
- prom_printf("found display : %s, opening ... ", path);
+ prom_printf("found display : %s, opening... ", path);
ih = call_prom("open", 1, 1, path);
if (ih == 0) {
@@ -2387,7 +2389,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
/*
* Now finally create the flattened device-tree
*/
- prom_printf("copying OF device tree ...\n");
+ prom_printf("copying OF device tree...\n");
flatten_device_tree();
/*
@@ -2402,7 +2404,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
* Call OF "quiesce" method to shut down pending DMA's from
* devices etc...
*/
- prom_printf("Calling quiesce ...\n");
+ prom_printf("Calling quiesce...\n");
call_prom("quiesce", 0, 0);
/*
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index 197d49c790a..297632cba04 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -67,7 +67,8 @@ static long compat_ptrace_old(struct task_struct *child, long request,
/* Macros to workout the correct index for the FPR in the thread struct */
#define FPRNUMBER(i) (((i) - PT_FPR0) >> 1)
#define FPRHALF(i) (((i) - PT_FPR0) & 1)
-#define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) + FPRHALF(i)
+#define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) * 2 + FPRHALF(i)
+#define FPRINDEX_3264(i) (TS_FPRWIDTH * ((i) - PT_FPR0))
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
compat_ulong_t caddr, compat_ulong_t cdata)
@@ -168,8 +169,9 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
CHECK_FULL_REGS(child->thread.regs);
if (numReg >= PT_FPR0) {
flush_fp_to_thread(child);
- tmp = ((unsigned long int *)child->thread.fpr)
- [FPRINDEX(numReg)];
+ /* get 64 bit FPR */
+ tmp = ((u64 *)child->thread.fpr)
+ [FPRINDEX_3264(numReg)];
} else { /* register within PT_REGS struct */
tmp = ptrace_get_reg(child, numReg);
}
@@ -262,8 +264,13 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
freg = (freg & 0xfffffffful) | (data << 32);
ret = ptrace_put_reg(child, numReg, freg);
} else {
+ u64 *tmp;
flush_fp_to_thread(child);
- ((unsigned int *)child->thread.regs)[index] = data;
+ /* get 64 bit FPR ... */
+ tmp = &(((u64 *)child->thread.fpr)
+ [FPRINDEX_3264(numReg)]);
+ /* ... write the 32 bit part we want */
+ ((u32 *)tmp)[index % 2] = data;
ret = 0;
}
break;
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 9774f9fed96..02fed27af7f 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -36,7 +36,6 @@
#include <linux/percpu.h>
#include <linux/lmb.h>
#include <linux/of_platform.h>
-#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/processor.h>
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index c9564031a2a..926ea864e34 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -1127,3 +1127,19 @@ void div128_by_32(u64 dividend_high, u64 dividend_low,
dr->result_low = ((u64)y << 32) + z;
}
+
+static int __init rtc_init(void)
+{
+ struct platform_device *pdev;
+
+ if (!ppc_md.get_rtc_time)
+ return -ENODEV;
+
+ pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
+}
+
+module_init(rtc_init);
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index ffa2a9fd53d..e3e87078d03 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -293,7 +293,7 @@ config CPM
config OF_RTC
bool
help
- Uses information from the OF or flattened device tree to instatiate
+ Uses information from the OF or flattened device tree to instantiate
platform devices for direct mapped RTC chips like the DS1742 or DS1743.
source "arch/powerpc/sysdev/bestcomm/Kconfig"
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 5744527a7f2..bed4690de39 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -644,7 +644,7 @@ static void dma_fixed_unmap_sg(struct device *dev, struct scatterlist *sg,
static int dma_fixed_dma_supported(struct device *dev, u64 mask)
{
- return mask == DMA_64BIT_MASK;
+ return mask == DMA_BIT_MASK(64);
}
static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask);
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 6ed75bffc8a..ff43f1fd834 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -202,7 +202,7 @@ static struct iommu_table vio_iommu_table;
void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag)
{
return iommu_alloc_coherent(NULL, &vio_iommu_table, size, dma_handle,
- DMA_32BIT_MASK, flag, -1);
+ DMA_BIT_MASK(32), flag, -1);
}
EXPORT_SYMBOL_GPL(iseries_hv_alloc);
@@ -217,7 +217,7 @@ dma_addr_t iseries_hv_map(void *vaddr, size_t size,
{
return iommu_map_page(NULL, &vio_iommu_table, virt_to_page(vaddr),
(unsigned long)vaddr % PAGE_SIZE, size,
- DMA_32BIT_MASK, direction, NULL);
+ DMA_BIT_MASK(32), direction, NULL);
}
void iseries_hv_unmap(dma_addr_t dma_handle, size_t size,
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
index e1c83c23b43..86e392b1b04 100644
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -808,6 +808,7 @@ u64 ps3_os_area_get_rtc_diff(void)
{
return saved_params.rtc_diff;
}
+EXPORT_SYMBOL(ps3_os_area_get_rtc_diff);
/**
* ps3_os_area_set_rtc_diff - Set the rtc diff value.
@@ -823,6 +824,7 @@ void ps3_os_area_set_rtc_diff(u64 rtc_diff)
os_area_queue_work();
}
}
+EXPORT_SYMBOL(ps3_os_area_set_rtc_diff);
/**
* ps3_os_area_get_av_multi_out - Returns the default video mode.
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index 235c13ebacd..136aa0637d9 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -64,8 +64,6 @@ int ps3_set_rtc_time(struct rtc_time *time);
void __init ps3_os_area_save_params(void);
void __init ps3_os_area_init(void);
-u64 ps3_os_area_get_rtc_diff(void);
-void ps3_os_area_set_rtc_diff(u64 rtc_diff);
/* spu */
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 3331ccbb8d3..66181821322 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -270,8 +270,6 @@ define_machine(ps3) {
.init_IRQ = ps3_init_IRQ,
.panic = ps3_panic,
.get_boot_time = ps3_get_boot_time,
- .set_rtc_time = ps3_set_rtc_time,
- .get_rtc_time = ps3_get_rtc_time,
.set_dabr = ps3_set_dabr,
.calibrate_decr = ps3_calibrate_decr,
.progress = ps3_progress,
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index a705fffbb49..9a73d023863 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -689,7 +689,7 @@ static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg,
static int ps3_dma_supported(struct device *_dev, u64 mask)
{
- return mask >= DMA_32BIT_MASK;
+ return mask >= DMA_BIT_MASK(32);
}
static struct dma_mapping_ops ps3_sb_dma_ops = {
diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c
index d0daf7d6d3b..b178a1e66c9 100644
--- a/arch/powerpc/platforms/ps3/time.c
+++ b/arch/powerpc/platforms/ps3/time.c
@@ -19,6 +19,7 @@
*/
#include <linux/kernel.h>
+#include <linux/platform_device.h>
#include <asm/rtc.h>
#include <asm/lv1call.h>
@@ -74,23 +75,20 @@ static u64 read_rtc(void)
return rtc_val;
}
-int ps3_set_rtc_time(struct rtc_time *tm)
+unsigned long __init ps3_get_boot_time(void)
{
- u64 now = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
-
- ps3_os_area_set_rtc_diff(now - read_rtc());
- return 0;
+ return read_rtc() + ps3_os_area_get_rtc_diff();
}
-void ps3_get_rtc_time(struct rtc_time *tm)
+static int __init ps3_rtc_init(void)
{
- to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm);
- tm->tm_year -= 1900;
- tm->tm_mon -= 1;
-}
+ struct platform_device *pdev;
-unsigned long __init ps3_get_boot_time(void)
-{
- return read_rtc() + ps3_os_area_get_rtc_diff();
+ pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
}
+
+module_init(ps3_rtc_init);
diff --git a/arch/powerpc/sysdev/bestcomm/Kconfig b/arch/powerpc/sysdev/bestcomm/Kconfig
index 0b192a1c429..29e427085ef 100644
--- a/arch/powerpc/sysdev/bestcomm/Kconfig
+++ b/arch/powerpc/sysdev/bestcomm/Kconfig
@@ -9,8 +9,8 @@ config PPC_BESTCOMM
select PPC_LIB_RHEAP
help
BestComm is the name of the communication coprocessor found
- on the Freescale MPC5200 family of processor. It's usage is
- optionnal for some drivers (like ATA), but required for
+ on the Freescale MPC5200 family of processor. Its usage is
+ optional for some drivers (like ATA), but required for
others (like FEC).
If you want to use drivers that require DMA operations,
diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c
index 0494ee55920..dceb8d1a843 100644
--- a/arch/powerpc/sysdev/fsl_lbc.c
+++ b/arch/powerpc/sysdev/fsl_lbc.c
@@ -150,7 +150,7 @@ int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar)
spin_lock_irqsave(&fsl_lbc_lock, flags);
- out_be32(&fsl_lbc_regs->mar, mar << (32 - upm->width));
+ out_be32(&fsl_lbc_regs->mar, mar);
switch (upm->width) {
case 8:
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 532e205303a..21b95670159 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1170,6 +1170,12 @@ struct mpic * __init mpic_alloc(struct device_node *node,
mb();
}
+ /* CoreInt */
+ if (flags & MPIC_ENABLE_COREINT)
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
+ mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
+ | MPIC_GREG_GCONF_COREINT);
+
if (flags & MPIC_ENABLE_MCK)
mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
@@ -1525,6 +1531,34 @@ unsigned int mpic_get_irq(void)
return mpic_get_one_irq(mpic);
}
+unsigned int mpic_get_coreint_irq(void)
+{
+#ifdef CONFIG_BOOKE
+ struct mpic *mpic = mpic_primary;
+ u32 src;
+
+ BUG_ON(mpic == NULL);
+
+ src = mfspr(SPRN_EPR);
+
+ if (unlikely(src == mpic->spurious_vec)) {
+ if (mpic->flags & MPIC_SPV_EOI)
+ mpic_eoi(mpic);
+ return NO_IRQ;
+ }
+ if (unlikely(mpic->protected && test_bit(src, mpic->protected))) {
+ if (printk_ratelimit())
+ printk(KERN_WARNING "%s: Got protected source %d !\n",
+ mpic->name, (int)src);
+ return NO_IRQ;
+ }
+
+ return irq_linear_revmap(mpic->irqhost, src);
+#else
+ return NO_IRQ;
+#endif
+}
+
unsigned int mpic_get_mcirq(void)
{
struct mpic *mpic = mpic_primary;
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index dcb667c4375..2eca5fe0e75 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -82,6 +82,7 @@ config S390
select USE_GENERIC_SMP_HELPERS if SMP
select HAVE_SYSCALL_WRAPPERS
select HAVE_FUNCTION_TRACER
+ select HAVE_DEFAULT_NO_SPIN_MUTEXES
select HAVE_OPROFILE
select HAVE_KPROBES
select HAVE_KRETPROBES
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index 2009158a450..72137bc907a 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -92,12 +92,6 @@ extern void arch_send_call_function_ipi(cpumask_t mask);
#endif
#ifndef CONFIG_SMP
-static inline void smp_send_stop(void)
-{
- /* Disable all interrupts/machine checks */
- __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
-}
-
#define hard_smp_processor_id() 0
#define smp_cpu_not_running(cpu) 1
#endif
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 8d50d527c59..e7390dd0283 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -14,6 +14,7 @@ config SUPERH
select HAVE_GENERIC_DMA_COHERENT
select HAVE_IOREMAP_PROT if MMU
select HAVE_ARCH_TRACEHOOK
+ select HAVE_DMA_API_DEBUG
help
The SuperH is a RISC processor targeted for use in embedded systems
and consumer electronics; it was also used in the Sega Dreamcast
@@ -21,16 +22,17 @@ config SUPERH
<http://www.linux-sh.org/>.
config SUPERH32
- def_bool !SUPERH64
+ def_bool ARCH = "sh"
select HAVE_KPROBES
select HAVE_KRETPROBES
select HAVE_FUNCTION_TRACER
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE
select HAVE_ARCH_KGDB
+ select ARCH_HIBERNATION_POSSIBLE if MMU
config SUPERH64
- def_bool y if CPU_SH5
+ def_bool ARCH = "sh64"
config ARCH_DEFCONFIG
string
@@ -129,6 +131,9 @@ config ARCH_HAS_ILOG2_U64
config ARCH_NO_VIRT_TO_BUS
def_bool y
+config ARCH_HAS_DEFAULT_IDLE
+ def_bool y
+
config IO_TRAPPED
bool
@@ -183,6 +188,8 @@ config ARCH_SHMOBILE
bool
select ARCH_SUSPEND_POSSIBLE
+if SUPERH32
+
choice
prompt "Processor sub-type selection"
@@ -404,6 +411,15 @@ config CPU_SUBTYPE_SH7366
select SYS_SUPPORTS_NUMA
select SYS_SUPPORTS_CMT
+endchoice
+
+endif
+
+if SUPERH64
+
+choice
+ prompt "Processor sub-type selection"
+
# SH-5 Processor Support
config CPU_SUBTYPE_SH5_101
@@ -416,6 +432,8 @@ config CPU_SUBTYPE_SH5_103
endchoice
+endif
+
source "arch/sh/mm/Kconfig"
source "arch/sh/Kconfig.cpu"
@@ -530,7 +548,7 @@ source kernel/Kconfig.hz
config KEXEC
bool "kexec system call (EXPERIMENTAL)"
- depends on SUPERH32 && EXPERIMENTAL
+ depends on SUPERH32 && EXPERIMENTAL && MMU
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
@@ -640,10 +658,10 @@ config GUSA_RB
depends on GUSA && CPU_SH3 || (CPU_SH4 && !CPU_SH4A)
help
Enabling this option will allow the kernel to implement some
- atomic operations using a software implemention of load-locked/
+ atomic operations using a software implementation of load-locked/
store-conditional (LLSC). On machines which do not have hardware
LLSC, this should be more efficient than the other alternative of
- disabling insterrupts around the atomic sequence.
+ disabling interrupts around the atomic sequence.
endmenu
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
index e27655b8a98..39e46919df1 100644
--- a/arch/sh/boards/board-ap325rxa.c
+++ b/arch/sh/boards/board-ap325rxa.c
@@ -22,6 +22,7 @@
#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_gpio.h>
+#include <media/ov772x.h>
#include <media/soc_camera.h>
#include <media/soc_camera_platform.h>
#include <media/sh_mobile_ceu.h>
@@ -235,6 +236,7 @@ static void camera_power(int val)
}
#ifdef CONFIG_I2C
+/* support for the old ncm03j camera */
static unsigned char camera_ncm03j_magic[] =
{
0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
@@ -255,6 +257,23 @@ static unsigned char camera_ncm03j_magic[] =
0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
};
+static int camera_probe(void)
+{
+ struct i2c_adapter *a = i2c_get_adapter(0);
+ struct i2c_msg msg;
+ int ret;
+
+ camera_power(1);
+ msg.addr = 0x6e;
+ msg.buf = camera_ncm03j_magic;
+ msg.len = 2;
+ msg.flags = 0;
+ ret = i2c_transfer(a, &msg, 1);
+ camera_power(0);
+
+ return ret;
+}
+
static int camera_set_capture(struct soc_camera_platform_info *info,
int enable)
{
@@ -306,12 +325,38 @@ static struct platform_device camera_device = {
.platform_data = &camera_info,
},
};
+
+static int __init camera_setup(void)
+{
+ if (camera_probe() > 0)
+ platform_device_register(&camera_device);
+
+ return 0;
+}
+late_initcall(camera_setup);
+
#endif /* CONFIG_I2C */
+static int ov7725_power(struct device *dev, int mode)
+{
+ camera_power(0);
+ if (mode)
+ camera_power(1);
+
+ return 0;
+}
+
+static struct ov772x_camera_info ov7725_info = {
+ .buswidth = SOCAM_DATAWIDTH_8,
+ .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
+ .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0),
+ .link = {
+ .power = ov7725_power,
+ },
+};
+
static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
- .flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
- SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER |
- SOCAM_DATAWIDTH_8,
+ .flags = SH_CEU_FLAG_USE_8BIT_BUS,
};
static struct resource ceu_resources[] = {
@@ -359,9 +404,6 @@ static struct platform_device *ap325rxa_devices[] __initdata = {
&ap325rxa_nor_flash_device,
&lcdc_device,
&ceu_device,
-#ifdef CONFIG_I2C
- &camera_device,
-#endif
&nand_flash_device,
&sdcard_cn3_device,
};
@@ -370,6 +412,10 @@ static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
{
I2C_BOARD_INFO("pcf8563", 0x51),
},
+ {
+ I2C_BOARD_INFO("ov772x", 0x21),
+ .platform_data = &ov7725_info,
+ },
};
static struct spi_board_info ap325rxa_spi_devices[] = {
diff --git a/arch/sh/boards/board-urquell.c b/arch/sh/boards/board-urquell.c
index 17036ce2008..beb88c4da2c 100644
--- a/arch/sh/boards/board-urquell.c
+++ b/arch/sh/boards/board-urquell.c
@@ -2,6 +2,8 @@
* Renesas Technology Corp. SH7786 Urquell Support.
*
* Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on board-sh7785lcr.c
* Copyright (C) 2008 Yoshihiro Shimoda
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -21,6 +23,32 @@
#include <asm/heartbeat.h>
#include <asm/sizes.h>
+/*
+ * bit 1234 5678
+ *----------------------------
+ * SW1 0101 0010 -> Pck 33MHz version
+ * (1101 0010) Pck 66MHz version
+ * SW2 0x1x xxxx -> little endian
+ * 29bit mode
+ * SW47 0001 1000 -> CS0 : on-board flash
+ * CS1 : SRAM, registers, LAN, PCMCIA
+ * 38400 bps for SCIF1
+ *
+ * Address
+ * 0x00000000 - 0x04000000 (CS0) Nor Flash
+ * 0x04000000 - 0x04200000 (CS1) SRAM
+ * 0x05000000 - 0x05800000 (CS1) on board register
+ * 0x05800000 - 0x06000000 (CS1) LAN91C111
+ * 0x06000000 - 0x06400000 (CS1) PCMCIA
+ * 0x08000000 - 0x10000000 (CS2-CS3) DDR3
+ * 0x10000000 - 0x14000000 (CS4) PCIe
+ * 0x14000000 - 0x14800000 (CS5) Core0 LRAM/URAM
+ * 0x14800000 - 0x15000000 (CS5) Core1 LRAM/URAM
+ * 0x18000000 - 0x1C000000 (CS6) ATA/NAND-Flash
+ * 0x1C000000 - (CS7) SH7786 Control register
+ */
+
+/* HeartBeat */
static struct resource heartbeat_resources[] = {
[0] = {
.start = BOARDREG(SLEDR),
@@ -43,6 +71,7 @@ static struct platform_device heartbeat_device = {
.resource = heartbeat_resources,
};
+/* LAN91C111 */
static struct smc91x_platdata smc91x_info = {
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
};
@@ -69,6 +98,7 @@ static struct platform_device smc91x_eth_device = {
},
};
+/* Nor Flash */
static struct mtd_partition nor_flash_partitions[] = {
{
.name = "loader",
@@ -129,6 +159,10 @@ static int __init urquell_devices_setup(void)
gpio_request(GPIO_FN_USB_OVC0, NULL);
gpio_request(GPIO_FN_USB_PENC0, NULL);
+ /* enable LAN */
+ __raw_writew(__raw_readw(UBOARDREG(IRL2MSKR)) & ~0x00000001,
+ UBOARDREG(IRL2MSKR));
+
return platform_add_devices(urquell_devices,
ARRAY_SIZE(urquell_devices));
}
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 4fd6a727873..1ee1de0bc1c 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -352,9 +352,7 @@ static int tw9910_power(struct device *dev, int mode)
}
static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
- .flags = SOCAM_MASTER | SOCAM_DATAWIDTH_8 | SOCAM_PCLK_SAMPLE_RISING
- | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH
- | SOCAM_DATA_ACTIVE_HIGH,
+ .flags = SH_CEU_FLAG_USE_8BIT_BUS,
};
static struct resource migor_ceu_resources[] = {
diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig
index 352f87d50fd..c8d982a8a2e 100644
--- a/arch/sh/configs/ap325rxa_defconfig
+++ b/arch/sh/configs/ap325rxa_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 27 11:45:08 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 17:46:53 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,14 +16,16 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -43,6 +45,15 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -58,6 +69,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -66,10 +78,8 @@ 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
@@ -77,6 +87,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -115,11 +126,6 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -128,6 +134,7 @@ CONFIG_CLASSIC_RCU=y
CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -156,6 +163,7 @@ CONFIG_CPU_SUBTYPE_SH7723=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -198,11 +206,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -228,6 +237,7 @@ CONFIG_SH_AP325RXA=y
# Timer and clock configuration
#
CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
CONFIG_SH_TIMER_IRQ=16
CONFIG_SH_PCLK_FREQ=33333333
CONFIG_TICK_ONESHOT=y
@@ -304,7 +314,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -359,6 +368,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -371,7 +381,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -483,7 +492,6 @@ CONFIG_MTD_NAND_SH_FLCTL=y
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
#
# UBI - Unsorted block images
@@ -510,10 +518,18 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -559,9 +575,11 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -594,8 +612,10 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -612,7 +632,6 @@ CONFIG_SMSC911X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -687,6 +706,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -723,12 +743,9 @@ CONFIG_I2C_SH_MOBILE=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_AT24 is not set
-# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -748,7 +765,6 @@ CONFIG_SPI_GPIO=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
@@ -822,7 +838,7 @@ CONFIG_VIDEO_MEDIA=y
#
# CONFIG_MEDIA_ATTACH is not set
CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
CONFIG_MEDIA_TUNER_SIMPLE=y
CONFIG_MEDIA_TUNER_TDA8290=y
CONFIG_MEDIA_TUNER_TDA9887=y
@@ -831,6 +847,7 @@ CONFIG_MEDIA_TUNER_TEA5767=y
CONFIG_MEDIA_TUNER_MT20XX=y
CONFIG_MEDIA_TUNER_XC2028=y
CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
CONFIG_VIDEO_V4L2=y
CONFIG_VIDEOBUF_GEN=y
CONFIG_VIDEOBUF_DMA_CONTIG=y
@@ -886,6 +903,7 @@ CONFIG_FB_SH_MOBILE_LCDC=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -995,6 +1013,7 @@ CONFIG_RTC_DRV_PCF8563=y
#
# CONFIG_RTC_DRV_SH is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=y
# CONFIG_UIO_PDRV is not set
CONFIG_UIO_PDRV_GENIRQ=y
@@ -1096,7 +1115,6 @@ CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1177,7 +1195,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1204,10 +1221,12 @@ CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1276,6 +1295,7 @@ CONFIG_CRYPTO_CBC=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1296,7 +1316,7 @@ CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
CONFIG_CRC7=y
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/cayman_defconfig b/arch/sh/configs/cayman_defconfig
index 92895013813..fa5fc1e1e98 100644
--- a/arch/sh/configs/cayman_defconfig
+++ b/arch/sh/configs/cayman_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27
-# Wed Oct 22 18:04:52 2008
+# Linux kernel version: 2.6.29
+# Thu Apr 2 17:49:14 2009
#
CONFIG_SUPERH=y
# CONFIG_SUPERH32 is not set
@@ -16,6 +16,8 @@ CONFIG_GENERIC_IRQ_PROBE=y
# CONFIG_GENERIC_GPIO is not set
# CONFIG_GENERIC_TIME is not set
# CONFIG_GENERIC_CLOCKEVENTS is not set
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -23,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -40,10 +43,19 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -51,6 +63,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -61,10 +74,8 @@ 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
@@ -73,18 +84,18 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -92,11 +103,9 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -112,7 +121,6 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
# CONFIG_FREEZER is not set
#
@@ -120,6 +128,7 @@ CONFIG_CLASSIC_RCU=y
#
CONFIG_CPU_SH5=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
# CONFIG_CPU_SUBTYPE_SH7206 is not set
# CONFIG_CPU_SUBTYPE_SH7263 is not set
@@ -146,6 +155,7 @@ CONFIG_CPU_SH5=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -188,16 +198,16 @@ CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_SPARSEMEM_STATIC=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_CACHE_WRITEBACK is not set
# CONFIG_CACHE_WRITETHROUGH is not set
CONFIG_CACHE_OFF=y
@@ -256,7 +266,6 @@ CONFIG_HZ=250
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
-# CONFIG_PREEMPT_RCU is not set
#
# Boot options
@@ -272,9 +281,12 @@ CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
CONFIG_PCI_AUTO=y
CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
+# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
@@ -285,6 +297,12 @@ CONFIG_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE is not set
CONFIG_NET=y
#
@@ -344,7 +362,9 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
#
# Network testing
@@ -355,13 +375,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -400,11 +420,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -447,6 +476,7 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -459,7 +489,10 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
@@ -478,6 +511,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_FUSION is not set
@@ -493,6 +527,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -510,7 +545,10 @@ CONFIG_NET_ETHERNET=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -543,9 +581,11 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_CHELSIO_T3 is not set
# CONFIG_ENIC is not set
# CONFIG_IXGBE is not set
@@ -554,11 +594,13 @@ CONFIG_NETDEV_10000=y
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -566,7 +608,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -636,10 +681,12 @@ CONFIG_DEVKMEM=y
# CONFIG_SERIAL_SH_SCI is not set
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -700,12 +747,9 @@ CONFIG_I2C_HELPER_AUTO=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -725,8 +769,10 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -747,10 +793,14 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
@@ -786,11 +836,11 @@ CONFIG_WATCHDOG=y
#
# CONFIG_PCIPCWATCHDOG is not set
# CONFIG_WDTPCI is not set
+CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
-CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
#
@@ -802,6 +852,8 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
#
# Multimedia devices
@@ -822,7 +874,7 @@ CONFIG_VIDEO_MEDIA=m
#
# CONFIG_MEDIA_ATTACH is not set
CONFIG_MEDIA_TUNER=m
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
CONFIG_MEDIA_TUNER_SIMPLE=m
CONFIG_MEDIA_TUNER_TDA8290=m
CONFIG_MEDIA_TUNER_TDA9887=m
@@ -831,6 +883,7 @@ CONFIG_MEDIA_TUNER_TEA5767=m
CONFIG_MEDIA_TUNER_MT20XX=m
CONFIG_MEDIA_TUNER_XC2028=m
CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MEDIA_TUNER_MC44S803=m
CONFIG_VIDEO_V4L2=m
CONFIG_VIDEO_V4L1=m
CONFIG_VIDEO_CAPTURE_DRIVERS=y
@@ -853,6 +906,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
# CONFIG_VIDEO_CAFE_CCIC is not set
# CONFIG_SOC_CAMERA is not set
# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DVB_DYNAMIC_MINORS is not set
CONFIG_DVB_CAPTURE_DRIVERS=y
#
@@ -884,89 +938,7 @@ CONFIG_DVB_CAPTURE_DRIVERS=y
#
# Supported DVB Frontends
#
-
-#
-# Customise DVB Frontends
-#
# CONFIG_DVB_FE_CUSTOMISE is not set
-
-#
-# DVB-S (satellite) frontends
-#
-# CONFIG_DVB_CX24110 is not set
-# CONFIG_DVB_CX24123 is not set
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_S5H1420 is not set
-# CONFIG_DVB_STV0288 is not set
-# CONFIG_DVB_STB6000 is not set
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_TDA8083 is not set
-# CONFIG_DVB_TDA10086 is not set
-# CONFIG_DVB_VES1X93 is not set
-# CONFIG_DVB_TUNER_ITD1000 is not set
-# CONFIG_DVB_TDA826X is not set
-# CONFIG_DVB_TUA6100 is not set
-# CONFIG_DVB_CX24116 is not set
-# CONFIG_DVB_SI21XX is not set
-
-#
-# DVB-T (terrestrial) frontends
-#
-# CONFIG_DVB_SP8870 is not set
-# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_CX22700 is not set
-# CONFIG_DVB_CX22702 is not set
-# CONFIG_DVB_DRX397XD is not set
-# CONFIG_DVB_L64781 is not set
-# CONFIG_DVB_TDA1004X is not set
-# CONFIG_DVB_NXT6000 is not set
-# CONFIG_DVB_MT352 is not set
-# CONFIG_DVB_ZL10353 is not set
-# CONFIG_DVB_DIB3000MB is not set
-# CONFIG_DVB_DIB3000MC is not set
-# CONFIG_DVB_DIB7000M is not set
-# CONFIG_DVB_DIB7000P is not set
-# CONFIG_DVB_TDA10048 is not set
-
-#
-# DVB-C (cable) frontends
-#
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_TDA10021 is not set
-# CONFIG_DVB_TDA10023 is not set
-# CONFIG_DVB_STV0297 is not set
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
-# CONFIG_DVB_NXT200X is not set
-# CONFIG_DVB_OR51211 is not set
-# CONFIG_DVB_OR51132 is not set
-# CONFIG_DVB_BCM3510 is not set
-# CONFIG_DVB_LGDT330X is not set
-# CONFIG_DVB_S5H1409 is not set
-# CONFIG_DVB_AU8522 is not set
-# CONFIG_DVB_S5H1411 is not set
-
-#
-# Digital terrestrial only tuners/PLL
-#
-# CONFIG_DVB_PLL is not set
-# CONFIG_DVB_TUNER_DIB0070 is not set
-
-#
-# SEC control devices for DVB-S
-#
-# CONFIG_DVB_LNBP21 is not set
-# CONFIG_DVB_ISL6405 is not set
-# CONFIG_DVB_ISL6421 is not set
-# CONFIG_DVB_LGS8GL5 is not set
-
-#
-# Tools to develop new frontends
-#
-# CONFIG_DVB_DUMMY_FE is not set
-# CONFIG_DVB_AF9013 is not set
CONFIG_DAB=y
#
@@ -979,15 +951,16 @@ CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
# CONFIG_FB_DDC is not set
# CONFIG_FB_BOOT_VESA_SUPPORT is not set
-CONFIG_FB_CFB_FILLRECT=m
-CONFIG_FB_CFB_COPYAREA=m
-CONFIG_FB_CFB_IMAGEBLIT=m
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
-# CONFIG_FB_SYS_FILLRECT is not set
-# CONFIG_FB_SYS_COPYAREA is not set
-# CONFIG_FB_SYS_IMAGEBLIT is not set
+CONFIG_FB_SYS_FILLRECT=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
# CONFIG_FB_FOREIGN_ENDIAN is not set
-# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_SYS_FOPS=m
+CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
@@ -1025,6 +998,8 @@ CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_SH_MOBILE_LCDC=m
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -1081,9 +1056,14 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -1091,6 +1071,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1114,6 +1095,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1148,10 +1130,7 @@ CONFIG_TMPFS=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1160,6 +1139,7 @@ CONFIG_HUGETLB_PAGE=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1179,7 +1159,6 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1252,6 +1231,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
CONFIG_FRAME_POINTER=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -1260,17 +1240,25 @@ CONFIG_FRAME_POINTER=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_DEBUG_BOOTMEM is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_4KSTACKS is not set
-CONFIG_SH64_PROC_ASIDS=y
+# CONFIG_SH_NO_BSS_INIT is not set
+# CONFIG_MORE_COMPILE_OPTIONS is not set
CONFIG_SH64_SR_WATCH=y
# CONFIG_POOR_MANS_STRACE is not set
-# CONFIG_SH_ALPHANUMERIC is not set
-# CONFIG_SH_NO_BSS_INIT is not set
#
# Security options
@@ -1286,6 +1274,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
@@ -1356,6 +1345,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1369,6 +1359,7 @@ CONFIG_CRYPTO_HW=y
# Library routines
#
CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
@@ -1376,7 +1367,7 @@ CONFIG_BITREVERSE=y
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
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig
index 2d86e048751..5c112364014 100644
--- a/arch/sh/configs/dreamcast_defconfig
+++ b/arch/sh/configs/dreamcast_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 16:54:55 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 17:51:48 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -44,10 +45,19 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -55,6 +65,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -64,10 +75,8 @@ 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
@@ -76,6 +85,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -116,11 +126,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -155,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7091=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -202,11 +208,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -263,9 +270,12 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_SH_DMA_IRQ_MULTI=y
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
CONFIG_NR_DMA_CHANNELS_BOOL=y
CONFIG_NR_DMA_CHANNELS=9
+# CONFIG_PVR2_DMA is not set
+# CONFIG_G2_DMA is not set
#
# Companion Chips
@@ -314,6 +324,8 @@ CONFIG_PCI_AUTO=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
@@ -335,7 +347,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -387,6 +398,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -399,13 +411,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -439,12 +451,16 @@ CONFIG_GDROM=y
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -470,6 +486,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -487,8 +504,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -532,7 +551,10 @@ CONFIG_8139TOO=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -628,6 +650,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -746,6 +769,7 @@ CONFIG_FB_PVR2=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -802,9 +826,13 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -813,6 +841,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -828,6 +857,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -871,6 +901,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -920,7 +951,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1012,6 +1042,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1033,7 +1064,7 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
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
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/edosk7705_defconfig b/arch/sh/configs/edosk7705_defconfig
index 461bfb35022..f4c34b03931 100644
--- a/arch/sh/configs/edosk7705_defconfig
+++ b/arch/sh/configs/edosk7705_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 16:55:29 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 17:54:02 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -35,6 +36,15 @@ CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
# CONFIG_CGROUPS is not set
@@ -50,7 +60,6 @@ CONFIG_EMBEDDED=y
# CONFIG_PRINTK is not set
# CONFIG_BUG is not set
# CONFIG_ELF_CORE is not set
-# CONFIG_COMPAT_BRK is not set
# CONFIG_BASE_FULL is not set
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
@@ -60,6 +69,7 @@ CONFIG_EMBEDDED=y
CONFIG_SHMEM=y
# CONFIG_AIO is not set
# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
@@ -74,11 +84,6 @@ CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_BASE_SMALL=1
# CONFIG_MODULES is not set
# CONFIG_BLOCK is not set
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -113,6 +118,7 @@ CONFIG_CPU_SUBTYPE_SH7705=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -157,12 +163,13 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
CONFIG_SH7705_CACHE_32KB=y
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -243,7 +250,6 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
# Executable file formats
#
CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
# CONFIG_NET is not set
@@ -361,6 +367,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig
index 14d4b35685a..7825c2699f1 100644
--- a/arch/sh/configs/edosk7760_defconfig
+++ b/arch/sh/configs/edosk7760_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 16:55:48 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 17:54:57 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -43,34 +44,45 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=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
@@ -79,6 +91,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
@@ -118,11 +131,6 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -157,6 +165,7 @@ CONFIG_CPU_SUBTYPE_SH7760=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -198,11 +207,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -245,7 +255,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=8
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
# CONFIG_SH_DMABRG is not set
@@ -310,7 +320,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -360,6 +369,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -372,13 +382,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -402,6 +412,7 @@ CONFIG_MTD_DEBUG=y
CONFIG_MTD_DEBUG_VERBOSE=0
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set
@@ -454,9 +465,7 @@ CONFIG_MTD_ABSENT=y
#
# 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_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -477,6 +486,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -506,6 +520,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -518,8 +533,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -536,7 +553,10 @@ CONFIG_SMC91X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -607,6 +627,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -643,12 +664,9 @@ CONFIG_I2C_SH7760=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
CONFIG_I2C_DEBUG_CORE=y
@@ -680,6 +698,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -732,6 +751,7 @@ CONFIG_FB_SH_MOBILE_LCDC=m
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -750,6 +770,7 @@ CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
# CONFIG_SND_SEQUENCER is not set
# CONFIG_SND_MIXER_OSS is not set
# CONFIG_SND_PCM_OSS is not set
@@ -781,6 +802,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=y
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -806,6 +828,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -851,6 +874,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -868,7 +892,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -974,6 +997,7 @@ CONFIG_DEBUG_INFO=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -989,7 +1013,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1095,6 +1118,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1115,7 +1139,9 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/espt_defconfig b/arch/sh/configs/espt_defconfig
index 873ec42c6e6..ebb4c37abaa 100644
--- a/arch/sh/configs/espt_defconfig
+++ b/arch/sh/configs/espt_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc7
-# Tue Mar 17 13:25:58 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 17:58:18 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -71,6 +72,7 @@ CONFIG_IPC_NS=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -80,10 +82,8 @@ 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
@@ -91,6 +91,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -213,11 +214,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -318,7 +320,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -373,6 +374,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -380,12 +382,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
# CONFIG_WIRELESS is not set
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
@@ -548,9 +550,11 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -583,8 +587,10 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
CONFIG_SH_ETH=y
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -601,7 +607,6 @@ CONFIG_SH_ETH=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -685,6 +690,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -764,6 +770,7 @@ CONFIG_FB_SH7760=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -817,6 +824,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -834,11 +842,11 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
@@ -880,7 +888,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -894,12 +901,14 @@ CONFIG_USB_STORAGE=y
#
# OTG and related infrastructure
#
+# CONFIG_NOP_USB_XCEIV 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_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -987,7 +996,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1071,7 +1079,7 @@ CONFIG_TRACING=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1163,6 +1171,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1184,7 +1193,7 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig
index 847a2510663..82b113af08d 100644
--- a/arch/sh/configs/hp6xx_defconfig
+++ b/arch/sh/configs/hp6xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 16:56:55 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:01:05 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -39,11 +40,20 @@ CONFIG_SWAP=y
# CONFIG_SYSVIPC is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -51,6 +61,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -60,10 +71,8 @@ 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
@@ -71,6 +80,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -104,11 +114,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_FREEZER=y
#
@@ -143,6 +148,7 @@ CONFIG_CPU_SUBTYPE_SH7709=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -184,11 +190,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -208,6 +215,7 @@ CONFIG_CPU_HAS_SR_RB=y
#
# CONFIG_SH_SOLUTION_ENGINE is not set
CONFIG_SH_HP6XX=y
+# CONFIG_SH_POLARIS is not set
#
# Timer and clock configuration
@@ -229,7 +237,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
#
@@ -302,6 +310,7 @@ CONFIG_PM=y
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
CONFIG_APM_EMULATION=y
# CONFIG_CPU_IDLE is not set
# CONFIG_NET is not set
@@ -329,9 +338,13 @@ CONFIG_BLK_DEV=y
# 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_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -375,6 +388,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -471,6 +485,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=64
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
#
@@ -554,12 +569,13 @@ CONFIG_FB_SH_MOBILE_LCDC=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
# CONFIG_LCD_ILI9320 is not set
# CONFIG_LCD_PLATFORM is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=y
CONFIG_BACKLIGHT_HP680=y
#
@@ -631,6 +647,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -647,6 +664,7 @@ CONFIG_EXT2_FS=y
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -692,6 +710,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -771,7 +790,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -799,10 +817,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
@@ -870,6 +890,7 @@ CONFIG_CRYPTO_MD5=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -890,7 +911,6 @@ CONFIG_CRC_T10DIF=y
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/landisk_defconfig b/arch/sh/configs/landisk_defconfig
index d3bbbb03771..b6fa4a7599d 100644
--- a/arch/sh/configs/landisk_defconfig
+++ b/arch/sh/configs/landisk_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 16:58:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:02:54 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,10 +43,19 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -53,6 +63,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -62,10 +73,8 @@ 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
@@ -74,6 +83,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -113,11 +123,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -152,6 +157,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -193,11 +199,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -290,6 +297,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
CONFIG_PCCARD=y
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=y
@@ -329,7 +338,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -410,6 +418,7 @@ CONFIG_ATALK=m
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -422,13 +431,13 @@ CONFIG_ATALK=m
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -468,18 +477,23 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
#
# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
+CONFIG_IDE_XFER_MODE=y
CONFIG_IDE_ATAPI=y
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_IDE_GD=y
@@ -585,6 +599,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -607,6 +622,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
@@ -631,6 +647,7 @@ CONFIG_MD_RAID1=m
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -648,8 +665,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -700,6 +719,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -718,6 +738,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -725,7 +746,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -814,6 +838,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -898,6 +923,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
CONFIG_V4L_USB_DRIVERS=y
# CONFIG_USB_VIDEO_CLASS is not set
# CONFIG_USB_GSPCA is not set
+# CONFIG_VIDEO_HDPVR is not set
CONFIG_VIDEO_USBVIDEO=m
CONFIG_USB_VICAM=m
CONFIG_USB_IBMCAM=m
@@ -911,6 +937,7 @@ CONFIG_USB_STV680=m
# CONFIG_USB_ZC0301 is not set
CONFIG_USB_PWC=m
# CONFIG_USB_PWC_DEBUG is not set
+CONFIG_USB_PWC_INPUT_EVDEV=y
# CONFIG_USB_ZR364XX is not set
# CONFIG_USB_STKWEBCAM is not set
# CONFIG_USB_S2255 is not set
@@ -1020,6 +1047,7 @@ CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
@@ -1041,22 +1069,21 @@ CONFIG_USB_PRINTER=m
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
# CONFIG_USB_STORAGE_USBAT is not set
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_STORAGE_KARMA is not set
@@ -1081,7 +1108,7 @@ CONFIG_USB_SERIAL=m
# 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_CP210X is not set
# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
# CONFIG_USB_SERIAL_EMPEG is not set
CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -1105,15 +1132,19 @@ CONFIG_USB_SERIAL_FTDI_SIO=m
# CONFIG_USB_SERIAL_NAVMAN is not set
CONFIG_USB_SERIAL_PL2303=m
# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QUALCOMM 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_SIEMENS_MPI is not set
# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL 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_OPTICON is not set
# CONFIG_USB_SERIAL_DEBUG is not set
#
@@ -1130,7 +1161,6 @@ CONFIG_USB_EMI26=m
# 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
@@ -1143,6 +1173,11 @@ CONFIG_USB_SISUSBVGA_CON=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1151,6 +1186,7 @@ CONFIG_USB_SISUSBVGA_CON=y
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1176,6 +1212,7 @@ CONFIG_REISERFS_FS=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1226,6 +1263,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1250,7 +1288,6 @@ CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1331,7 +1368,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -1424,6 +1460,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1445,7 +1482,7 @@ CONFIG_CRC_T10DIF=y
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
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig
index d5c5a1dbaa6..92c515c4199 100644
--- a/arch/sh/configs/lboxre2_defconfig
+++ b/arch/sh/configs/lboxre2_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:02:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:06:51 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,10 +43,19 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -53,6 +63,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -62,10 +73,8 @@ 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
@@ -74,6 +83,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -113,11 +123,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -152,6 +157,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -193,11 +199,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -291,6 +298,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
CONFIG_PCCARD=y
CONFIG_PCMCIA_DEBUG=y
CONFIG_PCMCIA=y
@@ -329,7 +338,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -408,6 +416,7 @@ CONFIG_NETFILTER_ADVANCED=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -420,13 +429,13 @@ CONFIG_NETFILTER_ADVANCED=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -465,12 +474,16 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -526,6 +539,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -549,6 +563,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -624,6 +639,7 @@ CONFIG_PATA_PLATFORM=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -641,8 +657,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -697,6 +715,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -715,6 +734,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -722,7 +742,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
CONFIG_NET_PCMCIA=y
# CONFIG_PCMCIA_3C589 is not set
# CONFIG_PCMCIA_3C574 is not set
@@ -810,6 +833,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -921,9 +945,13 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -968,6 +996,7 @@ CONFIG_RTC_INTF_DEV=y
#
# CONFIG_RTC_DRV_SH is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -990,6 +1019,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1036,6 +1066,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1124,7 +1155,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -1217,6 +1247,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1238,7 +1269,7 @@ CONFIG_CRC_T10DIF=y
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
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig
index 125d8019dc2..26586c2d64c 100644
--- a/arch/sh/configs/magicpanelr2_defconfig
+++ b/arch/sh/configs/magicpanelr2_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:03:37 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:07:39 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -43,33 +44,44 @@ CONFIG_BSD_PROCESS_ACCT_V3=y
# CONFIG_TASKSTATS is not set
CONFIG_AUDIT=y
# CONFIG_AUDITSYSCALL is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=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
@@ -77,6 +89,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -116,11 +129,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -155,6 +163,7 @@ CONFIG_CPU_SUBTYPE_SH7720=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +205,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -309,7 +319,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -359,6 +368,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -371,13 +381,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -402,6 +412,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -452,9 +463,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0000000
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -475,6 +484,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -491,9 +505,13 @@ CONFIG_BLK_DEV_RAM_SIZE=65536
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -507,6 +525,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -538,8 +557,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -556,7 +577,10 @@ CONFIG_SMSC911X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -778,6 +802,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -797,6 +822,7 @@ CONFIG_JBD=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -849,6 +875,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -868,7 +895,6 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -970,6 +996,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -984,7 +1011,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1025,7 +1051,8 @@ CONFIG_CRC32=y
CONFIG_AUDIT_GENERIC=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig
index 5a1c0485a35..75178355d69 100644
--- a/arch/sh/configs/microdev_defconfig
+++ b/arch/sh/configs/microdev_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:06:47 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:11:13 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,18 +43,32 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +78,8 @@ 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
@@ -74,6 +87,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -107,11 +121,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -146,6 +155,7 @@ CONFIG_CPU_SUBTYPE_SH4_202=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -193,11 +203,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -239,7 +250,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
#
@@ -304,7 +315,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_PACKET is not set
# CONFIG_UNIX is not set
CONFIG_XFRM=y
@@ -358,6 +368,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -370,13 +381,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -407,9 +418,13 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
@@ -443,6 +458,7 @@ CONFIG_IDE_PROC_FS=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -455,8 +471,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -473,7 +491,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -520,6 +541,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -601,15 +623,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -632,6 +659,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -678,6 +706,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -698,7 +727,6 @@ CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -778,7 +806,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -806,10 +833,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
@@ -877,6 +906,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -897,7 +927,9 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig
index 678576796bd..a8720f9c604 100644
--- a/arch/sh/configs/migor_defconfig
+++ b/arch/sh/configs/migor_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc1
-# Thu Jan 22 09:16:16 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:14:03 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,15 +16,17 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,14 +44,19 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_GROUP_SCHED is not set
-
-#
-# Control Group support
-#
# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -57,8 +64,13 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -68,10 +80,8 @@ 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
@@ -79,6 +89,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -120,11 +131,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -134,6 +140,7 @@ CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
CONFIG_CPU_SH4AL_DSP=y
CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -162,6 +169,7 @@ CONFIG_CPU_SHX2=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
CONFIG_CPU_SUBTYPE_SH7722=y
@@ -209,11 +217,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -243,6 +252,7 @@ CONFIG_SH_MIGOR_QVGA=y
# Timer and clock configuration
#
CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
CONFIG_SH_TIMER_IRQ=16
CONFIG_SH_PCLK_FREQ=33333333
# CONFIG_NO_HZ is not set
@@ -318,7 +328,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -373,6 +382,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -380,12 +390,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -495,7 +505,6 @@ CONFIG_MTD_NAND_PLATFORM=y
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
#
# UBI - Unsorted block images
@@ -514,10 +523,17 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -563,9 +579,11 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -578,8 +596,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -596,7 +616,6 @@ CONFIG_SMC91X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -679,6 +698,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -715,12 +735,9 @@ CONFIG_I2C_SH_MOBILE=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -797,7 +814,7 @@ CONFIG_VIDEO_MEDIA=y
#
# CONFIG_MEDIA_ATTACH is not set
CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
CONFIG_MEDIA_TUNER_SIMPLE=y
CONFIG_MEDIA_TUNER_TDA8290=y
CONFIG_MEDIA_TUNER_TDA9887=y
@@ -806,6 +823,7 @@ CONFIG_MEDIA_TUNER_TEA5767=y
CONFIG_MEDIA_TUNER_MT20XX=y
CONFIG_MEDIA_TUNER_XC2028=y
CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
CONFIG_VIDEO_V4L2=y
CONFIG_VIDEOBUF_GEN=y
CONFIG_VIDEOBUF_DMA_CONTIG=y
@@ -866,7 +884,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_USB_GADGET_MUSB_HDRC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
CONFIG_USB_GADGET=y
# CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -905,6 +923,7 @@ CONFIG_USB_G_SERIAL=y
# OTG and related infrastructure
#
# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -964,6 +983,7 @@ CONFIG_RTC_DRV_RS5C372=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=y
# CONFIG_UIO_PDRV is not set
CONFIG_UIO_PDRV_GENIRQ=y
@@ -1045,7 +1065,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1090,7 +1109,7 @@ CONFIG_TRACING=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1117,10 +1136,12 @@ CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1189,6 +1210,7 @@ CONFIG_CRYPTO_MANAGER2=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1209,7 +1231,9 @@ CONFIG_CRC_T10DIF=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/polaris_defconfig b/arch/sh/configs/polaris_defconfig
index 320def233b2..df2d177d534 100644
--- a/arch/sh/configs/polaris_defconfig
+++ b/arch/sh/configs/polaris_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc4
-# Wed Feb 11 18:41:59 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:16:48 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -68,6 +69,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -78,10 +80,8 @@ 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
@@ -89,6 +89,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -162,6 +163,7 @@ CONFIG_CPU_SUBTYPE_SH7709=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -203,11 +205,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -251,7 +254,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
#
@@ -314,7 +317,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -362,6 +364,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -374,7 +377,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
# CONFIG_WIRELESS is not set
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
@@ -481,7 +483,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
#
# UBI - Unsorted block images
@@ -517,6 +518,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -548,8 +550,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -566,7 +570,6 @@ CONFIG_SMSC911X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -750,6 +753,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -837,7 +841,6 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -907,6 +910,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -922,7 +926,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -963,7 +966,7 @@ CONFIG_CRC32=y
CONFIG_AUDIT_GENERIC=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig
index 65b01a9e593..7def4df46dd 100644
--- a/arch/sh/configs/r7780mp_defconfig
+++ b/arch/sh/configs/r7780mp_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:10:19 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:20:17 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_IO_TRAPPED=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -45,15 +46,24 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# 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_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -61,6 +71,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -71,10 +82,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -83,6 +92,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -124,11 +134,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -164,6 +169,7 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
CONFIG_CPU_SUBTYPE_SH7780=y
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -179,8 +185,11 @@ CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
# CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
CONFIG_VSYSCALL=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -212,11 +221,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -309,6 +319,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
@@ -330,7 +342,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -392,6 +403,7 @@ CONFIG_LLC=m
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -399,12 +411,12 @@ CONFIG_LLC=m
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -412,6 +424,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -451,13 +464,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-CONFIG_EEPROM_93CX6=y
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+CONFIG_EEPROM_93CX6=y
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -513,6 +533,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -535,6 +556,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -609,6 +631,7 @@ CONFIG_PATA_PLATFORM=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -627,8 +650,10 @@ CONFIG_AX88796_93CX6=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -684,6 +709,7 @@ CONFIG_R8169=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -702,6 +728,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -709,7 +736,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -796,6 +826,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -857,12 +888,9 @@ CONFIG_I2C_HIGHLANDER=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -885,6 +913,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -905,10 +934,14 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
@@ -949,6 +982,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -1007,9 +1041,13 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1071,6 +1109,7 @@ CONFIG_RTC_DRV_RS5C372=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1094,6 +1133,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1142,6 +1182,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1166,7 +1207,6 @@ CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1269,6 +1309,7 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1288,7 +1329,7 @@ CONFIG_TRACING=y
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1325,10 +1366,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1397,6 +1440,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1421,3 +1465,4 @@ CONFIG_CRC32=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig
index 8defaa5f13b..cb134ffc211 100644
--- a/arch/sh/configs/r7785rp_defconfig
+++ b/arch/sh/configs/r7785rp_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:14:41 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:24:35 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_NUMA=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
@@ -26,6 +26,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_IO_TRAPPED=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -48,11 +49,21 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
CONFIG_AUDIT_TREE=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_PREEMPT_RCU_TRACE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -60,21 +71,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=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
@@ -83,6 +92,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -126,12 +136,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_CLASSIC_RCU is not set
-# CONFIG_TREE_RCU is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_RCU_TRACE=y
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_PREEMPT_RCU_TRACE=y
# CONFIG_FREEZER is not set
#
@@ -168,6 +172,7 @@ CONFIG_CPU_SHX2=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
CONFIG_CPU_SUBTYPE_SH7785=y
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -183,8 +188,11 @@ CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
# CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
# CONFIG_X2TLB is not set
CONFIG_VSYSCALL=y
# CONFIG_NUMA is not set
@@ -222,11 +230,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -334,6 +343,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
@@ -355,7 +366,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -417,6 +427,7 @@ CONFIG_LLC=m
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -425,12 +436,12 @@ CONFIG_LLC=m
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -438,6 +449,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -477,13 +489,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-CONFIG_EEPROM_93CX6=y
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+CONFIG_EEPROM_93CX6=y
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -539,6 +558,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -561,6 +581,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -635,6 +656,7 @@ CONFIG_PATA_PLATFORM=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -653,8 +675,10 @@ CONFIG_AX88796_93CX6=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -687,6 +711,7 @@ CONFIG_R8169=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -705,6 +730,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -712,7 +738,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -800,6 +829,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -862,12 +892,9 @@ CONFIG_I2C_HIGHLANDER=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -914,6 +941,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -934,10 +962,14 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
@@ -979,6 +1011,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -1055,6 +1088,7 @@ CONFIG_FB_SH_MOBILE_LCDC=m
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -1089,9 +1123,13 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1153,6 +1191,7 @@ CONFIG_RTC_DRV_RS5C372=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1176,6 +1215,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1224,6 +1264,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1248,7 +1289,6 @@ CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1354,6 +1394,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1373,7 +1414,7 @@ CONFIG_TRACING=y
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1410,10 +1451,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1482,6 +1525,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1504,7 +1548,7 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_AUDIT_GENERIC=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/rsk7201_defconfig b/arch/sh/configs/rsk7201_defconfig
index 64ee69eef47..a037c744b79 100644
--- a/arch/sh/configs/rsk7201_defconfig
+++ b/arch/sh/configs/rsk7201_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:19:04 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:29:08 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -24,6 +24,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -38,11 +39,20 @@ CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
# CONFIG_IKCONFIG_PROC is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
CONFIG_NAMESPACES=y
@@ -52,8 +62,13 @@ CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -63,16 +78,15 @@ 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_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
# CONFIG_SLUB is not set
CONFIG_SLOB=y
@@ -112,11 +126,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -152,6 +161,7 @@ CONFIG_CPU_SUBTYPE_SH7201=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -190,11 +200,11 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -217,7 +227,6 @@ CONFIG_SH_RSK7201=y
#
# Timer and clock configuration
#
-# CONFIG_SH_CMT is not set
CONFIG_SH_MTU2=y
CONFIG_SH_TIMER_IRQ=16
CONFIG_SH_PCLK_FREQ=40000000
@@ -251,7 +260,6 @@ CONFIG_SH_CLK_MD=0
CONFIG_HZ_1000=y
CONFIG_HZ=1000
# CONFIG_SCHED_HRTICK is not set
-# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
# CONFIG_SECCOMP is not set
CONFIG_PREEMPT_NONE=y
@@ -308,6 +316,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -358,9 +367,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -381,6 +388,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -392,9 +404,13 @@ CONFIG_BLK_DEV=y
# 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_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -562,6 +578,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -577,6 +594,7 @@ CONFIG_EXT2_FS=y
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_FILE_LOCKING is not set
# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -626,6 +644,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -671,7 +690,7 @@ CONFIG_TRACING=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -701,7 +720,7 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/rsk7203_defconfig b/arch/sh/configs/rsk7203_defconfig
index 8d7a5972a86..9ae28e88426 100644
--- a/arch/sh/configs/rsk7203_defconfig
+++ b/arch/sh/configs/rsk7203_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:20:31 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:30:34 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -18,12 +18,14 @@ CONFIG_GENERIC_GPIO=y
# CONFIG_GENERIC_CLOCKEVENTS is not set
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,11 +43,20 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
# CONFIG_IKCONFIG_PROC is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
CONFIG_NAMESPACES=y
@@ -53,31 +64,35 @@ CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
+# CONFIG_NET_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=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_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
# CONFIG_SLUB is not set
CONFIG_SLOB=y
@@ -117,11 +132,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -157,6 +167,7 @@ CONFIG_CPU_SUBTYPE_SH7203=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -195,11 +206,11 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -271,7 +282,6 @@ CONFIG_HEARTBEAT=y
CONFIG_HZ_1000=y
CONFIG_HZ=1000
# CONFIG_SCHED_HRTICK is not set
-# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
# CONFIG_SECCOMP is not set
CONFIG_PREEMPT_NONE=y
@@ -315,8 +325,6 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_PACKET is not set
# CONFIG_UNIX is not set
# CONFIG_NET_KEY is not set
@@ -364,6 +372,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -371,18 +380,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -405,6 +415,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -455,9 +466,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -478,6 +487,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -492,9 +506,13 @@ CONFIG_BLK_DEV=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -508,6 +526,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -539,8 +558,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -557,7 +578,10 @@ CONFIG_SMSC911X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -777,7 +801,9 @@ CONFIG_USB_MON=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_SL811_HCD is not set
CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_HWA_HCD is not set
@@ -791,11 +817,11 @@ CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
# CONFIG_USB_LIBUSUAL is not set
@@ -823,7 +849,6 @@ CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -834,6 +859,12 @@ CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
CONFIG_NEW_LEDS=y
@@ -852,6 +883,10 @@ CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
# CONFIG_ACCESSIBILITY is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
@@ -891,6 +926,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -906,6 +942,7 @@ CONFIG_RTC_DRV_SH=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -945,6 +982,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -962,7 +1000,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1018,6 +1055,7 @@ CONFIG_STACKTRACE=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
CONFIG_DEBUG_WRITECOUNT=y
# CONFIG_DEBUG_MEMORY_INIT is not set
CONFIG_DEBUG_LIST=y
@@ -1031,6 +1069,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1048,7 +1087,7 @@ CONFIG_TRACING=y
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1086,7 +1125,8 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig
index d6680f4382c..c0f741af6da 100644
--- a/arch/sh/configs/rts7751r2d1_defconfig
+++ b/arch/sh/configs/rts7751r2d1_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:23:15 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:33:25 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_IO_TRAPPED=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -43,10 +44,19 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -54,6 +64,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +74,8 @@ 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
@@ -75,6 +84,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -116,11 +126,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -155,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +202,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -300,6 +307,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
CONFIG_HOTPLUG_PCI=y
# CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -324,7 +333,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -376,6 +384,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -383,12 +392,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -396,6 +405,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -434,12 +444,17 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -495,6 +510,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -517,6 +533,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -591,6 +608,7 @@ CONFIG_PATA_PLATFORM=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -609,8 +627,10 @@ CONFIG_MII=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -665,6 +685,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -683,6 +704,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -690,7 +712,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -780,6 +805,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -798,7 +824,6 @@ CONFIG_SPI_SH_SCI=y
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_W1 is not set
@@ -822,6 +847,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
@@ -918,6 +944,7 @@ CONFIG_FB_SM501=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -996,6 +1023,8 @@ CONFIG_SND_PCI=y
# CONFIG_SND_INDIGO is not set
# CONFIG_SND_INDIGOIO is not set
# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
@@ -1101,6 +1130,7 @@ CONFIG_USB_DEVICE_CLASS=y
#
# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
@@ -1122,18 +1152,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1169,7 +1198,6 @@ CONFIG_USB_LIBUSUAL=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1179,6 +1207,11 @@ CONFIG_USB_LIBUSUAL=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1230,6 +1263,7 @@ CONFIG_RTC_DRV_R9701=y
#
# CONFIG_RTC_DRV_SH is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1247,6 +1281,7 @@ CONFIG_EXT2_FS=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1293,6 +1328,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1385,7 +1421,7 @@ CONFIG_TRACING=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1479,6 +1515,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1500,7 +1537,7 @@ CONFIG_CRC_T10DIF=y
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
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig
index 3fca10e2483..8feef629e49 100644
--- a/arch/sh/configs/rts7751r2dplus_defconfig
+++ b/arch/sh/configs/rts7751r2dplus_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:26:10 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:34:12 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_IO_TRAPPED=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -43,10 +44,19 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -54,6 +64,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +74,8 @@ 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
@@ -75,6 +84,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -116,11 +126,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -155,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +202,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -300,6 +307,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
CONFIG_HOTPLUG_PCI=y
# CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -324,7 +333,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -376,6 +384,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -383,12 +392,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -396,6 +405,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -434,12 +444,17 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -495,6 +510,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -517,6 +533,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -591,6 +608,7 @@ CONFIG_PATA_PLATFORM=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -609,8 +627,10 @@ CONFIG_MII=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -665,6 +685,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -683,6 +704,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -690,7 +712,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -780,6 +805,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -798,7 +824,6 @@ CONFIG_SPI_SH_SCI=y
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_W1 is not set
@@ -822,6 +847,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
@@ -918,6 +944,7 @@ CONFIG_FB_SM501=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -996,6 +1023,8 @@ CONFIG_SND_PCI=y
# CONFIG_SND_INDIGO is not set
# CONFIG_SND_INDIGOIO is not set
# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
@@ -1101,6 +1130,7 @@ CONFIG_USB_DEVICE_CLASS=y
#
# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
@@ -1122,18 +1152,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1169,7 +1198,6 @@ CONFIG_USB_LIBUSUAL=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1179,6 +1207,11 @@ CONFIG_USB_LIBUSUAL=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1230,6 +1263,7 @@ CONFIG_RTC_DRV_R9701=y
#
# CONFIG_RTC_DRV_SH is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1247,6 +1281,7 @@ CONFIG_EXT2_FS=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1293,6 +1328,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1385,7 +1421,7 @@ CONFIG_TRACING=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1479,6 +1515,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1500,7 +1537,7 @@ CONFIG_CRC_T10DIF=y
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
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig
index 5d6b06755ae..739e2299ae8 100644
--- a/arch/sh/configs/sdk7780_defconfig
+++ b/arch/sh/configs/sdk7780_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:26:40 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:34:43 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -44,11 +45,20 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=18
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
@@ -56,21 +66,19 @@ CONFIG_RELAY=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=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
@@ -80,6 +88,7 @@ CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
@@ -119,11 +128,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -159,6 +163,7 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
CONFIG_CPU_SUBTYPE_SH7780=y
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -174,8 +179,11 @@ CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
# CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
CONFIG_VSYSCALL=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -207,11 +215,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -257,6 +266,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
+CONFIG_SH_DMA_IRQ_MULTI=y
CONFIG_NR_ONCHIP_DMA_CHANNELS=12
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
@@ -306,6 +316,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCI_LEGACY is not set
CONFIG_PCI_DEBUG=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
CONFIG_PCCARD=y
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=y
@@ -348,7 +360,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -427,6 +438,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
CONFIG_NET_SCHED=y
#
@@ -471,13 +483,13 @@ CONFIG_NET_SCH_FIFO=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -631,6 +643,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -654,6 +667,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -739,6 +753,7 @@ CONFIG_BLK_DEV_DM=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -756,8 +771,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -780,7 +797,10 @@ CONFIG_SMC91X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -840,7 +860,6 @@ 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_ELANTECH is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
@@ -899,6 +918,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_PPDEV is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -1023,6 +1043,7 @@ CONFIG_FB_SH_MOBILE_LCDC=m
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -1123,6 +1144,7 @@ CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
@@ -1141,18 +1163,17 @@ CONFIG_USB_PRINTER=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1189,7 +1210,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1201,6 +1221,11 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1243,7 +1268,9 @@ CONFIG_FS_MBCACHE=y
CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1295,6 +1322,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1318,7 +1346,6 @@ CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1424,6 +1451,7 @@ CONFIG_DEBUG_INFO=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1439,7 +1467,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1544,6 +1571,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1565,7 +1593,7 @@ CONFIG_CRC_T10DIF=y
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
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig
index e5b55b6f002..d30e0a7ad9f 100644
--- a/arch/sh/configs/se7206_defconfig
+++ b/arch/sh/configs/se7206_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:31:27 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:39:37 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -18,12 +18,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
# CONFIG_GENERIC_CLOCKEVENTS is not set
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -43,18 +45,28 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_TASKSTATS is not set
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_PREEMPT_RCU_TRACE=y
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
CONFIG_CGROUPS=y
CONFIG_CGROUP_DEBUG=y
CONFIG_CGROUP_NS=y
# CONFIG_CGROUP_FREEZER is not set
CONFIG_CGROUP_DEVICE=y
-# CONFIG_GROUP_SCHED is not set
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_MM_OWNER=y
CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_MM_OWNER=y
# CONFIG_SYSFS_DEPRECATED_V2 is not set
CONFIG_RELAY=y
CONFIG_NAMESPACES=y
@@ -62,31 +74,35 @@ CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
+# CONFIG_NET_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
# 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_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
# CONFIG_SLAB is not set
# CONFIG_SLUB is not set
CONFIG_SLOB=y
@@ -127,12 +143,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_CLASSIC_RCU is not set
-# CONFIG_TREE_RCU is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_RCU_TRACE=y
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_PREEMPT_RCU_TRACE=y
# CONFIG_FREEZER is not set
#
@@ -168,6 +178,7 @@ CONFIG_CPU_SUBTYPE_SH7206=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -206,11 +217,11 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -280,7 +291,6 @@ CONFIG_HEARTBEAT=y
CONFIG_HZ_1000=y
CONFIG_HZ=1000
# CONFIG_SCHED_HRTICK is not set
-CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
# CONFIG_SECCOMP is not set
# CONFIG_PREEMPT_NONE is not set
@@ -322,8 +332,6 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -378,6 +386,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -385,18 +394,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -419,6 +429,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -466,9 +477,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x20000000
-CONFIG_MTD_PHYSMAP_LEN=0x01000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -489,6 +498,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -506,9 +520,13 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-CONFIG_EEPROM_93CX6=y
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_93CX6=y
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -522,6 +540,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -534,8 +553,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -552,7 +573,10 @@ CONFIG_SMC91X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -696,6 +720,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -712,6 +737,7 @@ CONFIG_EXT2_FS=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -752,6 +778,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -771,7 +798,6 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -824,6 +850,7 @@ CONFIG_STACKTRACE=y
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
# CONFIG_DEBUG_WRITECOUNT is not set
# CONFIG_DEBUG_MEMORY_INIT is not set
CONFIG_DEBUG_LIST=y
@@ -835,6 +862,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -852,7 +880,7 @@ CONFIG_TRACING=y
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -955,6 +983,7 @@ CONFIG_CRYPTO_CRC32C=y
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
CONFIG_CRYPTO_LZO=y
#
@@ -980,7 +1009,8 @@ CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig
index 39005257703..fbb72d029e6 100644
--- a/arch/sh/configs/se7343_defconfig
+++ b/arch/sh/configs/se7343_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:33:53 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:42:00 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,14 +16,16 @@ CONFIG_GENERIC_IRQ_PROBE=y
# CONFIG_GENERIC_GPIO is not set
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,14 +43,23 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_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_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -56,6 +67,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -65,10 +77,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -76,6 +86,7 @@ CONFIG_EVENTFD=y
# CONFIG_SHMEM is not set
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -114,11 +125,6 @@ CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="deadline"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -127,6 +133,7 @@ CONFIG_CLASSIC_RCU=y
CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
CONFIG_CPU_SH4AL_DSP=y
+CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -155,6 +162,7 @@ CONFIG_CPU_SH4AL_DSP=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
CONFIG_CPU_SUBTYPE_SH7343=y
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +204,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -227,6 +236,7 @@ CONFIG_SH_7343_SOLUTION_ENGINE=y
# Timer and clock configuration
#
CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
CONFIG_SH_TIMER_IRQ=16
CONFIG_SH_PCLK_FREQ=33333333
# CONFIG_NO_HZ is not set
@@ -302,7 +312,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -353,6 +362,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -365,13 +375,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -394,6 +404,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -441,9 +452,7 @@ CONFIG_MTD_RAM=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -464,6 +473,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -520,9 +534,11 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -539,7 +555,10 @@ CONFIG_MII=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -633,6 +652,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -669,12 +689,9 @@ CONFIG_I2C_SH_MOBILE=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -706,6 +723,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -727,7 +745,7 @@ CONFIG_VIDEO_MEDIA=y
#
# CONFIG_MEDIA_ATTACH is not set
CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
CONFIG_MEDIA_TUNER_SIMPLE=y
CONFIG_MEDIA_TUNER_TDA8290=y
CONFIG_MEDIA_TUNER_TDA9887=y
@@ -736,6 +754,7 @@ CONFIG_MEDIA_TUNER_TEA5767=y
CONFIG_MEDIA_TUNER_MT20XX=y
CONFIG_MEDIA_TUNER_XC2028=y
CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
CONFIG_VIDEO_V4L2=y
CONFIG_VIDEO_V4L1=y
CONFIG_VIDEO_CAPTURE_DRIVERS=y
@@ -757,6 +776,7 @@ CONFIG_USB_GSPCA=m
# CONFIG_USB_GSPCA_ETOMS is not set
# CONFIG_USB_GSPCA_FINEPIX is not set
# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_MR97310A is not set
# CONFIG_USB_GSPCA_OV519 is not set
# CONFIG_USB_GSPCA_OV534 is not set
# CONFIG_USB_GSPCA_PAC207 is not set
@@ -769,6 +789,8 @@ CONFIG_USB_GSPCA=m
# CONFIG_USB_GSPCA_SPCA506 is not set
# CONFIG_USB_GSPCA_SPCA508 is not set
# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_SQ905 is not set
+# CONFIG_USB_GSPCA_SQ905C is not set
# CONFIG_USB_GSPCA_STK014 is not set
# CONFIG_USB_GSPCA_SUNPLUS is not set
# CONFIG_USB_GSPCA_T613 is not set
@@ -776,6 +798,7 @@ CONFIG_USB_GSPCA=m
# CONFIG_USB_GSPCA_VC032X is not set
# CONFIG_USB_GSPCA_ZC3XX is not set
# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_HDPVR is not set
# CONFIG_VIDEO_EM28XX is not set
# CONFIG_VIDEO_USBVISION is not set
# CONFIG_USB_VICAM is not set
@@ -833,6 +856,7 @@ CONFIG_FB_SH_MOBILE_LCDC=m
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -940,7 +964,9 @@ CONFIG_USB_DEVICE_CLASS=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
CONFIG_USB_ISP116X_HCD=y
+# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_HWA_HCD is not set
@@ -954,11 +980,11 @@ CONFIG_USB_ISP116X_HCD=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
# CONFIG_USB_STORAGE is not set
# CONFIG_USB_LIBUSUAL is not set
@@ -988,7 +1014,6 @@ CONFIG_USB_ISP116X_HCD=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -999,12 +1024,18 @@ CONFIG_USB_ISP116X_HCD=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_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_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=y
# CONFIG_UIO_PDRV is not set
# CONFIG_UIO_PDRV_GENIRQ is not set
@@ -1031,6 +1062,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -1084,6 +1116,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1105,7 +1138,6 @@ CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1146,7 +1178,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1240,6 +1271,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1265,3 +1297,4 @@ CONFIG_ZLIB_DEFLATE=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig
index 932b0235b1d..125304e80f5 100644
--- a/arch/sh/configs/se7619_defconfig
+++ b/arch/sh/configs/se7619_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:36:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:44:53 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -18,12 +18,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
# CONFIG_GENERIC_CLOCKEVENTS is not set
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -36,15 +38,25 @@ CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
# CONFIG_SYSCTL_SYSCALL is not set
@@ -53,16 +65,15 @@ CONFIG_EMBEDDED=y
CONFIG_PRINTK=y
CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
-CONFIG_COMPAT_BRK=y
# CONFIG_BASE_FULL is not set
# CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_AIO=y
# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -93,11 +104,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -132,6 +138,7 @@ CONFIG_CPU_SUBTYPE_SH7619=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -170,11 +177,11 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_CACHE_WRITEBACK is not set
CONFIG_CACHE_WRITETHROUGH=y
# CONFIG_CACHE_OFF is not set
@@ -228,7 +235,6 @@ CONFIG_HZ_100=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
# CONFIG_SCHED_HRTICK is not set
-# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
# CONFIG_SECCOMP is not set
CONFIG_PREEMPT_NONE=y
@@ -329,9 +335,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xa0000000
-CONFIG_MTD_PHYSMAP_LEN=0x01000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_SOLUTIONENGINE is not set
# CONFIG_MTD_PLATRAM is not set
@@ -353,6 +357,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -364,9 +373,13 @@ CONFIG_BLK_DEV=y
# 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_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -514,15 +527,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -537,6 +555,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -575,6 +594,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -614,7 +634,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig
index 8574d6eb00a..0308abf5238 100644
--- a/arch/sh/configs/se7705_defconfig
+++ b/arch/sh/configs/se7705_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:37:50 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:45:56 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,16 +42,30 @@ CONFIG_LOCALVERSION_AUTO=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -59,10 +74,8 @@ CONFIG_UID16=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -70,6 +83,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -106,11 +120,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -145,6 +154,7 @@ CONFIG_CPU_SUBTYPE_SH7705=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -186,12 +196,13 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
CONFIG_SH7705_CACHE_32KB=y
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -292,7 +303,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -347,6 +357,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -359,13 +370,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -384,6 +395,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -451,6 +463,11 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -467,9 +484,13 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -483,6 +504,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -495,8 +517,10 @@ CONFIG_NET_ETHERNET=y
# CONFIG_AX88796 is not set
CONFIG_STNIC=y
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -513,7 +537,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
CONFIG_PPP=y
# CONFIG_PPP_MULTILINK is not set
@@ -593,6 +620,7 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -684,15 +712,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -709,6 +742,7 @@ CONFIG_EXT2_FS=y
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -761,6 +795,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -778,7 +813,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -817,7 +851,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -908,6 +941,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -930,7 +964,8 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig
index e31ea84f116..a8c24b70348 100644
--- a/arch/sh/configs/se7712_defconfig
+++ b/arch/sh/configs/se7712_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:40:12 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:48:18 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,10 +42,19 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -52,21 +62,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
# CONFIG_BUG is not set
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
# CONFIG_BASE_FULL is not set
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -74,6 +82,7 @@ CONFIG_EVENTFD=y
# CONFIG_SHMEM is not set
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -112,11 +121,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -151,6 +155,7 @@ CONFIG_CPU_SUBTYPE_SH7712=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +197,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -300,7 +306,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -364,6 +369,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
CONFIG_NET_SCHED=y
#
@@ -411,7 +417,6 @@ CONFIG_NET_SCH_FIFO=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
@@ -419,6 +424,7 @@ CONFIG_WIRELESS=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -443,6 +449,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -510,6 +517,11 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -523,9 +535,13 @@ CONFIG_BLK_DEV=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -571,6 +587,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -579,6 +596,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_PLATFORM=y
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -611,8 +629,10 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
CONFIG_SH_ETH=y
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -629,7 +649,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -675,6 +698,7 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -744,9 +768,13 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
CONFIG_NEW_LEDS=y
@@ -764,9 +792,14 @@ CONFIG_LEDS_TRIGGERS=y
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -791,6 +824,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -844,6 +878,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -861,7 +896,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -923,6 +957,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -937,7 +972,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -974,10 +1008,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=y
# CONFIG_CRYPTO_TEST is not set
@@ -1046,6 +1082,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1068,7 +1105,7 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7721_defconfig b/arch/sh/configs/se7721_defconfig
index ad1bace3ad4..4b79c2567dc 100644
--- a/arch/sh/configs/se7721_defconfig
+++ b/arch/sh/configs/se7721_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:43:33 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:51:44 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,14 +42,23 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_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_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -56,21 +66,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
# CONFIG_BUG is not set
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
# CONFIG_BASE_FULL is not set
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -78,6 +86,7 @@ CONFIG_EVENTFD=y
# CONFIG_SHMEM is not set
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -116,11 +125,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -155,6 +159,7 @@ CONFIG_CPU_SUBTYPE_SH7721=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +201,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -303,7 +309,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -367,6 +372,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
CONFIG_NET_SCHED=y
#
@@ -414,7 +420,6 @@ CONFIG_NET_SCH_FIFO=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
@@ -422,6 +427,7 @@ CONFIG_WIRELESS=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -446,6 +452,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -513,6 +520,11 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -527,9 +539,13 @@ CONFIG_BLK_DEV=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -572,6 +588,7 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -580,6 +597,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_PLATFORM=y
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -595,7 +613,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -805,7 +826,9 @@ CONFIG_USB_MON=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -823,18 +846,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -870,7 +892,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -880,6 +901,11 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
CONFIG_NEW_LEDS=y
@@ -897,9 +923,14 @@ CONFIG_LEDS_TRIGGERS=y
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -924,6 +955,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -980,6 +1012,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1082,6 +1115,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1096,7 +1130,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1133,10 +1166,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=y
# CONFIG_CRYPTO_TEST is not set
@@ -1205,6 +1240,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1227,7 +1263,7 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig
index abb189a1d31..82bdaac45fb 100644
--- a/arch/sh/configs/se7722_defconfig
+++ b/arch/sh/configs/se7722_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:46:59 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:55:10 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,15 +16,17 @@ CONFIG_GENERIC_IRQ_PROBE=y
# CONFIG_GENERIC_GPIO is not set
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -44,19 +46,33 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -66,10 +82,8 @@ 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
@@ -78,6 +92,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
@@ -118,11 +133,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -132,6 +142,7 @@ CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
CONFIG_CPU_SH4AL_DSP=y
CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -160,6 +171,7 @@ CONFIG_CPU_SHX2=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
CONFIG_CPU_SUBTYPE_SH7722=y
@@ -213,11 +225,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -246,6 +259,7 @@ CONFIG_SH_7722_SOLUTION_ENGINE=y
# Timer and clock configuration
#
CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
CONFIG_SH_TIMER_IRQ=16
CONFIG_SH_PCLK_FREQ=33333333
CONFIG_TICK_ONESHOT=y
@@ -321,7 +335,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -373,6 +386,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -385,13 +399,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -422,9 +436,13 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -470,6 +488,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -478,6 +497,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_PLATFORM=y
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -490,8 +510,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -508,7 +530,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -589,6 +614,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -680,9 +706,13 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -725,6 +755,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -748,6 +779,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -791,6 +823,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -843,7 +876,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -936,6 +969,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -956,7 +990,9 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig
index ac874f63a62..ceef6d9138e 100644
--- a/arch/sh/configs/se7750_defconfig
+++ b/arch/sh/configs/se7750_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:49:22 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:57:31 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,11 +43,20 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -54,6 +64,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +74,8 @@ CONFIG_KALLSYMS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -74,6 +83,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -112,11 +122,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -151,6 +156,7 @@ CONFIG_CPU_SUBTYPE_SH7750=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +198,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -299,7 +306,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -355,6 +361,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -367,13 +374,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -392,6 +399,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -459,6 +467,11 @@ CONFIG_MTD_ROM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -472,9 +485,13 @@ CONFIG_BLK_DEV=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
@@ -538,9 +555,11 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -553,8 +572,10 @@ CONFIG_NET_ETHERNET=y
# CONFIG_AX88796 is not set
CONFIG_STNIC=y
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -571,7 +592,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -622,6 +646,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -711,15 +736,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -735,6 +765,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -789,6 +820,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -806,7 +838,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -859,7 +890,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -951,6 +981,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -973,7 +1004,7 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig
index f54ae056f17..67fc26b3a7d 100644
--- a/arch/sh/configs/se7751_defconfig
+++ b/arch/sh/configs/se7751_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:51:47 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:59:59 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,18 +43,32 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +78,8 @@ CONFIG_KALLSYMS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -74,6 +87,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -112,11 +126,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -151,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7751=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +202,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -301,7 +312,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -376,6 +386,7 @@ CONFIG_IP_NF_QUEUE=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -388,13 +399,13 @@ CONFIG_IP_NF_QUEUE=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -413,6 +424,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -480,6 +492,11 @@ CONFIG_MTD_RAM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -496,9 +513,13 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -512,6 +533,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -524,8 +546,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -542,7 +566,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -585,6 +612,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -673,15 +701,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -699,6 +732,7 @@ CONFIG_EXT2_FS=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -753,6 +787,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -802,7 +837,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -894,6 +928,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -916,7 +951,8 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig
index 7504978e874..ebce23cc2ad 100644
--- a/arch/sh/configs/se7780_defconfig
+++ b/arch/sh/configs/se7780_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:53:50 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:02:05 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,6 +42,15 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -52,6 +62,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -60,10 +71,8 @@ CONFIG_SYSCTL_SYSCALL=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 is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -72,6 +81,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -108,11 +118,6 @@ CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="deadline"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -148,6 +153,7 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
CONFIG_CPU_SUBTYPE_SH7780=y
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +198,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -283,6 +290,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
#
# Executable file formats
@@ -296,7 +305,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -351,6 +359,7 @@ CONFIG_IPV6=y
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -362,13 +371,13 @@ CONFIG_IPV6=y
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
#
@@ -386,6 +395,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -460,6 +470,11 @@ CONFIG_MTD_ROM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -479,10 +494,14 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -536,6 +555,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -557,6 +577,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -565,6 +586,7 @@ CONFIG_SATA_PMP=y
CONFIG_ATA_SFF=y
# CONFIG_SATA_SVW is not set
# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
@@ -619,6 +641,7 @@ CONFIG_SATA_SIL=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
@@ -654,8 +677,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -693,7 +718,10 @@ CONFIG_NET_PCI=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -885,6 +913,7 @@ CONFIG_FB_SH_MOBILE_LCDC=m
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -978,6 +1007,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_C67X00_HCD is not set
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
@@ -996,18 +1026,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1043,7 +1072,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1055,6 +1083,11 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -1062,6 +1095,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1120,6 +1154,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_HFSPLUS_FS is not set
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1214,7 +1249,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1301,6 +1336,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1323,7 +1359,7 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig
index 04bde1e9696..6fcdb090cf3 100644
--- a/arch/sh/configs/sh03_defconfig
+++ b/arch/sh/configs/sh03_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:56:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:04:59 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -44,18 +45,32 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -65,10 +80,8 @@ 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
@@ -77,6 +90,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -119,11 +133,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -158,6 +167,7 @@ CONFIG_CPU_SUBTYPE_SH7751=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -199,11 +209,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -294,6 +305,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
CONFIG_HOTPLUG_PCI=m
# CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -318,7 +331,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -375,6 +387,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -382,18 +395,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -430,12 +444,16 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
@@ -541,6 +559,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -562,6 +581,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_FUSION is not set
@@ -577,6 +597,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -594,8 +615,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -646,6 +669,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -664,6 +688,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -671,7 +696,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -754,6 +782,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -872,9 +901,13 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -883,6 +916,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -908,6 +942,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -957,6 +992,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -981,7 +1017,6 @@ CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1081,7 +1116,7 @@ CONFIG_TRACING=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -1110,10 +1145,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1182,6 +1219,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1205,7 +1243,8 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig
index 1b869f452ad..1ab37c01da6 100644
--- a/arch/sh/configs/sh7710voipgw_defconfig
+++ b/arch/sh/configs/sh7710voipgw_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:00:31 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:09:01 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,14 +42,23 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_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_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -56,6 +66,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -65,10 +76,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -76,6 +85,7 @@ CONFIG_EVENTFD=y
# CONFIG_SHMEM is not set
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -114,11 +124,6 @@ CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="deadline"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -153,6 +158,7 @@ CONFIG_CPU_SUBTYPE_SH7710=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -194,11 +200,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -299,7 +306,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -369,6 +375,7 @@ CONFIG_NETFILTER_ADVANCED=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
CONFIG_NET_SCHED=y
#
@@ -418,13 +425,13 @@ CONFIG_NET_SCH_FIFO=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -447,6 +454,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -514,6 +522,11 @@ CONFIG_MTD_RAM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -527,9 +540,13 @@ CONFIG_BLK_DEV=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -543,6 +560,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -556,8 +574,10 @@ CONFIG_NET_ETHERNET=y
# CONFIG_STNIC is not set
# CONFIG_SH_ETH is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -574,7 +594,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -640,6 +663,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -718,15 +742,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -742,6 +771,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -795,6 +825,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -844,7 +875,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -936,6 +967,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -961,3 +993,4 @@ CONFIG_ZLIB_DEFLATE=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh7763rdp_defconfig b/arch/sh/configs/sh7763rdp_defconfig
index ba33aca75af..c79bb84ec30 100644
--- a/arch/sh/configs/sh7763rdp_defconfig
+++ b/arch/sh/configs/sh7763rdp_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:02:28 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:10:57 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,15 +42,24 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# 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_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -58,9 +68,11 @@ CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -70,10 +82,8 @@ 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
@@ -81,6 +91,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -122,11 +133,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -162,6 +168,7 @@ CONFIG_CPU_SUBTYPE_SH7763=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -207,11 +214,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -231,6 +239,7 @@ CONFIG_CPU_HAS_FPU=y
# Board support
#
CONFIG_SH_SH7763RDP=y
+# CONFIG_SH_ESPT is not set
#
# Timer and clock configuration
@@ -311,8 +320,6 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -367,6 +374,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -374,12 +382,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -387,6 +395,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -409,6 +418,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set
@@ -462,9 +472,7 @@ CONFIG_MTD_CFI_UTIL=y
#
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x8000000
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -485,6 +493,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -544,9 +557,11 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -579,8 +594,10 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
CONFIG_SH_ETH=y
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -597,7 +614,10 @@ CONFIG_SH_ETH=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -677,6 +697,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -756,6 +777,7 @@ CONFIG_FB_SH7760=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -807,7 +829,9 @@ CONFIG_USB_MON=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -825,18 +849,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -872,7 +895,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -882,6 +904,11 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
@@ -903,6 +930,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -926,6 +954,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -974,6 +1003,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -991,7 +1021,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1075,7 +1104,7 @@ CONFIG_TRACING=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1167,6 +1196,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1187,7 +1217,7 @@ CONFIG_CRC_T10DIF=y
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
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig
index 54e1dee8e24..a6cf4505741 100644
--- a/arch/sh/configs/sh7785lcr_32bit_defconfig
+++ b/arch/sh/configs/sh7785lcr_32bit_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc4
-# Fri Feb 20 18:25:29 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:12:18 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_NUMA=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
@@ -26,6 +26,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_IO_TRAPPED=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -71,6 +72,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -81,10 +83,8 @@ 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
@@ -93,6 +93,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -169,6 +170,7 @@ CONFIG_CPU_SHX2=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
CONFIG_CPU_SUBTYPE_SH7785=y
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -220,11 +222,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -314,6 +317,7 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
@@ -335,7 +339,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -395,6 +398,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -407,7 +411,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -512,7 +515,6 @@ CONFIG_MTD_PHYSMAP=y
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
#
# UBI - Unsorted block images
@@ -578,6 +580,7 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -652,6 +655,7 @@ CONFIG_SATA_SIL=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -681,6 +685,7 @@ CONFIG_R8169=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
@@ -690,7 +695,6 @@ CONFIG_R8169=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -789,6 +793,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -854,7 +859,6 @@ CONFIG_I2C_PCA_PLATFORM=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_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -964,6 +968,7 @@ CONFIG_FB_SM501=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -1079,11 +1084,11 @@ CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
@@ -1125,7 +1130,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1141,6 +1145,7 @@ CONFIG_USB_TEST=m
#
# OTG and related infrastructure
#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1202,6 +1207,7 @@ CONFIG_RTC_DRV_RS5C372=y
#
# CONFIG_RTC_DRV_SH is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1299,7 +1305,6 @@ CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1404,6 +1409,7 @@ CONFIG_DEBUG_PREEMPT=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1419,7 +1425,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1455,10 +1460,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1527,6 +1534,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1547,7 +1555,7 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
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
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh7785lcr_defconfig b/arch/sh/configs/sh7785lcr_defconfig
index 1d63628df6f..8a42bbef1f5 100644
--- a/arch/sh/configs/sh7785lcr_defconfig
+++ b/arch/sh/configs/sh7785lcr_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:05:18 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:15:58 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_NUMA=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
@@ -26,6 +26,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_IO_TRAPPED=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -46,15 +47,24 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# 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_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -62,6 +72,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -72,10 +83,8 @@ 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
@@ -84,6 +93,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -124,11 +134,6 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -165,6 +170,7 @@ CONFIG_CPU_SHX2=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
CONFIG_CPU_SUBTYPE_SH7785=y
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -180,8 +186,11 @@ CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
# CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
# CONFIG_X2TLB is not set
CONFIG_VSYSCALL=y
# CONFIG_NUMA is not set
@@ -213,11 +222,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -239,7 +249,6 @@ CONFIG_CPU_HAS_FPU=y
#
# CONFIG_SH_HIGHLANDER is not set
CONFIG_SH_SH7785LCR=y
-CONFIG_SH_SH7785LCR_29BIT_PHYSMAPS=y
#
# Timer and clock configuration
@@ -307,6 +316,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
@@ -328,7 +339,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -388,6 +398,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -400,7 +411,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -408,6 +418,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -430,6 +441,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -477,9 +489,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x00000000
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set
@@ -502,6 +512,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -565,6 +580,7 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -639,6 +655,7 @@ CONFIG_SATA_SIL=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -668,6 +685,7 @@ CONFIG_R8169=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
@@ -677,7 +695,10 @@ CONFIG_R8169=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -772,6 +793,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -834,12 +856,9 @@ CONFIG_I2C_PCA_PLATFORM=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -871,6 +890,7 @@ CONFIG_MFD_SM501=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -948,6 +968,7 @@ CONFIG_FB_SM501=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -1041,6 +1062,7 @@ CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=m
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=m
@@ -1062,18 +1084,17 @@ CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1109,7 +1130,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1121,6 +1141,11 @@ CONFIG_USB_TEST=m
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1182,6 +1207,7 @@ CONFIG_RTC_DRV_RS5C372=y
#
# CONFIG_RTC_DRV_SH is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1204,6 +1230,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1253,6 +1280,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1277,7 +1305,6 @@ CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1382,6 +1409,7 @@ CONFIG_DEBUG_PREEMPT=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1397,7 +1425,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1433,10 +1460,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1505,6 +1534,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1525,7 +1555,7 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
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
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/shmin_defconfig b/arch/sh/configs/shmin_defconfig
index 8ba10e1e08c..d695e906187 100644
--- a/arch/sh/configs/shmin_defconfig
+++ b/arch/sh/configs/shmin_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:09:00 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:19:03 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -39,15 +40,25 @@ CONFIG_LOCALVERSION_AUTO=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
# CONFIG_SYSCTL_SYSCALL is not set
@@ -56,10 +67,8 @@ CONFIG_EMBEDDED=y
CONFIG_PRINTK=y
# CONFIG_BUG is not set
# CONFIG_ELF_CORE is not set
-CONFIG_COMPAT_BRK=y
# CONFIG_BASE_FULL is not set
# CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -67,6 +76,7 @@ CONFIG_EVENTFD=y
# CONFIG_SHMEM is not set
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
# CONFIG_SLUB is not set
CONFIG_SLOB=y
@@ -97,11 +107,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -136,6 +141,7 @@ CONFIG_CPU_SUBTYPE_SH7706=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -177,11 +183,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -267,7 +274,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 root=1f01 mtdparts=phys_mapped_flash:64k(f
# Executable file formats
#
CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
@@ -281,7 +287,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_PACKET is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
@@ -335,6 +340,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -347,13 +353,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -419,9 +425,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xa0000000
-CONFIG_MTD_PHYSMAP_LEN=0x80000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=1
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -442,6 +446,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -456,9 +465,13 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -472,6 +485,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -484,8 +498,10 @@ CONFIG_NET_ETHERNET=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -502,7 +518,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -549,6 +568,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -618,15 +638,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -641,6 +666,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -683,6 +709,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -702,7 +729,6 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -740,7 +766,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -831,6 +856,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -855,3 +881,4 @@ CONFIG_ZLIB_INFLATE=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig
index ed90a7e8109..e3651f57439 100644
--- a/arch/sh/configs/shx3_defconfig
+++ b/arch/sh/configs/shx3_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:10:57 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:20:54 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -19,7 +19,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_LOCKBREAK=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_SMP=y
CONFIG_SYS_SUPPORTS_NUMA=y
CONFIG_STACKTRACE_SUPPORT=y
@@ -27,6 +27,7 @@ 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_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -47,24 +48,35 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
CONFIG_AUDIT_TREE=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_PREEMPT_RCU_TRACE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_NS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
# CONFIG_CPUSETS is not set
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_MM_OWNER=y
CONFIG_CGROUP_MEM_RES_CTLR=y
+# CONFIG_CGROUP_MEM_RES_CTLR_SWAP is not set
+CONFIG_MM_OWNER=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
@@ -73,24 +85,23 @@ CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
+# CONFIG_NET_NS is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=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
@@ -98,6 +109,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
# CONFIG_SLUB is not set
CONFIG_SLOB=y
@@ -142,12 +154,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-# CONFIG_CLASSIC_RCU is not set
-# CONFIG_TREE_RCU is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_RCU_TRACE=y
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_PREEMPT_RCU_TRACE=y
CONFIG_FREEZER=y
#
@@ -184,6 +190,7 @@ CONFIG_CPU_SHX3=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
CONFIG_CPU_SUBTYPE_SHX3=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -240,11 +247,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -361,8 +369,6 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_PACKET is not set
# CONFIG_UNIX is not set
CONFIG_XFRM=y
@@ -434,6 +440,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -442,6 +449,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
CONFIG_CAN=m
CONFIG_CAN_RAW=m
@@ -455,8 +463,8 @@ CONFIG_CAN_VCAN=m
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -490,10 +498,18 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -539,6 +555,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -547,6 +564,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_PLATFORM=y
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -560,8 +578,10 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -578,7 +598,10 @@ CONFIG_SMC91X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -670,12 +693,9 @@ CONFIG_I2C_HELPER_AUTO=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -695,7 +715,6 @@ CONFIG_SPI_MASTER=y
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_W1 is not set
@@ -732,6 +751,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -788,7 +808,9 @@ CONFIG_USB_MON=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_SL811_HCD is not set
CONFIG_USB_R8A66597_HCD=m
# CONFIG_USB_HWA_HCD is not set
@@ -803,11 +825,11 @@ CONFIG_USB_R8A66597_HCD=m
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
# CONFIG_USB_STORAGE is not set
# CONFIG_USB_LIBUSUAL is not set
@@ -837,7 +859,6 @@ CONFIG_USB_R8A66597_HCD=m
# 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
@@ -860,10 +881,12 @@ CONFIG_USB_GADGET_SELECTED=y
# CONFIG_USB_GADGET_PXA25X is not set
# CONFIG_USB_GADGET_PXA27X is not set
# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
CONFIG_USB_GADGET_M66592=y
CONFIG_USB_M66592=y
# CONFIG_USB_GADGET_AMD5536UDC is not set
# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
# CONFIG_USB_GADGET_NET2280 is not set
# CONFIG_USB_GADGET_GOKU is not set
# CONFIG_USB_GADGET_DUMMY_HCD is not set
@@ -876,6 +899,11 @@ CONFIG_USB_GADGET_DUALSPEED=y
# CONFIG_USB_MIDI_GADGET is not set
# CONFIG_USB_G_PRINTER is not set
# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -942,6 +970,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=m
# CONFIG_UIO_PDRV is not set
# CONFIG_UIO_PDRV_GENIRQ is not set
@@ -969,6 +998,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1012,6 +1042,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1086,6 +1117,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1105,7 +1137,7 @@ CONFIG_TRACING=y
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1205,6 +1237,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1226,7 +1259,7 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_AUDIT_GENERIC=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig
index 98377e50265..6960f60bf52 100644
--- a/arch/sh/configs/snapgear_defconfig
+++ b/arch/sh/configs/snapgear_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:14:08 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:21:39 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,18 +42,32 @@ CONFIG_LOCALVERSION_AUTO=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -62,10 +77,8 @@ CONFIG_KALLSYMS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -74,6 +87,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -107,11 +121,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -146,6 +155,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -187,11 +197,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -239,6 +250,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
+CONFIG_SH_DMA_IRQ_MULTI=y
CONFIG_NR_ONCHIP_DMA_CHANNELS=8
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
@@ -288,6 +300,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
#
# Executable file formats
@@ -307,7 +321,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_PACKET is not set
# CONFIG_UNIX is not set
# CONFIG_NET_KEY is not set
@@ -352,6 +365,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -364,13 +378,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -464,6 +478,11 @@ CONFIG_MTD_PLATRAM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -509,6 +528,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -526,8 +546,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -571,7 +593,10 @@ CONFIG_8139TOO_PIO=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -711,6 +736,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -728,6 +754,7 @@ CONFIG_EXT2_FS=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -771,6 +798,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -820,7 +848,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -849,7 +876,8 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig
index 72703bf57af..7ea639bc593 100644
--- a/arch/sh/configs/systemh_defconfig
+++ b/arch/sh/configs/systemh_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:15:56 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:23:31 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -38,18 +39,32 @@ CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -59,10 +74,8 @@ CONFIG_KALLSYMS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -70,6 +83,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -109,11 +123,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -148,6 +157,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -189,11 +199,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -318,9 +329,13 @@ CONFIG_BLK_DEV_RAM_SIZE=1024
# 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_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -372,6 +387,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -452,15 +468,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -475,6 +496,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -518,6 +540,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -558,7 +581,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -587,7 +609,7 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
index 01fc1defb33..bbeb4c6ebb9 100644
--- a/arch/sh/configs/titan_defconfig
+++ b/arch/sh/configs/titan_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:17:19 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:24:55 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,19 +43,33 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -65,10 +80,8 @@ 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
@@ -77,6 +90,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -116,11 +130,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -155,6 +164,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +206,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -248,6 +259,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
+CONFIG_SH_DMA_IRQ_MULTI=y
CONFIG_NR_ONCHIP_DMA_CHANNELS=8
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
@@ -299,6 +311,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
CONFIG_HOTPLUG_PCI=y
# CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -323,7 +337,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -406,6 +419,7 @@ CONFIG_NETFILTER_NETLINK_LOG=m
CONFIG_NETFILTER_XTABLES=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_HL=m
CONFIG_NETFILTER_XT_TARGET_MARK=m
# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -418,6 +432,7 @@ CONFIG_NETFILTER_XT_MATCH_DCCP=m
# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
CONFIG_NETFILTER_XT_MATCH_ESP=m
# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+CONFIG_NETFILTER_XT_MATCH_HL=m
# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
@@ -475,11 +490,11 @@ CONFIG_IP6_NF_MATCH_HL=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
# CONFIG_IP6_NF_MATCH_MH is not set
CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
# CONFIG_BRIDGE_NF_EBTABLES is not set
# CONFIG_IP_DCCP is not set
@@ -500,6 +515,7 @@ CONFIG_LLC=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
CONFIG_NET_SCHED=y
#
@@ -565,7 +581,6 @@ CONFIG_NET_SCH_FIFO=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
@@ -574,6 +589,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -599,6 +615,7 @@ CONFIG_MTD_DEBUG=y
CONFIG_MTD_DEBUG_VERBOSE=0
# CONFIG_MTD_CONCAT is not set
# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_TESTS is not set
#
# User Modules And Translation Layers
@@ -675,6 +692,11 @@ CONFIG_MTD_NAND_IDS=m
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -698,12 +720,16 @@ CONFIG_ATA_OVER_ETH=m
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -760,6 +786,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -781,6 +808,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_FUSION is not set
@@ -796,6 +824,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_IFB is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -832,8 +861,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -888,6 +919,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -906,6 +938,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -913,7 +946,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -1025,6 +1061,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -1174,6 +1211,7 @@ CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
@@ -1195,18 +1233,17 @@ CONFIG_USB_PRINTER=m
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1235,7 +1272,7 @@ CONFIG_USB_SERIAL_ARK3116=m
# 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_CP210X 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
@@ -1259,15 +1296,19 @@ CONFIG_USB_SERIAL_ARK3116=m
# CONFIG_USB_SERIAL_NAVMAN is not set
CONFIG_USB_SERIAL_PL2303=m
# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QUALCOMM 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_SIEMENS_MPI is not set
# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL 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_OPTICON is not set
# CONFIG_USB_SERIAL_DEBUG is not set
#
@@ -1284,7 +1325,6 @@ CONFIG_USB_SERIAL_PL2303=m
# 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
@@ -1296,6 +1336,11 @@ CONFIG_USB_SERIAL_PL2303=m
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1337,6 +1382,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=m
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1363,6 +1409,7 @@ CONFIG_XFS_FS=m
# CONFIG_XFS_RT is not set
# CONFIG_XFS_DEBUG is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1413,6 +1460,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1436,7 +1484,6 @@ CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1559,6 +1606,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1573,7 +1621,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1610,10 +1657,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=y
# CONFIG_CRYPTO_TEST is not set
@@ -1683,6 +1732,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1706,11 +1756,12 @@ CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_TEXTSEARCH_BM=m
CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/ul2_defconfig b/arch/sh/configs/ul2_defconfig
index 27f968a959f..34f5192a324 100644
--- a/arch/sh/configs/ul2_defconfig
+++ b/arch/sh/configs/ul2_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:22:53 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:30:27 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,15 +16,17 @@ CONFIG_GENERIC_IRQ_PROBE=y
# CONFIG_GENERIC_GPIO is not set
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -44,19 +46,33 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -66,10 +82,8 @@ 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
@@ -78,6 +92,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
@@ -118,11 +133,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -132,6 +142,7 @@ CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
CONFIG_CPU_SH4AL_DSP=y
CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -160,6 +171,7 @@ CONFIG_CPU_SHX2=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -213,11 +225,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -243,6 +256,7 @@ CONFIG_CPU_HAS_DSP=y
# Timer and clock configuration
#
CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
CONFIG_SH_TIMER_IRQ=16
CONFIG_SH_PCLK_FREQ=33333333
CONFIG_TICK_ONESHOT=y
@@ -319,7 +333,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -374,6 +387,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -386,15 +400,14 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
CONFIG_CFG80211=y
# CONFIG_CFG80211_REG_DEBUG is not set
-CONFIG_NL80211=y
# CONFIG_WIRELESS_OLD_REGULATORY is not set
CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
CONFIG_LIB80211=m
+# CONFIG_LIB80211_DEBUG is not set
CONFIG_MAC80211=y
#
@@ -408,6 +421,7 @@ CONFIG_MAC80211_RC_DEFAULT="pid"
# CONFIG_MAC80211_MESH is not set
# CONFIG_MAC80211_LEDS is not set
# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -430,6 +444,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -497,6 +512,11 @@ CONFIG_MTD_RAM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -514,9 +534,13 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -562,6 +586,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -570,6 +595,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_PLATFORM=y
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -582,8 +608,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -605,12 +633,13 @@ CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_SDIO=m
CONFIG_LIBERTAS_DEBUG=y
# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
# CONFIG_USB_ZD1201 is not set
# CONFIG_USB_NET_RNDIS_WLAN is not set
# CONFIG_RTL8187 is not set
# CONFIG_MAC80211_HWSIM is not set
# CONFIG_P54_COMMON is not set
-# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_AR9170_USB is not set
# CONFIG_HOSTAP is not set
# CONFIG_B43 is not set
# CONFIG_B43LEGACY is not set
@@ -618,6 +647,10 @@ CONFIG_LIBERTAS_DEBUG=y
# CONFIG_RT2X00 is not set
#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
@@ -794,7 +827,9 @@ CONFIG_USB_MON=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_SL811_HCD is not set
CONFIG_USB_R8A66597_HCD=y
# CONFIG_SUPERH_ON_CHIP_R8A66597 is not set
@@ -809,18 +844,17 @@ CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -856,7 +890,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -866,6 +899,11 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
@@ -887,6 +925,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -909,6 +948,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -956,6 +996,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -976,7 +1017,6 @@ CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1059,7 +1099,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1087,10 +1126,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1159,6 +1200,7 @@ CONFIG_CRYPTO_ARC4=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1180,7 +1222,8 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig
index be726c7cdf9..d174b1a4d80 100644
--- a/arch/sh/configs/urquell_defconfig
+++ b/arch/sh/configs/urquell_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc4
-# Thu Mar 5 17:28:13 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:33:39 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_NUMA=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -69,6 +70,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -78,10 +80,8 @@ 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
@@ -89,6 +89,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -213,11 +214,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# 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
@@ -231,6 +233,7 @@ CONFIG_SH_FPU=y
CONFIG_SH_STORE_QUEUES=y
CONFIG_CPU_HAS_INTEVT=y
CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEAEX=y
CONFIG_CPU_HAS_FPU=y
#
@@ -318,7 +321,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -378,6 +380,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -390,7 +393,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -491,7 +493,6 @@ CONFIG_MTD_PHYSMAP=y
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
#
# UBI - Unsorted block images
@@ -553,6 +554,7 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -561,6 +563,7 @@ CONFIG_ATA_SFF=y
# CONFIG_PATA_PLATFORM is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -592,8 +595,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -610,7 +615,6 @@ CONFIG_SMC91X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -705,6 +709,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -746,7 +751,6 @@ CONFIG_I2C_PCA_PLATFORM=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_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -855,6 +859,7 @@ CONFIG_FB_SM501=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -922,7 +927,7 @@ CONFIG_THRUSTMASTER_FF=m
CONFIG_ZEROPLUS_FF=m
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_USB_ARCH_HAS_EHCI is not set
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
@@ -947,6 +952,8 @@ CONFIG_USB_MON=y
# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_HWA_HCD is not set
@@ -960,11 +967,11 @@ CONFIG_USB_MON=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
@@ -1006,7 +1013,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1022,12 +1028,14 @@ CONFIG_USB_STORAGE=y
# OTG and related infrastructure
#
# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV 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_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1125,7 +1133,6 @@ CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1206,7 +1213,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1234,10 +1240,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1306,6 +1314,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1326,7 +1335,7 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
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
+CONFIG_NLATTR=y
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
index f13a05285a9..666713ac5fc 100644
--- a/arch/sh/drivers/dma/Kconfig
+++ b/arch/sh/drivers/dma/Kconfig
@@ -12,21 +12,25 @@ config SH_DMA
config SH_DMA_IRQ_MULTI
bool
depends on SH_DMA
- default y if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7751 || \
- CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R || \
- CPU_SUBTYPE_SH7091 || CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7764 || \
- CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
+ default y if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7751 || \
+ CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7750R || \
+ CPU_SUBTYPE_SH7751R || CPU_SUBTYPE_SH7091 || \
+ CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7764 || \
+ CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
config NR_ONCHIP_DMA_CHANNELS
int
depends on SH_DMA
- default "4" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7750S
- default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R || CPU_SUBTYPE_SH7760
- default "12" if CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
+ default "4" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7751 || \
+ CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7091
+ default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R || \
+ CPU_SUBTYPE_SH7760
+ default "12" if CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7780 || \
+ CPU_SUBTYPE_SH7785
default "6"
help
This allows you to specify the number of channels that the on-chip
- DMAC supports. This will be 4 for SH7750/SH7751 and 8 for the
+ DMAC supports. This will be 4 for SH7091/SH7750/SH7751 and 8 for the
SH7750R/SH7751R.
config NR_DMA_CHANNELS_BOOL
diff --git a/arch/sh/drivers/pci/ops-sh7785lcr.c b/arch/sh/drivers/pci/ops-sh7785lcr.c
index b3bd6870205..fb0869f0bef 100644
--- a/arch/sh/drivers/pci/ops-sh7785lcr.c
+++ b/arch/sh/drivers/pci/ops-sh7785lcr.c
@@ -48,13 +48,13 @@ EXPORT_SYMBOL(board_pci_channels);
static struct sh4_pci_address_map sh7785_pci_map = {
.window0 = {
- .base = SH7780_CS2_BASE_ADDR,
- .size = 0x04000000,
- },
-
- .window1 = {
- .base = SH7780_CS3_BASE_ADDR,
- .size = 0x04000000,
+#if defined(CONFIG_32BIT)
+ .base = SH7780_32BIT_DDR_BASE_ADDR,
+ .size = 0x40000000,
+#else
+ .base = SH7780_CS0_BASE_ADDR,
+ .size = 0x20000000,
+#endif
},
.flags = SH4_PCIC_NO_RESET,
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index 773d575a04b..bae6a2cf047 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -120,19 +120,15 @@ int __init sh7780_pcic_init(struct sh4_pci_address_map *map)
/* Set IO and Mem windows to local address
* Make PCI and local address the same for easy 1 to 1 mapping
- * Window0 = map->window0.size @ non-cached area base = SDRAM
- * Window1 = map->window1.size @ cached area base = SDRAM
*/
- word = (CONFIG_MEMORY_SIZE - 0x00100000) | 0x00000001;
- pci_write_reg(word, SH4_PCILSR0);
- pci_write_reg(0x00000001, SH4_PCILSR1);
+ pci_write_reg(map->window0.size - 0xfffff, SH4_PCILSR0);
+ pci_write_reg(map->window1.size - 0xfffff, SH4_PCILSR1);
/* Set the values on window 0 PCI config registers */
- word = CONFIG_MEMORY_START | (CONFIG_MEMORY_SIZE - 0x01000000);
- pci_write_reg(word, SH4_PCILAR0);
- pci_write_reg(word, SH7780_PCIMBAR0);
+ pci_write_reg(map->window0.base, SH4_PCILAR0);
+ pci_write_reg(map->window0.base, SH7780_PCIMBAR0);
/* Set the values on window 1 PCI config registers */
- pci_write_reg(0x00000000, SH4_PCILAR1);
- pci_write_reg(0x00000000, SH7780_PCIMBAR1);
+ pci_write_reg(map->window1.base, SH4_PCILAR1);
+ pci_write_reg(map->window1.base, SH7780_PCIMBAR1);
/* Map IO space into PCI IO window
* The IO window is 64K-PCIBIOS_MIN_IO in size
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h
index 97b2c98f05c..93adc7119b7 100644
--- a/arch/sh/drivers/pci/pci-sh7780.h
+++ b/arch/sh/drivers/pci/pci-sh7780.h
@@ -104,6 +104,8 @@
#define SH7780_CS5_BASE_ADDR (SH7780_CS4_BASE_ADDR + SH7780_MEM_REGION_SIZE)
#define SH7780_CS6_BASE_ADDR (SH7780_CS5_BASE_ADDR + SH7780_MEM_REGION_SIZE)
+#define SH7780_32BIT_DDR_BASE_ADDR 0x40000000
+
struct sh4_pci_address_map;
/* arch/sh/drivers/pci/pci-sh7780.c */
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index e36c7b87086..0d6ac7a1db4 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <linux/dma-debug.h>
#include <asm/io.h>
static int __init pcibios_init(void)
@@ -43,6 +44,8 @@ static int __init pcibios_init(void)
pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq);
+ dma_debug_add_bus(&pci_bus_type);
+
return 0;
}
subsys_initcall(pcibios_init);
diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h
index 627315ecdb5..ea9d4f41c9d 100644
--- a/arch/sh/include/asm/dma-mapping.h
+++ b/arch/sh/include/asm/dma-mapping.h
@@ -3,6 +3,7 @@
#include <linux/mm.h>
#include <linux/scatterlist.h>
+#include <linux/dma-debug.h>
#include <asm/cacheflush.h>
#include <asm/io.h>
#include <asm-generic/dma-coherent.h>
@@ -38,16 +39,26 @@ static inline dma_addr_t dma_map_single(struct device *dev,
void *ptr, size_t size,
enum dma_data_direction dir)
{
+ dma_addr_t addr = virt_to_phys(ptr);
+
#if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT)
if (dev->bus == &pci_bus_type)
- return virt_to_phys(ptr);
+ return addr;
#endif
dma_cache_sync(dev, ptr, size, dir);
- return virt_to_phys(ptr);
+ debug_dma_map_page(dev, virt_to_page(ptr),
+ (unsigned long)ptr & ~PAGE_MASK, size,
+ dir, addr, true);
+
+ return addr;
}
-#define dma_unmap_single(dev, addr, size, dir) do { } while (0)
+static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
+ size_t size, enum dma_data_direction dir)
+{
+ debug_dma_unmap_page(dev, addr, size, dir, true);
+}
static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction dir)
@@ -59,12 +70,19 @@ static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
#endif
sg[i].dma_address = sg_phys(&sg[i]);
+ sg[i].dma_length = sg[i].length;
}
+ debug_dma_map_sg(dev, sg, nents, i, dir);
+
return nents;
}
-#define dma_unmap_sg(dev, sg, nents, dir) do { } while (0)
+static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+ debug_dma_unmap_sg(dev, sg, nents, dir);
+}
static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
@@ -111,6 +129,7 @@ static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg,
dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
#endif
sg[i].dma_address = sg_phys(&sg[i]);
+ sg[i].dma_length = sg[i].length;
}
}
@@ -119,6 +138,7 @@ static inline void dma_sync_single_for_cpu(struct device *dev,
enum dma_data_direction dir)
{
dma_sync_single(dev, dma_handle, size, dir);
+ debug_dma_sync_single_for_cpu(dev, dma_handle, size, dir);
}
static inline void dma_sync_single_for_device(struct device *dev,
@@ -127,6 +147,7 @@ static inline void dma_sync_single_for_device(struct device *dev,
enum dma_data_direction dir)
{
dma_sync_single(dev, dma_handle, size, dir);
+ debug_dma_sync_single_for_device(dev, dma_handle, size, dir);
}
static inline void dma_sync_single_range_for_cpu(struct device *dev,
@@ -136,6 +157,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev,
enum dma_data_direction direction)
{
dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction);
+ debug_dma_sync_single_range_for_cpu(dev, dma_handle,
+ offset, size, direction);
}
static inline void dma_sync_single_range_for_device(struct device *dev,
@@ -145,6 +168,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
enum dma_data_direction direction)
{
dma_sync_single_for_device(dev, dma_handle+offset, size, direction);
+ debug_dma_sync_single_range_for_device(dev, dma_handle,
+ offset, size, direction);
}
@@ -153,6 +178,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev,
enum dma_data_direction dir)
{
dma_sync_sg(dev, sg, nelems, dir);
+ debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir);
}
static inline void dma_sync_sg_for_device(struct device *dev,
@@ -160,9 +186,9 @@ static inline void dma_sync_sg_for_device(struct device *dev,
enum dma_data_direction dir)
{
dma_sync_sg(dev, sg, nelems, dir);
+ debug_dma_sync_sg_for_device(dev, sg, nelems, dir);
}
-
static inline int dma_get_cache_alignment(void)
{
/*
diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h
index 6c43625bb1a..f5963037c9d 100644
--- a/arch/sh/include/asm/mmu.h
+++ b/arch/sh/include/asm/mmu.h
@@ -1,22 +1,6 @@
#ifndef __MMU_H
#define __MMU_H
-/* Default "unsigned long" context */
-typedef unsigned long mm_context_id_t[NR_CPUS];
-
-typedef struct {
-#ifdef CONFIG_MMU
- mm_context_id_t id;
- void *vdso;
-#else
- unsigned long end_brk;
-#endif
-#ifdef CONFIG_BINFMT_ELF_FDPIC
- unsigned long exec_fdpic_loadmap;
- unsigned long interp_fdpic_loadmap;
-#endif
-} mm_context_t;
-
/*
* Privileged Space Mapping Buffer (PMB) definitions
*/
@@ -41,6 +25,24 @@ typedef struct {
#define PMB_NO_ENTRY (-1)
+#ifndef __ASSEMBLY__
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_id_t[NR_CPUS];
+
+typedef struct {
+#ifdef CONFIG_MMU
+ mm_context_id_t id;
+ void *vdso;
+#else
+ unsigned long end_brk;
+#endif
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+ unsigned long exec_fdpic_loadmap;
+ unsigned long interp_fdpic_loadmap;
+#endif
+} mm_context_t;
+
struct pmb_entry;
struct pmb_entry {
@@ -70,6 +72,7 @@ void pmb_free(struct pmb_entry *pmbe);
long pmb_remap(unsigned long virt, unsigned long phys,
unsigned long size, unsigned long flags);
void pmb_unmap(unsigned long addr);
+#endif /* __ASSEMBLY__ */
#endif /* __MMU_H */
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h
index efdd78a53b1..9a8714945dc 100644
--- a/arch/sh/include/asm/processor_32.h
+++ b/arch/sh/include/asm/processor_32.h
@@ -58,6 +58,14 @@ asmlinkage void __init sh_cpu_init(void);
#define SR_FD 0x00008000
/*
+ * DSP structure and data
+ */
+struct sh_dsp_struct {
+ unsigned long dsp_regs[14];
+ long status;
+};
+
+/*
* FPU structure and data
*/
@@ -96,6 +104,11 @@ struct thread_struct {
/* floating point info */
union sh_fpu_union fpu;
+
+#ifdef CONFIG_SH_DSP
+ /* Dsp status information */
+ struct sh_dsp_struct dsp_status;
+#endif
};
/* Count of active tasks with UBC settings */
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index 81c6568fdb3..d3f6caa936b 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -119,16 +119,8 @@ struct task_struct;
extern void user_enable_single_step(struct task_struct *);
extern void user_disable_single_step(struct task_struct *);
-#ifdef CONFIG_SH_DSP
-#define task_pt_regs(task) \
- ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \
- - sizeof(struct pt_dspregs)) - 1)
-#define task_pt_dspregs(task) \
- ((struct pt_dspregs *) (task_stack_page(task) + THREAD_SIZE) - 1)
-#else
#define task_pt_regs(task) \
((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE) - 1)
-#endif
static inline unsigned long profile_pc(struct pt_regs *regs)
{
diff --git a/arch/sh/include/asm/scatterlist.h b/arch/sh/include/asm/scatterlist.h
index 2084d037369..c693d268a41 100644
--- a/arch/sh/include/asm/scatterlist.h
+++ b/arch/sh/include/asm/scatterlist.h
@@ -5,12 +5,13 @@
struct scatterlist {
#ifdef CONFIG_DEBUG_SG
- unsigned long sg_magic;
+ unsigned long sg_magic;
#endif
- unsigned long page_link;
- unsigned int offset;/* for highmem, page offset */
- dma_addr_t dma_address;
- unsigned int length;
+ unsigned long page_link;
+ unsigned int offset; /* for highmem, page offset */
+ unsigned int length;
+ dma_addr_t dma_address;
+ unsigned int dma_length;
};
#define ISA_DMA_THRESHOLD PHYS_ADDR_MASK
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index c9ec6af8e74..a88895e6dcb 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -153,6 +153,7 @@ extern unsigned long cached_to_uncached;
extern struct dentry *sh_debugfs_root;
void per_cpu_trap_init(void);
+void default_idle(void);
asmlinkage void break_point_trap(void);
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h
index a726d5d0727..240b31e1142 100644
--- a/arch/sh/include/asm/system_32.h
+++ b/arch/sh/include/asm/system_32.h
@@ -3,59 +3,135 @@
#include <linux/types.h>
+#ifdef CONFIG_SH_DSP
+
+#define is_dsp_enabled(tsk) \
+ (!!(tsk->thread.dsp_status.status & SR_DSP))
+
+#define __restore_dsp(tsk) \
+do { \
+ register u32 *__ts2 __asm__ ("r2") = \
+ (u32 *)&tsk->thread.dsp_status; \
+ __asm__ __volatile__ ( \
+ ".balign 4\n\t" \
+ "movs.l @r2+, a1\n\t" \
+ "movs.l @r2+, a0g\n\t" \
+ "movs.l @r2+, a1g\n\t" \
+ "movs.l @r2+, m0\n\t" \
+ "movs.l @r2+, m1\n\t" \
+ "movs.l @r2+, a0\n\t" \
+ "movs.l @r2+, x0\n\t" \
+ "movs.l @r2+, x1\n\t" \
+ "movs.l @r2+, y0\n\t" \
+ "movs.l @r2+, y1\n\t" \
+ "lds.l @r2+, dsr\n\t" \
+ "ldc.l @r2+, rs\n\t" \
+ "ldc.l @r2+, re\n\t" \
+ "ldc.l @r2+, mod\n\t" \
+ : : "r" (__ts2)); \
+} while (0)
+
+
+#define __save_dsp(tsk) \
+do { \
+ register u32 *__ts2 __asm__ ("r2") = \
+ (u32 *)&tsk->thread.dsp_status + 14; \
+ \
+ __asm__ __volatile__ ( \
+ ".balign 4\n\t" \
+ "stc.l mod, @-r2\n\t" \
+ "stc.l re, @-r2\n\t" \
+ "stc.l rs, @-r2\n\t" \
+ "sts.l dsr, @-r2\n\t" \
+ "sts.l y1, @-r2\n\t" \
+ "sts.l y0, @-r2\n\t" \
+ "sts.l x1, @-r2\n\t" \
+ "sts.l x0, @-r2\n\t" \
+ "sts.l a0, @-r2\n\t" \
+ ".word 0xf653 ! movs.l a1, @-r2\n\t" \
+ ".word 0xf6f3 ! movs.l a0g, @-r2\n\t" \
+ ".word 0xf6d3 ! movs.l a1g, @-r2\n\t" \
+ ".word 0xf6c3 ! movs.l m0, @-r2\n\t" \
+ ".word 0xf6e3 ! movs.l m1, @-r2\n\t" \
+ : : "r" (__ts2)); \
+} while (0)
+
+#else
+
+#define is_dsp_enabled(tsk) (0)
+#define __save_dsp(tsk) do { } while (0)
+#define __restore_dsp(tsk) do { } while (0)
+#endif
+
struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *next);
/*
* switch_to() should switch tasks to task nr n, first
*/
-#define switch_to(prev, next, last) \
-do { \
- register u32 *__ts1 __asm__ ("r1") = (u32 *)&prev->thread.sp; \
- register u32 *__ts2 __asm__ ("r2") = (u32 *)&prev->thread.pc; \
- register u32 *__ts4 __asm__ ("r4") = (u32 *)prev; \
- register u32 *__ts5 __asm__ ("r5") = (u32 *)next; \
- register u32 *__ts6 __asm__ ("r6") = (u32 *)&next->thread.sp; \
- register u32 __ts7 __asm__ ("r7") = next->thread.pc; \
- struct task_struct *__last; \
- \
- __asm__ __volatile__ ( \
- ".balign 4\n\t" \
- "stc.l gbr, @-r15\n\t" \
- "sts.l pr, @-r15\n\t" \
- "mov.l r8, @-r15\n\t" \
- "mov.l r9, @-r15\n\t" \
- "mov.l r10, @-r15\n\t" \
- "mov.l r11, @-r15\n\t" \
- "mov.l r12, @-r15\n\t" \
- "mov.l r13, @-r15\n\t" \
- "mov.l r14, @-r15\n\t" \
- "mov.l r15, @r1\t! save SP\n\t" \
- "mov.l @r6, r15\t! change to new stack\n\t" \
- "mova 1f, %0\n\t" \
- "mov.l %0, @r2\t! save PC\n\t" \
- "mov.l 2f, %0\n\t" \
- "jmp @%0\t! call __switch_to\n\t" \
- " lds r7, pr\t! with return to new PC\n\t" \
- ".balign 4\n" \
- "2:\n\t" \
- ".long __switch_to\n" \
- "1:\n\t" \
- "mov.l @r15+, r14\n\t" \
- "mov.l @r15+, r13\n\t" \
- "mov.l @r15+, r12\n\t" \
- "mov.l @r15+, r11\n\t" \
- "mov.l @r15+, r10\n\t" \
- "mov.l @r15+, r9\n\t" \
- "mov.l @r15+, r8\n\t" \
- "lds.l @r15+, pr\n\t" \
- "ldc.l @r15+, gbr\n\t" \
- : "=z" (__last) \
- : "r" (__ts1), "r" (__ts2), "r" (__ts4), \
- "r" (__ts5), "r" (__ts6), "r" (__ts7) \
- : "r3", "t"); \
- \
- last = __last; \
+#define switch_to(prev, next, last) \
+do { \
+ register u32 *__ts1 __asm__ ("r1"); \
+ register u32 *__ts2 __asm__ ("r2"); \
+ register u32 *__ts4 __asm__ ("r4"); \
+ register u32 *__ts5 __asm__ ("r5"); \
+ register u32 *__ts6 __asm__ ("r6"); \
+ register u32 __ts7 __asm__ ("r7"); \
+ struct task_struct *__last; \
+ \
+ if (is_dsp_enabled(prev)) \
+ __save_dsp(prev); \
+ \
+ __ts1 = (u32 *)&prev->thread.sp; \
+ __ts2 = (u32 *)&prev->thread.pc; \
+ __ts4 = (u32 *)prev; \
+ __ts5 = (u32 *)next; \
+ __ts6 = (u32 *)&next->thread.sp; \
+ __ts7 = next->thread.pc; \
+ \
+ __asm__ __volatile__ ( \
+ ".balign 4\n\t" \
+ "stc.l gbr, @-r15\n\t" \
+ "sts.l pr, @-r15\n\t" \
+ "mov.l r8, @-r15\n\t" \
+ "mov.l r9, @-r15\n\t" \
+ "mov.l r10, @-r15\n\t" \
+ "mov.l r11, @-r15\n\t" \
+ "mov.l r12, @-r15\n\t" \
+ "mov.l r13, @-r15\n\t" \
+ "mov.l r14, @-r15\n\t" \
+ "mov.l r15, @r1\t! save SP\n\t" \
+ "mov.l @r6, r15\t! change to new stack\n\t" \
+ "mova 1f, %0\n\t" \
+ "mov.l %0, @r2\t! save PC\n\t" \
+ "mov.l 2f, %0\n\t" \
+ "jmp @%0\t! call __switch_to\n\t" \
+ " lds r7, pr\t! with return to new PC\n\t" \
+ ".balign 4\n" \
+ "2:\n\t" \
+ ".long __switch_to\n" \
+ "1:\n\t" \
+ "mov.l @r15+, r14\n\t" \
+ "mov.l @r15+, r13\n\t" \
+ "mov.l @r15+, r12\n\t" \
+ "mov.l @r15+, r11\n\t" \
+ "mov.l @r15+, r10\n\t" \
+ "mov.l @r15+, r9\n\t" \
+ "mov.l @r15+, r8\n\t" \
+ "lds.l @r15+, pr\n\t" \
+ "ldc.l @r15+, gbr\n\t" \
+ : "=z" (__last) \
+ : "r" (__ts1), "r" (__ts2), "r" (__ts4), \
+ "r" (__ts5), "r" (__ts6), "r" (__ts7) \
+ : "r3", "t"); \
+ \
+ last = __last; \
+} while (0)
+
+#define finish_arch_switch(prev) \
+do { \
+ if (is_dsp_enabled(prev)) \
+ __restore_dsp(prev); \
} while (0)
#define __uses_jump_to_uncached \
diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h
index a3f23954589..8489a0905a8 100644
--- a/arch/sh/include/asm/topology.h
+++ b/arch/sh/include/asm/topology.h
@@ -37,8 +37,11 @@
#define pcibus_to_node(bus) ((void)(bus), -1)
#define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \
CPU_MASK_ALL : \
- node_to_cpumask(pcibus_to_node(bus)) \
- )
+ node_to_cpumask(pcibus_to_node(bus)))
+#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \
+ CPU_MASK_ALL_PTR : \
+ cpumask_of_node(pcibus_to_node(bus)))
+
#endif
#include <asm-generic/topology.h>
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h
index d52c000cf92..2efb819e2db 100644
--- a/arch/sh/include/asm/unistd_32.h
+++ b/arch/sh/include/asm/unistd_32.h
@@ -341,8 +341,10 @@
#define __NR_dup3 330
#define __NR_pipe2 331
#define __NR_inotify_init1 332
+#define __NR_preadv 333
+#define __NR_pwritev 334
-#define NR_syscalls 333
+#define NR_syscalls 335
#ifdef __KERNEL__
diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h
index 7c54e91753c..6eb9d2934c0 100644
--- a/arch/sh/include/asm/unistd_64.h
+++ b/arch/sh/include/asm/unistd_64.h
@@ -381,10 +381,12 @@
#define __NR_dup3 358
#define __NR_pipe2 359
#define __NR_inotify_init1 360
+#define __NR_preadv 361
+#define __NR_pwritev 362
#ifdef __KERNEL__
-#define NR_syscalls 361
+#define NR_syscalls 363
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7786.h b/arch/sh/include/cpu-sh4/cpu/sh7786.h
index 48688adc0c8..977862f9072 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7786.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7786.h
@@ -51,142 +51,86 @@ enum {
GPIO_PJ7, GPIO_PJ6, GPIO_PJ5, GPIO_PJ4,
GPIO_PJ3, GPIO_PJ2, GPIO_PJ1, GPIO_PJ0,
- GPIO_FN_CDE,
- GPIO_FN_ETH_MAGIC,
- GPIO_FN_DISP,
- GPIO_FN_ETH_LINK,
- GPIO_FN_DR5,
- GPIO_FN_ETH_TX_ER,
- GPIO_FN_DR4,
- GPIO_FN_ETH_TX_EN,
- GPIO_FN_DR3,
- GPIO_FN_ETH_TXD3,
- GPIO_FN_DR2,
- GPIO_FN_ETH_TXD2,
- GPIO_FN_DR1,
- GPIO_FN_ETH_TXD1,
- GPIO_FN_DR0,
- GPIO_FN_ETH_TXD0,
- GPIO_FN_VSYNC,
- GPIO_FN_HSPI_CLK,
- GPIO_FN_ODDF,
- GPIO_FN_HSPI_CS,
- GPIO_FN_DG5,
- GPIO_FN_ETH_MDIO,
- GPIO_FN_DG4,
- GPIO_FN_ETH_RX_CLK,
- GPIO_FN_DG3,
- GPIO_FN_ETH_MDC,
- GPIO_FN_DG2,
- GPIO_FN_ETH_COL,
- GPIO_FN_DG1,
- GPIO_FN_ETH_TX_CLK,
- GPIO_FN_DG0,
- GPIO_FN_ETH_CRS,
- GPIO_FN_DCLKIN,
- GPIO_FN_HSPI_RX,
- GPIO_FN_HSYNC,
- GPIO_FN_HSPI_TX,
- GPIO_FN_DB5,
- GPIO_FN_ETH_RXD3,
- GPIO_FN_DB4,
- GPIO_FN_ETH_RXD2,
- GPIO_FN_DB3,
- GPIO_FN_ETH_RXD1,
- GPIO_FN_DB2,
- GPIO_FN_ETH_RXD0,
- GPIO_FN_DB1,
- GPIO_FN_ETH_RX_DV,
- GPIO_FN_DB0,
- GPIO_FN_ETH_RX_ER,
- GPIO_FN_DCLKOUT,
- GPIO_FN_SCIF1_SLK,
- GPIO_FN_SCIF1_RXD,
- GPIO_FN_SCIF1_TXD,
- GPIO_FN_DACK1,
- GPIO_FN_BACK,
- GPIO_FN_FALE,
- GPIO_FN_DACK0,
- GPIO_FN_FCLE,
- GPIO_FN_DREQ1,
- GPIO_FN_BREQ,
- GPIO_FN_USB_OVC1,
- GPIO_FN_DREQ0,
- GPIO_FN_USB_OVC0,
- GPIO_FN_USB_PENC1,
- GPIO_FN_USB_PENC0,
- GPIO_FN_HAC1_SDOUT,
- GPIO_FN_SSI1_SDATA,
- GPIO_FN_SDIF1CMD,
- GPIO_FN_HAC1_SDIN,
- GPIO_FN_SSI1_SCK,
- GPIO_FN_SDIF1CD,
- GPIO_FN_HAC1_SYNC,
- GPIO_FN_SSI1_WS,
- GPIO_FN_SDIF1WP,
- GPIO_FN_HAC1_BITCLK,
- GPIO_FN_SSI1_CLK,
- GPIO_FN_SDIF1CLK,
- GPIO_FN_HAC0_SDOUT,
- GPIO_FN_SSI0_SDATA,
- GPIO_FN_SDIF1D3,
- GPIO_FN_HAC0_SDIN,
- GPIO_FN_SSI0_SCK,
- GPIO_FN_SDIF1D2,
- GPIO_FN_HAC0_SYNC,
- GPIO_FN_SSI0_WS,
- GPIO_FN_SDIF1D1,
- GPIO_FN_HAC0_BITCLK,
- GPIO_FN_SSI0_CLK,
- GPIO_FN_SDIF1D0,
- GPIO_FN_SCIF3_SCK,
- GPIO_FN_SSI2_SDATA,
- GPIO_FN_SCIF3_RXD,
- GPIO_FN_TCLK,
- GPIO_FN_SSI2_SCK,
- GPIO_FN_SCIF3_TXD,
+ /* DU */
+ GPIO_FN_DCLKIN, GPIO_FN_DCLKOUT, GPIO_FN_ODDF,
+ GPIO_FN_VSYNC, GPIO_FN_HSYNC, GPIO_FN_CDE, GPIO_FN_DISP,
+ GPIO_FN_DR0, GPIO_FN_DG0, GPIO_FN_DB0,
+ GPIO_FN_DR1, GPIO_FN_DG1, GPIO_FN_DB1,
+ GPIO_FN_DR2, GPIO_FN_DG2, GPIO_FN_DB2,
+ GPIO_FN_DR3, GPIO_FN_DG3, GPIO_FN_DB3,
+ GPIO_FN_DR4, GPIO_FN_DG4, GPIO_FN_DB4,
+ GPIO_FN_DR5, GPIO_FN_DG5, GPIO_FN_DB5,
+
+ /* Eth */
+ GPIO_FN_ETH_MAGIC, GPIO_FN_ETH_LINK, GPIO_FN_ETH_TX_ER,
+ GPIO_FN_ETH_TX_EN, GPIO_FN_ETH_MDIO, GPIO_FN_ETH_RX_CLK,
+ GPIO_FN_ETH_MDC, GPIO_FN_ETH_COL, GPIO_FN_ETH_TX_CLK,
+ GPIO_FN_ETH_CRS, GPIO_FN_ETH_RX_DV, GPIO_FN_ETH_RX_ER,
+ GPIO_FN_ETH_TXD3, GPIO_FN_ETH_TXD2, GPIO_FN_ETH_TXD1, GPIO_FN_ETH_TXD0,
+ GPIO_FN_ETH_RXD3, GPIO_FN_ETH_RXD2, GPIO_FN_ETH_RXD1, GPIO_FN_ETH_RXD0,
+
+ /* HSPI */
+ GPIO_FN_HSPI_CLK, GPIO_FN_HSPI_CS, GPIO_FN_HSPI_RX, GPIO_FN_HSPI_TX,
+
+ /* SCIF0 */
+ GPIO_FN_SCIF0_CTS, GPIO_FN_SCIF0_RTS, GPIO_FN_SCIF0_SCK,
+ GPIO_FN_SCIF0_RXD, GPIO_FN_SCIF0_TXD,
+
+ /* SCIF1 */
+ GPIO_FN_SCIF1_SCK, GPIO_FN_SCIF1_RXD, GPIO_FN_SCIF1_TXD,
+
+ /* SCIF3 */
+ GPIO_FN_SCIF3_SCK, GPIO_FN_SCIF3_RXD, GPIO_FN_SCIF3_TXD,
+
+ /* SCIF4 */
+ GPIO_FN_SCIF4_SCK, GPIO_FN_SCIF4_RXD, GPIO_FN_SCIF4_TXD,
+
+ /* SCIF5 */
+ GPIO_FN_SCIF5_SCK, GPIO_FN_SCIF5_RXD, GPIO_FN_SCIF5_TXD,
+
+ /* LBSC */
+ GPIO_FN_BREQ, GPIO_FN_IOIS16, GPIO_FN_CE2B, GPIO_FN_CE2A, GPIO_FN_BACK,
+
+ /* FLCTL */
+ GPIO_FN_FALE, GPIO_FN_FRB, GPIO_FN_FSTATUS,
+ GPIO_FN_FSE, GPIO_FN_FCLE,
+
+ /* DMAC */
+ GPIO_FN_DACK0, GPIO_FN_DREQ0, GPIO_FN_DRAK0,
+ GPIO_FN_DACK1, GPIO_FN_DREQ1, GPIO_FN_DRAK1,
+ GPIO_FN_DACK2, GPIO_FN_DREQ2, GPIO_FN_DRAK2,
+ GPIO_FN_DACK3, GPIO_FN_DREQ3, GPIO_FN_DRAK3,
+
+ /* USB */
+ GPIO_FN_USB_OVC0, GPIO_FN_USB_PENC0,
+ GPIO_FN_USB_OVC1, GPIO_FN_USB_PENC1,
+
+ /* HAC */
GPIO_FN_HAC_RES,
- GPIO_FN_SSI2_WS,
- GPIO_FN_DACK3,
- GPIO_FN_SDIF0CMD,
- GPIO_FN_DACK2,
- GPIO_FN_SDIF0CD,
- GPIO_FN_DREQ3,
- GPIO_FN_SDIF0WP,
- GPIO_FN_SCIF0_CTS,
- GPIO_FN_DREQ2,
- GPIO_FN_SDIF0CLK,
- GPIO_FN_SCIF0_RTS,
- GPIO_FN_IRL7,
- GPIO_FN_SDIF0D3,
- GPIO_FN_SCIF0_SCK,
- GPIO_FN_IRL6,
- GPIO_FN_SDIF0D2,
- GPIO_FN_SCIF0_RXD,
- GPIO_FN_IRL5,
- GPIO_FN_SDIF0D1,
- GPIO_FN_SCIF0_TXD,
- GPIO_FN_IRL4,
- GPIO_FN_SDIF0D0,
- GPIO_FN_SCIF5_SCK,
- GPIO_FN_FRB,
- GPIO_FN_SCIF5_RXD,
- GPIO_FN_IOIS16,
- GPIO_FN_SCIF5_TXD,
- GPIO_FN_CE2B,
- GPIO_FN_DRAK3,
- GPIO_FN_CE2A,
- GPIO_FN_SCIF4_SCK,
- GPIO_FN_DRAK2,
- GPIO_FN_SSI3_WS,
- GPIO_FN_SCIF4_RXD,
- GPIO_FN_DRAK1,
- GPIO_FN_SSI3_SDATA,
- GPIO_FN_FSTATUS,
- GPIO_FN_SCIF4_TXD,
- GPIO_FN_DRAK0,
- GPIO_FN_SSI3_SCK,
- GPIO_FN_FSE,
+ GPIO_FN_HAC0_SDOUT, GPIO_FN_HAC0_SDIN,
+ GPIO_FN_HAC0_SYNC, GPIO_FN_HAC0_BITCLK,
+ GPIO_FN_HAC1_SDOUT, GPIO_FN_HAC1_SDIN,
+ GPIO_FN_HAC1_SYNC, GPIO_FN_HAC1_BITCLK,
+
+ /* SSI */
+ GPIO_FN_SSI0_SDATA, GPIO_FN_SSI0_SCK, GPIO_FN_SSI0_WS, GPIO_FN_SSI0_CLK,
+ GPIO_FN_SSI1_SDATA, GPIO_FN_SSI1_SCK, GPIO_FN_SSI1_WS, GPIO_FN_SSI1_CLK,
+ GPIO_FN_SSI2_SDATA, GPIO_FN_SSI2_SCK, GPIO_FN_SSI2_WS,
+ GPIO_FN_SSI3_SDATA, GPIO_FN_SSI3_SCK, GPIO_FN_SSI3_WS,
+
+ /* SDIF1 */
+ GPIO_FN_SDIF1CMD, GPIO_FN_SDIF1CD, GPIO_FN_SDIF1WP, GPIO_FN_SDIF1CLK,
+ GPIO_FN_SDIF1D3, GPIO_FN_SDIF1D2, GPIO_FN_SDIF1D1, GPIO_FN_SDIF1D0,
+
+ /* SDIF0 */
+ GPIO_FN_SDIF0CMD, GPIO_FN_SDIF0CD, GPIO_FN_SDIF0WP, GPIO_FN_SDIF0CLK,
+ GPIO_FN_SDIF0D3, GPIO_FN_SDIF0D2, GPIO_FN_SDIF0D1, GPIO_FN_SDIF0D0,
+
+ /* TMU */
+ GPIO_FN_TCLK,
+
+ /* INTC */
+ GPIO_FN_IRL7, GPIO_FN_IRL6, GPIO_FN_IRL5, GPIO_FN_IRL4,
};
#endif /* __CPU_SH7786_H__ */
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 55da0ff9848..3cb531f233f 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -254,40 +254,6 @@ restore_all:
lds k2, pr ! restore pr
!
-#ifdef CONFIG_SH_DSP
- mov.l @r15+, k0 ! DSP mode marker
- mov.l 5f, k1
- cmp/eq k0, k1 ! Do we have a DSP stack frame?
- bf skip_restore
-
- stc sr, k0 ! Enable CPU DSP mode
- or k1, k0 ! (within kernel it may be disabled)
- ldc k0, sr
- mov r2, k0 ! Backup r2
-
- ! Restore DSP registers from stack
- mov r15, r2
- movs.l @r2+, a1
- movs.l @r2+, a0g
- movs.l @r2+, a1g
- movs.l @r2+, m0
- movs.l @r2+, m1
- mov r2, r15
-
- lds.l @r15+, a0
- lds.l @r15+, x0
- lds.l @r15+, x1
- lds.l @r15+, y0
- lds.l @r15+, y1
- lds.l @r15+, dsr
- ldc.l @r15+, rs
- ldc.l @r15+, re
- ldc.l @r15+, mod
-
- mov k0, r2 ! Restore r2
-skip_restore:
-#endif
- !
! Calculate new SR value
mov k3, k2 ! original SR value
mov #0xf0, k1
@@ -358,7 +324,7 @@ general_exception:
add k0, k4
0:
! Setup stack and save DSP context (k0 contains original r15 on return)
- bsr prepare_stack_save_dsp
+ bsr prepare_stack
nop
! Save registers / Switch to bank 0
@@ -374,15 +340,14 @@ general_exception:
1: .long EXPEVT
#endif
-! prepare_stack_save_dsp()
+! prepare_stack()
! - roll back gRB
! - switch to kernel stack
-! - save DSP
! k0 returns original sp (after roll back)
! k1 trashed
! k2 trashed
-prepare_stack_save_dsp:
+prepare_stack:
#ifdef CONFIG_GUSA
! Check for roll back gRB (User and Kernel)
mov r15, k0
@@ -416,47 +381,9 @@ prepare_stack_save_dsp:
mov k1, r15 ! change to kernel stack
!
1:
-#ifdef CONFIG_SH_DSP
- ! Save DSP context if needed
- stc sr, k1
- mov #0x10, k2
- shll8 k2 ! DSP=1 (0x00001000)
- tst k2, k1 ! Check if in DSP mode (passed in k2)
- bt/s skip_save
- mov #0, k1 ! Set marker for no stack frame
-
- mov k2, k1 ! Save has-frame marker
-
- ! Save DSP registers on stack
- stc.l mod, @-r15
- stc.l re, @-r15
- stc.l rs, @-r15
- sts.l dsr, @-r15
- sts.l y1, @-r15
- sts.l y0, @-r15
- sts.l x1, @-r15
- sts.l x0, @-r15
- sts.l a0, @-r15
-
- ! GAS is broken, does not generate correct "movs.l Ds,@-As" instr.
-
- ! FIXME: Make sure that this is still the case with newer toolchains,
- ! as we're not at all interested in supporting ancient toolchains at
- ! this point. -- PFM.
-
- mov r15, k2
- .word 0xf653 ! movs.l a1, @-r2
- .word 0xf6f3 ! movs.l a0g, @-r2
- .word 0xf6d3 ! movs.l a1g, @-r2
- .word 0xf6c3 ! movs.l m0, @-r2
- .word 0xf6e3 ! movs.l m1, @-r2
- mov k2, r15
-
-skip_save:
- mov.l k1, @-r15 ! Push DSP mode marker onto stack
-#endif
rts
nop
+
!
! 0x400: Instruction and Data TLB miss exception vector
!
@@ -468,7 +395,7 @@ handle_exception:
mova exception_data, k0
! Setup stack and save DSP context (k0 contains original r15 on return)
- bsr prepare_stack_save_dsp
+ bsr prepare_stack
PREF(k0)
! Save registers / Switch to bank 0
@@ -572,7 +499,7 @@ ENTRY(handle_interrupt)
mova exception_data, k0
! Setup stack and save DSP context (k0 contains original r15 on return)
- bsr prepare_stack_save_dsp
+ bsr prepare_stack
PREF(k0)
! Save registers / Switch to bank 0
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 3d3a3c4425a..91e3677ae09 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -199,11 +199,6 @@ int __init detect_cpu_and_cache_system(void)
break;
}
-#ifdef CONFIG_SH_DIRECT_MAPPED
- boot_cpu_data.icache.ways = 1;
- boot_cpu_data.dcache.ways = 1;
-#endif
-
#ifdef CONFIG_CPU_HAS_PTEA
boot_cpu_data.flags |= CPU_HAS_PTEA;
#endif
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c
index 373b3447bfd..4229e0724c8 100644
--- a/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c
@@ -149,150 +149,44 @@ enum {
PINMUX_FUNCTION_END,
PINMUX_MARK_BEGIN,
- CDE_MARK,
- ETH_MAGIC_MARK,
- DISP_MARK,
- ETH_LINK_MARK,
- DR5_MARK,
- ETH_TX_ER_MARK,
- DR4_MARK,
- ETH_TX_EN_MARK,
- DR3_MARK,
- ETH_TXD3_MARK,
- DR2_MARK,
- ETH_TXD2_MARK,
- DR1_MARK,
- ETH_TXD1_MARK,
- DR0_MARK,
- ETH_TXD0_MARK,
-
- VSYNC_MARK,
- HSPI_CLK_MARK,
- ODDF_MARK,
- HSPI_CS_MARK,
- DG5_MARK,
- ETH_MDIO_MARK,
- DG4_MARK,
- ETH_RX_CLK_MARK,
- DG3_MARK,
- ETH_MDC_MARK,
- DG2_MARK,
- ETH_COL_MARK,
- DG1_MARK,
- ETH_TX_CLK_MARK,
- DG0_MARK,
- ETH_CRS_MARK,
-
- DCLKIN_MARK,
- HSPI_RX_MARK,
- HSYNC_MARK,
- HSPI_TX_MARK,
- DB5_MARK,
- ETH_RXD3_MARK,
- DB4_MARK,
- ETH_RXD2_MARK,
- DB3_MARK,
- ETH_RXD1_MARK,
- DB2_MARK,
- ETH_RXD0_MARK,
- DB1_MARK,
- ETH_RX_DV_MARK,
- DB0_MARK,
- ETH_RX_ER_MARK,
-
- DCLKOUT_MARK,
- SCIF1_SLK_MARK,
- SCIF1_RXD_MARK,
- SCIF1_TXD_MARK,
- DACK1_MARK,
- BACK_MARK,
- FALE_MARK,
- DACK0_MARK,
- FCLE_MARK,
- DREQ1_MARK,
- BREQ_MARK,
- USB_OVC1_MARK,
- DREQ0_MARK,
- USB_OVC0_MARK,
-
- USB_PENC1_MARK,
- USB_PENC0_MARK,
-
- HAC1_SDOUT_MARK,
- SSI1_SDATA_MARK,
- SDIF1CMD_MARK,
- HAC1_SDIN_MARK,
- SSI1_SCK_MARK,
- SDIF1CD_MARK,
- HAC1_SYNC_MARK,
- SSI1_WS_MARK,
- SDIF1WP_MARK,
- HAC1_BITCLK_MARK,
- SSI1_CLK_MARK,
- SDIF1CLK_MARK,
- HAC0_SDOUT_MARK,
- SSI0_SDATA_MARK,
- SDIF1D3_MARK,
- HAC0_SDIN_MARK,
- SSI0_SCK_MARK,
- SDIF1D2_MARK,
- HAC0_SYNC_MARK,
- SSI0_WS_MARK,
- SDIF1D1_MARK,
- HAC0_BITCLK_MARK,
- SSI0_CLK_MARK,
- SDIF1D0_MARK,
-
- SCIF3_SCK_MARK,
- SSI2_SDATA_MARK,
- SCIF3_RXD_MARK,
- TCLK_MARK,
- SSI2_SCK_MARK,
- SCIF3_TXD_MARK,
+ DCLKIN_MARK, DCLKOUT_MARK, ODDF_MARK,
+ VSYNC_MARK, HSYNC_MARK, CDE_MARK, DISP_MARK,
+ DR0_MARK, DR1_MARK, DR2_MARK, DR3_MARK, DR4_MARK, DR5_MARK,
+ DG0_MARK, DG1_MARK, DG2_MARK, DG3_MARK, DG4_MARK, DG5_MARK,
+ DB0_MARK, DB1_MARK, DB2_MARK, DB3_MARK, DB4_MARK, DB5_MARK,
+ ETH_MAGIC_MARK, ETH_LINK_MARK, ETH_TX_ER_MARK, ETH_TX_EN_MARK,
+ ETH_MDIO_MARK, ETH_RX_CLK_MARK, ETH_MDC_MARK, ETH_COL_MARK,
+ ETH_TX_CLK_MARK, ETH_CRS_MARK, ETH_RX_DV_MARK, ETH_RX_ER_MARK,
+ ETH_TXD3_MARK, ETH_TXD2_MARK, ETH_TXD1_MARK, ETH_TXD0_MARK,
+ ETH_RXD3_MARK, ETH_RXD2_MARK, ETH_RXD1_MARK, ETH_RXD0_MARK,
+ HSPI_CLK_MARK, HSPI_CS_MARK, HSPI_RX_MARK, HSPI_TX_MARK,
+ SCIF0_CTS_MARK, SCIF0_RTS_MARK,
+ SCIF0_SCK_MARK, SCIF0_RXD_MARK, SCIF0_TXD_MARK,
+ SCIF1_SCK_MARK, SCIF1_RXD_MARK, SCIF1_TXD_MARK,
+ SCIF3_SCK_MARK, SCIF3_RXD_MARK, SCIF3_TXD_MARK,
+ SCIF4_SCK_MARK, SCIF4_RXD_MARK, SCIF4_TXD_MARK,
+ SCIF5_SCK_MARK, SCIF5_RXD_MARK, SCIF5_TXD_MARK,
+ BREQ_MARK, IOIS16_MARK, CE2B_MARK, CE2A_MARK, BACK_MARK,
+ FALE_MARK, FRB_MARK, FSTATUS_MARK,
+ FSE_MARK, FCLE_MARK,
+ DACK0_MARK, DACK1_MARK, DACK2_MARK, DACK3_MARK,
+ DREQ0_MARK, DREQ1_MARK, DREQ2_MARK, DREQ3_MARK,
+ DRAK0_MARK, DRAK1_MARK, DRAK2_MARK, DRAK3_MARK,
+ USB_OVC1_MARK, USB_OVC0_MARK,
+ USB_PENC1_MARK, USB_PENC0_MARK,
HAC_RES_MARK,
- SSI2_WS_MARK,
-
- DACK3_MARK,
- SDIF0CMD_MARK,
- DACK2_MARK,
- SDIF0CD_MARK,
- DREQ3_MARK,
- SDIF0WP_MARK,
- SCIF0_CTS_MARK,
- DREQ2_MARK,
- SDIF0CLK_MARK,
- SCIF0_RTS_MARK,
- IRL7_MARK,
- SDIF0D3_MARK,
- SCIF0_SCK_MARK,
- IRL6_MARK,
- SDIF0D2_MARK,
- SCIF0_RXD_MARK,
- IRL5_MARK,
- SDIF0D1_MARK,
- SCIF0_TXD_MARK,
- IRL4_MARK,
- SDIF0D0_MARK,
-
- SCIF5_SCK_MARK,
- FRB_MARK,
- SCIF5_RXD_MARK,
- IOIS16_MARK,
- SCIF5_TXD_MARK,
- CE2B_MARK,
- DRAK3_MARK,
- CE2A_MARK,
- SCIF4_SCK_MARK,
- DRAK2_MARK,
- SSI3_WS_MARK,
- SCIF4_RXD_MARK,
- DRAK1_MARK,
- SSI3_SDATA_MARK,
- FSTATUS_MARK,
- SCIF4_TXD_MARK,
- DRAK0_MARK,
- SSI3_SCK_MARK,
- FSE_MARK,
+ HAC1_SDOUT_MARK, HAC1_SDIN_MARK, HAC1_SYNC_MARK, HAC1_BITCLK_MARK,
+ HAC0_SDOUT_MARK, HAC0_SDIN_MARK, HAC0_SYNC_MARK, HAC0_BITCLK_MARK,
+ SSI0_SDATA_MARK, SSI0_SCK_MARK, SSI0_WS_MARK, SSI0_CLK_MARK,
+ SSI1_SDATA_MARK, SSI1_SCK_MARK, SSI1_WS_MARK, SSI1_CLK_MARK,
+ SSI2_SDATA_MARK, SSI2_SCK_MARK, SSI2_WS_MARK,
+ SSI3_SDATA_MARK, SSI3_SCK_MARK, SSI3_WS_MARK,
+ SDIF1CMD_MARK, SDIF1CD_MARK, SDIF1WP_MARK, SDIF1CLK_MARK,
+ SDIF1D3_MARK, SDIF1D2_MARK, SDIF1D1_MARK, SDIF1D0_MARK,
+ SDIF0CMD_MARK, SDIF0CD_MARK, SDIF0WP_MARK, SDIF0CLK_MARK,
+ SDIF0D3_MARK, SDIF0D2_MARK, SDIF0D1_MARK, SDIF0D0_MARK,
+ TCLK_MARK,
+ IRL7_MARK, IRL6_MARK, IRL5_MARK, IRL4_MARK,
PINMUX_MARK_END,
};
@@ -377,7 +271,6 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(PJ1_DATA, PJ1_IN, PJ1_OUT, PJ1_IN_PU),
/* PA FN */
- PINMUX_MARK_BEGIN,
PINMUX_DATA(CDE_MARK, P1MSEL2_0, PA7_FN),
PINMUX_DATA(DISP_MARK, P1MSEL2_0, PA6_FN),
PINMUX_DATA(DR5_MARK, P1MSEL2_0, PA5_FN),
@@ -434,7 +327,7 @@ static pinmux_enum_t pinmux_data[] = {
/* PD FN */
PINMUX_DATA(DCLKOUT_MARK, PD7_FN),
- PINMUX_DATA(SCIF1_SLK_MARK, PD6_FN),
+ PINMUX_DATA(SCIF1_SCK_MARK, PD6_FN),
PINMUX_DATA(SCIF1_RXD_MARK, PD5_FN),
PINMUX_DATA(SCIF1_TXD_MARK, PD4_FN),
PINMUX_DATA(DACK1_MARK, P1MSEL13_1, P1MSEL12_0, PD3_FN),
@@ -662,7 +555,7 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_DB0, DB0_MARK),
PINMUX_GPIO(GPIO_FN_ETH_RX_ER, ETH_RX_ER_MARK),
PINMUX_GPIO(GPIO_FN_DCLKOUT, DCLKOUT_MARK),
- PINMUX_GPIO(GPIO_FN_SCIF1_SLK, SCIF1_SLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_SCK, SCIF1_SCK_MARK),
PINMUX_GPIO(GPIO_FN_SCIF1_RXD, SCIF1_RXD_MARK),
PINMUX_GPIO(GPIO_FN_SCIF1_TXD, SCIF1_TXD_MARK),
PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK),
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
index 5a47e1cf442..90e8cfff55f 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -143,14 +143,14 @@ static void __init sh7786_usb_setup(void)
* Set the PHY and PLL enable bit
*/
__raw_writel(PHY_ENB | PLL_ENB, USBPCTL1);
- while (i-- &&
- ((__raw_readl(USBST) & ACT_PLL_STATUS) != ACT_PLL_STATUS))
+ while (i--) {
+ if (ACT_PLL_STATUS == (__raw_readl(USBST) & ACT_PLL_STATUS)) {
+ /* Set the PHY RST bit */
+ __raw_writel(PHY_ENB | PLL_ENB | PHY_RST, USBPCTL1);
+ printk(KERN_INFO "sh7786 usb setup done\n");
+ break;
+ }
cpu_relax();
-
- if (i) {
- /* Set the PHY RST bit */
- __raw_writel(PHY_ENB | PLL_ENB | PHY_RST, USBPCTL1);
- printk(KERN_INFO "sh7786 usb setup done\n");
}
}
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index fe59ccfc115..f35ed034885 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -38,7 +38,7 @@ static int __init hlt_setup(char *__unused)
}
__setup("hlt", hlt_setup);
-static void default_idle(void)
+void default_idle(void)
{
if (!hlt_counter) {
clear_thread_flag(TIF_POLLING_NRFLAG);
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index 39cd7f3aec7..c22853b059e 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -14,6 +14,7 @@
#include <linux/bitops.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/uaccess.h>
@@ -32,6 +33,15 @@ EXPORT_SYMBOL_GPL(trapped_mem);
#endif
static DEFINE_SPINLOCK(trapped_lock);
+static int trapped_io_disable __read_mostly;
+
+static int __init trapped_io_setup(char *__unused)
+{
+ trapped_io_disable = 1;
+ return 1;
+}
+__setup("noiotrap", trapped_io_setup);
+
int register_trapped_io(struct trapped_io *tiop)
{
struct resource *res;
@@ -39,6 +49,9 @@ int register_trapped_io(struct trapped_io *tiop)
struct page *pages[TRAPPED_PAGES_MAX];
int k, n;
+ if (unlikely(trapped_io_disable))
+ return 0;
+
/* structure must be page aligned */
if ((unsigned long)tiop & (PAGE_SIZE - 1))
goto bad;
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 694bc15f84f..6d94725d22f 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -176,14 +176,26 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
{
struct thread_info *ti = task_thread_info(p);
struct pt_regs *childregs;
-#if defined(CONFIG_SH_FPU)
+#if defined(CONFIG_SH_FPU) || defined(CONFIG_SH_DSP)
struct task_struct *tsk = current;
+#endif
+#if defined(CONFIG_SH_FPU)
unlazy_fpu(tsk, regs);
p->thread.fpu = tsk->thread.fpu;
copy_to_stopped_child_used_math(p);
#endif
+#if defined(CONFIG_SH_DSP)
+ if (is_dsp_enabled(tsk)) {
+ /* We can use the __save_dsp or just copy the struct:
+ * __save_dsp(p);
+ * p->thread.dsp_status.status |= SR_DSP
+ */
+ p->thread.dsp_status = tsk->thread.dsp_status;
+ }
+#endif
+
childregs = task_pt_regs(p);
*childregs = *regs;
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 29ca09d24ef..f7b22dd83b0 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -200,7 +200,8 @@ static int dspregs_get(struct task_struct *target,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
{
- const struct pt_dspregs *regs = task_pt_dspregs(target);
+ const struct pt_dspregs *regs =
+ (struct pt_dspregs *)&target->thread.dsp_status.dsp_regs;
int ret;
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs,
@@ -217,7 +218,8 @@ static int dspregs_set(struct task_struct *target,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
- struct pt_dspregs *regs = task_pt_dspregs(target);
+ struct pt_dspregs *regs =
+ (struct pt_dspregs *)&target->thread.dsp_status.dsp_regs;
int ret;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs,
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 24c60251f68..04a6004fccc 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -103,12 +103,11 @@ static int __init early_parse_mem(char *p)
size = memparse(p, &p);
if (size > __MEMORY_SIZE) {
- static char msg[] __initdata = KERN_ERR
+ printk(KERN_ERR
"Using mem= to increase the size of kernel memory "
"is not allowed.\n"
" Recompile the kernel with the correct value for "
- "CONFIG_MEMORY_SIZE.\n";
- printk(msg);
+ "CONFIG_MEMORY_SIZE.\n");
return 0;
}
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S
index e67c1733e1b..05202edd8e2 100644
--- a/arch/sh/kernel/syscalls_32.S
+++ b/arch/sh/kernel/syscalls_32.S
@@ -349,3 +349,5 @@ ENTRY(sys_call_table)
.long sys_dup3 /* 330 */
.long sys_pipe2
.long sys_inotify_init1
+ .long sys_preadv
+ .long sys_writev
diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S
index 557cb91f5ca..a083609f928 100644
--- a/arch/sh/kernel/syscalls_64.S
+++ b/arch/sh/kernel/syscalls_64.S
@@ -387,3 +387,5 @@ sys_call_table:
.long sys_dup3
.long sys_pipe2
.long sys_inotify_init1 /* 360 */
+ .long sys_preadv
+ .long sys_pwritev
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 60dcf87ed01..30ca9c51e52 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -664,6 +664,8 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
if (is_dsp_inst(regs)) {
/* Enable DSP mode, and restart instruction. */
regs->sr |= SR_DSP;
+ /* Save DSP mode */
+ tsk->thread.dsp_status.status |= SR_DSP;
return;
}
#endif
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 10c24356d2d..d4079cab2d5 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -251,18 +251,6 @@ config SH7705_CACHE_32KB
depends on CPU_SUBTYPE_SH7705
default y
-config SH_DIRECT_MAPPED
- bool "Use direct-mapped caching"
- default n
- help
- Selecting this option will configure the caches to be direct-mapped,
- even if the cache supports a 2 or 4-way mode. This is useful primarily
- for debugging on platforms with 2 and 4-way caches (SH7750R/SH7751R,
- SH4-202, SH4-501, etc.)
-
- Turn this option off for platforms that do not have a direct-mapped
- cache, and you have no need to run the caches in such a configuration.
-
choice
prompt "Cache mode"
default CACHE_WRITEBACK if CPU_SH2A || CPU_SH3 || CPU_SH4 || CPU_SH5
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index edcd5fbf965..e098ec158dd 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -10,11 +10,22 @@
* for more details.
*/
#include <linux/mm.h>
+#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/dma-debug.h>
+#include <linux/io.h>
#include <asm/cacheflush.h>
#include <asm/addrspace.h>
-#include <asm/io.h>
+
+#define PREALLOC_DMA_DEBUG_ENTRIES 4096
+
+static int __init dma_init(void)
+{
+ dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+ return 0;
+}
+fs_initcall(dma_init);
void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp)
@@ -45,6 +56,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order);
*dma_handle = virt_to_phys(ret);
+
+ debug_dma_alloc_coherent(dev, size, *dma_handle, ret_nocache);
+
return ret_nocache;
}
EXPORT_SYMBOL(dma_alloc_coherent);
@@ -56,12 +70,15 @@ void dma_free_coherent(struct device *dev, size_t size,
unsigned long pfn = dma_handle >> PAGE_SHIFT;
int k;
- if (!dma_release_from_coherent(dev, order, vaddr)) {
- WARN_ON(irqs_disabled()); /* for portability */
- for (k = 0; k < (1 << order); k++)
- __free_pages(pfn_to_page(pfn + k), 0);
- iounmap(vaddr);
- }
+ WARN_ON(irqs_disabled()); /* for portability */
+
+ if (dma_release_from_coherent(dev, order, vaddr))
+ return;
+
+ debug_dma_free_coherent(dev, size, vaddr, dma_handle);
+ for (k = 0; k < (1 << order); k++)
+ __free_pages(pfn_to_page(pfn + k), 0);
+ iounmap(vaddr);
}
EXPORT_SYMBOL(dma_free_coherent);
diff --git a/arch/sparc/include/asm/mmzone.h b/arch/sparc/include/asm/mmzone.h
index ebf5986c12e..e8c648741ed 100644
--- a/arch/sparc/include/asm/mmzone.h
+++ b/arch/sparc/include/asm/mmzone.h
@@ -3,6 +3,8 @@
#ifdef CONFIG_NEED_MULTIPLE_NODES
+#include <linux/cpumask.h>
+
extern struct pglist_data *node_data[];
#define NODE_DATA(nid) (node_data[nid])
diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h
index dff3f0253aa..ff9ead640c4 100644
--- a/arch/sparc/include/asm/parport.h
+++ b/arch/sparc/include/asm/parport.h
@@ -117,7 +117,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id
if (!strcmp(parent->name, "dma")) {
p = parport_pc_probe_port(base, base + 0x400,
op->irqs[0], PARPORT_DMA_NOFIFO,
- op->dev.parent->parent);
+ op->dev.parent->parent, 0);
if (!p)
return -ENOMEM;
dev_set_drvdata(&op->dev, p);
@@ -168,7 +168,8 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id
p = parport_pc_probe_port(base, base + 0x400,
op->irqs[0],
slot,
- op->dev.parent);
+ op->dev.parent,
+ 0);
err = -ENOMEM;
if (!p)
goto out_disable_irq;
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index 031f038b19f..b8eb71ef316 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -392,8 +392,10 @@
#define __NR_pipe2 321
#define __NR_inotify_init1 322
#define __NR_accept4 323
+#define __NR_preadv 324
+#define __NR_pwritev 325
-#define NR_SYSCALLS 324
+#define NR_SYSCALLS 326
#ifdef __32bit_syscall_numbers__
/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
index a46c3a21e26..3a1b7bf03cf 100644
--- a/arch/sparc/kernel/head_64.S
+++ b/arch/sparc/kernel/head_64.S
@@ -686,7 +686,7 @@ tlb_fixup_done:
* point.
*
* There used to be enormous complexity wrt. transferring
- * over from the firwmare's trap table to the Linux kernel's.
+ * over from the firmware's trap table to the Linux kernel's.
* For example, there was a chicken & egg problem wrt. building
* the OBP page tables, yet needing to be on the Linux kernel
* trap table (to translate PAGE_OFFSET addresses) in order to
diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c
index b4a12c9aa5f..27381f1baff 100644
--- a/arch/sparc/kernel/of_device_64.c
+++ b/arch/sparc/kernel/of_device_64.c
@@ -99,8 +99,7 @@ static inline u64 of_read_addr(const u32 *cell, int size)
return r;
}
-static void __init get_cells(struct device_node *dp,
- int *addrc, int *sizec)
+static void get_cells(struct device_node *dp, int *addrc, int *sizec)
{
if (addrc)
*addrc = of_n_addr_cells(dp);
diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c
index 9462b68f489..d53f45bc7dd 100644
--- a/arch/sparc/kernel/pci_fire.c
+++ b/arch/sparc/kernel/pci_fire.c
@@ -409,8 +409,8 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm)
upa_writeq(~(u64)0, pbm->pbm_regs + FIRE_PEC_IENAB);
}
-static int __init pci_fire_pbm_init(struct pci_pbm_info *pbm,
- struct of_device *op, u32 portid)
+static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm,
+ struct of_device *op, u32 portid)
{
const struct linux_prom64_registers *regs;
struct device_node *dp = op->node;
diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c
index 3b34344082e..142b9d6984a 100644
--- a/arch/sparc/kernel/pci_psycho.c
+++ b/arch/sparc/kernel/pci_psycho.c
@@ -365,8 +365,8 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm)
pci_config_write8(addr, 64);
}
-static void __init psycho_scan_bus(struct pci_pbm_info *pbm,
- struct device *parent)
+static void __devinit psycho_scan_bus(struct pci_pbm_info *pbm,
+ struct device *parent)
{
pbm_config_busmastering(pbm);
pbm->is_66mhz_capable = 0;
@@ -482,8 +482,8 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm,
#define PSYCHO_MEMSPACE_B 0x180000000UL
#define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL
-static void __init psycho_pbm_init(struct pci_pbm_info *pbm,
- struct of_device *op, int is_pbm_a)
+static void __devinit psycho_pbm_init(struct pci_pbm_info *pbm,
+ struct of_device *op, int is_pbm_a)
{
psycho_pbm_init_common(pbm, op, "PSYCHO", PBM_CHIP_TYPE_PSYCHO);
psycho_pbm_strbuf_init(pbm, is_pbm_a);
diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c
index 713257b6963..ba6fbeba3e2 100644
--- a/arch/sparc/kernel/pci_sabre.c
+++ b/arch/sparc/kernel/pci_sabre.c
@@ -402,8 +402,8 @@ static void apb_init(struct pci_bus *sabre_bus)
}
}
-static void __init sabre_scan_bus(struct pci_pbm_info *pbm,
- struct device *parent)
+static void __devinit sabre_scan_bus(struct pci_pbm_info *pbm,
+ struct device *parent)
{
static int once;
@@ -442,8 +442,8 @@ static void __init sabre_scan_bus(struct pci_pbm_info *pbm,
sabre_register_error_handlers(pbm);
}
-static void __init sabre_pbm_init(struct pci_pbm_info *pbm,
- struct of_device *op)
+static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm,
+ struct of_device *op)
{
psycho_pbm_init_common(pbm, op, "SABRE", PBM_CHIP_TYPE_SABRE);
pbm->pci_afsr = pbm->controller_regs + SABRE_PIOAFSR;
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index 0ef0ab3d476..5db5ebed35d 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -545,8 +545,8 @@ static const struct dma_ops sun4v_dma_ops = {
.sync_sg_for_cpu = dma_4v_sync_sg_for_cpu,
};
-static void __init pci_sun4v_scan_bus(struct pci_pbm_info *pbm,
- struct device *parent)
+static void __devinit pci_sun4v_scan_bus(struct pci_pbm_info *pbm,
+ struct device *parent)
{
struct property *prop;
struct device_node *dp;
@@ -559,8 +559,8 @@ static void __init pci_sun4v_scan_bus(struct pci_pbm_info *pbm,
/* XXX register error interrupt handlers XXX */
}
-static unsigned long __init probe_existing_entries(struct pci_pbm_info *pbm,
- struct iommu *iommu)
+static unsigned long __devinit probe_existing_entries(struct pci_pbm_info *pbm,
+ struct iommu *iommu)
{
struct iommu_arena *arena = &iommu->arena;
unsigned long i, cnt = 0;
@@ -587,7 +587,7 @@ static unsigned long __init probe_existing_entries(struct pci_pbm_info *pbm,
return cnt;
}
-static int __init pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
+static int __devinit pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
{
static const u32 vdma_default[] = { 0x80000000, 0x80000000 };
struct iommu *iommu = pbm->iommu;
@@ -889,8 +889,8 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
}
#endif /* !(CONFIG_PCI_MSI) */
-static int __init pci_sun4v_pbm_init(struct pci_pbm_info *pbm,
- struct of_device *op, u32 devhandle)
+static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm,
+ struct of_device *op, u32 devhandle)
{
struct device_node *dp = op->node;
int err;
diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c
index ae88f06a7ec..e2a045c235a 100644
--- a/arch/sparc/kernel/power.c
+++ b/arch/sparc/kernel/power.c
@@ -23,7 +23,7 @@ static irqreturn_t power_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __init has_button_interrupt(unsigned int irq, struct device_node *dp)
+static int __devinit has_button_interrupt(unsigned int irq, struct device_node *dp)
{
if (irq == 0xffffffff)
return 0;
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S
index dccc95df0c7..00ec3b15f38 100644
--- a/arch/sparc/kernel/systbls_32.S
+++ b/arch/sparc/kernel/systbls_32.S
@@ -81,4 +81,4 @@ sys_call_table:
/*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
/*315*/ .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
-/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4
+/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv, sys_pwritev
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index a8000b1cda7..82b5bf85b9d 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -82,7 +82,7 @@ sys_call_table32:
.word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait
/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate
.word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1
-/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4
+/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv, compat_sys_pwritev
#endif /* CONFIG_COMPAT */
@@ -156,4 +156,4 @@ sys_call_table:
.word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
.word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
-/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4
+/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv, sys_pwritev
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 2c8dfeb7ab0..f26a352c08a 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -70,8 +70,8 @@ extern struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES];
#define MAX_BANKS 32
-static struct linux_prom64_registers pavail[MAX_BANKS] __initdata;
-static int pavail_ents __initdata;
+static struct linux_prom64_registers pavail[MAX_BANKS] __devinitdata;
+static int pavail_ents __devinitdata;
static int cmp_p64(const void *a, const void *b)
{
@@ -968,7 +968,7 @@ int of_node_to_nid(struct device_node *dp)
return nid;
}
-static void add_node_ranges(void)
+static void __init add_node_ranges(void)
{
int i;
@@ -1841,7 +1841,7 @@ void __init paging_init(void)
printk("Booting Linux...\n");
}
-int __init page_in_phys_avail(unsigned long paddr)
+int __devinit page_in_phys_avail(unsigned long paddr)
{
int i;
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index d42f826a8ab..f934225fd8e 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -22,6 +22,7 @@
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/blkdev.h"
+#include "linux/ata.h"
#include "linux/hdreg.h"
#include "linux/init.h"
#include "linux/cdrom.h"
@@ -1308,16 +1309,15 @@ static int ubd_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
struct ubd *ubd_dev = bdev->bd_disk->private_data;
- struct hd_driveid ubd_id = {
- .cyls = 0,
- .heads = 128,
- .sectors = 32,
- };
+ u16 ubd_id[ATA_ID_WORDS];
switch (cmd) {
struct cdrom_volctrl volume;
case HDIO_GET_IDENTITY:
- ubd_id.cyls = ubd_dev->size / (128 * 32 * 512);
+ memset(&ubd_id, 0, ATA_ID_WORDS * 2);
+ ubd_id[ATA_ID_CYLS] = ubd_dev->size / (128 * 32 * 512);
+ ubd_id[ATA_ID_HEADS] = 128;
+ ubd_id[ATA_ID_SECTORS] = 32;
if(copy_to_user((char __user *) arg, (char *) &ubd_id,
sizeof(ubd_id)))
return -EFAULT;
diff --git a/arch/um/include/asm/ftrace.h b/arch/um/include/asm/ftrace.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/um/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 748e50a1a15..bc25b9f5e4c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -34,6 +34,8 @@ config X86
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
+ select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE
+ select HAVE_FTRACE_SYSCALLS
select HAVE_KVM
select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK
@@ -250,16 +252,13 @@ config SMP
config X86_X2APIC
bool "Support x2apic"
- depends on X86_LOCAL_APIC && X86_64
+ depends on X86_LOCAL_APIC && X86_64 && INTR_REMAP
---help---
This enables x2apic support on CPUs that have this feature.
This allows 32-bit apic IDs (so it can support very large systems),
and accesses the local apic via MSRs not via mmio.
- ( On certain CPU models you may need to enable INTR_REMAP too,
- to get functional x2apic mode. )
-
If you don't know what to do here, say N.
config SPARSE_IRQ
@@ -1144,7 +1143,7 @@ config NODES_SHIFT
depends on NEED_MULTIPLE_NODES
---help---
Specify the maximum number of NUMA Nodes available on the target
- system. Increases memory reserved to accomodate various tables.
+ system. Increases memory reserved to accommodate various tables.
config HAVE_ARCH_BOOTMEM
def_bool y
@@ -1322,7 +1321,7 @@ config MTRR_SANITIZER
add writeback entries.
Can be disabled with disable_mtrr_cleanup on the kernel command line.
- The largest mtrr entry size for a continous block can be set with
+ The largest mtrr entry size for a continuous block can be set with
mtrr_chunk_size.
If unsure, say Y.
@@ -1837,8 +1836,8 @@ config PCI_MMCONFIG
config DMAR
bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
- depends on X86_64 && PCI_MSI && ACPI && EXPERIMENTAL
- ---help---
+ depends on PCI_MSI && ACPI && EXPERIMENTAL
+ help
DMA remapping (DMAR) devices support enables independent address
translations for Direct Memory Access (DMA) from devices.
These DMA remapping devices are reported via ACPI tables
@@ -1879,7 +1878,6 @@ config DMAR_FLOPPY_WA
config INTR_REMAP
bool "Support for Interrupt Remapping (EXPERIMENTAL)"
depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
- select X86_X2APIC
---help---
Supports Interrupt remapping for IO-APIC and MSI devices.
To use x2apic mode in the CPU's which support x2APIC enhancements or
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index fb737ce5888..6633b6e7505 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -57,6 +57,7 @@ $(obj)/cpustr.h: $(obj)/mkcpustr FORCE
# How to compile the 16-bit code. Note we always compile for -march=i386,
# that way we can complain to the user if the CPU is insufficient.
KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
+ -DDISABLE_BRANCH_PROFILING \
-Wall -Wstrict-prototypes \
-march=i386 -mregparm=3 \
-include $(srctree)/$(src)/code16gcc.h \
@@ -66,7 +67,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
$(call cc-option, -fno-unit-at-a-time)) \
$(call cc-option, -fno-stack-protector) \
$(call cc-option, -mpreferred-stack-boundary=2)
-KBUILD_CFLAGS += $(call cc-option,-m32)
+KBUILD_CFLAGS += $(call cc-option, -m32)
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
$(obj)/bzImage: asflags-y := $(SVGA_MODE)
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 3ca4c194b8e..65551c9f857 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -8,6 +8,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma h
KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
+KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
cflags-$(CONFIG_X86_64) := -mcmodel=small
KBUILD_CFLAGS += $(cflags-y)
KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
diff --git a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c
index 95d86ce0421..9e0587a3776 100644
--- a/arch/x86/boot/video-vga.c
+++ b/arch/x86/boot/video-vga.c
@@ -129,22 +129,18 @@ u16 vga_crtc(void)
return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
}
-static void vga_set_480_scanlines(int lines)
+static void vga_set_480_scanlines(void)
{
u16 crtc; /* CRTC base address */
u8 csel; /* CRTC miscellaneous output register */
- u8 ovfw; /* CRTC overflow register */
- int end = lines-1;
crtc = vga_crtc();
- ovfw = 0x3c | ((end >> (8-1)) & 0x02) | ((end >> (9-6)) & 0x40);
-
out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */
out_idx(0x0b, crtc, 0x06); /* Vertical total */
- out_idx(ovfw, crtc, 0x07); /* Vertical overflow */
+ out_idx(0x3e, crtc, 0x07); /* Vertical overflow */
out_idx(0xea, crtc, 0x10); /* Vertical sync start */
- out_idx(end, crtc, 0x12); /* Vertical display end */
+ out_idx(0xdf, crtc, 0x12); /* Vertical display end */
out_idx(0xe7, crtc, 0x15); /* Vertical blank start */
out_idx(0x04, crtc, 0x16); /* Vertical blank end */
csel = inb(0x3cc);
@@ -153,21 +149,38 @@ static void vga_set_480_scanlines(int lines)
outb(csel, 0x3c2);
}
+static void vga_set_vertical_end(int lines)
+{
+ u16 crtc; /* CRTC base address */
+ u8 ovfw; /* CRTC overflow register */
+ int end = lines-1;
+
+ crtc = vga_crtc();
+
+ ovfw = 0x3c | ((end >> (8-1)) & 0x02) | ((end >> (9-6)) & 0x40);
+
+ out_idx(ovfw, crtc, 0x07); /* Vertical overflow */
+ out_idx(end, crtc, 0x12); /* Vertical display end */
+}
+
static void vga_set_80x30(void)
{
- vga_set_480_scanlines(30*16);
+ vga_set_480_scanlines();
+ vga_set_vertical_end(30*16);
}
static void vga_set_80x34(void)
{
+ vga_set_480_scanlines();
vga_set_14font();
- vga_set_480_scanlines(34*14);
+ vga_set_vertical_end(34*14);
}
static void vga_set_80x60(void)
{
+ vga_set_480_scanlines();
vga_set_8font();
- vga_set_480_scanlines(60*8);
+ vga_set_vertical_end(60*8);
}
static int vga_set_mode(struct mode_info *mode)
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index df8a300dfe6..42f2f837742 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -107,6 +107,9 @@ extern u32 native_safe_apic_wait_icr_idle(void);
extern void native_apic_icr_write(u32 low, u32 id);
extern u64 native_apic_icr_read(void);
+#define EIM_8BIT_APIC_ID 0
+#define EIM_32BIT_APIC_ID 1
+
#ifdef CONFIG_X86_X2APIC
/*
* Make previous memory operations globally visible before
diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h
index b3894bf52fc..e55dfc1ad45 100644
--- a/arch/x86/include/asm/cacheflush.h
+++ b/arch/x86/include/asm/cacheflush.h
@@ -126,6 +126,11 @@ void clflush_cache_range(void *addr, unsigned int size);
#ifdef CONFIG_DEBUG_RODATA
void mark_rodata_ro(void);
extern const int rodata_test_data;
+void set_kernel_text_rw(void);
+void set_kernel_text_ro(void);
+#else
+static inline void set_kernel_text_rw(void) { }
+static inline void set_kernel_text_ro(void) { }
#endif
#ifdef CONFIG_DEBUG_RODATA_TEST
diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
index 222802029fa..222802029fa 100755..100644
--- a/arch/x86/include/asm/cpu_debug.h
+++ b/arch/x86/include/asm/cpu_debug.h
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 0beba0d1468..bb83b1c397a 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -154,6 +154,7 @@
* CPUID levels like 0x6, 0xA etc
*/
#define X86_FEATURE_IDA (7*32+ 0) /* Intel Dynamic Acceleration */
+#define X86_FEATURE_ARAT (7*32+ 1) /* Always Running APIC Timer */
/* Virtualization flags: Linux defined */
#define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */
diff --git a/arch/x86/include/asm/cpumask.h b/arch/x86/include/asm/cpumask.h
index a7f3c75f8ad..61c852fa346 100644
--- a/arch/x86/include/asm/cpumask.h
+++ b/arch/x86/include/asm/cpumask.h
@@ -3,8 +3,6 @@
#ifndef __ASSEMBLY__
#include <linux/cpumask.h>
-#ifdef CONFIG_X86_64
-
extern cpumask_var_t cpu_callin_mask;
extern cpumask_var_t cpu_callout_mask;
extern cpumask_var_t cpu_initialized_mask;
@@ -12,21 +10,5 @@ extern cpumask_var_t cpu_sibling_setup_mask;
extern void setup_cpu_local_masks(void);
-#else /* CONFIG_X86_32 */
-
-extern cpumask_t cpu_callin_map;
-extern cpumask_t cpu_callout_map;
-extern cpumask_t cpu_initialized;
-extern cpumask_t cpu_sibling_setup_map;
-
-#define cpu_callin_mask ((struct cpumask *)&cpu_callin_map)
-#define cpu_callout_mask ((struct cpumask *)&cpu_callout_map)
-#define cpu_initialized_mask ((struct cpumask *)&cpu_initialized)
-#define cpu_sibling_setup_mask ((struct cpumask *)&cpu_sibling_setup_map)
-
-static inline void setup_cpu_local_masks(void) { }
-
-#endif /* CONFIG_X86_32 */
-
#endif /* __ASSEMBLY__ */
#endif /* _ASM_X86_CPUMASK_H */
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index cea7b74963e..f82fdc412c6 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -238,7 +238,7 @@ static inline unsigned long dma_alloc_coherent_mask(struct device *dev,
dma_mask = dev->coherent_dma_mask;
if (!dma_mask)
- dma_mask = (gfp & GFP_DMA) ? DMA_24BIT_MASK : DMA_32BIT_MASK;
+ dma_mask = (gfp & GFP_DMA) ? DMA_BIT_MASK(24) : DMA_BIT_MASK(32);
return dma_mask;
}
@@ -247,10 +247,10 @@ static inline gfp_t dma_alloc_coherent_gfp_flags(struct device *dev, gfp_t gfp)
{
unsigned long dma_mask = dma_alloc_coherent_mask(dev, gfp);
- if (dma_mask <= DMA_24BIT_MASK)
+ if (dma_mask <= DMA_BIT_MASK(24))
gfp |= GFP_DMA;
#ifdef CONFIG_X86_64
- if (dma_mask <= DMA_32BIT_MASK && !(gfp & GFP_DMA))
+ if (dma_mask <= DMA_BIT_MASK(32) && !(gfp & GFP_DMA))
gfp |= GFP_DMA32;
#endif
return gfp;
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 63a79c77d22..2d81af3974a 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -111,6 +111,8 @@ enum fixed_addresses {
#ifdef CONFIG_PARAVIRT
FIX_PARAVIRT_BOOTMAP,
#endif
+ FIX_TEXT_POKE0, /* reserve 2 pages for text_poke() */
+ FIX_TEXT_POKE1,
__end_of_permanent_fixed_addresses,
#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
FIX_OHCI1394_BASE,
@@ -149,11 +151,11 @@ extern pte_t *pkmap_page_table;
void __native_set_fixmap(enum fixed_addresses idx, pte_t pte);
void native_set_fixmap(enum fixed_addresses idx,
- unsigned long phys, pgprot_t flags);
+ phys_addr_t phys, pgprot_t flags);
#ifndef CONFIG_PARAVIRT
static inline void __set_fixmap(enum fixed_addresses idx,
- unsigned long phys, pgprot_t flags)
+ phys_addr_t phys, pgprot_t flags)
{
native_set_fixmap(idx, phys, flags);
}
diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
index db24c2278be..bd2c6511c88 100644
--- a/arch/x86/include/asm/ftrace.h
+++ b/arch/x86/include/asm/ftrace.h
@@ -28,6 +28,13 @@
#endif
+/* FIXME: I don't want to stay hardcoded */
+#ifdef CONFIG_X86_64
+# define FTRACE_SYSCALL_MAX 296
+#else
+# define FTRACE_SYSCALL_MAX 333
+#endif
+
#ifdef CONFIG_FUNCTION_TRACER
#define MCOUNT_ADDR ((long)(mcount))
#define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index e5383e3d2f8..73739322b6d 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -193,8 +193,10 @@ extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size);
*/
extern void early_ioremap_init(void);
extern void early_ioremap_reset(void);
-extern void __iomem *early_ioremap(unsigned long offset, unsigned long size);
-extern void __iomem *early_memremap(unsigned long offset, unsigned long size);
+extern void __iomem *early_ioremap(resource_size_t phys_addr,
+ unsigned long size);
+extern void __iomem *early_memremap(resource_size_t phys_addr,
+ unsigned long size);
extern void early_iounmap(void __iomem *addr, unsigned long size);
#define IO_SPACE_LIMIT 0xffff
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 373cc2bbcad..9d826e43601 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -162,10 +162,13 @@ extern int (*ioapic_renumber_irq)(int ioapic, int irq);
extern void ioapic_init_mappings(void);
#ifdef CONFIG_X86_64
-extern int save_IO_APIC_setup(void);
-extern void mask_IO_APIC_setup(void);
-extern void restore_IO_APIC_setup(void);
-extern void reinit_intr_remapped_IO_APIC(int);
+extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
+extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries);
+extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
+extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
+extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
+extern void reinit_intr_remapped_IO_APIC(int intr_remapping,
+ struct IO_APIC_route_entry **ioapic_entries);
#endif
extern void probe_nr_irqs_gsi(void);
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 7727aa8b7dd..378e3691c08 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -347,7 +347,7 @@ struct pv_mmu_ops {
/* Sometimes the physical address is a pfn, and sometimes its
an mfn. We can tell which is which from the index. */
void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
- unsigned long phys, pgprot_t flags);
+ phys_addr_t phys, pgprot_t flags);
};
struct raw_spinlock;
@@ -1432,7 +1432,7 @@ static inline void arch_leave_lazy_mmu_mode(void)
void arch_flush_lazy_mmu_mode(void);
static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
- unsigned long phys, pgprot_t flags)
+ phys_addr_t phys, pgprot_t flags)
{
pv_mmu_ops.set_fixmap(idx, phys, flags);
}
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index a0301bfeb95..b51a1e8b0ba 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -89,12 +89,40 @@ extern void pci_iommu_alloc(void);
/* MSI arch hook */
#define arch_setup_msi_irqs arch_setup_msi_irqs
-#endif /* __KERNEL__ */
+#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
+
+#if defined(CONFIG_X86_64) || defined(CONFIG_DMA_API_DEBUG)
+
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
+ dma_addr_t ADDR_NAME;
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
+ __u32 LEN_NAME;
+#define pci_unmap_addr(PTR, ADDR_NAME) \
+ ((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
+ (((PTR)->ADDR_NAME) = (VAL))
+#define pci_unmap_len(PTR, LEN_NAME) \
+ ((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
+ (((PTR)->LEN_NAME) = (VAL))
-#ifdef CONFIG_X86_32
-# include "pci_32.h"
#else
-# include "pci_64.h"
+
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME[0];
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) unsigned LEN_NAME[0];
+#define pci_unmap_addr(PTR, ADDR_NAME) sizeof((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
+ do { break; } while (pci_unmap_addr(PTR, ADDR_NAME))
+#define pci_unmap_len(PTR, LEN_NAME) sizeof((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
+ do { break; } while (pci_unmap_len(PTR, LEN_NAME))
+
+#endif
+
+#endif /* __KERNEL__ */
+
+#ifdef CONFIG_X86_64
+#include "pci_64.h"
#endif
/* implement the pci_ DMA API in terms of the generic device dma_ one */
@@ -112,11 +140,6 @@ static inline int __pcibus_to_node(const struct pci_bus *bus)
return sd->node;
}
-static inline cpumask_t __pcibus_to_cpumask(struct pci_bus *bus)
-{
- return node_to_cpumask(__pcibus_to_node(bus));
-}
-
static inline const struct cpumask *
cpumask_of_pcibus(const struct pci_bus *bus)
{
diff --git a/arch/x86/include/asm/pci_32.h b/arch/x86/include/asm/pci_32.h
deleted file mode 100644
index 6f1213a6ef4..00000000000
--- a/arch/x86/include/asm/pci_32.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef _ASM_X86_PCI_32_H
-#define _ASM_X86_PCI_32_H
-
-
-#ifdef __KERNEL__
-
-
-/* Dynamic DMA mapping stuff.
- * i386 has everything mapped statically.
- */
-
-struct pci_dev;
-
-/* The PCI address space does equal the physical memory
- * address space. The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS (1)
-
-/* pci_unmap_{page,single} is a nop so... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME[0];
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) unsigned LEN_NAME[0];
-#define pci_unmap_addr(PTR, ADDR_NAME) sizeof((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- do { break; } while (pci_unmap_addr(PTR, ADDR_NAME))
-#define pci_unmap_len(PTR, LEN_NAME) sizeof((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- do { break; } while (pci_unmap_len(PTR, LEN_NAME))
-
-
-#endif /* __KERNEL__ */
-
-
-#endif /* _ASM_X86_PCI_32_H */
diff --git a/arch/x86/include/asm/pci_64.h b/arch/x86/include/asm/pci_64.h
index 4da20798277..ae5e40f67da 100644
--- a/arch/x86/include/asm/pci_64.h
+++ b/arch/x86/include/asm/pci_64.h
@@ -24,28 +24,6 @@ extern int (*pci_config_write)(int seg, int bus, int dev, int fn,
extern void dma32_reserve_bootmem(void);
-/* The PCI address space does equal the physical memory
- * address space. The networking and block device layers use
- * this boolean for bounce buffer decisions
- *
- * On AMD64 it mostly equals, but we set it to zero if a hardware
- * IOMMU (gart) of sotware IOMMU (swiotlb) is available.
- */
-#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
-
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
- dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
- __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME) \
- ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) \
- ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- (((PTR)->LEN_NAME) = (VAL))
-
#endif /* __KERNEL__ */
#endif /* _ASM_X86_PCI_64_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index ae85a8d66a3..fcf4d92e7e0 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -94,7 +94,7 @@ struct cpuinfo_x86 {
unsigned long loops_per_jiffy;
#ifdef CONFIG_SMP
/* cpus sharing the last level cache: */
- cpumask_t llc_shared_map;
+ cpumask_var_t llc_shared_map;
#endif
/* cpuid returned max cores value: */
u16 x86_max_cores;
@@ -352,6 +352,11 @@ struct i387_soft_struct {
u32 entry_eip;
};
+struct ymmh_struct {
+ /* 16 * 16 bytes for each YMMH-reg = 256 bytes */
+ u32 ymmh_space[64];
+};
+
struct xsave_hdr_struct {
u64 xstate_bv;
u64 reserved1[2];
@@ -361,6 +366,7 @@ struct xsave_hdr_struct {
struct xsave_struct {
struct i387_fxsave_struct i387;
struct xsave_hdr_struct xsave_hdr;
+ struct ymmh_struct ymmh;
/* new processor state extensions will go here */
} __attribute__ ((packed, aligned (64)));
@@ -736,6 +742,7 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
extern void select_idle_routine(const struct cpuinfo_x86 *c);
+extern void init_c1e_mask(void);
extern unsigned long boot_option_idle_override;
extern unsigned long idle_halt;
diff --git a/arch/x86/include/asm/ptrace-abi.h b/arch/x86/include/asm/ptrace-abi.h
index 8e0f8d199e0..86723035a51 100644
--- a/arch/x86/include/asm/ptrace-abi.h
+++ b/arch/x86/include/asm/ptrace-abi.h
@@ -80,8 +80,6 @@
#define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */
-#ifdef CONFIG_X86_PTRACE_BTS
-
#ifndef __ASSEMBLY__
#include <linux/types.h>
@@ -140,6 +138,5 @@ struct ptrace_bts_config {
BTS records are read from oldest to newest.
Returns number of BTS records drained.
*/
-#endif /* CONFIG_X86_PTRACE_BTS */
#endif /* _ASM_X86_PTRACE_ABI_H */
diff --git a/arch/x86/include/asm/required-features.h b/arch/x86/include/asm/required-features.h
index d5cd6c58688..a4737dddfd5 100644
--- a/arch/x86/include/asm/required-features.h
+++ b/arch/x86/include/asm/required-features.h
@@ -50,7 +50,7 @@
#ifdef CONFIG_X86_64
#define NEED_PSE 0
#define NEED_MSR (1<<(X86_FEATURE_MSR & 31))
-#define NEED_PGE (1<<(X86_FEATURE_PGE & 31))
+#define NEED_PGE 0
#define NEED_FXSR (1<<(X86_FEATURE_FXSR & 31))
#define NEED_XMM (1<<(X86_FEATURE_XMM & 31))
#define NEED_XMM2 (1<<(X86_FEATURE_XMM2 & 31))
diff --git a/arch/x86/include/asm/sigcontext.h b/arch/x86/include/asm/sigcontext.h
index ec666491aaa..72e5a449166 100644
--- a/arch/x86/include/asm/sigcontext.h
+++ b/arch/x86/include/asm/sigcontext.h
@@ -269,6 +269,11 @@ struct _xsave_hdr {
__u64 reserved2[5];
};
+struct _ymmh_state {
+ /* 16 * 16 bytes for each YMMH-reg */
+ __u32 ymmh_space[64];
+};
+
/*
* Extended state pointed by the fpstate pointer in the sigcontext.
* In addition to the fpstate, information encoded in the xstate_hdr
@@ -278,6 +283,7 @@ struct _xsave_hdr {
struct _xstate {
struct _fpstate fpstate;
struct _xsave_hdr xstate_hdr;
+ struct _ymmh_state ymmh;
/* new processor state extensions go here */
};
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 47d0e21f2b9..19e0d88b966 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -21,19 +21,19 @@
extern int smp_num_siblings;
extern unsigned int num_processors;
-DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
-DECLARE_PER_CPU(cpumask_t, cpu_core_map);
+DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map);
+DECLARE_PER_CPU(cpumask_var_t, cpu_core_map);
DECLARE_PER_CPU(u16, cpu_llc_id);
DECLARE_PER_CPU(int, cpu_number);
static inline struct cpumask *cpu_sibling_mask(int cpu)
{
- return &per_cpu(cpu_sibling_map, cpu);
+ return per_cpu(cpu_sibling_map, cpu);
}
static inline struct cpumask *cpu_core_mask(int cpu)
{
- return &per_cpu(cpu_core_map, cpu);
+ return per_cpu(cpu_core_map, cpu);
}
DECLARE_EARLY_PER_CPU(u16, x86_cpu_to_apicid);
@@ -121,9 +121,10 @@ static inline void arch_send_call_function_single_ipi(int cpu)
smp_ops.send_call_func_single_ipi(cpu);
}
-static inline void arch_send_call_function_ipi(cpumask_t mask)
+#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
+static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
{
- smp_ops.send_call_func_ipi(&mask);
+ smp_ops.send_call_func_ipi(mask);
}
void cpu_disable_common(void);
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index df9d5f78385..8820a73ae09 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -94,6 +94,7 @@ struct thread_info {
#define TIF_FORCED_TF 24 /* true if TF in eflags artificially */
#define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */
#define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */
+#define TIF_SYSCALL_FTRACE 27 /* for ftrace syscall instrumentation */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
@@ -115,15 +116,17 @@ struct thread_info {
#define _TIF_FORCED_TF (1 << TIF_FORCED_TF)
#define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR)
#define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR)
+#define _TIF_SYSCALL_FTRACE (1 << TIF_SYSCALL_FTRACE)
/* work to do in syscall_trace_enter() */
#define _TIF_WORK_SYSCALL_ENTRY \
- (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | \
+ (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_FTRACE | \
_TIF_SYSCALL_AUDIT | _TIF_SECCOMP | _TIF_SINGLESTEP)
/* work to do in syscall_trace_leave() */
#define _TIF_WORK_SYSCALL_EXIT \
- (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP)
+ (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP | \
+ _TIF_SYSCALL_FTRACE)
/* work to do on interrupt/exception return */
#define _TIF_WORK_MASK \
@@ -132,7 +135,7 @@ struct thread_info {
_TIF_SINGLESTEP|_TIF_SECCOMP|_TIF_SYSCALL_EMU))
/* work to do on any return to user space */
-#define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP)
+#define _TIF_ALLWORK_MASK ((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_FTRACE)
/* Only used for 64 bit */
#define _TIF_DO_NOTIFY_MASK \
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 744299c0b77..892b119dba6 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -44,9 +44,6 @@
#ifdef CONFIG_X86_32
-/* Mappings between node number and cpus on that node. */
-extern cpumask_t node_to_cpumask_map[];
-
/* Mappings between logical cpu number and node number */
extern int cpu_to_node_map[];
@@ -57,30 +54,8 @@ static inline int cpu_to_node(int cpu)
}
#define early_cpu_to_node(cpu) cpu_to_node(cpu)
-/* Returns a bitmask of CPUs on Node 'node'.
- *
- * Side note: this function creates the returned cpumask on the stack
- * so with a high NR_CPUS count, excessive stack space is used. The
- * cpumask_of_node function should be used whenever possible.
- */
-static inline cpumask_t node_to_cpumask(int node)
-{
- return node_to_cpumask_map[node];
-}
-
-/* Returns a bitmask of CPUs on Node 'node'. */
-static inline const struct cpumask *cpumask_of_node(int node)
-{
- return &node_to_cpumask_map[node];
-}
-
-static inline void setup_node_to_cpumask_map(void) { }
-
#else /* CONFIG_X86_64 */
-/* Mappings between node number and cpus on that node. */
-extern cpumask_t *node_to_cpumask_map;
-
/* Mappings between logical cpu number and node number */
DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map);
@@ -91,8 +66,6 @@ DECLARE_PER_CPU(int, node_number);
#ifdef CONFIG_DEBUG_PER_CPU_MAPS
extern int cpu_to_node(int cpu);
extern int early_cpu_to_node(int cpu);
-extern const cpumask_t *cpumask_of_node(int node);
-extern cpumask_t node_to_cpumask(int node);
#else /* !CONFIG_DEBUG_PER_CPU_MAPS */
@@ -108,42 +81,32 @@ static inline int early_cpu_to_node(int cpu)
return early_per_cpu(x86_cpu_to_node_map, cpu);
}
-/* Returns a pointer to the cpumask of CPUs on Node 'node'. */
-static inline const cpumask_t *cpumask_of_node(int node)
-{
- return &node_to_cpumask_map[node];
-}
+#endif /* !CONFIG_DEBUG_PER_CPU_MAPS */
+
+#endif /* CONFIG_X86_64 */
-/* Returns a bitmask of CPUs on Node 'node'. */
-static inline cpumask_t node_to_cpumask(int node)
+/* Mappings between node number and cpus on that node. */
+extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+extern const struct cpumask *cpumask_of_node(int node);
+#else
+/* Returns a pointer to the cpumask of CPUs on Node 'node'. */
+static inline const struct cpumask *cpumask_of_node(int node)
{
return node_to_cpumask_map[node];
}
-
-#endif /* !CONFIG_DEBUG_PER_CPU_MAPS */
+#endif
extern void setup_node_to_cpumask_map(void);
/*
- * Replace default node_to_cpumask_ptr with optimized version
- * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)"
- */
-#define node_to_cpumask_ptr(v, node) \
- const cpumask_t *v = cpumask_of_node(node)
-
-#define node_to_cpumask_ptr_next(v, node) \
- v = cpumask_of_node(node)
-
-#endif /* CONFIG_X86_64 */
-
-/*
* Returns the number of the node containing Node 'node'. This
* architecture is flat, so it is a pretty simple function!
*/
#define parent_node(node) (node)
#define pcibus_to_node(bus) __pcibus_to_node(bus)
-#define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus)
#ifdef CONFIG_X86_32
extern unsigned long node_start_pfn[];
@@ -209,40 +172,24 @@ static inline int early_cpu_to_node(int cpu)
return 0;
}
-static inline const cpumask_t *cpumask_of_node(int node)
-{
- return &cpu_online_map;
-}
-static inline cpumask_t node_to_cpumask(int node)
+static inline const struct cpumask *cpumask_of_node(int node)
{
- return cpu_online_map;
+ return cpu_online_mask;
}
static inline void setup_node_to_cpumask_map(void) { }
-/*
- * Replace default node_to_cpumask_ptr with optimized version
- * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)"
- */
-#define node_to_cpumask_ptr(v, node) \
- const cpumask_t *v = cpumask_of_node(node)
-
-#define node_to_cpumask_ptr_next(v, node) \
- v = cpumask_of_node(node)
#endif
#include <asm-generic/topology.h>
-extern cpumask_t cpu_coregroup_map(int cpu);
extern const struct cpumask *cpu_coregroup_mask(int cpu);
#ifdef ENABLE_TOPO_DEFINES
#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id)
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
-#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu))
-#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
-#define topology_core_cpumask(cpu) (&per_cpu(cpu_core_map, cpu))
-#define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu))
+#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
+#define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
/* indicates that pointers to the topology cpumask_t maps are valid */
#define arch_provides_topology_pointers yes
@@ -256,7 +203,7 @@ struct pci_bus;
void set_pci_bus_resources_arch_default(struct pci_bus *b);
#ifdef CONFIG_SMP
-#define mc_capable() (cpus_weight(per_cpu(cpu_core_map, 0)) != nr_cpu_ids)
+#define mc_capable() (cpumask_weight(cpu_core_mask(0)) != nr_cpu_ids)
#define smt_capable() (smp_num_siblings > 1)
#endif
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index 1a918dde46b..018a0a40079 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -124,7 +124,8 @@ static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
/* VIRT <-> MACHINE conversion */
#define virt_to_machine(v) (phys_to_machine(XPADDR(__pa(v))))
-#define virt_to_mfn(v) (pfn_to_mfn(PFN_DOWN(__pa(v))))
+#define virt_to_pfn(v) (PFN_DOWN(__pa(v)))
+#define virt_to_mfn(v) (pfn_to_mfn(virt_to_pfn(v)))
#define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT))
static inline unsigned long pte_mfn(pte_t pte)
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h
index 08e9a1ac07a..727acc15234 100644
--- a/arch/x86/include/asm/xsave.h
+++ b/arch/x86/include/asm/xsave.h
@@ -7,6 +7,7 @@
#define XSTATE_FP 0x1
#define XSTATE_SSE 0x2
+#define XSTATE_YMM 0x4
#define XSTATE_FPSSE (XSTATE_FP | XSTATE_SSE)
@@ -15,7 +16,7 @@
/*
* These are the features that the OS can handle currently.
*/
-#define XCNTXT_MASK (XSTATE_FP | XSTATE_SSE)
+#define XCNTXT_MASK (XSTATE_FP | XSTATE_SSE | XSTATE_YMM)
#ifdef CONFIG_X86_64
#define REX_PREFIX "0x48, "
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index c611ad64137..145cce75cda 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -66,7 +66,8 @@ obj-$(CONFIG_X86_MPPARSE) += mpparse.o
obj-y += apic/
obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
-obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
+obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o
obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index a18eb7ce223..723989d7f80 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -230,6 +230,35 @@ static void __cpuinit acpi_register_lapic(int id, u8 enabled)
}
static int __init
+acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
+{
+ struct acpi_madt_local_x2apic *processor = NULL;
+
+ processor = (struct acpi_madt_local_x2apic *)header;
+
+ if (BAD_MADT_ENTRY(processor, end))
+ return -EINVAL;
+
+ acpi_table_print_madt_entry(header);
+
+#ifdef CONFIG_X86_X2APIC
+ /*
+ * We need to register disabled CPU as well to permit
+ * counting disabled CPUs. This allows us to size
+ * cpus_possible_map more accurately, to permit
+ * to not preallocating memory for all NR_CPUS
+ * when we use CPU hotplug.
+ */
+ acpi_register_lapic(processor->local_apic_id, /* APIC ID */
+ processor->lapic_flags & ACPI_MADT_ENABLED);
+#else
+ printk(KERN_WARNING PREFIX "x2apic entry ignored\n");
+#endif
+
+ return 0;
+}
+
+static int __init
acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end)
{
struct acpi_madt_local_apic *processor = NULL;
@@ -289,6 +318,25 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header,
}
static int __init
+acpi_parse_x2apic_nmi(struct acpi_subtable_header *header,
+ const unsigned long end)
+{
+ struct acpi_madt_local_x2apic_nmi *x2apic_nmi = NULL;
+
+ x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header;
+
+ if (BAD_MADT_ENTRY(x2apic_nmi, end))
+ return -EINVAL;
+
+ acpi_table_print_madt_entry(header);
+
+ if (x2apic_nmi->lint != 1)
+ printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n");
+
+ return 0;
+}
+
+static int __init
acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end)
{
struct acpi_madt_local_apic_nmi *lapic_nmi = NULL;
@@ -793,6 +841,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
static int __init acpi_parse_madt_lapic_entries(void)
{
int count;
+ int x2count = 0;
if (!cpu_has_apic)
return -ENODEV;
@@ -816,22 +865,28 @@ static int __init acpi_parse_madt_lapic_entries(void)
count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC,
acpi_parse_sapic, MAX_APICS);
- if (!count)
+ if (!count) {
+ x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
+ acpi_parse_x2apic, MAX_APICS);
count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
acpi_parse_lapic, MAX_APICS);
- if (!count) {
+ }
+ if (!count && !x2count) {
printk(KERN_ERR PREFIX "No LAPIC entries present\n");
/* TBD: Cleanup to allow fallback to MPS */
return -ENODEV;
- } else if (count < 0) {
+ } else if (count < 0 || x2count < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
/* TBD: Cleanup to allow fallback to MPS */
return count;
}
+ x2count =
+ acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI,
+ acpi_parse_x2apic_nmi, 0);
count =
acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0);
- if (count < 0) {
+ if (count < 0 || x2count < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
/* TBD: Cleanup to allow fallback to MPS */
return count;
@@ -1470,7 +1525,7 @@ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d)
/*
* If your system is blacklisted here, but you find that acpi=force
- * works for you, please contact acpi-devel@sourceforge.net
+ * works for you, please contact linux-acpi@vger.kernel.org
*/
static struct dmi_system_id __initdata acpi_dmi_table[] = {
/*
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 4c80f155743..f5765870257 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -5,6 +5,7 @@
#include <linux/kprobes.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
+#include <linux/memory.h>
#include <asm/alternative.h>
#include <asm/sections.h>
#include <asm/pgtable.h>
@@ -12,7 +13,9 @@
#include <asm/nmi.h>
#include <asm/vsyscall.h>
#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
#include <asm/io.h>
+#include <asm/fixmap.h>
#define MAX_PATCH_LEN (255-1)
@@ -226,6 +229,7 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
{
u8 **ptr;
+ mutex_lock(&text_mutex);
for (ptr = start; ptr < end; ptr++) {
if (*ptr < text)
continue;
@@ -234,6 +238,7 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
/* turn DS segment override prefix into lock prefix */
text_poke(*ptr, ((unsigned char []){0xf0}), 1);
};
+ mutex_unlock(&text_mutex);
}
static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
@@ -243,6 +248,7 @@ static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end
if (noreplace_smp)
return;
+ mutex_lock(&text_mutex);
for (ptr = start; ptr < end; ptr++) {
if (*ptr < text)
continue;
@@ -251,6 +257,7 @@ static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end
/* turn lock prefix into DS segment override prefix */
text_poke(*ptr, ((unsigned char []){0x3E}), 1);
};
+ mutex_unlock(&text_mutex);
}
struct smp_alt_module {
@@ -500,15 +507,16 @@ void *text_poke_early(void *addr, const void *opcode, size_t len)
* It means the size must be writable atomically and the address must be aligned
* in a way that permits an atomic write. It also makes sure we fit on a single
* page.
+ *
+ * Note: Must be called under text_mutex.
*/
void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
{
+ unsigned long flags;
char *vaddr;
- int nr_pages = 2;
struct page *pages[2];
int i;
- might_sleep();
if (!core_kernel_text((unsigned long)addr)) {
pages[0] = vmalloc_to_page(addr);
pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
@@ -518,18 +526,21 @@ void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
pages[1] = virt_to_page(addr + PAGE_SIZE);
}
BUG_ON(!pages[0]);
- if (!pages[1])
- nr_pages = 1;
- vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
- BUG_ON(!vaddr);
- local_irq_disable();
+ local_irq_save(flags);
+ set_fixmap(FIX_TEXT_POKE0, page_to_phys(pages[0]));
+ if (pages[1])
+ set_fixmap(FIX_TEXT_POKE1, page_to_phys(pages[1]));
+ vaddr = (char *)fix_to_virt(FIX_TEXT_POKE0);
memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
- local_irq_enable();
- vunmap(vaddr);
+ clear_fixmap(FIX_TEXT_POKE0);
+ if (pages[1])
+ clear_fixmap(FIX_TEXT_POKE1);
+ local_flush_tlb();
sync_core();
/* Could also do a CLFLUSH here to speed up CPU recovery; but
that causes hangs on some VIA CPUs. */
for (i = 0; i < len; i++)
BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
+ local_irq_restore(flags);
return addr;
}
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index c5962fe3796..a97db99dad5 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -1928,6 +1928,12 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
return paddr;
}
+static int amd_iommu_domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap)
+{
+ return 0;
+}
+
static struct iommu_ops amd_iommu_ops = {
.domain_init = amd_iommu_domain_init,
.domain_destroy = amd_iommu_domain_destroy,
@@ -1936,5 +1942,6 @@ static struct iommu_ops amd_iommu_ops = {
.map = amd_iommu_map_range,
.unmap = amd_iommu_unmap_range,
.iova_to_phys = amd_iommu_iova_to_phys,
+ .domain_has_cap = amd_iommu_domain_has_cap,
};
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 85eb8e10081..f2870920f24 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -431,6 +431,12 @@ static void __cpuinit setup_APIC_timer(void)
{
struct clock_event_device *levt = &__get_cpu_var(lapic_events);
+ if (cpu_has(&current_cpu_data, X86_FEATURE_ARAT)) {
+ lapic_clockevent.features &= ~CLOCK_EVT_FEAT_C3STOP;
+ /* Make LAPIC timer preferrable over percpu HPET */
+ lapic_clockevent.rating = 150;
+ }
+
memcpy(levt, &lapic_clockevent, sizeof(*levt));
levt->cpumask = cpumask_of(smp_processor_id());
@@ -1304,6 +1310,7 @@ void __init enable_IR_x2apic(void)
#ifdef CONFIG_INTR_REMAP
int ret;
unsigned long flags;
+ struct IO_APIC_route_entry **ioapic_entries = NULL;
if (!cpu_has_x2apic)
return;
@@ -1334,17 +1341,23 @@ void __init enable_IR_x2apic(void)
return;
}
- ret = save_IO_APIC_setup();
+ ioapic_entries = alloc_ioapic_entries();
+ if (!ioapic_entries) {
+ pr_info("Allocate ioapic_entries failed: %d\n", ret);
+ goto end;
+ }
+
+ ret = save_IO_APIC_setup(ioapic_entries);
if (ret) {
pr_info("Saving IO-APIC state failed: %d\n", ret);
goto end;
}
local_irq_save(flags);
- mask_IO_APIC_setup();
+ mask_IO_APIC_setup(ioapic_entries);
mask_8259A();
- ret = enable_intr_remapping(1);
+ ret = enable_intr_remapping(EIM_32BIT_APIC_ID);
if (ret && x2apic_preenabled) {
local_irq_restore(flags);
@@ -1364,9 +1377,9 @@ end_restore:
/*
* IR enabling failed
*/
- restore_IO_APIC_setup();
+ restore_IO_APIC_setup(ioapic_entries);
else
- reinit_intr_remapped_IO_APIC(x2apic_preenabled);
+ reinit_intr_remapped_IO_APIC(x2apic_preenabled, ioapic_entries);
unmask_8259A();
local_irq_restore(flags);
@@ -1379,6 +1392,8 @@ end:
pr_info("Enabled Interrupt-remapping\n");
} else
pr_err("Failed to enable Interrupt-remapping and x2apic\n");
+ if (ioapic_entries)
+ free_ioapic_entries(ioapic_entries);
#else
if (!cpu_has_x2apic)
return;
@@ -1954,6 +1969,10 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state)
local_irq_save(flags);
disable_local_APIC();
+#ifdef CONFIG_INTR_REMAP
+ if (intr_remapping_enabled)
+ disable_intr_remapping();
+#endif
local_irq_restore(flags);
return 0;
}
@@ -1964,15 +1983,41 @@ static int lapic_resume(struct sys_device *dev)
unsigned long flags;
int maxlvt;
+#ifdef CONFIG_INTR_REMAP
+ int ret;
+ struct IO_APIC_route_entry **ioapic_entries = NULL;
+
if (!apic_pm_state.active)
return 0;
- maxlvt = lapic_get_maxlvt();
-
local_irq_save(flags);
+ if (x2apic) {
+ ioapic_entries = alloc_ioapic_entries();
+ if (!ioapic_entries) {
+ WARN(1, "Alloc ioapic_entries in lapic resume failed.");
+ return -ENOMEM;
+ }
+
+ ret = save_IO_APIC_setup(ioapic_entries);
+ if (ret) {
+ WARN(1, "Saving IO-APIC state failed: %d\n", ret);
+ free_ioapic_entries(ioapic_entries);
+ return ret;
+ }
+
+ mask_IO_APIC_setup(ioapic_entries);
+ mask_8259A();
+ enable_x2apic();
+ }
+#else
+ if (!apic_pm_state.active)
+ return 0;
+ local_irq_save(flags);
if (x2apic)
enable_x2apic();
+#endif
+
else {
/*
* Make sure the APICBASE points to the right address
@@ -1986,6 +2031,7 @@ static int lapic_resume(struct sys_device *dev)
wrmsr(MSR_IA32_APICBASE, l, h);
}
+ maxlvt = lapic_get_maxlvt();
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);
@@ -2009,8 +2055,20 @@ static int lapic_resume(struct sys_device *dev)
apic_write(APIC_ESR, 0);
apic_read(APIC_ESR);
+#ifdef CONFIG_INTR_REMAP
+ if (intr_remapping_enabled)
+ reenable_intr_remapping(EIM_32BIT_APIC_ID);
+
+ if (x2apic) {
+ unmask_8259A();
+ restore_IO_APIC_setup(ioapic_entries);
+ free_ioapic_entries(ioapic_entries);
+ }
+#endif
+
local_irq_restore(flags);
+
return 0;
}
@@ -2048,7 +2106,9 @@ static int __init init_lapic_sysfs(void)
error = sysdev_register(&device_lapic);
return error;
}
-device_initcall(init_lapic_sysfs);
+
+/* local apic needs to resume before other devices access its registers. */
+core_initcall(init_lapic_sysfs);
#else /* CONFIG_PM */
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c
index 0014714ea97..306e5e88fb6 100644
--- a/arch/x86/kernel/apic/apic_flat_64.c
+++ b/arch/x86/kernel/apic/apic_flat_64.c
@@ -212,7 +212,7 @@ struct apic apic_flat = {
.trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
.wait_for_init_deassert = NULL,
.smp_callin_clear_local_apic = NULL,
- .inquire_remote_apic = NULL,
+ .inquire_remote_apic = default_inquire_remote_apic,
.read = native_apic_mem_read,
.write = native_apic_mem_write,
@@ -362,7 +362,7 @@ struct apic apic_physflat = {
.trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
.wait_for_init_deassert = NULL,
.smp_callin_clear_local_apic = NULL,
- .inquire_remote_apic = NULL,
+ .inquire_remote_apic = default_inquire_remote_apic,
.read = native_apic_mem_read,
.write = native_apic_mem_write,
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c
index d806ecaa948..676cdac385c 100644
--- a/arch/x86/kernel/apic/bigsmp_32.c
+++ b/arch/x86/kernel/apic/bigsmp_32.c
@@ -26,12 +26,12 @@ static int bigsmp_apic_id_registered(void)
return 1;
}
-static const cpumask_t *bigsmp_target_cpus(void)
+static const struct cpumask *bigsmp_target_cpus(void)
{
#ifdef CONFIG_SMP
- return &cpu_online_map;
+ return cpu_online_mask;
#else
- return &cpumask_of_cpu(0);
+ return cpumask_of(0);
#endif
}
@@ -118,9 +118,9 @@ static int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid)
}
/* As we are using single CPU as destination, pick only one CPU here */
-static unsigned int bigsmp_cpu_mask_to_apicid(const cpumask_t *cpumask)
+static unsigned int bigsmp_cpu_mask_to_apicid(const struct cpumask *cpumask)
{
- return bigsmp_cpu_to_logical_apicid(first_cpu(*cpumask));
+ return bigsmp_cpu_to_logical_apicid(cpumask_first(cpumask));
}
static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
@@ -188,10 +188,10 @@ static const struct dmi_system_id bigsmp_dmi_table[] = {
{ } /* NULL entry stops DMI scanning */
};
-static void bigsmp_vector_allocation_domain(int cpu, cpumask_t *retmask)
+static void bigsmp_vector_allocation_domain(int cpu, struct cpumask *retmask)
{
- cpus_clear(*retmask);
- cpu_set(cpu, *retmask);
+ cpumask_clear(retmask);
+ cpumask_set_cpu(cpu, retmask);
}
static int probe_bigsmp(void)
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index 19588f2770e..1c11b819f24 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -410,7 +410,7 @@ static void es7000_enable_apic_mode(void)
WARN(1, "Command failed, status = %x\n", mip_status);
}
-static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask)
+static void es7000_vector_allocation_domain(int cpu, struct cpumask *retmask)
{
/* Careful. Some cpus do not strictly honor the set of cpus
* specified in the interrupt destination when using lowest
@@ -420,7 +420,8 @@ static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask)
* deliver interrupts to the wrong hyperthread when only one
* hyperthread was specified in the interrupt desitination.
*/
- *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
+ cpumask_clear(retmask);
+ cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
}
@@ -455,14 +456,14 @@ static int es7000_apic_id_registered(void)
return 1;
}
-static const cpumask_t *target_cpus_cluster(void)
+static const struct cpumask *target_cpus_cluster(void)
{
- return &CPU_MASK_ALL;
+ return cpu_all_mask;
}
-static const cpumask_t *es7000_target_cpus(void)
+static const struct cpumask *es7000_target_cpus(void)
{
- return &cpumask_of_cpu(smp_processor_id());
+ return cpumask_of(smp_processor_id());
}
static unsigned long
@@ -517,7 +518,7 @@ static void es7000_setup_apic_routing(void)
"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(*es7000_target_cpus())[0]);
+ nr_ioapics, cpumask_bits(es7000_target_cpus())[0]);
}
static int es7000_apicid_to_node(int logical_apicid)
@@ -572,7 +573,7 @@ static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
return 1;
}
-static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask)
+static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask)
{
unsigned int round = 0;
int cpu, uninitialized_var(apicid);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 1bb5c6cee3e..a2789e42e16 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -851,63 +851,74 @@ __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];
+struct IO_APIC_route_entry **alloc_ioapic_entries(void)
+{
+ int apic;
+ struct IO_APIC_route_entry **ioapic_entries;
+
+ ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics,
+ GFP_ATOMIC);
+ if (!ioapic_entries)
+ return 0;
+
+ for (apic = 0; apic < nr_ioapics; apic++) {
+ ioapic_entries[apic] =
+ kzalloc(sizeof(struct IO_APIC_route_entry) *
+ nr_ioapic_registers[apic], GFP_ATOMIC);
+ if (!ioapic_entries[apic])
+ goto nomem;
+ }
+
+ return ioapic_entries;
+
+nomem:
+ while (--apic >= 0)
+ kfree(ioapic_entries[apic]);
+ kfree(ioapic_entries);
+
+ return 0;
+}
/*
* Saves all the IO-APIC RTE's
*/
-int save_IO_APIC_setup(void)
+int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
{
- union IO_APIC_reg_01 reg_01;
- unsigned long flags;
int apic, pin;
- /*
- * 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;
- }
+ if (!ioapic_entries)
+ return -ENOMEM;
for (apic = 0; apic < nr_ioapics; apic++) {
- early_ioapic_entries[apic] =
- kzalloc(sizeof(struct IO_APIC_route_entry) *
- nr_ioapic_registers[apic], GFP_KERNEL);
- if (!early_ioapic_entries[apic])
- goto nomem;
- }
+ if (!ioapic_entries[apic])
+ return -ENOMEM;
- for (apic = 0; apic < nr_ioapics; apic++)
for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
- early_ioapic_entries[apic][pin] =
+ ioapic_entries[apic][pin] =
ioapic_read_entry(apic, pin);
+ }
return 0;
-
-nomem:
- while (apic >= 0)
- kfree(early_ioapic_entries[apic--]);
- memset(early_ioapic_entries, 0,
- ARRAY_SIZE(early_ioapic_entries));
-
- return -ENOMEM;
}
-void mask_IO_APIC_setup(void)
+/*
+ * Mask all IO APIC entries.
+ */
+void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
{
int apic, pin;
+ if (!ioapic_entries)
+ return;
+
for (apic = 0; apic < nr_ioapics; apic++) {
- if (!early_ioapic_entries[apic])
+ if (!ioapic_entries[apic])
break;
+
for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
struct IO_APIC_route_entry entry;
- entry = early_ioapic_entries[apic][pin];
+ entry = ioapic_entries[apic][pin];
if (!entry.mask) {
entry.mask = 1;
ioapic_write_entry(apic, pin, entry);
@@ -916,22 +927,30 @@ void mask_IO_APIC_setup(void)
}
}
-void restore_IO_APIC_setup(void)
+/*
+ * Restore IO APIC entries which was saved in ioapic_entries.
+ */
+int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
{
int apic, pin;
+ if (!ioapic_entries)
+ return -ENOMEM;
+
for (apic = 0; apic < nr_ioapics; apic++) {
- if (!early_ioapic_entries[apic])
- break;
+ if (!ioapic_entries[apic])
+ return -ENOMEM;
+
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;
+ ioapic_entries[apic][pin]);
}
+ return 0;
}
-void reinit_intr_remapped_IO_APIC(int intr_remapping)
+void reinit_intr_remapped_IO_APIC(int intr_remapping,
+ struct IO_APIC_route_entry **ioapic_entries)
+
{
/*
* for now plain restore of previous settings.
@@ -940,7 +959,17 @@ void reinit_intr_remapped_IO_APIC(int intr_remapping)
* table entries. for now, do a plain restore, and wait for
* the setup_IO_APIC_irqs() to do proper initialization.
*/
- restore_IO_APIC_setup();
+ restore_IO_APIC_setup(ioapic_entries);
+}
+
+void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries)
+{
+ int apic;
+
+ for (apic = 0; apic < nr_ioapics; apic++)
+ kfree(ioapic_entries[apic]);
+
+ kfree(ioapic_entries);
}
#endif
@@ -2495,7 +2524,6 @@ static void irq_complete_move(struct irq_desc **descp)
static inline void irq_complete_move(struct irq_desc **descp) {}
#endif
-#ifdef CONFIG_INTR_REMAP
static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
{
int apic, pin;
@@ -2529,6 +2557,7 @@ eoi_ioapic_irq(struct irq_desc *desc)
spin_unlock_irqrestore(&ioapic_lock, flags);
}
+#ifdef CONFIG_X86_X2APIC
static void ack_x2apic_level(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
@@ -2540,7 +2569,6 @@ static void ack_x2apic_edge(unsigned int irq)
{
ack_x2APIC_irq();
}
-
#endif
static void ack_apic_edge(unsigned int irq)
@@ -2606,6 +2634,9 @@ static void ack_apic_level(unsigned int irq)
*/
ack_APIC_irq();
+ if (irq_remapped(irq))
+ eoi_ioapic_irq(desc);
+
/* Now we can move and renable the irq */
if (unlikely(do_unmask_irq)) {
/* Only migrate the irq if the ack has been received.
@@ -2651,6 +2682,26 @@ static void ack_apic_level(unsigned int irq)
#endif
}
+#ifdef CONFIG_INTR_REMAP
+static void ir_ack_apic_edge(unsigned int irq)
+{
+#ifdef CONFIG_X86_X2APIC
+ if (x2apic_enabled())
+ return ack_x2apic_edge(irq);
+#endif
+ return ack_apic_edge(irq);
+}
+
+static void ir_ack_apic_level(unsigned int irq)
+{
+#ifdef CONFIG_X86_X2APIC
+ if (x2apic_enabled())
+ return ack_x2apic_level(irq);
+#endif
+ return ack_apic_level(irq);
+}
+#endif /* CONFIG_INTR_REMAP */
+
static struct irq_chip ioapic_chip __read_mostly = {
.name = "IO-APIC",
.startup = startup_ioapic_irq,
@@ -2670,8 +2721,8 @@ static struct irq_chip ir_ioapic_chip __read_mostly = {
.mask = mask_IO_APIC_irq,
.unmask = unmask_IO_APIC_irq,
#ifdef CONFIG_INTR_REMAP
- .ack = ack_x2apic_edge,
- .eoi = ack_x2apic_level,
+ .ack = ir_ack_apic_edge,
+ .eoi = ir_ack_apic_level,
#ifdef CONFIG_SMP
.set_affinity = set_ir_ioapic_affinity_irq,
#endif
@@ -3397,7 +3448,7 @@ static struct irq_chip msi_ir_chip = {
.unmask = unmask_msi_irq,
.mask = mask_msi_irq,
#ifdef CONFIG_INTR_REMAP
- .ack = ack_x2apic_edge,
+ .ack = ir_ack_apic_edge,
#ifdef CONFIG_SMP
.set_affinity = ir_set_msi_irq_affinity,
#endif
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c
index bdfad80c3cf..d6bd6240715 100644
--- a/arch/x86/kernel/apic/nmi.c
+++ b/arch/x86/kernel/apic/nmi.c
@@ -39,7 +39,7 @@
int unknown_nmi_panic;
int nmi_watchdog_enabled;
-static cpumask_t backtrace_mask = CPU_MASK_NONE;
+static cpumask_var_t backtrace_mask;
/* nmi_active:
* >0: the lapic NMI watchdog is active, but can be disabled
@@ -138,6 +138,7 @@ int __init check_nmi_watchdog(void)
if (!prev_nmi_count)
goto error;
+ alloc_cpumask_var(&backtrace_mask, GFP_KERNEL);
printk(KERN_INFO "Testing NMI watchdog ... ");
#ifdef CONFIG_SMP
@@ -413,14 +414,14 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason)
touched = 1;
}
- if (cpu_isset(cpu, backtrace_mask)) {
+ if (cpumask_test_cpu(cpu, backtrace_mask)) {
static DEFINE_SPINLOCK(lock); /* Serialise the printks */
spin_lock(&lock);
printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu);
dump_stack();
spin_unlock(&lock);
- cpu_clear(cpu, backtrace_mask);
+ cpumask_clear_cpu(cpu, backtrace_mask);
}
/* Could check oops_in_progress here too, but it's safer not to */
@@ -554,10 +555,10 @@ void __trigger_all_cpu_backtrace(void)
{
int i;
- backtrace_mask = cpu_online_map;
+ cpumask_copy(backtrace_mask, cpu_online_mask);
/* Wait for up to 10 seconds for all CPUs to do the backtrace */
for (i = 0; i < 10 * 1000; i++) {
- if (cpus_empty(backtrace_mask))
+ if (cpumask_empty(backtrace_mask))
break;
mdelay(1);
}
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c
index ba2fc646553..533e59c6fc8 100644
--- a/arch/x86/kernel/apic/numaq_32.c
+++ b/arch/x86/kernel/apic/numaq_32.c
@@ -334,9 +334,9 @@ static inline void numaq_smp_callin_clear_local_apic(void)
clear_local_APIC();
}
-static inline const cpumask_t *numaq_target_cpus(void)
+static inline const struct cpumask *numaq_target_cpus(void)
{
- return &CPU_MASK_ALL;
+ return cpu_all_mask;
}
static inline unsigned long
@@ -427,7 +427,7 @@ static inline int numaq_check_phys_apicid_present(int boot_cpu_physical_apicid)
* We use physical apicids here, not logical, so just return the default
* physical broadcast to stop people from breaking us
*/
-static inline unsigned int numaq_cpu_mask_to_apicid(const cpumask_t *cpumask)
+static unsigned int numaq_cpu_mask_to_apicid(const struct cpumask *cpumask)
{
return 0x0F;
}
@@ -462,7 +462,7 @@ static int probe_numaq(void)
return found_numaq;
}
-static void numaq_vector_allocation_domain(int cpu, cpumask_t *retmask)
+static void numaq_vector_allocation_domain(int cpu, struct cpumask *retmask)
{
/* Careful. Some cpus do not strictly honor the set of cpus
* specified in the interrupt destination when using lowest
@@ -472,7 +472,8 @@ static void numaq_vector_allocation_domain(int cpu, cpumask_t *retmask)
* deliver interrupts to the wrong hyperthread when only one
* hyperthread was specified in the interrupt desitination.
*/
- *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
+ cpumask_clear(retmask);
+ cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
}
static void numaq_setup_portio_remap(void)
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index 141c99a1c26..01eda2ac65e 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -83,7 +83,8 @@ static void default_vector_allocation_domain(int cpu, struct cpumask *retmask)
* deliver interrupts to the wrong hyperthread when only one
* hyperthread was specified in the interrupt desitination.
*/
- *retmask = (cpumask_t) { { [0] = APIC_ALL_CPUS } };
+ cpumask_clear(retmask);
+ cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
}
/* should be called last. */
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c
index aac52fa873f..9cfe1f415d8 100644
--- a/arch/x86/kernel/apic/summit_32.c
+++ b/arch/x86/kernel/apic/summit_32.c
@@ -53,23 +53,19 @@ static unsigned summit_get_apic_id(unsigned long x)
return (x >> 24) & 0xFF;
}
-static inline void summit_send_IPI_mask(const cpumask_t *mask, int vector)
+static inline void summit_send_IPI_mask(const struct cpumask *mask, int vector)
{
default_send_IPI_mask_sequence_logical(mask, vector);
}
static void summit_send_IPI_allbutself(int vector)
{
- cpumask_t mask = cpu_online_map;
- cpu_clear(smp_processor_id(), mask);
-
- if (!cpus_empty(mask))
- summit_send_IPI_mask(&mask, vector);
+ default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector);
}
static void summit_send_IPI_all(int vector)
{
- summit_send_IPI_mask(&cpu_online_map, vector);
+ summit_send_IPI_mask(cpu_online_mask, vector);
}
#include <asm/tsc.h>
@@ -186,13 +182,13 @@ static inline int is_WPEG(struct rio_detail *rio){
#define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER)
-static const cpumask_t *summit_target_cpus(void)
+static const struct cpumask *summit_target_cpus(void)
{
/* CPU_MASK_ALL (0xff) has undefined behaviour with
* dest_LowestPrio mode logical clustered apic interrupt routing
* Just start on cpu 0. IRQ balancing will spread load
*/
- return &cpumask_of_cpu(0);
+ return cpumask_of(0);
}
static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid)
@@ -289,7 +285,7 @@ static int summit_check_phys_apicid_present(int boot_cpu_physical_apicid)
return 1;
}
-static unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
+static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask)
{
unsigned int round = 0;
int cpu, apicid = 0;
@@ -346,7 +342,7 @@ static int probe_summit(void)
return 0;
}
-static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask)
+static void summit_vector_allocation_domain(int cpu, struct cpumask *retmask)
{
/* Careful. Some cpus do not strictly honor the set of cpus
* specified in the interrupt destination when using lowest
@@ -356,7 +352,8 @@ static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask)
* deliver interrupts to the wrong hyperthread when only one
* hyperthread was specified in the interrupt desitination.
*/
- *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
+ cpumask_clear(retmask);
+ cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
}
#ifdef CONFIG_X86_SUMMIT_NUMA
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index ac7783a6743..49e0939bac4 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -466,7 +466,7 @@ static const lookup_t error_table[] = {
* @err: APM BIOS return code
*
* Write a meaningful log entry to the kernel log in the event of
- * an APM error.
+ * an APM error. Note that this also handles (negative) kernel errors.
*/
static void apm_error(char *str, int err)
@@ -478,43 +478,14 @@ static void apm_error(char *str, int err)
break;
if (i < ERROR_COUNT)
printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg);
+ else if (err < 0)
+ printk(KERN_NOTICE "apm: %s: linux error code %i\n", str, err);
else
printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n",
str, err);
}
/*
- * Lock APM functionality to physical CPU 0
- */
-
-#ifdef CONFIG_SMP
-
-static cpumask_t apm_save_cpus(void)
-{
- cpumask_t x = current->cpus_allowed;
- /* Some bioses don't like being called from CPU != 0 */
- set_cpus_allowed(current, cpumask_of_cpu(0));
- BUG_ON(smp_processor_id() != 0);
- return x;
-}
-
-static inline void apm_restore_cpus(cpumask_t mask)
-{
- set_cpus_allowed(current, mask);
-}
-
-#else
-
-/*
- * No CPU lockdown needed on a uniprocessor
- */
-
-#define apm_save_cpus() (current->cpus_allowed)
-#define apm_restore_cpus(x) (void)(x)
-
-#endif
-
-/*
* These are the actual BIOS calls. Depending on APM_ZERO_SEGS and
* apm_info.allow_ints, we are being really paranoid here! Not only
* are interrupts disabled, but all the segment registers (except SS)
@@ -568,16 +539,23 @@ static inline void apm_irq_restore(unsigned long flags)
# define APM_DO_RESTORE_SEGS
#endif
+struct apm_bios_call {
+ u32 func;
+ /* In and out */
+ u32 ebx;
+ u32 ecx;
+ /* Out only */
+ u32 eax;
+ u32 edx;
+ u32 esi;
+
+ /* Error: -ENOMEM, or bits 8-15 of eax */
+ int err;
+};
+
/**
- * apm_bios_call - Make an APM BIOS 32bit call
- * @func: APM function to execute
- * @ebx_in: EBX register for call entry
- * @ecx_in: ECX register for call entry
- * @eax: EAX register return
- * @ebx: EBX register return
- * @ecx: ECX register return
- * @edx: EDX register return
- * @esi: ESI register return
+ * __apm_bios_call - Make an APM BIOS 32bit call
+ * @_call: pointer to struct apm_bios_call.
*
* Make an APM call using the 32bit protected mode interface. The
* caller is responsible for knowing if APM BIOS is configured and
@@ -586,80 +564,142 @@ static inline void apm_irq_restore(unsigned long flags)
* flag is loaded into AL. If there is an error, then the error
* code is returned in AH (bits 8-15 of eax) and this function
* returns non-zero.
+ *
+ * Note: this makes the call on the current CPU.
*/
-
-static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
- u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, u32 *esi)
+static long __apm_bios_call(void *_call)
{
APM_DECL_SEGS
unsigned long flags;
- cpumask_t cpus;
int cpu;
struct desc_struct save_desc_40;
struct desc_struct *gdt;
-
- cpus = apm_save_cpus();
+ struct apm_bios_call *call = _call;
cpu = get_cpu();
+ BUG_ON(cpu != 0);
gdt = get_cpu_gdt_table(cpu);
save_desc_40 = gdt[0x40 / 8];
gdt[0x40 / 8] = bad_bios_desc;
apm_irq_save(flags);
APM_DO_SAVE_SEGS;
- apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
+ apm_bios_call_asm(call->func, call->ebx, call->ecx,
+ &call->eax, &call->ebx, &call->ecx, &call->edx,
+ &call->esi);
APM_DO_RESTORE_SEGS;
apm_irq_restore(flags);
gdt[0x40 / 8] = save_desc_40;
put_cpu();
- apm_restore_cpus(cpus);
- return *eax & 0xff;
+ return call->eax & 0xff;
+}
+
+/* Run __apm_bios_call or __apm_bios_call_simple on CPU 0 */
+static int on_cpu0(long (*fn)(void *), struct apm_bios_call *call)
+{
+ int ret;
+
+ /* Don't bother with work_on_cpu in the common case, so we don't
+ * have to worry about OOM or overhead. */
+ if (get_cpu() == 0) {
+ ret = fn(call);
+ put_cpu();
+ } else {
+ put_cpu();
+ ret = work_on_cpu(0, fn, call);
+ }
+
+ /* work_on_cpu can fail with -ENOMEM */
+ if (ret < 0)
+ call->err = ret;
+ else
+ call->err = (call->eax >> 8) & 0xff;
+
+ return ret;
}
/**
- * apm_bios_call_simple - make a simple APM BIOS 32bit call
- * @func: APM function to invoke
- * @ebx_in: EBX register value for BIOS call
- * @ecx_in: ECX register value for BIOS call
- * @eax: EAX register on return from the BIOS call
+ * apm_bios_call - Make an APM BIOS 32bit call (on CPU 0)
+ * @call: the apm_bios_call registers.
+ *
+ * If there is an error, it is returned in @call.err.
+ */
+static int apm_bios_call(struct apm_bios_call *call)
+{
+ return on_cpu0(__apm_bios_call, call);
+}
+
+/**
+ * __apm_bios_call_simple - Make an APM BIOS 32bit call (on CPU 0)
+ * @_call: pointer to struct apm_bios_call.
*
* Make a BIOS call that returns one value only, or just status.
* If there is an error, then the error code is returned in AH
- * (bits 8-15 of eax) and this function returns non-zero. This is
- * used for simpler BIOS operations. This call may hold interrupts
- * off for a long time on some laptops.
+ * (bits 8-15 of eax) and this function returns non-zero (it can
+ * also return -ENOMEM). This is used for simpler BIOS operations.
+ * This call may hold interrupts off for a long time on some laptops.
+ *
+ * Note: this makes the call on the current CPU.
*/
-
-static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
+static long __apm_bios_call_simple(void *_call)
{
u8 error;
APM_DECL_SEGS
unsigned long flags;
- cpumask_t cpus;
int cpu;
struct desc_struct save_desc_40;
struct desc_struct *gdt;
-
- cpus = apm_save_cpus();
+ struct apm_bios_call *call = _call;
cpu = get_cpu();
+ BUG_ON(cpu != 0);
gdt = get_cpu_gdt_table(cpu);
save_desc_40 = gdt[0x40 / 8];
gdt[0x40 / 8] = bad_bios_desc;
apm_irq_save(flags);
APM_DO_SAVE_SEGS;
- error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
+ error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx,
+ &call->eax);
APM_DO_RESTORE_SEGS;
apm_irq_restore(flags);
gdt[0x40 / 8] = save_desc_40;
put_cpu();
- apm_restore_cpus(cpus);
return error;
}
/**
+ * apm_bios_call_simple - make a simple APM BIOS 32bit call
+ * @func: APM function to invoke
+ * @ebx_in: EBX register value for BIOS call
+ * @ecx_in: ECX register value for BIOS call
+ * @eax: EAX register on return from the BIOS call
+ * @err: bits
+ *
+ * Make a BIOS call that returns one value only, or just status.
+ * If there is an error, then the error code is returned in @err
+ * and this function returns non-zero. This is used for simpler
+ * BIOS operations. This call may hold interrupts off for a long
+ * time on some laptops.
+ */
+static int apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax,
+ int *err)
+{
+ struct apm_bios_call call;
+ int ret;
+
+ call.func = func;
+ call.ebx = ebx_in;
+ call.ecx = ecx_in;
+
+ ret = on_cpu0(__apm_bios_call_simple, &call);
+ *eax = call.eax;
+ *err = call.err;
+ return ret;
+}
+
+/**
* apm_driver_version - APM driver version
* @val: loaded with the APM version on return
*
@@ -678,9 +718,10 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
static int apm_driver_version(u_short *val)
{
u32 eax;
+ int err;
- if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax))
- return (eax >> 8) & 0xff;
+ if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax, &err))
+ return err;
*val = eax;
return APM_SUCCESS;
}
@@ -701,22 +742,21 @@ static int apm_driver_version(u_short *val)
* that APM 1.2 is in use. If no messges are pending the value 0x80
* is returned (No power management events pending).
*/
-
static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
{
- u32 eax;
- u32 ebx;
- u32 ecx;
- u32 dummy;
+ struct apm_bios_call call;
- if (apm_bios_call(APM_FUNC_GET_EVENT, 0, 0, &eax, &ebx, &ecx,
- &dummy, &dummy))
- return (eax >> 8) & 0xff;
- *event = ebx;
+ call.func = APM_FUNC_GET_EVENT;
+ call.ebx = call.ecx = 0;
+
+ if (apm_bios_call(&call))
+ return call.err;
+
+ *event = call.ebx;
if (apm_info.connection_version < 0x0102)
*info = ~0; /* indicate info not valid */
else
- *info = ecx;
+ *info = call.ecx;
return APM_SUCCESS;
}
@@ -737,9 +777,10 @@ static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
static int set_power_state(u_short what, u_short state)
{
u32 eax;
+ int err;
- if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax))
- return (eax >> 8) & 0xff;
+ if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax, &err))
+ return err;
return APM_SUCCESS;
}
@@ -770,6 +811,7 @@ static int apm_do_idle(void)
u8 ret = 0;
int idled = 0;
int polling;
+ int err;
polling = !!(current_thread_info()->status & TS_POLLING);
if (polling) {
@@ -782,7 +824,7 @@ static int apm_do_idle(void)
}
if (!need_resched()) {
idled = 1;
- ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax);
+ ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax, &err);
}
if (polling)
current_thread_info()->status |= TS_POLLING;
@@ -797,8 +839,7 @@ static int apm_do_idle(void)
* Only report the failure the first 5 times.
*/
if (++t < 5) {
- printk(KERN_DEBUG "apm_do_idle failed (%d)\n",
- (eax >> 8) & 0xff);
+ printk(KERN_DEBUG "apm_do_idle failed (%d)\n", err);
t = jiffies;
}
return -1;
@@ -816,9 +857,10 @@ static int apm_do_idle(void)
static void apm_do_busy(void)
{
u32 dummy;
+ int err;
if (clock_slowed || ALWAYS_CALL_BUSY) {
- (void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy);
+ (void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy, &err);
clock_slowed = 0;
}
}
@@ -937,7 +979,7 @@ static void apm_power_off(void)
/* Some bioses don't like being called from CPU != 0 */
if (apm_info.realmode_power_off) {
- (void)apm_save_cpus();
+ set_cpus_allowed_ptr(current, cpumask_of(0));
machine_real_restart(po_bios_call, sizeof(po_bios_call));
} else {
(void)set_system_power_state(APM_STATE_OFF);
@@ -956,12 +998,13 @@ static void apm_power_off(void)
static int apm_enable_power_management(int enable)
{
u32 eax;
+ int err;
if ((enable == 0) && (apm_info.bios.flags & APM_BIOS_DISENGAGED))
return APM_NOT_ENGAGED;
if (apm_bios_call_simple(APM_FUNC_ENABLE_PM, APM_DEVICE_BALL,
- enable, &eax))
- return (eax >> 8) & 0xff;
+ enable, &eax, &err))
+ return err;
if (enable)
apm_info.bios.flags &= ~APM_BIOS_DISABLED;
else
@@ -986,24 +1029,23 @@ static int apm_enable_power_management(int enable)
static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
{
- u32 eax;
- u32 ebx;
- u32 ecx;
- u32 edx;
- u32 dummy;
+ struct apm_bios_call call;
+
+ call.func = APM_FUNC_GET_STATUS;
+ call.ebx = APM_DEVICE_ALL;
+ call.ecx = 0;
if (apm_info.get_power_status_broken)
return APM_32_UNSUPPORTED;
- if (apm_bios_call(APM_FUNC_GET_STATUS, APM_DEVICE_ALL, 0,
- &eax, &ebx, &ecx, &edx, &dummy))
- return (eax >> 8) & 0xff;
- *status = ebx;
- *bat = ecx;
+ if (apm_bios_call(&call))
+ return call.err;
+ *status = call.ebx;
+ *bat = call.ecx;
if (apm_info.get_power_status_swabinminutes) {
- *life = swab16((u16)edx);
+ *life = swab16((u16)call.edx);
*life |= 0x8000;
} else
- *life = edx;
+ *life = call.edx;
return APM_SUCCESS;
}
@@ -1048,12 +1090,14 @@ static int apm_get_battery_status(u_short which, u_short *status,
static int apm_engage_power_management(u_short device, int enable)
{
u32 eax;
+ int err;
if ((enable == 0) && (device == APM_DEVICE_ALL)
&& (apm_info.bios.flags & APM_BIOS_DISABLED))
return APM_DISABLED;
- if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, enable, &eax))
- return (eax >> 8) & 0xff;
+ if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, enable,
+ &eax, &err))
+ return err;
if (device == APM_DEVICE_ALL) {
if (enable)
apm_info.bios.flags &= ~APM_BIOS_DISENGAGED;
@@ -1689,16 +1733,14 @@ static int apm(void *unused)
char *power_stat;
char *bat_stat;
-#ifdef CONFIG_SMP
/* 2002/08/01 - WT
* This is to avoid random crashes at boot time during initialization
* on SMP systems in case of "apm=power-off" mode. Seen on ASUS A7M266D.
* Some bioses don't like being called from CPU != 0.
* Method suggested by Ingo Molnar.
*/
- set_cpus_allowed(current, cpumask_of_cpu(0));
+ set_cpus_allowed_ptr(current, cpumask_of(0));
BUG_ON(smp_processor_id() != 0);
-#endif
if (apm_info.connection_version == 0) {
apm_info.connection_version = apm_info.bios.version;
diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c
index 8220ae69849..c965e521271 100644
--- a/arch/x86/kernel/cpu/addon_cpuid_features.c
+++ b/arch/x86/kernel/cpu/addon_cpuid_features.c
@@ -31,6 +31,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
{ X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
+ { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 },
{ 0, 0, 0, 0 }
};
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index e2962cc1e27..c4f667896c2 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -41,8 +41,6 @@
#include "cpu.h"
-#ifdef CONFIG_X86_64
-
/* all of these masks are initialized in setup_cpu_local_masks() */
cpumask_var_t cpu_initialized_mask;
cpumask_var_t cpu_callout_mask;
@@ -60,16 +58,6 @@ void __init setup_cpu_local_masks(void)
alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);
}
-#else /* CONFIG_X86_32 */
-
-cpumask_t cpu_sibling_setup_map;
-cpumask_t cpu_callout_map;
-cpumask_t cpu_initialized;
-cpumask_t cpu_callin_map;
-
-#endif /* CONFIG_X86_32 */
-
-
static const struct cpu_dev *this_cpu __cpuinitdata;
DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
@@ -859,6 +847,7 @@ static void vgetcpu_set_mode(void)
void __init identify_boot_cpu(void)
{
identify_cpu(&boot_cpu_data);
+ init_c1e_mask();
#ifdef CONFIG_X86_32
sysenter_setup();
enable_sep_cpu();
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index 46e29ab96c6..46e29ab96c6 100755..100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 23da96e57b1..837c2c4cc20 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -33,7 +33,7 @@
#include <linux/cpufreq.h>
#include <linux/compiler.h>
#include <linux/dmi.h>
-#include <linux/ftrace.h>
+#include <trace/power.h>
#include <linux/acpi.h>
#include <linux/io.h>
@@ -68,10 +68,13 @@ struct acpi_cpufreq_data {
unsigned int max_freq;
unsigned int resume;
unsigned int cpu_feature;
+ u64 saved_aperf, saved_mperf;
};
static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data);
+DEFINE_TRACE(power_mark);
+
/* acpi_perf_data is a pointer to percpu data. */
static struct acpi_processor_performance *acpi_perf_data;
@@ -150,7 +153,8 @@ struct drv_cmd {
u32 val;
};
-static long do_drv_read(void *_cmd)
+/* Called via smp_call_function_single(), on the target CPU */
+static void do_drv_read(void *_cmd)
{
struct drv_cmd *cmd = _cmd;
u32 h;
@@ -167,10 +171,10 @@ static long do_drv_read(void *_cmd)
default:
break;
}
- return 0;
}
-static long do_drv_write(void *_cmd)
+/* Called via smp_call_function_many(), on the target CPUs */
+static void do_drv_write(void *_cmd)
{
struct drv_cmd *cmd = _cmd;
u32 lo, hi;
@@ -189,23 +193,18 @@ static long do_drv_write(void *_cmd)
default:
break;
}
- return 0;
}
static void drv_read(struct drv_cmd *cmd)
{
cmd->val = 0;
- work_on_cpu(cpumask_any(cmd->mask), do_drv_read, cmd);
+ smp_call_function_single(cpumask_any(cmd->mask), do_drv_read, cmd, 1);
}
static void drv_write(struct drv_cmd *cmd)
{
- unsigned int i;
-
- for_each_cpu(i, cmd->mask) {
- work_on_cpu(i, do_drv_write, cmd);
- }
+ smp_call_function_many(cmd->mask, do_drv_write, cmd, 1);
}
static u32 get_cur_val(const struct cpumask *mask)
@@ -239,28 +238,23 @@ static u32 get_cur_val(const struct cpumask *mask)
return cmd.val;
}
-struct perf_cur {
+struct perf_pair {
union {
struct {
u32 lo;
u32 hi;
} split;
u64 whole;
- } aperf_cur, mperf_cur;
+ } aperf, mperf;
};
-
-static long read_measured_perf_ctrs(void *_cur)
+/* Called via smp_call_function_single(), on the target CPU */
+static void read_measured_perf_ctrs(void *_cur)
{
- struct perf_cur *cur = _cur;
+ struct perf_pair *cur = _cur;
- rdmsr(MSR_IA32_APERF, cur->aperf_cur.split.lo, cur->aperf_cur.split.hi);
- rdmsr(MSR_IA32_MPERF, cur->mperf_cur.split.lo, cur->mperf_cur.split.hi);
-
- wrmsr(MSR_IA32_APERF, 0, 0);
- wrmsr(MSR_IA32_MPERF, 0, 0);
-
- return 0;
+ rdmsr(MSR_IA32_APERF, cur->aperf.split.lo, cur->aperf.split.hi);
+ rdmsr(MSR_IA32_MPERF, cur->mperf.split.lo, cur->mperf.split.hi);
}
/*
@@ -279,52 +273,57 @@ static long read_measured_perf_ctrs(void *_cur)
static unsigned int get_measured_perf(struct cpufreq_policy *policy,
unsigned int cpu)
{
- struct perf_cur cur;
+ struct perf_pair readin, cur;
unsigned int perf_percent;
unsigned int retval;
- if (!work_on_cpu(cpu, read_measured_perf_ctrs, &cur))
+ if (smp_call_function_single(cpu, read_measured_perf_ctrs, &readin, 1))
return 0;
+ cur.aperf.whole = readin.aperf.whole -
+ per_cpu(drv_data, cpu)->saved_aperf;
+ cur.mperf.whole = readin.mperf.whole -
+ per_cpu(drv_data, cpu)->saved_mperf;
+ per_cpu(drv_data, cpu)->saved_aperf = readin.aperf.whole;
+ per_cpu(drv_data, cpu)->saved_mperf = readin.mperf.whole;
+
#ifdef __i386__
/*
* We dont want to do 64 bit divide with 32 bit kernel
* Get an approximate value. Return failure in case we cannot get
* an approximate value.
*/
- if (unlikely(cur.aperf_cur.split.hi || cur.mperf_cur.split.hi)) {
+ if (unlikely(cur.aperf.split.hi || cur.mperf.split.hi)) {
int shift_count;
u32 h;
- h = max_t(u32, cur.aperf_cur.split.hi, cur.mperf_cur.split.hi);
+ h = max_t(u32, cur.aperf.split.hi, cur.mperf.split.hi);
shift_count = fls(h);
- cur.aperf_cur.whole >>= shift_count;
- cur.mperf_cur.whole >>= shift_count;
+ cur.aperf.whole >>= shift_count;
+ cur.mperf.whole >>= shift_count;
}
- if (((unsigned long)(-1) / 100) < cur.aperf_cur.split.lo) {
+ if (((unsigned long)(-1) / 100) < cur.aperf.split.lo) {
int shift_count = 7;
- cur.aperf_cur.split.lo >>= shift_count;
- cur.mperf_cur.split.lo >>= shift_count;
+ cur.aperf.split.lo >>= shift_count;
+ cur.mperf.split.lo >>= shift_count;
}
- if (cur.aperf_cur.split.lo && cur.mperf_cur.split.lo)
- perf_percent = (cur.aperf_cur.split.lo * 100) /
- cur.mperf_cur.split.lo;
+ if (cur.aperf.split.lo && cur.mperf.split.lo)
+ perf_percent = (cur.aperf.split.lo * 100) / cur.mperf.split.lo;
else
perf_percent = 0;
#else
- if (unlikely(((unsigned long)(-1) / 100) < cur.aperf_cur.whole)) {
+ if (unlikely(((unsigned long)(-1) / 100) < cur.aperf.whole)) {
int shift_count = 7;
- cur.aperf_cur.whole >>= shift_count;
- cur.mperf_cur.whole >>= shift_count;
+ cur.aperf.whole >>= shift_count;
+ cur.mperf.whole >>= shift_count;
}
- if (cur.aperf_cur.whole && cur.mperf_cur.whole)
- perf_percent = (cur.aperf_cur.whole * 100) /
- cur.mperf_cur.whole;
+ if (cur.aperf.whole && cur.mperf.whole)
+ perf_percent = (cur.aperf.whole * 100) / cur.mperf.whole;
else
perf_percent = 0;
@@ -680,6 +679,18 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
perf->states[i].transition_latency * 1000;
}
+ /* Check for high latency (>20uS) from buggy BIOSes, like on T42 */
+ if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE &&
+ policy->cpuinfo.transition_latency > 20 * 1000) {
+ static int print_once;
+ policy->cpuinfo.transition_latency = 20 * 1000;
+ if (!print_once) {
+ print_once = 1;
+ printk(KERN_INFO "Capping off P-state tranision latency"
+ " at 20 uS\n");
+ }
+ }
+
data->max_freq = perf->states[0].core_frequency * 1000;
/* table init */
for (i = 0; i < perf->state_count; i++) {
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c
index f1c51aea064..ce2ed3e4aad 100644
--- a/arch/x86/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c
@@ -33,7 +33,6 @@
#include <linux/timex.h>
#include <linux/io.h>
#include <linux/acpi.h>
-#include <linux/kernel.h>
#include <asm/msr.h>
#include <acpi/processor.h>
@@ -305,7 +304,7 @@ retry_loop:
outb(3, 0x22);
} else if ((pr != NULL) && pr->flags.bm_control) {
/* Disable bus master arbitration */
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+ acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
}
switch (longhaul_version) {
@@ -328,7 +327,7 @@ retry_loop:
case TYPE_POWERSAVER:
if (longhaul_flags & USE_ACPI_C3) {
/* Don't allow wakeup */
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
+ acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
do_powersaver(cx->address, mults_index, dir);
} else {
do_powersaver(0, mults_index, dir);
@@ -341,7 +340,7 @@ retry_loop:
outb(0, 0x22);
} else if ((pr != NULL) && pr->flags.bm_control) {
/* Enable bus master arbitration */
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+ acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
}
outb(pic2_mask, 0xA1); /* restore mask */
outb(pic1_mask, 0x21);
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
index 41ed94915f9..6ac55bd341a 100644
--- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
@@ -211,7 +211,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
unsigned int i;
#ifdef CONFIG_SMP
- cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu));
+ cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
#endif
/* Errata workaround */
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index a15ac94e0b9..4709ead2db5 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -54,7 +54,10 @@ static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data);
static int cpu_family = CPU_OPTERON;
#ifndef CONFIG_SMP
-DEFINE_PER_CPU(cpumask_t, cpu_core_map);
+static inline const struct cpumask *cpu_core_mask(int cpu)
+{
+ return cpumask_of(0);
+}
#endif
/* Return a frequency in MHz, given an input fid */
@@ -699,7 +702,7 @@ static int fill_powernow_table(struct powernow_k8_data *data,
dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
data->powernow_table = powernow_table;
- if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
+ if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
print_basics(data);
for (j = 0; j < data->numps; j++)
@@ -862,7 +865,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
/* fill in data */
data->numps = data->acpi_data.state_count;
- if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
+ if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
print_basics(data);
powernow_k8_acpi_pst_values(data, 0);
@@ -1300,7 +1303,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
if (cpu_family == CPU_HW_PSTATE)
cpumask_copy(pol->cpus, cpumask_of(pol->cpu));
else
- cpumask_copy(pol->cpus, &per_cpu(cpu_core_map, pol->cpu));
+ cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu));
data->available_cores = pol->cpus;
if (cpu_family == CPU_HW_PSTATE)
@@ -1365,7 +1368,7 @@ static unsigned int powernowk8_get(unsigned int cpu)
unsigned int khz = 0;
unsigned int first;
- first = first_cpu(per_cpu(cpu_core_map, cpu));
+ first = cpumask_first(cpu_core_mask(cpu));
data = per_cpu(powernow_data, first);
if (!data)
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
index 8bbb11adb31..016c1a4fa3f 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
@@ -321,7 +321,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
/* only run on CPU to be set, or on its sibling */
#ifdef CONFIG_SMP
- cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu));
+ cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
#endif
cpus_allowed = current->cpus_allowed;
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index c471eb1a389..483eda96e10 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -159,7 +159,7 @@ struct _cpuid4_info_regs {
unsigned long can_disable;
};
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && defined(CONFIG_SYSFS)
static struct pci_device_id k8_nb_id[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1203) },
@@ -324,15 +324,6 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
return 0;
}
-static int
-__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
-{
- struct _cpuid4_info_regs *leaf_regs =
- (struct _cpuid4_info_regs *)this_leaf;
-
- return cpuid4_cache_lookup_regs(index, leaf_regs);
-}
-
static int __cpuinit find_num_cache_leaves(void)
{
unsigned int eax, ebx, ecx, edx;
@@ -508,6 +499,8 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
return l2;
}
+#ifdef CONFIG_SYSFS
+
/* pointer to _cpuid4_info array (for each cache leaf) */
static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info);
#define CPUID4_INFO_IDX(x, y) (&((per_cpu(cpuid4_info, x))[y]))
@@ -571,6 +564,15 @@ static void __cpuinit free_cache_attributes(unsigned int cpu)
per_cpu(cpuid4_info, cpu) = NULL;
}
+static int
+__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
+{
+ struct _cpuid4_info_regs *leaf_regs =
+ (struct _cpuid4_info_regs *)this_leaf;
+
+ return cpuid4_cache_lookup_regs(index, leaf_regs);
+}
+
static void __cpuinit get_cpu_leaves(void *_retval)
{
int j, *retval = _retval, cpu = smp_processor_id();
@@ -612,8 +614,6 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu)
return retval;
}
-#ifdef CONFIG_SYSFS
-
#include <linux/kobject.h>
#include <linux/sysfs.h>
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
index ca14604611e..863f89568b1 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_64.c
@@ -990,7 +990,7 @@ static struct sysdev_attribute *mce_attributes[] = {
NULL
};
-static cpumask_t mce_device_initialized = CPU_MASK_NONE;
+static cpumask_var_t mce_device_initialized;
/* Per cpu sysdev init. All of the cpus still share the same ctl bank */
static __cpuinit int mce_create_device(unsigned int cpu)
@@ -1021,7 +1021,7 @@ static __cpuinit int mce_create_device(unsigned int cpu)
if (err)
goto error2;
}
- cpu_set(cpu, mce_device_initialized);
+ cpumask_set_cpu(cpu, mce_device_initialized);
return 0;
error2:
@@ -1043,7 +1043,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu)
{
int i;
- if (!cpu_isset(cpu, mce_device_initialized))
+ if (!cpumask_test_cpu(cpu, mce_device_initialized))
return;
for (i = 0; mce_attributes[i]; i++)
@@ -1053,7 +1053,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu)
sysdev_remove_file(&per_cpu(device_mce, cpu),
&bank_attrs[i]);
sysdev_unregister(&per_cpu(device_mce,cpu));
- cpu_clear(cpu, mce_device_initialized);
+ cpumask_clear_cpu(cpu, mce_device_initialized);
}
/* Make sure there are no machine checks on offlined CPUs. */
@@ -1162,6 +1162,8 @@ static __init int mce_init_device(void)
if (!mce_available(&boot_cpu_data))
return -EIO;
+ alloc_cpumask_var(&mce_device_initialized, GFP_KERNEL);
+
err = mce_init_banks();
if (err)
return err;
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
index 7d01be86887..56dde9c4bc9 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
@@ -485,7 +485,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
#ifdef CONFIG_SMP
if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) { /* symlink */
- i = cpumask_first(&per_cpu(cpu_core_map, cpu));
+ i = cpumask_first(cpu_core_mask(cpu));
/* first core not up yet */
if (cpu_data(i).cpu_core_id)
@@ -505,7 +505,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
if (err)
goto out;
- cpumask_copy(b->cpus, &per_cpu(cpu_core_map, cpu));
+ cpumask_copy(b->cpus, cpu_core_mask(cpu));
per_cpu(threshold_banks, cpu)[bank] = b;
goto out;
}
@@ -529,7 +529,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
#ifndef CONFIG_SMP
cpumask_setall(b->cpus);
#else
- cpumask_copy(b->cpus, &per_cpu(cpu_core_map, cpu));
+ cpumask_copy(b->cpus, cpu_core_mask(cpu));
#endif
per_cpu(threshold_banks, cpu)[bank] = b;
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
index 57df3d38347..d6b72df89d6 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
@@ -249,7 +249,7 @@ void cmci_rediscover(int dying)
for_each_online_cpu (cpu) {
if (cpu == dying)
continue;
- if (set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)))
+ if (set_cpus_allowed_ptr(current, cpumask_of(cpu)))
continue;
/* Recheck banks in case CPUs don't all have the same */
if (cmci_supported(&banks))
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 37f28fc7cf9..0b776c09aff 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -462,9 +462,6 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
*base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
*type = base_lo & 0xff;
- printk(KERN_DEBUG " get_mtrr: cpu%d reg%02d base=%010lx size=%010lx %s\n",
- cpu, reg, *base, *size,
- mtrr_attrib_to_str(*type & 0xff));
out_put_cpu:
put_cpu();
}
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index d67e0e48bc2..f93047fed79 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -14,7 +14,7 @@ static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c,
if (c->x86_max_cores * smp_num_siblings > 1) {
seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
seq_printf(m, "siblings\t: %d\n",
- cpus_weight(per_cpu(cpu_core_map, cpu)));
+ cpumask_weight(cpu_sibling_mask(cpu)));
seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
seq_printf(m, "apicid\t\t: %d\n", c->apicid);
@@ -143,9 +143,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
static void *c_start(struct seq_file *m, loff_t *pos)
{
if (*pos == 0) /* just in case, cpu 0 is not the first */
- *pos = first_cpu(cpu_online_map);
+ *pos = cpumask_first(cpu_online_mask);
else
- *pos = next_cpu_nr(*pos - 1, cpu_online_map);
+ *pos = cpumask_next(*pos - 1, cpu_online_mask);
if ((*pos) < nr_cpu_ids)
return &cpu_data(*pos);
return NULL;
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index dd2130b0fb3..95ea5fa7d44 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -15,6 +15,7 @@
#include <linux/bug.h>
#include <linux/nmi.h>
#include <linux/sysfs.h>
+#include <linux/ftrace.h>
#include <asm/stacktrace.h>
@@ -196,6 +197,11 @@ unsigned __kprobes long oops_begin(void)
int cpu;
unsigned long flags;
+ /* notify the hw-branch tracer so it may disable tracing and
+ add the last trace to the trace buffer -
+ the earlier this happens, the more useful the trace. */
+ trace_hw_branch_oops();
+
oops_enter();
/* racy, but better than risking deadlock. */
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 76f7141e0f9..18dfa30795c 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -18,14 +18,28 @@
#include <linux/init.h>
#include <linux/list.h>
+#include <trace/syscall.h>
+
+#include <asm/cacheflush.h>
#include <asm/ftrace.h>
-#include <linux/ftrace.h>
#include <asm/nops.h>
#include <asm/nmi.h>
#ifdef CONFIG_DYNAMIC_FTRACE
+int ftrace_arch_code_modify_prepare(void)
+{
+ set_kernel_text_rw();
+ return 0;
+}
+
+int ftrace_arch_code_modify_post_process(void)
+{
+ set_kernel_text_ro();
+ return 0;
+}
+
union ftrace_code_union {
char code[MCOUNT_INSN_SIZE];
struct {
@@ -66,11 +80,11 @@ static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
*
* 1) Put the instruction pointer into the IP buffer
* and the new code into the "code" buffer.
- * 2) Set a flag that says we are modifying code
- * 3) Wait for any running NMIs to finish.
- * 4) Write the code
- * 5) clear the flag.
- * 6) Wait for any running NMIs to finish.
+ * 2) Wait for any running NMIs to finish and set a flag that says
+ * we are modifying code, it is done in an atomic operation.
+ * 3) Write the code
+ * 4) clear the flag.
+ * 5) Wait for any running NMIs to finish.
*
* If an NMI is executed, the first thing it does is to call
* "ftrace_nmi_enter". This will check if the flag is set to write
@@ -82,9 +96,9 @@ static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
* are the same as what exists.
*/
-static atomic_t in_nmi = ATOMIC_INIT(0);
+#define MOD_CODE_WRITE_FLAG (1 << 31) /* set when NMI should do the write */
+static atomic_t nmi_running = ATOMIC_INIT(0);
static int mod_code_status; /* holds return value of text write */
-static int mod_code_write; /* set when NMI should do the write */
static void *mod_code_ip; /* holds the IP to write to */
static void *mod_code_newcode; /* holds the text to write to the IP */
@@ -101,6 +115,20 @@ int ftrace_arch_read_dyn_info(char *buf, int size)
return r;
}
+static void clear_mod_flag(void)
+{
+ int old = atomic_read(&nmi_running);
+
+ for (;;) {
+ int new = old & ~MOD_CODE_WRITE_FLAG;
+
+ if (old == new)
+ break;
+
+ old = atomic_cmpxchg(&nmi_running, old, new);
+ }
+}
+
static void ftrace_mod_code(void)
{
/*
@@ -111,37 +139,52 @@ static void ftrace_mod_code(void)
*/
mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode,
MCOUNT_INSN_SIZE);
+
+ /* if we fail, then kill any new writers */
+ if (mod_code_status)
+ clear_mod_flag();
}
void ftrace_nmi_enter(void)
{
- atomic_inc(&in_nmi);
- /* Must have in_nmi seen before reading write flag */
- smp_mb();
- if (mod_code_write) {
+ if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) {
+ smp_rmb();
ftrace_mod_code();
atomic_inc(&nmi_update_count);
}
+ /* Must have previous changes seen before executions */
+ smp_mb();
}
void ftrace_nmi_exit(void)
{
- /* Finish all executions before clearing in_nmi */
- smp_wmb();
- atomic_dec(&in_nmi);
+ /* Finish all executions before clearing nmi_running */
+ smp_mb();
+ atomic_dec(&nmi_running);
+}
+
+static void wait_for_nmi_and_set_mod_flag(void)
+{
+ if (!atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG))
+ return;
+
+ do {
+ cpu_relax();
+ } while (atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG));
+
+ nmi_wait_count++;
}
static void wait_for_nmi(void)
{
- int waited = 0;
+ if (!atomic_read(&nmi_running))
+ return;
- while (atomic_read(&in_nmi)) {
- waited = 1;
+ do {
cpu_relax();
- }
+ } while (atomic_read(&nmi_running));
- if (waited)
- nmi_wait_count++;
+ nmi_wait_count++;
}
static int
@@ -151,14 +194,9 @@ do_ftrace_mod_code(unsigned long ip, void *new_code)
mod_code_newcode = new_code;
/* The buffers need to be visible before we let NMIs write them */
- smp_wmb();
-
- mod_code_write = 1;
-
- /* Make sure write bit is visible before we wait on NMIs */
smp_mb();
- wait_for_nmi();
+ wait_for_nmi_and_set_mod_flag();
/* Make sure all running NMIs have finished before we write the code */
smp_mb();
@@ -166,13 +204,9 @@ do_ftrace_mod_code(unsigned long ip, void *new_code)
ftrace_mod_code();
/* Make sure the write happens before clearing the bit */
- smp_wmb();
-
- mod_code_write = 0;
-
- /* make sure NMIs see the cleared bit */
smp_mb();
+ clear_mod_flag();
wait_for_nmi();
return mod_code_status;
@@ -368,25 +402,6 @@ int ftrace_disable_ftrace_graph_caller(void)
return ftrace_mod_jmp(ip, old_offset, new_offset);
}
-#else /* CONFIG_DYNAMIC_FTRACE */
-
-/*
- * These functions are picked from those used on
- * this page for dynamic ftrace. They have been
- * simplified to ignore all traces in NMI context.
- */
-static atomic_t in_nmi;
-
-void ftrace_nmi_enter(void)
-{
- atomic_inc(&in_nmi);
-}
-
-void ftrace_nmi_exit(void)
-{
- atomic_dec(&in_nmi);
-}
-
#endif /* !CONFIG_DYNAMIC_FTRACE */
/*
@@ -396,14 +411,13 @@ void ftrace_nmi_exit(void)
void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
{
unsigned long old;
- unsigned long long calltime;
int faulted;
struct ftrace_graph_ent trace;
unsigned long return_hooker = (unsigned long)
&return_to_handler;
/* Nmi's are currently unsupported */
- if (unlikely(atomic_read(&in_nmi)))
+ if (unlikely(in_nmi()))
return;
if (unlikely(atomic_read(&current->tracing_graph_pause)))
@@ -439,17 +453,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
return;
}
- if (unlikely(!__kernel_text_address(old))) {
- ftrace_graph_stop();
- *parent = old;
- WARN_ON(1);
- return;
- }
-
- calltime = cpu_clock(raw_smp_processor_id());
-
- if (ftrace_push_return_trace(old, calltime,
- self_addr, &trace.depth) == -EBUSY) {
+ if (ftrace_push_return_trace(old, self_addr, &trace.depth) == -EBUSY) {
*parent = old;
return;
}
@@ -463,3 +467,66 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
}
}
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+#ifdef CONFIG_FTRACE_SYSCALLS
+
+extern unsigned long __start_syscalls_metadata[];
+extern unsigned long __stop_syscalls_metadata[];
+extern unsigned long *sys_call_table;
+
+static struct syscall_metadata **syscalls_metadata;
+
+static struct syscall_metadata *find_syscall_meta(unsigned long *syscall)
+{
+ struct syscall_metadata *start;
+ struct syscall_metadata *stop;
+ char str[KSYM_SYMBOL_LEN];
+
+
+ start = (struct syscall_metadata *)__start_syscalls_metadata;
+ stop = (struct syscall_metadata *)__stop_syscalls_metadata;
+ kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str);
+
+ for ( ; start < stop; start++) {
+ if (start->name && !strcmp(start->name, str))
+ return start;
+ }
+ return NULL;
+}
+
+struct syscall_metadata *syscall_nr_to_meta(int nr)
+{
+ if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0)
+ return NULL;
+
+ return syscalls_metadata[nr];
+}
+
+void arch_init_ftrace_syscalls(void)
+{
+ int i;
+ struct syscall_metadata *meta;
+ unsigned long **psys_syscall_table = &sys_call_table;
+ static atomic_t refs;
+
+ if (atomic_inc_return(&refs) != 1)
+ goto end;
+
+ syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
+ FTRACE_SYSCALL_MAX, GFP_KERNEL);
+ if (!syscalls_metadata) {
+ WARN_ON(1);
+ return;
+ }
+
+ for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
+ meta = find_syscall_meta(psys_syscall_table[i]);
+ syscalls_metadata[i] = meta;
+ }
+ return;
+
+ /* Paranoid: avoid overflow */
+end:
+ atomic_dec(&refs);
+}
+#endif
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 3aaf7b9e3a8..c3fe010d74c 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -65,7 +65,7 @@ static int show_other_interrupts(struct seq_file *p, int prec)
seq_printf(p, " Spurious interrupts\n");
#endif
if (generic_interrupt_extension) {
- seq_printf(p, "PLT: ");
+ seq_printf(p, "%*s: ", prec, "PLT");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->generic_irqs);
seq_printf(p, " Platform interrupts\n");
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 55b94614e34..7b5169d2b00 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -638,13 +638,13 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
#else
" pushf\n"
/*
- * Skip cs, ip, orig_ax.
+ * Skip cs, ip, orig_ax and gs.
* trampoline_handler() will plug in these values
*/
- " subl $12, %esp\n"
+ " subl $16, %esp\n"
" pushl %fs\n"
- " pushl %ds\n"
" pushl %es\n"
+ " pushl %ds\n"
" pushl %eax\n"
" pushl %ebp\n"
" pushl %edi\n"
@@ -655,10 +655,10 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
" movl %esp, %eax\n"
" call trampoline_handler\n"
/* Move flags to cs */
- " movl 52(%esp), %edx\n"
- " movl %edx, 48(%esp)\n"
+ " movl 56(%esp), %edx\n"
+ " movl %edx, 52(%esp)\n"
/* Replace saved flags with true return address. */
- " movl %eax, 52(%esp)\n"
+ " movl %eax, 56(%esp)\n"
" popl %ebx\n"
" popl %ecx\n"
" popl %edx\n"
@@ -666,8 +666,8 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
" popl %edi\n"
" popl %ebp\n"
" popl %eax\n"
- /* Skip ip, orig_ax, es, ds, fs */
- " addl $20, %esp\n"
+ /* Skip ds, es, fs, gs, orig_ax and ip */
+ " addl $24, %esp\n"
" popf\n"
#endif
" ret\n");
@@ -691,6 +691,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
regs->cs = __KERNEL_CS;
#else
regs->cs = __KERNEL_CS | get_kernel_rpl();
+ regs->gs = 0;
#endif
regs->ip = trampoline_address;
regs->orig_ax = ~0UL;
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index c25fdb38229..453b5795a5c 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -12,31 +12,30 @@
*
* Licensed under the terms of the GNU General Public
* License version 2. See file COPYING for details.
-*/
-
+ */
+#include <linux/platform_device.h>
#include <linux/capability.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
#include <linux/miscdevice.h>
+#include <linux/firmware.h>
#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
+#include <linux/cpumask.h>
+#include <linux/pci_ids.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/cpu.h>
-#include <linux/firmware.h>
-#include <linux/platform_device.h>
#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
-#include <asm/msr.h>
-#include <asm/processor.h>
#include <asm/microcode.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
MODULE_DESCRIPTION("AMD Microcode Update Driver");
MODULE_AUTHOR("Peter Oruba");
@@ -72,8 +71,8 @@ struct microcode_header_amd {
} __attribute__((packed));
struct microcode_amd {
- struct microcode_header_amd hdr;
- unsigned int mpb[0];
+ struct microcode_header_amd hdr;
+ unsigned int mpb[0];
};
#define UCODE_MAX_SIZE 2048
@@ -184,8 +183,8 @@ static int get_ucode_data(void *to, const u8 *from, size_t n)
return 0;
}
-static void *get_next_ucode(const u8 *buf, unsigned int size,
- unsigned int *mc_size)
+static void *
+get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size)
{
unsigned int total_size;
u8 section_hdr[UCODE_CONTAINER_SECTION_HDR];
@@ -223,7 +222,6 @@ static void *get_next_ucode(const u8 *buf, unsigned int size,
return mc;
}
-
static int install_equiv_cpu_table(const u8 *buf)
{
u8 *container_hdr[UCODE_CONTAINER_HEADER_SIZE];
@@ -372,4 +370,3 @@ struct microcode_ops * __init init_amd_microcode(void)
{
return &microcode_amd_ops;
}
-
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index c9b721ba968..2e0eb414095 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -70,41 +70,41 @@
* Fix sigmatch() macro to handle old CPUs with pf == 0.
* Thanks to Stuart Swales for pointing out this bug.
*/
+#include <linux/platform_device.h>
#include <linux/capability.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/firmware.h>
#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
#include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/uaccess.h>
#include <linux/vmalloc.h>
-#include <linux/miscdevice.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/cpu.h>
-#include <linux/firmware.h>
-#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
-#include <asm/msr.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
#include <asm/microcode.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
MODULE_DESCRIPTION("Microcode Update Driver");
MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
MODULE_LICENSE("GPL");
-#define MICROCODE_VERSION "2.00"
+#define MICROCODE_VERSION "2.00"
-static struct microcode_ops *microcode_ops;
+static struct microcode_ops *microcode_ops;
/* no concurrent ->write()s are allowed on /dev/cpu/microcode */
static DEFINE_MUTEX(microcode_mutex);
-struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
+struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
EXPORT_SYMBOL_GPL(ucode_cpu_info);
#ifdef CONFIG_MICROCODE_OLD_INTERFACE
@@ -198,18 +198,33 @@ static void microcode_dev_exit(void)
MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
#else
-#define microcode_dev_init() 0
-#define microcode_dev_exit() do { } while (0)
+#define microcode_dev_init() 0
+#define microcode_dev_exit() do { } while (0)
#endif
/* fake device for request_firmware */
-static struct platform_device *microcode_pdev;
+static struct platform_device *microcode_pdev;
+
+static long reload_for_cpu(void *unused)
+{
+ struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id();
+ int err = 0;
+
+ mutex_lock(&microcode_mutex);
+ if (uci->valid) {
+ err = microcode_ops->request_microcode_fw(smp_processor_id(),
+ &microcode_pdev->dev);
+ if (!err)
+ microcode_ops->apply_microcode(smp_processor_id());
+ }
+ mutex_unlock(&microcode_mutex);
+ return err;
+}
static ssize_t reload_store(struct sys_device *dev,
struct sysdev_attribute *attr,
const char *buf, size_t sz)
{
- struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
char *end;
unsigned long val = simple_strtoul(buf, &end, 0);
int err = 0;
@@ -218,21 +233,9 @@ static ssize_t reload_store(struct sys_device *dev,
if (end == buf)
return -EINVAL;
if (val == 1) {
- cpumask_t old = current->cpus_allowed;
-
get_online_cpus();
- if (cpu_online(cpu)) {
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
- mutex_lock(&microcode_mutex);
- if (uci->valid) {
- err = microcode_ops->request_microcode_fw(cpu,
- &microcode_pdev->dev);
- if (!err)
- microcode_ops->apply_microcode(cpu);
- }
- mutex_unlock(&microcode_mutex);
- set_cpus_allowed_ptr(current, &old);
- }
+ if (cpu_online(cpu))
+ err = work_on_cpu(cpu, reload_for_cpu, NULL);
put_online_cpus();
}
if (err)
@@ -268,8 +271,8 @@ static struct attribute *mc_default_attrs[] = {
};
static struct attribute_group mc_attr_group = {
- .attrs = mc_default_attrs,
- .name = "microcode",
+ .attrs = mc_default_attrs,
+ .name = "microcode",
};
static void __microcode_fini_cpu(int cpu)
@@ -328,9 +331,9 @@ static int microcode_resume_cpu(int cpu)
return 0;
}
-static void microcode_update_cpu(int cpu)
+static long microcode_update_cpu(void *unused)
{
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+ struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id();
int err = 0;
/*
@@ -338,30 +341,27 @@ static void microcode_update_cpu(int cpu)
* otherwise just request a firmware:
*/
if (uci->valid) {
- err = microcode_resume_cpu(cpu);
- } else {
- collect_cpu_info(cpu);
+ err = microcode_resume_cpu(smp_processor_id());
+ } else {
+ collect_cpu_info(smp_processor_id());
if (uci->valid && system_state == SYSTEM_RUNNING)
- err = microcode_ops->request_microcode_fw(cpu,
+ err = microcode_ops->request_microcode_fw(
+ smp_processor_id(),
&microcode_pdev->dev);
}
if (!err)
- microcode_ops->apply_microcode(cpu);
+ microcode_ops->apply_microcode(smp_processor_id());
+ return err;
}
-static void microcode_init_cpu(int cpu)
+static int microcode_init_cpu(int cpu)
{
- cpumask_t old = current->cpus_allowed;
-
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
- /* We should bind the task to the CPU */
- BUG_ON(raw_smp_processor_id() != cpu);
-
+ int err;
mutex_lock(&microcode_mutex);
- microcode_update_cpu(cpu);
+ err = work_on_cpu(cpu, microcode_update_cpu, NULL);
mutex_unlock(&microcode_mutex);
- set_cpus_allowed_ptr(current, &old);
+ return err;
}
static int mc_sysdev_add(struct sys_device *sys_dev)
@@ -379,8 +379,11 @@ static int mc_sysdev_add(struct sys_device *sys_dev)
if (err)
return err;
- microcode_init_cpu(cpu);
- return 0;
+ err = microcode_init_cpu(cpu);
+ if (err)
+ sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
+
+ return err;
}
static int mc_sysdev_remove(struct sys_device *sys_dev)
@@ -404,14 +407,14 @@ static int mc_sysdev_resume(struct sys_device *dev)
return 0;
/* only CPU 0 will apply ucode here */
- microcode_update_cpu(0);
+ microcode_update_cpu(NULL);
return 0;
}
static struct sysdev_driver mc_sysdev_driver = {
- .add = mc_sysdev_add,
- .remove = mc_sysdev_remove,
- .resume = mc_sysdev_resume,
+ .add = mc_sysdev_add,
+ .remove = mc_sysdev_remove,
+ .resume = mc_sysdev_resume,
};
static __cpuinit int
@@ -424,7 +427,9 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
- microcode_init_cpu(cpu);
+ if (microcode_init_cpu(cpu))
+ printk(KERN_ERR "microcode: failed to init CPU%d\n",
+ cpu);
case CPU_DOWN_FAILED:
case CPU_DOWN_FAILED_FROZEN:
pr_debug("microcode: CPU%d added\n", cpu);
@@ -448,7 +453,7 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
}
static struct notifier_block __refdata mc_cpu_notifier = {
- .notifier_call = mc_cpu_callback,
+ .notifier_call = mc_cpu_callback,
};
static int __init microcode_init(void)
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index 5e9f4fc5138..149b9ec7c1a 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -70,28 +70,28 @@
* Fix sigmatch() macro to handle old CPUs with pf == 0.
* Thanks to Stuart Swales for pointing out this bug.
*/
+#include <linux/platform_device.h>
#include <linux/capability.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/firmware.h>
#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
#include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/uaccess.h>
#include <linux/vmalloc.h>
-#include <linux/miscdevice.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/cpu.h>
-#include <linux/firmware.h>
-#include <linux/platform_device.h>
-#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
-#include <asm/msr.h>
-#include <asm/processor.h>
#include <asm/microcode.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
MODULE_DESCRIPTION("Microcode Update Driver");
MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
@@ -129,12 +129,13 @@ struct extended_sigtable {
struct extended_signature sigs[0];
};
-#define DEFAULT_UCODE_DATASIZE (2000)
+#define DEFAULT_UCODE_DATASIZE (2000)
#define MC_HEADER_SIZE (sizeof(struct microcode_header_intel))
#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)
#define EXT_HEADER_SIZE (sizeof(struct extended_sigtable))
#define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature))
#define DWSIZE (sizeof(u32))
+
#define get_totalsize(mc) \
(((struct microcode_intel *)mc)->hdr.totalsize ? \
((struct microcode_intel *)mc)->hdr.totalsize : \
@@ -197,30 +198,31 @@ static inline int update_match_cpu(struct cpu_signature *csig, int sig, int pf)
}
static inline int
-update_match_revision(struct microcode_header_intel *mc_header, int rev)
+update_match_revision(struct microcode_header_intel *mc_header, int rev)
{
return (mc_header->rev <= rev) ? 0 : 1;
}
static int microcode_sanity_check(void *mc)
{
+ unsigned long total_size, data_size, ext_table_size;
struct microcode_header_intel *mc_header = mc;
struct extended_sigtable *ext_header = NULL;
- struct extended_signature *ext_sig;
- unsigned long total_size, data_size, ext_table_size;
int sum, orig_sum, ext_sigcount = 0, i;
+ struct extended_signature *ext_sig;
total_size = get_totalsize(mc_header);
data_size = get_datasize(mc_header);
+
if (data_size + MC_HEADER_SIZE > total_size) {
printk(KERN_ERR "microcode: error! "
- "Bad data size in microcode data file\n");
+ "Bad data size in microcode data file\n");
return -EINVAL;
}
if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {
printk(KERN_ERR "microcode: error! "
- "Unknown microcode update format\n");
+ "Unknown microcode update format\n");
return -EINVAL;
}
ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
@@ -318,11 +320,15 @@ get_matching_microcode(struct cpu_signature *cpu_sig, void *mc, int rev)
static void apply_microcode(int cpu)
{
+ struct microcode_intel *mc_intel;
+ struct ucode_cpu_info *uci;
unsigned long flags;
unsigned int val[2];
- int cpu_num = raw_smp_processor_id();
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
- struct microcode_intel *mc_intel = uci->mc;
+ int cpu_num;
+
+ cpu_num = raw_smp_processor_id();
+ uci = ucode_cpu_info + cpu;
+ mc_intel = uci->mc;
/* We should bind the task to the CPU */
BUG_ON(cpu_num != cpu);
@@ -348,15 +354,17 @@ static void apply_microcode(int cpu)
spin_unlock_irqrestore(&microcode_update_lock, flags);
if (val[1] != mc_intel->hdr.rev) {
printk(KERN_ERR "microcode: CPU%d update from revision "
- "0x%x to 0x%x failed\n", cpu_num, uci->cpu_sig.rev, val[1]);
+ "0x%x to 0x%x failed\n",
+ cpu_num, uci->cpu_sig.rev, val[1]);
return;
}
printk(KERN_INFO "microcode: CPU%d updated from revision "
- "0x%x to 0x%x, date = %04x-%02x-%02x \n",
+ "0x%x to 0x%x, date = %04x-%02x-%02x \n",
cpu_num, uci->cpu_sig.rev, val[1],
mc_intel->hdr.date & 0xffff,
mc_intel->hdr.date >> 24,
(mc_intel->hdr.date >> 16) & 0xff);
+
uci->cpu_sig.rev = val[1];
}
@@ -404,18 +412,23 @@ static int generic_load_microcode(int cpu, void *data, size_t size,
leftover -= mc_size;
}
- if (new_mc) {
- if (!leftover) {
- if (uci->mc)
- vfree(uci->mc);
- uci->mc = (struct microcode_intel *)new_mc;
- pr_debug("microcode: CPU%d found a matching microcode update with"
- " version 0x%x (current=0x%x)\n",
- cpu, new_rev, uci->cpu_sig.rev);
- } else
- vfree(new_mc);
+ if (!new_mc)
+ goto out;
+
+ if (leftover) {
+ vfree(new_mc);
+ goto out;
}
+ if (uci->mc)
+ vfree(uci->mc);
+ uci->mc = (struct microcode_intel *)new_mc;
+
+ pr_debug("microcode: CPU%d found a matching microcode update with"
+ " version 0x%x (current=0x%x)\n",
+ cpu, new_rev, uci->cpu_sig.rev);
+
+ out:
return (int)leftover;
}
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index dce99dca6cf..70fd7e414c1 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -679,7 +679,7 @@ void __init get_smp_config(void)
__get_smp_config(0);
}
-static void smp_reserve_bootmem(struct mpf_intel *mpf)
+static void __init smp_reserve_bootmem(struct mpf_intel *mpf)
{
unsigned long size = get_mpc_size(mpf->physptr);
#ifdef CONFIG_X86_32
@@ -838,7 +838,7 @@ static int __init get_MP_intsrc_index(struct mpc_intsrc *m)
static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM];
-static void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare)
+static void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare)
{
int i;
@@ -866,7 +866,8 @@ static void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare)
}
}
#else /* CONFIG_X86_IO_APIC */
-static inline void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {}
+static
+inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {}
#endif /* CONFIG_X86_IO_APIC */
static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length,
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 90f5b9ef5de..745579bc825 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -40,7 +40,7 @@ EXPORT_SYMBOL(bad_dma_address);
to older i386. */
struct device x86_dma_fallback_dev = {
.init_name = "fallback device",
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
.dma_mask = &x86_dma_fallback_dev.coherent_dma_mask,
};
EXPORT_SYMBOL(x86_dma_fallback_dev);
@@ -148,7 +148,7 @@ again:
if (!is_buffer_dma_capable(dma_mask, addr, size)) {
__free_pages(page, get_order(size));
- if (dma_mask < DMA_32BIT_MASK && !(flag & GFP_DMA)) {
+ if (dma_mask < DMA_BIT_MASK(32) && !(flag & GFP_DMA)) {
flag = (flag & ~GFP_DMA32) | GFP_DMA;
goto again;
}
@@ -243,7 +243,7 @@ int dma_supported(struct device *dev, u64 mask)
/* Copied from i386. Doesn't make much sense, because it will
only work for pci_alloc_coherent.
The caller just has to use GFP_DMA in this case. */
- if (mask < DMA_24BIT_MASK)
+ if (mask < DMA_BIT_MASK(24))
return 0;
/* Tell the device to use SAC when IOMMU force is on. This
@@ -258,7 +258,7 @@ int dma_supported(struct device *dev, u64 mask)
SAC for these. Assume all masks <= 40 bits are of this
type. Normally this doesn't make any difference, but gives
more gentle handling of IOMMU overflow. */
- if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) {
+ if (iommu_sac_force && (mask >= DMA_BIT_MASK(40))) {
dev_info(dev, "Force SAC with mask %Lx\n", mask);
return 0;
}
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
index c6d703b3932..71d412a09f3 100644
--- a/arch/x86/kernel/pci-nommu.c
+++ b/arch/x86/kernel/pci-nommu.c
@@ -15,7 +15,7 @@ static int
check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size)
{
if (hwdev && !is_buffer_dma_capable(*hwdev->dma_mask, bus, size)) {
- if (*hwdev->dma_mask >= DMA_32BIT_MASK)
+ if (*hwdev->dma_mask >= DMA_BIT_MASK(32))
printk(KERN_ERR
"nommu_%s: overflow %Lx+%zu of device mask %Lx\n",
name, (long long)bus, size,
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 156f87582c6..ca989158e84 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -8,7 +8,7 @@
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/clockchips.h>
-#include <linux/ftrace.h>
+#include <trace/power.h>
#include <asm/system.h>
#include <asm/apic.h>
#include <asm/idle.h>
@@ -22,6 +22,9 @@ EXPORT_SYMBOL(idle_nomwait);
struct kmem_cache *task_xstate_cachep;
+DEFINE_TRACE(power_start);
+DEFINE_TRACE(power_end);
+
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
{
*dst = *src;
@@ -325,7 +328,7 @@ void stop_this_cpu(void *dummy)
/*
* Remove this CPU:
*/
- cpu_clear(smp_processor_id(), cpu_online_map);
+ set_cpu_online(smp_processor_id(), false);
disable_local_APIC();
for (;;) {
@@ -475,12 +478,13 @@ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
return 1;
}
-static cpumask_t c1e_mask = CPU_MASK_NONE;
+static cpumask_var_t c1e_mask;
static int c1e_detected;
void c1e_remove_cpu(int cpu)
{
- cpu_clear(cpu, c1e_mask);
+ if (c1e_mask != NULL)
+ cpumask_clear_cpu(cpu, c1e_mask);
}
/*
@@ -509,8 +513,8 @@ static void c1e_idle(void)
if (c1e_detected) {
int cpu = smp_processor_id();
- if (!cpu_isset(cpu, c1e_mask)) {
- cpu_set(cpu, c1e_mask);
+ if (!cpumask_test_cpu(cpu, c1e_mask)) {
+ cpumask_set_cpu(cpu, c1e_mask);
/*
* Force broadcast so ACPI can not interfere. Needs
* to run with interrupts enabled as it uses
@@ -562,6 +566,15 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
pm_idle = default_idle;
}
+void __init init_c1e_mask(void)
+{
+ /* If we're using c1e_idle, we need to allocate c1e_mask. */
+ if (pm_idle == c1e_idle) {
+ alloc_cpumask_var(&c1e_mask, GFP_KERNEL);
+ cpumask_clear(c1e_mask);
+ }
+}
+
static int __init idle_setup(char *str)
{
if (!str)
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index b7cc21bc6ae..23b7c8f017e 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -34,6 +34,8 @@
#include <asm/proto.h>
#include <asm/ds.h>
+#include <trace/syscall.h>
+
#include "tls.h"
enum x86_regset {
@@ -1415,6 +1417,9 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs)
tracehook_report_syscall_entry(regs))
ret = -1L;
+ if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
+ ftrace_syscall_enter(regs);
+
if (unlikely(current->audit_context)) {
if (IS_IA32)
audit_syscall_entry(AUDIT_ARCH_I386,
@@ -1438,6 +1443,9 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
if (unlikely(current->audit_context))
audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
+ if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
+ ftrace_syscall_exit(regs);
+
if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, 0);
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 2aef36d8aca..1340dad417f 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -224,6 +224,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"),
},
},
+ { /* Handle problems with rebooting on Dell DXP061 */
+ .callback = set_bios_reboot,
+ .ident = "Dell DXP061",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Dell DXP061"),
+ },
+ },
{ }
};
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 400331b50a5..3a97a4cf187 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -153,7 +153,6 @@ static struct page * __init pcpur_get_page(unsigned int cpu, int pageno)
static ssize_t __init setup_pcpu_remap(size_t static_size)
{
static struct vm_struct vm;
- pg_data_t *last;
size_t ptrs_size, dyn_size;
unsigned int cpu;
ssize_t ret;
@@ -162,22 +161,9 @@ static ssize_t __init setup_pcpu_remap(size_t static_size)
* If large page isn't supported, there's no benefit in doing
* this. Also, on non-NUMA, embedding is better.
*/
- if (!cpu_has_pse || pcpu_need_numa())
+ if (!cpu_has_pse || !pcpu_need_numa())
return -EINVAL;
- last = NULL;
- for_each_possible_cpu(cpu) {
- int node = early_cpu_to_node(cpu);
-
- if (node_online(node) && NODE_DATA(node) &&
- last && last != NODE_DATA(node))
- goto proceed;
-
- last = NODE_DATA(node);
- }
- return -EINVAL;
-
-proceed:
/*
* Currently supports only single page. Supporting multiple
* pages won't be too difficult if it ever becomes necessary.
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index dfcc74ab0ab..14425166b8e 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -221,7 +221,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
if (!onsigstack) {
/* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) {
- if (sas_ss_flags(sp) == 0)
+ if (current->sas_ss_size)
sp = current->sas_ss_sp + current->sas_ss_size;
} else {
#ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index ef7d10170c3..58d24ef917d 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -101,11 +101,11 @@ EXPORT_SYMBOL(smp_num_siblings);
DEFINE_PER_CPU(u16, cpu_llc_id) = BAD_APICID;
/* representing HT siblings of each logical CPU */
-DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
+DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map);
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
/* representing HT and core siblings of each logical CPU */
-DEFINE_PER_CPU(cpumask_t, cpu_core_map);
+DEFINE_PER_CPU(cpumask_var_t, cpu_core_map);
EXPORT_PER_CPU_SYMBOL(cpu_core_map);
/* Per CPU bogomips and other parameters */
@@ -115,11 +115,6 @@ EXPORT_PER_CPU_SYMBOL(cpu_info);
atomic_t init_deasserted;
#if defined(CONFIG_NUMA) && defined(CONFIG_X86_32)
-
-/* which logical CPUs are on which nodes */
-cpumask_t node_to_cpumask_map[MAX_NUMNODES] __read_mostly =
- { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
-EXPORT_SYMBOL(node_to_cpumask_map);
/* which node each logical CPU is on */
int cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
EXPORT_SYMBOL(cpu_to_node_map);
@@ -128,7 +123,7 @@ EXPORT_SYMBOL(cpu_to_node_map);
static void map_cpu_to_node(int cpu, int node)
{
printk(KERN_INFO "Mapping cpu %d to node %d\n", cpu, node);
- cpumask_set_cpu(cpu, &node_to_cpumask_map[node]);
+ cpumask_set_cpu(cpu, node_to_cpumask_map[node]);
cpu_to_node_map[cpu] = node;
}
@@ -139,7 +134,7 @@ static void unmap_cpu_to_node(int cpu)
printk(KERN_INFO "Unmapping cpu %d from all nodes\n", cpu);
for (node = 0; node < MAX_NUMNODES; node++)
- cpumask_clear_cpu(cpu, &node_to_cpumask_map[node]);
+ cpumask_clear_cpu(cpu, node_to_cpumask_map[node]);
cpu_to_node_map[cpu] = 0;
}
#else /* !(CONFIG_NUMA && CONFIG_X86_32) */
@@ -301,7 +296,7 @@ notrace static void __cpuinit start_secondary(void *unused)
__flush_tlb_all();
#endif
- /* This must be done before setting cpu_online_map */
+ /* This must be done before setting cpu_online_mask */
set_cpu_sibling_map(raw_smp_processor_id());
wmb();
@@ -334,6 +329,23 @@ notrace static void __cpuinit start_secondary(void *unused)
cpu_idle();
}
+#ifdef CONFIG_CPUMASK_OFFSTACK
+/* In this case, llc_shared_map is a pointer to a cpumask. */
+static inline void copy_cpuinfo_x86(struct cpuinfo_x86 *dst,
+ const struct cpuinfo_x86 *src)
+{
+ struct cpumask *llc = dst->llc_shared_map;
+ *dst = *src;
+ dst->llc_shared_map = llc;
+}
+#else
+static inline void copy_cpuinfo_x86(struct cpuinfo_x86 *dst,
+ const struct cpuinfo_x86 *src)
+{
+ *dst = *src;
+}
+#endif /* CONFIG_CPUMASK_OFFSTACK */
+
/*
* The bootstrap kernel entry code has set these up. Save them for
* a given CPU
@@ -343,7 +355,7 @@ void __cpuinit smp_store_cpu_info(int id)
{
struct cpuinfo_x86 *c = &cpu_data(id);
- *c = boot_cpu_data;
+ copy_cpuinfo_x86(c, &boot_cpu_data);
c->cpu_index = id;
if (id != 0)
identify_secondary_cpu(c);
@@ -367,15 +379,15 @@ void __cpuinit set_cpu_sibling_map(int cpu)
cpumask_set_cpu(cpu, cpu_sibling_mask(i));
cpumask_set_cpu(i, cpu_core_mask(cpu));
cpumask_set_cpu(cpu, cpu_core_mask(i));
- cpumask_set_cpu(i, &c->llc_shared_map);
- cpumask_set_cpu(cpu, &o->llc_shared_map);
+ cpumask_set_cpu(i, c->llc_shared_map);
+ cpumask_set_cpu(cpu, o->llc_shared_map);
}
}
} else {
cpumask_set_cpu(cpu, cpu_sibling_mask(cpu));
}
- cpumask_set_cpu(cpu, &c->llc_shared_map);
+ cpumask_set_cpu(cpu, c->llc_shared_map);
if (current_cpu_data.x86_max_cores == 1) {
cpumask_copy(cpu_core_mask(cpu), cpu_sibling_mask(cpu));
@@ -386,8 +398,8 @@ void __cpuinit set_cpu_sibling_map(int cpu)
for_each_cpu(i, cpu_sibling_setup_mask) {
if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
- cpumask_set_cpu(i, &c->llc_shared_map);
- cpumask_set_cpu(cpu, &cpu_data(i).llc_shared_map);
+ cpumask_set_cpu(i, c->llc_shared_map);
+ cpumask_set_cpu(cpu, cpu_data(i).llc_shared_map);
}
if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
cpumask_set_cpu(i, cpu_core_mask(cpu));
@@ -425,12 +437,7 @@ const struct cpumask *cpu_coregroup_mask(int cpu)
if (sched_mc_power_savings || sched_smt_power_savings)
return cpu_core_mask(cpu);
else
- return &c->llc_shared_map;
-}
-
-cpumask_t cpu_coregroup_map(int cpu)
-{
- return *cpu_coregroup_mask(cpu);
+ return c->llc_shared_map;
}
static void impress_friends(void)
@@ -897,9 +904,8 @@ int __cpuinit native_cpu_up(unsigned int cpu)
*/
static __init void disable_smp(void)
{
- /* use the read/write pointers to the present and possible maps */
- cpumask_copy(&cpu_present_map, cpumask_of(0));
- cpumask_copy(&cpu_possible_map, cpumask_of(0));
+ init_cpu_present(cpumask_of(0));
+ init_cpu_possible(cpumask_of(0));
smpboot_clear_io_apic_irqs();
if (smp_found_config)
@@ -1031,6 +1037,8 @@ static void __init smp_cpu_index_default(void)
*/
void __init native_smp_prepare_cpus(unsigned int max_cpus)
{
+ unsigned int i;
+
preempt_disable();
smp_cpu_index_default();
current_cpu_data = boot_cpu_data;
@@ -1044,6 +1052,14 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
boot_cpu_logical_apicid = logical_smp_processor_id();
#endif
current_thread_info()->cpu = 0; /* needed? */
+ for_each_possible_cpu(i) {
+ alloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL);
+ alloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL);
+ alloc_cpumask_var(&cpu_data(i).llc_shared_map, GFP_KERNEL);
+ cpumask_clear(per_cpu(cpu_core_map, i));
+ cpumask_clear(per_cpu(cpu_sibling_map, i));
+ cpumask_clear(cpu_data(i).llc_shared_map);
+ }
set_cpu_sibling_map(0);
enable_IR_x2apic();
@@ -1132,11 +1148,11 @@ early_param("possible_cpus", _setup_possible_cpus);
/*
- * cpu_possible_map should be static, it cannot change as cpu's
+ * cpu_possible_mask should be static, it cannot change as cpu's
* are onlined, or offlined. The reason is per-cpu data-structures
* are allocated by some modules at init time, and dont expect to
* do this dynamically on cpu arrival/departure.
- * cpu_present_map on the other hand can change dynamically.
+ * cpu_present_mask on the other hand can change dynamically.
* In case when cpu_hotplug is not compiled, then we resort to current
* behaviour, which is cpu_possible == cpu_present.
* - Ashok Raj
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index 79c07324728..deb5ebb32c3 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -275,6 +275,8 @@ const struct cpumask *uv_flush_send_and_wait(int cpu, int this_blade,
return NULL;
}
+static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask);
+
/**
* uv_flush_tlb_others - globally purge translation cache of a virtual
* address or all TLB's
@@ -304,8 +306,7 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
struct mm_struct *mm,
unsigned long va, unsigned int cpu)
{
- static DEFINE_PER_CPU(cpumask_t, flush_tlb_mask);
- struct cpumask *flush_mask = &__get_cpu_var(flush_tlb_mask);
+ struct cpumask *flush_mask = __get_cpu_var(uv_flush_tlb_mask);
int i;
int bit;
int blade;
@@ -755,6 +756,10 @@ static int __init uv_bau_init(void)
if (!is_uv_system())
return 0;
+ for_each_possible_cpu(cur_cpu)
+ alloc_cpumask_var_node(&per_cpu(uv_flush_tlb_mask, cur_cpu),
+ GFP_KERNEL, cpu_to_node(cur_cpu));
+
uv_bau_retry_limit = 1;
uv_nshift = uv_hub_info->n_val;
uv_mmask = (1UL << uv_hub_info->n_val) - 1;
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index 2b54fe002e9..0a5b04aa98f 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -324,7 +324,7 @@ void __ref xsave_cntxt_init(void)
}
/*
- * for now OS knows only about FP/SSE
+ * Support only the state known to OS.
*/
pcntxt_mask = pcntxt_mask & XCNTXT_MASK;
xsave_init();
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 0a303c3ed11..a58504ea78c 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -59,7 +59,8 @@ config KVM_AMD
config KVM_TRACE
bool "KVM trace support"
- depends on KVM && MARKERS && SYSFS
+ depends on KVM && SYSFS
+ select MARKERS
select RELAY
select DEBUG_FS
default n
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 08537747cb5..fdd30d08ab5 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -14,7 +14,7 @@ obj-$(CONFIG_MMIOTRACE) += mmiotrace.o
mmiotrace-y := kmmio.o pf_in.o mmio-mod.o
obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o
-obj-$(CONFIG_NUMA) += numa_$(BITS).o
+obj-$(CONFIG_NUMA) += numa.o numa_$(BITS).o
obj-$(CONFIG_K8_NUMA) += k8topology_64.o
obj-$(CONFIG_ACPI_NUMA) += srat_$(BITS).o
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c
index be54176e9eb..6340cef6798 100644
--- a/arch/x86/mm/gup.c
+++ b/arch/x86/mm/gup.c
@@ -219,6 +219,22 @@ static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end,
return 1;
}
+/**
+ * get_user_pages_fast() - pin user pages in memory
+ * @start: starting user address
+ * @nr_pages: number of pages from start to pin
+ * @write: whether pages will be written to
+ * @pages: array that receives pointers to the pages pinned.
+ * Should be at least nr_pages long.
+ *
+ * Attempt to pin user pages in memory without taking mm->mmap_sem.
+ * If not successful, it will fall back to taking the lock and
+ * calling get_user_pages().
+ *
+ * Returns number of pages pinned. This may be fewer than the number
+ * requested. If nr_pages is 0 or negative, returns 0. If no pages
+ * were pinned, returns -errno.
+ */
int get_user_pages_fast(unsigned long start, int nr_pages, int write,
struct page **pages)
{
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index 5bc5d1688c1..8126e8d1a2a 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -40,7 +40,6 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
debug_kmap_atomic(type);
- debug_kmap_atomic(type);
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
BUG_ON(!pte_none(*(kmap_pte-idx)));
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index db81e9a8556..749559ed80f 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -1054,17 +1054,47 @@ static noinline int do_test_wp_bit(void)
const int rodata_test_data = 0xC3;
EXPORT_SYMBOL_GPL(rodata_test_data);
+static int kernel_set_to_readonly;
+
+void set_kernel_text_rw(void)
+{
+ unsigned long start = PFN_ALIGN(_text);
+ unsigned long size = PFN_ALIGN(_etext) - start;
+
+ if (!kernel_set_to_readonly)
+ return;
+
+ pr_debug("Set kernel text: %lx - %lx for read write\n",
+ start, start+size);
+
+ set_pages_rw(virt_to_page(start), size >> PAGE_SHIFT);
+}
+
+void set_kernel_text_ro(void)
+{
+ unsigned long start = PFN_ALIGN(_text);
+ unsigned long size = PFN_ALIGN(_etext) - start;
+
+ if (!kernel_set_to_readonly)
+ return;
+
+ pr_debug("Set kernel text: %lx - %lx for read only\n",
+ start, start+size);
+
+ set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
+}
+
void mark_rodata_ro(void)
{
unsigned long start = PFN_ALIGN(_text);
unsigned long size = PFN_ALIGN(_etext) - start;
-#ifndef CONFIG_DYNAMIC_FTRACE
- /* Dynamic tracing modifies the kernel text section */
set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
printk(KERN_INFO "Write protecting the kernel text: %luk\n",
size >> 10);
+ kernel_set_to_readonly = 1;
+
#ifdef CONFIG_CPA_DEBUG
printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n",
start, start+size);
@@ -1073,7 +1103,6 @@ void mark_rodata_ro(void)
printk(KERN_INFO "Testing CPA: write protecting again\n");
set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT);
#endif
-#endif /* CONFIG_DYNAMIC_FTRACE */
start += size;
size = (unsigned long)__end_rodata - start;
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 54efa57d1c0..1753e8020df 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -734,21 +734,48 @@ void __init mem_init(void)
const int rodata_test_data = 0xC3;
EXPORT_SYMBOL_GPL(rodata_test_data);
+static int kernel_set_to_readonly;
+
+void set_kernel_text_rw(void)
+{
+ unsigned long start = PFN_ALIGN(_stext);
+ unsigned long end = PFN_ALIGN(__start_rodata);
+
+ if (!kernel_set_to_readonly)
+ return;
+
+ pr_debug("Set kernel text: %lx - %lx for read write\n",
+ start, end);
+
+ set_memory_rw(start, (end - start) >> PAGE_SHIFT);
+}
+
+void set_kernel_text_ro(void)
+{
+ unsigned long start = PFN_ALIGN(_stext);
+ unsigned long end = PFN_ALIGN(__start_rodata);
+
+ if (!kernel_set_to_readonly)
+ return;
+
+ pr_debug("Set kernel text: %lx - %lx for read only\n",
+ start, end);
+
+ set_memory_ro(start, (end - start) >> PAGE_SHIFT);
+}
+
void mark_rodata_ro(void)
{
unsigned long start = PFN_ALIGN(_stext), end = PFN_ALIGN(__end_rodata);
unsigned long rodata_start =
((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK;
-#ifdef CONFIG_DYNAMIC_FTRACE
- /* Dynamic tracing modifies the kernel text section */
- start = rodata_start;
-#endif
-
printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
(end - start) >> 10);
set_memory_ro(start, (end - start) >> PAGE_SHIFT);
+ kernel_set_to_readonly = 1;
+
/*
* The rodata section (but not the kernel text!) should also be
* not-executable.
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c
index bff0c9032f8..8056545e2d3 100644
--- a/arch/x86/mm/iomap_32.c
+++ b/arch/x86/mm/iomap_32.c
@@ -23,7 +23,7 @@
int is_io_mapping_possible(resource_size_t base, unsigned long size)
{
-#ifndef CONFIG_X86_PAE
+#if !defined(CONFIG_X86_PAE) && defined(CONFIG_PHYS_ADDR_T_64BIT)
/* There is no way to map greater than 1 << 32 address without PAE */
if (base + size > 0x100000000ULL)
return 0;
@@ -39,6 +39,7 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
pagefault_disable();
+ debug_kmap_atomic(type);
idx = type + KM_TYPE_NR * smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
set_pte(kmap_pte - idx, pfn_pte(pfn, prot));
@@ -72,7 +73,6 @@ iounmap_atomic(void *kvaddr, enum km_type type)
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
- debug_kmap_atomic(type);
/*
* Force other mappings to Oops if they'll try to access this pte
* without first remap it. Keeping stale mappings around is a bad idea
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 0dfa09d69e8..09daebfdb11 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -547,7 +547,7 @@ void __init early_ioremap_reset(void)
}
static void __init __early_set_fixmap(enum fixed_addresses idx,
- unsigned long phys, pgprot_t flags)
+ phys_addr_t phys, pgprot_t flags)
{
unsigned long addr = __fix_to_virt(idx);
pte_t *pte;
@@ -566,7 +566,7 @@ static void __init __early_set_fixmap(enum fixed_addresses idx,
}
static inline void __init early_set_fixmap(enum fixed_addresses idx,
- unsigned long phys, pgprot_t prot)
+ phys_addr_t phys, pgprot_t prot)
{
if (after_paging_init)
__set_fixmap(idx, phys, prot);
@@ -607,9 +607,10 @@ static int __init check_early_ioremap_leak(void)
late_initcall(check_early_ioremap_leak);
static void __init __iomem *
-__early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot)
+__early_ioremap(resource_size_t phys_addr, unsigned long size, pgprot_t prot)
{
- unsigned long offset, last_addr;
+ unsigned long offset;
+ resource_size_t last_addr;
unsigned int nrpages;
enum fixed_addresses idx0, idx;
int i, slot;
@@ -625,15 +626,15 @@ __early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot)
}
if (slot < 0) {
- printk(KERN_INFO "early_iomap(%08lx, %08lx) not found slot\n",
- phys_addr, size);
+ printk(KERN_INFO "early_iomap(%08llx, %08lx) not found slot\n",
+ (u64)phys_addr, size);
WARN_ON(1);
return NULL;
}
if (early_ioremap_debug) {
- printk(KERN_INFO "early_ioremap(%08lx, %08lx) [%d] => ",
- phys_addr, size, slot);
+ printk(KERN_INFO "early_ioremap(%08llx, %08lx) [%d] => ",
+ (u64)phys_addr, size, slot);
dump_stack();
}
@@ -680,13 +681,15 @@ __early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot)
}
/* Remap an IO device */
-void __init __iomem *early_ioremap(unsigned long phys_addr, unsigned long size)
+void __init __iomem *
+early_ioremap(resource_size_t phys_addr, unsigned long size)
{
return __early_ioremap(phys_addr, size, PAGE_KERNEL_IO);
}
/* Remap memory */
-void __init __iomem *early_memremap(unsigned long phys_addr, unsigned long size)
+void __init __iomem *
+early_memremap(resource_size_t phys_addr, unsigned long size)
{
return __early_ioremap(phys_addr, size, PAGE_KERNEL);
}
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index 2c4baa88f2c..c9342ed8b40 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -378,27 +378,34 @@ static void clear_trace_list(void)
}
#ifdef CONFIG_HOTPLUG_CPU
-static cpumask_t downed_cpus;
+static cpumask_var_t downed_cpus;
static void enter_uniprocessor(void)
{
int cpu;
int err;
+ if (downed_cpus == NULL &&
+ !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) {
+ pr_notice(NAME "Failed to allocate mask\n");
+ goto out;
+ }
+
get_online_cpus();
- downed_cpus = cpu_online_map;
- cpu_clear(first_cpu(cpu_online_map), downed_cpus);
+ cpumask_copy(downed_cpus, cpu_online_mask);
+ cpumask_clear_cpu(cpumask_first(cpu_online_mask), downed_cpus);
if (num_online_cpus() > 1)
pr_notice(NAME "Disabling non-boot CPUs...\n");
put_online_cpus();
- for_each_cpu_mask(cpu, downed_cpus) {
+ for_each_cpu(cpu, downed_cpus) {
err = cpu_down(cpu);
if (!err)
pr_info(NAME "CPU%d is down.\n", cpu);
else
pr_err(NAME "Error taking CPU%d down: %d\n", cpu, err);
}
+out:
if (num_online_cpus() > 1)
pr_warning(NAME "multiple CPUs still online, "
"may miss events.\n");
@@ -411,10 +418,10 @@ static void __ref leave_uniprocessor(void)
int cpu;
int err;
- if (cpus_weight(downed_cpus) == 0)
+ if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0)
return;
pr_notice(NAME "Re-enabling CPUs...\n");
- for_each_cpu_mask(cpu, downed_cpus) {
+ for_each_cpu(cpu, downed_cpus) {
err = cpu_up(cpu);
if (!err)
pr_info(NAME "enabled CPU%d.\n", cpu);
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
new file mode 100644
index 00000000000..550df481acc
--- /dev/null
+++ b/arch/x86/mm/numa.c
@@ -0,0 +1,67 @@
+/* Common code for 32 and 64-bit NUMA */
+#include <linux/topology.h>
+#include <linux/module.h>
+#include <linux/bootmem.h>
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+# define DBG(x...) printk(KERN_DEBUG x)
+#else
+# define DBG(x...)
+#endif
+
+/*
+ * Which logical CPUs are on which nodes
+ */
+cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+EXPORT_SYMBOL(node_to_cpumask_map);
+
+/*
+ * Allocate node_to_cpumask_map based on number of available nodes
+ * Requires node_possible_map to be valid.
+ *
+ * Note: node_to_cpumask() is not valid until after this is done.
+ * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
+ */
+void __init setup_node_to_cpumask_map(void)
+{
+ unsigned int node, num = 0;
+
+ /* setup nr_node_ids if not done yet */
+ if (nr_node_ids == MAX_NUMNODES) {
+ for_each_node_mask(node, node_possible_map)
+ num = node;
+ nr_node_ids = num + 1;
+ }
+
+ /* allocate the map */
+ for (node = 0; node < nr_node_ids; node++)
+ alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
+
+ /* cpumask_of_node() will now work */
+ pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
+}
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+/*
+ * Returns a pointer to the bitmask of CPUs on Node 'node'.
+ */
+const struct cpumask *cpumask_of_node(int node)
+{
+ if (node >= nr_node_ids) {
+ printk(KERN_WARNING
+ "cpumask_of_node(%d): node > nr_node_ids(%d)\n",
+ node, nr_node_ids);
+ dump_stack();
+ return cpu_none_mask;
+ }
+ if (node_to_cpumask_map[node] == NULL) {
+ printk(KERN_WARNING
+ "cpumask_of_node(%d): no node_to_cpumask_map!\n",
+ node);
+ dump_stack();
+ return cpu_online_mask;
+ }
+ return node_to_cpumask_map[node];
+}
+EXPORT_SYMBOL(cpumask_of_node);
+#endif
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 64c9cf043cd..d73aaa89237 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -20,12 +20,6 @@
#include <asm/acpi.h>
#include <asm/k8.h>
-#ifdef CONFIG_DEBUG_PER_CPU_MAPS
-# define DBG(x...) printk(KERN_DEBUG x)
-#else
-# define DBG(x...)
-#endif
-
struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
EXPORT_SYMBOL(node_data);
@@ -49,12 +43,6 @@ DEFINE_EARLY_PER_CPU(int, x86_cpu_to_node_map, NUMA_NO_NODE);
EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_node_map);
/*
- * Which logical CPUs are on which nodes
- */
-cpumask_t *node_to_cpumask_map;
-EXPORT_SYMBOL(node_to_cpumask_map);
-
-/*
* Given a shift value, try to populate memnodemap[]
* Returns :
* 1 if OK
@@ -661,36 +649,6 @@ void __init init_cpu_to_node(void)
#endif
-/*
- * Allocate node_to_cpumask_map based on number of available nodes
- * Requires node_possible_map to be valid.
- *
- * Note: node_to_cpumask() is not valid until after this is done.
- * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
- */
-void __init setup_node_to_cpumask_map(void)
-{
- unsigned int node, num = 0;
- cpumask_t *map;
-
- /* setup nr_node_ids if not done yet */
- if (nr_node_ids == MAX_NUMNODES) {
- for_each_node_mask(node, node_possible_map)
- num = node;
- nr_node_ids = num + 1;
- }
-
- /* allocate the map */
- map = alloc_bootmem_low(nr_node_ids * sizeof(cpumask_t));
- DBG("node_to_cpumask_map at %p for %d nodes\n", map, nr_node_ids);
-
- pr_debug("Node to cpumask map at %p for %d nodes\n",
- map, nr_node_ids);
-
- /* node_to_cpumask() will now work */
- node_to_cpumask_map = map;
-}
-
void __cpuinit numa_set_node(int cpu, int node)
{
int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map);
@@ -723,12 +681,12 @@ void __cpuinit numa_clear_node(int cpu)
void __cpuinit numa_add_cpu(int cpu)
{
- cpu_set(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
+ cpumask_set_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
}
void __cpuinit numa_remove_cpu(int cpu)
{
- cpu_clear(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
+ cpumask_clear_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
}
#else /* CONFIG_DEBUG_PER_CPU_MAPS */
@@ -739,20 +697,20 @@ void __cpuinit numa_remove_cpu(int cpu)
static void __cpuinit numa_set_cpumask(int cpu, int enable)
{
int node = early_cpu_to_node(cpu);
- cpumask_t *mask;
+ struct cpumask *mask;
char buf[64];
- if (node_to_cpumask_map == NULL) {
- printk(KERN_ERR "node_to_cpumask_map NULL\n");
+ mask = node_to_cpumask_map[node];
+ if (mask == NULL) {
+ printk(KERN_ERR "node_to_cpumask_map[%i] NULL\n", node);
dump_stack();
return;
}
- mask = &node_to_cpumask_map[node];
if (enable)
- cpu_set(cpu, *mask);
+ cpumask_set_cpu(cpu, mask);
else
- cpu_clear(cpu, *mask);
+ cpumask_clear_cpu(cpu, mask);
cpulist_scnprintf(buf, sizeof(buf), mask);
printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n",
@@ -799,59 +757,6 @@ int early_cpu_to_node(int cpu)
return per_cpu(x86_cpu_to_node_map, cpu);
}
-
-/* empty cpumask */
-static const cpumask_t cpu_mask_none;
-
-/*
- * Returns a pointer to the bitmask of CPUs on Node 'node'.
- */
-const cpumask_t *cpumask_of_node(int node)
-{
- if (node_to_cpumask_map == NULL) {
- printk(KERN_WARNING
- "cpumask_of_node(%d): no node_to_cpumask_map!\n",
- node);
- dump_stack();
- return (const cpumask_t *)&cpu_online_map;
- }
- if (node >= nr_node_ids) {
- printk(KERN_WARNING
- "cpumask_of_node(%d): node > nr_node_ids(%d)\n",
- node, nr_node_ids);
- dump_stack();
- return &cpu_mask_none;
- }
- return &node_to_cpumask_map[node];
-}
-EXPORT_SYMBOL(cpumask_of_node);
-
-/*
- * Returns a bitmask of CPUs on Node 'node'.
- *
- * Side note: this function creates the returned cpumask on the stack
- * so with a high NR_CPUS count, excessive stack space is used. The
- * node_to_cpumask_ptr function should be used whenever possible.
- */
-cpumask_t node_to_cpumask(int node)
-{
- if (node_to_cpumask_map == NULL) {
- printk(KERN_WARNING
- "node_to_cpumask(%d): no node_to_cpumask_map!\n", node);
- dump_stack();
- return cpu_online_map;
- }
- if (node >= nr_node_ids) {
- printk(KERN_WARNING
- "node_to_cpumask(%d): node > nr_node_ids(%d)\n",
- node, nr_node_ids);
- dump_stack();
- return cpu_mask_none;
- }
- return node_to_cpumask_map[node];
-}
-EXPORT_SYMBOL(node_to_cpumask);
-
/*
* --------- end of debug versions of the numa functions ---------
*/
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 640339ee4fb..c009a241d56 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -31,7 +31,7 @@
#ifdef CONFIG_X86_PAT
int __read_mostly pat_enabled = 1;
-void __cpuinit pat_disable(const char *reason)
+static inline void pat_disable(const char *reason)
{
pat_enabled = 0;
printk(KERN_INFO "%s\n", reason);
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 5b7c7c8464f..7aa03a5389f 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -345,7 +345,8 @@ void __native_set_fixmap(enum fixed_addresses idx, pte_t pte)
fixmaps_set++;
}
-void native_set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
+void native_set_fixmap(enum fixed_addresses idx, phys_addr_t phys,
+ pgprot_t flags)
{
__native_set_fixmap(idx, pfn_pte(phys >> PAGE_SHIFT, flags));
}
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index 574c8bc95ef..c7d272b8574 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -116,6 +116,36 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
reserve_early(phys, phys + length, "ACPI SLIT");
}
+/* Callback for Proximity Domain -> x2APIC mapping */
+void __init
+acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
+{
+ int pxm, node;
+ int apic_id;
+
+ if (srat_disabled())
+ return;
+ if (pa->header.length < sizeof(struct acpi_srat_x2apic_cpu_affinity)) {
+ bad_srat();
+ return;
+ }
+ if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
+ return;
+ pxm = pa->proximity_domain;
+ node = setup_node(pxm);
+ if (node < 0) {
+ printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
+ bad_srat();
+ return;
+ }
+
+ apic_id = pa->apic_id;
+ apicid_to_node[apic_id] = node;
+ acpi_numa = 1;
+ printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
+ pxm, apic_id, node);
+}
+
/* Callback for Proximity Domain -> LAPIC mapping */
void __init
acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c
index 4c4a51c90bc..819b131fd75 100644
--- a/arch/x86/oprofile/op_model_p4.c
+++ b/arch/x86/oprofile/op_model_p4.c
@@ -380,7 +380,7 @@ static unsigned int get_stagger(void)
{
#ifdef CONFIG_SMP
int cpu = smp_processor_id();
- return (cpu != first_cpu(per_cpu(cpu_sibling_map, cpu)));
+ return cpu != cpumask_first(__get_cpu_var(cpu_sibling_map));
#endif
return 0;
}
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index f234a37bd42..f1817f71e00 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -258,24 +258,7 @@ void pcibios_set_master(struct pci_dev *dev)
pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
}
-static void pci_unmap_page_range(struct vm_area_struct *vma)
-{
- u64 addr = (u64)vma->vm_pgoff << PAGE_SHIFT;
- free_memtype(addr, addr + vma->vm_end - vma->vm_start);
-}
-
-static void pci_track_mmap_page_range(struct vm_area_struct *vma)
-{
- u64 addr = (u64)vma->vm_pgoff << PAGE_SHIFT;
- unsigned long flags = pgprot_val(vma->vm_page_prot)
- & _PAGE_CACHE_MASK;
-
- reserve_memtype(addr, addr + vma->vm_end - vma->vm_start, flags, NULL);
-}
-
static struct vm_operations_struct pci_mmap_ops = {
- .open = pci_track_mmap_page_range,
- .close = pci_unmap_page_range,
.access = generic_access_phys,
};
@@ -283,11 +266,6 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine)
{
unsigned long prot;
- u64 addr = vma->vm_pgoff << PAGE_SHIFT;
- unsigned long len = vma->vm_end - vma->vm_start;
- unsigned long flags;
- unsigned long new_flags;
- int retval;
/* I/O space cannot be accessed via normal processor loads and
* stores on this platform.
@@ -308,30 +286,6 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
vma->vm_page_prot = __pgprot(prot);
- flags = pgprot_val(vma->vm_page_prot) & _PAGE_CACHE_MASK;
- retval = reserve_memtype(addr, addr + len, flags, &new_flags);
- if (retval)
- return retval;
-
- if (flags != new_flags) {
- if (!is_new_memtype_allowed(flags, new_flags)) {
- free_memtype(addr, addr+len);
- return -EINVAL;
- }
- flags = new_flags;
- vma->vm_page_prot = __pgprot(
- (pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK) |
- flags);
- }
-
- if (((vma->vm_pgoff < max_low_pfn_mapped) ||
- (vma->vm_pgoff >= (1UL<<(32 - PAGE_SHIFT)) &&
- vma->vm_pgoff < max_pfn_mapped)) &&
- ioremap_change_attr((unsigned long)__va(addr), len, flags)) {
- free_memtype(addr, addr + len);
- return -EINVAL;
- }
-
if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
diff --git a/arch/x86/power/Makefile b/arch/x86/power/Makefile
index 9ff4d5b55ad..58b32db3312 100644
--- a/arch/x86/power/Makefile
+++ b/arch/x86/power/Makefile
@@ -1,2 +1,7 @@
+# __restore_processor_state() restores %gs after S3 resume and so should not
+# itself be stack-protected
+nostackp := $(call cc-option, -fno-stack-protector)
+CFLAGS_cpu_$(BITS).o := $(nostackp)
+
obj-$(CONFIG_PM_SLEEP) += cpu_$(BITS).o
obj-$(CONFIG_HIBERNATION) += hibernate_$(BITS).o hibernate_asm_$(BITS).o
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 82cd39a6cbd..f09e8c36ee8 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -42,6 +42,7 @@
#include <asm/xen/hypervisor.h>
#include <asm/fixmap.h>
#include <asm/processor.h>
+#include <asm/proto.h>
#include <asm/msr-index.h>
#include <asm/setup.h>
#include <asm/desc.h>
@@ -168,21 +169,23 @@ static void __init xen_banner(void)
xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : "");
}
+static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0;
+static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0;
+
static void xen_cpuid(unsigned int *ax, unsigned int *bx,
unsigned int *cx, unsigned int *dx)
{
+ unsigned maskecx = ~0;
unsigned maskedx = ~0;
/*
* Mask out inconvenient features, to try and disable as many
* unsupported kernel subsystems as possible.
*/
- if (*ax == 1)
- maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */
- (1 << X86_FEATURE_ACPI) | /* disable ACPI */
- (1 << X86_FEATURE_MCE) | /* disable MCE */
- (1 << X86_FEATURE_MCA) | /* disable MCA */
- (1 << X86_FEATURE_ACC)); /* thermal monitoring */
+ if (*ax == 1) {
+ maskecx = cpuid_leaf1_ecx_mask;
+ maskedx = cpuid_leaf1_edx_mask;
+ }
asm(XEN_EMULATE_PREFIX "cpuid"
: "=a" (*ax),
@@ -190,9 +193,43 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
"=c" (*cx),
"=d" (*dx)
: "0" (*ax), "2" (*cx));
+
+ *cx &= maskecx;
*dx &= maskedx;
}
+static __init void xen_init_cpuid_mask(void)
+{
+ unsigned int ax, bx, cx, dx;
+
+ cpuid_leaf1_edx_mask =
+ ~((1 << X86_FEATURE_MCE) | /* disable MCE */
+ (1 << X86_FEATURE_MCA) | /* disable MCA */
+ (1 << X86_FEATURE_ACC)); /* thermal monitoring */
+
+ if (!xen_initial_domain())
+ cpuid_leaf1_edx_mask &=
+ ~((1 << X86_FEATURE_APIC) | /* disable local APIC */
+ (1 << X86_FEATURE_ACPI)); /* disable ACPI */
+
+ ax = 1;
+ xen_cpuid(&ax, &bx, &cx, &dx);
+
+ /* cpuid claims we support xsave; try enabling it to see what happens */
+ if (cx & (1 << (X86_FEATURE_XSAVE % 32))) {
+ unsigned long cr4;
+
+ set_in_cr4(X86_CR4_OSXSAVE);
+
+ cr4 = read_cr4();
+
+ if ((cr4 & X86_CR4_OSXSAVE) == 0)
+ cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_XSAVE % 32));
+
+ clear_in_cr4(X86_CR4_OSXSAVE);
+ }
+}
+
static void xen_set_debugreg(int reg, unsigned long val)
{
HYPERVISOR_set_debugreg(reg, val);
@@ -284,12 +321,11 @@ static void xen_set_ldt(const void *addr, unsigned entries)
static void xen_load_gdt(const struct desc_ptr *dtr)
{
- unsigned long *frames;
unsigned long va = dtr->address;
unsigned int size = dtr->size + 1;
unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
+ unsigned long frames[pages];
int f;
- struct multicall_space mcs;
/* A GDT can be up to 64k in size, which corresponds to 8192
8-byte entries, or 16 4k pages.. */
@@ -297,19 +333,26 @@ static void xen_load_gdt(const struct desc_ptr *dtr)
BUG_ON(size > 65536);
BUG_ON(va & ~PAGE_MASK);
- mcs = xen_mc_entry(sizeof(*frames) * pages);
- frames = mcs.args;
-
for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
- frames[f] = arbitrary_virt_to_mfn((void *)va);
+ int level;
+ pte_t *ptep = lookup_address(va, &level);
+ unsigned long pfn, mfn;
+ void *virt;
+
+ BUG_ON(ptep == NULL);
+
+ pfn = pte_pfn(*ptep);
+ mfn = pfn_to_mfn(pfn);
+ virt = __va(PFN_PHYS(pfn));
+
+ frames[f] = mfn;
make_lowmem_page_readonly((void *)va);
- make_lowmem_page_readonly(mfn_to_virt(frames[f]));
+ make_lowmem_page_readonly(virt);
}
- MULTI_set_gdt(mcs.mc, frames, size / sizeof(struct desc_struct));
-
- xen_mc_issue(PARAVIRT_LAZY_CPU);
+ if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct)))
+ BUG();
}
static void load_TLS_descriptor(struct thread_struct *t,
@@ -385,7 +428,7 @@ static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum,
static int cvt_gate_to_trap(int vector, const gate_desc *val,
struct trap_info *info)
{
- if (val->type != 0xf && val->type != 0xe)
+ if (val->type != GATE_TRAP && val->type != GATE_INTERRUPT)
return 0;
info->vector = vector;
@@ -393,8 +436,8 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val,
info->cs = gate_segment(*val);
info->flags = val->dpl;
/* interrupt gates clear IF */
- if (val->type == 0xe)
- info->flags |= 4;
+ if (val->type == GATE_INTERRUPT)
+ info->flags |= 1 << 2;
return 1;
}
@@ -872,7 +915,6 @@ static const struct machine_ops __initdata xen_machine_ops = {
.emergency_restart = xen_emergency_restart,
};
-
/* First C function to be called on Xen boot */
asmlinkage void __init xen_start_kernel(void)
{
@@ -897,6 +939,8 @@ asmlinkage void __init xen_start_kernel(void)
xen_init_irq_ops();
+ xen_init_cpuid_mask();
+
#ifdef CONFIG_X86_LOCAL_APIC
/*
* set up the basic apic ops.
@@ -938,6 +982,11 @@ asmlinkage void __init xen_start_kernel(void)
if (!xen_initial_domain())
__supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
+#ifdef CONFIG_X86_64
+ /* Work out if we support NX */
+ check_efer();
+#endif
+
/* Don't do the full vcpu_info placement stuff until we have a
possible map and a non-dummy shared_info. */
per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index db3802fb7b8..9842b121240 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -184,7 +184,7 @@ static inline unsigned p2m_index(unsigned long pfn)
}
/* Build the parallel p2m_top_mfn structures */
-void xen_setup_mfn_list_list(void)
+static void __init xen_build_mfn_list_list(void)
{
unsigned pfn, idx;
@@ -198,7 +198,10 @@ void xen_setup_mfn_list_list(void)
unsigned topidx = idx * P2M_ENTRIES_PER_PAGE;
p2m_top_mfn_list[idx] = virt_to_mfn(&p2m_top_mfn[topidx]);
}
+}
+void xen_setup_mfn_list_list(void)
+{
BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
@@ -218,6 +221,8 @@ void __init xen_build_dynamic_phys_to_machine(void)
p2m_top[topidx] = &mfn_list[pfn];
}
+
+ xen_build_mfn_list_list();
}
unsigned long get_phys_to_machine(unsigned long pfn)
@@ -233,47 +238,74 @@ unsigned long get_phys_to_machine(unsigned long pfn)
}
EXPORT_SYMBOL_GPL(get_phys_to_machine);
-static void alloc_p2m(unsigned long **pp, unsigned long *mfnp)
+/* install a new p2m_top page */
+bool install_p2mtop_page(unsigned long pfn, unsigned long *p)
{
- unsigned long *p;
+ unsigned topidx = p2m_top_index(pfn);
+ unsigned long **pfnp, *mfnp;
unsigned i;
- p = (void *)__get_free_page(GFP_KERNEL | __GFP_NOFAIL);
- BUG_ON(p == NULL);
+ pfnp = &p2m_top[topidx];
+ mfnp = &p2m_top_mfn[topidx];
for (i = 0; i < P2M_ENTRIES_PER_PAGE; i++)
p[i] = INVALID_P2M_ENTRY;
- if (cmpxchg(pp, p2m_missing, p) != p2m_missing)
- free_page((unsigned long)p);
- else
+ if (cmpxchg(pfnp, p2m_missing, p) == p2m_missing) {
*mfnp = virt_to_mfn(p);
+ return true;
+ }
+
+ return false;
}
-void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+static void alloc_p2m(unsigned long pfn)
{
- unsigned topidx, idx;
+ unsigned long *p;
- if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) {
- BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
- return;
- }
+ p = (void *)__get_free_page(GFP_KERNEL | __GFP_NOFAIL);
+ BUG_ON(p == NULL);
+
+ if (!install_p2mtop_page(pfn, p))
+ free_page((unsigned long)p);
+}
+
+/* Try to install p2m mapping; fail if intermediate bits missing */
+bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+{
+ unsigned topidx, idx;
if (unlikely(pfn >= MAX_DOMAIN_PAGES)) {
BUG_ON(mfn != INVALID_P2M_ENTRY);
- return;
+ return true;
}
topidx = p2m_top_index(pfn);
if (p2m_top[topidx] == p2m_missing) {
- /* no need to allocate a page to store an invalid entry */
if (mfn == INVALID_P2M_ENTRY)
- return;
- alloc_p2m(&p2m_top[topidx], &p2m_top_mfn[topidx]);
+ return true;
+ return false;
}
idx = p2m_index(pfn);
p2m_top[topidx][idx] = mfn;
+
+ return true;
+}
+
+void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+{
+ if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) {
+ BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
+ return;
+ }
+
+ if (unlikely(!__set_phys_to_machine(pfn, mfn))) {
+ alloc_p2m(pfn);
+
+ if (!__set_phys_to_machine(pfn, mfn))
+ BUG();
+ }
}
unsigned long arbitrary_virt_to_mfn(void *vaddr)
@@ -987,7 +1019,7 @@ static __init int xen_mark_pinned(struct mm_struct *mm, struct page *page,
return 0;
}
-void __init xen_mark_init_mm_pinned(void)
+static void __init xen_mark_init_mm_pinned(void)
{
xen_pgd_walk(&init_mm, xen_mark_pinned, FIXADDR_TOP);
}
@@ -1270,8 +1302,8 @@ static void xen_flush_tlb_others(const struct cpumask *cpus,
} *args;
struct multicall_space mcs;
- BUG_ON(cpumask_empty(cpus));
- BUG_ON(!mm);
+ if (cpumask_empty(cpus))
+ return; /* nothing to do */
mcs = xen_mc_entry(sizeof(*args));
args = mcs.args;
@@ -1438,6 +1470,15 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
}
#endif
+static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn)
+{
+ struct mmuext_op op;
+ op.cmd = cmd;
+ op.arg1.mfn = pfn_to_mfn(pfn);
+ if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF))
+ BUG();
+}
+
/* Early in boot, while setting up the initial pagetable, assume
everything is pinned. */
static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn)
@@ -1446,22 +1487,29 @@ static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn)
BUG_ON(mem_map); /* should only be used early */
#endif
make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
+ pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);
+}
+
+/* Used for pmd and pud */
+static __init void xen_alloc_pmd_init(struct mm_struct *mm, unsigned long pfn)
+{
+#ifdef CONFIG_FLATMEM
+ BUG_ON(mem_map); /* should only be used early */
+#endif
+ make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
}
/* Early release_pte assumes that all pts are pinned, since there's
only init_mm and anything attached to that is pinned. */
-static void xen_release_pte_init(unsigned long pfn)
+static __init void xen_release_pte_init(unsigned long pfn)
{
+ pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn);
make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
}
-static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn)
+static __init void xen_release_pmd_init(unsigned long pfn)
{
- struct mmuext_op op;
- op.cmd = cmd;
- op.arg1.mfn = pfn_to_mfn(pfn);
- if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF))
- BUG();
+ make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
}
/* This needs to make sure the new pte page is pinned iff its being
@@ -1750,7 +1798,7 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
}
#endif /* CONFIG_X86_64 */
-static void xen_set_fixmap(unsigned idx, unsigned long phys, pgprot_t prot)
+static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
{
pte_t pte;
@@ -1773,6 +1821,9 @@ static void xen_set_fixmap(unsigned idx, unsigned long phys, pgprot_t prot)
#ifdef CONFIG_X86_LOCAL_APIC
case FIX_APIC_BASE: /* maps dummy local APIC */
#endif
+ case FIX_TEXT_POKE0:
+ case FIX_TEXT_POKE1:
+ /* All local page mappings */
pte = pfn_pte(phys, prot);
break;
@@ -1819,7 +1870,6 @@ __init void xen_post_allocator_init(void)
xen_mark_init_mm_pinned();
}
-
const struct pv_mmu_ops xen_mmu_ops __initdata = {
.pagetable_setup_start = xen_pagetable_setup_start,
.pagetable_setup_done = xen_pagetable_setup_done,
@@ -1843,9 +1893,9 @@ const struct pv_mmu_ops xen_mmu_ops __initdata = {
.alloc_pte = xen_alloc_pte_init,
.release_pte = xen_release_pte_init,
- .alloc_pmd = xen_alloc_pte_init,
+ .alloc_pmd = xen_alloc_pmd_init,
.alloc_pmd_clone = paravirt_nop,
- .release_pmd = xen_release_pte_init,
+ .release_pmd = xen_release_pmd_init,
#ifdef CONFIG_HIGHPTE
.kmap_atomic_pte = xen_kmap_atomic_pte,
@@ -1883,8 +1933,8 @@ const struct pv_mmu_ops xen_mmu_ops __initdata = {
.make_pud = PV_CALLEE_SAVE(xen_make_pud),
.set_pgd = xen_set_pgd_hyper,
- .alloc_pud = xen_alloc_pte_init,
- .release_pud = xen_release_pte_init,
+ .alloc_pud = xen_alloc_pmd_init,
+ .release_pud = xen_release_pmd_init,
#endif /* PAGETABLE_LEVELS == 4 */
.activate_mm = xen_activate_mm,
diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h
index 24d1b44a337..da730262489 100644
--- a/arch/x86/xen/mmu.h
+++ b/arch/x86/xen/mmu.h
@@ -11,6 +11,9 @@ enum pt_level {
};
+bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
+bool install_p2mtop_page(unsigned long pfn, unsigned long *p);
+
void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 8d470562ffc..429834ec168 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -158,7 +158,7 @@ static void __init xen_fill_possible_map(void)
rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
if (rc >= 0) {
num_processors++;
- cpu_set(i, cpu_possible_map);
+ set_cpu_possible(i, true);
}
}
}
@@ -197,7 +197,7 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus)
while ((num_possible_cpus() > 1) && (num_possible_cpus() > max_cpus)) {
for (cpu = nr_cpu_ids - 1; !cpu_possible(cpu); cpu--)
continue;
- cpu_clear(cpu, cpu_possible_map);
+ set_cpu_possible(cpu, false);
}
for_each_possible_cpu (cpu) {
@@ -210,7 +210,7 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus)
if (IS_ERR(idle))
panic("failed fork for CPU %d", cpu);
- cpu_set(cpu, cpu_present_map);
+ set_cpu_present(cpu, true);
}
}
@@ -317,7 +317,7 @@ static int __cpuinit xen_cpu_up(unsigned int cpu)
BUG_ON(rc);
while(per_cpu(cpu_state, cpu) != CPU_ONLINE) {
- HYPERVISOR_sched_op(SCHEDOP_yield, 0);
+ HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
barrier();
}
@@ -422,7 +422,7 @@ static void xen_smp_send_call_function_ipi(const struct cpumask *mask)
/* Make sure other vcpus get a chance to run if they need to. */
for_each_cpu(cpu, mask) {
if (xen_vcpu_stolen(cpu)) {
- HYPERVISOR_sched_op(SCHEDOP_yield, 0);
+ HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
break;
}
}
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 2f5ef2632ea..20139464943 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -57,8 +57,6 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id);
bool xen_vcpu_stolen(int vcpu);
-void xen_mark_init_mm_pinned(void);
-
void xen_setup_vcpu_info_placement(void);
#ifdef CONFIG_SMP
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 98120083043..fa6dc4dd3b1 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -4,16 +4,13 @@
mainmenu "Linux/Xtensa Kernel Configuration"
config FRAME_POINTER
- bool
- default n
+ def_bool n
config ZONE_DMA
- bool
- default y
+ def_bool y
config XTENSA
- bool
- default y
+ def_bool y
select HAVE_IDE
help
Xtensa processors are 32-bit RISC machines designed by Tensilica
@@ -24,28 +21,25 @@ config XTENSA
a home page at <http://xtensa.sourceforge.net/>.
config RWSEM_XCHGADD_ALGORITHM
- bool
- default y
+ def_bool y
config GENERIC_FIND_NEXT_BIT
- bool
- default y
+ def_bool y
config GENERIC_HWEIGHT
- bool
- default y
+ def_bool y
config GENERIC_HARDIRQS
- bool
- default y
+ def_bool y
+
+config GENERIC_GPIO
+ def_bool y
config ARCH_HAS_ILOG2_U32
- bool
- default n
+ def_bool n
config ARCH_HAS_ILOG2_U64
- bool
- default n
+ def_bool n
config NO_IOPORT
def_bool y
@@ -54,9 +48,18 @@ config HZ
int
default 100
+config GENERIC_TIME
+ def_bool y
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
+config MMU
+ def_bool n
+
+config VARIANT_IRQ_SWITCH
+ def_bool n
+
menu "Processor type and features"
choice
@@ -65,38 +68,41 @@ choice
config XTENSA_VARIANT_FSF
bool "fsf - default (not generic) configuration"
+ select MMU
config XTENSA_VARIANT_DC232B
bool "dc232b - Diamond 232L Standard Core Rev.B (LE)"
+ select MMU
help
- This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE).
-endchoice
+ This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE).
-config MMU
- bool
- default y
+config XTENSA_VARIANT_S6000
+ bool "s6000 - Stretch software configurable processor"
+ select VARIANT_IRQ_SWITCH
+ select ARCH_REQUIRE_GPIOLIB
+endchoice
config XTENSA_UNALIGNED_USER
bool "Unaligned memory access in use space"
- ---help---
- The Xtensa architecture currently does not handle unaligned
- memory accesses in hardware but through an exception handler.
- Per default, unaligned memory accesses are disabled in user space.
+ help
+ The Xtensa architecture currently does not handle unaligned
+ memory accesses in hardware but through an exception handler.
+ Per default, unaligned memory accesses are disabled in user space.
- Say Y here to enable unaligned memory access in user space.
+ Say Y here to enable unaligned memory access in user space.
config PREEMPT
bool "Preemptible Kernel"
- ---help---
- This option reduces the latency of the kernel when reacting to
- real-time or interactive events by allowing a low priority process to
- be preempted even if it is in kernel mode executing a system call.
- Unfortunately the kernel code has some race conditions if both
- CONFIG_SMP and CONFIG_PREEMPT are enabled, so this option is
- currently disabled if you are building an SMP kernel.
+ help
+ This option reduces the latency of the kernel when reacting to
+ real-time or interactive events by allowing a low priority process to
+ be preempted even if it is in kernel mode executing a system call.
+ Unfortunately the kernel code has some race conditions if both
+ CONFIG_SMP and CONFIG_PREEMPT are enabled, so this option is
+ currently disabled if you are building an SMP kernel.
- Say Y here if you are building a kernel for a desktop, embedded
- or real-time system. Say N if you are unsure.
+ Say Y here if you are building a kernel for a desktop, embedded
+ or real-time system. Say N if you are unsure.
config MATH_EMULATION
bool "Math emulation"
@@ -105,6 +111,32 @@ config MATH_EMULATION
endmenu
+config XTENSA_CALIBRATE_CCOUNT
+ def_bool n
+ help
+ On some platforms (XT2000, for example), the CPU clock rate can
+ vary. The frequency can be determined, however, by measuring
+ against a well known, fixed frequency, such as an UART oscillator.
+
+config SERIAL_CONSOLE
+ def_bool n
+
+config XTENSA_ISS_NETWORK
+ def_bool n
+
+menu "Bus options"
+
+config PCI
+ bool "PCI support"
+ default y
+ help
+ Find out whether you have a PCI motherboard. PCI is the name of a
+ bus system, i.e. the way the CPU talks to the other stuff inside
+ your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
+ VESA. If you have PCI, say Y, otherwise N.
+
+source "drivers/pci/Kconfig"
+
menu "Platform options"
choice
@@ -113,33 +145,35 @@ choice
config XTENSA_PLATFORM_ISS
bool "ISS"
+ select XTENSA_CALIBRATE_CCOUNT
+ select SERIAL_CONSOLE
+ select XTENSA_ISS_NETWORK
help
ISS is an acronym for Tensilica's Instruction Set Simulator.
config XTENSA_PLATFORM_XT2000
bool "XT2000"
+ select XTENSA_CALIBRATE_CCOUNT
+ select PCI
help
XT2000 is the name of Tensilica's feature-rich emulation platform.
This hardware is capable of running a full Linux distribution.
-endchoice
+config XTENSA_PLATFORM_S6105
+ bool "S6105"
+ select SERIAL_CONSOLE
+endchoice
-config XTENSA_CALIBRATE_CCOUNT
- bool "Auto calibration of the CPU clock rate"
- ---help---
- On some platforms (XT2000, for example), the CPU clock rate can
- vary. The frequency can be determined, however, by measuring
- against a well known, fixed frequency, such as an UART oscillator.
config XTENSA_CPU_CLOCK
int "CPU clock rate [MHz]"
depends on !XTENSA_CALIBRATE_CCOUNT
- default "16"
+ default 16
config GENERIC_CALIBRATE_DELAY
bool "Auto calibration of the BogoMIPS value"
- ---help---
+ help
The BogoMIPS value can easily be derived from the CPU frequency.
config CMDLINE_BOOL
@@ -156,52 +190,27 @@ config CMDLINE
time by entering them here. As a minimum, you should specify the
memory size and the root device (e.g., mem=64M root=/dev/nfs).
-config SERIAL_CONSOLE
- bool
- depends on XTENSA_PLATFORM_ISS
- default y
-
-config XTENSA_ISS_NETWORK
- bool
- depends on XTENSA_PLATFORM_ISS
- default y
-
source "mm/Kconfig"
endmenu
-menu "Bus options"
-
-config PCI
- bool "PCI support" if !XTENSA_PLATFORM_ISS
- depends on !XTENSA_PLATFORM_ISS
- default y
+config HOTPLUG
+ bool "Support for hot-pluggable devices"
help
- Find out whether you have a PCI motherboard. PCI is the name of a
- bus system, i.e. the way the CPU talks to the other stuff inside
- your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
- VESA. If you have PCI, say Y, otherwise N.
+ Say Y here if you want to plug devices into your computer while
+ the system is running, and be able to use them quickly. In many
+ cases, the devices can likewise be unplugged at any time too.
-source "drivers/pci/Kconfig"
+ One well known example of this is PCMCIA- or PC-cards, credit-card
+ size devices such as network cards, modems or hard drives which are
+ plugged into slots found on all modern laptop computers. Another
+ example, used on modern desktops as well as laptops, is USB.
-config HOTPLUG
-
- bool "Support for hot-pluggable devices"
- ---help---
- Say Y here if you want to plug devices into your computer while
- the system is running, and be able to use them quickly. In many
- cases, the devices can likewise be unplugged at any time too.
-
- One well known example of this is PCMCIA- or PC-cards, credit-card
- size devices such as network cards, modems or hard drives which are
- plugged into slots found on all modern laptop computers. Another
- example, used on modern desktops as well as laptops, is USB.
-
- Enable HOTPLUG and build a modular kernel. Get agent software
- (from <http://linux-hotplug.sourceforge.net/>) and install it.
- Then your kernel will automatically call out to a user mode "policy
- agent" (/sbin/hotplug) to load modules and set up software needed
- to use devices as you hotplug them.
+ Enable HOTPLUG and build a modular kernel. Get agent software
+ (from <http://linux-hotplug.sourceforge.net/>) and install it.
+ Then your kernel will automatically call out to a user mode "policy
+ agent" (/sbin/hotplug) to load modules and set up software needed
+ to use devices as you hotplug them.
source "drivers/pcmcia/Kconfig"
@@ -213,9 +222,8 @@ menu "Executable file formats"
# only elf supported
config KCORE_ELF
- bool
+ def_bool y
depends on PROC_FS
- default y
help
If you enabled support for /proc file system then the file
/proc/kcore will contain the kernel core image in ELF format. This
@@ -240,7 +248,7 @@ source "fs/Kconfig"
menu "Xtensa initrd options"
depends on BLK_DEV_INITRD
- config EMBEDDED_RAMDISK
+config EMBEDDED_RAMDISK
bool "Embed root filesystem ramdisk into the kernel"
config EMBEDDED_RAMDISK_IMAGE
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index 1da55fe4bef..4caffac3ca2 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -15,6 +15,7 @@
variant-$(CONFIG_XTENSA_VARIANT_FSF) := fsf
variant-$(CONFIG_XTENSA_VARIANT_DC232B) := dc232b
+variant-$(CONFIG_XTENSA_VARIANT_S6000) := s6000
variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM) := custom
VARIANT = $(variant-y)
@@ -24,6 +25,7 @@ export VARIANT
platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000
platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss
+platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105
PLATFORM = $(platform-y)
export PLATFORM
@@ -62,20 +64,23 @@ ifneq ($(VARIANT),)
endif
endif
-#
+# Only build variant and/or platform if it includes a Makefile
+
+buildvar := $(shell test -a $(srctree)/arch/xtensa/variants/$(VARIANT)/Makefile && echo arch/xtensa/variants/$(VARIANT)/)
+buildplf := $(shell test -a $(srctree)/arch/xtensa/platforms/$(PLATFORM)/Makefile && echo arch/xtensa/platforms/$(PLATFORM)/)
+
+# Find libgcc.a
LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
head-y := arch/xtensa/kernel/head.o
core-y += arch/xtensa/kernel/ arch/xtensa/mm/
-ifneq ($(PLATFORM),)
-core-y += arch/xtensa/platforms/$(PLATFORM)/
-endif
+core-y += $(buildvar) $(buildplf)
+
libs-y += arch/xtensa/lib/ $(LIBGCC)
boot := arch/xtensa/boot
-
all: zImage
bzImage : zImage
diff --git a/arch/xtensa/configs/s6105_defconfig b/arch/xtensa/configs/s6105_defconfig
new file mode 100644
index 00000000000..6e1deff4159
--- /dev/null
+++ b/arch/xtensa/configs/s6105_defconfig
@@ -0,0 +1,530 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc7-s6
+# Tue Mar 10 11:09:26 2009
+#
+# CONFIG_FRAME_POINTER is not set
+CONFIG_ZONE_DMA=y
+CONFIG_XTENSA=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_NO_IOPORT=y
+CONFIG_HZ=100
+CONFIG_GENERIC_TIME=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=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+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 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_AIO=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_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+# CONFIG_MMU is not set
+CONFIG_VARIANT_IRQ_SWITCH=y
+
+#
+# Processor type and features
+#
+# CONFIG_XTENSA_VARIANT_FSF is not set
+# CONFIG_XTENSA_VARIANT_DC232B is not set
+CONFIG_XTENSA_VARIANT_S6000=y
+# CONFIG_XTENSA_UNALIGNED_USER is not set
+CONFIG_PREEMPT=y
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_HIGHMEM is not set
+# CONFIG_XTENSA_CALIBRATE_CCOUNT is not set
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_XTENSA_ISS_NETWORK is not set
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# Platform options
+#
+# CONFIG_XTENSA_PLATFORM_ISS is not set
+# CONFIG_XTENSA_PLATFORM_XT2000 is not set
+CONFIG_XTENSA_PLATFORM_S6105=y
+CONFIG_XTENSA_CPU_CLOCK=300
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS1,38400 debug bootmem_debug loglevel=7"
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_VIRT_TO_BUS=y
+
+#
+# Executable file formats
+#
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+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 is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_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_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_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_CONNECTOR 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_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES 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 is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# 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
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# 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
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# 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
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Xtensa initrd options
+#
+# CONFIG_EMBEDDED_RAMDISK is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS 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=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_NOMMU_REGIONS=y
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS 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_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+
+#
+# Tracers
+#
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h
index 94c4c53a099..8fc1c0c8de0 100644
--- a/arch/xtensa/include/asm/cacheflush.h
+++ b/arch/xtensa/include/asm/cacheflush.h
@@ -65,13 +65,17 @@ extern void __flush_invalidate_dcache_range(unsigned long, unsigned long);
# define __flush_invalidate_dcache_range(p,s) __invalidate_dcache_range(p,s)
#endif
-#if (DCACHE_WAY_SIZE > PAGE_SIZE)
+#if defined(CONFIG_MMU) && (DCACHE_WAY_SIZE > PAGE_SIZE)
extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long);
+#else
+static inline void __flush_invalidate_dcache_page_alias(unsigned long virt,
+ unsigned long phys) { }
#endif
-#if (ICACHE_WAY_SIZE > PAGE_SIZE)
+#if defined(CONFIG_MMU) && (ICACHE_WAY_SIZE > PAGE_SIZE)
extern void __invalidate_icache_page_alias(unsigned long, unsigned long);
#else
-# define __invalidate_icache_page_alias(v,p) do { } while(0)
+static inline void __invalidate_icache_page_alias(unsigned long virt,
+ unsigned long phys) { }
#endif
/*
diff --git a/arch/xtensa/include/asm/dma.h b/arch/xtensa/include/asm/dma.h
index e30f3abf48f..137ca3945b0 100644
--- a/arch/xtensa/include/asm/dma.h
+++ b/arch/xtensa/include/asm/dma.h
@@ -44,8 +44,9 @@
* the value desired).
*/
+#ifndef MAX_DMA_ADDRESS
#define MAX_DMA_ADDRESS (PAGE_OFFSET + XCHAL_KIO_SIZE - 1)
-
+#endif
/* Reserve and release a DMA channel */
extern int request_dma(unsigned int dmanr, const char * device_id);
diff --git a/arch/xtensa/include/asm/flat.h b/arch/xtensa/include/asm/flat.h
new file mode 100644
index 00000000000..94c44abf15e
--- /dev/null
+++ b/arch/xtensa/include/asm/flat.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_XTENSA_FLAT_H
+#define __ASM_XTENSA_FLAT_H
+
+#define flat_argvp_envp_on_stack() 0
+#define flat_old_ram_flag(flags) (flags)
+#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
+#define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp)
+#define flat_put_addr_at_rp(rp, val, relval ) put_unaligned(val, rp)
+#define flat_get_relocate_addr(rel) (rel)
+#define flat_set_persistent(relval, p) 0
+
+#endif /* __ASM_XTENSA_FLAT_H */
diff --git a/arch/xtensa/include/asm/ftrace.h b/arch/xtensa/include/asm/ftrace.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/xtensa/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/xtensa/include/asm/gpio.h b/arch/xtensa/include/asm/gpio.h
new file mode 100644
index 00000000000..0763b076396
--- /dev/null
+++ b/arch/xtensa/include/asm/gpio.h
@@ -0,0 +1,56 @@
+/*
+ * Generic GPIO API implementation for xtensa.
+ *
+ * Stolen from x86, which is derived from the generic GPIO API for powerpc:
+ *
+ * Copyright (c) 2007-2008 MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.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.
+ */
+
+#ifndef _ASM_XTENSA_GPIO_H
+#define _ASM_XTENSA_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+#ifdef CONFIG_GPIOLIB
+
+/*
+ * Just call gpiolib.
+ */
+static inline int gpio_get_value(unsigned int gpio)
+{
+ return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned int gpio, int value)
+{
+ __gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned int gpio)
+{
+ return __gpio_cansleep(gpio);
+}
+
+/*
+ * Not implemented, yet.
+ */
+static inline int gpio_to_irq(unsigned int gpio)
+{
+ return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+ return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+#endif /* _ASM_XTENSA_GPIO_H */
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index 07b7299dab2..d04cd3a625f 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -69,21 +69,28 @@ static inline void * phys_to_virt(unsigned long address)
static inline void *ioremap(unsigned long offset, unsigned long size)
{
+#ifdef CONFIG_MMU
if (offset >= XCHAL_KIO_PADDR
&& offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR);
-
else
BUG();
+#else
+ return (void *)offset;
+#endif
}
static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
{
+#ifdef CONFIG_MMU
if (offset >= XCHAL_KIO_PADDR
&& offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR);
else
BUG();
+#else
+ return (void *)offset;
+#endif
}
static inline void iounmap(void *addr)
diff --git a/arch/xtensa/include/asm/irq.h b/arch/xtensa/include/asm/irq.h
index 1620d1e0e69..dfac82dc52a 100644
--- a/arch/xtensa/include/asm/irq.h
+++ b/arch/xtensa/include/asm/irq.h
@@ -14,6 +14,13 @@
#include <platform/hardware.h>
#include <variant/core.h>
+#ifdef CONFIG_VARIANT_IRQ_SWITCH
+#include <variant/irq.h>
+#else
+static inline void variant_irq_enable(unsigned int irq) { }
+static inline void variant_irq_disable(unsigned int irq) { }
+#endif
+
#ifndef PLATFORM_NR_IRQS
# define PLATFORM_NR_IRQS 0
#endif
diff --git a/arch/xtensa/include/asm/mmu.h b/arch/xtensa/include/asm/mmu.h
index 44c5bb04c55..04890d6e233 100644
--- a/arch/xtensa/include/asm/mmu.h
+++ b/arch/xtensa/include/asm/mmu.h
@@ -11,7 +11,12 @@
#ifndef _XTENSA_MMU_H
#define _XTENSA_MMU_H
+#ifndef CONFIG_MMU
+#include <asm/nommu.h>
+#else
+
/* Default "unsigned long" context */
typedef unsigned long mm_context_t;
+#endif /* CONFIG_MMU */
#endif /* _XTENSA_MMU_H */
diff --git a/arch/xtensa/include/asm/mmu_context.h b/arch/xtensa/include/asm/mmu_context.h
index c0fd8e5b451..dbd8731a876 100644
--- a/arch/xtensa/include/asm/mmu_context.h
+++ b/arch/xtensa/include/asm/mmu_context.h
@@ -13,16 +13,20 @@
#ifndef _XTENSA_MMU_CONTEXT_H
#define _XTENSA_MMU_CONTEXT_H
+#ifndef CONFIG_MMU
+#include <asm/nommu_context.h>
+#else
+
#include <linux/stringify.h>
#include <linux/sched.h>
+#include <variant/core.h>
+
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm-generic/mm_hooks.h>
-#define XCHAL_MMU_ASID_BITS 8
-
#if (XCHAL_HAVE_TLBS != 1)
# error "Linux must have an MMU!"
#endif
@@ -133,4 +137,5 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
}
+#endif /* CONFIG_MMU */
#endif /* _XTENSA_MMU_CONTEXT_H */
diff --git a/arch/xtensa/include/asm/nommu.h b/arch/xtensa/include/asm/nommu.h
new file mode 100644
index 00000000000..dce2c438c5b
--- /dev/null
+++ b/arch/xtensa/include/asm/nommu.h
@@ -0,0 +1,3 @@
+typedef struct {
+ unsigned long end_brk;
+} mm_context_t;
diff --git a/arch/xtensa/include/asm/nommu_context.h b/arch/xtensa/include/asm/nommu_context.h
new file mode 100644
index 00000000000..599e7a2e729
--- /dev/null
+++ b/arch/xtensa/include/asm/nommu_context.h
@@ -0,0 +1,25 @@
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ return 0;
+}
+
+static inline void destroy_context(struct mm_struct *mm)
+{
+}
+
+static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
+{
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+ struct task_struct *tsk)
+{
+}
+
+static inline void deactivate_mm(struct task_struct *tsk, struct mm_struct *mm)
+{
+}
diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h
index 11f7dc2dbec..17e0c5383b1 100644
--- a/arch/xtensa/include/asm/page.h
+++ b/arch/xtensa/include/asm/page.h
@@ -14,6 +14,7 @@
#include <asm/processor.h>
#include <asm/types.h>
#include <asm/cache.h>
+#include <platform/hardware.h>
/*
* Fixed TLB translations in the processor.
@@ -32,8 +33,14 @@
#define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
+#ifdef CONFIG_MMU
#define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR
#define MAX_MEM_PFN XCHAL_KSEG_SIZE
+#else
+#define PAGE_OFFSET 0
+#define MAX_MEM_PFN (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE)
+#endif
+
#define PGTABLE_START 0x80000000
/*
@@ -150,9 +157,11 @@ extern void copy_user_page(void*, void*, unsigned long, struct page*);
* addresses.
*/
+#define ARCH_PFN_OFFSET (PLATFORM_DEFAULT_MEM_START >> PAGE_SHIFT)
+
#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
-#define pfn_valid(pfn) ((unsigned long)pfn < max_mapnr)
+#define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
#ifdef CONFIG_DISCONTIGMEM
# error CONFIG_DISCONTIGMEM not supported
#endif
@@ -162,8 +171,9 @@ extern void copy_user_page(void*, void*, unsigned long, struct page*);
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
+#ifdef CONFIG_MMU
#define WANT_PAGE_VIRTUAL
-
+#endif
#endif /* __ASSEMBLY__ */
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h
index 8014d96b21f..a138770c358 100644
--- a/arch/xtensa/include/asm/pgtable.h
+++ b/arch/xtensa/include/asm/pgtable.h
@@ -183,7 +183,15 @@ extern unsigned long empty_zero_page[1024];
#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+#ifdef CONFIG_MMU
extern pgd_t swapper_pg_dir[PAGE_SIZE/sizeof(pgd_t)];
+extern void paging_init(void);
+extern void pgtable_cache_init(void);
+#else
+# define swapper_pg_dir NULL
+static inline void paging_init(void) { }
+static inline void pgtable_cache_init(void) { }
+#endif
/*
* The pmd contains the kernel virtual address of the pte page.
@@ -383,8 +391,6 @@ ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
#else
-extern void paging_init(void);
-
#define kern_addr_valid(addr) (1)
extern void update_mmu_cache(struct vm_area_struct * vma,
@@ -398,9 +404,6 @@ extern void update_mmu_cache(struct vm_area_struct * vma,
#define io_remap_pfn_range(vma,from,pfn,size,prot) \
remap_pfn_range(vma, from, pfn, size, prot)
-
-extern void pgtable_cache_init(void);
-
typedef pte_t *pte_addr_t;
#endif /* !defined (__ASSEMBLY__) */
diff --git a/arch/xtensa/include/asm/platform.h b/arch/xtensa/include/asm/platform.h
index e3d5a48ad49..7d936e58e9b 100644
--- a/arch/xtensa/include/asm/platform.h
+++ b/arch/xtensa/include/asm/platform.h
@@ -74,16 +74,5 @@ extern int platform_pcibios_fixup (void);
*/
extern void platform_calibrate_ccount (void);
-/*
- * platform_get_rtc_time returns RTC seconds (returns 0 for no error)
- */
-extern int platform_get_rtc_time(time_t*);
-
-/*
- * platform_set_rtc_time set RTC seconds (returns 0 for no error)
- */
-extern int platform_set_rtc_time(time_t);
-
-
#endif /* _XTENSA_PLATFORM_H */
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h
index 07387d3b99f..0ea4937c0b6 100644
--- a/arch/xtensa/include/asm/processor.h
+++ b/arch/xtensa/include/asm/processor.h
@@ -13,6 +13,7 @@
#include <variant/core.h>
#include <asm/coprocessor.h>
+#include <platform/hardware.h>
#include <linux/compiler.h>
#include <asm/ptrace.h>
@@ -25,6 +26,8 @@
# error Linux requires the Xtensa Windowed Registers Option.
#endif
+#define ARCH_SLAB_MINALIGN XCHAL_DATA_WIDTH
+
/*
* User space process size: 1 GB.
* Windowed call ABI requires caller and callee to be located within the same
@@ -33,7 +36,12 @@
* the 1 GB requirement applies to the stack as well.
*/
+#ifdef CONFIG_MMU
#define TASK_SIZE __XTENSA_UL_CONST(0x40000000)
+#else
+#define TASK_SIZE (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE)
+#endif
+
#define STACK_TOP TASK_SIZE
#define STACK_TOP_MAX STACK_TOP
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index a51d36a2738..80d24c485fd 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -1463,6 +1463,7 @@ ENTRY(_spill_registers)
callx0 a0 # should not return
1: j 1b
+#ifdef CONFIG_MMU
/*
* We should never get here. Bail out!
*/
@@ -1775,7 +1776,7 @@ ENTRY(fast_store_prohibited)
bbsi.l a2, PS_UM_BIT, 1f
j _kernel_exception
1: j _user_exception
-
+#endif /* CONFIG_MMU */
/*
* System Calls.
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S
index 67e69139520..0817f9db836 100644
--- a/arch/xtensa/kernel/head.S
+++ b/arch/xtensa/kernel/head.S
@@ -53,7 +53,7 @@ _start: _j 2f
2: l32r a0, 1b
jx a0
- .text
+ .section .init.text, "ax"
.align 4
_startup:
@@ -235,8 +235,9 @@ should_never_return:
*/
.section ".bss.page_aligned", "w"
+#ifdef CONFIG_MMU
ENTRY(swapper_pg_dir)
.fill PAGE_SIZE, 1, 0
+#endif
ENTRY(empty_zero_page)
.fill PAGE_SIZE, 1, 0
-
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index f3b66fba5b8..a36c85edd04 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -132,6 +132,18 @@ static void xtensa_irq_unmask(unsigned int irq)
set_sr (cached_irq_mask, INTENABLE);
}
+static void xtensa_irq_enable(unsigned int irq)
+{
+ variant_irq_enable(irq);
+ xtensa_irq_unmask(irq);
+}
+
+static void xtensa_irq_disable(unsigned int irq)
+{
+ xtensa_irq_mask(irq);
+ variant_irq_disable(irq);
+}
+
static void xtensa_irq_ack(unsigned int irq)
{
set_sr(1 << irq, INTCLEAR);
@@ -146,6 +158,8 @@ static int xtensa_irq_retrigger(unsigned int irq)
static struct irq_chip xtensa_irq_chip = {
.name = "xtensa",
+ .enable = xtensa_irq_enable,
+ .disable = xtensa_irq_disable,
.mask = xtensa_irq_mask,
.unmask = xtensa_irq_unmask,
.ack = xtensa_irq_ack,
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c
index 69675f21606..1b91a97f1d8 100644
--- a/arch/xtensa/kernel/platform.c
+++ b/arch/xtensa/kernel/platform.c
@@ -36,8 +36,6 @@ _F(void, power_off, (void), { while(1); });
_F(void, idle, (void), { __asm__ __volatile__ ("waiti 0" ::: "memory"); });
_F(void, heartbeat, (void), { });
_F(int, pcibios_fixup, (void), { return 0; });
-_F(int, get_rtc_time, (time_t* t), { return 0; });
-_F(int, set_rtc_time, (time_t t), { return 0; });
#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
_F(void, calibrate_ccount, (void),
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 4ec1633c294..1e5a034fe01 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -84,7 +84,13 @@ sysmem_info_t __initdata sysmem;
int initrd_is_mapped;
#endif
+#ifdef CONFIG_MMU
extern void init_mmu(void);
+#else
+static inline void init_mmu(void) { }
+#endif
+
+extern void zones_init(void);
/*
* Boot parameter parsing.
@@ -286,6 +292,7 @@ void __init setup_arch(char **cmdline_p)
paging_init();
+ zones_init();
#ifdef CONFIG_VT
# if defined(CONFIG_VGA_CONSOLE)
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index 8df1e842f6d..8848120d291 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -14,7 +14,7 @@
#include <linux/errno.h>
#include <linux/time.h>
-#include <linux/timex.h>
+#include <linux/clocksource.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -25,27 +25,31 @@
#include <asm/timex.h>
#include <asm/platform.h>
-
-DEFINE_SPINLOCK(rtc_lock);
-EXPORT_SYMBOL(rtc_lock);
-
-
#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
unsigned long ccount_per_jiffy; /* per 1/HZ */
unsigned long nsec_per_ccount; /* nsec per ccount increment */
#endif
-static long last_rtc_update = 0;
-
-/*
- * Scheduler clock - returns current tim in nanosec units.
- */
-
-unsigned long long sched_clock(void)
+static cycle_t ccount_read(void)
{
- return (unsigned long long)jiffies * (1000000000 / HZ);
+ return (cycle_t)get_ccount();
}
+static struct clocksource ccount_clocksource = {
+ .name = "ccount",
+ .rating = 200,
+ .read = ccount_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ /*
+ * With a shift of 22 the lower limit of the cpu clock is
+ * 1MHz, where NSEC_PER_CCOUNT is 1000 or a bit less than
+ * 2^10: Since we have 32 bits and the multiplicator can
+ * already take up as much as 10 bits, this leaves us with
+ * remaining upper 22 bits.
+ */
+ .shift = 22,
+};
+
static irqreturn_t timer_interrupt(int irq, void *dev_id);
static struct irqaction timer_irqaction = {
.handler = timer_interrupt,
@@ -55,11 +59,11 @@ static struct irqaction timer_irqaction = {
void __init time_init(void)
{
- time_t sec_o, sec_n = 0;
+ xtime.tv_nsec = 0;
+ xtime.tv_sec = read_persistent_clock();
- /* The platform must provide a function to calibrate the processor
- * speed for the CALIBRATE.
- */
+ set_normalized_timespec(&wall_to_monotonic,
+ -xtime.tv_sec, -xtime.tv_nsec);
#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
printk("Calibrating CPU frequency ");
@@ -67,19 +71,10 @@ void __init time_init(void)
printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ),
(int)(ccount_per_jiffy/(10000/HZ))%100);
#endif
-
- /* Set time from RTC (if provided) */
-
- if (platform_get_rtc_time(&sec_o) == 0)
- while (platform_get_rtc_time(&sec_n))
- if (sec_o != sec_n)
- break;
-
- xtime.tv_nsec = 0;
- last_rtc_update = xtime.tv_sec = sec_n;
-
- set_normalized_timespec(&wall_to_monotonic,
- -xtime.tv_sec, -xtime.tv_nsec);
+ ccount_clocksource.mult =
+ clocksource_hz2mult(CCOUNT_PER_JIFFY * HZ,
+ ccount_clocksource.shift);
+ clocksource_register(&ccount_clocksource);
/* Initialize the linux timer interrupt. */
@@ -87,69 +82,6 @@ void __init time_init(void)
set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY);
}
-
-int do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
- unsigned long delta;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
-
- /* This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * made, and then undo it!
- */
-
- delta = CCOUNT_PER_JIFFY;
- delta += get_ccount() - get_linux_timer();
- nsec -= delta * NSEC_PER_CCOUNT;
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
-
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- unsigned long volatile sec, usec, delta, seq;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
-
- sec = xtime.tv_sec;
- usec = (xtime.tv_nsec / NSEC_PER_USEC);
-
- delta = get_linux_timer() - get_ccount();
-
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- usec += (((unsigned long) CCOUNT_PER_JIFFY - delta)
- * (unsigned long) NSEC_PER_CCOUNT) / NSEC_PER_USEC;
-
- for (; usec >= 1000000; sec++, usec -= 1000000)
- ;
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
/*
* The timer interrupt is called HZ times per second.
*/
@@ -178,16 +110,6 @@ again:
next += CCOUNT_PER_JIFFY;
set_linux_timer(next);
- if (ntp_synced() &&
- xtime.tv_sec - last_rtc_update >= 659 &&
- abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ) {
-
- if (platform_set_rtc_time(xtime.tv_sec+1) == 0)
- last_rtc_update = xtime.tv_sec+1;
- else
- /* Do it again in 60 s */
- last_rtc_update += 60;
- }
write_sequnlock(&xtime_lock);
}
@@ -213,4 +135,3 @@ void __cpuinit calibrate_delay(void)
(loops_per_jiffy/(10000/HZ)) % 100);
}
#endif
-
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index c44f830b6c7..9f0b71189e9 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -104,6 +104,7 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
#endif
{ EXCCAUSE_UNALIGNED, KRNL, fast_unaligned },
#endif
+#ifdef CONFIG_MMU
{ EXCCAUSE_ITLB_MISS, 0, do_page_fault },
{ EXCCAUSE_ITLB_MISS, USER|KRNL, fast_second_level_miss},
{ EXCCAUSE_ITLB_MULTIHIT, 0, do_multihit },
@@ -118,6 +119,7 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, USER|KRNL, fast_store_prohibited },
{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault },
{ EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault },
+#endif /* CONFIG_MMU */
/* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */
#if XTENSA_HAVE_COPROCESSOR(0)
COPROCESSOR(0),
@@ -372,11 +374,10 @@ void show_trace(struct task_struct *task, unsigned long *sp)
unsigned long a0, a1, pc;
unsigned long sp_start, sp_end;
- a1 = (unsigned long)sp;
-
- if (a1 == 0)
- __asm__ __volatile__ ("mov %0, a1\n" : "=a"(a1));
-
+ if (sp)
+ a1 = (unsigned long)sp;
+ else
+ a1 = task->thread.sp;
sp_start = a1 & ~(THREAD_SIZE-1);
sp_end = sp_start + THREAD_SIZE;
@@ -418,9 +419,8 @@ void show_stack(struct task_struct *task, unsigned long *sp)
int i = 0;
unsigned long *stack;
- if (sp == 0)
- __asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp));
-
+ if (!sp)
+ sp = (unsigned long *)task->thread.sp;
stack = sp;
printk("\nStack: ");
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
index eb2d7bb69ee..74a7518faf1 100644
--- a/arch/xtensa/kernel/vectors.S
+++ b/arch/xtensa/kernel/vectors.S
@@ -309,6 +309,7 @@ ENTRY(_DoubleExceptionVector)
* All other exceptions are unexpected and thus unrecoverable!
*/
+#ifdef CONFIG_MMU
.extern fast_second_level_miss_double_kernel
.Lksp: /* a0: a0, a1: a1, a2: a2, a3: trashed, depc: depc, excsave: a3 */
@@ -319,6 +320,9 @@ ENTRY(_DoubleExceptionVector)
bnez a3, .Lunrecoverable
1: movi a3, fast_second_level_miss_double_kernel
jx a3
+#else
+.equ .Lksp, .Lunrecoverable
+#endif
/* Critical! We can't handle this situation. PANIC! */
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index d506774f4b0..c1be9a4a740 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -17,6 +17,7 @@
#include <asm-generic/vmlinux.lds.h>
#include <variant/core.h>
+#include <platform/hardware.h>
OUTPUT_ARCH(xtensa)
ENTRY(_start)
@@ -26,7 +27,9 @@ jiffies = jiffies_64 + 4;
jiffies = jiffies_64;
#endif
+#ifndef KERNELOFFSET
#define KERNELOFFSET 0xd0001000
+#endif
/* Note: In the following macros, it would be nice to specify only the
vector name and section kind and construct "sym" and "section" using
diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile
index 64e304a2f88..f0b646d2f84 100644
--- a/arch/xtensa/mm/Makefile
+++ b/arch/xtensa/mm/Makefile
@@ -2,4 +2,5 @@
# Makefile for the Linux/Xtensa-specific parts of the memory manager.
#
-obj-y := init.o fault.o tlb.o misc.o cache.o
+obj-y := init.o cache.o misc.o
+obj-$(CONFIG_MMU) += fault.o mmu.o tlb.o
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index 34163cfaaff..427e14fa43c 100644
--- a/arch/xtensa/mm/init.c
+++ b/arch/xtensa/mm/init.c
@@ -24,15 +24,8 @@
#include <linux/mm.h>
#include <linux/slab.h>
-#include <asm/pgtable.h>
#include <asm/bootparam.h>
-#include <asm/mmu_context.h>
-#include <asm/tlb.h>
#include <asm/page.h>
-#include <asm/pgalloc.h>
-
-
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
/* References to section boundaries */
@@ -130,7 +123,8 @@ void __init bootmem_init(void)
/* Find an area to use for the bootmem bitmap. */
- bootmap_size = bootmem_bootmap_pages(max_low_pfn) << PAGE_SHIFT;
+ bootmap_size = bootmem_bootmap_pages(max_low_pfn - min_low_pfn);
+ bootmap_size <<= PAGE_SHIFT;
bootmap_start = ~0;
for (i=0; i<sysmem.nr_banks; i++)
@@ -145,8 +139,9 @@ void __init bootmem_init(void)
/* Reserve the bootmem bitmap area */
mem_reserve(bootmap_start, bootmap_start + bootmap_size, 1);
- bootmap_size = init_bootmem_node(NODE_DATA(0), min_low_pfn,
+ bootmap_size = init_bootmem_node(NODE_DATA(0),
bootmap_start >> PAGE_SHIFT,
+ min_low_pfn,
max_low_pfn);
/* Add all remaining memory pieces into the bootmem map */
@@ -158,14 +153,14 @@ void __init bootmem_init(void)
}
-void __init paging_init(void)
+void __init zones_init(void)
{
unsigned long zones_size[MAX_NR_ZONES];
int i;
/* All pages are DMA-able, so we put them all in the DMA zone. */
- zones_size[ZONE_DMA] = max_low_pfn;
+ zones_size[ZONE_DMA] = max_low_pfn - ARCH_PFN_OFFSET;
for (i = 1; i < MAX_NR_ZONES; i++)
zones_size[i] = 0;
@@ -173,40 +168,7 @@ void __init paging_init(void)
zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
#endif
- /* Initialize the kernel's page tables. */
-
- memset(swapper_pg_dir, 0, PAGE_SIZE);
-
- free_area_init(zones_size);
-}
-
-/*
- * Flush the mmu and reset associated register to default values.
- */
-
-void __init init_mmu (void)
-{
- /* Writing zeros to the <t>TLBCFG special registers ensure
- * that valid values exist in the register. For existing
- * PGSZID<w> fields, zero selects the first element of the
- * page-size array. For nonexistent PGSZID<w> fields, zero is
- * the best value to write. Also, when changing PGSZID<w>
- * fields, the corresponding TLB must be flushed.
- */
- set_itlbcfg_register (0);
- set_dtlbcfg_register (0);
- flush_tlb_all ();
-
- /* Set rasid register to a known value. */
-
- set_rasid_register (ASID_USER_FIRST);
-
- /* Set PTEVADDR special register to the start of the page
- * table, which is in kernel mappable space (ie. not
- * statically mapped). This register's value is undefined on
- * reset.
- */
- set_ptevaddr_register (PGTABLE_START);
+ free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL);
}
/*
@@ -218,8 +180,8 @@ void __init mem_init(void)
unsigned long codesize, reservedpages, datasize, initsize;
unsigned long highmemsize, tmp, ram;
- max_mapnr = num_physpages = max_low_pfn;
- high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
+ max_mapnr = num_physpages = max_low_pfn - ARCH_PFN_OFFSET;
+ high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
highmemsize = 0;
#ifdef CONFIG_HIGHMEM
@@ -229,7 +191,7 @@ void __init mem_init(void)
totalram_pages += free_all_bootmem();
reservedpages = ram = 0;
- for (tmp = 0; tmp < max_low_pfn; tmp++) {
+ for (tmp = 0; tmp < max_mapnr; tmp++) {
ram++;
if (PageReserved(mem_map+tmp))
reservedpages++;
@@ -279,23 +241,3 @@ void free_initmem(void)
printk("Freeing unused kernel memory: %dk freed\n",
(&__init_end - &__init_begin) >> 10);
}
-
-struct kmem_cache *pgtable_cache __read_mostly;
-
-static void pgd_ctor(void* addr)
-{
- pte_t* ptep = (pte_t*)addr;
- int i;
-
- for (i = 0; i < 1024; i++, ptep++)
- pte_clear(NULL, 0, ptep);
-
-}
-
-void __init pgtable_cache_init(void)
-{
- pgtable_cache = kmem_cache_create("pgd",
- PAGE_SIZE, PAGE_SIZE,
- SLAB_HWCACHE_ALIGN,
- pgd_ctor);
-}
diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S
index c885664211d..b048406d875 100644
--- a/arch/xtensa/mm/misc.S
+++ b/arch/xtensa/mm/misc.S
@@ -84,6 +84,7 @@ ENTRY(copy_page)
retw
+#ifdef CONFIG_MMU
/*
* If we have to deal with cache aliasing, we use temporary memory mappings
* to ensure that the source and destination pages have the same color as
@@ -311,6 +312,7 @@ ENTRY(__invalidate_icache_page_alias)
/* End of special treatment in tlb miss exception */
ENTRY(__tlbtemp_mapping_end)
+#endif /* CONFIG_MMU
/*
* void __invalidate_icache_page(ulong start)
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c
new file mode 100644
index 00000000000..4bb91a970f1
--- /dev/null
+++ b/arch/xtensa/mm/mmu.c
@@ -0,0 +1,70 @@
+/*
+ * xtensa mmu stuff
+ *
+ * Extracted from init.c
+ */
+#include <linux/percpu.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/cache.h>
+
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+#include <asm/page.h>
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+void __init paging_init(void)
+{
+ memset(swapper_pg_dir, 0, PAGE_SIZE);
+}
+
+/*
+ * Flush the mmu and reset associated register to default values.
+ */
+void __init init_mmu(void)
+{
+ /* Writing zeros to the <t>TLBCFG special registers ensure
+ * that valid values exist in the register. For existing
+ * PGSZID<w> fields, zero selects the first element of the
+ * page-size array. For nonexistent PGSZID<w> fields, zero is
+ * the best value to write. Also, when changing PGSZID<w>
+ * fields, the corresponding TLB must be flushed.
+ */
+ set_itlbcfg_register(0);
+ set_dtlbcfg_register(0);
+ flush_tlb_all();
+
+ /* Set rasid register to a known value. */
+
+ set_rasid_register(ASID_USER_FIRST);
+
+ /* Set PTEVADDR special register to the start of the page
+ * table, which is in kernel mappable space (ie. not
+ * statically mapped). This register's value is undefined on
+ * reset.
+ */
+ set_ptevaddr_register(PGTABLE_START);
+}
+
+struct kmem_cache *pgtable_cache __read_mostly;
+
+static void pgd_ctor(void *addr)
+{
+ pte_t *ptep = (pte_t *)addr;
+ int i;
+
+ for (i = 0; i < 1024; i++, ptep++)
+ pte_clear(NULL, 0, ptep);
+
+}
+
+void __init pgtable_cache_init(void)
+{
+ pgtable_cache = kmem_cache_create("pgd",
+ PAGE_SIZE, PAGE_SIZE,
+ SLAB_HWCACHE_ALIGN,
+ pgd_ctor);
+}
diff --git a/arch/xtensa/platforms/s6105/Makefile b/arch/xtensa/platforms/s6105/Makefile
new file mode 100644
index 00000000000..0be6194bcb7
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/Makefile
@@ -0,0 +1,3 @@
+# Makefile for the Stretch S6105 eval board
+
+obj-y := setup.o device.o
diff --git a/arch/xtensa/platforms/s6105/device.c b/arch/xtensa/platforms/s6105/device.c
new file mode 100644
index 00000000000..78b08be5a92
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/device.c
@@ -0,0 +1,67 @@
+/*
+ * s6105 platform devices
+ *
+ * Copyright (c) 2009 emlix GmbH
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+
+#include <variant/hardware.h>
+
+#define UART_INTNUM 4
+
+static const signed char uart_irq_mappings[] = {
+ S6_INTC_UART(0),
+ S6_INTC_UART(1),
+ -1,
+};
+
+const signed char *platform_irq_mappings[NR_IRQS] = {
+ [UART_INTNUM] = uart_irq_mappings,
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .membase = (void *)S6_REG_UART + 0x0000,
+ .mapbase = S6_REG_UART + 0x0000,
+ .irq = UART_INTNUM,
+ .uartclk = S6_SCLK,
+ .regshift = 2,
+ .iotype = SERIAL_IO_MEM,
+ .flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST,
+ },
+ {
+ .membase = (void *)S6_REG_UART + 0x1000,
+ .mapbase = S6_REG_UART + 0x1000,
+ .irq = UART_INTNUM,
+ .uartclk = S6_SCLK,
+ .regshift = 2,
+ .iotype = SERIAL_IO_MEM,
+ .flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST,
+ },
+ { },
+};
+
+static struct platform_device platform_devices[] = {
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+ },
+};
+
+static int __init device_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(platform_devices); i++)
+ platform_device_register(&platform_devices[i]);
+ return 0;
+}
+arch_initcall_sync(device_init);
diff --git a/arch/xtensa/platforms/s6105/include/platform/gpio.h b/arch/xtensa/platforms/s6105/include/platform/gpio.h
new file mode 100644
index 00000000000..fa11aa4b61e
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/include/platform/gpio.h
@@ -0,0 +1,27 @@
+#ifndef __ASM_XTENSA_S6105_GPIO_H
+#define __ASM_XTENSA_S6105_GPIO_H
+
+#define GPIO_BP_TEMP_ALARM 0
+#define GPIO_PB_RESET_IN 1
+#define GPIO_EXP_IRQ 2
+#define GPIO_TRIGGER_IRQ 3
+#define GPIO_RTC_IRQ 4
+#define GPIO_PHY_IRQ 5
+#define GPIO_IMAGER_RESET 6
+#define GPIO_SD_IRQ 7
+#define GPIO_MINI_BOOT_INH 8
+#define GPIO_BOARD_RESET 9
+#define GPIO_EXP_PRESENT 10
+#define GPIO_LED1_NGREEN 12
+#define GPIO_LED1_RED 13
+#define GPIO_LED0_NGREEN 14
+#define GPIO_LED0_NRED 15
+#define GPIO_SPI_CS0 16
+#define GPIO_SPI_CS1 17
+#define GPIO_SPI_CS3 19
+#define GPIO_SPI_CS4 20
+#define GPIO_SD_WP 21
+#define GPIO_BP_RESET 22
+#define GPIO_ALARM_OUT 23
+
+#endif /* __ASM_XTENSA_S6105_GPIO_H */
diff --git a/arch/xtensa/platforms/s6105/include/platform/hardware.h b/arch/xtensa/platforms/s6105/include/platform/hardware.h
new file mode 100644
index 00000000000..d628efac708
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/include/platform/hardware.h
@@ -0,0 +1,11 @@
+#ifndef __XTENSA_S6105_HARDWARE_H
+#define __XTENSA_S6105_HARDWARE_H
+
+#define PLATFORM_DEFAULT_MEM_START 0x40000000
+#define PLATFORM_DEFAULT_MEM_SIZE 0x08000000
+
+#define MAX_DMA_ADDRESS 0
+
+#define KERNELOFFSET (PLATFORM_DEFAULT_MEM_START + 0x1000)
+
+#endif /* __XTENSA_S6105_HARDWARE_H */
diff --git a/arch/xtensa/platforms/s6105/include/platform/serial.h b/arch/xtensa/platforms/s6105/include/platform/serial.h
new file mode 100644
index 00000000000..c8a771e5981
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/include/platform/serial.h
@@ -0,0 +1,8 @@
+#ifndef __ASM_XTENSA_S6105_SERIAL_H
+#define __ASM_XTENSA_S6105_SERIAL_H
+
+#include <variant/hardware.h>
+
+#define BASE_BAUD (S6_SCLK / 16)
+
+#endif /* __ASM_XTENSA_S6105_SERIAL_H */
diff --git a/arch/xtensa/platforms/s6105/setup.c b/arch/xtensa/platforms/s6105/setup.c
new file mode 100644
index 00000000000..ae041d5027a
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/setup.c
@@ -0,0 +1,61 @@
+/*
+ * s6105 control routines
+ *
+ * Copyright (c) 2009 emlix GmbH
+ */
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/bootparam.h>
+
+#include <variant/hardware.h>
+#include <platform/gpio.h>
+
+void platform_halt(void)
+{
+ local_irq_disable();
+ while (1)
+ ;
+}
+
+void platform_power_off(void)
+{
+ platform_halt();
+}
+
+void platform_restart(void)
+{
+ platform_halt();
+}
+
+void __init platform_setup(char **cmdline)
+{
+ unsigned long reg;
+
+ reg = readl(S6_REG_GREG1 + S6_GREG1_CLKGATE);
+ reg &= ~(1 << S6_GREG1_BLOCK_SB);
+ writel(reg, S6_REG_GREG1 + S6_GREG1_CLKGATE);
+
+ reg = readl(S6_REG_GREG1 + S6_GREG1_BLOCKENA);
+ reg |= 1 << S6_GREG1_BLOCK_SB;
+ writel(reg, S6_REG_GREG1 + S6_GREG1_BLOCKENA);
+
+ printk(KERN_NOTICE "S6105 on Stretch S6000 - "
+ "Copyright (C) 2009 emlix GmbH <info@emlix.com>\n");
+}
+
+void __init platform_init(bp_tag_t *first)
+{
+ gpio_request(GPIO_LED1_NGREEN, "led1_green");
+ gpio_request(GPIO_LED1_RED, "led1_red");
+ gpio_direction_output(GPIO_LED1_NGREEN, 1);
+}
+
+void platform_heartbeat(void)
+{
+ static unsigned int c;
+
+ if (!(++c & 0x4F))
+ gpio_direction_output(GPIO_LED1_RED, !(c & 0x10));
+}
diff --git a/arch/xtensa/platforms/xt2000/include/platform/hardware.h b/arch/xtensa/platforms/xt2000/include/platform/hardware.h
index 41459ad0776..886ef156ded 100644
--- a/arch/xtensa/platforms/xt2000/include/platform/hardware.h
+++ b/arch/xtensa/platforms/xt2000/include/platform/hardware.h
@@ -16,7 +16,6 @@
#define _XTENSA_XT2000_HARDWARE_H
#include <variant/core.h>
-#include <asm/io.h>
/*
* Memory configuration.
diff --git a/arch/xtensa/variants/s6000/Makefile b/arch/xtensa/variants/s6000/Makefile
new file mode 100644
index 00000000000..03b3975468b
--- /dev/null
+++ b/arch/xtensa/variants/s6000/Makefile
@@ -0,0 +1,3 @@
+# s6000 Makefile
+
+obj-y += irq.o gpio.o
diff --git a/arch/xtensa/variants/s6000/gpio.c b/arch/xtensa/variants/s6000/gpio.c
new file mode 100644
index 00000000000..33a8d952934
--- /dev/null
+++ b/arch/xtensa/variants/s6000/gpio.c
@@ -0,0 +1,71 @@
+/*
+ * s6000 gpio driver
+ *
+ * Copyright (c) 2009 emlix GmbH
+ * Authors: Oskar Schirmer <os@emlix.com>
+ * Johannes Weiner <jw@emlix.com>
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <variant/hardware.h>
+
+#define S6_GPIO_DATA 0x000
+#define S6_GPIO_IS 0x404
+#define S6_GPIO_IBE 0x408
+#define S6_GPIO_IEV 0x40C
+#define S6_GPIO_IE 0x410
+#define S6_GPIO_RIS 0x414
+#define S6_GPIO_MIS 0x418
+#define S6_GPIO_IC 0x41C
+#define S6_GPIO_AFSEL 0x420
+#define S6_GPIO_DIR 0x800
+#define S6_GPIO_BANK(nr) ((nr) * 0x1000)
+#define S6_GPIO_MASK(nr) (4 << (nr))
+#define S6_GPIO_OFFSET(nr) \
+ (S6_GPIO_BANK((nr) >> 3) + S6_GPIO_MASK((nr) & 7))
+
+static int direction_input(struct gpio_chip *chip, unsigned int off)
+{
+ writeb(0, S6_REG_GPIO + S6_GPIO_DIR + S6_GPIO_OFFSET(off));
+ return 0;
+}
+
+static int get(struct gpio_chip *chip, unsigned int off)
+{
+ return readb(S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off));
+}
+
+static int direction_output(struct gpio_chip *chip, unsigned int off, int val)
+{
+ unsigned rel = S6_GPIO_OFFSET(off);
+ writeb(~0, S6_REG_GPIO + S6_GPIO_DIR + rel);
+ writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + rel);
+ return 0;
+}
+
+static void set(struct gpio_chip *chip, unsigned int off, int val)
+{
+ writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off));
+}
+
+static struct gpio_chip gpiochip = {
+ .owner = THIS_MODULE,
+ .direction_input = direction_input,
+ .get = get,
+ .direction_output = direction_output,
+ .set = set,
+ .base = 0,
+ .ngpio = 24,
+ .can_sleep = 0, /* no blocking io needed */
+ .exported = 0, /* no exporting to userspace */
+};
+
+static int gpio_init(void)
+{
+ return gpiochip_add(&gpiochip);
+}
+device_initcall(gpio_init);
diff --git a/arch/xtensa/variants/s6000/include/variant/core.h b/arch/xtensa/variants/s6000/include/variant/core.h
new file mode 100644
index 00000000000..af007953027
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/core.h
@@ -0,0 +1,431 @@
+/*
+ * Xtensa processor core configuration information.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2008 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_CONFIGURATION_H
+#define _XTENSA_CORE_CONFIGURATION_H
+
+
+/****************************************************************************
+ Parameters Useful for Any Code, USER or PRIVILEGED
+ ****************************************************************************/
+
+/*
+ * Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is
+ * configured, and a value of 0 otherwise. These macros are always defined.
+ */
+
+
+/*----------------------------------------------------------------------
+ ISA
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_BE 0 /* big-endian byte ordering */
+#define XCHAL_HAVE_WINDOWED 1 /* windowed registers option */
+#define XCHAL_NUM_AREGS 64 /* num of physical addr regs */
+#define XCHAL_NUM_AREGS_LOG2 6 /* log2(XCHAL_NUM_AREGS) */
+#define XCHAL_MAX_INSTRUCTION_SIZE 8 /* max instr bytes (3..8) */
+#define XCHAL_HAVE_DEBUG 1 /* debug option */
+#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */
+#define XCHAL_HAVE_LOOPS 1 /* zero-overhead loops */
+#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */
+#define XCHAL_HAVE_MINMAX 1 /* MIN/MAX instructions */
+#define XCHAL_HAVE_SEXT 1 /* SEXT instruction */
+#define XCHAL_HAVE_CLAMPS 1 /* CLAMPS instruction */
+#define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */
+#define XCHAL_HAVE_MUL32 1 /* MULL instruction */
+#define XCHAL_HAVE_MUL32_HIGH 1 /* MULUH/MULSH instructions */
+#define XCHAL_HAVE_DIV32 0 /* QUOS/QUOU/REMS/REMU instructions */
+#define XCHAL_HAVE_L32R 1 /* L32R instruction */
+#define XCHAL_HAVE_ABSOLUTE_LITERALS 1 /* non-PC-rel (extended) L32R */
+#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */
+#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */
+#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */
+#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */
+#define XCHAL_HAVE_CALL4AND12 1 /* (obsolete option) */
+#define XCHAL_HAVE_ABS 1 /* ABS instruction */
+/*#define XCHAL_HAVE_POPC 0*/ /* POPC instruction */
+/*#define XCHAL_HAVE_CRC 0*/ /* CRC instruction */
+#define XCHAL_HAVE_RELEASE_SYNC 0 /* L32AI/S32RI instructions */
+#define XCHAL_HAVE_S32C1I 0 /* S32C1I instruction */
+#define XCHAL_HAVE_SPECULATION 0 /* speculation */
+#define XCHAL_HAVE_FULL_RESET 0 /* all regs/state reset */
+#define XCHAL_NUM_CONTEXTS 1 /* */
+#define XCHAL_NUM_MISC_REGS 4 /* num of scratch regs (0..4) */
+#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */
+#define XCHAL_HAVE_PRID 0 /* processor ID register */
+#define XCHAL_HAVE_THREADPTR 0 /* THREADPTR register */
+#define XCHAL_HAVE_BOOLEANS 1 /* boolean registers */
+#define XCHAL_HAVE_CP 1 /* CPENABLE reg (coprocessor) */
+#define XCHAL_CP_MAXCFG 8 /* max allowed cp id plus one */
+#define XCHAL_HAVE_MAC16 0 /* MAC16 package */
+#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */
+#define XCHAL_HAVE_FP 1 /* floating point pkg */
+#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */
+#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */
+#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */
+
+
+/*----------------------------------------------------------------------
+ MISC
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_WRITEBUFFER_ENTRIES 8 /* size of write buffer */
+#define XCHAL_INST_FETCH_WIDTH 8 /* instr-fetch width in bytes */
+#define XCHAL_DATA_WIDTH 16 /* data width in bytes */
+/* In T1050, applies to selected core load and store instructions (see ISA): */
+#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */
+#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/
+
+#define XCHAL_SW_VERSION 701001 /* sw version of this header */
+
+#define XCHAL_CORE_ID "stretch_bali" /* alphanum core name
+ (CoreID) set in the Xtensa
+ Processor Generator */
+
+#define XCHAL_BUILD_UNIQUE_ID 0x000104B9 /* 22-bit sw build ID */
+
+/*
+ * These definitions describe the hardware targeted by this software.
+ */
+#define XCHAL_HW_CONFIGID0 0xC2F3F9FE /* ConfigID hi 32 bits*/
+#define XCHAL_HW_CONFIGID1 0x054104B9 /* ConfigID lo 32 bits*/
+#define XCHAL_HW_VERSION_NAME "LX1.0.2" /* full version name */
+#define XCHAL_HW_VERSION_MAJOR 2100 /* major ver# of targeted hw */
+#define XCHAL_HW_VERSION_MINOR 2 /* minor ver# of targeted hw */
+#define XCHAL_HW_VERSION 210002 /* major*100+minor */
+#define XCHAL_HW_REL_LX1 1
+#define XCHAL_HW_REL_LX1_0 1
+#define XCHAL_HW_REL_LX1_0_2 1
+#define XCHAL_HW_CONFIGID_RELIABLE 1
+/* If software targets a *range* of hardware versions, these are the bounds: */
+#define XCHAL_HW_MIN_VERSION_MAJOR 2100 /* major v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION_MINOR 2 /* minor v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION 210002 /* earliest targeted hw */
+#define XCHAL_HW_MAX_VERSION_MAJOR 2100 /* major v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION_MINOR 2 /* minor v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION 210002 /* latest targeted hw */
+
+
+/*----------------------------------------------------------------------
+ CACHE
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_ICACHE_LINESIZE 16 /* I-cache line size in bytes */
+#define XCHAL_DCACHE_LINESIZE 16 /* D-cache line size in bytes */
+#define XCHAL_ICACHE_LINEWIDTH 4 /* log2(I line size in bytes) */
+#define XCHAL_DCACHE_LINEWIDTH 4 /* log2(D line size in bytes) */
+
+#define XCHAL_ICACHE_SIZE 32768 /* I-cache size in bytes or 0 */
+#define XCHAL_DCACHE_SIZE 32768 /* D-cache size in bytes or 0 */
+
+#define XCHAL_DCACHE_IS_WRITEBACK 1 /* writeback feature */
+
+
+
+
+/****************************************************************************
+ Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code
+ ****************************************************************************/
+
+
+#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY
+
+/*----------------------------------------------------------------------
+ CACHE
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_PIF 1 /* any outbound PIF present */
+
+/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */
+
+/* Number of cache sets in log2(lines per way): */
+#define XCHAL_ICACHE_SETWIDTH 9
+#define XCHAL_DCACHE_SETWIDTH 10
+
+/* Cache set associativity (number of ways): */
+#define XCHAL_ICACHE_WAYS 4
+#define XCHAL_DCACHE_WAYS 2
+
+/* Cache features: */
+#define XCHAL_ICACHE_LINE_LOCKABLE 1
+#define XCHAL_DCACHE_LINE_LOCKABLE 0
+#define XCHAL_ICACHE_ECC_PARITY 0
+#define XCHAL_DCACHE_ECC_PARITY 0
+
+/* Number of encoded cache attr bits (see <xtensa/hal.h> for decoded bits): */
+#define XCHAL_CA_BITS 4
+
+
+/*----------------------------------------------------------------------
+ INTERNAL I/D RAM/ROMs and XLMI
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_INSTROM 0 /* number of core instr. ROMs */
+#define XCHAL_NUM_INSTRAM 0 /* number of core instr. RAMs */
+#define XCHAL_NUM_DATAROM 0 /* number of core data ROMs */
+#define XCHAL_NUM_DATARAM 1 /* number of core data RAMs */
+#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/
+#define XCHAL_NUM_XLMI 1 /* number of core XLMI ports */
+
+/* Data RAM 0: */
+#define XCHAL_DATARAM0_VADDR 0x3FFF0000
+#define XCHAL_DATARAM0_PADDR 0x3FFF0000
+#define XCHAL_DATARAM0_SIZE 65536
+#define XCHAL_DATARAM0_ECC_PARITY 0
+
+/* XLMI Port 0: */
+#define XCHAL_XLMI0_VADDR 0x37F80000
+#define XCHAL_XLMI0_PADDR 0x37F80000
+#define XCHAL_XLMI0_SIZE 262144
+#define XCHAL_XLMI0_ECC_PARITY 0
+
+
+/*----------------------------------------------------------------------
+ INTERRUPTS and TIMERS
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */
+#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */
+#define XCHAL_HAVE_NMI 1 /* non-maskable interrupt */
+#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */
+#define XCHAL_NUM_TIMERS 3 /* number of CCOMPAREn regs */
+#define XCHAL_NUM_INTERRUPTS 27 /* number of interrupts */
+#define XCHAL_NUM_INTERRUPTS_LOG2 5 /* ceil(log2(NUM_INTERRUPTS)) */
+#define XCHAL_NUM_EXTINTERRUPTS 20 /* num of external interrupts */
+#define XCHAL_NUM_INTLEVELS 4 /* number of interrupt levels
+ (not including level zero) */
+#define XCHAL_EXCM_LEVEL 1 /* level masked by PS.EXCM */
+ /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */
+
+/* Masks of interrupts at each interrupt level: */
+#define XCHAL_INTLEVEL1_MASK 0x01F07FFF
+#define XCHAL_INTLEVEL2_MASK 0x02018000
+#define XCHAL_INTLEVEL3_MASK 0x04060000
+#define XCHAL_INTLEVEL4_MASK 0x00000000
+#define XCHAL_INTLEVEL5_MASK 0x00080000
+#define XCHAL_INTLEVEL6_MASK 0x00000000
+#define XCHAL_INTLEVEL7_MASK 0x00000000
+
+/* Masks of interrupts at each range 1..n of interrupt levels: */
+#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x01F07FFF
+#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x03F1FFFF
+#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x07F7FFFF
+#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x07F7FFFF
+#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x07FFFFFF
+#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x07FFFFFF
+#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x07FFFFFF
+
+/* Level of each interrupt: */
+#define XCHAL_INT0_LEVEL 1
+#define XCHAL_INT1_LEVEL 1
+#define XCHAL_INT2_LEVEL 1
+#define XCHAL_INT3_LEVEL 1
+#define XCHAL_INT4_LEVEL 1
+#define XCHAL_INT5_LEVEL 1
+#define XCHAL_INT6_LEVEL 1
+#define XCHAL_INT7_LEVEL 1
+#define XCHAL_INT8_LEVEL 1
+#define XCHAL_INT9_LEVEL 1
+#define XCHAL_INT10_LEVEL 1
+#define XCHAL_INT11_LEVEL 1
+#define XCHAL_INT12_LEVEL 1
+#define XCHAL_INT13_LEVEL 1
+#define XCHAL_INT14_LEVEL 1
+#define XCHAL_INT15_LEVEL 2
+#define XCHAL_INT16_LEVEL 2
+#define XCHAL_INT17_LEVEL 3
+#define XCHAL_INT18_LEVEL 3
+#define XCHAL_INT19_LEVEL 5
+#define XCHAL_INT20_LEVEL 1
+#define XCHAL_INT21_LEVEL 1
+#define XCHAL_INT22_LEVEL 1
+#define XCHAL_INT23_LEVEL 1
+#define XCHAL_INT24_LEVEL 1
+#define XCHAL_INT25_LEVEL 2
+#define XCHAL_INT26_LEVEL 3
+#define XCHAL_DEBUGLEVEL 4 /* debug interrupt level */
+#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */
+#define XCHAL_NMILEVEL 5 /* NMI "level" (for use with
+ EXCSAVE/EPS/EPC_n, RFI n) */
+
+/* Type of each interrupt: */
+#define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT6_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT7_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT10_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT11_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT12_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT13_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT14_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT15_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT16_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT17_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT18_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT19_TYPE XTHAL_INTTYPE_NMI
+#define XCHAL_INT20_TYPE XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT21_TYPE XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT22_TYPE XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT23_TYPE XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT24_TYPE XTHAL_INTTYPE_TIMER
+#define XCHAL_INT25_TYPE XTHAL_INTTYPE_TIMER
+#define XCHAL_INT26_TYPE XTHAL_INTTYPE_TIMER
+
+/* Masks of interrupts for each type of interrupt: */
+#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xF8000000
+#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00F00000
+#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x00000000
+#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0007FFFF
+#define XCHAL_INTTYPE_MASK_TIMER 0x07000000
+#define XCHAL_INTTYPE_MASK_NMI 0x00080000
+#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000
+
+/* Interrupt numbers assigned to specific interrupt sources: */
+#define XCHAL_TIMER0_INTERRUPT 24 /* CCOMPARE0 */
+#define XCHAL_TIMER1_INTERRUPT 25 /* CCOMPARE1 */
+#define XCHAL_TIMER2_INTERRUPT 26 /* CCOMPARE2 */
+#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED
+#define XCHAL_NMI_INTERRUPT 19 /* non-maskable interrupt */
+
+/* Interrupt numbers for levels at which only one interrupt is configured: */
+#define XCHAL_INTLEVEL5_NUM 19
+/* (There are many interrupts each at level(s) 1, 2, 3.) */
+
+
+/*
+ * External interrupt vectors/levels.
+ * These macros describe how Xtensa processor interrupt numbers
+ * (as numbered internally, eg. in INTERRUPT and INTENABLE registers)
+ * map to external BInterrupt<n> pins, for those interrupts
+ * configured as external (level-triggered, edge-triggered, or NMI).
+ * See the Xtensa processor databook for more details.
+ */
+
+/* Core interrupt numbers mapped to each EXTERNAL interrupt number: */
+#define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */
+#define XCHAL_EXTINT1_NUM 1 /* (intlevel 1) */
+#define XCHAL_EXTINT2_NUM 2 /* (intlevel 1) */
+#define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */
+#define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */
+#define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */
+#define XCHAL_EXTINT6_NUM 6 /* (intlevel 1) */
+#define XCHAL_EXTINT7_NUM 7 /* (intlevel 1) */
+#define XCHAL_EXTINT8_NUM 8 /* (intlevel 1) */
+#define XCHAL_EXTINT9_NUM 9 /* (intlevel 1) */
+#define XCHAL_EXTINT10_NUM 10 /* (intlevel 1) */
+#define XCHAL_EXTINT11_NUM 11 /* (intlevel 1) */
+#define XCHAL_EXTINT12_NUM 12 /* (intlevel 1) */
+#define XCHAL_EXTINT13_NUM 13 /* (intlevel 1) */
+#define XCHAL_EXTINT14_NUM 14 /* (intlevel 1) */
+#define XCHAL_EXTINT15_NUM 15 /* (intlevel 2) */
+#define XCHAL_EXTINT16_NUM 16 /* (intlevel 2) */
+#define XCHAL_EXTINT17_NUM 17 /* (intlevel 3) */
+#define XCHAL_EXTINT18_NUM 18 /* (intlevel 3) */
+#define XCHAL_EXTINT19_NUM 19 /* (intlevel 5) */
+
+
+/*----------------------------------------------------------------------
+ EXCEPTIONS and VECTORS
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture
+ number: 1 == XEA1 (old)
+ 2 == XEA2 (new)
+ 0 == XEAX (extern) */
+#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */
+#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */
+#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */
+#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */
+#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */
+#define XCHAL_HAVE_VECTOR_SELECT 0 /* relocatable vectors */
+#define XCHAL_HAVE_VECBASE 0 /* relocatable vectors */
+
+#define XCHAL_RESET_VECOFS 0x00000000
+#define XCHAL_RESET_VECTOR_VADDR 0x3FFE03D0
+#define XCHAL_RESET_VECTOR_PADDR 0x3FFE03D0
+#define XCHAL_USER_VECOFS 0x00000000
+#define XCHAL_USER_VECTOR_VADDR 0x40000220
+#define XCHAL_USER_VECTOR_PADDR 0x40000220
+#define XCHAL_KERNEL_VECOFS 0x00000000
+#define XCHAL_KERNEL_VECTOR_VADDR 0x40000200
+#define XCHAL_KERNEL_VECTOR_PADDR 0x40000200
+#define XCHAL_DOUBLEEXC_VECOFS 0x00000000
+#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0x400002A0
+#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x400002A0
+#define XCHAL_WINDOW_OF4_VECOFS 0x00000000
+#define XCHAL_WINDOW_UF4_VECOFS 0x00000040
+#define XCHAL_WINDOW_OF8_VECOFS 0x00000080
+#define XCHAL_WINDOW_UF8_VECOFS 0x000000C0
+#define XCHAL_WINDOW_OF12_VECOFS 0x00000100
+#define XCHAL_WINDOW_UF12_VECOFS 0x00000140
+#define XCHAL_WINDOW_VECTORS_VADDR 0x40000000
+#define XCHAL_WINDOW_VECTORS_PADDR 0x40000000
+#define XCHAL_INTLEVEL2_VECOFS 0x00000000
+#define XCHAL_INTLEVEL2_VECTOR_VADDR 0x40000240
+#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x40000240
+#define XCHAL_INTLEVEL3_VECOFS 0x00000000
+#define XCHAL_INTLEVEL3_VECTOR_VADDR 0x40000260
+#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x40000260
+#define XCHAL_INTLEVEL4_VECOFS 0x00000000
+#define XCHAL_INTLEVEL4_VECTOR_VADDR 0x40000390
+#define XCHAL_INTLEVEL4_VECTOR_PADDR 0x40000390
+#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL4_VECOFS
+#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL4_VECTOR_VADDR
+#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL4_VECTOR_PADDR
+#define XCHAL_NMI_VECOFS 0x00000000
+#define XCHAL_NMI_VECTOR_VADDR 0x400003B0
+#define XCHAL_NMI_VECTOR_PADDR 0x400003B0
+#define XCHAL_INTLEVEL5_VECOFS XCHAL_NMI_VECOFS
+#define XCHAL_INTLEVEL5_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR
+#define XCHAL_INTLEVEL5_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR
+
+
+/*----------------------------------------------------------------------
+ DEBUG
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */
+#define XCHAL_NUM_IBREAK 2 /* number of IBREAKn regs */
+#define XCHAL_NUM_DBREAK 2 /* number of DBREAKn regs */
+#define XCHAL_HAVE_OCD_DIR_ARRAY 1 /* faster OCD option */
+
+
+/*----------------------------------------------------------------------
+ MMU
+ ----------------------------------------------------------------------*/
+
+/* See core-matmap.h header file for more details. */
+
+#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */
+#define XCHAL_HAVE_SPANNING_WAY 1 /* one way maps I+D 4GB vaddr */
+#define XCHAL_HAVE_IDENTITY_MAP 1 /* vaddr == paddr always */
+#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */
+#define XCHAL_HAVE_MIMIC_CACHEATTR 1 /* region protection */
+#define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */
+#define XCHAL_HAVE_PTP_MMU 0 /* full MMU (with page table
+ [autorefill] and protection)
+ usable for an MMU-based OS */
+/* If none of the above last 4 are set, it's a custom TLB configuration. */
+
+#define XCHAL_MMU_ASID_BITS 0 /* number of bits in ASIDs */
+#define XCHAL_MMU_RINGS 1 /* number of rings (1..4) */
+#define XCHAL_MMU_RING_BITS 0 /* num of bits in RING field */
+
+#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
+
+
+#endif /* _XTENSA_CORE_CONFIGURATION_H */
+
diff --git a/arch/xtensa/variants/s6000/include/variant/hardware.h b/arch/xtensa/variants/s6000/include/variant/hardware.h
new file mode 100644
index 00000000000..5d9ba098d84
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/hardware.h
@@ -0,0 +1,259 @@
+#ifndef __XTENSA_S6000_HARDWARE_H
+#define __XTENSA_S6000_HARDWARE_H
+
+#define S6_SCLK 1843200
+
+#define S6_MEM_REG 0x20000000
+#define S6_MEM_EFI 0x33F00000
+#define S6_MEM_PCIE_DATARAM1 0x34000000
+#define S6_MEM_XLMI 0x37F80000
+#define S6_MEM_PIF_DATARAM1 0x37FFC000
+#define S6_MEM_GMAC 0x38000000
+#define S6_MEM_I2S 0x3A000000
+#define S6_MEM_EGIB 0x3C000000
+#define S6_MEM_PCIE_CFG 0x3E000000
+#define S6_MEM_PIF_DATARAM 0x3FFE0000
+#define S6_MEM_XLMI_DATARAM 0x3FFF0000
+#define S6_MEM_DDR 0x40000000
+#define S6_MEM_PCIE_APER 0xC0000000
+#define S6_MEM_AUX 0xF0000000
+
+/* Device addresses */
+
+#define S6_REG_SCB S6_MEM_REG
+#define S6_REG_NB (S6_REG_SCB + 0x10000)
+#define S6_REG_LMSDMA (S6_REG_SCB + 0x20000)
+#define S6_REG_NI (S6_REG_SCB + 0x30000)
+#define S6_REG_NIDMA (S6_REG_SCB + 0x40000)
+#define S6_REG_NS (S6_REG_SCB + 0x50000)
+#define S6_REG_DDR (S6_REG_SCB + 0x60000)
+#define S6_REG_GREG1 (S6_REG_SCB + 0x70000)
+#define S6_REG_DP (S6_REG_SCB + 0x80000)
+#define S6_REG_DPDMA (S6_REG_SCB + 0x90000)
+#define S6_REG_EGIB (S6_REG_SCB + 0xA0000)
+#define S6_REG_PCIE (S6_REG_SCB + 0xB0000)
+#define S6_REG_I2S (S6_REG_SCB + 0xC0000)
+#define S6_REG_GMAC (S6_REG_SCB + 0xD0000)
+#define S6_REG_HIFDMA (S6_REG_SCB + 0xE0000)
+#define S6_REG_GREG2 (S6_REG_SCB + 0xF0000)
+
+#define S6_REG_APB S6_REG_SCB
+#define S6_REG_UART (S6_REG_APB + 0x0000)
+#define S6_REG_INTC (S6_REG_APB + 0x2000)
+#define S6_REG_SPI (S6_REG_APB + 0x3000)
+#define S6_REG_I2C (S6_REG_APB + 0x4000)
+#define S6_REG_GPIO (S6_REG_APB + 0x8000)
+
+/* Global register block */
+
+#define S6_GREG1_PLL_LOCKCLEAR 0x000
+#define S6_GREG1_PLL_LOCK_SYS 0
+#define S6_GREG1_PLL_LOCK_IO 1
+#define S6_GREG1_PLL_LOCK_AIM 2
+#define S6_GREG1_PLL_LOCK_DP0 3
+#define S6_GREG1_PLL_LOCK_DP2 4
+#define S6_GREG1_PLL_LOCK_DDR 5
+#define S6_GREG1_PLL_LOCKSTAT 0x004
+#define S6_GREG1_PLL_LOCKSTAT_CURLOCK 0
+#define S6_GREG1_PLL_LOCKSTAT_EVERUNLCK 8
+#define S6_GREG1_PLLSEL 0x010
+#define S6_GREG1_PLLSEL_AIM 0
+#define S6_GREG1_PLLSEL_AIM_DDR2 0
+#define S6_GREG1_PLLSEL_AIM_300MHZ 1
+#define S6_GREG1_PLLSEL_AIM_240MHZ 2
+#define S6_GREG1_PLLSEL_AIM_200MHZ 3
+#define S6_GREG1_PLLSEL_AIM_150MHZ 4
+#define S6_GREG1_PLLSEL_AIM_120MHZ 5
+#define S6_GREG1_PLLSEL_AIM_40MHZ 6
+#define S6_GREG1_PLLSEL_AIM_PLLAIMREF 7
+#define S6_GREG1_PLLSEL_AIM_MASK 7
+#define S6_GREG1_PLLSEL_DDR 8
+#define S6_GREG1_PLLSEL_DDR_HS 0
+#define S6_GREG1_PLLSEL_DDR_333MHZ 1
+#define S6_GREG1_PLLSEL_DDR_250MHZ 2
+#define S6_GREG1_PLLSEL_DDR_200MHZ 3
+#define S6_GREG1_PLLSEL_DDR_167MHZ 4
+#define S6_GREG1_PLLSEL_DDR_100MHZ 5
+#define S6_GREG1_PLLSEL_DDR_33MHZ 6
+#define S6_GREG1_PLLSEL_DDR_PLLIOREF 7
+#define S6_GREG1_PLLSEL_DDR_MASK 7
+#define S6_GREG1_PLLSEL_GMAC 16
+#define S6_GREG1_PLLSEL_GMAC_125MHZ 0
+#define S6_GREG1_PLLSEL_GMAC_25MHZ 1
+#define S6_GREG1_PLLSEL_GMAC_2500KHZ 2
+#define S6_GREG1_PLLSEL_GMAC_EXTERN 3
+#define S6_GREG1_PLLSEL_GMAC_MASK 3
+#define S6_GREG1_PLLSEL_GMII 18
+#define S6_GREG1_PLLSEL_GMII_111MHZ 0
+#define S6_GREG1_PLLSEL_GMII_IOREF 1
+#define S6_GREG1_PLLSEL_GMII_NONE 2
+#define S6_GREG1_PLLSEL_GMII_125MHZ 3
+#define S6_GREG1_PLLSEL_GMII_MASK 3
+#define S6_GREG1_SYSUNLOCKCNT 0x020
+#define S6_GREG1_IOUNLOCKCNT 0x024
+#define S6_GREG1_AIMUNLOCKCNT 0x028
+#define S6_GREG1_DP0UNLOCKCNT 0x02C
+#define S6_GREG1_DP2UNLOCKCNT 0x030
+#define S6_GREG1_DDRUNLOCKCNT 0x034
+#define S6_GREG1_CLKBAL0 0x040
+#define S6_GREG1_CLKBAL0_LSGB 0
+#define S6_GREG1_CLKBAL0_LSPX 8
+#define S6_GREG1_CLKBAL0_MEMDO 16
+#define S6_GREG1_CLKBAL0_HSXT1 24
+#define S6_GREG1_CLKBAL1 0x044
+#define S6_GREG1_CLKBAL1_HSISEF 0
+#define S6_GREG1_CLKBAL1_HSNI 8
+#define S6_GREG1_CLKBAL1_HSNS 16
+#define S6_GREG1_CLKBAL1_HSISEFCFG 24
+#define S6_GREG1_CLKBAL2 0x048
+#define S6_GREG1_CLKBAL2_LSNB 0
+#define S6_GREG1_CLKBAL2_LSSB 8
+#define S6_GREG1_CLKBAL2_LSREST 24
+#define S6_GREG1_CLKBAL3 0x04C
+#define S6_GREG1_CLKBAL3_ISEFXAD 0
+#define S6_GREG1_CLKBAL3_ISEFLMS 8
+#define S6_GREG1_CLKBAL3_ISEFISEF 16
+#define S6_GREG1_CLKBAL3_DDRDD 24
+#define S6_GREG1_CLKBAL4 0x050
+#define S6_GREG1_CLKBAL4_DDRDP 0
+#define S6_GREG1_CLKBAL4_DDRDO 8
+#define S6_GREG1_CLKBAL4_DDRNB 16
+#define S6_GREG1_CLKBAL4_DDRLMS 24
+#define S6_GREG1_BLOCKENA 0x100
+#define S6_GREG1_BLOCK_DDR 0
+#define S6_GREG1_BLOCK_DP 1
+#define S6_GREG1_BLOCK_NSNI 2
+#define S6_GREG1_BLOCK_PCIE 3
+#define S6_GREG1_BLOCK_GMAC 4
+#define S6_GREG1_BLOCK_I2S 5
+#define S6_GREG1_BLOCK_EGIB 6
+#define S6_GREG1_BLOCK_SB 7
+#define S6_GREG1_BLOCK_XT1 8
+#define S6_GREG1_CLKGATE 0x104
+#define S6_GREG1_BGATE_AIMNORTH 9
+#define S6_GREG1_BGATE_AIMEAST 10
+#define S6_GREG1_BGATE_AIMWEST 11
+#define S6_GREG1_BGATE_AIMSOUTH 12
+#define S6_GREG1_CHIPRES 0x108
+#define S6_GREG1_CHIPRES_SOFTRES 0
+#define S6_GREG1_CHIPRES_LOSTLOCK 1
+#define S6_GREG1_RESETCAUSE 0x10C
+#define S6_GREG1_RESETCAUSE_RESETN 0
+#define S6_GREG1_RESETCAUSE_GLOBAL 1
+#define S6_GREG1_RESETCAUSE_WDOGTIMER 2
+#define S6_GREG1_RESETCAUSE_SWCHIP 3
+#define S6_GREG1_RESETCAUSE_PLLSYSLOSS 4
+#define S6_GREG1_RESETCAUSE_PCIE 5
+#define S6_GREG1_RESETCAUSE_CREATEDGLOB 6
+#define S6_GREG1_REFCLOCKCNT 0x110
+#define S6_GREG1_RESETTIMER 0x114
+#define S6_GREG1_NMITIMER 0x118
+#define S6_GREG1_GLOBAL_TIMER 0x11C
+#define S6_GREG1_TIMER0 0x180
+#define S6_GREG1_TIMER1 0x184
+#define S6_GREG1_UARTCLOCKSEL 0x204
+#define S6_GREG1_CHIPVERSPACKG 0x208
+#define S6_GREG1_CHIPVERSPACKG_CHIPVID 0
+#define S6_GREG1_CHIPVERSPACKG_PACKSEL 8
+#define S6_GREG1_ONDIETERMCTRL 0x20C
+#define S6_GREG1_ONDIETERMCTRL_WEST 0
+#define S6_GREG1_ONDIETERMCTRL_NORTH 2
+#define S6_GREG1_ONDIETERMCTRL_EAST 4
+#define S6_GREG1_ONDIETERMCTRL_SOUTH 6
+#define S6_GREG1_ONDIETERMCTRL_NONE 0
+#define S6_GREG1_ONDIETERMCTRL_75OHM 2
+#define S6_GREG1_ONDIETERMCTRL_MASK 3
+#define S6_GREG1_BOOT_CFG0 0x210
+#define S6_GREG1_BOOT_CFG0_AIMSTRONG 1
+#define S6_GREG1_BOOT_CFG0_MINIBOOTDL 2
+#define S6_GREG1_BOOT_CFG0_OCDGPIO8SET 5
+#define S6_GREG1_BOOT_CFG0_OCDGPIOENA 6
+#define S6_GREG1_BOOT_CFG0_DOWNSTREAM 7
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV 8
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_300MHZ 1
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_240MHZ 2
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_200MHZ 3
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_150MHZ 4
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_120MHZ 5
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_40MHZ 6
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_MASK 7
+#define S6_GREG1_BOOT_CFG0_BALHSLMS 12
+#define S6_GREG1_BOOT_CFG0_BALHSNB 18
+#define S6_GREG1_BOOT_CFG0_BALHSXAD 24
+#define S6_GREG1_BOOT_CFG1 0x214
+#define S6_GREG1_BOOT_CFG1_PCIE1LANE 1
+#define S6_GREG1_BOOT_CFG1_MPLLPRESCALE 2
+#define S6_GREG1_BOOT_CFG1_MPLLNCY 4
+#define S6_GREG1_BOOT_CFG1_MPLLNCY5 9
+#define S6_GREG1_BOOT_CFG1_BALHSREST 14
+#define S6_GREG1_BOOT_CFG1_BALHSPSMEMS 20
+#define S6_GREG1_BOOT_CFG1_BALLSGI 26
+#define S6_GREG1_BOOT_CFG2 0x218
+#define S6_GREG1_BOOT_CFG2_PEID 0
+#define S6_GREG1_BOOT_CFG3 0x21C
+#define S6_GREG1_DRAMBUSYHOLDOF 0x220
+#define S6_GREG1_DRAMBUSYHOLDOF_XT0 0
+#define S6_GREG1_DRAMBUSYHOLDOF_XT1 4
+#define S6_GREG1_DRAMBUSYHOLDOF_XT_MASK 7
+#define S6_GREG1_PCIEBAR1SIZE 0x224
+#define S6_GREG1_PCIEBAR2SIZE 0x228
+#define S6_GREG1_PCIEVENDOR 0x22C
+#define S6_GREG1_PCIEDEVICE 0x230
+#define S6_GREG1_PCIEREV 0x234
+#define S6_GREG1_PCIECLASS 0x238
+#define S6_GREG1_XT1DCACHEMISS 0x240
+#define S6_GREG1_XT1ICACHEMISS 0x244
+#define S6_GREG1_HWSEMAPHORE(n) (0x400 + 4 * (n))
+#define S6_GREG1_HWSEMAPHORE_NB 16
+
+/* peripheral interrupt numbers */
+
+#define S6_INTC_GPIO(n) (n) /* 0..3 */
+#define S6_INTC_I2C 4
+#define S6_INTC_SPI 5
+#define S6_INTC_NB_ERR 6
+#define S6_INTC_DMA_LMSERR 7
+#define S6_INTC_DMA_LMSLOWWMRK(n) (8 + (n)) /* 0..11 */
+#define S6_INTC_DMA_LMSPENDCNT(n) (20 + (n)) /* 0..11 */
+#define S6_INTC_DMA HOSTLOWWMRK(n) (32 + (n)) /* 0..6 */
+#define S6_INTC_DMA_HOSTPENDCNT(n) (39 + (n)) /* 0..6 */
+#define S6_INTC_DMA_HOSTERR 46
+#define S6_INTC_UART(n) (47 + (n)) /* 0..1 */
+#define S6_INTC_XAD 49
+#define S6_INTC_NI_ERR 50
+#define S6_INTC_NI_INFIFOFULL 51
+#define S6_INTC_DMA_NIERR 52
+#define S6_INTC_DMA_NILOWWMRK(n) (53 + (n)) /* 0..3 */
+#define S6_INTC_DMA_NIPENDCNT(n) (57 + (n)) /* 0..3 */
+#define S6_INTC_DDR 61
+#define S6_INTC_NS_ERR 62
+#define S6_INTC_EFI_CFGERR 63
+#define S6_INTC_EFI_ISEFTEST 64
+#define S6_INTC_EFI_WRITEERR 65
+#define S6_INTC_NMI_TIMER 66
+#define S6_INTC_PLLLOCK_SYS 67
+#define S6_INTC_PLLLOCK_IO 68
+#define S6_INTC_PLLLOCK_AIM 69
+#define S6_INTC_PLLLOCK_DP0 70
+#define S6_INTC_PLLLOCK_DP2 71
+#define S6_INTC_I2S_ERR 72
+#define S6_INTC_GMAC_STAT 73
+#define S6_INTC_GMAC_ERR 74
+#define S6_INTC_GIB_ERR 75
+#define S6_INTC_PCIE_ERR 76
+#define S6_INTC_PCIE_MSI(n) (77 + (n)) /* 0..3 */
+#define S6_INTC_PCIE_INTA 81
+#define S6_INTC_PCIE_INTB 82
+#define S6_INTC_PCIE_INTC 83
+#define S6_INTC_PCIE_INTD 84
+#define S6_INTC_SW(n) (85 + (n)) /* 0..9 */
+#define S6_INTC_SW_ENABLE(n) (85 + 256 + (n))
+#define S6_INTC_DMA_DP_ERR 95
+#define S6_INTC_DMA_DPLOWWMRK(n) (96 + (n)) /* 0..3 */
+#define S6_INTC_DMA_DPPENDCNT(n) (100 + (n)) /* 0..3 */
+#define S6_INTC_DMA_DPTERMCNT(n) (104 + (n)) /* 0..3 */
+#define S6_INTC_TIMER0 108
+#define S6_INTC_TIMER1 109
+#define S6_INTC_DMA_HOSTTERMCNT(n) (110 + (n)) /* 0..6 */
+
+#endif /* __XTENSA_S6000_HARDWARE_H */
diff --git a/arch/xtensa/variants/s6000/include/variant/irq.h b/arch/xtensa/variants/s6000/include/variant/irq.h
new file mode 100644
index 00000000000..fa031cb0acc
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/irq.h
@@ -0,0 +1,9 @@
+#ifndef __XTENSA_S6000_IRQ_H
+#define __XTENSA_S6000_IRQ_H
+
+#define NO_IRQ (-1)
+
+extern void variant_irq_enable(unsigned int irq);
+extern void variant_irq_disable(unsigned int irq);
+
+#endif /* __XTENSA_S6000_IRQ_H */
diff --git a/arch/xtensa/variants/s6000/include/variant/tie-asm.h b/arch/xtensa/variants/s6000/include/variant/tie-asm.h
new file mode 100644
index 00000000000..f02d0a3a2e2
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/tie-asm.h
@@ -0,0 +1,304 @@
+/*
+ * This header file contains assembly-language definitions (assembly
+ * macros, etc.) for this specific Xtensa processor's TIE extensions
+ * and options. It is customized to this Xtensa processor configuration.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999-2008 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_TIE_ASM_H
+#define _XTENSA_CORE_TIE_ASM_H
+
+/* Selection parameter values for save-area save/restore macros: */
+/* Option vs. TIE: */
+#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */
+#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */
+/* Whether used automatically by compiler: */
+#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */
+#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */
+/* ABI handling across function calls: */
+#define XTHAL_SAS_CALR 0x0010 /* caller-saved */
+#define XTHAL_SAS_CALE 0x0020 /* callee-saved */
+#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */
+/* Misc */
+#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */
+
+
+
+/* Macro to save all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Save area ptr (clobbered): ptr (16 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed)
+ */
+ .macro xchal_ncp_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+ xchal_sa_align \ptr, 0, 1024-4, 4, 4
+ rsr \at1, BR // boolean option
+ s32i \at1, \ptr, .Lxchal_ofs_ + 0
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 4
+ .endif
+ .endm // xchal_ncp_store
+
+/* Macro to save all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Save area ptr (clobbered): ptr (16 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed)
+ */
+ .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+ xchal_sa_align \ptr, 0, 1024-4, 4, 4
+ l32i \at1, \ptr, .Lxchal_ofs_ + 0
+ wsr \at1, BR // boolean option
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 4
+ .endif
+ .endm // xchal_ncp_load
+
+
+
+#define XCHAL_NCP_NUM_ATMPS 1
+
+
+
+/* Macro to save the state of TIE coprocessor FPU.
+ * Save area ptr (clobbered): ptr (16 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP0_NUM_ATMPS needed)
+ */
+#define xchal_cp_FPU_store xchal_cp0_store
+/* #define xchal_cp_FPU_store_a2 xchal_cp0_store a2 a3 a4 a5 a6 */
+ .macro xchal_cp0_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+ xchal_sa_align \ptr, 0, 0, 1, 16
+ rur232 \at1 // FCR
+ s32i \at1, \ptr, 0
+ rur233 \at1 // FSR
+ s32i \at1, \ptr, 4
+ SSI f0, \ptr, 8
+ SSI f1, \ptr, 12
+ SSI f2, \ptr, 16
+ SSI f3, \ptr, 20
+ SSI f4, \ptr, 24
+ SSI f5, \ptr, 28
+ SSI f6, \ptr, 32
+ SSI f7, \ptr, 36
+ SSI f8, \ptr, 40
+ SSI f9, \ptr, 44
+ SSI f10, \ptr, 48
+ SSI f11, \ptr, 52
+ SSI f12, \ptr, 56
+ SSI f13, \ptr, 60
+ SSI f14, \ptr, 64
+ SSI f15, \ptr, 68
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 72
+ .endif
+ .endm // xchal_cp0_store
+
+/* Macro to restore the state of TIE coprocessor FPU.
+ * Save area ptr (clobbered): ptr (16 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP0_NUM_ATMPS needed)
+ */
+#define xchal_cp_FPU_load xchal_cp0_load
+/* #define xchal_cp_FPU_load_a2 xchal_cp0_load a2 a3 a4 a5 a6 */
+ .macro xchal_cp0_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+ xchal_sa_align \ptr, 0, 0, 1, 16
+ l32i \at1, \ptr, 0
+ wur232 \at1 // FCR
+ l32i \at1, \ptr, 4
+ wur233 \at1 // FSR
+ LSI f0, \ptr, 8
+ LSI f1, \ptr, 12
+ LSI f2, \ptr, 16
+ LSI f3, \ptr, 20
+ LSI f4, \ptr, 24
+ LSI f5, \ptr, 28
+ LSI f6, \ptr, 32
+ LSI f7, \ptr, 36
+ LSI f8, \ptr, 40
+ LSI f9, \ptr, 44
+ LSI f10, \ptr, 48
+ LSI f11, \ptr, 52
+ LSI f12, \ptr, 56
+ LSI f13, \ptr, 60
+ LSI f14, \ptr, 64
+ LSI f15, \ptr, 68
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 72
+ .endif
+ .endm // xchal_cp0_load
+
+#define XCHAL_CP0_NUM_ATMPS 1
+
+/* Macro to save the state of TIE coprocessor XAD.
+ * Save area ptr (clobbered): ptr (16 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP6_NUM_ATMPS needed)
+ */
+#define xchal_cp_XAD_store xchal_cp6_store
+/* #define xchal_cp_XAD_store_a2 xchal_cp6_store a2 a3 a4 a5 a6 */
+ .macro xchal_cp6_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+ xchal_sa_align \ptr, 0, 0, 1, 16
+ rur0 \at1 // LDCBHI
+ s32i \at1, \ptr, 0
+ rur1 \at1 // LDCBLO
+ s32i \at1, \ptr, 4
+ rur2 \at1 // STCBHI
+ s32i \at1, \ptr, 8
+ rur3 \at1 // STCBLO
+ s32i \at1, \ptr, 12
+ rur8 \at1 // LDBRBASE
+ s32i \at1, \ptr, 16
+ rur9 \at1 // LDBROFF
+ s32i \at1, \ptr, 20
+ rur10 \at1 // LDBRINC
+ s32i \at1, \ptr, 24
+ rur11 \at1 // STBRBASE
+ s32i \at1, \ptr, 28
+ rur12 \at1 // STBROFF
+ s32i \at1, \ptr, 32
+ rur13 \at1 // STBRINC
+ s32i \at1, \ptr, 36
+ rur24 \at1 // SCRATCH0
+ s32i \at1, \ptr, 40
+ rur25 \at1 // SCRATCH1
+ s32i \at1, \ptr, 44
+ rur26 \at1 // SCRATCH2
+ s32i \at1, \ptr, 48
+ rur27 \at1 // SCRATCH3
+ s32i \at1, \ptr, 52
+ WRAS128I wra0, \ptr, 64
+ WRAS128I wra1, \ptr, 80
+ WRAS128I wra2, \ptr, 96
+ WRAS128I wra3, \ptr, 112
+ WRAS128I wra4, \ptr, 128
+ WRAS128I wra5, \ptr, 144
+ WRAS128I wra6, \ptr, 160
+ WRAS128I wra7, \ptr, 176
+ WRAS128I wra8, \ptr, 192
+ WRAS128I wra9, \ptr, 208
+ WRAS128I wra10, \ptr, 224
+ WRAS128I wra11, \ptr, 240
+ WRAS128I wra12, \ptr, 256
+ WRAS128I wra13, \ptr, 272
+ WRAS128I wra14, \ptr, 288
+ WRAS128I wra15, \ptr, 304
+ WRBS128I wrb0, \ptr, 320
+ WRBS128I wrb1, \ptr, 336
+ WRBS128I wrb2, \ptr, 352
+ WRBS128I wrb3, \ptr, 368
+ WRBS128I wrb4, \ptr, 384
+ WRBS128I wrb5, \ptr, 400
+ WRBS128I wrb6, \ptr, 416
+ WRBS128I wrb7, \ptr, 432
+ WRBS128I wrb8, \ptr, 448
+ WRBS128I wrb9, \ptr, 464
+ WRBS128I wrb10, \ptr, 480
+ WRBS128I wrb11, \ptr, 496
+ WRBS128I wrb12, \ptr, 512
+ WRBS128I wrb13, \ptr, 528
+ WRBS128I wrb14, \ptr, 544
+ WRBS128I wrb15, \ptr, 560
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 576
+ .endif
+ .endm // xchal_cp6_store
+
+/* Macro to restore the state of TIE coprocessor XAD.
+ * Save area ptr (clobbered): ptr (16 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP6_NUM_ATMPS needed)
+ */
+#define xchal_cp_XAD_load xchal_cp6_load
+/* #define xchal_cp_XAD_load_a2 xchal_cp6_load a2 a3 a4 a5 a6 */
+ .macro xchal_cp6_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+ xchal_sa_align \ptr, 0, 0, 1, 16
+ l32i \at1, \ptr, 0
+ wur0 \at1 // LDCBHI
+ l32i \at1, \ptr, 4
+ wur1 \at1 // LDCBLO
+ l32i \at1, \ptr, 8
+ wur2 \at1 // STCBHI
+ l32i \at1, \ptr, 12
+ wur3 \at1 // STCBLO
+ l32i \at1, \ptr, 16
+ wur8 \at1 // LDBRBASE
+ l32i \at1, \ptr, 20
+ wur9 \at1 // LDBROFF
+ l32i \at1, \ptr, 24
+ wur10 \at1 // LDBRINC
+ l32i \at1, \ptr, 28
+ wur11 \at1 // STBRBASE
+ l32i \at1, \ptr, 32
+ wur12 \at1 // STBROFF
+ l32i \at1, \ptr, 36
+ wur13 \at1 // STBRINC
+ l32i \at1, \ptr, 40
+ wur24 \at1 // SCRATCH0
+ l32i \at1, \ptr, 44
+ wur25 \at1 // SCRATCH1
+ l32i \at1, \ptr, 48
+ wur26 \at1 // SCRATCH2
+ l32i \at1, \ptr, 52
+ wur27 \at1 // SCRATCH3
+ WRBL128I wrb0, \ptr, 320
+ WRBL128I wrb1, \ptr, 336
+ WRBL128I wrb2, \ptr, 352
+ WRBL128I wrb3, \ptr, 368
+ WRBL128I wrb4, \ptr, 384
+ WRBL128I wrb5, \ptr, 400
+ WRBL128I wrb6, \ptr, 416
+ WRBL128I wrb7, \ptr, 432
+ WRBL128I wrb8, \ptr, 448
+ WRBL128I wrb9, \ptr, 464
+ WRBL128I wrb10, \ptr, 480
+ WRBL128I wrb11, \ptr, 496
+ WRBL128I wrb12, \ptr, 512
+ WRBL128I wrb13, \ptr, 528
+ WRBL128I wrb14, \ptr, 544
+ WRBL128I wrb15, \ptr, 560
+ WRAL128I wra0, \ptr, 64
+ WRAL128I wra1, \ptr, 80
+ WRAL128I wra2, \ptr, 96
+ WRAL128I wra3, \ptr, 112
+ WRAL128I wra4, \ptr, 128
+ WRAL128I wra5, \ptr, 144
+ WRAL128I wra6, \ptr, 160
+ WRAL128I wra7, \ptr, 176
+ WRAL128I wra8, \ptr, 192
+ WRAL128I wra9, \ptr, 208
+ WRAL128I wra10, \ptr, 224
+ WRAL128I wra11, \ptr, 240
+ WRAL128I wra12, \ptr, 256
+ WRAL128I wra13, \ptr, 272
+ WRAL128I wra14, \ptr, 288
+ WRAL128I wra15, \ptr, 304
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 576
+ .endif
+ .endm // xchal_cp6_load
+
+#define XCHAL_CP6_NUM_ATMPS 1
+#define XCHAL_SA_NUM_ATMPS 1
+
+ /* Empty macros for unconfigured coprocessors: */
+ .macro xchal_cp1_store p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp1_load p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp2_store p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp2_load p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp3_store p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp3_load p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp4_store p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp4_load p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp5_store p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp5_load p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp7_store p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp7_load p a b c d continue=0 ofs=-1 select=-1 ; .endm
+
+#endif /*_XTENSA_CORE_TIE_ASM_H*/
+
diff --git a/arch/xtensa/variants/s6000/include/variant/tie.h b/arch/xtensa/variants/s6000/include/variant/tie.h
new file mode 100644
index 00000000000..be7ea843d5d
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/tie.h
@@ -0,0 +1,191 @@
+/*
+ * This header file describes this specific Xtensa processor's TIE extensions
+ * that extend basic Xtensa core functionality. It is customized to this
+ * Xtensa processor configuration.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999-2008 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_TIE_H
+#define _XTENSA_CORE_TIE_H
+
+#define XCHAL_CP_NUM 2 /* number of coprocessors */
+#define XCHAL_CP_MAX 7 /* max CP ID + 1 (0 if none) */
+#define XCHAL_CP_MASK 0x41 /* bitmask of all CPs by ID */
+#define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */
+
+/* Basic parameters of each coprocessor: */
+#define XCHAL_CP0_NAME "FPU"
+#define XCHAL_CP0_IDENT FPU
+#define XCHAL_CP0_SA_SIZE 72 /* size of state save area */
+#define XCHAL_CP0_SA_ALIGN 4 /* min alignment of save area */
+#define XCHAL_CP_ID_FPU 0 /* coprocessor ID (0..7) */
+#define XCHAL_CP6_NAME "XAD"
+#define XCHAL_CP6_IDENT XAD
+#define XCHAL_CP6_SA_SIZE 576 /* size of state save area */
+#define XCHAL_CP6_SA_ALIGN 16 /* min alignment of save area */
+#define XCHAL_CP_ID_XAD 6 /* coprocessor ID (0..7) */
+
+/* Filler info for unassigned coprocessors, to simplify arrays etc: */
+#define XCHAL_CP1_SA_SIZE 0
+#define XCHAL_CP1_SA_ALIGN 1
+#define XCHAL_CP2_SA_SIZE 0
+#define XCHAL_CP2_SA_ALIGN 1
+#define XCHAL_CP3_SA_SIZE 0
+#define XCHAL_CP3_SA_ALIGN 1
+#define XCHAL_CP4_SA_SIZE 0
+#define XCHAL_CP4_SA_ALIGN 1
+#define XCHAL_CP5_SA_SIZE 0
+#define XCHAL_CP5_SA_ALIGN 1
+#define XCHAL_CP7_SA_SIZE 0
+#define XCHAL_CP7_SA_ALIGN 1
+
+/* Save area for non-coprocessor optional and custom (TIE) state: */
+#define XCHAL_NCP_SA_SIZE 4
+#define XCHAL_NCP_SA_ALIGN 4
+
+/* Total save area for optional and custom state (NCP + CPn): */
+#define XCHAL_TOTAL_SA_SIZE 672 /* with 16-byte align padding */
+#define XCHAL_TOTAL_SA_ALIGN 16 /* actual minimum alignment */
+
+/*
+ * Detailed contents of save areas.
+ * NOTE: caller must define the XCHAL_SA_REG macro (not defined here)
+ * before expanding the XCHAL_xxx_SA_LIST() macros.
+ *
+ * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize,
+ * dbnum,base,regnum,bitsz,gapsz,reset,x...)
+ *
+ * s = passed from XCHAL_*_LIST(s), eg. to select how to expand
+ * ccused = set if used by compiler without special options or code
+ * abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global)
+ * kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg)
+ * opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg)
+ * name = lowercase reg name (no quotes)
+ * galign = group byte alignment (power of 2) (galign >= align)
+ * align = register byte alignment (power of 2)
+ * asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz)
+ * (not including any pad bytes required to galign this or next reg)
+ * dbnum = unique target number f/debug (see <xtensa-libdb-macros.h>)
+ * base = reg shortname w/o index (or sr=special, ur=TIE user reg)
+ * regnum = reg index in regfile, or special/TIE-user reg number
+ * bitsz = number of significant bits (regfile width, or ur/sr mask bits)
+ * gapsz = intervening bits, if bitsz bits not stored contiguously
+ * (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize)
+ * reset = register reset value (or 0 if undefined at reset)
+ * x = reserved for future use (0 until then)
+ *
+ * To filter out certain registers, e.g. to expand only the non-global
+ * registers used by the compiler, you can do something like this:
+ *
+ * #define XCHAL_SA_REG(s,ccused,p...) SELCC##ccused(p)
+ * #define SELCC0(p...)
+ * #define SELCC1(abikind,p...) SELAK##abikind(p)
+ * #define SELAK0(p...) REG(p)
+ * #define SELAK1(p...) REG(p)
+ * #define SELAK2(p...)
+ * #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \
+ * ...what you want to expand...
+ */
+
+#define XCHAL_NCP_SA_NUM 1
+#define XCHAL_NCP_SA_LIST(s) \
+ XCHAL_SA_REG(s,0,0,0,1, br, 4, 4, 4,0x0204, sr,4 , 16,0,0,0)
+
+#define XCHAL_CP0_SA_NUM 18
+#define XCHAL_CP0_SA_LIST(s) \
+ XCHAL_SA_REG(s,0,0,1,0, fcr, 4, 4, 4,0x03E8, ur,232, 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, fsr, 4, 4, 4,0x03E9, ur,233, 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f0, 4, 4, 4,0x0030, f,0 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f1, 4, 4, 4,0x0031, f,1 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f2, 4, 4, 4,0x0032, f,2 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f3, 4, 4, 4,0x0033, f,3 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f4, 4, 4, 4,0x0034, f,4 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f5, 4, 4, 4,0x0035, f,5 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f6, 4, 4, 4,0x0036, f,6 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f7, 4, 4, 4,0x0037, f,7 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f8, 4, 4, 4,0x0038, f,8 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f9, 4, 4, 4,0x0039, f,9 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f10, 4, 4, 4,0x003A, f,10 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f11, 4, 4, 4,0x003B, f,11 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f12, 4, 4, 4,0x003C, f,12 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f13, 4, 4, 4,0x003D, f,13 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f14, 4, 4, 4,0x003E, f,14 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f15, 4, 4, 4,0x003F, f,15 , 32,0,0,0)
+
+#define XCHAL_CP1_SA_NUM 0
+#define XCHAL_CP1_SA_LIST(s) /* empty */
+
+#define XCHAL_CP2_SA_NUM 0
+#define XCHAL_CP2_SA_LIST(s) /* empty */
+
+#define XCHAL_CP3_SA_NUM 0
+#define XCHAL_CP3_SA_LIST(s) /* empty */
+
+#define XCHAL_CP4_SA_NUM 0
+#define XCHAL_CP4_SA_LIST(s) /* empty */
+
+#define XCHAL_CP5_SA_NUM 0
+#define XCHAL_CP5_SA_LIST(s) /* empty */
+
+#define XCHAL_CP6_SA_NUM 46
+#define XCHAL_CP6_SA_LIST(s) \
+ XCHAL_SA_REG(s,0,0,1,0, ldcbhi,16, 4, 4,0x0300, ur,0 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, ldcblo, 4, 4, 4,0x0301, ur,1 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, stcbhi, 4, 4, 4,0x0302, ur,2 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, stcblo, 4, 4, 4,0x0303, ur,3 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, ldbrbase, 4, 4, 4,0x0308, ur,8 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, ldbroff, 4, 4, 4,0x0309, ur,9 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, ldbrinc, 4, 4, 4,0x030A, ur,10 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, stbrbase, 4, 4, 4,0x030B, ur,11 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, stbroff, 4, 4, 4,0x030C, ur,12 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, stbrinc, 4, 4, 4,0x030D, ur,13 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, scratch0, 4, 4, 4,0x0318, ur,24 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, scratch1, 4, 4, 4,0x0319, ur,25 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, scratch2, 4, 4, 4,0x031A, ur,26 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, scratch3, 4, 4, 4,0x031B, ur,27 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra0,16,16,16,0x1010, wra,0 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra1,16,16,16,0x1011, wra,1 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra2,16,16,16,0x1012, wra,2 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra3,16,16,16,0x1013, wra,3 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra4,16,16,16,0x1014, wra,4 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra5,16,16,16,0x1015, wra,5 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra6,16,16,16,0x1016, wra,6 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra7,16,16,16,0x1017, wra,7 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra8,16,16,16,0x1018, wra,8 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra9,16,16,16,0x1019, wra,9 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra10,16,16,16,0x101A, wra,10 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra11,16,16,16,0x101B, wra,11 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra12,16,16,16,0x101C, wra,12 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra13,16,16,16,0x101D, wra,13 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra14,16,16,16,0x101E, wra,14 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra15,16,16,16,0x101F, wra,15 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb0,16,16,16,0x1020, wrb,0 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb1,16,16,16,0x1021, wrb,1 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb2,16,16,16,0x1022, wrb,2 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb3,16,16,16,0x1023, wrb,3 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb4,16,16,16,0x1024, wrb,4 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb5,16,16,16,0x1025, wrb,5 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb6,16,16,16,0x1026, wrb,6 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb7,16,16,16,0x1027, wrb,7 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb8,16,16,16,0x1028, wrb,8 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb9,16,16,16,0x1029, wrb,9 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb10,16,16,16,0x102A, wrb,10 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb11,16,16,16,0x102B, wrb,11 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb12,16,16,16,0x102C, wrb,12 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb13,16,16,16,0x102D, wrb,13 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb14,16,16,16,0x102E, wrb,14 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb15,16,16,16,0x102F, wrb,15 ,128,0,0,0)
+
+#define XCHAL_CP7_SA_NUM 0
+#define XCHAL_CP7_SA_LIST(s) /* empty */
+
+/* Byte length of instruction from its first nibble (op0 field), per FLIX. */
+#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8
+
+#endif /*_XTENSA_CORE_TIE_H*/
+
diff --git a/arch/xtensa/variants/s6000/irq.c b/arch/xtensa/variants/s6000/irq.c
new file mode 100644
index 00000000000..6651e3285fc
--- /dev/null
+++ b/arch/xtensa/variants/s6000/irq.c
@@ -0,0 +1,74 @@
+/*
+ * s6000 irq crossbar
+ *
+ * Copyright (c) 2009 emlix GmbH
+ * Authors: Johannes Weiner <jw@emlix.com>
+ * Oskar Schirmer <os@emlix.com>
+ */
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <variant/hardware.h>
+
+/* S6_REG_INTC */
+#define INTC_STATUS 0x000
+#define INTC_RAW 0x010
+#define INTC_STATUS_AG 0x100
+#define INTC_CFG(n) (0x200 + 4 * (n))
+
+/*
+ * The s6000 has a crossbar that multiplexes interrupt output lines
+ * from the peripherals to input lines on the xtensa core.
+ *
+ * We leave the mapping decisions to the platform as it depends on the
+ * actually connected peripherals which distribution makes sense.
+ */
+extern const signed char *platform_irq_mappings[NR_IRQS];
+
+static unsigned long scp_to_intc_enable[] = {
+#define TO_INTC_ENABLE(n) (((n) << 1) + 1)
+ TO_INTC_ENABLE(0),
+ TO_INTC_ENABLE(1),
+ TO_INTC_ENABLE(2),
+ TO_INTC_ENABLE(3),
+ TO_INTC_ENABLE(4),
+ TO_INTC_ENABLE(5),
+ TO_INTC_ENABLE(6),
+ TO_INTC_ENABLE(7),
+ TO_INTC_ENABLE(8),
+ TO_INTC_ENABLE(9),
+ TO_INTC_ENABLE(10),
+ TO_INTC_ENABLE(11),
+ TO_INTC_ENABLE(12),
+ -1,
+ -1,
+ TO_INTC_ENABLE(13),
+ -1,
+ TO_INTC_ENABLE(14),
+ -1,
+ TO_INTC_ENABLE(15),
+#undef TO_INTC_ENABLE
+};
+
+static void irq_set(unsigned int irq, int enable)
+{
+ unsigned long en;
+ const signed char *m = platform_irq_mappings[irq];
+
+ if (!m)
+ return;
+ en = enable ? scp_to_intc_enable[irq] : 0;
+ while (*m >= 0) {
+ writel(en, S6_REG_INTC + INTC_CFG(*m));
+ m++;
+ }
+}
+
+void variant_irq_enable(unsigned int irq)
+{
+ irq_set(irq, 1);
+}
+
+void variant_irq_disable(unsigned int irq)
+{
+ irq_set(irq, 0);
+}
diff --git a/block/Kconfig b/block/Kconfig
index 0cbb3b88b59..e7d12782bcf 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -44,22 +44,6 @@ config LBD
If unsure, say N.
-config BLK_DEV_IO_TRACE
- bool "Support for tracing block io actions"
- depends on SYSFS
- select RELAY
- select DEBUG_FS
- select TRACEPOINTS
- help
- Say Y here if you want to be able to trace the block layer actions
- on a given queue. Tracing allows you to see any traffic happening
- on a block device queue. For more information (and the userspace
- support tools needed), fetch the blktrace tools from:
-
- git://git.kernel.dk/blktrace.git
-
- If unsure, say N.
-
config BLK_DEV_BSG
bool "Block layer SG support v4 (EXPERIMENTAL)"
depends on EXPERIMENTAL
diff --git a/block/Makefile b/block/Makefile
index bfe73049f93..e9fa4dd690f 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -13,6 +13,5 @@ obj-$(CONFIG_IOSCHED_AS) += as-iosched.o
obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
-obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o
obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
obj-$(CONFIG_BLK_DEV_INTEGRITY) += blk-integrity.o
diff --git a/block/blk-core.c b/block/blk-core.c
index 996ed906d8c..07ab75403e1 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -64,12 +64,11 @@ static struct workqueue_struct *kblockd_workqueue;
static void drive_stat_acct(struct request *rq, int new_io)
{
- struct gendisk *disk = rq->rq_disk;
struct hd_struct *part;
int rw = rq_data_dir(rq);
int cpu;
- if (!blk_fs_request(rq) || !disk || !blk_do_io_stat(disk->queue))
+ if (!blk_fs_request(rq) || !blk_do_io_stat(rq))
return;
cpu = part_stat_lock();
@@ -132,6 +131,7 @@ void blk_rq_init(struct request_queue *q, struct request *rq)
INIT_HLIST_NODE(&rq->hash);
RB_CLEAR_NODE(&rq->rb_node);
rq->cmd = rq->__cmd;
+ rq->cmd_len = BLK_MAX_CDB;
rq->tag = -1;
rq->ref_count = 1;
}
@@ -484,11 +484,11 @@ static int blk_init_free_list(struct request_queue *q)
{
struct request_list *rl = &q->rq;
- rl->count[READ] = rl->count[WRITE] = 0;
- rl->starved[READ] = rl->starved[WRITE] = 0;
+ rl->count[BLK_RW_SYNC] = rl->count[BLK_RW_ASYNC] = 0;
+ rl->starved[BLK_RW_SYNC] = rl->starved[BLK_RW_ASYNC] = 0;
rl->elvpriv = 0;
- init_waitqueue_head(&rl->wait[READ]);
- init_waitqueue_head(&rl->wait[WRITE]);
+ init_waitqueue_head(&rl->wait[BLK_RW_SYNC]);
+ init_waitqueue_head(&rl->wait[BLK_RW_ASYNC]);
rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
mempool_free_slab, request_cachep, q->node);
@@ -699,18 +699,18 @@ static void ioc_set_batching(struct request_queue *q, struct io_context *ioc)
ioc->last_waited = jiffies;
}
-static void __freed_request(struct request_queue *q, int rw)
+static void __freed_request(struct request_queue *q, int sync)
{
struct request_list *rl = &q->rq;
- if (rl->count[rw] < queue_congestion_off_threshold(q))
- blk_clear_queue_congested(q, rw);
+ if (rl->count[sync] < queue_congestion_off_threshold(q))
+ blk_clear_queue_congested(q, sync);
- if (rl->count[rw] + 1 <= q->nr_requests) {
- if (waitqueue_active(&rl->wait[rw]))
- wake_up(&rl->wait[rw]);
+ if (rl->count[sync] + 1 <= q->nr_requests) {
+ if (waitqueue_active(&rl->wait[sync]))
+ wake_up(&rl->wait[sync]);
- blk_clear_queue_full(q, rw);
+ blk_clear_queue_full(q, sync);
}
}
@@ -718,18 +718,18 @@ static void __freed_request(struct request_queue *q, int rw)
* A request has just been released. Account for it, update the full and
* congestion status, wake up any waiters. Called under q->queue_lock.
*/
-static void freed_request(struct request_queue *q, int rw, int priv)
+static void freed_request(struct request_queue *q, int sync, int priv)
{
struct request_list *rl = &q->rq;
- rl->count[rw]--;
+ rl->count[sync]--;
if (priv)
rl->elvpriv--;
- __freed_request(q, rw);
+ __freed_request(q, sync);
- if (unlikely(rl->starved[rw ^ 1]))
- __freed_request(q, rw ^ 1);
+ if (unlikely(rl->starved[sync ^ 1]))
+ __freed_request(q, sync ^ 1);
}
/*
@@ -743,15 +743,15 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
struct request *rq = NULL;
struct request_list *rl = &q->rq;
struct io_context *ioc = NULL;
- const int rw = rw_flags & 0x01;
+ const bool is_sync = rw_is_sync(rw_flags) != 0;
int may_queue, priv;
may_queue = elv_may_queue(q, rw_flags);
if (may_queue == ELV_MQUEUE_NO)
goto rq_starved;
- if (rl->count[rw]+1 >= queue_congestion_on_threshold(q)) {
- if (rl->count[rw]+1 >= q->nr_requests) {
+ if (rl->count[is_sync]+1 >= queue_congestion_on_threshold(q)) {
+ if (rl->count[is_sync]+1 >= q->nr_requests) {
ioc = current_io_context(GFP_ATOMIC, q->node);
/*
* The queue will fill after this allocation, so set
@@ -759,9 +759,9 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
* This process will be allowed to complete a batch of
* requests, others will be blocked.
*/
- if (!blk_queue_full(q, rw)) {
+ if (!blk_queue_full(q, is_sync)) {
ioc_set_batching(q, ioc);
- blk_set_queue_full(q, rw);
+ blk_set_queue_full(q, is_sync);
} else {
if (may_queue != ELV_MQUEUE_MUST
&& !ioc_batching(q, ioc)) {
@@ -774,7 +774,7 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
}
}
}
- blk_set_queue_congested(q, rw);
+ blk_set_queue_congested(q, is_sync);
}
/*
@@ -782,11 +782,11 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
* limit of requests, otherwise we could have thousands of requests
* allocated with any setting of ->nr_requests
*/
- if (rl->count[rw] >= (3 * q->nr_requests / 2))
+ if (rl->count[is_sync] >= (3 * q->nr_requests / 2))
goto out;
- rl->count[rw]++;
- rl->starved[rw] = 0;
+ rl->count[is_sync]++;
+ rl->starved[is_sync] = 0;
priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
if (priv)
@@ -804,7 +804,7 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
* wait queue, but this is pretty rare.
*/
spin_lock_irq(q->queue_lock);
- freed_request(q, rw, priv);
+ freed_request(q, is_sync, priv);
/*
* in the very unlikely event that allocation failed and no
@@ -814,8 +814,8 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
* rq mempool into READ and WRITE
*/
rq_starved:
- if (unlikely(rl->count[rw] == 0))
- rl->starved[rw] = 1;
+ if (unlikely(rl->count[is_sync] == 0))
+ rl->starved[is_sync] = 1;
goto out;
}
@@ -829,7 +829,7 @@ rq_starved:
if (ioc_batching(q, ioc))
ioc->nr_batch_requests--;
- trace_block_getrq(q, bio, rw);
+ trace_block_getrq(q, bio, rw_flags & 1);
out:
return rq;
}
@@ -843,7 +843,7 @@ out:
static struct request *get_request_wait(struct request_queue *q, int rw_flags,
struct bio *bio)
{
- const int rw = rw_flags & 0x01;
+ const bool is_sync = rw_is_sync(rw_flags) != 0;
struct request *rq;
rq = get_request(q, rw_flags, bio, GFP_NOIO);
@@ -852,10 +852,10 @@ static struct request *get_request_wait(struct request_queue *q, int rw_flags,
struct io_context *ioc;
struct request_list *rl = &q->rq;
- prepare_to_wait_exclusive(&rl->wait[rw], &wait,
+ prepare_to_wait_exclusive(&rl->wait[is_sync], &wait,
TASK_UNINTERRUPTIBLE);
- trace_block_sleeprq(q, bio, rw);
+ trace_block_sleeprq(q, bio, rw_flags & 1);
__generic_unplug_device(q);
spin_unlock_irq(q->queue_lock);
@@ -871,7 +871,7 @@ static struct request *get_request_wait(struct request_queue *q, int rw_flags,
ioc_set_batching(q, ioc);
spin_lock_irq(q->queue_lock);
- finish_wait(&rl->wait[rw], &wait);
+ finish_wait(&rl->wait[is_sync], &wait);
rq = get_request(q, rw_flags, bio, GFP_NOIO);
};
@@ -1070,14 +1070,14 @@ void __blk_put_request(struct request_queue *q, struct request *req)
* it didn't come out of our reserved rq pools
*/
if (req->cmd_flags & REQ_ALLOCED) {
- int rw = rq_data_dir(req);
+ int is_sync = rq_is_sync(req) != 0;
int priv = req->cmd_flags & REQ_ELVPRIV;
BUG_ON(!list_empty(&req->queuelist));
BUG_ON(!hlist_unhashed(&req->hash));
blk_free_request(q, req);
- freed_request(q, rw, priv);
+ freed_request(q, is_sync, priv);
}
}
EXPORT_SYMBOL_GPL(__blk_put_request);
@@ -1124,10 +1124,10 @@ void init_request_from_bio(struct request *req, struct bio *bio)
if (bio_sync(bio))
req->cmd_flags |= REQ_RW_SYNC;
- if (bio_unplug(bio))
- req->cmd_flags |= REQ_UNPLUG;
if (bio_rw_meta(bio))
req->cmd_flags |= REQ_RW_META;
+ if (bio_noidle(bio))
+ req->cmd_flags |= REQ_NOIDLE;
req->errors = 0;
req->hard_sector = req->sector = bio->bi_sector;
@@ -1136,6 +1136,15 @@ void init_request_from_bio(struct request *req, struct bio *bio)
blk_rq_bio_prep(req->q, req, bio);
}
+/*
+ * Only disabling plugging for non-rotational devices if it does tagging
+ * as well, otherwise we do need the proper merging
+ */
+static inline bool queue_should_plug(struct request_queue *q)
+{
+ return !(blk_queue_nonrot(q) && blk_queue_tagged(q));
+}
+
static int __make_request(struct request_queue *q, struct bio *bio)
{
struct request *req;
@@ -1242,11 +1251,11 @@ get_rq:
if (test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags) ||
bio_flagged(bio, BIO_CPU_AFFINE))
req->cpu = blk_cpu_to_group(smp_processor_id());
- if (!blk_queue_nonrot(q) && elv_queue_empty(q))
+ if (queue_should_plug(q) && elv_queue_empty(q))
blk_plug_device(q);
add_request(q, req);
out:
- if (unplug || blk_queue_nonrot(q))
+ if (unplug || !queue_should_plug(q))
__generic_unplug_device(q);
spin_unlock_irq(q->queue_lock);
return 0;
@@ -1664,9 +1673,7 @@ EXPORT_SYMBOL(blkdev_dequeue_request);
static void blk_account_io_completion(struct request *req, unsigned int bytes)
{
- struct gendisk *disk = req->rq_disk;
-
- if (!disk || !blk_do_io_stat(disk->queue))
+ if (!blk_do_io_stat(req))
return;
if (blk_fs_request(req)) {
@@ -1683,9 +1690,7 @@ static void blk_account_io_completion(struct request *req, unsigned int bytes)
static void blk_account_io_done(struct request *req)
{
- struct gendisk *disk = req->rq_disk;
-
- if (!disk || !blk_do_io_stat(disk->queue))
+ if (!blk_do_io_stat(req))
return;
/*
@@ -1700,7 +1705,7 @@ static void blk_account_io_done(struct request *req)
int cpu;
cpu = part_stat_lock();
- part = disk_map_sector_rcu(disk, req->sector);
+ part = disk_map_sector_rcu(req->rq_disk, req->sector);
part_stat_inc(cpu, part, ios[rw]);
part_stat_add(cpu, part, ticks[rw], duration);
diff --git a/block/blk-merge.c b/block/blk-merge.c
index e39cb24b767..63760ca3da0 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -338,6 +338,22 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
return 1;
}
+static void blk_account_io_merge(struct request *req)
+{
+ if (blk_do_io_stat(req)) {
+ struct hd_struct *part;
+ int cpu;
+
+ cpu = part_stat_lock();
+ part = disk_map_sector_rcu(req->rq_disk, req->sector);
+
+ part_round_stats(cpu, part);
+ part_dec_in_flight(part);
+
+ part_stat_unlock();
+ }
+}
+
/*
* Has to be called with the request spinlock acquired
*/
@@ -386,18 +402,7 @@ static int attempt_merge(struct request_queue *q, struct request *req,
elv_merge_requests(q, req, next);
- if (req->rq_disk) {
- struct hd_struct *part;
- int cpu;
-
- cpu = part_stat_lock();
- part = disk_map_sector_rcu(req->rq_disk, req->sector);
-
- part_round_stats(cpu, part);
- part_dec_in_flight(part);
-
- part_stat_unlock();
- }
+ blk_account_io_merge(req);
req->ioprio = ioprio_best(req->ioprio, next->ioprio);
if (blk_rq_cpu_valid(next))
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 59fd05d9f1d..69c42adde52 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -431,7 +431,7 @@ EXPORT_SYMBOL(blk_queue_segment_boundary);
*
* description:
* set required memory and length alignment for direct dma transactions.
- * this is used when buiding direct io requests for the queue.
+ * this is used when building direct io requests for the queue.
*
**/
void blk_queue_dma_alignment(struct request_queue *q, int mask)
diff --git a/block/blk-softirq.c b/block/blk-softirq.c
index ce0efc6b26d..ee9c2160222 100644
--- a/block/blk-softirq.c
+++ b/block/blk-softirq.c
@@ -64,7 +64,7 @@ static int raise_blk_irq(int cpu, struct request *rq)
data->info = rq;
data->flags = 0;
- __smp_call_function_single(cpu, data);
+ __smp_call_function_single(cpu, data, 0);
return 0;
}
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index e29ddfc73cf..73f36beff5c 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -48,28 +48,28 @@ queue_requests_store(struct request_queue *q, const char *page, size_t count)
q->nr_requests = nr;
blk_queue_congestion_threshold(q);
- if (rl->count[READ] >= queue_congestion_on_threshold(q))
- blk_set_queue_congested(q, READ);
- else if (rl->count[READ] < queue_congestion_off_threshold(q))
- blk_clear_queue_congested(q, READ);
-
- if (rl->count[WRITE] >= queue_congestion_on_threshold(q))
- blk_set_queue_congested(q, WRITE);
- else if (rl->count[WRITE] < queue_congestion_off_threshold(q))
- blk_clear_queue_congested(q, WRITE);
-
- if (rl->count[READ] >= q->nr_requests) {
- blk_set_queue_full(q, READ);
- } else if (rl->count[READ]+1 <= q->nr_requests) {
- blk_clear_queue_full(q, READ);
- wake_up(&rl->wait[READ]);
+ if (rl->count[BLK_RW_SYNC] >= queue_congestion_on_threshold(q))
+ blk_set_queue_congested(q, BLK_RW_SYNC);
+ else if (rl->count[BLK_RW_SYNC] < queue_congestion_off_threshold(q))
+ blk_clear_queue_congested(q, BLK_RW_SYNC);
+
+ if (rl->count[BLK_RW_ASYNC] >= queue_congestion_on_threshold(q))
+ blk_set_queue_congested(q, BLK_RW_ASYNC);
+ else if (rl->count[BLK_RW_ASYNC] < queue_congestion_off_threshold(q))
+ blk_clear_queue_congested(q, BLK_RW_ASYNC);
+
+ if (rl->count[BLK_RW_SYNC] >= q->nr_requests) {
+ blk_set_queue_full(q, BLK_RW_SYNC);
+ } else if (rl->count[BLK_RW_SYNC]+1 <= q->nr_requests) {
+ blk_clear_queue_full(q, BLK_RW_SYNC);
+ wake_up(&rl->wait[BLK_RW_SYNC]);
}
- if (rl->count[WRITE] >= q->nr_requests) {
- blk_set_queue_full(q, WRITE);
- } else if (rl->count[WRITE]+1 <= q->nr_requests) {
- blk_clear_queue_full(q, WRITE);
- wake_up(&rl->wait[WRITE]);
+ if (rl->count[BLK_RW_ASYNC] >= q->nr_requests) {
+ blk_set_queue_full(q, BLK_RW_ASYNC);
+ } else if (rl->count[BLK_RW_ASYNC]+1 <= q->nr_requests) {
+ blk_clear_queue_full(q, BLK_RW_ASYNC);
+ wake_up(&rl->wait[BLK_RW_ASYNC]);
}
spin_unlock_irq(q->queue_lock);
return ret;
@@ -209,10 +209,14 @@ static ssize_t queue_iostats_store(struct request_queue *q, const char *page,
ssize_t ret = queue_var_store(&stats, page, count);
spin_lock_irq(q->queue_lock);
+ elv_quisce_start(q);
+
if (stats)
queue_flag_set(QUEUE_FLAG_IO_STAT, q);
else
queue_flag_clear(QUEUE_FLAG_IO_STAT, q);
+
+ elv_quisce_end(q);
spin_unlock_irq(q->queue_lock);
return ret;
diff --git a/block/blk.h b/block/blk.h
index 0dce92c3749..24fcaeeaf62 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -70,6 +70,10 @@ void blk_queue_congestion_threshold(struct request_queue *q);
int blk_dev_init(void);
+void elv_quisce_start(struct request_queue *q);
+void elv_quisce_end(struct request_queue *q);
+
+
/*
* Return the threshold (number of used requests) at which the queue is
* considered to be congested. It include a little hysteresis to keep the
@@ -102,18 +106,20 @@ static inline int blk_cpu_to_group(int cpu)
const struct cpumask *mask = cpu_coregroup_mask(cpu);
return cpumask_first(mask);
#elif defined(CONFIG_SCHED_SMT)
- return first_cpu(per_cpu(cpu_sibling_map, cpu));
+ return cpumask_first(topology_thread_cpumask(cpu));
#else
return cpu;
#endif
}
-static inline int blk_do_io_stat(struct request_queue *q)
+static inline int blk_do_io_stat(struct request *rq)
{
- if (q)
- return blk_queue_io_stat(q);
+ struct gendisk *disk = rq->rq_disk;
- return 0;
+ if (!disk || !disk->queue)
+ return 0;
+
+ return blk_queue_io_stat(disk->queue) && (rq->cmd_flags & REQ_ELVPRIV);
}
#endif
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 664ebfd092e..a4809de6fea 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -160,6 +160,7 @@ struct cfq_queue {
unsigned long slice_end;
long slice_resid;
+ unsigned int slice_dispatch;
/* pending metadata requests */
int meta_pending;
@@ -176,13 +177,12 @@ struct cfq_queue {
enum cfqq_state_flags {
CFQ_CFQQ_FLAG_on_rr = 0, /* on round-robin busy list */
CFQ_CFQQ_FLAG_wait_request, /* waiting for a request */
+ CFQ_CFQQ_FLAG_must_dispatch, /* must be allowed a dispatch */
CFQ_CFQQ_FLAG_must_alloc, /* must be allowed rq alloc */
CFQ_CFQQ_FLAG_must_alloc_slice, /* per-slice must_alloc flag */
- CFQ_CFQQ_FLAG_must_dispatch, /* must dispatch, even if expired */
CFQ_CFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */
CFQ_CFQQ_FLAG_idle_window, /* slice idling enabled */
CFQ_CFQQ_FLAG_prio_changed, /* task priority has changed */
- CFQ_CFQQ_FLAG_queue_new, /* queue never been serviced */
CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */
CFQ_CFQQ_FLAG_sync, /* synchronous queue */
};
@@ -203,13 +203,12 @@ static inline int cfq_cfqq_##name(const struct cfq_queue *cfqq) \
CFQ_CFQQ_FNS(on_rr);
CFQ_CFQQ_FNS(wait_request);
+CFQ_CFQQ_FNS(must_dispatch);
CFQ_CFQQ_FNS(must_alloc);
CFQ_CFQQ_FNS(must_alloc_slice);
-CFQ_CFQQ_FNS(must_dispatch);
CFQ_CFQQ_FNS(fifo_expire);
CFQ_CFQQ_FNS(idle_window);
CFQ_CFQQ_FNS(prio_changed);
-CFQ_CFQQ_FNS(queue_new);
CFQ_CFQQ_FNS(slice_new);
CFQ_CFQQ_FNS(sync);
#undef CFQ_CFQQ_FNS
@@ -774,10 +773,15 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd,
if (cfqq) {
cfq_log_cfqq(cfqd, cfqq, "set_active");
cfqq->slice_end = 0;
+ cfqq->slice_dispatch = 0;
+
+ cfq_clear_cfqq_wait_request(cfqq);
+ cfq_clear_cfqq_must_dispatch(cfqq);
cfq_clear_cfqq_must_alloc_slice(cfqq);
cfq_clear_cfqq_fifo_expire(cfqq);
cfq_mark_cfqq_slice_new(cfqq);
- cfq_clear_cfqq_queue_new(cfqq);
+
+ del_timer(&cfqd->idle_slice_timer);
}
cfqd->active_queue = cfqq;
@@ -795,7 +799,6 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
if (cfq_cfqq_wait_request(cfqq))
del_timer(&cfqd->idle_slice_timer);
- cfq_clear_cfqq_must_dispatch(cfqq);
cfq_clear_cfqq_wait_request(cfqq);
/*
@@ -924,7 +927,6 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
(sample_valid(cic->ttime_samples) && cic->ttime_mean > 2))
return;
- cfq_mark_cfqq_must_dispatch(cfqq);
cfq_mark_cfqq_wait_request(cfqq);
/*
@@ -1010,7 +1012,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
/*
* The active queue has run out of time, expire it and select new.
*/
- if (cfq_slice_used(cfqq))
+ if (cfq_slice_used(cfqq) && !cfq_cfqq_must_dispatch(cfqq))
goto expire;
/*
@@ -1053,66 +1055,6 @@ keep_queue:
return cfqq;
}
-/*
- * Dispatch some requests from cfqq, moving them to the request queue
- * dispatch list.
- */
-static int
-__cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
- int max_dispatch)
-{
- int dispatched = 0;
-
- BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list));
-
- do {
- struct request *rq;
-
- /*
- * follow expired path, else get first next available
- */
- rq = cfq_check_fifo(cfqq);
- if (rq == NULL)
- rq = cfqq->next_rq;
-
- /*
- * finally, insert request into driver dispatch list
- */
- cfq_dispatch_insert(cfqd->queue, rq);
-
- dispatched++;
-
- if (!cfqd->active_cic) {
- atomic_inc(&RQ_CIC(rq)->ioc->refcount);
- cfqd->active_cic = RQ_CIC(rq);
- }
-
- if (RB_EMPTY_ROOT(&cfqq->sort_list))
- break;
-
- /*
- * If there is a non-empty RT cfqq waiting for current
- * cfqq's timeslice to complete, pre-empt this cfqq
- */
- if (!cfq_class_rt(cfqq) && cfqd->busy_rt_queues)
- break;
-
- } while (dispatched < max_dispatch);
-
- /*
- * expire an async queue immediately if it has used up its slice. idle
- * queue always expire after 1 dispatch round.
- */
- if (cfqd->busy_queues > 1 && ((!cfq_cfqq_sync(cfqq) &&
- dispatched >= cfq_prio_to_maxrq(cfqd, cfqq)) ||
- cfq_class_idle(cfqq))) {
- cfqq->slice_end = jiffies + 1;
- cfq_slice_expired(cfqd, 0);
- }
-
- return dispatched;
-}
-
static int __cfq_forced_dispatch_cfqq(struct cfq_queue *cfqq)
{
int dispatched = 0;
@@ -1146,11 +1088,45 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd)
return dispatched;
}
+/*
+ * Dispatch a request from cfqq, moving them to the request queue
+ * dispatch list.
+ */
+static void cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+{
+ struct request *rq;
+
+ BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list));
+
+ /*
+ * follow expired path, else get first next available
+ */
+ rq = cfq_check_fifo(cfqq);
+ if (!rq)
+ rq = cfqq->next_rq;
+
+ /*
+ * insert request into driver dispatch list
+ */
+ cfq_dispatch_insert(cfqd->queue, rq);
+
+ if (!cfqd->active_cic) {
+ struct cfq_io_context *cic = RQ_CIC(rq);
+
+ atomic_inc(&cic->ioc->refcount);
+ cfqd->active_cic = cic;
+ }
+}
+
+/*
+ * Find the cfqq that we need to service and move a request from that to the
+ * dispatch list
+ */
static int cfq_dispatch_requests(struct request_queue *q, int force)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
struct cfq_queue *cfqq;
- int dispatched;
+ unsigned int max_dispatch;
if (!cfqd->busy_queues)
return 0;
@@ -1158,29 +1134,63 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
if (unlikely(force))
return cfq_forced_dispatch(cfqd);
- dispatched = 0;
- while ((cfqq = cfq_select_queue(cfqd)) != NULL) {
- int max_dispatch;
+ cfqq = cfq_select_queue(cfqd);
+ if (!cfqq)
+ return 0;
+
+ /*
+ * If this is an async queue and we have sync IO in flight, let it wait
+ */
+ if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq))
+ return 0;
+
+ max_dispatch = cfqd->cfq_quantum;
+ if (cfq_class_idle(cfqq))
+ max_dispatch = 1;
- max_dispatch = cfqd->cfq_quantum;
+ /*
+ * Does this cfqq already have too much IO in flight?
+ */
+ if (cfqq->dispatched >= max_dispatch) {
+ /*
+ * idle queue must always only have a single IO in flight
+ */
if (cfq_class_idle(cfqq))
- max_dispatch = 1;
+ return 0;
- if (cfqq->dispatched >= max_dispatch && cfqd->busy_queues > 1)
- break;
+ /*
+ * We have other queues, don't allow more IO from this one
+ */
+ if (cfqd->busy_queues > 1)
+ return 0;
- if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq))
- break;
+ /*
+ * we are the only queue, allow up to 4 times of 'quantum'
+ */
+ if (cfqq->dispatched >= 4 * max_dispatch)
+ return 0;
+ }
- cfq_clear_cfqq_must_dispatch(cfqq);
- cfq_clear_cfqq_wait_request(cfqq);
- del_timer(&cfqd->idle_slice_timer);
+ /*
+ * Dispatch a request from this cfqq
+ */
+ cfq_dispatch_request(cfqd, cfqq);
+ cfqq->slice_dispatch++;
+ cfq_clear_cfqq_must_dispatch(cfqq);
- dispatched += __cfq_dispatch_requests(cfqd, cfqq, max_dispatch);
+ /*
+ * expire an async queue immediately if it has used up its slice. idle
+ * queue always expire after 1 dispatch round.
+ */
+ if (cfqd->busy_queues > 1 && ((!cfq_cfqq_sync(cfqq) &&
+ cfqq->slice_dispatch >= cfq_prio_to_maxrq(cfqd, cfqq)) ||
+ cfq_class_idle(cfqq))) {
+ cfqq->slice_end = jiffies + 1;
+ cfq_slice_expired(cfqd, 0);
}
- cfq_log(cfqd, "dispatched=%d", dispatched);
- return dispatched;
+ cfq_log(cfqd, "dispatched a request");
+ return 1;
}
/*
@@ -1506,7 +1516,6 @@ retry:
cfqq->cfqd = cfqd;
cfq_mark_cfqq_prio_changed(cfqq);
- cfq_mark_cfqq_queue_new(cfqq);
cfq_init_prio_data(cfqq, ioc);
@@ -1893,15 +1902,13 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
if (cfqq == cfqd->active_queue) {
/*
- * if we are waiting for a request for this queue, let it rip
- * immediately and flag that we must not expire this queue
- * just now
+ * Remember that we saw a request from this process, but
+ * don't start queuing just yet. Otherwise we risk seeing lots
+ * of tiny requests, because we disrupt the normal plugging
+ * and merging.
*/
- if (cfq_cfqq_wait_request(cfqq)) {
+ if (cfq_cfqq_wait_request(cfqq))
cfq_mark_cfqq_must_dispatch(cfqq);
- del_timer(&cfqd->idle_slice_timer);
- blk_start_queueing(cfqd->queue);
- }
} else if (cfq_should_preempt(cfqd, cfqq, rq)) {
/*
* not the active queue - expire current slice if it is
@@ -1910,7 +1917,6 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
* this new queue is RT and the current one is BE
*/
cfq_preempt_queue(cfqd, cfqq);
- cfq_mark_cfqq_must_dispatch(cfqq);
blk_start_queueing(cfqd->queue);
}
}
@@ -1992,8 +1998,10 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
}
if (cfq_slice_used(cfqq) || cfq_class_idle(cfqq))
cfq_slice_expired(cfqd, 1);
- else if (sync && RB_EMPTY_ROOT(&cfqq->sort_list))
+ else if (sync && !rq_noidle(rq) &&
+ RB_EMPTY_ROOT(&cfqq->sort_list)) {
cfq_arm_slice_timer(cfqd);
+ }
}
if (!cfqd->rq_in_driver)
@@ -2170,6 +2178,12 @@ static void cfq_idle_slice_timer(unsigned long data)
timed_out = 0;
/*
+ * We saw a request before the queue expired, let it through
+ */
+ if (cfq_cfqq_must_dispatch(cfqq))
+ goto out_kick;
+
+ /*
* expired
*/
if (cfq_slice_used(cfqq))
@@ -2185,10 +2199,8 @@ static void cfq_idle_slice_timer(unsigned long data)
/*
* not expired and it has a request pending, let it dispatch
*/
- if (!RB_EMPTY_ROOT(&cfqq->sort_list)) {
- cfq_mark_cfqq_must_dispatch(cfqq);
+ if (!RB_EMPTY_ROOT(&cfqq->sort_list))
goto out_kick;
- }
}
expire:
cfq_slice_expired(cfqd, timed_out);
diff --git a/block/elevator.c b/block/elevator.c
index 98259eda0ef..fb81bcc14a8 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -573,7 +573,7 @@ void elv_requeue_request(struct request_queue *q, struct request *rq)
elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE);
}
-static void elv_drain_elevator(struct request_queue *q)
+void elv_drain_elevator(struct request_queue *q)
{
static int printed;
while (q->elevator->ops->elevator_dispatch_fn(q, 1))
@@ -587,6 +587,31 @@ static void elv_drain_elevator(struct request_queue *q)
}
}
+/*
+ * Call with queue lock held, interrupts disabled
+ */
+void elv_quisce_start(struct request_queue *q)
+{
+ queue_flag_set(QUEUE_FLAG_ELVSWITCH, q);
+
+ /*
+ * make sure we don't have any requests in flight
+ */
+ elv_drain_elevator(q);
+ while (q->rq.elvpriv) {
+ blk_start_queueing(q);
+ spin_unlock_irq(q->queue_lock);
+ msleep(10);
+ spin_lock_irq(q->queue_lock);
+ elv_drain_elevator(q);
+ }
+}
+
+void elv_quisce_end(struct request_queue *q)
+{
+ queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
+}
+
void elv_insert(struct request_queue *q, struct request *rq, int where)
{
struct list_head *pos;
@@ -677,7 +702,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where)
}
if (unplug_it && blk_queue_plugged(q)) {
- int nrq = q->rq.count[READ] + q->rq.count[WRITE]
+ int nrq = q->rq.count[BLK_RW_SYNC] + q->rq.count[BLK_RW_ASYNC]
- q->in_flight;
if (nrq >= q->unplug_thresh)
@@ -1101,18 +1126,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
* Turn on BYPASS and drain all requests w/ elevator private data
*/
spin_lock_irq(q->queue_lock);
-
- queue_flag_set(QUEUE_FLAG_ELVSWITCH, q);
-
- elv_drain_elevator(q);
-
- while (q->rq.elvpriv) {
- blk_start_queueing(q);
- spin_unlock_irq(q->queue_lock);
- msleep(10);
- spin_lock_irq(q->queue_lock);
- elv_drain_elevator(q);
- }
+ elv_quisce_start(q);
/*
* Remember old elevator.
@@ -1136,7 +1150,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
*/
elevator_exit(old_elevator);
spin_lock_irq(q->queue_lock);
- queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
+ elv_quisce_end(q);
spin_unlock_irq(q->queue_lock);
blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name);
diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
index f21147f3626..06eb6cc09fe 100644
--- a/crypto/async_tx/async_tx.c
+++ b/crypto/async_tx/async_tx.c
@@ -30,7 +30,7 @@
#ifdef CONFIG_DMA_ENGINE
static int __init async_tx_init(void)
{
- dmaengine_get();
+ async_dmaengine_get();
printk(KERN_INFO "async_tx: api initialized (async)\n");
@@ -39,7 +39,7 @@ static int __init async_tx_init(void)
static void __exit async_tx_exit(void)
{
- dmaengine_put();
+ async_dmaengine_put();
}
/**
@@ -56,7 +56,7 @@ __async_tx_find_channel(struct dma_async_tx_descriptor *depend_tx,
if (depend_tx &&
dma_has_cap(tx_type, depend_tx->chan->device->cap_mask))
return depend_tx->chan;
- return dma_find_channel(tx_type);
+ return async_dma_find_channel(tx_type);
}
EXPORT_SYMBOL_GPL(__async_tx_find_channel);
#else
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index 595b78672b3..95fe2c8d6c5 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -30,11 +30,8 @@
#include <linux/raid/xor.h>
#include <linux/async_tx.h>
-/* do_async_xor - dma map the pages and perform the xor with an engine.
- * This routine is marked __always_inline so it can be compiled away
- * when CONFIG_DMA_ENGINE=n
- */
-static __always_inline struct dma_async_tx_descriptor *
+/* do_async_xor - dma map the pages and perform the xor with an engine */
+static __async_inline struct dma_async_tx_descriptor *
do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list,
unsigned int offset, int src_cnt, size_t len,
enum async_tx_flags flags,
diff --git a/crypto/shash.c b/crypto/shash.c
index 7a659733f94..2ccc8b0076c 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -77,6 +77,9 @@ static int shash_update_unaligned(struct shash_desc *desc, const u8 *data,
u8 buf[shash_align_buffer_size(unaligned_len, alignmask)]
__attribute__ ((aligned));
+ if (unaligned_len > len)
+ unaligned_len = len;
+
memcpy(buf, data, unaligned_len);
return shash->update(desc, buf, unaligned_len) ?:
diff --git a/crypto/xor.c b/crypto/xor.c
index b2e6db075e4..996b6ee57d9 100644
--- a/crypto/xor.c
+++ b/crypto/xor.c
@@ -18,8 +18,8 @@
#define BH_TRACE 0
#include <linux/module.h>
-#include <linux/raid/md.h>
#include <linux/raid/xor.h>
+#include <linux/jiffies.h>
#include <asm/xor.h>
/* The xor routines to use. */
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 8a851d0f438..431f8b43955 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -11,9 +11,9 @@ menuconfig ACPI
select PNP
select CPU_IDLE
default y
- ---help---
+ help
Advanced Configuration and Power Interface (ACPI) support for
- Linux requires an ACPI compliant platform (hardware/firmware),
+ Linux requires an ACPI-compliant platform (hardware/firmware),
and assumes the presence of OS-directed configuration and power
management (OSPM) software. This option will enlarge your
kernel by about 70K.
@@ -23,20 +23,19 @@ menuconfig ACPI
the Plug-and-Play BIOS specification (PnP BIOS), the
MultiProcessor Specification (MPS), and the Advanced Power
Management (APM) specification. If both ACPI and APM support
- are configured, whichever is loaded first shall be used.
+ are configured, ACPI is used.
- The ACPI SourceForge project contains the latest source code,
- documentation, tools, mailing list subscription, and other
- information. This project is available at:
- <http://sourceforge.net/projects/acpi>
+ The project home page for the Linux ACPI subsystem is here:
+ <http://www.lesswatts.org/projects/acpi/>
Linux support for ACPI is based on Intel Corporation's ACPI
- Component Architecture (ACPI CA). For more information see:
- <http://developer.intel.com/technology/iapc/acpi>
+ Component Architecture (ACPI CA). For more information on the
+ ACPI CA, see:
+ <http://acpica.org/>
- ACPI is an open industry specification co-developed by Compaq,
- Intel, Microsoft, Phoenix, and Toshiba. The specification is
- available at:
+ ACPI is an open industry specification co-developed by
+ Hewlett-Packard, Intel, Microsoft, Phoenix, and Toshiba.
+ The specification is available at:
<http://www.acpi.info>
if ACPI
@@ -49,14 +48,14 @@ config ACPI_SLEEP
config ACPI_PROCFS
bool "Deprecated /proc/acpi files"
depends on PROC_FS
- ---help---
+ help
For backwards compatibility, this option allows
deprecated /proc/acpi/ files to exist, even when
they have been replaced by functions in /sys.
The deprecated files (and their replacements) include:
/proc/acpi/sleep (/sys/power/state)
- /proc/acpi/info (/sys/modules/acpi/parameters/acpica_version)
+ /proc/acpi/info (/sys/module/acpi/parameters/acpica_version)
/proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT)
/proc/acpi/fadt (/sys/firmware/acpi/tables/FACP)
/proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer)
@@ -66,11 +65,12 @@ config ACPI_PROCFS
and functions which do not yet exist in /sys.
Say N to delete /proc/acpi/ files that have moved to /sys/
+
config ACPI_PROCFS_POWER
bool "Deprecated power /proc/acpi directories"
depends on PROC_FS
default y
- ---help---
+ help
For backwards compatibility, this option allows
deprecated power /proc/acpi/ directories to exist, even when
they have been replaced by functions in /sys.
@@ -86,19 +86,19 @@ config ACPI_SYSFS_POWER
bool "Future power /sys interface"
select POWER_SUPPLY
default y
- ---help---
+ help
Say N to disable power /sys interface
config ACPI_PROC_EVENT
bool "Deprecated /proc/acpi/event support"
depends on PROC_FS
default y
- ---help---
- A user-space daemon, acpi, typically read /proc/acpi/event
- and handled all ACPI sub-system generated events.
+ help
+ A user-space daemon, acpid, typically reads /proc/acpi/event
+ and handles all ACPI-generated events.
- These events are now delivered to user-space via
- either the input layer, or as netlink events.
+ These events are now delivered to user-space either
+ via the input layer or as netlink events.
This build option enables the old code for legacy
user-space implementation. After some time, this will
@@ -112,10 +112,13 @@ config ACPI_AC
depends on X86
default y
help
- This driver adds support for the AC Adapter object, which indicates
- whether a system is on AC, or not. If you have a system that can
+ This driver supports the AC Adapter object, which indicates
+ whether a system is on AC or not. If you have a system that can
switch between A/C and battery, say Y.
+ To compile this driver as a module, choose M here:
+ the module will be called ac.
+
config ACPI_BATTERY
tristate "Battery"
depends on X86
@@ -125,15 +128,21 @@ config ACPI_BATTERY
/proc/acpi/battery. If you have a mobile system with a battery,
say Y.
+ To compile this driver as a module, choose M here:
+ the module will be called battery.
+
config ACPI_BUTTON
tristate "Button"
depends on INPUT
default y
help
- This driver handles events on the power, sleep and lid buttons.
+ This driver handles events on the power, sleep, and lid buttons.
A daemon reads /proc/acpi/event and perform user-defined actions
such as shutting down the system. This is necessary for
- software controlled poweroff.
+ software-controlled poweroff.
+
+ To compile this driver as a module, choose M here:
+ the module will be called button.
config ACPI_VIDEO
tristate "Video"
@@ -141,38 +150,45 @@ config ACPI_VIDEO
depends on INPUT
select THERMAL
help
- This driver implement the ACPI Extensions For Display Adapters
+ This driver implements the ACPI Extensions For Display Adapters
for integrated graphics devices on motherboard, as specified in
- ACPI 2.0 Specification, Appendix B, allowing to perform some basic
- control like defining the video POST device, retrieving EDID information
- or to setup a video output, etc.
- Note that this is an ref. implementation only. It may or may not work
- for your integrated video device.
+ ACPI 2.0 Specification, Appendix B. This supports basic operations
+ such as defining the video POST device, retrieving EDID information,
+ and setting up a video output.
+
+ To compile this driver as a module, choose M here:
+ the module will be called video.
config ACPI_FAN
tristate "Fan"
select THERMAL
default y
help
- This driver adds support for ACPI fan devices, allowing user-mode
+ This driver supports ACPI fan devices, allowing user-mode
applications to perform basic fan control (on, off, status).
+ To compile this driver as a module, choose M here:
+ the module will be called fan.
+
config ACPI_DOCK
bool "Dock"
depends on EXPERIMENTAL
help
- This driver adds support for ACPI controlled docking stations and removable
- drive bays such as the IBM ultrabay or the Dell Module Bay.
+ This driver supports ACPI-controlled docking stations and removable
+ drive bays such as the IBM Ultrabay and the Dell Module Bay.
config ACPI_PROCESSOR
tristate "Processor"
select THERMAL
default y
help
- This driver installs ACPI as the idle handler for Linux, and uses
- ACPI C2 and C3 processor states to save power, on systems that
+ This driver installs ACPI as the idle handler for Linux and uses
+ ACPI C2 and C3 processor states to save power on systems that
support it. It is required by several flavors of cpufreq
- Performance-state drivers.
+ performance-state drivers.
+
+ To compile this driver as a module, choose M here:
+ the module will be called processor.
config ACPI_HOTPLUG_CPU
bool
@@ -186,11 +202,14 @@ config ACPI_THERMAL
select THERMAL
default y
help
- This driver adds support for ACPI thermal zones. Most mobile and
+ This driver supports ACPI thermal zones. Most mobile and
some desktop systems support ACPI thermal zones. It is HIGHLY
recommended that this option be enabled, as your processor(s)
may be damaged without it.
+ To compile this driver as a module, choose M here:
+ the module will be called thermal.
+
config ACPI_NUMA
bool "NUMA support"
depends on NUMA
@@ -218,7 +237,7 @@ config ACPI_BLACKLIST_YEAR
int "Disable ACPI for systems before Jan 1st this year" if X86_32
default 0
help
- enter a 4-digit year, eg. 2001 to disable ACPI by default
+ Enter a 4-digit year, e.g., 2001, to disable ACPI by default
on platforms with DMI BIOS date before January 1st that year.
"acpi=force" can be used to override this mechanism.
@@ -249,10 +268,13 @@ config ACPI_PCI_SLOT
tristate "PCI slot detection driver"
default n
help
- This driver will attempt to discover all PCI slots in your system,
- and creates entries in /sys/bus/pci/slots/. This feature can
- help you correlate PCI bus addresses with the physical geography
- of your slots. If you are unsure, say N.
+ This driver creates entries in /sys/bus/pci/slots/ for all PCI
+ slots in the system. This can help correlate PCI bus addresses,
+ i.e., segment/bus/device/function tuples, with physical slots in
+ the system. If you are unsure, say N.
+
+ To compile this driver as a module, choose M here:
+ the module will be called pci_slot.
config X86_PM_TIMER
bool "Power Management Timer Support" if EMBEDDED
@@ -271,43 +293,43 @@ config X86_PM_TIMER
systems require this timer.
config ACPI_CONTAINER
- tristate "ACPI0004,PNP0A05 and PNP0A06 Container Driver (EXPERIMENTAL)"
+ tristate "Container and Module Devices (EXPERIMENTAL)"
depends on EXPERIMENTAL
default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
- ---help---
- This allows _physical_ insertion and removal of CPUs and memory.
- This can be useful, for example, on NUMA machines that support
- ACPI based physical hotplug of nodes, or non-NUMA machines that
- support physical cpu/memory hot-plug.
+ help
+ This driver supports ACPI Container and Module devices (IDs
+ ACPI0004, PNP0A05, and PNP0A06).
- If one selects "m", this driver can be loaded with
- "modprobe container".
+ This helps support hotplug of nodes, CPUs, and memory.
+
+ To compile this driver as a module, choose M here:
+ the module will be called container.
config ACPI_HOTPLUG_MEMORY
tristate "Memory Hotplug"
depends on MEMORY_HOTPLUG
default n
help
- This driver adds supports for ACPI Memory Hotplug. This driver
- provides support for fielding notifications on ACPI memory
- devices (PNP0C80) which represent memory ranges that may be
- onlined or offlined during runtime.
+ This driver supports ACPI memory hotplug. The driver
+ fields notifications on ACPI memory devices (PNP0C80),
+ which represent memory ranges that may be onlined or
+ offlined during runtime.
- Enabling this driver assumes that your platform hardware
- and firmware have support for hot-plugging physical memory. If
- your system does not support physically adding or ripping out
- memory DIMMs at some platform defined granularity (individually
- or as a bank) at runtime, then you need not enable this driver.
+ If your hardware and firmware do not support adding or
+ removing memory devices at runtime, you need not enable
+ this driver.
- If one selects "m," this driver can be loaded using the following
- command:
- $>modprobe acpi_memhotplug
+ To compile this driver as a module, choose M here:
+ the module will be called acpi_memhotplug.
config ACPI_SBS
tristate "Smart Battery System"
depends on X86
help
- This driver adds support for the Smart Battery System, another
+ This driver supports the Smart Battery System, another
type of access to battery information, found on some laptops.
+ To compile this driver as a module, choose M here:
+ the modules will be called sbs and sbshc.
+
endif # ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index b130ea0d075..03a985be3fe 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -14,48 +14,50 @@ obj-$(CONFIG_X86) += blacklist.o
#
# ACPI Core Subsystem (Interpreter)
#
-obj-y += osl.o utils.o reboot.o\
+obj-y += acpi.o \
acpica/
+# All the builtin files are in the "acpi." module_param namespace.
+acpi-y += osl.o utils.o reboot.o
+
# sleep related files
-obj-y += wakeup.o
-obj-y += sleep.o
-obj-$(CONFIG_ACPI_SLEEP) += proc.o
+acpi-y += wakeup.o
+acpi-y += sleep.o
+acpi-$(CONFIG_ACPI_SLEEP) += proc.o
#
# ACPI Bus and Device Drivers
#
-processor-objs += processor_core.o processor_throttling.o \
- processor_idle.o processor_thermal.o
-ifdef CONFIG_CPU_FREQ
-processor-objs += processor_perflib.o
+acpi-y += bus.o glue.o
+acpi-y += scan.o
+acpi-y += ec.o
+acpi-$(CONFIG_ACPI_DOCK) += dock.o
+acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
+acpi-y += power.o
+acpi-y += system.o event.o
+acpi-$(CONFIG_ACPI_DEBUG) += debug.o
+acpi-$(CONFIG_ACPI_NUMA) += numa.o
+acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
+ifdef CONFIG_ACPI_VIDEO
+acpi-y += video_detect.o
endif
-obj-y += bus.o glue.o
-obj-y += scan.o
-# Keep EC driver first. Initialization of others depend on it.
-obj-y += ec.o
+# These are (potentially) separate modules
obj-$(CONFIG_ACPI_AC) += ac.o
-obj-$(CONFIG_ACPI_BATTERY) += battery.o
obj-$(CONFIG_ACPI_BUTTON) += button.o
obj-$(CONFIG_ACPI_FAN) += fan.o
-obj-$(CONFIG_ACPI_DOCK) += dock.o
obj-$(CONFIG_ACPI_VIDEO) += video.o
-ifdef CONFIG_ACPI_VIDEO
-obj-y += video_detect.o
-endif
-
-obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o
obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
obj-$(CONFIG_ACPI_CONTAINER) += container.o
obj-$(CONFIG_ACPI_THERMAL) += thermal.o
-obj-y += power.o
-obj-y += system.o event.o
-obj-$(CONFIG_ACPI_DEBUG) += debug.o
-obj-$(CONFIG_ACPI_NUMA) += numa.o
-obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
-obj-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
+obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
+obj-$(CONFIG_ACPI_BATTERY) += battery.o
obj-$(CONFIG_ACPI_SBS) += sbshc.o
obj-$(CONFIG_ACPI_SBS) += sbs.o
+
+# processor has its own "processor." module_param namespace
+processor-y := processor_core.o processor_throttling.o
+processor-y += processor_idle.o processor_thermal.o
+processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index 3f23298ee3f..17e50824a6f 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -18,7 +18,7 @@ obj-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\
excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \
exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o
-obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o
+obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o
obj-$(ACPI_FUTURE_USAGE) += hwtimer.o
@@ -41,4 +41,4 @@ obj-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
- utstate.o utmutex.o utobject.o utresrc.o
+ utstate.o utmutex.o utobject.o utresrc.o utlock.o
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index ddb40f5c68f..16e5210ae93 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -148,9 +148,12 @@ ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list;
ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT;
ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS;
-/* These addresses are calculated from FADT address values */
+/* These addresses are calculated from the FADT Event Block addresses */
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_status;
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
+
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_status;
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
/*
@@ -162,6 +165,10 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width;
ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
+/* Reader/Writer lock is used for namespace walk and dynamic table unload */
+
+ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock;
+
/*****************************************************************************
*
* Mutual exlusion within ACPICA subsystem
@@ -245,6 +252,7 @@ ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
ACPI_EXTERN u8 acpi_gbl_events_initialized;
ACPI_EXTERN u8 acpi_gbl_system_awake_and_running;
+ACPI_EXTERN u8 acpi_gbl_osi_data;
#ifndef DEFINE_ACPI_GLOBALS
@@ -371,7 +379,6 @@ ACPI_EXTERN char *acpi_gbl_db_buffer;
ACPI_EXTERN char *acpi_gbl_db_filename;
ACPI_EXTERN u32 acpi_gbl_db_debug_level;
ACPI_EXTERN u32 acpi_gbl_db_console_debug_level;
-ACPI_EXTERN struct acpi_table_header *acpi_gbl_db_table_ptr;
ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node;
/*
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h
index 58c69dc49ab..4afa3d8e0ef 100644
--- a/drivers/acpi/acpica/achware.h
+++ b/drivers/acpi/acpica/achware.h
@@ -64,14 +64,22 @@ u32 acpi_hw_get_mode(void);
*/
struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id);
-acpi_status
-acpi_hw_register_read(u32 register_id, u32 * return_value);
+acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control);
+
+acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value);
acpi_status acpi_hw_register_write(u32 register_id, u32 value);
acpi_status acpi_hw_clear_acpi_status(void);
/*
+ * hwvalid - Port I/O with validation
+ */
+acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width);
+
+acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width);
+
+/*
* hwgpe - GPE support
*/
acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 492d02761bb..772ee5c4ccc 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -108,6 +108,14 @@ static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = {
#endif
#endif
+/* Lock structure for reader/writer interfaces */
+
+struct acpi_rw_lock {
+ acpi_mutex writer_mutex;
+ acpi_mutex reader_mutex;
+ u32 num_readers;
+};
+
/*
* Predefined handles for spinlocks used within the subsystem.
* These spinlocks are created by acpi_ut_mutex_initialize
@@ -772,7 +780,19 @@ struct acpi_bit_register_info {
* must be preserved.
*/
#define ACPI_PM1_STATUS_PRESERVED_BITS 0x0800 /* Bit 11 */
-#define ACPI_PM1_CONTROL_PRESERVED_BITS 0x0200 /* Bit 9 (whatever) */
+
+/* Write-only bits must be zeroed by software */
+
+#define ACPI_PM1_CONTROL_WRITEONLY_BITS 0x2004 /* Bits 13, 2 */
+
+/* For control registers, both ignored and reserved bits must be preserved */
+
+#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0201 /* Bits 9, 0(SCI_EN) */
+#define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */
+#define ACPI_PM1_CONTROL_PRESERVED_BITS \
+ (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS)
+
+#define ACPI_PM2_CONTROL_PRESERVED_BITS 0xFFFFFFFE /* All except bit 0 */
/*
* Register IDs
@@ -781,12 +801,10 @@ struct acpi_bit_register_info {
#define ACPI_REGISTER_PM1_STATUS 0x01
#define ACPI_REGISTER_PM1_ENABLE 0x02
#define ACPI_REGISTER_PM1_CONTROL 0x03
-#define ACPI_REGISTER_PM1A_CONTROL 0x04
-#define ACPI_REGISTER_PM1B_CONTROL 0x05
-#define ACPI_REGISTER_PM2_CONTROL 0x06
-#define ACPI_REGISTER_PM_TIMER 0x07
-#define ACPI_REGISTER_PROCESSOR_BLOCK 0x08
-#define ACPI_REGISTER_SMI_COMMAND_BLOCK 0x09
+#define ACPI_REGISTER_PM2_CONTROL 0x04
+#define ACPI_REGISTER_PM_TIMER 0x05
+#define ACPI_REGISTER_PROCESSOR_BLOCK 0x06
+#define ACPI_REGISTER_SMI_COMMAND_BLOCK 0x07
/* Masks used to access the bit_registers */
@@ -818,7 +836,7 @@ struct acpi_bit_register_info {
#define ACPI_BITMASK_SCI_ENABLE 0x0001
#define ACPI_BITMASK_BUS_MASTER_RLD 0x0002
#define ACPI_BITMASK_GLOBAL_LOCK_RELEASE 0x0004
-#define ACPI_BITMASK_SLEEP_TYPE_X 0x1C00
+#define ACPI_BITMASK_SLEEP_TYPE 0x1C00
#define ACPI_BITMASK_SLEEP_ENABLE 0x2000
#define ACPI_BITMASK_ARB_DISABLE 0x0001
@@ -844,11 +862,35 @@ struct acpi_bit_register_info {
#define ACPI_BITPOSITION_SCI_ENABLE 0x00
#define ACPI_BITPOSITION_BUS_MASTER_RLD 0x01
#define ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE 0x02
-#define ACPI_BITPOSITION_SLEEP_TYPE_X 0x0A
+#define ACPI_BITPOSITION_SLEEP_TYPE 0x0A
#define ACPI_BITPOSITION_SLEEP_ENABLE 0x0D
#define ACPI_BITPOSITION_ARB_DISABLE 0x00
+/* Structs and definitions for _OSI support and I/O port validation */
+
+#define ACPI_OSI_WIN_2000 0x01
+#define ACPI_OSI_WIN_XP 0x02
+#define ACPI_OSI_WIN_XP_SP1 0x03
+#define ACPI_OSI_WINSRV_2003 0x04
+#define ACPI_OSI_WIN_XP_SP2 0x05
+#define ACPI_OSI_WINSRV_2003_SP1 0x06
+#define ACPI_OSI_WIN_VISTA 0x07
+
+#define ACPI_ALWAYS_ILLEGAL 0x00
+
+struct acpi_interface_info {
+ char *name;
+ u8 value;
+};
+
+struct acpi_port_info {
+ char *name;
+ u16 start;
+ u16 end;
+ u8 osi_dependency;
+};
+
/*****************************************************************************
*
* Resource descriptors
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h
index 9c127e8e2d6..91ac7d7b440 100644
--- a/drivers/acpi/acpica/acmacros.h
+++ b/drivers/acpi/acpica/acmacros.h
@@ -292,10 +292,6 @@
#define ACPI_GET_DESCRIPTOR_TYPE(d) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type)
#define ACPI_SET_DESCRIPTOR_TYPE(d, t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t)
-/* Macro to test the object type */
-
-#define ACPI_GET_OBJECT_TYPE(d) (((union acpi_operand_object *)(void *)(d))->common.type)
-
/*
* Macros for the master AML opcode table
*/
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h
index eb6f038b03d..544dcf83492 100644
--- a/drivers/acpi/acpica/acobject.h
+++ b/drivers/acpi/acpica/acobject.h
@@ -97,7 +97,6 @@
#define AOPOBJ_OBJECT_INITIALIZED 0x08
#define AOPOBJ_SETUP_COMPLETE 0x10
#define AOPOBJ_SINGLE_DATUM 0x20
-#define AOPOBJ_INVALID 0x40 /* Used if host OS won't allow an op_region address */
/******************************************************************************
*
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h
index 16a9ca9a66e..63f656ae360 100644
--- a/drivers/acpi/acpica/acpredef.h
+++ b/drivers/acpi/acpica/acpredef.h
@@ -52,41 +52,44 @@
* 1) PTYPE1 packages do not contain sub-packages.
*
* ACPI_PTYPE1_FIXED: Fixed length, 1 or 2 object types:
- * object type
- * count
- * object type
- * count
+ * object type
+ * count
+ * object type
+ * count
*
* ACPI_PTYPE1_VAR: Variable length:
- * object type (Int/Buf/Ref)
+ * object type (Int/Buf/Ref)
*
- * ACPI_PTYPE1_OPTION: Package has some required and some optional elements:
- * Used for _PRW
+ * ACPI_PTYPE1_OPTION: Package has some required and some optional elements
+ * (Used for _PRW)
*
*
* 2) PTYPE2 packages contain a variable number of sub-packages. Each of the
* different types describe the contents of each of the sub-packages.
*
* ACPI_PTYPE2: Each subpackage contains 1 or 2 object types:
- * object type
- * count
- * object type
- * count
+ * object type
+ * count
+ * object type
+ * count
+ * (Used for _ALR,_MLS,_PSS,_TRT,_TSS)
*
* ACPI_PTYPE2_COUNT: Each subpackage has a count as first element:
- * object type
+ * object type
+ * (Used for _CSD,_PSD,_TSD)
*
* ACPI_PTYPE2_PKG_COUNT: Count of subpackages at start, 1 or 2 object types:
- * object type
- * count
- * object type
- * count
+ * object type
+ * count
+ * object type
+ * count
+ * (Used for _CST)
*
- * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length:
- * Used for _PRT
+ * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length
+ * (Used for _PRT)
*
* ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length
- * Used for _HPX
+ * (Used for _HPX)
*
*****************************************************************************/
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index 7ce6e33c7f7..01c76b8ea7b 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -49,7 +49,7 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count);
/*
* tbfadt - FADT parse/convert/validate
*/
-void acpi_tb_parse_fadt(u32 table_index, u8 flags);
+void acpi_tb_parse_fadt(u32 table_index);
void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
@@ -79,7 +79,7 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc);
void acpi_tb_terminate(void);
-void acpi_tb_delete_namespace_by_owner(u32 table_index);
+acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index);
acpi_status acpi_tb_allocate_owner_id(u32 table_index);
@@ -109,9 +109,8 @@ acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length);
void
acpi_tb_install_table(acpi_physical_address address,
- u8 flags, char *signature, u32 table_index);
+ char *signature, u32 table_index);
-acpi_status
-acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags);
+acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address);
#endif /* __ACTABLES_H__ */
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h
index 80d8813484f..897810ba0cc 100644
--- a/drivers/acpi/acpica/acutils.h
+++ b/drivers/acpi/acpica/acutils.h
@@ -346,6 +346,21 @@ acpi_status
acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest);
/*
+ * utlock - reader/writer locks
+ */
+acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock);
+
+void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock);
+
+void acpi_ut_release_write_lock(struct acpi_rw_lock *lock);
+
+/*
* utobject - internal object create/delete/cache routines
*/
union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c
index eb144b13d8f..3aae13f30c5 100644
--- a/drivers/acpi/acpica/dsinit.c
+++ b/drivers/acpi/acpica/dsinit.c
@@ -180,11 +180,23 @@ acpi_ds_initialize_objects(u32 table_index,
/* Walk entire namespace from the supplied root */
- status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
- acpi_ds_init_one_object, &info, NULL);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ /*
+ * We don't use acpi_walk_namespace since we do not want to acquire
+ * the namespace reader lock.
+ */
+ status =
+ acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object,
+ &info, NULL);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
}
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
status = acpi_get_table_by_index(table_index, &table);
if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c
index da0f5468184..22b1a3ce2c9 100644
--- a/drivers/acpi/acpica/dsmthdat.c
+++ b/drivers/acpi/acpica/dsmthdat.c
@@ -713,6 +713,6 @@ acpi_ds_method_data_get_type(u16 opcode,
/* Get the object type */
- return_VALUE(ACPI_GET_OBJECT_TYPE(object));
+ return_VALUE(object->type);
}
#endif
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c
index 15c628e6aa0..dab3f48f0b4 100644
--- a/drivers/acpi/acpica/dsobject.c
+++ b/drivers/acpi/acpica/dsobject.c
@@ -565,7 +565,7 @@ acpi_ds_create_node(struct acpi_walk_state *walk_state,
/* Re-type the object according to its argument */
- node->type = ACPI_GET_OBJECT_TYPE(obj_desc);
+ node->type = obj_desc->common.type;
/* Attach obj to node */
@@ -619,7 +619,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
/* Perform per-object initialization */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_BUFFER:
/*
@@ -803,7 +803,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
default:
ACPI_ERROR((AE_INFO, "Unimplemented data type: %X",
- ACPI_GET_OBJECT_TYPE(obj_desc)));
+ obj_desc->common.type));
status = AE_AML_OPERAND_TYPE;
break;
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index 0c3b4dd60e8..b4c87b5053e 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -397,30 +397,6 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
extra_desc->extra.aml_length,
extra_desc->extra.aml_start);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
-
- /* Validate the region address/length via the host OS */
-
- status = acpi_os_validate_address(obj_desc->region.space_id,
- obj_desc->region.address,
- (acpi_size) obj_desc->region.length,
- acpi_ut_get_node_name(node));
-
- if (ACPI_FAILURE(status)) {
- /*
- * Invalid address/length. We will emit an error message and mark
- * the region as invalid, so that it will cause an additional error if
- * it is ever used. Then return AE_OK.
- */
- ACPI_EXCEPTION((AE_INFO, status,
- "During address validation of OpRegion [%4.4s]",
- node->name.ascii));
- obj_desc->common.flags |= AOPOBJ_INVALID;
- status = AE_OK;
- }
-
return_ACPI_STATUS(status);
}
@@ -484,7 +460,7 @@ acpi_ds_init_buffer_field(u16 aml_opcode,
/* Host object must be a Buffer */
- if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) {
+ if (buffer_desc->common.type != ACPI_TYPE_BUFFER) {
ACPI_ERROR((AE_INFO,
"Target of Create Field is not a Buffer object - %s",
acpi_ut_get_object_type_name(buffer_desc)));
@@ -1365,10 +1341,8 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
if ((ACPI_GET_DESCRIPTOR_TYPE
(walk_state->results->results.obj_desc[0]) ==
ACPI_DESC_TYPE_OPERAND)
- &&
- (ACPI_GET_OBJECT_TYPE
- (walk_state->results->results.obj_desc[0]) ==
- ACPI_TYPE_LOCAL_REFERENCE)
+ && ((walk_state->results->results.obj_desc[0])->
+ common.type == ACPI_TYPE_LOCAL_REFERENCE)
&& ((walk_state->results->results.obj_desc[0])->
reference.class != ACPI_REFCLASS_INDEX)) {
status =
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c
index dabc23a4617..dfa10410292 100644
--- a/drivers/acpi/acpica/dsutils.c
+++ b/drivers/acpi/acpica/dsutils.c
@@ -816,7 +816,7 @@ acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state)
goto push_result;
}
- type = ACPI_GET_OBJECT_TYPE(*operand);
+ type = (*operand)->common.type;
status = acpi_ex_resolve_to_value(operand, walk_state);
if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c
index 350e6656bc8..f0280856dc0 100644
--- a/drivers/acpi/acpica/dswexec.c
+++ b/drivers/acpi/acpica/dswexec.c
@@ -138,11 +138,10 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state,
goto cleanup;
}
- if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) {
+ if (local_obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X",
- obj_desc, walk_state,
- ACPI_GET_OBJECT_TYPE(obj_desc)));
+ obj_desc, walk_state, obj_desc->common.type));
status = AE_AML_OPERAND_TYPE;
goto cleanup;
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c
index 803edd9e3f6..cd55c774e88 100644
--- a/drivers/acpi/acpica/evevent.c
+++ b/drivers/acpi/acpica/evevent.c
@@ -183,7 +183,7 @@ acpi_status acpi_ev_install_xrupt_handlers(void)
*
* RETURN: Status
*
- * DESCRIPTION: Install the fixed event handlers and enable the fixed events.
+ * DESCRIPTION: Install the fixed event handlers and disable all fixed events.
*
******************************************************************************/
@@ -200,12 +200,13 @@ static acpi_status acpi_ev_fixed_event_initialize(void)
acpi_gbl_fixed_event_handlers[i].handler = NULL;
acpi_gbl_fixed_event_handlers[i].context = NULL;
- /* Enable the fixed event */
+ /* Disable the fixed event */
if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
status =
- acpi_set_register(acpi_gbl_fixed_event_info[i].
- enable_register_id, 0);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info
+ [i].enable_register_id,
+ ACPI_DISABLE_EVENT);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -288,16 +289,17 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event)
/* Clear the status bit */
- (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
- status_register_id, 1);
+ (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ status_register_id, ACPI_CLEAR_STATUS);
/*
* Make sure we've got a handler. If not, report an error. The event is
* disabled to prevent further interrupts.
*/
if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
- (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, 0);
+ (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id,
+ ACPI_DISABLE_EVENT);
ACPI_ERROR((AE_INFO,
"No installed handler for fixed event [%08X]",
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index f345ced3647..b9d8ee69ca6 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -88,10 +88,10 @@ acpi_ev_set_gpe_type(struct acpi_gpe_event_info *gpe_event_info, u8 type)
status = acpi_ev_disable_gpe(gpe_event_info);
- /* Type was validated above */
+ /* Clear the type bits and insert the new Type */
- gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; /* Clear type bits */
- gpe_event_info->flags |= type; /* Insert type */
+ gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK;
+ gpe_event_info->flags |= type;
return_ACPI_STATUS(status);
}
@@ -122,6 +122,7 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info,
if (!gpe_register_info) {
return_ACPI_STATUS(AE_NOT_EXIST);
}
+
register_bit = (u8)
(1 <<
(gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index 484cc0565d5..7b346363942 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -104,9 +104,9 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
while (gpe_block) {
if ((&gpe_block->event_info[0] <= gpe_event_info) &&
- (&gpe_block->
- event_info[((acpi_size) gpe_block->
- register_count) * 8] >
+ (&gpe_block->event_info[((acpi_size)
+ gpe_block->
+ register_count) * 8] >
gpe_event_info)) {
return (TRUE);
}
@@ -210,10 +210,9 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
/* Now look at the individual GPEs in this byte register */
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
- gpe_event_info =
- &gpe_block->
- event_info[((acpi_size) i *
- ACPI_GPE_REGISTER_WIDTH) + j];
+ gpe_event_info = &gpe_block->event_info[((acpi_size) i *
+ ACPI_GPE_REGISTER_WIDTH)
+ + j];
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_HANDLER) {
@@ -293,8 +292,8 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
/* Unknown method type, just ignore it! */
ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
- "Ignoring unknown GPE method type: %s (name not of form _Lxx or _Exx)",
- name));
+ "Ignoring unknown GPE method type: %s "
+ "(name not of form _Lxx or _Exx)", name));
return_ACPI_STATUS(AE_OK);
}
@@ -306,17 +305,16 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
/* Conversion failed; invalid method, just ignore it */
ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
- "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)",
- name));
+ "Could not extract GPE number from name: %s "
+ "(name is not of form _Lxx or _Exx)", name));
return_ACPI_STATUS(AE_OK);
}
/* Ensure that we have a valid GPE number for this GPE block */
if ((gpe_number < gpe_block->block_base_number) ||
- (gpe_number >=
- (gpe_block->block_base_number +
- (gpe_block->register_count * 8)))) {
+ (gpe_number >= (gpe_block->block_base_number +
+ (gpe_block->register_count * 8)))) {
/*
* Not valid for this GPE block, just ignore it. However, it may be
* valid for a different GPE block, since GPE0 and GPE1 methods both
@@ -408,7 +406,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
*/
obj_desc = pkg_desc->package.elements[0];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
/* Use FADT-defined GPE device (from definition of _PRW) */
@@ -417,15 +415,15 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
/* Integer is the GPE number in the FADT described GPE blocks */
gpe_number = (u32) obj_desc->integer.value;
- } else if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+ } else if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
/* Package contains a GPE reference and GPE number within a GPE block */
if ((obj_desc->package.count < 2) ||
- (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[0]) !=
- ACPI_TYPE_LOCAL_REFERENCE)
- || (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[1]) !=
- ACPI_TYPE_INTEGER)) {
+ ((obj_desc->package.elements[0])->common.type !=
+ ACPI_TYPE_LOCAL_REFERENCE) ||
+ ((obj_desc->package.elements[1])->common.type !=
+ ACPI_TYPE_INTEGER)) {
goto cleanup;
}
@@ -450,11 +448,11 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
*/
if ((gpe_device == target_gpe_device) &&
(gpe_number >= gpe_block->block_base_number) &&
- (gpe_number <
- gpe_block->block_base_number + (gpe_block->register_count * 8))) {
- gpe_event_info =
- &gpe_block->event_info[gpe_number -
- gpe_block->block_base_number];
+ (gpe_number < gpe_block->block_base_number +
+ (gpe_block->register_count * 8))) {
+ gpe_event_info = &gpe_block->event_info[gpe_number -
+ gpe_block->
+ block_base_number];
/* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
@@ -1033,8 +1031,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
* 1) are "runtime" or "run/wake" GPEs, and
* 2) have a corresponding _Lxx or _Exx method
*
- * Any other GPEs within this block must be enabled via the acpi_enable_gpe()
- * external interface.
+ * Any other GPEs within this block must be enabled via the
+ * acpi_enable_gpe() external interface.
*/
wake_gpe_count = 0;
gpe_enabled_count = 0;
@@ -1044,14 +1042,13 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
/* Get the info block for this particular GPE */
- gpe_event_info =
- &gpe_block->
- event_info[((acpi_size) i *
- ACPI_GPE_REGISTER_WIDTH) + j];
+ gpe_event_info = &gpe_block->event_info[((acpi_size) i *
+ ACPI_GPE_REGISTER_WIDTH)
+ + j];
if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
- ACPI_GPE_DISPATCH_METHOD)
- && (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
+ ACPI_GPE_DISPATCH_METHOD) &&
+ (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
gpe_enabled_count++;
}
@@ -1105,8 +1102,8 @@ acpi_status acpi_ev_gpe_initialize(void)
/*
* Initialize the GPE Block(s) defined in the FADT
*
- * Why the GPE register block lengths are divided by 2: From the ACPI Spec,
- * section "General-Purpose Event Registers", we have:
+ * Why the GPE register block lengths are divided by 2: From the ACPI
+ * Spec, section "General-Purpose Event Registers", we have:
*
* "Each register block contains two registers of equal length
* GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
@@ -1163,7 +1160,8 @@ acpi_status acpi_ev_gpe_initialize(void)
if ((register_count0) &&
(gpe_number_max >= acpi_gbl_FADT.gpe1_base)) {
ACPI_ERROR((AE_INFO,
- "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1",
+ "GPE0 block (GPE 0 to %d) overlaps the GPE1 block "
+ "(GPE %d to %d) - Ignoring GPE1",
gpe_number_max, acpi_gbl_FADT.gpe1_base,
acpi_gbl_FADT.gpe1_base +
((register_count1 *
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c
index 5f893057bcc..ce224e1eaa8 100644
--- a/drivers/acpi/acpica/evmisc.c
+++ b/drivers/acpi/acpica/evmisc.c
@@ -163,10 +163,10 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
* 2) Global device notify handler
* 3) Per-device notify handler
*/
- if ((acpi_gbl_system_notify.handler
- && (notify_value <= ACPI_MAX_SYS_NOTIFY))
- || (acpi_gbl_device_notify.handler
- && (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
+ if ((acpi_gbl_system_notify.handler &&
+ (notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
+ (acpi_gbl_device_notify.handler &&
+ (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
notify_info = acpi_ut_create_generic_state();
if (!notify_info) {
return (AE_NO_MEMORY);
@@ -174,7 +174,8 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
if (!handler_obj) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Executing system notify handler for Notify (%4.4s, %X) node %p\n",
+ "Executing system notify handler for Notify (%4.4s, %X) "
+ "node %p\n",
acpi_ut_get_node_name(node),
notify_value, node));
}
@@ -534,8 +535,9 @@ acpi_status acpi_ev_release_global_lock(void)
*/
if (pending) {
status =
- acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
- 1);
+ acpi_write_bit_register
+ (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
+ ACPI_ENABLE_EVENT);
}
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c
index 665c0887ab4..538d6326455 100644
--- a/drivers/acpi/acpica/evregion.c
+++ b/drivers/acpi/acpica/evregion.c
@@ -691,7 +691,7 @@ acpi_ev_install_handler(acpi_handle obj_handle,
/* Devices are handled different than regions */
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_DEVICE) {
+ if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
/* Check if this Device already has a handler for this address space */
@@ -703,7 +703,8 @@ acpi_ev_install_handler(acpi_handle obj_handle,
if (next_handler_obj->address_space.space_id ==
handler_obj->address_space.space_id) {
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
- "Found handler for region [%s] in device %p(%p) handler %p\n",
+ "Found handler for region [%s] in device %p(%p) "
+ "handler %p\n",
acpi_ut_get_region_name
(handler_obj->address_space.
space_id), obj_desc,
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c
index f3f1fb45c3d..284a7becbe9 100644
--- a/drivers/acpi/acpica/evrgnini.c
+++ b/drivers/acpi/acpica/evrgnini.c
@@ -241,7 +241,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
status = AE_OK;
} else {
ACPI_EXCEPTION((AE_INFO, status,
- "Could not install PciConfig handler for Root Bridge %4.4s",
+ "Could not install PciConfig handler "
+ "for Root Bridge %4.4s",
acpi_ut_get_node_name
(pci_root_node)));
}
@@ -293,9 +294,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
* Get the PCI device and function numbers from the _ADR object contained
* in the parent's scope.
*/
- status =
- acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node,
- &pci_value);
+ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
+ pci_device_node, &pci_value);
/*
* The default is zero, and since the allocation above zeroed the data,
@@ -308,18 +308,16 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
/* The PCI segment number comes from the _SEG method */
- status =
- acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, pci_root_node,
- &pci_value);
+ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG,
+ pci_root_node, &pci_value);
if (ACPI_SUCCESS(status)) {
pci_id->segment = ACPI_LOWORD(pci_value);
}
/* The PCI bus number comes from the _BBN method */
- status =
- acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, pci_root_node,
- &pci_value);
+ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN,
+ pci_root_node, &pci_value);
if (ACPI_SUCCESS(status)) {
pci_id->bus = ACPI_LOWORD(pci_value);
}
@@ -632,8 +630,8 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
acpi_ns_locked);
/*
- * Tell all users that this region is usable by running the _REG
- * method
+ * Tell all users that this region is usable by
+ * running the _REG method
*/
if (acpi_ns_locked) {
status =
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index 3aca9010a11..10b8543dd46 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -631,7 +631,8 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
/* Setup up dispatch flags to indicate handler (vs. method) */
- gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* Clear bits */
+ gpe_event_info->flags &=
+ ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index 35485e4b60a..d0a080747ec 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -172,8 +172,8 @@ acpi_status acpi_enable_event(u32 event, u32 flags)
* register bit)
*/
status =
- acpi_set_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, 1);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, ACPI_ENABLE_EVENT);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -181,8 +181,8 @@ acpi_status acpi_enable_event(u32 event, u32 flags)
/* Make sure that the hardware responded */
status =
- acpi_get_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, &value);
+ acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, &value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -354,15 +354,15 @@ acpi_status acpi_disable_event(u32 event, u32 flags)
* register bit)
*/
status =
- acpi_set_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, 0);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, ACPI_DISABLE_EVENT);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
status =
- acpi_get_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, &value);
+ acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, &value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -407,8 +407,8 @@ acpi_status acpi_clear_event(u32 event)
* register bit)
*/
status =
- acpi_set_register(acpi_gbl_fixed_event_info[event].
- status_register_id, 1);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ status_register_id, ACPI_CLEAR_STATUS);
return_ACPI_STATUS(status);
}
@@ -495,7 +495,7 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
/* Get the status of the requested fixed event */
status =
- acpi_get_register(acpi_gbl_fixed_event_info[event].
+ acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
enable_register_id, &value);
if (ACPI_FAILURE(status))
return_ACPI_STATUS(status);
@@ -503,7 +503,7 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
*event_status = value;
status =
- acpi_get_register(acpi_gbl_fixed_event_info[event].
+ acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
status_register_id, &value);
if (ACPI_FAILURE(status))
return_ACPI_STATUS(status);
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c
index 479e7a3721b..7c3d2d356ff 100644
--- a/drivers/acpi/acpica/evxfregn.c
+++ b/drivers/acpi/acpica/evxfregn.c
@@ -193,7 +193,8 @@ acpi_remove_address_space_handler(acpi_handle device,
/* Matched space_id, first dereference this in the Regions */
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
- "Removing address handler %p(%p) for region %s on Device %p(%p)\n",
+ "Removing address handler %p(%p) for region %s "
+ "on Device %p(%p)\n",
handler_obj, handler,
acpi_ut_get_region_name(space_id),
node, obj_desc));
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index 932bbc26aa0..3deb20a126b 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -291,7 +291,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
/* Source Object can be either an op_region or a Buffer/Field */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_REGION:
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
@@ -501,7 +501,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
*/
if ((!ddb_handle) ||
(ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
- (ACPI_GET_OBJECT_TYPE(ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) {
+ (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
@@ -520,13 +520,14 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
}
}
- /*
- * Delete the entire namespace under this table Node
- * (Offset contains the table_id)
- */
- acpi_tb_delete_namespace_by_owner(table_index);
- (void)acpi_tb_release_owner_id(table_index);
+ /* Delete the portion of the namespace owned by this table */
+
+ status = acpi_tb_delete_namespace_by_owner(table_index);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+ (void)acpi_tb_release_owner_id(table_index);
acpi_tb_set_table_loaded_flag(table_index, FALSE);
/* Table unloaded, remove a reference to the ddb_handle object */
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c
index 0be10188316..37d0d39e60a 100644
--- a/drivers/acpi/acpica/exconvrt.c
+++ b/drivers/acpi/acpica/exconvrt.c
@@ -82,7 +82,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc);
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
/* No conversion necessary */
@@ -116,7 +116,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
/* String conversion is different than Buffer conversion */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_STRING:
/*
@@ -206,7 +206,7 @@ acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc);
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_BUFFER:
/* No conversion necessary */
@@ -409,7 +409,7 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc);
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_STRING:
/* No conversion necessary */
@@ -605,8 +605,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
default:
/* No conversion allowed for these types */
- if (destination_type !=
- ACPI_GET_OBJECT_TYPE(source_desc)) {
+ if (destination_type != source_desc->common.type) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Explicit operator, will store (%s) over existing type (%s)\n",
acpi_ut_get_object_type_name
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c
index aa313574b0d..89d141fdae0 100644
--- a/drivers/acpi/acpica/exdump.c
+++ b/drivers/acpi/acpica/exdump.c
@@ -350,6 +350,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
break;
case ACPI_EXD_TYPE:
+
acpi_ex_out_string("Type",
acpi_ut_get_object_type_name
(obj_desc));
@@ -422,6 +423,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
break;
default:
+
acpi_os_printf("**** Invalid table opcode [%X] ****\n",
info->opcode);
return;
@@ -492,7 +494,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
/* Decode object type */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
acpi_os_printf("Reference: [%s] ",
@@ -527,44 +529,16 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
type));
break;
- case ACPI_REFCLASS_ARG:
-
- acpi_os_printf("%X", obj_desc->reference.value);
-
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
-
- /* Value is an Integer */
-
- acpi_os_printf(" value is [%8.8X%8.8x]",
- ACPI_FORMAT_UINT64(obj_desc->
- integer.
- value));
- }
+ case ACPI_REFCLASS_NAME:
- acpi_os_printf("\n");
+ acpi_os_printf("- [%4.4s]\n",
+ obj_desc->reference.node->name.ascii);
break;
+ case ACPI_REFCLASS_ARG:
case ACPI_REFCLASS_LOCAL:
- acpi_os_printf("%X", obj_desc->reference.value);
-
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
-
- /* Value is an Integer */
-
- acpi_os_printf(" value is [%8.8X%8.8x]",
- ACPI_FORMAT_UINT64(obj_desc->
- integer.
- value));
- }
-
- acpi_os_printf("\n");
- break;
-
- case ACPI_REFCLASS_NAME:
-
- acpi_os_printf("- [%4.4s]\n",
- obj_desc->reference.node->name.ascii);
+ acpi_os_printf("%X\n", obj_desc->reference.value);
break;
default: /* Unknown reference class */
@@ -661,8 +635,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
case ACPI_TYPE_LOCAL_REGION_FIELD:
acpi_os_printf
- ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n",
- obj_desc->field.bit_length,
+ ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at "
+ "byte=%X bit=%X of below:\n", obj_desc->field.bit_length,
obj_desc->field.access_byte_width,
obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
@@ -686,9 +660,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
if (!obj_desc->buffer_field.buffer_obj) {
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n"));
- } else
- if (ACPI_GET_OBJECT_TYPE(obj_desc->buffer_field.buffer_obj)
- != ACPI_TYPE_BUFFER) {
+ } else if ((obj_desc->buffer_field.buffer_obj)->common.type !=
+ ACPI_TYPE_BUFFER) {
acpi_os_printf("*not a Buffer*\n");
} else {
acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj,
@@ -737,8 +710,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
default:
/* Unknown Type */
- acpi_os_printf("Unknown Type %X\n",
- ACPI_GET_OBJECT_TYPE(obj_desc));
+ acpi_os_printf("Unknown Type %X\n", obj_desc->common.type);
break;
}
@@ -939,7 +911,7 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
/* Packages may only contain a few object types */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
acpi_os_printf("[Integer] = %8.8X%8.8X\n",
@@ -990,8 +962,7 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
default:
- acpi_os_printf("[Unknown Type] %X\n",
- ACPI_GET_OBJECT_TYPE(obj_desc));
+ acpi_os_printf("[Unknown Type] %X\n", obj_desc->common.type);
break;
}
}
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
index a352d023385..546dcdd8678 100644
--- a/drivers/acpi/acpica/exfield.c
+++ b/drivers/acpi/acpica/exfield.c
@@ -84,7 +84,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+ if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
/*
* If the buffer_field arguments have not been previously evaluated,
* evaluate them now and save the results.
@@ -95,9 +95,8 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(status);
}
}
- } else
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
- && (obj_desc->field.region_obj->region.space_id ==
+ } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+ (obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_SMBUS)) {
/*
* This is an SMBus read. We must create a buffer to hold the data
@@ -163,7 +162,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"FieldRead [TO]: Obj %p, Type %X, Buf %p, ByteLen %X\n",
- obj_desc, ACPI_GET_OBJECT_TYPE(obj_desc), buffer,
+ obj_desc, obj_desc->common.type, buffer,
(u32) length));
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n",
@@ -222,7 +221,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
return_ACPI_STATUS(AE_AML_NO_OPERAND);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+ if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
/*
* If the buffer_field arguments have not been previously evaluated,
* evaluate them now and save the results.
@@ -233,9 +232,8 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
return_ACPI_STATUS(status);
}
}
- } else
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
- && (obj_desc->field.region_obj->region.space_id ==
+ } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+ (obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_SMBUS)) {
/*
* This is an SMBus write. We will bypass the entire field mechanism
@@ -243,7 +241,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
*
* Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE).
*/
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+ if (source_desc->common.type != ACPI_TYPE_BUFFER) {
ACPI_ERROR((AE_INFO,
"SMBus write requires Buffer, found type %s",
acpi_ut_get_object_type_name(source_desc)));
@@ -291,7 +289,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
/* Get a pointer to the data to be written */
- switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+ switch (source_desc->common.type) {
case ACPI_TYPE_INTEGER:
buffer = &source_desc->integer.value;
length = sizeof(source_desc->integer.value);
@@ -314,15 +312,14 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
source_desc,
- acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
- (source_desc)),
- ACPI_GET_OBJECT_TYPE(source_desc), buffer, length));
+ acpi_ut_get_type_name(source_desc->common.type),
+ source_desc->common.type, buffer, length));
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"FieldWrite [TO]: Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n",
obj_desc,
- acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)),
- ACPI_GET_OBJECT_TYPE(obj_desc),
+ acpi_ut_get_type_name(obj_desc->common.type),
+ obj_desc->common.type,
obj_desc->common_field.bit_length,
obj_desc->common_field.start_field_bit_offset,
obj_desc->common_field.base_byte_offset));
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c
index ef58ac4e687..99cee61e655 100644
--- a/drivers/acpi/acpica/exfldio.c
+++ b/drivers/acpi/acpica/exfldio.c
@@ -94,9 +94,9 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
/* We must have a valid region */
- if (ACPI_GET_OBJECT_TYPE(rgn_desc) != ACPI_TYPE_REGION) {
+ if (rgn_desc->common.type != ACPI_TYPE_REGION) {
ACPI_ERROR((AE_INFO, "Needed Region, found type %X (%s)",
- ACPI_GET_OBJECT_TYPE(rgn_desc),
+ rgn_desc->common.type,
acpi_ut_get_object_type_name(rgn_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -113,12 +113,6 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
}
}
- /* Exit if Address/Length have been disallowed by the host OS */
-
- if (rgn_desc->common.flags & AOPOBJ_INVALID) {
- return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
- }
-
/*
* Exit now for SMBus address space, it has a non-linear address space
* and the request cannot be directly validated
@@ -390,7 +384,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
* index_field - Write to an Index Register, then read/write from/to a
* Data Register
*/
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_BUFFER_FIELD:
/*
* If the buffer_field arguments have not been previously evaluated,
@@ -527,7 +521,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
default:
ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %X",
- ACPI_GET_OBJECT_TYPE(obj_desc)));
+ obj_desc->common.type));
status = AE_AML_INTERNAL;
break;
}
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c
index 6b0747ac683..998eac32993 100644
--- a/drivers/acpi/acpica/exmisc.c
+++ b/drivers/acpi/acpica/exmisc.c
@@ -80,7 +80,7 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
case ACPI_DESC_TYPE_OPERAND:
- if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) {
+ if (obj_desc->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
@@ -260,7 +260,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
* guaranteed to be either Integer/String/Buffer by the operand
* resolution mechanism.
*/
- switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+ switch (operand0->common.type) {
case ACPI_TYPE_INTEGER:
status =
acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
@@ -277,7 +277,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
default:
ACPI_ERROR((AE_INFO, "Invalid object type: %X",
- ACPI_GET_OBJECT_TYPE(operand0)));
+ operand0->common.type));
status = AE_AML_INTERNAL;
}
@@ -298,7 +298,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
* 2) Two Strings concatenated to produce a new String
* 3) Two Buffers concatenated to produce a new Buffer
*/
- switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+ switch (operand0->common.type) {
case ACPI_TYPE_INTEGER:
/* Result of two Integers is a Buffer */
@@ -379,7 +379,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
/* Invalid object type, should not happen here */
ACPI_ERROR((AE_INFO, "Invalid object type: %X",
- ACPI_GET_OBJECT_TYPE(operand0)));
+ operand0->common.type));
status = AE_AML_INTERNAL;
goto cleanup;
}
@@ -581,7 +581,7 @@ acpi_ex_do_logical_op(u16 opcode,
* guaranteed to be either Integer/String/Buffer by the operand
* resolution mechanism.
*/
- switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+ switch (operand0->common.type) {
case ACPI_TYPE_INTEGER:
status =
acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
@@ -608,7 +608,7 @@ acpi_ex_do_logical_op(u16 opcode,
/*
* Two cases: 1) Both Integers, 2) Both Strings or Buffers
*/
- if (ACPI_GET_OBJECT_TYPE(operand0) == ACPI_TYPE_INTEGER) {
+ if (operand0->common.type == ACPI_TYPE_INTEGER) {
/*
* 1) Both operands are of type integer
* Note: local_operand1 may have changed above
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c
index b530480cc7d..9635d21e568 100644
--- a/drivers/acpi/acpica/exoparg1.c
+++ b/drivers/acpi/acpica/exoparg1.c
@@ -807,11 +807,9 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
acpi_namespace_node *)
operand[0]);
if (temp_desc
- &&
- ((ACPI_GET_OBJECT_TYPE(temp_desc) ==
- ACPI_TYPE_STRING)
- || (ACPI_GET_OBJECT_TYPE(temp_desc) ==
- ACPI_TYPE_LOCAL_REFERENCE))) {
+ && ((temp_desc->common.type == ACPI_TYPE_STRING)
+ || (temp_desc->common.type ==
+ ACPI_TYPE_LOCAL_REFERENCE))) {
operand[0] = temp_desc;
acpi_ut_add_reference(temp_desc);
} else {
@@ -819,7 +817,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
goto cleanup;
}
} else {
- switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+ switch ((operand[0])->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
/*
* This is a deref_of (local_x | arg_x)
@@ -877,8 +875,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) !=
ACPI_DESC_TYPE_NAMED) {
- if (ACPI_GET_OBJECT_TYPE(operand[0]) ==
- ACPI_TYPE_STRING) {
+ if ((operand[0])->common.type == ACPI_TYPE_STRING) {
/*
* This is a deref_of (String). The string is a reference
* to a named ACPI object.
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c
index 0b4f513ca88..85d95c92dfd 100644
--- a/drivers/acpi/acpica/exoparg2.c
+++ b/drivers/acpi/acpica/exoparg2.c
@@ -399,7 +399,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
* At this point, the Source operand is a String, Buffer, or Package.
* Verify that the index is within range.
*/
- switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+ switch ((operand[0])->common.type) {
case ACPI_TYPE_STRING:
if (index >= operand[0]->string.length) {
diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c
index c6520bbf882..253f9e12258 100644
--- a/drivers/acpi/acpica/exoparg3.c
+++ b/drivers/acpi/acpica/exoparg3.c
@@ -161,9 +161,8 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
* Create the return object. The Source operand is guaranteed to be
* either a String or a Buffer, so just use its type.
*/
- return_desc =
- acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
- (operand[0]));
+ return_desc = acpi_ut_create_internal_object((operand[0])->
+ common.type);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -191,7 +190,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
/* Strings always have a sub-pointer, not so for buffers */
- switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+ switch ((operand[0])->common.type) {
case ACPI_TYPE_STRING:
/* Always allocate a new buffer for the String */
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c
index a226f74d4a5..52fec07064f 100644
--- a/drivers/acpi/acpica/exprep.c
+++ b/drivers/acpi/acpica/exprep.c
@@ -279,7 +279,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
return_UINT32(0);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+ if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
/*
* buffer_field access can be on any byte boundary, so the
* byte_alignment is always 1 byte -- regardless of any byte_alignment
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c
index 76ec8ff903b..3a54b737d2d 100644
--- a/drivers/acpi/acpica/exregion.c
+++ b/drivers/acpi/acpica/exregion.c
@@ -294,14 +294,14 @@ acpi_ex_system_io_space_handler(u32 function,
switch (function) {
case ACPI_READ:
- status = acpi_os_read_port((acpi_io_address) address,
+ status = acpi_hw_read_port((acpi_io_address) address,
&value32, bit_width);
*value = value32;
break;
case ACPI_WRITE:
- status = acpi_os_write_port((acpi_io_address) address,
+ status = acpi_hw_write_port((acpi_io_address) address,
(u32) * value, bit_width);
break;
diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c
index a063a74006f..607958ff467 100644
--- a/drivers/acpi/acpica/exresnte.c
+++ b/drivers/acpi/acpica/exresnte.c
@@ -136,7 +136,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
switch (entry_type) {
case ACPI_TYPE_PACKAGE:
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_PACKAGE) {
+ if (source_desc->common.type != ACPI_TYPE_PACKAGE) {
ACPI_ERROR((AE_INFO, "Object not a Package, type %s",
acpi_ut_get_object_type_name(source_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -154,7 +154,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
case ACPI_TYPE_BUFFER:
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+ if (source_desc->common.type != ACPI_TYPE_BUFFER) {
ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s",
acpi_ut_get_object_type_name(source_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -172,7 +172,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
case ACPI_TYPE_STRING:
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) {
+ if (source_desc->common.type != ACPI_TYPE_STRING) {
ACPI_ERROR((AE_INFO, "Object not a String, type %s",
acpi_ut_get_object_type_name(source_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -186,7 +186,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
case ACPI_TYPE_INTEGER:
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) {
+ if (source_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO, "Object not a Integer, type %s",
acpi_ut_get_object_type_name(source_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c
index f6105a6d612..c93b54ce7f7 100644
--- a/drivers/acpi/acpica/exresolv.c
+++ b/drivers/acpi/acpica/exresolv.c
@@ -149,7 +149,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
/* This is a union acpi_operand_object */
- switch (ACPI_GET_OBJECT_TYPE(stack_desc)) {
+ switch (stack_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
ref_type = stack_desc->reference.class;
@@ -297,8 +297,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"FieldRead SourceDesc=%p Type=%X\n",
- stack_desc,
- ACPI_GET_OBJECT_TYPE(stack_desc)));
+ stack_desc, stack_desc->common.type));
status =
acpi_ex_read_data_from_field(walk_state, stack_desc,
@@ -386,7 +385,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
* specification of the object_type and size_of operators). This means
* traversing the list of possibly many nested references.
*/
- while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
+ while (obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
switch (obj_desc->reference.class) {
case ACPI_REFCLASS_REFOF:
case ACPI_REFCLASS_NAME:
@@ -518,7 +517,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
* Now we are guaranteed to have an object that has not been created
* via the ref_of or Index operators.
*/
- type = ACPI_GET_OBJECT_TYPE(obj_desc);
+ type = obj_desc->common.type;
exit:
/* Convert internal types to external types */
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c
index 3c3802764bf..5c729a9e913 100644
--- a/drivers/acpi/acpica/exresop.c
+++ b/drivers/acpi/acpica/exresop.c
@@ -212,7 +212,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* ACPI internal object */
- object_type = ACPI_GET_OBJECT_TYPE(obj_desc);
+ object_type = obj_desc->common.type;
/* Check for bad acpi_object_type */
@@ -287,8 +287,7 @@ acpi_ex_resolve_operands(u16 opcode,
if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
ACPI_DESC_TYPE_OPERAND)
- && (ACPI_GET_OBJECT_TYPE(obj_desc) ==
- ACPI_TYPE_STRING)) {
+ && (obj_desc->common.type == ACPI_TYPE_STRING)) {
/*
* String found - the string references a named object and
* must be resolved to a node
@@ -336,7 +335,7 @@ acpi_ex_resolve_operands(u16 opcode,
* -- All others must be resolved below.
*/
if ((opcode == AML_STORE_OP) &&
- (ACPI_GET_OBJECT_TYPE(*stack_ptr) ==
+ ((*stack_ptr)->common.type ==
ACPI_TYPE_LOCAL_REFERENCE)
&& ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) {
goto next_operand;
@@ -490,7 +489,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Need an operand of type INTEGER, STRING or BUFFER */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -512,7 +511,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Need an operand of type STRING or BUFFER */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -553,7 +552,7 @@ acpi_ex_resolve_operands(u16 opcode,
* The only reference allowed here is a direct reference to
* a namespace node.
*/
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_PACKAGE:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -576,7 +575,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Need a buffer or package or (ACPI 2.0) String */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_PACKAGE:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -598,7 +597,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_BUFFER:
case ACPI_TYPE_REGION:
@@ -619,7 +618,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Used by the Store() operator only */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
case ACPI_TYPE_PACKAGE:
case ACPI_TYPE_STRING:
@@ -677,8 +676,8 @@ acpi_ex_resolve_operands(u16 opcode,
* required object type (Simple cases only).
*/
status = acpi_ex_check_object_type(type_needed,
- ACPI_GET_OBJECT_TYPE
- (*stack_ptr), *stack_ptr);
+ (*stack_ptr)->common.type,
+ *stack_ptr);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c
index e35e9b4f6a4..90d606196c9 100644
--- a/drivers/acpi/acpica/exstore.c
+++ b/drivers/acpi/acpica/exstore.c
@@ -129,7 +129,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
/* source_desc is of type ACPI_DESC_TYPE_OPERAND */
- switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+ switch (source_desc->common.type) {
case ACPI_TYPE_INTEGER:
/* Output correct integer width */
@@ -324,7 +324,7 @@ acpi_ex_store(union acpi_operand_object *source_desc,
/* Destination object must be a Reference or a Constant object */
- switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+ switch (dest_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
break;
@@ -460,9 +460,8 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
*/
obj_desc = *(index_desc->reference.where);
- if (ACPI_GET_OBJECT_TYPE(source_desc) ==
- ACPI_TYPE_LOCAL_REFERENCE
- && source_desc->reference.class == ACPI_REFCLASS_TABLE) {
+ if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
+ source_desc->reference.class == ACPI_REFCLASS_TABLE) {
/* This is a DDBHandle, just add a reference to it */
@@ -520,8 +519,8 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
* by the INDEX_OP code.
*/
obj_desc = index_desc->reference.object;
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_BUFFER) &&
- (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_STRING)) {
+ if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
+ (obj_desc->common.type != ACPI_TYPE_STRING)) {
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
@@ -529,7 +528,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
* The assignment of the individual elements will be slightly
* different for each source type.
*/
- switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+ switch (source_desc->common.type) {
case ACPI_TYPE_INTEGER:
/* Use the least-significant byte of the integer */
@@ -707,8 +706,7 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
/* No conversions for all other types. Just attach the source object */
status = acpi_ns_attach_object(node, source_desc,
- ACPI_GET_OBJECT_TYPE
- (source_desc));
+ source_desc->common.type);
break;
}
diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c
index 145d15305f7..608e838d537 100644
--- a/drivers/acpi/acpica/exstoren.c
+++ b/drivers/acpi/acpica/exstoren.c
@@ -96,8 +96,7 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
* are all essentially the same. This case handles the
* "interchangeable" types Integer, String, and Buffer.
*/
- if (ACPI_GET_OBJECT_TYPE(source_desc) ==
- ACPI_TYPE_LOCAL_REFERENCE) {
+ if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
/* Resolve a reference object first */
@@ -117,13 +116,11 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
/* Must have a Integer, Buffer, or String */
- if ((ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) &&
- (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) &&
- (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) &&
- !((ACPI_GET_OBJECT_TYPE(source_desc) ==
- ACPI_TYPE_LOCAL_REFERENCE)
- && (source_desc->reference.class ==
- ACPI_REFCLASS_TABLE))) {
+ if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&
+ (source_desc->common.type != ACPI_TYPE_BUFFER) &&
+ (source_desc->common.type != ACPI_TYPE_STRING) &&
+ !((source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
+ (source_desc->reference.class == ACPI_REFCLASS_TABLE))) {
/* Conversion successful but still not a valid type */
@@ -218,8 +215,7 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
return_ACPI_STATUS(status);
}
- if (ACPI_GET_OBJECT_TYPE(source_desc) !=
- ACPI_GET_OBJECT_TYPE(dest_desc)) {
+ if (source_desc->common.type != dest_desc->common.type) {
/*
* The source type does not match the type of the destination.
* Perform the "implicit conversion" of the source to the current type
@@ -229,11 +225,10 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
* Otherwise, actual_src_desc is a temporary object to hold the
* converted object.
*/
- status =
- acpi_ex_convert_to_target_type(ACPI_GET_OBJECT_TYPE
- (dest_desc), source_desc,
- &actual_src_desc,
- walk_state);
+ status = acpi_ex_convert_to_target_type(dest_desc->common.type,
+ source_desc,
+ &actual_src_desc,
+ walk_state);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -252,7 +247,7 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
* We now have two objects of identical types, and we can perform a
* copy of the *value* of the source object.
*/
- switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+ switch (dest_desc->common.type) {
case ACPI_TYPE_INTEGER:
dest_desc->integer.value = actual_src_desc->integer.value;
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c
index 32b85d68e75..87730e94413 100644
--- a/drivers/acpi/acpica/exutils.c
+++ b/drivers/acpi/acpica/exutils.c
@@ -221,7 +221,7 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
*/
if ((!obj_desc) ||
(ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) ||
- (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
+ (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
return;
}
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c
index a9d4fea4167..9af361a191e 100644
--- a/drivers/acpi/acpica/hwacpi.c
+++ b/drivers/acpi/acpica/hwacpi.c
@@ -86,7 +86,8 @@ acpi_status acpi_hw_set_mode(u32 mode)
*/
if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
ACPI_ERROR((AE_INFO,
- "No ACPI mode transition supported in this system (enable/disable both zero)"));
+ "No ACPI mode transition supported in this system "
+ "(enable/disable both zero)"));
return_ACPI_STATUS(AE_OK);
}
@@ -95,7 +96,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
/* BIOS should have disabled ALL fixed and GP events */
- status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+ status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.acpi_enable, 8);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Attempting to enable ACPI mode\n"));
@@ -107,7 +108,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
* BIOS should clear all fixed status bits and restore fixed event
* enable bits to default
*/
- status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+ status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.acpi_disable,
8);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -172,7 +173,7 @@ u32 acpi_hw_get_mode(void)
return_UINT32(ACPI_SYS_MODE_ACPI);
}
- status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value);
+ status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
if (ACPI_FAILURE(status)) {
return_UINT32(ACPI_SYS_MODE_LEGACY);
}
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index 2013b66745d..d3b7e37c9ee 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -89,10 +89,9 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
/* Clear just the bit that corresponds to this GPE */
- ACPI_CLEAR_BIT(enable_mask,
- ((u32) 1 <<
- (gpe_event_info->gpe_number -
- gpe_register_info->base_gpe_number)));
+ ACPI_CLEAR_BIT(enable_mask, ((u32)1 <<
+ (gpe_event_info->gpe_number -
+ gpe_register_info->base_gpe_number)));
/* Write the updated enable mask */
@@ -156,10 +155,9 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
ACPI_FUNCTION_ENTRY();
- register_bit = (u8)
- (1 <<
- (gpe_event_info->gpe_number -
- gpe_event_info->register_info->base_gpe_number));
+ register_bit = (u8)(1 <<
+ (gpe_event_info->gpe_number -
+ gpe_event_info->register_info->base_gpe_number));
/*
* Write a one to the appropriate bit in the status register to
@@ -206,10 +204,9 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
/* Get the register bitmask for this GPE */
- register_bit = (u8)
- (1 <<
- (gpe_event_info->gpe_number -
- gpe_event_info->register_info->base_gpe_number));
+ register_bit = (u8)(1 <<
+ (gpe_event_info->gpe_number -
+ gpe_event_info->register_info->base_gpe_number));
/* GPE currently enabled? (enabled for runtime?) */
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c
index 4dc43b01851..7b2fb602b5c 100644
--- a/drivers/acpi/acpica/hwregs.c
+++ b/drivers/acpi/acpica/hwregs.c
@@ -51,6 +51,17 @@
#define _COMPONENT ACPI_HARDWARE
ACPI_MODULE_NAME("hwregs")
+/* Local Prototypes */
+static acpi_status
+acpi_hw_read_multiple(u32 *value,
+ struct acpi_generic_address *register_a,
+ struct acpi_generic_address *register_b);
+
+static acpi_status
+acpi_hw_write_multiple(u32 value,
+ struct acpi_generic_address *register_a,
+ struct acpi_generic_address *register_b);
+
/*******************************************************************************
*
* FUNCTION: acpi_hw_clear_acpi_status
@@ -60,9 +71,9 @@ ACPI_MODULE_NAME("hwregs")
* RETURN: Status
*
* DESCRIPTION: Clears all fixed and general purpose status bits
- * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
*
******************************************************************************/
+
acpi_status acpi_hw_clear_acpi_status(void)
{
acpi_status status;
@@ -70,28 +81,20 @@ acpi_status acpi_hw_clear_acpi_status(void)
ACPI_FUNCTION_TRACE(hw_clear_acpi_status);
- ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n",
+ ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n",
ACPI_BITMASK_ALL_FIXED_STATUS,
- (u16) acpi_gbl_FADT.xpm1a_event_block.address));
+ acpi_gbl_xpm1a_status.address));
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
+ /* Clear the fixed events in PM1 A/B */
+
status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
ACPI_BITMASK_ALL_FIXED_STATUS);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
- /* Clear the fixed events */
-
- if (acpi_gbl_FADT.xpm1b_event_block.address) {
- status = acpi_write(ACPI_BITMASK_ALL_FIXED_STATUS,
- &acpi_gbl_FADT.xpm1b_event_block);
- if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
- }
- }
-
/* Clear the GPE Bits in all GPE registers in all GPE blocks */
status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
@@ -128,6 +131,42 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
/******************************************************************************
*
+ * FUNCTION: acpi_hw_write_pm1_control
+ *
+ * PARAMETERS: pm1a_control - Value to be written to PM1A control
+ * pm1b_control - Value to be written to PM1B control
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write the PM1 A/B control registers. These registers are
+ * different than than the PM1 A/B status and enable registers
+ * in that different values can be written to the A/B registers.
+ * Most notably, the SLP_TYP bits can be different, as per the
+ * values returned from the _Sx predefined methods.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(hw_write_pm1_control);
+
+ status = acpi_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ if (acpi_gbl_FADT.xpm1b_control_block.address) {
+ status =
+ acpi_write(pm1b_control,
+ &acpi_gbl_FADT.xpm1b_control_block);
+ }
+ return_ACPI_STATUS(status);
+}
+
+/******************************************************************************
+ *
* FUNCTION: acpi_hw_register_read
*
* PARAMETERS: register_id - ACPI Register ID
@@ -141,64 +180,56 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
acpi_status
acpi_hw_register_read(u32 register_id, u32 * return_value)
{
- u32 value1 = 0;
- u32 value2 = 0;
+ u32 value = 0;
acpi_status status;
ACPI_FUNCTION_TRACE(hw_register_read);
switch (register_id) {
- case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
-
- status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_event_block);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* PM1B is optional */
+ case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
- status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_event_block);
- value1 |= value2;
+ status = acpi_hw_read_multiple(&value,
+ &acpi_gbl_xpm1a_status,
+ &acpi_gbl_xpm1b_status);
break;
- case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
+ case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */
- status = acpi_read(&value1, &acpi_gbl_xpm1a_enable);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* PM1B is optional */
-
- status = acpi_read(&value2, &acpi_gbl_xpm1b_enable);
- value1 |= value2;
+ status = acpi_hw_read_multiple(&value,
+ &acpi_gbl_xpm1a_enable,
+ &acpi_gbl_xpm1b_enable);
break;
- case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
+ case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
- status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_control_block);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
+ status = acpi_hw_read_multiple(&value,
+ &acpi_gbl_FADT.
+ xpm1a_control_block,
+ &acpi_gbl_FADT.
+ xpm1b_control_block);
- status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_control_block);
- value1 |= value2;
+ /*
+ * Zero the write-only bits. From the ACPI specification, "Hardware
+ * Write-Only Bits": "Upon reads to registers with write-only bits,
+ * software masks out all write-only bits."
+ */
+ value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
break;
case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
- status = acpi_read(&value1, &acpi_gbl_FADT.xpm2_control_block);
+ status = acpi_read(&value, &acpi_gbl_FADT.xpm2_control_block);
break;
case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
- status = acpi_read(&value1, &acpi_gbl_FADT.xpm_timer_block);
+ status = acpi_read(&value, &acpi_gbl_FADT.xpm_timer_block);
break;
case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
status =
- acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8);
+ acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8);
break;
default:
@@ -207,10 +238,8 @@ acpi_hw_register_read(u32 register_id, u32 * return_value)
break;
}
- exit:
-
if (ACPI_SUCCESS(status)) {
- *return_value = value1;
+ *return_value = value;
}
return_ACPI_STATUS(status);
@@ -250,52 +279,42 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
ACPI_FUNCTION_TRACE(hw_register_write);
switch (register_id) {
- case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
-
- /* Perform a read first to preserve certain bits (per ACPI spec) */
-
- status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
- &read_value);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* Insert the bits to be preserved */
-
- ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS,
- read_value);
-
- /* Now we can write the data */
-
- status = acpi_write(value, &acpi_gbl_FADT.xpm1a_event_block);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* PM1B is optional */
+ case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
+ /*
+ * Handle the "ignored" bit in PM1 Status. According to the ACPI
+ * specification, ignored bits are to be preserved when writing.
+ * Normally, this would mean a read/modify/write sequence. However,
+ * preserving a bit in the status register is different. Writing a
+ * one clears the status, and writing a zero preserves the status.
+ * Therefore, we must always write zero to the ignored bit.
+ *
+ * This behavior is clarified in the ACPI 4.0 specification.
+ */
+ value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
- status = acpi_write(value, &acpi_gbl_FADT.xpm1b_event_block);
+ status = acpi_hw_write_multiple(value,
+ &acpi_gbl_xpm1a_status,
+ &acpi_gbl_xpm1b_status);
break;
- case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
+ case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access */
- status = acpi_write(value, &acpi_gbl_xpm1a_enable);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* PM1B is optional */
-
- status = acpi_write(value, &acpi_gbl_xpm1b_enable);
+ status = acpi_hw_write_multiple(value,
+ &acpi_gbl_xpm1a_enable,
+ &acpi_gbl_xpm1b_enable);
break;
- case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
+ case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
/*
* Perform a read first to preserve certain bits (per ACPI spec)
+ * Note: This includes SCI_EN, we never want to change this bit
*/
- status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
- &read_value);
+ status = acpi_hw_read_multiple(&read_value,
+ &acpi_gbl_FADT.
+ xpm1a_control_block,
+ &acpi_gbl_FADT.
+ xpm1b_control_block);
if (ACPI_FAILURE(status)) {
goto exit;
}
@@ -307,25 +326,29 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
/* Now we can write the data */
- status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
+ status = acpi_hw_write_multiple(value,
+ &acpi_gbl_FADT.
+ xpm1a_control_block,
+ &acpi_gbl_FADT.
+ xpm1b_control_block);
break;
- case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */
-
- status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
- break;
+ case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
- case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */
+ /*
+ * For control registers, all reserved bits must be preserved,
+ * as per the ACPI spec.
+ */
+ status =
+ acpi_read(&read_value, &acpi_gbl_FADT.xpm2_control_block);
+ if (ACPI_FAILURE(status)) {
+ goto exit;
+ }
- status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
- break;
+ /* Insert the bits to be preserved */
- case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
+ ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS,
+ read_value);
status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block);
break;
@@ -340,10 +363,11 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
/* SMI_CMD is currently always in IO space */
status =
- acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8);
+ acpi_hw_write_port(acpi_gbl_FADT.smi_command, value, 8);
break;
default:
+ ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id));
status = AE_BAD_PARAMETER;
break;
}
@@ -351,3 +375,103 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
exit:
return_ACPI_STATUS(status);
}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_read_multiple
+ *
+ * PARAMETERS: Value - Where the register value is returned
+ * register_a - First ACPI register (required)
+ * register_b - Second ACPI register (optional)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_read_multiple(u32 *value,
+ struct acpi_generic_address *register_a,
+ struct acpi_generic_address *register_b)
+{
+ u32 value_a = 0;
+ u32 value_b = 0;
+ acpi_status status;
+
+ /* The first register is always required */
+
+ status = acpi_read(&value_a, register_a);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ /* Second register is optional */
+
+ if (register_b->address) {
+ status = acpi_read(&value_b, register_b);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+ }
+
+ /*
+ * OR the two return values together. No shifting or masking is necessary,
+ * because of how the PM1 registers are defined in the ACPI specification:
+ *
+ * "Although the bits can be split between the two register blocks (each
+ * register block has a unique pointer within the FADT), the bit positions
+ * are maintained. The register block with unimplemented bits (that is,
+ * those implemented in the other register block) always returns zeros,
+ * and writes have no side effects"
+ */
+ *value = (value_a | value_b);
+ return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_write_multiple
+ *
+ * PARAMETERS: Value - The value to write
+ * register_a - First ACPI register (required)
+ * register_b - Second ACPI register (optional)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_write_multiple(u32 value,
+ struct acpi_generic_address *register_a,
+ struct acpi_generic_address *register_b)
+{
+ acpi_status status;
+
+ /* The first register is always required */
+
+ status = acpi_write(value, register_a);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ /*
+ * Second register is optional
+ *
+ * No bit shifting or clearing is necessary, because of how the PM1
+ * registers are defined in the ACPI specification:
+ *
+ * "Although the bits can be split between the two register blocks (each
+ * register block has a unique pointer within the FADT), the bit positions
+ * are maintained. The register block with unimplemented bits (that is,
+ * those implemented in the other register block) always returns zeros,
+ * and writes have no side effects"
+ */
+ if (register_b->address) {
+ status = acpi_write(value, register_b);
+ }
+
+ return (status);
+}
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
index a2af2a4f2f2..baa5fc05e12 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -90,6 +90,7 @@ acpi_set_firmware_waking_vector(u32 physical_address)
ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
+#if ACPI_MACHINE_WIDTH == 64
/*******************************************************************************
*
* FUNCTION: acpi_set_firmware_waking_vector64
@@ -100,7 +101,8 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
* RETURN: Status
*
* DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if
- * it exists in the table.
+ * it exists in the table. This function is intended for use with
+ * 64-bit host operating systems.
*
******************************************************************************/
acpi_status
@@ -124,6 +126,7 @@ acpi_set_firmware_waking_vector64(u64 physical_address)
}
ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64)
+#endif
/*******************************************************************************
*
@@ -147,9 +150,8 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
- /*
- * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
- */
+ /* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */
+
status = acpi_get_sleep_type_data(sleep_state,
&acpi_gbl_sleep_type_a,
&acpi_gbl_sleep_type_b);
@@ -223,8 +225,8 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
******************************************************************************/
acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
{
- u32 PM1Acontrol;
- u32 PM1Bcontrol;
+ u32 pm1a_control;
+ u32 pm1b_control;
struct acpi_bit_register_info *sleep_type_reg_info;
struct acpi_bit_register_info *sleep_enable_reg_info;
u32 in_value;
@@ -242,13 +244,14 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
}
sleep_type_reg_info =
- acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+ acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
sleep_enable_reg_info =
acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
/* Clear wake status */
- status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+ status =
+ acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -289,24 +292,25 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Get current value of PM1A control */
- status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+ status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
+ &pm1a_control);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
ACPI_DEBUG_PRINT((ACPI_DB_INIT,
"Entering sleep state [S%d]\n", sleep_state));
- /* Clear SLP_EN and SLP_TYP fields */
+ /* Clear the SLP_EN and SLP_TYP fields */
- PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
- sleep_enable_reg_info->access_bit_mask);
- PM1Bcontrol = PM1Acontrol;
+ pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
+ sleep_enable_reg_info->access_bit_mask);
+ pm1b_control = pm1a_control;
- /* Insert SLP_TYP bits */
+ /* Insert the SLP_TYP bits */
- PM1Acontrol |=
+ pm1a_control |=
(acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
- PM1Bcontrol |=
+ pm1b_control |=
(acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
/*
@@ -314,37 +318,25 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
* poorly implemented hardware.
*/
- /* Write #1: fill in SLP_TYP data */
+ /* Write #1: write the SLP_TYP data to the PM1 Control registers */
- status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
- PM1Acontrol);
+ status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
- PM1Bcontrol);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
+ /* Insert the sleep enable (SLP_EN) bit */
- /* Insert SLP_ENABLE bit */
+ pm1a_control |= sleep_enable_reg_info->access_bit_mask;
+ pm1b_control |= sleep_enable_reg_info->access_bit_mask;
- PM1Acontrol |= sleep_enable_reg_info->access_bit_mask;
- PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask;
-
- /* Write #2: SLP_TYP + SLP_EN */
+ /* Flush caches, as per ACPI specification */
ACPI_FLUSH_CPU_CACHE();
- status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
- PM1Acontrol);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
+ /* Write #2: Write both SLP_TYP + SLP_EN */
- status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
- PM1Bcontrol);
+ status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -357,8 +349,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
* Wait ten seconds, then try again. This is to get S4/S5 to work on
* all machines.
*
- * We wait so long to allow chipsets that poll this reg very slowly to
- * still read the right value. Ideally, this block would go
+ * We wait so long to allow chipsets that poll this reg very slowly
+ * to still read the right value. Ideally, this block would go
* away entirely.
*/
acpi_os_stall(10000000);
@@ -374,7 +366,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Wait until we enter sleep state */
do {
- status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
+ status = acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS,
&in_value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
@@ -408,7 +400,10 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
- status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+ /* Clear the wake status bit (PM1) */
+
+ status =
+ acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -435,12 +430,13 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
ACPI_FLUSH_CPU_CACHE();
- status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+ status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.S4bios_request, 8);
do {
acpi_os_stall(1000);
- status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
+ status =
+ acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -471,8 +467,8 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
acpi_status status;
struct acpi_bit_register_info *sleep_type_reg_info;
struct acpi_bit_register_info *sleep_enable_reg_info;
- u32 PM1Acontrol;
- u32 PM1Bcontrol;
+ u32 pm1a_control;
+ u32 pm1b_control;
ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
@@ -486,38 +482,34 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
&acpi_gbl_sleep_type_b);
if (ACPI_SUCCESS(status)) {
sleep_type_reg_info =
- acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+ acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
sleep_enable_reg_info =
acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
/* Get current value of PM1A control */
status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
- &PM1Acontrol);
+ &pm1a_control);
if (ACPI_SUCCESS(status)) {
- /* Clear SLP_EN and SLP_TYP fields */
+ /* Clear the SLP_EN and SLP_TYP fields */
- PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
- sleep_enable_reg_info->
- access_bit_mask);
- PM1Bcontrol = PM1Acontrol;
+ pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
+ sleep_enable_reg_info->
+ access_bit_mask);
+ pm1b_control = pm1a_control;
- /* Insert SLP_TYP bits */
+ /* Insert the SLP_TYP bits */
- PM1Acontrol |=
- (acpi_gbl_sleep_type_a << sleep_type_reg_info->
- bit_position);
- PM1Bcontrol |=
- (acpi_gbl_sleep_type_b << sleep_type_reg_info->
- bit_position);
+ pm1a_control |= (acpi_gbl_sleep_type_a <<
+ sleep_type_reg_info->bit_position);
+ pm1b_control |= (acpi_gbl_sleep_type_b <<
+ sleep_type_reg_info->bit_position);
- /* Just ignore any errors */
+ /* Write the control registers and ignore any errors */
- (void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
- PM1Acontrol);
- (void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
- PM1Bcontrol);
+ (void)acpi_hw_write_pm1_control(pm1a_control,
+ pm1b_control);
}
}
@@ -603,19 +595,21 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
* it to determine whether the system is rebooting or resuming. Clear
* it for compatibility.
*/
- acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+ acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1);
acpi_gbl_system_awake_and_running = TRUE;
/* Enable power button */
(void)
- acpi_set_register(acpi_gbl_fixed_event_info
- [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info
+ [ACPI_EVENT_POWER_BUTTON].
+ enable_register_id, ACPI_ENABLE_EVENT);
(void)
- acpi_set_register(acpi_gbl_fixed_event_info
- [ACPI_EVENT_POWER_BUTTON].status_register_id, 1);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info
+ [ACPI_EVENT_POWER_BUTTON].
+ status_register_id, ACPI_CLEAR_STATUS);
arg.integer.value = ACPI_SST_WORKING;
status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
new file mode 100644
index 00000000000..7737afb157c
--- /dev/null
+++ b/drivers/acpi/acpica/hwvalid.c
@@ -0,0 +1,257 @@
+
+/******************************************************************************
+ *
+ * Module Name: hwvalid - I/O request validation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2009, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT ACPI_HARDWARE
+ACPI_MODULE_NAME("hwvalid")
+
+/* Local prototypes */
+static acpi_status
+acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width);
+
+/*
+ * Protected I/O ports. Some ports are always illegal, and some are
+ * conditionally illegal. This table must remain ordered by port address.
+ *
+ * The table is used to implement the Microsoft port access rules that
+ * first appeared in Windows XP. Some ports are always illegal, and some
+ * ports are only illegal if the BIOS calls _OSI with a win_xP string or
+ * later (meaning that the BIOS itelf is post-XP.)
+ *
+ * This provides ACPICA with the desired port protections and
+ * Microsoft compatibility.
+ *
+ * Description of port entries:
+ * DMA: DMA controller
+ * PIC0: Programmable Interrupt Controller (8259_a)
+ * PIT1: System Timer 1
+ * PIT2: System Timer 2 failsafe
+ * RTC: Real-time clock
+ * CMOS: Extended CMOS
+ * DMA1: DMA 1 page registers
+ * DMA1L: DMA 1 Ch 0 low page
+ * DMA2: DMA 2 page registers
+ * DMA2L: DMA 2 low page refresh
+ * ARBC: Arbitration control
+ * SETUP: Reserved system board setup
+ * POS: POS channel select
+ * PIC1: Cascaded PIC
+ * IDMA: ISA DMA
+ * ELCR: PIC edge/level registers
+ * PCI: PCI configuration space
+ */
+static const struct acpi_port_info acpi_protected_ports[] = {
+ {"DMA", 0x0000, 0x000F, ACPI_OSI_WIN_XP},
+ {"PIC0", 0x0020, 0x0021, ACPI_ALWAYS_ILLEGAL},
+ {"PIT1", 0x0040, 0x0043, ACPI_OSI_WIN_XP},
+ {"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP},
+ {"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP},
+ {"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP},
+ {"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP},
+ {"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP},
+ {"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP},
+ {"ARBC", 0x0090, 0x0091, ACPI_OSI_WIN_XP},
+ {"SETUP", 0x0093, 0x0094, ACPI_OSI_WIN_XP},
+ {"POS", 0x0096, 0x0097, ACPI_OSI_WIN_XP},
+ {"PIC1", 0x00A0, 0x00A1, ACPI_ALWAYS_ILLEGAL},
+ {"IDMA", 0x00C0, 0x00DF, ACPI_OSI_WIN_XP},
+ {"ELCR", 0x04D0, 0x04D1, ACPI_ALWAYS_ILLEGAL},
+ {"PCI", 0x0CF8, 0x0CFF, ACPI_OSI_WIN_XP}
+};
+
+#define ACPI_PORT_INFO_ENTRIES ACPI_ARRAY_LENGTH (acpi_protected_ports)
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_validate_io_request
+ *
+ * PARAMETERS: Address Address of I/O port/register
+ * bit_width Number of bits (8,16,32)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Validates an I/O request (address/length). Certain ports are
+ * always illegal and some ports are only illegal depending on
+ * the requests the BIOS AML code makes to the predefined
+ * _OSI method.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
+{
+ u32 i;
+ u32 byte_width;
+ acpi_io_address last_address;
+ const struct acpi_port_info *port_info;
+
+ ACPI_FUNCTION_TRACE(hw_validate_io_request);
+
+ /* Supported widths are 8/16/32 */
+
+ if ((bit_width != 8) && (bit_width != 16) && (bit_width != 32)) {
+ return AE_BAD_PARAMETER;
+ }
+
+ port_info = acpi_protected_ports;
+ byte_width = ACPI_DIV_8(bit_width);
+ last_address = address + byte_width - 1;
+
+ ACPI_DEBUG_PRINT((ACPI_DB_IO, "Address %p LastAddress %p Length %X",
+ ACPI_CAST_PTR(void, address), ACPI_CAST_PTR(void,
+ last_address),
+ byte_width));
+
+ /* Maximum 16-bit address in I/O space */
+
+ if (last_address > ACPI_UINT16_MAX) {
+ ACPI_ERROR((AE_INFO,
+ "Illegal I/O port address/length above 64K: 0x%p/%X",
+ ACPI_CAST_PTR(void, address), byte_width));
+ return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+ }
+
+ /* Exit if requested address is not within the protected port table */
+
+ if (address > acpi_protected_ports[ACPI_PORT_INFO_ENTRIES - 1].end) {
+ return_ACPI_STATUS(AE_OK);
+ }
+
+ /* Check request against the list of protected I/O ports */
+
+ for (i = 0; i < ACPI_PORT_INFO_ENTRIES; i++, port_info++) {
+ /*
+ * Check if the requested address range will write to a reserved
+ * port. Four cases to consider:
+ *
+ * 1) Address range is contained completely in the port address range
+ * 2) Address range overlaps port range at the port range start
+ * 3) Address range overlaps port range at the port range end
+ * 4) Address range completely encompasses the port range
+ */
+ if ((address <= port_info->end)
+ && (last_address >= port_info->start)) {
+
+ /* Port illegality may depend on the _OSI calls made by the BIOS */
+
+ if (acpi_gbl_osi_data >= port_info->osi_dependency) {
+ ACPI_ERROR((AE_INFO,
+ "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)",
+ ACPI_CAST_PTR(void, address),
+ byte_width, port_info->name,
+ port_info->start, port_info->end));
+
+ return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+ }
+ }
+
+ /* Finished if address range ends before the end of this port */
+
+ if (last_address <= port_info->end) {
+ break;
+ }
+ }
+
+ return_ACPI_STATUS(AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_read_port
+ *
+ * PARAMETERS: Address Address of I/O port/register to read
+ * Value Where value is placed
+ * Width Number of bits
+ *
+ * RETURN: Value read from port
+ *
+ * DESCRIPTION: Read data from an I/O port or register. This is a front-end
+ * to acpi_os_read_port that performs validation on both the port
+ * address and the length.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
+{
+ acpi_status status;
+
+ status = acpi_hw_validate_io_request(address, width);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ status = acpi_os_read_port(address, value, width);
+ return status;
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_write_port
+ *
+ * PARAMETERS: Address Address of I/O port/register to write
+ * Value Value to write
+ * Width Number of bits
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Write data to an I/O port or register. This is a front-end
+ * to acpi_os_write_port that performs validation on both the port
+ * address and the length.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
+{
+ acpi_status status;
+
+ status = acpi_hw_validate_io_request(address, width);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ status = acpi_os_write_port(address, value, width);
+ return status;
+}
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index ae597c0ab53..9829979f2bd 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -107,19 +107,18 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg)
ACPI_FUNCTION_NAME(acpi_read);
/*
- * Must have a valid pointer to a GAS structure, and
- * a non-zero address within. However, don't return an error
- * because the PM1A/B code must not fail if B isn't present.
+ * Must have a valid pointer to a GAS structure, and a non-zero address
+ * within.
*/
if (!reg) {
- return (AE_OK);
+ return (AE_BAD_PARAMETER);
}
/* Get a local copy of the address. Handles possible alignment issues */
ACPI_MOVE_64_TO_64(&address, &reg->address);
if (!address) {
- return (AE_OK);
+ return (AE_BAD_ADDRESS);
}
/* Supported widths are 8/16/32 */
@@ -134,8 +133,8 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg)
*value = 0;
/*
- * Two address spaces supported: Memory or IO.
- * PCI_Config is not supported here because the GAS struct is insufficient
+ * Two address spaces supported: Memory or IO. PCI_Config is
+ * not supported here because the GAS structure is insufficient
*/
switch (reg->space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
@@ -147,7 +146,7 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg)
case ACPI_ADR_SPACE_SYSTEM_IO:
status =
- acpi_os_read_port((acpi_io_address) address, value, width);
+ acpi_hw_read_port((acpi_io_address) address, value, width);
break;
default:
@@ -187,19 +186,18 @@ acpi_status acpi_write(u32 value, struct acpi_generic_address *reg)
ACPI_FUNCTION_NAME(acpi_write);
/*
- * Must have a valid pointer to a GAS structure, and
- * a non-zero address within. However, don't return an error
- * because the PM1A/B code must not fail if B isn't present.
+ * Must have a valid pointer to a GAS structure, and a non-zero address
+ * within.
*/
if (!reg) {
- return (AE_OK);
+ return (AE_BAD_PARAMETER);
}
/* Get a local copy of the address. Handles possible alignment issues */
ACPI_MOVE_64_TO_64(&address, &reg->address);
if (!address) {
- return (AE_OK);
+ return (AE_BAD_ADDRESS);
}
/* Supported widths are 8/16/32 */
@@ -222,7 +220,7 @@ acpi_status acpi_write(u32 value, struct acpi_generic_address *reg)
case ACPI_ADR_SPACE_SYSTEM_IO:
- status = acpi_os_write_port((acpi_io_address) address, value,
+ status = acpi_hw_write_port((acpi_io_address) address, value,
width);
break;
@@ -244,24 +242,36 @@ ACPI_EXPORT_SYMBOL(acpi_write)
/*******************************************************************************
*
- * FUNCTION: acpi_get_register_unlocked
+ * FUNCTION: acpi_read_bit_register
*
- * PARAMETERS: register_id - ID of ACPI bit_register to access
- * return_value - Value that was read from the register
+ * PARAMETERS: register_id - ID of ACPI Bit Register to access
+ * return_value - Value that was read from the register,
+ * normalized to bit position zero.
*
- * RETURN: Status and the value read from specified Register. Value
+ * RETURN: Status and the value read from the specified Register. Value
* returned is normalized to bit0 (is shifted all the way right)
*
* DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock.
*
+ * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ * PM2 Control.
+ *
+ * Note: The hardware lock is not required when reading the ACPI bit registers
+ * since almost all of them are single bit and it does not matter that
+ * the parent hardware register can be split across two physical
+ * registers. The only multi-bit field is SLP_TYP in the PM1 control
+ * register, but this field does not cross an 8-bit boundary (nor does
+ * it make much sense to actually read this field.)
+ *
******************************************************************************/
-acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value)
+acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value)
{
- u32 register_value = 0;
struct acpi_bit_register_info *bit_reg_info;
+ u32 register_value;
+ u32 value;
acpi_status status;
- ACPI_FUNCTION_TRACE(acpi_get_register_unlocked);
+ ACPI_FUNCTION_TRACE_U32(acpi_read_bit_register, register_id);
/* Get the info structure corresponding to the requested ACPI Register */
@@ -270,209 +280,133 @@ acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value)
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- /* Read from the register */
+ /* Read the entire parent register */
status = acpi_hw_register_read(bit_reg_info->parent_register,
&register_value);
-
- if (ACPI_SUCCESS(status)) {
-
- /* Normalize the value that was read */
-
- register_value =
- ((register_value & bit_reg_info->access_bit_mask)
- >> bit_reg_info->bit_position);
-
- *return_value = register_value;
-
- ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n",
- register_value,
- bit_reg_info->parent_register));
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- return_ACPI_STATUS(status);
-}
+ /* Normalize the value that was read, mask off other bits */
-ACPI_EXPORT_SYMBOL(acpi_get_register_unlocked)
+ value = ((register_value & bit_reg_info->access_bit_mask)
+ >> bit_reg_info->bit_position);
-/*******************************************************************************
- *
- * FUNCTION: acpi_get_register
- *
- * PARAMETERS: register_id - ID of ACPI bit_register to access
- * return_value - Value that was read from the register
- *
- * RETURN: Status and the value read from specified Register. Value
- * returned is normalized to bit0 (is shifted all the way right)
- *
- * DESCRIPTION: ACPI bit_register read function.
- *
- ******************************************************************************/
-acpi_status acpi_get_register(u32 register_id, u32 *return_value)
-{
- acpi_status status;
- acpi_cpu_flags flags;
-
- flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
- status = acpi_get_register_unlocked(register_id, return_value);
- acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
+ ACPI_DEBUG_PRINT((ACPI_DB_IO,
+ "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
+ register_id, bit_reg_info->parent_register,
+ register_value, value));
- return (status);
+ *return_value = value;
+ return_ACPI_STATUS(AE_OK);
}
-ACPI_EXPORT_SYMBOL(acpi_get_register)
+ACPI_EXPORT_SYMBOL(acpi_read_bit_register)
/*******************************************************************************
*
- * FUNCTION: acpi_set_register
+ * FUNCTION: acpi_write_bit_register
*
- * PARAMETERS: register_id - ID of ACPI bit_register to access
- * Value - (only used on write) value to write to the
- * Register, NOT pre-normalized to the bit pos
+ * PARAMETERS: register_id - ID of ACPI Bit Register to access
+ * Value - Value to write to the register, in bit
+ * position zero. The bit is automaticallly
+ * shifted to the correct position.
*
* RETURN: Status
*
- * DESCRIPTION: ACPI Bit Register write function.
+ * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
+ * since most operations require a read/modify/write sequence.
+ *
+ * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ * PM2 Control.
+ *
+ * Note that at this level, the fact that there may be actually two
+ * hardware registers (A and B - and B may not exist) is abstracted.
*
******************************************************************************/
-acpi_status acpi_set_register(u32 register_id, u32 value)
+acpi_status acpi_write_bit_register(u32 register_id, u32 value)
{
- u32 register_value = 0;
struct acpi_bit_register_info *bit_reg_info;
- acpi_status status;
acpi_cpu_flags lock_flags;
+ u32 register_value;
+ acpi_status status = AE_OK;
- ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id);
+ ACPI_FUNCTION_TRACE_U32(acpi_write_bit_register, register_id);
/* Get the info structure corresponding to the requested ACPI Register */
bit_reg_info = acpi_hw_get_bit_register_info(register_id);
if (!bit_reg_info) {
- ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X",
- register_id));
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
- /* Always do a register read first so we can insert the new bits */
-
- status = acpi_hw_register_read(bit_reg_info->parent_register,
- &register_value);
- if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
- }
-
/*
- * Decode the Register ID
- * Register ID = [Register block ID] | [bit ID]
- *
- * Check bit ID to fine locate Register offset.
- * Check Mask to determine Register offset, and then read-write.
+ * At this point, we know that the parent register is one of the
+ * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control
*/
- switch (bit_reg_info->parent_register) {
- case ACPI_REGISTER_PM1_STATUS:
-
+ if (bit_reg_info->parent_register != ACPI_REGISTER_PM1_STATUS) {
/*
- * Status Registers are different from the rest. Clear by
- * writing 1, and writing 0 has no effect. So, the only relevant
- * information is the single bit we're interested in, all others should
- * be written as 0 so they will be left unchanged.
+ * 1) Case for PM1 Enable, PM1 Control, and PM2 Control
+ *
+ * Perform a register read to preserve the bits that we are not
+ * interested in
*/
- value = ACPI_REGISTER_PREPARE_BITS(value,
- bit_reg_info->bit_position,
- bit_reg_info->
- access_bit_mask);
- if (value) {
- status =
- acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
- (u16) value);
- register_value = 0;
- }
- break;
-
- case ACPI_REGISTER_PM1_ENABLE:
-
- ACPI_REGISTER_INSERT_VALUE(register_value,
- bit_reg_info->bit_position,
- bit_reg_info->access_bit_mask,
- value);
-
- status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
- (u16) register_value);
- break;
-
- case ACPI_REGISTER_PM1_CONTROL:
-
- /*
- * Write the PM1 Control register.
- * Note that at this level, the fact that there are actually TWO
- * registers (A and B - and B may not exist) is abstracted.
- */
- ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n",
- register_value));
-
- ACPI_REGISTER_INSERT_VALUE(register_value,
- bit_reg_info->bit_position,
- bit_reg_info->access_bit_mask,
- value);
-
- status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
- (u16) register_value);
- break;
-
- case ACPI_REGISTER_PM2_CONTROL:
-
- status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
+ status = acpi_hw_register_read(bit_reg_info->parent_register,
&register_value);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
- ACPI_DEBUG_PRINT((ACPI_DB_IO,
- "PM2 control: Read %X from %8.8X%8.8X\n",
- register_value,
- ACPI_FORMAT_UINT64(acpi_gbl_FADT.
- xpm2_control_block.
- address)));
-
+ /*
+ * Insert the input bit into the value that was just read
+ * and write the register
+ */
ACPI_REGISTER_INSERT_VALUE(register_value,
bit_reg_info->bit_position,
bit_reg_info->access_bit_mask,
value);
- ACPI_DEBUG_PRINT((ACPI_DB_IO,
- "About to write %4.4X to %8.8X%8.8X\n",
- register_value,
- ACPI_FORMAT_UINT64(acpi_gbl_FADT.
- xpm2_control_block.
- address)));
+ status = acpi_hw_register_write(bit_reg_info->parent_register,
+ register_value);
+ } else {
+ /*
+ * 2) Case for PM1 Status
+ *
+ * The Status register is different from the rest. Clear an event
+ * by writing 1, writing 0 has no effect. So, the only relevant
+ * information is the single bit we're interested in, all others
+ * should be written as 0 so they will be left unchanged.
+ */
+ register_value = ACPI_REGISTER_PREPARE_BITS(value,
+ bit_reg_info->
+ bit_position,
+ bit_reg_info->
+ access_bit_mask);
- status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
- (u8) (register_value));
- break;
+ /* No need to write the register if value is all zeros */
- default:
- break;
+ if (register_value) {
+ status =
+ acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
+ register_value);
+ }
}
- unlock_and_exit:
-
- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
-
- /* Normalize the value that was read */
+ ACPI_DEBUG_PRINT((ACPI_DB_IO,
+ "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
+ register_id, bit_reg_info->parent_register, value,
+ register_value));
- ACPI_DEBUG_EXEC(register_value =
- ((register_value & bit_reg_info->access_bit_mask) >>
- bit_reg_info->bit_position));
+unlock_and_exit:
- ACPI_DEBUG_PRINT((ACPI_DB_IO,
- "Set bits: %8.8X actual %8.8X register %X\n", value,
- register_value, bit_reg_info->parent_register));
+ acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
return_ACPI_STATUS(status);
}
-ACPI_EXPORT_SYMBOL(acpi_set_register)
+ACPI_EXPORT_SYMBOL(acpi_write_bit_register)
/*******************************************************************************
*
@@ -534,7 +468,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
/* It must be of type Package */
- else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) {
+ else if (info->return_object->common.type != ACPI_TYPE_PACKAGE) {
ACPI_ERROR((AE_INFO,
"Sleep State return object is not a Package"));
status = AE_AML_OPERAND_TYPE;
@@ -555,12 +489,13 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
/* The first two elements must both be of type Integer */
- else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0])
+ else if (((info->return_object->package.elements[0])->common.type
!= ACPI_TYPE_INTEGER) ||
- (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1])
+ ((info->return_object->package.elements[1])->common.type
!= ACPI_TYPE_INTEGER)) {
ACPI_ERROR((AE_INFO,
- "Sleep State return package elements are not both Integers (%s, %s)",
+ "Sleep State return package elements are not both Integers "
+ "(%s, %s)",
acpi_ut_get_object_type_name(info->return_object->
package.elements[0]),
acpi_ut_get_object_type_name(info->return_object->
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c
index 88303ebe924..9c3cdbe2d82 100644
--- a/drivers/acpi/acpica/nsaccess.c
+++ b/drivers/acpi/acpica/nsaccess.c
@@ -118,9 +118,8 @@ acpi_status acpi_ns_root_initialize(void)
}
/*
- * Name entered successfully.
- * If entry in pre_defined_names[] specifies an
- * initial value, create the initial value.
+ * Name entered successfully. If entry in pre_defined_names[] specifies
+ * an initial value, create the initial value.
*/
if (init_val->val) {
status = acpi_os_predefined_override(init_val, &val);
@@ -178,9 +177,8 @@ acpi_status acpi_ns_root_initialize(void)
case ACPI_TYPE_STRING:
- /*
- * Build an object around the static string
- */
+ /* Build an object around the static string */
+
obj_desc->string.length =
(u32) ACPI_STRLEN(val);
obj_desc->string.pointer = val;
@@ -234,8 +232,7 @@ acpi_status acpi_ns_root_initialize(void)
/* Store pointer to value descriptor in the Node */
status = acpi_ns_attach_object(new_node, obj_desc,
- ACPI_GET_OBJECT_TYPE
- (obj_desc));
+ obj_desc->common.type);
/* Remove local reference to the object */
@@ -315,10 +312,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
return_ACPI_STATUS(AE_NO_NAMESPACE);
}
- /*
- * Get the prefix scope.
- * A null scope means use the root scope
- */
+ /* Get the prefix scope. A null scope means use the root scope */
+
if ((!scope_info) || (!scope_info->scope.node)) {
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
"Null scope prefix, using root node (%p)\n",
@@ -338,8 +333,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) {
/*
* This node might not be a actual "scope" node (such as a
- * Device/Method, etc.) It could be a Package or other object node.
- * Backup up the tree to find the containing scope node.
+ * Device/Method, etc.) It could be a Package or other object
+ * node. Backup up the tree to find the containing scope node.
*/
while (!acpi_ns_opens_scope(prefix_node->type) &&
prefix_node->type != ACPI_TYPE_ANY) {
@@ -349,7 +344,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
}
}
- /* Save type TBD: may be no longer necessary */
+ /* Save type. TBD: may be no longer necessary */
type_to_check_for = type;
@@ -414,6 +409,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
/* Name is fully qualified, no search rules apply */
search_parent_flag = ACPI_NS_NO_UPSEARCH;
+
/*
* Point past this prefix to the name segment
* part or the next Parent Prefix
@@ -429,7 +425,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
/* Current scope has no parent scope */
ACPI_ERROR((AE_INFO,
- "ACPI path has too many parent prefixes (^) - reached beyond root node"));
+ "ACPI path has too many parent prefixes (^) "
+ "- reached beyond root node"));
return_ACPI_STATUS(AE_NOT_FOUND);
}
}
@@ -531,9 +528,9 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
while (num_segments && current_node) {
num_segments--;
if (!num_segments) {
- /*
- * This is the last segment, enable typechecking
- */
+
+ /* This is the last segment, enable typechecking */
+
this_search_type = type;
/*
@@ -584,9 +581,9 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
if (num_segments > 0) {
/*
* If we have an alias to an object that opens a scope (such as a
- * device or processor), we need to dereference the alias here so that
- * we can access any children of the original node (via the remaining
- * segments).
+ * device or processor), we need to dereference the alias here so
+ * that we can access any children of the original node (via the
+ * remaining segments).
*/
if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
if (!this_node->object) {
@@ -594,8 +591,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
}
if (acpi_ns_opens_scope
- (((struct acpi_namespace_node *)this_node->
- object)->type)) {
+ (((struct acpi_namespace_node *)
+ this_node->object)->type)) {
this_node =
(struct acpi_namespace_node *)
this_node->object;
@@ -639,8 +636,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
/*
* If this is the last name segment and we are not looking for a
- * specific type, but the type of found object is known, use that type
- * to (later) see if it opens a scope.
+ * specific type, but the type of found object is known, use that
+ * type to (later) see if it opens a scope.
*/
if (type == ACPI_TYPE_ANY) {
type = this_node->type;
@@ -653,9 +650,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
current_node = this_node;
}
- /*
- * Always check if we need to open a new scope
- */
+ /* Always check if we need to open a new scope */
+
if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) {
/*
* If entry is a type which opens a scope, push the new scope on the
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c
index f976d848fe8..aceb9311196 100644
--- a/drivers/acpi/acpica/nsalloc.c
+++ b/drivers/acpi/acpica/nsalloc.c
@@ -76,8 +76,7 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name)
ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++);
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
- temp =
- acpi_gbl_ns_node_list->total_allocated -
+ temp = acpi_gbl_ns_node_list->total_allocated -
acpi_gbl_ns_node_list->total_freed;
if (temp > acpi_gbl_ns_node_list->max_occupied) {
acpi_gbl_ns_node_list->max_occupied = temp;
@@ -145,9 +144,8 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)
ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
- /*
- * Detach an object if there is one, then delete the node
- */
+ /* Detach an object if there is one, then delete the node */
+
acpi_ns_detach_object(node);
(void)acpi_os_release_object(acpi_gbl_namespace_cache, node);
return_VOID;
@@ -183,9 +181,8 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp
ACPI_FUNCTION_TRACE(ns_install_node);
/*
- * Get the owner ID from the Walk state
- * The owner ID is used to track table deletion and
- * deletion of objects created by methods
+ * Get the owner ID from the Walk state. The owner ID is used to track
+ * table deletion and deletion of objects created by methods.
*/
if (walk_state) {
owner_id = walk_state->owner_id;
@@ -260,9 +257,8 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
return_VOID;
}
- /*
- * Deallocate all children at this level
- */
+ /* Deallocate all children at this level */
+
do {
/* Get the things we need */
@@ -285,9 +281,8 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
"Object %p, Remaining %X\n", child_node,
acpi_gbl_current_node_count));
- /*
- * Detach an object if there is one, then free the child node
- */
+ /* Detach an object if there is one, then free the child node */
+
acpi_ns_detach_object(child_node);
/* Now we can delete the node */
@@ -304,7 +299,6 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
/* Clear the parent's child pointer */
parent_node->child = NULL;
-
return_VOID;
}
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
index 0da33c8e9ba..2bad613db73 100644
--- a/drivers/acpi/acpica/nsdump.c
+++ b/drivers/acpi/acpica/nsdump.c
@@ -181,6 +181,12 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
}
this_node = acpi_ns_map_handle_to_node(obj_handle);
+ if (!this_node) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n",
+ obj_handle));
+ return (AE_OK);
+ }
+
type = this_node->type;
/* Check if the owner matches */
@@ -214,9 +220,8 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node));
}
- /*
- * Now we can print out the pertinent information
- */
+ /* Now we can print out the pertinent information */
+
acpi_os_printf(" %-12s %p %2.2X ",
acpi_ut_get_type_name(type), this_node,
this_node->owner_id);
@@ -509,7 +514,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
case ACPI_DESC_TYPE_OPERAND:
- obj_type = ACPI_GET_OBJECT_TYPE(obj_desc);
+ obj_type = obj_desc->common.type;
if (obj_type > ACPI_TYPE_LOCAL_MAX) {
acpi_os_printf
@@ -539,9 +544,8 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
goto cleanup;
}
- /*
- * Valid object, get the pointer to next level, if any
- */
+ /* Valid object, get the pointer to next level, if any */
+
switch (obj_type) {
case ACPI_TYPE_BUFFER:
case ACPI_TYPE_STRING:
@@ -602,14 +606,14 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
* display_type - 0 or ACPI_DISPLAY_SUMMARY
* max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX
* for an effectively unlimited depth.
- * owner_id - Dump only objects owned by this ID. Use
+ * owner_id - Dump only objects owned by this ID. Use
* ACPI_UINT32_MAX to match all owners.
* start_handle - Where in namespace to start/end search
*
* RETURN: None
*
- * DESCRIPTION: Dump typed objects within the loaded namespace.
- * Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
+ * DESCRIPTION: Dump typed objects within the loaded namespace. Uses
+ * acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c
index 0f3d5f9b596..8e7dec1176c 100644
--- a/drivers/acpi/acpica/nseval.c
+++ b/drivers/acpi/acpica/nseval.c
@@ -155,7 +155,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
}
- ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:",
+ ACPI_DUMP_PATHNAME(info->resolved_node, "ACPI: Execute Method",
ACPI_LV_INFO, _COMPONENT);
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c
index 13501cb8186..2adfcf329e1 100644
--- a/drivers/acpi/acpica/nsinit.c
+++ b/drivers/acpi/acpica/nsinit.c
@@ -103,7 +103,8 @@ acpi_status acpi_ns_initialize_objects(void)
}
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
- "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n",
+ "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd "
+ "Buffers %hd/%hd Packages (%hd nodes)\n",
info.op_region_init, info.op_region_count,
info.field_init, info.field_count,
info.buffer_init, info.buffer_count,
@@ -148,7 +149,8 @@ acpi_status acpi_ns_initialize_devices(void)
info.num_INI = 0;
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
- "Initializing Device/Processor/Thermal objects by executing _INI methods:"));
+ "Initializing Device/Processor/Thermal objects "
+ "by executing _INI methods:"));
/* Tree analysis: find all subtrees that contain _INI methods */
@@ -180,7 +182,8 @@ acpi_status acpi_ns_initialize_devices(void)
}
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
- "\nExecuted %hd _INI methods requiring %hd _STA executions (examined %hd objects)\n",
+ "\nExecuted %hd _INI methods requiring %hd _STA executions "
+ "(examined %hd objects)\n",
info.num_INI, info.num_STA, info.device_count));
return_ACPI_STATUS(status);
@@ -263,16 +266,14 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
return (AE_OK);
}
- /*
- * If the object is already initialized, nothing else to do
- */
+ /* If the object is already initialized, nothing else to do */
+
if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
return (AE_OK);
}
- /*
- * Must lock the interpreter before executing AML code
- */
+ /* Must lock the interpreter before executing AML code */
+
acpi_ex_enter_interpreter();
/*
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c
index a0ba9e12379..dcd7a6adbbb 100644
--- a/drivers/acpi/acpica/nsload.c
+++ b/drivers/acpi/acpica/nsload.c
@@ -128,12 +128,12 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
* parse trees.
*/
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "**** Begin Table Method Parsing and Object Initialization ****\n"));
+ "**** Begin Table Method Parsing and Object Initialization\n"));
status = acpi_ds_initialize_objects(table_index, node);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "**** Completed Table Method Parsing and Object Initialization ****\n"));
+ "**** Completed Table Method Parsing and Object Initialization\n"));
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c
index 08a97a57f8f..3eb20bfda9d 100644
--- a/drivers/acpi/acpica/nsobject.c
+++ b/drivers/acpi/acpica/nsobject.c
@@ -209,8 +209,7 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node)
obj_desc = node->object;
- if (!obj_desc ||
- (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA)) {
+ if (!obj_desc || (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
return_VOID;
}
@@ -220,8 +219,7 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node)
if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) {
node->object = obj_desc->common.next_object;
if (node->object &&
- (ACPI_GET_OBJECT_TYPE(node->object) !=
- ACPI_TYPE_LOCAL_DATA)) {
+ ((node->object)->common.type != ACPI_TYPE_LOCAL_DATA)) {
node->object = node->object->common.next_object;
}
}
@@ -267,7 +265,7 @@ union acpi_operand_object *acpi_ns_get_attached_object(struct
((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND)
&& (ACPI_GET_DESCRIPTOR_TYPE(node->object) !=
ACPI_DESC_TYPE_NAMED))
- || (ACPI_GET_OBJECT_TYPE(node->object) == ACPI_TYPE_LOCAL_DATA)) {
+ || ((node->object)->common.type == ACPI_TYPE_LOCAL_DATA)) {
return_PTR(NULL);
}
@@ -294,9 +292,9 @@ union acpi_operand_object *acpi_ns_get_secondary_object(union
ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc);
if ((!obj_desc) ||
- (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) ||
+ (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) ||
(!obj_desc->common.next_object) ||
- (ACPI_GET_OBJECT_TYPE(obj_desc->common.next_object) ==
+ ((obj_desc->common.next_object)->common.type ==
ACPI_TYPE_LOCAL_DATA)) {
return_PTR(NULL);
}
@@ -331,7 +329,7 @@ acpi_ns_attach_data(struct acpi_namespace_node *node,
prev_obj_desc = NULL;
obj_desc = node->object;
while (obj_desc) {
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+ if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
(obj_desc->data.handler == handler)) {
return (AE_ALREADY_EXISTS);
}
@@ -385,7 +383,7 @@ acpi_ns_detach_data(struct acpi_namespace_node * node,
prev_obj_desc = NULL;
obj_desc = node->object;
while (obj_desc) {
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+ if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
(obj_desc->data.handler == handler)) {
if (prev_obj_desc) {
prev_obj_desc->common.next_object =
@@ -428,7 +426,7 @@ acpi_ns_get_attached_data(struct acpi_namespace_node * node,
obj_desc = node->object;
while (obj_desc) {
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+ if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
(obj_desc->data.handler == handler)) {
*data = obj_desc->data.pointer;
return (AE_OK);
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c
index b9e8d0070b6..662a4bd5b62 100644
--- a/drivers/acpi/acpica/nsparse.c
+++ b/drivers/acpi/acpica/nsparse.c
@@ -176,9 +176,8 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
* performs another complete parse of the AML.
*/
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
- status =
- acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index,
- start_node);
+ status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
+ table_index, start_node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -193,9 +192,8 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
* parse objects are all cached.
*/
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
- status =
- acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index,
- start_node);
+ status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
+ table_index, start_node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index 452703290d3..d9e8cbc6e67 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -79,7 +79,9 @@ acpi_ns_check_package(char *pathname,
static acpi_status
acpi_ns_check_package_elements(char *pathname,
union acpi_operand_object **elements,
- u8 type1, u32 count1, u8 type2, u32 count2);
+ u8 type1,
+ u32 count1,
+ u8 type2, u32 count2, u32 start_index);
static acpi_status
acpi_ns_check_object_type(char *pathname,
@@ -221,7 +223,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
/* For returned Package objects, check the type of all sub-objects */
- if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) {
+ if (return_object->common.type == ACPI_TYPE_PACKAGE) {
status =
acpi_ns_check_package(pathname, return_object_ptr,
predefined);
@@ -302,7 +304,8 @@ acpi_ns_check_parameter_count(char *pathname,
if ((user_param_count != required_params_current) &&
(user_param_count != required_params_old)) {
ACPI_WARNING((AE_INFO,
- "%s: Parameter count mismatch - caller passed %d, ACPI requires %d",
+ "%s: Parameter count mismatch - "
+ "caller passed %d, ACPI requires %d",
pathname, user_param_count,
required_params_current));
}
@@ -472,7 +475,7 @@ acpi_ns_check_package(char *pathname,
package->ret_info.
object_type2,
package->ret_info.
- count2);
+ count2, 0);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -623,7 +626,7 @@ acpi_ns_check_package(char *pathname,
object_type2,
package->
ret_info.
- count2);
+ count2, 0);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -672,7 +675,8 @@ acpi_ns_check_package(char *pathname,
object_type1,
sub_package->
package.
- count, 0, 0);
+ count, 0, 0,
+ 0);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -710,7 +714,8 @@ acpi_ns_check_package(char *pathname,
ret_info.
object_type1,
(expected_count
- - 1), 0, 0);
+ - 1), 0, 0,
+ 1);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -758,6 +763,7 @@ acpi_ns_check_package(char *pathname,
* Count1 - Count for first group
* Type2 - Object type for second group
* Count2 - Count for second group
+ * start_index - Start of the first group of elements
*
* RETURN: Status
*
@@ -769,7 +775,9 @@ acpi_ns_check_package(char *pathname,
static acpi_status
acpi_ns_check_package_elements(char *pathname,
union acpi_operand_object **elements,
- u8 type1, u32 count1, u8 type2, u32 count2)
+ u8 type1,
+ u32 count1,
+ u8 type2, u32 count2, u32 start_index)
{
union acpi_operand_object **this_element = elements;
acpi_status status;
@@ -782,7 +790,7 @@ acpi_ns_check_package_elements(char *pathname,
*/
for (i = 0; i < count1; i++) {
status = acpi_ns_check_object_type(pathname, this_element,
- type1, i);
+ type1, i + start_index);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -791,7 +799,8 @@ acpi_ns_check_package_elements(char *pathname,
for (i = 0; i < count2; i++) {
status = acpi_ns_check_object_type(pathname, this_element,
- type2, (i + count1));
+ type2,
+ (i + count1 + start_index));
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -858,7 +867,7 @@ acpi_ns_check_object_type(char *pathname,
* from all of the predefined names (including elements of returned
* packages)
*/
- switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+ switch (return_object->common.type) {
case ACPI_TYPE_INTEGER:
return_btype = ACPI_RTYPE_INTEGER;
break;
@@ -901,7 +910,7 @@ acpi_ns_check_object_type(char *pathname,
/* For reference objects, check that the reference type is correct */
- if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) {
+ if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
status = acpi_ns_check_reference(pathname, return_object);
}
@@ -974,7 +983,8 @@ acpi_ns_check_reference(char *pathname,
}
ACPI_WARNING((AE_INFO,
- "%s: Return type mismatch - unexpected reference object type [%s] %2.2X",
+ "%s: Return type mismatch - "
+ "unexpected reference object type [%s] %2.2X",
pathname, acpi_ut_get_reference_name(return_object),
return_object->reference.class));
@@ -1006,7 +1016,7 @@ acpi_ns_repair_object(u32 expected_btypes,
union acpi_operand_object *new_object;
acpi_size length;
- switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+ switch (return_object->common.type) {
case ACPI_TYPE_BUFFER:
if (!(expected_btypes & ACPI_RTYPE_STRING)) {
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c
index 6fea13f3f52..f9b4f51bf8f 100644
--- a/drivers/acpi/acpica/nssearch.c
+++ b/drivers/acpi/acpica/nssearch.c
@@ -167,7 +167,8 @@ acpi_ns_search_one_scope(u32 target_name,
/* Searched entire namespace level, not found */
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
- "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
+ "Name [%4.4s] (%s) not found in search in scope [%4.4s] "
+ "%p first child %p\n",
ACPI_CAST_PTR(char, &target_name),
acpi_ut_get_type_name(type),
acpi_ut_get_node_name(parent_node), parent_node,
@@ -239,9 +240,8 @@ acpi_ns_search_parent_tree(u32 target_name,
acpi_ut_get_node_name(parent_node),
ACPI_CAST_PTR(char, &target_name)));
- /*
- * Search parents until target is found or we have backed up to the root
- */
+ /* Search parents until target is found or we have backed up to the root */
+
while (parent_node) {
/*
* Search parent scope. Use TYPE_ANY because we don't care about the
@@ -395,9 +395,9 @@ acpi_ns_search_and_enter(u32 target_name,
return_ACPI_STATUS(AE_NO_MEMORY);
}
#ifdef ACPI_ASL_COMPILER
- /*
- * Node is an object defined by an External() statement
- */
+
+ /* Node is an object defined by an External() statement */
+
if (flags & ACPI_NS_EXTERNAL) {
new_node->flags |= ANOBJ_IS_EXTERNAL;
}
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c
index 3e1149bf4aa..78277ed0833 100644
--- a/drivers/acpi/acpica/nsutils.c
+++ b/drivers/acpi/acpica/nsutils.c
@@ -325,9 +325,8 @@ void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
next_external_char++;
}
} else {
- /*
- * Handle Carat prefixes
- */
+ /* Handle Carat prefixes */
+
while (*next_external_char == '^') {
info->num_carats++;
next_external_char++;
@@ -552,9 +551,8 @@ acpi_ns_externalize_name(u32 internal_name_length,
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- /*
- * Check for a prefix (one '\' | one or more '^').
- */
+ /* Check for a prefix (one '\' | one or more '^') */
+
switch (internal_name[0]) {
case '\\':
prefix_length = 1;
@@ -580,7 +578,7 @@ acpi_ns_externalize_name(u32 internal_name_length,
}
/*
- * Check for object names. Note that there could be 0-255 of these
+ * Check for object names. Note that there could be 0-255 of these
* 4-byte elements.
*/
if (prefix_length < internal_name_length) {
@@ -637,9 +635,8 @@ acpi_ns_externalize_name(u32 internal_name_length,
return_ACPI_STATUS(AE_BAD_PATHNAME);
}
- /*
- * Build converted_name
- */
+ /* Build the converted_name */
+
*converted_name = ACPI_ALLOCATE_ZEROED(required_length);
if (!(*converted_name)) {
return_ACPI_STATUS(AE_NO_MEMORY);
@@ -685,6 +682,9 @@ acpi_ns_externalize_name(u32 internal_name_length,
* and keep all pointers within this subsystem - however this introduces
* more (and perhaps unnecessary) overhead.
*
+ * The current implemenation is basically a placeholder until such time comes
+ * that it is needed.
+ *
******************************************************************************/
struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
@@ -692,9 +692,8 @@ struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
ACPI_FUNCTION_ENTRY();
- /*
- * Simple implementation
- */
+ /* Parameter validation */
+
if ((!handle) || (handle == ACPI_ROOT_OBJECT)) {
return (acpi_gbl_root_node);
}
@@ -872,7 +871,7 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
(flags | ACPI_NS_DONT_OPEN_SCOPE), NULL,
return_node);
if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n",
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s, %s\n",
pathname, acpi_format_exception(status)));
}
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c
index 200895fa272..83e3aa6d4b9 100644
--- a/drivers/acpi/acpica/nswalk.c
+++ b/drivers/acpi/acpica/nswalk.c
@@ -135,8 +135,8 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct
* starting (and ending) at the node specified by start_handle.
* The user_function is called whenever a node that matches
* the type parameter is found. If the user function returns
- * a non-zero value, the search is terminated immediately and this
- * value is returned to the caller.
+ * a non-zero value, the search is terminated immediately and
+ * this value is returned to the caller.
*
* The point of this procedure is to provide a generic namespace
* walk routine that can be called from multiple places to
@@ -200,10 +200,10 @@ acpi_ns_walk_namespace(acpi_object_type type,
/*
* Ignore all temporary namespace nodes (created during control
* method execution) unless told otherwise. These temporary nodes
- * can cause a race condition because they can be deleted during the
- * execution of the user function (if the namespace is unlocked before
- * invocation of the user function.) Only the debugger namespace dump
- * will examine the temporary nodes.
+ * can cause a race condition because they can be deleted during
+ * the execution of the user function (if the namespace is
+ * unlocked before invocation of the user function.) Only the
+ * debugger namespace dump will examine the temporary nodes.
*/
if ((child_node->flags & ANOBJ_TEMPORARY) &&
!(flags & ACPI_NS_WALK_TEMP_NODES)) {
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c
index 22a7171ac1e..daf4ad37896 100644
--- a/drivers/acpi/acpica/nsxfeval.c
+++ b/drivers/acpi/acpica/nsxfeval.c
@@ -53,7 +53,6 @@ ACPI_MODULE_NAME("nsxfeval")
/* Local prototypes */
static void acpi_ns_resolve_references(struct acpi_evaluate_info *info);
-#ifdef ACPI_FUTURE_USAGE
/*******************************************************************************
*
* FUNCTION: acpi_evaluate_object_typed
@@ -147,7 +146,7 @@ acpi_evaluate_object_typed(acpi_handle handle,
}
ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed)
-#endif /* ACPI_FUTURE_USAGE */
+
/*******************************************************************************
*
* FUNCTION: acpi_evaluate_object
@@ -387,8 +386,7 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
/* We are interested in reference objects only */
- if (ACPI_GET_OBJECT_TYPE(info->return_object) !=
- ACPI_TYPE_LOCAL_REFERENCE) {
+ if ((info->return_object)->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
return;
}
@@ -476,21 +474,40 @@ acpi_walk_namespace(acpi_object_type type,
}
/*
- * Lock the namespace around the walk.
- * The namespace will be unlocked/locked around each call
- * to the user function - since this function
- * must be allowed to make Acpi calls itself.
+ * Need to acquire the namespace reader lock to prevent interference
+ * with any concurrent table unloads (which causes the deletion of
+ * namespace objects). We cannot allow the deletion of a namespace node
+ * while the user function is using it. The exception to this are the
+ * nodes created and deleted during control method execution -- these
+ * nodes are marked as temporary nodes and are ignored by the namespace
+ * walk. Thus, control methods can be executed while holding the
+ * namespace deletion lock (and the user function can execute control
+ * methods.)
+ */
+ status = acpi_ut_acquire_read_lock(&acpi_gbl_namespace_rw_lock);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ /*
+ * Lock the namespace around the walk. The namespace will be
+ * unlocked/locked around each call to the user function - since the user
+ * function must be allowed to make ACPICA calls itself (for example, it
+ * will typically execute control methods during device enumeration.)
*/
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto unlock_and_exit;
}
status = acpi_ns_walk_namespace(type, start_object, max_depth,
- ACPI_NS_WALK_UNLOCK,
- user_function, context, return_value);
+ ACPI_NS_WALK_UNLOCK, user_function,
+ context, return_value);
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+ unlock_and_exit:
+ (void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock);
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c
index 52865ee6bc7..b6667ff059e 100644
--- a/drivers/acpi/acpica/rscalc.c
+++ b/drivers/acpi/acpica/rscalc.c
@@ -557,9 +557,9 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
table_index++) {
if (*sub_object_list && /* Null object allowed */
((ACPI_TYPE_STRING ==
- ACPI_GET_OBJECT_TYPE(*sub_object_list)) ||
+ (*sub_object_list)->common.type) ||
((ACPI_TYPE_LOCAL_REFERENCE ==
- ACPI_GET_OBJECT_TYPE(*sub_object_list)) &&
+ (*sub_object_list)->common.type) &&
((*sub_object_list)->reference.class ==
ACPI_REFCLASS_NAME)))) {
name_found = TRUE;
@@ -575,8 +575,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
/* Was a String type found? */
if (name_found) {
- if (ACPI_GET_OBJECT_TYPE(*sub_object_list) ==
- ACPI_TYPE_STRING) {
+ if ((*sub_object_list)->common.type == ACPI_TYPE_STRING) {
/*
* The length String.Length field does not include the
* terminating NULL, add 1
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c
index 61566b1a061..663f692fffc 100644
--- a/drivers/acpi/acpica/rscreate.c
+++ b/drivers/acpi/acpica/rscreate.c
@@ -212,7 +212,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* Each element of the top-level package must also be a package */
- if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) {
+ if ((*top_object_list)->common.type != ACPI_TYPE_PACKAGE) {
ACPI_ERROR((AE_INFO,
"(PRT[%X]) Need sub-package, found %s",
index,
@@ -240,7 +240,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 1) First subobject: Dereference the PRT.Address */
obj_desc = sub_object_list[0];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].Address) Need Integer, found %s",
index,
@@ -253,7 +253,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 2) Second subobject: Dereference the PRT.Pin */
obj_desc = sub_object_list[1];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].Pin) Need Integer, found %s",
index,
@@ -265,7 +265,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
* If BIOS erroneously reversed the _PRT source_name and source_index,
* then reverse them back.
*/
- if (ACPI_GET_OBJECT_TYPE(sub_object_list[3]) !=
+ if ((sub_object_list[3])->common.type !=
ACPI_TYPE_INTEGER) {
if (acpi_gbl_enable_interpreter_slack) {
source_name_index = 3;
@@ -291,8 +291,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
* other ACPI implementations.
*/
obj_desc = sub_object_list[3];
- if (!obj_desc
- || (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
+ if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
sub_object_list[3] = sub_object_list[2];
sub_object_list[2] = obj_desc;
@@ -307,7 +306,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
*/
obj_desc = sub_object_list[source_name_index];
if (obj_desc) {
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
if (obj_desc->reference.class !=
@@ -380,7 +379,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 4) Fourth subobject: Dereference the PRT.source_index */
obj_desc = sub_object_list[source_index_index];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].SourceIndex) Need Integer, found %s",
index,
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 3636e4f8fb7..71e655d14cb 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -57,6 +57,8 @@ static void acpi_tb_convert_fadt(void);
static void acpi_tb_validate_fadt(void);
+static void acpi_tb_setup_fadt_registers(void);
+
/* Table for conversion of FADT to common internal format and FADT validation */
typedef struct acpi_fadt_info {
@@ -130,7 +132,38 @@ static struct acpi_fadt_info fadt_info_table[] = {
ACPI_FADT_SEPARATE_LENGTH}
};
-#define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
+#define ACPI_FADT_INFO_ENTRIES \
+ (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
+
+/* Table used to split Event Blocks into separate status/enable registers */
+
+typedef struct acpi_fadt_pm_info {
+ struct acpi_generic_address *target;
+ u8 source;
+ u8 register_num;
+
+} acpi_fadt_pm_info;
+
+static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
+ {&acpi_gbl_xpm1a_status,
+ ACPI_FADT_OFFSET(xpm1a_event_block),
+ 0},
+
+ {&acpi_gbl_xpm1a_enable,
+ ACPI_FADT_OFFSET(xpm1a_event_block),
+ 1},
+
+ {&acpi_gbl_xpm1b_status,
+ ACPI_FADT_OFFSET(xpm1b_event_block),
+ 0},
+
+ {&acpi_gbl_xpm1b_enable,
+ ACPI_FADT_OFFSET(xpm1b_event_block),
+ 1}
+};
+
+#define ACPI_FADT_PM_INFO_ENTRIES \
+ (sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info))
/*******************************************************************************
*
@@ -172,7 +205,6 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
* FUNCTION: acpi_tb_parse_fadt
*
* PARAMETERS: table_index - Index for the FADT
- * Flags - Flags
*
* RETURN: None
*
@@ -181,7 +213,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
*
******************************************************************************/
-void acpi_tb_parse_fadt(u32 table_index, u8 flags)
+void acpi_tb_parse_fadt(u32 table_index)
{
u32 length;
struct acpi_table_header *table;
@@ -208,7 +240,7 @@ void acpi_tb_parse_fadt(u32 table_index, u8 flags)
*/
(void)acpi_tb_verify_checksum(table, length);
- /* Obtain a local copy of the FADT in common ACPI 2.0+ format */
+ /* Create a local copy of the FADT in common ACPI 2.0+ format */
acpi_tb_create_local_fadt(table, length);
@@ -219,10 +251,10 @@ void acpi_tb_parse_fadt(u32 table_index, u8 flags)
/* Obtain the DSDT and FACS tables via their addresses within the FADT */
acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
- flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
+ ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs,
- flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
+ ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
}
/*******************************************************************************
@@ -266,11 +298,17 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
ACPI_MEMCPY(&acpi_gbl_FADT, table,
ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
- /*
- * 1) Convert the local copy of the FADT to the common internal format
- * 2) Validate some of the important values within the FADT
- */
+ /* Convert the local copy of the FADT to the common internal format */
+
acpi_tb_convert_fadt();
+
+ /* Validate FADT values now, before we make any changes */
+
+ acpi_tb_validate_fadt();
+
+ /* Initialize the global ACPI register structures */
+
+ acpi_tb_setup_fadt_registers();
}
/*******************************************************************************
@@ -282,31 +320,35 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
* RETURN: None
*
* DESCRIPTION: Converts all versions of the FADT to a common internal format.
- * Expand all 32-bit addresses to 64-bit.
+ * Expand 32-bit addresses to 64-bit as necessary.
*
* NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt),
* and must contain a copy of the actual FADT.
*
- * ACPICA will use the "X" fields of the FADT for all addresses.
+ * Notes on 64-bit register addresses:
+ *
+ * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
+ * fields of the FADT for all ACPI register addresses.
*
- * "X" fields are optional extensions to the original V1.0 fields. Even if
- * they are present in the structure, they can be optionally not used by
- * setting them to zero. Therefore, we must selectively expand V1.0 fields
- * if the corresponding X field is zero.
+ * The 64-bit "X" fields are optional extensions to the original 32-bit FADT
+ * V1.0 fields. Even if they are present in the FADT, they are optional and
+ * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
+ * 32-bit V1.0 fields if the corresponding X field is zero.
*
- * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding
- * "X" fields.
+ * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the
+ * corresponding "X" fields in the internal FADT.
*
- * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by
- * expanding the corresponding ACPI 1.0 field.
+ * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
+ * to the corresponding 64-bit X fields. For compatibility with other ACPI
+ * implementations, we ignore the 64-bit field if the 32-bit field is valid,
+ * regardless of whether the host OS is 32-bit or 64-bit.
*
******************************************************************************/
static void acpi_tb_convert_fadt(void)
{
- u8 pm1_register_bit_width;
- u8 pm1_register_byte_width;
- struct acpi_generic_address *target64;
+ struct acpi_generic_address *address64;
+ u32 address32;
u32 i;
/* Update the local FADT table header length */
@@ -355,140 +397,56 @@ static void acpi_tb_convert_fadt(void)
* Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
* generic address structures as necessary. Later code will always use
* the 64-bit address structures.
+ *
+ * March 2009:
+ * We now always use the 32-bit address if it is valid (non-null). This
+ * is not in accordance with the ACPI specification which states that
+ * the 64-bit address supersedes the 32-bit version, but we do this for
+ * compatibility with other ACPI implementations. Most notably, in the
+ * case where both the 32 and 64 versions are non-null, we use the 32-bit
+ * version. This is the only address that is guaranteed to have been
+ * tested by the BIOS manufacturer.
*/
for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
- target64 =
- ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
- fadt_info_table[i].address64);
+ address32 = *ACPI_ADD_PTR(u32,
+ &acpi_gbl_FADT,
+ fadt_info_table[i].address32);
- /* Expand only if the 64-bit X target is null */
+ address64 = ACPI_ADD_PTR(struct acpi_generic_address,
+ &acpi_gbl_FADT,
+ fadt_info_table[i].address64);
- if (!target64->address) {
+ /*
+ * If both 32- and 64-bit addresses are valid (non-zero),
+ * they must match.
+ */
+ if (address64->address && address32 &&
+ (address64->address != (u64) address32)) {
+ ACPI_ERROR((AE_INFO,
+ "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 32",
+ fadt_info_table[i].name, address32,
+ ACPI_FORMAT_UINT64(address64->address)));
+ }
- /* The space_id is always I/O for the 32-bit legacy address fields */
+ /* Always use 32-bit address if it is valid (non-null) */
- acpi_tb_init_generic_address(target64,
+ if (address32) {
+ /*
+ * Copy the 32-bit address to the 64-bit GAS structure. The
+ * Space ID is always I/O for 32-bit legacy address fields
+ */
+ acpi_tb_init_generic_address(address64,
ACPI_ADR_SPACE_SYSTEM_IO,
*ACPI_ADD_PTR(u8,
&acpi_gbl_FADT,
fadt_info_table
[i].length),
- (u64) * ACPI_ADD_PTR(u32,
- &acpi_gbl_FADT,
- fadt_info_table
- [i].
- address32));
- }
- }
-
- /* Validate FADT values now, before we make any changes */
-
- acpi_tb_validate_fadt();
-
- /*
- * Optionally check all register lengths against the default values and
- * update them if they are incorrect.
- */
- if (acpi_gbl_use_default_register_widths) {
- for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
- target64 =
- ACPI_ADD_PTR(struct acpi_generic_address,
- &acpi_gbl_FADT,
- fadt_info_table[i].address64);
-
- /*
- * If a valid register (Address != 0) and the (default_length > 0)
- * (Not a GPE register), then check the width against the default.
- */
- if ((target64->address) &&
- (fadt_info_table[i].default_length > 0) &&
- (fadt_info_table[i].default_length !=
- target64->bit_width)) {
- ACPI_WARNING((AE_INFO,
- "Invalid length for %s: %d, using default %d",
- fadt_info_table[i].name,
- target64->bit_width,
- fadt_info_table[i].
- default_length));
-
- /* Incorrect size, set width to the default */
-
- target64->bit_width =
- fadt_info_table[i].default_length;
- }
+ address32);
}
}
-
- /*
- * Get the length of the individual PM1 registers (enable and status).
- * Each register is defined to be (event block length / 2).
- */
- pm1_register_bit_width =
- (u8)ACPI_DIV_2(acpi_gbl_FADT.xpm1a_event_block.bit_width);
- pm1_register_byte_width = (u8)ACPI_DIV_8(pm1_register_bit_width);
-
- /*
- * Adjust the lengths of the PM1 Event Blocks so that they can be used to
- * access the PM1 status register(s). Use (width / 2)
- */
- acpi_gbl_FADT.xpm1a_event_block.bit_width = pm1_register_bit_width;
- acpi_gbl_FADT.xpm1b_event_block.bit_width = pm1_register_bit_width;
-
- /*
- * Calculate separate GAS structs for the PM1 Enable registers.
- * These addresses do not appear (directly) in the FADT, so it is
- * useful to calculate them once, here.
- *
- * The PM event blocks are split into two register blocks, first is the
- * PM Status Register block, followed immediately by the PM Enable
- * Register block. Each is of length (xpm1x_event_block.bit_width/2).
- *
- * On various systems the v2 fields (and particularly the bit widths)
- * cannot be relied upon, though. Hence resort to using the v1 length
- * here (and warn about the inconsistency).
- */
- if (acpi_gbl_FADT.xpm1a_event_block.bit_width
- != acpi_gbl_FADT.pm1_event_length * 8)
- printk(KERN_WARNING "FADT: "
- "X_PM1a_EVT_BLK.bit_width (%u) does not match"
- " PM1_EVT_LEN (%u)\n",
- acpi_gbl_FADT.xpm1a_event_block.bit_width,
- acpi_gbl_FADT.pm1_event_length);
-
- /* The PM1A register block is required */
-
- acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
- acpi_gbl_FADT.xpm1a_event_block.space_id,
- pm1_register_byte_width,
- (acpi_gbl_FADT.xpm1a_event_block.address +
- pm1_register_byte_width));
- /* Don't forget to copy space_id of the GAS */
- acpi_gbl_xpm1a_enable.space_id =
- acpi_gbl_FADT.xpm1a_event_block.space_id;
-
- /* The PM1B register block is optional, ignore if not present */
-
- if (acpi_gbl_FADT.xpm1b_event_block.address) {
- if (acpi_gbl_FADT.xpm1b_event_block.bit_width
- != acpi_gbl_FADT.pm1_event_length * 8)
- printk(KERN_WARNING "FADT: "
- "X_PM1b_EVT_BLK.bit_width (%u) does not match"
- " PM1_EVT_LEN (%u)\n",
- acpi_gbl_FADT.xpm1b_event_block.bit_width,
- acpi_gbl_FADT.pm1_event_length);
- acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
- acpi_gbl_FADT.xpm1b_event_block.space_id,
- pm1_register_byte_width,
- (acpi_gbl_FADT.xpm1b_event_block.
- address + pm1_register_byte_width));
- /* Don't forget to copy space_id of the GAS */
- acpi_gbl_xpm1b_enable.space_id =
- acpi_gbl_FADT.xpm1b_event_block.space_id;
-
- }
}
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_tb_validate_fadt
*
@@ -525,18 +483,22 @@ static void acpi_tb_validate_fadt(void)
(acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) {
ACPI_WARNING((AE_INFO,
"32/64X FACS address mismatch in FADT - "
- "two FACS tables! %8.8X/%8.8X%8.8X",
+ "%8.8X/%8.8X%8.8X, using 32",
acpi_gbl_FADT.facs,
ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs)));
+
+ acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs;
}
if (acpi_gbl_FADT.dsdt &&
(acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) {
ACPI_WARNING((AE_INFO,
"32/64X DSDT address mismatch in FADT - "
- "two DSDT tables! %8.8X/%8.8X%8.8X",
+ "%8.8X/%8.8X%8.8X, using 32",
acpi_gbl_FADT.dsdt,
ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt)));
+
+ acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt;
}
/* Examine all of the 64-bit extended address fields (X fields) */
@@ -561,7 +523,8 @@ static void acpi_tb_validate_fadt(void)
* For each extended field, check for length mismatch between the
* legacy length field and the corresponding 64-bit X length field.
*/
- if (address64 && (address64->bit_width != ACPI_MUL_8(length))) {
+ if (address64->address &&
+ (address64->bit_width != ACPI_MUL_8(length))) {
ACPI_WARNING((AE_INFO,
"32/64X length mismatch in %s: %d/%d",
name, ACPI_MUL_8(length),
@@ -575,7 +538,8 @@ static void acpi_tb_validate_fadt(void)
*/
if (!address64->address || !length) {
ACPI_ERROR((AE_INFO,
- "Required field %s has zero address and/or length: %8.8X%8.8X/%X",
+ "Required field %s has zero address and/or length:"
+ " %8.8X%8.8X/%X",
name,
ACPI_FORMAT_UINT64(address64->
address),
@@ -584,27 +548,112 @@ static void acpi_tb_validate_fadt(void)
} else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) {
/*
* Field is optional (PM2Control, GPE0, GPE1) AND has its own
- * length field. If present, both the address and length must be valid.
+ * length field. If present, both the address and length must
+ * be valid.
*/
- if ((address64->address && !length)
- || (!address64->address && length)) {
+ if ((address64->address && !length) ||
+ (!address64->address && length)) {
ACPI_WARNING((AE_INFO,
- "Optional field %s has zero address or length: %8.8X%8.8X/%X",
+ "Optional field %s has zero address or length: "
+ "%8.8X%8.8X/%X",
name,
ACPI_FORMAT_UINT64(address64->
address),
length));
}
}
+ }
+}
- /* If both 32- and 64-bit addresses are valid (non-zero), they must match */
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_tb_setup_fadt_registers
+ *
+ * PARAMETERS: None, uses acpi_gbl_FADT.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
+ * force FADT register definitions to their default lengths.
+ *
+ ******************************************************************************/
- if (address64->address && *address32 &&
- (address64->address != (u64) * address32)) {
- ACPI_ERROR((AE_INFO,
- "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 64X",
- name, *address32,
- ACPI_FORMAT_UINT64(address64->address)));
+static void acpi_tb_setup_fadt_registers(void)
+{
+ struct acpi_generic_address *target64;
+ struct acpi_generic_address *source64;
+ u8 pm1_register_byte_width;
+ u32 i;
+
+ /*
+ * Optionally check all register lengths against the default values and
+ * update them if they are incorrect.
+ */
+ if (acpi_gbl_use_default_register_widths) {
+ for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
+ target64 =
+ ACPI_ADD_PTR(struct acpi_generic_address,
+ &acpi_gbl_FADT,
+ fadt_info_table[i].address64);
+
+ /*
+ * If a valid register (Address != 0) and the (default_length > 0)
+ * (Not a GPE register), then check the width against the default.
+ */
+ if ((target64->address) &&
+ (fadt_info_table[i].default_length > 0) &&
+ (fadt_info_table[i].default_length !=
+ target64->bit_width)) {
+ ACPI_WARNING((AE_INFO,
+ "Invalid length for %s: %d, using default %d",
+ fadt_info_table[i].name,
+ target64->bit_width,
+ fadt_info_table[i].
+ default_length));
+
+ /* Incorrect size, set width to the default */
+
+ target64->bit_width =
+ fadt_info_table[i].default_length;
+ }
+ }
+ }
+
+ /*
+ * Get the length of the individual PM1 registers (enable and status).
+ * Each register is defined to be (event block length / 2). Extra divide
+ * by 8 converts bits to bytes.
+ */
+ pm1_register_byte_width = (u8)
+ ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width);
+
+ /*
+ * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
+ * registers. These addresses do not appear (directly) in the FADT, so it
+ * is useful to pre-calculate them from the PM1 Event Block definitions.
+ *
+ * The PM event blocks are split into two register blocks, first is the
+ * PM Status Register block, followed immediately by the PM Enable
+ * Register block. Each is of length (pm1_event_length/2)
+ *
+ * Note: The PM1A event block is required by the ACPI specification.
+ * However, the PM1B event block is optional and is rarely, if ever,
+ * used.
+ */
+
+ for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) {
+ source64 =
+ ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
+ fadt_pm_info_table[i].source);
+
+ if (source64->address) {
+ acpi_tb_init_generic_address(fadt_pm_info_table[i].
+ target, source64->space_id,
+ pm1_register_byte_width,
+ source64->address +
+ (fadt_pm_info_table[i].
+ register_num *
+ pm1_register_byte_width));
}
}
}
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 37374b21969..f865d5a096d 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -103,7 +103,9 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
*
* RETURN: Status
*
- * DESCRIPTION: This function is called to add the ACPI table
+ * DESCRIPTION: This function is called to add an ACPI table. It is used to
+ * dynamically load tables via the Load and load_table AML
+ * operators.
*
******************************************************************************/
@@ -112,6 +114,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
{
u32 i;
acpi_status status = AE_OK;
+ struct acpi_table_header *override_table = NULL;
ACPI_FUNCTION_TRACE(tb_add_table);
@@ -201,6 +204,29 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
}
}
+ /*
+ * ACPI Table Override:
+ * Allow the host to override dynamically loaded tables.
+ */
+ status = acpi_os_table_override(table_desc->pointer, &override_table);
+ if (ACPI_SUCCESS(status) && override_table) {
+ ACPI_INFO((AE_INFO,
+ "%4.4s @ 0x%p Table override, replaced with:",
+ table_desc->pointer->signature,
+ ACPI_CAST_PTR(void, table_desc->address)));
+
+ /* We can delete the table that was passed as a parameter */
+
+ acpi_tb_delete_table(table_desc);
+
+ /* Setup descriptor for the new table */
+
+ table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table);
+ table_desc->pointer = override_table;
+ table_desc->length = override_table->length;
+ table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+ }
+
/* Add the table to the global root table list */
status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
@@ -247,8 +273,9 @@ acpi_status acpi_tb_resize_root_table_list(void)
/* Increase the Table Array size */
tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
- size + ACPI_ROOT_TABLE_SIZE_INCREMENT)
- * sizeof(struct acpi_table_desc));
+ size +
+ ACPI_ROOT_TABLE_SIZE_INCREMENT) *
+ sizeof(struct acpi_table_desc));
if (!tables) {
ACPI_ERROR((AE_INFO,
"Could not allocate new root table array"));
@@ -407,27 +434,56 @@ void acpi_tb_terminate(void)
*
* PARAMETERS: table_index - Table index
*
- * RETURN: None
+ * RETURN: Status
*
* DESCRIPTION: Delete all namespace objects created when this table was loaded.
*
******************************************************************************/
-void acpi_tb_delete_namespace_by_owner(u32 table_index)
+acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
{
acpi_owner_id owner_id;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ if (table_index >= acpi_gbl_root_table_list.count) {
+
+ /* The table index does not exist */
- (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
- if (table_index < acpi_gbl_root_table_list.count) {
- owner_id =
- acpi_gbl_root_table_list.tables[table_index].owner_id;
- } else {
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
- return;
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
+ /* Get the owner ID for this table, used to delete namespace nodes */
+
+ owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+
+ /*
+ * Need to acquire the namespace writer lock to prevent interference
+ * with any concurrent namespace walks. The interpreter must be
+ * released during the deletion since the acquisition of the deletion
+ * lock may block, and also since the execution of a namespace walk
+ * must be allowed to use the interpreter.
+ */
+ acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
+ status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
+
acpi_ns_delete_namespace_by_owner(owner_id);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
+ return_ACPI_STATUS(status);
}
/*******************************************************************************
@@ -535,8 +591,8 @@ u8 acpi_tb_is_table_loaded(u32 table_index)
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
if (table_index < acpi_gbl_root_table_list.count) {
is_loaded = (u8)
- (acpi_gbl_root_table_list.tables[table_index].
- flags & ACPI_TABLE_IS_LOADED);
+ (acpi_gbl_root_table_list.tables[table_index].flags &
+ ACPI_TABLE_IS_LOADED);
}
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 22ce4898572..ef7d2c2d8f0 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -177,19 +177,23 @@ acpi_tb_print_table_header(acpi_physical_address address,
struct acpi_table_header *header)
{
+ /*
+ * The reason that the Address is cast to a void pointer is so that we
+ * can use %p which will work properly on both 32-bit and 64-bit hosts.
+ */
if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
- /* FACS only has signature and length fields of common table header */
+ /* FACS only has signature and length fields */
- ACPI_INFO((AE_INFO, "%4.4s %08lX, %04X",
- header->signature, (unsigned long)address,
+ ACPI_INFO((AE_INFO, "%4.4s %p %05X",
+ header->signature, ACPI_CAST_PTR(void, address),
header->length));
} else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
/* RSDP has no common fields */
- ACPI_INFO((AE_INFO, "RSDP %08lX, %04X (r%d %6.6s)",
- (unsigned long)address,
+ ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
+ ACPI_CAST_PTR (void, address),
(ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
revision >
0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
@@ -202,8 +206,8 @@ acpi_tb_print_table_header(acpi_physical_address address,
/* Standard ACPI table with full common header */
ACPI_INFO((AE_INFO,
- "%4.4s %08lX, %04X (r%d %6.6s %8.8s %8X %4.4s %8X)",
- header->signature, (unsigned long)address,
+ "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
+ header->signature, ACPI_CAST_PTR (void, address),
header->length, header->revision, header->oem_id,
header->oem_table_id, header->oem_revision,
header->asl_compiler_id,
@@ -280,22 +284,28 @@ u8 acpi_tb_checksum(u8 *buffer, u32 length)
* FUNCTION: acpi_tb_install_table
*
* PARAMETERS: Address - Physical address of DSDT or FACS
- * Flags - Flags
* Signature - Table signature, NULL if no need to
* match
* table_index - Index into root table array
*
* RETURN: None
*
- * DESCRIPTION: Install an ACPI table into the global data structure.
+ * DESCRIPTION: Install an ACPI table into the global data structure. The
+ * table override mechanism is implemented here to allow the host
+ * OS to replace any table before it is installed in the root
+ * table array.
*
******************************************************************************/
void
acpi_tb_install_table(acpi_physical_address address,
- u8 flags, char *signature, u32 table_index)
+ char *signature, u32 table_index)
{
- struct acpi_table_header *table;
+ u8 flags;
+ acpi_status status;
+ struct acpi_table_header *table_to_install;
+ struct acpi_table_header *mapped_table;
+ struct acpi_table_header *override_table = NULL;
if (!address) {
ACPI_ERROR((AE_INFO,
@@ -306,41 +316,69 @@ acpi_tb_install_table(acpi_physical_address address,
/* Map just the table header */
- table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
- if (!table) {
+ mapped_table =
+ acpi_os_map_memory(address, sizeof(struct acpi_table_header));
+ if (!mapped_table) {
return;
}
- /* If a particular signature is expected, signature must match */
+ /* If a particular signature is expected (DSDT/FACS), it must match */
- if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
+ if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) {
ACPI_ERROR((AE_INFO,
- "Invalid signature 0x%X for ACPI table [%s]",
- *ACPI_CAST_PTR(u32, table->signature), signature));
+ "Invalid signature 0x%X for ACPI table, expected [%s]",
+ *ACPI_CAST_PTR(u32, mapped_table->signature),
+ signature));
goto unmap_and_exit;
}
+ /*
+ * ACPI Table Override:
+ *
+ * Before we install the table, let the host OS override it with a new
+ * one if desired. Any table within the RSDT/XSDT can be replaced,
+ * including the DSDT which is pointed to by the FADT.
+ */
+ status = acpi_os_table_override(mapped_table, &override_table);
+ if (ACPI_SUCCESS(status) && override_table) {
+ ACPI_INFO((AE_INFO,
+ "%4.4s @ 0x%p Table override, replaced with:",
+ mapped_table->signature, ACPI_CAST_PTR(void,
+ address)));
+
+ acpi_gbl_root_table_list.tables[table_index].pointer =
+ override_table;
+ address = ACPI_PTR_TO_PHYSADDR(override_table);
+
+ table_to_install = override_table;
+ flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+ } else {
+ table_to_install = mapped_table;
+ flags = ACPI_TABLE_ORIGIN_MAPPED;
+ }
+
/* Initialize the table entry */
acpi_gbl_root_table_list.tables[table_index].address = address;
- acpi_gbl_root_table_list.tables[table_index].length = table->length;
+ acpi_gbl_root_table_list.tables[table_index].length =
+ table_to_install->length;
acpi_gbl_root_table_list.tables[table_index].flags = flags;
ACPI_MOVE_32_TO_32(&
(acpi_gbl_root_table_list.tables[table_index].
- signature), table->signature);
+ signature), table_to_install->signature);
- acpi_tb_print_table_header(address, table);
+ acpi_tb_print_table_header(address, table_to_install);
if (table_index == ACPI_TABLE_INDEX_DSDT) {
/* Global integer width is based upon revision of the DSDT */
- acpi_ut_set_integer_width(table->revision);
+ acpi_ut_set_integer_width(table_to_install->revision);
}
unmap_and_exit:
- acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+ acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
}
/*******************************************************************************
@@ -379,7 +417,8 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
} else {
/*
* 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
- * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit
+ * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
+ * return 64-bit
*/
ACPI_MOVE_64_TO_64(&address64, table_entry);
@@ -389,7 +428,8 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
/* Will truncate 64-bit address to 32 bits, issue warning */
ACPI_WARNING((AE_INFO,
- "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating",
+ "64-bit Physical Address in XSDT is too large (%8.8X%8.8X),"
+ " truncating",
ACPI_FORMAT_UINT64(address64)));
}
#endif
@@ -402,7 +442,6 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
* FUNCTION: acpi_tb_parse_root_table
*
* PARAMETERS: Rsdp - Pointer to the RSDP
- * Flags - Flags
*
* RETURN: Status
*
@@ -416,7 +455,7 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
******************************************************************************/
acpi_status __init
-acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
+acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
{
struct acpi_table_rsdp *rsdp;
u32 table_entry_size;
@@ -513,13 +552,12 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
/* Calculate the number of tables described in the root table */
- table_count =
- (u32) ((table->length -
- sizeof(struct acpi_table_header)) / table_entry_size);
-
+ table_count = (u32)((table->length - sizeof(struct acpi_table_header)) /
+ table_entry_size);
/*
- * First two entries in the table array are reserved for the DSDT and FACS,
- * which are not actually present in the RSDT/XSDT - they come from the FADT
+ * First two entries in the table array are reserved for the DSDT
+ * and FACS, which are not actually present in the RSDT/XSDT - they
+ * come from the FADT
*/
table_entry =
ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
@@ -567,14 +605,14 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
*/
for (i = 2; i < acpi_gbl_root_table_list.count; i++) {
acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
- address, flags, NULL, i);
+ address, NULL, i);
/* Special case for FADT - get the DSDT and FACS */
if (ACPI_COMPARE_NAME
(&acpi_gbl_root_table_list.tables[i].signature,
ACPI_SIG_FADT)) {
- acpi_tb_parse_fadt(i, flags);
+ acpi_tb_parse_fadt(i);
}
}
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index ab0aff3c7d6..a88f02bd6c9 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -150,8 +150,7 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
* Root Table Array. This array contains the information of the RSDT/XSDT
* in a common, more useable format.
*/
- status =
- acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED);
+ status = acpi_tb_parse_root_table(rsdp_address);
return_ACPI_STATUS(status);
}
@@ -247,7 +246,7 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
ACPI_EXPORT_SYMBOL(acpi_load_table)
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_get_table_header
*
@@ -262,7 +261,7 @@ ACPI_EXPORT_SYMBOL(acpi_load_table)
* NOTE: Caller is responsible in unmapping the header with
* acpi_os_unmap_memory
*
- *****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_get_table_header(char *signature,
u32 instance, struct acpi_table_header *out_table_header)
@@ -277,9 +276,8 @@ acpi_get_table_header(char *signature,
return (AE_BAD_PARAMETER);
}
- /*
- * Walk the root table list
- */
+ /* Walk the root table list */
+
for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
if (!ACPI_COMPARE_NAME
(&(acpi_gbl_root_table_list.tables[i].signature),
@@ -292,8 +290,8 @@ acpi_get_table_header(char *signature,
}
if (!acpi_gbl_root_table_list.tables[i].pointer) {
- if ((acpi_gbl_root_table_list.tables[i].
- flags & ACPI_TABLE_ORIGIN_MASK) ==
+ if ((acpi_gbl_root_table_list.tables[i].flags &
+ ACPI_TABLE_ORIGIN_MASK) ==
ACPI_TABLE_ORIGIN_MAPPED) {
header =
acpi_os_map_memory(acpi_gbl_root_table_list.
@@ -324,7 +322,7 @@ acpi_get_table_header(char *signature,
ACPI_EXPORT_SYMBOL(acpi_get_table_header)
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_unload_table_id
*
@@ -375,7 +373,7 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
*
* DESCRIPTION: Finds and verifies an ACPI table.
*
- *****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_get_table_with_size(char *signature,
u32 instance, struct acpi_table_header **out_table,
@@ -391,9 +389,8 @@ acpi_get_table_with_size(char *signature,
return (AE_BAD_PARAMETER);
}
- /*
- * Walk the root table list
- */
+ /* Walk the root table list */
+
for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
if (!ACPI_COMPARE_NAME
(&(acpi_gbl_root_table_list.tables[i].signature),
@@ -502,7 +499,6 @@ ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
static acpi_status acpi_tb_load_namespace(void)
{
acpi_status status;
- struct acpi_table_header *table;
u32 i;
ACPI_FUNCTION_TRACE(tb_load_namespace);
@@ -526,58 +522,28 @@ static acpi_status acpi_tb_load_namespace(void)
goto unlock_and_exit;
}
- /*
- * Find DSDT table
- */
- status =
- acpi_os_table_override(acpi_gbl_root_table_list.
- tables[ACPI_TABLE_INDEX_DSDT].pointer,
- &table);
- if (ACPI_SUCCESS(status) && table) {
- /*
- * DSDT table has been found
- */
- acpi_tb_delete_table(&acpi_gbl_root_table_list.
- tables[ACPI_TABLE_INDEX_DSDT]);
- acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
- table;
- acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
- table->length;
- acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
- ACPI_TABLE_ORIGIN_UNKNOWN;
-
- ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
- acpi_tb_print_table_header(0, table);
-
- if (no_auto_ssdt == 0) {
- printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
- }
- }
+ /* A valid DSDT is required */
status =
acpi_tb_verify_table(&acpi_gbl_root_table_list.
tables[ACPI_TABLE_INDEX_DSDT]);
if (ACPI_FAILURE(status)) {
- /* A valid DSDT is required */
-
status = AE_NO_ACPI_TABLES;
goto unlock_and_exit;
}
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
- /*
- * Load and parse tables.
- */
+ /* Load and parse tables */
+
status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- /*
- * Load any SSDT or PSDT tables. Note: Loop leaves tables locked
- */
+ /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
+
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
if ((!ACPI_COMPARE_NAME
@@ -630,9 +596,8 @@ acpi_status acpi_load_tables(void)
ACPI_FUNCTION_TRACE(acpi_load_tables);
- /*
- * Load the namespace from the tables
- */
+ /* Load the namespace from the tables */
+
status = acpi_tb_load_namespace();
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c
index b7fc8dd4334..85ea834199e 100644
--- a/drivers/acpi/acpica/tbxfroot.c
+++ b/drivers/acpi/acpica/tbxfroot.c
@@ -75,8 +75,8 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
* Note: Sometimes there exists more than one RSDP in memory; the valid
* RSDP has a valid checksum, all others have an invalid checksum.
*/
- if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)
- != 0) {
+ if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP,
+ sizeof(ACPI_SIG_RSDP) - 1) != 0) {
/* Nope, BAD Signature */
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c
index b0dcfd3c872..919624f123d 100644
--- a/drivers/acpi/acpica/utcopy.c
+++ b/drivers/acpi/acpica/utcopy.c
@@ -135,11 +135,11 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
* In general, the external object will be the same type as
* the internal object
*/
- external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+ external_object->type = internal_object->common.type;
/* However, only a limited number of external types are supported */
- switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
+ switch (internal_object->common.type) {
case ACPI_TYPE_STRING:
external_object->string.pointer = (char *)data_space;
@@ -222,8 +222,8 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
*/
ACPI_ERROR((AE_INFO,
"Unsupported object type, cannot convert to external object: %s",
- acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
- (internal_object))));
+ acpi_ut_get_type_name(internal_object->common.
+ type)));
return_ACPI_STATUS(AE_SUPPORT);
}
@@ -355,7 +355,7 @@ acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
info.object_space = 0;
info.num_packages = 1;
- external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+ external_object->type = internal_object->common.type;
external_object->package.count = internal_object->package.count;
external_object->package.elements = ACPI_CAST_PTR(union acpi_object,
info.free_space);
@@ -399,7 +399,7 @@ acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object,
ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);
- if (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE) {
+ if (internal_object->common.type == ACPI_TYPE_PACKAGE) {
/*
* Package object: Copy all subobjects (including
* nested packages)
@@ -496,8 +496,9 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
case ACPI_TYPE_STRING:
internal_object->string.pointer =
- ACPI_ALLOCATE_ZEROED((acpi_size) external_object->string.
- length + 1);
+ ACPI_ALLOCATE_ZEROED((acpi_size)
+ external_object->string.length + 1);
+
if (!internal_object->string.pointer) {
goto error_exit;
}
@@ -697,7 +698,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
/* Handle the objects with extra data */
- switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+ switch (dest_desc->common.type) {
case ACPI_TYPE_BUFFER:
/*
* Allocate and copy the actual buffer if and only if:
@@ -814,8 +815,8 @@ acpi_ut_copy_ielement_to_ielement(u8 object_type,
* This is a simple object, just copy it
*/
target_object =
- acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
- (source_object));
+ acpi_ut_create_internal_object(source_object->
+ common.type);
if (!target_object) {
return (AE_NO_MEMORY);
}
@@ -892,7 +893,7 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);
- dest_obj->common.type = ACPI_GET_OBJECT_TYPE(source_obj);
+ dest_obj->common.type = source_obj->common.type;
dest_obj->common.flags = source_obj->common.flags;
dest_obj->package.count = source_obj->package.count;
@@ -950,15 +951,14 @@ acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
/* Create the top level object */
- *dest_desc =
- acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE(source_desc));
+ *dest_desc = acpi_ut_create_internal_object(source_desc->common.type);
if (!*dest_desc) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Copy the object and possible subobjects */
- if (ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_PACKAGE) {
+ if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
status =
acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
walk_state);
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c
index a0be9e39531..a5ee23bc4f5 100644
--- a/drivers/acpi/acpica/utdelete.c
+++ b/drivers/acpi/acpica/utdelete.c
@@ -86,7 +86,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
* Must delete or free any pointers within the object that are not
* actual ACPI objects (for example, a raw buffer pointer).
*/
- switch (ACPI_GET_OBJECT_TYPE(object)) {
+ switch (object->common.type) {
case ACPI_TYPE_STRING:
ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
@@ -382,7 +382,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
object, new_count));
}
- if (ACPI_GET_OBJECT_TYPE(object) == ACPI_TYPE_METHOD) {
+ if (object->common.type == ACPI_TYPE_METHOD) {
ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
"Method Obj %p Refs=%X, [Decremented]\n",
object, new_count));
@@ -469,7 +469,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
* All sub-objects must have their reference count incremented also.
* Different object types have different subobjects.
*/
- switch (ACPI_GET_OBJECT_TYPE(object)) {
+ switch (object->common.type) {
case ACPI_TYPE_DEVICE:
case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_POWER:
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c
index 9c9897dbe90..006b16c2601 100644
--- a/drivers/acpi/acpica/uteval.c
+++ b/drivers/acpi/acpica/uteval.c
@@ -59,26 +59,35 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
/*
* Strings supported by the _OSI predefined (internal) method.
+ *
+ * March 2009: Removed "Linux" as this host no longer wants to respond true
+ * for this string. Basically, the only safe OS strings are windows-related
+ * and in many or most cases represent the only test path within the
+ * BIOS-provided ASL code.
+ *
+ * The second element of each entry is used to track the newest version of
+ * Windows that the BIOS has requested.
*/
-static char *acpi_interfaces_supported[] = {
+static struct acpi_interface_info acpi_interfaces_supported[] = {
/* Operating System Vendor Strings */
- "Windows 2000", /* Windows 2000 */
- "Windows 2001", /* Windows XP */
- "Windows 2001 SP1", /* Windows XP SP1 */
- "Windows 2001 SP2", /* Windows XP SP2 */
- "Windows 2001.1", /* Windows Server 2003 */
- "Windows 2001.1 SP1", /* Windows Server 2003 SP1 - Added 03/2006 */
- "Windows 2006", /* Windows Vista - Added 03/2006 */
+ {"Windows 2000", ACPI_OSI_WIN_2000}, /* Windows 2000 */
+ {"Windows 2001", ACPI_OSI_WIN_XP}, /* Windows XP */
+ {"Windows 2001 SP1", ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */
+ {"Windows 2001.1", ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */
+ {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */
+ {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */
+ {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */
/* Feature Group Strings */
- "Extended Address Space Descriptor"
- /*
- * All "optional" feature group strings (features that are implemented
- * by the host) should be implemented in the host version of
- * acpi_os_validate_interface and should not be added here.
- */
+ {"Extended Address Space Descriptor", 0}
+
+ /*
+ * All "optional" feature group strings (features that are implemented
+ * by the host) should be implemented in the host version of
+ * acpi_os_validate_interface and should not be added here.
+ */
};
/*******************************************************************************
@@ -98,6 +107,7 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
acpi_status status;
union acpi_operand_object *string_desc;
union acpi_operand_object *return_desc;
+ u32 return_value;
u32 i;
ACPI_FUNCTION_TRACE(ut_osi_implementation);
@@ -116,19 +126,28 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
return_ACPI_STATUS(AE_NO_MEMORY);
}
- /* Default return value is 0, NOT-SUPPORTED */
+ /* Default return value is 0, NOT SUPPORTED */
- return_desc->integer.value = 0;
- walk_state->return_desc = return_desc;
+ return_value = 0;
/* Compare input string to static table of supported interfaces */
for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
- if (!ACPI_STRCMP
- (string_desc->string.pointer,
- acpi_interfaces_supported[i])) {
- return_desc->integer.value = ACPI_UINT32_MAX;
- goto done;
+ if (!ACPI_STRCMP(string_desc->string.pointer,
+ acpi_interfaces_supported[i].name)) {
+ /*
+ * The interface is supported.
+ * Update the osi_data if necessary. We keep track of the latest
+ * version of Windows that has been requested by the BIOS.
+ */
+ if (acpi_interfaces_supported[i].value >
+ acpi_gbl_osi_data) {
+ acpi_gbl_osi_data =
+ acpi_interfaces_supported[i].value;
+ }
+
+ return_value = ACPI_UINT32_MAX;
+ goto exit;
}
}
@@ -139,15 +158,22 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
*/
status = acpi_os_validate_interface(string_desc->string.pointer);
if (ACPI_SUCCESS(status)) {
- return_desc->integer.value = ACPI_UINT32_MAX;
+
+ /* The interface is supported */
+
+ return_value = ACPI_UINT32_MAX;
}
-done:
- ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n",
- string_desc->string.pointer,
- return_desc->integer.value == 0 ? "not-" : ""));
+exit:
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
+ "ACPI: BIOS _OSI(%s) is %ssupported\n",
+ string_desc->string.pointer, return_value == 0 ? "not " : ""));
- return_ACPI_STATUS(AE_OK);
+ /* Complete the return value */
+
+ return_desc->integer.value = return_value;
+ walk_state->return_desc = return_desc;
+ return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
@@ -167,8 +193,8 @@ acpi_status acpi_osi_invalidate(char *interface)
int i;
for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
- if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) {
- *acpi_interfaces_supported[i] = '\0';
+ if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) {
+ *acpi_interfaces_supported[i].name = '\0';
return AE_OK;
}
}
@@ -248,7 +274,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
/* Map the return object type to the bitmapped type */
- switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
+ switch ((info->return_object)->common.type) {
case ACPI_TYPE_INTEGER:
return_btype = ACPI_BTYPE_INTEGER;
break;
@@ -418,7 +444,7 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
return_ACPI_STATUS(status);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
/* Convert the Numeric HID to string */
@@ -459,7 +485,7 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
struct acpi_compatible_id *one_cid)
{
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
/* Convert the Numeric CID to string */
@@ -527,7 +553,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
/* Get the number of _CIDs returned */
count = 1;
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+ if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
count = obj_desc->package.count;
}
@@ -555,7 +581,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
/* The _CID object can be either a single CID or a package (list) of CIDs */
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+ if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
/* Translate each package element */
@@ -620,7 +646,7 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
return_ACPI_STATUS(status);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
/* Convert the Numeric UID to string */
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c
index a3ab9d9da29..59e46f257c0 100644
--- a/drivers/acpi/acpica/utglobal.c
+++ b/drivers/acpi/acpica/utglobal.c
@@ -294,12 +294,9 @@ struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = {
/* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL,
ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE,
ACPI_BITMASK_GLOBAL_LOCK_RELEASE},
- /* ACPI_BITREG_SLEEP_TYPE_A */ {ACPI_REGISTER_PM1_CONTROL,
- ACPI_BITPOSITION_SLEEP_TYPE_X,
- ACPI_BITMASK_SLEEP_TYPE_X},
- /* ACPI_BITREG_SLEEP_TYPE_B */ {ACPI_REGISTER_PM1_CONTROL,
- ACPI_BITPOSITION_SLEEP_TYPE_X,
- ACPI_BITMASK_SLEEP_TYPE_X},
+ /* ACPI_BITREG_SLEEP_TYPE */ {ACPI_REGISTER_PM1_CONTROL,
+ ACPI_BITPOSITION_SLEEP_TYPE,
+ ACPI_BITMASK_SLEEP_TYPE},
/* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL,
ACPI_BITPOSITION_SLEEP_ENABLE,
ACPI_BITMASK_SLEEP_ENABLE},
@@ -476,7 +473,7 @@ char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
return ("[NULL Object Descriptor]");
}
- return (acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)));
+ return (acpi_ut_get_type_name(obj_desc->common.type));
}
/*******************************************************************************
@@ -749,7 +746,10 @@ acpi_status acpi_ut_init_globals(void)
for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
acpi_gbl_owner_id_mask[i] = 0;
}
- acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; /* Last ID is never valid */
+
+ /* Last owner_iD is never valid */
+
+ acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
/* GPE support */
@@ -789,6 +789,7 @@ acpi_status acpi_ut_init_globals(void)
acpi_gbl_trace_dbg_layer = 0;
acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
+ acpi_gbl_osi_data = 0;
/* Hardware oriented */
diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c
new file mode 100644
index 00000000000..25e03120686
--- /dev/null
+++ b/drivers/acpi/acpica/utlock.c
@@ -0,0 +1,175 @@
+/******************************************************************************
+ *
+ * Module Name: utlock - Reader/Writer lock interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2009, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT ACPI_UTILITIES
+ACPI_MODULE_NAME("utlock")
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_rw_lock
+ * acpi_ut_delete_rw_lock
+ *
+ * PARAMETERS: Lock - Pointer to a valid RW lock
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Reader/writer lock creation and deletion interfaces.
+ *
+ ******************************************************************************/
+acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock)
+{
+ acpi_status status;
+
+ lock->num_readers = 0;
+ status = acpi_os_create_mutex(&lock->reader_mutex);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ status = acpi_os_create_mutex(&lock->writer_mutex);
+ return status;
+}
+
+void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock)
+{
+
+ acpi_os_delete_mutex(lock->reader_mutex);
+ acpi_os_delete_mutex(lock->writer_mutex);
+
+ lock->num_readers = 0;
+ lock->reader_mutex = NULL;
+ lock->writer_mutex = NULL;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_acquire_read_lock
+ * acpi_ut_release_read_lock
+ *
+ * PARAMETERS: Lock - Pointer to a valid RW lock
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition,
+ * only the first reader acquires the write mutex. On release,
+ * only the last reader releases the write mutex. Although this
+ * algorithm can in theory starve writers, this should not be a
+ * problem with ACPICA since the subsystem is infrequently used
+ * in comparison to (for example) an I/O system.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock)
+{
+ acpi_status status;
+
+ status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ /* Acquire the write lock only for the first reader */
+
+ lock->num_readers++;
+ if (lock->num_readers == 1) {
+ status =
+ acpi_os_acquire_mutex(lock->writer_mutex,
+ ACPI_WAIT_FOREVER);
+ }
+
+ acpi_os_release_mutex(lock->reader_mutex);
+ return status;
+}
+
+acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock)
+{
+ acpi_status status;
+
+ status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ /* Release the write lock only for the very last reader */
+
+ lock->num_readers--;
+ if (lock->num_readers == 0) {
+ acpi_os_release_mutex(lock->writer_mutex);
+ }
+
+ acpi_os_release_mutex(lock->reader_mutex);
+ return status;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_acquire_write_lock
+ * acpi_ut_release_write_lock
+ *
+ * PARAMETERS: Lock - Pointer to a valid RW lock
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or
+ * release the writer mutex associated with the lock. Acquisition
+ * of the lock is fully exclusive and will block all readers and
+ * writers until it is released.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock)
+{
+ acpi_status status;
+
+ status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER);
+ return status;
+}
+
+void acpi_ut_release_write_lock(struct acpi_rw_lock *lock)
+{
+
+ acpi_os_release_mutex(lock->writer_mutex);
+}
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c
index c1f7f4e1a72..1c9e250caef 100644
--- a/drivers/acpi/acpica/utmisc.c
+++ b/drivers/acpi/acpica/utmisc.c
@@ -938,8 +938,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
if ((!this_source_obj) ||
(ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
ACPI_DESC_TYPE_OPERAND)
- || (ACPI_GET_OBJECT_TYPE(this_source_obj) !=
- ACPI_TYPE_PACKAGE)) {
+ || (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) {
status =
walk_callback(ACPI_COPY_TYPE_SIMPLE,
this_source_obj, state, context);
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index 14eb52c4d64..26c93a748e6 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -60,7 +60,8 @@ static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
*
* RETURN: Status
*
- * DESCRIPTION: Create the system mutex objects.
+ * DESCRIPTION: Create the system mutex objects. This includes mutexes,
+ * spin locks, and reader/writer locks.
*
******************************************************************************/
@@ -71,9 +72,8 @@ acpi_status acpi_ut_mutex_initialize(void)
ACPI_FUNCTION_TRACE(ut_mutex_initialize);
- /*
- * Create each of the predefined mutex objects
- */
+ /* Create each of the predefined mutex objects */
+
for (i = 0; i < ACPI_NUM_MUTEX; i++) {
status = acpi_ut_create_mutex(i);
if (ACPI_FAILURE(status)) {
@@ -86,6 +86,9 @@ acpi_status acpi_ut_mutex_initialize(void)
spin_lock_init(acpi_gbl_gpe_lock);
spin_lock_init(acpi_gbl_hardware_lock);
+ /* Create the reader/writer lock for namespace access */
+
+ status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
return_ACPI_STATUS(status);
}
@@ -97,7 +100,8 @@ acpi_status acpi_ut_mutex_initialize(void)
*
* RETURN: None.
*
- * DESCRIPTION: Delete all of the system mutex objects.
+ * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
+ * spin locks, and reader/writer locks.
*
******************************************************************************/
@@ -107,9 +111,8 @@ void acpi_ut_mutex_terminate(void)
ACPI_FUNCTION_TRACE(ut_mutex_terminate);
- /*
- * Delete each predefined mutex object
- */
+ /* Delete each predefined mutex object */
+
for (i = 0; i < ACPI_NUM_MUTEX; i++) {
(void)acpi_ut_delete_mutex(i);
}
@@ -118,6 +121,10 @@ void acpi_ut_mutex_terminate(void)
acpi_os_delete_lock(acpi_gbl_gpe_lock);
acpi_os_delete_lock(acpi_gbl_hardware_lock);
+
+ /* Delete the reader/writer lock */
+
+ acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
return_VOID;
}
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c
index fd5ea7543e5..0207b625274 100644
--- a/drivers/acpi/acpica/utobject.c
+++ b/drivers/acpi/acpica/utobject.c
@@ -310,7 +310,7 @@ u8 acpi_ut_valid_internal_object(void *object)
/* Check for a null pointer */
if (!object) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Null Object Ptr\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
return (FALSE);
}
@@ -324,7 +324,7 @@ u8 acpi_ut_valid_internal_object(void *object)
return (TRUE);
default:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"%p is not not an ACPI operand obj [%s]\n",
object, acpi_ut_get_descriptor_name(object)));
break;
@@ -457,7 +457,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
* must be accessed bytewise or there may be alignment problems on
* certain processors
*/
- switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
+ switch (internal_object->common.type) {
case ACPI_TYPE_STRING:
length += (acpi_size) internal_object->string.length + 1;
@@ -518,8 +518,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
ACPI_ERROR((AE_INFO, "Cannot convert to external object - "
"unsupported type [%s] %X in object %p",
acpi_ut_get_object_type_name(internal_object),
- ACPI_GET_OBJECT_TYPE(internal_object),
- internal_object));
+ internal_object->common.type, internal_object));
status = AE_TYPE;
break;
}
@@ -664,7 +663,7 @@ acpi_ut_get_object_size(union acpi_operand_object *internal_object,
if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) ==
ACPI_DESC_TYPE_OPERAND)
- && (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE)) {
+ && (internal_object->common.type == ACPI_TYPE_PACKAGE)) {
status =
acpi_ut_get_package_object_size(internal_object,
obj_length);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 3bcb5bfc45d..b0de6312919 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/jiffies.h>
+#include <linux/async.h>
#ifdef CONFIG_ACPI_PROCFS_POWER
#include <linux/proc_fs.h>
@@ -92,7 +93,7 @@ struct acpi_battery {
#endif
struct acpi_device *device;
unsigned long update_time;
- int current_now;
+ int rate_now;
int capacity_now;
int voltage_now;
int design_capacity;
@@ -196,7 +197,8 @@ static int acpi_battery_get_property(struct power_supply *psy,
val->intval = battery->voltage_now * 1000;
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
- val->intval = battery->current_now * 1000;
+ case POWER_SUPPLY_PROP_POWER_NOW:
+ val->intval = battery->rate_now * 1000;
break;
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
@@ -247,6 +249,7 @@ static enum power_supply_property energy_battery_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_POWER_NOW,
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_FULL,
POWER_SUPPLY_PROP_ENERGY_NOW,
@@ -273,7 +276,7 @@ struct acpi_offsets {
static struct acpi_offsets state_offsets[] = {
{offsetof(struct acpi_battery, state), 0},
- {offsetof(struct acpi_battery, current_now), 0},
+ {offsetof(struct acpi_battery, rate_now), 0},
{offsetof(struct acpi_battery, capacity_now), 0},
{offsetof(struct acpi_battery, voltage_now), 0},
};
@@ -605,11 +608,11 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
else
seq_printf(seq, "charging state: charged\n");
- if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
+ if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "present rate: unknown\n");
else
seq_printf(seq, "present rate: %d %s\n",
- battery->current_now, acpi_battery_units(battery));
+ battery->rate_now, acpi_battery_units(battery));
if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "remaining capacity: unknown\n");
@@ -740,7 +743,7 @@ DECLARE_FILE_FUNCTIONS(alarm);
static struct battery_file {
struct file_operations ops;
mode_t mode;
- char *name;
+ const char *name;
} acpi_battery_file[] = {
FILE_DESCRIPTION_RO(info),
FILE_DESCRIPTION_RO(state),
@@ -900,21 +903,27 @@ static struct acpi_driver acpi_battery_driver = {
},
};
-static int __init acpi_battery_init(void)
+static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
{
if (acpi_disabled)
- return -ENODEV;
+ return;
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_battery_dir = acpi_lock_battery_dir();
if (!acpi_battery_dir)
- return -ENODEV;
+ return;
#endif
if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_unlock_battery_dir(acpi_battery_dir);
#endif
- return -ENODEV;
+ return;
}
+ return;
+}
+
+static int __init acpi_battery_init(void)
+{
+ async_schedule(acpi_battery_init_async, NULL);
return 0;
}
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index bee64b73c91..e8f7b64e92d 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -39,6 +39,8 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
+#include "internal.h"
+
#define _COMPONENT ACPI_BUS_COMPONENT
ACPI_MODULE_NAME("bus");
@@ -846,6 +848,7 @@ static int __init acpi_init(void)
acpi_kobj = NULL;
}
+ init_acpi_device_notify();
result = acpi_bus_init();
if (!result) {
@@ -860,11 +863,23 @@ static int __init acpi_init(void)
}
} else
disable_acpi();
+
+ if (acpi_disabled)
+ return result;
+
/*
* If the laptop falls into the DMI check table, the power state check
* will be disabled in the course of device power transistion.
*/
dmi_check_system(power_nocheck_dmi_table);
+
+ acpi_scan_init();
+ acpi_ec_init();
+ acpi_power_init();
+ acpi_system_init();
+ acpi_debug_init();
+ acpi_sleep_proc_init();
+ acpi_wakeup_device_init();
return result;
}
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index c2f06069dcd..d73c94b8441 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -78,6 +78,7 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);
static int acpi_button_add(struct acpi_device *device);
static int acpi_button_remove(struct acpi_device *device, int type);
static int acpi_button_resume(struct acpi_device *device);
+static void acpi_button_notify(struct acpi_device *device, u32 event);
static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
@@ -89,6 +90,7 @@ static struct acpi_driver acpi_button_driver = {
.add = acpi_button_add,
.resume = acpi_button_resume,
.remove = acpi_button_remove,
+ .notify = acpi_button_notify,
},
};
@@ -263,15 +265,18 @@ static int acpi_lid_send_state(struct acpi_button *button)
return 0;
}
-static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_button_notify(struct acpi_device *device, u32 event)
{
- struct acpi_button *button = data;
+ struct acpi_button *button = acpi_driver_data(device);
struct input_dev *input;
if (!button || !button->device)
return;
switch (event) {
+ case ACPI_FIXED_HARDWARE_EVENT:
+ event = ACPI_BUTTON_NOTIFY_STATUS;
+ /* fall through */
case ACPI_BUTTON_NOTIFY_STATUS:
input = button->input;
if (button->type == ACPI_BUTTON_TYPE_LID) {
@@ -298,46 +303,6 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
return;
}
-static acpi_status acpi_button_notify_fixed(void *data)
-{
- struct acpi_button *button = data;
-
- if (!button)
- return AE_BAD_PARAMETER;
-
- acpi_button_notify(button->device->handle, ACPI_BUTTON_NOTIFY_STATUS, button);
-
- return AE_OK;
-}
-
-static int acpi_button_install_notify_handlers(struct acpi_button *button)
-{
- acpi_status status;
-
- switch (button->type) {
- case ACPI_BUTTON_TYPE_POWERF:
- status =
- acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
- acpi_button_notify_fixed,
- button);
- break;
- case ACPI_BUTTON_TYPE_SLEEPF:
- status =
- acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
- acpi_button_notify_fixed,
- button);
- break;
- default:
- status = acpi_install_notify_handler(button->device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_button_notify,
- button);
- break;
- }
-
- return ACPI_FAILURE(status) ? -ENODEV : 0;
-}
-
static int acpi_button_resume(struct acpi_device *device)
{
struct acpi_button *button;
@@ -349,25 +314,6 @@ static int acpi_button_resume(struct acpi_device *device)
return 0;
}
-static void acpi_button_remove_notify_handlers(struct acpi_button *button)
-{
- switch (button->type) {
- case ACPI_BUTTON_TYPE_POWERF:
- acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
- acpi_button_notify_fixed);
- break;
- case ACPI_BUTTON_TYPE_SLEEPF:
- acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
- acpi_button_notify_fixed);
- break;
- default:
- acpi_remove_notify_handler(button->device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_button_notify);
- break;
- }
-}
-
static int acpi_button_add(struct acpi_device *device)
{
int error;
@@ -432,10 +378,6 @@ static int acpi_button_add(struct acpi_device *device)
if (error)
goto err_free_input;
- error = acpi_button_install_notify_handlers(button);
- if (error)
- goto err_remove_fs;
-
snprintf(button->phys, sizeof(button->phys),
"%s/button/input0", acpi_device_hid(device));
@@ -466,7 +408,7 @@ static int acpi_button_add(struct acpi_device *device)
error = input_register_device(input);
if (error)
- goto err_remove_handlers;
+ goto err_remove_fs;
if (button->type == ACPI_BUTTON_TYPE_LID)
acpi_lid_send_state(button);
@@ -485,8 +427,6 @@ static int acpi_button_add(struct acpi_device *device)
return 0;
- err_remove_handlers:
- acpi_button_remove_notify_handlers(button);
err_remove_fs:
acpi_button_remove_fs(device);
err_free_input:
@@ -505,7 +445,6 @@ static int acpi_button_remove(struct acpi_device *device, int type)
button = acpi_driver_data(device);
- acpi_button_remove_notify_handlers(button);
acpi_button_remove_fs(device);
input_unregister_device(button->input);
kfree(button);
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index 20223cbd0d1..a8287be0870 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -13,11 +13,6 @@
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("debug");
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
-
struct acpi_dlayer {
const char *name;
unsigned long value;
@@ -297,17 +292,15 @@ acpi_system_write_debug(struct file *file,
return count;
}
+#endif
-static int __init acpi_debug_init(void)
+int __init acpi_debug_init(void)
{
+#ifdef CONFIG_ACPI_PROCFS
struct proc_dir_entry *entry;
int error = 0;
char *name;
-
- if (acpi_disabled)
- return 0;
-
/* 'debug_layer' [R/W] */
name = ACPI_SYSTEM_FILE_DEBUG_LAYER;
entry =
@@ -338,7 +331,7 @@ static int __init acpi_debug_init(void)
remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir);
error = -ENODEV;
goto Done;
-}
-
-subsys_initcall(acpi_debug_init);
+#else
+ return 0;
#endif
+}
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 7af7db1ba8c..efb959d6c8a 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -1146,9 +1146,10 @@ static int __init dock_init(void)
static void __exit dock_exit(void)
{
struct dock_station *dock_station;
+ struct dock_station *tmp;
unregister_acpi_bus_notifier(&dock_acpi_notifier);
- list_for_each_entry(dock_station, &dock_stations, sibiling)
+ list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling)
dock_remove(dock_station);
}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 2fe15060dcd..04e90443eff 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -67,7 +67,7 @@ enum ec_command {
#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */
#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
-#define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */
+#define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */
#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts
per one transaction */
@@ -236,13 +236,23 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
return 0;
}
+static void ec_delay(void)
+{
+ /* EC in MSI notebooks don't tolerate delays other than 550 usec */
+ if (EC_FLAGS_MSI)
+ udelay(ACPI_EC_DELAY);
+ else
+ /* Use shortest sleep available */
+ msleep(1);
+}
+
static int ec_poll(struct acpi_ec *ec)
{
unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
- udelay(ACPI_EC_UDELAY);
+ udelay(ACPI_EC_CDELAY);
while (time_before(jiffies, delay)) {
gpe_transaction(ec, acpi_ec_read_status(ec));
- udelay(ACPI_EC_UDELAY);
+ ec_delay();
if (ec_transaction_done(ec))
return 0;
}
@@ -672,7 +682,7 @@ static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_ec_read_info, PDE(inode)->data);
}
-static struct file_operations acpi_ec_info_ops = {
+static const struct file_operations acpi_ec_info_ops = {
.open = acpi_ec_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -755,6 +765,10 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
unsigned long long tmp = 0;
struct acpi_ec *ec = context;
+
+ /* clear addr values, ec_parse_io_ports depend on it */
+ ec->command_addr = ec->data_addr = 0;
+
status = acpi_walk_resources(handle, METHOD_NAME__CRS,
ec_parse_io_ports, ec);
if (ACPI_FAILURE(status))
@@ -804,11 +818,11 @@ static int acpi_ec_add(struct acpi_device *device)
ec = make_acpi_ec();
if (!ec)
return -ENOMEM;
- if (ec_parse_device(device->handle, 0, ec, NULL) !=
- AE_CTRL_TERMINATE) {
+ }
+ if (ec_parse_device(device->handle, 0, ec, NULL) !=
+ AE_CTRL_TERMINATE) {
kfree(ec);
return -EINVAL;
- }
}
ec->handle = device->handle;
@@ -986,12 +1000,12 @@ int __init acpi_ec_ecdt_probe(void)
boot_ec->handle = ACPI_ROOT_OBJECT;
acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
/* Don't trust ECDT, which comes from ASUSTek */
- if (!dmi_name_in_vendors("ASUS"))
+ if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0)
goto install;
saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!saved_ec)
return -ENOMEM;
- memcpy(saved_ec, boot_ec, sizeof(*saved_ec));
+ memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec));
/* fall through */
}
/* This workaround is needed only on some broken machines,
@@ -1069,13 +1083,10 @@ static struct acpi_driver acpi_ec_driver = {
},
};
-static int __init acpi_ec_init(void)
+int __init acpi_ec_init(void)
{
int result = 0;
- if (acpi_disabled)
- return 0;
-
acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
if (!acpi_ec_dir)
return -ENODEV;
@@ -1090,8 +1101,6 @@ static int __init acpi_ec_init(void)
return result;
}
-subsys_initcall(acpi_ec_init);
-
/* EC driver currently not unloadable */
#if 0
static void __exit acpi_ec_exit(void)
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 8a02944bf92..53698ea0837 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -68,31 +68,35 @@ static struct acpi_driver acpi_fan_driver = {
};
/* thermal cooling device callbacks */
-static int fan_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
+ *state)
{
/* ACPI fan device only support two states: ON/OFF */
- return sprintf(buf, "1\n");
+ *state = 1;
+ return 0;
}
-static int fan_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
+ *state)
{
struct acpi_device *device = cdev->devdata;
- int state;
int result;
+ int acpi_state;
if (!device)
return -EINVAL;
- result = acpi_bus_get_power(device->handle, &state);
+ result = acpi_bus_get_power(device->handle, &acpi_state);
if (result)
return result;
- return sprintf(buf, "%s\n", state == ACPI_STATE_D3 ? "0" :
- (state == ACPI_STATE_D0 ? "1" : "unknown"));
+ *state = (acpi_state == ACPI_STATE_D3 ? 0 :
+ (acpi_state == ACPI_STATE_D0 ? 1 : -1));
+ return 0;
}
static int
-fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
{
struct acpi_device *device = cdev->devdata;
int result;
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 5479b9f4251..8bd2c2a6884 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -286,10 +286,8 @@ static int acpi_platform_notify_remove(struct device *dev)
return 0;
}
-static int __init init_acpi_device_notify(void)
+int __init init_acpi_device_notify(void)
{
- if (acpi_disabled)
- return 0;
if (platform_notify || platform_notify_remove) {
printk(KERN_ERR PREFIX "Can't use platform_notify\n");
return 0;
@@ -298,5 +296,3 @@ static int __init init_acpi_device_notify(void)
platform_notify_remove = acpi_platform_notify_remove;
return 0;
}
-
-arch_initcall(init_acpi_device_notify);
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
new file mode 100644
index 00000000000..11a69b53004
--- /dev/null
+++ b/drivers/acpi/internal.h
@@ -0,0 +1,43 @@
+/* For use by Linux/ACPI infrastructure, not drivers */
+
+int init_acpi_device_notify(void);
+int acpi_scan_init(void);
+int acpi_system_init(void);
+
+#ifdef CONFIG_ACPI_DEBUG
+int acpi_debug_init(void);
+#else
+static inline int acpi_debug_init(void) { return 0; }
+#endif
+
+/* --------------------------------------------------------------------------
+ Power Resource
+ -------------------------------------------------------------------------- */
+int acpi_power_init(void);
+int acpi_device_sleep_wake(struct acpi_device *dev,
+ int enable, int sleep_state, int dev_state);
+int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state);
+int acpi_disable_wakeup_device_power(struct acpi_device *dev);
+int acpi_power_get_inferred_state(struct acpi_device *device);
+int acpi_power_transition(struct acpi_device *device, int state);
+extern int acpi_power_nocheck;
+
+int acpi_wakeup_device_init(void);
+
+/* --------------------------------------------------------------------------
+ Embedded Controller
+ -------------------------------------------------------------------------- */
+int acpi_ec_init(void);
+int acpi_ec_ecdt_probe(void);
+int acpi_boot_ec_enable(void);
+
+/*--------------------------------------------------------------------------
+ Suspend/Resume
+ -------------------------------------------------------------------------- */
+extern int acpi_sleep_init(void);
+
+#ifdef CONFIG_ACPI_SLEEP
+int acpi_sleep_proc_init(void);
+#else
+static inline int acpi_sleep_proc_init(void) { return 0; }
+#endif
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 3a0d8ef25c7..d440ccd27d9 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -131,6 +131,21 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
#endif /* ACPI_DEBUG_OUTPUT */
break;
+ case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
+#ifdef ACPI_DEBUG_OUTPUT
+ {
+ struct acpi_srat_x2apic_cpu_affinity *p =
+ (struct acpi_srat_x2apic_cpu_affinity *)header;
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "SRAT Processor (x2apicid[0x%08x]) in"
+ " proximity domain %d %s\n",
+ p->apic_id,
+ p->proximity_domain,
+ (p->flags & ACPI_SRAT_CPU_ENABLED) ?
+ "enabled" : "disabled"));
+ }
+#endif /* ACPI_DEBUG_OUTPUT */
+ break;
default:
printk(KERN_WARNING PREFIX
"Found unsupported SRAT entry (type = 0x%x)\n",
@@ -180,8 +195,35 @@ static int __init acpi_parse_slit(struct acpi_table_header *table)
return 0;
}
+void __init __attribute__ ((weak))
+acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
+{
+ printk(KERN_WARNING PREFIX
+ "Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id);
+ return;
+}
+
+
+static int __init
+acpi_parse_x2apic_affinity(struct acpi_subtable_header *header,
+ const unsigned long end)
+{
+ struct acpi_srat_x2apic_cpu_affinity *processor_affinity;
+
+ processor_affinity = (struct acpi_srat_x2apic_cpu_affinity *)header;
+ if (!processor_affinity)
+ return -EINVAL;
+
+ acpi_table_print_srat_entry(header);
+
+ /* let architecture-dependent part to do it */
+ acpi_numa_x2apic_affinity_init(processor_affinity);
+
+ return 0;
+}
+
static int __init
-acpi_parse_processor_affinity(struct acpi_subtable_header * header,
+acpi_parse_processor_affinity(struct acpi_subtable_header *header,
const unsigned long end)
{
struct acpi_srat_cpu_affinity *processor_affinity;
@@ -241,6 +283,8 @@ int __init acpi_numa_init(void)
{
/* SRAT: Static Resource Affinity Table */
if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
+ acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY,
+ acpi_parse_x2apic_affinity, NR_CPUS);
acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
acpi_parse_processor_affinity, NR_CPUS);
acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index eb8980d6736..d59f08ecaf1 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1070,9 +1070,9 @@ __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
* in arbitrary AML code and can interfere with legacy drivers.
* acpi_enforce_resources= can be set to:
*
- * - strict (2)
+ * - strict (default) (2)
* -> further driver trying to access the resources will not load
- * - lax (default) (1)
+ * - lax (1)
* -> further driver trying to access the resources will load, but you
* get a system message that something might go wrong...
*
@@ -1084,7 +1084,7 @@ __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
#define ENFORCE_RESOURCES_LAX 1
#define ENFORCE_RESOURCES_NO 0
-static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_LAX;
+static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
static int __init acpi_enforce_resources_setup(char *str)
{
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 891bdf6679f..51b9f8280f8 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -86,7 +86,7 @@ static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(struct pci_dev *dev,
}
/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */
-static struct dmi_system_id medion_md9580[] = {
+static const struct dmi_system_id medion_md9580[] = {
{
.ident = "Medion MD9580-F laptop",
.matches = {
@@ -98,7 +98,7 @@ static struct dmi_system_id medion_md9580[] = {
};
/* http://bugzilla.kernel.org/show_bug.cgi?id=5044 */
-static struct dmi_system_id dell_optiplex[] = {
+static const struct dmi_system_id dell_optiplex[] = {
{
.ident = "Dell Optiplex GX1",
.matches = {
@@ -110,7 +110,7 @@ static struct dmi_system_id dell_optiplex[] = {
};
/* http://bugzilla.kernel.org/show_bug.cgi?id=10138 */
-static struct dmi_system_id hp_t5710[] = {
+static const struct dmi_system_id hp_t5710[] = {
{
.ident = "HP t5710",
.matches = {
@@ -123,13 +123,13 @@ static struct dmi_system_id hp_t5710[] = {
};
struct prt_quirk {
- struct dmi_system_id *system;
+ const struct dmi_system_id *system;
unsigned int segment;
unsigned int bus;
unsigned int device;
unsigned char pin;
- char *source; /* according to BIOS */
- char *actual_source;
+ const char *source; /* according to BIOS */
+ const char *actual_source;
};
#define PCI_INTX_PIN(c) (c - 'A' + 1)
@@ -139,7 +139,7 @@ struct prt_quirk {
* interrupt at the listed segment/bus/device/pin is connected to the first
* link device, but it is actually connected to the second.
*/
-static struct prt_quirk prt_quirks[] = {
+static const struct prt_quirk prt_quirks[] = {
{ medion_md9580, 0, 0, 9, PCI_INTX_PIN('A'),
"\\_SB_.PCI0.ISA_.LNKA",
"\\_SB_.PCI0.ISA_.LNKB"},
@@ -155,7 +155,7 @@ static void do_prt_fixups(struct acpi_prt_entry *entry,
struct acpi_pci_routing_table *prt)
{
int i;
- struct prt_quirk *quirk;
+ const struct prt_quirk *quirk;
for (i = 0; i < ARRAY_SIZE(prt_quirks); i++) {
quirk = &prt_quirks[i];
@@ -319,7 +319,7 @@ static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
*/
bridge = dev->bus->self;
while (bridge) {
- pin = (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1;
+ pin = pci_swizzle_interrupt_pin(dev, pin);
if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
/* PC card has the same IRQ as its cardbridge */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 6c772ca76bd..16e0f9d3d17 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -43,13 +43,14 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-#define _COMPONENT ACPI_PCI_COMPONENT
+#define _COMPONENT ACPI_PCI_COMPONENT
ACPI_MODULE_NAME("pci_link");
#define ACPI_PCI_LINK_CLASS "pci_irq_routing"
#define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link"
#define ACPI_PCI_LINK_FILE_INFO "info"
#define ACPI_PCI_LINK_FILE_STATUS "state"
-#define ACPI_PCI_LINK_MAX_POSSIBLE 16
+#define ACPI_PCI_LINK_MAX_POSSIBLE 16
+
static int acpi_pci_link_add(struct acpi_device *device);
static int acpi_pci_link_remove(struct acpi_device *device, int type);
@@ -66,7 +67,7 @@ static struct acpi_driver acpi_pci_link_driver = {
.ops = {
.add = acpi_pci_link_add,
.remove = acpi_pci_link_remove,
- },
+ },
};
/*
@@ -76,7 +77,7 @@ static struct acpi_driver acpi_pci_link_driver = {
struct acpi_pci_link_irq {
u8 active; /* Current IRQ */
u8 triggering; /* All IRQs */
- u8 polarity; /* All IRQs */
+ u8 polarity; /* All IRQs */
u8 resource_type;
u8 possible_count;
u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
@@ -85,16 +86,13 @@ struct acpi_pci_link_irq {
};
struct acpi_pci_link {
- struct list_head node;
- struct acpi_device *device;
- struct acpi_pci_link_irq irq;
- int refcnt;
+ struct list_head list;
+ struct acpi_device *device;
+ struct acpi_pci_link_irq irq;
+ int refcnt;
};
-static struct {
- int count;
- struct list_head entries;
-} acpi_link;
+static LIST_HEAD(acpi_link_list);
static DEFINE_MUTEX(acpi_link_lock);
/* --------------------------------------------------------------------------
@@ -104,12 +102,11 @@ static DEFINE_MUTEX(acpi_link_lock);
/*
* set context (link) possible list from resource list
*/
-static acpi_status
-acpi_pci_link_check_possible(struct acpi_resource *resource, void *context)
+static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,
+ void *context)
{
struct acpi_pci_link *link = context;
- u32 i = 0;
-
+ u32 i;
switch (resource->type) {
case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -179,10 +176,6 @@ static int acpi_pci_link_get_possible(struct acpi_pci_link *link)
{
acpi_status status;
-
- if (!link)
- return -EINVAL;
-
status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS,
acpi_pci_link_check_possible, link);
if (ACPI_FAILURE(status)) {
@@ -197,11 +190,10 @@ static int acpi_pci_link_get_possible(struct acpi_pci_link *link)
return 0;
}
-static acpi_status
-acpi_pci_link_check_current(struct acpi_resource *resource, void *context)
+static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource,
+ void *context)
{
- int *irq = (int *)context;
-
+ int *irq = context;
switch (resource->type) {
case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -258,12 +250,9 @@ acpi_pci_link_check_current(struct acpi_resource *resource, void *context)
static int acpi_pci_link_get_current(struct acpi_pci_link *link)
{
int result = 0;
- acpi_status status = AE_OK;
+ acpi_status status;
int irq = 0;
- if (!link)
- return -EINVAL;
-
link->irq.active = 0;
/* in practice, status disabled is meaningless, ignore it */
@@ -308,16 +297,15 @@ static int acpi_pci_link_get_current(struct acpi_pci_link *link)
static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
{
- int result = 0;
- acpi_status status = AE_OK;
+ int result;
+ acpi_status status;
struct {
struct acpi_resource res;
struct acpi_resource end;
} *resource;
struct acpi_buffer buffer = { 0, NULL };
-
- if (!link || !irq)
+ if (!irq)
return -EINVAL;
resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
@@ -479,30 +467,22 @@ static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ9 PCI, often acpi */
PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ10 PCI */
PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ11 PCI */
- PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */
- PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */
- PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */
- PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */
+ PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */
+ PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */
+ PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */
+ PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */
/* >IRQ15 */
};
int __init acpi_irq_penalty_init(void)
{
- struct list_head *node = NULL;
- struct acpi_pci_link *link = NULL;
- int i = 0;
-
+ struct acpi_pci_link *link;
+ int i;
/*
* Update penalties to facilitate IRQ balancing.
*/
- list_for_each(node, &acpi_link.entries) {
-
- link = list_entry(node, struct acpi_pci_link, node);
- if (!link) {
- printk(KERN_ERR PREFIX "Invalid link context\n");
- continue;
- }
+ list_for_each_entry(link, &acpi_link_list, list) {
/*
* reflect the possible and active irqs in the penalty table --
@@ -527,7 +507,6 @@ int __init acpi_irq_penalty_init(void)
}
/* Add a penalty for the SCI */
acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING;
-
return 0;
}
@@ -538,7 +517,6 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
int irq;
int i;
-
if (link->irq.initialized) {
if (link->refcnt == 0)
/* This means the link is disabled but initialized */
@@ -566,11 +544,10 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
/*
* if active found, use it; else pick entry from end of possible list.
*/
- if (link->irq.active) {
+ if (link->irq.active)
irq = link->irq.active;
- } else {
+ else
irq = link->irq.possible[link->irq.possible_count - 1];
- }
if (acpi_irq_balance || !link->irq.active) {
/*
@@ -599,7 +576,6 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
}
link->irq.initialized = 1;
-
return 0;
}
@@ -608,16 +584,12 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
* success: return IRQ >= 0
* failure: return -1
*/
-
-int
-acpi_pci_link_allocate_irq(acpi_handle handle,
- int index,
- int *triggering, int *polarity, char **name)
+int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
+ int *polarity, char **name)
{
- int result = 0;
- struct acpi_device *device = NULL;
- struct acpi_pci_link *link = NULL;
-
+ int result;
+ struct acpi_device *device;
+ struct acpi_pci_link *link;
result = acpi_bus_get_device(handle, &device);
if (result) {
@@ -669,11 +641,10 @@ acpi_pci_link_allocate_irq(acpi_handle handle,
*/
int acpi_pci_link_free_irq(acpi_handle handle)
{
- struct acpi_device *device = NULL;
- struct acpi_pci_link *link = NULL;
+ struct acpi_device *device;
+ struct acpi_pci_link *link;
acpi_status result;
-
result = acpi_bus_get_device(handle, &device);
if (result) {
printk(KERN_ERR PREFIX "Invalid link device\n");
@@ -708,9 +679,9 @@ int acpi_pci_link_free_irq(acpi_handle handle)
"Link %s is dereferenced\n",
acpi_device_bid(link->device)));
- if (link->refcnt == 0) {
+ if (link->refcnt == 0)
acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);
- }
+
mutex_unlock(&acpi_link_lock);
return (link->irq.active);
}
@@ -721,15 +692,11 @@ int acpi_pci_link_free_irq(acpi_handle handle)
static int acpi_pci_link_add(struct acpi_device *device)
{
- int result = 0;
- struct acpi_pci_link *link = NULL;
- int i = 0;
+ int result;
+ struct acpi_pci_link *link;
+ int i;
int found = 0;
-
- if (!device)
- return -EINVAL;
-
link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
if (!link)
return -ENOMEM;
@@ -767,9 +734,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
printk("\n");
- /* TBD: Acquire/release lock */
- list_add_tail(&link->node, &acpi_link.entries);
- acpi_link.count++;
+ list_add_tail(&link->list, &acpi_link_list);
end:
/* disable all links -- to be activated on use */
@@ -784,24 +749,17 @@ static int acpi_pci_link_add(struct acpi_device *device)
static int acpi_pci_link_resume(struct acpi_pci_link *link)
{
-
if (link->refcnt && link->irq.active && link->irq.initialized)
return (acpi_pci_link_set(link, link->irq.active));
- else
- return 0;
+
+ return 0;
}
static int irqrouter_resume(struct sys_device *dev)
{
- struct list_head *node = NULL;
- struct acpi_pci_link *link = NULL;
+ struct acpi_pci_link *link;
- list_for_each(node, &acpi_link.entries) {
- link = list_entry(node, struct acpi_pci_link, node);
- if (!link) {
- printk(KERN_ERR PREFIX "Invalid link context\n");
- continue;
- }
+ list_for_each_entry(link, &acpi_link_list, list) {
acpi_pci_link_resume(link);
}
return 0;
@@ -809,20 +767,15 @@ static int irqrouter_resume(struct sys_device *dev)
static int acpi_pci_link_remove(struct acpi_device *device, int type)
{
- struct acpi_pci_link *link = NULL;
-
-
- if (!device || !acpi_driver_data(device))
- return -EINVAL;
+ struct acpi_pci_link *link;
link = acpi_driver_data(device);
mutex_lock(&acpi_link_lock);
- list_del(&link->node);
+ list_del(&link->list);
mutex_unlock(&acpi_link_lock);
kfree(link);
-
return 0;
}
@@ -931,7 +884,6 @@ static int __init irqrouter_init_sysfs(void)
{
int error;
-
if (acpi_disabled || acpi_noirq)
return 0;
@@ -957,9 +909,6 @@ static int __init acpi_pci_link_init(void)
acpi_irq_balance = 0;
}
- acpi_link.count = 0;
- INIT_LIST_HEAD(&acpi_link.entries);
-
if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0)
return -ENODEV;
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c
index cd1f4467be7..12158e0d009 100644
--- a/drivers/acpi/pci_slot.c
+++ b/drivers/acpi/pci_slot.c
@@ -164,6 +164,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
list_add(&slot->list, &slot_list);
mutex_unlock(&slot_list_lock);
+ get_device(&pci_bus->dev);
+
dbg("pci_slot: %p, pci_bus: %x, device: %d, name: %s\n",
pci_slot, pci_bus->number, device, name);
@@ -310,12 +312,15 @@ static void
acpi_pci_slot_remove(acpi_handle handle)
{
struct acpi_pci_slot *slot, *tmp;
+ struct pci_bus *pbus;
mutex_lock(&slot_list_lock);
list_for_each_entry_safe(slot, tmp, &slot_list, list) {
if (slot->root_handle == handle) {
list_del(&slot->list);
+ pbus = slot->pci_slot->bus;
pci_destroy_slot(slot->pci_slot);
+ put_device(&pbus->dev);
kfree(slot);
}
}
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index c926e7d4a0d..56665a63bf1 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -54,10 +54,6 @@ ACPI_MODULE_NAME("power");
#define ACPI_POWER_RESOURCE_STATE_ON 0x01
#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
int acpi_power_nocheck;
module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
@@ -773,14 +769,10 @@ static int acpi_power_resume(struct acpi_device *device)
return 0;
}
-static int __init acpi_power_init(void)
+int __init acpi_power_init(void)
{
int result = 0;
-
- if (acpi_disabled)
- return 0;
-
INIT_LIST_HEAD(&acpi_power_resource_list);
acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir);
@@ -795,5 +787,3 @@ static int __init acpi_power_init(void)
return 0;
}
-
-subsys_initcall(acpi_power_init);
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index 428c911dba0..d0d550d22a6 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -343,9 +343,6 @@ acpi_system_write_alarm(struct file *file,
}
#endif /* HAVE_ACPI_LEGACY_ALARM */
-extern struct list_head acpi_wakeup_device_list;
-extern spinlock_t acpi_device_lock;
-
static int
acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
{
@@ -353,7 +350,7 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
seq_printf(seq, "Device\tS-state\t Status Sysfs node\n");
- spin_lock(&acpi_device_lock);
+ mutex_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev =
container_of(node, struct acpi_device, wakeup_list);
@@ -361,7 +358,6 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
if (!dev->wakeup.flags.valid)
continue;
- spin_unlock(&acpi_device_lock);
ldev = acpi_get_physical_device(dev->handle);
seq_printf(seq, "%s\t S%d\t%c%-8s ",
@@ -376,9 +372,8 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
seq_printf(seq, "\n");
put_device(ldev);
- spin_lock(&acpi_device_lock);
}
- spin_unlock(&acpi_device_lock);
+ mutex_unlock(&acpi_device_lock);
return 0;
}
@@ -409,7 +404,7 @@ acpi_system_write_wakeup_device(struct file *file,
strbuf[len] = '\0';
sscanf(strbuf, "%s", str);
- spin_lock(&acpi_device_lock);
+ mutex_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev =
container_of(node, struct acpi_device, wakeup_list);
@@ -446,7 +441,7 @@ acpi_system_write_wakeup_device(struct file *file,
}
}
}
- spin_unlock(&acpi_device_lock);
+ mutex_unlock(&acpi_device_lock);
return count;
}
@@ -496,11 +491,8 @@ static u32 rtc_handler(void *context)
}
#endif /* HAVE_ACPI_LEGACY_ALARM */
-static int __init acpi_sleep_proc_init(void)
+int __init acpi_sleep_proc_init(void)
{
- if (acpi_disabled)
- return 0;
-
#ifdef CONFIG_ACPI_PROCFS
/* 'sleep' [R/W] */
proc_create("sleep", S_IFREG | S_IRUGO | S_IWUSR,
@@ -527,5 +519,3 @@ static int __init acpi_sleep_proc_init(void)
return 0;
}
-
-late_initcall(acpi_sleep_proc_init);
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index fa2f7422d23..45ad3288c5f 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -82,7 +82,7 @@ static int acpi_processor_add(struct acpi_device *device);
static int acpi_processor_start(struct acpi_device *device);
static int acpi_processor_remove(struct acpi_device *device, int type);
static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
-static void acpi_processor_notify(acpi_handle handle, u32 event, void *data);
+static void acpi_processor_notify(struct acpi_device *device, u32 event);
static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
static int acpi_processor_handle_eject(struct acpi_processor *pr);
@@ -104,6 +104,7 @@ static struct acpi_driver acpi_processor_driver = {
.start = acpi_processor_start,
.suspend = acpi_processor_suspend,
.resume = acpi_processor_resume,
+ .notify = acpi_processor_notify,
},
};
@@ -426,6 +427,29 @@ static int map_lapic_id(struct acpi_subtable_header *entry,
return 0;
}
+static int map_x2apic_id(struct acpi_subtable_header *entry,
+ int device_declaration, u32 acpi_id, int *apic_id)
+{
+ struct acpi_madt_local_x2apic *apic =
+ (struct acpi_madt_local_x2apic *)entry;
+ u32 tmp = apic->local_apic_id;
+
+ /* Only check enabled APICs*/
+ if (!(apic->lapic_flags & ACPI_MADT_ENABLED))
+ return 0;
+
+ /* Device statement declaration type */
+ if (device_declaration) {
+ if (apic->uid == acpi_id)
+ goto found;
+ }
+
+ return 0;
+found:
+ *apic_id = tmp;
+ return 1;
+}
+
static int map_lsapic_id(struct acpi_subtable_header *entry,
int device_declaration, u32 acpi_id, int *apic_id)
{
@@ -475,6 +499,9 @@ static int map_madt_entry(int type, u32 acpi_id)
if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
if (map_lapic_id(header, acpi_id, &apic_id))
break;
+ } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
+ if (map_x2apic_id(header, type, acpi_id, &apic_id))
+ break;
} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
if (map_lsapic_id(header, type, acpi_id, &apic_id))
break;
@@ -665,7 +692,6 @@ static DEFINE_PER_CPU(void *, processor_device_array);
static int __cpuinit acpi_processor_start(struct acpi_device *device)
{
int result = 0;
- acpi_status status = AE_OK;
struct acpi_processor *pr;
struct sys_device *sysdev;
@@ -702,9 +728,6 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev"))
return -EFAULT;
- status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
- acpi_processor_notify, pr);
-
/* _PDC call should be done before doing anything else (if reqd.). */
arch_acpi_processor_init_pdc(pr);
acpi_processor_set_pdc(pr);
@@ -750,18 +773,14 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
return result;
}
-static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_processor_notify(struct acpi_device *device, u32 event)
{
- struct acpi_processor *pr = data;
- struct acpi_device *device = NULL;
+ struct acpi_processor *pr = acpi_driver_data(device);
int saved;
if (!pr)
return;
- if (acpi_bus_get_device(pr->handle, &device))
- return;
-
switch (event) {
case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
saved = pr->performance_platform_limit;
@@ -840,7 +859,6 @@ static int acpi_processor_add(struct acpi_device *device)
static int acpi_processor_remove(struct acpi_device *device, int type)
{
- acpi_status status = AE_OK;
struct acpi_processor *pr = NULL;
@@ -859,9 +877,6 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
acpi_processor_power_exit(pr, device);
- status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
- acpi_processor_notify);
-
sysfs_remove_link(&device->dev.kobj, "sysdev");
acpi_processor_remove_fs(device);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 7bc22a471fe..6fe121434ff 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -64,7 +64,6 @@
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_idle");
#define ACPI_PROCESSOR_FILE_POWER "power"
-#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
#define C2_OVERHEAD 1 /* 1us */
#define C3_OVERHEAD 1 /* 1us */
@@ -78,6 +77,10 @@ module_param(nocst, uint, 0000);
static unsigned int latency_factor __read_mostly = 2;
module_param(latency_factor, uint, 0644);
+static s64 us_to_pm_timer_ticks(s64 t)
+{
+ return div64_u64(t * PM_TIMER_FREQUENCY, 1000000);
+}
/*
* IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
* For now disable this. Probably a bug somewhere else.
@@ -101,57 +104,6 @@ static int set_max_cstate(const struct dmi_system_id *id)
/* Actually this shouldn't be __cpuinitdata, would be better to fix the
callers to only run once -AK */
static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET70WW")}, (void *)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1},
- { set_max_cstate, "Medion 41700", {
- DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
- DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1},
{ set_max_cstate, "Clevo 5600D", {
DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
@@ -159,25 +111,6 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
{},
};
-static inline u32 ticks_elapsed(u32 t1, u32 t2)
-{
- if (t2 >= t1)
- return (t2 - t1);
- else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
- return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
- else
- return ((0xFFFFFFFF - t1) + t2);
-}
-
-static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
-{
- if (t2 >= t1)
- return PM_TIMER_TICKS_TO_US(t2 - t1);
- else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
- return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
- else
- return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
-}
/*
* Callers should disable interrupts before the call and enable
@@ -212,6 +145,9 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr,
struct acpi_processor_power *pwr = &pr->power;
u8 type = local_apic_timer_c2_ok ? ACPI_STATE_C3 : ACPI_STATE_C2;
+ if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
+ return;
+
/*
* Check, if one of the previous states already marked the lapic
* unstable
@@ -630,7 +566,7 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
* In either case, the proper way to
* handle BM_RLD is to set it and leave it set.
*/
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
+ acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
return;
}
@@ -800,9 +736,9 @@ static int acpi_idle_bm_check(void)
{
u32 bm_status = 0;
- acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
+ acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
if (bm_status)
- acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
+ acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
/*
* PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
* the true state of bus mastering activity; forcing us to
@@ -853,7 +789,8 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
static int acpi_idle_enter_c1(struct cpuidle_device *dev,
struct cpuidle_state *state)
{
- u32 t1, t2;
+ ktime_t kt1, kt2;
+ s64 idle_time;
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
@@ -871,14 +808,15 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
return 0;
}
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt1 = ktime_get_real();
acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt2 = ktime_get_real();
+ idle_time = ktime_to_us(ktime_sub(kt2, kt1));
local_irq_enable();
cx->usage++;
- return ticks_elapsed_in_us(t1, t2);
+ return idle_time;
}
/**
@@ -891,8 +829,9 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
{
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
- u32 t1, t2;
- int sleep_ticks = 0;
+ ktime_t kt1, kt2;
+ s64 idle_time;
+ s64 sleep_ticks = 0;
pr = __get_cpu_var(processors);
@@ -925,18 +864,19 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
if (cx->type == ACPI_STATE_C3)
ACPI_FLUSH_CPU_CACHE();
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt1 = ktime_get_real();
/* Tell the scheduler that we are going deep-idle: */
sched_clock_idle_sleep_event();
acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt2 = ktime_get_real();
+ idle_time = ktime_to_us(ktime_sub(kt2, kt1));
#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
/* TSC could halt in idle, so notify users */
if (tsc_halts_in_c(cx->type))
mark_tsc_unstable("TSC halts in idle");;
#endif
- sleep_ticks = ticks_elapsed(t1, t2);
+ sleep_ticks = us_to_pm_timer_ticks(idle_time);
/* Tell the scheduler how much we idled: */
sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
@@ -948,7 +888,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
acpi_state_timer_broadcast(pr, cx, 0);
cx->time += sleep_ticks;
- return ticks_elapsed_in_us(t1, t2);
+ return idle_time;
}
static int c3_cpu_count;
@@ -966,8 +906,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
{
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
- u32 t1, t2;
- int sleep_ticks = 0;
+ ktime_t kt1, kt2;
+ s64 idle_time;
+ s64 sleep_ticks = 0;
+
pr = __get_cpu_var(processors);
@@ -1028,20 +970,21 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
c3_cpu_count++;
/* Disable bus master arbitration when all CPUs are in C3 */
if (c3_cpu_count == num_online_cpus())
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+ acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
spin_unlock(&c3_lock);
} else if (!pr->flags.bm_check) {
ACPI_FLUSH_CPU_CACHE();
}
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt1 = ktime_get_real();
acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt2 = ktime_get_real();
+ idle_time = ktime_to_us(ktime_sub(kt2, kt1));
/* Re-enable bus master arbitration */
if (pr->flags.bm_check && pr->flags.bm_control) {
spin_lock(&c3_lock);
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+ acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
c3_cpu_count--;
spin_unlock(&c3_lock);
}
@@ -1051,7 +994,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
if (tsc_halts_in_c(ACPI_STATE_C3))
mark_tsc_unstable("TSC halts in idle");
#endif
- sleep_ticks = ticks_elapsed(t1, t2);
+ sleep_ticks = us_to_pm_timer_ticks(idle_time);
/* Tell the scheduler how much we idled: */
sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
@@ -1062,7 +1005,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
acpi_state_timer_broadcast(pr, cx, 0);
cx->time += sleep_ticks;
- return ticks_elapsed_in_us(t1, t2);
+ return idle_time;
}
struct cpuidle_driver acpi_idle_driver = {
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 68fd3d29279..cafb41000f6 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -479,6 +479,13 @@ static int acpi_processor_get_psd(struct acpi_processor *pr)
goto end;
}
+ if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
+ pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
+ pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
+ printk(KERN_ERR PREFIX "Invalid _PSD:coord_type\n");
+ result = -EFAULT;
+ goto end;
+ }
end:
kfree(buffer.pointer);
return result;
@@ -501,9 +508,10 @@ int acpi_processor_preregister_performance(
mutex_lock(&performance_mutex);
- retval = 0;
-
- /* Call _PSD for all CPUs */
+ /*
+ * Check if another driver has already registered, and abort before
+ * changing pr->performance if it has. Check input data as well.
+ */
for_each_possible_cpu(i) {
pr = per_cpu(processors, i);
if (!pr) {
@@ -513,13 +521,20 @@ int acpi_processor_preregister_performance(
if (pr->performance) {
retval = -EBUSY;
- continue;
+ goto err_out;
}
if (!performance || !per_cpu_ptr(performance, i)) {
retval = -EINVAL;
- continue;
+ goto err_out;
}
+ }
+
+ /* Call _PSD for all CPUs */
+ for_each_possible_cpu(i) {
+ pr = per_cpu(processors, i);
+ if (!pr)
+ continue;
pr->performance = per_cpu_ptr(performance, i);
cpumask_set_cpu(i, pr->performance->shared_cpu_map);
@@ -535,26 +550,6 @@ int acpi_processor_preregister_performance(
* Now that we have _PSD data from all CPUs, lets setup P-state
* domain info.
*/
- for_each_possible_cpu(i) {
- pr = per_cpu(processors, i);
- if (!pr)
- continue;
-
- /* Basic validity check for domain info */
- pdomain = &(pr->performance->domain_info);
- if ((pdomain->revision != ACPI_PSD_REV0_REVISION) ||
- (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES)) {
- retval = -EINVAL;
- goto err_ret;
- }
- if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
- pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
- pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
- retval = -EINVAL;
- goto err_ret;
- }
- }
-
cpumask_clear(covered_cpus);
for_each_possible_cpu(i) {
pr = per_cpu(processors, i);
@@ -643,6 +638,7 @@ err_ret:
pr->performance = NULL; /* Will be set for real in register */
}
+err_out:
mutex_unlock(&performance_mutex);
free_cpumask_var(covered_cpus);
return retval;
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index b1eb376fae4..39838c66603 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -373,7 +373,8 @@ static int acpi_processor_max_state(struct acpi_processor *pr)
return max_state;
}
static int
-processor_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+processor_get_max_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr = acpi_driver_data(device);
@@ -381,28 +382,29 @@ processor_get_max_state(struct thermal_cooling_device *cdev, char *buf)
if (!device || !pr)
return -EINVAL;
- return sprintf(buf, "%d\n", acpi_processor_max_state(pr));
+ *state = acpi_processor_max_state(pr);
+ return 0;
}
static int
-processor_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+processor_get_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long *cur_state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr = acpi_driver_data(device);
- int cur_state;
if (!device || !pr)
return -EINVAL;
- cur_state = cpufreq_get_cur_state(pr->id);
+ *cur_state = cpufreq_get_cur_state(pr->id);
if (pr->flags.throttling)
- cur_state += pr->throttling.state;
-
- return sprintf(buf, "%d\n", cur_state);
+ *cur_state += pr->throttling.state;
+ return 0;
}
static int
-processor_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+processor_set_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr = acpi_driver_data(device);
@@ -507,7 +509,7 @@ static ssize_t acpi_processor_write_limit(struct file * file,
return count;
}
-struct file_operations acpi_processor_limit_fops = {
+const struct file_operations acpi_processor_limit_fops = {
.owner = THIS_MODULE,
.open = acpi_processor_limit_open_fs,
.read = seq_read,
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index d27838171f4..d0d1f4d5043 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -783,11 +783,9 @@ static int acpi_get_throttling_state(struct acpi_processor *pr,
(struct acpi_processor_tx_tss *)&(pr->throttling.
states_tss[i]);
if (tx->control == value)
- break;
+ return i;
}
- if (i > pr->throttling.state_count)
- i = -1;
- return i;
+ return -1;
}
static int acpi_get_throttling_value(struct acpi_processor *pr,
@@ -1291,7 +1289,7 @@ static ssize_t acpi_processor_write_throttling(struct file *file,
return count;
}
-struct file_operations acpi_processor_throttling_fops = {
+const struct file_operations acpi_processor_throttling_fops = {
.owner = THIS_MODULE,
.open = acpi_processor_throttling_open_fs,
.read = seq_read,
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 59afd52ccc1..4b214b74eba 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -102,8 +102,8 @@ struct acpi_battery {
u16 cycle_count;
u16 temp_now;
u16 voltage_now;
- s16 current_now;
- s16 current_avg;
+ s16 rate_now;
+ s16 rate_avg;
u16 capacity_now;
u16 state_of_charge;
u16 state;
@@ -202,9 +202,9 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
return -ENODEV;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
- if (battery->current_now < 0)
+ if (battery->rate_now < 0)
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
- else if (battery->current_now > 0)
+ else if (battery->rate_now > 0)
val->intval = POWER_SUPPLY_STATUS_CHARGING;
else
val->intval = POWER_SUPPLY_STATUS_FULL;
@@ -224,11 +224,13 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
acpi_battery_vscale(battery) * 1000;
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
- val->intval = abs(battery->current_now) *
+ case POWER_SUPPLY_PROP_POWER_NOW:
+ val->intval = abs(battery->rate_now) *
acpi_battery_ipscale(battery) * 1000;
break;
case POWER_SUPPLY_PROP_CURRENT_AVG:
- val->intval = abs(battery->current_avg) *
+ case POWER_SUPPLY_PROP_POWER_AVG:
+ val->intval = abs(battery->rate_avg) *
acpi_battery_ipscale(battery) * 1000;
break;
case POWER_SUPPLY_PROP_CAPACITY:
@@ -293,6 +295,8 @@ static enum power_supply_property sbs_energy_battery_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CURRENT_AVG,
+ POWER_SUPPLY_PROP_POWER_NOW,
+ POWER_SUPPLY_PROP_POWER_AVG,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_FULL,
@@ -301,6 +305,7 @@ static enum power_supply_property sbs_energy_battery_props[] = {
POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_MANUFACTURER,
};
+
#endif
/* --------------------------------------------------------------------------
@@ -330,8 +335,8 @@ static struct acpi_battery_reader info_readers[] = {
static struct acpi_battery_reader state_readers[] = {
{0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
{0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
- {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
- {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
+ {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_now)},
+ {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_avg)},
{0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
{0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
{0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
@@ -479,9 +484,9 @@ static int
acpi_sbs_add_fs(struct proc_dir_entry **dir,
struct proc_dir_entry *parent_dir,
char *dir_name,
- struct file_operations *info_fops,
- struct file_operations *state_fops,
- struct file_operations *alarm_fops, void *data)
+ const struct file_operations *info_fops,
+ const struct file_operations *state_fops,
+ const struct file_operations *alarm_fops, void *data)
{
if (!*dir) {
*dir = proc_mkdir(dir_name, parent_dir);
@@ -588,9 +593,9 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
seq_printf(seq, "capacity state: %s\n",
(battery->state & 0x0010) ? "critical" : "ok");
seq_printf(seq, "charging state: %s\n",
- (battery->current_now < 0) ? "discharging" :
- ((battery->current_now > 0) ? "charging" : "charged"));
- rate = abs(battery->current_now) * acpi_battery_ipscale(battery);
+ (battery->rate_now < 0) ? "discharging" :
+ ((battery->rate_now > 0) ? "charging" : "charged"));
+ rate = abs(battery->rate_now) * acpi_battery_ipscale(battery);
rate *= (acpi_battery_mode(battery))?(battery->voltage_now *
acpi_battery_vscale(battery)/1000):1;
seq_printf(seq, "present rate: %d%s\n", rate,
@@ -676,7 +681,7 @@ static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
}
-static struct file_operations acpi_battery_info_fops = {
+static const struct file_operations acpi_battery_info_fops = {
.open = acpi_battery_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -684,7 +689,7 @@ static struct file_operations acpi_battery_info_fops = {
.owner = THIS_MODULE,
};
-static struct file_operations acpi_battery_state_fops = {
+static const struct file_operations acpi_battery_state_fops = {
.open = acpi_battery_state_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -692,7 +697,7 @@ static struct file_operations acpi_battery_state_fops = {
.owner = THIS_MODULE,
};
-static struct file_operations acpi_battery_alarm_fops = {
+static const struct file_operations acpi_battery_alarm_fops = {
.open = acpi_battery_alarm_open_fs,
.read = seq_read,
.write = acpi_battery_write_alarm,
@@ -724,7 +729,7 @@ static int acpi_ac_state_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_ac_read_state, PDE(inode)->data);
}
-static struct file_operations acpi_ac_state_fops = {
+static const struct file_operations acpi_ac_state_fops = {
.open = acpi_ac_state_open_fs,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index c54d7b6c406..8ff510b91d8 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -11,6 +11,8 @@
#include <acpi/acpi_drivers.h>
+#include "internal.h"
+
#define _COMPONENT ACPI_BUS_COMPONENT
ACPI_MODULE_NAME("scan");
#define STRUCT_TO_INT(s) (*((int*)&s))
@@ -22,7 +24,7 @@ extern struct acpi_device *acpi_root;
static LIST_HEAD(acpi_device_list);
static LIST_HEAD(acpi_bus_id_list);
-DEFINE_SPINLOCK(acpi_device_lock);
+DEFINE_MUTEX(acpi_device_lock);
LIST_HEAD(acpi_wakeup_device_list);
struct acpi_device_bus_id{
@@ -357,6 +359,61 @@ static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0;
}
+static void acpi_device_notify(acpi_handle handle, u32 event, void *data)
+{
+ struct acpi_device *device = data;
+
+ device->driver->ops.notify(device, event);
+}
+
+static acpi_status acpi_device_notify_fixed(void *data)
+{
+ struct acpi_device *device = data;
+
+ acpi_device_notify(device->handle, ACPI_FIXED_HARDWARE_EVENT, device);
+ return AE_OK;
+}
+
+static int acpi_device_install_notify_handler(struct acpi_device *device)
+{
+ acpi_status status;
+ char *hid;
+
+ hid = acpi_device_hid(device);
+ if (!strcmp(hid, ACPI_BUTTON_HID_POWERF))
+ status =
+ acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+ acpi_device_notify_fixed,
+ device);
+ else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEPF))
+ status =
+ acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+ acpi_device_notify_fixed,
+ device);
+ else
+ status = acpi_install_notify_handler(device->handle,
+ ACPI_DEVICE_NOTIFY,
+ acpi_device_notify,
+ device);
+
+ if (ACPI_FAILURE(status))
+ return -EINVAL;
+ return 0;
+}
+
+static void acpi_device_remove_notify_handler(struct acpi_device *device)
+{
+ if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF))
+ acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+ acpi_device_notify_fixed);
+ else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF))
+ acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+ acpi_device_notify_fixed);
+ else
+ acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+ acpi_device_notify);
+}
+
static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
static int acpi_start_single_object(struct acpi_device *);
static int acpi_device_probe(struct device * dev)
@@ -369,6 +426,20 @@ static int acpi_device_probe(struct device * dev)
if (!ret) {
if (acpi_dev->bus_ops.acpi_op_start)
acpi_start_single_object(acpi_dev);
+
+ if (acpi_drv->ops.notify) {
+ ret = acpi_device_install_notify_handler(acpi_dev);
+ if (ret) {
+ if (acpi_drv->ops.stop)
+ acpi_drv->ops.stop(acpi_dev,
+ acpi_dev->removal_type);
+ if (acpi_drv->ops.remove)
+ acpi_drv->ops.remove(acpi_dev,
+ acpi_dev->removal_type);
+ return ret;
+ }
+ }
+
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Found driver [%s] for device [%s]\n",
acpi_drv->name, acpi_dev->pnp.bus_id));
@@ -383,6 +454,8 @@ static int acpi_device_remove(struct device * dev)
struct acpi_driver *acpi_drv = acpi_dev->driver;
if (acpi_drv) {
+ if (acpi_drv->ops.notify)
+ acpi_device_remove_notify_handler(acpi_dev);
if (acpi_drv->ops.stop)
acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type);
if (acpi_drv->ops.remove)
@@ -395,22 +468,10 @@ static int acpi_device_remove(struct device * dev)
return 0;
}
-static void acpi_device_shutdown(struct device *dev)
-{
- struct acpi_device *acpi_dev = to_acpi_device(dev);
- struct acpi_driver *acpi_drv = acpi_dev->driver;
-
- if (acpi_drv && acpi_drv->ops.shutdown)
- acpi_drv->ops.shutdown(acpi_dev);
-
- return ;
-}
-
struct bus_type acpi_bus_type = {
.name = "acpi",
.suspend = acpi_device_suspend,
.resume = acpi_device_resume,
- .shutdown = acpi_device_shutdown,
.match = acpi_bus_match,
.probe = acpi_device_probe,
.remove = acpi_device_remove,
@@ -430,7 +491,6 @@ static int acpi_device_register(struct acpi_device *device,
*/
INIT_LIST_HEAD(&device->children);
INIT_LIST_HEAD(&device->node);
- INIT_LIST_HEAD(&device->g_list);
INIT_LIST_HEAD(&device->wakeup_list);
new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
@@ -439,7 +499,7 @@ static int acpi_device_register(struct acpi_device *device,
return -ENOMEM;
}
- spin_lock(&acpi_device_lock);
+ mutex_lock(&acpi_device_lock);
/*
* Find suitable bus_id and instance number in acpi_bus_id_list
* If failed, create one and link it into acpi_bus_id_list
@@ -460,14 +520,12 @@ static int acpi_device_register(struct acpi_device *device,
}
dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
- if (device->parent) {
+ if (device->parent)
list_add_tail(&device->node, &device->parent->children);
- list_add_tail(&device->g_list, &device->parent->g_list);
- } else
- list_add_tail(&device->g_list, &acpi_device_list);
+
if (device->wakeup.flags.valid)
list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
- spin_unlock(&acpi_device_lock);
+ mutex_unlock(&acpi_device_lock);
if (device->parent)
device->dev.parent = &parent->dev;
@@ -488,28 +546,22 @@ static int acpi_device_register(struct acpi_device *device,
device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
return 0;
end:
- spin_lock(&acpi_device_lock);
- if (device->parent) {
+ mutex_lock(&acpi_device_lock);
+ if (device->parent)
list_del(&device->node);
- list_del(&device->g_list);
- } else
- list_del(&device->g_list);
list_del(&device->wakeup_list);
- spin_unlock(&acpi_device_lock);
+ mutex_unlock(&acpi_device_lock);
return result;
}
static void acpi_device_unregister(struct acpi_device *device, int type)
{
- spin_lock(&acpi_device_lock);
- if (device->parent) {
+ mutex_lock(&acpi_device_lock);
+ if (device->parent)
list_del(&device->node);
- list_del(&device->g_list);
- } else
- list_del(&device->g_list);
list_del(&device->wakeup_list);
- spin_unlock(&acpi_device_lock);
+ mutex_unlock(&acpi_device_lock);
acpi_detach_data(device->handle, acpi_bus_data_handler);
@@ -1524,16 +1576,11 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
return result;
}
-
-static int __init acpi_scan_init(void)
+int __init acpi_scan_init(void)
{
int result;
struct acpi_bus_ops ops;
-
- if (acpi_disabled)
- return 0;
-
memset(&ops, 0, sizeof(ops));
ops.acpi_op_add = 1;
ops.acpi_op_start = 1;
@@ -1566,5 +1613,3 @@ static int __init acpi_scan_init(void)
Done:
return result;
}
-
-subsys_initcall(acpi_scan_init);
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 00456fccfa3..779e4e500df 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -21,6 +21,8 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
+
+#include "internal.h"
#include "sleep.h"
u8 sleep_states[ACPI_S_STATE_COUNT];
@@ -248,7 +250,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
/* If ACPI is not enabled by the BIOS, we need to enable it here. */
if (set_sci_en_on_resume)
- acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1);
+ acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
else
acpi_enable();
@@ -394,6 +396,15 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"),
},
},
+ {
+ .callback = init_old_suspend_ordering,
+ .ident = "Panasonic CF51-2L",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR,
+ "Matsushita Electric Industrial Co.,Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
+ },
+ },
{},
};
#endif /* CONFIG_SUSPEND */
diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h
index cfaf8f5b0a1..8a8f3b3382a 100644
--- a/drivers/acpi/sleep.h
+++ b/drivers/acpi/sleep.h
@@ -5,3 +5,6 @@ extern int acpi_suspend (u32 state);
extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
extern void acpi_enable_wakeup_device(u8 sleep_state);
extern void acpi_disable_wakeup_device(u8 sleep_state);
+
+extern struct list_head acpi_wakeup_device_list;
+extern struct mutex acpi_device_lock;
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 391d0358a59..da51f05ef8d 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -33,10 +33,6 @@
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("system");
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
#define ACPI_SYSTEM_CLASS "system"
#define ACPI_SYSTEM_DEVICE_NAME "System"
@@ -62,6 +58,7 @@ module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
-------------------------------------------------------------------------- */
static LIST_HEAD(acpi_table_attr_list);
static struct kobject *tables_kobj;
+static struct kobject *dynamic_tables_kobj;
struct acpi_table_attr {
struct bin_attribute attr;
@@ -128,6 +125,40 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
return;
}
+static acpi_status
+acpi_sysfs_table_handler(u32 event, void *table, void *context)
+{
+ struct acpi_table_attr *table_attr;
+
+ switch (event) {
+ case ACPI_TABLE_EVENT_LOAD:
+ table_attr =
+ kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
+ if (!table_attr)
+ return AE_NO_MEMORY;
+
+ acpi_table_attr_init(table_attr, table);
+ if (sysfs_create_bin_file(dynamic_tables_kobj,
+ &table_attr->attr)) {
+ kfree(table_attr);
+ return AE_ERROR;
+ } else
+ list_add_tail(&table_attr->node,
+ &acpi_table_attr_list);
+ break;
+ case ACPI_TABLE_EVENT_UNLOAD:
+ /*
+ * we do not need to do anything right now
+ * because the table is not deleted from the
+ * global table list when unloading it.
+ */
+ break;
+ default:
+ return AE_BAD_PARAMETER;
+ }
+ return AE_OK;
+}
+
static int acpi_system_sysfs_init(void)
{
struct acpi_table_attr *table_attr;
@@ -137,7 +168,11 @@ static int acpi_system_sysfs_init(void)
tables_kobj = kobject_create_and_add("tables", acpi_kobj);
if (!tables_kobj)
- return -ENOMEM;
+ goto err;
+
+ dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj);
+ if (!dynamic_tables_kobj)
+ goto err_dynamic_tables;
do {
result = acpi_get_table_by_index(table_index, &table_header);
@@ -162,8 +197,14 @@ static int acpi_system_sysfs_init(void)
}
} while (!result);
kobject_uevent(tables_kobj, KOBJ_ADD);
-
- return 0;
+ kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
+ result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
+
+ return result == AE_OK ? 0 : -EINVAL;
+err_dynamic_tables:
+ kobject_put(tables_kobj);
+err:
+ return -ENOMEM;
}
/*
@@ -571,12 +612,9 @@ static int acpi_system_procfs_init(void)
}
#endif
-static int __init acpi_system_init(void)
+int __init acpi_system_init(void)
{
- int result = 0;
-
- if (acpi_disabled)
- return 0;
+ int result;
result = acpi_system_procfs_init();
if (result)
@@ -586,5 +624,3 @@ static int __init acpi_system_init(void)
return result;
}
-
-subsys_initcall(acpi_system_init);
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index fec1ae36d43..646d39c031c 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -62,6 +62,18 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
}
break;
+ case ACPI_MADT_TYPE_LOCAL_X2APIC:
+ {
+ struct acpi_madt_local_x2apic *p =
+ (struct acpi_madt_local_x2apic *)header;
+ printk(KERN_INFO PREFIX
+ "X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n",
+ p->local_apic_id, p->uid,
+ (p->lapic_flags & ACPI_MADT_ENABLED) ?
+ "enabled" : "disabled");
+ }
+ break;
+
case ACPI_MADT_TYPE_IO_APIC:
{
struct acpi_madt_io_apic *p =
@@ -116,6 +128,24 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
}
break;
+ case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
+ {
+ u16 polarity, trigger;
+ struct acpi_madt_local_x2apic_nmi *p =
+ (struct acpi_madt_local_x2apic_nmi *)header;
+
+ polarity = p->inti_flags & ACPI_MADT_POLARITY_MASK;
+ trigger = (p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2;
+
+ printk(KERN_INFO PREFIX
+ "X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n",
+ p->uid,
+ mps_inti_flags_polarity[polarity],
+ mps_inti_flags_trigger[trigger],
+ p->lint);
+ }
+ break;
+
case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
{
struct acpi_madt_local_apic_override *p =
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index c11f9aeca70..9cd15e8c893 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -37,11 +37,11 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
-#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/kmod.h>
#include <linux/seq_file.h>
#include <linux/reboot.h>
+#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/thermal.h>
#include <acpi/acpi_bus.h>
@@ -98,6 +98,7 @@ MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
static int acpi_thermal_add(struct acpi_device *device);
static int acpi_thermal_remove(struct acpi_device *device, int type);
static int acpi_thermal_resume(struct acpi_device *device);
+static void acpi_thermal_notify(struct acpi_device *device, u32 event);
static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
@@ -123,6 +124,7 @@ static struct acpi_driver acpi_thermal_driver = {
.add = acpi_thermal_add,
.remove = acpi_thermal_remove,
.resume = acpi_thermal_resume,
+ .notify = acpi_thermal_notify,
},
};
@@ -190,9 +192,9 @@ struct acpi_thermal {
struct acpi_thermal_state state;
struct acpi_thermal_trips trips;
struct acpi_handle_list devices;
- struct timer_list timer;
struct thermal_zone_device *thermal_zone;
int tz_enabled;
+ int kelvin_offset;
struct mutex lock;
};
@@ -290,6 +292,11 @@ static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */
+ tz->thermal_zone->polling_delay = seconds * 1000;
+
+ if (tz->tz_enabled)
+ thermal_zone_device_update(tz->thermal_zone);
+
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Polling frequency set to %lu seconds\n",
tz->polling_frequency/10));
@@ -367,7 +374,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
/*
* Treat freezing temperatures as invalid as well; some
* BIOSes return really low values and cause reboots at startup.
- * Below zero (Celcius) values clearly aren't right for sure..
+ * Below zero (Celsius) values clearly aren't right for sure..
* ... so lets discard those as invalid.
*/
if (ACPI_FAILURE(status) ||
@@ -569,392 +576,18 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
}
-static int acpi_thermal_critical(struct acpi_thermal *tz)
-{
- if (!tz || !tz->trips.critical.flags.valid)
- return -EINVAL;
-
- if (tz->temperature >= tz->trips.critical.temperature) {
- printk(KERN_WARNING PREFIX "Critical trip point\n");
- tz->trips.critical.flags.enabled = 1;
- } else if (tz->trips.critical.flags.enabled)
- tz->trips.critical.flags.enabled = 0;
-
- acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
- tz->trips.critical.flags.enabled);
- acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
- dev_name(&tz->device->dev),
- ACPI_THERMAL_NOTIFY_CRITICAL,
- tz->trips.critical.flags.enabled);
-
- /* take no action if nocrt is set */
- if(!nocrt) {
- printk(KERN_EMERG
- "Critical temperature reached (%ld C), shutting down.\n",
- KELVIN_TO_CELSIUS(tz->temperature));
- orderly_poweroff(true);
- }
-
- return 0;
-}
-
-static int acpi_thermal_hot(struct acpi_thermal *tz)
-{
- if (!tz || !tz->trips.hot.flags.valid)
- return -EINVAL;
-
- if (tz->temperature >= tz->trips.hot.temperature) {
- printk(KERN_WARNING PREFIX "Hot trip point\n");
- tz->trips.hot.flags.enabled = 1;
- } else if (tz->trips.hot.flags.enabled)
- tz->trips.hot.flags.enabled = 0;
-
- acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
- tz->trips.hot.flags.enabled);
- acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
- dev_name(&tz->device->dev),
- ACPI_THERMAL_NOTIFY_HOT,
- tz->trips.hot.flags.enabled);
-
- /* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */
-
- return 0;
-}
-
-static void acpi_thermal_passive(struct acpi_thermal *tz)
-{
- int result = 1;
- struct acpi_thermal_passive *passive = NULL;
- int trend = 0;
- int i = 0;
-
-
- if (!tz || !tz->trips.passive.flags.valid)
- return;
-
- passive = &(tz->trips.passive);
-
- /*
- * Above Trip?
- * -----------
- * Calculate the thermal trend (using the passive cooling equation)
- * and modify the performance limit for all passive cooling devices
- * accordingly. Note that we assume symmetry.
- */
- if (tz->temperature >= passive->temperature) {
- trend =
- (passive->tc1 * (tz->temperature - tz->last_temperature)) +
- (passive->tc2 * (tz->temperature - passive->temperature));
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n",
- trend, passive->tc1, tz->temperature,
- tz->last_temperature, passive->tc2,
- tz->temperature, passive->temperature));
- passive->flags.enabled = 1;
- /* Heating up? */
- if (trend > 0)
- for (i = 0; i < passive->devices.count; i++)
- acpi_processor_set_thermal_limit(passive->
- devices.
- handles[i],
- ACPI_PROCESSOR_LIMIT_INCREMENT);
- /* Cooling off? */
- else if (trend < 0) {
- for (i = 0; i < passive->devices.count; i++)
- /*
- * assume that we are on highest
- * freq/lowest thrott and can leave
- * passive mode, even in error case
- */
- if (!acpi_processor_set_thermal_limit
- (passive->devices.handles[i],
- ACPI_PROCESSOR_LIMIT_DECREMENT))
- result = 0;
- /*
- * Leave cooling mode, even if the temp might
- * higher than trip point This is because some
- * machines might have long thermal polling
- * frequencies (tsp) defined. We will fall back
- * into passive mode in next cycle (probably quicker)
- */
- if (result) {
- passive->flags.enabled = 0;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Disabling passive cooling, still above threshold,"
- " but we are cooling down\n"));
- }
- }
- return;
- }
-
- /*
- * Below Trip?
- * -----------
- * Implement passive cooling hysteresis to slowly increase performance
- * and avoid thrashing around the passive trip point. Note that we
- * assume symmetry.
- */
- if (!passive->flags.enabled)
- return;
- for (i = 0; i < passive->devices.count; i++)
- if (!acpi_processor_set_thermal_limit
- (passive->devices.handles[i],
- ACPI_PROCESSOR_LIMIT_DECREMENT))
- result = 0;
- if (result) {
- passive->flags.enabled = 0;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Disabling passive cooling (zone is cool)\n"));
- }
-}
-
-static void acpi_thermal_active(struct acpi_thermal *tz)
-{
- int result = 0;
- struct acpi_thermal_active *active = NULL;
- int i = 0;
- int j = 0;
- unsigned long maxtemp = 0;
-
-
- if (!tz)
- return;
-
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
- active = &(tz->trips.active[i]);
- if (!active || !active->flags.valid)
- break;
- if (tz->temperature >= active->temperature) {
- /*
- * Above Threshold?
- * ----------------
- * If not already enabled, turn ON all cooling devices
- * associated with this active threshold.
- */
- if (active->temperature > maxtemp)
- tz->state.active_index = i;
- maxtemp = active->temperature;
- if (active->flags.enabled)
- continue;
- for (j = 0; j < active->devices.count; j++) {
- result =
- acpi_bus_set_power(active->devices.
- handles[j],
- ACPI_STATE_D0);
- if (result) {
- printk(KERN_WARNING PREFIX
- "Unable to turn cooling device [%p] 'on'\n",
- active->devices.
- handles[j]);
- continue;
- }
- active->flags.enabled = 1;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Cooling device [%p] now 'on'\n",
- active->devices.handles[j]));
- }
- continue;
- }
- if (!active->flags.enabled)
- continue;
- /*
- * Below Threshold?
- * ----------------
- * Turn OFF all cooling devices associated with this
- * threshold.
- */
- for (j = 0; j < active->devices.count; j++) {
- result = acpi_bus_set_power(active->devices.handles[j],
- ACPI_STATE_D3);
- if (result) {
- printk(KERN_WARNING PREFIX
- "Unable to turn cooling device [%p] 'off'\n",
- active->devices.handles[j]);
- continue;
- }
- active->flags.enabled = 0;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Cooling device [%p] now 'off'\n",
- active->devices.handles[j]));
- }
- }
-}
-
-static void acpi_thermal_check(void *context);
-
-static void acpi_thermal_run(unsigned long data)
-{
- struct acpi_thermal *tz = (struct acpi_thermal *)data;
- if (!tz->zombie)
- acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data);
-}
-
-static void acpi_thermal_active_off(void *data)
-{
- int result = 0;
- struct acpi_thermal *tz = data;
- int i = 0;
- int j = 0;
- struct acpi_thermal_active *active = NULL;
-
- if (!tz) {
- printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
- return;
- }
-
- result = acpi_thermal_get_temperature(tz);
- if (result)
- return;
-
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
- active = &(tz->trips.active[i]);
- if (!active || !active->flags.valid)
- break;
- if (tz->temperature >= active->temperature) {
- /*
- * If the thermal temperature is greater than the
- * active threshod, unnecessary to turn off the
- * the active cooling device.
- */
- continue;
- }
- /*
- * Below Threshold?
- * ----------------
- * Turn OFF all cooling devices associated with this
- * threshold.
- */
- for (j = 0; j < active->devices.count; j++)
- result = acpi_bus_set_power(active->devices.handles[j],
- ACPI_STATE_D3);
- }
-}
-
static void acpi_thermal_check(void *data)
{
- int result = 0;
struct acpi_thermal *tz = data;
- unsigned long sleep_time = 0;
- unsigned long timeout_jiffies = 0;
- int i = 0;
- struct acpi_thermal_state state;
-
-
- if (!tz) {
- printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
- return;
- }
-
- /* Check if someone else is already running */
- if (!mutex_trylock(&tz->lock))
- return;
-
- state = tz->state;
-
- result = acpi_thermal_get_temperature(tz);
- if (result)
- goto unlock;
-
- if (!tz->tz_enabled)
- goto unlock;
-
- memset(&tz->state, 0, sizeof(tz->state));
-
- /*
- * Check Trip Points
- * -----------------
- * Compare the current temperature to the trip point values to see
- * if we've entered one of the thermal policy states. Note that
- * this function determines when a state is entered, but the
- * individual policy decides when it is exited (e.g. hysteresis).
- */
- if (tz->trips.critical.flags.valid)
- state.critical |=
- (tz->temperature >= tz->trips.critical.temperature);
- if (tz->trips.hot.flags.valid)
- state.hot |= (tz->temperature >= tz->trips.hot.temperature);
- if (tz->trips.passive.flags.valid)
- state.passive |=
- (tz->temperature >= tz->trips.passive.temperature);
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
- if (tz->trips.active[i].flags.valid)
- state.active |=
- (tz->temperature >=
- tz->trips.active[i].temperature);
- /*
- * Invoke Policy
- * -------------
- * Separated from the above check to allow individual policy to
- * determine when to exit a given state.
- */
- if (state.critical)
- acpi_thermal_critical(tz);
- if (state.hot)
- acpi_thermal_hot(tz);
- if (state.passive)
- acpi_thermal_passive(tz);
- if (state.active)
- acpi_thermal_active(tz);
-
- /*
- * Calculate State
- * ---------------
- * Again, separated from the above two to allow independent policy
- * decisions.
- */
- tz->state.critical = tz->trips.critical.flags.enabled;
- tz->state.hot = tz->trips.hot.flags.enabled;
- tz->state.passive = tz->trips.passive.flags.enabled;
- tz->state.active = 0;
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
- tz->state.active |= tz->trips.active[i].flags.enabled;
-
- /*
- * Calculate Sleep Time
- * --------------------
- * If we're in the passive state, use _TSP's value. Otherwise
- * use the default polling frequency (e.g. _TZP). If no polling
- * frequency is specified then we'll wait forever (at least until
- * a thermal event occurs). Note that _TSP and _TZD values are
- * given in 1/10th seconds (we must covert to milliseconds).
- */
- if (tz->state.passive) {
- sleep_time = tz->trips.passive.tsp * 100;
- timeout_jiffies = jiffies + (HZ * sleep_time) / 1000;
- } else if (tz->polling_frequency > 0) {
- sleep_time = tz->polling_frequency * 100;
- timeout_jiffies = round_jiffies(jiffies + (HZ * sleep_time) / 1000);
- }
-
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
- tz->name, tz->temperature, sleep_time));
-
- /*
- * Schedule Next Poll
- * ------------------
- */
- if (!sleep_time) {
- if (timer_pending(&(tz->timer)))
- del_timer(&(tz->timer));
- } else {
- if (timer_pending(&(tz->timer)))
- mod_timer(&(tz->timer), timeout_jiffies);
- else {
- tz->timer.data = (unsigned long)tz;
- tz->timer.function = acpi_thermal_run;
- tz->timer.expires = timeout_jiffies;
- add_timer(&(tz->timer));
- }
- }
- unlock:
- mutex_unlock(&tz->lock);
+ thermal_zone_device_update(tz->thermal_zone);
}
/* sys I/F for generic thermal sysfs support */
-#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
+#define KELVIN_TO_MILLICELSIUS(t, off) (((t) - (off)) * 100)
-static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
+static int thermal_get_temp(struct thermal_zone_device *thermal,
+ unsigned long *temp)
{
struct acpi_thermal *tz = thermal->devdata;
int result;
@@ -966,25 +599,28 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
if (result)
return result;
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
+ *temp = KELVIN_TO_MILLICELSIUS(tz->temperature, tz->kelvin_offset);
+ return 0;
}
static const char enabled[] = "kernel";
static const char disabled[] = "user";
static int thermal_get_mode(struct thermal_zone_device *thermal,
- char *buf)
+ enum thermal_device_mode *mode)
{
struct acpi_thermal *tz = thermal->devdata;
if (!tz)
return -EINVAL;
- return sprintf(buf, "%s\n", tz->tz_enabled ?
- enabled : disabled);
+ *mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED :
+ THERMAL_DEVICE_DISABLED;
+
+ return 0;
}
static int thermal_set_mode(struct thermal_zone_device *thermal,
- const char *buf)
+ enum thermal_device_mode mode)
{
struct acpi_thermal *tz = thermal->devdata;
int enable;
@@ -995,9 +631,9 @@ static int thermal_set_mode(struct thermal_zone_device *thermal,
/*
* enable/disable thermal management from ACPI thermal driver
*/
- if (!strncmp(buf, enabled, sizeof enabled - 1))
+ if (mode == THERMAL_DEVICE_ENABLED)
enable = 1;
- else if (!strncmp(buf, disabled, sizeof disabled - 1))
+ else if (mode == THERMAL_DEVICE_DISABLED)
enable = 0;
else
return -EINVAL;
@@ -1013,7 +649,7 @@ static int thermal_set_mode(struct thermal_zone_device *thermal,
}
static int thermal_get_trip_type(struct thermal_zone_device *thermal,
- int trip, char *buf)
+ int trip, enum thermal_trip_type *type)
{
struct acpi_thermal *tz = thermal->devdata;
int i;
@@ -1022,27 +658,35 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal,
return -EINVAL;
if (tz->trips.critical.flags.valid) {
- if (!trip)
- return sprintf(buf, "critical\n");
+ if (!trip) {
+ *type = THERMAL_TRIP_CRITICAL;
+ return 0;
+ }
trip--;
}
if (tz->trips.hot.flags.valid) {
- if (!trip)
- return sprintf(buf, "hot\n");
+ if (!trip) {
+ *type = THERMAL_TRIP_HOT;
+ return 0;
+ }
trip--;
}
if (tz->trips.passive.flags.valid) {
- if (!trip)
- return sprintf(buf, "passive\n");
+ if (!trip) {
+ *type = THERMAL_TRIP_PASSIVE;
+ return 0;
+ }
trip--;
}
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
tz->trips.active[i].flags.valid; i++) {
- if (!trip)
- return sprintf(buf, "active%d\n", i);
+ if (!trip) {
+ *type = THERMAL_TRIP_ACTIVE;
+ return 0;
+ }
trip--;
}
@@ -1050,7 +694,7 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal,
}
static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
- int trip, char *buf)
+ int trip, unsigned long *temp)
{
struct acpi_thermal *tz = thermal->devdata;
int i;
@@ -1059,31 +703,43 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
return -EINVAL;
if (tz->trips.critical.flags.valid) {
- if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
- tz->trips.critical.temperature));
+ if (!trip) {
+ *temp = KELVIN_TO_MILLICELSIUS(
+ tz->trips.critical.temperature,
+ tz->kelvin_offset);
+ return 0;
+ }
trip--;
}
if (tz->trips.hot.flags.valid) {
- if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
- tz->trips.hot.temperature));
+ if (!trip) {
+ *temp = KELVIN_TO_MILLICELSIUS(
+ tz->trips.hot.temperature,
+ tz->kelvin_offset);
+ return 0;
+ }
trip--;
}
if (tz->trips.passive.flags.valid) {
- if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
- tz->trips.passive.temperature));
+ if (!trip) {
+ *temp = KELVIN_TO_MILLICELSIUS(
+ tz->trips.passive.temperature,
+ tz->kelvin_offset);
+ return 0;
+ }
trip--;
}
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
tz->trips.active[i].flags.valid; i++) {
- if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
- tz->trips.active[i].temperature));
+ if (!trip) {
+ *temp = KELVIN_TO_MILLICELSIUS(
+ tz->trips.active[i].temperature,
+ tz->kelvin_offset);
+ return 0;
+ }
trip--;
}
@@ -1096,12 +752,36 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
if (tz->trips.critical.flags.valid) {
*temperature = KELVIN_TO_MILLICELSIUS(
- tz->trips.critical.temperature);
+ tz->trips.critical.temperature,
+ tz->kelvin_offset);
return 0;
} else
return -EINVAL;
}
+static int thermal_notify(struct thermal_zone_device *thermal, int trip,
+ enum thermal_trip_type trip_type)
+{
+ u8 type = 0;
+ struct acpi_thermal *tz = thermal->devdata;
+
+ if (trip_type == THERMAL_TRIP_CRITICAL)
+ type = ACPI_THERMAL_NOTIFY_CRITICAL;
+ else if (trip_type == THERMAL_TRIP_HOT)
+ type = ACPI_THERMAL_NOTIFY_HOT;
+ else
+ return 0;
+
+ acpi_bus_generate_proc_event(tz->device, type, 1);
+ acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
+ dev_name(&tz->device->dev), type, 1);
+
+ if (trip_type == THERMAL_TRIP_CRITICAL && nocrt)
+ return 1;
+
+ return 0;
+}
+
typedef int (*cb)(struct thermal_zone_device *, int,
struct thermal_cooling_device *);
static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
@@ -1194,6 +874,7 @@ static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
.get_trip_type = thermal_get_trip_type,
.get_trip_temp = thermal_get_trip_temp,
.get_crit_temp = thermal_get_crit_temp,
+ .notify = thermal_notify,
};
static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
@@ -1214,8 +895,21 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
tz->trips.active[i].flags.valid; i++, trips++);
- tz->thermal_zone = thermal_zone_device_register("acpitz",
- trips, tz, &acpi_thermal_zone_ops);
+
+ if (tz->trips.passive.flags.valid)
+ tz->thermal_zone =
+ thermal_zone_device_register("acpitz", trips, tz,
+ &acpi_thermal_zone_ops,
+ tz->trips.passive.tc1,
+ tz->trips.passive.tc2,
+ tz->trips.passive.tsp*100,
+ tz->polling_frequency*100);
+ else
+ tz->thermal_zone =
+ thermal_zone_device_register("acpitz", trips, tz,
+ &acpi_thermal_zone_ops,
+ 0, 0, 0,
+ tz->polling_frequency);
if (IS_ERR(tz->thermal_zone))
return -ENODEV;
@@ -1447,13 +1141,13 @@ static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
if (!tz)
goto end;
- if (!tz->polling_frequency) {
+ if (!tz->thermal_zone->polling_delay) {
seq_puts(seq, "<polling disabled>\n");
goto end;
}
- seq_printf(seq, "polling frequency: %lu seconds\n",
- (tz->polling_frequency / 10));
+ seq_printf(seq, "polling frequency: %d seconds\n",
+ (tz->thermal_zone->polling_delay / 1000));
end:
return 0;
@@ -1578,17 +1272,14 @@ static int acpi_thermal_remove_fs(struct acpi_device *device)
Driver Interface
-------------------------------------------------------------------------- */
-static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_thermal_notify(struct acpi_device *device, u32 event)
{
- struct acpi_thermal *tz = data;
- struct acpi_device *device = NULL;
+ struct acpi_thermal *tz = acpi_driver_data(device);
if (!tz)
return;
- device = tz->device;
-
switch (event) {
case ACPI_THERMAL_NOTIFY_TEMPERATURE:
acpi_thermal_check(tz);
@@ -1612,8 +1303,6 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
"Unsupported event [0x%x]\n", event));
break;
}
-
- return;
}
static int acpi_thermal_get_info(struct acpi_thermal *tz)
@@ -1648,10 +1337,28 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz)
return 0;
}
+/*
+ * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI
+ * handles temperature values with a single decimal place. As a consequence,
+ * some implementations use an offset of 273.1 and others use an offset of
+ * 273.2. Try to find out which one is being used, to present the most
+ * accurate and visually appealing number.
+ *
+ * The heuristic below should work for all ACPI thermal zones which have a
+ * critical trip point with a value being a multiple of 0.5 degree Celsius.
+ */
+static void acpi_thermal_guess_offset(struct acpi_thermal *tz)
+{
+ if (tz->trips.critical.flags.valid &&
+ (tz->trips.critical.temperature % 5) == 1)
+ tz->kelvin_offset = 2731;
+ else
+ tz->kelvin_offset = 2732;
+}
+
static int acpi_thermal_add(struct acpi_device *device)
{
int result = 0;
- acpi_status status = AE_OK;
struct acpi_thermal *tz = NULL;
@@ -1674,6 +1381,8 @@ static int acpi_thermal_add(struct acpi_device *device)
if (result)
goto free_memory;
+ acpi_thermal_guess_offset(tz);
+
result = acpi_thermal_register_thermal_zone(tz);
if (result)
goto free_memory;
@@ -1682,27 +1391,11 @@ static int acpi_thermal_add(struct acpi_device *device)
if (result)
goto unregister_thermal_zone;
- init_timer(&tz->timer);
-
- acpi_thermal_active_off(tz);
-
- acpi_thermal_check(tz);
-
- status = acpi_install_notify_handler(device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_thermal_notify, tz);
- if (ACPI_FAILURE(status)) {
- result = -ENODEV;
- goto remove_fs;
- }
-
printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
acpi_device_name(device), acpi_device_bid(device),
KELVIN_TO_CELSIUS(tz->temperature));
goto end;
-remove_fs:
- acpi_thermal_remove_fs(device);
unregister_thermal_zone:
thermal_zone_device_unregister(tz->thermal_zone);
free_memory:
@@ -1713,39 +1406,13 @@ end:
static int acpi_thermal_remove(struct acpi_device *device, int type)
{
- acpi_status status = AE_OK;
struct acpi_thermal *tz = NULL;
-
if (!device || !acpi_driver_data(device))
return -EINVAL;
tz = acpi_driver_data(device);
- /* avoid timer adding new defer task */
- tz->zombie = 1;
- /* wait for running timer (on other CPUs) finish */
- del_timer_sync(&(tz->timer));
- /* synchronize deferred task */
- acpi_os_wait_events_complete(NULL);
- /* deferred task may reinsert timer */
- del_timer_sync(&(tz->timer));
-
- status = acpi_remove_notify_handler(device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_thermal_notify);
-
- /* Terminate policy */
- if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {
- tz->trips.passive.flags.enabled = 0;
- acpi_thermal_passive(tz);
- }
- if (tz->trips.active[0].flags.valid
- && tz->trips.active[0].flags.enabled) {
- tz->trips.active[0].flags.enabled = 0;
- acpi_thermal_active(tz);
- }
-
acpi_thermal_remove_fs(device);
acpi_thermal_unregister_thermal_zone(tz);
mutex_destroy(&tz->lock);
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 67cc36dc9b8..cd4fb7543a9 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -37,6 +37,8 @@
#include <linux/thermal.h>
#include <linux/video_output.h>
#include <linux/sort.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
#include <asm/uaccess.h>
#include <acpi/acpi_bus.h>
@@ -77,6 +79,7 @@ module_param(brightness_switch_enabled, bool, 0644);
static int acpi_video_bus_add(struct acpi_device *device);
static int acpi_video_bus_remove(struct acpi_device *device, int type);
static int acpi_video_resume(struct acpi_device *device);
+static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id video_device_ids[] = {
{ACPI_VIDEO_HID, 0},
@@ -92,6 +95,7 @@ static struct acpi_driver acpi_video_bus = {
.add = acpi_video_bus_add,
.remove = acpi_video_bus_remove,
.resume = acpi_video_resume,
+ .notify = acpi_video_bus_notify,
},
};
@@ -162,16 +166,26 @@ struct acpi_video_device_cap {
u8 _BCL:1; /*Query list of brightness control levels supported */
u8 _BCM:1; /*Set the brightness level */
u8 _BQC:1; /* Get current brightness level */
+ u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */
u8 _DDC:1; /*Return the EDID for this device */
u8 _DCS:1; /*Return status of output device */
u8 _DGS:1; /*Query graphics state */
u8 _DSS:1; /*Device state set */
};
+struct acpi_video_brightness_flags {
+ u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */
+ u8 _BCL_reversed:1; /* _BCL package is in a reversed order*/
+ u8 _BCL_use_index:1; /* levels in _BCL are index values */
+ u8 _BCM_use_index:1; /* input of _BCM is an index value */
+ u8 _BQC_use_index:1; /* _BQC returns an index value */
+};
+
struct acpi_video_device_brightness {
int curr;
int count;
int *levels;
+ struct acpi_video_brightness_flags flags;
};
struct acpi_video_device {
@@ -189,7 +203,7 @@ struct acpi_video_device {
/* bus */
static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_info_fops = {
+static const struct file_operations acpi_video_bus_info_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_info_open_fs,
.read = seq_read,
@@ -198,7 +212,7 @@ static struct file_operations acpi_video_bus_info_fops = {
};
static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_ROM_fops = {
+static const struct file_operations acpi_video_bus_ROM_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_ROM_open_fs,
.read = seq_read,
@@ -208,7 +222,7 @@ static struct file_operations acpi_video_bus_ROM_fops = {
static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
struct file *file);
-static struct file_operations acpi_video_bus_POST_info_fops = {
+static const struct file_operations acpi_video_bus_POST_info_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_POST_info_open_fs,
.read = seq_read,
@@ -217,19 +231,25 @@ static struct file_operations acpi_video_bus_POST_info_fops = {
};
static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_POST_fops = {
+static ssize_t acpi_video_bus_write_POST(struct file *file,
+ const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_bus_POST_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_POST_open_fs,
.read = seq_read,
+ .write = acpi_video_bus_write_POST,
.llseek = seq_lseek,
.release = single_release,
};
static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_DOS_fops = {
+static ssize_t acpi_video_bus_write_DOS(struct file *file,
+ const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_bus_DOS_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_DOS_open_fs,
.read = seq_read,
+ .write = acpi_video_bus_write_DOS,
.llseek = seq_lseek,
.release = single_release,
};
@@ -237,7 +257,7 @@ static struct file_operations acpi_video_bus_DOS_fops = {
/* device */
static int acpi_video_device_info_open_fs(struct inode *inode,
struct file *file);
-static struct file_operations acpi_video_device_info_fops = {
+static const struct file_operations acpi_video_device_info_fops = {
.owner = THIS_MODULE,
.open = acpi_video_device_info_open_fs,
.read = seq_read,
@@ -247,27 +267,33 @@ static struct file_operations acpi_video_device_info_fops = {
static int acpi_video_device_state_open_fs(struct inode *inode,
struct file *file);
-static struct file_operations acpi_video_device_state_fops = {
+static ssize_t acpi_video_device_write_state(struct file *file,
+ const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_device_state_fops = {
.owner = THIS_MODULE,
.open = acpi_video_device_state_open_fs,
.read = seq_read,
+ .write = acpi_video_device_write_state,
.llseek = seq_lseek,
.release = single_release,
};
static int acpi_video_device_brightness_open_fs(struct inode *inode,
struct file *file);
+static ssize_t acpi_video_device_write_brightness(struct file *file,
+ const char __user *buffer, size_t count, loff_t *data);
static struct file_operations acpi_video_device_brightness_fops = {
.owner = THIS_MODULE,
.open = acpi_video_device_brightness_open_fs,
.read = seq_read,
+ .write = acpi_video_device_write_brightness,
.llseek = seq_lseek,
.release = single_release,
};
static int acpi_video_device_EDID_open_fs(struct inode *inode,
struct file *file);
-static struct file_operations acpi_video_device_EDID_fops = {
+static const struct file_operations acpi_video_device_EDID_fops = {
.owner = THIS_MODULE,
.open = acpi_video_device_EDID_open_fs,
.read = seq_read,
@@ -275,7 +301,7 @@ static struct file_operations acpi_video_device_EDID_fops = {
.release = single_release,
};
-static char device_decode[][30] = {
+static const char device_decode[][30] = {
"motherboard VGA device",
"PCI VGA device",
"AGP VGA device",
@@ -294,7 +320,7 @@ static int acpi_video_device_lcd_get_level_current(
unsigned long long *level);
static int acpi_video_get_next_level(struct acpi_video_device *device,
u32 level_current, u32 event);
-static void acpi_video_switch_brightness(struct acpi_video_device *device,
+static int acpi_video_switch_brightness(struct acpi_video_device *device,
int event);
static int acpi_video_device_get_state(struct acpi_video_device *device,
unsigned long long *state);
@@ -308,7 +334,9 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
int i;
struct acpi_video_device *vd =
(struct acpi_video_device *)bl_get_data(bd);
- acpi_video_device_lcd_get_level_current(vd, &cur_level);
+
+ if (acpi_video_device_lcd_get_level_current(vd, &cur_level))
+ return -EINVAL;
for (i = 2; i < vd->brightness->count; i++) {
if (vd->brightness->levels[i] == cur_level)
/* The first two entries are special - see page 575
@@ -320,12 +348,12 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
static int acpi_video_set_brightness(struct backlight_device *bd)
{
- int request_level = bd->props.brightness+2;
+ int request_level = bd->props.brightness + 2;
struct acpi_video_device *vd =
(struct acpi_video_device *)bl_get_data(bd);
- acpi_video_device_lcd_set_level(vd,
- vd->brightness->levels[request_level]);
- return 0;
+
+ return acpi_video_device_lcd_set_level(vd,
+ vd->brightness->levels[request_level]);
}
static struct backlight_ops acpi_backlight_ops = {
@@ -358,32 +386,37 @@ static struct output_properties acpi_output_properties = {
/* thermal cooling device callbacks */
-static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned
+ long *state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_video_device *video = acpi_driver_data(device);
- return sprintf(buf, "%d\n", video->brightness->count - 3);
+ *state = video->brightness->count - 3;
+ return 0;
}
-static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned
+ long *state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_video_device *video = acpi_driver_data(device);
unsigned long long level;
- int state;
+ int offset;
- acpi_video_device_lcd_get_level_current(video, &level);
- for (state = 2; state < video->brightness->count; state++)
- if (level == video->brightness->levels[state])
- return sprintf(buf, "%d\n",
- video->brightness->count - state - 1);
+ if (acpi_video_device_lcd_get_level_current(video, &level))
+ return -EINVAL;
+ for (offset = 2; offset < video->brightness->count; offset++)
+ if (level == video->brightness->levels[offset]) {
+ *state = video->brightness->count - offset - 1;
+ return 0;
+ }
return -EINVAL;
}
static int
-video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_video_device *video = acpi_driver_data(device);
@@ -479,34 +512,68 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
static int
acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
{
- int status = AE_OK;
+ int status;
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list args = { 1, &arg0 };
int state;
-
arg0.integer.value = level;
- if (device->cap._BCM)
- status = acpi_evaluate_object(device->dev->handle, "_BCM",
- &args, NULL);
+ status = acpi_evaluate_object(device->dev->handle, "_BCM",
+ &args, NULL);
+ if (ACPI_FAILURE(status)) {
+ ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
+ return -EIO;
+ }
+
device->brightness->curr = level;
for (state = 2; state < device->brightness->count; state++)
- if (level == device->brightness->levels[state])
- device->backlight->props.brightness = state - 2;
+ if (level == device->brightness->levels[state]) {
+ if (device->backlight)
+ device->backlight->props.brightness = state - 2;
+ return 0;
+ }
- return status;
+ ACPI_ERROR((AE_INFO, "Current brightness invalid"));
+ return -EINVAL;
}
static int
acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
unsigned long long *level)
{
- if (device->cap._BQC)
- return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
- level);
+ acpi_status status = AE_OK;
+
+ if (device->cap._BQC || device->cap._BCQ) {
+ char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
+
+ status = acpi_evaluate_integer(device->dev->handle, buf,
+ NULL, level);
+ if (ACPI_SUCCESS(status)) {
+ if (device->brightness->flags._BQC_use_index) {
+ if (device->brightness->flags._BCL_reversed)
+ *level = device->brightness->count
+ - 3 - (*level);
+ *level = device->brightness->levels[*level + 2];
+
+ }
+ device->brightness->curr = *level;
+ return 0;
+ } else {
+ /* Fixme:
+ * should we return an error or ignore this failure?
+ * dev->brightness->curr is a cached value which stores
+ * the correct current backlight level in most cases.
+ * ACPI video backlight still works w/ buggy _BQC.
+ * http://bugzilla.kernel.org/show_bug.cgi?id=12233
+ */
+ ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf));
+ device->cap._BQC = device->cap._BCQ = 0;
+ }
+ }
+
*level = device->brightness->curr;
- return AE_OK;
+ return 0;
}
static int
@@ -655,9 +722,11 @@ static int
acpi_video_init_brightness(struct acpi_video_device *device)
{
union acpi_object *obj = NULL;
- int i, max_level = 0, count = 0;
+ int i, max_level = 0, count = 0, level_ac_battery = 0;
+ unsigned long long level, level_old;
union acpi_object *o;
struct acpi_video_device_brightness *br = NULL;
+ int result = -EINVAL;
if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
@@ -671,13 +740,16 @@ acpi_video_init_brightness(struct acpi_video_device *device)
br = kzalloc(sizeof(*br), GFP_KERNEL);
if (!br) {
printk(KERN_ERR "can't allocate memory\n");
+ result = -ENOMEM;
goto out;
}
- br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
+ br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels),
GFP_KERNEL);
- if (!br->levels)
+ if (!br->levels) {
+ result = -ENOMEM;
goto out_free;
+ }
for (i = 0; i < obj->package.count; i++) {
o = (union acpi_object *)&obj->package.elements[i];
@@ -692,18 +764,86 @@ acpi_video_init_brightness(struct acpi_video_device *device)
count++;
}
- /* don't sort the first two brightness levels */
- sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
- acpi_video_cmp_level, NULL);
-
- if (count < 2)
- goto out_free_levels;
+ /*
+ * some buggy BIOS don't export the levels
+ * when machine is on AC/Battery in _BCL package.
+ * In this case, the first two elements in _BCL packages
+ * are also supported brightness levels that OS should take care of.
+ */
+ for (i = 2; i < count; i++)
+ if (br->levels[i] == br->levels[0] ||
+ br->levels[i] == br->levels[1])
+ level_ac_battery++;
+
+ if (level_ac_battery < 2) {
+ level_ac_battery = 2 - level_ac_battery;
+ br->flags._BCL_no_ac_battery_levels = 1;
+ for (i = (count - 1 + level_ac_battery); i >= 2; i--)
+ br->levels[i] = br->levels[i - level_ac_battery];
+ count += level_ac_battery;
+ } else if (level_ac_battery > 2)
+ ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n"));
+
+ /* Check if the _BCL package is in a reversed order */
+ if (max_level == br->levels[2]) {
+ br->flags._BCL_reversed = 1;
+ sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
+ acpi_video_cmp_level, NULL);
+ } else if (max_level != br->levels[count - 1])
+ ACPI_ERROR((AE_INFO,
+ "Found unordered _BCL package\n"));
br->count = count;
device->brightness = br;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
+
+ /* Check the input/output of _BQC/_BCL/_BCM */
+ if ((max_level < 100) && (max_level <= (count - 2)))
+ br->flags._BCL_use_index = 1;
+
+ /*
+ * _BCM is always consistent with _BCL,
+ * at least for all the laptops we have ever seen.
+ */
+ br->flags._BCM_use_index = br->flags._BCL_use_index;
+
+ /* _BQC uses INDEX while _BCL uses VALUE in some laptops */
+ br->curr = max_level;
+ result = acpi_video_device_lcd_get_level_current(device, &level_old);
+ if (result)
+ goto out_free_levels;
+
+ result = acpi_video_device_lcd_set_level(device, br->curr);
+ if (result)
+ goto out_free_levels;
+
+ result = acpi_video_device_lcd_get_level_current(device, &level);
+ if (result)
+ goto out_free_levels;
+
+ if ((level != level_old) && !br->flags._BCM_use_index) {
+ /* Note:
+ * This piece of code does not work correctly if the current
+ * brightness levels is 0.
+ * But I guess boxes that boot with such a dark screen are rare
+ * and no more code is needed to cover this specifial case.
+ */
+
+ if (level_ac_battery != 2) {
+ /*
+ * For now, we don't support the _BCL like this:
+ * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16
+ * because we may mess up the index returned by _BQC.
+ * Plus: we have not got a box like this.
+ */
+ ACPI_ERROR((AE_INFO, "_BCL not supported\n"));
+ }
+ br->flags._BQC_use_index = 1;
+ }
+
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "found %d brightness levels\n", count - 2));
kfree(obj);
- return max_level;
+ return result;
out_free_levels:
kfree(br->levels);
@@ -712,7 +852,7 @@ out_free:
out:
device->brightness = NULL;
kfree(obj);
- return 0;
+ return result;
}
/*
@@ -729,7 +869,6 @@ out:
static void acpi_video_device_find_cap(struct acpi_video_device *device)
{
acpi_handle h_dummy1;
- u32 max_level = 0;
memset(&device->cap, 0, sizeof(device->cap));
@@ -745,6 +884,12 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
}
if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
device->cap._BQC = 1;
+ else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ",
+ &h_dummy1))) {
+ printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n");
+ device->cap._BCQ = 1;
+ }
+
if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
device->cap._DDC = 1;
}
@@ -758,13 +903,14 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
device->cap._DSS = 1;
}
- if (acpi_video_backlight_support())
- max_level = acpi_video_init_brightness(device);
-
- if (device->cap._BCL && device->cap._BCM && max_level > 0) {
+ if (acpi_video_backlight_support()) {
int result;
static int count = 0;
char *name;
+
+ result = acpi_video_init_brightness(device);
+ if (result)
+ return;
name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
if (!name)
return;
@@ -773,18 +919,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
device->backlight = backlight_device_register(name,
NULL, device, &acpi_backlight_ops);
device->backlight->props.max_brightness = device->brightness->count-3;
- /*
- * If there exists the _BQC object, the _BQC object will be
- * called to get the current backlight brightness. Otherwise
- * the brightness will be set to the maximum.
- */
- if (device->cap._BQC)
- device->backlight->props.brightness =
- acpi_video_get_brightness(device->backlight);
- else
- device->backlight->props.brightness =
- device->backlight->props.max_brightness;
- backlight_update_status(device->backlight);
kfree(name);
device->cdev = thermal_cooling_device_register("LCD",
@@ -1061,13 +1195,12 @@ acpi_video_device_write_brightness(struct file *file,
/* validate through the list of available levels */
for (i = 2; i < dev->brightness->count; i++)
if (level == dev->brightness->levels[i]) {
- if (ACPI_SUCCESS
- (acpi_video_device_lcd_set_level(dev, level)))
- dev->brightness->curr = level;
+ if (!acpi_video_device_lcd_set_level(dev, level))
+ return count;
break;
}
- return count;
+ return -EINVAL;
}
static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
@@ -1132,7 +1265,6 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
goto err_remove_dir;
/* 'state' [R/W] */
- acpi_video_device_state_fops.write = acpi_video_device_write_state;
entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR,
device_dir,
&acpi_video_device_state_fops,
@@ -1141,8 +1273,6 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
goto err_remove_info;
/* 'brightness' [R/W] */
- acpi_video_device_brightness_fops.write =
- acpi_video_device_write_brightness;
entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR,
device_dir,
&acpi_video_device_brightness_fops,
@@ -1423,7 +1553,6 @@ static int acpi_video_bus_add_fs(struct acpi_device *device)
goto err_remove_rom;
/* 'POST' [R/W] */
- acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
device_dir,
&acpi_video_bus_POST_fops,
@@ -1432,7 +1561,6 @@ static int acpi_video_bus_add_fs(struct acpi_device *device)
goto err_remove_post_info;
/* 'DOS' [R/W] */
- acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
device_dir,
&acpi_video_bus_DOS_fops,
@@ -1745,15 +1873,29 @@ acpi_video_get_next_level(struct acpi_video_device *device,
}
}
-static void
+static int
acpi_video_switch_brightness(struct acpi_video_device *device, int event)
{
unsigned long long level_current, level_next;
+ int result = -EINVAL;
+
if (!device->brightness)
- return;
- acpi_video_device_lcd_get_level_current(device, &level_current);
+ goto out;
+
+ result = acpi_video_device_lcd_get_level_current(device,
+ &level_current);
+ if (result)
+ goto out;
+
level_next = acpi_video_get_next_level(device, level_current, event);
- acpi_video_device_lcd_set_level(device, level_next);
+
+ result = acpi_video_device_lcd_set_level(device, level_next);
+
+out:
+ if (result)
+ printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
+
+ return result;
}
static int
@@ -1846,17 +1988,15 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
return acpi_video_bus_DOS(video, 0, 1);
}
-static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
{
- struct acpi_video_bus *video = data;
- struct acpi_device *device = NULL;
+ struct acpi_video_bus *video = acpi_driver_data(device);
struct input_dev *input;
int keycode;
if (!video)
return;
- device = video->device;
input = video->input;
switch (event) {
@@ -1987,7 +2127,6 @@ static int acpi_video_resume(struct acpi_device *device)
static int acpi_video_bus_add(struct acpi_device *device)
{
- acpi_status status;
struct acpi_video_bus *video;
struct input_dev *input;
int error;
@@ -2029,20 +2168,10 @@ static int acpi_video_bus_add(struct acpi_device *device)
acpi_video_bus_get_devices(video, device);
acpi_video_bus_start_devices(video);
- status = acpi_install_notify_handler(device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_video_bus_notify, video);
- if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX
- "Error installing notify handler\n");
- error = -ENODEV;
- goto err_stop_video;
- }
-
video->input = input = input_allocate_device();
if (!input) {
error = -ENOMEM;
- goto err_uninstall_notify;
+ goto err_stop_video;
}
snprintf(video->phys, sizeof(video->phys),
@@ -2078,9 +2207,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
err_free_input_dev:
input_free_device(input);
- err_uninstall_notify:
- acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
- acpi_video_bus_notify);
err_stop_video:
acpi_video_bus_stop_devices(video);
acpi_video_bus_put_devices(video);
@@ -2095,7 +2221,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
static int acpi_video_bus_remove(struct acpi_device *device, int type)
{
- acpi_status status = 0;
struct acpi_video_bus *video = NULL;
@@ -2105,11 +2230,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
video = acpi_driver_data(device);
acpi_video_bus_stop_devices(video);
-
- status = acpi_remove_notify_handler(video->device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_video_bus_notify);
-
acpi_video_bus_put_devices(video);
acpi_video_bus_remove_fs(device);
@@ -2120,7 +2240,27 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
return 0;
}
-static int __init acpi_video_init(void)
+static int __init intel_opregion_present(void)
+{
+#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
+ struct pci_dev *dev = NULL;
+ u32 address;
+
+ for_each_pci_dev(dev) {
+ if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+ continue;
+ if (dev->vendor != PCI_VENDOR_ID_INTEL)
+ continue;
+ pci_read_config_dword(dev, 0xfc, &address);
+ if (!address)
+ continue;
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+int acpi_video_register(void)
{
int result = 0;
@@ -2136,6 +2276,22 @@ static int __init acpi_video_init(void)
return 0;
}
+EXPORT_SYMBOL(acpi_video_register);
+
+/*
+ * This is kind of nasty. Hardware using Intel chipsets may require
+ * the video opregion code to be run first in order to initialise
+ * state before any ACPI video calls are made. To handle this we defer
+ * registration of the video class until the opregion code has run.
+ */
+
+static int __init acpi_video_init(void)
+{
+ if (intel_opregion_present())
+ return 0;
+
+ return acpi_video_register();
+}
static void __exit acpi_video_exit(void)
{
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 50e3d2dbf3a..09737275e25 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -55,6 +55,9 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
"support\n"));
*cap |= ACPI_VIDEO_BACKLIGHT;
+ if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy)))
+ printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness "
+ "control misses _BQC function\n");
/* We have backlight support, no need to scan further */
return AE_CTRL_TERMINATE;
}
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index 2d34806d45d..88725dcdf8b 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -8,14 +8,18 @@
#include <acpi/acpi_drivers.h>
#include <linux/kernel.h>
#include <linux/types.h>
+
+#include "internal.h"
#include "sleep.h"
+/*
+ * We didn't lock acpi_device_lock in the file, because it invokes oops in
+ * suspend/resume and isn't really required as this is called in S-state. At
+ * that time, there is no device hotplug
+ **/
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("wakeup_devices")
-extern struct list_head acpi_wakeup_device_list;
-extern spinlock_t acpi_device_lock;
-
/**
* acpi_enable_wakeup_device_prep - prepare wakeup devices
* @sleep_state: ACPI state
@@ -27,7 +31,6 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state)
{
struct list_head *node, *next;
- spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev = container_of(node,
struct acpi_device,
@@ -38,11 +41,8 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state)
(sleep_state > (u32) dev->wakeup.sleep_state))
continue;
- spin_unlock(&acpi_device_lock);
acpi_enable_wakeup_device_power(dev, sleep_state);
- spin_lock(&acpi_device_lock);
}
- spin_unlock(&acpi_device_lock);
}
/**
@@ -58,7 +58,6 @@ void acpi_enable_wakeup_device(u8 sleep_state)
* Caution: this routine must be invoked when interrupt is disabled
* Refer ACPI2.0: P212
*/
- spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev =
container_of(node, struct acpi_device, wakeup_list);
@@ -72,22 +71,17 @@ void acpi_enable_wakeup_device(u8 sleep_state)
if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
|| sleep_state > (u32) dev->wakeup.sleep_state) {
if (dev->wakeup.flags.run_wake) {
- spin_unlock(&acpi_device_lock);
/* set_gpe_type will disable GPE, leave it like that */
acpi_set_gpe_type(dev->wakeup.gpe_device,
dev->wakeup.gpe_number,
ACPI_GPE_TYPE_RUNTIME);
- spin_lock(&acpi_device_lock);
}
continue;
}
- spin_unlock(&acpi_device_lock);
if (!dev->wakeup.flags.run_wake)
acpi_enable_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number);
- spin_lock(&acpi_device_lock);
}
- spin_unlock(&acpi_device_lock);
}
/**
@@ -99,7 +93,6 @@ void acpi_disable_wakeup_device(u8 sleep_state)
{
struct list_head *node, *next;
- spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev =
container_of(node, struct acpi_device, wakeup_list);
@@ -110,19 +103,16 @@ void acpi_disable_wakeup_device(u8 sleep_state)
if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
|| sleep_state > (u32) dev->wakeup.sleep_state) {
if (dev->wakeup.flags.run_wake) {
- spin_unlock(&acpi_device_lock);
acpi_set_gpe_type(dev->wakeup.gpe_device,
dev->wakeup.gpe_number,
ACPI_GPE_TYPE_WAKE_RUN);
/* Re-enable it, since set_gpe_type will disable it */
acpi_enable_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number);
- spin_lock(&acpi_device_lock);
}
continue;
}
- spin_unlock(&acpi_device_lock);
acpi_disable_wakeup_device_power(dev);
/* Never disable run-wake GPE */
if (!dev->wakeup.flags.run_wake) {
@@ -131,19 +121,14 @@ void acpi_disable_wakeup_device(u8 sleep_state)
acpi_clear_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number, ACPI_NOT_ISR);
}
- spin_lock(&acpi_device_lock);
}
- spin_unlock(&acpi_device_lock);
}
-static int __init acpi_wakeup_device_init(void)
+int __init acpi_wakeup_device_init(void)
{
struct list_head *node, *next;
- if (acpi_disabled)
- return 0;
-
- spin_lock(&acpi_device_lock);
+ mutex_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev = container_of(node,
struct acpi_device,
@@ -151,17 +136,13 @@ static int __init acpi_wakeup_device_init(void)
/* In case user doesn't load button driver */
if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
continue;
- spin_unlock(&acpi_device_lock);
acpi_set_gpe_type(dev->wakeup.gpe_device,
dev->wakeup.gpe_number,
ACPI_GPE_TYPE_WAKE_RUN);
acpi_enable_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number);
dev->wakeup.state.enabled = 1;
- spin_lock(&acpi_device_lock);
}
- spin_unlock(&acpi_device_lock);
+ mutex_unlock(&acpi_device_lock);
return 0;
}
-
-late_initcall(acpi_wakeup_device_init);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 0bcf2646467..9120717c070 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -86,7 +86,7 @@ config ATA_SFF
For users with exclusively modern controllers like AHCI,
Silicon Image 3124, or Marvell 6440, you may choose to
- disable this uneeded SFF support.
+ disable this unneeded SFF support.
If unsure, say Y.
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 788bba2b1e1..08186ecbaf8 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -78,6 +78,7 @@ static ssize_t ahci_led_store(struct ata_port *ap, const char *buf,
static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
ssize_t size);
#define MAX_SLOTS 8
+#define MAX_RETRY 15
enum {
AHCI_PCI_BAR = 5,
@@ -113,6 +114,7 @@ enum {
board_ahci_sb700 = 5, /* for SB700 and SB800 */
board_ahci_mcp65 = 6,
board_ahci_nopmp = 7,
+ board_ahci_yesncq = 8,
/* global controller registers */
HOST_CAP = 0x00, /* host capabilities */
@@ -468,6 +470,14 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
+ /* board_ahci_yesncq */
+ {
+ AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ),
+ .flags = AHCI_FLAG_COMMON,
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_ops,
+ },
};
static const struct pci_device_id ahci_pci_tbl[] = {
@@ -534,30 +544,30 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, 0x045d), board_ahci_mcp65 }, /* MCP65 */
{ PCI_VDEVICE(NVIDIA, 0x045e), board_ahci_mcp65 }, /* MCP65 */
{ PCI_VDEVICE(NVIDIA, 0x045f), board_ahci_mcp65 }, /* MCP65 */
- { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0553), board_ahci }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0554), board_ahci }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0555), board_ahci }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0556), board_ahci }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0557), board_ahci }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0558), board_ahci }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0559), board_ahci }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci }, /* MCP73 */
- { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci }, /* MCP73 */
- { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci }, /* MCP73 */
- { PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci }, /* MCP73 */
- { PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci }, /* MCP73 */
- { PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci }, /* MCP73 */
- { PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci }, /* MCP73 */
- { PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci }, /* MCP73 */
- { PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci }, /* MCP73 */
- { PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci }, /* MCP73 */
- { PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci }, /* MCP73 */
- { PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0553), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0554), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0555), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0556), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0557), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0558), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0559), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci_yesncq }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci_yesncq }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci_yesncq }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci_yesncq }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci_yesncq }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci_yesncq }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci_yesncq }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci_yesncq }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci_yesncq }, /* MCP73 */
{ PCI_VDEVICE(NVIDIA, 0x0ad0), board_ahci }, /* MCP77 */
{ PCI_VDEVICE(NVIDIA, 0x0ad1), board_ahci }, /* MCP77 */
{ PCI_VDEVICE(NVIDIA, 0x0ad2), board_ahci }, /* MCP77 */
@@ -1115,6 +1125,8 @@ static void ahci_start_port(struct ata_port *ap)
struct ahci_port_priv *pp = ap->private_data;
struct ata_link *link;
struct ahci_em_priv *emp;
+ ssize_t rc;
+ int i;
/* enable FIS reception */
ahci_start_fis_rx(ap);
@@ -1126,7 +1138,17 @@ static void ahci_start_port(struct ata_port *ap)
if (ap->flags & ATA_FLAG_EM) {
ata_for_each_link(link, ap, EDGE) {
emp = &pp->em_priv[link->pmp];
- ahci_transmit_led_message(ap, emp->led_state, 4);
+
+ /* EM Transmit bit maybe busy during init */
+ for (i = 0; i < MAX_RETRY; i++) {
+ rc = ahci_transmit_led_message(ap,
+ emp->led_state,
+ 4);
+ if (rc == -EBUSY)
+ udelay(100);
+ else
+ break;
+ }
}
}
@@ -1331,7 +1353,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
em_ctl = readl(mmio + HOST_EM_CTL);
if (em_ctl & EM_CTL_TM) {
spin_unlock_irqrestore(ap->lock, flags);
- return -EINVAL;
+ return -EBUSY;
}
/*
@@ -2405,10 +2427,10 @@ static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
int rc;
if (using_dac &&
- !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
- rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (rc) {
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"64-bit DMA enable failed\n");
@@ -2416,13 +2438,13 @@ static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
}
}
} else {
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit DMA enable failed\n");
return rc;
}
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit consistent DMA enable failed\n");
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index e5cbe80ce17..942d14ac879 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -1053,6 +1053,13 @@ static int piix_broken_suspend(void)
DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M500"),
},
},
+ {
+ .ident = "VGN-BX297XP",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-BX297XP"),
+ },
+ },
{ } /* terminate list */
};
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index e7ea77cf606..065507c4664 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -6110,13 +6110,11 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
ata_port_printk(ap, KERN_INFO, "DUMMY\n");
}
- /* perform each probe synchronously */
- DPRINTK("probe begin\n");
+ /* perform each probe asynchronously */
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
async_schedule(async_port_probe, ap);
}
- DPRINTK("probe end\n");
return 0;
}
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index db6a96984f3..0df83cf7423 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -203,11 +203,11 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
return -ENODEV;
}
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n");
return -ENODEV;
}
- if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n");
return -ENODEV;
}
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index 19fdecf319a..ba54b089f98 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -157,7 +157,7 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
return -ENOMEM;
/* acquire resources and fill host */
- pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000);
data->cs1 = devm_ioremap(&pdev->dev, cs1->start, 0x1000);
diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c
index efe2c1985af..8d9343accf3 100644
--- a/drivers/ata/pata_octeon_cf.c
+++ b/drivers/ata/pata_octeon_cf.c
@@ -503,7 +503,7 @@ static void octeon_cf_dma_setup(struct ata_queued_cmd *qc)
struct ata_port *ap = qc->ap;
struct octeon_cf_port *cf_port;
- cf_port = (struct octeon_cf_port *)ap->private_data;
+ cf_port = ap->private_data;
DPRINTK("ENTER\n");
/* issue r/w command */
qc->cursg = qc->sg;
@@ -596,7 +596,7 @@ static unsigned int octeon_cf_dma_finished(struct ata_port *ap,
if (ap->hsm_task_state != HSM_ST_LAST)
return 0;
- cf_port = (struct octeon_cf_port *)ap->private_data;
+ cf_port = ap->private_data;
dma_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine));
if (dma_cfg.s.size != 0xfffff) {
@@ -657,7 +657,7 @@ static irqreturn_t octeon_cf_interrupt(int irq, void *dev_instance)
continue;
ocd = ap->dev->platform_data;
- cf_port = (struct octeon_cf_port *)ap->private_data;
+ cf_port = ap->private_data;
dma_int.u64 =
cvmx_read_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine));
dma_cfg.u64 =
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 39588178d02..6c65b0776a2 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -607,13 +607,13 @@ static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
{
int rc;
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit DMA enable failed\n");
return rc;
}
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit consistent DMA enable failed\n");
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index 305a4f825f5..8d890cc5a7e 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -861,14 +861,14 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
/* Set dma_mask. This devices doesn't support 64bit addressing. */
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit DMA enable failed\n");
return rc;
}
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit consistent DMA enable failed\n");
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index a377226b81c..37ae5dc1070 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -28,10 +28,6 @@
/*
* sata_mv TODO list:
*
- * --> More errata workarounds for PCI-X.
- *
- * --> Complete a full errata audit for all chipsets to identify others.
- *
* --> Develop a low-power-consumption strategy, and implement it.
*
* --> Add sysfs attributes for per-chip / per-HC IRQ coalescing thresholds.
@@ -44,6 +40,15 @@
* connect two SATA ports.
*/
+/*
+ * 80x1-B2 errata PCI#11:
+ *
+ * Users of the 6041/6081 Rev.B2 chips (current is C0)
+ * should be careful to insert those cards only onto PCI-X bus #0,
+ * and only in device slots 0..7, not higher. The chips may not
+ * work correctly otherwise (note: this is a pretty rare condition).
+ */
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
@@ -64,7 +69,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_mv"
-#define DRV_VERSION "1.27"
+#define DRV_VERSION "1.28"
/*
* module options
@@ -109,23 +114,23 @@ enum {
* Coalescing defers the interrupt until either the IO_THRESHOLD
* (count of completed I/Os) is met, or the TIME_THRESHOLD is met.
*/
- MV_COAL_REG_BASE = 0x18000,
- MV_IRQ_COAL_CAUSE = (MV_COAL_REG_BASE + 0x08),
+ COAL_REG_BASE = 0x18000,
+ IRQ_COAL_CAUSE = (COAL_REG_BASE + 0x08),
ALL_PORTS_COAL_IRQ = (1 << 4), /* all ports irq event */
- MV_IRQ_COAL_IO_THRESHOLD = (MV_COAL_REG_BASE + 0xcc),
- MV_IRQ_COAL_TIME_THRESHOLD = (MV_COAL_REG_BASE + 0xd0),
+ IRQ_COAL_IO_THRESHOLD = (COAL_REG_BASE + 0xcc),
+ IRQ_COAL_TIME_THRESHOLD = (COAL_REG_BASE + 0xd0),
/*
* Registers for the (unused here) transaction coalescing feature:
*/
- MV_TRAN_COAL_CAUSE_LO = (MV_COAL_REG_BASE + 0x88),
- MV_TRAN_COAL_CAUSE_HI = (MV_COAL_REG_BASE + 0x8c),
+ TRAN_COAL_CAUSE_LO = (COAL_REG_BASE + 0x88),
+ TRAN_COAL_CAUSE_HI = (COAL_REG_BASE + 0x8c),
- MV_SATAHC0_REG_BASE = 0x20000,
- MV_FLASH_CTL_OFS = 0x1046c,
- MV_GPIO_PORT_CTL_OFS = 0x104f0,
- MV_RESET_CFG_OFS = 0x180d8,
+ SATAHC0_REG_BASE = 0x20000,
+ FLASH_CTL = 0x1046c,
+ GPIO_PORT_CTL = 0x104f0,
+ RESET_CFG = 0x180d8,
MV_PCI_REG_SZ = MV_MAJOR_REG_AREA_SZ,
MV_SATAHC_REG_SZ = MV_MAJOR_REG_AREA_SZ,
@@ -180,40 +185,41 @@ enum {
/* PCI interface registers */
- PCI_COMMAND_OFS = 0xc00,
- PCI_COMMAND_MRDTRIG = (1 << 7), /* PCI Master Read Trigger */
+ MV_PCI_COMMAND = 0xc00,
+ MV_PCI_COMMAND_MWRCOM = (1 << 4), /* PCI Master Write Combining */
+ MV_PCI_COMMAND_MRDTRIG = (1 << 7), /* PCI Master Read Trigger */
- PCI_MAIN_CMD_STS_OFS = 0xd30,
+ PCI_MAIN_CMD_STS = 0xd30,
STOP_PCI_MASTER = (1 << 2),
PCI_MASTER_EMPTY = (1 << 3),
GLOB_SFT_RST = (1 << 4),
- MV_PCI_MODE_OFS = 0xd00,
+ MV_PCI_MODE = 0xd00,
MV_PCI_MODE_MASK = 0x30,
MV_PCI_EXP_ROM_BAR_CTL = 0xd2c,
MV_PCI_DISC_TIMER = 0xd04,
MV_PCI_MSI_TRIGGER = 0xc38,
MV_PCI_SERR_MASK = 0xc28,
- MV_PCI_XBAR_TMOUT_OFS = 0x1d04,
+ MV_PCI_XBAR_TMOUT = 0x1d04,
MV_PCI_ERR_LOW_ADDRESS = 0x1d40,
MV_PCI_ERR_HIGH_ADDRESS = 0x1d44,
MV_PCI_ERR_ATTRIBUTE = 0x1d48,
MV_PCI_ERR_COMMAND = 0x1d50,
- PCI_IRQ_CAUSE_OFS = 0x1d58,
- PCI_IRQ_MASK_OFS = 0x1d5c,
+ PCI_IRQ_CAUSE = 0x1d58,
+ PCI_IRQ_MASK = 0x1d5c,
PCI_UNMASK_ALL_IRQS = 0x7fffff, /* bits 22-0 */
- PCIE_IRQ_CAUSE_OFS = 0x1900,
- PCIE_IRQ_MASK_OFS = 0x1910,
+ PCIE_IRQ_CAUSE = 0x1900,
+ PCIE_IRQ_MASK = 0x1910,
PCIE_UNMASK_ALL_IRQS = 0x40a, /* assorted bits */
/* Host Controller Main Interrupt Cause/Mask registers (1 per-chip) */
- PCI_HC_MAIN_IRQ_CAUSE_OFS = 0x1d60,
- PCI_HC_MAIN_IRQ_MASK_OFS = 0x1d64,
- SOC_HC_MAIN_IRQ_CAUSE_OFS = 0x20020,
- SOC_HC_MAIN_IRQ_MASK_OFS = 0x20024,
+ PCI_HC_MAIN_IRQ_CAUSE = 0x1d60,
+ PCI_HC_MAIN_IRQ_MASK = 0x1d64,
+ SOC_HC_MAIN_IRQ_CAUSE = 0x20020,
+ SOC_HC_MAIN_IRQ_MASK = 0x20024,
ERR_IRQ = (1 << 0), /* shift by (2 * port #) */
DONE_IRQ = (1 << 1), /* shift by (2 * port #) */
HC0_IRQ_PEND = 0x1ff, /* bits 0-8 = HC0's ports */
@@ -234,9 +240,9 @@ enum {
HC_MAIN_RSVD_SOC = (0x3fffffb << 6), /* bits 31-9, 7-6 */
/* SATAHC registers */
- HC_CFG_OFS = 0,
+ HC_CFG = 0x00,
- HC_IRQ_CAUSE_OFS = 0x14,
+ HC_IRQ_CAUSE = 0x14,
DMA_IRQ = (1 << 0), /* shift by port # */
HC_COAL_IRQ = (1 << 4), /* IRQ coalescing */
DEV_IRQ = (1 << 8), /* shift by port # */
@@ -248,53 +254,54 @@ enum {
* Coalescing defers the interrupt until either the IO_THRESHOLD
* (count of completed I/Os) is met, or the TIME_THRESHOLD is met.
*/
- HC_IRQ_COAL_IO_THRESHOLD_OFS = 0x000c,
- HC_IRQ_COAL_TIME_THRESHOLD_OFS = 0x0010,
+ HC_IRQ_COAL_IO_THRESHOLD = 0x000c,
+ HC_IRQ_COAL_TIME_THRESHOLD = 0x0010,
- SOC_LED_CTRL_OFS = 0x2c,
+ SOC_LED_CTRL = 0x2c,
SOC_LED_CTRL_BLINK = (1 << 0), /* Active LED blink */
SOC_LED_CTRL_ACT_PRESENCE = (1 << 2), /* Multiplex dev presence */
/* with dev activity LED */
/* Shadow block registers */
- SHD_BLK_OFS = 0x100,
- SHD_CTL_AST_OFS = 0x20, /* ofs from SHD_BLK_OFS */
+ SHD_BLK = 0x100,
+ SHD_CTL_AST = 0x20, /* ofs from SHD_BLK */
/* SATA registers */
- SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */
- SATA_ACTIVE_OFS = 0x350,
- SATA_FIS_IRQ_CAUSE_OFS = 0x364,
- SATA_FIS_IRQ_AN = (1 << 9), /* async notification */
+ SATA_STATUS = 0x300, /* ctrl, err regs follow status */
+ SATA_ACTIVE = 0x350,
+ FIS_IRQ_CAUSE = 0x364,
+ FIS_IRQ_CAUSE_AN = (1 << 9), /* async notification */
- LTMODE_OFS = 0x30c,
+ LTMODE = 0x30c, /* requires read-after-write */
LTMODE_BIT8 = (1 << 8), /* unknown, but necessary */
+ PHY_MODE2 = 0x330,
PHY_MODE3 = 0x310,
- PHY_MODE4 = 0x314,
+
+ PHY_MODE4 = 0x314, /* requires read-after-write */
PHY_MODE4_CFG_MASK = 0x00000003, /* phy internal config field */
PHY_MODE4_CFG_VALUE = 0x00000001, /* phy internal config field */
PHY_MODE4_RSVD_ZEROS = 0x5de3fffa, /* Gen2e always write zeros */
PHY_MODE4_RSVD_ONES = 0x00000005, /* Gen2e always write ones */
- PHY_MODE2 = 0x330,
- SATA_IFCTL_OFS = 0x344,
- SATA_TESTCTL_OFS = 0x348,
- SATA_IFSTAT_OFS = 0x34c,
- VENDOR_UNIQUE_FIS_OFS = 0x35c,
+ SATA_IFCTL = 0x344,
+ SATA_TESTCTL = 0x348,
+ SATA_IFSTAT = 0x34c,
+ VENDOR_UNIQUE_FIS = 0x35c,
- FISCFG_OFS = 0x360,
+ FISCFG = 0x360,
FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */
FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */
MV5_PHY_MODE = 0x74,
- MV5_LTMODE_OFS = 0x30,
- MV5_PHY_CTL_OFS = 0x0C,
- SATA_INTERFACE_CFG_OFS = 0x050,
+ MV5_LTMODE = 0x30,
+ MV5_PHY_CTL = 0x0C,
+ SATA_IFCFG = 0x050,
MV_M2_PREAMP_MASK = 0x7e0,
/* Port registers */
- EDMA_CFG_OFS = 0,
+ EDMA_CFG = 0,
EDMA_CFG_Q_DEPTH = 0x1f, /* max device queue depth */
EDMA_CFG_NCQ = (1 << 5), /* for R/W FPDMA queued */
EDMA_CFG_NCQ_GO_ON_ERR = (1 << 14), /* continue on error */
@@ -303,8 +310,8 @@ enum {
EDMA_CFG_EDMA_FBS = (1 << 16), /* EDMA FIS-Based Switching */
EDMA_CFG_FBS = (1 << 26), /* FIS-Based Switching */
- EDMA_ERR_IRQ_CAUSE_OFS = 0x8,
- EDMA_ERR_IRQ_MASK_OFS = 0xc,
+ EDMA_ERR_IRQ_CAUSE = 0x8,
+ EDMA_ERR_IRQ_MASK = 0xc,
EDMA_ERR_D_PAR = (1 << 0), /* UDMA data parity err */
EDMA_ERR_PRD_PAR = (1 << 1), /* UDMA PRD parity err */
EDMA_ERR_DEV = (1 << 2), /* device error */
@@ -373,36 +380,36 @@ enum {
EDMA_ERR_INTRL_PAR |
EDMA_ERR_IORDY,
- EDMA_REQ_Q_BASE_HI_OFS = 0x10,
- EDMA_REQ_Q_IN_PTR_OFS = 0x14, /* also contains BASE_LO */
+ EDMA_REQ_Q_BASE_HI = 0x10,
+ EDMA_REQ_Q_IN_PTR = 0x14, /* also contains BASE_LO */
- EDMA_REQ_Q_OUT_PTR_OFS = 0x18,
+ EDMA_REQ_Q_OUT_PTR = 0x18,
EDMA_REQ_Q_PTR_SHIFT = 5,
- EDMA_RSP_Q_BASE_HI_OFS = 0x1c,
- EDMA_RSP_Q_IN_PTR_OFS = 0x20,
- EDMA_RSP_Q_OUT_PTR_OFS = 0x24, /* also contains BASE_LO */
+ EDMA_RSP_Q_BASE_HI = 0x1c,
+ EDMA_RSP_Q_IN_PTR = 0x20,
+ EDMA_RSP_Q_OUT_PTR = 0x24, /* also contains BASE_LO */
EDMA_RSP_Q_PTR_SHIFT = 3,
- EDMA_CMD_OFS = 0x28, /* EDMA command register */
+ EDMA_CMD = 0x28, /* EDMA command register */
EDMA_EN = (1 << 0), /* enable EDMA */
EDMA_DS = (1 << 1), /* disable EDMA; self-negated */
EDMA_RESET = (1 << 2), /* reset eng/trans/link/phy */
- EDMA_STATUS_OFS = 0x30, /* EDMA engine status */
+ EDMA_STATUS = 0x30, /* EDMA engine status */
EDMA_STATUS_CACHE_EMPTY = (1 << 6), /* GenIIe command cache empty */
EDMA_STATUS_IDLE = (1 << 7), /* GenIIe EDMA enabled/idle */
- EDMA_IORDY_TMOUT_OFS = 0x34,
- EDMA_ARB_CFG_OFS = 0x38,
+ EDMA_IORDY_TMOUT = 0x34,
+ EDMA_ARB_CFG = 0x38,
- EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */
- EDMA_UNKNOWN_RSVD_OFS = 0x6C, /* GenIIe unknown/reserved */
+ EDMA_HALTCOND = 0x60, /* GenIIe halt conditions */
+ EDMA_UNKNOWN_RSVD = 0x6C, /* GenIIe unknown/reserved */
- BMDMA_CMD_OFS = 0x224, /* bmdma command register */
- BMDMA_STATUS_OFS = 0x228, /* bmdma status register */
- BMDMA_PRD_LOW_OFS = 0x22c, /* bmdma PRD addr 31:0 */
- BMDMA_PRD_HIGH_OFS = 0x230, /* bmdma PRD addr 63:32 */
+ BMDMA_CMD = 0x224, /* bmdma command register */
+ BMDMA_STATUS = 0x228, /* bmdma status register */
+ BMDMA_PRD_LOW = 0x22c, /* bmdma PRD addr 31:0 */
+ BMDMA_PRD_HIGH = 0x230, /* bmdma PRD addr 63:32 */
/* Host private flags (hp_flags) */
MV_HP_FLAG_MSI = (1 << 0),
@@ -534,8 +541,8 @@ struct mv_host_priv {
void __iomem *base;
void __iomem *main_irq_cause_addr;
void __iomem *main_irq_mask_addr;
- u32 irq_cause_ofs;
- u32 irq_mask_ofs;
+ u32 irq_cause_offset;
+ u32 irq_mask_offset;
u32 unmask_all_irqs;
/*
* These consistent DMA memory pools give us guaranteed
@@ -694,49 +701,49 @@ static struct ata_port_operations mv_iie_ops = {
static const struct ata_port_info mv_port_info[] = {
{ /* chip_504x */
.flags = MV_GEN_I_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_508x */
.flags = MV_GEN_I_FLAGS | MV_FLAG_DUAL_HC,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_5080 */
.flags = MV_GEN_I_FLAGS | MV_FLAG_DUAL_HC,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_604x */
.flags = MV_GEN_II_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &mv6_ops,
},
{ /* chip_608x */
.flags = MV_GEN_II_FLAGS | MV_FLAG_DUAL_HC,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &mv6_ops,
},
{ /* chip_6042 */
.flags = MV_GEN_IIE_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
},
{ /* chip_7042 */
.flags = MV_GEN_IIE_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
},
{ /* chip_soc */
.flags = MV_GEN_IIE_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
},
@@ -840,7 +847,7 @@ static inline unsigned int mv_hardport_from_port(unsigned int port)
static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc)
{
- return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ));
+ return (base + SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ));
}
static inline void __iomem *mv_hc_base_from_port(void __iomem *base,
@@ -895,10 +902,10 @@ static void mv_save_cached_regs(struct ata_port *ap)
void __iomem *port_mmio = mv_ap_base(ap);
struct mv_port_priv *pp = ap->private_data;
- pp->cached.fiscfg = readl(port_mmio + FISCFG_OFS);
- pp->cached.ltmode = readl(port_mmio + LTMODE_OFS);
- pp->cached.haltcond = readl(port_mmio + EDMA_HALTCOND_OFS);
- pp->cached.unknown_rsvd = readl(port_mmio + EDMA_UNKNOWN_RSVD_OFS);
+ pp->cached.fiscfg = readl(port_mmio + FISCFG);
+ pp->cached.ltmode = readl(port_mmio + LTMODE);
+ pp->cached.haltcond = readl(port_mmio + EDMA_HALTCOND);
+ pp->cached.unknown_rsvd = readl(port_mmio + EDMA_UNKNOWN_RSVD);
}
/**
@@ -913,8 +920,26 @@ static void mv_save_cached_regs(struct ata_port *ap)
static inline void mv_write_cached_reg(void __iomem *addr, u32 *old, u32 new)
{
if (new != *old) {
+ unsigned long laddr;
*old = new;
- writel(new, addr);
+ /*
+ * Workaround for 88SX60x1-B2 FEr SATA#13:
+ * Read-after-write is needed to prevent generating 64-bit
+ * write cycles on the PCI bus for SATA interface registers
+ * at offsets ending in 0x4 or 0xc.
+ *
+ * Looks like a lot of fuss, but it avoids an unnecessary
+ * +1 usec read-after-write delay for unaffected registers.
+ */
+ laddr = (long)addr & 0xffff;
+ if (laddr >= 0x300 && laddr <= 0x33c) {
+ laddr &= 0x000f;
+ if (laddr == 0x4 || laddr == 0xc) {
+ writelfl(new, addr); /* read after write */
+ return;
+ }
+ }
+ writel(new, addr); /* unaffected by the errata */
}
}
@@ -931,10 +956,10 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio,
index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT;
WARN_ON(pp->crqb_dma & 0x3ff);
- writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
+ writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI);
writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | index,
- port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
- writelfl(index, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
+ port_mmio + EDMA_REQ_Q_IN_PTR);
+ writelfl(index, port_mmio + EDMA_REQ_Q_OUT_PTR);
/*
* initialize response queue
@@ -943,10 +968,10 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio,
index = pp->resp_idx << EDMA_RSP_Q_PTR_SHIFT;
WARN_ON(pp->crpb_dma & 0xff);
- writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
- writelfl(index, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
+ writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI);
+ writelfl(index, port_mmio + EDMA_RSP_Q_IN_PTR);
writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | index,
- port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+ port_mmio + EDMA_RSP_Q_OUT_PTR);
}
static void mv_write_main_irq_mask(u32 mask, struct mv_host_priv *hpriv)
@@ -1004,15 +1029,15 @@ static void mv_clear_and_enable_port_irqs(struct ata_port *ap,
u32 hc_irq_cause;
/* clear EDMA event indicators, if any */
- writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+ writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE);
/* clear pending irq events */
hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
- writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+ writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE);
/* clear FIS IRQ Cause */
if (IS_GEN_IIE(hpriv))
- writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
+ writelfl(0, port_mmio + FIS_IRQ_CAUSE);
mv_enable_port_irqs(ap, port_irqs);
}
@@ -1048,10 +1073,10 @@ static void mv_set_irq_coalescing(struct ata_host *host,
* GEN_II/GEN_IIE with dual host controllers:
* one set of global thresholds for the entire chip.
*/
- writel(clks, mmio + MV_IRQ_COAL_TIME_THRESHOLD);
- writel(count, mmio + MV_IRQ_COAL_IO_THRESHOLD);
+ writel(clks, mmio + IRQ_COAL_TIME_THRESHOLD);
+ writel(count, mmio + IRQ_COAL_IO_THRESHOLD);
/* clear leftover coal IRQ bit */
- writel(~ALL_PORTS_COAL_IRQ, mmio + MV_IRQ_COAL_CAUSE);
+ writel(~ALL_PORTS_COAL_IRQ, mmio + IRQ_COAL_CAUSE);
if (count)
coal_enable = ALL_PORTS_COAL_DONE;
clks = count = 0; /* force clearing of regular regs below */
@@ -1061,16 +1086,16 @@ static void mv_set_irq_coalescing(struct ata_host *host,
* All chips: independent thresholds for each HC on the chip.
*/
hc_mmio = mv_hc_base_from_port(mmio, 0);
- writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS);
- writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS);
- writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE_OFS);
+ writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD);
+ writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD);
+ writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE);
if (count)
coal_enable |= PORTS_0_3_COAL_DONE;
if (is_dual_hc) {
hc_mmio = mv_hc_base_from_port(mmio, MV_PORTS_PER_HC);
- writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS);
- writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS);
- writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE_OFS);
+ writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD);
+ writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD);
+ writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE);
if (count)
coal_enable |= PORTS_4_7_COAL_DONE;
}
@@ -1108,7 +1133,7 @@ static void mv_start_edma(struct ata_port *ap, void __iomem *port_mmio,
mv_set_edma_ptrs(port_mmio, hpriv, pp);
mv_clear_and_enable_port_irqs(ap, port_mmio, DONE_IRQ|ERR_IRQ);
- writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS);
+ writelfl(EDMA_EN, port_mmio + EDMA_CMD);
pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
}
}
@@ -1128,7 +1153,7 @@ static void mv_wait_for_edma_empty_idle(struct ata_port *ap)
* as a rough guess at what even more drives might require.
*/
for (i = 0; i < timeout; ++i) {
- u32 edma_stat = readl(port_mmio + EDMA_STATUS_OFS);
+ u32 edma_stat = readl(port_mmio + EDMA_STATUS);
if ((edma_stat & empty_idle) == empty_idle)
break;
udelay(per_loop);
@@ -1148,11 +1173,11 @@ static int mv_stop_edma_engine(void __iomem *port_mmio)
int i;
/* Disable eDMA. The disable bit auto clears. */
- writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
+ writelfl(EDMA_DS, port_mmio + EDMA_CMD);
/* Wait for the chip to confirm eDMA is off. */
for (i = 10000; i > 0; i--) {
- u32 reg = readl(port_mmio + EDMA_CMD_OFS);
+ u32 reg = readl(port_mmio + EDMA_CMD);
if (!(reg & EDMA_EN))
return 0;
udelay(10);
@@ -1262,10 +1287,10 @@ static unsigned int mv_scr_offset(unsigned int sc_reg_in)
case SCR_STATUS:
case SCR_CONTROL:
case SCR_ERROR:
- ofs = SATA_STATUS_OFS + (sc_reg_in * sizeof(u32));
+ ofs = SATA_STATUS + (sc_reg_in * sizeof(u32));
break;
case SCR_ACTIVE:
- ofs = SATA_ACTIVE_OFS; /* active is not with the others */
+ ofs = SATA_ACTIVE; /* active is not with the others */
break;
default:
ofs = 0xffffffffU;
@@ -1290,7 +1315,25 @@ static int mv_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val)
unsigned int ofs = mv_scr_offset(sc_reg_in);
if (ofs != 0xffffffffU) {
- writelfl(val, mv_ap_base(link->ap) + ofs);
+ void __iomem *addr = mv_ap_base(link->ap) + ofs;
+ if (sc_reg_in == SCR_CONTROL) {
+ /*
+ * Workaround for 88SX60x1 FEr SATA#26:
+ *
+ * COMRESETs have to take care not to accidently
+ * put the drive to sleep when writing SCR_CONTROL.
+ * Setting bits 12..15 prevents this problem.
+ *
+ * So if we see an outbound COMMRESET, set those bits.
+ * Ditto for the followup write that clears the reset.
+ *
+ * The proprietary driver does this for
+ * all chip versions, and so do we.
+ */
+ if ((val & 0xf) == 1 || (readl(addr) & 0xf) == 1)
+ val |= 0xf000;
+ }
+ writelfl(val, addr);
return 0;
} else
return -EINVAL;
@@ -1368,9 +1411,9 @@ static void mv_config_fbs(struct ata_port *ap, int want_ncq, int want_fbs)
}
port_mmio = mv_ap_base(ap);
- mv_write_cached_reg(port_mmio + FISCFG_OFS, old_fiscfg, fiscfg);
- mv_write_cached_reg(port_mmio + LTMODE_OFS, old_ltmode, ltmode);
- mv_write_cached_reg(port_mmio + EDMA_HALTCOND_OFS, old_haltcond, haltcond);
+ mv_write_cached_reg(port_mmio + FISCFG, old_fiscfg, fiscfg);
+ mv_write_cached_reg(port_mmio + LTMODE, old_ltmode, ltmode);
+ mv_write_cached_reg(port_mmio + EDMA_HALTCOND, old_haltcond, haltcond);
}
static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq)
@@ -1379,13 +1422,13 @@ static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq)
u32 old, new;
/* workaround for 88SX60x1 FEr SATA#25 (part 1) */
- old = readl(hpriv->base + MV_GPIO_PORT_CTL_OFS);
+ old = readl(hpriv->base + GPIO_PORT_CTL);
if (want_ncq)
new = old | (1 << 22);
else
new = old & ~(1 << 22);
if (new != old)
- writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS);
+ writel(new, hpriv->base + GPIO_PORT_CTL);
}
/**
@@ -1409,7 +1452,7 @@ static void mv_bmdma_enable_iie(struct ata_port *ap, int enable_bmdma)
new = *old | 1;
else
new = *old & ~1;
- mv_write_cached_reg(mv_ap_base(ap) + EDMA_UNKNOWN_RSVD_OFS, old, new);
+ mv_write_cached_reg(mv_ap_base(ap) + EDMA_UNKNOWN_RSVD, old, new);
}
/*
@@ -1437,8 +1480,8 @@ static void mv_soc_led_blink_enable(struct ata_port *ap)
return;
hpriv->hp_flags |= MV_HP_QUIRK_LED_BLINK_EN;
hc_mmio = mv_hc_base_from_port(mv_host_base(host), ap->port_no);
- led_ctrl = readl(hc_mmio + SOC_LED_CTRL_OFS);
- writel(led_ctrl | SOC_LED_CTRL_BLINK, hc_mmio + SOC_LED_CTRL_OFS);
+ led_ctrl = readl(hc_mmio + SOC_LED_CTRL);
+ writel(led_ctrl | SOC_LED_CTRL_BLINK, hc_mmio + SOC_LED_CTRL);
}
static void mv_soc_led_blink_disable(struct ata_port *ap)
@@ -1463,8 +1506,8 @@ static void mv_soc_led_blink_disable(struct ata_port *ap)
hpriv->hp_flags &= ~MV_HP_QUIRK_LED_BLINK_EN;
hc_mmio = mv_hc_base_from_port(mv_host_base(host), ap->port_no);
- led_ctrl = readl(hc_mmio + SOC_LED_CTRL_OFS);
- writel(led_ctrl & ~SOC_LED_CTRL_BLINK, hc_mmio + SOC_LED_CTRL_OFS);
+ led_ctrl = readl(hc_mmio + SOC_LED_CTRL);
+ writel(led_ctrl & ~SOC_LED_CTRL_BLINK, hc_mmio + SOC_LED_CTRL);
}
static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma)
@@ -1528,7 +1571,7 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma)
pp->pp_flags |= MV_PP_FLAG_NCQ_EN;
}
- writelfl(cfg, port_mmio + EDMA_CFG_OFS);
+ writelfl(cfg, port_mmio + EDMA_CFG);
}
static void mv_port_free_dma_mem(struct ata_port *ap)
@@ -1575,6 +1618,7 @@ static int mv_port_start(struct ata_port *ap)
struct device *dev = ap->host->dev;
struct mv_host_priv *hpriv = ap->host->private_data;
struct mv_port_priv *pp;
+ unsigned long flags;
int tag;
pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
@@ -1610,8 +1654,12 @@ static int mv_port_start(struct ata_port *ap)
pp->sg_tbl_dma[tag] = pp->sg_tbl_dma[0];
}
}
+
+ spin_lock_irqsave(ap->lock, flags);
mv_save_cached_regs(ap);
mv_edma_cfg(ap, 0, 0);
+ spin_unlock_irqrestore(ap->lock, flags);
+
return 0;
out_port_free_dma_mem:
@@ -1630,8 +1678,12 @@ out_port_free_dma_mem:
*/
static void mv_port_stop(struct ata_port *ap)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(ap->lock, flags);
mv_stop_edma(ap);
mv_enable_port_irqs(ap, 0);
+ spin_unlock_irqrestore(ap->lock, flags);
mv_port_free_dma_mem(ap);
}
@@ -1749,13 +1801,13 @@ static void mv_bmdma_setup(struct ata_queued_cmd *qc)
mv_fill_sg(qc);
/* clear all DMA cmd bits */
- writel(0, port_mmio + BMDMA_CMD_OFS);
+ writel(0, port_mmio + BMDMA_CMD);
/* load PRD table addr. */
writel((pp->sg_tbl_dma[qc->tag] >> 16) >> 16,
- port_mmio + BMDMA_PRD_HIGH_OFS);
+ port_mmio + BMDMA_PRD_HIGH);
writelfl(pp->sg_tbl_dma[qc->tag],
- port_mmio + BMDMA_PRD_LOW_OFS);
+ port_mmio + BMDMA_PRD_LOW);
/* issue r/w command */
ap->ops->sff_exec_command(ap, &qc->tf);
@@ -1776,7 +1828,7 @@ static void mv_bmdma_start(struct ata_queued_cmd *qc)
u32 cmd = (rw ? 0 : ATA_DMA_WR) | ATA_DMA_START;
/* start host DMA transaction */
- writelfl(cmd, port_mmio + BMDMA_CMD_OFS);
+ writelfl(cmd, port_mmio + BMDMA_CMD);
}
/**
@@ -1795,9 +1847,9 @@ static void mv_bmdma_stop(struct ata_queued_cmd *qc)
u32 cmd;
/* clear start/stop bit */
- cmd = readl(port_mmio + BMDMA_CMD_OFS);
+ cmd = readl(port_mmio + BMDMA_CMD);
cmd &= ~ATA_DMA_START;
- writelfl(cmd, port_mmio + BMDMA_CMD_OFS);
+ writelfl(cmd, port_mmio + BMDMA_CMD);
/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
ata_sff_dma_pause(ap);
@@ -1821,7 +1873,7 @@ static u8 mv_bmdma_status(struct ata_port *ap)
* Other bits are valid only if ATA_DMA_ACTIVE==0,
* and the ATA_DMA_INTR bit doesn't exist.
*/
- reg = readl(port_mmio + BMDMA_STATUS_OFS);
+ reg = readl(port_mmio + BMDMA_STATUS);
if (reg & ATA_DMA_ACTIVE)
status = ATA_DMA_ACTIVE;
else
@@ -2029,28 +2081,28 @@ static unsigned int mv_send_fis(struct ata_port *ap, u32 *fis, int nwords)
int i, timeout = 200, final_word = nwords - 1;
/* Initiate FIS transmission mode */
- old_ifctl = readl(port_mmio + SATA_IFCTL_OFS);
+ old_ifctl = readl(port_mmio + SATA_IFCTL);
ifctl = 0x100 | (old_ifctl & 0xf);
- writelfl(ifctl, port_mmio + SATA_IFCTL_OFS);
+ writelfl(ifctl, port_mmio + SATA_IFCTL);
/* Send all words of the FIS except for the final word */
for (i = 0; i < final_word; ++i)
- writel(fis[i], port_mmio + VENDOR_UNIQUE_FIS_OFS);
+ writel(fis[i], port_mmio + VENDOR_UNIQUE_FIS);
/* Flag end-of-transmission, and then send the final word */
- writelfl(ifctl | 0x200, port_mmio + SATA_IFCTL_OFS);
- writelfl(fis[final_word], port_mmio + VENDOR_UNIQUE_FIS_OFS);
+ writelfl(ifctl | 0x200, port_mmio + SATA_IFCTL);
+ writelfl(fis[final_word], port_mmio + VENDOR_UNIQUE_FIS);
/*
* Wait for FIS transmission to complete.
* This typically takes just a single iteration.
*/
do {
- ifstat = readl(port_mmio + SATA_IFSTAT_OFS);
+ ifstat = readl(port_mmio + SATA_IFSTAT);
} while (!(ifstat & 0x1000) && --timeout);
/* Restore original port configuration */
- writelfl(old_ifctl, port_mmio + SATA_IFCTL_OFS);
+ writelfl(old_ifctl, port_mmio + SATA_IFCTL);
/* See if it worked */
if ((ifstat & 0x3000) != 0x1000) {
@@ -2148,7 +2200,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
/* Write the request in pointer to kick the EDMA to life */
writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index,
- port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+ port_mmio + EDMA_REQ_Q_IN_PTR);
return 0;
case ATA_PROT_PIO:
@@ -2259,7 +2311,7 @@ static unsigned int mv_get_err_pmp_map(struct ata_port *ap)
{
void __iomem *port_mmio = mv_ap_base(ap);
- return readl(port_mmio + SATA_TESTCTL_OFS) >> 16;
+ return readl(port_mmio + SATA_TESTCTL) >> 16;
}
static void mv_pmp_eh_prep(struct ata_port *ap, unsigned int pmp_map)
@@ -2292,9 +2344,9 @@ static int mv_req_q_empty(struct ata_port *ap)
void __iomem *port_mmio = mv_ap_base(ap);
u32 in_ptr, out_ptr;
- in_ptr = (readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS)
+ in_ptr = (readl(port_mmio + EDMA_REQ_Q_IN_PTR)
>> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
- out_ptr = (readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS)
+ out_ptr = (readl(port_mmio + EDMA_REQ_Q_OUT_PTR)
>> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
return (in_ptr == out_ptr); /* 1 == queue_is_empty */
}
@@ -2456,12 +2508,12 @@ static void mv_err_intr(struct ata_port *ap)
sata_scr_read(&ap->link, SCR_ERROR, &serr);
sata_scr_write_flush(&ap->link, SCR_ERROR, serr);
- edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+ edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE);
if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) {
- fis_cause = readl(port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
- writelfl(~fis_cause, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
+ fis_cause = readl(port_mmio + FIS_IRQ_CAUSE);
+ writelfl(~fis_cause, port_mmio + FIS_IRQ_CAUSE);
}
- writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+ writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE);
if (edma_err_cause & EDMA_ERR_DEV) {
/*
@@ -2479,7 +2531,7 @@ static void mv_err_intr(struct ata_port *ap)
if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) {
ata_ehi_push_desc(ehi, "fis_cause=%08x", fis_cause);
- if (fis_cause & SATA_FIS_IRQ_AN) {
+ if (fis_cause & FIS_IRQ_CAUSE_AN) {
u32 ec = edma_err_cause &
~(EDMA_ERR_TRANS_IRQ_7 | EDMA_ERR_IRQ_TRANSIENT);
sata_async_notification(ap);
@@ -2581,7 +2633,7 @@ static void mv_process_crpb_response(struct ata_port *ap,
u16 edma_status = le16_to_cpu(response->flags);
/*
* edma_status from a response queue entry:
- * LSB is from EDMA_ERR_IRQ_CAUSE_OFS (non-NCQ only).
+ * LSB is from EDMA_ERR_IRQ_CAUSE (non-NCQ only).
* MSB is saved ATA status from command completion.
*/
if (!ncq_enabled) {
@@ -2613,7 +2665,7 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp
int ncq_enabled = (pp->pp_flags & MV_PP_FLAG_NCQ_EN);
/* Get the hardware queue position index */
- in_index = (readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS)
+ in_index = (readl(port_mmio + EDMA_RSP_Q_IN_PTR)
>> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
/* Process new responses from since the last time we looked */
@@ -2638,7 +2690,7 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp
if (work_done)
writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) |
(pp->resp_idx << EDMA_RSP_Q_PTR_SHIFT),
- port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+ port_mmio + EDMA_RSP_Q_OUT_PTR);
}
static void mv_port_intr(struct ata_port *ap, u32 port_cause)
@@ -2695,7 +2747,7 @@ static int mv_host_intr(struct ata_host *host, u32 main_irq_cause)
/* If asserted, clear the "all ports" IRQ coalescing bit */
if (main_irq_cause & ALL_PORTS_COAL_DONE)
- writel(~ALL_PORTS_COAL_IRQ, mmio + MV_IRQ_COAL_CAUSE);
+ writel(~ALL_PORTS_COAL_IRQ, mmio + IRQ_COAL_CAUSE);
for (port = 0; port < hpriv->n_ports; port++) {
struct ata_port *ap = host->ports[port];
@@ -2739,7 +2791,7 @@ static int mv_host_intr(struct ata_host *host, u32 main_irq_cause)
ack_irqs |= (DMA_IRQ | DEV_IRQ) << p;
}
hc_mmio = mv_hc_base_from_port(mmio, port);
- writelfl(~ack_irqs, hc_mmio + HC_IRQ_CAUSE_OFS);
+ writelfl(~ack_irqs, hc_mmio + HC_IRQ_CAUSE);
handled = 1;
}
/*
@@ -2761,7 +2813,7 @@ static int mv_pci_error(struct ata_host *host, void __iomem *mmio)
unsigned int i, err_mask, printed = 0;
u32 err_cause;
- err_cause = readl(mmio + hpriv->irq_cause_ofs);
+ err_cause = readl(mmio + hpriv->irq_cause_offset);
dev_printk(KERN_ERR, host->dev, "PCI ERROR; PCI IRQ cause=0x%08x\n",
err_cause);
@@ -2769,7 +2821,7 @@ static int mv_pci_error(struct ata_host *host, void __iomem *mmio)
DPRINTK("All regs @ PCI error\n");
mv_dump_all_regs(mmio, -1, to_pci_dev(host->dev));
- writelfl(0, mmio + hpriv->irq_cause_ofs);
+ writelfl(0, mmio + hpriv->irq_cause_offset);
for (i = 0; i < host->n_ports; i++) {
ap = host->ports[i];
@@ -2906,7 +2958,7 @@ static void mv5_reset_bus(struct ata_host *host, void __iomem *mmio)
static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio)
{
- writel(0x0fcfffff, mmio + MV_FLASH_CTL_OFS);
+ writel(0x0fcfffff, mmio + FLASH_CTL);
}
static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx,
@@ -2925,7 +2977,7 @@ static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio)
{
u32 tmp;
- writel(0, mmio + MV_GPIO_PORT_CTL_OFS);
+ writel(0, mmio + GPIO_PORT_CTL);
/* FIXME: handle MV_HP_ERRATA_50XXB2 errata */
@@ -2943,14 +2995,14 @@ static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
int fix_apm_sq = (hpriv->hp_flags & MV_HP_ERRATA_50XXB0);
if (fix_apm_sq) {
- tmp = readl(phy_mmio + MV5_LTMODE_OFS);
+ tmp = readl(phy_mmio + MV5_LTMODE);
tmp |= (1 << 19);
- writel(tmp, phy_mmio + MV5_LTMODE_OFS);
+ writel(tmp, phy_mmio + MV5_LTMODE);
- tmp = readl(phy_mmio + MV5_PHY_CTL_OFS);
+ tmp = readl(phy_mmio + MV5_PHY_CTL);
tmp &= ~0x3;
tmp |= 0x1;
- writel(tmp, phy_mmio + MV5_PHY_CTL_OFS);
+ writel(tmp, phy_mmio + MV5_PHY_CTL);
}
tmp = readl(phy_mmio + MV5_PHY_MODE);
@@ -2971,7 +3023,7 @@ static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio,
mv_reset_channel(hpriv, mmio, port);
ZERO(0x028); /* command */
- writel(0x11f, port_mmio + EDMA_CFG_OFS);
+ writel(0x11f, port_mmio + EDMA_CFG);
ZERO(0x004); /* timer */
ZERO(0x008); /* irq err cause */
ZERO(0x00c); /* irq err mask */
@@ -2982,7 +3034,7 @@ static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio,
ZERO(0x024); /* respq outp */
ZERO(0x020); /* respq inp */
ZERO(0x02c); /* test control */
- writel(0xbc, port_mmio + EDMA_IORDY_TMOUT_OFS);
+ writel(0xbc, port_mmio + EDMA_IORDY_TMOUT);
}
#undef ZERO
@@ -3028,16 +3080,16 @@ static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio)
struct mv_host_priv *hpriv = host->private_data;
u32 tmp;
- tmp = readl(mmio + MV_PCI_MODE_OFS);
+ tmp = readl(mmio + MV_PCI_MODE);
tmp &= 0xff00ffff;
- writel(tmp, mmio + MV_PCI_MODE_OFS);
+ writel(tmp, mmio + MV_PCI_MODE);
ZERO(MV_PCI_DISC_TIMER);
ZERO(MV_PCI_MSI_TRIGGER);
- writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT_OFS);
+ writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT);
ZERO(MV_PCI_SERR_MASK);
- ZERO(hpriv->irq_cause_ofs);
- ZERO(hpriv->irq_mask_ofs);
+ ZERO(hpriv->irq_cause_offset);
+ ZERO(hpriv->irq_mask_offset);
ZERO(MV_PCI_ERR_LOW_ADDRESS);
ZERO(MV_PCI_ERR_HIGH_ADDRESS);
ZERO(MV_PCI_ERR_ATTRIBUTE);
@@ -3051,10 +3103,10 @@ static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio)
mv5_reset_flash(hpriv, mmio);
- tmp = readl(mmio + MV_GPIO_PORT_CTL_OFS);
+ tmp = readl(mmio + GPIO_PORT_CTL);
tmp &= 0x3;
tmp |= (1 << 5) | (1 << 6);
- writel(tmp, mmio + MV_GPIO_PORT_CTL_OFS);
+ writel(tmp, mmio + GPIO_PORT_CTL);
}
/**
@@ -3069,7 +3121,7 @@ static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio)
static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int n_hc)
{
- void __iomem *reg = mmio + PCI_MAIN_CMD_STS_OFS;
+ void __iomem *reg = mmio + PCI_MAIN_CMD_STS;
int i, rc = 0;
u32 t;
@@ -3127,7 +3179,7 @@ static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx,
void __iomem *port_mmio;
u32 tmp;
- tmp = readl(mmio + MV_RESET_CFG_OFS);
+ tmp = readl(mmio + RESET_CFG);
if ((tmp & (1 << 0)) == 0) {
hpriv->signal[idx].amps = 0x7 << 8;
hpriv->signal[idx].pre = 0x1 << 5;
@@ -3143,7 +3195,7 @@ static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx,
static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio)
{
- writel(0x00000060, mmio + MV_GPIO_PORT_CTL_OFS);
+ writel(0x00000060, mmio + GPIO_PORT_CTL);
}
static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -3201,6 +3253,7 @@ static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
* Workaround for 60x1-B2 errata SATA#13:
* Any write to PHY_MODE4 (above) may corrupt PHY_MODE3,
* so we must always rewrite PHY_MODE3 after PHY_MODE4.
+ * Or ensure we use writelfl() when writing PHY_MODE4.
*/
writel(m3, port_mmio + PHY_MODE3);
@@ -3252,7 +3305,7 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv,
mv_reset_channel(hpriv, mmio, port);
ZERO(0x028); /* command */
- writel(0x101f, port_mmio + EDMA_CFG_OFS);
+ writel(0x101f, port_mmio + EDMA_CFG);
ZERO(0x004); /* timer */
ZERO(0x008); /* irq err cause */
ZERO(0x00c); /* irq err mask */
@@ -3263,7 +3316,7 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv,
ZERO(0x024); /* respq outp */
ZERO(0x020); /* respq inp */
ZERO(0x02c); /* test control */
- writel(0xbc, port_mmio + EDMA_IORDY_TMOUT_OFS);
+ writel(0xbc, port_mmio + EDMA_IORDY_TMOUT);
}
#undef ZERO
@@ -3308,12 +3361,12 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
{
- u32 ifcfg = readl(port_mmio + SATA_INTERFACE_CFG_OFS);
+ u32 ifcfg = readl(port_mmio + SATA_IFCFG);
ifcfg = (ifcfg & 0xf7f) | 0x9b1000; /* from chip spec */
if (want_gen2i)
ifcfg |= (1 << 7); /* enable gen2i speed */
- writelfl(ifcfg, port_mmio + SATA_INTERFACE_CFG_OFS);
+ writelfl(ifcfg, port_mmio + SATA_IFCFG);
}
static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -3327,7 +3380,7 @@ static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
* to disable the EDMA engine before doing the EDMA_RESET operation.
*/
mv_stop_edma_engine(port_mmio);
- writelfl(EDMA_RESET, port_mmio + EDMA_CMD_OFS);
+ writelfl(EDMA_RESET, port_mmio + EDMA_CMD);
if (!IS_GEN_I(hpriv)) {
/* Enable 3.0gb/s link speed: this survives EDMA_RESET */
@@ -3336,11 +3389,11 @@ static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
/*
* Strobing EDMA_RESET here causes a hard reset of the SATA transport,
* link, and physical layers. It resets all SATA interface registers
- * (except for SATA_INTERFACE_CFG), and issues a COMRESET to the dev.
+ * (except for SATA_IFCFG), and issues a COMRESET to the dev.
*/
- writelfl(EDMA_RESET, port_mmio + EDMA_CMD_OFS);
+ writelfl(EDMA_RESET, port_mmio + EDMA_CMD);
udelay(25); /* allow reset propagation */
- writelfl(0, port_mmio + EDMA_CMD_OFS);
+ writelfl(0, port_mmio + EDMA_CMD);
hpriv->ops->phy_errata(hpriv, mmio, port_no);
@@ -3352,12 +3405,12 @@ static void mv_pmp_select(struct ata_port *ap, int pmp)
{
if (sata_pmp_supported(ap)) {
void __iomem *port_mmio = mv_ap_base(ap);
- u32 reg = readl(port_mmio + SATA_IFCTL_OFS);
+ u32 reg = readl(port_mmio + SATA_IFCTL);
int old = reg & 0xf;
if (old != pmp) {
reg = (reg & ~0xf) | pmp;
- writelfl(reg, port_mmio + SATA_IFCTL_OFS);
+ writelfl(reg, port_mmio + SATA_IFCTL);
}
}
}
@@ -3432,11 +3485,11 @@ static void mv_eh_thaw(struct ata_port *ap)
u32 hc_irq_cause;
/* clear EDMA errors on this port */
- writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+ writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE);
/* clear pending irq events */
hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
- writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+ writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE);
mv_enable_port_irqs(ap, ERR_IRQ);
}
@@ -3455,8 +3508,7 @@ static void mv_eh_thaw(struct ata_port *ap)
*/
static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
{
- void __iomem *shd_base = port_mmio + SHD_BLK_OFS;
- unsigned serr_ofs;
+ void __iomem *serr, *shd_base = port_mmio + SHD_BLK;
/* PIO related setup
*/
@@ -3471,23 +3523,23 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
port->status_addr =
port->command_addr = shd_base + (sizeof(u32) * ATA_REG_STATUS);
/* special case: control/altstatus doesn't have ATA_REG_ address */
- port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST_OFS;
+ port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST;
/* unused: */
port->cmd_addr = port->bmdma_addr = port->scr_addr = NULL;
/* Clear any currently outstanding port interrupt conditions */
- serr_ofs = mv_scr_offset(SCR_ERROR);
- writelfl(readl(port_mmio + serr_ofs), port_mmio + serr_ofs);
- writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+ serr = port_mmio + mv_scr_offset(SCR_ERROR);
+ writelfl(readl(serr), serr);
+ writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE);
/* unmask all non-transient EDMA error interrupts */
- writelfl(~EDMA_ERR_IRQ_TRANSIENT, port_mmio + EDMA_ERR_IRQ_MASK_OFS);
+ writelfl(~EDMA_ERR_IRQ_TRANSIENT, port_mmio + EDMA_ERR_IRQ_MASK);
VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n",
- readl(port_mmio + EDMA_CFG_OFS),
- readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS),
- readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS));
+ readl(port_mmio + EDMA_CFG),
+ readl(port_mmio + EDMA_ERR_IRQ_CAUSE),
+ readl(port_mmio + EDMA_ERR_IRQ_MASK));
}
static unsigned int mv_in_pcix_mode(struct ata_host *host)
@@ -3498,7 +3550,7 @@ static unsigned int mv_in_pcix_mode(struct ata_host *host)
if (IS_SOC(hpriv) || !IS_PCIE(hpriv))
return 0; /* not PCI-X capable */
- reg = readl(mmio + MV_PCI_MODE_OFS);
+ reg = readl(mmio + MV_PCI_MODE);
if ((reg & MV_PCI_MODE_MASK) == 0)
return 0; /* conventional PCI mode */
return 1; /* chip is in PCI-X mode */
@@ -3511,13 +3563,25 @@ static int mv_pci_cut_through_okay(struct ata_host *host)
u32 reg;
if (!mv_in_pcix_mode(host)) {
- reg = readl(mmio + PCI_COMMAND_OFS);
- if (reg & PCI_COMMAND_MRDTRIG)
+ reg = readl(mmio + MV_PCI_COMMAND);
+ if (reg & MV_PCI_COMMAND_MRDTRIG)
return 0; /* not okay */
}
return 1; /* okay */
}
+static void mv_60x1b2_errata_pci7(struct ata_host *host)
+{
+ struct mv_host_priv *hpriv = host->private_data;
+ void __iomem *mmio = hpriv->base;
+
+ /* workaround for 60x1-B2 errata PCI#7 */
+ if (mv_in_pcix_mode(host)) {
+ u32 reg = readl(mmio + MV_PCI_COMMAND);
+ writelfl(reg & ~MV_PCI_COMMAND_MWRCOM, mmio + MV_PCI_COMMAND);
+ }
+}
+
static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
{
struct pci_dev *pdev = to_pci_dev(host->dev);
@@ -3571,6 +3635,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
switch (pdev->revision) {
case 0x7:
+ mv_60x1b2_errata_pci7(host);
hp_flags |= MV_HP_ERRATA_60X1B2;
break;
case 0x9:
@@ -3647,12 +3712,12 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
hpriv->hp_flags = hp_flags;
if (hp_flags & MV_HP_PCIE) {
- hpriv->irq_cause_ofs = PCIE_IRQ_CAUSE_OFS;
- hpriv->irq_mask_ofs = PCIE_IRQ_MASK_OFS;
+ hpriv->irq_cause_offset = PCIE_IRQ_CAUSE;
+ hpriv->irq_mask_offset = PCIE_IRQ_MASK;
hpriv->unmask_all_irqs = PCIE_UNMASK_ALL_IRQS;
} else {
- hpriv->irq_cause_ofs = PCI_IRQ_CAUSE_OFS;
- hpriv->irq_mask_ofs = PCI_IRQ_MASK_OFS;
+ hpriv->irq_cause_offset = PCI_IRQ_CAUSE;
+ hpriv->irq_mask_offset = PCI_IRQ_MASK;
hpriv->unmask_all_irqs = PCI_UNMASK_ALL_IRQS;
}
@@ -3681,11 +3746,11 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
goto done;
if (IS_SOC(hpriv)) {
- hpriv->main_irq_cause_addr = mmio + SOC_HC_MAIN_IRQ_CAUSE_OFS;
- hpriv->main_irq_mask_addr = mmio + SOC_HC_MAIN_IRQ_MASK_OFS;
+ hpriv->main_irq_cause_addr = mmio + SOC_HC_MAIN_IRQ_CAUSE;
+ hpriv->main_irq_mask_addr = mmio + SOC_HC_MAIN_IRQ_MASK;
} else {
- hpriv->main_irq_cause_addr = mmio + PCI_HC_MAIN_IRQ_CAUSE_OFS;
- hpriv->main_irq_mask_addr = mmio + PCI_HC_MAIN_IRQ_MASK_OFS;
+ hpriv->main_irq_cause_addr = mmio + PCI_HC_MAIN_IRQ_CAUSE;
+ hpriv->main_irq_mask_addr = mmio + PCI_HC_MAIN_IRQ_MASK;
}
/* initialize shadow irq mask with register's value */
@@ -3727,18 +3792,20 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
VPRINTK("HC%i: HC config=0x%08x HC IRQ cause "
"(before clear)=0x%08x\n", hc,
- readl(hc_mmio + HC_CFG_OFS),
- readl(hc_mmio + HC_IRQ_CAUSE_OFS));
+ readl(hc_mmio + HC_CFG),
+ readl(hc_mmio + HC_IRQ_CAUSE));
/* Clear any currently outstanding hc interrupt conditions */
- writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS);
+ writelfl(0, hc_mmio + HC_IRQ_CAUSE);
}
- /* Clear any currently outstanding host interrupt conditions */
- writelfl(0, mmio + hpriv->irq_cause_ofs);
+ if (!IS_SOC(hpriv)) {
+ /* Clear any currently outstanding host interrupt conditions */
+ writelfl(0, mmio + hpriv->irq_cause_offset);
- /* and unmask interrupt generation for host regs */
- writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs);
+ /* and unmask interrupt generation for host regs */
+ writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_offset);
+ }
/*
* enable only global host interrupts for now.
@@ -3844,7 +3911,7 @@ static int mv_platform_probe(struct platform_device *pdev)
host->iomap = NULL;
hpriv->base = devm_ioremap(&pdev->dev, res->start,
res->end - res->start + 1);
- hpriv->base -= MV_SATAHC0_REG_BASE;
+ hpriv->base -= SATAHC0_REG_BASE;
/*
* (Re-)program MBUS remapping windows if we are asked to.
@@ -3913,10 +3980,10 @@ static int pci_go_64(struct pci_dev *pdev)
{
int rc;
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
- rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (rc) {
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"64-bit DMA enable failed\n");
@@ -3924,13 +3991,13 @@ static int pci_go_64(struct pci_dev *pdev)
}
}
} else {
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit DMA enable failed\n");
return rc;
}
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit consistent DMA enable failed\n");
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index c3936d35cda..326c0cfc29b 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -584,10 +584,10 @@ static int qs_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
int rc, have_64bit_bus = (bus_info & QS_HPHY_64BIT);
if (have_64bit_bus &&
- !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
- rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (rc) {
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"64-bit DMA enable failed\n");
@@ -595,13 +595,13 @@ static int qs_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
}
}
} else {
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit DMA enable failed\n");
return rc;
}
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit consistent DMA enable failed\n");
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 0d8990dcdfc..77aa8d7ecec 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -1297,10 +1297,10 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
host->iomap = iomap;
/* configure and activate the device */
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
- rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (rc) {
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"64-bit DMA enable failed\n");
@@ -1308,13 +1308,13 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
}
} else {
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit DMA enable failed\n");
return rc;
}
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit consistent DMA enable failed\n");
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 98e8c50703b..bdd43c7f432 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -566,7 +566,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
static int printed_version;
unsigned int i;
int rc;
- struct ata_host *host;
+ struct ata_host *host = NULL;
int board_id = (int) ent->driver_data;
const unsigned *bar_sizes;
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index ed70bd28fa2..8b2a278b254 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -399,10 +399,10 @@ static int __devinit vsc_sata_init_one(struct pci_dev *pdev,
/*
* Use 32 bit DMA mask, because 64 bit address support is poor.
*/
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc)
return rc;
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc)
return rc;
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index bdbad7edf68..2de64065aa1 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -358,7 +358,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
if (pci_enable_device(pci_dev))
return -EIO;
- if (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK) != 0) {
+ if (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32)) != 0) {
printk(KERN_WARNING "he: no suitable dma available\n");
err = -EIO;
goto init_one_failure;
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index 8733a2ea04c..cf97c34cbaf 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -1957,12 +1957,12 @@ static int __devinit lanai_pci_start(struct lanai_dev *lanai)
return -ENXIO;
}
pci_set_master(pci);
- if (pci_set_dma_mask(pci, DMA_32BIT_MASK) != 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) != 0) {
printk(KERN_WARNING DEV_LABEL
"(itf %d): No suitable DMA available.\n", lanai->number);
return -EBUSY;
}
- if (pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) != 0) {
+ if (pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) != 0) {
printk(KERN_WARNING DEV_LABEL
"(itf %d): No suitable DMA available.\n", lanai->number);
return -EBUSY;
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index be204308cc1..9359613addc 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -1059,7 +1059,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
goto out;
}
- err = pci_set_dma_mask(dev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(dev, DMA_BIT_MASK(32));
if (err) {
dev_warn(&dev->dev, "Failed to set 32-bit DMA mask\n");
goto out;
diff --git a/drivers/base/iommu.c b/drivers/base/iommu.c
index c2d1eed9037..9f0e672f4be 100644
--- a/drivers/base/iommu.c
+++ b/drivers/base/iommu.c
@@ -98,3 +98,10 @@ phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
return iommu_ops->iova_to_phys(domain, iova);
}
EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
+
+int iommu_domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap)
+{
+ return iommu_ops->domain_has_cap(domain, cap);
+}
+EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
diff --git a/drivers/base/isa.c b/drivers/base/isa.c
index 479694b6cbe..91dba65d726 100644
--- a/drivers/base/isa.c
+++ b/drivers/base/isa.c
@@ -141,7 +141,7 @@ int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev)
isa_dev->dev.release = isa_dev_release;
isa_dev->id = id;
- isa_dev->dev.coherent_dma_mask = DMA_24BIT_MASK;
+ isa_dev->dev.coherent_dma_mask = DMA_BIT_MASK(24);
isa_dev->dev.dma_mask = &isa_dev->dev.coherent_dma_mask;
error = device_register(&isa_dev->dev);
diff --git a/drivers/base/node.c b/drivers/base/node.c
index f8f578a71b2..40b809742a1 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -24,7 +24,7 @@ static struct sysdev_class node_class = {
static ssize_t node_read_cpumap(struct sys_device *dev, int type, char *buf)
{
struct node *node_dev = to_node(dev);
- node_to_cpumask_ptr(mask, node_dev->sysdev.id);
+ const struct cpumask *mask = cpumask_of_node(node_dev->sysdev.id);
int len;
/* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 76ce75bad91..3236b434b96 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -300,7 +300,7 @@ void sysdev_unregister(struct sys_device *sysdev)
* and the class driver.
*
* Note: The list is iterated in reverse order, so that we shut down
- * child devices before we shut down thier parents. The list ordering
+ * child devices before we shut down their parents. The list ordering
* is guaranteed by virtue of the fact that child devices are registered
* after their parents.
*/
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index f6a337c34ac..f22ed6cc69f 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -1169,9 +1169,9 @@ static bool DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
int i;
- if (pci_set_dma_mask(Controller->PCIDevice, DMA_32BIT_MASK))
+ if (pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32)))
return DAC960_Failure(Controller, "DMA mask out of range");
- Controller->BounceBufferLimit = DMA_32BIT_MASK;
+ Controller->BounceBufferLimit = DMA_BIT_MASK(32);
if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller)) {
CommandMailboxesSize = 0;
@@ -1372,10 +1372,10 @@ static bool DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
dma_addr_t CommandMailboxDMA;
DAC960_V2_CommandStatus_T CommandStatus;
- if (!pci_set_dma_mask(Controller->PCIDevice, DMA_64BIT_MASK))
- Controller->BounceBufferLimit = DMA_64BIT_MASK;
- else if (!pci_set_dma_mask(Controller->PCIDevice, DMA_32BIT_MASK))
- Controller->BounceBufferLimit = DMA_32BIT_MASK;
+ if (!pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(64)))
+ Controller->BounceBufferLimit = DMA_BIT_MASK(64);
+ else if (!pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32)))
+ Controller->BounceBufferLimit = DMA_BIT_MASK(32);
else
return DAC960_Failure(Controller, "DMA mask out of range");
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index e7b8aa0cb47..ddea8e485cc 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -410,6 +410,23 @@ config ATA_OVER_ETH
This driver provides Support for ATA over Ethernet block
devices like the Coraid EtherDrive (R) Storage Blade.
+config MG_DISK
+ tristate "mGine mflash, gflash support"
+ depends on ARM && ATA && GPIOLIB
+ help
+ mGine mFlash(gFlash) block device driver
+
+config MG_DISK_RES
+ int "Size of reserved area before MBR"
+ depends on MG_DISK
+ default 0
+ help
+ Define size of reserved area that usually used for boot. Unit is KB.
+ All of the block device operation will be taken this value as start
+ offset
+ Examples:
+ 1024 => 1 MB
+
config SUNVDC
tristate "Sun Virtual Disk Client support"
depends on SUN_LDOMS
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 3145141cef7..7755a5e2a85 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o
obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o
obj-$(CONFIG_XILINX_SYSACE) += xsysace.o
obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o
+obj-$(CONFIG_MG_DISK) += mg_disk.o
obj-$(CONFIG_SUNVDC) += sunvdc.o
obj-$(CONFIG_BLK_DEV_UMEM) += umem.o
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 45c5a33daf4..31693bc2444 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -4,6 +4,7 @@
* Filesystem request handling methods
*/
+#include <linux/ata.h>
#include <linux/hdreg.h>
#include <linux/blkdev.h>
#include <linux/skbuff.h>
@@ -267,7 +268,7 @@ aoecmd_ata_rw(struct aoedev *d)
writebit = 0;
}
- ah->cmdstat = WIN_READ | writebit | extbit;
+ ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit;
/* mark all tracking fields and load out */
buf->nframesout += 1;
@@ -362,10 +363,10 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
switch (ah->cmdstat) {
default:
break;
- case WIN_READ:
- case WIN_READ_EXT:
- case WIN_WRITE:
- case WIN_WRITE_EXT:
+ case ATA_CMD_PIO_READ:
+ case ATA_CMD_PIO_READ_EXT:
+ case ATA_CMD_PIO_WRITE:
+ case ATA_CMD_PIO_WRITE_EXT:
put_lba(ah, f->lba);
n = f->bcnt;
@@ -812,8 +813,8 @@ aoecmd_ata_rsp(struct sk_buff *skb)
d->htgt = NULL;
n = ahout->scnt << 9;
switch (ahout->cmdstat) {
- case WIN_READ:
- case WIN_READ_EXT:
+ case ATA_CMD_PIO_READ:
+ case ATA_CMD_PIO_READ_EXT:
if (skb->len - sizeof *hin - sizeof *ahin < n) {
printk(KERN_ERR
"aoe: %s. skb->len=%d need=%ld\n",
@@ -823,8 +824,8 @@ aoecmd_ata_rsp(struct sk_buff *skb)
return;
}
memcpy(f->bufaddr, ahin+1, n);
- case WIN_WRITE:
- case WIN_WRITE_EXT:
+ case ATA_CMD_PIO_WRITE:
+ case ATA_CMD_PIO_WRITE_EXT:
ifp = getif(t, skb->dev);
if (ifp) {
ifp->lost = 0;
@@ -838,7 +839,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
goto xmit;
}
break;
- case WIN_IDENTIFY:
+ case ATA_CMD_ID_ATA:
if (skb->len - sizeof *hin - sizeof *ahin < 512) {
printk(KERN_INFO
"aoe: runt data size in ataid. skb->len=%d\n",
@@ -914,7 +915,7 @@ aoecmd_ata_id(struct aoedev *d)
/* set up ata header */
ah->scnt = 1;
- ah->cmdstat = WIN_IDENTIFY;
+ ah->cmdstat = ATA_CMD_ID_ATA;
ah->lba3 = 0xa0;
skb->dev = t->ifp->nd;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 5d0e135824f..4d4d5e0d3fa 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -51,6 +51,7 @@
#include <scsi/scsi_ioctl.h>
#include <linux/cdrom.h>
#include <linux/scatterlist.h>
+#include <linux/kthread.h>
#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
#define DRIVER_NAME "HP CISS Driver (v 3.6.20)"
@@ -186,6 +187,8 @@ static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size,
__u8 page_code, int cmd_type);
static void fail_all_cmds(unsigned long ctlr);
+static int scan_thread(void *data);
+static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c);
#ifdef CONFIG_PROC_FS
static void cciss_procinit(int i);
@@ -735,6 +738,12 @@ static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo)
return 0;
}
+static void check_ioctl_unit_attention(ctlr_info_t *host, CommandList_struct *c)
+{
+ if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
+ c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION)
+ (void)check_for_unit_attention(host, c);
+}
/*
* ioctl
*/
@@ -1029,6 +1038,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
iocommand.buf_size,
PCI_DMA_BIDIRECTIONAL);
+ check_ioctl_unit_attention(host, c);
+
/* Copy the error information out */
iocommand.error_info = *(c->err_info);
if (copy_to_user
@@ -1180,6 +1191,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
(dma_addr_t) temp64.val, buff_size[i],
PCI_DMA_BIDIRECTIONAL);
}
+ check_ioctl_unit_attention(host, c);
/* Copy the error information out */
ioc->error_info = *(c->err_info);
if (copy_to_user(argp, ioc, sizeof(*ioc))) {
@@ -1287,6 +1299,7 @@ static void cciss_softirq_done(struct request *rq)
{
CommandList_struct *cmd = rq->completion_data;
ctlr_info_t *h = hba[cmd->ctlr];
+ unsigned int nr_bytes;
unsigned long flags;
u64bit temp64;
int i, ddir;
@@ -1308,7 +1321,14 @@ static void cciss_softirq_done(struct request *rq)
printk("Done with %p\n", rq);
#endif /* CCISS_DEBUG */
- if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, blk_rq_bytes(rq)))
+ /*
+ * Store the full size and set the residual count for pc requests
+ */
+ nr_bytes = blk_rq_bytes(rq);
+ if (blk_pc_request(rq))
+ rq->data_len = cmd->err_info->ResidualCnt;
+
+ if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, nr_bytes))
BUG();
spin_lock_irqsave(&h->lock, flags);
@@ -2585,12 +2605,14 @@ static inline unsigned int make_status_bytes(unsigned int scsi_status_byte,
((driver_byte & 0xff) << 24);
}
-static inline int evaluate_target_status(CommandList_struct *cmd)
+static inline int evaluate_target_status(ctlr_info_t *h,
+ CommandList_struct *cmd, int *retry_cmd)
{
unsigned char sense_key;
unsigned char status_byte, msg_byte, host_byte, driver_byte;
int error_value;
+ *retry_cmd = 0;
/* If we get in here, it means we got "target status", that is, scsi status */
status_byte = cmd->err_info->ScsiStatus;
driver_byte = DRIVER_OK;
@@ -2618,6 +2640,11 @@ static inline int evaluate_target_status(CommandList_struct *cmd)
if (((sense_key == 0x0) || (sense_key == 0x1)) && !blk_pc_request(cmd->rq))
error_value = 0;
+ if (check_for_unit_attention(h, cmd)) {
+ *retry_cmd = !blk_pc_request(cmd->rq);
+ return 0;
+ }
+
if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */
if (error_value != 0)
printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION"
@@ -2657,7 +2684,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
switch (cmd->err_info->CommandStatus) {
case CMD_TARGET_STATUS:
- rq->errors = evaluate_target_status(cmd);
+ rq->errors = evaluate_target_status(h, cmd, &retry_cmd);
break;
case CMD_DATA_UNDERRUN:
if (blk_fs_request(cmd->rq)) {
@@ -3008,6 +3035,63 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static int scan_thread(void *data)
+{
+ ctlr_info_t *h = data;
+ int rc;
+ DECLARE_COMPLETION_ONSTACK(wait);
+ h->rescan_wait = &wait;
+
+ for (;;) {
+ rc = wait_for_completion_interruptible(&wait);
+ if (kthread_should_stop())
+ break;
+ if (!rc)
+ rebuild_lun_table(h, 0);
+ }
+ return 0;
+}
+
+static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c)
+{
+ if (c->err_info->SenseInfo[2] != UNIT_ATTENTION)
+ return 0;
+
+ switch (c->err_info->SenseInfo[12]) {
+ case STATE_CHANGED:
+ printk(KERN_WARNING "cciss%d: a state change "
+ "detected, command retried\n", h->ctlr);
+ return 1;
+ break;
+ case LUN_FAILED:
+ printk(KERN_WARNING "cciss%d: LUN failure "
+ "detected, action required\n", h->ctlr);
+ return 1;
+ break;
+ case REPORT_LUNS_CHANGED:
+ printk(KERN_WARNING "cciss%d: report LUN data "
+ "changed\n", h->ctlr);
+ if (h->rescan_wait)
+ complete(h->rescan_wait);
+ return 1;
+ break;
+ case POWER_OR_RESET:
+ printk(KERN_WARNING "cciss%d: a power on "
+ "or device reset detected\n", h->ctlr);
+ return 1;
+ break;
+ case UNIT_ATTENTION_CLEARED:
+ printk(KERN_WARNING "cciss%d: unit attention "
+ "cleared by another initiator\n", h->ctlr);
+ return 1;
+ break;
+ default:
+ printk(KERN_WARNING "cciss%d: unknown "
+ "unit attention detected\n", h->ctlr);
+ return 1;
+ }
+}
+
/*
* We cannot read the structure directly, for portability we must use
* the io functions.
@@ -3181,12 +3265,21 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
*/
cciss_interrupt_mode(c, pdev, board_id);
- /*
- * Memory base addr is first addr , the second points to the config
- * table
- */
+ /* find the memory BAR */
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ if (pci_resource_flags(pdev, i) & IORESOURCE_MEM)
+ break;
+ }
+ if (i == DEVICE_COUNT_RESOURCE) {
+ printk(KERN_WARNING "cciss: No memory BAR found\n");
+ err = -ENODEV;
+ goto err_out_free_res;
+ }
+
+ c->paddr = pci_resource_start(pdev, i); /* addressing mode bits
+ * already removed
+ */
- c->paddr = pci_resource_start(pdev, 0); /* addressing mode bits already removed */
#ifdef CCISS_DEBUG
printk("address 0 = %lx\n", c->paddr);
#endif /* CCISS_DEBUG */
@@ -3412,7 +3505,7 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u
/* The Inbound Post Queue only accepts 32-bit physical addresses for the
CCISS commands, so they must be allocated from the lower 4GiB of
memory. */
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
iounmap(vaddr);
return -ENOMEM;
@@ -3637,9 +3730,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->pdev = pdev;
/* configure PCI DMA stuff */
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
dac = 1;
- else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK))
+ else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
dac = 0;
else {
printk(KERN_ERR "cciss: no suitable DMA available\n");
@@ -3753,6 +3846,11 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->busy_initializing = 0;
rebuild_lun_table(hba[i], 1);
+ hba[i]->cciss_scan_thread = kthread_run(scan_thread, hba[i],
+ "cciss_scan%02d", i);
+ if (IS_ERR(hba[i]->cciss_scan_thread))
+ return PTR_ERR(hba[i]->cciss_scan_thread);
+
return 1;
clean4:
@@ -3828,6 +3926,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
printk(KERN_ERR "cciss: Unable to remove device \n");
return;
}
+
tmp_ptr = pci_get_drvdata(pdev);
i = tmp_ptr->ctlr;
if (hba[i] == NULL) {
@@ -3836,6 +3935,8 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
return;
}
+ kthread_stop(hba[i]->cciss_scan_thread);
+
remove_proc_entry(hba[i]->devname, proc_cciss);
unregister_blkdev(hba[i]->major, hba[i]->devname);
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 15e2b84734e..703e08038fb 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -121,6 +121,8 @@ struct ctlr_info
struct sendcmd_reject_list scsi_rejects;
#endif
unsigned char alive;
+ struct completion *rescan_wait;
+ struct task_struct *cciss_scan_thread;
};
/* Defining the diffent access_menthods */
diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h
index 24e22dea1a9..40b1b92dae7 100644
--- a/drivers/block/cciss_cmd.h
+++ b/drivers/block/cciss_cmd.h
@@ -25,6 +25,29 @@
#define CMD_TIMEOUT 0x000B
#define CMD_UNABORTABLE 0x000C
+/* Unit Attentions ASC's as defined for the MSA2012sa */
+#define POWER_OR_RESET 0x29
+#define STATE_CHANGED 0x2a
+#define UNIT_ATTENTION_CLEARED 0x2f
+#define LUN_FAILED 0x3e
+#define REPORT_LUNS_CHANGED 0x3f
+
+/* Unit Attentions ASCQ's as defined for the MSA2012sa */
+
+ /* These ASCQ's defined for ASC = POWER_OR_RESET */
+#define POWER_ON_RESET 0x00
+#define POWER_ON_REBOOT 0x01
+#define SCSI_BUS_RESET 0x02
+#define MSA_TARGET_RESET 0x03
+#define CONTROLLER_FAILOVER 0x04
+#define TRANSCEIVER_SE 0x05
+#define TRANSCEIVER_LVD 0x06
+
+ /* These ASCQ's defined for ASC = STATE_CHANGED */
+#define RESERVATION_PREEMPTED 0x03
+#define ASYM_ACCESS_CHANGED 0x06
+#define LUN_CAPACITY_CHANGED 0x09
+
//transfer direction
#define XFER_NONE 0x00
#define XFER_WRITE 0x01
diff --git a/drivers/block/hd.c b/drivers/block/hd.c
index 482c0c4b964..3c11f062a18 100644
--- a/drivers/block/hd.c
+++ b/drivers/block/hd.c
@@ -42,6 +42,8 @@
#include <linux/ata.h>
#include <linux/hdreg.h>
+#define HD_IRQ 14
+
#define REALLY_SLOW_IO
#include <asm/system.h>
#include <asm/io.h>
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 40b17d3b55a..ddae8082589 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1431,6 +1431,7 @@ static int lo_open(struct block_device *bdev, fmode_t mode)
static int lo_release(struct gendisk *disk, fmode_t mode)
{
struct loop_device *lo = disk->private_data;
+ int err;
mutex_lock(&lo->lo_ctl_mutex);
@@ -1442,7 +1443,9 @@ static int lo_release(struct gendisk *disk, fmode_t mode)
* In autoclear mode, stop the loop thread
* and remove configuration after last close.
*/
- loop_clr_fd(lo, NULL);
+ err = loop_clr_fd(lo, NULL);
+ if (!err)
+ goto out_unlocked;
} else {
/*
* Otherwise keep thread (if running) and config,
@@ -1453,7 +1456,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode)
out:
mutex_unlock(&lo->lo_ctl_mutex);
-
+out_unlocked:
return 0;
}
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c
new file mode 100644
index 00000000000..fb39d9aa3cd
--- /dev/null
+++ b/drivers/block/mg_disk.c
@@ -0,0 +1,1005 @@
+/*
+ * drivers/block/mg_disk.c
+ *
+ * Support for the mGine m[g]flash IO mode.
+ * Based on legacy hd.c
+ *
+ * (c) 2008 mGine Co.,LTD
+ * (c) 2008 unsik Kim <donari75@gmail.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/fs.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/libata.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/mg_disk.h>
+
+#define MG_RES_SEC (CONFIG_MG_DISK_RES << 1)
+
+static void mg_request(struct request_queue *);
+
+static void mg_dump_status(const char *msg, unsigned int stat,
+ struct mg_host *host)
+{
+ char *name = MG_DISK_NAME;
+ struct request *req;
+
+ if (host->breq) {
+ req = elv_next_request(host->breq);
+ if (req)
+ name = req->rq_disk->disk_name;
+ }
+
+ printk(KERN_ERR "%s: %s: status=0x%02x { ", name, msg, stat & 0xff);
+ if (stat & MG_REG_STATUS_BIT_BUSY)
+ printk("Busy ");
+ if (stat & MG_REG_STATUS_BIT_READY)
+ printk("DriveReady ");
+ if (stat & MG_REG_STATUS_BIT_WRITE_FAULT)
+ printk("WriteFault ");
+ if (stat & MG_REG_STATUS_BIT_SEEK_DONE)
+ printk("SeekComplete ");
+ if (stat & MG_REG_STATUS_BIT_DATA_REQ)
+ printk("DataRequest ");
+ if (stat & MG_REG_STATUS_BIT_CORRECTED_ERROR)
+ printk("CorrectedError ");
+ if (stat & MG_REG_STATUS_BIT_ERROR)
+ printk("Error ");
+ printk("}\n");
+ if ((stat & MG_REG_STATUS_BIT_ERROR) == 0) {
+ host->error = 0;
+ } else {
+ host->error = inb((unsigned long)host->dev_base + MG_REG_ERROR);
+ printk(KERN_ERR "%s: %s: error=0x%02x { ", name, msg,
+ host->error & 0xff);
+ if (host->error & MG_REG_ERR_BBK)
+ printk("BadSector ");
+ if (host->error & MG_REG_ERR_UNC)
+ printk("UncorrectableError ");
+ if (host->error & MG_REG_ERR_IDNF)
+ printk("SectorIdNotFound ");
+ if (host->error & MG_REG_ERR_ABRT)
+ printk("DriveStatusError ");
+ if (host->error & MG_REG_ERR_AMNF)
+ printk("AddrMarkNotFound ");
+ printk("}");
+ if (host->error &
+ (MG_REG_ERR_BBK | MG_REG_ERR_UNC |
+ MG_REG_ERR_IDNF | MG_REG_ERR_AMNF)) {
+ if (host->breq) {
+ req = elv_next_request(host->breq);
+ if (req)
+ printk(", sector=%ld", req->sector);
+ }
+
+ }
+ printk("\n");
+ }
+}
+
+static unsigned int mg_wait(struct mg_host *host, u32 expect, u32 msec)
+{
+ u8 status;
+ unsigned long expire, cur_jiffies;
+ struct mg_drv_data *prv_data = host->dev->platform_data;
+
+ host->error = MG_ERR_NONE;
+ expire = jiffies + msecs_to_jiffies(msec);
+
+ status = inb((unsigned long)host->dev_base + MG_REG_STATUS);
+
+ do {
+ cur_jiffies = jiffies;
+ if (status & MG_REG_STATUS_BIT_BUSY) {
+ if (expect == MG_REG_STATUS_BIT_BUSY)
+ break;
+ } else {
+ /* Check the error condition! */
+ if (status & MG_REG_STATUS_BIT_ERROR) {
+ mg_dump_status("mg_wait", status, host);
+ break;
+ }
+
+ if (expect == MG_STAT_READY)
+ if (MG_READY_OK(status))
+ break;
+
+ if (expect == MG_REG_STATUS_BIT_DATA_REQ)
+ if (status & MG_REG_STATUS_BIT_DATA_REQ)
+ break;
+ }
+ if (!msec) {
+ mg_dump_status("not ready", status, host);
+ return MG_ERR_INV_STAT;
+ }
+ if (prv_data->use_polling)
+ msleep(1);
+
+ status = inb((unsigned long)host->dev_base + MG_REG_STATUS);
+ } while (time_before(cur_jiffies, expire));
+
+ if (time_after_eq(cur_jiffies, expire) && msec)
+ host->error = MG_ERR_TIMEOUT;
+
+ return host->error;
+}
+
+static unsigned int mg_wait_rstout(u32 rstout, u32 msec)
+{
+ unsigned long expire;
+
+ expire = jiffies + msecs_to_jiffies(msec);
+ while (time_before(jiffies, expire)) {
+ if (gpio_get_value(rstout) == 1)
+ return MG_ERR_NONE;
+ msleep(10);
+ }
+
+ return MG_ERR_RSTOUT;
+}
+
+static void mg_unexpected_intr(struct mg_host *host)
+{
+ u32 status = inb((unsigned long)host->dev_base + MG_REG_STATUS);
+
+ mg_dump_status("mg_unexpected_intr", status, host);
+}
+
+static irqreturn_t mg_irq(int irq, void *dev_id)
+{
+ struct mg_host *host = dev_id;
+ void (*handler)(struct mg_host *) = host->mg_do_intr;
+
+ host->mg_do_intr = 0;
+ del_timer(&host->timer);
+ if (!handler)
+ handler = mg_unexpected_intr;
+ handler(host);
+ return IRQ_HANDLED;
+}
+
+static int mg_get_disk_id(struct mg_host *host)
+{
+ u32 i;
+ s32 err;
+ const u16 *id = host->id;
+ struct mg_drv_data *prv_data = host->dev->platform_data;
+ char fwrev[ATA_ID_FW_REV_LEN + 1];
+ char model[ATA_ID_PROD_LEN + 1];
+ char serial[ATA_ID_SERNO_LEN + 1];
+
+ if (!prv_data->use_polling)
+ outb(MG_REG_CTRL_INTR_DISABLE,
+ (unsigned long)host->dev_base +
+ MG_REG_DRV_CTRL);
+
+ outb(MG_CMD_ID, (unsigned long)host->dev_base + MG_REG_COMMAND);
+ err = mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, MG_TMAX_WAIT_RD_DRQ);
+ if (err)
+ return err;
+
+ for (i = 0; i < (MG_SECTOR_SIZE >> 1); i++)
+ host->id[i] = le16_to_cpu(inw((unsigned long)host->dev_base +
+ MG_BUFF_OFFSET + i * 2));
+
+ outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
+ err = mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD);
+ if (err)
+ return err;
+
+ if ((id[ATA_ID_FIELD_VALID] & 1) == 0)
+ return MG_ERR_TRANSLATION;
+
+ host->n_sectors = ata_id_u32(id, ATA_ID_LBA_CAPACITY);
+ host->cyls = id[ATA_ID_CYLS];
+ host->heads = id[ATA_ID_HEADS];
+ host->sectors = id[ATA_ID_SECTORS];
+
+ if (MG_RES_SEC && host->heads && host->sectors) {
+ /* modify cyls, n_sectors */
+ host->cyls = (host->n_sectors - MG_RES_SEC) /
+ host->heads / host->sectors;
+ host->nres_sectors = host->n_sectors - host->cyls *
+ host->heads * host->sectors;
+ host->n_sectors -= host->nres_sectors;
+ }
+
+ ata_id_c_string(id, fwrev, ATA_ID_FW_REV, sizeof(fwrev));
+ ata_id_c_string(id, model, ATA_ID_PROD, sizeof(model));
+ ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
+ printk(KERN_INFO "mg_disk: model: %s\n", model);
+ printk(KERN_INFO "mg_disk: firm: %.8s\n", fwrev);
+ printk(KERN_INFO "mg_disk: serial: %s\n", serial);
+ printk(KERN_INFO "mg_disk: %d + reserved %d sectors\n",
+ host->n_sectors, host->nres_sectors);
+
+ if (!prv_data->use_polling)
+ outb(MG_REG_CTRL_INTR_ENABLE, (unsigned long)host->dev_base +
+ MG_REG_DRV_CTRL);
+
+ return err;
+}
+
+
+static int mg_disk_init(struct mg_host *host)
+{
+ struct mg_drv_data *prv_data = host->dev->platform_data;
+ s32 err;
+ u8 init_status;
+
+ /* hdd rst low */
+ gpio_set_value(host->rst, 0);
+ err = mg_wait(host, MG_REG_STATUS_BIT_BUSY, MG_TMAX_RST_TO_BUSY);
+ if (err)
+ return err;
+
+ /* hdd rst high */
+ gpio_set_value(host->rst, 1);
+ err = mg_wait(host, MG_STAT_READY, MG_TMAX_HDRST_TO_RDY);
+ if (err)
+ return err;
+
+ /* soft reset on */
+ outb(MG_REG_CTRL_RESET |
+ (prv_data->use_polling ? MG_REG_CTRL_INTR_DISABLE :
+ MG_REG_CTRL_INTR_ENABLE),
+ (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
+ err = mg_wait(host, MG_REG_STATUS_BIT_BUSY, MG_TMAX_RST_TO_BUSY);
+ if (err)
+ return err;
+
+ /* soft reset off */
+ outb(prv_data->use_polling ? MG_REG_CTRL_INTR_DISABLE :
+ MG_REG_CTRL_INTR_ENABLE,
+ (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
+ err = mg_wait(host, MG_STAT_READY, MG_TMAX_SWRST_TO_RDY);
+ if (err)
+ return err;
+
+ init_status = inb((unsigned long)host->dev_base + MG_REG_STATUS) & 0xf;
+
+ if (init_status == 0xf)
+ return MG_ERR_INIT_STAT;
+
+ return err;
+}
+
+static void mg_bad_rw_intr(struct mg_host *host)
+{
+ struct request *req = elv_next_request(host->breq);
+ if (req != NULL)
+ if (++req->errors >= MG_MAX_ERRORS ||
+ host->error == MG_ERR_TIMEOUT)
+ end_request(req, 0);
+}
+
+static unsigned int mg_out(struct mg_host *host,
+ unsigned int sect_num,
+ unsigned int sect_cnt,
+ unsigned int cmd,
+ void (*intr_addr)(struct mg_host *))
+{
+ struct mg_drv_data *prv_data = host->dev->platform_data;
+
+ if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD))
+ return host->error;
+
+ if (!prv_data->use_polling) {
+ host->mg_do_intr = intr_addr;
+ mod_timer(&host->timer, jiffies + 3 * HZ);
+ }
+ if (MG_RES_SEC)
+ sect_num += MG_RES_SEC;
+ outb((u8)sect_cnt, (unsigned long)host->dev_base + MG_REG_SECT_CNT);
+ outb((u8)sect_num, (unsigned long)host->dev_base + MG_REG_SECT_NUM);
+ outb((u8)(sect_num >> 8), (unsigned long)host->dev_base +
+ MG_REG_CYL_LOW);
+ outb((u8)(sect_num >> 16), (unsigned long)host->dev_base +
+ MG_REG_CYL_HIGH);
+ outb((u8)((sect_num >> 24) | MG_REG_HEAD_LBA_MODE),
+ (unsigned long)host->dev_base + MG_REG_DRV_HEAD);
+ outb(cmd, (unsigned long)host->dev_base + MG_REG_COMMAND);
+ return MG_ERR_NONE;
+}
+
+static void mg_read(struct request *req)
+{
+ u32 remains, j;
+ struct mg_host *host = req->rq_disk->private_data;
+
+ remains = req->nr_sectors;
+
+ if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, 0) !=
+ MG_ERR_NONE)
+ mg_bad_rw_intr(host);
+
+ MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
+ remains, req->sector, req->buffer);
+
+ while (remains) {
+ if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ,
+ MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) {
+ mg_bad_rw_intr(host);
+ return;
+ }
+ for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) {
+ *(u16 *)req->buffer =
+ inw((unsigned long)host->dev_base +
+ MG_BUFF_OFFSET + (j << 1));
+ req->buffer += 2;
+ }
+
+ req->sector++;
+ req->errors = 0;
+ remains = --req->nr_sectors;
+ --req->current_nr_sectors;
+
+ if (req->current_nr_sectors <= 0) {
+ MG_DBG("remain : %d sects\n", remains);
+ end_request(req, 1);
+ if (remains > 0)
+ req = elv_next_request(host->breq);
+ }
+
+ outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base +
+ MG_REG_COMMAND);
+ }
+}
+
+static void mg_write(struct request *req)
+{
+ u32 remains, j;
+ struct mg_host *host = req->rq_disk->private_data;
+
+ remains = req->nr_sectors;
+
+ if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, 0) !=
+ MG_ERR_NONE) {
+ mg_bad_rw_intr(host);
+ return;
+ }
+
+
+ MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
+ remains, req->sector, req->buffer);
+ while (remains) {
+ if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ,
+ MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) {
+ mg_bad_rw_intr(host);
+ return;
+ }
+ for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) {
+ outw(*(u16 *)req->buffer,
+ (unsigned long)host->dev_base +
+ MG_BUFF_OFFSET + (j << 1));
+ req->buffer += 2;
+ }
+ req->sector++;
+ remains = --req->nr_sectors;
+ --req->current_nr_sectors;
+
+ if (req->current_nr_sectors <= 0) {
+ MG_DBG("remain : %d sects\n", remains);
+ end_request(req, 1);
+ if (remains > 0)
+ req = elv_next_request(host->breq);
+ }
+
+ outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
+ MG_REG_COMMAND);
+ }
+}
+
+static void mg_read_intr(struct mg_host *host)
+{
+ u32 i;
+ struct request *req;
+
+ /* check status */
+ do {
+ i = inb((unsigned long)host->dev_base + MG_REG_STATUS);
+ if (i & MG_REG_STATUS_BIT_BUSY)
+ break;
+ if (!MG_READY_OK(i))
+ break;
+ if (i & MG_REG_STATUS_BIT_DATA_REQ)
+ goto ok_to_read;
+ } while (0);
+ mg_dump_status("mg_read_intr", i, host);
+ mg_bad_rw_intr(host);
+ mg_request(host->breq);
+ return;
+
+ok_to_read:
+ /* get current segment of request */
+ req = elv_next_request(host->breq);
+
+ /* read 1 sector */
+ for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) {
+ *(u16 *)req->buffer =
+ inw((unsigned long)host->dev_base + MG_BUFF_OFFSET +
+ (i << 1));
+ req->buffer += 2;
+ }
+
+ /* manipulate request */
+ MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n",
+ req->sector, req->nr_sectors - 1, req->buffer);
+
+ req->sector++;
+ req->errors = 0;
+ i = --req->nr_sectors;
+ --req->current_nr_sectors;
+
+ /* let know if current segment done */
+ if (req->current_nr_sectors <= 0)
+ end_request(req, 1);
+
+ /* set handler if read remains */
+ if (i > 0) {
+ host->mg_do_intr = mg_read_intr;
+ mod_timer(&host->timer, jiffies + 3 * HZ);
+ }
+
+ /* send read confirm */
+ outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
+
+ /* goto next request */
+ if (!i)
+ mg_request(host->breq);
+}
+
+static void mg_write_intr(struct mg_host *host)
+{
+ u32 i, j;
+ u16 *buff;
+ struct request *req;
+
+ /* get current segment of request */
+ req = elv_next_request(host->breq);
+
+ /* check status */
+ do {
+ i = inb((unsigned long)host->dev_base + MG_REG_STATUS);
+ if (i & MG_REG_STATUS_BIT_BUSY)
+ break;
+ if (!MG_READY_OK(i))
+ break;
+ if ((req->nr_sectors <= 1) || (i & MG_REG_STATUS_BIT_DATA_REQ))
+ goto ok_to_write;
+ } while (0);
+ mg_dump_status("mg_write_intr", i, host);
+ mg_bad_rw_intr(host);
+ mg_request(host->breq);
+ return;
+
+ok_to_write:
+ /* manipulate request */
+ req->sector++;
+ i = --req->nr_sectors;
+ --req->current_nr_sectors;
+ req->buffer += MG_SECTOR_SIZE;
+
+ /* let know if current segment or all done */
+ if (!i || (req->bio && req->current_nr_sectors <= 0))
+ end_request(req, 1);
+
+ /* write 1 sector and set handler if remains */
+ if (i > 0) {
+ buff = (u16 *)req->buffer;
+ for (j = 0; j < MG_STORAGE_BUFFER_SIZE >> 1; j++) {
+ outw(*buff, (unsigned long)host->dev_base +
+ MG_BUFF_OFFSET + (j << 1));
+ buff++;
+ }
+ MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n",
+ req->sector, req->nr_sectors, req->buffer);
+ host->mg_do_intr = mg_write_intr;
+ mod_timer(&host->timer, jiffies + 3 * HZ);
+ }
+
+ /* send write confirm */
+ outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
+
+ if (!i)
+ mg_request(host->breq);
+}
+
+void mg_times_out(unsigned long data)
+{
+ struct mg_host *host = (struct mg_host *)data;
+ char *name;
+ struct request *req;
+
+ req = elv_next_request(host->breq);
+ if (!req)
+ return;
+
+ host->mg_do_intr = NULL;
+
+ name = req->rq_disk->disk_name;
+ printk(KERN_DEBUG "%s: timeout\n", name);
+
+ host->error = MG_ERR_TIMEOUT;
+ mg_bad_rw_intr(host);
+
+ mg_request(host->breq);
+}
+
+static void mg_request_poll(struct request_queue *q)
+{
+ struct request *req;
+ struct mg_host *host;
+
+ while ((req = elv_next_request(q)) != NULL) {
+ host = req->rq_disk->private_data;
+ if (blk_fs_request(req)) {
+ switch (rq_data_dir(req)) {
+ case READ:
+ mg_read(req);
+ break;
+ case WRITE:
+ mg_write(req);
+ break;
+ default:
+ printk(KERN_WARNING "%s:%d unknown command\n",
+ __func__, __LINE__);
+ end_request(req, 0);
+ break;
+ }
+ }
+ }
+}
+
+static unsigned int mg_issue_req(struct request *req,
+ struct mg_host *host,
+ unsigned int sect_num,
+ unsigned int sect_cnt)
+{
+ u16 *buff;
+ u32 i;
+
+ switch (rq_data_dir(req)) {
+ case READ:
+ if (mg_out(host, sect_num, sect_cnt, MG_CMD_RD, &mg_read_intr)
+ != MG_ERR_NONE) {
+ mg_bad_rw_intr(host);
+ return host->error;
+ }
+ break;
+ case WRITE:
+ /* TODO : handler */
+ outb(MG_REG_CTRL_INTR_DISABLE,
+ (unsigned long)host->dev_base +
+ MG_REG_DRV_CTRL);
+ if (mg_out(host, sect_num, sect_cnt, MG_CMD_WR, &mg_write_intr)
+ != MG_ERR_NONE) {
+ mg_bad_rw_intr(host);
+ return host->error;
+ }
+ del_timer(&host->timer);
+ mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, MG_TMAX_WAIT_WR_DRQ);
+ outb(MG_REG_CTRL_INTR_ENABLE, (unsigned long)host->dev_base +
+ MG_REG_DRV_CTRL);
+ if (host->error) {
+ mg_bad_rw_intr(host);
+ return host->error;
+ }
+ buff = (u16 *)req->buffer;
+ for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) {
+ outw(*buff, (unsigned long)host->dev_base +
+ MG_BUFF_OFFSET + (i << 1));
+ buff++;
+ }
+ mod_timer(&host->timer, jiffies + 3 * HZ);
+ outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
+ MG_REG_COMMAND);
+ break;
+ default:
+ printk(KERN_WARNING "%s:%d unknown command\n",
+ __func__, __LINE__);
+ end_request(req, 0);
+ break;
+ }
+ return MG_ERR_NONE;
+}
+
+/* This function also called from IRQ context */
+static void mg_request(struct request_queue *q)
+{
+ struct request *req;
+ struct mg_host *host;
+ u32 sect_num, sect_cnt;
+
+ while (1) {
+ req = elv_next_request(q);
+ if (!req)
+ return;
+
+ host = req->rq_disk->private_data;
+
+ /* check unwanted request call */
+ if (host->mg_do_intr)
+ return;
+
+ del_timer(&host->timer);
+
+ sect_num = req->sector;
+ /* deal whole segments */
+ sect_cnt = req->nr_sectors;
+
+ /* sanity check */
+ if (sect_num >= get_capacity(req->rq_disk) ||
+ ((sect_num + sect_cnt) >
+ get_capacity(req->rq_disk))) {
+ printk(KERN_WARNING
+ "%s: bad access: sector=%d, count=%d\n",
+ req->rq_disk->disk_name,
+ sect_num, sect_cnt);
+ end_request(req, 0);
+ continue;
+ }
+
+ if (!blk_fs_request(req))
+ return;
+
+ if (!mg_issue_req(req, host, sect_num, sect_cnt))
+ return;
+ }
+}
+
+static int mg_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+ struct mg_host *host = bdev->bd_disk->private_data;
+
+ geo->cylinders = (unsigned short)host->cyls;
+ geo->heads = (unsigned char)host->heads;
+ geo->sectors = (unsigned char)host->sectors;
+ return 0;
+}
+
+static struct block_device_operations mg_disk_ops = {
+ .getgeo = mg_getgeo
+};
+
+static int mg_suspend(struct platform_device *plat_dev, pm_message_t state)
+{
+ struct mg_drv_data *prv_data = plat_dev->dev.platform_data;
+ struct mg_host *host = prv_data->host;
+
+ if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD))
+ return -EIO;
+
+ if (!prv_data->use_polling)
+ outb(MG_REG_CTRL_INTR_DISABLE,
+ (unsigned long)host->dev_base +
+ MG_REG_DRV_CTRL);
+
+ outb(MG_CMD_SLEEP, (unsigned long)host->dev_base + MG_REG_COMMAND);
+ /* wait until mflash deep sleep */
+ msleep(1);
+
+ if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) {
+ if (!prv_data->use_polling)
+ outb(MG_REG_CTRL_INTR_ENABLE,
+ (unsigned long)host->dev_base +
+ MG_REG_DRV_CTRL);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int mg_resume(struct platform_device *plat_dev)
+{
+ struct mg_drv_data *prv_data = plat_dev->dev.platform_data;
+ struct mg_host *host = prv_data->host;
+
+ if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD))
+ return -EIO;
+
+ outb(MG_CMD_WAKEUP, (unsigned long)host->dev_base + MG_REG_COMMAND);
+ /* wait until mflash wakeup */
+ msleep(1);
+
+ if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD))
+ return -EIO;
+
+ if (!prv_data->use_polling)
+ outb(MG_REG_CTRL_INTR_ENABLE, (unsigned long)host->dev_base +
+ MG_REG_DRV_CTRL);
+
+ return 0;
+}
+
+static int mg_probe(struct platform_device *plat_dev)
+{
+ struct mg_host *host;
+ struct resource *rsc;
+ struct mg_drv_data *prv_data = plat_dev->dev.platform_data;
+ int err = 0;
+
+ if (!prv_data) {
+ printk(KERN_ERR "%s:%d fail (no driver_data)\n",
+ __func__, __LINE__);
+ err = -EINVAL;
+ goto probe_err;
+ }
+
+ /* alloc mg_host */
+ host = kzalloc(sizeof(struct mg_host), GFP_KERNEL);
+ if (!host) {
+ printk(KERN_ERR "%s:%d fail (no memory for mg_host)\n",
+ __func__, __LINE__);
+ err = -ENOMEM;
+ goto probe_err;
+ }
+ host->major = MG_DISK_MAJ;
+
+ /* link each other */
+ prv_data->host = host;
+ host->dev = &plat_dev->dev;
+
+ /* io remap */
+ rsc = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
+ if (!rsc) {
+ printk(KERN_ERR "%s:%d platform_get_resource fail\n",
+ __func__, __LINE__);
+ err = -EINVAL;
+ goto probe_err_2;
+ }
+ host->dev_base = ioremap(rsc->start , rsc->end + 1);
+ if (!host->dev_base) {
+ printk(KERN_ERR "%s:%d ioremap fail\n",
+ __func__, __LINE__);
+ err = -EIO;
+ goto probe_err_2;
+ }
+ MG_DBG("dev_base = 0x%x\n", (u32)host->dev_base);
+
+ /* get reset pin */
+ rsc = platform_get_resource_byname(plat_dev, IORESOURCE_IO,
+ MG_RST_PIN);
+ if (!rsc) {
+ printk(KERN_ERR "%s:%d get reset pin fail\n",
+ __func__, __LINE__);
+ err = -EIO;
+ goto probe_err_3;
+ }
+ host->rst = rsc->start;
+
+ /* init rst pin */
+ err = gpio_request(host->rst, MG_RST_PIN);
+ if (err)
+ goto probe_err_3;
+ gpio_direction_output(host->rst, 1);
+
+ /* reset out pin */
+ if (!(prv_data->dev_attr & MG_DEV_MASK))
+ goto probe_err_3a;
+
+ if (prv_data->dev_attr != MG_BOOT_DEV) {
+ rsc = platform_get_resource_byname(plat_dev, IORESOURCE_IO,
+ MG_RSTOUT_PIN);
+ if (!rsc) {
+ printk(KERN_ERR "%s:%d get reset-out pin fail\n",
+ __func__, __LINE__);
+ err = -EIO;
+ goto probe_err_3a;
+ }
+ host->rstout = rsc->start;
+ err = gpio_request(host->rstout, MG_RSTOUT_PIN);
+ if (err)
+ goto probe_err_3a;
+ gpio_direction_input(host->rstout);
+ }
+
+ /* disk reset */
+ if (prv_data->dev_attr == MG_STORAGE_DEV) {
+ /* If POR seq. not yet finised, wait */
+ err = mg_wait_rstout(host->rstout, MG_TMAX_RSTOUT);
+ if (err)
+ goto probe_err_3b;
+ err = mg_disk_init(host);
+ if (err) {
+ printk(KERN_ERR "%s:%d fail (err code : %d)\n",
+ __func__, __LINE__, err);
+ err = -EIO;
+ goto probe_err_3b;
+ }
+ }
+
+ /* get irq resource */
+ if (!prv_data->use_polling) {
+ host->irq = platform_get_irq(plat_dev, 0);
+ if (host->irq == -ENXIO) {
+ err = host->irq;
+ goto probe_err_3b;
+ }
+ err = request_irq(host->irq, mg_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING,
+ MG_DEV_NAME, host);
+ if (err) {
+ printk(KERN_ERR "%s:%d fail (request_irq err=%d)\n",
+ __func__, __LINE__, err);
+ goto probe_err_3b;
+ }
+
+ }
+
+ /* get disk id */
+ err = mg_get_disk_id(host);
+ if (err) {
+ printk(KERN_ERR "%s:%d fail (err code : %d)\n",
+ __func__, __LINE__, err);
+ err = -EIO;
+ goto probe_err_4;
+ }
+
+ err = register_blkdev(host->major, MG_DISK_NAME);
+ if (err < 0) {
+ printk(KERN_ERR "%s:%d register_blkdev fail (err code : %d)\n",
+ __func__, __LINE__, err);
+ goto probe_err_4;
+ }
+ if (!host->major)
+ host->major = err;
+
+ spin_lock_init(&host->lock);
+
+ if (prv_data->use_polling)
+ host->breq = blk_init_queue(mg_request_poll, &host->lock);
+ else
+ host->breq = blk_init_queue(mg_request, &host->lock);
+
+ if (!host->breq) {
+ err = -ENOMEM;
+ printk(KERN_ERR "%s:%d (blk_init_queue) fail\n",
+ __func__, __LINE__);
+ goto probe_err_5;
+ }
+
+ /* mflash is random device, thanx for the noop */
+ elevator_exit(host->breq->elevator);
+ err = elevator_init(host->breq, "noop");
+ if (err) {
+ printk(KERN_ERR "%s:%d (elevator_init) fail\n",
+ __func__, __LINE__);
+ goto probe_err_6;
+ }
+ blk_queue_max_sectors(host->breq, MG_MAX_SECTS);
+ blk_queue_hardsect_size(host->breq, MG_SECTOR_SIZE);
+
+ init_timer(&host->timer);
+ host->timer.function = mg_times_out;
+ host->timer.data = (unsigned long)host;
+
+ host->gd = alloc_disk(MG_DISK_MAX_PART);
+ if (!host->gd) {
+ printk(KERN_ERR "%s:%d (alloc_disk) fail\n",
+ __func__, __LINE__);
+ err = -ENOMEM;
+ goto probe_err_7;
+ }
+ host->gd->major = host->major;
+ host->gd->first_minor = 0;
+ host->gd->fops = &mg_disk_ops;
+ host->gd->queue = host->breq;
+ host->gd->private_data = host;
+ sprintf(host->gd->disk_name, MG_DISK_NAME"a");
+
+ set_capacity(host->gd, host->n_sectors);
+
+ add_disk(host->gd);
+
+ return err;
+
+probe_err_7:
+ del_timer_sync(&host->timer);
+probe_err_6:
+ blk_cleanup_queue(host->breq);
+probe_err_5:
+ unregister_blkdev(MG_DISK_MAJ, MG_DISK_NAME);
+probe_err_4:
+ if (!prv_data->use_polling)
+ free_irq(host->irq, host);
+probe_err_3b:
+ gpio_free(host->rstout);
+probe_err_3a:
+ gpio_free(host->rst);
+probe_err_3:
+ iounmap(host->dev_base);
+probe_err_2:
+ kfree(host);
+probe_err:
+ return err;
+}
+
+static int mg_remove(struct platform_device *plat_dev)
+{
+ struct mg_drv_data *prv_data = plat_dev->dev.platform_data;
+ struct mg_host *host = prv_data->host;
+ int err = 0;
+
+ /* delete timer */
+ del_timer_sync(&host->timer);
+
+ /* remove disk */
+ if (host->gd) {
+ del_gendisk(host->gd);
+ put_disk(host->gd);
+ }
+ /* remove queue */
+ if (host->breq)
+ blk_cleanup_queue(host->breq);
+
+ /* unregister blk device */
+ unregister_blkdev(host->major, MG_DISK_NAME);
+
+ /* free irq */
+ if (!prv_data->use_polling)
+ free_irq(host->irq, host);
+
+ /* free reset-out pin */
+ if (prv_data->dev_attr != MG_BOOT_DEV)
+ gpio_free(host->rstout);
+
+ /* free rst pin */
+ if (host->rst)
+ gpio_free(host->rst);
+
+ /* unmap io */
+ if (host->dev_base)
+ iounmap(host->dev_base);
+
+ /* free mg_host */
+ kfree(host);
+
+ return err;
+}
+
+static struct platform_driver mg_disk_driver = {
+ .probe = mg_probe,
+ .remove = mg_remove,
+ .suspend = mg_suspend,
+ .resume = mg_resume,
+ .driver = {
+ .name = MG_DEV_NAME,
+ .owner = THIS_MODULE,
+ }
+};
+
+/****************************************************************************
+ *
+ * Module stuff
+ *
+ ****************************************************************************/
+
+static int __init mg_init(void)
+{
+ printk(KERN_INFO "mGine mflash driver, (c) 2008 mGine Co.\n");
+ return platform_driver_register(&mg_disk_driver);
+}
+
+static void __exit mg_exit(void)
+{
+ printk(KERN_INFO "mflash driver : bye bye\n");
+ platform_driver_unregister(&mg_disk_driver);
+}
+
+module_init(mg_init);
+module_exit(mg_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("unsik Kim <donari75@gmail.com>");
+MODULE_DESCRIPTION("mGine m[g]flash device driver");
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index a18e1ca0f76..ff0448e4bf0 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -1586,9 +1586,9 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out;
#ifdef IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */
- rc = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (!rc) {
- rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (rc) {
printk(KERN_ERR DRV_NAME "(%s): consistent DMA mask failure\n",
pci_name(pdev));
@@ -1597,7 +1597,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_dac = 1;
} else {
#endif
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
printk(KERN_ERR DRV_NAME "(%s): DMA mask failure\n",
pci_name(pdev));
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index c24e1bdbad4..9744d59a69f 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -829,8 +829,8 @@ static int __devinit mm_pci_probe(struct pci_dev *dev,
dev_printk(KERN_INFO, &dev->dev,
"Micro Memory(tm) controller found (PCI Mem Module (Battery Backup))\n");
- if (pci_set_dma_mask(dev, DMA_64BIT_MASK) &&
- pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(dev, DMA_BIT_MASK(64)) &&
+ pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
dev_printk(KERN_WARNING, &dev->dev, "NO suitable DMA found\n");
return -ENOMEM;
}
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 119be3442f2..4aecf5dc6a9 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -89,6 +89,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
+#include <linux/ata.h>
#include <linux/hdreg.h>
#include <linux/platform_device.h>
#if defined(CONFIG_OF)
@@ -208,7 +209,7 @@ struct ace_device {
struct gendisk *gd;
/* Inserted CF card parameters */
- struct hd_driveid cf_id;
+ u16 cf_id[ATA_ID_WORDS];
};
static int ace_major;
@@ -402,21 +403,14 @@ static void ace_dump_regs(struct ace_device *ace)
ace_in32(ace, ACE_CFGLBA), ace_in(ace, ACE_FATSTAT));
}
-void ace_fix_driveid(struct hd_driveid *id)
+void ace_fix_driveid(u16 *id)
{
#if defined(__BIG_ENDIAN)
- u16 *buf = (void *)id;
int i;
/* All half words have wrong byte order; swap the bytes */
- for (i = 0; i < sizeof(struct hd_driveid); i += 2, buf++)
- *buf = le16_to_cpu(*buf);
-
- /* Some of the data values are 32bit; swap the half words */
- id->lba_capacity = ((id->lba_capacity >> 16) & 0x0000FFFF) |
- ((id->lba_capacity << 16) & 0xFFFF0000);
- id->spg = ((id->spg >> 16) & 0x0000FFFF) |
- ((id->spg << 16) & 0xFFFF0000);
+ for (i = 0; i < ATA_ID_WORDS; i++, id++)
+ *id = le16_to_cpu(*id);
#endif
}
@@ -569,7 +563,7 @@ static void ace_fsm_dostate(struct ace_device *ace)
case ACE_FSM_STATE_IDENTIFY_PREPARE:
/* Send identify command */
ace->fsm_task = ACE_TASK_IDENTIFY;
- ace->data_ptr = &ace->cf_id;
+ ace->data_ptr = ace->cf_id;
ace->data_count = ACE_BUF_PER_SECTOR;
ace_out(ace, ACE_SECCNTCMD, ACE_SECCNTCMD_IDENTIFY);
@@ -614,8 +608,8 @@ static void ace_fsm_dostate(struct ace_device *ace)
break;
case ACE_FSM_STATE_IDENTIFY_COMPLETE:
- ace_fix_driveid(&ace->cf_id);
- ace_dump_mem(&ace->cf_id, 512); /* Debug: Dump out disk ID */
+ ace_fix_driveid(ace->cf_id);
+ ace_dump_mem(ace->cf_id, 512); /* Debug: Dump out disk ID */
if (ace->data_result) {
/* Error occured, disable the disk */
@@ -627,9 +621,10 @@ static void ace_fsm_dostate(struct ace_device *ace)
ace->media_change = 0;
/* Record disk parameters */
- set_capacity(ace->gd, ace->cf_id.lba_capacity);
+ set_capacity(ace->gd,
+ ata_id_u32(ace->cf_id, ATA_ID_LBA_CAPACITY));
dev_info(ace->dev, "capacity: %i sectors\n",
- ace->cf_id.lba_capacity);
+ ata_id_u32(ace->cf_id, ATA_ID_LBA_CAPACITY));
}
/* We're done, drop to IDLE state and notify waiters */
@@ -928,12 +923,13 @@ static int ace_release(struct gendisk *disk, fmode_t mode)
static int ace_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
struct ace_device *ace = bdev->bd_disk->private_data;
+ u16 *cf_id = ace->cf_id;
dev_dbg(ace->dev, "ace_getgeo()\n");
- geo->heads = ace->cf_id.heads;
- geo->sectors = ace->cf_id.sectors;
- geo->cylinders = ace->cf_id.cyls;
+ geo->heads = cf_id[ATA_ID_HEADS];
+ geo->sectors = cf_id[ATA_ID_SECTORS];
+ geo->cylinders = cf_id[ATA_ID_CYLS];
return 0;
}
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 9d9490e22e0..3686912427b 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -2131,6 +2131,8 @@ static const struct intel_driver_description {
{ PCI_DEVICE_ID_INTEL_82845G_HB, PCI_DEVICE_ID_INTEL_82845G_IG, 0, "830M",
&intel_845_driver, &intel_830_driver },
{ PCI_DEVICE_ID_INTEL_82850_HB, 0, 0, "i850", &intel_850_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82854_HB, PCI_DEVICE_ID_INTEL_82854_IG, 0, "854",
+ &intel_845_driver, &intel_830_driver },
{ PCI_DEVICE_ID_INTEL_82855PM_HB, 0, 0, "855PM", &intel_845_driver, NULL },
{ PCI_DEVICE_ID_INTEL_82855GM_HB, PCI_DEVICE_ID_INTEL_82855GM_IG, 0, "855GM",
&intel_845_driver, &intel_830_driver },
@@ -2355,6 +2357,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_82845_HB),
ID(PCI_DEVICE_ID_INTEL_82845G_HB),
ID(PCI_DEVICE_ID_INTEL_82850_HB),
+ ID(PCI_DEVICE_ID_INTEL_82854_HB),
ID(PCI_DEVICE_ID_INTEL_82855PM_HB),
ID(PCI_DEVICE_ID_INTEL_82855GM_HB),
ID(PCI_DEVICE_ID_INTEL_82860_HB),
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 05674febb0c..73a0765344b 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -75,6 +75,7 @@ MODULE_DEVICE_TABLE(pci, applicom_pci_tbl);
MODULE_AUTHOR("David Woodhouse & Applicom International");
MODULE_DESCRIPTION("Driver for Applicom Profibus card");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(AC_MINOR);
MODULE_SUPPORTED_DEVICE("ac");
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index f6094ae0ef3..140ea10ecb8 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -140,7 +140,7 @@ static int bsr_open(struct inode * inode, struct file * filp)
return 0;
}
-const static struct file_operations bsr_fops = {
+static const struct file_operations bsr_fops = {
.owner = THIS_MODULE,
.mmap = bsr_mmap,
.open = bsr_open,
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 272db0e2b49..1fdb9f657d8 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -646,6 +646,7 @@
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/firmware.h>
+#include <linux/device.h>
#include <asm/system.h>
#include <linux/io.h>
@@ -5408,3 +5409,4 @@ module_exit(cy_cleanup_module);
MODULE_LICENSE("GPL");
MODULE_VERSION(CY_VERSION);
+MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR);
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index 45ec263ec01..a5c59fc2b0f 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -2258,7 +2258,7 @@ static int esp_open(struct tty_struct *tty, struct file *filp)
* driver.
*/
-static void show_serial_version(void)
+static void __init show_serial_version(void)
{
printk(KERN_INFO "%s version %s (DMA %u)\n",
serial_name, serial_version, dma);
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c
index 10ad41be589..dcd352ad0e7 100644
--- a/drivers/char/hw_random/timeriomem-rng.c
+++ b/drivers/char/hw_random/timeriomem-rng.c
@@ -90,10 +90,30 @@ static struct hwrng timeriomem_rng_ops = {
static int __init timeriomem_rng_probe(struct platform_device *pdev)
{
+ struct resource *res, *mem;
int ret;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (!res)
+ return -ENOENT;
+
+ mem = request_mem_region(res->start, res->end - res->start + 1,
+ pdev->name);
+ if (mem == NULL)
+ return -EBUSY;
+
+ dev_set_drvdata(&pdev->dev, mem);
+
timeriomem_rng_data = pdev->dev.platform_data;
+ timeriomem_rng_data->address = ioremap(res->start,
+ res->end - res->start + 1);
+ if (!timeriomem_rng_data->address) {
+ ret = -ENOMEM;
+ goto err_ioremap;
+ }
+
if (timeriomem_rng_data->period != 0
&& usecs_to_jiffies(timeriomem_rng_data->period) > 0) {
timeriomem_rng_timer.expires = jiffies;
@@ -104,23 +124,34 @@ static int __init timeriomem_rng_probe(struct platform_device *pdev)
timeriomem_rng_data->present = 1;
ret = hwrng_register(&timeriomem_rng_ops);
- if (ret) {
- dev_err(&pdev->dev, "problem registering\n");
- return ret;
- }
+ if (ret)
+ goto err_register;
dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n",
timeriomem_rng_data->address,
timeriomem_rng_data->period);
return 0;
+
+err_register:
+ dev_err(&pdev->dev, "problem registering\n");
+ iounmap(timeriomem_rng_data->address);
+err_ioremap:
+ release_resource(mem);
+
+ return ret;
}
static int __devexit timeriomem_rng_remove(struct platform_device *pdev)
{
+ struct resource *mem = dev_get_drvdata(&pdev->dev);
+
del_timer_sync(&timeriomem_rng_timer);
hwrng_unregister(&timeriomem_rng_ops);
+ iounmap(timeriomem_rng_data->address);
+ release_resource(mem);
+
return 0;
}
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 24aa6e88e22..a59eac584d1 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -925,6 +925,7 @@ static void isicom_shutdown_port(struct isi_port *port)
if (!card->count)
isicom_shutdown_board(card);
}
+ tty_kref_put(tty);
}
static void isicom_flush_buffer(struct tty_struct *tty)
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 8b0da97d529..4a4cab73d0b 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -1486,11 +1486,11 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
}
if (!handle) /* nothing else to do */
- return 0;
+ goto put;
intr = readw(ip); /* port irq status */
if (intr == 0)
- return 0;
+ goto put;
writew(0, ip); /* ACK port */
ofsAddr = p->tableAddr;
@@ -1499,16 +1499,17 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
ofsAddr + HostStat);
if (!inited)
- return 0;
+ goto put;
if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */
tty_insert_flip_char(tty, 0, TTY_BREAK);
tty_schedule_flip(tty);
}
- tty_kref_put(tty);
if (intr & IntrLine)
moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state);
+put:
+ tty_kref_put(tty);
return 0;
}
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 402c9f217f8..a420e8d437d 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -820,7 +820,6 @@ static void mxser_check_modem_status(struct tty_struct *tty,
wake_up_interruptible(&port->port.open_wait);
}
- tty = tty_port_tty_get(&port->port);
if (port->port.flags & ASYNC_CTS_FLOW) {
if (tty->hw_stopped) {
if (status & UART_MSR_CTS) {
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 2e8a6eed34b..ce81da5b2da 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -333,7 +333,7 @@ void rio_copy_to_card(void *from, void __iomem *to, int len)
int rio_minor(struct tty_struct *tty)
{
- return tty->index + (tty->driver == rio_driver) ? 0 : 256;
+ return tty->index + ((tty->driver == rio_driver) ? 0 : 256);
}
static int rio_set_real_termios(void *ptr)
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 9af8d74875b..21766045123 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -48,6 +48,7 @@
#include <linux/delay.h>
#include <linux/tty_flip.h>
#include <linux/spinlock.h>
+#include <linux/device.h>
#include <linux/uaccess.h>
@@ -1524,6 +1525,7 @@ module_param(iobase2, int, 0);
module_param(iobase3, int, 0);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(RISCOM8_NORMAL_MAJOR);
#endif /* MODULE */
/*
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 3c67c3d83de..e72be4190a4 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -2365,3 +2365,4 @@ module_init(specialix_init_module);
module_exit(specialix_exit_module);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(SPECIALIX_NORMAL_MAJOR);
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index ebea9b2c30a..b0a6a3e5192 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -35,7 +35,6 @@
#include <linux/vt_kern.h>
#include <linux/workqueue.h>
#include <linux/kexec.h>
-#include <linux/interrupt.h>
#include <linux/hrtimer.h>
#include <linux/oom.h>
@@ -283,7 +282,7 @@ static void sysrq_ftrace_dump(int key, struct tty_struct *tty)
}
static struct sysrq_key_op sysrq_ftrace_dump_op = {
.handler = sysrq_ftrace_dump,
- .help_msg = "dumpZ-ftrace-buffer",
+ .help_msg = "dump-ftrace-buffer(Z)",
.action_msg = "Dump ftrace buffer",
.enable_mask = SYSRQ_ENABLE_DUMP,
};
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 7783b42f691..1c92c39a53a 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -465,7 +465,6 @@ static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
ced->set_mode = sh_cmt_clock_event_mode;
pr_info("sh_cmt: %s used for clock events\n", ced->name);
- ced->mult = 1; /* work around misplaced WARN_ON() in clockevents.c */
clockevents_register_device(ced);
}
@@ -557,7 +556,7 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
cfg->clockevent_rating,
cfg->clocksource_rating);
err2:
- free_irq(irq, p);
+ remove_irq(irq, &p->irqaction);
err1:
iounmap(p->mapbase);
err0:
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index 4d85402a9e4..2bef086fb34 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -2575,7 +2575,7 @@ static int hifn_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return err;
pci_set_master(pdev);
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err)
goto err_out_disable_pci_device;
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index d9e751be8c5..f9f05d7a707 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -101,6 +101,7 @@ struct buffer_desc {
u32 phys_addr;
u32 __reserved[4];
struct buffer_desc *next;
+ enum dma_data_direction dir;
};
struct crypt_ctl {
@@ -132,14 +133,10 @@ struct crypt_ctl {
struct ablk_ctx {
struct buffer_desc *src;
struct buffer_desc *dst;
- unsigned src_nents;
- unsigned dst_nents;
};
struct aead_ctx {
struct buffer_desc *buffer;
- unsigned short assoc_nents;
- unsigned short src_nents;
struct scatterlist ivlist;
/* used when the hmac is not on one sg entry */
u8 *hmac_virt;
@@ -212,7 +209,7 @@ static struct platform_device pseudo_dev = {
.id = 0,
.num_resources = 0,
.dev = {
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
.release = dev_release,
}
};
@@ -312,7 +309,7 @@ static struct crypt_ctl *get_crypt_desc_emerg(void)
}
}
-static void free_buf_chain(struct buffer_desc *buf, u32 phys)
+static void free_buf_chain(struct device *dev, struct buffer_desc *buf,u32 phys)
{
while (buf) {
struct buffer_desc *buf1;
@@ -320,6 +317,7 @@ static void free_buf_chain(struct buffer_desc *buf, u32 phys)
buf1 = buf->next;
phys1 = buf->phys_next;
+ dma_unmap_single(dev, buf->phys_next, buf->buf_len, buf->dir);
dma_pool_free(buffer_pool, buf, phys);
buf = buf1;
phys = phys1;
@@ -348,7 +346,6 @@ static void one_packet(dma_addr_t phys)
struct crypt_ctl *crypt;
struct ixp_ctx *ctx;
int failed;
- enum dma_data_direction src_direction = DMA_BIDIRECTIONAL;
failed = phys & 0x1 ? -EBADMSG : 0;
phys &= ~0x3;
@@ -358,13 +355,8 @@ static void one_packet(dma_addr_t phys)
case CTL_FLAG_PERFORM_AEAD: {
struct aead_request *req = crypt->data.aead_req;
struct aead_ctx *req_ctx = aead_request_ctx(req);
- dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents,
- DMA_TO_DEVICE);
- dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
- dma_unmap_sg(dev, req->src, req_ctx->src_nents,
- DMA_BIDIRECTIONAL);
- free_buf_chain(req_ctx->buffer, crypt->src_buf);
+ free_buf_chain(dev, req_ctx->buffer, crypt->src_buf);
if (req_ctx->hmac_virt) {
finish_scattered_hmac(crypt);
}
@@ -374,16 +366,11 @@ static void one_packet(dma_addr_t phys)
case CTL_FLAG_PERFORM_ABLK: {
struct ablkcipher_request *req = crypt->data.ablk_req;
struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req);
- int nents;
+
if (req_ctx->dst) {
- nents = req_ctx->dst_nents;
- dma_unmap_sg(dev, req->dst, nents, DMA_FROM_DEVICE);
- free_buf_chain(req_ctx->dst, crypt->dst_buf);
- src_direction = DMA_TO_DEVICE;
+ free_buf_chain(dev, req_ctx->dst, crypt->dst_buf);
}
- nents = req_ctx->src_nents;
- dma_unmap_sg(dev, req->src, nents, src_direction);
- free_buf_chain(req_ctx->src, crypt->src_buf);
+ free_buf_chain(dev, req_ctx->src, crypt->src_buf);
req->base.complete(&req->base, failed);
break;
}
@@ -750,56 +737,35 @@ static int setup_cipher(struct crypto_tfm *tfm, int encrypt,
return 0;
}
-static int count_sg(struct scatterlist *sg, int nbytes)
+static struct buffer_desc *chainup_buffers(struct device *dev,
+ struct scatterlist *sg, unsigned nbytes,
+ struct buffer_desc *buf, gfp_t flags,
+ enum dma_data_direction dir)
{
- int i;
- for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
- nbytes -= sg->length;
- return i;
-}
-
-static struct buffer_desc *chainup_buffers(struct scatterlist *sg,
- unsigned nbytes, struct buffer_desc *buf, gfp_t flags)
-{
- int nents = 0;
-
- while (nbytes > 0) {
+ for (;nbytes > 0; sg = scatterwalk_sg_next(sg)) {
+ unsigned len = min(nbytes, sg->length);
struct buffer_desc *next_buf;
u32 next_buf_phys;
- unsigned len = min(nbytes, sg_dma_len(sg));
+ void *ptr;
- nents++;
nbytes -= len;
- if (!buf->phys_addr) {
- buf->phys_addr = sg_dma_address(sg);
- buf->buf_len = len;
- buf->next = NULL;
- buf->phys_next = 0;
- goto next;
- }
- /* Two consecutive chunks on one page may be handled by the old
- * buffer descriptor, increased by the length of the new one
- */
- if (sg_dma_address(sg) == buf->phys_addr + buf->buf_len) {
- buf->buf_len += len;
- goto next;
- }
+ ptr = page_address(sg_page(sg)) + sg->offset;
next_buf = dma_pool_alloc(buffer_pool, flags, &next_buf_phys);
- if (!next_buf)
- return NULL;
+ if (!next_buf) {
+ buf = NULL;
+ break;
+ }
+ sg_dma_address(sg) = dma_map_single(dev, ptr, len, dir);
buf->next = next_buf;
buf->phys_next = next_buf_phys;
-
buf = next_buf;
- buf->next = NULL;
- buf->phys_next = 0;
+
buf->phys_addr = sg_dma_address(sg);
buf->buf_len = len;
-next:
- if (nbytes > 0) {
- sg = sg_next(sg);
- }
+ buf->dir = dir;
}
+ buf->next = NULL;
+ buf->phys_next = 0;
return buf;
}
@@ -860,12 +826,12 @@ static int ablk_perform(struct ablkcipher_request *req, int encrypt)
struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
struct ixp_ctx *ctx = crypto_ablkcipher_ctx(tfm);
unsigned ivsize = crypto_ablkcipher_ivsize(tfm);
- int ret = -ENOMEM;
struct ix_sa_dir *dir;
struct crypt_ctl *crypt;
- unsigned int nbytes = req->nbytes, nents;
+ unsigned int nbytes = req->nbytes;
enum dma_data_direction src_direction = DMA_BIDIRECTIONAL;
struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req);
+ struct buffer_desc src_hook;
gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
GFP_KERNEL : GFP_ATOMIC;
@@ -878,7 +844,7 @@ static int ablk_perform(struct ablkcipher_request *req, int encrypt)
crypt = get_crypt_desc();
if (!crypt)
- return ret;
+ return -ENOMEM;
crypt->data.ablk_req = req;
crypt->crypto_ctx = dir->npe_ctx_phys;
@@ -891,53 +857,41 @@ static int ablk_perform(struct ablkcipher_request *req, int encrypt)
BUG_ON(ivsize && !req->info);
memcpy(crypt->iv, req->info, ivsize);
if (req->src != req->dst) {
+ struct buffer_desc dst_hook;
crypt->mode |= NPE_OP_NOT_IN_PLACE;
- nents = count_sg(req->dst, nbytes);
/* This was never tested by Intel
* for more than one dst buffer, I think. */
- BUG_ON(nents != 1);
- req_ctx->dst_nents = nents;
- dma_map_sg(dev, req->dst, nents, DMA_FROM_DEVICE);
- req_ctx->dst = dma_pool_alloc(buffer_pool, flags,&crypt->dst_buf);
- if (!req_ctx->dst)
- goto unmap_sg_dest;
- req_ctx->dst->phys_addr = 0;
- if (!chainup_buffers(req->dst, nbytes, req_ctx->dst, flags))
+ BUG_ON(req->dst->length < nbytes);
+ req_ctx->dst = NULL;
+ if (!chainup_buffers(dev, req->dst, nbytes, &dst_hook,
+ flags, DMA_FROM_DEVICE))
goto free_buf_dest;
src_direction = DMA_TO_DEVICE;
+ req_ctx->dst = dst_hook.next;
+ crypt->dst_buf = dst_hook.phys_next;
} else {
req_ctx->dst = NULL;
- req_ctx->dst_nents = 0;
}
- nents = count_sg(req->src, nbytes);
- req_ctx->src_nents = nents;
- dma_map_sg(dev, req->src, nents, src_direction);
-
- req_ctx->src = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf);
- if (!req_ctx->src)
- goto unmap_sg_src;
- req_ctx->src->phys_addr = 0;
- if (!chainup_buffers(req->src, nbytes, req_ctx->src, flags))
+ req_ctx->src = NULL;
+ if (!chainup_buffers(dev, req->src, nbytes, &src_hook,
+ flags, src_direction))
goto free_buf_src;
+ req_ctx->src = src_hook.next;
+ crypt->src_buf = src_hook.phys_next;
crypt->ctl_flags |= CTL_FLAG_PERFORM_ABLK;
qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt));
BUG_ON(qmgr_stat_overflow(SEND_QID));
return -EINPROGRESS;
free_buf_src:
- free_buf_chain(req_ctx->src, crypt->src_buf);
-unmap_sg_src:
- dma_unmap_sg(dev, req->src, req_ctx->src_nents, src_direction);
+ free_buf_chain(dev, req_ctx->src, crypt->src_buf);
free_buf_dest:
if (req->src != req->dst) {
- free_buf_chain(req_ctx->dst, crypt->dst_buf);
-unmap_sg_dest:
- dma_unmap_sg(dev, req->src, req_ctx->dst_nents,
- DMA_FROM_DEVICE);
+ free_buf_chain(dev, req_ctx->dst, crypt->dst_buf);
}
crypt->ctl_flags = CTL_FLAG_UNUSED;
- return ret;
+ return -ENOMEM;
}
static int ablk_encrypt(struct ablkcipher_request *req)
@@ -985,7 +939,7 @@ static int hmac_inconsistent(struct scatterlist *sg, unsigned start,
break;
offset += sg->length;
- sg = sg_next(sg);
+ sg = scatterwalk_sg_next(sg);
}
return (start + nbytes > offset + sg->length);
}
@@ -997,11 +951,10 @@ static int aead_perform(struct aead_request *req, int encrypt,
struct ixp_ctx *ctx = crypto_aead_ctx(tfm);
unsigned ivsize = crypto_aead_ivsize(tfm);
unsigned authsize = crypto_aead_authsize(tfm);
- int ret = -ENOMEM;
struct ix_sa_dir *dir;
struct crypt_ctl *crypt;
- unsigned int cryptlen, nents;
- struct buffer_desc *buf;
+ unsigned int cryptlen;
+ struct buffer_desc *buf, src_hook;
struct aead_ctx *req_ctx = aead_request_ctx(req);
gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
GFP_KERNEL : GFP_ATOMIC;
@@ -1022,7 +975,7 @@ static int aead_perform(struct aead_request *req, int encrypt,
}
crypt = get_crypt_desc();
if (!crypt)
- return ret;
+ return -ENOMEM;
crypt->data.aead_req = req;
crypt->crypto_ctx = dir->npe_ctx_phys;
@@ -1041,31 +994,27 @@ static int aead_perform(struct aead_request *req, int encrypt,
BUG(); /* -ENOTSUP because of my lazyness */
}
- req_ctx->buffer = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf);
- if (!req_ctx->buffer)
- goto out;
- req_ctx->buffer->phys_addr = 0;
/* ASSOC data */
- nents = count_sg(req->assoc, req->assoclen);
- req_ctx->assoc_nents = nents;
- dma_map_sg(dev, req->assoc, nents, DMA_TO_DEVICE);
- buf = chainup_buffers(req->assoc, req->assoclen, req_ctx->buffer,flags);
+ buf = chainup_buffers(dev, req->assoc, req->assoclen, &src_hook,
+ flags, DMA_TO_DEVICE);
+ req_ctx->buffer = src_hook.next;
+ crypt->src_buf = src_hook.phys_next;
if (!buf)
- goto unmap_sg_assoc;
+ goto out;
/* IV */
sg_init_table(&req_ctx->ivlist, 1);
sg_set_buf(&req_ctx->ivlist, iv, ivsize);
- dma_map_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
- buf = chainup_buffers(&req_ctx->ivlist, ivsize, buf, flags);
+ buf = chainup_buffers(dev, &req_ctx->ivlist, ivsize, buf, flags,
+ DMA_BIDIRECTIONAL);
if (!buf)
- goto unmap_sg_iv;
+ goto free_chain;
if (unlikely(hmac_inconsistent(req->src, cryptlen, authsize))) {
/* The 12 hmac bytes are scattered,
* we need to copy them into a safe buffer */
req_ctx->hmac_virt = dma_pool_alloc(buffer_pool, flags,
&crypt->icv_rev_aes);
if (unlikely(!req_ctx->hmac_virt))
- goto unmap_sg_iv;
+ goto free_chain;
if (!encrypt) {
scatterwalk_map_and_copy(req_ctx->hmac_virt,
req->src, cryptlen, authsize, 0);
@@ -1075,33 +1024,28 @@ static int aead_perform(struct aead_request *req, int encrypt,
req_ctx->hmac_virt = NULL;
}
/* Crypt */
- nents = count_sg(req->src, cryptlen + authsize);
- req_ctx->src_nents = nents;
- dma_map_sg(dev, req->src, nents, DMA_BIDIRECTIONAL);
- buf = chainup_buffers(req->src, cryptlen + authsize, buf, flags);
+ buf = chainup_buffers(dev, req->src, cryptlen + authsize, buf, flags,
+ DMA_BIDIRECTIONAL);
if (!buf)
- goto unmap_sg_src;
+ goto free_hmac_virt;
if (!req_ctx->hmac_virt) {
crypt->icv_rev_aes = buf->phys_addr + buf->buf_len - authsize;
}
+
crypt->ctl_flags |= CTL_FLAG_PERFORM_AEAD;
qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt));
BUG_ON(qmgr_stat_overflow(SEND_QID));
return -EINPROGRESS;
-unmap_sg_src:
- dma_unmap_sg(dev, req->src, req_ctx->src_nents, DMA_BIDIRECTIONAL);
+free_hmac_virt:
if (req_ctx->hmac_virt) {
dma_pool_free(buffer_pool, req_ctx->hmac_virt,
crypt->icv_rev_aes);
}
-unmap_sg_iv:
- dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
-unmap_sg_assoc:
- dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents, DMA_TO_DEVICE);
- free_buf_chain(req_ctx->buffer, crypt->src_buf);
+free_chain:
+ free_buf_chain(dev, req_ctx->buffer, crypt->src_buf);
out:
crypt->ctl_flags = CTL_FLAG_UNUSED;
- return ret;
+ return -ENOMEM;
}
static int aead_setup(struct crypto_aead *tfm, unsigned int authsize)
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 48ea59e7967..3b3c01b6f1e 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -98,6 +98,17 @@ config NET_DMA
Say Y here if you enabled INTEL_IOATDMA or FSL_DMA, otherwise
say N.
+config ASYNC_TX_DMA
+ bool "Async_tx: Offload support for the async_tx api"
+ depends on DMA_ENGINE
+ help
+ This allows the async_tx api to take advantage of offload engines for
+ memcpy, memset, xor, and raid6 p+q operations. If your platform has
+ a dma engine that can perform raid operations and you have enabled
+ MD_RAID456 say Y.
+
+ If unsure, say N.
+
config DMATEST
tristate "DMA Test client"
depends on DMA_ENGINE
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 280a9d263eb..92438e9dacc 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -507,6 +507,7 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v
* published in the general-purpose allocator
*/
dma_cap_set(DMA_PRIVATE, device->cap_mask);
+ device->privatecnt++;
err = dma_chan_get(chan);
if (err == -ENODEV) {
@@ -518,6 +519,8 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v
dma_chan_name(chan), err);
else
break;
+ if (--device->privatecnt == 0)
+ dma_cap_clear(DMA_PRIVATE, device->cap_mask);
chan->private = NULL;
chan = NULL;
}
@@ -537,6 +540,9 @@ void dma_release_channel(struct dma_chan *chan)
WARN_ONCE(chan->client_count != 1,
"chan reference count %d != 1\n", chan->client_count);
dma_chan_put(chan);
+ /* drop PRIVATE cap enabled by __dma_request_channel() */
+ if (--chan->device->privatecnt == 0)
+ dma_cap_clear(DMA_PRIVATE, chan->device->cap_mask);
chan->private = NULL;
mutex_unlock(&dma_list_mutex);
}
@@ -602,6 +608,24 @@ void dmaengine_put(void)
}
EXPORT_SYMBOL(dmaengine_put);
+static int get_dma_id(struct dma_device *device)
+{
+ int rc;
+
+ idr_retry:
+ if (!idr_pre_get(&dma_idr, GFP_KERNEL))
+ return -ENOMEM;
+ mutex_lock(&dma_list_mutex);
+ rc = idr_get_new(&dma_idr, NULL, &device->dev_id);
+ mutex_unlock(&dma_list_mutex);
+ if (rc == -EAGAIN)
+ goto idr_retry;
+ else if (rc != 0)
+ return rc;
+
+ return 0;
+}
+
/**
* dma_async_device_register - registers DMA devices found
* @device: &dma_device
@@ -640,27 +664,25 @@ int dma_async_device_register(struct dma_device *device)
idr_ref = kmalloc(sizeof(*idr_ref), GFP_KERNEL);
if (!idr_ref)
return -ENOMEM;
- atomic_set(idr_ref, 0);
- idr_retry:
- if (!idr_pre_get(&dma_idr, GFP_KERNEL))
- return -ENOMEM;
- mutex_lock(&dma_list_mutex);
- rc = idr_get_new(&dma_idr, NULL, &device->dev_id);
- mutex_unlock(&dma_list_mutex);
- if (rc == -EAGAIN)
- goto idr_retry;
- else if (rc != 0)
+ rc = get_dma_id(device);
+ if (rc != 0) {
+ kfree(idr_ref);
return rc;
+ }
+
+ atomic_set(idr_ref, 0);
/* represent channels in sysfs. Probably want devs too */
list_for_each_entry(chan, &device->channels, device_node) {
+ rc = -ENOMEM;
chan->local = alloc_percpu(typeof(*chan->local));
if (chan->local == NULL)
- continue;
+ goto err_out;
chan->dev = kzalloc(sizeof(*chan->dev), GFP_KERNEL);
if (chan->dev == NULL) {
free_percpu(chan->local);
- continue;
+ chan->local = NULL;
+ goto err_out;
}
chan->chan_id = chancnt++;
@@ -677,6 +699,8 @@ int dma_async_device_register(struct dma_device *device)
if (rc) {
free_percpu(chan->local);
chan->local = NULL;
+ kfree(chan->dev);
+ atomic_dec(idr_ref);
goto err_out;
}
chan->client_count = 0;
@@ -701,12 +725,23 @@ int dma_async_device_register(struct dma_device *device)
}
}
list_add_tail_rcu(&device->global_node, &dma_device_list);
+ if (dma_has_cap(DMA_PRIVATE, device->cap_mask))
+ device->privatecnt++; /* Always private */
dma_channel_rebalance();
mutex_unlock(&dma_list_mutex);
return 0;
err_out:
+ /* if we never registered a channel just release the idr */
+ if (atomic_read(idr_ref) == 0) {
+ mutex_lock(&dma_list_mutex);
+ idr_remove(&dma_idr, device->dev_id);
+ mutex_unlock(&dma_list_mutex);
+ kfree(idr_ref);
+ return rc;
+ }
+
list_for_each_entry(chan, &device->channels, device_node) {
if (chan->local == NULL)
continue;
@@ -893,6 +928,7 @@ void dma_async_tx_descriptor_init(struct dma_async_tx_descriptor *tx,
{
tx->chan = chan;
spin_lock_init(&tx->lock);
+ INIT_LIST_HEAD(&tx->tx_list);
}
EXPORT_SYMBOL(dma_async_tx_descriptor_init);
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index e190d8b3070..a27c0fb1bc1 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -38,6 +38,11 @@ module_param(max_channels, uint, S_IRUGO);
MODULE_PARM_DESC(max_channels,
"Maximum number of channels to use (default: all)");
+static unsigned int xor_sources = 3;
+module_param(xor_sources, uint, S_IRUGO);
+MODULE_PARM_DESC(xor_sources,
+ "Number of xor source buffers (default: 3)");
+
/*
* Initialization patterns. All bytes in the source buffer has bit 7
* set, all bytes in the destination buffer has bit 7 cleared.
@@ -59,8 +64,9 @@ struct dmatest_thread {
struct list_head node;
struct task_struct *task;
struct dma_chan *chan;
- u8 *srcbuf;
- u8 *dstbuf;
+ u8 **srcs;
+ u8 **dsts;
+ enum dma_transaction_type type;
};
struct dmatest_chan {
@@ -98,30 +104,37 @@ static unsigned long dmatest_random(void)
return buf;
}
-static void dmatest_init_srcbuf(u8 *buf, unsigned int start, unsigned int len)
+static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len)
{
unsigned int i;
-
- for (i = 0; i < start; i++)
- buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
- for ( ; i < start + len; i++)
- buf[i] = PATTERN_SRC | PATTERN_COPY
- | (~i & PATTERN_COUNT_MASK);;
- for ( ; i < test_buf_size; i++)
- buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+ u8 *buf;
+
+ for (; (buf = *bufs); bufs++) {
+ for (i = 0; i < start; i++)
+ buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+ for ( ; i < start + len; i++)
+ buf[i] = PATTERN_SRC | PATTERN_COPY
+ | (~i & PATTERN_COUNT_MASK);;
+ for ( ; i < test_buf_size; i++)
+ buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+ buf++;
+ }
}
-static void dmatest_init_dstbuf(u8 *buf, unsigned int start, unsigned int len)
+static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len)
{
unsigned int i;
-
- for (i = 0; i < start; i++)
- buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
- for ( ; i < start + len; i++)
- buf[i] = PATTERN_DST | PATTERN_OVERWRITE
- | (~i & PATTERN_COUNT_MASK);
- for ( ; i < test_buf_size; i++)
- buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+ u8 *buf;
+
+ for (; (buf = *bufs); bufs++) {
+ for (i = 0; i < start; i++)
+ buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+ for ( ; i < start + len; i++)
+ buf[i] = PATTERN_DST | PATTERN_OVERWRITE
+ | (~i & PATTERN_COUNT_MASK);
+ for ( ; i < test_buf_size; i++)
+ buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+ }
}
static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
@@ -150,23 +163,30 @@ static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
thread_name, index, expected, actual);
}
-static unsigned int dmatest_verify(u8 *buf, unsigned int start,
+static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
unsigned int end, unsigned int counter, u8 pattern,
bool is_srcbuf)
{
unsigned int i;
unsigned int error_count = 0;
u8 actual;
-
- for (i = start; i < end; i++) {
- actual = buf[i];
- if (actual != (pattern | (~counter & PATTERN_COUNT_MASK))) {
- if (error_count < 32)
- dmatest_mismatch(actual, pattern, i, counter,
- is_srcbuf);
- error_count++;
+ u8 expected;
+ u8 *buf;
+ unsigned int counter_orig = counter;
+
+ for (; (buf = *bufs); bufs++) {
+ counter = counter_orig;
+ for (i = start; i < end; i++) {
+ actual = buf[i];
+ expected = pattern | (~counter & PATTERN_COUNT_MASK);
+ if (actual != expected) {
+ if (error_count < 32)
+ dmatest_mismatch(actual, pattern, i,
+ counter, is_srcbuf);
+ error_count++;
+ }
+ counter++;
}
- counter++;
}
if (error_count > 32)
@@ -176,12 +196,17 @@ static unsigned int dmatest_verify(u8 *buf, unsigned int start,
return error_count;
}
+static void dmatest_callback(void *completion)
+{
+ complete(completion);
+}
+
/*
* This function repeatedly tests DMA transfers of various lengths and
- * offsets until it is told to exit by kthread_stop(). There may be
- * multiple threads running this function in parallel for a single
- * channel, and there may be multiple channels being tested in
- * parallel.
+ * offsets for a given operation type until it is told to exit by
+ * kthread_stop(). There may be multiple threads running this function
+ * in parallel for a single channel, and there may be multiple channels
+ * being tested in parallel.
*
* Before each test, the source and destination buffer is initialized
* with a known pattern. This pattern is different depending on
@@ -201,25 +226,57 @@ static int dmatest_func(void *data)
unsigned int total_tests = 0;
dma_cookie_t cookie;
enum dma_status status;
+ enum dma_ctrl_flags flags;
int ret;
+ int src_cnt;
+ int dst_cnt;
+ int i;
thread_name = current->comm;
ret = -ENOMEM;
- thread->srcbuf = kmalloc(test_buf_size, GFP_KERNEL);
- if (!thread->srcbuf)
- goto err_srcbuf;
- thread->dstbuf = kmalloc(test_buf_size, GFP_KERNEL);
- if (!thread->dstbuf)
- goto err_dstbuf;
smp_rmb();
chan = thread->chan;
+ if (thread->type == DMA_MEMCPY)
+ src_cnt = dst_cnt = 1;
+ else if (thread->type == DMA_XOR) {
+ src_cnt = xor_sources | 1; /* force odd to ensure dst = src */
+ dst_cnt = 1;
+ } else
+ goto err_srcs;
+
+ thread->srcs = kcalloc(src_cnt+1, sizeof(u8 *), GFP_KERNEL);
+ if (!thread->srcs)
+ goto err_srcs;
+ for (i = 0; i < src_cnt; i++) {
+ thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL);
+ if (!thread->srcs[i])
+ goto err_srcbuf;
+ }
+ thread->srcs[i] = NULL;
+
+ thread->dsts = kcalloc(dst_cnt+1, sizeof(u8 *), GFP_KERNEL);
+ if (!thread->dsts)
+ goto err_dsts;
+ for (i = 0; i < dst_cnt; i++) {
+ thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL);
+ if (!thread->dsts[i])
+ goto err_dstbuf;
+ }
+ thread->dsts[i] = NULL;
+
+ set_user_nice(current, 10);
+
+ flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT;
while (!kthread_should_stop()) {
struct dma_device *dev = chan->device;
- struct dma_async_tx_descriptor *tx;
- dma_addr_t dma_src, dma_dest;
+ struct dma_async_tx_descriptor *tx = NULL;
+ dma_addr_t dma_srcs[src_cnt];
+ dma_addr_t dma_dsts[dst_cnt];
+ struct completion cmp;
+ unsigned long tmo = msecs_to_jiffies(3000);
total_tests++;
@@ -227,22 +284,41 @@ static int dmatest_func(void *data)
src_off = dmatest_random() % (test_buf_size - len + 1);
dst_off = dmatest_random() % (test_buf_size - len + 1);
- dmatest_init_srcbuf(thread->srcbuf, src_off, len);
- dmatest_init_dstbuf(thread->dstbuf, dst_off, len);
+ dmatest_init_srcs(thread->srcs, src_off, len);
+ dmatest_init_dsts(thread->dsts, dst_off, len);
- dma_src = dma_map_single(dev->dev, thread->srcbuf + src_off,
- len, DMA_TO_DEVICE);
+ for (i = 0; i < src_cnt; i++) {
+ u8 *buf = thread->srcs[i] + src_off;
+
+ dma_srcs[i] = dma_map_single(dev->dev, buf, len,
+ DMA_TO_DEVICE);
+ }
/* map with DMA_BIDIRECTIONAL to force writeback/invalidate */
- dma_dest = dma_map_single(dev->dev, thread->dstbuf,
- test_buf_size, DMA_BIDIRECTIONAL);
+ for (i = 0; i < dst_cnt; i++) {
+ dma_dsts[i] = dma_map_single(dev->dev, thread->dsts[i],
+ test_buf_size,
+ DMA_BIDIRECTIONAL);
+ }
+
+ if (thread->type == DMA_MEMCPY)
+ tx = dev->device_prep_dma_memcpy(chan,
+ dma_dsts[0] + dst_off,
+ dma_srcs[0], len,
+ flags);
+ else if (thread->type == DMA_XOR)
+ tx = dev->device_prep_dma_xor(chan,
+ dma_dsts[0] + dst_off,
+ dma_srcs, xor_sources,
+ len, flags);
- tx = dev->device_prep_dma_memcpy(chan, dma_dest + dst_off,
- dma_src, len,
- DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP);
if (!tx) {
- dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
- dma_unmap_single(dev->dev, dma_dest,
- test_buf_size, DMA_BIDIRECTIONAL);
+ for (i = 0; i < src_cnt; i++)
+ dma_unmap_single(dev->dev, dma_srcs[i], len,
+ DMA_TO_DEVICE);
+ for (i = 0; i < dst_cnt; i++)
+ dma_unmap_single(dev->dev, dma_dsts[i],
+ test_buf_size,
+ DMA_BIDIRECTIONAL);
pr_warning("%s: #%u: prep error with src_off=0x%x "
"dst_off=0x%x len=0x%x\n",
thread_name, total_tests - 1,
@@ -251,7 +327,10 @@ static int dmatest_func(void *data)
failed_tests++;
continue;
}
- tx->callback = NULL;
+
+ init_completion(&cmp);
+ tx->callback = dmatest_callback;
+ tx->callback_param = &cmp;
cookie = tx->tx_submit(tx);
if (dma_submit_error(cookie)) {
@@ -263,44 +342,50 @@ static int dmatest_func(void *data)
failed_tests++;
continue;
}
- dma_async_memcpy_issue_pending(chan);
+ dma_async_issue_pending(chan);
- do {
- msleep(1);
- status = dma_async_memcpy_complete(
- chan, cookie, NULL, NULL);
- } while (status == DMA_IN_PROGRESS);
+ tmo = wait_for_completion_timeout(&cmp, tmo);
+ status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
- if (status == DMA_ERROR) {
- pr_warning("%s: #%u: error during copy\n",
- thread_name, total_tests - 1);
+ if (tmo == 0) {
+ pr_warning("%s: #%u: test timed out\n",
+ thread_name, total_tests - 1);
+ failed_tests++;
+ continue;
+ } else if (status != DMA_SUCCESS) {
+ pr_warning("%s: #%u: got completion callback,"
+ " but status is \'%s\'\n",
+ thread_name, total_tests - 1,
+ status == DMA_ERROR ? "error" : "in progress");
failed_tests++;
continue;
}
+
/* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */
- dma_unmap_single(dev->dev, dma_dest,
- test_buf_size, DMA_BIDIRECTIONAL);
+ for (i = 0; i < dst_cnt; i++)
+ dma_unmap_single(dev->dev, dma_dsts[i], test_buf_size,
+ DMA_BIDIRECTIONAL);
error_count = 0;
pr_debug("%s: verifying source buffer...\n", thread_name);
- error_count += dmatest_verify(thread->srcbuf, 0, src_off,
+ error_count += dmatest_verify(thread->srcs, 0, src_off,
0, PATTERN_SRC, true);
- error_count += dmatest_verify(thread->srcbuf, src_off,
+ error_count += dmatest_verify(thread->srcs, src_off,
src_off + len, src_off,
PATTERN_SRC | PATTERN_COPY, true);
- error_count += dmatest_verify(thread->srcbuf, src_off + len,
+ error_count += dmatest_verify(thread->srcs, src_off + len,
test_buf_size, src_off + len,
PATTERN_SRC, true);
pr_debug("%s: verifying dest buffer...\n",
thread->task->comm);
- error_count += dmatest_verify(thread->dstbuf, 0, dst_off,
+ error_count += dmatest_verify(thread->dsts, 0, dst_off,
0, PATTERN_DST, false);
- error_count += dmatest_verify(thread->dstbuf, dst_off,
+ error_count += dmatest_verify(thread->dsts, dst_off,
dst_off + len, src_off,
PATTERN_SRC | PATTERN_COPY, false);
- error_count += dmatest_verify(thread->dstbuf, dst_off + len,
+ error_count += dmatest_verify(thread->dsts, dst_off + len,
test_buf_size, dst_off + len,
PATTERN_DST, false);
@@ -319,10 +404,16 @@ static int dmatest_func(void *data)
}
ret = 0;
- kfree(thread->dstbuf);
+ for (i = 0; thread->dsts[i]; i++)
+ kfree(thread->dsts[i]);
err_dstbuf:
- kfree(thread->srcbuf);
+ kfree(thread->dsts);
+err_dsts:
+ for (i = 0; thread->srcs[i]; i++)
+ kfree(thread->srcs[i]);
err_srcbuf:
+ kfree(thread->srcs);
+err_srcs:
pr_notice("%s: terminating after %u tests, %u failures (status %d)\n",
thread_name, total_tests, failed_tests, ret);
return ret;
@@ -344,35 +435,36 @@ static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
kfree(dtc);
}
-static int dmatest_add_channel(struct dma_chan *chan)
+static int dmatest_add_threads(struct dmatest_chan *dtc, enum dma_transaction_type type)
{
- struct dmatest_chan *dtc;
- struct dmatest_thread *thread;
- unsigned int i;
-
- dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
- if (!dtc) {
- pr_warning("dmatest: No memory for %s\n", dma_chan_name(chan));
- return -ENOMEM;
- }
+ struct dmatest_thread *thread;
+ struct dma_chan *chan = dtc->chan;
+ char *op;
+ unsigned int i;
- dtc->chan = chan;
- INIT_LIST_HEAD(&dtc->threads);
+ if (type == DMA_MEMCPY)
+ op = "copy";
+ else if (type == DMA_XOR)
+ op = "xor";
+ else
+ return -EINVAL;
for (i = 0; i < threads_per_chan; i++) {
thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL);
if (!thread) {
- pr_warning("dmatest: No memory for %s-test%u\n",
- dma_chan_name(chan), i);
+ pr_warning("dmatest: No memory for %s-%s%u\n",
+ dma_chan_name(chan), op, i);
+
break;
}
thread->chan = dtc->chan;
+ thread->type = type;
smp_wmb();
- thread->task = kthread_run(dmatest_func, thread, "%s-test%u",
- dma_chan_name(chan), i);
+ thread->task = kthread_run(dmatest_func, thread, "%s-%s%u",
+ dma_chan_name(chan), op, i);
if (IS_ERR(thread->task)) {
- pr_warning("dmatest: Failed to run thread %s-test%u\n",
- dma_chan_name(chan), i);
+ pr_warning("dmatest: Failed to run thread %s-%s%u\n",
+ dma_chan_name(chan), op, i);
kfree(thread);
break;
}
@@ -382,7 +474,36 @@ static int dmatest_add_channel(struct dma_chan *chan)
list_add_tail(&thread->node, &dtc->threads);
}
- pr_info("dmatest: Started %u threads using %s\n", i, dma_chan_name(chan));
+ return i;
+}
+
+static int dmatest_add_channel(struct dma_chan *chan)
+{
+ struct dmatest_chan *dtc;
+ struct dma_device *dma_dev = chan->device;
+ unsigned int thread_count = 0;
+ unsigned int cnt;
+
+ dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
+ if (!dtc) {
+ pr_warning("dmatest: No memory for %s\n", dma_chan_name(chan));
+ return -ENOMEM;
+ }
+
+ dtc->chan = chan;
+ INIT_LIST_HEAD(&dtc->threads);
+
+ if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
+ cnt = dmatest_add_threads(dtc, DMA_MEMCPY);
+ thread_count += cnt > 0 ?: 0;
+ }
+ if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
+ cnt = dmatest_add_threads(dtc, DMA_XOR);
+ thread_count += cnt > 0 ?: 0;
+ }
+
+ pr_info("dmatest: Started %u threads using %s\n",
+ thread_count, dma_chan_name(chan));
list_add_tail(&dtc->node, &dmatest_channels);
nr_channels++;
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 20ad3d26bec..98c9a847bf5 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -363,6 +363,82 @@ static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc)
dwc_descriptor_complete(dwc, bad_desc);
}
+/* --------------------- Cyclic DMA API extensions -------------------- */
+
+inline dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ return channel_readl(dwc, SAR);
+}
+EXPORT_SYMBOL(dw_dma_get_src_addr);
+
+inline dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ return channel_readl(dwc, DAR);
+}
+EXPORT_SYMBOL(dw_dma_get_dst_addr);
+
+/* called with dwc->lock held and all DMAC interrupts disabled */
+static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
+ u32 status_block, u32 status_err, u32 status_xfer)
+{
+ if (status_block & dwc->mask) {
+ void (*callback)(void *param);
+ void *callback_param;
+
+ dev_vdbg(chan2dev(&dwc->chan), "new cyclic period llp 0x%08x\n",
+ channel_readl(dwc, LLP));
+ dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+
+ callback = dwc->cdesc->period_callback;
+ callback_param = dwc->cdesc->period_callback_param;
+ if (callback) {
+ spin_unlock(&dwc->lock);
+ callback(callback_param);
+ spin_lock(&dwc->lock);
+ }
+ }
+
+ /*
+ * Error and transfer complete are highly unlikely, and will most
+ * likely be due to a configuration error by the user.
+ */
+ if (unlikely(status_err & dwc->mask) ||
+ unlikely(status_xfer & dwc->mask)) {
+ int i;
+
+ dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s "
+ "interrupt, stopping DMA transfer\n",
+ status_xfer ? "xfer" : "error");
+ dev_err(chan2dev(&dwc->chan),
+ " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+ channel_readl(dwc, SAR),
+ channel_readl(dwc, DAR),
+ channel_readl(dwc, LLP),
+ channel_readl(dwc, CTL_HI),
+ channel_readl(dwc, CTL_LO));
+
+ channel_clear_bit(dw, CH_EN, dwc->mask);
+ while (dma_readl(dw, CH_EN) & dwc->mask)
+ cpu_relax();
+
+ /* make sure DMA does not restart by loading a new list */
+ channel_writel(dwc, LLP, 0);
+ channel_writel(dwc, CTL_LO, 0);
+ channel_writel(dwc, CTL_HI, 0);
+
+ dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+ dma_writel(dw, CLEAR.ERROR, dwc->mask);
+ dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+ for (i = 0; i < dwc->cdesc->periods; i++)
+ dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
static void dw_dma_tasklet(unsigned long data)
{
struct dw_dma *dw = (struct dw_dma *)data;
@@ -382,7 +458,10 @@ static void dw_dma_tasklet(unsigned long data)
for (i = 0; i < dw->dma.chancnt; i++) {
dwc = &dw->chan[i];
spin_lock(&dwc->lock);
- if (status_err & (1 << i))
+ if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags))
+ dwc_handle_cyclic(dw, dwc, status_block, status_err,
+ status_xfer);
+ else if (status_err & (1 << i))
dwc_handle_error(dw, dwc);
else if ((status_block | status_xfer) & (1 << i))
dwc_scan_descriptors(dw, dwc);
@@ -826,7 +905,6 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
dma_async_tx_descriptor_init(&desc->txd, chan);
desc->txd.tx_submit = dwc_tx_submit;
desc->txd.flags = DMA_CTRL_ACK;
- INIT_LIST_HEAD(&desc->txd.tx_list);
desc->txd.phys = dma_map_single(chan2parent(chan), &desc->lli,
sizeof(desc->lli), DMA_TO_DEVICE);
dwc_desc_put(dwc, desc);
@@ -884,6 +962,257 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
dev_vdbg(chan2dev(chan), "free_chan_resources done\n");
}
+/* --------------------- Cyclic DMA API extensions -------------------- */
+
+/**
+ * dw_dma_cyclic_start - start the cyclic DMA transfer
+ * @chan: the DMA channel to start
+ *
+ * Must be called with soft interrupts disabled. Returns zero on success or
+ * -errno on failure.
+ */
+int dw_dma_cyclic_start(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+
+ if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
+ dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n");
+ return -ENODEV;
+ }
+
+ spin_lock(&dwc->lock);
+
+ /* assert channel is idle */
+ if (dma_readl(dw, CH_EN) & dwc->mask) {
+ dev_err(chan2dev(&dwc->chan),
+ "BUG: Attempted to start non-idle channel\n");
+ dev_err(chan2dev(&dwc->chan),
+ " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+ channel_readl(dwc, SAR),
+ channel_readl(dwc, DAR),
+ channel_readl(dwc, LLP),
+ channel_readl(dwc, CTL_HI),
+ channel_readl(dwc, CTL_LO));
+ spin_unlock(&dwc->lock);
+ return -EBUSY;
+ }
+
+ dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+ dma_writel(dw, CLEAR.ERROR, dwc->mask);
+ dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+ /* setup DMAC channel registers */
+ channel_writel(dwc, LLP, dwc->cdesc->desc[0]->txd.phys);
+ channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
+ channel_writel(dwc, CTL_HI, 0);
+
+ channel_set_bit(dw, CH_EN, dwc->mask);
+
+ spin_unlock(&dwc->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(dw_dma_cyclic_start);
+
+/**
+ * dw_dma_cyclic_stop - stop the cyclic DMA transfer
+ * @chan: the DMA channel to stop
+ *
+ * Must be called with soft interrupts disabled.
+ */
+void dw_dma_cyclic_stop(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+
+ spin_lock(&dwc->lock);
+
+ channel_clear_bit(dw, CH_EN, dwc->mask);
+ while (dma_readl(dw, CH_EN) & dwc->mask)
+ cpu_relax();
+
+ spin_unlock(&dwc->lock);
+}
+EXPORT_SYMBOL(dw_dma_cyclic_stop);
+
+/**
+ * dw_dma_cyclic_prep - prepare the cyclic DMA transfer
+ * @chan: the DMA channel to prepare
+ * @buf_addr: physical DMA address where the buffer starts
+ * @buf_len: total number of bytes for the entire buffer
+ * @period_len: number of bytes for each period
+ * @direction: transfer direction, to or from device
+ *
+ * Must be called before trying to start the transfer. Returns a valid struct
+ * dw_cyclic_desc if successful or an ERR_PTR(-errno) if not successful.
+ */
+struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
+ dma_addr_t buf_addr, size_t buf_len, size_t period_len,
+ enum dma_data_direction direction)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_cyclic_desc *cdesc;
+ struct dw_cyclic_desc *retval = NULL;
+ struct dw_desc *desc;
+ struct dw_desc *last = NULL;
+ struct dw_dma_slave *dws = chan->private;
+ unsigned long was_cyclic;
+ unsigned int reg_width;
+ unsigned int periods;
+ unsigned int i;
+
+ spin_lock_bh(&dwc->lock);
+ if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) {
+ spin_unlock_bh(&dwc->lock);
+ dev_dbg(chan2dev(&dwc->chan),
+ "queue and/or active list are not empty\n");
+ return ERR_PTR(-EBUSY);
+ }
+
+ was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+ spin_unlock_bh(&dwc->lock);
+ if (was_cyclic) {
+ dev_dbg(chan2dev(&dwc->chan),
+ "channel already prepared for cyclic DMA\n");
+ return ERR_PTR(-EBUSY);
+ }
+
+ retval = ERR_PTR(-EINVAL);
+ reg_width = dws->reg_width;
+ periods = buf_len / period_len;
+
+ /* Check for too big/unaligned periods and unaligned DMA buffer. */
+ if (period_len > (DWC_MAX_COUNT << reg_width))
+ goto out_err;
+ if (unlikely(period_len & ((1 << reg_width) - 1)))
+ goto out_err;
+ if (unlikely(buf_addr & ((1 << reg_width) - 1)))
+ goto out_err;
+ if (unlikely(!(direction & (DMA_TO_DEVICE | DMA_FROM_DEVICE))))
+ goto out_err;
+
+ retval = ERR_PTR(-ENOMEM);
+
+ if (periods > NR_DESCS_PER_CHANNEL)
+ goto out_err;
+
+ cdesc = kzalloc(sizeof(struct dw_cyclic_desc), GFP_KERNEL);
+ if (!cdesc)
+ goto out_err;
+
+ cdesc->desc = kzalloc(sizeof(struct dw_desc *) * periods, GFP_KERNEL);
+ if (!cdesc->desc)
+ goto out_err_alloc;
+
+ for (i = 0; i < periods; i++) {
+ desc = dwc_desc_get(dwc);
+ if (!desc)
+ goto out_err_desc_get;
+
+ switch (direction) {
+ case DMA_TO_DEVICE:
+ desc->lli.dar = dws->tx_reg;
+ desc->lli.sar = buf_addr + (period_len * i);
+ desc->lli.ctllo = (DWC_DEFAULT_CTLLO
+ | DWC_CTLL_DST_WIDTH(reg_width)
+ | DWC_CTLL_SRC_WIDTH(reg_width)
+ | DWC_CTLL_DST_FIX
+ | DWC_CTLL_SRC_INC
+ | DWC_CTLL_FC_M2P
+ | DWC_CTLL_INT_EN);
+ break;
+ case DMA_FROM_DEVICE:
+ desc->lli.dar = buf_addr + (period_len * i);
+ desc->lli.sar = dws->rx_reg;
+ desc->lli.ctllo = (DWC_DEFAULT_CTLLO
+ | DWC_CTLL_SRC_WIDTH(reg_width)
+ | DWC_CTLL_DST_WIDTH(reg_width)
+ | DWC_CTLL_DST_INC
+ | DWC_CTLL_SRC_FIX
+ | DWC_CTLL_FC_P2M
+ | DWC_CTLL_INT_EN);
+ break;
+ default:
+ break;
+ }
+
+ desc->lli.ctlhi = (period_len >> reg_width);
+ cdesc->desc[i] = desc;
+
+ if (last) {
+ last->lli.llp = desc->txd.phys;
+ dma_sync_single_for_device(chan2parent(chan),
+ last->txd.phys, sizeof(last->lli),
+ DMA_TO_DEVICE);
+ }
+
+ last = desc;
+ }
+
+ /* lets make a cyclic list */
+ last->lli.llp = cdesc->desc[0]->txd.phys;
+ dma_sync_single_for_device(chan2parent(chan), last->txd.phys,
+ sizeof(last->lli), DMA_TO_DEVICE);
+
+ dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%08x len %zu "
+ "period %zu periods %d\n", buf_addr, buf_len,
+ period_len, periods);
+
+ cdesc->periods = periods;
+ dwc->cdesc = cdesc;
+
+ return cdesc;
+
+out_err_desc_get:
+ while (i--)
+ dwc_desc_put(dwc, cdesc->desc[i]);
+out_err_alloc:
+ kfree(cdesc);
+out_err:
+ clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+ return (struct dw_cyclic_desc *)retval;
+}
+EXPORT_SYMBOL(dw_dma_cyclic_prep);
+
+/**
+ * dw_dma_cyclic_free - free a prepared cyclic DMA transfer
+ * @chan: the DMA channel to free
+ */
+void dw_dma_cyclic_free(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+ struct dw_cyclic_desc *cdesc = dwc->cdesc;
+ int i;
+
+ dev_dbg(chan2dev(&dwc->chan), "cyclic free\n");
+
+ if (!cdesc)
+ return;
+
+ spin_lock_bh(&dwc->lock);
+
+ channel_clear_bit(dw, CH_EN, dwc->mask);
+ while (dma_readl(dw, CH_EN) & dwc->mask)
+ cpu_relax();
+
+ dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+ dma_writel(dw, CLEAR.ERROR, dwc->mask);
+ dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+ spin_unlock_bh(&dwc->lock);
+
+ for (i = 0; i < cdesc->periods; i++)
+ dwc_desc_put(dwc, cdesc->desc[i]);
+
+ kfree(cdesc->desc);
+ kfree(cdesc);
+
+ clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+}
+EXPORT_SYMBOL(dw_dma_cyclic_free);
+
/*----------------------------------------------------------------------*/
static void dw_dma_off(struct dw_dma *dw)
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index b252b202c5c..13a58076703 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -126,6 +126,10 @@ struct dw_dma_regs {
#define DW_REGLEN 0x400
+enum dw_dmac_flags {
+ DW_DMA_IS_CYCLIC = 0,
+};
+
struct dw_dma_chan {
struct dma_chan chan;
void __iomem *ch_regs;
@@ -134,10 +138,12 @@ struct dw_dma_chan {
spinlock_t lock;
/* these other elements are all protected by lock */
+ unsigned long flags;
dma_cookie_t completed;
struct list_head active_list;
struct list_head queue;
struct list_head free_list;
+ struct dw_cyclic_desc *cdesc;
unsigned int descs_allocated;
};
@@ -158,7 +164,6 @@ static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan)
return container_of(chan, struct dw_dma_chan, chan);
}
-
struct dw_dma {
struct dma_device dma;
void __iomem *regs;
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 86d6da47f55..da8a8ed9e41 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -354,7 +354,6 @@ static struct fsl_desc_sw *fsl_dma_alloc_descriptor(
dma_async_tx_descriptor_init(&desc_sw->async_tx,
&fsl_chan->common);
desc_sw->async_tx.tx_submit = fsl_dma_tx_submit;
- INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
desc_sw->async_tx.phys = pdesc;
}
diff --git a/drivers/dma/ioat.c b/drivers/dma/ioat.c
index ed83dd9df19..2225bb6ba3d 100644
--- a/drivers/dma/ioat.c
+++ b/drivers/dma/ioat.c
@@ -98,15 +98,15 @@ static int __devinit ioat_probe(struct pci_dev *pdev,
if (err)
goto err_request_regions;
- err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (err)
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err)
goto err_set_dma_mask;
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (err)
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (err)
goto err_set_dma_mask;
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index 5905cd36bcd..e4fc33c1c32 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -693,7 +693,6 @@ static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
desc_sw->async_tx.tx_submit = ioat2_tx_submit;
break;
}
- INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
desc_sw->hw = desc;
desc_sw->async_tx.phys = phys;
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 16adbe61cfb..2f052265122 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -498,7 +498,6 @@ static int iop_adma_alloc_chan_resources(struct dma_chan *chan)
slot->async_tx.tx_submit = iop_adma_tx_submit;
INIT_LIST_HEAD(&slot->chain_node);
INIT_LIST_HEAD(&slot->slot_node);
- INIT_LIST_HEAD(&slot->async_tx.tx_list);
hw_desc = (char *) iop_chan->device->dma_desc_pool;
slot->async_tx.phys =
(dma_addr_t) &hw_desc[idx * IOP_ADMA_SLOT_SIZE];
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index da781d10789..e202a6ce557 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -28,6 +28,9 @@
#define FS_VF_IN_VALID 0x00000002
#define FS_ENC_IN_VALID 0x00000001
+static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
+ bool wait_for_stop);
+
/*
* There can be only one, we could allocate it dynamically, but then we'd have
* to add an extra parameter to some functions, and use something as ugly as
@@ -107,7 +110,7 @@ static uint32_t bytes_per_pixel(enum pixel_fmt fmt)
}
}
-/* Enable / disable direct write to memory by the Camera Sensor Interface */
+/* Enable direct write to memory by the Camera Sensor Interface */
static void ipu_ic_enable_task(struct ipu *ipu, enum ipu_channel channel)
{
uint32_t ic_conf, mask;
@@ -126,6 +129,7 @@ static void ipu_ic_enable_task(struct ipu *ipu, enum ipu_channel channel)
idmac_write_icreg(ipu, ic_conf, IC_CONF);
}
+/* Called under spin_lock_irqsave(&ipu_data.lock) */
static void ipu_ic_disable_task(struct ipu *ipu, enum ipu_channel channel)
{
uint32_t ic_conf, mask;
@@ -422,7 +426,7 @@ static void ipu_ch_param_set_size(union chan_param_mem *params,
break;
default:
dev_err(ipu_data.dev,
- "mxc ipu: unimplemented pixel format %d\n", pixel_fmt);
+ "mx3 ipu: unimplemented pixel format %d\n", pixel_fmt);
break;
}
@@ -433,20 +437,20 @@ static void ipu_ch_param_set_burst_size(union chan_param_mem *params,
uint16_t burst_pixels)
{
params->pp.npb = burst_pixels - 1;
-};
+}
static void ipu_ch_param_set_buffer(union chan_param_mem *params,
dma_addr_t buf0, dma_addr_t buf1)
{
params->pp.eba0 = buf0;
params->pp.eba1 = buf1;
-};
+}
static void ipu_ch_param_set_rotation(union chan_param_mem *params,
enum ipu_rotate_mode rotate)
{
params->pp.bam = rotate;
-};
+}
static void ipu_write_param_mem(uint32_t addr, uint32_t *data,
uint32_t num_words)
@@ -571,7 +575,7 @@ static uint32_t dma_param_addr(uint32_t dma_ch)
{
/* Channel Parameter Memory */
return 0x10000 | (dma_ch << 4);
-};
+}
static void ipu_channel_set_priority(struct ipu *ipu, enum ipu_channel channel,
bool prio)
@@ -611,7 +615,8 @@ static uint32_t ipu_channel_conf_mask(enum ipu_channel channel)
/**
* ipu_enable_channel() - enable an IPU channel.
- * @channel: channel ID.
+ * @idmac: IPU DMAC context.
+ * @ichan: IDMAC channel.
* @return: 0 on success or negative error code on failure.
*/
static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan)
@@ -649,7 +654,7 @@ static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan)
/**
* ipu_init_channel_buffer() - initialize a buffer for logical IPU channel.
- * @channel: channel ID.
+ * @ichan: IDMAC channel.
* @pixel_fmt: pixel format of buffer. Pixel format is a FOURCC ASCII code.
* @width: width of buffer in pixels.
* @height: height of buffer in pixels.
@@ -687,7 +692,7 @@ static int ipu_init_channel_buffer(struct idmac_channel *ichan,
}
/* IC channel's stride must be a multiple of 8 pixels */
- if ((channel <= 13) && (stride % 8)) {
+ if ((channel <= IDMAC_IC_13) && (stride % 8)) {
dev_err(ipu->dev, "Stride must be 8 pixel multiple\n");
return -EINVAL;
}
@@ -752,7 +757,7 @@ static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
/**
* ipu_update_channel_buffer() - update physical address of a channel buffer.
- * @channel: channel ID.
+ * @ichan: IDMAC channel.
* @buffer_n: buffer number to update.
* 0 or 1 are the only valid values.
* @phyaddr: buffer physical address.
@@ -760,9 +765,10 @@ static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
* function will fail if the buffer is set to ready.
*/
/* Called under spin_lock(_irqsave)(&ichan->lock) */
-static int ipu_update_channel_buffer(enum ipu_channel channel,
+static int ipu_update_channel_buffer(struct idmac_channel *ichan,
int buffer_n, dma_addr_t phyaddr)
{
+ enum ipu_channel channel = ichan->dma_chan.chan_id;
uint32_t reg;
unsigned long flags;
@@ -771,8 +777,8 @@ static int ipu_update_channel_buffer(enum ipu_channel channel,
if (buffer_n == 0) {
reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
if (reg & (1UL << channel)) {
- spin_unlock_irqrestore(&ipu_data.lock, flags);
- return -EACCES;
+ ipu_ic_disable_task(&ipu_data, channel);
+ ichan->status = IPU_CHANNEL_READY;
}
/* 44.3.3.1.9 - Row Number 1 (WORD1, offset 0) */
@@ -782,8 +788,8 @@ static int ipu_update_channel_buffer(enum ipu_channel channel,
} else {
reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
if (reg & (1UL << channel)) {
- spin_unlock_irqrestore(&ipu_data.lock, flags);
- return -EACCES;
+ ipu_ic_disable_task(&ipu_data, channel);
+ ichan->status = IPU_CHANNEL_READY;
}
/* Check if double-buffering is already enabled */
@@ -805,6 +811,39 @@ static int ipu_update_channel_buffer(enum ipu_channel channel,
}
/* Called under spin_lock_irqsave(&ichan->lock) */
+static int ipu_submit_buffer(struct idmac_channel *ichan,
+ struct idmac_tx_desc *desc, struct scatterlist *sg, int buf_idx)
+{
+ unsigned int chan_id = ichan->dma_chan.chan_id;
+ struct device *dev = &ichan->dma_chan.dev->device;
+ int ret;
+
+ if (async_tx_test_ack(&desc->txd))
+ return -EINTR;
+
+ /*
+ * On first invocation this shouldn't be necessary, the call to
+ * ipu_init_channel_buffer() above will set addresses for us, so we
+ * could make it conditional on status >= IPU_CHANNEL_ENABLED, but
+ * doing it again shouldn't hurt either.
+ */
+ ret = ipu_update_channel_buffer(ichan, buf_idx,
+ sg_dma_address(sg));
+
+ if (ret < 0) {
+ dev_err(dev, "Updating sg %p on channel 0x%x buffer %d failed!\n",
+ sg, chan_id, buf_idx);
+ return ret;
+ }
+
+ ipu_select_buffer(chan_id, buf_idx);
+ dev_dbg(dev, "Updated sg %p on channel 0x%x buffer %d\n",
+ sg, chan_id, buf_idx);
+
+ return 0;
+}
+
+/* Called under spin_lock_irqsave(&ichan->lock) */
static int ipu_submit_channel_buffers(struct idmac_channel *ichan,
struct idmac_tx_desc *desc)
{
@@ -815,20 +854,10 @@ static int ipu_submit_channel_buffers(struct idmac_channel *ichan,
if (!ichan->sg[i]) {
ichan->sg[i] = sg;
- /*
- * On first invocation this shouldn't be necessary, the
- * call to ipu_init_channel_buffer() above will set
- * addresses for us, so we could make it conditional
- * on status >= IPU_CHANNEL_ENABLED, but doing it again
- * shouldn't hurt either.
- */
- ret = ipu_update_channel_buffer(ichan->dma_chan.chan_id, i,
- sg_dma_address(sg));
+ ret = ipu_submit_buffer(ichan, desc, sg, i);
if (ret < 0)
return ret;
- ipu_select_buffer(ichan->dma_chan.chan_id, i);
-
sg = sg_next(sg);
}
}
@@ -842,19 +871,22 @@ static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
struct idmac_channel *ichan = to_idmac_chan(tx->chan);
struct idmac *idmac = to_idmac(tx->chan->device);
struct ipu *ipu = to_ipu(idmac);
+ struct device *dev = &ichan->dma_chan.dev->device;
dma_cookie_t cookie;
unsigned long flags;
+ int ret;
/* Sanity check */
if (!list_empty(&desc->list)) {
/* The descriptor doesn't belong to client */
- dev_err(&ichan->dma_chan.dev->device,
- "Descriptor %p not prepared!\n", tx);
+ dev_err(dev, "Descriptor %p not prepared!\n", tx);
return -EBUSY;
}
mutex_lock(&ichan->chan_mutex);
+ async_tx_clear_ack(tx);
+
if (ichan->status < IPU_CHANNEL_READY) {
struct idmac_video_param *video = &ichan->params.video;
/*
@@ -878,16 +910,7 @@ static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
goto out;
}
- /* ipu->lock can be taken under ichan->lock, but not v.v. */
- spin_lock_irqsave(&ichan->lock, flags);
-
- /* submit_buffers() atomically verifies and fills empty sg slots */
- cookie = ipu_submit_channel_buffers(ichan, desc);
-
- spin_unlock_irqrestore(&ichan->lock, flags);
-
- if (cookie < 0)
- goto out;
+ dev_dbg(dev, "Submitting sg %p\n", &desc->sg[0]);
cookie = ichan->dma_chan.cookie;
@@ -897,24 +920,40 @@ static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
/* from dmaengine.h: "last cookie value returned to client" */
ichan->dma_chan.cookie = cookie;
tx->cookie = cookie;
+
+ /* ipu->lock can be taken under ichan->lock, but not v.v. */
spin_lock_irqsave(&ichan->lock, flags);
+
list_add_tail(&desc->list, &ichan->queue);
+ /* submit_buffers() atomically verifies and fills empty sg slots */
+ ret = ipu_submit_channel_buffers(ichan, desc);
+
spin_unlock_irqrestore(&ichan->lock, flags);
+ if (ret < 0) {
+ cookie = ret;
+ goto dequeue;
+ }
+
if (ichan->status < IPU_CHANNEL_ENABLED) {
- int ret = ipu_enable_channel(idmac, ichan);
+ ret = ipu_enable_channel(idmac, ichan);
if (ret < 0) {
cookie = ret;
- spin_lock_irqsave(&ichan->lock, flags);
- list_del_init(&desc->list);
- spin_unlock_irqrestore(&ichan->lock, flags);
- tx->cookie = cookie;
- ichan->dma_chan.cookie = cookie;
+ goto dequeue;
}
}
dump_idmac_reg(ipu);
+dequeue:
+ if (cookie < 0) {
+ spin_lock_irqsave(&ichan->lock, flags);
+ list_del_init(&desc->list);
+ spin_unlock_irqrestore(&ichan->lock, flags);
+ tx->cookie = cookie;
+ ichan->dma_chan.cookie = cookie;
+ }
+
out:
mutex_unlock(&ichan->chan_mutex);
@@ -944,8 +983,6 @@ static int idmac_desc_alloc(struct idmac_channel *ichan, int n)
memset(txd, 0, sizeof(*txd));
dma_async_tx_descriptor_init(txd, &ichan->dma_chan);
txd->tx_submit = idmac_tx_submit;
- txd->chan = &ichan->dma_chan;
- INIT_LIST_HEAD(&txd->tx_list);
list_add(&desc->list, &ichan->free_list);
@@ -1161,6 +1198,24 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
return 0;
}
+static struct scatterlist *idmac_sg_next(struct idmac_channel *ichan,
+ struct idmac_tx_desc **desc, struct scatterlist *sg)
+{
+ struct scatterlist *sgnew = sg ? sg_next(sg) : NULL;
+
+ if (sgnew)
+ /* next sg-element in this list */
+ return sgnew;
+
+ if ((*desc)->list.next == &ichan->queue)
+ /* No more descriptors on the queue */
+ return NULL;
+
+ /* Fetch next descriptor */
+ *desc = list_entry((*desc)->list.next, struct idmac_tx_desc, list);
+ return (*desc)->sg;
+}
+
/*
* We have several possibilities here:
* current BUF next BUF
@@ -1176,23 +1231,46 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
static irqreturn_t idmac_interrupt(int irq, void *dev_id)
{
struct idmac_channel *ichan = dev_id;
+ struct device *dev = &ichan->dma_chan.dev->device;
unsigned int chan_id = ichan->dma_chan.chan_id;
struct scatterlist **sg, *sgnext, *sgnew = NULL;
/* Next transfer descriptor */
- struct idmac_tx_desc *desc = NULL, *descnew;
+ struct idmac_tx_desc *desc, *descnew;
dma_async_tx_callback callback;
void *callback_param;
bool done = false;
- u32 ready0 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY),
- ready1 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY),
- curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+ u32 ready0, ready1, curbuf, err;
+ unsigned long flags;
/* IDMAC has cleared the respective BUFx_RDY bit, we manage the buffer */
- pr_debug("IDMAC irq %d\n", irq);
+ dev_dbg(dev, "IDMAC irq %d, buf %d\n", irq, ichan->active_buffer);
+
+ spin_lock_irqsave(&ipu_data.lock, flags);
+
+ ready0 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
+ ready1 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
+ curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+ err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4);
+
+ if (err & (1 << chan_id)) {
+ idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4);
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
+ /*
+ * Doing this
+ * ichan->sg[0] = ichan->sg[1] = NULL;
+ * you can force channel re-enable on the next tx_submit(), but
+ * this is dirty - think about descriptors with multiple
+ * sg elements.
+ */
+ dev_warn(dev, "NFB4EOF on channel %d, ready %x, %x, cur %x\n",
+ chan_id, ready0, ready1, curbuf);
+ return IRQ_HANDLED;
+ }
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
+
/* Other interrupts do not interfere with this channel */
spin_lock(&ichan->lock);
-
if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 &&
((curbuf >> chan_id) & 1) == ichan->active_buffer)) {
int i = 100;
@@ -1207,19 +1285,23 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
if (!i) {
spin_unlock(&ichan->lock);
- dev_dbg(ichan->dma_chan.device->dev,
+ dev_dbg(dev,
"IRQ on active buffer on channel %x, active "
"%d, ready %x, %x, current %x!\n", chan_id,
ichan->active_buffer, ready0, ready1, curbuf);
return IRQ_NONE;
- }
+ } else
+ dev_dbg(dev,
+ "Buffer deactivated on channel %x, active "
+ "%d, ready %x, %x, current %x, rest %d!\n", chan_id,
+ ichan->active_buffer, ready0, ready1, curbuf, i);
}
if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) ||
(!ichan->active_buffer && (ready0 >> chan_id) & 1)
)) {
spin_unlock(&ichan->lock);
- dev_dbg(ichan->dma_chan.device->dev,
+ dev_dbg(dev,
"IRQ with active buffer still ready on channel %x, "
"active %d, ready %x, %x!\n", chan_id,
ichan->active_buffer, ready0, ready1);
@@ -1227,8 +1309,9 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
}
if (unlikely(list_empty(&ichan->queue))) {
+ ichan->sg[ichan->active_buffer] = NULL;
spin_unlock(&ichan->lock);
- dev_err(ichan->dma_chan.device->dev,
+ dev_err(dev,
"IRQ without queued buffers on channel %x, active %d, "
"ready %x, %x!\n", chan_id,
ichan->active_buffer, ready0, ready1);
@@ -1243,40 +1326,44 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
sg = &ichan->sg[ichan->active_buffer];
sgnext = ichan->sg[!ichan->active_buffer];
+ if (!*sg) {
+ spin_unlock(&ichan->lock);
+ return IRQ_HANDLED;
+ }
+
+ desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
+ descnew = desc;
+
+ dev_dbg(dev, "IDMAC irq %d, dma 0x%08x, next dma 0x%08x, current %d, curbuf 0x%08x\n",
+ irq, sg_dma_address(*sg), sgnext ? sg_dma_address(sgnext) : 0, ichan->active_buffer, curbuf);
+
+ /* Find the descriptor of sgnext */
+ sgnew = idmac_sg_next(ichan, &descnew, *sg);
+ if (sgnext != sgnew)
+ dev_err(dev, "Submitted buffer %p, next buffer %p\n", sgnext, sgnew);
+
/*
* if sgnext == NULL sg must be the last element in a scatterlist and
* queue must be empty
*/
if (unlikely(!sgnext)) {
- if (unlikely(sg_next(*sg))) {
- dev_err(ichan->dma_chan.device->dev,
- "Broken buffer-update locking on channel %x!\n",
- chan_id);
- /* We'll let the user catch up */
+ if (!WARN_ON(sg_next(*sg)))
+ dev_dbg(dev, "Underrun on channel %x\n", chan_id);
+ ichan->sg[!ichan->active_buffer] = sgnew;
+
+ if (unlikely(sgnew)) {
+ ipu_submit_buffer(ichan, descnew, sgnew, !ichan->active_buffer);
} else {
- /* Underrun */
+ spin_lock_irqsave(&ipu_data.lock, flags);
ipu_ic_disable_task(&ipu_data, chan_id);
- dev_dbg(ichan->dma_chan.device->dev,
- "Underrun on channel %x\n", chan_id);
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
ichan->status = IPU_CHANNEL_READY;
/* Continue to check for complete descriptor */
}
}
- desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
-
- /* First calculate and submit the next sg element */
- if (likely(sgnext))
- sgnew = sg_next(sgnext);
-
- if (unlikely(!sgnew)) {
- /* Start a new scatterlist, if any queued */
- if (likely(desc->list.next != &ichan->queue)) {
- descnew = list_entry(desc->list.next,
- struct idmac_tx_desc, list);
- sgnew = &descnew->sg[0];
- }
- }
+ /* Calculate and submit the next sg element */
+ sgnew = idmac_sg_next(ichan, &descnew, sgnew);
if (unlikely(!sg_next(*sg)) || !sgnext) {
/*
@@ -1289,17 +1376,13 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
*sg = sgnew;
- if (likely(sgnew)) {
- int ret;
-
- ret = ipu_update_channel_buffer(chan_id, ichan->active_buffer,
- sg_dma_address(*sg));
- if (ret < 0)
- dev_err(ichan->dma_chan.device->dev,
- "Failed to update buffer on channel %x buffer %d!\n",
- chan_id, ichan->active_buffer);
- else
- ipu_select_buffer(chan_id, ichan->active_buffer);
+ if (likely(sgnew) &&
+ ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) {
+ callback = desc->txd.callback;
+ callback_param = desc->txd.callback_param;
+ spin_unlock(&ichan->lock);
+ callback(callback_param);
+ spin_lock(&ichan->lock);
}
/* Flip the active buffer - even if update above failed */
@@ -1327,13 +1410,20 @@ static void ipu_gc_tasklet(unsigned long arg)
struct idmac_channel *ichan = ipu->channel + i;
struct idmac_tx_desc *desc;
unsigned long flags;
- int j;
+ struct scatterlist *sg;
+ int j, k;
for (j = 0; j < ichan->n_tx_desc; j++) {
desc = ichan->desc + j;
spin_lock_irqsave(&ichan->lock, flags);
if (async_tx_test_ack(&desc->txd)) {
list_move(&desc->list, &ichan->free_list);
+ for_each_sg(desc->sg, sg, desc->sg_len, k) {
+ if (ichan->sg[0] == sg)
+ ichan->sg[0] = NULL;
+ else if (ichan->sg[1] == sg)
+ ichan->sg[1] = NULL;
+ }
async_tx_clear_ack(&desc->txd);
}
spin_unlock_irqrestore(&ichan->lock, flags);
@@ -1341,13 +1431,7 @@ static void ipu_gc_tasklet(unsigned long arg)
}
}
-/*
- * At the time .device_alloc_chan_resources() method is called, we cannot know,
- * whether the client will accept the channel. Thus we must only check, if we
- * can satisfy client's request but the only real criterion to verify, whether
- * the client has accepted our offer is the client_count. That's why we have to
- * perform the rest of our allocation tasks on the first call to this function.
- */
+/* Allocate and initialise a transfer descriptor. */
static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan,
struct scatterlist *sgl, unsigned int sg_len,
enum dma_data_direction direction, unsigned long tx_flags)
@@ -1358,8 +1442,8 @@ static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan
unsigned long flags;
/* We only can handle these three channels so far */
- if (ichan->dma_chan.chan_id != IDMAC_SDC_0 && ichan->dma_chan.chan_id != IDMAC_SDC_1 &&
- ichan->dma_chan.chan_id != IDMAC_IC_7)
+ if (chan->chan_id != IDMAC_SDC_0 && chan->chan_id != IDMAC_SDC_1 &&
+ chan->chan_id != IDMAC_IC_7)
return NULL;
if (direction != DMA_FROM_DEVICE && direction != DMA_TO_DEVICE) {
@@ -1400,7 +1484,7 @@ static void idmac_issue_pending(struct dma_chan *chan)
/* This is not always needed, but doesn't hurt either */
spin_lock_irqsave(&ipu->lock, flags);
- ipu_select_buffer(ichan->dma_chan.chan_id, ichan->active_buffer);
+ ipu_select_buffer(chan->chan_id, ichan->active_buffer);
spin_unlock_irqrestore(&ipu->lock, flags);
/*
@@ -1432,8 +1516,7 @@ static void __idmac_terminate_all(struct dma_chan *chan)
struct idmac_tx_desc *desc = ichan->desc + i;
if (list_empty(&desc->list))
/* Descriptor was prepared, but not submitted */
- list_add(&desc->list,
- &ichan->free_list);
+ list_add(&desc->list, &ichan->free_list);
async_tx_clear_ack(&desc->txd);
}
@@ -1458,6 +1541,28 @@ static void idmac_terminate_all(struct dma_chan *chan)
mutex_unlock(&ichan->chan_mutex);
}
+#ifdef DEBUG
+static irqreturn_t ic_sof_irq(int irq, void *dev_id)
+{
+ struct idmac_channel *ichan = dev_id;
+ printk(KERN_DEBUG "Got SOF IRQ %d on Channel %d\n",
+ irq, ichan->dma_chan.chan_id);
+ disable_irq(irq);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t ic_eof_irq(int irq, void *dev_id)
+{
+ struct idmac_channel *ichan = dev_id;
+ printk(KERN_DEBUG "Got EOF IRQ %d on Channel %d\n",
+ irq, ichan->dma_chan.chan_id);
+ disable_irq(irq);
+ return IRQ_HANDLED;
+}
+
+static int ic_sof = -EINVAL, ic_eof = -EINVAL;
+#endif
+
static int idmac_alloc_chan_resources(struct dma_chan *chan)
{
struct idmac_channel *ichan = to_idmac_chan(chan);
@@ -1471,31 +1576,49 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan)
chan->cookie = 1;
ichan->completed = -ENXIO;
- ret = ipu_irq_map(ichan->dma_chan.chan_id);
+ ret = ipu_irq_map(chan->chan_id);
if (ret < 0)
goto eimap;
ichan->eof_irq = ret;
+
+ /*
+ * Important to first disable the channel, because maybe someone
+ * used it before us, e.g., the bootloader
+ */
+ ipu_disable_channel(idmac, ichan, true);
+
+ ret = ipu_init_channel(idmac, ichan);
+ if (ret < 0)
+ goto eichan;
+
ret = request_irq(ichan->eof_irq, idmac_interrupt, 0,
ichan->eof_name, ichan);
if (ret < 0)
goto erirq;
- ret = ipu_init_channel(idmac, ichan);
- if (ret < 0)
- goto eichan;
+#ifdef DEBUG
+ if (chan->chan_id == IDMAC_IC_7) {
+ ic_sof = ipu_irq_map(69);
+ if (ic_sof > 0)
+ request_irq(ic_sof, ic_sof_irq, 0, "IC SOF", ichan);
+ ic_eof = ipu_irq_map(70);
+ if (ic_eof > 0)
+ request_irq(ic_eof, ic_eof_irq, 0, "IC EOF", ichan);
+ }
+#endif
ichan->status = IPU_CHANNEL_INITIALIZED;
- dev_dbg(&ichan->dma_chan.dev->device, "Found channel 0x%x, irq %d\n",
- ichan->dma_chan.chan_id, ichan->eof_irq);
+ dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
+ chan->chan_id, ichan->eof_irq);
return ret;
-eichan:
- free_irq(ichan->eof_irq, ichan);
erirq:
- ipu_irq_unmap(ichan->dma_chan.chan_id);
+ ipu_uninit_channel(idmac, ichan);
+eichan:
+ ipu_irq_unmap(chan->chan_id);
eimap:
return ret;
}
@@ -1510,8 +1633,22 @@ static void idmac_free_chan_resources(struct dma_chan *chan)
__idmac_terminate_all(chan);
if (ichan->status > IPU_CHANNEL_FREE) {
+#ifdef DEBUG
+ if (chan->chan_id == IDMAC_IC_7) {
+ if (ic_sof > 0) {
+ free_irq(ic_sof, ichan);
+ ipu_irq_unmap(69);
+ ic_sof = -EINVAL;
+ }
+ if (ic_eof > 0) {
+ free_irq(ic_eof, ichan);
+ ipu_irq_unmap(70);
+ ic_eof = -EINVAL;
+ }
+ }
+#endif
free_irq(ichan->eof_irq, ichan);
- ipu_irq_unmap(ichan->dma_chan.chan_id);
+ ipu_irq_unmap(chan->chan_id);
}
ichan->status = IPU_CHANNEL_FREE;
@@ -1573,7 +1710,7 @@ static int __init ipu_idmac_init(struct ipu *ipu)
dma_chan->device = &idmac->dma;
dma_chan->cookie = 1;
dma_chan->chan_id = i;
- list_add_tail(&ichan->dma_chan.device_node, &dma->channels);
+ list_add_tail(&dma_chan->device_node, &dma->channels);
}
idmac_write_icreg(ipu, 0x00000070, IDMAC_CONF);
@@ -1581,7 +1718,7 @@ static int __init ipu_idmac_init(struct ipu *ipu)
return dma_async_device_register(&idmac->dma);
}
-static void ipu_idmac_exit(struct ipu *ipu)
+static void __exit ipu_idmac_exit(struct ipu *ipu)
{
int i;
struct idmac *idmac = &ipu->idmac;
@@ -1600,7 +1737,7 @@ static void ipu_idmac_exit(struct ipu *ipu)
* IPU common probe / remove
*/
-static int ipu_probe(struct platform_device *pdev)
+static int __init ipu_probe(struct platform_device *pdev)
{
struct ipu_platform_data *pdata = pdev->dev.platform_data;
struct resource *mem_ipu, *mem_ic;
@@ -1700,7 +1837,7 @@ err_noirq:
return ret;
}
-static int ipu_remove(struct platform_device *pdev)
+static int __exit ipu_remove(struct platform_device *pdev)
{
struct ipu *ipu = platform_get_drvdata(pdev);
@@ -1725,7 +1862,7 @@ static struct platform_driver ipu_platform_driver = {
.name = "ipu-core",
.owner = THIS_MODULE,
},
- .remove = ipu_remove,
+ .remove = __exit_p(ipu_remove),
};
static int __init ipu_init(void)
diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
index 83f532cc767..dd8ebc75b66 100644
--- a/drivers/dma/ipu/ipu_irq.c
+++ b/drivers/dma/ipu/ipu_irq.c
@@ -352,7 +352,7 @@ static struct irq_chip ipu_irq_chip = {
};
/* Install the IRQ handler */
-int ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
+int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
{
struct ipu_platform_data *pdata = dev->dev.platform_data;
unsigned int irq, irq_base, i;
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index cb7f26fb9f1..ddab94f5122 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -632,7 +632,6 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
slot->async_tx.tx_submit = mv_xor_tx_submit;
INIT_LIST_HEAD(&slot->chain_node);
INIT_LIST_HEAD(&slot->slot_node);
- INIT_LIST_HEAD(&slot->async_tx.tx_list);
hw_desc = (char *) mv_chan->device->dma_desc_pool;
slot->async_tx.phys =
(dma_addr_t) &hw_desc[idx * MV_XOR_SLOT_SIZE];
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index 28f2c3f959b..6ad95c8d636 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -767,11 +767,19 @@ static inline void pci_write_bits16(struct pci_dev *pdev, int offset,
pci_write_config_word(pdev, offset, value);
}
-/* write all or some bits in a dword-register*/
+/*
+ * pci_write_bits32
+ *
+ * edac local routine to do pci_write_config_dword, but adds
+ * a mask parameter. If mask is all ones, ignore the mask.
+ * Otherwise utilize the mask to isolate specified bits
+ *
+ * write all or some bits in a dword-register
+ */
static inline void pci_write_bits32(struct pci_dev *pdev, int offset,
u32 value, u32 mask)
{
- if (mask != 0xffff) {
+ if (mask != 0xffffffff) {
u32 buf;
pci_read_config_dword(pdev, offset, &buf);
diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c
index ca9113e1c10..a7d2c717d03 100644
--- a/drivers/edac/edac_device.c
+++ b/drivers/edac/edac_device.c
@@ -389,7 +389,7 @@ static void del_edac_device_from_global_list(struct edac_device_ctl_info
*/
static void edac_device_workq_function(struct work_struct *work_req)
{
- struct delayed_work *d_work = (struct delayed_work *)work_req;
+ struct delayed_work *d_work = to_delayed_work(work_req);
struct edac_device_ctl_info *edac_dev = to_edac_device_ctl_work(d_work);
mutex_lock(&device_ctls_mutex);
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 25d66940b4f..335b7ebdb11 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -260,7 +260,7 @@ static int edac_mc_assert_error_check_and_clear(void)
*/
static void edac_mc_workq_function(struct work_struct *work_req)
{
- struct delayed_work *d_work = (struct delayed_work *)work_req;
+ struct delayed_work *d_work = to_delayed_work(work_req);
struct mem_ctl_info *mci = to_edac_mem_ctl_work(d_work);
mutex_lock(&mem_ctls_mutex);
diff --git a/drivers/edac/edac_pci.c b/drivers/edac/edac_pci.c
index 5b150aea703..30b585b1d60 100644
--- a/drivers/edac/edac_pci.c
+++ b/drivers/edac/edac_pci.c
@@ -233,7 +233,7 @@ EXPORT_SYMBOL_GPL(edac_pci_find);
*/
static void edac_pci_workq_function(struct work_struct *work_req)
{
- struct delayed_work *d_work = (struct delayed_work *)work_req;
+ struct delayed_work *d_work = to_delayed_work(work_req);
struct edac_pci_ctl_info *pci = to_edac_pci_ctl_work(d_work);
int msec;
unsigned long delay;
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 3009e0171e5..18d65fb42ee 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -545,7 +545,7 @@ static int __devinit dcdbas_probe(struct platform_device *dev)
* BIOS SMI calls require buffer addresses be in 32-bit address space.
* This is done by setting the DMA mask below.
*/
- dcdbas_pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+ dcdbas_pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
dcdbas_pdev->dev.dma_mask = &dcdbas_pdev->dev.coherent_dma_mask;
error = sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group);
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 3d2565441b3..edb02530e46 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -42,9 +42,9 @@ config DEBUG_GPIO
depends on DEBUG_KERNEL
help
Say Y here to add some extra checks and diagnostics to GPIO calls.
- The checks help ensure that GPIOs have been properly initialized
- before they are used and that sleeping calls aren not made from
- nonsleeping contexts. They can make bitbanged serial protocols
+ These checks help ensure that GPIOs have been properly initialized
+ before they are used, and that sleeping calls are not made from
+ non-sleeping contexts. They can make bitbanged serial protocols
slower. The diagnostics help catch the type of setup errors
that are most common when setting up new platforms or boards.
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index c23b3a95b7c..a000cf02882 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1179,8 +1179,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (!IS_I945G(dev) && !IS_I945GM(dev))
pci_enable_msi(dev->pdev);
- intel_opregion_init(dev);
-
spin_lock_init(&dev_priv->user_irq_lock);
dev_priv->user_irq_refcount = 0;
@@ -1199,6 +1197,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
}
}
+ /* Must be done after probing outputs */
+ intel_opregion_init(dev, 0);
+
return 0;
out_iomapfree:
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 2c016769345..6503e2210f6 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -101,7 +101,7 @@ static int i915_resume(struct drm_device *dev)
i915_restore_state(dev);
- intel_opregion_init(dev);
+ intel_opregion_init(dev, 1);
/* KMS EnterVT equivalent */
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bccd4146d55..473a8f7fbdb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -673,12 +673,12 @@ extern int i915_restore_state(struct drm_device *dev);
#ifdef CONFIG_ACPI
/* i915_opregion.c */
-extern int intel_opregion_init(struct drm_device *dev);
+extern int intel_opregion_init(struct drm_device *dev, int resume);
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);
#else
-static inline int intel_opregion_init(struct drm_device *dev) { return 0; }
+static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; }
static inline void intel_opregion_free(struct drm_device *dev) { return; }
static inline void opregion_asle_intr(struct drm_device *dev) { return; }
static inline void opregion_enable_asle(struct drm_device *dev) { return; }
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index ff012835a38..69427722d20 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -26,6 +26,7 @@
*/
#include <linux/acpi.h>
+#include <acpi/video.h>
#include "drmP.h"
#include "i915_drm.h"
@@ -136,6 +137,12 @@ struct opregion_asle {
#define ASLE_CBLV_VALID (1<<31)
+#define ACPI_OTHER_OUTPUT (0<<8)
+#define ACPI_VGA_OUTPUT (1<<8)
+#define ACPI_TV_OUTPUT (2<<8)
+#define ACPI_DIGITAL_OUTPUT (3<<8)
+#define ACPI_LVDS_OUTPUT (4<<8)
+
static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -282,7 +289,58 @@ static struct notifier_block intel_opregion_notifier = {
.notifier_call = intel_opregion_video_event,
};
-int intel_opregion_init(struct drm_device *dev)
+/*
+ * Initialise the DIDL field in opregion. This passes a list of devices to
+ * the firmware. Values are defined by section B.4.2 of the ACPI specification
+ * (version 3)
+ */
+
+static void intel_didl_outputs(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_opregion *opregion = &dev_priv->opregion;
+ struct drm_connector *connector;
+ int i = 0;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ int output_type = ACPI_OTHER_OUTPUT;
+ if (i >= 8) {
+ dev_printk (KERN_ERR, &dev->pdev->dev,
+ "More than 8 outputs detected\n");
+ return;
+ }
+ switch (connector->connector_type) {
+ case DRM_MODE_CONNECTOR_VGA:
+ case DRM_MODE_CONNECTOR_DVIA:
+ output_type = ACPI_VGA_OUTPUT;
+ break;
+ case DRM_MODE_CONNECTOR_Composite:
+ case DRM_MODE_CONNECTOR_SVIDEO:
+ case DRM_MODE_CONNECTOR_Component:
+ case DRM_MODE_CONNECTOR_9PinDIN:
+ output_type = ACPI_TV_OUTPUT;
+ break;
+ case DRM_MODE_CONNECTOR_DVII:
+ case DRM_MODE_CONNECTOR_DVID:
+ case DRM_MODE_CONNECTOR_DisplayPort:
+ case DRM_MODE_CONNECTOR_HDMIA:
+ case DRM_MODE_CONNECTOR_HDMIB:
+ output_type = ACPI_DIGITAL_OUTPUT;
+ break;
+ case DRM_MODE_CONNECTOR_LVDS:
+ output_type = ACPI_LVDS_OUTPUT;
+ break;
+ }
+ opregion->acpi->didl[i] |= (1<<31) | output_type | i;
+ i++;
+ }
+
+ /* If fewer than 8 outputs, the list must be null terminated */
+ if (i < 8)
+ opregion->acpi->didl[i] = 0;
+}
+
+int intel_opregion_init(struct drm_device *dev, int resume)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_opregion *opregion = &dev_priv->opregion;
@@ -312,6 +370,11 @@ int intel_opregion_init(struct drm_device *dev)
if (mboxes & MBOX_ACPI) {
DRM_DEBUG("Public ACPI methods supported\n");
opregion->acpi = base + OPREGION_ACPI_OFFSET;
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ intel_didl_outputs(dev);
+ if (!resume)
+ acpi_video_register();
+ }
} else {
DRM_DEBUG("Public ACPI methods not supported\n");
err = -ENOTSUPP;
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index e85c8fe9ffc..7e67dcb3d4f 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -29,11 +29,11 @@ config HID
For docs and specs, see http://www.usb.org/developers/hidpage/
- If unsure, say Y
+ If unsure, say Y.
config HID_DEBUG
bool "HID debugging support"
- default y if !EMBEDDED
+ default y
depends on HID
---help---
This option lets the HID layer output diagnostics about its internal
@@ -44,7 +44,7 @@ config HID_DEBUG
This feature is useful for those who are either debugging the HID parser
or any HID hardware device.
- If unsure, say N
+ If unsure, say Y.
config HIDRAW
bool "/dev/hidraw raw HID device support"
@@ -70,18 +70,6 @@ source "drivers/hid/usbhid/Kconfig"
menu "Special HID drivers"
depends on HID
-config HID_COMPAT
- bool "Load all HID drivers on hid core load"
- default y
- ---help---
- Compatible option for older userspace. If you have system without udev
- support of module loading through aliases and also old
- module-init-tools which can't handle hid bus, choose Y here. Otherwise
- say N. If you say N and your userspace is old enough, the only
- functionality you lose is modules autoloading.
-
- If unsure, say Y.
-
config HID_A4TECH
tristate "A4 tech" if EMBEDDED
depends on USB_HID
@@ -128,6 +116,14 @@ config HID_CYPRESS
---help---
Support for cypress mouse and barcode readers.
+config DRAGONRISE_FF
+ tristate "DragonRise Inc. force feedback support"
+ depends on USB_HID
+ select INPUT_FF_MEMLESS
+ ---help---
+ Say Y here if you want to enable force feedback support for DragonRise Inc.
+ game controllers.
+
config HID_EZKEY
tristate "Ezkey" if EMBEDDED
depends on USB_HID
@@ -135,6 +131,13 @@ config HID_EZKEY
---help---
Support for Ezkey BTC 8193 keyboard.
+config HID_KYE
+ tristate "Kye" if EMBEDDED
+ depends on USB_HID
+ default !EMBEDDED
+ ---help---
+ Support for Kye/Genius Ergo Mouse.
+
config HID_GYRATION
tristate "Gyration" if EMBEDDED
depends on USB_HID
@@ -142,6 +145,13 @@ config HID_GYRATION
---help---
Support for Gyration remote control.
+config HID_KENSINGTON
+ tristate "Kensington" if EMBEDDED
+ depends on USB_HID
+ default !EMBEDDED
+ ---help---
+ Support for Kensington Slimblade Trackball.
+
config HID_LOGITECH
tristate "Logitech" if EMBEDDED
depends on USB_HID
@@ -243,7 +253,7 @@ config GREENASIA_FF
select INPUT_FF_MEMLESS
---help---
Say Y here if you have a GreenAsia (Product ID 0x12) based game controller
- (like MANTA Warior MM816 and SpeedLink Strike2 SL-6635) or adapter
+ (like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter
and want to enable force feedback support for it.
config HID_TOPSEED
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index fbd021f153f..1f7cb0fd450 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -8,10 +8,6 @@ obj-$(CONFIG_HID) += hid.o
hid-$(CONFIG_HID_DEBUG) += hid-debug.o
hid-$(CONFIG_HIDRAW) += hidraw.o
-ifdef CONFIG_HID_COMPAT
-obj-m += hid-dummy.o
-endif
-
hid-logitech-objs := hid-lg.o
ifdef CONFIG_LOGITECH_FF
hid-logitech-objs += hid-lgff.o
@@ -26,8 +22,11 @@ obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
obj-$(CONFIG_HID_CHERRY) += hid-cherry.o
obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
+obj-$(CONFIG_DRAGONRISE_FF) += hid-drff.o
obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
+obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
+obj-$(CONFIG_HID_KYE) += hid-kye.o
obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c
index ebca00e6c10..42ea359e94c 100644
--- a/drivers/hid/hid-a4tech.c
+++ b/drivers/hid/hid-a4tech.c
@@ -158,5 +158,3 @@ static void a4_exit(void)
module_init(a4_init);
module_exit(a4_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(a4tech);
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index aa28aed0e46..7359d9d88e4 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -53,7 +53,7 @@ struct apple_key_translation {
u8 flags;
};
-static struct apple_key_translation apple_fn_keys[] = {
+static const struct apple_key_translation apple_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_ENTER, KEY_INSERT },
{ KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
@@ -75,7 +75,7 @@ static struct apple_key_translation apple_fn_keys[] = {
{ }
};
-static struct apple_key_translation powerbook_fn_keys[] = {
+static const struct apple_key_translation powerbook_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
{ KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
@@ -94,7 +94,7 @@ static struct apple_key_translation powerbook_fn_keys[] = {
{ }
};
-static struct apple_key_translation powerbook_numlock_keys[] = {
+static const struct apple_key_translation powerbook_numlock_keys[] = {
{ KEY_J, KEY_KP1 },
{ KEY_K, KEY_KP2 },
{ KEY_L, KEY_KP3 },
@@ -117,16 +117,16 @@ static struct apple_key_translation powerbook_numlock_keys[] = {
{ }
};
-static struct apple_key_translation apple_iso_keyboard[] = {
+static const struct apple_key_translation apple_iso_keyboard[] = {
{ KEY_GRAVE, KEY_102ND },
{ KEY_102ND, KEY_GRAVE },
{ }
};
-static struct apple_key_translation *apple_find_translation(
- struct apple_key_translation *table, u16 from)
+static const struct apple_key_translation *apple_find_translation(
+ const struct apple_key_translation *table, u16 from)
{
- struct apple_key_translation *trans;
+ const struct apple_key_translation *trans;
/* Look for the translation */
for (trans = table; trans->from; trans++)
@@ -140,7 +140,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
struct hid_usage *usage, __s32 value)
{
struct apple_sc *asc = hid_get_drvdata(hid);
- struct apple_key_translation *trans;
+ const struct apple_key_translation *trans;
if (usage->code == KEY_FN) {
asc->fn_on = !!value;
@@ -253,7 +253,7 @@ static void apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
static void apple_setup_input(struct input_dev *input)
{
- struct apple_key_translation *trans;
+ const struct apple_key_translation *trans;
set_bit(KEY_NUMLOCK, input->keybit);
@@ -387,6 +387,12 @@ static const struct hid_device_id apple_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS),
+ .driver_data = APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI),
.driver_data = APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO),
@@ -468,5 +474,3 @@ static void apple_exit(void)
module_init(apple_init);
module_exit(apple_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(apple);
diff --git a/drivers/hid/hid-belkin.c b/drivers/hid/hid-belkin.c
index 12c8a9ba6ed..2f6723133a4 100644
--- a/drivers/hid/hid-belkin.c
+++ b/drivers/hid/hid-belkin.c
@@ -101,5 +101,3 @@ static void belkin_exit(void)
module_init(belkin_init);
module_exit(belkin_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(belkin);
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c
index b833b9769ab..ab8209e7e45 100644
--- a/drivers/hid/hid-cherry.c
+++ b/drivers/hid/hid-cherry.c
@@ -83,5 +83,3 @@ static void ch_exit(void)
module_init(ch_init);
module_exit(ch_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(cherry);
diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c
index a54d4096e0f..7f91076d849 100644
--- a/drivers/hid/hid-chicony.c
+++ b/drivers/hid/hid-chicony.c
@@ -76,5 +76,3 @@ static void ch_exit(void)
module_init(ch_init);
module_exit(ch_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(chicony);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 1cc967448f4..5746a5903bc 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1236,6 +1236,9 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) },
@@ -1262,6 +1265,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
@@ -1269,6 +1273,8 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
@@ -1813,14 +1819,21 @@ void hid_unregister_driver(struct hid_driver *hdrv)
}
EXPORT_SYMBOL_GPL(hid_unregister_driver);
-#ifdef CONFIG_HID_COMPAT
-static void hid_compat_load(struct work_struct *ws)
+int hid_check_keys_pressed(struct hid_device *hid)
{
- request_module("hid-dummy");
+ struct hid_input *hidinput;
+ int i;
+
+ list_for_each_entry(hidinput, &hid->inputs, list) {
+ for (i = 0; i < BITS_TO_LONGS(KEY_MAX); i++)
+ if (hidinput->input->key[i])
+ return 1;
+ }
+
+ return 0;
}
-static DECLARE_WORK(hid_compat_work, hid_compat_load);
-static struct workqueue_struct *hid_compat_wq;
-#endif
+
+EXPORT_SYMBOL_GPL(hid_check_keys_pressed);
static int __init hid_init(void)
{
@@ -1836,15 +1849,6 @@ static int __init hid_init(void)
if (ret)
goto err_bus;
-#ifdef CONFIG_HID_COMPAT
- hid_compat_wq = create_singlethread_workqueue("hid_compat");
- if (!hid_compat_wq) {
- hidraw_exit();
- goto err;
- }
- queue_work(hid_compat_wq, &hid_compat_work);
-#endif
-
return 0;
err_bus:
bus_unregister(&hid_bus_type);
@@ -1854,9 +1858,6 @@ err:
static void __exit hid_exit(void)
{
-#ifdef CONFIG_HID_COMPAT
- destroy_workqueue(hid_compat_wq);
-#endif
hidraw_exit();
bus_unregister(&hid_bus_type);
}
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
index 5d69d27b935..9d6d3b91773 100644
--- a/drivers/hid/hid-cypress.c
+++ b/drivers/hid/hid-cypress.c
@@ -154,5 +154,3 @@ static void cp_exit(void)
module_init(cp_init);
module_exit(cp_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(cypress);
diff --git a/drivers/hid/hid-drff.c b/drivers/hid/hid-drff.c
new file mode 100644
index 00000000000..34f3eb65100
--- /dev/null
+++ b/drivers/hid/hid-drff.c
@@ -0,0 +1,188 @@
+/*
+ * Force feedback support for DragonRise Inc. game controllers
+ *
+ * From what I have gathered, these devices are mass produced in China and are
+ * distributed under several vendors. They often share the same design as
+ * the original PlayStation DualShock controller.
+ *
+ * 0079:0006 "DragonRise Inc. Generic USB Joystick "
+ * - tested with a Tesun USB-703 game controller.
+ *
+ * Copyright (c) 2009 Richard Walmsley <richwalm@gmail.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/hid.h>
+
+#include "hid-ids.h"
+#include "usbhid/usbhid.h"
+
+struct drff_device {
+ struct hid_report *report;
+};
+
+static int drff_play(struct input_dev *dev, void *data,
+ struct ff_effect *effect)
+{
+ struct hid_device *hid = input_get_drvdata(dev);
+ struct drff_device *drff = data;
+ int strong, weak;
+
+ strong = effect->u.rumble.strong_magnitude;
+ weak = effect->u.rumble.weak_magnitude;
+
+ dbg_hid("called with 0x%04x 0x%04x", strong, weak);
+
+ if (strong || weak) {
+ strong = strong * 0xff / 0xffff;
+ weak = weak * 0xff / 0xffff;
+
+ /* While reverse engineering this device, I found that when
+ this value is set, it causes the strong rumble to function
+ at a near maximum speed, so we'll bypass it. */
+ if (weak == 0x0a)
+ weak = 0x0b;
+
+ drff->report->field[0]->value[0] = 0x51;
+ drff->report->field[0]->value[1] = 0x00;
+ drff->report->field[0]->value[2] = weak;
+ drff->report->field[0]->value[4] = strong;
+ usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+ drff->report->field[0]->value[0] = 0xfa;
+ drff->report->field[0]->value[1] = 0xfe;
+ } else {
+ drff->report->field[0]->value[0] = 0xf3;
+ drff->report->field[0]->value[1] = 0x00;
+ }
+
+ drff->report->field[0]->value[2] = 0x00;
+ drff->report->field[0]->value[4] = 0x00;
+ dbg_hid("running with 0x%02x 0x%02x", strong, weak);
+ usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+ return 0;
+}
+
+static int drff_init(struct hid_device *hid)
+{
+ struct drff_device *drff;
+ struct hid_report *report;
+ struct hid_input *hidinput = list_first_entry(&hid->inputs,
+ struct hid_input, list);
+ struct list_head *report_list =
+ &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+ int error;
+
+ if (list_empty(report_list)) {
+ dev_err(&hid->dev, "no output reports found\n");
+ return -ENODEV;
+ }
+
+ report = list_first_entry(report_list, struct hid_report, list);
+ if (report->maxfield < 1) {
+ dev_err(&hid->dev, "no fields in the report\n");
+ return -ENODEV;
+ }
+
+ if (report->field[0]->report_count < 7) {
+ dev_err(&hid->dev, "not enough values in the field\n");
+ return -ENODEV;
+ }
+
+ drff = kzalloc(sizeof(struct drff_device), GFP_KERNEL);
+ if (!drff)
+ return -ENOMEM;
+
+ set_bit(FF_RUMBLE, dev->ffbit);
+
+ error = input_ff_create_memless(dev, drff, drff_play);
+ if (error) {
+ kfree(drff);
+ return error;
+ }
+
+ drff->report = report;
+ drff->report->field[0]->value[0] = 0xf3;
+ drff->report->field[0]->value[1] = 0x00;
+ drff->report->field[0]->value[2] = 0x00;
+ drff->report->field[0]->value[3] = 0x00;
+ drff->report->field[0]->value[4] = 0x00;
+ drff->report->field[0]->value[5] = 0x00;
+ drff->report->field[0]->value[6] = 0x00;
+ usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+ dev_info(&hid->dev, "Force Feedback for DragonRise Inc. game "
+ "controllers by Richard Walmsley <richwalm@gmail.com>\n");
+
+ return 0;
+}
+
+static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+ int ret;
+
+ dev_dbg(&hdev->dev, "DragonRise Inc. HID hardware probe...");
+
+ ret = hid_parse(hdev);
+ if (ret) {
+ dev_err(&hdev->dev, "parse failed\n");
+ goto err;
+ }
+
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
+ if (ret) {
+ dev_err(&hdev->dev, "hw start failed\n");
+ goto err;
+ }
+
+ drff_init(hdev);
+
+ return 0;
+err:
+ return ret;
+}
+
+static const struct hid_device_id dr_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006), },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, dr_devices);
+
+static struct hid_driver dr_driver = {
+ .name = "dragonrise",
+ .id_table = dr_devices,
+ .probe = dr_probe,
+};
+
+static int __init dr_init(void)
+{
+ return hid_register_driver(&dr_driver);
+}
+
+static void __exit dr_exit(void)
+{
+ hid_unregister_driver(&dr_driver);
+}
+
+module_init(dr_init);
+module_exit(dr_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c
deleted file mode 100644
index b4cc0f743d6..00000000000
--- a/drivers/hid/hid-dummy.c
+++ /dev/null
@@ -1,78 +0,0 @@
-#include <linux/autoconf.h>
-#include <linux/module.h>
-#include <linux/hid.h>
-
-static int __init hid_dummy_init(void)
-{
-#ifdef CONFIG_HID_A4TECH_MODULE
- HID_COMPAT_CALL_DRIVER(a4tech);
-#endif
-#ifdef CONFIG_HID_APPLE_MODULE
- HID_COMPAT_CALL_DRIVER(apple);
-#endif
-#ifdef CONFIG_HID_BELKIN_MODULE
- HID_COMPAT_CALL_DRIVER(belkin);
-#endif
-#ifdef CONFIG_HID_BRIGHT_MODULE
- HID_COMPAT_CALL_DRIVER(bright);
-#endif
-#ifdef CONFIG_HID_CHERRY_MODULE
- HID_COMPAT_CALL_DRIVER(cherry);
-#endif
-#ifdef CONFIG_HID_CHICONY_MODULE
- HID_COMPAT_CALL_DRIVER(chicony);
-#endif
-#ifdef CONFIG_HID_CYPRESS_MODULE
- HID_COMPAT_CALL_DRIVER(cypress);
-#endif
-#ifdef CONFIG_HID_DELL_MODULE
- HID_COMPAT_CALL_DRIVER(dell);
-#endif
-#ifdef CONFIG_HID_EZKEY_MODULE
- HID_COMPAT_CALL_DRIVER(ezkey);
-#endif
-#ifdef CONFIG_HID_GYRATION_MODULE
- HID_COMPAT_CALL_DRIVER(gyration);
-#endif
-#ifdef CONFIG_HID_LOGITECH_MODULE
- HID_COMPAT_CALL_DRIVER(logitech);
-#endif
-#ifdef CONFIG_HID_MICROSOFT_MODULE
- HID_COMPAT_CALL_DRIVER(microsoft);
-#endif
-#ifdef CONFIG_HID_MONTEREY_MODULE
- HID_COMPAT_CALL_DRIVER(monterey);
-#endif
-#ifdef CONFIG_HID_NTRIG_MODULE
- HID_COMPAT_CALL_DRIVER(ntrig);
-#endif
-#ifdef CONFIG_HID_PANTHERLORD_MODULE
- HID_COMPAT_CALL_DRIVER(pantherlord);
-#endif
-#ifdef CONFIG_HID_PETALYNX_MODULE
- HID_COMPAT_CALL_DRIVER(petalynx);
-#endif
-#ifdef CONFIG_HID_SAMSUNG_MODULE
- HID_COMPAT_CALL_DRIVER(samsung);
-#endif
-#ifdef CONFIG_HID_SONY_MODULE
- HID_COMPAT_CALL_DRIVER(sony);
-#endif
-#ifdef CONFIG_HID_SUNPLUS_MODULE
- HID_COMPAT_CALL_DRIVER(sunplus);
-#endif
-#ifdef CONFIG_GREENASIA_FF_MODULE
- HID_COMPAT_CALL_DRIVER(greenasia);
-#endif
-#ifdef CONFIG_THRUSTMASTER_FF_MODULE
- HID_COMPAT_CALL_DRIVER(thrustmaster);
-#endif
-#ifdef CONFIG_ZEROPLUS_FF_MODULE
- HID_COMPAT_CALL_DRIVER(zeroplus);
-#endif
-
- return -EIO;
-}
-module_init(hid_dummy_init);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-ezkey.c b/drivers/hid/hid-ezkey.c
index deb42f931b7..0a1fe054799 100644
--- a/drivers/hid/hid-ezkey.c
+++ b/drivers/hid/hid-ezkey.c
@@ -91,5 +91,3 @@ static void ez_exit(void)
module_init(ez_init);
module_exit(ez_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(ezkey);
diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c
index 71211f6a4f0..510ad3ab8d3 100644
--- a/drivers/hid/hid-gaff.c
+++ b/drivers/hid/hid-gaff.c
@@ -181,5 +181,3 @@ static void __exit ga_exit(void)
module_init(ga_init);
module_exit(ga_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(greenasia);
diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c
index 04a0afec52a..d42d222097a 100644
--- a/drivers/hid/hid-gyration.c
+++ b/drivers/hid/hid-gyration.c
@@ -94,5 +94,3 @@ static void gyration_exit(void)
module_init(gyration_init);
module_exit(gyration_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(gyration);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 88511970508..bdeda4c7cc1 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -67,6 +67,9 @@
#define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a
#define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b
#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c
+#define USB_DEVICE_ID_APPLE_ALU_MINI_ANSI 0x021d
+#define USB_DEVICE_ID_APPLE_ALU_MINI_ISO 0x021e
+#define USB_DEVICE_ID_APPLE_ALU_MINI_JIS 0x021f
#define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220
#define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221
#define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222
@@ -148,6 +151,8 @@
#define USB_VENDOR_ID_DMI 0x0c0b
#define USB_DEVICE_ID_DMI_ENC 0x5fab
+#define USB_VENDOR_ID_DRAGONRISE 0x0079
+
#define USB_VENDOR_ID_ELO 0x04E7
#define USB_DEVICE_ID_ELO_TS2700 0x0020
@@ -272,6 +277,9 @@
#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030
#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
+#define USB_VENDOR_ID_KENSINGTON 0x047d
+#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041
+
#define USB_VENDOR_ID_LOGITECH 0x046d
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
@@ -418,6 +426,8 @@
#define USB_VENDOR_ID_ZEROPLUS 0x0c12
#define USB_VENDOR_ID_KYE 0x0458
+#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
+
#endif
diff --git a/drivers/hid/hid-kensington.c b/drivers/hid/hid-kensington.c
new file mode 100644
index 00000000000..7353bd79cbe
--- /dev/null
+++ b/drivers/hid/hid-kensington.c
@@ -0,0 +1,63 @@
+/*
+ * HID driver for Kensigton Slimblade Trackball
+ *
+ * Copyright (c) 2009 Jiri Kosina
+ */
+
+/*
+ * 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/device.h>
+#include <linux/input.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+#define ks_map_key(c) hid_map_usage(hi, usage, bit, max, EV_KEY, (c))
+
+static int ks_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+ struct hid_field *field, struct hid_usage *usage,
+ unsigned long **bit, int *max)
+{
+ if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
+ return 0;
+
+ switch (usage->hid & HID_USAGE) {
+ case 0x01: ks_map_key(BTN_MIDDLE); break;
+ case 0x02: ks_map_key(BTN_SIDE); break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+static const struct hid_device_id ks_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, ks_devices);
+
+static struct hid_driver ks_driver = {
+ .name = "kensington",
+ .id_table = ks_devices,
+ .input_mapping = ks_input_mapping,
+};
+
+static int ks_init(void)
+{
+ return hid_register_driver(&ks_driver);
+}
+
+static void ks_exit(void)
+{
+ hid_unregister_driver(&ks_driver);
+}
+
+module_init(ks_init);
+module_exit(ks_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c
new file mode 100644
index 00000000000..72ee3fec56d
--- /dev/null
+++ b/drivers/hid/hid-kye.c
@@ -0,0 +1,69 @@
+/*
+ * HID driver for Kye/Genius devices not fully compliant with HID standard
+ *
+ * Copyright (c) 2009 Jiri Kosina
+ * Copyright (c) 2009 Tomas Hanak
+ */
+
+/*
+ * 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/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+/* the fixups that need to be done:
+ * - change led usage page to button for extra buttons
+ * - report size 8 count 1 must be size 1 count 8 for button bitfield
+ * - change the button usage range to 4-7 for the extra buttons
+ */
+static void kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int rsize)
+{
+ if (rsize >= 74 &&
+ rdesc[61] == 0x05 && rdesc[62] == 0x08 &&
+ rdesc[63] == 0x19 && rdesc[64] == 0x08 &&
+ rdesc[65] == 0x29 && rdesc[66] == 0x0f &&
+ rdesc[71] == 0x75 && rdesc[72] == 0x08 &&
+ rdesc[73] == 0x95 && rdesc[74] == 0x01) {
+ dev_info(&hdev->dev, "fixing up Kye/Genius Ergo Mouse report "
+ "descriptor\n");
+ rdesc[62] = 0x09;
+ rdesc[64] = 0x04;
+ rdesc[66] = 0x07;
+ rdesc[72] = 0x01;
+ rdesc[74] = 0x08;
+ }
+}
+
+static const struct hid_device_id kye_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, kye_devices);
+
+static struct hid_driver kye_driver = {
+ .name = "kye",
+ .id_table = kye_devices,
+ .report_fixup = kye_report_fixup,
+};
+
+static int kye_init(void)
+{
+ return hid_register_driver(&kye_driver);
+}
+
+static void kye_exit(void)
+{
+ hid_unregister_driver(&kye_driver);
+}
+
+module_init(kye_init);
+module_exit(kye_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 83e07c9f414..7b80cb69498 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -326,5 +326,3 @@ static void lg_exit(void)
module_init(lg_init);
module_exit(lg_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(logitech);
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 25b10dcad90..5e9e37a0506 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -210,5 +210,3 @@ static void ms_exit(void)
module_init(ms_init);
module_exit(ms_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(microsoft);
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c
index f3a85a065f1..240f87618be 100644
--- a/drivers/hid/hid-monterey.c
+++ b/drivers/hid/hid-monterey.c
@@ -78,5 +78,3 @@ static void mr_exit(void)
module_init(mr_init);
module_exit(mr_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(monterey);
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index db44fbd7bdf..c5b252be9c2 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -78,5 +78,3 @@ static void ntrig_exit(void)
module_init(ntrig_init);
module_exit(ntrig_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(ntrig);
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c
index 10945fe12d5..2e83e8ff891 100644
--- a/drivers/hid/hid-petalynx.c
+++ b/drivers/hid/hid-petalynx.c
@@ -118,5 +118,3 @@ static void pl_exit(void)
module_init(pl_init);
module_exit(pl_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(petalynx);
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
index 46941f979b9..4db9a348376 100644
--- a/drivers/hid/hid-pl.c
+++ b/drivers/hid/hid-pl.c
@@ -9,9 +9,12 @@
* - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT)
*
* 0e8f:0003 "GreenAsia Inc. USB Joystick "
- * - tested with K??ng Gaming gamepad
+ * - tested with König Gaming gamepad
*
- * Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
+ * 0e8f:0003 "GASIA USB Gamepad"
+ * - another version of the König gamepad
+ *
+ * Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com>
*/
/*
@@ -46,6 +49,8 @@
struct plff_device {
struct hid_report *report;
+ s32 *strong;
+ s32 *weak;
};
static int hid_plff_play(struct input_dev *dev, void *data,
@@ -62,8 +67,8 @@ static int hid_plff_play(struct input_dev *dev, void *data,
left = left * 0x7f / 0xffff;
right = right * 0x7f / 0xffff;
- plff->report->field[0]->value[2] = left;
- plff->report->field[0]->value[3] = right;
+ *plff->strong = left;
+ *plff->weak = right;
debug("running with 0x%02x 0x%02x", left, right);
usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
@@ -80,6 +85,8 @@ static int plff_init(struct hid_device *hid)
struct list_head *report_ptr = report_list;
struct input_dev *dev;
int error;
+ s32 *strong;
+ s32 *weak;
/* The device contains one output report per physical device, all
containing 1 field, which contains 4 ff00.0002 usages and 4 16bit
@@ -87,7 +94,12 @@ static int plff_init(struct hid_device *hid)
The input reports also contain a field which contains
8 ff00.0001 usages and 8 boolean values. Their meaning is
- currently unknown. */
+ currently unknown.
+
+ A version of the 0e8f:0003 exists that has all the values in
+ separate fields and misses the extra input field, thus resembling
+ Zeroplus (hid-zpff) devices.
+ */
if (list_empty(report_list)) {
dev_err(&hid->dev, "no output reports found\n");
@@ -110,8 +122,21 @@ static int plff_init(struct hid_device *hid)
return -ENODEV;
}
- if (report->field[0]->report_count < 4) {
- dev_err(&hid->dev, "not enough values in the field\n");
+ if (report->field[0]->report_count >= 4) {
+ report->field[0]->value[0] = 0x00;
+ report->field[0]->value[1] = 0x00;
+ strong = &report->field[0]->value[2];
+ weak = &report->field[0]->value[3];
+ debug("detected single-field device");
+ } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 &&
+ report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) {
+ report->field[0]->value[0] = 0x00;
+ report->field[1]->value[0] = 0x00;
+ strong = &report->field[2]->value[0];
+ weak = &report->field[3]->value[0];
+ debug("detected 4-field device");
+ } else {
+ dev_err(&hid->dev, "not enough fields or values\n");
return -ENODEV;
}
@@ -130,10 +155,11 @@ static int plff_init(struct hid_device *hid)
}
plff->report = report;
- plff->report->field[0]->value[0] = 0x00;
- plff->report->field[0]->value[1] = 0x00;
- plff->report->field[0]->value[2] = 0x00;
- plff->report->field[0]->value[3] = 0x00;
+ plff->strong = strong;
+ plff->weak = weak;
+
+ *strong = 0x00;
+ *weak = 0x00;
usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
}
@@ -180,7 +206,7 @@ static const struct hid_device_id pl_devices[] = {
.driver_data = 1 }, /* Twin USB Joystick */
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR),
.driver_data = 1 }, /* Twin USB Joystick */
- { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, /* GreenAsia Inc. USB Joystick */
+ { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), },
{ }
};
MODULE_DEVICE_TABLE(hid, pl_devices);
@@ -204,5 +230,3 @@ static void pl_exit(void)
module_init(pl_init);
module_exit(pl_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(pantherlord);
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
index 15f3c049245..07083aa6c19 100644
--- a/drivers/hid/hid-samsung.c
+++ b/drivers/hid/hid-samsung.c
@@ -96,5 +96,3 @@ static void samsung_exit(void)
module_init(samsung_init);
module_exit(samsung_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(samsung);
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index dd5a3979a4d..c2599388a35 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -148,5 +148,3 @@ static void sony_exit(void)
module_init(sony_init);
module_exit(sony_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(sony);
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c
index 5ba68f7dbb7..e0a8fd36a85 100644
--- a/drivers/hid/hid-sunplus.c
+++ b/drivers/hid/hid-sunplus.c
@@ -78,5 +78,3 @@ static void sp_exit(void)
module_init(sp_init);
module_exit(sp_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(sunplus);
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index 1b7cba0f7e1..7c1f7b50330 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -265,5 +265,3 @@ static void tm_exit(void)
module_init(tm_init);
module_exit(tm_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(thrustmaster);
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c
index cca64a0564a..152ccfabeba 100644
--- a/drivers/hid/hid-topseed.c
+++ b/drivers/hid/hid-topseed.c
@@ -73,5 +73,3 @@ static void ts_exit(void)
module_init(ts_init);
module_exit(ts_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(topseed);
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
index ea82f3718b2..85a198a1853 100644
--- a/drivers/hid/hid-zpff.c
+++ b/drivers/hid/hid-zpff.c
@@ -158,5 +158,3 @@ static void zp_exit(void)
module_init(zp_init);
module_exit(zp_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(zeroplus);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 02b19db5442..e263d473117 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -181,9 +181,17 @@ static int hidraw_open(struct inode *inode, struct file *file)
dev = hidraw_table[minor];
if (!dev->open++) {
+ if (dev->hid->ll_driver->power) {
+ err = dev->hid->ll_driver->power(dev->hid, PM_HINT_FULLON);
+ if (err < 0)
+ goto out_unlock;
+ }
err = dev->hid->ll_driver->open(dev->hid);
- if (err < 0)
+ if (err < 0) {
+ if (dev->hid->ll_driver->power)
+ dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
dev->open--;
+ }
}
out_unlock:
@@ -209,10 +217,13 @@ static int hidraw_release(struct inode * inode, struct file * file)
list_del(&list->node);
dev = hidraw_table[minor];
if (!--dev->open) {
- if (list->hidraw->exist)
+ if (list->hidraw->exist) {
+ if (dev->hid->ll_driver->power)
+ dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
dev->hid->ll_driver->close(dev->hid);
- else
+ } else {
kfree(list->hidraw);
+ }
}
kfree(list);
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index f0a0f72238a..4306cb1b8ce 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -5,6 +5,7 @@
* Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
* Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
* Copyright (c) 2006-2008 Jiri Kosina
+ * Copyright (c) 2007-2008 Oliver Neukum
*/
/*
@@ -27,6 +28,7 @@
#include <asm/byteorder.h>
#include <linux/input.h>
#include <linux/wait.h>
+#include <linux/workqueue.h>
#include <linux/usb.h>
@@ -53,6 +55,10 @@ static unsigned int hid_mousepoll_interval;
module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
+static unsigned int ignoreled;
+module_param_named(ignoreled, ignoreled, uint, 0644);
+MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds");
+
/* Quirks specified at module load time */
static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
module_param_array_named(quirks, quirks_param, charp, NULL, 0444);
@@ -63,8 +69,13 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
/*
* Input submission and I/O error handler.
*/
+static DEFINE_MUTEX(hid_open_mut);
+static struct workqueue_struct *resumption_waker;
static void hid_io_error(struct hid_device *hid);
+static int hid_submit_out(struct hid_device *hid);
+static int hid_submit_ctrl(struct hid_device *hid);
+static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid);
/* Start up the input URB */
static int hid_start_in(struct hid_device *hid)
@@ -73,15 +84,16 @@ static int hid_start_in(struct hid_device *hid)
int rc = 0;
struct usbhid_device *usbhid = hid->driver_data;
- spin_lock_irqsave(&usbhid->inlock, flags);
- if (hid->open > 0 && !test_bit(HID_SUSPENDED, &usbhid->iofl) &&
+ spin_lock_irqsave(&usbhid->lock, flags);
+ if (hid->open > 0 &&
!test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
+ !test_bit(HID_REPORTED_IDLE, &usbhid->iofl) &&
!test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
if (rc != 0)
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
}
- spin_unlock_irqrestore(&usbhid->inlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
return rc;
}
@@ -145,7 +157,7 @@ static void hid_io_error(struct hid_device *hid)
unsigned long flags;
struct usbhid_device *usbhid = hid->driver_data;
- spin_lock_irqsave(&usbhid->inlock, flags);
+ spin_lock_irqsave(&usbhid->lock, flags);
/* Stop when disconnected */
if (test_bit(HID_DISCONNECTED, &usbhid->iofl))
@@ -175,7 +187,51 @@ static void hid_io_error(struct hid_device *hid)
mod_timer(&usbhid->io_retry,
jiffies + msecs_to_jiffies(usbhid->retry_delay));
done:
- spin_unlock_irqrestore(&usbhid->inlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
+}
+
+static void usbhid_mark_busy(struct usbhid_device *usbhid)
+{
+ struct usb_interface *intf = usbhid->intf;
+
+ usb_mark_last_busy(interface_to_usbdev(intf));
+}
+
+static int usbhid_restart_out_queue(struct usbhid_device *usbhid)
+{
+ struct hid_device *hid = usb_get_intfdata(usbhid->intf);
+ int kicked;
+
+ if (!hid)
+ return 0;
+
+ if ((kicked = (usbhid->outhead != usbhid->outtail))) {
+ dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail);
+ if (hid_submit_out(hid)) {
+ clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
+ wake_up(&usbhid->wait);
+ }
+ }
+ return kicked;
+}
+
+static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid)
+{
+ struct hid_device *hid = usb_get_intfdata(usbhid->intf);
+ int kicked;
+
+ WARN_ON(hid == NULL);
+ if (!hid)
+ return 0;
+
+ if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) {
+ dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail);
+ if (hid_submit_ctrl(hid)) {
+ clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+ wake_up(&usbhid->wait);
+ }
+ }
+ return kicked;
}
/*
@@ -190,12 +246,23 @@ static void hid_irq_in(struct urb *urb)
switch (urb->status) {
case 0: /* success */
+ usbhid_mark_busy(usbhid);
usbhid->retry_delay = 0;
hid_input_report(urb->context, HID_INPUT_REPORT,
urb->transfer_buffer,
urb->actual_length, 1);
+ /*
+ * autosuspend refused while keys are pressed
+ * because most keyboards don't wake up when
+ * a key is released
+ */
+ if (hid_check_keys_pressed(hid))
+ set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
+ else
+ clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
break;
case -EPIPE: /* stall */
+ usbhid_mark_busy(usbhid);
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
set_bit(HID_CLEAR_HALT, &usbhid->iofl);
schedule_work(&usbhid->reset_work);
@@ -209,6 +276,7 @@ static void hid_irq_in(struct urb *urb)
case -EPROTO: /* protocol error or unplug */
case -ETIME: /* protocol error or unplug */
case -ETIMEDOUT: /* Should never happen, but... */
+ usbhid_mark_busy(usbhid);
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
hid_io_error(hid);
return;
@@ -239,16 +307,25 @@ static int hid_submit_out(struct hid_device *hid)
report = usbhid->out[usbhid->outtail].report;
raw_report = usbhid->out[usbhid->outtail].raw_report;
- usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
- usbhid->urbout->dev = hid_to_usb_dev(hid);
- memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length);
- kfree(raw_report);
+ if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
+ usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+ usbhid->urbout->dev = hid_to_usb_dev(hid);
+ memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length);
+ kfree(raw_report);
- dbg_hid("submitting out urb\n");
+ dbg_hid("submitting out urb\n");
- if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
- err_hid("usb_submit_urb(out) failed");
- return -1;
+ if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
+ err_hid("usb_submit_urb(out) failed");
+ return -1;
+ }
+ } else {
+ /*
+ * queue work to wake up the device.
+ * as the work queue is freezeable, this is safe
+ * with respect to STD and STR
+ */
+ queue_work(resumption_waker, &usbhid->restart_work);
}
return 0;
@@ -266,41 +343,50 @@ static int hid_submit_ctrl(struct hid_device *hid)
raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
dir = usbhid->ctrl[usbhid->ctrltail].dir;
- len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
- if (dir == USB_DIR_OUT) {
- usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
- usbhid->urbctrl->transfer_buffer_length = len;
- memcpy(usbhid->ctrlbuf, raw_report, len);
- kfree(raw_report);
- } else {
- int maxpacket, padlen;
-
- usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
- maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
- if (maxpacket > 0) {
- padlen = DIV_ROUND_UP(len, maxpacket);
- padlen *= maxpacket;
- if (padlen > usbhid->bufsize)
- padlen = usbhid->bufsize;
- } else
- padlen = 0;
- usbhid->urbctrl->transfer_buffer_length = padlen;
- }
- usbhid->urbctrl->dev = hid_to_usb_dev(hid);
+ if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
+ len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+ if (dir == USB_DIR_OUT) {
+ usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
+ usbhid->urbctrl->transfer_buffer_length = len;
+ memcpy(usbhid->ctrlbuf, raw_report, len);
+ kfree(raw_report);
+ } else {
+ int maxpacket, padlen;
+
+ usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
+ maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
+ if (maxpacket > 0) {
+ padlen = DIV_ROUND_UP(len, maxpacket);
+ padlen *= maxpacket;
+ if (padlen > usbhid->bufsize)
+ padlen = usbhid->bufsize;
+ } else
+ padlen = 0;
+ usbhid->urbctrl->transfer_buffer_length = padlen;
+ }
+ usbhid->urbctrl->dev = hid_to_usb_dev(hid);
- usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
- usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
- usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
- usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
- usbhid->cr->wLength = cpu_to_le16(len);
+ usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
+ usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
+ usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
+ usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
+ usbhid->cr->wLength = cpu_to_le16(len);
- dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
- usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
- usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
+ dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
+ usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
+ usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
- if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
- err_hid("usb_submit_urb(ctrl) failed");
- return -1;
+ if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
+ err_hid("usb_submit_urb(ctrl) failed");
+ return -1;
+ }
+ } else {
+ /*
+ * queue work to wake up the device.
+ * as the work queue is freezeable, this is safe
+ * with respect to STD and STR
+ */
+ queue_work(resumption_waker, &usbhid->restart_work);
}
return 0;
@@ -332,7 +418,7 @@ static void hid_irq_out(struct urb *urb)
"received\n", urb->status);
}
- spin_lock_irqsave(&usbhid->outlock, flags);
+ spin_lock_irqsave(&usbhid->lock, flags);
if (unplug)
usbhid->outtail = usbhid->outhead;
@@ -344,12 +430,12 @@ static void hid_irq_out(struct urb *urb)
clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
wake_up(&usbhid->wait);
}
- spin_unlock_irqrestore(&usbhid->outlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
return;
}
clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
- spin_unlock_irqrestore(&usbhid->outlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
wake_up(&usbhid->wait);
}
@@ -361,12 +447,11 @@ static void hid_ctrl(struct urb *urb)
{
struct hid_device *hid = urb->context;
struct usbhid_device *usbhid = hid->driver_data;
- unsigned long flags;
- int unplug = 0;
+ int unplug = 0, status = urb->status;
- spin_lock_irqsave(&usbhid->ctrllock, flags);
+ spin_lock(&usbhid->lock);
- switch (urb->status) {
+ switch (status) {
case 0: /* success */
if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
hid_input_report(urb->context,
@@ -383,7 +468,7 @@ static void hid_ctrl(struct urb *urb)
break;
default: /* error */
dev_warn(&urb->dev->dev, "ctrl urb status %d "
- "received\n", urb->status);
+ "received\n", status);
}
if (unplug)
@@ -396,19 +481,18 @@ static void hid_ctrl(struct urb *urb)
clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
wake_up(&usbhid->wait);
}
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+ spin_unlock(&usbhid->lock);
return;
}
clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+ spin_unlock(&usbhid->lock);
wake_up(&usbhid->wait);
}
-void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
{
int head;
- unsigned long flags;
struct usbhid_device *usbhid = hid->driver_data;
int len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
@@ -416,18 +500,13 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
return;
if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
-
- spin_lock_irqsave(&usbhid->outlock, flags);
-
if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) {
- spin_unlock_irqrestore(&usbhid->outlock, flags);
dev_warn(&hid->dev, "output queue full\n");
return;
}
usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
if (!usbhid->out[usbhid->outhead].raw_report) {
- spin_unlock_irqrestore(&usbhid->outlock, flags);
dev_warn(&hid->dev, "output queueing failed\n");
return;
}
@@ -438,15 +517,10 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl))
if (hid_submit_out(hid))
clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
-
- spin_unlock_irqrestore(&usbhid->outlock, flags);
return;
}
- spin_lock_irqsave(&usbhid->ctrllock, flags);
-
if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) {
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
dev_warn(&hid->dev, "control queue full\n");
return;
}
@@ -454,7 +528,6 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
if (dir == USB_DIR_OUT) {
usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
dev_warn(&hid->dev, "control queueing failed\n");
return;
}
@@ -467,15 +540,25 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl))
if (hid_submit_ctrl(hid))
clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+}
+
+void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+ unsigned long flags;
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+ spin_lock_irqsave(&usbhid->lock, flags);
+ __usbhid_submit_report(hid, report, dir);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
}
EXPORT_SYMBOL_GPL(usbhid_submit_report);
static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
struct hid_device *hid = input_get_drvdata(dev);
+ struct usbhid_device *usbhid = hid->driver_data;
struct hid_field *field;
+ unsigned long flags;
int offset;
if (type == EV_FF)
@@ -490,6 +573,15 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un
}
hid_set_field(field, offset, value);
+ if (value) {
+ spin_lock_irqsave(&usbhid->lock, flags);
+ usbhid->ledcount++;
+ spin_unlock_irqrestore(&usbhid->lock, flags);
+ } else {
+ spin_lock_irqsave(&usbhid->lock, flags);
+ usbhid->ledcount--;
+ spin_unlock_irqrestore(&usbhid->lock, flags);
+ }
usbhid_submit_report(hid, field->report, USB_DIR_OUT);
return 0;
@@ -538,15 +630,22 @@ int usbhid_open(struct hid_device *hid)
struct usbhid_device *usbhid = hid->driver_data;
int res;
+ mutex_lock(&hid_open_mut);
if (!hid->open++) {
res = usb_autopm_get_interface(usbhid->intf);
+ /* the device must be awake to reliable request remote wakeup */
if (res < 0) {
hid->open--;
+ mutex_unlock(&hid_open_mut);
return -EIO;
}
+ usbhid->intf->needs_remote_wakeup = 1;
+ if (hid_start_in(hid))
+ hid_io_error(hid);
+
+ usb_autopm_put_interface(usbhid->intf);
}
- if (hid_start_in(hid))
- hid_io_error(hid);
+ mutex_unlock(&hid_open_mut);
return 0;
}
@@ -554,10 +653,22 @@ void usbhid_close(struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;
+ mutex_lock(&hid_open_mut);
+
+ /* protecting hid->open to make sure we don't restart
+ * data acquistion due to a resumption we no longer
+ * care about
+ */
+ spin_lock_irq(&usbhid->lock);
if (!--hid->open) {
+ spin_unlock_irq(&usbhid->lock);
usb_kill_urb(usbhid->urbin);
- usb_autopm_put_interface(usbhid->intf);
+ flush_scheduled_work();
+ usbhid->intf->needs_remote_wakeup = 0;
+ } else {
+ spin_unlock_irq(&usbhid->lock);
}
+ mutex_unlock(&hid_open_mut);
}
/*
@@ -687,6 +798,25 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
return ret;
}
+static void usbhid_restart_queues(struct usbhid_device *usbhid)
+{
+ if (usbhid->urbout)
+ usbhid_restart_out_queue(usbhid);
+ usbhid_restart_ctrl_queue(usbhid);
+}
+
+static void __usbhid_restart_queues(struct work_struct *work)
+{
+ struct usbhid_device *usbhid =
+ container_of(work, struct usbhid_device, restart_work);
+ int r;
+
+ r = usb_autopm_get_interface(usbhid->intf);
+ if (r < 0)
+ return;
+ usb_autopm_put_interface(usbhid->intf);
+}
+
static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;
@@ -711,6 +841,9 @@ static int usbhid_parse(struct hid_device *hid)
quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
+ if (quirks & HID_QUIRK_IGNORE)
+ return -ENODEV;
+
/* Many keyboards and mice don't like to be polled for reports,
* so we will always set the HID_QUIRK_NOGET flag for them. */
if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
@@ -850,11 +983,11 @@ static int usbhid_start(struct hid_device *hid)
init_waitqueue_head(&usbhid->wait);
INIT_WORK(&usbhid->reset_work, hid_reset);
+ INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
- spin_lock_init(&usbhid->inlock);
- spin_lock_init(&usbhid->outlock);
- spin_lock_init(&usbhid->ctrllock);
+ spin_lock_init(&usbhid->lock);
+ spin_lock_init(&usbhid->lock);
usbhid->intf = intf;
usbhid->ifnum = interface->desc.bInterfaceNumber;
@@ -906,15 +1039,14 @@ static void usbhid_stop(struct hid_device *hid)
return;
clear_bit(HID_STARTED, &usbhid->iofl);
- spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
+ spin_lock_irq(&usbhid->lock); /* Sync with error handler */
set_bit(HID_DISCONNECTED, &usbhid->iofl);
- spin_unlock_irq(&usbhid->inlock);
+ spin_unlock_irq(&usbhid->lock);
usb_kill_urb(usbhid->urbin);
usb_kill_urb(usbhid->urbout);
usb_kill_urb(usbhid->urbctrl);
- del_timer_sync(&usbhid->io_retry);
- cancel_work_sync(&usbhid->reset_work);
+ hid_cancel_delayed_stuff(usbhid);
if (hid->claimed & HID_CLAIMED_INPUT)
hidinput_disconnect(hid);
@@ -935,12 +1067,28 @@ static void usbhid_stop(struct hid_device *hid)
hid_free_buffers(hid_to_usb_dev(hid), hid);
}
+static int usbhid_power(struct hid_device *hid, int lvl)
+{
+ int r = 0;
+
+ switch (lvl) {
+ case PM_HINT_FULLON:
+ r = usbhid_get_power(hid);
+ break;
+ case PM_HINT_NORMAL:
+ usbhid_put_power(hid);
+ break;
+ }
+ return r;
+}
+
static struct hid_ll_driver usb_hid_driver = {
.parse = usbhid_parse,
.start = usbhid_start,
.stop = usbhid_stop,
.open = usbhid_open,
.close = usbhid_close,
+ .power = usbhid_power,
.hidinput_input_event = usb_hidinput_input_event,
};
@@ -1049,19 +1197,126 @@ static void hid_disconnect(struct usb_interface *intf)
kfree(usbhid);
}
+static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
+{
+ del_timer_sync(&usbhid->io_retry);
+ cancel_work_sync(&usbhid->restart_work);
+ cancel_work_sync(&usbhid->reset_work);
+}
+
+static void hid_cease_io(struct usbhid_device *usbhid)
+{
+ del_timer(&usbhid->io_retry);
+ usb_kill_urb(usbhid->urbin);
+ usb_kill_urb(usbhid->urbctrl);
+ usb_kill_urb(usbhid->urbout);
+}
+
+/* Treat USB reset pretty much the same as suspend/resume */
+static int hid_pre_reset(struct usb_interface *intf)
+{
+ struct hid_device *hid = usb_get_intfdata(intf);
+ struct usbhid_device *usbhid = hid->driver_data;
+
+ spin_lock_irq(&usbhid->lock);
+ set_bit(HID_RESET_PENDING, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ cancel_work_sync(&usbhid->restart_work);
+ hid_cease_io(usbhid);
+
+ return 0;
+}
+
+/* Same routine used for post_reset and reset_resume */
+static int hid_post_reset(struct usb_interface *intf)
+{
+ struct usb_device *dev = interface_to_usbdev (intf);
+ struct hid_device *hid = usb_get_intfdata(intf);
+ struct usbhid_device *usbhid = hid->driver_data;
+ int status;
+
+ spin_lock_irq(&usbhid->lock);
+ clear_bit(HID_RESET_PENDING, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
+ /* FIXME: Any more reinitialization needed? */
+ status = hid_start_in(hid);
+ if (status < 0)
+ hid_io_error(hid);
+ usbhid_restart_queues(usbhid);
+
+ return 0;
+}
+
+int usbhid_get_power(struct hid_device *hid)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+
+ return usb_autopm_get_interface(usbhid->intf);
+}
+
+void usbhid_put_power(struct hid_device *hid)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+
+ usb_autopm_put_interface(usbhid->intf);
+}
+
+
+#ifdef CONFIG_PM
static int hid_suspend(struct usb_interface *intf, pm_message_t message)
{
- struct hid_device *hid = usb_get_intfdata (intf);
+ struct hid_device *hid = usb_get_intfdata(intf);
struct usbhid_device *usbhid = hid->driver_data;
+ struct usb_device *udev = interface_to_usbdev(intf);
+ int status;
- if (!test_bit(HID_STARTED, &usbhid->iofl))
- return 0;
+ if (udev->auto_pm) {
+ spin_lock_irq(&usbhid->lock); /* Sync with error handler */
+ if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
+ && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
+ && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)
+ && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl)
+ && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl)
+ && (!usbhid->ledcount || ignoreled))
+ {
+ set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ } else {
+ usbhid_mark_busy(usbhid);
+ spin_unlock_irq(&usbhid->lock);
+ return -EBUSY;
+ }
- spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
- set_bit(HID_SUSPENDED, &usbhid->iofl);
- spin_unlock_irq(&usbhid->inlock);
- del_timer_sync(&usbhid->io_retry);
- usb_kill_urb(usbhid->urbin);
+ } else {
+ spin_lock_irq(&usbhid->lock);
+ set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ if (usbhid_wait_io(hid) < 0)
+ return -EIO;
+ }
+
+ if (!ignoreled && udev->auto_pm) {
+ spin_lock_irq(&usbhid->lock);
+ if (test_bit(HID_LED_ON, &usbhid->iofl)) {
+ spin_unlock_irq(&usbhid->lock);
+ usbhid_mark_busy(usbhid);
+ return -EBUSY;
+ }
+ spin_unlock_irq(&usbhid->lock);
+ }
+
+ hid_cancel_delayed_stuff(usbhid);
+ hid_cease_io(usbhid);
+
+ if (udev->auto_pm && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
+ /* lost race against keypresses */
+ status = hid_start_in(hid);
+ if (status < 0)
+ hid_io_error(hid);
+ usbhid_mark_busy(usbhid);
+ return -EBUSY;
+ }
dev_dbg(&intf->dev, "suspend\n");
return 0;
}
@@ -1075,32 +1330,33 @@ static int hid_resume(struct usb_interface *intf)
if (!test_bit(HID_STARTED, &usbhid->iofl))
return 0;
- clear_bit(HID_SUSPENDED, &usbhid->iofl);
+ clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ usbhid_mark_busy(usbhid);
+
+ if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
+ test_bit(HID_RESET_PENDING, &usbhid->iofl))
+ schedule_work(&usbhid->reset_work);
usbhid->retry_delay = 0;
status = hid_start_in(hid);
- dev_dbg(&intf->dev, "resume status %d\n", status);
- return status;
-}
+ if (status < 0)
+ hid_io_error(hid);
+ usbhid_restart_queues(usbhid);
-/* Treat USB reset pretty much the same as suspend/resume */
-static int hid_pre_reset(struct usb_interface *intf)
-{
- /* FIXME: What if the interface is already suspended? */
- hid_suspend(intf, PMSG_ON);
+ dev_dbg(&intf->dev, "resume status %d\n", status);
return 0;
}
-/* Same routine used for post_reset and reset_resume */
-static int hid_post_reset(struct usb_interface *intf)
+static int hid_reset_resume(struct usb_interface *intf)
{
- struct usb_device *dev = interface_to_usbdev (intf);
-
- hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
- /* FIXME: Any more reinitialization needed? */
+ struct hid_device *hid = usb_get_intfdata(intf);
+ struct usbhid_device *usbhid = hid->driver_data;
- return hid_resume(intf);
+ clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ return hid_post_reset(intf);
}
+#endif /* CONFIG_PM */
+
static struct usb_device_id hid_usb_ids [] = {
{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
.bInterfaceClass = USB_INTERFACE_CLASS_HID },
@@ -1113,9 +1369,11 @@ static struct usb_driver hid_driver = {
.name = "usbhid",
.probe = hid_probe,
.disconnect = hid_disconnect,
+#ifdef CONFIG_PM
.suspend = hid_suspend,
.resume = hid_resume,
- .reset_resume = hid_post_reset,
+ .reset_resume = hid_reset_resume,
+#endif
.pre_reset = hid_pre_reset,
.post_reset = hid_post_reset,
.id_table = hid_usb_ids,
@@ -1134,7 +1392,11 @@ static struct hid_driver hid_usb_driver = {
static int __init hid_init(void)
{
- int retval;
+ int retval = -ENOMEM;
+
+ resumption_waker = create_freezeable_workqueue("usbhid_resumer");
+ if (!resumption_waker)
+ goto no_queue;
retval = hid_register_driver(&hid_usb_driver);
if (retval)
goto hid_register_fail;
@@ -1158,6 +1420,8 @@ hiddev_init_fail:
usbhid_quirks_init_fail:
hid_unregister_driver(&hid_usb_driver);
hid_register_fail:
+ destroy_workqueue(resumption_waker);
+no_queue:
return retval;
}
@@ -1167,6 +1431,7 @@ static void __exit hid_exit(void)
hiddev_exit();
usbhid_quirks_exit();
hid_unregister_driver(&hid_usb_driver);
+ destroy_workqueue(resumption_waker);
}
module_init(hid_init);
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index aa214170baf..e9b436d2d94 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -246,10 +246,12 @@ static int hiddev_release(struct inode * inode, struct file * file)
spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
if (!--list->hiddev->open) {
- if (list->hiddev->exist)
+ if (list->hiddev->exist) {
usbhid_close(list->hiddev->hid);
- else
+ usbhid_put_power(list->hiddev->hid);
+ } else {
kfree(list->hiddev);
+ }
}
kfree(list);
@@ -300,6 +302,17 @@ static int hiddev_open(struct inode *inode, struct file *file)
list_add_tail(&list->node, &hiddev_table[i]->list);
spin_unlock_irq(&list->hiddev->list_lock);
+ if (!list->hiddev->open++)
+ if (list->hiddev->exist) {
+ struct hid_device *hid = hiddev_table[i]->hid;
+ res = usbhid_get_power(hid);
+ if (res < 0) {
+ res = -EIO;
+ goto bail;
+ }
+ usbhid_open(hid);
+ }
+
return 0;
bail:
file->private_data = NULL;
@@ -875,16 +888,21 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
hiddev->hid = hid;
hiddev->exist = 1;
+ /* when lock_kernel() usage is fixed in usb_open(),
+ * we could also fix it here */
+ lock_kernel();
retval = usb_register_dev(usbhid->intf, &hiddev_class);
if (retval) {
err_hid("Not able to get a minor for this device.");
hid->hiddev = NULL;
+ unlock_kernel();
kfree(hiddev);
return -1;
} else {
hid->minor = usbhid->intf->minor;
hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
}
+ unlock_kernel();
return 0;
}
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
index 9eb30564be9..08f505ca2e3 100644
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -38,7 +38,10 @@ int usbhid_wait_io(struct hid_device* hid);
void usbhid_close(struct hid_device *hid);
int usbhid_open(struct hid_device *hid);
void usbhid_init_reports(struct hid_device *hid);
-void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir);
+void usbhid_submit_report
+(struct hid_device *hid, struct hid_report *report, unsigned char dir);
+int usbhid_get_power(struct hid_device *hid);
+void usbhid_put_power(struct hid_device *hid);
/* iofl flags */
#define HID_CTRL_RUNNING 1
@@ -49,6 +52,9 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
#define HID_CLEAR_HALT 6
#define HID_DISCONNECTED 7
#define HID_STARTED 8
+#define HID_REPORTED_IDLE 9
+#define HID_KEYS_PRESSED 10
+#define HID_LED_ON 11
/*
* USB-specific HID struct, to be pointed to
@@ -66,7 +72,6 @@ struct usbhid_device {
struct urb *urbin; /* Input URB */
char *inbuf; /* Input buffer */
dma_addr_t inbuf_dma; /* Input buffer dma */
- spinlock_t inlock; /* Input fifo spinlock */
struct urb *urbctrl; /* Control URB */
struct usb_ctrlrequest *cr; /* Control request struct */
@@ -75,21 +80,22 @@ struct usbhid_device {
unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */
char *ctrlbuf; /* Control buffer */
dma_addr_t ctrlbuf_dma; /* Control buffer dma */
- spinlock_t ctrllock; /* Control fifo spinlock */
struct urb *urbout; /* Output URB */
struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */
unsigned char outhead, outtail; /* Output pipe fifo head & tail */
char *outbuf; /* Output buffer */
dma_addr_t outbuf_dma; /* Output buffer dma */
- spinlock_t outlock; /* Output fifo spinlock */
+ spinlock_t lock; /* fifo spinlock */
unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
struct timer_list io_retry; /* Retry timer */
unsigned long stop_retry; /* Time to give up, in jiffies */
unsigned int retry_delay; /* Delay length in ms */
struct work_struct reset_work; /* Task context for resets */
+ struct work_struct restart_work; /* waking up for output to be done in a task */
wait_queue_head_t wait; /* For sleeping */
+ int ledcount; /* counting the number of active leds */
};
#define hid_to_usb_dev(hid_dev) \
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index ce52bf2f235..d73f5f473e3 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -248,6 +248,18 @@ config SENSORS_ASB100
This driver can also be built as a module. If so, the module
will be called asb100.
+config SENSORS_ATK0110
+ tristate "ASUS ATK0110 ACPI hwmon"
+ depends on X86 && ACPI && EXPERIMENTAL
+ help
+ If you say yes here you get support for the ACPI hardware
+ monitoring interface found in many ASUS motherboards. This
+ driver will provide readings of fans, voltages and temperatures
+ through the system firmware.
+
+ This driver can also be built as a module. If so, the module
+ will be called asus_atk0110.
+
config SENSORS_ATXP1
tristate "Attansic ATXP1 VID controller"
depends on I2C && EXPERIMENTAL
@@ -358,6 +370,16 @@ config SENSORS_FSCHMD
This driver can also be built as a module. If so, the module
will be called fschmd.
+config SENSORS_G760A
+ tristate "GMT G760A"
+ depends on I2C
+ help
+ If you say yes here you get support for Global Mixed-mode
+ Technology Inc G760A fan speed PWM controller chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called g760a.
+
config SENSORS_GL518SM
tristate "Genesys Logic GL518SM"
depends on I2C
@@ -670,6 +692,16 @@ config SENSORS_PCF8591
These devices are hard to detect and rarely found on mainstream
hardware. If unsure, say N.
+config SENSORS_SHT15
+ tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
+ depends on GENERIC_GPIO
+ help
+ If you say yes here you get support for the Sensiron SHT10, SHT11,
+ SHT15, SHT71, SHT75 humidity and temperature sensors.
+
+ This driver can also be built as a module. If so, the module
+ will be called sht15.
+
config SENSORS_SIS5595
tristate "Silicon Integrated Systems Corp. SiS5595"
depends on PCI
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 3a6b1f06f8f..0ae26984ba4 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o
obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
obj-$(CONFIG_SENSORS_AMS) += ams/
+obj-$(CONFIG_SENSORS_ATK0110) += asus_atk0110.o
obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
obj-$(CONFIG_SENSORS_DME1737) += dme1737.o
@@ -42,6 +43,7 @@ obj-$(CONFIG_SENSORS_F75375S) += f75375s.o
obj-$(CONFIG_SENSORS_FSCHER) += fscher.o
obj-$(CONFIG_SENSORS_FSCHMD) += fschmd.o
obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o
+obj-$(CONFIG_SENSORS_G760A) += g760a.o
obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o
obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o
obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o
@@ -74,6 +76,7 @@ obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
+obj-$(CONFIG_SENSORS_SHT15) += sht15.o
obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
new file mode 100644
index 00000000000..0897edef257
--- /dev/null
+++ b/drivers/hwmon/asus_atk0110.c
@@ -0,0 +1,1009 @@
+/*
+ * Copyright (C) 2007-2009 Luca Tettamanti <kronos.it@gmail.com>
+ *
+ * This file is released under the GPLv2
+ * See COPYING in the top level directory of the kernel tree.
+ */
+
+#include <linux/kernel.h>
+#include <linux/hwmon.h>
+#include <linux/list.h>
+#include <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acpixf.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+
+
+#define ATK_HID "ATK0110"
+
+/* Minimum time between readings, enforced in order to avoid
+ * hogging the CPU.
+ */
+#define CACHE_TIME HZ
+
+#define BOARD_ID "MBIF"
+#define METHOD_ENUMERATE "GGRP"
+#define METHOD_READ "GITM"
+#define METHOD_WRITE "SITM"
+#define METHOD_OLD_READ_TMP "RTMP"
+#define METHOD_OLD_READ_VLT "RVLT"
+#define METHOD_OLD_READ_FAN "RFAN"
+#define METHOD_OLD_ENUM_TMP "TSIF"
+#define METHOD_OLD_ENUM_VLT "VSIF"
+#define METHOD_OLD_ENUM_FAN "FSIF"
+
+#define ATK_MUX_HWMON 0x00000006ULL
+
+#define ATK_CLASS_MASK 0xff000000ULL
+#define ATK_CLASS_FREQ_CTL 0x03000000ULL
+#define ATK_CLASS_FAN_CTL 0x04000000ULL
+#define ATK_CLASS_HWMON 0x06000000ULL
+
+#define ATK_TYPE_MASK 0x00ff0000ULL
+#define HWMON_TYPE_VOLT 0x00020000ULL
+#define HWMON_TYPE_TEMP 0x00030000ULL
+#define HWMON_TYPE_FAN 0x00040000ULL
+
+#define HWMON_SENSOR_ID_MASK 0x0000ffffULL
+
+enum atk_pack_member {
+ HWMON_PACK_FLAGS,
+ HWMON_PACK_NAME,
+ HWMON_PACK_LIMIT1,
+ HWMON_PACK_LIMIT2,
+ HWMON_PACK_ENABLE
+};
+
+/* New package format */
+#define _HWMON_NEW_PACK_SIZE 7
+#define _HWMON_NEW_PACK_FLAGS 0
+#define _HWMON_NEW_PACK_NAME 1
+#define _HWMON_NEW_PACK_UNK1 2
+#define _HWMON_NEW_PACK_UNK2 3
+#define _HWMON_NEW_PACK_LIMIT1 4
+#define _HWMON_NEW_PACK_LIMIT2 5
+#define _HWMON_NEW_PACK_ENABLE 6
+
+/* Old package format */
+#define _HWMON_OLD_PACK_SIZE 5
+#define _HWMON_OLD_PACK_FLAGS 0
+#define _HWMON_OLD_PACK_NAME 1
+#define _HWMON_OLD_PACK_LIMIT1 2
+#define _HWMON_OLD_PACK_LIMIT2 3
+#define _HWMON_OLD_PACK_ENABLE 4
+
+
+struct atk_data {
+ struct device *hwmon_dev;
+ acpi_handle atk_handle;
+ struct acpi_device *acpi_dev;
+
+ bool old_interface;
+
+ /* old interface */
+ acpi_handle rtmp_handle;
+ acpi_handle rvlt_handle;
+ acpi_handle rfan_handle;
+ /* new inteface */
+ acpi_handle enumerate_handle;
+ acpi_handle read_handle;
+
+ int voltage_count;
+ int temperature_count;
+ int fan_count;
+ struct list_head sensor_list;
+};
+
+
+typedef ssize_t (*sysfs_show_func)(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static const struct acpi_device_id atk_ids[] = {
+ {ATK_HID, 0},
+ {"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, atk_ids);
+
+#define ATTR_NAME_SIZE 16 /* Worst case is "tempN_input" */
+
+struct atk_sensor_data {
+ struct list_head list;
+ struct atk_data *data;
+ struct device_attribute label_attr;
+ struct device_attribute input_attr;
+ struct device_attribute limit1_attr;
+ struct device_attribute limit2_attr;
+ char label_attr_name[ATTR_NAME_SIZE];
+ char input_attr_name[ATTR_NAME_SIZE];
+ char limit1_attr_name[ATTR_NAME_SIZE];
+ char limit2_attr_name[ATTR_NAME_SIZE];
+ u64 id;
+ u64 type;
+ u64 limit1;
+ u64 limit2;
+ u64 cached_value;
+ unsigned long last_updated; /* in jiffies */
+ bool is_valid;
+ char const *acpi_name;
+};
+
+struct atk_acpi_buffer_u64 {
+ union acpi_object buf;
+ u64 value;
+};
+
+static int atk_add(struct acpi_device *device);
+static int atk_remove(struct acpi_device *device, int type);
+static void atk_print_sensor(struct atk_data *data, union acpi_object *obj);
+static int atk_read_value(struct atk_sensor_data *sensor, u64 *value);
+static void atk_free_sensors(struct atk_data *data);
+
+static struct acpi_driver atk_driver = {
+ .name = ATK_HID,
+ .class = "hwmon",
+ .ids = atk_ids,
+ .ops = {
+ .add = atk_add,
+ .remove = atk_remove,
+ },
+};
+
+#define input_to_atk_sensor(attr) \
+ container_of(attr, struct atk_sensor_data, input_attr)
+
+#define label_to_atk_sensor(attr) \
+ container_of(attr, struct atk_sensor_data, label_attr)
+
+#define limit1_to_atk_sensor(attr) \
+ container_of(attr, struct atk_sensor_data, limit1_attr)
+
+#define limit2_to_atk_sensor(attr) \
+ container_of(attr, struct atk_sensor_data, limit2_attr)
+
+static ssize_t atk_input_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct atk_sensor_data *s = input_to_atk_sensor(attr);
+ u64 value;
+ int err;
+
+ err = atk_read_value(s, &value);
+ if (err)
+ return err;
+
+ if (s->type == HWMON_TYPE_TEMP)
+ /* ACPI returns decidegree */
+ value *= 100;
+
+ return sprintf(buf, "%llu\n", value);
+}
+
+static ssize_t atk_label_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct atk_sensor_data *s = label_to_atk_sensor(attr);
+
+ return sprintf(buf, "%s\n", s->acpi_name);
+}
+
+static ssize_t atk_limit1_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct atk_sensor_data *s = limit1_to_atk_sensor(attr);
+ u64 value = s->limit1;
+
+ if (s->type == HWMON_TYPE_TEMP)
+ value *= 100;
+
+ return sprintf(buf, "%lld\n", value);
+}
+
+static ssize_t atk_limit2_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct atk_sensor_data *s = limit2_to_atk_sensor(attr);
+ u64 value = s->limit2;
+
+ if (s->type == HWMON_TYPE_TEMP)
+ value *= 100;
+
+ return sprintf(buf, "%lld\n", value);
+}
+
+static ssize_t atk_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "atk0110\n");
+}
+static struct device_attribute atk_name_attr =
+ __ATTR(name, 0444, atk_name_show, NULL);
+
+static void atk_init_attribute(struct device_attribute *attr, char *name,
+ sysfs_show_func show)
+{
+ attr->attr.name = name;
+ attr->attr.mode = 0444;
+ attr->show = show;
+ attr->store = NULL;
+}
+
+
+static union acpi_object *atk_get_pack_member(struct atk_data *data,
+ union acpi_object *pack,
+ enum atk_pack_member m)
+{
+ bool old_if = data->old_interface;
+ int offset;
+
+ switch (m) {
+ case HWMON_PACK_FLAGS:
+ offset = old_if ? _HWMON_OLD_PACK_FLAGS : _HWMON_NEW_PACK_FLAGS;
+ break;
+ case HWMON_PACK_NAME:
+ offset = old_if ? _HWMON_OLD_PACK_NAME : _HWMON_NEW_PACK_NAME;
+ break;
+ case HWMON_PACK_LIMIT1:
+ offset = old_if ? _HWMON_OLD_PACK_LIMIT1 :
+ _HWMON_NEW_PACK_LIMIT1;
+ break;
+ case HWMON_PACK_LIMIT2:
+ offset = old_if ? _HWMON_OLD_PACK_LIMIT2 :
+ _HWMON_NEW_PACK_LIMIT2;
+ break;
+ case HWMON_PACK_ENABLE:
+ offset = old_if ? _HWMON_OLD_PACK_ENABLE :
+ _HWMON_NEW_PACK_ENABLE;
+ break;
+ default:
+ return NULL;
+ }
+
+ return &pack->package.elements[offset];
+}
+
+
+/* New package format is:
+ * - flag (int)
+ * class - used for de-muxing the request to the correct GITn
+ * type (volt, temp, fan)
+ * sensor id |
+ * sensor id - used for de-muxing the request _inside_ the GITn
+ * - name (str)
+ * - unknown (int)
+ * - unknown (int)
+ * - limit1 (int)
+ * - limit2 (int)
+ * - enable (int)
+ *
+ * The old package has the same format but it's missing the two unknown fields.
+ */
+static int validate_hwmon_pack(struct atk_data *data, union acpi_object *obj)
+{
+ struct device *dev = &data->acpi_dev->dev;
+ union acpi_object *tmp;
+ bool old_if = data->old_interface;
+ int const expected_size = old_if ? _HWMON_OLD_PACK_SIZE :
+ _HWMON_NEW_PACK_SIZE;
+
+ if (obj->type != ACPI_TYPE_PACKAGE) {
+ dev_warn(dev, "Invalid type: %d\n", obj->type);
+ return -EINVAL;
+ }
+
+ if (obj->package.count != expected_size) {
+ dev_warn(dev, "Invalid package size: %d, expected: %d\n",
+ obj->package.count, expected_size);
+ return -EINVAL;
+ }
+
+ tmp = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
+ if (tmp->type != ACPI_TYPE_INTEGER) {
+ dev_warn(dev, "Invalid type (flag): %d\n", tmp->type);
+ return -EINVAL;
+ }
+
+ tmp = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
+ if (tmp->type != ACPI_TYPE_STRING) {
+ dev_warn(dev, "Invalid type (name): %d\n", tmp->type);
+ return -EINVAL;
+ }
+
+ /* Don't check... we don't know what they're useful for anyway */
+#if 0
+ tmp = &obj->package.elements[HWMON_PACK_UNK1];
+ if (tmp->type != ACPI_TYPE_INTEGER) {
+ dev_warn(dev, "Invalid type (unk1): %d\n", tmp->type);
+ return -EINVAL;
+ }
+
+ tmp = &obj->package.elements[HWMON_PACK_UNK2];
+ if (tmp->type != ACPI_TYPE_INTEGER) {
+ dev_warn(dev, "Invalid type (unk2): %d\n", tmp->type);
+ return -EINVAL;
+ }
+#endif
+
+ tmp = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
+ if (tmp->type != ACPI_TYPE_INTEGER) {
+ dev_warn(dev, "Invalid type (limit1): %d\n", tmp->type);
+ return -EINVAL;
+ }
+
+ tmp = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);
+ if (tmp->type != ACPI_TYPE_INTEGER) {
+ dev_warn(dev, "Invalid type (limit2): %d\n", tmp->type);
+ return -EINVAL;
+ }
+
+ tmp = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);
+ if (tmp->type != ACPI_TYPE_INTEGER) {
+ dev_warn(dev, "Invalid type (enable): %d\n", tmp->type);
+ return -EINVAL;
+ }
+
+ atk_print_sensor(data, obj);
+
+ return 0;
+}
+
+static char const *atk_sensor_type(union acpi_object *flags)
+{
+ u64 type = flags->integer.value & ATK_TYPE_MASK;
+ char const *what;
+
+ switch (type) {
+ case HWMON_TYPE_VOLT:
+ what = "voltage";
+ break;
+ case HWMON_TYPE_TEMP:
+ what = "temperature";
+ break;
+ case HWMON_TYPE_FAN:
+ what = "fan";
+ break;
+ default:
+ what = "unknown";
+ break;
+ }
+
+ return what;
+}
+
+static void atk_print_sensor(struct atk_data *data, union acpi_object *obj)
+{
+#ifdef DEBUG
+ struct device *dev = &data->acpi_dev->dev;
+ union acpi_object *flags;
+ union acpi_object *name;
+ union acpi_object *limit1;
+ union acpi_object *limit2;
+ union acpi_object *enable;
+ char const *what;
+
+ flags = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
+ name = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
+ limit1 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
+ limit2 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);
+ enable = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);
+
+ what = atk_sensor_type(flags);
+
+ dev_dbg(dev, "%s: %#llx %s [%llu-%llu] %s\n", what,
+ flags->integer.value,
+ name->string.pointer,
+ limit1->integer.value, limit2->integer.value,
+ enable->integer.value ? "enabled" : "disabled");
+#endif
+}
+
+static int atk_read_value_old(struct atk_sensor_data *sensor, u64 *value)
+{
+ struct atk_data *data = sensor->data;
+ struct device *dev = &data->acpi_dev->dev;
+ struct acpi_object_list params;
+ union acpi_object id;
+ acpi_status status;
+ acpi_handle method;
+
+ switch (sensor->type) {
+ case HWMON_TYPE_VOLT:
+ method = data->rvlt_handle;
+ break;
+ case HWMON_TYPE_TEMP:
+ method = data->rtmp_handle;
+ break;
+ case HWMON_TYPE_FAN:
+ method = data->rfan_handle;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ id.type = ACPI_TYPE_INTEGER;
+ id.integer.value = sensor->id;
+
+ params.count = 1;
+ params.pointer = &id;
+
+ status = acpi_evaluate_integer(method, NULL, &params, value);
+ if (status != AE_OK) {
+ dev_warn(dev, "%s: ACPI exception: %s\n", __func__,
+ acpi_format_exception(status));
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
+{
+ struct atk_data *data = sensor->data;
+ struct device *dev = &data->acpi_dev->dev;
+ struct acpi_object_list params;
+ struct acpi_buffer ret;
+ union acpi_object id;
+ struct atk_acpi_buffer_u64 tmp;
+ acpi_status status;
+
+ id.type = ACPI_TYPE_INTEGER;
+ id.integer.value = sensor->id;
+
+ params.count = 1;
+ params.pointer = &id;
+
+ tmp.buf.type = ACPI_TYPE_BUFFER;
+ tmp.buf.buffer.pointer = (u8 *)&tmp.value;
+ tmp.buf.buffer.length = sizeof(u64);
+ ret.length = sizeof(tmp);
+ ret.pointer = &tmp;
+
+ status = acpi_evaluate_object_typed(data->read_handle, NULL, &params,
+ &ret, ACPI_TYPE_BUFFER);
+ if (status != AE_OK) {
+ dev_warn(dev, "%s: ACPI exception: %s\n", __func__,
+ acpi_format_exception(status));
+ return -EIO;
+ }
+
+ /* Return buffer format:
+ * [0-3] "value" is valid flag
+ * [4-7] value
+ */
+ if (!(tmp.value & 0xffffffff)) {
+ /* The reading is not valid, possible causes:
+ * - sensor failure
+ * - enumeration was FUBAR (and we didn't notice)
+ */
+ dev_info(dev, "Failure: %#llx\n", tmp.value);
+ return -EIO;
+ }
+
+ *value = (tmp.value & 0xffffffff00000000ULL) >> 32;
+
+ return 0;
+}
+
+static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)
+{
+ int err;
+
+ if (!sensor->is_valid ||
+ time_after(jiffies, sensor->last_updated + CACHE_TIME)) {
+ if (sensor->data->old_interface)
+ err = atk_read_value_old(sensor, value);
+ else
+ err = atk_read_value_new(sensor, value);
+
+ sensor->is_valid = true;
+ sensor->last_updated = jiffies;
+ sensor->cached_value = *value;
+ } else {
+ *value = sensor->cached_value;
+ err = 0;
+ }
+
+ return err;
+}
+
+static int atk_add_sensor(struct atk_data *data, union acpi_object *obj)
+{
+ struct device *dev = &data->acpi_dev->dev;
+ union acpi_object *flags;
+ union acpi_object *name;
+ union acpi_object *limit1;
+ union acpi_object *limit2;
+ union acpi_object *enable;
+ struct atk_sensor_data *sensor;
+ char const *base_name;
+ char const *limit1_name;
+ char const *limit2_name;
+ u64 type;
+ int err;
+ int *num;
+ int start;
+
+ if (obj->type != ACPI_TYPE_PACKAGE) {
+ /* wft is this? */
+ dev_warn(dev, "Unknown type for ACPI object: (%d)\n",
+ obj->type);
+ return -EINVAL;
+ }
+
+ err = validate_hwmon_pack(data, obj);
+ if (err)
+ return err;
+
+ /* Ok, we have a valid hwmon package */
+ type = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS)->integer.value
+ & ATK_TYPE_MASK;
+
+ switch (type) {
+ case HWMON_TYPE_VOLT:
+ base_name = "in";
+ limit1_name = "min";
+ limit2_name = "max";
+ num = &data->voltage_count;
+ start = 0;
+ break;
+ case HWMON_TYPE_TEMP:
+ base_name = "temp";
+ limit1_name = "max";
+ limit2_name = "crit";
+ num = &data->temperature_count;
+ start = 1;
+ break;
+ case HWMON_TYPE_FAN:
+ base_name = "fan";
+ limit1_name = "min";
+ limit2_name = "max";
+ num = &data->fan_count;
+ start = 1;
+ break;
+ default:
+ dev_warn(dev, "Unknown sensor type: %#llx\n", type);
+ return -EINVAL;
+ }
+
+ enable = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);
+ if (!enable->integer.value)
+ /* sensor is disabled */
+ return 0;
+
+ flags = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
+ name = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
+ limit1 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
+ limit2 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);
+
+ sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
+ if (!sensor)
+ return -ENOMEM;
+
+ sensor->acpi_name = kstrdup(name->string.pointer, GFP_KERNEL);
+ if (!sensor->acpi_name) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&sensor->list);
+ sensor->type = type;
+ sensor->data = data;
+ sensor->id = flags->integer.value;
+ sensor->limit1 = limit1->integer.value;
+ sensor->limit2 = limit2->integer.value;
+
+ snprintf(sensor->input_attr_name, ATTR_NAME_SIZE,
+ "%s%d_input", base_name, start + *num);
+ atk_init_attribute(&sensor->input_attr,
+ sensor->input_attr_name,
+ atk_input_show);
+
+ snprintf(sensor->label_attr_name, ATTR_NAME_SIZE,
+ "%s%d_label", base_name, start + *num);
+ atk_init_attribute(&sensor->label_attr,
+ sensor->label_attr_name,
+ atk_label_show);
+
+ snprintf(sensor->limit1_attr_name, ATTR_NAME_SIZE,
+ "%s%d_%s", base_name, start + *num, limit1_name);
+ atk_init_attribute(&sensor->limit1_attr,
+ sensor->limit1_attr_name,
+ atk_limit1_show);
+
+ snprintf(sensor->limit2_attr_name, ATTR_NAME_SIZE,
+ "%s%d_%s", base_name, start + *num, limit2_name);
+ atk_init_attribute(&sensor->limit2_attr,
+ sensor->limit2_attr_name,
+ atk_limit2_show);
+
+ list_add(&sensor->list, &data->sensor_list);
+ (*num)++;
+
+ return 1;
+out:
+ kfree(sensor->acpi_name);
+ kfree(sensor);
+ return err;
+}
+
+static int atk_enumerate_old_hwmon(struct atk_data *data)
+{
+ struct device *dev = &data->acpi_dev->dev;
+ struct acpi_buffer buf;
+ union acpi_object *pack;
+ acpi_status status;
+ int i, ret;
+ int count = 0;
+
+ /* Voltages */
+ buf.length = ACPI_ALLOCATE_BUFFER;
+ status = acpi_evaluate_object_typed(data->atk_handle,
+ METHOD_OLD_ENUM_VLT, NULL, &buf, ACPI_TYPE_PACKAGE);
+ if (status != AE_OK) {
+ dev_warn(dev, METHOD_OLD_ENUM_VLT ": ACPI exception: %s\n",
+ acpi_format_exception(status));
+
+ return -ENODEV;
+ }
+
+ pack = buf.pointer;
+ for (i = 1; i < pack->package.count; i++) {
+ union acpi_object *obj = &pack->package.elements[i];
+
+ ret = atk_add_sensor(data, obj);
+ if (ret > 0)
+ count++;
+ }
+ ACPI_FREE(buf.pointer);
+
+ /* Temperatures */
+ buf.length = ACPI_ALLOCATE_BUFFER;
+ status = acpi_evaluate_object_typed(data->atk_handle,
+ METHOD_OLD_ENUM_TMP, NULL, &buf, ACPI_TYPE_PACKAGE);
+ if (status != AE_OK) {
+ dev_warn(dev, METHOD_OLD_ENUM_TMP ": ACPI exception: %s\n",
+ acpi_format_exception(status));
+
+ ret = -ENODEV;
+ goto cleanup;
+ }
+
+ pack = buf.pointer;
+ for (i = 1; i < pack->package.count; i++) {
+ union acpi_object *obj = &pack->package.elements[i];
+
+ ret = atk_add_sensor(data, obj);
+ if (ret > 0)
+ count++;
+ }
+ ACPI_FREE(buf.pointer);
+
+ /* Fans */
+ buf.length = ACPI_ALLOCATE_BUFFER;
+ status = acpi_evaluate_object_typed(data->atk_handle,
+ METHOD_OLD_ENUM_FAN, NULL, &buf, ACPI_TYPE_PACKAGE);
+ if (status != AE_OK) {
+ dev_warn(dev, METHOD_OLD_ENUM_FAN ": ACPI exception: %s\n",
+ acpi_format_exception(status));
+
+ ret = -ENODEV;
+ goto cleanup;
+ }
+
+ pack = buf.pointer;
+ for (i = 1; i < pack->package.count; i++) {
+ union acpi_object *obj = &pack->package.elements[i];
+
+ ret = atk_add_sensor(data, obj);
+ if (ret > 0)
+ count++;
+ }
+ ACPI_FREE(buf.pointer);
+
+ return count;
+cleanup:
+ atk_free_sensors(data);
+ return ret;
+}
+
+static int atk_enumerate_new_hwmon(struct atk_data *data)
+{
+ struct device *dev = &data->acpi_dev->dev;
+ struct acpi_buffer buf;
+ acpi_status ret;
+ struct acpi_object_list params;
+ union acpi_object id;
+ union acpi_object *pack;
+ int err;
+ int i;
+
+ dev_dbg(dev, "Enumerating hwmon sensors\n");
+
+ id.type = ACPI_TYPE_INTEGER;
+ id.integer.value = ATK_MUX_HWMON;
+ params.count = 1;
+ params.pointer = &id;
+
+ buf.length = ACPI_ALLOCATE_BUFFER;
+ ret = acpi_evaluate_object_typed(data->enumerate_handle, NULL, &params,
+ &buf, ACPI_TYPE_PACKAGE);
+ if (ret != AE_OK) {
+ dev_warn(dev, METHOD_ENUMERATE ": ACPI exception: %s\n",
+ acpi_format_exception(ret));
+ return -ENODEV;
+ }
+
+ /* Result must be a package */
+ pack = buf.pointer;
+
+ if (pack->package.count < 1) {
+ dev_dbg(dev, "%s: hwmon package is too small: %d\n", __func__,
+ pack->package.count);
+ err = -EINVAL;
+ goto out;
+ }
+
+ for (i = 0; i < pack->package.count; i++) {
+ union acpi_object *obj = &pack->package.elements[i];
+
+ atk_add_sensor(data, obj);
+ }
+
+ err = data->voltage_count + data->temperature_count + data->fan_count;
+
+out:
+ ACPI_FREE(buf.pointer);
+ return err;
+}
+
+static int atk_create_files(struct atk_data *data)
+{
+ struct atk_sensor_data *s;
+ int err;
+
+ list_for_each_entry(s, &data->sensor_list, list) {
+ err = device_create_file(data->hwmon_dev, &s->input_attr);
+ if (err)
+ return err;
+ err = device_create_file(data->hwmon_dev, &s->label_attr);
+ if (err)
+ return err;
+ err = device_create_file(data->hwmon_dev, &s->limit1_attr);
+ if (err)
+ return err;
+ err = device_create_file(data->hwmon_dev, &s->limit2_attr);
+ if (err)
+ return err;
+ }
+
+ err = device_create_file(data->hwmon_dev, &atk_name_attr);
+
+ return err;
+}
+
+static void atk_remove_files(struct atk_data *data)
+{
+ struct atk_sensor_data *s;
+
+ list_for_each_entry(s, &data->sensor_list, list) {
+ device_remove_file(data->hwmon_dev, &s->input_attr);
+ device_remove_file(data->hwmon_dev, &s->label_attr);
+ device_remove_file(data->hwmon_dev, &s->limit1_attr);
+ device_remove_file(data->hwmon_dev, &s->limit2_attr);
+ }
+ device_remove_file(data->hwmon_dev, &atk_name_attr);
+}
+
+static void atk_free_sensors(struct atk_data *data)
+{
+ struct list_head *head = &data->sensor_list;
+ struct atk_sensor_data *s, *tmp;
+
+ list_for_each_entry_safe(s, tmp, head, list) {
+ kfree(s->acpi_name);
+ kfree(s);
+ }
+}
+
+static int atk_register_hwmon(struct atk_data *data)
+{
+ struct device *dev = &data->acpi_dev->dev;
+ int err;
+
+ dev_dbg(dev, "registering hwmon device\n");
+ data->hwmon_dev = hwmon_device_register(dev);
+ if (IS_ERR(data->hwmon_dev))
+ return PTR_ERR(data->hwmon_dev);
+
+ dev_dbg(dev, "populating sysfs directory\n");
+ err = atk_create_files(data);
+ if (err)
+ goto remove;
+
+ return 0;
+remove:
+ /* Cleanup the registered files */
+ atk_remove_files(data);
+ hwmon_device_unregister(data->hwmon_dev);
+ return err;
+}
+
+static int atk_check_old_if(struct atk_data *data)
+{
+ struct device *dev = &data->acpi_dev->dev;
+ acpi_handle ret;
+ acpi_status status;
+
+ /* RTMP: read temperature */
+ status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_TMP, &ret);
+ if (status != AE_OK) {
+ dev_dbg(dev, "method " METHOD_OLD_READ_TMP " not found: %s\n",
+ acpi_format_exception(status));
+ return -ENODEV;
+ }
+ data->rtmp_handle = ret;
+
+ /* RVLT: read voltage */
+ status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_VLT, &ret);
+ if (status != AE_OK) {
+ dev_dbg(dev, "method " METHOD_OLD_READ_VLT " not found: %s\n",
+ acpi_format_exception(status));
+ return -ENODEV;
+ }
+ data->rvlt_handle = ret;
+
+ /* RFAN: read fan status */
+ status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_FAN, &ret);
+ if (status != AE_OK) {
+ dev_dbg(dev, "method " METHOD_OLD_READ_FAN " not found: %s\n",
+ acpi_format_exception(status));
+ return -ENODEV;
+ }
+ data->rfan_handle = ret;
+
+ return 0;
+}
+
+static int atk_check_new_if(struct atk_data *data)
+{
+ struct device *dev = &data->acpi_dev->dev;
+ acpi_handle ret;
+ acpi_status status;
+
+ /* Enumeration */
+ status = acpi_get_handle(data->atk_handle, METHOD_ENUMERATE, &ret);
+ if (status != AE_OK) {
+ dev_dbg(dev, "method " METHOD_ENUMERATE " not found: %s\n",
+ acpi_format_exception(status));
+ return -ENODEV;
+ }
+ data->enumerate_handle = ret;
+
+ /* De-multiplexer (read) */
+ status = acpi_get_handle(data->atk_handle, METHOD_READ, &ret);
+ if (status != AE_OK) {
+ dev_dbg(dev, "method " METHOD_READ " not found: %s\n",
+ acpi_format_exception(status));
+ return -ENODEV;
+ }
+ data->read_handle = ret;
+
+ return 0;
+}
+
+static int atk_add(struct acpi_device *device)
+{
+ acpi_status ret;
+ int err;
+ struct acpi_buffer buf;
+ union acpi_object *obj;
+ struct atk_data *data;
+
+ dev_dbg(&device->dev, "adding...\n");
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->acpi_dev = device;
+ data->atk_handle = device->handle;
+ INIT_LIST_HEAD(&data->sensor_list);
+
+ buf.length = ACPI_ALLOCATE_BUFFER;
+ ret = acpi_evaluate_object_typed(data->atk_handle, BOARD_ID, NULL,
+ &buf, ACPI_TYPE_PACKAGE);
+ if (ret != AE_OK) {
+ dev_dbg(&device->dev, "atk: method MBIF not found\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ obj = buf.pointer;
+ if (obj->package.count >= 2 &&
+ obj->package.elements[1].type == ACPI_TYPE_STRING) {
+ dev_dbg(&device->dev, "board ID = %s\n",
+ obj->package.elements[1].string.pointer);
+ }
+ ACPI_FREE(buf.pointer);
+
+ /* Check for hwmon methods: first check "old" style methods; note that
+ * both may be present: in this case we stick to the old interface;
+ * analysis of multiple DSDTs indicates that when both interfaces
+ * are present the new one (GGRP/GITM) is not functional.
+ */
+ err = atk_check_old_if(data);
+ if (!err) {
+ dev_dbg(&device->dev, "Using old hwmon interface\n");
+ data->old_interface = true;
+ } else {
+ err = atk_check_new_if(data);
+ if (err)
+ goto out;
+
+ dev_dbg(&device->dev, "Using new hwmon interface\n");
+ data->old_interface = false;
+ }
+
+ if (data->old_interface)
+ err = atk_enumerate_old_hwmon(data);
+ else
+ err = atk_enumerate_new_hwmon(data);
+ if (err < 0)
+ goto out;
+ if (err == 0) {
+ dev_info(&device->dev,
+ "No usable sensor detected, bailing out\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ err = atk_register_hwmon(data);
+ if (err)
+ goto cleanup;
+
+ device->driver_data = data;
+ return 0;
+cleanup:
+ atk_free_sensors(data);
+out:
+ kfree(data);
+ return err;
+}
+
+static int atk_remove(struct acpi_device *device, int type)
+{
+ struct atk_data *data = device->driver_data;
+ dev_dbg(&device->dev, "removing...\n");
+
+ device->driver_data = NULL;
+
+ atk_remove_files(data);
+ atk_free_sensors(data);
+ hwmon_device_unregister(data->hwmon_dev);
+
+ kfree(data);
+
+ return 0;
+}
+
+static int __init atk0110_init(void)
+{
+ int ret;
+
+ ret = acpi_bus_register_driver(&atk_driver);
+ if (ret)
+ pr_info("atk: acpi_bus_register_driver failed: %d\n", ret);
+
+ return ret;
+}
+
+static void __exit atk0110_exit(void)
+{
+ acpi_bus_unregister_driver(&atk_driver);
+}
+
+module_init(atk0110_init);
+module_exit(atk0110_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 18a1ba88816..e2107e533ed 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -1,7 +1,7 @@
/*
* f75375s.c - driver for the Fintek F75375/SP and F75373
* hardware monitoring features
- * Copyright (C) 2006-2007 Riku Voipio <riku.voipio@movial.fi>
+ * Copyright (C) 2006-2007 Riku Voipio
*
* Datasheets available at:
*
@@ -721,7 +721,7 @@ static void __exit sensors_f75375_exit(void)
i2c_del_driver(&f75375_driver);
}
-MODULE_AUTHOR("Riku Voipio <riku.voipio@movial.fi>");
+MODULE_AUTHOR("Riku Voipio");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("F75373/F75375 hardware monitoring driver");
diff --git a/drivers/hwmon/g760a.c b/drivers/hwmon/g760a.c
new file mode 100644
index 00000000000..19c01a49f6b
--- /dev/null
+++ b/drivers/hwmon/g760a.c
@@ -0,0 +1,272 @@
+/*
+ g760a - Driver for the Global Mixed-mode Technology Inc. G760A
+ fan speed PWM controller chip
+
+ Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
+
+ Complete datasheet is available at GMT's website:
+ http://www.gmt.com.tw/datasheet/g760a.pdf
+
+ 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/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/sysfs.h>
+
+static const struct i2c_device_id g760a_id[] = {
+ { "g760a", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, g760a_id);
+
+enum g760a_regs {
+ G760A_REG_SET_CNT = 0x00,
+ G760A_REG_ACT_CNT = 0x01,
+ G760A_REG_FAN_STA = 0x02
+};
+
+#define G760A_REG_FAN_STA_RPM_OFF 0x1 /* +/-20% off */
+#define G760A_REG_FAN_STA_RPM_LOW 0x2 /* below 1920rpm */
+
+/* register data is read (and cached) at most once per second */
+#define G760A_UPDATE_INTERVAL (HZ)
+
+struct g760a_data {
+ struct i2c_client *client;
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+
+ /* board specific parameters */
+ u32 clk; /* default 32kHz */
+ u16 fan_div; /* default P=2 */
+
+ /* g760a register cache */
+ unsigned int valid:1;
+ unsigned long last_updated; /* In jiffies */
+
+ u8 set_cnt; /* PWM (period) count number; 0xff stops fan */
+ u8 act_cnt; /* formula: cnt = (CLK * 30)/(rpm * P) */
+ u8 fan_sta; /* bit 0: set when actual fan speed more than 20%
+ * outside requested fan speed
+ * bit 1: set when fan speed below 1920 rpm */
+};
+
+#define G760A_DEFAULT_CLK 32768
+#define G760A_DEFAULT_FAN_DIV 2
+
+#define PWM_FROM_CNT(cnt) (0xff-(cnt))
+#define PWM_TO_CNT(pwm) (0xff-(pwm))
+
+unsigned int rpm_from_cnt(u8 val, u32 clk, u16 div)
+{
+ return ((val == 0x00) ? 0 : ((clk*30)/(val*div)));
+}
+
+/* new-style driver model */
+static int g760a_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
+static int g760a_remove(struct i2c_client *client);
+
+static struct i2c_driver g760a_driver = {
+ .driver = {
+ .name = "g760a",
+ },
+ .probe = g760a_probe,
+ .remove = g760a_remove,
+ .id_table = g760a_id,
+};
+
+/* read/write wrappers */
+static int g760a_read_value(struct i2c_client *client, enum g760a_regs reg)
+{
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int g760a_write_value(struct i2c_client *client, enum g760a_regs reg,
+ u16 value)
+{
+ return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+/****************************************************************************
+ * sysfs attributes
+ */
+
+static struct g760a_data *g760a_update_client(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct g760a_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + G760A_UPDATE_INTERVAL)
+ || !data->valid) {
+ dev_dbg(&client->dev, "Starting g760a update\n");
+
+ data->set_cnt = g760a_read_value(client, G760A_REG_SET_CNT);
+ data->act_cnt = g760a_read_value(client, G760A_REG_ACT_CNT);
+ data->fan_sta = g760a_read_value(client, G760A_REG_FAN_STA);
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static ssize_t show_fan(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct g760a_data *data = g760a_update_client(dev);
+ unsigned int rpm = 0;
+
+ mutex_lock(&data->update_lock);
+ if (!(data->fan_sta & G760A_REG_FAN_STA_RPM_LOW))
+ rpm = rpm_from_cnt(data->act_cnt, data->clk, data->fan_div);
+ mutex_unlock(&data->update_lock);
+
+ return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t show_fan_alarm(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct g760a_data *data = g760a_update_client(dev);
+
+ int fan_alarm = (data->fan_sta & G760A_REG_FAN_STA_RPM_OFF) ? 1 : 0;
+
+ return sprintf(buf, "%d\n", fan_alarm);
+}
+
+static ssize_t get_pwm(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct g760a_data *data = g760a_update_client(dev);
+
+ return sprintf(buf, "%d\n", PWM_FROM_CNT(data->set_cnt));
+}
+
+static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct g760a_data *data = g760a_update_client(dev);
+ unsigned long val;
+
+ if (strict_strtoul(buf, 10, &val))
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->set_cnt = PWM_TO_CNT(SENSORS_LIMIT(val, 0, 255));
+ g760a_write_value(client, G760A_REG_SET_CNT, data->set_cnt);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm);
+static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL);
+static DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL);
+
+static struct attribute *g760a_attributes[] = {
+ &dev_attr_pwm1.attr,
+ &dev_attr_fan1_input.attr,
+ &dev_attr_fan1_alarm.attr,
+ NULL
+};
+
+static const struct attribute_group g760a_group = {
+ .attrs = g760a_attributes,
+};
+
+/****************************************************************************
+ * new-style driver model code
+ */
+
+static int g760a_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct g760a_data *data;
+ int err;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA))
+ return -EIO;
+
+ data = kzalloc(sizeof(struct g760a_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, data);
+
+ data->client = client;
+ mutex_init(&data->update_lock);
+
+ /* setup default configuration for now */
+ data->fan_div = G760A_DEFAULT_FAN_DIV;
+ data->clk = G760A_DEFAULT_CLK;
+
+ /* Register sysfs hooks */
+ err = sysfs_create_group(&client->dev.kobj, &g760a_group);
+ if (err)
+ goto error_sysfs_create_group;
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ err = PTR_ERR(data->hwmon_dev);
+ goto error_hwmon_device_register;
+ }
+
+ return 0;
+
+error_hwmon_device_register:
+ sysfs_remove_group(&client->dev.kobj, &g760a_group);
+error_sysfs_create_group:
+ kfree(data);
+ i2c_set_clientdata(client, NULL);
+
+ return err;
+}
+
+static int g760a_remove(struct i2c_client *client)
+{
+ struct g760a_data *data = i2c_get_clientdata(client);
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &g760a_group);
+ kfree(data);
+ i2c_set_clientdata(client, NULL);
+
+ return 0;
+}
+
+/* module management */
+
+static int __init g760a_init(void)
+{
+ return i2c_add_driver(&g760a_driver);
+}
+
+static void __exit g760a_exit(void)
+{
+ i2c_del_driver(&g760a_driver);
+}
+
+MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
+MODULE_DESCRIPTION("GMT G760A driver");
+MODULE_LICENSE("GPL");
+
+module_init(g760a_init);
+module_exit(g760a_exit);
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index 55d3dc565be..abca7e9f953 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -34,7 +34,6 @@
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/freezer.h>
-#include <linux/version.h>
#include <linux/uaccess.h>
#include <linux/leds.h>
#include <acpi/acpi_drivers.h>
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c
index 091d95f38aa..e34f9e402a2 100644
--- a/drivers/hwmon/lm95241.c
+++ b/drivers/hwmon/lm95241.c
@@ -87,25 +87,11 @@ I2C_CLIENT_INSMOD_1(lm95241);
(val_h)) * 1000 + (val_l) * 1000 / 256)
/* Functions declaration */
-static int lm95241_attach_adapter(struct i2c_adapter *adapter);
-static int lm95241_detect(struct i2c_adapter *adapter, int address,
- int kind);
static void lm95241_init_client(struct i2c_client *client);
-static int lm95241_detach_client(struct i2c_client *client);
static struct lm95241_data *lm95241_update_device(struct device *dev);
-/* Driver data (common to all clients) */
-static struct i2c_driver lm95241_driver = {
- .driver = {
- .name = "lm95241",
- },
- .attach_adapter = lm95241_attach_adapter,
- .detach_client = lm95241_detach_client,
-};
-
/* Client data (each client gets its own) */
struct lm95241_data {
- struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
unsigned long last_updated, rate; /* in jiffies */
@@ -323,42 +309,16 @@ static const struct attribute_group lm95241_group = {
.attrs = lm95241_attributes,
};
-/* Init/exit code */
-static int lm95241_attach_adapter(struct i2c_adapter *adapter)
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int lm95241_detect(struct i2c_client *new_client, int kind,
+ struct i2c_board_info *info)
{
- if (!(adapter->class & I2C_CLASS_HWMON))
- return 0;
- return i2c_probe(adapter, &addr_data, lm95241_detect);
-}
-
-/*
- * The following function does more than just detection. If detection
- * succeeds, it also registers the new chip.
- */
-static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind)
-{
- struct i2c_client *new_client;
- struct lm95241_data *data;
- int err = 0;
+ struct i2c_adapter *adapter = new_client->adapter;
+ int address = new_client->addr;
const char *name = "";
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- goto exit;
-
- data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL);
- if (!data) {
- err = -ENOMEM;
- goto exit;
- }
-
- /* The common I2C client data is placed right before the
- LM95241-specific data. */
- new_client = &data->client;
- i2c_set_clientdata(new_client, data);
- new_client->addr = address;
- new_client->adapter = adapter;
- new_client->driver = &lm95241_driver;
- new_client->flags = 0;
+ return -ENODEV;
/*
* Now we do the remaining detection. A negative kind means that
@@ -378,7 +338,7 @@ static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind)
dev_dbg(&adapter->dev,
"LM95241 detection failed at 0x%02x.\n",
address);
- goto exit_free;
+ return -ENODEV;
}
}
@@ -392,23 +352,32 @@ static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind)
if (kind <= 0) { /* identification failed */
dev_info(&adapter->dev, "Unsupported chip\n");
- goto exit_free;
+ return -ENODEV;
}
}
}
+ /* Fill the i2c board info */
if (kind == lm95241)
name = "lm95241";
+ strlcpy(info->type, name, I2C_NAME_SIZE);
+ return 0;
+}
- /* We can fill in the remaining client fields */
- strlcpy(new_client->name, name, I2C_NAME_SIZE);
- data->valid = 0;
- mutex_init(&data->update_lock);
+static int lm95241_probe(struct i2c_client *new_client,
+ const struct i2c_device_id *id)
+{
+ struct lm95241_data *data;
+ int err;
- /* Tell the I2C layer a new client has arrived */
- err = i2c_attach_client(new_client);
- if (err)
- goto exit_free;
+ data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ i2c_set_clientdata(new_client, data);
+ mutex_init(&data->update_lock);
/* Initialize the LM95241 chip */
lm95241_init_client(new_client);
@@ -416,7 +385,7 @@ static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind)
/* Register sysfs hooks */
err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group);
if (err)
- goto exit_detach;
+ goto exit_free;
data->hwmon_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->hwmon_dev)) {
@@ -428,8 +397,6 @@ static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove_files:
sysfs_remove_group(&new_client->dev.kobj, &lm95241_group);
-exit_detach:
- i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
@@ -456,18 +423,14 @@ static void lm95241_init_client(struct i2c_client *client)
data->model);
}
-static int lm95241_detach_client(struct i2c_client *client)
+static int lm95241_remove(struct i2c_client *client)
{
struct lm95241_data *data = i2c_get_clientdata(client);
- int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm95241_group);
- err = i2c_detach_client(client);
- if (err)
- return err;
-
+ i2c_set_clientdata(client, NULL);
kfree(data);
return 0;
}
@@ -509,6 +472,25 @@ static struct lm95241_data *lm95241_update_device(struct device *dev)
return data;
}
+/* Driver data (common to all clients) */
+static const struct i2c_device_id lm95241_id[] = {
+ { "lm95241", lm95241 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, lm95241_id);
+
+static struct i2c_driver lm95241_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "lm95241",
+ },
+ .probe = lm95241_probe,
+ .remove = lm95241_remove,
+ .id_table = lm95241_id,
+ .detect = lm95241_detect,
+ .address_data = &addr_data,
+};
+
static int __init sensors_lm95241_init(void)
{
return i2c_add_driver(&lm95241_driver);
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
new file mode 100644
index 00000000000..6cbdc2fea73
--- /dev/null
+++ b/drivers/hwmon/sht15.c
@@ -0,0 +1,692 @@
+/*
+ * sht15.c - support for the SHT15 Temperature and Humidity Sensor
+ *
+ * Copyright (c) 2009 Jonathan Cameron
+ *
+ * Copyright (c) 2007 Wouter Horre
+ *
+ * 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.
+ *
+ * Currently ignoring checksum on readings.
+ * Default resolution only (14bit temp, 12bit humidity)
+ * Ignoring battery status.
+ * Heater not enabled.
+ * Timings are all conservative.
+ *
+ * Data sheet available (1/2009) at
+ * http://www.sensirion.ch/en/pdf/product_information/Datasheet-humidity-sensor-SHT1x.pdf
+ *
+ * Regulator supply name = vcc
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/err.h>
+#include <linux/sht15.h>
+#include <linux/regulator/consumer.h>
+#include <asm/atomic.h>
+
+#define SHT15_MEASURE_TEMP 3
+#define SHT15_MEASURE_RH 5
+
+#define SHT15_READING_NOTHING 0
+#define SHT15_READING_TEMP 1
+#define SHT15_READING_HUMID 2
+
+/* Min timings in nsecs */
+#define SHT15_TSCKL 100 /* clock low */
+#define SHT15_TSCKH 100 /* clock high */
+#define SHT15_TSU 150 /* data setup time */
+
+/**
+ * struct sht15_temppair - elements of voltage dependant temp calc
+ * @vdd: supply voltage in microvolts
+ * @d1: see data sheet
+ */
+struct sht15_temppair {
+ int vdd; /* microvolts */
+ int d1;
+};
+
+/* Table 9 from data sheet - relates temperature calculation
+ * to supply voltage.
+ */
+static const struct sht15_temppair temppoints[] = {
+ { 2500000, -39400 },
+ { 3000000, -39600 },
+ { 3500000, -39700 },
+ { 4000000, -39800 },
+ { 5000000, -40100 },
+};
+
+/**
+ * struct sht15_data - device instance specific data
+ * @pdata: platform data (gpio's etc)
+ * @read_work: bh of interrupt handler
+ * @wait_queue: wait queue for getting values from device
+ * @val_temp: last temperature value read from device
+ * @val_humid: last humidity value read from device
+ * @flag: status flag used to identify what the last request was
+ * @valid: are the current stored values valid (start condition)
+ * @last_updat: time of last update
+ * @read_lock: mutex to ensure only one read in progress
+ * at a time.
+ * @dev: associate device structure
+ * @hwmon_dev: device associated with hwmon subsystem
+ * @reg: associated regulator (if specified)
+ * @nb: notifier block to handle notifications of voltage changes
+ * @supply_uV: local copy of supply voltage used to allow
+ * use of regulator consumer if available
+ * @supply_uV_valid: indicates that an updated value has not yet
+ * been obtained from the regulator and so any calculations
+ * based upon it will be invalid.
+ * @update_supply_work: work struct that is used to update the supply_uV
+ * @interrupt_handled: flag used to indicate a hander has been scheduled
+ */
+struct sht15_data {
+ struct sht15_platform_data *pdata;
+ struct work_struct read_work;
+ wait_queue_head_t wait_queue;
+ uint16_t val_temp;
+ uint16_t val_humid;
+ u8 flag;
+ u8 valid;
+ unsigned long last_updat;
+ struct mutex read_lock;
+ struct device *dev;
+ struct device *hwmon_dev;
+ struct regulator *reg;
+ struct notifier_block nb;
+ int supply_uV;
+ int supply_uV_valid;
+ struct work_struct update_supply_work;
+ atomic_t interrupt_handled;
+};
+
+/**
+ * sht15_connection_reset() - reset the comms interface
+ * @data: sht15 specific data
+ *
+ * This implements section 3.4 of the data sheet
+ */
+static void sht15_connection_reset(struct sht15_data *data)
+{
+ int i;
+ gpio_direction_output(data->pdata->gpio_data, 1);
+ ndelay(SHT15_TSCKL);
+ gpio_set_value(data->pdata->gpio_sck, 0);
+ ndelay(SHT15_TSCKL);
+ for (i = 0; i < 9; ++i) {
+ gpio_set_value(data->pdata->gpio_sck, 1);
+ ndelay(SHT15_TSCKH);
+ gpio_set_value(data->pdata->gpio_sck, 0);
+ ndelay(SHT15_TSCKL);
+ }
+}
+/**
+ * sht15_send_bit() - send an individual bit to the device
+ * @data: device state data
+ * @val: value of bit to be sent
+ **/
+static inline void sht15_send_bit(struct sht15_data *data, int val)
+{
+
+ gpio_set_value(data->pdata->gpio_data, val);
+ ndelay(SHT15_TSU);
+ gpio_set_value(data->pdata->gpio_sck, 1);
+ ndelay(SHT15_TSCKH);
+ gpio_set_value(data->pdata->gpio_sck, 0);
+ ndelay(SHT15_TSCKL); /* clock low time */
+}
+
+/**
+ * sht15_transmission_start() - specific sequence for new transmission
+ *
+ * @data: device state data
+ * Timings for this are not documented on the data sheet, so very
+ * conservative ones used in implementation. This implements
+ * figure 12 on the data sheet.
+ **/
+static void sht15_transmission_start(struct sht15_data *data)
+{
+ /* ensure data is high and output */
+ gpio_direction_output(data->pdata->gpio_data, 1);
+ ndelay(SHT15_TSU);
+ gpio_set_value(data->pdata->gpio_sck, 0);
+ ndelay(SHT15_TSCKL);
+ gpio_set_value(data->pdata->gpio_sck, 1);
+ ndelay(SHT15_TSCKH);
+ gpio_set_value(data->pdata->gpio_data, 0);
+ ndelay(SHT15_TSU);
+ gpio_set_value(data->pdata->gpio_sck, 0);
+ ndelay(SHT15_TSCKL);
+ gpio_set_value(data->pdata->gpio_sck, 1);
+ ndelay(SHT15_TSCKH);
+ gpio_set_value(data->pdata->gpio_data, 1);
+ ndelay(SHT15_TSU);
+ gpio_set_value(data->pdata->gpio_sck, 0);
+ ndelay(SHT15_TSCKL);
+}
+/**
+ * sht15_send_byte() - send a single byte to the device
+ * @data: device state
+ * @byte: value to be sent
+ **/
+static void sht15_send_byte(struct sht15_data *data, u8 byte)
+{
+ int i;
+ for (i = 0; i < 8; i++) {
+ sht15_send_bit(data, !!(byte & 0x80));
+ byte <<= 1;
+ }
+}
+/**
+ * sht15_wait_for_response() - checks for ack from device
+ * @data: device state
+ **/
+static int sht15_wait_for_response(struct sht15_data *data)
+{
+ gpio_direction_input(data->pdata->gpio_data);
+ gpio_set_value(data->pdata->gpio_sck, 1);
+ ndelay(SHT15_TSCKH);
+ if (gpio_get_value(data->pdata->gpio_data)) {
+ gpio_set_value(data->pdata->gpio_sck, 0);
+ dev_err(data->dev, "Command not acknowledged\n");
+ sht15_connection_reset(data);
+ return -EIO;
+ }
+ gpio_set_value(data->pdata->gpio_sck, 0);
+ ndelay(SHT15_TSCKL);
+ return 0;
+}
+
+/**
+ * sht15_send_cmd() - Sends a command to the device.
+ * @data: device state
+ * @cmd: command byte to be sent
+ *
+ * On entry, sck is output low, data is output pull high
+ * and the interrupt disabled.
+ **/
+static int sht15_send_cmd(struct sht15_data *data, u8 cmd)
+{
+ int ret = 0;
+ sht15_transmission_start(data);
+ sht15_send_byte(data, cmd);
+ ret = sht15_wait_for_response(data);
+ return ret;
+}
+/**
+ * sht15_update_single_val() - get a new value from device
+ * @data: device instance specific data
+ * @command: command sent to request value
+ * @timeout_msecs: timeout after which comms are assumed
+ * to have failed are reset.
+ **/
+static inline int sht15_update_single_val(struct sht15_data *data,
+ int command,
+ int timeout_msecs)
+{
+ int ret;
+ ret = sht15_send_cmd(data, command);
+ if (ret)
+ return ret;
+
+ gpio_direction_input(data->pdata->gpio_data);
+ atomic_set(&data->interrupt_handled, 0);
+
+ enable_irq(gpio_to_irq(data->pdata->gpio_data));
+ if (gpio_get_value(data->pdata->gpio_data) == 0) {
+ disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
+ /* Only relevant if the interrupt hasn't occured. */
+ if (!atomic_read(&data->interrupt_handled))
+ schedule_work(&data->read_work);
+ }
+ ret = wait_event_timeout(data->wait_queue,
+ (data->flag == SHT15_READING_NOTHING),
+ msecs_to_jiffies(timeout_msecs));
+ if (ret == 0) {/* timeout occurred */
+ disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));;
+ sht15_connection_reset(data);
+ return -ETIME;
+ }
+ return 0;
+}
+
+/**
+ * sht15_update_vals() - get updated readings from device if too old
+ * @data: device state
+ **/
+static int sht15_update_vals(struct sht15_data *data)
+{
+ int ret = 0;
+ int timeout = HZ;
+
+ mutex_lock(&data->read_lock);
+ if (time_after(jiffies, data->last_updat + timeout)
+ || !data->valid) {
+ data->flag = SHT15_READING_HUMID;
+ ret = sht15_update_single_val(data, SHT15_MEASURE_RH, 160);
+ if (ret)
+ goto error_ret;
+ data->flag = SHT15_READING_TEMP;
+ ret = sht15_update_single_val(data, SHT15_MEASURE_TEMP, 400);
+ if (ret)
+ goto error_ret;
+ data->valid = 1;
+ data->last_updat = jiffies;
+ }
+error_ret:
+ mutex_unlock(&data->read_lock);
+
+ return ret;
+}
+
+/**
+ * sht15_calc_temp() - convert the raw reading to a temperature
+ * @data: device state
+ *
+ * As per section 4.3 of the data sheet.
+ **/
+static inline int sht15_calc_temp(struct sht15_data *data)
+{
+ int d1 = 0;
+ int i;
+
+ for (i = 1; i < ARRAY_SIZE(temppoints) - 1; i++)
+ /* Find pointer to interpolate */
+ if (data->supply_uV > temppoints[i - 1].vdd) {
+ d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd)
+ * (temppoints[i].d1 - temppoints[i - 1].d1)
+ / (temppoints[i].vdd - temppoints[i - 1].vdd)
+ + temppoints[i - 1].d1;
+ break;
+ }
+
+ return data->val_temp*10 + d1;
+}
+
+/**
+ * sht15_calc_humid() - using last temperature convert raw to humid
+ * @data: device state
+ *
+ * This is the temperature compensated version as per section 4.2 of
+ * the data sheet.
+ **/
+static inline int sht15_calc_humid(struct sht15_data *data)
+{
+ int RHlinear; /* milli percent */
+ int temp = sht15_calc_temp(data);
+
+ const int c1 = -4;
+ const int c2 = 40500; /* x 10 ^ -6 */
+ const int c3 = 2800; /* x10 ^ -9 */
+
+ RHlinear = c1*1000
+ + c2 * data->val_humid/1000
+ + (data->val_humid * data->val_humid * c3)/1000000;
+ return (temp - 25000) * (10000 + 800 * data->val_humid)
+ / 1000000 + RHlinear;
+}
+
+static ssize_t sht15_show_temp(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int ret;
+ struct sht15_data *data = dev_get_drvdata(dev);
+
+ /* Technically no need to read humidity as well */
+ ret = sht15_update_vals(data);
+
+ return ret ? ret : sprintf(buf, "%d\n",
+ sht15_calc_temp(data));
+}
+
+static ssize_t sht15_show_humidity(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int ret;
+ struct sht15_data *data = dev_get_drvdata(dev);
+
+ ret = sht15_update_vals(data);
+
+ return ret ? ret : sprintf(buf, "%d\n", sht15_calc_humid(data));
+
+};
+static ssize_t show_name(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ return sprintf(buf, "%s\n", pdev->name);
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input,
+ S_IRUGO, sht15_show_temp,
+ NULL, 0);
+static SENSOR_DEVICE_ATTR(humidity1_input,
+ S_IRUGO, sht15_show_humidity,
+ NULL, 0);
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+static struct attribute *sht15_attrs[] = {
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_humidity1_input.dev_attr.attr,
+ &dev_attr_name.attr,
+ NULL,
+};
+
+static const struct attribute_group sht15_attr_group = {
+ .attrs = sht15_attrs,
+};
+
+static irqreturn_t sht15_interrupt_fired(int irq, void *d)
+{
+ struct sht15_data *data = d;
+ /* First disable the interrupt */
+ disable_irq_nosync(irq);
+ atomic_inc(&data->interrupt_handled);
+ /* Then schedule a reading work struct */
+ if (data->flag != SHT15_READING_NOTHING)
+ schedule_work(&data->read_work);
+ return IRQ_HANDLED;
+}
+
+/* Each byte of data is acknowledged by pulling the data line
+ * low for one clock pulse.
+ */
+static void sht15_ack(struct sht15_data *data)
+{
+ gpio_direction_output(data->pdata->gpio_data, 0);
+ ndelay(SHT15_TSU);
+ gpio_set_value(data->pdata->gpio_sck, 1);
+ ndelay(SHT15_TSU);
+ gpio_set_value(data->pdata->gpio_sck, 0);
+ ndelay(SHT15_TSU);
+ gpio_set_value(data->pdata->gpio_data, 1);
+
+ gpio_direction_input(data->pdata->gpio_data);
+}
+/**
+ * sht15_end_transmission() - notify device of end of transmission
+ * @data: device state
+ *
+ * This is basically a NAK. (single clock pulse, data high)
+ **/
+static void sht15_end_transmission(struct sht15_data *data)
+{
+ gpio_direction_output(data->pdata->gpio_data, 1);
+ ndelay(SHT15_TSU);
+ gpio_set_value(data->pdata->gpio_sck, 1);
+ ndelay(SHT15_TSCKH);
+ gpio_set_value(data->pdata->gpio_sck, 0);
+ ndelay(SHT15_TSCKL);
+}
+
+static void sht15_bh_read_data(struct work_struct *work_s)
+{
+ int i;
+ uint16_t val = 0;
+ struct sht15_data *data
+ = container_of(work_s, struct sht15_data,
+ read_work);
+ /* Firstly, verify the line is low */
+ if (gpio_get_value(data->pdata->gpio_data)) {
+ /* If not, then start the interrupt again - care
+ here as could have gone low in meantime so verify
+ it hasn't!
+ */
+ atomic_set(&data->interrupt_handled, 0);
+ enable_irq(gpio_to_irq(data->pdata->gpio_data));
+ /* If still not occured or another handler has been scheduled */
+ if (gpio_get_value(data->pdata->gpio_data)
+ || atomic_read(&data->interrupt_handled))
+ return;
+ }
+ /* Read the data back from the device */
+ for (i = 0; i < 16; ++i) {
+ val <<= 1;
+ gpio_set_value(data->pdata->gpio_sck, 1);
+ ndelay(SHT15_TSCKH);
+ val |= !!gpio_get_value(data->pdata->gpio_data);
+ gpio_set_value(data->pdata->gpio_sck, 0);
+ ndelay(SHT15_TSCKL);
+ if (i == 7)
+ sht15_ack(data);
+ }
+ /* Tell the device we are done */
+ sht15_end_transmission(data);
+
+ switch (data->flag) {
+ case SHT15_READING_TEMP:
+ data->val_temp = val;
+ break;
+ case SHT15_READING_HUMID:
+ data->val_humid = val;
+ break;
+ }
+
+ data->flag = SHT15_READING_NOTHING;
+ wake_up(&data->wait_queue);
+}
+
+static void sht15_update_voltage(struct work_struct *work_s)
+{
+ struct sht15_data *data
+ = container_of(work_s, struct sht15_data,
+ update_supply_work);
+ data->supply_uV = regulator_get_voltage(data->reg);
+}
+
+/**
+ * sht15_invalidate_voltage() - mark supply voltage invalid when notified by reg
+ * @nb: associated notification structure
+ * @event: voltage regulator state change event code
+ * @ignored: function parameter - ignored here
+ *
+ * Note that as the notification code holds the regulator lock, we have
+ * to schedule an update of the supply voltage rather than getting it directly.
+ **/
+static int sht15_invalidate_voltage(struct notifier_block *nb,
+ unsigned long event,
+ void *ignored)
+{
+ struct sht15_data *data = container_of(nb, struct sht15_data, nb);
+
+ if (event == REGULATOR_EVENT_VOLTAGE_CHANGE)
+ data->supply_uV_valid = false;
+ schedule_work(&data->update_supply_work);
+
+ return NOTIFY_OK;
+}
+
+static int __devinit sht15_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
+
+ if (!data) {
+ ret = -ENOMEM;
+ dev_err(&pdev->dev, "kzalloc failed");
+ goto error_ret;
+ }
+
+ INIT_WORK(&data->read_work, sht15_bh_read_data);
+ INIT_WORK(&data->update_supply_work, sht15_update_voltage);
+ platform_set_drvdata(pdev, data);
+ mutex_init(&data->read_lock);
+ data->dev = &pdev->dev;
+ init_waitqueue_head(&data->wait_queue);
+
+ if (pdev->dev.platform_data == NULL) {
+ dev_err(&pdev->dev, "no platform data supplied");
+ goto err_free_data;
+ }
+ data->pdata = pdev->dev.platform_data;
+ data->supply_uV = data->pdata->supply_mv*1000;
+
+/* If a regulator is available, query what the supply voltage actually is!*/
+ data->reg = regulator_get(data->dev, "vcc");
+ if (!IS_ERR(data->reg)) {
+ data->supply_uV = regulator_get_voltage(data->reg);
+ regulator_enable(data->reg);
+ /* setup a notifier block to update this if another device
+ * causes the voltage to change */
+ data->nb.notifier_call = &sht15_invalidate_voltage;
+ ret = regulator_register_notifier(data->reg, &data->nb);
+ }
+/* Try requesting the GPIOs */
+ ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck");
+ if (ret) {
+ dev_err(&pdev->dev, "gpio request failed");
+ goto err_free_data;
+ }
+ gpio_direction_output(data->pdata->gpio_sck, 0);
+ ret = gpio_request(data->pdata->gpio_data, "SHT15 data");
+ if (ret) {
+ dev_err(&pdev->dev, "gpio request failed");
+ goto err_release_gpio_sck;
+ }
+ ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group);
+ if (ret) {
+ dev_err(&pdev->dev, "sysfs create failed");
+ goto err_free_data;
+ }
+
+ ret = request_irq(gpio_to_irq(data->pdata->gpio_data),
+ sht15_interrupt_fired,
+ IRQF_TRIGGER_FALLING,
+ "sht15 data",
+ data);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get irq for data line");
+ goto err_release_gpio_data;
+ }
+ disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
+ sht15_connection_reset(data);
+ sht15_send_cmd(data, 0x1E);
+
+ data->hwmon_dev = hwmon_device_register(data->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ ret = PTR_ERR(data->hwmon_dev);
+ goto err_release_gpio_data;
+ }
+ return 0;
+
+err_release_gpio_data:
+ gpio_free(data->pdata->gpio_data);
+err_release_gpio_sck:
+ gpio_free(data->pdata->gpio_sck);
+err_free_data:
+ kfree(data);
+error_ret:
+
+ return ret;
+}
+
+static int __devexit sht15_remove(struct platform_device *pdev)
+{
+ struct sht15_data *data = platform_get_drvdata(pdev);
+
+ /* Make sure any reads from the device are done and
+ * prevent new ones beginnning */
+ mutex_lock(&data->read_lock);
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
+ if (!IS_ERR(data->reg)) {
+ regulator_unregister_notifier(data->reg, &data->nb);
+ regulator_disable(data->reg);
+ regulator_put(data->reg);
+ }
+
+ free_irq(gpio_to_irq(data->pdata->gpio_data), data);
+ gpio_free(data->pdata->gpio_data);
+ gpio_free(data->pdata->gpio_sck);
+ mutex_unlock(&data->read_lock);
+ kfree(data);
+ return 0;
+}
+
+
+static struct platform_driver sht_drivers[] = {
+ {
+ .driver = {
+ .name = "sht10",
+ .owner = THIS_MODULE,
+ },
+ .probe = sht15_probe,
+ .remove = sht15_remove,
+ }, {
+ .driver = {
+ .name = "sht11",
+ .owner = THIS_MODULE,
+ },
+ .probe = sht15_probe,
+ .remove = sht15_remove,
+ }, {
+ .driver = {
+ .name = "sht15",
+ .owner = THIS_MODULE,
+ },
+ .probe = sht15_probe,
+ .remove = sht15_remove,
+ }, {
+ .driver = {
+ .name = "sht71",
+ .owner = THIS_MODULE,
+ },
+ .probe = sht15_probe,
+ .remove = sht15_remove,
+ }, {
+ .driver = {
+ .name = "sht75",
+ .owner = THIS_MODULE,
+ },
+ .probe = sht15_probe,
+ .remove = sht15_remove,
+ },
+};
+
+
+static int __init sht15_init(void)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sht_drivers); i++) {
+ ret = platform_driver_register(&sht_drivers[i]);
+ if (ret)
+ goto error_unreg;
+ }
+
+ return 0;
+
+error_unreg:
+ while (--i >= 0)
+ platform_driver_unregister(&sht_drivers[i]);
+
+ return ret;
+}
+module_init(sht15_init);
+
+static void __exit sht15_exit(void)
+{
+ int i;
+ for (i = ARRAY_SIZE(sht_drivers) - 1; i >= 0; i--)
+ platform_driver_unregister(&sht_drivers[i]);
+}
+module_exit(sht15_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig
index b788579b822..7b2ce4a0852 100644
--- a/drivers/i2c/algos/Kconfig
+++ b/drivers/i2c/algos/Kconfig
@@ -14,8 +14,4 @@ config I2C_ALGOPCF
config I2C_ALGOPCA
tristate "I2C PCA 9564 interfaces"
-config I2C_ALGO_SGI
- tristate
- depends on SGI_IP22 || SGI_IP32 || X86_VISWS
-
endmenu
diff --git a/drivers/i2c/algos/Makefile b/drivers/i2c/algos/Makefile
index cac1051bd4f..18b3e962ec0 100644
--- a/drivers/i2c/algos/Makefile
+++ b/drivers/i2c/algos/Makefile
@@ -5,7 +5,6 @@
obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o
obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o
obj-$(CONFIG_I2C_ALGOPCA) += i2c-algo-pca.o
-obj-$(CONFIG_I2C_ALGO_SGI) += i2c-algo-sgi.o
ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
index f68e5f8e23e..6318f7ddc1d 100644
--- a/drivers/i2c/algos/i2c-algo-pca.c
+++ b/drivers/i2c/algos/i2c-algo-pca.c
@@ -190,7 +190,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
int completed = 1;
unsigned long timeout = jiffies + i2c_adap->timeout;
- while (pca_status(adap) != 0xf8) {
+ while ((state = pca_status(adap)) != 0xf8) {
if (time_before(jiffies, timeout)) {
msleep(10);
} else {
diff --git a/drivers/i2c/algos/i2c-algo-sgi.c b/drivers/i2c/algos/i2c-algo-sgi.c
deleted file mode 100644
index 6eaf145e1ad..00000000000
--- a/drivers/i2c/algos/i2c-algo-sgi.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * i2c-algo-sgi.c: i2c driver algorithm used by the VINO (SGI Indy) and
- * MACE (SGI O2) chips.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-sgi.h>
-
-
-#define SGI_I2C_FORCE_IDLE (0 << 0)
-#define SGI_I2C_NOT_IDLE (1 << 0)
-#define SGI_I2C_WRITE (0 << 1)
-#define SGI_I2C_READ (1 << 1)
-#define SGI_I2C_RELEASE_BUS (0 << 2)
-#define SGI_I2C_HOLD_BUS (1 << 2)
-#define SGI_I2C_XFER_DONE (0 << 4)
-#define SGI_I2C_XFER_BUSY (1 << 4)
-#define SGI_I2C_ACK (0 << 5)
-#define SGI_I2C_NACK (1 << 5)
-#define SGI_I2C_BUS_OK (0 << 7)
-#define SGI_I2C_BUS_ERR (1 << 7)
-
-#define get_control() adap->getctrl(adap->data)
-#define set_control(val) adap->setctrl(adap->data, val)
-#define read_data() adap->rdata(adap->data)
-#define write_data(val) adap->wdata(adap->data, val)
-
-
-static int wait_xfer_done(struct i2c_algo_sgi_data *adap)
-{
- int i;
-
- for (i = 0; i < adap->xfer_timeout; i++) {
- if ((get_control() & SGI_I2C_XFER_BUSY) == 0)
- return 0;
- udelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-static int wait_ack(struct i2c_algo_sgi_data *adap)
-{
- int i;
-
- if (wait_xfer_done(adap))
- return -ETIMEDOUT;
- for (i = 0; i < adap->ack_timeout; i++) {
- if ((get_control() & SGI_I2C_NACK) == 0)
- return 0;
- udelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-static int force_idle(struct i2c_algo_sgi_data *adap)
-{
- int i;
-
- set_control(SGI_I2C_FORCE_IDLE);
- for (i = 0; i < adap->xfer_timeout; i++) {
- if ((get_control() & SGI_I2C_NOT_IDLE) == 0)
- goto out;
- udelay(1);
- }
- return -ETIMEDOUT;
-out:
- if (get_control() & SGI_I2C_BUS_ERR)
- return -EIO;
- return 0;
-}
-
-static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr,
- int rd)
-{
- if (rd)
- set_control(SGI_I2C_NOT_IDLE);
- /* Check if bus is idle, eventually force it to do so */
- if (get_control() & SGI_I2C_NOT_IDLE)
- if (force_idle(adap))
- return -EIO;
- /* Write out the i2c chip address and specify operation */
- set_control(SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE);
- if (rd)
- addr |= 1;
- write_data(addr);
- if (wait_ack(adap))
- return -EIO;
- return 0;
-}
-
-static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf,
- unsigned int len)
-{
- int i;
-
- set_control(SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE);
- for (i = 0; i < len; i++) {
- if (wait_xfer_done(adap))
- return -EIO;
- buf[i] = read_data();
- }
- set_control(SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE);
-
- return 0;
-
-}
-
-static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf,
- unsigned int len)
-{
- int i;
-
- /* We are already in write state */
- for (i = 0; i < len; i++) {
- write_data(buf[i]);
- if (wait_ack(adap))
- return -EIO;
- }
- return 0;
-}
-
-static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
- int num)
-{
- struct i2c_algo_sgi_data *adap = i2c_adap->algo_data;
- struct i2c_msg *p;
- int i, err = 0;
-
- for (i = 0; !err && i < num; i++) {
- p = &msgs[i];
- err = do_address(adap, p->addr, p->flags & I2C_M_RD);
- if (err || !p->len)
- continue;
- if (p->flags & I2C_M_RD)
- err = i2c_read(adap, p->buf, p->len);
- else
- err = i2c_write(adap, p->buf, p->len);
- }
-
- return (err < 0) ? err : i;
-}
-
-static u32 sgi_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm sgi_algo = {
- .master_xfer = sgi_xfer,
- .functionality = sgi_func,
-};
-
-/*
- * registering functions to load algorithms at runtime
- */
-int i2c_sgi_add_bus(struct i2c_adapter *adap)
-{
- adap->algo = &sgi_algo;
-
- return i2c_add_adapter(adap);
-}
-EXPORT_SYMBOL(i2c_sgi_add_bus);
-
-MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
-MODULE_DESCRIPTION("I2C-Bus SGI algorithm");
-MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index da809ad0996..a48c8aee021 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -356,6 +356,16 @@ config I2C_IBM_IIC
This driver can also be built as a module. If so, the module
will be called i2c-ibm_iic.
+config I2C_IMX
+ tristate "IMX I2C interface"
+ depends on ARCH_MXC
+ help
+ Say Y here if you want to use the IIC bus controller on
+ the Freescale i.MX/MXC processors.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-imx.
+
config I2C_IOP3XX
tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX
@@ -462,6 +472,16 @@ config I2C_S3C2410
Say Y here to include support for I2C controller in the
Samsung S3C2410 based System-on-Chip devices.
+config I2C_S6000
+ tristate "S6000 I2C support"
+ depends on XTENSA_VARIANT_S6000
+ help
+ This driver supports the on chip I2C device on the
+ S6000 xtensa processor family.
+
+ To compile this driver as a module, choose M here. The module
+ will be called i2c-s6000.
+
config I2C_SH7760
tristate "Renesas SH7760 I2C Controller"
depends on CPU_SUBTYPE_SH7760
@@ -584,12 +604,14 @@ comment "Graphics adapter I2C/DDC channel drivers"
depends on PCI
config I2C_VOODOO3
- tristate "Voodoo 3"
+ tristate "Voodoo 3 (DEPRECATED)"
depends on PCI
select I2C_ALGOBIT
help
If you say yes to this option, support will be included for the
- Voodoo 3 I2C interface.
+ Voodoo 3 I2C interface. This driver is deprecated and you should
+ use the tdfxfb driver instead, which additionally provides
+ framebuffer support.
This driver can also be built as a module. If so, the module
will be called i2c-voodoo3.
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 0c2c4b26cdf..776acb6403a 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o
obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
+obj-$(CONFIG_I2C_IMX) += i2c-imx.o
obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
@@ -43,6 +44,7 @@ obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o
obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
+obj-$(CONFIG_I2C_S6000) += i2c-s6000.o
obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o
obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
new file mode 100644
index 00000000000..0b486a63460
--- /dev/null
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -0,0 +1,624 @@
+/*
+ * Copyright (C) 2002 Motorola GSG-China
+ *
+ * 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.
+ *
+ * Author:
+ * Darius Augulis, Teltonika Inc.
+ *
+ * Desc.:
+ * Implementation of I2C Adapter/Algorithm Driver
+ * for I2C Bus integrated in Freescale i.MX/MXC processors
+ *
+ * Derived from Motorola GSG China I2C example driver
+ *
+ * Copyright (C) 2005 Torsten Koschorrek <koschorrek at synertronixx.de
+ * Copyright (C) 2005 Matthias Blaschke <blaschke at synertronixx.de
+ * Copyright (C) 2007 RightHand Technologies, Inc.
+ * Copyright (C) 2008 Darius Augulis <darius.augulis at teltonika.lt>
+ *
+ */
+
+/** Includes *******************************************************************
+*******************************************************************************/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/sched.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/i2c.h>
+
+/** Defines ********************************************************************
+*******************************************************************************/
+
+/* This will be the driver name the kernel reports */
+#define DRIVER_NAME "imx-i2c"
+
+/* Default value */
+#define IMX_I2C_BIT_RATE 100000 /* 100kHz */
+
+/* IMX I2C registers */
+#define IMX_I2C_IADR 0x00 /* i2c slave address */
+#define IMX_I2C_IFDR 0x04 /* i2c frequency divider */
+#define IMX_I2C_I2CR 0x08 /* i2c control */
+#define IMX_I2C_I2SR 0x0C /* i2c status */
+#define IMX_I2C_I2DR 0x10 /* i2c transfer data */
+
+/* Bits of IMX I2C registers */
+#define I2SR_RXAK 0x01
+#define I2SR_IIF 0x02
+#define I2SR_SRW 0x04
+#define I2SR_IAL 0x10
+#define I2SR_IBB 0x20
+#define I2SR_IAAS 0x40
+#define I2SR_ICF 0x80
+#define I2CR_RSTA 0x04
+#define I2CR_TXAK 0x08
+#define I2CR_MTX 0x10
+#define I2CR_MSTA 0x20
+#define I2CR_IIEN 0x40
+#define I2CR_IEN 0x80
+
+/** Variables ******************************************************************
+*******************************************************************************/
+
+/*
+ * sorted list of clock divider, register value pairs
+ * taken from table 26-5, p.26-9, Freescale i.MX
+ * Integrated Portable System Processor Reference Manual
+ * Document Number: MC9328MXLRM, Rev. 5.1, 06/2007
+ *
+ * Duplicated divider values removed from list
+ */
+
+static u16 __initdata i2c_clk_div[50][2] = {
+ { 22, 0x20 }, { 24, 0x21 }, { 26, 0x22 }, { 28, 0x23 },
+ { 30, 0x00 }, { 32, 0x24 }, { 36, 0x25 }, { 40, 0x26 },
+ { 42, 0x03 }, { 44, 0x27 }, { 48, 0x28 }, { 52, 0x05 },
+ { 56, 0x29 }, { 60, 0x06 }, { 64, 0x2A }, { 72, 0x2B },
+ { 80, 0x2C }, { 88, 0x09 }, { 96, 0x2D }, { 104, 0x0A },
+ { 112, 0x2E }, { 128, 0x2F }, { 144, 0x0C }, { 160, 0x30 },
+ { 192, 0x31 }, { 224, 0x32 }, { 240, 0x0F }, { 256, 0x33 },
+ { 288, 0x10 }, { 320, 0x34 }, { 384, 0x35 }, { 448, 0x36 },
+ { 480, 0x13 }, { 512, 0x37 }, { 576, 0x14 }, { 640, 0x38 },
+ { 768, 0x39 }, { 896, 0x3A }, { 960, 0x17 }, { 1024, 0x3B },
+ { 1152, 0x18 }, { 1280, 0x3C }, { 1536, 0x3D }, { 1792, 0x3E },
+ { 1920, 0x1B }, { 2048, 0x3F }, { 2304, 0x1C }, { 2560, 0x1D },
+ { 3072, 0x1E }, { 3840, 0x1F }
+};
+
+struct imx_i2c_struct {
+ struct i2c_adapter adapter;
+ struct resource *res;
+ struct clk *clk;
+ void __iomem *base;
+ int irq;
+ wait_queue_head_t queue;
+ unsigned long i2csr;
+ unsigned int disable_delay;
+};
+
+/** Functions for IMX I2C adapter driver ***************************************
+*******************************************************************************/
+
+static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx)
+{
+ unsigned long orig_jiffies = jiffies;
+
+ dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
+
+ /* wait for bus not busy */
+ while (readb(i2c_imx->base + IMX_I2C_I2SR) & I2SR_IBB) {
+ if (signal_pending(current)) {
+ dev_dbg(&i2c_imx->adapter.dev,
+ "<%s> I2C Interrupted\n", __func__);
+ return -EINTR;
+ }
+ if (time_after(jiffies, orig_jiffies + HZ / 1000)) {
+ dev_dbg(&i2c_imx->adapter.dev,
+ "<%s> I2C bus is busy\n", __func__);
+ return -EIO;
+ }
+ schedule();
+ }
+
+ return 0;
+}
+
+static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx)
+{
+ int result;
+
+ result = wait_event_interruptible_timeout(i2c_imx->queue,
+ i2c_imx->i2csr & I2SR_IIF, HZ / 10);
+
+ if (unlikely(result < 0)) {
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> result < 0\n", __func__);
+ return result;
+ } else if (unlikely(!(i2c_imx->i2csr & I2SR_IIF))) {
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> TRX complete\n", __func__);
+ i2c_imx->i2csr = 0;
+ return 0;
+}
+
+static int i2c_imx_acked(struct imx_i2c_struct *i2c_imx)
+{
+ if (readb(i2c_imx->base + IMX_I2C_I2SR) & I2SR_RXAK) {
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> No ACK\n", __func__);
+ return -EIO; /* No ACK */
+ }
+
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> ACK received\n", __func__);
+ return 0;
+}
+
+static void i2c_imx_start(struct imx_i2c_struct *i2c_imx)
+{
+ unsigned int temp = 0;
+
+ dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
+
+ /* Enable I2C controller */
+ writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR);
+ /* Start I2C transaction */
+ temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+ temp |= I2CR_MSTA;
+ writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+ temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
+ writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+}
+
+static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
+{
+ unsigned int temp = 0;
+
+ /* Stop I2C transaction */
+ dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
+ temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+ temp &= ~I2CR_MSTA;
+ writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+ /* setup chip registers to defaults */
+ writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR);
+ writeb(0, i2c_imx->base + IMX_I2C_I2SR);
+ /*
+ * This delay caused by an i.MXL hardware bug.
+ * If no (or too short) delay, no "STOP" bit will be generated.
+ */
+ udelay(i2c_imx->disable_delay);
+ /* Disable I2C controller */
+ writeb(0, i2c_imx->base + IMX_I2C_I2CR);
+}
+
+static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
+ unsigned int rate)
+{
+ unsigned int i2c_clk_rate;
+ unsigned int div;
+ int i;
+
+ /* Divider value calculation */
+ i2c_clk_rate = clk_get_rate(i2c_imx->clk);
+ div = (i2c_clk_rate + rate - 1) / rate;
+ if (div < i2c_clk_div[0][0])
+ i = 0;
+ else if (div > i2c_clk_div[ARRAY_SIZE(i2c_clk_div) - 1][0])
+ i = ARRAY_SIZE(i2c_clk_div) - 1;
+ else
+ for (i = 0; i2c_clk_div[i][0] < div; i++);
+
+ /* Write divider value to register */
+ writeb(i2c_clk_div[i][1], i2c_imx->base + IMX_I2C_IFDR);
+
+ /*
+ * There dummy delay is calculated.
+ * It should be about one I2C clock period long.
+ * This delay is used in I2C bus disable function
+ * to fix chip hardware bug.
+ */
+ i2c_imx->disable_delay = (500000U * i2c_clk_div[i][0]
+ + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
+
+ /* dev_dbg() can't be used, because adapter is not yet registered */
+#ifdef CONFIG_I2C_DEBUG_BUS
+ printk(KERN_DEBUG "I2C: <%s> I2C_CLK=%d, REQ DIV=%d\n",
+ __func__, i2c_clk_rate, div);
+ printk(KERN_DEBUG "I2C: <%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
+ __func__, i2c_clk_div[i][1], i2c_clk_div[i][0]);
+#endif
+}
+
+static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
+{
+ struct imx_i2c_struct *i2c_imx = dev_id;
+ unsigned int temp;
+
+ temp = readb(i2c_imx->base + IMX_I2C_I2SR);
+ if (temp & I2SR_IIF) {
+ /* save status register */
+ i2c_imx->i2csr = temp;
+ temp &= ~I2SR_IIF;
+ writeb(temp, i2c_imx->base + IMX_I2C_I2SR);
+ wake_up_interruptible(&i2c_imx->queue);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
+{
+ int i, result;
+
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> write slave address: addr=0x%x\n",
+ __func__, msgs->addr << 1);
+
+ /* write slave address */
+ writeb(msgs->addr << 1, i2c_imx->base + IMX_I2C_I2DR);
+ result = i2c_imx_trx_complete(i2c_imx);
+ if (result)
+ return result;
+ result = i2c_imx_acked(i2c_imx);
+ if (result)
+ return result;
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> write data\n", __func__);
+
+ /* write data */
+ for (i = 0; i < msgs->len; i++) {
+ dev_dbg(&i2c_imx->adapter.dev,
+ "<%s> write byte: B%d=0x%X\n",
+ __func__, i, msgs->buf[i]);
+ writeb(msgs->buf[i], i2c_imx->base + IMX_I2C_I2DR);
+ result = i2c_imx_trx_complete(i2c_imx);
+ if (result)
+ return result;
+ result = i2c_imx_acked(i2c_imx);
+ if (result)
+ return result;
+ }
+ return 0;
+}
+
+static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
+{
+ int i, result;
+ unsigned int temp;
+
+ dev_dbg(&i2c_imx->adapter.dev,
+ "<%s> write slave address: addr=0x%x\n",
+ __func__, (msgs->addr << 1) | 0x01);
+
+ /* write slave address */
+ writeb((msgs->addr << 1) | 0x01, i2c_imx->base + IMX_I2C_I2DR);
+ result = i2c_imx_trx_complete(i2c_imx);
+ if (result)
+ return result;
+ result = i2c_imx_acked(i2c_imx);
+ if (result)
+ return result;
+
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> setup bus\n", __func__);
+
+ /* setup bus to read data */
+ temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+ temp &= ~I2CR_MTX;
+ if (msgs->len - 1)
+ temp &= ~I2CR_TXAK;
+ writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+ readb(i2c_imx->base + IMX_I2C_I2DR); /* dummy read */
+
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> read data\n", __func__);
+
+ /* read data */
+ for (i = 0; i < msgs->len; i++) {
+ result = i2c_imx_trx_complete(i2c_imx);
+ if (result)
+ return result;
+ if (i == (msgs->len - 1)) {
+ dev_dbg(&i2c_imx->adapter.dev,
+ "<%s> clear MSTA\n", __func__);
+ temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+ temp &= ~I2CR_MSTA;
+ writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+ } else if (i == (msgs->len - 2)) {
+ dev_dbg(&i2c_imx->adapter.dev,
+ "<%s> set TXAK\n", __func__);
+ temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+ temp |= I2CR_TXAK;
+ writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+ }
+ msgs->buf[i] = readb(i2c_imx->base + IMX_I2C_I2DR);
+ dev_dbg(&i2c_imx->adapter.dev,
+ "<%s> read byte: B%d=0x%X\n",
+ __func__, i, msgs->buf[i]);
+ }
+ return 0;
+}
+
+static int i2c_imx_xfer(struct i2c_adapter *adapter,
+ struct i2c_msg *msgs, int num)
+{
+ unsigned int i, temp;
+ int result;
+ struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);
+
+ dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
+
+ /* Check if i2c bus is not busy */
+ result = i2c_imx_bus_busy(i2c_imx);
+ if (result)
+ goto fail0;
+
+ /* Start I2C transfer */
+ i2c_imx_start(i2c_imx);
+
+ /* read/write data */
+ for (i = 0; i < num; i++) {
+ if (i) {
+ dev_dbg(&i2c_imx->adapter.dev,
+ "<%s> repeated start\n", __func__);
+ temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+ temp |= I2CR_RSTA;
+ writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+ }
+ dev_dbg(&i2c_imx->adapter.dev,
+ "<%s> transfer message: %d\n", __func__, i);
+ /* write/read data */
+#ifdef CONFIG_I2C_DEBUG_BUS
+ temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> CONTROL: IEN=%d, IIEN=%d, "
+ "MSTA=%d, MTX=%d, TXAK=%d, RSTA=%d\n", __func__,
+ (temp & I2CR_IEN ? 1 : 0), (temp & I2CR_IIEN ? 1 : 0),
+ (temp & I2CR_MSTA ? 1 : 0), (temp & I2CR_MTX ? 1 : 0),
+ (temp & I2CR_TXAK ? 1 : 0), (temp & I2CR_RSTA ? 1 : 0));
+ temp = readb(i2c_imx->base + IMX_I2C_I2SR);
+ dev_dbg(&i2c_imx->adapter.dev,
+ "<%s> STATUS: ICF=%d, IAAS=%d, IBB=%d, "
+ "IAL=%d, SRW=%d, IIF=%d, RXAK=%d\n", __func__,
+ (temp & I2SR_ICF ? 1 : 0), (temp & I2SR_IAAS ? 1 : 0),
+ (temp & I2SR_IBB ? 1 : 0), (temp & I2SR_IAL ? 1 : 0),
+ (temp & I2SR_SRW ? 1 : 0), (temp & I2SR_IIF ? 1 : 0),
+ (temp & I2SR_RXAK ? 1 : 0));
+#endif
+ if (msgs[i].flags & I2C_M_RD)
+ result = i2c_imx_read(i2c_imx, &msgs[i]);
+ else
+ result = i2c_imx_write(i2c_imx, &msgs[i]);
+ }
+
+fail0:
+ /* Stop I2C transfer */
+ i2c_imx_stop(i2c_imx);
+
+ dev_dbg(&i2c_imx->adapter.dev, "<%s> exit with: %s: %d\n", __func__,
+ (result < 0) ? "error" : "success msg",
+ (result < 0) ? result : num);
+ return (result < 0) ? result : num;
+}
+
+static u32 i2c_imx_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm i2c_imx_algo = {
+ .master_xfer = i2c_imx_xfer,
+ .functionality = i2c_imx_func,
+};
+
+static int __init i2c_imx_probe(struct platform_device *pdev)
+{
+ struct imx_i2c_struct *i2c_imx;
+ struct resource *res;
+ struct imxi2c_platform_data *pdata;
+ void __iomem *base;
+ resource_size_t res_size;
+ int irq;
+ int ret;
+
+ dev_dbg(&pdev->dev, "<%s>\n", __func__);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "can't get device resources\n");
+ return -ENOENT;
+ }
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "can't get irq number\n");
+ return -ENOENT;
+ }
+
+ pdata = pdev->dev.platform_data;
+
+ if (pdata && pdata->init) {
+ ret = pdata->init(&pdev->dev);
+ if (ret)
+ return ret;
+ }
+
+ res_size = resource_size(res);
+ base = ioremap(res->start, res_size);
+ if (!base) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -EIO;
+ goto fail0;
+ }
+
+ i2c_imx = kzalloc(sizeof(struct imx_i2c_struct), GFP_KERNEL);
+ if (!i2c_imx) {
+ dev_err(&pdev->dev, "can't allocate interface\n");
+ ret = -ENOMEM;
+ goto fail1;
+ }
+
+ if (!request_mem_region(res->start, res_size, DRIVER_NAME)) {
+ ret = -EBUSY;
+ goto fail2;
+ }
+
+ /* Setup i2c_imx driver structure */
+ strcpy(i2c_imx->adapter.name, pdev->name);
+ i2c_imx->adapter.owner = THIS_MODULE;
+ i2c_imx->adapter.algo = &i2c_imx_algo;
+ i2c_imx->adapter.dev.parent = &pdev->dev;
+ i2c_imx->adapter.nr = pdev->id;
+ i2c_imx->irq = irq;
+ i2c_imx->base = base;
+ i2c_imx->res = res;
+
+ /* Get I2C clock */
+ i2c_imx->clk = clk_get(&pdev->dev, "i2c_clk");
+ if (IS_ERR(i2c_imx->clk)) {
+ ret = PTR_ERR(i2c_imx->clk);
+ dev_err(&pdev->dev, "can't get I2C clock\n");
+ goto fail3;
+ }
+ clk_enable(i2c_imx->clk);
+
+ /* Request IRQ */
+ ret = request_irq(i2c_imx->irq, i2c_imx_isr, 0, pdev->name, i2c_imx);
+ if (ret) {
+ dev_err(&pdev->dev, "can't claim irq %d\n", i2c_imx->irq);
+ goto fail4;
+ }
+
+ /* Init queue */
+ init_waitqueue_head(&i2c_imx->queue);
+
+ /* Set up adapter data */
+ i2c_set_adapdata(&i2c_imx->adapter, i2c_imx);
+
+ /* Set up clock divider */
+ if (pdata && pdata->bitrate)
+ i2c_imx_set_clk(i2c_imx, pdata->bitrate);
+ else
+ i2c_imx_set_clk(i2c_imx, IMX_I2C_BIT_RATE);
+
+ /* Set up chip registers to defaults */
+ writeb(0, i2c_imx->base + IMX_I2C_I2CR);
+ writeb(0, i2c_imx->base + IMX_I2C_I2SR);
+
+ /* Add I2C adapter */
+ ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "registration failed\n");
+ goto fail5;
+ }
+
+ /* Set up platform driver data */
+ platform_set_drvdata(pdev, i2c_imx);
+
+ dev_dbg(&i2c_imx->adapter.dev, "claimed irq %d\n", i2c_imx->irq);
+ dev_dbg(&i2c_imx->adapter.dev, "device resources from 0x%x to 0x%x\n",
+ i2c_imx->res->start, i2c_imx->res->end);
+ dev_dbg(&i2c_imx->adapter.dev, "allocated %d bytes at 0x%x \n",
+ res_size, i2c_imx->res->start);
+ dev_dbg(&i2c_imx->adapter.dev, "adapter name: \"%s\"\n",
+ i2c_imx->adapter.name);
+ dev_dbg(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
+
+ return 0; /* Return OK */
+
+fail5:
+ free_irq(i2c_imx->irq, i2c_imx);
+fail4:
+ clk_disable(i2c_imx->clk);
+ clk_put(i2c_imx->clk);
+fail3:
+ release_mem_region(i2c_imx->res->start, resource_size(res));
+fail2:
+ kfree(i2c_imx);
+fail1:
+ iounmap(base);
+fail0:
+ if (pdata && pdata->exit)
+ pdata->exit(&pdev->dev);
+ return ret; /* Return error number */
+}
+
+static int __exit i2c_imx_remove(struct platform_device *pdev)
+{
+ struct imx_i2c_struct *i2c_imx = platform_get_drvdata(pdev);
+ struct imxi2c_platform_data *pdata = pdev->dev.platform_data;
+
+ /* remove adapter */
+ dev_dbg(&i2c_imx->adapter.dev, "adapter removed\n");
+ i2c_del_adapter(&i2c_imx->adapter);
+ platform_set_drvdata(pdev, NULL);
+
+ /* free interrupt */
+ free_irq(i2c_imx->irq, i2c_imx);
+
+ /* setup chip registers to defaults */
+ writeb(0, i2c_imx->base + IMX_I2C_IADR);
+ writeb(0, i2c_imx->base + IMX_I2C_IFDR);
+ writeb(0, i2c_imx->base + IMX_I2C_I2CR);
+ writeb(0, i2c_imx->base + IMX_I2C_I2SR);
+
+ /* Shut down hardware */
+ if (pdata && pdata->exit)
+ pdata->exit(&pdev->dev);
+
+ /* Disable I2C clock */
+ clk_disable(i2c_imx->clk);
+ clk_put(i2c_imx->clk);
+
+ release_mem_region(i2c_imx->res->start, resource_size(i2c_imx->res));
+ iounmap(i2c_imx->base);
+ kfree(i2c_imx);
+ return 0;
+}
+
+static struct platform_driver i2c_imx_driver = {
+ .probe = i2c_imx_probe,
+ .remove = __exit_p(i2c_imx_remove),
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ }
+};
+
+static int __init i2c_adap_imx_init(void)
+{
+ return platform_driver_probe(&i2c_imx_driver, i2c_imx_probe);
+}
+
+static void __exit i2c_adap_imx_exit(void)
+{
+ platform_driver_unregister(&i2c_imx_driver);
+}
+
+module_init(i2c_adap_imx_init);
+module_exit(i2c_adap_imx_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Darius Augulis");
+MODULE_DESCRIPTION("I2C adapter driver for IMX I2C bus");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 26bf3701058..4af5c09f0e8 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -20,18 +20,21 @@
#include <linux/of_platform.h>
#include <linux/of_i2c.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/fsl_devices.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <asm/mpc52xx.h>
+#include <sysdev/fsl_soc.h>
+
#define DRV_NAME "mpc-i2c"
-#define MPC_I2C_FDR 0x04
-#define MPC_I2C_CR 0x08
-#define MPC_I2C_SR 0x0c
-#define MPC_I2C_DR 0x10
+#define MPC_I2C_FDR 0x04
+#define MPC_I2C_CR 0x08
+#define MPC_I2C_SR 0x0c
+#define MPC_I2C_DR 0x10
#define MPC_I2C_DFSRR 0x14
#define CCR_MEN 0x80
@@ -50,15 +53,27 @@
#define CSR_RXAK 0x01
struct mpc_i2c {
+ struct device *dev;
void __iomem *base;
u32 interrupt;
wait_queue_head_t queue;
struct i2c_adapter adap;
int irq;
- u32 flags;
};
-static __inline__ void writeccr(struct mpc_i2c *i2c, u32 x)
+struct mpc_i2c_divider {
+ u16 divider;
+ u16 fdr; /* including dfsrr */
+};
+
+struct mpc_i2c_match_data {
+ void (*setclock)(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler);
+ u32 prescaler;
+};
+
+static inline void writeccr(struct mpc_i2c *i2c, u32 x)
{
writeb(x, i2c->base + MPC_I2C_CR);
}
@@ -100,12 +115,11 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
u32 x;
int result = 0;
- if (i2c->irq == NO_IRQ)
- {
+ if (i2c->irq == NO_IRQ) {
while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
schedule();
if (time_after(jiffies, orig_jiffies + timeout)) {
- pr_debug("I2C: timeout\n");
+ dev_dbg(i2c->dev, "timeout\n");
writeccr(i2c, 0);
result = -EIO;
break;
@@ -119,7 +133,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
(i2c->interrupt & CSR_MIF), timeout);
if (unlikely(!(i2c->interrupt & CSR_MIF))) {
- pr_debug("I2C: wait timeout\n");
+ dev_dbg(i2c->dev, "wait timeout\n");
writeccr(i2c, 0);
result = -ETIMEDOUT;
}
@@ -132,17 +146,17 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
return result;
if (!(x & CSR_MCF)) {
- pr_debug("I2C: unfinished\n");
+ dev_dbg(i2c->dev, "unfinished\n");
return -EIO;
}
if (x & CSR_MAL) {
- pr_debug("I2C: MAL\n");
+ dev_dbg(i2c->dev, "MAL\n");
return -EIO;
}
if (writing && (x & CSR_RXAK)) {
- pr_debug("I2C: No RXAK\n");
+ dev_dbg(i2c->dev, "No RXAK\n");
/* generate stop */
writeccr(i2c, CCR_MEN);
return -EIO;
@@ -150,18 +164,181 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
return 0;
}
-static void mpc_i2c_setclock(struct mpc_i2c *i2c)
+#ifdef CONFIG_PPC_52xx
+static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
+ {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
+ {28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02},
+ {36, 0x26}, {40, 0x27}, {44, 0x04}, {48, 0x28},
+ {52, 0x63}, {56, 0x29}, {60, 0x41}, {64, 0x2a},
+ {68, 0x07}, {72, 0x2b}, {80, 0x2c}, {88, 0x09},
+ {96, 0x2d}, {104, 0x0a}, {112, 0x2e}, {120, 0x81},
+ {128, 0x2f}, {136, 0x47}, {144, 0x0c}, {160, 0x30},
+ {176, 0x49}, {192, 0x31}, {208, 0x4a}, {224, 0x32},
+ {240, 0x0f}, {256, 0x33}, {272, 0x87}, {288, 0x10},
+ {320, 0x34}, {352, 0x89}, {384, 0x35}, {416, 0x8a},
+ {448, 0x36}, {480, 0x13}, {512, 0x37}, {576, 0x14},
+ {640, 0x38}, {768, 0x39}, {896, 0x3a}, {960, 0x17},
+ {1024, 0x3b}, {1152, 0x18}, {1280, 0x3c}, {1536, 0x3d},
+ {1792, 0x3e}, {1920, 0x1b}, {2048, 0x3f}, {2304, 0x1c},
+ {2560, 0x1d}, {3072, 0x1e}, {3584, 0x7e}, {3840, 0x1f},
+ {4096, 0x7f}, {4608, 0x5c}, {5120, 0x5d}, {6144, 0x5e},
+ {7168, 0xbe}, {7680, 0x5f}, {8192, 0xbf}, {9216, 0x9c},
+ {10240, 0x9d}, {12288, 0x9e}, {15360, 0x9f}
+};
+
+int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler)
+{
+ const struct mpc52xx_i2c_divider *div = NULL;
+ unsigned int pvr = mfspr(SPRN_PVR);
+ u32 divider;
+ int i;
+
+ if (!clock)
+ return -EINVAL;
+
+ /* Determine divider value */
+ divider = mpc52xx_find_ipb_freq(node) / clock;
+
+ /*
+ * We want to choose an FDR/DFSR that generates an I2C bus speed that
+ * is equal to or lower than the requested speed.
+ */
+ for (i = 0; i < ARRAY_SIZE(mpc52xx_i2c_dividers); i++) {
+ div = &mpc_i2c_dividers_52xx[i];
+ /* Old MPC5200 rev A CPUs do not support the high bits */
+ if (div->fdr & 0xc0 && pvr == 0x80822011)
+ continue;
+ if (div->divider >= divider)
+ break;
+ }
+
+ return div ? (int)div->fdr : -EINVAL;
+}
+
+static void mpc_i2c_setclock_52xx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
{
- /* Set clock and filters */
- if (i2c->flags & FSL_I2C_DEV_SEPARATE_DFSRR) {
- writeb(0x31, i2c->base + MPC_I2C_FDR);
- writeb(0x10, i2c->base + MPC_I2C_DFSRR);
- } else if (i2c->flags & FSL_I2C_DEV_CLOCK_5200)
- writeb(0x3f, i2c->base + MPC_I2C_FDR);
- else
- writel(0x1031, i2c->base + MPC_I2C_FDR);
+ int fdr = mpc52xx_i2c_get_fdr(node, clock, prescaler);
+
+ if (fdr < 0)
+ fdr = 0x3f; /* backward compatibility */
+ writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
+ dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
+}
+#else /* !CONFIG_PPC_52xx */
+static void mpc_i2c_setclock_52xx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
+{
+}
+#endif /* CONFIG_PPC_52xx*/
+
+#ifdef CONFIG_FSL_SOC
+static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = {
+ {160, 0x0120}, {192, 0x0121}, {224, 0x0122}, {256, 0x0123},
+ {288, 0x0100}, {320, 0x0101}, {352, 0x0601}, {384, 0x0102},
+ {416, 0x0602}, {448, 0x0126}, {480, 0x0103}, {512, 0x0127},
+ {544, 0x0b03}, {576, 0x0104}, {608, 0x1603}, {640, 0x0105},
+ {672, 0x2003}, {704, 0x0b05}, {736, 0x2b03}, {768, 0x0106},
+ {800, 0x3603}, {832, 0x0b06}, {896, 0x012a}, {960, 0x0107},
+ {1024, 0x012b}, {1088, 0x1607}, {1152, 0x0108}, {1216, 0x2b07},
+ {1280, 0x0109}, {1408, 0x1609}, {1536, 0x010a}, {1664, 0x160a},
+ {1792, 0x012e}, {1920, 0x010b}, {2048, 0x012f}, {2176, 0x2b0b},
+ {2304, 0x010c}, {2560, 0x010d}, {2816, 0x2b0d}, {3072, 0x010e},
+ {3328, 0x2b0e}, {3584, 0x0132}, {3840, 0x010f}, {4096, 0x0133},
+ {4608, 0x0110}, {5120, 0x0111}, {6144, 0x0112}, {7168, 0x0136},
+ {7680, 0x0113}, {8192, 0x0137}, {9216, 0x0114}, {10240, 0x0115},
+ {12288, 0x0116}, {14336, 0x013a}, {15360, 0x0117}, {16384, 0x013b},
+ {18432, 0x0118}, {20480, 0x0119}, {24576, 0x011a}, {28672, 0x013e},
+ {30720, 0x011b}, {32768, 0x013f}, {36864, 0x011c}, {40960, 0x011d},
+ {49152, 0x011e}, {61440, 0x011f}
+};
+
+u32 mpc_i2c_get_sec_cfg_8xxx(void)
+{
+ struct device_node *node = NULL;
+ u32 __iomem *reg;
+ u32 val = 0;
+
+ node = of_find_node_by_name(NULL, "global-utilities");
+ if (node) {
+ const u32 *prop = of_get_property(node, "reg", NULL);
+ if (prop) {
+ /*
+ * Map and check POR Device Status Register 2
+ * (PORDEVSR2) at 0xE0014
+ */
+ reg = ioremap(get_immrbase() + *prop + 0x14, 0x4);
+ if (!reg)
+ printk(KERN_ERR
+ "Error: couldn't map PORDEVSR2\n");
+ else
+ val = in_be32(reg) & 0x00000080; /* sec-cfg */
+ iounmap(reg);
+ }
+ }
+ if (node)
+ of_node_put(node);
+
+ return val;
}
+int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler)
+{
+ const struct mpc_i2c_divider *div = NULL;
+ u32 divider;
+ int i;
+
+ if (!clock)
+ return -EINVAL;
+
+ /* Determine proper divider value */
+ if (of_device_is_compatible(node, "fsl,mpc8544-i2c"))
+ prescaler = mpc_i2c_get_sec_cfg_8xxx() ? 3 : 2;
+ if (!prescaler)
+ prescaler = 1;
+
+ divider = fsl_get_sys_freq() / clock / prescaler;
+
+ pr_debug("I2C: src_clock=%d clock=%d divider=%d\n",
+ fsl_get_sys_freq(), clock, divider);
+
+ /*
+ * We want to choose an FDR/DFSR that generates an I2C bus speed that
+ * is equal to or lower than the requested speed.
+ */
+ for (i = 0; i < ARRAY_SIZE(mpc_i2c_dividers_8xxx); i++) {
+ div = &mpc_i2c_dividers_8xxx[i];
+ if (div->divider >= divider)
+ break;
+ }
+
+ return div ? (int)div->fdr : -EINVAL;
+}
+
+static void mpc_i2c_setclock_8xxx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
+{
+ int fdr = mpc_i2c_get_fdr_8xxx(node, clock, prescaler);
+
+ if (fdr < 0)
+ fdr = 0x1031; /* backward compatibility */
+ writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
+ writeb((fdr >> 8) & 0xff, i2c->base + MPC_I2C_DFSRR);
+ dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n",
+ clock, fdr >> 8, fdr & 0xff);
+}
+
+#else /* !CONFIG_FSL_SOC */
+static void mpc_i2c_setclock_8xxx(struct device_node *node,
+ struct mpc_i2c *i2c,
+ u32 clock, u32 prescaler)
+{
+}
+#endif /* CONFIG_FSL_SOC */
+
static void mpc_i2c_start(struct mpc_i2c *i2c)
{
/* Clear arbitration */
@@ -176,7 +353,7 @@ static void mpc_i2c_stop(struct mpc_i2c *i2c)
}
static int mpc_write(struct mpc_i2c *i2c, int target,
- const u8 * data, int length, int restart)
+ const u8 *data, int length, int restart)
{
int i, result;
unsigned timeout = i2c->adap.timeout;
@@ -207,7 +384,7 @@ static int mpc_write(struct mpc_i2c *i2c, int target,
}
static int mpc_read(struct mpc_i2c *i2c, int target,
- u8 * data, int length, int restart)
+ u8 *data, int length, int restart)
{
unsigned timeout = i2c->adap.timeout;
int i, result;
@@ -264,12 +441,12 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
/* Allow bus up to 1s to become not busy */
while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) {
if (signal_pending(current)) {
- pr_debug("I2C: Interrupted\n");
+ dev_dbg(i2c->dev, "Interrupted\n");
writeccr(i2c, 0);
return -EINTR;
}
if (time_after(jiffies, orig_jiffies + HZ)) {
- pr_debug("I2C: timeout\n");
+ dev_dbg(i2c->dev, "timeout\n");
if (readb(i2c->base + MPC_I2C_SR) ==
(CSR_MCF | CSR_MBB | CSR_RXAK))
mpc_i2c_fixup(i2c);
@@ -280,9 +457,10 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
for (i = 0; ret >= 0 && i < num; i++) {
pmsg = &msgs[i];
- pr_debug("Doing %s %d bytes to 0x%02x - %d of %d messages\n",
- pmsg->flags & I2C_M_RD ? "read" : "write",
- pmsg->len, pmsg->addr, i + 1, num);
+ dev_dbg(i2c->dev,
+ "Doing %s %d bytes to 0x%02x - %d of %d messages\n",
+ pmsg->flags & I2C_M_RD ? "read" : "write",
+ pmsg->len, pmsg->addr, i + 1, num);
if (pmsg->flags & I2C_M_RD)
ret =
mpc_read(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);
@@ -311,27 +489,26 @@ static struct i2c_adapter mpc_ops = {
.timeout = HZ,
};
-static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_id *match)
+static int __devinit fsl_i2c_probe(struct of_device *op,
+ const struct of_device_id *match)
{
- int result = 0;
struct mpc_i2c *i2c;
+ const u32 *prop;
+ u32 clock = 0;
+ int result = 0;
+ int plen;
i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
if (!i2c)
return -ENOMEM;
- if (of_get_property(op->node, "dfsrr", NULL))
- i2c->flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
-
- if (of_device_is_compatible(op->node, "fsl,mpc5200-i2c") ||
- of_device_is_compatible(op->node, "mpc5200-i2c"))
- i2c->flags |= FSL_I2C_DEV_CLOCK_5200;
+ i2c->dev = &op->dev; /* for debug and error output */
init_waitqueue_head(&i2c->queue);
i2c->base = of_iomap(op->node, 0);
if (!i2c->base) {
- printk(KERN_ERR "i2c-mpc - failed to map controller\n");
+ dev_err(i2c->dev, "failed to map controller\n");
result = -ENOMEM;
goto fail_map;
}
@@ -341,12 +518,27 @@ static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_
result = request_irq(i2c->irq, mpc_i2c_isr,
IRQF_SHARED, "i2c-mpc", i2c);
if (result < 0) {
- printk(KERN_ERR "i2c-mpc - failed to attach interrupt\n");
+ dev_err(i2c->dev, "failed to attach interrupt\n");
goto fail_request;
}
}
-
- mpc_i2c_setclock(i2c);
+
+ if (!of_get_property(op->node, "fsl,preserve-clocking", NULL)) {
+ prop = of_get_property(op->node, "clock-frequency", &plen);
+ if (prop && plen == sizeof(u32))
+ clock = *prop;
+
+ if (match->data) {
+ struct mpc_i2c_match_data *data =
+ (struct mpc_i2c_match_data *)match->data;
+ data->setclock(op->node, i2c, clock, data->prescaler);
+ } else {
+ /* Backwards compatibility */
+ if (of_get_property(op->node, "dfsrr", NULL))
+ mpc_i2c_setclock_8xxx(op->node, i2c,
+ clock, 0);
+ }
+ }
dev_set_drvdata(&op->dev, i2c);
@@ -356,7 +548,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_
result = i2c_add_adapter(&i2c->adap);
if (result < 0) {
- printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
+ dev_err(i2c->dev, "failed to add adapter\n");
goto fail_add;
}
of_register_i2c_devices(&i2c->adap, op->node);
@@ -368,7 +560,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_
free_irq(i2c->irq, i2c);
fail_request:
irq_dispose_mapping(i2c->irq);
- iounmap(i2c->base);
+ iounmap(i2c->base);
fail_map:
kfree(i2c);
return result;
@@ -391,9 +583,43 @@ static int __devexit fsl_i2c_remove(struct of_device *op)
};
static const struct of_device_id mpc_i2c_of_match[] = {
- {.compatible = "fsl-i2c",},
+ {.compatible = "mpc5200-i2c",
+ .data = &(struct mpc_i2c_match_data) {
+ .setclock = mpc_i2c_setclock_52xx,
+ },
+ },
+ {.compatible = "fsl,mpc5200b-i2c",
+ .data = &(struct mpc_i2c_match_data) {
+ .setclock = mpc_i2c_setclock_52xx,
+ },
+ },
+ {.compatible = "fsl,mpc5200-i2c",
+ .data = &(struct mpc_i2c_match_data) {
+ .setclock = mpc_i2c_setclock_52xx,
+ },
+ },
+ {.compatible = "fsl,mpc8313-i2c",
+ .data = &(struct mpc_i2c_match_data) {
+ .setclock = mpc_i2c_setclock_8xxx,
+ },
+ },
+ {.compatible = "fsl,mpc8543-i2c",
+ .data = &(struct mpc_i2c_match_data) {
+ .setclock = mpc_i2c_setclock_8xxx,
+ .prescaler = 2,
+ },
+ },
+ {.compatible = "fsl,mpc8544-i2c",
+ .data = &(struct mpc_i2c_match_data) {
+ .setclock = mpc_i2c_setclock_8xxx,
+ .prescaler = 3,
+ },
+ /* Backward compatibility */
+ },
+ {.compatible = "fsl-i2c", },
{},
};
+
MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
@@ -414,7 +640,7 @@ static int __init fsl_i2c_init(void)
rv = of_register_platform_driver(&mpc_i2c_driver);
if (rv)
- printk(KERN_ERR DRV_NAME
+ printk(KERN_ERR DRV_NAME
" of_register_platform_driver failed (%i)\n", rv);
return rv;
}
@@ -428,6 +654,6 @@ module_init(fsl_i2c_init);
module_exit(fsl_i2c_exit);
MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
-MODULE_DESCRIPTION
- ("I2C-Bus adapter for MPC107 bridge and MPC824x/85xx/52xx processors");
+MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and "
+ "MPC824x/85xx/52xx processors");
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 5b7f95641ba..1691ef0f1ee 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -1,6 +1,6 @@
/* linux/drivers/i2c/busses/i2c-s3c2410.c
*
- * Copyright (C) 2004,2005 Simtec Electronics
+ * Copyright (C) 2004,2005,2009 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 I2C Controller
@@ -590,18 +590,6 @@ static int s3c24xx_i2c_calcdivisor(unsigned long clkin, unsigned int wanted,
return clkin / (calc_divs * calc_div1);
}
-/* freq_acceptable
- *
- * test wether a frequency is within the acceptable range of error
-*/
-
-static inline int freq_acceptable(unsigned int freq, unsigned int wanted)
-{
- int diff = freq - wanted;
-
- return diff >= -2 && diff <= 2;
-}
-
/* s3c24xx_i2c_clockrate
*
* work out a divisor for the user requested frequency setting,
@@ -614,44 +602,28 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
struct s3c2410_platform_i2c *pdata = i2c->dev->platform_data;
unsigned long clkin = clk_get_rate(i2c->clk);
unsigned int divs, div1;
+ unsigned long target_frequency;
u32 iiccon;
int freq;
- int start, end;
i2c->clkrate = clkin;
clkin /= 1000; /* clkin now in KHz */
- dev_dbg(i2c->dev, "pdata %p, freq %lu %lu..%lu\n",
- pdata, pdata->bus_freq, pdata->min_freq, pdata->max_freq);
-
- if (pdata->bus_freq != 0) {
- freq = s3c24xx_i2c_calcdivisor(clkin, pdata->bus_freq/1000,
- &div1, &divs);
- if (freq_acceptable(freq, pdata->bus_freq/1000))
- goto found;
- }
-
- /* ok, we may have to search for something suitable... */
+ dev_dbg(i2c->dev, "pdata desired frequency %lu\n", pdata->frequency);
- start = (pdata->max_freq == 0) ? pdata->bus_freq : pdata->max_freq;
- end = pdata->min_freq;
+ target_frequency = pdata->frequency ? pdata->frequency : 100000;
- start /= 1000;
- end /= 1000;
+ target_frequency /= 1000; /* Target frequency now in KHz */
- /* search loop... */
+ freq = s3c24xx_i2c_calcdivisor(clkin, target_frequency, &div1, &divs);
- for (; start > end; start--) {
- freq = s3c24xx_i2c_calcdivisor(clkin, start, &div1, &divs);
- if (freq_acceptable(freq, start))
- goto found;
+ if (freq > target_frequency) {
+ dev_err(i2c->dev,
+ "Unable to achieve desired frequency %luKHz." \
+ " Lowest achievable %dKHz\n", target_frequency, freq);
+ return -EINVAL;
}
- /* cannot find frequency spec */
-
- return -EINVAL;
-
- found:
*got = freq;
iiccon = readl(i2c->regs + S3C2410_IICCON);
@@ -663,6 +635,23 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
writel(iiccon, i2c->regs + S3C2410_IICCON);
+ if (s3c24xx_i2c_is2440(i2c)) {
+ unsigned long sda_delay;
+
+ if (pdata->sda_delay) {
+ sda_delay = (freq / 1000) * pdata->sda_delay;
+ sda_delay /= 1000000;
+ sda_delay = DIV_ROUND_UP(sda_delay, 5);
+ if (sda_delay > 3)
+ sda_delay = 3;
+ sda_delay |= S3C2410_IICLC_FILTER_ON;
+ } else
+ sda_delay = 0;
+
+ dev_dbg(i2c->dev, "IICLC=%08lx\n", sda_delay);
+ writel(sda_delay, i2c->regs + S3C2440_IICLC);
+ }
+
return 0;
}
@@ -769,11 +758,8 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
/* check for s3c2440 i2c controller */
- if (s3c24xx_i2c_is2440(i2c)) {
- dev_dbg(i2c->dev, "S3C2440_IICLC=%08x\n", pdata->sda_delay);
-
- writel(pdata->sda_delay, i2c->regs + S3C2440_IICLC);
- }
+ if (s3c24xx_i2c_is2440(i2c))
+ writel(0x0, i2c->regs + S3C2440_IICLC);
return 0;
}
@@ -1018,14 +1004,13 @@ static int __init i2c_adap_s3c_init(void)
return ret;
}
+subsys_initcall(i2c_adap_s3c_init);
static void __exit i2c_adap_s3c_exit(void)
{
platform_driver_unregister(&s3c2410_i2c_driver);
platform_driver_unregister(&s3c2440_i2c_driver);
}
-
-module_init(i2c_adap_s3c_init);
module_exit(i2c_adap_s3c_exit);
MODULE_DESCRIPTION("S3C24XX I2C Bus driver");
diff --git a/drivers/i2c/busses/i2c-s6000.c b/drivers/i2c/busses/i2c-s6000.c
new file mode 100644
index 00000000000..c91359f4965
--- /dev/null
+++ b/drivers/i2c/busses/i2c-s6000.c
@@ -0,0 +1,407 @@
+/*
+ * drivers/i2c/busses/i2c-s6000.c
+ *
+ * Description: Driver for S6000 Family I2C Interface
+ * Copyright (c) 2008 emlix GmbH
+ * Author: Oskar Schirmer <os@emlix.com>
+ *
+ * Partially based on i2c-bfin-twi.c driver by <sonic.zhang@analog.com>
+ * Copyright (c) 2005-2007 Analog Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c/s6000.h>
+#include <linux/timer.h>
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include "i2c-s6000.h"
+
+#define DRV_NAME "i2c-s6000"
+
+#define POLL_TIMEOUT (2 * HZ)
+
+struct s6i2c_if {
+ u8 __iomem *reg; /* memory mapped registers */
+ int irq;
+ spinlock_t lock;
+ struct i2c_msg *msgs; /* messages currently handled */
+ int msgs_num; /* nb of msgs to do */
+ int msgs_push; /* nb of msgs read/written */
+ int msgs_done; /* nb of msgs finally handled */
+ unsigned push; /* nb of bytes read/written in msg */
+ unsigned done; /* nb of bytes finally handled */
+ int timeout_count; /* timeout retries left */
+ struct timer_list timeout_timer;
+ struct i2c_adapter adap;
+ struct completion complete;
+ struct clk *clk;
+ struct resource *res;
+};
+
+static inline u16 i2c_rd16(struct s6i2c_if *iface, unsigned n)
+{
+ return readw(iface->reg + (n));
+}
+
+static inline void i2c_wr16(struct s6i2c_if *iface, unsigned n, u16 v)
+{
+ writew(v, iface->reg + (n));
+}
+
+static inline u32 i2c_rd32(struct s6i2c_if *iface, unsigned n)
+{
+ return readl(iface->reg + (n));
+}
+
+static inline void i2c_wr32(struct s6i2c_if *iface, unsigned n, u32 v)
+{
+ writel(v, iface->reg + (n));
+}
+
+static struct s6i2c_if s6i2c_if;
+
+static void s6i2c_handle_interrupt(struct s6i2c_if *iface)
+{
+ if (i2c_rd16(iface, S6_I2C_INTRSTAT) & (1 << S6_I2C_INTR_TXABRT)) {
+ i2c_rd16(iface, S6_I2C_CLRTXABRT);
+ i2c_wr16(iface, S6_I2C_INTRMASK, 0);
+ complete(&iface->complete);
+ return;
+ }
+ if (iface->msgs_done >= iface->msgs_num) {
+ dev_err(&iface->adap.dev, "s6i2c: spurious I2C irq: %04x\n",
+ i2c_rd16(iface, S6_I2C_INTRSTAT));
+ i2c_wr16(iface, S6_I2C_INTRMASK, 0);
+ return;
+ }
+ while ((iface->msgs_push < iface->msgs_num)
+ && (i2c_rd16(iface, S6_I2C_STATUS) & (1 << S6_I2C_STATUS_TFNF))) {
+ struct i2c_msg *m = &iface->msgs[iface->msgs_push];
+ if (!(m->flags & I2C_M_RD))
+ i2c_wr16(iface, S6_I2C_DATACMD, m->buf[iface->push]);
+ else
+ i2c_wr16(iface, S6_I2C_DATACMD,
+ 1 << S6_I2C_DATACMD_READ);
+ if (++iface->push >= m->len) {
+ iface->push = 0;
+ iface->msgs_push += 1;
+ }
+ }
+ do {
+ struct i2c_msg *m = &iface->msgs[iface->msgs_done];
+ if (!(m->flags & I2C_M_RD)) {
+ if (iface->msgs_done < iface->msgs_push)
+ iface->msgs_done += 1;
+ else
+ break;
+ } else if (i2c_rd16(iface, S6_I2C_STATUS)
+ & (1 << S6_I2C_STATUS_RFNE)) {
+ m->buf[iface->done] = i2c_rd16(iface, S6_I2C_DATACMD);
+ if (++iface->done >= m->len) {
+ iface->done = 0;
+ iface->msgs_done += 1;
+ }
+ } else{
+ break;
+ }
+ } while (iface->msgs_done < iface->msgs_num);
+ if (iface->msgs_done >= iface->msgs_num) {
+ i2c_wr16(iface, S6_I2C_INTRMASK, 1 << S6_I2C_INTR_TXABRT);
+ complete(&iface->complete);
+ } else if (iface->msgs_push >= iface->msgs_num) {
+ i2c_wr16(iface, S6_I2C_INTRMASK, (1 << S6_I2C_INTR_TXABRT) |
+ (1 << S6_I2C_INTR_RXFULL));
+ } else {
+ i2c_wr16(iface, S6_I2C_INTRMASK, (1 << S6_I2C_INTR_TXABRT) |
+ (1 << S6_I2C_INTR_TXEMPTY) |
+ (1 << S6_I2C_INTR_RXFULL));
+ }
+}
+
+static irqreturn_t s6i2c_interrupt_entry(int irq, void *dev_id)
+{
+ struct s6i2c_if *iface = dev_id;
+ if (!(i2c_rd16(iface, S6_I2C_STATUS) & ((1 << S6_I2C_INTR_RXUNDER)
+ | (1 << S6_I2C_INTR_RXOVER)
+ | (1 << S6_I2C_INTR_RXFULL)
+ | (1 << S6_I2C_INTR_TXOVER)
+ | (1 << S6_I2C_INTR_TXEMPTY)
+ | (1 << S6_I2C_INTR_RDREQ)
+ | (1 << S6_I2C_INTR_TXABRT)
+ | (1 << S6_I2C_INTR_RXDONE)
+ | (1 << S6_I2C_INTR_ACTIVITY)
+ | (1 << S6_I2C_INTR_STOPDET)
+ | (1 << S6_I2C_INTR_STARTDET)
+ | (1 << S6_I2C_INTR_GENCALL))))
+ return IRQ_NONE;
+
+ spin_lock(&iface->lock);
+ del_timer(&iface->timeout_timer);
+ s6i2c_handle_interrupt(iface);
+ spin_unlock(&iface->lock);
+ return IRQ_HANDLED;
+}
+
+static void s6i2c_timeout(unsigned long data)
+{
+ struct s6i2c_if *iface = (struct s6i2c_if *)data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&iface->lock, flags);
+ s6i2c_handle_interrupt(iface);
+ if (--iface->timeout_count > 0) {
+ iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
+ add_timer(&iface->timeout_timer);
+ } else {
+ complete(&iface->complete);
+ i2c_wr16(iface, S6_I2C_INTRMASK, 0);
+ }
+ spin_unlock_irqrestore(&iface->lock, flags);
+}
+
+static int s6i2c_master_xfer(struct i2c_adapter *adap,
+ struct i2c_msg *msgs, int num)
+{
+ struct s6i2c_if *iface = adap->algo_data;
+ int i;
+ if (num == 0)
+ return 0;
+ if (i2c_rd16(iface, S6_I2C_STATUS) & (1 << S6_I2C_STATUS_ACTIVITY))
+ yield();
+ i2c_wr16(iface, S6_I2C_INTRMASK, 0);
+ i2c_rd16(iface, S6_I2C_CLRINTR);
+ for (i = 0; i < num; i++) {
+ if (msgs[i].flags & I2C_M_TEN) {
+ dev_err(&adap->dev,
+ "s6i2c: 10 bits addr not supported\n");
+ return -EINVAL;
+ }
+ if (msgs[i].len == 0) {
+ dev_err(&adap->dev,
+ "s6i2c: zero length message not supported\n");
+ return -EINVAL;
+ }
+ if (msgs[i].addr != msgs[0].addr) {
+ dev_err(&adap->dev,
+ "s6i2c: multiple xfer cannot change target\n");
+ return -EINVAL;
+ }
+ }
+
+ iface->msgs = msgs;
+ iface->msgs_num = num;
+ iface->msgs_push = 0;
+ iface->msgs_done = 0;
+ iface->push = 0;
+ iface->done = 0;
+ iface->timeout_count = 10;
+ i2c_wr16(iface, S6_I2C_TAR, msgs[0].addr);
+ i2c_wr16(iface, S6_I2C_ENABLE, 1);
+ i2c_wr16(iface, S6_I2C_INTRMASK, (1 << S6_I2C_INTR_TXEMPTY) |
+ (1 << S6_I2C_INTR_TXABRT));
+
+ iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
+ add_timer(&iface->timeout_timer);
+ wait_for_completion(&iface->complete);
+ del_timer_sync(&iface->timeout_timer);
+ while (i2c_rd32(iface, S6_I2C_TXFLR) > 0)
+ schedule();
+ while (i2c_rd16(iface, S6_I2C_STATUS) & (1 << S6_I2C_STATUS_ACTIVITY))
+ schedule();
+
+ i2c_wr16(iface, S6_I2C_INTRMASK, 0);
+ i2c_wr16(iface, S6_I2C_ENABLE, 0);
+ return iface->msgs_done;
+}
+
+static u32 s6i2c_functionality(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm s6i2c_algorithm = {
+ .master_xfer = s6i2c_master_xfer,
+ .functionality = s6i2c_functionality,
+};
+
+static u16 __devinit nanoseconds_on_clk(struct s6i2c_if *iface, u32 ns)
+{
+ u32 dividend = ((clk_get_rate(iface->clk) / 1000) * ns) / 1000000;
+ if (dividend > 0xffff)
+ return 0xffff;
+ return dividend;
+}
+
+static int __devinit s6i2c_probe(struct platform_device *dev)
+{
+ struct s6i2c_if *iface = &s6i2c_if;
+ struct i2c_adapter *p_adap;
+ const char *clock;
+ int bus_num, rc;
+ spin_lock_init(&iface->lock);
+ init_completion(&iface->complete);
+ iface->irq = platform_get_irq(dev, 0);
+ if (iface->irq < 0) {
+ rc = iface->irq;
+ goto err_out;
+ }
+ iface->res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!iface->res) {
+ rc = -ENXIO;
+ goto err_out;
+ }
+ iface->res = request_mem_region(iface->res->start,
+ resource_size(iface->res),
+ dev->dev.bus_id);
+ if (!iface->res) {
+ rc = -EBUSY;
+ goto err_out;
+ }
+ iface->reg = ioremap_nocache(iface->res->start,
+ resource_size(iface->res));
+ if (!iface->reg) {
+ rc = -ENOMEM;
+ goto err_reg;
+ }
+
+ clock = 0;
+ bus_num = -1;
+ if (dev->dev.platform_data) {
+ struct s6_i2c_platform_data *pdata = dev->dev.platform_data;
+ bus_num = pdata->bus_num;
+ clock = pdata->clock;
+ }
+ iface->clk = clk_get(&dev->dev, clock);
+ if (IS_ERR(iface->clk)) {
+ rc = PTR_ERR(iface->clk);
+ goto err_map;
+ }
+ rc = clk_enable(iface->clk);
+ if (rc < 0)
+ goto err_clk_put;
+ init_timer(&iface->timeout_timer);
+ iface->timeout_timer.function = s6i2c_timeout;
+ iface->timeout_timer.data = (unsigned long)iface;
+
+ p_adap = &iface->adap;
+ strlcpy(p_adap->name, dev->name, sizeof(p_adap->name));
+ p_adap->algo = &s6i2c_algorithm;
+ p_adap->algo_data = iface;
+ p_adap->nr = bus_num;
+ p_adap->class = 0;
+ p_adap->dev.parent = &dev->dev;
+ i2c_wr16(iface, S6_I2C_INTRMASK, 0);
+ rc = request_irq(iface->irq, s6i2c_interrupt_entry,
+ IRQF_SHARED, dev->name, iface);
+ if (rc) {
+ dev_err(&p_adap->dev, "s6i2c: cant get IRQ %d\n", iface->irq);
+ goto err_clk_dis;
+ }
+
+ i2c_wr16(iface, S6_I2C_ENABLE, 0);
+ udelay(1);
+ i2c_wr32(iface, S6_I2C_SRESET, 1 << S6_I2C_SRESET_IC_SRST);
+ i2c_wr16(iface, S6_I2C_CLRTXABRT, 1);
+ i2c_wr16(iface, S6_I2C_CON,
+ (1 << S6_I2C_CON_MASTER) |
+ (S6_I2C_CON_SPEED_NORMAL << S6_I2C_CON_SPEED) |
+ (0 << S6_I2C_CON_10BITSLAVE) |
+ (0 << S6_I2C_CON_10BITMASTER) |
+ (1 << S6_I2C_CON_RESTARTENA) |
+ (1 << S6_I2C_CON_SLAVEDISABLE));
+ i2c_wr16(iface, S6_I2C_SSHCNT, nanoseconds_on_clk(iface, 4000));
+ i2c_wr16(iface, S6_I2C_SSLCNT, nanoseconds_on_clk(iface, 4700));
+ i2c_wr16(iface, S6_I2C_FSHCNT, nanoseconds_on_clk(iface, 600));
+ i2c_wr16(iface, S6_I2C_FSLCNT, nanoseconds_on_clk(iface, 1300));
+ i2c_wr16(iface, S6_I2C_RXTL, 0);
+ i2c_wr16(iface, S6_I2C_TXTL, 0);
+
+ platform_set_drvdata(dev, iface);
+ if (bus_num < 0)
+ rc = i2c_add_adapter(p_adap);
+ else
+ rc = i2c_add_numbered_adapter(p_adap);
+ if (rc)
+ goto err_irq_free;
+ return 0;
+
+err_irq_free:
+ free_irq(iface->irq, iface);
+err_clk_dis:
+ clk_disable(iface->clk);
+err_clk_put:
+ clk_put(iface->clk);
+err_map:
+ iounmap(iface->reg);
+err_reg:
+ release_mem_region(iface->res->start,
+ resource_size(iface->res));
+err_out:
+ return rc;
+}
+
+static int __devexit s6i2c_remove(struct platform_device *pdev)
+{
+ struct s6i2c_if *iface = platform_get_drvdata(pdev);
+ i2c_wr16(iface, S6_I2C_ENABLE, 0);
+ platform_set_drvdata(pdev, NULL);
+ i2c_del_adapter(&iface->adap);
+ free_irq(iface->irq, iface);
+ clk_disable(iface->clk);
+ clk_put(iface->clk);
+ iounmap(iface->reg);
+ release_mem_region(iface->res->start,
+ resource_size(iface->res));
+ return 0;
+}
+
+static struct platform_driver s6i2c_driver = {
+ .probe = s6i2c_probe,
+ .remove = __devexit_p(s6i2c_remove),
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init s6i2c_init(void)
+{
+ pr_info("I2C: S6000 I2C driver\n");
+ return platform_driver_register(&s6i2c_driver);
+}
+
+static void __exit s6i2c_exit(void)
+{
+ platform_driver_unregister(&s6i2c_driver);
+}
+
+MODULE_DESCRIPTION("I2C-Bus adapter routines for S6000 I2C");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
+
+subsys_initcall(s6i2c_init);
+module_exit(s6i2c_exit);
diff --git a/drivers/i2c/busses/i2c-s6000.h b/drivers/i2c/busses/i2c-s6000.h
new file mode 100644
index 00000000000..ff23b81ded4
--- /dev/null
+++ b/drivers/i2c/busses/i2c-s6000.h
@@ -0,0 +1,79 @@
+/*
+ * drivers/i2c/busses/i2c-s6000.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Emlix GmbH <info@emlix.com>
+ * Author: Oskar Schirmer <os@emlix.com>
+ */
+
+#ifndef __DRIVERS_I2C_BUSSES_I2C_S6000_H
+#define __DRIVERS_I2C_BUSSES_I2C_S6000_H
+
+#define S6_I2C_CON 0x000
+#define S6_I2C_CON_MASTER 0
+#define S6_I2C_CON_SPEED 1
+#define S6_I2C_CON_SPEED_NORMAL 1
+#define S6_I2C_CON_SPEED_FAST 2
+#define S6_I2C_CON_SPEED_MASK 3
+#define S6_I2C_CON_10BITSLAVE 3
+#define S6_I2C_CON_10BITMASTER 4
+#define S6_I2C_CON_RESTARTENA 5
+#define S6_I2C_CON_SLAVEDISABLE 6
+#define S6_I2C_TAR 0x004
+#define S6_I2C_TAR_GCORSTART 10
+#define S6_I2C_TAR_SPECIAL 11
+#define S6_I2C_SAR 0x008
+#define S6_I2C_HSMADDR 0x00C
+#define S6_I2C_DATACMD 0x010
+#define S6_I2C_DATACMD_READ 8
+#define S6_I2C_SSHCNT 0x014
+#define S6_I2C_SSLCNT 0x018
+#define S6_I2C_FSHCNT 0x01C
+#define S6_I2C_FSLCNT 0x020
+#define S6_I2C_INTRSTAT 0x02C
+#define S6_I2C_INTRMASK 0x030
+#define S6_I2C_RAWINTR 0x034
+#define S6_I2C_INTR_RXUNDER 0
+#define S6_I2C_INTR_RXOVER 1
+#define S6_I2C_INTR_RXFULL 2
+#define S6_I2C_INTR_TXOVER 3
+#define S6_I2C_INTR_TXEMPTY 4
+#define S6_I2C_INTR_RDREQ 5
+#define S6_I2C_INTR_TXABRT 6
+#define S6_I2C_INTR_RXDONE 7
+#define S6_I2C_INTR_ACTIVITY 8
+#define S6_I2C_INTR_STOPDET 9
+#define S6_I2C_INTR_STARTDET 10
+#define S6_I2C_INTR_GENCALL 11
+#define S6_I2C_RXTL 0x038
+#define S6_I2C_TXTL 0x03C
+#define S6_I2C_CLRINTR 0x040
+#define S6_I2C_CLRRXUNDER 0x044
+#define S6_I2C_CLRRXOVER 0x048
+#define S6_I2C_CLRTXOVER 0x04C
+#define S6_I2C_CLRRDREQ 0x050
+#define S6_I2C_CLRTXABRT 0x054
+#define S6_I2C_CLRRXDONE 0x058
+#define S6_I2C_CLRACTIVITY 0x05C
+#define S6_I2C_CLRSTOPDET 0x060
+#define S6_I2C_CLRSTARTDET 0x064
+#define S6_I2C_CLRGENCALL 0x068
+#define S6_I2C_ENABLE 0x06C
+#define S6_I2C_STATUS 0x070
+#define S6_I2C_STATUS_ACTIVITY 0
+#define S6_I2C_STATUS_TFNF 1
+#define S6_I2C_STATUS_TFE 2
+#define S6_I2C_STATUS_RFNE 3
+#define S6_I2C_STATUS_RFF 4
+#define S6_I2C_TXFLR 0x074
+#define S6_I2C_RXFLR 0x078
+#define S6_I2C_SRESET 0x07C
+#define S6_I2C_SRESET_IC_SRST 0
+#define S6_I2C_SRESET_IC_MASTER_SRST 1
+#define S6_I2C_SRESET_IC_SLAVE_SRST 2
+#define S6_I2C_TXABRTSOURCE 0x080
+
+#endif
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index b6f3a0de6ca..85e2e919d1c 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -716,8 +716,7 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
/* new style driver methods can't mix with legacy ones */
if (is_newstyle_driver(driver)) {
- if (driver->attach_adapter || driver->detach_adapter
- || driver->detach_client) {
+ if (driver->detach_adapter || driver->detach_client) {
printk(KERN_WARNING
"i2c-core: driver [%s] is confused\n",
driver->driver.name);
diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c
index 8eda552326e..403d0e4265d 100644
--- a/drivers/ide/at91_ide.c
+++ b/drivers/ide/at91_ide.c
@@ -20,7 +20,6 @@
*
*/
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/clk.h>
@@ -175,90 +174,6 @@ static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
leave_16bit(chipselect, mode);
}
-static u8 ide_mm_inb(unsigned long port)
-{
- return readb((void __iomem *) port);
-}
-
-static void ide_mm_outb(u8 value, unsigned long port)
-{
- writeb(value, (void __iomem *) port);
-}
-
-static void at91_ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &cmd->tf;
- u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
- if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
- HIHI = 0xFF;
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
- ide_mm_outb(tf->hob_feature, io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
- ide_mm_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
- ide_mm_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
- ide_mm_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
- ide_mm_outb(tf->hob_lbah, io_ports->lbah_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
- ide_mm_outb(tf->feature, io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
- ide_mm_outb(tf->nsect, io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
- ide_mm_outb(tf->lbal, io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
- ide_mm_outb(tf->lbam, io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
- ide_mm_outb(tf->lbah, io_ports->lbah_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
- ide_mm_outb((tf->device & HIHI) | drive->select, io_ports->device_addr);
-}
-
-static void at91_ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &cmd->tf;
-
- /* be sure we're looking at the low order bits */
- ide_mm_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
- tf->error = ide_mm_inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
- tf->nsect = ide_mm_inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
- tf->lbal = ide_mm_inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
- tf->lbam = ide_mm_inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
- tf->lbah = ide_mm_inb(io_ports->lbah_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
- tf->device = ide_mm_inb(io_ports->device_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- ide_mm_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
- tf->hob_error = ide_mm_inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr);
- }
-}
-
static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
struct ide_timing *timing;
@@ -284,8 +199,8 @@ static const struct ide_tp_ops at91_ide_tp_ops = {
.write_devctl = ide_write_devctl,
.dev_select = ide_dev_select,
- .tf_load = at91_ide_tf_load,
- .tf_read = at91_ide_tf_read,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
.input_data = at91_ide_input_data,
.output_data = at91_ide_output_data,
@@ -300,7 +215,7 @@ static const struct ide_port_info at91_ide_port_info __initdata = {
.tp_ops = &at91_ide_tp_ops,
.host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA | IDE_HFLAG_SINGLE |
IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_UNMASK_IRQS,
- .pio_mask = ATA_PIO5,
+ .pio_mask = ATA_PIO6,
};
/*
diff --git a/drivers/ide/cs5520.c b/drivers/ide/cs5520.c
index 58fb90e5b76..87987a7d36c 100644
--- a/drivers/ide/cs5520.c
+++ b/drivers/ide/cs5520.c
@@ -122,7 +122,7 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
return -ENODEV;
}
pci_set_master(dev);
- if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "%s: No suitable DMA available.\n",
d->name);
return -ENODEV;
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c
index afa2af9a362..0e2df6755ec 100644
--- a/drivers/ide/falconide.c
+++ b/drivers/ide/falconide.c
@@ -20,6 +20,7 @@
#include <asm/atarihw.h>
#include <asm/atariints.h>
#include <asm/atari_stdma.h>
+#include <asm/ide.h>
#define DRV_NAME "falconide"
@@ -67,8 +68,10 @@ static void falconide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
- return insw(data_addr, buf, (len + 1) / 2);
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
+ __ide_mm_insw(data_addr, buf, (len + 1) / 2);
+ return;
+ }
raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
@@ -78,8 +81,10 @@ static void falconide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
- return outsw(data_addr, buf, (len + 1) / 2);
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
+ __ide_mm_outsw(data_addr, buf, (len + 1) / 2);
+ return;
+ }
raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index 12f436951bf..77f79d26b26 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -318,8 +318,9 @@ static int do_drive_set_taskfiles(ide_drive_t *drive,
/* convert GTF to taskfile */
memset(&cmd, 0, sizeof(cmd));
- memcpy(&cmd.tf_array[7], gtf, REGS_PER_GTF);
- cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memcpy(&cmd.tf.feature, gtf, REGS_PER_GTF);
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
err = ide_no_data_taskfile(drive, &cmd);
if (err) {
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index 3e43b889dd6..7201b176d75 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -254,16 +254,13 @@ EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);
void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
{
- struct ide_cmd cmd;
+ struct ide_taskfile tf;
- memset(&cmd, 0, sizeof(cmd));
- cmd.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
- IDE_TFLAG_IN_NSECT;
+ drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT |
+ IDE_VALID_LBAM | IDE_VALID_LBAH);
- drive->hwif->tp_ops->tf_read(drive, &cmd);
-
- *bcount = (cmd.tf.lbah << 8) | cmd.tf.lbam;
- *ireason = cmd.tf.nsect & 3;
+ *bcount = (tf.lbah << 8) | tf.lbam;
+ *ireason = tf.nsect & 3;
}
EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
@@ -439,12 +436,12 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
return ide_started;
}
-static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags,
+static void ide_init_packet_cmd(struct ide_cmd *cmd, u8 valid_tf,
u16 bcount, u8 dma)
{
- cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO;
- cmd->tf_flags |= IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM |
- IDE_TFLAG_OUT_FEATURE | tf_flags;
+ cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO;
+ cmd->valid.out.tf = IDE_VALID_LBAH | IDE_VALID_LBAM |
+ IDE_VALID_FEATURE | valid_tf;
cmd->tf.command = ATA_CMD_PACKET;
cmd->tf.feature = dma; /* Use PIO/DMA */
cmd->tf.lbam = bcount & 0xff;
@@ -453,14 +450,11 @@ static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags,
static u8 ide_read_ireason(ide_drive_t *drive)
{
- struct ide_cmd cmd;
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.tf_flags = IDE_TFLAG_IN_NSECT;
+ struct ide_taskfile tf;
- drive->hwif->tp_ops->tf_read(drive, &cmd);
+ drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT);
- return cmd.tf.nsect & 3;
+ return tf.nsect & 3;
}
static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
@@ -588,12 +582,12 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
ide_expiry_t *expiry = NULL;
struct request *rq = hwif->rq;
unsigned int timeout;
- u32 tf_flags;
u16 bcount;
+ u8 valid_tf;
u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT);
if (dev_is_idecd(drive)) {
- tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
+ valid_tf = IDE_VALID_NSECT | IDE_VALID_LBAL;
bcount = ide_cd_get_xferlen(rq);
expiry = ide_cd_expiry;
timeout = ATAPI_WAIT_PC;
@@ -607,7 +601,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
pc->xferred = 0;
pc->cur_pos = pc->buf;
- tf_flags = IDE_TFLAG_OUT_DEVICE;
+ valid_tf = IDE_VALID_DEVICE;
bcount = ((drive->media == ide_tape) ?
pc->req_xfer :
min(pc->req_xfer, 63 * 1024));
@@ -627,7 +621,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
: WAIT_TAPE_CMD;
}
- ide_init_packet_cmd(cmd, tf_flags, bcount, drive->dma);
+ ide_init_packet_cmd(cmd, valid_tf, bcount, drive->dma);
(void)do_rw_taskfile(drive, cmd);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 35729a47f79..3aec19d1fdf 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -265,35 +265,62 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
cdrom_analyze_sense_data(drive, NULL, sense);
}
+
/*
+ * Allow the drive 5 seconds to recover; some devices will return NOT_READY
+ * while flushing data from cache.
+ *
+ * returns: 0 failed (write timeout expired)
+ * 1 success
+ */
+static int ide_cd_breathe(ide_drive_t *drive, struct request *rq)
+{
+
+ struct cdrom_info *info = drive->driver_data;
+
+ if (!rq->errors)
+ info->write_timeout = jiffies + ATAPI_WAIT_WRITE_BUSY;
+
+ rq->errors = 1;
+
+ if (time_after(jiffies, info->write_timeout))
+ return 0;
+ else {
+ struct request_queue *q = drive->queue;
+ unsigned long flags;
+
+ /*
+ * take a breather relying on the unplug timer to kick us again
+ */
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ blk_plug_device(q);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ return 1;
+ }
+}
+
+/**
* Returns:
* 0: if the request should be continued.
* 1: if the request will be going through error recovery.
* 2: if the request should be ended.
*/
-static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
+static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
{
ide_hwif_t *hwif = drive->hwif;
struct request *rq = hwif->rq;
- int stat, err, sense_key;
-
- /* check for errors */
- stat = hwif->tp_ops->read_status(hwif);
-
- if (stat_ret)
- *stat_ret = stat;
-
- if (OK_STAT(stat, good_stat, BAD_R_STAT))
- return 0;
+ int err, sense_key, do_end_request = 0;
+ u8 quiet = rq->cmd_flags & REQ_QUIET;
/* get the IDE error register */
err = ide_read_error(drive);
sense_key = err >> 4;
- ide_debug_log(IDE_DBG_RQ, "stat: 0x%x, good_stat: 0x%x, cmd[0]: 0x%x, "
- "rq->cmd_type: 0x%x, err: 0x%x",
- stat, good_stat, rq->cmd[0], rq->cmd_type,
- err);
+ ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, rq->cmd_type: 0x%x, err: 0x%x, "
+ "stat 0x%x",
+ rq->cmd[0], rq->cmd_type, err, stat);
if (blk_sense_request(rq)) {
/*
@@ -303,151 +330,108 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
*/
rq->cmd_flags |= REQ_FAILED;
return 2;
- } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) {
- /* All other functions, except for READ. */
+ }
- /*
- * if we have an error, pass back CHECK_CONDITION as the
- * scsi status byte
- */
- if (blk_pc_request(rq) && !rq->errors)
- rq->errors = SAM_STAT_CHECK_CONDITION;
+ /* if we have an error, pass CHECK_CONDITION as the SCSI status byte */
+ if (blk_pc_request(rq) && !rq->errors)
+ rq->errors = SAM_STAT_CHECK_CONDITION;
- /* check for tray open */
- if (sense_key == NOT_READY) {
- cdrom_saw_media_change(drive);
- } else if (sense_key == UNIT_ATTENTION) {
- /* check for media change */
+ if (blk_noretry_request(rq))
+ do_end_request = 1;
+
+ switch (sense_key) {
+ case NOT_READY:
+ if (blk_fs_request(rq) && rq_data_dir(rq) == WRITE) {
+ if (ide_cd_breathe(drive, rq))
+ return 1;
+ } else {
cdrom_saw_media_change(drive);
- return 0;
- } else if (sense_key == ILLEGAL_REQUEST &&
- rq->cmd[0] == GPCMD_START_STOP_UNIT) {
- /*
- * Don't print error message for this condition--
- * SFF8090i indicates that 5/24/00 is the correct
- * response to a request to close the tray if the
- * drive doesn't have that capability.
- * cdrom_log_sense() knows this!
- */
- } else if (!(rq->cmd_flags & REQ_QUIET)) {
- /* otherwise, print an error */
- ide_dump_status(drive, "packet command error", stat);
+
+ if (blk_fs_request(rq) && !quiet)
+ printk(KERN_ERR PFX "%s: tray open\n",
+ drive->name);
}
+ do_end_request = 1;
+ break;
+ case UNIT_ATTENTION:
+ cdrom_saw_media_change(drive);
- rq->cmd_flags |= REQ_FAILED;
+ if (blk_fs_request(rq) == 0)
+ return 0;
/*
- * instead of playing games with moving completions around,
- * remove failed request completely and end it when the
- * request sense has completed
+ * Arrange to retry the request but be sure to give up if we've
+ * retried too many times.
*/
- goto end_request;
-
- } else if (blk_fs_request(rq)) {
- int do_end_request = 0;
-
- /* handle errors from READ and WRITE requests */
-
- if (blk_noretry_request(rq))
+ if (++rq->errors > ERROR_MAX)
do_end_request = 1;
-
- if (sense_key == NOT_READY) {
- /* tray open */
- if (rq_data_dir(rq) == READ) {
- cdrom_saw_media_change(drive);
-
- /* fail the request */
- printk(KERN_ERR PFX "%s: tray open\n",
- drive->name);
- do_end_request = 1;
- } else {
- struct cdrom_info *info = drive->driver_data;
-
- /*
- * Allow the drive 5 seconds to recover, some
- * devices will return this error while flushing
- * data from cache.
- */
- if (!rq->errors)
- info->write_timeout = jiffies +
- ATAPI_WAIT_WRITE_BUSY;
- rq->errors = 1;
- if (time_after(jiffies, info->write_timeout))
- do_end_request = 1;
- else {
- struct request_queue *q = drive->queue;
- unsigned long flags;
-
- /*
- * take a breather relying on the unplug
- * timer to kick us again
- */
- spin_lock_irqsave(q->queue_lock, flags);
- blk_plug_device(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
-
- return 1;
- }
- }
- } else if (sense_key == UNIT_ATTENTION) {
- /* media change */
- cdrom_saw_media_change(drive);
-
- /*
- * Arrange to retry the request but be sure to give up
- * if we've retried too many times.
- */
- if (++rq->errors > ERROR_MAX)
- do_end_request = 1;
- } else if (sense_key == ILLEGAL_REQUEST ||
- sense_key == DATA_PROTECT) {
- /*
- * No point in retrying after an illegal request or data
- * protect error.
- */
+ break;
+ case ILLEGAL_REQUEST:
+ /*
+ * Don't print error message for this condition -- SFF8090i
+ * indicates that 5/24/00 is the correct response to a request
+ * to close the tray if the drive doesn't have that capability.
+ *
+ * cdrom_log_sense() knows this!
+ */
+ if (rq->cmd[0] == GPCMD_START_STOP_UNIT)
+ break;
+ /* fall-through */
+ case DATA_PROTECT:
+ /*
+ * No point in retrying after an illegal request or data
+ * protect error.
+ */
+ if (!quiet)
ide_dump_status(drive, "command error", stat);
- do_end_request = 1;
- } else if (sense_key == MEDIUM_ERROR) {
- /*
- * No point in re-trying a zillion times on a bad
- * sector. If we got here the error is not correctable.
- */
- ide_dump_status(drive, "media error (bad sector)",
+ do_end_request = 1;
+ break;
+ case MEDIUM_ERROR:
+ /*
+ * No point in re-trying a zillion times on a bad sector.
+ * If we got here the error is not correctable.
+ */
+ if (!quiet)
+ ide_dump_status(drive, "media error "
+ "(bad sector)", stat);
+ do_end_request = 1;
+ break;
+ case BLANK_CHECK:
+ /* disk appears blank? */
+ if (!quiet)
+ ide_dump_status(drive, "media error (blank)",
stat);
- do_end_request = 1;
- } else if (sense_key == BLANK_CHECK) {
- /* disk appears blank ?? */
- ide_dump_status(drive, "media error (blank)", stat);
- do_end_request = 1;
- } else if ((err & ~ATA_ABORTED) != 0) {
+ do_end_request = 1;
+ break;
+ default:
+ if (blk_fs_request(rq) == 0)
+ break;
+ if (err & ~ATA_ABORTED) {
/* go to the default handler for other errors */
ide_error(drive, "cdrom_decode_status", stat);
return 1;
- } else if ((++rq->errors > ERROR_MAX)) {
+ } else if (++rq->errors > ERROR_MAX)
/* we've racked up too many retries, abort */
do_end_request = 1;
- }
-
- /*
- * End a request through request sense analysis when we have
- * sense data. We need this in order to perform end of media
- * processing.
- */
- if (do_end_request)
- goto end_request;
+ }
- /*
- * If we got a CHECK_CONDITION status, queue
- * a request sense command.
- */
- if (stat & ATA_ERR)
- cdrom_queue_request_sense(drive, NULL, NULL);
- return 1;
- } else {
- blk_dump_rq_flags(rq, PFX "bad rq");
- return 2;
+ if (blk_fs_request(rq) == 0) {
+ rq->cmd_flags |= REQ_FAILED;
+ do_end_request = 1;
}
+ /*
+ * End a request through request sense analysis when we have sense data.
+ * We need this in order to perform end of media processing.
+ */
+ if (do_end_request)
+ goto end_request;
+
+ /* if we got a CHECK_CONDITION status, queue a request sense command */
+ if (stat & ATA_ERR)
+ cdrom_queue_request_sense(drive, NULL, NULL);
+ return 1;
+
end_request:
if (stat & ATA_ERR) {
struct request_queue *q = drive->queue;
@@ -624,15 +608,14 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq;
ide_expiry_t *expiry = NULL;
- int dma_error = 0, dma, stat, thislen, uptodate = 0;
+ int dma_error = 0, dma, thislen, uptodate = 0;
int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors;
int sense = blk_sense_request(rq);
unsigned int timeout;
u16 len;
- u8 ireason;
+ u8 ireason, stat;
- ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x",
- rq->cmd[0], write);
+ ide_debug_log(IDE_DBG_PC, "cmd: 0x%x, write: 0x%x", rq->cmd[0], write);
/* check for errors */
dma = drive->dma;
@@ -648,11 +631,16 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
}
}
- rc = cdrom_decode_status(drive, 0, &stat);
- if (rc) {
- if (rc == 2)
- goto out_end;
- return ide_stopped;
+ /* check status */
+ stat = hwif->tp_ops->read_status(hwif);
+
+ if (!OK_STAT(stat, 0, BAD_R_STAT)) {
+ rc = cdrom_decode_status(drive, stat);
+ if (rc) {
+ if (rc == 2)
+ goto out_end;
+ return ide_stopped;
+ }
}
/* using dma, transfer is complete now */
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index c998cf8e971..a9fbe2c3121 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -97,35 +97,38 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
}
memset(&cmd, 0, sizeof(cmd));
- cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
if (drive->dev_flags & IDE_DFLAG_LBA) {
if (lba48) {
pr_debug("%s: LBA=0x%012llx\n", drive->name,
(unsigned long long)block);
- tf->hob_nsect = (nsectors >> 8) & 0xff;
- tf->hob_lbal = (u8)(block >> 24);
- if (sizeof(block) != 4) {
- tf->hob_lbam = (u8)((u64)block >> 32);
- tf->hob_lbah = (u8)((u64)block >> 40);
- }
-
tf->nsect = nsectors & 0xff;
tf->lbal = (u8) block;
tf->lbam = (u8)(block >> 8);
tf->lbah = (u8)(block >> 16);
+ tf->device = ATA_LBA;
- cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+ tf = &cmd.hob;
+ tf->nsect = (nsectors >> 8) & 0xff;
+ tf->lbal = (u8)(block >> 24);
+ if (sizeof(block) != 4) {
+ tf->lbam = (u8)((u64)block >> 32);
+ tf->lbah = (u8)((u64)block >> 40);
+ }
+
+ cmd.valid.out.hob = IDE_VALID_OUT_HOB;
+ cmd.valid.in.hob = IDE_VALID_IN_HOB;
+ cmd.tf_flags |= IDE_TFLAG_LBA48;
} else {
tf->nsect = nsectors & 0xff;
tf->lbal = block;
tf->lbam = block >>= 8;
tf->lbah = block >>= 8;
- tf->device = (block >> 8) & 0xf;
+ tf->device = ((block >> 8) & 0xf) | ATA_LBA;
}
-
- tf->device |= ATA_LBA;
} else {
unsigned int sect, head, cyl, track;
@@ -220,15 +223,19 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
tf->command = ATA_CMD_READ_NATIVE_MAX;
tf->device = ATA_LBA;
- cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- if (lba48)
- cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
+ if (lba48) {
+ cmd.valid.out.hob = IDE_VALID_OUT_HOB;
+ cmd.valid.in.hob = IDE_VALID_IN_HOB;
+ cmd.tf_flags = IDE_TFLAG_LBA48;
+ }
ide_no_data_taskfile(drive, &cmd);
/* if OK, compute maximum address value */
if (!(tf->status & ATA_ERR))
- addr = ide_get_lba_addr(tf, lba48) + 1;
+ addr = ide_get_lba_addr(&cmd, lba48) + 1;
return addr;
}
@@ -250,9 +257,9 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
tf->lbam = (addr_req >>= 8) & 0xff;
tf->lbah = (addr_req >>= 8) & 0xff;
if (lba48) {
- tf->hob_lbal = (addr_req >>= 8) & 0xff;
- tf->hob_lbam = (addr_req >>= 8) & 0xff;
- tf->hob_lbah = (addr_req >>= 8) & 0xff;
+ cmd.hob.lbal = (addr_req >>= 8) & 0xff;
+ cmd.hob.lbam = (addr_req >>= 8) & 0xff;
+ cmd.hob.lbah = (addr_req >>= 8) & 0xff;
tf->command = ATA_CMD_SET_MAX_EXT;
} else {
tf->device = (addr_req >>= 8) & 0x0f;
@@ -260,15 +267,19 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
}
tf->device |= ATA_LBA;
- cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- if (lba48)
- cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
+ if (lba48) {
+ cmd.valid.out.hob = IDE_VALID_OUT_HOB;
+ cmd.valid.in.hob = IDE_VALID_IN_HOB;
+ cmd.tf_flags = IDE_TFLAG_LBA48;
+ }
ide_no_data_taskfile(drive, &cmd);
/* if OK, compute maximum address value */
if (!(tf->status & ATA_ERR))
- addr_set = ide_get_lba_addr(tf, lba48) + 1;
+ addr_set = ide_get_lba_addr(&cmd, lba48) + 1;
return addr_set;
}
@@ -395,8 +406,8 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
cmd->tf.command = ATA_CMD_FLUSH_EXT;
else
cmd->tf.command = ATA_CMD_FLUSH;
- cmd->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
- IDE_TFLAG_DYN;
+ cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd->tf_flags = IDE_TFLAG_DYN;
cmd->protocol = ATA_PROT_NODATA;
rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
@@ -457,7 +468,8 @@ static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect)
cmd.tf.feature = feature;
cmd.tf.nsect = nsect;
cmd.tf.command = ATA_CMD_SET_FEATURES;
- cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
return ide_no_data_taskfile(drive, &cmd);
}
@@ -533,7 +545,8 @@ static int do_idedisk_flushcache(ide_drive_t *drive)
cmd.tf.command = ATA_CMD_FLUSH_EXT;
else
cmd.tf.command = ATA_CMD_FLUSH;
- cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
return ide_no_data_taskfile(drive, &cmd);
}
@@ -715,7 +728,8 @@ static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk,
memset(&cmd, 0, sizeof(cmd));
cmd.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
- cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
ret = ide_no_data_taskfile(drive, &cmd);
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c
index eaea3bef207..19f263bf0a9 100644
--- a/drivers/ide/ide-disk_proc.c
+++ b/drivers/ide/ide-disk_proc.c
@@ -13,7 +13,8 @@ static int smart_enable(ide_drive_t *drive)
tf->lbam = ATA_SMART_LBAM_PASS;
tf->lbah = ATA_SMART_LBAH_PASS;
tf->command = ATA_CMD_SMART;
- cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
return ide_no_data_taskfile(drive, &cmd);
}
@@ -29,7 +30,8 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
tf->lbam = ATA_SMART_LBAM_PASS;
tf->lbah = ATA_SMART_LBAH_PASS;
tf->command = ATA_CMD_SMART;
- cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
cmd.protocol = ATA_PROT_PIO;
return ide_raw_taskfile(drive, &cmd, buf, 1);
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index 16fc46edc32..e4cdf78cc3e 100644
--- a/drivers/ide/ide-dma-sff.c
+++ b/drivers/ide/ide-dma-sff.c
@@ -277,8 +277,6 @@ void ide_dma_start(ide_drive_t *drive)
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
outb(dma_cmd | ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD);
}
-
- wmb();
}
EXPORT_SYMBOL_GPL(ide_dma_start);
@@ -286,7 +284,7 @@ EXPORT_SYMBOL_GPL(ide_dma_start);
int ide_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- u8 dma_stat = 0, dma_cmd = 0, mask;
+ u8 dma_stat = 0, dma_cmd = 0;
/* stop DMA */
if (hwif->host_flags & IDE_HFLAG_MMIO) {
@@ -304,11 +302,10 @@ int ide_dma_end(ide_drive_t *drive)
/* clear INTR & ERROR bits */
ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
- wmb();
+#define CHECK_DMA_MASK (ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR)
/* verify good DMA status */
- mask = ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR;
- if ((dma_stat & mask) != ATA_DMA_INTR)
+ if ((dma_stat & CHECK_DMA_MASK) != ATA_DMA_INTR)
return 0x10 | dma_stat;
return 0;
}
diff --git a/drivers/ide/ide-h8300.c b/drivers/ide/ide-h8300.c
index dac9a6d4496..c06ebdc4a13 100644
--- a/drivers/ide/ide-h8300.c
+++ b/drivers/ide/ide-h8300.c
@@ -22,103 +22,6 @@
(r); \
})
-static void mm_outw(u16 d, unsigned long a)
-{
- __asm__("mov.b %w0,r2h\n\t"
- "mov.b %x0,r2l\n\t"
- "mov.w r2,@%1"
- :
- :"r"(d),"r"(a)
- :"er2");
-}
-
-static u16 mm_inw(unsigned long a)
-{
- register u16 r __asm__("er0");
- __asm__("mov.w @%1,r2\n\t"
- "mov.b r2l,%x0\n\t"
- "mov.b r2h,%w0"
- :"=r"(r)
- :"r"(a)
- :"er2");
- return r;
-}
-
-static void h8300_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &cmd->tf;
- u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
- if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
- HIHI = 0xFF;
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
- outb(tf->hob_feature, io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
- outb(tf->hob_nsect, io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
- outb(tf->hob_lbal, io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
- outb(tf->hob_lbam, io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
- outb(tf->hob_lbah, io_ports->lbah_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
- outb(tf->feature, io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
- outb(tf->nsect, io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
- outb(tf->lbal, io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
- outb(tf->lbam, io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
- outb(tf->lbah, io_ports->lbah_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
- outb((tf->device & HIHI) | drive->select,
- io_ports->device_addr);
-}
-
-static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &cmd->tf;
-
- /* be sure we're looking at the low order bits */
- outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
- tf->error = inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
- tf->nsect = inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
- tf->lbal = inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
- tf->lbam = inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
- tf->lbah = inb(io_ports->lbah_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
- tf->device = inb(io_ports->device_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
- tf->hob_error = inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = inb(io_ports->lbah_addr);
- }
-}
-
static void mm_outsw(unsigned long addr, void *buf, u32 len)
{
unsigned short *bp = (unsigned short *)buf;
@@ -152,8 +55,8 @@ static const struct ide_tp_ops h8300_tp_ops = {
.write_devctl = ide_write_devctl,
.dev_select = ide_dev_select,
- .tf_load = h8300_tf_load,
- .tf_read = h8300_tf_read,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
.input_data = h8300_input_data,
.output_data = h8300_output_data,
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c
index 9cac281d82c..46721c45451 100644
--- a/drivers/ide/ide-io-std.c
+++ b/drivers/ide/ide-io-std.c
@@ -85,98 +85,57 @@ void ide_dev_select(ide_drive_t *drive)
}
EXPORT_SYMBOL_GPL(ide_dev_select);
-void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
+void ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &cmd->tf;
void (*tf_outb)(u8 addr, unsigned long port);
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
- u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
if (mmio)
tf_outb = ide_mm_outb;
else
tf_outb = ide_outb;
- if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
- HIHI = 0xFF;
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
- tf_outb(tf->hob_feature, io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
- tf_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
- tf_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
- tf_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
- tf_outb(tf->hob_lbah, io_ports->lbah_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (valid & IDE_VALID_FEATURE)
tf_outb(tf->feature, io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (valid & IDE_VALID_NSECT)
tf_outb(tf->nsect, io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (valid & IDE_VALID_LBAL)
tf_outb(tf->lbal, io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (valid & IDE_VALID_LBAM)
tf_outb(tf->lbam, io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (valid & IDE_VALID_LBAH)
tf_outb(tf->lbah, io_ports->lbah_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
- tf_outb((tf->device & HIHI) | drive->select,
- io_ports->device_addr);
+ if (valid & IDE_VALID_DEVICE)
+ tf_outb(tf->device, io_ports->device_addr);
}
EXPORT_SYMBOL_GPL(ide_tf_load);
-void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
+void ide_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &cmd->tf;
- void (*tf_outb)(u8 addr, unsigned long port);
u8 (*tf_inb)(unsigned long port);
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
- if (mmio) {
- tf_outb = ide_mm_outb;
+ if (mmio)
tf_inb = ide_mm_inb;
- } else {
- tf_outb = ide_outb;
+ else
tf_inb = ide_inb;
- }
-
- /* be sure we're looking at the low order bits */
- tf_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ if (valid & IDE_VALID_ERROR)
tf->error = tf_inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (valid & IDE_VALID_NSECT)
tf->nsect = tf_inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (valid & IDE_VALID_LBAL)
tf->lbal = tf_inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (valid & IDE_VALID_LBAM)
tf->lbam = tf_inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (valid & IDE_VALID_LBAH)
tf->lbah = tf_inb(io_ports->lbah_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (valid & IDE_VALID_DEVICE)
tf->device = tf_inb(io_ports->device_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- tf_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
- tf->hob_error = tf_inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tf_inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tf_inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tf_inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tf_inb(io_ports->lbah_addr);
- }
}
EXPORT_SYMBOL_GPL(ide_tf_read);
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 1deb6d29b18..2ae02b8d7f8 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -86,18 +86,18 @@ void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
tp_ops->input_data(drive, cmd, data, 2);
- tf->data = data[0];
- tf->hob_data = data[1];
+ cmd->tf.data = data[0];
+ cmd->hob.data = data[1];
}
- tp_ops->tf_read(drive, cmd);
+ ide_tf_readback(drive, cmd);
if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) &&
tf_cmd == ATA_CMD_IDLEIMMEDIATE) {
if (tf->lbal != 0xc4) {
printk(KERN_ERR "%s: head unload failed!\n",
drive->name);
- ide_tf_dump(drive->name, tf);
+ ide_tf_dump(drive->name, cmd);
} else
drive->dev_flags |= IDE_DFLAG_PARKED;
}
@@ -205,8 +205,9 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive)
return ide_stopped;
}
- cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE |
- IDE_TFLAG_CUSTOM_HANDLER;
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
+ cmd.tf_flags = IDE_TFLAG_CUSTOM_HANDLER;
do_rw_taskfile(drive, &cmd);
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index 77014276743..c1c25ebbaa1 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -141,11 +141,12 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
tf->lbal = args[1];
tf->lbam = 0x4f;
tf->lbah = 0xc2;
- cmd.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT;
+ cmd.valid.out.tf = IDE_VALID_OUT_TF;
+ cmd.valid.in.tf = IDE_VALID_NSECT;
} else {
tf->nsect = args[1];
- cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
- IDE_TFLAG_IN_NSECT;
+ cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT;
+ cmd.valid.in.tf = IDE_VALID_NSECT;
}
tf->command = args[0];
cmd.protocol = args[3] ? ATA_PROT_PIO : ATA_PROT_NODATA;
@@ -205,14 +206,15 @@ static int ide_task_ioctl(ide_drive_t *drive, unsigned long arg)
return -EFAULT;
memset(&cmd, 0, sizeof(cmd));
- memcpy(&cmd.tf_array[7], &args[1], 6);
+ memcpy(&cmd.tf.feature, &args[1], 6);
cmd.tf.command = args[0];
- cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
err = ide_no_data_taskfile(drive, &cmd);
args[0] = cmd.tf.command;
- memcpy(&args[1], &cmd.tf_array[7], 6);
+ memcpy(&args[1], &cmd.tf.feature, 6);
if (copy_to_user(p, args, 7))
err = -EFAULT;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 27bb70ddd45..c19a221b1e1 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -37,14 +37,11 @@ void SELECT_MASK(ide_drive_t *drive, int mask)
u8 ide_read_error(ide_drive_t *drive)
{
- struct ide_cmd cmd;
+ struct ide_taskfile tf;
- memset(&cmd, 0, sizeof(cmd));
- cmd.tf_flags = IDE_TFLAG_IN_ERROR;
+ drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_ERROR);
- drive->hwif->tp_ops->tf_read(drive, &cmd);
-
- return cmd.tf.error;
+ return tf.error;
}
EXPORT_SYMBOL_GPL(ide_read_error);
@@ -312,10 +309,10 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+ struct ide_taskfile tf;
u16 *id = drive->id, i;
int error = 0;
u8 stat;
- struct ide_cmd cmd;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_ops) /* check if host supports DMA */
@@ -347,12 +344,11 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
udelay(1);
tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
- memset(&cmd, 0, sizeof(cmd));
- cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT;
- cmd.tf.feature = SETFEATURES_XFER;
- cmd.tf.nsect = speed;
+ memset(&tf, 0, sizeof(tf));
+ tf.feature = SETFEATURES_XFER;
+ tf.nsect = speed;
- tp_ops->tf_load(drive, &cmd);
+ tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE | IDE_VALID_NSECT);
tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES);
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 217b7fdf2b1..56ff8c46c7d 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -49,16 +49,17 @@ static void ide_dump_opcode(ide_drive_t *drive)
printk(KERN_CONT "0x%02x\n", cmd->tf.command);
}
-u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48)
+u64 ide_get_lba_addr(struct ide_cmd *cmd, int lba48)
{
+ struct ide_taskfile *tf = &cmd->tf;
u32 high, low;
- if (lba48)
- high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) |
- tf->hob_lbal;
- else
- high = tf->device & 0xf;
low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal;
+ if (lba48) {
+ tf = &cmd->hob;
+ high = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal;
+ } else
+ high = tf->device & 0xf;
return ((u64)high << 24) | low;
}
@@ -71,17 +72,18 @@ static void ide_dump_sector(ide_drive_t *drive)
u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
memset(&cmd, 0, sizeof(cmd));
- if (lba48)
- cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA |
- IDE_TFLAG_LBA48;
- else
- cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE;
+ if (lba48) {
+ cmd.valid.in.tf = IDE_VALID_LBA;
+ cmd.valid.in.hob = IDE_VALID_LBA;
+ cmd.tf_flags = IDE_TFLAG_LBA48;
+ } else
+ cmd.valid.in.tf = IDE_VALID_LBA | IDE_VALID_DEVICE;
- drive->hwif->tp_ops->tf_read(drive, &cmd);
+ ide_tf_readback(drive, &cmd);
if (lba48 || (tf->device & ATA_LBA))
printk(KERN_CONT ", LBAsect=%llu",
- (unsigned long long)ide_get_lba_addr(tf, lba48));
+ (unsigned long long)ide_get_lba_addr(&cmd, lba48));
else
printk(KERN_CONT ", CHS=%d/%d/%d", (tf->lbah << 8) + tf->lbam,
tf->device & 0xf, tf->lbal);
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index 9490b446519..310d03f2b5b 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -74,7 +74,8 @@ ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq)
tf->lbal = 0x4c;
tf->lbam = 0x4e;
tf->lbah = 0x55;
- cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
} else /* cmd == REQ_UNPARK_HEADS */
tf->command = ATA_CMD_CHK_POWER;
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c
index bb7858ebb7d..0d8a151c0a0 100644
--- a/drivers/ide/ide-pm.c
+++ b/drivers/ide/ide-pm.c
@@ -163,7 +163,8 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
return ide_stopped;
out_do_tf:
- cmd->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd->valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
cmd->protocol = ATA_PROT_NODATA;
return do_rw_taskfile(drive, cmd);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index d8c1c3e735b..7f264ed1141 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -283,13 +283,11 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
* identify command to be sure of reply
*/
if (cmd == ATA_CMD_ID_ATAPI) {
- struct ide_cmd cmd;
+ struct ide_taskfile tf;
- memset(&cmd, 0, sizeof(cmd));
+ memset(&tf, 0, sizeof(tf));
/* disable DMA & overlap */
- cmd.tf_flags = IDE_TFLAG_OUT_FEATURE;
-
- tp_ops->tf_load(drive, &cmd);
+ tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE);
}
/* ask drive for ID */
@@ -337,14 +335,11 @@ int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus)
static u8 ide_read_device(ide_drive_t *drive)
{
- struct ide_cmd cmd;
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.tf_flags = IDE_TFLAG_IN_DEVICE;
+ struct ide_taskfile tf;
- drive->hwif->tp_ops->tf_read(drive, &cmd);
+ drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_DEVICE);
- return cmd.tf.device;
+ return tf.device;
}
/**
@@ -1314,6 +1309,7 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
host->get_lock = d->get_lock;
host->release_lock = d->release_lock;
host->host_flags = d->host_flags;
+ host->irq_flags = d->irq_flags;
}
return host;
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 10a88bf3eef..3242698832a 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -204,8 +204,8 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
cmd.tf.command = ATA_CMD_SET_FEATURES;
cmd.tf.feature = SETFEATURES_XFER;
cmd.tf.nsect = (u8)arg;
- cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
- IDE_TFLAG_IN_NSECT;
+ cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT;
+ cmd.valid.in.tf = IDE_VALID_NSECT;
err = ide_no_data_taskfile(drive, &cmd);
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 243421ce40d..4aa6223c11b 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -23,17 +23,33 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-void ide_tf_dump(const char *s, struct ide_taskfile *tf)
+void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+
+ /* Be sure we're looking at the low order bytes */
+ tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
+
+ tp_ops->tf_read(drive, &cmd->tf, cmd->valid.in.tf);
+
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ tp_ops->write_devctl(hwif, ATA_HOB | ATA_DEVCTL_OBS);
+
+ tp_ops->tf_read(drive, &cmd->hob, cmd->valid.in.hob);
+ }
+}
+
+void ide_tf_dump(const char *s, struct ide_cmd *cmd)
{
#ifdef DEBUG
printk("%s: tf: feat 0x%02x nsect 0x%02x lbal 0x%02x "
"lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n",
- s, tf->feature, tf->nsect, tf->lbal,
- tf->lbam, tf->lbah, tf->device, tf->command);
- printk("%s: hob: nsect 0x%02x lbal 0x%02x "
- "lbam 0x%02x lbah 0x%02x\n",
- s, tf->hob_nsect, tf->hob_lbal,
- tf->hob_lbam, tf->hob_lbah);
+ s, cmd->tf.feature, cmd->tf.nsect,
+ cmd->tf.lbal, cmd->tf.lbam, cmd->tf.lbah,
+ cmd->tf.device, cmd->tf.command);
+ printk("%s: hob: nsect 0x%02x lbal 0x%02x lbam 0x%02x lbah 0x%02x\n",
+ s, cmd->hob.nsect, cmd->hob.lbal, cmd->hob.lbam, cmd->hob.lbah);
#endif
}
@@ -47,7 +63,8 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
cmd.tf.command = ATA_CMD_ID_ATA;
else
cmd.tf.command = ATA_CMD_ID_ATAPI;
- cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
cmd.protocol = ATA_PROT_PIO;
return ide_raw_taskfile(drive, &cmd, buf, 1);
@@ -79,16 +96,27 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
memcpy(cmd, orig_cmd, sizeof(*cmd));
if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
- ide_tf_dump(drive->name, tf);
+ ide_tf_dump(drive->name, cmd);
tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
SELECT_MASK(drive, 0);
if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
- u8 data[2] = { tf->data, tf->hob_data };
+ u8 data[2] = { cmd->tf.data, cmd->hob.data };
tp_ops->output_data(drive, cmd, data, 2);
}
- tp_ops->tf_load(drive, cmd);
+
+ if (cmd->valid.out.tf & IDE_VALID_DEVICE) {
+ u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ?
+ 0xE0 : 0xEF;
+
+ if (!(cmd->ftf_flags & IDE_FTFLAG_FLAGGED))
+ cmd->tf.device &= HIHI;
+ cmd->tf.device |= drive->select;
+ }
+
+ tp_ops->tf_load(drive, &cmd->hob, cmd->valid.out.hob);
+ tp_ops->tf_load(drive, &cmd->tf, cmd->valid.out.tf);
}
switch (cmd->protocol) {
@@ -489,16 +517,17 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
memset(&cmd, 0, sizeof(cmd));
- memcpy(&cmd.tf_array[0], req_task->hob_ports,
- HDIO_DRIVE_HOB_HDR_SIZE - 2);
- memcpy(&cmd.tf_array[6], req_task->io_ports,
- HDIO_DRIVE_TASK_HDR_SIZE);
+ memcpy(&cmd.hob, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2);
+ memcpy(&cmd.tf, req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
- cmd.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
- IDE_TFLAG_IN_TF;
+ cmd.valid.out.tf = IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_DEVICE | IDE_VALID_IN_TF;
+ cmd.tf_flags = IDE_TFLAG_IO_16BIT;
- if (drive->dev_flags & IDE_DFLAG_LBA48)
- cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
+ if (drive->dev_flags & IDE_DFLAG_LBA48) {
+ cmd.tf_flags |= IDE_TFLAG_LBA48;
+ cmd.valid.in.hob = IDE_VALID_IN_HOB;
+ }
if (req_task->out_flags.all) {
cmd.ftf_flags |= IDE_FTFLAG_FLAGGED;
@@ -507,28 +536,28 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
cmd.ftf_flags |= IDE_FTFLAG_OUT_DATA;
if (req_task->out_flags.b.nsector_hob)
- cmd.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT;
+ cmd.valid.out.hob |= IDE_VALID_NSECT;
if (req_task->out_flags.b.sector_hob)
- cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL;
+ cmd.valid.out.hob |= IDE_VALID_LBAL;
if (req_task->out_flags.b.lcyl_hob)
- cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM;
+ cmd.valid.out.hob |= IDE_VALID_LBAM;
if (req_task->out_flags.b.hcyl_hob)
- cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH;
+ cmd.valid.out.hob |= IDE_VALID_LBAH;
if (req_task->out_flags.b.error_feature)
- cmd.tf_flags |= IDE_TFLAG_OUT_FEATURE;
+ cmd.valid.out.tf |= IDE_VALID_FEATURE;
if (req_task->out_flags.b.nsector)
- cmd.tf_flags |= IDE_TFLAG_OUT_NSECT;
+ cmd.valid.out.tf |= IDE_VALID_NSECT;
if (req_task->out_flags.b.sector)
- cmd.tf_flags |= IDE_TFLAG_OUT_LBAL;
+ cmd.valid.out.tf |= IDE_VALID_LBAL;
if (req_task->out_flags.b.lcyl)
- cmd.tf_flags |= IDE_TFLAG_OUT_LBAM;
+ cmd.valid.out.tf |= IDE_VALID_LBAM;
if (req_task->out_flags.b.hcyl)
- cmd.tf_flags |= IDE_TFLAG_OUT_LBAH;
+ cmd.valid.out.tf |= IDE_VALID_LBAH;
} else {
- cmd.tf_flags |= IDE_TFLAG_OUT_TF;
+ cmd.valid.out.tf |= IDE_VALID_OUT_TF;
if (cmd.tf_flags & IDE_TFLAG_LBA48)
- cmd.tf_flags |= IDE_TFLAG_OUT_HOB;
+ cmd.valid.out.hob |= IDE_VALID_OUT_HOB;
}
if (req_task->in_flags.b.data)
@@ -594,7 +623,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
nsect = 0;
else if (!nsect) {
- nsect = (cmd.tf.hob_nsect << 8) | cmd.tf.nsect;
+ nsect = (cmd.hob.nsect << 8) | cmd.tf.nsect;
if (!nsect) {
printk(KERN_ERR "%s: in/out command without data\n",
@@ -606,10 +635,8 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
err = ide_raw_taskfile(drive, &cmd, data_buf, nsect);
- memcpy(req_task->hob_ports, &cmd.tf_array[0],
- HDIO_DRIVE_HOB_HDR_SIZE - 2);
- memcpy(req_task->io_ports, &cmd.tf_array[6],
- HDIO_DRIVE_TASK_HDR_SIZE);
+ memcpy(req_task->hob_ports, &cmd.hob, HDIO_DRIVE_HOB_HDR_SIZE - 2);
+ memcpy(req_task->io_ports, &cmd.tf, HDIO_DRIVE_TASK_HDR_SIZE);
if ((cmd.ftf_flags & IDE_FTFLAG_SET_IN_FLAGS) &&
req_task->in_flags.all == 0) {
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index 71a39fb3856..95327a2c242 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -61,41 +61,23 @@ static u8 superio_dma_sff_read_status(ide_hwif_t *hwif)
return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS);
}
-static void superio_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
+static void superio_tf_read(ide_drive_t *drive, struct ide_taskfile *tf,
+ u8 valid)
{
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
- struct ide_taskfile *tf = &cmd->tf;
- /* be sure we're looking at the low order bits */
- outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ if (valid & IDE_VALID_ERROR)
tf->error = inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (valid & IDE_VALID_NSECT)
tf->nsect = inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (valid & IDE_VALID_LBAL)
tf->lbal = inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (valid & IDE_VALID_LBAM)
tf->lbam = inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (valid & IDE_VALID_LBAH)
tf->lbah = inb(io_ports->lbah_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (valid & IDE_VALID_DEVICE)
tf->device = superio_ide_inb(io_ports->device_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
- tf->hob_error = inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = inb(io_ports->lbah_addr);
- }
}
static void ns87415_dev_select(ide_drive_t *drive);
diff --git a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c
index d007e7f6659..c7934667924 100644
--- a/drivers/ide/q40ide.c
+++ b/drivers/ide/q40ide.c
@@ -16,6 +16,8 @@
#include <linux/blkdev.h>
#include <linux/ide.h>
+#include <asm/ide.h>
+
/*
* Bases of the IDE interfaces
*/
@@ -77,8 +79,10 @@ static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
- return insw(data_addr, buf, (len + 1) / 2);
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
+ __ide_mm_insw(data_addr, buf, (len + 1) / 2);
+ return;
+ }
raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
@@ -88,8 +92,10 @@ static void q40ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
- return outsw(data_addr, buf, (len + 1) / 2);
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
+ __ide_mm_outsw(data_addr, buf, (len + 1) / 2);
+ return;
+ }
raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c
index 6d8dbd9c10b..5be41f25204 100644
--- a/drivers/ide/scc_pata.c
+++ b/drivers/ide/scc_pata.c
@@ -337,7 +337,6 @@ static void scc_dma_start(ide_drive_t *drive)
/* start DMA */
scc_ide_outb(dma_cmd | 1, hwif->dma_base);
- wmb();
}
static int __scc_dma_end(ide_drive_t *drive)
@@ -354,7 +353,6 @@ static int __scc_dma_end(ide_drive_t *drive)
/* clear the INTR & ERROR bits */
scc_ide_outb(dma_stat | 6, hwif->dma_base + 4);
/* verify good DMA status */
- wmb();
return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
}
@@ -647,77 +645,40 @@ static int __devinit init_setup_scc(struct pci_dev *dev,
return rc;
}
-static void scc_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
+static void scc_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
{
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
- struct ide_taskfile *tf = &cmd->tf;
- u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
- if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
- HIHI = 0xFF;
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
- scc_ide_outb(tf->hob_feature, io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
- scc_ide_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
- scc_ide_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
- scc_ide_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
- scc_ide_outb(tf->hob_lbah, io_ports->lbah_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
+
+ if (valid & IDE_VALID_FEATURE)
scc_ide_outb(tf->feature, io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (valid & IDE_VALID_NSECT)
scc_ide_outb(tf->nsect, io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (valid & IDE_VALID_LBAL)
scc_ide_outb(tf->lbal, io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (valid & IDE_VALID_LBAM)
scc_ide_outb(tf->lbam, io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (valid & IDE_VALID_LBAH)
scc_ide_outb(tf->lbah, io_ports->lbah_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
- scc_ide_outb((tf->device & HIHI) | drive->select,
- io_ports->device_addr);
+ if (valid & IDE_VALID_DEVICE)
+ scc_ide_outb(tf->device, io_ports->device_addr);
}
-static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
+static void scc_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
{
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
- struct ide_taskfile *tf = &cmd->tf;
-
- /* be sure we're looking at the low order bits */
- scc_ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ if (valid & IDE_VALID_ERROR)
tf->error = scc_ide_inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (valid & IDE_VALID_NSECT)
tf->nsect = scc_ide_inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (valid & IDE_VALID_LBAL)
tf->lbal = scc_ide_inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (valid & IDE_VALID_LBAM)
tf->lbam = scc_ide_inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (valid & IDE_VALID_LBAH)
tf->lbah = scc_ide_inb(io_ports->lbah_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (valid & IDE_VALID_DEVICE)
tf->device = scc_ide_inb(io_ports->device_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- scc_ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
- tf->hob_error = scc_ide_inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr);
- }
}
static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index a19dbccd761..7a3a12d6e63 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -208,7 +208,7 @@ static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d)
* a DMA mask field to the struct ide_port_info if we need it
* (or let lower level driver set the DMA mask)
*/
- ret = pci_set_dma_mask(dev, DMA_32BIT_MASK);
+ ret = pci_set_dma_mask(dev, DMA_BIT_MASK(32));
if (ret < 0) {
printk(KERN_ERR "%s %s: can't set DMA mask\n",
d->name, pci_name(dev));
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c
index 4cb79c4c260..e33d764e294 100644
--- a/drivers/ide/tx4938ide.c
+++ b/drivers/ide/tx4938ide.c
@@ -72,91 +72,6 @@ static void tx4938ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
#ifdef __BIG_ENDIAN
/* custom iops (independent from SWAP_IO_SPACE) */
-static u8 tx4938ide_inb(unsigned long port)
-{
- return __raw_readb((void __iomem *)port);
-}
-
-static void tx4938ide_outb(u8 value, unsigned long port)
-{
- __raw_writeb(value, (void __iomem *)port);
-}
-
-static void tx4938ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &cmd->tf;
- u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
-
- if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
- HIHI = 0xFF;
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
- tx4938ide_outb(tf->hob_feature, io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
- tx4938ide_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
- tx4938ide_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
- tx4938ide_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
- tx4938ide_outb(tf->hob_lbah, io_ports->lbah_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
- tx4938ide_outb(tf->feature, io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
- tx4938ide_outb(tf->nsect, io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
- tx4938ide_outb(tf->lbal, io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
- tx4938ide_outb(tf->lbam, io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
- tx4938ide_outb(tf->lbah, io_ports->lbah_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
- tx4938ide_outb((tf->device & HIHI) | drive->select,
- io_ports->device_addr);
-}
-
-static void tx4938ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &cmd->tf;
-
- /* be sure we're looking at the low order bits */
- tx4938ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
- tf->error = tx4938ide_inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
- tf->nsect = tx4938ide_inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
- tf->lbal = tx4938ide_inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
- tf->lbam = tx4938ide_inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
- tf->lbah = tx4938ide_inb(io_ports->lbah_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
- tf->device = tx4938ide_inb(io_ports->device_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- tx4938ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
- tf->hob_error = tx4938ide_inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr);
- }
-}
-
static void tx4938ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
@@ -190,8 +105,8 @@ static const struct ide_tp_ops tx4938ide_tp_ops = {
.write_devctl = ide_write_devctl,
.dev_select = ide_dev_select,
- .tf_load = tx4938ide_tf_load,
- .tf_read = tx4938ide_tf_read,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
.input_data = tx4938ide_input_data_swap,
.output_data = tx4938ide_output_data_swap,
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index 0040a9a3e26..564422d2397 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -327,15 +327,15 @@ static int tx4939ide_dma_end(ide_drive_t *drive)
/* read and clear the INTR & ERROR bits */
dma_stat = tx4939ide_clear_dma_status(base);
- wmb();
+#define CHECK_DMA_MASK (ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR)
/* verify good DMA status */
- if ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == 0 &&
+ if ((dma_stat & CHECK_DMA_MASK) == 0 &&
(ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) ==
(TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST))
/* INT_IDE lost... bug? */
return 0;
- return ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) !=
+ return ((dma_stat & CHECK_DMA_MASK) !=
ATA_DMA_INTR) ? 0x10 | dma_stat : 0;
}
@@ -434,97 +434,19 @@ static void tx4939ide_tf_load_fixup(ide_drive_t *drive)
tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl);
}
-#ifdef __BIG_ENDIAN
-
-/* custom iops (independent from SWAP_IO_SPACE) */
-static u8 tx4939ide_inb(unsigned long port)
+static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf,
+ u8 valid)
{
- return __raw_readb((void __iomem *)port);
-}
+ ide_tf_load(drive, tf, valid);
-static void tx4939ide_outb(u8 value, unsigned long port)
-{
- __raw_writeb(value, (void __iomem *)port);
-}
-
-static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &cmd->tf;
- u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
-
- if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
- HIHI = 0xFF;
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
- tx4939ide_outb(tf->hob_feature, io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
- tx4939ide_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
- tx4939ide_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
- tx4939ide_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
- tx4939ide_outb(tf->hob_lbah, io_ports->lbah_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
- tx4939ide_outb(tf->feature, io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
- tx4939ide_outb(tf->nsect, io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
- tx4939ide_outb(tf->lbal, io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
- tx4939ide_outb(tf->lbam, io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
- tx4939ide_outb(tf->lbah, io_ports->lbah_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) {
- tx4939ide_outb((tf->device & HIHI) | drive->select,
- io_ports->device_addr);
+ if (valid & IDE_VALID_DEVICE)
tx4939ide_tf_load_fixup(drive);
- }
}
-static void tx4939ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &cmd->tf;
-
- /* be sure we're looking at the low order bits */
- tx4939ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
- tf->error = tx4939ide_inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
- tf->nsect = tx4939ide_inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
- tf->lbal = tx4939ide_inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
- tf->lbam = tx4939ide_inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
- tf->lbah = tx4939ide_inb(io_ports->lbah_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
- tf->device = tx4939ide_inb(io_ports->device_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- tx4939ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
-
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
- tf->hob_error = tx4939ide_inb(io_ports->feature_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr);
- }
-}
+#ifdef __BIG_ENDIAN
-static void tx4939ide_input_data_swap(ide_drive_t *drive, struct request *rq,
+/* custom iops (independent from SWAP_IO_SPACE) */
+static void tx4939ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long port = drive->hwif->io_ports.data_addr;
@@ -536,7 +458,7 @@ static void tx4939ide_input_data_swap(ide_drive_t *drive, struct request *rq,
__ide_flush_dcache_range((unsigned long)buf, roundup(len, 2));
}
-static void tx4939ide_output_data_swap(ide_drive_t *drive, struct request *rq,
+static void tx4939ide_output_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long port = drive->hwif->io_ports.data_addr;
@@ -558,7 +480,7 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
.dev_select = ide_dev_select,
.tf_load = tx4939ide_tf_load,
- .tf_read = tx4939ide_tf_read,
+ .tf_read = ide_tf_read,
.input_data = tx4939ide_input_data_swap,
.output_data = tx4939ide_output_data_swap,
@@ -566,14 +488,6 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
#else /* __LITTLE_ENDIAN */
-static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
-{
- ide_tf_load(drive, cmd);
-
- if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
- tx4939ide_tf_load_fixup(drive);
-}
-
static const struct ide_tp_ops tx4939ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
diff --git a/drivers/idle/i7300_idle.c b/drivers/idle/i7300_idle.c
index 17e8ddd0133..bf740394d70 100644
--- a/drivers/idle/i7300_idle.c
+++ b/drivers/idle/i7300_idle.c
@@ -178,7 +178,7 @@ static int __init i7300_idle_ioat_selftest(u8 *ctl,
static struct device dummy_dma_dev = {
.init_name = "fallback device",
- .coherent_dma_mask = DMA_64BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
.dma_mask = &dummy_dma_dev.coherent_dma_mask,
};
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
index 38f71203620..9555fd25386 100644
--- a/drivers/ieee1394/pcilynx.c
+++ b/drivers/ieee1394/pcilynx.c
@@ -1171,7 +1171,7 @@ static int __devinit add_card(struct pci_dev *dev,
error = -ENXIO;
- if (pci_set_dma_mask(dev, DMA_32BIT_MASK))
+ if (pci_set_dma_mask(dev, DMA_BIT_MASK(32)))
FAIL("DMA address limits not supported for PCILynx hardware");
if (pci_enable_device(dev))
FAIL("failed to enable PCILynx hardware");
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 2a2e50871b4..851de83ff45 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -297,21 +297,25 @@ static void cma_detach_from_dev(struct rdma_id_private *id_priv)
id_priv->cma_dev = NULL;
}
-static int cma_set_qkey(struct ib_device *device, u8 port_num,
- enum rdma_port_space ps,
- struct rdma_dev_addr *dev_addr, u32 *qkey)
+static int cma_set_qkey(struct rdma_id_private *id_priv)
{
struct ib_sa_mcmember_rec rec;
int ret = 0;
- switch (ps) {
+ if (id_priv->qkey)
+ return 0;
+
+ switch (id_priv->id.ps) {
case RDMA_PS_UDP:
- *qkey = RDMA_UDP_QKEY;
+ id_priv->qkey = RDMA_UDP_QKEY;
break;
case RDMA_PS_IPOIB:
- ib_addr_get_mgid(dev_addr, &rec.mgid);
- ret = ib_sa_get_mcmember_rec(device, port_num, &rec.mgid, &rec);
- *qkey = be32_to_cpu(rec.qkey);
+ ib_addr_get_mgid(&id_priv->id.route.addr.dev_addr, &rec.mgid);
+ ret = ib_sa_get_mcmember_rec(id_priv->id.device,
+ id_priv->id.port_num, &rec.mgid,
+ &rec);
+ if (!ret)
+ id_priv->qkey = be32_to_cpu(rec.qkey);
break;
default:
break;
@@ -341,12 +345,7 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv)
ret = ib_find_cached_gid(cma_dev->device, &gid,
&id_priv->id.port_num, NULL);
if (!ret) {
- ret = cma_set_qkey(cma_dev->device,
- id_priv->id.port_num,
- id_priv->id.ps, dev_addr,
- &id_priv->qkey);
- if (!ret)
- cma_attach_to_dev(id_priv, cma_dev);
+ cma_attach_to_dev(id_priv, cma_dev);
break;
}
}
@@ -578,6 +577,10 @@ static int cma_ib_init_qp_attr(struct rdma_id_private *id_priv,
*qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;
if (cma_is_ud_ps(id_priv->id.ps)) {
+ ret = cma_set_qkey(id_priv);
+ if (ret)
+ return ret;
+
qp_attr->qkey = id_priv->qkey;
*qp_attr_mask |= IB_QP_QKEY;
} else {
@@ -2201,6 +2204,12 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id,
event.status = ib_event->param.sidr_rep_rcvd.status;
break;
}
+ ret = cma_set_qkey(id_priv);
+ if (ret) {
+ event.event = RDMA_CM_EVENT_ADDR_ERROR;
+ event.status = -EINVAL;
+ break;
+ }
if (id_priv->qkey != rep->qkey) {
event.event = RDMA_CM_EVENT_UNREACHABLE;
event.status = -EINVAL;
@@ -2480,10 +2489,14 @@ static int cma_send_sidr_rep(struct rdma_id_private *id_priv,
const void *private_data, int private_data_len)
{
struct ib_cm_sidr_rep_param rep;
+ int ret;
memset(&rep, 0, sizeof rep);
rep.status = status;
if (status == IB_SIDR_SUCCESS) {
+ ret = cma_set_qkey(id_priv);
+ if (ret)
+ return ret;
rep.qp_num = id_priv->qp_num;
rep.qkey = id_priv->qkey;
}
@@ -2713,6 +2726,10 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv,
IB_SA_MCMEMBER_REC_FLOW_LABEL |
IB_SA_MCMEMBER_REC_TRAFFIC_CLASS;
+ if (id_priv->id.ps == RDMA_PS_IPOIB)
+ comp_mask |= IB_SA_MCMEMBER_REC_RATE |
+ IB_SA_MCMEMBER_REC_RATE_SELECTOR;
+
mc->multicast.ib = ib_sa_join_multicast(&sa_client, id_priv->id.device,
id_priv->id.port_num, &rec,
comp_mask, GFP_KERNEL,
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c
index 7d79aa361e2..0cfbb6d2f76 100644
--- a/drivers/infiniband/hw/amso1100/c2.c
+++ b/drivers/infiniband/hw/amso1100/c2.c
@@ -989,13 +989,13 @@ static int __devinit c2_probe(struct pci_dev *pcidev,
}
if ((sizeof(dma_addr_t) > 4)) {
- ret = pci_set_dma_mask(pcidev, DMA_64BIT_MASK);
+ ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64));
if (ret < 0) {
printk(KERN_ERR PFX "64b DMA configuration failed\n");
goto bail2;
}
} else {
- ret = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
+ ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32));
if (ret < 0) {
printk(KERN_ERR PFX "32b DMA configuration failed\n");
goto bail2;
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index a4a82bff710..8d71086f5a1 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -152,7 +152,7 @@ static int cxio_hal_clear_qp_ctx(struct cxio_rdev *rdev_p, u32 qpid)
sge_cmd = qpid << 8 | 3;
wqe->sge_cmd = cpu_to_be64(sge_cmd);
skb->priority = CPL_PRIORITY_CONTROL;
- return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+ return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
}
int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
@@ -571,7 +571,7 @@ static int cxio_hal_init_ctrl_qp(struct cxio_rdev *rdev_p)
(unsigned long long) rdev_p->ctrl_qp.dma_addr,
rdev_p->ctrl_qp.workq, 1 << T3_CTRL_QP_SIZE_LOG2);
skb->priority = CPL_PRIORITY_CONTROL;
- return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+ return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
err:
kfree_skb(skb);
return err;
@@ -701,7 +701,7 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry,
u32 stag_idx;
u32 wptr;
- if (rdev_p->flags)
+ if (cxio_fatal_error(rdev_p))
return -EIO;
stag_state = stag_state > 0;
@@ -858,7 +858,7 @@ int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr)
wqe->qp_dma_size = cpu_to_be32(attr->qp_dma_size);
wqe->irs = cpu_to_be32(attr->irs);
skb->priority = 0; /* 0=>ToeQ; 1=>CtrlQ */
- return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+ return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
}
void cxio_register_ev_cb(cxio_hal_ev_callback_func_t ev_cb)
@@ -1041,9 +1041,9 @@ void cxio_rdev_close(struct cxio_rdev *rdev_p)
cxio_hal_pblpool_destroy(rdev_p);
cxio_hal_rqtpool_destroy(rdev_p);
list_del(&rdev_p->entry);
- rdev_p->t3cdev_p->ulp = NULL;
cxio_hal_destroy_ctrl_qp(rdev_p);
cxio_hal_destroy_resource(rdev_p->rscp);
+ rdev_p->t3cdev_p->ulp = NULL;
}
}
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h
index 094a66d1480..bfd03bf8be5 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h
@@ -115,6 +115,11 @@ struct cxio_rdev {
#define CXIO_ERROR_FATAL 1
};
+static inline int cxio_fatal_error(struct cxio_rdev *rdev_p)
+{
+ return rdev_p->flags & CXIO_ERROR_FATAL;
+}
+
static inline int cxio_num_stags(struct cxio_rdev *rdev_p)
{
return min((int)T3_MAX_NUM_STAG, (int)((rdev_p->rnic_info.tpt_top - rdev_p->rnic_info.tpt_base) >> 5));
@@ -188,6 +193,7 @@ void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
void cxio_flush_hw_cq(struct t3_cq *cq);
int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
u8 *cqe_flushed, u64 *cookie, u32 *credit);
+int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb);
#define MOD "iw_cxgb3: "
#define PDBG(fmt, args...) pr_debug(MOD fmt, ## args)
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c
index 37a4fc264a0..26fc0a4eaa7 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.c
+++ b/drivers/infiniband/hw/cxgb3/iwch.c
@@ -165,12 +165,19 @@ static void close_rnic_dev(struct t3cdev *tdev)
static void iwch_err_handler(struct t3cdev *tdev, u32 status, u32 error)
{
struct cxio_rdev *rdev = tdev->ulp;
+ struct iwch_dev *rnicp = rdev_to_iwch_dev(rdev);
+ struct ib_event event;
- if (status == OFFLOAD_STATUS_DOWN)
+ if (status == OFFLOAD_STATUS_DOWN) {
rdev->flags = CXIO_ERROR_FATAL;
- return;
+ event.device = &rnicp->ibdev;
+ event.event = IB_EVENT_DEVICE_FATAL;
+ event.element.port_num = 0;
+ ib_dispatch_event(&event);
+ }
+ return;
}
static int __init iwch_init_module(void)
diff --git a/drivers/infiniband/hw/cxgb3/iwch.h b/drivers/infiniband/hw/cxgb3/iwch.h
index 3773453b2cf..84735506333 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.h
+++ b/drivers/infiniband/hw/cxgb3/iwch.h
@@ -117,6 +117,11 @@ static inline struct iwch_dev *to_iwch_dev(struct ib_device *ibdev)
return container_of(ibdev, struct iwch_dev, ibdev);
}
+static inline struct iwch_dev *rdev_to_iwch_dev(struct cxio_rdev *rdev)
+{
+ return container_of(rdev, struct iwch_dev, rdev);
+}
+
static inline int t3b_device(const struct iwch_dev *rhp)
{
return rhp->rdev.t3cdev_p->type == T3B;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 8699947aaf6..fef3f1ae722 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -139,6 +139,38 @@ static void stop_ep_timer(struct iwch_ep *ep)
put_ep(&ep->com);
}
+int iwch_l2t_send(struct t3cdev *tdev, struct sk_buff *skb, struct l2t_entry *l2e)
+{
+ int error = 0;
+ struct cxio_rdev *rdev;
+
+ rdev = (struct cxio_rdev *)tdev->ulp;
+ if (cxio_fatal_error(rdev)) {
+ kfree_skb(skb);
+ return -EIO;
+ }
+ error = l2t_send(tdev, skb, l2e);
+ if (error)
+ kfree_skb(skb);
+ return error;
+}
+
+int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb)
+{
+ int error = 0;
+ struct cxio_rdev *rdev;
+
+ rdev = (struct cxio_rdev *)tdev->ulp;
+ if (cxio_fatal_error(rdev)) {
+ kfree_skb(skb);
+ return -EIO;
+ }
+ error = cxgb3_ofld_send(tdev, skb);
+ if (error)
+ kfree_skb(skb);
+ return error;
+}
+
static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb)
{
struct cpl_tid_release *req;
@@ -150,7 +182,7 @@ static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb)
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid));
skb->priority = CPL_PRIORITY_SETUP;
- cxgb3_ofld_send(tdev, skb);
+ iwch_cxgb3_ofld_send(tdev, skb);
return;
}
@@ -172,8 +204,7 @@ int iwch_quiesce_tid(struct iwch_ep *ep)
req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE);
skb->priority = CPL_PRIORITY_DATA;
- cxgb3_ofld_send(ep->com.tdev, skb);
- return 0;
+ return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
}
int iwch_resume_tid(struct iwch_ep *ep)
@@ -194,8 +225,7 @@ int iwch_resume_tid(struct iwch_ep *ep)
req->val = 0;
skb->priority = CPL_PRIORITY_DATA;
- cxgb3_ofld_send(ep->com.tdev, skb);
- return 0;
+ return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
}
static void set_emss(struct iwch_ep *ep, u16 opt)
@@ -252,18 +282,22 @@ static void *alloc_ep(int size, gfp_t gfp)
void __free_ep(struct kref *kref)
{
- struct iwch_ep_common *epc;
- epc = container_of(kref, struct iwch_ep_common, kref);
- PDBG("%s ep %p state %s\n", __func__, epc, states[state_read(epc)]);
- kfree(epc);
+ struct iwch_ep *ep;
+ ep = container_of(container_of(kref, struct iwch_ep_common, kref),
+ struct iwch_ep, com);
+ PDBG("%s ep %p state %s\n", __func__, ep, states[state_read(&ep->com)]);
+ if (ep->com.flags & RELEASE_RESOURCES) {
+ cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid);
+ dst_release(ep->dst);
+ l2t_release(L2DATA(ep->com.tdev), ep->l2t);
+ }
+ kfree(ep);
}
static void release_ep_resources(struct iwch_ep *ep)
{
PDBG("%s ep %p tid %d\n", __func__, ep, ep->hwtid);
- cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid);
- dst_release(ep->dst);
- l2t_release(L2DATA(ep->com.tdev), ep->l2t);
+ ep->com.flags |= RELEASE_RESOURCES;
put_ep(&ep->com);
}
@@ -382,7 +416,7 @@ static void abort_arp_failure(struct t3cdev *dev, struct sk_buff *skb)
PDBG("%s t3cdev %p\n", __func__, dev);
req->cmd = CPL_ABORT_NO_RST;
- cxgb3_ofld_send(dev, skb);
+ iwch_cxgb3_ofld_send(dev, skb);
}
static int send_halfclose(struct iwch_ep *ep, gfp_t gfp)
@@ -402,8 +436,7 @@ static int send_halfclose(struct iwch_ep *ep, gfp_t gfp)
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON));
req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, ep->hwtid));
- l2t_send(ep->com.tdev, skb, ep->l2t);
- return 0;
+ return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
}
static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp)
@@ -424,8 +457,7 @@ static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp)
req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, ep->hwtid));
req->cmd = CPL_ABORT_SEND_RST;
- l2t_send(ep->com.tdev, skb, ep->l2t);
- return 0;
+ return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
}
static int send_connect(struct iwch_ep *ep)
@@ -469,8 +501,7 @@ static int send_connect(struct iwch_ep *ep)
req->opt0l = htonl(opt0l);
req->params = 0;
req->opt2 = htonl(opt2);
- l2t_send(ep->com.tdev, skb, ep->l2t);
- return 0;
+ return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
}
static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb)
@@ -527,7 +558,7 @@ static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb)
req->sndseq = htonl(ep->snd_seq);
BUG_ON(ep->mpa_skb);
ep->mpa_skb = skb;
- l2t_send(ep->com.tdev, skb, ep->l2t);
+ iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
start_ep_timer(ep);
state_set(&ep->com, MPA_REQ_SENT);
return;
@@ -578,8 +609,7 @@ static int send_mpa_reject(struct iwch_ep *ep, const void *pdata, u8 plen)
req->sndseq = htonl(ep->snd_seq);
BUG_ON(ep->mpa_skb);
ep->mpa_skb = skb;
- l2t_send(ep->com.tdev, skb, ep->l2t);
- return 0;
+ return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
}
static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen)
@@ -630,8 +660,7 @@ static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen)
req->sndseq = htonl(ep->snd_seq);
ep->mpa_skb = skb;
state_set(&ep->com, MPA_REP_SENT);
- l2t_send(ep->com.tdev, skb, ep->l2t);
- return 0;
+ return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
}
static int act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
@@ -795,7 +824,7 @@ static int update_rx_credits(struct iwch_ep *ep, u32 credits)
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid));
req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1));
skb->priority = CPL_PRIORITY_ACK;
- cxgb3_ofld_send(ep->com.tdev, skb);
+ iwch_cxgb3_ofld_send(ep->com.tdev, skb);
return credits;
}
@@ -1127,8 +1156,8 @@ static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
* We get 2 abort replies from the HW. The first one must
* be ignored except for scribbling that we need one more.
*/
- if (!(ep->flags & ABORT_REQ_IN_PROGRESS)) {
- ep->flags |= ABORT_REQ_IN_PROGRESS;
+ if (!(ep->com.flags & ABORT_REQ_IN_PROGRESS)) {
+ ep->com.flags |= ABORT_REQ_IN_PROGRESS;
return CPL_RET_BUF_DONE;
}
@@ -1203,8 +1232,7 @@ static int listen_start(struct iwch_listen_ep *ep)
req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK));
skb->priority = 1;
- cxgb3_ofld_send(ep->com.tdev, skb);
- return 0;
+ return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
}
static int pass_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
@@ -1237,8 +1265,7 @@ static int listen_stop(struct iwch_listen_ep *ep)
req->cpu_idx = 0;
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid));
skb->priority = 1;
- cxgb3_ofld_send(ep->com.tdev, skb);
- return 0;
+ return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
}
static int close_listsrv_rpl(struct t3cdev *tdev, struct sk_buff *skb,
@@ -1286,7 +1313,7 @@ static void accept_cr(struct iwch_ep *ep, __be32 peer_ip, struct sk_buff *skb)
rpl->opt2 = htonl(opt2);
rpl->rsvd = rpl->opt2; /* workaround for HW bug */
skb->priority = CPL_PRIORITY_SETUP;
- l2t_send(ep->com.tdev, skb, ep->l2t);
+ iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
return;
}
@@ -1315,7 +1342,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip,
rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT);
rpl->opt2 = 0;
rpl->rsvd = rpl->opt2;
- cxgb3_ofld_send(tdev, skb);
+ iwch_cxgb3_ofld_send(tdev, skb);
}
}
@@ -1534,8 +1561,8 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
* We get 2 peer aborts from the HW. The first one must
* be ignored except for scribbling that we need one more.
*/
- if (!(ep->flags & PEER_ABORT_IN_PROGRESS)) {
- ep->flags |= PEER_ABORT_IN_PROGRESS;
+ if (!(ep->com.flags & PEER_ABORT_IN_PROGRESS)) {
+ ep->com.flags |= PEER_ABORT_IN_PROGRESS;
return CPL_RET_BUF_DONE;
}
@@ -1613,7 +1640,7 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid));
rpl->cmd = CPL_ABORT_NO_RST;
- cxgb3_ofld_send(ep->com.tdev, rpl_skb);
+ iwch_cxgb3_ofld_send(ep->com.tdev, rpl_skb);
out:
if (release)
release_ep_resources(ep);
@@ -2017,8 +2044,11 @@ int iwch_destroy_listen(struct iw_cm_id *cm_id)
ep->com.rpl_done = 0;
ep->com.rpl_err = 0;
err = listen_stop(ep);
+ if (err)
+ goto done;
wait_event(ep->com.waitq, ep->com.rpl_done);
cxgb3_free_stid(ep->com.tdev, ep->stid);
+done:
err = ep->com.rpl_err;
cm_id->rem_ref(cm_id);
put_ep(&ep->com);
@@ -2030,12 +2060,22 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp)
int ret=0;
unsigned long flags;
int close = 0;
+ int fatal = 0;
+ struct t3cdev *tdev;
+ struct cxio_rdev *rdev;
spin_lock_irqsave(&ep->com.lock, flags);
PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep,
states[ep->com.state], abrupt);
+ tdev = (struct t3cdev *)ep->com.tdev;
+ rdev = (struct cxio_rdev *)tdev->ulp;
+ if (cxio_fatal_error(rdev)) {
+ fatal = 1;
+ close_complete_upcall(ep);
+ ep->com.state = DEAD;
+ }
switch (ep->com.state) {
case MPA_REQ_WAIT:
case MPA_REQ_SENT:
@@ -2075,7 +2115,11 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp)
ret = send_abort(ep, NULL, gfp);
else
ret = send_halfclose(ep, gfp);
+ if (ret)
+ fatal = 1;
}
+ if (fatal)
+ release_ep_resources(ep);
return ret;
}
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.h b/drivers/infiniband/hw/cxgb3/iwch_cm.h
index d7c7e09f099..43c0aea7ead 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.h
@@ -147,6 +147,7 @@ enum iwch_ep_state {
enum iwch_ep_flags {
PEER_ABORT_IN_PROGRESS = (1 << 0),
ABORT_REQ_IN_PROGRESS = (1 << 1),
+ RELEASE_RESOURCES = (1 << 2),
};
struct iwch_ep_common {
@@ -161,6 +162,7 @@ struct iwch_ep_common {
wait_queue_head_t waitq;
int rpl_done;
int rpl_err;
+ u32 flags;
};
struct iwch_listen_ep {
@@ -188,7 +190,6 @@ struct iwch_ep {
u16 plen;
u32 ird;
u32 ord;
- u32 flags;
};
static inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id)
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index c758fbd5847..2f546a62533 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -751,7 +751,7 @@ int iwch_post_zb_read(struct iwch_qp *qhp)
wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)|
V_FW_RIWR_LEN(flit_cnt));
skb->priority = CPL_PRIORITY_DATA;
- return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
+ return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
}
/*
@@ -783,7 +783,7 @@ int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg)
V_FW_RIWR_FLAGS(T3_COMPLETION_FLAG | T3_NOTIFY_FLAG));
wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid));
skb->priority = CPL_PRIORITY_DATA;
- return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
+ return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
}
/*
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index cb9daa6ac02..04e88b60055 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -470,14 +470,14 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
goto bail_disable;
}
- ret = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (ret) {
/*
* if the 64 bit setup fails, try 32 bit. Some systems
* do not setup 64 bit maps on systems with 2GB or less
* memory installed.
*/
- ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (ret) {
dev_info(&pdev->dev,
"Unable to set DMA mask for unit %u: %d\n",
@@ -486,7 +486,7 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
}
else {
ipath_dbg("No 64bit DMA mask, used 32 bit mask\n");
- ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (ret)
dev_info(&pdev->dev,
"Unable to set DMA consistent mask "
@@ -496,7 +496,7 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
}
}
else {
- ret = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (ret)
dev_info(&pdev->dev,
"Unable to set DMA consistent mask "
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 2ccb9d31771..ae3d7590346 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -394,8 +394,7 @@ static int mlx4_ib_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
PAGE_SIZE, vma->vm_page_prot))
return -EAGAIN;
} else if (vma->vm_pgoff == 1 && dev->dev->caps.bf_reg_size != 0) {
- /* FIXME want pgprot_writecombine() for BlueFlame pages */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
if (io_remap_pfn_range(vma, vma->vm_start,
to_mucontext(context)->uar.pfn +
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 52f60f4eea0..1d83cf7caf3 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -1016,20 +1016,20 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type)
pci_set_master(pdev);
- err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (err) {
dev_warn(&pdev->dev, "Warning: couldn't set 64-bit PCI DMA mask.\n");
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "Can't set PCI DMA mask, aborting.\n");
goto err_free_res;
}
}
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (err) {
dev_warn(&pdev->dev, "Warning: couldn't set 64-bit "
"consistent PCI DMA mask.\n");
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "Can't set consistent PCI DMA mask, "
"aborting.\n");
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index ca599767ffb..cbde0cfe27e 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -478,23 +478,23 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i
}
if ((sizeof(dma_addr_t) > 4)) {
- ret = pci_set_dma_mask(pcidev, DMA_64BIT_MASK);
+ ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64));
if (ret < 0) {
printk(KERN_ERR PFX "64b DMA mask configuration failed\n");
goto bail2;
}
- ret = pci_set_consistent_dma_mask(pcidev, DMA_64BIT_MASK);
+ ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64));
if (ret) {
printk(KERN_ERR PFX "64b DMA consistent mask configuration failed\n");
goto bail2;
}
} else {
- ret = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
+ ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32));
if (ret < 0) {
printk(KERN_ERR PFX "32b DMA mask configuration failed\n");
goto bail2;
}
- ret = pci_set_consistent_dma_mask(pcidev, DMA_32BIT_MASK);
+ ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32));
if (ret) {
printk(KERN_ERR PFX "32b DMA consistent mask configuration failed\n");
goto bail2;
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
index 04b12ad2339..17621de54a9 100644
--- a/drivers/infiniband/hw/nes/nes.h
+++ b/drivers/infiniband/hw/nes/nes.h
@@ -289,8 +289,8 @@ static inline __le32 get_crc_value(struct nes_v4_quad *nes_quad)
static inline void
set_wqe_64bit_value(__le32 *wqe_words, u32 index, u64 value)
{
- wqe_words[index] = cpu_to_le32((u32) ((unsigned long)value));
- wqe_words[index + 1] = cpu_to_le32((u32)(upper_32_bits((unsigned long)value)));
+ wqe_words[index] = cpu_to_le32((u32) value);
+ wqe_words[index + 1] = cpu_to_le32(upper_32_bits(value));
}
static inline void
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 52425154acd..dbd9a75474e 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -426,6 +426,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
if (type == NES_TIMER_TYPE_CLOSE) {
new_send->timetosend += (HZ/10);
if (cm_node->recv_entry) {
+ kfree(new_send);
WARN_ON(1);
return -EINVAL;
}
@@ -445,8 +446,8 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
if (ret != NETDEV_TX_OK) {
nes_debug(NES_DBG_CM, "Error sending packet %p "
"(jiffies = %lu)\n", new_send, jiffies);
- atomic_dec(&new_send->skb->users);
new_send->timetosend = jiffies;
+ ret = NETDEV_TX_OK;
} else {
cm_packets_sent++;
if (!send_retrans) {
@@ -630,7 +631,6 @@ static void nes_cm_timer_tick(unsigned long pass)
nes_debug(NES_DBG_CM, "rexmit failed for "
"node=%p\n", cm_node);
cm_packets_bounced++;
- atomic_dec(&send_entry->skb->users);
send_entry->retrycount--;
nexttimeout = jiffies + NES_SHORT_TIME;
settimer = 1;
@@ -666,11 +666,6 @@ static void nes_cm_timer_tick(unsigned long pass)
spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
rem_ref_cm_node(cm_node->cm_core, cm_node);
- if (ret != NETDEV_TX_OK) {
- nes_debug(NES_DBG_CM, "rexmit failed for cm_node=%p\n",
- cm_node);
- break;
- }
}
if (settimer) {
@@ -1262,7 +1257,6 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
cm_node->nesqp = NULL;
}
- cm_node->freed = 1;
kfree(cm_node);
return 0;
}
@@ -1999,13 +1993,17 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
if (loopbackremotelistener == NULL) {
create_event(cm_node, NES_CM_EVENT_ABORTED);
} else {
- atomic_inc(&cm_loopbacks);
loopback_cm_info = *cm_info;
loopback_cm_info.loc_port = cm_info->rem_port;
loopback_cm_info.rem_port = cm_info->loc_port;
loopback_cm_info.cm_id = loopbackremotelistener->cm_id;
loopbackremotenode = make_cm_node(cm_core, nesvnic,
&loopback_cm_info, loopbackremotelistener);
+ if (!loopbackremotenode) {
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
+ return NULL;
+ }
+ atomic_inc(&cm_loopbacks);
loopbackremotenode->loopbackpartner = cm_node;
loopbackremotenode->tcp_cntxt.rcv_wscale =
NES_CM_DEFAULT_RCV_WND_SCALE;
@@ -2690,6 +2688,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
struct ib_mr *ibmr = NULL;
struct ib_phys_buf ibphysbuf;
struct nes_pd *nespd;
+ u64 tagged_offset;
@@ -2755,10 +2754,11 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
ibphysbuf.addr = nesqp->ietf_frame_pbase;
ibphysbuf.size = conn_param->private_data_len +
sizeof(struct ietf_mpa_frame);
+ tagged_offset = (u64)(unsigned long)nesqp->ietf_frame;
ibmr = nesibdev->ibdev.reg_phys_mr((struct ib_pd *)nespd,
&ibphysbuf, 1,
IB_ACCESS_LOCAL_WRITE,
- (u64 *)&nesqp->ietf_frame);
+ &tagged_offset);
if (!ibmr) {
nes_debug(NES_DBG_CM, "Unable to register memory region"
"for lSMM for cm_node = %p \n",
@@ -2782,7 +2782,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
sizeof(struct ietf_mpa_frame));
set_wqe_64bit_value(wqe->wqe_words,
NES_IWARP_SQ_WQE_FRAG0_LOW_IDX,
- (u64)nesqp->ietf_frame);
+ (u64)(unsigned long)nesqp->ietf_frame);
wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] =
cpu_to_le32(conn_param->private_data_len +
sizeof(struct ietf_mpa_frame));
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h
index d5f778202eb..80bba189257 100644
--- a/drivers/infiniband/hw/nes/nes_cm.h
+++ b/drivers/infiniband/hw/nes/nes_cm.h
@@ -298,7 +298,6 @@ struct nes_cm_node {
struct nes_vnic *nesvnic;
int apbvt_set;
int accept_pend;
- int freed;
struct list_head timer_entry;
struct list_head reset_entry;
struct nes_qp *nesqp;
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 52e734042b8..d6fc9ae4406 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -46,6 +46,10 @@ static unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR;
module_param(nes_lro_max_aggr, uint, 0444);
MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation");
+static int wide_ppm_offset;
+module_param(wide_ppm_offset, int, 0644);
+MODULE_PARM_DESC(wide_ppm_offset, "Increase CX4 interface clock ppm offset, 0=100ppm (default), 1=300ppm");
+
static u32 crit_err_count;
u32 int_mod_timer_init;
u32 int_mod_cq_depth_256;
@@ -546,8 +550,11 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
msleep(1);
}
if (int_cnt > 1) {
+ u32 sds;
spin_lock_irqsave(&nesadapter->phy_lock, flags);
- nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088);
+ sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
+ sds |= 0x00000040;
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds);
mh_detected++;
reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET);
reset_value |= 0x0000003d;
@@ -736,39 +743,49 @@ static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count,
{
int i;
u32 u32temp;
- u32 serdes_common_control;
+ u32 sds;
if (hw_rev != NE020_REV) {
/* init serdes 0 */
+ if (wide_ppm_offset && (nesadapter->phy_type[0] == NES_PHY_TYPE_CX4))
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000FFFAA);
+ else
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
- nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
- serdes_common_control = nes_read_indexed(nesdev,
- NES_IDX_ETH_SERDES_COMMON_CONTROL0);
- serdes_common_control |= 0x000000100;
- nes_write_indexed(nesdev,
- NES_IDX_ETH_SERDES_COMMON_CONTROL0,
- serdes_common_control);
- } else if (!OneG_Mode) {
- nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000);
+ sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0);
+ sds |= 0x00000100;
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds);
}
- if (((port_count > 1) &&
- (nesadapter->phy_type[0] != NES_PHY_TYPE_PUMA_1G)) ||
- ((port_count > 2) &&
- (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G))) {
- /* init serdes 1 */
- nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF);
- if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
- serdes_common_control = nes_read_indexed(nesdev,
- NES_IDX_ETH_SERDES_COMMON_CONTROL1);
- serdes_common_control |= 0x000000100;
- nes_write_indexed(nesdev,
- NES_IDX_ETH_SERDES_COMMON_CONTROL1,
- serdes_common_control);
- } else if (!OneG_Mode) {
- nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000);
- }
+ if (!OneG_Mode)
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000);
+
+ if (port_count < 2)
+ return 0;
+
+ /* init serdes 1 */
+ switch (nesadapter->phy_type[1]) {
+ case NES_PHY_TYPE_ARGUS:
+ case NES_PHY_TYPE_SFP_D:
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP0, 0x00000000);
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP1, 0x00000000);
+ break;
+ case NES_PHY_TYPE_CX4:
+ sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
+ sds &= 0xFFFFFFBF;
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds);
+ if (wide_ppm_offset)
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000FFFAA);
+ else
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF);
+ break;
+ case NES_PHY_TYPE_PUMA_1G:
+ sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
+ sds |= 0x000000100;
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds);
}
+ if (!OneG_Mode)
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000);
} else {
/* init serdes 0 */
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, 0x00000008);
@@ -1259,203 +1276,162 @@ int nes_init_phy(struct nes_device *nesdev)
{
struct nes_adapter *nesadapter = nesdev->nesadapter;
u32 counter = 0;
- u32 sds_common_control0;
+ u32 sds;
u32 mac_index = nesdev->mac_index;
u32 tx_config = 0;
u16 phy_data;
u32 temp_phy_data = 0;
u32 temp_phy_data2 = 0;
- u32 i = 0;
+ u8 phy_type = nesadapter->phy_type[mac_index];
+ u8 phy_index = nesadapter->phy_index[mac_index];
if ((nesadapter->OneG_Mode) &&
- (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
+ (phy_type != NES_PHY_TYPE_PUMA_1G)) {
nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index);
- if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) {
- printk(PFX "%s: Programming mdc config for 1G\n", __func__);
+ if (phy_type == NES_PHY_TYPE_1G) {
tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
tx_config &= 0xFFFFFFE3;
tx_config |= 0x04;
nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
}
- nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data);
- nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n",
- nesadapter->phy_index[mac_index], phy_data);
- nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000);
+ nes_read_1G_phy_reg(nesdev, 1, phy_index, &phy_data);
+ nes_write_1G_phy_reg(nesdev, 23, phy_index, 0xb000);
/* Reset the PHY */
- nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000);
+ nes_write_1G_phy_reg(nesdev, 0, phy_index, 0x8000);
udelay(100);
counter = 0;
do {
- nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
- nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data);
- if (counter++ > 100) break;
+ nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
+ if (counter++ > 100)
+ break;
} while (phy_data & 0x8000);
/* Setting no phy loopback */
phy_data &= 0xbfff;
phy_data |= 0x1140;
- nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data);
- nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
- nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data);
-
- nes_read_1G_phy_reg(nesdev, 0x17, nesadapter->phy_index[mac_index], &phy_data);
- nes_debug(NES_DBG_PHY, "Phy data from register 0x17 = 0x%X.\n", phy_data);
-
- nes_read_1G_phy_reg(nesdev, 0x1e, nesadapter->phy_index[mac_index], &phy_data);
- nes_debug(NES_DBG_PHY, "Phy data from register 0x1e = 0x%X.\n", phy_data);
+ nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data);
+ nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
+ nes_read_1G_phy_reg(nesdev, 0x17, phy_index, &phy_data);
+ nes_read_1G_phy_reg(nesdev, 0x1e, phy_index, &phy_data);
/* Setting the interrupt mask */
- nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data);
- nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data);
- nes_write_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], 0xffee);
-
- nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data);
- nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data);
+ nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data);
+ nes_write_1G_phy_reg(nesdev, 0x19, phy_index, 0xffee);
+ nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data);
/* turning on flow control */
- nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data);
- nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data);
- nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index],
- (phy_data & ~(0x03E0)) | 0xc00);
- /* nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index],
- phy_data | 0xc00); */
- nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data);
- nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data);
-
- nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data);
- nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data);
- /* Clear Half duplex */
- nes_write_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index],
- phy_data & ~(0x0100));
- nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data);
- nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data);
-
- nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
- nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300);
- } else {
- if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) ||
- (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
- /* setup 10G MDIO operation */
- tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
- tx_config &= 0xFFFFFFE3;
- tx_config |= 0x15;
- nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
- }
- if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
- nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
+ nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data);
+ nes_write_1G_phy_reg(nesdev, 4, phy_index, (phy_data & ~(0x03E0)) | 0xc00);
+ nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data);
- temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
- mdelay(10);
- nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
- temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+ /* Clear Half duplex */
+ nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data);
+ nes_write_1G_phy_reg(nesdev, 9, phy_index, phy_data & ~(0x0100));
+ nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data);
- /*
- * if firmware is already running (like from a
- * driver un-load/load, don't do anything.
- */
- if (temp_phy_data == temp_phy_data2) {
- /* configure QT2505 AMCC PHY */
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0x0000, 0x8000);
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0000);
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc302, 0x0044);
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc318, 0x0052);
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc319, 0x0008);
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc31a, 0x0098);
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0026, 0x0E00);
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0001);
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0028, 0xA528);
+ nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
+ nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data | 0x0300);
- /*
- * remove micro from reset; chip boots from ROM,
- * uploads EEPROM f/w image, uC executes f/w
- */
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0002);
+ return 0;
+ }
- /*
- * wait for heart beat to start to
- * know loading is done
- */
- counter = 0;
- do {
- nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
- temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
- if (counter++ > 1000) {
- nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from heartbeat check <this is bad!!!> \n");
- break;
- }
- mdelay(100);
- nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
- temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
- } while ((temp_phy_data2 == temp_phy_data));
+ if ((phy_type == NES_PHY_TYPE_IRIS) ||
+ (phy_type == NES_PHY_TYPE_ARGUS) ||
+ (phy_type == NES_PHY_TYPE_SFP_D)) {
+ /* setup 10G MDIO operation */
+ tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
+ tx_config &= 0xFFFFFFE3;
+ tx_config |= 0x15;
+ nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
+ }
+ if ((phy_type == NES_PHY_TYPE_ARGUS) ||
+ (phy_type == NES_PHY_TYPE_SFP_D)) {
+ /* Check firmware heartbeat */
+ nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
+ temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+ udelay(1500);
+ nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
+ temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+
+ if (temp_phy_data != temp_phy_data2)
+ return 0;
- /*
- * wait for tracking to start to know
- * f/w is good to go
- */
- counter = 0;
- do {
- nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7fd);
- temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
- if (counter++ > 1000) {
- nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from status check <this is bad!!!> \n");
- break;
- }
- mdelay(1000);
- /*
- * nes_debug(NES_DBG_PHY, "AMCC PHY- phy_status not ready yet = 0x%02X\n",
- * temp_phy_data);
- */
- } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70));
-
- /* set LOS Control invert RXLOSB_I_PADINV */
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd003, 0x0000);
- /* set LOS Control to mask of RXLOSB_I */
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc314, 0x0042);
- /* set LED1 to input mode (LED1 and LED2 share same LED) */
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd006, 0x0007);
- /* set LED2 to RX link_status and activity */
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd007, 0x000A);
- /* set LED3 to RX link_status */
- nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd008, 0x0009);
+ /* no heartbeat, configure the PHY */
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0000);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052);
+ if (phy_type == NES_PHY_TYPE_ARGUS) {
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x000C);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0008);
+ } else {
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x0004);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0038);
+ }
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0098);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0001);
- /*
- * reset the res-calibration on t2
- * serdes; ensures it is stable after
- * the amcc phy is stable
- */
+ /* setup LEDs */
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x0007);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x000A);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0009);
- sds_common_control0 = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0);
- sds_common_control0 |= 0x1;
- nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0028, 0xA528);
- /* release the res-calibration reset */
- sds_common_control0 &= 0xfffffffe;
- nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
+ /* Bring PHY out of reset */
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0002);
- i = 0;
- while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040)
- && (i++ < 5000)) {
- /* mdelay(1); */
- }
+ /* Check for heartbeat */
+ counter = 0;
+ mdelay(690);
+ nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
+ temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+ do {
+ if (counter++ > 150) {
+ nes_debug(NES_DBG_PHY, "No PHY heartbeat\n");
+ break;
+ }
+ mdelay(1);
+ nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
+ temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+ } while ((temp_phy_data2 == temp_phy_data));
- /*
- * wait for link train done before moving on,
- * or will get an interupt storm
- */
- counter = 0;
- do {
- temp_phy_data = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
- (0x200 * (nesdev->mac_index & 1)));
- if (counter++ > 1000) {
- nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from link train wait <this is bad, link didnt train!!!>\n");
- break;
- }
- mdelay(1);
- } while (((temp_phy_data & 0x0f1f0000) != 0x0f0f0000));
+ /* wait for tracking */
+ counter = 0;
+ do {
+ nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd);
+ temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+ if (counter++ > 300) {
+ nes_debug(NES_DBG_PHY, "PHY did not track\n");
+ break;
}
- }
+ mdelay(10);
+ } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70));
+
+ /* setup signal integrity */
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00D, 0x00FE);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00E, 0x0032);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00F, 0x0002);
+ nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc314, 0x0063);
+
+ /* reset serdes */
+ sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 +
+ mac_index * 0x200);
+ sds |= 0x1;
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 +
+ mac_index * 0x200, sds);
+ sds &= 0xfffffffe;
+ nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 +
+ mac_index * 0x200, sds);
+
+ counter = 0;
+ while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040)
+ && (counter++ < 5000))
+ ;
}
return 0;
}
@@ -2359,6 +2335,7 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
u16 temp_phy_data;
u32 pcs_val = 0x0f0f0000;
u32 pcs_mask = 0x0f1f0000;
+ u32 cdr_ctrl;
spin_lock_irqsave(&nesadapter->phy_lock, flags);
if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) {
@@ -2473,6 +2450,7 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
break;
case NES_PHY_TYPE_ARGUS:
+ case NES_PHY_TYPE_SFP_D:
/* clear the alarms */
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008);
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001);
@@ -2483,19 +2461,18 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9004);
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005);
/* check link status */
- nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
+ nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003);
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
- u32temp = 100;
- do {
- nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
- phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
- if ((phy_data == temp_phy_data) || (!(--u32temp)))
- break;
- temp_phy_data = phy_data;
- } while (1);
+ nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021);
+ nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+ nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021);
+ phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+
+ phy_data = (!temp_phy_data && (phy_data == 0x8000)) ? 0x4 : 0x0;
+
nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
- __func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP");
+ __func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP");
break;
case NES_PHY_TYPE_PUMA_1G:
@@ -2511,6 +2488,17 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
}
if (phy_data & 0x0004) {
+ if (wide_ppm_offset &&
+ (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_CX4) &&
+ (nesadapter->hw_rev != NE020_REV)) {
+ cdr_ctrl = nes_read_indexed(nesdev,
+ NES_IDX_ETH_SERDES_CDR_CONTROL0 +
+ mac_index * 0x200);
+ nes_write_indexed(nesdev,
+ NES_IDX_ETH_SERDES_CDR_CONTROL0 +
+ mac_index * 0x200,
+ cdr_ctrl | 0x000F0000);
+ }
nesadapter->mac_link_down[mac_index] = 0;
list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n",
@@ -2525,6 +2513,17 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
}
}
} else {
+ if (wide_ppm_offset &&
+ (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_CX4) &&
+ (nesadapter->hw_rev != NE020_REV)) {
+ cdr_ctrl = nes_read_indexed(nesdev,
+ NES_IDX_ETH_SERDES_CDR_CONTROL0 +
+ mac_index * 0x200);
+ nes_write_indexed(nesdev,
+ NES_IDX_ETH_SERDES_CDR_CONTROL0 +
+ mac_index * 0x200,
+ cdr_ctrl & 0xFFF0FFFF);
+ }
nesadapter->mac_link_down[mac_index] = 1;
list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n",
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index f41a8710d2a..c3654c6383f 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -35,12 +35,14 @@
#include <linux/inet_lro.h>
+#define NES_PHY_TYPE_CX4 1
#define NES_PHY_TYPE_1G 2
#define NES_PHY_TYPE_IRIS 3
#define NES_PHY_TYPE_ARGUS 4
#define NES_PHY_TYPE_PUMA_1G 5
#define NES_PHY_TYPE_PUMA_10G 6
#define NES_PHY_TYPE_GLADIUS 7
+#define NES_PHY_TYPE_SFP_D 8
#define NES_MULTICAST_PF_MAX 8
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index ecb1f6fd627..c6e6611d301 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -1426,49 +1426,55 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
struct nes_vnic *nesvnic = netdev_priv(netdev);
struct nes_device *nesdev = nesvnic->nesdev;
struct nes_adapter *nesadapter = nesdev->nesadapter;
+ u32 mac_index = nesdev->mac_index;
+ u8 phy_type = nesadapter->phy_type[mac_index];
+ u8 phy_index = nesadapter->phy_index[mac_index];
u16 phy_data;
et_cmd->duplex = DUPLEX_FULL;
et_cmd->port = PORT_MII;
+ et_cmd->maxtxpkt = 511;
+ et_cmd->maxrxpkt = 511;
if (nesadapter->OneG_Mode) {
et_cmd->speed = SPEED_1000;
- if (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) {
+ if (phy_type == NES_PHY_TYPE_PUMA_1G) {
et_cmd->supported = SUPPORTED_1000baseT_Full;
et_cmd->advertising = ADVERTISED_1000baseT_Full;
et_cmd->autoneg = AUTONEG_DISABLE;
et_cmd->transceiver = XCVR_INTERNAL;
- et_cmd->phy_address = nesdev->mac_index;
+ et_cmd->phy_address = mac_index;
} else {
- et_cmd->supported = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg;
- et_cmd->advertising = ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg;
- nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], &phy_data);
+ et_cmd->supported = SUPPORTED_1000baseT_Full
+ | SUPPORTED_Autoneg;
+ et_cmd->advertising = ADVERTISED_1000baseT_Full
+ | ADVERTISED_Autoneg;
+ nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
if (phy_data & 0x1000)
et_cmd->autoneg = AUTONEG_ENABLE;
else
et_cmd->autoneg = AUTONEG_DISABLE;
et_cmd->transceiver = XCVR_EXTERNAL;
- et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
+ et_cmd->phy_address = phy_index;
}
+ return 0;
+ }
+ if ((phy_type == NES_PHY_TYPE_IRIS) ||
+ (phy_type == NES_PHY_TYPE_ARGUS) ||
+ (phy_type == NES_PHY_TYPE_SFP_D)) {
+ et_cmd->transceiver = XCVR_EXTERNAL;
+ et_cmd->port = PORT_FIBRE;
+ et_cmd->supported = SUPPORTED_FIBRE;
+ et_cmd->advertising = ADVERTISED_FIBRE;
+ et_cmd->phy_address = phy_index;
} else {
- if ((nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) ||
- (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_ARGUS)) {
- et_cmd->transceiver = XCVR_EXTERNAL;
- et_cmd->port = PORT_FIBRE;
- et_cmd->supported = SUPPORTED_FIBRE;
- et_cmd->advertising = ADVERTISED_FIBRE;
- et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
- } else {
- et_cmd->transceiver = XCVR_INTERNAL;
- et_cmd->supported = SUPPORTED_10000baseT_Full;
- et_cmd->advertising = ADVERTISED_10000baseT_Full;
- et_cmd->phy_address = nesdev->mac_index;
- }
- et_cmd->speed = SPEED_10000;
- et_cmd->autoneg = AUTONEG_DISABLE;
+ et_cmd->transceiver = XCVR_INTERNAL;
+ et_cmd->supported = SUPPORTED_10000baseT_Full;
+ et_cmd->advertising = ADVERTISED_10000baseT_Full;
+ et_cmd->phy_address = mac_index;
}
- et_cmd->maxtxpkt = 511;
- et_cmd->maxrxpkt = 511;
+ et_cmd->speed = SPEED_10000;
+ et_cmd->autoneg = AUTONEG_DISABLE;
return 0;
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 5a76a551035..4c57f329dd5 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -70,12 +70,14 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
*/
if (ppriv->pkey == pkey) {
result = -ENOTUNIQ;
+ priv = NULL;
goto err;
}
list_for_each_entry(priv, &ppriv->child_intfs, list) {
if (priv->pkey == pkey) {
result = -ENOTUNIQ;
+ priv = NULL;
goto err;
}
}
@@ -96,7 +98,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
result = ipoib_set_dev_features(priv, ppriv->ca);
if (result)
- goto device_init_failed;
+ goto err;
priv->pkey = pkey;
@@ -109,7 +111,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
ipoib_warn(ppriv, "failed to initialize subinterface: "
"device %s, port %d",
ppriv->ca->name, ppriv->port);
- goto device_init_failed;
+ goto err;
}
result = register_netdevice(priv->dev);
@@ -146,19 +148,19 @@ sysfs_failed:
register_failed:
ipoib_dev_cleanup(priv->dev);
-device_init_failed:
- free_netdev(priv->dev);
-
err:
mutex_unlock(&ppriv->vlan_mutex);
rtnl_unlock();
+ if (priv)
+ free_netdev(priv->dev);
+
return result;
}
int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
{
struct ipoib_dev_priv *ppriv, *priv, *tpriv;
- int ret = -ENOENT;
+ struct net_device *dev = NULL;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
@@ -172,14 +174,17 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
unregister_netdevice(priv->dev);
ipoib_dev_cleanup(priv->dev);
list_del(&priv->list);
- free_netdev(priv->dev);
-
- ret = 0;
+ dev = priv->dev;
break;
}
}
mutex_unlock(&ppriv->vlan_mutex);
rtnl_unlock();
- return ret;
+ if (dev) {
+ free_netdev(dev);
+ return 0;
+ }
+
+ return -ENODEV;
}
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 5f9d860925a..cd50c00ab20 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -143,7 +143,7 @@ config INPUT_APMPOWER
---help---
Say Y here if you want suspend key events to trigger a user
requested suspend through APM. This is useful on embedded
- systems where such behviour is desired without userspace
+ systems where such behaviour is desired without userspace
interaction. If unsure, say N.
To compile this driver as a module, choose M here: the
diff --git a/drivers/input/input.c b/drivers/input/input.c
index ec3db3ade11..d44065d2e66 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -132,6 +132,11 @@ static void input_start_autorepeat(struct input_dev *dev, int code)
}
}
+static void input_stop_autorepeat(struct input_dev *dev)
+{
+ del_timer(&dev->timer);
+}
+
#define INPUT_IGNORE_EVENT 0
#define INPUT_PASS_TO_HANDLERS 1
#define INPUT_PASS_TO_DEVICE 2
@@ -167,6 +172,8 @@ static void input_handle_event(struct input_dev *dev,
__change_bit(code, dev->key);
if (value)
input_start_autorepeat(dev, code);
+ else
+ input_stop_autorepeat(dev);
}
disposition = INPUT_PASS_TO_HANDLERS;
@@ -737,11 +744,11 @@ static inline void input_wakeup_procfs_readers(void)
static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)
{
- int state = input_devices_state;
-
poll_wait(file, &input_devices_poll_wait, wait);
- if (state != input_devices_state)
+ if (file->f_version != input_devices_state) {
+ file->f_version = input_devices_state;
return POLLIN | POLLRDNORM;
+ }
return 0;
}
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 45470f18d7e..f999dc60c3b 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -229,7 +229,8 @@ struct atkbd {
/*
* System-specific ketymap fixup routine
*/
-static void (*atkbd_platform_fixup)(struct atkbd *);
+static void (*atkbd_platform_fixup)(struct atkbd *, const void *data);
+static void *atkbd_platform_fixup_data;
static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
ssize_t (*handler)(struct atkbd *, char *));
@@ -834,87 +835,64 @@ static void atkbd_disconnect(struct serio *serio)
}
/*
- * Most special keys (Fn+F?) on Dell laptops do not generate release
- * events so we have to do it ourselves.
+ * generate release events for the keycodes given in data
*/
-static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
+static void atkbd_apply_forced_release_keylist(struct atkbd* atkbd,
+ const void *data)
{
- static const unsigned int forced_release_keys[] = {
- 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
- };
- int i;
+ const unsigned int *keys = data;
+ unsigned int i;
if (atkbd->set == 2)
- for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
- __set_bit(forced_release_keys[i],
- atkbd->force_release_mask);
+ for (i = 0; keys[i] != -1U; i++)
+ __set_bit(keys[i], atkbd->force_release_mask);
}
/*
+ * Most special keys (Fn+F?) on Dell laptops do not generate release
+ * events so we have to do it ourselves.
+ */
+static unsigned int atkbd_dell_laptop_forced_release_keys[] = {
+ 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, -1U
+};
+
+/*
* Perform fixup for HP system that doesn't generate release
* for its video switch
*/
-static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)
-{
- static const unsigned int forced_release_keys[] = {
- 0x94,
- };
- int i;
-
- if (atkbd->set == 2)
- for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
- __set_bit(forced_release_keys[i],
- atkbd->force_release_mask);
-}
+static unsigned int atkbd_hp_forced_release_keys[] = {
+ 0x94, -1U
+};
/*
* Inventec system with broken key release on volume keys
*/
-static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd)
-{
- const unsigned int forced_release_keys[] = {
- 0xae, 0xb0,
- };
- int i;
-
- if (atkbd->set == 2)
- for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
- __set_bit(forced_release_keys[i],
- atkbd->force_release_mask);
-}
+static unsigned int atkbd_inventec_forced_release_keys[] = {
+ 0xae, 0xb0, -1U
+};
/*
* Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release
* for its volume buttons
*/
-static void atkbd_hp_zv6100_keymap_fixup(struct atkbd *atkbd)
-{
- const unsigned int forced_release_keys[] = {
- 0xae, 0xb0,
- };
- int i;
-
- if (atkbd->set == 2)
- for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
- __set_bit(forced_release_keys[i],
- atkbd->force_release_mask);
-}
+static unsigned int atkbd_hp_zv6100_forced_release_keys[] = {
+ 0xae, 0xb0, -1U
+};
/*
* Samsung NC10 with Fn+F? key release not working
*/
-static void atkbd_samsung_keymap_fixup(struct atkbd *atkbd)
-{
- const unsigned int forced_release_keys[] = {
- 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9,
- };
- int i;
+static unsigned int atkbd_samsung_forced_release_keys[] = {
+ 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U
+};
- if (atkbd->set == 2)
- for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
- __set_bit(forced_release_keys[i],
- atkbd->force_release_mask);
-}
+/*
+ * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop
+ * do not generate release events so we have to do it ourselves.
+ */
+static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = {
+ 0xb0, 0xae, -1U
+};
/*
* atkbd_set_keycode_table() initializes keyboard's keycode table
@@ -967,7 +945,7 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
* Perform additional fixups
*/
if (atkbd_platform_fixup)
- atkbd_platform_fixup(atkbd);
+ atkbd_platform_fixup(atkbd, atkbd_platform_fixup_data);
}
/*
@@ -1492,9 +1470,11 @@ static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf)
return sprintf(buf, "%lu\n", atkbd->err_count);
}
-static int __init atkbd_setup_fixup(const struct dmi_system_id *id)
+static int __init atkbd_setup_forced_release(const struct dmi_system_id *id)
{
- atkbd_platform_fixup = id->driver_data;
+ atkbd_platform_fixup = atkbd_apply_forced_release_keylist;
+ atkbd_platform_fixup_data = id->driver_data;
+
return 0;
}
@@ -1505,8 +1485,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
},
- .callback = atkbd_setup_fixup,
- .driver_data = atkbd_dell_laptop_keymap_fixup,
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_dell_laptop_forced_release_keys,
},
{
.ident = "Dell Laptop",
@@ -1514,8 +1494,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
},
- .callback = atkbd_setup_fixup,
- .driver_data = atkbd_dell_laptop_keymap_fixup,
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_dell_laptop_forced_release_keys,
},
{
.ident = "HP 2133",
@@ -1523,8 +1503,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"),
},
- .callback = atkbd_setup_fixup,
- .driver_data = atkbd_hp_keymap_fixup,
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_hp_forced_release_keys,
},
{
.ident = "HP Pavilion ZV6100",
@@ -1532,8 +1512,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),
},
- .callback = atkbd_setup_fixup,
- .driver_data = atkbd_hp_zv6100_keymap_fixup,
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_hp_zv6100_forced_release_keys,
},
{
.ident = "Inventec Symphony",
@@ -1541,8 +1521,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"),
DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
},
- .callback = atkbd_setup_fixup,
- .driver_data = atkbd_inventec_keymap_fixup,
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_inventec_forced_release_keys,
},
{
.ident = "Samsung NC10",
@@ -1550,8 +1530,17 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),
},
- .callback = atkbd_setup_fixup,
- .driver_data = atkbd_samsung_keymap_fixup,
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_samsung_forced_release_keys,
+ },
+ {
+ .ident = "Fujitsu Amilo PA 1510",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"),
+ },
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_amilo_pa1510_forced_release_keys,
},
{ }
};
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
index ee855c5202e..e94b7d735ac 100644
--- a/drivers/input/keyboard/bf54x-keys.c
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -211,8 +211,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT ||
!pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) {
- printk(KERN_ERR DRV_NAME
- ": Invalid Debounce/Columdrive Time from pdata\n");
+ printk(KERN_WARNING DRV_NAME
+ ": Invalid Debounce/Columndrive Time in platform data\n");
bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */
} else {
bfin_write_KPAD_MSEL(
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index aacf71f3cd4..e9d639ec283 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -198,45 +198,28 @@ static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len)
}
-/* initialise HIL */
-static int __init
-hil_keyb_init(void)
+/* initialize HIL */
+static int __devinit hil_keyb_init(void)
{
unsigned char c;
unsigned int i, kbid;
wait_queue_head_t hil_wait;
int err;
- if (hil_dev.dev) {
+ if (hil_dev.dev)
return -ENODEV; /* already initialized */
- }
+ init_waitqueue_head(&hil_wait);
spin_lock_init(&hil_dev.lock);
+
hil_dev.dev = input_allocate_device();
if (!hil_dev.dev)
return -ENOMEM;
-#if defined(CONFIG_HP300)
- if (!MACH_IS_HP300) {
- err = -ENODEV;
- goto err1;
- }
- if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {
- printk(KERN_ERR "HIL: hardware register was not found\n");
- err = -ENODEV;
- goto err1;
- }
- if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {
- printk(KERN_ERR "HIL: IOPORT region already used\n");
- err = -EIO;
- goto err1;
- }
-#endif
-
err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id);
if (err) {
printk(KERN_ERR "HIL: Can't get IRQ\n");
- goto err2;
+ goto err1;
}
/* Turn on interrupts */
@@ -246,11 +229,9 @@ hil_keyb_init(void)
hil_dev.valid = 0; /* clear any pending data */
hil_do(HIL_READKBDSADR, NULL, 0);
- init_waitqueue_head(&hil_wait);
- wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ);
- if (!hil_dev.valid) {
+ wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3 * HZ);
+ if (!hil_dev.valid)
printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n");
- }
c = hil_dev.c;
hil_dev.valid = 0;
@@ -268,7 +249,7 @@ hil_keyb_init(void)
for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++)
if (hphilkeyb_keycode[i] != KEY_RESERVED)
- set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
+ __set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
hil_dev.dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
hil_dev.dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
@@ -287,34 +268,45 @@ hil_keyb_init(void)
err = input_register_device(hil_dev.dev);
if (err) {
printk(KERN_ERR "HIL: Can't register device\n");
- goto err3;
+ goto err2;
}
+
printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n",
hil_dev.dev->name, kbid, HILBASE, HIL_IRQ);
return 0;
-err3:
+err2:
hil_do(HIL_INTOFF, NULL, 0);
- disable_irq(HIL_IRQ);
free_irq(HIL_IRQ, hil_dev.dev_id);
-err2:
-#if defined(CONFIG_HP300)
- release_region(HILBASE + HIL_DATA, 2);
err1:
-#endif
input_free_device(hil_dev.dev);
hil_dev.dev = NULL;
return err;
}
+static void __devexit hil_keyb_exit(void)
+{
+ if (HIL_IRQ)
+ free_irq(HIL_IRQ, hil_dev.dev_id);
+
+ /* Turn off interrupts */
+ hil_do(HIL_INTOFF, NULL, 0);
+
+ input_unregister_device(hil_dev.dev);
+ hil_dev.dev = NULL;
+}
#if defined(CONFIG_PARISC)
-static int __init
-hil_init_chip(struct parisc_device *dev)
+static int __devinit hil_probe_chip(struct parisc_device *dev)
{
+ /* Only allow one HIL keyboard */
+ if (hil_dev.dev)
+ return -ENODEV;
+
if (!dev->irq) {
- printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa.start);
+ printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%p\n",
+ (void *)dev->hpa.start);
return -ENODEV;
}
@@ -327,51 +319,79 @@ hil_init_chip(struct parisc_device *dev)
return hil_keyb_init();
}
+static int __devexit hil_remove_chip(struct parisc_device *dev)
+{
+ hil_keyb_exit();
+
+ return 0;
+}
+
static struct parisc_device_id hil_tbl[] = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 },
{ 0, }
};
+#if 0
+/* Disabled to avoid conflicts with the HP SDC HIL drivers */
MODULE_DEVICE_TABLE(parisc, hil_tbl);
+#endif
static struct parisc_driver hil_driver = {
- .name = "hil",
- .id_table = hil_tbl,
- .probe = hil_init_chip,
+ .name = "hil",
+ .id_table = hil_tbl,
+ .probe = hil_probe_chip,
+ .remove = __devexit_p(hil_remove_chip),
};
-#endif /* CONFIG_PARISC */
-
static int __init hil_init(void)
{
-#if defined(CONFIG_PARISC)
return register_parisc_driver(&hil_driver);
-#else
- return hil_keyb_init();
-#endif
}
-
static void __exit hil_exit(void)
{
- if (HIL_IRQ) {
- disable_irq(HIL_IRQ);
- free_irq(HIL_IRQ, hil_dev.dev_id);
+ unregister_parisc_driver(&hil_driver);
+}
+
+#else /* !CONFIG_PARISC */
+
+static int __init hil_init(void)
+{
+ int error;
+
+ /* Only allow one HIL keyboard */
+ if (hil_dev.dev)
+ return -EBUSY;
+
+ if (!MACH_IS_HP300)
+ return -ENODEV;
+
+ if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {
+ printk(KERN_ERR "HIL: hardware register was not found\n");
+ return -ENODEV;
}
- /* Turn off interrupts */
- hil_do(HIL_INTOFF, NULL, 0);
+ if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {
+ printk(KERN_ERR "HIL: IOPORT region already used\n");
+ return -EIO;
+ }
- input_unregister_device(hil_dev.dev);
+ error = hil_keyb_init();
+ if (error) {
+ release_region(HILBASE + HIL_DATA, 2);
+ return error;
+ }
- hil_dev.dev = NULL;
+ return 0;
+}
-#if defined(CONFIG_PARISC)
- unregister_parisc_driver(&hil_driver);
-#else
- release_region(HILBASE+HIL_DATA, 2);
-#endif
+static void __exit hil_exit(void)
+{
+ hil_keyb_exit();
+ release_region(HILBASE + HIL_DATA, 2);
}
+#endif /* CONFIG_PARISC */
+
module_init(hil_init);
module_exit(hil_exit);
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index e1480fb11de..cea70e6a103 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -259,12 +259,15 @@ static int sh_keysc_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
+ int irq = platform_get_irq(pdev, 0);
unsigned short value;
value = ioread16(priv->iomem_base + KYCR1_OFFS);
- if (device_may_wakeup(dev))
+ if (device_may_wakeup(dev)) {
value |= 0x80;
+ enable_irq_wake(irq);
+ }
else
value &= ~0x80;
@@ -272,8 +275,20 @@ static int sh_keysc_suspend(struct device *dev)
return 0;
}
+static int sh_keysc_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ int irq = platform_get_irq(pdev, 0);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(irq);
+
+ return 0;
+}
+
static struct dev_pm_ops sh_keysc_dev_pm_ops = {
.suspend = sh_keysc_suspend,
+ .resume = sh_keysc_resume,
};
struct platform_driver sh_keysc_device_driver = {
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 67e5553f699..203abac1e23 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -227,4 +227,27 @@ config INPUT_PCF50633_PMU
Say Y to include support for delivering PMU events via input
layer on NXP PCF50633.
+config INPUT_GPIO_ROTARY_ENCODER
+ tristate "Rotary encoders connected to GPIO pins"
+ depends on GPIOLIB && GENERIC_GPIO
+ help
+ Say Y here to add support for rotary encoders connected to GPIO lines.
+ Check file:Documentation/incput/rotary_encoder.txt for more
+ information.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rotary_encoder.
+
+config INPUT_RB532_BUTTON
+ tristate "Mikrotik Routerboard 532 button interface"
+ depends on MIKROTIK_RB532
+ depends on GPIOLIB && GENERIC_GPIO
+ select INPUT_POLLDEV
+ help
+ Say Y here if you want support for the S1 button built into
+ Mikrotik's Routerboard 532.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rb532_button.
+
endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index bb62e6efacf..eb3f407baed 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -4,21 +4,23 @@
# Each configuration option enables a list of files.
-obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
-obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
-obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
-obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
-obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
-obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
-obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
+obj-$(CONFIG_INPUT_APANEL) += apanel.o
obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o
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_ATLAS_BTNS) += atlas_btns.o
obj-$(CONFIG_INPUT_CM109) += cm109.o
+obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
-obj-$(CONFIG_INPUT_UINPUT) += uinput.o
-obj-$(CONFIG_INPUT_APANEL) += apanel.o
-obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
+obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
+obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
+obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o
+obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
+obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
+obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o
+obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o
+obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
+obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
+obj-$(CONFIG_INPUT_UINPUT) += uinput.o
+obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
+obj-$(CONFIG_INPUT_YEALINK) += yealink.o
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index 3c9988dc0e9..922c0514158 100644
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -31,12 +31,73 @@ MODULE_LICENSE("GPL");
* newly configured "channel".
*/
-static unsigned int channel_mask = 0xFFFF;
-module_param(channel_mask, uint, 0644);
+enum {
+ ATI_REMOTE2_MAX_CHANNEL_MASK = 0xFFFF,
+ ATI_REMOTE2_MAX_MODE_MASK = 0x1F,
+};
+
+static int ati_remote2_set_mask(const char *val,
+ struct kernel_param *kp, unsigned int max)
+{
+ unsigned long mask;
+ int ret;
+
+ if (!val)
+ return -EINVAL;
+
+ ret = strict_strtoul(val, 0, &mask);
+ if (ret)
+ return ret;
+
+ if (mask & ~max)
+ return -EINVAL;
+
+ *(unsigned int *)kp->arg = mask;
+
+ return 0;
+}
+
+static int ati_remote2_set_channel_mask(const char *val,
+ struct kernel_param *kp)
+{
+ pr_debug("%s()\n", __func__);
+
+ return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK);
+}
+
+static int ati_remote2_get_channel_mask(char *buffer, struct kernel_param *kp)
+{
+ pr_debug("%s()\n", __func__);
+
+ return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg);
+}
+
+static int ati_remote2_set_mode_mask(const char *val, struct kernel_param *kp)
+{
+ pr_debug("%s()\n", __func__);
+
+ return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK);
+}
+
+static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp)
+{
+ pr_debug("%s()\n", __func__);
+
+ return sprintf(buffer, "0x%02x", *(unsigned int *)kp->arg);
+}
+
+static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK;
+#define param_check_channel_mask(name, p) __param_check(name, p, unsigned int)
+#define param_set_channel_mask ati_remote2_set_channel_mask
+#define param_get_channel_mask ati_remote2_get_channel_mask
+module_param(channel_mask, channel_mask, 0644);
MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>");
-static unsigned int mode_mask = 0x1F;
-module_param(mode_mask, uint, 0644);
+static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK;
+#define param_check_mode_mask(name, p) __param_check(name, p, unsigned int)
+#define param_set_mode_mask ati_remote2_set_mode_mask
+#define param_get_mode_mask ati_remote2_get_mode_mask
+module_param(mode_mask, mode_mask, 0644);
MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");
static struct usb_device_id ati_remote2_id_table[] = {
@@ -133,12 +194,18 @@ struct ati_remote2 {
u16 keycode[ATI_REMOTE2_MODES][ARRAY_SIZE(ati_remote2_key_table)];
unsigned int flags;
+
+ unsigned int channel_mask;
+ unsigned int mode_mask;
};
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 int ati_remote2_reset_resume(struct usb_interface *interface);
+static int ati_remote2_pre_reset(struct usb_interface *interface);
+static int ati_remote2_post_reset(struct usb_interface *interface);
static struct usb_driver ati_remote2_driver = {
.name = "ati_remote2",
@@ -147,6 +214,9 @@ static struct usb_driver ati_remote2_driver = {
.id_table = ati_remote2_id_table,
.suspend = ati_remote2_suspend,
.resume = ati_remote2_resume,
+ .reset_resume = ati_remote2_reset_resume,
+ .pre_reset = ati_remote2_pre_reset,
+ .post_reset = ati_remote2_post_reset,
.supports_autosuspend = 1,
};
@@ -238,7 +308,7 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
channel = data[0] >> 4;
- if (!((1 << channel) & channel_mask))
+ if (!((1 << channel) & ar2->channel_mask))
return;
mode = data[0] & 0x0F;
@@ -250,7 +320,7 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
return;
}
- if (!((1 << mode) & mode_mask))
+ if (!((1 << mode) & ar2->mode_mask))
return;
input_event(idev, EV_REL, REL_X, (s8) data[1]);
@@ -277,7 +347,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
channel = data[0] >> 4;
- if (!((1 << channel) & channel_mask))
+ if (!((1 << channel) & ar2->channel_mask))
return;
mode = data[0] & 0x0F;
@@ -305,7 +375,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
ar2->mode = mode;
}
- if (!((1 << mode) & mode_mask))
+ if (!((1 << mode) & ar2->mode_mask))
return;
index = ati_remote2_lookup(hw_code);
@@ -410,7 +480,7 @@ static int ati_remote2_getkeycode(struct input_dev *idev,
int index, mode;
mode = scancode >> 8;
- if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
+ if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
return -EINVAL;
index = ati_remote2_lookup(scancode & 0xFF);
@@ -427,7 +497,7 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc
int index, mode, old_keycode;
mode = scancode >> 8;
- if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
+ if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
return -EINVAL;
index = ati_remote2_lookup(scancode & 0xFF);
@@ -550,7 +620,7 @@ static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2)
}
}
-static int ati_remote2_setup(struct ati_remote2 *ar2)
+static int ati_remote2_setup(struct ati_remote2 *ar2, unsigned int ch_mask)
{
int r, i, channel;
@@ -565,8 +635,8 @@ static int ati_remote2_setup(struct ati_remote2 *ar2)
channel = 0;
for (i = 0; i < 16; i++) {
- if ((1 << i) & channel_mask) {
- if (!(~(1 << i) & 0xFFFF & channel_mask))
+ if ((1 << i) & ch_mask) {
+ if (!(~(1 << i) & ch_mask))
channel = i + 1;
break;
}
@@ -585,6 +655,99 @@ static int ati_remote2_setup(struct ati_remote2 *ar2)
return 0;
}
+static ssize_t ati_remote2_show_channel_mask(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_device *udev = to_usb_device(dev);
+ struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+ struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+
+ return sprintf(buf, "0x%04x\n", ar2->channel_mask);
+}
+
+static ssize_t ati_remote2_store_channel_mask(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_device *udev = to_usb_device(dev);
+ struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+ struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+ unsigned long mask;
+ int r;
+
+ if (strict_strtoul(buf, 0, &mask))
+ return -EINVAL;
+
+ if (mask & ~ATI_REMOTE2_MAX_CHANNEL_MASK)
+ return -EINVAL;
+
+ 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);
+ return r;
+ }
+
+ mutex_lock(&ati_remote2_mutex);
+
+ if (mask != ar2->channel_mask && !ati_remote2_setup(ar2, mask))
+ ar2->channel_mask = mask;
+
+ mutex_unlock(&ati_remote2_mutex);
+
+ usb_autopm_put_interface(ar2->intf[0]);
+
+ return count;
+}
+
+static ssize_t ati_remote2_show_mode_mask(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_device *udev = to_usb_device(dev);
+ struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+ struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+
+ return sprintf(buf, "0x%02x\n", ar2->mode_mask);
+}
+
+static ssize_t ati_remote2_store_mode_mask(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_device *udev = to_usb_device(dev);
+ struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+ struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+ unsigned long mask;
+
+ if (strict_strtoul(buf, 0, &mask))
+ return -EINVAL;
+
+ if (mask & ~ATI_REMOTE2_MAX_MODE_MASK)
+ return -EINVAL;
+
+ ar2->mode_mask = mask;
+
+ return count;
+}
+
+static DEVICE_ATTR(channel_mask, 0644, ati_remote2_show_channel_mask,
+ ati_remote2_store_channel_mask);
+
+static DEVICE_ATTR(mode_mask, 0644, ati_remote2_show_mode_mask,
+ ati_remote2_store_mode_mask);
+
+static struct attribute *ati_remote2_attrs[] = {
+ &dev_attr_channel_mask.attr,
+ &dev_attr_mode_mask.attr,
+ NULL,
+};
+
+static struct attribute_group ati_remote2_attr_group = {
+ .attrs = ati_remote2_attrs,
+};
+
static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(interface);
@@ -615,7 +778,10 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
if (r)
goto fail2;
- r = ati_remote2_setup(ar2);
+ ar2->channel_mask = channel_mask;
+ ar2->mode_mask = mode_mask;
+
+ r = ati_remote2_setup(ar2, ar2->channel_mask);
if (r)
goto fail2;
@@ -624,19 +790,24 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name));
- r = ati_remote2_input_init(ar2);
+ r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group);
if (r)
goto fail2;
+ r = ati_remote2_input_init(ar2);
+ if (r)
+ goto fail3;
+
usb_set_intfdata(interface, ar2);
interface->needs_remote_wakeup = 1;
return 0;
+ fail3:
+ sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group);
fail2:
ati_remote2_urb_cleanup(ar2);
-
usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
fail1:
kfree(ar2);
@@ -657,6 +828,8 @@ static void ati_remote2_disconnect(struct usb_interface *interface)
input_unregister_device(ar2->idev);
+ sysfs_remove_group(&ar2->udev->dev.kobj, &ati_remote2_attr_group);
+
ati_remote2_urb_cleanup(ar2);
usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
@@ -715,6 +888,78 @@ static int ati_remote2_resume(struct usb_interface *interface)
return r;
}
+static int ati_remote2_reset_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);
+
+ r = ati_remote2_setup(ar2, ar2->channel_mask);
+ if (r)
+ goto out;
+
+ if (ar2->flags & ATI_REMOTE2_OPENED)
+ r = ati_remote2_submit_urbs(ar2);
+
+ if (!r)
+ ar2->flags &= ~ATI_REMOTE2_SUSPENDED;
+
+ out:
+ mutex_unlock(&ati_remote2_mutex);
+
+ return r;
+}
+
+static int ati_remote2_pre_reset(struct usb_interface *interface)
+{
+ 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);
+
+ return 0;
+}
+
+static int ati_remote2_post_reset(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__);
+
+ if (ar2->flags == ATI_REMOTE2_OPENED)
+ r = ati_remote2_submit_urbs(ar2);
+
+ mutex_unlock(&ati_remote2_mutex);
+
+ return r;
+}
+
static int __init ati_remote2_init(void)
{
int r;
diff --git a/drivers/input/misc/rb532_button.c b/drivers/input/misc/rb532_button.c
new file mode 100644
index 00000000000..e2c7f622a0b
--- /dev/null
+++ b/drivers/input/misc/rb532_button.c
@@ -0,0 +1,120 @@
+/*
+ * Support for the S1 button on Routerboard 532
+ *
+ * Copyright (C) 2009 Phil Sutter <n0-1@freewrt.org>
+ */
+
+#include <linux/input-polldev.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-rc32434/gpio.h>
+#include <asm/mach-rc32434/rb.h>
+
+#define DRV_NAME "rb532-button"
+
+#define RB532_BTN_RATE 100 /* msec */
+#define RB532_BTN_KSYM BTN_0
+
+/* The S1 button state is provided by GPIO pin 1. But as this
+ * pin is also used for uart input as alternate function, the
+ * operational modes must be switched first:
+ * 1) disable uart using set_latch_u5()
+ * 2) turn off alternate function implicitly through
+ * gpio_direction_input()
+ * 3) read the GPIO's current value
+ * 4) undo step 2 by enabling alternate function (in this
+ * mode the GPIO direction is fixed, so no change needed)
+ * 5) turn on uart again
+ * The GPIO value occurs to be inverted, so pin high means
+ * button is not pressed.
+ */
+static bool rb532_button_pressed(void)
+{
+ int val;
+
+ set_latch_u5(0, LO_FOFF);
+ gpio_direction_input(GPIO_BTN_S1);
+
+ val = gpio_get_value(GPIO_BTN_S1);
+
+ rb532_gpio_set_func(GPIO_BTN_S1);
+ set_latch_u5(LO_FOFF, 0);
+
+ return !val;
+}
+
+static void rb532_button_poll(struct input_polled_dev *poll_dev)
+{
+ input_report_key(poll_dev->input, RB532_BTN_KSYM,
+ rb532_button_pressed());
+ input_sync(poll_dev->input);
+}
+
+static int __devinit rb532_button_probe(struct platform_device *pdev)
+{
+ struct input_polled_dev *poll_dev;
+ int error;
+
+ poll_dev = input_allocate_polled_device();
+ if (!poll_dev)
+ return -ENOMEM;
+
+ poll_dev->poll = rb532_button_poll;
+ poll_dev->poll_interval = RB532_BTN_RATE;
+
+ poll_dev->input->name = "rb532 button";
+ poll_dev->input->phys = "rb532/button0";
+ poll_dev->input->id.bustype = BUS_HOST;
+ poll_dev->input->dev.parent = &pdev->dev;
+
+ dev_set_drvdata(&pdev->dev, poll_dev);
+
+ input_set_capability(poll_dev->input, EV_KEY, RB532_BTN_KSYM);
+
+ error = input_register_polled_device(poll_dev);
+ if (error) {
+ input_free_polled_device(poll_dev);
+ return error;
+ }
+
+ return 0;
+}
+
+static int __devexit rb532_button_remove(struct platform_device *pdev)
+{
+ struct input_polled_dev *poll_dev = dev_get_drvdata(&pdev->dev);
+
+ input_unregister_polled_device(poll_dev);
+ input_free_polled_device(poll_dev);
+ dev_set_drvdata(&pdev->dev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver rb532_button_driver = {
+ .probe = rb532_button_probe,
+ .remove = __devexit_p(rb532_button_remove),
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init rb532_button_init(void)
+{
+ return platform_driver_register(&rb532_button_driver);
+}
+
+static void __exit rb532_button_exit(void)
+{
+ platform_driver_unregister(&rb532_button_driver);
+}
+
+module_init(rb532_button_init);
+module_exit(rb532_button_exit);
+
+MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Support for S1 button on Routerboard 532");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
new file mode 100644
index 00000000000..5bb3ab51b8c
--- /dev/null
+++ b/drivers/input/misc/rotary_encoder.c
@@ -0,0 +1,221 @@
+/*
+ * rotary_encoder.c
+ *
+ * (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * state machine code inspired by code from Tim Ruetz
+ *
+ * A generic driver for rotary encoders connected to GPIO lines.
+ * See file:Documentation/input/rotary_encoder.txt for more information
+ *
+ * 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/init.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/rotary_encoder.h>
+
+#define DRV_NAME "rotary-encoder"
+
+struct rotary_encoder {
+ unsigned int irq_a;
+ unsigned int irq_b;
+ unsigned int pos;
+ unsigned int armed;
+ unsigned int dir;
+ struct input_dev *input;
+ struct rotary_encoder_platform_data *pdata;
+};
+
+static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
+{
+ struct rotary_encoder *encoder = dev_id;
+ struct rotary_encoder_platform_data *pdata = encoder->pdata;
+ int a = !!gpio_get_value(pdata->gpio_a);
+ int b = !!gpio_get_value(pdata->gpio_b);
+ int state;
+
+ a ^= pdata->inverted_a;
+ b ^= pdata->inverted_b;
+ state = (a << 1) | b;
+
+ switch (state) {
+
+ case 0x0:
+ if (!encoder->armed)
+ break;
+
+ if (encoder->dir) {
+ /* turning counter-clockwise */
+ encoder->pos += pdata->steps;
+ encoder->pos--;
+ encoder->pos %= pdata->steps;
+ } else {
+ /* turning clockwise */
+ encoder->pos++;
+ encoder->pos %= pdata->steps;
+ }
+
+ input_report_abs(encoder->input, pdata->axis, encoder->pos);
+ input_sync(encoder->input);
+
+ encoder->armed = 0;
+ break;
+
+ case 0x1:
+ case 0x2:
+ if (encoder->armed)
+ encoder->dir = state - 1;
+ break;
+
+ case 0x3:
+ encoder->armed = 1;
+ break;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit rotary_encoder_probe(struct platform_device *pdev)
+{
+ struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data;
+ struct rotary_encoder *encoder;
+ struct input_dev *input;
+ int err;
+
+ if (!pdata || !pdata->steps) {
+ dev_err(&pdev->dev, "invalid platform data\n");
+ return -ENOENT;
+ }
+
+ encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL);
+ input = input_allocate_device();
+ if (!encoder || !input) {
+ dev_err(&pdev->dev, "failed to allocate memory for device\n");
+ err = -ENOMEM;
+ goto exit_free_mem;
+ }
+
+ encoder->input = input;
+ encoder->pdata = pdata;
+ encoder->irq_a = gpio_to_irq(pdata->gpio_a);
+ encoder->irq_b = gpio_to_irq(pdata->gpio_b);
+
+ /* create and register the input driver */
+ input->name = pdev->name;
+ input->id.bustype = BUS_HOST;
+ input->dev.parent = &pdev->dev;
+ input->evbit[0] = BIT_MASK(EV_ABS);
+ input_set_abs_params(encoder->input,
+ pdata->axis, 0, pdata->steps, 0, 1);
+
+ err = input_register_device(input);
+ if (err) {
+ dev_err(&pdev->dev, "failed to register input device\n");
+ goto exit_free_mem;
+ }
+
+ /* request the GPIOs */
+ err = gpio_request(pdata->gpio_a, DRV_NAME);
+ if (err) {
+ dev_err(&pdev->dev, "unable to request GPIO %d\n",
+ pdata->gpio_a);
+ goto exit_unregister_input;
+ }
+
+ err = gpio_request(pdata->gpio_b, DRV_NAME);
+ if (err) {
+ dev_err(&pdev->dev, "unable to request GPIO %d\n",
+ pdata->gpio_b);
+ goto exit_free_gpio_a;
+ }
+
+ /* request the IRQs */
+ err = request_irq(encoder->irq_a, &rotary_encoder_irq,
+ IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
+ DRV_NAME, encoder);
+ if (err) {
+ dev_err(&pdev->dev, "unable to request IRQ %d\n",
+ encoder->irq_a);
+ goto exit_free_gpio_b;
+ }
+
+ err = request_irq(encoder->irq_b, &rotary_encoder_irq,
+ IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
+ DRV_NAME, encoder);
+ if (err) {
+ dev_err(&pdev->dev, "unable to request IRQ %d\n",
+ encoder->irq_b);
+ goto exit_free_irq_a;
+ }
+
+ platform_set_drvdata(pdev, encoder);
+
+ return 0;
+
+exit_free_irq_a:
+ free_irq(encoder->irq_a, encoder);
+exit_free_gpio_b:
+ gpio_free(pdata->gpio_b);
+exit_free_gpio_a:
+ gpio_free(pdata->gpio_a);
+exit_unregister_input:
+ input_unregister_device(input);
+ input = NULL; /* so we don't try to free it */
+exit_free_mem:
+ input_free_device(input);
+ kfree(encoder);
+ return err;
+}
+
+static int __devexit rotary_encoder_remove(struct platform_device *pdev)
+{
+ struct rotary_encoder *encoder = platform_get_drvdata(pdev);
+ struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data;
+
+ free_irq(encoder->irq_a, encoder);
+ free_irq(encoder->irq_b, encoder);
+ gpio_free(pdata->gpio_a);
+ gpio_free(pdata->gpio_b);
+ input_unregister_device(encoder->input);
+ platform_set_drvdata(pdev, NULL);
+ kfree(encoder);
+
+ return 0;
+}
+
+static struct platform_driver rotary_encoder_driver = {
+ .probe = rotary_encoder_probe,
+ .remove = __devexit_p(rotary_encoder_remove),
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ }
+};
+
+static int __init rotary_encoder_init(void)
+{
+ return platform_driver_register(&rotary_encoder_driver);
+}
+
+static void __exit rotary_encoder_exit(void)
+{
+ platform_driver_unregister(&rotary_encoder_driver);
+}
+
+module_init(rotary_encoder_init);
+module_exit(rotary_encoder_exit);
+
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DESCRIPTION("GPIO rotary encoder driver");
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 4f38e6f7dfd..c66cc3d08c2 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -292,4 +292,15 @@ config MOUSE_PXA930_TRKBALL
help
Say Y here to support PXA930 Trackball mouse.
+config MOUSE_MAPLE
+ tristate "Maple mouse (for the Dreamcast)"
+ depends on MAPLE
+ help
+ This driver supports the Maple mouse on the SEGA Dreamcast.
+
+ Most Dreamcast users, who have a mouse, will say Y here.
+
+ To compile this driver as a module choose M here: the module will be
+ called maplemouse.
+
endif
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index 8c8a1f236e2..472189468d6 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -6,18 +6,19 @@
obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o
obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o
-obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o
obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o
-obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o
+obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o
+obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
+obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o
obj-$(CONFIG_MOUSE_INPORT) += inport.o
obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o
+obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o
obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o
obj-$(CONFIG_MOUSE_PS2) += psmouse.o
obj-$(CONFIG_MOUSE_PXA930_TRKBALL) += pxa930_trkball.o
+obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o
obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o
-obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o
obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o
-obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
psmouse-objs := psmouse-base.o synaptics.o
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c
index 0db8d16c5ed..5e5eb88d8d1 100644
--- a/drivers/input/mouse/gpio_mouse.c
+++ b/drivers/input/mouse/gpio_mouse.c
@@ -18,7 +18,7 @@
/*
* Timer function which is run every scan_ms ms when the device is opened.
- * The dev input varaible is set to the the input_dev pointer.
+ * The dev input variable is set to the the input_dev pointer.
*/
static void gpio_mouse_scan(struct input_polled_dev *dev)
{
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
index 55cd0fa6833..a1ad2f1a7bb 100644
--- a/drivers/input/mouse/hgpk.c
+++ b/drivers/input/mouse/hgpk.c
@@ -472,7 +472,7 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
return -EIO;
}
- hgpk_dbg(psmouse, "ID: %02x %02x %02x", param[0], param[1], param[2]);
+ hgpk_dbg(psmouse, "ID: %02x %02x %02x\n", param[0], param[1], param[2]);
/* HGPK signature: 0x67, 0x00, 0x<model> */
if (param[0] != 0x67 || param[1] != 0x00)
diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c
new file mode 100644
index 00000000000..d196abfb68b
--- /dev/null
+++ b/drivers/input/mouse/maplemouse.c
@@ -0,0 +1,147 @@
+/*
+ * SEGA Dreamcast mouse driver
+ * Based on drivers/usb/usbmouse.c
+ *
+ * Copyright Yaegashi Takeshi, 2001
+ * Adrian McMenamin, 2008
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/maple.h>
+
+MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
+MODULE_DESCRIPTION("SEGA Dreamcast mouse driver");
+MODULE_LICENSE("GPL");
+
+struct dc_mouse {
+ struct input_dev *dev;
+ struct maple_device *mdev;
+};
+
+static void dc_mouse_callback(struct mapleq *mq)
+{
+ int buttons, relx, rely, relz;
+ struct maple_device *mapledev = mq->dev;
+ struct dc_mouse *mse = maple_get_drvdata(mapledev);
+ struct input_dev *dev = mse->dev;
+ unsigned char *res = mq->recvbuf;
+
+ buttons = ~res[8];
+ relx = *(unsigned short *)(res + 12) - 512;
+ rely = *(unsigned short *)(res + 14) - 512;
+ relz = *(unsigned short *)(res + 16) - 512;
+
+ input_report_key(dev, BTN_LEFT, buttons & 4);
+ input_report_key(dev, BTN_MIDDLE, buttons & 9);
+ input_report_key(dev, BTN_RIGHT, buttons & 2);
+ input_report_rel(dev, REL_X, relx);
+ input_report_rel(dev, REL_Y, rely);
+ input_report_rel(dev, REL_WHEEL, relz);
+ input_sync(dev);
+}
+
+static int dc_mouse_open(struct input_dev *dev)
+{
+ struct dc_mouse *mse = dev->dev.platform_data;
+
+ maple_getcond_callback(mse->mdev, dc_mouse_callback, HZ/50,
+ MAPLE_FUNC_MOUSE);
+
+ return 0;
+}
+
+static void dc_mouse_close(struct input_dev *dev)
+{
+ struct dc_mouse *mse = dev->dev.platform_data;
+
+ maple_getcond_callback(mse->mdev, dc_mouse_callback, 0,
+ MAPLE_FUNC_MOUSE);
+}
+
+
+static int __devinit probe_maple_mouse(struct device *dev)
+{
+ struct maple_device *mdev = to_maple_dev(dev);
+ struct maple_driver *mdrv = to_maple_driver(dev->driver);
+ struct input_dev *input_dev;
+ struct dc_mouse *mse;
+ int error;
+
+ mse = kzalloc(sizeof(struct dc_mouse), GFP_KERNEL);
+ input_dev = input_allocate_device();
+
+ if (!mse || !input_dev) {
+ error = -ENOMEM;
+ goto fail;
+ }
+
+ mse->dev = input_dev;
+ mse->mdev = mdev;
+
+ input_set_drvdata(input_dev, mse);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+ input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) |
+ BIT_MASK(REL_WHEEL);
+ input_dev->name = mdev->product_name;
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->open = dc_mouse_open;
+ input_dev->close = dc_mouse_close;
+
+ mdev->driver = mdrv;
+ maple_set_drvdata(mdev, mse);
+
+ error = input_register_device(input_dev);
+ if (error)
+ goto fail;
+
+ return 0;
+
+fail:
+ input_free_device(input_dev);
+ maple_set_drvdata(mdev, NULL);
+ kfree(mse);
+ mdev->driver = NULL;
+ return error;
+}
+
+static int __devexit remove_maple_mouse(struct device *dev)
+{
+ struct maple_device *mdev = to_maple_dev(dev);
+ struct dc_mouse *mse = maple_get_drvdata(mdev);
+
+ mdev->callback = NULL;
+ input_unregister_device(mse->dev);
+ maple_set_drvdata(mdev, NULL);
+ kfree(mse);
+
+ return 0;
+}
+
+static struct maple_driver dc_mouse_driver = {
+ .function = MAPLE_FUNC_MOUSE,
+ .drv = {
+ .name = "Dreamcast_mouse",
+ .probe = probe_maple_mouse,
+ .remove = __devexit_p(remove_maple_mouse),
+ },
+};
+
+static int __init dc_mouse_init(void)
+{
+ return maple_driver_register(&dc_mouse_driver);
+}
+
+static void __exit dc_mouse_exit(void)
+{
+ maple_driver_unregister(&dc_mouse_driver);
+}
+
+module_init(dc_mouse_init);
+module_exit(dc_mouse_exit);
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c
index fd09c8df81f..f63995f854f 100644
--- a/drivers/input/mouse/pc110pad.c
+++ b/drivers/input/mouse/pc110pad.c
@@ -111,11 +111,8 @@ static int __init pc110pad_init(void)
struct pci_dev *dev;
int err;
- dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
- if (dev) {
- pci_dev_put(dev);
+ if (!no_pci_devices())
return -ENODEV;
- }
if (!request_region(pc110pad_io, 4, "pc110pad")) {
printk(KERN_ERR "pc110pad: I/O area %#x-%#x in use.\n",
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 6fa2deff744..83ed2d56b92 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -151,6 +151,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
DMI_MATCH(DMI_PRODUCT_VERSION, "01"),
},
},
+ {
+ .ident = "HP DV9700",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
+ },
+ },
{ }
};
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index bb6486a8c07..b01fd61dadc 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -29,6 +29,51 @@ config TOUCHSCREEN_ADS7846
To compile this driver as a module, choose M here: the
module will be called ads7846.
+config TOUCHSCREEN_AD7877
+ tristate "AD7877 based touchscreens"
+ depends on SPI_MASTER
+ help
+ Say Y here if you have a touchscreen interface using the
+ AD7877 controller, and your board-specific initialization
+ code includes that in its table of SPI devices.
+
+ If unsure, say N (but it's safe to say "Y").
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad7877.
+
+config TOUCHSCREEN_AD7879_I2C
+ tristate "AD7879 based touchscreens: AD7879-1 I2C Interface"
+ depends on I2C
+ select TOUCHSCREEN_AD7879
+ help
+ Say Y here if you have a touchscreen interface using the
+ AD7879-1 controller, and your board-specific initialization
+ code includes that in its table of I2C devices.
+
+ If unsure, say N (but it's safe to say "Y").
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad7879.
+
+config TOUCHSCREEN_AD7879_SPI
+ tristate "AD7879 based touchscreens: AD7879 SPI Interface"
+ depends on SPI_MASTER && TOUCHSCREEN_AD7879_I2C = n
+ select TOUCHSCREEN_AD7879
+ help
+ Say Y here if you have a touchscreen interface using the
+ AD7879 controller, and your board-specific initialization
+ code includes that in its table of SPI devices.
+
+ If unsure, say N (but it's safe to say "Y").
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad7879.
+
+config TOUCHSCREEN_AD7879
+ tristate
+ default n
+
config TOUCHSCREEN_BITSY
tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
depends on SA1100_BITSY
@@ -308,6 +353,19 @@ config TOUCHSCREEN_WM97XX_MAINSTONE
To compile this driver as a module, choose M here: the
module will be called mainstone-wm97xx.
+config TOUCHSCREEN_WM97XX_ZYLONITE
+ tristate "Zylonite accelerated touch"
+ depends on TOUCHSCREEN_WM97XX && MACH_ZYLONITE
+ select TOUCHSCREEN_WM9713
+ help
+ Say Y here for support for streaming mode with the touchscreen
+ on Zylonite systems.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called zylonite-wm97xx.
+
config TOUCHSCREEN_USB_COMPOSITE
tristate "USB Touchscreen Driver"
depends on USB_ARCH_HAS_HCD
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index d3375aff46f..6700f7b9d16 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -6,6 +6,8 @@
wm97xx-ts-y := wm97xx-core.o
+obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o
+obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o
obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o
obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
@@ -34,3 +36,4 @@ wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o
wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o
obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o
+obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c
new file mode 100644
index 00000000000..e4728a28f49
--- /dev/null
+++ b/drivers/input/touchscreen/ad7877.c
@@ -0,0 +1,844 @@
+/*
+ * Copyright (C) 2006-2008 Michael Hennerich, Analog Devices Inc.
+ *
+ * Description: AD7877 based touchscreen, sensor (ADCs), DAC and GPIO driver
+ * Based on: ads7846.c
+ *
+ * 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
+ *
+ * History:
+ * Copyright (c) 2005 David Brownell
+ * Copyright (c) 2006 Nokia Corporation
+ * Various changes: Imre Deak <imre.deak@nokia.com>
+ *
+ * Using code from:
+ * - corgi_ts.c
+ * Copyright (C) 2004-2005 Richard Purdie
+ * - omap_ts.[hc], ads7846.h, ts_osk.c
+ * Copyright (C) 2002 MontaVista Software
+ * Copyright (C) 2004 Texas Instruments
+ * Copyright (C) 2005 Dirk Behme
+ */
+
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ad7877.h>
+#include <asm/irq.h>
+
+#define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50)
+
+#define MAX_SPI_FREQ_HZ 20000000
+#define MAX_12BIT ((1<<12)-1)
+
+#define AD7877_REG_ZEROS 0
+#define AD7877_REG_CTRL1 1
+#define AD7877_REG_CTRL2 2
+#define AD7877_REG_ALERT 3
+#define AD7877_REG_AUX1HIGH 4
+#define AD7877_REG_AUX1LOW 5
+#define AD7877_REG_BAT1HIGH 6
+#define AD7877_REG_BAT1LOW 7
+#define AD7877_REG_BAT2HIGH 8
+#define AD7877_REG_BAT2LOW 9
+#define AD7877_REG_TEMP1HIGH 10
+#define AD7877_REG_TEMP1LOW 11
+#define AD7877_REG_SEQ0 12
+#define AD7877_REG_SEQ1 13
+#define AD7877_REG_DAC 14
+#define AD7877_REG_NONE1 15
+#define AD7877_REG_EXTWRITE 15
+#define AD7877_REG_XPLUS 16
+#define AD7877_REG_YPLUS 17
+#define AD7877_REG_Z2 18
+#define AD7877_REG_aux1 19
+#define AD7877_REG_aux2 20
+#define AD7877_REG_aux3 21
+#define AD7877_REG_bat1 22
+#define AD7877_REG_bat2 23
+#define AD7877_REG_temp1 24
+#define AD7877_REG_temp2 25
+#define AD7877_REG_Z1 26
+#define AD7877_REG_GPIOCTRL1 27
+#define AD7877_REG_GPIOCTRL2 28
+#define AD7877_REG_GPIODATA 29
+#define AD7877_REG_NONE2 30
+#define AD7877_REG_NONE3 31
+
+#define AD7877_SEQ_YPLUS_BIT (1<<11)
+#define AD7877_SEQ_XPLUS_BIT (1<<10)
+#define AD7877_SEQ_Z2_BIT (1<<9)
+#define AD7877_SEQ_AUX1_BIT (1<<8)
+#define AD7877_SEQ_AUX2_BIT (1<<7)
+#define AD7877_SEQ_AUX3_BIT (1<<6)
+#define AD7877_SEQ_BAT1_BIT (1<<5)
+#define AD7877_SEQ_BAT2_BIT (1<<4)
+#define AD7877_SEQ_TEMP1_BIT (1<<3)
+#define AD7877_SEQ_TEMP2_BIT (1<<2)
+#define AD7877_SEQ_Z1_BIT (1<<1)
+
+enum {
+ AD7877_SEQ_YPOS = 0,
+ AD7877_SEQ_XPOS = 1,
+ AD7877_SEQ_Z2 = 2,
+ AD7877_SEQ_AUX1 = 3,
+ AD7877_SEQ_AUX2 = 4,
+ AD7877_SEQ_AUX3 = 5,
+ AD7877_SEQ_BAT1 = 6,
+ AD7877_SEQ_BAT2 = 7,
+ AD7877_SEQ_TEMP1 = 8,
+ AD7877_SEQ_TEMP2 = 9,
+ AD7877_SEQ_Z1 = 10,
+ AD7877_NR_SENSE = 11,
+};
+
+/* DAC Register Default RANGE 0 to Vcc, Volatge Mode, DAC On */
+#define AD7877_DAC_CONF 0x1
+
+/* If gpio3 is set AUX3/GPIO3 acts as GPIO Output */
+#define AD7877_EXTW_GPIO_3_CONF 0x1C4
+#define AD7877_EXTW_GPIO_DATA 0x200
+
+/* Control REG 2 */
+#define AD7877_TMR(x) ((x & 0x3) << 0)
+#define AD7877_REF(x) ((x & 0x1) << 2)
+#define AD7877_POL(x) ((x & 0x1) << 3)
+#define AD7877_FCD(x) ((x & 0x3) << 4)
+#define AD7877_PM(x) ((x & 0x3) << 6)
+#define AD7877_ACQ(x) ((x & 0x3) << 8)
+#define AD7877_AVG(x) ((x & 0x3) << 10)
+
+/* Control REG 1 */
+#define AD7877_SER (1 << 11) /* non-differential */
+#define AD7877_DFR (0 << 11) /* differential */
+
+#define AD7877_MODE_NOC (0) /* Do not convert */
+#define AD7877_MODE_SCC (1) /* Single channel conversion */
+#define AD7877_MODE_SEQ0 (2) /* Sequence 0 in Slave Mode */
+#define AD7877_MODE_SEQ1 (3) /* Sequence 1 in Master Mode */
+
+#define AD7877_CHANADD(x) ((x&0xF)<<7)
+#define AD7877_READADD(x) ((x)<<2)
+#define AD7877_WRITEADD(x) ((x)<<12)
+
+#define AD7877_READ_CHAN(x) (AD7877_WRITEADD(AD7877_REG_CTRL1) | AD7877_SER | \
+ AD7877_MODE_SCC | AD7877_CHANADD(AD7877_REG_ ## x) | \
+ AD7877_READADD(AD7877_REG_ ## x))
+
+#define AD7877_MM_SEQUENCE (AD7877_SEQ_YPLUS_BIT | AD7877_SEQ_XPLUS_BIT | \
+ AD7877_SEQ_Z2_BIT | AD7877_SEQ_Z1_BIT)
+
+/*
+ * Non-touchscreen sensors only use single-ended conversions.
+ */
+
+struct ser_req {
+ u16 reset;
+ u16 ref_on;
+ u16 command;
+ u16 sample;
+ struct spi_message msg;
+ struct spi_transfer xfer[6];
+};
+
+struct ad7877 {
+ struct input_dev *input;
+ char phys[32];
+
+ struct spi_device *spi;
+ u16 model;
+ u16 vref_delay_usecs;
+ u16 x_plate_ohms;
+ u16 pressure_max;
+
+ u16 cmd_crtl1;
+ u16 cmd_crtl2;
+ u16 cmd_dummy;
+ u16 dac;
+
+ u8 stopacq_polarity;
+ u8 first_conversion_delay;
+ u8 acquisition_time;
+ u8 averaging;
+ u8 pen_down_acc_interval;
+
+ u16 conversion_data[AD7877_NR_SENSE];
+
+ struct spi_transfer xfer[AD7877_NR_SENSE + 2];
+ struct spi_message msg;
+
+ struct mutex mutex;
+ unsigned disabled:1; /* P: mutex */
+ unsigned gpio3:1; /* P: mutex */
+ unsigned gpio4:1; /* P: mutex */
+
+ spinlock_t lock;
+ struct timer_list timer; /* P: lock */
+ unsigned pending:1; /* P: lock */
+};
+
+static int gpio3;
+module_param(gpio3, int, 0);
+MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3");
+
+/*
+ * ad7877_read/write are only used for initial setup and for sysfs controls.
+ * The main traffic is done using spi_async() in the interrupt handler.
+ */
+
+static int ad7877_read(struct spi_device *spi, u16 reg)
+{
+ struct ser_req *req;
+ int status, ret;
+
+ req = kzalloc(sizeof *req, GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ spi_message_init(&req->msg);
+
+ req->command = (u16) (AD7877_WRITEADD(AD7877_REG_CTRL1) |
+ AD7877_READADD(reg));
+ req->xfer[0].tx_buf = &req->command;
+ req->xfer[0].len = 2;
+
+ req->xfer[1].rx_buf = &req->sample;
+ req->xfer[1].len = 2;
+
+ spi_message_add_tail(&req->xfer[0], &req->msg);
+ spi_message_add_tail(&req->xfer[1], &req->msg);
+
+ status = spi_sync(spi, &req->msg);
+ ret = status ? : req->sample;
+
+ kfree(req);
+
+ return ret;
+}
+
+static int ad7877_write(struct spi_device *spi, u16 reg, u16 val)
+{
+ struct ser_req *req;
+ int status;
+
+ req = kzalloc(sizeof *req, GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ spi_message_init(&req->msg);
+
+ req->command = (u16) (AD7877_WRITEADD(reg) | (val & MAX_12BIT));
+ req->xfer[0].tx_buf = &req->command;
+ req->xfer[0].len = 2;
+
+ spi_message_add_tail(&req->xfer[0], &req->msg);
+
+ status = spi_sync(spi, &req->msg);
+
+ kfree(req);
+
+ return status;
+}
+
+static int ad7877_read_adc(struct spi_device *spi, unsigned command)
+{
+ struct ad7877 *ts = dev_get_drvdata(&spi->dev);
+ struct ser_req *req;
+ int status;
+ int sample;
+ int i;
+
+ req = kzalloc(sizeof *req, GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ spi_message_init(&req->msg);
+
+ /* activate reference, so it has time to settle; */
+ req->ref_on = AD7877_WRITEADD(AD7877_REG_CTRL2) |
+ AD7877_POL(ts->stopacq_polarity) |
+ AD7877_AVG(0) | AD7877_PM(2) | AD7877_TMR(0) |
+ AD7877_ACQ(ts->acquisition_time) | AD7877_FCD(0);
+
+ req->reset = AD7877_WRITEADD(AD7877_REG_CTRL1) | AD7877_MODE_NOC;
+
+ req->command = (u16) command;
+
+ req->xfer[0].tx_buf = &req->reset;
+ req->xfer[0].len = 2;
+
+ req->xfer[1].tx_buf = &req->ref_on;
+ req->xfer[1].len = 2;
+ req->xfer[1].delay_usecs = ts->vref_delay_usecs;
+
+ req->xfer[2].tx_buf = &req->command;
+ req->xfer[2].len = 2;
+ req->xfer[2].delay_usecs = ts->vref_delay_usecs;
+
+ req->xfer[3].rx_buf = &req->sample;
+ req->xfer[3].len = 2;
+
+ req->xfer[4].tx_buf = &ts->cmd_crtl2; /*REF OFF*/
+ req->xfer[4].len = 2;
+
+ req->xfer[5].tx_buf = &ts->cmd_crtl1; /*DEFAULT*/
+ req->xfer[5].len = 2;
+
+ /* group all the transfers together, so we can't interfere with
+ * reading touchscreen state; disable penirq while sampling
+ */
+ for (i = 0; i < 6; i++)
+ spi_message_add_tail(&req->xfer[i], &req->msg);
+
+ status = spi_sync(spi, &req->msg);
+ sample = req->sample;
+
+ kfree(req);
+
+ return status ? : sample;
+}
+
+static void ad7877_rx(struct ad7877 *ts)
+{
+ struct input_dev *input_dev = ts->input;
+ unsigned Rt;
+ u16 x, y, z1, z2;
+
+ x = ts->conversion_data[AD7877_SEQ_XPOS] & MAX_12BIT;
+ y = ts->conversion_data[AD7877_SEQ_YPOS] & MAX_12BIT;
+ z1 = ts->conversion_data[AD7877_SEQ_Z1] & MAX_12BIT;
+ z2 = ts->conversion_data[AD7877_SEQ_Z2] & MAX_12BIT;
+
+ /*
+ * The samples processed here are already preprocessed by the AD7877.
+ * The preprocessing function consists of an averaging filter.
+ * The combination of 'first conversion delay' and averaging provides a robust solution,
+ * discarding the spurious noise in the signal and keeping only the data of interest.
+ * The size of the averaging filter is programmable. (dev.platform_data, see linux/spi/ad7877.h)
+ * Other user-programmable conversion controls include variable acquisition time,
+ * and first conversion delay. Up to 16 averages can be taken per conversion.
+ */
+
+ if (likely(x && z1)) {
+ /* compute touch pressure resistance using equation #1 */
+ Rt = (z2 - z1) * x * ts->x_plate_ohms;
+ Rt /= z1;
+ Rt = (Rt + 2047) >> 12;
+
+ input_report_abs(input_dev, ABS_X, x);
+ input_report_abs(input_dev, ABS_Y, y);
+ input_report_abs(input_dev, ABS_PRESSURE, Rt);
+ input_sync(input_dev);
+ }
+}
+
+static inline void ad7877_ts_event_release(struct ad7877 *ts)
+{
+ struct input_dev *input_dev = ts->input;
+
+ input_report_abs(input_dev, ABS_PRESSURE, 0);
+ input_sync(input_dev);
+}
+
+static void ad7877_timer(unsigned long handle)
+{
+ struct ad7877 *ts = (void *)handle;
+
+ ad7877_ts_event_release(ts);
+}
+
+static irqreturn_t ad7877_irq(int irq, void *handle)
+{
+ struct ad7877 *ts = handle;
+ unsigned long flags;
+ int status;
+
+ /*
+ * The repeated conversion sequencer controlled by TMR kicked off
+ * too fast. We ignore the last and process the sample sequence
+ * currently in the queue. It can't be older than 9.4ms, and we
+ * need to avoid that ts->msg doesn't get issued twice while in work.
+ */
+
+ spin_lock_irqsave(&ts->lock, flags);
+ if (!ts->pending) {
+ ts->pending = 1;
+
+ status = spi_async(ts->spi, &ts->msg);
+ if (status)
+ dev_err(&ts->spi->dev, "spi_sync --> %d\n", status);
+ }
+ spin_unlock_irqrestore(&ts->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static void ad7877_callback(void *_ts)
+{
+ struct ad7877 *ts = _ts;
+
+ spin_lock_irq(&ts->lock);
+
+ ad7877_rx(ts);
+ ts->pending = 0;
+ mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT);
+
+ spin_unlock_irq(&ts->lock);
+}
+
+static void ad7877_disable(struct ad7877 *ts)
+{
+ mutex_lock(&ts->mutex);
+
+ if (!ts->disabled) {
+ ts->disabled = 1;
+ disable_irq(ts->spi->irq);
+
+ /* Wait for spi_async callback */
+ while (ts->pending)
+ msleep(1);
+
+ if (del_timer_sync(&ts->timer))
+ ad7877_ts_event_release(ts);
+ }
+
+ /* we know the chip's in lowpower mode since we always
+ * leave it that way after every request
+ */
+
+ mutex_unlock(&ts->mutex);
+}
+
+static void ad7877_enable(struct ad7877 *ts)
+{
+ mutex_lock(&ts->mutex);
+
+ if (ts->disabled) {
+ ts->disabled = 0;
+ enable_irq(ts->spi->irq);
+ }
+
+ mutex_unlock(&ts->mutex);
+}
+
+#define SHOW(name) static ssize_t \
+name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+ struct ad7877 *ts = dev_get_drvdata(dev); \
+ ssize_t v = ad7877_read_adc(ts->spi, \
+ AD7877_READ_CHAN(name)); \
+ if (v < 0) \
+ return v; \
+ return sprintf(buf, "%u\n", (unsigned) v); \
+} \
+static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
+
+SHOW(aux1)
+SHOW(aux2)
+SHOW(aux3)
+SHOW(bat1)
+SHOW(bat2)
+SHOW(temp1)
+SHOW(temp2)
+
+static ssize_t ad7877_disable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ad7877 *ts = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", ts->disabled);
+}
+
+static ssize_t ad7877_disable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ad7877 *ts = dev_get_drvdata(dev);
+ unsigned long val;
+ int error;
+
+ error = strict_strtoul(buf, 10, &val);
+ if (error)
+ return error;
+
+ if (val)
+ ad7877_disable(ts);
+ else
+ ad7877_enable(ts);
+
+ return count;
+}
+
+static DEVICE_ATTR(disable, 0664, ad7877_disable_show, ad7877_disable_store);
+
+static ssize_t ad7877_dac_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ad7877 *ts = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", ts->dac);
+}
+
+static ssize_t ad7877_dac_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ad7877 *ts = dev_get_drvdata(dev);
+ unsigned long val;
+ int error;
+
+ error = strict_strtoul(buf, 10, &val);
+ if (error)
+ return error;
+
+ mutex_lock(&ts->mutex);
+ ts->dac = val & 0xFF;
+ ad7877_write(ts->spi, AD7877_REG_DAC, (ts->dac << 4) | AD7877_DAC_CONF);
+ mutex_unlock(&ts->mutex);
+
+ return count;
+}
+
+static DEVICE_ATTR(dac, 0664, ad7877_dac_show, ad7877_dac_store);
+
+static ssize_t ad7877_gpio3_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ad7877 *ts = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", ts->gpio3);
+}
+
+static ssize_t ad7877_gpio3_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ad7877 *ts = dev_get_drvdata(dev);
+ unsigned long val;
+ int error;
+
+ error = strict_strtoul(buf, 10, &val);
+ if (error)
+ return error;
+
+ mutex_lock(&ts->mutex);
+ ts->gpio3 = !!val;
+ ad7877_write(ts->spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_DATA |
+ (ts->gpio4 << 4) | (ts->gpio3 << 5));
+ mutex_unlock(&ts->mutex);
+
+ return count;
+}
+
+static DEVICE_ATTR(gpio3, 0664, ad7877_gpio3_show, ad7877_gpio3_store);
+
+static ssize_t ad7877_gpio4_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ad7877 *ts = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", ts->gpio4);
+}
+
+static ssize_t ad7877_gpio4_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ad7877 *ts = dev_get_drvdata(dev);
+ unsigned long val;
+ int error;
+
+ error = strict_strtoul(buf, 10, &val);
+ if (error)
+ return error;
+
+ mutex_lock(&ts->mutex);
+ ts->gpio4 = !!val;
+ ad7877_write(ts->spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_DATA |
+ (ts->gpio4 << 4) | (ts->gpio3 << 5));
+ mutex_unlock(&ts->mutex);
+
+ return count;
+}
+
+static DEVICE_ATTR(gpio4, 0664, ad7877_gpio4_show, ad7877_gpio4_store);
+
+static struct attribute *ad7877_attributes[] = {
+ &dev_attr_temp1.attr,
+ &dev_attr_temp2.attr,
+ &dev_attr_aux1.attr,
+ &dev_attr_aux2.attr,
+ &dev_attr_bat1.attr,
+ &dev_attr_bat2.attr,
+ &dev_attr_disable.attr,
+ &dev_attr_dac.attr,
+ &dev_attr_gpio4.attr,
+ NULL
+};
+
+static const struct attribute_group ad7877_attr_group = {
+ .attrs = ad7877_attributes,
+};
+
+static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts)
+{
+ struct spi_message *m;
+ int i;
+
+ ts->cmd_crtl2 = AD7877_WRITEADD(AD7877_REG_CTRL2) |
+ AD7877_POL(ts->stopacq_polarity) |
+ AD7877_AVG(ts->averaging) | AD7877_PM(1) |
+ AD7877_TMR(ts->pen_down_acc_interval) |
+ AD7877_ACQ(ts->acquisition_time) |
+ AD7877_FCD(ts->first_conversion_delay);
+
+ ad7877_write(spi, AD7877_REG_CTRL2, ts->cmd_crtl2);
+
+ ts->cmd_crtl1 = AD7877_WRITEADD(AD7877_REG_CTRL1) |
+ AD7877_READADD(AD7877_REG_XPLUS-1) |
+ AD7877_MODE_SEQ1 | AD7877_DFR;
+
+ ad7877_write(spi, AD7877_REG_CTRL1, ts->cmd_crtl1);
+
+ ts->cmd_dummy = 0;
+
+ m = &ts->msg;
+
+ spi_message_init(m);
+
+ m->complete = ad7877_callback;
+ m->context = ts;
+
+ ts->xfer[0].tx_buf = &ts->cmd_crtl1;
+ ts->xfer[0].len = 2;
+
+ spi_message_add_tail(&ts->xfer[0], m);
+
+ ts->xfer[1].tx_buf = &ts->cmd_dummy; /* Send ZERO */
+ ts->xfer[1].len = 2;
+
+ spi_message_add_tail(&ts->xfer[1], m);
+
+ for (i = 0; i < 11; i++) {
+ ts->xfer[i + 2].rx_buf = &ts->conversion_data[AD7877_SEQ_YPOS + i];
+ ts->xfer[i + 2].len = 2;
+ spi_message_add_tail(&ts->xfer[i + 2], m);
+ }
+}
+
+static int __devinit ad7877_probe(struct spi_device *spi)
+{
+ struct ad7877 *ts;
+ struct input_dev *input_dev;
+ struct ad7877_platform_data *pdata = spi->dev.platform_data;
+ int err;
+ u16 verify;
+
+ if (!spi->irq) {
+ dev_dbg(&spi->dev, "no IRQ?\n");
+ return -ENODEV;
+ }
+
+ if (!pdata) {
+ dev_dbg(&spi->dev, "no platform data?\n");
+ return -ENODEV;
+ }
+
+ /* don't exceed max specified SPI CLK frequency */
+ if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) {
+ dev_dbg(&spi->dev, "SPI CLK %d Hz?\n",spi->max_speed_hz);
+ return -EINVAL;
+ }
+
+ ts = kzalloc(sizeof(struct ad7877), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!ts || !input_dev) {
+ err = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ dev_set_drvdata(&spi->dev, ts);
+ ts->spi = spi;
+ ts->input = input_dev;
+
+ setup_timer(&ts->timer, ad7877_timer, (unsigned long) ts);
+ mutex_init(&ts->mutex);
+ spin_lock_init(&ts->lock);
+
+ ts->model = pdata->model ? : 7877;
+ ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
+ ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
+ ts->pressure_max = pdata->pressure_max ? : ~0;
+
+ ts->stopacq_polarity = pdata->stopacq_polarity;
+ ts->first_conversion_delay = pdata->first_conversion_delay;
+ ts->acquisition_time = pdata->acquisition_time;
+ ts->averaging = pdata->averaging;
+ ts->pen_down_acc_interval = pdata->pen_down_acc_interval;
+
+ snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev));
+
+ input_dev->name = "AD7877 Touchscreen";
+ input_dev->phys = ts->phys;
+ input_dev->dev.parent = &spi->dev;
+
+ __set_bit(EV_ABS, input_dev->evbit);
+ __set_bit(ABS_X, input_dev->absbit);
+ __set_bit(ABS_Y, input_dev->absbit);
+ __set_bit(ABS_PRESSURE, input_dev->absbit);
+
+ input_set_abs_params(input_dev, ABS_X,
+ pdata->x_min ? : 0,
+ pdata->x_max ? : MAX_12BIT,
+ 0, 0);
+ input_set_abs_params(input_dev, ABS_Y,
+ pdata->y_min ? : 0,
+ pdata->y_max ? : MAX_12BIT,
+ 0, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE,
+ pdata->pressure_min, pdata->pressure_max, 0, 0);
+
+ ad7877_write(spi, AD7877_REG_SEQ1, AD7877_MM_SEQUENCE);
+
+ verify = ad7877_read(spi, AD7877_REG_SEQ1);
+
+ if (verify != AD7877_MM_SEQUENCE){
+ dev_err(&spi->dev, "%s: Failed to probe %s\n",
+ dev_name(&spi->dev), input_dev->name);
+ err = -ENODEV;
+ goto err_free_mem;
+ }
+
+ if (gpio3)
+ ad7877_write(spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_3_CONF);
+
+ ad7877_setup_ts_def_msg(spi, ts);
+
+ /* Request AD7877 /DAV GPIO interrupt */
+
+ err = request_irq(spi->irq, ad7877_irq, IRQF_TRIGGER_FALLING |
+ IRQF_SAMPLE_RANDOM, spi->dev.driver->name, ts);
+ if (err) {
+ dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
+ goto err_free_mem;
+ }
+
+ err = sysfs_create_group(&spi->dev.kobj, &ad7877_attr_group);
+ if (err)
+ goto err_free_irq;
+
+ err = device_create_file(&spi->dev,
+ gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3);
+ if (err)
+ goto err_remove_attr_group;
+
+ err = input_register_device(input_dev);
+ if (err)
+ goto err_remove_attr;
+
+ return 0;
+
+err_remove_attr:
+ device_remove_file(&spi->dev,
+ gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3);
+err_remove_attr_group:
+ sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group);
+err_free_irq:
+ free_irq(spi->irq, ts);
+err_free_mem:
+ input_free_device(input_dev);
+ kfree(ts);
+ dev_set_drvdata(&spi->dev, NULL);
+ return err;
+}
+
+static int __devexit ad7877_remove(struct spi_device *spi)
+{
+ struct ad7877 *ts = dev_get_drvdata(&spi->dev);
+
+ sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group);
+ device_remove_file(&spi->dev,
+ gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3);
+
+ ad7877_disable(ts);
+ free_irq(ts->spi->irq, ts);
+
+ input_unregister_device(ts->input);
+ kfree(ts);
+
+ dev_dbg(&spi->dev, "unregistered touchscreen\n");
+ dev_set_drvdata(&spi->dev, NULL);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ad7877_suspend(struct spi_device *spi, pm_message_t message)
+{
+ struct ad7877 *ts = dev_get_drvdata(&spi->dev);
+
+ ad7877_disable(ts);
+
+ return 0;
+}
+
+static int ad7877_resume(struct spi_device *spi)
+{
+ struct ad7877 *ts = dev_get_drvdata(&spi->dev);
+
+ ad7877_enable(ts);
+
+ return 0;
+}
+#else
+#define ad7877_suspend NULL
+#define ad7877_resume NULL
+#endif
+
+static struct spi_driver ad7877_driver = {
+ .driver = {
+ .name = "ad7877",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = ad7877_probe,
+ .remove = __devexit_p(ad7877_remove),
+ .suspend = ad7877_suspend,
+ .resume = ad7877_resume,
+};
+
+static int __init ad7877_init(void)
+{
+ return spi_register_driver(&ad7877_driver);
+}
+module_init(ad7877_init);
+
+static void __exit ad7877_exit(void)
+{
+ spi_unregister_driver(&ad7877_driver);
+}
+module_exit(ad7877_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("AD7877 touchscreen Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c
new file mode 100644
index 00000000000..ea4c61d6868
--- /dev/null
+++ b/drivers/input/touchscreen/ad7879.c
@@ -0,0 +1,782 @@
+/*
+ * Copyright (C) 2008 Michael Hennerich, Analog Devices Inc.
+ *
+ * Description: AD7879 based touchscreen, and GPIO driver (I2C/SPI Interface)
+ *
+ * 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
+ *
+ * History:
+ * Copyright (c) 2005 David Brownell
+ * Copyright (c) 2006 Nokia Corporation
+ * Various changes: Imre Deak <imre.deak@nokia.com>
+ *
+ * Using code from:
+ * - corgi_ts.c
+ * Copyright (C) 2004-2005 Richard Purdie
+ * - omap_ts.[hc], ads7846.h, ts_osk.c
+ * Copyright (C) 2002 MontaVista Software
+ * Copyright (C) 2004 Texas Instruments
+ * Copyright (C) 2005 Dirk Behme
+ * - ad7877.c
+ * Copyright (C) 2006-2008 Analog Devices Inc.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+
+#include <linux/spi/ad7879.h>
+
+#define AD7879_REG_ZEROS 0
+#define AD7879_REG_CTRL1 1
+#define AD7879_REG_CTRL2 2
+#define AD7879_REG_CTRL3 3
+#define AD7879_REG_AUX1HIGH 4
+#define AD7879_REG_AUX1LOW 5
+#define AD7879_REG_TEMP1HIGH 6
+#define AD7879_REG_TEMP1LOW 7
+#define AD7879_REG_XPLUS 8
+#define AD7879_REG_YPLUS 9
+#define AD7879_REG_Z1 10
+#define AD7879_REG_Z2 11
+#define AD7879_REG_AUXVBAT 12
+#define AD7879_REG_TEMP 13
+#define AD7879_REG_REVID 14
+
+/* Control REG 1 */
+#define AD7879_TMR(x) ((x & 0xFF) << 0)
+#define AD7879_ACQ(x) ((x & 0x3) << 8)
+#define AD7879_MODE_NOC (0 << 10) /* Do not convert */
+#define AD7879_MODE_SCC (1 << 10) /* Single channel conversion */
+#define AD7879_MODE_SEQ0 (2 << 10) /* Sequence 0 in Slave Mode */
+#define AD7879_MODE_SEQ1 (3 << 10) /* Sequence 1 in Master Mode */
+#define AD7879_MODE_INT (1 << 15) /* PENIRQ disabled INT enabled */
+
+/* Control REG 2 */
+#define AD7879_FCD(x) ((x & 0x3) << 0)
+#define AD7879_RESET (1 << 4)
+#define AD7879_MFS(x) ((x & 0x3) << 5)
+#define AD7879_AVG(x) ((x & 0x3) << 7)
+#define AD7879_SER (1 << 9) /* non-differential */
+#define AD7879_DFR (0 << 9) /* differential */
+#define AD7879_GPIOPOL (1 << 10)
+#define AD7879_GPIODIR (1 << 11)
+#define AD7879_GPIO_DATA (1 << 12)
+#define AD7879_GPIO_EN (1 << 13)
+#define AD7879_PM(x) ((x & 0x3) << 14)
+#define AD7879_PM_SHUTDOWN (0)
+#define AD7879_PM_DYN (1)
+#define AD7879_PM_FULLON (2)
+
+/* Control REG 3 */
+#define AD7879_TEMPMASK_BIT (1<<15)
+#define AD7879_AUXVBATMASK_BIT (1<<14)
+#define AD7879_INTMODE_BIT (1<<13)
+#define AD7879_GPIOALERTMASK_BIT (1<<12)
+#define AD7879_AUXLOW_BIT (1<<11)
+#define AD7879_AUXHIGH_BIT (1<<10)
+#define AD7879_TEMPLOW_BIT (1<<9)
+#define AD7879_TEMPHIGH_BIT (1<<8)
+#define AD7879_YPLUS_BIT (1<<7)
+#define AD7879_XPLUS_BIT (1<<6)
+#define AD7879_Z1_BIT (1<<5)
+#define AD7879_Z2_BIT (1<<4)
+#define AD7879_AUX_BIT (1<<3)
+#define AD7879_VBAT_BIT (1<<2)
+#define AD7879_TEMP_BIT (1<<1)
+
+enum {
+ AD7879_SEQ_XPOS = 0,
+ AD7879_SEQ_YPOS = 1,
+ AD7879_SEQ_Z1 = 2,
+ AD7879_SEQ_Z2 = 3,
+ AD7879_NR_SENSE = 4,
+};
+
+#define MAX_12BIT ((1<<12)-1)
+#define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50)
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+#define AD7879_DEVID 0x7A
+typedef struct spi_device bus_device;
+#elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+#define AD7879_DEVID 0x79
+typedef struct i2c_client bus_device;
+#endif
+
+struct ad7879 {
+ bus_device *bus;
+ struct input_dev *input;
+ struct work_struct work;
+ struct timer_list timer;
+
+ struct mutex mutex;
+ unsigned disabled:1; /* P: mutex */
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+ struct spi_message msg;
+ struct spi_transfer xfer[AD7879_NR_SENSE + 1];
+ u16 cmd;
+#endif
+ u16 conversion_data[AD7879_NR_SENSE];
+ char phys[32];
+ u8 first_conversion_delay;
+ u8 acquisition_time;
+ u8 averaging;
+ u8 pen_down_acc_interval;
+ u8 median;
+ u16 x_plate_ohms;
+ u16 pressure_max;
+ u16 gpio_init;
+ u16 cmd_crtl1;
+ u16 cmd_crtl2;
+ u16 cmd_crtl3;
+ unsigned gpio:1;
+};
+
+static int ad7879_read(bus_device *, u8);
+static int ad7879_write(bus_device *, u8, u16);
+static void ad7879_collect(struct ad7879 *);
+
+static void ad7879_report(struct ad7879 *ts)
+{
+ struct input_dev *input_dev = ts->input;
+ unsigned Rt;
+ u16 x, y, z1, z2;
+
+ x = ts->conversion_data[AD7879_SEQ_XPOS] & MAX_12BIT;
+ y = ts->conversion_data[AD7879_SEQ_YPOS] & MAX_12BIT;
+ z1 = ts->conversion_data[AD7879_SEQ_Z1] & MAX_12BIT;
+ z2 = ts->conversion_data[AD7879_SEQ_Z2] & MAX_12BIT;
+
+ /*
+ * The samples processed here are already preprocessed by the AD7879.
+ * The preprocessing function consists of a median and an averaging filter.
+ * The combination of these two techniques provides a robust solution,
+ * discarding the spurious noise in the signal and keeping only the data of interest.
+ * The size of both filters is programmable. (dev.platform_data, see linux/spi/ad7879.h)
+ * Other user-programmable conversion controls include variable acquisition time,
+ * and first conversion delay. Up to 16 averages can be taken per conversion.
+ */
+
+ if (likely(x && z1)) {
+ /* compute touch pressure resistance using equation #1 */
+ Rt = (z2 - z1) * x * ts->x_plate_ohms;
+ Rt /= z1;
+ Rt = (Rt + 2047) >> 12;
+
+ input_report_abs(input_dev, ABS_X, x);
+ input_report_abs(input_dev, ABS_Y, y);
+ input_report_abs(input_dev, ABS_PRESSURE, Rt);
+ input_sync(input_dev);
+ }
+}
+
+static void ad7879_work(struct work_struct *work)
+{
+ struct ad7879 *ts = container_of(work, struct ad7879, work);
+
+ /* use keventd context to read the result registers */
+ ad7879_collect(ts);
+ ad7879_report(ts);
+ mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT);
+}
+
+static void ad7879_ts_event_release(struct ad7879 *ts)
+{
+ struct input_dev *input_dev = ts->input;
+
+ input_report_abs(input_dev, ABS_PRESSURE, 0);
+ input_sync(input_dev);
+}
+
+static void ad7879_timer(unsigned long handle)
+{
+ struct ad7879 *ts = (void *)handle;
+
+ ad7879_ts_event_release(ts);
+}
+
+static irqreturn_t ad7879_irq(int irq, void *handle)
+{
+ struct ad7879 *ts = handle;
+
+ /* The repeated conversion sequencer controlled by TMR kicked off too fast.
+ * We ignore the last and process the sample sequence currently in the queue.
+ * It can't be older than 9.4ms
+ */
+
+ if (!work_pending(&ts->work))
+ schedule_work(&ts->work);
+
+ return IRQ_HANDLED;
+}
+
+static void ad7879_setup(struct ad7879 *ts)
+{
+ ts->cmd_crtl3 = AD7879_YPLUS_BIT |
+ AD7879_XPLUS_BIT |
+ AD7879_Z2_BIT |
+ AD7879_Z1_BIT |
+ AD7879_TEMPMASK_BIT |
+ AD7879_AUXVBATMASK_BIT |
+ AD7879_GPIOALERTMASK_BIT;
+
+ ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR |
+ AD7879_AVG(ts->averaging) |
+ AD7879_MFS(ts->median) |
+ AD7879_FCD(ts->first_conversion_delay) |
+ ts->gpio_init;
+
+ ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 |
+ AD7879_ACQ(ts->acquisition_time) |
+ AD7879_TMR(ts->pen_down_acc_interval);
+
+ ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2);
+ ad7879_write(ts->bus, AD7879_REG_CTRL3, ts->cmd_crtl3);
+ ad7879_write(ts->bus, AD7879_REG_CTRL1, ts->cmd_crtl1);
+}
+
+static void ad7879_disable(struct ad7879 *ts)
+{
+ mutex_lock(&ts->mutex);
+
+ if (!ts->disabled) {
+
+ ts->disabled = 1;
+ disable_irq(ts->bus->irq);
+
+ cancel_work_sync(&ts->work);
+
+ if (del_timer_sync(&ts->timer))
+ ad7879_ts_event_release(ts);
+
+ ad7879_write(ts->bus, AD7879_REG_CTRL2,
+ AD7879_PM(AD7879_PM_SHUTDOWN));
+ }
+
+ mutex_unlock(&ts->mutex);
+}
+
+static void ad7879_enable(struct ad7879 *ts)
+{
+ mutex_lock(&ts->mutex);
+
+ if (ts->disabled) {
+ ad7879_setup(ts);
+ ts->disabled = 0;
+ enable_irq(ts->bus->irq);
+ }
+
+ mutex_unlock(&ts->mutex);
+}
+
+static ssize_t ad7879_disable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ad7879 *ts = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", ts->disabled);
+}
+
+static ssize_t ad7879_disable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ad7879 *ts = dev_get_drvdata(dev);
+ unsigned long val;
+ int error;
+
+ error = strict_strtoul(buf, 10, &val);
+ if (error)
+ return error;
+
+ if (val)
+ ad7879_disable(ts);
+ else
+ ad7879_enable(ts);
+
+ return count;
+}
+
+static DEVICE_ATTR(disable, 0664, ad7879_disable_show, ad7879_disable_store);
+
+static ssize_t ad7879_gpio_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ad7879 *ts = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", ts->gpio);
+}
+
+static ssize_t ad7879_gpio_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ad7879 *ts = dev_get_drvdata(dev);
+ unsigned long val;
+ int error;
+
+ error = strict_strtoul(buf, 10, &val);
+ if (error)
+ return error;
+
+ mutex_lock(&ts->mutex);
+ ts->gpio = !!val;
+ error = ad7879_write(ts->bus, AD7879_REG_CTRL2,
+ ts->gpio ?
+ ts->cmd_crtl2 & ~AD7879_GPIO_DATA :
+ ts->cmd_crtl2 | AD7879_GPIO_DATA);
+ mutex_unlock(&ts->mutex);
+
+ return error ? : count;
+}
+
+static DEVICE_ATTR(gpio, 0664, ad7879_gpio_show, ad7879_gpio_store);
+
+static struct attribute *ad7879_attributes[] = {
+ &dev_attr_disable.attr,
+ &dev_attr_gpio.attr,
+ NULL
+};
+
+static const struct attribute_group ad7879_attr_group = {
+ .attrs = ad7879_attributes,
+};
+
+static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts)
+{
+ struct input_dev *input_dev;
+ struct ad7879_platform_data *pdata = bus->dev.platform_data;
+ int err;
+ u16 revid;
+
+ if (!bus->irq) {
+ dev_err(&bus->dev, "no IRQ?\n");
+ return -ENODEV;
+ }
+
+ if (!pdata) {
+ dev_err(&bus->dev, "no platform data?\n");
+ return -ENODEV;
+ }
+
+ input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
+
+ ts->input = input_dev;
+
+ setup_timer(&ts->timer, ad7879_timer, (unsigned long) ts);
+ INIT_WORK(&ts->work, ad7879_work);
+ mutex_init(&ts->mutex);
+
+ ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
+ ts->pressure_max = pdata->pressure_max ? : ~0;
+
+ ts->first_conversion_delay = pdata->first_conversion_delay;
+ ts->acquisition_time = pdata->acquisition_time;
+ ts->averaging = pdata->averaging;
+ ts->pen_down_acc_interval = pdata->pen_down_acc_interval;
+ ts->median = pdata->median;
+
+ if (pdata->gpio_output)
+ ts->gpio_init = AD7879_GPIO_EN |
+ (pdata->gpio_default ? 0 : AD7879_GPIO_DATA);
+ else
+ ts->gpio_init = AD7879_GPIO_EN | AD7879_GPIODIR;
+
+ snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&bus->dev));
+
+ input_dev->name = "AD7879 Touchscreen";
+ input_dev->phys = ts->phys;
+ input_dev->dev.parent = &bus->dev;
+
+ __set_bit(EV_ABS, input_dev->evbit);
+ __set_bit(ABS_X, input_dev->absbit);
+ __set_bit(ABS_Y, input_dev->absbit);
+ __set_bit(ABS_PRESSURE, input_dev->absbit);
+
+ input_set_abs_params(input_dev, ABS_X,
+ pdata->x_min ? : 0,
+ pdata->x_max ? : MAX_12BIT,
+ 0, 0);
+ input_set_abs_params(input_dev, ABS_Y,
+ pdata->y_min ? : 0,
+ pdata->y_max ? : MAX_12BIT,
+ 0, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE,
+ pdata->pressure_min, pdata->pressure_max, 0, 0);
+
+ err = ad7879_write(bus, AD7879_REG_CTRL2, AD7879_RESET);
+
+ if (err < 0) {
+ dev_err(&bus->dev, "Failed to write %s\n", input_dev->name);
+ goto err_free_mem;
+ }
+
+ revid = ad7879_read(bus, AD7879_REG_REVID);
+
+ if ((revid & 0xFF) != AD7879_DEVID) {
+ dev_err(&bus->dev, "Failed to probe %s\n", input_dev->name);
+ err = -ENODEV;
+ goto err_free_mem;
+ }
+
+ ad7879_setup(ts);
+
+ err = request_irq(bus->irq, ad7879_irq,
+ IRQF_TRIGGER_FALLING | IRQF_SAMPLE_RANDOM,
+ bus->dev.driver->name, ts);
+
+ if (err) {
+ dev_err(&bus->dev, "irq %d busy?\n", bus->irq);
+ goto err_free_mem;
+ }
+
+ err = sysfs_create_group(&bus->dev.kobj, &ad7879_attr_group);
+ if (err)
+ goto err_free_irq;
+
+ err = input_register_device(input_dev);
+ if (err)
+ goto err_remove_attr;
+
+ dev_info(&bus->dev, "Rev.%d touchscreen, irq %d\n",
+ revid >> 8, bus->irq);
+
+ return 0;
+
+err_remove_attr:
+ sysfs_remove_group(&bus->dev.kobj, &ad7879_attr_group);
+err_free_irq:
+ free_irq(bus->irq, ts);
+err_free_mem:
+ input_free_device(input_dev);
+
+ return err;
+}
+
+static int __devexit ad7879_destroy(bus_device *bus, struct ad7879 *ts)
+{
+ ad7879_disable(ts);
+ sysfs_remove_group(&ts->bus->dev.kobj, &ad7879_attr_group);
+ free_irq(ts->bus->irq, ts);
+ input_unregister_device(ts->input);
+ dev_dbg(&bus->dev, "unregistered touchscreen\n");
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ad7879_suspend(bus_device *bus, pm_message_t message)
+{
+ struct ad7879 *ts = dev_get_drvdata(&bus->dev);
+
+ ad7879_disable(ts);
+
+ return 0;
+}
+
+static int ad7879_resume(bus_device *bus)
+{
+ struct ad7879 *ts = dev_get_drvdata(&bus->dev);
+
+ ad7879_enable(ts);
+
+ return 0;
+}
+#else
+#define ad7879_suspend NULL
+#define ad7879_resume NULL
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+#define MAX_SPI_FREQ_HZ 5000000
+#define AD7879_CMD_MAGIC 0xE000
+#define AD7879_CMD_READ (1 << 10)
+#define AD7879_WRITECMD(reg) (AD7879_CMD_MAGIC | (reg & 0xF))
+#define AD7879_READCMD(reg) (AD7879_CMD_MAGIC | AD7879_CMD_READ | (reg & 0xF))
+
+struct ser_req {
+ u16 command;
+ u16 data;
+ struct spi_message msg;
+ struct spi_transfer xfer[2];
+};
+
+/*
+ * ad7879_read/write are only used for initial setup and for sysfs controls.
+ * The main traffic is done in ad7879_collect().
+ */
+
+static int ad7879_read(struct spi_device *spi, u8 reg)
+{
+ struct ser_req *req;
+ int status, ret;
+
+ req = kzalloc(sizeof *req, GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ spi_message_init(&req->msg);
+
+ req->command = (u16) AD7879_READCMD(reg);
+ req->xfer[0].tx_buf = &req->command;
+ req->xfer[0].len = 2;
+
+ req->xfer[1].rx_buf = &req->data;
+ req->xfer[1].len = 2;
+
+ spi_message_add_tail(&req->xfer[0], &req->msg);
+ spi_message_add_tail(&req->xfer[1], &req->msg);
+
+ status = spi_sync(spi, &req->msg);
+ ret = status ? : req->data;
+
+ kfree(req);
+
+ return ret;
+}
+
+static int ad7879_write(struct spi_device *spi, u8 reg, u16 val)
+{
+ struct ser_req *req;
+ int status;
+
+ req = kzalloc(sizeof *req, GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ spi_message_init(&req->msg);
+
+ req->command = (u16) AD7879_WRITECMD(reg);
+ req->xfer[0].tx_buf = &req->command;
+ req->xfer[0].len = 2;
+
+ req->data = val;
+ req->xfer[1].tx_buf = &req->data;
+ req->xfer[1].len = 2;
+
+ spi_message_add_tail(&req->xfer[0], &req->msg);
+ spi_message_add_tail(&req->xfer[1], &req->msg);
+
+ status = spi_sync(spi, &req->msg);
+
+ kfree(req);
+
+ return status;
+}
+
+static void ad7879_collect(struct ad7879 *ts)
+{
+ int status = spi_sync(ts->bus, &ts->msg);
+
+ if (status)
+ dev_err(&ts->bus->dev, "spi_sync --> %d\n", status);
+}
+
+static void ad7879_setup_ts_def_msg(struct ad7879 *ts)
+{
+ struct spi_message *m;
+ int i;
+
+ ts->cmd = (u16) AD7879_READCMD(AD7879_REG_XPLUS);
+
+ m = &ts->msg;
+ spi_message_init(m);
+ ts->xfer[0].tx_buf = &ts->cmd;
+ ts->xfer[0].len = 2;
+
+ spi_message_add_tail(&ts->xfer[0], m);
+
+ for (i = 0; i < AD7879_NR_SENSE; i++) {
+ ts->xfer[i + 1].rx_buf = &ts->conversion_data[i];
+ ts->xfer[i + 1].len = 2;
+ spi_message_add_tail(&ts->xfer[i + 1], m);
+ }
+}
+
+static int __devinit ad7879_probe(struct spi_device *spi)
+{
+ struct ad7879 *ts;
+ int error;
+
+ /* don't exceed max specified SPI CLK frequency */
+ if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) {
+ dev_err(&spi->dev, "SPI CLK %d Hz?\n", spi->max_speed_hz);
+ return -EINVAL;
+ }
+
+ ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL);
+ if (!ts)
+ return -ENOMEM;
+
+ dev_set_drvdata(&spi->dev, ts);
+ ts->bus = spi;
+
+ ad7879_setup_ts_def_msg(ts);
+
+ error = ad7879_construct(spi, ts);
+ if (error) {
+ dev_set_drvdata(&spi->dev, NULL);
+ kfree(ts);
+ }
+
+ return 0;
+}
+
+static int __devexit ad7879_remove(struct spi_device *spi)
+{
+ struct ad7879 *ts = dev_get_drvdata(&spi->dev);
+
+ ad7879_destroy(spi, ts);
+ dev_set_drvdata(&spi->dev, NULL);
+ kfree(ts);
+
+ return 0;
+}
+
+static struct spi_driver ad7879_driver = {
+ .driver = {
+ .name = "ad7879",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = ad7879_probe,
+ .remove = __devexit_p(ad7879_remove),
+ .suspend = ad7879_suspend,
+ .resume = ad7879_resume,
+};
+
+static int __init ad7879_init(void)
+{
+ return spi_register_driver(&ad7879_driver);
+}
+module_init(ad7879_init);
+
+static void __exit ad7879_exit(void)
+{
+ spi_unregister_driver(&ad7879_driver);
+}
+module_exit(ad7879_exit);
+
+#elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+
+/* All registers are word-sized.
+ * AD7879 uses a high-byte first convention.
+ */
+static int ad7879_read(struct i2c_client *client, u8 reg)
+{
+ return swab16(i2c_smbus_read_word_data(client, reg));
+}
+
+static int ad7879_write(struct i2c_client *client, u8 reg, u16 val)
+{
+ return i2c_smbus_write_word_data(client, reg, swab16(val));
+}
+
+static void ad7879_collect(struct ad7879 *ts)
+{
+ int i;
+
+ for (i = 0; i < AD7879_NR_SENSE; i++)
+ ts->conversion_data[i] = ad7879_read(ts->bus,
+ AD7879_REG_XPLUS + i);
+}
+
+static int __devinit ad7879_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct ad7879 *ts;
+ int error;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_WORD_DATA)) {
+ dev_err(&client->dev, "SMBUS Word Data not Supported\n");
+ return -EIO;
+ }
+
+ ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL);
+ if (!ts)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, ts);
+ ts->bus = client;
+
+ error = ad7879_construct(client, ts);
+ if (error) {
+ i2c_set_clientdata(client, NULL);
+ kfree(ts);
+ }
+
+ return 0;
+}
+
+static int __devexit ad7879_remove(struct i2c_client *client)
+{
+ struct ad7879 *ts = dev_get_drvdata(&client->dev);
+
+ ad7879_destroy(client, ts);
+ i2c_set_clientdata(client, NULL);
+ kfree(ts);
+
+ return 0;
+}
+
+static const struct i2c_device_id ad7879_id[] = {
+ { "ad7879", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ad7879_id);
+
+static struct i2c_driver ad7879_driver = {
+ .driver = {
+ .name = "ad7879",
+ .owner = THIS_MODULE,
+ },
+ .probe = ad7879_probe,
+ .remove = __devexit_p(ad7879_remove),
+ .suspend = ad7879_suspend,
+ .resume = ad7879_resume,
+ .id_table = ad7879_id,
+};
+
+static int __init ad7879_init(void)
+{
+ return i2c_add_driver(&ad7879_driver);
+}
+module_init(ad7879_init);
+
+static void __exit ad7879_exit(void)
+{
+ i2c_del_driver(&ad7879_driver);
+}
+module_exit(ad7879_exit);
+#endif
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("AD7879(-1) touchscreen Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 7c27c8b9b6d..056ac77e2cf 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -295,7 +295,7 @@ name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
-/* Sysfs conventions report temperatures in millidegrees Celcius.
+/* Sysfs conventions report temperatures in millidegrees Celsius.
* ADS7846 could use the low-accuracy two-sample scheme, but can't do the high
* accuracy scheme without calibration data. For now we won't try either;
* userspace sees raw sensor values, and must scale/calibrate appropriately.
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c
index 1d11e2be9ef..dfa6a84ab50 100644
--- a/drivers/input/touchscreen/mainstone-wm97xx.c
+++ b/drivers/input/touchscreen/mainstone-wm97xx.c
@@ -162,6 +162,7 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm)
input_report_abs(wm->input_dev, ABS_X, x & 0xfff);
input_report_abs(wm->input_dev, ABS_Y, y & 0xfff);
input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff);
+ input_report_key(wm->input_dev, BTN_TOUCH, (p != 0));
input_sync(wm->input_dev);
reads++;
} while (reads < cinfo[sp_idx].reads);
@@ -245,7 +246,7 @@ static void wm97xx_irq_enable(struct wm97xx *wm, int enable)
if (enable)
enable_irq(wm->pen_irq);
else
- disable_irq(wm->pen_irq);
+ disable_irq_nosync(wm->pen_irq);
}
static struct wm97xx_mach_ops mainstone_mach_ops = {
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c
index 504ca11749a..141dd584330 100644
--- a/drivers/input/touchscreen/migor_ts.c
+++ b/drivers/input/touchscreen/migor_ts.c
@@ -198,6 +198,7 @@ static int migor_ts_probe(struct i2c_client *client,
goto err2;
}
+ device_init_wakeup(&client->dev, 1);
return 0;
err2:
@@ -224,6 +225,26 @@ static int migor_ts_remove(struct i2c_client *client)
return 0;
}
+static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
+
+ if (device_may_wakeup(&client->dev))
+ enable_irq_wake(priv->irq);
+
+ return 0;
+}
+
+static int migor_ts_resume(struct i2c_client *client)
+{
+ struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
+
+ if (device_may_wakeup(&client->dev))
+ disable_irq_wake(priv->irq);
+
+ return 0;
+}
+
static const struct i2c_device_id migor_ts_id[] = {
{ "migor_ts", 0 },
{ }
@@ -236,6 +257,8 @@ static struct i2c_driver migor_ts_driver = {
},
.probe = migor_ts_probe,
.remove = migor_ts_remove,
+ .suspend = migor_ts_suspend,
+ .resume = migor_ts_resume,
.id_table = migor_ts_id,
};
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 54986627def..e868264fe79 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -151,12 +151,14 @@ static void ucb1400_ts_evt_add(struct input_dev *idev, u16 pressure, u16 x, u16
input_report_abs(idev, ABS_X, x);
input_report_abs(idev, ABS_Y, y);
input_report_abs(idev, ABS_PRESSURE, pressure);
+ input_report_key(idev, BTN_TOUCH, 1);
input_sync(idev);
}
static void ucb1400_ts_event_release(struct input_dev *idev)
{
input_report_abs(idev, ABS_PRESSURE, 0);
+ input_report_key(idev, BTN_TOUCH, 0);
input_sync(idev);
}
@@ -377,7 +379,8 @@ static int ucb1400_ts_probe(struct platform_device *dev)
ucb->ts_idev->id.product = ucb->id;
ucb->ts_idev->open = ucb1400_ts_open;
ucb->ts_idev->close = ucb1400_ts_close;
- ucb->ts_idev->evbit[0] = BIT_MASK(EV_ABS);
+ ucb->ts_idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
+ ucb->ts_idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
ucb1400_adc_enable(ucb->ac97);
x_res = ucb1400_ts_read_xres(ucb);
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index d15aa11d705..cec480bffe3 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -409,6 +409,7 @@ static int wm97xx_read_samples(struct wm97xx *wm)
wm->pen_is_down = 0;
dev_dbg(wm->dev, "pen up\n");
input_report_abs(wm->input_dev, ABS_PRESSURE, 0);
+ input_report_key(wm->input_dev, BTN_TOUCH, 0);
input_sync(wm->input_dev);
} else if (!(rc & RC_AGAIN)) {
/* We need high frequency updates only while
@@ -433,6 +434,7 @@ static int wm97xx_read_samples(struct wm97xx *wm)
input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff);
input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff);
input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff);
+ input_report_key(wm->input_dev, BTN_TOUCH, 1);
input_sync(wm->input_dev);
wm->pen_is_down = 1;
wm->ts_reader_interval = wm->ts_reader_min_interval;
@@ -628,18 +630,21 @@ static int wm97xx_probe(struct device *dev)
wm->input_dev->phys = "wm97xx";
wm->input_dev->open = wm97xx_ts_input_open;
wm->input_dev->close = wm97xx_ts_input_close;
- set_bit(EV_ABS, wm->input_dev->evbit);
- set_bit(ABS_X, wm->input_dev->absbit);
- set_bit(ABS_Y, wm->input_dev->absbit);
- set_bit(ABS_PRESSURE, wm->input_dev->absbit);
+
+ __set_bit(EV_ABS, wm->input_dev->evbit);
+ __set_bit(EV_KEY, wm->input_dev->evbit);
+ __set_bit(BTN_TOUCH, wm->input_dev->keybit);
+
input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],
abs_x[2], 0);
input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],
abs_y[2], 0);
input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1],
abs_p[2], 0);
+
input_set_drvdata(wm->input_dev, wm);
wm->input_dev->dev.parent = dev;
+
ret = input_register_device(wm->input_dev);
if (ret < 0)
goto dev_alloc_err;
diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c
new file mode 100644
index 00000000000..41e4359c277
--- /dev/null
+++ b/drivers/input/touchscreen/zylonite-wm97xx.c
@@ -0,0 +1,240 @@
+/*
+ * zylonite-wm97xx.c -- Zylonite Continuous Touch screen driver
+ *
+ * Copyright 2004, 2007, 2008 Wolfson Microelectronics PLC.
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ * Parts Copyright : Ian Molton <spyro@f2s.com>
+ * Andrew Zabolotny <zap@homelink.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Notes:
+ * This is a wm97xx extended touch driver supporting interrupt driven
+ * and continuous operation on Marvell Zylonite development systems
+ * (which have a WM9713 on board).
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/wm97xx.h>
+
+#include <mach/hardware.h>
+#include <mach/mfp.h>
+#include <mach/regs-ac97.h>
+
+struct continuous {
+ u16 id; /* codec id */
+ u8 code; /* continuous code */
+ u8 reads; /* number of coord reads per read cycle */
+ u32 speed; /* number of coords per second */
+};
+
+#define WM_READS(sp) ((sp / HZ) + 1)
+
+static const struct continuous cinfo[] = {
+ { WM9713_ID2, 0, WM_READS(94), 94 },
+ { WM9713_ID2, 1, WM_READS(120), 120 },
+ { WM9713_ID2, 2, WM_READS(154), 154 },
+ { WM9713_ID2, 3, WM_READS(188), 188 },
+};
+
+/* continuous speed index */
+static int sp_idx;
+
+/*
+ * Pen sampling frequency (Hz) in continuous mode.
+ */
+static int cont_rate = 200;
+module_param(cont_rate, int, 0);
+MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)");
+
+/*
+ * Pressure readback.
+ *
+ * Set to 1 to read back pen down pressure
+ */
+static int pressure;
+module_param(pressure, int, 0);
+MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)");
+
+/*
+ * AC97 touch data slot.
+ *
+ * Touch screen readback data ac97 slot
+ */
+static int ac97_touch_slot = 5;
+module_param(ac97_touch_slot, int, 0);
+MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number");
+
+
+/* flush AC97 slot 5 FIFO machines */
+static void wm97xx_acc_pen_up(struct wm97xx *wm)
+{
+ int i;
+
+ msleep(1);
+
+ for (i = 0; i < 16; i++)
+ MODR;
+}
+
+static int wm97xx_acc_pen_down(struct wm97xx *wm)
+{
+ u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES;
+ int reads = 0;
+ static u16 last, tries;
+
+ /* When the AC97 queue has been drained we need to allow time
+ * to buffer up samples otherwise we end up spinning polling
+ * for samples. The controller can't have a suitably low
+ * threashold set to use the notifications it gives.
+ */
+ msleep(1);
+
+ if (tries > 5) {
+ tries = 0;
+ return RC_PENUP;
+ }
+
+ x = MODR;
+ if (x == last) {
+ tries++;
+ return RC_AGAIN;
+ }
+ last = x;
+ do {
+ if (reads)
+ x = MODR;
+ y = MODR;
+ if (pressure)
+ p = MODR;
+
+ /* are samples valid */
+ if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X ||
+ (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y ||
+ (p & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_PRES)
+ goto up;
+
+ /* coordinate is good */
+ tries = 0;
+ input_report_abs(wm->input_dev, ABS_X, x & 0xfff);
+ input_report_abs(wm->input_dev, ABS_Y, y & 0xfff);
+ input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff);
+ input_report_key(wm->input_dev, BTN_TOUCH, (p != 0));
+ input_sync(wm->input_dev);
+ reads++;
+ } while (reads < cinfo[sp_idx].reads);
+up:
+ return RC_PENDOWN | RC_AGAIN;
+}
+
+static int wm97xx_acc_startup(struct wm97xx *wm)
+{
+ int idx;
+
+ /* check we have a codec */
+ if (wm->ac97 == NULL)
+ return -ENODEV;
+
+ /* Go you big red fire engine */
+ for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) {
+ if (wm->id != cinfo[idx].id)
+ continue;
+ sp_idx = idx;
+ if (cont_rate <= cinfo[idx].speed)
+ break;
+ }
+ wm->acc_rate = cinfo[sp_idx].code;
+ wm->acc_slot = ac97_touch_slot;
+ dev_info(wm->dev,
+ "zylonite accelerated touchscreen driver, %d samples/sec\n",
+ cinfo[sp_idx].speed);
+
+ return 0;
+}
+
+static void wm97xx_irq_enable(struct wm97xx *wm, int enable)
+{
+ if (enable)
+ enable_irq(wm->pen_irq);
+ else
+ disable_irq_nosync(wm->pen_irq);
+}
+
+static struct wm97xx_mach_ops zylonite_mach_ops = {
+ .acc_enabled = 1,
+ .acc_pen_up = wm97xx_acc_pen_up,
+ .acc_pen_down = wm97xx_acc_pen_down,
+ .acc_startup = wm97xx_acc_startup,
+ .irq_enable = wm97xx_irq_enable,
+ .irq_gpio = WM97XX_GPIO_2,
+};
+
+static int zylonite_wm97xx_probe(struct platform_device *pdev)
+{
+ struct wm97xx *wm = platform_get_drvdata(pdev);
+ int gpio_touch_irq;
+
+ if (cpu_is_pxa320())
+ gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO15);
+ else
+ gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO26);
+
+ wm->pen_irq = IRQ_GPIO(gpio_touch_irq);
+ set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH);
+
+ wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
+ WM97XX_GPIO_POL_HIGH,
+ WM97XX_GPIO_STICKY,
+ WM97XX_GPIO_WAKE);
+ wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT,
+ WM97XX_GPIO_POL_HIGH,
+ WM97XX_GPIO_NOTSTICKY,
+ WM97XX_GPIO_NOWAKE);
+
+ return wm97xx_register_mach_ops(wm, &zylonite_mach_ops);
+}
+
+static int zylonite_wm97xx_remove(struct platform_device *pdev)
+{
+ struct wm97xx *wm = platform_get_drvdata(pdev);
+
+ wm97xx_unregister_mach_ops(wm);
+
+ return 0;
+}
+
+static struct platform_driver zylonite_wm97xx_driver = {
+ .probe = zylonite_wm97xx_probe,
+ .remove = zylonite_wm97xx_remove,
+ .driver = {
+ .name = "wm97xx-touch",
+ },
+};
+
+static int __init zylonite_wm97xx_init(void)
+{
+ return platform_driver_register(&zylonite_wm97xx_driver);
+}
+
+static void __exit zylonite_wm97xx_exit(void)
+{
+ platform_driver_unregister(&zylonite_wm97xx_driver);
+}
+
+module_init(zylonite_wm97xx_init);
+module_exit(zylonite_wm97xx_exit);
+
+/* Module information */
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("wm97xx continuous touch driver for Zylonite");
+MODULE_LICENSE("GPL");
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 831ddce1467..781c4041f7b 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -821,7 +821,7 @@ static void read_iso_callback(struct urb *urb)
/* pass URB to tasklet */
ubc->isoindone = urb;
ubc->isoinstatus = status;
- tasklet_schedule(&ubc->rcvd_tasklet);
+ tasklet_hi_schedule(&ubc->rcvd_tasklet);
} else {
/* tasklet still busy, drop data and resubmit URB */
ubc->loststatus = status;
@@ -888,7 +888,7 @@ static void write_iso_callback(struct urb *urb)
ubc->isooutovfl = ubc->isooutdone;
ubc->isooutdone = ucx;
spin_unlock_irqrestore(&ubc->isooutlock, flags);
- tasklet_schedule(&ubc->sent_tasklet);
+ tasklet_hi_schedule(&ubc->sent_tasklet);
}
/* starturbs
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index 311e7ca0fb0..820a30923fe 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -193,7 +193,9 @@ static void if_close(struct tty_struct *tty, struct file *filp)
mutex_lock(&cs->mutex);
- if (!cs->open_count)
+ if (!cs->connected)
+ gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
+ else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__);
else {
if (!--cs->open_count) {
@@ -228,7 +230,10 @@ static int if_ioctl(struct tty_struct *tty, struct file *file,
if (mutex_lock_interruptible(&cs->mutex))
return -ERESTARTSYS; // FIXME -EINTR?
- if (!cs->open_count)
+ if (!cs->connected) {
+ gig_dbg(DEBUG_IF, "not connected");
+ retval = -ENODEV;
+ } else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__);
else {
retval = 0;
@@ -248,13 +253,6 @@ static int if_ioctl(struct tty_struct *tty, struct file *file,
retval = put_user(int_arg, (int __user *) arg);
break;
case GIGASET_BRKCHARS:
- //FIXME test if MS_LOCKED
- if (!cs->connected) {
- gig_dbg(DEBUG_ANY,
- "can't communicate with unplugged device");
- retval = -ENODEV;
- break;
- }
retval = copy_from_user(&buf,
(const unsigned char __user *) arg, 6)
? -EFAULT : 0;
@@ -331,7 +329,7 @@ static int if_tiocmset(struct tty_struct *tty, struct file *file,
return -ERESTARTSYS; // FIXME -EINTR?
if (!cs->connected) {
- gig_dbg(DEBUG_ANY, "can't communicate with unplugged device");
+ gig_dbg(DEBUG_IF, "not connected");
retval = -ENODEV;
} else {
mc = (cs->control_state | set) & ~clear & (TIOCM_RTS|TIOCM_DTR);
@@ -360,14 +358,14 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count)
if (mutex_lock_interruptible(&cs->mutex))
return -ERESTARTSYS; // FIXME -EINTR?
- if (!cs->open_count)
+ if (!cs->connected) {
+ gig_dbg(DEBUG_IF, "not connected");
+ retval = -ENODEV;
+ } else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__);
else if (cs->mstate != MS_LOCKED) {
dev_warn(cs->dev, "can't write to unlocked device\n");
retval = -EBUSY;
- } else if (!cs->connected) {
- gig_dbg(DEBUG_ANY, "can't write to unplugged device");
- retval = -EBUSY; //FIXME
} else {
retval = cs->ops->write_cmd(cs, buf, count,
&cs->if_wake_tasklet);
@@ -394,14 +392,14 @@ static int if_write_room(struct tty_struct *tty)
if (mutex_lock_interruptible(&cs->mutex))
return -ERESTARTSYS; // FIXME -EINTR?
- if (!cs->open_count)
+ if (!cs->connected) {
+ gig_dbg(DEBUG_IF, "not connected");
+ retval = -ENODEV;
+ } else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__);
else if (cs->mstate != MS_LOCKED) {
dev_warn(cs->dev, "can't write to unlocked device\n");
retval = -EBUSY;
- } else if (!cs->connected) {
- gig_dbg(DEBUG_ANY, "can't write to unplugged device");
- retval = -EBUSY; //FIXME
} else
retval = cs->ops->write_room(cs);
@@ -426,14 +424,14 @@ static int if_chars_in_buffer(struct tty_struct *tty)
if (mutex_lock_interruptible(&cs->mutex))
return -ERESTARTSYS; // FIXME -EINTR?
- if (!cs->open_count)
+ if (!cs->connected) {
+ gig_dbg(DEBUG_IF, "not connected");
+ retval = -ENODEV;
+ } else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__);
else if (cs->mstate != MS_LOCKED) {
dev_warn(cs->dev, "can't write to unlocked device\n");
retval = -EBUSY;
- } else if (!cs->connected) {
- gig_dbg(DEBUG_ANY, "can't write to unplugged device");
- retval = -EBUSY; //FIXME
} else
retval = cs->ops->chars_in_buffer(cs);
@@ -456,7 +454,9 @@ static void if_throttle(struct tty_struct *tty)
mutex_lock(&cs->mutex);
- if (!cs->open_count)
+ if (!cs->connected)
+ gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
+ else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__);
else {
//FIXME
@@ -479,7 +479,9 @@ static void if_unthrottle(struct tty_struct *tty)
mutex_lock(&cs->mutex);
- if (!cs->open_count)
+ if (!cs->connected)
+ gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
+ else if (!cs->open_count)
dev_warn(cs->dev, "%s: device not opened\n", __func__);
else {
//FIXME
@@ -506,13 +508,13 @@ static void if_set_termios(struct tty_struct *tty, struct ktermios *old)
mutex_lock(&cs->mutex);
- if (!cs->open_count) {
- dev_warn(cs->dev, "%s: device not opened\n", __func__);
+ if (!cs->connected) {
+ gig_dbg(DEBUG_IF, "not connected");
goto out;
}
- if (!cs->connected) {
- gig_dbg(DEBUG_ANY, "can't communicate with unplugged device");
+ if (!cs->open_count) {
+ dev_warn(cs->dev, "%s: device not opened\n", __func__);
goto out;
}
diff --git a/drivers/isdn/mISDN/Kconfig b/drivers/isdn/mISDN/Kconfig
index 4938355c407..1747a02a019 100644
--- a/drivers/isdn/mISDN/Kconfig
+++ b/drivers/isdn/mISDN/Kconfig
@@ -14,13 +14,15 @@ config MISDN_DSP
depends on MISDN
help
Enable support for digital audio processing capability.
+
This module may be used for special applications that require
- cross connecting of bchannels, conferencing, dtmf decoding
+ cross connecting of bchannels, conferencing, dtmf decoding,
echo cancelation, tone generation, and Blowfish encryption and
- decryption.
- It may use hardware features if available.
+ decryption. It may use hardware features if available.
+
E.g. it is required for PBX4Linux. Go to http://isdn.eversberg.eu
- and get more informations about this module and it's usage.
+ and get more information about this module and its usage.
+
If unsure, say 'N'.
config MISDN_L1OIP
diff --git a/drivers/isdn/mISDN/l1oip_codec.c b/drivers/isdn/mISDN/l1oip_codec.c
index 2ec4b28d9ed..e4ecba3d48d 100644
--- a/drivers/isdn/mISDN/l1oip_codec.c
+++ b/drivers/isdn/mISDN/l1oip_codec.c
@@ -331,7 +331,7 @@ l1oip_4bit_alloc(int ulaw)
/* alloc conversion tables */
table_com = vmalloc(65536);
table_dec = vmalloc(512);
- if (!table_com | !table_dec) {
+ if (!table_com || !table_dec) {
l1oip_4bit_free();
return -ENOMEM;
}
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 556aeca0d86..9b60b6b684d 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -31,6 +31,13 @@ config LEDS_LOCOMO
This option enables support for the LEDs on Sharp Locomo.
Zaurus models SL-5500 and SL-5600.
+config LEDS_MIKROTIK_RB532
+ tristate "LED Support for Mikrotik Routerboard 532"
+ depends on LEDS_CLASS && MIKROTIK_RB532
+ help
+ This option enables support for the so called "User LED" of
+ Mikrotik's Routerboard 532.
+
config LEDS_S3C24XX
tristate "LED Support for Samsung S3C24XX GPIO LEDs"
depends on LEDS_CLASS && ARCH_S3C2410
@@ -100,7 +107,7 @@ config LEDS_HP6XX
tristate "LED Support for the HP Jornada 6xx"
depends on LEDS_CLASS && SH_HP6XX
help
- This option enables led support for the handheld
+ This option enables LED support for the handheld
HP Jornada 620/660/680/690.
config LEDS_PCA9532
@@ -108,7 +115,7 @@ config LEDS_PCA9532
depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL
help
This option enables support for NXP pca9532
- led controller. It is generally only usefull
+ LED controller. It is generally only useful
as a platform driver
config LEDS_GPIO
@@ -117,11 +124,40 @@ config LEDS_GPIO
help
This option enables support for the LEDs connected to GPIO
outputs. To be useful the particular board must have LEDs
- and they must be connected to the GPIO lines.
+ and they must be connected to the GPIO lines. The LEDs must be
+ defined as platform devices and/or OpenFirmware platform devices.
+ The code to use these bindings can be selected below.
+
+config LEDS_GPIO_PLATFORM
+ bool "Platform device bindings for GPIO LEDs"
+ depends on LEDS_GPIO
+ default y
+ help
+ Let the leds-gpio driver drive LEDs which have been defined as
+ platform devices. If you don't know what this means, say yes.
+
+config LEDS_GPIO_OF
+ bool "OpenFirmware platform device bindings for GPIO LEDs"
+ depends on LEDS_GPIO && OF_DEVICE
+ default y
+ help
+ Let the leds-gpio driver drive LEDs which have been defined as
+ of_platform devices. For instance, LEDs which are listed in a "dts"
+ file.
+
+config LEDS_LP5521
+ tristate "LED Support for the LP5521 LEDs"
+ depends on LEDS_CLASS && I2C
+ help
+ If you say 'Y' here you get support for the National Semiconductor
+ LP5521 LED driver used in n8x0 boards.
+
+ This driver can be built as a module by choosing 'M'. The module
+ will be called leds-lp5521.
config LEDS_CLEVO_MAIL
- tristate "Mail LED on Clevo notebook (EXPERIMENTAL)"
- depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI && EXPERIMENTAL
+ tristate "Mail LED on Clevo notebook"
+ depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI
help
This driver makes the mail LED accessible from userspace
programs through the leds subsystem. This LED have three
@@ -144,7 +180,7 @@ config LEDS_CLEVO_MAIL
Positivo Mobile (Clevo M5x0V)
If your model is not listed here you can try the "nodetect"
- module paramter.
+ module parameter.
To compile this driver as a module, choose M here: the
module will be called leds-clevo-mail.
@@ -171,6 +207,26 @@ config LEDS_DA903X
This option enables support for on-chip LED drivers found
on Dialog Semiconductor DA9030/DA9034 PMICs.
+config LEDS_DAC124S085
+ tristate "LED Support for DAC124S085 SPI DAC"
+ depends on LEDS_CLASS && SPI
+ help
+ This option enables support for DAC124S085 SPI DAC from NatSemi,
+ which can be used to control up to four LEDs.
+
+config LEDS_PWM
+ tristate "PWM driven LED Support"
+ depends on LEDS_CLASS && HAVE_PWM
+ help
+ This option enables support for pwm driven LEDs
+
+config LEDS_BD2802
+ tristate "LED driver for BD2802 RGB LED"
+ depends on LEDS_CLASS && I2C
+ help
+ This option enables support for BD2802GU RGB LED driver chips
+ accessed via the I2C bus.
+
comment "LED Triggers"
config LEDS_TRIGGERS
@@ -216,6 +272,19 @@ config LEDS_TRIGGER_BACKLIGHT
If unsure, say N.
+config LEDS_TRIGGER_GPIO
+ tristate "LED GPIO Trigger"
+ depends on LEDS_TRIGGERS
+ depends on GPIOLIB
+ help
+ This allows LEDs to be controlled by gpio events. It's good
+ when using gpios as switches and triggering the needed LEDs
+ from there. One use case is n810's keypad LEDs that could
+ be triggered by this trigger when user slides up to show
+ keypad.
+
+ If unsure, say N.
+
config LEDS_TRIGGER_DEFAULT_ON
tristate "LED Default ON Trigger"
depends on LEDS_TRIGGERS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 9d76f0f160a..2d41c4dcf92 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -6,7 +6,9 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
# LED Platform Drivers
obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o
+obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
+obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o
obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
@@ -24,10 +26,15 @@ obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o
obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o
obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o
+obj-$(CONFIG_LEDS_PWM) += leds-pwm.o
+
+# LED SPI Drivers
+obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
# LED Triggers
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
+obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o
obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 52f82e3ea13..f2cc13d7681 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -64,7 +64,16 @@ static ssize_t led_brightness_store(struct device *dev,
return ret;
}
+static ssize_t led_max_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", led_cdev->max_brightness);
+}
+
static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
+static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL);
#ifdef CONFIG_LEDS_TRIGGERS
static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
#endif
@@ -138,6 +147,13 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
list_add_tail(&led_cdev->node, &leds_list);
up_write(&leds_list_lock);
+ if (!led_cdev->max_brightness)
+ led_cdev->max_brightness = LED_FULL;
+
+ rc = device_create_file(led_cdev->dev, &dev_attr_max_brightness);
+ if (rc)
+ goto err_out_attr_max;
+
led_update_brightness(led_cdev);
#ifdef CONFIG_LEDS_TRIGGERS
@@ -155,9 +171,11 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
#ifdef CONFIG_LEDS_TRIGGERS
err_out_led_list:
+ device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
+#endif
+err_out_attr_max:
device_remove_file(led_cdev->dev, &dev_attr_brightness);
list_del(&led_cdev->node);
-#endif
err_out:
device_unregister(led_cdev->dev);
return rc;
@@ -172,6 +190,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register);
*/
void led_classdev_unregister(struct led_classdev *led_cdev)
{
+ device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
device_remove_file(led_cdev->dev, &dev_attr_brightness);
#ifdef CONFIG_LEDS_TRIGGERS
device_remove_file(led_cdev->dev, &dev_attr_trigger);
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index f910eaffe3a..d8ddd9ef899 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -156,12 +156,20 @@ EXPORT_SYMBOL_GPL(led_trigger_set_default);
int led_trigger_register(struct led_trigger *trigger)
{
struct led_classdev *led_cdev;
+ struct led_trigger *trig;
rwlock_init(&trigger->leddev_list_lock);
INIT_LIST_HEAD(&trigger->led_cdevs);
- /* Add to the list of led triggers */
down_write(&triggers_list_lock);
+ /* Make sure the trigger's name isn't already in use */
+ list_for_each_entry(trig, &trigger_list, next_trig) {
+ if (!strcmp(trig->name, trigger->name)) {
+ up_write(&triggers_list_lock);
+ return -EEXIST;
+ }
+ }
+ /* Add to the list of led triggers */
list_add_tail(&trigger->next_trig, &trigger_list);
up_write(&triggers_list_lock);
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
new file mode 100644
index 00000000000..4149ecb3a9b
--- /dev/null
+++ b/drivers/leds/leds-bd2802.c
@@ -0,0 +1,765 @@
+/*
+ * leds-bd2802.c - RGB LED Driver
+ *
+ * Copyright (C) 2009 Samsung Electronics
+ * Kim Kyuwon <q1.kim@samsung.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.
+ *
+ * Datasheet: http://www.rohm.com/products/databook/driver/pdf/bd2802gu-e.pdf
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/leds-bd2802.h>
+
+
+#define LED_CTL(rgb2en, rgb1en) ((rgb2en) << 4 | ((rgb1en) << 0))
+
+#define BD2802_LED_OFFSET 0xa
+#define BD2802_COLOR_OFFSET 0x3
+
+#define BD2802_REG_CLKSETUP 0x00
+#define BD2802_REG_CONTROL 0x01
+#define BD2802_REG_HOURSETUP 0x02
+#define BD2802_REG_CURRENT1SETUP 0x03
+#define BD2802_REG_CURRENT2SETUP 0x04
+#define BD2802_REG_WAVEPATTERN 0x05
+
+#define BD2802_CURRENT_032 0x10 /* 3.2mA */
+#define BD2802_CURRENT_000 0x00 /* 0.0mA */
+
+#define BD2802_PATTERN_FULL 0x07
+#define BD2802_PATTERN_HALF 0x03
+
+enum led_ids {
+ LED1,
+ LED2,
+ LED_NUM,
+};
+
+enum led_colors {
+ RED,
+ GREEN,
+ BLUE,
+};
+
+enum led_bits {
+ BD2802_OFF,
+ BD2802_BLINK,
+ BD2802_ON,
+};
+
+/*
+ * State '0' : 'off'
+ * State '1' : 'blink'
+ * State '2' : 'on'.
+ */
+struct led_state {
+ unsigned r:2;
+ unsigned g:2;
+ unsigned b:2;
+};
+
+struct bd2802_led {
+ struct bd2802_led_platform_data *pdata;
+ struct i2c_client *client;
+ struct rw_semaphore rwsem;
+ struct work_struct work;
+
+ struct led_state led[2];
+
+ /*
+ * Making led_classdev as array is not recommended, because array
+ * members prevent using 'container_of' macro. So repetitive works
+ * are needed.
+ */
+ struct led_classdev cdev_led1r;
+ struct led_classdev cdev_led1g;
+ struct led_classdev cdev_led1b;
+ struct led_classdev cdev_led2r;
+ struct led_classdev cdev_led2g;
+ struct led_classdev cdev_led2b;
+
+ /*
+ * Advanced Configuration Function(ADF) mode:
+ * In ADF mode, user can set registers of BD2802GU directly,
+ * therefore BD2802GU doesn't enter reset state.
+ */
+ int adf_on;
+
+ enum led_ids led_id;
+ enum led_colors color;
+ enum led_bits state;
+};
+
+
+/*--------------------------------------------------------------*/
+/* BD2802GU helper functions */
+/*--------------------------------------------------------------*/
+
+static inline int bd2802_is_rgb_off(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color)
+{
+ switch (color) {
+ case RED:
+ return !led->led[id].r;
+ case GREEN:
+ return !led->led[id].g;
+ case BLUE:
+ return !led->led[id].b;
+ default:
+ dev_err(&led->client->dev, "%s: Invalid color\n", __func__);
+ return -EINVAL;
+ }
+}
+
+static inline int bd2802_is_led_off(struct bd2802_led *led, enum led_ids id)
+{
+ if (led->led[id].r || led->led[id].g || led->led[id].b)
+ return 0;
+
+ return 1;
+}
+
+static inline int bd2802_is_all_off(struct bd2802_led *led)
+{
+ int i;
+
+ for (i = 0; i < LED_NUM; i++)
+ if (!bd2802_is_led_off(led, i))
+ return 0;
+
+ return 1;
+}
+
+static inline u8 bd2802_get_base_offset(enum led_ids id, enum led_colors color)
+{
+ return id * BD2802_LED_OFFSET + color * BD2802_COLOR_OFFSET;
+}
+
+static inline u8 bd2802_get_reg_addr(enum led_ids id, enum led_colors color,
+ u8 reg_offset)
+{
+ return reg_offset + bd2802_get_base_offset(id, color);
+}
+
+
+/*--------------------------------------------------------------*/
+/* BD2802GU core functions */
+/*--------------------------------------------------------------*/
+
+static int bd2802_write_byte(struct i2c_client *client, u8 reg, u8 val)
+{
+ int ret = i2c_smbus_write_byte_data(client, reg, val);
+ if (ret >= 0)
+ return 0;
+
+ dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n",
+ __func__, reg, val, ret);
+
+ return ret;
+}
+
+static void bd2802_update_state(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color, enum led_bits led_bit)
+{
+ int i;
+ u8 value;
+
+ for (i = 0; i < LED_NUM; i++) {
+ if (i == id) {
+ switch (color) {
+ case RED:
+ led->led[i].r = led_bit;
+ break;
+ case GREEN:
+ led->led[i].g = led_bit;
+ break;
+ case BLUE:
+ led->led[i].b = led_bit;
+ break;
+ default:
+ dev_err(&led->client->dev,
+ "%s: Invalid color\n", __func__);
+ return;
+ }
+ }
+ }
+
+ if (led_bit == BD2802_BLINK || led_bit == BD2802_ON)
+ return;
+
+ if (!bd2802_is_led_off(led, id))
+ return;
+
+ if (bd2802_is_all_off(led) && !led->adf_on) {
+ gpio_set_value(led->pdata->reset_gpio, 0);
+ return;
+ }
+
+ /*
+ * In this case, other led is turned on, and current led is turned
+ * off. So set RGB LED Control register to stop the current RGB LED
+ */
+ value = (id == LED1) ? LED_CTL(1, 0) : LED_CTL(0, 1);
+ bd2802_write_byte(led->client, BD2802_REG_CONTROL, value);
+}
+
+static void bd2802_configure(struct bd2802_led *led)
+{
+ struct bd2802_led_platform_data *pdata = led->pdata;
+ u8 reg;
+
+ reg = bd2802_get_reg_addr(LED1, RED, BD2802_REG_HOURSETUP);
+ bd2802_write_byte(led->client, reg, pdata->rgb_time);
+
+ reg = bd2802_get_reg_addr(LED2, RED, BD2802_REG_HOURSETUP);
+ bd2802_write_byte(led->client, reg, pdata->rgb_time);
+}
+
+static void bd2802_reset_cancel(struct bd2802_led *led)
+{
+ gpio_set_value(led->pdata->reset_gpio, 1);
+ udelay(100);
+ bd2802_configure(led);
+}
+
+static void bd2802_enable(struct bd2802_led *led, enum led_ids id)
+{
+ enum led_ids other_led = (id == LED1) ? LED2 : LED1;
+ u8 value, other_led_on;
+
+ other_led_on = !bd2802_is_led_off(led, other_led);
+ if (id == LED1)
+ value = LED_CTL(other_led_on, 1);
+ else
+ value = LED_CTL(1 , other_led_on);
+
+ bd2802_write_byte(led->client, BD2802_REG_CONTROL, value);
+}
+
+static void bd2802_set_on(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color)
+{
+ u8 reg;
+
+ if (bd2802_is_all_off(led) && !led->adf_on)
+ bd2802_reset_cancel(led);
+
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_032);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN);
+ bd2802_write_byte(led->client, reg, BD2802_PATTERN_FULL);
+
+ bd2802_enable(led, id);
+ bd2802_update_state(led, id, color, BD2802_ON);
+}
+
+static void bd2802_set_blink(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color)
+{
+ u8 reg;
+
+ if (bd2802_is_all_off(led) && !led->adf_on)
+ bd2802_reset_cancel(led);
+
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_032);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN);
+ bd2802_write_byte(led->client, reg, BD2802_PATTERN_HALF);
+
+ bd2802_enable(led, id);
+ bd2802_update_state(led, id, color, BD2802_BLINK);
+}
+
+static void bd2802_turn_on(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color, enum led_bits led_bit)
+{
+ if (led_bit == BD2802_OFF) {
+ dev_err(&led->client->dev,
+ "Only 'blink' and 'on' are allowed\n");
+ return;
+ }
+
+ if (led_bit == BD2802_BLINK)
+ bd2802_set_blink(led, id, color);
+ else
+ bd2802_set_on(led, id, color);
+}
+
+static void bd2802_turn_off(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color)
+{
+ u8 reg;
+
+ if (bd2802_is_rgb_off(led, id, color))
+ return;
+
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+
+ bd2802_update_state(led, id, color, BD2802_OFF);
+}
+
+static void bd2802_restore_state(struct bd2802_led *led)
+{
+ int i;
+
+ for (i = 0; i < LED_NUM; i++) {
+ if (led->led[i].r)
+ bd2802_turn_on(led, i, RED, led->led[i].r);
+ if (led->led[i].g)
+ bd2802_turn_on(led, i, GREEN, led->led[i].g);
+ if (led->led[i].b)
+ bd2802_turn_on(led, i, BLUE, led->led[i].b);
+ }
+}
+
+#define BD2802_SET_REGISTER(reg_addr, reg_name) \
+static ssize_t bd2802_store_reg##reg_addr(struct device *dev, \
+ struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+ struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\
+ unsigned long val; \
+ int ret; \
+ if (!count) \
+ return -EINVAL; \
+ ret = strict_strtoul(buf, 16, &val); \
+ if (ret) \
+ return ret; \
+ down_write(&led->rwsem); \
+ bd2802_write_byte(led->client, reg_addr, (u8) val); \
+ up_write(&led->rwsem); \
+ return count; \
+} \
+static struct device_attribute bd2802_reg##reg_addr##_attr = { \
+ .attr = {.name = reg_name, .mode = 0644, .owner = THIS_MODULE}, \
+ .store = bd2802_store_reg##reg_addr, \
+};
+
+BD2802_SET_REGISTER(0x00, "0x00");
+BD2802_SET_REGISTER(0x01, "0x01");
+BD2802_SET_REGISTER(0x02, "0x02");
+BD2802_SET_REGISTER(0x03, "0x03");
+BD2802_SET_REGISTER(0x04, "0x04");
+BD2802_SET_REGISTER(0x05, "0x05");
+BD2802_SET_REGISTER(0x06, "0x06");
+BD2802_SET_REGISTER(0x07, "0x07");
+BD2802_SET_REGISTER(0x08, "0x08");
+BD2802_SET_REGISTER(0x09, "0x09");
+BD2802_SET_REGISTER(0x0a, "0x0a");
+BD2802_SET_REGISTER(0x0b, "0x0b");
+BD2802_SET_REGISTER(0x0c, "0x0c");
+BD2802_SET_REGISTER(0x0d, "0x0d");
+BD2802_SET_REGISTER(0x0e, "0x0e");
+BD2802_SET_REGISTER(0x0f, "0x0f");
+BD2802_SET_REGISTER(0x10, "0x10");
+BD2802_SET_REGISTER(0x11, "0x11");
+BD2802_SET_REGISTER(0x12, "0x12");
+BD2802_SET_REGISTER(0x13, "0x13");
+BD2802_SET_REGISTER(0x14, "0x14");
+BD2802_SET_REGISTER(0x15, "0x15");
+
+static struct device_attribute *bd2802_addr_attributes[] = {
+ &bd2802_reg0x00_attr,
+ &bd2802_reg0x01_attr,
+ &bd2802_reg0x02_attr,
+ &bd2802_reg0x03_attr,
+ &bd2802_reg0x04_attr,
+ &bd2802_reg0x05_attr,
+ &bd2802_reg0x06_attr,
+ &bd2802_reg0x07_attr,
+ &bd2802_reg0x08_attr,
+ &bd2802_reg0x09_attr,
+ &bd2802_reg0x0a_attr,
+ &bd2802_reg0x0b_attr,
+ &bd2802_reg0x0c_attr,
+ &bd2802_reg0x0d_attr,
+ &bd2802_reg0x0e_attr,
+ &bd2802_reg0x0f_attr,
+ &bd2802_reg0x10_attr,
+ &bd2802_reg0x11_attr,
+ &bd2802_reg0x12_attr,
+ &bd2802_reg0x13_attr,
+ &bd2802_reg0x14_attr,
+ &bd2802_reg0x15_attr,
+};
+
+static void bd2802_enable_adv_conf(struct bd2802_led *led)
+{
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++) {
+ ret = device_create_file(&led->client->dev,
+ bd2802_addr_attributes[i]);
+ if (ret) {
+ dev_err(&led->client->dev, "failed to sysfs file %s\n",
+ bd2802_addr_attributes[i]->attr.name);
+ goto failed_remove_files;
+ }
+ }
+
+ if (bd2802_is_all_off(led))
+ bd2802_reset_cancel(led);
+
+ led->adf_on = 1;
+
+ return;
+
+failed_remove_files:
+ for (i--; i >= 0; i--)
+ device_remove_file(&led->client->dev,
+ bd2802_addr_attributes[i]);
+}
+
+static void bd2802_disable_adv_conf(struct bd2802_led *led)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++)
+ device_remove_file(&led->client->dev,
+ bd2802_addr_attributes[i]);
+
+ if (bd2802_is_all_off(led))
+ gpio_set_value(led->pdata->reset_gpio, 0);
+
+ led->adf_on = 0;
+}
+
+static ssize_t bd2802_show_adv_conf(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));
+ ssize_t ret;
+
+ down_read(&led->rwsem);
+ if (led->adf_on)
+ ret = sprintf(buf, "on\n");
+ else
+ ret = sprintf(buf, "off\n");
+ up_read(&led->rwsem);
+
+ return ret;
+}
+
+static ssize_t bd2802_store_adv_conf(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));
+
+ if (!count)
+ return -EINVAL;
+
+ down_write(&led->rwsem);
+ if (!led->adf_on && !strncmp(buf, "on", 2))
+ bd2802_enable_adv_conf(led);
+ else if (led->adf_on && !strncmp(buf, "off", 3))
+ bd2802_disable_adv_conf(led);
+ up_write(&led->rwsem);
+
+ return count;
+}
+
+static struct device_attribute bd2802_adv_conf_attr = {
+ .attr = {
+ .name = "advanced_configuration",
+ .mode = 0644,
+ .owner = THIS_MODULE
+ },
+ .show = bd2802_show_adv_conf,
+ .store = bd2802_store_adv_conf,
+};
+
+static void bd2802_led_work(struct work_struct *work)
+{
+ struct bd2802_led *led = container_of(work, struct bd2802_led, work);
+
+ if (led->state)
+ bd2802_turn_on(led, led->led_id, led->color, led->state);
+ else
+ bd2802_turn_off(led, led->led_id, led->color);
+}
+
+#define BD2802_CONTROL_RGBS(name, id, clr) \
+static void bd2802_set_##name##_brightness(struct led_classdev *led_cdev,\
+ enum led_brightness value) \
+{ \
+ struct bd2802_led *led = \
+ container_of(led_cdev, struct bd2802_led, cdev_##name); \
+ led->led_id = id; \
+ led->color = clr; \
+ if (value == LED_OFF) \
+ led->state = BD2802_OFF; \
+ else \
+ led->state = BD2802_ON; \
+ schedule_work(&led->work); \
+} \
+static int bd2802_set_##name##_blink(struct led_classdev *led_cdev, \
+ unsigned long *delay_on, unsigned long *delay_off) \
+{ \
+ struct bd2802_led *led = \
+ container_of(led_cdev, struct bd2802_led, cdev_##name); \
+ if (*delay_on == 0 || *delay_off == 0) \
+ return -EINVAL; \
+ led->led_id = id; \
+ led->color = clr; \
+ led->state = BD2802_BLINK; \
+ schedule_work(&led->work); \
+ return 0; \
+}
+
+BD2802_CONTROL_RGBS(led1r, LED1, RED);
+BD2802_CONTROL_RGBS(led1g, LED1, GREEN);
+BD2802_CONTROL_RGBS(led1b, LED1, BLUE);
+BD2802_CONTROL_RGBS(led2r, LED2, RED);
+BD2802_CONTROL_RGBS(led2g, LED2, GREEN);
+BD2802_CONTROL_RGBS(led2b, LED2, BLUE);
+
+static int bd2802_register_led_classdev(struct bd2802_led *led)
+{
+ int ret;
+
+ INIT_WORK(&led->work, bd2802_led_work);
+
+ led->cdev_led1r.name = "led1_R";
+ led->cdev_led1r.brightness = LED_OFF;
+ led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness;
+ led->cdev_led1r.blink_set = bd2802_set_led1r_blink;
+ led->cdev_led1r.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led1r);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led1r.name);
+ goto failed_unregister_led1_R;
+ }
+
+ led->cdev_led1g.name = "led1_G";
+ led->cdev_led1g.brightness = LED_OFF;
+ led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness;
+ led->cdev_led1g.blink_set = bd2802_set_led1g_blink;
+ led->cdev_led1g.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led1g);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led1g.name);
+ goto failed_unregister_led1_G;
+ }
+
+ led->cdev_led1b.name = "led1_B";
+ led->cdev_led1b.brightness = LED_OFF;
+ led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness;
+ led->cdev_led1b.blink_set = bd2802_set_led1b_blink;
+ led->cdev_led1b.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led1b);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led1b.name);
+ goto failed_unregister_led1_B;
+ }
+
+ led->cdev_led2r.name = "led2_R";
+ led->cdev_led2r.brightness = LED_OFF;
+ led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness;
+ led->cdev_led2r.blink_set = bd2802_set_led2r_blink;
+ led->cdev_led2r.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led2r);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led2r.name);
+ goto failed_unregister_led2_R;
+ }
+
+ led->cdev_led2g.name = "led2_G";
+ led->cdev_led2g.brightness = LED_OFF;
+ led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness;
+ led->cdev_led2g.blink_set = bd2802_set_led2g_blink;
+ led->cdev_led2g.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led2g);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led2g.name);
+ goto failed_unregister_led2_G;
+ }
+
+ led->cdev_led2b.name = "led2_B";
+ led->cdev_led2b.brightness = LED_OFF;
+ led->cdev_led2b.brightness_set = bd2802_set_led2b_brightness;
+ led->cdev_led2b.blink_set = bd2802_set_led2b_blink;
+ led->cdev_led2b.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led2b);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led2b.name);
+ goto failed_unregister_led2_B;
+ }
+
+ return 0;
+
+failed_unregister_led2_B:
+ led_classdev_unregister(&led->cdev_led2g);
+failed_unregister_led2_G:
+ led_classdev_unregister(&led->cdev_led2r);
+failed_unregister_led2_R:
+ led_classdev_unregister(&led->cdev_led1b);
+failed_unregister_led1_B:
+ led_classdev_unregister(&led->cdev_led1g);
+failed_unregister_led1_G:
+ led_classdev_unregister(&led->cdev_led1r);
+failed_unregister_led1_R:
+
+ return ret;
+}
+
+static void bd2802_unregister_led_classdev(struct bd2802_led *led)
+{
+ cancel_work_sync(&led->work);
+ led_classdev_unregister(&led->cdev_led1r);
+}
+
+static int __devinit bd2802_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct bd2802_led *led;
+ struct bd2802_led_platform_data *pdata;
+ int ret;
+
+ led = kzalloc(sizeof(struct bd2802_led), GFP_KERNEL);
+ if (!led) {
+ dev_err(&client->dev, "failed to allocate driver data\n");
+ return -ENOMEM;
+ }
+
+ led->client = client;
+ pdata = led->pdata = client->dev.platform_data;
+ i2c_set_clientdata(client, led);
+
+ /* Configure RESET GPIO (L: RESET, H: RESET cancel) */
+ gpio_request(pdata->reset_gpio, "RGB_RESETB");
+ gpio_direction_output(pdata->reset_gpio, 1);
+
+ /* Tacss = min 0.1ms */
+ udelay(100);
+
+ /* Detect BD2802GU */
+ ret = bd2802_write_byte(client, BD2802_REG_CLKSETUP, 0x00);
+ if (ret < 0) {
+ dev_err(&client->dev, "failed to detect device\n");
+ goto failed_free;
+ } else
+ dev_info(&client->dev, "return 0x%02x\n", ret);
+
+ /* To save the power, reset BD2802 after detecting */
+ gpio_set_value(led->pdata->reset_gpio, 0);
+
+ init_rwsem(&led->rwsem);
+
+ ret = device_create_file(&client->dev, &bd2802_adv_conf_attr);
+ if (ret) {
+ dev_err(&client->dev, "failed to create sysfs file %s\n",
+ bd2802_adv_conf_attr.attr.name);
+ goto failed_free;
+ }
+
+ ret = bd2802_register_led_classdev(led);
+ if (ret < 0)
+ goto failed_unregister_dev_file;
+
+ return 0;
+
+failed_unregister_dev_file:
+ device_remove_file(&client->dev, &bd2802_adv_conf_attr);
+failed_free:
+ i2c_set_clientdata(client, NULL);
+ kfree(led);
+
+ return ret;
+}
+
+static int __exit bd2802_remove(struct i2c_client *client)
+{
+ struct bd2802_led *led = i2c_get_clientdata(client);
+
+ bd2802_unregister_led_classdev(led);
+ gpio_set_value(led->pdata->reset_gpio, 0);
+ if (led->adf_on)
+ bd2802_disable_adv_conf(led);
+ device_remove_file(&client->dev, &bd2802_adv_conf_attr);
+ i2c_set_clientdata(client, NULL);
+ kfree(led);
+
+ return 0;
+}
+
+static int bd2802_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ struct bd2802_led *led = i2c_get_clientdata(client);
+
+ gpio_set_value(led->pdata->reset_gpio, 0);
+
+ return 0;
+}
+
+static int bd2802_resume(struct i2c_client *client)
+{
+ struct bd2802_led *led = i2c_get_clientdata(client);
+
+ if (!bd2802_is_all_off(led) || led->adf_on) {
+ gpio_set_value(led->pdata->reset_gpio, 1);
+ udelay(100);
+ bd2802_restore_state(led);
+ }
+
+ return 0;
+}
+
+static const struct i2c_device_id bd2802_id[] = {
+ { "BD2802", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, bd2802_id);
+
+static struct i2c_driver bd2802_i2c_driver = {
+ .driver = {
+ .name = "BD2802",
+ },
+ .probe = bd2802_probe,
+ .remove = __exit_p(bd2802_remove),
+ .suspend = bd2802_suspend,
+ .resume = bd2802_resume,
+ .id_table = bd2802_id,
+};
+
+static int __init bd2802_init(void)
+{
+ return i2c_add_driver(&bd2802_i2c_driver);
+}
+module_init(bd2802_init);
+
+static void __exit bd2802_exit(void)
+{
+ i2c_del_driver(&bd2802_i2c_driver);
+}
+module_exit(bd2802_exit);
+
+MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>");
+MODULE_DESCRIPTION("BD2802 LED driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-dac124s085.c b/drivers/leds/leds-dac124s085.c
new file mode 100644
index 00000000000..098d9aae725
--- /dev/null
+++ b/drivers/leds/leds-dac124s085.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * LED driver for the DAC124S085 SPI DAC
+ */
+
+#include <linux/gfp.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+
+struct dac124s085_led {
+ struct led_classdev ldev;
+ struct spi_device *spi;
+ int id;
+ int brightness;
+ char name[sizeof("dac124s085-3")];
+
+ struct mutex mutex;
+ struct work_struct work;
+ spinlock_t lock;
+};
+
+struct dac124s085 {
+ struct dac124s085_led leds[4];
+};
+
+#define REG_WRITE (0 << 12)
+#define REG_WRITE_UPDATE (1 << 12)
+#define ALL_WRITE_UPDATE (2 << 12)
+#define POWER_DOWN_OUTPUT (3 << 12)
+
+static void dac124s085_led_work(struct work_struct *work)
+{
+ struct dac124s085_led *led = container_of(work, struct dac124s085_led,
+ work);
+ u16 word;
+
+ mutex_lock(&led->mutex);
+ word = cpu_to_le16(((led->id) << 14) | REG_WRITE_UPDATE |
+ (led->brightness & 0xfff));
+ spi_write(led->spi, (const u8 *)&word, sizeof(word));
+ mutex_unlock(&led->mutex);
+}
+
+static void dac124s085_set_brightness(struct led_classdev *ldev,
+ enum led_brightness brightness)
+{
+ struct dac124s085_led *led = container_of(ldev, struct dac124s085_led,
+ ldev);
+
+ spin_lock(&led->lock);
+ led->brightness = brightness;
+ schedule_work(&led->work);
+ spin_unlock(&led->lock);
+}
+
+static int dac124s085_probe(struct spi_device *spi)
+{
+ struct dac124s085 *dac;
+ struct dac124s085_led *led;
+ int i, ret;
+
+ dac = kzalloc(sizeof(*dac), GFP_KERNEL);
+ if (!dac)
+ return -ENOMEM;
+
+ spi->bits_per_word = 16;
+
+ for (i = 0; i < ARRAY_SIZE(dac->leds); i++) {
+ led = dac->leds + i;
+ led->id = i;
+ led->brightness = LED_OFF;
+ led->spi = spi;
+ snprintf(led->name, sizeof(led->name), "dac124s085-%d", i);
+ spin_lock_init(&led->lock);
+ INIT_WORK(&led->work, dac124s085_led_work);
+ mutex_init(&led->mutex);
+ led->ldev.name = led->name;
+ led->ldev.brightness = LED_OFF;
+ led->ldev.max_brightness = 0xfff;
+ led->ldev.brightness_set = dac124s085_set_brightness;
+ ret = led_classdev_register(&spi->dev, &led->ldev);
+ if (ret < 0)
+ goto eledcr;
+ }
+
+ spi_set_drvdata(spi, dac);
+
+ return 0;
+
+eledcr:
+ while (i--)
+ led_classdev_unregister(&dac->leds[i].ldev);
+
+ spi_set_drvdata(spi, NULL);
+ kfree(dac);
+ return ret;
+}
+
+static int dac124s085_remove(struct spi_device *spi)
+{
+ struct dac124s085 *dac = spi_get_drvdata(spi);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dac->leds); i++) {
+ led_classdev_unregister(&dac->leds[i].ldev);
+ cancel_work_sync(&dac->leds[i].work);
+ }
+
+ spi_set_drvdata(spi, NULL);
+ kfree(dac);
+
+ return 0;
+}
+
+static struct spi_driver dac124s085_driver = {
+ .probe = dac124s085_probe,
+ .remove = dac124s085_remove,
+ .driver = {
+ .name = "dac124s085",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init dac124s085_leds_init(void)
+{
+ return spi_register_driver(&dac124s085_driver);
+}
+
+static void __exit dac124s085_leds_exit(void)
+{
+ spi_unregister_driver(&dac124s085_driver);
+}
+
+module_init(dac124s085_leds_init);
+module_exit(dac124s085_leds_exit);
+
+MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
+MODULE_DESCRIPTION("DAC124S085 LED driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 2e3df08b649..d2109054de8 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2007 8D Technologies inc.
* Raphael Assenat <raph@8d.com>
+ * Copyright (C) 2008 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -71,11 +72,67 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
return led_dat->platform_gpio_blink_set(led_dat->gpio, delay_on, delay_off);
}
+static int __devinit create_gpio_led(const struct gpio_led *template,
+ struct gpio_led_data *led_dat, struct device *parent,
+ int (*blink_set)(unsigned, unsigned long *, unsigned long *))
+{
+ int ret;
+
+ /* skip leds that aren't available */
+ if (!gpio_is_valid(template->gpio)) {
+ printk(KERN_INFO "Skipping unavilable LED gpio %d (%s)\n",
+ template->gpio, template->name);
+ return 0;
+ }
+
+ ret = gpio_request(template->gpio, template->name);
+ if (ret < 0)
+ return ret;
+
+ led_dat->cdev.name = template->name;
+ led_dat->cdev.default_trigger = template->default_trigger;
+ led_dat->gpio = template->gpio;
+ led_dat->can_sleep = gpio_cansleep(template->gpio);
+ led_dat->active_low = template->active_low;
+ if (blink_set) {
+ led_dat->platform_gpio_blink_set = blink_set;
+ led_dat->cdev.blink_set = gpio_blink_set;
+ }
+ led_dat->cdev.brightness_set = gpio_led_set;
+ led_dat->cdev.brightness = LED_OFF;
+ if (!template->retain_state_suspended)
+ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = gpio_direction_output(led_dat->gpio, led_dat->active_low);
+ if (ret < 0)
+ goto err;
+
+ INIT_WORK(&led_dat->work, gpio_led_work);
+
+ ret = led_classdev_register(parent, &led_dat->cdev);
+ if (ret < 0)
+ goto err;
+
+ return 0;
+err:
+ gpio_free(led_dat->gpio);
+ return ret;
+}
+
+static void delete_gpio_led(struct gpio_led_data *led)
+{
+ if (!gpio_is_valid(led->gpio))
+ return;
+ led_classdev_unregister(&led->cdev);
+ cancel_work_sync(&led->work);
+ gpio_free(led->gpio);
+}
+
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
static int gpio_led_probe(struct platform_device *pdev)
{
struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
- struct gpio_led *cur_led;
- struct gpio_led_data *leds_data, *led_dat;
+ struct gpio_led_data *leds_data;
int i, ret = 0;
if (!pdata)
@@ -87,35 +144,10 @@ static int gpio_led_probe(struct platform_device *pdev)
return -ENOMEM;
for (i = 0; i < pdata->num_leds; i++) {
- cur_led = &pdata->leds[i];
- led_dat = &leds_data[i];
-
- ret = gpio_request(cur_led->gpio, cur_led->name);
+ ret = create_gpio_led(&pdata->leds[i], &leds_data[i],
+ &pdev->dev, pdata->gpio_blink_set);
if (ret < 0)
goto err;
-
- led_dat->cdev.name = cur_led->name;
- led_dat->cdev.default_trigger = cur_led->default_trigger;
- led_dat->gpio = cur_led->gpio;
- led_dat->can_sleep = gpio_cansleep(cur_led->gpio);
- led_dat->active_low = cur_led->active_low;
- if (pdata->gpio_blink_set) {
- led_dat->platform_gpio_blink_set = pdata->gpio_blink_set;
- led_dat->cdev.blink_set = gpio_blink_set;
- }
- led_dat->cdev.brightness_set = gpio_led_set;
- led_dat->cdev.brightness = LED_OFF;
- led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
-
- gpio_direction_output(led_dat->gpio, led_dat->active_low);
-
- INIT_WORK(&led_dat->work, gpio_led_work);
-
- ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
- if (ret < 0) {
- gpio_free(led_dat->gpio);
- goto err;
- }
}
platform_set_drvdata(pdev, leds_data);
@@ -123,13 +155,8 @@ static int gpio_led_probe(struct platform_device *pdev)
return 0;
err:
- if (i > 0) {
- for (i = i - 1; i >= 0; i--) {
- led_classdev_unregister(&leds_data[i].cdev);
- cancel_work_sync(&leds_data[i].work);
- gpio_free(leds_data[i].gpio);
- }
- }
+ for (i = i - 1; i >= 0; i--)
+ delete_gpio_led(&leds_data[i]);
kfree(leds_data);
@@ -144,11 +171,8 @@ static int __devexit gpio_led_remove(struct platform_device *pdev)
leds_data = platform_get_drvdata(pdev);
- for (i = 0; i < pdata->num_leds; i++) {
- led_classdev_unregister(&leds_data[i].cdev);
- cancel_work_sync(&leds_data[i].work);
- gpio_free(leds_data[i].gpio);
- }
+ for (i = 0; i < pdata->num_leds; i++)
+ delete_gpio_led(&leds_data[i]);
kfree(leds_data);
@@ -164,20 +188,133 @@ static struct platform_driver gpio_led_driver = {
},
};
+MODULE_ALIAS("platform:leds-gpio");
+#endif /* CONFIG_LEDS_GPIO_PLATFORM */
+
+/* Code to create from OpenFirmware platform devices */
+#ifdef CONFIG_LEDS_GPIO_OF
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+
+struct gpio_led_of_platform_data {
+ int num_leds;
+ struct gpio_led_data led_data[];
+};
+
+static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct device_node *np = ofdev->node, *child;
+ struct gpio_led led;
+ struct gpio_led_of_platform_data *pdata;
+ int count = 0, ret;
+
+ /* count LEDs defined by this device, so we know how much to allocate */
+ for_each_child_of_node(np, child)
+ count++;
+ if (!count)
+ return 0; /* or ENODEV? */
+
+ pdata = kzalloc(sizeof(*pdata) + sizeof(struct gpio_led_data) * count,
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ memset(&led, 0, sizeof(led));
+ for_each_child_of_node(np, child) {
+ enum of_gpio_flags flags;
+
+ led.gpio = of_get_gpio_flags(child, 0, &flags);
+ led.active_low = flags & OF_GPIO_ACTIVE_LOW;
+ led.name = of_get_property(child, "label", NULL) ? : child->name;
+ led.default_trigger =
+ of_get_property(child, "linux,default-trigger", NULL);
+
+ ret = create_gpio_led(&led, &pdata->led_data[pdata->num_leds++],
+ &ofdev->dev, NULL);
+ if (ret < 0) {
+ of_node_put(child);
+ goto err;
+ }
+ }
+
+ dev_set_drvdata(&ofdev->dev, pdata);
+
+ return 0;
+
+err:
+ for (count = pdata->num_leds - 2; count >= 0; count--)
+ delete_gpio_led(&pdata->led_data[count]);
+
+ kfree(pdata);
+
+ return ret;
+}
+
+static int __devexit of_gpio_leds_remove(struct of_device *ofdev)
+{
+ struct gpio_led_of_platform_data *pdata = dev_get_drvdata(&ofdev->dev);
+ int i;
+
+ for (i = 0; i < pdata->num_leds; i++)
+ delete_gpio_led(&pdata->led_data[i]);
+
+ kfree(pdata);
+
+ dev_set_drvdata(&ofdev->dev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id of_gpio_leds_match[] = {
+ { .compatible = "gpio-leds", },
+ {},
+};
+
+static struct of_platform_driver of_gpio_leds_driver = {
+ .driver = {
+ .name = "of_gpio_leds",
+ .owner = THIS_MODULE,
+ },
+ .match_table = of_gpio_leds_match,
+ .probe = of_gpio_leds_probe,
+ .remove = __devexit_p(of_gpio_leds_remove),
+};
+#endif
+
static int __init gpio_led_init(void)
{
- return platform_driver_register(&gpio_led_driver);
+ int ret;
+
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
+ ret = platform_driver_register(&gpio_led_driver);
+ if (ret)
+ return ret;
+#endif
+#ifdef CONFIG_LEDS_GPIO_OF
+ ret = of_register_platform_driver(&of_gpio_leds_driver);
+#endif
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
+ if (ret)
+ platform_driver_unregister(&gpio_led_driver);
+#endif
+
+ return ret;
}
static void __exit gpio_led_exit(void)
{
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
platform_driver_unregister(&gpio_led_driver);
+#endif
+#ifdef CONFIG_LEDS_GPIO_OF
+ of_unregister_platform_driver(&of_gpio_leds_driver);
+#endif
}
module_init(gpio_led_init);
module_exit(gpio_led_exit);
-MODULE_AUTHOR("Raphael Assenat <raph@8d.com>");
+MODULE_AUTHOR("Raphael Assenat <raph@8d.com>, Trent Piepho <tpiepho@freescale.com>");
MODULE_DESCRIPTION("GPIO LED driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:leds-gpio");
diff --git a/drivers/leds/leds-h1940.c b/drivers/leds/leds-h1940.c
index 11b77a70bbc..1aa46a390a0 100644
--- a/drivers/leds/leds-h1940.c
+++ b/drivers/leds/leds-h1940.c
@@ -104,7 +104,7 @@ static struct led_classdev h1940_blueled = {
.default_trigger = "h1940-bluetooth",
};
-static int __init h1940leds_probe(struct platform_device *pdev)
+static int __devinit h1940leds_probe(struct platform_device *pdev)
{
int ret;
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index 76ec7498e2d..3937244fdca 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -1,7 +1,7 @@
/*
* pca9532.c - 16-bit Led dimmer
*
- * Copyright (C) 2008 Riku Voipio <riku.voipio@movial.fi>
+ * Copyright (C) 2008 Riku Voipio
*
* 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
@@ -169,7 +169,7 @@ static int pca9532_event(struct input_dev *dev, unsigned int type,
{
struct pca9532_data *data = input_get_drvdata(dev);
- if (type != EV_SND && (code != SND_BELL || code != SND_TONE))
+ if (!(type == EV_SND && (code == SND_BELL || code == SND_TONE)))
return -1;
/* XXX: allow different kind of beeps with psc/pwm modifications */
@@ -367,7 +367,7 @@ static void __exit pca9532_exit(void)
i2c_del_driver(&pca9532_driver);
}
-MODULE_AUTHOR("Riku Voipio <riku.voipio@movial.fi>");
+MODULE_AUTHOR("Riku Voipio");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("PCA 9532 LED dimmer");
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
new file mode 100644
index 00000000000..cdfdc8714e1
--- /dev/null
+++ b/drivers/leds/leds-pwm.c
@@ -0,0 +1,153 @@
+/*
+ * linux/drivers/leds-pwm.c
+ *
+ * simple PWM based LED control
+ *
+ * Copyright 2009 Luotao Fu @ Pengutronix (l.fu@pengutronix.de)
+ *
+ * based on leds-gpio.c by Raphael Assenat <raph@8d.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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <linux/pwm.h>
+#include <linux/leds_pwm.h>
+
+struct led_pwm_data {
+ struct led_classdev cdev;
+ struct pwm_device *pwm;
+ unsigned int active_low;
+ unsigned int period;
+ unsigned int max_brightness;
+};
+
+static void led_pwm_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct led_pwm_data *led_dat =
+ container_of(led_cdev, struct led_pwm_data, cdev);
+ unsigned int max = led_dat->max_brightness;
+ unsigned int period = led_dat->period;
+
+ if (brightness == 0) {
+ pwm_config(led_dat->pwm, 0, period);
+ pwm_disable(led_dat->pwm);
+ } else {
+ pwm_config(led_dat->pwm, brightness * period / max, period);
+ pwm_enable(led_dat->pwm);
+ }
+}
+
+static int led_pwm_probe(struct platform_device *pdev)
+{
+ struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
+ struct led_pwm *cur_led;
+ struct led_pwm_data *leds_data, *led_dat;
+ int i, ret = 0;
+
+ if (!pdata)
+ return -EBUSY;
+
+ leds_data = kzalloc(sizeof(struct led_pwm_data) * pdata->num_leds,
+ GFP_KERNEL);
+ if (!leds_data)
+ return -ENOMEM;
+
+ for (i = 0; i < pdata->num_leds; i++) {
+ cur_led = &pdata->leds[i];
+ led_dat = &leds_data[i];
+
+ led_dat->pwm = pwm_request(cur_led->pwm_id,
+ cur_led->name);
+ if (IS_ERR(led_dat->pwm)) {
+ dev_err(&pdev->dev, "unable to request PWM %d\n",
+ cur_led->pwm_id);
+ goto err;
+ }
+
+ led_dat->cdev.name = cur_led->name;
+ led_dat->cdev.default_trigger = cur_led->default_trigger;
+ led_dat->active_low = cur_led->active_low;
+ led_dat->max_brightness = cur_led->max_brightness;
+ led_dat->period = cur_led->pwm_period_ns;
+ led_dat->cdev.brightness_set = led_pwm_set;
+ led_dat->cdev.brightness = LED_OFF;
+ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
+ if (ret < 0) {
+ pwm_free(led_dat->pwm);
+ goto err;
+ }
+ }
+
+ platform_set_drvdata(pdev, leds_data);
+
+ return 0;
+
+err:
+ if (i > 0) {
+ for (i = i - 1; i >= 0; i--) {
+ led_classdev_unregister(&leds_data[i].cdev);
+ pwm_free(leds_data[i].pwm);
+ }
+ }
+
+ kfree(leds_data);
+
+ return ret;
+}
+
+static int __devexit led_pwm_remove(struct platform_device *pdev)
+{
+ int i;
+ struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
+ struct led_pwm_data *leds_data;
+
+ leds_data = platform_get_drvdata(pdev);
+
+ for (i = 0; i < pdata->num_leds; i++) {
+ led_classdev_unregister(&leds_data[i].cdev);
+ pwm_free(leds_data[i].pwm);
+ }
+
+ kfree(leds_data);
+
+ return 0;
+}
+
+static struct platform_driver led_pwm_driver = {
+ .probe = led_pwm_probe,
+ .remove = __devexit_p(led_pwm_remove),
+ .driver = {
+ .name = "leds_pwm",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init led_pwm_init(void)
+{
+ return platform_driver_register(&led_pwm_driver);
+}
+
+static void __exit led_pwm_exit(void)
+{
+ platform_driver_unregister(&led_pwm_driver);
+}
+
+module_init(led_pwm_init);
+module_exit(led_pwm_exit);
+
+MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
+MODULE_DESCRIPTION("PWM LED driver for PXA");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:leds-pwm");
diff --git a/drivers/leds/leds-rb532.c b/drivers/leds/leds-rb532.c
new file mode 100644
index 00000000000..c3525f37f73
--- /dev/null
+++ b/drivers/leds/leds-rb532.c
@@ -0,0 +1,77 @@
+/*
+ * LEDs driver for the "User LED" on Routerboard532
+ *
+ * Copyright (C) 2009 Phil Sutter <n0-1@freewrt.org>
+ *
+ * Based on leds-cobalt-qube.c by Florian Fainelly and
+ * rb-diag.c (my own standalone driver for both LED and
+ * button of Routerboard532).
+ */
+
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-rc32434/gpio.h>
+#include <asm/mach-rc32434/rb.h>
+
+static void rb532_led_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ if (brightness)
+ set_latch_u5(LO_ULED, 0);
+
+ else
+ set_latch_u5(0, LO_ULED);
+}
+
+static enum led_brightness rb532_led_get(struct led_classdev *cdev)
+{
+ return (get_latch_u5() & LO_ULED) ? LED_FULL : LED_OFF;
+}
+
+static struct led_classdev rb532_uled = {
+ .name = "uled",
+ .brightness_set = rb532_led_set,
+ .brightness_get = rb532_led_get,
+ .default_trigger = "nand-disk",
+};
+
+static int __devinit rb532_led_probe(struct platform_device *pdev)
+{
+ return led_classdev_register(&pdev->dev, &rb532_uled);
+}
+
+static int __devexit rb532_led_remove(struct platform_device *pdev)
+{
+ led_classdev_unregister(&rb532_uled);
+ return 0;
+}
+
+static struct platform_driver rb532_led_driver = {
+ .probe = rb532_led_probe,
+ .remove = __devexit_p(rb532_led_remove),
+ .driver = {
+ .name = "rb532-led",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init rb532_led_init(void)
+{
+ return platform_driver_register(&rb532_led_driver);
+}
+
+static void __exit rb532_led_exit(void)
+{
+ platform_driver_unregister(&rb532_led_driver);
+}
+
+module_init(rb532_led_init);
+module_exit(rb532_led_exit);
+
+MODULE_ALIAS("platform:rb532-led");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("User LED support for Routerboard532");
+MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>");
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c
index 4d81131542a..aa2e7ae0cda 100644
--- a/drivers/leds/leds-s3c24xx.c
+++ b/drivers/leds/leds-s3c24xx.c
@@ -102,14 +102,11 @@ static int s3c24xx_led_probe(struct platform_device *dev)
ret = led_classdev_register(&dev->dev, &led->cdev);
if (ret < 0) {
dev_err(&dev->dev, "led_classdev_register failed\n");
- goto exit_err1;
+ kfree(led);
+ return ret;
}
return 0;
-
- exit_err1:
- kfree(led);
- return ret;
}
static struct platform_driver s3c24xx_led_driver = {
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index 5edbf52c4fa..2dd8ecbfdc3 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -20,8 +20,8 @@
static inline void led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness value)
{
- if (value > LED_FULL)
- value = LED_FULL;
+ if (value > led_cdev->max_brightness)
+ value = led_cdev->max_brightness;
led_cdev->brightness = value;
if (!(led_cdev->flags & LED_SUSPENDED))
led_cdev->brightness_set(led_cdev, value);
diff --git a/drivers/leds/ledtrig-default-on.c b/drivers/leds/ledtrig-default-on.c
index 92995e40cfa..a4ef54b9d50 100644
--- a/drivers/leds/ledtrig-default-on.c
+++ b/drivers/leds/ledtrig-default-on.c
@@ -19,7 +19,7 @@
static void defon_trig_activate(struct led_classdev *led_cdev)
{
- led_set_brightness(led_cdev, LED_FULL);
+ led_set_brightness(led_cdev, led_cdev->max_brightness);
}
static struct led_trigger defon_led_trigger = {
diff --git a/drivers/leds/ledtrig-gpio.c b/drivers/leds/ledtrig-gpio.c
new file mode 100644
index 00000000000..a247ae63374
--- /dev/null
+++ b/drivers/leds/ledtrig-gpio.c
@@ -0,0 +1,239 @@
+/*
+ * ledtrig-gio.c - LED Trigger Based on GPIO events
+ *
+ * Copyright 2009 Felipe Balbi <me@felipebalbi.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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/leds.h>
+#include "leds.h"
+
+struct gpio_trig_data {
+ struct led_classdev *led;
+ struct work_struct work;
+
+ unsigned desired_brightness; /* desired brightness when led is on */
+ unsigned inverted; /* true when gpio is inverted */
+ unsigned gpio; /* gpio that triggers the leds */
+};
+
+static irqreturn_t gpio_trig_irq(int irq, void *_led)
+{
+ struct led_classdev *led = _led;
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ /* just schedule_work since gpio_get_value can sleep */
+ schedule_work(&gpio_data->work);
+
+ return IRQ_HANDLED;
+};
+
+static void gpio_trig_work(struct work_struct *work)
+{
+ struct gpio_trig_data *gpio_data = container_of(work,
+ struct gpio_trig_data, work);
+ int tmp;
+
+ if (!gpio_data->gpio)
+ return;
+
+ tmp = gpio_get_value(gpio_data->gpio);
+ if (gpio_data->inverted)
+ tmp = !tmp;
+
+ if (tmp) {
+ if (gpio_data->desired_brightness)
+ led_set_brightness(gpio_data->led,
+ gpio_data->desired_brightness);
+ else
+ led_set_brightness(gpio_data->led, LED_FULL);
+ } else {
+ led_set_brightness(gpio_data->led, LED_OFF);
+ }
+}
+
+static ssize_t gpio_trig_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ return sprintf(buf, "%u\n", gpio_data->desired_brightness);
+}
+
+static ssize_t gpio_trig_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t n)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+ unsigned desired_brightness;
+ int ret;
+
+ ret = sscanf(buf, "%u", &desired_brightness);
+ if (ret < 1 || desired_brightness > 255) {
+ dev_err(dev, "invalid value\n");
+ return -EINVAL;
+ }
+
+ gpio_data->desired_brightness = desired_brightness;
+
+ return n;
+}
+static DEVICE_ATTR(desired_brightness, 0644, gpio_trig_brightness_show,
+ gpio_trig_brightness_store);
+
+static ssize_t gpio_trig_inverted_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ return sprintf(buf, "%s\n", gpio_data->inverted ? "yes" : "no");
+}
+
+static ssize_t gpio_trig_inverted_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t n)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+ unsigned inverted;
+ int ret;
+
+ ret = sscanf(buf, "%u", &inverted);
+ if (ret < 1) {
+ dev_err(dev, "invalid value\n");
+ return -EINVAL;
+ }
+
+ gpio_data->inverted = !!inverted;
+
+ return n;
+}
+static DEVICE_ATTR(inverted, 0644, gpio_trig_inverted_show,
+ gpio_trig_inverted_store);
+
+static ssize_t gpio_trig_gpio_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ return sprintf(buf, "%u\n", gpio_data->gpio);
+}
+
+static ssize_t gpio_trig_gpio_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t n)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+ unsigned gpio;
+ int ret;
+
+ ret = sscanf(buf, "%u", &gpio);
+ if (ret < 1) {
+ dev_err(dev, "couldn't read gpio number\n");
+ flush_work(&gpio_data->work);
+ return -EINVAL;
+ }
+
+ if (!gpio) {
+ free_irq(gpio_to_irq(gpio_data->gpio), led);
+ return n;
+ }
+
+ if (gpio_data->gpio > 0 && gpio_data->gpio != gpio)
+ free_irq(gpio_to_irq(gpio_data->gpio), led);
+
+ gpio_data->gpio = gpio;
+ ret = request_irq(gpio_to_irq(gpio), gpio_trig_irq,
+ IRQF_SHARED | IRQF_TRIGGER_RISING
+ | IRQF_TRIGGER_FALLING, "ledtrig-gpio", led);
+ if (ret)
+ dev_err(dev, "request_irq failed with error %d\n", ret);
+
+ return ret ? ret : n;
+}
+static DEVICE_ATTR(gpio, 0644, gpio_trig_gpio_show, gpio_trig_gpio_store);
+
+static void gpio_trig_activate(struct led_classdev *led)
+{
+ struct gpio_trig_data *gpio_data;
+ int ret;
+
+ gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL);
+ if (!gpio_data)
+ return;
+
+ ret = device_create_file(led->dev, &dev_attr_gpio);
+ if (ret)
+ goto err_gpio;
+
+ ret = device_create_file(led->dev, &dev_attr_inverted);
+ if (ret)
+ goto err_inverted;
+
+ ret = device_create_file(led->dev, &dev_attr_desired_brightness);
+ if (ret)
+ goto err_brightness;
+
+ gpio_data->led = led;
+ led->trigger_data = gpio_data;
+ INIT_WORK(&gpio_data->work, gpio_trig_work);
+
+ return;
+
+err_brightness:
+ device_remove_file(led->dev, &dev_attr_inverted);
+
+err_inverted:
+ device_remove_file(led->dev, &dev_attr_gpio);
+
+err_gpio:
+ kfree(gpio_data);
+}
+
+static void gpio_trig_deactivate(struct led_classdev *led)
+{
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ if (gpio_data) {
+ device_remove_file(led->dev, &dev_attr_gpio);
+ device_remove_file(led->dev, &dev_attr_inverted);
+ device_remove_file(led->dev, &dev_attr_desired_brightness);
+ flush_work(&gpio_data->work);
+ free_irq(gpio_to_irq(gpio_data->gpio),led);
+ kfree(gpio_data);
+ }
+}
+
+static struct led_trigger gpio_led_trigger = {
+ .name = "gpio",
+ .activate = gpio_trig_activate,
+ .deactivate = gpio_trig_deactivate,
+};
+
+static int __init gpio_trig_init(void)
+{
+ return led_trigger_register(&gpio_led_trigger);
+}
+module_init(gpio_trig_init);
+
+static void __exit gpio_trig_exit(void)
+{
+ led_trigger_unregister(&gpio_led_trigger);
+}
+module_exit(gpio_trig_exit);
+
+MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
+MODULE_DESCRIPTION("GPIO LED trigger");
+MODULE_LICENSE("GPL");
diff --git a/drivers/leds/ledtrig-heartbeat.c b/drivers/leds/ledtrig-heartbeat.c
index 4bf8cec8b8c..c1c1ea6f817 100644
--- a/drivers/leds/ledtrig-heartbeat.c
+++ b/drivers/leds/ledtrig-heartbeat.c
@@ -47,7 +47,7 @@ static void led_heartbeat_function(unsigned long data)
msecs_to_jiffies(heartbeat_data->period);
delay = msecs_to_jiffies(70);
heartbeat_data->phase++;
- brightness = LED_FULL;
+ brightness = led_cdev->max_brightness;
break;
case 1:
delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
@@ -56,7 +56,7 @@ static void led_heartbeat_function(unsigned long data)
case 2:
delay = msecs_to_jiffies(70);
heartbeat_data->phase++;
- brightness = LED_FULL;
+ brightness = led_cdev->max_brightness;
break;
default:
delay = heartbeat_data->period - heartbeat_data->period / 4 -
diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c
index 883a577b1b9..ec099fcbcb0 100644
--- a/drivers/leds/ledtrig-ide-disk.c
+++ b/drivers/leds/ledtrig-ide-disk.c
@@ -37,7 +37,8 @@ static void ledtrig_ide_timerfunc(unsigned long data)
{
if (ide_lastactivity != ide_activity) {
ide_lastactivity = ide_activity;
- led_trigger_event(ledtrig_ide, LED_FULL);
+ /* INT_MAX will set each LED to its maximum brightness */
+ led_trigger_event(ledtrig_ide, INT_MAX);
mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
} else {
led_trigger_event(ledtrig_ide, LED_OFF);
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index 3d6531396dd..3b83406de75 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -166,7 +166,7 @@ static void timer_trig_activate(struct led_classdev *led_cdev)
timer_data->brightness_on = led_get_brightness(led_cdev);
if (timer_data->brightness_on == LED_OFF)
- timer_data->brightness_on = LED_FULL;
+ timer_data->brightness_on = led_cdev->max_brightness;
led_cdev->trigger_data = timer_data;
init_timer(&timer_data->timer);
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 2281b5098e9..36e0675be9f 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -121,6 +121,7 @@ config MD_RAID10
config MD_RAID456
tristate "RAID-4/RAID-5/RAID-6 mode"
depends on BLK_DEV_MD
+ select MD_RAID6_PQ
select ASYNC_MEMCPY
select ASYNC_XOR
---help---
@@ -151,34 +152,8 @@ config MD_RAID456
If unsure, say Y.
-config MD_RAID5_RESHAPE
- bool "Support adding drives to a raid-5 array"
- depends on MD_RAID456
- default y
- ---help---
- A RAID-5 set can be expanded by adding extra drives. This
- requires "restriping" the array which means (almost) every
- block must be written to a different place.
-
- This option allows such restriping to be done while the array
- is online.
-
- You will need mdadm version 2.4.1 or later to use this
- feature safely. During the early stage of reshape there is
- a critical section where live data is being over-written. A
- crash during this time needs extra care for recovery. The
- newer mdadm takes a copy of the data in the critical section
- and will restore it, if necessary, after a crash.
-
- The mdadm usage is e.g.
- mdadm --grow /dev/md1 --raid-disks=6
- to grow '/dev/md1' to having 6 disks.
-
- Note: The array can only be expanded, not contracted.
- There should be enough spares already present to make the new
- array workable.
-
- If unsure, say Y.
+config MD_RAID6_PQ
+ tristate
config MD_MULTIPATH
tristate "Multipath I/O support"
diff --git a/drivers/md/Makefile b/drivers/md/Makefile
index 72880b7e28d..45cc5951d92 100644
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -2,20 +2,21 @@
# Makefile for the kernel software RAID and LVM drivers.
#
-dm-mod-objs := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
+dm-mod-y += dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
dm-ioctl.o dm-io.o dm-kcopyd.o dm-sysfs.o
-dm-multipath-objs := dm-path-selector.o dm-mpath.o
-dm-snapshot-objs := dm-snap.o dm-exception-store.o dm-snap-transient.o \
+dm-multipath-y += dm-path-selector.o dm-mpath.o
+dm-snapshot-y += dm-snap.o dm-exception-store.o dm-snap-transient.o \
dm-snap-persistent.o
-dm-mirror-objs := dm-raid1.o
-md-mod-objs := md.o bitmap.o
-raid456-objs := raid5.o raid6algos.o raid6recov.o raid6tables.o \
+dm-mirror-y += dm-raid1.o
+md-mod-y += md.o bitmap.o
+raid456-y += raid5.o
+raid6_pq-y += raid6algos.o raid6recov.o raid6tables.o \
raid6int1.o raid6int2.o raid6int4.o \
raid6int8.o raid6int16.o raid6int32.o \
raid6altivec1.o raid6altivec2.o raid6altivec4.o \
raid6altivec8.o \
raid6mmx.o raid6sse1.o raid6sse2.o
-hostprogs-y := mktables
+hostprogs-y += mktables
# Note: link order is important. All raid personalities
# and must come before md.o, as they each initialise
@@ -26,6 +27,7 @@ obj-$(CONFIG_MD_LINEAR) += linear.o
obj-$(CONFIG_MD_RAID0) += raid0.o
obj-$(CONFIG_MD_RAID1) += raid1.o
obj-$(CONFIG_MD_RAID10) += raid10.o
+obj-$(CONFIG_MD_RAID6_PQ) += raid6_pq.o
obj-$(CONFIG_MD_RAID456) += raid456.o
obj-$(CONFIG_MD_MULTIPATH) += multipath.o
obj-$(CONFIG_MD_FAULTY) += faulty.o
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 71994376339..f8a9f7ab2cb 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -16,6 +16,7 @@
* wait if count gets too high, wake when it drops to half.
*/
+#include <linux/blkdev.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
@@ -26,8 +27,8 @@
#include <linux/file.h>
#include <linux/mount.h>
#include <linux/buffer_head.h>
-#include <linux/raid/md.h>
-#include <linux/raid/bitmap.h>
+#include "md.h"
+#include "bitmap.h"
/* debug macros */
@@ -111,9 +112,10 @@ static int bitmap_checkpage(struct bitmap *bitmap, unsigned long page, int creat
unsigned char *mappage;
if (page >= bitmap->pages) {
- printk(KERN_ALERT
- "%s: invalid bitmap page request: %lu (> %lu)\n",
- bmname(bitmap), page, bitmap->pages-1);
+ /* This can happen if bitmap_start_sync goes beyond
+ * End-of-device while looking for a whole page.
+ * It is harmless.
+ */
return -EINVAL;
}
@@ -265,7 +267,6 @@ static mdk_rdev_t *next_active_rdev(mdk_rdev_t *rdev, mddev_t *mddev)
list_for_each_continue_rcu(pos, &mddev->disks) {
rdev = list_entry(pos, mdk_rdev_t, same_set);
if (rdev->raid_disk >= 0 &&
- test_bit(In_sync, &rdev->flags) &&
!test_bit(Faulty, &rdev->flags)) {
/* this is a usable devices */
atomic_inc(&rdev->nr_pending);
@@ -297,7 +298,7 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
+ size/512 > 0)
/* bitmap runs in to metadata */
goto bad_alignment;
- if (rdev->data_offset + mddev->size*2
+ if (rdev->data_offset + mddev->dev_sectors
> rdev->sb_start + bitmap->offset)
/* data runs in to bitmap */
goto bad_alignment;
@@ -570,7 +571,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
reason = "unrecognized superblock version";
- else if (chunksize < PAGE_SIZE)
+ else if (chunksize < 512)
reason = "bitmap chunksize too small";
else if ((1 << ffz(~chunksize)) != chunksize)
reason = "bitmap chunksize not a power of 2";
@@ -1306,6 +1307,9 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
PRINTK(KERN_DEBUG "dec write-behind count %d/%d\n",
atomic_read(&bitmap->behind_writes), bitmap->max_write_behind);
}
+ if (bitmap->mddev->degraded)
+ /* Never clear bits or update events_cleared when degraded */
+ success = 0;
while (sectors) {
int blocks;
@@ -1345,8 +1349,8 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
}
}
-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
- int degraded)
+static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+ int degraded)
{
bitmap_counter_t *bmc;
int rv;
@@ -1374,6 +1378,29 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
return rv;
}
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+ int degraded)
+{
+ /* bitmap_start_sync must always report on multiples of whole
+ * pages, otherwise resync (which is very PAGE_SIZE based) will
+ * get confused.
+ * So call __bitmap_start_sync repeatedly (if needed) until
+ * At least PAGE_SIZE>>9 blocks are covered.
+ * Return the 'or' of the result.
+ */
+ int rv = 0;
+ int blocks1;
+
+ *blocks = 0;
+ while (*blocks < (PAGE_SIZE>>9)) {
+ rv |= __bitmap_start_sync(bitmap, offset,
+ &blocks1, degraded);
+ offset += blocks1;
+ *blocks += blocks1;
+ }
+ return rv;
+}
+
void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted)
{
bitmap_counter_t *bmc;
@@ -1443,6 +1470,8 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
wait_event(bitmap->mddev->recovery_wait,
atomic_read(&bitmap->mddev->recovery_active) == 0);
+ bitmap->mddev->curr_resync_completed = bitmap->mddev->curr_resync;
+ set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags);
sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1);
s = 0;
while (s < sector && s < bitmap->mddev->resync_max_sectors) {
diff --git a/include/linux/raid/bitmap.h b/drivers/md/bitmap.h
index e98900671ca..e98900671ca 100644
--- a/include/linux/raid/bitmap.h
+++ b/drivers/md/bitmap.h
diff --git a/drivers/md/dm-bio-list.h b/drivers/md/dm-bio-list.h
index d4509be0fe6..345098b4ca7 100644
--- a/drivers/md/dm-bio-list.h
+++ b/drivers/md/dm-bio-list.h
@@ -52,6 +52,16 @@ static inline void bio_list_add(struct bio_list *bl, struct bio *bio)
bl->tail = bio;
}
+static inline void bio_list_add_head(struct bio_list *bl, struct bio *bio)
+{
+ bio->bi_next = bl->head;
+
+ bl->head = bio;
+
+ if (!bl->tail)
+ bl->tail = bio;
+}
+
static inline void bio_list_merge(struct bio_list *bl, struct bio_list *bl2)
{
if (!bl2->head)
diff --git a/drivers/md/dm-bio-record.h b/drivers/md/dm-bio-record.h
index d3ec217847d..3a8cfa2645c 100644
--- a/drivers/md/dm-bio-record.h
+++ b/drivers/md/dm-bio-record.h
@@ -16,30 +16,56 @@
* functions in this file help the target record and restore the
* original bio state.
*/
+
+struct dm_bio_vec_details {
+#if PAGE_SIZE < 65536
+ __u16 bv_len;
+ __u16 bv_offset;
+#else
+ unsigned bv_len;
+ unsigned bv_offset;
+#endif
+};
+
struct dm_bio_details {
sector_t bi_sector;
struct block_device *bi_bdev;
unsigned int bi_size;
unsigned short bi_idx;
unsigned long bi_flags;
+ struct dm_bio_vec_details bi_io_vec[BIO_MAX_PAGES];
};
static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio)
{
+ unsigned i;
+
bd->bi_sector = bio->bi_sector;
bd->bi_bdev = bio->bi_bdev;
bd->bi_size = bio->bi_size;
bd->bi_idx = bio->bi_idx;
bd->bi_flags = bio->bi_flags;
+
+ for (i = 0; i < bio->bi_vcnt; i++) {
+ bd->bi_io_vec[i].bv_len = bio->bi_io_vec[i].bv_len;
+ bd->bi_io_vec[i].bv_offset = bio->bi_io_vec[i].bv_offset;
+ }
}
static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio)
{
+ unsigned i;
+
bio->bi_sector = bd->bi_sector;
bio->bi_bdev = bd->bi_bdev;
bio->bi_size = bd->bi_size;
bio->bi_idx = bd->bi_idx;
bio->bi_flags = bd->bi_flags;
+
+ for (i = 0; i < bio->bi_vcnt; i++) {
+ bio->bi_io_vec[i].bv_len = bd->bi_io_vec[i].bv_len;
+ bio->bi_io_vec[i].bv_offset = bd->bi_io_vec[i].bv_offset;
+ }
}
#endif
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index bfefd079a95..53394e863c7 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1156,8 +1156,7 @@ bad_ivmode:
crypto_free_ablkcipher(tfm);
bad_cipher:
/* Must zero key material before freeing */
- memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
- kfree(cc);
+ kzfree(cc);
return -EINVAL;
}
@@ -1183,8 +1182,7 @@ static void crypt_dtr(struct dm_target *ti)
dm_put_device(ti, cc->dev);
/* Must zero key material before freeing */
- memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
- kfree(cc);
+ kzfree(cc);
}
static int crypt_map(struct dm_target *ti, struct bio *bio,
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index dccbfb0e010..a2e26c24214 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -7,6 +7,7 @@
#include "dm-exception-store.h"
+#include <linux/ctype.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/vmalloc.h>
@@ -14,6 +15,257 @@
#define DM_MSG_PREFIX "snapshot exception stores"
+static LIST_HEAD(_exception_store_types);
+static DEFINE_SPINLOCK(_lock);
+
+static struct dm_exception_store_type *__find_exception_store_type(const char *name)
+{
+ struct dm_exception_store_type *type;
+
+ list_for_each_entry(type, &_exception_store_types, list)
+ if (!strcmp(name, type->name))
+ return type;
+
+ return NULL;
+}
+
+static struct dm_exception_store_type *_get_exception_store_type(const char *name)
+{
+ struct dm_exception_store_type *type;
+
+ spin_lock(&_lock);
+
+ type = __find_exception_store_type(name);
+
+ if (type && !try_module_get(type->module))
+ type = NULL;
+
+ spin_unlock(&_lock);
+
+ return type;
+}
+
+/*
+ * get_type
+ * @type_name
+ *
+ * Attempt to retrieve the dm_exception_store_type by name. If not already
+ * available, attempt to load the appropriate module.
+ *
+ * Exstore modules are named "dm-exstore-" followed by the 'type_name'.
+ * Modules may contain multiple types.
+ * This function will first try the module "dm-exstore-<type_name>",
+ * then truncate 'type_name' on the last '-' and try again.
+ *
+ * For example, if type_name was "clustered-shared", it would search
+ * 'dm-exstore-clustered-shared' then 'dm-exstore-clustered'.
+ *
+ * 'dm-exception-store-<type_name>' is too long of a name in my
+ * opinion, which is why I've chosen to have the files
+ * containing exception store implementations be 'dm-exstore-<type_name>'.
+ * If you want your module to be autoloaded, you will follow this
+ * naming convention.
+ *
+ * Returns: dm_exception_store_type* on success, NULL on failure
+ */
+static struct dm_exception_store_type *get_type(const char *type_name)
+{
+ char *p, *type_name_dup;
+ struct dm_exception_store_type *type;
+
+ type = _get_exception_store_type(type_name);
+ if (type)
+ return type;
+
+ type_name_dup = kstrdup(type_name, GFP_KERNEL);
+ if (!type_name_dup) {
+ DMERR("No memory left to attempt load for \"%s\"", type_name);
+ return NULL;
+ }
+
+ while (request_module("dm-exstore-%s", type_name_dup) ||
+ !(type = _get_exception_store_type(type_name))) {
+ p = strrchr(type_name_dup, '-');
+ if (!p)
+ break;
+ p[0] = '\0';
+ }
+
+ if (!type)
+ DMWARN("Module for exstore type \"%s\" not found.", type_name);
+
+ kfree(type_name_dup);
+
+ return type;
+}
+
+static void put_type(struct dm_exception_store_type *type)
+{
+ spin_lock(&_lock);
+ module_put(type->module);
+ spin_unlock(&_lock);
+}
+
+int dm_exception_store_type_register(struct dm_exception_store_type *type)
+{
+ int r = 0;
+
+ spin_lock(&_lock);
+ if (!__find_exception_store_type(type->name))
+ list_add(&type->list, &_exception_store_types);
+ else
+ r = -EEXIST;
+ spin_unlock(&_lock);
+
+ return r;
+}
+EXPORT_SYMBOL(dm_exception_store_type_register);
+
+int dm_exception_store_type_unregister(struct dm_exception_store_type *type)
+{
+ spin_lock(&_lock);
+
+ if (!__find_exception_store_type(type->name)) {
+ spin_unlock(&_lock);
+ return -EINVAL;
+ }
+
+ list_del(&type->list);
+
+ spin_unlock(&_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(dm_exception_store_type_unregister);
+
+/*
+ * Round a number up to the nearest 'size' boundary. size must
+ * be a power of 2.
+ */
+static ulong round_up(ulong n, ulong size)
+{
+ size--;
+ return (n + size) & ~size;
+}
+
+static int set_chunk_size(struct dm_exception_store *store,
+ const char *chunk_size_arg, char **error)
+{
+ unsigned long chunk_size_ulong;
+ char *value;
+
+ chunk_size_ulong = simple_strtoul(chunk_size_arg, &value, 10);
+ if (*chunk_size_arg == '\0' || *value != '\0') {
+ *error = "Invalid chunk size";
+ return -EINVAL;
+ }
+
+ if (!chunk_size_ulong) {
+ store->chunk_size = store->chunk_mask = store->chunk_shift = 0;
+ return 0;
+ }
+
+ /*
+ * Chunk size must be multiple of page size. Silently
+ * round up if it's not.
+ */
+ chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9);
+
+ /* Check chunk_size is a power of 2 */
+ if (!is_power_of_2(chunk_size_ulong)) {
+ *error = "Chunk size is not a power of 2";
+ return -EINVAL;
+ }
+
+ /* Validate the chunk size against the device block size */
+ if (chunk_size_ulong % (bdev_hardsect_size(store->cow->bdev) >> 9)) {
+ *error = "Chunk size is not a multiple of device blocksize";
+ return -EINVAL;
+ }
+
+ store->chunk_size = chunk_size_ulong;
+ store->chunk_mask = chunk_size_ulong - 1;
+ store->chunk_shift = ffs(chunk_size_ulong) - 1;
+
+ return 0;
+}
+
+int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+ unsigned *args_used,
+ struct dm_exception_store **store)
+{
+ int r = 0;
+ struct dm_exception_store_type *type;
+ struct dm_exception_store *tmp_store;
+ char persistent;
+
+ if (argc < 3) {
+ ti->error = "Insufficient exception store arguments";
+ return -EINVAL;
+ }
+
+ tmp_store = kmalloc(sizeof(*tmp_store), GFP_KERNEL);
+ if (!tmp_store) {
+ ti->error = "Exception store allocation failed";
+ return -ENOMEM;
+ }
+
+ persistent = toupper(*argv[1]);
+ if (persistent != 'P' && persistent != 'N') {
+ ti->error = "Persistent flag is not P or N";
+ return -EINVAL;
+ }
+
+ type = get_type(argv[1]);
+ if (!type) {
+ ti->error = "Exception store type not recognised";
+ r = -EINVAL;
+ goto bad_type;
+ }
+
+ tmp_store->type = type;
+ tmp_store->ti = ti;
+
+ r = dm_get_device(ti, argv[0], 0, 0,
+ FMODE_READ | FMODE_WRITE, &tmp_store->cow);
+ if (r) {
+ ti->error = "Cannot get COW device";
+ goto bad_cow;
+ }
+
+ r = set_chunk_size(tmp_store, argv[2], &ti->error);
+ if (r)
+ goto bad_cow;
+
+ r = type->ctr(tmp_store, 0, NULL);
+ if (r) {
+ ti->error = "Exception store type constructor failed";
+ goto bad_ctr;
+ }
+
+ *args_used = 3;
+ *store = tmp_store;
+ return 0;
+
+bad_ctr:
+ dm_put_device(ti, tmp_store->cow);
+bad_cow:
+ put_type(type);
+bad_type:
+ kfree(tmp_store);
+ return r;
+}
+EXPORT_SYMBOL(dm_exception_store_create);
+
+void dm_exception_store_destroy(struct dm_exception_store *store)
+{
+ store->type->dtr(store);
+ dm_put_device(store->ti, store->cow);
+ put_type(store->type);
+ kfree(store);
+}
+EXPORT_SYMBOL(dm_exception_store_destroy);
+
int dm_exception_store_init(void)
{
int r;
diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h
index bb9f33d5daa..0a2e6e7f67b 100644
--- a/drivers/md/dm-exception-store.h
+++ b/drivers/md/dm-exception-store.h
@@ -37,11 +37,18 @@ struct dm_snap_exception {
* Abstraction to handle the meta/layout of exception stores (the
* COW device).
*/
-struct dm_exception_store {
+struct dm_exception_store;
+struct dm_exception_store_type {
+ const char *name;
+ struct module *module;
+
+ int (*ctr) (struct dm_exception_store *store,
+ unsigned argc, char **argv);
+
/*
* Destroys this object when you've finished with it.
*/
- void (*destroy) (struct dm_exception_store *store);
+ void (*dtr) (struct dm_exception_store *store);
/*
* The target shouldn't read the COW device until this is
@@ -72,8 +79,9 @@ struct dm_exception_store {
*/
void (*drop_snapshot) (struct dm_exception_store *store);
- int (*status) (struct dm_exception_store *store, status_type_t status,
- char *result, unsigned int maxlen);
+ unsigned (*status) (struct dm_exception_store *store,
+ status_type_t status, char *result,
+ unsigned maxlen);
/*
* Return how full the snapshot is.
@@ -82,7 +90,21 @@ struct dm_exception_store {
sector_t *numerator,
sector_t *denominator);
- struct dm_snapshot *snap;
+ /* For internal device-mapper use only. */
+ struct list_head list;
+};
+
+struct dm_exception_store {
+ struct dm_exception_store_type *type;
+ struct dm_target *ti;
+
+ struct dm_dev *cow;
+
+ /* Size of data blocks saved - must be a power of 2 */
+ chunk_t chunk_size;
+ chunk_t chunk_mask;
+ chunk_t chunk_shift;
+
void *context;
};
@@ -129,6 +151,28 @@ static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e)
# endif
+/*
+ * Return the number of sectors in the device.
+ */
+static inline sector_t get_dev_size(struct block_device *bdev)
+{
+ return bdev->bd_inode->i_size >> SECTOR_SHIFT;
+}
+
+static inline chunk_t sector_to_chunk(struct dm_exception_store *store,
+ sector_t sector)
+{
+ return (sector & ~store->chunk_mask) >> store->chunk_shift;
+}
+
+int dm_exception_store_type_register(struct dm_exception_store_type *type);
+int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
+
+int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+ unsigned *args_used,
+ struct dm_exception_store **store);
+void dm_exception_store_destroy(struct dm_exception_store *store);
+
int dm_exception_store_init(void);
void dm_exception_store_exit(void);
@@ -141,8 +185,4 @@ void dm_persistent_snapshot_exit(void);
int dm_transient_snapshot_init(void);
void dm_transient_snapshot_exit(void);
-int dm_create_persistent(struct dm_exception_store *store);
-
-int dm_create_transient(struct dm_exception_store *store);
-
#endif /* _LINUX_DM_EXCEPTION_STORE */
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 36e2b5e46a6..e73aabd61cd 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -370,16 +370,13 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,
while (1) {
set_current_state(TASK_UNINTERRUPTIBLE);
- if (!atomic_read(&io.count) || signal_pending(current))
+ if (!atomic_read(&io.count))
break;
io_schedule();
}
set_current_state(TASK_RUNNING);
- if (atomic_read(&io.count))
- return -EINTR;
-
if (error_bits)
*error_bits = io.error_bits;
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index f01096549a9..823ceba6efa 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1047,6 +1047,19 @@ static int populate_table(struct dm_table *table,
return dm_table_complete(table);
}
+static int table_prealloc_integrity(struct dm_table *t,
+ struct mapped_device *md)
+{
+ struct list_head *devices = dm_table_get_devices(t);
+ struct dm_dev_internal *dd;
+
+ list_for_each_entry(dd, devices, list)
+ if (bdev_get_integrity(dd->dm_dev.bdev))
+ return blk_integrity_register(dm_disk(md), NULL);
+
+ return 0;
+}
+
static int table_load(struct dm_ioctl *param, size_t param_size)
{
int r;
@@ -1068,6 +1081,14 @@ static int table_load(struct dm_ioctl *param, size_t param_size)
goto out;
}
+ r = table_prealloc_integrity(t, md);
+ if (r) {
+ DMERR("%s: could not register integrity profile.",
+ dm_device_name(md));
+ dm_table_destroy(t);
+ goto out;
+ }
+
down_write(&_hash_lock);
hc = dm_get_mdptr(md);
if (!hc || hc->md != md) {
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c
index 0a225da2127..3e3fc06cb86 100644
--- a/drivers/md/dm-kcopyd.c
+++ b/drivers/md/dm-kcopyd.c
@@ -297,7 +297,8 @@ static int run_complete_job(struct kcopyd_job *job)
dm_kcopyd_notify_fn fn = job->fn;
struct dm_kcopyd_client *kc = job->kc;
- kcopyd_put_pages(kc, job->pages);
+ if (job->pages)
+ kcopyd_put_pages(kc, job->pages);
mempool_free(job, kc->job_pool);
fn(read_err, write_err, context);
@@ -461,6 +462,7 @@ static void segment_complete(int read_err, unsigned long write_err,
sector_t progress = 0;
sector_t count = 0;
struct kcopyd_job *job = (struct kcopyd_job *) context;
+ struct dm_kcopyd_client *kc = job->kc;
mutex_lock(&job->lock);
@@ -490,7 +492,7 @@ static void segment_complete(int read_err, unsigned long write_err,
if (count) {
int i;
- struct kcopyd_job *sub_job = mempool_alloc(job->kc->job_pool,
+ struct kcopyd_job *sub_job = mempool_alloc(kc->job_pool,
GFP_NOIO);
*sub_job = *job;
@@ -509,13 +511,16 @@ static void segment_complete(int read_err, unsigned long write_err,
} else if (atomic_dec_and_test(&job->sub_jobs)) {
/*
- * To avoid a race we must keep the job around
- * until after the notify function has completed.
- * Otherwise the client may try and stop the job
- * after we've completed.
+ * Queue the completion callback to the kcopyd thread.
+ *
+ * Some callers assume that all the completions are called
+ * from a single thread and don't race with each other.
+ *
+ * We must not call the callback directly here because this
+ * code may not be executing in the thread.
*/
- job->fn(read_err, write_err, job->context);
- mempool_free(job, job->kc->job_pool);
+ push(&kc->complete_jobs, job);
+ wake(kc);
}
}
@@ -528,6 +533,8 @@ static void split_job(struct kcopyd_job *job)
{
int i;
+ atomic_inc(&job->kc->nr_jobs);
+
atomic_set(&job->sub_jobs, SPLIT_COUNT);
for (i = 0; i < SPLIT_COUNT; i++)
segment_complete(0, 0u, job);
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index bfa107f59d9..79fb53e51c7 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -142,7 +142,6 @@ static struct target_type linear_target = {
.status = linear_status,
.ioctl = linear_ioctl,
.merge = linear_merge,
- .features = DM_TARGET_SUPPORTS_BARRIERS,
};
int __init dm_linear_init(void)
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 737961f275c..be233bc4d91 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -16,40 +16,29 @@
#define DM_MSG_PREFIX "dirty region log"
-struct dm_dirty_log_internal {
- struct dm_dirty_log_type *type;
-
- struct list_head list;
- long use;
-};
-
static LIST_HEAD(_log_types);
static DEFINE_SPINLOCK(_lock);
-static struct dm_dirty_log_internal *__find_dirty_log_type(const char *name)
+static struct dm_dirty_log_type *__find_dirty_log_type(const char *name)
{
- struct dm_dirty_log_internal *log_type;
+ struct dm_dirty_log_type *log_type;
list_for_each_entry(log_type, &_log_types, list)
- if (!strcmp(name, log_type->type->name))
+ if (!strcmp(name, log_type->name))
return log_type;
return NULL;
}
-static struct dm_dirty_log_internal *_get_dirty_log_type(const char *name)
+static struct dm_dirty_log_type *_get_dirty_log_type(const char *name)
{
- struct dm_dirty_log_internal *log_type;
+ struct dm_dirty_log_type *log_type;
spin_lock(&_lock);
log_type = __find_dirty_log_type(name);
- if (log_type) {
- if (!log_type->use && !try_module_get(log_type->type->module))
- log_type = NULL;
- else
- log_type->use++;
- }
+ if (log_type && !try_module_get(log_type->module))
+ log_type = NULL;
spin_unlock(&_lock);
@@ -76,14 +65,14 @@ static struct dm_dirty_log_internal *_get_dirty_log_type(const char *name)
static struct dm_dirty_log_type *get_type(const char *type_name)
{
char *p, *type_name_dup;
- struct dm_dirty_log_internal *log_type;
+ struct dm_dirty_log_type *log_type;
if (!type_name)
return NULL;
log_type = _get_dirty_log_type(type_name);
if (log_type)
- return log_type->type;
+ return log_type;
type_name_dup = kstrdup(type_name, GFP_KERNEL);
if (!type_name_dup) {
@@ -105,56 +94,33 @@ static struct dm_dirty_log_type *get_type(const char *type_name)
kfree(type_name_dup);
- return log_type ? log_type->type : NULL;
+ return log_type;
}
static void put_type(struct dm_dirty_log_type *type)
{
- struct dm_dirty_log_internal *log_type;
-
if (!type)
return;
spin_lock(&_lock);
- log_type = __find_dirty_log_type(type->name);
- if (!log_type)
+ if (!__find_dirty_log_type(type->name))
goto out;
- if (!--log_type->use)
- module_put(type->module);
-
- BUG_ON(log_type->use < 0);
+ module_put(type->module);
out:
spin_unlock(&_lock);
}
-static struct dm_dirty_log_internal *_alloc_dirty_log_type(struct dm_dirty_log_type *type)
-{
- struct dm_dirty_log_internal *log_type = kzalloc(sizeof(*log_type),
- GFP_KERNEL);
-
- if (log_type)
- log_type->type = type;
-
- return log_type;
-}
-
int dm_dirty_log_type_register(struct dm_dirty_log_type *type)
{
- struct dm_dirty_log_internal *log_type = _alloc_dirty_log_type(type);
int r = 0;
- if (!log_type)
- return -ENOMEM;
-
spin_lock(&_lock);
if (!__find_dirty_log_type(type->name))
- list_add(&log_type->list, &_log_types);
- else {
- kfree(log_type);
+ list_add(&type->list, &_log_types);
+ else
r = -EEXIST;
- }
spin_unlock(&_lock);
return r;
@@ -163,25 +129,16 @@ EXPORT_SYMBOL(dm_dirty_log_type_register);
int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type)
{
- struct dm_dirty_log_internal *log_type;
-
spin_lock(&_lock);
- log_type = __find_dirty_log_type(type->name);
- if (!log_type) {
+ if (!__find_dirty_log_type(type->name)) {
spin_unlock(&_lock);
return -EINVAL;
}
- if (log_type->use) {
- spin_unlock(&_lock);
- return -ETXTBSY;
- }
-
- list_del(&log_type->list);
+ list_del(&type->list);
spin_unlock(&_lock);
- kfree(log_type);
return 0;
}
diff --git a/drivers/md/dm-path-selector.c b/drivers/md/dm-path-selector.c
index 96ea226155b..42c04f04a0c 100644
--- a/drivers/md/dm-path-selector.c
+++ b/drivers/md/dm-path-selector.c
@@ -17,9 +17,7 @@
struct ps_internal {
struct path_selector_type pst;
-
struct list_head list;
- long use;
};
#define pst_to_psi(__pst) container_of((__pst), struct ps_internal, pst)
@@ -45,12 +43,8 @@ static struct ps_internal *get_path_selector(const char *name)
down_read(&_ps_lock);
psi = __find_path_selector_type(name);
- if (psi) {
- if ((psi->use == 0) && !try_module_get(psi->pst.module))
- psi = NULL;
- else
- psi->use++;
- }
+ if (psi && !try_module_get(psi->pst.module))
+ psi = NULL;
up_read(&_ps_lock);
return psi;
@@ -84,11 +78,7 @@ void dm_put_path_selector(struct path_selector_type *pst)
if (!psi)
goto out;
- if (--psi->use == 0)
- module_put(psi->pst.module);
-
- BUG_ON(psi->use < 0);
-
+ module_put(psi->pst.module);
out:
up_read(&_ps_lock);
}
@@ -136,11 +126,6 @@ int dm_unregister_path_selector(struct path_selector_type *pst)
return -EINVAL;
}
- if (psi->use) {
- up_write(&_ps_lock);
- return -ETXTBSY;
- }
-
list_del(&psi->list);
up_write(&_ps_lock);
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 4d6bc101962..536ef0bef15 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -145,6 +145,8 @@ struct dm_raid1_read_record {
struct dm_bio_details details;
};
+static struct kmem_cache *_dm_raid1_read_record_cache;
+
/*
* Every mirror should look like this one.
*/
@@ -586,6 +588,9 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
int state;
struct bio *bio;
struct bio_list sync, nosync, recover, *this_list = NULL;
+ struct bio_list requeue;
+ struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
+ region_t region;
if (!writes->head)
return;
@@ -596,10 +601,18 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
bio_list_init(&sync);
bio_list_init(&nosync);
bio_list_init(&recover);
+ bio_list_init(&requeue);
while ((bio = bio_list_pop(writes))) {
- state = dm_rh_get_state(ms->rh,
- dm_rh_bio_to_region(ms->rh, bio), 1);
+ region = dm_rh_bio_to_region(ms->rh, bio);
+
+ if (log->type->is_remote_recovering &&
+ log->type->is_remote_recovering(log, region)) {
+ bio_list_add(&requeue, bio);
+ continue;
+ }
+
+ state = dm_rh_get_state(ms->rh, region, 1);
switch (state) {
case DM_RH_CLEAN:
case DM_RH_DIRTY:
@@ -619,6 +632,16 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
}
/*
+ * Add bios that are delayed due to remote recovery
+ * back on to the write queue
+ */
+ if (unlikely(requeue.head)) {
+ spin_lock_irq(&ms->lock);
+ bio_list_merge(&ms->writes, &requeue);
+ spin_unlock_irq(&ms->lock);
+ }
+
+ /*
* Increment the pending counts for any regions that will
* be written to (writes to recover regions are going to
* be delayed).
@@ -764,9 +787,9 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors,
atomic_set(&ms->suspend, 0);
atomic_set(&ms->default_mirror, DEFAULT_MIRROR);
- len = sizeof(struct dm_raid1_read_record);
- ms->read_record_pool = mempool_create_kmalloc_pool(MIN_READ_RECORDS,
- len);
+ ms->read_record_pool = mempool_create_slab_pool(MIN_READ_RECORDS,
+ _dm_raid1_read_record_cache);
+
if (!ms->read_record_pool) {
ti->error = "Error creating mirror read_record_pool";
kfree(ms);
@@ -1279,16 +1302,31 @@ static int __init dm_mirror_init(void)
{
int r;
+ _dm_raid1_read_record_cache = KMEM_CACHE(dm_raid1_read_record, 0);
+ if (!_dm_raid1_read_record_cache) {
+ DMERR("Can't allocate dm_raid1_read_record cache");
+ r = -ENOMEM;
+ goto bad_cache;
+ }
+
r = dm_register_target(&mirror_target);
- if (r < 0)
+ if (r < 0) {
DMERR("Failed to register mirror target");
+ goto bad_target;
+ }
+
+ return 0;
+bad_target:
+ kmem_cache_destroy(_dm_raid1_read_record_cache);
+bad_cache:
return r;
}
static void __exit dm_mirror_exit(void)
{
dm_unregister_target(&mirror_target);
+ kmem_cache_destroy(_dm_raid1_read_record_cache);
}
/* Module hooks */
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index 936b34e0959..e75c6dd76a9 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -6,7 +6,6 @@
*/
#include "dm-exception-store.h"
-#include "dm-snap.h"
#include <linux/mm.h>
#include <linux/pagemap.h>
@@ -89,7 +88,7 @@ struct commit_callback {
* The top level structure for a persistent exception store.
*/
struct pstore {
- struct dm_snapshot *snap; /* up pointer to my snapshot */
+ struct dm_exception_store *store;
int version;
int valid;
uint32_t exceptions_per_area;
@@ -141,7 +140,7 @@ static int alloc_area(struct pstore *ps)
int r = -ENOMEM;
size_t len;
- len = ps->snap->chunk_size << SECTOR_SHIFT;
+ len = ps->store->chunk_size << SECTOR_SHIFT;
/*
* Allocate the chunk_size block of memory that will hold
@@ -163,9 +162,12 @@ static int alloc_area(struct pstore *ps)
static void free_area(struct pstore *ps)
{
- vfree(ps->area);
+ if (ps->area)
+ vfree(ps->area);
ps->area = NULL;
- vfree(ps->zero_area);
+
+ if (ps->zero_area)
+ vfree(ps->zero_area);
ps->zero_area = NULL;
}
@@ -189,9 +191,9 @@ static void do_metadata(struct work_struct *work)
static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata)
{
struct dm_io_region where = {
- .bdev = ps->snap->cow->bdev,
- .sector = ps->snap->chunk_size * chunk,
- .count = ps->snap->chunk_size,
+ .bdev = ps->store->cow->bdev,
+ .sector = ps->store->chunk_size * chunk,
+ .count = ps->store->chunk_size,
};
struct dm_io_request io_req = {
.bi_rw = rw,
@@ -247,15 +249,15 @@ static int area_io(struct pstore *ps, int rw)
static void zero_memory_area(struct pstore *ps)
{
- memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
+ memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT);
}
static int zero_disk_area(struct pstore *ps, chunk_t area)
{
struct dm_io_region where = {
- .bdev = ps->snap->cow->bdev,
- .sector = ps->snap->chunk_size * area_location(ps, area),
- .count = ps->snap->chunk_size,
+ .bdev = ps->store->cow->bdev,
+ .sector = ps->store->chunk_size * area_location(ps, area),
+ .count = ps->store->chunk_size,
};
struct dm_io_request io_req = {
.bi_rw = WRITE,
@@ -278,15 +280,15 @@ static int read_header(struct pstore *ps, int *new_snapshot)
/*
* Use default chunk size (or hardsect_size, if larger) if none supplied
*/
- if (!ps->snap->chunk_size) {
- ps->snap->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
- bdev_hardsect_size(ps->snap->cow->bdev) >> 9);
- ps->snap->chunk_mask = ps->snap->chunk_size - 1;
- ps->snap->chunk_shift = ffs(ps->snap->chunk_size) - 1;
+ if (!ps->store->chunk_size) {
+ ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
+ bdev_hardsect_size(ps->store->cow->bdev) >> 9);
+ ps->store->chunk_mask = ps->store->chunk_size - 1;
+ ps->store->chunk_shift = ffs(ps->store->chunk_size) - 1;
chunk_size_supplied = 0;
}
- ps->io_client = dm_io_client_create(sectors_to_pages(ps->snap->
+ ps->io_client = dm_io_client_create(sectors_to_pages(ps->store->
chunk_size));
if (IS_ERR(ps->io_client))
return PTR_ERR(ps->io_client);
@@ -317,22 +319,22 @@ static int read_header(struct pstore *ps, int *new_snapshot)
ps->version = le32_to_cpu(dh->version);
chunk_size = le32_to_cpu(dh->chunk_size);
- if (!chunk_size_supplied || ps->snap->chunk_size == chunk_size)
+ if (!chunk_size_supplied || ps->store->chunk_size == chunk_size)
return 0;
DMWARN("chunk size %llu in device metadata overrides "
"table chunk size of %llu.",
(unsigned long long)chunk_size,
- (unsigned long long)ps->snap->chunk_size);
+ (unsigned long long)ps->store->chunk_size);
/* We had a bogus chunk_size. Fix stuff up. */
free_area(ps);
- ps->snap->chunk_size = chunk_size;
- ps->snap->chunk_mask = chunk_size - 1;
- ps->snap->chunk_shift = ffs(chunk_size) - 1;
+ ps->store->chunk_size = chunk_size;
+ ps->store->chunk_mask = chunk_size - 1;
+ ps->store->chunk_shift = ffs(chunk_size) - 1;
- r = dm_io_client_resize(sectors_to_pages(ps->snap->chunk_size),
+ r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size),
ps->io_client);
if (r)
return r;
@@ -349,13 +351,13 @@ static int write_header(struct pstore *ps)
{
struct disk_header *dh;
- memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
+ memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT);
dh = (struct disk_header *) ps->area;
dh->magic = cpu_to_le32(SNAP_MAGIC);
dh->valid = cpu_to_le32(ps->valid);
dh->version = cpu_to_le32(ps->version);
- dh->chunk_size = cpu_to_le32(ps->snap->chunk_size);
+ dh->chunk_size = cpu_to_le32(ps->store->chunk_size);
return chunk_io(ps, 0, WRITE, 1);
}
@@ -474,18 +476,25 @@ static struct pstore *get_info(struct dm_exception_store *store)
static void persistent_fraction_full(struct dm_exception_store *store,
sector_t *numerator, sector_t *denominator)
{
- *numerator = get_info(store)->next_free * store->snap->chunk_size;
- *denominator = get_dev_size(store->snap->cow->bdev);
+ *numerator = get_info(store)->next_free * store->chunk_size;
+ *denominator = get_dev_size(store->cow->bdev);
}
-static void persistent_destroy(struct dm_exception_store *store)
+static void persistent_dtr(struct dm_exception_store *store)
{
struct pstore *ps = get_info(store);
destroy_workqueue(ps->metadata_wq);
- dm_io_client_destroy(ps->io_client);
- vfree(ps->callbacks);
+
+ /* Created in read_header */
+ if (ps->io_client)
+ dm_io_client_destroy(ps->io_client);
free_area(ps);
+
+ /* Allocated in persistent_read_metadata */
+ if (ps->callbacks)
+ vfree(ps->callbacks);
+
kfree(ps);
}
@@ -507,7 +516,7 @@ static int persistent_read_metadata(struct dm_exception_store *store,
/*
* Now we know correct chunk_size, complete the initialisation.
*/
- ps->exceptions_per_area = (ps->snap->chunk_size << SECTOR_SHIFT) /
+ ps->exceptions_per_area = (ps->store->chunk_size << SECTOR_SHIFT) /
sizeof(struct disk_exception);
ps->callbacks = dm_vcalloc(ps->exceptions_per_area,
sizeof(*ps->callbacks));
@@ -564,10 +573,10 @@ static int persistent_prepare_exception(struct dm_exception_store *store,
struct pstore *ps = get_info(store);
uint32_t stride;
chunk_t next_free;
- sector_t size = get_dev_size(store->snap->cow->bdev);
+ sector_t size = get_dev_size(store->cow->bdev);
/* Is there enough room ? */
- if (size < ((ps->next_free + 1) * store->snap->chunk_size))
+ if (size < ((ps->next_free + 1) * store->chunk_size))
return -ENOSPC;
e->new_chunk = ps->next_free;
@@ -656,16 +665,17 @@ static void persistent_drop_snapshot(struct dm_exception_store *store)
DMWARN("write header failed");
}
-int dm_create_persistent(struct dm_exception_store *store)
+static int persistent_ctr(struct dm_exception_store *store,
+ unsigned argc, char **argv)
{
struct pstore *ps;
/* allocate the pstore */
- ps = kmalloc(sizeof(*ps), GFP_KERNEL);
+ ps = kzalloc(sizeof(*ps), GFP_KERNEL);
if (!ps)
return -ENOMEM;
- ps->snap = store->snap;
+ ps->store = store;
ps->valid = 1;
ps->version = SNAPSHOT_DISK_VERSION;
ps->area = NULL;
@@ -683,22 +693,77 @@ int dm_create_persistent(struct dm_exception_store *store)
return -ENOMEM;
}
- store->destroy = persistent_destroy;
- store->read_metadata = persistent_read_metadata;
- store->prepare_exception = persistent_prepare_exception;
- store->commit_exception = persistent_commit_exception;
- store->drop_snapshot = persistent_drop_snapshot;
- store->fraction_full = persistent_fraction_full;
store->context = ps;
return 0;
}
+static unsigned persistent_status(struct dm_exception_store *store,
+ status_type_t status, char *result,
+ unsigned maxlen)
+{
+ unsigned sz = 0;
+
+ switch (status) {
+ case STATUSTYPE_INFO:
+ break;
+ case STATUSTYPE_TABLE:
+ DMEMIT(" %s P %llu", store->cow->name,
+ (unsigned long long)store->chunk_size);
+ }
+
+ return sz;
+}
+
+static struct dm_exception_store_type _persistent_type = {
+ .name = "persistent",
+ .module = THIS_MODULE,
+ .ctr = persistent_ctr,
+ .dtr = persistent_dtr,
+ .read_metadata = persistent_read_metadata,
+ .prepare_exception = persistent_prepare_exception,
+ .commit_exception = persistent_commit_exception,
+ .drop_snapshot = persistent_drop_snapshot,
+ .fraction_full = persistent_fraction_full,
+ .status = persistent_status,
+};
+
+static struct dm_exception_store_type _persistent_compat_type = {
+ .name = "P",
+ .module = THIS_MODULE,
+ .ctr = persistent_ctr,
+ .dtr = persistent_dtr,
+ .read_metadata = persistent_read_metadata,
+ .prepare_exception = persistent_prepare_exception,
+ .commit_exception = persistent_commit_exception,
+ .drop_snapshot = persistent_drop_snapshot,
+ .fraction_full = persistent_fraction_full,
+ .status = persistent_status,
+};
+
int dm_persistent_snapshot_init(void)
{
- return 0;
+ int r;
+
+ r = dm_exception_store_type_register(&_persistent_type);
+ if (r) {
+ DMERR("Unable to register persistent exception store type");
+ return r;
+ }
+
+ r = dm_exception_store_type_register(&_persistent_compat_type);
+ if (r) {
+ DMERR("Unable to register old-style persistent exception "
+ "store type");
+ dm_exception_store_type_unregister(&_persistent_type);
+ return r;
+ }
+
+ return r;
}
void dm_persistent_snapshot_exit(void)
{
+ dm_exception_store_type_unregister(&_persistent_type);
+ dm_exception_store_type_unregister(&_persistent_compat_type);
}
diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c
index 7f6e2e6dcb0..cde5aa558e6 100644
--- a/drivers/md/dm-snap-transient.c
+++ b/drivers/md/dm-snap-transient.c
@@ -6,7 +6,6 @@
*/
#include "dm-exception-store.h"
-#include "dm-snap.h"
#include <linux/mm.h>
#include <linux/pagemap.h>
@@ -23,7 +22,7 @@ struct transient_c {
sector_t next_free;
};
-static void transient_destroy(struct dm_exception_store *store)
+static void transient_dtr(struct dm_exception_store *store)
{
kfree(store->context);
}
@@ -39,14 +38,14 @@ static int transient_read_metadata(struct dm_exception_store *store,
static int transient_prepare_exception(struct dm_exception_store *store,
struct dm_snap_exception *e)
{
- struct transient_c *tc = (struct transient_c *) store->context;
- sector_t size = get_dev_size(store->snap->cow->bdev);
+ struct transient_c *tc = store->context;
+ sector_t size = get_dev_size(store->cow->bdev);
- if (size < (tc->next_free + store->snap->chunk_size))
+ if (size < (tc->next_free + store->chunk_size))
return -1;
- e->new_chunk = sector_to_chunk(store->snap, tc->next_free);
- tc->next_free += store->snap->chunk_size;
+ e->new_chunk = sector_to_chunk(store, tc->next_free);
+ tc->next_free += store->chunk_size;
return 0;
}
@@ -64,20 +63,14 @@ static void transient_fraction_full(struct dm_exception_store *store,
sector_t *numerator, sector_t *denominator)
{
*numerator = ((struct transient_c *) store->context)->next_free;
- *denominator = get_dev_size(store->snap->cow->bdev);
+ *denominator = get_dev_size(store->cow->bdev);
}
-int dm_create_transient(struct dm_exception_store *store)
+static int transient_ctr(struct dm_exception_store *store,
+ unsigned argc, char **argv)
{
struct transient_c *tc;
- store->destroy = transient_destroy;
- store->read_metadata = transient_read_metadata;
- store->prepare_exception = transient_prepare_exception;
- store->commit_exception = transient_commit_exception;
- store->drop_snapshot = NULL;
- store->fraction_full = transient_fraction_full;
-
tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL);
if (!tc)
return -ENOMEM;
@@ -88,11 +81,70 @@ int dm_create_transient(struct dm_exception_store *store)
return 0;
}
+static unsigned transient_status(struct dm_exception_store *store,
+ status_type_t status, char *result,
+ unsigned maxlen)
+{
+ unsigned sz = 0;
+
+ switch (status) {
+ case STATUSTYPE_INFO:
+ break;
+ case STATUSTYPE_TABLE:
+ DMEMIT(" %s N %llu", store->cow->name,
+ (unsigned long long)store->chunk_size);
+ }
+
+ return sz;
+}
+
+static struct dm_exception_store_type _transient_type = {
+ .name = "transient",
+ .module = THIS_MODULE,
+ .ctr = transient_ctr,
+ .dtr = transient_dtr,
+ .read_metadata = transient_read_metadata,
+ .prepare_exception = transient_prepare_exception,
+ .commit_exception = transient_commit_exception,
+ .fraction_full = transient_fraction_full,
+ .status = transient_status,
+};
+
+static struct dm_exception_store_type _transient_compat_type = {
+ .name = "N",
+ .module = THIS_MODULE,
+ .ctr = transient_ctr,
+ .dtr = transient_dtr,
+ .read_metadata = transient_read_metadata,
+ .prepare_exception = transient_prepare_exception,
+ .commit_exception = transient_commit_exception,
+ .fraction_full = transient_fraction_full,
+ .status = transient_status,
+};
+
int dm_transient_snapshot_init(void)
{
- return 0;
+ int r;
+
+ r = dm_exception_store_type_register(&_transient_type);
+ if (r) {
+ DMWARN("Unable to register transient exception store type");
+ return r;
+ }
+
+ r = dm_exception_store_type_register(&_transient_compat_type);
+ if (r) {
+ DMWARN("Unable to register old-style transient "
+ "exception store type");
+ dm_exception_store_type_unregister(&_transient_type);
+ return r;
+ }
+
+ return r;
}
void dm_transient_snapshot_exit(void)
{
+ dm_exception_store_type_unregister(&_transient_type);
+ dm_exception_store_type_unregister(&_transient_compat_type);
}
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 65ff82ff124..981a0413068 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -7,7 +7,6 @@
*/
#include <linux/blkdev.h>
-#include <linux/ctype.h>
#include <linux/device-mapper.h>
#include <linux/delay.h>
#include <linux/fs.h>
@@ -20,9 +19,9 @@
#include <linux/vmalloc.h>
#include <linux/log2.h>
#include <linux/dm-kcopyd.h>
+#include <linux/workqueue.h>
#include "dm-exception-store.h"
-#include "dm-snap.h"
#include "dm-bio-list.h"
#define DM_MSG_PREFIX "snapshots"
@@ -47,9 +46,76 @@
*/
#define MIN_IOS 256
+#define DM_TRACKED_CHUNK_HASH_SIZE 16
+#define DM_TRACKED_CHUNK_HASH(x) ((unsigned long)(x) & \
+ (DM_TRACKED_CHUNK_HASH_SIZE - 1))
+
+struct exception_table {
+ uint32_t hash_mask;
+ unsigned hash_shift;
+ struct list_head *table;
+};
+
+struct dm_snapshot {
+ struct rw_semaphore lock;
+
+ struct dm_dev *origin;
+
+ /* List of snapshots per Origin */
+ struct list_head list;
+
+ /* You can't use a snapshot if this is 0 (e.g. if full) */
+ int valid;
+
+ /* Origin writes don't trigger exceptions until this is set */
+ int active;
+
+ mempool_t *pending_pool;
+
+ atomic_t pending_exceptions_count;
+
+ struct exception_table pending;
+ struct exception_table complete;
+
+ /*
+ * pe_lock protects all pending_exception operations and access
+ * as well as the snapshot_bios list.
+ */
+ spinlock_t pe_lock;
+
+ /* The on disk metadata handler */
+ struct dm_exception_store *store;
+
+ struct dm_kcopyd_client *kcopyd_client;
+
+ /* Queue of snapshot writes for ksnapd to flush */
+ struct bio_list queued_bios;
+ struct work_struct queued_bios_work;
+
+ /* Chunks with outstanding reads */
+ mempool_t *tracked_chunk_pool;
+ spinlock_t tracked_chunk_lock;
+ struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
+};
+
static struct workqueue_struct *ksnapd;
static void flush_queued_bios(struct work_struct *work);
+static sector_t chunk_to_sector(struct dm_exception_store *store,
+ chunk_t chunk)
+{
+ return chunk << store->chunk_shift;
+}
+
+static int bdev_equal(struct block_device *lhs, struct block_device *rhs)
+{
+ /*
+ * There is only ever one instance of a particular block
+ * device so we can compare pointers safely.
+ */
+ return lhs == rhs;
+}
+
struct dm_snap_pending_exception {
struct dm_snap_exception e;
@@ -476,11 +542,11 @@ static int init_hash_tables(struct dm_snapshot *s)
* Calculate based on the size of the original volume or
* the COW volume...
*/
- cow_dev_size = get_dev_size(s->cow->bdev);
+ cow_dev_size = get_dev_size(s->store->cow->bdev);
origin_dev_size = get_dev_size(s->origin->bdev);
max_buckets = calc_max_buckets();
- hash_size = min(origin_dev_size, cow_dev_size) >> s->chunk_shift;
+ hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift;
hash_size = min(hash_size, max_buckets);
hash_size = rounddown_pow_of_two(hash_size);
@@ -505,58 +571,6 @@ static int init_hash_tables(struct dm_snapshot *s)
}
/*
- * Round a number up to the nearest 'size' boundary. size must
- * be a power of 2.
- */
-static ulong round_up(ulong n, ulong size)
-{
- size--;
- return (n + size) & ~size;
-}
-
-static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg,
- char **error)
-{
- unsigned long chunk_size;
- char *value;
-
- chunk_size = simple_strtoul(chunk_size_arg, &value, 10);
- if (*chunk_size_arg == '\0' || *value != '\0') {
- *error = "Invalid chunk size";
- return -EINVAL;
- }
-
- if (!chunk_size) {
- s->chunk_size = s->chunk_mask = s->chunk_shift = 0;
- return 0;
- }
-
- /*
- * Chunk size must be multiple of page size. Silently
- * round up if it's not.
- */
- chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
-
- /* Check chunk_size is a power of 2 */
- if (!is_power_of_2(chunk_size)) {
- *error = "Chunk size is not a power of 2";
- return -EINVAL;
- }
-
- /* Validate the chunk size against the device block size */
- if (chunk_size % (bdev_hardsect_size(s->cow->bdev) >> 9)) {
- *error = "Chunk size is not a multiple of device blocksize";
- return -EINVAL;
- }
-
- s->chunk_size = chunk_size;
- s->chunk_mask = chunk_size - 1;
- s->chunk_shift = ffs(chunk_size) - 1;
-
- return 0;
-}
-
-/*
* Construct a snapshot mapping: <origin_dev> <COW-dev> <p/n> <chunk-size>
*/
static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
@@ -564,91 +578,68 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
struct dm_snapshot *s;
int i;
int r = -EINVAL;
- char persistent;
char *origin_path;
- char *cow_path;
+ struct dm_exception_store *store;
+ unsigned args_used;
if (argc != 4) {
ti->error = "requires exactly 4 arguments";
r = -EINVAL;
- goto bad1;
+ goto bad_args;
}
origin_path = argv[0];
- cow_path = argv[1];
- persistent = toupper(*argv[2]);
+ argv++;
+ argc--;
- if (persistent != 'P' && persistent != 'N') {
- ti->error = "Persistent flag is not P or N";
+ r = dm_exception_store_create(ti, argc, argv, &args_used, &store);
+ if (r) {
+ ti->error = "Couldn't create exception store";
r = -EINVAL;
- goto bad1;
+ goto bad_args;
}
+ argv += args_used;
+ argc -= args_used;
+
s = kmalloc(sizeof(*s), GFP_KERNEL);
- if (s == NULL) {
+ if (!s) {
ti->error = "Cannot allocate snapshot context private "
"structure";
r = -ENOMEM;
- goto bad1;
+ goto bad_snap;
}
r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin);
if (r) {
ti->error = "Cannot get origin device";
- goto bad2;
- }
-
- r = dm_get_device(ti, cow_path, 0, 0,
- FMODE_READ | FMODE_WRITE, &s->cow);
- if (r) {
- dm_put_device(ti, s->origin);
- ti->error = "Cannot get COW device";
- goto bad2;
+ goto bad_origin;
}
- r = set_chunk_size(s, argv[3], &ti->error);
- if (r)
- goto bad3;
-
- s->type = persistent;
-
+ s->store = store;
s->valid = 1;
s->active = 0;
atomic_set(&s->pending_exceptions_count, 0);
init_rwsem(&s->lock);
spin_lock_init(&s->pe_lock);
- s->ti = ti;
/* Allocate hash table for COW data */
if (init_hash_tables(s)) {
ti->error = "Unable to allocate hash table space";
r = -ENOMEM;
- goto bad3;
- }
-
- s->store.snap = s;
-
- if (persistent == 'P')
- r = dm_create_persistent(&s->store);
- else
- r = dm_create_transient(&s->store);
-
- if (r) {
- ti->error = "Couldn't create exception store";
- r = -EINVAL;
- goto bad4;
+ goto bad_hash_tables;
}
r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client);
if (r) {
ti->error = "Could not create kcopyd client";
- goto bad5;
+ goto bad_kcopyd;
}
s->pending_pool = mempool_create_slab_pool(MIN_IOS, pending_cache);
if (!s->pending_pool) {
ti->error = "Could not allocate mempool for pending exceptions";
- goto bad6;
+ goto bad_pending_pool;
}
s->tracked_chunk_pool = mempool_create_slab_pool(MIN_IOS,
@@ -665,7 +656,8 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
spin_lock_init(&s->tracked_chunk_lock);
/* Metadata must only be loaded into one table at once */
- r = s->store.read_metadata(&s->store, dm_add_exception, (void *)s);
+ r = s->store->type->read_metadata(s->store, dm_add_exception,
+ (void *)s);
if (r < 0) {
ti->error = "Failed to read snapshot metadata";
goto bad_load_and_register;
@@ -686,34 +678,33 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
ti->private = s;
- ti->split_io = s->chunk_size;
+ ti->split_io = s->store->chunk_size;
return 0;
- bad_load_and_register:
+bad_load_and_register:
mempool_destroy(s->tracked_chunk_pool);
- bad_tracked_chunk_pool:
+bad_tracked_chunk_pool:
mempool_destroy(s->pending_pool);
- bad6:
+bad_pending_pool:
dm_kcopyd_client_destroy(s->kcopyd_client);
- bad5:
- s->store.destroy(&s->store);
-
- bad4:
+bad_kcopyd:
exit_exception_table(&s->pending, pending_cache);
exit_exception_table(&s->complete, exception_cache);
- bad3:
- dm_put_device(ti, s->cow);
+bad_hash_tables:
dm_put_device(ti, s->origin);
- bad2:
+bad_origin:
kfree(s);
- bad1:
+bad_snap:
+ dm_exception_store_destroy(store);
+
+bad_args:
return r;
}
@@ -724,8 +715,6 @@ static void __free_exceptions(struct dm_snapshot *s)
exit_exception_table(&s->pending, pending_cache);
exit_exception_table(&s->complete, exception_cache);
-
- s->store.destroy(&s->store);
}
static void snapshot_dtr(struct dm_target *ti)
@@ -761,7 +750,8 @@ static void snapshot_dtr(struct dm_target *ti)
mempool_destroy(s->pending_pool);
dm_put_device(ti, s->origin);
- dm_put_device(ti, s->cow);
+
+ dm_exception_store_destroy(s->store);
kfree(s);
}
@@ -820,12 +810,12 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err)
else if (err == -ENOMEM)
DMERR("Invalidating snapshot: Unable to allocate exception.");
- if (s->store.drop_snapshot)
- s->store.drop_snapshot(&s->store);
+ if (s->store->type->drop_snapshot)
+ s->store->type->drop_snapshot(s->store);
s->valid = 0;
- dm_table_event(s->ti->table);
+ dm_table_event(s->store->ti->table);
}
static void get_pending_exception(struct dm_snap_pending_exception *pe)
@@ -943,8 +933,8 @@ static void copy_callback(int read_err, unsigned long write_err, void *context)
else
/* Update the metadata if we are persistent */
- s->store.commit_exception(&s->store, &pe->e, commit_callback,
- pe);
+ s->store->type->commit_exception(s->store, &pe->e,
+ commit_callback, pe);
}
/*
@@ -960,11 +950,11 @@ static void start_copy(struct dm_snap_pending_exception *pe)
dev_size = get_dev_size(bdev);
src.bdev = bdev;
- src.sector = chunk_to_sector(s, pe->e.old_chunk);
- src.count = min(s->chunk_size, dev_size - src.sector);
+ src.sector = chunk_to_sector(s->store, pe->e.old_chunk);
+ src.count = min(s->store->chunk_size, dev_size - src.sector);
- dest.bdev = s->cow->bdev;
- dest.sector = chunk_to_sector(s, pe->e.new_chunk);
+ dest.bdev = s->store->cow->bdev;
+ dest.sector = chunk_to_sector(s->store, pe->e.new_chunk);
dest.count = src.count;
/* Hand over to kcopyd */
@@ -972,6 +962,17 @@ static void start_copy(struct dm_snap_pending_exception *pe)
&src, 1, &dest, 0, copy_callback, pe);
}
+static struct dm_snap_pending_exception *
+__lookup_pending_exception(struct dm_snapshot *s, chunk_t chunk)
+{
+ struct dm_snap_exception *e = lookup_exception(&s->pending, chunk);
+
+ if (!e)
+ return NULL;
+
+ return container_of(e, struct dm_snap_pending_exception, e);
+}
+
/*
* Looks to see if this snapshot already has a pending exception
* for this chunk, otherwise it allocates a new one and inserts
@@ -981,40 +982,15 @@ static void start_copy(struct dm_snap_pending_exception *pe)
* this.
*/
static struct dm_snap_pending_exception *
-__find_pending_exception(struct dm_snapshot *s, struct bio *bio)
+__find_pending_exception(struct dm_snapshot *s,
+ struct dm_snap_pending_exception *pe, chunk_t chunk)
{
- struct dm_snap_exception *e;
- struct dm_snap_pending_exception *pe;
- chunk_t chunk = sector_to_chunk(s, bio->bi_sector);
+ struct dm_snap_pending_exception *pe2;
- /*
- * Is there a pending exception for this already ?
- */
- e = lookup_exception(&s->pending, chunk);
- if (e) {
- /* cast the exception to a pending exception */
- pe = container_of(e, struct dm_snap_pending_exception, e);
- goto out;
- }
-
- /*
- * Create a new pending exception, we don't want
- * to hold the lock while we do this.
- */
- up_write(&s->lock);
- pe = alloc_pending_exception(s);
- down_write(&s->lock);
-
- if (!s->valid) {
- free_pending_exception(pe);
- return NULL;
- }
-
- e = lookup_exception(&s->pending, chunk);
- if (e) {
+ pe2 = __lookup_pending_exception(s, chunk);
+ if (pe2) {
free_pending_exception(pe);
- pe = container_of(e, struct dm_snap_pending_exception, e);
- goto out;
+ return pe2;
}
pe->e.old_chunk = chunk;
@@ -1024,7 +1000,7 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
atomic_set(&pe->ref_count, 0);
pe->started = 0;
- if (s->store.prepare_exception(&s->store, &pe->e)) {
+ if (s->store->type->prepare_exception(s->store, &pe->e)) {
free_pending_exception(pe);
return NULL;
}
@@ -1032,17 +1008,18 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
get_pending_exception(pe);
insert_exception(&s->pending, &pe->e);
- out:
return pe;
}
static void remap_exception(struct dm_snapshot *s, struct dm_snap_exception *e,
struct bio *bio, chunk_t chunk)
{
- bio->bi_bdev = s->cow->bdev;
- bio->bi_sector = chunk_to_sector(s, dm_chunk_number(e->new_chunk) +
- (chunk - e->old_chunk)) +
- (bio->bi_sector & s->chunk_mask);
+ bio->bi_bdev = s->store->cow->bdev;
+ bio->bi_sector = chunk_to_sector(s->store,
+ dm_chunk_number(e->new_chunk) +
+ (chunk - e->old_chunk)) +
+ (bio->bi_sector &
+ s->store->chunk_mask);
}
static int snapshot_map(struct dm_target *ti, struct bio *bio,
@@ -1054,7 +1031,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
chunk_t chunk;
struct dm_snap_pending_exception *pe = NULL;
- chunk = sector_to_chunk(s, bio->bi_sector);
+ chunk = sector_to_chunk(s->store, bio->bi_sector);
/* Full snapshots are not usable */
/* To get here the table must be live so s->active is always set. */
@@ -1083,11 +1060,31 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
* writeable.
*/
if (bio_rw(bio) == WRITE) {
- pe = __find_pending_exception(s, bio);
+ pe = __lookup_pending_exception(s, chunk);
if (!pe) {
- __invalidate_snapshot(s, -ENOMEM);
- r = -EIO;
- goto out_unlock;
+ up_write(&s->lock);
+ pe = alloc_pending_exception(s);
+ down_write(&s->lock);
+
+ if (!s->valid) {
+ free_pending_exception(pe);
+ r = -EIO;
+ goto out_unlock;
+ }
+
+ e = lookup_exception(&s->complete, chunk);
+ if (e) {
+ free_pending_exception(pe);
+ remap_exception(s, e, bio, chunk);
+ goto out_unlock;
+ }
+
+ pe = __find_pending_exception(s, pe, chunk);
+ if (!pe) {
+ __invalidate_snapshot(s, -ENOMEM);
+ r = -EIO;
+ goto out_unlock;
+ }
}
remap_exception(s, &pe->e, bio, chunk);
@@ -1137,24 +1134,25 @@ static void snapshot_resume(struct dm_target *ti)
static int snapshot_status(struct dm_target *ti, status_type_t type,
char *result, unsigned int maxlen)
{
+ unsigned sz = 0;
struct dm_snapshot *snap = ti->private;
switch (type) {
case STATUSTYPE_INFO:
if (!snap->valid)
- snprintf(result, maxlen, "Invalid");
+ DMEMIT("Invalid");
else {
- if (snap->store.fraction_full) {
+ if (snap->store->type->fraction_full) {
sector_t numerator, denominator;
- snap->store.fraction_full(&snap->store,
- &numerator,
- &denominator);
- snprintf(result, maxlen, "%llu/%llu",
- (unsigned long long)numerator,
- (unsigned long long)denominator);
+ snap->store->type->fraction_full(snap->store,
+ &numerator,
+ &denominator);
+ DMEMIT("%llu/%llu",
+ (unsigned long long)numerator,
+ (unsigned long long)denominator);
}
else
- snprintf(result, maxlen, "Unknown");
+ DMEMIT("Unknown");
}
break;
@@ -1164,10 +1162,9 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
* to make private copies if the output is to
* make sense.
*/
- snprintf(result, maxlen, "%s %s %c %llu",
- snap->origin->name, snap->cow->name,
- snap->type,
- (unsigned long long)snap->chunk_size);
+ DMEMIT("%s", snap->origin->name);
+ snap->store->type->status(snap->store, type, result + sz,
+ maxlen - sz);
break;
}
@@ -1196,14 +1193,14 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
goto next_snapshot;
/* Nothing to do if writing beyond end of snapshot */
- if (bio->bi_sector >= dm_table_get_size(snap->ti->table))
+ if (bio->bi_sector >= dm_table_get_size(snap->store->ti->table))
goto next_snapshot;
/*
* Remember, different snapshots can have
* different chunk sizes.
*/
- chunk = sector_to_chunk(snap, bio->bi_sector);
+ chunk = sector_to_chunk(snap->store, bio->bi_sector);
/*
* Check exception table to see if block
@@ -1217,10 +1214,28 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
if (e)
goto next_snapshot;
- pe = __find_pending_exception(snap, bio);
+ pe = __lookup_pending_exception(snap, chunk);
if (!pe) {
- __invalidate_snapshot(snap, -ENOMEM);
- goto next_snapshot;
+ up_write(&snap->lock);
+ pe = alloc_pending_exception(snap);
+ down_write(&snap->lock);
+
+ if (!snap->valid) {
+ free_pending_exception(pe);
+ goto next_snapshot;
+ }
+
+ e = lookup_exception(&snap->complete, chunk);
+ if (e) {
+ free_pending_exception(pe);
+ goto next_snapshot;
+ }
+
+ pe = __find_pending_exception(snap, pe, chunk);
+ if (!pe) {
+ __invalidate_snapshot(snap, -ENOMEM);
+ goto next_snapshot;
+ }
}
if (!primary_pe) {
@@ -1360,7 +1375,8 @@ static void origin_resume(struct dm_target *ti)
o = __lookup_origin(dev->bdev);
if (o)
list_for_each_entry (snap, &o->snapshots, list)
- chunk_size = min_not_zero(chunk_size, snap->chunk_size);
+ chunk_size = min_not_zero(chunk_size,
+ snap->store->chunk_size);
up_read(&_origins_lock);
ti->split_io = chunk_size;
diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h
deleted file mode 100644
index d9e62b43cf8..00000000000
--- a/drivers/md/dm-snap.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
- *
- * This file is released under the GPL.
- */
-
-#ifndef DM_SNAPSHOT_H
-#define DM_SNAPSHOT_H
-
-#include <linux/device-mapper.h>
-#include "dm-exception-store.h"
-#include "dm-bio-list.h"
-#include <linux/blkdev.h>
-#include <linux/workqueue.h>
-
-struct exception_table {
- uint32_t hash_mask;
- unsigned hash_shift;
- struct list_head *table;
-};
-
-#define DM_TRACKED_CHUNK_HASH_SIZE 16
-#define DM_TRACKED_CHUNK_HASH(x) ((unsigned long)(x) & \
- (DM_TRACKED_CHUNK_HASH_SIZE - 1))
-
-struct dm_snapshot {
- struct rw_semaphore lock;
- struct dm_target *ti;
-
- struct dm_dev *origin;
- struct dm_dev *cow;
-
- /* List of snapshots per Origin */
- struct list_head list;
-
- /* Size of data blocks saved - must be a power of 2 */
- chunk_t chunk_size;
- chunk_t chunk_mask;
- chunk_t chunk_shift;
-
- /* You can't use a snapshot if this is 0 (e.g. if full) */
- int valid;
-
- /* Origin writes don't trigger exceptions until this is set */
- int active;
-
- /* Used for display of table */
- char type;
-
- mempool_t *pending_pool;
-
- atomic_t pending_exceptions_count;
-
- struct exception_table pending;
- struct exception_table complete;
-
- /*
- * pe_lock protects all pending_exception operations and access
- * as well as the snapshot_bios list.
- */
- spinlock_t pe_lock;
-
- /* The on disk metadata handler */
- struct dm_exception_store store;
-
- struct dm_kcopyd_client *kcopyd_client;
-
- /* Queue of snapshot writes for ksnapd to flush */
- struct bio_list queued_bios;
- struct work_struct queued_bios_work;
-
- /* Chunks with outstanding reads */
- mempool_t *tracked_chunk_pool;
- spinlock_t tracked_chunk_lock;
- struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
-};
-
-/*
- * Return the number of sectors in the device.
- */
-static inline sector_t get_dev_size(struct block_device *bdev)
-{
- return bdev->bd_inode->i_size >> SECTOR_SHIFT;
-}
-
-static inline chunk_t sector_to_chunk(struct dm_snapshot *s, sector_t sector)
-{
- return (sector & ~s->chunk_mask) >> s->chunk_shift;
-}
-
-static inline sector_t chunk_to_sector(struct dm_snapshot *s, chunk_t chunk)
-{
- return chunk << s->chunk_shift;
-}
-
-static inline int bdev_equal(struct block_device *lhs, struct block_device *rhs)
-{
- /*
- * There is only ever one instance of a particular block
- * device so we can compare pointers safely.
- */
- return lhs == rhs;
-}
-
-#endif
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 2fd66c30f7f..429b50b975d 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -52,8 +52,6 @@ struct dm_table {
sector_t *highs;
struct dm_target *targets;
- unsigned barriers_supported:1;
-
/*
* Indicates the rw permissions for the new logical
* device. This should be a combination of FMODE_READ
@@ -243,7 +241,6 @@ int dm_table_create(struct dm_table **result, fmode_t mode,
INIT_LIST_HEAD(&t->devices);
atomic_set(&t->holders, 0);
- t->barriers_supported = 1;
if (!num_targets)
num_targets = KEYS_PER_NODE;
@@ -399,28 +396,30 @@ static int check_device_area(struct dm_dev_internal *dd, sector_t start,
}
/*
- * This upgrades the mode on an already open dm_dev. Being
+ * This upgrades the mode on an already open dm_dev, being
* careful to leave things as they were if we fail to reopen the
- * device.
+ * device and not to touch the existing bdev field in case
+ * it is accessed concurrently inside dm_table_any_congested().
*/
static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode,
struct mapped_device *md)
{
int r;
- struct dm_dev_internal dd_copy;
- dev_t dev = dd->dm_dev.bdev->bd_dev;
+ struct dm_dev_internal dd_new, dd_old;
+
+ dd_new = dd_old = *dd;
+
+ dd_new.dm_dev.mode |= new_mode;
+ dd_new.dm_dev.bdev = NULL;
- dd_copy = *dd;
+ r = open_dev(&dd_new, dd->dm_dev.bdev->bd_dev, md);
+ if (r)
+ return r;
dd->dm_dev.mode |= new_mode;
- dd->dm_dev.bdev = NULL;
- r = open_dev(dd, dev, md);
- if (!r)
- close_dev(&dd_copy, md);
- else
- *dd = dd_copy;
+ close_dev(&dd_old, md);
- return r;
+ return 0;
}
/*
@@ -749,10 +748,6 @@ int dm_table_add_target(struct dm_table *t, const char *type,
/* FIXME: the plan is to combine high here and then have
* the merge fn apply the target level restrictions. */
combine_restrictions_low(&t->limits, &tgt->limits);
-
- if (!(tgt->type->features & DM_TARGET_SUPPORTS_BARRIERS))
- t->barriers_supported = 0;
-
return 0;
bad:
@@ -797,12 +792,6 @@ int dm_table_complete(struct dm_table *t)
check_for_valid_limits(&t->limits);
- /*
- * We only support barriers if there is exactly one underlying device.
- */
- if (!list_is_singular(&t->devices))
- t->barriers_supported = 0;
-
/* how many indexes will the btree have ? */
leaf_nodes = dm_div_up(t->num_targets, KEYS_PER_NODE);
t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE);
@@ -877,6 +866,45 @@ struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector)
return &t->targets[(KEYS_PER_NODE * n) + k];
}
+/*
+ * Set the integrity profile for this device if all devices used have
+ * matching profiles.
+ */
+static void dm_table_set_integrity(struct dm_table *t)
+{
+ struct list_head *devices = dm_table_get_devices(t);
+ struct dm_dev_internal *prev = NULL, *dd = NULL;
+
+ if (!blk_get_integrity(dm_disk(t->md)))
+ return;
+
+ list_for_each_entry(dd, devices, list) {
+ if (prev &&
+ blk_integrity_compare(prev->dm_dev.bdev->bd_disk,
+ dd->dm_dev.bdev->bd_disk) < 0) {
+ DMWARN("%s: integrity not set: %s and %s mismatch",
+ dm_device_name(t->md),
+ prev->dm_dev.bdev->bd_disk->disk_name,
+ dd->dm_dev.bdev->bd_disk->disk_name);
+ goto no_integrity;
+ }
+ prev = dd;
+ }
+
+ if (!prev || !bdev_get_integrity(prev->dm_dev.bdev))
+ goto no_integrity;
+
+ blk_integrity_register(dm_disk(t->md),
+ bdev_get_integrity(prev->dm_dev.bdev));
+
+ return;
+
+no_integrity:
+ blk_integrity_register(dm_disk(t->md), NULL);
+
+ return;
+}
+
void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q)
{
/*
@@ -897,6 +925,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q)
else
queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q);
+ dm_table_set_integrity(t);
}
unsigned int dm_table_get_num_targets(struct dm_table *t)
@@ -1017,12 +1046,6 @@ struct mapped_device *dm_table_get_md(struct dm_table *t)
return t->md;
}
-int dm_table_barrier_ok(struct dm_table *t)
-{
- return t->barriers_supported;
-}
-EXPORT_SYMBOL(dm_table_barrier_ok);
-
EXPORT_SYMBOL(dm_vcalloc);
EXPORT_SYMBOL(dm_get_device);
EXPORT_SYMBOL(dm_put_device);
diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c
index 7decf10006e..04feccf2a99 100644
--- a/drivers/md/dm-target.c
+++ b/drivers/md/dm-target.c
@@ -14,45 +14,34 @@
#define DM_MSG_PREFIX "target"
-struct tt_internal {
- struct target_type tt;
-
- struct list_head list;
- long use;
-};
-
static LIST_HEAD(_targets);
static DECLARE_RWSEM(_lock);
#define DM_MOD_NAME_SIZE 32
-static inline struct tt_internal *__find_target_type(const char *name)
+static inline struct target_type *__find_target_type(const char *name)
{
- struct tt_internal *ti;
+ struct target_type *tt;
- list_for_each_entry (ti, &_targets, list)
- if (!strcmp(name, ti->tt.name))
- return ti;
+ list_for_each_entry(tt, &_targets, list)
+ if (!strcmp(name, tt->name))
+ return tt;
return NULL;
}
-static struct tt_internal *get_target_type(const char *name)
+static struct target_type *get_target_type(const char *name)
{
- struct tt_internal *ti;
+ struct target_type *tt;
down_read(&_lock);
- ti = __find_target_type(name);
- if (ti) {
- if ((ti->use == 0) && !try_module_get(ti->tt.module))
- ti = NULL;
- else
- ti->use++;
- }
+ tt = __find_target_type(name);
+ if (tt && !try_module_get(tt->module))
+ tt = NULL;
up_read(&_lock);
- return ti;
+ return tt;
}
static void load_module(const char *name)
@@ -62,92 +51,59 @@ static void load_module(const char *name)
struct target_type *dm_get_target_type(const char *name)
{
- struct tt_internal *ti = get_target_type(name);
+ struct target_type *tt = get_target_type(name);
- if (!ti) {
+ if (!tt) {
load_module(name);
- ti = get_target_type(name);
+ tt = get_target_type(name);
}
- return ti ? &ti->tt : NULL;
+ return tt;
}
-void dm_put_target_type(struct target_type *t)
+void dm_put_target_type(struct target_type *tt)
{
- struct tt_internal *ti = (struct tt_internal *) t;
-
down_read(&_lock);
- if (--ti->use == 0)
- module_put(ti->tt.module);
-
- BUG_ON(ti->use < 0);
+ module_put(tt->module);
up_read(&_lock);
-
- return;
-}
-
-static struct tt_internal *alloc_target(struct target_type *t)
-{
- struct tt_internal *ti = kzalloc(sizeof(*ti), GFP_KERNEL);
-
- if (ti)
- ti->tt = *t;
-
- return ti;
}
-
int dm_target_iterate(void (*iter_func)(struct target_type *tt,
void *param), void *param)
{
- struct tt_internal *ti;
+ struct target_type *tt;
down_read(&_lock);
- list_for_each_entry (ti, &_targets, list)
- iter_func(&ti->tt, param);
+ list_for_each_entry(tt, &_targets, list)
+ iter_func(tt, param);
up_read(&_lock);
return 0;
}
-int dm_register_target(struct target_type *t)
+int dm_register_target(struct target_type *tt)
{
int rv = 0;
- struct tt_internal *ti = alloc_target(t);
-
- if (!ti)
- return -ENOMEM;
down_write(&_lock);
- if (__find_target_type(t->name))
+ if (__find_target_type(tt->name))
rv = -EEXIST;
else
- list_add(&ti->list, &_targets);
+ list_add(&tt->list, &_targets);
up_write(&_lock);
- if (rv)
- kfree(ti);
return rv;
}
-void dm_unregister_target(struct target_type *t)
+void dm_unregister_target(struct target_type *tt)
{
- struct tt_internal *ti;
-
down_write(&_lock);
- if (!(ti = __find_target_type(t->name))) {
- DMCRIT("Unregistering unrecognised target: %s", t->name);
- BUG();
- }
-
- if (ti->use) {
- DMCRIT("Attempt to unregister target still in use: %s",
- t->name);
+ if (!__find_target_type(tt->name)) {
+ DMCRIT("Unregistering unrecognised target: %s", tt->name);
BUG();
}
- list_del(&ti->list);
- kfree(ti);
+ list_del(&tt->list);
up_write(&_lock);
}
@@ -156,17 +112,17 @@ void dm_unregister_target(struct target_type *t)
* io-err: always fails an io, useful for bringing
* up LVs that have holes in them.
*/
-static int io_err_ctr(struct dm_target *ti, unsigned int argc, char **args)
+static int io_err_ctr(struct dm_target *tt, unsigned int argc, char **args)
{
return 0;
}
-static void io_err_dtr(struct dm_target *ti)
+static void io_err_dtr(struct dm_target *tt)
{
/* empty */
}
-static int io_err_map(struct dm_target *ti, struct bio *bio,
+static int io_err_map(struct dm_target *tt, struct bio *bio,
union map_info *map_context)
{
return -EIO;
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 8d40f27cce8..8a994be035b 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -89,29 +89,20 @@ union map_info *dm_get_mapinfo(struct bio *bio)
/*
* Bits for the md->flags field.
*/
-#define DMF_BLOCK_IO 0
+#define DMF_BLOCK_IO_FOR_SUSPEND 0
#define DMF_SUSPENDED 1
#define DMF_FROZEN 2
#define DMF_FREEING 3
#define DMF_DELETING 4
#define DMF_NOFLUSH_SUSPENDING 5
+#define DMF_QUEUE_IO_TO_THREAD 6
/*
* Work processed by per-device workqueue.
*/
-struct dm_wq_req {
- enum {
- DM_WQ_FLUSH_DEFERRED,
- } type;
- struct work_struct work;
- struct mapped_device *md;
- void *context;
-};
-
struct mapped_device {
struct rw_semaphore io_lock;
struct mutex suspend_lock;
- spinlock_t pushback_lock;
rwlock_t map_lock;
atomic_t holders;
atomic_t open_count;
@@ -129,8 +120,14 @@ struct mapped_device {
*/
atomic_t pending;
wait_queue_head_t wait;
+ struct work_struct work;
struct bio_list deferred;
- struct bio_list pushback;
+ spinlock_t deferred_lock;
+
+ /*
+ * An error from the barrier request currently being processed.
+ */
+ int barrier_error;
/*
* Processing queue (flush/barriers)
@@ -433,6 +430,10 @@ static void end_io_acct(struct dm_io *io)
part_stat_add(cpu, &dm_disk(md)->part0, ticks[rw], duration);
part_stat_unlock();
+ /*
+ * After this is decremented the bio must not be touched if it is
+ * a barrier.
+ */
dm_disk(md)->part0.in_flight = pending =
atomic_dec_return(&md->pending);
@@ -444,19 +445,18 @@ static void end_io_acct(struct dm_io *io)
/*
* Add the bio to the list of deferred io.
*/
-static int queue_io(struct mapped_device *md, struct bio *bio)
+static void queue_io(struct mapped_device *md, struct bio *bio)
{
down_write(&md->io_lock);
- if (!test_bit(DMF_BLOCK_IO, &md->flags)) {
- up_write(&md->io_lock);
- return 1;
- }
-
+ spin_lock_irq(&md->deferred_lock);
bio_list_add(&md->deferred, bio);
+ spin_unlock_irq(&md->deferred_lock);
+
+ if (!test_and_set_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags))
+ queue_work(md->wq, &md->work);
up_write(&md->io_lock);
- return 0; /* deferred successfully */
}
/*
@@ -537,30 +537,38 @@ static void dec_pending(struct dm_io *io, int error)
if (io->error == DM_ENDIO_REQUEUE) {
/*
* Target requested pushing back the I/O.
- * This must be handled before the sleeper on
- * suspend queue merges the pushback list.
*/
- spin_lock_irqsave(&md->pushback_lock, flags);
+ spin_lock_irqsave(&md->deferred_lock, flags);
if (__noflush_suspending(md))
- bio_list_add(&md->pushback, io->bio);
+ bio_list_add_head(&md->deferred, io->bio);
else
/* noflush suspend was interrupted. */
io->error = -EIO;
- spin_unlock_irqrestore(&md->pushback_lock, flags);
+ spin_unlock_irqrestore(&md->deferred_lock, flags);
}
- end_io_acct(io);
-
io_error = io->error;
bio = io->bio;
- free_io(md, io);
+ if (bio_barrier(bio)) {
+ /*
+ * There can be just one barrier request so we use
+ * a per-device variable for error reporting.
+ * Note that you can't touch the bio after end_io_acct
+ */
+ md->barrier_error = io_error;
+ end_io_acct(io);
+ } else {
+ end_io_acct(io);
- if (io_error != DM_ENDIO_REQUEUE) {
- trace_block_bio_complete(md->queue, bio);
+ if (io_error != DM_ENDIO_REQUEUE) {
+ trace_block_bio_complete(md->queue, bio);
- bio_endio(bio, io_error);
+ bio_endio(bio, io_error);
+ }
}
+
+ free_io(md, io);
}
}
@@ -702,13 +710,19 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector,
clone->bi_sector = sector;
clone->bi_bdev = bio->bi_bdev;
- clone->bi_rw = bio->bi_rw;
+ clone->bi_rw = bio->bi_rw & ~(1 << BIO_RW_BARRIER);
clone->bi_vcnt = 1;
clone->bi_size = to_bytes(len);
clone->bi_io_vec->bv_offset = offset;
clone->bi_io_vec->bv_len = clone->bi_size;
clone->bi_flags |= 1 << BIO_CLONED;
+ if (bio_integrity(bio)) {
+ bio_integrity_clone(clone, bio, GFP_NOIO);
+ bio_integrity_trim(clone,
+ bio_sector_offset(bio, idx, offset), len);
+ }
+
return clone;
}
@@ -723,6 +737,7 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector,
clone = bio_alloc_bioset(GFP_NOIO, bio->bi_max_vecs, bs);
__bio_clone(clone, bio);
+ clone->bi_rw &= ~(1 << BIO_RW_BARRIER);
clone->bi_destructor = dm_bio_destructor;
clone->bi_sector = sector;
clone->bi_idx = idx;
@@ -730,6 +745,14 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector,
clone->bi_size = to_bytes(len);
clone->bi_flags &= ~(1 << BIO_SEG_VALID);
+ if (bio_integrity(bio)) {
+ bio_integrity_clone(clone, bio, GFP_NOIO);
+
+ if (idx != bio->bi_idx || clone->bi_size < bio->bi_size)
+ bio_integrity_trim(clone,
+ bio_sector_offset(bio, idx, 0), len);
+ }
+
return clone;
}
@@ -834,21 +857,22 @@ static int __clone_and_map(struct clone_info *ci)
}
/*
- * Split the bio into several clones.
+ * Split the bio into several clones and submit it to targets.
*/
-static int __split_bio(struct mapped_device *md, struct bio *bio)
+static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
{
struct clone_info ci;
int error = 0;
ci.map = dm_get_table(md);
- if (unlikely(!ci.map))
- return -EIO;
- if (unlikely(bio_barrier(bio) && !dm_table_barrier_ok(ci.map))) {
- dm_table_put(ci.map);
- bio_endio(bio, -EOPNOTSUPP);
- return 0;
+ if (unlikely(!ci.map)) {
+ if (!bio_barrier(bio))
+ bio_io_error(bio);
+ else
+ md->barrier_error = -EIO;
+ return;
}
+
ci.md = md;
ci.bio = bio;
ci.io = alloc_io(md);
@@ -867,8 +891,6 @@ static int __split_bio(struct mapped_device *md, struct bio *bio)
/* drop the extra reference count */
dec_pending(ci.io, error);
dm_table_put(ci.map);
-
- return 0;
}
/*-----------------------------------------------------------------
* CRUD END
@@ -927,7 +949,6 @@ out:
*/
static int dm_request(struct request_queue *q, struct bio *bio)
{
- int r = -EIO;
int rw = bio_data_dir(bio);
struct mapped_device *md = q->queuedata;
int cpu;
@@ -940,32 +961,26 @@ static int dm_request(struct request_queue *q, struct bio *bio)
part_stat_unlock();
/*
- * If we're suspended we have to queue
- * this io for later.
+ * If we're suspended or the thread is processing barriers
+ * we have to queue this io for later.
*/
- while (test_bit(DMF_BLOCK_IO, &md->flags)) {
+ if (unlikely(test_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags)) ||
+ unlikely(bio_barrier(bio))) {
up_read(&md->io_lock);
- if (bio_rw(bio) != READA)
- r = queue_io(md, bio);
+ if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) &&
+ bio_rw(bio) == READA) {
+ bio_io_error(bio);
+ return 0;
+ }
- if (r <= 0)
- goto out_req;
+ queue_io(md, bio);
- /*
- * We're in a while loop, because someone could suspend
- * before we get to the following read lock.
- */
- down_read(&md->io_lock);
+ return 0;
}
- r = __split_bio(md, bio);
+ __split_and_process_bio(md, bio);
up_read(&md->io_lock);
-
-out_req:
- if (r < 0)
- bio_io_error(bio);
-
return 0;
}
@@ -986,7 +1001,7 @@ static int dm_any_congested(void *congested_data, int bdi_bits)
struct mapped_device *md = congested_data;
struct dm_table *map;
- if (!test_bit(DMF_BLOCK_IO, &md->flags)) {
+ if (!test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) {
map = dm_get_table(md);
if (map) {
r = dm_table_any_congested(map, bdi_bits);
@@ -1074,6 +1089,8 @@ out:
static struct block_device_operations dm_blk_dops;
+static void dm_wq_work(struct work_struct *work);
+
/*
* Allocate and initialise a blank device with a given minor.
*/
@@ -1101,7 +1118,7 @@ static struct mapped_device *alloc_dev(int minor)
init_rwsem(&md->io_lock);
mutex_init(&md->suspend_lock);
- spin_lock_init(&md->pushback_lock);
+ spin_lock_init(&md->deferred_lock);
rwlock_init(&md->map_lock);
atomic_set(&md->holders, 1);
atomic_set(&md->open_count, 0);
@@ -1118,6 +1135,7 @@ static struct mapped_device *alloc_dev(int minor)
md->queue->backing_dev_info.congested_fn = dm_any_congested;
md->queue->backing_dev_info.congested_data = md;
blk_queue_make_request(md->queue, dm_request);
+ blk_queue_ordered(md->queue, QUEUE_ORDERED_DRAIN, NULL);
blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
md->queue->unplug_fn = dm_unplug_all;
blk_queue_merge_bvec(md->queue, dm_merge_bvec);
@@ -1140,6 +1158,7 @@ static struct mapped_device *alloc_dev(int minor)
atomic_set(&md->pending, 0);
init_waitqueue_head(&md->wait);
+ INIT_WORK(&md->work, dm_wq_work);
init_waitqueue_head(&md->eventq);
md->disk->major = _major;
@@ -1197,6 +1216,7 @@ static void free_dev(struct mapped_device *md)
mempool_destroy(md->tio_pool);
mempool_destroy(md->io_pool);
bioset_free(md->bs);
+ blk_integrity_unregister(md->disk);
del_gendisk(md->disk);
free_minor(minor);
@@ -1379,18 +1399,24 @@ void dm_put(struct mapped_device *md)
}
EXPORT_SYMBOL_GPL(dm_put);
-static int dm_wait_for_completion(struct mapped_device *md)
+static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
{
int r = 0;
+ DECLARE_WAITQUEUE(wait, current);
+
+ dm_unplug_all(md->queue);
+
+ add_wait_queue(&md->wait, &wait);
while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
+ set_current_state(interruptible);
smp_mb();
if (!atomic_read(&md->pending))
break;
- if (signal_pending(current)) {
+ if (interruptible == TASK_INTERRUPTIBLE &&
+ signal_pending(current)) {
r = -EINTR;
break;
}
@@ -1399,68 +1425,80 @@ static int dm_wait_for_completion(struct mapped_device *md)
}
set_current_state(TASK_RUNNING);
+ remove_wait_queue(&md->wait, &wait);
+
return r;
}
-/*
- * Process the deferred bios
- */
-static void __flush_deferred_io(struct mapped_device *md)
+static int dm_flush(struct mapped_device *md)
{
- struct bio *c;
+ dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE);
+ return 0;
+}
+
+static void process_barrier(struct mapped_device *md, struct bio *bio)
+{
+ int error = dm_flush(md);
- while ((c = bio_list_pop(&md->deferred))) {
- if (__split_bio(md, c))
- bio_io_error(c);
+ if (unlikely(error)) {
+ bio_endio(bio, error);
+ return;
+ }
+ if (bio_empty_barrier(bio)) {
+ bio_endio(bio, 0);
+ return;
}
- clear_bit(DMF_BLOCK_IO, &md->flags);
-}
+ __split_and_process_bio(md, bio);
-static void __merge_pushback_list(struct mapped_device *md)
-{
- unsigned long flags;
+ error = dm_flush(md);
- spin_lock_irqsave(&md->pushback_lock, flags);
- clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
- bio_list_merge_head(&md->deferred, &md->pushback);
- bio_list_init(&md->pushback);
- spin_unlock_irqrestore(&md->pushback_lock, flags);
+ if (!error && md->barrier_error)
+ error = md->barrier_error;
+
+ if (md->barrier_error != DM_ENDIO_REQUEUE)
+ bio_endio(bio, error);
}
+/*
+ * Process the deferred bios
+ */
static void dm_wq_work(struct work_struct *work)
{
- struct dm_wq_req *req = container_of(work, struct dm_wq_req, work);
- struct mapped_device *md = req->md;
+ struct mapped_device *md = container_of(work, struct mapped_device,
+ work);
+ struct bio *c;
down_write(&md->io_lock);
- switch (req->type) {
- case DM_WQ_FLUSH_DEFERRED:
- __flush_deferred_io(md);
- break;
- default:
- DMERR("dm_wq_work: unrecognised work type %d", req->type);
- BUG();
+
+ while (!test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) {
+ spin_lock_irq(&md->deferred_lock);
+ c = bio_list_pop(&md->deferred);
+ spin_unlock_irq(&md->deferred_lock);
+
+ if (!c) {
+ clear_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags);
+ break;
+ }
+
+ up_write(&md->io_lock);
+
+ if (bio_barrier(c))
+ process_barrier(md, c);
+ else
+ __split_and_process_bio(md, c);
+
+ down_write(&md->io_lock);
}
- up_write(&md->io_lock);
-}
-static void dm_wq_queue(struct mapped_device *md, int type, void *context,
- struct dm_wq_req *req)
-{
- req->type = type;
- req->md = md;
- req->context = context;
- INIT_WORK(&req->work, dm_wq_work);
- queue_work(md->wq, &req->work);
+ up_write(&md->io_lock);
}
-static void dm_queue_flush(struct mapped_device *md, int type, void *context)
+static void dm_queue_flush(struct mapped_device *md)
{
- struct dm_wq_req req;
-
- dm_wq_queue(md, type, context, &req);
- flush_workqueue(md->wq);
+ clear_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags);
+ smp_mb__after_clear_bit();
+ queue_work(md->wq, &md->work);
}
/*
@@ -1534,7 +1572,6 @@ static void unlock_fs(struct mapped_device *md)
int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
{
struct dm_table *map = NULL;
- DECLARE_WAITQUEUE(wait, current);
int r = 0;
int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0;
int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0;
@@ -1579,38 +1616,54 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
}
/*
- * First we set the BLOCK_IO flag so no more ios will be mapped.
+ * Here we must make sure that no processes are submitting requests
+ * to target drivers i.e. no one may be executing
+ * __split_and_process_bio. This is called from dm_request and
+ * dm_wq_work.
+ *
+ * To get all processes out of __split_and_process_bio in dm_request,
+ * we take the write lock. To prevent any process from reentering
+ * __split_and_process_bio from dm_request, we set
+ * DMF_QUEUE_IO_TO_THREAD.
+ *
+ * To quiesce the thread (dm_wq_work), we set DMF_BLOCK_IO_FOR_SUSPEND
+ * and call flush_workqueue(md->wq). flush_workqueue will wait until
+ * dm_wq_work exits and DMF_BLOCK_IO_FOR_SUSPEND will prevent any
+ * further calls to __split_and_process_bio from dm_wq_work.
*/
down_write(&md->io_lock);
- set_bit(DMF_BLOCK_IO, &md->flags);
-
- add_wait_queue(&md->wait, &wait);
+ set_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags);
+ set_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags);
up_write(&md->io_lock);
- /* unplug */
- if (map)
- dm_table_unplug_all(map);
+ flush_workqueue(md->wq);
/*
- * Wait for the already-mapped ios to complete.
+ * At this point no more requests are entering target request routines.
+ * We call dm_wait_for_completion to wait for all existing requests
+ * to finish.
*/
- r = dm_wait_for_completion(md);
+ r = dm_wait_for_completion(md, TASK_INTERRUPTIBLE);
down_write(&md->io_lock);
- remove_wait_queue(&md->wait, &wait);
-
if (noflush)
- __merge_pushback_list(md);
+ clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
up_write(&md->io_lock);
/* were we interrupted ? */
if (r < 0) {
- dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL);
+ dm_queue_flush(md);
unlock_fs(md);
goto out; /* pushback list is already flushed, so skip flush */
}
+ /*
+ * If dm_wait_for_completion returned 0, the device is completely
+ * quiescent now. There is no request-processing activity. All new
+ * requests are being added to md->deferred list.
+ */
+
dm_table_postsuspend_targets(map);
set_bit(DMF_SUSPENDED, &md->flags);
@@ -1645,7 +1698,7 @@ int dm_resume(struct mapped_device *md)
if (r)
goto out;
- dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL);
+ dm_queue_flush(md);
unlock_fs(md);
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 20194e000c5..a31506d93e9 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -52,7 +52,6 @@ int dm_table_any_congested(struct dm_table *t, int bdi_bits);
* To check the return value from dm_table_find_target().
*/
#define dm_target_is_valid(t) ((t)->table)
-int dm_table_barrier_ok(struct dm_table *t);
/*-----------------------------------------------------------------
* A registry of target types.
@@ -60,7 +59,7 @@ int dm_table_barrier_ok(struct dm_table *t);
int dm_target_init(void);
void dm_target_exit(void);
struct target_type *dm_get_target_type(const char *name);
-void dm_put_target_type(struct target_type *t);
+void dm_put_target_type(struct target_type *tt);
int dm_target_iterate(void (*iter_func)(struct target_type *tt,
void *param), void *param);
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 86d9adf90e7..8695809b24b 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -62,7 +62,10 @@
#define ModeShift 5
#define MaxFault 50
-#include <linux/raid/md.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include "md.h"
+#include <linux/seq_file.h>
static void faulty_fail(struct bio *bio, int error)
@@ -280,6 +283,17 @@ static int reconfig(mddev_t *mddev, int layout, int chunk_size)
return 0;
}
+static sector_t faulty_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ WARN_ONCE(raid_disks,
+ "%s does not support generic reshape\n", __func__);
+
+ if (sectors == 0)
+ return mddev->dev_sectors;
+
+ return sectors;
+}
+
static int run(mddev_t *mddev)
{
mdk_rdev_t *rdev;
@@ -298,7 +312,7 @@ static int run(mddev_t *mddev)
list_for_each_entry(rdev, &mddev->disks, same_set)
conf->rdev = rdev;
- mddev->array_sectors = mddev->size * 2;
+ md_set_array_sectors(mddev, faulty_size(mddev, 0, 0));
mddev->private = conf;
reconfig(mddev, mddev->layout, -1);
@@ -325,6 +339,7 @@ static struct mdk_personality faulty_personality =
.stop = stop,
.status = status,
.reconfig = reconfig,
+ .size = faulty_size,
};
static int __init raid_init(void)
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 09658b21847..7a36e38393a 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -16,7 +16,11 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/raid/linear.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "linear.h"
/*
* find which device holds a particular offset
@@ -97,6 +101,16 @@ static int linear_congested(void *data, int bits)
return ret;
}
+static sector_t linear_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ linear_conf_t *conf = mddev_to_conf(mddev);
+
+ WARN_ONCE(sectors || raid_disks,
+ "%s does not support generic reshape\n", __func__);
+
+ return conf->array_sectors;
+}
+
static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
{
linear_conf_t *conf;
@@ -135,8 +149,8 @@ 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->num_sectors = rdev->size * 2;
- conf->array_sectors += rdev->size * 2;
+ disk->num_sectors = rdev->sectors;
+ conf->array_sectors += rdev->sectors;
cnt++;
}
@@ -249,7 +263,7 @@ static int linear_run (mddev_t *mddev)
if (!conf)
return 1;
mddev->private = conf;
- mddev->array_sectors = conf->array_sectors;
+ md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
mddev->queue->unplug_fn = linear_unplug;
@@ -283,7 +297,7 @@ static int linear_add(mddev_t *mddev, mdk_rdev_t *rdev)
newconf->prev = mddev_to_conf(mddev);
mddev->private = newconf;
mddev->raid_disks++;
- mddev->array_sectors = newconf->array_sectors;
+ md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
set_capacity(mddev->gendisk, mddev->array_sectors);
return 0;
}
@@ -381,6 +395,7 @@ static struct mdk_personality linear_personality =
.stop = linear_stop,
.status = linear_status,
.hot_add_disk = linear_add,
+ .size = linear_size,
};
static int __init linear_init (void)
diff --git a/include/linux/raid/linear.h b/drivers/md/linear.h
index f38b9c586af..bf8179587f9 100644
--- a/include/linux/raid/linear.h
+++ b/drivers/md/linear.h
@@ -1,8 +1,6 @@
#ifndef _LINEAR_H
#define _LINEAR_H
-#include <linux/raid/md.h>
-
struct dev_info {
mdk_rdev_t *rdev;
sector_t num_sectors;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index a307f87eb90..ed5727c089a 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -33,9 +33,9 @@
*/
#include <linux/kthread.h>
-#include <linux/raid/md.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
#include <linux/sysctl.h>
+#include <linux/seq_file.h>
#include <linux/buffer_head.h> /* for invalidate_bdev */
#include <linux/poll.h>
#include <linux/ctype.h>
@@ -45,11 +45,10 @@
#include <linux/reboot.h>
#include <linux/file.h>
#include <linux/delay.h>
-
-#define MAJOR_NR MD_MAJOR
-
-/* 63 partitions with the alternate major number (mdp) */
-#define MdpMinorShift 6
+#include <linux/raid/md_p.h>
+#include <linux/raid/md_u.h>
+#include "md.h"
+#include "bitmap.h"
#define DEBUG 0
#define dprintk(x...) ((void)(DEBUG && printk(x)))
@@ -202,12 +201,68 @@ static DEFINE_SPINLOCK(all_mddevs_lock);
)
-static int md_fail_request(struct request_queue *q, struct bio *bio)
+/* Rather than calling directly into the personality make_request function,
+ * IO requests come here first so that we can check if the device is
+ * being suspended pending a reconfiguration.
+ * We hold a refcount over the call to ->make_request. By the time that
+ * call has finished, the bio has been linked into some internal structure
+ * and so is visible to ->quiesce(), so we don't need the refcount any more.
+ */
+static int md_make_request(struct request_queue *q, struct bio *bio)
{
- bio_io_error(bio);
- return 0;
+ mddev_t *mddev = q->queuedata;
+ int rv;
+ if (mddev == NULL || mddev->pers == NULL) {
+ bio_io_error(bio);
+ return 0;
+ }
+ rcu_read_lock();
+ if (mddev->suspended) {
+ DEFINE_WAIT(__wait);
+ for (;;) {
+ prepare_to_wait(&mddev->sb_wait, &__wait,
+ TASK_UNINTERRUPTIBLE);
+ if (!mddev->suspended)
+ break;
+ rcu_read_unlock();
+ schedule();
+ rcu_read_lock();
+ }
+ finish_wait(&mddev->sb_wait, &__wait);
+ }
+ atomic_inc(&mddev->active_io);
+ rcu_read_unlock();
+ rv = mddev->pers->make_request(q, bio);
+ if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended)
+ wake_up(&mddev->sb_wait);
+
+ return rv;
+}
+
+static void mddev_suspend(mddev_t *mddev)
+{
+ BUG_ON(mddev->suspended);
+ mddev->suspended = 1;
+ synchronize_rcu();
+ wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
+ mddev->pers->quiesce(mddev, 1);
+ md_unregister_thread(mddev->thread);
+ mddev->thread = NULL;
+ /* we now know that no code is executing in the personality module,
+ * except possibly the tail end of a ->bi_end_io function, but that
+ * is certain to complete before the module has a chance to get
+ * unloaded
+ */
+}
+
+static void mddev_resume(mddev_t *mddev)
+{
+ mddev->suspended = 0;
+ wake_up(&mddev->sb_wait);
+ mddev->pers->quiesce(mddev, 0);
}
+
static inline mddev_t *mddev_get(mddev_t *mddev)
{
atomic_inc(&mddev->active);
@@ -310,6 +365,7 @@ static mddev_t * mddev_find(dev_t unit)
init_timer(&new->safemode_timer);
atomic_set(&new->active, 1);
atomic_set(&new->openers, 0);
+ atomic_set(&new->active_io, 0);
spin_lock_init(&new->write_lock);
init_waitqueue_head(&new->sb_wait);
init_waitqueue_head(&new->recovery_wait);
@@ -326,6 +382,11 @@ static inline int mddev_lock(mddev_t * mddev)
return mutex_lock_interruptible(&mddev->reconfig_mutex);
}
+static inline int mddev_is_locked(mddev_t *mddev)
+{
+ return mutex_is_locked(&mddev->reconfig_mutex);
+}
+
static inline int mddev_trylock(mddev_t * mddev)
{
return mutex_trylock(&mddev->reconfig_mutex);
@@ -409,7 +470,7 @@ static void free_disk_sb(mdk_rdev_t * rdev)
rdev->sb_loaded = 0;
rdev->sb_page = NULL;
rdev->sb_start = 0;
- rdev->size = 0;
+ rdev->sectors = 0;
}
}
@@ -775,9 +836,9 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version
else
ret = 0;
}
- rdev->size = calc_num_sectors(rdev, sb->chunk_size) / 2;
+ rdev->sectors = calc_num_sectors(rdev, sb->chunk_size);
- if (rdev->size < sb->size && sb->level > 1)
+ if (rdev->sectors < sb->size * 2 && sb->level > 1)
/* "this cannot possibly happen" ... */
ret = -EINVAL;
@@ -812,7 +873,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
mddev->clevel[0] = 0;
mddev->layout = sb->layout;
mddev->raid_disks = sb->raid_disks;
- mddev->size = sb->size;
+ mddev->dev_sectors = sb->size * 2;
mddev->events = ev1;
mddev->bitmap_offset = 0;
mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
@@ -926,7 +987,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
sb->ctime = mddev->ctime;
sb->level = mddev->level;
- sb->size = mddev->size;
+ sb->size = mddev->dev_sectors / 2;
sb->raid_disks = mddev->raid_disks;
sb->md_minor = mddev->md_minor;
sb->not_persistent = 0;
@@ -1024,7 +1085,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
static unsigned long long
super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
{
- if (num_sectors && num_sectors < rdev->mddev->size * 2)
+ if (num_sectors && num_sectors < rdev->mddev->dev_sectors)
return 0; /* component must fit device */
if (rdev->mddev->bitmap_offset)
return 0; /* can't move bitmap */
@@ -1180,16 +1241,17 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
ret = 0;
}
if (minor_version)
- rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2;
+ rdev->sectors = (rdev->bdev->bd_inode->i_size >> 9) -
+ le64_to_cpu(sb->data_offset);
else
- rdev->size = rdev->sb_start / 2;
- if (rdev->size < le64_to_cpu(sb->data_size)/2)
+ rdev->sectors = rdev->sb_start;
+ if (rdev->sectors < le64_to_cpu(sb->data_size))
return -EINVAL;
- rdev->size = le64_to_cpu(sb->data_size)/2;
+ rdev->sectors = le64_to_cpu(sb->data_size);
if (le32_to_cpu(sb->chunksize))
- rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1);
+ rdev->sectors &= ~((sector_t)le32_to_cpu(sb->chunksize) - 1);
- if (le64_to_cpu(sb->size) > rdev->size*2)
+ if (le64_to_cpu(sb->size) > rdev->sectors)
return -EINVAL;
return ret;
}
@@ -1216,7 +1278,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
mddev->clevel[0] = 0;
mddev->layout = le32_to_cpu(sb->layout);
mddev->raid_disks = le32_to_cpu(sb->raid_disks);
- mddev->size = le64_to_cpu(sb->size)/2;
+ mddev->dev_sectors = le64_to_cpu(sb->size);
mddev->events = ev1;
mddev->bitmap_offset = 0;
mddev->default_bitmap_offset = 1024 >> 9;
@@ -1312,7 +1374,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors));
sb->raid_disks = cpu_to_le32(mddev->raid_disks);
- sb->size = cpu_to_le64(mddev->size<<1);
+ sb->size = cpu_to_le64(mddev->dev_sectors);
if (mddev->bitmap && mddev->bitmap_file == NULL) {
sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
@@ -1320,10 +1382,15 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
}
if (rdev->raid_disk >= 0 &&
- !test_bit(In_sync, &rdev->flags) &&
- rdev->recovery_offset > 0) {
- sb->feature_map |= cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
- sb->recovery_offset = cpu_to_le64(rdev->recovery_offset);
+ !test_bit(In_sync, &rdev->flags)) {
+ if (mddev->curr_resync_completed > rdev->recovery_offset)
+ rdev->recovery_offset = mddev->curr_resync_completed;
+ if (rdev->recovery_offset > 0) {
+ sb->feature_map |=
+ cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
+ sb->recovery_offset =
+ cpu_to_le64(rdev->recovery_offset);
+ }
}
if (mddev->reshape_position != MaxSector) {
@@ -1365,7 +1432,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
{
struct mdp_superblock_1 *sb;
sector_t max_sectors;
- if (num_sectors && num_sectors < rdev->mddev->size * 2)
+ if (num_sectors && num_sectors < rdev->mddev->dev_sectors)
return 0; /* component must fit device */
if (rdev->sb_start < rdev->data_offset) {
/* minor versions 1 and 2; superblock before data */
@@ -1381,7 +1448,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
sector_t sb_start;
sb_start = (rdev->bdev->bd_inode->i_size >> 9) - 8*2;
sb_start &= ~(sector_t)(4*2 - 1);
- max_sectors = rdev->size * 2 + sb_start - rdev->sb_start;
+ max_sectors = rdev->sectors + sb_start - rdev->sb_start;
if (!num_sectors || num_sectors > max_sectors)
num_sectors = max_sectors;
rdev->sb_start = sb_start;
@@ -1433,6 +1500,38 @@ static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
static LIST_HEAD(pending_raid_disks);
+static void md_integrity_check(mdk_rdev_t *rdev, mddev_t *mddev)
+{
+ struct mdk_personality *pers = mddev->pers;
+ struct gendisk *disk = mddev->gendisk;
+ struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev);
+ struct blk_integrity *bi_mddev = blk_get_integrity(disk);
+
+ /* Data integrity passthrough not supported on RAID 4, 5 and 6 */
+ if (pers && pers->level >= 4 && pers->level <= 6)
+ return;
+
+ /* If rdev is integrity capable, register profile for mddev */
+ if (!bi_mddev && bi_rdev) {
+ if (blk_integrity_register(disk, bi_rdev))
+ printk(KERN_ERR "%s: %s Could not register integrity!\n",
+ __func__, disk->disk_name);
+ else
+ printk(KERN_NOTICE "Enabling data integrity on %s\n",
+ disk->disk_name);
+ return;
+ }
+
+ /* Check that mddev and rdev have matching profiles */
+ if (blk_integrity_compare(disk, rdev->bdev->bd_disk) < 0) {
+ printk(KERN_ERR "%s: %s/%s integrity mismatch!\n", __func__,
+ disk->disk_name, rdev->bdev->bd_disk->disk_name);
+ printk(KERN_NOTICE "Disabling data integrity on %s\n",
+ disk->disk_name);
+ blk_integrity_unregister(disk);
+ }
+}
+
static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
{
char b[BDEVNAME_SIZE];
@@ -1449,8 +1548,9 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
if (find_rdev(mddev, rdev->bdev->bd_dev))
return -EEXIST;
- /* make sure rdev->size exceeds mddev->size */
- if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
+ /* make sure rdev->sectors exceeds mddev->dev_sectors */
+ if (rdev->sectors && (mddev->dev_sectors == 0 ||
+ rdev->sectors < mddev->dev_sectors)) {
if (mddev->pers) {
/* Cannot change size, so fail
* If mddev->level <= 0, then we don't care
@@ -1459,7 +1559,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
if (mddev->level > 0)
return -ENOSPC;
} else
- mddev->size = rdev->size;
+ mddev->dev_sectors = rdev->sectors;
}
/* Verify rdev->desc_nr is unique.
@@ -1503,6 +1603,8 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
/* May as well allow recovery to be retried once */
mddev->recovery_disabled = 0;
+
+ md_integrity_check(rdev, mddev);
return 0;
fail:
@@ -1713,8 +1815,8 @@ static void print_sb_1(struct mdp_superblock_1 *sb)
static void print_rdev(mdk_rdev_t *rdev, int major_version)
{
char b[BDEVNAME_SIZE];
- printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n",
- bdevname(rdev->bdev,b), (unsigned long long)rdev->size,
+ printk(KERN_INFO "md: rdev %s, Sect:%08llu F:%d S:%d DN:%u\n",
+ bdevname(rdev->bdev, b), (unsigned long long)rdev->sectors,
test_bit(Faulty, &rdev->flags), test_bit(In_sync, &rdev->flags),
rdev->desc_nr);
if (rdev->sb_loaded) {
@@ -2153,7 +2255,7 @@ offset_store(mdk_rdev_t *rdev, const char *buf, size_t len)
return -EINVAL;
if (rdev->mddev->pers && rdev->raid_disk >= 0)
return -EBUSY;
- if (rdev->size && rdev->mddev->external)
+ if (rdev->sectors && rdev->mddev->external)
/* Must set offset before size, so overlap checks
* can be sane */
return -EBUSY;
@@ -2167,7 +2269,7 @@ __ATTR(offset, S_IRUGO|S_IWUSR, offset_show, offset_store);
static ssize_t
rdev_size_show(mdk_rdev_t *rdev, char *page)
{
- return sprintf(page, "%llu\n", (unsigned long long)rdev->size);
+ return sprintf(page, "%llu\n", (unsigned long long)rdev->sectors / 2);
}
static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2)
@@ -2180,34 +2282,52 @@ static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2)
return 1;
}
+static int strict_blocks_to_sectors(const char *buf, sector_t *sectors)
+{
+ unsigned long long blocks;
+ sector_t new;
+
+ if (strict_strtoull(buf, 10, &blocks) < 0)
+ return -EINVAL;
+
+ if (blocks & 1ULL << (8 * sizeof(blocks) - 1))
+ return -EINVAL; /* sector conversion overflow */
+
+ new = blocks * 2;
+ if (new != blocks * 2)
+ return -EINVAL; /* unsigned long long to sector_t overflow */
+
+ *sectors = new;
+ return 0;
+}
+
static ssize_t
rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
{
- unsigned long long size;
- unsigned long long oldsize = rdev->size;
mddev_t *my_mddev = rdev->mddev;
+ sector_t oldsectors = rdev->sectors;
+ sector_t sectors;
- if (strict_strtoull(buf, 10, &size) < 0)
+ if (strict_blocks_to_sectors(buf, &sectors) < 0)
return -EINVAL;
if (my_mddev->pers && rdev->raid_disk >= 0) {
if (my_mddev->persistent) {
- size = super_types[my_mddev->major_version].
- rdev_size_change(rdev, size * 2);
- if (!size)
+ sectors = super_types[my_mddev->major_version].
+ rdev_size_change(rdev, sectors);
+ if (!sectors)
return -EBUSY;
- } else if (!size) {
- size = (rdev->bdev->bd_inode->i_size >> 10);
- size -= rdev->data_offset/2;
- }
+ } else if (!sectors)
+ sectors = (rdev->bdev->bd_inode->i_size >> 9) -
+ rdev->data_offset;
}
- if (size < my_mddev->size)
+ if (sectors < my_mddev->dev_sectors)
return -EINVAL; /* component must fit device */
- rdev->size = size;
- if (size > oldsize && my_mddev->external) {
+ rdev->sectors = sectors;
+ if (sectors > oldsectors && my_mddev->external) {
/* need to check that all other rdevs with the same ->bdev
* do not overlap. We need to unlock the mddev to avoid
- * a deadlock. We have already changed rdev->size, and if
+ * a deadlock. We have already changed rdev->sectors, and if
* we have to change it back, we will have the lock again.
*/
mddev_t *mddev;
@@ -2223,9 +2343,9 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
if (test_bit(AllReserved, &rdev2->flags) ||
(rdev->bdev == rdev2->bdev &&
rdev != rdev2 &&
- overlaps(rdev->data_offset, rdev->size * 2,
+ overlaps(rdev->data_offset, rdev->sectors,
rdev2->data_offset,
- rdev2->size * 2))) {
+ rdev2->sectors))) {
overlap = 1;
break;
}
@@ -2239,11 +2359,11 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
if (overlap) {
/* Someone else could have slipped in a size
* change here, but doing so is just silly.
- * We put oldsize back because we *know* it is
+ * We put oldsectors back because we *know* it is
* safe, and trust userspace not to race with
* itself
*/
- rdev->size = oldsize;
+ rdev->sectors = oldsectors;
return -EBUSY;
}
}
@@ -2547,18 +2667,101 @@ level_show(mddev_t *mddev, char *page)
static ssize_t
level_store(mddev_t *mddev, const char *buf, size_t len)
{
+ char level[16];
ssize_t rv = len;
- if (mddev->pers)
+ struct mdk_personality *pers;
+ void *priv;
+
+ if (mddev->pers == NULL) {
+ if (len == 0)
+ return 0;
+ if (len >= sizeof(mddev->clevel))
+ return -ENOSPC;
+ strncpy(mddev->clevel, buf, len);
+ if (mddev->clevel[len-1] == '\n')
+ len--;
+ mddev->clevel[len] = 0;
+ mddev->level = LEVEL_NONE;
+ return rv;
+ }
+
+ /* request to change the personality. Need to ensure:
+ * - array is not engaged in resync/recovery/reshape
+ * - old personality can be suspended
+ * - new personality will access other array.
+ */
+
+ if (mddev->sync_thread || mddev->reshape_position != MaxSector)
return -EBUSY;
- if (len == 0)
- return 0;
- if (len >= sizeof(mddev->clevel))
- return -ENOSPC;
- strncpy(mddev->clevel, buf, len);
- if (mddev->clevel[len-1] == '\n')
+
+ if (!mddev->pers->quiesce) {
+ printk(KERN_WARNING "md: %s: %s does not support online personality change\n",
+ mdname(mddev), mddev->pers->name);
+ return -EINVAL;
+ }
+
+ /* Now find the new personality */
+ if (len == 0 || len >= sizeof(level))
+ return -EINVAL;
+ strncpy(level, buf, len);
+ if (level[len-1] == '\n')
len--;
- mddev->clevel[len] = 0;
- mddev->level = LEVEL_NONE;
+ level[len] = 0;
+
+ request_module("md-%s", level);
+ spin_lock(&pers_lock);
+ pers = find_pers(LEVEL_NONE, level);
+ if (!pers || !try_module_get(pers->owner)) {
+ spin_unlock(&pers_lock);
+ printk(KERN_WARNING "md: personality %s not loaded\n", level);
+ return -EINVAL;
+ }
+ spin_unlock(&pers_lock);
+
+ if (pers == mddev->pers) {
+ /* Nothing to do! */
+ module_put(pers->owner);
+ return rv;
+ }
+ if (!pers->takeover) {
+ module_put(pers->owner);
+ printk(KERN_WARNING "md: %s: %s does not support personality takeover\n",
+ mdname(mddev), level);
+ return -EINVAL;
+ }
+
+ /* ->takeover must set new_* and/or delta_disks
+ * if it succeeds, and may set them when it fails.
+ */
+ priv = pers->takeover(mddev);
+ if (IS_ERR(priv)) {
+ mddev->new_level = mddev->level;
+ mddev->new_layout = mddev->layout;
+ mddev->new_chunk = mddev->chunk_size;
+ mddev->raid_disks -= mddev->delta_disks;
+ mddev->delta_disks = 0;
+ module_put(pers->owner);
+ printk(KERN_WARNING "md: %s: %s would not accept array\n",
+ mdname(mddev), level);
+ return PTR_ERR(priv);
+ }
+
+ /* Looks like we have a winner */
+ mddev_suspend(mddev);
+ mddev->pers->stop(mddev);
+ module_put(mddev->pers->owner);
+ mddev->pers = pers;
+ mddev->private = priv;
+ strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
+ mddev->level = mddev->new_level;
+ mddev->layout = mddev->new_layout;
+ mddev->chunk_size = mddev->new_chunk;
+ mddev->delta_disks = 0;
+ pers->run(mddev);
+ mddev_resume(mddev);
+ set_bit(MD_CHANGE_DEVS, &mddev->flags);
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ md_wakeup_thread(mddev->thread);
return rv;
}
@@ -2586,12 +2789,18 @@ layout_store(mddev_t *mddev, const char *buf, size_t len)
if (!*buf || (*e && *e != '\n'))
return -EINVAL;
- if (mddev->pers)
- return -EBUSY;
- if (mddev->reshape_position != MaxSector)
+ if (mddev->pers) {
+ int err;
+ if (mddev->pers->reconfig == NULL)
+ return -EBUSY;
+ err = mddev->pers->reconfig(mddev, n, -1);
+ if (err)
+ return err;
+ } else {
mddev->new_layout = n;
- else
- mddev->layout = n;
+ if (mddev->reshape_position == MaxSector)
+ mddev->layout = n;
+ }
return len;
}
static struct md_sysfs_entry md_layout =
@@ -2648,19 +2857,24 @@ chunk_size_show(mddev_t *mddev, char *page)
static ssize_t
chunk_size_store(mddev_t *mddev, const char *buf, size_t len)
{
- /* can only set chunk_size if array is not yet active */
char *e;
unsigned long n = simple_strtoul(buf, &e, 10);
if (!*buf || (*e && *e != '\n'))
return -EINVAL;
- if (mddev->pers)
- return -EBUSY;
- else if (mddev->reshape_position != MaxSector)
+ if (mddev->pers) {
+ int err;
+ if (mddev->pers->reconfig == NULL)
+ return -EBUSY;
+ err = mddev->pers->reconfig(mddev, -1, n);
+ if (err)
+ return err;
+ } else {
mddev->new_chunk = n;
- else
- mddev->chunk_size = n;
+ if (mddev->reshape_position == MaxSector)
+ mddev->chunk_size = n;
+ }
return len;
}
static struct md_sysfs_entry md_chunk_size =
@@ -2669,6 +2883,8 @@ __ATTR(chunk_size, S_IRUGO|S_IWUSR, chunk_size_show, chunk_size_store);
static ssize_t
resync_start_show(mddev_t *mddev, char *page)
{
+ if (mddev->recovery_cp == MaxSector)
+ return sprintf(page, "none\n");
return sprintf(page, "%llu\n", (unsigned long long)mddev->recovery_cp);
}
@@ -2766,7 +2982,7 @@ array_state_show(mddev_t *mddev, char *page)
else {
if (list_empty(&mddev->disks) &&
mddev->raid_disks == 0 &&
- mddev->size == 0)
+ mddev->dev_sectors == 0)
st = clear;
else
st = inactive;
@@ -2973,7 +3189,8 @@ __ATTR(bitmap_set_bits, S_IWUSR, null_show, bitmap_store);
static ssize_t
size_show(mddev_t *mddev, char *page)
{
- return sprintf(page, "%llu\n", (unsigned long long)mddev->size);
+ return sprintf(page, "%llu\n",
+ (unsigned long long)mddev->dev_sectors / 2);
}
static int update_size(mddev_t *mddev, sector_t num_sectors);
@@ -2985,20 +3202,18 @@ size_store(mddev_t *mddev, const char *buf, size_t len)
* not increase it (except from 0).
* If array is active, we can try an on-line resize
*/
- char *e;
- int err = 0;
- unsigned long long size = simple_strtoull(buf, &e, 10);
- if (!*buf || *buf == '\n' ||
- (*e && *e != '\n'))
- return -EINVAL;
+ sector_t sectors;
+ int err = strict_blocks_to_sectors(buf, &sectors);
+ if (err < 0)
+ return err;
if (mddev->pers) {
- err = update_size(mddev, size * 2);
+ err = update_size(mddev, sectors);
md_update_sb(mddev, 1);
} else {
- if (mddev->size == 0 ||
- mddev->size > size)
- mddev->size = size;
+ if (mddev->dev_sectors == 0 ||
+ mddev->dev_sectors > sectors)
+ mddev->dev_sectors = sectors;
else
err = -ENOSPC;
}
@@ -3251,6 +3466,8 @@ static ssize_t
sync_speed_show(mddev_t *mddev, char *page)
{
unsigned long resync, dt, db;
+ if (mddev->curr_resync == 0)
+ return sprintf(page, "none\n");
resync = mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active);
dt = (jiffies - mddev->resync_mark) / HZ;
if (!dt) dt++;
@@ -3263,15 +3480,15 @@ static struct md_sysfs_entry md_sync_speed = __ATTR_RO(sync_speed);
static ssize_t
sync_completed_show(mddev_t *mddev, char *page)
{
- unsigned long max_blocks, resync;
+ unsigned long max_sectors, resync;
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
- max_blocks = mddev->resync_max_sectors;
+ max_sectors = mddev->resync_max_sectors;
else
- max_blocks = mddev->size << 1;
+ max_sectors = mddev->dev_sectors;
resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active));
- return sprintf(page, "%lu / %lu\n", resync, max_blocks);
+ return sprintf(page, "%lu / %lu\n", resync, max_sectors);
}
static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed);
@@ -3431,6 +3648,57 @@ static struct md_sysfs_entry md_reshape_position =
__ATTR(reshape_position, S_IRUGO|S_IWUSR, reshape_position_show,
reshape_position_store);
+static ssize_t
+array_size_show(mddev_t *mddev, char *page)
+{
+ if (mddev->external_size)
+ return sprintf(page, "%llu\n",
+ (unsigned long long)mddev->array_sectors/2);
+ else
+ return sprintf(page, "default\n");
+}
+
+static ssize_t
+array_size_store(mddev_t *mddev, const char *buf, size_t len)
+{
+ sector_t sectors;
+
+ if (strncmp(buf, "default", 7) == 0) {
+ if (mddev->pers)
+ sectors = mddev->pers->size(mddev, 0, 0);
+ else
+ sectors = mddev->array_sectors;
+
+ mddev->external_size = 0;
+ } else {
+ if (strict_blocks_to_sectors(buf, &sectors) < 0)
+ return -EINVAL;
+ if (mddev->pers && mddev->pers->size(mddev, 0, 0) < sectors)
+ return -EINVAL;
+
+ mddev->external_size = 1;
+ }
+
+ mddev->array_sectors = sectors;
+ set_capacity(mddev->gendisk, mddev->array_sectors);
+ if (mddev->pers) {
+ struct block_device *bdev = bdget_disk(mddev->gendisk, 0);
+
+ if (bdev) {
+ mutex_lock(&bdev->bd_inode->i_mutex);
+ i_size_write(bdev->bd_inode,
+ (loff_t)mddev->array_sectors << 9);
+ mutex_unlock(&bdev->bd_inode->i_mutex);
+ bdput(bdev);
+ }
+ }
+
+ return len;
+}
+
+static struct md_sysfs_entry md_array_size =
+__ATTR(array_size, S_IRUGO|S_IWUSR, array_size_show,
+ array_size_store);
static struct attribute *md_default_attrs[] = {
&md_level.attr,
@@ -3444,6 +3712,7 @@ static struct attribute *md_default_attrs[] = {
&md_safe_delay.attr,
&md_array_state.attr,
&md_reshape_position.attr,
+ &md_array_size.attr,
NULL,
};
@@ -3602,10 +3871,12 @@ static int md_alloc(dev_t dev, char *name)
mddev_put(mddev);
return -ENOMEM;
}
+ mddev->queue->queuedata = mddev;
+
/* Can be unlocked because the queue is new: no concurrency */
queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue);
- blk_queue_make_request(mddev->queue, md_fail_request);
+ blk_queue_make_request(mddev->queue, md_make_request);
disk = alloc_disk(1 << shift);
if (!disk) {
@@ -3731,13 +4002,13 @@ static int do_md_run(mddev_t * mddev)
list_for_each_entry(rdev, &mddev->disks, same_set) {
if (test_bit(Faulty, &rdev->flags))
continue;
- if (rdev->size < chunk_size / 1024) {
+ if (rdev->sectors < chunk_size / 512) {
printk(KERN_WARNING
"md: Dev %s smaller than chunk_size:"
- " %lluk < %dk\n",
+ " %llu < %d\n",
bdevname(rdev->bdev,b),
- (unsigned long long)rdev->size,
- chunk_size / 1024);
+ (unsigned long long)rdev->sectors,
+ chunk_size / 512);
return -EINVAL;
}
}
@@ -3761,11 +4032,11 @@ static int do_md_run(mddev_t * mddev)
/* perform some consistency tests on the device.
* We don't want the data to overlap the metadata,
- * Internal Bitmap issues has handled elsewhere.
+ * Internal Bitmap issues have been handled elsewhere.
*/
if (rdev->data_offset < rdev->sb_start) {
- if (mddev->size &&
- rdev->data_offset + mddev->size*2
+ if (mddev->dev_sectors &&
+ rdev->data_offset + mddev->dev_sectors
> rdev->sb_start) {
printk("md: %s: data overlaps metadata\n",
mdname(mddev));
@@ -3801,9 +4072,16 @@ static int do_md_run(mddev_t * mddev)
}
mddev->pers = pers;
spin_unlock(&pers_lock);
- mddev->level = pers->level;
+ if (mddev->level != pers->level) {
+ mddev->level = pers->level;
+ mddev->new_level = pers->level;
+ }
strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
+ if (pers->level >= 4 && pers->level <= 6)
+ /* Cannot support integrity (yet) */
+ blk_integrity_unregister(mddev->gendisk);
+
if (mddev->reshape_position != MaxSector &&
pers->start_reshape == NULL) {
/* This personality cannot handle reshaping... */
@@ -3843,7 +4121,9 @@ static int do_md_run(mddev_t * mddev)
}
mddev->recovery = 0;
- mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
+ /* may be over-ridden by personality */
+ mddev->resync_max_sectors = mddev->dev_sectors;
+
mddev->barriers_work = 1;
mddev->ok_start_degraded = start_dirty_degraded;
@@ -3853,7 +4133,17 @@ static int do_md_run(mddev_t * mddev)
err = mddev->pers->run(mddev);
if (err)
printk(KERN_ERR "md: pers->run() failed ...\n");
- else if (mddev->pers->sync_request) {
+ else if (mddev->pers->size(mddev, 0, 0) < mddev->array_sectors) {
+ WARN_ONCE(!mddev->external_size, "%s: default size too small,"
+ " but 'external_size' not in effect?\n", __func__);
+ printk(KERN_ERR
+ "md: invalid array_size %llu > default size %llu\n",
+ (unsigned long long)mddev->array_sectors / 2,
+ (unsigned long long)mddev->pers->size(mddev, 0, 0) / 2);
+ err = -EINVAL;
+ mddev->pers->stop(mddev);
+ }
+ if (err == 0 && mddev->pers->sync_request) {
err = bitmap_create(mddev);
if (err) {
printk(KERN_ERR "%s: failed to create bitmap (%d)\n",
@@ -3899,16 +4189,6 @@ static int do_md_run(mddev_t * mddev)
set_capacity(disk, mddev->array_sectors);
- /* If we call blk_queue_make_request here, it will
- * re-initialise max_sectors etc which may have been
- * refined inside -> run. So just set the bits we need to set.
- * Most initialisation happended when we called
- * blk_queue_make_request(..., md_fail_request)
- * earlier.
- */
- mddev->queue->queuedata = mddev;
- mddev->queue->make_request_fn = mddev->pers->make_request;
-
/* If there is a partially-recovered drive we need to
* start recovery here. If we leave it to md_check_recovery,
* it will remove the drives and not do the right thing
@@ -4038,7 +4318,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
md_super_wait(mddev);
if (mddev->ro)
set_disk_ro(disk, 0);
- blk_queue_make_request(mddev->queue, md_fail_request);
+
mddev->pers->stop(mddev);
mddev->queue->merge_bvec_fn = NULL;
mddev->queue->unplug_fn = NULL;
@@ -4095,7 +4375,8 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
export_array(mddev);
mddev->array_sectors = 0;
- mddev->size = 0;
+ mddev->external_size = 0;
+ mddev->dev_sectors = 0;
mddev->raid_disks = 0;
mddev->recovery_cp = 0;
mddev->resync_min = 0;
@@ -4135,6 +4416,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
printk(KERN_INFO "md: %s switched to read-only mode.\n",
mdname(mddev));
err = 0;
+ blk_integrity_unregister(disk);
md_new_event(mddev);
sysfs_notify_dirent(mddev->sysfs_state);
out:
@@ -4300,8 +4582,8 @@ static int get_array_info(mddev_t * mddev, void __user * arg)
info.patch_version = MD_PATCHLEVEL_VERSION;
info.ctime = mddev->ctime;
info.level = mddev->level;
- info.size = mddev->size;
- if (info.size != mddev->size) /* overflow */
+ info.size = mddev->dev_sectors / 2;
+ if (info.size != mddev->dev_sectors / 2) /* overflow */
info.size = -1;
info.nr_disks = nr;
info.raid_disks = mddev->raid_disks;
@@ -4480,6 +4762,8 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
clear_bit(In_sync, &rdev->flags); /* just to be sure */
if (info->state & (1<<MD_DISK_WRITEMOSTLY))
set_bit(WriteMostly, &rdev->flags);
+ else
+ clear_bit(WriteMostly, &rdev->flags);
rdev->raid_disk = -1;
err = bind_rdev_to_array(rdev, mddev);
@@ -4543,7 +4827,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
} else
rdev->sb_start = calc_dev_sboffset(rdev->bdev);
- rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2;
+ rdev->sectors = calc_num_sectors(rdev, mddev->chunk_size);
err = bind_rdev_to_array(rdev, mddev);
if (err) {
@@ -4613,7 +4897,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
else
rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
- rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2;
+ rdev->sectors = calc_num_sectors(rdev, mddev->chunk_size);
if (test_bit(Faulty, &rdev->flags)) {
printk(KERN_WARNING
@@ -4749,7 +5033,7 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
mddev->level = info->level;
mddev->clevel[0] = 0;
- mddev->size = info->size;
+ mddev->dev_sectors = 2 * (sector_t)info->size;
mddev->raid_disks = info->raid_disks;
/* don't set md_minor, it is determined by which /dev/md* was
* openned
@@ -4788,6 +5072,17 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
return 0;
}
+void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors)
+{
+ WARN(!mddev_is_locked(mddev), "%s: unlocked mddev!\n", __func__);
+
+ if (mddev->external_size)
+ return;
+
+ mddev->array_sectors = array_sectors;
+}
+EXPORT_SYMBOL(md_set_array_sectors);
+
static int update_size(mddev_t *mddev, sector_t num_sectors)
{
mdk_rdev_t *rdev;
@@ -4814,8 +5109,7 @@ static int update_size(mddev_t *mddev, sector_t num_sectors)
*/
return -EBUSY;
list_for_each_entry(rdev, &mddev->disks, same_set) {
- sector_t avail;
- avail = rdev->size * 2;
+ sector_t avail = rdev->sectors;
if (fit && (num_sectors == 0 || num_sectors > avail))
num_sectors = avail;
@@ -4887,12 +5181,18 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
)
return -EINVAL;
/* Check there is only one change */
- if (info->size >= 0 && mddev->size != info->size) cnt++;
- if (mddev->raid_disks != info->raid_disks) cnt++;
- if (mddev->layout != info->layout) cnt++;
- if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) cnt++;
- if (cnt == 0) return 0;
- if (cnt > 1) return -EINVAL;
+ if (info->size >= 0 && mddev->dev_sectors / 2 != info->size)
+ cnt++;
+ if (mddev->raid_disks != info->raid_disks)
+ cnt++;
+ if (mddev->layout != info->layout)
+ cnt++;
+ if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT))
+ cnt++;
+ if (cnt == 0)
+ return 0;
+ if (cnt > 1)
+ return -EINVAL;
if (mddev->layout != info->layout) {
/* Change layout
@@ -4904,7 +5204,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
else
return mddev->pers->reconfig(mddev, info->layout, -1);
}
- if (info->size >= 0 && mddev->size != info->size)
+ if (info->size >= 0 && mddev->dev_sectors / 2 != info->size)
rv = update_size(mddev, (sector_t)info->size * 2);
if (mddev->raid_disks != info->raid_disks)
@@ -5331,6 +5631,8 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
void md_unregister_thread(mdk_thread_t *thread)
{
+ if (!thread)
+ return;
dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
kthread_stop(thread->tsk);
@@ -5404,7 +5706,7 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev)
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
max_blocks = mddev->resync_max_sectors >> 1;
else
- max_blocks = mddev->size;
+ max_blocks = mddev->dev_sectors / 2;
/*
* Should not happen.
@@ -5537,7 +5839,7 @@ struct mdstat_info {
static int md_seq_show(struct seq_file *seq, void *v)
{
mddev_t *mddev = v;
- sector_t size;
+ sector_t sectors;
mdk_rdev_t *rdev;
struct mdstat_info *mi = seq->private;
struct bitmap *bitmap;
@@ -5573,7 +5875,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, " %s", mddev->pers->name);
}
- size = 0;
+ sectors = 0;
list_for_each_entry(rdev, &mddev->disks, same_set) {
char b[BDEVNAME_SIZE];
seq_printf(seq, " %s[%d]",
@@ -5585,7 +5887,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
continue;
} else if (rdev->raid_disk < 0)
seq_printf(seq, "(S)"); /* spare */
- size += rdev->size;
+ sectors += rdev->sectors;
}
if (!list_empty(&mddev->disks)) {
@@ -5595,7 +5897,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
mddev->array_sectors / 2);
else
seq_printf(seq, "\n %llu blocks",
- (unsigned long long)size);
+ (unsigned long long)sectors / 2);
}
if (mddev->persistent) {
if (mddev->major_version != 0 ||
@@ -5722,19 +6024,19 @@ int unregister_md_personality(struct mdk_personality *p)
return 0;
}
-static int is_mddev_idle(mddev_t *mddev)
+static int is_mddev_idle(mddev_t *mddev, int init)
{
mdk_rdev_t * rdev;
int idle;
- long curr_events;
+ int curr_events;
idle = 1;
rcu_read_lock();
rdev_for_each_rcu(rdev, mddev) {
struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
- curr_events = part_stat_read(&disk->part0, sectors[0]) +
- part_stat_read(&disk->part0, sectors[1]) -
- atomic_read(&disk->sync_io);
+ curr_events = (int)part_stat_read(&disk->part0, sectors[0]) +
+ (int)part_stat_read(&disk->part0, sectors[1]) -
+ atomic_read(&disk->sync_io);
/* sync IO will cause sync_io to increase before the disk_stats
* as sync_io is counted when a request starts, and
* disk_stats is counted when it completes.
@@ -5757,7 +6059,7 @@ static int is_mddev_idle(mddev_t *mddev)
* always make curr_events less than last_events.
*
*/
- if (curr_events - rdev->last_events > 4096) {
+ if (init || curr_events - rdev->last_events > 64) {
rdev->last_events = curr_events;
idle = 0;
}
@@ -5980,10 +6282,10 @@ void md_do_sync(mddev_t *mddev)
j = mddev->recovery_cp;
} else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
- max_sectors = mddev->size << 1;
+ max_sectors = mddev->dev_sectors;
else {
/* recovery follows the physical size of devices */
- max_sectors = mddev->size << 1;
+ max_sectors = mddev->dev_sectors;
j = MaxSector;
list_for_each_entry(rdev, &mddev->disks, same_set)
if (rdev->raid_disk >= 0 &&
@@ -6000,7 +6302,7 @@ void md_do_sync(mddev_t *mddev)
"(but not more than %d KB/sec) for %s.\n",
speed_max(mddev), desc);
- is_mddev_idle(mddev); /* this also initializes IO event counters */
+ is_mddev_idle(mddev, 1); /* this initializes IO event counters */
io_sectors = 0;
for (m = 0; m < SYNC_MARKS; m++) {
@@ -6040,6 +6342,18 @@ void md_do_sync(mddev_t *mddev)
}
if (kthread_should_stop())
goto interrupted;
+
+ if (mddev->curr_resync > mddev->curr_resync_completed &&
+ (mddev->curr_resync - mddev->curr_resync_completed)
+ > (max_sectors >> 4)) {
+ /* time to update curr_resync_completed */
+ blk_unplug(mddev->queue);
+ wait_event(mddev->recovery_wait,
+ atomic_read(&mddev->recovery_active) == 0);
+ mddev->curr_resync_completed =
+ mddev->curr_resync;
+ set_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ }
sectors = mddev->pers->sync_request(mddev, j, &skipped,
currspeed < speed_min(mddev));
if (sectors == 0) {
@@ -6102,7 +6416,7 @@ void md_do_sync(mddev_t *mddev)
if (currspeed > speed_min(mddev)) {
if ((currspeed > speed_max(mddev)) ||
- !is_mddev_idle(mddev)) {
+ !is_mddev_idle(mddev, 0)) {
msleep(500);
goto repeat;
}
@@ -6173,6 +6487,8 @@ static int remove_and_add_spares(mddev_t *mddev)
mdk_rdev_t *rdev;
int spares = 0;
+ mddev->curr_resync_completed = 0;
+
list_for_each_entry(rdev, &mddev->disks, same_set)
if (rdev->raid_disk >= 0 &&
!test_bit(Blocked, &rdev->flags) &&
@@ -6327,6 +6643,9 @@ void md_check_recovery(mddev_t *mddev)
sysfs_notify(&mddev->kobj, NULL,
"degraded");
}
+ if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
+ mddev->pers->finish_reshape)
+ mddev->pers->finish_reshape(mddev);
md_update_sb(mddev, 1);
/* if array is no-longer degraded, then any saved_raid_disk
@@ -6470,13 +6789,13 @@ static void md_geninit(void)
static int __init md_init(void)
{
- if (register_blkdev(MAJOR_NR, "md"))
+ if (register_blkdev(MD_MAJOR, "md"))
return -1;
if ((mdp_major=register_blkdev(0, "mdp"))<=0) {
- unregister_blkdev(MAJOR_NR, "md");
+ unregister_blkdev(MD_MAJOR, "md");
return -1;
}
- blk_register_region(MKDEV(MAJOR_NR, 0), 1UL<<MINORBITS, THIS_MODULE,
+ blk_register_region(MKDEV(MD_MAJOR, 0), 1UL<<MINORBITS, THIS_MODULE,
md_probe, NULL, NULL);
blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE,
md_probe, NULL, NULL);
@@ -6562,10 +6881,10 @@ static __exit void md_exit(void)
mddev_t *mddev;
struct list_head *tmp;
- blk_unregister_region(MKDEV(MAJOR_NR,0), 1U << MINORBITS);
+ blk_unregister_region(MKDEV(MD_MAJOR,0), 1U << MINORBITS);
blk_unregister_region(MKDEV(mdp_major,0), 1U << MINORBITS);
- unregister_blkdev(MAJOR_NR,"md");
+ unregister_blkdev(MD_MAJOR,"md");
unregister_blkdev(mdp_major, "mdp");
unregister_reboot_notifier(&md_notifier);
unregister_sysctl_table(raid_table_header);
diff --git a/include/linux/raid/md_k.h b/drivers/md/md.h
index 9743e4dbc91..e9b7f54c24d 100644
--- a/include/linux/raid/md_k.h
+++ b/drivers/md/md.h
@@ -15,21 +15,8 @@
#ifndef _MD_K_H
#define _MD_K_H
-/* and dm-bio-list.h is not under include/linux because.... ??? */
-#include "../../../drivers/md/dm-bio-list.h"
-
#ifdef CONFIG_BLOCK
-#define LEVEL_MULTIPATH (-4)
-#define LEVEL_LINEAR (-1)
-#define LEVEL_FAULTY (-5)
-
-/* we need a value for 'no level specified' and 0
- * means 'raid0', so we need something else. This is
- * for internal use only
- */
-#define LEVEL_NONE (-1000000)
-
#define MaxSector (~(sector_t)0)
typedef struct mddev_s mddev_t;
@@ -49,9 +36,9 @@ struct mdk_rdev_s
{
struct list_head same_set; /* RAID devices within the same set */
- sector_t size; /* Device size (in blocks) */
+ sector_t sectors; /* Device size (in 512bytes sectors) */
mddev_t *mddev; /* RAID array if running */
- long last_events; /* IO event timestamp */
+ int last_events; /* IO event timestamp */
struct block_device *bdev; /* block device handle */
@@ -132,6 +119,8 @@ struct mddev_s
#define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */
#define MD_CHANGE_PENDING 2 /* superblock update in progress */
+ int suspended;
+ atomic_t active_io;
int ro;
struct gendisk *gendisk;
@@ -155,8 +144,11 @@ struct mddev_s
char clevel[16];
int raid_disks;
int max_disks;
- sector_t size; /* used size of component devices */
+ sector_t dev_sectors; /* used size of
+ * component devices */
sector_t array_sectors; /* exported array size */
+ int external_size; /* size managed
+ * externally */
__u64 events;
char uuid[16];
@@ -172,6 +164,13 @@ struct mddev_s
struct mdk_thread_s *thread; /* management thread */
struct mdk_thread_s *sync_thread; /* doing resync or reconstruct */
sector_t curr_resync; /* last block scheduled */
+ /* As resync requests can complete out of order, we cannot easily track
+ * how much resync has been completed. So we occasionally pause until
+ * everything completes, then set curr_resync_completed to curr_resync.
+ * As such it may be well behind the real resync mark, but it is a value
+ * we are certain of.
+ */
+ sector_t curr_resync_completed;
unsigned long resync_mark; /* a recent timestamp */
sector_t resync_mark_cnt;/* blocks written at resync_mark */
sector_t curr_mark_cnt; /* blocks scheduled now */
@@ -315,8 +314,10 @@ struct mdk_personality
int (*spare_active) (mddev_t *mddev);
sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster);
int (*resize) (mddev_t *mddev, sector_t sectors);
+ sector_t (*size) (mddev_t *mddev, sector_t sectors, int raid_disks);
int (*check_reshape) (mddev_t *mddev);
int (*start_reshape) (mddev_t *mddev);
+ void (*finish_reshape) (mddev_t *mddev);
int (*reconfig) (mddev_t *mddev, int layout, int chunk_size);
/* quiesce moves between quiescence states
* 0 - fully active
@@ -324,6 +325,16 @@ struct mdk_personality
* others - reserved
*/
void (*quiesce) (mddev_t *mddev, int state);
+ /* takeover is used to transition an array from one
+ * personality to another. The new personality must be able
+ * to handle the data in the current layout.
+ * e.g. 2drive raid1 -> 2drive raid5
+ * ndrive raid5 -> degraded n+1drive raid6 with special layout
+ * If the takeover succeeds, a new 'private' structure is returned.
+ * This needs to be installed and then ->run used to activate the
+ * array.
+ */
+ void *(*takeover) (mddev_t *mddev);
};
@@ -400,3 +411,26 @@ static inline void safe_put_page(struct page *p)
#endif /* CONFIG_BLOCK */
#endif
+
+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_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_done_sync(mddev_t *mddev, int blocks, int ok);
+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);
+extern void md_super_wait(mddev_t *mddev);
+extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
+ struct page *page, int rw);
+extern void md_do_sync(mddev_t *mddev);
+extern void md_new_event(mddev_t *mddev);
+extern int md_allow_write(mddev_t *mddev);
+extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
+extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors);
diff --git a/drivers/md/mktables.c b/drivers/md/mktables.c
index b61d5767aae..3b1500843bb 100644
--- a/drivers/md/mktables.c
+++ b/drivers/md/mktables.c
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
uint8_t v;
uint8_t exptbl[256], invtbl[256];
- printf("#include \"raid6.h\"\n");
+ printf("#include <linux/raid/pq.h>\n");
/* Compute multiplication table */
printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -76,6 +76,9 @@ int main(int argc, char *argv[])
printf("\t},\n");
}
printf("};\n");
+ printf("#ifdef __KERNEL__\n");
+ printf("EXPORT_SYMBOL(raid6_gfmul);\n");
+ printf("#endif\n");
/* Compute power-of-2 table (exponent) */
v = 1;
@@ -92,6 +95,9 @@ int main(int argc, char *argv[])
}
}
printf("};\n");
+ printf("#ifdef __KERNEL__\n");
+ printf("EXPORT_SYMBOL(raid6_gfexp);\n");
+ printf("#endif\n");
/* Compute inverse table x^-1 == x^254 */
printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -104,6 +110,9 @@ int main(int argc, char *argv[])
}
}
printf("};\n");
+ printf("#ifdef __KERNEL__\n");
+ printf("EXPORT_SYMBOL(raid6_gfinv);\n");
+ printf("#endif\n");
/* Compute inv(2^x + 1) (exponent-xor-inverse) table */
printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -115,6 +124,9 @@ int main(int argc, char *argv[])
(j == 7) ? '\n' : ' ');
}
printf("};\n");
+ printf("#ifdef __KERNEL__\n");
+ printf("EXPORT_SYMBOL(raid6_gfexi);\n");
+ printf("#endif\n");
return 0;
}
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index f6d08f24167..41ced0cbe82 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -19,7 +19,11 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/raid/multipath.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "multipath.h"
#define MAX_WORK_PER_DISK 128
@@ -402,6 +406,14 @@ static void multipathd (mddev_t *mddev)
spin_unlock_irqrestore(&conf->device_lock, flags);
}
+static sector_t multipath_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ WARN_ONCE(sectors || raid_disks,
+ "%s does not support generic reshape\n", __func__);
+
+ return mddev->dev_sectors;
+}
+
static int multipath_run (mddev_t *mddev)
{
multipath_conf_t *conf;
@@ -498,7 +510,7 @@ static int multipath_run (mddev_t *mddev)
/*
* Ok, everything is just fine now
*/
- mddev->array_sectors = mddev->size * 2;
+ md_set_array_sectors(mddev, multipath_size(mddev, 0, 0));
mddev->queue->unplug_fn = multipath_unplug;
mddev->queue->backing_dev_info.congested_fn = multipath_congested;
@@ -543,6 +555,7 @@ static struct mdk_personality multipath_personality =
.error_handler = multipath_error,
.hot_add_disk = multipath_add_disk,
.hot_remove_disk= multipath_remove_disk,
+ .size = multipath_size,
};
static int __init multipath_init (void)
diff --git a/include/linux/raid/multipath.h b/drivers/md/multipath.h
index 6f53fc177a4..6fa70b400cd 100644
--- a/include/linux/raid/multipath.h
+++ b/drivers/md/multipath.h
@@ -1,8 +1,6 @@
#ifndef _MULTIPATH_H
#define _MULTIPATH_H
-#include <linux/raid/md.h>
-
struct multipath_info {
mdk_rdev_t *rdev;
};
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index c605ba80558..c08d7559be5 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -18,7 +18,10 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/raid/raid0.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "raid0.h"
static void raid0_unplug(struct request_queue *q)
{
@@ -73,16 +76,15 @@ static int create_strip_zones (mddev_t *mddev)
list_for_each_entry(rdev2, &mddev->disks, same_set) {
printk(KERN_INFO "raid0: comparing %s(%llu)",
bdevname(rdev1->bdev,b),
- (unsigned long long)rdev1->size);
+ (unsigned long long)rdev1->sectors);
printk(KERN_INFO " with %s(%llu)\n",
bdevname(rdev2->bdev,b),
- (unsigned long long)rdev2->size);
+ (unsigned long long)rdev2->sectors);
if (rdev2 == rdev1) {
printk(KERN_INFO "raid0: END\n");
break;
}
- if (rdev2->size == rdev1->size)
- {
+ if (rdev2->sectors == rdev1->sectors) {
/*
* Not unique, don't count it as a new
* group
@@ -145,7 +147,7 @@ static int create_strip_zones (mddev_t *mddev)
mddev->queue->max_sectors > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
- if (!smallest || (rdev1->size <smallest->size))
+ if (!smallest || (rdev1->sectors < smallest->sectors))
smallest = rdev1;
cnt++;
}
@@ -155,10 +157,10 @@ static int create_strip_zones (mddev_t *mddev)
goto abort;
}
zone->nb_dev = cnt;
- zone->sectors = smallest->size * cnt * 2;
+ zone->sectors = smallest->sectors * cnt;
zone->zone_start = 0;
- current_start = smallest->size * 2;
+ current_start = smallest->sectors;
curr_zone_start = zone->sectors;
/* now do the other zones */
@@ -177,29 +179,29 @@ static int create_strip_zones (mddev_t *mddev)
rdev = conf->strip_zone[0].dev[j];
printk(KERN_INFO "raid0: checking %s ...",
bdevname(rdev->bdev, b));
- if (rdev->size > current_start / 2) {
- printk(KERN_INFO " contained as device %d\n",
- c);
- zone->dev[c] = rdev;
- c++;
- if (!smallest || (rdev->size <smallest->size)) {
- smallest = rdev;
- printk(KERN_INFO " (%llu) is smallest!.\n",
- (unsigned long long)rdev->size);
- }
- } else
+ if (rdev->sectors <= current_start) {
printk(KERN_INFO " nope.\n");
+ continue;
+ }
+ printk(KERN_INFO " contained as device %d\n", c);
+ zone->dev[c] = rdev;
+ c++;
+ if (!smallest || rdev->sectors < smallest->sectors) {
+ smallest = rdev;
+ printk(KERN_INFO " (%llu) is smallest!.\n",
+ (unsigned long long)rdev->sectors);
+ }
}
zone->nb_dev = c;
- zone->sectors = (smallest->size * 2 - current_start) * c;
+ zone->sectors = (smallest->sectors - current_start) * c;
printk(KERN_INFO "raid0: zone->nb_dev: %d, sectors: %llu\n",
zone->nb_dev, (unsigned long long)zone->sectors);
zone->zone_start = curr_zone_start;
curr_zone_start += zone->sectors;
- current_start = smallest->size * 2;
+ current_start = smallest->sectors;
printk(KERN_INFO "raid0: current zone start: %llu\n",
(unsigned long long)current_start);
}
@@ -261,12 +263,25 @@ static int raid0_mergeable_bvec(struct request_queue *q,
return max;
}
+static sector_t raid0_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ sector_t array_sectors = 0;
+ mdk_rdev_t *rdev;
+
+ WARN_ONCE(sectors || raid_disks,
+ "%s does not support generic reshape\n", __func__);
+
+ list_for_each_entry(rdev, &mddev->disks, same_set)
+ array_sectors += rdev->sectors;
+
+ return array_sectors;
+}
+
static int raid0_run (mddev_t *mddev)
{
unsigned cur=0, i=0, nb_zone;
s64 sectors;
raid0_conf_t *conf;
- mdk_rdev_t *rdev;
if (mddev->chunk_size == 0) {
printk(KERN_ERR "md/raid0: non-zero chunk size required.\n");
@@ -291,16 +306,14 @@ static int raid0_run (mddev_t *mddev)
goto out_free_conf;
/* calculate array device size */
- mddev->array_sectors = 0;
- list_for_each_entry(rdev, &mddev->disks, same_set)
- mddev->array_sectors += rdev->size * 2;
+ md_set_array_sectors(mddev, raid0_size(mddev, 0, 0));
printk(KERN_INFO "raid0 : md_size is %llu sectors.\n",
(unsigned long long)mddev->array_sectors);
printk(KERN_INFO "raid0 : conf->spacing is %llu sectors.\n",
(unsigned long long)conf->spacing);
{
- sector_t s = mddev->array_sectors;
+ sector_t s = raid0_size(mddev, 0, 0);
sector_t space = conf->spacing;
int round;
conf->sector_shift = 0;
@@ -509,6 +522,7 @@ static struct mdk_personality raid0_personality=
.run = raid0_run,
.stop = raid0_stop,
.status = raid0_status,
+ .size = raid0_size,
};
static int __init raid0_init (void)
diff --git a/include/linux/raid/raid0.h b/drivers/md/raid0.h
index fd42aa87c39..824b12eb1d4 100644
--- a/include/linux/raid/raid0.h
+++ b/drivers/md/raid0.h
@@ -1,8 +1,6 @@
#ifndef _RAID0_H
#define _RAID0_H
-#include <linux/raid/md.h>
-
struct strip_zone
{
sector_t zone_start; /* Zone offset in md_dev (in sectors) */
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index e2466425d9c..274b491a11c 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -31,10 +31,13 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "dm-bio-list.h"
#include <linux/delay.h>
-#include <linux/raid/raid1.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "dm-bio-list.h"
+#include "raid1.h"
+#include "bitmap.h"
#define DEBUG 0
#if DEBUG
@@ -120,6 +123,7 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
goto out_free_pages;
bio->bi_io_vec[i].bv_page = page;
+ bio->bi_vcnt = i+1;
}
}
/* If not user-requests, copy the page pointers to all bios */
@@ -135,9 +139,9 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
return r1_bio;
out_free_pages:
- for (i=0; i < RESYNC_PAGES ; i++)
- for (j=0 ; j < pi->raid_disks; j++)
- safe_put_page(r1_bio->bios[j]->bi_io_vec[i].bv_page);
+ for (j=0 ; j < pi->raid_disks; j++)
+ for (i=0; i < r1_bio->bios[j]->bi_vcnt ; i++)
+ put_page(r1_bio->bios[j]->bi_io_vec[i].bv_page);
j = -1;
out_free_bio:
while ( ++j < pi->raid_disks )
@@ -582,7 +586,7 @@ static int raid1_congested(void *data, int bits)
/* Note the '|| 1' - when read_balance prefers
* non-congested targets, it can be removed
*/
- if ((bits & (1<<BDI_write_congested)) || 1)
+ if ((bits & (1<<BDI_async_congested)) || 1)
ret |= bdi_congested(&q->backing_dev_info, bits);
else
ret &= bdi_congested(&q->backing_dev_info, bits);
@@ -1723,7 +1727,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
return 0;
}
- max_sector = mddev->size << 1;
+ max_sector = mddev->dev_sectors;
if (sector_nr >= max_sector) {
/* If we aborted, we need to abort the
* sync on the 'current' bitmap chunk (there will
@@ -1919,6 +1923,14 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
return nr_sectors;
}
+static sector_t raid1_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ if (sectors)
+ return sectors;
+
+ return mddev->dev_sectors;
+}
+
static int run(mddev_t *mddev)
{
conf_t *conf;
@@ -2048,7 +2060,7 @@ static int run(mddev_t *mddev)
/*
* Ok, everything is just fine now
*/
- mddev->array_sectors = mddev->size * 2;
+ md_set_array_sectors(mddev, raid1_size(mddev, 0, 0));
mddev->queue->unplug_fn = raid1_unplug;
mddev->queue->backing_dev_info.congested_fn = raid1_congested;
@@ -2089,6 +2101,9 @@ static int stop(mddev_t *mddev)
/* need to kick something here to make sure I/O goes? */
}
+ raise_barrier(conf);
+ lower_barrier(conf);
+
md_unregister_thread(mddev->thread);
mddev->thread = NULL;
blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
@@ -2110,15 +2125,17 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors)
* any io in the removed space completes, but it hardly seems
* worth it.
*/
- mddev->array_sectors = sectors;
+ md_set_array_sectors(mddev, raid1_size(mddev, sectors, 0));
+ if (mddev->array_sectors > raid1_size(mddev, sectors, 0))
+ return -EINVAL;
set_capacity(mddev->gendisk, mddev->array_sectors);
mddev->changed = 1;
- if (mddev->array_sectors / 2 > mddev->size &&
+ if (sectors > mddev->dev_sectors &&
mddev->recovery_cp == MaxSector) {
- mddev->recovery_cp = mddev->size << 1;
+ mddev->recovery_cp = mddev->dev_sectors;
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
}
- mddev->size = mddev->array_sectors / 2;
+ mddev->dev_sectors = sectors;
mddev->resync_max_sectors = sectors;
return 0;
}
@@ -2264,6 +2281,7 @@ static struct mdk_personality raid1_personality =
.spare_active = raid1_spare_active,
.sync_request = sync_request,
.resize = raid1_resize,
+ .size = raid1_size,
.check_reshape = raid1_reshape,
.quiesce = raid1_quiesce,
};
diff --git a/include/linux/raid/raid1.h b/drivers/md/raid1.h
index 0a9ba7c3302..1620eea3d57 100644
--- a/include/linux/raid/raid1.h
+++ b/drivers/md/raid1.h
@@ -1,8 +1,6 @@
#ifndef _RAID1_H
#define _RAID1_H
-#include <linux/raid/md.h>
-
typedef struct mirror_info mirror_info_t;
struct mirror_info {
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 7301631abe0..e293d92641a 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -18,10 +18,13 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "dm-bio-list.h"
#include <linux/delay.h>
-#include <linux/raid/raid10.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "dm-bio-list.h"
+#include "raid10.h"
+#include "bitmap.h"
/*
* RAID10 provides a combination of RAID0 and RAID1 functionality.
@@ -1695,7 +1698,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
return 0;
skipped:
- max_sector = mddev->size << 1;
+ max_sector = mddev->dev_sectors;
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
max_sector = mddev->resync_max_sectors;
if (sector_nr >= max_sector) {
@@ -2020,6 +2023,25 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
goto skipped;
}
+static sector_t
+raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ sector_t size;
+ conf_t *conf = mddev_to_conf(mddev);
+
+ if (!raid_disks)
+ raid_disks = mddev->raid_disks;
+ if (!sectors)
+ sectors = mddev->dev_sectors;
+
+ size = sectors >> conf->chunk_shift;
+ sector_div(size, conf->far_copies);
+ size = size * raid_disks;
+ sector_div(size, conf->near_copies);
+
+ return size << conf->chunk_shift;
+}
+
static int run(mddev_t *mddev)
{
conf_t *conf;
@@ -2076,7 +2098,7 @@ static int run(mddev_t *mddev)
conf->far_offset = fo;
conf->chunk_mask = (sector_t)(mddev->chunk_size>>9)-1;
conf->chunk_shift = ffz(~mddev->chunk_size) - 9;
- size = mddev->size >> (conf->chunk_shift-1);
+ size = mddev->dev_sectors >> conf->chunk_shift;
sector_div(size, fc);
size = size * conf->raid_disks;
sector_div(size, nc);
@@ -2089,7 +2111,7 @@ static int run(mddev_t *mddev)
*/
stride += conf->raid_disks - 1;
sector_div(stride, conf->raid_disks);
- mddev->size = stride << (conf->chunk_shift-1);
+ mddev->dev_sectors = stride << conf->chunk_shift;
if (fo)
stride = 1;
@@ -2171,8 +2193,8 @@ static int run(mddev_t *mddev)
/*
* Ok, everything is just fine now
*/
- mddev->array_sectors = size << conf->chunk_shift;
- mddev->resync_max_sectors = size << conf->chunk_shift;
+ md_set_array_sectors(mddev, raid10_size(mddev, 0, 0));
+ mddev->resync_max_sectors = raid10_size(mddev, 0, 0);
mddev->queue->unplug_fn = raid10_unplug;
mddev->queue->backing_dev_info.congested_fn = raid10_congested;
@@ -2208,6 +2230,9 @@ static int stop(mddev_t *mddev)
{
conf_t *conf = mddev_to_conf(mddev);
+ raise_barrier(conf, 0);
+ lower_barrier(conf);
+
md_unregister_thread(mddev->thread);
mddev->thread = NULL;
blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
@@ -2255,6 +2280,7 @@ static struct mdk_personality raid10_personality =
.spare_active = raid10_spare_active,
.sync_request = sync_request,
.quiesce = raid10_quiesce,
+ .size = raid10_size,
};
static int __init raid_init(void)
diff --git a/include/linux/raid/raid10.h b/drivers/md/raid10.h
index e9091cfeb28..244dbe507a5 100644
--- a/include/linux/raid/raid10.h
+++ b/drivers/md/raid10.h
@@ -1,8 +1,6 @@
#ifndef _RAID10_H
#define _RAID10_H
-#include <linux/raid/md.h>
-
typedef struct mirror_info mirror_info_t;
struct mirror_info {
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index a5ba080d303..3bbc6d64704 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -43,11 +43,14 @@
* miss any bits.
*/
+#include <linux/blkdev.h>
#include <linux/kthread.h>
-#include "raid6.h"
-
-#include <linux/raid/bitmap.h>
+#include <linux/raid/pq.h>
#include <linux/async_tx.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "raid5.h"
+#include "bitmap.h"
/*
* Stripe cache
@@ -91,11 +94,6 @@
#define printk_rl(args...) ((void) (printk_ratelimit() && printk(args)))
-#if !RAID6_USE_EMPTY_ZERO_PAGE
-/* In .bss so it's zeroed */
-const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
-#endif
-
/*
* We maintain a biased count of active stripes in the bottom 16 bits of
* bi_phys_segments, and a count of processed stripes in the upper 16 bits
@@ -130,12 +128,42 @@ static inline void raid5_set_bi_hw_segments(struct bio *bio, unsigned int cnt)
bio->bi_phys_segments = raid5_bi_phys_segments(bio) || (cnt << 16);
}
+/* Find first data disk in a raid6 stripe */
+static inline int raid6_d0(struct stripe_head *sh)
+{
+ if (sh->ddf_layout)
+ /* ddf always start from first device */
+ return 0;
+ /* md starts just after Q block */
+ if (sh->qd_idx == sh->disks - 1)
+ return 0;
+ else
+ return sh->qd_idx + 1;
+}
static inline int raid6_next_disk(int disk, int raid_disks)
{
disk++;
return (disk < raid_disks) ? disk : 0;
}
+/* When walking through the disks in a raid5, starting at raid6_d0,
+ * We need to map each disk to a 'slot', where the data disks are slot
+ * 0 .. raid_disks-3, the parity disk is raid_disks-2 and the Q disk
+ * is raid_disks-1. This help does that mapping.
+ */
+static int raid6_idx_to_slot(int idx, struct stripe_head *sh,
+ int *count, int syndrome_disks)
+{
+ int slot;
+
+ if (idx == sh->pd_idx)
+ return syndrome_disks;
+ if (idx == sh->qd_idx)
+ return syndrome_disks + 1;
+ slot = (*count)++;
+ return slot;
+}
+
static void return_io(struct bio *return_bi)
{
struct bio *bi = return_bi;
@@ -193,6 +221,7 @@ static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh)
}
}
}
+
static void release_stripe(struct stripe_head *sh)
{
raid5_conf_t *conf = sh->raid_conf;
@@ -270,9 +299,11 @@ 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, int previous);
+static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous,
+ struct stripe_head *sh);
-static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks)
+static void init_stripe(struct stripe_head *sh, sector_t sector, int previous)
{
raid5_conf_t *conf = sh->raid_conf;
int i;
@@ -287,11 +318,12 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int
remove_hash(sh);
+ sh->generation = conf->generation - previous;
+ sh->disks = previous ? conf->previous_raid_disks : conf->raid_disks;
sh->sector = sector;
- sh->pd_idx = pd_idx;
+ stripe_set_idx(sector, conf, previous, sh);
sh->state = 0;
- sh->disks = disks;
for (i = sh->disks; i--; ) {
struct r5dev *dev = &sh->dev[i];
@@ -305,12 +337,13 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int
BUG();
}
dev->flags = 0;
- raid5_build_block(sh, i);
+ raid5_build_block(sh, i, previous);
}
insert_hash(conf, sh);
}
-static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, int disks)
+static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector,
+ short generation)
{
struct stripe_head *sh;
struct hlist_node *hn;
@@ -318,7 +351,7 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, in
CHECK_DEVLOCK();
pr_debug("__find_stripe, sector %llu\n", (unsigned long long)sector);
hlist_for_each_entry(sh, hn, stripe_hash(conf, sector), hash)
- if (sh->sector == sector && sh->disks == disks)
+ if (sh->sector == sector && sh->generation == generation)
return sh;
pr_debug("__stripe %llu not in cache\n", (unsigned long long)sector);
return NULL;
@@ -327,8 +360,9 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, in
static void unplug_slaves(mddev_t *mddev);
static void raid5_unplug_device(struct request_queue *q);
-static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector, int disks,
- int pd_idx, int noblock)
+static struct stripe_head *
+get_active_stripe(raid5_conf_t *conf, sector_t sector,
+ int previous, int noblock)
{
struct stripe_head *sh;
@@ -340,7 +374,7 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
wait_event_lock_irq(conf->wait_for_stripe,
conf->quiesce == 0,
conf->device_lock, /* nothing */);
- sh = __find_stripe(conf, sector, disks);
+ sh = __find_stripe(conf, sector, conf->generation - previous);
if (!sh) {
if (!conf->inactive_blocked)
sh = get_free_stripe(conf);
@@ -358,10 +392,11 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
);
conf->inactive_blocked = 0;
} else
- init_stripe(sh, sector, pd_idx, disks);
+ init_stripe(sh, sector, previous);
} else {
if (atomic_read(&sh->count)) {
- BUG_ON(!list_empty(&sh->lru));
+ BUG_ON(!list_empty(&sh->lru)
+ && !test_bit(STRIPE_EXPANDING, &sh->state));
} else {
if (!test_bit(STRIPE_HANDLE, &sh->state))
atomic_inc(&conf->active_stripes);
@@ -895,8 +930,10 @@ static int grow_stripes(raid5_conf_t *conf, int num)
struct kmem_cache *sc;
int devs = conf->raid_disks;
- sprintf(conf->cache_name[0], "raid5-%s", mdname(conf->mddev));
- sprintf(conf->cache_name[1], "raid5-%s-alt", mdname(conf->mddev));
+ sprintf(conf->cache_name[0],
+ "raid%d-%s", conf->level, mdname(conf->mddev));
+ sprintf(conf->cache_name[1],
+ "raid%d-%s-alt", conf->level, mdname(conf->mddev));
conf->active_name = 0;
sc = kmem_cache_create(conf->cache_name[conf->active_name],
sizeof(struct stripe_head)+(devs-1)*sizeof(struct r5dev),
@@ -911,7 +948,6 @@ static int grow_stripes(raid5_conf_t *conf, int num)
return 0;
}
-#ifdef CONFIG_MD_RAID5_RESHAPE
static int resize_stripes(raid5_conf_t *conf, int newsize)
{
/* Make all the stripes able to hold 'newsize' devices.
@@ -1036,7 +1072,6 @@ static int resize_stripes(raid5_conf_t *conf, int newsize)
conf->pool_size = newsize;
return err;
}
-#endif
static int drop_one_stripe(raid5_conf_t *conf)
{
@@ -1066,7 +1101,7 @@ static void shrink_stripes(raid5_conf_t *conf)
static void raid5_end_read_request(struct bio * bi, int error)
{
- struct stripe_head *sh = bi->bi_private;
+ struct stripe_head *sh = bi->bi_private;
raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks, i;
int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1148,7 +1183,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
static void raid5_end_write_request(struct bio *bi, int error)
{
- struct stripe_head *sh = bi->bi_private;
+ struct stripe_head *sh = bi->bi_private;
raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks, i;
int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1176,9 +1211,9 @@ static void raid5_end_write_request(struct bio *bi, int error)
}
-static sector_t compute_blocknr(struct stripe_head *sh, int i);
+static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous);
-static void raid5_build_block(struct stripe_head *sh, int i)
+static void raid5_build_block(struct stripe_head *sh, int i, int previous)
{
struct r5dev *dev = &sh->dev[i];
@@ -1194,7 +1229,7 @@ static void raid5_build_block(struct stripe_head *sh, int i)
dev->req.bi_private = sh;
dev->flags = 0;
- dev->sector = compute_blocknr(sh, i);
+ dev->sector = compute_blocknr(sh, i, previous);
}
static void error(mddev_t *mddev, mdk_rdev_t *rdev)
@@ -1227,15 +1262,23 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
* Input: a 'big' sector number,
* Output: index of the data and parity disk, and the sector # in them.
*/
-static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
- unsigned int data_disks, unsigned int * dd_idx,
- unsigned int * pd_idx, raid5_conf_t *conf)
+static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
+ int previous, int *dd_idx,
+ struct stripe_head *sh)
{
long stripe;
unsigned long chunk_number;
unsigned int chunk_offset;
+ int pd_idx, qd_idx;
+ int ddf_layout = 0;
sector_t new_sector;
- int sectors_per_chunk = conf->chunk_size >> 9;
+ int algorithm = previous ? conf->prev_algo
+ : conf->algorithm;
+ int sectors_per_chunk = previous ? (conf->prev_chunk >> 9)
+ : (conf->chunk_size >> 9);
+ int raid_disks = previous ? conf->previous_raid_disks
+ : conf->raid_disks;
+ int data_disks = raid_disks - conf->max_degraded;
/* First compute the information on this sector */
@@ -1259,68 +1302,170 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
/*
* Select the parity disk based on the user selected algorithm.
*/
+ pd_idx = qd_idx = ~0;
switch(conf->level) {
case 4:
- *pd_idx = data_disks;
+ pd_idx = data_disks;
break;
case 5:
- switch (conf->algorithm) {
+ switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
- *pd_idx = data_disks - stripe % raid_disks;
- if (*dd_idx >= *pd_idx)
+ pd_idx = data_disks - stripe % raid_disks;
+ if (*dd_idx >= pd_idx)
(*dd_idx)++;
break;
case ALGORITHM_RIGHT_ASYMMETRIC:
- *pd_idx = stripe % raid_disks;
- if (*dd_idx >= *pd_idx)
+ pd_idx = stripe % raid_disks;
+ if (*dd_idx >= pd_idx)
(*dd_idx)++;
break;
case ALGORITHM_LEFT_SYMMETRIC:
- *pd_idx = data_disks - stripe % raid_disks;
- *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
+ pd_idx = data_disks - stripe % raid_disks;
+ *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
break;
case ALGORITHM_RIGHT_SYMMETRIC:
- *pd_idx = stripe % raid_disks;
- *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
+ pd_idx = stripe % raid_disks;
+ *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
+ break;
+ case ALGORITHM_PARITY_0:
+ pd_idx = 0;
+ (*dd_idx)++;
+ break;
+ case ALGORITHM_PARITY_N:
+ pd_idx = data_disks;
break;
default:
printk(KERN_ERR "raid5: unsupported algorithm %d\n",
- conf->algorithm);
+ algorithm);
+ BUG();
}
break;
case 6:
- /**** FIX THIS ****/
- switch (conf->algorithm) {
+ switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
- *pd_idx = raid_disks - 1 - (stripe % raid_disks);
- if (*pd_idx == raid_disks-1)
- (*dd_idx)++; /* Q D D D P */
- else if (*dd_idx >= *pd_idx)
+ pd_idx = raid_disks - 1 - (stripe % raid_disks);
+ qd_idx = pd_idx + 1;
+ if (pd_idx == raid_disks-1) {
+ (*dd_idx)++; /* Q D D D P */
+ qd_idx = 0;
+ } else if (*dd_idx >= pd_idx)
(*dd_idx) += 2; /* D D P Q D */
break;
case ALGORITHM_RIGHT_ASYMMETRIC:
- *pd_idx = stripe % raid_disks;
- if (*pd_idx == raid_disks-1)
- (*dd_idx)++; /* Q D D D P */
- else if (*dd_idx >= *pd_idx)
+ pd_idx = stripe % raid_disks;
+ qd_idx = pd_idx + 1;
+ if (pd_idx == raid_disks-1) {
+ (*dd_idx)++; /* Q D D D P */
+ qd_idx = 0;
+ } else if (*dd_idx >= pd_idx)
(*dd_idx) += 2; /* D D P Q D */
break;
case ALGORITHM_LEFT_SYMMETRIC:
- *pd_idx = raid_disks - 1 - (stripe % raid_disks);
- *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
+ pd_idx = raid_disks - 1 - (stripe % raid_disks);
+ qd_idx = (pd_idx + 1) % raid_disks;
+ *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
break;
case ALGORITHM_RIGHT_SYMMETRIC:
- *pd_idx = stripe % raid_disks;
- *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
+ pd_idx = stripe % raid_disks;
+ qd_idx = (pd_idx + 1) % raid_disks;
+ *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
+ break;
+
+ case ALGORITHM_PARITY_0:
+ pd_idx = 0;
+ qd_idx = 1;
+ (*dd_idx) += 2;
+ break;
+ case ALGORITHM_PARITY_N:
+ pd_idx = data_disks;
+ qd_idx = data_disks + 1;
break;
+
+ case ALGORITHM_ROTATING_ZERO_RESTART:
+ /* Exactly the same as RIGHT_ASYMMETRIC, but or
+ * of blocks for computing Q is different.
+ */
+ pd_idx = stripe % raid_disks;
+ qd_idx = pd_idx + 1;
+ if (pd_idx == raid_disks-1) {
+ (*dd_idx)++; /* Q D D D P */
+ qd_idx = 0;
+ } else if (*dd_idx >= pd_idx)
+ (*dd_idx) += 2; /* D D P Q D */
+ ddf_layout = 1;
+ break;
+
+ case ALGORITHM_ROTATING_N_RESTART:
+ /* Same a left_asymmetric, by first stripe is
+ * D D D P Q rather than
+ * Q D D D P
+ */
+ pd_idx = raid_disks - 1 - ((stripe + 1) % raid_disks);
+ qd_idx = pd_idx + 1;
+ if (pd_idx == raid_disks-1) {
+ (*dd_idx)++; /* Q D D D P */
+ qd_idx = 0;
+ } else if (*dd_idx >= pd_idx)
+ (*dd_idx) += 2; /* D D P Q D */
+ ddf_layout = 1;
+ break;
+
+ case ALGORITHM_ROTATING_N_CONTINUE:
+ /* Same as left_symmetric but Q is before P */
+ pd_idx = raid_disks - 1 - (stripe % raid_disks);
+ qd_idx = (pd_idx + raid_disks - 1) % raid_disks;
+ *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
+ ddf_layout = 1;
+ break;
+
+ case ALGORITHM_LEFT_ASYMMETRIC_6:
+ /* RAID5 left_asymmetric, with Q on last device */
+ pd_idx = data_disks - stripe % (raid_disks-1);
+ if (*dd_idx >= pd_idx)
+ (*dd_idx)++;
+ qd_idx = raid_disks - 1;
+ break;
+
+ case ALGORITHM_RIGHT_ASYMMETRIC_6:
+ pd_idx = stripe % (raid_disks-1);
+ if (*dd_idx >= pd_idx)
+ (*dd_idx)++;
+ qd_idx = raid_disks - 1;
+ break;
+
+ case ALGORITHM_LEFT_SYMMETRIC_6:
+ pd_idx = data_disks - stripe % (raid_disks-1);
+ *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
+ qd_idx = raid_disks - 1;
+ break;
+
+ case ALGORITHM_RIGHT_SYMMETRIC_6:
+ pd_idx = stripe % (raid_disks-1);
+ *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
+ qd_idx = raid_disks - 1;
+ break;
+
+ case ALGORITHM_PARITY_0_6:
+ pd_idx = 0;
+ (*dd_idx)++;
+ qd_idx = raid_disks - 1;
+ break;
+
+
default:
printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
- conf->algorithm);
+ algorithm);
+ BUG();
}
break;
}
+ if (sh) {
+ sh->pd_idx = pd_idx;
+ sh->qd_idx = qd_idx;
+ sh->ddf_layout = ddf_layout;
+ }
/*
* Finally, compute the new sector number
*/
@@ -1329,17 +1474,21 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
}
-static sector_t compute_blocknr(struct stripe_head *sh, int i)
+static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
{
raid5_conf_t *conf = sh->raid_conf;
int raid_disks = sh->disks;
int data_disks = raid_disks - conf->max_degraded;
sector_t new_sector = sh->sector, check;
- int sectors_per_chunk = conf->chunk_size >> 9;
+ int sectors_per_chunk = previous ? (conf->prev_chunk >> 9)
+ : (conf->chunk_size >> 9);
+ int algorithm = previous ? conf->prev_algo
+ : conf->algorithm;
sector_t stripe;
int chunk_offset;
- int chunk_number, dummy1, dummy2, dd_idx = i;
+ int chunk_number, dummy1, dd_idx = i;
sector_t r_sector;
+ struct stripe_head sh2;
chunk_offset = sector_div(new_sector, sectors_per_chunk);
@@ -1351,7 +1500,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
switch(conf->level) {
case 4: break;
case 5:
- switch (conf->algorithm) {
+ switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
case ALGORITHM_RIGHT_ASYMMETRIC:
if (i > sh->pd_idx)
@@ -1363,19 +1512,27 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
i += raid_disks;
i -= (sh->pd_idx + 1);
break;
+ case ALGORITHM_PARITY_0:
+ i -= 1;
+ break;
+ case ALGORITHM_PARITY_N:
+ break;
default:
printk(KERN_ERR "raid5: unsupported algorithm %d\n",
- conf->algorithm);
+ algorithm);
+ BUG();
}
break;
case 6:
- if (i == raid6_next_disk(sh->pd_idx, raid_disks))
+ if (i == sh->qd_idx)
return 0; /* It is the Q disk */
- switch (conf->algorithm) {
+ switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
case ALGORITHM_RIGHT_ASYMMETRIC:
- if (sh->pd_idx == raid_disks-1)
- i--; /* Q D D D P */
+ case ALGORITHM_ROTATING_ZERO_RESTART:
+ case ALGORITHM_ROTATING_N_RESTART:
+ if (sh->pd_idx == raid_disks-1)
+ i--; /* Q D D D P */
else if (i > sh->pd_idx)
i -= 2; /* D D P Q D */
break;
@@ -1390,9 +1547,35 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
i -= (sh->pd_idx + 2);
}
break;
+ case ALGORITHM_PARITY_0:
+ i -= 2;
+ break;
+ case ALGORITHM_PARITY_N:
+ break;
+ case ALGORITHM_ROTATING_N_CONTINUE:
+ if (sh->pd_idx == 0)
+ i--; /* P D D D Q */
+ else if (i > sh->pd_idx)
+ i -= 2; /* D D Q P D */
+ break;
+ case ALGORITHM_LEFT_ASYMMETRIC_6:
+ case ALGORITHM_RIGHT_ASYMMETRIC_6:
+ if (i > sh->pd_idx)
+ i--;
+ break;
+ case ALGORITHM_LEFT_SYMMETRIC_6:
+ case ALGORITHM_RIGHT_SYMMETRIC_6:
+ if (i < sh->pd_idx)
+ i += data_disks + 1;
+ i -= (sh->pd_idx + 1);
+ break;
+ case ALGORITHM_PARITY_0_6:
+ i -= 1;
+ break;
default:
printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
- conf->algorithm);
+ algorithm);
+ BUG();
}
break;
}
@@ -1400,8 +1583,10 @@ 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);
- if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
+ check = raid5_compute_sector(conf, r_sector,
+ previous, &dummy1, &sh2);
+ if (check != sh->sector || dummy1 != dd_idx || sh2.pd_idx != sh->pd_idx
+ || sh2.qd_idx != sh->qd_idx) {
printk(KERN_ERR "compute_blocknr: map not correct\n");
return 0;
}
@@ -1468,14 +1653,16 @@ static void copy_data(int frombio, struct bio *bio,
static void compute_parity6(struct stripe_head *sh, int method)
{
- raid6_conf_t *conf = sh->raid_conf;
- int i, pd_idx = sh->pd_idx, qd_idx, d0_idx, disks = sh->disks, count;
+ raid5_conf_t *conf = sh->raid_conf;
+ int i, pd_idx, qd_idx, d0_idx, disks = sh->disks, count;
+ int syndrome_disks = sh->ddf_layout ? disks : (disks - 2);
struct bio *chosen;
/**** FIX THIS: This could be very bad if disks is close to 256 ****/
- void *ptrs[disks];
+ void *ptrs[syndrome_disks+2];
- qd_idx = raid6_next_disk(pd_idx, disks);
- d0_idx = raid6_next_disk(qd_idx, disks);
+ pd_idx = sh->pd_idx;
+ qd_idx = sh->qd_idx;
+ d0_idx = raid6_d0(sh);
pr_debug("compute_parity, stripe %llu, method %d\n",
(unsigned long long)sh->sector, method);
@@ -1513,24 +1700,29 @@ static void compute_parity6(struct stripe_head *sh, int method)
set_bit(R5_UPTODATE, &sh->dev[i].flags);
}
-// switch(method) {
-// case RECONSTRUCT_WRITE:
-// case CHECK_PARITY:
-// case UPDATE_PARITY:
- /* Note that unlike RAID-5, the ordering of the disks matters greatly. */
- /* FIX: Is this ordering of drives even remotely optimal? */
- count = 0;
- i = d0_idx;
- do {
- ptrs[count++] = page_address(sh->dev[i].page);
- if (count <= disks-2 && !test_bit(R5_UPTODATE, &sh->dev[i].flags))
- printk("block %d/%d not uptodate on parity calc\n", i,count);
- i = raid6_next_disk(i, disks);
- } while ( i != d0_idx );
-// break;
-// }
-
- raid6_call.gen_syndrome(disks, STRIPE_SIZE, ptrs);
+ /* Note that unlike RAID-5, the ordering of the disks matters greatly.*/
+
+ for (i = 0; i < disks; i++)
+ ptrs[i] = (void *)raid6_empty_zero_page;
+
+ count = 0;
+ i = d0_idx;
+ do {
+ int slot = raid6_idx_to_slot(i, sh, &count, syndrome_disks);
+
+ ptrs[slot] = page_address(sh->dev[i].page);
+ if (slot < syndrome_disks &&
+ !test_bit(R5_UPTODATE, &sh->dev[i].flags)) {
+ printk(KERN_ERR "block %d/%d not uptodate "
+ "on parity calc\n", i, count);
+ BUG();
+ }
+
+ i = raid6_next_disk(i, disks);
+ } while (i != d0_idx);
+ BUG_ON(count != syndrome_disks);
+
+ raid6_call.gen_syndrome(syndrome_disks+2, STRIPE_SIZE, ptrs);
switch(method) {
case RECONSTRUCT_WRITE:
@@ -1552,8 +1744,7 @@ static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero)
{
int i, count, disks = sh->disks;
void *ptr[MAX_XOR_BLOCKS], *dest, *p;
- int pd_idx = sh->pd_idx;
- int qd_idx = raid6_next_disk(pd_idx, disks);
+ int qd_idx = sh->qd_idx;
pr_debug("compute_block_1, stripe %llu, idx %d\n",
(unsigned long long)sh->sector, dd_idx);
@@ -1589,63 +1780,65 @@ static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero)
static void compute_block_2(struct stripe_head *sh, int dd_idx1, int dd_idx2)
{
int i, count, disks = sh->disks;
- int pd_idx = sh->pd_idx;
- int qd_idx = raid6_next_disk(pd_idx, disks);
- int d0_idx = raid6_next_disk(qd_idx, disks);
- int faila, failb;
+ int syndrome_disks = sh->ddf_layout ? disks : disks-2;
+ int d0_idx = raid6_d0(sh);
+ int faila = -1, failb = -1;
+ /**** FIX THIS: This could be very bad if disks is close to 256 ****/
+ void *ptrs[syndrome_disks+2];
- /* faila and failb are disk numbers relative to d0_idx */
- /* pd_idx become disks-2 and qd_idx become disks-1 */
- faila = (dd_idx1 < d0_idx) ? dd_idx1+(disks-d0_idx) : dd_idx1-d0_idx;
- failb = (dd_idx2 < d0_idx) ? dd_idx2+(disks-d0_idx) : dd_idx2-d0_idx;
+ for (i = 0; i < disks ; i++)
+ ptrs[i] = (void *)raid6_empty_zero_page;
+ count = 0;
+ i = d0_idx;
+ do {
+ int slot = raid6_idx_to_slot(i, sh, &count, syndrome_disks);
+
+ ptrs[slot] = page_address(sh->dev[i].page);
+
+ if (i == dd_idx1)
+ faila = slot;
+ if (i == dd_idx2)
+ failb = slot;
+ i = raid6_next_disk(i, disks);
+ } while (i != d0_idx);
+ BUG_ON(count != syndrome_disks);
BUG_ON(faila == failb);
if ( failb < faila ) { int tmp = faila; faila = failb; failb = tmp; }
pr_debug("compute_block_2, stripe %llu, idx %d,%d (%d,%d)\n",
- (unsigned long long)sh->sector, dd_idx1, dd_idx2, faila, failb);
+ (unsigned long long)sh->sector, dd_idx1, dd_idx2,
+ faila, failb);
- if ( failb == disks-1 ) {
+ if (failb == syndrome_disks+1) {
/* Q disk is one of the missing disks */
- if ( faila == disks-2 ) {
+ if (faila == syndrome_disks) {
/* Missing P+Q, just recompute */
compute_parity6(sh, UPDATE_PARITY);
return;
} else {
/* We're missing D+Q; recompute D from P */
- compute_block_1(sh, (dd_idx1 == qd_idx) ? dd_idx2 : dd_idx1, 0);
+ compute_block_1(sh, ((dd_idx1 == sh->qd_idx) ?
+ dd_idx2 : dd_idx1),
+ 0);
compute_parity6(sh, UPDATE_PARITY); /* Is this necessary? */
return;
}
}
- /* We're missing D+P or D+D; build pointer table */
- {
- /**** FIX THIS: This could be very bad if disks is close to 256 ****/
- void *ptrs[disks];
-
- count = 0;
- i = d0_idx;
- do {
- ptrs[count++] = page_address(sh->dev[i].page);
- i = raid6_next_disk(i, disks);
- if (i != dd_idx1 && i != dd_idx2 &&
- !test_bit(R5_UPTODATE, &sh->dev[i].flags))
- printk("compute_2 with missing block %d/%d\n", count, i);
- } while ( i != d0_idx );
-
- if ( failb == disks-2 ) {
- /* We're missing D+P. */
- raid6_datap_recov(disks, STRIPE_SIZE, faila, ptrs);
- } else {
- /* We're missing D+D. */
- raid6_2data_recov(disks, STRIPE_SIZE, faila, failb, ptrs);
- }
-
- /* Both the above update both missing blocks */
- set_bit(R5_UPTODATE, &sh->dev[dd_idx1].flags);
- set_bit(R5_UPTODATE, &sh->dev[dd_idx2].flags);
+ /* We're missing D+P or D+D; */
+ if (failb == syndrome_disks) {
+ /* We're missing D+P. */
+ raid6_datap_recov(syndrome_disks+2, STRIPE_SIZE, faila, ptrs);
+ } else {
+ /* We're missing D+D. */
+ raid6_2data_recov(syndrome_disks+2, STRIPE_SIZE, faila, failb,
+ ptrs);
}
+
+ /* Both the above update both missing blocks */
+ set_bit(R5_UPTODATE, &sh->dev[dd_idx1].flags);
+ set_bit(R5_UPTODATE, &sh->dev[dd_idx2].flags);
}
static void
@@ -1800,17 +1993,21 @@ static int page_is_zero(struct page *p)
memcmp(a, a+4, STRIPE_SIZE-4)==0);
}
-static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks)
+static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous,
+ struct stripe_head *sh)
{
- int sectors_per_chunk = conf->chunk_size >> 9;
- int pd_idx, dd_idx;
+ int sectors_per_chunk =
+ previous ? (conf->prev_chunk >> 9)
+ : (conf->chunk_size >> 9);
+ int dd_idx;
int chunk_offset = sector_div(stripe, sectors_per_chunk);
+ int disks = previous ? conf->previous_raid_disks : conf->raid_disks;
- raid5_compute_sector(stripe * (disks - conf->max_degraded)
+ raid5_compute_sector(conf,
+ stripe * (disks - conf->max_degraded)
*sectors_per_chunk + chunk_offset,
- disks, disks - conf->max_degraded,
- &dd_idx, &pd_idx, conf);
- return pd_idx;
+ previous,
+ &dd_idx, sh);
}
static void
@@ -2181,7 +2378,7 @@ static void handle_stripe_dirtying6(raid5_conf_t *conf,
struct r6_state *r6s, int disks)
{
int rcw = 0, must_compute = 0, pd_idx = sh->pd_idx, i;
- int qd_idx = r6s->qd_idx;
+ int qd_idx = sh->qd_idx;
for (i = disks; i--; ) {
struct r5dev *dev = &sh->dev[i];
/* Would I have to read this buffer for reconstruct_write */
@@ -2371,7 +2568,7 @@ static void handle_parity_checks6(raid5_conf_t *conf, struct stripe_head *sh,
int update_p = 0, update_q = 0;
struct r5dev *dev;
int pd_idx = sh->pd_idx;
- int qd_idx = r6s->qd_idx;
+ int qd_idx = sh->qd_idx;
set_bit(STRIPE_HANDLE, &sh->state);
@@ -2467,17 +2664,14 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
struct dma_async_tx_descriptor *tx = NULL;
clear_bit(STRIPE_EXPAND_SOURCE, &sh->state);
for (i = 0; i < sh->disks; i++)
- if (i != sh->pd_idx && (!r6s || i != r6s->qd_idx)) {
- int dd_idx, pd_idx, j;
+ if (i != sh->pd_idx && i != sh->qd_idx) {
+ int dd_idx, j;
struct stripe_head *sh2;
- sector_t bn = compute_blocknr(sh, i);
- sector_t s = raid5_compute_sector(bn, conf->raid_disks,
- conf->raid_disks -
- conf->max_degraded, &dd_idx,
- &pd_idx, conf);
- sh2 = get_active_stripe(conf, s, conf->raid_disks,
- pd_idx, 1);
+ sector_t bn = compute_blocknr(sh, i, 1);
+ sector_t s = raid5_compute_sector(conf, bn, 0,
+ &dd_idx, NULL);
+ sh2 = get_active_stripe(conf, s, 0, 1);
if (sh2 == NULL)
/* so far only the early blocks of this stripe
* have been requested. When later blocks
@@ -2500,8 +2694,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
set_bit(R5_UPTODATE, &sh2->dev[dd_idx].flags);
for (j = 0; j < conf->raid_disks; j++)
if (j != sh2->pd_idx &&
- (!r6s || j != raid6_next_disk(sh2->pd_idx,
- sh2->disks)) &&
+ (!r6s || j != sh2->qd_idx) &&
!test_bit(R5_Expanded, &sh2->dev[j].flags))
break;
if (j == conf->raid_disks) {
@@ -2750,6 +2943,23 @@ static bool handle_stripe5(struct stripe_head *sh)
/* Finish reconstruct operations initiated by the expansion process */
if (sh->reconstruct_state == reconstruct_state_result) {
+ struct stripe_head *sh2
+ = get_active_stripe(conf, sh->sector, 1, 1);
+ if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
+ /* sh cannot be written until sh2 has been read.
+ * so arrange for sh to be delayed a little
+ */
+ set_bit(STRIPE_DELAYED, &sh->state);
+ set_bit(STRIPE_HANDLE, &sh->state);
+ if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE,
+ &sh2->state))
+ atomic_inc(&conf->preread_active_stripes);
+ release_stripe(sh2);
+ goto unlock;
+ }
+ if (sh2)
+ release_stripe(sh2);
+
sh->reconstruct_state = reconstruct_state_idle;
clear_bit(STRIPE_EXPANDING, &sh->state);
for (i = conf->raid_disks; i--; ) {
@@ -2763,8 +2973,7 @@ static bool handle_stripe5(struct stripe_head *sh)
!sh->reconstruct_state) {
/* Need to write out all blocks after computing parity */
sh->disks = conf->raid_disks;
- sh->pd_idx = stripe_to_pdidx(sh->sector, conf,
- conf->raid_disks);
+ stripe_set_idx(sh->sector, conf, 0, sh);
schedule_reconstruction5(sh, &s, 1, 1);
} else if (s.expanded && !sh->reconstruct_state && s.locked == 0) {
clear_bit(STRIPE_EXPAND_READY, &sh->state);
@@ -2796,20 +3005,19 @@ static bool handle_stripe5(struct stripe_head *sh)
static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
{
- raid6_conf_t *conf = sh->raid_conf;
+ raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks;
struct bio *return_bi = NULL;
- int i, pd_idx = sh->pd_idx;
+ int i, pd_idx = sh->pd_idx, qd_idx = sh->qd_idx;
struct stripe_head_state s;
struct r6_state r6s;
struct r5dev *dev, *pdev, *qdev;
mdk_rdev_t *blocked_rdev = NULL;
- r6s.qd_idx = raid6_next_disk(pd_idx, disks);
pr_debug("handling stripe %llu, state=%#lx cnt=%d, "
"pd_idx=%d, qd_idx=%d\n",
(unsigned long long)sh->sector, sh->state,
- atomic_read(&sh->count), pd_idx, r6s.qd_idx);
+ atomic_read(&sh->count), pd_idx, qd_idx);
memset(&s, 0, sizeof(s));
spin_lock(&sh->lock);
@@ -2920,9 +3128,9 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
pdev = &sh->dev[pd_idx];
r6s.p_failed = (s.failed >= 1 && r6s.failed_num[0] == pd_idx)
|| (s.failed >= 2 && r6s.failed_num[1] == pd_idx);
- qdev = &sh->dev[r6s.qd_idx];
- r6s.q_failed = (s.failed >= 1 && r6s.failed_num[0] == r6s.qd_idx)
- || (s.failed >= 2 && r6s.failed_num[1] == r6s.qd_idx);
+ qdev = &sh->dev[qd_idx];
+ r6s.q_failed = (s.failed >= 1 && r6s.failed_num[0] == qd_idx)
+ || (s.failed >= 2 && r6s.failed_num[1] == qd_idx);
if ( s.written &&
( r6s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
@@ -2980,10 +3188,26 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
}
if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state)) {
+ struct stripe_head *sh2
+ = get_active_stripe(conf, sh->sector, 1, 1);
+ if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
+ /* sh cannot be written until sh2 has been read.
+ * so arrange for sh to be delayed a little
+ */
+ set_bit(STRIPE_DELAYED, &sh->state);
+ set_bit(STRIPE_HANDLE, &sh->state);
+ if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE,
+ &sh2->state))
+ atomic_inc(&conf->preread_active_stripes);
+ release_stripe(sh2);
+ goto unlock;
+ }
+ if (sh2)
+ release_stripe(sh2);
+
/* Need to write out all blocks after computing P&Q */
sh->disks = conf->raid_disks;
- sh->pd_idx = stripe_to_pdidx(sh->sector, conf,
- conf->raid_disks);
+ stripe_set_idx(sh->sector, conf, 0, sh);
compute_parity6(sh, RECONSTRUCT_WRITE);
for (i = conf->raid_disks ; i-- ; ) {
set_bit(R5_LOCKED, &sh->dev[i].flags);
@@ -3134,6 +3358,8 @@ static int raid5_mergeable_bvec(struct request_queue *q,
if ((bvm->bi_rw & 1) == WRITE)
return biovec->bv_len; /* always allow writes to be mergeable */
+ if (mddev->new_chunk < mddev->chunk_size)
+ chunk_sectors = mddev->new_chunk >> 9;
max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9;
if (max < 0) max = 0;
if (max <= biovec->bv_len && bio_sectors == 0)
@@ -3149,6 +3375,8 @@ static int in_chunk_boundary(mddev_t *mddev, struct bio *bio)
unsigned int chunk_sectors = mddev->chunk_size >> 9;
unsigned int bio_sectors = bio->bi_size >> 9;
+ if (mddev->new_chunk < mddev->chunk_size)
+ chunk_sectors = mddev->new_chunk >> 9;
return chunk_sectors >=
((sector & (chunk_sectors - 1)) + bio_sectors);
}
@@ -3255,9 +3483,7 @@ static int chunk_aligned_read(struct request_queue *q, struct bio * raid_bio)
{
mddev_t *mddev = q->queuedata;
raid5_conf_t *conf = mddev_to_conf(mddev);
- const unsigned int raid_disks = conf->raid_disks;
- const unsigned int data_disks = raid_disks - conf->max_degraded;
- unsigned int dd_idx, pd_idx;
+ unsigned int dd_idx;
struct bio* align_bi;
mdk_rdev_t *rdev;
@@ -3266,7 +3492,7 @@ static int chunk_aligned_read(struct request_queue *q, struct bio * raid_bio)
return 0;
}
/*
- * use bio_clone to make a copy of the bio
+ * use bio_clone to make a copy of the bio
*/
align_bi = bio_clone(raid_bio, GFP_NOIO);
if (!align_bi)
@@ -3280,12 +3506,9 @@ static int chunk_aligned_read(struct request_queue *q, struct bio * raid_bio)
/*
* compute position
*/
- align_bi->bi_sector = raid5_compute_sector(raid_bio->bi_sector,
- raid_disks,
- data_disks,
- &dd_idx,
- &pd_idx,
- conf);
+ align_bi->bi_sector = raid5_compute_sector(conf, raid_bio->bi_sector,
+ 0,
+ &dd_idx, NULL);
rcu_read_lock();
rdev = rcu_dereference(conf->disks[dd_idx].rdev);
@@ -3377,7 +3600,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
{
mddev_t *mddev = q->queuedata;
raid5_conf_t *conf = mddev_to_conf(mddev);
- unsigned int dd_idx, pd_idx;
+ int dd_idx;
sector_t new_sector;
sector_t logical_sector, last_sector;
struct stripe_head *sh;
@@ -3400,7 +3623,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
if (rw == READ &&
mddev->reshape_position == MaxSector &&
chunk_aligned_read(q,bi))
- return 0;
+ return 0;
logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
last_sector = bi->bi_sector + (bi->bi_size>>9);
@@ -3410,26 +3633,31 @@ static int make_request(struct request_queue *q, struct bio * bi)
for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
DEFINE_WAIT(w);
int disks, data_disks;
+ int previous;
retry:
+ previous = 0;
+ disks = conf->raid_disks;
prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE);
- if (likely(conf->expand_progress == MaxSector))
- disks = conf->raid_disks;
- else {
- /* spinlock is needed as expand_progress may be
+ if (unlikely(conf->reshape_progress != MaxSector)) {
+ /* spinlock is needed as reshape_progress may be
* 64bit on a 32bit platform, and so it might be
* possible to see a half-updated value
- * Ofcourse expand_progress could change after
+ * Ofcourse reshape_progress could change after
* the lock is dropped, so once we get a reference
* to the stripe that we think it is, we will have
* to check again.
*/
spin_lock_irq(&conf->device_lock);
- disks = conf->raid_disks;
- if (logical_sector >= conf->expand_progress)
+ if (mddev->delta_disks < 0
+ ? logical_sector < conf->reshape_progress
+ : logical_sector >= conf->reshape_progress) {
disks = conf->previous_raid_disks;
- else {
- if (logical_sector >= conf->expand_lo) {
+ previous = 1;
+ } else {
+ if (mddev->delta_disks < 0
+ ? logical_sector < conf->reshape_safe
+ : logical_sector >= conf->reshape_safe) {
spin_unlock_irq(&conf->device_lock);
schedule();
goto retry;
@@ -3439,15 +3667,17 @@ static int make_request(struct request_queue *q, struct bio * bi)
}
data_disks = disks - conf->max_degraded;
- new_sector = raid5_compute_sector(logical_sector, disks, data_disks,
- &dd_idx, &pd_idx, conf);
+ new_sector = raid5_compute_sector(conf, logical_sector,
+ previous,
+ &dd_idx, NULL);
pr_debug("raid5: make_request, sector %llu logical %llu\n",
(unsigned long long)new_sector,
(unsigned long long)logical_sector);
- sh = get_active_stripe(conf, new_sector, disks, pd_idx, (bi->bi_rw&RWA_MASK));
+ sh = get_active_stripe(conf, new_sector, previous,
+ (bi->bi_rw&RWA_MASK));
if (sh) {
- if (unlikely(conf->expand_progress != MaxSector)) {
+ if (unlikely(previous)) {
/* expansion might have moved on while waiting for a
* stripe, so we must do the range check again.
* Expansion could still move past after this
@@ -3458,8 +3688,9 @@ static int make_request(struct request_queue *q, struct bio * bi)
*/
int must_retry = 0;
spin_lock_irq(&conf->device_lock);
- if (logical_sector < conf->expand_progress &&
- disks == conf->previous_raid_disks)
+ if (mddev->delta_disks < 0
+ ? logical_sector >= conf->reshape_progress
+ : logical_sector < conf->reshape_progress)
/* mismatch, need to try again */
must_retry = 1;
spin_unlock_irq(&conf->device_lock);
@@ -3514,6 +3745,8 @@ static int make_request(struct request_queue *q, struct bio * bi)
return 0;
}
+static sector_t raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks);
+
static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped)
{
/* reshaping is quite different to recovery/resync so it is
@@ -3527,61 +3760,118 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
*/
raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
struct stripe_head *sh;
- int pd_idx;
sector_t first_sector, last_sector;
int raid_disks = conf->previous_raid_disks;
int data_disks = raid_disks - conf->max_degraded;
int new_data_disks = conf->raid_disks - conf->max_degraded;
int i;
int dd_idx;
- sector_t writepos, safepos, gap;
-
- if (sector_nr == 0 &&
- conf->expand_progress != 0) {
- /* restarting in the middle, skip the initial sectors */
- sector_nr = conf->expand_progress;
+ sector_t writepos, readpos, safepos;
+ sector_t stripe_addr;
+ int reshape_sectors;
+ struct list_head stripes;
+
+ if (sector_nr == 0) {
+ /* If restarting in the middle, skip the initial sectors */
+ if (mddev->delta_disks < 0 &&
+ conf->reshape_progress < raid5_size(mddev, 0, 0)) {
+ sector_nr = raid5_size(mddev, 0, 0)
+ - conf->reshape_progress;
+ } else if (mddev->delta_disks > 0 &&
+ conf->reshape_progress > 0)
+ sector_nr = conf->reshape_progress;
sector_div(sector_nr, new_data_disks);
- *skipped = 1;
- return sector_nr;
+ if (sector_nr) {
+ *skipped = 1;
+ return sector_nr;
+ }
}
+ /* We need to process a full chunk at a time.
+ * If old and new chunk sizes differ, we need to process the
+ * largest of these
+ */
+ if (mddev->new_chunk > mddev->chunk_size)
+ reshape_sectors = mddev->new_chunk / 512;
+ else
+ reshape_sectors = mddev->chunk_size / 512;
+
/* we update the metadata when there is more than 3Meg
* in the block range (that is rather arbitrary, should
* probably be time based) or when the data about to be
* copied would over-write the source of the data at
* the front of the range.
- * i.e. one new_stripe forward from expand_progress new_maps
- * to after where expand_lo old_maps to
+ * i.e. one new_stripe along from reshape_progress new_maps
+ * to after where reshape_safe old_maps to
*/
- writepos = conf->expand_progress +
- conf->chunk_size/512*(new_data_disks);
+ writepos = conf->reshape_progress;
sector_div(writepos, new_data_disks);
- safepos = conf->expand_lo;
+ readpos = conf->reshape_progress;
+ sector_div(readpos, data_disks);
+ safepos = conf->reshape_safe;
sector_div(safepos, data_disks);
- gap = conf->expand_progress - conf->expand_lo;
+ if (mddev->delta_disks < 0) {
+ writepos -= reshape_sectors;
+ readpos += reshape_sectors;
+ safepos += reshape_sectors;
+ } else {
+ writepos += reshape_sectors;
+ readpos -= reshape_sectors;
+ safepos -= reshape_sectors;
+ }
- if (writepos >= safepos ||
- gap > (new_data_disks)*3000*2 /*3Meg*/) {
+ /* 'writepos' is the most advanced device address we might write.
+ * 'readpos' is the least advanced device address we might read.
+ * 'safepos' is the least address recorded in the metadata as having
+ * been reshaped.
+ * If 'readpos' is behind 'writepos', then there is no way that we can
+ * ensure safety in the face of a crash - that must be done by userspace
+ * making a backup of the data. So in that case there is no particular
+ * rush to update metadata.
+ * Otherwise if 'safepos' is behind 'writepos', then we really need to
+ * update the metadata to advance 'safepos' to match 'readpos' so that
+ * we can be safe in the event of a crash.
+ * So we insist on updating metadata if safepos is behind writepos and
+ * readpos is beyond writepos.
+ * In any case, update the metadata every 10 seconds.
+ * Maybe that number should be configurable, but I'm not sure it is
+ * worth it.... maybe it could be a multiple of safemode_delay???
+ */
+ if ((mddev->delta_disks < 0
+ ? (safepos > writepos && readpos < writepos)
+ : (safepos < writepos && readpos > writepos)) ||
+ time_after(jiffies, conf->reshape_checkpoint + 10*HZ)) {
/* Cannot proceed until we've updated the superblock... */
wait_event(conf->wait_for_overlap,
atomic_read(&conf->reshape_stripes)==0);
- mddev->reshape_position = conf->expand_progress;
+ mddev->reshape_position = conf->reshape_progress;
+ conf->reshape_checkpoint = jiffies;
set_bit(MD_CHANGE_DEVS, &mddev->flags);
md_wakeup_thread(mddev->thread);
wait_event(mddev->sb_wait, mddev->flags == 0 ||
kthread_should_stop());
spin_lock_irq(&conf->device_lock);
- conf->expand_lo = mddev->reshape_position;
+ conf->reshape_safe = mddev->reshape_position;
spin_unlock_irq(&conf->device_lock);
wake_up(&conf->wait_for_overlap);
}
- for (i=0; i < conf->chunk_size/512; i+= STRIPE_SECTORS) {
+ if (mddev->delta_disks < 0) {
+ BUG_ON(conf->reshape_progress == 0);
+ stripe_addr = writepos;
+ BUG_ON((mddev->dev_sectors &
+ ~((sector_t)reshape_sectors - 1))
+ - reshape_sectors - stripe_addr
+ != sector_nr);
+ } else {
+ BUG_ON(writepos != sector_nr + reshape_sectors);
+ stripe_addr = sector_nr;
+ }
+ INIT_LIST_HEAD(&stripes);
+ for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) {
int j;
int skipped = 0;
- pd_idx = stripe_to_pdidx(sector_nr+i, conf, conf->raid_disks);
- sh = get_active_stripe(conf, sector_nr+i,
- conf->raid_disks, pd_idx, 0);
+ sh = get_active_stripe(conf, stripe_addr+i, 0, 0);
set_bit(STRIPE_EXPANDING, &sh->state);
atomic_inc(&conf->reshape_stripes);
/* If any of this stripe is beyond the end of the old
@@ -3592,10 +3882,10 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
if (j == sh->pd_idx)
continue;
if (conf->level == 6 &&
- j == raid6_next_disk(sh->pd_idx, sh->disks))
+ j == sh->qd_idx)
continue;
- s = compute_blocknr(sh, j);
- if (s < mddev->array_sectors) {
+ s = compute_blocknr(sh, j, 0);
+ if (s < raid5_size(mddev, 0, 0)) {
skipped = 1;
continue;
}
@@ -3607,10 +3897,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
set_bit(STRIPE_EXPAND_READY, &sh->state);
set_bit(STRIPE_HANDLE, &sh->state);
}
- release_stripe(sh);
+ list_add(&sh->lru, &stripes);
}
spin_lock_irq(&conf->device_lock);
- conf->expand_progress = (sector_nr + i) * new_data_disks;
+ if (mddev->delta_disks < 0)
+ conf->reshape_progress -= reshape_sectors * new_data_disks;
+ else
+ conf->reshape_progress += reshape_sectors * new_data_disks;
spin_unlock_irq(&conf->device_lock);
/* Ok, those stripe are ready. We can start scheduling
* reads on the source stripes.
@@ -3618,46 +3911,50 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
* block on the destination stripes.
*/
first_sector =
- raid5_compute_sector(sector_nr*(new_data_disks),
- raid_disks, data_disks,
- &dd_idx, &pd_idx, conf);
+ raid5_compute_sector(conf, stripe_addr*(new_data_disks),
+ 1, &dd_idx, NULL);
last_sector =
- raid5_compute_sector((sector_nr+conf->chunk_size/512)
- *(new_data_disks) -1,
- raid_disks, data_disks,
- &dd_idx, &pd_idx, conf);
- if (last_sector >= (mddev->size<<1))
- last_sector = (mddev->size<<1)-1;
+ raid5_compute_sector(conf, ((stripe_addr+conf->chunk_size/512)
+ *(new_data_disks) - 1),
+ 1, &dd_idx, NULL);
+ if (last_sector >= mddev->dev_sectors)
+ last_sector = mddev->dev_sectors - 1;
while (first_sector <= last_sector) {
- pd_idx = stripe_to_pdidx(first_sector, conf,
- conf->previous_raid_disks);
- sh = get_active_stripe(conf, first_sector,
- conf->previous_raid_disks, pd_idx, 0);
+ sh = get_active_stripe(conf, first_sector, 1, 0);
set_bit(STRIPE_EXPAND_SOURCE, &sh->state);
set_bit(STRIPE_HANDLE, &sh->state);
release_stripe(sh);
first_sector += STRIPE_SECTORS;
}
+ /* Now that the sources are clearly marked, we can release
+ * the destination stripes
+ */
+ while (!list_empty(&stripes)) {
+ sh = list_entry(stripes.next, struct stripe_head, lru);
+ list_del_init(&sh->lru);
+ release_stripe(sh);
+ }
/* If this takes us to the resync_max point where we have to pause,
* then we need to write out the superblock.
*/
- sector_nr += conf->chunk_size>>9;
+ sector_nr += reshape_sectors;
if (sector_nr >= mddev->resync_max) {
/* Cannot proceed until we've updated the superblock... */
wait_event(conf->wait_for_overlap,
atomic_read(&conf->reshape_stripes) == 0);
- mddev->reshape_position = conf->expand_progress;
+ mddev->reshape_position = conf->reshape_progress;
+ conf->reshape_checkpoint = jiffies;
set_bit(MD_CHANGE_DEVS, &mddev->flags);
md_wakeup_thread(mddev->thread);
wait_event(mddev->sb_wait,
!test_bit(MD_CHANGE_DEVS, &mddev->flags)
|| kthread_should_stop());
spin_lock_irq(&conf->device_lock);
- conf->expand_lo = mddev->reshape_position;
+ conf->reshape_safe = mddev->reshape_position;
spin_unlock_irq(&conf->device_lock);
wake_up(&conf->wait_for_overlap);
}
- return conf->chunk_size>>9;
+ return reshape_sectors;
}
/* FIXME go_faster isn't used */
@@ -3665,9 +3962,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
{
raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
struct stripe_head *sh;
- int pd_idx;
- int raid_disks = conf->raid_disks;
- sector_t max_sector = mddev->size << 1;
+ sector_t max_sector = mddev->dev_sectors;
int sync_blocks;
int still_degraded = 0;
int i;
@@ -3675,6 +3970,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
if (sector_nr >= max_sector) {
/* just being told to finish up .. nothing much to do */
unplug_slaves(mddev);
+
if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) {
end_reshape(conf);
return 0;
@@ -3705,7 +4001,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
*/
if (mddev->degraded >= conf->max_degraded &&
test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
- sector_t rv = (mddev->size << 1) - sector_nr;
+ sector_t rv = mddev->dev_sectors - sector_nr;
*skipped = 1;
return rv;
}
@@ -3721,10 +4017,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
bitmap_cond_end_sync(mddev->bitmap, sector_nr);
- pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks);
- sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1);
+ sh = get_active_stripe(conf, sector_nr, 0, 1);
if (sh == NULL) {
- sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 0);
+ sh = get_active_stripe(conf, sector_nr, 0, 0);
/* make sure we don't swamp the stripe cache if someone else
* is trying to get access
*/
@@ -3766,19 +4061,15 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
* it will be only one 'dd_idx' and only need one call to raid5_compute_sector.
*/
struct stripe_head *sh;
- int dd_idx, pd_idx;
+ int dd_idx;
sector_t sector, logical_sector, last_sector;
int scnt = 0;
int remaining;
int handled = 0;
logical_sector = raid_bio->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
- sector = raid5_compute_sector( logical_sector,
- conf->raid_disks,
- conf->raid_disks - conf->max_degraded,
- &dd_idx,
- &pd_idx,
- conf);
+ sector = raid5_compute_sector(conf, logical_sector,
+ 0, &dd_idx, NULL);
last_sector = raid_bio->bi_sector + (raid_bio->bi_size>>9);
for (; logical_sector < last_sector;
@@ -3790,7 +4081,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
/* already done this stripe */
continue;
- sh = get_active_stripe(conf, sector, conf->raid_disks, pd_idx, 1);
+ sh = get_active_stripe(conf, sector, 0, 1);
if (!sh) {
/* failed to get a stripe - must wait */
@@ -3992,89 +4283,69 @@ static struct attribute_group raid5_attrs_group = {
.attrs = raid5_attrs,
};
-static int run(mddev_t *mddev)
+static sector_t
+raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+
+ if (!sectors)
+ sectors = mddev->dev_sectors;
+ if (!raid_disks) {
+ /* size is defined by the smallest of previous and new size */
+ if (conf->raid_disks < conf->previous_raid_disks)
+ raid_disks = conf->raid_disks;
+ else
+ raid_disks = conf->previous_raid_disks;
+ }
+
+ sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
+ sectors &= ~((sector_t)mddev->new_chunk/512 - 1);
+ return sectors * (raid_disks - conf->max_degraded);
+}
+
+static raid5_conf_t *setup_conf(mddev_t *mddev)
{
raid5_conf_t *conf;
int raid_disk, memory;
mdk_rdev_t *rdev;
struct disk_info *disk;
- int working_disks = 0;
- if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) {
+ if (mddev->new_level != 5
+ && mddev->new_level != 4
+ && mddev->new_level != 6) {
printk(KERN_ERR "raid5: %s: raid level not set to 4/5/6 (%d)\n",
- mdname(mddev), mddev->level);
- return -EIO;
+ mdname(mddev), mddev->new_level);
+ return ERR_PTR(-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->new_level == 5
+ && !algorithm_valid_raid5(mddev->new_layout)) ||
+ (mddev->new_level == 6
+ && !algorithm_valid_raid6(mddev->new_layout))) {
+ printk(KERN_ERR "raid5: %s: layout %d not supported\n",
+ mdname(mddev), mddev->new_layout);
+ return ERR_PTR(-EIO);
}
-
- if (mddev->reshape_position != MaxSector) {
- /* Check that we can continue the reshape.
- * Currently only disks can change, it must
- * increase, and we must be past the point where
- * a stripe over-writes itself
- */
- sector_t here_new, here_old;
- int old_disks;
- int max_degraded = (mddev->level == 5 ? 1 : 2);
-
- if (mddev->new_level != mddev->level ||
- mddev->new_layout != mddev->layout ||
- mddev->new_chunk != mddev->chunk_size) {
- printk(KERN_ERR "raid5: %s: unsupported reshape "
- "required - aborting.\n",
- mdname(mddev));
- return -EINVAL;
- }
- if (mddev->delta_disks <= 0) {
- printk(KERN_ERR "raid5: %s: unsupported reshape "
- "(reduce disks) required - aborting.\n",
- mdname(mddev));
- return -EINVAL;
- }
- old_disks = mddev->raid_disks - mddev->delta_disks;
- /* reshape_position must be on a new-stripe boundary, and one
- * further up in new geometry must map after here in old
- * geometry.
- */
- here_new = mddev->reshape_position;
- if (sector_div(here_new, (mddev->chunk_size>>9)*
- (mddev->raid_disks - max_degraded))) {
- printk(KERN_ERR "raid5: reshape_position not "
- "on a stripe boundary\n");
- return -EINVAL;
- }
- /* here_new is the stripe we will write to */
- here_old = mddev->reshape_position;
- sector_div(here_old, (mddev->chunk_size>>9)*
- (old_disks-max_degraded));
- /* here_old is the first stripe that we might need to read
- * from */
- if (here_new >= here_old) {
- /* Reading from the same stripe as writing to - bad */
- printk(KERN_ERR "raid5: reshape_position too early for "
- "auto-recovery - aborting.\n");
- return -EINVAL;
- }
- printk(KERN_INFO "raid5: reshape will continue\n");
- /* OK, we should be able to continue; */
+ if (mddev->new_level == 6 && mddev->raid_disks < 4) {
+ printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n",
+ mdname(mddev), mddev->raid_disks);
+ return ERR_PTR(-EINVAL);
}
+ if (!mddev->new_chunk || mddev->new_chunk % PAGE_SIZE) {
+ printk(KERN_ERR "raid5: invalid chunk size %d for %s\n",
+ mddev->new_chunk, mdname(mddev));
+ return ERR_PTR(-EINVAL);
+ }
- mddev->private = kzalloc(sizeof (raid5_conf_t), GFP_KERNEL);
- if ((conf = mddev->private) == NULL)
+ conf = kzalloc(sizeof(raid5_conf_t), GFP_KERNEL);
+ if (conf == NULL)
goto abort;
- if (mddev->reshape_position == MaxSector) {
- conf->previous_raid_disks = conf->raid_disks = mddev->raid_disks;
- } else {
- conf->raid_disks = mddev->raid_disks;
+
+ conf->raid_disks = mddev->raid_disks;
+ if (mddev->reshape_position == MaxSector)
+ conf->previous_raid_disks = mddev->raid_disks;
+ else
conf->previous_raid_disks = mddev->raid_disks - mddev->delta_disks;
- }
conf->disks = kzalloc(conf->raid_disks * sizeof(struct disk_info),
GFP_KERNEL);
@@ -4086,13 +4357,12 @@ static int run(mddev_t *mddev)
if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL)
goto abort;
- if (mddev->level == 6) {
+ if (mddev->new_level == 6) {
conf->spare_page = alloc_page(GFP_KERNEL);
if (!conf->spare_page)
goto abort;
}
spin_lock_init(&conf->device_lock);
- mddev->queue->queue_lock = &conf->device_lock;
init_waitqueue_head(&conf->wait_for_stripe);
init_waitqueue_head(&conf->wait_for_overlap);
INIT_LIST_HEAD(&conf->handle_list);
@@ -4121,47 +4391,134 @@ static int run(mddev_t *mddev)
printk(KERN_INFO "raid5: device %s operational as raid"
" disk %d\n", bdevname(rdev->bdev,b),
raid_disk);
- working_disks++;
} else
/* Cannot rely on bitmap to complete recovery */
conf->fullsync = 1;
}
- /*
- * 0 for a fully functional array, 1 or 2 for a degraded array.
- */
- mddev->degraded = conf->raid_disks - working_disks;
- conf->mddev = mddev;
- conf->chunk_size = mddev->chunk_size;
- conf->level = mddev->level;
+ conf->chunk_size = mddev->new_chunk;
+ conf->level = mddev->new_level;
if (conf->level == 6)
conf->max_degraded = 2;
else
conf->max_degraded = 1;
- conf->algorithm = mddev->layout;
+ conf->algorithm = mddev->new_layout;
conf->max_nr_stripes = NR_STRIPES;
- conf->expand_progress = mddev->reshape_position;
-
- /* device size must be a multiple of chunk size */
- mddev->size &= ~(mddev->chunk_size/1024 -1);
- mddev->resync_max_sectors = mddev->size << 1;
+ conf->reshape_progress = mddev->reshape_position;
+ if (conf->reshape_progress != MaxSector) {
+ conf->prev_chunk = mddev->chunk_size;
+ conf->prev_algo = mddev->layout;
+ }
- if (conf->level == 6 && conf->raid_disks < 4) {
- printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n",
- mdname(mddev), conf->raid_disks);
+ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
+ conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
+ if (grow_stripes(conf, conf->max_nr_stripes)) {
+ printk(KERN_ERR
+ "raid5: couldn't allocate %dkB for buffers\n", memory);
goto abort;
- }
- if (!conf->chunk_size || conf->chunk_size % 4) {
- printk(KERN_ERR "raid5: invalid chunk size %d for %s\n",
- conf->chunk_size, mdname(mddev));
+ } else
+ printk(KERN_INFO "raid5: allocated %dkB for %s\n",
+ memory, mdname(mddev));
+
+ conf->thread = md_register_thread(raid5d, mddev, "%s_raid5");
+ if (!conf->thread) {
+ printk(KERN_ERR
+ "raid5: couldn't allocate thread for %s\n",
+ mdname(mddev));
goto abort;
}
- if (conf->algorithm > ALGORITHM_RIGHT_SYMMETRIC) {
- printk(KERN_ERR
- "raid5: unsupported parity algorithm %d for %s\n",
- conf->algorithm, mdname(mddev));
- goto abort;
+
+ return conf;
+
+ abort:
+ if (conf) {
+ shrink_stripes(conf);
+ safe_put_page(conf->spare_page);
+ kfree(conf->disks);
+ kfree(conf->stripe_hashtbl);
+ kfree(conf);
+ return ERR_PTR(-EIO);
+ } else
+ return ERR_PTR(-ENOMEM);
+}
+
+static int run(mddev_t *mddev)
+{
+ raid5_conf_t *conf;
+ int working_disks = 0;
+ mdk_rdev_t *rdev;
+
+ if (mddev->reshape_position != MaxSector) {
+ /* Check that we can continue the reshape.
+ * Currently only disks can change, it must
+ * increase, and we must be past the point where
+ * a stripe over-writes itself
+ */
+ sector_t here_new, here_old;
+ int old_disks;
+ int max_degraded = (mddev->level == 6 ? 2 : 1);
+
+ if (mddev->new_level != mddev->level) {
+ printk(KERN_ERR "raid5: %s: unsupported reshape "
+ "required - aborting.\n",
+ mdname(mddev));
+ return -EINVAL;
+ }
+ old_disks = mddev->raid_disks - mddev->delta_disks;
+ /* reshape_position must be on a new-stripe boundary, and one
+ * further up in new geometry must map after here in old
+ * geometry.
+ */
+ here_new = mddev->reshape_position;
+ if (sector_div(here_new, (mddev->new_chunk>>9)*
+ (mddev->raid_disks - max_degraded))) {
+ printk(KERN_ERR "raid5: reshape_position not "
+ "on a stripe boundary\n");
+ return -EINVAL;
+ }
+ /* here_new is the stripe we will write to */
+ here_old = mddev->reshape_position;
+ sector_div(here_old, (mddev->chunk_size>>9)*
+ (old_disks-max_degraded));
+ /* here_old is the first stripe that we might need to read
+ * from */
+ if (here_new >= here_old) {
+ /* Reading from the same stripe as writing to - bad */
+ printk(KERN_ERR "raid5: reshape_position too early for "
+ "auto-recovery - aborting.\n");
+ return -EINVAL;
+ }
+ printk(KERN_INFO "raid5: reshape will continue\n");
+ /* OK, we should be able to continue; */
+ } else {
+ BUG_ON(mddev->level != mddev->new_level);
+ BUG_ON(mddev->layout != mddev->new_layout);
+ BUG_ON(mddev->chunk_size != mddev->new_chunk);
+ BUG_ON(mddev->delta_disks != 0);
}
+
+ if (mddev->private == NULL)
+ conf = setup_conf(mddev);
+ else
+ conf = mddev->private;
+
+ if (IS_ERR(conf))
+ return PTR_ERR(conf);
+
+ mddev->thread = conf->thread;
+ conf->thread = NULL;
+ mddev->private = conf;
+
+ /*
+ * 0 for a fully functional array, 1 or 2 for a degraded array.
+ */
+ list_for_each_entry(rdev, &mddev->disks, same_set)
+ if (rdev->raid_disk >= 0 &&
+ test_bit(In_sync, &rdev->flags))
+ working_disks++;
+
+ mddev->degraded = conf->raid_disks - working_disks;
+
if (mddev->degraded > conf->max_degraded) {
printk(KERN_ERR "raid5: not enough operational devices for %s"
" (%d/%d failed)\n",
@@ -4169,6 +4526,10 @@ static int run(mddev_t *mddev)
goto abort;
}
+ /* device size must be a multiple of chunk size */
+ mddev->dev_sectors &= ~(mddev->chunk_size / 512 - 1);
+ mddev->resync_max_sectors = mddev->dev_sectors;
+
if (mddev->degraded > 0 &&
mddev->recovery_cp != MaxSector) {
if (mddev->ok_start_degraded)
@@ -4184,43 +4545,22 @@ static int run(mddev_t *mddev)
}
}
- {
- mddev->thread = md_register_thread(raid5d, mddev, "%s_raid5");
- if (!mddev->thread) {
- printk(KERN_ERR
- "raid5: couldn't allocate thread for %s\n",
- mdname(mddev));
- goto abort;
- }
- }
- memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
- conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
- if (grow_stripes(conf, conf->max_nr_stripes)) {
- printk(KERN_ERR
- "raid5: couldn't allocate %dkB for buffers\n", memory);
- shrink_stripes(conf);
- md_unregister_thread(mddev->thread);
- goto abort;
- } else
- printk(KERN_INFO "raid5: allocated %dkB for %s\n",
- memory, mdname(mddev));
-
if (mddev->degraded == 0)
printk("raid5: raid level %d set %s active with %d out of %d"
- " devices, algorithm %d\n", conf->level, mdname(mddev),
- mddev->raid_disks-mddev->degraded, mddev->raid_disks,
- conf->algorithm);
+ " devices, algorithm %d\n", conf->level, mdname(mddev),
+ mddev->raid_disks-mddev->degraded, mddev->raid_disks,
+ mddev->new_layout);
else
printk(KERN_ALERT "raid5: raid level %d set %s active with %d"
" out of %d devices, algorithm %d\n", conf->level,
mdname(mddev), mddev->raid_disks - mddev->degraded,
- mddev->raid_disks, conf->algorithm);
+ mddev->raid_disks, mddev->new_layout);
print_raid5_conf(conf);
- if (conf->expand_progress != MaxSector) {
+ if (conf->reshape_progress != MaxSector) {
printk("...ok start reshape thread\n");
- conf->expand_lo = conf->expand_progress;
+ conf->reshape_safe = conf->reshape_progress;
atomic_set(&conf->reshape_stripes, 0);
clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
@@ -4247,18 +4587,22 @@ static int run(mddev_t *mddev)
"raid5: failed to create sysfs attributes for %s\n",
mdname(mddev));
+ mddev->queue->queue_lock = &conf->device_lock;
+
mddev->queue->unplug_fn = raid5_unplug_device;
mddev->queue->backing_dev_info.congested_data = mddev;
mddev->queue->backing_dev_info.congested_fn = raid5_congested;
- mddev->array_sectors = 2 * mddev->size * (conf->previous_raid_disks -
- conf->max_degraded);
+ md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));
blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec);
return 0;
abort:
+ md_unregister_thread(mddev->thread);
+ mddev->thread = NULL;
if (conf) {
+ shrink_stripes(conf);
print_raid5_conf(conf);
safe_put_page(conf->spare_page);
kfree(conf->disks);
@@ -4396,6 +4740,10 @@ static int raid5_remove_disk(mddev_t *mddev, int number)
print_raid5_conf(conf);
rdev = p->rdev;
if (rdev) {
+ if (number >= conf->raid_disks &&
+ conf->reshape_progress == MaxSector)
+ clear_bit(In_sync, &rdev->flags);
+
if (test_bit(In_sync, &rdev->flags) ||
atomic_read(&rdev->nr_pending)) {
err = -EBUSY;
@@ -4405,7 +4753,8 @@ static int raid5_remove_disk(mddev_t *mddev, int number)
* isn't possible.
*/
if (!test_bit(Faulty, &rdev->flags) &&
- mddev->degraded <= conf->max_degraded) {
+ mddev->degraded <= conf->max_degraded &&
+ number < conf->raid_disks) {
err = -EBUSY;
goto abort;
}
@@ -4472,36 +4821,48 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors)
* any io in the removed space completes, but it hardly seems
* worth it.
*/
- raid5_conf_t *conf = mddev_to_conf(mddev);
-
sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
- mddev->array_sectors = sectors * (mddev->raid_disks
- - conf->max_degraded);
+ md_set_array_sectors(mddev, raid5_size(mddev, sectors,
+ mddev->raid_disks));
+ if (mddev->array_sectors >
+ raid5_size(mddev, sectors, mddev->raid_disks))
+ return -EINVAL;
set_capacity(mddev->gendisk, mddev->array_sectors);
mddev->changed = 1;
- if (sectors/2 > mddev->size && mddev->recovery_cp == MaxSector) {
- mddev->recovery_cp = mddev->size << 1;
+ if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) {
+ mddev->recovery_cp = mddev->dev_sectors;
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
}
- mddev->size = sectors /2;
+ mddev->dev_sectors = sectors;
mddev->resync_max_sectors = sectors;
return 0;
}
-#ifdef CONFIG_MD_RAID5_RESHAPE
static int raid5_check_reshape(mddev_t *mddev)
{
raid5_conf_t *conf = mddev_to_conf(mddev);
- int err;
- if (mddev->delta_disks < 0 ||
- mddev->new_level != mddev->level)
- return -EINVAL; /* Cannot shrink array or change level yet */
- if (mddev->delta_disks == 0)
- return 0; /* nothing to do */
+ if (mddev->delta_disks == 0 &&
+ mddev->new_layout == mddev->layout &&
+ mddev->new_chunk == mddev->chunk_size)
+ return -EINVAL; /* nothing to do */
if (mddev->bitmap)
/* Cannot grow a bitmap yet */
return -EBUSY;
+ if (mddev->degraded > conf->max_degraded)
+ return -EINVAL;
+ if (mddev->delta_disks < 0) {
+ /* We might be able to shrink, but the devices must
+ * be made bigger first.
+ * For raid6, 4 is the minimum size.
+ * Otherwise 2 is the minimum
+ */
+ int min = 2;
+ if (mddev->level == 6)
+ min = 4;
+ if (mddev->raid_disks + mddev->delta_disks < min)
+ return -EINVAL;
+ }
/* Can only proceed if there are plenty of stripe_heads.
* We need a minimum of one full stripe,, and for sensible progress
@@ -4514,18 +4875,12 @@ static int raid5_check_reshape(mddev_t *mddev)
if ((mddev->chunk_size / STRIPE_SIZE) * 4 > conf->max_nr_stripes ||
(mddev->new_chunk / STRIPE_SIZE) * 4 > conf->max_nr_stripes) {
printk(KERN_WARNING "raid5: reshape: not enough stripes. Needed %lu\n",
- (mddev->chunk_size / STRIPE_SIZE)*4);
+ (max(mddev->chunk_size, mddev->new_chunk)
+ / STRIPE_SIZE)*4);
return -ENOSPC;
}
- err = resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
- if (err)
- return err;
-
- if (mddev->degraded > conf->max_degraded)
- return -EINVAL;
- /* looks like we might be able to manage this */
- return 0;
+ return resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
}
static int raid5_start_reshape(mddev_t *mddev)
@@ -4550,12 +4905,31 @@ static int raid5_start_reshape(mddev_t *mddev)
*/
return -EINVAL;
+ /* Refuse to reduce size of the array. Any reductions in
+ * array size must be through explicit setting of array_size
+ * attribute.
+ */
+ if (raid5_size(mddev, 0, conf->raid_disks + mddev->delta_disks)
+ < mddev->array_sectors) {
+ printk(KERN_ERR "md: %s: array size must be reduced "
+ "before number of disks\n", mdname(mddev));
+ return -EINVAL;
+ }
+
atomic_set(&conf->reshape_stripes, 0);
spin_lock_irq(&conf->device_lock);
conf->previous_raid_disks = conf->raid_disks;
conf->raid_disks += mddev->delta_disks;
- conf->expand_progress = 0;
- conf->expand_lo = 0;
+ conf->prev_chunk = conf->chunk_size;
+ conf->chunk_size = mddev->new_chunk;
+ conf->prev_algo = conf->algorithm;
+ conf->algorithm = mddev->new_layout;
+ if (mddev->delta_disks < 0)
+ conf->reshape_progress = raid5_size(mddev, 0, 0);
+ else
+ conf->reshape_progress = 0;
+ conf->reshape_safe = conf->reshape_progress;
+ conf->generation++;
spin_unlock_irq(&conf->device_lock);
/* Add some new drives, as many as will fit.
@@ -4580,9 +4954,12 @@ static int raid5_start_reshape(mddev_t *mddev)
break;
}
- spin_lock_irqsave(&conf->device_lock, flags);
- mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices;
- spin_unlock_irqrestore(&conf->device_lock, flags);
+ if (mddev->delta_disks > 0) {
+ spin_lock_irqsave(&conf->device_lock, flags);
+ mddev->degraded = (conf->raid_disks - conf->previous_raid_disks)
+ - added_devices;
+ spin_unlock_irqrestore(&conf->device_lock, flags);
+ }
mddev->raid_disks = conf->raid_disks;
mddev->reshape_position = 0;
set_bit(MD_CHANGE_DEVS, &mddev->flags);
@@ -4597,52 +4974,86 @@ static int raid5_start_reshape(mddev_t *mddev)
mddev->recovery = 0;
spin_lock_irq(&conf->device_lock);
mddev->raid_disks = conf->raid_disks = conf->previous_raid_disks;
- conf->expand_progress = MaxSector;
+ conf->reshape_progress = MaxSector;
spin_unlock_irq(&conf->device_lock);
return -EAGAIN;
}
+ conf->reshape_checkpoint = jiffies;
md_wakeup_thread(mddev->sync_thread);
md_new_event(mddev);
return 0;
}
-#endif
+/* This is called from the reshape thread and should make any
+ * changes needed in 'conf'
+ */
static void end_reshape(raid5_conf_t *conf)
{
- struct block_device *bdev;
if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
- conf->mddev->array_sectors = 2 * conf->mddev->size *
- (conf->raid_disks - conf->max_degraded);
- set_capacity(conf->mddev->gendisk, conf->mddev->array_sectors);
- conf->mddev->changed = 1;
-
- bdev = bdget_disk(conf->mddev->gendisk, 0);
- if (bdev) {
- mutex_lock(&bdev->bd_inode->i_mutex);
- i_size_write(bdev->bd_inode,
- (loff_t)conf->mddev->array_sectors << 9);
- mutex_unlock(&bdev->bd_inode->i_mutex);
- bdput(bdev);
- }
+
spin_lock_irq(&conf->device_lock);
- conf->expand_progress = MaxSector;
+ conf->previous_raid_disks = conf->raid_disks;
+ conf->reshape_progress = MaxSector;
spin_unlock_irq(&conf->device_lock);
- conf->mddev->reshape_position = MaxSector;
+ wake_up(&conf->wait_for_overlap);
/* read-ahead size must cover two whole stripes, which is
* 2 * (datadisks) * chunksize where 'n' is the number of raid devices
*/
{
- int data_disks = conf->previous_raid_disks - conf->max_degraded;
- int stripe = data_disks *
- (conf->mddev->chunk_size / PAGE_SIZE);
+ int data_disks = conf->raid_disks - conf->max_degraded;
+ int stripe = data_disks * (conf->chunk_size
+ / PAGE_SIZE);
if (conf->mddev->queue->backing_dev_info.ra_pages < 2 * stripe)
conf->mddev->queue->backing_dev_info.ra_pages = 2 * stripe;
}
}
}
+/* This is called from the raid5d thread with mddev_lock held.
+ * It makes config changes to the device.
+ */
+static void raid5_finish_reshape(mddev_t *mddev)
+{
+ struct block_device *bdev;
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+
+ if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
+
+ if (mddev->delta_disks > 0) {
+ md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));
+ set_capacity(mddev->gendisk, mddev->array_sectors);
+ mddev->changed = 1;
+
+ bdev = bdget_disk(mddev->gendisk, 0);
+ if (bdev) {
+ mutex_lock(&bdev->bd_inode->i_mutex);
+ i_size_write(bdev->bd_inode,
+ (loff_t)mddev->array_sectors << 9);
+ mutex_unlock(&bdev->bd_inode->i_mutex);
+ bdput(bdev);
+ }
+ } else {
+ int d;
+ mddev->degraded = conf->raid_disks;
+ for (d = 0; d < conf->raid_disks ; d++)
+ if (conf->disks[d].rdev &&
+ test_bit(In_sync,
+ &conf->disks[d].rdev->flags))
+ mddev->degraded--;
+ for (d = conf->raid_disks ;
+ d < conf->raid_disks - mddev->delta_disks;
+ d++)
+ raid5_remove_disk(mddev, d);
+ }
+ mddev->layout = conf->algorithm;
+ mddev->chunk_size = conf->chunk_size;
+ mddev->reshape_position = MaxSector;
+ mddev->delta_disks = 0;
+ }
+}
+
static void raid5_quiesce(mddev_t *mddev, int state)
{
raid5_conf_t *conf = mddev_to_conf(mddev);
@@ -4672,6 +5083,212 @@ static void raid5_quiesce(mddev_t *mddev, int state)
}
}
+
+static void *raid5_takeover_raid1(mddev_t *mddev)
+{
+ int chunksect;
+
+ if (mddev->raid_disks != 2 ||
+ mddev->degraded > 1)
+ return ERR_PTR(-EINVAL);
+
+ /* Should check if there are write-behind devices? */
+
+ chunksect = 64*2; /* 64K by default */
+
+ /* The array must be an exact multiple of chunksize */
+ while (chunksect && (mddev->array_sectors & (chunksect-1)))
+ chunksect >>= 1;
+
+ if ((chunksect<<9) < STRIPE_SIZE)
+ /* array size does not allow a suitable chunk size */
+ return ERR_PTR(-EINVAL);
+
+ mddev->new_level = 5;
+ mddev->new_layout = ALGORITHM_LEFT_SYMMETRIC;
+ mddev->new_chunk = chunksect << 9;
+
+ return setup_conf(mddev);
+}
+
+static void *raid5_takeover_raid6(mddev_t *mddev)
+{
+ int new_layout;
+
+ switch (mddev->layout) {
+ case ALGORITHM_LEFT_ASYMMETRIC_6:
+ new_layout = ALGORITHM_LEFT_ASYMMETRIC;
+ break;
+ case ALGORITHM_RIGHT_ASYMMETRIC_6:
+ new_layout = ALGORITHM_RIGHT_ASYMMETRIC;
+ break;
+ case ALGORITHM_LEFT_SYMMETRIC_6:
+ new_layout = ALGORITHM_LEFT_SYMMETRIC;
+ break;
+ case ALGORITHM_RIGHT_SYMMETRIC_6:
+ new_layout = ALGORITHM_RIGHT_SYMMETRIC;
+ break;
+ case ALGORITHM_PARITY_0_6:
+ new_layout = ALGORITHM_PARITY_0;
+ break;
+ case ALGORITHM_PARITY_N:
+ new_layout = ALGORITHM_PARITY_N;
+ break;
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+ mddev->new_level = 5;
+ mddev->new_layout = new_layout;
+ mddev->delta_disks = -1;
+ mddev->raid_disks -= 1;
+ return setup_conf(mddev);
+}
+
+
+static int raid5_reconfig(mddev_t *mddev, int new_layout, int new_chunk)
+{
+ /* For a 2-drive array, the layout and chunk size can be changed
+ * immediately as not restriping is needed.
+ * For larger arrays we record the new value - after validation
+ * to be used by a reshape pass.
+ */
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+
+ if (new_layout >= 0 && !algorithm_valid_raid5(new_layout))
+ return -EINVAL;
+ if (new_chunk > 0) {
+ if (new_chunk & (new_chunk-1))
+ /* not a power of 2 */
+ return -EINVAL;
+ if (new_chunk < PAGE_SIZE)
+ return -EINVAL;
+ if (mddev->array_sectors & ((new_chunk>>9)-1))
+ /* not factor of array size */
+ return -EINVAL;
+ }
+
+ /* They look valid */
+
+ if (mddev->raid_disks == 2) {
+
+ if (new_layout >= 0) {
+ conf->algorithm = new_layout;
+ mddev->layout = mddev->new_layout = new_layout;
+ }
+ if (new_chunk > 0) {
+ conf->chunk_size = new_chunk;
+ mddev->chunk_size = mddev->new_chunk = new_chunk;
+ }
+ set_bit(MD_CHANGE_DEVS, &mddev->flags);
+ md_wakeup_thread(mddev->thread);
+ } else {
+ if (new_layout >= 0)
+ mddev->new_layout = new_layout;
+ if (new_chunk > 0)
+ mddev->new_chunk = new_chunk;
+ }
+ return 0;
+}
+
+static int raid6_reconfig(mddev_t *mddev, int new_layout, int new_chunk)
+{
+ if (new_layout >= 0 && !algorithm_valid_raid6(new_layout))
+ return -EINVAL;
+ if (new_chunk > 0) {
+ if (new_chunk & (new_chunk-1))
+ /* not a power of 2 */
+ return -EINVAL;
+ if (new_chunk < PAGE_SIZE)
+ return -EINVAL;
+ if (mddev->array_sectors & ((new_chunk>>9)-1))
+ /* not factor of array size */
+ return -EINVAL;
+ }
+
+ /* They look valid */
+
+ if (new_layout >= 0)
+ mddev->new_layout = new_layout;
+ if (new_chunk > 0)
+ mddev->new_chunk = new_chunk;
+
+ return 0;
+}
+
+static void *raid5_takeover(mddev_t *mddev)
+{
+ /* raid5 can take over:
+ * raid0 - if all devices are the same - make it a raid4 layout
+ * raid1 - if there are two drives. We need to know the chunk size
+ * raid4 - trivial - just use a raid4 layout.
+ * raid6 - Providing it is a *_6 layout
+ *
+ * For now, just do raid1
+ */
+
+ if (mddev->level == 1)
+ return raid5_takeover_raid1(mddev);
+ if (mddev->level == 4) {
+ mddev->new_layout = ALGORITHM_PARITY_N;
+ mddev->new_level = 5;
+ return setup_conf(mddev);
+ }
+ if (mddev->level == 6)
+ return raid5_takeover_raid6(mddev);
+
+ return ERR_PTR(-EINVAL);
+}
+
+
+static struct mdk_personality raid5_personality;
+
+static void *raid6_takeover(mddev_t *mddev)
+{
+ /* Currently can only take over a raid5. We map the
+ * personality to an equivalent raid6 personality
+ * with the Q block at the end.
+ */
+ int new_layout;
+
+ if (mddev->pers != &raid5_personality)
+ return ERR_PTR(-EINVAL);
+ if (mddev->degraded > 1)
+ return ERR_PTR(-EINVAL);
+ if (mddev->raid_disks > 253)
+ return ERR_PTR(-EINVAL);
+ if (mddev->raid_disks < 3)
+ return ERR_PTR(-EINVAL);
+
+ switch (mddev->layout) {
+ case ALGORITHM_LEFT_ASYMMETRIC:
+ new_layout = ALGORITHM_LEFT_ASYMMETRIC_6;
+ break;
+ case ALGORITHM_RIGHT_ASYMMETRIC:
+ new_layout = ALGORITHM_RIGHT_ASYMMETRIC_6;
+ break;
+ case ALGORITHM_LEFT_SYMMETRIC:
+ new_layout = ALGORITHM_LEFT_SYMMETRIC_6;
+ break;
+ case ALGORITHM_RIGHT_SYMMETRIC:
+ new_layout = ALGORITHM_RIGHT_SYMMETRIC_6;
+ break;
+ case ALGORITHM_PARITY_0:
+ new_layout = ALGORITHM_PARITY_0_6;
+ break;
+ case ALGORITHM_PARITY_N:
+ new_layout = ALGORITHM_PARITY_N;
+ break;
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+ mddev->new_level = 6;
+ mddev->new_layout = new_layout;
+ mddev->delta_disks = 1;
+ mddev->raid_disks += 1;
+ return setup_conf(mddev);
+}
+
+
static struct mdk_personality raid6_personality =
{
.name = "raid6",
@@ -4687,11 +5304,13 @@ static struct mdk_personality raid6_personality =
.spare_active = raid5_spare_active,
.sync_request = sync_request,
.resize = raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+ .size = raid5_size,
.check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape,
-#endif
+ .finish_reshape = raid5_finish_reshape,
.quiesce = raid5_quiesce,
+ .takeover = raid6_takeover,
+ .reconfig = raid6_reconfig,
};
static struct mdk_personality raid5_personality =
{
@@ -4708,11 +5327,13 @@ static struct mdk_personality raid5_personality =
.spare_active = raid5_spare_active,
.sync_request = sync_request,
.resize = raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+ .size = raid5_size,
.check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape,
-#endif
+ .finish_reshape = raid5_finish_reshape,
.quiesce = raid5_quiesce,
+ .takeover = raid5_takeover,
+ .reconfig = raid5_reconfig,
};
static struct mdk_personality raid4_personality =
@@ -4730,20 +5351,15 @@ static struct mdk_personality raid4_personality =
.spare_active = raid5_spare_active,
.sync_request = sync_request,
.resize = raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+ .size = raid5_size,
.check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape,
-#endif
+ .finish_reshape = raid5_finish_reshape,
.quiesce = raid5_quiesce,
};
static int __init raid5_init(void)
{
- int e;
-
- e = raid6_select_algo();
- if ( e )
- return e;
register_md_personality(&raid6_personality);
register_md_personality(&raid5_personality);
register_md_personality(&raid4_personality);
diff --git a/include/linux/raid/raid5.h b/drivers/md/raid5.h
index 3b267279245..52ba99954de 100644
--- a/include/linux/raid/raid5.h
+++ b/drivers/md/raid5.h
@@ -1,7 +1,6 @@
#ifndef _RAID5_H
#define _RAID5_H
-#include <linux/raid/md.h>
#include <linux/raid/xor.h>
/*
@@ -197,15 +196,19 @@ enum reconstruct_states {
struct stripe_head {
struct hlist_node hash;
- struct list_head lru; /* inactive_list or handle_list */
- struct raid5_private_data *raid_conf;
- sector_t sector; /* sector of this row */
- int pd_idx; /* parity disk index */
- unsigned long state; /* state flags */
- atomic_t count; /* nr of active thread/requests */
+ struct list_head lru; /* inactive_list or handle_list */
+ struct raid5_private_data *raid_conf;
+ short generation; /* increments with every
+ * reshape */
+ sector_t sector; /* sector of this row */
+ short pd_idx; /* parity disk index */
+ short qd_idx; /* 'Q' disk index for raid6 */
+ short ddf_layout;/* use DDF ordering to calculate Q */
+ unsigned long state; /* state flags */
+ atomic_t count; /* nr of active thread/requests */
spinlock_t lock;
int bm_seq; /* sequence number for bitmap flushes */
- int disks; /* disks in stripe */
+ int disks; /* disks in stripe */
enum check_states check_state;
enum reconstruct_states reconstruct_state;
/* stripe_operations
@@ -238,7 +241,7 @@ struct stripe_head_state {
/* r6_state - extra state data only relevant to r6 */
struct r6_state {
- int p_failed, q_failed, qd_idx, failed_num[2];
+ int p_failed, q_failed, failed_num[2];
};
/* Flags */
@@ -268,6 +271,8 @@ struct r6_state {
#define READ_MODIFY_WRITE 2
/* not a write method, but a compute_parity mode */
#define CHECK_PARITY 3
+/* Additional compute_parity mode -- updates the parity w/o LOCKING */
+#define UPDATE_PARITY 4
/*
* Stripe state
@@ -319,7 +324,7 @@ struct r6_state {
* PREREAD_ACTIVE is set, else we set DELAYED which will send it to the delayed queue.
* HANDLE gets cleared if stripe_handle leave nothing locked.
*/
-
+
struct disk_info {
mdk_rdev_t *rdev;
@@ -334,12 +339,21 @@ struct raid5_private_data {
int raid_disks;
int max_nr_stripes;
- /* used during an expand */
- sector_t expand_progress; /* MaxSector when no expand happening */
- sector_t expand_lo; /* from here up to expand_progress it out-of-bounds
- * as we haven't flushed the metadata yet
- */
+ /* reshape_progress is the leading edge of a 'reshape'
+ * It has value MaxSector when no reshape is happening
+ * If delta_disks < 0, it is the last sector we started work on,
+ * else is it the next sector to work on.
+ */
+ sector_t reshape_progress;
+ /* reshape_safe is the trailing edge of a reshape. We know that
+ * before (or after) this address, all reshape has completed.
+ */
+ sector_t reshape_safe;
int previous_raid_disks;
+ int prev_chunk, prev_algo;
+ short generation; /* increments with every reshape */
+ unsigned long reshape_checkpoint; /* Time we last updated
+ * metadata */
struct list_head handle_list; /* stripes needing handling */
struct list_head hold_list; /* preread ready stripes */
@@ -385,6 +399,11 @@ struct raid5_private_data {
int pool_size; /* number of disks in stripeheads in pool */
spinlock_t device_lock;
struct disk_info *disks;
+
+ /* When taking over an array from a different personality, we store
+ * the new thread here until we fully activate the array.
+ */
+ struct mdk_thread_s *thread;
};
typedef struct raid5_private_data raid5_conf_t;
@@ -394,9 +413,62 @@ typedef struct raid5_private_data raid5_conf_t;
/*
* Our supported algorithms
*/
-#define ALGORITHM_LEFT_ASYMMETRIC 0
-#define ALGORITHM_RIGHT_ASYMMETRIC 1
-#define ALGORITHM_LEFT_SYMMETRIC 2
-#define ALGORITHM_RIGHT_SYMMETRIC 3
+#define ALGORITHM_LEFT_ASYMMETRIC 0 /* Rotating Parity N with Data Restart */
+#define ALGORITHM_RIGHT_ASYMMETRIC 1 /* Rotating Parity 0 with Data Restart */
+#define ALGORITHM_LEFT_SYMMETRIC 2 /* Rotating Parity N with Data Continuation */
+#define ALGORITHM_RIGHT_SYMMETRIC 3 /* Rotating Parity 0 with Data Continuation */
+
+/* Define non-rotating (raid4) algorithms. These allow
+ * conversion of raid4 to raid5.
+ */
+#define ALGORITHM_PARITY_0 4 /* P or P,Q are initial devices */
+#define ALGORITHM_PARITY_N 5 /* P or P,Q are final devices. */
+
+/* DDF RAID6 layouts differ from md/raid6 layouts in two ways.
+ * Firstly, the exact positioning of the parity block is slightly
+ * different between the 'LEFT_*' modes of md and the "_N_*" modes
+ * of DDF.
+ * Secondly, or order of datablocks over which the Q syndrome is computed
+ * is different.
+ * Consequently we have different layouts for DDF/raid6 than md/raid6.
+ * These layouts are from the DDFv1.2 spec.
+ * Interestingly DDFv1.2-Errata-A does not specify N_CONTINUE but
+ * leaves RLQ=3 as 'Vendor Specific'
+ */
+
+#define ALGORITHM_ROTATING_ZERO_RESTART 8 /* DDF PRL=6 RLQ=1 */
+#define ALGORITHM_ROTATING_N_RESTART 9 /* DDF PRL=6 RLQ=2 */
+#define ALGORITHM_ROTATING_N_CONTINUE 10 /*DDF PRL=6 RLQ=3 */
+
+
+/* For every RAID5 algorithm we define a RAID6 algorithm
+ * with exactly the same layout for data and parity, and
+ * with the Q block always on the last device (N-1).
+ * This allows trivial conversion from RAID5 to RAID6
+ */
+#define ALGORITHM_LEFT_ASYMMETRIC_6 16
+#define ALGORITHM_RIGHT_ASYMMETRIC_6 17
+#define ALGORITHM_LEFT_SYMMETRIC_6 18
+#define ALGORITHM_RIGHT_SYMMETRIC_6 19
+#define ALGORITHM_PARITY_0_6 20
+#define ALGORITHM_PARITY_N_6 ALGORITHM_PARITY_N
+
+static inline int algorithm_valid_raid5(int layout)
+{
+ return (layout >= 0) &&
+ (layout <= 5);
+}
+static inline int algorithm_valid_raid6(int layout)
+{
+ return (layout >= 0 && layout <= 5)
+ ||
+ (layout == 8 || layout == 10)
+ ||
+ (layout >= 16 && layout <= 20);
+}
+static inline int algorithm_is_DDF(int layout)
+{
+ return layout >= 8 && layout <= 10;
+}
#endif
diff --git a/drivers/md/raid6algos.c b/drivers/md/raid6algos.c
index 21987e3dbe6..866215ac7f2 100644
--- a/drivers/md/raid6algos.c
+++ b/drivers/md/raid6algos.c
@@ -5,7 +5,7 @@
* 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, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -16,13 +16,20 @@
* Algorithm list and algorithm selection for RAID-6
*/
-#include "raid6.h"
+#include <linux/raid/pq.h>
#ifndef __KERNEL__
#include <sys/mman.h>
#include <stdio.h>
+#else
+#if !RAID6_USE_EMPTY_ZERO_PAGE
+/* In .bss so it's zeroed */
+const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
+EXPORT_SYMBOL(raid6_empty_zero_page);
+#endif
#endif
struct raid6_calls raid6_call;
+EXPORT_SYMBOL_GPL(raid6_call);
/* Various routine sets */
extern const struct raid6_calls raid6_intx1;
@@ -79,6 +86,7 @@ const struct raid6_calls * const raid6_algos[] = {
#else
/* Need more time to be stable in userspace */
#define RAID6_TIME_JIFFIES_LG2 9
+#define time_before(x, y) ((x) < (y))
#endif
/* Try to pick the best algorithm */
@@ -152,3 +160,12 @@ int __init raid6_select_algo(void)
return best ? 0 : -EINVAL;
}
+
+static void raid6_exit(void)
+{
+ do { } while (0);
+}
+
+subsys_initcall(raid6_select_algo);
+module_exit(raid6_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/md/raid6altivec.uc b/drivers/md/raid6altivec.uc
index b9afd35b881..699dfeee494 100644
--- a/drivers/md/raid6altivec.uc
+++ b/drivers/md/raid6altivec.uc
@@ -5,7 +5,7 @@
* 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, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -22,7 +22,7 @@
* bracked this with preempt_disable/enable or in a lock)
*/
-#include "raid6.h"
+#include <linux/raid/pq.h>
#ifdef CONFIG_ALTIVEC
diff --git a/drivers/md/raid6int.uc b/drivers/md/raid6int.uc
index ad004cee0e2..f9bf9cba357 100644
--- a/drivers/md/raid6int.uc
+++ b/drivers/md/raid6int.uc
@@ -5,7 +5,7 @@
* 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, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
* This file is postprocessed using unroll.pl
*/
-#include "raid6.h"
+#include <linux/raid/pq.h>
/*
* This is the C data type to use
diff --git a/drivers/md/raid6mmx.c b/drivers/md/raid6mmx.c
index d4e4a1bd70a..e7f6c13132b 100644
--- a/drivers/md/raid6mmx.c
+++ b/drivers/md/raid6mmx.c
@@ -5,7 +5,7 @@
* 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, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
#if defined(__i386__) && !defined(__arch_um__)
-#include "raid6.h"
+#include <linux/raid/pq.h>
#include "raid6x86.h"
/* Shared with raid6sse1.c */
diff --git a/drivers/md/raid6recov.c b/drivers/md/raid6recov.c
index a8c4d9451bd..2609f00e0d6 100644
--- a/drivers/md/raid6recov.c
+++ b/drivers/md/raid6recov.c
@@ -5,7 +5,7 @@
* 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, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
* the syndrome.)
*/
-#include "raid6.h"
+#include <linux/raid/pq.h>
/* Recover two failed data blocks. */
void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
@@ -63,9 +63,7 @@ void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
p++; q++;
}
}
-
-
-
+EXPORT_SYMBOL_GPL(raid6_2data_recov);
/* Recover failure of one data block plus the P block */
void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs)
@@ -97,9 +95,10 @@ void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs)
q++; dq++;
}
}
+EXPORT_SYMBOL_GPL(raid6_datap_recov);
-
-#ifndef __KERNEL__ /* Testing only */
+#ifndef __KERNEL__
+/* Testing only */
/* Recover two failed blocks. */
void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs)
diff --git a/drivers/md/raid6sse1.c b/drivers/md/raid6sse1.c
index 0666237276f..b274dd5eab8 100644
--- a/drivers/md/raid6sse1.c
+++ b/drivers/md/raid6sse1.c
@@ -5,7 +5,7 @@
* 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, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -23,7 +23,7 @@
#if defined(__i386__) && !defined(__arch_um__)
-#include "raid6.h"
+#include <linux/raid/pq.h>
#include "raid6x86.h"
/* Defined in raid6mmx.c */
diff --git a/drivers/md/raid6sse2.c b/drivers/md/raid6sse2.c
index b034ad86803..6ed6c6c0389 100644
--- a/drivers/md/raid6sse2.c
+++ b/drivers/md/raid6sse2.c
@@ -5,7 +5,7 @@
* 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, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -19,7 +19,7 @@
#if (defined(__i386__) || defined(__x86_64__)) && !defined(__arch_um__)
-#include "raid6.h"
+#include <linux/raid/pq.h>
#include "raid6x86.h"
static const struct raid6_sse_constants {
diff --git a/drivers/md/raid6test/Makefile b/drivers/md/raid6test/Makefile
index 78e0396adf2..58ffdf4f516 100644
--- a/drivers/md/raid6test/Makefile
+++ b/drivers/md/raid6test/Makefile
@@ -5,7 +5,7 @@
CC = gcc
OPTFLAGS = -O2 # Adjust as desired
-CFLAGS = -I.. -g $(OPTFLAGS)
+CFLAGS = -I.. -I ../../../include -g $(OPTFLAGS)
LD = ld
PERL = perl
AR = ar
diff --git a/drivers/md/raid6test/test.c b/drivers/md/raid6test/test.c
index 559cc41b258..7a930318b17 100644
--- a/drivers/md/raid6test/test.c
+++ b/drivers/md/raid6test/test.c
@@ -17,7 +17,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include "raid6.h"
+#include <linux/raid/pq.h>
#define NDISKS 16 /* Including P and Q */
diff --git a/drivers/md/raid6x86.h b/drivers/md/raid6x86.h
index 99fea7a70ca..4c22c156855 100644
--- a/drivers/md/raid6x86.h
+++ b/drivers/md/raid6x86.h
@@ -5,7 +5,7 @@
* 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, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 52c3f65b12d..607d319ce8e 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -148,7 +148,7 @@ config MEDIA_TUNER_XC5000
default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon tuner XC5000 from Xceive.
- This device is only used inside a SiP called togther with a
+ This device is only used inside a SiP called together with a
demodulator for now.
config MEDIA_TUNER_MXL5005S
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index 5b20cf5a29f..971a8b18f6d 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -662,7 +662,7 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
if (ret < 0)
goto err_kfree;
- ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (ret < 0)
goto err_pci_disable_device;
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 6103caad164..60955a70d88 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -294,7 +294,7 @@ config DVB_USB_DTV5100
config DVB_USB_AF9015
tristate "Afatech AF9015 DVB-T USB2.0 support"
- depends on DVB_USB && EXPERIMENTAL
+ depends on DVB_USB
select DVB_AF9013
select DVB_PLL if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
@@ -309,6 +309,6 @@ config DVB_USB_CE6230
tristate "Intel CE6230 DVB-T USB2.0 support"
depends on DVB_USB && EXPERIMENTAL
select DVB_ZL10353
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index f0ba8b07b84..53bfc8e42fb 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -782,17 +782,14 @@ static int af9015_read_config(struct usb_device *udev)
ARRAY_SIZE(af9015_ir_table_leadtek);
break;
case USB_VID_VISIONPLUS:
- if (udev->descriptor.idProduct ==
- cpu_to_le16(USB_PID_AZUREWAVE_AD_TU700)) {
- af9015_properties[i].rc_key_map =
- af9015_rc_keys_twinhan;
- af9015_properties[i].rc_key_map_size =
- ARRAY_SIZE(af9015_rc_keys_twinhan);
- af9015_config.ir_table =
- af9015_ir_table_twinhan;
- af9015_config.ir_table_size =
- ARRAY_SIZE(af9015_ir_table_twinhan);
- }
+ af9015_properties[i].rc_key_map =
+ af9015_rc_keys_twinhan;
+ af9015_properties[i].rc_key_map_size =
+ ARRAY_SIZE(af9015_rc_keys_twinhan);
+ af9015_config.ir_table =
+ af9015_ir_table_twinhan;
+ af9015_config.ir_table_size =
+ ARRAY_SIZE(af9015_ir_table_twinhan);
break;
case USB_VID_KWORLD_2:
/* TODO: use correct rc keys */
@@ -833,6 +830,16 @@ static int af9015_read_config(struct usb_device *udev)
af9015_ir_table_msi;
af9015_config.ir_table_size =
ARRAY_SIZE(af9015_ir_table_msi);
+ } else if (udev->descriptor.idProduct ==
+ cpu_to_le16(USB_PID_TREKSTOR_DVBT)) {
+ af9015_properties[i].rc_key_map =
+ af9015_rc_keys_trekstor;
+ af9015_properties[i].rc_key_map_size =
+ ARRAY_SIZE(af9015_rc_keys_trekstor);
+ af9015_config.ir_table =
+ af9015_ir_table_trekstor;
+ af9015_config.ir_table_size =
+ ARRAY_SIZE(af9015_ir_table_trekstor);
}
break;
case USB_VID_AVERMEDIA:
@@ -981,6 +988,21 @@ error:
if (ret)
err("eeprom read failed:%d", ret);
+ /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
+ content :-( Override some wrong values here. */
+ if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
+ le16_to_cpu(udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850) {
+ deb_info("%s: AverMedia A850: overriding config\n", __func__);
+ /* disable dual mode */
+ af9015_config.dual_mode = 0;
+ /* disable 2nd adapter */
+ for (i = 0; i < af9015_properties_count; i++)
+ af9015_properties[i].num_adapters = 1;
+
+ /* set correct IF */
+ af9015_af9013_config[0].tuner_if = 4570;
+ }
+
return ret;
}
@@ -1237,6 +1259,9 @@ static struct usb_device_id af9015_usb_table[] = {
/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
+ {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)},
+ {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)},
+ {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)},
{0},
};
MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1401,7 +1426,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.i2c_algo = &af9015_i2c_algo,
- .num_device_descs = 7,
+ .num_device_descs = 9,
.devices = {
{
.name = "Xtensions XD-380",
@@ -1437,7 +1462,19 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.name = "KWorld USB DVB-T TV Stick II " \
"(VS-DVB-T 395U)",
.cold_ids = {&af9015_usb_table[16],
- &af9015_usb_table[17], NULL},
+ &af9015_usb_table[17],
+ &af9015_usb_table[18], NULL},
+ .warm_ids = {NULL},
+ },
+ {
+ .name = "TrekStor DVB-T USB Stick",
+ .cold_ids = {&af9015_usb_table[19], NULL},
+ .warm_ids = {NULL},
+ },
+ {
+ .name = "AverMedia AVerTV Volar Black HD " \
+ "(A850)",
+ .cold_ids = {&af9015_usb_table[20], NULL},
.warm_ids = {NULL},
},
}
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index 00e25714662..8d81a17c116 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -64,14 +64,6 @@
#define AF9015_EEPROM_OFFSET (AF9015_EEPROM_SAW_BW2 - AF9015_EEPROM_SAW_BW1)
-#define AF9015_GPIO_ON (1 << 0)
-#define AF9015_GPIO_EN (1 << 1)
-#define AF9015_GPIO_O (1 << 2)
-#define AF9015_GPIO_I (1 << 3)
-
-#define AF9015_GPIO_TUNER_ON (AF9015_GPIO_ON|AF9015_GPIO_EN)
-#define AF9015_GPIO_TUNER_OFF (AF9015_GPIO_ON|AF9015_GPIO_EN|AF9015_GPIO_O)
-
struct req_t {
u8 cmd; /* [0] */
/* seq */ /* [1] */
@@ -120,11 +112,11 @@ struct af9015_config {
enum af9015_remote {
AF9015_REMOTE_NONE = 0,
- AF9015_REMOTE_A_LINK_DTU_M,
+/* 1 */ AF9015_REMOTE_A_LINK_DTU_M,
AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
AF9015_REMOTE_MYGICTV_U718,
AF9015_REMOTE_DIGITTRADE_DVB_T,
- AF9015_REMOTE_AVERMEDIA_KS,
+/* 5 */ AF9015_REMOTE_AVERMEDIA_KS,
};
/* Leadtek WinFast DTV Dongle Gold */
@@ -691,4 +683,67 @@ static u8 af9015_ir_table_digittrade[] = {
0x00, 0xff, 0x1d, 0xe2, 0x40, 0x00, 0x00,
};
+/* TREKSTOR DVB-T USB Stick */
+static struct dvb_usb_rc_key af9015_rc_keys_trekstor[] = {
+ { 0x07, 0x04, KEY_AGAIN }, /* Home */
+ { 0x07, 0x05, KEY_MUTE }, /* Mute */
+ { 0x07, 0x06, KEY_UP }, /* Up */
+ { 0x07, 0x07, KEY_DOWN }, /* Down */
+ { 0x07, 0x09, KEY_RIGHT }, /* Right */
+ { 0x07, 0x0a, KEY_ENTER }, /* OK */
+ { 0x07, 0x0b, KEY_FASTFORWARD }, /* Fast forward */
+ { 0x07, 0x0c, KEY_REWIND }, /* Rewind */
+ { 0x07, 0x0d, KEY_PLAY }, /* Play/Pause */
+ { 0x07, 0x0e, KEY_VOLUMEUP }, /* Volume + */
+ { 0x07, 0x0f, KEY_VOLUMEDOWN }, /* Volume - */
+ { 0x07, 0x10, KEY_RECORD }, /* Record */
+ { 0x07, 0x11, KEY_STOP }, /* Stop */
+ { 0x07, 0x12, KEY_ZOOM }, /* TV */
+ { 0x07, 0x13, KEY_EPG }, /* Info/EPG */
+ { 0x07, 0x14, KEY_CHANNELDOWN }, /* Channel - */
+ { 0x07, 0x15, KEY_CHANNELUP }, /* Channel + */
+ { 0x07, 0x1e, KEY_1 },
+ { 0x07, 0x1f, KEY_2 },
+ { 0x07, 0x20, KEY_3 },
+ { 0x07, 0x21, KEY_4 },
+ { 0x07, 0x22, KEY_5 },
+ { 0x07, 0x23, KEY_6 },
+ { 0x07, 0x24, KEY_7 },
+ { 0x07, 0x25, KEY_8 },
+ { 0x07, 0x26, KEY_9 },
+ { 0x07, 0x08, KEY_LEFT }, /* LEFT */
+ { 0x07, 0x27, KEY_0 },
+};
+
+static u8 af9015_ir_table_trekstor[] = {
+ 0x00, 0xff, 0x86, 0x79, 0x04, 0x07, 0x00,
+ 0x00, 0xff, 0x85, 0x7a, 0x05, 0x07, 0x00,
+ 0x00, 0xff, 0x87, 0x78, 0x06, 0x07, 0x00,
+ 0x00, 0xff, 0x8c, 0x73, 0x07, 0x07, 0x00,
+ 0x00, 0xff, 0x89, 0x76, 0x09, 0x07, 0x00,
+ 0x00, 0xff, 0x88, 0x77, 0x0a, 0x07, 0x00,
+ 0x00, 0xff, 0x8a, 0x75, 0x0b, 0x07, 0x00,
+ 0x00, 0xff, 0x9e, 0x61, 0x0c, 0x07, 0x00,
+ 0x00, 0xff, 0x8d, 0x72, 0x0d, 0x07, 0x00,
+ 0x00, 0xff, 0x8b, 0x74, 0x0e, 0x07, 0x00,
+ 0x00, 0xff, 0x9b, 0x64, 0x0f, 0x07, 0x00,
+ 0x00, 0xff, 0x9d, 0x62, 0x10, 0x07, 0x00,
+ 0x00, 0xff, 0x8e, 0x71, 0x11, 0x07, 0x00,
+ 0x00, 0xff, 0x9c, 0x63, 0x12, 0x07, 0x00,
+ 0x00, 0xff, 0x8f, 0x70, 0x13, 0x07, 0x00,
+ 0x00, 0xff, 0x93, 0x6c, 0x14, 0x07, 0x00,
+ 0x00, 0xff, 0x97, 0x68, 0x15, 0x07, 0x00,
+ 0x00, 0xff, 0x92, 0x6d, 0x1e, 0x07, 0x00,
+ 0x00, 0xff, 0x96, 0x69, 0x1f, 0x07, 0x00,
+ 0x00, 0xff, 0x9a, 0x65, 0x20, 0x07, 0x00,
+ 0x00, 0xff, 0x91, 0x6e, 0x21, 0x07, 0x00,
+ 0x00, 0xff, 0x95, 0x6a, 0x22, 0x07, 0x00,
+ 0x00, 0xff, 0x99, 0x66, 0x23, 0x07, 0x00,
+ 0x00, 0xff, 0x90, 0x6f, 0x24, 0x07, 0x00,
+ 0x00, 0xff, 0x94, 0x6b, 0x25, 0x07, 0x00,
+ 0x00, 0xff, 0x98, 0x67, 0x26, 0x07, 0x00,
+ 0x00, 0xff, 0x9f, 0x60, 0x08, 0x07, 0x00,
+ 0x00, 0xff, 0x84, 0x7b, 0x27, 0x07, 0x00,
+};
+
#endif
diff --git a/drivers/media/dvb/dvb-usb/ce6230.c b/drivers/media/dvb/dvb-usb/ce6230.c
index 5862820f109..52badc00e67 100644
--- a/drivers/media/dvb/dvb-usb/ce6230.c
+++ b/drivers/media/dvb/dvb-usb/ce6230.c
@@ -250,6 +250,7 @@ static int ce6230_probe(struct usb_interface *intf,
static struct usb_device_id ce6230_table[] = {
{ USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500) },
+ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A310) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, ce6230_table);
@@ -284,13 +285,18 @@ static struct dvb_usb_device_properties ce6230_properties = {
.i2c_algo = &ce6230_i2c_algo,
- .num_device_descs = 1,
+ .num_device_descs = 2,
.devices = {
{
.name = "Intel CE9500 reference design",
.cold_ids = {NULL},
.warm_ids = {&ce6230_table[0], NULL},
},
+ {
+ .name = "AVerMedia A310 USB 2.0 DVB-T tuner",
+ .cold_ids = {NULL},
+ .warm_ids = {&ce6230_table[1], NULL},
+ },
}
};
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index dc7ea21cd13..f506c74119f 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -65,6 +65,7 @@
#define USB_PID_AFATECH_AF9005 0x9020
#define USB_PID_AFATECH_AF9015_9015 0x9015
#define USB_PID_AFATECH_AF9015_9016 0x9016
+#define USB_PID_TREKSTOR_DVBT 0x901b
#define USB_VID_ALINK_DTU 0xf170
#define USB_PID_ANSONIC_DVBT_USB 0x6000
#define USB_PID_ANYSEE 0x861f
@@ -102,6 +103,7 @@
#define USB_PID_KWORLD_399U 0xe399
#define USB_PID_KWORLD_395U 0xe396
#define USB_PID_KWORLD_395U_2 0xe39b
+#define USB_PID_KWORLD_395U_3 0xe395
#define USB_PID_KWORLD_PC160_2T 0xc160
#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
@@ -167,6 +169,8 @@
#define USB_PID_AVERMEDIA_VOLAR_X 0xa815
#define USB_PID_AVERMEDIA_VOLAR_X_2 0x8150
#define USB_PID_AVERMEDIA_A309 0xa309
+#define USB_PID_AVERMEDIA_A310 0xa310
+#define USB_PID_AVERMEDIA_A850 0x850a
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index 12f7730184a..32526f103b5 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -151,7 +151,7 @@ static void debug_fcp(const u8 *data, int length)
subunit_type = data[1] >> 3;
subunit_id = data[1] & 7;
op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
- printk(KERN_INFO "%ssu=%x.%x l=%zu: %-8s - %s\n",
+ printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n",
prefix, subunit_type, subunit_id, length,
debug_fcp_ctype(data[0]),
debug_fcp_opcode(op, data, length));
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index a206cee23f7..23e4cffeba3 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -479,7 +479,7 @@ config DVB_TUNER_DIB0070
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon baseband tuner DiB0070 from DiBcom.
- This device is only used inside a SiP called togther with a
+ This device is only used inside a SiP called together with a
demodulator for now.
comment "SEC control devices for DVB-S"
@@ -513,6 +513,13 @@ config DVB_LGS8GL5
help
A DMB-TH tuner module. Say Y when you want to support this frontend.
+config DVB_LGS8GXX
+ tristate "Legend Silicon LGS8913/LGS8GL5/LGS8GXX DMB-TH demodulator"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DMB-TH tuner module. Say Y when you want to support this frontend.
+
comment "Tools to develop new frontends"
config DVB_DUMMY_FE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 65a336aa1db..bc2b00abd10 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_DVB_TDA10048) += tda10048.o
obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o
obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
+obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o
obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
obj-$(CONFIG_DVB_AF9013) += af9013.o
obj-$(CONFIG_DVB_CX24116) += cx24116.o
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
index d63e1527dc8..9e9a75576a1 100644
--- a/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -652,7 +652,7 @@ static int au8522_reset(struct v4l2_subdev *sd, u32 val)
}
static int au8522_s_video_routing(struct v4l2_subdev *sd,
- const struct v4l2_routing *route)
+ u32 input, u32 output, u32 config)
{
struct au8522_state *state = to_state(sd);
@@ -663,11 +663,11 @@ static int au8522_s_video_routing(struct v4l2_subdev *sd,
closed), and then came back to analog mode */
au8522_writereg(state, 0x106, 1);
- if (route->input == AU8522_COMPOSITE_CH1) {
+ if (input == AU8522_COMPOSITE_CH1) {
au8522_setup_cvbs_mode(state);
- } else if (route->input == AU8522_SVIDEO_CH13) {
+ } else if (input == AU8522_SVIDEO_CH13) {
au8522_setup_svideo_mode(state);
- } else if (route->input == AU8522_COMPOSITE_CH4_SIF) {
+ } else if (input == AU8522_COMPOSITE_CH4_SIF) {
au8522_setup_cvbs_tuner_mode(state);
} else {
printk(KERN_ERR "au8522 mode not currently supported\n");
@@ -677,10 +677,10 @@ static int au8522_s_video_routing(struct v4l2_subdev *sd,
}
static int au8522_s_audio_routing(struct v4l2_subdev *sd,
- const struct v4l2_routing *route)
+ u32 input, u32 output, u32 config)
{
struct au8522_state *state = to_state(sd);
- set_audio_input(state, route->input);
+ set_audio_input(state, input);
return 0;
}
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index 1e81e713df6..172f1f928f0 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -74,7 +74,7 @@ static struct {
} fw[] = {
#define _FW_ENTRY(a, b, c) { \
.name = a, \
- .file = 0, \
+ .file = NULL, \
.lock = __RW_LOCK_UNLOCKED(fw[c].lock), \
.refcnt = 0, \
.data = { } }
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c
new file mode 100644
index 00000000000..f9785dfe735
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgs8gxx.c
@@ -0,0 +1,816 @@
+/*
+ * Support for Legend Silicon DMB-TH demodulator
+ * LGS8913, LGS8GL5
+ * experimental support LGS8G42, LGS8G52
+ *
+ * Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com>
+ * Copyright (C) 2008 Sirius International (Hong Kong) Limited
+ * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
+ *
+ * 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 <asm/div64.h>
+
+#include "dvb_frontend.h"
+
+#include "lgs8gxx.h"
+#include "lgs8gxx_priv.h"
+
+#define dprintk(args...) \
+ do { \
+ if (debug) \
+ printk(KERN_DEBUG "lgs8gxx: " args); \
+ } while (0)
+
+static int debug;
+static int fake_signal_str;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+module_param(fake_signal_str, int, 0644);
+MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913."
+"Signal strength calculation is slow.(default:off).");
+
+/* LGS8GXX internal helper functions */
+
+static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data)
+{
+ int ret;
+ u8 buf[] = { reg, data };
+ struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
+
+ msg.addr = priv->config->demod_address;
+ if (reg >= 0xC0)
+ msg.addr += 0x02;
+
+ if (debug >= 2)
+ printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
+ __func__, reg, data);
+
+ ret = i2c_transfer(priv->i2c, &msg, 1);
+
+ if (ret != 1)
+ dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n",
+ __func__, reg, data, ret);
+
+ return (ret != 1) ? -1 : 0;
+}
+
+static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data)
+{
+ int ret;
+ u8 dev_addr;
+
+ u8 b0[] = { reg };
+ u8 b1[] = { 0 };
+ struct i2c_msg msg[] = {
+ { .flags = 0, .buf = b0, .len = 1 },
+ { .flags = I2C_M_RD, .buf = b1, .len = 1 },
+ };
+
+ dev_addr = priv->config->demod_address;
+ if (reg >= 0xC0)
+ dev_addr += 0x02;
+ msg[1].addr = msg[0].addr = dev_addr;
+
+ ret = i2c_transfer(priv->i2c, msg, 2);
+ if (ret != 2) {
+ dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n",
+ __func__, reg, ret);
+ return -1;
+ }
+
+ *p_data = b1[0];
+ if (debug >= 2)
+ printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
+ __func__, reg, b1[0]);
+ return 0;
+}
+
+static int lgs8gxx_soft_reset(struct lgs8gxx_state *priv)
+{
+ lgs8gxx_write_reg(priv, 0x02, 0x00);
+ msleep(1);
+ lgs8gxx_write_reg(priv, 0x02, 0x01);
+ msleep(100);
+
+ return 0;
+}
+
+static int lgs8gxx_set_ad_mode(struct lgs8gxx_state *priv)
+{
+ const struct lgs8gxx_config *config = priv->config;
+ u8 if_conf;
+
+ if_conf = 0x10; /* AGC output on; */
+
+ if_conf |=
+ ((config->ext_adc) ? 0x80 : 0x00) |
+ ((config->if_neg_center) ? 0x04 : 0x00) |
+ ((config->if_freq == 0) ? 0x08 : 0x00) | /* Baseband */
+ ((config->ext_adc && config->adc_signed) ? 0x02 : 0x00) |
+ ((config->ext_adc && config->if_neg_edge) ? 0x01 : 0x00);
+
+ if (config->ext_adc &&
+ (config->prod == LGS8GXX_PROD_LGS8G52)) {
+ lgs8gxx_write_reg(priv, 0xBA, 0x40);
+ }
+
+ lgs8gxx_write_reg(priv, 0x07, if_conf);
+
+ return 0;
+}
+
+static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/)
+{
+ u64 val;
+ u32 v32;
+ u32 if_clk;
+
+ if_clk = priv->config->if_clk_freq;
+
+ val = freq;
+ if (freq != 0) {
+ val *= (u64)1 << 32;
+ if (if_clk != 0)
+ do_div(val, if_clk);
+ v32 = val & 0xFFFFFFFF;
+ dprintk("Set IF Freq to %dkHz\n", freq);
+ } else {
+ v32 = 0;
+ dprintk("Set IF Freq to baseband\n");
+ }
+ dprintk("AFC_INIT_FREQ = 0x%08X\n", v32);
+
+ lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32));
+ lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 8));
+ lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 16));
+ lgs8gxx_write_reg(priv, 0x0C, 0xFF & (v32 >> 24));
+
+ return 0;
+}
+
+static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv)
+{
+ u8 t;
+
+ if (priv->config->prod == LGS8GXX_PROD_LGS8913)
+ lgs8gxx_write_reg(priv, 0xC6, 0x01);
+
+ lgs8gxx_read_reg(priv, 0x7E, &t);
+ lgs8gxx_write_reg(priv, 0x7E, t | 0x01);
+
+ /* clear FEC self reset */
+ lgs8gxx_read_reg(priv, 0xC5, &t);
+ lgs8gxx_write_reg(priv, 0xC5, t & 0xE0);
+
+ if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
+ /* FEC auto detect */
+ lgs8gxx_write_reg(priv, 0xC1, 0x03);
+
+ lgs8gxx_read_reg(priv, 0x7C, &t);
+ t = (t & 0x8C) | 0x03;
+ lgs8gxx_write_reg(priv, 0x7C, t);
+ }
+
+
+ if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
+ /* BER test mode */
+ lgs8gxx_read_reg(priv, 0xC3, &t);
+ t = (t & 0xEF) | 0x10;
+ lgs8gxx_write_reg(priv, 0xC3, t);
+ }
+
+ if (priv->config->prod == LGS8GXX_PROD_LGS8G52)
+ lgs8gxx_write_reg(priv, 0xD9, 0x40);
+
+ return 0;
+}
+
+static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv)
+{
+ int ret = 0;
+ u8 t;
+
+ /* turn off auto-detect; manual settings */
+ lgs8gxx_write_reg(priv, 0x7E, 0);
+ if (priv->config->prod == LGS8GXX_PROD_LGS8913)
+ lgs8gxx_write_reg(priv, 0xC1, 0);
+
+ ret = lgs8gxx_read_reg(priv, 0xC5, &t);
+ t = (t & 0xE0) | 0x06;
+ lgs8gxx_write_reg(priv, 0xC5, t);
+
+ lgs8gxx_soft_reset(priv);
+
+ return 0;
+}
+
+static int lgs8gxx_is_locked(struct lgs8gxx_state *priv, u8 *locked)
+{
+ int ret = 0;
+ u8 t;
+
+ ret = lgs8gxx_read_reg(priv, 0x4B, &t);
+ if (ret != 0)
+ return ret;
+
+ *locked = ((t & 0xC0) == 0xC0) ? 1 : 0;
+ return 0;
+}
+
+static int lgs8gxx_is_autodetect_finished(struct lgs8gxx_state *priv,
+ u8 *finished)
+{
+ int ret = 0;
+ u8 t;
+
+ ret = lgs8gxx_read_reg(priv, 0xA4, &t);
+ if (ret != 0)
+ return ret;
+
+ *finished = ((t & 0x3) == 0x1) ? 1 : 0;
+
+ return 0;
+}
+
+static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 *locked)
+{
+ int err;
+ u8 ad_fini = 0;
+
+ if (gi == GI_945)
+ dprintk("try GI 945\n");
+ else if (gi == GI_595)
+ dprintk("try GI 595\n");
+ else if (gi == GI_420)
+ dprintk("try GI 420\n");
+ lgs8gxx_write_reg(priv, 0x04, gi);
+ lgs8gxx_soft_reset(priv);
+ msleep(50);
+ err = lgs8gxx_is_autodetect_finished(priv, &ad_fini);
+ if (err != 0)
+ return err;
+ if (ad_fini) {
+ err = lgs8gxx_is_locked(priv, locked);
+ if (err != 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static int lgs8gxx_auto_detect(struct lgs8gxx_state *priv,
+ u8 *detected_param, u8 *gi)
+{
+ int i, j;
+ int err = 0;
+ u8 locked = 0, tmp_gi;
+
+ dprintk("%s\n", __func__);
+
+ lgs8gxx_set_mode_auto(priv);
+ /* Guard Interval */
+ lgs8gxx_write_reg(priv, 0x03, 00);
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ tmp_gi = GI_945;
+ err = lgs8gxx_autolock_gi(priv, GI_945, &locked);
+ if (err)
+ goto out;
+ if (locked)
+ goto locked;
+ }
+ for (j = 0; j < 2; j++) {
+ tmp_gi = GI_420;
+ err = lgs8gxx_autolock_gi(priv, GI_420, &locked);
+ if (err)
+ goto out;
+ if (locked)
+ goto locked;
+ }
+ tmp_gi = GI_595;
+ err = lgs8gxx_autolock_gi(priv, GI_595, &locked);
+ if (err)
+ goto out;
+ if (locked)
+ goto locked;
+ }
+
+locked:
+ if ((err == 0) && (locked == 1)) {
+ u8 t;
+
+ lgs8gxx_read_reg(priv, 0xA2, &t);
+ *detected_param = t;
+
+ if (tmp_gi == GI_945)
+ dprintk("GI 945 locked\n");
+ else if (tmp_gi == GI_595)
+ dprintk("GI 595 locked\n");
+ else if (tmp_gi == GI_420)
+ dprintk("GI 420 locked\n");
+ *gi = tmp_gi;
+ }
+ if (!locked)
+ err = -1;
+
+out:
+ return err;
+}
+
+static void lgs8gxx_auto_lock(struct lgs8gxx_state *priv)
+{
+ s8 err;
+ u8 gi = 0x2;
+ u8 detected_param = 0;
+
+ err = lgs8gxx_auto_detect(priv, &detected_param, &gi);
+
+ if (err != 0) {
+ dprintk("lgs8gxx_auto_detect failed\n");
+ }
+
+ /* Apply detected parameters */
+ if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
+ u8 inter_leave_len = detected_param & TIM_MASK ;
+ inter_leave_len = (inter_leave_len == TIM_LONG) ? 0x60 : 0x40;
+ detected_param &= CF_MASK | SC_MASK | LGS_FEC_MASK;
+ detected_param |= inter_leave_len;
+ }
+ lgs8gxx_write_reg(priv, 0x7D, detected_param);
+ if (priv->config->prod == LGS8GXX_PROD_LGS8913)
+ lgs8gxx_write_reg(priv, 0xC0, detected_param);
+ /* lgs8gxx_soft_reset(priv); */
+
+ /* Enter manual mode */
+ lgs8gxx_set_mode_manual(priv);
+
+ switch (gi) {
+ case GI_945:
+ priv->curr_gi = 945; break;
+ case GI_595:
+ priv->curr_gi = 595; break;
+ case GI_420:
+ priv->curr_gi = 420; break;
+ default:
+ priv->curr_gi = 945; break;
+ }
+}
+
+static int lgs8gxx_set_mpeg_mode(struct lgs8gxx_state *priv,
+ u8 serial, u8 clk_pol, u8 clk_gated)
+{
+ int ret = 0;
+ u8 t;
+
+ ret = lgs8gxx_read_reg(priv, 0xC2, &t);
+ if (ret != 0)
+ return ret;
+
+ t &= 0xF8;
+ t |= serial ? TS_SERIAL : TS_PARALLEL;
+ t |= clk_pol ? TS_CLK_INVERTED : TS_CLK_NORMAL;
+ t |= clk_gated ? TS_CLK_GATED : TS_CLK_FREERUN;
+
+ ret = lgs8gxx_write_reg(priv, 0xC2, t);
+ if (ret != 0)
+ return ret;
+
+ return 0;
+}
+
+
+/* LGS8913 demod frontend functions */
+
+static int lgs8913_init(struct lgs8gxx_state *priv)
+{
+ u8 t;
+
+ /* LGS8913 specific */
+ lgs8gxx_write_reg(priv, 0xc1, 0x3);
+
+ lgs8gxx_read_reg(priv, 0x7c, &t);
+ lgs8gxx_write_reg(priv, 0x7c, (t&0x8c) | 0x3);
+
+ /* LGS8913 specific */
+ lgs8gxx_read_reg(priv, 0xc3, &t);
+ lgs8gxx_write_reg(priv, 0xc3, t&0x10);
+
+
+ return 0;
+}
+
+static int lgs8gxx_init(struct dvb_frontend *fe)
+{
+ struct lgs8gxx_state *priv =
+ (struct lgs8gxx_state *)fe->demodulator_priv;
+ const struct lgs8gxx_config *config = priv->config;
+ u8 data = 0;
+ s8 err;
+ dprintk("%s\n", __func__);
+
+ lgs8gxx_read_reg(priv, 0, &data);
+ dprintk("reg 0 = 0x%02X\n", data);
+
+ /* Setup MPEG output format */
+ err = lgs8gxx_set_mpeg_mode(priv, config->serial_ts,
+ config->ts_clk_pol,
+ config->ts_clk_gated);
+ if (err != 0)
+ return -EIO;
+
+ if (config->prod == LGS8GXX_PROD_LGS8913)
+ lgs8913_init(priv);
+ lgs8gxx_set_if_freq(priv, priv->config->if_freq);
+ if (config->prod != LGS8GXX_PROD_LGS8913)
+ lgs8gxx_set_ad_mode(priv);
+
+ return 0;
+}
+
+static void lgs8gxx_release(struct dvb_frontend *fe)
+{
+ struct lgs8gxx_state *state = fe->demodulator_priv;
+ dprintk("%s\n", __func__);
+
+ kfree(state);
+}
+
+
+static int lgs8gxx_write(struct dvb_frontend *fe, u8 *buf, int len)
+{
+ struct lgs8gxx_state *priv = fe->demodulator_priv;
+
+ if (len != 2)
+ return -EINVAL;
+
+ return lgs8gxx_write_reg(priv, buf[0], buf[1]);
+}
+
+static int lgs8gxx_set_fe(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *fe_params)
+{
+ struct lgs8gxx_state *priv = fe->demodulator_priv;
+
+ dprintk("%s\n", __func__);
+
+ /* set frequency */
+ if (fe->ops.tuner_ops.set_params) {
+ fe->ops.tuner_ops.set_params(fe, fe_params);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ }
+
+ /* start auto lock */
+ lgs8gxx_auto_lock(priv);
+
+ msleep(10);
+
+ return 0;
+}
+
+static int lgs8gxx_get_fe(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *fe_params)
+{
+ struct lgs8gxx_state *priv = fe->demodulator_priv;
+ u8 t;
+
+ dprintk("%s\n", __func__);
+
+ /* TODO: get real readings from device */
+ /* inversion status */
+ fe_params->inversion = INVERSION_OFF;
+
+ /* bandwidth */
+ fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
+
+
+ lgs8gxx_read_reg(priv, 0x7D, &t);
+ fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
+ fe_params->u.ofdm.code_rate_LP = FEC_AUTO;
+
+ /* constellation */
+ switch (t & SC_MASK) {
+ case SC_QAM64:
+ fe_params->u.ofdm.constellation = QAM_64;
+ break;
+ case SC_QAM32:
+ fe_params->u.ofdm.constellation = QAM_32;
+ break;
+ case SC_QAM16:
+ fe_params->u.ofdm.constellation = QAM_16;
+ break;
+ case SC_QAM4:
+ case SC_QAM4NR:
+ fe_params->u.ofdm.constellation = QPSK;
+ break;
+ default:
+ fe_params->u.ofdm.constellation = QAM_64;
+ }
+
+ /* transmission mode */
+ fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
+
+ /* guard interval */
+ fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
+
+ /* hierarchy */
+ fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE;
+
+ return 0;
+}
+
+static
+int lgs8gxx_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings *fesettings)
+{
+ /* FIXME: copy from tda1004x.c */
+ fesettings->min_delay_ms = 800;
+ fesettings->step_size = 0;
+ fesettings->max_drift = 0;
+ return 0;
+}
+
+static int lgs8gxx_read_status(struct dvb_frontend *fe, fe_status_t *fe_status)
+{
+ struct lgs8gxx_state *priv = fe->demodulator_priv;
+ s8 ret;
+ u8 t;
+
+ dprintk("%s\n", __func__);
+
+ ret = lgs8gxx_read_reg(priv, 0x4B, &t);
+ if (ret != 0)
+ return -EIO;
+
+ dprintk("Reg 0x4B: 0x%02X\n", t);
+
+ *fe_status = 0;
+ if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
+ if ((t & 0x40) == 0x40)
+ *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+ if ((t & 0x80) == 0x80)
+ *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC |
+ FE_HAS_LOCK;
+ } else {
+ if ((t & 0x80) == 0x80)
+ *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+ }
+
+ /* success */
+ dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
+ return 0;
+}
+
+static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal)
+{
+ u16 v;
+ u8 agc_lvl[2], cat;
+
+ dprintk("%s()\n", __func__);
+ lgs8gxx_read_reg(priv, 0x3F, &agc_lvl[0]);
+ lgs8gxx_read_reg(priv, 0x3E, &agc_lvl[1]);
+
+ v = agc_lvl[0];
+ v <<= 8;
+ v |= agc_lvl[1];
+
+ dprintk("agc_lvl: 0x%04X\n", v);
+
+ if (v < 0x100)
+ cat = 0;
+ else if (v < 0x190)
+ cat = 5;
+ else if (v < 0x2A8)
+ cat = 4;
+ else if (v < 0x381)
+ cat = 3;
+ else if (v < 0x400)
+ cat = 2;
+ else if (v == 0x400)
+ cat = 1;
+ else
+ cat = 0;
+
+ *signal = cat;
+
+ return 0;
+}
+
+static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
+{
+ u8 t; s8 ret;
+ s16 max_strength = 0;
+ u8 str;
+ u16 i, gi = priv->curr_gi;
+
+ dprintk("%s\n", __func__);
+
+ ret = lgs8gxx_read_reg(priv, 0x4B, &t);
+ if (ret != 0)
+ return -EIO;
+
+ if (fake_signal_str) {
+ if ((t & 0xC0) == 0xC0) {
+ dprintk("Fake signal strength as 50\n");
+ *signal = 0x32;
+ } else
+ *signal = 0;
+ return 0;
+ }
+
+ dprintk("gi = %d\n", gi);
+ for (i = 0; i < gi; i++) {
+
+ if ((i & 0xFF) == 0)
+ lgs8gxx_write_reg(priv, 0x84, 0x03 & (i >> 8));
+ lgs8gxx_write_reg(priv, 0x83, i & 0xFF);
+
+ lgs8gxx_read_reg(priv, 0x94, &str);
+ if (max_strength < str)
+ max_strength = str;
+ }
+
+ *signal = max_strength;
+ dprintk("%s: signal=0x%02X\n", __func__, *signal);
+
+ lgs8gxx_read_reg(priv, 0x95, &t);
+ dprintk("%s: AVG Noise=0x%02X\n", __func__, t);
+
+ return 0;
+}
+
+static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
+{
+ struct lgs8gxx_state *priv = fe->demodulator_priv;
+
+ if (priv->config->prod == LGS8GXX_PROD_LGS8913)
+ return lgs8913_read_signal_strength(priv, signal);
+ else
+ return lgs8gxx_read_signal_agc(priv, signal);
+}
+
+static int lgs8gxx_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct lgs8gxx_state *priv = fe->demodulator_priv;
+ u8 t;
+ *snr = 0;
+
+ lgs8gxx_read_reg(priv, 0x95, &t);
+ dprintk("AVG Noise=0x%02X\n", t);
+ *snr = 256 - t;
+ *snr <<= 8;
+ dprintk("snr=0x%x\n", *snr);
+
+ return 0;
+}
+
+static int lgs8gxx_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ *ucblocks = 0;
+ dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks);
+ return 0;
+}
+
+static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct lgs8gxx_state *priv = fe->demodulator_priv;
+ u8 r0, r1, r2, r3;
+ u32 total_cnt, err_cnt;
+
+ dprintk("%s\n", __func__);
+
+ lgs8gxx_write_reg(priv, 0xc6, 0x01);
+ lgs8gxx_write_reg(priv, 0xc6, 0x41);
+ lgs8gxx_write_reg(priv, 0xc6, 0x01);
+
+ msleep(200);
+
+ lgs8gxx_write_reg(priv, 0xc6, 0x81);
+ lgs8gxx_read_reg(priv, 0xd0, &r0);
+ lgs8gxx_read_reg(priv, 0xd1, &r1);
+ lgs8gxx_read_reg(priv, 0xd2, &r2);
+ lgs8gxx_read_reg(priv, 0xd3, &r3);
+ total_cnt = (r3 << 24) | (r2 << 16) | (r1 << 8) | (r0);
+ lgs8gxx_read_reg(priv, 0xd4, &r0);
+ lgs8gxx_read_reg(priv, 0xd5, &r1);
+ lgs8gxx_read_reg(priv, 0xd6, &r2);
+ lgs8gxx_read_reg(priv, 0xd7, &r3);
+ err_cnt = (r3 << 24) | (r2 << 16) | (r1 << 8) | (r0);
+ dprintk("error=%d total=%d\n", err_cnt, total_cnt);
+
+ if (total_cnt == 0)
+ *ber = 0;
+ else
+ *ber = err_cnt * 100 / total_cnt;
+
+ dprintk("%s: ber=0x%x\n", __func__, *ber);
+ return 0;
+}
+
+static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct lgs8gxx_state *priv = fe->demodulator_priv;
+
+ if (priv->config->tuner_address == 0)
+ return 0;
+ if (enable) {
+ u8 v = 0x80 | priv->config->tuner_address;
+ return lgs8gxx_write_reg(priv, 0x01, v);
+ }
+ return lgs8gxx_write_reg(priv, 0x01, 0);
+}
+
+static struct dvb_frontend_ops lgs8gxx_ops = {
+ .info = {
+ .name = "Legend Silicon LGS8913/LGS8GXX DMB-TH",
+ .type = FE_OFDM,
+ .frequency_min = 474000000,
+ .frequency_max = 858000000,
+ .frequency_stepsize = 10000,
+ .caps =
+ FE_CAN_FEC_AUTO |
+ FE_CAN_QAM_AUTO |
+ FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO
+ },
+
+ .release = lgs8gxx_release,
+
+ .init = lgs8gxx_init,
+ .write = lgs8gxx_write,
+ .i2c_gate_ctrl = lgs8gxx_i2c_gate_ctrl,
+
+ .set_frontend = lgs8gxx_set_fe,
+ .get_frontend = lgs8gxx_get_fe,
+ .get_tune_settings = lgs8gxx_get_tune_settings,
+
+ .read_status = lgs8gxx_read_status,
+ .read_ber = lgs8gxx_read_ber,
+ .read_signal_strength = lgs8gxx_read_signal_strength,
+ .read_snr = lgs8gxx_read_snr,
+ .read_ucblocks = lgs8gxx_read_ucblocks,
+};
+
+struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct lgs8gxx_state *priv = NULL;
+ u8 data = 0;
+
+ dprintk("%s()\n", __func__);
+
+ if (config == NULL || i2c == NULL)
+ return NULL;
+
+ priv = kzalloc(sizeof(struct lgs8gxx_state), GFP_KERNEL);
+ if (priv == NULL)
+ goto error_out;
+
+ priv->config = config;
+ priv->i2c = i2c;
+
+ /* check if the demod is there */
+ if (lgs8gxx_read_reg(priv, 0, &data) != 0) {
+ dprintk("%s lgs8gxx not found at i2c addr 0x%02X\n",
+ __func__, priv->config->demod_address);
+ goto error_out;
+ }
+
+ lgs8gxx_read_reg(priv, 1, &data);
+
+ memcpy(&priv->frontend.ops, &lgs8gxx_ops,
+ sizeof(struct dvb_frontend_ops));
+ priv->frontend.demodulator_priv = priv;
+
+ return &priv->frontend;
+
+error_out:
+ dprintk("%s() error_out\n", __func__);
+ kfree(priv);
+ return NULL;
+
+}
+EXPORT_SYMBOL(lgs8gxx_attach);
+
+MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver");
+MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lgs8gxx.h b/drivers/media/dvb/frontends/lgs8gxx.h
new file mode 100644
index 00000000000..321d366a830
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgs8gxx.h
@@ -0,0 +1,90 @@
+/*
+ * Support for Legend Silicon DMB-TH demodulator
+ * LGS8913, LGS8GL5
+ * experimental support LGS8G42, LGS8G52
+ *
+ * Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com>
+ * Copyright (C) 2008 Sirius International (Hong Kong) Limited
+ * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
+ *
+ * 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.
+ *
+ */
+
+#ifndef __LGS8GXX_H__
+#define __LGS8GXX_H__
+
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#define LGS8GXX_PROD_LGS8913 0
+#define LGS8GXX_PROD_LGS8GL5 1
+#define LGS8GXX_PROD_LGS8G42 3
+#define LGS8GXX_PROD_LGS8G52 4
+#define LGS8GXX_PROD_LGS8G54 5
+
+struct lgs8gxx_config {
+
+ /* product type */
+ u8 prod;
+
+ /* the demodulator's i2c address */
+ u8 demod_address;
+
+ /* parallel or serial transport stream */
+ u8 serial_ts;
+
+ /* transport stream polarity*/
+ u8 ts_clk_pol;
+
+ /* transport stream clock gated by ts_valid */
+ u8 ts_clk_gated;
+
+ /* A/D Clock frequency */
+ u32 if_clk_freq; /* in kHz */
+
+ /* IF frequency */
+ u32 if_freq; /* in kHz */
+
+ /*Use External ADC*/
+ u8 ext_adc;
+
+ /*External ADC output two's complement*/
+ u8 adc_signed;
+
+ /*Sample IF data at falling edge of IF_CLK*/
+ u8 if_neg_edge;
+
+ /*IF use Negative center frequency*/
+ u8 if_neg_center;
+
+ /* slave address and configuration of the tuner */
+ u8 tuner_address;
+};
+
+#if defined(CONFIG_DVB_LGS8GXX) || \
+ (defined(CONFIG_DVB_LGS8GXX_MODULE) && defined(MODULE))
+extern struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
+ struct i2c_adapter *i2c);
+#else
+static inline
+struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
+ struct i2c_adapter *i2c) {
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_LGS8GXX */
+
+#endif /* __LGS8GXX_H__ */
diff --git a/drivers/media/dvb/frontends/lgs8gxx_priv.h b/drivers/media/dvb/frontends/lgs8gxx_priv.h
new file mode 100644
index 00000000000..9776d30686d
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgs8gxx_priv.h
@@ -0,0 +1,70 @@
+/*
+ * Support for Legend Silicon DMB-TH demodulator
+ * LGS8913, LGS8GL5
+ * experimental support LGS8G42, LGS8G52
+ *
+ * Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com>
+ * Copyright (C) 2008 Sirius International (Hong Kong) Limited
+ * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
+ *
+ * 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.
+ *
+ */
+
+#ifndef LGS8913_PRIV_H
+#define LGS8913_PRIV_H
+
+struct lgs8gxx_state {
+ struct i2c_adapter *i2c;
+ /* configuration settings */
+ const struct lgs8gxx_config *config;
+ struct dvb_frontend frontend;
+ u16 curr_gi; /* current guard interval */
+};
+
+#define SC_MASK 0x1C /* Sub-Carrier Modulation Mask */
+#define SC_QAM64 0x10 /* 64QAM modulation */
+#define SC_QAM32 0x0C /* 32QAM modulation */
+#define SC_QAM16 0x08 /* 16QAM modulation */
+#define SC_QAM4NR 0x04 /* 4QAM modulation */
+#define SC_QAM4 0x00 /* 4QAM modulation */
+
+#define LGS_FEC_MASK 0x03 /* FEC Rate Mask */
+#define LGS_FEC_0_4 0x00 /* FEC Rate 0.4 */
+#define LGS_FEC_0_6 0x01 /* FEC Rate 0.6 */
+#define LGS_FEC_0_8 0x02 /* FEC Rate 0.8 */
+
+#define TIM_MASK 0x20 /* Time Interleave Length Mask */
+#define TIM_LONG 0x00 /* Time Interleave Length = 720 */
+#define TIM_MIDDLE 0x20 /* Time Interleave Length = 240 */
+
+#define CF_MASK 0x80 /* Control Frame Mask */
+#define CF_EN 0x80 /* Control Frame On */
+
+#define GI_MASK 0x03 /* Guard Interval Mask */
+#define GI_420 0x00 /* 1/9 Guard Interval */
+#define GI_595 0x01 /* */
+#define GI_945 0x02 /* 1/4 Guard Interval */
+
+
+#define TS_PARALLEL 0x00 /* Parallel TS Output a.k.a. SPI */
+#define TS_SERIAL 0x01 /* Serial TS Output a.k.a. SSI */
+#define TS_CLK_NORMAL 0x00 /* MPEG Clock Normal */
+#define TS_CLK_INVERTED 0x02 /* MPEG Clock Inverted */
+#define TS_CLK_GATED 0x00 /* MPEG clock gated */
+#define TS_CLK_FREERUN 0x04 /* MPEG clock free running*/
+
+
+#endif
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index ee89623be85..598eaf8acc6 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -616,7 +616,7 @@ static int __devinit pluto2_probe(struct pci_dev *pdev,
/* enable interrupts */
pci_write_config_dword(pdev, 0x6c, 0x8000);
- ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (ret < 0)
goto err_pci_disable_device;
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 772990415f9..68eb4493f99 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -28,25 +28,12 @@ config DVB_AV7110
download/extract it, and then copy it to /usr/lib/hotplug/firmware
or /lib/firmware (depending on configuration of firmware hotplug).
- Say Y if you own such a card and want to use it.
-
-config DVB_AV7110_FIRMWARE
- bool "Compile AV7110 firmware into the driver"
- depends on DVB_AV7110 && !STANDALONE
- default y if DVB_AV7110=y
- help
- The AV7110 firmware is normally loaded by the firmware hotplug manager.
- If you want to compile the firmware into the driver you need to say
- Y here and provide the correct path of the firmware. You need this
- option if you want to compile the whole driver statically into the
- kernel.
+ Alternatively, you can download the file and use the kernel's
+ EXTRA_FIRMWARE configuration option to build it into your
+ kernel image by adding the filename to the EXTRA_FIRMWARE
+ configuration option string.
- All other people say N.
-
-config DVB_AV7110_FIRMWARE_FILE
- string "Full pathname of av7110 firmware file"
- depends on DVB_AV7110_FIRMWARE
- default "/usr/lib/hotplug/firmware/dvb-ttpci-01.fw"
+ Say Y if you own such a card and want to use it.
config DVB_AV7110_OSD
bool "AV7110 OSD support"
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile
index 71451237294..8a4d5bb20a5 100644
--- a/drivers/media/dvb/ttpci/Makefile
+++ b/drivers/media/dvb/ttpci/Makefile
@@ -19,12 +19,3 @@ obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
EXTRA_CFLAGS += -Idrivers/media/common/tuners
-
-hostprogs-y := fdump
-
-ifeq ($(CONFIG_DVB_AV7110_FIRMWARE),y)
-$(obj)/av7110.o: $(obj)/av7110_firm.h
-
-$(obj)/av7110_firm.h: $(obj)/fdump
- $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@
-endif
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 4624cee93e7..d1d959ed37b 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -1518,20 +1518,6 @@ static int check_firmware(struct av7110* av7110)
return 0;
}
-#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE
-#include "av7110_firm.h"
-static void put_firmware(struct av7110* av7110)
-{
- av7110->bin_fw = NULL;
-}
-
-static inline int get_firmware(struct av7110* av7110)
-{
- av7110->bin_fw = dvb_ttpci_fw;
- av7110->size_fw = sizeof(dvb_ttpci_fw);
- return check_firmware(av7110);
-}
-#else
static void put_firmware(struct av7110* av7110)
{
vfree(av7110->bin_fw);
@@ -1580,8 +1566,6 @@ static int get_firmware(struct av7110* av7110)
release_firmware(fw);
return ret;
}
-#endif
-
static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
{
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 3a3f5279e92..5e3f88911a1 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -198,29 +198,10 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len)
/* we cannot write av7110 DRAM directly, so load a bootloader into
* the DPRAM which implements a simple boot protocol */
-static u8 bootcode[] = {
- 0xea, 0x00, 0x00, 0x0e, 0xe1, 0xb0, 0xf0, 0x0e, 0xe2, 0x5e, 0xf0, 0x04,
- 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x08, 0xe2, 0x5e, 0xf0, 0x04,
- 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x04, 0x2c, 0x00, 0x00, 0x24,
- 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0xa5, 0xa5, 0x5a, 0x5a, 0x00, 0x1f, 0x15, 0x55,
- 0x00, 0x00, 0x00, 0x09, 0xe5, 0x9f, 0xd0, 0x7c, 0xe5, 0x9f, 0x40, 0x74,
- 0xe3, 0xa0, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x04,
- 0xe5, 0x9f, 0x10, 0x70, 0xe5, 0x9f, 0x20, 0x70, 0xe5, 0x9f, 0x30, 0x64,
- 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, 0xe1, 0x51, 0x00, 0x02,
- 0xda, 0xff, 0xff, 0xfb, 0xe5, 0x9f, 0xf0, 0x50, 0xe1, 0xd4, 0x10, 0xb0,
- 0xe3, 0x51, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xfc, 0xe1, 0xa0, 0x10, 0x0d,
- 0xe5, 0x94, 0x30, 0x04, 0xe1, 0xd4, 0x20, 0xb2, 0xe2, 0x82, 0x20, 0x3f,
- 0xe1, 0xb0, 0x23, 0x22, 0x03, 0xa0, 0x00, 0x02, 0xe1, 0xc4, 0x00, 0xb0,
- 0x0a, 0xff, 0xff, 0xf4, 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0,
- 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, 0xe2, 0x52, 0x20, 0x01,
- 0x1a, 0xff, 0xff, 0xf9, 0xe2, 0x2d, 0xdb, 0x05, 0xea, 0xff, 0xff, 0xec,
- 0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x04, 0x00, 0x9e, 0x00, 0x08, 0x00,
- 0x2c, 0x00, 0x00, 0x74, 0x2c, 0x00, 0x00, 0xc0
-};
-
int av7110_bootarm(struct av7110 *av7110)
{
+ const struct firmware *fw;
+ const char *fw_name = "av7110/bootcode.bin";
struct saa7146_dev *dev = av7110->dev;
u32 ret;
int i;
@@ -261,7 +242,15 @@ int av7110_bootarm(struct av7110 *av7110)
//saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT);
//saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);
- mwdebi(av7110, DEBISWAB, DPRAM_BASE, bootcode, sizeof(bootcode));
+ ret = request_firmware(&fw, fw_name, &dev->pci->dev);
+ if (ret) {
+ printk(KERN_ERR "dvb-ttpci: Failed to load firmware \"%s\"\n",
+ fw_name);
+ return ret;
+ }
+
+ mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size);
+ release_firmware(fw);
iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
@@ -302,7 +291,7 @@ int av7110_bootarm(struct av7110 *av7110)
av7110->arm_ready = 1;
return 0;
}
-
+MODULE_FIRMWARE("av7110/bootcode.bin");
/****************************************************************************
* DEBI command polling
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
index ca99e5c1fc8..1634aba5cb8 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.h
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -390,7 +390,8 @@ static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val,
}
/* buffer writes */
-static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, u8 *val, int count)
+static inline void mwdebi(struct av7110 *av7110, u32 config, int addr,
+ const u8 *val, int count)
{
memcpy(av7110->debi_virt, val, count);
av7110_debiwrite(av7110, config, addr, 0, count);
diff --git a/drivers/media/dvb/ttpci/fdump.c b/drivers/media/dvb/ttpci/fdump.c
deleted file mode 100644
index c90001d35e7..00000000000
--- a/drivers/media/dvb/ttpci/fdump.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-int main(int argc, char **argv)
-{
- unsigned char buf[8];
- unsigned int i, count, bytes = 0;
- FILE *fd_in, *fd_out;
-
- if (argc != 4) {
- fprintf(stderr, "\n\tusage: %s <ucode.bin> <array_name> <output_name>\n\n", argv[0]);
- return -1;
- }
-
- fd_in = fopen(argv[1], "rb");
- if (fd_in == NULL) {
- fprintf(stderr, "firmware file '%s' not found\n", argv[1]);
- return -1;
- }
-
- fd_out = fopen(argv[3], "w+");
- if (fd_out == NULL) {
- fprintf(stderr, "cannot create output file '%s'\n", argv[3]);
- return -1;
- }
-
- fprintf(fd_out, "\n#include <asm/types.h>\n\nu8 %s [] = {", argv[2]);
-
- while ((count = fread(buf, 1, 8, fd_in)) > 0) {
- fprintf(fd_out, "\n\t");
- for (i = 0; i < count; i++, bytes++)
- fprintf(fd_out, "0x%02x, ", buf[i]);
- }
-
- fprintf(fd_out, "\n};\n\n");
-
- fclose(fd_in);
- fclose(fd_out);
-
- return 0;
-}
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index cc54ed4efc4..61357620229 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -33,6 +33,9 @@
History:
+ Version 0.45:
+ Converted to v4l2_device.
+
Version 0.44:
Add suspend/resume functions, fix unplug of device,
a lot of cleanups and fixes by Alexey Klimov <klimov.linux@gmail.com>
@@ -88,7 +91,7 @@
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <linux/usb.h>
@@ -97,39 +100,8 @@
*/
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define DRIVER_VERSION "v0.44"
-#define RADIO_VERSION KERNEL_VERSION(0, 4, 4)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },
-/* HINT: the disabled controls are only here to satify kradio and such apps */
- { .id = V4L2_CID_AUDIO_VOLUME,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- {
- .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_LOUDNESS,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
-};
+#define DRIVER_VERSION "v0.45"
+#define RADIO_VERSION KERNEL_VERSION(0, 4, 5)
#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
#define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver"
@@ -167,6 +139,8 @@ module_param(radio_nr, int, 0);
struct dsbr100_device {
struct usb_device *usbdev;
struct video_device videodev;
+ struct v4l2_device v4l2_dev;
+
u8 *transfer_buffer;
struct mutex lock; /* buffer locking */
int curfreq;
@@ -384,6 +358,7 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
mutex_unlock(&radio->lock);
video_unregister_device(&radio->videodev);
+ v4l2_device_disconnect(&radio->v4l2_dev);
}
@@ -479,14 +454,11 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
}
+
return -EINVAL;
}
@@ -656,6 +628,7 @@ static void usb_dsbr100_video_device_release(struct video_device *videodev)
{
struct dsbr100_device *radio = videodev_to_radio(videodev);
+ v4l2_device_unregister(&radio->v4l2_dev);
kfree(radio->transfer_buffer);
kfree(radio);
}
@@ -683,22 +656,15 @@ static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
.vidioc_s_input = vidioc_s_input,
};
-/* V4L2 interface */
-static struct video_device dsbr100_videodev_data = {
- .name = "D-Link DSB-R 100",
- .fops = &usb_dsbr100_fops,
- .ioctl_ops = &usb_dsbr100_ioctl_ops,
- .release = usb_dsbr100_video_device_release,
-};
-
/* check if the device is present and register with v4l and usb if it is */
static int usb_dsbr100_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct dsbr100_device *radio;
+ struct v4l2_device *v4l2_dev;
int retval;
- radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL);
+ radio = kzalloc(sizeof(struct dsbr100_device), GFP_KERNEL);
if (!radio)
return -ENOMEM;
@@ -710,17 +676,35 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
return -ENOMEM;
}
+ v4l2_dev = &radio->v4l2_dev;
+
+ retval = v4l2_device_register(&intf->dev, v4l2_dev);
+ if (retval < 0) {
+ v4l2_err(v4l2_dev, "couldn't register v4l2_device\n");
+ kfree(radio->transfer_buffer);
+ kfree(radio);
+ return retval;
+ }
+
+ strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name));
+ radio->videodev.v4l2_dev = v4l2_dev;
+ radio->videodev.fops = &usb_dsbr100_fops;
+ radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops;
+ radio->videodev.release = usb_dsbr100_video_device_release;
+
mutex_init(&radio->lock);
- radio->videodev = dsbr100_videodev_data;
radio->removed = 0;
radio->users = 0;
radio->usbdev = interface_to_usbdev(intf);
radio->curfreq = FREQ_MIN * FREQ_MUL;
+
video_set_drvdata(&radio->videodev, radio);
+
retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr);
if (retval < 0) {
- dev_err(&intf->dev, "couldn't register video device\n");
+ v4l2_err(v4l2_dev, "couldn't register video device\n");
+ v4l2_device_unregister(v4l2_dev);
kfree(radio->transfer_buffer);
kfree(radio);
return -EIO;
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index ac82e33cb6f..35edee009ba 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -355,20 +355,8 @@ static int vidioc_s_audio(struct file *file, void *priv,
return a->index ? -EINVAL : 0;
}
-static int rtrack_open(struct file *file)
-{
- return 0;
-}
-
-static int rtrack_release(struct file *file)
-{
- return 0;
-}
-
static const struct v4l2_file_operations rtrack_fops = {
.owner = THIS_MODULE,
- .open = rtrack_open,
- .release = rtrack_release,
.ioctl = video_ioctl2,
};
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 49299f7fd83..8daf809eb01 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -318,20 +318,8 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
return -EINVAL;
}
-static int aztech_open(struct file *file)
-{
- return 0;
-}
-
-static int aztech_release(struct file *file)
-{
- return 0;
-}
-
static const struct v4l2_file_operations aztech_fops = {
.owner = THIS_MODULE,
- .open = aztech_open,
- .release = aztech_release,
.ioctl = video_ioctl2,
};
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 09265d25725..c3f579de6e7 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -356,20 +356,8 @@ static struct pci_device_id gemtek_pci_id[] =
MODULE_DEVICE_TABLE(pci, gemtek_pci_id);
-static int gemtek_pci_open(struct file *file)
-{
- return 0;
-}
-
-static int gemtek_pci_release(struct file *file)
-{
- return 0;
-}
-
static const struct v4l2_file_operations gemtek_pci_fops = {
.owner = THIS_MODULE,
- .open = gemtek_pci_open,
- .release = gemtek_pci_release,
.ioctl = video_ioctl2,
};
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 150464426d1..73985f641f0 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -375,20 +375,9 @@ static int gemtek_probe(struct gemtek *gt)
/*
* Video 4 Linux stuff.
*/
-static int gemtek_open(struct file *file)
-{
- return 0;
-}
-
-static int gemtek_release(struct file *file)
-{
- return 0;
-}
static const struct v4l2_file_operations gemtek_fops = {
.owner = THIS_MODULE,
- .open = gemtek_open,
- .release = gemtek_release,
.ioctl = video_ioctl2,
};
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index 01a6d22950a..64d737c35ac 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -292,20 +292,8 @@ static int vidioc_s_audio(struct file *file, void *priv,
return a->index ? -EINVAL : 0;
}
-static int maestro_open(struct file *file)
-{
- return 0;
-}
-
-static int maestro_release(struct file *file)
-{
- return 0;
-}
-
static const struct v4l2_file_operations maestro_fops = {
.owner = THIS_MODULE,
- .open = maestro_open,
- .release = maestro_release,
.ioctl = video_ioctl2,
};
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 2606f0b3035..3da51fe8fb9 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -339,20 +339,8 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
return -EINVAL;
}
-static int maxiradio_open(struct file *file)
-{
- return 0;
-}
-
-static int maxiradio_release(struct file *file)
-{
- return 0;
-}
-
static const struct v4l2_file_operations maxiradio_fops = {
.owner = THIS_MODULE,
- .open = maxiradio_open,
- .release = maxiradio_release,
.ioctl = video_ioctl2,
};
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index ded25bfb366..cab19d05e02 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -43,6 +43,7 @@
* Douglas Schilling Landgraf <dougsland@gmail.com> and
* David Ellingsworth <david@identd.dyndns.org>
* for discussion, help and support.
+ * Version 0.11: Converted to v4l2_device.
*
* Many things to do:
* - Correct power managment of device (suspend & resume)
@@ -59,7 +60,7 @@
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <linux/usb.h>
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
@@ -67,8 +68,8 @@
/* driver and module definitions */
#define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>"
#define DRIVER_DESC "AverMedia MR 800 USB FM radio driver"
-#define DRIVER_VERSION "0.10"
-#define RADIO_VERSION KERNEL_VERSION(0, 1, 0)
+#define DRIVER_VERSION "0.11"
+#define RADIO_VERSION KERNEL_VERSION(0, 1, 1)
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
@@ -113,38 +114,6 @@ static int radio_nr = -1;
module_param(radio_nr, int, 0);
MODULE_PARM_DESC(radio_nr, "Radio Nr");
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },
-/* HINT: the disabled controls are only here to satify kradio and such apps */
- { .id = V4L2_CID_AUDIO_VOLUME,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- {
- .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_LOUDNESS,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
-};
-
static int usb_amradio_probe(struct usb_interface *intf,
const struct usb_device_id *id);
static void usb_amradio_disconnect(struct usb_interface *intf);
@@ -159,6 +128,7 @@ struct amradio_device {
/* reference to USB and video device */
struct usb_device *usbdev;
struct video_device *videodev;
+ struct v4l2_device v4l2_dev;
unsigned char *buffer;
struct mutex lock; /* buffer locking */
@@ -329,6 +299,7 @@ static void usb_amradio_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
video_unregister_device(radio->videodev);
+ v4l2_device_disconnect(&radio->v4l2_dev);
}
/* vidioc_querycap - query device capabilities */
@@ -463,14 +434,11 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
}
+
return -EINVAL;
}
@@ -671,34 +639,29 @@ static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
.vidioc_s_input = vidioc_s_input,
};
-static void usb_amradio_device_release(struct video_device *videodev)
+static void usb_amradio_video_device_release(struct video_device *videodev)
{
struct amradio_device *radio = video_get_drvdata(videodev);
/* we call v4l to free radio->videodev */
video_device_release(videodev);
+ v4l2_device_unregister(&radio->v4l2_dev);
+
/* free rest memory */
kfree(radio->buffer);
kfree(radio);
}
-/* V4L2 interface */
-static struct video_device amradio_videodev_template = {
- .name = "AverMedia MR 800 USB FM Radio",
- .fops = &usb_amradio_fops,
- .ioctl_ops = &usb_amradio_ioctl_ops,
- .release = usb_amradio_device_release,
-};
-
/* check if the device is present and register with v4l and usb if it is */
static int usb_amradio_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct amradio_device *radio;
+ struct v4l2_device *v4l2_dev;
int retval;
- radio = kmalloc(sizeof(struct amradio_device), GFP_KERNEL);
+ radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL);
if (!radio) {
dev_err(&intf->dev, "kmalloc for amradio_device failed\n");
@@ -713,6 +676,15 @@ static int usb_amradio_probe(struct usb_interface *intf,
return -ENOMEM;
}
+ v4l2_dev = &radio->v4l2_dev;
+ retval = v4l2_device_register(&intf->dev, v4l2_dev);
+ if (retval < 0) {
+ dev_err(&intf->dev, "couldn't register v4l2_device\n");
+ kfree(radio->buffer);
+ kfree(radio);
+ return retval;
+ }
+
radio->videodev = video_device_alloc();
if (!radio->videodev) {
@@ -722,8 +694,11 @@ static int usb_amradio_probe(struct usb_interface *intf,
return -ENOMEM;
}
- memcpy(radio->videodev, &amradio_videodev_template,
- sizeof(amradio_videodev_template));
+ strlcpy(radio->videodev->name, v4l2_dev->name, sizeof(radio->videodev->name));
+ radio->videodev->v4l2_dev = v4l2_dev;
+ radio->videodev->fops = &usb_amradio_fops;
+ radio->videodev->ioctl_ops = &usb_amradio_ioctl_ops;
+ radio->videodev->release = usb_amradio_video_device_release;
radio->removed = 0;
radio->users = 0;
@@ -734,10 +709,12 @@ static int usb_amradio_probe(struct usb_interface *intf,
mutex_init(&radio->lock);
video_set_drvdata(radio->videodev, radio);
+
retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
if (retval < 0) {
dev_err(&intf->dev, "could not register video device\n");
video_device_release(radio->videodev);
+ v4l2_device_unregister(v4l2_dev);
kfree(radio->buffer);
kfree(radio);
return -EIO;
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index d1e6b01d4ec..9cb193fa6e3 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -260,20 +260,8 @@ static int vidioc_s_audio(struct file *file, void *priv,
return a->index ? -EINVAL : 0;
}
-static int rtrack2_open(struct file *file)
-{
- return 0;
-}
-
-static int rtrack2_release(struct file *file)
-{
- return 0;
-}
-
static const struct v4l2_file_operations rtrack2_fops = {
.owner = THIS_MODULE,
- .open = rtrack2_open,
- .release = rtrack2_release,
.ioctl = video_ioctl2,
};
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index f4784f0d1a8..1dba8f0832a 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -260,20 +260,8 @@ static int vidioc_s_audio(struct file *file, void *priv,
return a->index ? -EINVAL : 0;
}
-static int fmi_open(struct file *file)
-{
- return 0;
-}
-
-static int fmi_release(struct file *file)
-{
- return 0;
-}
-
static const struct v4l2_file_operations fmi_fops = {
.owner = THIS_MODULE,
- .open = fmi_open,
- .release = fmi_release,
.ioctl = video_ioctl2,
};
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 0ba9d88a80f..c09ca8600ea 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -377,20 +377,8 @@ static int vidioc_s_audio(struct file *file, void *priv,
return a->index ? -EINVAL : 0;
}
-static int fmr2_open(struct file *file)
-{
- return 0;
-}
-
-static int fmr2_release(struct file *file)
-{
- return 0;
-}
-
static const struct v4l2_file_operations fmr2_fops = {
.owner = THIS_MODULE,
- .open = fmr2_open,
- .release = fmr2_release,
.ioctl = video_ioctl2,
};
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index 713e242ba8b..92c297796a9 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -1686,7 +1686,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
/* show some infos about the specific si470x device */
if (si470x_get_all_registers(radio) < 0) {
retval = -EIO;
- goto err_all;
+ goto err_video;
}
printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
radio->registers[DEVICEID], radio->registers[CHIPID]);
@@ -1694,7 +1694,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
/* get software and hardware versions */
if (si470x_get_scratch_page_versions(radio) < 0) {
retval = -EIO;
- goto err_all;
+ goto err_video;
}
printk(KERN_INFO DRIVER_NAME
": software version %d, hardware version %d\n",
@@ -1727,7 +1727,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
if (!radio->buffer) {
retval = -EIO;
- goto err_all;
+ goto err_video;
}
/* rds buffer configuration */
@@ -1749,8 +1749,9 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
return 0;
err_all:
- video_device_release(radio->videodev);
kfree(radio->buffer);
+err_video:
+ video_device_release(radio->videodev);
err_radio:
kfree(radio);
err_initial:
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index 5b007f5c74b..699db9acaaf 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -332,20 +332,8 @@ static int vidioc_s_audio(struct file *file, void *priv,
return a->index ? -EINVAL : 0;
}
-static int terratec_open(struct file *file)
-{
- return 0;
-}
-
-static int terratec_release(struct file *file)
-{
- return 0;
-}
-
static const struct v4l2_file_operations terratec_fops = {
.owner = THIS_MODULE,
- .open = terratec_open,
- .release = terratec_release,
.ioctl = video_ioctl2,
};
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index d1be6492a07..6f9ecc35935 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -338,20 +338,8 @@ static int vidioc_s_audio(struct file *file, void *priv,
return a->index ? -EINVAL : 0;
}
-static int trust_open(struct file *file)
-{
- return 0;
-}
-
-static int trust_release(struct file *file)
-{
- return 0;
-}
-
static const struct v4l2_file_operations trust_fops = {
.owner = THIS_MODULE,
- .open = trust_open,
- .release = trust_release,
.ioctl = video_ioctl2,
};
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index 92d923c7f36..3a98f139949 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -314,20 +314,8 @@ static int vidioc_log_status(struct file *file, void *priv)
return 0;
}
-static int typhoon_open(struct file *file)
-{
- return 0;
-}
-
-static int typhoon_release(struct file *file)
-{
- return 0;
-}
-
static const struct v4l2_file_operations typhoon_fops = {
.owner = THIS_MODULE,
- .open = typhoon_open,
- .release = typhoon_release,
.ioctl = video_ioctl2,
};
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 1f85f2024dc..80e98b6422f 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -370,21 +370,9 @@ static int vidioc_s_audio(struct file *file, void *priv,
return a->index ? -EINVAL : 0;
}
-static int zoltrix_open(struct file *file)
-{
- return 0;
-}
-
-static int zoltrix_release(struct file *file)
-{
- return 0;
-}
-
static const struct v4l2_file_operations zoltrix_fops =
{
.owner = THIS_MODULE,
- .open = zoltrix_open,
- .release = zoltrix_release,
.ioctl = video_ioctl2,
};
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 76bad581959..9d48da2fb01 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -746,6 +746,18 @@ config SOC_CAMERA_OV772X
help
This is a ov772x camera driver
+config MX1_VIDEO
+ bool
+
+config VIDEO_MX1
+ tristate "i.MX1/i.MXL CMOS Sensor Interface driver"
+ depends on VIDEO_DEV && ARCH_MX1 && SOC_CAMERA
+ select FIQ
+ select VIDEOBUF_DMA_CONTIG
+ select MX1_VIDEO
+ ---help---
+ This is a v4l2 driver for the i.MX1/i.MXL CMOS Sensor Interface
+
config VIDEO_MX3
tristate "i.MX3x Camera Sensor Interface driver"
depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
@@ -795,6 +807,8 @@ source "drivers/media/video/hdpvr/Kconfig"
source "drivers/media/video/em28xx/Kconfig"
+source "drivers/media/video/cx231xx/Kconfig"
+
source "drivers/media/video/usbvision/Kconfig"
source "drivers/media/video/usbvideo/Kconfig"
@@ -904,5 +918,4 @@ config USB_S2255
This driver can be compiled as a module, called s2255drv.
endif # V4L_USB_DRIVERS
-
endif # VIDEO_CAPTURE_DRIVERS
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index b9046744463..3f1a0350a56 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -10,7 +10,7 @@ stkwebcam-objs := stk-webcam.o stk-sensor.o
omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
-videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-subdev.o
+videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o
obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o
ifeq ($(CONFIG_COMPAT),y)
@@ -67,6 +67,7 @@ obj-$(CONFIG_VIDEO_MEYE) += meye.o
obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
obj-$(CONFIG_VIDEO_CX88) += cx88/
obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
+obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
@@ -133,6 +134,7 @@ obj-$(CONFIG_VIDEO_CX18) += cx18/
obj-$(CONFIG_VIDEO_VIVI) += vivi.o
obj-$(CONFIG_VIDEO_CX23885) += cx23885/
+obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o
obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
index 873c30a41bd..97b003449c9 100644
--- a/drivers/media/video/adv7170.c
+++ b/drivers/media/video/adv7170.c
@@ -219,18 +219,19 @@ static int adv7170_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
return 0;
}
-static int adv7170_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int adv7170_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct adv7170 *encoder = to_adv7170(sd);
- /* RJ: route->input = 0: input is from decoder
- route->input = 1: input is from ZR36060
- route->input = 2: color bar */
+ /* RJ: input = 0: input is from decoder
+ input = 1: input is from ZR36060
+ input = 2: color bar */
v4l2_dbg(1, debug, sd, "set input from %s\n",
- route->input == 0 ? "decoder" : "ZR36060");
+ input == 0 ? "decoder" : "ZR36060");
- switch (route->input) {
+ switch (input) {
case 0:
adv7170_write(sd, 0x01, 0x20);
adv7170_write(sd, 0x08, TR1CAPT); /* TR1 */
@@ -250,11 +251,11 @@ static int adv7170_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *
break;
default:
- v4l2_dbg(1, debug, sd, "illegal input: %d\n", route->input);
+ v4l2_dbg(1, debug, sd, "illegal input: %d\n", input);
return -EINVAL;
}
- v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[route->input]);
- encoder->input = route->input;
+ v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[input]);
+ encoder->input = input;
return 0;
}
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
index ff121030329..cf8c06c85de 100644
--- a/drivers/media/video/adv7175.c
+++ b/drivers/media/video/adv7175.c
@@ -237,15 +237,16 @@ static int adv7175_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
return 0;
}
-static int adv7175_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int adv7175_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct adv7175 *encoder = to_adv7175(sd);
- /* RJ: route->input = 0: input is from decoder
- route->input = 1: input is from ZR36060
- route->input = 2: color bar */
+ /* RJ: input = 0: input is from decoder
+ input = 1: input is from ZR36060
+ input = 2: color bar */
- switch (route->input) {
+ switch (input) {
case 0:
adv7175_write(sd, 0x01, 0x00);
@@ -288,11 +289,11 @@ static int adv7175_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *
break;
default:
- v4l2_dbg(1, debug, sd, "illegal input: %d\n", route->input);
+ v4l2_dbg(1, debug, sd, "illegal input: %d\n", input);
return -EINVAL;
}
- v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[route->input]);
- encoder->input = route->input;
+ v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[input]);
+ encoder->input = input;
return 0;
}
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
index 05cdf494dfb..0c3a5ba0e85 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/video/au0828/Kconfig
@@ -4,6 +4,7 @@ config VIDEO_AU0828
depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2
select I2C_ALGOBIT
select VIDEO_TVEEPROM
+ select VIDEOBUF_VMALLOC
select DVB_AU8522 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 1aabaa7e55b..053bbe8c8e3 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -46,6 +46,7 @@ struct au0828_board au0828_boards[] = {
.name = "Hauppauge HVR850",
.tuner_type = TUNER_XC5000,
.tuner_addr = 0x61,
+ .i2c_clk_divider = AU0828_I2C_CLK_30KHZ,
.input = {
{
.type = AU0828_VMUX_TELEVISION,
@@ -70,6 +71,13 @@ struct au0828_board au0828_boards[] = {
.name = "Hauppauge HVR950Q",
.tuner_type = TUNER_XC5000,
.tuner_addr = 0x61,
+ /* The au0828 hardware i2c implementation does not properly
+ support the xc5000's i2c clock stretching. So we need to
+ lower the clock frequency enough where the 15us clock
+ stretch fits inside of a normal clock cycle, or else the
+ au0828 fails to set the STOP bit. A 30 KHz clock puts the
+ clock pulse width at 18us */
+ .i2c_clk_divider = AU0828_I2C_CLK_30KHZ,
.input = {
{
.type = AU0828_VMUX_TELEVISION,
@@ -94,16 +102,19 @@ struct au0828_board au0828_boards[] = {
.name = "Hauppauge HVR950Q rev xxF8",
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
+ .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
},
[AU0828_BOARD_DVICO_FUSIONHDTV7] = {
.name = "DViCO FusionHDTV USB",
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
+ .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
},
[AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
.name = "Hauppauge Woodbury",
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
+ .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
},
};
@@ -200,8 +211,8 @@ void au0828_card_setup(struct au0828_dev *dev)
/* Load the analog demodulator driver (note this would need to
be abstracted out if we ever need to support a different
demod) */
- sd = v4l2_i2c_new_subdev(&dev->i2c_adap, "au8522", "au8522",
- 0x8e >> 1);
+ sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "au8522", "au8522", 0x8e >> 1);
if (sd == NULL)
printk(KERN_ERR "analog subdev registration failed\n");
}
@@ -209,8 +220,8 @@ void au0828_card_setup(struct au0828_dev *dev)
/* Setup tuners */
if (dev->board.tuner_type != TUNER_ABSENT) {
/* Load the tuner module, which does the attach */
- sd = v4l2_i2c_new_subdev(&dev->i2c_adap, "tuner", "tuner",
- dev->board.tuner_addr);
+ sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "tuner", "tuner", dev->board.tuner_addr);
if (sd == NULL)
printk(KERN_ERR "tuner subdev registration fail\n");
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
index 8c761d16444..4cee0b92eee 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/video/au0828/au0828-core.c
@@ -36,8 +36,6 @@ int au0828_debug;
module_param_named(debug, au0828_debug, int, 0644);
MODULE_PARM_DESC(debug, "enable debug messages");
-static atomic_t au0828_instance = ATOMIC_INIT(0);
-
#define _AU0828_BULKPIPE 0x03
#define _BULKPIPESIZE 0xffff
@@ -169,7 +167,7 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
static int au0828_usb_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
- int ifnum, retval, i;
+ int ifnum, retval;
struct au0828_dev *dev;
struct usb_device *usbdev = interface_to_usbdev(interface);
@@ -197,10 +195,7 @@ static int au0828_usb_probe(struct usb_interface *interface,
usb_set_intfdata(interface, dev);
/* Create the v4l2_device */
- i = atomic_inc_return(&au0828_instance) - 1;
- snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s-%03d",
- "au0828", i);
- retval = v4l2_device_register(&dev->usbdev->dev, &dev->v4l2_dev);
+ retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
if (retval) {
printk(KERN_ERR "%s() v4l2_device_register failed\n",
__func__);
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c
index f9a958d0aef..13e494365e7 100644
--- a/drivers/media/video/au0828/au0828-i2c.c
+++ b/drivers/media/video/au0828/au0828-i2c.c
@@ -39,13 +39,15 @@ MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
static inline int i2c_slave_did_write_ack(struct i2c_adapter *i2c_adap)
{
struct au0828_dev *dev = i2c_adap->algo_data;
- return au0828_read(dev, REG_201) & 0x08 ? 0 : 1;
+ return au0828_read(dev, AU0828_I2C_STATUS_201) &
+ AU0828_I2C_STATUS_NO_WRITE_ACK ? 0 : 1;
}
static inline int i2c_slave_did_read_ack(struct i2c_adapter *i2c_adap)
{
struct au0828_dev *dev = i2c_adap->algo_data;
- return au0828_read(dev, REG_201) & 0x02 ? 0 : 1;
+ return au0828_read(dev, AU0828_I2C_STATUS_201) &
+ AU0828_I2C_STATUS_NO_READ_ACK ? 0 : 1;
}
static int i2c_wait_read_ack(struct i2c_adapter *i2c_adap)
@@ -67,7 +69,8 @@ static int i2c_wait_read_ack(struct i2c_adapter *i2c_adap)
static inline int i2c_is_read_busy(struct i2c_adapter *i2c_adap)
{
struct au0828_dev *dev = i2c_adap->algo_data;
- return au0828_read(dev, REG_201) & 0x01 ? 0 : 1;
+ return au0828_read(dev, AU0828_I2C_STATUS_201) &
+ AU0828_I2C_STATUS_READ_DONE ? 0 : 1;
}
static int i2c_wait_read_done(struct i2c_adapter *i2c_adap)
@@ -89,7 +92,8 @@ static int i2c_wait_read_done(struct i2c_adapter *i2c_adap)
static inline int i2c_is_write_done(struct i2c_adapter *i2c_adap)
{
struct au0828_dev *dev = i2c_adap->algo_data;
- return au0828_read(dev, REG_201) & 0x04 ? 1 : 0;
+ return au0828_read(dev, AU0828_I2C_STATUS_201) &
+ AU0828_I2C_STATUS_WRITE_DONE ? 1 : 0;
}
static int i2c_wait_write_done(struct i2c_adapter *i2c_adap)
@@ -111,7 +115,8 @@ static int i2c_wait_write_done(struct i2c_adapter *i2c_adap)
static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
{
struct au0828_dev *dev = i2c_adap->algo_data;
- return au0828_read(dev, REG_201) & 0x10 ? 1 : 0;
+ return au0828_read(dev, AU0828_I2C_STATUS_201) &
+ AU0828_I2C_STATUS_BUSY ? 1 : 0;
}
static int i2c_wait_done(struct i2c_adapter *i2c_adap)
@@ -139,19 +144,14 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
dprintk(4, "%s()\n", __func__);
- au0828_write(dev, REG_2FF, 0x01);
+ au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
- /* FIXME: There is a problem with i2c communications with xc5000 that
- requires us to slow down the i2c clock until we have a better
- strategy (such as using the secondary i2c bus to do firmware
- loading */
- if ((msg->addr << 1) == 0xc2)
- au0828_write(dev, REG_202, 0x40);
- else
- au0828_write(dev, REG_202, 0x07);
+ /* Set the I2C clock */
+ au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
+ dev->board.i2c_clk_divider);
/* Hardware needs 8 bit addresses */
- au0828_write(dev, REG_203, msg->addr << 1);
+ au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
dprintk(4, "SEND: %02x\n", msg->addr);
@@ -163,7 +163,9 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
actual bytes to the bus, just do a read check. This is
consistent with how I saw i2c device checking done in the
USB trace of the Windows driver */
- au0828_write(dev, REG_200, 0x20);
+ au0828_write(dev, AU0828_I2C_TRIGGER_200,
+ AU0828_I2C_TRIGGER_READ);
+
if (!i2c_wait_done(i2c_adap))
return -EIO;
@@ -177,7 +179,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
dprintk(4, " %02x\n", msg->buf[i]);
- au0828_write(dev, REG_205, msg->buf[i]);
+ au0828_write(dev, AU0828_I2C_WRITE_FIFO_205, msg->buf[i]);
strobe++;
i++;
@@ -186,9 +188,12 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
/* Strobe the byte into the bus */
if (i < msg->len)
- au0828_write(dev, REG_200, 0x41);
+ au0828_write(dev, AU0828_I2C_TRIGGER_200,
+ AU0828_I2C_TRIGGER_WRITE |
+ AU0828_I2C_TRIGGER_HOLD);
else
- au0828_write(dev, REG_200, 0x01);
+ au0828_write(dev, AU0828_I2C_TRIGGER_200,
+ AU0828_I2C_TRIGGER_WRITE);
/* Reset strobe trigger */
strobe = 0;
@@ -216,25 +221,22 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
dprintk(4, "%s()\n", __func__);
- au0828_write(dev, REG_2FF, 0x01);
+ au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
- /* FIXME: There is a problem with i2c communications with xc5000 that
- requires us to slow down the i2c clock until we have a better
- strategy (such as using the secondary i2c bus to do firmware
- loading */
- if ((msg->addr << 1) == 0xc2)
- au0828_write(dev, REG_202, 0x40);
- else
- au0828_write(dev, REG_202, 0x07);
+ /* Set the I2C clock */
+ au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
+ dev->board.i2c_clk_divider);
/* Hardware needs 8 bit addresses */
- au0828_write(dev, REG_203, msg->addr << 1);
+ au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
dprintk(4, " RECV:\n");
/* Deal with i2c_scan */
if (msg->len == 0) {
- au0828_write(dev, REG_200, 0x20);
+ au0828_write(dev, AU0828_I2C_TRIGGER_200,
+ AU0828_I2C_TRIGGER_READ);
+
if (i2c_wait_read_ack(i2c_adap))
return -EIO;
return 0;
@@ -245,14 +247,18 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
i++;
if (i < msg->len)
- au0828_write(dev, REG_200, 0x60);
+ au0828_write(dev, AU0828_I2C_TRIGGER_200,
+ AU0828_I2C_TRIGGER_READ |
+ AU0828_I2C_TRIGGER_HOLD);
else
- au0828_write(dev, REG_200, 0x20);
+ au0828_write(dev, AU0828_I2C_TRIGGER_200,
+ AU0828_I2C_TRIGGER_READ);
if (!i2c_wait_read_done(i2c_adap))
return -EIO;
- msg->buf[i-1] = au0828_read(dev, REG_209) & 0xff;
+ msg->buf[i-1] = au0828_read(dev, AU0828_I2C_READ_FIFO_209) &
+ 0xff;
dprintk(4, " %02x\n", msg->buf[i-1]);
}
diff --git a/drivers/media/video/au0828/au0828-reg.h b/drivers/media/video/au0828/au0828-reg.h
index b15e4a3b6fc..c39f3d2b721 100644
--- a/drivers/media/video/au0828/au0828-reg.h
+++ b/drivers/media/video/au0828/au0828-reg.h
@@ -30,15 +30,36 @@
#define AU0828_SENSORCTRL_100 0x100
#define AU0828_SENSORCTRL_VBI_103 0x103
-#define REG_200 0x200
-#define REG_201 0x201
-#define REG_202 0x202
-#define REG_203 0x203
-#define REG_205 0x205
-#define REG_209 0x209
-#define REG_2FF 0x2ff
+/* I2C registers */
+#define AU0828_I2C_TRIGGER_200 0x200
+#define AU0828_I2C_STATUS_201 0x201
+#define AU0828_I2C_CLK_DIVIDER_202 0x202
+#define AU0828_I2C_DEST_ADDR_203 0x203
+#define AU0828_I2C_WRITE_FIFO_205 0x205
+#define AU0828_I2C_READ_FIFO_209 0x209
+#define AU0828_I2C_MULTIBYTE_MODE_2FF 0x2ff
/* Audio registers */
#define AU0828_AUDIOCTRL_50C 0x50C
#define REG_600 0x600
+
+/*********************************************************************/
+/* Here are constants for values associated with the above registers */
+
+/* I2C Trigger (Reg 0x200) */
+#define AU0828_I2C_TRIGGER_WRITE 0x01
+#define AU0828_I2C_TRIGGER_READ 0x20
+#define AU0828_I2C_TRIGGER_HOLD 0x40
+
+/* I2C Status (Reg 0x201) */
+#define AU0828_I2C_STATUS_READ_DONE 0x01
+#define AU0828_I2C_STATUS_NO_READ_ACK 0x02
+#define AU0828_I2C_STATUS_WRITE_DONE 0x04
+#define AU0828_I2C_STATUS_NO_WRITE_ACK 0x08
+#define AU0828_I2C_STATUS_BUSY 0x10
+
+/* I2C Clock Divider (Reg 0x202) */
+#define AU0828_I2C_CLK_250KHZ 0x07
+#define AU0828_I2C_CLK_100KHZ 0x14
+#define AU0828_I2C_CLK_30KHZ 0x40
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index f7ad4958b94..27bedc6c779 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -1100,7 +1100,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
have to make the au0828 bridge adjust the size of its capture
buffer, which is currently hardcoded at 720x480 */
- v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_std, *norm);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, *norm);
return 0;
}
@@ -1154,7 +1154,6 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
struct au0828_fh *fh = priv;
struct au0828_dev *dev = fh->dev;
int i;
- struct v4l2_routing route;
dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __func__,
index);
@@ -1180,9 +1179,8 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
break;
}
- route.input = AUVI_INPUT(index).vmux;
- route.output = 0;
- v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, &route);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
+ AUVI_INPUT(index).vmux, 0, 0);
for (i = 0; i < AU0828_MAX_INPUT; i++) {
int enable = 0;
@@ -1205,8 +1203,8 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
}
}
- route.input = AUVI_INPUT(index).amux;
- v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, &route);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
+ AUVI_INPUT(index).amux, 0, 0);
return 0;
}
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index 6ed1a612973..b977915efbd 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -81,6 +81,7 @@ struct au0828_board {
char *name;
unsigned int tuner_type;
unsigned char tuner_addr;
+ unsigned char i2c_clk_divider;
struct au0828_input input[AU0828_MAX_INPUT];
};
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index df4516d8dca..f9330e3529c 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -292,21 +292,22 @@ static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
return 0;
}
-static int bt819_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int bt819_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct bt819 *decoder = to_bt819(sd);
- v4l2_dbg(1, debug, sd, "set input %x\n", route->input);
+ v4l2_dbg(1, debug, sd, "set input %x\n", input);
- if (route->input < 0 || route->input > 7)
+ if (input < 0 || input > 7)
return -EINVAL;
if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
v4l2_err(sd, "no notify found!\n");
- if (decoder->input != route->input) {
+ if (decoder->input != input) {
v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0);
- decoder->input = route->input;
+ decoder->input = input;
/* select mode */
if (decoder->input == 0) {
bt819_setbit(decoder, 0x0b, 6, 0);
@@ -444,9 +445,6 @@ static const struct v4l2_subdev_core_ops bt819_core_ops = {
.g_ctrl = bt819_g_ctrl,
.s_ctrl = bt819_s_ctrl,
.queryctrl = bt819_queryctrl,
-};
-
-static const struct v4l2_subdev_tuner_ops bt819_tuner_ops = {
.s_std = bt819_s_std,
};
@@ -459,7 +457,6 @@ static const struct v4l2_subdev_video_ops bt819_video_ops = {
static const struct v4l2_subdev_ops bt819_ops = {
.core = &bt819_core_ops,
- .tuner = &bt819_tuner_ops,
.video = &bt819_video_ops,
};
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
index 78db3950394..d0b4d4925ff 100644
--- a/drivers/media/video/bt856.c
+++ b/drivers/media/video/bt856.c
@@ -142,16 +142,17 @@ static int bt856_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
return 0;
}
-static int bt856_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int bt856_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct bt856 *encoder = to_bt856(sd);
- v4l2_dbg(1, debug, sd, "set input %d\n", route->input);
+ v4l2_dbg(1, debug, sd, "set input %d\n", input);
/* We only have video bus.
- * route->input= 0: input is from bt819
- * route->input= 1: input is from ZR36060 */
- switch (route->input) {
+ * input= 0: input is from bt819
+ * input= 1: input is from ZR36060 */
+ switch (input) {
case 0:
bt856_setbit(encoder, 0xde, 4, 0);
bt856_setbit(encoder, 0xde, 3, 1);
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
index 350cae4b02c..af7e3a5bac9 100644
--- a/drivers/media/video/bt866.c
+++ b/drivers/media/video/bt866.c
@@ -99,7 +99,8 @@ static int bt866_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
return 0;
}
-static int bt866_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int bt866_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
static const __u8 init[] = {
0xc8, 0xcc, /* CRSCALE */
@@ -137,7 +138,7 @@ static int bt866_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *ro
val = encoder->reg[0xdc];
- if (route->input == 0)
+ if (input == 0)
val |= 0x40; /* CBSWAP */
else
val &= ~0x40; /* !CBSWAP */
@@ -145,15 +146,15 @@ static int bt866_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *ro
bt866_write(encoder, 0xdc, val);
val = encoder->reg[0xcc];
- if (route->input == 2)
+ if (input == 2)
val |= 0x01; /* OSDBAR */
else
val &= ~0x01; /* !OSDBAR */
bt866_write(encoder, 0xcc, val);
- v4l2_dbg(1, debug, sd, "set input %d\n", route->input);
+ v4l2_dbg(1, debug, sd, "set input %d\n", input);
- switch (route->input) {
+ switch (input) {
case 0:
case 1:
case 2:
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index b9c3ba51fb8..fdb4adff3d2 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -3324,17 +3324,6 @@ void __devinit bttv_init_card1(struct bttv *btv)
/* initialization part two -- after registering i2c bus */
void __devinit bttv_init_card2(struct bttv *btv)
{
- static const unsigned short tvaudio_addrs[] = {
- I2C_ADDR_TDA8425 >> 1,
- I2C_ADDR_TEA6300 >> 1,
- I2C_ADDR_TEA6420 >> 1,
- I2C_ADDR_TDA9840 >> 1,
- I2C_ADDR_TDA985x_L >> 1,
- I2C_ADDR_TDA985x_H >> 1,
- I2C_ADDR_TDA9874 >> 1,
- I2C_ADDR_PIC16C54 >> 1,
- I2C_CLIENT_END
- };
int addr=ADDR_UNSET;
btv->tuner_type = UNSET;
@@ -3512,12 +3501,15 @@ void __devinit bttv_init_card2(struct bttv *btv)
/* Load tuner module before issuing tuner config call! */
if (bttv_tvcards[btv->c.type].has_radio)
- v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
- "tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_RADIO));
- v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, "tuner",
- "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
- v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, "tuner",
- "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
+ v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+ &btv->c.i2c_adap, "tuner", "tuner",
+ v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+ v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+ &btv->c.i2c_adap, "tuner", "tuner",
+ v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+ &btv->c.i2c_adap, "tuner", "tuner",
+ v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
tun_setup.type = btv->tuner_type;
@@ -3570,8 +3562,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
};
struct v4l2_subdev *sd;
- sd = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
- "saa6588", "saa6588", addrs);
+ sd = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+ &btv->c.i2c_adap, "saa6588", "saa6588", addrs);
btv->has_saa6588 = (sd != NULL);
}
@@ -3595,8 +3587,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
I2C_CLIENT_END
};
- btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
- "msp3400", "msp3400", addrs);
+ btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+ &btv->c.i2c_adap, "msp3400", "msp3400", addrs);
if (btv->sd_msp34xx)
return;
goto no_audio;
@@ -3609,16 +3601,16 @@ void __devinit bttv_init_card2(struct bttv *btv)
I2C_CLIENT_END
};
- if (v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
- "tda7432", "tda7432", addrs))
+ if (v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+ &btv->c.i2c_adap, "tda7432", "tda7432", addrs))
return;
goto no_audio;
}
case 3: {
/* The user specified that we should probe for tvaudio */
- btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
- "tvaudio", "tvaudio", tvaudio_addrs);
+ btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+ &btv->c.i2c_adap, "tvaudio", "tvaudio", tvaudio_addrs());
if (btv->sd_tvaudio)
return;
goto no_audio;
@@ -3637,21 +3629,13 @@ void __devinit bttv_init_card2(struct bttv *btv)
it really is a msp3400, so it will return NULL when the device
found is really something else (e.g. a tea6300). */
if (!bttv_tvcards[btv->c.type].no_msp34xx) {
- static const unsigned short addrs[] = {
- I2C_ADDR_MSP3400 >> 1,
- I2C_CLIENT_END
- };
-
- btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
- "msp3400", "msp3400", addrs);
+ btv->sd_msp34xx = v4l2_i2c_new_probed_subdev_addr(&btv->c.v4l2_dev,
+ &btv->c.i2c_adap, "msp3400", "msp3400",
+ I2C_ADDR_MSP3400 >> 1);
} else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
- static const unsigned short addrs[] = {
- I2C_ADDR_MSP3400_ALT >> 1,
- I2C_CLIENT_END
- };
-
- btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
- "msp3400", "msp3400", addrs);
+ btv->sd_msp34xx = v4l2_i2c_new_probed_subdev_addr(&btv->c.v4l2_dev,
+ &btv->c.i2c_adap, "msp3400", "msp3400",
+ I2C_ADDR_MSP3400_ALT >> 1);
}
/* If we found a msp34xx, then we're done. */
@@ -3665,14 +3649,14 @@ void __devinit bttv_init_card2(struct bttv *btv)
I2C_CLIENT_END
};
- if (v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
- "tda7432", "tda7432", addrs))
+ if (v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+ &btv->c.i2c_adap, "tda7432", "tda7432", addrs))
return;
}
/* Now see if we can find one of the tvaudio devices. */
- btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
- "tvaudio", "tvaudio", tvaudio_addrs);
+ btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+ &btv->c.i2c_adap, "tvaudio", "tvaudio", tvaudio_addrs());
if (btv->sd_tvaudio)
return;
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 7a8ca0d8356..23b7499b318 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -1198,7 +1198,7 @@ audio_mux(struct bttv *btv, int input, int mute)
ctrl.value = btv->mute;
bttv_call_all(btv, core, s_ctrl, &ctrl);
if (btv->sd_msp34xx) {
- struct v4l2_routing route;
+ u32 in;
/* Note: the inputs tuner/radio/extern/intern are translated
to msp routings. This assumes common behavior for all msp3400
@@ -1207,11 +1207,11 @@ audio_mux(struct bttv *btv, int input, int mute)
For now this is sufficient. */
switch (input) {
case TVAUDIO_INPUT_RADIO:
- route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
+ in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
break;
case TVAUDIO_INPUT_EXTERN:
- route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
+ in = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
break;
case TVAUDIO_INPUT_INTERN:
@@ -1220,7 +1220,7 @@ audio_mux(struct bttv *btv, int input, int mute)
input is the BTTV_BOARD_AVERMEDIA98. I wonder how
that was tested. My guess is that the whole INTERN
input does not work. */
- route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
+ in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
break;
case TVAUDIO_INPUT_TUNER:
@@ -1229,21 +1229,18 @@ audio_mux(struct bttv *btv, int input, int mute)
is the only difference between the VOODOOTV_FM
and VOODOOTV_200 */
if (btv->c.type == BTTV_BOARD_VOODOOTV_200)
- route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER2, \
+ in = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER2, \
MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER);
else
- route.input = MSP_INPUT_DEFAULT;
+ in = MSP_INPUT_DEFAULT;
break;
}
- route.output = MSP_OUTPUT_DEFAULT;
- v4l2_subdev_call(btv->sd_msp34xx, audio, s_routing, &route);
+ v4l2_subdev_call(btv->sd_msp34xx, audio, s_routing,
+ in, MSP_OUTPUT_DEFAULT, 0);
}
if (btv->sd_tvaudio) {
- struct v4l2_routing route;
-
- route.input = input;
- route.output = 0;
- v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing, &route);
+ v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing,
+ input, 0, 0);
}
return 0;
}
@@ -1329,7 +1326,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
break;
}
id = tvnorm->v4l2_id;
- bttv_call_all(btv, tuner, s_std, id);
+ bttv_call_all(btv, core, s_std, id);
return 0;
}
@@ -4320,7 +4317,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
btv->c.nr);
return -EIO;
}
- if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
btv->c.nr);
return -EIO;
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index 96498489199..a1d0e9c9f28 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -26,7 +26,7 @@
#define _BTTVP_H_
#include <linux/version.h>
-#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,17)
+#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,18)
#include <linux/types.h>
#include <linux/wait.h>
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 7abe94d9fb4..5f582726985 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -1954,7 +1954,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
goto out_freeirq;
cam->sensor_addr = 0x42;
- cam->sensor = v4l2_i2c_new_subdev(&cam->i2c_adapter,
+ cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, &cam->i2c_adapter,
"ov7670", "ov7670", cam->sensor_addr);
if (cam->sensor == NULL) {
ret = -ENODEV;
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 9714059ee94..57dc1704b6c 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -53,14 +53,15 @@ static inline int cs5345_read(struct v4l2_subdev *sd, u8 reg)
return i2c_smbus_read_byte_data(client, reg);
}
-static int cs5345_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int cs5345_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
- if ((route->input & 0xf) > 6) {
- v4l2_err(sd, "Invalid input %d.\n", route->input);
+ if ((input & 0xf) > 6) {
+ v4l2_err(sd, "Invalid input %d.\n", input);
return -EINVAL;
}
- cs5345_write(sd, 0x09, route->input & 0xf);
- cs5345_write(sd, 0x05, route->input & 0xf0);
+ cs5345_write(sd, 0x09, input & 0xf);
+ cs5345_write(sd, 0x05, input & 0xf0);
return 0;
}
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index 5aeb066857a..80bca8df9fb 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -58,17 +58,18 @@ static int cs53l32a_read(struct v4l2_subdev *sd, u8 reg)
return i2c_smbus_read_byte_data(client, reg);
}
-static int cs53l32a_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int cs53l32a_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
/* There are 2 physical inputs, but the second input can be
placed in two modes, the first mode bypasses the PGA (gain),
the second goes through the PGA. Hence there are three
possible inputs to choose from. */
- if (route->input > 2) {
- v4l2_err(sd, "Invalid input %d.\n", route->input);
+ if (input > 2) {
+ v4l2_err(sd, "Invalid input %d.\n", input);
return -EINVAL;
}
- cs53l32a_write(sd, 0x01, 0x01 + (route->input << 4));
+ cs53l32a_write(sd, 0x01, 0x01 + (input << 4));
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
index bb5c5165dd5..1519e91c677 100644
--- a/drivers/media/video/cx18/cx18-audio.c
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -33,7 +33,6 @@
int cx18_audio_set_io(struct cx18 *cx)
{
const struct cx18_card_audio_input *in;
- struct v4l2_routing route;
u32 val;
int err;
@@ -44,13 +43,11 @@ int cx18_audio_set_io(struct cx18 *cx)
in = &cx->card->audio_inputs[cx->audio_input];
/* handle muxer chips */
- route.input = in->muxer_input;
- route.output = 0;
- v4l2_subdev_call(cx->sd_extmux, audio, s_routing, &route);
+ v4l2_subdev_call(cx->sd_extmux, audio, s_routing,
+ in->audio_input, 0, 0);
- route.input = in->audio_input;
err = cx18_call_hw_err(cx, cx->card->hw_audio_ctrl,
- audio, s_routing, &route);
+ audio, s_routing, in->audio_input, 0, 0);
if (err)
return err;
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index f4dd9d78eb3..cf2bd888a42 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -203,43 +203,42 @@ static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
{
- struct cx18_av_state *state = to_cx18_av_state(sd);
struct cx18 *cx = v4l2_get_subdevdata(sd);
- switch (val) {
- case CX18_AV_INIT_PLLS:
- /*
- * The crystal freq used in calculations in this driver will be
- * 28.636360 MHz.
- * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
- */
+ /*
+ * The crystal freq used in calculations in this driver will be
+ * 28.636360 MHz.
+ * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
+ */
- /*
- * VDCLK Integer = 0x0f, Post Divider = 0x04
- * AIMCLK Integer = 0x0e, Post Divider = 0x16
- */
- cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
+ /*
+ * VDCLK Integer = 0x0f, Post Divider = 0x04
+ * AIMCLK Integer = 0x0e, Post Divider = 0x16
+ */
+ cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
- /* VDCLK Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
- cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
+ /* VDCLK Fraction = 0x2be2fe */
+ /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
+ cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
- /* AIMCLK Fraction = 0x05227ad */
- /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
- cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
+ /* AIMCLK Fraction = 0x05227ad */
+ /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
+ cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
- cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
- break;
+ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
+ cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
+ return 0;
+}
- case CX18_AV_INIT_NORMAL:
- default:
- if (!state->is_initialized) {
- /* initialize on first use */
- state->is_initialized = 1;
- cx18_av_initialize(cx);
- }
- break;
+static int cx18_av_load_fw(struct v4l2_subdev *sd)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ if (!state->is_initialized) {
+ /* initialize on first use */
+ state->is_initialized = 1;
+ cx18_av_initialize(cx);
}
return 0;
}
@@ -548,19 +547,19 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
}
static int cx18_av_s_video_routing(struct v4l2_subdev *sd,
- const struct v4l2_routing *route)
+ u32 input, u32 output, u32 config)
{
struct cx18_av_state *state = to_cx18_av_state(sd);
struct cx18 *cx = v4l2_get_subdevdata(sd);
- return set_input(cx, route->input, state->aud_input);
+ return set_input(cx, input, state->aud_input);
}
static int cx18_av_s_audio_routing(struct v4l2_subdev *sd,
- const struct v4l2_routing *route)
+ u32 input, u32 output, u32 config)
{
struct cx18_av_state *state = to_cx18_av_state(sd);
struct cx18 *cx = v4l2_get_subdevdata(sd);
- return set_input(cx, state->vid_input, route->input);
+ return set_input(cx, state->vid_input, input);
}
static int cx18_av_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
@@ -1185,10 +1184,12 @@ static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
.g_chip_ident = cx18_av_g_chip_ident,
.log_status = cx18_av_log_status,
.init = cx18_av_init,
+ .load_fw = cx18_av_load_fw,
.reset = cx18_av_reset,
.queryctrl = cx18_av_queryctrl,
.g_ctrl = cx18_av_g_ctrl,
.s_ctrl = cx18_av_s_ctrl,
+ .s_std = cx18_av_s_std,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = cx18_av_g_register,
.s_register = cx18_av_s_register,
@@ -1200,7 +1201,6 @@ static const struct v4l2_subdev_tuner_ops cx18_av_tuner_ops = {
.s_frequency = cx18_av_s_frequency,
.g_tuner = cx18_av_g_tuner,
.s_tuner = cx18_av_s_tuner,
- .s_std = cx18_av_s_std,
};
static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index c458120e8c9..9b84a0c58e0 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -328,11 +328,6 @@ static inline struct cx18_av_state *to_cx18_av_state(struct v4l2_subdev *sd)
return container_of(sd, struct cx18_av_state, sd);
}
-enum cx18_av_subdev_init_arg {
- CX18_AV_INIT_NORMAL = 0,
- CX18_AV_INIT_PLLS = 1,
-};
-
/* ----------------------------------------------------------------------- */
/* cx18_av-core.c */
int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 210c68aaae0..49b1c3d7b1a 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -810,7 +810,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
CX18_ERR("Could not register A/V decoder subdevice\n");
goto free_map;
}
- cx18_call_hw(cx, CX18_HW_418_AV, core, init, (u32) CX18_AV_INIT_PLLS);
+ cx18_call_hw(cx, CX18_HW_418_AV, core, init, 0);
/* Initialize GPIO Reset Controller to do chip resets during i2c init */
if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) {
@@ -1028,7 +1028,7 @@ int cx18_init_on_first_open(struct cx18 *cx)
cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
/* Init the A/V decoder, if it hasn't been already */
- v4l2_subdev_call(cx->sd_av, core, init, (u32) CX18_AV_INIT_NORMAL);
+ v4l2_subdev_call(cx->sd_av, core, load_fw);
vf.tuner = 0;
vf.type = V4L2_TUNER_ANALOG_TV;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 4d7d6d5a7f8..b3889c0b269 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -608,7 +608,7 @@ int cx18_v4l2_close(struct file *filp)
/* Mark that the radio is no longer in use */
clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
/* Switch tuner to TV */
- cx18_call_all(cx, tuner, s_std, cx->std);
+ cx18_call_all(cx, core, s_std, cx->std);
/* Select correct audio input (i.e. TV tuner or Line in) */
cx18_audio_set_io(cx);
if (atomic_read(&cx->ana_capturing) > 0) {
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index 5518d1424f8..86a204b5448 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -156,12 +156,12 @@ static int gpiomux_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
}
static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,
- const struct v4l2_routing *route)
+ u32 input, u32 output, u32 config)
{
struct cx18 *cx = v4l2_get_subdevdata(sd);
u32 data;
- switch (route->input) {
+ switch (input) {
case 0:
data = cx->card->gpio_audio_input.tuner;
break;
@@ -180,10 +180,10 @@ static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,
static const struct v4l2_subdev_core_ops gpiomux_core_ops = {
.log_status = gpiomux_log_status,
+ .s_std = gpiomux_s_std,
};
static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = {
- .s_std = gpiomux_s_std,
.s_radio = gpiomux_s_radio,
};
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index d092643faf4..b9b7064a2be 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -100,16 +100,16 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
if (hw == CX18_HW_TUNER) {
/* special tuner group handling */
- sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
- cx->card_i2c->radio);
+ sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev,
+ adap, mod, type, cx->card_i2c->radio);
if (sd != NULL)
sd->grp_id = hw;
- sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
- cx->card_i2c->demod);
+ sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev,
+ adap, mod, type, cx->card_i2c->demod);
if (sd != NULL)
sd->grp_id = hw;
- sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
- cx->card_i2c->tv);
+ sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev,
+ adap, mod, type, cx->card_i2c->tv);
if (sd != NULL)
sd->grp_id = hw;
return sd != NULL ? 0 : -1;
@@ -120,7 +120,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
return -1;
/* It's an I2C device other than an analog tuner */
- sd = v4l2_i2c_new_subdev(adap, mod, type, hw_addrs[idx]);
+ sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx]);
if (sd != NULL)
sd->grp_id = hw;
return sd != NULL ? 0 : -1;
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index e4c9e3d8bac..d7b1921e666 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -705,7 +705,7 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
(unsigned long long) cx->std);
/* Tuner */
- cx18_call_all(cx, tuner, s_std, cx->std);
+ cx18_call_all(cx, core, s_std, cx->std);
return 0;
}
@@ -926,16 +926,6 @@ static long cx18_default(struct file *file, void *fh, int cmd, void *arg)
struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
switch (cmd) {
- case VIDIOC_INT_S_AUDIO_ROUTING: {
- struct v4l2_routing *route = arg;
-
- CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n",
- route->input, route->output);
- cx18_call_hw(cx, cx->card->hw_audio_ctrl, audio, s_routing,
- route);
- break;
- }
-
case VIDIOC_INT_RESET: {
u32 val = *(u32 *)arg;
diff --git a/drivers/media/video/cx18/cx18-video.c b/drivers/media/video/cx18/cx18-video.c
index 6fdadedf17a..6dc84aac8f4 100644
--- a/drivers/media/video/cx18/cx18-video.c
+++ b/drivers/media/video/cx18/cx18-video.c
@@ -25,20 +25,8 @@
void cx18_video_set_io(struct cx18 *cx)
{
- struct v4l2_routing route;
int inp = cx->active_input;
- u32 type;
- route.input = cx->card->video_inputs[inp].video_input;
- route.output = 0;
- v4l2_subdev_call(cx->sd_av, video, s_routing, &route);
-
- type = cx->card->video_inputs[inp].video_type;
-
- if (type == CX18_CARD_INPUT_VID_TUNER)
- route.input = 0; /* Tuner */
- else if (type < CX18_CARD_INPUT_COMPOSITE1)
- route.input = 2; /* S-Video */
- else
- route.input = 1; /* Composite */
+ v4l2_subdev_call(cx->sd_av, video, s_routing,
+ cx->card->video_inputs[inp].video_input, 0, 0);
}
diff --git a/drivers/media/video/cx231xx/Kconfig b/drivers/media/video/cx231xx/Kconfig
new file mode 100644
index 00000000000..91156546a07
--- /dev/null
+++ b/drivers/media/video/cx231xx/Kconfig
@@ -0,0 +1,35 @@
+config VIDEO_CX231XX
+ tristate "Conexant cx231xx USB video capture support"
+ depends on VIDEO_DEV && I2C && INPUT
+ select VIDEO_TUNER
+ select VIDEO_TVEEPROM
+ select VIDEO_IR
+ select VIDEOBUF_VMALLOC
+ select VIDEO_CX25840
+ select VIDEO_CX231XX_ALSA
+
+ ---help---
+ This is a video4linux driver for Conexant 231xx USB based TV cards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cx231xx
+
+config VIDEO_CX231XX_ALSA
+ tristate "Conexant Cx231xx ALSA audio module"
+ depends on VIDEO_CX231XX && SND
+ select SND_PCM
+
+ ---help---
+ This is an ALSA driver for Cx231xx USB based TV cards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cx231xx-alsa
+
+config VIDEO_CX231XX_DVB
+ tristate "DVB/ATSC Support for Cx231xx based TV cards"
+ depends on VIDEO_CX231XX && DVB_CORE
+ select VIDEOBUF_DVB
+ select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMISE
+ ---help---
+ This adds support for DVB cards based on the
+ Conexant cx231xx chips.
diff --git a/drivers/media/video/cx231xx/Makefile b/drivers/media/video/cx231xx/Makefile
new file mode 100644
index 00000000000..755dd0ce65f
--- /dev/null
+++ b/drivers/media/video/cx231xx/Makefile
@@ -0,0 +1,14 @@
+cx231xx-objs := cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o \
+ cx231xx-avcore.o cx231xx-pcb-cfg.o cx231xx-vbi.o
+
+cx231xx-alsa-objs := cx231xx-audio.o
+
+obj-$(CONFIG_VIDEO_CX231XX) += cx231xx.o
+obj-$(CONFIG_VIDEO_CX231XX_ALSA) += cx231xx-alsa.o
+obj-$(CONFIG_VIDEO_CX231XX_DVB) += cx231xx-dvb.o
+
+EXTRA_CFLAGS += -Idrivers/media/video
+EXTRA_CFLAGS += -Idrivers/media/common/tuners
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
+
diff --git a/drivers/media/video/cx231xx/cx231xx-audio.c b/drivers/media/video/cx231xx/cx231xx-audio.c
new file mode 100644
index 00000000000..7793d60966d
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-audio.c
@@ -0,0 +1,586 @@
+/*
+ * Conexant Cx231xx audio extension
+ *
+ * Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+ * Based on em28xx driver
+ *
+ *
+ * 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/kernel.h>
+#include <linux/usb.h>
+#include <linux/init.h>
+#include <linux/sound.h>
+#include <linux/spinlock.h>
+#include <linux/soundcard.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/info.h>
+#include <sound/initval.h>
+#include <sound/control.h>
+#include <media/v4l2-common.h>
+#include "cx231xx.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
+
+#define dprintk(fmt, arg...) do { \
+ if (debug) \
+ printk(KERN_INFO "cx231xx-audio %s: " fmt, \
+ __func__, ##arg); \
+ } while (0)
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+
+static int cx231xx_isoc_audio_deinit(struct cx231xx *dev)
+{
+ int i;
+
+ dprintk("Stopping isoc\n");
+
+ for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
+ if (dev->adev.urb[i]) {
+ if (!irqs_disabled())
+ usb_kill_urb(dev->adev.urb[i]);
+ else
+ usb_unlink_urb(dev->adev.urb[i]);
+
+ usb_free_urb(dev->adev.urb[i]);
+ dev->adev.urb[i] = NULL;
+
+ kfree(dev->adev.transfer_buffer[i]);
+ dev->adev.transfer_buffer[i] = NULL;
+ }
+ }
+
+ return 0;
+}
+
+static void cx231xx_audio_isocirq(struct urb *urb)
+{
+ struct cx231xx *dev = urb->context;
+ int i;
+ unsigned int oldptr;
+ int period_elapsed = 0;
+ int status;
+ unsigned char *cp;
+ unsigned int stride;
+ struct snd_pcm_substream *substream;
+ struct snd_pcm_runtime *runtime;
+
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ dprintk("urb completition error %d.\n", urb->status);
+ break;
+ }
+
+ if (dev->adev.capture_pcm_substream) {
+ substream = dev->adev.capture_pcm_substream;
+ runtime = substream->runtime;
+ stride = runtime->frame_bits >> 3;
+
+ for (i = 0; i < urb->number_of_packets; i++) {
+ int length = urb->iso_frame_desc[i].actual_length /
+ stride;
+ cp = (unsigned char *)urb->transfer_buffer +
+ urb->iso_frame_desc[i].offset;
+
+ if (!length)
+ continue;
+
+ oldptr = dev->adev.hwptr_done_capture;
+ if (oldptr + length >= runtime->buffer_size) {
+ unsigned int cnt;
+
+ cnt = runtime->buffer_size - oldptr;
+ memcpy(runtime->dma_area + oldptr * stride, cp,
+ cnt * stride);
+ memcpy(runtime->dma_area, cp + cnt * stride,
+ length * stride - cnt * stride);
+ } else {
+ memcpy(runtime->dma_area + oldptr * stride, cp,
+ length * stride);
+ }
+
+ snd_pcm_stream_lock(substream);
+
+ dev->adev.hwptr_done_capture += length;
+ if (dev->adev.hwptr_done_capture >=
+ runtime->buffer_size)
+ dev->adev.hwptr_done_capture -=
+ runtime->buffer_size;
+
+ dev->adev.capture_transfer_done += length;
+ if (dev->adev.capture_transfer_done >=
+ runtime->period_size) {
+ dev->adev.capture_transfer_done -=
+ runtime->period_size;
+ period_elapsed = 1;
+ }
+ snd_pcm_stream_unlock(substream);
+ }
+ if (period_elapsed)
+ snd_pcm_period_elapsed(substream);
+ }
+ urb->status = 0;
+
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status < 0) {
+ cx231xx_errdev("resubmit of audio urb failed (error=%i)\n",
+ status);
+ }
+ return;
+}
+
+static int cx231xx_init_audio_isoc(struct cx231xx *dev)
+{
+ int i, errCode;
+ int sb_size;
+
+ cx231xx_info("%s: Starting AUDIO transfers\n", __func__);
+
+ sb_size = CX231XX_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size;
+
+ for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
+ struct urb *urb;
+ int j, k;
+
+ dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC);
+ if (!dev->adev.transfer_buffer[i])
+ return -ENOMEM;
+
+ memset(dev->adev.transfer_buffer[i], 0x80, sb_size);
+ urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
+ if (!urb) {
+ cx231xx_errdev("usb_alloc_urb failed!\n");
+ for (j = 0; j < i; j++) {
+ usb_free_urb(dev->adev.urb[j]);
+ kfree(dev->adev.transfer_buffer[j]);
+ }
+ return -ENOMEM;
+ }
+
+ urb->dev = dev->udev;
+ urb->context = dev;
+ urb->pipe = usb_rcvisocpipe(dev->udev,
+ dev->adev.end_point_addr);
+ urb->transfer_flags = URB_ISO_ASAP;
+ urb->transfer_buffer = dev->adev.transfer_buffer[i];
+ urb->interval = 1;
+ urb->complete = cx231xx_audio_isocirq;
+ urb->number_of_packets = CX231XX_NUM_AUDIO_PACKETS;
+ urb->transfer_buffer_length = sb_size;
+
+ for (j = k = 0; j < CX231XX_NUM_AUDIO_PACKETS;
+ j++, k += dev->adev.max_pkt_size) {
+ urb->iso_frame_desc[j].offset = k;
+ urb->iso_frame_desc[j].length = dev->adev.max_pkt_size;
+ }
+ dev->adev.urb[i] = urb;
+ }
+
+ for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
+ errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
+ if (errCode < 0) {
+ cx231xx_isoc_audio_deinit(dev);
+ return errCode;
+ }
+ }
+
+ return errCode;
+}
+
+static int cx231xx_cmd(struct cx231xx *dev, int cmd, int arg)
+{
+ dprintk("%s transfer\n", (dev->adev.capture_stream == STREAM_ON) ?
+ "stop" : "start");
+
+ switch (cmd) {
+ case CX231XX_CAPTURE_STREAM_EN:
+ if (dev->adev.capture_stream == STREAM_OFF && arg == 1) {
+ dev->adev.capture_stream = STREAM_ON;
+ cx231xx_init_audio_isoc(dev);
+ } else if (dev->adev.capture_stream == STREAM_ON && arg == 0) {
+ dev->adev.capture_stream = STREAM_OFF;
+ cx231xx_isoc_audio_deinit(dev);
+ } else {
+ cx231xx_errdev("An underrun very likely occurred. "
+ "Ignoring it.\n");
+ }
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
+ size_t size)
+{
+ struct snd_pcm_runtime *runtime = subs->runtime;
+
+ dprintk("Allocating vbuffer\n");
+ if (runtime->dma_area) {
+ if (runtime->dma_bytes > size)
+ return 0;
+
+ vfree(runtime->dma_area);
+ }
+ runtime->dma_area = vmalloc(size);
+ if (!runtime->dma_area)
+ return -ENOMEM;
+
+ runtime->dma_bytes = size;
+
+ return 0;
+}
+
+static struct snd_pcm_hardware snd_cx231xx_hw_capture = {
+ .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID,
+
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+
+ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT,
+
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */
+ .period_bytes_min = 64, /* 12544/2, */
+ .period_bytes_max = 12544,
+ .periods_min = 2,
+ .periods_max = 98, /* 12544, */
+};
+
+static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream)
+{
+ struct cx231xx *dev = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int ret = 0;
+
+ dprintk("opening device and trying to acquire exclusive lock\n");
+
+ if (!dev) {
+ cx231xx_errdev("BUG: cx231xx can't find device struct."
+ " Can't proceed with open\n");
+ return -ENODEV;
+ }
+
+ /* Sets volume, mute, etc */
+ dev->mute = 0;
+
+ /* set alternate setting for audio interface */
+ /* 1 - 48000 samples per sec */
+ ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 1);
+ if (ret < 0) {
+ cx231xx_errdev("failed to set alternate setting !\n");
+
+ return ret;
+ }
+
+ /* inform hardware to start streaming */
+ ret = cx231xx_capture_start(dev, 1, Audio);
+
+ runtime->hw = snd_cx231xx_hw_capture;
+
+ mutex_lock(&dev->lock);
+ dev->adev.users++;
+ mutex_unlock(&dev->lock);
+
+ snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ dev->adev.capture_pcm_substream = substream;
+ runtime->private_data = dev;
+
+ return 0;
+}
+
+static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream)
+{
+ int ret;
+ struct cx231xx *dev = snd_pcm_substream_chip(substream);
+
+ dprintk("closing device\n");
+
+ /* set alternate setting for audio interface */
+ /* 1 - 48000 samples per sec */
+ ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0);
+ if (ret < 0) {
+ cx231xx_errdev("failed to set alternate setting !\n");
+
+ return ret;
+ }
+
+ /* inform hardware to start streaming */
+ ret = cx231xx_capture_start(dev, 0, Audio);
+
+ dev->mute = 1;
+ mutex_lock(&dev->lock);
+ dev->adev.users--;
+ mutex_unlock(&dev->lock);
+
+ if (dev->adev.users == 0 && dev->adev.shutdown == 1) {
+ dprintk("audio users: %d\n", dev->adev.users);
+ dprintk("disabling audio stream!\n");
+ dev->adev.shutdown = 0;
+ dprintk("released lock\n");
+ cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN, 0);
+ }
+ return 0;
+}
+
+static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ unsigned int channels, rate, format;
+ int ret;
+
+ dprintk("Setting capture parameters\n");
+
+ ret = snd_pcm_alloc_vmalloc_buffer(substream,
+ params_buffer_bytes(hw_params));
+ format = params_format(hw_params);
+ rate = params_rate(hw_params);
+ channels = params_channels(hw_params);
+
+ /* TODO: set up cx231xx audio chip to deliver the correct audio format,
+ current default is 48000hz multiplexed => 96000hz mono
+ which shouldn't matter since analogue TV only supports mono */
+ return 0;
+}
+
+static int snd_cx231xx_hw_capture_free(struct snd_pcm_substream *substream)
+{
+ struct cx231xx *dev = snd_pcm_substream_chip(substream);
+
+ dprintk("Stop capture, if needed\n");
+
+ if (dev->adev.capture_stream == STREAM_ON)
+ cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN, CX231XX_STOP_AUDIO);
+
+ return 0;
+}
+
+static int snd_cx231xx_prepare(struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
+static int snd_cx231xx_capture_trigger(struct snd_pcm_substream *substream,
+ int cmd)
+{
+ struct cx231xx *dev = snd_pcm_substream_chip(substream);
+ int retval;
+
+ dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START) ?
+ "start" : "stop");
+
+ spin_lock(&dev->adev.slock);
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN,
+ CX231XX_START_AUDIO);
+ retval = 0;
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN, CX231XX_STOP_AUDIO);
+ retval = 0;
+ break;
+ default:
+ retval = -EINVAL;
+ }
+
+ spin_unlock(&dev->adev.slock);
+ return retval;
+}
+
+static snd_pcm_uframes_t snd_cx231xx_capture_pointer(struct snd_pcm_substream
+ *substream)
+{
+ struct cx231xx *dev;
+ unsigned long flags;
+ snd_pcm_uframes_t hwptr_done;
+
+ dev = snd_pcm_substream_chip(substream);
+
+ spin_lock_irqsave(&dev->adev.slock, flags);
+ hwptr_done = dev->adev.hwptr_done_capture;
+ spin_unlock_irqrestore(&dev->adev.slock, flags);
+
+ return hwptr_done;
+}
+
+static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
+ unsigned long offset)
+{
+ void *pageptr = subs->runtime->dma_area + offset;
+
+ return vmalloc_to_page(pageptr);
+}
+
+static struct snd_pcm_ops snd_cx231xx_pcm_capture = {
+ .open = snd_cx231xx_capture_open,
+ .close = snd_cx231xx_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_cx231xx_hw_capture_params,
+ .hw_free = snd_cx231xx_hw_capture_free,
+ .prepare = snd_cx231xx_prepare,
+ .trigger = snd_cx231xx_capture_trigger,
+ .pointer = snd_cx231xx_capture_pointer,
+ .page = snd_pcm_get_vmalloc_page,
+};
+
+static int cx231xx_audio_init(struct cx231xx *dev)
+{
+ struct cx231xx_audio *adev = &dev->adev;
+ struct snd_pcm *pcm;
+ struct snd_card *card;
+ static int devnr;
+ int err;
+ struct usb_interface *uif;
+ int i, isoc_pipe = 0;
+
+ if (dev->has_alsa_audio != 1) {
+ /* This device does not support the extension (in this case
+ the device is expecting the snd-usb-audio module or
+ doesn't have analog audio support at all) */
+ return 0;
+ }
+
+ cx231xx_info("cx231xx-audio.c: probing for cx231xx "
+ "non standard usbaudio\n");
+
+ err = snd_card_create(index[devnr], "Cx231xx Audio", THIS_MODULE,
+ 0, &card);
+ if (err < 0)
+ return err;
+
+ spin_lock_init(&adev->slock);
+ err = snd_pcm_new(card, "Cx231xx Audio", 0, 0, 1, &pcm);
+ if (err < 0) {
+ snd_card_free(card);
+ return err;
+ }
+
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+ &snd_cx231xx_pcm_capture);
+ pcm->info_flags = 0;
+ pcm->private_data = dev;
+ strcpy(pcm->name, "Conexant cx231xx Capture");
+ strcpy(card->driver, "Conexant cx231xx Audio");
+ strcpy(card->shortname, "Cx231xx Audio");
+ strcpy(card->longname, "Conexant cx231xx Audio");
+
+ err = snd_card_register(card);
+ if (err < 0) {
+ snd_card_free(card);
+ return err;
+ }
+ adev->sndcard = card;
+ adev->udev = dev->udev;
+
+ /* compute alternate max packet sizes for Audio */
+ uif =
+ dev->udev->actconfig->interface[dev->current_pcb_config.
+ hs_config_info[0].interface_info.
+ audio_index + 1];
+
+ adev->end_point_addr =
+ le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
+ bEndpointAddress);
+
+ adev->num_alt = uif->num_altsetting;
+ cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
+ adev->end_point_addr, adev->num_alt);
+ adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL);
+
+ if (adev->alt_max_pkt_size == NULL) {
+ cx231xx_errdev("out of memory!\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < adev->num_alt; i++) {
+ u16 tmp =
+ le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
+ wMaxPacketSize);
+ adev->alt_max_pkt_size[i] =
+ (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+ cx231xx_info("Alternate setting %i, max size= %i\n", i,
+ adev->alt_max_pkt_size[i]);
+ }
+
+ return 0;
+}
+
+static int cx231xx_audio_fini(struct cx231xx *dev)
+{
+ if (dev == NULL)
+ return 0;
+
+ if (dev->has_alsa_audio != 1) {
+ /* This device does not support the extension (in this case
+ the device is expecting the snd-usb-audio module or
+ doesn't have analog audio support at all) */
+ return 0;
+ }
+
+ if (dev->adev.sndcard) {
+ snd_card_free(dev->adev.sndcard);
+ kfree(dev->adev.alt_max_pkt_size);
+ dev->adev.sndcard = NULL;
+ }
+
+ return 0;
+}
+
+static struct cx231xx_ops audio_ops = {
+ .id = CX231XX_AUDIO,
+ .name = "Cx231xx Audio Extension",
+ .init = cx231xx_audio_init,
+ .fini = cx231xx_audio_fini,
+};
+
+static int __init cx231xx_alsa_register(void)
+{
+ return cx231xx_register_extension(&audio_ops);
+}
+
+static void __exit cx231xx_alsa_unregister(void)
+{
+ cx231xx_unregister_extension(&audio_ops);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
+MODULE_DESCRIPTION("Cx231xx Audio driver");
+
+module_init(cx231xx_alsa_register);
+module_exit(cx231xx_alsa_unregister);
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
new file mode 100644
index 00000000000..1be3881be99
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -0,0 +1,2581 @@
+/*
+ cx231xx_avcore.c - driver for Conexant Cx23100/101/102
+ USB video capture devices
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+
+ This program contains the specific code to control the avdecoder chip and
+ other related usb control functions for cx231xx based chipset.
+
+ 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/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/bitmap.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <linux/version.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-chip-ident.h>
+
+#include "cx231xx.h"
+
+/******************************************************************************
+ -: BLOCK ARRANGEMENT :-
+ I2S block ----------------------|
+ [I2S audio] |
+ |
+ Analog Front End --> Direct IF -|-> Cx25840 --> Audio
+ [video & audio] | [Audio]
+ |
+ |-> Cx25840 --> Video
+ [Video]
+
+*******************************************************************************/
+
+/******************************************************************************
+ * A F E - B L O C K C O N T R O L functions *
+ * [ANALOG FRONT END] *
+ ******************************************************************************/
+static int afe_write_byte(struct cx231xx *dev, u16 saddr, u8 data)
+{
+ return cx231xx_write_i2c_data(dev, AFE_DEVICE_ADDRESS,
+ saddr, 2, data, 1);
+}
+
+static int afe_read_byte(struct cx231xx *dev, u16 saddr, u8 *data)
+{
+ int status;
+ u32 temp = 0;
+
+ status = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
+ saddr, 2, &temp, 1);
+ *data = (u8) temp;
+ return status;
+}
+
+int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count)
+{
+ int status = 0;
+ u8 temp = 0;
+ u8 afe_power_status = 0;
+ int i = 0;
+
+ /* super block initialize */
+ temp = (u8) (ref_count & 0xff);
+ status = afe_write_byte(dev, SUP_BLK_TUNE2, temp);
+ if (status < 0)
+ return status;
+
+ status = afe_read_byte(dev, SUP_BLK_TUNE2, &afe_power_status);
+ if (status < 0)
+ return status;
+
+ temp = (u8) ((ref_count & 0x300) >> 8);
+ temp |= 0x40;
+ status = afe_write_byte(dev, SUP_BLK_TUNE1, temp);
+ if (status < 0)
+ return status;
+
+ status = afe_write_byte(dev, SUP_BLK_PLL2, 0x0f);
+ if (status < 0)
+ return status;
+
+ /* enable pll */
+ while (afe_power_status != 0x18) {
+ status = afe_write_byte(dev, SUP_BLK_PWRDN, 0x18);
+ if (status < 0) {
+ cx231xx_info(
+ ": Init Super Block failed in send cmd\n");
+ break;
+ }
+
+ status = afe_read_byte(dev, SUP_BLK_PWRDN, &afe_power_status);
+ afe_power_status &= 0xff;
+ if (status < 0) {
+ cx231xx_info(
+ ": Init Super Block failed in receive cmd\n");
+ break;
+ }
+ i++;
+ if (i == 10) {
+ cx231xx_info(
+ ": Init Super Block force break in loop !!!!\n");
+ status = -1;
+ break;
+ }
+ }
+
+ if (status < 0)
+ return status;
+
+ /* start tuning filter */
+ status = afe_write_byte(dev, SUP_BLK_TUNE3, 0x40);
+ if (status < 0)
+ return status;
+
+ msleep(5);
+
+ /* exit tuning */
+ status = afe_write_byte(dev, SUP_BLK_TUNE3, 0x00);
+
+ return status;
+}
+
+int cx231xx_afe_init_channels(struct cx231xx *dev)
+{
+ int status = 0;
+
+ /* power up all 3 channels, clear pd_buffer */
+ status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1, 0x00);
+ status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2, 0x00);
+ status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x00);
+
+ /* Enable quantizer calibration */
+ status = afe_write_byte(dev, ADC_COM_QUANT, 0x02);
+
+ /* channel initialize, force modulator (fb) reset */
+ status = afe_write_byte(dev, ADC_FB_FRCRST_CH1, 0x17);
+ status = afe_write_byte(dev, ADC_FB_FRCRST_CH2, 0x17);
+ status = afe_write_byte(dev, ADC_FB_FRCRST_CH3, 0x17);
+
+ /* start quantilizer calibration */
+ status = afe_write_byte(dev, ADC_CAL_ATEST_CH1, 0x10);
+ status = afe_write_byte(dev, ADC_CAL_ATEST_CH2, 0x10);
+ status = afe_write_byte(dev, ADC_CAL_ATEST_CH3, 0x10);
+ msleep(5);
+
+ /* exit modulator (fb) reset */
+ status = afe_write_byte(dev, ADC_FB_FRCRST_CH1, 0x07);
+ status = afe_write_byte(dev, ADC_FB_FRCRST_CH2, 0x07);
+ status = afe_write_byte(dev, ADC_FB_FRCRST_CH3, 0x07);
+
+ /* enable the pre_clamp in each channel for single-ended input */
+ status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH1, 0xf0);
+ status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH2, 0xf0);
+ status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH3, 0xf0);
+
+ /* use diode instead of resistor, so set term_en to 0, res_en to 0 */
+ status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
+ ADC_QGAIN_RES_TRM_CH1, 3, 7, 0x00);
+ status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
+ ADC_QGAIN_RES_TRM_CH2, 3, 7, 0x00);
+ status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
+ ADC_QGAIN_RES_TRM_CH3, 3, 7, 0x00);
+
+ /* dynamic element matching off */
+ status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH1, 0x03);
+ status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH2, 0x03);
+ status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH3, 0x03);
+
+ return status;
+}
+
+int cx231xx_afe_setup_AFE_for_baseband(struct cx231xx *dev)
+{
+ u8 c_value = 0;
+ int status = 0;
+
+ status = afe_read_byte(dev, ADC_PWRDN_CLAMP_CH2, &c_value);
+ c_value &= (~(0x50));
+ status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2, c_value);
+
+ return status;
+}
+
+/*
+ The Analog Front End in Cx231xx has 3 channels. These
+ channels are used to share between different inputs
+ like tuner, s-video and composite inputs.
+
+ channel 1 ----- pin 1 to pin4(in reg is 1-4)
+ channel 2 ----- pin 5 to pin8(in reg is 5-8)
+ channel 3 ----- pin 9 to pin 12(in reg is 9-11)
+*/
+int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux)
+{
+ u8 ch1_setting = (u8) input_mux;
+ u8 ch2_setting = (u8) (input_mux >> 8);
+ u8 ch3_setting = (u8) (input_mux >> 16);
+ int status = 0;
+ u8 value = 0;
+
+ if (ch1_setting != 0) {
+ status = afe_read_byte(dev, ADC_INPUT_CH1, &value);
+ value &= (!INPUT_SEL_MASK);
+ value |= (ch1_setting - 1) << 4;
+ value &= 0xff;
+ status = afe_write_byte(dev, ADC_INPUT_CH1, value);
+ }
+
+ if (ch2_setting != 0) {
+ status = afe_read_byte(dev, ADC_INPUT_CH2, &value);
+ value &= (!INPUT_SEL_MASK);
+ value |= (ch2_setting - 1) << 4;
+ value &= 0xff;
+ status = afe_write_byte(dev, ADC_INPUT_CH2, value);
+ }
+
+ /* For ch3_setting, the value to put in the register is
+ 7 less than the input number */
+ if (ch3_setting != 0) {
+ status = afe_read_byte(dev, ADC_INPUT_CH3, &value);
+ value &= (!INPUT_SEL_MASK);
+ value |= (ch3_setting - 1) << 4;
+ value &= 0xff;
+ status = afe_write_byte(dev, ADC_INPUT_CH3, value);
+ }
+
+ return status;
+}
+
+int cx231xx_afe_set_mode(struct cx231xx *dev, enum AFE_MODE mode)
+{
+ int status = 0;
+
+ /*
+ * FIXME: We need to implement the AFE code for LOW IF and for HI IF.
+ * Currently, only baseband works.
+ */
+
+ switch (mode) {
+ case AFE_MODE_LOW_IF:
+ /* SetupAFEforLowIF(); */
+ break;
+ case AFE_MODE_BASEBAND:
+ status = cx231xx_afe_setup_AFE_for_baseband(dev);
+ break;
+ case AFE_MODE_EU_HI_IF:
+ /* SetupAFEforEuHiIF(); */
+ break;
+ case AFE_MODE_US_HI_IF:
+ /* SetupAFEforUsHiIF(); */
+ break;
+ case AFE_MODE_JAPAN_HI_IF:
+ /* SetupAFEforJapanHiIF(); */
+ break;
+ }
+
+ if ((mode != dev->afe_mode) &&
+ (dev->video_input == CX231XX_VMUX_TELEVISION))
+ status = cx231xx_afe_adjust_ref_count(dev,
+ CX231XX_VMUX_TELEVISION);
+
+ dev->afe_mode = mode;
+
+ return status;
+}
+
+int cx231xx_afe_update_power_control(struct cx231xx *dev,
+ enum AV_MODE avmode)
+{
+ u8 afe_power_status = 0;
+ int status = 0;
+
+ switch (dev->model) {
+ case CX231XX_BOARD_CNXT_RDE_250:
+ case CX231XX_BOARD_CNXT_RDU_250:
+ if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
+ while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
+ FLD_PWRDN_ENABLE_PLL)) {
+ status = afe_write_byte(dev, SUP_BLK_PWRDN,
+ FLD_PWRDN_TUNING_BIAS |
+ FLD_PWRDN_ENABLE_PLL);
+ status |= afe_read_byte(dev, SUP_BLK_PWRDN,
+ &afe_power_status);
+ if (status < 0)
+ break;
+ }
+
+ status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
+ 0x00);
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
+ 0x00);
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
+ 0x00);
+ } else if (avmode == POLARIS_AVMODE_DIGITAL) {
+ status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
+ 0x70);
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
+ 0x70);
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
+ 0x70);
+
+ status |= afe_read_byte(dev, SUP_BLK_PWRDN,
+ &afe_power_status);
+ afe_power_status |= FLD_PWRDN_PD_BANDGAP |
+ FLD_PWRDN_PD_BIAS |
+ FLD_PWRDN_PD_TUNECK;
+ status |= afe_write_byte(dev, SUP_BLK_PWRDN,
+ afe_power_status);
+ } else if (avmode == POLARIS_AVMODE_ENXTERNAL_AV) {
+ while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
+ FLD_PWRDN_ENABLE_PLL)) {
+ status = afe_write_byte(dev, SUP_BLK_PWRDN,
+ FLD_PWRDN_TUNING_BIAS |
+ FLD_PWRDN_ENABLE_PLL);
+ status |= afe_read_byte(dev, SUP_BLK_PWRDN,
+ &afe_power_status);
+ if (status < 0)
+ break;
+ }
+
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
+ 0x00);
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
+ 0x00);
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
+ 0x00);
+ } else {
+ cx231xx_info("Invalid AV mode input\n");
+ status = -1;
+ }
+ break;
+ default:
+ if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
+ while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
+ FLD_PWRDN_ENABLE_PLL)) {
+ status = afe_write_byte(dev, SUP_BLK_PWRDN,
+ FLD_PWRDN_TUNING_BIAS |
+ FLD_PWRDN_ENABLE_PLL);
+ status |= afe_read_byte(dev, SUP_BLK_PWRDN,
+ &afe_power_status);
+ if (status < 0)
+ break;
+ }
+
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
+ 0x40);
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
+ 0x40);
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
+ 0x00);
+ } else if (avmode == POLARIS_AVMODE_DIGITAL) {
+ status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
+ 0x70);
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
+ 0x70);
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
+ 0x70);
+
+ status |= afe_read_byte(dev, SUP_BLK_PWRDN,
+ &afe_power_status);
+ afe_power_status |= FLD_PWRDN_PD_BANDGAP |
+ FLD_PWRDN_PD_BIAS |
+ FLD_PWRDN_PD_TUNECK;
+ status |= afe_write_byte(dev, SUP_BLK_PWRDN,
+ afe_power_status);
+ } else if (avmode == POLARIS_AVMODE_ENXTERNAL_AV) {
+ while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
+ FLD_PWRDN_ENABLE_PLL)) {
+ status = afe_write_byte(dev, SUP_BLK_PWRDN,
+ FLD_PWRDN_TUNING_BIAS |
+ FLD_PWRDN_ENABLE_PLL);
+ status |= afe_read_byte(dev, SUP_BLK_PWRDN,
+ &afe_power_status);
+ if (status < 0)
+ break;
+ }
+
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
+ 0x00);
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
+ 0x00);
+ status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
+ 0x40);
+ } else {
+ cx231xx_info("Invalid AV mode input\n");
+ status = -1;
+ }
+ } /* switch */
+
+ return status;
+}
+
+int cx231xx_afe_adjust_ref_count(struct cx231xx *dev, u32 video_input)
+{
+ u8 input_mode = 0;
+ u8 ntf_mode = 0;
+ int status = 0;
+
+ dev->video_input = video_input;
+
+ if (video_input == CX231XX_VMUX_TELEVISION) {
+ status = afe_read_byte(dev, ADC_INPUT_CH3, &input_mode);
+ status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH3,
+ &ntf_mode);
+ } else {
+ status = afe_read_byte(dev, ADC_INPUT_CH1, &input_mode);
+ status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH1,
+ &ntf_mode);
+ }
+
+ input_mode = (ntf_mode & 0x3) | ((input_mode & 0x6) << 1);
+
+ switch (input_mode) {
+ case SINGLE_ENDED:
+ dev->afe_ref_count = 0x23C;
+ break;
+ case LOW_IF:
+ dev->afe_ref_count = 0x24C;
+ break;
+ case EU_IF:
+ dev->afe_ref_count = 0x258;
+ break;
+ case US_IF:
+ dev->afe_ref_count = 0x260;
+ break;
+ default:
+ break;
+ }
+
+ status = cx231xx_afe_init_super_block(dev, dev->afe_ref_count);
+
+ return status;
+}
+
+/******************************************************************************
+ * V I D E O / A U D I O D E C O D E R C O N T R O L functions *
+ ******************************************************************************/
+static int vid_blk_write_byte(struct cx231xx *dev, u16 saddr, u8 data)
+{
+ return cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+ saddr, 2, data, 1);
+}
+
+static int vid_blk_read_byte(struct cx231xx *dev, u16 saddr, u8 *data)
+{
+ int status;
+ u32 temp = 0;
+
+ status = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+ saddr, 2, &temp, 1);
+ *data = (u8) temp;
+ return status;
+}
+
+static int vid_blk_write_word(struct cx231xx *dev, u16 saddr, u32 data)
+{
+ return cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+ saddr, 2, data, 4);
+}
+
+static int vid_blk_read_word(struct cx231xx *dev, u16 saddr, u32 *data)
+{
+ return cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+ saddr, 2, data, 4);
+}
+
+int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input)
+{
+ int status = 0;
+
+ switch (INPUT(input)->type) {
+ case CX231XX_VMUX_COMPOSITE1:
+ case CX231XX_VMUX_SVIDEO:
+ if ((dev->current_pcb_config.type == USB_BUS_POWER) &&
+ (dev->power_mode != POLARIS_AVMODE_ENXTERNAL_AV)) {
+ /* External AV */
+ status = cx231xx_set_power_mode(dev,
+ POLARIS_AVMODE_ENXTERNAL_AV);
+ if (status < 0) {
+ cx231xx_errdev("%s: set_power_mode : Failed to"
+ " set Power - errCode [%d]!\n",
+ __func__, status);
+ return status;
+ }
+ }
+ status = cx231xx_set_decoder_video_input(dev,
+ INPUT(input)->type,
+ INPUT(input)->vmux);
+ break;
+ case CX231XX_VMUX_TELEVISION:
+ case CX231XX_VMUX_CABLE:
+ if ((dev->current_pcb_config.type == USB_BUS_POWER) &&
+ (dev->power_mode != POLARIS_AVMODE_ANALOGT_TV)) {
+ /* Tuner */
+ status = cx231xx_set_power_mode(dev,
+ POLARIS_AVMODE_ANALOGT_TV);
+ if (status < 0) {
+ cx231xx_errdev("%s: set_power_mode:Failed"
+ " to set Power - errCode [%d]!\n",
+ __func__, status);
+ return status;
+ }
+ }
+ status = cx231xx_set_decoder_video_input(dev,
+ CX231XX_VMUX_COMPOSITE1,
+ INPUT(input)->vmux);
+ break;
+ default:
+ cx231xx_errdev("%s: set_power_mode : Unknown Input %d !\n",
+ __func__, INPUT(input)->type);
+ break;
+ }
+
+ /* save the selection */
+ dev->video_input = input;
+
+ return status;
+}
+
+int cx231xx_set_decoder_video_input(struct cx231xx *dev,
+ u8 pin_type, u8 input)
+{
+ int status = 0;
+ u32 value = 0;
+
+ if (pin_type != dev->video_input) {
+ status = cx231xx_afe_adjust_ref_count(dev, pin_type);
+ if (status < 0) {
+ cx231xx_errdev("%s: adjust_ref_count :Failed to set"
+ "AFE input mux - errCode [%d]!\n",
+ __func__, status);
+ return status;
+ }
+ }
+
+ /* call afe block to set video inputs */
+ status = cx231xx_afe_set_input_mux(dev, input);
+ if (status < 0) {
+ cx231xx_errdev("%s: set_input_mux :Failed to set"
+ " AFE input mux - errCode [%d]!\n",
+ __func__, status);
+ return status;
+ }
+
+ switch (pin_type) {
+ case CX231XX_VMUX_COMPOSITE1:
+ status = vid_blk_read_word(dev, AFE_CTRL, &value);
+ value |= (0 << 13) | (1 << 4);
+ value &= ~(1 << 5);
+
+ /* set [24:23] [22:15] to 0 */
+ value &= (~(0x1ff8000));
+ /* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0 */
+ value |= 0x1000000;
+ status = vid_blk_write_word(dev, AFE_CTRL, value);
+
+ status = vid_blk_read_word(dev, OUT_CTRL1, &value);
+ value |= (1 << 7);
+ status = vid_blk_write_word(dev, OUT_CTRL1, value);
+
+ /* Set vip 1.1 output mode */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ OUT_CTRL1,
+ FLD_OUT_MODE,
+ OUT_MODE_VIP11);
+
+ /* Tell DIF object to go to baseband mode */
+ status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
+ if (status < 0) {
+ cx231xx_errdev("%s: cx231xx_dif set to By pass"
+ " mode- errCode [%d]!\n",
+ __func__, status);
+ return status;
+ }
+
+ /* Read the DFE_CTRL1 register */
+ status = vid_blk_read_word(dev, DFE_CTRL1, &value);
+
+ /* enable the VBI_GATE_EN */
+ value |= FLD_VBI_GATE_EN;
+
+ /* Enable the auto-VGA enable */
+ value |= FLD_VGA_AUTO_EN;
+
+ /* Write it back */
+ status = vid_blk_write_word(dev, DFE_CTRL1, value);
+
+ /* Disable auto config of registers */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ MODE_CTRL, FLD_ACFG_DIS,
+ cx231xx_set_field(FLD_ACFG_DIS, 1));
+
+ /* Set CVBS input mode */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ MODE_CTRL, FLD_INPUT_MODE,
+ cx231xx_set_field(FLD_INPUT_MODE, INPUT_MODE_CVBS_0));
+ break;
+ case CX231XX_VMUX_SVIDEO:
+ /* Disable the use of DIF */
+
+ status = vid_blk_read_word(dev, AFE_CTRL, &value);
+
+ /* set [24:23] [22:15] to 0 */
+ value &= (~(0x1ff8000));
+ /* set FUNC_MODE[24:23] = 2
+ IF_MOD[22:15] = 0 DCR_BYP_CH2[4:4] = 1; */
+ value |= 0x1000010;
+ status = vid_blk_write_word(dev, AFE_CTRL, value);
+
+ /* Tell DIF object to go to baseband mode */
+ status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
+ if (status < 0) {
+ cx231xx_errdev("%s: cx231xx_dif set to By pass"
+ " mode- errCode [%d]!\n",
+ __func__, status);
+ return status;
+ }
+
+ /* Read the DFE_CTRL1 register */
+ status = vid_blk_read_word(dev, DFE_CTRL1, &value);
+
+ /* enable the VBI_GATE_EN */
+ value |= FLD_VBI_GATE_EN;
+
+ /* Enable the auto-VGA enable */
+ value |= FLD_VGA_AUTO_EN;
+
+ /* Write it back */
+ status = vid_blk_write_word(dev, DFE_CTRL1, value);
+
+ /* Disable auto config of registers */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ MODE_CTRL, FLD_ACFG_DIS,
+ cx231xx_set_field(FLD_ACFG_DIS, 1));
+
+ /* Set YC input mode */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ MODE_CTRL,
+ FLD_INPUT_MODE,
+ cx231xx_set_field(FLD_INPUT_MODE, INPUT_MODE_YC_1));
+
+ /* Chroma to ADC2 */
+ status = vid_blk_read_word(dev, AFE_CTRL, &value);
+ value |= FLD_CHROMA_IN_SEL; /* set the chroma in select */
+
+ /* Clear VGA_SEL_CH2 and VGA_SEL_CH3 (bits 7 and 8)
+ This sets them to use video
+ rather than audio. Only one of the two will be in use. */
+ value &= ~(FLD_VGA_SEL_CH2 | FLD_VGA_SEL_CH3);
+
+ status = vid_blk_write_word(dev, AFE_CTRL, value);
+
+ status = cx231xx_afe_set_mode(dev, AFE_MODE_BASEBAND);
+ break;
+ case CX231XX_VMUX_TELEVISION:
+ case CX231XX_VMUX_CABLE:
+ default:
+ switch (dev->model) {
+ case CX231XX_BOARD_CNXT_RDE_250:
+ case CX231XX_BOARD_CNXT_RDU_250:
+ /* Disable the use of DIF */
+
+ status = vid_blk_read_word(dev, AFE_CTRL, &value);
+ value |= (0 << 13) | (1 << 4);
+ value &= ~(1 << 5);
+
+ /* set [24:23] [22:15] to 0 */
+ value &= (~(0x1FF8000));
+ /* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0 */
+ value |= 0x1000000;
+ status = vid_blk_write_word(dev, AFE_CTRL, value);
+
+ status = vid_blk_read_word(dev, OUT_CTRL1, &value);
+ value |= (1 << 7);
+ status = vid_blk_write_word(dev, OUT_CTRL1, value);
+
+ /* Set vip 1.1 output mode */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ OUT_CTRL1, FLD_OUT_MODE,
+ OUT_MODE_VIP11);
+
+ /* Tell DIF object to go to baseband mode */
+ status = cx231xx_dif_set_standard(dev,
+ DIF_USE_BASEBAND);
+ if (status < 0) {
+ cx231xx_errdev("%s: cx231xx_dif set to By pass"
+ " mode- errCode [%d]!\n",
+ __func__, status);
+ return status;
+ }
+
+ /* Read the DFE_CTRL1 register */
+ status = vid_blk_read_word(dev, DFE_CTRL1, &value);
+
+ /* enable the VBI_GATE_EN */
+ value |= FLD_VBI_GATE_EN;
+
+ /* Enable the auto-VGA enable */
+ value |= FLD_VGA_AUTO_EN;
+
+ /* Write it back */
+ status = vid_blk_write_word(dev, DFE_CTRL1, value);
+
+ /* Disable auto config of registers */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ MODE_CTRL, FLD_ACFG_DIS,
+ cx231xx_set_field(FLD_ACFG_DIS, 1));
+
+ /* Set CVBS input mode */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ MODE_CTRL, FLD_INPUT_MODE,
+ cx231xx_set_field(FLD_INPUT_MODE,
+ INPUT_MODE_CVBS_0));
+ break;
+ default:
+ /* Enable the DIF for the tuner */
+
+ /* Reinitialize the DIF */
+ status = cx231xx_dif_set_standard(dev, dev->norm);
+ if (status < 0) {
+ cx231xx_errdev("%s: cx231xx_dif set to By pass"
+ " mode- errCode [%d]!\n",
+ __func__, status);
+ return status;
+ }
+
+ /* Make sure bypass is cleared */
+ status = vid_blk_read_word(dev, DIF_MISC_CTRL, &value);
+
+ /* Clear the bypass bit */
+ value &= ~FLD_DIF_DIF_BYPASS;
+
+ /* Enable the use of the DIF block */
+ status = vid_blk_write_word(dev, DIF_MISC_CTRL, value);
+
+ /* Read the DFE_CTRL1 register */
+ status = vid_blk_read_word(dev, DFE_CTRL1, &value);
+
+ /* Disable the VBI_GATE_EN */
+ value &= ~FLD_VBI_GATE_EN;
+
+ /* Enable the auto-VGA enable, AGC, and
+ set the skip count to 2 */
+ value |= FLD_VGA_AUTO_EN | FLD_AGC_AUTO_EN | 0x00200000;
+
+ /* Write it back */
+ status = vid_blk_write_word(dev, DFE_CTRL1, value);
+
+ /* Wait until AGC locks up */
+ msleep(1);
+
+ /* Disable the auto-VGA enable AGC */
+ value &= ~(FLD_VGA_AUTO_EN);
+
+ /* Write it back */
+ status = vid_blk_write_word(dev, DFE_CTRL1, value);
+
+ /* Enable Polaris B0 AGC output */
+ status = vid_blk_read_word(dev, PIN_CTRL, &value);
+ value |= (FLD_OEF_AGC_RF) |
+ (FLD_OEF_AGC_IFVGA) |
+ (FLD_OEF_AGC_IF);
+ status = vid_blk_write_word(dev, PIN_CTRL, value);
+
+ /* Set vip 1.1 output mode */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ OUT_CTRL1, FLD_OUT_MODE,
+ OUT_MODE_VIP11);
+
+ /* Disable auto config of registers */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ MODE_CTRL, FLD_ACFG_DIS,
+ cx231xx_set_field(FLD_ACFG_DIS, 1));
+
+ /* Set CVBS input mode */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ MODE_CTRL, FLD_INPUT_MODE,
+ cx231xx_set_field(FLD_INPUT_MODE,
+ INPUT_MODE_CVBS_0));
+
+ /* Set some bits in AFE_CTRL so that channel 2 or 3
+ * is ready to receive audio */
+ /* Clear clamp for channels 2 and 3 (bit 16-17) */
+ /* Clear droop comp (bit 19-20) */
+ /* Set VGA_SEL (for audio control) (bit 7-8) */
+ status = vid_blk_read_word(dev, AFE_CTRL, &value);
+
+ value |= FLD_VGA_SEL_CH3 | FLD_VGA_SEL_CH2;
+
+ status = vid_blk_write_word(dev, AFE_CTRL, value);
+ break;
+
+ }
+ break;
+ }
+
+ /* Set raw VBI mode */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ OUT_CTRL1, FLD_VBIHACTRAW_EN,
+ cx231xx_set_field(FLD_VBIHACTRAW_EN, 1));
+
+ status = vid_blk_read_word(dev, OUT_CTRL1, &value);
+ if (value & 0x02) {
+ value |= (1 << 19);
+ status = vid_blk_write_word(dev, OUT_CTRL1, value);
+ }
+
+ return status;
+}
+
+/*
+ * Handle any video-mode specific overrides that are different
+ * on a per video standards basis after touching the MODE_CTRL
+ * register which resets many values for autodetect
+ */
+int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev)
+{
+ int status = 0;
+
+ cx231xx_info("do_mode_ctrl_overrides : 0x%x\n",
+ (unsigned int)dev->norm);
+
+ /* Change the DFE_CTRL3 bp_percent to fix flagging */
+ status = vid_blk_write_word(dev, DFE_CTRL3, 0xCD3F0280);
+
+ if (dev->norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) {
+ cx231xx_info("do_mode_ctrl_overrides NTSC\n");
+
+ /* Move the close caption lines out of active video,
+ adjust the active video start point */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ VERT_TIM_CTRL,
+ FLD_VBLANK_CNT, 0x18);
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ VERT_TIM_CTRL,
+ FLD_VACTIVE_CNT,
+ 0x1E6000);
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ VERT_TIM_CTRL,
+ FLD_V656BLANK_CNT,
+ 0x1E000000);
+
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ HORIZ_TIM_CTRL,
+ FLD_HBLANK_CNT,
+ cx231xx_set_field
+ (FLD_HBLANK_CNT, 0x79));
+ } else if (dev->norm & V4L2_STD_SECAM) {
+ cx231xx_info("do_mode_ctrl_overrides SECAM\n");
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ VERT_TIM_CTRL,
+ FLD_VBLANK_CNT, 0x24);
+ /* Adjust the active video horizontal start point */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ HORIZ_TIM_CTRL,
+ FLD_HBLANK_CNT,
+ cx231xx_set_field
+ (FLD_HBLANK_CNT, 0x85));
+ } else {
+ cx231xx_info("do_mode_ctrl_overrides PAL\n");
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ VERT_TIM_CTRL,
+ FLD_VBLANK_CNT, 0x24);
+ /* Adjust the active video horizontal start point */
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ HORIZ_TIM_CTRL,
+ FLD_HBLANK_CNT,
+ cx231xx_set_field
+ (FLD_HBLANK_CNT, 0x85));
+ }
+
+ return status;
+}
+
+int cx231xx_set_audio_input(struct cx231xx *dev, u8 input)
+{
+ int status = 0;
+ enum AUDIO_INPUT ainput = AUDIO_INPUT_LINE;
+
+ switch (INPUT(input)->amux) {
+ case CX231XX_AMUX_VIDEO:
+ ainput = AUDIO_INPUT_TUNER_TV;
+ break;
+ case CX231XX_AMUX_LINE_IN:
+ status = cx231xx_i2s_blk_set_audio_input(dev, input);
+ ainput = AUDIO_INPUT_LINE;
+ break;
+ default:
+ break;
+ }
+
+ status = cx231xx_set_audio_decoder_input(dev, ainput);
+
+ return status;
+}
+
+int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
+ enum AUDIO_INPUT audio_input)
+{
+ u32 dwval;
+ int status;
+ u8 gen_ctrl;
+ u32 value = 0;
+
+ /* Put it in soft reset */
+ status = vid_blk_read_byte(dev, GENERAL_CTL, &gen_ctrl);
+ gen_ctrl |= 1;
+ status = vid_blk_write_byte(dev, GENERAL_CTL, gen_ctrl);
+
+ switch (audio_input) {
+ case AUDIO_INPUT_LINE:
+ /* setup AUD_IO control from Merlin paralle output */
+ value = cx231xx_set_field(FLD_AUD_CHAN1_SRC,
+ AUD_CHAN_SRC_PARALLEL);
+ status = vid_blk_write_word(dev, AUD_IO_CTRL, value);
+
+ /* setup input to Merlin, SRC2 connect to AC97
+ bypass upsample-by-2, slave mode, sony mode, left justify
+ adr 091c, dat 01000000 */
+ status = vid_blk_read_word(dev, AC97_CTL, &dwval);
+
+ status = vid_blk_write_word(dev, AC97_CTL,
+ (dwval | FLD_AC97_UP2X_BYPASS));
+
+ /* select the parallel1 and SRC3 */
+ status = vid_blk_write_word(dev, BAND_OUT_SEL,
+ cx231xx_set_field(FLD_SRC3_IN_SEL, 0x0) |
+ cx231xx_set_field(FLD_SRC3_CLK_SEL, 0x0) |
+ cx231xx_set_field(FLD_PARALLEL1_SRC_SEL, 0x0));
+
+ /* unmute all, AC97 in, independence mode
+ adr 08d0, data 0x00063073 */
+ status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063073);
+
+ /* set AVC maximum threshold, adr 08d4, dat ffff0024 */
+ status = vid_blk_read_word(dev, PATH1_VOL_CTL, &dwval);
+ status = vid_blk_write_word(dev, PATH1_VOL_CTL,
+ (dwval | FLD_PATH1_AVC_THRESHOLD));
+
+ /* set SC maximum threshold, adr 08ec, dat ffffb3a3 */
+ status = vid_blk_read_word(dev, PATH1_SC_CTL, &dwval);
+ status = vid_blk_write_word(dev, PATH1_SC_CTL,
+ (dwval | FLD_PATH1_SC_THRESHOLD));
+ break;
+
+ case AUDIO_INPUT_TUNER_TV:
+ default:
+
+ /* Setup SRC sources and clocks */
+ status = vid_blk_write_word(dev, BAND_OUT_SEL,
+ cx231xx_set_field(FLD_SRC6_IN_SEL, 0x00) |
+ cx231xx_set_field(FLD_SRC6_CLK_SEL, 0x01) |
+ cx231xx_set_field(FLD_SRC5_IN_SEL, 0x00) |
+ cx231xx_set_field(FLD_SRC5_CLK_SEL, 0x02) |
+ cx231xx_set_field(FLD_SRC4_IN_SEL, 0x02) |
+ cx231xx_set_field(FLD_SRC4_CLK_SEL, 0x03) |
+ cx231xx_set_field(FLD_SRC3_IN_SEL, 0x00) |
+ cx231xx_set_field(FLD_SRC3_CLK_SEL, 0x00) |
+ cx231xx_set_field(FLD_BASEBAND_BYPASS_CTL, 0x00) |
+ cx231xx_set_field(FLD_AC97_SRC_SEL, 0x03) |
+ cx231xx_set_field(FLD_I2S_SRC_SEL, 0x00) |
+ cx231xx_set_field(FLD_PARALLEL2_SRC_SEL, 0x02) |
+ cx231xx_set_field(FLD_PARALLEL1_SRC_SEL, 0x01));
+
+ /* Setup the AUD_IO control */
+ status = vid_blk_write_word(dev, AUD_IO_CTRL,
+ cx231xx_set_field(FLD_I2S_PORT_DIR, 0x00) |
+ cx231xx_set_field(FLD_I2S_OUT_SRC, 0x00) |
+ cx231xx_set_field(FLD_AUD_CHAN3_SRC, 0x00) |
+ cx231xx_set_field(FLD_AUD_CHAN2_SRC, 0x00) |
+ cx231xx_set_field(FLD_AUD_CHAN1_SRC, 0x03));
+
+ status = vid_blk_write_word(dev, PATH1_CTL1, 0x1F063870);
+
+ /* setAudioStandard(_audio_standard); */
+
+ status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063870);
+ switch (dev->model) {
+ case CX231XX_BOARD_CNXT_RDE_250:
+ case CX231XX_BOARD_CNXT_RDU_250:
+ status = cx231xx_read_modify_write_i2c_dword(dev,
+ VID_BLK_I2C_ADDRESS,
+ CHIP_CTRL,
+ FLD_SIF_EN,
+ cx231xx_set_field(FLD_SIF_EN, 1));
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case AUDIO_INPUT_TUNER_FM:
+ /* use SIF for FM radio
+ setupFM();
+ setAudioStandard(_audio_standard);
+ */
+ break;
+
+ case AUDIO_INPUT_MUTE:
+ status = vid_blk_write_word(dev, PATH1_CTL1, 0x1F011012);
+ break;
+ }
+
+ /* Take it out of soft reset */
+ status = vid_blk_read_byte(dev, GENERAL_CTL, &gen_ctrl);
+ gen_ctrl &= ~1;
+ status = vid_blk_write_byte(dev, GENERAL_CTL, gen_ctrl);
+
+ return status;
+}
+
+/* Set resolution of the video */
+int cx231xx_resolution_set(struct cx231xx *dev)
+{
+ int width, height;
+ u32 hscale, vscale;
+ int status = 0;
+
+ width = dev->width;
+ height = dev->height;
+
+ get_scale(dev, width, height, &hscale, &vscale);
+
+ /* set horzontal scale */
+ status = vid_blk_write_word(dev, HSCALE_CTRL, hscale);
+
+ /* set vertical scale */
+ status = vid_blk_write_word(dev, VSCALE_CTRL, vscale);
+
+ return status;
+}
+
+/******************************************************************************
+ * C H I P Specific C O N T R O L functions *
+ ******************************************************************************/
+int cx231xx_init_ctrl_pin_status(struct cx231xx *dev)
+{
+ u32 value;
+ int status = 0;
+
+ status = vid_blk_read_word(dev, PIN_CTRL, &value);
+ value |= (~dev->board.ctl_pin_status_mask);
+ status = vid_blk_write_word(dev, PIN_CTRL, value);
+
+ return status;
+}
+
+int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev,
+ u8 analog_or_digital)
+{
+ int status = 0;
+
+ /* first set the direction to output */
+ status = cx231xx_set_gpio_direction(dev,
+ dev->board.
+ agc_analog_digital_select_gpio, 1);
+
+ /* 0 - demod ; 1 - Analog mode */
+ status = cx231xx_set_gpio_value(dev,
+ dev->board.agc_analog_digital_select_gpio,
+ analog_or_digital);
+
+ return status;
+}
+
+int cx231xx_enable_i2c_for_tuner(struct cx231xx *dev, u8 I2CIndex)
+{
+ u8 value[4] = { 0, 0, 0, 0 };
+ int status = 0;
+
+ cx231xx_info("Changing the i2c port for tuner to %d\n", I2CIndex);
+
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ if (status < 0)
+ return status;
+
+ if (I2CIndex == I2C_1) {
+ if (value[0] & I2C_DEMOD_EN) {
+ value[0] &= ~I2C_DEMOD_EN;
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ }
+ } else {
+ if (!(value[0] & I2C_DEMOD_EN)) {
+ value[0] |= I2C_DEMOD_EN;
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ }
+ }
+
+ return status;
+
+}
+
+/******************************************************************************
+ * D I F - B L O C K C O N T R O L functions *
+ ******************************************************************************/
+int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode,
+ u32 function_mode, u32 standard)
+{
+ int status = 0;
+
+ if (mode == V4L2_TUNER_RADIO) {
+ /* C2HH */
+ /* lo if big signal */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
+ /* FUNC_MODE = DIF */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 23, 24, function_mode);
+ /* IF_MODE */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xFF);
+ /* no inv */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
+ } else if (standard != DIF_USE_BASEBAND) {
+ if (standard & V4L2_STD_MN) {
+ /* lo if big signal */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
+ /* FUNC_MODE = DIF */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
+ function_mode);
+ /* IF_MODE */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xb);
+ /* no inv */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
+ /* 0x124, AUD_CHAN1_SRC = 0x3 */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AUD_IO_CTRL, 0, 31, 0x00000003);
+ } else if ((standard == V4L2_STD_PAL_I) |
+ (standard & V4L2_STD_SECAM)) {
+ /* C2HH setup */
+ /* lo if big signal */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
+ /* FUNC_MODE = DIF */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
+ function_mode);
+ /* IF_MODE */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xF);
+ /* no inv */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
+ } else {
+ /* default PAL BG */
+ /* C2HH setup */
+ /* lo if big signal */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
+ /* FUNC_MODE = DIF */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
+ function_mode);
+ /* IF_MODE */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xE);
+ /* no inv */
+ status = cx231xx_reg_mask_write(dev,
+ VID_BLK_I2C_ADDRESS, 32,
+ AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
+ }
+ }
+
+ return status;
+}
+
+int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard)
+{
+ int status = 0;
+ u32 dif_misc_ctrl_value = 0;
+ u32 func_mode = 0;
+
+ cx231xx_info("%s: setStandard to %x\n", __func__, standard);
+
+ status = vid_blk_read_word(dev, DIF_MISC_CTRL, &dif_misc_ctrl_value);
+ if (standard != DIF_USE_BASEBAND)
+ dev->norm = standard;
+
+ switch (dev->model) {
+ case CX231XX_BOARD_CNXT_RDE_250:
+ case CX231XX_BOARD_CNXT_RDU_250:
+ func_mode = 0x03;
+ break;
+ default:
+ func_mode = 0x01;
+ }
+
+ status = cx231xx_dif_configure_C2HH_for_low_IF(dev, dev->active_mode,
+ func_mode, standard);
+
+ if (standard == DIF_USE_BASEBAND) { /* base band */
+ /* There is a different SRC_PHASE_INC value
+ for baseband vs. DIF */
+ status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC, 0xDF7DF83);
+ status = vid_blk_read_word(dev, DIF_MISC_CTRL,
+ &dif_misc_ctrl_value);
+ dif_misc_ctrl_value |= FLD_DIF_DIF_BYPASS;
+ status = vid_blk_write_word(dev, DIF_MISC_CTRL,
+ dif_misc_ctrl_value);
+ } else if (standard & V4L2_STD_PAL_D) {
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL3, 0, 31, 0x00008800);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_IF_REF, 0, 31, 0x444C1380);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_IF_INT_CURRENT, 0, 31,
+ 0x26001700);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_RF_CURRENT, 0, 31,
+ 0x00002660);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_VIDEO_AGC_CTRL, 0, 31,
+ 0x72500800);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_VID_AUD_OVERRIDE, 0, 31,
+ 0x27000100);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AV_SEP_CTRL, 0, 31, 0x3F3934EA);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_COMP_FLT_CTRL, 0, 31,
+ 0x00000000);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_SRC_PHASE_INC, 0, 31,
+ 0x1befbf06);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_SRC_GAIN_CONTROL, 0, 31,
+ 0x000035e8);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_RPT_VARIANCE, 0, 31, 0x00000000);
+ /* Save the Spec Inversion value */
+ dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+ dif_misc_ctrl_value |= 0x3a023F11;
+ } else if (standard & V4L2_STD_PAL_I) {
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL3, 0, 31, 0x00008800);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_IF_REF, 0, 31, 0x444C1380);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_IF_INT_CURRENT, 0, 31,
+ 0x26001700);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_RF_CURRENT, 0, 31,
+ 0x00002660);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_VIDEO_AGC_CTRL, 0, 31,
+ 0x72500800);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_VID_AUD_OVERRIDE, 0, 31,
+ 0x27000100);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AV_SEP_CTRL, 0, 31, 0x5F39A934);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_COMP_FLT_CTRL, 0, 31,
+ 0x00000000);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_SRC_PHASE_INC, 0, 31,
+ 0x1befbf06);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_SRC_GAIN_CONTROL, 0, 31,
+ 0x000035e8);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_RPT_VARIANCE, 0, 31, 0x00000000);
+ /* Save the Spec Inversion value */
+ dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+ dif_misc_ctrl_value |= 0x3a033F11;
+ } else if (standard & V4L2_STD_PAL_M) {
+ /* improved Low Frequency Phase Noise */
+ status = vid_blk_write_word(dev, DIF_PLL_CTRL, 0xFF01FF0C);
+ status = vid_blk_write_word(dev, DIF_PLL_CTRL1, 0xbd038c85);
+ status = vid_blk_write_word(dev, DIF_PLL_CTRL2, 0x1db4640a);
+ status = vid_blk_write_word(dev, DIF_PLL_CTRL3, 0x00008800);
+ status = vid_blk_write_word(dev, DIF_AGC_IF_REF, 0x444C1380);
+ status = vid_blk_write_word(dev, DIF_AGC_IF_INT_CURRENT,
+ 0x26001700);
+ status = vid_blk_write_word(dev, DIF_AGC_RF_CURRENT,
+ 0x00002660);
+ status = vid_blk_write_word(dev, DIF_VIDEO_AGC_CTRL,
+ 0x72500800);
+ status = vid_blk_write_word(dev, DIF_VID_AUD_OVERRIDE,
+ 0x27000100);
+ status = vid_blk_write_word(dev, DIF_AV_SEP_CTRL, 0x012c405d);
+ status = vid_blk_write_word(dev, DIF_COMP_FLT_CTRL,
+ 0x009f50c1);
+ status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC,
+ 0x1befbf06);
+ status = vid_blk_write_word(dev, DIF_SRC_GAIN_CONTROL,
+ 0x000035e8);
+ status = vid_blk_write_word(dev, DIF_SOFT_RST_CTRL_REVB,
+ 0x00000000);
+ /* Save the Spec Inversion value */
+ dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+ dif_misc_ctrl_value |= 0x3A0A3F10;
+ } else if (standard & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) {
+ /* improved Low Frequency Phase Noise */
+ status = vid_blk_write_word(dev, DIF_PLL_CTRL, 0xFF01FF0C);
+ status = vid_blk_write_word(dev, DIF_PLL_CTRL1, 0xbd038c85);
+ status = vid_blk_write_word(dev, DIF_PLL_CTRL2, 0x1db4640a);
+ status = vid_blk_write_word(dev, DIF_PLL_CTRL3, 0x00008800);
+ status = vid_blk_write_word(dev, DIF_AGC_IF_REF, 0x444C1380);
+ status = vid_blk_write_word(dev, DIF_AGC_IF_INT_CURRENT,
+ 0x26001700);
+ status = vid_blk_write_word(dev, DIF_AGC_RF_CURRENT,
+ 0x00002660);
+ status = vid_blk_write_word(dev, DIF_VIDEO_AGC_CTRL,
+ 0x72500800);
+ status = vid_blk_write_word(dev, DIF_VID_AUD_OVERRIDE,
+ 0x27000100);
+ status = vid_blk_write_word(dev, DIF_AV_SEP_CTRL,
+ 0x012c405d);
+ status = vid_blk_write_word(dev, DIF_COMP_FLT_CTRL,
+ 0x009f50c1);
+ status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC,
+ 0x1befbf06);
+ status = vid_blk_write_word(dev, DIF_SRC_GAIN_CONTROL,
+ 0x000035e8);
+ status = vid_blk_write_word(dev, DIF_SOFT_RST_CTRL_REVB,
+ 0x00000000);
+ /* Save the Spec Inversion value */
+ dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+ dif_misc_ctrl_value = 0x3A093F10;
+ } else if (standard &
+ (V4L2_STD_SECAM_B | V4L2_STD_SECAM_D | V4L2_STD_SECAM_G |
+ V4L2_STD_SECAM_K | V4L2_STD_SECAM_K1)) {
+
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL3, 0, 31, 0x00008800);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_IF_REF, 0, 31, 0x888C0380);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_IF, 0, 31, 0xe0262600);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_INT, 0, 31, 0xc2171700);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_RF, 0, 31, 0xc2262600);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_IF_INT_CURRENT, 0, 31,
+ 0x26001700);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_RF_CURRENT, 0, 31,
+ 0x00002660);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_VID_AUD_OVERRIDE, 0, 31,
+ 0x27000100);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AV_SEP_CTRL, 0, 31, 0x3F3530ec);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_COMP_FLT_CTRL, 0, 31,
+ 0x00000000);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_SRC_PHASE_INC, 0, 31,
+ 0x1befbf06);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_SRC_GAIN_CONTROL, 0, 31,
+ 0x000035e8);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_RPT_VARIANCE, 0, 31, 0x00000000);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_VIDEO_AGC_CTRL, 0, 31,
+ 0xf4000000);
+
+ /* Save the Spec Inversion value */
+ dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+ dif_misc_ctrl_value |= 0x3a023F11;
+ } else if (standard & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) {
+ /* Is it SECAM_L1? */
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL3, 0, 31, 0x00008800);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_IF_REF, 0, 31, 0x888C0380);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_IF, 0, 31, 0xe0262600);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_INT, 0, 31, 0xc2171700);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_RF, 0, 31, 0xc2262600);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_IF_INT_CURRENT, 0, 31,
+ 0x26001700);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_RF_CURRENT, 0, 31,
+ 0x00002660);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_VID_AUD_OVERRIDE, 0, 31,
+ 0x27000100);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AV_SEP_CTRL, 0, 31, 0x3F3530ec);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_COMP_FLT_CTRL, 0, 31,
+ 0x00000000);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_SRC_PHASE_INC, 0, 31,
+ 0x1befbf06);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_SRC_GAIN_CONTROL, 0, 31,
+ 0x000035e8);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_RPT_VARIANCE, 0, 31, 0x00000000);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_VIDEO_AGC_CTRL, 0, 31,
+ 0xf2560000);
+
+ /* Save the Spec Inversion value */
+ dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+ dif_misc_ctrl_value |= 0x3a023F11;
+
+ } else if (standard & V4L2_STD_NTSC_M) {
+ /* V4L2_STD_NTSC_M (75 IRE Setup) Or
+ V4L2_STD_NTSC_M_JP (Japan, 0 IRE Setup) */
+
+ /* For NTSC the centre frequency of video coming out of
+ sidewinder is around 7.1MHz or 3.6MHz depending on the
+ spectral inversion. so for a non spectrally inverted channel
+ the pll freq word is 0x03420c49
+ */
+
+ status = vid_blk_write_word(dev, DIF_PLL_CTRL, 0x6503BC0C);
+ status = vid_blk_write_word(dev, DIF_PLL_CTRL1, 0xBD038C85);
+ status = vid_blk_write_word(dev, DIF_PLL_CTRL2, 0x1DB4640A);
+ status = vid_blk_write_word(dev, DIF_PLL_CTRL3, 0x00008800);
+ status = vid_blk_write_word(dev, DIF_AGC_IF_REF, 0x444C0380);
+ status = vid_blk_write_word(dev, DIF_AGC_IF_INT_CURRENT,
+ 0x26001700);
+ status = vid_blk_write_word(dev, DIF_AGC_RF_CURRENT,
+ 0x00002660);
+ status = vid_blk_write_word(dev, DIF_VIDEO_AGC_CTRL,
+ 0x04000800);
+ status = vid_blk_write_word(dev, DIF_VID_AUD_OVERRIDE,
+ 0x27000100);
+ status = vid_blk_write_word(dev, DIF_AV_SEP_CTRL, 0x01296e1f);
+
+ status = vid_blk_write_word(dev, DIF_COMP_FLT_CTRL,
+ 0x009f50c1);
+ status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC,
+ 0x1befbf06);
+ status = vid_blk_write_word(dev, DIF_SRC_GAIN_CONTROL,
+ 0x000035e8);
+
+ status = vid_blk_write_word(dev, DIF_AGC_CTRL_IF, 0xC2262600);
+ status = vid_blk_write_word(dev, DIF_AGC_CTRL_INT,
+ 0xC2262600);
+ status = vid_blk_write_word(dev, DIF_AGC_CTRL_RF, 0xC2262600);
+
+ /* Save the Spec Inversion value */
+ dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+ dif_misc_ctrl_value |= 0x3a003F10;
+ } else {
+ /* default PAL BG */
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_PLL_CTRL3, 0, 31, 0x00008800);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_IF_REF, 0, 31, 0x444C1380);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_IF_INT_CURRENT, 0, 31,
+ 0x26001700);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AGC_RF_CURRENT, 0, 31,
+ 0x00002660);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_VIDEO_AGC_CTRL, 0, 31,
+ 0x72500800);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_VID_AUD_OVERRIDE, 0, 31,
+ 0x27000100);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_AV_SEP_CTRL, 0, 31, 0x3F3530EC);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_COMP_FLT_CTRL, 0, 31,
+ 0x00A653A8);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_SRC_PHASE_INC, 0, 31,
+ 0x1befbf06);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_SRC_GAIN_CONTROL, 0, 31,
+ 0x000035e8);
+ status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+ DIF_RPT_VARIANCE, 0, 31, 0x00000000);
+ /* Save the Spec Inversion value */
+ dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+ dif_misc_ctrl_value |= 0x3a013F11;
+ }
+
+ /* The AGC values should be the same for all standards,
+ AUD_SRC_SEL[19] should always be disabled */
+ dif_misc_ctrl_value &= ~FLD_DIF_AUD_SRC_SEL;
+
+ /* It is still possible to get Set Standard calls even when we
+ are in FM mode.
+ This is done to override the value for FM. */
+ if (dev->active_mode == V4L2_TUNER_RADIO)
+ dif_misc_ctrl_value = 0x7a080000;
+
+ /* Write the calculated value for misc ontrol register */
+ status = vid_blk_write_word(dev, DIF_MISC_CTRL, dif_misc_ctrl_value);
+
+ return status;
+}
+
+int cx231xx_tuner_pre_channel_change(struct cx231xx *dev)
+{
+ int status = 0;
+ u32 dwval;
+
+ /* Set the RF and IF k_agc values to 3 */
+ status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval);
+ dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
+ dwval |= 0x33000000;
+
+ status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval);
+
+ return status;
+}
+
+int cx231xx_tuner_post_channel_change(struct cx231xx *dev)
+{
+ int status = 0;
+ u32 dwval;
+
+ /* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for
+ * SECAM L/B/D standards */
+ status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval);
+ dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
+
+ if (dev->norm & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_B |
+ V4L2_STD_SECAM_D))
+ dwval |= 0x88000000;
+ else
+ dwval |= 0x44000000;
+
+ status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval);
+
+ return status;
+}
+
+/******************************************************************************
+ * I 2 S - B L O C K C O N T R O L functions *
+ ******************************************************************************/
+int cx231xx_i2s_blk_initialize(struct cx231xx *dev)
+{
+ int status = 0;
+ u32 value;
+
+ status = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+ CH_PWR_CTRL1, 1, &value, 1);
+ /* enables clock to delta-sigma and decimation filter */
+ value |= 0x80;
+ status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+ CH_PWR_CTRL1, 1, value, 1);
+ /* power up all channel */
+ status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+ CH_PWR_CTRL2, 1, 0x00, 1);
+
+ return status;
+}
+
+int cx231xx_i2s_blk_update_power_control(struct cx231xx *dev,
+ enum AV_MODE avmode)
+{
+ int status = 0;
+ u32 value = 0;
+
+ if (avmode != POLARIS_AVMODE_ENXTERNAL_AV) {
+ status = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+ CH_PWR_CTRL2, 1, &value, 1);
+ value |= 0xfe;
+ status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+ CH_PWR_CTRL2, 1, value, 1);
+ } else {
+ status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+ CH_PWR_CTRL2, 1, 0x00, 1);
+ }
+
+ return status;
+}
+
+/* set i2s_blk for audio input types */
+int cx231xx_i2s_blk_set_audio_input(struct cx231xx *dev, u8 audio_input)
+{
+ int status = 0;
+
+ switch (audio_input) {
+ case CX231XX_AMUX_LINE_IN:
+ status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+ CH_PWR_CTRL2, 1, 0x00, 1);
+ status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+ CH_PWR_CTRL1, 1, 0x80, 1);
+ break;
+ case CX231XX_AMUX_VIDEO:
+ default:
+ break;
+ }
+
+ dev->ctl_ainput = audio_input;
+
+ return status;
+}
+
+/******************************************************************************
+ * P O W E R C O N T R O L functions *
+ ******************************************************************************/
+int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode)
+{
+ u8 value[4] = { 0, 0, 0, 0 };
+ u32 tmp = 0;
+ int status = 0;
+
+ if (dev->power_mode != mode)
+ dev->power_mode = mode;
+ else {
+ cx231xx_info(" setPowerMode::mode = %d, No Change req.\n",
+ mode);
+ return 0;
+ }
+
+ cx231xx_info(" setPowerMode::mode = %d\n", mode);
+
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
+ 4);
+ if (status < 0)
+ return status;
+
+ tmp = *((u32 *) value);
+
+ switch (mode) {
+ case POLARIS_AVMODE_ENXTERNAL_AV:
+
+ tmp &= (~PWR_MODE_MASK);
+
+ tmp |= PWR_AV_EN;
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ msleep(PWR_SLEEP_INTERVAL);
+
+ tmp |= PWR_ISO_EN;
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status =
+ cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN,
+ value, 4);
+ msleep(PWR_SLEEP_INTERVAL);
+
+ tmp |= POLARIS_AVMODE_ENXTERNAL_AV;
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+
+ /* reset state of xceive tuner */
+ dev->xc_fw_load_done = 0;
+ break;
+
+ case POLARIS_AVMODE_ANALOGT_TV:
+
+ tmp &= (~PWR_DEMOD_EN);
+ tmp |= (I2C_DEMOD_EN);
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ msleep(PWR_SLEEP_INTERVAL);
+
+ if (!(tmp & PWR_TUNER_EN)) {
+ tmp |= (PWR_TUNER_EN);
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ msleep(PWR_SLEEP_INTERVAL);
+ }
+
+ if (!(tmp & PWR_AV_EN)) {
+ tmp |= PWR_AV_EN;
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ msleep(PWR_SLEEP_INTERVAL);
+ }
+ if (!(tmp & PWR_ISO_EN)) {
+ tmp |= PWR_ISO_EN;
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ msleep(PWR_SLEEP_INTERVAL);
+ }
+
+ if (!(tmp & POLARIS_AVMODE_ANALOGT_TV)) {
+ tmp |= POLARIS_AVMODE_ANALOGT_TV;
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ msleep(PWR_SLEEP_INTERVAL);
+ }
+
+ if ((dev->model == CX231XX_BOARD_CNXT_RDE_250) ||
+ (dev->model == CX231XX_BOARD_CNXT_RDU_250)) {
+ /* tuner path to channel 1 from port 3 */
+ cx231xx_enable_i2c_for_tuner(dev, I2C_3);
+
+ if (dev->cx231xx_reset_analog_tuner)
+ dev->cx231xx_reset_analog_tuner(dev);
+ }
+ break;
+
+ case POLARIS_AVMODE_DIGITAL:
+ if (!(tmp & PWR_TUNER_EN)) {
+ tmp |= (PWR_TUNER_EN);
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ msleep(PWR_SLEEP_INTERVAL);
+ }
+ if (!(tmp & PWR_AV_EN)) {
+ tmp |= PWR_AV_EN;
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ msleep(PWR_SLEEP_INTERVAL);
+ }
+ if (!(tmp & PWR_ISO_EN)) {
+ tmp |= PWR_ISO_EN;
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ msleep(PWR_SLEEP_INTERVAL);
+ }
+
+ tmp |= POLARIS_AVMODE_DIGITAL | I2C_DEMOD_EN;
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ msleep(PWR_SLEEP_INTERVAL);
+
+ if (!(tmp & PWR_DEMOD_EN)) {
+ tmp |= PWR_DEMOD_EN;
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ msleep(PWR_SLEEP_INTERVAL);
+ }
+
+ if ((dev->model == CX231XX_BOARD_CNXT_RDE_250) ||
+ (dev->model == CX231XX_BOARD_CNXT_RDU_250)) {
+ /* tuner path to channel 1 from port 3 */
+ cx231xx_enable_i2c_for_tuner(dev, I2C_3);
+
+ if (dev->cx231xx_reset_analog_tuner)
+ dev->cx231xx_reset_analog_tuner(dev);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ msleep(PWR_SLEEP_INTERVAL);
+
+ /* For power saving, only enable Pwr_resetout_n
+ when digital TV is selected. */
+ if (mode == POLARIS_AVMODE_DIGITAL) {
+ tmp |= PWR_RESETOUT_EN;
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ PWR_CTL_EN, value, 4);
+ msleep(PWR_SLEEP_INTERVAL);
+ }
+
+ /* update power control for afe */
+ status = cx231xx_afe_update_power_control(dev, mode);
+
+ /* update power control for i2s_blk */
+ status = cx231xx_i2s_blk_update_power_control(dev, mode);
+
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
+ 4);
+ cx231xx_info(" The data of PWR_CTL_EN register 0x74"
+ "=0x%0x,0x%0x,0x%0x,0x%0x\n",
+ value[0], value[1], value[2], value[3]);
+
+ return status;
+}
+
+int cx231xx_power_suspend(struct cx231xx *dev)
+{
+ u8 value[4] = { 0, 0, 0, 0 };
+ u32 tmp = 0;
+ int status = 0;
+
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN,
+ value, 4);
+ if (status > 0)
+ return status;
+
+ tmp = *((u32 *) value);
+ tmp &= (~PWR_MODE_MASK);
+
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN,
+ value, 4);
+
+ return status;
+}
+
+/******************************************************************************
+ * S T R E A M C O N T R O L functions *
+ ******************************************************************************/
+int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask)
+{
+ u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
+ u32 tmp = 0;
+ int status = 0;
+
+ cx231xx_info("cx231xx_start_stream():: ep_mask = %x\n", ep_mask);
+ status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET,
+ value, 4);
+ if (status < 0)
+ return status;
+
+ tmp = *((u32 *) value);
+ tmp |= ep_mask;
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, EP_MODE_SET,
+ value, 4);
+
+ return status;
+}
+
+int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask)
+{
+ u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
+ u32 tmp = 0;
+ int status = 0;
+
+ cx231xx_info("cx231xx_stop_stream():: ep_mask = %x\n", ep_mask);
+ status =
+ cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4);
+ if (status < 0)
+ return status;
+
+ tmp = *((u32 *) value);
+ tmp &= (~ep_mask);
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+
+ status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, EP_MODE_SET,
+ value, 4);
+
+ return status;
+}
+
+int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
+{
+ int status = 0;
+
+ if (dev->udev->speed == USB_SPEED_HIGH) {
+ switch (media_type) {
+ case 81: /* audio */
+ cx231xx_info("%s: Audio enter HANC\n", __func__);
+ status =
+ cx231xx_mode_register(dev, TS_MODE_REG, 0x9300);
+ break;
+
+ case 2: /* vbi */
+ cx231xx_info("%s: set vanc registers\n", __func__);
+ status = cx231xx_mode_register(dev, TS_MODE_REG, 0x300);
+ break;
+
+ case 3: /* sliced cc */
+ cx231xx_info("%s: set hanc registers\n", __func__);
+ status =
+ cx231xx_mode_register(dev, TS_MODE_REG, 0x1300);
+ break;
+
+ case 0: /* video */
+ cx231xx_info("%s: set video registers\n", __func__);
+ status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100);
+ break;
+
+ case 4: /* ts1 */
+ cx231xx_info("%s: set ts1 registers\n", __func__);
+ status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101);
+ status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400);
+ break;
+ case 6: /* ts1 parallel mode */
+ cx231xx_info("%s: set ts1 parrallel mode registers\n",
+ __func__);
+ status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100);
+ status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400);
+ break;
+ }
+ } else {
+ status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101);
+ }
+
+ return status;
+}
+
+int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type)
+{
+ int rc;
+ u32 ep_mask = -1;
+ struct pcb_config *pcb_config;
+
+ /* get EP for media type */
+ pcb_config = (struct pcb_config *)&dev->current_pcb_config;
+
+ if (pcb_config->config_num == 1) {
+ switch (media_type) {
+ case 0: /* Video */
+ ep_mask = ENABLE_EP4; /* ep4 [00:1000] */
+ break;
+ case 1: /* Audio */
+ ep_mask = ENABLE_EP3; /* ep3 [00:0100] */
+ break;
+ case 2: /* Vbi */
+ ep_mask = ENABLE_EP5; /* ep5 [01:0000] */
+ break;
+ case 3: /* Sliced_cc */
+ ep_mask = ENABLE_EP6; /* ep6 [10:0000] */
+ break;
+ case 4: /* ts1 */
+ case 6: /* ts1 parallel mode */
+ ep_mask = ENABLE_EP1; /* ep1 [00:0001] */
+ break;
+ case 5: /* ts2 */
+ ep_mask = ENABLE_EP2; /* ep2 [00:0010] */
+ break;
+ }
+
+ } else if (pcb_config->config_num > 1) {
+ switch (media_type) {
+ case 0: /* Video */
+ ep_mask = ENABLE_EP4; /* ep4 [00:1000] */
+ break;
+ case 1: /* Audio */
+ ep_mask = ENABLE_EP3; /* ep3 [00:0100] */
+ break;
+ case 2: /* Vbi */
+ ep_mask = ENABLE_EP5; /* ep5 [01:0000] */
+ break;
+ case 3: /* Sliced_cc */
+ ep_mask = ENABLE_EP6; /* ep6 [10:0000] */
+ break;
+ case 4: /* ts1 */
+ case 6: /* ts1 parallel mode */
+ ep_mask = ENABLE_EP1; /* ep1 [00:0001] */
+ break;
+ case 5: /* ts2 */
+ ep_mask = ENABLE_EP2; /* ep2 [00:0010] */
+ break;
+ }
+
+ }
+
+ if (start) {
+ rc = cx231xx_initialize_stream_xfer(dev, media_type);
+
+ if (rc < 0)
+ return rc;
+
+ /* enable video capture */
+ if (ep_mask > 0)
+ rc = cx231xx_start_stream(dev, ep_mask);
+ } else {
+ /* disable video capture */
+ if (ep_mask > 0)
+ rc = cx231xx_stop_stream(dev, ep_mask);
+ }
+
+ if (dev->mode == CX231XX_ANALOG_MODE)
+ ;/* do any in Analog mode */
+ else
+ ;/* do any in digital mode */
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(cx231xx_capture_start);
+
+/*****************************************************************************
+* G P I O B I T control functions *
+******************************************************************************/
+int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val)
+{
+ int status = 0;
+
+ status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 0);
+
+ return status;
+}
+
+int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val)
+{
+ int status = 0;
+
+ status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 1);
+
+ return status;
+}
+
+/*
+* cx231xx_set_gpio_direction
+* Sets the direction of the GPIO pin to input or output
+*
+* Parameters :
+* pin_number : The GPIO Pin number to program the direction for
+* from 0 to 31
+* pin_value : The Direction of the GPIO Pin under reference.
+* 0 = Input direction
+* 1 = Output direction
+*/
+int cx231xx_set_gpio_direction(struct cx231xx *dev,
+ int pin_number, int pin_value)
+{
+ int status = 0;
+ u32 value = 0;
+
+ /* Check for valid pin_number - if 32 , bail out */
+ if (pin_number >= 32)
+ return -EINVAL;
+
+ /* input */
+ if (pin_value == 0)
+ value = dev->gpio_dir & (~(1 << pin_number)); /* clear */
+ else
+ value = dev->gpio_dir | (1 << pin_number);
+
+ status = cx231xx_set_gpio_bit(dev, value, (u8 *) &dev->gpio_val);
+
+ /* cache the value for future */
+ dev->gpio_dir = value;
+
+ return status;
+}
+
+/*
+* cx231xx_set_gpio_value
+* Sets the value of the GPIO pin to Logic high or low. The Pin under
+* reference should ALREADY BE SET IN OUTPUT MODE !!!!!!!!!
+*
+* Parameters :
+* pin_number : The GPIO Pin number to program the direction for
+* pin_value : The value of the GPIO Pin under reference.
+* 0 = set it to 0
+* 1 = set it to 1
+*/
+int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value)
+{
+ int status = 0;
+ u32 value = 0;
+
+ /* Check for valid pin_number - if 0xFF , bail out */
+ if (pin_number >= 32)
+ return -EINVAL;
+
+ /* first do a sanity check - if the Pin is not output, make it output */
+ if ((dev->gpio_dir & (1 << pin_number)) == 0x00) {
+ /* It was in input mode */
+ value = dev->gpio_dir | (1 << pin_number);
+ dev->gpio_dir = value;
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+ (u8 *) &dev->gpio_val);
+ value = 0;
+ }
+
+ if (pin_value == 0)
+ value = dev->gpio_val & (~(1 << pin_number));
+ else
+ value = dev->gpio_val | (1 << pin_number);
+
+ /* store the value */
+ dev->gpio_val = value;
+
+ /* toggle bit0 of GP_IO */
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+ return status;
+}
+
+/*****************************************************************************
+* G P I O I2C related functions *
+******************************************************************************/
+int cx231xx_gpio_i2c_start(struct cx231xx *dev)
+{
+ int status = 0;
+
+ /* set SCL to output 1 ; set SDA to output 1 */
+ dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
+ dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
+ dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+ dev->gpio_val |= 1 << dev->board.tuner_sda_gpio;
+
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+ if (status < 0)
+ return -EINVAL;
+
+ /* set SCL to output 1; set SDA to output 0 */
+ dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+ dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+ if (status < 0)
+ return -EINVAL;
+
+ /* set SCL to output 0; set SDA to output 0 */
+ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+ dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+ if (status < 0)
+ return -EINVAL;
+
+ return status;
+}
+
+int cx231xx_gpio_i2c_end(struct cx231xx *dev)
+{
+ int status = 0;
+
+ /* set SCL to output 0; set SDA to output 0 */
+ dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
+ dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
+
+ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+ dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+ if (status < 0)
+ return -EINVAL;
+
+ /* set SCL to output 1; set SDA to output 0 */
+ dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+ dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+ if (status < 0)
+ return -EINVAL;
+
+ /* set SCL to input ,release SCL cable control
+ set SDA to input ,release SDA cable control */
+ dev->gpio_dir &= ~(1 << dev->board.tuner_scl_gpio);
+ dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
+
+ status =
+ cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+ if (status < 0)
+ return -EINVAL;
+
+ return status;
+}
+
+int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data)
+{
+ int status = 0;
+ u8 i;
+
+ /* set SCL to output ; set SDA to output */
+ dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
+ dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
+
+ for (i = 0; i < 8; i++) {
+ if (((data << i) & 0x80) == 0) {
+ /* set SCL to output 0; set SDA to output 0 */
+ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+ dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+ (u8 *)&dev->gpio_val);
+
+ /* set SCL to output 1; set SDA to output 0 */
+ dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+ (u8 *)&dev->gpio_val);
+
+ /* set SCL to output 0; set SDA to output 0 */
+ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+ (u8 *)&dev->gpio_val);
+ } else {
+ /* set SCL to output 0; set SDA to output 1 */
+ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+ dev->gpio_val |= 1 << dev->board.tuner_sda_gpio;
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+ (u8 *)&dev->gpio_val);
+
+ /* set SCL to output 1; set SDA to output 1 */
+ dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+ (u8 *)&dev->gpio_val);
+
+ /* set SCL to output 0; set SDA to output 1 */
+ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+ (u8 *)&dev->gpio_val);
+ }
+ }
+ return status;
+}
+
+int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 * buf)
+{
+ u8 value = 0;
+ int status = 0;
+ u32 gpio_logic_value = 0;
+ u8 i;
+
+ /* read byte */
+ for (i = 0; i < 8; i++) { /* send write I2c addr */
+
+ /* set SCL to output 0; set SDA to input */
+ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+ (u8 *)&dev->gpio_val);
+
+ /* set SCL to output 1; set SDA to input */
+ dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+ (u8 *)&dev->gpio_val);
+
+ /* get SDA data bit */
+ gpio_logic_value = dev->gpio_val;
+ status = cx231xx_get_gpio_bit(dev, dev->gpio_dir,
+ (u8 *)&dev->gpio_val);
+ if ((dev->gpio_val & (1 << dev->board.tuner_sda_gpio)) != 0)
+ value |= (1 << (8 - i - 1));
+
+ dev->gpio_val = gpio_logic_value;
+ }
+
+ /* set SCL to output 0,finish the read latest SCL signal.
+ !!!set SDA to input, never to modify SDA direction at
+ the same times */
+ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+ /* store the value */
+ *buf = value & 0xff;
+
+ return status;
+}
+
+int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev)
+{
+ int status = 0;
+ u32 gpio_logic_value = 0;
+ int nCnt = 10;
+ int nInit = nCnt;
+
+ /* clock stretch; set SCL to input; set SDA to input;
+ get SCL value till SCL = 1 */
+ dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
+ dev->gpio_dir &= ~(1 << dev->board.tuner_scl_gpio);
+
+ gpio_logic_value = dev->gpio_val;
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+ do {
+ msleep(2);
+ status = cx231xx_get_gpio_bit(dev, dev->gpio_dir,
+ (u8 *)&dev->gpio_val);
+ nCnt--;
+ } while (((dev->gpio_val &
+ (1 << dev->board.tuner_scl_gpio)) == 0) &&
+ (nCnt > 0));
+
+ if (nCnt == 0)
+ cx231xx_info("No ACK after %d msec -GPIO I2C failed!",
+ nInit * 10);
+
+ /* readAck
+ throuth clock stretch ,slave has given a SCL signal,
+ so the SDA data can be directly read. */
+ status = cx231xx_get_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+ if ((dev->gpio_val & 1 << dev->board.tuner_sda_gpio) == 0) {
+ dev->gpio_val = gpio_logic_value;
+ dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+ status = 0;
+ } else {
+ dev->gpio_val = gpio_logic_value;
+ dev->gpio_val |= (1 << dev->board.tuner_sda_gpio);
+ }
+
+ /* read SDA end, set the SCL to output 0, after this operation,
+ SDA direction can be changed. */
+ dev->gpio_val = gpio_logic_value;
+ dev->gpio_dir |= (1 << dev->board.tuner_scl_gpio);
+ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+ return status;
+}
+
+int cx231xx_gpio_i2c_write_ack(struct cx231xx *dev)
+{
+ int status = 0;
+
+ /* set SDA to ouput */
+ dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+ /* set SCL = 0 (output); set SDA = 0 (output) */
+ dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+ /* set SCL = 1 (output); set SDA = 0 (output) */
+ dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+ /* set SCL = 0 (output); set SDA = 0 (output) */
+ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+ /* set SDA to input,and then the slave will read data from SDA. */
+ dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+ return status;
+}
+
+int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev)
+{
+ int status = 0;
+
+ /* set scl to output ; set sda to input */
+ dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
+ dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+ /* set scl to output 0; set sda to input */
+ dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+ /* set scl to output 1; set sda to input */
+ dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+ status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+ return status;
+}
+
+/*****************************************************************************
+* G P I O I2C related functions *
+******************************************************************************/
+/* cx231xx_gpio_i2c_read
+ * Function to read data from gpio based I2C interface
+ */
+int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len)
+{
+ int status = 0;
+ int i = 0;
+
+ /* get the lock */
+ mutex_lock(&dev->gpio_i2c_lock);
+
+ /* start */
+ status = cx231xx_gpio_i2c_start(dev);
+
+ /* write dev_addr */
+ status = cx231xx_gpio_i2c_write_byte(dev, (dev_addr << 1) + 1);
+
+ /* readAck */
+ status = cx231xx_gpio_i2c_read_ack(dev);
+
+ /* read data */
+ for (i = 0; i < len; i++) {
+ /* read data */
+ buf[i] = 0;
+ status = cx231xx_gpio_i2c_read_byte(dev, &buf[i]);
+
+ if ((i + 1) != len) {
+ /* only do write ack if we more length */
+ status = cx231xx_gpio_i2c_write_ack(dev);
+ }
+ }
+
+ /* write NAK - inform reads are complete */
+ status = cx231xx_gpio_i2c_write_nak(dev);
+
+ /* write end */
+ status = cx231xx_gpio_i2c_end(dev);
+
+ /* release the lock */
+ mutex_unlock(&dev->gpio_i2c_lock);
+
+ return status;
+}
+
+/* cx231xx_gpio_i2c_write
+ * Function to write data to gpio based I2C interface
+ */
+int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len)
+{
+ int status = 0;
+ int i = 0;
+
+ /* get the lock */
+ mutex_lock(&dev->gpio_i2c_lock);
+
+ /* start */
+ status = cx231xx_gpio_i2c_start(dev);
+
+ /* write dev_addr */
+ status = cx231xx_gpio_i2c_write_byte(dev, dev_addr << 1);
+
+ /* read Ack */
+ status = cx231xx_gpio_i2c_read_ack(dev);
+
+ for (i = 0; i < len; i++) {
+ /* Write data */
+ status = cx231xx_gpio_i2c_write_byte(dev, buf[i]);
+
+ /* read Ack */
+ status = cx231xx_gpio_i2c_read_ack(dev);
+ }
+
+ /* write End */
+ status = cx231xx_gpio_i2c_end(dev);
+
+ /* release the lock */
+ mutex_unlock(&dev->gpio_i2c_lock);
+
+ return 0;
+}
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
new file mode 100644
index 00000000000..c8a32b1b538
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -0,0 +1,914 @@
+/*
+ cx231xx-cards.c - driver for Conexant Cx23100/101/102
+ USB video capture devices
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+ Based on em28xx driver
+
+ 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/module.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/usb.h>
+#include <media/tuner.h>
+#include <media/tveeprom.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+
+#include <media/cx25840.h>
+#include "xc5000.h"
+
+#include "cx231xx.h"
+
+static int tuner = -1;
+module_param(tuner, int, 0444);
+MODULE_PARM_DESC(tuner, "tuner type");
+
+static unsigned int disable_ir;
+module_param(disable_ir, int, 0444);
+MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
+
+/* Bitmask marking allocated devices from 0 to CX231XX_MAXBOARDS */
+static unsigned long cx231xx_devused;
+
+/*
+ * Reset sequences for analog/digital modes
+ */
+
+static struct cx231xx_reg_seq RDE250_XCV_TUNER[] = {
+ {0x03, 0x01, 10},
+ {0x03, 0x00, 30},
+ {0x03, 0x01, 10},
+ {-1, -1, -1},
+};
+
+/*
+ * Board definitions
+ */
+struct cx231xx_board cx231xx_boards[] = {
+ [CX231XX_BOARD_UNKNOWN] = {
+ .name = "Unknown CX231xx video grabber",
+ .tuner_type = TUNER_ABSENT,
+ .input = {{
+ .type = CX231XX_VMUX_TELEVISION,
+ .vmux = CX231XX_VIN_3_1,
+ .amux = CX231XX_AMUX_VIDEO,
+ .gpio = 0,
+ }, {
+ .type = CX231XX_VMUX_COMPOSITE1,
+ .vmux = CX231XX_VIN_2_1,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = 0,
+ }, {
+ .type = CX231XX_VMUX_SVIDEO,
+ .vmux = CX231XX_VIN_1_1 |
+ (CX231XX_VIN_1_2 << 8) |
+ CX25840_SVIDEO_ON,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = 0,
+ }
+ },
+ },
+ [CX231XX_BOARD_CNXT_RDE_250] = {
+ .name = "Conexant Hybrid TV - RDE250",
+ .tuner_type = TUNER_XC5000,
+ .tuner_addr = 0x61,
+ .tuner_gpio = RDE250_XCV_TUNER,
+ .tuner_sif_gpio = 0x05,
+ .tuner_scl_gpio = 0x1a,
+ .tuner_sda_gpio = 0x1b,
+ .decoder = CX231XX_AVDECODER,
+ .demod_xfer_mode = 0,
+ .ctl_pin_status_mask = 0xFFFFFFC4,
+ .agc_analog_digital_select_gpio = 0x0c,
+ .gpio_pin_status_mask = 0x4001000,
+ .tuner_i2c_master = 1,
+ .demod_i2c_master = 2,
+ .has_dvb = 1,
+ .demod_addr = 0x02,
+ .norm = V4L2_STD_PAL,
+
+ .input = {{
+ .type = CX231XX_VMUX_TELEVISION,
+ .vmux = CX231XX_VIN_3_1,
+ .amux = CX231XX_AMUX_VIDEO,
+ .gpio = 0,
+ }, {
+ .type = CX231XX_VMUX_COMPOSITE1,
+ .vmux = CX231XX_VIN_2_1,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = 0,
+ }, {
+ .type = CX231XX_VMUX_SVIDEO,
+ .vmux = CX231XX_VIN_1_1 |
+ (CX231XX_VIN_1_2 << 8) |
+ CX25840_SVIDEO_ON,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = 0,
+ }
+ },
+ },
+
+ [CX231XX_BOARD_CNXT_RDU_250] = {
+ .name = "Conexant Hybrid TV - RDU250",
+ .tuner_type = TUNER_XC5000,
+ .tuner_addr = 0x61,
+ .tuner_gpio = RDE250_XCV_TUNER,
+ .tuner_sif_gpio = 0x05,
+ .tuner_scl_gpio = 0x1a,
+ .tuner_sda_gpio = 0x1b,
+ .decoder = CX231XX_AVDECODER,
+ .demod_xfer_mode = 0,
+ .ctl_pin_status_mask = 0xFFFFFFC4,
+ .agc_analog_digital_select_gpio = 0x0c,
+ .gpio_pin_status_mask = 0x4001000,
+ .tuner_i2c_master = 1,
+ .demod_i2c_master = 2,
+ .has_dvb = 1,
+ .demod_addr = 0x32,
+ .norm = V4L2_STD_NTSC,
+
+ .input = {{
+ .type = CX231XX_VMUX_TELEVISION,
+ .vmux = CX231XX_VIN_3_1,
+ .amux = CX231XX_AMUX_VIDEO,
+ .gpio = 0,
+ }, {
+ .type = CX231XX_VMUX_COMPOSITE1,
+ .vmux = CX231XX_VIN_2_1,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = 0,
+ }, {
+ .type = CX231XX_VMUX_SVIDEO,
+ .vmux = CX231XX_VIN_1_1 |
+ (CX231XX_VIN_1_2 << 8) |
+ CX25840_SVIDEO_ON,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = 0,
+ }
+ },
+ },
+};
+const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
+
+/* table of devices that work with this driver */
+struct usb_device_id cx231xx_id_table[] = {
+ {USB_DEVICE(0x0572, 0x5A3C),
+ .driver_info = CX231XX_BOARD_UNKNOWN},
+ {USB_DEVICE(0x0572, 0x58A2),
+ .driver_info = CX231XX_BOARD_CNXT_RDE_250},
+ {USB_DEVICE(0x0572, 0x58A1),
+ .driver_info = CX231XX_BOARD_CNXT_RDU_250},
+ {},
+};
+
+MODULE_DEVICE_TABLE(usb, cx231xx_id_table);
+
+/* cx231xx_tuner_callback
+ * will be used to reset XC5000 tuner using GPIO pin
+ */
+
+int cx231xx_tuner_callback(void *ptr, int component, int command, int arg)
+{
+ int rc = 0;
+ struct cx231xx *dev = ptr;
+
+ if (dev->tuner_type == TUNER_XC5000) {
+ if (command == XC5000_TUNER_RESET) {
+ cx231xx_info
+ ("Tuner CB: RESET: cmd %d : tuner type %d \n",
+ command, dev->tuner_type);
+ cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
+ 1);
+ msleep(10);
+ cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
+ 0);
+ msleep(330);
+ cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
+ 1);
+ msleep(10);
+ }
+ }
+ return rc;
+}
+EXPORT_SYMBOL_GPL(cx231xx_tuner_callback);
+
+static inline void cx231xx_set_model(struct cx231xx *dev)
+{
+ memcpy(&dev->board, &cx231xx_boards[dev->model], sizeof(dev->board));
+}
+
+/* Since cx231xx_pre_card_setup() requires a proper dev->model,
+ * this won't work for boards with generic PCI IDs
+ */
+void cx231xx_pre_card_setup(struct cx231xx *dev)
+{
+
+ cx231xx_set_model(dev);
+
+ cx231xx_info("Identified as %s (card=%d)\n",
+ dev->board.name, dev->model);
+
+ /* set the direction for GPIO pins */
+ cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1);
+ cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1);
+ cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1);
+
+ /* request some modules if any required */
+
+ /* reset the Tuner */
+ cx231xx_gpio_set(dev, dev->board.tuner_gpio);
+
+ /* set the mode to Analog mode initially */
+ cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
+
+ /* Unlock device */
+ /* cx231xx_set_mode(dev, CX231XX_SUSPEND); */
+
+}
+
+static void cx231xx_config_tuner(struct cx231xx *dev)
+{
+ struct tuner_setup tun_setup;
+ struct v4l2_frequency f;
+
+ if (dev->tuner_type == TUNER_ABSENT)
+ return;
+
+ tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
+ tun_setup.type = dev->tuner_type;
+ tun_setup.addr = dev->tuner_addr;
+ tun_setup.tuner_callback = cx231xx_tuner_callback;
+
+ tuner_call(dev, tuner, s_type_addr, &tun_setup);
+
+#if 0
+ if (tun_setup.type == TUNER_XC5000) {
+ static struct xc2028_ctrl ctrl = {
+ .fname = XC5000_DEFAULT_FIRMWARE,
+ .max_len = 64,
+ .demod = 0;
+ };
+ struct v4l2_priv_tun_config cfg = {
+ .tuner = dev->tuner_type,
+ .priv = &ctrl,
+ };
+ tuner_call(dev, tuner, s_config, &cfg);
+ }
+#endif
+ /* configure tuner */
+ f.tuner = 0;
+ f.type = V4L2_TUNER_ANALOG_TV;
+ f.frequency = 9076; /* just a magic number */
+ dev->ctl_freq = f.frequency;
+ call_all(dev, tuner, s_frequency, &f);
+
+}
+
+/* ----------------------------------------------------------------------- */
+void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir)
+{
+ if (disable_ir) {
+ ir->get_key = NULL;
+ return;
+ }
+
+ /* detect & configure */
+ switch (dev->model) {
+
+ case CX231XX_BOARD_CNXT_RDE_250:
+ break;
+ case CX231XX_BOARD_CNXT_RDU_250:
+ break;
+ default:
+ break;
+ }
+}
+
+void cx231xx_card_setup(struct cx231xx *dev)
+{
+
+ cx231xx_set_model(dev);
+
+ dev->tuner_type = cx231xx_boards[dev->model].tuner_type;
+ if (cx231xx_boards[dev->model].tuner_addr)
+ dev->tuner_addr = cx231xx_boards[dev->model].tuner_addr;
+
+ /* request some modules */
+ if (dev->board.decoder == CX231XX_AVDECODER) {
+ dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
+ &dev->i2c_bus[0].i2c_adap,
+ "cx25840", "cx25840", 0x88 >> 1);
+ if (dev->sd_cx25840 == NULL)
+ cx231xx_info("cx25840 subdev registration failure\n");
+ cx25840_call(dev, core, load_fw);
+
+ }
+
+ if (dev->board.tuner_type != TUNER_ABSENT) {
+ dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev,
+ &dev->i2c_bus[1].i2c_adap,
+ "tuner", "tuner", 0xc2 >> 1);
+ if (dev->sd_tuner == NULL)
+ cx231xx_info("tuner subdev registration failure\n");
+
+ cx231xx_config_tuner(dev);
+ }
+
+ cx231xx_config_tuner(dev);
+
+#if 0
+ /* TBD IR will be added later */
+ cx231xx_ir_init(dev);
+#endif
+}
+
+/*
+ * cx231xx_config()
+ * inits registers with sane defaults
+ */
+int cx231xx_config(struct cx231xx *dev)
+{
+ /* TBD need to add cx231xx specific code */
+ dev->mute = 1; /* maybe not the right place... */
+ dev->volume = 0x1f;
+
+ return 0;
+}
+
+/*
+ * cx231xx_config_i2c()
+ * configure i2c attached devices
+ */
+void cx231xx_config_i2c(struct cx231xx *dev)
+{
+ /* u32 input = INPUT(dev->video_input)->vmux; */
+
+ call_all(dev, video, s_stream, 1);
+}
+
+/*
+ * cx231xx_realease_resources()
+ * unregisters the v4l2,i2c and usb devices
+ * called when the device gets disconected or at module unload
+*/
+void cx231xx_release_resources(struct cx231xx *dev)
+{
+
+#if 0 /* TBD IR related */
+ if (dev->ir)
+ cx231xx_ir_fini(dev);
+#endif
+
+ cx231xx_release_analog_resources(dev);
+
+ cx231xx_remove_from_devlist(dev);
+
+ cx231xx_dev_uninit(dev);
+
+ usb_put_dev(dev->udev);
+
+ /* Mark device as unused */
+ cx231xx_devused &= ~(1 << dev->devno);
+}
+
+/*
+ * cx231xx_init_dev()
+ * allocates and inits the device structs, registers i2c bus and v4l device
+ */
+static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
+ int minor)
+{
+ struct cx231xx *dev = *devhandle;
+ int retval = -ENOMEM;
+ int errCode;
+ unsigned int maxh, maxw;
+
+ dev->udev = udev;
+ mutex_init(&dev->lock);
+ mutex_init(&dev->ctrl_urb_lock);
+ mutex_init(&dev->gpio_i2c_lock);
+
+ spin_lock_init(&dev->video_mode.slock);
+ spin_lock_init(&dev->vbi_mode.slock);
+ spin_lock_init(&dev->sliced_cc_mode.slock);
+
+ init_waitqueue_head(&dev->open);
+ init_waitqueue_head(&dev->wait_frame);
+ init_waitqueue_head(&dev->wait_stream);
+
+ dev->cx231xx_read_ctrl_reg = cx231xx_read_ctrl_reg;
+ dev->cx231xx_write_ctrl_reg = cx231xx_write_ctrl_reg;
+ dev->cx231xx_send_usb_command = cx231xx_send_usb_command;
+ dev->cx231xx_gpio_i2c_read = cx231xx_gpio_i2c_read;
+ dev->cx231xx_gpio_i2c_write = cx231xx_gpio_i2c_write;
+
+ /* Query cx231xx to find what pcb config it is related to */
+ initialize_cx231xx(dev);
+
+ /* Cx231xx pre card setup */
+ cx231xx_pre_card_setup(dev);
+
+ errCode = cx231xx_config(dev);
+ if (errCode) {
+ cx231xx_errdev("error configuring device\n");
+ return -ENOMEM;
+ }
+
+ /* set default norm */
+ dev->norm = dev->board.norm;
+
+ /* register i2c bus */
+ errCode = cx231xx_dev_init(dev);
+ if (errCode < 0) {
+ cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n",
+ __func__, errCode);
+ return errCode;
+ }
+
+ /* Do board specific init */
+ cx231xx_card_setup(dev);
+
+ /* configure the device */
+ cx231xx_config_i2c(dev);
+
+ maxw = norm_maxw(dev);
+ maxh = norm_maxh(dev);
+
+ /* set default image size */
+ dev->width = maxw;
+ dev->height = maxh;
+ dev->interlaced = 0;
+ dev->hscale = 0;
+ dev->vscale = 0;
+ dev->video_input = 0;
+
+ errCode = cx231xx_config(dev);
+ if (errCode < 0) {
+ cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n",
+ __func__, errCode);
+ return errCode;
+ }
+
+ /* init video dma queues */
+ INIT_LIST_HEAD(&dev->video_mode.vidq.active);
+ INIT_LIST_HEAD(&dev->video_mode.vidq.queued);
+
+ /* init vbi dma queues */
+ INIT_LIST_HEAD(&dev->vbi_mode.vidq.active);
+ INIT_LIST_HEAD(&dev->vbi_mode.vidq.queued);
+
+ /* Reset other chips required if they are tied up with GPIO pins */
+
+ cx231xx_add_into_devlist(dev);
+
+ retval = cx231xx_register_analog_devices(dev);
+ if (retval < 0) {
+ cx231xx_release_resources(dev);
+ goto fail_reg_devices;
+ }
+
+ cx231xx_init_extension(dev);
+
+ return 0;
+
+fail_reg_devices:
+ mutex_unlock(&dev->lock);
+ return retval;
+}
+
+#if defined(CONFIG_MODULES) && defined(MODULE)
+static void request_module_async(struct work_struct *work)
+{
+ struct cx231xx *dev = container_of(work,
+ struct cx231xx, request_module_wk);
+
+ if (dev->has_alsa_audio)
+ request_module("cx231xx-alsa");
+
+ if (dev->board.has_dvb)
+ request_module("cx231xx-dvb");
+
+}
+
+static void request_modules(struct cx231xx *dev)
+{
+ INIT_WORK(&dev->request_module_wk, request_module_async);
+ schedule_work(&dev->request_module_wk);
+}
+#else
+#define request_modules(dev)
+#endif /* CONFIG_MODULES */
+
+/*
+ * cx231xx_usb_probe()
+ * checks for supported devices
+ */
+static int cx231xx_usb_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct usb_device *udev;
+ struct usb_interface *uif;
+ struct cx231xx *dev = NULL;
+ int retval = -ENODEV;
+ int nr = 0, ifnum;
+ int i, isoc_pipe = 0;
+ char *speed;
+ char descr[255] = "";
+ struct usb_interface *lif = NULL;
+ int skip_interface = 0;
+ struct usb_interface_assoc_descriptor *assoc_desc;
+
+ udev = usb_get_dev(interface_to_usbdev(interface));
+ ifnum = interface->altsetting[0].desc.bInterfaceNumber;
+
+ if (!ifnum) {
+ /*
+ * Interface number 0 - IR interface
+ */
+ /* Check to see next free device and mark as used */
+ nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS);
+ cx231xx_devused |= 1 << nr;
+
+ if (nr >= CX231XX_MAXBOARDS) {
+ cx231xx_err(DRIVER_NAME ": Supports only %i cx231xx boards.\n",
+ CX231XX_MAXBOARDS);
+ cx231xx_devused &= ~(1 << nr);
+ return -ENOMEM;
+ }
+
+ /* allocate memory for our device state and initialize it */
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (dev == NULL) {
+ cx231xx_err(DRIVER_NAME ": out of memory!\n");
+ cx231xx_devused &= ~(1 << nr);
+ return -ENOMEM;
+ }
+
+ snprintf(dev->name, 29, "cx231xx #%d", nr);
+ dev->devno = nr;
+ dev->model = id->driver_info;
+ dev->video_mode.alt = -1;
+ dev->interface_count++;
+
+ /* reset gpio dir and value */
+ dev->gpio_dir = 0;
+ dev->gpio_val = 0;
+ dev->xc_fw_load_done = 0;
+ dev->has_alsa_audio = 1;
+ dev->power_mode = -1;
+
+ /* 0 - vbi ; 1 -sliced cc mode */
+ dev->vbi_or_sliced_cc_mode = 0;
+
+ /* get maximum no.of IAD interfaces */
+ assoc_desc = udev->actconfig->intf_assoc[0];
+ dev->max_iad_interface_count = assoc_desc->bInterfaceCount;
+
+ /* init CIR module TBD */
+
+ /* store the current interface */
+ lif = interface;
+
+ switch (udev->speed) {
+ case USB_SPEED_LOW:
+ speed = "1.5";
+ break;
+ case USB_SPEED_UNKNOWN:
+ case USB_SPEED_FULL:
+ speed = "12";
+ break;
+ case USB_SPEED_HIGH:
+ speed = "480";
+ break;
+ default:
+ speed = "unknown";
+ }
+
+ if (udev->manufacturer)
+ strlcpy(descr, udev->manufacturer, sizeof(descr));
+
+ if (udev->product) {
+ if (*descr)
+ strlcat(descr, " ", sizeof(descr));
+ strlcat(descr, udev->product, sizeof(descr));
+ }
+ if (*descr)
+ strlcat(descr, " ", sizeof(descr));
+
+ cx231xx_info("New device %s@ %s Mbps "
+ "(%04x:%04x) with %d interfaces\n",
+ descr,
+ speed,
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct),
+ dev->max_iad_interface_count);
+ } else {
+ /* Get dev structure first */
+ dev = usb_get_intfdata(udev->actconfig->interface[0]);
+ if (dev == NULL) {
+ cx231xx_err(DRIVER_NAME ": out of first interface!\n");
+ return -ENODEV;
+ }
+
+ /* store the interface 0 back */
+ lif = udev->actconfig->interface[0];
+
+ /* increment interface count */
+ dev->interface_count++;
+
+ /* get device number */
+ nr = dev->devno;
+
+ /*
+ * set skip interface, for all interfaces but
+ * interface 1 and the last one
+ */
+ if ((ifnum != 1) && ((dev->interface_count - 1)
+ != dev->max_iad_interface_count))
+ skip_interface = 1;
+
+ if (ifnum == 1) {
+ assoc_desc = udev->actconfig->intf_assoc[0];
+ if (assoc_desc->bFirstInterface != ifnum) {
+ cx231xx_err(DRIVER_NAME ": Not found "
+ "matching IAD interface\n");
+ return -ENODEV;
+ }
+ }
+ }
+
+ if (skip_interface)
+ return -ENODEV;
+
+ cx231xx_info("registering interface %d\n", ifnum);
+
+ /* save our data pointer in this interface device */
+ usb_set_intfdata(lif, dev);
+
+ if ((dev->interface_count - 1) != dev->max_iad_interface_count)
+ return 0;
+
+ /*
+ * AV device initialization - only done at the last interface
+ */
+
+ /* Create v4l2 device */
+ retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
+ if (retval) {
+ cx231xx_errdev("v4l2_device_register failed\n");
+ cx231xx_devused &= ~(1 << nr);
+ kfree(dev);
+ return -EIO;
+ }
+
+ /* allocate device struct */
+ retval = cx231xx_init_dev(&dev, udev, nr);
+ if (retval) {
+ cx231xx_devused &= ~(1 << dev->devno);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ kfree(dev);
+ return retval;
+ }
+
+ /* compute alternate max packet sizes for video */
+ uif = udev->actconfig->interface[dev->current_pcb_config.
+ hs_config_info[0].interface_info.video_index + 1];
+
+ dev->video_mode.end_point_addr = le16_to_cpu(uif->altsetting[0].
+ endpoint[isoc_pipe].desc.bEndpointAddress);
+
+ dev->video_mode.num_alt = uif->num_altsetting;
+ cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
+ dev->video_mode.end_point_addr,
+ dev->video_mode.num_alt);
+ dev->video_mode.alt_max_pkt_size =
+ kmalloc(32 * dev->video_mode.num_alt, GFP_KERNEL);
+
+ if (dev->video_mode.alt_max_pkt_size == NULL) {
+ cx231xx_errdev("out of memory!\n");
+ cx231xx_devused &= ~(1 << nr);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ kfree(dev);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < dev->video_mode.num_alt; i++) {
+ u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
+ desc.wMaxPacketSize);
+ dev->video_mode.alt_max_pkt_size[i] =
+ (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+ cx231xx_info("Alternate setting %i, max size= %i\n", i,
+ dev->video_mode.alt_max_pkt_size[i]);
+ }
+
+ /* compute alternate max packet sizes for vbi */
+ uif = udev->actconfig->interface[dev->current_pcb_config.
+ hs_config_info[0].interface_info.
+ vanc_index + 1];
+
+ dev->vbi_mode.end_point_addr =
+ le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
+ bEndpointAddress);
+
+ dev->vbi_mode.num_alt = uif->num_altsetting;
+ cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
+ dev->vbi_mode.end_point_addr,
+ dev->vbi_mode.num_alt);
+ dev->vbi_mode.alt_max_pkt_size =
+ kmalloc(32 * dev->vbi_mode.num_alt, GFP_KERNEL);
+
+ if (dev->vbi_mode.alt_max_pkt_size == NULL) {
+ cx231xx_errdev("out of memory!\n");
+ cx231xx_devused &= ~(1 << nr);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ kfree(dev);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < dev->vbi_mode.num_alt; i++) {
+ u16 tmp =
+ le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
+ desc.wMaxPacketSize);
+ dev->vbi_mode.alt_max_pkt_size[i] =
+ (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+ cx231xx_info("Alternate setting %i, max size= %i\n", i,
+ dev->vbi_mode.alt_max_pkt_size[i]);
+ }
+
+ /* compute alternate max packet sizes for sliced CC */
+ uif = udev->actconfig->interface[dev->current_pcb_config.
+ hs_config_info[0].interface_info.
+ hanc_index + 1];
+
+ dev->sliced_cc_mode.end_point_addr =
+ le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
+ bEndpointAddress);
+
+ dev->sliced_cc_mode.num_alt = uif->num_altsetting;
+ cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
+ dev->sliced_cc_mode.end_point_addr,
+ dev->sliced_cc_mode.num_alt);
+ dev->sliced_cc_mode.alt_max_pkt_size =
+ kmalloc(32 * dev->sliced_cc_mode.num_alt, GFP_KERNEL);
+
+ if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) {
+ cx231xx_errdev("out of memory!\n");
+ cx231xx_devused &= ~(1 << nr);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ kfree(dev);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) {
+ u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
+ desc.wMaxPacketSize);
+ dev->sliced_cc_mode.alt_max_pkt_size[i] =
+ (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+ cx231xx_info("Alternate setting %i, max size= %i\n", i,
+ dev->sliced_cc_mode.alt_max_pkt_size[i]);
+ }
+
+ if (dev->current_pcb_config.ts1_source != 0xff) {
+ /* compute alternate max packet sizes for TS1 */
+ uif = udev->actconfig->interface[dev->current_pcb_config.
+ hs_config_info[0].
+ interface_info.
+ ts1_index + 1];
+
+ dev->ts1_mode.end_point_addr =
+ le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].
+ desc.bEndpointAddress);
+
+ dev->ts1_mode.num_alt = uif->num_altsetting;
+ cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
+ dev->ts1_mode.end_point_addr,
+ dev->ts1_mode.num_alt);
+ dev->ts1_mode.alt_max_pkt_size =
+ kmalloc(32 * dev->ts1_mode.num_alt, GFP_KERNEL);
+
+ if (dev->ts1_mode.alt_max_pkt_size == NULL) {
+ cx231xx_errdev("out of memory!\n");
+ cx231xx_devused &= ~(1 << nr);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ kfree(dev);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < dev->ts1_mode.num_alt; i++) {
+ u16 tmp = le16_to_cpu(uif->altsetting[i].
+ endpoint[isoc_pipe].desc.
+ wMaxPacketSize);
+ dev->ts1_mode.alt_max_pkt_size[i] =
+ (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+ cx231xx_info("Alternate setting %i, max size= %i\n", i,
+ dev->ts1_mode.alt_max_pkt_size[i]);
+ }
+ }
+
+ /* load other modules required */
+ request_modules(dev);
+
+ return 0;
+}
+
+/*
+ * cx231xx_usb_disconnect()
+ * called when the device gets diconencted
+ * video device will be unregistered on v4l2_close in case it is still open
+ */
+static void cx231xx_usb_disconnect(struct usb_interface *interface)
+{
+ struct cx231xx *dev;
+
+ dev = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
+
+ if (!dev)
+ return;
+
+ if (!dev->udev)
+ return;
+
+ /* delete v4l2 device */
+ v4l2_device_unregister(&dev->v4l2_dev);
+
+ /* wait until all current v4l2 io is finished then deallocate
+ resources */
+ mutex_lock(&dev->lock);
+
+ wake_up_interruptible_all(&dev->open);
+
+ if (dev->users) {
+ cx231xx_warn
+ ("device /dev/video%d is open! Deregistration and memory "
+ "deallocation are deferred on close.\n", dev->vdev->num);
+
+ dev->state |= DEV_MISCONFIGURED;
+ cx231xx_uninit_isoc(dev);
+ dev->state |= DEV_DISCONNECTED;
+ wake_up_interruptible(&dev->wait_frame);
+ wake_up_interruptible(&dev->wait_stream);
+ } else {
+ dev->state |= DEV_DISCONNECTED;
+ cx231xx_release_resources(dev);
+ }
+
+ cx231xx_close_extension(dev);
+
+ mutex_unlock(&dev->lock);
+
+ if (!dev->users) {
+ kfree(dev->video_mode.alt_max_pkt_size);
+ kfree(dev->vbi_mode.alt_max_pkt_size);
+ kfree(dev->sliced_cc_mode.alt_max_pkt_size);
+ kfree(dev->ts1_mode.alt_max_pkt_size);
+ kfree(dev);
+ }
+}
+
+static struct usb_driver cx231xx_usb_driver = {
+ .name = "cx231xx",
+ .probe = cx231xx_usb_probe,
+ .disconnect = cx231xx_usb_disconnect,
+ .id_table = cx231xx_id_table,
+};
+
+static int __init cx231xx_module_init(void)
+{
+ int result;
+
+ printk(KERN_INFO DRIVER_NAME " v4l2 driver loaded.\n");
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&cx231xx_usb_driver);
+ if (result)
+ cx231xx_err(DRIVER_NAME
+ " usb_register failed. Error number %d.\n", result);
+
+ return result;
+}
+
+static void __exit cx231xx_module_exit(void)
+{
+ /* deregister this driver with the USB subsystem */
+ usb_deregister(&cx231xx_usb_driver);
+}
+
+module_init(cx231xx_module_init);
+module_exit(cx231xx_module_exit);
diff --git a/drivers/media/video/cx231xx/cx231xx-conf-reg.h b/drivers/media/video/cx231xx/cx231xx-conf-reg.h
new file mode 100644
index 00000000000..a6f398a175c
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-conf-reg.h
@@ -0,0 +1,494 @@
+/*
+ cx231xx_conf-reg.h - driver for Conexant Cx23100/101/102 USB
+ video capture devices
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot 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.
+ */
+
+#ifndef _POLARIS_REG_H_
+#define _POLARIS_REG_H_
+
+#define BOARD_CFG_STAT 0x0
+#define TS_MODE_REG 0x4
+#define TS1_CFG_REG 0x8
+#define TS1_LENGTH_REG 0xc
+#define TS2_CFG_REG 0x10
+#define TS2_LENGTH_REG 0x14
+#define EP_MODE_SET 0x18
+#define CIR_PWR_PTN1 0x1c
+#define CIR_PWR_PTN2 0x20
+#define CIR_PWR_PTN3 0x24
+#define CIR_PWR_MASK0 0x28
+#define CIR_PWR_MASK1 0x2c
+#define CIR_PWR_MASK2 0x30
+#define CIR_GAIN 0x34
+#define CIR_CAR_REG 0x38
+#define CIR_OT_CFG1 0x40
+#define CIR_OT_CFG2 0x44
+#define PWR_CTL_EN 0x74
+
+/* Polaris Endpoints capture mask for register EP_MODE_SET */
+#define ENABLE_EP1 0x01 /* Bit[0]=1 */
+#define ENABLE_EP2 0x02 /* Bit[1]=1 */
+#define ENABLE_EP3 0x04 /* Bit[2]=1 */
+#define ENABLE_EP4 0x08 /* Bit[3]=1 */
+#define ENABLE_EP5 0x10 /* Bit[4]=1 */
+#define ENABLE_EP6 0x20 /* Bit[5]=1 */
+
+/* Bit definition for register PWR_CTL_EN */
+#define PWR_MODE_MASK 0x17f
+#define PWR_AV_EN 0x08 /* bit3 */
+#define PWR_ISO_EN 0x40 /* bit6 */
+#define PWR_AV_MODE 0x30 /* bit4,5 */
+#define PWR_TUNER_EN 0x04 /* bit2 */
+#define PWR_DEMOD_EN 0x02 /* bit1 */
+#define I2C_DEMOD_EN 0x01 /* bit0 */
+#define PWR_RESETOUT_EN 0x100 /* bit8 */
+
+enum AV_MODE{
+ POLARIS_AVMODE_DEFAULT = 0,
+ POLARIS_AVMODE_DIGITAL = 0x10,
+ POLARIS_AVMODE_ANALOGT_TV = 0x20,
+ POLARIS_AVMODE_ENXTERNAL_AV = 0x30,
+
+};
+
+/* Colibri Registers */
+
+#define SINGLE_ENDED 0x0
+#define LOW_IF 0x4
+#define EU_IF 0x9
+#define US_IF 0xa
+
+#define SUP_BLK_TUNE1 0x00
+#define SUP_BLK_TUNE2 0x01
+#define SUP_BLK_TUNE3 0x02
+#define SUP_BLK_XTAL 0x03
+#define SUP_BLK_PLL1 0x04
+#define SUP_BLK_PLL2 0x05
+#define SUP_BLK_PLL3 0x06
+#define SUP_BLK_REF 0x07
+#define SUP_BLK_PWRDN 0x08
+#define SUP_BLK_TESTPAD 0x09
+#define ADC_COM_INT5_STAB_REF 0x0a
+#define ADC_COM_QUANT 0x0b
+#define ADC_COM_BIAS1 0x0c
+#define ADC_COM_BIAS2 0x0d
+#define ADC_COM_BIAS3 0x0e
+#define TESTBUS_CTRL 0x12
+
+#define FLD_PWRDN_TUNING_BIAS 0x10
+#define FLD_PWRDN_ENABLE_PLL 0x08
+#define FLD_PWRDN_PD_BANDGAP 0x04
+#define FLD_PWRDN_PD_BIAS 0x02
+#define FLD_PWRDN_PD_TUNECK 0x01
+
+
+#define ADC_STATUS_CH1 0x20
+#define ADC_STATUS_CH2 0x40
+#define ADC_STATUS_CH3 0x60
+
+#define ADC_STATUS2_CH1 0x21
+#define ADC_STATUS2_CH2 0x41
+#define ADC_STATUS2_CH3 0x61
+
+#define ADC_CAL_ATEST_CH1 0x22
+#define ADC_CAL_ATEST_CH2 0x42
+#define ADC_CAL_ATEST_CH3 0x62
+
+#define ADC_PWRDN_CLAMP_CH1 0x23
+#define ADC_PWRDN_CLAMP_CH2 0x43
+#define ADC_PWRDN_CLAMP_CH3 0x63
+
+#define ADC_CTRL_DAC23_CH1 0x24
+#define ADC_CTRL_DAC23_CH2 0x44
+#define ADC_CTRL_DAC23_CH3 0x64
+
+#define ADC_CTRL_DAC1_CH1 0x25
+#define ADC_CTRL_DAC1_CH2 0x45
+#define ADC_CTRL_DAC1_CH3 0x65
+
+#define ADC_DCSERVO_DEM_CH1 0x26
+#define ADC_DCSERVO_DEM_CH2 0x46
+#define ADC_DCSERVO_DEM_CH3 0x66
+
+#define ADC_FB_FRCRST_CH1 0x27
+#define ADC_FB_FRCRST_CH2 0x47
+#define ADC_FB_FRCRST_CH3 0x67
+
+#define ADC_INPUT_CH1 0x28
+#define ADC_INPUT_CH2 0x48
+#define ADC_INPUT_CH3 0x68
+#define INPUT_SEL_MASK 0x30 /* [5:4] in_sel */
+
+#define ADC_NTF_PRECLMP_EN_CH1 0x29
+#define ADC_NTF_PRECLMP_EN_CH2 0x49
+#define ADC_NTF_PRECLMP_EN_CH3 0x69
+
+#define ADC_QGAIN_RES_TRM_CH1 0x2a
+#define ADC_QGAIN_RES_TRM_CH2 0x4a
+#define ADC_QGAIN_RES_TRM_CH3 0x6a
+
+#define ADC_SOC_PRECLMP_TERM_CH1 0x2b
+#define ADC_SOC_PRECLMP_TERM_CH2 0x4b
+#define ADC_SOC_PRECLMP_TERM_CH3 0x6b
+
+#define TESTBUS_CTRL_CH1 0x32
+#define TESTBUS_CTRL_CH2 0x52
+#define TESTBUS_CTRL_CH3 0x72
+
+/******************************************************************************
+ * DIF registers *
+ ******************************************************************************/
+#define DIRECT_IF_REVB_BASE 0x00300
+
+/*****************************************************************************/
+#define DIF_PLL_FREQ_WORD (DIRECT_IF_REVB_BASE + 0x00000000)
+/*****************************************************************************/
+#define FLD_DIF_PLL_LOCK 0x80000000
+/* Reserved [30:29] */
+#define FLD_DIF_PLL_FREE_RUN 0x10000000
+#define FLD_DIF_PLL_FREQ 0x0fffffff
+
+/*****************************************************************************/
+#define DIF_PLL_CTRL (DIRECT_IF_REVB_BASE + 0x00000004)
+/*****************************************************************************/
+#define FLD_DIF_KD_PD 0xff000000
+/* Reserved [23:20] */
+#define FLD_DIF_KDS_PD 0x000f0000
+#define FLD_DIF_KI_PD 0x0000ff00
+/* Reserved [7:4] */
+#define FLD_DIF_KIS_PD 0x0000000f
+
+/*****************************************************************************/
+#define DIF_PLL_CTRL1 (DIRECT_IF_REVB_BASE + 0x00000008)
+/*****************************************************************************/
+#define FLD_DIF_KD_FD 0xff000000
+/* Reserved [23:20] */
+#define FLD_DIF_KDS_FD 0x000f0000
+#define FLD_DIF_KI_FD 0x0000ff00
+#define FLD_DIF_SIG_PROP_SZ 0x000000f0
+#define FLD_DIF_KIS_FD 0x0000000f
+
+/*****************************************************************************/
+#define DIF_PLL_CTRL2 (DIRECT_IF_REVB_BASE + 0x0000000c)
+/*****************************************************************************/
+#define FLD_DIF_PLL_AGC_REF 0xfff00000
+#define FLD_DIF_PLL_AGC_KI 0x000f0000
+/* Reserved [15] */
+#define FLD_DIF_FREQ_LIMIT 0x00007000
+#define FLD_DIF_K_FD 0x00000f00
+#define FLD_DIF_DOWNSMPL_FD 0x000000ff
+
+/*****************************************************************************/
+#define DIF_PLL_CTRL3 (DIRECT_IF_REVB_BASE + 0x00000010)
+/*****************************************************************************/
+/* Reserved [31:16] */
+#define FLD_DIF_PLL_AGC_EN 0x00008000
+/* Reserved [14:12] */
+#define FLD_DIF_PLL_MAN_GAIN 0x00000fff
+
+/*****************************************************************************/
+#define DIF_AGC_IF_REF (DIRECT_IF_REVB_BASE + 0x00000014)
+/*****************************************************************************/
+#define FLD_DIF_K_AGC_RF 0xf0000000
+#define FLD_DIF_K_AGC_IF 0x0f000000
+#define FLD_DIF_K_AGC_INT 0x00f00000
+/* Reserved [19:12] */
+#define FLD_DIF_IF_REF 0x00000fff
+
+/*****************************************************************************/
+#define DIF_AGC_CTRL_IF (DIRECT_IF_REVB_BASE + 0x00000018)
+/*****************************************************************************/
+#define FLD_DIF_IF_MAX 0xff000000
+#define FLD_DIF_IF_MIN 0x00ff0000
+#define FLD_DIF_IF_AGC 0x0000ffff
+
+/*****************************************************************************/
+#define DIF_AGC_CTRL_INT (DIRECT_IF_REVB_BASE + 0x0000001c)
+/*****************************************************************************/
+#define FLD_DIF_INT_MAX 0xff000000
+#define FLD_DIF_INT_MIN 0x00ff0000
+#define FLD_DIF_INT_AGC 0x0000ffff
+
+/*****************************************************************************/
+#define DIF_AGC_CTRL_RF (DIRECT_IF_REVB_BASE + 0x00000020)
+/*****************************************************************************/
+#define FLD_DIF_RF_MAX 0xff000000
+#define FLD_DIF_RF_MIN 0x00ff0000
+#define FLD_DIF_RF_AGC 0x0000ffff
+
+/*****************************************************************************/
+#define DIF_AGC_IF_INT_CURRENT (DIRECT_IF_REVB_BASE + 0x00000024)
+/*****************************************************************************/
+#define FLD_DIF_IF_AGC_IN 0xffff0000
+#define FLD_DIF_INT_AGC_IN 0x0000ffff
+
+/*****************************************************************************/
+#define DIF_AGC_RF_CURRENT (DIRECT_IF_REVB_BASE + 0x00000028)
+/*****************************************************************************/
+/* Reserved [31:16] */
+#define FLD_DIF_RF_AGC_IN 0x0000ffff
+
+/*****************************************************************************/
+#define DIF_VIDEO_AGC_CTRL (DIRECT_IF_REVB_BASE + 0x0000002c)
+/*****************************************************************************/
+#define FLD_DIF_AFD 0xc0000000
+#define FLD_DIF_K_VID_AGC 0x30000000
+#define FLD_DIF_LINE_LENGTH 0x0fff0000
+#define FLD_DIF_AGC_GAIN 0x0000ffff
+
+/*****************************************************************************/
+#define DIF_VID_AUD_OVERRIDE (DIRECT_IF_REVB_BASE + 0x00000030)
+/*****************************************************************************/
+#define FLD_DIF_AUDIO_AGC_OVERRIDE 0x80000000
+/* Reserved [30:30] */
+#define FLD_DIF_AUDIO_MAN_GAIN 0x3f000000
+/* Reserved [23:17] */
+#define FLD_DIF_VID_AGC_OVERRIDE 0x00010000
+#define FLD_DIF_VID_MAN_GAIN 0x0000ffff
+
+/*****************************************************************************/
+#define DIF_AV_SEP_CTRL (DIRECT_IF_REVB_BASE + 0x00000034)
+/*****************************************************************************/
+#define FLD_DIF_LPF_FREQ 0xc0000000
+#define FLD_DIF_AV_PHASE_INC 0x3f000000
+#define FLD_DIF_AUDIO_FREQ 0x00ffffff
+
+/*****************************************************************************/
+#define DIF_COMP_FLT_CTRL (DIRECT_IF_REVB_BASE + 0x00000038)
+/*****************************************************************************/
+/* Reserved [31:24] */
+#define FLD_DIF_IIR23_R2 0x00ff0000
+#define FLD_DIF_IIR23_R1 0x0000ff00
+#define FLD_DIF_IIR1_R1 0x000000ff
+
+/*****************************************************************************/
+#define DIF_MISC_CTRL (DIRECT_IF_REVB_BASE + 0x0000003c)
+/*****************************************************************************/
+#define FLD_DIF_DIF_BYPASS 0x80000000
+#define FLD_DIF_FM_NYQ_GAIN 0x40000000
+#define FLD_DIF_RF_AGC_ENA 0x20000000
+#define FLD_DIF_INT_AGC_ENA 0x10000000
+#define FLD_DIF_IF_AGC_ENA 0x08000000
+#define FLD_DIF_FORCE_RF_IF_LOCK 0x04000000
+#define FLD_DIF_VIDEO_AGC_ENA 0x02000000
+#define FLD_DIF_RF_AGC_INV 0x01000000
+#define FLD_DIF_INT_AGC_INV 0x00800000
+#define FLD_DIF_IF_AGC_INV 0x00400000
+#define FLD_DIF_SPEC_INV 0x00200000
+#define FLD_DIF_AUD_FULL_BW 0x00100000
+#define FLD_DIF_AUD_SRC_SEL 0x00080000
+/* Reserved [18] */
+#define FLD_DIF_IF_FREQ 0x00030000
+/* Reserved [15:14] */
+#define FLD_DIF_TIP_OFFSET 0x00003f00
+/* Reserved [7:5] */
+#define FLD_DIF_DITHER_ENA 0x00000010
+/* Reserved [3:1] */
+#define FLD_DIF_RF_IF_LOCK 0x00000001
+
+/*****************************************************************************/
+#define DIF_SRC_PHASE_INC (DIRECT_IF_REVB_BASE + 0x00000040)
+/*****************************************************************************/
+/* Reserved [31:29] */
+#define FLD_DIF_PHASE_INC 0x1fffffff
+
+/*****************************************************************************/
+#define DIF_SRC_GAIN_CONTROL (DIRECT_IF_REVB_BASE + 0x00000044)
+/*****************************************************************************/
+/* Reserved [31:16] */
+#define FLD_DIF_SRC_KI 0x0000ff00
+#define FLD_DIF_SRC_KD 0x000000ff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF01 (DIRECT_IF_REVB_BASE + 0x00000048)
+/*****************************************************************************/
+/* Reserved [31:19] */
+#define FLD_DIF_BPF_COEFF_0 0x00070000
+/* Reserved [15:4] */
+#define FLD_DIF_BPF_COEFF_1 0x0000000f
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF23 (DIRECT_IF_REVB_BASE + 0x0000004c)
+/*****************************************************************************/
+/* Reserved [31:22] */
+#define FLD_DIF_BPF_COEFF_2 0x003f0000
+/* Reserved [15:7] */
+#define FLD_DIF_BPF_COEFF_3 0x0000007f
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF45 (DIRECT_IF_REVB_BASE + 0x00000050)
+/*****************************************************************************/
+/* Reserved [31:24] */
+#define FLD_DIF_BPF_COEFF_4 0x00ff0000
+/* Reserved [15:8] */
+#define FLD_DIF_BPF_COEFF_5 0x000000ff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF67 (DIRECT_IF_REVB_BASE + 0x00000054)
+/*****************************************************************************/
+/* Reserved [31:25] */
+#define FLD_DIF_BPF_COEFF_6 0x01ff0000
+/* Reserved [15:9] */
+#define FLD_DIF_BPF_COEFF_7 0x000001ff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF89 (DIRECT_IF_REVB_BASE + 0x00000058)
+/*****************************************************************************/
+/* Reserved [31:26] */
+#define FLD_DIF_BPF_COEFF_8 0x03ff0000
+/* Reserved [15:10] */
+#define FLD_DIF_BPF_COEFF_9 0x000003ff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF1011 (DIRECT_IF_REVB_BASE + 0x0000005c)
+/*****************************************************************************/
+/* Reserved [31:27] */
+#define FLD_DIF_BPF_COEFF_10 0x07ff0000
+/* Reserved [15:11] */
+#define FLD_DIF_BPF_COEFF_11 0x000007ff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF1213 (DIRECT_IF_REVB_BASE + 0x00000060)
+/*****************************************************************************/
+/* Reserved [31:27] */
+#define FLD_DIF_BPF_COEFF_12 0x07ff0000
+/* Reserved [15:12] */
+#define FLD_DIF_BPF_COEFF_13 0x00000fff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF1415 (DIRECT_IF_REVB_BASE + 0x00000064)
+/*****************************************************************************/
+/* Reserved [31:28] */
+#define FLD_DIF_BPF_COEFF_14 0x0fff0000
+/* Reserved [15:12] */
+#define FLD_DIF_BPF_COEFF_15 0x00000fff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF1617 (DIRECT_IF_REVB_BASE + 0x00000068)
+/*****************************************************************************/
+/* Reserved [31:29] */
+#define FLD_DIF_BPF_COEFF_16 0x1fff0000
+/* Reserved [15:13] */
+#define FLD_DIF_BPF_COEFF_17 0x00001fff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF1819 (DIRECT_IF_REVB_BASE + 0x0000006c)
+/*****************************************************************************/
+/* Reserved [31:29] */
+#define FLD_DIF_BPF_COEFF_18 0x1fff0000
+/* Reserved [15:13] */
+#define FLD_DIF_BPF_COEFF_19 0x00001fff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF2021 (DIRECT_IF_REVB_BASE + 0x00000070)
+/*****************************************************************************/
+/* Reserved [31:29] */
+#define FLD_DIF_BPF_COEFF_20 0x1fff0000
+/* Reserved [15:14] */
+#define FLD_DIF_BPF_COEFF_21 0x00003fff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF2223 (DIRECT_IF_REVB_BASE + 0x00000074)
+/*****************************************************************************/
+/* Reserved [31:30] */
+#define FLD_DIF_BPF_COEFF_22 0x3fff0000
+/* Reserved [15:14] */
+#define FLD_DIF_BPF_COEFF_23 0x00003fff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF2425 (DIRECT_IF_REVB_BASE + 0x00000078)
+/*****************************************************************************/
+/* Reserved [31:30] */
+#define FLD_DIF_BPF_COEFF_24 0x3fff0000
+/* Reserved [15:14] */
+#define FLD_DIF_BPF_COEFF_25 0x00003fff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF2627 (DIRECT_IF_REVB_BASE + 0x0000007c)
+/*****************************************************************************/
+/* Reserved [31:30] */
+#define FLD_DIF_BPF_COEFF_26 0x3fff0000
+/* Reserved [15:14] */
+#define FLD_DIF_BPF_COEFF_27 0x00003fff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF2829 (DIRECT_IF_REVB_BASE + 0x00000080)
+/*****************************************************************************/
+/* Reserved [31:30] */
+#define FLD_DIF_BPF_COEFF_28 0x3fff0000
+/* Reserved [15:14] */
+#define FLD_DIF_BPF_COEFF_29 0x00003fff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF3031 (DIRECT_IF_REVB_BASE + 0x00000084)
+/*****************************************************************************/
+/* Reserved [31:30] */
+#define FLD_DIF_BPF_COEFF_30 0x3fff0000
+/* Reserved [15:14] */
+#define FLD_DIF_BPF_COEFF_31 0x00003fff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF3233 (DIRECT_IF_REVB_BASE + 0x00000088)
+/*****************************************************************************/
+/* Reserved [31:30] */
+#define FLD_DIF_BPF_COEFF_32 0x3fff0000
+/* Reserved [15:14] */
+#define FLD_DIF_BPF_COEFF_33 0x00003fff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF3435 (DIRECT_IF_REVB_BASE + 0x0000008c)
+/*****************************************************************************/
+/* Reserved [31:30] */
+#define FLD_DIF_BPF_COEFF_34 0x3fff0000
+/* Reserved [15:14] */
+#define FLD_DIF_BPF_COEFF_35 0x00003fff
+
+/*****************************************************************************/
+#define DIF_BPF_COEFF36 (DIRECT_IF_REVB_BASE + 0x00000090)
+/*****************************************************************************/
+/* Reserved [31:30] */
+#define FLD_DIF_BPF_COEFF_36 0x3fff0000
+/* Reserved [15:0] */
+
+/*****************************************************************************/
+#define DIF_RPT_VARIANCE (DIRECT_IF_REVB_BASE + 0x00000094)
+/*****************************************************************************/
+/* Reserved [31:20] */
+#define FLD_DIF_RPT_VARIANCE 0x000fffff
+
+/*****************************************************************************/
+#define DIF_SOFT_RST_CTRL_REVB (DIRECT_IF_REVB_BASE + 0x00000098)
+/*****************************************************************************/
+/* Reserved [31:8] */
+#define FLD_DIF_DIF_SOFT_RST 0x00000080
+#define FLD_DIF_DIF_REG_RST_MSK 0x00000040
+#define FLD_DIF_AGC_RST_MSK 0x00000020
+#define FLD_DIF_CMP_RST_MSK 0x00000010
+#define FLD_DIF_AVS_RST_MSK 0x00000008
+#define FLD_DIF_NYQ_RST_MSK 0x00000004
+#define FLD_DIF_DIF_SRC_RST_MSK 0x00000002
+#define FLD_DIF_PLL_RST_MSK 0x00000001
+
+/*****************************************************************************/
+#define DIF_PLL_FREQ_ERR (DIRECT_IF_REVB_BASE + 0x0000009c)
+/*****************************************************************************/
+/* Reserved [31:25] */
+#define FLD_DIF_CTL_IP 0x01ffffff
+
+#endif
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c
new file mode 100644
index 00000000000..0d333e679f7
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-core.c
@@ -0,0 +1,1200 @@
+/*
+ cx231xx-core.c - driver for Conexant Cx23100/101/102
+ USB video capture devices
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+ Based on em28xx driver
+
+ 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/list.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/vmalloc.h>
+#include <media/v4l2-common.h>
+
+#include "cx231xx.h"
+#include "cx231xx-reg.h"
+
+/* #define ENABLE_DEBUG_ISOC_FRAMES */
+
+static unsigned int core_debug;
+module_param(core_debug, int, 0644);
+MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
+
+#define cx231xx_coredbg(fmt, arg...) do {\
+ if (core_debug) \
+ printk(KERN_INFO "%s %s :"fmt, \
+ dev->name, __func__ , ##arg); } while (0)
+
+static unsigned int reg_debug;
+module_param(reg_debug, int, 0644);
+MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]");
+
+#define cx231xx_regdbg(fmt, arg...) do {\
+ if (reg_debug) \
+ printk(KERN_INFO "%s %s :"fmt, \
+ dev->name, __func__ , ##arg); } while (0)
+
+static int alt = CX231XX_PINOUT;
+module_param(alt, int, 0644);
+MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
+
+#define cx231xx_isocdbg(fmt, arg...) do {\
+ if (core_debug) \
+ printk(KERN_INFO "%s %s :"fmt, \
+ dev->name, __func__ , ##arg); } while (0)
+
+/*****************************************************************
+* Device control list functions *
+******************************************************************/
+
+static LIST_HEAD(cx231xx_devlist);
+static DEFINE_MUTEX(cx231xx_devlist_mutex);
+
+struct cx231xx *cx231xx_get_device(int minor,
+ enum v4l2_buf_type *fh_type, int *has_radio)
+{
+ struct cx231xx *h, *dev = NULL;
+
+ *fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ *has_radio = 0;
+
+ mutex_lock(&cx231xx_devlist_mutex);
+ list_for_each_entry(h, &cx231xx_devlist, devlist) {
+ if (h->vdev->minor == minor)
+ dev = h;
+ if (h->vbi_dev->minor == minor) {
+ dev = h;
+ *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ }
+ if (h->radio_dev && h->radio_dev->minor == minor) {
+ dev = h;
+ *has_radio = 1;
+ }
+ }
+ mutex_unlock(&cx231xx_devlist_mutex);
+
+ return dev;
+}
+
+/*
+ * cx231xx_realease_resources()
+ * unregisters the v4l2,i2c and usb devices
+ * called when the device gets disconected or at module unload
+*/
+void cx231xx_remove_from_devlist(struct cx231xx *dev)
+{
+ mutex_lock(&cx231xx_devlist_mutex);
+ list_del(&dev->devlist);
+ mutex_unlock(&cx231xx_devlist_mutex);
+};
+
+void cx231xx_add_into_devlist(struct cx231xx *dev)
+{
+ mutex_lock(&cx231xx_devlist_mutex);
+ list_add_tail(&dev->devlist, &cx231xx_devlist);
+ mutex_unlock(&cx231xx_devlist_mutex);
+};
+
+static LIST_HEAD(cx231xx_extension_devlist);
+static DEFINE_MUTEX(cx231xx_extension_devlist_lock);
+
+int cx231xx_register_extension(struct cx231xx_ops *ops)
+{
+ struct cx231xx *dev = NULL;
+
+ mutex_lock(&cx231xx_devlist_mutex);
+ mutex_lock(&cx231xx_extension_devlist_lock);
+ list_add_tail(&ops->next, &cx231xx_extension_devlist);
+ list_for_each_entry(dev, &cx231xx_devlist, devlist) {
+ if (dev)
+ ops->init(dev);
+ }
+ printk(KERN_INFO DRIVER_NAME ": %s initialized\n", ops->name);
+ mutex_unlock(&cx231xx_extension_devlist_lock);
+ mutex_unlock(&cx231xx_devlist_mutex);
+ return 0;
+}
+EXPORT_SYMBOL(cx231xx_register_extension);
+
+void cx231xx_unregister_extension(struct cx231xx_ops *ops)
+{
+ struct cx231xx *dev = NULL;
+
+ mutex_lock(&cx231xx_devlist_mutex);
+ list_for_each_entry(dev, &cx231xx_devlist, devlist) {
+ if (dev)
+ ops->fini(dev);
+ }
+
+ mutex_lock(&cx231xx_extension_devlist_lock);
+ printk(KERN_INFO DRIVER_NAME ": %s removed\n", ops->name);
+ list_del(&ops->next);
+ mutex_unlock(&cx231xx_extension_devlist_lock);
+ mutex_unlock(&cx231xx_devlist_mutex);
+}
+EXPORT_SYMBOL(cx231xx_unregister_extension);
+
+void cx231xx_init_extension(struct cx231xx *dev)
+{
+ struct cx231xx_ops *ops = NULL;
+
+ mutex_lock(&cx231xx_extension_devlist_lock);
+ if (!list_empty(&cx231xx_extension_devlist)) {
+ list_for_each_entry(ops, &cx231xx_extension_devlist, next) {
+ if (ops->init)
+ ops->init(dev);
+ }
+ }
+ mutex_unlock(&cx231xx_extension_devlist_lock);
+}
+
+void cx231xx_close_extension(struct cx231xx *dev)
+{
+ struct cx231xx_ops *ops = NULL;
+
+ mutex_lock(&cx231xx_extension_devlist_lock);
+ if (!list_empty(&cx231xx_extension_devlist)) {
+ list_for_each_entry(ops, &cx231xx_extension_devlist, next) {
+ if (ops->fini)
+ ops->fini(dev);
+ }
+ }
+ mutex_unlock(&cx231xx_extension_devlist_lock);
+}
+
+/****************************************************************
+* U S B related functions *
+*****************************************************************/
+int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus,
+ struct cx231xx_i2c_xfer_data *req_data)
+{
+ int status = 0;
+ struct cx231xx *dev = i2c_bus->dev;
+ struct VENDOR_REQUEST_IN ven_req;
+
+ u8 saddr_len = 0;
+ u8 _i2c_period = 0;
+ u8 _i2c_nostop = 0;
+ u8 _i2c_reserve = 0;
+
+ /* Get the I2C period, nostop and reserve parameters */
+ _i2c_period = i2c_bus->i2c_period;
+ _i2c_nostop = i2c_bus->i2c_nostop;
+ _i2c_reserve = i2c_bus->i2c_reserve;
+
+ saddr_len = req_data->saddr_len;
+
+ /* Set wValue */
+ if (saddr_len == 1) /* need check saddr_len == 0 */
+ ven_req.wValue =
+ req_data->
+ dev_addr << 9 | _i2c_period << 4 | saddr_len << 2 |
+ _i2c_nostop << 1 | I2C_SYNC | _i2c_reserve << 6;
+ else
+ ven_req.wValue =
+ req_data->
+ dev_addr << 9 | _i2c_period << 4 | saddr_len << 2 |
+ _i2c_nostop << 1 | I2C_SYNC | _i2c_reserve << 6;
+
+ /* set channel number */
+ if (req_data->direction & I2C_M_RD) {
+ /* channel number, for read,spec required channel_num +4 */
+ ven_req.bRequest = i2c_bus->nr + 4;
+ } else
+ ven_req.bRequest = i2c_bus->nr; /* channel number, */
+
+ /* set index value */
+ switch (saddr_len) {
+ case 0:
+ ven_req.wIndex = 0; /* need check */
+ break;
+ case 1:
+ ven_req.wIndex = (req_data->saddr_dat & 0xff);
+ break;
+ case 2:
+ ven_req.wIndex = req_data->saddr_dat;
+ break;
+ }
+
+ /* set wLength value */
+ ven_req.wLength = req_data->buf_size;
+
+ /* set bData value */
+ ven_req.bData = 0;
+
+ /* set the direction */
+ if (req_data->direction) {
+ ven_req.direction = USB_DIR_IN;
+ memset(req_data->p_buffer, 0x00, ven_req.wLength);
+ } else
+ ven_req.direction = USB_DIR_OUT;
+
+ /* set the buffer for read / write */
+ ven_req.pBuff = req_data->p_buffer;
+
+
+ /* call common vendor command request */
+ status = cx231xx_send_vendor_cmd(dev, &ven_req);
+ if (status < 0) {
+ cx231xx_info
+ ("UsbInterface::sendCommand, failed with status -%d\n",
+ status);
+ }
+
+ return status;
+}
+EXPORT_SYMBOL_GPL(cx231xx_send_usb_command);
+
+/*
+ * cx231xx_read_ctrl_reg()
+ * reads data from the usb device specifying bRequest and wValue
+ */
+int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
+ char *buf, int len)
+{
+ u8 val = 0;
+ int ret;
+ int pipe = usb_rcvctrlpipe(dev->udev, 0);
+
+ if (dev->state & DEV_DISCONNECTED)
+ return -ENODEV;
+
+ if (len > URB_MAX_CTRL_SIZE)
+ return -EINVAL;
+
+ switch (len) {
+ case 1:
+ val = ENABLE_ONE_BYTE;
+ break;
+ case 2:
+ val = ENABLE_TWE_BYTE;
+ break;
+ case 3:
+ val = ENABLE_THREE_BYTE;
+ break;
+ case 4:
+ val = ENABLE_FOUR_BYTE;
+ break;
+ default:
+ val = 0xFF; /* invalid option */
+ }
+
+ if (val == 0xFF)
+ return -EINVAL;
+
+ if (reg_debug) {
+ cx231xx_isocdbg("(pipe 0x%08x): "
+ "IN: %02x %02x %02x %02x %02x %02x %02x %02x ",
+ pipe,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ req, 0, val,
+ reg & 0xff, reg >> 8, len & 0xff, len >> 8);
+ }
+
+ mutex_lock(&dev->ctrl_urb_lock);
+ ret = usb_control_msg(dev->udev, pipe, req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ val, reg, dev->urb_buf, len, HZ);
+ if (ret < 0) {
+ cx231xx_isocdbg(" failed!\n");
+ /* mutex_unlock(&dev->ctrl_urb_lock); */
+ return ret;
+ }
+
+ if (len)
+ memcpy(buf, dev->urb_buf, len);
+
+ mutex_unlock(&dev->ctrl_urb_lock);
+
+ if (reg_debug) {
+ int byte;
+
+ cx231xx_isocdbg("<<<");
+ for (byte = 0; byte < len; byte++)
+ cx231xx_isocdbg(" %02x", (unsigned char)buf[byte]);
+ cx231xx_isocdbg("\n");
+ }
+
+ return ret;
+}
+
+int cx231xx_send_vendor_cmd(struct cx231xx *dev,
+ struct VENDOR_REQUEST_IN *ven_req)
+{
+ int ret;
+ int pipe = 0;
+
+ if (dev->state & DEV_DISCONNECTED)
+ return -ENODEV;
+
+ if ((ven_req->wLength > URB_MAX_CTRL_SIZE))
+ return -EINVAL;
+
+ if (ven_req->direction)
+ pipe = usb_rcvctrlpipe(dev->udev, 0);
+ else
+ pipe = usb_sndctrlpipe(dev->udev, 0);
+
+ if (reg_debug) {
+ int byte;
+
+ cx231xx_isocdbg("(pipe 0x%08x): "
+ "OUT: %02x %02x %02x %04x %04x %04x >>>",
+ pipe,
+ ven_req->
+ direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ ven_req->bRequest, 0, ven_req->wValue,
+ ven_req->wIndex, ven_req->wLength);
+
+ for (byte = 0; byte < ven_req->wLength; byte++)
+ cx231xx_isocdbg(" %02x",
+ (unsigned char)ven_req->pBuff[byte]);
+ cx231xx_isocdbg("\n");
+ }
+
+ mutex_lock(&dev->ctrl_urb_lock);
+ ret = usb_control_msg(dev->udev, pipe, ven_req->bRequest,
+ ven_req->
+ direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ ven_req->wValue, ven_req->wIndex, ven_req->pBuff,
+ ven_req->wLength, HZ);
+ mutex_unlock(&dev->ctrl_urb_lock);
+
+ return ret;
+}
+
+/*
+ * cx231xx_write_ctrl_reg()
+ * sends data to the usb device, specifying bRequest
+ */
+int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, char *buf,
+ int len)
+{
+ u8 val = 0;
+ int ret;
+ int pipe = usb_sndctrlpipe(dev->udev, 0);
+
+ if (dev->state & DEV_DISCONNECTED)
+ return -ENODEV;
+
+ if ((len < 1) || (len > URB_MAX_CTRL_SIZE))
+ return -EINVAL;
+
+ switch (len) {
+ case 1:
+ val = ENABLE_ONE_BYTE;
+ break;
+ case 2:
+ val = ENABLE_TWE_BYTE;
+ break;
+ case 3:
+ val = ENABLE_THREE_BYTE;
+ break;
+ case 4:
+ val = ENABLE_FOUR_BYTE;
+ break;
+ default:
+ val = 0xFF; /* invalid option */
+ }
+
+ if (val == 0xFF)
+ return -EINVAL;
+
+ if (reg_debug) {
+ int byte;
+
+ cx231xx_isocdbg("(pipe 0x%08x): "
+ "OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>",
+ pipe,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ req, 0, val, reg & 0xff,
+ reg >> 8, len & 0xff, len >> 8);
+
+ for (byte = 0; byte < len; byte++)
+ cx231xx_isocdbg(" %02x", (unsigned char)buf[byte]);
+ cx231xx_isocdbg("\n");
+ }
+
+ mutex_lock(&dev->ctrl_urb_lock);
+ memcpy(dev->urb_buf, buf, len);
+ ret = usb_control_msg(dev->udev, pipe, req,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ val, reg, dev->urb_buf, len, HZ);
+ mutex_unlock(&dev->ctrl_urb_lock);
+
+ return ret;
+}
+
+/****************************************************************
+* USB Alternate Setting functions *
+*****************************************************************/
+
+int cx231xx_set_video_alternate(struct cx231xx *dev)
+{
+ int errCode, prev_alt = dev->video_mode.alt;
+ unsigned int min_pkt_size = dev->width * 2 + 4;
+ u32 usb_interface_index = 0;
+
+ /* When image size is bigger than a certain value,
+ the frame size should be increased, otherwise, only
+ green screen will be received.
+ */
+ if (dev->width * 2 * dev->height > 720 * 240 * 2)
+ min_pkt_size *= 2;
+
+ if (dev->width > 360) {
+ /* resolutions: 720,704,640 */
+ dev->video_mode.alt = 3;
+ } else if (dev->width > 180) {
+ /* resolutions: 360,352,320,240 */
+ dev->video_mode.alt = 2;
+ } else if (dev->width > 0) {
+ /* resolutions: 180,176,160,128,88 */
+ dev->video_mode.alt = 1;
+ } else {
+ /* Change to alt0 BULK to release USB bandwidth */
+ dev->video_mode.alt = 0;
+ }
+
+ /* Get the correct video interface Index */
+ usb_interface_index =
+ dev->current_pcb_config.hs_config_info[0].interface_info.
+ video_index + 1;
+
+ if (dev->video_mode.alt != prev_alt) {
+ cx231xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
+ min_pkt_size, dev->video_mode.alt);
+ dev->video_mode.max_pkt_size =
+ dev->video_mode.alt_max_pkt_size[dev->video_mode.alt];
+ cx231xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n",
+ dev->video_mode.alt,
+ dev->video_mode.max_pkt_size);
+ cx231xx_info
+ (" setting alt %d with wMaxPktSize=%u , Interface = %d\n",
+ dev->video_mode.alt, dev->video_mode.max_pkt_size,
+ usb_interface_index);
+ errCode =
+ usb_set_interface(dev->udev, usb_interface_index,
+ dev->video_mode.alt);
+ if (errCode < 0) {
+ cx231xx_errdev
+ ("cannot change alt number to %d (error=%i)\n",
+ dev->video_mode.alt, errCode);
+ return errCode;
+ }
+ }
+ return 0;
+}
+
+int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt)
+{
+ int status = 0;
+ u32 usb_interface_index = 0;
+ u32 max_pkt_size = 0;
+
+ switch (index) {
+ case INDEX_TS1:
+ usb_interface_index =
+ dev->current_pcb_config.hs_config_info[0].interface_info.
+ ts1_index + 1;
+ dev->video_mode.alt = alt;
+ if (dev->ts1_mode.alt_max_pkt_size != NULL)
+ max_pkt_size = dev->ts1_mode.max_pkt_size =
+ dev->ts1_mode.alt_max_pkt_size[dev->ts1_mode.alt];
+ break;
+ case INDEX_TS2:
+ usb_interface_index =
+ dev->current_pcb_config.hs_config_info[0].interface_info.
+ ts2_index + 1;
+ break;
+ case INDEX_AUDIO:
+ usb_interface_index =
+ dev->current_pcb_config.hs_config_info[0].interface_info.
+ audio_index + 1;
+ dev->adev.alt = alt;
+ if (dev->adev.alt_max_pkt_size != NULL)
+ max_pkt_size = dev->adev.max_pkt_size =
+ dev->adev.alt_max_pkt_size[dev->adev.alt];
+ break;
+ case INDEX_VIDEO:
+ usb_interface_index =
+ dev->current_pcb_config.hs_config_info[0].interface_info.
+ video_index + 1;
+ dev->video_mode.alt = alt;
+ if (dev->video_mode.alt_max_pkt_size != NULL)
+ max_pkt_size = dev->video_mode.max_pkt_size =
+ dev->video_mode.alt_max_pkt_size[dev->video_mode.
+ alt];
+ break;
+ case INDEX_VANC:
+ usb_interface_index =
+ dev->current_pcb_config.hs_config_info[0].interface_info.
+ vanc_index + 1;
+ dev->vbi_mode.alt = alt;
+ if (dev->vbi_mode.alt_max_pkt_size != NULL)
+ max_pkt_size = dev->vbi_mode.max_pkt_size =
+ dev->vbi_mode.alt_max_pkt_size[dev->vbi_mode.alt];
+ break;
+ case INDEX_HANC:
+ usb_interface_index =
+ dev->current_pcb_config.hs_config_info[0].interface_info.
+ hanc_index + 1;
+ dev->sliced_cc_mode.alt = alt;
+ if (dev->sliced_cc_mode.alt_max_pkt_size != NULL)
+ max_pkt_size = dev->sliced_cc_mode.max_pkt_size =
+ dev->sliced_cc_mode.alt_max_pkt_size[dev->
+ sliced_cc_mode.
+ alt];
+ break;
+ default:
+ break;
+ }
+
+ if (alt > 0 && max_pkt_size == 0) {
+ cx231xx_errdev
+ ("can't change interface %d alt no. to %d: Max. Pkt size = 0\n",
+ usb_interface_index, alt);
+ return -1;
+ }
+
+ cx231xx_info
+ (" setting alternate %d with wMaxPacketSize=%u , Interface = %d\n",
+ alt, max_pkt_size, usb_interface_index);
+
+ if (usb_interface_index > 0) {
+ status = usb_set_interface(dev->udev, usb_interface_index, alt);
+ if (status < 0) {
+ cx231xx_errdev
+ ("can't change interface %d alt no. to %d (err=%i)\n",
+ usb_interface_index, alt, status);
+ return status;
+ }
+ }
+
+ return status;
+}
+EXPORT_SYMBOL_GPL(cx231xx_set_alt_setting);
+
+int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio)
+{
+ int rc = 0;
+
+ if (!gpio)
+ return rc;
+
+ /* Send GPIO reset sequences specified at board entry */
+ while (gpio->sleep >= 0) {
+ rc = cx231xx_set_gpio_value(dev, gpio->bit, gpio->val);
+ if (rc < 0)
+ return rc;
+
+ if (gpio->sleep > 0)
+ msleep(gpio->sleep);
+
+ gpio++;
+ }
+ return rc;
+}
+
+int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
+{
+ if (dev->mode == set_mode)
+ return 0;
+
+ if (set_mode == CX231XX_SUSPEND) {
+ /* Set the chip in power saving mode */
+ dev->mode = set_mode;
+ }
+
+ /* Resource is locked */
+ if (dev->mode != CX231XX_SUSPEND)
+ return -EINVAL;
+
+ dev->mode = set_mode;
+
+ if (dev->mode == CX231XX_DIGITAL_MODE)
+ ;/* Set Digital power mode */
+ else
+ ;/* Set Analog Power mode */
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cx231xx_set_mode);
+
+/*****************************************************************
+* URB Streaming functions *
+******************************************************************/
+
+/*
+ * IRQ callback, called by URB callback
+ */
+static void cx231xx_irq_callback(struct urb *urb)
+{
+ struct cx231xx_dmaqueue *dma_q = urb->context;
+ struct cx231xx_video_mode *vmode =
+ container_of(dma_q, struct cx231xx_video_mode, vidq);
+ struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode);
+ int rc, i;
+
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ cx231xx_isocdbg("urb completition error %d.\n", urb->status);
+ break;
+ }
+
+ /* Copy data from URB */
+ spin_lock(&dev->video_mode.slock);
+ rc = dev->video_mode.isoc_ctl.isoc_copy(dev, urb);
+ spin_unlock(&dev->video_mode.slock);
+
+ /* Reset urb buffers */
+ for (i = 0; i < urb->number_of_packets; i++) {
+ urb->iso_frame_desc[i].status = 0;
+ urb->iso_frame_desc[i].actual_length = 0;
+ }
+ urb->status = 0;
+
+ urb->status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (urb->status) {
+ cx231xx_isocdbg("urb resubmit failed (error=%i)\n",
+ urb->status);
+ }
+}
+
+/*
+ * Stop and Deallocate URBs
+ */
+void cx231xx_uninit_isoc(struct cx231xx *dev)
+{
+ struct urb *urb;
+ int i;
+
+ cx231xx_isocdbg("cx231xx: called cx231xx_uninit_isoc\n");
+
+ dev->video_mode.isoc_ctl.nfields = -1;
+ for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) {
+ urb = dev->video_mode.isoc_ctl.urb[i];
+ if (urb) {
+ if (!irqs_disabled())
+ usb_kill_urb(urb);
+ else
+ usb_unlink_urb(urb);
+
+ if (dev->video_mode.isoc_ctl.transfer_buffer[i]) {
+ usb_buffer_free(dev->udev,
+ urb->transfer_buffer_length,
+ dev->video_mode.isoc_ctl.
+ transfer_buffer[i],
+ urb->transfer_dma);
+ }
+ usb_free_urb(urb);
+ dev->video_mode.isoc_ctl.urb[i] = NULL;
+ }
+ dev->video_mode.isoc_ctl.transfer_buffer[i] = NULL;
+ }
+
+ kfree(dev->video_mode.isoc_ctl.urb);
+ kfree(dev->video_mode.isoc_ctl.transfer_buffer);
+
+ dev->video_mode.isoc_ctl.urb = NULL;
+ dev->video_mode.isoc_ctl.transfer_buffer = NULL;
+ dev->video_mode.isoc_ctl.num_bufs = 0;
+
+ cx231xx_capture_start(dev, 0, Raw_Video);
+}
+EXPORT_SYMBOL_GPL(cx231xx_uninit_isoc);
+
+/*
+ * Allocate URBs and start IRQ
+ */
+int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
+ int num_bufs, int max_pkt_size,
+ int (*isoc_copy) (struct cx231xx *dev, struct urb *urb))
+{
+ struct cx231xx_dmaqueue *dma_q = &dev->video_mode.vidq;
+ int i;
+ int sb_size, pipe;
+ struct urb *urb;
+ int j, k;
+ int rc;
+
+ cx231xx_isocdbg("cx231xx: called cx231xx_prepare_isoc\n");
+
+ dev->video_input = dev->video_input > 2 ? 2 : dev->video_input;
+
+ cx231xx_info("Setting Video mux to %d\n", dev->video_input);
+ video_mux(dev, dev->video_input);
+
+ /* De-allocates all pending stuff */
+ cx231xx_uninit_isoc(dev);
+
+ dev->video_mode.isoc_ctl.isoc_copy = isoc_copy;
+ dev->video_mode.isoc_ctl.num_bufs = num_bufs;
+ dma_q->pos = 0;
+ dma_q->is_partial_line = 0;
+ dma_q->last_sav = 0;
+ dma_q->current_field = -1;
+ dma_q->field1_done = 0;
+ dma_q->lines_per_field = dev->height / 2;
+ dma_q->bytes_left_in_line = dev->width << 1;
+ dma_q->lines_completed = 0;
+ for (i = 0; i < 8; i++)
+ dma_q->partial_buf[i] = 0;
+
+ dev->video_mode.isoc_ctl.urb =
+ kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
+ if (!dev->video_mode.isoc_ctl.urb) {
+ cx231xx_errdev("cannot alloc memory for usb buffers\n");
+ return -ENOMEM;
+ }
+
+ dev->video_mode.isoc_ctl.transfer_buffer =
+ kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
+ if (!dev->video_mode.isoc_ctl.transfer_buffer) {
+ cx231xx_errdev("cannot allocate memory for usbtransfer\n");
+ kfree(dev->video_mode.isoc_ctl.urb);
+ return -ENOMEM;
+ }
+
+ dev->video_mode.isoc_ctl.max_pkt_size = max_pkt_size;
+ dev->video_mode.isoc_ctl.buf = NULL;
+
+ sb_size = max_packets * dev->video_mode.isoc_ctl.max_pkt_size;
+
+ /* allocate urbs and transfer buffers */
+ for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) {
+ urb = usb_alloc_urb(max_packets, GFP_KERNEL);
+ if (!urb) {
+ cx231xx_err("cannot alloc isoc_ctl.urb %i\n", i);
+ cx231xx_uninit_isoc(dev);
+ return -ENOMEM;
+ }
+ dev->video_mode.isoc_ctl.urb[i] = urb;
+
+ dev->video_mode.isoc_ctl.transfer_buffer[i] =
+ usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,
+ &urb->transfer_dma);
+ if (!dev->video_mode.isoc_ctl.transfer_buffer[i]) {
+ cx231xx_err("unable to allocate %i bytes for transfer"
+ " buffer %i%s\n",
+ sb_size, i,
+ in_interrupt() ? " while in int" : "");
+ cx231xx_uninit_isoc(dev);
+ return -ENOMEM;
+ }
+ memset(dev->video_mode.isoc_ctl.transfer_buffer[i], 0, sb_size);
+
+ pipe =
+ usb_rcvisocpipe(dev->udev, dev->video_mode.end_point_addr);
+
+ usb_fill_int_urb(urb, dev->udev, pipe,
+ dev->video_mode.isoc_ctl.transfer_buffer[i],
+ sb_size, cx231xx_irq_callback, dma_q, 1);
+
+ urb->number_of_packets = max_packets;
+ urb->transfer_flags = URB_ISO_ASAP;
+
+ k = 0;
+ for (j = 0; j < max_packets; j++) {
+ urb->iso_frame_desc[j].offset = k;
+ urb->iso_frame_desc[j].length =
+ dev->video_mode.isoc_ctl.max_pkt_size;
+ k += dev->video_mode.isoc_ctl.max_pkt_size;
+ }
+ }
+
+ init_waitqueue_head(&dma_q->wq);
+
+ /* submit urbs and enables IRQ */
+ for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) {
+ rc = usb_submit_urb(dev->video_mode.isoc_ctl.urb[i],
+ GFP_ATOMIC);
+ if (rc) {
+ cx231xx_err("submit of urb %i failed (error=%i)\n", i,
+ rc);
+ cx231xx_uninit_isoc(dev);
+ return rc;
+ }
+ }
+
+ cx231xx_capture_start(dev, 1, Raw_Video);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cx231xx_init_isoc);
+
+/*****************************************************************
+* Device Init/UnInit functions *
+******************************************************************/
+int cx231xx_dev_init(struct cx231xx *dev)
+{
+ int errCode = 0;
+
+ /* Initialize I2C bus */
+
+ /* External Master 1 Bus */
+ dev->i2c_bus[0].nr = 0;
+ dev->i2c_bus[0].dev = dev;
+ dev->i2c_bus[0].i2c_period = I2C_SPEED_1M; /* 1MHz */
+ dev->i2c_bus[0].i2c_nostop = 0;
+ dev->i2c_bus[0].i2c_reserve = 0;
+
+ /* External Master 2 Bus */
+ dev->i2c_bus[1].nr = 1;
+ dev->i2c_bus[1].dev = dev;
+ dev->i2c_bus[1].i2c_period = I2C_SPEED_1M; /* 1MHz */
+ dev->i2c_bus[1].i2c_nostop = 0;
+ dev->i2c_bus[1].i2c_reserve = 0;
+
+ /* Internal Master 3 Bus */
+ dev->i2c_bus[2].nr = 2;
+ dev->i2c_bus[2].dev = dev;
+ dev->i2c_bus[2].i2c_period = I2C_SPEED_400K; /* 400kHz */
+ dev->i2c_bus[2].i2c_nostop = 0;
+ dev->i2c_bus[2].i2c_reserve = 0;
+
+ /* register I2C buses */
+ cx231xx_i2c_register(&dev->i2c_bus[0]);
+ cx231xx_i2c_register(&dev->i2c_bus[1]);
+ cx231xx_i2c_register(&dev->i2c_bus[2]);
+
+ /* init hardware */
+ /* Note : with out calling set power mode function,
+ afe can not be set up correctly */
+ errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV);
+ if (errCode < 0) {
+ cx231xx_errdev
+ ("%s: Failed to set Power - errCode [%d]!\n",
+ __func__, errCode);
+ return errCode;
+ }
+
+ /* initialize Colibri block */
+ errCode = cx231xx_afe_init_super_block(dev, 0x23c);
+ if (errCode < 0) {
+ cx231xx_errdev
+ ("%s: cx231xx_afe init super block - errCode [%d]!\n",
+ __func__, errCode);
+ return errCode;
+ }
+ errCode = cx231xx_afe_init_channels(dev);
+ if (errCode < 0) {
+ cx231xx_errdev
+ ("%s: cx231xx_afe init channels - errCode [%d]!\n",
+ __func__, errCode);
+ return errCode;
+ }
+
+ /* Set DIF in By pass mode */
+ errCode = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
+ if (errCode < 0) {
+ cx231xx_errdev
+ ("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n",
+ __func__, errCode);
+ return errCode;
+ }
+
+ /* I2S block related functions */
+ errCode = cx231xx_i2s_blk_initialize(dev);
+ if (errCode < 0) {
+ cx231xx_errdev
+ ("%s: cx231xx_i2s block initialize - errCode [%d]!\n",
+ __func__, errCode);
+ return errCode;
+ }
+
+ /* init control pins */
+ errCode = cx231xx_init_ctrl_pin_status(dev);
+ if (errCode < 0) {
+ cx231xx_errdev("%s: cx231xx_init ctrl pins - errCode [%d]!\n",
+ __func__, errCode);
+ return errCode;
+ }
+
+ /* set AGC mode to Analog */
+ errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1);
+ if (errCode < 0) {
+ cx231xx_errdev
+ ("%s: cx231xx_AGC mode to Analog - errCode [%d]!\n",
+ __func__, errCode);
+ return errCode;
+ }
+
+ /* set all alternate settings to zero initially */
+ cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0);
+ cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
+ cx231xx_set_alt_setting(dev, INDEX_HANC, 0);
+ if (dev->board.has_dvb)
+ cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
+
+ /* set the I2C master port to 3 on channel 1 */
+ errCode = cx231xx_enable_i2c_for_tuner(dev, I2C_3);
+
+ return errCode;
+}
+EXPORT_SYMBOL_GPL(cx231xx_dev_init);
+
+void cx231xx_dev_uninit(struct cx231xx *dev)
+{
+ /* Un Initialize I2C bus */
+ cx231xx_i2c_unregister(&dev->i2c_bus[2]);
+ cx231xx_i2c_unregister(&dev->i2c_bus[1]);
+ cx231xx_i2c_unregister(&dev->i2c_bus[0]);
+}
+EXPORT_SYMBOL_GPL(cx231xx_dev_uninit);
+
+/*****************************************************************
+* G P I O related functions *
+******************************************************************/
+int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val,
+ u8 len, u8 request, u8 direction)
+{
+ int status = 0;
+ struct VENDOR_REQUEST_IN ven_req;
+
+ /* Set wValue */
+ ven_req.wValue = (u16) (gpio_bit >> 16 & 0xffff);
+
+ /* set request */
+ if (!request) {
+ if (direction)
+ ven_req.bRequest = VRT_GET_GPIO; /* 0x8 gpio */
+ else
+ ven_req.bRequest = VRT_SET_GPIO; /* 0x9 gpio */
+ } else {
+ if (direction)
+ ven_req.bRequest = VRT_GET_GPIE; /* 0xa gpie */
+ else
+ ven_req.bRequest = VRT_SET_GPIE; /* 0xb gpie */
+ }
+
+ /* set index value */
+ ven_req.wIndex = (u16) (gpio_bit & 0xffff);
+
+ /* set wLength value */
+ ven_req.wLength = len;
+
+ /* set bData value */
+ ven_req.bData = 0;
+
+ /* set the buffer for read / write */
+ ven_req.pBuff = gpio_val;
+
+ /* set the direction */
+ if (direction) {
+ ven_req.direction = USB_DIR_IN;
+ memset(ven_req.pBuff, 0x00, ven_req.wLength);
+ } else
+ ven_req.direction = USB_DIR_OUT;
+
+
+ /* call common vendor command request */
+ status = cx231xx_send_vendor_cmd(dev, &ven_req);
+ if (status < 0) {
+ cx231xx_info
+ ("UsbInterface::sendCommand, failed with status -%d\n",
+ status);
+ }
+
+ return status;
+}
+EXPORT_SYMBOL_GPL(cx231xx_send_gpio_cmd);
+
+/*****************************************************************
+ * C O N T R O L - Register R E A D / W R I T E functions *
+ *****************************************************************/
+int cx231xx_mode_register(struct cx231xx *dev, u16 address, u32 mode)
+{
+ u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
+ u32 tmp = 0;
+ int status = 0;
+
+ status =
+ cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, address, value, 4);
+ if (status < 0)
+ return status;
+
+ tmp = *((u32 *) value);
+ tmp |= mode;
+
+ value[0] = (u8) tmp;
+ value[1] = (u8) (tmp >> 8);
+ value[2] = (u8) (tmp >> 16);
+ value[3] = (u8) (tmp >> 24);
+
+ status =
+ cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, address, value, 4);
+
+ return status;
+}
+
+/*****************************************************************
+ * I 2 C Internal C O N T R O L functions *
+ *****************************************************************/
+int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr,
+ u8 saddr_len, u32 *data, u8 data_len)
+{
+ int status = 0;
+ struct cx231xx_i2c_xfer_data req_data;
+ u8 value[4] = { 0, 0, 0, 0 };
+
+ if (saddr_len == 0)
+ saddr = 0;
+ else if (saddr_len == 0)
+ saddr &= 0xff;
+
+ /* prepare xfer_data struct */
+ req_data.dev_addr = dev_addr >> 1;
+ req_data.direction = I2C_M_RD;
+ req_data.saddr_len = saddr_len;
+ req_data.saddr_dat = saddr;
+ req_data.buf_size = data_len;
+ req_data.p_buffer = (u8 *) value;
+
+ /* usb send command */
+ status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0], &req_data);
+
+ if (status >= 0) {
+ /* Copy the data read back to main buffer */
+ if (data_len == 1)
+ *data = value[0];
+ else
+ *data =
+ value[0] | value[1] << 8 | value[2] << 16 | value[3]
+ << 24;
+ }
+
+ return status;
+}
+
+int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr,
+ u8 saddr_len, u32 data, u8 data_len)
+{
+ int status = 0;
+ u8 value[4] = { 0, 0, 0, 0 };
+ struct cx231xx_i2c_xfer_data req_data;
+
+ value[0] = (u8) data;
+ value[1] = (u8) (data >> 8);
+ value[2] = (u8) (data >> 16);
+ value[3] = (u8) (data >> 24);
+
+ if (saddr_len == 0)
+ saddr = 0;
+ else if (saddr_len == 0)
+ saddr &= 0xff;
+
+ /* prepare xfer_data struct */
+ req_data.dev_addr = dev_addr >> 1;
+ req_data.direction = 0;
+ req_data.saddr_len = saddr_len;
+ req_data.saddr_dat = saddr;
+ req_data.buf_size = data_len;
+ req_data.p_buffer = value;
+
+ /* usb send command */
+ status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0], &req_data);
+
+ return status;
+}
+
+int cx231xx_reg_mask_write(struct cx231xx *dev, u8 dev_addr, u8 size,
+ u16 register_address, u8 bit_start, u8 bit_end,
+ u32 value)
+{
+ int status = 0;
+ u32 tmp;
+ u32 mask = 0;
+ int i;
+
+ if (bit_start > (size - 1) || bit_end > (size - 1))
+ return -1;
+
+ if (size == 8) {
+ status =
+ cx231xx_read_i2c_data(dev, dev_addr, register_address, 2,
+ &tmp, 1);
+ } else {
+ status =
+ cx231xx_read_i2c_data(dev, dev_addr, register_address, 2,
+ &tmp, 4);
+ }
+
+ if (status < 0)
+ return status;
+
+ mask = 1 << bit_end;
+ for (i = bit_end; i > bit_start && i > 0; i--)
+ mask = mask + (1 << (i - 1));
+
+ value <<= bit_start;
+
+ if (size == 8) {
+ tmp &= ~mask;
+ tmp |= value;
+ tmp &= 0xff;
+ status =
+ cx231xx_write_i2c_data(dev, dev_addr, register_address, 2,
+ tmp, 1);
+ } else {
+ tmp &= ~mask;
+ tmp |= value;
+ status =
+ cx231xx_write_i2c_data(dev, dev_addr, register_address, 2,
+ tmp, 4);
+ }
+
+ return status;
+}
+
+int cx231xx_read_modify_write_i2c_dword(struct cx231xx *dev, u8 dev_addr,
+ u16 saddr, u32 mask, u32 value)
+{
+ u32 temp;
+ int status = 0;
+
+ status = cx231xx_read_i2c_data(dev, dev_addr, saddr, 2, &temp, 4);
+
+ if (status < 0)
+ return status;
+
+ temp &= ~mask;
+ temp |= value;
+
+ status = cx231xx_write_i2c_data(dev, dev_addr, saddr, 2, temp, 4);
+
+ return status;
+}
+
+u32 cx231xx_set_field(u32 field_mask, u32 data)
+{
+ u32 temp;
+
+ for (temp = field_mask; (temp & 1) == 0; temp >>= 1)
+ data <<= 1;
+
+ return data;
+}
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c
new file mode 100644
index 00000000000..c5082a4e8ce
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-dvb.c
@@ -0,0 +1,559 @@
+/*
+ DVB device driver for cx231xx
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+ Based on em28xx driver
+
+ 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/kernel.h>
+#include <linux/usb.h>
+
+#include "cx231xx.h"
+#include <media/v4l2-common.h>
+#include <media/videobuf-vmalloc.h>
+
+#include "xc5000.h"
+#include "dvb_dummy_fe.h"
+
+MODULE_DESCRIPTION("driver for cx231xx based DVB cards");
+MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
+MODULE_LICENSE("GPL");
+
+static unsigned int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debug messages [dvb]");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define dprintk(level, fmt, arg...) do { \
+if (debug >= level) \
+ printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \
+} while (0)
+
+#define CX231XX_DVB_NUM_BUFS 5
+#define CX231XX_DVB_MAX_PACKETSIZE 564
+#define CX231XX_DVB_MAX_PACKETS 64
+
+struct cx231xx_dvb {
+ struct dvb_frontend *frontend;
+
+ /* feed count management */
+ struct mutex lock;
+ int nfeeds;
+
+ /* general boilerplate stuff */
+ struct dvb_adapter adapter;
+ struct dvb_demux demux;
+ struct dmxdev dmxdev;
+ struct dmx_frontend fe_hw;
+ struct dmx_frontend fe_mem;
+ struct dvb_net net;
+};
+
+static inline void print_err_status(struct cx231xx *dev, int packet, int status)
+{
+ char *errmsg = "Unknown";
+
+ switch (status) {
+ case -ENOENT:
+ errmsg = "unlinked synchronuously";
+ break;
+ case -ECONNRESET:
+ errmsg = "unlinked asynchronuously";
+ break;
+ case -ENOSR:
+ errmsg = "Buffer error (overrun)";
+ break;
+ case -EPIPE:
+ errmsg = "Stalled (device not responding)";
+ break;
+ case -EOVERFLOW:
+ errmsg = "Babble (bad cable?)";
+ break;
+ case -EPROTO:
+ errmsg = "Bit-stuff error (bad cable?)";
+ break;
+ case -EILSEQ:
+ errmsg = "CRC/Timeout (could be anything)";
+ break;
+ case -ETIME:
+ errmsg = "Device does not respond";
+ break;
+ }
+ if (packet < 0) {
+ dprintk(1, "URB status %d [%s].\n", status, errmsg);
+ } else {
+ dprintk(1, "URB packet %d, status %d [%s].\n",
+ packet, status, errmsg);
+ }
+}
+
+static inline int dvb_isoc_copy(struct cx231xx *dev, struct urb *urb)
+{
+ int i;
+
+ if (!dev)
+ return 0;
+
+ if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
+ return 0;
+
+ if (urb->status < 0) {
+ print_err_status(dev, -1, urb->status);
+ if (urb->status == -ENOENT)
+ return 0;
+ }
+
+ for (i = 0; i < urb->number_of_packets; i++) {
+ int status = urb->iso_frame_desc[i].status;
+
+ if (status < 0) {
+ print_err_status(dev, i, status);
+ if (urb->iso_frame_desc[i].status != -EPROTO)
+ continue;
+ }
+
+ dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer +
+ urb->iso_frame_desc[i].offset,
+ urb->iso_frame_desc[i].actual_length);
+ }
+
+ return 0;
+}
+
+static int start_streaming(struct cx231xx_dvb *dvb)
+{
+ int rc;
+ struct cx231xx *dev = dvb->adapter.priv;
+
+ usb_set_interface(dev->udev, 0, 1);
+ rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
+ if (rc < 0)
+ return rc;
+
+ return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS,
+ CX231XX_DVB_NUM_BUFS,
+ CX231XX_DVB_MAX_PACKETSIZE, dvb_isoc_copy);
+}
+
+static int stop_streaming(struct cx231xx_dvb *dvb)
+{
+ struct cx231xx *dev = dvb->adapter.priv;
+
+ cx231xx_uninit_isoc(dev);
+
+ cx231xx_set_mode(dev, CX231XX_SUSPEND);
+
+ return 0;
+}
+
+static int start_feed(struct dvb_demux_feed *feed)
+{
+ struct dvb_demux *demux = feed->demux;
+ struct cx231xx_dvb *dvb = demux->priv;
+ int rc, ret;
+
+ if (!demux->dmx.frontend)
+ return -EINVAL;
+
+ mutex_lock(&dvb->lock);
+ dvb->nfeeds++;
+ rc = dvb->nfeeds;
+
+ if (dvb->nfeeds == 1) {
+ ret = start_streaming(dvb);
+ if (ret < 0)
+ rc = ret;
+ }
+
+ mutex_unlock(&dvb->lock);
+ return rc;
+}
+
+static int stop_feed(struct dvb_demux_feed *feed)
+{
+ struct dvb_demux *demux = feed->demux;
+ struct cx231xx_dvb *dvb = demux->priv;
+ int err = 0;
+
+ mutex_lock(&dvb->lock);
+ dvb->nfeeds--;
+
+ if (0 == dvb->nfeeds)
+ err = stop_streaming(dvb);
+
+ mutex_unlock(&dvb->lock);
+ return err;
+}
+
+/* ------------------------------------------------------------------ */
+static int cx231xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
+{
+ struct cx231xx *dev = fe->dvb->priv;
+
+ if (acquire)
+ return cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
+ else
+ return cx231xx_set_mode(dev, CX231XX_SUSPEND);
+}
+
+/* ------------------------------------------------------------------ */
+
+static struct xc5000_config cnxt_rde250_tunerconfig = {
+ .i2c_address = 0x61,
+ .if_khz = 5380,
+};
+
+/* ------------------------------------------------------------------ */
+#if 0
+static int attach_xc5000(u8 addr, struct cx231xx *dev)
+{
+
+ struct dvb_frontend *fe;
+ struct xc5000_config cfg;
+
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.i2c_adap = &dev->i2c_bus[1].i2c_adap;
+ cfg.i2c_addr = addr;
+
+ if (!dev->dvb->frontend) {
+ printk(KERN_ERR "%s/2: dvb frontend not attached. "
+ "Can't attach xc5000\n", dev->name);
+ return -EINVAL;
+ }
+
+ fe = dvb_attach(xc5000_attach, dev->dvb->frontend, &cfg);
+ if (!fe) {
+ printk(KERN_ERR "%s/2: xc5000 attach failed\n", dev->name);
+ dvb_frontend_detach(dev->dvb->frontend);
+ dev->dvb->frontend = NULL;
+ return -EINVAL;
+ }
+
+ printk(KERN_INFO "%s/2: xc5000 attached\n", dev->name);
+
+ return 0;
+}
+#endif
+
+int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq)
+{
+ int status = 0;
+
+ if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {
+
+ struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;
+
+ if (dops->set_analog_params != NULL) {
+ struct analog_parameters params;
+
+ params.frequency = freq;
+ params.std = dev->norm;
+ params.mode = 0; /* 0- Air; 1 - cable */
+ /*params.audmode = ; */
+
+ /* Set the analog parameters to set the frequency */
+ cx231xx_info("Setting Frequency for XC5000\n");
+ dops->set_analog_params(dev->dvb->frontend, &params);
+ }
+
+ }
+
+ return status;
+}
+
+int cx231xx_reset_analog_tuner(struct cx231xx *dev)
+{
+ int status = 0;
+
+ if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {
+
+ struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;
+
+ if (dops->init != NULL && !dev->xc_fw_load_done) {
+
+ cx231xx_info("Reloading firmware for XC5000\n");
+ status = dops->init(dev->dvb->frontend);
+ if (status == 0) {
+ dev->xc_fw_load_done = 1;
+ cx231xx_info
+ ("XC5000 firmware download completed\n");
+ } else {
+ dev->xc_fw_load_done = 0;
+ cx231xx_info
+ ("XC5000 firmware download failed !!!\n");
+ }
+ }
+
+ }
+
+ return status;
+}
+
+/* ------------------------------------------------------------------ */
+
+static int register_dvb(struct cx231xx_dvb *dvb,
+ struct module *module,
+ struct cx231xx *dev, struct device *device)
+{
+ int result;
+
+ mutex_init(&dvb->lock);
+
+ /* register adapter */
+ result = dvb_register_adapter(&dvb->adapter, dev->name, module, device,
+ adapter_nr);
+ if (result < 0) {
+ printk(KERN_WARNING
+ "%s: dvb_register_adapter failed (errno = %d)\n",
+ dev->name, result);
+ goto fail_adapter;
+ }
+
+ /* Ensure all frontends negotiate bus access */
+ dvb->frontend->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl;
+
+ dvb->adapter.priv = dev;
+
+ /* register frontend */
+ result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
+ if (result < 0) {
+ printk(KERN_WARNING
+ "%s: dvb_register_frontend failed (errno = %d)\n",
+ dev->name, result);
+ goto fail_frontend;
+ }
+
+ /* register demux stuff */
+ dvb->demux.dmx.capabilities =
+ DMX_TS_FILTERING | DMX_SECTION_FILTERING |
+ DMX_MEMORY_BASED_FILTERING;
+ dvb->demux.priv = dvb;
+ dvb->demux.filternum = 256;
+ dvb->demux.feednum = 256;
+ dvb->demux.start_feed = start_feed;
+ dvb->demux.stop_feed = stop_feed;
+
+ result = dvb_dmx_init(&dvb->demux);
+ if (result < 0) {
+ printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n",
+ dev->name, result);
+ goto fail_dmx;
+ }
+
+ dvb->dmxdev.filternum = 256;
+ dvb->dmxdev.demux = &dvb->demux.dmx;
+ dvb->dmxdev.capabilities = 0;
+ result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
+ if (result < 0) {
+ printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
+ dev->name, result);
+ goto fail_dmxdev;
+ }
+
+ dvb->fe_hw.source = DMX_FRONTEND_0;
+ result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+ if (result < 0) {
+ printk(KERN_WARNING
+ "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
+ dev->name, result);
+ goto fail_fe_hw;
+ }
+
+ dvb->fe_mem.source = DMX_MEMORY_FE;
+ result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
+ if (result < 0) {
+ printk(KERN_WARNING
+ "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
+ dev->name, result);
+ goto fail_fe_mem;
+ }
+
+ result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+ if (result < 0) {
+ printk(KERN_WARNING
+ "%s: connect_frontend failed (errno = %d)\n", dev->name,
+ result);
+ goto fail_fe_conn;
+ }
+
+ /* register network adapter */
+ dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
+ return 0;
+
+fail_fe_conn:
+ dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
+fail_fe_mem:
+ dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+fail_fe_hw:
+ dvb_dmxdev_release(&dvb->dmxdev);
+fail_dmxdev:
+ dvb_dmx_release(&dvb->demux);
+fail_dmx:
+ dvb_unregister_frontend(dvb->frontend);
+fail_frontend:
+ dvb_frontend_detach(dvb->frontend);
+ dvb_unregister_adapter(&dvb->adapter);
+fail_adapter:
+ return result;
+}
+
+static void unregister_dvb(struct cx231xx_dvb *dvb)
+{
+ 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);
+}
+
+static int dvb_init(struct cx231xx *dev)
+{
+ int result = 0;
+ struct cx231xx_dvb *dvb;
+
+ if (!dev->board.has_dvb) {
+ /* This device does not support the extension */
+ return 0;
+ }
+
+ dvb = kzalloc(sizeof(struct cx231xx_dvb), GFP_KERNEL);
+
+ if (dvb == NULL) {
+ printk(KERN_INFO "cx231xx_dvb: memory allocation failed\n");
+ return -ENOMEM;
+ }
+ dev->dvb = dvb;
+ dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq;
+ dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner;
+
+ cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
+ /* init frontend */
+ switch (dev->model) {
+ case CX231XX_BOARD_CNXT_RDE_250:
+
+ /* dev->dvb->frontend = dvb_attach(s5h1411_attach,
+ &dvico_s5h1411_config,
+ &dev->i2c_bus[1].i2c_adap); */
+ dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach);
+
+ if (dev->dvb->frontend == NULL) {
+ printk(DRIVER_NAME
+ ": Failed to attach dummy front end\n");
+ result = -EINVAL;
+ goto out_free;
+ }
+
+ /* define general-purpose callback pointer */
+ dvb->frontend->callback = cx231xx_tuner_callback;
+
+ if (dvb_attach(xc5000_attach, dev->dvb->frontend,
+ &dev->i2c_bus[1].i2c_adap,
+ &cnxt_rde250_tunerconfig) < 0) {
+ result = -EINVAL;
+ goto out_free;
+ }
+
+ break;
+ case CX231XX_BOARD_CNXT_RDU_250:
+
+ dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach);
+
+ if (dev->dvb->frontend == NULL) {
+ printk(DRIVER_NAME
+ ": Failed to attach dummy front end\n");
+ result = -EINVAL;
+ goto out_free;
+ }
+
+ /* define general-purpose callback pointer */
+ dvb->frontend->callback = cx231xx_tuner_callback;
+
+ if (dvb_attach(xc5000_attach, dev->dvb->frontend,
+ &dev->i2c_bus[1].i2c_adap,
+ &cnxt_rde250_tunerconfig) < 0) {
+ result = -EINVAL;
+ goto out_free;
+ }
+ break;
+
+ default:
+ printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
+ " isn't supported yet\n", dev->name);
+ break;
+ }
+ if (NULL == dvb->frontend) {
+ printk(KERN_ERR
+ "%s/2: frontend initialization failed\n", dev->name);
+ result = -EINVAL;
+ goto out_free;
+ }
+
+ /* register everything */
+ result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
+
+ if (result < 0)
+ goto out_free;
+
+ cx231xx_set_mode(dev, CX231XX_SUSPEND);
+ printk(KERN_INFO "Successfully loaded cx231xx-dvb\n");
+ return 0;
+
+out_free:
+ cx231xx_set_mode(dev, CX231XX_SUSPEND);
+ kfree(dvb);
+ dev->dvb = NULL;
+ return result;
+}
+
+static int dvb_fini(struct cx231xx *dev)
+{
+ if (!dev->board.has_dvb) {
+ /* This device does not support the extension */
+ return 0;
+ }
+
+ if (dev->dvb) {
+ unregister_dvb(dev->dvb);
+ dev->dvb = NULL;
+ }
+
+ return 0;
+}
+
+static struct cx231xx_ops dvb_ops = {
+ .id = CX231XX_DVB,
+ .name = "Cx231xx dvb Extension",
+ .init = dvb_init,
+ .fini = dvb_fini,
+};
+
+static int __init cx231xx_dvb_register(void)
+{
+ return cx231xx_register_extension(&dvb_ops);
+}
+
+static void __exit cx231xx_dvb_unregister(void)
+{
+ cx231xx_unregister_extension(&dvb_ops);
+}
+
+module_init(cx231xx_dvb_register);
+module_exit(cx231xx_dvb_unregister);
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c
new file mode 100644
index 00000000000..b4a03d813e0
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-i2c.c
@@ -0,0 +1,555 @@
+/*
+ cx231xx-i2c.c - driver for Conexant Cx23100/101/102 USB video capture devices
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+ Based on em28xx driver
+ Based on Cx23885 driver
+
+ 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/module.h>
+#include <linux/kernel.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <media/v4l2-common.h>
+#include <media/tuner.h>
+
+#include "cx231xx.h"
+
+/* ----------------------------------------------------------- */
+
+static unsigned int i2c_scan;
+module_param(i2c_scan, int, 0444);
+MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
+
+static unsigned int i2c_debug;
+module_param(i2c_debug, int, 0644);
+MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
+
+#define dprintk1(lvl, fmt, args...) \
+do { \
+ if (i2c_debug >= lvl) { \
+ printk(fmt, ##args); \
+ } \
+} while (0)
+
+#define dprintk2(lvl, fmt, args...) \
+do { \
+ if (i2c_debug >= lvl) { \
+ printk(KERN_DEBUG "%s at %s: " fmt, \
+ dev->name, __func__ , ##args); \
+ } \
+} while (0)
+
+/*
+ * cx231xx_i2c_send_bytes()
+ */
+int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap,
+ const struct i2c_msg *msg)
+{
+ struct cx231xx_i2c *bus = i2c_adap->algo_data;
+ struct cx231xx *dev = bus->dev;
+ struct cx231xx_i2c_xfer_data req_data;
+ int status = 0;
+ u16 size = 0;
+ u8 loop = 0;
+ u8 saddr_len = 1;
+ u8 *buf_ptr = NULL;
+ u16 saddr = 0;
+ u8 need_gpio = 0;
+
+ if ((bus->nr == 1) && (msg->addr == 0x61)
+ && (dev->tuner_type == TUNER_XC5000)) {
+
+ size = msg->len;
+
+ if (size == 2) { /* register write sub addr */
+ /* Just writing sub address will cause problem
+ * to XC5000. So ignore the request */
+ return 0;
+ } else if (size == 4) { /* register write with sub addr */
+ if (msg->len >= 2)
+ saddr = msg->buf[0] << 8 | msg->buf[1];
+ else if (msg->len == 1)
+ saddr = msg->buf[0];
+
+ switch (saddr) {
+ case 0x0000: /* start tuner calibration mode */
+ need_gpio = 1;
+ /* FW Loading is done */
+ dev->xc_fw_load_done = 1;
+ break;
+ case 0x000D: /* Set signal source */
+ case 0x0001: /* Set TV standard - Video */
+ case 0x0002: /* Set TV standard - Audio */
+ case 0x0003: /* Set RF Frequency */
+ need_gpio = 1;
+ break;
+ default:
+ if (dev->xc_fw_load_done)
+ need_gpio = 1;
+ break;
+ }
+
+ if (need_gpio) {
+ dprintk1(1,
+ "GPIO WRITE: addr 0x%x, len %d, saddr 0x%x\n",
+ msg->addr, msg->len, saddr);
+
+ return dev->cx231xx_gpio_i2c_write(dev,
+ msg->addr,
+ msg->buf,
+ msg->len);
+ }
+ }
+
+ /* special case for Xc5000 tuner case */
+ saddr_len = 1;
+
+ /* adjust the length to correct length */
+ size -= saddr_len;
+ buf_ptr = (u8 *) (msg->buf + 1);
+
+ do {
+ /* prepare xfer_data struct */
+ req_data.dev_addr = msg->addr;
+ req_data.direction = msg->flags;
+ req_data.saddr_len = saddr_len;
+ req_data.saddr_dat = msg->buf[0];
+ req_data.buf_size = size > 16 ? 16 : size;
+ req_data.p_buffer = (u8 *) (buf_ptr + loop * 16);
+
+ bus->i2c_nostop = (size > 16) ? 1 : 0;
+ bus->i2c_reserve = (loop == 0) ? 0 : 1;
+
+ /* usb send command */
+ status = dev->cx231xx_send_usb_command(bus, &req_data);
+ loop++;
+
+ if (size >= 16)
+ size -= 16;
+ else
+ size = 0;
+
+ } while (size > 0);
+
+ bus->i2c_nostop = 0;
+ bus->i2c_reserve = 0;
+
+ } else { /* regular case */
+
+ /* prepare xfer_data struct */
+ req_data.dev_addr = msg->addr;
+ req_data.direction = msg->flags;
+ req_data.saddr_len = 0;
+ req_data.saddr_dat = 0;
+ req_data.buf_size = msg->len;
+ req_data.p_buffer = msg->buf;
+
+ /* usb send command */
+ status = dev->cx231xx_send_usb_command(bus, &req_data);
+ }
+
+ return status < 0 ? status : 0;
+}
+
+/*
+ * cx231xx_i2c_recv_bytes()
+ * read a byte from the i2c device
+ */
+static int cx231xx_i2c_recv_bytes(struct i2c_adapter *i2c_adap,
+ const struct i2c_msg *msg)
+{
+ struct cx231xx_i2c *bus = i2c_adap->algo_data;
+ struct cx231xx *dev = bus->dev;
+ struct cx231xx_i2c_xfer_data req_data;
+ int status = 0;
+ u16 saddr = 0;
+ u8 need_gpio = 0;
+
+ if ((bus->nr == 1) && (msg->addr == 0x61)
+ && dev->tuner_type == TUNER_XC5000) {
+
+ if (msg->len == 2)
+ saddr = msg->buf[0] << 8 | msg->buf[1];
+ else if (msg->len == 1)
+ saddr = msg->buf[0];
+
+ if (dev->xc_fw_load_done) {
+
+ switch (saddr) {
+ case 0x0009: /* BUSY check */
+ dprintk1(1,
+ "GPIO R E A D: Special case BUSY check \n");
+ /*Try read BUSY register, just set it to zero*/
+ msg->buf[0] = 0;
+ if (msg->len == 2)
+ msg->buf[1] = 0;
+ return 0;
+ case 0x0004: /* read Lock status */
+ need_gpio = 1;
+ break;
+
+ }
+
+ if (need_gpio) {
+ /* this is a special case to handle Xceive tuner
+ clock stretch issue with gpio based I2C */
+
+ dprintk1(1,
+ "GPIO R E A D: addr 0x%x, len %d, saddr 0x%x\n",
+ msg->addr, msg->len,
+ msg->buf[0] << 8 | msg->buf[1]);
+
+ status =
+ dev->cx231xx_gpio_i2c_write(dev, msg->addr,
+ msg->buf,
+ msg->len);
+ status =
+ dev->cx231xx_gpio_i2c_read(dev, msg->addr,
+ msg->buf,
+ msg->len);
+ return status;
+ }
+ }
+
+ /* prepare xfer_data struct */
+ req_data.dev_addr = msg->addr;
+ req_data.direction = msg->flags;
+ req_data.saddr_len = msg->len;
+ req_data.saddr_dat = msg->buf[0] << 8 | msg->buf[1];
+ req_data.buf_size = msg->len;
+ req_data.p_buffer = msg->buf;
+
+ /* usb send command */
+ status = dev->cx231xx_send_usb_command(bus, &req_data);
+
+ } else {
+
+ /* prepare xfer_data struct */
+ req_data.dev_addr = msg->addr;
+ req_data.direction = msg->flags;
+ req_data.saddr_len = 0;
+ req_data.saddr_dat = 0;
+ req_data.buf_size = msg->len;
+ req_data.p_buffer = msg->buf;
+
+ /* usb send command */
+ status = dev->cx231xx_send_usb_command(bus, &req_data);
+ }
+
+ return status < 0 ? status : 0;
+}
+
+/*
+ * cx231xx_i2c_recv_bytes_with_saddr()
+ * read a byte from the i2c device
+ */
+static int cx231xx_i2c_recv_bytes_with_saddr(struct i2c_adapter *i2c_adap,
+ const struct i2c_msg *msg1,
+ const struct i2c_msg *msg2)
+{
+ struct cx231xx_i2c *bus = i2c_adap->algo_data;
+ struct cx231xx *dev = bus->dev;
+ struct cx231xx_i2c_xfer_data req_data;
+ int status = 0;
+ u16 saddr = 0;
+ u8 need_gpio = 0;
+
+ if (msg1->len == 2)
+ saddr = msg1->buf[0] << 8 | msg1->buf[1];
+ else if (msg1->len == 1)
+ saddr = msg1->buf[0];
+
+ if ((bus->nr == 1) && (msg2->addr == 0x61)
+ && dev->tuner_type == TUNER_XC5000) {
+
+ if ((msg2->len < 16)) {
+
+ dprintk1(1,
+ "i2c_read: addr 0x%x, len %d, saddr 0x%x, len %d\n",
+ msg2->addr, msg2->len, saddr, msg1->len);
+
+ switch (saddr) {
+ case 0x0008: /* read FW load status */
+ need_gpio = 1;
+ break;
+ case 0x0004: /* read Lock status */
+ need_gpio = 1;
+ break;
+ }
+
+ if (need_gpio) {
+ status =
+ dev->cx231xx_gpio_i2c_write(dev, msg1->addr,
+ msg1->buf,
+ msg1->len);
+ status =
+ dev->cx231xx_gpio_i2c_read(dev, msg2->addr,
+ msg2->buf,
+ msg2->len);
+ return status;
+ }
+ }
+ }
+
+ /* prepare xfer_data struct */
+ req_data.dev_addr = msg2->addr;
+ req_data.direction = msg2->flags;
+ req_data.saddr_len = msg1->len;
+ req_data.saddr_dat = saddr;
+ req_data.buf_size = msg2->len;
+ req_data.p_buffer = msg2->buf;
+
+ /* usb send command */
+ status = dev->cx231xx_send_usb_command(bus, &req_data);
+
+ return status < 0 ? status : 0;
+}
+
+/*
+ * cx231xx_i2c_check_for_device()
+ * check if there is a i2c_device at the supplied address
+ */
+static int cx231xx_i2c_check_for_device(struct i2c_adapter *i2c_adap,
+ const struct i2c_msg *msg)
+{
+ struct cx231xx_i2c *bus = i2c_adap->algo_data;
+ struct cx231xx *dev = bus->dev;
+ struct cx231xx_i2c_xfer_data req_data;
+ int status = 0;
+
+ /* prepare xfer_data struct */
+ req_data.dev_addr = msg->addr;
+ req_data.direction = msg->flags;
+ req_data.saddr_len = 0;
+ req_data.saddr_dat = 0;
+ req_data.buf_size = 0;
+ req_data.p_buffer = NULL;
+
+ /* usb send command */
+ status = dev->cx231xx_send_usb_command(bus, &req_data);
+
+ return status < 0 ? status : 0;
+}
+
+/*
+ * cx231xx_i2c_xfer()
+ * the main i2c transfer function
+ */
+static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap,
+ struct i2c_msg msgs[], int num)
+{
+ struct cx231xx_i2c *bus = i2c_adap->algo_data;
+ struct cx231xx *dev = bus->dev;
+ int addr, rc, i, byte;
+
+ if (num <= 0)
+ return 0;
+
+ for (i = 0; i < num; i++) {
+
+ addr = msgs[i].addr >> 1;
+
+ dprintk2(2, "%s %s addr=%x len=%d:",
+ (msgs[i].flags & I2C_M_RD) ? "read" : "write",
+ i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
+ if (!msgs[i].len) {
+ /* no len: check only for device presence */
+ rc = cx231xx_i2c_check_for_device(i2c_adap, &msgs[i]);
+ if (rc < 0) {
+ dprintk2(2, " no device\n");
+ return rc;
+ }
+
+ } else if (msgs[i].flags & I2C_M_RD) {
+ /* read bytes */
+ rc = cx231xx_i2c_recv_bytes(i2c_adap, &msgs[i]);
+ if (i2c_debug >= 2) {
+ for (byte = 0; byte < msgs[i].len; byte++)
+ printk(" %02x", msgs[i].buf[byte]);
+ }
+ } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
+ msgs[i].addr == msgs[i + 1].addr
+ && (msgs[i].len <= 2) && (bus->nr < 2)) {
+ /* read bytes */
+ rc = cx231xx_i2c_recv_bytes_with_saddr(i2c_adap,
+ &msgs[i],
+ &msgs[i + 1]);
+ if (i2c_debug >= 2) {
+ for (byte = 0; byte < msgs[i].len; byte++)
+ printk(" %02x", msgs[i].buf[byte]);
+ }
+ i++;
+ } else {
+ /* write bytes */
+ if (i2c_debug >= 2) {
+ for (byte = 0; byte < msgs[i].len; byte++)
+ printk(" %02x", msgs[i].buf[byte]);
+ }
+ rc = cx231xx_i2c_send_bytes(i2c_adap, &msgs[i]);
+ }
+ if (rc < 0)
+ goto err;
+ if (i2c_debug >= 2)
+ printk("\n");
+ }
+
+ return num;
+err:
+ dprintk2(2, " ERROR: %i\n", rc);
+ return rc;
+}
+
+/* ----------------------------------------------------------- */
+
+/*
+ * functionality()
+ */
+static u32 functionality(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
+}
+
+/*
+ * attach_inform()
+ * gets called when a device attaches to the i2c bus
+ * does some basic configuration
+ */
+static int attach_inform(struct i2c_client *client)
+{
+ struct cx231xx_i2c *bus = i2c_get_adapdata(client->adapter);
+ struct cx231xx *dev = bus->dev;
+
+ switch (client->addr << 1) {
+ case 0x8e:
+ {
+ struct IR_i2c *ir = i2c_get_clientdata(client);
+ dprintk1(1, "attach_inform: IR detected (%s).\n",
+ ir->phys);
+ cx231xx_set_ir(dev, ir);
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static struct i2c_algorithm cx231xx_algo = {
+ .master_xfer = cx231xx_i2c_xfer,
+ .functionality = functionality,
+};
+
+static struct i2c_adapter cx231xx_adap_template = {
+ .owner = THIS_MODULE,
+ .name = "cx231xx",
+ .id = I2C_HW_B_CX231XX,
+ .algo = &cx231xx_algo,
+ .client_register = attach_inform,
+};
+
+static struct i2c_client cx231xx_client_template = {
+ .name = "cx231xx internal",
+};
+
+/* ----------------------------------------------------------- */
+
+/*
+ * i2c_devs
+ * incomplete list of known devices
+ */
+static char *i2c_devs[128] = {
+ [0x60 >> 1] = "colibri",
+ [0x88 >> 1] = "hammerhead",
+ [0x8e >> 1] = "CIR",
+ [0x32 >> 1] = "GeminiIII",
+ [0x02 >> 1] = "Aquarius",
+ [0xa0 >> 1] = "eeprom",
+ [0xc0 >> 1] = "tuner/XC3028",
+ [0xc2 >> 1] = "tuner/XC5000",
+};
+
+/*
+ * cx231xx_do_i2c_scan()
+ * check i2c address range for devices
+ */
+void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c)
+{
+ unsigned char buf;
+ int i, rc;
+
+ cx231xx_info(": Checking for I2C devices ..\n");
+ for (i = 0; i < 128; i++) {
+ c->addr = i;
+ rc = i2c_master_recv(c, &buf, 0);
+ if (rc < 0)
+ continue;
+ cx231xx_info("%s: i2c scan: found device @ 0x%x [%s]\n",
+ dev->name, i << 1,
+ i2c_devs[i] ? i2c_devs[i] : "???");
+ }
+ cx231xx_info(": Completed Checking for I2C devices.\n");
+}
+
+/*
+ * cx231xx_i2c_register()
+ * register i2c bus
+ */
+int cx231xx_i2c_register(struct cx231xx_i2c *bus)
+{
+ struct cx231xx *dev = bus->dev;
+
+ BUG_ON(!dev->cx231xx_send_usb_command);
+
+ memcpy(&bus->i2c_adap, &cx231xx_adap_template, sizeof(bus->i2c_adap));
+ memcpy(&bus->i2c_algo, &cx231xx_algo, sizeof(bus->i2c_algo));
+ memcpy(&bus->i2c_client, &cx231xx_client_template,
+ sizeof(bus->i2c_client));
+
+ bus->i2c_adap.dev.parent = &dev->udev->dev;
+
+ strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
+
+ bus->i2c_algo.data = bus;
+ bus->i2c_adap.algo_data = bus;
+ i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
+ i2c_add_adapter(&bus->i2c_adap);
+
+ bus->i2c_client.adapter = &bus->i2c_adap;
+
+ if (0 == bus->i2c_rc) {
+ if (i2c_scan)
+ cx231xx_do_i2c_scan(dev, &bus->i2c_client);
+ } else
+ cx231xx_warn("%s: i2c bus %d register FAILED\n",
+ dev->name, bus->nr);
+
+ return bus->i2c_rc;
+}
+
+/*
+ * cx231xx_i2c_unregister()
+ * unregister i2c_bus
+ */
+int cx231xx_i2c_unregister(struct cx231xx_i2c *bus)
+{
+ i2c_del_adapter(&bus->i2c_adap);
+ return 0;
+}
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c
new file mode 100644
index 00000000000..97e304c3c79
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-input.c
@@ -0,0 +1,246 @@
+/*
+ handle cx231xx IR remotes via linux kernel input layer.
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+ Based on em28xx driver
+
+ < This is a place holder for IR now.>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#include "cx231xx.h"
+
+static unsigned int ir_debug;
+module_param(ir_debug, int, 0644);
+MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
+
+#define i2cdprintk(fmt, arg...) \
+ if (ir_debug) { \
+ printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \
+ }
+
+#define dprintk(fmt, arg...) \
+ if (ir_debug) { \
+ printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
+ }
+
+/**********************************************************
+ Polling structure used by cx231xx IR's
+ **********************************************************/
+
+struct cx231xx_ir_poll_result {
+ unsigned int toggle_bit:1;
+ unsigned int read_count:7;
+ u8 rc_address;
+ u8 rc_data[4];
+};
+
+struct cx231xx_IR {
+ struct cx231xx *dev;
+ struct input_dev *input;
+ struct ir_input_state ir;
+ char name[32];
+ char phys[32];
+
+ /* poll external decoder */
+ int polling;
+ struct work_struct work;
+ struct timer_list timer;
+ unsigned int last_toggle:1;
+ unsigned int last_readcount;
+ unsigned int repeat_interval;
+
+ int (*get_key) (struct cx231xx_IR *, struct cx231xx_ir_poll_result *);
+};
+
+/**********************************************************
+ Polling code for cx231xx
+ **********************************************************/
+
+static void cx231xx_ir_handle_key(struct cx231xx_IR *ir)
+{
+ int result;
+ int do_sendkey = 0;
+ struct cx231xx_ir_poll_result poll_result;
+
+ /* read the registers containing the IR status */
+ result = ir->get_key(ir, &poll_result);
+ if (result < 0) {
+ dprintk("ir->get_key() failed %d\n", result);
+ return;
+ }
+
+ dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x\n",
+ poll_result.toggle_bit, poll_result.read_count,
+ ir->last_readcount, poll_result.rc_data[0]);
+
+ if (ir->dev->chip_id == CHIP_ID_EM2874) {
+ /* The em2874 clears the readcount field every time the
+ register is read. The em2860/2880 datasheet says that it
+ is supposed to clear the readcount, but it doesn't. So with
+ the em2874, we are looking for a non-zero read count as
+ opposed to a readcount that is incrementing */
+ ir->last_readcount = 0;
+ }
+
+ if (poll_result.read_count == 0) {
+ /* The button has not been pressed since the last read */
+ } else if (ir->last_toggle != poll_result.toggle_bit) {
+ /* A button has been pressed */
+ dprintk("button has been pressed\n");
+ ir->last_toggle = poll_result.toggle_bit;
+ ir->repeat_interval = 0;
+ do_sendkey = 1;
+ } else if (poll_result.toggle_bit == ir->last_toggle &&
+ poll_result.read_count > 0 &&
+ poll_result.read_count != ir->last_readcount) {
+ /* The button is still being held down */
+ dprintk("button being held down\n");
+
+ /* Debouncer for first keypress */
+ if (ir->repeat_interval++ > 9) {
+ /* Start repeating after 1 second */
+ do_sendkey = 1;
+ }
+ }
+
+ if (do_sendkey) {
+ dprintk("sending keypress\n");
+ ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0],
+ poll_result.rc_data[0]);
+ ir_input_nokey(ir->input, &ir->ir);
+ }
+
+ ir->last_readcount = poll_result.read_count;
+ return;
+}
+
+static void ir_timer(unsigned long data)
+{
+ struct cx231xx_IR *ir = (struct cx231xx_IR *)data;
+
+ schedule_work(&ir->work);
+}
+
+static void cx231xx_ir_work(struct work_struct *work)
+{
+ struct cx231xx_IR *ir = container_of(work, struct cx231xx_IR, work);
+
+ cx231xx_ir_handle_key(ir);
+ mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
+}
+
+void cx231xx_ir_start(struct cx231xx_IR *ir)
+{
+ setup_timer(&ir->timer, ir_timer, (unsigned long)ir);
+ INIT_WORK(&ir->work, cx231xx_ir_work);
+ schedule_work(&ir->work);
+}
+
+static void cx231xx_ir_stop(struct cx231xx_IR *ir)
+{
+ del_timer_sync(&ir->timer);
+ flush_scheduled_work();
+}
+
+int cx231xx_ir_init(struct cx231xx *dev)
+{
+ struct cx231xx_IR *ir;
+ struct input_dev *input_dev;
+ u8 ir_config;
+ int err = -ENOMEM;
+
+ if (dev->board.ir_codes == NULL) {
+ /* No remote control support */
+ return 0;
+ }
+
+ ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!ir || !input_dev)
+ goto err_out_free;
+
+ ir->input = input_dev;
+
+ /* Setup the proper handler based on the chip */
+ switch (dev->chip_id) {
+ default:
+ printk("Unrecognized cx231xx chip id: IR not supported\n");
+ goto err_out_free;
+ }
+
+ /* This is how often we ask the chip for IR information */
+ ir->polling = 100; /* ms */
+
+ /* init input device */
+ snprintf(ir->name, sizeof(ir->name), "cx231xx IR (%s)", dev->name);
+
+ usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
+ strlcat(ir->phys, "/input0", sizeof(ir->phys));
+
+ ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, dev->board.ir_codes);
+ input_dev->name = ir->name;
+ input_dev->phys = ir->phys;
+ input_dev->id.bustype = BUS_USB;
+ input_dev->id.version = 1;
+ input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+
+ input_dev->dev.parent = &dev->udev->dev;
+ /* record handles to ourself */
+ ir->dev = dev;
+ dev->ir = ir;
+
+ cx231xx_ir_start(ir);
+
+ /* all done */
+ err = input_register_device(ir->input);
+ if (err)
+ goto err_out_stop;
+
+ return 0;
+err_out_stop:
+ cx231xx_ir_stop(ir);
+ dev->ir = NULL;
+err_out_free:
+ input_free_device(input_dev);
+ kfree(ir);
+ return err;
+}
+
+int cx231xx_ir_fini(struct cx231xx *dev)
+{
+ struct cx231xx_IR *ir = dev->ir;
+
+ /* skip detach on non attached boards */
+ if (!ir)
+ return 0;
+
+ cx231xx_ir_stop(ir);
+ input_unregister_device(ir->input);
+ kfree(ir);
+
+ /* done */
+ dev->ir = NULL;
+ return 0;
+}
diff --git a/drivers/media/video/cx231xx/cx231xx-pcb-cfg.c b/drivers/media/video/cx231xx/cx231xx-pcb-cfg.c
new file mode 100644
index 00000000000..7473c33e823
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-pcb-cfg.c
@@ -0,0 +1,795 @@
+/*
+ cx231xx-pcb-config.c - driver for Conexant
+ Cx23100/101/102 USB video capture devices
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot 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 "cx231xx.h"
+#include "cx231xx-conf-reg.h"
+
+static unsigned int pcb_debug;
+module_param(pcb_debug, int, 0644);
+MODULE_PARM_DESC(pcb_debug, "enable pcb config debug messages [video]");
+
+/******************************************************************************/
+
+struct pcb_config cx231xx_Scenario[] = {
+ {
+ INDEX_SELFPOWER_DIGITAL_ONLY, /* index */
+ USB_SELF_POWER, /* power_type */
+ 0, /* speed , not decide yet */
+ MOD_DIGITAL, /* mode */
+ SOURCE_TS_BDA, /* ts1_source, digital tv only */
+ NOT_SUPPORTED, /* ts2_source */
+ NOT_SUPPORTED, /* analog source */
+
+ 0, /* digital_index */
+ 0, /* analog index */
+ 0, /* dif_index */
+ 0, /* external_index */
+
+ 1, /* only one configuration */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ 1, /* ts1 index */
+ NOT_SUPPORTED, /* TS2 index */
+ NOT_SUPPORTED, /* AUDIO */
+ NOT_SUPPORTED, /* VIDEO */
+ NOT_SUPPORTED, /* VANC */
+ NOT_SUPPORTED, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ ,
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ ,
+ /* full-speed config */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ 1, /* ts1 index */
+ NOT_SUPPORTED, /* TS2 index */
+ NOT_SUPPORTED, /* AUDIO */
+ NOT_SUPPORTED, /* VIDEO */
+ NOT_SUPPORTED, /* VANC */
+ NOT_SUPPORTED, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ }
+ ,
+
+ {
+ INDEX_SELFPOWER_DUAL_DIGITAL, /* index */
+ USB_SELF_POWER, /* power_type */
+ 0, /* speed , not decide yet */
+ MOD_DIGITAL, /* mode */
+ SOURCE_TS_BDA, /* ts1_source, digital tv only */
+ 0, /* ts2_source,need update from register */
+ NOT_SUPPORTED, /* analog source */
+ 0, /* digital_index */
+ 0, /* analog index */
+ 0, /* dif_index */
+ 0, /* external_index */
+
+ 1, /* only one configuration */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ 1, /* ts1 index */
+ 2, /* TS2 index */
+ NOT_SUPPORTED, /* AUDIO */
+ NOT_SUPPORTED, /* VIDEO */
+ NOT_SUPPORTED, /* VANC */
+ NOT_SUPPORTED, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ ,
+ /* full-speed */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ 1, /* ts1 index */
+ 2, /* TS2 index */
+ NOT_SUPPORTED, /* AUDIO */
+ NOT_SUPPORTED, /* VIDEO */
+ NOT_SUPPORTED, /* VANC */
+ NOT_SUPPORTED, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ }
+ ,
+
+ {
+ INDEX_SELFPOWER_ANALOG_ONLY, /* index */
+ USB_SELF_POWER, /* power_type */
+ 0, /* speed , not decide yet */
+ MOD_ANALOG | MOD_DIF | MOD_EXTERNAL, /* mode ,analog tv only */
+ NOT_SUPPORTED, /* ts1_source, NOT SUPPORT */
+ NOT_SUPPORTED, /* ts2_source,NOT SUPPORT */
+ 0, /* analog source, need update */
+
+ 0, /* digital_index */
+ 0, /* analog index */
+ 0, /* dif_index */
+ 0, /* external_index */
+
+ 1, /* only one configuration */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ NOT_SUPPORTED, /* ts1 index */
+ NOT_SUPPORTED, /* TS2 index */
+ 1, /* AUDIO */
+ 2, /* VIDEO */
+ 3, /* VANC */
+ 4, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ ,
+ /* full-speed */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ NOT_SUPPORTED, /* ts1 index */
+ NOT_SUPPORTED, /* TS2 index */
+ 1, /* AUDIO */
+ 2, /* VIDEO */
+ NOT_SUPPORTED, /* VANC */
+ NOT_SUPPORTED, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ }
+ ,
+
+ {
+ INDEX_SELFPOWER_DUAL, /* index */
+ USB_SELF_POWER, /* power_type */
+ 0, /* speed , not decide yet */
+ /* mode ,analog tv and digital path */
+ MOD_ANALOG | MOD_DIF | MOD_DIGITAL | MOD_EXTERNAL,
+ 0, /* ts1_source,will update in register */
+ NOT_SUPPORTED, /* ts2_source,NOT SUPPORT */
+ 0, /* analog source need update */
+ 0, /* digital_index */
+ 0, /* analog index */
+ 0, /* dif_index */
+ 0, /* external_index */
+ 1, /* only one configuration */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ 1, /* ts1 index */
+ NOT_SUPPORTED, /* TS2 index */
+ 2, /* AUDIO */
+ 3, /* VIDEO */
+ 4, /* VANC */
+ 5, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ ,
+ /* full-speed */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ 1, /* ts1 index */
+ NOT_SUPPORTED, /* TS2 index */
+ 2, /* AUDIO */
+ 3, /* VIDEO */
+ NOT_SUPPORTED, /* VANC */
+ NOT_SUPPORTED, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ }
+ ,
+
+ {
+ INDEX_SELFPOWER_TRIPLE, /* index */
+ USB_SELF_POWER, /* power_type */
+ 0, /* speed , not decide yet */
+ /* mode ,analog tv and digital path */
+ MOD_ANALOG | MOD_DIF | MOD_DIGITAL | MOD_EXTERNAL,
+ 0, /* ts1_source, update in register */
+ 0, /* ts2_source,update in register */
+ 0, /* analog source, need update */
+
+ 0, /* digital_index */
+ 0, /* analog index */
+ 0, /* dif_index */
+ 0, /* external_index */
+ 1, /* only one configuration */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ 1, /* ts1 index */
+ 2, /* TS2 index */
+ 3, /* AUDIO */
+ 4, /* VIDEO */
+ 5, /* VANC */
+ 6, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ ,
+ /* full-speed */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ 1, /* ts1 index */
+ 2, /* TS2 index */
+ 3, /* AUDIO */
+ 4, /* VIDEO */
+ NOT_SUPPORTED, /* VANC */
+ NOT_SUPPORTED, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ }
+ ,
+
+ {
+ INDEX_SELFPOWER_COMPRESSOR, /* index */
+ USB_SELF_POWER, /* power_type */
+ 0, /* speed , not decide yet */
+ /* mode ,analog tv AND DIGITAL path */
+ MOD_ANALOG | MOD_DIF | MOD_DIGITAL | MOD_EXTERNAL,
+ NOT_SUPPORTED, /* ts1_source, disable */
+ SOURCE_TS_BDA, /* ts2_source */
+ 0, /* analog source,need update */
+ 0, /* digital_index */
+ 0, /* analog index */
+ 0, /* dif_index */
+ 0, /* external_index */
+ 1, /* only one configuration */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ NOT_SUPPORTED, /* ts1 index */
+ 1, /* TS2 index */
+ 2, /* AUDIO */
+ 3, /* VIDEO */
+ 4, /* VANC */
+ 5, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ ,
+ /* full-speed */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ NOT_SUPPORTED, /* ts1 index */
+ 1, /* TS2 index */
+ 2, /* AUDIO */
+ 3, /* VIDEO */
+ NOT_SUPPORTED, /* VANC */
+ NOT_SUPPORTED, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ }
+ ,
+
+ {
+ INDEX_BUSPOWER_DIGITAL_ONLY, /* index */
+ USB_BUS_POWER, /* power_type */
+ 0, /* speed , not decide yet */
+ MOD_DIGITAL, /* mode ,analog tv AND DIGITAL path */
+ SOURCE_TS_BDA, /* ts1_source, disable */
+ NOT_SUPPORTED, /* ts2_source */
+ NOT_SUPPORTED, /* analog source */
+
+ 0, /* digital_index */
+ 0, /* analog index */
+ 0, /* dif_index */
+ 0, /* external_index */
+
+ 1, /* only one configuration */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index = 2 */
+ 1, /* ts1 index */
+ NOT_SUPPORTED, /* TS2 index */
+ NOT_SUPPORTED, /* AUDIO */
+ NOT_SUPPORTED, /* VIDEO */
+ NOT_SUPPORTED, /* VANC */
+ NOT_SUPPORTED, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ ,
+ /* full-speed */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index = 2 */
+ 1, /* ts1 index */
+ NOT_SUPPORTED, /* TS2 index */
+ NOT_SUPPORTED, /* AUDIO */
+ NOT_SUPPORTED, /* VIDEO */
+ NOT_SUPPORTED, /* VANC */
+ NOT_SUPPORTED, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ }
+ ,
+ {
+ INDEX_BUSPOWER_ANALOG_ONLY, /* index */
+ USB_BUS_POWER, /* power_type */
+ 0, /* speed , not decide yet */
+ MOD_ANALOG, /* mode ,analog tv AND DIGITAL path */
+ NOT_SUPPORTED, /* ts1_source, disable */
+ NOT_SUPPORTED, /* ts2_source */
+ SOURCE_ANALOG, /* analog source--analog */
+ 0, /* digital_index */
+ 0, /* analog index */
+ 0, /* dif_index */
+ 0, /* external_index */
+ 1, /* only one configuration */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ NOT_SUPPORTED, /* ts1 index */
+ NOT_SUPPORTED, /* TS2 index */
+ 1, /* AUDIO */
+ 2, /* VIDEO */
+ 3, /* VANC */
+ 4, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ ,
+ { /* full-speed */
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ NOT_SUPPORTED, /* ts1 index */
+ NOT_SUPPORTED, /* TS2 index */
+ 1, /* AUDIO */
+ 2, /* VIDEO */
+ NOT_SUPPORTED, /* VANC */
+ NOT_SUPPORTED, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ }
+ ,
+ {
+ INDEX_BUSPOWER_DIF_ONLY, /* index */
+ USB_BUS_POWER, /* power_type */
+ 0, /* speed , not decide yet */
+ /* mode ,analog tv AND DIGITAL path */
+ MOD_DIF | MOD_ANALOG | MOD_DIGITAL | MOD_EXTERNAL,
+ SOURCE_TS_BDA, /* ts1_source, disable */
+ NOT_SUPPORTED, /* ts2_source */
+ SOURCE_DIF | SOURCE_ANALOG | SOURCE_EXTERNAL, /* analog source, dif */
+ 0, /* digital_index */
+ 0, /* analog index */
+ 0, /* dif_index */
+ 0, /* external_index */
+ 1, /* only one configuration */
+ {
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ 1, /* ts1 index */
+ NOT_SUPPORTED, /* TS2 index */
+ 2, /* AUDIO */
+ 3, /* VIDEO */
+ 4, /* VANC */
+ 5, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ ,
+ { /* full speed */
+ {
+ 0, /* config index */
+ {
+ 0, /* interrupt ep index */
+ 1, /* ts1 index */
+ NOT_SUPPORTED, /* TS2 index */
+ 2, /* AUDIO */
+ 3, /* VIDEO */
+ NOT_SUPPORTED, /* VANC */
+ NOT_SUPPORTED, /* HANC */
+ NOT_SUPPORTED /* ir_index */
+ }
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ ,
+ {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+ NOT_SUPPORTED}
+ }
+ }
+ }
+ ,
+
+};
+
+/*****************************************************************/
+
+u32 initialize_cx231xx(struct cx231xx *dev)
+{
+ u32 config_info = 0;
+ struct pcb_config *p_pcb_info;
+ u8 usb_speed = 1; /* from register,1--HS, 0--FS */
+ u8 data[4] = { 0, 0, 0, 0 };
+ u32 ts1_source = 0;
+ u32 ts2_source = 0;
+ u32 analog_source = 0;
+ u8 _current_scenario_idx = 0xff;
+
+ ts1_source = SOURCE_TS_BDA;
+ ts2_source = SOURCE_TS_BDA;
+
+ /* read board config register to find out which
+ pcb config it is related to */
+ cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, data, 4);
+
+ config_info = *((u32 *) data);
+ usb_speed = (u8) (config_info & 0x1);
+
+ /* Verify this device belongs to Bus power or Self power device */
+ if (config_info & BUS_POWER) { /* bus-power */
+ switch (config_info & BUSPOWER_MASK) {
+ case TS1_PORT | BUS_POWER:
+ cx231xx_Scenario[INDEX_BUSPOWER_DIGITAL_ONLY].speed =
+ usb_speed;
+ p_pcb_info =
+ &cx231xx_Scenario[INDEX_BUSPOWER_DIGITAL_ONLY];
+ _current_scenario_idx = INDEX_BUSPOWER_DIGITAL_ONLY;
+ break;
+ case AVDEC_ENABLE | BUS_POWER:
+ cx231xx_Scenario[INDEX_BUSPOWER_ANALOG_ONLY].speed =
+ usb_speed;
+ p_pcb_info =
+ &cx231xx_Scenario[INDEX_BUSPOWER_ANALOG_ONLY];
+ _current_scenario_idx = INDEX_BUSPOWER_ANALOG_ONLY;
+ break;
+ case AVDEC_ENABLE | BUS_POWER | TS1_PORT:
+ cx231xx_Scenario[INDEX_BUSPOWER_DIF_ONLY].speed =
+ usb_speed;
+ p_pcb_info = &cx231xx_Scenario[INDEX_BUSPOWER_DIF_ONLY];
+ _current_scenario_idx = INDEX_BUSPOWER_DIF_ONLY;
+ break;
+ default:
+ cx231xx_info("bad config in buspower!!!!\n");
+ cx231xx_info("config_info=%x\n",
+ (config_info & BUSPOWER_MASK));
+ return 1;
+ }
+ } else { /* self-power */
+
+ switch (config_info & SELFPOWER_MASK) {
+ case TS1_PORT | SELF_POWER:
+ cx231xx_Scenario[INDEX_SELFPOWER_DIGITAL_ONLY].speed =
+ usb_speed;
+ p_pcb_info =
+ &cx231xx_Scenario[INDEX_SELFPOWER_DIGITAL_ONLY];
+ _current_scenario_idx = INDEX_SELFPOWER_DIGITAL_ONLY;
+ break;
+ case TS1_TS2_PORT | SELF_POWER:
+ cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL].speed =
+ usb_speed;
+ cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL].
+ ts2_source = ts2_source;
+ p_pcb_info =
+ &cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL];
+ _current_scenario_idx = INDEX_SELFPOWER_DUAL_DIGITAL;
+ break;
+ case AVDEC_ENABLE | SELF_POWER:
+ cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY].speed =
+ usb_speed;
+ cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY].
+ analog_source = analog_source;
+ p_pcb_info =
+ &cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY];
+ _current_scenario_idx = INDEX_SELFPOWER_ANALOG_ONLY;
+ break;
+ case AVDEC_ENABLE | TS1_PORT | SELF_POWER:
+ cx231xx_Scenario[INDEX_SELFPOWER_DUAL].speed =
+ usb_speed;
+ cx231xx_Scenario[INDEX_SELFPOWER_DUAL].ts1_source =
+ ts1_source;
+ cx231xx_Scenario[INDEX_SELFPOWER_DUAL].analog_source =
+ analog_source;
+ p_pcb_info = &cx231xx_Scenario[INDEX_SELFPOWER_DUAL];
+ _current_scenario_idx = INDEX_SELFPOWER_DUAL;
+ break;
+ case AVDEC_ENABLE | TS1_TS2_PORT | SELF_POWER:
+ cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].speed =
+ usb_speed;
+ cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].ts1_source =
+ ts1_source;
+ cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].ts2_source =
+ ts2_source;
+ cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].analog_source =
+ analog_source;
+ p_pcb_info = &cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE];
+ _current_scenario_idx = INDEX_SELFPOWER_TRIPLE;
+ break;
+ case AVDEC_ENABLE | TS1VIP_TS2_PORT | SELF_POWER:
+ cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR].speed =
+ usb_speed;
+ cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR].
+ analog_source = analog_source;
+ p_pcb_info =
+ &cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR];
+ _current_scenario_idx = INDEX_SELFPOWER_COMPRESSOR;
+ break;
+ default:
+ cx231xx_info("bad senario!!!!!\n");
+ cx231xx_info("config_info=%x\n",
+ (config_info & SELFPOWER_MASK));
+ return 1;
+ }
+ }
+
+ dev->current_scenario_idx = _current_scenario_idx;
+
+ memcpy(&dev->current_pcb_config, p_pcb_info,
+ sizeof(struct pcb_config));
+
+ if (pcb_debug) {
+ cx231xx_info("SC(0x00) register = 0x%x\n", config_info);
+ cx231xx_info("scenario %d\n",
+ (dev->current_pcb_config.index) + 1);
+ cx231xx_info("type=%x\n", dev->current_pcb_config.type);
+ cx231xx_info("mode=%x\n", dev->current_pcb_config.mode);
+ cx231xx_info("speed=%x\n", dev->current_pcb_config.speed);
+ cx231xx_info("ts1_source=%x\n",
+ dev->current_pcb_config.ts1_source);
+ cx231xx_info("ts2_source=%x\n",
+ dev->current_pcb_config.ts2_source);
+ cx231xx_info("analog_source=%x\n",
+ dev->current_pcb_config.analog_source);
+ }
+
+ return 0;
+}
diff --git a/drivers/media/video/cx231xx/cx231xx-pcb-cfg.h b/drivers/media/video/cx231xx/cx231xx-pcb-cfg.h
new file mode 100644
index 00000000000..f5e46e89f3a
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-pcb-cfg.h
@@ -0,0 +1,231 @@
+/*
+ cx231xx-pcb-cfg.h - driver for Conexant
+ Cx23100/101/102 USB video capture devices
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot 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.
+ */
+
+#ifndef _PCB_CONFIG_H_
+#define _PCB_CONFIG_H_
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+/***************************************************************************
+ * Class Information *
+***************************************************************************/
+#define CLASS_DEFAULT 0xFF
+
+enum VENDOR_REQUEST_TYPE {
+ /* Set/Get I2C */
+ VRT_SET_I2C0 = 0x0,
+ VRT_SET_I2C1 = 0x1,
+ VRT_SET_I2C2 = 0x2,
+ VRT_GET_I2C0 = 0x4,
+ VRT_GET_I2C1 = 0x5,
+ VRT_GET_I2C2 = 0x6,
+
+ /* Set/Get GPIO */
+ VRT_SET_GPIO = 0x8,
+ VRT_GET_GPIO = 0x9,
+
+ /* Set/Get GPIE */
+ VRT_SET_GPIE = 0xA,
+ VRT_GET_GPIE = 0xB,
+
+ /* Set/Get Register Control/Status */
+ VRT_SET_REGISTER = 0xC,
+ VRT_GET_REGISTER = 0xD,
+
+ /* Get Extended Compat ID Descriptor */
+ VRT_GET_EXTCID_DESC = 0xFF,
+};
+
+enum BYTE_ENABLE_MASK {
+ ENABLE_ONE_BYTE = 0x1,
+ ENABLE_TWE_BYTE = 0x3,
+ ENABLE_THREE_BYTE = 0x7,
+ ENABLE_FOUR_BYTE = 0xF,
+};
+
+#define SPEED_MASK 0x1
+enum USB_SPEED{
+ FULL_SPEED = 0x0, /* 0: full speed */
+ HIGH_SPEED = 0x1 /* 1: high speed */
+};
+
+enum _true_false{
+ FALSE = 0,
+ TRUE = 1
+};
+
+#define TS_MASK 0x6
+enum TS_PORT{
+ NO_TS_PORT = 0x0, /* 2'b00: Neither port used. PCB not a Hybrid,
+ only offers Analog TV or Video */
+ TS1_PORT = 0x4, /* 2'b10: TS1 Input (Hybrid mode :
+ Digital or External Analog/Compressed source) */
+ TS1_TS2_PORT = 0x6, /* 2'b11: TS1 & TS2 Inputs
+ (Dual inputs from Digital and/or
+ External Analog/Compressed sources) */
+ TS1_EXT_CLOCK = 0x6, /* 2'b11: TS1 & TS2 as selector
+ to external clock */
+ TS1VIP_TS2_PORT = 0x2 /* 2'b01: TS1 used as 656/VIP Output,
+ TS2 Input (from Compressor) */
+};
+
+#define EAVP_MASK 0x8
+enum EAV_PRESENT{
+ NO_EXTERNAL_AV = 0x0, /* 0: No External A/V inputs
+ (no need for i2s blcok),
+ Analog Tuner must be present */
+ EXTERNAL_AV = 0x8 /* 1: External A/V inputs
+ present (requires i2s blk) */
+};
+
+#define ATM_MASK 0x30
+enum AT_MODE{
+ DIF_TUNER = 0x30, /* 2'b11: IF Tuner (requires use of DIF) */
+ BASEBAND_SOUND = 0x20, /* 2'b10: Baseband Composite &
+ Sound-IF Signals present */
+ NO_TUNER = 0x10 /* 2'b0x: No Analog Tuner present */
+};
+
+#define PWR_SEL_MASK 0x40
+enum POWE_TYPE{
+ SELF_POWER = 0x0, /* 0: self power */
+ BUS_POWER = 0x40 /* 1: bus power */
+};
+
+enum USB_POWE_TYPE{
+ USB_SELF_POWER = 0,
+ USB_BUS_POWER
+};
+
+#define BO_0_MASK 0x80
+enum AVDEC_STATUS{
+ AVDEC_DISABLE = 0x0, /* 0: A/V Decoder Disabled */
+ AVDEC_ENABLE = 0x80 /* 1: A/V Decoder Enabled */
+};
+
+#define BO_1_MASK 0x100
+
+#define BUSPOWER_MASK 0xC4 /* for Polaris spec 0.8 */
+#define SELFPOWER_MASK 0x86
+
+/***************************************************************************/
+#define NOT_DECIDE_YET 0xFE
+#define NOT_SUPPORTED 0xFF
+
+/***************************************************************************
+ * for mod field use *
+***************************************************************************/
+#define MOD_DIGITAL 0x1
+#define MOD_ANALOG 0x2
+#define MOD_DIF 0x4
+#define MOD_EXTERNAL 0x8
+#define CAP_ALL_MOD 0x0f
+
+/***************************************************************************
+ * source define *
+***************************************************************************/
+#define SOURCE_DIGITAL 0x1
+#define SOURCE_ANALOG 0x2
+#define SOURCE_DIF 0x4
+#define SOURCE_EXTERNAL 0x8
+#define SOURCE_TS_BDA 0x10
+#define SOURCE_TS_ENCODE 0x20
+#define SOURCE_TS_EXTERNAL 0x40
+
+/***************************************************************************
+ * interface information define *
+***************************************************************************/
+struct INTERFACE_INFO {
+ u8 interrupt_index;
+ u8 ts1_index;
+ u8 ts2_index;
+ u8 audio_index;
+ u8 video_index;
+ u8 vanc_index; /* VBI */
+ u8 hanc_index; /* Sliced CC */
+ u8 ir_index;
+};
+
+enum INDEX_INTERFACE_INFO{
+ INDEX_INTERRUPT = 0x0,
+ INDEX_TS1,
+ INDEX_TS2,
+ INDEX_AUDIO,
+ INDEX_VIDEO,
+ INDEX_VANC,
+ INDEX_HANC,
+ INDEX_IR,
+};
+
+/***************************************************************************
+ * configuration information define *
+***************************************************************************/
+struct CONFIG_INFO {
+ u8 config_index;
+ struct INTERFACE_INFO interface_info;
+};
+
+struct pcb_config {
+ u8 index;
+ u8 type; /* bus power or self power,
+ self power--0, bus_power--1 */
+ u8 speed; /* usb speed, 2.0--1, 1.1--0 */
+ u8 mode; /* digital , anlog, dif or external A/V */
+ u32 ts1_source; /* three source -- BDA,External,encode */
+ u32 ts2_source;
+ u32 analog_source;
+ u8 digital_index; /* bus-power used */
+ u8 analog_index; /* bus-power used */
+ u8 dif_index; /* bus-power used */
+ u8 external_index; /* bus-power used */
+ u8 config_num; /* current config num, 0,1,2,
+ for self-power, always 0 */
+ struct CONFIG_INFO hs_config_info[3];
+ struct CONFIG_INFO fs_config_info[3];
+};
+
+enum INDEX_PCB_CONFIG{
+ INDEX_SELFPOWER_DIGITAL_ONLY = 0x0,
+ INDEX_SELFPOWER_DUAL_DIGITAL,
+ INDEX_SELFPOWER_ANALOG_ONLY,
+ INDEX_SELFPOWER_DUAL,
+ INDEX_SELFPOWER_TRIPLE,
+ INDEX_SELFPOWER_COMPRESSOR,
+ INDEX_BUSPOWER_DIGITAL_ONLY,
+ INDEX_BUSPOWER_ANALOG_ONLY,
+ INDEX_BUSPOWER_DIF_ONLY,
+ INDEX_BUSPOWER_EXTERNAL_ONLY,
+ INDEX_BUSPOWER_EXTERNAL_ANALOG,
+ INDEX_BUSPOWER_EXTERNAL_DIF,
+ INDEX_BUSPOWER_EXTERNAL_DIGITAL,
+ INDEX_BUSPOWER_DIGITAL_ANALOG,
+ INDEX_BUSPOWER_DIGITAL_DIF,
+ INDEX_BUSPOWER_DIGITAL_ANALOG_EXTERNAL,
+ INDEX_BUSPOWER_DIGITAL_DIF_EXTERNAL,
+};
+
+/***************************************************************************/
+struct cx231xx;
+
+u32 initialize_cx231xx(struct cx231xx *p_dev);
+
+#endif
diff --git a/drivers/media/video/cx231xx/cx231xx-reg.h b/drivers/media/video/cx231xx/cx231xx-reg.h
new file mode 100644
index 00000000000..750c5d37d56
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-reg.h
@@ -0,0 +1,1564 @@
+/*
+ cx231xx-reg.h - driver for Conexant Cx23100/101/102
+ USB video capture devices
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot 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.
+ */
+
+#ifndef _CX231XX_REG_H
+#define _CX231XX_REG_H
+
+/*****************************************************************************
+ * VBI codes *
+*****************************************************************************/
+
+#define SAV_ACTIVE_VIDEO_FIELD1 0x80
+#define EAV_ACTIVE_VIDEO_FIELD1 0x90
+
+#define SAV_ACTIVE_VIDEO_FIELD2 0xc0
+#define EAV_ACTIVE_VIDEO_FIELD2 0xd0
+
+#define SAV_VBLANK_FIELD1 0xa0
+#define EAV_VBLANK_FIELD1 0xb0
+
+#define SAV_VBLANK_FIELD2 0xe0
+#define EAV_VBLANK_FIELD2 0xf0
+
+#define SAV_VBI_FIELD1 0x20
+#define EAV_VBI_FIELD1 0x30
+
+#define SAV_VBI_FIELD2 0x60
+#define EAV_VBI_FIELD2 0x70
+
+/*****************************************************************************/
+/* Audio ADC Registers */
+#define CH_PWR_CTRL1 0x0000000e
+#define CH_PWR_CTRL2 0x0000000f
+/*****************************************************************************/
+
+#define HOST_REG1 0x000
+#define FLD_FORCE_CHIP_SEL 0x80
+#define FLD_AUTO_INC_DIS 0x20
+#define FLD_PREFETCH_EN 0x10
+/* Reserved [2:3] */
+#define FLD_DIGITAL_PWR_DN 0x02
+#define FLD_SLEEP 0x01
+
+/*****************************************************************************/
+#define HOST_REG2 0x001
+
+/*****************************************************************************/
+#define HOST_REG3 0x002
+
+/*****************************************************************************/
+/* added for polaris */
+#define GPIO_PIN_CTL0 0x3
+#define GPIO_PIN_CTL1 0x4
+#define GPIO_PIN_CTL2 0x5
+#define GPIO_PIN_CTL3 0x6
+#define TS1_PIN_CTL0 0x7
+#define TS1_PIN_CTL1 0x8
+/*****************************************************************************/
+
+#define FLD_CLK_IN_EN 0x80
+#define FLD_XTAL_CTRL 0x70
+#define FLD_BB_CLK_MODE 0x0C
+#define FLD_REF_DIV_PLL 0x02
+#define FLD_REF_SEL_PLL1 0x01
+
+/*****************************************************************************/
+#define CHIP_CTRL 0x100
+/* Reserved [27] */
+/* Reserved [31:21] */
+#define FLD_CHIP_ACFG_DIS 0x00100000
+/* Reserved [19] */
+#define FLD_DUAL_MODE_ADC2 0x00040000
+#define FLD_SIF_EN 0x00020000
+#define FLD_SOFT_RST 0x00010000
+#define FLD_DEVICE_ID 0x0000ffff
+
+/*****************************************************************************/
+#define AFE_CTRL 0x104
+#define AFE_CTRL_C2HH_SRC_CTRL 0x104
+#define FLD_DIF_OUT_SEL 0xc0000000
+#define FLD_AUX_PLL_CLK_ALT_SEL 0x3c000000
+#define FLD_UV_ORDER_MODE 0x02000000
+#define FLD_FUNC_MODE 0x01800000
+#define FLD_ROT1_PHASE_CTL 0x007f8000
+#define FLD_AUD_IN_SEL 0x00004000
+#define FLD_LUMA_IN_SEL 0x00002000
+#define FLD_CHROMA_IN_SEL 0x00001000
+/* reserve [11:10] */
+#define FLD_INV_SPEC_DIS 0x00000200
+#define FLD_VGA_SEL_CH3 0x00000100
+#define FLD_VGA_SEL_CH2 0x00000080
+#define FLD_VGA_SEL_CH1 0x00000040
+#define FLD_DCR_BYP_CH1 0x00000020
+#define FLD_DCR_BYP_CH2 0x00000010
+#define FLD_DCR_BYP_CH3 0x00000008
+#define FLD_EN_12DB_CH3 0x00000004
+#define FLD_EN_12DB_CH2 0x00000002
+#define FLD_EN_12DB_CH1 0x00000001
+
+/* redefine in Cx231xx */
+/*****************************************************************************/
+#define DC_CTRL1 0x108
+/* reserve [31:30] */
+#define FLD_CLAMP_LVL_CH1 0x3fff8000
+#define FLD_CLAMP_LVL_CH2 0x00007fff
+/*****************************************************************************/
+
+/*****************************************************************************/
+#define DC_CTRL2 0x10c
+/* reserve [31:28] */
+#define FLD_CLAMP_LVL_CH3 0x00fffe00
+#define FLD_CLAMP_WIND_LENTH 0x000001e0
+#define FLD_C2HH_SAT_MIN 0x0000001e
+#define FLD_FLT_BYP_SEL 0x00000001
+/*****************************************************************************/
+
+/*****************************************************************************/
+#define DC_CTRL3 0x110
+/* reserve [31:16] */
+#define FLD_ERR_GAIN_CTL 0x00070000
+#define FLD_LPF_MIN 0x0000ffff
+/*****************************************************************************/
+
+/*****************************************************************************/
+#define DC_CTRL4 0x114
+/* reserve [31:31] */
+#define FLD_INTG_CH1 0x7fffffff
+/*****************************************************************************/
+
+/*****************************************************************************/
+#define DC_CTRL5 0x118
+/* reserve [31:31] */
+#define FLD_INTG_CH2 0x7fffffff
+/*****************************************************************************/
+
+/*****************************************************************************/
+#define DC_CTRL6 0x11c
+/* reserve [31:31] */
+#define FLD_INTG_CH3 0x7fffffff
+/*****************************************************************************/
+
+/*****************************************************************************/
+#define PIN_CTRL 0x120
+#define FLD_OEF_AGC_RF 0x00000001
+#define FLD_OEF_AGC_IFVGA 0x00000002
+#define FLD_OEF_AGC_IF 0x00000004
+#define FLD_REG_BO_PUD 0x80000000
+#define FLD_IR_IRQ_STAT 0x40000000
+#define FLD_AUD_IRQ_STAT 0x20000000
+#define FLD_VID_IRQ_STAT 0x10000000
+/* Reserved [27:26] */
+#define FLD_IRQ_N_OUT_EN 0x02000000
+#define FLD_IRQ_N_POLAR 0x01000000
+/* Reserved [23:6] */
+#define FLD_OE_AUX_PLL_CLK 0x00000020
+#define FLD_OE_I2S_BCLK 0x00000010
+#define FLD_OE_I2S_WCLK 0x00000008
+#define FLD_OE_AGC_IF 0x00000004
+#define FLD_OE_AGC_IFVGA 0x00000002
+#define FLD_OE_AGC_RF 0x00000001
+
+/*****************************************************************************/
+#define AUD_IO_CTRL 0x124
+/* Reserved [31:8] */
+#define FLD_I2S_PORT_DIR 0x00000080
+#define FLD_I2S_OUT_SRC 0x00000040
+#define FLD_AUD_CHAN3_SRC 0x00000030
+#define FLD_AUD_CHAN2_SRC 0x0000000c
+#define FLD_AUD_CHAN1_SRC 0x00000003
+
+/*****************************************************************************/
+#define AUD_LOCK1 0x128
+#define FLD_AUD_LOCK_KI_SHIFT 0xc0000000
+#define FLD_AUD_LOCK_KD_SHIFT 0x30000000
+/* Reserved [27:25] */
+#define FLD_EN_AV_LOCK 0x01000000
+#define FLD_VID_COUNT 0x00ffffff
+
+/*****************************************************************************/
+#define AUD_LOCK2 0x12c
+#define FLD_AUD_LOCK_KI_MULT 0xf0000000
+#define FLD_AUD_LOCK_KD_MULT 0x0F000000
+/* Reserved [23:22] */
+#define FLD_AUD_LOCK_FREQ_SHIFT 0x00300000
+#define FLD_AUD_COUNT 0x000fffff
+
+/*****************************************************************************/
+#define AFE_DIAG_CTRL1 0x134
+/* Reserved [31:16] */
+#define FLD_CUV_DLY_LENGTH 0x0000ff00
+#define FLD_YC_DLY_LENGTH 0x000000ff
+
+/*****************************************************************************/
+/* Poalris redefine */
+#define AFE_DIAG_CTRL3 0x138
+/* Reserved [31:26] */
+#define FLD_AUD_DUAL_FLAG_POL 0x02000000
+#define FLD_VID_DUAL_FLAG_POL 0x01000000
+/* Reserved [23:23] */
+#define FLD_COL_CLAMP_DIS_CH1 0x00400000
+#define FLD_COL_CLAMP_DIS_CH2 0x00200000
+#define FLD_COL_CLAMP_DIS_CH3 0x00100000
+
+#define TEST_CTRL1 0x144
+/* Reserved [31:29] */
+#define FLD_LBIST_EN 0x10000000
+/* Reserved [27:10] */
+#define FLD_FI_BIST_INTR_R 0x0000200
+#define FLD_FI_BIST_INTR_L 0x0000100
+#define FLD_BIST_FAIL_AUD_PLL 0x0000080
+#define FLD_BIST_INTR_AUD_PLL 0x0000040
+#define FLD_BIST_FAIL_VID_PLL 0x0000020
+#define FLD_BIST_INTR_VID_PLL 0x0000010
+/* Reserved [3:1] */
+#define FLD_CIR_TEST_DIS 0x00000001
+
+/*****************************************************************************/
+#define TEST_CTRL2 0x148
+#define FLD_TSXCLK_POL_CTL 0x80000000
+#define FLD_ISO_CTL_SEL 0x40000000
+#define FLD_ISO_CTL_EN 0x20000000
+#define FLD_BIST_DEBUGZ 0x10000000
+#define FLD_AUD_BIST_TEST_H 0x0f000000
+/* Reserved [23:22] */
+#define FLD_FLTRN_BIST_TEST_H 0x00020000
+#define FLD_VID_BIST_TEST_H 0x00010000
+/* Reserved [19:17] */
+#define FLD_BIST_TEST_H 0x00010000
+/* Reserved [15:13] */
+#define FLD_TAB_EN 0x00001000
+/* Reserved [11:0] */
+
+/*****************************************************************************/
+#define BIST_STAT 0x14c
+#define FLD_AUD_BIST_FAIL_H 0xfff00000
+#define FLD_FLTRN_BIST_FAIL_H 0x00180000
+#define FLD_VID_BIST_FAIL_H 0x00070000
+#define FLD_AUD_BIST_TST_DONE 0x0000fff0
+#define FLD_FLTRN_BIST_TST_DONE 0x00000008
+#define FLD_VID_BIST_TST_DONE 0x00000007
+
+/*****************************************************************************/
+/* DirectIF registers definition have been moved to DIF_reg.h */
+/*****************************************************************************/
+#define MODE_CTRL 0x400
+#define FLD_AFD_PAL60_DIS 0x20000000
+#define FLD_AFD_FORCE_SECAM 0x10000000
+#define FLD_AFD_FORCE_PALNC 0x08000000
+#define FLD_AFD_FORCE_PAL 0x04000000
+#define FLD_AFD_PALM_SEL 0x03000000
+#define FLD_CKILL_MODE 0x00300000
+#define FLD_COMB_NOTCH_MODE 0x00c00000 /* bit[19:18] */
+#define FLD_CLR_LOCK_STAT 0x00020000
+#define FLD_FAST_LOCK_MD 0x00010000
+#define FLD_WCEN 0x00008000
+#define FLD_CAGCEN 0x00004000
+#define FLD_CKILLEN 0x00002000
+#define FLD_AUTO_SC_LOCK 0x00001000
+#define FLD_MAN_SC_FAST_LOCK 0x00000800
+#define FLD_INPUT_MODE 0x00000600
+#define FLD_AFD_ACQUIRE 0x00000100
+#define FLD_AFD_NTSC_SEL 0x00000080
+#define FLD_AFD_PAL_SEL 0x00000040
+#define FLD_ACFG_DIS 0x00000020
+#define FLD_SQ_PIXEL 0x00000010
+#define FLD_VID_FMT_SEL 0x0000000f
+
+/*****************************************************************************/
+#define OUT_CTRL1 0x404
+#define FLD_POLAR 0x7f000000
+/* Reserved [23] */
+#define FLD_RND_MODE 0x00600000
+#define FLD_VIPCLAMP_EN 0x00100000
+#define FLD_VIPBLANK_EN 0x00080000
+#define FLD_VIP_OPT_AL 0x00040000
+#define FLD_IDID0_SOURCE 0x00020000
+#define FLD_DCMODE 0x00010000
+#define FLD_CLK_GATING 0x0000c000
+#define FLD_CLK_INVERT 0x00002000
+#define FLD_HSFMT 0x00001000
+#define FLD_VALIDFMT 0x00000800
+#define FLD_ACTFMT 0x00000400
+#define FLD_SWAPRAW 0x00000200
+#define FLD_CLAMPRAW_EN 0x00000100
+#define FLD_BLUE_FIELD_EN 0x00000080
+#define FLD_BLUE_FIELD_ACT 0x00000040
+#define FLD_TASKBIT_VAL 0x00000020
+#define FLD_ANC_DATA_EN 0x00000010
+#define FLD_VBIHACTRAW_EN 0x00000008
+#define FLD_MODE10B 0x00000004
+#define FLD_OUT_MODE 0x00000003
+
+/*****************************************************************************/
+#define OUT_CTRL2 0x408
+#define FLD_AUD_GRP 0xc0000000
+#define FLD_SAMPLE_RATE 0x30000000
+#define FLD_AUD_ANC_EN 0x08000000
+#define FLD_EN_C 0x04000000
+#define FLD_EN_B 0x02000000
+#define FLD_EN_A 0x01000000
+/* Reserved [23:20] */
+#define FLD_IDID1_LSB 0x000c0000
+#define FLD_IDID0_LSB 0x00030000
+#define FLD_IDID1_MSB 0x0000ff00
+#define FLD_IDID0_MSB 0x000000ff
+
+/*****************************************************************************/
+#define GEN_STAT 0x40c
+#define FLD_VCR_DETECT 0x00800000
+#define FLD_SPECIAL_PLAY_N 0x00400000
+#define FLD_VPRES 0x00200000
+#define FLD_AGC_LOCK 0x00100000
+#define FLD_CSC_LOCK 0x00080000
+#define FLD_VLOCK 0x00040000
+#define FLD_SRC_LOCK 0x00020000
+#define FLD_HLOCK 0x00010000
+#define FLD_VSYNC_N 0x00008000
+#define FLD_SRC_FIFO_UFLOW 0x00004000
+#define FLD_SRC_FIFO_OFLOW 0x00002000
+#define FLD_FIELD 0x00001000
+#define FLD_AFD_FMT_STAT 0x00000f00
+#define FLD_MV_TYPE2_PAIR 0x00000080
+#define FLD_MV_T3CS 0x00000040
+#define FLD_MV_CS 0x00000020
+#define FLD_MV_PSP 0x00000010
+/* Reserved [3] */
+#define FLD_MV_CDAT 0x00000003
+
+/*****************************************************************************/
+#define INT_STAT_MASK 0x410
+#define FLD_COMB_3D_FIFO_MSK 0x80000000
+#define FLD_WSS_DAT_AVAIL_MSK 0x40000000
+#define FLD_GS2_DAT_AVAIL_MSK 0x20000000
+#define FLD_GS1_DAT_AVAIL_MSK 0x10000000
+#define FLD_CC_DAT_AVAIL_MSK 0x08000000
+#define FLD_VPRES_CHANGE_MSK 0x04000000
+#define FLD_MV_CHANGE_MSK 0x02000000
+#define FLD_END_VBI_EVEN_MSK 0x01000000
+#define FLD_END_VBI_ODD_MSK 0x00800000
+#define FLD_FMT_CHANGE_MSK 0x00400000
+#define FLD_VSYNC_TRAIL_MSK 0x00200000
+#define FLD_HLOCK_CHANGE_MSK 0x00100000
+#define FLD_VLOCK_CHANGE_MSK 0x00080000
+#define FLD_CSC_LOCK_CHANGE_MSK 0x00040000
+#define FLD_SRC_FIFO_UFLOW_MSK 0x00020000
+#define FLD_SRC_FIFO_OFLOW_MSK 0x00010000
+#define FLD_COMB_3D_FIFO_STAT 0x00008000
+#define FLD_WSS_DAT_AVAIL_STAT 0x00004000
+#define FLD_GS2_DAT_AVAIL_STAT 0x00002000
+#define FLD_GS1_DAT_AVAIL_STAT 0x00001000
+#define FLD_CC_DAT_AVAIL_STAT 0x00000800
+#define FLD_VPRES_CHANGE_STAT 0x00000400
+#define FLD_MV_CHANGE_STAT 0x00000200
+#define FLD_END_VBI_EVEN_STAT 0x00000100
+#define FLD_END_VBI_ODD_STAT 0x00000080
+#define FLD_FMT_CHANGE_STAT 0x00000040
+#define FLD_VSYNC_TRAIL_STAT 0x00000020
+#define FLD_HLOCK_CHANGE_STAT 0x00000010
+#define FLD_VLOCK_CHANGE_STAT 0x00000008
+#define FLD_CSC_LOCK_CHANGE_STAT 0x00000004
+#define FLD_SRC_FIFO_UFLOW_STAT 0x00000002
+#define FLD_SRC_FIFO_OFLOW_STAT 0x00000001
+
+/*****************************************************************************/
+#define LUMA_CTRL 0x414
+#define BRIGHTNESS_CTRL_BYTE 0x414
+#define CONTRAST_CTRL_BYTE 0x415
+#define LUMA_CTRL_BYTE_3 0x416
+#define FLD_LUMA_CORE_SEL 0x00c00000
+#define FLD_RANGE 0x00300000
+/* Reserved [19] */
+#define FLD_PEAK_EN 0x00040000
+#define FLD_PEAK_SEL 0x00030000
+#define FLD_CNTRST 0x0000ff00
+#define FLD_BRITE 0x000000ff
+
+/*****************************************************************************/
+#define HSCALE_CTRL 0x418
+#define FLD_HFILT 0x03000000
+#define FLD_HSCALE 0x00ffffff
+
+/*****************************************************************************/
+#define VSCALE_CTRL 0x41c
+#define FLD_LINE_AVG_DIS 0x01000000
+/* Reserved [23:20] */
+#define FLD_VS_INTRLACE 0x00080000
+#define FLD_VFILT 0x00070000
+/* Reserved [15:13] */
+#define FLD_VSCALE 0x00001fff
+
+/*****************************************************************************/
+#define CHROMA_CTRL 0x420
+#define USAT_CTRL_BYTE 0x420
+#define VSAT_CTRL_BYTE 0x421
+#define HUE_CTRL_BYTE 0x422
+#define FLD_C_LPF_EN 0x20000000
+#define FLD_CHR_DELAY 0x1c000000
+#define FLD_C_CORE_SEL 0x03000000
+#define FLD_HUE 0x00ff0000
+#define FLD_VSAT 0x0000ff00
+#define FLD_USAT 0x000000ff
+
+/*****************************************************************************/
+#define VBI_LINE_CTRL1 0x424
+#define FLD_VBI_MD_LINE4 0xff000000
+#define FLD_VBI_MD_LINE3 0x00ff0000
+#define FLD_VBI_MD_LINE2 0x0000ff00
+#define FLD_VBI_MD_LINE1 0x000000ff
+
+/*****************************************************************************/
+#define VBI_LINE_CTRL2 0x428
+#define FLD_VBI_MD_LINE8 0xff000000
+#define FLD_VBI_MD_LINE7 0x00ff0000
+#define FLD_VBI_MD_LINE6 0x0000ff00
+#define FLD_VBI_MD_LINE5 0x000000ff
+
+/*****************************************************************************/
+#define VBI_LINE_CTRL3 0x42c
+#define FLD_VBI_MD_LINE12 0xff000000
+#define FLD_VBI_MD_LINE11 0x00ff0000
+#define FLD_VBI_MD_LINE10 0x0000ff00
+#define FLD_VBI_MD_LINE9 0x000000ff
+
+/*****************************************************************************/
+#define VBI_LINE_CTRL4 0x430
+#define FLD_VBI_MD_LINE16 0xff000000
+#define FLD_VBI_MD_LINE15 0x00ff0000
+#define FLD_VBI_MD_LINE14 0x0000ff00
+#define FLD_VBI_MD_LINE13 0x000000ff
+
+/*****************************************************************************/
+#define VBI_LINE_CTRL5 0x434
+#define FLD_VBI_MD_LINE17 0x000000ff
+
+/*****************************************************************************/
+#define VBI_FC_CFG 0x438
+#define FLD_FC_ALT2 0xff000000
+#define FLD_FC_ALT1 0x00ff0000
+#define FLD_FC_ALT2_TYPE 0x0000f000
+#define FLD_FC_ALT1_TYPE 0x00000f00
+/* Reserved [7:1] */
+#define FLD_FC_SEARCH_MODE 0x00000001
+
+/*****************************************************************************/
+#define VBI_MISC_CFG1 0x43c
+#define FLD_TTX_PKTADRU 0xfff00000
+#define FLD_TTX_PKTADRL 0x000fff00
+/* Reserved [7:6] */
+#define FLD_MOJI_PACK_DIS 0x00000020
+#define FLD_VPS_DEC_DIS 0x00000010
+#define FLD_CRI_MARG_SCALE 0x0000000c
+#define FLD_EDGE_RESYNC_EN 0x00000002
+#define FLD_ADAPT_SLICE_DIS 0x00000001
+
+/*****************************************************************************/
+#define VBI_MISC_CFG2 0x440
+#define FLD_HAMMING_TYPE 0x0f000000
+/* Reserved [23:20] */
+#define FLD_WSS_FIFO_RST 0x00080000
+#define FLD_GS2_FIFO_RST 0x00040000
+#define FLD_GS1_FIFO_RST 0x00020000
+#define FLD_CC_FIFO_RST 0x00010000
+/* Reserved [15:12] */
+#define FLD_VBI3_SDID 0x00000f00
+#define FLD_VBI2_SDID 0x000000f0
+#define FLD_VBI1_SDID 0x0000000f
+
+/*****************************************************************************/
+#define VBI_PAY1 0x444
+#define FLD_GS1_FIFO_DAT 0xFF000000
+#define FLD_GS1_STAT 0x00FF0000
+#define FLD_CC_FIFO_DAT 0x0000FF00
+#define FLD_CC_STAT 0x000000FF
+
+/*****************************************************************************/
+#define VBI_PAY2 0x448
+#define FLD_WSS_FIFO_DAT 0xff000000
+#define FLD_WSS_STAT 0x00ff0000
+#define FLD_GS2_FIFO_DAT 0x0000ff00
+#define FLD_GS2_STAT 0x000000ff
+
+/*****************************************************************************/
+#define VBI_CUST1_CFG1 0x44c
+/* Reserved [31] */
+#define FLD_VBI1_CRIWIN 0x7f000000
+#define FLD_VBI1_SLICE_DIST 0x00f00000
+#define FLD_VBI1_BITINC 0x000fff00
+#define FLD_VBI1_HDELAY 0x000000ff
+
+/*****************************************************************************/
+#define VBI_CUST1_CFG2 0x450
+#define FLD_VBI1_FC_LENGTH 0x1f000000
+#define FLD_VBI1_FRAME_CODE 0x00ffffff
+
+/*****************************************************************************/
+#define VBI_CUST1_CFG3 0x454
+#define FLD_VBI1_HAM_EN 0x80000000
+#define FLD_VBI1_FIFO_MODE 0x70000000
+#define FLD_VBI1_FORMAT_TYPE 0x0f000000
+#define FLD_VBI1_PAYLD_LENGTH 0x00ff0000
+#define FLD_VBI1_CRI_LENGTH 0x0000f000
+#define FLD_VBI1_CRI_MARGIN 0x00000f00
+#define FLD_VBI1_CRI_TIME 0x000000ff
+
+/*****************************************************************************/
+#define VBI_CUST2_CFG1 0x458
+/* Reserved [31] */
+#define FLD_VBI2_CRIWIN 0x7f000000
+#define FLD_VBI2_SLICE_DIST 0x00f00000
+#define FLD_VBI2_BITINC 0x000fff00
+#define FLD_VBI2_HDELAY 0x000000ff
+
+/*****************************************************************************/
+#define VBI_CUST2_CFG2 0x45c
+#define FLD_VBI2_FC_LENGTH 0x1f000000
+#define FLD_VBI2_FRAME_CODE 0x00ffffff
+
+/*****************************************************************************/
+#define VBI_CUST2_CFG3 0x460
+#define FLD_VBI2_HAM_EN 0x80000000
+#define FLD_VBI2_FIFO_MODE 0x70000000
+#define FLD_VBI2_FORMAT_TYPE 0x0f000000
+#define FLD_VBI2_PAYLD_LENGTH 0x00ff0000
+#define FLD_VBI2_CRI_LENGTH 0x0000f000
+#define FLD_VBI2_CRI_MARGIN 0x00000f00
+#define FLD_VBI2_CRI_TIME 0x000000ff
+
+/*****************************************************************************/
+#define VBI_CUST3_CFG1 0x464
+/* Reserved [31] */
+#define FLD_VBI3_CRIWIN 0x7f000000
+#define FLD_VBI3_SLICE_DIST 0x00f00000
+#define FLD_VBI3_BITINC 0x000fff00
+#define FLD_VBI3_HDELAY 0x000000ff
+
+/*****************************************************************************/
+#define VBI_CUST3_CFG2 0x468
+#define FLD_VBI3_FC_LENGTH 0x1f000000
+#define FLD_VBI3_FRAME_CODE 0x00ffffff
+
+/*****************************************************************************/
+#define VBI_CUST3_CFG3 0x46c
+#define FLD_VBI3_HAM_EN 0x80000000
+#define FLD_VBI3_FIFO_MODE 0x70000000
+#define FLD_VBI3_FORMAT_TYPE 0x0f000000
+#define FLD_VBI3_PAYLD_LENGTH 0x00ff0000
+#define FLD_VBI3_CRI_LENGTH 0x0000f000
+#define FLD_VBI3_CRI_MARGIN 0x00000f00
+#define FLD_VBI3_CRI_TIME 0x000000ff
+
+/*****************************************************************************/
+#define HORIZ_TIM_CTRL 0x470
+#define FLD_BGDEL_CNT 0xff000000
+/* Reserved [23:22] */
+#define FLD_HACTIVE_CNT 0x003ff000
+/* Reserved [11:10] */
+#define FLD_HBLANK_CNT 0x000003ff
+
+/*****************************************************************************/
+#define VERT_TIM_CTRL 0x474
+#define FLD_V656BLANK_CNT 0xff000000
+/* Reserved [23:22] */
+#define FLD_VACTIVE_CNT 0x003ff000
+/* Reserved [11:10] */
+#define FLD_VBLANK_CNT 0x000003ff
+
+/*****************************************************************************/
+#define SRC_COMB_CFG 0x478
+#define FLD_CCOMB_2LN_CHECK 0x80000000
+#define FLD_CCOMB_3LN_EN 0x40000000
+#define FLD_CCOMB_2LN_EN 0x20000000
+#define FLD_CCOMB_3D_EN 0x10000000
+/* Reserved [27] */
+#define FLD_LCOMB_3LN_EN 0x04000000
+#define FLD_LCOMB_2LN_EN 0x02000000
+#define FLD_LCOMB_3D_EN 0x01000000
+#define FLD_LUMA_LPF_SEL 0x00c00000
+#define FLD_UV_LPF_SEL 0x00300000
+#define FLD_BLEND_SLOPE 0x000f0000
+#define FLD_CCOMB_REDUCE_EN 0x00008000
+/* Reserved [14:10] */
+#define FLD_SRC_DECIM_RATIO 0x000003ff
+
+/*****************************************************************************/
+#define CHROMA_VBIOFF_CFG 0x47c
+#define FLD_VBI_VOFFSET 0x1f000000
+/* Reserved [23:20] */
+#define FLD_SC_STEP 0x000fffff
+
+/*****************************************************************************/
+#define FIELD_COUNT 0x480
+#define FLD_FIELD_COUNT_FLD 0x000003ff
+
+/*****************************************************************************/
+#define MISC_TIM_CTRL 0x484
+#define FLD_DEBOUNCE_COUNT 0xc0000000
+#define FLD_VT_LINE_CNT_HYST 0x30000000
+/* Reserved [27] */
+#define FLD_AFD_STAT 0x07ff0000
+#define FLD_VPRES_VERT_EN 0x00008000
+/* Reserved [14:12] */
+#define FLD_HR32 0x00000800
+#define FLD_TDALGN 0x00000400
+#define FLD_TDFIELD 0x00000200
+/* Reserved [8:6] */
+#define FLD_TEMPDEC 0x0000003f
+
+/*****************************************************************************/
+#define DFE_CTRL1 0x488
+#define FLD_CLAMP_AUTO_EN 0x80000000
+#define FLD_AGC_AUTO_EN 0x40000000
+#define FLD_VGA_CRUSH_EN 0x20000000
+#define FLD_VGA_AUTO_EN 0x10000000
+#define FLD_VBI_GATE_EN 0x08000000
+#define FLD_CLAMP_LEVEL 0x07000000
+/* Reserved [23:22] */
+#define FLD_CLAMP_SKIP_CNT 0x00300000
+#define FLD_AGC_GAIN 0x000fff00
+/* Reserved [7:6] */
+#define FLD_VGA_GAIN 0x0000003f
+
+/*****************************************************************************/
+#define DFE_CTRL2 0x48c
+#define FLD_VGA_ACQUIRE_RANGE 0x00ff0000
+#define FLD_VGA_TRACK_RANGE 0x0000ff00
+#define FLD_VGA_SYNC 0x000000ff
+
+/*****************************************************************************/
+#define DFE_CTRL3 0x490
+#define FLD_BP_PERCENT 0xff000000
+#define FLD_DFT_THRESHOLD 0x00ff0000
+/* Reserved [15:12] */
+#define FLD_SYNC_WIDTH_SEL 0x00000600
+#define FLD_BP_LOOP_GAIN 0x00000300
+#define FLD_SYNC_LOOP_GAIN 0x000000c0
+/* Reserved [5:4] */
+#define FLD_AGC_LOOP_GAIN 0x0000000c
+#define FLD_DCC_LOOP_GAIN 0x00000003
+
+/*****************************************************************************/
+#define PLL_CTRL 0x494
+#define FLD_PLL_KD 0xff000000
+#define FLD_PLL_KI 0x00ff0000
+#define FLD_PLL_MAX_OFFSET 0x0000ffff
+
+/*****************************************************************************/
+#define HTL_CTRL 0x498
+/* Reserved [31:24] */
+#define FLD_AUTO_LOCK_SPD 0x00080000
+#define FLD_MAN_FAST_LOCK 0x00040000
+#define FLD_HTL_15K_EN 0x00020000
+#define FLD_HTL_500K_EN 0x00010000
+#define FLD_HTL_KD 0x0000ff00
+#define FLD_HTL_KI 0x000000ff
+
+/*****************************************************************************/
+#define COMB_CTRL 0x49c
+#define FLD_COMB_PHASE_LIMIT 0xff000000
+#define FLD_CCOMB_ERR_LIMIT 0x00ff0000
+#define FLD_LUMA_THRESHOLD 0x0000ff00
+#define FLD_LCOMB_ERR_LIMIT 0x000000ff
+
+/*****************************************************************************/
+#define CRUSH_CTRL 0x4a0
+#define FLD_WTW_EN 0x00400000
+#define FLD_CRUSH_FREQ 0x00200000
+#define FLD_MAJ_SEL_EN 0x00100000
+#define FLD_MAJ_SEL 0x000c0000
+/* Reserved [17:15] */
+#define FLD_SYNC_TIP_REDUCE 0x00007e00
+/* Reserved [8:6] */
+#define FLD_SYNC_TIP_INC 0x0000003f
+
+/*****************************************************************************/
+#define SOFT_RST_CTRL 0x4a4
+#define FLD_VD_SOFT_RST 0x00008000
+/* Reserved [14:12] */
+#define FLD_REG_RST_MSK 0x00000800
+#define FLD_VOF_RST_MSK 0x00000400
+#define FLD_MVDET_RST_MSK 0x00000200
+#define FLD_VBI_RST_MSK 0x00000100
+#define FLD_SCALE_RST_MSK 0x00000080
+#define FLD_CHROMA_RST_MSK 0x00000040
+#define FLD_LUMA_RST_MSK 0x00000020
+#define FLD_VTG_RST_MSK 0x00000010
+#define FLD_YCSEP_RST_MSK 0x00000008
+#define FLD_SRC_RST_MSK 0x00000004
+#define FLD_DFE_RST_MSK 0x00000002
+/* Reserved [0] */
+
+/*****************************************************************************/
+#define MV_DT_CTRL1 0x4a8
+/* Reserved [31:29] */
+#define FLD_PSP_STOP_LINE 0x1f000000
+/* Reserved [23:21] */
+#define FLD_PSP_STRT_LINE 0x001f0000
+/* Reserved [15] */
+#define FLD_PSP_LLIMW 0x00007f00
+/* Reserved [7] */
+#define FLD_PSP_ULIMW 0x0000007f
+
+/*****************************************************************************/
+#define MV_DT_CTRL2 0x4aC
+#define FLD_CS_STOPWIN 0xff000000
+#define FLD_CS_STRTWIN 0x00ff0000
+#define FLD_CS_WIDTH 0x0000ff00
+#define FLD_PSP_SPEC_VAL 0x000000ff
+
+/*****************************************************************************/
+#define MV_DT_CTRL3 0x4B0
+#define FLD_AUTO_RATE_DIS 0x80000000
+#define FLD_HLOCK_DIS 0x40000000
+#define FLD_SEL_FIELD_CNT 0x20000000
+#define FLD_CS_TYPE2_SEL 0x10000000
+#define FLD_CS_LINE_THRSH_SEL 0x08000000
+#define FLD_CS_ATHRESH_SEL 0x04000000
+#define FLD_PSP_SPEC_SEL 0x02000000
+#define FLD_PSP_LINES_SEL 0x01000000
+#define FLD_FIELD_CNT 0x00f00000
+#define FLD_CS_TYPE2_CNT 0x000fc000
+#define FLD_CS_LINE_CNT 0x00003f00
+#define FLD_CS_ATHRESH_LEV 0x000000ff
+
+/*****************************************************************************/
+#define CHIP_VERSION 0x4b4
+/* Cx231xx redefine */
+#define VERSION 0x4b4
+#define FLD_REV_ID 0x000000ff
+
+/*****************************************************************************/
+#define MISC_DIAG_CTRL 0x4b8
+/* Reserved [31:24] */
+#define FLD_SC_CONVERGE_THRESH 0x00ff0000
+#define FLD_CCOMB_ERR_LIMIT_3D 0x0000ff00
+#define FLD_LCOMB_ERR_LIMIT_3D 0x000000ff
+
+/*****************************************************************************/
+#define VBI_PASS_CTRL 0x4bc
+#define FLD_VBI_PASS_MD 0x00200000
+#define FLD_VBI_SETUP_DIS 0x00100000
+#define FLD_PASS_LINE_CTRL 0x000fffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define VCR_DET_CTRL 0x4c0
+#define FLD_EN_FIELD_PHASE_DET 0x80000000
+#define FLD_EN_HEAD_SW_DET 0x40000000
+#define FLD_FIELD_PHASE_LENGTH 0x01ff0000
+/* Reserved [29:25] */
+#define FLD_FIELD_PHASE_DELAY 0x0000ff00
+#define FLD_FIELD_PHASE_LIMIT 0x000000f0
+#define FLD_HEAD_SW_DET_LIMIT 0x0000000f
+
+/*****************************************************************************/
+#define DL_CTL 0x800
+#define DL_CTL_ADDRESS_LOW 0x800 /* Byte 1 in DL_CTL */
+#define DL_CTL_ADDRESS_HIGH 0x801 /* Byte 2 in DL_CTL */
+#define DL_CTL_DATA 0x802 /* Byte 3 in DL_CTL */
+#define DL_CTL_CONTROL 0x803 /* Byte 4 in DL_CTL */
+/* Reserved [31:5] */
+#define FLD_START_8051 0x10000000
+#define FLD_DL_ENABLE 0x08000000
+#define FLD_DL_AUTO_INC 0x04000000
+#define FLD_DL_MAP 0x03000000
+
+/*****************************************************************************/
+#define STD_DET_STATUS 0x804
+#define FLD_SPARE_STATUS1 0xff000000
+#define FLD_SPARE_STATUS0 0x00ff0000
+#define FLD_MOD_DET_STATUS1 0x0000ff00
+#define FLD_MOD_DET_STATUS0 0x000000ff
+
+/*****************************************************************************/
+#define AUD_BUILD_NUM 0x806
+#define AUD_VER_NUM 0x807
+#define STD_DET_CTL 0x808
+#define STD_DET_CTL_AUD_CTL 0x808 /* Byte 1 in STD_DET_CTL */
+#define STD_DET_CTL_PREF_MODE 0x809 /* Byte 2 in STD_DET_CTL */
+#define FLD_SPARE_CTL0 0xff000000
+#define FLD_DIS_DBX 0x00800000
+#define FLD_DIS_BTSC 0x00400000
+#define FLD_DIS_NICAM_A2 0x00200000
+#define FLD_VIDEO_PRESENT 0x00100000
+#define FLD_DW8051_VIDEO_FORMAT 0x000f0000
+#define FLD_PREF_DEC_MODE 0x0000ff00
+#define FLD_AUD_CONFIG 0x000000ff
+
+/*****************************************************************************/
+#define DW8051_INT 0x80c
+#define FLD_VIDEO_PRESENT_CHANGE 0x80000000
+#define FLD_VIDEO_CHANGE 0x40000000
+#define FLD_RDS_READY 0x20000000
+#define FLD_AC97_INT 0x10000000
+#define FLD_NICAM_BIT_ERROR_TOO_HIGH 0x08000000
+#define FLD_NICAM_LOCK 0x04000000
+#define FLD_NICAM_UNLOCK 0x02000000
+#define FLD_DFT4_TH_CMP 0x01000000
+/* Reserved [23:22] */
+#define FLD_LOCK_IND_INT 0x00200000
+#define FLD_DFT3_TH_CMP 0x00100000
+#define FLD_DFT2_TH_CMP 0x00080000
+#define FLD_DFT1_TH_CMP 0x00040000
+#define FLD_FM2_DFT_TH_CMP 0x00020000
+#define FLD_FM1_DFT_TH_CMP 0x00010000
+#define FLD_VIDEO_PRESENT_EN 0x00008000
+#define FLD_VIDEO_CHANGE_EN 0x00004000
+#define FLD_RDS_READY_EN 0x00002000
+#define FLD_AC97_INT_EN 0x00001000
+#define FLD_NICAM_BIT_ERROR_TOO_HIGH_EN 0x00000800
+#define FLD_NICAM_LOCK_EN 0x00000400
+#define FLD_NICAM_UNLOCK_EN 0x00000200
+#define FLD_DFT4_TH_CMP_EN 0x00000100
+/* Reserved [7] */
+#define FLD_DW8051_INT6_CTL1 0x00000040
+#define FLD_DW8051_INT5_CTL1 0x00000020
+#define FLD_DW8051_INT4_CTL1 0x00000010
+#define FLD_DW8051_INT3_CTL1 0x00000008
+#define FLD_DW8051_INT2_CTL1 0x00000004
+#define FLD_DW8051_INT1_CTL1 0x00000002
+#define FLD_DW8051_INT0_CTL1 0x00000001
+
+/*****************************************************************************/
+#define GENERAL_CTL 0x810
+#define FLD_RDS_INT 0x80000000
+#define FLD_NBER_INT 0x40000000
+#define FLD_NLL_INT 0x20000000
+#define FLD_IFL_INT 0x10000000
+#define FLD_FDL_INT 0x08000000
+#define FLD_AFC_INT 0x04000000
+#define FLD_AMC_INT 0x02000000
+#define FLD_AC97_INT_CTL 0x01000000
+#define FLD_RDS_INT_DIS 0x00800000
+#define FLD_NBER_INT_DIS 0x00400000
+#define FLD_NLL_INT_DIS 0x00200000
+#define FLD_IFL_INT_DIS 0x00100000
+#define FLD_FDL_INT_DIS 0x00080000
+#define FLD_FC_INT_DIS 0x00040000
+#define FLD_AMC_INT_DIS 0x00020000
+#define FLD_AC97_INT_DIS 0x00010000
+#define FLD_REV_NUM 0x0000ff00
+/* Reserved [7:5] */
+#define FLD_DBX_SOFT_RESET_REG 0x00000010
+#define FLD_AD_SOFT_RESET_REG 0x00000008
+#define FLD_SRC_SOFT_RESET_REG 0x00000004
+#define FLD_CDMOD_SOFT_RESET 0x00000002
+#define FLD_8051_SOFT_RESET 0x00000001
+
+/*****************************************************************************/
+#define AAGC_CTL 0x814
+#define FLD_AFE_12DB_EN 0x80000000
+#define FLD_AAGC_DEFAULT_EN 0x40000000
+#define FLD_AAGC_DEFAULT 0x3f000000
+/* Reserved [23] */
+#define FLD_AAGC_GAIN 0x00600000
+#define FLD_AAGC_TH 0x001f0000
+/* Reserved [15:14] */
+#define FLD_AAGC_HYST2 0x00003f00
+/* Reserved [7:6] */
+#define FLD_AAGC_HYST1 0x0000003f
+
+/*****************************************************************************/
+#define IF_SRC_CTL 0x818
+#define FLD_DBX_BYPASS 0x80000000
+/* Reserved [30:25] */
+#define FLD_IF_SRC_MODE 0x01000000
+/* Reserved [23:18] */
+#define FLD_IF_SRC_PHASE_INC 0x0001ffff
+
+/*****************************************************************************/
+#define ANALOG_DEMOD_CTL 0x81c
+#define FLD_ROT1_PHACC_PROG 0xffff0000
+/* Reserved [15] */
+#define FLD_FM1_DELAY_FIX 0x00007000
+#define FLD_PDF4_SHIFT 0x00000c00
+#define FLD_PDF3_SHIFT 0x00000300
+#define FLD_PDF2_SHIFT 0x000000c0
+#define FLD_PDF1_SHIFT 0x00000030
+#define FLD_FMBYPASS_MODE2 0x00000008
+#define FLD_FMBYPASS_MODE1 0x00000004
+#define FLD_NICAM_MODE 0x00000002
+#define FLD_BTSC_FMRADIO_MODE 0x00000001
+
+/*****************************************************************************/
+#define ROT_FREQ_CTL 0x820
+#define FLD_ROT3_PHACC_PROG 0xffff0000
+#define FLD_ROT2_PHACC_PROG 0x0000ffff
+
+/*****************************************************************************/
+#define FM_CTL 0x824
+#define FLD_FM2_DC_FB_SHIFT 0xf0000000
+#define FLD_FM2_DC_INT_SHIFT 0x0f000000
+#define FLD_FM2_AFC_RESET 0x00800000
+#define FLD_FM2_DC_PASS_IN 0x00400000
+#define FLD_FM2_DAGC_SHIFT 0x00380000
+#define FLD_FM2_CORDIC_SHIFT 0x00070000
+#define FLD_FM1_DC_FB_SHIFT 0x0000f000
+#define FLD_FM1_DC_INT_SHIFT 0x00000f00
+#define FLD_FM1_AFC_RESET 0x00000080
+#define FLD_FM1_DC_PASS_IN 0x00000040
+#define FLD_FM1_DAGC_SHIFT 0x00000038
+#define FLD_FM1_CORDIC_SHIFT 0x00000007
+
+/*****************************************************************************/
+#define LPF_PDF_CTL 0x828
+/* Reserved [31:30] */
+#define FLD_LPF32_SHIFT1 0x30000000
+#define FLD_LPF32_SHIFT2 0x0c000000
+#define FLD_LPF160_SHIFTA 0x03000000
+#define FLD_LPF160_SHIFTB 0x00c00000
+#define FLD_LPF160_SHIFTC 0x00300000
+#define FLD_LPF32_COEF_SEL2 0x000c0000
+#define FLD_LPF32_COEF_SEL1 0x00030000
+#define FLD_LPF160_COEF_SELC 0x0000c000
+#define FLD_LPF160_COEF_SELB 0x00003000
+#define FLD_LPF160_COEF_SELA 0x00000c00
+#define FLD_LPF160_IN_EN_REG 0x00000300
+#define FLD_PDF4_PDF_SEL 0x000000c0
+#define FLD_PDF3_PDF_SEL 0x00000030
+#define FLD_PDF2_PDF_SEL 0x0000000c
+#define FLD_PDF1_PDF_SEL 0x00000003
+
+/*****************************************************************************/
+#define DFT1_CTL1 0x82c
+#define FLD_DFT1_DWELL 0xffff0000
+#define FLD_DFT1_FREQ 0x0000ffff
+
+/*****************************************************************************/
+#define DFT1_CTL2 0x830
+#define FLD_DFT1_THRESHOLD 0xffffff00
+#define FLD_DFT1_CMP_CTL 0x00000080
+#define FLD_DFT1_AVG 0x00000070
+/* Reserved [3:1] */
+#define FLD_DFT1_START 0x00000001
+
+/*****************************************************************************/
+#define DFT1_STATUS 0x834
+#define FLD_DFT1_DONE 0x80000000
+#define FLD_DFT1_TH_CMP_STAT 0x40000000
+#define FLD_DFT1_RESULT 0x3fffffff
+
+/*****************************************************************************/
+#define DFT2_CTL1 0x838
+#define FLD_DFT2_DWELL 0xffff0000
+#define FLD_DFT2_FREQ 0x0000ffff
+
+/*****************************************************************************/
+#define DFT2_CTL2 0x83C
+#define FLD_DFT2_THRESHOLD 0xffffff00
+#define FLD_DFT2_CMP_CTL 0x00000080
+#define FLD_DFT2_AVG 0x00000070
+/* Reserved [3:1] */
+#define FLD_DFT2_START 0x00000001
+
+/*****************************************************************************/
+#define DFT2_STATUS 0x840
+#define FLD_DFT2_DONE 0x80000000
+#define FLD_DFT2_TH_CMP_STAT 0x40000000
+#define FLD_DFT2_RESULT 0x3fffffff
+
+/*****************************************************************************/
+#define DFT3_CTL1 0x844
+#define FLD_DFT3_DWELL 0xffff0000
+#define FLD_DFT3_FREQ 0x0000ffff
+
+/*****************************************************************************/
+#define DFT3_CTL2 0x848
+#define FLD_DFT3_THRESHOLD 0xffffff00
+#define FLD_DFT3_CMP_CTL 0x00000080
+#define FLD_DFT3_AVG 0x00000070
+/* Reserved [3:1] */
+#define FLD_DFT3_START 0x00000001
+
+/*****************************************************************************/
+#define DFT3_STATUS 0x84c
+#define FLD_DFT3_DONE 0x80000000
+#define FLD_DFT3_TH_CMP_STAT 0x40000000
+#define FLD_DFT3_RESULT 0x3fffffff
+
+/*****************************************************************************/
+#define DFT4_CTL1 0x850
+#define FLD_DFT4_DWELL 0xffff0000
+#define FLD_DFT4_FREQ 0x0000ffff
+
+/*****************************************************************************/
+#define DFT4_CTL2 0x854
+#define FLD_DFT4_THRESHOLD 0xffffff00
+#define FLD_DFT4_CMP_CTL 0x00000080
+#define FLD_DFT4_AVG 0x00000070
+/* Reserved [3:1] */
+#define FLD_DFT4_START 0x00000001
+
+/*****************************************************************************/
+#define DFT4_STATUS 0x858
+#define FLD_DFT4_DONE 0x80000000
+#define FLD_DFT4_TH_CMP_STAT 0x40000000
+#define FLD_DFT4_RESULT 0x3fffffff
+
+/*****************************************************************************/
+#define AM_MTS_DET 0x85c
+#define FLD_AM_MTS_MODE 0x80000000
+/* Reserved [30:26] */
+#define FLD_AM_SUB 0x02000000
+#define FLD_AM_GAIN_EN 0x01000000
+/* Reserved [23:16] */
+#define FLD_AMMTS_GAIN_SCALE 0x0000e000
+#define FLD_MTS_PDF_SHIFT 0x00001800
+#define FLD_AM_REG_GAIN 0x00000700
+#define FLD_AGC_REF 0x000000ff
+
+/*****************************************************************************/
+#define ANALOG_MUX_CTL 0x860
+/* Reserved [31:29] */
+#define FLD_MUX21_SEL 0x10000000
+#define FLD_MUX20_SEL 0x08000000
+#define FLD_MUX19_SEL 0x04000000
+#define FLD_MUX18_SEL 0x02000000
+#define FLD_MUX17_SEL 0x01000000
+#define FLD_MUX16_SEL 0x00800000
+#define FLD_MUX15_SEL 0x00400000
+#define FLD_MUX14_SEL 0x00300000
+#define FLD_MUX13_SEL 0x000C0000
+#define FLD_MUX12_SEL 0x00020000
+#define FLD_MUX11_SEL 0x00018000
+#define FLD_MUX10_SEL 0x00004000
+#define FLD_MUX9_SEL 0x00002000
+#define FLD_MUX8_SEL 0x00001000
+#define FLD_MUX7_SEL 0x00000800
+#define FLD_MUX6_SEL 0x00000600
+#define FLD_MUX5_SEL 0x00000100
+#define FLD_MUX4_SEL 0x000000c0
+#define FLD_MUX3_SEL 0x00000030
+#define FLD_MUX2_SEL 0x0000000c
+#define FLD_MUX1_SEL 0x00000003
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define DPLL_CTRL1 0x864
+#define DIG_PLL_CTL1 0x864
+
+#define FLD_PLL_STATUS 0x07000000
+#define FLD_BANDWIDTH_SELECT 0x00030000
+#define FLD_PLL_SHIFT_REG 0x00007000
+#define FLD_PHASE_SHIFT 0x000007ff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define DPLL_CTRL2 0x868
+#define DIG_PLL_CTL2 0x868
+#define FLD_PLL_UNLOCK_THR 0xff000000
+#define FLD_PLL_LOCK_THR 0x00ff0000
+/* Reserved [15:8] */
+#define FLD_AM_PDF_SEL2 0x000000c0
+#define FLD_AM_PDF_SEL1 0x00000030
+#define FLD_DPLL_FSM_CTRL 0x0000000c
+/* Reserved [1] */
+#define FLD_PLL_PILOT_DET 0x00000001
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define DPLL_CTRL3 0x86c
+#define DIG_PLL_CTL3 0x86c
+#define FLD_DISABLE_LOOP 0x01000000
+#define FLD_A1_DS1_SEL 0x000c0000
+#define FLD_A1_DS2_SEL 0x00030000
+#define FLD_A1_KI 0x0000ff00
+#define FLD_A1_KD 0x000000ff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define DPLL_CTRL4 0x870
+#define DIG_PLL_CTL4 0x870
+#define FLD_A2_DS1_SEL 0x000c0000
+#define FLD_A2_DS2_SEL 0x00030000
+#define FLD_A2_KI 0x0000ff00
+#define FLD_A2_KD 0x000000ff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define DPLL_CTRL5 0x874
+#define DIG_PLL_CTL5 0x874
+#define FLD_TRK_DS1_SEL 0x000c0000
+#define FLD_TRK_DS2_SEL 0x00030000
+#define FLD_TRK_KI 0x0000ff00
+#define FLD_TRK_KD 0x000000ff
+
+/*****************************************************************************/
+#define DEEMPH_GAIN_CTL 0x878
+#define FLD_DEEMPH2_GAIN 0xFFFF0000
+#define FLD_DEEMPH1_GAIN 0x0000FFFF
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define DEEMPH_COEFF1 0x87c
+#define DEEMPH_COEF1 0x87c
+#define FLD_DEEMPH_B0 0xffff0000
+#define FLD_DEEMPH_A0 0x0000ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define DEEMPH_COEFF2 0x880
+#define DEEMPH_COEF2 0x880
+#define FLD_DEEMPH_B1 0xFFFF0000
+#define FLD_DEEMPH_A1 0x0000FFFF
+
+/*****************************************************************************/
+#define DBX1_CTL1 0x884
+#define FLD_DBX1_WBE_GAIN 0xffff0000
+#define FLD_DBX1_IN_GAIN 0x0000ffff
+
+/*****************************************************************************/
+#define DBX1_CTL2 0x888
+#define FLD_DBX1_SE_BYPASS 0xffff0000
+#define FLD_DBX1_SE_GAIN 0x0000ffff
+
+/*****************************************************************************/
+#define DBX1_RMS_SE 0x88C
+#define FLD_DBX1_RMS_WBE 0xffff0000
+#define FLD_DBX1_RMS_SE_FLD 0x0000ffff
+
+/*****************************************************************************/
+#define DBX2_CTL1 0x890
+#define FLD_DBX2_WBE_GAIN 0xffff0000
+#define FLD_DBX2_IN_GAIN 0x0000ffff
+
+/*****************************************************************************/
+#define DBX2_CTL2 0x894
+#define FLD_DBX2_SE_BYPASS 0xffff0000
+#define FLD_DBX2_SE_GAIN 0x0000ffff
+
+/*****************************************************************************/
+#define DBX2_RMS_SE 0x898
+#define FLD_DBX2_RMS_WBE 0xffff0000
+#define FLD_DBX2_RMS_SE_FLD 0x0000ffff
+
+/*****************************************************************************/
+#define AM_FM_DIFF 0x89c
+/* Reserved [31] */
+#define FLD_FM_DIFF_OUT 0x7fff0000
+/* Reserved [15] */
+#define FLD_AM_DIFF_OUT 0x00007fff
+
+/*****************************************************************************/
+#define NICAM_FAW 0x8a0
+#define FLD_FAWDETWINEND 0xFc000000
+#define FLD_FAWDETWINSTR 0x03ff0000
+/* Reserved [15:12] */
+#define FLD_FAWDETTHRSHLD3 0x00000f00
+#define FLD_FAWDETTHRSHLD2 0x000000f0
+#define FLD_FAWDETTHRSHLD1 0x0000000f
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define DEEMPH_GAIN 0x8a4
+#define NICAM_DEEMPHGAIN 0x8a4
+/* Reserved [31:18] */
+#define FLD_DEEMPHGAIN 0x0003ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define DEEMPH_NUMER1 0x8a8
+#define NICAM_DEEMPHNUMER1 0x8a8
+/* Reserved [31:18] */
+#define FLD_DEEMPHNUMER1 0x0003ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define DEEMPH_NUMER2 0x8ac
+#define NICAM_DEEMPHNUMER2 0x8ac
+/* Reserved [31:18] */
+#define FLD_DEEMPHNUMER2 0x0003ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define DEEMPH_DENOM1 0x8b0
+#define NICAM_DEEMPHDENOM1 0x8b0
+/* Reserved [31:18] */
+#define FLD_DEEMPHDENOM1 0x0003ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define DEEMPH_DENOM2 0x8b4
+#define NICAM_DEEMPHDENOM2 0x8b4
+/* Reserved [31:18] */
+#define FLD_DEEMPHDENOM2 0x0003ffff
+
+/*****************************************************************************/
+#define NICAM_ERRLOG_CTL1 0x8B8
+/* Reserved [31:28] */
+#define FLD_ERRINTRPTTHSHLD1 0x0fff0000
+/* Reserved [15:12] */
+#define FLD_ERRLOGPERIOD 0x00000fff
+
+/*****************************************************************************/
+#define NICAM_ERRLOG_CTL2 0x8bc
+/* Reserved [31:28] */
+#define FLD_ERRINTRPTTHSHLD3 0x0fff0000
+/* Reserved [15:12] */
+#define FLD_ERRINTRPTTHSHLD2 0x00000fff
+
+/*****************************************************************************/
+#define NICAM_ERRLOG_STS1 0x8c0
+/* Reserved [31:28] */
+#define FLD_ERRLOG2 0x0fff0000
+/* Reserved [15:12] */
+#define FLD_ERRLOG1 0x00000fff
+
+/*****************************************************************************/
+#define NICAM_ERRLOG_STS2 0x8c4
+/* Reserved [31:12] */
+#define FLD_ERRLOG3 0x00000fff
+
+/*****************************************************************************/
+#define NICAM_STATUS 0x8c8
+/* Reserved [31:20] */
+#define FLD_NICAM_CIB 0x000c0000
+#define FLD_NICAM_LOCK_STAT 0x00020000
+#define FLD_NICAM_MUTE 0x00010000
+#define FLD_NICAMADDIT_DATA 0x0000ffe0
+#define FLD_NICAMCNTRL 0x0000001f
+
+/*****************************************************************************/
+#define DEMATRIX_CTL 0x8cc
+#define FLD_AC97_IN_SHIFT 0xf0000000
+#define FLD_I2S_IN_SHIFT 0x0f000000
+#define FLD_DEMATRIX_SEL_CTL 0x00ff0000
+/* Reserved [15:11] */
+#define FLD_DMTRX_BYPASS 0x00000400
+#define FLD_DEMATRIX_MODE 0x00000300
+/* Reserved [7:6] */
+#define FLD_PH_DBX_SEL 0x00000020
+#define FLD_PH_CH_SEL 0x00000010
+#define FLD_PHASE_FIX 0x0000000f
+
+/*****************************************************************************/
+#define PATH1_CTL1 0x8d0
+/* Reserved [31:29] */
+#define FLD_PATH1_MUTE_CTL 0x1f000000
+/* Reserved [23:22] */
+#define FLD_PATH1_AVC_CG 0x00300000
+#define FLD_PATH1_AVC_RT 0x000f0000
+#define FLD_PATH1_AVC_AT 0x0000f000
+#define FLD_PATH1_AVC_STEREO 0x00000800
+#define FLD_PATH1_AVC_CR 0x00000700
+#define FLD_PATH1_AVC_RMS_CON 0x000000f0
+#define FLD_PATH1_SEL_CTL 0x0000000f
+
+/*****************************************************************************/
+#define PATH1_VOL_CTL 0x8d4
+#define FLD_PATH1_AVC_THRESHOLD 0x7fff0000
+#define FLD_PATH1_BAL_LEFT 0x00008000
+#define FLD_PATH1_BAL_LEVEL 0x00007f00
+#define FLD_PATH1_VOLUME 0x000000ff
+
+/*****************************************************************************/
+#define PATH1_EQ_CTL 0x8d8
+/* Reserved [31:30] */
+#define FLD_PATH1_EQ_TREBLE_VOL 0x3f000000
+/* Reserved [23:22] */
+#define FLD_PATH1_EQ_MID_VOL 0x003f0000
+/* Reserved [15:14] */
+#define FLD_PATH1_EQ_BASS_VOL 0x00003f00
+/* Reserved [7:1] */
+#define FLD_PATH1_EQ_BAND_SEL 0x00000001
+
+/*****************************************************************************/
+#define PATH1_SC_CTL 0x8dc
+#define FLD_PATH1_SC_THRESHOLD 0x7fff0000
+#define FLD_PATH1_SC_RT 0x0000f000
+#define FLD_PATH1_SC_AT 0x00000f00
+#define FLD_PATH1_SC_STEREO 0x00000080
+#define FLD_PATH1_SC_CR 0x00000070
+#define FLD_PATH1_SC_RMS_CON 0x0000000f
+
+/*****************************************************************************/
+#define PATH2_CTL1 0x8e0
+/* Reserved [31:26] */
+#define FLD_PATH2_MUTE_CTL 0x03000000
+/* Reserved [23:22] */
+#define FLD_PATH2_AVC_CG 0x00300000
+#define FLD_PATH2_AVC_RT 0x000f0000
+#define FLD_PATH2_AVC_AT 0x0000f000
+#define FLD_PATH2_AVC_STEREO 0x00000800
+#define FLD_PATH2_AVC_CR 0x00000700
+#define FLD_PATH2_AVC_RMS_CON 0x000000f0
+#define FLD_PATH2_SEL_CTL 0x0000000f
+
+/*****************************************************************************/
+#define PATH2_VOL_CTL 0x8e4
+#define FLD_PATH2_AVC_THRESHOLD 0xffff0000
+#define FLD_PATH2_BAL_LEFT 0x00008000
+#define FLD_PATH2_BAL_LEVEL 0x00007f00
+#define FLD_PATH2_VOLUME 0x000000ff
+
+/*****************************************************************************/
+#define PATH2_EQ_CTL 0x8e8
+/* Reserved [31:30] */
+#define FLD_PATH2_EQ_TREBLE_VOL 0x3f000000
+/* Reserved [23:22] */
+#define FLD_PATH2_EQ_MID_VOL 0x003f0000
+/* Reserved [15:14] */
+#define FLD_PATH2_EQ_BASS_VOL 0x00003f00
+/* Reserved [7:1] */
+#define FLD_PATH2_EQ_BAND_SEL 0x00000001
+
+/*****************************************************************************/
+#define PATH2_SC_CTL 0x8eC
+#define FLD_PATH2_SC_THRESHOLD 0xffff0000
+#define FLD_PATH2_SC_RT 0x0000f000
+#define FLD_PATH2_SC_AT 0x00000f00
+#define FLD_PATH2_SC_STEREO 0x00000080
+#define FLD_PATH2_SC_CR 0x00000070
+#define FLD_PATH2_SC_RMS_CON 0x0000000f
+
+/*****************************************************************************/
+#define SRC_CTL 0x8f0
+#define FLD_SRC_STATUS 0xffffff00
+#define FLD_FIFO_LF_EN 0x000000fc
+#define FLD_BYPASS_LI 0x00000002
+#define FLD_BYPASS_PF 0x00000001
+
+/*****************************************************************************/
+#define SRC_LF_COEF 0x8f4
+#define FLD_LOOP_FILTER_COEF2 0xffff0000
+#define FLD_LOOP_FILTER_COEF1 0x0000ffff
+
+/*****************************************************************************/
+#define SRC1_CTL 0x8f8
+/* Reserved [31:28] */
+#define FLD_SRC1_FIFO_RD_TH 0x0f000000
+/* Reserved [23:18] */
+#define FLD_SRC1_PHASE_INC 0x0003ffff
+
+/*****************************************************************************/
+#define SRC2_CTL 0x8fc
+/* Reserved [31:28] */
+#define FLD_SRC2_FIFO_RD_TH 0x0f000000
+/* Reserved [23:18] */
+#define FLD_SRC2_PHASE_INC 0x0003ffff
+
+/*****************************************************************************/
+#define SRC3_CTL 0x900
+/* Reserved [31:28] */
+#define FLD_SRC3_FIFO_RD_TH 0x0f000000
+/* Reserved [23:18] */
+#define FLD_SRC3_PHASE_INC 0x0003ffff
+
+/*****************************************************************************/
+#define SRC4_CTL 0x904
+/* Reserved [31:28] */
+#define FLD_SRC4_FIFO_RD_TH 0x0f000000
+/* Reserved [23:18] */
+#define FLD_SRC4_PHASE_INC 0x0003ffff
+
+/*****************************************************************************/
+#define SRC5_CTL 0x908
+/* Reserved [31:28] */
+#define FLD_SRC5_FIFO_RD_TH 0x0f000000
+/* Reserved [23:18] */
+#define FLD_SRC5_PHASE_INC 0x0003ffff
+
+/*****************************************************************************/
+#define SRC6_CTL 0x90c
+/* Reserved [31:28] */
+#define FLD_SRC6_FIFO_RD_TH 0x0f000000
+/* Reserved [23:18] */
+#define FLD_SRC6_PHASE_INC 0x0003ffff
+
+/*****************************************************************************/
+#define BAND_OUT_SEL 0x910
+#define FLD_SRC6_IN_SEL 0xc0000000
+#define FLD_SRC6_CLK_SEL 0x30000000
+#define FLD_SRC5_IN_SEL 0x0c000000
+#define FLD_SRC5_CLK_SEL 0x03000000
+#define FLD_SRC4_IN_SEL 0x00c00000
+#define FLD_SRC4_CLK_SEL 0x00300000
+#define FLD_SRC3_IN_SEL 0x000c0000
+#define FLD_SRC3_CLK_SEL 0x00030000
+#define FLD_BASEBAND_BYPASS_CTL 0x0000ff00
+#define FLD_AC97_SRC_SEL 0x000000c0
+#define FLD_I2S_SRC_SEL 0x00000030
+#define FLD_PARALLEL2_SRC_SEL 0x0000000c
+#define FLD_PARALLEL1_SRC_SEL 0x00000003
+
+/*****************************************************************************/
+#define I2S_IN_CTL 0x914
+/* Reserved [31:11] */
+#define FLD_I2S_UP2X_BW20K 0x00000400
+#define FLD_I2S_UP2X_BYPASS 0x00000200
+#define FLD_I2S_IN_MASTER_MODE 0x00000100
+#define FLD_I2S_IN_SONY_MODE 0x00000080
+#define FLD_I2S_IN_RIGHT_JUST 0x00000040
+#define FLD_I2S_IN_WS_SEL 0x00000020
+#define FLD_I2S_IN_BCN_DEL 0x0000001f
+
+/*****************************************************************************/
+#define I2S_OUT_CTL 0x918
+/* Reserved [31:17] */
+#define FLD_I2S_OUT_SOFT_RESET_EN 0x00010000
+/* Reserved [15:9] */
+#define FLD_I2S_OUT_MASTER_MODE 0x00000100
+#define FLD_I2S_OUT_SONY_MODE 0x00000080
+#define FLD_I2S_OUT_RIGHT_JUST 0x00000040
+#define FLD_I2S_OUT_WS_SEL 0x00000020
+#define FLD_I2S_OUT_BCN_DEL 0x0000001f
+
+/*****************************************************************************/
+#define AC97_CTL 0x91c
+/* Reserved [31:26] */
+#define FLD_AC97_UP2X_BW20K 0x02000000
+#define FLD_AC97_UP2X_BYPASS 0x01000000
+/* Reserved [23:17] */
+#define FLD_AC97_RST_ACL 0x00010000
+/* Reserved [15:9] */
+#define FLD_AC97_WAKE_UP_SYNC 0x00000100
+/* Reserved [7:1] */
+#define FLD_AC97_SHUTDOWN 0x00000001
+
+/* Cx231xx redefine */
+#define QPSK_IAGC_CTL1 0x94c
+#define QPSK_IAGC_CTL2 0x950
+#define QPSK_FEPR_FREQ 0x954
+#define QPSK_BTL_CTL1 0x958
+#define QPSK_BTL_CTL2 0x95c
+#define QPSK_CTL_CTL1 0x960
+#define QPSK_CTL_CTL2 0x964
+#define QPSK_MF_FAGC_CTL 0x968
+#define QPSK_EQ_CTL 0x96c
+#define QPSK_LOCK_CTL 0x970
+
+/*****************************************************************************/
+#define FM1_DFT_CTL 0x9a8
+#define FLD_FM1_DFT_THRESHOLD 0xffff0000
+/* Reserved [15:8] */
+#define FLD_FM1_DFT_CMP_CTL 0x00000080
+#define FLD_FM1_DFT_AVG 0x00000070
+/* Reserved [3:1] */
+#define FLD_FM1_DFT_START 0x00000001
+
+/*****************************************************************************/
+#define FM1_DFT_STATUS 0x9ac
+#define FLD_FM1_DFT_DONE 0x80000000
+/* Reserved [30:19] */
+#define FLD_FM_DFT_TH_CMP 0x00040000
+#define FLD_FM1_DFT 0x0003ffff
+
+/*****************************************************************************/
+#define FM2_DFT_CTL 0x9b0
+#define FLD_FM2_DFT_THRESHOLD 0xffff0000
+/* Reserved [15:8] */
+#define FLD_FM2_DFT_CMP_CTL 0x00000080
+#define FLD_FM2_DFT_AVG 0x00000070
+/* Reserved [3:1] */
+#define FLD_FM2_DFT_START 0x00000001
+
+/*****************************************************************************/
+#define FM2_DFT_STATUS 0x9b4
+#define FLD_FM2_DFT_DONE 0x80000000
+/* Reserved [30:19] */
+#define FLD_FM2_DFT_TH_CMP_STAT 0x00040000
+#define FLD_FM2_DFT 0x0003ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define AAGC_STATUS_REG 0x9b8
+#define AAGC_STATUS 0x9b8
+/* Reserved [31:27] */
+#define FLD_FM2_DAGC_OUT 0x07000000
+/* Reserved [23:19] */
+#define FLD_FM1_DAGC_OUT 0x00070000
+/* Reserved [15:6] */
+#define FLD_AFE_VGA_OUT 0x0000003f
+
+/*****************************************************************************/
+#define MTS_GAIN_STATUS 0x9bc
+/* Reserved [31:14] */
+#define FLD_MTS_GAIN 0x00003fff
+
+#define RDS_OUT 0x9c0
+#define FLD_RDS_Q 0xffff0000
+#define FLD_RDS_I 0x0000ffff
+
+/*****************************************************************************/
+#define AUTOCONFIG_REG 0x9c4
+/* Reserved [31:4] */
+#define FLD_AUTOCONFIG_MODE 0x0000000f
+
+#define FM_AFC 0x9c8
+#define FLD_FM2_AFC 0xffff0000
+#define FLD_FM1_AFC 0x0000ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define NEW_SPARE 0x9cc
+#define NEW_SPARE_REG 0x9cc
+
+/*****************************************************************************/
+#define DBX_ADJ 0x9d0
+/* Reserved [31:28] */
+#define FLD_DBX2_ADJ 0x0fff0000
+/* Reserved [15:12] */
+#define FLD_DBX1_ADJ 0x00000fff
+
+#define VID_FMT_AUTO 0
+#define VID_FMT_NTSC_M 1
+#define VID_FMT_NTSC_J 2
+#define VID_FMT_NTSC_443 3
+#define VID_FMT_PAL_BDGHI 4
+#define VID_FMT_PAL_M 5
+#define VID_FMT_PAL_N 6
+#define VID_FMT_PAL_NC 7
+#define VID_FMT_PAL_60 8
+#define VID_FMT_SECAM 12
+#define VID_FMT_SECAM_60 13
+
+#define INPUT_MODE_CVBS_0 0 /* INPUT_MODE_VALUE(0) */
+#define INPUT_MODE_YC_1 1 /* INPUT_MODE_VALUE(1) */
+#define INPUT_MODE_YC2_2 2 /* INPUT_MODE_VALUE(2) */
+#define INPUT_MODE_YUV_3 3 /* INPUT_MODE_VALUE(3) */
+
+#define LUMA_LPF_LOW_BANDPASS 0 /* 0.6Mhz LPF BW */
+#define LUMA_LPF_MEDIUM_BANDPASS 1 /* 1.0Mhz LPF BW */
+#define LUMA_LPF_HIGH_BANDPASS 2 /* 1.5Mhz LPF BW */
+
+#define UV_LPF_LOW_BANDPASS 0 /* 0.6Mhz LPF BW */
+#define UV_LPF_MEDIUM_BANDPASS 1 /* 1.0Mhz LPF BW */
+#define UV_LPF_HIGH_BANDPASS 2 /* 1.5Mhz LPF BW */
+
+#define TWO_TAP_FILT 0
+#define THREE_TAP_FILT 1
+#define FOUR_TAP_FILT 2
+#define FIVE_TAP_FILT 3
+
+#define AUD_CHAN_SRC_PARALLEL 0
+#define AUD_CHAN_SRC_I2S_INPUT 1
+#define AUD_CHAN_SRC_FLATIRON 2
+#define AUD_CHAN_SRC_PARALLEL3 3
+
+#define OUT_MODE_601 0
+#define OUT_MODE_656 1
+#define OUT_MODE_VIP11 2
+#define OUT_MODE_VIP20 3
+
+#define PHASE_INC_49MHZ 0x0df22
+#define PHASE_INC_56MHZ 0x0fa5b
+#define PHASE_INC_28MHZ 0x010000
+
+#endif
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c
new file mode 100644
index 00000000000..94180526909
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-vbi.c
@@ -0,0 +1,701 @@
+/*
+ cx231xx_vbi.c - driver for Conexant Cx23100/101/102 USB video capture devices
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+ Based on cx88 driver
+
+ 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/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/bitmap.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <linux/version.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/msp3400.h>
+#include <media/tuner.h>
+
+#include "cx231xx.h"
+#include "cx231xx-vbi.h"
+
+static inline void print_err_status(struct cx231xx *dev, int packet, int status)
+{
+ char *errmsg = "Unknown";
+
+ switch (status) {
+ case -ENOENT:
+ errmsg = "unlinked synchronuously";
+ break;
+ case -ECONNRESET:
+ errmsg = "unlinked asynchronuously";
+ break;
+ case -ENOSR:
+ errmsg = "Buffer error (overrun)";
+ break;
+ case -EPIPE:
+ errmsg = "Stalled (device not responding)";
+ break;
+ case -EOVERFLOW:
+ errmsg = "Babble (bad cable?)";
+ break;
+ case -EPROTO:
+ errmsg = "Bit-stuff error (bad cable?)";
+ break;
+ case -EILSEQ:
+ errmsg = "CRC/Timeout (could be anything)";
+ break;
+ case -ETIME:
+ errmsg = "Device does not respond";
+ break;
+ }
+ if (packet < 0) {
+ cx231xx_err(DRIVER_NAME "URB status %d [%s].\n", status,
+ errmsg);
+ } else {
+ cx231xx_err(DRIVER_NAME "URB packet %d, status %d [%s].\n",
+ packet, status, errmsg);
+ }
+}
+
+/*
+ * Controls the isoc copy of each urb packet
+ */
+static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb)
+{
+ struct cx231xx_buffer *buf;
+ struct cx231xx_dmaqueue *dma_q = urb->context;
+ int rc = 1;
+ unsigned char *p_buffer;
+ u32 bytes_parsed = 0, buffer_size = 0;
+ u8 sav_eav = 0;
+
+ if (!dev)
+ return 0;
+
+ if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
+ return 0;
+
+ if (urb->status < 0) {
+ print_err_status(dev, -1, urb->status);
+ if (urb->status == -ENOENT)
+ return 0;
+ }
+
+ buf = dev->vbi_mode.isoc_ctl.buf;
+
+ /* get buffer pointer and length */
+ p_buffer = urb->transfer_buffer;
+ buffer_size = urb->actual_length;
+
+ if (buffer_size > 0) {
+ bytes_parsed = 0;
+
+ if (dma_q->is_partial_line) {
+ /* Handle the case where we were working on a partial
+ line */
+ sav_eav = dma_q->last_sav;
+ } else {
+ /* Check for a SAV/EAV overlapping the
+ buffer boundary */
+
+ sav_eav = cx231xx_find_boundary_SAV_EAV(p_buffer,
+ dma_q->partial_buf,
+ &bytes_parsed);
+ }
+
+ sav_eav &= 0xF0;
+ /* Get the first line if we have some portion of an SAV/EAV from
+ the last buffer or a partial line */
+ if (sav_eav) {
+ bytes_parsed += cx231xx_get_vbi_line(dev, dma_q,
+ sav_eav, /* SAV/EAV */
+ p_buffer + bytes_parsed, /* p_buffer */
+ buffer_size - bytes_parsed); /* buffer size */
+ }
+
+ /* Now parse data that is completely in this buffer */
+ dma_q->is_partial_line = 0;
+
+ while (bytes_parsed < buffer_size) {
+ u32 bytes_used = 0;
+
+ sav_eav = cx231xx_find_next_SAV_EAV(
+ p_buffer + bytes_parsed, /* p_buffer */
+ buffer_size - bytes_parsed, /* buffer size */
+ &bytes_used); /* bytes used to get SAV/EAV */
+
+ bytes_parsed += bytes_used;
+
+ sav_eav &= 0xF0;
+ if (sav_eav && (bytes_parsed < buffer_size)) {
+ bytes_parsed += cx231xx_get_vbi_line(dev,
+ dma_q, sav_eav, /* SAV/EAV */
+ p_buffer+bytes_parsed, /* p_buffer */
+ buffer_size-bytes_parsed);/*buf size*/
+ }
+ }
+
+ /* Save the last four bytes of the buffer so we can
+ check the buffer boundary condition next time */
+ memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);
+ bytes_parsed = 0;
+ }
+
+ return rc;
+}
+
+/* ------------------------------------------------------------------
+ Vbi buf operations
+ ------------------------------------------------------------------*/
+
+static int
+vbi_buffer_setup(struct videobuf_queue *vq, unsigned int *count,
+ unsigned int *size)
+{
+ struct cx231xx_fh *fh = vq->priv_data;
+ struct cx231xx *dev = fh->dev;
+ u32 height = 0;
+
+ height = ((dev->norm & V4L2_STD_625_50) ?
+ PAL_VBI_LINES : NTSC_VBI_LINES);
+
+ *size = (dev->width * height * 2);
+ if (0 == *count)
+ *count = CX231XX_DEF_VBI_BUF;
+
+ if (*count < CX231XX_MIN_BUF)
+ *count = CX231XX_MIN_BUF;
+
+ return 0;
+}
+
+/* This is called *without* dev->slock held; please keep it that way */
+static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
+{
+ struct cx231xx_fh *fh = vq->priv_data;
+ struct cx231xx *dev = fh->dev;
+ unsigned long flags = 0;
+ if (in_interrupt())
+ BUG();
+
+ /* We used to wait for the buffer to finish here, but this didn't work
+ because, as we were keeping the state as VIDEOBUF_QUEUED,
+ videobuf_queue_cancel marked it as finished for us.
+ (Also, it could wedge forever if the hardware was misconfigured.)
+
+ This should be safe; by the time we get here, the buffer isn't
+ queued anymore. If we ever start marking the buffers as
+ VIDEOBUF_ACTIVE, it won't be, though.
+ */
+ spin_lock_irqsave(&dev->vbi_mode.slock, flags);
+ if (dev->vbi_mode.isoc_ctl.buf == buf)
+ dev->vbi_mode.isoc_ctl.buf = NULL;
+ spin_unlock_irqrestore(&dev->vbi_mode.slock, flags);
+
+ videobuf_vmalloc_free(&buf->vb);
+ buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int
+vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
+ enum v4l2_field field)
+{
+ struct cx231xx_fh *fh = vq->priv_data;
+ struct cx231xx_buffer *buf =
+ container_of(vb, struct cx231xx_buffer, vb);
+ struct cx231xx *dev = fh->dev;
+ int rc = 0, urb_init = 0;
+ u32 height = 0;
+
+ height = ((dev->norm & V4L2_STD_625_50) ?
+ PAL_VBI_LINES : NTSC_VBI_LINES);
+ buf->vb.size = ((dev->width << 1) * height);
+
+ if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
+ return -EINVAL;
+
+ buf->vb.width = dev->width;
+ buf->vb.height = height;
+ buf->vb.field = field;
+ buf->vb.field = V4L2_FIELD_SEQ_TB;
+
+ if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+ rc = videobuf_iolock(vq, &buf->vb, NULL);
+ if (rc < 0)
+ goto fail;
+ }
+
+ if (!dev->vbi_mode.isoc_ctl.num_bufs)
+ urb_init = 1;
+
+ if (urb_init) {
+ rc = cx231xx_init_vbi_isoc(dev, CX231XX_NUM_VBI_PACKETS,
+ CX231XX_NUM_VBI_BUFS,
+ dev->vbi_mode.alt_max_pkt_size[0],
+ cx231xx_isoc_vbi_copy);
+ if (rc < 0)
+ goto fail;
+ }
+
+ buf->vb.state = VIDEOBUF_PREPARED;
+ return 0;
+
+fail:
+ free_buffer(vq, buf);
+ return rc;
+}
+
+static void
+vbi_buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+ struct cx231xx_buffer *buf =
+ container_of(vb, struct cx231xx_buffer, vb);
+ struct cx231xx_fh *fh = vq->priv_data;
+ struct cx231xx *dev = fh->dev;
+ struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq;
+
+ buf->vb.state = VIDEOBUF_QUEUED;
+ list_add_tail(&buf->vb.queue, &vidq->active);
+
+}
+
+static void vbi_buffer_release(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct cx231xx_buffer *buf =
+ container_of(vb, struct cx231xx_buffer, vb);
+
+
+ free_buffer(vq, buf);
+}
+
+struct videobuf_queue_ops cx231xx_vbi_qops = {
+ .buf_setup = vbi_buffer_setup,
+ .buf_prepare = vbi_buffer_prepare,
+ .buf_queue = vbi_buffer_queue,
+ .buf_release = vbi_buffer_release,
+};
+
+/* ------------------------------------------------------------------
+ URB control
+ ------------------------------------------------------------------*/
+
+/*
+ * IRQ callback, called by URB callback
+ */
+static void cx231xx_irq_vbi_callback(struct urb *urb)
+{
+ struct cx231xx_dmaqueue *dma_q = urb->context;
+ struct cx231xx_video_mode *vmode =
+ container_of(dma_q, struct cx231xx_video_mode, vidq);
+ struct cx231xx *dev = container_of(vmode, struct cx231xx, vbi_mode);
+ int rc;
+
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ cx231xx_err(DRIVER_NAME "urb completition error %d.\n",
+ urb->status);
+ break;
+ }
+
+ /* Copy data from URB */
+ spin_lock(&dev->vbi_mode.slock);
+ rc = dev->vbi_mode.isoc_ctl.isoc_copy(dev, urb);
+ spin_unlock(&dev->vbi_mode.slock);
+
+ /* Reset status */
+ urb->status = 0;
+
+ urb->status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (urb->status) {
+ cx231xx_err(DRIVER_NAME "urb resubmit failed (error=%i)\n",
+ urb->status);
+ }
+}
+
+/*
+ * Stop and Deallocate URBs
+ */
+void cx231xx_uninit_vbi_isoc(struct cx231xx *dev)
+{
+ struct urb *urb;
+ int i;
+
+ cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_uninit_vbi_isoc\n");
+
+ dev->vbi_mode.isoc_ctl.nfields = -1;
+ for (i = 0; i < dev->vbi_mode.isoc_ctl.num_bufs; i++) {
+ urb = dev->vbi_mode.isoc_ctl.urb[i];
+ if (urb) {
+ if (!irqs_disabled())
+ usb_kill_urb(urb);
+ else
+ usb_unlink_urb(urb);
+
+ if (dev->vbi_mode.isoc_ctl.transfer_buffer[i]) {
+
+ kfree(dev->vbi_mode.isoc_ctl.
+ transfer_buffer[i]);
+ dev->vbi_mode.isoc_ctl.transfer_buffer[i] =
+ NULL;
+ }
+ usb_free_urb(urb);
+ dev->vbi_mode.isoc_ctl.urb[i] = NULL;
+ }
+ dev->vbi_mode.isoc_ctl.transfer_buffer[i] = NULL;
+ }
+
+ kfree(dev->vbi_mode.isoc_ctl.urb);
+ kfree(dev->vbi_mode.isoc_ctl.transfer_buffer);
+
+ dev->vbi_mode.isoc_ctl.urb = NULL;
+ dev->vbi_mode.isoc_ctl.transfer_buffer = NULL;
+ dev->vbi_mode.isoc_ctl.num_bufs = 0;
+
+ cx231xx_capture_start(dev, 0, Vbi);
+}
+EXPORT_SYMBOL_GPL(cx231xx_uninit_vbi_isoc);
+
+/*
+ * Allocate URBs and start IRQ
+ */
+int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets,
+ int num_bufs, int max_pkt_size,
+ int (*isoc_copy) (struct cx231xx *dev,
+ struct urb *urb))
+{
+ struct cx231xx_dmaqueue *dma_q = &dev->vbi_mode.vidq;
+ int i;
+ int sb_size, pipe;
+ struct urb *urb;
+ int rc;
+
+ cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_prepare_isoc\n");
+
+ /* De-allocates all pending stuff */
+ cx231xx_uninit_vbi_isoc(dev);
+
+ /* clear if any halt */
+ usb_clear_halt(dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+ dev->vbi_mode.end_point_addr));
+
+ dev->vbi_mode.isoc_ctl.isoc_copy = isoc_copy;
+ dev->vbi_mode.isoc_ctl.num_bufs = num_bufs;
+ dma_q->pos = 0;
+ dma_q->is_partial_line = 0;
+ dma_q->last_sav = 0;
+ dma_q->current_field = -1;
+ dma_q->bytes_left_in_line = dev->width << 1;
+ dma_q->lines_per_field = ((dev->norm & V4L2_STD_625_50) ?
+ PAL_VBI_LINES : NTSC_VBI_LINES);
+ dma_q->lines_completed = 0;
+ for (i = 0; i < 8; i++)
+ dma_q->partial_buf[i] = 0;
+
+ dev->vbi_mode.isoc_ctl.urb = kzalloc(sizeof(void *) * num_bufs,
+ GFP_KERNEL);
+ if (!dev->vbi_mode.isoc_ctl.urb) {
+ cx231xx_errdev("cannot alloc memory for usb buffers\n");
+ return -ENOMEM;
+ }
+
+ dev->vbi_mode.isoc_ctl.transfer_buffer =
+ kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
+ if (!dev->vbi_mode.isoc_ctl.transfer_buffer) {
+ cx231xx_errdev("cannot allocate memory for usbtransfer\n");
+ kfree(dev->vbi_mode.isoc_ctl.urb);
+ return -ENOMEM;
+ }
+
+ dev->vbi_mode.isoc_ctl.max_pkt_size = max_pkt_size;
+ dev->vbi_mode.isoc_ctl.buf = NULL;
+
+ sb_size = max_packets * dev->vbi_mode.isoc_ctl.max_pkt_size;
+
+ /* allocate urbs and transfer buffers */
+ for (i = 0; i < dev->vbi_mode.isoc_ctl.num_bufs; i++) {
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ cx231xx_err(DRIVER_NAME
+ ": cannot alloc isoc_ctl.urb %i\n", i);
+ cx231xx_uninit_vbi_isoc(dev);
+ return -ENOMEM;
+ }
+ dev->vbi_mode.isoc_ctl.urb[i] = urb;
+ urb->transfer_flags = 0;
+
+ dev->vbi_mode.isoc_ctl.transfer_buffer[i] =
+ kzalloc(sb_size, GFP_KERNEL);
+ if (!dev->vbi_mode.isoc_ctl.transfer_buffer[i]) {
+ cx231xx_err(DRIVER_NAME
+ ": unable to allocate %i bytes for transfer"
+ " buffer %i%s\n", sb_size, i,
+ in_interrupt() ? " while in int" : "");
+ cx231xx_uninit_vbi_isoc(dev);
+ return -ENOMEM;
+ }
+
+ pipe = usb_rcvbulkpipe(dev->udev, dev->vbi_mode.end_point_addr);
+ usb_fill_bulk_urb(urb, dev->udev, pipe,
+ dev->vbi_mode.isoc_ctl.transfer_buffer[i],
+ sb_size, cx231xx_irq_vbi_callback, dma_q);
+ }
+
+ init_waitqueue_head(&dma_q->wq);
+
+ /* submit urbs and enables IRQ */
+ for (i = 0; i < dev->vbi_mode.isoc_ctl.num_bufs; i++) {
+ rc = usb_submit_urb(dev->vbi_mode.isoc_ctl.urb[i], GFP_ATOMIC);
+ if (rc) {
+ cx231xx_err(DRIVER_NAME
+ ": submit of urb %i failed (error=%i)\n", i,
+ rc);
+ cx231xx_uninit_vbi_isoc(dev);
+ return rc;
+ }
+ }
+
+ cx231xx_capture_start(dev, 1, Vbi);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cx231xx_init_vbi_isoc);
+
+u32 cx231xx_get_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+ u8 sav_eav, u8 *p_buffer, u32 buffer_size)
+{
+ u32 bytes_copied = 0;
+ int current_field = -1;
+
+ switch (sav_eav) {
+
+ case SAV_VBI_FIELD1:
+ current_field = 1;
+ break;
+
+ case SAV_VBI_FIELD2:
+ current_field = 2;
+ break;
+ default:
+ break;
+ }
+
+ if (current_field < 0)
+ return bytes_copied;
+
+ dma_q->last_sav = sav_eav;
+
+ bytes_copied =
+ cx231xx_copy_vbi_line(dev, dma_q, p_buffer, buffer_size,
+ current_field);
+
+ return bytes_copied;
+}
+
+/*
+ * Announces that a buffer were filled and request the next
+ */
+static inline void vbi_buffer_filled(struct cx231xx *dev,
+ struct cx231xx_dmaqueue *dma_q,
+ struct cx231xx_buffer *buf)
+{
+ /* Advice that buffer was filled */
+ /* cx231xx_info(DRIVER_NAME "[%p/%d] wakeup\n", buf, buf->vb.i); */
+
+ buf->vb.state = VIDEOBUF_DONE;
+ buf->vb.field_count++;
+ do_gettimeofday(&buf->vb.ts);
+
+ dev->vbi_mode.isoc_ctl.buf = NULL;
+
+ list_del(&buf->vb.queue);
+ wake_up(&buf->vb.done);
+}
+
+u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+ u8 *p_line, u32 length, int field_number)
+{
+ u32 bytes_to_copy;
+ struct cx231xx_buffer *buf;
+ u32 _line_size = dev->width * 2;
+
+ if (dma_q->current_field != field_number)
+ cx231xx_reset_vbi_buffer(dev, dma_q);
+
+ /* get the buffer pointer */
+ buf = dev->vbi_mode.isoc_ctl.buf;
+
+ /* Remember the field number for next time */
+ dma_q->current_field = field_number;
+
+ bytes_to_copy = dma_q->bytes_left_in_line;
+ if (bytes_to_copy > length)
+ bytes_to_copy = length;
+
+ if (dma_q->lines_completed >= dma_q->lines_per_field) {
+ dma_q->bytes_left_in_line -= bytes_to_copy;
+ dma_q->is_partial_line =
+ (dma_q->bytes_left_in_line == 0) ? 0 : 1;
+ return 0;
+ }
+
+ dma_q->is_partial_line = 1;
+
+ /* If we don't have a buffer, just return the number of bytes we would
+ have copied if we had a buffer. */
+ if (!buf) {
+ dma_q->bytes_left_in_line -= bytes_to_copy;
+ dma_q->is_partial_line =
+ (dma_q->bytes_left_in_line == 0) ? 0 : 1;
+ return bytes_to_copy;
+ }
+
+ /* copy the data to video buffer */
+ cx231xx_do_vbi_copy(dev, dma_q, p_line, bytes_to_copy);
+
+ dma_q->pos += bytes_to_copy;
+ dma_q->bytes_left_in_line -= bytes_to_copy;
+
+ if (dma_q->bytes_left_in_line == 0) {
+
+ dma_q->bytes_left_in_line = _line_size;
+ dma_q->lines_completed++;
+ dma_q->is_partial_line = 0;
+
+ if (cx231xx_is_vbi_buffer_done(dev, dma_q) && buf) {
+
+ vbi_buffer_filled(dev, dma_q, buf);
+
+ dma_q->pos = 0;
+ buf = NULL;
+ dma_q->lines_completed = 0;
+ }
+ }
+
+ return bytes_to_copy;
+}
+
+/*
+ * video-buf generic routine to get the next available buffer
+ */
+static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q,
+ struct cx231xx_buffer **buf)
+{
+ struct cx231xx_video_mode *vmode =
+ container_of(dma_q, struct cx231xx_video_mode, vidq);
+ struct cx231xx *dev = container_of(vmode, struct cx231xx, vbi_mode);
+ char *outp;
+
+ if (list_empty(&dma_q->active)) {
+ cx231xx_err(DRIVER_NAME ": No active queue to serve\n");
+ dev->vbi_mode.isoc_ctl.buf = NULL;
+ *buf = NULL;
+ return;
+ }
+
+ /* Get the next buffer */
+ *buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue);
+
+ /* Cleans up buffer - Usefull for testing for frame/URB loss */
+ outp = videobuf_to_vmalloc(&(*buf)->vb);
+ memset(outp, 0, (*buf)->vb.size);
+
+ dev->vbi_mode.isoc_ctl.buf = *buf;
+
+ return;
+}
+
+void cx231xx_reset_vbi_buffer(struct cx231xx *dev,
+ struct cx231xx_dmaqueue *dma_q)
+{
+ struct cx231xx_buffer *buf;
+
+ buf = dev->vbi_mode.isoc_ctl.buf;
+
+ if (buf == NULL) {
+ /* first try to get the buffer */
+ get_next_vbi_buf(dma_q, &buf);
+
+ dma_q->pos = 0;
+ dma_q->current_field = -1;
+ }
+
+ dma_q->bytes_left_in_line = dev->width << 1;
+ dma_q->lines_completed = 0;
+}
+
+int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+ u8 *p_buffer, u32 bytes_to_copy)
+{
+ u8 *p_out_buffer = NULL;
+ u32 current_line_bytes_copied = 0;
+ struct cx231xx_buffer *buf;
+ u32 _line_size = dev->width << 1;
+ void *startwrite;
+ int offset, lencopy;
+
+ buf = dev->vbi_mode.isoc_ctl.buf;
+
+ if (buf == NULL)
+ return -EINVAL;
+
+ p_out_buffer = videobuf_to_vmalloc(&buf->vb);
+
+ if (dma_q->bytes_left_in_line != _line_size) {
+ current_line_bytes_copied =
+ _line_size - dma_q->bytes_left_in_line;
+ }
+
+ offset = (dma_q->lines_completed * _line_size) +
+ current_line_bytes_copied;
+
+ /* prepare destination address */
+ startwrite = p_out_buffer + offset;
+
+ lencopy = dma_q->bytes_left_in_line > bytes_to_copy ?
+ bytes_to_copy : dma_q->bytes_left_in_line;
+
+ memcpy(startwrite, p_buffer, lencopy);
+
+ return 0;
+}
+
+u8 cx231xx_is_vbi_buffer_done(struct cx231xx *dev,
+ struct cx231xx_dmaqueue *dma_q)
+{
+ u32 height = 0;
+
+ height = ((dev->norm & V4L2_STD_625_50) ?
+ PAL_VBI_LINES : NTSC_VBI_LINES);
+ return (dma_q->lines_completed == height) ? 1 : 0;
+}
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.h b/drivers/media/video/cx231xx/cx231xx-vbi.h
new file mode 100644
index 00000000000..89c7fe80b26
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-vbi.h
@@ -0,0 +1,65 @@
+/*
+ cx231xx_vbi.h - driver for Conexant Cx23100/101/102 USB video capture devices
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+ Based on cx88 driver
+
+ 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.
+ */
+
+#ifndef _CX231XX_VBI_H
+#define _CX231XX_VBI_H
+
+extern struct videobuf_queue_ops cx231xx_vbi_qops;
+
+#define NTSC_VBI_START_LINE 10 /* line 10 - 21 */
+#define NTSC_VBI_END_LINE 21
+#define NTSC_VBI_LINES (NTSC_VBI_END_LINE-NTSC_VBI_START_LINE+1)
+
+#define PAL_VBI_START_LINE 6
+#define PAL_VBI_END_LINE 23
+#define PAL_VBI_LINES (PAL_VBI_END_LINE-PAL_VBI_START_LINE+1)
+
+#define VBI_STRIDE 1440
+#define VBI_SAMPLES_PER_LINE 1440
+
+#define CX231XX_NUM_VBI_PACKETS 4
+#define CX231XX_NUM_VBI_BUFS 5
+
+/* stream functions */
+int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets,
+ int num_bufs, int max_pkt_size,
+ int (*isoc_copy) (struct cx231xx *dev,
+ struct urb *urb));
+
+void cx231xx_uninit_vbi_isoc(struct cx231xx *dev);
+
+/* vbi data copy functions */
+u32 cx231xx_get_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+ u8 sav_eav, u8 *p_buffer, u32 buffer_size);
+
+u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+ u8 *p_line, u32 length, int field_number);
+
+void cx231xx_reset_vbi_buffer(struct cx231xx *dev,
+ struct cx231xx_dmaqueue *dma_q);
+
+int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+ u8 *p_buffer, u32 bytes_to_copy);
+
+u8 cx231xx_is_vbi_buffer_done(struct cx231xx *dev,
+ struct cx231xx_dmaqueue *dma_q);
+
+#endif
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
new file mode 100644
index 00000000000..a23ae73fe63
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -0,0 +1,2434 @@
+/*
+ cx231xx-video.c - driver for Conexant Cx23100/101/102
+ USB video capture devices
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+ Based on em28xx driver
+ Based on cx23885 driver
+ Based on cx88 driver
+
+ 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/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/bitmap.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <linux/version.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/msp3400.h>
+#include <media/tuner.h>
+
+#include "dvb_frontend.h"
+
+#include "cx231xx.h"
+#include "cx231xx-vbi.h"
+
+#define CX231XX_VERSION_CODE KERNEL_VERSION(0, 0, 1)
+
+#define DRIVER_AUTHOR "Srinivasa Deevi <srinivasa.deevi@conexant.com>"
+#define DRIVER_DESC "Conexant cx231xx based USB video device driver"
+
+#define cx231xx_videodbg(fmt, arg...) do {\
+ if (video_debug) \
+ printk(KERN_INFO "%s %s :"fmt, \
+ dev->name, __func__ , ##arg); } while (0)
+
+static unsigned int isoc_debug;
+module_param(isoc_debug, int, 0644);
+MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
+
+#define cx231xx_isocdbg(fmt, arg...) \
+do {\
+ if (isoc_debug) { \
+ printk(KERN_INFO "%s %s :"fmt, \
+ dev->name, __func__ , ##arg); \
+ } \
+ } while (0)
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+static unsigned int card[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
+static unsigned int video_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
+static unsigned int vbi_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
+static unsigned int radio_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
+
+module_param_array(card, int, NULL, 0444);
+module_param_array(video_nr, int, NULL, 0444);
+module_param_array(vbi_nr, int, NULL, 0444);
+module_param_array(radio_nr, int, NULL, 0444);
+
+MODULE_PARM_DESC(card, "card type");
+MODULE_PARM_DESC(video_nr, "video device numbers");
+MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
+MODULE_PARM_DESC(radio_nr, "radio device numbers");
+
+static unsigned int video_debug;
+module_param(video_debug, int, 0644);
+MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
+
+/* supported video standards */
+static struct cx231xx_fmt format[] = {
+ {
+ .name = "16bpp YUY2, 4:2:2, packed",
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .depth = 16,
+ .reg = 0,
+ },
+};
+
+/* supported controls */
+/* Common to all boards */
+
+/* ------------------------------------------------------------------- */
+
+static const struct v4l2_queryctrl no_ctl = {
+ .name = "42",
+ .flags = V4L2_CTRL_FLAG_DISABLED,
+};
+
+static struct cx231xx_ctrl cx231xx_ctls[] = {
+ /* --- video --- */
+ {
+ .v = {
+ .id = V4L2_CID_BRIGHTNESS,
+ .name = "Brightness",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0x7f,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ },
+ .off = 128,
+ .reg = LUMA_CTRL,
+ .mask = 0x00ff,
+ .shift = 0,
+ }, {
+ .v = {
+ .id = V4L2_CID_CONTRAST,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0x3f,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ },
+ .off = 0,
+ .reg = LUMA_CTRL,
+ .mask = 0xff00,
+ .shift = 8,
+ }, {
+ .v = {
+ .id = V4L2_CID_HUE,
+ .name = "Hue",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0x7f,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ },
+ .off = 128,
+ .reg = CHROMA_CTRL,
+ .mask = 0xff0000,
+ .shift = 16,
+ }, {
+ /* strictly, this only describes only U saturation.
+ * V saturation is handled specially through code.
+ */
+ .v = {
+ .id = V4L2_CID_SATURATION,
+ .name = "Saturation",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0x7f,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ },
+ .off = 0,
+ .reg = CHROMA_CTRL,
+ .mask = 0x00ff,
+ .shift = 0,
+ }, {
+ /* --- audio --- */
+ .v = {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },
+ .reg = PATH1_CTL1,
+ .mask = (0x1f << 24),
+ .shift = 24,
+ }, {
+ .v = {
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 0x3f,
+ .step = 1,
+ .default_value = 0x3f,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ },
+ .reg = PATH1_VOL_CTL,
+ .mask = 0xff,
+ .shift = 0,
+ }
+};
+static const int CX231XX_CTLS = ARRAY_SIZE(cx231xx_ctls);
+
+static const u32 cx231xx_user_ctrls[] = {
+ V4L2_CID_USER_CLASS,
+ V4L2_CID_BRIGHTNESS,
+ V4L2_CID_CONTRAST,
+ V4L2_CID_SATURATION,
+ V4L2_CID_HUE,
+ V4L2_CID_AUDIO_VOLUME,
+#if 0
+ V4L2_CID_AUDIO_BALANCE,
+#endif
+ V4L2_CID_AUDIO_MUTE,
+ 0
+};
+
+static const u32 *ctrl_classes[] = {
+ cx231xx_user_ctrls,
+ NULL
+};
+
+/* ------------------------------------------------------------------
+ Video buffer and parser functions
+ ------------------------------------------------------------------*/
+
+/*
+ * Announces that a buffer were filled and request the next
+ */
+static inline void buffer_filled(struct cx231xx *dev,
+ struct cx231xx_dmaqueue *dma_q,
+ struct cx231xx_buffer *buf)
+{
+ /* Advice that buffer was filled */
+ cx231xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
+ buf->vb.state = VIDEOBUF_DONE;
+ buf->vb.field_count++;
+ do_gettimeofday(&buf->vb.ts);
+
+ dev->video_mode.isoc_ctl.buf = NULL;
+
+ list_del(&buf->vb.queue);
+ wake_up(&buf->vb.done);
+}
+
+static inline void print_err_status(struct cx231xx *dev, int packet, int status)
+{
+ char *errmsg = "Unknown";
+
+ switch (status) {
+ case -ENOENT:
+ errmsg = "unlinked synchronuously";
+ break;
+ case -ECONNRESET:
+ errmsg = "unlinked asynchronuously";
+ break;
+ case -ENOSR:
+ errmsg = "Buffer error (overrun)";
+ break;
+ case -EPIPE:
+ errmsg = "Stalled (device not responding)";
+ break;
+ case -EOVERFLOW:
+ errmsg = "Babble (bad cable?)";
+ break;
+ case -EPROTO:
+ errmsg = "Bit-stuff error (bad cable?)";
+ break;
+ case -EILSEQ:
+ errmsg = "CRC/Timeout (could be anything)";
+ break;
+ case -ETIME:
+ errmsg = "Device does not respond";
+ break;
+ }
+ if (packet < 0) {
+ cx231xx_isocdbg("URB status %d [%s].\n", status, errmsg);
+ } else {
+ cx231xx_isocdbg("URB packet %d, status %d [%s].\n",
+ packet, status, errmsg);
+ }
+}
+
+/*
+ * video-buf generic routine to get the next available buffer
+ */
+static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q,
+ struct cx231xx_buffer **buf)
+{
+ struct cx231xx_video_mode *vmode =
+ container_of(dma_q, struct cx231xx_video_mode, vidq);
+ struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode);
+
+ char *outp;
+
+ if (list_empty(&dma_q->active)) {
+ cx231xx_isocdbg("No active queue to serve\n");
+ dev->video_mode.isoc_ctl.buf = NULL;
+ *buf = NULL;
+ return;
+ }
+
+ /* Get the next buffer */
+ *buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue);
+
+ /* Cleans up buffer - Usefull for testing for frame/URB loss */
+ outp = videobuf_to_vmalloc(&(*buf)->vb);
+ memset(outp, 0, (*buf)->vb.size);
+
+ dev->video_mode.isoc_ctl.buf = *buf;
+
+ return;
+}
+
+/*
+ * Controls the isoc copy of each urb packet
+ */
+static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
+{
+ struct cx231xx_buffer *buf;
+ struct cx231xx_dmaqueue *dma_q = urb->context;
+ unsigned char *outp = NULL;
+ int i, rc = 1;
+ unsigned char *p_buffer;
+ u32 bytes_parsed = 0, buffer_size = 0;
+ u8 sav_eav = 0;
+
+ if (!dev)
+ return 0;
+
+ if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
+ return 0;
+
+ if (urb->status < 0) {
+ print_err_status(dev, -1, urb->status);
+ if (urb->status == -ENOENT)
+ return 0;
+ }
+
+ buf = dev->video_mode.isoc_ctl.buf;
+ if (buf != NULL)
+ outp = videobuf_to_vmalloc(&buf->vb);
+
+ for (i = 0; i < urb->number_of_packets; i++) {
+ int status = urb->iso_frame_desc[i].status;
+
+ if (status < 0) {
+ print_err_status(dev, i, status);
+ if (urb->iso_frame_desc[i].status != -EPROTO)
+ continue;
+ }
+
+ if (urb->iso_frame_desc[i].actual_length <= 0) {
+ /* cx231xx_isocdbg("packet %d is empty",i); - spammy */
+ continue;
+ }
+ if (urb->iso_frame_desc[i].actual_length >
+ dev->video_mode.max_pkt_size) {
+ cx231xx_isocdbg("packet bigger than packet size");
+ continue;
+ }
+
+ /* get buffer pointer and length */
+ p_buffer = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+ buffer_size = urb->iso_frame_desc[i].actual_length;
+ bytes_parsed = 0;
+
+ if (dma_q->is_partial_line) {
+ /* Handle the case of a partial line */
+ sav_eav = dma_q->last_sav;
+ } else {
+ /* Check for a SAV/EAV overlapping
+ the buffer boundary */
+ sav_eav =
+ cx231xx_find_boundary_SAV_EAV(p_buffer,
+ dma_q->partial_buf,
+ &bytes_parsed);
+ }
+
+ sav_eav &= 0xF0;
+ /* Get the first line if we have some portion of an SAV/EAV from
+ the last buffer or a partial line */
+ if (sav_eav) {
+ bytes_parsed += cx231xx_get_video_line(dev, dma_q,
+ sav_eav, /* SAV/EAV */
+ p_buffer + bytes_parsed, /* p_buffer */
+ buffer_size - bytes_parsed);/* buf size */
+ }
+
+ /* Now parse data that is completely in this buffer */
+ /* dma_q->is_partial_line = 0; */
+
+ while (bytes_parsed < buffer_size) {
+ u32 bytes_used = 0;
+
+ sav_eav = cx231xx_find_next_SAV_EAV(
+ p_buffer + bytes_parsed, /* p_buffer */
+ buffer_size - bytes_parsed, /* buf size */
+ &bytes_used);/* bytes used to get SAV/EAV */
+
+ bytes_parsed += bytes_used;
+
+ sav_eav &= 0xF0;
+ if (sav_eav && (bytes_parsed < buffer_size)) {
+ bytes_parsed += cx231xx_get_video_line(dev,
+ dma_q, sav_eav, /* SAV/EAV */
+ p_buffer + bytes_parsed,/* p_buffer */
+ buffer_size - bytes_parsed);/*buf size*/
+ }
+ }
+
+ /* Save the last four bytes of the buffer so we can check the
+ buffer boundary condition next time */
+ memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);
+ bytes_parsed = 0;
+
+ }
+ return rc;
+}
+
+u8 cx231xx_find_boundary_SAV_EAV(u8 *p_buffer, u8 *partial_buf,
+ u32 *p_bytes_used)
+{
+ u32 bytes_used;
+ u8 boundary_bytes[8];
+ u8 sav_eav = 0;
+
+ *p_bytes_used = 0;
+
+ /* Create an array of the last 4 bytes of the last buffer and the first
+ 4 bytes of the current buffer. */
+
+ memcpy(boundary_bytes, partial_buf, 4);
+ memcpy(boundary_bytes + 4, p_buffer, 4);
+
+ /* Check for the SAV/EAV in the boundary buffer */
+ sav_eav = cx231xx_find_next_SAV_EAV((u8 *)&boundary_bytes, 8,
+ &bytes_used);
+
+ if (sav_eav) {
+ /* found a boundary SAV/EAV. Updates the bytes used to reflect
+ only those used in the new buffer */
+ *p_bytes_used = bytes_used - 4;
+ }
+
+ return sav_eav;
+}
+
+u8 cx231xx_find_next_SAV_EAV(u8 *p_buffer, u32 buffer_size, u32 *p_bytes_used)
+{
+ u32 i;
+ u8 sav_eav = 0;
+
+ /*
+ * Don't search if the buffer size is less than 4. It causes a page
+ * fault since buffer_size - 4 evaluates to a large number in that
+ * case.
+ */
+ if (buffer_size < 4) {
+ *p_bytes_used = buffer_size;
+ return 0;
+ }
+
+ for (i = 0; i < (buffer_size - 3); i++) {
+
+ if ((p_buffer[i] == 0xFF) &&
+ (p_buffer[i + 1] == 0x00) && (p_buffer[i + 2] == 0x00)) {
+
+ *p_bytes_used = i + 4;
+ sav_eav = p_buffer[i + 3];
+ return sav_eav;
+ }
+ }
+
+ *p_bytes_used = buffer_size;
+ return 0;
+}
+
+u32 cx231xx_get_video_line(struct cx231xx *dev,
+ struct cx231xx_dmaqueue *dma_q, u8 sav_eav,
+ u8 *p_buffer, u32 buffer_size)
+{
+ u32 bytes_copied = 0;
+ int current_field = -1;
+
+ switch (sav_eav) {
+ case SAV_ACTIVE_VIDEO_FIELD1:
+ /* looking for skipped line which occurred in PAL 720x480 mode.
+ In this case, there will be no active data contained
+ between the SAV and EAV */
+ if ((buffer_size > 3) && (p_buffer[0] == 0xFF) &&
+ (p_buffer[1] == 0x00) && (p_buffer[2] == 0x00) &&
+ ((p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1) ||
+ (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2) ||
+ (p_buffer[3] == EAV_VBLANK_FIELD1) ||
+ (p_buffer[3] == EAV_VBLANK_FIELD2)))
+ return bytes_copied;
+ current_field = 1;
+ break;
+
+ case SAV_ACTIVE_VIDEO_FIELD2:
+ /* looking for skipped line which occurred in PAL 720x480 mode.
+ In this case, there will be no active data contained between
+ the SAV and EAV */
+ if ((buffer_size > 3) && (p_buffer[0] == 0xFF) &&
+ (p_buffer[1] == 0x00) && (p_buffer[2] == 0x00) &&
+ ((p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1) ||
+ (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2) ||
+ (p_buffer[3] == EAV_VBLANK_FIELD1) ||
+ (p_buffer[3] == EAV_VBLANK_FIELD2)))
+ return bytes_copied;
+ current_field = 2;
+ break;
+ }
+
+ dma_q->last_sav = sav_eav;
+
+ bytes_copied = cx231xx_copy_video_line(dev, dma_q, p_buffer,
+ buffer_size, current_field);
+
+ return bytes_copied;
+}
+
+u32 cx231xx_copy_video_line(struct cx231xx *dev,
+ struct cx231xx_dmaqueue *dma_q, u8 *p_line,
+ u32 length, int field_number)
+{
+ u32 bytes_to_copy;
+ struct cx231xx_buffer *buf;
+ u32 _line_size = dev->width * 2;
+
+ if (dma_q->current_field != field_number)
+ cx231xx_reset_video_buffer(dev, dma_q);
+
+ /* get the buffer pointer */
+ buf = dev->video_mode.isoc_ctl.buf;
+
+ /* Remember the field number for next time */
+ dma_q->current_field = field_number;
+
+ bytes_to_copy = dma_q->bytes_left_in_line;
+ if (bytes_to_copy > length)
+ bytes_to_copy = length;
+
+ if (dma_q->lines_completed >= dma_q->lines_per_field) {
+ dma_q->bytes_left_in_line -= bytes_to_copy;
+ dma_q->is_partial_line = (dma_q->bytes_left_in_line == 0) ?
+ 0 : 1;
+ return 0;
+ }
+
+ dma_q->is_partial_line = 1;
+
+ /* If we don't have a buffer, just return the number of bytes we would
+ have copied if we had a buffer. */
+ if (!buf) {
+ dma_q->bytes_left_in_line -= bytes_to_copy;
+ dma_q->is_partial_line = (dma_q->bytes_left_in_line == 0)
+ ? 0 : 1;
+ return bytes_to_copy;
+ }
+
+ /* copy the data to video buffer */
+ cx231xx_do_copy(dev, dma_q, p_line, bytes_to_copy);
+
+ dma_q->pos += bytes_to_copy;
+ dma_q->bytes_left_in_line -= bytes_to_copy;
+
+ if (dma_q->bytes_left_in_line == 0) {
+ dma_q->bytes_left_in_line = _line_size;
+ dma_q->lines_completed++;
+ dma_q->is_partial_line = 0;
+
+ if (cx231xx_is_buffer_done(dev, dma_q) && buf) {
+ buffer_filled(dev, dma_q, buf);
+
+ dma_q->pos = 0;
+ buf = NULL;
+ dma_q->lines_completed = 0;
+ }
+ }
+
+ return bytes_to_copy;
+}
+
+void cx231xx_reset_video_buffer(struct cx231xx *dev,
+ struct cx231xx_dmaqueue *dma_q)
+{
+ struct cx231xx_buffer *buf;
+
+ /* handle the switch from field 1 to field 2 */
+ if (dma_q->current_field == 1) {
+ if (dma_q->lines_completed >= dma_q->lines_per_field)
+ dma_q->field1_done = 1;
+ else
+ dma_q->field1_done = 0;
+ }
+
+ buf = dev->video_mode.isoc_ctl.buf;
+
+ if (buf == NULL) {
+ u8 *outp = NULL;
+ /* first try to get the buffer */
+ get_next_buf(dma_q, &buf);
+
+ if (buf)
+ outp = videobuf_to_vmalloc(&buf->vb);
+
+ dma_q->pos = 0;
+ dma_q->field1_done = 0;
+ dma_q->current_field = -1;
+ }
+
+ /* reset the counters */
+ dma_q->bytes_left_in_line = dev->width << 1;
+ dma_q->lines_completed = 0;
+}
+
+int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+ u8 *p_buffer, u32 bytes_to_copy)
+{
+ u8 *p_out_buffer = NULL;
+ u32 current_line_bytes_copied = 0;
+ struct cx231xx_buffer *buf;
+ u32 _line_size = dev->width << 1;
+ void *startwrite;
+ int offset, lencopy;
+
+ buf = dev->video_mode.isoc_ctl.buf;
+
+ if (buf == NULL)
+ return -1;
+
+ p_out_buffer = videobuf_to_vmalloc(&buf->vb);
+
+ current_line_bytes_copied = _line_size - dma_q->bytes_left_in_line;
+
+ /* Offset field 2 one line from the top of the buffer */
+ offset = (dma_q->current_field == 1) ? 0 : _line_size;
+
+ /* Offset for field 2 */
+ startwrite = p_out_buffer + offset;
+
+ /* lines already completed in the current field */
+ startwrite += (dma_q->lines_completed * _line_size * 2);
+
+ /* bytes already completed in the current line */
+ startwrite += current_line_bytes_copied;
+
+ lencopy = dma_q->bytes_left_in_line > bytes_to_copy ?
+ bytes_to_copy : dma_q->bytes_left_in_line;
+
+ if ((u8 *)(startwrite + lencopy) > (u8 *)(p_out_buffer + buf->vb.size))
+ return 0;
+
+ /* The below copies the UYVY data straight into video buffer */
+ cx231xx_swab((u16 *) p_buffer, (u16 *) startwrite, (u16) lencopy);
+
+ return 0;
+}
+
+void cx231xx_swab(u16 *from, u16 *to, u16 len)
+{
+ u16 i;
+
+ if (len <= 0)
+ return;
+
+ for (i = 0; i < len / 2; i++)
+ to[i] = (from[i] << 8) | (from[i] >> 8);
+}
+
+u8 cx231xx_is_buffer_done(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q)
+{
+ u8 buffer_complete = 0;
+
+ /* Dual field stream */
+ buffer_complete = ((dma_q->current_field == 2) &&
+ (dma_q->lines_completed >= dma_q->lines_per_field) &&
+ dma_q->field1_done);
+
+ return buffer_complete;
+}
+
+/* ------------------------------------------------------------------
+ Videobuf operations
+ ------------------------------------------------------------------*/
+
+static int
+buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
+{
+ struct cx231xx_fh *fh = vq->priv_data;
+ struct cx231xx *dev = fh->dev;
+ struct v4l2_frequency f;
+
+ *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7)>>3;
+ if (0 == *count)
+ *count = CX231XX_DEF_BUF;
+
+ if (*count < CX231XX_MIN_BUF)
+ *count = CX231XX_MIN_BUF;
+
+ /* Ask tuner to go to analog mode */
+ memset(&f, 0, sizeof(f));
+ f.frequency = dev->ctl_freq;
+ f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+
+ call_all(dev, tuner, s_frequency, &f);
+
+ return 0;
+}
+
+/* This is called *without* dev->slock held; please keep it that way */
+static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
+{
+ struct cx231xx_fh *fh = vq->priv_data;
+ struct cx231xx *dev = fh->dev;
+ unsigned long flags = 0;
+
+ if (in_interrupt())
+ BUG();
+
+ /* We used to wait for the buffer to finish here, but this didn't work
+ because, as we were keeping the state as VIDEOBUF_QUEUED,
+ videobuf_queue_cancel marked it as finished for us.
+ (Also, it could wedge forever if the hardware was misconfigured.)
+
+ This should be safe; by the time we get here, the buffer isn't
+ queued anymore. If we ever start marking the buffers as
+ VIDEOBUF_ACTIVE, it won't be, though.
+ */
+ spin_lock_irqsave(&dev->video_mode.slock, flags);
+ if (dev->video_mode.isoc_ctl.buf == buf)
+ dev->video_mode.isoc_ctl.buf = NULL;
+ spin_unlock_irqrestore(&dev->video_mode.slock, flags);
+
+ videobuf_vmalloc_free(&buf->vb);
+ buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int
+buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
+ enum v4l2_field field)
+{
+ struct cx231xx_fh *fh = vq->priv_data;
+ struct cx231xx_buffer *buf =
+ container_of(vb, struct cx231xx_buffer, vb);
+ struct cx231xx *dev = fh->dev;
+ int rc = 0, urb_init = 0;
+
+ /* The only currently supported format is 16 bits/pixel */
+ buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth
+ + 7) >> 3;
+ if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
+ return -EINVAL;
+
+ buf->vb.width = dev->width;
+ buf->vb.height = dev->height;
+ buf->vb.field = field;
+
+ if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+ rc = videobuf_iolock(vq, &buf->vb, NULL);
+ if (rc < 0)
+ goto fail;
+ }
+
+ if (!dev->video_mode.isoc_ctl.num_bufs)
+ urb_init = 1;
+
+ if (urb_init) {
+ rc = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS,
+ CX231XX_NUM_BUFS,
+ dev->video_mode.max_pkt_size,
+ cx231xx_isoc_copy);
+ if (rc < 0)
+ goto fail;
+ }
+
+ buf->vb.state = VIDEOBUF_PREPARED;
+ return 0;
+
+fail:
+ free_buffer(vq, buf);
+ return rc;
+}
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+ struct cx231xx_buffer *buf =
+ container_of(vb, struct cx231xx_buffer, vb);
+ struct cx231xx_fh *fh = vq->priv_data;
+ struct cx231xx *dev = fh->dev;
+ struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq;
+
+ buf->vb.state = VIDEOBUF_QUEUED;
+ list_add_tail(&buf->vb.queue, &vidq->active);
+
+}
+
+static void buffer_release(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct cx231xx_buffer *buf =
+ container_of(vb, struct cx231xx_buffer, vb);
+ struct cx231xx_fh *fh = vq->priv_data;
+ struct cx231xx *dev = (struct cx231xx *)fh->dev;
+
+ cx231xx_isocdbg("cx231xx: called buffer_release\n");
+
+ free_buffer(vq, buf);
+}
+
+static struct videobuf_queue_ops cx231xx_video_qops = {
+ .buf_setup = buffer_setup,
+ .buf_prepare = buffer_prepare,
+ .buf_queue = buffer_queue,
+ .buf_release = buffer_release,
+};
+
+/********************* v4l2 interface **************************************/
+
+void video_mux(struct cx231xx *dev, int index)
+{
+ dev->video_input = index;
+ dev->ctl_ainput = INPUT(index)->amux;
+
+ cx231xx_set_video_input_mux(dev, index);
+
+ cx25840_call(dev, video, s_routing, INPUT(index)->vmux, 0, 0);
+
+ cx231xx_set_audio_input(dev, dev->ctl_ainput);
+
+ cx231xx_info("video_mux : %d\n", index);
+
+ /* do mode control overrides if required */
+ cx231xx_do_mode_ctrl_overrides(dev);
+}
+
+/* Usage lock check functions */
+static int res_get(struct cx231xx_fh *fh)
+{
+ struct cx231xx *dev = fh->dev;
+ int rc = 0;
+
+ /* This instance already has stream_on */
+ if (fh->stream_on)
+ return rc;
+
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ if (dev->stream_on)
+ return -EBUSY;
+ dev->stream_on = 1;
+ } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ if (dev->vbi_stream_on)
+ return -EBUSY;
+ dev->vbi_stream_on = 1;
+ } else
+ return -EINVAL;
+
+ fh->stream_on = 1;
+
+ return rc;
+}
+
+static int res_check(struct cx231xx_fh *fh)
+{
+ return fh->stream_on;
+}
+
+static void res_free(struct cx231xx_fh *fh)
+{
+ struct cx231xx *dev = fh->dev;
+
+ fh->stream_on = 0;
+
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ dev->stream_on = 0;
+ if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ dev->vbi_stream_on = 0;
+}
+
+static int check_dev(struct cx231xx *dev)
+{
+ if (dev->state & DEV_DISCONNECTED) {
+ cx231xx_errdev("v4l2 ioctl: device not present\n");
+ return -ENODEV;
+ }
+
+ if (dev->state & DEV_MISCONFIGURED) {
+ cx231xx_errdev("v4l2 ioctl: device is misconfigured; "
+ "close and open it again\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+void get_scale(struct cx231xx *dev,
+ unsigned int width, unsigned int height,
+ unsigned int *hscale, unsigned int *vscale)
+{
+ unsigned int maxw = norm_maxw(dev);
+ unsigned int maxh = norm_maxh(dev);
+
+ *hscale = (((unsigned long)maxw) << 12) / width - 4096L;
+ if (*hscale >= 0x4000)
+ *hscale = 0x3fff;
+
+ *vscale = (((unsigned long)maxh) << 12) / height - 4096L;
+ if (*vscale >= 0x4000)
+ *vscale = 0x3fff;
+
+ dev->hscale = *hscale;
+ dev->vscale = *vscale;
+
+}
+
+/* ------------------------------------------------------------------
+ IOCTL vidioc handling
+ ------------------------------------------------------------------*/
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+
+ mutex_lock(&dev->lock);
+
+ f->fmt.pix.width = dev->width;
+ f->fmt.pix.height = dev->height;
+ f->fmt.pix.pixelformat = dev->format->fourcc;;
+ f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;;
+ f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+
+ f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+
+ mutex_unlock(&dev->lock);
+
+ return 0;
+}
+
+static struct cx231xx_fmt *format_by_fourcc(unsigned int fourcc)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(format); i++)
+ if (format[i].fourcc == fourcc)
+ return &format[i];
+
+ return NULL;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int width = f->fmt.pix.width;
+ int height = f->fmt.pix.height;
+ unsigned int maxw = norm_maxw(dev);
+ unsigned int maxh = norm_maxh(dev);
+ unsigned int hscale, vscale;
+ struct cx231xx_fmt *fmt;
+
+ fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ if (!fmt) {
+ cx231xx_videodbg("Fourcc format (%08x) invalid.\n",
+ f->fmt.pix.pixelformat);
+ return -EINVAL;
+ }
+
+ /* width must even because of the YUYV format
+ height must be even because of interlacing */
+ height &= 0xfffe;
+ width &= 0xfffe;
+
+ if (unlikely(height < 32))
+ height = 32;
+ if (unlikely(height > maxh))
+ height = maxh;
+ if (unlikely(width < 48))
+ width = 48;
+ if (unlikely(width > maxw))
+ width = maxw;
+
+ get_scale(dev, width, height, &hscale, &vscale);
+
+ width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
+ height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
+
+ f->fmt.pix.width = width;
+ f->fmt.pix.height = height;
+ f->fmt.pix.pixelformat = fmt->fourcc;
+ f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3;
+ f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+ struct cx231xx_fmt *fmt;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ mutex_lock(&dev->lock);
+
+ vidioc_try_fmt_vid_cap(file, priv, f);
+
+ fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ if (!fmt) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ if (videobuf_queue_is_busy(&fh->vb_vidq)) {
+ cx231xx_errdev("%s queue busy\n", __func__);
+ rc = -EBUSY;
+ goto out;
+ }
+
+ if (dev->stream_on && !fh->stream_on) {
+ cx231xx_errdev("%s device in use by another fh\n", __func__);
+ rc = -EBUSY;
+ goto out;
+ }
+
+ /* set new image size */
+ dev->width = f->fmt.pix.width;
+ dev->height = f->fmt.pix.height;
+ dev->format = fmt;
+ get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
+
+ call_all(dev, video, s_fmt, f);
+
+ /* Set the correct alternate setting for this resolution */
+ cx231xx_resolution_set(dev);
+
+out:
+ mutex_unlock(&dev->lock);
+ return rc;
+}
+
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id * id)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+
+ *id = dev->norm;
+ return 0;
+}
+
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ struct v4l2_format f;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ cx231xx_info("vidioc_s_std : 0x%x\n", (unsigned int)*norm);
+
+ mutex_lock(&dev->lock);
+ dev->norm = *norm;
+
+ /* Adjusts width/height, if needed */
+ f.fmt.pix.width = dev->width;
+ f.fmt.pix.height = dev->height;
+ vidioc_try_fmt_vid_cap(file, priv, &f);
+
+ /* set new image size */
+ dev->width = f.fmt.pix.width;
+ dev->height = f.fmt.pix.height;
+ get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
+
+ call_all(dev, core, s_std, dev->norm);
+
+ mutex_unlock(&dev->lock);
+
+ cx231xx_resolution_set(dev);
+
+ /* do mode control overrides */
+ cx231xx_do_mode_ctrl_overrides(dev);
+
+ return 0;
+}
+
+static const char *iname[] = {
+ [CX231XX_VMUX_COMPOSITE1] = "Composite1",
+ [CX231XX_VMUX_SVIDEO] = "S-Video",
+ [CX231XX_VMUX_TELEVISION] = "Television",
+ [CX231XX_VMUX_CABLE] = "Cable TV",
+ [CX231XX_VMUX_DVB] = "DVB",
+ [CX231XX_VMUX_DEBUG] = "for debug only",
+};
+
+static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *i)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ unsigned int n;
+
+ n = i->index;
+ if (n >= MAX_CX231XX_INPUT)
+ return -EINVAL;
+ if (0 == INPUT(n)->type)
+ return -EINVAL;
+
+ i->index = n;
+ i->type = V4L2_INPUT_TYPE_CAMERA;
+
+ strcpy(i->name, iname[INPUT(n)->type]);
+
+ if ((CX231XX_VMUX_TELEVISION == INPUT(n)->type) ||
+ (CX231XX_VMUX_CABLE == INPUT(n)->type))
+ i->type = V4L2_INPUT_TYPE_TUNER;
+
+ i->std = dev->vdev->tvnorms;
+
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+
+ *i = dev->video_input;
+
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ if (i >= MAX_CX231XX_INPUT)
+ return -EINVAL;
+ if (0 == INPUT(i)->type)
+ return -EINVAL;
+
+ mutex_lock(&dev->lock);
+
+ video_mux(dev, i);
+
+ mutex_unlock(&dev->lock);
+ return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+
+ switch (a->index) {
+ case CX231XX_AMUX_VIDEO:
+ strcpy(a->name, "Television");
+ break;
+ case CX231XX_AMUX_LINE_IN:
+ strcpy(a->name, "Line In");
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ a->index = dev->ctl_ainput;
+ a->capability = V4L2_AUDCAP_STEREO;
+
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int status = 0;
+
+ /* Doesn't allow manual routing */
+ if (a->index != dev->ctl_ainput)
+ return -EINVAL;
+
+ dev->ctl_ainput = INPUT(a->index)->amux;
+ status = cx231xx_set_audio_input(dev, dev->ctl_ainput);
+
+ return status;
+}
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int id = qc->id;
+ int i;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ qc->id = v4l2_ctrl_next(ctrl_classes, qc->id);
+ if (unlikely(qc->id == 0))
+ return -EINVAL;
+
+ memset(qc, 0, sizeof(*qc));
+
+ qc->id = id;
+
+ if (qc->id < V4L2_CID_BASE || qc->id >= V4L2_CID_LASTP1)
+ return -EINVAL;
+
+ for (i = 0; i < CX231XX_CTLS; i++)
+ if (cx231xx_ctls[i].v.id == qc->id)
+ break;
+
+ if (i == CX231XX_CTLS) {
+ *qc = no_ctl;
+ return 0;
+ }
+ *qc = cx231xx_ctls[i].v;
+
+ mutex_lock(&dev->lock);
+ call_all(dev, core, queryctrl, qc);
+ mutex_unlock(&dev->lock);
+
+ if (qc->type)
+ return 0;
+ else
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ mutex_lock(&dev->lock);
+ call_all(dev, core, g_ctrl, ctrl);
+ mutex_unlock(&dev->lock);
+ return rc;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ mutex_lock(&dev->lock);
+ call_all(dev, core, s_ctrl, ctrl);
+ mutex_unlock(&dev->lock);
+ return rc;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ if (0 != t->index)
+ return -EINVAL;
+
+ strcpy(t->name, "Tuner");
+
+ t->type = V4L2_TUNER_ANALOG_TV;
+ t->capability = V4L2_TUNER_CAP_NORM;
+ t->rangehigh = 0xffffffffUL;
+ t->signal = 0xffff; /* LOCKED */
+
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ if (0 != t->index)
+ return -EINVAL;
+#if 0
+ mutex_lock(&dev->lock);
+ call_all(dev, tuner, s_tuner, t);
+ mutex_unlock(&dev->lock);
+#endif
+ return 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+
+ mutex_lock(&dev->lock);
+ f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+ f->frequency = dev->ctl_freq;
+
+ call_all(dev, tuner, g_frequency, f);
+
+ mutex_unlock(&dev->lock);
+
+ return 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ if (0 != f->tuner)
+ return -EINVAL;
+
+ if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV))
+ return -EINVAL;
+ if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO))
+ return -EINVAL;
+
+ /* set pre channel change settings in DIF first */
+ rc = cx231xx_tuner_pre_channel_change(dev);
+
+ mutex_lock(&dev->lock);
+
+ dev->ctl_freq = f->frequency;
+
+ if (dev->tuner_type == TUNER_XC5000) {
+ if (dev->cx231xx_set_analog_freq != NULL)
+ dev->cx231xx_set_analog_freq(dev, f->frequency);
+ } else
+ call_all(dev, tuner, s_frequency, f);
+
+ mutex_unlock(&dev->lock);
+
+ /* set post channel change settings in DIF first */
+ rc = cx231xx_tuner_post_channel_change(dev);
+
+ cx231xx_info("Set New FREQUENCY to %d\n", f->frequency);
+
+ return rc;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+
+/*
+ -R, --list-registers=type=<host/i2cdrv/i2caddr>,
+ chip=<chip>[,min=<addr>,max=<addr>]
+ dump registers from <min> to <max> [VIDIOC_DBG_G_REGISTER]
+ -r, --set-register=type=<host/i2cdrv/i2caddr>,
+ chip=<chip>,reg=<addr>,val=<val>
+ set the register [VIDIOC_DBG_S_REGISTER]
+
+ if type == host, then <chip> is the hosts chip ID (default 0)
+ if type == i2cdrv (default), then <chip> is the I2C driver name or ID
+ if type == i2caddr, then <chip> is the 7-bit I2C address
+*/
+
+static int vidioc_g_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int ret = 0;
+ u8 value[4] = { 0, 0, 0, 0 };
+ u32 data = 0;
+
+ switch (reg->match.type) {
+ case V4L2_CHIP_MATCH_HOST:
+ switch (reg->match.addr) {
+ case 0: /* Cx231xx - internal registers */
+ ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
+ (u16)reg->reg, value, 4);
+ reg->val = value[0] | value[1] << 8 |
+ value[2] << 16 | value[3] << 24;
+ break;
+ case 1: /* AFE - read byte */
+ ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
+ (u16)reg->reg, 2, &data, 1);
+ reg->val = le32_to_cpu(data & 0xff);
+ break;
+ case 14: /* AFE - read dword */
+ ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
+ (u16)reg->reg, 2, &data, 4);
+ reg->val = le32_to_cpu(data);
+ break;
+ case 2: /* Video Block - read byte */
+ ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+ (u16)reg->reg, 2, &data, 1);
+ reg->val = le32_to_cpu(data & 0xff);
+ break;
+ case 24: /* Video Block - read dword */
+ ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+ (u16)reg->reg, 2, &data, 4);
+ reg->val = le32_to_cpu(data);
+ break;
+ case 3: /* I2S block - read byte */
+ ret = cx231xx_read_i2c_data(dev,
+ I2S_BLK_DEVICE_ADDRESS,
+ (u16)reg->reg, 1,
+ &data, 1);
+ reg->val = le32_to_cpu(data & 0xff);
+ break;
+ case 34: /* I2S Block - read dword */
+ ret =
+ cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+ (u16)reg->reg, 1, &data, 4);
+ reg->val = le32_to_cpu(data);
+ break;
+ }
+ return ret < 0 ? ret : 0;
+
+ case V4L2_CHIP_MATCH_I2C_DRIVER:
+ call_all(dev, core, g_register, reg);
+ return 0;
+ case V4L2_CHIP_MATCH_I2C_ADDR:
+ /* Not supported yet */
+ return -EINVAL;
+ default:
+ if (!v4l2_chip_match_host(&reg->match))
+ return -EINVAL;
+ }
+
+ mutex_lock(&dev->lock);
+ call_all(dev, core, g_register, reg);
+ mutex_unlock(&dev->lock);
+
+ return ret;
+}
+
+static int vidioc_s_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int ret = 0;
+ __le64 buf;
+ u32 value;
+ u8 data[4] = { 0, 0, 0, 0 };
+
+ buf = cpu_to_le64(reg->val);
+
+ switch (reg->match.type) {
+ case V4L2_CHIP_MATCH_HOST:
+ {
+ value = (u32) buf & 0xffffffff;
+
+ switch (reg->match.addr) {
+ case 0: /* cx231xx internal registers */
+ data[0] = (u8) value;
+ data[1] = (u8) (value >> 8);
+ data[2] = (u8) (value >> 16);
+ data[3] = (u8) (value >> 24);
+ ret = cx231xx_write_ctrl_reg(dev,
+ VRT_SET_REGISTER,
+ (u16)reg->reg, data,
+ 4);
+ break;
+ case 1: /* AFE - read byte */
+ ret = cx231xx_write_i2c_data(dev,
+ AFE_DEVICE_ADDRESS,
+ (u16)reg->reg, 2,
+ value, 1);
+ break;
+ case 14: /* AFE - read dword */
+ ret = cx231xx_write_i2c_data(dev,
+ AFE_DEVICE_ADDRESS,
+ (u16)reg->reg, 2,
+ value, 4);
+ break;
+ case 2: /* Video Block - read byte */
+ ret =
+ cx231xx_write_i2c_data(dev,
+ VID_BLK_I2C_ADDRESS,
+ (u16)reg->reg, 2,
+ value, 1);
+ break;
+ case 24: /* Video Block - read dword */
+ ret =
+ cx231xx_write_i2c_data(dev,
+ VID_BLK_I2C_ADDRESS,
+ (u16)reg->reg, 2,
+ value, 4);
+ break;
+ case 3: /* I2S block - read byte */
+ ret =
+ cx231xx_write_i2c_data(dev,
+ I2S_BLK_DEVICE_ADDRESS,
+ (u16)reg->reg, 1,
+ value, 1);
+ break;
+ case 34: /* I2S block - read dword */
+ ret =
+ cx231xx_write_i2c_data(dev,
+ I2S_BLK_DEVICE_ADDRESS,
+ (u16)reg->reg, 1,
+ value, 4);
+ break;
+ }
+ }
+ return ret < 0 ? ret : 0;
+
+ default:
+ break;
+ }
+
+ mutex_lock(&dev->lock);
+ call_all(dev, core, s_register, reg);
+ mutex_unlock(&dev->lock);
+
+ return ret;
+}
+#endif
+
+static int vidioc_cropcap(struct file *file, void *priv,
+ struct v4l2_cropcap *cc)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+
+ if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ cc->bounds.left = 0;
+ cc->bounds.top = 0;
+ cc->bounds.width = dev->width;
+ cc->bounds.height = dev->height;
+ cc->defrect = cc->bounds;
+ cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */
+ cc->pixelaspect.denominator = 59;
+
+ return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ mutex_lock(&dev->lock);
+ rc = res_get(fh);
+
+ if (likely(rc >= 0))
+ rc = videobuf_streamon(&fh->vb_vidq);
+
+ call_all(dev, video, s_stream, 1);
+
+ mutex_unlock(&dev->lock);
+
+ return rc;
+}
+
+static int vidioc_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
+ (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))
+ return -EINVAL;
+ if (type != fh->type)
+ return -EINVAL;
+
+ mutex_lock(&dev->lock);
+
+ cx25840_call(dev, video, s_stream, 0);
+
+ videobuf_streamoff(&fh->vb_vidq);
+ res_free(fh);
+
+ mutex_unlock(&dev->lock);
+
+ return 0;
+}
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+
+ strlcpy(cap->driver, "cx231xx", sizeof(cap->driver));
+ strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
+
+ cap->version = CX231XX_VERSION_CODE;
+
+ cap->capabilities = V4L2_CAP_VBI_CAPTURE |
+#if 0
+ V4L2_CAP_SLICED_VBI_CAPTURE |
+#endif
+ V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_AUDIO |
+ V4L2_CAP_READWRITE |
+ V4L2_CAP_STREAMING;
+
+ if (dev->tuner_type != TUNER_ABSENT)
+ cap->capabilities |= V4L2_CAP_TUNER;
+
+ return 0;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ if (unlikely(f->index >= ARRAY_SIZE(format)))
+ return -EINVAL;
+
+ strlcpy(f->description, format[f->index].name, sizeof(f->description));
+ f->pixelformat = format[f->index].fourcc;
+
+ return 0;
+}
+
+/* Sliced VBI ioctls */
+static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ mutex_lock(&dev->lock);
+
+ f->fmt.sliced.service_set = 0;
+
+ call_all(dev, video, g_fmt, f);
+
+ if (f->fmt.sliced.service_set == 0)
+ rc = -EINVAL;
+
+ mutex_unlock(&dev->lock);
+ return rc;
+}
+
+static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ mutex_lock(&dev->lock);
+ call_all(dev, video, g_fmt, f);
+ mutex_unlock(&dev->lock);
+
+ if (f->fmt.sliced.service_set == 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+/* RAW VBI ioctls */
+
+static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+
+ f->fmt.vbi.sampling_rate = (dev->norm & V4L2_STD_625_50) ?
+ 35468950 : 28636363;
+ f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
+ f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
+ f->fmt.vbi.offset = 64 * 4;
+ f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ?
+ PAL_VBI_START_LINE : NTSC_VBI_START_LINE;
+ f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ?
+ PAL_VBI_LINES : NTSC_VBI_LINES;
+ f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ?
+ PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263;
+ f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
+
+ return 0;
+
+}
+
+static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+
+ if (dev->vbi_stream_on && !fh->stream_on) {
+ cx231xx_errdev("%s device in use by another fh\n", __func__);
+ return -EBUSY;
+ }
+
+ f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ f->fmt.vbi.sampling_rate = (dev->norm & V4L2_STD_625_50) ?
+ 35468950 : 28636363;
+ f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
+ f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
+ f->fmt.vbi.offset = 244;
+ f->fmt.vbi.flags = 0;
+ f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ?
+ PAL_VBI_START_LINE : NTSC_VBI_START_LINE;
+ f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ?
+ PAL_VBI_LINES : NTSC_VBI_LINES;
+ f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ?
+ PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263;
+ f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
+
+ return 0;
+
+}
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *rb)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ return videobuf_reqbufs(&fh->vb_vidq, rb);
+}
+
+static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ return videobuf_querybuf(&fh->vb_vidq, b);
+}
+
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ return videobuf_qbuf(&fh->vb_vidq, b);
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+ struct cx231xx_fh *fh = priv;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
+}
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
+{
+ struct cx231xx_fh *fh = priv;
+
+ return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
+}
+#endif
+
+/* ----------------------------------------------------------- */
+/* RADIO ESPECIFIC IOCTLS */
+/* ----------------------------------------------------------- */
+
+static int radio_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;
+
+ strlcpy(cap->driver, "cx231xx", sizeof(cap->driver));
+ strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
+
+ cap->version = CX231XX_VERSION_CODE;
+ cap->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
+{
+ struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;
+
+ if (unlikely(t->index > 0))
+ return -EINVAL;
+
+ strcpy(t->name, "Radio");
+ t->type = V4L2_TUNER_RADIO;
+
+ mutex_lock(&dev->lock);
+ call_all(dev, tuner, s_tuner, t);
+ mutex_unlock(&dev->lock);
+
+ return 0;
+}
+
+static int radio_enum_input(struct file *file, void *priv, struct v4l2_input *i)
+{
+ if (i->index != 0)
+ return -EINVAL;
+ strcpy(i->name, "Radio");
+ i->type = V4L2_INPUT_TYPE_TUNER;
+
+ return 0;
+}
+
+static int radio_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+ if (unlikely(a->index))
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ return 0;
+}
+
+static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
+{
+ struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;
+
+ if (0 != t->index)
+ return -EINVAL;
+
+ mutex_lock(&dev->lock);
+ call_all(dev, tuner, s_tuner, t);
+ mutex_unlock(&dev->lock);
+
+ return 0;
+}
+
+static int radio_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ return 0;
+}
+
+static int radio_s_input(struct file *file, void *fh, unsigned int i)
+{
+ return 0;
+}
+
+static int radio_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *c)
+{
+ int i;
+
+ if (c->id < V4L2_CID_BASE || c->id >= V4L2_CID_LASTP1)
+ return -EINVAL;
+ if (c->id == V4L2_CID_AUDIO_MUTE) {
+ for (i = 0; i < CX231XX_CTLS; i++)
+ if (cx231xx_ctls[i].v.id == c->id)
+ break;
+ *c = cx231xx_ctls[i].v;
+ } else
+ *c = no_ctl;
+ return 0;
+}
+
+/*
+ * cx231xx_v4l2_open()
+ * inits the device and starts isoc transfer
+ */
+static int cx231xx_v4l2_open(struct file *filp)
+{
+ int minor = video_devdata(filp)->minor;
+ int errCode = 0, radio = 0;
+ struct cx231xx *dev = NULL;
+ struct cx231xx_fh *fh;
+ enum v4l2_buf_type fh_type = 0;
+
+ dev = cx231xx_get_device(minor, &fh_type, &radio);
+ if (NULL == dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->lock);
+
+ cx231xx_videodbg("open minor=%d type=%s users=%d\n",
+ minor, v4l2_type_names[fh_type], dev->users);
+
+#if 0
+ errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
+ if (errCode < 0) {
+ cx231xx_errdev
+ ("Device locked on digital mode. Can't open analog\n");
+ mutex_unlock(&dev->lock);
+ return -EBUSY;
+ }
+#endif
+
+ fh = kzalloc(sizeof(struct cx231xx_fh), GFP_KERNEL);
+ if (!fh) {
+ cx231xx_errdev("cx231xx-video.c: Out of memory?!\n");
+ mutex_unlock(&dev->lock);
+ return -ENOMEM;
+ }
+ fh->dev = dev;
+ fh->radio = radio;
+ fh->type = fh_type;
+ filp->private_data = fh;
+
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
+ dev->width = norm_maxw(dev);
+ dev->height = norm_maxh(dev);
+ dev->hscale = 0;
+ dev->vscale = 0;
+
+ /* Power up in Analog TV mode */
+ cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV);
+
+#if 0
+ cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
+#endif
+ cx231xx_resolution_set(dev);
+
+ /* set video alternate setting */
+ cx231xx_set_video_alternate(dev);
+
+ /* Needed, since GPIO might have disabled power of
+ some i2c device */
+ cx231xx_config_i2c(dev);
+
+ /* device needs to be initialized before isoc transfer */
+ dev->video_input = dev->video_input > 2 ? 2 : dev->video_input;
+ video_mux(dev, dev->video_input);
+
+ }
+ if (fh->radio) {
+ cx231xx_videodbg("video_open: setting radio device\n");
+
+ /* cx231xx_start_radio(dev); */
+
+ call_all(dev, tuner, s_radio);
+ }
+
+ dev->users++;
+
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_video_qops,
+ NULL, &dev->video_mode.slock,
+ fh->type, V4L2_FIELD_INTERLACED,
+ sizeof(struct cx231xx_buffer), fh);
+ if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ /* Set the required alternate setting VBI interface works in
+ Bulk mode only */
+ cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
+
+ videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops,
+ NULL, &dev->vbi_mode.slock,
+ fh->type, V4L2_FIELD_SEQ_TB,
+ sizeof(struct cx231xx_buffer), fh);
+ }
+
+ mutex_unlock(&dev->lock);
+
+ return errCode;
+}
+
+/*
+ * cx231xx_realease_resources()
+ * unregisters the v4l2,i2c and usb devices
+ * called when the device gets disconected or at module unload
+*/
+void cx231xx_release_analog_resources(struct cx231xx *dev)
+{
+
+ /*FIXME: I2C IR should be disconnected */
+
+ if (dev->radio_dev) {
+ if (-1 != dev->radio_dev->minor)
+ video_unregister_device(dev->radio_dev);
+ else
+ video_device_release(dev->radio_dev);
+ dev->radio_dev = NULL;
+ }
+ if (dev->vbi_dev) {
+ cx231xx_info("V4L2 device /dev/vbi%d deregistered\n",
+ dev->vbi_dev->num);
+ if (-1 != dev->vbi_dev->minor)
+ video_unregister_device(dev->vbi_dev);
+ else
+ video_device_release(dev->vbi_dev);
+ dev->vbi_dev = NULL;
+ }
+ if (dev->vdev) {
+ cx231xx_info("V4L2 device /dev/video%d deregistered\n",
+ dev->vdev->num);
+ if (-1 != dev->vdev->minor)
+ video_unregister_device(dev->vdev);
+ else
+ video_device_release(dev->vdev);
+ dev->vdev = NULL;
+ }
+}
+
+/*
+ * cx231xx_v4l2_close()
+ * stops streaming and deallocates all resources allocated by the v4l2
+ * calls and ioctls
+ */
+static int cx231xx_v4l2_close(struct file *filp)
+{
+ struct cx231xx_fh *fh = filp->private_data;
+ struct cx231xx *dev = fh->dev;
+
+ cx231xx_videodbg("users=%d\n", dev->users);
+
+ mutex_lock(&dev->lock);
+
+ if (res_check(fh))
+ res_free(fh);
+
+ if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ videobuf_stop(&fh->vb_vidq);
+ videobuf_mmap_free(&fh->vb_vidq);
+
+ /* the device is already disconnect,
+ free the remaining resources */
+ if (dev->state & DEV_DISCONNECTED) {
+ cx231xx_release_resources(dev);
+ mutex_unlock(&dev->lock);
+ kfree(dev);
+ return 0;
+ }
+
+ /* do this before setting alternate! */
+ cx231xx_uninit_vbi_isoc(dev);
+
+ /* set alternate 0 */
+ if (!dev->vbi_or_sliced_cc_mode)
+ cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
+ else
+ cx231xx_set_alt_setting(dev, INDEX_HANC, 0);
+
+ kfree(fh);
+ dev->users--;
+ wake_up_interruptible_nr(&dev->open, 1);
+ mutex_unlock(&dev->lock);
+ return 0;
+ }
+
+ if (dev->users == 1) {
+ videobuf_stop(&fh->vb_vidq);
+ videobuf_mmap_free(&fh->vb_vidq);
+
+ /* the device is already disconnect,
+ free the remaining resources */
+ if (dev->state & DEV_DISCONNECTED) {
+ cx231xx_release_resources(dev);
+ mutex_unlock(&dev->lock);
+ kfree(dev);
+ return 0;
+ }
+
+ /* Save some power by putting tuner to sleep */
+ call_all(dev, tuner, s_standby);
+
+ /* do this before setting alternate! */
+ cx231xx_uninit_isoc(dev);
+ cx231xx_set_mode(dev, CX231XX_SUSPEND);
+
+ /* set alternate 0 */
+ cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0);
+ }
+ kfree(fh);
+ dev->users--;
+ wake_up_interruptible_nr(&dev->open, 1);
+ mutex_unlock(&dev->lock);
+ return 0;
+}
+
+/*
+ * cx231xx_v4l2_read()
+ * will allocate buffers when called for the first time
+ */
+static ssize_t
+cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
+ loff_t *pos)
+{
+ struct cx231xx_fh *fh = filp->private_data;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ if ((fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
+ (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)) {
+ mutex_lock(&dev->lock);
+ rc = res_get(fh);
+ mutex_unlock(&dev->lock);
+
+ if (unlikely(rc < 0))
+ return rc;
+
+ return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
+ filp->f_flags & O_NONBLOCK);
+ }
+ return 0;
+}
+
+/*
+ * cx231xx_v4l2_poll()
+ * will allocate buffers when called for the first time
+ */
+static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table * wait)
+{
+ struct cx231xx_fh *fh = filp->private_data;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ mutex_lock(&dev->lock);
+ rc = res_get(fh);
+ mutex_unlock(&dev->lock);
+
+ if (unlikely(rc < 0))
+ return POLLERR;
+
+ if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) ||
+ (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type))
+ return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
+ else
+ return POLLERR;
+}
+
+/*
+ * cx231xx_v4l2_mmap()
+ */
+static int cx231xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct cx231xx_fh *fh = filp->private_data;
+ struct cx231xx *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ mutex_lock(&dev->lock);
+ rc = res_get(fh);
+ mutex_unlock(&dev->lock);
+
+ if (unlikely(rc < 0))
+ return rc;
+
+ rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+
+ cx231xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
+ (unsigned long)vma->vm_start,
+ (unsigned long)vma->vm_end -
+ (unsigned long)vma->vm_start, rc);
+
+ return rc;
+}
+
+static const struct v4l2_file_operations cx231xx_v4l_fops = {
+ .owner = THIS_MODULE,
+ .open = cx231xx_v4l2_open,
+ .release = cx231xx_v4l2_close,
+ .read = cx231xx_v4l2_read,
+ .poll = cx231xx_v4l2_poll,
+ .mmap = cx231xx_v4l2_mmap,
+ .ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+ .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
+ .vidioc_try_fmt_vbi_cap = vidioc_try_fmt_vbi_cap,
+ .vidioc_s_fmt_vbi_cap = vidioc_try_fmt_vbi_cap,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_cropcap = vidioc_cropcap,
+ .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
+ .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+ .vidioc_s_std = vidioc_s_std,
+ .vidioc_g_std = vidioc_g_std,
+ .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = vidioc_g_register,
+ .vidioc_s_register = vidioc_s_register,
+#endif
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ .vidiocgmbuf = vidiocgmbuf,
+#endif
+};
+
+static struct video_device cx231xx_vbi_template;
+
+static const struct video_device cx231xx_video_template = {
+ .fops = &cx231xx_v4l_fops,
+ .release = video_device_release,
+ .ioctl_ops = &video_ioctl_ops,
+ .minor = -1,
+ .tvnorms = V4L2_STD_ALL,
+ .current_norm = V4L2_STD_PAL,
+};
+
+static const struct v4l2_file_operations radio_fops = {
+ .owner = THIS_MODULE,
+ .open = cx231xx_v4l2_open,
+ .release = cx231xx_v4l2_close,
+ .ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops radio_ioctl_ops = {
+ .vidioc_querycap = radio_querycap,
+ .vidioc_g_tuner = radio_g_tuner,
+ .vidioc_enum_input = radio_enum_input,
+ .vidioc_g_audio = radio_g_audio,
+ .vidioc_s_tuner = radio_s_tuner,
+ .vidioc_s_audio = radio_s_audio,
+ .vidioc_s_input = radio_s_input,
+ .vidioc_queryctrl = radio_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = vidioc_g_register,
+ .vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+static struct video_device cx231xx_radio_template = {
+ .name = "cx231xx-radio",
+ .fops = &radio_fops,
+ .ioctl_ops = &radio_ioctl_ops,
+ .minor = -1,
+};
+
+/******************************** usb interface ******************************/
+
+static struct video_device *cx231xx_vdev_init(struct cx231xx *dev,
+ const struct video_device
+ *template, const char *type_name)
+{
+ struct video_device *vfd;
+
+ vfd = video_device_alloc();
+ if (NULL == vfd)
+ return NULL;
+
+ *vfd = *template;
+ vfd->minor = -1;
+ vfd->v4l2_dev = &dev->v4l2_dev;
+ vfd->release = video_device_release;
+ vfd->debug = video_debug;
+
+ snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
+
+ return vfd;
+}
+
+int cx231xx_register_analog_devices(struct cx231xx *dev)
+{
+ int ret;
+
+ cx231xx_info("%s: v4l2 driver version %d.%d.%d\n",
+ dev->name,
+ (CX231XX_VERSION_CODE >> 16) & 0xff,
+ (CX231XX_VERSION_CODE >> 8) & 0xff,
+ CX231XX_VERSION_CODE & 0xff);
+
+ /* set default norm */
+ /*dev->norm = cx231xx_video_template.current_norm; */
+ dev->width = norm_maxw(dev);
+ dev->height = norm_maxh(dev);
+ dev->interlaced = 0;
+ dev->hscale = 0;
+ dev->vscale = 0;
+
+ /* Analog specific initialization */
+ dev->format = &format[0];
+ /* video_mux(dev, dev->video_input); */
+
+ /* Audio defaults */
+ dev->mute = 1;
+ dev->volume = 0x1f;
+
+ /* enable vbi capturing */
+ /* write code here... */
+
+ /* allocate and fill video video_device struct */
+ dev->vdev = cx231xx_vdev_init(dev, &cx231xx_video_template, "video");
+ if (!dev->vdev) {
+ cx231xx_errdev("cannot allocate video_device.\n");
+ return -ENODEV;
+ }
+
+ /* register v4l2 video video_device */
+ ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
+ video_nr[dev->devno]);
+ if (ret) {
+ cx231xx_errdev("unable to register video device (error=%i).\n",
+ ret);
+ return ret;
+ }
+
+ cx231xx_info("%s/0: registered device video%d [v4l2]\n",
+ dev->name, dev->vdev->num);
+
+ /* Initialize VBI template */
+ memcpy(&cx231xx_vbi_template, &cx231xx_video_template,
+ sizeof(cx231xx_vbi_template));
+ strcpy(cx231xx_vbi_template.name, "cx231xx-vbi");
+
+ /* Allocate and fill vbi video_device struct */
+ dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi");
+
+ /* register v4l2 vbi video_device */
+ ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
+ vbi_nr[dev->devno]);
+ if (ret < 0) {
+ cx231xx_errdev("unable to register vbi device\n");
+ return ret;
+ }
+
+ cx231xx_info("%s/0: registered device vbi%d\n",
+ dev->name, dev->vbi_dev->num);
+
+ if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) {
+ dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template,
+ "radio");
+ if (!dev->radio_dev) {
+ cx231xx_errdev("cannot allocate video_device.\n");
+ return -ENODEV;
+ }
+ ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
+ radio_nr[dev->devno]);
+ if (ret < 0) {
+ cx231xx_errdev("can't register radio device\n");
+ return ret;
+ }
+ cx231xx_info("Registered radio device as /dev/radio%d\n",
+ dev->radio_dev->num);
+ }
+
+ cx231xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
+ dev->vdev->num, dev->vbi_dev->num);
+
+ return 0;
+}
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
new file mode 100644
index 00000000000..aa4a23ef491
--- /dev/null
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -0,0 +1,779 @@
+/*
+ cx231xx.h - driver for Conexant Cx23100/101/102 USB video capture devices
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+ Based on em28xx driver
+
+ 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.
+ */
+
+#ifndef _CX231XX_H
+#define _CX231XX_H
+
+#include <linux/videodev2.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/mutex.h>
+
+
+#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
+#include <media/ir-kbd-i2c.h>
+#if defined(CONFIG_VIDEO_CX231XX_DVB) || \
+ defined(CONFIG_VIDEO_CX231XX_DVB_MODULE)
+#include <media/videobuf-dvb.h>
+#endif
+
+#include "cx231xx-reg.h"
+#include "cx231xx-pcb-cfg.h"
+#include "cx231xx-conf-reg.h"
+
+#define DRIVER_NAME "cx231xx"
+#define PWR_SLEEP_INTERVAL 5
+
+/* I2C addresses for control block in Cx231xx */
+#define AFE_DEVICE_ADDRESS 0x60
+#define I2S_BLK_DEVICE_ADDRESS 0x98
+#define VID_BLK_I2C_ADDRESS 0x88
+#define DIF_USE_BASEBAND 0xFFFFFFFF
+
+/* Boards supported by driver */
+#define CX231XX_BOARD_UNKNOWN 0
+#define CX231XX_BOARD_CNXT_RDE_250 1
+#define CX231XX_BOARD_CNXT_RDU_250 2
+
+/* Limits minimum and default number of buffers */
+#define CX231XX_MIN_BUF 4
+#define CX231XX_DEF_BUF 12
+#define CX231XX_DEF_VBI_BUF 6
+
+#define VBI_LINE_COUNT 17
+#define VBI_LINE_LENGTH 1440
+
+/*Limits the max URB message size */
+#define URB_MAX_CTRL_SIZE 80
+
+/* Params for validated field */
+#define CX231XX_BOARD_NOT_VALIDATED 1
+#define CX231XX_BOARD_VALIDATED 0
+
+/* maximum number of cx231xx boards */
+#define CX231XX_MAXBOARDS 8
+
+/* maximum number of frames that can be queued */
+#define CX231XX_NUM_FRAMES 5
+
+/* number of buffers for isoc transfers */
+#define CX231XX_NUM_BUFS 8
+
+/* number of packets for each buffer
+ windows requests only 40 packets .. so we better do the same
+ this is what I found out for all alternate numbers there!
+ */
+#define CX231XX_NUM_PACKETS 40
+
+/* default alternate; 0 means choose the best */
+#define CX231XX_PINOUT 0
+
+#define CX231XX_INTERLACED_DEFAULT 1
+
+/* time to wait when stopping the isoc transfer */
+#define CX231XX_URB_TIMEOUT \
+ msecs_to_jiffies(CX231XX_NUM_BUFS * CX231XX_NUM_PACKETS)
+
+enum cx231xx_mode {
+ CX231XX_SUSPEND,
+ CX231XX_ANALOG_MODE,
+ CX231XX_DIGITAL_MODE,
+};
+
+enum cx231xx_std_mode {
+ CX231XX_TV_AIR = 0,
+ CX231XX_TV_CABLE
+};
+
+enum cx231xx_stream_state {
+ STREAM_OFF,
+ STREAM_INTERRUPT,
+ STREAM_ON,
+};
+
+struct cx231xx;
+
+struct cx231xx_usb_isoc_ctl {
+ /* max packet size of isoc transaction */
+ int max_pkt_size;
+
+ /* number of allocated urbs */
+ int num_bufs;
+
+ /* urb for isoc transfers */
+ struct urb **urb;
+
+ /* transfer buffers for isoc transfer */
+ char **transfer_buffer;
+
+ /* Last buffer command and region */
+ u8 cmd;
+ int pos, size, pktsize;
+
+ /* Last field: ODD or EVEN? */
+ int field;
+
+ /* Stores incomplete commands */
+ u32 tmp_buf;
+ int tmp_buf_len;
+
+ /* Stores already requested buffers */
+ struct cx231xx_buffer *buf;
+
+ /* Stores the number of received fields */
+ int nfields;
+
+ /* isoc urb callback */
+ int (*isoc_copy) (struct cx231xx *dev, struct urb *urb);
+};
+
+struct cx231xx_fmt {
+ char *name;
+ u32 fourcc; /* v4l2 format id */
+ int depth;
+ int reg;
+};
+
+/* buffer for one video frame */
+struct cx231xx_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct videobuf_buffer vb;
+
+ struct list_head frame;
+ int top_field;
+ int receiving;
+};
+
+struct cx231xx_dmaqueue {
+ struct list_head active;
+ struct list_head queued;
+
+ wait_queue_head_t wq;
+
+ /* Counters to control buffer fill */
+ int pos;
+ u8 is_partial_line;
+ u8 partial_buf[8];
+ u8 last_sav;
+ int current_field;
+ u32 bytes_left_in_line;
+ u32 lines_completed;
+ u8 field1_done;
+ u32 lines_per_field;
+};
+
+/* inputs */
+
+#define MAX_CX231XX_INPUT 4
+
+enum cx231xx_itype {
+ CX231XX_VMUX_COMPOSITE1 = 1,
+ CX231XX_VMUX_SVIDEO,
+ CX231XX_VMUX_TELEVISION,
+ CX231XX_VMUX_CABLE,
+ CX231XX_RADIO,
+ CX231XX_VMUX_DVB,
+ CX231XX_VMUX_DEBUG
+};
+
+enum cx231xx_v_input {
+ CX231XX_VIN_1_1 = 0x1,
+ CX231XX_VIN_2_1,
+ CX231XX_VIN_3_1,
+ CX231XX_VIN_4_1,
+ CX231XX_VIN_1_2 = 0x01,
+ CX231XX_VIN_2_2,
+ CX231XX_VIN_3_2,
+ CX231XX_VIN_1_3 = 0x1,
+ CX231XX_VIN_2_3,
+ CX231XX_VIN_3_3,
+};
+
+/* cx231xx has two audio inputs: tuner and line in */
+enum cx231xx_amux {
+ /* This is the only entry for cx231xx tuner input */
+ CX231XX_AMUX_VIDEO, /* cx231xx tuner */
+ CX231XX_AMUX_LINE_IN, /* Line In */
+};
+
+struct cx231xx_reg_seq {
+ unsigned char bit;
+ unsigned char val;
+ int sleep;
+};
+
+struct cx231xx_input {
+ enum cx231xx_itype type;
+ unsigned int vmux;
+ enum cx231xx_amux amux;
+ struct cx231xx_reg_seq *gpio;
+};
+
+#define INPUT(nr) (&cx231xx_boards[dev->model].input[nr])
+
+enum cx231xx_decoder {
+ CX231XX_NODECODER,
+ CX231XX_AVDECODER
+};
+
+enum CX231XX_I2C_MASTER_PORT {
+ I2C_0 = 0,
+ I2C_1 = 1,
+ I2C_2 = 2,
+ I2C_3 = 3
+};
+
+struct cx231xx_board {
+ char *name;
+ int vchannels;
+ int tuner_type;
+ int tuner_addr;
+ v4l2_std_id norm; /* tv norm */
+
+ /* demod related */
+ int demod_addr;
+ u8 demod_xfer_mode; /* 0 - Serial; 1 - parallel */
+
+ /* GPIO Pins */
+ struct cx231xx_reg_seq *dvb_gpio;
+ struct cx231xx_reg_seq *suspend_gpio;
+ struct cx231xx_reg_seq *tuner_gpio;
+ u8 tuner_sif_gpio;
+ u8 tuner_scl_gpio;
+ u8 tuner_sda_gpio;
+
+ /* PIN ctrl */
+ u32 ctl_pin_status_mask;
+ u8 agc_analog_digital_select_gpio;
+ u32 gpio_pin_status_mask;
+
+ /* i2c masters */
+ u8 tuner_i2c_master;
+ u8 demod_i2c_master;
+
+ unsigned int max_range_640_480:1;
+ unsigned int has_dvb:1;
+ unsigned int valid:1;
+
+ unsigned char xclk, i2c_speed;
+
+ enum cx231xx_decoder decoder;
+
+ struct cx231xx_input input[MAX_CX231XX_INPUT];
+ struct cx231xx_input radio;
+ IR_KEYTAB_TYPE *ir_codes;
+};
+
+/* device states */
+enum cx231xx_dev_state {
+ DEV_INITIALIZED = 0x01,
+ DEV_DISCONNECTED = 0x02,
+ DEV_MISCONFIGURED = 0x04,
+};
+
+enum AFE_MODE {
+ AFE_MODE_LOW_IF,
+ AFE_MODE_BASEBAND,
+ AFE_MODE_EU_HI_IF,
+ AFE_MODE_US_HI_IF,
+ AFE_MODE_JAPAN_HI_IF
+};
+
+enum AUDIO_INPUT {
+ AUDIO_INPUT_MUTE,
+ AUDIO_INPUT_LINE,
+ AUDIO_INPUT_TUNER_TV,
+ AUDIO_INPUT_SPDIF,
+ AUDIO_INPUT_TUNER_FM
+};
+
+#define CX231XX_AUDIO_BUFS 5
+#define CX231XX_NUM_AUDIO_PACKETS 64
+#define CX231XX_CAPTURE_STREAM_EN 1
+#define CX231XX_STOP_AUDIO 0
+#define CX231XX_START_AUDIO 1
+
+/* cx231xx extensions */
+#define CX231XX_AUDIO 0x10
+#define CX231XX_DVB 0x20
+
+struct cx231xx_audio {
+ char name[50];
+ char *transfer_buffer[CX231XX_AUDIO_BUFS];
+ struct urb *urb[CX231XX_AUDIO_BUFS];
+ struct usb_device *udev;
+ unsigned int capture_transfer_done;
+ struct snd_pcm_substream *capture_pcm_substream;
+
+ unsigned int hwptr_done_capture;
+ struct snd_card *sndcard;
+
+ int users, shutdown;
+ enum cx231xx_stream_state capture_stream;
+ spinlock_t slock;
+
+ int alt; /* alternate */
+ int max_pkt_size; /* max packet size of isoc transaction */
+ int num_alt; /* Number of alternative settings */
+ unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
+ u16 end_point_addr;
+};
+
+struct cx231xx;
+
+struct cx231xx_fh {
+ struct cx231xx *dev;
+ unsigned int stream_on:1; /* Locks streams */
+ int radio;
+
+ struct videobuf_queue vb_vidq;
+
+ enum v4l2_buf_type type;
+};
+
+/*****************************************************************/
+/* set/get i2c */
+/* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */
+#define I2C_SPEED_1M 0x0
+#define I2C_SPEED_400K 0x1
+#define I2C_SPEED_100K 0x2
+#define I2C_SPEED_5M 0x3
+
+/* 0-- STOP transaction */
+#define I2C_STOP 0x0
+/* 1-- do not transmit STOP at end of transaction */
+#define I2C_NOSTOP 0x1
+/* 1--alllow slave to insert clock wait states */
+#define I2C_SYNC 0x1
+
+struct cx231xx_i2c {
+ struct cx231xx *dev;
+
+ int nr;
+
+ /* i2c i/o */
+ struct i2c_adapter i2c_adap;
+ struct i2c_algo_bit_data i2c_algo;
+ struct i2c_client i2c_client;
+ u32 i2c_rc;
+
+ /* different settings for each bus */
+ u8 i2c_period;
+ u8 i2c_nostop;
+ u8 i2c_reserve;
+};
+
+struct cx231xx_i2c_xfer_data {
+ u8 dev_addr;
+ u8 direction; /* 1 - IN, 0 - OUT */
+ u8 saddr_len; /* sub address len */
+ u16 saddr_dat; /* sub addr data */
+ u8 buf_size; /* buffer size */
+ u8 *p_buffer; /* pointer to the buffer */
+};
+
+struct VENDOR_REQUEST_IN {
+ u8 bRequest;
+ u16 wValue;
+ u16 wIndex;
+ u16 wLength;
+ u8 direction;
+ u8 bData;
+ u8 *pBuff;
+};
+
+struct cx231xx_ctrl {
+ struct v4l2_queryctrl v;
+ u32 off;
+ u32 reg;
+ u32 mask;
+ u32 shift;
+};
+
+enum TRANSFER_TYPE {
+ Raw_Video = 0,
+ Audio,
+ Vbi, /* VANC */
+ Sliced_cc, /* HANC */
+ TS1_serial_mode,
+ TS2,
+ TS1_parallel_mode
+} ;
+
+struct cx231xx_video_mode {
+ /* Isoc control struct */
+ struct cx231xx_dmaqueue vidq;
+ struct cx231xx_usb_isoc_ctl isoc_ctl;
+ spinlock_t slock;
+
+ /* usb transfer */
+ int alt; /* alternate */
+ int max_pkt_size; /* max packet size of isoc transaction */
+ int num_alt; /* Number of alternative settings */
+ unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
+ u16 end_point_addr;
+};
+
+/* main device struct */
+struct cx231xx {
+ /* generic device properties */
+ char name[30]; /* name (including minor) of the device */
+ int model; /* index in the device_data struct */
+ int devno; /* marks the number of this device */
+
+ struct cx231xx_board board;
+
+ unsigned int stream_on:1; /* Locks streams */
+ unsigned int vbi_stream_on:1; /* Locks streams for VBI */
+ unsigned int has_audio_class:1;
+ unsigned int has_alsa_audio:1;
+
+ struct cx231xx_fmt *format;
+
+ struct v4l2_device v4l2_dev;
+ struct v4l2_subdev *sd_cx25840;
+ struct v4l2_subdev *sd_tuner;
+
+ struct cx231xx_IR *ir;
+
+ struct list_head devlist;
+
+ int tuner_type; /* type of the tuner */
+ int tuner_addr; /* tuner address */
+
+ /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
+ struct cx231xx_i2c i2c_bus[3];
+ unsigned int xc_fw_load_done:1;
+ struct mutex gpio_i2c_lock;
+
+ /* video for linux */
+ int users; /* user count for exclusive use */
+ struct video_device *vdev; /* video for linux device struct */
+ v4l2_std_id norm; /* selected tv norm */
+ int ctl_freq; /* selected frequency */
+ unsigned int ctl_ainput; /* selected audio input */
+ int mute;
+ int volume;
+
+ /* frame properties */
+ int width; /* current frame width */
+ int height; /* current frame height */
+ unsigned hscale; /* horizontal scale factor (see datasheet) */
+ unsigned vscale; /* vertical scale factor (see datasheet) */
+ int interlaced; /* 1=interlace fileds, 0=just top fileds */
+
+ struct cx231xx_audio adev;
+
+ /* states */
+ enum cx231xx_dev_state state;
+
+ struct work_struct request_module_wk;
+
+ /* locks */
+ struct mutex lock;
+ struct mutex ctrl_urb_lock; /* protects urb_buf */
+ struct list_head inqueue, outqueue;
+ wait_queue_head_t open, wait_frame, wait_stream;
+ struct video_device *vbi_dev;
+ struct video_device *radio_dev;
+
+ unsigned char eedata[256];
+
+ struct cx231xx_video_mode video_mode;
+ struct cx231xx_video_mode vbi_mode;
+ struct cx231xx_video_mode sliced_cc_mode;
+ struct cx231xx_video_mode ts1_mode;
+
+ struct usb_device *udev; /* the usb device */
+ char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */
+
+ /* helper funcs that call usb_control_msg */
+ int (*cx231xx_read_ctrl_reg) (struct cx231xx *dev, u8 req, u16 reg,
+ char *buf, int len);
+ int (*cx231xx_write_ctrl_reg) (struct cx231xx *dev, u8 req, u16 reg,
+ char *buf, int len);
+ int (*cx231xx_send_usb_command) (struct cx231xx_i2c *i2c_bus,
+ struct cx231xx_i2c_xfer_data *req_data);
+ int (*cx231xx_gpio_i2c_read) (struct cx231xx *dev, u8 dev_addr,
+ u8 *buf, u8 len);
+ int (*cx231xx_gpio_i2c_write) (struct cx231xx *dev, u8 dev_addr,
+ u8 *buf, u8 len);
+
+ int (*cx231xx_set_analog_freq) (struct cx231xx *dev, u32 freq);
+ int (*cx231xx_reset_analog_tuner) (struct cx231xx *dev);
+
+ enum cx231xx_mode mode;
+
+ struct cx231xx_dvb *dvb;
+
+ /* Cx231xx supported PCB config's */
+ struct pcb_config current_pcb_config;
+ u8 current_scenario_idx;
+ u8 interface_count;
+ u8 max_iad_interface_count;
+
+ /* GPIO related register direction and values */
+ u32 gpio_dir;
+ u32 gpio_val;
+
+ /* Power Modes */
+ int power_mode;
+
+ /* afe parameters */
+ enum AFE_MODE afe_mode;
+ u32 afe_ref_count;
+
+ /* video related parameters */
+ u32 video_input;
+ u32 active_mode;
+ u8 vbi_or_sliced_cc_mode; /* 0 - vbi ; 1 - sliced cc mode */
+ enum cx231xx_std_mode std_mode; /* 0 - Air; 1 - cable */
+
+};
+
+#define cx25840_call(cx231xx, o, f, args...) \
+ v4l2_subdev_call(cx231xx->sd_cx25840, o, f, ##args)
+#define tuner_call(cx231xx, o, f, args...) \
+ v4l2_subdev_call(cx231xx->sd_tuner, o, f, ##args)
+#define call_all(dev, o, f, args...) \
+ v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
+
+struct cx231xx_ops {
+ struct list_head next;
+ char *name;
+ int id;
+ int (*init) (struct cx231xx *);
+ int (*fini) (struct cx231xx *);
+};
+
+/* call back functions in dvb module */
+int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq);
+int cx231xx_reset_analog_tuner(struct cx231xx *dev);
+
+/* Provided by cx231xx-i2c.c */
+void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c);
+int cx231xx_i2c_register(struct cx231xx_i2c *bus);
+int cx231xx_i2c_unregister(struct cx231xx_i2c *bus);
+
+/* Internal block control functions */
+int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr,
+ u16 saddr, u8 saddr_len, u32 *data, u8 data_len);
+int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr,
+ u16 saddr, u8 saddr_len, u32 data, u8 data_len);
+int cx231xx_reg_mask_write(struct cx231xx *dev, u8 dev_addr, u8 size,
+ u16 register_address, u8 bit_start, u8 bit_end,
+ u32 value);
+int cx231xx_read_modify_write_i2c_dword(struct cx231xx *dev, u8 dev_addr,
+ u16 saddr, u32 mask, u32 value);
+u32 cx231xx_set_field(u32 field_mask, u32 data);
+
+/* afe related functions */
+int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count);
+int cx231xx_afe_init_channels(struct cx231xx *dev);
+int cx231xx_afe_setup_AFE_for_baseband(struct cx231xx *dev);
+int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux);
+int cx231xx_afe_set_mode(struct cx231xx *dev, enum AFE_MODE mode);
+int cx231xx_afe_update_power_control(struct cx231xx *dev,
+ enum AV_MODE avmode);
+int cx231xx_afe_adjust_ref_count(struct cx231xx *dev, u32 video_input);
+
+/* i2s block related functions */
+int cx231xx_i2s_blk_initialize(struct cx231xx *dev);
+int cx231xx_i2s_blk_update_power_control(struct cx231xx *dev,
+ enum AV_MODE avmode);
+int cx231xx_i2s_blk_set_audio_input(struct cx231xx *dev, u8 audio_input);
+
+/* DIF related functions */
+int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode,
+ u32 function_mode, u32 standard);
+int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard);
+int cx231xx_tuner_pre_channel_change(struct cx231xx *dev);
+int cx231xx_tuner_post_channel_change(struct cx231xx *dev);
+
+/* video parser functions */
+u8 cx231xx_find_next_SAV_EAV(u8 *p_buffer, u32 buffer_size,
+ u32 *p_bytes_used);
+u8 cx231xx_find_boundary_SAV_EAV(u8 *p_buffer, u8 *partial_buf,
+ u32 *p_bytes_used);
+int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+ u8 *p_buffer, u32 bytes_to_copy);
+void cx231xx_reset_video_buffer(struct cx231xx *dev,
+ struct cx231xx_dmaqueue *dma_q);
+u8 cx231xx_is_buffer_done(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q);
+u32 cx231xx_copy_video_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+ u8 *p_line, u32 length, int field_number);
+u32 cx231xx_get_video_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+ u8 sav_eav, u8 *p_buffer, u32 buffer_size);
+void cx231xx_swab(u16 *from, u16 *to, u16 len);
+
+/* Provided by cx231xx-core.c */
+
+u32 cx231xx_request_buffers(struct cx231xx *dev, u32 count);
+void cx231xx_queue_unusedframes(struct cx231xx *dev);
+void cx231xx_release_buffers(struct cx231xx *dev);
+
+/* read from control pipe */
+int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
+ char *buf, int len);
+
+/* write to control pipe */
+int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
+ char *buf, int len);
+int cx231xx_mode_register(struct cx231xx *dev, u16 address, u32 mode);
+
+int cx231xx_send_vendor_cmd(struct cx231xx *dev,
+ struct VENDOR_REQUEST_IN *ven_req);
+int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus,
+ struct cx231xx_i2c_xfer_data *req_data);
+
+/* Gpio related functions */
+int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val,
+ u8 len, u8 request, u8 direction);
+int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val);
+int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val);
+int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value);
+int cx231xx_set_gpio_direction(struct cx231xx *dev, int pin_number,
+ int pin_value);
+
+int cx231xx_gpio_i2c_start(struct cx231xx *dev);
+int cx231xx_gpio_i2c_end(struct cx231xx *dev);
+int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data);
+int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 *buf);
+int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev);
+int cx231xx_gpio_i2c_write_ack(struct cx231xx *dev);
+int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev);
+
+int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len);
+int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len);
+
+/* audio related functions */
+int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
+ enum AUDIO_INPUT audio_input);
+
+int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type);
+int cx231xx_resolution_set(struct cx231xx *dev);
+int cx231xx_set_video_alternate(struct cx231xx *dev);
+int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt);
+int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
+ int num_bufs, int max_pkt_size,
+ int (*isoc_copy) (struct cx231xx *dev,
+ struct urb *urb));
+void cx231xx_uninit_isoc(struct cx231xx *dev);
+int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode);
+int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio);
+
+/* Device list functions */
+void cx231xx_release_resources(struct cx231xx *dev);
+void cx231xx_release_analog_resources(struct cx231xx *dev);
+int cx231xx_register_analog_devices(struct cx231xx *dev);
+void cx231xx_remove_from_devlist(struct cx231xx *dev);
+void cx231xx_add_into_devlist(struct cx231xx *dev);
+struct cx231xx *cx231xx_get_device(int minor,
+ enum v4l2_buf_type *fh_type, int *has_radio);
+void cx231xx_init_extension(struct cx231xx *dev);
+void cx231xx_close_extension(struct cx231xx *dev);
+
+/* hardware init functions */
+int cx231xx_dev_init(struct cx231xx *dev);
+void cx231xx_dev_uninit(struct cx231xx *dev);
+void cx231xx_config_i2c(struct cx231xx *dev);
+int cx231xx_config(struct cx231xx *dev);
+
+/* Stream control functions */
+int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask);
+int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask);
+
+int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type);
+
+/* Power control functions */
+int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode);
+int cx231xx_power_suspend(struct cx231xx *dev);
+
+/* chip specific control functions */
+int cx231xx_init_ctrl_pin_status(struct cx231xx *dev);
+int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev,
+ u8 analog_or_digital);
+int cx231xx_enable_i2c_for_tuner(struct cx231xx *dev, u8 I2CIndex);
+
+/* video audio decoder related functions */
+void video_mux(struct cx231xx *dev, int index);
+int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input);
+int cx231xx_set_decoder_video_input(struct cx231xx *dev, u8 pin_type, u8 input);
+int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev);
+int cx231xx_set_audio_input(struct cx231xx *dev, u8 input);
+void get_scale(struct cx231xx *dev,
+ unsigned int width, unsigned int height,
+ unsigned int *hscale, unsigned int *vscale);
+
+/* Provided by cx231xx-video.c */
+int cx231xx_register_extension(struct cx231xx_ops *dev);
+void cx231xx_unregister_extension(struct cx231xx_ops *dev);
+void cx231xx_init_extension(struct cx231xx *dev);
+void cx231xx_close_extension(struct cx231xx *dev);
+
+/* Provided by cx231xx-cards.c */
+extern void cx231xx_pre_card_setup(struct cx231xx *dev);
+extern void cx231xx_card_setup(struct cx231xx *dev);
+extern struct cx231xx_board cx231xx_boards[];
+extern struct usb_device_id cx231xx_id_table[];
+extern const unsigned int cx231xx_bcount;
+void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir);
+int cx231xx_tuner_callback(void *ptr, int component, int command, int arg);
+
+/* Provided by cx231xx-input.c */
+int cx231xx_ir_init(struct cx231xx *dev);
+int cx231xx_ir_fini(struct cx231xx *dev);
+
+/* printk macros */
+
+#define cx231xx_err(fmt, arg...) do {\
+ printk(KERN_ERR fmt , ##arg); } while (0)
+
+#define cx231xx_errdev(fmt, arg...) do {\
+ printk(KERN_ERR "%s: "fmt,\
+ dev->name , ##arg); } while (0)
+
+#define cx231xx_info(fmt, arg...) do {\
+ printk(KERN_INFO "%s: "fmt,\
+ dev->name , ##arg); } while (0)
+#define cx231xx_warn(fmt, arg...) do {\
+ printk(KERN_WARNING "%s: "fmt,\
+ dev->name , ##arg); } while (0)
+
+static inline unsigned int norm_maxw(struct cx231xx *dev)
+{
+ if (dev->board.max_range_640_480)
+ return 640;
+ else
+ return 720;
+}
+
+static inline unsigned int norm_maxh(struct cx231xx *dev)
+{
+ if (dev->board.max_range_640_480)
+ return 480;
+ else
+ return (dev->norm & V4L2_STD_625_50) ? 576 : 480;
+}
+#endif
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 5e4b7e790d9..a3c0565be1a 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -739,9 +739,10 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
- dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->i2c_bus[2].i2c_adap,
+ dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
+ &dev->i2c_bus[2].i2c_adap,
"cx25840", "cx25840", 0x88 >> 1);
- v4l2_subdev_call(dev->sd_cx25840, core, init, 0);
+ v4l2_subdev_call(dev->sd_cx25840, core, load_fw);
break;
}
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index dc7fff22cfd..beda42925ce 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -875,7 +875,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);
- call_all(dev, core, s_standby, 0);
+ call_all(dev, tuner, s_standby);
cx23885_ir_init(dev);
if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index d43c7439676..f48454ab390 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -673,7 +673,7 @@ static int dvb_register(struct cx23885_tsport *port)
fe0->dvb.frontend->callback = cx23885_tuner_callback;
/* Put the analog decoder in standby to keep it quiet */
- call_all(dev, core, s_standby, 0);
+ call_all(dev, tuner, s_standby);
if (fe0->dvb.frontend->ops.analog_ops.standby)
fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index f0ac62c5dc8..68068c6d098 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -299,7 +299,7 @@ static int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
dev->tvnorm = norm;
- call_all(dev, tuner, s_std, norm);
+ call_all(dev, core, s_std, norm);
return 0;
}
@@ -393,9 +393,6 @@ static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh,
static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
{
- struct v4l2_routing route;
- memset(&route, 0, sizeof(route));
-
dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
__func__,
input, INPUT(input)->vmux,
@@ -403,10 +400,9 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
INPUT(input)->gpio2, INPUT(input)->gpio3);
dev->input = input;
- route.input = INPUT(input)->vmux;
-
/* Tell the internal A/V decoder */
- v4l2_subdev_call(dev->sd_cx25840, video, s_routing, &route);
+ v4l2_subdev_call(dev->sd_cx25840, video, s_routing,
+ INPUT(input)->vmux, 0, 0);
return 0;
}
@@ -1523,10 +1519,12 @@ int cx23885_video_register(struct cx23885_dev *dev)
struct v4l2_subdev *sd = NULL;
if (dev->tuner_addr)
- sd = v4l2_i2c_new_subdev(&dev->i2c_bus[1].i2c_adap,
+ sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
+ &dev->i2c_bus[1].i2c_adap,
"tuner", "tuner", dev->tuner_addr);
else
- sd = v4l2_i2c_new_probed_subdev(&dev->i2c_bus[1].i2c_adap,
+ sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+ &dev->i2c_bus[1].i2c_adap,
"tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV));
if (sd) {
struct tuner_setup tun_setup;
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 02d980a2996..85642831ea8 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, 2)
#define UNSET (-1U)
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index 93d74bee292..2f846f5e0f9 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -32,7 +32,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
/* common for all inputs and rates */
/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
- if (!state->is_cx23885)
+ if (!state->is_cx23885 && !state->is_cx231xx)
cx25840_write(client, 0x127, 0x50);
if (state->aud_input != CX25840_AUDIO_SERIAL) {
@@ -43,11 +43,14 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
* so avoid destroying registers. */
break;
}
- /* VID_PLL and AUX_PLL */
- cx25840_write4(client, 0x108, 0x1006040f);
- /* AUX_PLL_FRAC */
- cx25840_write4(client, 0x110, 0x01bb39ee);
+ if (!state->is_cx231xx) {
+ /* VID_PLL and AUX_PLL */
+ cx25840_write4(client, 0x108, 0x1006040f);
+
+ /* AUX_PLL_FRAC */
+ cx25840_write4(client, 0x110, 0x01bb39ee);
+ }
if (state->is_cx25836)
break;
@@ -64,11 +67,14 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
* so avoid destroying registers. */
break;
}
- /* VID_PLL and AUX_PLL */
- cx25840_write4(client, 0x108, 0x1009040f);
- /* AUX_PLL_FRAC */
- cx25840_write4(client, 0x110, 0x00ec6bd6);
+ if (!state->is_cx231xx) {
+ /* VID_PLL and AUX_PLL */
+ cx25840_write4(client, 0x108, 0x1009040f);
+
+ /* AUX_PLL_FRAC */
+ cx25840_write4(client, 0x110, 0x00ec6bd6);
+ }
if (state->is_cx25836)
break;
@@ -85,11 +91,14 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
* so avoid destroying registers. */
break;
}
- /* VID_PLL and AUX_PLL */
- cx25840_write4(client, 0x108, 0x100a040f);
- /* AUX_PLL_FRAC */
- cx25840_write4(client, 0x110, 0x0098d6e5);
+ if (!state->is_cx231xx) {
+ /* VID_PLL and AUX_PLL */
+ cx25840_write4(client, 0x108, 0x100a040f);
+
+ /* AUX_PLL_FRAC */
+ cx25840_write4(client, 0x110, 0x0098d6e5);
+ }
if (state->is_cx25836)
break;
@@ -108,11 +117,14 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
* so avoid destroying registers. */
break;
}
- /* VID_PLL and AUX_PLL */
- cx25840_write4(client, 0x108, 0x1e08040f);
- /* AUX_PLL_FRAC */
- cx25840_write4(client, 0x110, 0x012a0869);
+ if (!state->is_cx231xx) {
+ /* VID_PLL and AUX_PLL */
+ cx25840_write4(client, 0x108, 0x1e08040f);
+
+ /* AUX_PLL_FRAC */
+ cx25840_write4(client, 0x110, 0x012a0869);
+ }
if (state->is_cx25836)
break;
@@ -136,11 +148,14 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
break;
}
- /* VID_PLL and AUX_PLL */
- cx25840_write4(client, 0x108, 0x1809040f);
- /* AUX_PLL_FRAC */
- cx25840_write4(client, 0x110, 0x00ec6bd6);
+ if (!state->is_cx231xx) {
+ /* VID_PLL and AUX_PLL */
+ cx25840_write4(client, 0x108, 0x1809040f);
+
+ /* AUX_PLL_FRAC */
+ cx25840_write4(client, 0x110, 0x00ec6bd6);
+ }
if (state->is_cx25836)
break;
@@ -155,7 +170,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
break;
case 48000:
- if (!state->is_cx23885) {
+ if (!state->is_cx23885 && !state->is_cx231xx) {
/* VID_PLL and AUX_PLL */
cx25840_write4(client, 0x108, 0x180a040f);
@@ -166,7 +181,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
if (state->is_cx25836)
break;
- if (!state->is_cx23885) {
+ if (!state->is_cx23885 && !state->is_cx231xx) {
/* src1_ctl */
cx25840_write4(client, 0x8f8, 0x08018000);
@@ -227,10 +242,9 @@ void cx25840_audio_set_path(struct i2c_client *client)
/* deassert soft reset */
cx25840_and_or(client, 0x810, ~0x1, 0x00);
- if (state->is_cx23885) {
- /* Ensure the controller is running when we exit */
+ /* Ensure the controller is running when we exit */
+ if (state->is_cx23885 || state->is_cx231xx)
cx25840_and_or(client, 0x803, ~0x10, 0x10);
- }
}
static int get_volume(struct i2c_client *client)
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 737ee4ea883..0be51b65f09 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -345,6 +345,77 @@ static void cx23885_initialize(struct i2c_client *client)
/* ----------------------------------------------------------------------- */
+static void cx231xx_initialize(struct i2c_client *client)
+{
+ DEFINE_WAIT(wait);
+ struct cx25840_state *state = to_state(i2c_get_clientdata(client));
+ struct workqueue_struct *q;
+
+ /* Internal Reset */
+ cx25840_and_or(client, 0x102, ~0x01, 0x01);
+ cx25840_and_or(client, 0x102, ~0x01, 0x00);
+
+ /* Stop microcontroller */
+ cx25840_and_or(client, 0x803, ~0x10, 0x00);
+
+ /* DIF in reset? */
+ cx25840_write(client, 0x398, 0);
+
+ /* Trust the default xtal, no division */
+ /* This changes for the cx23888 products */
+ cx25840_write(client, 0x2, 0x76);
+
+ /* Bring down the regulator for AUX clk */
+ cx25840_write(client, 0x1, 0x40);
+
+ /* Disable DIF bypass */
+ cx25840_write4(client, 0x33c, 0x00000001);
+
+ /* DIF Src phase inc */
+ cx25840_write4(client, 0x340, 0x0df7df83);
+
+ /* Luma */
+ cx25840_write4(client, 0x414, 0x00107d12);
+
+ /* Chroma */
+ cx25840_write4(client, 0x420, 0x3d008282);
+
+ /* ADC2 input select */
+ cx25840_write(client, 0x102, 0x10);
+
+ /* VIN1 & VIN5 */
+ cx25840_write(client, 0x103, 0x11);
+
+ /* Enable format auto detect */
+ cx25840_write(client, 0x400, 0);
+ /* Fast subchroma lock */
+ /* White crush, Chroma AGC & Chroma Killer enabled */
+ cx25840_write(client, 0x401, 0xe8);
+
+ /* Do the firmware load in a work handler to prevent.
+ Otherwise the kernel is blocked waiting for the
+ bit-banging i2c interface to finish uploading the
+ firmware. */
+ INIT_WORK(&state->fw_work, cx25840_work_handler);
+ init_waitqueue_head(&state->fw_wait);
+ q = create_singlethread_workqueue("cx25840_fw");
+ prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
+ queue_work(q, &state->fw_work);
+ schedule();
+ finish_wait(&state->fw_wait, &wait);
+ destroy_workqueue(q);
+
+ cx25840_std_setup(client);
+
+ /* (re)set input */
+ set_input(client, state->vid_input, state->aud_input);
+
+ /* start microcontroller */
+ cx25840_and_or(client, 0x803, ~0x10, 0x10);
+}
+
+/* ----------------------------------------------------------------------- */
+
void cx25840_std_setup(struct i2c_client *client)
{
struct cx25840_state *state = to_state(i2c_get_clientdata(client));
@@ -414,39 +485,41 @@ void cx25840_std_setup(struct i2c_client *client)
}
/* DEBUG: Displays configured PLL frequency */
- pll_int = cx25840_read(client, 0x108);
- pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
- pll_post = cx25840_read(client, 0x109);
- v4l_dbg(1, cx25840_debug, client,
- "PLL regs = int: %u, frac: %u, post: %u\n",
- pll_int, pll_frac, pll_post);
-
- if (pll_post) {
- int fin, fsc;
- int pll = (28636363L * ((((u64)pll_int) << 25L) + pll_frac)) >> 25L;
-
- pll /= pll_post;
- v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n",
- pll / 1000000, pll % 1000000);
- v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n",
- pll / 8000000, (pll / 8) % 1000000);
-
- fin = ((u64)src_decimation * pll) >> 12;
- v4l_dbg(1, cx25840_debug, client,
- "ADC Sampling freq = %d.%06d MHz\n",
- fin / 1000000, fin % 1000000);
-
- fsc = (((u64)sc) * pll) >> 24L;
+ if (!state->is_cx231xx) {
+ pll_int = cx25840_read(client, 0x108);
+ pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
+ pll_post = cx25840_read(client, 0x109);
v4l_dbg(1, cx25840_debug, client,
- "Chroma sub-carrier freq = %d.%06d MHz\n",
- fsc / 1000000, fsc % 1000000);
-
- v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, "
- "vblank %i, vactive %i, vblank656 %i, src_dec %i, "
- "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, "
- "sc 0x%06x\n",
- hblank, hactive, vblank, vactive, vblank656,
- src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
+ "PLL regs = int: %u, frac: %u, post: %u\n",
+ pll_int, pll_frac, pll_post);
+
+ if (pll_post) {
+ int fin, fsc;
+ int pll = (28636363L * ((((u64)pll_int) << 25L) + pll_frac)) >> 25L;
+
+ pll /= pll_post;
+ v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n",
+ pll / 1000000, pll % 1000000);
+ v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n",
+ pll / 8000000, (pll / 8) % 1000000);
+
+ fin = ((u64)src_decimation * pll) >> 12;
+ v4l_dbg(1, cx25840_debug, client,
+ "ADC Sampling freq = %d.%06d MHz\n",
+ fin / 1000000, fin % 1000000);
+
+ fsc = (((u64)sc) * pll) >> 24L;
+ v4l_dbg(1, cx25840_debug, client,
+ "Chroma sub-carrier freq = %d.%06d MHz\n",
+ fsc / 1000000, fsc % 1000000);
+
+ v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, "
+ "vblank %i, vactive %i, vblank656 %i, src_dec %i, "
+ "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, "
+ "sc 0x%06x\n",
+ hblank, hactive, vblank, vactive, vblank656,
+ src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
+ }
}
/* Sets horizontal blanking delay and active lines */
@@ -596,7 +669,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
* configuration in reg (for the cx23885) so we have no
* need to attempt to flip bits for earlier av decoders.
*/
- if (!state->is_cx23885) {
+ if (!state->is_cx23885 && !state->is_cx231xx) {
switch (aud_input) {
case CX25840_AUDIO_SERIAL:
/* do nothing, use serial audio input */
@@ -619,7 +692,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
/* Set INPUT_MODE to Composite (0) or S-Video (1) */
cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
- if (!state->is_cx23885) {
+ if (!state->is_cx23885 && !state->is_cx231xx) {
/* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
/* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */
@@ -659,6 +732,19 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
*/
cx25840_write(client, 0x918, 0xa0);
cx25840_write(client, 0x919, 0x01);
+ } else if (state->is_cx231xx) {
+ /* Audio channel 1 src : Parallel 1 */
+ cx25840_write(client, 0x124, 0x03);
+
+ /* I2S_IN_CTL: I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 */
+ cx25840_write(client, 0x914, 0xa0);
+
+ /* I2S_OUT_CTL:
+ * I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1
+ * I2S_OUT_MASTER_MODE = Master
+ */
+ cx25840_write(client, 0x918, 0xa0);
+ cx25840_write(client, 0x919, 0x01);
}
return 0;
@@ -1096,7 +1182,7 @@ static void log_audio_status(struct i2c_client *client)
/* ----------------------------------------------------------------------- */
-/* This init operation must be called to load the driver's firmware.
+/* This load_fw operation must be called to load the driver's firmware.
Without this the audio standard detection will fail and you will
only get mono.
@@ -1106,18 +1192,20 @@ static void log_audio_status(struct i2c_client *client)
postponing it is that loading this firmware takes a long time (seconds)
due to the slow i2c bus speed. So it will speed up the boot process if
you can avoid loading the fw as long as the video device isn't used. */
-static int cx25840_init(struct v4l2_subdev *sd, u32 val)
+static int cx25840_load_fw(struct v4l2_subdev *sd)
{
struct cx25840_state *state = to_state(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
if (!state->is_initialized) {
- /* initialize on first use */
+ /* initialize and load firmware */
state->is_initialized = 1;
if (state->is_cx25836)
cx25836_initialize(client);
else if (state->is_cx23885)
cx23885_initialize(client);
+ else if (state->is_cx231xx)
+ cx231xx_initialize(client);
else
cx25840_initialize(client);
}
@@ -1159,7 +1247,7 @@ static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
v4l_dbg(1, cx25840_debug, client, "%s output\n",
enable ? "enable" : "disable");
if (enable) {
- if (state->is_cx23885) {
+ if (state->is_cx23885 || state->is_cx231xx) {
u8 v = (cx25840_read(client, 0x421) | 0x0b);
cx25840_write(client, 0x421, v);
} else {
@@ -1169,7 +1257,7 @@ static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
state->is_cx25836 ? 0x04 : 0x07);
}
} else {
- if (state->is_cx23885) {
+ if (state->is_cx23885 || state->is_cx231xx) {
u8 v = cx25840_read(client, 0x421) & ~(0x0b);
cx25840_write(client, 0x421, v);
} else {
@@ -1234,22 +1322,24 @@ static int cx25840_s_radio(struct v4l2_subdev *sd)
return 0;
}
-static int cx25840_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int cx25840_s_video_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct cx25840_state *state = to_state(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- return set_input(client, route->input, state->aud_input);
+ return set_input(client, input, state->aud_input);
}
-static int cx25840_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int cx25840_s_audio_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct cx25840_state *state = to_state(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
if (state->is_cx25836)
return -EINVAL;
- return set_input(client, state->vid_input, route->input);
+ return set_input(client, state->vid_input, input);
}
static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
@@ -1350,6 +1440,8 @@ static int cx25840_reset(struct v4l2_subdev *sd, u32 val)
cx25836_initialize(client);
else if (state->is_cx23885)
cx23885_initialize(client);
+ else if (state->is_cx231xx)
+ cx231xx_initialize(client);
else
cx25840_initialize(client);
return 0;
@@ -1382,8 +1474,9 @@ static const struct v4l2_subdev_core_ops cx25840_core_ops = {
.g_ctrl = cx25840_g_ctrl,
.s_ctrl = cx25840_s_ctrl,
.queryctrl = cx25840_queryctrl,
+ .s_std = cx25840_s_std,
.reset = cx25840_reset,
- .init = cx25840_init,
+ .load_fw = cx25840_load_fw,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = cx25840_g_register,
.s_register = cx25840_s_register,
@@ -1392,7 +1485,6 @@ static const struct v4l2_subdev_core_ops cx25840_core_ops = {
static const struct v4l2_subdev_tuner_ops cx25840_tuner_ops = {
.s_frequency = cx25840_s_frequency,
- .s_std = cx25840_s_std,
.s_radio = cx25840_s_radio,
.g_tuner = cx25840_g_tuner,
.s_tuner = cx25840_s_tuner,
@@ -1449,6 +1541,8 @@ static int cx25840_probe(struct i2c_client *client,
id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
} else if (device_id == 0x1313) {
id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
+ } else if ((device_id & 0xfff0) == 0x5A30) {
+ id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
}
else {
v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
@@ -1471,6 +1565,7 @@ static int cx25840_probe(struct i2c_client *client,
state->c = client;
state->is_cx25836 = ((device_id & 0xff00) == 0x8300);
state->is_cx23885 = (device_id == 0x0000) || (device_id == 0x1313);
+ state->is_cx231xx = (device_id == 0x5a3e);
state->vid_input = CX25840_COMPOSITE7;
state->aud_input = CX25840_AUDIO8;
state->audclk_freq = 48000;
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index 9ad0eb86ecf..814b5653699 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -50,6 +50,7 @@ struct cx25840_state {
u32 rev;
int is_cx25836;
int is_cx23885;
+ int is_cx231xx;
int is_initialized;
wait_queue_head_t fw_wait; /* wake up when the fw load is finished */
struct work_struct fw_work; /* work entry for fw load */
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
index 0b2dceb7410..0df53b0d75d 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -25,6 +25,7 @@
#define FWFILE "v4l-cx25840.fw"
#define FWFILE_CX23885 "v4l-cx23885-avcore-01.fw"
+#define FWFILE_CX231XX "v4l-cx231xx-avcore-01.fw"
/*
* Mike Isely <isely@pobox.com> - The FWSEND parameter controls the
@@ -96,9 +97,17 @@ int cx25840_loadfw(struct i2c_client *client)
u8 buffer[FWSEND];
const u8 *ptr;
int size, retval;
+ int MAX_BUF_SIZE = FWSEND;
if (state->is_cx23885)
firmware = FWFILE_CX23885;
+ else if (state->is_cx231xx)
+ firmware = FWFILE_CX231XX;
+
+ if ((state->is_cx231xx) && MAX_BUF_SIZE > 16) {
+ v4l_err(client, " Firmware download size changed to 16 bytes max length\n");
+ MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */
+ }
if (request_firmware(&fw, firmware, FWDEV(client)) != 0) {
v4l_err(client, "unable to open firmware %s\n", firmware);
@@ -113,7 +122,7 @@ int cx25840_loadfw(struct i2c_client *client)
size = fw->size;
ptr = fw->data;
while (size > 0) {
- int len = min(FWSEND - 2, size);
+ int len = min(MAX_BUF_SIZE - 2, size);
memcpy(buffer + 2, ptr, len);
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index ce98d955231..0ccdf36626e 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -745,7 +745,7 @@ static int __devinit snd_cx88_create(struct snd_card *card,
return err;
}
- if (!pci_dma_supported(pci,DMA_32BIT_MASK)) {
+ if (!pci_dma_supported(pci,DMA_BIT_MASK(32))) {
dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
err = -EIO;
cx88_core_put(core,pci);
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 0363971a23a..6bbbfc66bb4 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -3049,7 +3049,7 @@ static void cx88_card_setup(struct cx88_core *core)
ctl.fname);
call_all(core, tuner, s_config, &xc2028_cfg);
}
- call_all(core, core, s_standby, 0);
+ call_all(core, tuner, s_standby);
}
/* ------------------------------------------------------------------ */
@@ -3221,16 +3221,19 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
The radio_type is sometimes missing, or set to UNSET but
later code configures a tea5767.
*/
- v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner", "tuner",
+ v4l2_i2c_new_probed_subdev(&core->v4l2_dev, &core->i2c_adap,
+ "tuner", "tuner",
v4l2_i2c_tuner_addrs(ADDRS_RADIO));
if (has_demod)
- v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner",
- "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ v4l2_i2c_new_probed_subdev(&core->v4l2_dev,
+ &core->i2c_adap, "tuner", "tuner",
+ v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
if (core->board.tuner_addr == ADDR_UNSET) {
- v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner",
- "tuner", has_demod ? tv_addrs + 4 : tv_addrs);
+ v4l2_i2c_new_probed_subdev(&core->v4l2_dev,
+ &core->i2c_adap, "tuner", "tuner",
+ has_demod ? tv_addrs + 4 : tv_addrs);
} else {
- v4l2_i2c_new_subdev(&core->i2c_adap,
+ v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
"tuner", "tuner", core->board.tuner_addr);
}
}
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index f2fb9f30bfc..0e149b22bd1 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -991,7 +991,7 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
set_tvaudio(core);
// tell i2c chips
- call_all(core, tuner, s_std, norm);
+ call_all(core, core, s_std, norm);
// done
return 0;
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 4ff4d9fe035..9389cf290c1 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -1168,7 +1168,7 @@ static int dvb_register(struct cx8802_dev *dev)
fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
/* Put the analog decoder in standby to keep it quiet */
- call_all(core, core, s_standby, 0);
+ call_all(core, tuner, s_standby);
/* register everything */
return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index b295b76737e..da4e3912cd3 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -455,7 +455,7 @@ static int cx8802_init_common(struct cx8802_dev *dev)
if (pci_enable_device(dev->pci))
return -EIO;
pci_set_master(dev->pci);
- if (!pci_dma_supported(dev->pci,DMA_32BIT_MASK)) {
+ if (!pci_dma_supported(dev->pci,DMA_BIT_MASK(32))) {
printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name);
return -EIO;
}
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 434237af518..b993d42fe73 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -428,10 +428,8 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
routes for different inputs. HVR-1300 surely does */
if (core->board.audio_chip &&
core->board.audio_chip == V4L2_IDENT_WM8775) {
- struct v4l2_routing route;
-
- route.input = INPUT(input).audioroute;
- call_all(core, audio, s_routing, &route);
+ call_all(core, audio, s_routing,
+ INPUT(input).audioroute, 0, 0);
}
/* cx2388's C-ADC is connected to the tuner only.
When used with S-Video, that ADC is busy dealing with
@@ -823,10 +821,8 @@ static int video_open(struct file *file)
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;
- call_all(core, audio, s_routing, &route);
+ call_all(core, audio, s_routing,
+ core->board.radio.audioroute, 0, 0);
}
/* "I2S ADC mode" */
core->tvaudio = WW_I2SADC;
@@ -931,7 +927,7 @@ static int video_release(struct file *file)
kfree(fh);
if(atomic_dec_and_test(&dev->core->users))
- call_all(dev->core, core, s_standby, 0);
+ call_all(dev->core, tuner, s_standby);
return 0;
}
@@ -1836,7 +1832,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0));
pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev,DMA_32BIT_MASK)) {
+ if (!pci_dma_supported(pci_dev,DMA_BIT_MASK(32))) {
printk("%s/0: Oops: no 32bit PCI DMA ???\n",core->name);
err = -EIO;
goto fail_core;
@@ -1882,18 +1878,15 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
/* load and configure helper modules */
if (core->board.audio_chip == V4L2_IDENT_WM8775)
- v4l2_i2c_new_subdev(&core->i2c_adap,
+ v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
"wm8775", "wm8775", 0x36 >> 1);
if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
/* This probes for a tda9874 as is used on some
Pixelview Ultra boards. */
- static const unsigned short i2c_addr[] = {
- 0xb0 >> 1, I2C_CLIENT_END
- };
-
- v4l2_i2c_new_probed_subdev(&core->i2c_adap,
- "tvaudio", "tvaudio", i2c_addr);
+ v4l2_i2c_new_probed_subdev_addr(&core->v4l2_dev,
+ &core->i2c_adap,
+ "tvaudio", "tvaudio", 0xb0 >> 1);
}
switch (core->boardnr) {
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 9a43fdf20fa..7724d168fc0 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -41,7 +41,7 @@
#include <linux/version.h>
#include <linux/mutex.h>
-#define CX88_VERSION_CODE KERNEL_VERSION(0,0,6)
+#define CX88_VERSION_CODE KERNEL_VERSION(0,0,7)
#define UNSET (-1U)
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 0f48c0ff5ac..7c70738479d 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -31,6 +31,8 @@
#include <media/msp3400.h>
#include <media/saa7115.h>
#include <media/tvp5150.h>
+#include <media/tvaudio.h>
+#include <media/i2c-addr.h>
#include <media/tveeprom.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
@@ -1240,6 +1242,7 @@ struct em28xx_board em28xx_boards[] = {
[EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
.name = "Compro VideoMate ForYou/Stereo",
.tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tvaudio_addr = 0xb0,
.tda9887_conf = TDA9887_PRESENT,
.decoder = EM28XX_TVP5150,
.adecoder = EM28XX_TVAUDIO,
@@ -1444,6 +1447,24 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
{0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
};
+/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
+static unsigned short saa711x_addrs[] = {
+ 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
+ 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
+ I2C_CLIENT_END };
+
+static unsigned short tvp5150_addrs[] = {
+ 0xb8 >> 1,
+ 0xba >> 1,
+ I2C_CLIENT_END
+};
+
+static unsigned short msp3400_addrs[] = {
+ 0x80 >> 1,
+ 0x88 >> 1,
+ I2C_CLIENT_END
+};
+
int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
{
int rc = 0;
@@ -1672,31 +1693,55 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
}
}
-static void em28xx_config_tuner(struct em28xx *dev)
+static void em28xx_tuner_setup(struct em28xx *dev)
{
- struct v4l2_priv_tun_config xc2028_cfg;
struct tuner_setup tun_setup;
struct v4l2_frequency f;
if (dev->tuner_type == TUNER_ABSENT)
return;
+ memset(&tun_setup, 0, sizeof(tun_setup));
+
tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = dev->tuner_type;
- tun_setup.addr = dev->tuner_addr;
tun_setup.tuner_callback = em28xx_tuner_callback;
- em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+ if (dev->board.radio.type) {
+ tun_setup.type = dev->board.radio.type;
+ tun_setup.addr = dev->board.radio_addr;
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
+ }
+
+ if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) {
+ tun_setup.type = dev->tuner_type;
+ tun_setup.addr = dev->tuner_addr;
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
+ }
+
+ if (dev->tda9887_conf) {
+ struct v4l2_priv_tun_config tda9887_cfg;
+
+ tda9887_cfg.tuner = TUNER_TDA9887;
+ tda9887_cfg.priv = &dev->tda9887_conf;
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &tda9887_cfg);
+ }
if (dev->tuner_type == TUNER_XC2028) {
+ struct v4l2_priv_tun_config xc2028_cfg;
struct xc2028_ctrl ctl;
+ memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
+ memset(&ctl, 0, sizeof(ctl));
+
em28xx_setup_xc3028(dev, &ctl);
xc2028_cfg.tuner = TUNER_XC2028;
xc2028_cfg.priv = &ctl;
- em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &xc2028_cfg);
}
/* configure tuner */
@@ -1704,7 +1749,7 @@ static void em28xx_config_tuner(struct em28xx *dev)
f.type = V4L2_TUNER_ANALOG_TV;
f.frequency = 9076; /* just a magic number */
dev->ctl_freq = f.frequency;
- em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
}
static int em28xx_hint_board(struct em28xx *dev)
@@ -1911,22 +1956,52 @@ void em28xx_card_setup(struct em28xx *dev)
if (tuner >= 0)
dev->tuner_type = tuner;
-#ifdef CONFIG_MODULES
/* request some modules */
if (dev->board.has_msp34xx)
- request_module("msp3400");
+ v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "msp3400", "msp3400", msp3400_addrs);
+
if (dev->board.decoder == EM28XX_SAA711X)
- request_module("saa7115");
+ v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "saa7115", "saa7115_auto", saa711x_addrs);
+
if (dev->board.decoder == EM28XX_TVP5150)
- request_module("tvp5150");
- if (dev->board.tuner_type != TUNER_ABSENT)
- request_module("tuner");
- if (dev->board.adecoder == EM28XX_TVAUDIO)
- request_module("tvaudio");
-#endif
+ v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "tvp5150", "tvp5150", tvp5150_addrs);
- em28xx_config_tuner(dev);
+ if (dev->board.adecoder == EM28XX_TVAUDIO)
+ v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "tvaudio", "tvaudio", dev->board.tvaudio_addr);
+
+ if (dev->board.tuner_type != TUNER_ABSENT) {
+ int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
+
+ if (dev->board.radio.type)
+ v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "tuner", "tuner", dev->board.radio_addr);
+
+ if (has_demod)
+ v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+ &dev->i2c_adap, "tuner", "tuner",
+ v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ if (dev->tuner_addr == 0) {
+ enum v4l2_i2c_tuner_type type =
+ has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+ struct v4l2_subdev *sd;
+
+ sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+ &dev->i2c_adap, "tuner", "tuner",
+ v4l2_i2c_tuner_addrs(type));
+
+ if (sd)
+ dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
+ } else {
+ v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "tuner", "tuner", dev->tuner_addr);
+ }
+ }
+ em28xx_tuner_setup(dev);
em28xx_ir_init(dev);
}
@@ -1975,6 +2050,9 @@ void em28xx_release_resources(struct em28xx *dev)
em28xx_remove_from_devlist(dev);
em28xx_i2c_unregister(dev);
+
+ v4l2_device_unregister(&dev->v4l2_dev);
+
usb_put_dev(dev->udev);
/* Mark device as unused */
@@ -1986,6 +2064,7 @@ void em28xx_release_resources(struct em28xx *dev)
* allocates and inits the device structs, registers i2c bus and v4l device
*/
static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
+ struct usb_interface *interface,
int minor)
{
struct em28xx *dev = *devhandle;
@@ -2019,9 +2098,16 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
}
}
+ retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
+ if (retval < 0) {
+ em28xx_errdev("Call to v4l2_device_register() failed!\n");
+ return retval;
+ }
+
/* register i2c bus */
errCode = em28xx_i2c_register(dev);
if (errCode < 0) {
+ v4l2_device_unregister(&dev->v4l2_dev);
em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n",
__func__, errCode);
return errCode;
@@ -2033,6 +2119,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
/* Configure audio */
errCode = em28xx_audio_setup(dev);
if (errCode < 0) {
+ v4l2_device_unregister(&dev->v4l2_dev);
em28xx_errdev("%s: Error while setting audio - errCode [%d]!\n",
__func__, errCode);
}
@@ -2077,7 +2164,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
em28xx_init_extension(dev);
/* Save some power by putting tuner to sleep */
- em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
return 0;
@@ -2096,7 +2183,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
struct usb_device *udev;
struct usb_interface *uif;
struct em28xx *dev = NULL;
- int retval = -ENODEV;
+ int retval;
int i, nr, ifnum, isoc_pipe;
char *speed;
char descr[255] = "";
@@ -2118,7 +2205,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
interface->altsetting[0].desc.bInterfaceClass);
em28xx_devused &= ~(1<<nr);
- return -ENODEV;
+ retval = -ENODEV;
+ goto err;
}
endpoint = &interface->cur_altsetting->endpoint[0].desc;
@@ -2151,7 +2239,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
"interface not used by the driver\n");
em28xx_devused &= ~(1<<nr);
- return -ENODEV;
+ retval = -ENODEV;
+ goto err;
}
}
@@ -2194,7 +2283,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
EM28XX_MAXBOARDS);
em28xx_devused &= ~(1<<nr);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto err;
}
/* allocate memory for our device state and initialize it */
@@ -2202,7 +2292,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
if (dev == NULL) {
em28xx_err(DRIVER_NAME ": out of memory!\n");
em28xx_devused &= ~(1<<nr);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto err;
}
snprintf(dev->name, 29, "em28xx #%d", nr);
@@ -2229,7 +2320,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
em28xx_errdev("out of memory!\n");
em28xx_devused &= ~(1<<nr);
kfree(dev);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto err;
}
for (i = 0; i < dev->num_alt ; i++) {
@@ -2244,12 +2336,11 @@ static int em28xx_usb_probe(struct usb_interface *interface,
/* allocate device struct */
mutex_init(&dev->lock);
mutex_lock(&dev->lock);
- retval = em28xx_init_dev(&dev, udev, nr);
+ retval = em28xx_init_dev(&dev, udev, interface, nr);
if (retval) {
em28xx_devused &= ~(1<<dev->devno);
kfree(dev);
-
- return retval;
+ goto err;
}
/* save our data pointer in this interface device */
@@ -2263,6 +2354,9 @@ static int em28xx_usb_probe(struct usb_interface *interface,
mutex_unlock(&dev->lock);
return 0;
+
+err:
+ return retval;
}
/*
@@ -2288,6 +2382,8 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
wake_up_interruptible_all(&dev->open);
+ v4l2_device_disconnect(&dev->v4l2_dev);
+
if (dev->users) {
em28xx_warn
("device /dev/video%d is open! Deregistration and memory "
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 8f1999ca480..192b76cdd5d 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1018,14 +1018,10 @@ EXPORT_SYMBOL_GPL(em28xx_init_isoc);
*/
void em28xx_wake_i2c(struct em28xx *dev)
{
- struct v4l2_routing route;
- int zero = 0;
-
- route.input = INPUT(dev->ctl_input)->vmux;
- route.output = 0;
- em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, &zero);
- em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
- em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
+ INPUT(dev->ctl_input)->vmux, 0, 0);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
}
/*
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 02c12fe6361..f0bf1d960c7 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -459,70 +459,15 @@ static u32 functionality(struct i2c_adapter *adap)
static int attach_inform(struct i2c_client *client)
{
struct em28xx *dev = client->adapter->algo_data;
+ struct IR_i2c *ir = i2c_get_clientdata(client);
switch (client->addr << 1) {
- case 0x86:
- case 0x84:
- case 0x96:
- case 0x94:
- {
- struct v4l2_priv_tun_config tda9887_cfg;
-
- struct tuner_setup tun_setup;
-
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = TUNER_TDA9887;
- tun_setup.addr = client->addr;
-
- em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR,
- &tun_setup);
-
- tda9887_cfg.tuner = TUNER_TDA9887;
- tda9887_cfg.priv = &dev->tda9887_conf;
- em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG,
- &tda9887_cfg);
- break;
- }
- case 0x42:
- dprintk1(1, "attach_inform: saa7114 detected.\n");
- break;
- case 0x4a:
- dprintk1(1, "attach_inform: saa7113 detected.\n");
- break;
- case 0xa0:
- dprintk1(1, "attach_inform: eeprom detected.\n");
- break;
case 0x60:
case 0x8e:
- {
- struct IR_i2c *ir = i2c_get_clientdata(client);
- dprintk1(1, "attach_inform: IR detected (%s).\n",
- ir->phys);
+ dprintk1(1, "attach_inform: IR detected (%s).\n", ir->phys);
em28xx_set_ir(dev, ir);
break;
}
- case 0x80:
- case 0x88:
- dprintk1(1, "attach_inform: msp34xx detected.\n");
- break;
- case 0xb8:
- case 0xba:
- dprintk1(1, "attach_inform: tvp5150 detected.\n");
- break;
-
- case 0xb0:
- dprintk1(1, "attach_inform: tda9874 detected\n");
- break;
-
- default:
- if (!dev->tuner_addr)
- dev->tuner_addr = client->addr;
-
- dprintk1(1, "attach inform: detected I2C address %x\n",
- client->addr << 1);
- dprintk1(1, "driver id %d\n", client->driver->id);
-
- }
return 0;
}
@@ -534,7 +479,6 @@ static struct i2c_algorithm em28xx_algo = {
static struct i2c_adapter em28xx_adap_template = {
.owner = THIS_MODULE,
- .class = I2C_CLASS_TV_ANALOG,
.name = "em28xx",
.id = I2C_HW_B_EM28XX,
.algo = &em28xx_algo,
@@ -595,16 +539,6 @@ void em28xx_do_i2c_scan(struct em28xx *dev)
}
/*
- * em28xx_i2c_call_clients()
- * send commands to all attached i2c devices
- */
-void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg)
-{
- BUG_ON(NULL == dev->i2c_adap.algo_data);
- i2c_clients_command(&dev->i2c_adap, cmd, arg);
-}
-
-/*
* em28xx_i2c_register()
* register i2c bus
*/
@@ -618,6 +552,7 @@ int em28xx_i2c_register(struct em28xx *dev)
dev->i2c_adap.dev.parent = &dev->udev->dev;
strcpy(dev->i2c_adap.name, dev->name);
dev->i2c_adap.algo_data = dev;
+ i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
retval = i2c_add_adapter(&dev->i2c_adap);
if (retval < 0) {
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 575472f1e70..882796e84db 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -49,7 +49,7 @@
"Sascha Sommer <saschasommer@freenet.de>"
#define DRIVER_DESC "Empia em28xx based USB video device driver"
-#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 1)
+#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 2)
#define em28xx_videodbg(fmt, arg...) do {\
if (video_debug) \
@@ -400,7 +400,7 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
f.frequency = dev->ctl_freq;
f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
return 0;
}
@@ -515,10 +515,6 @@ static struct videobuf_queue_ops em28xx_video_qops = {
static void video_mux(struct em28xx *dev, int index)
{
- struct v4l2_routing route;
-
- route.input = INPUT(index)->vmux;
- route.output = 0;
dev->ctl_input = index;
dev->ctl_ainput = INPUT(index)->amux;
dev->ctl_aoutput = INPUT(index)->aout;
@@ -526,25 +522,22 @@ static void video_mux(struct em28xx *dev, int index)
if (!dev->ctl_aoutput)
dev->ctl_aoutput = EM28XX_AOUT_MASTER;
- em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
+ INPUT(index)->vmux, 0, 0);
if (dev->board.has_msp34xx) {
if (dev->i2s_speed) {
- em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ,
- &dev->i2s_speed);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, audio,
+ s_i2s_clock_freq, dev->i2s_speed);
}
- route.input = dev->ctl_ainput;
- route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
/* Note: this is msp3400 specific */
- em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
- &route);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
+ dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
}
if (dev->board.adecoder != EM28XX_NOADECODER) {
- route.input = dev->ctl_ainput;
- route.output = dev->ctl_aoutput;
- em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
- &route);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
+ dev->ctl_ainput, dev->ctl_aoutput, 0);
}
em28xx_audio_analog_set(dev);
@@ -829,7 +822,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
em28xx_resolution_set(dev);
- em28xx_i2c_call_clients(dev, VIDIOC_S_STD, &dev->norm);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
mutex_unlock(&dev->lock);
return 0;
@@ -995,8 +988,9 @@ static int vidioc_queryctrl(struct file *file, void *priv,
}
}
}
+
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, VIDIOC_QUERYCTRL, qc);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
mutex_unlock(&dev->lock);
if (qc->type)
@@ -1020,11 +1014,11 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
mutex_lock(&dev->lock);
if (dev->board.has_msp34xx)
- em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
else {
rc = em28xx_get_ctrl(dev, ctrl);
if (rc < 0) {
- em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
rc = 0;
}
}
@@ -1048,7 +1042,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
mutex_lock(&dev->lock);
if (dev->board.has_msp34xx)
- em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
else {
rc = 1;
for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
@@ -1067,7 +1061,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
/* Control not found - try to send it to the attached devices */
if (rc == 1) {
- em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
rc = 0;
}
@@ -1092,10 +1086,9 @@ static int vidioc_g_tuner(struct file *file, void *priv,
strcpy(t->name, "Tuner");
mutex_lock(&dev->lock);
-
- em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
-
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
mutex_unlock(&dev->lock);
+
return 0;
}
@@ -1114,10 +1107,9 @@ static int vidioc_s_tuner(struct file *file, void *priv,
return -EINVAL;
mutex_lock(&dev->lock);
-
- em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
-
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
mutex_unlock(&dev->lock);
+
return 0;
}
@@ -1157,7 +1149,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
mutex_lock(&dev->lock);
dev->ctl_freq = f->frequency;
- em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
mutex_unlock(&dev->lock);
@@ -1186,7 +1178,7 @@ static int vidioc_g_chip_ident(struct file *file, void *priv,
chip->ident = V4L2_IDENT_NONE;
chip->revision = 0;
- em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
return 0;
}
@@ -1211,7 +1203,7 @@ static int vidioc_g_register(struct file *file, void *priv,
reg->size = 1;
return 0;
case V4L2_CHIP_MATCH_I2C_DRIVER:
- em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_REGISTER, reg);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
return 0;
case V4L2_CHIP_MATCH_I2C_ADDR:
/* Not supported yet */
@@ -1263,7 +1255,7 @@ static int vidioc_s_register(struct file *file, void *priv,
return rc;
case V4L2_CHIP_MATCH_I2C_DRIVER:
- em28xx_i2c_call_clients(dev, VIDIOC_DBG_S_REGISTER, reg);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
return 0;
case V4L2_CHIP_MATCH_I2C_ADDR:
/* Not supported yet */
@@ -1406,13 +1398,13 @@ static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
mutex_lock(&dev->lock);
f->fmt.sliced.service_set = 0;
-
- em28xx_i2c_call_clients(dev, VIDIOC_G_FMT, f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, g_fmt, f);
if (f->fmt.sliced.service_set == 0)
rc = -EINVAL;
mutex_unlock(&dev->lock);
+
return rc;
}
@@ -1428,7 +1420,7 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
return rc;
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, VIDIOC_G_FMT, f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, g_fmt, f);
mutex_unlock(&dev->lock);
if (f->fmt.sliced.service_set == 0)
@@ -1532,7 +1524,7 @@ static int radio_g_tuner(struct file *file, void *priv,
t->type = V4L2_TUNER_RADIO;
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
mutex_unlock(&dev->lock);
return 0;
@@ -1567,7 +1559,7 @@ static int radio_s_tuner(struct file *file, void *priv,
return -EINVAL;
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
mutex_unlock(&dev->lock);
return 0;
@@ -1655,7 +1647,7 @@ static int em28xx_v4l2_open(struct file *filp)
}
if (fh->radio) {
em28xx_videodbg("video_open: setting radio device\n");
- em28xx_i2c_call_clients(dev, AUDC_SET_RADIO, NULL);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
}
dev->users++;
@@ -1738,7 +1730,7 @@ static int em28xx_v4l2_close(struct file *filp)
}
/* Save some power by putting tuner to sleep */
- em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
/* do this before setting alternate! */
em28xx_uninit_isoc(dev);
@@ -1959,11 +1951,12 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
vfd = video_device_alloc();
if (NULL == vfd)
return NULL;
- *vfd = *template;
- vfd->minor = -1;
- vfd->parent = &dev->udev->dev;
- vfd->release = video_device_release;
- vfd->debug = video_debug;
+
+ *vfd = *template;
+ vfd->minor = -1;
+ vfd->v4l2_dev = &dev->v4l2_dev;
+ vfd->release = video_device_release;
+ vfd->debug = video_debug;
snprintf(vfd->name, sizeof(vfd->name), "%s %s",
dev->name, type_name);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index a33a58da016..4c4e58004f5 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -27,6 +27,7 @@
#include <linux/videodev2.h>
#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
@@ -385,6 +386,8 @@ struct em28xx_board {
unsigned int valid:1;
unsigned char xclk, i2c_speed;
+ unsigned char radio_addr;
+ unsigned short tvaudio_addr;
enum em28xx_decoder decoder;
enum em28xx_adecoder adecoder;
@@ -460,6 +463,7 @@ struct em28xx {
int devno; /* marks the number of this device */
enum em28xx_chip_id chip_id;
+ struct v4l2_device v4l2_dev;
struct em28xx_board board;
unsigned int stream_on:1; /* Locks streams */
@@ -577,11 +581,9 @@ struct em28xx_ops {
};
/* Provided by em28xx-i2c.c */
-
-void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg);
void em28xx_do_i2c_scan(struct em28xx *dev);
-int em28xx_i2c_register(struct em28xx *dev);
-int em28xx_i2c_unregister(struct em28xx *dev);
+int em28xx_i2c_register(struct em28xx *dev);
+int em28xx_i2c_unregister(struct em28xx *dev);
/* Provided by em28xx-core.c */
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index a75c1ca2db4..a2741d7dccf 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -1132,6 +1132,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
if (input->index != 0)
return -EINVAL;
input->type = V4L2_INPUT_TYPE_CAMERA;
+ input->status = gspca_dev->cam.input_flags;
strncpy(input->name, gspca_dev->sd_desc->name,
sizeof input->name);
return 0;
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index e4d4cf6ce05..58e8ff02136 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -56,6 +56,7 @@ struct cam {
* - cannot be > MAX_NURBS
* - when 0 and bulk_size != 0 means
* 1 URB and submit done by subdriver */
+ u32 input_flags; /* value for ENUM_INPUT status flags */
};
struct gspca_dev;
diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile
index 226ab4fc9d6..9fa3644f486 100644
--- a/drivers/media/video/gspca/m5602/Makefile
+++ b/drivers/media/video/gspca/m5602/Makefile
@@ -7,5 +7,4 @@ gspca_m5602-objs := m5602_core.o \
m5602_s5k83a.o \
m5602_s5k4aa.o
-EXTRA_CFLAGS += -Idrivers/media/video/gspca
-
+EXTRA_CFLAGS += -Idrivers/media/video/gspca \ No newline at end of file
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h
index a3f3b7a0c7e..8f1cea6fd3b 100644
--- a/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -112,14 +112,14 @@ static const unsigned char sensor_urb_skeleton[] = {
struct sd {
struct gspca_dev gspca_dev;
- /* The name of the m5602 camera */
- char *name;
-
/* A pointer to the currently connected sensor */
- struct m5602_sensor *sensor;
+ const struct m5602_sensor *sensor;
struct sd_desc *desc;
+ /* Sensor private data */
+ void *sensor_priv;
+
/* The current frame's id, used to detect frame boundaries */
u8 frame_id;
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index b35e4838a6e..1aac2985fee 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -51,7 +51,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data)
address, *i2c_data);
/* usb_control_msg(...) returns the number of bytes sent upon success,
- mask that and return zero upon success instead*/
+ mask that and return zero instead*/
return (err < 0) ? err : 0;
}
@@ -76,7 +76,7 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
4, M5602_URB_MSG_TIMEOUT);
/* usb_control_msg(...) returns the number of bytes sent upon success,
- mask that and return zero upon success instead */
+ mask that and return zero instead */
return (err < 0) ? err : 0;
}
@@ -92,29 +92,29 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
} while ((*i2c_data & I2C_BUSY) && !err);
if (err < 0)
- goto out;
+ return err;
err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
sd->sensor->i2c_slave_id);
if (err < 0)
- goto out;
+ return err;
err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
if (err < 0)
- goto out;
+ return err;
if (sd->sensor->i2c_regW == 1) {
err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, len);
if (err < 0)
- goto out;
+ return err;
err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
if (err < 0)
- goto out;
+ return err;
} else {
err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
if (err < 0)
- goto out;
+ return err;
}
for (i = 0; (i < len) && !err; i++) {
@@ -123,7 +123,6 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
PDEBUG(D_CONF, "Reading sensor register "
"0x%x containing 0x%x ", address, *i2c_data);
}
-out:
return err;
}
@@ -310,7 +309,11 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
static void m5602_stop_transfer(struct gspca_dev *gspca_dev)
{
- /* Is there are a command to stop a data transfer? */
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ /* Run the sensor specific end transfer sequence */
+ if (sd->sensor->stop)
+ sd->sensor->stop(sd);
}
/* sub-driver description, the ctrl and nctrl is filled at probe time */
@@ -359,6 +362,17 @@ static int m5602_probe(struct usb_interface *intf,
THIS_MODULE);
}
+void m5602_disconnect(struct usb_interface *intf)
+{
+ struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (sd->sensor->disconnect)
+ sd->sensor->disconnect(sd);
+
+ gspca_disconnect(intf);
+}
+
static struct usb_driver sd_driver = {
.name = MODULE_NAME,
.id_table = m5602_table,
@@ -367,7 +381,7 @@ static struct usb_driver sd_driver = {
.suspend = gspca_suspend,
.resume = gspca_resume,
#endif
- .disconnect = gspca_disconnect
+ .disconnect = m5602_disconnect
};
/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index c0e71c33145..7d3f9e348ef 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -18,6 +18,61 @@
#include "m5602_mt9m111.h"
+static struct v4l2_pix_format mt9m111_modes[] = {
+ {
+ 640,
+ 480,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 640 * 480,
+ .bytesperline = 640,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
+ }
+};
+
+const static struct ctrl mt9m111_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = mt9m111_set_vflip,
+ .get = mt9m111_get_vflip
+ }, {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = mt9m111_set_hflip,
+ .get = mt9m111_get_hflip
+ }, {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "gain",
+ .minimum = 0,
+ .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2,
+ .step = 1,
+ .default_value = DEFAULT_GAIN,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = mt9m111_set_gain,
+ .get = mt9m111_get_gain
+ }
+};
+
+
static void mt9m111_dump_registers(struct sd *sd);
int mt9m111_probe(struct sd *sd)
@@ -62,10 +117,10 @@ int mt9m111_probe(struct sd *sd)
return -ENODEV;
sensor_found:
- sd->gspca_dev.cam.cam_mode = mt9m111.modes;
- sd->gspca_dev.cam.nmodes = mt9m111.nmodes;
- sd->desc->ctrls = mt9m111.ctrls;
- sd->desc->nctrls = mt9m111.nctrls;
+ sd->gspca_dev.cam.cam_mode = mt9m111_modes;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes);
+ sd->desc->ctrls = mt9m111_ctrls;
+ sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls);
return 0;
}
@@ -125,16 +180,15 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
/* Set the correct page map */
err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
if (err < 0)
- goto out;
+ return err;
err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
if (err < 0)
- goto out;
+ return err;
data[0] = (data[0] & 0xfe) | val;
err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
data, 2);
-out:
return err;
}
@@ -163,16 +217,15 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
/* Set the correct page map */
err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
if (err < 0)
- goto out;
+ return err;
err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
if (err < 0)
- goto out;
+ return err;
data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02);
err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
data, 2);
-out:
return err;
}
@@ -204,7 +257,7 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
/* Set the correct page map */
err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
if (err < 0)
- goto out;
+ return err;
if (val >= INITIAL_MAX_GAIN * 2 * 2 * 2)
return -EINVAL;
@@ -229,7 +282,7 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
data, 2);
-out:
+
return err;
}
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index e795ab7a36c..00c6db02bdb 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -94,7 +94,7 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-static struct m5602_sensor mt9m111 = {
+const static struct m5602_sensor mt9m111 = {
.name = "MT9M111",
.i2c_slave_id = 0xba,
@@ -102,64 +102,7 @@ static struct m5602_sensor mt9m111 = {
.probe = mt9m111_probe,
.init = mt9m111_init,
- .power_down = mt9m111_power_down,
-
- .nctrls = 3,
- .ctrls = {
- {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = mt9m111_set_vflip,
- .get = mt9m111_get_vflip
- }, {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = mt9m111_set_hflip,
- .get = mt9m111_get_hflip
- }, {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
- .minimum = 0,
- .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2,
- .step = 1,
- .default_value = DEFAULT_GAIN,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = mt9m111_set_gain,
- .get = mt9m111_get_gain
- }
- },
-
- .nmodes = 1,
- .modes = {
- {
- M5602_DEFAULT_FRAME_WIDTH,
- M5602_DEFAULT_FRAME_HEIGHT,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
- .bytesperline = M5602_DEFAULT_FRAME_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
- }
+ .power_down = mt9m111_power_down
};
static const unsigned char preinit_mt9m111[][4] =
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index c908a8d6970..fc4548fd441 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -65,14 +65,177 @@ static
DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700")
}
},
- { }
+ {}
+};
+
+const static struct ctrl ov9650_ctrls[] = {
+#define EXPOSURE_IDX 0
+ {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "exposure",
+ .minimum = 0x00,
+ .maximum = 0x1ff,
+ .step = 0x4,
+ .default_value = EXPOSURE_DEFAULT,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = ov9650_set_exposure,
+ .get = ov9650_get_exposure
+ },
+#define GAIN_IDX 1
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "gain",
+ .minimum = 0x00,
+ .maximum = 0x3ff,
+ .step = 0x1,
+ .default_value = GAIN_DEFAULT,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = ov9650_set_gain,
+ .get = ov9650_get_gain
+ },
+#define RED_BALANCE_IDX 2
+ {
+ {
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "red balance",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x1,
+ .default_value = RED_GAIN_DEFAULT,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = ov9650_set_red_balance,
+ .get = ov9650_get_red_balance
+ },
+#define BLUE_BALANCE_IDX 3
+ {
+ {
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "blue balance",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x1,
+ .default_value = BLUE_GAIN_DEFAULT,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = ov9650_set_blue_balance,
+ .get = ov9650_get_blue_balance
+ },
+#define HFLIP_IDX 4
+ {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = ov9650_set_hflip,
+ .get = ov9650_get_hflip
+ },
+#define VFLIP_IDX 5
+ {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = ov9650_set_vflip,
+ .get = ov9650_get_vflip
+ },
+#define AUTO_WHITE_BALANCE_IDX 6
+ {
+ {
+ .id = V4L2_CID_AUTO_WHITE_BALANCE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "auto white balance",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1
+ },
+ .set = ov9650_set_auto_white_balance,
+ .get = ov9650_get_auto_white_balance
+ },
+#define AUTO_GAIN_CTRL_IDX 7
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "auto gain control",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1
+ },
+ .set = ov9650_set_auto_gain,
+ .get = ov9650_get_auto_gain
+ }
+};
+
+static struct v4l2_pix_format ov9650_modes[] = {
+ {
+ 176,
+ 144,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ 176 * 144,
+ .bytesperline = 176,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 9
+ }, {
+ 320,
+ 240,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ 320 * 240,
+ .bytesperline = 320,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 8
+ }, {
+ 352,
+ 288,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ 352 * 288,
+ .bytesperline = 352,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 9
+ }, {
+ 640,
+ 480,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ 640 * 480,
+ .bytesperline = 640,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 9
+ }
};
static void ov9650_dump_registers(struct sd *sd);
int ov9650_probe(struct sd *sd)
{
+ int err = 0;
u8 prod_id = 0, ver_id = 0, i;
+ s32 *sensor_settings;
if (force_sensor) {
if (force_sensor == OV9650_SENSOR) {
@@ -86,16 +249,20 @@ int ov9650_probe(struct sd *sd)
info("Probing for an ov9650 sensor");
- /* Run the pre-init to actually probe the unit */
- for (i = 0; i < ARRAY_SIZE(preinit_ov9650); i++) {
+ /* Run the pre-init before probing the sensor */
+ for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
u8 data = preinit_ov9650[i][2];
if (preinit_ov9650[i][0] == SENSOR)
- m5602_write_sensor(sd,
- preinit_ov9650[i][1], &data, 1);
+ err = m5602_write_sensor(sd,
+ preinit_ov9650[i][1], &data, 1);
else
- m5602_write_bridge(sd, preinit_ov9650[i][1], data);
+ err = m5602_write_bridge(sd,
+ preinit_ov9650[i][1], data);
}
+ if (err < 0)
+ return err;
+
if (m5602_read_sensor(sd, OV9650_PID, &prod_id, 1))
return -ENODEV;
@@ -106,14 +273,28 @@ int ov9650_probe(struct sd *sd)
info("Detected an ov9650 sensor");
goto sensor_found;
}
-
return -ENODEV;
sensor_found:
- sd->gspca_dev.cam.cam_mode = ov9650.modes;
- sd->gspca_dev.cam.nmodes = ov9650.nmodes;
- sd->desc->ctrls = ov9650.ctrls;
- sd->desc->nctrls = ov9650.nctrls;
+ sensor_settings = kmalloc(
+ ARRAY_SIZE(ov9650_ctrls) * sizeof(s32), GFP_KERNEL);
+ if (!sensor_settings)
+ return -ENOMEM;
+
+ sd->gspca_dev.cam.cam_mode = ov9650_modes;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov9650_modes);
+ sd->desc->ctrls = ov9650_ctrls;
+ sd->desc->nctrls = ARRAY_SIZE(ov9650_ctrls);
+
+ for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++)
+ sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value;
+ sd->sensor_priv = sensor_settings;
+
+ if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
+ info("vflip quirk active");
+ sensor_settings[VFLIP_IDX] = 1;
+ }
+
return 0;
}
@@ -121,6 +302,7 @@ int ov9650_init(struct sd *sd)
{
int i, err = 0;
u8 data;
+ s32 *sensor_settings = sd->sensor_priv;
if (dump_sensor)
ov9650_dump_registers(sd);
@@ -134,70 +316,157 @@ int ov9650_init(struct sd *sd)
err = m5602_write_bridge(sd, init_ov9650[i][1], data);
}
- if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
- info("vflip quirk active");
- data = 0x30;
- err = m5602_write_sensor(sd, OV9650_MVFP, &data, 1);
- }
+ err = ov9650_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = ov9650_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
+ if (err < 0)
+ return err;
+
+ err = ov9650_set_red_balance(&sd->gspca_dev, sensor_settings[RED_BALANCE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = ov9650_set_blue_balance(&sd->gspca_dev, sensor_settings[BLUE_BALANCE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = ov9650_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
+ if (err < 0)
+ return err;
+
+ err = ov9650_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+ if (err < 0)
+ return err;
+
+ err = ov9650_set_auto_white_balance(&sd->gspca_dev, sensor_settings[AUTO_WHITE_BALANCE_IDX]);
+ if (err < 0)
+ return err;
+
+ err = ov9650_set_auto_gain(&sd->gspca_dev, sensor_settings[AUTO_GAIN_CTRL_IDX]);
return err;
}
int ov9650_start(struct sd *sd)
{
+ u8 data;
int i, err = 0;
struct cam *cam = &sd->gspca_dev.cam;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
+ int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
+ int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
+ int hor_offs = OV9650_LEFT_OFFSET;
+
+ if (sensor_settings[VFLIP_IDX])
+ ver_offs--;
+ if (width <= 320)
+ hor_offs /= 2;
+
+ /* Synthesize the vsync/hsync setup */
for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
- u8 data = res_init_ov9650[i][1];
- err = m5602_write_bridge(sd, res_init_ov9650[i][0], data);
+ if (res_init_ov9650[i][0] == BRIDGE)
+ err = m5602_write_bridge(sd, res_init_ov9650[i][1],
+ res_init_ov9650[i][2]);
+ else if (res_init_ov9650[i][0] == SENSOR) {
+ u8 data = res_init_ov9650[i][2];
+ err = m5602_write_sensor(sd,
+ res_init_ov9650[i][1], &data, 1);
+ }
}
if (err < 0)
return err;
- switch (cam->cam_mode[sd->gspca_dev.curr_mode].width)
- {
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
+ ((ver_offs >> 8) & 0xff));
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < 2 && !err; i++)
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
+ (hor_offs >> 8) & 0xff);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, hor_offs & 0xff);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
+ ((width + hor_offs) >> 8) & 0xff);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
+ ((width + hor_offs) & 0xff));
+ if (err < 0)
+ return err;
+
+ switch (width) {
case 640:
PDEBUG(D_V4L2, "Configuring camera for VGA mode");
- for (i = 0; i < ARRAY_SIZE(VGA_ov9650) && !err; i++) {
- u8 data = VGA_ov9650[i][2];
- if (VGA_ov9650[i][0] == SENSOR)
- err = m5602_write_sensor(sd,
- VGA_ov9650[i][1], &data, 1);
- else
- err = m5602_write_bridge(sd, VGA_ov9650[i][1], data);
- }
+ data = OV9650_VGA_SELECT | OV9650_RGB_SELECT |
+ OV9650_RAW_RGB_SELECT;
+ err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
break;
case 352:
PDEBUG(D_V4L2, "Configuring camera for CIF mode");
- for (i = 0; i < ARRAY_SIZE(CIF_ov9650) && !err; i++) {
- u8 data = CIF_ov9650[i][2];
- if (CIF_ov9650[i][0] == SENSOR)
- err = m5602_write_sensor(sd,
- CIF_ov9650[i][1], &data, 1);
- else
- err = m5602_write_bridge(sd, CIF_ov9650[i][1], data);
- }
+ data = OV9650_CIF_SELECT | OV9650_RGB_SELECT |
+ OV9650_RAW_RGB_SELECT;
+ err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
break;
case 320:
PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
- for (i = 0; i < ARRAY_SIZE(QVGA_ov9650) && !err; i++) {
- u8 data = QVGA_ov9650[i][2];
- if (QVGA_ov9650[i][0] == SENSOR)
- err = m5602_write_sensor(sd,
- QVGA_ov9650[i][1], &data, 1);
- else
- err = m5602_write_bridge(sd, QVGA_ov9650[i][1], data);
- }
+ data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT |
+ OV9650_RAW_RGB_SELECT;
+ err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
+ break;
+
+ case 176:
+ PDEBUG(D_V4L2, "Configuring camera for QCIF mode");
+
+ data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT |
+ OV9650_RAW_RGB_SELECT;
+ err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
break;
}
return err;
}
+int ov9650_stop(struct sd *sd)
+{
+ u8 data = OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X;
+ return m5602_write_sensor(sd, OV9650_COM2, &data, 1);
+}
+
int ov9650_power_down(struct sd *sd)
{
int i, err = 0;
@@ -214,76 +483,63 @@ int ov9650_power_down(struct sd *sd)
return err;
}
-int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+void ov9650_disconnect(struct sd *sd)
{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 i2c_data;
- int err;
-
- err = m5602_read_sensor(sd, OV9650_COM1, &i2c_data, 1);
- if (err < 0)
- goto out;
- *val = i2c_data & 0x03;
+ ov9650_stop(sd);
+ ov9650_power_down(sd);
- err = m5602_read_sensor(sd, OV9650_AECH, &i2c_data, 1);
- if (err < 0)
- goto out;
- *val |= (i2c_data << 2);
+ sd->sensor = NULL;
+ kfree(sd->sensor_priv);
+}
- err = m5602_read_sensor(sd, OV9650_AECHM, &i2c_data, 1);
- if (err < 0)
- goto out;
- *val |= (i2c_data & 0x3f) << 10;
+int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+ *val = sensor_settings[EXPOSURE_IDX];
PDEBUG(D_V4L2, "Read exposure %d", *val);
-out:
- return err;
+ return 0;
}
int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
u8 i2c_data;
int err;
- PDEBUG(D_V4L2, "Set exposure to %d",
- val & 0xffff);
+ PDEBUG(D_V4L2, "Set exposure to %d", val);
+ sensor_settings[EXPOSURE_IDX] = val;
/* The 6 MSBs */
i2c_data = (val >> 10) & 0x3f;
err = m5602_write_sensor(sd, OV9650_AECHM,
&i2c_data, 1);
if (err < 0)
- goto out;
+ return err;
/* The 8 middle bits */
i2c_data = (val >> 2) & 0xff;
err = m5602_write_sensor(sd, OV9650_AECH,
&i2c_data, 1);
if (err < 0)
- goto out;
+ return err;
/* The 2 LSBs */
i2c_data = val & 0x03;
err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1);
-
-out:
return err;
}
int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
- *val = (i2c_data & 0x03) << 8;
-
- err = m5602_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
- *val |= i2c_data;
+ *val = sensor_settings[GAIN_IDX];
PDEBUG(D_V4L2, "Read gain %d", *val);
- return err;
+ return 0;
}
int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -291,15 +547,25 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
int err;
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ PDEBUG(D_V4L2, "Setting gain to %d", val);
+
+ sensor_settings[GAIN_IDX] = val;
/* The 2 MSB */
/* Read the OV9650_VREF register first to avoid
corrupting the VREF high and low bits */
- m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
+ err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
+ if (err < 0)
+ return err;
+
/* Mask away all uninteresting bits */
i2c_data = ((val & 0x0300) >> 2) |
(i2c_data & 0x3F);
err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
+ if (err < 0)
+ return err;
/* The 8 LSBs */
i2c_data = val & 0xff;
@@ -309,16 +575,12 @@ int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_read_sensor(sd, OV9650_RED, &i2c_data, 1);
- *val = i2c_data;
-
+ *val = sensor_settings[RED_BALANCE_IDX];
PDEBUG(D_V4L2, "Read red gain %d", *val);
-
- return err;
+ return 0;
}
int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -326,28 +588,26 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
int err;
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- PDEBUG(D_V4L2, "Set red gain to %d",
- val & 0xff);
+ PDEBUG(D_V4L2, "Set red gain to %d", val);
+
+ sensor_settings[RED_BALANCE_IDX] = val;
i2c_data = val & 0xff;
err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1);
-
return err;
}
int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_read_sensor(sd, OV9650_BLUE, &i2c_data, 1);
- *val = i2c_data;
-
+ *val = sensor_settings[BLUE_BALANCE_IDX];
PDEBUG(D_V4L2, "Read blue gain %d", *val);
- return err;
+ return 0;
}
int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -355,30 +615,25 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
int err;
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ PDEBUG(D_V4L2, "Set blue gain to %d", val);
- PDEBUG(D_V4L2, "Set blue gain to %d",
- val & 0xff);
+ sensor_settings[BLUE_BALANCE_IDX] = val;
i2c_data = val & 0xff;
err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1);
-
return err;
}
int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
- if (dmi_check_system(ov9650_flip_dmi_table))
- *val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1;
- else
- *val = (i2c_data & OV9650_HFLIP) >> 5;
+ *val = sensor_settings[HFLIP_IDX];
PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
-
- return err;
+ return 0;
}
int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -386,38 +641,26 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
int err;
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
- err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
- if (err < 0)
- goto out;
-
- if (dmi_check_system(ov9650_flip_dmi_table))
- i2c_data = ((i2c_data & 0xdf) |
- (((val ? 0 : 1) & 0x01) << 5));
- else
- i2c_data = ((i2c_data & 0xdf) |
- ((val & 0x01) << 5));
+ sensor_settings[HFLIP_IDX] = val;
+ i2c_data = ((val & 0x01) << 5) | (sensor_settings[VFLIP_IDX] << 4);
err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
-out:
+
return err;
}
int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
- if (dmi_check_system(ov9650_flip_dmi_table))
- *val = ((i2c_data & 0x10) >> 4) ? 0 : 1;
- else
- *val = (i2c_data & 0x10) >> 4;
+ *val = sensor_settings[VFLIP_IDX];
PDEBUG(D_V4L2, "Read vertical flip %d", *val);
- return err;
+ return 0;
}
int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -425,40 +668,32 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
int err;
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
PDEBUG(D_V4L2, "Set vertical flip to %d", val);
- err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
+ sensor_settings[VFLIP_IDX] = val;
+
+ i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
+ err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
if (err < 0)
- goto out;
+ return err;
- if (dmi_check_system(ov9650_flip_dmi_table))
- i2c_data = ((i2c_data & 0xef) |
- (((val ? 0 : 1) & 0x01) << 4));
- else
- i2c_data = ((i2c_data & 0xef) |
- ((val & 0x01) << 4));
+ /* When vflip is toggled we need to readjust the bridge hsync/vsync */
+ if (gspca_dev->streaming)
+ err = ov9650_start(sd);
- err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
-out:
return err;
}
int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
- if (err < 0)
- goto out;
- *val = (i2c_data & 0x03) << 8;
-
- err = m5602_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
- *val |= i2c_data;
+ *val = sensor_settings[GAIN_IDX];
PDEBUG(D_V4L2, "Read gain %d", *val);
-out:
- return err;
+
+ return 0;
}
int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -466,40 +701,38 @@ int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
int err;
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- PDEBUG(D_V4L2, "Set gain to %d", val & 0x3ff);
+ PDEBUG(D_V4L2, "Set gain to %d", val);
+
+ sensor_settings[GAIN_IDX] = val;
/* Read the OV9650_VREF register first to avoid
corrupting the VREF high and low bits */
err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
if (err < 0)
- goto out;
+ return err;
/* Mask away all uninteresting bits */
i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F);
err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
if (err < 0)
- goto out;
+ return err;
/* The 8 LSBs */
i2c_data = val & 0xff;
err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
-out:
return err;
}
int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
- *val = (i2c_data & OV9650_AWB_EN) >> 1;
- PDEBUG(D_V4L2, "Read auto white balance %d", *val);
-
- return err;
+ *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
+ return 0;
}
int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -507,29 +740,29 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
int err;
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
PDEBUG(D_V4L2, "Set auto white balance to %d", val);
+
+ sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
if (err < 0)
- goto out;
+ return err;
i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
-out:
+
return err;
}
int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
- *val = (i2c_data & OV9650_AGC_EN) >> 2;
+ *val = sensor_settings[AUTO_GAIN_CTRL_IDX];
PDEBUG(D_V4L2, "Read auto gain control %d", *val);
-
- return err;
+ return 0;
}
int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -537,15 +770,18 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
int err;
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
PDEBUG(D_V4L2, "Set auto gain control to %d", val);
+
+ sensor_settings[AUTO_GAIN_CTRL_IDX] = val;
err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
if (err < 0)
- goto out;
+ return err;
i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
-out:
+
return err;
}
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index f4b33b8e8da..fcc54e4c0f4 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -32,6 +32,7 @@
#define OV9650_BAVE 0x05
#define OV9650_GEAVE 0x06
#define OV9650_RSVD7 0x07
+#define OV9650_COM2 0x09
#define OV9650_PID 0x0a
#define OV9650_VER 0x0b
#define OV9650_COM3 0x0c
@@ -96,6 +97,7 @@
#define OV9650_VGA_SELECT (1 << 6)
#define OV9650_CIF_SELECT (1 << 5)
#define OV9650_QVGA_SELECT (1 << 4)
+#define OV9650_QCIF_SELECT (1 << 3)
#define OV9650_RGB_SELECT (1 << 2)
#define OV9650_RAW_RGB_SELECT (1 << 0)
@@ -115,10 +117,15 @@
#define OV9650_VFLIP (1 << 4)
#define OV9650_HFLIP (1 << 5)
+#define OV9650_SOFT_SLEEP (1 << 4)
+#define OV9650_OUTPUT_DRIVE_2X (1 << 0)
+
+#define OV9650_LEFT_OFFSET 0x62
+
#define GAIN_DEFAULT 0x14
#define RED_GAIN_DEFAULT 0x70
#define BLUE_GAIN_DEFAULT 0x20
-#define EXPOSURE_DEFAULT 0x5003
+#define EXPOSURE_DEFAULT 0x1ff
/*****************************************************************************/
@@ -129,7 +136,9 @@ extern int dump_sensor;
int ov9650_probe(struct sd *sd);
int ov9650_init(struct sd *sd);
int ov9650_start(struct sd *sd);
+int ov9650_stop(struct sd *sd);
int ov9650_power_down(struct sd *sd);
+void ov9650_disconnect(struct sd *sd);
int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
@@ -150,152 +159,16 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val);
int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
-static struct m5602_sensor ov9650 = {
+const static struct m5602_sensor ov9650 = {
.name = "OV9650",
.i2c_slave_id = 0x60,
.i2c_regW = 1,
.probe = ov9650_probe,
.init = ov9650_init,
.start = ov9650_start,
+ .stop = ov9650_stop,
.power_down = ov9650_power_down,
-
- .nctrls = 8,
- .ctrls = {
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0xffff,
- .step = 0x1,
- .default_value = EXPOSURE_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = ov9650_set_exposure,
- .get = ov9650_get_exposure
- }, {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
- .minimum = 0x00,
- .maximum = 0x3ff,
- .step = 0x1,
- .default_value = GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = ov9650_set_gain,
- .get = ov9650_get_gain
- }, {
- {
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = RED_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = ov9650_set_red_balance,
- .get = ov9650_get_red_balance
- }, {
- {
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = BLUE_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = ov9650_set_blue_balance,
- .get = ov9650_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 = ov9650_set_hflip,
- .get = ov9650_get_hflip
- }, {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = ov9650_set_vflip,
- .get = ov9650_get_vflip
- }, {
- {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto white balance",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = ov9650_set_auto_white_balance,
- .get = ov9650_get_auto_white_balance
- }, {
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto gain control",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = ov9650_set_auto_gain,
- .get = ov9650_get_auto_gain
- }
- },
-
- .nmodes = 3,
- .modes = {
- {
- 320,
- 240,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 320 * 240,
- .bytesperline = 320,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- }, {
- 352,
- 288,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 352 * 288,
- .bytesperline = 352,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- }, {
- 640,
- 480,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 640 * 480,
- .bytesperline = 640,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- }
- }
+ .disconnect = ov9650_disconnect,
};
static const unsigned char preinit_ov9650[][3] =
@@ -345,6 +218,10 @@ static const unsigned char init_ov9650[][3] =
/* Reset chip */
{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
+ /* One extra reset is needed in order to make the sensor behave
+ properly when resuming from ram */
+ {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
+
/* Enable double clock */
{SENSOR, OV9650_CLKRC, 0x80},
/* Do something out of spec with the power */
@@ -427,18 +304,12 @@ static const unsigned char init_ov9650[][3] =
/* Enable denoise, and white-pixel erase */
{SENSOR, OV9650_COM22, 0x23},
- /* Set the high bits of the exposure value */
- {SENSOR, OV9650_AECH, ((EXPOSURE_DEFAULT & 0xff00) >> 8)},
-
/* Enable VARIOPIXEL */
{SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
{SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL},
- /* Set the low bits of the exposure value */
- {SENSOR, OV9650_COM1, (EXPOSURE_DEFAULT & 0xff)},
- {SENSOR, OV9650_GAIN, GAIN_DEFAULT},
- {SENSOR, OV9650_BLUE, BLUE_GAIN_DEFAULT},
- {SENSOR, OV9650_RED, RED_GAIN_DEFAULT},
+ /* Put the sensor in soft sleep mode */
+ {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
};
static const unsigned char power_down_ov9650[][3] =
@@ -461,73 +332,15 @@ static const unsigned char power_down_ov9650[][3] =
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
};
-static const unsigned char res_init_ov9650[][2] =
-{
- {M5602_XB_LINE_OF_FRAME_H, 0x82},
- {M5602_XB_LINE_OF_FRAME_L, 0x00},
- {M5602_XB_PIX_OF_LINE_H, 0x82},
- {M5602_XB_PIX_OF_LINE_L, 0x00},
- {M5602_XB_SIG_INI, 0x01}
-};
-
-static const unsigned char VGA_ov9650[][3] =
+static const unsigned char res_init_ov9650[][3] =
{
- /* Moves the view window in a vertical orientation */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, /* 640 + 98 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0xe2},
-
- {SENSOR, OV9650_COM7, OV9650_VGA_SELECT |
- OV9650_RGB_SELECT |
- OV9650_RAW_RGB_SELECT},
-};
+ {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X},
-static const unsigned char CIF_ov9650[][3] =
-{
- /* Moves the view window in a vertical orientation */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x20}, /* 288 */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 352 + 98 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0xc2},
-
- {SENSOR, OV9650_COM7, OV9650_CIF_SELECT |
- OV9650_RGB_SELECT |
- OV9650_RAW_RGB_SELECT},
-};
-
-static const unsigned char QVGA_ov9650[][3] =
-{
- /* Moves the view window in a vertical orientation */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xf0}, /* 240 */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x31}, /* 50 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 320 + 50 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x71},
-
- {SENSOR, OV9650_COM7, OV9650_QVGA_SELECT |
- OV9650_RGB_SELECT |
- OV9650_RAW_RGB_SELECT},
+ {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
+ {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
+ {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
+ {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
+ {BRIDGE, M5602_XB_SIG_INI, 0x01}
};
#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 2e7fb91673c..eaddf488bad 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -18,6 +18,99 @@
#include "m5602_po1030.h"
+static struct v4l2_pix_format po1030_modes[] = {
+ {
+ 640,
+ 480,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 640 * 480,
+ .bytesperline = 640,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
+ }
+};
+
+const static struct ctrl po1030_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "gain",
+ .minimum = 0x00,
+ .maximum = 0x4f,
+ .step = 0x1,
+ .default_value = PO1030_GLOBAL_GAIN_DEFAULT,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = po1030_set_gain,
+ .get = po1030_get_gain
+ }, {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "exposure",
+ .minimum = 0x00,
+ .maximum = 0x02ff,
+ .step = 0x1,
+ .default_value = PO1030_EXPOSURE_DEFAULT,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = po1030_set_exposure,
+ .get = po1030_get_exposure
+ }, {
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "red balance",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x1,
+ .default_value = PO1030_RED_GAIN_DEFAULT,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = po1030_set_red_balance,
+ .get = po1030_get_red_balance
+ }, {
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "blue balance",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x1,
+ .default_value = PO1030_BLUE_GAIN_DEFAULT,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .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
+ }
+};
+
static void po1030_dump_registers(struct sd *sd);
int po1030_probe(struct sd *sd)
@@ -59,10 +152,10 @@ int po1030_probe(struct sd *sd)
return -ENODEV;
sensor_found:
- sd->gspca_dev.cam.cam_mode = po1030.modes;
- sd->gspca_dev.cam.nmodes = po1030.nmodes;
- sd->desc->ctrls = po1030.ctrls;
- sd->desc->nctrls = po1030.nctrls;
+ sd->gspca_dev.cam.cam_mode = po1030_modes;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes);
+ sd->desc->ctrls = po1030_ctrls;
+ sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls);
return 0;
}
@@ -108,7 +201,7 @@ int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H,
&i2c_data, 1);
if (err < 0)
- goto out;
+ return err;
*val = (i2c_data << 8);
err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M,
@@ -116,7 +209,7 @@ int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
*val |= i2c_data;
PDEBUG(D_V4L2, "Exposure read as %d", *val);
-out:
+
return err;
}
@@ -135,7 +228,7 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H,
&i2c_data, 1);
if (err < 0)
- goto out;
+ return err;
i2c_data = (val & 0xff);
PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
@@ -143,7 +236,6 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M,
&i2c_data, 1);
-out:
return err;
}
@@ -186,14 +278,13 @@ int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
PDEBUG(D_V4L2, "Set hflip %d", val);
err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
if (err < 0)
- goto out;
+ return err;
i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
&i2c_data, 1);
-out:
return err;
}
@@ -222,14 +313,13 @@ int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
PDEBUG(D_V4L2, "Set vflip %d", val);
err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
if (err < 0)
- goto out;
+ return err;
i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
&i2c_data, 1);
-out:
return err;
}
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index def39d5bcec..c10b1233581 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -141,7 +141,7 @@ 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 = {
+static const struct m5602_sensor po1030 = {
.name = "PO1030",
.i2c_slave_id = 0xdc,
@@ -150,102 +150,6 @@ static struct m5602_sensor po1030 = {
.probe = po1030_probe,
.init = po1030_init,
.power_down = po1030_power_down,
-
- .nctrls = 6,
- .ctrls = {
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
- .minimum = 0x00,
- .maximum = 0x4f,
- .step = 0x1,
- .default_value = PO1030_GLOBAL_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = po1030_set_gain,
- .get = po1030_get_gain
- }, {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0x02ff,
- .step = 0x1,
- .default_value = PO1030_EXPOSURE_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = po1030_set_exposure,
- .get = po1030_get_exposure
- }, {
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = PO1030_RED_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = po1030_set_red_balance,
- .get = po1030_get_red_balance
- }, {
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = PO1030_BLUE_GAIN_DEFAULT,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .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 = {
- {
- M5602_DEFAULT_FRAME_WIDTH,
- M5602_DEFAULT_FRAME_HEIGHT,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
- .bytesperline = M5602_DEFAULT_FRAME_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
- }
};
static const unsigned char preinit_po1030[][3] =
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 48892b5715d..4306d596056 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -50,6 +50,76 @@ static
{ }
};
+static struct v4l2_pix_format s5k4aa_modes[] = {
+ {
+ 640,
+ 480,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ 640 * 480,
+ .bytesperline = 640,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
+ }
+};
+
+const static struct ctrl s5k4aa_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = s5k4aa_set_vflip,
+ .get = s5k4aa_get_vflip
+
+ }, {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = s5k4aa_set_hflip,
+ .get = s5k4aa_get_hflip
+
+ }, {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gain",
+ .minimum = 0,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0xa0,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = s5k4aa_set_gain,
+ .get = s5k4aa_get_gain
+ }, {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Exposure",
+ .minimum = 13,
+ .maximum = 0xfff,
+ .step = 1,
+ .default_value = 0x100,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = s5k4aa_set_exposure,
+ .get = s5k4aa_get_exposure
+ }
+};
+
static void s5k4aa_dump_registers(struct sd *sd);
int s5k4aa_probe(struct sd *sd)
@@ -115,14 +185,56 @@ int s5k4aa_probe(struct sd *sd)
info("Detected a s5k4aa sensor");
sensor_found:
- sd->gspca_dev.cam.cam_mode = s5k4aa.modes;
- sd->gspca_dev.cam.nmodes = s5k4aa.nmodes;
- sd->desc->ctrls = s5k4aa.ctrls;
- sd->desc->nctrls = s5k4aa.nctrls;
-
+ sd->gspca_dev.cam.cam_mode = s5k4aa_modes;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes);
+ sd->desc->ctrls = s5k4aa_ctrls;
+ sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls);
return 0;
}
+int s5k4aa_start(struct sd *sd)
+{
+ int i, err = 0;
+ u8 data[2];
+ struct cam *cam = &sd->gspca_dev.cam;
+
+ switch (cam->cam_mode[sd->gspca_dev.curr_mode].width)
+ {
+ case 640:
+ PDEBUG(D_V4L2, "Configuring camera for VGA mode");
+
+ for (i = 0; i < ARRAY_SIZE(VGA_s5k4aa); i++) {
+ switch (VGA_s5k4aa[i][0]) {
+ case BRIDGE:
+ err = m5602_write_bridge(sd,
+ VGA_s5k4aa[i][1],
+ VGA_s5k4aa[i][2]);
+ break;
+
+ case SENSOR:
+ data[0] = VGA_s5k4aa[i][2];
+ err = m5602_write_sensor(sd,
+ VGA_s5k4aa[i][1],
+ data, 1);
+ break;
+
+ case SENSOR_LONG:
+ data[0] = VGA_s5k4aa[i][2];
+ data[1] = VGA_s5k4aa[i][3];
+ err = m5602_write_sensor(sd,
+ VGA_s5k4aa[i][1],
+ data, 2);
+ break;
+
+ default:
+ err("Invalid stream command, exiting init");
+ return -EINVAL;
+ }
+ }
+ }
+ return err;
+}
+
int s5k4aa_init(struct sd *sd)
{
int i, err = 0;
@@ -194,17 +306,17 @@ int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
- goto out;
+ return err;
err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
if (err < 0)
- goto out;
+ return err;
*val = data << 8;
err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
*val |= data;
PDEBUG(D_V4L2, "Read exposure %d", *val);
-out:
+
return err;
}
@@ -217,14 +329,14 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
PDEBUG(D_V4L2, "Set exposure to %d", val);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
- goto out;
+ return err;
data = (val >> 8) & 0xff;
err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
if (err < 0)
- goto out;
+ return err;
data = val & 0xff;
err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
-out:
+
return err;
}
@@ -236,13 +348,12 @@ int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
- goto out;
+ return err;
err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
*val = (data & S5K4AA_RM_V_FLIP) >> 7;
PDEBUG(D_V4L2, "Read vertical flip %d", *val);
-out:
return err;
}
@@ -255,32 +366,32 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
PDEBUG(D_V4L2, "Set vertical flip to %d", val);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
- goto out;
+ return err;
err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
if (err < 0)
- goto out;
+ return err;
data = ((data & ~S5K4AA_RM_V_FLIP)
| ((val & 0x01) << 7));
err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
if (err < 0)
- goto out;
+ return err;
if (val) {
err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
if (err < 0)
- goto out;
+ return err;
data++;
err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
} else {
err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
if (err < 0)
- goto out;
+ return err;
data--;
err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
}
-out:
+
return err;
}
@@ -292,12 +403,12 @@ int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
- goto out;
+ return err;
err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
*val = (data & S5K4AA_RM_H_FLIP) >> 6;
PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
-out:
+
return err;
}
@@ -311,32 +422,32 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
val);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
- goto out;
+ return err;
err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
if (err < 0)
- goto out;
+ return err;
data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
if (err < 0)
- goto out;
+ return err;
if (val) {
err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
if (err < 0)
- goto out;
+ return err;
data++;
err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
if (err < 0)
- goto out;
+ return err;
} else {
err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
if (err < 0)
- goto out;
+ return err;
data--;
err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
}
-out:
+
return err;
}
@@ -348,13 +459,12 @@ int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
- goto out;
+ return err;
err = m5602_read_sensor(sd, S5K4AA_GAIN_2, &data, 1);
*val = data;
PDEBUG(D_V4L2, "Read gain %d", *val);
-out:
return err;
}
@@ -367,12 +477,11 @@ int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
PDEBUG(D_V4L2, "Set gain to %d", val);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
- goto out;
+ return err;
data = val & 0xff;
err = m5602_write_sensor(sd, S5K4AA_GAIN_2, &data, 1);
-out:
return err;
}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index 1f88b0d040c..ca854d4f947 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -65,6 +65,7 @@ extern int dump_sensor;
int s5k4aa_probe(struct sd *sd);
int s5k4aa_init(struct sd *sd);
+int s5k4aa_start(struct sd *sd);
int s5k4aa_power_down(struct sd *sd);
int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
@@ -76,84 +77,14 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
-static struct m5602_sensor s5k4aa = {
+static const struct m5602_sensor s5k4aa = {
.name = "S5K4AA",
.probe = s5k4aa_probe,
.init = s5k4aa_init,
+ .start = s5k4aa_start,
.power_down = s5k4aa_power_down,
.i2c_slave_id = 0x5a,
.i2c_regW = 2,
- .nctrls = 4,
- .ctrls = {
- {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = s5k4aa_set_vflip,
- .get = s5k4aa_get_vflip
-
- }, {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = s5k4aa_set_hflip,
- .get = s5k4aa_get_hflip
-
- }, {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain",
- .minimum = 0,
- .maximum = 127,
- .step = 1,
- .default_value = 0xa0,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = s5k4aa_set_gain,
- .get = s5k4aa_get_gain
- }, {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Exposure",
- .minimum = 13,
- .maximum = 0xfff,
- .step = 1,
- .default_value = 0x100,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = s5k4aa_set_exposure,
- .get = s5k4aa_get_exposure
- }
- },
-
- .nmodes = 1,
- .modes = {
- {
- M5602_DEFAULT_FRAME_WIDTH,
- M5602_DEFAULT_FRAME_HEIGHT,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
- .bytesperline = M5602_DEFAULT_FRAME_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
- }
};
static const unsigned char preinit_s5k4aa[][4] =
@@ -329,4 +260,63 @@ static const unsigned char init_s5k4aa[][4] =
{SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
};
+static const unsigned char VGA_s5k4aa[][4] =
+{
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
+ {BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
+ {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
+ {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
+ {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
+ {BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+ /* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+ {BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+ {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
+ {BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
+ {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
+ {BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
+ /* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */
+ {BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
+ {BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00},
+ {BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
+ {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
+ {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
+
+ {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
+ {SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X
+ | S5K4AA_RM_COL_SKIP_2X, 0x00},
+ /* 0x37 : Fix image stability when light is too bright and improves
+ * image quality in 640x480, but worsens it in 1280x1024 */
+ {SENSOR, 0x37, 0x01, 0x00},
+ /* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
+ {SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
+ {SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00},
+ {SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
+ {SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00},
+ /* window_height_hi, window_height_lo : 960 = 0x03c0 */
+ {SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00},
+ {SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00},
+ /* window_width_hi, window_width_lo : 1280 = 0x0500 */
+ {SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
+ {SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
+ {SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
+ {SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */
+ {SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
+ {SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
+ {SENSOR, 0x11, 0x04, 0x00},
+ {SENSOR, 0x12, 0xc3, 0x00},
+ {SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
+ {SENSOR, 0x02, 0x0e, 0x00},
+ {SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00},
+ {SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00},
+ {SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
+};
+
#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index ccea4a75846..42c86aa4dc8 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -18,6 +18,88 @@
#include "m5602_s5k83a.h"
+static struct v4l2_pix_format s5k83a_modes[] = {
+ {
+ 640,
+ 480,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ 640 * 480,
+ .bytesperline = 640,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
+ }
+};
+
+const static struct ctrl s5k83a_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "brightness",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x01,
+ .default_value = S5K83A_DEFAULT_BRIGHTNESS,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = s5k83a_set_brightness,
+ .get = s5k83a_get_brightness
+
+ }, {
+ {
+ .id = V4L2_CID_WHITENESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "whiteness",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x01,
+ .default_value = S5K83A_DEFAULT_WHITENESS,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = s5k83a_set_whiteness,
+ .get = s5k83a_get_whiteness,
+ }, {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "gain",
+ .minimum = 0x00,
+ .maximum = S5K83A_MAXIMUM_GAIN,
+ .step = 0x01,
+ .default_value = S5K83A_DEFAULT_GAIN,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = s5k83a_set_gain,
+ .get = s5k83a_get_gain
+ }, {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = s5k83a_set_hflip,
+ .get = s5k83a_get_hflip
+ }, {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = s5k83a_set_vflip,
+ .get = s5k83a_get_vflip
+ }
+};
+
static void s5k83a_dump_registers(struct sd *sd);
int s5k83a_probe(struct sd *sd)
@@ -63,10 +145,10 @@ int s5k83a_probe(struct sd *sd)
info("Detected a s5k83a sensor");
sensor_found:
- sd->gspca_dev.cam.cam_mode = s5k83a.modes;
- sd->gspca_dev.cam.nmodes = s5k83a.nmodes;
- sd->desc->ctrls = s5k83a.ctrls;
- sd->desc->nctrls = s5k83a.nctrls;
+ sd->gspca_dev.cam.cam_mode = s5k83a_modes;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
+ sd->desc->ctrls = s5k83a_ctrls;
+ sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls);
return 0;
}
@@ -108,6 +190,16 @@ int s5k83a_init(struct sd *sd)
return (err < 0) ? err : 0;
}
+int s5k83a_start(struct sd *sd)
+{
+ return s5k83a_set_led_indication(sd, 1);
+}
+
+int s5k83a_stop(struct sd *sd)
+{
+ return s5k83a_set_led_indication(sd, 0);
+}
+
int s5k83a_power_down(struct sd *sd)
{
return 0;
@@ -163,12 +255,11 @@ int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
err = m5602_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
if (err < 0)
- goto out;
+ return err;
data[1] = data[1] << 1;
*val = data[1];
-out:
return err;
}
@@ -182,13 +273,13 @@ int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
data[1] = 0x20;
err = m5602_write_sensor(sd, 0x14, data, 2);
if (err < 0)
- goto out;
+ return err;
data[0] = 0x01;
data[1] = 0x00;
err = m5602_write_sensor(sd, 0x0d, data, 2);
if (err < 0)
- goto out;
+ return err;
/* FIXME: This is not sane, we need to figure out the composition
of these registers */
@@ -196,7 +287,6 @@ int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
data[1] = val >> 1; /* brightness, high 7 bits */
err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
-out:
return err;
}
@@ -208,11 +298,10 @@ int s5k83a_get_whiteness(struct gspca_dev *gspca_dev, __s32 *val)
err = m5602_read_sensor(sd, S5K83A_WHITENESS, &data, 1);
if (err < 0)
- goto out;
+ return err;
*val = data;
-out:
return err;
}
@@ -236,7 +325,7 @@ int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
err = m5602_read_sensor(sd, S5K83A_GAIN, data, 2);
if (err < 0)
- goto out;
+ return err;
data[1] = data[1] & 0x3f;
if (data[1] > S5K83A_MAXIMUM_GAIN)
@@ -244,7 +333,6 @@ int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
*val = data[1];
-out:
return err;
}
@@ -269,12 +357,11 @@ int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
data[0] = 0x05;
err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
if (err < 0)
- goto out;
+ return err;
err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
*val = (data[0] | 0x40) ? 1 : 0;
-out:
return err;
}
@@ -287,23 +374,22 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
data[0] = 0x05;
err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
if (err < 0)
- goto out;
+ return err;
err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
if (err < 0)
- goto out;
+ return err;
/* set or zero six bit, seven is hflip */
data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK
: (data[0] & 0x80) | S5K83A_FLIP_MASK;
err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
if (err < 0)
- goto out;
+ return err;
data[0] = (val) ? 0x0b : 0x0a;
err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
-out:
return err;
}
@@ -316,12 +402,11 @@ int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
data[0] = 0x05;
err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
if (err < 0)
- goto out;
+ return err;
err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
*val = (data[0] | 0x80) ? 1 : 0;
-out:
return err;
}
@@ -334,21 +419,40 @@ int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
data[0] = 0x05;
err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
if (err < 0)
- goto out;
+ return err;
err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
if (err < 0)
- goto out;
+ return err;
/* set or zero seven bit, six is vflip */
data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK
: (data[0] & 0x40) | S5K83A_FLIP_MASK;
err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
if (err < 0)
- goto out;
+ return err;
data[0] = (val) ? 0x0a : 0x0b;
err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
-out:
+
return err;
}
+
+int s5k83a_set_led_indication(struct sd *sd, u8 val)
+{
+ int err = 0;
+ u8 data[1];
+
+ err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data);
+ if (err < 0)
+ return err;
+
+ if (val)
+ data[0] = data[0] | S5K83A_GPIO_LED_MASK;
+ else
+ data[0] = data[0] & ~S5K83A_GPIO_LED_MASK;
+
+ err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
+
+ return (err < 0) ? err : 0;
+}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 05ccb5b57a8..819ab25272b 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -34,7 +34,7 @@
#define S5K83A_DEFAULT_GAIN 0x00
#define S5K83A_MAXIMUM_GAIN 0x3c
#define S5K83A_FLIP_MASK 0x10
-
+#define S5K83A_GPIO_LED_MASK 0x10
/*****************************************************************************/
@@ -44,8 +44,12 @@ extern int dump_sensor;
int s5k83a_probe(struct sd *sd);
int s5k83a_init(struct sd *sd);
+int s5k83a_start(struct sd *sd);
+int s5k83a_stop(struct sd *sd);
int s5k83a_power_down(struct sd *sd);
+int s5k83a_set_led_indication(struct sd *sd, u8 val);
+
int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val);
@@ -57,95 +61,15 @@ int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
-static struct m5602_sensor s5k83a = {
+static const struct m5602_sensor s5k83a = {
.name = "S5K83A",
.probe = s5k83a_probe,
.init = s5k83a_init,
+ .start = s5k83a_start,
+ .stop = s5k83a_stop,
.power_down = s5k83a_power_down,
.i2c_slave_id = 0x5a,
.i2c_regW = 2,
- .nctrls = 5,
- .ctrls = {
- {
- {
- .id = V4L2_CID_BRIGHTNESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "brightness",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = S5K83A_DEFAULT_BRIGHTNESS,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = s5k83a_set_brightness,
- .get = s5k83a_get_brightness
-
- }, {
- {
- .id = V4L2_CID_WHITENESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "whiteness",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = S5K83A_DEFAULT_WHITENESS,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = s5k83a_set_whiteness,
- .get = s5k83a_get_whiteness,
- }, {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
- .minimum = 0x00,
- .maximum = S5K83A_MAXIMUM_GAIN,
- .step = 0x01,
- .default_value = S5K83A_DEFAULT_GAIN,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = s5k83a_set_gain,
- .get = s5k83a_get_gain
- }, {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = s5k83a_set_hflip,
- .get = s5k83a_get_hflip
- }, {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = s5k83a_set_vflip,
- .get = s5k83a_get_vflip
- }
- },
- .nmodes = 1,
- .modes = {
- {
- M5602_DEFAULT_FRAME_WIDTH,
- M5602_DEFAULT_FRAME_HEIGHT,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
- .bytesperline = M5602_DEFAULT_FRAME_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
- }
};
static const unsigned char preinit_s5k83a[][4] =
@@ -381,7 +305,7 @@ static const unsigned char init_s5k83a[][4] =
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
- {BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
+ {BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
index 261623f0da4..0d3026936f2 100644
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -21,11 +21,6 @@
#include "m5602_bridge.h"
-#define M5602_DEFAULT_FRAME_WIDTH 640
-#define M5602_DEFAULT_FRAME_HEIGHT 480
-
-#define M5602_MAX_CTRLS (V4L2_CID_LASTP1 - V4L2_CID_BASE + 10)
-
/* Enumerates all supported sensors */
enum sensors {
OV9650_SENSOR = 1,
@@ -61,14 +56,14 @@ struct m5602_sensor {
/* Executed when the camera starts to send data */
int (*start)(struct sd *sd);
- /* Performs a power down sequence */
- int (*power_down)(struct sd *sd);
+ /* Executed when the camera ends to send data */
+ int (*stop)(struct sd *sd);
- int nctrls;
- struct ctrl ctrls[M5602_MAX_CTRLS];
+ /* Executed when the device is disconnected */
+ void (*disconnect)(struct sd *sd);
- char nmodes;
- struct v4l2_pix_format modes[];
+ /* Performs a power down sequence */
+ int (*power_down)(struct sd *sd);
};
#endif
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
index 04e3ae57a2e..2e1cdf068fd 100644
--- a/drivers/media/video/gspca/sq905.c
+++ b/drivers/media/video/gspca/sq905.c
@@ -360,6 +360,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
gspca_dev->cam.nmodes = ARRAY_SIZE(sq905_mode);
if (!(ident & SQ905_HIRES_MASK))
gspca_dev->cam.nmodes--;
+
+ if (ident & SQ905_ORIENTATION_MASK)
+ gspca_dev->cam.input_flags = V4L2_IN_ST_VFLIP;
+ else
+ gspca_dev->cam.input_flags = V4L2_IN_ST_VFLIP |
+ V4L2_IN_ST_HFLIP;
return 0;
}
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 4c802fb12cd..e4e933c400b 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -159,37 +159,16 @@ static const struct v4l2_pix_format vc0323_mode[] = {
.priv = 2},
};
static const struct v4l2_pix_format bi_mode[] = {
-/*fixme: jeg does not work
- {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 5},
-*/
{320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 * 2,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 4},
-/*
- {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 640,
- .sizeimage = 640 * 480 * 3 / 8 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .priv = 3},
-*/
+ .priv = 2},
{640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
.bytesperline = 640,
.sizeimage = 640 * 480 * 2,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 2},
-/*
- {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
- .bytesperline = 1280,
- .sizeimage = 1280 * 1024 * 1 / 4 + 590,
- .colorspace = V4L2_COLORSPACE_JPEG,
.priv = 1},
-*/
{1280, 1024, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
.bytesperline = 1280,
.sizeimage = 1280 * 1024 * 2,
@@ -1034,121 +1013,6 @@ static const u8 mi1320_soc_InitVGA[][4] = {
{0xb3, 0x5c, 0x01, 0xcc},
{}
};
-static const u8 mi1320_soc_InitVGA_JPG[][4] = {
- {0xb3, 0x01, 0x01, 0xcc},
- {0xb0, 0x03, 0x19, 0xcc},
- {0xb0, 0x04, 0x02, 0xcc},
- {0x00, 0x00, 0x30, 0xdd},
- {0xb3, 0x00, 0x64, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc},
- {0xb3, 0x35, 0xc8, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc},
- {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x01, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc},
- {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc},
- {0xbc, 0x00, 0x71, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x00, 0x00, 0x10, 0xdd},
- {0xc8, 0x00, 0x00, 0xbb},
- {0x00, 0x00, 0x30, 0xdd},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x00, 0x00, 0x10, 0xdd},
- {0x07, 0x00, 0xe0, 0xbb},
- {0x08, 0x00, 0x0b, 0xbb},
- {0x21, 0x00, 0x0c, 0xbb},
- {0x20, 0x01, 0x03, 0xbb},
- {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x02, 0xcc},
- {0xb6, 0x02, 0x80, 0xcc},
- {0xb6, 0x05, 0x01, 0xcc},
- {0xb6, 0x04, 0xe0, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x05, 0xcc},
- {0xb6, 0x18, 0x02, 0xcc},
- {0xb6, 0x17, 0x58, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc},
- {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc},
- {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x00, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x05, 0x01, 0x78, 0xbb},
- {0x06, 0x00, 0x11, 0xbb},
- {0x07, 0x01, 0x42, 0xbb},
- {0x08, 0x00, 0x11, 0xbb},
- {0x20, 0x01, 0x03, 0xbb},
- {0x21, 0x80, 0x00, 0xbb},
- {0x22, 0x0d, 0x0f, 0xbb},
- {0x24, 0x80, 0x00, 0xbb},
- {0x59, 0x00, 0xff, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x39, 0x03, 0xca, 0xbb},
- {0x3a, 0x06, 0x80, 0xbb},
- {0x3b, 0x01, 0x52, 0xbb},
- {0x3c, 0x05, 0x40, 0xbb},
- {0x57, 0x01, 0x9c, 0xbb},
- {0x58, 0x01, 0xee, 0xbb},
- {0x59, 0x00, 0xf0, 0xbb},
- {0x5a, 0x01, 0x20, 0xbb},
- {0x5c, 0x1d, 0x17, 0xbb},
- {0x5d, 0x22, 0x1c, 0xbb},
- {0x64, 0x1e, 0x1c, 0xbb},
- {0x5b, 0x00, 0x00, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x22, 0xa0, 0x78, 0xbb},
- {0x23, 0xa0, 0x78, 0xbb},
- {0x24, 0x7f, 0x00, 0xbb},
- {0x28, 0xea, 0x02, 0xbb},
- {0x29, 0x86, 0x7a, 0xbb},
- {0x5e, 0x52, 0x4c, 0xbb},
- {0x5f, 0x20, 0x24, 0xbb},
- {0x60, 0x00, 0x02, 0xbb},
- {0x02, 0x00, 0xee, 0xbb},
- {0x03, 0x39, 0x23, 0xbb},
- {0x04, 0x07, 0x24, 0xbb},
- {0x09, 0x00, 0xc0, 0xbb},
- {0x0a, 0x00, 0x79, 0xbb},
- {0x0b, 0x00, 0x04, 0xbb},
- {0x0c, 0x00, 0x5c, 0xbb},
- {0x0d, 0x00, 0xd9, 0xbb},
- {0x0e, 0x00, 0x53, 0xbb},
- {0x0f, 0x00, 0x21, 0xbb},
- {0x10, 0x00, 0xa4, 0xbb},
- {0x11, 0x00, 0xe5, 0xbb},
- {0x15, 0x00, 0x00, 0xbb},
- {0x16, 0x00, 0x00, 0xbb},
- {0x17, 0x00, 0x00, 0xbb},
- {0x18, 0x00, 0x00, 0xbb},
- {0x19, 0x00, 0x00, 0xbb},
- {0x1a, 0x00, 0x00, 0xbb},
- {0x1b, 0x00, 0x00, 0xbb},
- {0x1c, 0x00, 0x00, 0xbb},
- {0x1d, 0x00, 0x00, 0xbb},
- {0x1e, 0x00, 0x00, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x06, 0xe0, 0x0e, 0xbb},
- {0x06, 0x60, 0x0e, 0xbb},
- {0xb3, 0x5c, 0x01, 0xcc},
- {}
-};
static const u8 mi1320_soc_InitQVGA[][4] = {
{0xb3, 0x01, 0x01, 0xcc},
{0xb0, 0x03, 0x19, 0xcc},
@@ -1262,268 +1126,6 @@ static const u8 mi1320_soc_InitQVGA[][4] = {
{0xb3, 0x5c, 0x01, 0xcc},
{}
};
-static const u8 mi1320_soc_InitQVGA_JPG[][4] = {
- {0xb3, 0x01, 0x01, 0xcc},
- {0xb0, 0x03, 0x19, 0xcc},
- {0xb0, 0x04, 0x02, 0xcc},
- {0x00, 0x00, 0x30, 0xdd},
- {0xb3, 0x00, 0x64, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb3, 0x05, 0x01, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc},
- {0xb3, 0x35, 0xc8, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc},
- {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x01, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x02, 0xcc},
- {0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc},
- {0xbc, 0x00, 0xd1, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x00, 0x00, 0x10, 0xdd},
- {0xc8, 0x00, 0x00, 0xbb},
- {0x00, 0x00, 0x30, 0xdd},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x00, 0x00, 0x10, 0xdd},
- {0x07, 0x00, 0xe0, 0xbb},
- {0x08, 0x00, 0x0b, 0xbb},
- {0x21, 0x00, 0x0c, 0xbb},
- {0x20, 0x01, 0x03, 0xbb},
- {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x01, 0xcc},
- {0xb6, 0x02, 0x40, 0xcc},
- {0xb6, 0x05, 0x00, 0xcc},
- {0xb6, 0x04, 0xf0, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x05, 0xcc},
- {0xb6, 0x18, 0x00, 0xcc},
- {0xb6, 0x17, 0x96, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc},
- {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc},
- {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x00, 0xcc},
- {0xbc, 0x02, 0x18, 0xcc},
- {0xbc, 0x03, 0x50, 0xcc},
- {0xbc, 0x04, 0x18, 0xcc},
- {0xbc, 0x05, 0x00, 0xcc},
- {0xbc, 0x06, 0x00, 0xcc},
- {0xbc, 0x08, 0x30, 0xcc},
- {0xbc, 0x09, 0x40, 0xcc},
- {0xbc, 0x0a, 0x10, 0xcc},
- {0xbc, 0x0b, 0x00, 0xcc},
- {0xbc, 0x0c, 0x00, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x05, 0x01, 0x78, 0xbb},
- {0x06, 0x00, 0x11, 0xbb},
- {0x07, 0x01, 0x42, 0xbb},
- {0x08, 0x00, 0x11, 0xbb},
- {0x20, 0x01, 0x03, 0xbb},
- {0x21, 0x80, 0x00, 0xbb},
- {0x22, 0x0d, 0x0f, 0xbb},
- {0x24, 0x80, 0x00, 0xbb},
- {0x59, 0x00, 0xff, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x39, 0x03, 0xca, 0xbb},
- {0x3a, 0x06, 0x80, 0xbb},
- {0x3b, 0x01, 0x52, 0xbb},
- {0x3c, 0x05, 0x40, 0xbb},
- {0x57, 0x01, 0x9c, 0xbb},
- {0x58, 0x01, 0xee, 0xbb},
- {0x59, 0x00, 0xf0, 0xbb},
- {0x5a, 0x01, 0x20, 0xbb},
- {0x5c, 0x1d, 0x17, 0xbb},
- {0x5d, 0x22, 0x1c, 0xbb},
- {0x64, 0x1e, 0x1c, 0xbb},
- {0x5b, 0x00, 0x00, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x22, 0xa0, 0x78, 0xbb},
- {0x23, 0xa0, 0x78, 0xbb},
- {0x24, 0x7f, 0x00, 0xbb},
- {0x28, 0xea, 0x02, 0xbb},
- {0x29, 0x86, 0x7a, 0xbb},
- {0x5e, 0x52, 0x4c, 0xbb},
- {0x5f, 0x20, 0x24, 0xbb},
- {0x60, 0x00, 0x02, 0xbb},
- {0x02, 0x00, 0xee, 0xbb},
- {0x03, 0x39, 0x23, 0xbb},
- {0x04, 0x07, 0x24, 0xbb},
- {0x09, 0x00, 0xc0, 0xbb},
- {0x0a, 0x00, 0x79, 0xbb},
- {0x0b, 0x00, 0x04, 0xbb},
- {0x0c, 0x00, 0x5c, 0xbb},
- {0x0d, 0x00, 0xd9, 0xbb},
- {0x0e, 0x00, 0x53, 0xbb},
- {0x0f, 0x00, 0x21, 0xbb},
- {0x10, 0x00, 0xa4, 0xbb},
- {0x11, 0x00, 0xe5, 0xbb},
- {0x15, 0x00, 0x00, 0xbb},
- {0x16, 0x00, 0x00, 0xbb},
- {0x17, 0x00, 0x00, 0xbb},
- {0x18, 0x00, 0x00, 0xbb},
- {0x19, 0x00, 0x00, 0xbb},
- {0x1a, 0x00, 0x00, 0xbb},
- {0x1b, 0x00, 0x00, 0xbb},
- {0x1c, 0x00, 0x00, 0xbb},
- {0x1d, 0x00, 0x00, 0xbb},
- {0x1e, 0x00, 0x00, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x06, 0xe0, 0x0e, 0xbb},
- {0x06, 0x60, 0x0e, 0xbb},
- {0xb3, 0x5c, 0x01, 0xcc},
- {}
-};
-static const u8 mi1320_soc_InitSXGA_JPG[][4] = {
- {0xb3, 0x01, 0x01, 0xcc},
- {0xb0, 0x03, 0x19, 0xcc},
- {0xb0, 0x04, 0x02, 0xcc},
- {0x00, 0x00, 0x33, 0xdd},
- {0xb3, 0x00, 0x64, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x00, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc},
- {0xb3, 0x35, 0xc8, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc},
- {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x04, 0xcc},
- {0xb3, 0x23, 0x00, 0xcc},
- {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x04, 0xcc},
- {0xb3, 0x17, 0xff, 0xcc},
- {0xb3, 0x00, 0x67, 0xcc},
- {0xbc, 0x00, 0x71, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x00, 0x00, 0x30, 0xdd},
- {0xc8, 0x9f, 0x0b, 0xbb},
- {0x00, 0x00, 0x20, 0xdd},
- {0x5b, 0x00, 0x01, 0xbb},
- {0x00, 0x00, 0x20, 0xdd},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x00, 0x00, 0x30, 0xdd},
- {0x20, 0x01, 0x03, 0xbb},
- {0x00, 0x00, 0x20, 0xdd},
- {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x05, 0xcc},
- {0xb6, 0x02, 0x00, 0xcc},
- {0xb6, 0x05, 0x04, 0xcc},
- {0xb6, 0x04, 0x00, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x29, 0xcc},
- {0xb6, 0x18, 0x0a, 0xcc},
- {0xb6, 0x17, 0x00, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc},
- {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc},
- {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x05, 0x01, 0x78, 0xbb},
- {0x06, 0x00, 0x11, 0xbb},
- {0x07, 0x01, 0x42, 0xbb},
- {0x08, 0x00, 0x11, 0xbb},
- {0x20, 0x01, 0x03, 0xbb},
- {0x21, 0x80, 0x00, 0xbb},
- {0x22, 0x0d, 0x0f, 0xbb},
- {0x24, 0x80, 0x00, 0xbb},
- {0x59, 0x00, 0xff, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x39, 0x03, 0xca, 0xbb},
- {0x3a, 0x06, 0x80, 0xbb},
- {0x3b, 0x01, 0x52, 0xbb},
- {0x3c, 0x05, 0x40, 0xbb},
- {0x57, 0x01, 0x9c, 0xbb},
- {0x58, 0x01, 0xee, 0xbb},
- {0x59, 0x00, 0xf0, 0xbb},
- {0x5a, 0x01, 0x20, 0xbb},
- {0x5c, 0x1d, 0x17, 0xbb},
- {0x5d, 0x22, 0x1c, 0xbb},
- {0x64, 0x1e, 0x1c, 0xbb},
- {0x5b, 0x00, 0x00, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x22, 0xa0, 0x78, 0xbb},
- {0x23, 0xa0, 0x78, 0xbb},
- {0x24, 0x7f, 0x00, 0xbb},
- {0x28, 0xea, 0x02, 0xbb},
- {0x29, 0x86, 0x7a, 0xbb},
- {0x5e, 0x52, 0x4c, 0xbb},
- {0x5f, 0x20, 0x24, 0xbb},
- {0x60, 0x00, 0x02, 0xbb},
- {0x02, 0x00, 0xee, 0xbb},
- {0x03, 0x39, 0x23, 0xbb},
- {0x04, 0x07, 0x24, 0xbb},
- {0x09, 0x00, 0xc0, 0xbb},
- {0x0a, 0x00, 0x79, 0xbb},
- {0x0b, 0x00, 0x04, 0xbb},
- {0x0c, 0x00, 0x5c, 0xbb},
- {0x0d, 0x00, 0xd9, 0xbb},
- {0x0e, 0x00, 0x53, 0xbb},
- {0x0f, 0x00, 0x21, 0xbb},
- {0x10, 0x00, 0xa4, 0xbb},
- {0x11, 0x00, 0xe5, 0xbb},
- {0x15, 0x00, 0x00, 0xbb},
- {0x16, 0x00, 0x00, 0xbb},
- {0x17, 0x00, 0x00, 0xbb},
- {0x18, 0x00, 0x00, 0xbb},
- {0x19, 0x00, 0x00, 0xbb},
- {0x1a, 0x00, 0x00, 0xbb},
- {0x1b, 0x00, 0x00, 0xbb},
- {0x1c, 0x00, 0x00, 0xbb},
- {0x1d, 0x00, 0x00, 0xbb},
- {0x1e, 0x00, 0x00, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x06, 0xe0, 0x0e, 0xbb},
- {0x06, 0x60, 0x0e, 0xbb},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb},
- {0x05, 0x01, 0x13, 0xbb},
- {0x06, 0x00, 0x11, 0xbb},
- {0x07, 0x00, 0x85, 0xbb},
- {0x08, 0x00, 0x27, 0xbb},
- {0x20, 0x01, 0x03, 0xbb},
- {0x21, 0x80, 0x00, 0xbb},
- {0x22, 0x0d, 0x0f, 0xbb},
- {0x24, 0x80, 0x00, 0xbb},
- {0x59, 0x00, 0xff, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x39, 0x03, 0x0d, 0xbb},
- {0x3a, 0x06, 0x1b, 0xbb},
- {0x3b, 0x00, 0x95, 0xbb},
- {0x3c, 0x04, 0xdb, 0xbb},
- {0x57, 0x02, 0x00, 0xbb},
- {0x58, 0x02, 0x66, 0xbb},
- {0x59, 0x00, 0xff, 0xbb},
- {0x5a, 0x01, 0x33, 0xbb},
- {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb},
- {0x64, 0x5e, 0x1c, 0xbb},
- {0x2f, 0x90, 0x00, 0xbb},
- {}
-};
static const u8 mi1320_soc_InitSXGA[][4] = {
{0xb3, 0x01, 0x01, 0xcc},
{0xb0, 0x03, 0x19, 0xcc},
@@ -3015,11 +2617,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
int mode;
static const u8 (*mi1320_soc_init[])[4] = {
mi1320_soc_InitSXGA,
- mi1320_soc_InitSXGA_JPG,
mi1320_soc_InitVGA,
- mi1320_soc_InitVGA_JPG,
mi1320_soc_InitQVGA,
- mi1320_soc_InitQVGA_JPG
};
/* Assume start use the good resolution from gspca_dev->mode */
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index eca8bf92a22..b0195e8ee4d 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -884,12 +884,9 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
}
else if (itv->card->type == IVTV_CARD_GV_MVPRX ||
itv->card->type == IVTV_CARD_GV_MVPRX2E) {
- struct v4l2_crystal_freq crystal_freq;
-
/* The crystal frequency of GVMVPRX is 24.576MHz */
- crystal_freq.freq = SAA7115_FREQ_24_576_MHZ;
- crystal_freq.flags = SAA7115_FREQ_FL_UCGC;
- v4l2_subdev_call(itv->sd_video, video, s_crystal_freq, &crystal_freq);
+ v4l2_subdev_call(itv->sd_video, video, s_crystal_freq,
+ SAA7115_FREQ_24_576_MHZ, SAA7115_FREQ_FL_UCGC);
}
if (hw & IVTV_HW_CX25840) {
@@ -1234,7 +1231,7 @@ int ivtv_init_on_first_open(struct ivtv *itv)
if (itv->card->hw_all & IVTV_HW_CX25840) {
struct v4l2_control ctrl;
- v4l2_subdev_call(itv->sd_video, core, init, 0);
+ v4l2_subdev_call(itv->sd_video, core, load_fw);
/* CX25840_CID_ENABLE_PVR150_WORKAROUND */
ctrl.id = V4L2_CID_PRIVATE_BASE;
ctrl.value = itv->pvr150_workaround;
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index cfaacf6096d..e707ef3086b 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -857,15 +857,12 @@ int ivtv_v4l2_close(struct file *filp)
/* Mark that the radio is no longer in use */
clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
/* Switch tuner to TV */
- ivtv_call_all(itv, tuner, s_std, itv->std);
+ ivtv_call_all(itv, core, s_std, itv->std);
/* Select correct audio input (i.e. TV tuner or Line in) */
ivtv_audio_set_io(itv);
- if (itv->hw_flags & IVTV_HW_SAA711X)
- {
- struct v4l2_crystal_freq crystal_freq;
- crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
- crystal_freq.flags = 0;
- ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq, &crystal_freq);
+ if (itv->hw_flags & IVTV_HW_SAA711X) {
+ ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,
+ SAA7115_FREQ_32_11_MHZ, 0);
}
if (atomic_read(&itv->capturing) > 0) {
/* Undo video mute */
@@ -956,10 +953,8 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
/* Select the correct audio input (i.e. radio tuner) */
ivtv_audio_set_io(itv);
if (itv->hw_flags & IVTV_HW_SAA711X) {
- struct v4l2_crystal_freq crystal_freq;
- crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
- crystal_freq.flags = SAA7115_FREQ_FL_APLL;
- ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq, &crystal_freq);
+ ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,
+ SAA7115_FREQ_32_11_MHZ, SAA7115_FREQ_FL_APLL);
}
/* Done! Unmute and continue. */
ivtv_unmute(itv);
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
index 3321983d89e..ceb05bdcaf6 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -248,15 +248,16 @@ static int subdev_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
return 0;
}
-static int subdev_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int subdev_s_audio_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct ivtv *itv = sd_to_ivtv(sd);
u16 mask, data;
- if (route->input > 2)
+ if (input > 2)
return -EINVAL;
mask = itv->card->gpio_audio_input.mask;
- switch (route->input) {
+ switch (input) {
case 0:
data = itv->card->gpio_audio_input.tuner;
break;
@@ -318,17 +319,18 @@ static int subdev_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int subdev_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int subdev_s_video_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct ivtv *itv = sd_to_ivtv(sd);
u16 mask, data;
- if (route->input > 2) /* 0:Tuner 1:Composite 2:S-Video */
+ if (input > 2) /* 0:Tuner 1:Composite 2:S-Video */
return -EINVAL;
mask = itv->card->gpio_video_input.mask;
- if (route->input == 0)
+ if (input == 0)
data = itv->card->gpio_video_input.tuner;
- else if (route->input == 1)
+ else if (input == 1)
data = itv->card->gpio_video_input.composite;
else
data = itv->card->gpio_video_input.svideo;
@@ -342,10 +344,10 @@ static const struct v4l2_subdev_core_ops subdev_core_ops = {
.g_ctrl = subdev_g_ctrl,
.s_ctrl = subdev_s_ctrl,
.queryctrl = subdev_queryctrl,
+ .s_std = subdev_s_std,
};
static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = {
- .s_std = subdev_s_std,
.s_radio = subdev_s_radio,
.g_tuner = subdev_g_tuner,
.s_tuner = subdev_s_tuner,
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index e73a196ecc7..9e3d32b8004 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -161,15 +161,18 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
return -1;
if (hw == IVTV_HW_TUNER) {
/* special tuner handling */
- sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
+ sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev,
+ adap, mod, type,
itv->card_i2c->radio);
if (sd)
sd->grp_id = 1 << idx;
- sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
+ sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev,
+ adap, mod, type,
itv->card_i2c->demod);
if (sd)
sd->grp_id = 1 << idx;
- sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
+ sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev,
+ adap, mod, type,
itv->card_i2c->tv);
if (sd)
sd->grp_id = 1 << idx;
@@ -178,11 +181,11 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
if (!hw_addrs[idx])
return -1;
if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
- unsigned short addrs[2] = { hw_addrs[idx], I2C_CLIENT_END };
-
- sd = v4l2_i2c_new_probed_subdev(adap, mod, type, addrs);
+ sd = v4l2_i2c_new_probed_subdev_addr(&itv->v4l2_dev,
+ adap, mod, type, hw_addrs[idx]);
} else {
- sd = v4l2_i2c_new_subdev(adap, mod, type, hw_addrs[idx]);
+ sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
+ adap, mod, type, hw_addrs[idx]);
}
if (sd)
sd->grp_id = 1 << idx;
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 9a0424298af..4a2d464f055 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1033,7 +1033,6 @@ static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
{
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- struct v4l2_routing route;
if (outp >= itv->card->nof_outputs)
return -EINVAL;
@@ -1046,9 +1045,9 @@ static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
itv->active_output, outp);
itv->active_output = outp;
- route.input = SAA7127_INPUT_TYPE_NORMAL;
- route.output = itv->card->video_outputs[outp].video_output;
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, &route);
+ ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
+ SAA7127_INPUT_TYPE_NORMAL,
+ itv->card->video_outputs[outp].video_output, 0);
return 0;
}
@@ -1121,7 +1120,7 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
/* Tuner */
- ivtv_call_all(itv, tuner, s_std, itv->std);
+ ivtv_call_all(itv, core, s_std, itv->std);
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
/* set display standard */
@@ -1735,13 +1734,6 @@ static long ivtv_default(struct file *file, void *fh, int cmd, void *arg)
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
switch (cmd) {
- case VIDIOC_INT_S_AUDIO_ROUTING: {
- struct v4l2_routing *route = arg;
-
- ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing, route);
- break;
- }
-
case VIDIOC_INT_RESET: {
u32 val = *(u32 *)arg;
diff --git a/drivers/media/video/ivtv/ivtv-routing.c b/drivers/media/video/ivtv/ivtv-routing.c
index 3fd30229449..8898c569a1c 100644
--- a/drivers/media/video/ivtv/ivtv-routing.c
+++ b/drivers/media/video/ivtv/ivtv-routing.c
@@ -34,7 +34,7 @@
void ivtv_audio_set_io(struct ivtv *itv)
{
const struct ivtv_card_audio_input *in;
- struct v4l2_routing route;
+ u32 input, output = 0;
/* Determine which input to use */
if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags))
@@ -43,73 +43,77 @@ void ivtv_audio_set_io(struct ivtv *itv)
in = &itv->card->audio_inputs[itv->audio_input];
/* handle muxer chips */
- route.input = in->muxer_input;
- route.output = 0;
+ input = in->muxer_input;
if (itv->card->hw_muxer & IVTV_HW_M52790)
- route.output = M52790_OUT_STEREO;
- v4l2_subdev_call(itv->sd_muxer, audio, s_routing, &route);
+ output = M52790_OUT_STEREO;
+ v4l2_subdev_call(itv->sd_muxer, audio, s_routing,
+ input, output, 0);
- route.input = in->audio_input;
- route.output = 0;
+ input = in->audio_input;
+ output = 0;
if (itv->card->hw_audio & IVTV_HW_MSP34XX)
- route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
- ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing, &route);
+ output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
+ ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing,
+ input, output, 0);
}
/* Selects the video input and output according to the current
settings. */
void ivtv_video_set_io(struct ivtv *itv)
{
- struct v4l2_routing route;
int inp = itv->active_input;
+ u32 input;
u32 type;
- route.input = itv->card->video_inputs[inp].video_input;
- route.output = 0;
- v4l2_subdev_call(itv->sd_video, video, s_routing, &route);
+ v4l2_subdev_call(itv->sd_video, video, s_routing,
+ itv->card->video_inputs[inp].video_input, 0, 0);
type = itv->card->video_inputs[inp].video_type;
if (type == IVTV_CARD_INPUT_VID_TUNER) {
- route.input = 0; /* Tuner */
+ input = 0; /* Tuner */
} else if (type < IVTV_CARD_INPUT_COMPOSITE1) {
- route.input = 2; /* S-Video */
+ input = 2; /* S-Video */
} else {
- route.input = 1; /* Composite */
+ input = 1; /* Composite */
}
if (itv->card->hw_video & IVTV_HW_GPIO)
- ivtv_call_hw(itv, IVTV_HW_GPIO, video, s_routing, &route);
+ ivtv_call_hw(itv, IVTV_HW_GPIO, video, s_routing,
+ input, 0, 0);
if (itv->card->hw_video & IVTV_HW_UPD64031A) {
if (type == IVTV_CARD_INPUT_VID_TUNER ||
type >= IVTV_CARD_INPUT_COMPOSITE1) {
/* Composite: GR on, connect to 3DYCS */
- route.input = UPD64031A_GR_ON | UPD64031A_3DYCS_COMPOSITE;
+ input = UPD64031A_GR_ON | UPD64031A_3DYCS_COMPOSITE;
} else {
/* S-Video: GR bypassed, turn it off */
- route.input = UPD64031A_GR_OFF | UPD64031A_3DYCS_DISABLE;
+ input = UPD64031A_GR_OFF | UPD64031A_3DYCS_DISABLE;
}
- route.input |= itv->card->gr_config;
+ input |= itv->card->gr_config;
- ivtv_call_hw(itv, IVTV_HW_UPD64031A, video, s_routing, &route);
+ ivtv_call_hw(itv, IVTV_HW_UPD64031A, video, s_routing,
+ input, 0, 0);
}
if (itv->card->hw_video & IVTV_HW_UPD6408X) {
- route.input = UPD64083_YCS_MODE;
+ input = UPD64083_YCS_MODE;
if (type > IVTV_CARD_INPUT_VID_TUNER &&
type < IVTV_CARD_INPUT_COMPOSITE1) {
- /* S-Video uses YCNR mode and internal Y-ADC, the upd64031a
- is not used. */
- route.input |= UPD64083_YCNR_MODE;
+ /* S-Video uses YCNR mode and internal Y-ADC, the
+ upd64031a is not used. */
+ input |= UPD64083_YCNR_MODE;
}
else if (itv->card->hw_video & IVTV_HW_UPD64031A) {
- /* Use upd64031a output for tuner and composite(CX23416GYC only) inputs */
- if ((type == IVTV_CARD_INPUT_VID_TUNER)||
- (itv->card->type == IVTV_CARD_CX23416GYC)) {
- route.input |= UPD64083_EXT_Y_ADC;
- }
+ /* Use upd64031a output for tuner and
+ composite(CX23416GYC only) inputs */
+ if (type == IVTV_CARD_INPUT_VID_TUNER ||
+ itv->card->type == IVTV_CARD_CX23416GYC) {
+ input |= UPD64083_EXT_Y_ADC;
+ }
}
- ivtv_call_hw(itv, IVTV_HW_UPD6408X, video, s_routing, &route);
+ ivtv_call_hw(itv, IVTV_HW_UPD6408X, video, s_routing,
+ input, 0, 0);
}
}
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
index 841024b6bcd..fab8e0254bb 100644
--- a/drivers/media/video/ks0127.c
+++ b/drivers/media/video/ks0127.c
@@ -409,11 +409,12 @@ static void ks0127_init(struct v4l2_subdev *sd)
}
}
-static int ks0127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int ks0127_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct ks0127 *ks = to_ks0127(sd);
- switch (route->input) {
+ switch (input) {
case KS_INPUT_COMPOSITE_1:
case KS_INPUT_COMPOSITE_2:
case KS_INPUT_COMPOSITE_3:
@@ -421,13 +422,13 @@ static int ks0127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *r
case KS_INPUT_COMPOSITE_5:
case KS_INPUT_COMPOSITE_6:
v4l2_dbg(1, debug, sd,
- "s_routing %d: Composite\n", route->input);
+ "s_routing %d: Composite\n", input);
/* autodetect 50/60 Hz */
ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00);
/* VSE=0 */
ks0127_and_or(sd, KS_CMDA, ~0x40, 0x00);
/* set input line */
- ks0127_and_or(sd, KS_CMDB, 0xb0, route->input);
+ ks0127_and_or(sd, KS_CMDB, 0xb0, input);
/* non-freerunning mode */
ks0127_and_or(sd, KS_CMDC, 0x70, 0x0a);
/* analog input */
@@ -455,13 +456,13 @@ static int ks0127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *r
case KS_INPUT_SVIDEO_2:
case KS_INPUT_SVIDEO_3:
v4l2_dbg(1, debug, sd,
- "s_routing %d: S-Video\n", route->input);
+ "s_routing %d: S-Video\n", input);
/* autodetect 50/60 Hz */
ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00);
/* VSE=0 */
ks0127_and_or(sd, KS_CMDA, ~0x40, 0x00);
/* set input line */
- ks0127_and_or(sd, KS_CMDB, 0xb0, route->input);
+ ks0127_and_or(sd, KS_CMDB, 0xb0, input);
/* non-freerunning mode */
ks0127_and_or(sd, KS_CMDC, 0x70, 0x0a);
/* analog input */
@@ -496,7 +497,7 @@ static int ks0127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *r
ks0127_and_or(sd, KS_CMDA, 0xff, 0x40); /* VSE=1 */
/* set input line and VALIGN */
- ks0127_and_or(sd, KS_CMDB, 0xb0, (route->input | 0x40));
+ ks0127_and_or(sd, KS_CMDB, 0xb0, (input | 0x40));
/* freerunning mode, */
/* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/
ks0127_and_or(sd, KS_CMDC, 0x70, 0x87);
@@ -531,7 +532,7 @@ static int ks0127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *r
default:
v4l2_dbg(1, debug, sd,
- "s_routing: Unknown input %d\n", route->input);
+ "s_routing: Unknown input %d\n", input);
break;
}
@@ -648,9 +649,6 @@ static int ks0127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_iden
static const struct v4l2_subdev_core_ops ks0127_core_ops = {
.g_chip_ident = ks0127_g_chip_ident,
-};
-
-static const struct v4l2_subdev_tuner_ops ks0127_tuner_ops = {
.s_std = ks0127_s_std,
};
@@ -663,7 +661,6 @@ static const struct v4l2_subdev_video_ops ks0127_video_ops = {
static const struct v4l2_subdev_ops ks0127_ops = {
.core = &ks0127_core_ops,
- .tuner = &ks0127_tuner_ops,
.video = &ks0127_video_ops,
};
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index 1f340fefc49..d7317e798cc 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -69,12 +69,13 @@ static int m52790_write(struct v4l2_subdev *sd)
part of the audio output routing. The normal case is that another
chip takes care of the actual muting so making it part of the
output routing seems to be the right thing to do for now. */
-static int m52790_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int m52790_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct m52790_state *state = to_state(sd);
- state->input = route->input;
- state->output = route->output;
+ state->input = input;
+ state->output = output;
m52790_write(sd);
return 0;
}
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 2ad11f0999c..1d66855a379 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -117,7 +117,7 @@ static int ptable_alloc(void)
memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
/* give only 32 bit DMA addresses */
- if (dma_set_mask(&meye.mchip_dev->dev, DMA_32BIT_MASK))
+ if (dma_set_mask(&meye.mchip_dev->dev, DMA_BIT_MASK(32)))
return -1;
meye.mchip_ptable_toc = dma_alloc_coherent(&meye.mchip_dev->dev,
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 9e8e06cfe5c..e9df3cb02cc 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -56,7 +56,7 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include <media/msp3400.h>
#include <media/tvaudio.h>
#include "msp3400-driver.h"
@@ -108,10 +108,6 @@ MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
/* DSP unit subaddress */
#define I2C_MSP_DSP 0x12
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x80 >> 1, 0x88 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
/* ----------------------------------------------------------------------- */
/* functions for talking to the MSP3400C Sound processor */
@@ -509,25 +505,26 @@ static int msp_s_std(struct v4l2_subdev *sd, v4l2_std_id id)
return 0;
}
-static int msp_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *rt)
+static int msp_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct msp_state *state = to_state(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- int tuner = (rt->input >> 3) & 1;
- int sc_in = rt->input & 0x7;
- int sc1_out = rt->output & 0xf;
- int sc2_out = (rt->output >> 4) & 0xf;
+ int tuner = (input >> 3) & 1;
+ int sc_in = input & 0x7;
+ int sc1_out = output & 0xf;
+ int sc2_out = (output >> 4) & 0xf;
u16 val, reg;
int i;
int extern_input = 1;
- if (state->routing.input == rt->input &&
- state->routing.output == rt->output)
+ if (state->route_in == input && state->route_out == output)
return 0;
- state->routing = *rt;
+ state->route_in = input;
+ state->route_out = output;
/* check if the tuner input is used */
for (i = 0; i < 5; i++) {
- if (((rt->input >> (4 + i * 4)) & 0xf) == 0)
+ if (((input >> (4 + i * 4)) & 0xf) == 0)
extern_input = 0;
}
state->mode = extern_input ? MSP_MODE_EXTERN : MSP_MODE_AM_DETECT;
@@ -677,7 +674,7 @@ static int msp_log_status(struct v4l2_subdev *sd)
}
v4l_info(client, "Audmode: 0x%04x\n", state->audmode);
v4l_info(client, "Routing: 0x%08x (input) 0x%08x (output)\n",
- state->routing.input, state->routing.output);
+ state->route_in, state->route_out);
v4l_info(client, "ACB: 0x%04x\n", state->acb);
return 0;
}
@@ -696,11 +693,6 @@ static int msp_resume(struct i2c_client *client)
return 0;
}
-static int msp_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops msp_core_ops = {
@@ -709,6 +701,7 @@ static const struct v4l2_subdev_core_ops msp_core_ops = {
.g_ctrl = msp_g_ctrl,
.s_ctrl = msp_s_ctrl,
.queryctrl = msp_queryctrl,
+ .s_std = msp_s_std,
};
static const struct v4l2_subdev_tuner_ops msp_tuner_ops = {
@@ -716,7 +709,6 @@ static const struct v4l2_subdev_tuner_ops msp_tuner_ops = {
.g_tuner = msp_g_tuner,
.s_tuner = msp_s_tuner,
.s_radio = msp_s_radio,
- .s_std = msp_s_std,
};
static const struct v4l2_subdev_audio_ops msp_audio_ops = {
@@ -770,8 +762,8 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
state->i2s_mode = 0;
init_waitqueue_head(&state->wq);
/* These are the reset input/output positions */
- state->routing.input = MSP_INPUT_DEFAULT;
- state->routing.output = MSP_OUTPUT_DEFAULT;
+ state->route_in = MSP_INPUT_DEFAULT;
+ state->route_out = MSP_OUTPUT_DEFAULT;
state->rev1 = msp_read_dsp(client, 0x1e);
if (state->rev1 != -1)
@@ -925,8 +917,6 @@ MODULE_DEVICE_TABLE(i2c, msp_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "msp3400",
- .driverid = I2C_DRIVERID_MSP3400,
- .command = msp_command,
.probe = msp_probe,
.remove = msp_remove,
.suspend = msp_suspend,
diff --git a/drivers/media/video/msp3400-driver.h b/drivers/media/video/msp3400-driver.h
index 3fe1c1b10f5..d6b3e6d0eef 100644
--- a/drivers/media/video/msp3400-driver.h
+++ b/drivers/media/video/msp3400-driver.h
@@ -80,7 +80,8 @@ struct msp_state {
int i2s_mode;
int main, second; /* sound carrier */
int input;
- struct v4l2_routing routing;
+ u32 route_in;
+ u32 route_out;
/* v4l2 */
int audmode;
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
index a655e9c3014..168bca70361 100644
--- a/drivers/media/video/msp3400-kthreads.c
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -188,7 +188,7 @@ void msp3400c_set_mode(struct i2c_client *client, int mode)
{
struct msp_state *state = to_state(i2c_get_clientdata(client));
struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
- int tuner = (state->routing.input >> 3) & 1;
+ int tuner = (state->route_in >> 3) & 1;
int i;
v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode);
@@ -896,7 +896,7 @@ static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
static void msp34xxg_set_sources(struct i2c_client *client)
{
struct msp_state *state = to_state(i2c_get_clientdata(client));
- u32 in = state->routing.input;
+ u32 in = state->route_in;
msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf);
/* quasi-peak detector is set to same input as the loudspeaker (MAIN) */
@@ -912,7 +912,7 @@ static void msp34xxg_set_sources(struct i2c_client *client)
static void msp34xxg_reset(struct i2c_client *client)
{
struct msp_state *state = to_state(i2c_get_clientdata(client));
- int tuner = (state->routing.input >> 3) & 1;
+ int tuner = (state->route_in >> 3) & 1;
int modus;
/* initialize std to 1 (autodetect) to signal that no standard is
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index fa7e5093ede..684f62fa789 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -207,7 +207,7 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
/* MT9M001 has all capture_format parameters fixed */
- unsigned long flags = SOCAM_PCLK_SAMPLE_RISING |
+ unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING |
SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER;
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 23f9ce9d67e..2b0927bfd21 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -141,8 +141,19 @@ static int get_shutter(struct soc_camera_device *icd, u32 *data)
static int mt9t031_init(struct soc_camera_device *icd)
{
+ struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+ struct soc_camera_link *icl = mt9t031->client->dev.platform_data;
int ret;
+ if (icl->power) {
+ ret = icl->power(&mt9t031->client->dev, 1);
+ if (ret < 0) {
+ dev_err(icd->vdev->parent,
+ "Platform failed to power-on the camera.\n");
+ return ret;
+ }
+ }
+
/* Disable chip output, synchronous option update */
ret = reg_write(icd, MT9T031_RESET, 1);
if (ret >= 0)
@@ -150,13 +161,23 @@ static int mt9t031_init(struct soc_camera_device *icd)
if (ret >= 0)
ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2);
+ if (ret < 0 && icl->power)
+ icl->power(&mt9t031->client->dev, 0);
+
return ret >= 0 ? 0 : -EIO;
}
static int mt9t031_release(struct soc_camera_device *icd)
{
+ struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+ struct soc_camera_link *icl = mt9t031->client->dev.platform_data;
+
/* Disable the chip */
reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2);
+
+ if (icl->power)
+ icl->power(&mt9t031->client->dev, 0);
+
return 0;
}
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
new file mode 100644
index 00000000000..86fab56c5a2
--- /dev/null
+++ b/drivers/media/video/mx1_camera.c
@@ -0,0 +1,827 @@
+/*
+ * V4L2 Driver for i.MXL/i.MXL camera (CSI) host
+ *
+ * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ * Copyright (C) 2009, Darius Augulis <augulis.darius@gmail.com>
+ *
+ * Based on PXA SoC camera driver
+ * Copyright (C) 2006, Sascha Hauer, Pengutronix
+ * Copyright (C) 2008, Guennadi Liakhovetski <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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/time.h>
+#include <linux/version.h>
+#include <linux/videodev2.h>
+
+#include <media/soc_camera.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-dev.h>
+#include <media/videobuf-dma-contig.h>
+
+#include <asm/dma.h>
+#include <asm/fiq.h>
+#include <mach/dma-mx1-mx2.h>
+#include <mach/hardware.h>
+#include <mach/mx1_camera.h>
+
+/*
+ * CSI registers
+ */
+#define DMA_CCR(x) (0x8c + ((x) << 6)) /* Control Registers */
+#define DMA_DIMR 0x08 /* Interrupt mask Register */
+#define CSICR1 0x00 /* CSI Control Register 1 */
+#define CSISR 0x08 /* CSI Status Register */
+#define CSIRXR 0x10 /* CSI RxFIFO Register */
+
+#define CSICR1_RXFF_LEVEL(x) (((x) & 0x3) << 19)
+#define CSICR1_SOF_POL (1 << 17)
+#define CSICR1_SOF_INTEN (1 << 16)
+#define CSICR1_MCLKDIV(x) (((x) & 0xf) << 12)
+#define CSICR1_MCLKEN (1 << 9)
+#define CSICR1_FCC (1 << 8)
+#define CSICR1_BIG_ENDIAN (1 << 7)
+#define CSICR1_CLR_RXFIFO (1 << 5)
+#define CSICR1_GCLK_MODE (1 << 4)
+#define CSICR1_DATA_POL (1 << 2)
+#define CSICR1_REDGE (1 << 1)
+#define CSICR1_EN (1 << 0)
+
+#define CSISR_SFF_OR_INT (1 << 25)
+#define CSISR_RFF_OR_INT (1 << 24)
+#define CSISR_STATFF_INT (1 << 21)
+#define CSISR_RXFF_INT (1 << 18)
+#define CSISR_SOF_INT (1 << 16)
+#define CSISR_DRDY (1 << 0)
+
+#define VERSION_CODE KERNEL_VERSION(0, 0, 1)
+#define DRIVER_NAME "mx1-camera"
+
+#define CSI_IRQ_MASK (CSISR_SFF_OR_INT | CSISR_RFF_OR_INT | \
+ CSISR_STATFF_INT | CSISR_RXFF_INT | CSISR_SOF_INT)
+
+#define CSI_BUS_FLAGS (SOCAM_MASTER | SOCAM_HSYNC_ACTIVE_HIGH | \
+ SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW | \
+ SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | \
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_LOW | \
+ SOCAM_DATAWIDTH_8)
+
+#define MAX_VIDEO_MEM 16 /* Video memory limit in megabytes */
+
+/*
+ * Structures
+ */
+
+/* buffer for one video frame */
+struct mx1_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct videobuf_buffer vb;
+ const struct soc_camera_data_format *fmt;
+ int inwork;
+};
+
+/* i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor
+ * Interface. If anyone ever builds hardware to enable more than
+ * one camera, they will have to modify this driver too */
+struct mx1_camera_dev {
+ struct soc_camera_device *icd;
+ struct mx1_camera_pdata *pdata;
+ struct mx1_buffer *active;
+ struct device *dev;
+ struct resource *res;
+ struct clk *clk;
+ struct list_head capture;
+
+ void __iomem *base;
+ int dma_chan;
+ unsigned int irq;
+ unsigned long mclk;
+
+ spinlock_t lock;
+};
+
+/*
+ * Videobuf operations
+ */
+static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
+ unsigned int *size)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+
+ *size = icd->width * icd->height *
+ ((icd->current_fmt->depth + 7) >> 3);
+
+ if (!*count)
+ *count = 32;
+
+ while (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
+ (*count)--;
+
+ dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
+
+ return 0;
+}
+
+static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct videobuf_buffer *vb = &buf->vb;
+
+ BUG_ON(in_interrupt());
+
+ dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+ vb, vb->baddr, vb->bsize);
+
+ /* This waits until this buffer is out of danger, i.e., until it is no
+ * longer in STATE_QUEUED or STATE_ACTIVE */
+ videobuf_waiton(vb, 0, 0);
+ videobuf_dma_contig_free(vq, vb);
+
+ vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int mx1_videobuf_prepare(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb, enum v4l2_field field)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
+ int ret;
+
+ dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+ vb, vb->baddr, vb->bsize);
+
+ /* Added list head initialization on alloc */
+ WARN_ON(!list_empty(&vb->queue));
+
+ BUG_ON(NULL == icd->current_fmt);
+
+ /* I think, in buf_prepare you only have to protect global data,
+ * the actual buffer is yours */
+ buf->inwork = 1;
+
+ if (buf->fmt != icd->current_fmt ||
+ vb->width != icd->width ||
+ vb->height != icd->height ||
+ vb->field != field) {
+ buf->fmt = icd->current_fmt;
+ vb->width = icd->width;
+ vb->height = icd->height;
+ vb->field = field;
+ vb->state = VIDEOBUF_NEEDS_INIT;
+ }
+
+ vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3);
+ if (0 != vb->baddr && vb->bsize < vb->size) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (vb->state == VIDEOBUF_NEEDS_INIT) {
+ ret = videobuf_iolock(vq, vb, NULL);
+ if (ret)
+ goto fail;
+
+ vb->state = VIDEOBUF_PREPARED;
+ }
+
+ buf->inwork = 0;
+
+ return 0;
+
+fail:
+ free_buffer(vq, buf);
+out:
+ buf->inwork = 0;
+ return ret;
+}
+
+static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
+{
+ struct videobuf_buffer *vbuf = &pcdev->active->vb;
+ int ret;
+
+ if (unlikely(!pcdev->active)) {
+ dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n");
+ return -EFAULT;
+ }
+
+ /* setup sg list for future DMA */
+ ret = imx_dma_setup_single(pcdev->dma_chan,
+ videobuf_to_dma_contig(vbuf),
+ vbuf->size, pcdev->res->start +
+ CSIRXR, DMA_MODE_READ);
+ if (unlikely(ret))
+ dev_err(pcdev->dev, "Failed to setup DMA sg list\n");
+
+ return ret;
+}
+
+static void mx1_videobuf_queue(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx1_camera_dev *pcdev = ici->priv;
+ struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
+ unsigned long flags;
+
+ dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+ vb, vb->baddr, vb->bsize);
+
+ spin_lock_irqsave(&pcdev->lock, flags);
+
+ list_add_tail(&vb->queue, &pcdev->capture);
+
+ vb->state = VIDEOBUF_ACTIVE;
+
+ if (!pcdev->active) {
+ pcdev->active = buf;
+
+ /* setup sg list for future DMA */
+ if (!mx1_camera_setup_dma(pcdev)) {
+ unsigned int temp;
+ /* enable SOF irq */
+ temp = __raw_readl(pcdev->base + CSICR1) |
+ CSICR1_SOF_INTEN;
+ __raw_writel(temp, pcdev->base + CSICR1);
+ }
+ }
+
+ spin_unlock_irqrestore(&pcdev->lock, flags);
+}
+
+static void mx1_videobuf_release(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
+#ifdef DEBUG
+ struct soc_camera_device *icd = vq->priv_data;
+
+ dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+ vb, vb->baddr, vb->bsize);
+
+ switch (vb->state) {
+ case VIDEOBUF_ACTIVE:
+ dev_dbg(&icd->dev, "%s (active)\n", __func__);
+ break;
+ case VIDEOBUF_QUEUED:
+ dev_dbg(&icd->dev, "%s (queued)\n", __func__);
+ break;
+ case VIDEOBUF_PREPARED:
+ dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
+ break;
+ default:
+ dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
+ break;
+ }
+#endif
+
+ free_buffer(vq, buf);
+}
+
+static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev,
+ struct videobuf_buffer *vb,
+ struct mx1_buffer *buf)
+{
+ /* _init is used to debug races, see comment in mx1_camera_reqbufs() */
+ list_del_init(&vb->queue);
+ vb->state = VIDEOBUF_DONE;
+ do_gettimeofday(&vb->ts);
+ vb->field_count++;
+ wake_up(&vb->done);
+
+ if (list_empty(&pcdev->capture)) {
+ pcdev->active = NULL;
+ return;
+ }
+
+ pcdev->active = list_entry(pcdev->capture.next,
+ struct mx1_buffer, vb.queue);
+
+ /* setup sg list for future DMA */
+ if (likely(!mx1_camera_setup_dma(pcdev))) {
+ unsigned int temp;
+
+ /* enable SOF irq */
+ temp = __raw_readl(pcdev->base + CSICR1) | CSICR1_SOF_INTEN;
+ __raw_writel(temp, pcdev->base + CSICR1);
+ }
+}
+
+static void mx1_camera_dma_irq(int channel, void *data)
+{
+ struct mx1_camera_dev *pcdev = data;
+ struct mx1_buffer *buf;
+ struct videobuf_buffer *vb;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pcdev->lock, flags);
+
+ imx_dma_disable(channel);
+
+ if (unlikely(!pcdev->active)) {
+ dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n");
+ goto out;
+ }
+
+ vb = &pcdev->active->vb;
+ buf = container_of(vb, struct mx1_buffer, vb);
+ WARN_ON(buf->inwork || list_empty(&vb->queue));
+ dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+ vb, vb->baddr, vb->bsize);
+
+ mx1_camera_wakeup(pcdev, vb, buf);
+out:
+ spin_unlock_irqrestore(&pcdev->lock, flags);
+}
+
+static struct videobuf_queue_ops mx1_videobuf_ops = {
+ .buf_setup = mx1_videobuf_setup,
+ .buf_prepare = mx1_videobuf_prepare,
+ .buf_queue = mx1_videobuf_queue,
+ .buf_release = mx1_videobuf_release,
+};
+
+static void mx1_camera_init_videobuf(struct videobuf_queue *q,
+ struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx1_camera_dev *pcdev = ici->priv;
+
+ videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, pcdev->dev,
+ &pcdev->lock,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ V4L2_FIELD_NONE,
+ sizeof(struct mx1_buffer), icd);
+}
+
+static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
+{
+ unsigned int mclk = pcdev->mclk;
+ unsigned long div;
+ unsigned long lcdclk;
+
+ lcdclk = clk_get_rate(pcdev->clk);
+
+ /* We verify platform_mclk_10khz != 0, so if anyone breaks it, here
+ * they get a nice Oops */
+ div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
+
+ dev_dbg(pcdev->dev, "System clock %lukHz, target freq %dkHz, "
+ "divisor %lu\n", lcdclk / 1000, mclk / 1000, div);
+
+ return div;
+}
+
+static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
+{
+ unsigned int csicr1 = CSICR1_EN;
+
+ dev_dbg(pcdev->dev, "Activate device\n");
+
+ clk_enable(pcdev->clk);
+
+ /* enable CSI before doing anything else */
+ __raw_writel(csicr1, pcdev->base + CSICR1);
+
+ csicr1 |= CSICR1_MCLKEN | CSICR1_FCC | CSICR1_GCLK_MODE;
+ csicr1 |= CSICR1_MCLKDIV(mclk_get_divisor(pcdev));
+ csicr1 |= CSICR1_RXFF_LEVEL(2); /* 16 words */
+
+ __raw_writel(csicr1, pcdev->base + CSICR1);
+}
+
+static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
+{
+ dev_dbg(pcdev->dev, "Deactivate device\n");
+
+ /* Disable all CSI interface */
+ __raw_writel(0x00, pcdev->base + CSICR1);
+
+ clk_disable(pcdev->clk);
+}
+
+/* The following two functions absolutely depend on the fact, that
+ * there can be only one camera on i.MX1/i.MXL camera sensor interface */
+static int mx1_camera_add_device(struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx1_camera_dev *pcdev = ici->priv;
+ int ret;
+
+ if (pcdev->icd) {
+ ret = -EBUSY;
+ goto ebusy;
+ }
+
+ dev_info(&icd->dev, "MX1 Camera driver attached to camera %d\n",
+ icd->devnum);
+
+ mx1_camera_activate(pcdev);
+ ret = icd->ops->init(icd);
+
+ if (!ret)
+ pcdev->icd = icd;
+
+ebusy:
+ return ret;
+}
+
+static void mx1_camera_remove_device(struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx1_camera_dev *pcdev = ici->priv;
+ unsigned int csicr1;
+
+ BUG_ON(icd != pcdev->icd);
+
+ /* disable interrupts */
+ csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK;
+ __raw_writel(csicr1, pcdev->base + CSICR1);
+
+ /* Stop DMA engine */
+ imx_dma_disable(pcdev->dma_chan);
+
+ dev_info(&icd->dev, "MX1 Camera driver detached from camera %d\n",
+ icd->devnum);
+
+ icd->ops->release(icd);
+
+ mx1_camera_deactivate(pcdev);
+
+ pcdev->icd = NULL;
+}
+
+static int mx1_camera_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ return icd->ops->set_crop(icd, rect);
+}
+
+static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx1_camera_dev *pcdev = ici->priv;
+ unsigned long camera_flags, common_flags;
+ unsigned int csicr1;
+ int ret;
+
+ camera_flags = icd->ops->query_bus_param(icd);
+
+ /* MX1 supports only 8bit buswidth */
+ common_flags = soc_camera_bus_param_compatible(camera_flags,
+ CSI_BUS_FLAGS);
+ if (!common_flags)
+ return -EINVAL;
+
+ icd->buswidth = 8;
+
+ /* Make choises, based on platform choice */
+ if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
+ (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
+ if (!pcdev->pdata ||
+ pcdev->pdata->flags & MX1_CAMERA_VSYNC_HIGH)
+ common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
+ else
+ common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
+ }
+
+ if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
+ (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
+ if (!pcdev->pdata ||
+ pcdev->pdata->flags & MX1_CAMERA_PCLK_RISING)
+ common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
+ else
+ common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
+ }
+
+ if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) &&
+ (common_flags & SOCAM_DATA_ACTIVE_LOW)) {
+ if (!pcdev->pdata ||
+ pcdev->pdata->flags & MX1_CAMERA_DATA_HIGH)
+ common_flags &= ~SOCAM_DATA_ACTIVE_LOW;
+ else
+ common_flags &= ~SOCAM_DATA_ACTIVE_HIGH;
+ }
+
+ ret = icd->ops->set_bus_param(icd, common_flags);
+ if (ret < 0)
+ return ret;
+
+ csicr1 = __raw_readl(pcdev->base + CSICR1);
+
+ if (common_flags & SOCAM_PCLK_SAMPLE_RISING)
+ csicr1 |= CSICR1_REDGE;
+ if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH)
+ csicr1 |= CSICR1_SOF_POL;
+ if (common_flags & SOCAM_DATA_ACTIVE_LOW)
+ csicr1 |= CSICR1_DATA_POL;
+
+ __raw_writel(csicr1, pcdev->base + CSICR1);
+
+ return 0;
+}
+
+static int mx1_camera_set_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ const struct soc_camera_format_xlate *xlate;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ int ret;
+
+ xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
+ if (!xlate) {
+ dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+ return -EINVAL;
+ }
+
+ ret = icd->ops->set_fmt(icd, f);
+ if (!ret) {
+ icd->buswidth = xlate->buswidth;
+ icd->current_fmt = xlate->host_fmt;
+ }
+
+ return ret;
+}
+
+static int mx1_camera_try_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ /* TODO: limit to mx1 hardware capabilities */
+
+ /* limit to sensor capabilities */
+ return icd->ops->try_fmt(icd, f);
+}
+
+static int mx1_camera_reqbufs(struct soc_camera_file *icf,
+ struct v4l2_requestbuffers *p)
+{
+ int i;
+
+ /* This is for locking debugging only. I removed spinlocks and now I
+ * check whether .prepare is ever called on a linked buffer, or whether
+ * a dma IRQ can occur for an in-work or unlinked buffer. Until now
+ * it hadn't triggered */
+ for (i = 0; i < p->count; i++) {
+ struct mx1_buffer *buf = container_of(icf->vb_vidq.bufs[i],
+ struct mx1_buffer, vb);
+ buf->inwork = 0;
+ INIT_LIST_HEAD(&buf->vb.queue);
+ }
+
+ return 0;
+}
+
+static unsigned int mx1_camera_poll(struct file *file, poll_table *pt)
+{
+ struct soc_camera_file *icf = file->private_data;
+ struct mx1_buffer *buf;
+
+ buf = list_entry(icf->vb_vidq.stream.next, struct mx1_buffer,
+ vb.stream);
+
+ poll_wait(file, &buf->vb.done, pt);
+
+ if (buf->vb.state == VIDEOBUF_DONE ||
+ buf->vb.state == VIDEOBUF_ERROR)
+ return POLLIN | POLLRDNORM;
+
+ return 0;
+}
+
+static int mx1_camera_querycap(struct soc_camera_host *ici,
+ struct v4l2_capability *cap)
+{
+ /* cap->name is set by the friendly caller:-> */
+ strlcpy(cap->card, "i.MX1/i.MXL Camera", sizeof(cap->card));
+ cap->version = VERSION_CODE;
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+
+ return 0;
+}
+
+static struct soc_camera_host_ops mx1_soc_camera_host_ops = {
+ .owner = THIS_MODULE,
+ .add = mx1_camera_add_device,
+ .remove = mx1_camera_remove_device,
+ .set_bus_param = mx1_camera_set_bus_param,
+ .set_crop = mx1_camera_set_crop,
+ .set_fmt = mx1_camera_set_fmt,
+ .try_fmt = mx1_camera_try_fmt,
+ .init_videobuf = mx1_camera_init_videobuf,
+ .reqbufs = mx1_camera_reqbufs,
+ .poll = mx1_camera_poll,
+ .querycap = mx1_camera_querycap,
+};
+
+/* Should be allocated dynamically too, but we have only one. */
+static struct soc_camera_host mx1_soc_camera_host = {
+ .drv_name = DRIVER_NAME,
+ .ops = &mx1_soc_camera_host_ops,
+};
+
+static struct fiq_handler fh = {
+ .name = "csi_sof"
+};
+
+static int __init mx1_camera_probe(struct platform_device *pdev)
+{
+ struct mx1_camera_dev *pcdev;
+ struct resource *res;
+ struct pt_regs regs;
+ struct clk *clk;
+ void __iomem *base;
+ unsigned int irq;
+ int err = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!res || !irq) {
+ err = -ENODEV;
+ goto exit;
+ }
+
+ clk = clk_get(&pdev->dev, "csi_clk");
+ if (IS_ERR(clk)) {
+ err = PTR_ERR(clk);
+ goto exit;
+ }
+
+ pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
+ if (!pcdev) {
+ dev_err(&pdev->dev, "Could not allocate pcdev\n");
+ err = -ENOMEM;
+ goto exit_put_clk;
+ }
+
+ dev_set_drvdata(&pdev->dev, pcdev);
+ pcdev->res = res;
+ pcdev->clk = clk;
+
+ pcdev->pdata = pdev->dev.platform_data;
+
+ if (pcdev->pdata)
+ pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
+
+ if (!pcdev->mclk) {
+ dev_warn(&pdev->dev,
+ "mclk_10khz == 0! Please, fix your platform data. "
+ "Using default 20MHz\n");
+ pcdev->mclk = 20000000;
+ }
+
+ INIT_LIST_HEAD(&pcdev->capture);
+ spin_lock_init(&pcdev->lock);
+
+ /*
+ * Request the regions.
+ */
+ if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) {
+ err = -EBUSY;
+ goto exit_kfree;
+ }
+
+ base = ioremap(res->start, resource_size(res));
+ if (!base) {
+ err = -ENOMEM;
+ goto exit_release;
+ }
+ pcdev->irq = irq;
+ pcdev->base = base;
+ pcdev->dev = &pdev->dev;
+
+ /* request dma */
+ pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH);
+ if (pcdev->dma_chan < 0) {
+ dev_err(pcdev->dev, "Can't request DMA for MX1 CSI\n");
+ err = -EBUSY;
+ goto exit_iounmap;
+ }
+ dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chan);
+
+ imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL,
+ pcdev);
+
+ imx_dma_config_channel(pcdev->dma_chan, IMX_DMA_TYPE_FIFO,
+ IMX_DMA_MEMSIZE_32, DMA_REQ_CSI_R, 0);
+ /* burst length : 16 words = 64 bytes */
+ imx_dma_config_burstlen(pcdev->dma_chan, 0);
+
+ /* request irq */
+ err = claim_fiq(&fh);
+ if (err) {
+ dev_err(pcdev->dev, "Camera interrupt register failed \n");
+ goto exit_free_dma;
+ }
+
+ set_fiq_handler(&mx1_camera_sof_fiq_start, &mx1_camera_sof_fiq_end -
+ &mx1_camera_sof_fiq_start);
+
+ regs.ARM_r8 = DMA_BASE + DMA_DIMR;
+ regs.ARM_r9 = DMA_BASE + DMA_CCR(pcdev->dma_chan);
+ regs.ARM_r10 = (long)pcdev->base + CSICR1;
+ regs.ARM_fp = (long)pcdev->base + CSISR;
+ regs.ARM_sp = 1 << pcdev->dma_chan;
+ set_fiq_regs(&regs);
+
+ mxc_set_irq_fiq(irq, 1);
+ enable_fiq(irq);
+
+ mx1_soc_camera_host.priv = pcdev;
+ mx1_soc_camera_host.dev.parent = &pdev->dev;
+ mx1_soc_camera_host.nr = pdev->id;
+ err = soc_camera_host_register(&mx1_soc_camera_host);
+ if (err)
+ goto exit_free_irq;
+
+ dev_info(&pdev->dev, "MX1 Camera driver loaded\n");
+
+ return 0;
+
+exit_free_irq:
+ disable_fiq(irq);
+ mxc_set_irq_fiq(irq, 0);
+ release_fiq(&fh);
+exit_free_dma:
+ imx_dma_free(pcdev->dma_chan);
+exit_iounmap:
+ iounmap(base);
+exit_release:
+ release_mem_region(res->start, resource_size(res));
+exit_kfree:
+ kfree(pcdev);
+exit_put_clk:
+ clk_put(clk);
+exit:
+ return err;
+}
+
+static int __exit mx1_camera_remove(struct platform_device *pdev)
+{
+ struct mx1_camera_dev *pcdev = platform_get_drvdata(pdev);
+ struct resource *res;
+
+ imx_dma_free(pcdev->dma_chan);
+ disable_fiq(pcdev->irq);
+ mxc_set_irq_fiq(pcdev->irq, 0);
+ release_fiq(&fh);
+
+ clk_put(pcdev->clk);
+
+ soc_camera_host_unregister(&mx1_soc_camera_host);
+
+ iounmap(pcdev->base);
+
+ res = pcdev->res;
+ release_mem_region(res->start, resource_size(res));
+
+ kfree(pcdev);
+
+ dev_info(&pdev->dev, "MX1 Camera driver unloaded\n");
+
+ return 0;
+}
+
+static struct platform_driver mx1_camera_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ },
+ .remove = __exit_p(mx1_camera_remove),
+};
+
+static int __init mx1_camera_init(void)
+{
+ return platform_driver_probe(&mx1_camera_driver, mx1_camera_probe);
+}
+
+static void __exit mx1_camera_exit(void)
+{
+ return platform_driver_unregister(&mx1_camera_driver);
+}
+
+module_init(mx1_camera_init);
+module_exit(mx1_camera_exit);
+
+MODULE_DESCRIPTION("i.MX1/i.MXL SoC Camera Host driver");
+MODULE_AUTHOR("Paulius Zaleckas <paulius.zaleckas@teltonika.lt>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 70629e172e6..c462b811e99 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -1100,7 +1100,7 @@ static int mx3_camera_probe(struct platform_device *pdev)
}
memset(mx3_cam, 0, sizeof(*mx3_cam));
- mx3_cam->clk = clk_get(&pdev->dev, "csi_clk");
+ mx3_cam->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(mx3_cam->clk)) {
err = PTR_ERR(mx3_cam->clk);
goto eclkget;
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index 84aec62e845..3be5a71bdac 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -83,9 +83,14 @@ static struct {
static int video_audio_connect[MXB_INPUTS] =
{ 0, 1, 3, 3 };
+struct mxb_routing {
+ u32 input;
+ u32 output;
+};
+
/* These are the necessary input-output-pins for bringing one audio source
(see above) to the CD-output. Note that gain is set to 0 in this table. */
-static struct v4l2_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
+static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
{ { 1, 1 }, { 1, 1 } }, /* Tuner */
{ { 5, 1 }, { 6, 1 } }, /* AUX 1 */
{ { 4, 1 }, { 6, 1 } }, /* AUX 2 */
@@ -97,7 +102,7 @@ static struct v4l2_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
/* These are the necessary input-output-pins for bringing one audio source
(see above) to the line-output. Note that gain is set to 0 in this table. */
-static struct v4l2_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
+static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
{ { 2, 3 }, { 1, 2 } },
{ { 5, 3 }, { 6, 2 } },
{ { 4, 3 }, { 6, 2 } },
@@ -134,10 +139,6 @@ struct mxb
#define saa7111a_call(mxb, o, f, args...) \
v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
-#define tea6420_1_call(mxb, o, f, args...) \
- v4l2_subdev_call(mxb->tea6420_1, o, f, ##args)
-#define tea6420_2_call(mxb, o, f, args...) \
- v4l2_subdev_call(mxb->tea6420_2, o, f, ##args)
#define tda9840_call(mxb, o, f, args...) \
v4l2_subdev_call(mxb->tda9840, o, f, ##args)
#define tea6415c_call(mxb, o, f, args...) \
@@ -147,6 +148,22 @@ struct mxb
#define call_all(dev, o, f, args...) \
v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
+static inline void tea6420_route_cd(struct mxb *mxb, int idx)
+{
+ v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
+ TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0);
+ v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
+ TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0);
+}
+
+static inline void tea6420_route_line(struct mxb *mxb, int idx)
+{
+ v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
+ TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0);
+ v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
+ TEA6420_line[idx][1].input, TEA6420_line[idx][1].output, 0);
+}
+
static struct saa7146_extension extension;
static int mxb_probe(struct saa7146_dev *dev)
@@ -168,13 +185,20 @@ static int mxb_probe(struct saa7146_dev *dev)
return -EFAULT;
}
- mxb->saa7111a = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "saa7115", "saa7111", I2C_SAA7111A);
- mxb->tea6420_1 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6420", "tea6420", I2C_TEA6420_1);
- mxb->tea6420_2 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6420", "tea6420", I2C_TEA6420_2);
- mxb->tea6415c = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6415c", "tea6415c", I2C_TEA6415C);
- mxb->tda9840 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tda9840", "tda9840", I2C_TDA9840);
- mxb->tuner = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tuner", "tuner", I2C_TUNER);
- if (v4l2_i2c_new_subdev(&mxb->i2c_adapter, "saa5246a", "saa5246a", I2C_SAA5246A)) {
+ mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+ "saa7115", "saa7111", I2C_SAA7111A);
+ mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+ "tea6420", "tea6420", I2C_TEA6420_1);
+ mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+ "tea6420", "tea6420", I2C_TEA6420_2);
+ mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+ "tea6415c", "tea6415c", I2C_TEA6415C);
+ mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+ "tda9840", "tda9840", I2C_TDA9840);
+ mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+ "tuner", "tuner", I2C_TUNER);
+ if (v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+ "saa5246a", "saa5246a", I2C_SAA5246A)) {
printk(KERN_INFO "mxb: found teletext decoder\n");
}
@@ -261,18 +285,16 @@ static int mxb_init_done(struct saa7146_dev* dev)
struct i2c_msg msg;
struct tuner_setup tun_setup;
v4l2_std_id std = V4L2_STD_PAL_BG;
- struct v4l2_routing route;
int i = 0, err = 0;
/* select video mode in saa7111a */
- saa7111a_call(mxb, tuner, s_std, std);
+ saa7111a_call(mxb, core, s_std, std);
/* select tuner-output on saa7111a */
i = 0;
- route.input = SAA7115_COMPOSITE0;
- route.output = SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS;
- saa7111a_call(mxb, video, s_routing, &route);
+ saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
+ SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS, 0);
/* select a tuner type */
tun_setup.mode_mask = T_ANALOG_TV;
@@ -286,23 +308,17 @@ static int mxb_init_done(struct saa7146_dev* dev)
tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
/* set a default video standard */
- tuner_call(mxb, tuner, s_std, std);
+ tuner_call(mxb, core, s_std, std);
/* mute audio on tea6420s */
- tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]);
- tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]);
- tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]);
- tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]);
+ tea6420_route_line(mxb, 6);
+ tea6420_route_cd(mxb, 6);
/* switch to tuner-channel on tea6415c */
- route.input = 3;
- route.output = 17;
- tea6415c_call(mxb, video, s_routing, &route);
+ tea6415c_call(mxb, video, s_routing, 3, 17, 0);
/* select tuner-output on multicable on tea6415c */
- route.input = 3;
- route.output = 13;
- tea6415c_call(mxb, video, s_routing, &route);
+ tea6415c_call(mxb, video, s_routing, 3, 13, 0);
/* the rest for mxb */
mxb->cur_input = 0;
@@ -426,18 +442,9 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
if (vc->id == V4L2_CID_AUDIO_MUTE) {
mxb->cur_mute = vc->value;
- if (!vc->value) {
- /* switch the audio-source */
- tea6420_1_call(mxb, audio, s_routing,
- &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
- tea6420_2_call(mxb, audio, s_routing,
- &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
- } else {
- tea6420_1_call(mxb, audio, s_routing,
- &TEA6420_line[6][0]);
- tea6420_2_call(mxb, audio, s_routing,
- &TEA6420_line[6][1]);
- }
+ /* switch the audio-source */
+ tea6420_route_line(mxb, vc->value ? 6 :
+ video_audio_connect[mxb->cur_input]);
DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
}
return 0;
@@ -466,7 +473,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
{
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct mxb *mxb = (struct mxb *)dev->ext_priv;
- struct v4l2_routing route;
+ int err = 0;
int i = 0;
DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
@@ -484,16 +491,12 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
switch (input) {
case TUNER:
i = SAA7115_COMPOSITE0;
- route.input = 3;
- route.output = 17;
- if (tea6415c_call(mxb, video, s_routing, &route)) {
- printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
- return -EFAULT;
- }
+ err = tea6415c_call(mxb, video, s_routing, 3, 17, 0);
+
/* connect tuner-output always to multicable */
- route.input = 3;
- route.output = 13;
+ if (!err)
+ err = tea6415c_call(mxb, video, s_routing, 3, 13, 0);
break;
case AUX3_YC:
/* nothing to be done here. aux3_yc is
@@ -507,37 +510,20 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
break;
case AUX1:
i = SAA7115_COMPOSITE0;
- route.input = 1;
- route.output = 17;
+ err = tea6415c_call(mxb, video, s_routing, 1, 17, 0);
break;
}
- /* switch video in tea6415c only if necessary */
- switch (input) {
- case TUNER:
- case AUX1:
- if (tea6415c_call(mxb, video, s_routing, &route)) {
- printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
- return -EFAULT;
- }
- break;
- default:
- break;
- }
+ if (err)
+ return err;
/* switch video in saa7111a */
- route.input = i;
- route.output = 0;
- if (saa7111a_call(mxb, video, s_routing, &route))
+ if (saa7111a_call(mxb, video, s_routing, i, 0, 0))
printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n");
/* switch the audio-source only if necessary */
- if (0 == mxb->cur_mute) {
- tea6420_1_call(mxb, audio, s_routing,
- &TEA6420_line[video_audio_connect[input]][0]);
- tea6420_2_call(mxb, audio, s_routing,
- &TEA6420_line[video_audio_connect[input]][1]);
- }
+ if (0 == mxb->cur_mute)
+ tea6420_route_line(mxb, video_audio_connect[input]);
return 0;
}
@@ -679,9 +665,7 @@ static long vidioc_default(struct file *file, void *fh, int cmd, void *arg)
DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i));
- tea6420_1_call(mxb, audio, s_routing, &TEA6420_cd[i][0]);
- tea6420_2_call(mxb, audio, s_routing, &TEA6420_cd[i][1]);
-
+ tea6420_route_cd(mxb, i);
return 0;
}
case MXB_S_AUDIO_LINE:
@@ -694,9 +678,7 @@ static long vidioc_default(struct file *file, void *fh, int cmd, void *arg)
}
DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i));
- tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[i][0]);
- tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[i][1]);
-
+ tea6420_route_line(mxb, i);
return 0;
}
default:
@@ -788,7 +770,7 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
saa7146_write(dev, GPIO_CTRL, 0x00404050);
/* unset the 7111 gpio register -- I don't know what this does exactly */
saa7111a_call(mxb, core, s_gpio, 0);
- tuner_call(mxb, tuner, s_std, std);
+ tuner_call(mxb, core, s_std, std);
} else {
v4l2_std_id std = V4L2_STD_PAL_BG;
@@ -797,7 +779,7 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
saa7146_write(dev, GPIO_CTRL, 0x00404050);
/* set the 7111 gpio register -- I don't know what this does exactly */
saa7111a_call(mxb, core, s_gpio, 1);
- tuner_call(mxb, tuner, s_std, std);
+ tuner_call(mxb, core, s_std, std);
}
return 0;
}
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 84b0fc1bb23..c0d91125286 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -169,11 +169,11 @@
#define GAM15 0x8C /* Gamma Curve 15th segment input end point */
#define SLOP 0x8D /* Gamma curve highest segment slope */
#define DNSTH 0x8E /* De-noise threshold */
-#define EDGE0 0x8F /* Edge enhancement control 0 */
-#define EDGE1 0x90 /* Edge enhancement control 1 */
+#define EDGE_STRNGT 0x8F /* Edge strength control when manual mode */
+#define EDGE_TRSHLD 0x90 /* Edge threshold control when manual mode */
#define DNSOFF 0x91 /* Auto De-noise threshold control */
-#define EDGE2 0x92 /* Edge enhancement strength low point control */
-#define EDGE3 0x93 /* Edge enhancement strength high point control */
+#define EDGE_UPPER 0x92 /* Edge strength upper limit when Auto mode */
+#define EDGE_LOWER 0x93 /* Edge strength lower limit when Auto mode */
#define MTX1 0x94 /* Matrix coefficient 1 */
#define MTX2 0x95 /* Matrix coefficient 2 */
#define MTX3 0x96 /* Matrix coefficient 3 */
@@ -358,6 +358,14 @@
#define VOSZ_VGA 0xF0
#define VOSZ_QVGA 0x78
+/* DSPAUTO (DSP Auto Function ON/OFF Control) */
+#define AWB_ACTRL 0x80 /* AWB auto threshold control */
+#define DENOISE_ACTRL 0x40 /* De-noise auto threshold control */
+#define EDGE_ACTRL 0x20 /* Edge enhancement auto strength control */
+#define UV_ACTRL 0x10 /* UV adjust auto slope control */
+#define SCAL0_ACTRL 0x08 /* Auto scaling factor control */
+#define SCAL1_2_ACTRL 0x04 /* Auto scaling factor control */
+
/*
* ID
*/
@@ -670,7 +678,7 @@ static int ov772x_set_bus_param(struct soc_camera_device *icd,
static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
{
struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
- struct soc_camera_link *icl = priv->client->dev.platform_data;
+ struct soc_camera_link *icl = &priv->info->link;
unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
@@ -816,6 +824,53 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
ov772x_reset(priv->client);
/*
+ * Edge Ctrl
+ */
+ if (priv->info->edgectrl.strength & OV772X_MANUAL_EDGE_CTRL) {
+
+ /*
+ * Manual Edge Control Mode
+ *
+ * Edge auto strength bit is set by default.
+ * Remove it when manual mode.
+ */
+
+ ret = ov772x_mask_set(priv->client, DSPAUTO, EDGE_ACTRL, 0x00);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ ret = ov772x_mask_set(priv->client,
+ EDGE_TRSHLD, EDGE_THRESHOLD_MASK,
+ priv->info->edgectrl.threshold);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ ret = ov772x_mask_set(priv->client,
+ EDGE_STRNGT, EDGE_STRENGTH_MASK,
+ priv->info->edgectrl.strength);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ } else if (priv->info->edgectrl.upper > priv->info->edgectrl.lower) {
+ /*
+ * Auto Edge Control Mode
+ *
+ * set upper and lower limit
+ */
+ ret = ov772x_mask_set(priv->client,
+ EDGE_UPPER, EDGE_UPPER_MASK,
+ priv->info->edgectrl.upper);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ ret = ov772x_mask_set(priv->client,
+ EDGE_LOWER, EDGE_LOWER_MASK,
+ priv->info->edgectrl.lower);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+ }
+
+ /*
* set size format
*/
ret = ov772x_write_array(priv->client, priv->win->regs);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index ccf2a3c7ad0..10ef1a2c13e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -58,9 +58,9 @@ static const struct routing_scheme routing_schemes[] = {
void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
if (hdw->input_dirty || hdw->force_dirty) {
- struct v4l2_routing route;
const struct routing_scheme *sp;
unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+ u32 input;
pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo");
@@ -68,7 +68,7 @@ void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
((sp = routing_schemes + sid) != NULL) &&
(hdw->input_val >= 0) &&
(hdw->input_val < sp->cnt)) {
- route.input = sp->def[hdw->input_val];
+ input = sp->def[hdw->input_val];
} else {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
"*** WARNING *** subdev msp3400 set_input:"
@@ -77,8 +77,8 @@ void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
sid, hdw->input_val);
return;
}
- route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
- sd->ops->audio->s_routing(sd, &route);
+ sd->ops->audio->s_routing(sd, input,
+ MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
}
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
index b5c3428ebb9..9023adf3fdc 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
@@ -60,16 +60,16 @@ static const struct routing_scheme routing_schemes[] = {
void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
if (hdw->input_dirty || hdw->force_dirty) {
- struct v4l2_routing route;
const struct routing_scheme *sp;
unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+ u32 input;
pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
hdw->input_val);
if ((sid < ARRAY_SIZE(routing_schemes)) &&
((sp = routing_schemes + sid) != NULL) &&
(hdw->input_val >= 0) &&
(hdw->input_val < sp->cnt)) {
- route.input = sp->def[hdw->input_val];
+ input = sp->def[hdw->input_val];
} else {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
"*** WARNING *** subdev v4l2 set_input:"
@@ -78,8 +78,7 @@ void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
sid, hdw->input_val);
return;
}
- route.output = 0;
- sd->ops->audio->s_routing(sd, &route);
+ sd->ops->audio->s_routing(sd, input, 0, 0);
}
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
index 203f54cd18a..1b992b84719 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
@@ -137,14 +137,12 @@ int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr)
int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr, int *valptr)
{
int ret = 0;
- if (!cptr) return 0;
+ if (!cptr) return -EINVAL;
LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->type == pvr2_ctl_int) {
- if (cptr->info->get_def_value) {
- ret = cptr->info->get_def_value(cptr, valptr);
- } else {
- *valptr = cptr->info->default_value;
- }
+ if (cptr->info->get_def_value) {
+ ret = cptr->info->get_def_value(cptr, valptr);
+ } else {
+ *valptr = cptr->info->default_value;
}
} while(0); LOCK_GIVE(cptr->hdw->big_lock);
return ret;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 4e017ff26c3..05e52358ae4 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -105,14 +105,11 @@ void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update...");
if (hdw->input_dirty || hdw->force_dirty) {
- struct v4l2_routing route;
enum cx25840_video_input vid_input;
enum cx25840_audio_input aud_input;
const struct routing_scheme *sp;
unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
- memset(&route, 0, sizeof(route));
-
if ((sid < ARRAY_SIZE(routing_schemes)) &&
((sp = routing_schemes + sid) != NULL) &&
(hdw->input_val >= 0) &&
@@ -131,10 +128,8 @@ void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
pvr2_trace(PVR2_TRACE_CHIPS,
"subdev cx2584x set_input vid=0x%x aud=0x%x",
vid_input, aud_input);
- route.input = (u32)vid_input;
- sd->ops->video->s_routing(sd, &route);
- route.input = (u32)aud_input;
- sd->ops->audio->s_routing(sd, &route);
+ sd->ops->video->s_routing(sd, (u32)vid_input, 0, 0);
+ sd->ops->audio->s_routing(sd, (u32)aud_input, 0, 0);
}
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 7a65b42a4f5..d9d974a8f52 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2039,7 +2039,7 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
"Module ID %u:"
" Setting up with specified i2c address 0x%x",
mid, i2caddr[0]);
- sd = v4l2_i2c_new_subdev(&hdw->i2c_adap,
+ sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
fname, fname,
i2caddr[0]);
} else {
@@ -2047,7 +2047,7 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
"Module ID %u:"
" Setting up with address probe list",
mid);
- sd = v4l2_i2c_new_probed_subdev(&hdw->i2c_adap,
+ sd = v4l2_i2c_new_probed_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
fname, fname,
i2caddr);
}
@@ -2185,7 +2185,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
pvr2_hdw_load_modules(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return;
- v4l2_device_call_all(&hdw->v4l2_dev, 0, core, init, 0);
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, core, load_fw);
for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
cptr = hdw->controls + idx;
@@ -2574,7 +2574,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
if (!hdw->ctl_read_urb) goto fail;
- if (v4l2_device_register(&usb_dev->dev, &hdw->v4l2_dev) != 0) {
+ if (v4l2_device_register(&intf->dev, &hdw->v4l2_dev) != 0) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
"Error registering with v4l core, giving up");
goto fail;
@@ -2926,6 +2926,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
pvr2_trace(PVR2_TRACE_CHIPS, "subdev tuner set_type(%d)",
hdw->tuner_type);
if (((int)(hdw->tuner_type)) >= 0) {
+ memset(&setup, 0, sizeof(setup));
setup.addr = ADDR_UNSET;
setup.type = hdw->tuner_type;
setup.mode_mask = T_RADIO | T_ANALOG_TV;
@@ -2943,7 +2944,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
v4l2_std_id vs;
vs = hdw->std_mask_cur;
v4l2_device_call_all(&hdw->v4l2_dev, 0,
- tuner, s_std, vs);
+ core, s_std, vs);
}
hdw->tuner_signal_stale = !0;
hdw->cropcap_stale = !0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 9464862745f..9af282f9e76 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -520,16 +520,6 @@ static u32 pvr2_i2c_functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
}
-static int pvr2_i2c_attach_inform(struct i2c_client *client)
-{
- return 0;
-}
-
-static int pvr2_i2c_detach_inform(struct i2c_client *client)
-{
- return 0;
-}
-
static struct i2c_algorithm pvr2_i2c_algo_template = {
.master_xfer = pvr2_i2c_xfer,
.functionality = pvr2_i2c_functionality,
@@ -539,8 +529,6 @@ static struct i2c_adapter pvr2_i2c_adap_template = {
.owner = THIS_MODULE,
.class = 0,
.id = I2C_HW_B_BT848,
- .client_register = pvr2_i2c_attach_inform,
- .client_unregister = pvr2_i2c_detach_inform,
};
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index e20ba1e6e0e..299c1cbc383 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -153,14 +153,16 @@ static ssize_t show_def(struct device *class_dev,
struct pvr2_sysfs_ctl_item *cip;
int val;
int ret;
+ unsigned int cnt = 0;
cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_def);
ret = pvr2_ctrl_get_def(cip->cptr, &val);
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %d, stat=%d",
- cip->chptr, cip->ctl_id, val, ret);
- if (ret < 0) {
- return ret;
- }
- return scnprintf(buf, PAGE_SIZE, "%d\n", val);
+ if (ret < 0) return ret;
+ ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val,
+ buf, PAGE_SIZE - 1, &cnt);
+ pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %.*s (%d)",
+ cip->chptr, cip->ctl_id, cnt, buf, val);
+ buf[cnt] = '\n';
+ return cnt + 1;
}
static ssize_t show_val_norm(struct device *class_dev,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index b3862f5554b..d2fe7c8f2c3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -75,16 +75,17 @@ static const struct routing_scheme routing_schemes[] = {
void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
if (hdw->input_dirty || hdw->force_dirty) {
- struct v4l2_routing route;
const struct routing_scheme *sp;
unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+ u32 input;
+
pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
hdw->input_val);
if ((sid < ARRAY_SIZE(routing_schemes)) &&
((sp = routing_schemes + sid) != NULL) &&
(hdw->input_val >= 0) &&
(hdw->input_val < sp->cnt)) {
- route.input = sp->def[hdw->input_val];
+ input = sp->def[hdw->input_val];
} else {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
"*** WARNING *** subdev v4l2 set_input:"
@@ -93,8 +94,7 @@ void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
sid, hdw->input_val);
return;
}
- route.output = 0;
- sd->ops->video->s_routing(sd, &route);
+ sd->ops->video->s_routing(sd, input, 0, 0);
}
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
index 1670aa4051c..8c1eae05aa0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
@@ -39,24 +39,22 @@
void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
if (hdw->input_dirty || hdw->force_dirty) {
- struct v4l2_routing route;
-
- memset(&route, 0, sizeof(route));
+ u32 input;
switch (hdw->input_val) {
case PVR2_CVAL_INPUT_RADIO:
- route.input = 1;
+ input = 1;
break;
default:
/* All other cases just use the second input */
- route.input = 2;
+ input = 2;
break;
}
pvr2_trace(PVR2_TRACE_CHIPS, "subdev wm8775"
" set_input(val=%d route=0x%x)",
- hdw->input_val, route.input);
+ hdw->input_val, input);
- sd->ops->audio->s_routing(sd, &route);
+ sd->ops->audio->s_routing(sd, input, 0, 0);
}
}
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig
index 8b9f0aa844a..340f954aba3 100644
--- a/drivers/media/video/pwc/Kconfig
+++ b/drivers/media/video/pwc/Kconfig
@@ -39,7 +39,7 @@ config USB_PWC_DEBUG
config USB_PWC_INPUT_EVDEV
bool "USB Philips Cameras input events device support"
default y
- depends on USB_PWC && INPUT
+ depends on USB_PWC=INPUT || INPUT=y
---help---
This option makes USB Philips cameras register the snapshot button as
an input device to report button events.
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index c522616ef38..c639845460f 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -163,6 +163,13 @@
CICR0_EOFM | CICR0_FOM)
/*
+ * YUV422P picture size should be a multiple of 16, so the heuristic aligns
+ * height, width on 4 byte boundaries to reach the 16 multiple for the size.
+ */
+#define YUV422P_X_Y_ALIGN 4
+#define YUV422P_SIZE_ALIGN YUV422P_X_Y_ALIGN * YUV422P_X_Y_ALIGN
+
+/*
* Structures
*/
enum pxa_camera_active_dma {
@@ -236,20 +243,11 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
unsigned int *size)
{
struct soc_camera_device *icd = vq->priv_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
- struct pxa_camera_dev *pcdev = ici->priv;
dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
- /* planar capture requires Y, U and V buffers to be page aligned */
- if (pcdev->channels == 3) {
- *size = PAGE_ALIGN(icd->width * icd->height); /* Y pages */
- *size += PAGE_ALIGN(icd->width * icd->height / 2); /* U pages */
- *size += PAGE_ALIGN(icd->width * icd->height / 2); /* V pages */
- } else {
- *size = icd->width * icd->height *
- ((icd->current_fmt->depth + 7) >> 3);
- }
+ *size = roundup(icd->width * icd->height *
+ ((icd->current_fmt->depth + 7) >> 3), 8);
if (0 == *count)
*count = 32;
@@ -289,19 +287,63 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
buf->vb.state = VIDEOBUF_NEEDS_INIT;
}
+static int calculate_dma_sglen(struct scatterlist *sglist, int sglen,
+ int sg_first_ofs, int size)
+{
+ int i, offset, dma_len, xfer_len;
+ struct scatterlist *sg;
+
+ offset = sg_first_ofs;
+ for_each_sg(sglist, sg, sglen, i) {
+ dma_len = sg_dma_len(sg);
+
+ /* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
+ xfer_len = roundup(min(dma_len - offset, size), 8);
+
+ size = max(0, size - xfer_len);
+ offset = 0;
+ if (size == 0)
+ break;
+ }
+
+ BUG_ON(size != 0);
+ return i + 1;
+}
+
+/**
+ * pxa_init_dma_channel - init dma descriptors
+ * @pcdev: pxa camera device
+ * @buf: pxa buffer to find pxa dma channel
+ * @dma: dma video buffer
+ * @channel: dma channel (0 => 'Y', 1 => 'U', 2 => 'V')
+ * @cibr: camera Receive Buffer Register
+ * @size: bytes to transfer
+ * @sg_first: first element of sg_list
+ * @sg_first_ofs: offset in first element of sg_list
+ *
+ * Prepares the pxa dma descriptors to transfer one camera channel.
+ * Beware sg_first and sg_first_ofs are both input and output parameters.
+ *
+ * Returns 0 or -ENOMEM if no coherent memory is available
+ */
static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
struct pxa_buffer *buf,
struct videobuf_dmabuf *dma, int channel,
- int sglen, int sg_start, int cibr,
- unsigned int size)
+ int cibr, int size,
+ struct scatterlist **sg_first, int *sg_first_ofs)
{
struct pxa_cam_dma *pxa_dma = &buf->dmas[channel];
- int i;
+ struct scatterlist *sg;
+ int i, offset, sglen;
+ int dma_len = 0, xfer_len = 0;
if (pxa_dma->sg_cpu)
dma_free_coherent(pcdev->dev, pxa_dma->sg_size,
pxa_dma->sg_cpu, pxa_dma->sg_dma);
+ sglen = calculate_dma_sglen(*sg_first, dma->sglen,
+ *sg_first_ofs, size);
+
pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc);
pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->dev, pxa_dma->sg_size,
&pxa_dma->sg_dma, GFP_KERNEL);
@@ -309,31 +351,75 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
return -ENOMEM;
pxa_dma->sglen = sglen;
+ offset = *sg_first_ofs;
- for (i = 0; i < sglen; i++) {
- int sg_i = sg_start + i;
- struct scatterlist *sg = dma->sglist;
- unsigned int dma_len = sg_dma_len(&sg[sg_i]), xfer_len;
+ dev_dbg(pcdev->dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
+ *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma);
- pxa_dma->sg_cpu[i].dsadr = pcdev->res->start + cibr;
- pxa_dma->sg_cpu[i].dtadr = sg_dma_address(&sg[sg_i]);
+
+ for_each_sg(*sg_first, sg, sglen, i) {
+ dma_len = sg_dma_len(sg);
/* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
- xfer_len = (min(dma_len, size) + 7) & ~7;
+ xfer_len = roundup(min(dma_len - offset, size), 8);
+ size = max(0, size - xfer_len);
+
+ pxa_dma->sg_cpu[i].dsadr = pcdev->res->start + cibr;
+ pxa_dma->sg_cpu[i].dtadr = sg_dma_address(sg) + offset;
pxa_dma->sg_cpu[i].dcmd =
DCMD_FLOWSRC | DCMD_BURST8 | DCMD_INCTRGADDR | xfer_len;
- size -= dma_len;
+#ifdef DEBUG
+ if (!i)
+ pxa_dma->sg_cpu[i].dcmd |= DCMD_STARTIRQEN;
+#endif
pxa_dma->sg_cpu[i].ddadr =
pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc);
+
+ dev_vdbg(pcdev->dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
+ pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc),
+ sg_dma_address(sg) + offset, xfer_len);
+ offset = 0;
+
+ if (size == 0)
+ break;
}
- pxa_dma->sg_cpu[sglen - 1].ddadr = DDADR_STOP;
- pxa_dma->sg_cpu[sglen - 1].dcmd |= DCMD_ENDIRQEN;
+ pxa_dma->sg_cpu[sglen].ddadr = DDADR_STOP;
+ pxa_dma->sg_cpu[sglen].dcmd = DCMD_FLOWSRC | DCMD_BURST8 | DCMD_ENDIRQEN;
+
+ /*
+ * Handle 1 special case :
+ * - in 3 planes (YUV422P format), we might finish with xfer_len equal
+ * to dma_len (end on PAGE boundary). In this case, the sg element
+ * for next plane should be the next after the last used to store the
+ * last scatter gather RAM page
+ */
+ if (xfer_len >= dma_len) {
+ *sg_first_ofs = xfer_len - dma_len;
+ *sg_first = sg_next(sg);
+ } else {
+ *sg_first_ofs = xfer_len;
+ *sg_first = sg;
+ }
return 0;
}
+static void pxa_videobuf_set_actdma(struct pxa_camera_dev *pcdev,
+ struct pxa_buffer *buf)
+{
+ buf->active_dma = DMA_Y;
+ if (pcdev->channels == 3)
+ buf->active_dma |= DMA_U | DMA_V;
+}
+
+/*
+ * Please check the DMA prepared buffer structure in :
+ * Documentation/video4linux/pxa_camera.txt
+ * Please check also in pxa_camera_check_link_miss() to understand why DMA chain
+ * modification while DMA chain is running will work anyway.
+ */
static int pxa_videobuf_prepare(struct videobuf_queue *vq,
struct videobuf_buffer *vb, enum v4l2_field field)
{
@@ -342,7 +428,6 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
struct pxa_camera_dev *pcdev = ici->priv;
struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
int ret;
- int sglen_y, sglen_yu = 0, sglen_u = 0, sglen_v = 0;
int size_y, size_u = 0, size_v = 0;
dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
@@ -381,62 +466,58 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
}
if (vb->state == VIDEOBUF_NEEDS_INIT) {
- unsigned int size = vb->size;
+ int size = vb->size;
+ int next_ofs = 0;
struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
+ struct scatterlist *sg;
ret = videobuf_iolock(vq, vb, NULL);
if (ret)
goto fail;
if (pcdev->channels == 3) {
- /* FIXME the calculations should be more precise */
- sglen_y = dma->sglen / 2;
- sglen_u = sglen_v = dma->sglen / 4 + 1;
- sglen_yu = sglen_y + sglen_u;
size_y = size / 2;
size_u = size_v = size / 4;
} else {
- sglen_y = dma->sglen;
size_y = size;
}
- /* init DMA for Y channel */
- ret = pxa_init_dma_channel(pcdev, buf, dma, 0, sglen_y,
- 0, 0x28, size_y);
+ sg = dma->sglist;
+ /* init DMA for Y channel */
+ ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y,
+ &sg, &next_ofs);
if (ret) {
dev_err(pcdev->dev,
"DMA initialization for Y/RGB failed\n");
goto fail;
}
- if (pcdev->channels == 3) {
- /* init DMA for U channel */
- ret = pxa_init_dma_channel(pcdev, buf, dma, 1, sglen_u,
- sglen_y, 0x30, size_u);
- if (ret) {
- dev_err(pcdev->dev,
- "DMA initialization for U failed\n");
- goto fail_u;
- }
-
- /* init DMA for V channel */
- ret = pxa_init_dma_channel(pcdev, buf, dma, 2, sglen_v,
- sglen_yu, 0x38, size_v);
- if (ret) {
- dev_err(pcdev->dev,
- "DMA initialization for V failed\n");
- goto fail_v;
- }
+ /* init DMA for U channel */
+ if (size_u)
+ ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1,
+ size_u, &sg, &next_ofs);
+ if (ret) {
+ dev_err(pcdev->dev,
+ "DMA initialization for U failed\n");
+ goto fail_u;
+ }
+
+ /* init DMA for V channel */
+ if (size_v)
+ ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2,
+ size_v, &sg, &next_ofs);
+ if (ret) {
+ dev_err(pcdev->dev,
+ "DMA initialization for V failed\n");
+ goto fail_v;
}
vb->state = VIDEOBUF_PREPARED;
}
buf->inwork = 0;
- buf->active_dma = DMA_Y;
- if (pcdev->channels == 3)
- buf->active_dma |= DMA_U | DMA_V;
+ pxa_videobuf_set_actdma(pcdev, buf);
return 0;
@@ -453,6 +534,92 @@ out:
return ret;
}
+/**
+ * pxa_dma_start_channels - start DMA channel for active buffer
+ * @pcdev: pxa camera device
+ *
+ * Initialize DMA channels to the beginning of the active video buffer, and
+ * start these channels.
+ */
+static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev)
+{
+ int i;
+ struct pxa_buffer *active;
+
+ active = pcdev->active;
+
+ for (i = 0; i < pcdev->channels; i++) {
+ dev_dbg(pcdev->dev, "%s (channel=%d) ddadr=%08x\n", __func__,
+ i, active->dmas[i].sg_dma);
+ DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma;
+ DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
+ }
+}
+
+static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev)
+{
+ int i;
+
+ for (i = 0; i < pcdev->channels; i++) {
+ dev_dbg(pcdev->dev, "%s (channel=%d)\n", __func__, i);
+ DCSR(pcdev->dma_chans[i]) = 0;
+ }
+}
+
+static void pxa_dma_add_tail_buf(struct pxa_camera_dev *pcdev,
+ struct pxa_buffer *buf)
+{
+ int i;
+ struct pxa_dma_desc *buf_last_desc;
+
+ for (i = 0; i < pcdev->channels; i++) {
+ buf_last_desc = buf->dmas[i].sg_cpu + buf->dmas[i].sglen;
+ buf_last_desc->ddadr = DDADR_STOP;
+
+ if (pcdev->sg_tail[i])
+ /* Link the new buffer to the old tail */
+ pcdev->sg_tail[i]->ddadr = buf->dmas[i].sg_dma;
+
+ /* Update the channel tail */
+ pcdev->sg_tail[i] = buf_last_desc;
+ }
+}
+
+/**
+ * pxa_camera_start_capture - start video capturing
+ * @pcdev: camera device
+ *
+ * Launch capturing. DMA channels should not be active yet. They should get
+ * activated at the end of frame interrupt, to capture only whole frames, and
+ * never begin the capture of a partial frame.
+ */
+static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
+{
+ unsigned long cicr0, cifr;
+
+ dev_dbg(pcdev->dev, "%s\n", __func__);
+ /* Reset the FIFOs */
+ cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
+ __raw_writel(cifr, pcdev->base + CIFR);
+ /* Enable End-Of-Frame Interrupt */
+ cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB;
+ cicr0 &= ~CICR0_EOFM;
+ __raw_writel(cicr0, pcdev->base + CICR0);
+}
+
+static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
+{
+ unsigned long cicr0;
+
+ pxa_dma_stop_channels(pcdev);
+
+ cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB;
+ __raw_writel(cicr0, pcdev->base + CICR0);
+
+ pcdev->active = NULL;
+ dev_dbg(pcdev->dev, "%s\n", __func__);
+}
+
static void pxa_videobuf_queue(struct videobuf_queue *vq,
struct videobuf_buffer *vb)
{
@@ -460,81 +627,20 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct pxa_camera_dev *pcdev = ici->priv;
struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
- struct pxa_buffer *active;
unsigned long flags;
- int i;
- dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
+ dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d active=%p\n", __func__,
+ vb, vb->baddr, vb->bsize, pcdev->active);
+
spin_lock_irqsave(&pcdev->lock, flags);
list_add_tail(&vb->queue, &pcdev->capture);
vb->state = VIDEOBUF_ACTIVE;
- active = pcdev->active;
+ pxa_dma_add_tail_buf(pcdev, buf);
- if (!active) {
- unsigned long cifr, cicr0;
-
- cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
- __raw_writel(cifr, pcdev->base + CIFR);
-
- for (i = 0; i < pcdev->channels; i++) {
- DDADR(pcdev->dma_chans[i]) = buf->dmas[i].sg_dma;
- DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
- pcdev->sg_tail[i] = buf->dmas[i].sg_cpu + buf->dmas[i].sglen - 1;
- }
-
- pcdev->active = buf;
-
- cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB;
- __raw_writel(cicr0, pcdev->base + CICR0);
- } else {
- struct pxa_cam_dma *buf_dma;
- struct pxa_cam_dma *act_dma;
- int nents;
-
- for (i = 0; i < pcdev->channels; i++) {
- buf_dma = &buf->dmas[i];
- act_dma = &active->dmas[i];
- nents = buf_dma->sglen;
-
- /* Stop DMA engine */
- DCSR(pcdev->dma_chans[i]) = 0;
-
- /* Add the descriptors we just initialized to
- the currently running chain */
- pcdev->sg_tail[i]->ddadr = buf_dma->sg_dma;
- pcdev->sg_tail[i] = buf_dma->sg_cpu + buf_dma->sglen - 1;
-
- /* Setup a dummy descriptor with the DMA engines current
- * state
- */
- buf_dma->sg_cpu[nents].dsadr =
- pcdev->res->start + 0x28 + i*8; /* CIBRx */
- buf_dma->sg_cpu[nents].dtadr =
- DTADR(pcdev->dma_chans[i]);
- buf_dma->sg_cpu[nents].dcmd =
- DCMD(pcdev->dma_chans[i]);
-
- if (DDADR(pcdev->dma_chans[i]) == DDADR_STOP) {
- /* The DMA engine is on the last
- descriptor, set the next descriptors
- address to the descriptors we just
- initialized */
- buf_dma->sg_cpu[nents].ddadr = buf_dma->sg_dma;
- } else {
- buf_dma->sg_cpu[nents].ddadr =
- DDADR(pcdev->dma_chans[i]);
- }
-
- /* The next descriptor is the dummy descriptor */
- DDADR(pcdev->dma_chans[i]) = buf_dma->sg_dma + nents *
- sizeof(struct pxa_dma_desc);
-
- DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
- }
- }
+ if (!pcdev->active)
+ pxa_camera_start_capture(pcdev);
spin_unlock_irqrestore(&pcdev->lock, flags);
}
@@ -572,7 +678,7 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
struct videobuf_buffer *vb,
struct pxa_buffer *buf)
{
- unsigned long cicr0;
+ int i;
/* _init is used to debug races, see comment in pxa_camera_reqbufs() */
list_del_init(&vb->queue);
@@ -580,15 +686,12 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
do_gettimeofday(&vb->ts);
vb->field_count++;
wake_up(&vb->done);
+ dev_dbg(pcdev->dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb);
if (list_empty(&pcdev->capture)) {
- pcdev->active = NULL;
- DCSR(pcdev->dma_chans[0]) = 0;
- DCSR(pcdev->dma_chans[1]) = 0;
- DCSR(pcdev->dma_chans[2]) = 0;
-
- cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB;
- __raw_writel(cicr0, pcdev->base + CICR0);
+ pxa_camera_stop_capture(pcdev);
+ for (i = 0; i < pcdev->channels; i++)
+ pcdev->sg_tail[i] = NULL;
return;
}
@@ -596,6 +699,35 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
struct pxa_buffer, vb.queue);
}
+/**
+ * pxa_camera_check_link_miss - check missed DMA linking
+ * @pcdev: camera device
+ *
+ * The DMA chaining is done with DMA running. This means a tiny temporal window
+ * remains, where a buffer is queued on the chain, while the chain is already
+ * stopped. This means the tailed buffer would never be transfered by DMA.
+ * This function restarts the capture for this corner case, where :
+ * - DADR() == DADDR_STOP
+ * - a videobuffer is queued on the pcdev->capture list
+ *
+ * Please check the "DMA hot chaining timeslice issue" in
+ * Documentation/video4linux/pxa_camera.txt
+ *
+ * Context: should only be called within the dma irq handler
+ */
+static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
+{
+ int i, is_dma_stopped = 1;
+
+ for (i = 0; i < pcdev->channels; i++)
+ if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP)
+ is_dma_stopped = 0;
+ dev_dbg(pcdev->dev, "%s : top queued buffer=%p, dma_stopped=%d\n",
+ __func__, pcdev->active, is_dma_stopped);
+ if (pcdev->active && is_dma_stopped)
+ pxa_camera_start_capture(pcdev);
+}
+
static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
enum pxa_camera_active_dma act_dma)
{
@@ -603,61 +735,70 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
unsigned long flags;
u32 status, camera_status, overrun;
struct videobuf_buffer *vb;
- unsigned long cifr, cicr0;
spin_lock_irqsave(&pcdev->lock, flags);
status = DCSR(channel);
- DCSR(channel) = status | DCSR_ENDINTR;
+ DCSR(channel) = status;
+
+ camera_status = __raw_readl(pcdev->base + CISR);
+ overrun = CISR_IFO_0;
+ if (pcdev->channels == 3)
+ overrun |= CISR_IFO_1 | CISR_IFO_2;
if (status & DCSR_BUSERR) {
dev_err(pcdev->dev, "DMA Bus Error IRQ!\n");
goto out;
}
- if (!(status & DCSR_ENDINTR)) {
+ if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) {
dev_err(pcdev->dev, "Unknown DMA IRQ source, "
"status: 0x%08x\n", status);
goto out;
}
- if (!pcdev->active) {
- dev_err(pcdev->dev, "DMA End IRQ with no active buffer!\n");
- goto out;
- }
-
- camera_status = __raw_readl(pcdev->base + CISR);
- overrun = CISR_IFO_0;
- if (pcdev->channels == 3)
- overrun |= CISR_IFO_1 | CISR_IFO_2;
- if (camera_status & overrun) {
- dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n", camera_status);
- /* Stop the Capture Interface */
- cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB;
- __raw_writel(cicr0, pcdev->base + CICR0);
-
- /* Stop DMA */
- DCSR(channel) = 0;
- /* Reset the FIFOs */
- cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
- __raw_writel(cifr, pcdev->base + CIFR);
- /* Enable End-Of-Frame Interrupt */
- cicr0 &= ~CICR0_EOFM;
- __raw_writel(cicr0, pcdev->base + CICR0);
- /* Restart the Capture Interface */
- __raw_writel(cicr0 | CICR0_ENB, pcdev->base + CICR0);
+ /*
+ * pcdev->active should not be NULL in DMA irq handler.
+ *
+ * But there is one corner case : if capture was stopped due to an
+ * overrun of channel 1, and at that same channel 2 was completed.
+ *
+ * When handling the overrun in DMA irq for channel 1, we'll stop the
+ * capture and restart it (and thus set pcdev->active to NULL). But the
+ * DMA irq handler will already be pending for channel 2. So on entering
+ * the DMA irq handler for channel 2 there will be no active buffer, yet
+ * that is normal.
+ */
+ if (!pcdev->active)
goto out;
- }
vb = &pcdev->active->vb;
buf = container_of(vb, struct pxa_buffer, vb);
WARN_ON(buf->inwork || list_empty(&vb->queue));
- dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
- buf->active_dma &= ~act_dma;
- if (!buf->active_dma)
- pxa_camera_wakeup(pcdev, vb, buf);
+ dev_dbg(pcdev->dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
+ __func__, channel, status & DCSR_STARTINTR ? "SOF " : "",
+ status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel));
+
+ if (status & DCSR_ENDINTR) {
+ /*
+ * It's normal if the last frame creates an overrun, as there
+ * are no more DMA descriptors to fetch from QCI fifos
+ */
+ if (camera_status & overrun &&
+ !list_is_last(pcdev->capture.next, &pcdev->capture)) {
+ dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n",
+ camera_status);
+ pxa_camera_stop_capture(pcdev);
+ pxa_camera_start_capture(pcdev);
+ goto out;
+ }
+ buf->active_dma &= ~act_dma;
+ if (!buf->active_dma) {
+ pxa_camera_wakeup(pcdev, vb, buf);
+ pxa_camera_check_link_miss(pcdev);
+ }
+ }
out:
spin_unlock_irqrestore(&pcdev->lock, flags);
@@ -786,6 +927,8 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
{
struct pxa_camera_dev *pcdev = data;
unsigned long status, cicr0;
+ struct pxa_buffer *buf;
+ struct videobuf_buffer *vb;
status = __raw_readl(pcdev->base + CISR);
dev_dbg(pcdev->dev, "Camera interrupt status 0x%lx\n", status);
@@ -796,12 +939,14 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
__raw_writel(status, pcdev->base + CISR);
if (status & CISR_EOF) {
- int i;
- for (i = 0; i < pcdev->channels; i++) {
- DDADR(pcdev->dma_chans[i]) =
- pcdev->active->dmas[i].sg_dma;
- DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
- }
+ pcdev->active = list_first_entry(&pcdev->capture,
+ struct pxa_buffer, vb.queue);
+ vb = &pcdev->active->vb;
+ buf = container_of(vb, struct pxa_buffer, vb);
+ pxa_videobuf_set_actdma(pcdev, buf);
+
+ pxa_dma_start_channels(pcdev);
+
cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_EOFM;
__raw_writel(cicr0, pcdev->base + CICR0);
}
@@ -1265,6 +1410,18 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
pix->width = 2048;
pix->width &= ~0x01;
+ /*
+ * YUV422P planar format requires images size to be a 16 bytes
+ * multiple. If not, zeros will be inserted between Y and U planes, and
+ * U and V planes, and YUV422P standard would be violated.
+ */
+ if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P) {
+ if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN))
+ pix->height = ALIGN(pix->height, YUV422P_X_Y_ALIGN);
+ if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN))
+ pix->width = ALIGN(pix->width, YUV422P_X_Y_ALIGN);
+ }
+
pix->bytesperline = pix->width *
DIV_ROUND_UP(xlate->host_fmt->depth, 8);
pix->sizeimage = pix->height * pix->bytesperline;
@@ -1372,18 +1529,8 @@ static int pxa_camera_resume(struct soc_camera_device *icd)
ret = pcdev->icd->ops->resume(pcdev->icd);
/* Restart frame capture if active buffer exists */
- if (!ret && pcdev->active) {
- unsigned long cifr, cicr0;
-
- /* Reset the FIFOs */
- cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
- __raw_writel(cifr, pcdev->base + CIFR);
-
- cicr0 = __raw_readl(pcdev->base + CICR0);
- cicr0 &= ~CICR0_EOFM; /* Enable End-Of-Frame Interrupt */
- cicr0 |= CICR0_ENB; /* Restart the Capture Interface */
- __raw_writel(cicr0, pcdev->base + CICR0);
- }
+ if (!ret && pcdev->active)
+ pxa_camera_start_capture(pcdev);
return ret;
}
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index b5be633e3bb..5202cadb2aa 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -722,7 +722,6 @@ static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
{
dprintk(4, "%s\n", __func__);
- videobuf_waiton(&buf->vb, 0, 0);
videobuf_vmalloc_free(&buf->vb);
buf->vb.state = VIDEOBUF_NEEDS_INIT;
}
@@ -1324,7 +1323,6 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
{
- int res;
struct s2255_fh *fh = priv;
struct s2255_dev *dev = fh->dev;
@@ -1338,9 +1336,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
return -EINVAL;
}
s2255_stop_acquire(dev, fh->channel);
- res = videobuf_streamoff(&fh->vb_vidq);
- if (res < 0)
- return res;
+ videobuf_streamoff(&fh->vb_vidq);
res_free(dev, fh);
return 0;
}
@@ -1707,13 +1703,13 @@ static void s2255_destroy(struct kref *kref)
kfree(dev->fw_data);
usb_put_dev(dev->udev);
dprintk(1, "%s", __func__);
- kfree(dev);
while (!list_empty(&s2255_devlist)) {
list = s2255_devlist.next;
list_del(list);
}
mutex_unlock(&dev->open_lock);
+ kfree(dev);
}
static int s2255_close(struct file *file)
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index df4e08d2dce..5c24c993ac1 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -299,17 +299,18 @@ static int saa7110_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
return 0;
}
-static int saa7110_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa7110_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct saa7110 *decoder = to_saa7110(sd);
- if (route->input < 0 || route->input >= SAA7110_MAX_INPUT) {
- v4l2_dbg(1, debug, sd, "input=%d not available\n", route->input);
+ if (input < 0 || input >= SAA7110_MAX_INPUT) {
+ v4l2_dbg(1, debug, sd, "input=%d not available\n", input);
return -EINVAL;
}
- if (decoder->input != route->input) {
- saa7110_selmux(sd, route->input);
- v4l2_dbg(1, debug, sd, "switched to input=%d\n", route->input);
+ if (decoder->input != input) {
+ saa7110_selmux(sd, input);
+ v4l2_dbg(1, debug, sd, "switched to input=%d\n", input);
}
return 0;
}
@@ -414,9 +415,6 @@ static const struct v4l2_subdev_core_ops saa7110_core_ops = {
.g_ctrl = saa7110_g_ctrl,
.s_ctrl = saa7110_s_ctrl,
.queryctrl = saa7110_queryctrl,
-};
-
-static const struct v4l2_subdev_tuner_ops saa7110_tuner_ops = {
.s_std = saa7110_s_std,
};
@@ -429,7 +427,6 @@ static const struct v4l2_subdev_video_ops saa7110_video_ops = {
static const struct v4l2_subdev_ops saa7110_ops = {
.core = &saa7110_core_ops,
- .tuner = &saa7110_tuner_ops,
.video = &saa7110_video_ops,
};
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index cebf159f52c..44873a016c2 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -46,7 +46,7 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include <media/saa7115.h>
#include <asm/div64.h>
@@ -62,12 +62,6 @@ module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-static unsigned short normal_i2c[] = {
- 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
- 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
- I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
struct saa711x_state {
struct v4l2_subdev sd;
@@ -1234,30 +1228,32 @@ static int saa711x_s_radio(struct v4l2_subdev *sd)
return 0;
}
-static int saa711x_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa711x_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct saa711x_state *state = to_state(sd);
- u32 input = route->input;
u8 mask = (state->ident == V4L2_IDENT_SAA7111) ? 0xf8 : 0xf0;
- v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n", route->input, route->output);
+ v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
+ input, output);
+
/* saa7111/3 does not have these inputs */
if ((state->ident == V4L2_IDENT_SAA7113 ||
state->ident == V4L2_IDENT_SAA7111) &&
- (route->input == SAA7115_COMPOSITE4 ||
- route->input == SAA7115_COMPOSITE5)) {
+ (input == SAA7115_COMPOSITE4 ||
+ input == SAA7115_COMPOSITE5)) {
return -EINVAL;
}
- if (route->input > SAA7115_SVIDEO3)
+ if (input > SAA7115_SVIDEO3)
return -EINVAL;
- if (route->output > SAA7115_IPORT_ON)
+ if (output > SAA7115_IPORT_ON)
return -EINVAL;
- if (state->input == route->input && state->output == route->output)
+ if (state->input == input && state->output == output)
return 0;
v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
- (route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
- (route->output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
- state->input = route->input;
+ (input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
+ (output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
+ state->input = input;
/* saa7111 has slightly different input numbering */
if (state->ident == V4L2_IDENT_SAA7111) {
@@ -1266,10 +1262,10 @@ static int saa711x_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *
/* saa7111 specific */
saa711x_write(sd, R_10_CHROMA_CNTL_2,
(saa711x_read(sd, R_10_CHROMA_CNTL_2) & 0x3f) |
- ((route->output & 0xc0) ^ 0x40));
+ ((output & 0xc0) ^ 0x40));
saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL,
(saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) |
- ((route->output & 2) ? 0x0a : 0));
+ ((output & 2) ? 0x0a : 0));
}
/* select mode */
@@ -1282,7 +1278,7 @@ static int saa711x_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *
(saa711x_read(sd, R_09_LUMA_CNTL) & 0x7f) |
(state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
- state->output = route->output;
+ state->output = output;
if (state->ident == V4L2_IDENT_SAA7114 ||
state->ident == V4L2_IDENT_SAA7115) {
saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
@@ -1319,17 +1315,16 @@ static int saa711x_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
}
-static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, struct v4l2_crystal_freq *freq)
+static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, u32 freq, u32 flags)
{
struct saa711x_state *state = to_state(sd);
- if (freq->freq != SAA7115_FREQ_32_11_MHZ &&
- freq->freq != SAA7115_FREQ_24_576_MHZ)
+ if (freq != SAA7115_FREQ_32_11_MHZ && freq != SAA7115_FREQ_24_576_MHZ)
return -EINVAL;
- state->crystal_freq = freq->freq;
- state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
- state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
- state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
+ state->crystal_freq = freq;
+ state->cgcdiv = (flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
+ state->ucgc = (flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
+ state->apll = (flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
saa711x_s_clock_freq(sd, state->audclk_freq);
return 0;
}
@@ -1498,11 +1493,6 @@ static int saa711x_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int saa711x_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops saa711x_core_ops = {
@@ -1511,6 +1501,7 @@ static const struct v4l2_subdev_core_ops saa711x_core_ops = {
.g_ctrl = saa711x_g_ctrl,
.s_ctrl = saa711x_s_ctrl,
.queryctrl = saa711x_queryctrl,
+ .s_std = saa711x_s_std,
.reset = saa711x_reset,
.s_gpio = saa711x_s_gpio,
#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -1520,7 +1511,6 @@ static const struct v4l2_subdev_core_ops saa711x_core_ops = {
};
static const struct v4l2_subdev_tuner_ops saa711x_tuner_ops = {
- .s_std = saa711x_s_std,
.s_radio = saa711x_s_radio,
.g_tuner = saa711x_g_tuner,
};
@@ -1676,10 +1666,7 @@ MODULE_DEVICE_TABLE(i2c, saa7115_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa7115",
- .driverid = I2C_DRIVERID_SAA711X,
- .command = saa711x_command,
.probe = saa711x_probe,
.remove = saa711x_remove,
- .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
.id_table = saa7115_id,
};
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 128bb8b8dbb..2fe7a701b95 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -570,15 +570,16 @@ static int saa7127_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
return saa7127_set_std(sd, std);
}
-static int saa7127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa7127_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct saa7127_state *state = to_state(sd);
int rc = 0;
- if (state->input_type != route->input)
- rc = saa7127_set_input_type(sd, route->input);
- if (rc == 0 && state->output_type != route->output)
- rc = saa7127_set_output_type(sd, route->output);
+ if (state->input_type != input)
+ rc = saa7127_set_input_type(sd, input);
+ if (rc == 0 && state->output_type != output)
+ rc = saa7127_set_output_type(sd, output);
return rc;
}
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index dc2213e2f86..63c4b8f1f54 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -928,9 +928,6 @@ static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
.g_ext_ctrls = saa6752hs_g_ext_ctrls,
.s_ext_ctrls = saa6752hs_s_ext_ctrls,
.try_ext_ctrls = saa6752hs_try_ext_ctrls,
-};
-
-static const struct v4l2_subdev_tuner_ops saa6752hs_tuner_ops = {
.s_std = saa6752hs_s_std,
};
@@ -941,7 +938,6 @@ static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
static const struct v4l2_subdev_ops saa6752hs_ops = {
.core = &saa6752hs_core_ops,
- .tuner = &saa6752hs_tuner_ops,
.video = &saa6752hs_video_ops,
};
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index a790a7246a6..fdb19449d26 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -4508,12 +4508,17 @@ struct saa7134_board saa7134_boards[] = {
/* Matthias Schwarzott <zzam@gentoo.org> */
.name = "Avermedia DVB-S Hybrid+FM A700",
.audio_clock = 0x00187de7,
- .tuner_type = TUNER_ABSENT, /* TUNER_XC2028 */
+ .tuner_type = TUNER_XC2028,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.mpeg = SAA7134_MPEG_DVB,
.inputs = { {
+ .name = name_tv,
+ .vmux = 4,
+ .amux = TV,
+ .tv = 1,
+ }, {
.name = name_comp,
.vmux = 1,
.amux = LINE1,
@@ -4522,6 +4527,10 @@ struct saa7134_board saa7134_boards[] = {
.vmux = 6,
.amux = LINE1,
} },
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
+ },
},
[SAA7134_BOARD_BEHOLD_H6] = {
/* Igor Kuznetsov <igk@igk.ru> */
@@ -5914,6 +5923,11 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev,
msleep(10);
saa7134_set_gpio(dev, 21, 1);
break;
+ case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
+ saa7134_set_gpio(dev, 18, 0);
+ msleep(10);
+ saa7134_set_gpio(dev, 18, 1);
+ break;
}
return 0;
}
@@ -6259,10 +6273,6 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0c0007cd, 0x0c0007cd);
break;
case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
- printk("%s: %s: hybrid analog/dvb card\n"
- "%s: Sorry, of the analog inputs, only analog s-video and composite "
- "are supported for now.\n",
- dev->name, card(dev).name, dev->name);
case SAA7134_BOARD_AVERMEDIA_A700_PRO:
/* write windows gpio values */
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100);
@@ -6326,6 +6336,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
case SAA7134_BOARD_AVERMEDIA_A16D:
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
case SAA7134_BOARD_AVERMEDIA_M103:
+ case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
ctl.demod = XC3028_FE_ZARLINK456;
break;
default:
@@ -6599,20 +6610,24 @@ int saa7134_board_init2(struct saa7134_dev *dev)
/* Note: radio tuner address is always filled in,
so we do not need to probe for a radio tuner device. */
if (dev->radio_type != UNSET)
- v4l2_i2c_new_subdev(&dev->i2c_adap,
- "tuner", "tuner", dev->radio_addr);
+ v4l2_i2c_new_subdev(&dev->v4l2_dev,
+ &dev->i2c_adap, "tuner", "tuner",
+ dev->radio_addr);
if (has_demod)
- v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
- "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+ &dev->i2c_adap, "tuner", "tuner",
+ v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
if (dev->tuner_addr == ADDR_UNSET) {
enum v4l2_i2c_tuner_type type =
has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
- v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
- "tuner", v4l2_i2c_tuner_addrs(type));
+ v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+ &dev->i2c_adap, "tuner", "tuner",
+ v4l2_i2c_tuner_addrs(type));
} else {
- v4l2_i2c_new_subdev(&dev->i2c_adap,
- "tuner", "tuner", dev->tuner_addr);
+ v4l2_i2c_new_subdev(&dev->v4l2_dev,
+ &dev->i2c_adap, "tuner", "tuner",
+ dev->tuner_addr);
}
}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index dafa0d88bed..2def6fec814 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -911,7 +911,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0));
pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev, DMA_32BIT_MASK)) {
+ if (!pci_dma_supported(pci_dev, DMA_BIT_MASK(32))) {
printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name);
err = -EIO;
goto fail1;
@@ -982,7 +982,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
/* load i2c helpers */
if (card_is_empress(dev)) {
struct v4l2_subdev *sd =
- v4l2_i2c_new_subdev(&dev->i2c_adap,
+ v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
"saa6752hs", "saa6752hs",
saa7134_boards[dev->board].empress_addr);
@@ -991,12 +991,11 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
}
if (saa7134_boards[dev->board].rds_addr) {
- unsigned short addrs[2] = { 0, I2C_CLIENT_END };
struct v4l2_subdev *sd;
- addrs[0] = saa7134_boards[dev->board].rds_addr;
- sd = v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "saa6588",
- "saa6588", addrs);
+ sd = v4l2_i2c_new_probed_subdev_addr(&dev->v4l2_dev,
+ &dev->i2c_adap, "saa6588", "saa6588",
+ saa7134_boards[dev->board].rds_addr);
if (sd)
printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
}
@@ -1015,7 +1014,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
saa7134_irq_video_signalchange(dev);
if (TUNER_ABSENT != dev->tuner_type)
- saa_call_all(dev, core, s_standby, 0);
+ saa_call_all(dev, tuner, s_standby);
/* register v4l devices */
if (saa7134_no_overlay > 0)
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 404f70eeb35..493cad94146 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -625,10 +625,10 @@ void saa7134_set_tvnorm_hw(struct saa7134_dev *dev)
saa7134_set_decoder(dev);
if (card_in(dev, dev->ctl_input).tv)
- saa_call_all(dev, tuner, s_std, dev->tvnorm->id);
+ saa_call_all(dev, core, s_std, dev->tvnorm->id);
/* Set the correct norm for the saa6752hs. This function
does nothing if there is no saa6752hs. */
- saa_call_empress(dev, tuner, s_std, dev->tvnorm->id);
+ saa_call_empress(dev, core, s_std, dev->tvnorm->id);
}
static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
@@ -1496,7 +1496,7 @@ static int video_release(struct file *file)
saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
- saa_call_all(dev, core, s_standby, 0);
+ saa_call_all(dev, tuner, s_standby);
if (fh->radio)
saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd);
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index a2dd326de5b..0cbaf90d487 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -20,7 +20,7 @@
*/
#include <linux/version.h>
-#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,14)
+#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,15)
#include <linux/pci.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index 25bf2303a6b..b15c40908e8 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -1104,22 +1104,22 @@ static struct v4l2_queryctrl saa717x_qctrl[] = {
},
};
-static int saa717x_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa717x_s_video_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct saa717x_state *decoder = to_state(sd);
- int inp = route->input;
- int is_tuner = inp & 0x80; /* tuner input flag */
+ int is_tuner = input & 0x80; /* tuner input flag */
- inp &= 0x7f;
+ input &= 0x7f;
- v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", inp);
+ v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input);
/* inputs from 0-9 are available*/
/* saa717x have mode0-mode9 but mode5 is reserved. */
- if (inp < 0 || inp > 9 || inp == 5)
+ if (input < 0 || input > 9 || input == 5)
return -EINVAL;
- if (decoder->input != inp) {
- int input_line = inp;
+ if (decoder->input != input) {
+ int input_line = input;
decoder->input = input_line;
v4l2_dbg(1, debug, sd, "now setting %s input %d\n",
@@ -1276,12 +1276,13 @@ static int saa717x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
return 0;
}
-static int saa717x_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa717x_s_audio_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct saa717x_state *decoder = to_state(sd);
- if (route->input < 3) { /* FIXME! --tadachi */
- decoder->audio_input = route->input;
+ if (input < 3) { /* FIXME! --tadachi */
+ decoder->audio_input = input;
v4l2_dbg(1, debug, sd,
"set decoder audio input to %d\n",
decoder->audio_input);
@@ -1390,12 +1391,12 @@ static const struct v4l2_subdev_core_ops saa717x_core_ops = {
.queryctrl = saa717x_queryctrl,
.g_ctrl = saa717x_g_ctrl,
.s_ctrl = saa717x_s_ctrl,
+ .s_std = saa717x_s_std,
};
static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = {
.g_tuner = saa717x_g_tuner,
.s_tuner = saa717x_s_tuner,
- .s_std = saa717x_s_std,
.s_radio = saa717x_s_radio,
};
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
index 75747b104d0..212baa10829 100644
--- a/drivers/media/video/saa7185.c
+++ b/drivers/media/video/saa7185.c
@@ -245,14 +245,15 @@ static int saa7185_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
return 0;
}
-static int saa7185_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa7185_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct saa7185 *encoder = to_saa7185(sd);
- /* RJ: route->input = 0: input is from SA7111
- route->input = 1: input is from ZR36060 */
+ /* RJ: input = 0: input is from SA7111
+ input = 1: input is from ZR36060 */
- switch (route->input) {
+ switch (input) {
case 0:
/* turn off colorbar */
saa7185_write(sd, 0x3a, 0x0f);
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
index 3f523aeec56..a2513772196 100644
--- a/drivers/media/video/saa7191.c
+++ b/drivers/media/video/saa7191.c
@@ -160,14 +160,14 @@ static int saa7191_write_block(struct v4l2_subdev *sd,
/* Helper functions */
static int saa7191_s_routing(struct v4l2_subdev *sd,
- const struct v4l2_routing *route)
+ u32 input, u32 output, u32 config)
{
struct saa7191 *decoder = to_saa7191(sd);
u8 luma = saa7191_read_reg(sd, SAA7191_REG_LUMA);
u8 iock = saa7191_read_reg(sd, SAA7191_REG_IOCK);
int err;
- switch (route->input) {
+ switch (input) {
case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
| SAA7191_IOCK_GPSW2);
@@ -190,7 +190,7 @@ static int saa7191_s_routing(struct v4l2_subdev *sd,
if (err)
return -EIO;
- decoder->input = route->input;
+ decoder->input = input;
return 0;
}
@@ -582,9 +582,6 @@ static const struct v4l2_subdev_core_ops saa7191_core_ops = {
.g_chip_ident = saa7191_g_chip_ident,
.g_ctrl = saa7191_g_ctrl,
.s_ctrl = saa7191_s_ctrl,
-};
-
-static const struct v4l2_subdev_tuner_ops saa7191_tuner_ops = {
.s_std = saa7191_s_std,
};
@@ -597,7 +594,6 @@ static const struct v4l2_subdev_video_ops saa7191_video_ops = {
static const struct v4l2_subdev_ops saa7191_ops = {
.core = &saa7191_core_ops,
.video = &saa7191_video_ops,
- .tuner = &saa7191_tuner_ops,
};
static int saa7191_probe(struct i2c_client *client,
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 6d8bfd4d97e..0e890cc2337 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -764,7 +764,10 @@ static int soc_camera_s_register(struct file *file, void *fh,
static int device_register_link(struct soc_camera_device *icd)
{
- int ret = device_register(&icd->dev);
+ int ret = dev_set_name(&icd->dev, "%u-%u", icd->iface, icd->devnum);
+
+ if (!ret)
+ ret = device_register(&icd->dev);
if (ret < 0) {
/* Prevent calling device_unregister() */
@@ -1060,7 +1063,6 @@ int soc_camera_device_register(struct soc_camera_device *icd)
icd->devnum = num;
icd->dev.bus = &soc_camera_bus_type;
- dev_set_name(&icd->dev, "%u-%u", icd->iface, icd->devnum);
icd->dev.release = dummy_release;
icd->use_count = 0;
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
index fe1158094c2..d381fce3db4 100644
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/video/tda9840.c
@@ -192,7 +192,6 @@ static int tda9840_remove(struct i2c_client *client)
return 0;
}
-
static const struct i2c_device_id tda9840_id[] = {
{ "tda9840", 0 },
{ }
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index d61c56f42bc..d4a9ed45764 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -47,12 +47,11 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
/* makes a connection between the input-pin 'i' and the output-pin 'o' */
-static int tea6415c_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int tea6415c_s_routing(struct v4l2_subdev *sd,
+ u32 i, u32 o, u32 config)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
u8 byte = 0;
- u32 i = route->input;
- u32 o = route->output;
int ret;
v4l2_dbg(1, debug, sd, "i=%d, o=%d\n", i, o);
@@ -170,7 +169,6 @@ static int tea6415c_remove(struct i2c_client *client)
return 0;
}
-
static const struct i2c_device_id tea6415c_id[] = {
{ "tea6415c", 0 },
{ }
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
index 34922232402..ced6eadf347 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -48,15 +48,15 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
/* make a connection between the input 'i' and the output 'o'
with gain 'g' (note: i = 6 means 'mute') */
-static int tea6420_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int tea6420_s_routing(struct v4l2_subdev *sd,
+ u32 i, u32 o, u32 config)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- int i = route->input;
- int o = route->output & 0xf;
- int g = (route->output >> 4) & 0xf;
+ int g = (o >> 4) & 0xf;
u8 byte;
int ret;
+ o &= 0xf;
v4l2_dbg(1, debug, sd, "i=%d, o=%d, g=%d\n", i, o, g);
/* check if the parameters are valid */
@@ -133,13 +133,8 @@ static int tea6420_probe(struct i2c_client *client,
/* set initial values: set "mute"-input to all outputs at gain 0 */
err = 0;
- for (i = 1; i < 5; i++) {
- struct v4l2_routing route;
-
- route.input = 6;
- route.output = i;
- err += tea6420_s_routing(sd, &route);
- }
+ for (i = 1; i < 5; i++)
+ err += tea6420_s_routing(sd, 6, i, 0);
if (err) {
v4l_dbg(1, debug, client, "could not initialize tea6420\n");
return -ENODEV;
@@ -156,7 +151,6 @@ static int tea6420_remove(struct i2c_client *client)
return 0;
}
-
static const struct i2c_device_id tea6420_id[] = {
{ "tea6420", 0 },
{ }
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 72d41032742..78c377a399c 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -15,12 +15,12 @@
#include <linux/i2c.h>
#include <linux/types.h>
#include <linux/init.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/tuner.h>
#include <media/tuner-types.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include "mt20xx.h"
#include "tda8290.h"
#include "tea5761.h"
@@ -101,18 +101,6 @@ static inline struct tuner *to_tuner(struct v4l2_subdev *sd)
return container_of(sd, struct tuner, sd);
}
-/* standard i2c insmod options */
-static unsigned short normal_i2c[] = {
-#if defined(CONFIG_MEDIA_TUNER_TEA5761) || (defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE) && defined(MODULE))
- 0x10,
-#endif
- 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- I2C_CLIENT_END
-};
-
-I2C_CLIENT_INSMOD;
/* insmod options used at init time => read/only */
static unsigned int addr;
@@ -785,7 +773,7 @@ static int tuner_s_radio(struct v4l2_subdev *sd)
return 0;
}
-static int tuner_s_standby(struct v4l2_subdev *sd, u32 standby)
+static int tuner_s_standby(struct v4l2_subdev *sd)
{
struct tuner *t = to_tuner(sd);
struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
@@ -951,11 +939,6 @@ static int tuner_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
static int tuner_suspend(struct i2c_client *c, pm_message_t state)
{
struct tuner *t = to_tuner(i2c_get_clientdata(c));
@@ -980,15 +963,28 @@ static int tuner_resume(struct i2c_client *c)
return 0;
}
+static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ /* TUNER_SET_CONFIG is still called by tuner-simple.c, so we have
+ to handle it here.
+ There must be a better way of doing this... */
+ switch (cmd) {
+ case TUNER_SET_CONFIG:
+ return tuner_s_config(sd, arg);
+ }
+ return -ENOIOCTLCMD;
+}
+
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tuner_core_ops = {
.log_status = tuner_log_status,
- .s_standby = tuner_s_standby,
+ .s_std = tuner_s_std,
};
static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
- .s_std = tuner_s_std,
.s_radio = tuner_s_radio,
.g_tuner = tuner_g_tuner,
.s_tuner = tuner_s_tuner,
@@ -996,6 +992,7 @@ static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
.g_frequency = tuner_g_frequency,
.s_type_addr = tuner_s_type_addr,
.s_config = tuner_s_config,
+ .s_standby = tuner_s_standby,
};
static const struct v4l2_subdev_ops tuner_ops = {
@@ -1023,7 +1020,7 @@ static void tuner_lookup(struct i2c_adapter *adap,
int mode_mask;
if (pos->i2c->adapter != adap ||
- pos->i2c->driver->id != I2C_DRIVERID_TUNER)
+ strcmp(pos->i2c->driver->driver.name, "tuner"))
continue;
mode_mask = pos->mode_mask & ~T_STANDBY;
@@ -1167,40 +1164,6 @@ register_client:
return 0;
}
-static int tuner_legacy_probe(struct i2c_adapter *adap)
-{
- if (0 != addr) {
- normal_i2c[0] = addr;
- normal_i2c[1] = I2C_CLIENT_END;
- }
-
- if ((adap->class & I2C_CLASS_TV_ANALOG) == 0)
- return 0;
-
- /* HACK: Ignore 0x6b and 0x6f on cx88 boards.
- * FusionHDTV5 RT Gold has an ir receiver at 0x6b
- * and an RTC at 0x6f which can get corrupted if probed.
- */
- if ((adap->id == I2C_HW_B_CX2388x) ||
- (adap->id == I2C_HW_B_CX23885)) {
- unsigned int i = 0;
-
- while (i < I2C_CLIENT_MAX_OPTS && ignore[i] != I2C_CLIENT_END)
- i += 2;
- if (i + 4 < I2C_CLIENT_MAX_OPTS) {
- ignore[i+0] = adap->nr;
- ignore[i+1] = 0x6b;
- ignore[i+2] = adap->nr;
- ignore[i+3] = 0x6f;
- ignore[i+4] = I2C_CLIENT_END;
- } else
- printk(KERN_WARNING "tuner: "
- "too many options specified "
- "in i2c probe ignore list!\n");
- }
- return 1;
-}
-
static int tuner_remove(struct i2c_client *client)
{
struct tuner *t = to_tuner(i2c_get_clientdata(client));
@@ -1227,13 +1190,11 @@ MODULE_DEVICE_TABLE(i2c, tuner_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tuner",
- .driverid = I2C_DRIVERID_TUNER,
- .command = tuner_command,
.probe = tuner_probe,
.remove = tuner_remove,
+ .command = tuner_command,
.suspend = tuner_suspend,
.resume = tuner_resume,
- .legacy_probe = tuner_legacy_probe,
.id_table = tuner_id,
};
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 226bf3565ac..0869bafc2b5 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -35,7 +35,7 @@
#include <media/tvaudio.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include <media/i2c-addr.h>
@@ -136,20 +136,6 @@ static inline struct CHIPSTATE *to_state(struct v4l2_subdev *sd)
return container_of(sd, struct CHIPSTATE, sd);
}
-/* ---------------------------------------------------------------------- */
-/* i2c addresses */
-
-static unsigned short normal_i2c[] = {
- I2C_ADDR_TDA8425 >> 1,
- I2C_ADDR_TEA6300 >> 1,
- I2C_ADDR_TEA6420 >> 1,
- I2C_ADDR_TDA9840 >> 1,
- I2C_ADDR_TDA985x_L >> 1,
- I2C_ADDR_TDA985x_H >> 1,
- I2C_ADDR_TDA9874 >> 1,
- I2C_ADDR_PIC16C54 >> 1,
- I2C_CLIENT_END };
-I2C_CLIENT_INSMOD;
/* ---------------------------------------------------------------------- */
/* i2c I/O functions */
@@ -1795,17 +1781,18 @@ static int tvaudio_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
return -EINVAL;
}
-static int tvaudio_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *rt)
+static int tvaudio_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct CHIPSTATE *chip = to_state(sd);
struct CHIPDESC *desc = chip->desc;
if (!(desc->flags & CHIP_HAS_INPUTSEL))
return 0;
- if (rt->input >= 4)
+ if (input >= 4)
return -EINVAL;
/* There are four inputs: tuner, radio, extern and intern. */
- chip->input = rt->input;
+ chip->input = input;
if (chip->muted)
return 0;
chip_write_masked(chip, desc->inputreg,
@@ -1918,11 +1905,6 @@ static int tvaudio_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ide
return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVAUDIO, 0);
}
-static int tvaudio_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tvaudio_core_ops = {
@@ -1930,12 +1912,12 @@ static const struct v4l2_subdev_core_ops tvaudio_core_ops = {
.queryctrl = tvaudio_queryctrl,
.g_ctrl = tvaudio_g_ctrl,
.s_ctrl = tvaudio_s_ctrl,
+ .s_std = tvaudio_s_std,
};
static const struct v4l2_subdev_tuner_ops tvaudio_tuner_ops = {
.s_radio = tvaudio_s_radio,
.s_frequency = tvaudio_s_frequency,
- .s_std = tvaudio_s_std,
.s_tuner = tvaudio_s_tuner,
.s_tuner = tvaudio_g_tuner,
};
@@ -2088,17 +2070,6 @@ static int tvaudio_remove(struct i2c_client *client)
return 0;
}
-static int tvaudio_legacy_probe(struct i2c_adapter *adap)
-{
- /* don't attach on saa7146 based cards,
- because dedicated drivers are used */
- if ((adap->id == I2C_HW_SAA7146))
- return 0;
- if (adap->class & I2C_CLASS_TV_ANALOG)
- return 1;
- return 0;
-}
-
/* This driver supports many devices and the idea is to let the driver
detect which device is present. So rather than listing all supported
devices here, we pretend to support a single, fake device type. */
@@ -2110,10 +2081,7 @@ MODULE_DEVICE_TABLE(i2c, tvaudio_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tvaudio",
- .driverid = I2C_DRIVERID_TVAUDIO,
- .command = tvaudio_command,
.probe = tvaudio_probe,
.remove = tvaudio_remove,
- .legacy_probe = tvaudio_legacy_probe,
.id_table = tvaudio_id,
};
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 3a5a95f134b..2d38e253f14 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -10,7 +10,7 @@
#include <linux/delay.h>
#include <media/v4l2-device.h>
#include <media/tvp5150.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include <media/v4l2-chip-ident.h>
#include "tvp5150_reg.h"
@@ -19,14 +19,6 @@ MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver");
MODULE_AUTHOR("Mauro Carvalho Chehab");
MODULE_LICENSE("GPL");
-/* standard i2c insmod options */
-static unsigned short normal_i2c[] = {
- 0xb8 >> 1,
- 0xba >> 1,
- I2C_CLIENT_END
-};
-
-I2C_CLIENT_INSMOD;
static int debug;
module_param(debug, int, 0);
@@ -77,7 +69,8 @@ struct tvp5150 {
struct v4l2_subdev sd;
v4l2_std_id norm; /* Current set standard */
- struct v4l2_routing route;
+ u32 input;
+ u32 output;
int enable;
int bright;
int contrast;
@@ -288,10 +281,10 @@ static inline void tvp5150_selmux(struct v4l2_subdev *sd)
int input = 0;
unsigned char val;
- if ((decoder->route.output & TVP5150_BLACK_SCREEN) || !decoder->enable)
+ if ((decoder->output & TVP5150_BLACK_SCREEN) || !decoder->enable)
input = 8;
- switch (decoder->route.input) {
+ switch (decoder->input) {
case TVP5150_COMPOSITE1:
input |= 2;
/* fall through */
@@ -307,8 +300,8 @@ static inline void tvp5150_selmux(struct v4l2_subdev *sd)
v4l2_dbg(1, debug, sd, "Selecting video route: route input=%i, output=%i "
"=> tvp5150 input=%i, opmode=%i\n",
- decoder->route.input,decoder->route.output,
- input, opmode );
+ decoder->input, decoder->output,
+ input, opmode);
tvp5150_write(sd, TVP5150_OP_MODE_CTL, opmode);
tvp5150_write(sd, TVP5150_VD_IN_SRC_SEL_1, input);
@@ -317,7 +310,7 @@ static inline void tvp5150_selmux(struct v4l2_subdev *sd)
* For Composite and TV, it should be the reverse
*/
val = tvp5150_read(sd, TVP5150_MISC_CTL);
- if (decoder->route.input == TVP5150_SVIDEO)
+ if (decoder->input == TVP5150_SVIDEO)
val = (val & ~0x40) | 0x10;
else
val = (val & ~0x10) | 0x40;
@@ -886,11 +879,13 @@ static int tvp5150_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
I2C Command
****************************************************************************/
-static int tvp5150_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int tvp5150_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct tvp5150 *decoder = to_tvp5150(sd);
- decoder->route = *route;
+ decoder->input = input;
+ decoder->output = output;
tvp5150_selmux(sd);
return 0;
}
@@ -1026,11 +1021,6 @@ static int tvp5150_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
return -EINVAL;
}
-static int tvp5150_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tvp5150_core_ops = {
@@ -1038,6 +1028,7 @@ static const struct v4l2_subdev_core_ops tvp5150_core_ops = {
.g_ctrl = tvp5150_g_ctrl,
.s_ctrl = tvp5150_s_ctrl,
.queryctrl = tvp5150_queryctrl,
+ .s_std = tvp5150_s_std,
.reset = tvp5150_reset,
.g_chip_ident = tvp5150_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -1047,7 +1038,6 @@ static const struct v4l2_subdev_core_ops tvp5150_core_ops = {
};
static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = {
- .s_std = tvp5150_s_std,
.g_tuner = tvp5150_g_tuner,
};
@@ -1090,7 +1080,7 @@ static int tvp5150_probe(struct i2c_client *c,
c->addr << 1, c->adapter->name);
core->norm = V4L2_STD_ALL; /* Default is autodetect */
- core->route.input = TVP5150_COMPOSITE1;
+ core->input = TVP5150_COMPOSITE1;
core->enable = 1;
core->bright = 128;
core->contrast = 128;
@@ -1125,9 +1115,7 @@ MODULE_DEVICE_TABLE(i2c, tvp5150_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tvp5150",
- .command = tvp5150_command,
.probe = tvp5150_probe,
.remove = tvp5150_remove,
- .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
.id_table = tvp5150_id,
};
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index c0ac651bb35..a07a3fbb51e 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -124,17 +124,18 @@ static int upd64031a_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *
/* ------------------------------------------------------------------------ */
-static int upd64031a_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int upd64031a_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct upd64031a_state *state = to_state(sd);
u8 r00, r05, r08;
- state->gr_mode = (route->input & 3) << 6;
- state->direct_3dycs_connect = (route->input & 0xc) << 4;
+ state->gr_mode = (input & 3) << 6;
+ state->direct_3dycs_connect = (input & 0xc) << 4;
state->ext_comp_sync =
- (route->input & UPD64031A_COMPOSITE_EXTERNAL) << 1;
+ (input & UPD64031A_COMPOSITE_EXTERNAL) << 1;
state->ext_vert_sync =
- (route->input & UPD64031A_VERTICAL_EXTERNAL) << 2;
+ (input & UPD64031A_VERTICAL_EXTERNAL) << 2;
r00 = (state->regs[R00] & ~GR_MODE_MASK) | state->gr_mode;
r05 = (state->regs[R00] & ~SYNC_CIRCUIT_MASK) |
state->ext_comp_sync | state->ext_vert_sync;
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 410c915d51f..6eb0e5b00c3 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -102,15 +102,16 @@ static u8 upd64083_read(struct v4l2_subdev *sd, u8 reg)
/* ------------------------------------------------------------------------ */
-static int upd64083_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int upd64083_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct upd64083_state *state = to_state(sd);
u8 r00, r02;
- if (route->input > 7 || (route->input & 6) == 6)
+ if (input > 7 || (input & 6) == 6)
return -EINVAL;
- state->mode = (route->input & 3) << 6;
- state->ext_y_adc = (route->input & UPD64083_EXT_Y_ADC) << 3;
+ state->mode = (input & 3) << 6;
+ state->ext_y_adc = (input & UPD64083_EXT_Y_ADC) << 3;
r00 = (state->regs[R00] & ~(3 << 6)) | state->mode;
r02 = (state->regs[R02] & ~(1 << 5)) | state->ext_y_adc;
upd64083_write(sd, R00, r00);
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index a0feb1c9773..8bc03b9e131 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -2597,7 +2597,6 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel)
/* inputs #1 and #2 are variable for SAA7111 and SAA7113 */
int mode[4]= {SAA7115_COMPOSITE0, 0, 0, SAA7115_COMPOSITE3};
int audio[]= {1, 0, 0, 0};
- struct v4l2_routing route;
//channel 0 is TV with audiochannel 1 (tuner mono)
//channel 1 is Composite with audio channel 0 (line in)
//channel 2 is S-Video with audio channel 0 (line in)
@@ -2630,9 +2629,7 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel)
mode[2] = SAA7115_SVIDEO1;
break;
}
- route.input = mode[channel];
- route.output = 0;
- call_all(usbvision, video, s_routing, &route);
+ call_all(usbvision, video, s_routing, mode[channel], 0, 0);
usbvision_set_audio(usbvision, audio[channel]);
return 0;
}
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index dd2f8f27c73..1fe5befbbf8 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -28,7 +28,6 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/slab.h>
-#include <linux/version.h>
#include <linux/utsname.h>
#include <linux/init.h>
#include <asm/uaccess.h>
@@ -247,7 +246,8 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
switch (usbvision_device_data[usbvision->DevModel].Codec) {
case CODEC_SAA7113:
case CODEC_SAA7111:
- v4l2_i2c_new_probed_subdev(&usbvision->i2c_adap, "saa7115",
+ v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev,
+ &usbvision->i2c_adap, "saa7115",
"saa7115_auto", saa711x_addrs);
break;
}
@@ -256,13 +256,15 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
enum v4l2_i2c_tuner_type type;
struct tuner_setup tun_setup;
- sd = v4l2_i2c_new_probed_subdev(&usbvision->i2c_adap, "tuner",
+ sd = v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev,
+ &usbvision->i2c_adap, "tuner",
"tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
/* depending on whether we found a demod or not, select
the tuner type. */
type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
- sd = v4l2_i2c_new_probed_subdev(&usbvision->i2c_adap, "tuner",
+ sd = v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev,
+ &usbvision->i2c_adap, "tuner",
"tuner", v4l2_i2c_tuner_addrs(type));
if (usbvision->tuner_type != -1) {
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index fa62a2fd7b2..d7056a5b7f9 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -1,5 +1,5 @@
/*
- * USB USBVISION Video device driver 0.9.9
+ * USB USBVISION Video device driver 0.9.10
*
*
*
@@ -79,7 +79,7 @@
#define DRIVER_LICENSE "GPL"
#define USBVISION_DRIVER_VERSION_MAJOR 0
#define USBVISION_DRIVER_VERSION_MINOR 9
-#define USBVISION_DRIVER_VERSION_PATCHLEVEL 9
+#define USBVISION_DRIVER_VERSION_PATCHLEVEL 10
#define USBVISION_DRIVER_VERSION KERNEL_VERSION(USBVISION_DRIVER_VERSION_MAJOR,\
USBVISION_DRIVER_VERSION_MINOR,\
USBVISION_DRIVER_VERSION_PATCHLEVEL)
@@ -621,7 +621,7 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id)
usbvision->tvnormId=*id;
mutex_lock(&usbvision->lock);
- call_all(usbvision, tuner, s_std, usbvision->tvnormId);
+ call_all(usbvision, core, s_std, usbvision->tvnormId);
mutex_unlock(&usbvision->lock);
/* propagate the change to the decoder */
usbvision_muxsel(usbvision, usbvision->ctl_input);
@@ -1522,7 +1522,8 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
* Returns NULL on error, a pointer to usb_usbvision else.
*
*/
-static struct usb_usbvision *usbvision_alloc(struct usb_device *dev)
+static struct usb_usbvision *usbvision_alloc(struct usb_device *dev,
+ struct usb_interface *intf)
{
struct usb_usbvision *usbvision;
@@ -1531,7 +1532,7 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev)
return NULL;
usbvision->dev = dev;
- if (v4l2_device_register(&dev->dev, &usbvision->v4l2_dev))
+ if (v4l2_device_register(&intf->dev, &usbvision->v4l2_dev))
goto err_free;
mutex_init(&usbvision->lock); /* available */
@@ -1669,7 +1670,8 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
return -ENODEV;
}
- if ((usbvision = usbvision_alloc(dev)) == NULL) {
+ usbvision = usbvision_alloc(dev, intf);
+ if (usbvision == NULL) {
dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", __func__);
return -ENOMEM;
}
diff --git a/drivers/media/video/uvc/Kconfig b/drivers/media/video/uvc/Kconfig
index c2d9760de83..2956a763721 100644
--- a/drivers/media/video/uvc/Kconfig
+++ b/drivers/media/video/uvc/Kconfig
@@ -9,7 +9,7 @@ config USB_VIDEO_CLASS
config USB_VIDEO_CLASS_INPUT_EVDEV
bool "UVC input events device support"
default y
- depends on USB_VIDEO_CLASS && INPUT
+ depends on USB_VIDEO_CLASS=INPUT || INPUT=y
---help---
This option makes USB Video Class devices register an input device
to report button events.
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index b617bf05e2d..02f2a6d18b4 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -575,6 +575,8 @@ static noinline long v4l1_compat_get_input_info(
chan->norm = VIDEO_MODE_NTSC;
if (sid & V4L2_STD_SECAM)
chan->norm = VIDEO_MODE_SECAM;
+ if (sid == V4L2_STD_ALL)
+ chan->norm = VIDEO_MODE_AUTO;
}
done:
return err;
@@ -601,6 +603,9 @@ static noinline long v4l1_compat_set_input(
case VIDEO_MODE_SECAM:
sid = V4L2_STD_SECAM;
break;
+ case VIDEO_MODE_AUTO:
+ sid = V4L2_STD_ALL;
+ break;
}
if (0 != sid) {
err = drv(file, VIDIOC_S_STD, &sid);
@@ -804,9 +809,9 @@ static noinline long v4l1_compat_select_tuner(
t.index = tun->tuner;
- err = drv(file, VIDIOC_S_INPUT, &t);
+ err = drv(file, VIDIOC_S_TUNER, &t);
if (err < 0)
- dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %ld\n", err);
+ dprintk("VIDIOCSTUNER / VIDIOC_S_TUNER: %ld\n", err);
return err;
}
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 1da8cb836cb..f576ef66b80 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -739,33 +739,8 @@ EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
/* ----------------------------------------------------------------- */
-/* Helper function for I2C legacy drivers */
+/* I2C Helper functions */
-int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver,
- const char *name,
- int (*probe)(struct i2c_client *, const struct i2c_device_id *))
-{
- struct i2c_client *client;
- int err;
-
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
-
- client->addr = address;
- client->adapter = adapter;
- client->driver = driver;
- strlcpy(client->name, name, sizeof(client->name));
-
- err = probe(client, NULL);
- if (err == 0) {
- i2c_attach_client(client);
- } else {
- kfree(client);
- }
- return err != -ENOMEM ? 0 : err;
-}
-EXPORT_SYMBOL(v4l2_i2c_attach);
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
const struct v4l2_subdev_ops *ops)
@@ -785,18 +760,16 @@ EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
-/* Load an i2c sub-device. It assumes that i2c_get_adapdata(adapter)
- returns the v4l2_device and that i2c_get_clientdata(client)
- returns the v4l2_subdev. */
-struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter,
+/* Load an i2c sub-device. */
+struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
+ struct i2c_adapter *adapter,
const char *module_name, const char *client_type, u8 addr)
{
- struct v4l2_device *dev = i2c_get_adapdata(adapter);
struct v4l2_subdev *sd = NULL;
struct i2c_client *client;
struct i2c_board_info info;
- BUG_ON(!dev);
+ BUG_ON(!v4l2_dev);
if (module_name)
request_module(module_name);
@@ -823,7 +796,7 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter,
/* Register with the v4l2_device which increases the module's
use count as well. */
- if (v4l2_device_register_subdev(dev, sd))
+ if (v4l2_device_register_subdev(v4l2_dev, sd))
sd = NULL;
/* Decrease the module use count to match the first try_module_get. */
module_put(client->driver->driver.owner);
@@ -837,19 +810,17 @@ error:
}
EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
-/* Probe and load an i2c sub-device. It assumes that i2c_get_adapdata(adapter)
- returns the v4l2_device and that i2c_get_clientdata(client)
- returns the v4l2_subdev. */
-struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
+/* Probe and load an i2c sub-device. */
+struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct v4l2_device *v4l2_dev,
+ struct i2c_adapter *adapter,
const char *module_name, const char *client_type,
const unsigned short *addrs)
{
- struct v4l2_device *dev = i2c_get_adapdata(adapter);
struct v4l2_subdev *sd = NULL;
struct i2c_client *client = NULL;
struct i2c_board_info info;
- BUG_ON(!dev);
+ BUG_ON(!v4l2_dev);
if (module_name)
request_module(module_name);
@@ -875,7 +846,7 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
/* Register with the v4l2_device which increases the module's
use count as well. */
- if (v4l2_device_register_subdev(dev, sd))
+ if (v4l2_device_register_subdev(v4l2_dev, sd))
sd = NULL;
/* Decrease the module use count to match the first try_module_get. */
module_put(client->driver->driver.owner);
@@ -889,6 +860,17 @@ error:
}
EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev);
+struct v4l2_subdev *v4l2_i2c_new_probed_subdev_addr(struct v4l2_device *v4l2_dev,
+ struct i2c_adapter *adapter,
+ const char *module_name, const char *client_type, u8 addr)
+{
+ unsigned short addrs[2] = { addr, I2C_CLIENT_END };
+
+ return v4l2_i2c_new_probed_subdev(v4l2_dev, adapter,
+ module_name, client_type, addrs);
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev_addr);
+
/* Return i2c client address of v4l2_subdev. */
unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
{
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 91228b3df07..31eac66411d 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -229,7 +229,7 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
static int v4l2_open(struct inode *inode, struct file *filp)
{
struct video_device *vdev;
- int ret;
+ int ret = 0;
/* Check if the video device is available */
mutex_lock(&videodev_lock);
@@ -243,7 +243,9 @@ static int v4l2_open(struct inode *inode, struct file *filp)
/* and increase the device refcount */
video_get(vdev);
mutex_unlock(&videodev_lock);
- ret = vdev->fops->open(filp);
+ if (vdev->fops->open)
+ ret = vdev->fops->open(filp);
+
/* decrease the refcount in case of an error */
if (ret)
video_put(vdev);
@@ -254,7 +256,10 @@ static int v4l2_open(struct inode *inode, struct file *filp)
static int v4l2_release(struct inode *inode, struct file *filp)
{
struct video_device *vdev = video_devdata(filp);
- int ret = vdev->fops->release(filp);
+ int ret = 0;
+
+ if (vdev->fops->release)
+ vdev->fops->release(filp);
/* decrease the refcount unconditionally since the release()
return value is ignored. */
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index f41c6f506f4..88f10d6cbc9 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -275,32 +275,6 @@ static const char *v4l2_ioctls[] = {
};
#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
-static const char *v4l2_int_ioctls[] = {
- [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
-
- [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
- [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
- [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG",
-
- [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
- [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
- [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
- [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
- [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
- [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
- [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
- [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
- [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
- [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
- [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
- [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
- [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ",
- [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT",
- [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT",
- [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT",
-};
-#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
-
/* Common ioctl debug function. This function can be used by
external ioctl messages as well as internal V4L ioctl */
void v4l_printk_ioctl(unsigned int cmd)
@@ -309,12 +283,8 @@ void v4l_printk_ioctl(unsigned int cmd)
switch (_IOC_TYPE(cmd)) {
case 'd':
- if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) {
- type = "v4l2_int";
- break;
- }
- printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]);
- return;
+ type = "v4l2_int";
+ break;
#ifdef CONFIG_VIDEO_V4L1_COMPAT
case 'v':
if (_IOC_NR(cmd) >= V4L1_IOCTLS) {
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
deleted file mode 100644
index dc881671d53..00000000000
--- a/drivers/media/video/v4l2-subdev.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- V4L2 sub-device support.
-
- Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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/types.h>
-#include <linux/ioctl.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-subdev.h>
-
-int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg)
-{
- switch (cmd) {
- case VIDIOC_QUERYCTRL:
- return v4l2_subdev_call(sd, core, queryctrl, arg);
- case VIDIOC_G_CTRL:
- return v4l2_subdev_call(sd, core, g_ctrl, arg);
- case VIDIOC_S_CTRL:
- return v4l2_subdev_call(sd, core, s_ctrl, arg);
- case VIDIOC_G_EXT_CTRLS:
- return v4l2_subdev_call(sd, core, g_ext_ctrls, arg);
- case VIDIOC_S_EXT_CTRLS:
- return v4l2_subdev_call(sd, core, s_ext_ctrls, arg);
- case VIDIOC_TRY_EXT_CTRLS:
- return v4l2_subdev_call(sd, core, try_ext_ctrls, arg);
- case VIDIOC_QUERYMENU:
- return v4l2_subdev_call(sd, core, querymenu, arg);
- case VIDIOC_LOG_STATUS:
- return v4l2_subdev_call(sd, core, log_status);
- case VIDIOC_DBG_G_CHIP_IDENT:
- return v4l2_subdev_call(sd, core, g_chip_ident, arg);
- case VIDIOC_INT_S_STANDBY:
- return v4l2_subdev_call(sd, core, s_standby, arg ? (*(u32 *)arg) : 0);
- case VIDIOC_INT_RESET:
- return v4l2_subdev_call(sd, core, reset, arg ? (*(u32 *)arg) : 0);
- case VIDIOC_INT_S_GPIO:
- return v4l2_subdev_call(sd, core, s_gpio, arg ? (*(u32 *)arg) : 0);
- case VIDIOC_INT_INIT:
- return v4l2_subdev_call(sd, core, init, arg ? (*(u32 *)arg) : 0);
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_DBG_G_REGISTER:
- return v4l2_subdev_call(sd, core, g_register, arg);
- case VIDIOC_DBG_S_REGISTER:
- return v4l2_subdev_call(sd, core, s_register, arg);
-#endif
-
- case VIDIOC_INT_S_TUNER_MODE:
- return v4l2_subdev_call(sd, tuner, s_mode, *(enum v4l2_tuner_type *)arg);
- case AUDC_SET_RADIO:
- return v4l2_subdev_call(sd, tuner, s_radio);
- case VIDIOC_S_TUNER:
- return v4l2_subdev_call(sd, tuner, s_tuner, arg);
- case VIDIOC_G_TUNER:
- return v4l2_subdev_call(sd, tuner, g_tuner, arg);
- case VIDIOC_S_STD:
- return v4l2_subdev_call(sd, tuner, s_std, *(v4l2_std_id *)arg);
- case VIDIOC_S_FREQUENCY:
- return v4l2_subdev_call(sd, tuner, s_frequency, arg);
- case VIDIOC_G_FREQUENCY:
- return v4l2_subdev_call(sd, tuner, g_frequency, arg);
- case TUNER_SET_TYPE_ADDR:
- return v4l2_subdev_call(sd, tuner, s_type_addr, arg);
- case TUNER_SET_CONFIG:
- return v4l2_subdev_call(sd, tuner, s_config, arg);
-
- case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- return v4l2_subdev_call(sd, audio, s_clock_freq, *(u32 *)arg);
- case VIDIOC_INT_S_AUDIO_ROUTING:
- return v4l2_subdev_call(sd, audio, s_routing, arg);
- case VIDIOC_INT_I2S_CLOCK_FREQ:
- return v4l2_subdev_call(sd, audio, s_i2s_clock_freq, *(u32 *)arg);
-
- case VIDIOC_INT_S_VIDEO_ROUTING:
- return v4l2_subdev_call(sd, video, s_routing, arg);
- case VIDIOC_INT_S_CRYSTAL_FREQ:
- return v4l2_subdev_call(sd, video, s_crystal_freq, arg);
- case VIDIOC_INT_DECODE_VBI_LINE:
- return v4l2_subdev_call(sd, video, decode_vbi_line, arg);
- case VIDIOC_INT_S_VBI_DATA:
- return v4l2_subdev_call(sd, video, s_vbi_data, arg);
- case VIDIOC_INT_G_VBI_DATA:
- return v4l2_subdev_call(sd, video, g_vbi_data, arg);
- case VIDIOC_G_SLICED_VBI_CAP:
- return v4l2_subdev_call(sd, video, g_sliced_vbi_cap, arg);
- case VIDIOC_ENUM_FMT:
- return v4l2_subdev_call(sd, video, enum_fmt, arg);
- case VIDIOC_TRY_FMT:
- return v4l2_subdev_call(sd, video, try_fmt, arg);
- case VIDIOC_S_FMT:
- return v4l2_subdev_call(sd, video, s_fmt, arg);
- case VIDIOC_G_FMT:
- return v4l2_subdev_call(sd, video, g_fmt, arg);
- case VIDIOC_INT_S_STD_OUTPUT:
- return v4l2_subdev_call(sd, video, s_std_output, *(v4l2_std_id *)arg);
- case VIDIOC_QUERYSTD:
- return v4l2_subdev_call(sd, video, querystd, arg);
- case VIDIOC_INT_G_INPUT_STATUS:
- return v4l2_subdev_call(sd, video, g_input_status, arg);
- case VIDIOC_STREAMON:
- return v4l2_subdev_call(sd, video, s_stream, 1);
- case VIDIOC_STREAMOFF:
- return v4l2_subdev_call(sd, video, s_stream, 0);
- case VIDIOC_S_PARM:
- return v4l2_subdev_call(sd, video, s_parm, arg);
- case VIDIOC_G_PARM:
- return v4l2_subdev_call(sd, video, g_parm, arg);
-
- default:
- return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
- }
-}
-EXPORT_SYMBOL_GPL(v4l2_subdev_command);
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 8da4dd1e0e9..43e0998adb5 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -60,8 +60,8 @@
// #define VINO_DEBUG
// #define VINO_DEBUG_INT
-#define VINO_MODULE_VERSION "0.0.5"
-#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 5)
+#define VINO_MODULE_VERSION "0.0.6"
+#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 6)
MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver");
MODULE_VERSION(VINO_MODULE_VERSION);
@@ -2565,12 +2565,11 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
int input;
int data_norm;
v4l2_std_id norm;
- struct v4l2_routing route = { 0, 0 };
input = VINO_INPUT_COMPOSITE;
- route.input = vino_get_saa7191_input(input);
- ret = decoder_call(video, s_routing, &route);
+ ret = decoder_call(video, s_routing,
+ vino_get_saa7191_input(input), 0, 0);
if (ret) {
ret = -EINVAL;
goto out;
@@ -2589,7 +2588,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
}
if (data_norm == 3)
data_norm = VINO_DATA_NORM_PAL;
- ret = decoder_call(tuner, s_std, norm);
+ ret = decoder_call(core, s_std, norm);
}
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
@@ -2656,10 +2655,9 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
if (vino_drvdata->decoder_owner == vcs->channel) {
int data_norm;
v4l2_std_id norm;
- struct v4l2_routing route = { 0, 0 };
- route.input = vino_get_saa7191_input(input);
- ret = decoder_call(video, s_routing, &route);
+ ret = decoder_call(video, s_routing,
+ vino_get_saa7191_input(input), 0, 0);
if (ret) {
vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
ret = -EINVAL;
@@ -2679,7 +2677,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
}
if (data_norm == 3)
data_norm = VINO_DATA_NORM_PAL;
- ret = decoder_call(tuner, s_std, norm);
+ ret = decoder_call(core, s_std, norm);
}
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
@@ -2813,7 +2811,7 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs,
* as it may take a while... */
norm = vino_data_norms[data_norm].std;
- err = decoder_call(tuner, s_std, norm);
+ err = decoder_call(core, s_std, norm);
spin_lock_irqsave(&vino_drvdata->input_lock, *flags);
@@ -4266,7 +4264,6 @@ static int vino_init_channel_settings(struct vino_channel_settings *vcs,
static int __init vino_module_init(void)
{
- unsigned short addr[] = { 0, I2C_CLIENT_END };
int ret;
printk(KERN_INFO "SGI VINO driver version %s\n",
@@ -4336,12 +4333,12 @@ static int __init vino_module_init(void)
}
vino_init_stage++;
- addr[0] = 0x45;
- vino_drvdata->decoder = v4l2_i2c_new_probed_subdev(&vino_i2c_adapter,
- "saa7191", "saa7191", addr);
- addr[0] = 0x2b;
- vino_drvdata->camera = v4l2_i2c_new_probed_subdev(&vino_i2c_adapter,
- "indycam", "indycam", addr);
+ vino_drvdata->decoder =
+ v4l2_i2c_new_probed_subdev_addr(&vino_drvdata->v4l2_dev,
+ &vino_i2c_adapter, "saa7191", "saa7191", 0x45);
+ vino_drvdata->camera =
+ v4l2_i2c_new_probed_subdev_addr(&vino_drvdata->v4l2_dev,
+ &vino_i2c_adapter, "indycam", "indycam", 0x2b);
dprintk("init complete!\n");
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
index 42e23a4fa60..38e53b303cc 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/video/vp27smpx.c
@@ -134,11 +134,11 @@ static int vp27smpx_log_status(struct v4l2_subdev *sd)
static const struct v4l2_subdev_core_ops vp27smpx_core_ops = {
.log_status = vp27smpx_log_status,
.g_chip_ident = vp27smpx_g_chip_ident,
+ .s_std = vp27smpx_s_std,
};
static const struct v4l2_subdev_tuner_ops vp27smpx_tuner_ops = {
.s_radio = vp27smpx_s_radio,
- .s_std = vp27smpx_s_std,
.s_tuner = vp27smpx_s_tuner,
.g_tuner = vp27smpx_g_tuner,
};
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 2fa7e8bb574..97e0ce28ff1 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -376,33 +376,34 @@ static int vpx3220_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
return 0;
}
-static int vpx3220_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int vpx3220_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
int data;
- /* RJ: route->input = 0: ST8 (PCTV) input
- route->input = 1: COMPOSITE input
- route->input = 2: SVHS input */
+ /* RJ: input = 0: ST8 (PCTV) input
+ input = 1: COMPOSITE input
+ input = 2: SVHS input */
- const int input[3][2] = {
+ const int input_vals[3][2] = {
{0x0c, 0},
{0x0d, 0},
{0x0e, 1}
};
- if (route->input < 0 || route->input > 2)
+ if (input < 0 || input > 2)
return -EINVAL;
- v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[route->input]);
+ v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[input]);
- vpx3220_write(sd, 0x33, input[route->input][0]);
+ vpx3220_write(sd, 0x33, input_vals[input][0]);
data = vpx3220_fp_read(sd, 0xf2) & ~(0x0020);
if (data < 0)
return data;
/* 0x0010 is required to latch the setting */
vpx3220_fp_write(sd, 0xf2,
- data | (input[route->input][1] << 5) | 0x0010);
+ data | (input_vals[input][1] << 5) | 0x0010);
udelay(10);
return 0;
@@ -516,9 +517,6 @@ static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
.g_ctrl = vpx3220_g_ctrl,
.s_ctrl = vpx3220_s_ctrl,
.queryctrl = vpx3220_queryctrl,
-};
-
-static const struct v4l2_subdev_tuner_ops vpx3220_tuner_ops = {
.s_std = vpx3220_s_std,
};
@@ -531,7 +529,6 @@ static const struct v4l2_subdev_video_ops vpx3220_video_ops = {
static const struct v4l2_subdev_ops vpx3220_ops = {
.core = &vpx3220_core_ops,
- .tuner = &vpx3220_tuner_ops,
.video = &vpx3220_video_ops,
};
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 3b08bc4af90..f59b2bd07e8 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -3440,7 +3440,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
if (!cam)
return -ENOMEM;
- err = v4l2_device_register(&udev->dev, &cam->v4l2_dev);
+ err = v4l2_device_register(&intf->dev, &cam->v4l2_dev);
if (err)
goto fail0;
@@ -3523,7 +3523,8 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
w9968cf_turn_on_led(cam);
w9968cf_i2c_init(cam);
- cam->sensor_sd = v4l2_i2c_new_probed_subdev(&cam->i2c_adapter,
+ cam->sensor_sd = v4l2_i2c_new_probed_subdev(&cam->v4l2_dev,
+ &cam->i2c_adapter,
"ovcamchip", "ovcamchip", addrs);
usb_set_intfdata(intf, cam);
diff --git a/drivers/media/video/w9968cf.h b/drivers/media/video/w9968cf.h
index fdfc6a4e1c8..73ad864b484 100644
--- a/drivers/media/video/w9968cf.h
+++ b/drivers/media/video/w9968cf.h
@@ -134,7 +134,7 @@ static const struct w9968cf_format w9968cf_formatlist[] = {
#define W9968CF_MODULE_NAME "V4L driver for W996[87]CF JPEG USB " \
"Dual Mode Camera Chip"
-#define W9968CF_MODULE_VERSION "1:1.33-basic"
+#define W9968CF_MODULE_VERSION "1:1.34-basic"
#define W9968CF_MODULE_AUTHOR "(C) 2002-2004 Luca Risolia"
#define W9968CF_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
#define W9968CF_MODULE_LICENSE "GPL"
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index eddf11abe1d..f1f261a3524 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -79,7 +79,8 @@ static int wm8775_write(struct v4l2_subdev *sd, int reg, u16 val)
return -1;
}
-static int wm8775_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int wm8775_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct wm8775_state *state = to_state(sd);
@@ -88,11 +89,11 @@ static int wm8775_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *r
16 combinations.
If only one input is active (the normal case) then the
input values 1, 2, 4 or 8 should be used. */
- if (route->input > 15) {
- v4l2_err(sd, "Invalid input %d.\n", route->input);
+ if (input > 15) {
+ v4l2_err(sd, "Invalid input %d.\n", input);
return -EINVAL;
}
- state->input = route->input;
+ state->input = input;
if (state->muted)
return 0;
wm8775_write(sd, R21, 0x0c0);
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h
index afecf32f1a8..d439c76b27e 100644
--- a/drivers/media/video/zoran/zoran.h
+++ b/drivers/media/video/zoran/zoran.h
@@ -143,8 +143,8 @@ Private IOCTL to set up for displaying MJPEG
#ifdef __KERNEL__
#define MAJOR_VERSION 0 /* driver major version */
-#define MINOR_VERSION 9 /* driver minor version */
-#define RELEASE_VERSION 5 /* release version */
+#define MINOR_VERSION 10 /* driver minor version */
+#define RELEASE_VERSION 0 /* release version */
#define ZORAN_NAME "ZORAN" /* name of the device */
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index f91bba435ed..ea6c577b0eb 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -1087,10 +1087,8 @@ zr36057_init (struct zoran *zr)
detect_guest_activity(zr);
test_interrupts(zr);
if (!pass_through) {
- struct v4l2_routing route = { 2, 0 };
-
decoder_call(zr, video, s_stream, 0);
- encoder_call(zr, video, s_routing, &route);
+ encoder_call(zr, video, s_routing, 2, 0, 0);
}
zr->zoran_proc = NULL;
@@ -1360,11 +1358,13 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
goto zr_free_irq;
}
- zr->decoder = v4l2_i2c_new_probed_subdev(&zr->i2c_adapter,
- zr->card.mod_decoder, zr->card.i2c_decoder, zr->card.addrs_decoder);
+ zr->decoder = v4l2_i2c_new_probed_subdev(&zr->v4l2_dev,
+ &zr->i2c_adapter, zr->card.mod_decoder, zr->card.i2c_decoder,
+ zr->card.addrs_decoder);
if (zr->card.mod_encoder)
- zr->encoder = v4l2_i2c_new_probed_subdev(&zr->i2c_adapter,
+ zr->encoder = v4l2_i2c_new_probed_subdev(&zr->v4l2_dev,
+ &zr->i2c_adapter,
zr->card.mod_encoder, zr->card.i2c_encoder,
zr->card.addrs_encoder);
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c
index e0223deed35..f6c2fb4fc3b 100644
--- a/drivers/media/video/zoran/zoran_device.c
+++ b/drivers/media/video/zoran/zoran_device.c
@@ -971,7 +971,6 @@ zr36057_enable_jpg (struct zoran *zr,
struct vfe_settings cap;
int field_size =
zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff;
- struct v4l2_routing route = { 0, 0 };
zr->codec_mode = mode;
@@ -994,8 +993,7 @@ zr36057_enable_jpg (struct zoran *zr,
*/
set_videobus_dir(zr, 0);
decoder_call(zr, video, s_stream, 1);
- route.input = 0;
- encoder_call(zr, video, s_routing, &route);
+ encoder_call(zr, video, s_routing, 0, 0, 0);
/* Take the JPEG codec and the VFE out of sleep */
jpeg_codec_sleep(zr, 0);
@@ -1043,8 +1041,7 @@ zr36057_enable_jpg (struct zoran *zr,
*/
decoder_call(zr, video, s_stream, 0);
set_videobus_dir(zr, 1);
- route.input = 1;
- encoder_call(zr, video, s_routing, &route);
+ encoder_call(zr, video, s_routing, 1, 0, 0);
/* Take the JPEG codec and the VFE out of sleep */
jpeg_codec_sleep(zr, 0);
@@ -1089,8 +1086,7 @@ zr36057_enable_jpg (struct zoran *zr,
zr36057_adjust_vfe(zr, mode);
decoder_call(zr, video, s_stream, 1);
- route.input = 0;
- encoder_call(zr, video, s_routing, &route);
+ encoder_call(zr, video, s_routing, 0, 0, 0);
dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr));
break;
@@ -1571,8 +1567,6 @@ zoran_set_pci_master (struct zoran *zr,
void
zoran_init_hardware (struct zoran *zr)
{
- struct v4l2_routing route = { 0, 0 };
-
/* Enable bus-mastering */
zoran_set_pci_master(zr, 1);
@@ -1581,16 +1575,14 @@ zoran_init_hardware (struct zoran *zr)
zr->card.init(zr);
}
- route.input = zr->card.input[zr->input].muxsel;
-
decoder_call(zr, core, init, 0);
- decoder_call(zr, tuner, s_std, zr->norm);
- decoder_call(zr, video, s_routing, &route);
+ decoder_call(zr, core, s_std, zr->norm);
+ decoder_call(zr, video, s_routing,
+ zr->card.input[zr->input].muxsel, 0, 0);
encoder_call(zr, core, init, 0);
encoder_call(zr, video, s_std_output, zr->norm);
- route.input = 0;
- encoder_call(zr, video, s_routing, &route);
+ encoder_call(zr, video, s_routing, 0, 0, 0);
/* toggle JPEG codec sleep to sync PLL */
jpeg_codec_sleep(zr, 1);
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index f16e57cf11e..092333b1c34 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -1018,10 +1018,8 @@ zoran_close(struct file *file)
zoran_set_pci_master(zr, 0);
if (!pass_through) { /* Switch to color bar */
- struct v4l2_routing route = { 2, 0 };
-
decoder_call(zr, video, s_stream, 0);
- encoder_call(zr, video, s_routing, &route);
+ encoder_call(zr, video, s_routing, 2, 0, 0);
}
}
@@ -1449,7 +1447,7 @@ zoran_set_norm (struct zoran *zr,
v4l2_std_id std = 0;
decoder_call(zr, video, querystd, &std);
- decoder_call(zr, tuner, s_std, std);
+ decoder_call(zr, core, s_std, std);
/* let changes come into effect */
ssleep(2);
@@ -1461,7 +1459,7 @@ zoran_set_norm (struct zoran *zr,
"%s: %s - no norm detected\n",
ZR_DEVNAME(zr), __func__);
/* reset norm */
- decoder_call(zr, tuner, s_std, zr->norm);
+ decoder_call(zr, core, s_std, zr->norm);
return -EIO;
}
@@ -1480,7 +1478,7 @@ zoran_set_norm (struct zoran *zr,
if (on)
zr36057_overlay(zr, 0);
- decoder_call(zr, tuner, s_std, norm);
+ decoder_call(zr, core, s_std, norm);
encoder_call(zr, video, s_std_output, norm);
if (on)
@@ -1496,8 +1494,6 @@ static int
zoran_set_input (struct zoran *zr,
int input)
{
- struct v4l2_routing route = { 0, 0 };
-
if (input == zr->input) {
return 0;
}
@@ -1519,10 +1515,10 @@ zoran_set_input (struct zoran *zr,
return -EINVAL;
}
- route.input = zr->card.input[input].muxsel;
zr->input = input;
- decoder_call(zr, video, s_routing, &route);
+ decoder_call(zr, video, s_routing,
+ zr->card.input[input].muxsel, 0, 0);
return 0;
}
@@ -1748,7 +1744,6 @@ jpgreqbuf_unlock_and_return:
case BUZIOC_G_STATUS:
{
struct zoran_status *bstat = arg;
- struct v4l2_routing route = { 0, 0 };
int status = 0, res = 0;
v4l2_std_id norm;
@@ -1762,8 +1757,6 @@ jpgreqbuf_unlock_and_return:
return -EINVAL;
}
- route.input = zr->card.input[bstat->input].muxsel;
-
mutex_lock(&zr->resource_lock);
if (zr->codec_mode != BUZ_MODE_IDLE) {
@@ -1775,7 +1768,8 @@ jpgreqbuf_unlock_and_return:
goto gstat_unlock_and_return;
}
- decoder_call(zr, video, s_routing, &route);
+ decoder_call(zr, video, s_routing,
+ zr->card.input[bstat->input].muxsel, 0, 0);
/* sleep 1 second */
ssleep(1);
@@ -1785,8 +1779,8 @@ jpgreqbuf_unlock_and_return:
decoder_call(zr, video, g_input_status, &status);
/* restore previous input and norm */
- route.input = zr->card.input[zr->input].muxsel;
- decoder_call(zr, video, s_routing, &route);
+ decoder_call(zr, video, s_routing,
+ zr->card.input[zr->input].muxsel, 0, 0);
gstat_unlock_and_return:
mutex_unlock(&zr->resource_lock);
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 221409fe168..ac169c9eb18 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -26,7 +26,6 @@
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb.h>
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index 2fb95a5b72e..f4a162a4bec 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -877,7 +877,7 @@ static int jmb38x_ms_probe(struct pci_dev *pdev,
int pci_dev_busy = 0;
int rc, cnt;
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc)
return rc;
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index ea3aafbbda4..d0d126c6935 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1534,13 +1534,13 @@ mpt_mapresources(MPT_ADAPTER *ioc)
pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)
- && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+ && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
ioc->name));
- } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)
- && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+ } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
+ && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
ioc->name));
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 12b732512e5..a9019f081b9 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -2279,9 +2279,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
mutex_lock(&ioc->sas_topology_mutex);
list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
- if (port_info->phy_info &&
- (!(port_info->phy_info[0].identify.device_info &
- MPI_SAS_DEVICE_INFO_SMP_TARGET)))
+ if (!(port_info->phy_info[0].identify.device_info &
+ MPI_SAS_DEVICE_INFO_SMP_TARGET))
continue;
if (mptsas_sas_expander_pg0(ioc, &buffer,
diff --git a/drivers/message/i2o/memory.c b/drivers/message/i2o/memory.c
index f5cc95c564e..292b41e49fb 100644
--- a/drivers/message/i2o/memory.c
+++ b/drivers/message/i2o/memory.c
@@ -185,9 +185,9 @@ int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len)
int dma_64 = 0;
mutex_lock(&mem_lock);
- if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) {
+ if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_BIT_MASK(64))) {
dma_64 = 1;
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
mutex_unlock(&mem_lock);
return -ENOMEM;
}
@@ -196,7 +196,7 @@ int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len)
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))
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
printk(KERN_WARNING "i2o: unable to set 64-bit DMA");
mutex_unlock(&mem_lock);
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
index 25d6f234198..35ba2ae38b4 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/message/i2o/pci.c
@@ -334,7 +334,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
return rc;
}
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "i2o: no suitable DMA found for %s\n",
pci_name(pdev));
rc = -ENODEV;
@@ -397,7 +397,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
}
#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
if (sizeof(dma_addr_t) > 4) {
- if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
printk(KERN_INFO "%s: 64-bit DMA unavailable\n",
c->name);
else {
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 06a2b0f7737..ee3927ab11e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -52,6 +52,7 @@ config HTC_EGPIO
config HTC_PASIC3
tristate "HTC PASIC3 LED/DS1WM chip support"
+ select MFD_CORE
help
This core driver provides register access for the LED/DS1WM
chips labeled "AIC2" and "AIC3", found on HTC Blueangel and
@@ -88,7 +89,7 @@ config MENELAUS
help
If you say yes here you get support for the Texas Instruments
TWL92330/Menelaus Power Management chip. This include voltage
- regulators, Dual slot memory card tranceivers, real-time clock
+ regulators, Dual slot memory card transceivers, real-time clock
and other features that are often used in portable devices like
cell phones and PDAs.
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c
index 99f8dcfe3d9..7283d88656a 100644
--- a/drivers/mfd/da903x.c
+++ b/drivers/mfd/da903x.c
@@ -413,7 +413,7 @@ static void da903x_irq_work(struct work_struct *work)
enable_irq(chip->client->irq);
}
-static int da903x_irq_handler(int irq, void *data)
+static irqreturn_t da903x_irq_handler(int irq, void *data)
{
struct da903x_chip *chip = data;
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
index 91b294dcc13..386da1566fc 100644
--- a/drivers/mfd/htc-pasic3.c
+++ b/drivers/mfd/htc-pasic3.c
@@ -12,18 +12,17 @@
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/ds1wm.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/ds1wm.h>
#include <linux/mfd/htc-pasic3.h>
struct pasic3_data {
void __iomem *mapping;
unsigned int bus_shift;
- struct platform_device *ds1wm_pdev;
- struct platform_device *led_pdev;
};
#define REG_ADDR 5
@@ -65,46 +64,15 @@ EXPORT_SYMBOL(pasic3_read_register); /* for leds-pasic3 */
* LEDs
*/
-static int led_device_add(struct device *pasic3_dev,
- const struct pasic3_leds_machinfo *pdata)
-{
- struct pasic3_data *asic = pasic3_dev->driver_data;
- struct platform_device *pdev;
- int ret;
-
- pdev = platform_device_alloc("pasic3-led", -1);
- if (!pdev) {
- dev_dbg(pasic3_dev, "failed to allocate LED platform device\n");
- return -ENOMEM;
- }
-
- ret = platform_device_add_data(pdev, pdata,
- sizeof(struct pasic3_leds_machinfo));
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add LED platform data\n");
- goto exit_pdev_put;
- }
-
- pdev->dev.parent = pasic3_dev;
- ret = platform_device_add(pdev);
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add LED platform device\n");
- goto exit_pdev_put;
- }
-
- asic->led_pdev = pdev;
- return 0;
-
-exit_pdev_put:
- platform_device_put(pdev);
- return ret;
-}
+static struct mfd_cell led_cell __initdata = {
+ .name = "leds-pasic3",
+};
/*
* DS1WM
*/
-static void ds1wm_enable(struct platform_device *pdev)
+static int ds1wm_enable(struct platform_device *pdev)
{
struct device *dev = pdev->dev.parent;
int c;
@@ -113,9 +81,10 @@ static void ds1wm_enable(struct platform_device *pdev)
pasic3_write_register(dev, 0x28, c & 0x7f);
dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & 0x7f);
+ return 0;
}
-static void ds1wm_disable(struct platform_device *pdev)
+static int ds1wm_disable(struct platform_device *pdev)
{
struct device *dev = pdev->dev.parent;
int c;
@@ -124,56 +93,33 @@ static void ds1wm_disable(struct platform_device *pdev)
pasic3_write_register(dev, 0x28, c | 0x80);
dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | 0x80);
+ return 0;
}
-static struct ds1wm_platform_data ds1wm_pdata = {
- .bus_shift = 2,
- .enable = ds1wm_enable,
- .disable = ds1wm_disable,
+static struct ds1wm_driver_data ds1wm_pdata = {
+ .active_high = 0,
};
-static int ds1wm_device_add(struct platform_device *pasic3_pdev, int bus_shift)
-{
- struct device *pasic3_dev = &pasic3_pdev->dev;
- struct pasic3_data *asic = pasic3_dev->driver_data;
- struct platform_device *pdev;
- int ret;
-
- pdev = platform_device_alloc("ds1wm", -1);
- if (!pdev) {
- dev_dbg(pasic3_dev, "failed to allocate DS1WM platform device\n");
- return -ENOMEM;
- }
-
- ret = platform_device_add_resources(pdev, pasic3_pdev->resource,
- pasic3_pdev->num_resources);
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add DS1WM resources\n");
- goto exit_pdev_put;
- }
-
- ds1wm_pdata.bus_shift = asic->bus_shift;
- ret = platform_device_add_data(pdev, &ds1wm_pdata,
- sizeof(struct ds1wm_platform_data));
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add DS1WM platform data\n");
- goto exit_pdev_put;
- }
-
- pdev->dev.parent = pasic3_dev;
- ret = platform_device_add(pdev);
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add DS1WM platform device\n");
- goto exit_pdev_put;
- }
-
- asic->ds1wm_pdev = pdev;
- return 0;
+static struct resource ds1wm_resources[] __initdata = {
+ [0] = {
+ .start = 0,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
-exit_pdev_put:
- platform_device_put(pdev);
- return ret;
-}
+static struct mfd_cell ds1wm_cell __initdata = {
+ .name = "ds1wm",
+ .enable = ds1wm_enable,
+ .disable = ds1wm_disable,
+ .driver_data = &ds1wm_pdata,
+ .num_resources = 2,
+ .resources = ds1wm_resources,
+};
static int __init pasic3_probe(struct platform_device *pdev)
{
@@ -182,12 +128,27 @@ static int __init pasic3_probe(struct platform_device *pdev)
struct pasic3_data *asic;
struct resource *r;
int ret;
+ int irq = 0;
+
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (r) {
+ ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags &
+ (IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE));
+ irq = r->start;
+ }
+
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (r) {
+ ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags &
+ (IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE));
+ irq = r->start;
+ }
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r)
return -ENXIO;
- if (!request_mem_region(r->start, r->end - r->start + 1, "pasic3"))
+ if (!request_mem_region(r->start, resource_size(r), "pasic3"))
return -EBUSY;
asic = kzalloc(sizeof(struct pasic3_data), GFP_KERNEL);
@@ -196,24 +157,33 @@ static int __init pasic3_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, asic);
- if (pdata && pdata->bus_shift)
- asic->bus_shift = pdata->bus_shift;
- else
- asic->bus_shift = 2;
-
- asic->mapping = ioremap(r->start, r->end - r->start + 1);
+ asic->mapping = ioremap(r->start, resource_size(r));
if (!asic->mapping) {
dev_err(dev, "couldn't ioremap PASIC3\n");
kfree(asic);
return -ENOMEM;
}
- ret = ds1wm_device_add(pdev, asic->bus_shift);
- if (ret < 0)
- dev_warn(dev, "failed to register DS1WM\n");
+ /* calculate bus shift from mem resource */
+ asic->bus_shift = (resource_size(r) - 5) >> 3;
+
+ if (pdata && pdata->clock_rate) {
+ ds1wm_pdata.clock_rate = pdata->clock_rate;
+ /* the first 5 PASIC3 registers control the DS1WM */
+ ds1wm_resources[0].end = (5 << asic->bus_shift) - 1;
+ ds1wm_cell.platform_data = &ds1wm_cell;
+ ds1wm_cell.data_size = sizeof(ds1wm_cell);
+ ret = mfd_add_devices(&pdev->dev, pdev->id,
+ &ds1wm_cell, 1, r, irq);
+ if (ret < 0)
+ dev_warn(dev, "failed to register DS1WM\n");
+ }
- if (pdata->led_pdata) {
- ret = led_device_add(dev, pdata->led_pdata);
+ if (pdata && pdata->led_pdata) {
+ led_cell.driver_data = pdata->led_pdata;
+ led_cell.platform_data = &led_cell;
+ led_cell.data_size = sizeof(ds1wm_cell);
+ ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0);
if (ret < 0)
dev_warn(dev, "failed to register LED device\n");
}
@@ -226,14 +196,11 @@ static int pasic3_remove(struct platform_device *pdev)
struct pasic3_data *asic = platform_get_drvdata(pdev);
struct resource *r;
- if (asic->led_pdev)
- platform_device_unregister(asic->led_pdev);
- if (asic->ds1wm_pdev)
- platform_device_unregister(asic->ds1wm_pdev);
+ mfd_remove_devices(&pdev->dev);
iounmap(asic->mapping);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(r->start, r->end - r->start + 1);
+ release_mem_region(r->start, resource_size(r));
kfree(asic);
return 0;
}
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 2e36057659e..7793932a513 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -15,7 +15,6 @@
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/sysfs.h>
-#include <linux/device.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/interrupt.h>
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 9f7024c0f8e..e9f4323dd2c 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -108,7 +108,7 @@ static int t7l66xb_mmc_disable(struct platform_device *mmc)
/*--------------------------------------------------------------------------*/
-const static struct resource t7l66xb_mmc_resources[] = {
+static const struct resource t7l66xb_mmc_resources[] = {
{
.start = 0x800,
.end = 0x9ff,
@@ -126,7 +126,7 @@ const static struct resource t7l66xb_mmc_resources[] = {
},
};
-const static struct resource t7l66xb_nand_resources[] = {
+static const struct resource t7l66xb_nand_resources[] = {
{
.start = 0xc00,
.end = 0xc07,
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index f856e9463a9..77a12fc8045 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -172,7 +172,7 @@ static struct resource __devinitdata tc6393xb_mmc_resources[] = {
},
};
-const static struct resource tc6393xb_ohci_resources[] = {
+static const struct resource tc6393xb_ohci_resources[] = {
{
.start = 0x3000,
.end = 0x31ff,
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index 68826f1e36b..ec90e953adc 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -592,11 +592,9 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
/* maybe add LDOs that are omitted on cost-reduced parts */
if (twl_has_regulator() && !(features & TPS_SUBSET)) {
- /*
child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
if (IS_ERR(child))
return PTR_ERR(child);
- */
child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2);
if (IS_ERR(child))
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index b1087603698..aca2670afd7 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -182,7 +182,7 @@ static int twl4030_irq_thread(void *data)
long irq = (long)data;
struct irq_desc *desc = irq_to_desc(irq);
static unsigned i2c_errors;
- const static unsigned max_i2c_errors = 100;
+ static const unsigned max_i2c_errors = 100;
if (!desc) {
pr_err("twl4030: Invalid IRQ: %ld\n", irq);
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index b457a05b28d..c2be3088e2e 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -1111,7 +1111,7 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
do {
schedule_timeout_interruptible(1);
reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
- } while (--tries && (reg & WM8350_AUXADC_POLL));
+ } while ((reg & WM8350_AUXADC_POLL) && --tries);
if (!tries)
dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
@@ -1238,7 +1238,7 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode)
}
wm8350->reg_cache =
- kzalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL);
+ kmalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL);
if (wm8350->reg_cache == NULL)
return -ENOMEM;
@@ -1246,17 +1246,20 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode)
* a PMIC so the device many not be in a virgin state and we
* can't rely on the silicon values.
*/
+ ret = wm8350->read_dev(wm8350, 0,
+ sizeof(u16) * (WM8350_MAX_REGISTER + 1),
+ wm8350->reg_cache);
+ if (ret < 0) {
+ dev_err(wm8350->dev,
+ "failed to read initial cache values\n");
+ goto out;
+ }
+
+ /* Mask out uncacheable/unreadable bits and the audio. */
for (i = 0; i < WM8350_MAX_REGISTER; i++) {
- /* audio register range */
if (wm8350_reg_io_map[i].readable &&
(i < WM8350_CLOCK_CONTROL_1 || i > WM8350_AIF_TEST)) {
- ret = wm8350->read_dev(wm8350, i, 2, (char *)&value);
- if (ret < 0) {
- dev_err(wm8350->dev,
- "failed to read initial cache value\n");
- goto out;
- }
- value = be16_to_cpu(value);
+ value = be16_to_cpu(wm8350->reg_cache[i]);
value &= wm8350_reg_io_map[i].readable;
value &= ~wm8350_reg_io_map[i].vol;
wm8350->reg_cache[i] = value;
@@ -1435,7 +1438,21 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
mutex_init(&wm8350->irq_mutex);
INIT_WORK(&wm8350->irq_work, wm8350_irq_worker);
if (irq) {
- ret = request_irq(irq, wm8350_irq, 0,
+ int flags = 0;
+
+ if (pdata && pdata->irq_high) {
+ flags |= IRQF_TRIGGER_HIGH;
+
+ wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
+ WM8350_IRQ_POL);
+ } else {
+ flags |= IRQF_TRIGGER_LOW;
+
+ wm8350_clear_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
+ WM8350_IRQ_POL);
+ }
+
+ ret = request_irq(irq, wm8350_irq, flags,
"wm8350", wm8350);
if (ret != 0) {
dev_err(wm8350->dev, "Failed to request IRQ: %d\n",
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 0b92b2f6ea6..6d1ac180f6e 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -18,8 +18,8 @@ config ATMEL_PWM
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
- purposes including software controlled power-efficent backlights
+ on certain Atmel processors. Pulse Width Modulation is used for
+ purposes including software controlled power-efficient backlights
on LCD displays, motor control, and waveform generation.
config ATMEL_TCLIB
@@ -142,7 +142,7 @@ config ATMEL_SSC
tristate "Device driver for Atmel SSC peripheral"
depends on AVR32 || ARCH_AT91
---help---
- This option enables device driver support for Atmel Syncronized
+ This option enables device driver support for Atmel Synchronized
Serial Communication peripheral (SSC).
The SSC peripheral supports a wide variety of serial frame based
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index d184dfab963..db39f4a52f5 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -278,7 +278,7 @@ static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr,
* We only use page mode writes; the alternative is sloooow. This routine
* writes at most one page.
*/
-static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf,
+static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf,
unsigned offset, size_t count)
{
struct i2c_client *client;
@@ -347,8 +347,8 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf,
return -ETIMEDOUT;
}
-static ssize_t at24_write(struct at24_data *at24,
- char *buf, loff_t off, size_t count)
+static ssize_t at24_write(struct at24_data *at24, const char *buf, loff_t off,
+ size_t count)
{
ssize_t retval = 0;
@@ -406,7 +406,7 @@ static ssize_t at24_macc_read(struct memory_accessor *macc, char *buf,
return at24_read(at24, buf, offset, count);
}
-static ssize_t at24_macc_write(struct memory_accessor *macc, char *buf,
+static ssize_t at24_macc_write(struct memory_accessor *macc, const char *buf,
off_t offset, size_t count)
{
struct at24_data *at24 = container_of(macc, struct at24_data, macc);
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index 6bc0dac5c1e..b34cb5f79ee 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -140,7 +140,8 @@ at25_bin_read(struct kobject *kobj, struct bin_attribute *bin_attr,
static ssize_t
-at25_ee_write(struct at25_data *at25, char *buf, loff_t off, size_t count)
+at25_ee_write(struct at25_data *at25, const char *buf, loff_t off,
+ size_t count)
{
ssize_t status = 0;
unsigned written = 0;
@@ -276,7 +277,7 @@ static ssize_t at25_mem_read(struct memory_accessor *mem, char *buf,
return at25_ee_read(at25, buf, offset, count);
}
-static ssize_t at25_mem_write(struct memory_accessor *mem, char *buf,
+static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf,
off_t offset, size_t count)
{
struct at25_data *at25 = container_of(mem, struct at25_data, mem);
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
index 114444cfd49..b94d5f76770 100644
--- a/drivers/misc/sgi-xp/xpc.h
+++ b/drivers/misc/sgi-xp/xpc.h
@@ -90,18 +90,21 @@ struct xpc_rsvd_page {
short max_npartitions; /* value of XPC_MAX_PARTITIONS */
u8 version;
u8 pad1[3]; /* align to next u64 in 1st 64-byte cacheline */
+ unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
union {
- unsigned long vars_pa; /* phys address of struct xpc_vars */
- unsigned long activate_gru_mq_desc_gpa; /* phys addr of */
- /* activate mq's */
- /* gru mq descriptor */
+ struct {
+ unsigned long vars_pa; /* phys addr */
+ } sn2;
+ struct {
+ unsigned long heartbeat_gpa; /* phys addr */
+ unsigned long activate_gru_mq_desc_gpa; /* phys addr */
+ } uv;
} sn;
- unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
- u64 pad2[10]; /* align to last u64 in 2nd 64-byte cacheline */
+ u64 pad2[9]; /* align to last u64 in 2nd 64-byte cacheline */
u64 SAL_nasids_size; /* SAL: size of each nasid mask in bytes */
};
-#define XPC_RP_VERSION _XPC_VERSION(2, 0) /* version 2.0 of the reserved page */
+#define XPC_RP_VERSION _XPC_VERSION(3, 0) /* version 3.0 of the reserved page */
/*
* Define the structures by which XPC variables can be exported to other
@@ -182,6 +185,17 @@ struct xpc_vars_part_sn2 {
(XPC_RP_MACH_NASIDS(_rp) + \
xpc_nasid_mask_nlongs))
+
+/*
+ * The following structure describes the partition's heartbeat info which
+ * will be periodically read by other partitions to determine whether this
+ * XPC is still 'alive'.
+ */
+struct xpc_heartbeat_uv {
+ unsigned long value;
+ unsigned long offline; /* if 0, heartbeat should be changing */
+};
+
/*
* Info pertinent to a GRU message queue using a watch list for irq generation.
*/
@@ -198,7 +212,7 @@ struct xpc_gru_mq_uv {
/*
* The activate_mq is used to send/receive GRU messages that affect XPC's
- * heartbeat, partition active state, and channel state. This is UV only.
+ * partition active state and channel state. This is uv only.
*/
struct xpc_activate_mq_msghdr_uv {
unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */
@@ -210,33 +224,27 @@ struct xpc_activate_mq_msghdr_uv {
/* activate_mq defined message types */
#define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV 0
-#define XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV 1
-#define XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV 2
-#define XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV 3
-#define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV 4
-#define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV 5
+#define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV 1
+#define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV 2
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV 6
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV 7
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV 8
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV 9
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV 3
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV 4
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV 5
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV 6
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV 7
-#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV 10
-#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 11
+#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV 8
+#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 9
struct xpc_activate_mq_msg_uv {
struct xpc_activate_mq_msghdr_uv hdr;
};
-struct xpc_activate_mq_msg_heartbeat_req_uv {
- struct xpc_activate_mq_msghdr_uv hdr;
- u64 heartbeat;
-};
-
struct xpc_activate_mq_msg_activate_req_uv {
struct xpc_activate_mq_msghdr_uv hdr;
unsigned long rp_gpa;
+ unsigned long heartbeat_gpa;
unsigned long activate_gru_mq_desc_gpa;
};
@@ -271,6 +279,11 @@ struct xpc_activate_mq_msg_chctl_openreply_uv {
unsigned long notify_gru_mq_desc_gpa;
};
+struct xpc_activate_mq_msg_chctl_opencomplete_uv {
+ struct xpc_activate_mq_msghdr_uv hdr;
+ short ch_number;
+};
+
/*
* Functions registered by add_timer() or called by kernel_thread() only
* allow for a single 64-bit argument. The following macros can be used to
@@ -576,30 +589,32 @@ struct xpc_channel {
#define XPC_C_WASCONNECTED 0x00000001 /* channel was connected */
-#define XPC_C_ROPENREPLY 0x00000002 /* remote open channel reply */
-#define XPC_C_OPENREPLY 0x00000004 /* local open channel reply */
-#define XPC_C_ROPENREQUEST 0x00000008 /* remote open channel request */
-#define XPC_C_OPENREQUEST 0x00000010 /* local open channel request */
+#define XPC_C_ROPENCOMPLETE 0x00000002 /* remote open channel complete */
+#define XPC_C_OPENCOMPLETE 0x00000004 /* local open channel complete */
+#define XPC_C_ROPENREPLY 0x00000008 /* remote open channel reply */
+#define XPC_C_OPENREPLY 0x00000010 /* local open channel reply */
+#define XPC_C_ROPENREQUEST 0x00000020 /* remote open channel request */
+#define XPC_C_OPENREQUEST 0x00000040 /* local open channel request */
-#define XPC_C_SETUP 0x00000020 /* channel's msgqueues are alloc'd */
-#define XPC_C_CONNECTEDCALLOUT 0x00000040 /* connected callout initiated */
+#define XPC_C_SETUP 0x00000080 /* channel's msgqueues are alloc'd */
+#define XPC_C_CONNECTEDCALLOUT 0x00000100 /* connected callout initiated */
#define XPC_C_CONNECTEDCALLOUT_MADE \
- 0x00000080 /* connected callout completed */
-#define XPC_C_CONNECTED 0x00000100 /* local channel is connected */
-#define XPC_C_CONNECTING 0x00000200 /* channel is being connected */
+ 0x00000200 /* connected callout completed */
+#define XPC_C_CONNECTED 0x00000400 /* local channel is connected */
+#define XPC_C_CONNECTING 0x00000800 /* channel is being connected */
-#define XPC_C_RCLOSEREPLY 0x00000400 /* remote close channel reply */
-#define XPC_C_CLOSEREPLY 0x00000800 /* local close channel reply */
-#define XPC_C_RCLOSEREQUEST 0x00001000 /* remote close channel request */
-#define XPC_C_CLOSEREQUEST 0x00002000 /* local close channel request */
+#define XPC_C_RCLOSEREPLY 0x00001000 /* remote close channel reply */
+#define XPC_C_CLOSEREPLY 0x00002000 /* local close channel reply */
+#define XPC_C_RCLOSEREQUEST 0x00004000 /* remote close channel request */
+#define XPC_C_CLOSEREQUEST 0x00008000 /* local close channel request */
-#define XPC_C_DISCONNECTED 0x00004000 /* channel is disconnected */
-#define XPC_C_DISCONNECTING 0x00008000 /* channel is being disconnected */
+#define XPC_C_DISCONNECTED 0x00010000 /* channel is disconnected */
+#define XPC_C_DISCONNECTING 0x00020000 /* channel is being disconnected */
#define XPC_C_DISCONNECTINGCALLOUT \
- 0x00010000 /* disconnecting callout initiated */
+ 0x00040000 /* disconnecting callout initiated */
#define XPC_C_DISCONNECTINGCALLOUT_MADE \
- 0x00020000 /* disconnecting callout completed */
-#define XPC_C_WDISCONNECT 0x00040000 /* waiting for channel disconnect */
+ 0x00080000 /* disconnecting callout completed */
+#define XPC_C_WDISCONNECT 0x00100000 /* waiting for channel disconnect */
/*
* The channel control flags (chctl) union consists of a 64-bit variable which
@@ -618,11 +633,13 @@ union xpc_channel_ctl_flags {
#define XPC_CHCTL_CLOSEREPLY 0x02
#define XPC_CHCTL_OPENREQUEST 0x04
#define XPC_CHCTL_OPENREPLY 0x08
-#define XPC_CHCTL_MSGREQUEST 0x10
+#define XPC_CHCTL_OPENCOMPLETE 0x10
+#define XPC_CHCTL_MSGREQUEST 0x20
#define XPC_OPENCLOSE_CHCTL_FLAGS \
(XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \
- XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY)
+ XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY | \
+ XPC_CHCTL_OPENCOMPLETE)
#define XPC_MSG_CHCTL_FLAGS XPC_CHCTL_MSGREQUEST
static inline int
@@ -687,6 +704,9 @@ struct xpc_partition_sn2 {
};
struct xpc_partition_uv {
+ unsigned long heartbeat_gpa; /* phys addr of partition's heartbeat */
+ struct xpc_heartbeat_uv cached_heartbeat; /* cached copy of */
+ /* partition's heartbeat */
unsigned long activate_gru_mq_desc_gpa; /* phys addr of parititon's */
/* activate mq's gru mq */
/* descriptor */
@@ -698,14 +718,12 @@ struct xpc_partition_uv {
u8 remote_act_state; /* remote partition's act_state */
u8 act_state_req; /* act_state request from remote partition */
enum xp_retval reason; /* reason for deactivate act_state request */
- u64 heartbeat; /* incremented by remote partition */
};
/* struct xpc_partition_uv flags */
-#define XPC_P_HEARTBEAT_OFFLINE_UV 0x00000001
+#define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV 0x00000001
#define XPC_P_ENGAGED_UV 0x00000002
-#define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV 0x00000004
/* struct xpc_partition_uv act_state change requests */
@@ -762,6 +780,62 @@ struct xpc_partition {
} ____cacheline_aligned;
+struct xpc_arch_operations {
+ int (*setup_partitions) (void);
+ void (*teardown_partitions) (void);
+ void (*process_activate_IRQ_rcvd) (void);
+ enum xp_retval (*get_partition_rsvd_page_pa)
+ (void *, u64 *, unsigned long *, size_t *);
+ int (*setup_rsvd_page) (struct xpc_rsvd_page *);
+
+ void (*allow_hb) (short);
+ void (*disallow_hb) (short);
+ void (*disallow_all_hbs) (void);
+ void (*increment_heartbeat) (void);
+ void (*offline_heartbeat) (void);
+ void (*online_heartbeat) (void);
+ void (*heartbeat_init) (void);
+ void (*heartbeat_exit) (void);
+ enum xp_retval (*get_remote_heartbeat) (struct xpc_partition *);
+
+ void (*request_partition_activation) (struct xpc_rsvd_page *,
+ unsigned long, int);
+ void (*request_partition_reactivation) (struct xpc_partition *);
+ void (*request_partition_deactivation) (struct xpc_partition *);
+ void (*cancel_partition_deactivation_request) (struct xpc_partition *);
+ enum xp_retval (*setup_ch_structures) (struct xpc_partition *);
+ void (*teardown_ch_structures) (struct xpc_partition *);
+
+ enum xp_retval (*make_first_contact) (struct xpc_partition *);
+
+ u64 (*get_chctl_all_flags) (struct xpc_partition *);
+ void (*send_chctl_closerequest) (struct xpc_channel *, unsigned long *);
+ void (*send_chctl_closereply) (struct xpc_channel *, unsigned long *);
+ void (*send_chctl_openrequest) (struct xpc_channel *, unsigned long *);
+ void (*send_chctl_openreply) (struct xpc_channel *, unsigned long *);
+ void (*send_chctl_opencomplete) (struct xpc_channel *, unsigned long *);
+ void (*process_msg_chctl_flags) (struct xpc_partition *, int);
+
+ enum xp_retval (*save_remote_msgqueue_pa) (struct xpc_channel *,
+ unsigned long);
+
+ enum xp_retval (*setup_msg_structures) (struct xpc_channel *);
+ void (*teardown_msg_structures) (struct xpc_channel *);
+
+ void (*indicate_partition_engaged) (struct xpc_partition *);
+ void (*indicate_partition_disengaged) (struct xpc_partition *);
+ void (*assume_partition_disengaged) (short);
+ int (*partition_engaged) (short);
+ int (*any_partition_engaged) (void);
+
+ int (*n_of_deliverable_payloads) (struct xpc_channel *);
+ enum xp_retval (*send_payload) (struct xpc_channel *, u32, void *,
+ u16, u8, xpc_notify_func, void *);
+ void *(*get_deliverable_payload) (struct xpc_channel *);
+ void (*received_payload) (struct xpc_channel *, void *);
+ void (*notify_senders_of_disconnect) (struct xpc_channel *);
+};
+
/* struct xpc_partition act_state values (for XPC HB) */
#define XPC_P_AS_INACTIVE 0x00 /* partition is not active */
@@ -802,67 +876,17 @@ extern struct xpc_registration xpc_registrations[];
/* found in xpc_main.c */
extern struct device *xpc_part;
extern struct device *xpc_chan;
+extern struct xpc_arch_operations xpc_arch_ops;
extern int xpc_disengage_timelimit;
extern int xpc_disengage_timedout;
extern int xpc_activate_IRQ_rcvd;
extern spinlock_t xpc_activate_IRQ_rcvd_lock;
extern wait_queue_head_t xpc_activate_IRQ_wq;
-extern void *xpc_heartbeating_to_mask;
extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
extern void xpc_activate_partition(struct xpc_partition *);
extern void xpc_activate_kthreads(struct xpc_channel *, int);
extern void xpc_create_kthreads(struct xpc_channel *, int, int);
extern void xpc_disconnect_wait(int);
-extern int (*xpc_setup_partitions_sn) (void);
-extern void (*xpc_teardown_partitions_sn) (void);
-extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *, u64 *,
- unsigned long *,
- size_t *);
-extern int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *);
-extern void (*xpc_heartbeat_init) (void);
-extern void (*xpc_heartbeat_exit) (void);
-extern void (*xpc_increment_heartbeat) (void);
-extern void (*xpc_offline_heartbeat) (void);
-extern void (*xpc_online_heartbeat) (void);
-extern enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *);
-extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
-extern u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *);
-extern enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *);
-extern void (*xpc_teardown_msg_structures) (struct xpc_channel *);
-extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *);
-extern void (*xpc_process_msg_chctl_flags) (struct xpc_partition *, int);
-extern int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *);
-extern void *(*xpc_get_deliverable_payload) (struct xpc_channel *);
-extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *,
- unsigned long, int);
-extern void (*xpc_request_partition_reactivation) (struct xpc_partition *);
-extern void (*xpc_request_partition_deactivation) (struct xpc_partition *);
-extern void (*xpc_cancel_partition_deactivation_request) (
- struct xpc_partition *);
-extern void (*xpc_process_activate_IRQ_rcvd) (void);
-extern enum xp_retval (*xpc_setup_ch_structures_sn) (struct xpc_partition *);
-extern void (*xpc_teardown_ch_structures_sn) (struct xpc_partition *);
-
-extern void (*xpc_indicate_partition_engaged) (struct xpc_partition *);
-extern int (*xpc_partition_engaged) (short);
-extern int (*xpc_any_partition_engaged) (void);
-extern void (*xpc_indicate_partition_disengaged) (struct xpc_partition *);
-extern void (*xpc_assume_partition_disengaged) (short);
-
-extern void (*xpc_send_chctl_closerequest) (struct xpc_channel *,
- unsigned long *);
-extern void (*xpc_send_chctl_closereply) (struct xpc_channel *,
- unsigned long *);
-extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *,
- unsigned long *);
-extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *);
-
-extern enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *,
- unsigned long);
-
-extern enum xp_retval (*xpc_send_payload) (struct xpc_channel *, u32, void *,
- u16, u8, xpc_notify_func, void *);
-extern void (*xpc_received_payload) (struct xpc_channel *, void *);
/* found in xpc_sn2.c */
extern int xpc_init_sn2(void);
@@ -909,40 +933,6 @@ extern void xpc_disconnect_channel(const int, struct xpc_channel *,
extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
-static inline int
-xpc_hb_allowed(short partid, void *heartbeating_to_mask)
-{
- return test_bit(partid, heartbeating_to_mask);
-}
-
-static inline int
-xpc_any_hbs_allowed(void)
-{
- DBUG_ON(xpc_heartbeating_to_mask == NULL);
- return !bitmap_empty(xpc_heartbeating_to_mask, xp_max_npartitions);
-}
-
-static inline void
-xpc_allow_hb(short partid)
-{
- DBUG_ON(xpc_heartbeating_to_mask == NULL);
- set_bit(partid, xpc_heartbeating_to_mask);
-}
-
-static inline void
-xpc_disallow_hb(short partid)
-{
- DBUG_ON(xpc_heartbeating_to_mask == NULL);
- clear_bit(partid, xpc_heartbeating_to_mask);
-}
-
-static inline void
-xpc_disallow_all_hbs(void)
-{
- DBUG_ON(xpc_heartbeating_to_mask == NULL);
- bitmap_zero(xpc_heartbeating_to_mask, xp_max_npartitions);
-}
-
static inline void
xpc_wakeup_channel_mgr(struct xpc_partition *part)
{
diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c
index 99a2534c38a..652593fc486 100644
--- a/drivers/misc/sgi-xp/xpc_channel.c
+++ b/drivers/misc/sgi-xp/xpc_channel.c
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved.
*/
/*
@@ -39,34 +39,38 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
if (!(ch->flags & XPC_C_SETUP)) {
spin_unlock_irqrestore(&ch->lock, *irq_flags);
- ret = xpc_setup_msg_structures(ch);
+ ret = xpc_arch_ops.setup_msg_structures(ch);
spin_lock_irqsave(&ch->lock, *irq_flags);
if (ret != xpSuccess)
XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags);
+ else
+ ch->flags |= XPC_C_SETUP;
- ch->flags |= XPC_C_SETUP;
-
- if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING))
+ if (ch->flags & XPC_C_DISCONNECTING)
return;
}
if (!(ch->flags & XPC_C_OPENREPLY)) {
ch->flags |= XPC_C_OPENREPLY;
- xpc_send_chctl_openreply(ch, irq_flags);
+ xpc_arch_ops.send_chctl_openreply(ch, irq_flags);
}
if (!(ch->flags & XPC_C_ROPENREPLY))
return;
- ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP); /* clear all else */
+ if (!(ch->flags & XPC_C_OPENCOMPLETE)) {
+ ch->flags |= (XPC_C_OPENCOMPLETE | XPC_C_CONNECTED);
+ xpc_arch_ops.send_chctl_opencomplete(ch, irq_flags);
+ }
+
+ if (!(ch->flags & XPC_C_ROPENCOMPLETE))
+ return;
dev_info(xpc_chan, "channel %d to partition %d connected\n",
ch->number, ch->partid);
- spin_unlock_irqrestore(&ch->lock, *irq_flags);
- xpc_create_kthreads(ch, 1, 0);
- spin_lock_irqsave(&ch->lock, *irq_flags);
+ ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP); /* clear all else */
}
/*
@@ -96,7 +100,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
if (part->act_state == XPC_P_AS_DEACTIVATING) {
/* can't proceed until the other side disengages from us */
- if (xpc_partition_engaged(ch->partid))
+ if (xpc_arch_ops.partition_engaged(ch->partid))
return;
} else {
@@ -108,7 +112,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
if (!(ch->flags & XPC_C_CLOSEREPLY)) {
ch->flags |= XPC_C_CLOSEREPLY;
- xpc_send_chctl_closereply(ch, irq_flags);
+ xpc_arch_ops.send_chctl_closereply(ch, irq_flags);
}
if (!(ch->flags & XPC_C_RCLOSEREPLY))
@@ -118,7 +122,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
/* wake those waiting for notify completion */
if (atomic_read(&ch->n_to_notify) > 0) {
/* we do callout while holding ch->lock, callout can't block */
- xpc_notify_senders_of_disconnect(ch);
+ xpc_arch_ops.notify_senders_of_disconnect(ch);
}
/* both sides are disconnected now */
@@ -132,7 +136,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
DBUG_ON(atomic_read(&ch->n_to_notify) != 0);
/* it's now safe to free the channel's message queues */
- xpc_teardown_msg_structures(ch);
+ xpc_arch_ops.teardown_msg_structures(ch);
ch->func = NULL;
ch->key = NULL;
@@ -144,8 +148,9 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
/*
* Mark the channel disconnected and clear all other flags, including
- * XPC_C_SETUP (because of call to xpc_teardown_msg_structures()) but
- * not including XPC_C_WDISCONNECT (if it was set).
+ * XPC_C_SETUP (because of call to
+ * xpc_arch_ops.teardown_msg_structures()) but not including
+ * XPC_C_WDISCONNECT (if it was set).
*/
ch->flags = (XPC_C_DISCONNECTED | (ch->flags & XPC_C_WDISCONNECT));
@@ -184,6 +189,7 @@ xpc_process_openclose_chctl_flags(struct xpc_partition *part, int ch_number,
struct xpc_channel *ch = &part->channels[ch_number];
enum xp_retval reason;
enum xp_retval ret;
+ int create_kthread = 0;
spin_lock_irqsave(&ch->lock, irq_flags);
@@ -196,8 +202,7 @@ again:
* has had a chance to see that the channel is disconnected.
*/
ch->delayed_chctl_flags |= chctl_flags;
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return;
+ goto out;
}
if (chctl_flags & XPC_CHCTL_CLOSEREQUEST) {
@@ -239,8 +244,7 @@ again:
XPC_CHCTL_CLOSEREQUEST;
spin_unlock(&part->chctl_lock);
}
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return;
+ goto out;
}
XPC_SET_REASON(ch, 0, 0);
@@ -250,7 +254,8 @@ again:
ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST);
}
- chctl_flags &= ~(XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY);
+ chctl_flags &= ~(XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY |
+ XPC_CHCTL_OPENCOMPLETE);
/*
* The meaningful CLOSEREQUEST connection state fields are:
@@ -269,8 +274,7 @@ again:
XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
DBUG_ON(chctl_flags & XPC_CHCTL_CLOSEREPLY);
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return;
+ goto out;
}
xpc_process_disconnect(ch, &irq_flags);
@@ -283,8 +287,7 @@ again:
if (ch->flags & XPC_C_DISCONNECTED) {
DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING);
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return;
+ goto out;
}
DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
@@ -299,8 +302,7 @@ again:
XPC_CHCTL_CLOSEREPLY;
spin_unlock(&part->chctl_lock);
}
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return;
+ goto out;
}
ch->flags |= XPC_C_RCLOSEREPLY;
@@ -320,14 +322,12 @@ again:
if (part->act_state == XPC_P_AS_DEACTIVATING ||
(ch->flags & XPC_C_ROPENREQUEST)) {
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return;
+ goto out;
}
if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) {
ch->delayed_chctl_flags |= XPC_CHCTL_OPENREQUEST;
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return;
+ goto out;
}
DBUG_ON(!(ch->flags & (XPC_C_DISCONNECTED |
XPC_C_OPENREQUEST)));
@@ -341,8 +341,7 @@ again:
*/
if (args->entry_size == 0 || args->local_nentries == 0) {
/* assume OPENREQUEST was delayed by mistake */
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return;
+ goto out;
}
ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING);
@@ -352,8 +351,7 @@ again:
if (args->entry_size != ch->entry_size) {
XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes,
&irq_flags);
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return;
+ goto out;
}
} else {
ch->entry_size = args->entry_size;
@@ -375,15 +373,13 @@ again:
args->local_msgqueue_pa, args->local_nentries,
args->remote_nentries, ch->partid, ch->number);
- if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) {
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return;
- }
+ if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED))
+ goto out;
+
if (!(ch->flags & XPC_C_OPENREQUEST)) {
XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError,
&irq_flags);
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return;
+ goto out;
}
DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
@@ -400,11 +396,11 @@ again:
DBUG_ON(args->local_nentries == 0);
DBUG_ON(args->remote_nentries == 0);
- ret = xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa);
+ ret = xpc_arch_ops.save_remote_msgqueue_pa(ch,
+ args->local_msgqueue_pa);
if (ret != xpSuccess) {
XPC_DISCONNECT_CHANNEL(ch, ret, &irq_flags);
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return;
+ goto out;
}
ch->flags |= XPC_C_ROPENREPLY;
@@ -430,7 +426,36 @@ again:
xpc_process_connect(ch, &irq_flags);
}
+ if (chctl_flags & XPC_CHCTL_OPENCOMPLETE) {
+
+ dev_dbg(xpc_chan, "XPC_CHCTL_OPENCOMPLETE received from "
+ "partid=%d, channel=%d\n", ch->partid, ch->number);
+
+ if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED))
+ goto out;
+
+ if (!(ch->flags & XPC_C_OPENREQUEST) ||
+ !(ch->flags & XPC_C_OPENREPLY)) {
+ XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError,
+ &irq_flags);
+ goto out;
+ }
+
+ DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
+ DBUG_ON(!(ch->flags & XPC_C_ROPENREPLY));
+ DBUG_ON(!(ch->flags & XPC_C_CONNECTED));
+
+ ch->flags |= XPC_C_ROPENCOMPLETE;
+
+ xpc_process_connect(ch, &irq_flags);
+ create_kthread = 1;
+ }
+
+out:
spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+ if (create_kthread)
+ xpc_create_kthreads(ch, 1, 0);
}
/*
@@ -508,7 +533,7 @@ xpc_connect_channel(struct xpc_channel *ch)
/* initiate the connection */
ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING);
- xpc_send_chctl_openrequest(ch, &irq_flags);
+ xpc_arch_ops.send_chctl_openrequest(ch, &irq_flags);
xpc_process_connect(ch, &irq_flags);
@@ -526,7 +551,7 @@ xpc_process_sent_chctl_flags(struct xpc_partition *part)
int ch_number;
u32 ch_flags;
- chctl.all_flags = xpc_get_chctl_all_flags(part);
+ chctl.all_flags = xpc_arch_ops.get_chctl_all_flags(part);
/*
* Initiate channel connections for registered channels.
@@ -564,10 +589,6 @@ xpc_process_sent_chctl_flags(struct xpc_partition *part)
if (!(ch_flags & XPC_C_OPENREQUEST)) {
DBUG_ON(ch_flags & XPC_C_SETUP);
(void)xpc_connect_channel(ch);
- } else {
- spin_lock_irqsave(&ch->lock, irq_flags);
- xpc_process_connect(ch, &irq_flags);
- spin_unlock_irqrestore(&ch->lock, irq_flags);
}
continue;
}
@@ -579,7 +600,7 @@ xpc_process_sent_chctl_flags(struct xpc_partition *part)
*/
if (chctl.flags[ch_number] & XPC_MSG_CHCTL_FLAGS)
- xpc_process_msg_chctl_flags(part, ch_number);
+ xpc_arch_ops.process_msg_chctl_flags(part, ch_number);
}
}
@@ -755,7 +776,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
XPC_C_CONNECTING | XPC_C_CONNECTED);
- xpc_send_chctl_closerequest(ch, irq_flags);
+ xpc_arch_ops.send_chctl_closerequest(ch, irq_flags);
if (channel_was_connected)
ch->flags |= XPC_C_WASCONNECTED;
@@ -862,8 +883,8 @@ xpc_initiate_send(short partid, int ch_number, u32 flags, void *payload,
DBUG_ON(payload == NULL);
if (xpc_part_ref(part)) {
- ret = xpc_send_payload(&part->channels[ch_number], flags,
- payload, payload_size, 0, NULL, NULL);
+ ret = xpc_arch_ops.send_payload(&part->channels[ch_number],
+ flags, payload, payload_size, 0, NULL, NULL);
xpc_part_deref(part);
}
@@ -914,9 +935,8 @@ xpc_initiate_send_notify(short partid, int ch_number, u32 flags, void *payload,
DBUG_ON(func == NULL);
if (xpc_part_ref(part)) {
- ret = xpc_send_payload(&part->channels[ch_number], flags,
- payload, payload_size, XPC_N_CALL, func,
- key);
+ ret = xpc_arch_ops.send_payload(&part->channels[ch_number],
+ flags, payload, payload_size, XPC_N_CALL, func, key);
xpc_part_deref(part);
}
return ret;
@@ -930,7 +950,7 @@ xpc_deliver_payload(struct xpc_channel *ch)
{
void *payload;
- payload = xpc_get_deliverable_payload(ch);
+ payload = xpc_arch_ops.get_deliverable_payload(ch);
if (payload != NULL) {
/*
@@ -984,7 +1004,7 @@ xpc_initiate_received(short partid, int ch_number, void *payload)
DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
ch = &part->channels[ch_number];
- xpc_received_payload(ch, payload);
+ xpc_arch_ops.received_payload(ch, payload);
/* the call to xpc_msgqueue_ref() was done by xpc_deliver_payload() */
xpc_msgqueue_deref(ch);
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index 1ab9fda87fa..fd3688a3e23 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved.
*/
/*
@@ -150,7 +150,6 @@ DECLARE_WAIT_QUEUE_HEAD(xpc_activate_IRQ_wq);
static unsigned long xpc_hb_check_timeout;
static struct timer_list xpc_hb_timer;
-void *xpc_heartbeating_to_mask;
/* notification that the xpc_hb_checker thread has exited */
static DECLARE_COMPLETION(xpc_hb_checker_exited);
@@ -170,62 +169,7 @@ static struct notifier_block xpc_die_notifier = {
.notifier_call = xpc_system_die,
};
-int (*xpc_setup_partitions_sn) (void);
-void (*xpc_teardown_partitions_sn) (void);
-enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *buf, u64 *cookie,
- unsigned long *rp_pa,
- size_t *len);
-int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *rp);
-void (*xpc_heartbeat_init) (void);
-void (*xpc_heartbeat_exit) (void);
-void (*xpc_increment_heartbeat) (void);
-void (*xpc_offline_heartbeat) (void);
-void (*xpc_online_heartbeat) (void);
-enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *part);
-
-enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *part);
-void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *ch);
-u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *part);
-enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *ch);
-void (*xpc_teardown_msg_structures) (struct xpc_channel *ch);
-void (*xpc_process_msg_chctl_flags) (struct xpc_partition *part, int ch_number);
-int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *ch);
-void *(*xpc_get_deliverable_payload) (struct xpc_channel *ch);
-
-void (*xpc_request_partition_activation) (struct xpc_rsvd_page *remote_rp,
- unsigned long remote_rp_pa,
- int nasid);
-void (*xpc_request_partition_reactivation) (struct xpc_partition *part);
-void (*xpc_request_partition_deactivation) (struct xpc_partition *part);
-void (*xpc_cancel_partition_deactivation_request) (struct xpc_partition *part);
-
-void (*xpc_process_activate_IRQ_rcvd) (void);
-enum xp_retval (*xpc_setup_ch_structures_sn) (struct xpc_partition *part);
-void (*xpc_teardown_ch_structures_sn) (struct xpc_partition *part);
-
-void (*xpc_indicate_partition_engaged) (struct xpc_partition *part);
-int (*xpc_partition_engaged) (short partid);
-int (*xpc_any_partition_engaged) (void);
-void (*xpc_indicate_partition_disengaged) (struct xpc_partition *part);
-void (*xpc_assume_partition_disengaged) (short partid);
-
-void (*xpc_send_chctl_closerequest) (struct xpc_channel *ch,
- unsigned long *irq_flags);
-void (*xpc_send_chctl_closereply) (struct xpc_channel *ch,
- unsigned long *irq_flags);
-void (*xpc_send_chctl_openrequest) (struct xpc_channel *ch,
- unsigned long *irq_flags);
-void (*xpc_send_chctl_openreply) (struct xpc_channel *ch,
- unsigned long *irq_flags);
-
-enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch,
- unsigned long msgqueue_pa);
-
-enum xp_retval (*xpc_send_payload) (struct xpc_channel *ch, u32 flags,
- void *payload, u16 payload_size,
- u8 notify_type, xpc_notify_func func,
- void *key);
-void (*xpc_received_payload) (struct xpc_channel *ch, void *payload);
+struct xpc_arch_operations xpc_arch_ops;
/*
* Timer function to enforce the timelimit on the partition disengage.
@@ -240,7 +184,7 @@ xpc_timeout_partition_disengage(unsigned long data)
(void)xpc_partition_disengaged(part);
DBUG_ON(part->disengage_timeout != 0);
- DBUG_ON(xpc_partition_engaged(XPC_PARTID(part)));
+ DBUG_ON(xpc_arch_ops.partition_engaged(XPC_PARTID(part)));
}
/*
@@ -251,7 +195,7 @@ xpc_timeout_partition_disengage(unsigned long data)
static void
xpc_hb_beater(unsigned long dummy)
{
- xpc_increment_heartbeat();
+ xpc_arch_ops.increment_heartbeat();
if (time_is_before_eq_jiffies(xpc_hb_check_timeout))
wake_up_interruptible(&xpc_activate_IRQ_wq);
@@ -263,7 +207,7 @@ xpc_hb_beater(unsigned long dummy)
static void
xpc_start_hb_beater(void)
{
- xpc_heartbeat_init();
+ xpc_arch_ops.heartbeat_init();
init_timer(&xpc_hb_timer);
xpc_hb_timer.function = xpc_hb_beater;
xpc_hb_beater(0);
@@ -273,7 +217,7 @@ static void
xpc_stop_hb_beater(void)
{
del_timer_sync(&xpc_hb_timer);
- xpc_heartbeat_exit();
+ xpc_arch_ops.heartbeat_exit();
}
/*
@@ -302,7 +246,7 @@ xpc_check_remote_hb(void)
continue;
}
- ret = xpc_get_remote_heartbeat(part);
+ ret = xpc_arch_ops.get_remote_heartbeat(part);
if (ret != xpSuccess)
XPC_DEACTIVATE_PARTITION(part, ret);
}
@@ -353,7 +297,7 @@ xpc_hb_checker(void *ignore)
force_IRQ = 0;
dev_dbg(xpc_part, "processing activate IRQs "
"received\n");
- xpc_process_activate_IRQ_rcvd();
+ xpc_arch_ops.process_activate_IRQ_rcvd();
}
/* wait for IRQ or timeout */
@@ -528,7 +472,7 @@ xpc_setup_ch_structures(struct xpc_partition *part)
init_waitqueue_head(&ch->idle_wq);
}
- ret = xpc_setup_ch_structures_sn(part);
+ ret = xpc_arch_ops.setup_ch_structures(part);
if (ret != xpSuccess)
goto out_2;
@@ -572,7 +516,7 @@ xpc_teardown_ch_structures(struct xpc_partition *part)
/* now we can begin tearing down the infrastructure */
- xpc_teardown_ch_structures_sn(part);
+ xpc_arch_ops.teardown_ch_structures(part);
kfree(part->remote_openclose_args_base);
part->remote_openclose_args = NULL;
@@ -620,12 +564,12 @@ xpc_activating(void *__partid)
dev_dbg(xpc_part, "activating partition %d\n", partid);
- xpc_allow_hb(partid);
+ xpc_arch_ops.allow_hb(partid);
if (xpc_setup_ch_structures(part) == xpSuccess) {
(void)xpc_part_ref(part); /* this will always succeed */
- if (xpc_make_first_contact(part) == xpSuccess) {
+ if (xpc_arch_ops.make_first_contact(part) == xpSuccess) {
xpc_mark_partition_active(part);
xpc_channel_mgr(part);
/* won't return until partition is deactivating */
@@ -635,12 +579,12 @@ xpc_activating(void *__partid)
xpc_teardown_ch_structures(part);
}
- xpc_disallow_hb(partid);
+ xpc_arch_ops.disallow_hb(partid);
xpc_mark_partition_inactive(part);
if (part->reason == xpReactivating) {
/* interrupting ourselves results in activating partition */
- xpc_request_partition_reactivation(part);
+ xpc_arch_ops.request_partition_reactivation(part);
}
return 0;
@@ -713,10 +657,13 @@ xpc_activate_kthreads(struct xpc_channel *ch, int needed)
static void
xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch)
{
+ int (*n_of_deliverable_payloads) (struct xpc_channel *) =
+ xpc_arch_ops.n_of_deliverable_payloads;
+
do {
/* deliver messages to their intended recipients */
- while (xpc_n_of_deliverable_payloads(ch) > 0 &&
+ while (n_of_deliverable_payloads(ch) > 0 &&
!(ch->flags & XPC_C_DISCONNECTING)) {
xpc_deliver_payload(ch);
}
@@ -732,7 +679,7 @@ xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch)
"wait_event_interruptible_exclusive()\n");
(void)wait_event_interruptible_exclusive(ch->idle_wq,
- (xpc_n_of_deliverable_payloads(ch) > 0 ||
+ (n_of_deliverable_payloads(ch) > 0 ||
(ch->flags & XPC_C_DISCONNECTING)));
atomic_dec(&ch->kthreads_idle);
@@ -749,6 +696,8 @@ xpc_kthread_start(void *args)
struct xpc_channel *ch;
int n_needed;
unsigned long irq_flags;
+ int (*n_of_deliverable_payloads) (struct xpc_channel *) =
+ xpc_arch_ops.n_of_deliverable_payloads;
dev_dbg(xpc_chan, "kthread starting, partid=%d, channel=%d\n",
partid, ch_number);
@@ -777,7 +726,7 @@ xpc_kthread_start(void *args)
* additional kthreads to help deliver them. We only
* need one less than total #of messages to deliver.
*/
- n_needed = xpc_n_of_deliverable_payloads(ch) - 1;
+ n_needed = n_of_deliverable_payloads(ch) - 1;
if (n_needed > 0 && !(ch->flags & XPC_C_DISCONNECTING))
xpc_activate_kthreads(ch, n_needed);
@@ -805,7 +754,7 @@ xpc_kthread_start(void *args)
if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
atomic_dec_return(&part->nchannels_engaged) == 0) {
- xpc_indicate_partition_disengaged(part);
+ xpc_arch_ops.indicate_partition_disengaged(part);
}
xpc_msgqueue_deref(ch);
@@ -837,6 +786,8 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed,
u64 args = XPC_PACK_ARGS(ch->partid, ch->number);
struct xpc_partition *part = &xpc_partitions[ch->partid];
struct task_struct *kthread;
+ void (*indicate_partition_disengaged) (struct xpc_partition *) =
+ xpc_arch_ops.indicate_partition_disengaged;
while (needed-- > 0) {
@@ -858,7 +809,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed,
} else if (atomic_inc_return(&ch->kthreads_assigned) == 1 &&
atomic_inc_return(&part->nchannels_engaged) == 1) {
- xpc_indicate_partition_engaged(part);
+ xpc_arch_ops.indicate_partition_engaged(part);
}
(void)xpc_part_ref(part);
xpc_msgqueue_ref(ch);
@@ -880,7 +831,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed,
if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
atomic_dec_return(&part->nchannels_engaged) == 0) {
- xpc_indicate_partition_disengaged(part);
+ indicate_partition_disengaged(part);
}
xpc_msgqueue_deref(ch);
xpc_part_deref(part);
@@ -993,13 +944,13 @@ xpc_setup_partitions(void)
atomic_set(&part->references, 0);
}
- return xpc_setup_partitions_sn();
+ return xpc_arch_ops.setup_partitions();
}
static void
xpc_teardown_partitions(void)
{
- xpc_teardown_partitions_sn();
+ xpc_arch_ops.teardown_partitions();
kfree(xpc_partitions);
}
@@ -1055,7 +1006,7 @@ xpc_do_exit(enum xp_retval reason)
disengage_timeout = part->disengage_timeout;
}
- if (xpc_any_partition_engaged()) {
+ if (xpc_arch_ops.any_partition_engaged()) {
if (time_is_before_jiffies(printmsg_time)) {
dev_info(xpc_part, "waiting for remote "
"partitions to deactivate, timeout in "
@@ -1086,8 +1037,7 @@ xpc_do_exit(enum xp_retval reason)
} while (1);
- DBUG_ON(xpc_any_partition_engaged());
- DBUG_ON(xpc_any_hbs_allowed() != 0);
+ DBUG_ON(xpc_arch_ops.any_partition_engaged());
xpc_teardown_rsvd_page();
@@ -1152,15 +1102,15 @@ xpc_die_deactivate(void)
/* keep xpc_hb_checker thread from doing anything (just in case) */
xpc_exiting = 1;
- xpc_disallow_all_hbs(); /*indicate we're deactivated */
+ xpc_arch_ops.disallow_all_hbs(); /*indicate we're deactivated */
for (partid = 0; partid < xp_max_npartitions; partid++) {
part = &xpc_partitions[partid];
- if (xpc_partition_engaged(partid) ||
+ if (xpc_arch_ops.partition_engaged(partid) ||
part->act_state != XPC_P_AS_INACTIVE) {
- xpc_request_partition_deactivation(part);
- xpc_indicate_partition_disengaged(part);
+ xpc_arch_ops.request_partition_deactivation(part);
+ xpc_arch_ops.indicate_partition_disengaged(part);
}
}
@@ -1177,7 +1127,7 @@ xpc_die_deactivate(void)
wait_to_print = XPC_DEACTIVATE_PRINTMSG_INTERVAL * 1000 * 5;
while (1) {
- any_engaged = xpc_any_partition_engaged();
+ any_engaged = xpc_arch_ops.any_partition_engaged();
if (!any_engaged) {
dev_info(xpc_part, "all partitions have deactivated\n");
break;
@@ -1186,7 +1136,7 @@ xpc_die_deactivate(void)
if (!keep_waiting--) {
for (partid = 0; partid < xp_max_npartitions;
partid++) {
- if (xpc_partition_engaged(partid)) {
+ if (xpc_arch_ops.partition_engaged(partid)) {
dev_info(xpc_part, "deactivate from "
"remote partition %d timed "
"out\n", partid);
@@ -1233,7 +1183,7 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
/* fall through */
case DIE_MCA_MONARCH_ENTER:
case DIE_INIT_MONARCH_ENTER:
- xpc_offline_heartbeat();
+ xpc_arch_ops.offline_heartbeat();
break;
case DIE_KDEBUG_LEAVE:
@@ -1244,7 +1194,7 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
/* fall through */
case DIE_MCA_MONARCH_LEAVE:
case DIE_INIT_MONARCH_LEAVE:
- xpc_online_heartbeat();
+ xpc_arch_ops.online_heartbeat();
break;
}
#else
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c
index 6722f6fe4dc..65877bc5eda 100644
--- a/drivers/misc/sgi-xp/xpc_partition.c
+++ b/drivers/misc/sgi-xp/xpc_partition.c
@@ -70,6 +70,9 @@ xpc_get_rsvd_page_pa(int nasid)
size_t buf_len = 0;
void *buf = buf;
void *buf_base = NULL;
+ enum xp_retval (*get_partition_rsvd_page_pa)
+ (void *, u64 *, unsigned long *, size_t *) =
+ xpc_arch_ops.get_partition_rsvd_page_pa;
while (1) {
@@ -79,8 +82,7 @@ xpc_get_rsvd_page_pa(int nasid)
* ??? function or have two versions? Rename rp_pa for UV to
* ??? rp_gpa?
*/
- ret = xpc_get_partition_rsvd_page_pa(buf, &cookie, &rp_pa,
- &len);
+ ret = get_partition_rsvd_page_pa(buf, &cookie, &rp_pa, &len);
dev_dbg(xpc_part, "SAL returned with ret=%d, cookie=0x%016lx, "
"address=0x%016lx, len=0x%016lx\n", ret,
@@ -172,7 +174,7 @@ xpc_setup_rsvd_page(void)
xpc_part_nasids = XPC_RP_PART_NASIDS(rp);
xpc_mach_nasids = XPC_RP_MACH_NASIDS(rp);
- ret = xpc_setup_rsvd_page_sn(rp);
+ ret = xpc_arch_ops.setup_rsvd_page(rp);
if (ret != 0)
return ret;
@@ -264,7 +266,7 @@ xpc_partition_disengaged(struct xpc_partition *part)
short partid = XPC_PARTID(part);
int disengaged;
- disengaged = !xpc_partition_engaged(partid);
+ disengaged = !xpc_arch_ops.partition_engaged(partid);
if (part->disengage_timeout) {
if (!disengaged) {
if (time_is_after_jiffies(part->disengage_timeout)) {
@@ -280,7 +282,7 @@ xpc_partition_disengaged(struct xpc_partition *part)
dev_info(xpc_part, "deactivate request to remote "
"partition %d timed out\n", partid);
xpc_disengage_timedout = 1;
- xpc_assume_partition_disengaged(partid);
+ xpc_arch_ops.assume_partition_disengaged(partid);
disengaged = 1;
}
part->disengage_timeout = 0;
@@ -294,7 +296,7 @@ xpc_partition_disengaged(struct xpc_partition *part)
if (part->act_state != XPC_P_AS_INACTIVE)
xpc_wakeup_channel_mgr(part);
- xpc_cancel_partition_deactivation_request(part);
+ xpc_arch_ops.cancel_partition_deactivation_request(part);
}
return disengaged;
}
@@ -339,7 +341,7 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
spin_unlock_irqrestore(&part->act_lock, irq_flags);
if (reason == xpReactivating) {
/* we interrupt ourselves to reactivate partition */
- xpc_request_partition_reactivation(part);
+ xpc_arch_ops.request_partition_reactivation(part);
}
return;
}
@@ -358,7 +360,7 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
spin_unlock_irqrestore(&part->act_lock, irq_flags);
/* ask remote partition to deactivate with regard to us */
- xpc_request_partition_deactivation(part);
+ xpc_arch_ops.request_partition_deactivation(part);
/* set a timelimit on the disengage phase of the deactivation request */
part->disengage_timeout = jiffies + (xpc_disengage_timelimit * HZ);
@@ -496,7 +498,7 @@ xpc_discovery(void)
continue;
}
- xpc_request_partition_activation(remote_rp,
+ xpc_arch_ops.request_partition_activation(remote_rp,
remote_rp_pa, nasid);
}
}
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c
index eaaa964942d..915a3b495da 100644
--- a/drivers/misc/sgi-xp/xpc_sn2.c
+++ b/drivers/misc/sgi-xp/xpc_sn2.c
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved.
*/
/*
@@ -60,14 +60,14 @@ static struct xpc_vars_sn2 *xpc_vars_sn2;
static struct xpc_vars_part_sn2 *xpc_vars_part_sn2;
static int
-xpc_setup_partitions_sn_sn2(void)
+xpc_setup_partitions_sn2(void)
{
/* nothing needs to be done */
return 0;
}
static void
-xpc_teardown_partitions_sn_sn2(void)
+xpc_teardown_partitions_sn2(void)
{
/* nothing needs to be done */
}
@@ -431,6 +431,13 @@ xpc_send_chctl_openreply_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
}
static void
+xpc_send_chctl_opencomplete_sn2(struct xpc_channel *ch,
+ unsigned long *irq_flags)
+{
+ XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENCOMPLETE, irq_flags);
+}
+
+static void
xpc_send_chctl_msgrequest_sn2(struct xpc_channel *ch)
{
XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST, NULL);
@@ -621,7 +628,7 @@ xpc_get_partition_rsvd_page_pa_sn2(void *buf, u64 *cookie, unsigned long *rp_pa,
static int
-xpc_setup_rsvd_page_sn_sn2(struct xpc_rsvd_page *rp)
+xpc_setup_rsvd_page_sn2(struct xpc_rsvd_page *rp)
{
struct amo *amos_page;
int i;
@@ -629,7 +636,7 @@ xpc_setup_rsvd_page_sn_sn2(struct xpc_rsvd_page *rp)
xpc_vars_sn2 = XPC_RP_VARS(rp);
- rp->sn.vars_pa = xp_pa(xpc_vars_sn2);
+ rp->sn.sn2.vars_pa = xp_pa(xpc_vars_sn2);
/* vars_part array follows immediately after vars */
xpc_vars_part_sn2 = (struct xpc_vars_part_sn2 *)((u8 *)XPC_RP_VARS(rp) +
@@ -693,6 +700,33 @@ xpc_setup_rsvd_page_sn_sn2(struct xpc_rsvd_page *rp)
return 0;
}
+static int
+xpc_hb_allowed_sn2(short partid, void *heartbeating_to_mask)
+{
+ return test_bit(partid, heartbeating_to_mask);
+}
+
+static void
+xpc_allow_hb_sn2(short partid)
+{
+ DBUG_ON(xpc_vars_sn2 == NULL);
+ set_bit(partid, xpc_vars_sn2->heartbeating_to_mask);
+}
+
+static void
+xpc_disallow_hb_sn2(short partid)
+{
+ DBUG_ON(xpc_vars_sn2 == NULL);
+ clear_bit(partid, xpc_vars_sn2->heartbeating_to_mask);
+}
+
+static void
+xpc_disallow_all_hbs_sn2(void)
+{
+ DBUG_ON(xpc_vars_sn2 == NULL);
+ bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, xp_max_npartitions);
+}
+
static void
xpc_increment_heartbeat_sn2(void)
{
@@ -719,7 +753,6 @@ xpc_heartbeat_init_sn2(void)
DBUG_ON(xpc_vars_sn2 == NULL);
bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
- xpc_heartbeating_to_mask = &xpc_vars_sn2->heartbeating_to_mask[0];
xpc_online_heartbeat_sn2();
}
@@ -751,9 +784,9 @@ xpc_get_remote_heartbeat_sn2(struct xpc_partition *part)
remote_vars->heartbeating_to_mask[0]);
if ((remote_vars->heartbeat == part->last_heartbeat &&
- remote_vars->heartbeat_offline == 0) ||
- !xpc_hb_allowed(sn_partition_id,
- &remote_vars->heartbeating_to_mask)) {
+ !remote_vars->heartbeat_offline) ||
+ !xpc_hb_allowed_sn2(sn_partition_id,
+ remote_vars->heartbeating_to_mask)) {
ret = xpNoHeartbeat;
} else {
part->last_heartbeat = remote_vars->heartbeat;
@@ -972,7 +1005,7 @@ xpc_identify_activate_IRQ_req_sn2(int nasid)
return;
}
- remote_vars_pa = remote_rp->sn.vars_pa;
+ remote_vars_pa = remote_rp->sn.sn2.vars_pa;
remote_rp_version = remote_rp->version;
remote_rp_ts_jiffies = remote_rp->ts_jiffies;
@@ -1129,7 +1162,7 @@ xpc_process_activate_IRQ_rcvd_sn2(void)
* Setup the channel structures that are sn2 specific.
*/
static enum xp_retval
-xpc_setup_ch_structures_sn_sn2(struct xpc_partition *part)
+xpc_setup_ch_structures_sn2(struct xpc_partition *part)
{
struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
struct xpc_channel_sn2 *ch_sn2;
@@ -1251,7 +1284,7 @@ out_1:
* Teardown the channel structures that are sn2 specific.
*/
static void
-xpc_teardown_ch_structures_sn_sn2(struct xpc_partition *part)
+xpc_teardown_ch_structures_sn2(struct xpc_partition *part)
{
struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
short partid = XPC_PARTID(part);
@@ -2315,61 +2348,70 @@ xpc_received_payload_sn2(struct xpc_channel *ch, void *payload)
xpc_acknowledge_msgs_sn2(ch, get, msg->flags);
}
+static struct xpc_arch_operations xpc_arch_ops_sn2 = {
+ .setup_partitions = xpc_setup_partitions_sn2,
+ .teardown_partitions = xpc_teardown_partitions_sn2,
+ .process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_sn2,
+ .get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2,
+ .setup_rsvd_page = xpc_setup_rsvd_page_sn2,
+
+ .allow_hb = xpc_allow_hb_sn2,
+ .disallow_hb = xpc_disallow_hb_sn2,
+ .disallow_all_hbs = xpc_disallow_all_hbs_sn2,
+ .increment_heartbeat = xpc_increment_heartbeat_sn2,
+ .offline_heartbeat = xpc_offline_heartbeat_sn2,
+ .online_heartbeat = xpc_online_heartbeat_sn2,
+ .heartbeat_init = xpc_heartbeat_init_sn2,
+ .heartbeat_exit = xpc_heartbeat_exit_sn2,
+ .get_remote_heartbeat = xpc_get_remote_heartbeat_sn2,
+
+ .request_partition_activation =
+ xpc_request_partition_activation_sn2,
+ .request_partition_reactivation =
+ xpc_request_partition_reactivation_sn2,
+ .request_partition_deactivation =
+ xpc_request_partition_deactivation_sn2,
+ .cancel_partition_deactivation_request =
+ xpc_cancel_partition_deactivation_request_sn2,
+
+ .setup_ch_structures = xpc_setup_ch_structures_sn2,
+ .teardown_ch_structures = xpc_teardown_ch_structures_sn2,
+
+ .make_first_contact = xpc_make_first_contact_sn2,
+
+ .get_chctl_all_flags = xpc_get_chctl_all_flags_sn2,
+ .send_chctl_closerequest = xpc_send_chctl_closerequest_sn2,
+ .send_chctl_closereply = xpc_send_chctl_closereply_sn2,
+ .send_chctl_openrequest = xpc_send_chctl_openrequest_sn2,
+ .send_chctl_openreply = xpc_send_chctl_openreply_sn2,
+ .send_chctl_opencomplete = xpc_send_chctl_opencomplete_sn2,
+ .process_msg_chctl_flags = xpc_process_msg_chctl_flags_sn2,
+
+ .save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_sn2,
+
+ .setup_msg_structures = xpc_setup_msg_structures_sn2,
+ .teardown_msg_structures = xpc_teardown_msg_structures_sn2,
+
+ .indicate_partition_engaged = xpc_indicate_partition_engaged_sn2,
+ .indicate_partition_disengaged = xpc_indicate_partition_disengaged_sn2,
+ .partition_engaged = xpc_partition_engaged_sn2,
+ .any_partition_engaged = xpc_any_partition_engaged_sn2,
+ .assume_partition_disengaged = xpc_assume_partition_disengaged_sn2,
+
+ .n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_sn2,
+ .send_payload = xpc_send_payload_sn2,
+ .get_deliverable_payload = xpc_get_deliverable_payload_sn2,
+ .received_payload = xpc_received_payload_sn2,
+ .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2,
+};
+
int
xpc_init_sn2(void)
{
int ret;
size_t buf_size;
- xpc_setup_partitions_sn = xpc_setup_partitions_sn_sn2;
- xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_sn2;
- xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2;
- xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_sn2;
- xpc_increment_heartbeat = xpc_increment_heartbeat_sn2;
- xpc_offline_heartbeat = xpc_offline_heartbeat_sn2;
- xpc_online_heartbeat = xpc_online_heartbeat_sn2;
- xpc_heartbeat_init = xpc_heartbeat_init_sn2;
- xpc_heartbeat_exit = xpc_heartbeat_exit_sn2;
- xpc_get_remote_heartbeat = xpc_get_remote_heartbeat_sn2;
-
- xpc_request_partition_activation = xpc_request_partition_activation_sn2;
- xpc_request_partition_reactivation =
- xpc_request_partition_reactivation_sn2;
- xpc_request_partition_deactivation =
- xpc_request_partition_deactivation_sn2;
- xpc_cancel_partition_deactivation_request =
- xpc_cancel_partition_deactivation_request_sn2;
-
- xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_sn2;
- xpc_setup_ch_structures_sn = xpc_setup_ch_structures_sn_sn2;
- xpc_teardown_ch_structures_sn = xpc_teardown_ch_structures_sn_sn2;
- xpc_make_first_contact = xpc_make_first_contact_sn2;
-
- xpc_get_chctl_all_flags = xpc_get_chctl_all_flags_sn2;
- xpc_send_chctl_closerequest = xpc_send_chctl_closerequest_sn2;
- xpc_send_chctl_closereply = xpc_send_chctl_closereply_sn2;
- xpc_send_chctl_openrequest = xpc_send_chctl_openrequest_sn2;
- xpc_send_chctl_openreply = xpc_send_chctl_openreply_sn2;
-
- xpc_save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_sn2;
-
- xpc_setup_msg_structures = xpc_setup_msg_structures_sn2;
- xpc_teardown_msg_structures = xpc_teardown_msg_structures_sn2;
-
- xpc_notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2;
- xpc_process_msg_chctl_flags = xpc_process_msg_chctl_flags_sn2;
- xpc_n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_sn2;
- xpc_get_deliverable_payload = xpc_get_deliverable_payload_sn2;
-
- xpc_indicate_partition_engaged = xpc_indicate_partition_engaged_sn2;
- xpc_indicate_partition_disengaged =
- xpc_indicate_partition_disengaged_sn2;
- xpc_partition_engaged = xpc_partition_engaged_sn2;
- xpc_any_partition_engaged = xpc_any_partition_engaged_sn2;
- xpc_assume_partition_disengaged = xpc_assume_partition_disengaged_sn2;
-
- xpc_send_payload = xpc_send_payload_sn2;
- xpc_received_payload = xpc_received_payload_sn2;
+ xpc_arch_ops = xpc_arch_ops_sn2;
if (offsetof(struct xpc_msg_sn2, payload) > XPC_MSG_HDR_MAX_SIZE) {
dev_err(xpc_part, "header portion of struct xpc_msg_sn2 is "
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
index f7fff4727ed..9172fcdee4e 100644
--- a/drivers/misc/sgi-xp/xpc_uv.c
+++ b/drivers/misc/sgi-xp/xpc_uv.c
@@ -46,8 +46,7 @@ struct uv_IO_APIC_route_entry {
};
#endif
-static atomic64_t xpc_heartbeat_uv;
-static DECLARE_BITMAP(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV);
+static struct xpc_heartbeat_uv *xpc_heartbeat_uv;
#define XPC_ACTIVATE_MSG_SIZE_UV (1 * GRU_CACHE_LINE_BYTES)
#define XPC_ACTIVATE_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \
@@ -63,7 +62,7 @@ static struct xpc_gru_mq_uv *xpc_activate_mq_uv;
static struct xpc_gru_mq_uv *xpc_notify_mq_uv;
static int
-xpc_setup_partitions_sn_uv(void)
+xpc_setup_partitions_uv(void)
{
short partid;
struct xpc_partition_uv *part_uv;
@@ -79,7 +78,7 @@ xpc_setup_partitions_sn_uv(void)
}
static void
-xpc_teardown_partitions_sn_uv(void)
+xpc_teardown_partitions_uv(void)
{
short partid;
struct xpc_partition_uv *part_uv;
@@ -423,41 +422,6 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
/* syncing of remote_act_state was just done above */
break;
- case XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV: {
- struct xpc_activate_mq_msg_heartbeat_req_uv *msg;
-
- msg = container_of(msg_hdr,
- struct xpc_activate_mq_msg_heartbeat_req_uv,
- hdr);
- part_uv->heartbeat = msg->heartbeat;
- break;
- }
- case XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV: {
- struct xpc_activate_mq_msg_heartbeat_req_uv *msg;
-
- msg = container_of(msg_hdr,
- struct xpc_activate_mq_msg_heartbeat_req_uv,
- hdr);
- part_uv->heartbeat = msg->heartbeat;
-
- spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
- part_uv->flags |= XPC_P_HEARTBEAT_OFFLINE_UV;
- spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
- break;
- }
- case XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV: {
- struct xpc_activate_mq_msg_heartbeat_req_uv *msg;
-
- msg = container_of(msg_hdr,
- struct xpc_activate_mq_msg_heartbeat_req_uv,
- hdr);
- part_uv->heartbeat = msg->heartbeat;
-
- spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
- part_uv->flags &= ~XPC_P_HEARTBEAT_OFFLINE_UV;
- spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
- break;
- }
case XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV: {
struct xpc_activate_mq_msg_activate_req_uv *msg;
@@ -475,6 +439,7 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV;
part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */
part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies;
+ part_uv->heartbeat_gpa = msg->heartbeat_gpa;
if (msg->activate_gru_mq_desc_gpa !=
part_uv->activate_gru_mq_desc_gpa) {
@@ -569,6 +534,17 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
xpc_wakeup_channel_mgr(part);
break;
}
+ case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: {
+ struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg;
+
+ msg = container_of(msg_hdr, struct
+ xpc_activate_mq_msg_chctl_opencomplete_uv, hdr);
+ spin_lock_irqsave(&part->chctl_lock, irq_flags);
+ part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENCOMPLETE;
+ spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
+
+ xpc_wakeup_channel_mgr(part);
+ }
case XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV:
spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
part_uv->flags |= XPC_P_ENGAGED_UV;
@@ -759,7 +735,7 @@ xpc_send_local_activate_IRQ_uv(struct xpc_partition *part, int act_state_req)
/*
* !!! Make our side think that the remote partition sent an activate
- * !!! message our way by doing what the activate IRQ handler would
+ * !!! mq message our way by doing what the activate IRQ handler would
* !!! do had one really been sent.
*/
@@ -806,90 +782,82 @@ xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa,
}
static int
-xpc_setup_rsvd_page_sn_uv(struct xpc_rsvd_page *rp)
+xpc_setup_rsvd_page_uv(struct xpc_rsvd_page *rp)
{
- rp->sn.activate_gru_mq_desc_gpa =
+ xpc_heartbeat_uv =
+ &xpc_partitions[sn_partition_id].sn.uv.cached_heartbeat;
+ rp->sn.uv.heartbeat_gpa = uv_gpa(xpc_heartbeat_uv);
+ rp->sn.uv.activate_gru_mq_desc_gpa =
uv_gpa(xpc_activate_mq_uv->gru_mq_desc);
return 0;
}
static void
-xpc_send_heartbeat_uv(int msg_type)
+xpc_allow_hb_uv(short partid)
{
- short partid;
- struct xpc_partition *part;
- struct xpc_activate_mq_msg_heartbeat_req_uv msg;
-
- /*
- * !!! On uv we're broadcasting a heartbeat message every 5 seconds.
- * !!! Whereas on sn2 we're bte_copy'ng the heartbeat info every 20
- * !!! seconds. This is an increase in numalink traffic.
- * ??? Is this good?
- */
-
- msg.heartbeat = atomic64_inc_return(&xpc_heartbeat_uv);
-
- partid = find_first_bit(xpc_heartbeating_to_mask_uv,
- XP_MAX_NPARTITIONS_UV);
-
- while (partid < XP_MAX_NPARTITIONS_UV) {
- part = &xpc_partitions[partid];
+}
- xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
- msg_type);
+static void
+xpc_disallow_hb_uv(short partid)
+{
+}
- partid = find_next_bit(xpc_heartbeating_to_mask_uv,
- XP_MAX_NPARTITIONS_UV, partid + 1);
- }
+static void
+xpc_disallow_all_hbs_uv(void)
+{
}
static void
xpc_increment_heartbeat_uv(void)
{
- xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV);
+ xpc_heartbeat_uv->value++;
}
static void
xpc_offline_heartbeat_uv(void)
{
- xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV);
+ xpc_increment_heartbeat_uv();
+ xpc_heartbeat_uv->offline = 1;
}
static void
xpc_online_heartbeat_uv(void)
{
- xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV);
+ xpc_increment_heartbeat_uv();
+ xpc_heartbeat_uv->offline = 0;
}
static void
xpc_heartbeat_init_uv(void)
{
- atomic64_set(&xpc_heartbeat_uv, 0);
- bitmap_zero(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV);
- xpc_heartbeating_to_mask = &xpc_heartbeating_to_mask_uv[0];
+ xpc_heartbeat_uv->value = 1;
+ xpc_heartbeat_uv->offline = 0;
}
static void
xpc_heartbeat_exit_uv(void)
{
- xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV);
+ xpc_offline_heartbeat_uv();
}
static enum xp_retval
xpc_get_remote_heartbeat_uv(struct xpc_partition *part)
{
struct xpc_partition_uv *part_uv = &part->sn.uv;
- enum xp_retval ret = xpNoHeartbeat;
+ enum xp_retval ret;
- if (part_uv->remote_act_state != XPC_P_AS_INACTIVE &&
- part_uv->remote_act_state != XPC_P_AS_DEACTIVATING) {
+ ret = xp_remote_memcpy(uv_gpa(&part_uv->cached_heartbeat),
+ part_uv->heartbeat_gpa,
+ sizeof(struct xpc_heartbeat_uv));
+ if (ret != xpSuccess)
+ return ret;
- if (part_uv->heartbeat != part->last_heartbeat ||
- (part_uv->flags & XPC_P_HEARTBEAT_OFFLINE_UV)) {
+ if (part_uv->cached_heartbeat.value == part->last_heartbeat &&
+ !part_uv->cached_heartbeat.offline) {
- part->last_heartbeat = part_uv->heartbeat;
- ret = xpSuccess;
- }
+ ret = xpNoHeartbeat;
+ } else {
+ part->last_heartbeat = part_uv->cached_heartbeat.value;
}
return ret;
}
@@ -904,8 +872,9 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
part->remote_rp_pa = remote_rp_gpa; /* !!! _pa here is really _gpa */
part->remote_rp_ts_jiffies = remote_rp->ts_jiffies;
+ part->sn.uv.heartbeat_gpa = remote_rp->sn.uv.heartbeat_gpa;
part->sn.uv.activate_gru_mq_desc_gpa =
- remote_rp->sn.activate_gru_mq_desc_gpa;
+ remote_rp->sn.uv.activate_gru_mq_desc_gpa;
/*
* ??? Is it a good idea to make this conditional on what is
@@ -913,8 +882,9 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
*/
if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) {
msg.rp_gpa = uv_gpa(xpc_rsvd_page);
+ msg.heartbeat_gpa = xpc_rsvd_page->sn.uv.heartbeat_gpa;
msg.activate_gru_mq_desc_gpa =
- xpc_rsvd_page->sn.activate_gru_mq_desc_gpa;
+ xpc_rsvd_page->sn.uv.activate_gru_mq_desc_gpa;
xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV);
}
@@ -1010,7 +980,7 @@ xpc_n_of_fifo_entries_uv(struct xpc_fifo_head_uv *head)
* Setup the channel structures that are uv specific.
*/
static enum xp_retval
-xpc_setup_ch_structures_sn_uv(struct xpc_partition *part)
+xpc_setup_ch_structures_uv(struct xpc_partition *part)
{
struct xpc_channel_uv *ch_uv;
int ch_number;
@@ -1029,7 +999,7 @@ xpc_setup_ch_structures_sn_uv(struct xpc_partition *part)
* Teardown the channel structures that are uv specific.
*/
static void
-xpc_teardown_ch_structures_sn_uv(struct xpc_partition *part)
+xpc_teardown_ch_structures_uv(struct xpc_partition *part)
{
/* nothing needs to be done */
return;
@@ -1243,6 +1213,16 @@ xpc_send_chctl_openreply_uv(struct xpc_channel *ch, unsigned long *irq_flags)
}
static void
+xpc_send_chctl_opencomplete_uv(struct xpc_channel *ch, unsigned long *irq_flags)
+{
+ struct xpc_activate_mq_msg_chctl_opencomplete_uv msg;
+
+ msg.ch_number = ch->number;
+ xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
+ XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV);
+}
+
+static void
xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number)
{
unsigned long irq_flags;
@@ -1669,58 +1649,67 @@ xpc_received_payload_uv(struct xpc_channel *ch, void *payload)
msg->hdr.msg_slot_number += ch->remote_nentries;
}
+static struct xpc_arch_operations xpc_arch_ops_uv = {
+ .setup_partitions = xpc_setup_partitions_uv,
+ .teardown_partitions = xpc_teardown_partitions_uv,
+ .process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv,
+ .get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv,
+ .setup_rsvd_page = xpc_setup_rsvd_page_uv,
+
+ .allow_hb = xpc_allow_hb_uv,
+ .disallow_hb = xpc_disallow_hb_uv,
+ .disallow_all_hbs = xpc_disallow_all_hbs_uv,
+ .increment_heartbeat = xpc_increment_heartbeat_uv,
+ .offline_heartbeat = xpc_offline_heartbeat_uv,
+ .online_heartbeat = xpc_online_heartbeat_uv,
+ .heartbeat_init = xpc_heartbeat_init_uv,
+ .heartbeat_exit = xpc_heartbeat_exit_uv,
+ .get_remote_heartbeat = xpc_get_remote_heartbeat_uv,
+
+ .request_partition_activation =
+ xpc_request_partition_activation_uv,
+ .request_partition_reactivation =
+ xpc_request_partition_reactivation_uv,
+ .request_partition_deactivation =
+ xpc_request_partition_deactivation_uv,
+ .cancel_partition_deactivation_request =
+ xpc_cancel_partition_deactivation_request_uv,
+
+ .setup_ch_structures = xpc_setup_ch_structures_uv,
+ .teardown_ch_structures = xpc_teardown_ch_structures_uv,
+
+ .make_first_contact = xpc_make_first_contact_uv,
+
+ .get_chctl_all_flags = xpc_get_chctl_all_flags_uv,
+ .send_chctl_closerequest = xpc_send_chctl_closerequest_uv,
+ .send_chctl_closereply = xpc_send_chctl_closereply_uv,
+ .send_chctl_openrequest = xpc_send_chctl_openrequest_uv,
+ .send_chctl_openreply = xpc_send_chctl_openreply_uv,
+ .send_chctl_opencomplete = xpc_send_chctl_opencomplete_uv,
+ .process_msg_chctl_flags = xpc_process_msg_chctl_flags_uv,
+
+ .save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv,
+
+ .setup_msg_structures = xpc_setup_msg_structures_uv,
+ .teardown_msg_structures = xpc_teardown_msg_structures_uv,
+
+ .indicate_partition_engaged = xpc_indicate_partition_engaged_uv,
+ .indicate_partition_disengaged = xpc_indicate_partition_disengaged_uv,
+ .assume_partition_disengaged = xpc_assume_partition_disengaged_uv,
+ .partition_engaged = xpc_partition_engaged_uv,
+ .any_partition_engaged = xpc_any_partition_engaged_uv,
+
+ .n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_uv,
+ .send_payload = xpc_send_payload_uv,
+ .get_deliverable_payload = xpc_get_deliverable_payload_uv,
+ .received_payload = xpc_received_payload_uv,
+ .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv,
+};
+
int
xpc_init_uv(void)
{
- xpc_setup_partitions_sn = xpc_setup_partitions_sn_uv;
- xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_uv;
- xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv;
- xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv;
- xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_uv;
- xpc_increment_heartbeat = xpc_increment_heartbeat_uv;
- xpc_offline_heartbeat = xpc_offline_heartbeat_uv;
- xpc_online_heartbeat = xpc_online_heartbeat_uv;
- xpc_heartbeat_init = xpc_heartbeat_init_uv;
- xpc_heartbeat_exit = xpc_heartbeat_exit_uv;
- xpc_get_remote_heartbeat = xpc_get_remote_heartbeat_uv;
-
- xpc_request_partition_activation = xpc_request_partition_activation_uv;
- xpc_request_partition_reactivation =
- xpc_request_partition_reactivation_uv;
- xpc_request_partition_deactivation =
- xpc_request_partition_deactivation_uv;
- xpc_cancel_partition_deactivation_request =
- xpc_cancel_partition_deactivation_request_uv;
-
- xpc_setup_ch_structures_sn = xpc_setup_ch_structures_sn_uv;
- xpc_teardown_ch_structures_sn = xpc_teardown_ch_structures_sn_uv;
-
- xpc_make_first_contact = xpc_make_first_contact_uv;
-
- xpc_get_chctl_all_flags = xpc_get_chctl_all_flags_uv;
- xpc_send_chctl_closerequest = xpc_send_chctl_closerequest_uv;
- xpc_send_chctl_closereply = xpc_send_chctl_closereply_uv;
- xpc_send_chctl_openrequest = xpc_send_chctl_openrequest_uv;
- xpc_send_chctl_openreply = xpc_send_chctl_openreply_uv;
-
- xpc_save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv;
-
- xpc_setup_msg_structures = xpc_setup_msg_structures_uv;
- xpc_teardown_msg_structures = xpc_teardown_msg_structures_uv;
-
- xpc_indicate_partition_engaged = xpc_indicate_partition_engaged_uv;
- xpc_indicate_partition_disengaged =
- xpc_indicate_partition_disengaged_uv;
- xpc_assume_partition_disengaged = xpc_assume_partition_disengaged_uv;
- xpc_partition_engaged = xpc_partition_engaged_uv;
- xpc_any_partition_engaged = xpc_any_partition_engaged_uv;
-
- xpc_n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_uv;
- xpc_process_msg_chctl_flags = xpc_process_msg_chctl_flags_uv;
- xpc_send_payload = xpc_send_payload_uv;
- xpc_notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv;
- xpc_get_deliverable_payload = xpc_get_deliverable_payload_uv;
- xpc_received_payload = xpc_received_payload_uv;
+ xpc_arch_ops = xpc_arch_ops_uv;
if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) {
dev_err(xpc_part, "xpc_notify_mq_msghdr_uv is larger than %d\n",
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
index be5672a9870..a6ef18259da 100644
--- a/drivers/misc/tifm_7xx1.c
+++ b/drivers/misc/tifm_7xx1.c
@@ -324,7 +324,7 @@ static int tifm_7xx1_probe(struct pci_dev *dev,
int pci_dev_busy = 0;
int rc;
- rc = pci_set_dma_mask(dev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(dev, DMA_BIT_MASK(32));
if (rc)
return rc;
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 513eb09a638..fe8041e619e 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -41,6 +41,8 @@
#include "queue.h"
+MODULE_ALIAS("mmc:block");
+
/*
* max 8 partitions per card
*/
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index f210a8ee686..bdb165f9304 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -84,6 +84,14 @@ mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
}
retval = add_uevent_var(env, "MMC_NAME=%s", mmc_card_name(card));
+ if (retval)
+ return retval;
+
+ /*
+ * Request the mmc_block device. Note: that this is a direct request
+ * for the module it carries no information as to what is inserted.
+ */
+ retval = add_uevent_var(env, "MODALIAS=mmc:block");
return retval;
}
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index df6ce4a06cf..fa073ab3fa3 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -21,6 +21,7 @@
#include <linux/leds.h>
#include <linux/scatterlist.h>
#include <linux/log2.h>
+#include <linux/regulator/consumer.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -297,6 +298,21 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
data->timeout_clks = 0;
}
}
+ /*
+ * Some cards need very high timeouts if driven in SPI mode.
+ * The worst observed timeout was 900ms after writing a
+ * continuous stream of data until the internal logic
+ * overflowed.
+ */
+ if (mmc_host_is_spi(card->host)) {
+ if (data->flags & MMC_DATA_WRITE) {
+ if (data->timeout_ns < 1000000000)
+ data->timeout_ns = 1000000000; /* 1s */
+ } else {
+ if (data->timeout_ns < 100000000)
+ data->timeout_ns = 100000000; /* 100ms */
+ }
+ }
}
EXPORT_SYMBOL(mmc_set_data_timeout);
@@ -523,6 +539,105 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max)
}
EXPORT_SYMBOL(mmc_vddrange_to_ocrmask);
+#ifdef CONFIG_REGULATOR
+
+/**
+ * mmc_regulator_get_ocrmask - return mask of supported voltages
+ * @supply: regulator to use
+ *
+ * This returns either a negative errno, or a mask of voltages that
+ * can be provided to MMC/SD/SDIO devices using the specified voltage
+ * regulator. This would normally be called before registering the
+ * MMC host adapter.
+ */
+int mmc_regulator_get_ocrmask(struct regulator *supply)
+{
+ int result = 0;
+ int count;
+ int i;
+
+ count = regulator_count_voltages(supply);
+ if (count < 0)
+ return count;
+
+ for (i = 0; i < count; i++) {
+ int vdd_uV;
+ int vdd_mV;
+
+ vdd_uV = regulator_list_voltage(supply, i);
+ if (vdd_uV <= 0)
+ continue;
+
+ vdd_mV = vdd_uV / 1000;
+ result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV);
+ }
+
+ return result;
+}
+EXPORT_SYMBOL(mmc_regulator_get_ocrmask);
+
+/**
+ * mmc_regulator_set_ocr - set regulator to match host->ios voltage
+ * @vdd_bit: zero for power off, else a bit number (host->ios.vdd)
+ * @supply: regulator to use
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * MMC host drivers may use this to enable or disable a regulator using
+ * a particular supply voltage. This would normally be called from the
+ * set_ios() method.
+ */
+int mmc_regulator_set_ocr(struct regulator *supply, unsigned short vdd_bit)
+{
+ int result = 0;
+ int min_uV, max_uV;
+ int enabled;
+
+ enabled = regulator_is_enabled(supply);
+ if (enabled < 0)
+ return enabled;
+
+ if (vdd_bit) {
+ int tmp;
+ int voltage;
+
+ /* REVISIT mmc_vddrange_to_ocrmask() may have set some
+ * bits this regulator doesn't quite support ... don't
+ * be too picky, most cards and regulators are OK with
+ * a 0.1V range goof (it's a small error percentage).
+ */
+ tmp = vdd_bit - ilog2(MMC_VDD_165_195);
+ if (tmp == 0) {
+ min_uV = 1650 * 1000;
+ max_uV = 1950 * 1000;
+ } else {
+ min_uV = 1900 * 1000 + tmp * 100 * 1000;
+ max_uV = min_uV + 100 * 1000;
+ }
+
+ /* avoid needless changes to this voltage; the regulator
+ * might not allow this operation
+ */
+ voltage = regulator_get_voltage(supply);
+ if (voltage < 0)
+ result = voltage;
+ else if (voltage < min_uV || voltage > max_uV)
+ result = regulator_set_voltage(supply, min_uV, max_uV);
+ else
+ result = 0;
+
+ if (result == 0 && !enabled)
+ result = regulator_enable(supply);
+ } else if (enabled) {
+ result = regulator_disable(supply);
+ }
+
+ return result;
+}
+EXPORT_SYMBOL(mmc_regulator_set_ocr);
+
+#endif
+
/*
* Mask off any voltages we don't support and select
* the lowest voltage
@@ -815,6 +930,7 @@ void mmc_stop_host(struct mmc_host *host)
spin_unlock_irqrestore(&host->lock, flags);
#endif
+ cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
mmc_bus_get(host);
@@ -842,6 +958,7 @@ void mmc_stop_host(struct mmc_host *host)
*/
int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
{
+ cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
mmc_bus_get(host);
@@ -875,6 +992,7 @@ int mmc_resume_host(struct mmc_host *host)
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
mmc_power_up(host);
+ mmc_select_voltage(host, host->ocr);
BUG_ON(!host->bus_ops->resume);
host->bus_ops->resume(host);
}
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 1237bb4c722..610dbd1fcc8 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -184,6 +184,68 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(mmc_dbg_card_status_fops, mmc_dbg_card_status_get,
NULL, "%08llx\n");
+#define EXT_CSD_STR_LEN 1025
+
+static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
+{
+ struct mmc_card *card = inode->i_private;
+ char *buf;
+ ssize_t n = 0;
+ u8 *ext_csd;
+ int err, i;
+
+ buf = kmalloc(EXT_CSD_STR_LEN + 1, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ ext_csd = kmalloc(512, GFP_KERNEL);
+ if (!ext_csd) {
+ err = -ENOMEM;
+ goto out_free;
+ }
+
+ mmc_claim_host(card->host);
+ err = mmc_send_ext_csd(card, ext_csd);
+ mmc_release_host(card->host);
+ if (err)
+ goto out_free;
+
+ for (i = 511; i >= 0; i--)
+ n += sprintf(buf + n, "%02x", ext_csd[i]);
+ n += sprintf(buf + n, "\n");
+ BUG_ON(n != EXT_CSD_STR_LEN);
+
+ filp->private_data = buf;
+ kfree(ext_csd);
+ return 0;
+
+out_free:
+ kfree(buf);
+ kfree(ext_csd);
+ return err;
+}
+
+static ssize_t mmc_ext_csd_read(struct file *filp, char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ char *buf = filp->private_data;
+
+ return simple_read_from_buffer(ubuf, cnt, ppos,
+ buf, EXT_CSD_STR_LEN);
+}
+
+static int mmc_ext_csd_release(struct inode *inode, struct file *file)
+{
+ kfree(file->private_data);
+ return 0;
+}
+
+static struct file_operations mmc_dbg_ext_csd_fops = {
+ .open = mmc_ext_csd_open,
+ .read = mmc_ext_csd_read,
+ .release = mmc_ext_csd_release,
+};
+
void mmc_add_card_debugfs(struct mmc_card *card)
{
struct mmc_host *host = card->host;
@@ -211,6 +273,11 @@ void mmc_add_card_debugfs(struct mmc_card *card)
&mmc_dbg_card_status_fops))
goto err;
+ if (mmc_card_mmc(card))
+ if (!debugfs_create_file("ext_csd", S_IRUSR, root, card,
+ &mmc_dbg_ext_csd_fops))
+ goto err;
+
return;
err:
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index c232d11a7ed..06084dbf127 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -208,7 +208,7 @@ static int mmc_read_ext_csd(struct mmc_card *card)
}
ext_csd_struct = ext_csd[EXT_CSD_REV];
- if (ext_csd_struct > 2) {
+ if (ext_csd_struct > 3) {
printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
"version %d\n", mmc_hostname(card->host),
ext_csd_struct);
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 26fc098d77c..cd81c395e16 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -363,15 +363,6 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
goto err;
/*
- * For SPI, enable CRC as appropriate.
- */
- if (mmc_host_is_spi(host)) {
- err = mmc_spi_set_crc(host, use_spi_crc);
- if (err)
- goto err;
- }
-
- /*
* Fetch CID from card.
*/
if (mmc_host_is_spi(host))
@@ -458,6 +449,18 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
}
/*
+ * For SPI, enable CRC as appropriate.
+ * This CRC enable is located AFTER the reading of the
+ * card registers because some SDHC cards are not able
+ * to provide valid CRCs for non-512-byte blocks.
+ */
+ if (mmc_host_is_spi(host)) {
+ err = mmc_spi_set_crc(host, use_spi_crc);
+ if (err)
+ goto free_card;
+ }
+
+ /*
* Attempt to change to high-speed (if supported)
*/
err = mmc_switch_hs(card);
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c
index 956bd767750..963f2937c5e 100644
--- a/drivers/mmc/core/sdio_cis.c
+++ b/drivers/mmc/core/sdio_cis.c
@@ -223,10 +223,18 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
if (tpl_code == 0xff)
break;
+ /* null entries have no link field or data */
+ if (tpl_code == 0x00)
+ continue;
+
ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_link);
if (ret)
break;
+ /* a size of 0xff also means we're done */
+ if (tpl_link == 0xff)
+ break;
+
this = kmalloc(sizeof(*this) + tpl_link, GFP_KERNEL);
if (!this)
return -ENOMEM;
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
index c8fa095a448..4eb7825fd1a 100644
--- a/drivers/mmc/core/sdio_ops.c
+++ b/drivers/mmc/core/sdio_ops.c
@@ -76,6 +76,10 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
BUG_ON(!card);
BUG_ON(fn > 7);
+ /* sanity check */
+ if (addr & ~0x1FFFF)
+ return -EINVAL;
+
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = SD_IO_RW_DIRECT;
@@ -125,6 +129,10 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
WARN_ON(blocks == 0);
WARN_ON(blksz == 0);
+ /* sanity check */
+ if (addr & ~0x1FFFF)
+ return -EINVAL;
+
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 99d4b28d52e..b4cf691f3f6 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -37,6 +37,13 @@ config MMC_SDHCI
If unsure, say N.
+config MMC_SDHCI_IO_ACCESSORS
+ bool
+ depends on MMC_SDHCI
+ help
+ This is silent Kconfig symbol that is selected by the drivers that
+ need to overwrite SDHCI IO memory accessors.
+
config MMC_SDHCI_PCI
tristate "SDHCI support on PCI bus"
depends on MMC_SDHCI && PCI
@@ -65,6 +72,17 @@ config MMC_RICOH_MMC
If unsure, say Y.
+config MMC_SDHCI_OF
+ tristate "SDHCI support on OpenFirmware platforms"
+ depends on MMC_SDHCI && PPC_OF
+ select MMC_SDHCI_IO_ACCESSORS
+ help
+ This selects the OF support for Secure Digital Host Controller
+ Interfaces. So far, only the Freescale eSDHC controller is known
+ to exist on OF platforms.
+
+ If unsure, say N.
+
config MMC_OMAP
tristate "TI OMAP Multimedia Card Interface support"
depends on ARCH_OMAP
@@ -171,13 +189,24 @@ config MMC_TIFM_SD
To compile this driver as a module, choose M here: the
module will be called tifm_sd.
+config MMC_MVSDIO
+ tristate "Marvell MMC/SD/SDIO host driver"
+ depends on PLAT_ORION
+ ---help---
+ This selects the Marvell SDIO host driver.
+ SDIO may currently be found on the Kirkwood 88F6281 and 88F6192
+ SoC controllers.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mvsdio.
+
config MMC_SPI
tristate "MMC/SD/SDIO over SPI"
depends on SPI_MASTER && !HIGHMEM && HAS_DMA
select CRC7
select CRC_ITU_T
help
- Some systems accss MMC/SD/SDIO cards using a SPI controller
+ Some systems access MMC/SD/SDIO cards using a SPI controller
instead of using a "native" MMC/SD/SDIO controller. This has a
disadvantage of being relatively high overhead, but a compensating
advantage of working on many systems without dedicated MMC/SD/SDIO
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index dedec55861d..970a997620e 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o
+obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o
obj-$(CONFIG_MMC_WBSD) += wbsd.o
obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
obj-$(CONFIG_MMC_OMAP) += omap.o
@@ -20,6 +21,7 @@ obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o
obj-$(CONFIG_MMC_AT91) += at91_mci.o
obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o
obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
+obj-$(CONFIG_MMC_MVSDIO) += mvsdio.o
obj-$(CONFIG_MMC_SPI) += mmc_spi.o
ifeq ($(CONFIG_OF),y)
obj-$(CONFIG_MMC_SPI) += of_mmc_spi.o
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index e94e92001e7..cf6a100bb38 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -812,7 +812,7 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
slot->sdc_reg |= MCI_SDCBUS_1BIT;
break;
case MMC_BUS_WIDTH_4:
- slot->sdc_reg = MCI_SDCBUS_4BIT;
+ slot->sdc_reg |= MCI_SDCBUS_4BIT;
break;
}
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c
index eb29b1d933a..e0be21a4a69 100644
--- a/drivers/mmc/host/imxmmc.c
+++ b/drivers/mmc/host/imxmmc.c
@@ -307,13 +307,6 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data)
wmb();
- if (host->actual_bus_width == MMC_BUS_WIDTH_4)
- BLR(host->dma) = 0; /* burst 64 byte read / 64 bytes write */
- else
- BLR(host->dma) = 16; /* burst 16 byte read / 16 bytes write */
-
- RSSR(host->dma) = DMA_REQ_SDHC;
-
set_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
clear_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events);
@@ -818,9 +811,11 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (ios->bus_width == MMC_BUS_WIDTH_4) {
host->actual_bus_width = MMC_BUS_WIDTH_4;
imx_gpio_mode(PB11_PF_SD_DAT3);
+ BLR(host->dma) = 0; /* burst 64 byte read/write */
} else {
host->actual_bus_width = MMC_BUS_WIDTH_1;
imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11);
+ BLR(host->dma) = 16; /* burst 16 byte read/write */
}
if (host->power_mode != ios->power_mode) {
@@ -938,7 +933,7 @@ static void imxmci_check_status(unsigned long data)
mod_timer(&host->timer, jiffies + (HZ>>1));
}
-static int imxmci_probe(struct platform_device *pdev)
+static int __init imxmci_probe(struct platform_device *pdev)
{
struct mmc_host *mmc;
struct imxmci_host *host = NULL;
@@ -1034,6 +1029,7 @@ static int imxmci_probe(struct platform_device *pdev)
}
host->dma_allocated = 1;
imx_dma_setup_handlers(host->dma, imxmci_dma_irq, NULL, host);
+ RSSR(host->dma) = DMA_REQ_SDHC;
tasklet_init(&host->tasklet, imxmci_tasklet_fnc, (unsigned long)host);
host->status_reg=0;
@@ -1079,7 +1075,7 @@ out:
return ret;
}
-static int imxmci_remove(struct platform_device *pdev)
+static int __exit imxmci_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
@@ -1145,8 +1141,7 @@ static int imxmci_resume(struct platform_device *dev)
#endif /* CONFIG_PM */
static struct platform_driver imxmci_driver = {
- .probe = imxmci_probe,
- .remove = imxmci_remove,
+ .remove = __exit_p(imxmci_remove),
.suspend = imxmci_suspend,
.resume = imxmci_resume,
.driver = {
@@ -1157,7 +1152,7 @@ static struct platform_driver imxmci_driver = {
static int __init imxmci_init(void)
{
- return platform_driver_register(&imxmci_driver);
+ return platform_driver_probe(&imxmci_driver, imxmci_probe);
}
static void __exit imxmci_exit(void)
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 87e211df68a..f48349d18c9 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -24,7 +24,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/hrtimer.h>
+#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/bio.h>
#include <linux/dma-mapping.h>
@@ -95,7 +95,7 @@
* reads which takes nowhere near that long. Older cards may be able to use
* shorter timeouts ... but why bother?
*/
-#define r1b_timeout ktime_set(3, 0)
+#define r1b_timeout (HZ * 3)
/****************************************************************************/
@@ -183,12 +183,11 @@ mmc_spi_readbytes(struct mmc_spi_host *host, unsigned len)
return status;
}
-static int
-mmc_spi_skip(struct mmc_spi_host *host, ktime_t timeout, unsigned n, u8 byte)
+static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout,
+ unsigned n, u8 byte)
{
u8 *cp = host->data->status;
-
- timeout = ktime_add(timeout, ktime_get());
+ unsigned long start = jiffies;
while (1) {
int status;
@@ -203,22 +202,26 @@ mmc_spi_skip(struct mmc_spi_host *host, ktime_t timeout, unsigned n, u8 byte)
return cp[i];
}
- /* REVISIT investigate msleep() to avoid busy-wait I/O
- * in at least some cases.
- */
- if (ktime_to_ns(ktime_sub(ktime_get(), timeout)) > 0)
+ if (time_is_before_jiffies(start + timeout))
break;
+
+ /* If we need long timeouts, we may release the CPU.
+ * We use jiffies here because we want to have a relation
+ * between elapsed time and the blocking of the scheduler.
+ */
+ if (time_is_before_jiffies(start+1))
+ schedule();
}
return -ETIMEDOUT;
}
static inline int
-mmc_spi_wait_unbusy(struct mmc_spi_host *host, ktime_t timeout)
+mmc_spi_wait_unbusy(struct mmc_spi_host *host, unsigned long timeout)
{
return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0);
}
-static int mmc_spi_readtoken(struct mmc_spi_host *host, ktime_t timeout)
+static int mmc_spi_readtoken(struct mmc_spi_host *host, unsigned long timeout)
{
return mmc_spi_skip(host, timeout, 1, 0xff);
}
@@ -251,6 +254,10 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
u8 *cp = host->data->status;
u8 *end = cp + host->t.len;
int value = 0;
+ int bitshift;
+ u8 leftover = 0;
+ unsigned short rotator;
+ int i;
char tag[32];
snprintf(tag, sizeof(tag), " ... CMD%d response SPI_%s",
@@ -268,9 +275,8 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
/* Data block reads (R1 response types) may need more data... */
if (cp == end) {
- unsigned i;
-
cp = host->data->status;
+ end = cp+1;
/* Card sends N(CR) (== 1..8) bytes of all-ones then one
* status byte ... and we already scanned 2 bytes.
@@ -279,8 +285,11 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
* so it can always DMA directly into the target buffer.
* It'd probably be better to memcpy() the first chunk and
* avoid extra i/o calls...
+ *
+ * Note we check for more than 8 bytes, because in practice,
+ * some SD cards are slow...
*/
- for (i = 2; i < 9; i++) {
+ for (i = 2; i < 16; i++) {
value = mmc_spi_readbytes(host, 1);
if (value < 0)
goto done;
@@ -292,20 +301,34 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
}
checkstatus:
- if (*cp & 0x80) {
- dev_dbg(&host->spi->dev, "%s: INVALID RESPONSE, %02x\n",
- tag, *cp);
- value = -EBADR;
- goto done;
+ bitshift = 0;
+ if (*cp & 0x80) {
+ /* Houston, we have an ugly card with a bit-shifted response */
+ rotator = *cp++ << 8;
+ /* read the next byte */
+ if (cp == end) {
+ value = mmc_spi_readbytes(host, 1);
+ if (value < 0)
+ goto done;
+ cp = host->data->status;
+ end = cp+1;
+ }
+ rotator |= *cp++;
+ while (rotator & 0x8000) {
+ bitshift++;
+ rotator <<= 1;
+ }
+ cmd->resp[0] = rotator >> 8;
+ leftover = rotator;
+ } else {
+ cmd->resp[0] = *cp++;
}
-
- cmd->resp[0] = *cp++;
cmd->error = 0;
/* Status byte: the entire seven-bit R1 response. */
if (cmd->resp[0] != 0) {
if ((R1_SPI_PARAMETER | R1_SPI_ADDRESS
- | R1_SPI_ILLEGAL_COMMAND)
+ | R1_SPI_ILLEGAL_COMMAND)
& cmd->resp[0])
value = -EINVAL;
else if (R1_SPI_COM_CRC & cmd->resp[0])
@@ -333,12 +356,45 @@ checkstatus:
* SPI R5 == R1 + data byte; IO_RW_DIRECT
*/
case MMC_RSP_SPI_R2:
- cmd->resp[0] |= *cp << 8;
+ /* read the next byte */
+ if (cp == end) {
+ value = mmc_spi_readbytes(host, 1);
+ if (value < 0)
+ goto done;
+ cp = host->data->status;
+ end = cp+1;
+ }
+ if (bitshift) {
+ rotator = leftover << 8;
+ rotator |= *cp << bitshift;
+ cmd->resp[0] |= (rotator & 0xFF00);
+ } else {
+ cmd->resp[0] |= *cp << 8;
+ }
break;
/* SPI R3, R4, or R7 == R1 + 4 bytes */
case MMC_RSP_SPI_R3:
- cmd->resp[1] = get_unaligned_be32(cp);
+ rotator = leftover << 8;
+ cmd->resp[1] = 0;
+ for (i = 0; i < 4; i++) {
+ cmd->resp[1] <<= 8;
+ /* read the next byte */
+ if (cp == end) {
+ value = mmc_spi_readbytes(host, 1);
+ if (value < 0)
+ goto done;
+ cp = host->data->status;
+ end = cp+1;
+ }
+ if (bitshift) {
+ rotator |= *cp++ << bitshift;
+ cmd->resp[1] |= (rotator >> 8);
+ rotator <<= 8;
+ } else {
+ cmd->resp[1] |= *cp++;
+ }
+ }
break;
/* SPI R1 == just one status byte */
@@ -604,11 +660,12 @@ mmc_spi_setup_data_message(
*/
static int
mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
- ktime_t timeout)
+ unsigned long timeout)
{
struct spi_device *spi = host->spi;
int status, i;
struct scratch *scratch = host->data;
+ u32 pattern;
if (host->mmc->use_spi_crc)
scratch->crc_val = cpu_to_be16(
@@ -636,8 +693,27 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
* doesn't necessarily tell whether the write operation succeeded;
* it just says if the transmission was ok and whether *earlier*
* writes succeeded; see the standard.
+ *
+ * In practice, there are (even modern SDHC-)cards which are late
+ * in sending the response, and miss the time frame by a few bits,
+ * so we have to cope with this situation and check the response
+ * bit-by-bit. Arggh!!!
*/
- switch (SPI_MMC_RESPONSE_CODE(scratch->status[0])) {
+ pattern = scratch->status[0] << 24;
+ pattern |= scratch->status[1] << 16;
+ pattern |= scratch->status[2] << 8;
+ pattern |= scratch->status[3];
+
+ /* First 3 bit of pattern are undefined */
+ pattern |= 0xE0000000;
+
+ /* left-adjust to leading 0 bit */
+ while (pattern & 0x80000000)
+ pattern <<= 1;
+ /* right-adjust for pattern matching. Code is in bit 4..0 now. */
+ pattern >>= 27;
+
+ switch (pattern) {
case SPI_RESPONSE_ACCEPTED:
status = 0;
break;
@@ -668,8 +744,9 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
/* Return when not busy. If we didn't collect that status yet,
* we'll need some more I/O.
*/
- for (i = 1; i < sizeof(scratch->status); i++) {
- if (scratch->status[i] != 0)
+ for (i = 4; i < sizeof(scratch->status); i++) {
+ /* card is non-busy if the most recent bit is 1 */
+ if (scratch->status[i] & 0x01)
return 0;
}
return mmc_spi_wait_unbusy(host, timeout);
@@ -693,11 +770,13 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
*/
static int
mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
- ktime_t timeout)
+ unsigned long timeout)
{
struct spi_device *spi = host->spi;
int status;
struct scratch *scratch = host->data;
+ unsigned int bitshift;
+ u8 leftover;
/* At least one SD card sends an all-zeroes byte when N(CX)
* applies, before the all-ones bytes ... just cope with that.
@@ -709,38 +788,60 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
if (status == 0xff || status == 0)
status = mmc_spi_readtoken(host, timeout);
- if (status == SPI_TOKEN_SINGLE) {
- if (host->dma_dev) {
- dma_sync_single_for_device(host->dma_dev,
- host->data_dma, sizeof(*scratch),
- DMA_BIDIRECTIONAL);
- dma_sync_single_for_device(host->dma_dev,
- t->rx_dma, t->len,
- DMA_FROM_DEVICE);
- }
+ if (status < 0) {
+ dev_dbg(&spi->dev, "read error %02x (%d)\n", status, status);
+ return status;
+ }
- status = spi_sync(spi, &host->m);
+ /* The token may be bit-shifted...
+ * the first 0-bit precedes the data stream.
+ */
+ bitshift = 7;
+ while (status & 0x80) {
+ status <<= 1;
+ bitshift--;
+ }
+ leftover = status << 1;
- if (host->dma_dev) {
- dma_sync_single_for_cpu(host->dma_dev,
- host->data_dma, sizeof(*scratch),
- DMA_BIDIRECTIONAL);
- dma_sync_single_for_cpu(host->dma_dev,
- t->rx_dma, t->len,
- DMA_FROM_DEVICE);
- }
+ if (host->dma_dev) {
+ dma_sync_single_for_device(host->dma_dev,
+ host->data_dma, sizeof(*scratch),
+ DMA_BIDIRECTIONAL);
+ dma_sync_single_for_device(host->dma_dev,
+ t->rx_dma, t->len,
+ DMA_FROM_DEVICE);
+ }
- } else {
- dev_dbg(&spi->dev, "read error %02x (%d)\n", status, status);
+ status = spi_sync(spi, &host->m);
- /* we've read extra garbage, timed out, etc */
- if (status < 0)
- return status;
+ if (host->dma_dev) {
+ dma_sync_single_for_cpu(host->dma_dev,
+ host->data_dma, sizeof(*scratch),
+ DMA_BIDIRECTIONAL);
+ dma_sync_single_for_cpu(host->dma_dev,
+ t->rx_dma, t->len,
+ DMA_FROM_DEVICE);
+ }
- /* low four bits are an R2 subset, fifth seems to be
- * vendor specific ... map them all to generic error..
+ if (bitshift) {
+ /* Walk through the data and the crc and do
+ * all the magic to get byte-aligned data.
*/
- return -EIO;
+ u8 *cp = t->rx_buf;
+ unsigned int len;
+ unsigned int bitright = 8 - bitshift;
+ u8 temp;
+ for (len = t->len; len; len--) {
+ temp = *cp;
+ *cp++ = leftover | (temp >> bitshift);
+ leftover = temp << bitright;
+ }
+ cp = (u8 *) &scratch->crc_val;
+ temp = *cp;
+ *cp++ = leftover | (temp >> bitshift);
+ leftover = temp << bitright;
+ temp = *cp;
+ *cp = leftover | (temp >> bitshift);
}
if (host->mmc->use_spi_crc) {
@@ -779,7 +880,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
unsigned n_sg;
int multiple = (data->blocks > 1);
u32 clock_rate;
- ktime_t timeout;
+ unsigned long timeout;
if (data->flags & MMC_DATA_READ)
direction = DMA_FROM_DEVICE;
@@ -793,8 +894,9 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
else
clock_rate = spi->max_speed_hz;
- timeout = ktime_add_ns(ktime_set(0, 0), data->timeout_ns +
- data->timeout_clks * 1000000 / clock_rate);
+ timeout = data->timeout_ns +
+ data->timeout_clks * 1000000 / clock_rate;
+ timeout = usecs_to_jiffies((unsigned int)(timeout / 1000)) + 1;
/* Handle scatterlist segments one at a time, with synch for
* each 512-byte block
@@ -1204,10 +1306,12 @@ static int mmc_spi_probe(struct spi_device *spi)
/* MMC and SD specs only seem to care that sampling is on the
* rising edge ... meaning SPI modes 0 or 3. So either SPI mode
- * should be legit. We'll use mode 0 since it seems to be a
- * bit less troublesome on some hardware ... unclear why.
+ * should be legit. We'll use mode 0 since the steady state is 0,
+ * which is appropriate for hotplugging, unless the platform data
+ * specify mode 3 (if hardware is not compatible to mode 0).
*/
- spi->mode = SPI_MODE_0;
+ if (spi->mode != SPI_MODE_3)
+ spi->mode = SPI_MODE_0;
spi->bits_per_word = 8;
status = spi_setup(spi);
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
new file mode 100644
index 00000000000..b5c375d94ab
--- /dev/null
+++ b/drivers/mmc/host/mvsdio.c
@@ -0,0 +1,885 @@
+/*
+ * Marvell MMC/SD/SDIO driver
+ *
+ * Authors: Maen Suleiman, Nicolas Pitre
+ * Copyright (C) 2008-2009 Marvell Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/mbus.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+
+#include <asm/sizes.h>
+#include <asm/unaligned.h>
+#include <plat/mvsdio.h>
+
+#include "mvsdio.h"
+
+#define DRIVER_NAME "mvsdio"
+
+static int maxfreq = MVSD_CLOCKRATE_MAX;
+static int nodma;
+
+struct mvsd_host {
+ void __iomem *base;
+ struct mmc_request *mrq;
+ spinlock_t lock;
+ unsigned int xfer_mode;
+ unsigned int intr_en;
+ unsigned int ctrl;
+ unsigned int pio_size;
+ void *pio_ptr;
+ unsigned int sg_frags;
+ unsigned int ns_per_clk;
+ unsigned int clock;
+ unsigned int base_clock;
+ struct timer_list timer;
+ struct mmc_host *mmc;
+ struct device *dev;
+ struct resource *res;
+ int irq;
+ int gpio_card_detect;
+ int gpio_write_protect;
+};
+
+#define mvsd_write(offs, val) writel(val, iobase + (offs))
+#define mvsd_read(offs) readl(iobase + (offs))
+
+static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
+{
+ void __iomem *iobase = host->base;
+ unsigned int tmout;
+ int tmout_index;
+
+ /* If timeout=0 then maximum timeout index is used. */
+ tmout = DIV_ROUND_UP(data->timeout_ns, host->ns_per_clk);
+ tmout += data->timeout_clks;
+ tmout_index = fls(tmout - 1) - 12;
+ if (tmout_index < 0)
+ tmout_index = 0;
+ if (tmout_index > MVSD_HOST_CTRL_TMOUT_MAX)
+ tmout_index = MVSD_HOST_CTRL_TMOUT_MAX;
+
+ dev_dbg(host->dev, "data %s at 0x%08x: blocks=%d blksz=%d tmout=%u (%d)\n",
+ (data->flags & MMC_DATA_READ) ? "read" : "write",
+ (u32)sg_virt(data->sg), data->blocks, data->blksz,
+ tmout, tmout_index);
+
+ host->ctrl &= ~MVSD_HOST_CTRL_TMOUT_MASK;
+ host->ctrl |= MVSD_HOST_CTRL_TMOUT(tmout_index);
+ mvsd_write(MVSD_HOST_CTRL, host->ctrl);
+ mvsd_write(MVSD_BLK_COUNT, data->blocks);
+ mvsd_write(MVSD_BLK_SIZE, data->blksz);
+
+ if (nodma || (data->blksz | data->sg->offset) & 3) {
+ /*
+ * We cannot do DMA on a buffer which offset or size
+ * is not aligned on a 4-byte boundary.
+ */
+ host->pio_size = data->blocks * data->blksz;
+ host->pio_ptr = sg_virt(data->sg);
+ if (!nodma)
+ printk(KERN_DEBUG "%s: fallback to PIO for data "
+ "at 0x%p size %d\n",
+ mmc_hostname(host->mmc),
+ host->pio_ptr, host->pio_size);
+ return 1;
+ } else {
+ dma_addr_t phys_addr;
+ int dma_dir = (data->flags & MMC_DATA_READ) ?
+ DMA_FROM_DEVICE : DMA_TO_DEVICE;
+ host->sg_frags = dma_map_sg(mmc_dev(host->mmc), data->sg,
+ data->sg_len, dma_dir);
+ phys_addr = sg_dma_address(data->sg);
+ mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff);
+ mvsd_write(MVSD_SYS_ADDR_HI, (u32)phys_addr >> 16);
+ return 0;
+ }
+}
+
+static void mvsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ struct mvsd_host *host = mmc_priv(mmc);
+ void __iomem *iobase = host->base;
+ struct mmc_command *cmd = mrq->cmd;
+ u32 cmdreg = 0, xfer = 0, intr = 0;
+ unsigned long flags;
+
+ BUG_ON(host->mrq != NULL);
+ host->mrq = mrq;
+
+ dev_dbg(host->dev, "cmd %d (hw state 0x%04x)\n",
+ cmd->opcode, mvsd_read(MVSD_HW_STATE));
+
+ cmdreg = MVSD_CMD_INDEX(cmd->opcode);
+
+ if (cmd->flags & MMC_RSP_BUSY)
+ cmdreg |= MVSD_CMD_RSP_48BUSY;
+ else if (cmd->flags & MMC_RSP_136)
+ cmdreg |= MVSD_CMD_RSP_136;
+ else if (cmd->flags & MMC_RSP_PRESENT)
+ cmdreg |= MVSD_CMD_RSP_48;
+ else
+ cmdreg |= MVSD_CMD_RSP_NONE;
+
+ if (cmd->flags & MMC_RSP_CRC)
+ cmdreg |= MVSD_CMD_CHECK_CMDCRC;
+
+ if (cmd->flags & MMC_RSP_OPCODE)
+ cmdreg |= MVSD_CMD_INDX_CHECK;
+
+ if (cmd->flags & MMC_RSP_PRESENT) {
+ cmdreg |= MVSD_UNEXPECTED_RESP;
+ intr |= MVSD_NOR_UNEXP_RSP;
+ }
+
+ if (mrq->data) {
+ struct mmc_data *data = mrq->data;
+ int pio;
+
+ cmdreg |= MVSD_CMD_DATA_PRESENT | MVSD_CMD_CHECK_DATACRC16;
+ xfer |= MVSD_XFER_MODE_HW_WR_DATA_EN;
+ if (data->flags & MMC_DATA_READ)
+ xfer |= MVSD_XFER_MODE_TO_HOST;
+
+ pio = mvsd_setup_data(host, data);
+ if (pio) {
+ xfer |= MVSD_XFER_MODE_PIO;
+ /* PIO section of mvsd_irq has comments on those bits */
+ if (data->flags & MMC_DATA_WRITE)
+ intr |= MVSD_NOR_TX_AVAIL;
+ else if (host->pio_size > 32)
+ intr |= MVSD_NOR_RX_FIFO_8W;
+ else
+ intr |= MVSD_NOR_RX_READY;
+ }
+
+ if (data->stop) {
+ struct mmc_command *stop = data->stop;
+ u32 cmd12reg = 0;
+
+ mvsd_write(MVSD_AUTOCMD12_ARG_LOW, stop->arg & 0xffff);
+ mvsd_write(MVSD_AUTOCMD12_ARG_HI, stop->arg >> 16);
+
+ if (stop->flags & MMC_RSP_BUSY)
+ cmd12reg |= MVSD_AUTOCMD12_BUSY;
+ if (stop->flags & MMC_RSP_OPCODE)
+ cmd12reg |= MVSD_AUTOCMD12_INDX_CHECK;
+ cmd12reg |= MVSD_AUTOCMD12_INDEX(stop->opcode);
+ mvsd_write(MVSD_AUTOCMD12_CMD, cmd12reg);
+
+ xfer |= MVSD_XFER_MODE_AUTO_CMD12;
+ intr |= MVSD_NOR_AUTOCMD12_DONE;
+ } else {
+ intr |= MVSD_NOR_XFER_DONE;
+ }
+ } else {
+ intr |= MVSD_NOR_CMD_DONE;
+ }
+
+ mvsd_write(MVSD_ARG_LOW, cmd->arg & 0xffff);
+ mvsd_write(MVSD_ARG_HI, cmd->arg >> 16);
+
+ spin_lock_irqsave(&host->lock, flags);
+
+ host->xfer_mode &= MVSD_XFER_MODE_INT_CHK_EN;
+ host->xfer_mode |= xfer;
+ mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+
+ mvsd_write(MVSD_NOR_INTR_STATUS, ~MVSD_NOR_CARD_INT);
+ mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+ mvsd_write(MVSD_CMD, cmdreg);
+
+ host->intr_en &= MVSD_NOR_CARD_INT;
+ host->intr_en |= intr | MVSD_NOR_ERROR;
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ mvsd_write(MVSD_ERR_INTR_EN, 0xffff);
+
+ mod_timer(&host->timer, jiffies + 5 * HZ);
+
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static u32 mvsd_finish_cmd(struct mvsd_host *host, struct mmc_command *cmd,
+ u32 err_status)
+{
+ void __iomem *iobase = host->base;
+
+ if (cmd->flags & MMC_RSP_136) {
+ unsigned int response[8], i;
+ for (i = 0; i < 8; i++)
+ response[i] = mvsd_read(MVSD_RSP(i));
+ cmd->resp[0] = ((response[0] & 0x03ff) << 22) |
+ ((response[1] & 0xffff) << 6) |
+ ((response[2] & 0xfc00) >> 10);
+ cmd->resp[1] = ((response[2] & 0x03ff) << 22) |
+ ((response[3] & 0xffff) << 6) |
+ ((response[4] & 0xfc00) >> 10);
+ cmd->resp[2] = ((response[4] & 0x03ff) << 22) |
+ ((response[5] & 0xffff) << 6) |
+ ((response[6] & 0xfc00) >> 10);
+ cmd->resp[3] = ((response[6] & 0x03ff) << 22) |
+ ((response[7] & 0x3fff) << 8);
+ } else if (cmd->flags & MMC_RSP_PRESENT) {
+ unsigned int response[3], i;
+ for (i = 0; i < 3; i++)
+ response[i] = mvsd_read(MVSD_RSP(i));
+ cmd->resp[0] = ((response[2] & 0x003f) << (8 - 8)) |
+ ((response[1] & 0xffff) << (14 - 8)) |
+ ((response[0] & 0x03ff) << (30 - 8));
+ cmd->resp[1] = ((response[0] & 0xfc00) >> 10);
+ cmd->resp[2] = 0;
+ cmd->resp[3] = 0;
+ }
+
+ if (err_status & MVSD_ERR_CMD_TIMEOUT) {
+ cmd->error = -ETIMEDOUT;
+ } else if (err_status & (MVSD_ERR_CMD_CRC | MVSD_ERR_CMD_ENDBIT |
+ MVSD_ERR_CMD_INDEX | MVSD_ERR_CMD_STARTBIT)) {
+ cmd->error = -EILSEQ;
+ }
+ err_status &= ~(MVSD_ERR_CMD_TIMEOUT | MVSD_ERR_CMD_CRC |
+ MVSD_ERR_CMD_ENDBIT | MVSD_ERR_CMD_INDEX |
+ MVSD_ERR_CMD_STARTBIT);
+
+ return err_status;
+}
+
+static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
+ u32 err_status)
+{
+ void __iomem *iobase = host->base;
+
+ if (host->pio_ptr) {
+ host->pio_ptr = NULL;
+ host->pio_size = 0;
+ } else {
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags,
+ (data->flags & MMC_DATA_READ) ?
+ DMA_FROM_DEVICE : DMA_TO_DEVICE);
+ }
+
+ if (err_status & MVSD_ERR_DATA_TIMEOUT)
+ data->error = -ETIMEDOUT;
+ else if (err_status & (MVSD_ERR_DATA_CRC | MVSD_ERR_DATA_ENDBIT))
+ data->error = -EILSEQ;
+ else if (err_status & MVSD_ERR_XFER_SIZE)
+ data->error = -EBADE;
+ err_status &= ~(MVSD_ERR_DATA_TIMEOUT | MVSD_ERR_DATA_CRC |
+ MVSD_ERR_DATA_ENDBIT | MVSD_ERR_XFER_SIZE);
+
+ dev_dbg(host->dev, "data done: blocks_left=%d, bytes_left=%d\n",
+ mvsd_read(MVSD_CURR_BLK_LEFT), mvsd_read(MVSD_CURR_BYTE_LEFT));
+ data->bytes_xfered =
+ (data->blocks - mvsd_read(MVSD_CURR_BLK_LEFT)) * data->blksz;
+ /* We can't be sure about the last block when errors are detected */
+ if (data->bytes_xfered && data->error)
+ data->bytes_xfered -= data->blksz;
+
+ /* Handle Auto cmd 12 response */
+ if (data->stop) {
+ unsigned int response[3], i;
+ for (i = 0; i < 3; i++)
+ response[i] = mvsd_read(MVSD_AUTO_RSP(i));
+ data->stop->resp[0] = ((response[2] & 0x003f) << (8 - 8)) |
+ ((response[1] & 0xffff) << (14 - 8)) |
+ ((response[0] & 0x03ff) << (30 - 8));
+ data->stop->resp[1] = ((response[0] & 0xfc00) >> 10);
+ data->stop->resp[2] = 0;
+ data->stop->resp[3] = 0;
+
+ if (err_status & MVSD_ERR_AUTOCMD12) {
+ u32 err_cmd12 = mvsd_read(MVSD_AUTOCMD12_ERR_STATUS);
+ dev_dbg(host->dev, "c12err 0x%04x\n", err_cmd12);
+ if (err_cmd12 & MVSD_AUTOCMD12_ERR_NOTEXE)
+ data->stop->error = -ENOEXEC;
+ else if (err_cmd12 & MVSD_AUTOCMD12_ERR_TIMEOUT)
+ data->stop->error = -ETIMEDOUT;
+ else if (err_cmd12)
+ data->stop->error = -EILSEQ;
+ err_status &= ~MVSD_ERR_AUTOCMD12;
+ }
+ }
+
+ return err_status;
+}
+
+static irqreturn_t mvsd_irq(int irq, void *dev)
+{
+ struct mvsd_host *host = dev;
+ void __iomem *iobase = host->base;
+ u32 intr_status, intr_done_mask;
+ int irq_handled = 0;
+
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ dev_dbg(host->dev, "intr 0x%04x intr_en 0x%04x hw_state 0x%04x\n",
+ intr_status, mvsd_read(MVSD_NOR_INTR_EN),
+ mvsd_read(MVSD_HW_STATE));
+
+ spin_lock(&host->lock);
+
+ /* PIO handling, if needed. Messy business... */
+ if (host->pio_size &&
+ (intr_status & host->intr_en &
+ (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) {
+ u16 *p = host->pio_ptr;
+ int s = host->pio_size;
+ while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) {
+ readsw(iobase + MVSD_FIFO, p, 16);
+ p += 16;
+ s -= 32;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ /*
+ * Normally we'd use < 32 here, but the RX_FIFO_8W bit
+ * doesn't appear to assert when there is exactly 32 bytes
+ * (8 words) left to fetch in a transfer.
+ */
+ if (s <= 32) {
+ while (s >= 4 && (intr_status & MVSD_NOR_RX_READY)) {
+ put_unaligned(mvsd_read(MVSD_FIFO), p++);
+ put_unaligned(mvsd_read(MVSD_FIFO), p++);
+ s -= 4;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ if (s && s < 4 && (intr_status & MVSD_NOR_RX_READY)) {
+ u16 val[2] = {0, 0};
+ val[0] = mvsd_read(MVSD_FIFO);
+ val[1] = mvsd_read(MVSD_FIFO);
+ memcpy(p, &val, s);
+ s = 0;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ if (s == 0) {
+ host->intr_en &=
+ ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W);
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ } else if (host->intr_en & MVSD_NOR_RX_FIFO_8W) {
+ host->intr_en &= ~MVSD_NOR_RX_FIFO_8W;
+ host->intr_en |= MVSD_NOR_RX_READY;
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ }
+ }
+ dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
+ s, intr_status, mvsd_read(MVSD_HW_STATE));
+ host->pio_ptr = p;
+ host->pio_size = s;
+ irq_handled = 1;
+ } else if (host->pio_size &&
+ (intr_status & host->intr_en &
+ (MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) {
+ u16 *p = host->pio_ptr;
+ int s = host->pio_size;
+ /*
+ * The TX_FIFO_8W bit is unreliable. When set, bursting
+ * 16 halfwords all at once in the FIFO drops data. Actually
+ * TX_AVAIL does go off after only one word is pushed even if
+ * TX_FIFO_8W remains set.
+ */
+ while (s >= 4 && (intr_status & MVSD_NOR_TX_AVAIL)) {
+ mvsd_write(MVSD_FIFO, get_unaligned(p++));
+ mvsd_write(MVSD_FIFO, get_unaligned(p++));
+ s -= 4;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ if (s < 4) {
+ if (s && (intr_status & MVSD_NOR_TX_AVAIL)) {
+ u16 val[2] = {0, 0};
+ memcpy(&val, p, s);
+ mvsd_write(MVSD_FIFO, val[0]);
+ mvsd_write(MVSD_FIFO, val[1]);
+ s = 0;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ if (s == 0) {
+ host->intr_en &=
+ ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ }
+ }
+ dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
+ s, intr_status, mvsd_read(MVSD_HW_STATE));
+ host->pio_ptr = p;
+ host->pio_size = s;
+ irq_handled = 1;
+ }
+
+ mvsd_write(MVSD_NOR_INTR_STATUS, intr_status);
+
+ intr_done_mask = MVSD_NOR_CARD_INT | MVSD_NOR_RX_READY |
+ MVSD_NOR_RX_FIFO_8W | MVSD_NOR_TX_FIFO_8W;
+ if (intr_status & host->intr_en & ~intr_done_mask) {
+ struct mmc_request *mrq = host->mrq;
+ struct mmc_command *cmd = mrq->cmd;
+ u32 err_status = 0;
+
+ del_timer(&host->timer);
+ host->mrq = NULL;
+
+ host->intr_en &= MVSD_NOR_CARD_INT;
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ mvsd_write(MVSD_ERR_INTR_EN, 0);
+
+ spin_unlock(&host->lock);
+
+ if (intr_status & MVSD_NOR_UNEXP_RSP) {
+ cmd->error = -EPROTO;
+ } else if (intr_status & MVSD_NOR_ERROR) {
+ err_status = mvsd_read(MVSD_ERR_INTR_STATUS);
+ dev_dbg(host->dev, "err 0x%04x\n", err_status);
+ }
+
+ err_status = mvsd_finish_cmd(host, cmd, err_status);
+ if (mrq->data)
+ err_status = mvsd_finish_data(host, mrq->data, err_status);
+ if (err_status) {
+ printk(KERN_ERR "%s: unhandled error status %#04x\n",
+ mmc_hostname(host->mmc), err_status);
+ cmd->error = -ENOMSG;
+ }
+
+ mmc_request_done(host->mmc, mrq);
+ irq_handled = 1;
+ } else
+ spin_unlock(&host->lock);
+
+ if (intr_status & MVSD_NOR_CARD_INT) {
+ mmc_signal_sdio_irq(host->mmc);
+ irq_handled = 1;
+ }
+
+ if (irq_handled)
+ return IRQ_HANDLED;
+
+ printk(KERN_ERR "%s: unhandled interrupt status=0x%04x en=0x%04x "
+ "pio=%d\n", mmc_hostname(host->mmc), intr_status,
+ host->intr_en, host->pio_size);
+ return IRQ_NONE;
+}
+
+static void mvsd_timeout_timer(unsigned long data)
+{
+ struct mvsd_host *host = (struct mvsd_host *)data;
+ void __iomem *iobase = host->base;
+ struct mmc_request *mrq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ mrq = host->mrq;
+ if (mrq) {
+ printk(KERN_ERR "%s: Timeout waiting for hardware interrupt.\n",
+ mmc_hostname(host->mmc));
+ printk(KERN_ERR "%s: hw_state=0x%04x, intr_status=0x%04x "
+ "intr_en=0x%04x\n", mmc_hostname(host->mmc),
+ mvsd_read(MVSD_HW_STATE),
+ mvsd_read(MVSD_NOR_INTR_STATUS),
+ mvsd_read(MVSD_NOR_INTR_EN));
+
+ host->mrq = NULL;
+
+ mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+
+ host->xfer_mode &= MVSD_XFER_MODE_INT_CHK_EN;
+ mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+
+ host->intr_en &= MVSD_NOR_CARD_INT;
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ mvsd_write(MVSD_ERR_INTR_EN, 0);
+ mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+
+ mrq->cmd->error = -ETIMEDOUT;
+ mvsd_finish_cmd(host, mrq->cmd, 0);
+ if (mrq->data) {
+ mrq->data->error = -ETIMEDOUT;
+ mvsd_finish_data(host, mrq->data, 0);
+ }
+ }
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ if (mrq)
+ mmc_request_done(host->mmc, mrq);
+}
+
+static irqreturn_t mvsd_card_detect_irq(int irq, void *dev)
+{
+ struct mvsd_host *host = dev;
+ mmc_detect_change(host->mmc, msecs_to_jiffies(100));
+ return IRQ_HANDLED;
+}
+
+static void mvsd_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+ struct mvsd_host *host = mmc_priv(mmc);
+ void __iomem *iobase = host->base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ if (enable) {
+ host->xfer_mode |= MVSD_XFER_MODE_INT_CHK_EN;
+ host->intr_en |= MVSD_NOR_CARD_INT;
+ } else {
+ host->xfer_mode &= ~MVSD_XFER_MODE_INT_CHK_EN;
+ host->intr_en &= ~MVSD_NOR_CARD_INT;
+ }
+ mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static int mvsd_get_ro(struct mmc_host *mmc)
+{
+ struct mvsd_host *host = mmc_priv(mmc);
+
+ if (host->gpio_write_protect)
+ return gpio_get_value(host->gpio_write_protect);
+
+ /*
+ * Board doesn't support read only detection; let the mmc core
+ * decide what to do.
+ */
+ return -ENOSYS;
+}
+
+static void mvsd_power_up(struct mvsd_host *host)
+{
+ void __iomem *iobase = host->base;
+ dev_dbg(host->dev, "power up\n");
+ mvsd_write(MVSD_NOR_INTR_EN, 0);
+ mvsd_write(MVSD_ERR_INTR_EN, 0);
+ mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+ mvsd_write(MVSD_XFER_MODE, 0);
+ mvsd_write(MVSD_NOR_STATUS_EN, 0xffff);
+ mvsd_write(MVSD_ERR_STATUS_EN, 0xffff);
+ mvsd_write(MVSD_NOR_INTR_STATUS, 0xffff);
+ mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+}
+
+static void mvsd_power_down(struct mvsd_host *host)
+{
+ void __iomem *iobase = host->base;
+ dev_dbg(host->dev, "power down\n");
+ mvsd_write(MVSD_NOR_INTR_EN, 0);
+ mvsd_write(MVSD_ERR_INTR_EN, 0);
+ mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+ mvsd_write(MVSD_XFER_MODE, MVSD_XFER_MODE_STOP_CLK);
+ mvsd_write(MVSD_NOR_STATUS_EN, 0);
+ mvsd_write(MVSD_ERR_STATUS_EN, 0);
+ mvsd_write(MVSD_NOR_INTR_STATUS, 0xffff);
+ mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+}
+
+static void mvsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct mvsd_host *host = mmc_priv(mmc);
+ void __iomem *iobase = host->base;
+ u32 ctrl_reg = 0;
+
+ if (ios->power_mode == MMC_POWER_UP)
+ mvsd_power_up(host);
+
+ if (ios->clock == 0) {
+ mvsd_write(MVSD_XFER_MODE, MVSD_XFER_MODE_STOP_CLK);
+ mvsd_write(MVSD_CLK_DIV, MVSD_BASE_DIV_MAX);
+ host->clock = 0;
+ dev_dbg(host->dev, "clock off\n");
+ } else if (ios->clock != host->clock) {
+ u32 m = DIV_ROUND_UP(host->base_clock, ios->clock) - 1;
+ if (m > MVSD_BASE_DIV_MAX)
+ m = MVSD_BASE_DIV_MAX;
+ mvsd_write(MVSD_CLK_DIV, m);
+ host->clock = ios->clock;
+ host->ns_per_clk = 1000000000 / (host->base_clock / (m+1));
+ dev_dbg(host->dev, "clock=%d (%d), div=0x%04x\n",
+ ios->clock, host->base_clock / (m+1), m);
+ }
+
+ /* default transfer mode */
+ ctrl_reg |= MVSD_HOST_CTRL_BIG_ENDIAN;
+ ctrl_reg &= ~MVSD_HOST_CTRL_LSB_FIRST;
+
+ /* default to maximum timeout */
+ ctrl_reg |= MVSD_HOST_CTRL_TMOUT_MASK;
+ ctrl_reg |= MVSD_HOST_CTRL_TMOUT_EN;
+
+ if (ios->bus_mode == MMC_BUSMODE_PUSHPULL)
+ ctrl_reg |= MVSD_HOST_CTRL_PUSH_PULL_EN;
+
+ if (ios->bus_width == MMC_BUS_WIDTH_4)
+ ctrl_reg |= MVSD_HOST_CTRL_DATA_WIDTH_4_BITS;
+
+ if (ios->timing == MMC_TIMING_MMC_HS ||
+ ios->timing == MMC_TIMING_SD_HS)
+ ctrl_reg |= MVSD_HOST_CTRL_HI_SPEED_EN;
+
+ host->ctrl = ctrl_reg;
+ mvsd_write(MVSD_HOST_CTRL, ctrl_reg);
+ dev_dbg(host->dev, "ctrl 0x%04x: %s %s %s\n", ctrl_reg,
+ (ctrl_reg & MVSD_HOST_CTRL_PUSH_PULL_EN) ?
+ "push-pull" : "open-drain",
+ (ctrl_reg & MVSD_HOST_CTRL_DATA_WIDTH_4_BITS) ?
+ "4bit-width" : "1bit-width",
+ (ctrl_reg & MVSD_HOST_CTRL_HI_SPEED_EN) ?
+ "high-speed" : "");
+
+ if (ios->power_mode == MMC_POWER_OFF)
+ mvsd_power_down(host);
+}
+
+static const struct mmc_host_ops mvsd_ops = {
+ .request = mvsd_request,
+ .get_ro = mvsd_get_ro,
+ .set_ios = mvsd_set_ios,
+ .enable_sdio_irq = mvsd_enable_sdio_irq,
+};
+
+static void __init mv_conf_mbus_windows(struct mvsd_host *host,
+ struct mbus_dram_target_info *dram)
+{
+ void __iomem *iobase = host->base;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ writel(0, iobase + MVSD_WINDOW_CTRL(i));
+ writel(0, iobase + MVSD_WINDOW_BASE(i));
+ }
+
+ for (i = 0; i < dram->num_cs; i++) {
+ struct mbus_dram_window *cs = dram->cs + i;
+ writel(((cs->size - 1) & 0xffff0000) |
+ (cs->mbus_attr << 8) |
+ (dram->mbus_dram_target_id << 4) | 1,
+ iobase + MVSD_WINDOW_CTRL(i));
+ writel(cs->base, iobase + MVSD_WINDOW_BASE(i));
+ }
+}
+
+static int __init mvsd_probe(struct platform_device *pdev)
+{
+ struct mmc_host *mmc = NULL;
+ struct mvsd_host *host = NULL;
+ const struct mvsdio_platform_data *mvsd_data;
+ struct resource *r;
+ int ret, irq;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ mvsd_data = pdev->dev.platform_data;
+ if (!r || irq < 0 || !mvsd_data)
+ return -ENXIO;
+
+ r = request_mem_region(r->start, SZ_1K, DRIVER_NAME);
+ if (!r)
+ return -EBUSY;
+
+ mmc = mmc_alloc_host(sizeof(struct mvsd_host), &pdev->dev);
+ if (!mmc) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ host = mmc_priv(mmc);
+ host->mmc = mmc;
+ host->dev = &pdev->dev;
+ host->res = r;
+ host->base_clock = mvsd_data->clock / 2;
+
+ mmc->ops = &mvsd_ops;
+
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ |
+ MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
+
+ mmc->f_min = DIV_ROUND_UP(host->base_clock, MVSD_BASE_DIV_MAX);
+ mmc->f_max = maxfreq;
+
+ mmc->max_blk_size = 2048;
+ mmc->max_blk_count = 65535;
+
+ mmc->max_hw_segs = 1;
+ mmc->max_phys_segs = 1;
+ mmc->max_seg_size = mmc->max_blk_size * mmc->max_blk_count;
+ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+
+ spin_lock_init(&host->lock);
+
+ host->base = ioremap(r->start, SZ_4K);
+ if (!host->base) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* (Re-)program MBUS remapping windows if we are asked to. */
+ if (mvsd_data->dram != NULL)
+ mv_conf_mbus_windows(host, mvsd_data->dram);
+
+ mvsd_power_down(host);
+
+ ret = request_irq(irq, mvsd_irq, 0, DRIVER_NAME, host);
+ if (ret) {
+ printk(KERN_ERR "%s: cannot assign irq %d\n", DRIVER_NAME, irq);
+ goto out;
+ } else
+ host->irq = irq;
+
+ if (mvsd_data->gpio_card_detect) {
+ ret = gpio_request(mvsd_data->gpio_card_detect,
+ DRIVER_NAME " cd");
+ if (ret == 0) {
+ gpio_direction_input(mvsd_data->gpio_card_detect);
+ irq = gpio_to_irq(mvsd_data->gpio_card_detect);
+ ret = request_irq(irq, mvsd_card_detect_irq,
+ IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING,
+ DRIVER_NAME " cd", host);
+ if (ret == 0)
+ host->gpio_card_detect =
+ mvsd_data->gpio_card_detect;
+ else
+ gpio_free(mvsd_data->gpio_card_detect);
+ }
+ }
+ if (!host->gpio_card_detect)
+ mmc->caps |= MMC_CAP_NEEDS_POLL;
+
+ if (mvsd_data->gpio_write_protect) {
+ ret = gpio_request(mvsd_data->gpio_write_protect,
+ DRIVER_NAME " wp");
+ if (ret == 0) {
+ gpio_direction_input(mvsd_data->gpio_write_protect);
+ host->gpio_write_protect =
+ mvsd_data->gpio_write_protect;
+ }
+ }
+
+ setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host);
+ platform_set_drvdata(pdev, mmc);
+ ret = mmc_add_host(mmc);
+ if (ret)
+ goto out;
+
+ printk(KERN_NOTICE "%s: %s driver initialized, ",
+ mmc_hostname(mmc), DRIVER_NAME);
+ if (host->gpio_card_detect)
+ printk("using GPIO %d for card detection\n",
+ host->gpio_card_detect);
+ else
+ printk("lacking card detect (fall back to polling)\n");
+ return 0;
+
+out:
+ if (host) {
+ if (host->irq)
+ free_irq(host->irq, host);
+ if (host->gpio_card_detect) {
+ free_irq(gpio_to_irq(host->gpio_card_detect), host);
+ gpio_free(host->gpio_card_detect);
+ }
+ if (host->gpio_write_protect)
+ gpio_free(host->gpio_write_protect);
+ if (host->base)
+ iounmap(host->base);
+ }
+ if (r)
+ release_resource(r);
+ if (mmc)
+ mmc_free_host(mmc);
+
+ return ret;
+}
+
+static int __exit mvsd_remove(struct platform_device *pdev)
+{
+ struct mmc_host *mmc = platform_get_drvdata(pdev);
+
+ if (mmc) {
+ struct mvsd_host *host = mmc_priv(mmc);
+
+ if (host->gpio_card_detect) {
+ free_irq(gpio_to_irq(host->gpio_card_detect), host);
+ gpio_free(host->gpio_card_detect);
+ }
+ mmc_remove_host(mmc);
+ free_irq(host->irq, host);
+ if (host->gpio_write_protect)
+ gpio_free(host->gpio_write_protect);
+ del_timer_sync(&host->timer);
+ mvsd_power_down(host);
+ iounmap(host->base);
+ release_resource(host->res);
+ mmc_free_host(mmc);
+ }
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int mvsd_suspend(struct platform_device *dev, pm_message_t state,
+ u32 level)
+{
+ struct mmc_host *mmc = platform_get_drvdata(dev);
+ int ret = 0;
+
+ if (mmc && level == SUSPEND_DISABLE)
+ ret = mmc_suspend_host(mmc, state);
+
+ return ret;
+}
+
+static int mvsd_resume(struct platform_device *dev, u32 level)
+{
+ struct mmc_host *mmc = platform_dev_get_drvdata(dev);
+ int ret = 0;
+
+ if (mmc && level == RESUME_ENABLE)
+ ret = mmc_resume_host(mmc);
+
+ return ret;
+}
+#else
+#define mvsd_suspend NULL
+#define mvsd_resume NULL
+#endif
+
+static struct platform_driver mvsd_driver = {
+ .remove = __exit_p(mvsd_remove),
+ .suspend = mvsd_suspend,
+ .resume = mvsd_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ },
+};
+
+static int __init mvsd_init(void)
+{
+ return platform_driver_probe(&mvsd_driver, mvsd_probe);
+}
+
+static void __exit mvsd_exit(void)
+{
+ platform_driver_unregister(&mvsd_driver);
+}
+
+module_init(mvsd_init);
+module_exit(mvsd_exit);
+
+/* maximum card clock frequency (default 50MHz) */
+module_param(maxfreq, int, 0);
+
+/* force PIO transfers all the time */
+module_param(nodma, int, 0);
+
+MODULE_AUTHOR("Maen Suleiman, Nicolas Pitre");
+MODULE_DESCRIPTION("Marvell MMC,SD,SDIO Host Controller driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/mvsdio.h b/drivers/mmc/host/mvsdio.h
new file mode 100644
index 00000000000..7d9727b9f5a
--- /dev/null
+++ b/drivers/mmc/host/mvsdio.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2008 Marvell Semiconductors, 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.
+ */
+
+#ifndef __MVSDIO_H
+#define __MVSDIO_H
+
+/*
+ * Clock rates
+ */
+
+#define MVSD_CLOCKRATE_MAX 50000000
+#define MVSD_BASE_DIV_MAX 0x7ff
+
+
+/*
+ * Register offsets
+ */
+
+#define MVSD_SYS_ADDR_LOW 0x000
+#define MVSD_SYS_ADDR_HI 0x004
+#define MVSD_BLK_SIZE 0x008
+#define MVSD_BLK_COUNT 0x00c
+#define MVSD_ARG_LOW 0x010
+#define MVSD_ARG_HI 0x014
+#define MVSD_XFER_MODE 0x018
+#define MVSD_CMD 0x01c
+#define MVSD_RSP(i) (0x020 + ((i)<<2))
+#define MVSD_RSP0 0x020
+#define MVSD_RSP1 0x024
+#define MVSD_RSP2 0x028
+#define MVSD_RSP3 0x02c
+#define MVSD_RSP4 0x030
+#define MVSD_RSP5 0x034
+#define MVSD_RSP6 0x038
+#define MVSD_RSP7 0x03c
+#define MVSD_FIFO 0x040
+#define MVSD_RSP_CRC7 0x044
+#define MVSD_HW_STATE 0x048
+#define MVSD_HOST_CTRL 0x050
+#define MVSD_BLK_GAP_CTRL 0x054
+#define MVSD_CLK_CTRL 0x058
+#define MVSD_SW_RESET 0x05c
+#define MVSD_NOR_INTR_STATUS 0x060
+#define MVSD_ERR_INTR_STATUS 0x064
+#define MVSD_NOR_STATUS_EN 0x068
+#define MVSD_ERR_STATUS_EN 0x06c
+#define MVSD_NOR_INTR_EN 0x070
+#define MVSD_ERR_INTR_EN 0x074
+#define MVSD_AUTOCMD12_ERR_STATUS 0x078
+#define MVSD_CURR_BYTE_LEFT 0x07c
+#define MVSD_CURR_BLK_LEFT 0x080
+#define MVSD_AUTOCMD12_ARG_LOW 0x084
+#define MVSD_AUTOCMD12_ARG_HI 0x088
+#define MVSD_AUTOCMD12_CMD 0x08c
+#define MVSD_AUTO_RSP(i) (0x090 + ((i)<<2))
+#define MVSD_AUTO_RSP0 0x090
+#define MVSD_AUTO_RSP1 0x094
+#define MVSD_AUTO_RSP2 0x098
+#define MVSD_CLK_DIV 0x128
+
+#define MVSD_WINDOW_CTRL(i) (0x108 + ((i) << 3))
+#define MVSD_WINDOW_BASE(i) (0x10c + ((i) << 3))
+
+
+/*
+ * MVSD_CMD
+ */
+
+#define MVSD_CMD_RSP_NONE (0 << 0)
+#define MVSD_CMD_RSP_136 (1 << 0)
+#define MVSD_CMD_RSP_48 (2 << 0)
+#define MVSD_CMD_RSP_48BUSY (3 << 0)
+
+#define MVSD_CMD_CHECK_DATACRC16 (1 << 2)
+#define MVSD_CMD_CHECK_CMDCRC (1 << 3)
+#define MVSD_CMD_INDX_CHECK (1 << 4)
+#define MVSD_CMD_DATA_PRESENT (1 << 5)
+#define MVSD_UNEXPECTED_RESP (1 << 7)
+#define MVSD_CMD_INDEX(x) ((x) << 8)
+
+
+/*
+ * MVSD_AUTOCMD12_CMD
+ */
+
+#define MVSD_AUTOCMD12_BUSY (1 << 0)
+#define MVSD_AUTOCMD12_INDX_CHECK (1 << 1)
+#define MVSD_AUTOCMD12_INDEX(x) ((x) << 8)
+
+/*
+ * MVSD_XFER_MODE
+ */
+
+#define MVSD_XFER_MODE_WR_DATA_START (1 << 0)
+#define MVSD_XFER_MODE_HW_WR_DATA_EN (1 << 1)
+#define MVSD_XFER_MODE_AUTO_CMD12 (1 << 2)
+#define MVSD_XFER_MODE_INT_CHK_EN (1 << 3)
+#define MVSD_XFER_MODE_TO_HOST (1 << 4)
+#define MVSD_XFER_MODE_STOP_CLK (1 << 5)
+#define MVSD_XFER_MODE_PIO (1 << 6)
+
+
+/*
+ * MVSD_HOST_CTRL
+ */
+
+#define MVSD_HOST_CTRL_PUSH_PULL_EN (1 << 0)
+
+#define MVSD_HOST_CTRL_CARD_TYPE_MEM_ONLY (0 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_ONLY (1 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_MEM_COMBO (2 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_MMC (3 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_MASK (3 << 1)
+
+#define MVSD_HOST_CTRL_BIG_ENDIAN (1 << 3)
+#define MVSD_HOST_CTRL_LSB_FIRST (1 << 4)
+#define MVSD_HOST_CTRL_DATA_WIDTH_4_BITS (1 << 9)
+#define MVSD_HOST_CTRL_HI_SPEED_EN (1 << 10)
+
+#define MVSD_HOST_CTRL_TMOUT_MAX 0xf
+#define MVSD_HOST_CTRL_TMOUT_MASK (0xf << 11)
+#define MVSD_HOST_CTRL_TMOUT(x) ((x) << 11)
+#define MVSD_HOST_CTRL_TMOUT_EN (1 << 15)
+
+
+/*
+ * MVSD_SW_RESET
+ */
+
+#define MVSD_SW_RESET_NOW (1 << 8)
+
+
+/*
+ * Normal interrupt status bits
+ */
+
+#define MVSD_NOR_CMD_DONE (1 << 0)
+#define MVSD_NOR_XFER_DONE (1 << 1)
+#define MVSD_NOR_BLK_GAP_EVT (1 << 2)
+#define MVSD_NOR_DMA_DONE (1 << 3)
+#define MVSD_NOR_TX_AVAIL (1 << 4)
+#define MVSD_NOR_RX_READY (1 << 5)
+#define MVSD_NOR_CARD_INT (1 << 8)
+#define MVSD_NOR_READ_WAIT_ON (1 << 9)
+#define MVSD_NOR_RX_FIFO_8W (1 << 10)
+#define MVSD_NOR_TX_FIFO_8W (1 << 11)
+#define MVSD_NOR_SUSPEND_ON (1 << 12)
+#define MVSD_NOR_AUTOCMD12_DONE (1 << 13)
+#define MVSD_NOR_UNEXP_RSP (1 << 14)
+#define MVSD_NOR_ERROR (1 << 15)
+
+
+/*
+ * Error status bits
+ */
+
+#define MVSD_ERR_CMD_TIMEOUT (1 << 0)
+#define MVSD_ERR_CMD_CRC (1 << 1)
+#define MVSD_ERR_CMD_ENDBIT (1 << 2)
+#define MVSD_ERR_CMD_INDEX (1 << 3)
+#define MVSD_ERR_DATA_TIMEOUT (1 << 4)
+#define MVSD_ERR_DATA_CRC (1 << 5)
+#define MVSD_ERR_DATA_ENDBIT (1 << 6)
+#define MVSD_ERR_AUTOCMD12 (1 << 8)
+#define MVSD_ERR_CMD_STARTBIT (1 << 9)
+#define MVSD_ERR_XFER_SIZE (1 << 10)
+#define MVSD_ERR_RESP_T_BIT (1 << 11)
+#define MVSD_ERR_CRC_ENDBIT (1 << 12)
+#define MVSD_ERR_CRC_STARTBIT (1 << 13)
+#define MVSD_ERR_CRC_STATUS (1 << 14)
+
+
+/*
+ * CMD12 error status bits
+ */
+
+#define MVSD_AUTOCMD12_ERR_NOTEXE (1 << 0)
+#define MVSD_AUTOCMD12_ERR_TIMEOUT (1 << 1)
+#define MVSD_AUTOCMD12_ERR_CRC (1 << 2)
+#define MVSD_AUTOCMD12_ERR_ENDBIT (1 << 3)
+#define MVSD_AUTOCMD12_ERR_INDEX (1 << 4)
+#define MVSD_AUTOCMD12_ERR_RESP_T_BIT (1 << 5)
+#define MVSD_AUTOCMD12_ERR_RESP_STARTBIT (1 << 6)
+
+#endif
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 3916a5618e2..e62a22a7f00 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -56,6 +56,7 @@
#define SDVS18 (0x5 << 9)
#define SDVS30 (0x6 << 9)
#define SDVS33 (0x7 << 9)
+#define SDVS_MASK 0x00000E00
#define SDVSCLR 0xFFFFF1FF
#define SDVSDET 0x00000400
#define AUTOIDLE 0x1
@@ -76,6 +77,7 @@
#define MSBS (1 << 5)
#define BCE (1 << 1)
#define FOUR_BIT (1 << 1)
+#define DW8 (1 << 5)
#define CC 0x1
#define TC 0x02
#define OD 0x1
@@ -98,10 +100,8 @@
*/
#define OMAP_MMC1_DEVID 0
#define OMAP_MMC2_DEVID 1
+#define OMAP_MMC3_DEVID 2
-#define OMAP_MMC_DATADIR_NONE 0
-#define OMAP_MMC_DATADIR_READ 1
-#define OMAP_MMC_DATADIR_WRITE 2
#define MMC_TIMEOUT_MS 20
#define OMAP_MMC_MASTER_CLOCK 96000000
#define DRIVER_NAME "mmci-omap-hs"
@@ -137,18 +137,18 @@ struct mmc_omap_host {
resource_size_t mapbase;
unsigned int id;
unsigned int dma_len;
- unsigned int dma_dir;
+ unsigned int dma_sg_idx;
unsigned char bus_mode;
- unsigned char datadir;
u32 *buffer;
u32 bytesleft;
int suspended;
int irq;
int carddetect;
int use_dma, dma_ch;
- int initstr;
+ int dma_line_tx, dma_line_rx;
int slot_id;
int dbclk_enabled;
+ int response_busy;
struct omap_mmc_platform_data *pdata;
};
@@ -218,7 +218,7 @@ mmc_omap_show_slot_name(struct device *dev, struct device_attribute *attr,
struct mmc_omap_host *host = mmc_priv(mmc);
struct omap_mmc_slot_data slot = host->pdata->slots[host->slot_id];
- return sprintf(buf, "slot:%s\n", slot.name);
+ return sprintf(buf, "%s\n", slot.name);
}
static DEVICE_ATTR(slot_name, S_IRUGO, mmc_omap_show_slot_name, NULL);
@@ -243,10 +243,14 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd,
OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
+ host->response_busy = 0;
if (cmd->flags & MMC_RSP_PRESENT) {
if (cmd->flags & MMC_RSP_136)
resptype = 1;
- else
+ else if (cmd->flags & MMC_RSP_BUSY) {
+ resptype = 3;
+ host->response_busy = 1;
+ } else
resptype = 2;
}
@@ -275,19 +279,34 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd,
OMAP_HSMMC_WRITE(host->base, CMD, cmdreg);
}
+static int
+mmc_omap_get_dma_dir(struct mmc_omap_host *host, struct mmc_data *data)
+{
+ if (data->flags & MMC_DATA_WRITE)
+ return DMA_TO_DEVICE;
+ else
+ return DMA_FROM_DEVICE;
+}
+
/*
* Notify the transfer complete to MMC core
*/
static void
mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
{
+ if (!data) {
+ struct mmc_request *mrq = host->mrq;
+
+ host->mrq = NULL;
+ mmc_request_done(host->mmc, mrq);
+ return;
+ }
+
host->data = NULL;
if (host->use_dma && host->dma_ch != -1)
dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len,
- host->dma_dir);
-
- host->datadir = OMAP_MMC_DATADIR_NONE;
+ mmc_omap_get_dma_dir(host, data));
if (!data->error)
data->bytes_xfered += data->blocks * (data->blksz);
@@ -322,7 +341,7 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10);
}
}
- if (host->data == NULL || cmd->error) {
+ if ((host->data == NULL && !host->response_busy) || cmd->error) {
host->mrq = NULL;
mmc_request_done(host->mmc, cmd->mrq);
}
@@ -331,19 +350,18 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
/*
* DMA clean up for command errors
*/
-static void mmc_dma_cleanup(struct mmc_omap_host *host)
+static void mmc_dma_cleanup(struct mmc_omap_host *host, int errno)
{
- host->data->error = -ETIMEDOUT;
+ host->data->error = errno;
if (host->use_dma && host->dma_ch != -1) {
dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,
- host->dma_dir);
+ mmc_omap_get_dma_dir(host, host->data));
omap_free_dma(host->dma_ch);
host->dma_ch = -1;
up(&host->sem);
}
host->data = NULL;
- host->datadir = OMAP_MMC_DATADIR_NONE;
}
/*
@@ -412,9 +430,11 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
struct mmc_data *data;
int end_cmd = 0, end_trans = 0, status;
- if (host->cmd == NULL && host->data == NULL) {
+ if (host->mrq == NULL) {
OMAP_HSMMC_WRITE(host->base, STAT,
OMAP_HSMMC_READ(host->base, STAT));
+ /* Flush posted write */
+ OMAP_HSMMC_READ(host->base, STAT);
return IRQ_HANDLED;
}
@@ -437,18 +457,24 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
}
end_cmd = 1;
}
- if (host->data) {
- mmc_dma_cleanup(host);
+ if (host->data || host->response_busy) {
+ if (host->data)
+ mmc_dma_cleanup(host, -ETIMEDOUT);
+ host->response_busy = 0;
mmc_omap_reset_controller_fsm(host, SRD);
}
}
if ((status & DATA_TIMEOUT) ||
(status & DATA_CRC)) {
- if (host->data) {
- if (status & DATA_TIMEOUT)
- mmc_dma_cleanup(host);
+ if (host->data || host->response_busy) {
+ int err = (status & DATA_TIMEOUT) ?
+ -ETIMEDOUT : -EILSEQ;
+
+ if (host->data)
+ mmc_dma_cleanup(host, err);
else
- host->data->error = -EILSEQ;
+ host->mrq->cmd->error = err;
+ host->response_busy = 0;
mmc_omap_reset_controller_fsm(host, SRD);
end_trans = 1;
}
@@ -464,8 +490,10 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
}
OMAP_HSMMC_WRITE(host->base, STAT, status);
+ /* Flush posted write */
+ OMAP_HSMMC_READ(host->base, STAT);
- if (end_cmd || (status & CC))
+ if (end_cmd || ((status & CC) && host->cmd))
mmc_omap_cmd_done(host, host->cmd);
if (end_trans || (status & TC))
mmc_omap_xfer_done(host, data);
@@ -473,6 +501,19 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static void set_sd_bus_power(struct mmc_omap_host *host)
+{
+ unsigned long i;
+
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+ for (i = 0; i < loops_per_jiffy; i++) {
+ if (OMAP_HSMMC_READ(host->base, HCTL) & SDBP)
+ break;
+ cpu_relax();
+ }
+}
+
/*
* Switch MMC interface voltage ... only relevant for MMC1.
*
@@ -485,9 +526,6 @@ static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd)
u32 reg_val = 0;
int ret;
- if (host->id != OMAP_MMC1_DEVID)
- return 0;
-
/* Disable the clocks */
clk_disable(host->fclk);
clk_disable(host->iclk);
@@ -532,9 +570,7 @@ static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd)
reg_val |= SDVS30;
OMAP_HSMMC_WRITE(host->base, HCTL, reg_val);
-
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+ set_sd_bus_power(host);
return 0;
err:
@@ -551,7 +587,10 @@ static void mmc_omap_detect(struct work_struct *work)
mmc_carddetect_work);
struct omap_mmc_slot_data *slot = &mmc_slot(host);
- host->carddetect = slot->card_detect(slot->card_detect_irq);
+ if (mmc_slot(host).card_detect)
+ host->carddetect = slot->card_detect(slot->card_detect_irq);
+ else
+ host->carddetect = -ENOSYS;
sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
if (host->carddetect) {
@@ -574,6 +613,48 @@ static irqreturn_t omap_mmc_cd_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static int mmc_omap_get_dma_sync_dev(struct mmc_omap_host *host,
+ struct mmc_data *data)
+{
+ int sync_dev;
+
+ if (data->flags & MMC_DATA_WRITE)
+ sync_dev = host->dma_line_tx;
+ else
+ sync_dev = host->dma_line_rx;
+ return sync_dev;
+}
+
+static void mmc_omap_config_dma_params(struct mmc_omap_host *host,
+ struct mmc_data *data,
+ struct scatterlist *sgl)
+{
+ int blksz, nblk, dma_ch;
+
+ dma_ch = host->dma_ch;
+ if (data->flags & MMC_DATA_WRITE) {
+ omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
+ (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+ omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
+ sg_dma_address(sgl), 0, 0);
+ } else {
+ omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
+ (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+ omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
+ sg_dma_address(sgl), 0, 0);
+ }
+
+ blksz = host->data->blksz;
+ nblk = sg_dma_len(sgl) / blksz;
+
+ omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
+ blksz / 4, nblk, OMAP_DMA_SYNC_FRAME,
+ mmc_omap_get_dma_sync_dev(host, data),
+ !(data->flags & MMC_DATA_WRITE));
+
+ omap_start_dma(dma_ch);
+}
+
/*
* DMA call back function
*/
@@ -587,6 +668,14 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
if (host->dma_ch < 0)
return;
+ host->dma_sg_idx++;
+ if (host->dma_sg_idx < host->dma_len) {
+ /* Fire up the next transfer. */
+ mmc_omap_config_dma_params(host, host->data,
+ host->data->sg + host->dma_sg_idx);
+ return;
+ }
+
omap_free_dma(host->dma_ch);
host->dma_ch = -1;
/*
@@ -597,38 +686,28 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
}
/*
- * Configure dma src and destination parameters
- */
-static int mmc_omap_config_dma_param(int sync_dir, struct mmc_omap_host *host,
- struct mmc_data *data)
-{
- if (sync_dir == 0) {
- omap_set_dma_dest_params(host->dma_ch, 0,
- OMAP_DMA_AMODE_CONSTANT,
- (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
- omap_set_dma_src_params(host->dma_ch, 0,
- OMAP_DMA_AMODE_POST_INC,
- sg_dma_address(&data->sg[0]), 0, 0);
- } else {
- omap_set_dma_src_params(host->dma_ch, 0,
- OMAP_DMA_AMODE_CONSTANT,
- (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
- omap_set_dma_dest_params(host->dma_ch, 0,
- OMAP_DMA_AMODE_POST_INC,
- sg_dma_address(&data->sg[0]), 0, 0);
- }
- return 0;
-}
-/*
* Routine to configure and start DMA for the MMC card
*/
static int
mmc_omap_start_dma_transfer(struct mmc_omap_host *host, struct mmc_request *req)
{
- int sync_dev, sync_dir = 0;
- int dma_ch = 0, ret = 0, err = 1;
+ int dma_ch = 0, ret = 0, err = 1, i;
struct mmc_data *data = req->data;
+ /* Sanity check: all the SG entries must be aligned by block size. */
+ for (i = 0; i < host->dma_len; i++) {
+ struct scatterlist *sgl;
+
+ sgl = data->sg + i;
+ if (sgl->length % data->blksz)
+ return -EINVAL;
+ }
+ if ((data->blksz % 4) != 0)
+ /* REVISIT: The MMC buffer increments only when MSB is written.
+ * Return error for blksz which is non multiple of four.
+ */
+ return -EINVAL;
+
/*
* If for some reason the DMA transfer is still active,
* we wait for timeout period and free the dma
@@ -647,49 +726,22 @@ mmc_omap_start_dma_transfer(struct mmc_omap_host *host, struct mmc_request *req)
return err;
}
- if (!(data->flags & MMC_DATA_WRITE)) {
- host->dma_dir = DMA_FROM_DEVICE;
- if (host->id == OMAP_MMC1_DEVID)
- sync_dev = OMAP24XX_DMA_MMC1_RX;
- else
- sync_dev = OMAP24XX_DMA_MMC2_RX;
- } else {
- host->dma_dir = DMA_TO_DEVICE;
- if (host->id == OMAP_MMC1_DEVID)
- sync_dev = OMAP24XX_DMA_MMC1_TX;
- else
- sync_dev = OMAP24XX_DMA_MMC2_TX;
- }
-
- ret = omap_request_dma(sync_dev, "MMC/SD", mmc_omap_dma_cb,
- host, &dma_ch);
+ ret = omap_request_dma(mmc_omap_get_dma_sync_dev(host, data), "MMC/SD",
+ mmc_omap_dma_cb,host, &dma_ch);
if (ret != 0) {
- dev_dbg(mmc_dev(host->mmc),
+ dev_err(mmc_dev(host->mmc),
"%s: omap_request_dma() failed with %d\n",
mmc_hostname(host->mmc), ret);
return ret;
}
host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
- data->sg_len, host->dma_dir);
+ data->sg_len, mmc_omap_get_dma_dir(host, data));
host->dma_ch = dma_ch;
+ host->dma_sg_idx = 0;
- if (!(data->flags & MMC_DATA_WRITE))
- mmc_omap_config_dma_param(1, host, data);
- else
- mmc_omap_config_dma_param(0, host, data);
-
- if ((data->blksz % 4) == 0)
- omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
- (data->blksz / 4), data->blocks, OMAP_DMA_SYNC_FRAME,
- sync_dev, sync_dir);
- else
- /* REVISIT: The MMC buffer increments only when MSB is written.
- * Return error for blksz which is non multiple of four.
- */
- return -EINVAL;
+ mmc_omap_config_dma_params(host, data, data->sg);
- omap_start_dma(dma_ch);
return 0;
}
@@ -739,7 +791,6 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
host->data = req->data;
if (req->data == NULL) {
- host->datadir = OMAP_MMC_DATADIR_NONE;
OMAP_HSMMC_WRITE(host->base, BLK, 0);
return 0;
}
@@ -748,9 +799,6 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
| (req->data->blocks << 16));
set_data_timeout(host, req);
- host->datadir = (req->data->flags & MMC_DATA_WRITE) ?
- OMAP_MMC_DATADIR_WRITE : OMAP_MMC_DATADIR_READ;
-
if (host->use_dma) {
ret = mmc_omap_start_dma_transfer(host, req);
if (ret != 0) {
@@ -782,36 +830,29 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
u16 dsor = 0;
unsigned long regval;
unsigned long timeout;
+ u32 con;
switch (ios->power_mode) {
case MMC_POWER_OFF:
mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
- /*
- * Reset interface voltage to 3V if it's 1.8V now;
- * only relevant on MMC-1, the others always use 1.8V.
- *
- * REVISIT: If we are able to detect cards after unplugging
- * a 1.8V card, this code should not be needed.
- */
- if (host->id != OMAP_MMC1_DEVID)
- break;
- if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) {
- int vdd = fls(host->mmc->ocr_avail) - 1;
- if (omap_mmc_switch_opcond(host, vdd) != 0)
- host->mmc->ios.vdd = vdd;
- }
break;
case MMC_POWER_UP:
mmc_slot(host).set_power(host->dev, host->slot_id, 1, ios->vdd);
break;
}
+ con = OMAP_HSMMC_READ(host->base, CON);
switch (mmc->ios.bus_width) {
+ case MMC_BUS_WIDTH_8:
+ OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
+ break;
case MMC_BUS_WIDTH_4:
+ OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
OMAP_HSMMC_WRITE(host->base, HCTL,
OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
break;
case MMC_BUS_WIDTH_1:
+ OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
OMAP_HSMMC_WRITE(host->base, HCTL,
OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
break;
@@ -891,6 +932,33 @@ static int omap_hsmmc_get_ro(struct mmc_host *mmc)
return pdata->slots[0].get_ro(host->dev, 0);
}
+static void omap_hsmmc_init(struct mmc_omap_host *host)
+{
+ u32 hctl, capa, value;
+
+ /* Only MMC1 supports 3.0V */
+ if (host->id == OMAP_MMC1_DEVID) {
+ hctl = SDVS30;
+ capa = VS30 | VS18;
+ } else {
+ hctl = SDVS18;
+ capa = VS18;
+ }
+
+ value = OMAP_HSMMC_READ(host->base, HCTL) & ~SDVS_MASK;
+ OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl);
+
+ value = OMAP_HSMMC_READ(host->base, CAPA);
+ OMAP_HSMMC_WRITE(host->base, CAPA, value | capa);
+
+ /* Set the controller to AUTO IDLE mode */
+ value = OMAP_HSMMC_READ(host->base, SYSCONFIG);
+ OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE);
+
+ /* Set SD bus power bit */
+ set_sd_bus_power(host);
+}
+
static struct mmc_host_ops mmc_omap_ops = {
.request = omap_mmc_request,
.set_ios = omap_mmc_set_ios,
@@ -906,7 +974,6 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
struct mmc_omap_host *host = NULL;
struct resource *res;
int ret = 0, irq;
- u32 hctl, capa;
if (pdata == NULL) {
dev_err(&pdev->dev, "Platform Data is missing\n");
@@ -996,10 +1063,11 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
else
host->dbclk_enabled = 1;
-#ifdef CONFIG_MMC_BLOCK_BOUNCE
- mmc->max_phys_segs = 1;
- mmc->max_hw_segs = 1;
-#endif
+ /* Since we do only SG emulation, we can have as many segs
+ * as we want. */
+ mmc->max_phys_segs = 1024;
+ mmc->max_hw_segs = 1024;
+
mmc->max_blk_size = 512; /* Block Length at max can be 1024 */
mmc->max_blk_count = 0xFFFF; /* No. of Blocks is 16 bits */
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
@@ -1008,31 +1076,31 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
mmc->ocr_avail = mmc_slot(host).ocr_mask;
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
- if (pdata->slots[host->slot_id].wires >= 4)
+ if (pdata->slots[host->slot_id].wires >= 8)
+ mmc->caps |= MMC_CAP_8_BIT_DATA;
+ else if (pdata->slots[host->slot_id].wires >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
- /* Only MMC1 supports 3.0V */
- if (host->id == OMAP_MMC1_DEVID) {
- hctl = SDVS30;
- capa = VS30 | VS18;
- } else {
- hctl = SDVS18;
- capa = VS18;
- }
-
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) | hctl);
-
- OMAP_HSMMC_WRITE(host->base, CAPA,
- OMAP_HSMMC_READ(host->base, CAPA) | capa);
-
- /* Set the controller to AUTO IDLE mode */
- OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
- OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
+ omap_hsmmc_init(host);
- /* Set SD bus power bit */
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+ /* Select DMA lines */
+ switch (host->id) {
+ case OMAP_MMC1_DEVID:
+ host->dma_line_tx = OMAP24XX_DMA_MMC1_TX;
+ host->dma_line_rx = OMAP24XX_DMA_MMC1_RX;
+ break;
+ case OMAP_MMC2_DEVID:
+ host->dma_line_tx = OMAP24XX_DMA_MMC2_TX;
+ host->dma_line_rx = OMAP24XX_DMA_MMC2_RX;
+ break;
+ case OMAP_MMC3_DEVID:
+ host->dma_line_tx = OMAP34XX_DMA_MMC3_TX;
+ host->dma_line_rx = OMAP34XX_DMA_MMC3_RX;
+ break;
+ default:
+ dev_err(mmc_dev(host->mmc), "Invalid MMC id\n");
+ goto err_irq;
+ }
/* Request IRQ for MMC operations */
ret = request_irq(host->irq, mmc_omap_irq, IRQF_DISABLED,
@@ -1051,7 +1119,7 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
}
/* Request IRQ for card detect */
- if ((mmc_slot(host).card_detect_irq) && (mmc_slot(host).card_detect)) {
+ if ((mmc_slot(host).card_detect_irq)) {
ret = request_irq(mmc_slot(host).card_detect_irq,
omap_mmc_cd_handler,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
@@ -1074,8 +1142,8 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
if (ret < 0)
goto err_slot_name;
}
- if (mmc_slot(host).card_detect_irq && mmc_slot(host).card_detect &&
- host->pdata->slots[host->slot_id].get_cover_state) {
+ if (mmc_slot(host).card_detect_irq &&
+ host->pdata->slots[host->slot_id].get_cover_state) {
ret = device_create_file(&mmc->class_dev,
&dev_attr_cover_switch);
if (ret < 0)
@@ -1173,20 +1241,8 @@ static int omap_mmc_suspend(struct platform_device *pdev, pm_message_t state)
" level suspend\n");
}
- if (host->id == OMAP_MMC1_DEVID
- && !(OMAP_HSMMC_READ(host->base, HCTL)
- & SDVSDET)) {
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL)
- & SDVSCLR);
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL)
- | SDVS30);
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL)
- | SDBP);
- }
-
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
clk_disable(host->fclk);
clk_disable(host->iclk);
clk_disable(host->dbclk);
@@ -1222,6 +1278,8 @@ static int omap_mmc_resume(struct platform_device *pdev)
dev_dbg(mmc_dev(host->mmc),
"Enabling debounce clk failed\n");
+ omap_hsmmc_init(host);
+
if (host->pdata->resume) {
ret = host->pdata->resume(&pdev->dev, host->slot_id);
if (ret)
diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of.c
new file mode 100644
index 00000000000..3ff4ac3abe8
--- /dev/null
+++ b/drivers/mmc/host/sdhci-of.c
@@ -0,0 +1,309 @@
+/*
+ * OpenFirmware bindings for Secure Digital Host Controller Interface.
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ * Copyright (c) 2009 MontaVista Software, Inc.
+ *
+ * Authors: Xiaobo Xie <X.Xie@freescale.com>
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/mmc/host.h>
+#include "sdhci.h"
+
+struct sdhci_of_data {
+ unsigned int quirks;
+ struct sdhci_ops ops;
+};
+
+struct sdhci_of_host {
+ unsigned int clock;
+ u16 xfer_mode_shadow;
+};
+
+/*
+ * Ops and quirks for the Freescale eSDHC controller.
+ */
+
+#define ESDHC_DMA_SYSCTL 0x40c
+#define ESDHC_DMA_SNOOP 0x00000040
+
+#define ESDHC_SYSTEM_CONTROL 0x2c
+#define ESDHC_CLOCK_MASK 0x0000fff0
+#define ESDHC_PREDIV_SHIFT 8
+#define ESDHC_DIVIDER_SHIFT 4
+#define ESDHC_CLOCK_PEREN 0x00000004
+#define ESDHC_CLOCK_HCKEN 0x00000002
+#define ESDHC_CLOCK_IPGEN 0x00000001
+
+static u32 esdhc_readl(struct sdhci_host *host, int reg)
+{
+ return in_be32(host->ioaddr + reg);
+}
+
+static u16 esdhc_readw(struct sdhci_host *host, int reg)
+{
+ return in_be16(host->ioaddr + (reg ^ 0x2));
+}
+
+static u8 esdhc_readb(struct sdhci_host *host, int reg)
+{
+ return in_8(host->ioaddr + (reg ^ 0x3));
+}
+
+static void esdhc_writel(struct sdhci_host *host, u32 val, int reg)
+{
+ out_be32(host->ioaddr + reg, val);
+}
+
+static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
+{
+ struct sdhci_of_host *of_host = sdhci_priv(host);
+ int base = reg & ~0x3;
+ int shift = (reg & 0x2) * 8;
+
+ switch (reg) {
+ case SDHCI_TRANSFER_MODE:
+ /*
+ * Postpone this write, we must do it together with a
+ * command write that is down below.
+ */
+ of_host->xfer_mode_shadow = val;
+ return;
+ case SDHCI_COMMAND:
+ esdhc_writel(host, val << 16 | of_host->xfer_mode_shadow,
+ SDHCI_TRANSFER_MODE);
+ return;
+ case SDHCI_BLOCK_SIZE:
+ /*
+ * Two last DMA bits are reserved, and first one is used for
+ * non-standard blksz of 4096 bytes that we don't support
+ * yet. So clear the DMA boundary bits.
+ */
+ val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
+ /* fall through */
+ }
+ clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
+}
+
+static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+ int base = reg & ~0x3;
+ int shift = (reg & 0x3) * 8;
+
+ clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
+}
+
+static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+ int div;
+ int pre_div = 2;
+
+ clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
+ ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
+
+ if (clock == 0)
+ goto out;
+
+ if (host->max_clk / 16 > clock) {
+ for (; pre_div < 256; pre_div *= 2) {
+ if (host->max_clk / pre_div < clock * 16)
+ break;
+ }
+ }
+
+ for (div = 1; div <= 16; div++) {
+ if (host->max_clk / (div * pre_div) <= clock)
+ break;
+ }
+
+ pre_div >>= 1;
+
+ setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
+ ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
+ div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT);
+ mdelay(100);
+out:
+ host->clock = clock;
+}
+
+static int esdhc_enable_dma(struct sdhci_host *host)
+{
+ setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
+ return 0;
+}
+
+static unsigned int esdhc_get_max_clock(struct sdhci_host *host)
+{
+ struct sdhci_of_host *of_host = sdhci_priv(host);
+
+ return of_host->clock;
+}
+
+static unsigned int esdhc_get_timeout_clock(struct sdhci_host *host)
+{
+ struct sdhci_of_host *of_host = sdhci_priv(host);
+
+ return of_host->clock / 1000;
+}
+
+static struct sdhci_of_data sdhci_esdhc = {
+ .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
+ SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+ SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
+ SDHCI_QUIRK_NO_BUSY_IRQ |
+ SDHCI_QUIRK_NONSTANDARD_CLOCK |
+ SDHCI_QUIRK_PIO_NEEDS_DELAY |
+ SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET |
+ SDHCI_QUIRK_NO_CARD_NO_RESET,
+ .ops = {
+ .readl = esdhc_readl,
+ .readw = esdhc_readw,
+ .readb = esdhc_readb,
+ .writel = esdhc_writel,
+ .writew = esdhc_writew,
+ .writeb = esdhc_writeb,
+ .set_clock = esdhc_set_clock,
+ .enable_dma = esdhc_enable_dma,
+ .get_max_clock = esdhc_get_max_clock,
+ .get_timeout_clock = esdhc_get_timeout_clock,
+ },
+};
+
+#ifdef CONFIG_PM
+
+static int sdhci_of_suspend(struct of_device *ofdev, pm_message_t state)
+{
+ struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+ return mmc_suspend_host(host->mmc, state);
+}
+
+static int sdhci_of_resume(struct of_device *ofdev)
+{
+ struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+ return mmc_resume_host(host->mmc);
+}
+
+#else
+
+#define sdhci_of_suspend NULL
+#define sdhci_of_resume NULL
+
+#endif
+
+static int __devinit sdhci_of_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct device_node *np = ofdev->node;
+ struct sdhci_of_data *sdhci_of_data = match->data;
+ struct sdhci_host *host;
+ struct sdhci_of_host *of_host;
+ const u32 *clk;
+ int size;
+ int ret;
+
+ if (!of_device_is_available(np))
+ return -ENODEV;
+
+ host = sdhci_alloc_host(&ofdev->dev, sizeof(*of_host));
+ if (!host)
+ return -ENOMEM;
+
+ of_host = sdhci_priv(host);
+ dev_set_drvdata(&ofdev->dev, host);
+
+ host->ioaddr = of_iomap(np, 0);
+ if (!host->ioaddr) {
+ ret = -ENOMEM;
+ goto err_addr_map;
+ }
+
+ host->irq = irq_of_parse_and_map(np, 0);
+ if (!host->irq) {
+ ret = -EINVAL;
+ goto err_no_irq;
+ }
+
+ host->hw_name = dev_name(&ofdev->dev);
+ if (sdhci_of_data) {
+ host->quirks = sdhci_of_data->quirks;
+ host->ops = &sdhci_of_data->ops;
+ }
+
+ clk = of_get_property(np, "clock-frequency", &size);
+ if (clk && size == sizeof(*clk) && *clk)
+ of_host->clock = *clk;
+
+ ret = sdhci_add_host(host);
+ if (ret)
+ goto err_add_host;
+
+ return 0;
+
+err_add_host:
+ irq_dispose_mapping(host->irq);
+err_no_irq:
+ iounmap(host->ioaddr);
+err_addr_map:
+ sdhci_free_host(host);
+ return ret;
+}
+
+static int __devexit sdhci_of_remove(struct of_device *ofdev)
+{
+ struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+ sdhci_remove_host(host, 0);
+ sdhci_free_host(host);
+ irq_dispose_mapping(host->irq);
+ iounmap(host->ioaddr);
+ return 0;
+}
+
+static const struct of_device_id sdhci_of_match[] = {
+ { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, },
+ { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, },
+ { .compatible = "generic-sdhci", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sdhci_of_match);
+
+static struct of_platform_driver sdhci_of_driver = {
+ .driver.name = "sdhci-of",
+ .match_table = sdhci_of_match,
+ .probe = sdhci_of_probe,
+ .remove = __devexit_p(sdhci_of_remove),
+ .suspend = sdhci_of_suspend,
+ .resume = sdhci_of_resume,
+};
+
+static int __init sdhci_of_init(void)
+{
+ return of_register_platform_driver(&sdhci_of_driver);
+}
+module_init(sdhci_of_init);
+
+static void __exit sdhci_of_exit(void)
+{
+ of_unregister_platform_driver(&sdhci_of_driver);
+}
+module_exit(sdhci_of_exit);
+
+MODULE_DESCRIPTION("Secure Digital Host Controller Interface OF driver");
+MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
+ "Anton Vorontsov <avorontsov@ru.mvista.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 406da9a8d45..cd37962ec44 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -380,7 +380,7 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host)
"doesn't fully claim to support it.\n");
}
- ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (ret)
return ret;
@@ -729,6 +729,6 @@ static void __exit sdhci_drv_exit(void)
module_init(sdhci_drv_init);
module_exit(sdhci_drv_exit);
-MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
+MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
MODULE_DESCRIPTION("Secure Digital Host Controller Interface PCI driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index accb592764e..9234be2226e 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -48,35 +48,35 @@ static void sdhci_dumpregs(struct sdhci_host *host)
printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n");
printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n",
- readl(host->ioaddr + SDHCI_DMA_ADDRESS),
- readw(host->ioaddr + SDHCI_HOST_VERSION));
+ sdhci_readl(host, SDHCI_DMA_ADDRESS),
+ sdhci_readw(host, SDHCI_HOST_VERSION));
printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n",
- readw(host->ioaddr + SDHCI_BLOCK_SIZE),
- readw(host->ioaddr + SDHCI_BLOCK_COUNT));
+ sdhci_readw(host, SDHCI_BLOCK_SIZE),
+ sdhci_readw(host, SDHCI_BLOCK_COUNT));
printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
- readl(host->ioaddr + SDHCI_ARGUMENT),
- readw(host->ioaddr + SDHCI_TRANSFER_MODE));
+ sdhci_readl(host, SDHCI_ARGUMENT),
+ sdhci_readw(host, SDHCI_TRANSFER_MODE));
printk(KERN_DEBUG DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n",
- readl(host->ioaddr + SDHCI_PRESENT_STATE),
- readb(host->ioaddr + SDHCI_HOST_CONTROL));
+ sdhci_readl(host, SDHCI_PRESENT_STATE),
+ sdhci_readb(host, SDHCI_HOST_CONTROL));
printk(KERN_DEBUG DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n",
- readb(host->ioaddr + SDHCI_POWER_CONTROL),
- readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL));
+ sdhci_readb(host, SDHCI_POWER_CONTROL),
+ sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
printk(KERN_DEBUG DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n",
- readb(host->ioaddr + SDHCI_WAKE_UP_CONTROL),
- readw(host->ioaddr + SDHCI_CLOCK_CONTROL));
+ sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
+ sdhci_readw(host, SDHCI_CLOCK_CONTROL));
printk(KERN_DEBUG DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n",
- readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL),
- readl(host->ioaddr + SDHCI_INT_STATUS));
+ sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
+ sdhci_readl(host, SDHCI_INT_STATUS));
printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
- readl(host->ioaddr + SDHCI_INT_ENABLE),
- readl(host->ioaddr + SDHCI_SIGNAL_ENABLE));
+ sdhci_readl(host, SDHCI_INT_ENABLE),
+ sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
- readw(host->ioaddr + SDHCI_ACMD12_ERR),
- readw(host->ioaddr + SDHCI_SLOT_INT_STATUS));
+ sdhci_readw(host, SDHCI_ACMD12_ERR),
+ sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
printk(KERN_DEBUG DRIVER_NAME ": Caps: 0x%08x | Max curr: 0x%08x\n",
- readl(host->ioaddr + SDHCI_CAPABILITIES),
- readl(host->ioaddr + SDHCI_MAX_CURRENT));
+ sdhci_readl(host, SDHCI_CAPABILITIES),
+ sdhci_readl(host, SDHCI_MAX_CURRENT));
printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
}
@@ -87,17 +87,65 @@ static void sdhci_dumpregs(struct sdhci_host *host)
* *
\*****************************************************************************/
+static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
+{
+ u32 ier;
+
+ ier = sdhci_readl(host, SDHCI_INT_ENABLE);
+ ier &= ~clear;
+ ier |= set;
+ sdhci_writel(host, ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
+}
+
+static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
+{
+ sdhci_clear_set_irqs(host, 0, irqs);
+}
+
+static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
+{
+ sdhci_clear_set_irqs(host, irqs, 0);
+}
+
+static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
+{
+ u32 irqs = SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT;
+
+ if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+ return;
+
+ if (enable)
+ sdhci_unmask_irqs(host, irqs);
+ else
+ sdhci_mask_irqs(host, irqs);
+}
+
+static void sdhci_enable_card_detection(struct sdhci_host *host)
+{
+ sdhci_set_card_detection(host, true);
+}
+
+static void sdhci_disable_card_detection(struct sdhci_host *host)
+{
+ sdhci_set_card_detection(host, false);
+}
+
static void sdhci_reset(struct sdhci_host *host, u8 mask)
{
unsigned long timeout;
+ u32 uninitialized_var(ier);
if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
- if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
+ if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
SDHCI_CARD_PRESENT))
return;
}
- writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET);
+ if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
+ ier = sdhci_readl(host, SDHCI_INT_ENABLE);
+
+ sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
if (mask & SDHCI_RESET_ALL)
host->clock = 0;
@@ -106,7 +154,7 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
timeout = 100;
/* hw clears the bit when it's done */
- while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) {
+ while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
if (timeout == 0) {
printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
mmc_hostname(host->mmc), (int)mask);
@@ -116,42 +164,44 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
timeout--;
mdelay(1);
}
+
+ if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
+ sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
}
static void sdhci_init(struct sdhci_host *host)
{
- u32 intmask;
-
sdhci_reset(host, SDHCI_RESET_ALL);
- intmask = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
+ sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
+ SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
- SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT |
- SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL |
- SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE |
- SDHCI_INT_ADMA_ERROR;
+ SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
+}
- writel(intmask, host->ioaddr + SDHCI_INT_ENABLE);
- writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE);
+static void sdhci_reinit(struct sdhci_host *host)
+{
+ sdhci_init(host);
+ sdhci_enable_card_detection(host);
}
static void sdhci_activate_led(struct sdhci_host *host)
{
u8 ctrl;
- ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
ctrl |= SDHCI_CTRL_LED;
- writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
}
static void sdhci_deactivate_led(struct sdhci_host *host)
{
u8 ctrl;
- ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
ctrl &= ~SDHCI_CTRL_LED;
- writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
}
#ifdef SDHCI_USE_LEDS_CLASS
@@ -205,7 +255,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host)
while (len) {
if (chunk == 0) {
- scratch = readl(host->ioaddr + SDHCI_BUFFER);
+ scratch = sdhci_readl(host, SDHCI_BUFFER);
chunk = 4;
}
@@ -257,7 +307,7 @@ static void sdhci_write_block_pio(struct sdhci_host *host)
len--;
if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
- writel(scratch, host->ioaddr + SDHCI_BUFFER);
+ sdhci_writel(host, scratch, SDHCI_BUFFER);
chunk = 0;
scratch = 0;
}
@@ -292,7 +342,10 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
(host->data->blocks == 1))
mask = ~0;
- while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
+ while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
+ if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY)
+ udelay(100);
+
if (host->data->flags & MMC_DATA_READ)
sdhci_read_block_pio(host);
else
@@ -561,6 +614,17 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
return count;
}
+static void sdhci_set_transfer_irqs(struct sdhci_host *host)
+{
+ u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL;
+ u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
+
+ if (host->flags & SDHCI_REQ_USE_DMA)
+ sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
+ else
+ sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
+}
+
static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
{
u8 count;
@@ -581,7 +645,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
host->data_early = 0;
count = sdhci_calc_timeout(host, data);
- writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL);
+ sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
if (host->flags & SDHCI_USE_DMA)
host->flags |= SDHCI_REQ_USE_DMA;
@@ -661,8 +725,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
WARN_ON(1);
host->flags &= ~SDHCI_REQ_USE_DMA;
} else {
- writel(host->adma_addr,
- host->ioaddr + SDHCI_ADMA_ADDRESS);
+ sdhci_writel(host, host->adma_addr,
+ SDHCI_ADMA_ADDRESS);
}
} else {
int sg_cnt;
@@ -681,8 +745,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
host->flags &= ~SDHCI_REQ_USE_DMA;
} else {
WARN_ON(sg_cnt != 1);
- writel(sg_dma_address(data->sg),
- host->ioaddr + SDHCI_DMA_ADDRESS);
+ sdhci_writel(host, sg_dma_address(data->sg),
+ SDHCI_DMA_ADDRESS);
}
}
}
@@ -693,14 +757,14 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
* is ADMA.
*/
if (host->version >= SDHCI_SPEC_200) {
- ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
ctrl &= ~SDHCI_CTRL_DMA_MASK;
if ((host->flags & SDHCI_REQ_USE_DMA) &&
(host->flags & SDHCI_USE_ADMA))
ctrl |= SDHCI_CTRL_ADMA32;
else
ctrl |= SDHCI_CTRL_SDMA;
- writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
}
if (!(host->flags & SDHCI_REQ_USE_DMA)) {
@@ -709,10 +773,11 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
host->blocks = data->blocks;
}
+ sdhci_set_transfer_irqs(host);
+
/* We do not handle DMA boundaries, so set it to max (512 KiB) */
- writew(SDHCI_MAKE_BLKSZ(7, data->blksz),
- host->ioaddr + SDHCI_BLOCK_SIZE);
- writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT);
+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE);
+ sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
}
static void sdhci_set_transfer_mode(struct sdhci_host *host,
@@ -733,7 +798,7 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host,
if (host->flags & SDHCI_REQ_USE_DMA)
mode |= SDHCI_TRNS_DMA;
- writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE);
+ sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
}
static void sdhci_finish_data(struct sdhci_host *host)
@@ -802,7 +867,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
if (host->mrq->data && (cmd == host->mrq->data->stop))
mask &= ~SDHCI_DATA_INHIBIT;
- while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
+ while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
if (timeout == 0) {
printk(KERN_ERR "%s: Controller never released "
"inhibit bit(s).\n", mmc_hostname(host->mmc));
@@ -821,7 +886,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
sdhci_prepare_data(host, cmd->data);
- writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT);
+ sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
sdhci_set_transfer_mode(host, cmd->data);
@@ -849,8 +914,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
if (cmd->data)
flags |= SDHCI_CMD_DATA;
- writew(SDHCI_MAKE_CMD(cmd->opcode, flags),
- host->ioaddr + SDHCI_COMMAND);
+ sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
}
static void sdhci_finish_command(struct sdhci_host *host)
@@ -863,15 +927,15 @@ static void sdhci_finish_command(struct sdhci_host *host)
if (host->cmd->flags & MMC_RSP_136) {
/* CRC is stripped so we need to do some shifting. */
for (i = 0;i < 4;i++) {
- host->cmd->resp[i] = readl(host->ioaddr +
+ host->cmd->resp[i] = sdhci_readl(host,
SDHCI_RESPONSE + (3-i)*4) << 8;
if (i != 3)
host->cmd->resp[i] |=
- readb(host->ioaddr +
+ sdhci_readb(host,
SDHCI_RESPONSE + (3-i)*4-1);
}
} else {
- host->cmd->resp[0] = readl(host->ioaddr + SDHCI_RESPONSE);
+ host->cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
}
}
@@ -895,7 +959,13 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
if (clock == host->clock)
return;
- writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
+ if (host->ops->set_clock) {
+ host->ops->set_clock(host, clock);
+ if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
+ return;
+ }
+
+ sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
if (clock == 0)
goto out;
@@ -908,11 +978,11 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
clk = div << SDHCI_DIVIDER_SHIFT;
clk |= SDHCI_CLOCK_INT_EN;
- writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
/* Wait max 10 ms */
timeout = 10;
- while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL))
+ while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
& SDHCI_CLOCK_INT_STABLE)) {
if (timeout == 0) {
printk(KERN_ERR "%s: Internal clock never "
@@ -925,7 +995,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
}
clk |= SDHCI_CLOCK_CARD_EN;
- writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
out:
host->clock = clock;
@@ -939,7 +1009,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
return;
if (power == (unsigned short)-1) {
- writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
+ sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
goto out;
}
@@ -948,7 +1018,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
* a new value. Some controllers don't seem to like this though.
*/
if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
- writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
+ sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
pwr = SDHCI_POWER_ON;
@@ -973,10 +1043,9 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
* and set turn on power at the same time, so set the voltage first.
*/
if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
- writeb(pwr & ~SDHCI_POWER_ON,
- host->ioaddr + SDHCI_POWER_CONTROL);
+ sdhci_writeb(host, pwr & ~SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
- writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL);
+ sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
out:
host->power = power;
@@ -991,6 +1060,7 @@ out:
static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct sdhci_host *host;
+ bool present;
unsigned long flags;
host = mmc_priv(mmc);
@@ -1005,8 +1075,14 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
host->mrq = mrq;
- if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)
- || (host->flags & SDHCI_DEVICE_DEAD)) {
+ /* If polling, assume that the card is always present. */
+ if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+ present = true;
+ else
+ present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
+ SDHCI_CARD_PRESENT;
+
+ if (!present || host->flags & SDHCI_DEVICE_DEAD) {
host->mrq->cmd->error = -ENOMEDIUM;
tasklet_schedule(&host->finish_tasklet);
} else
@@ -1034,8 +1110,8 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
* Should clear out any weird states.
*/
if (ios->power_mode == MMC_POWER_OFF) {
- writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE);
- sdhci_init(host);
+ sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
+ sdhci_reinit(host);
}
sdhci_set_clock(host, ios->clock);
@@ -1045,7 +1121,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
else
sdhci_set_power(host, ios->vdd);
- ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
if (ios->bus_width == MMC_BUS_WIDTH_4)
ctrl |= SDHCI_CTRL_4BITBUS;
@@ -1057,7 +1133,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
else
ctrl &= ~SDHCI_CTRL_HISPD;
- writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
/*
* Some (ENE) controllers go apeshit on some ios operation,
@@ -1085,10 +1161,12 @@ static int sdhci_get_ro(struct mmc_host *mmc)
if (host->flags & SDHCI_DEVICE_DEAD)
present = 0;
else
- present = readl(host->ioaddr + SDHCI_PRESENT_STATE);
+ present = sdhci_readl(host, SDHCI_PRESENT_STATE);
spin_unlock_irqrestore(&host->lock, flags);
+ if (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)
+ return !!(present & SDHCI_WRITE_PROTECT);
return !(present & SDHCI_WRITE_PROTECT);
}
@@ -1096,7 +1174,6 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct sdhci_host *host;
unsigned long flags;
- u32 ier;
host = mmc_priv(mmc);
@@ -1105,15 +1182,10 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
if (host->flags & SDHCI_DEVICE_DEAD)
goto out;
- ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
-
- ier &= ~SDHCI_INT_CARD_INT;
if (enable)
- ier |= SDHCI_INT_CARD_INT;
-
- writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
- writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
-
+ sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
+ else
+ sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
out:
mmiowb();
@@ -1142,7 +1214,7 @@ static void sdhci_tasklet_card(unsigned long param)
spin_lock_irqsave(&host->lock, flags);
- if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
+ if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
if (host->mrq) {
printk(KERN_ERR "%s: Card removed during transfer!\n",
mmc_hostname(host->mmc));
@@ -1346,8 +1418,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
* we need to at least restart the transfer.
*/
if (intmask & SDHCI_INT_DMA_END)
- writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS),
- host->ioaddr + SDHCI_DMA_ADDRESS);
+ sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS),
+ SDHCI_DMA_ADDRESS);
if (intmask & SDHCI_INT_DATA_END) {
if (host->cmd) {
@@ -1373,7 +1445,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
spin_lock(&host->lock);
- intmask = readl(host->ioaddr + SDHCI_INT_STATUS);
+ intmask = sdhci_readl(host, SDHCI_INT_STATUS);
if (!intmask || intmask == 0xffffffff) {
result = IRQ_NONE;
@@ -1384,22 +1456,22 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
mmc_hostname(host->mmc), intmask);
if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
- writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE),
- host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
+ SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
tasklet_schedule(&host->card_tasklet);
}
intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
if (intmask & SDHCI_INT_CMD_MASK) {
- writel(intmask & SDHCI_INT_CMD_MASK,
- host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
+ SDHCI_INT_STATUS);
sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
}
if (intmask & SDHCI_INT_DATA_MASK) {
- writel(intmask & SDHCI_INT_DATA_MASK,
- host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
+ SDHCI_INT_STATUS);
sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
}
@@ -1410,7 +1482,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
if (intmask & SDHCI_INT_BUS_POWER) {
printk(KERN_ERR "%s: Card is consuming too much power!\n",
mmc_hostname(host->mmc));
- writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
}
intmask &= ~SDHCI_INT_BUS_POWER;
@@ -1425,7 +1497,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
mmc_hostname(host->mmc), intmask);
sdhci_dumpregs(host);
- writel(intmask, host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, intmask, SDHCI_INT_STATUS);
}
result = IRQ_HANDLED;
@@ -1455,6 +1527,8 @@ int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
{
int ret;
+ sdhci_disable_card_detection(host);
+
ret = mmc_suspend_host(host->mmc, state);
if (ret)
return ret;
@@ -1487,6 +1561,8 @@ int sdhci_resume_host(struct sdhci_host *host)
if (ret)
return ret;
+ sdhci_enable_card_detection(host);
+
return 0;
}
@@ -1537,7 +1613,7 @@ int sdhci_add_host(struct sdhci_host *host)
sdhci_reset(host, SDHCI_RESET_ALL);
- host->version = readw(host->ioaddr + SDHCI_HOST_VERSION);
+ host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
host->version = (host->version & SDHCI_SPEC_VER_MASK)
>> SDHCI_SPEC_VER_SHIFT;
if (host->version > SDHCI_SPEC_200) {
@@ -1546,7 +1622,7 @@ int sdhci_add_host(struct sdhci_host *host)
host->version);
}
- caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
+ caps = sdhci_readl(host, SDHCI_CAPABILITIES);
if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
host->flags |= SDHCI_USE_DMA;
@@ -1614,19 +1690,27 @@ int sdhci_add_host(struct sdhci_host *host)
host->max_clk =
(caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
+ host->max_clk *= 1000000;
if (host->max_clk == 0) {
- printk(KERN_ERR "%s: Hardware doesn't specify base clock "
- "frequency.\n", mmc_hostname(mmc));
- return -ENODEV;
+ if (!host->ops->get_max_clock) {
+ printk(KERN_ERR
+ "%s: Hardware doesn't specify base clock "
+ "frequency.\n", mmc_hostname(mmc));
+ return -ENODEV;
+ }
+ host->max_clk = host->ops->get_max_clock(host);
}
- host->max_clk *= 1000000;
host->timeout_clk =
(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
if (host->timeout_clk == 0) {
- printk(KERN_ERR "%s: Hardware doesn't specify timeout clock "
- "frequency.\n", mmc_hostname(mmc));
- return -ENODEV;
+ if (!host->ops->get_timeout_clock) {
+ printk(KERN_ERR
+ "%s: Hardware doesn't specify timeout clock "
+ "frequency.\n", mmc_hostname(mmc));
+ return -ENODEV;
+ }
+ host->timeout_clk = host->ops->get_timeout_clock(host);
}
if (caps & SDHCI_TIMEOUT_CLK_UNIT)
host->timeout_clk *= 1000;
@@ -1642,6 +1726,9 @@ int sdhci_add_host(struct sdhci_host *host)
if (caps & SDHCI_CAN_DO_HISPD)
mmc->caps |= MMC_CAP_SD_HIGHSPEED;
+ if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+ mmc->caps |= MMC_CAP_NEEDS_POLL;
+
mmc->ocr_avail = 0;
if (caps & SDHCI_CAN_VDD_330)
mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
@@ -1690,13 +1777,19 @@ int sdhci_add_host(struct sdhci_host *host)
* Maximum block size. This varies from controller to controller and
* is specified in the capabilities register.
*/
- mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
- if (mmc->max_blk_size >= 3) {
- printk(KERN_WARNING "%s: Invalid maximum block size, "
- "assuming 512 bytes\n", mmc_hostname(mmc));
- mmc->max_blk_size = 512;
- } else
- mmc->max_blk_size = 512 << mmc->max_blk_size;
+ if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) {
+ mmc->max_blk_size = 2;
+ } else {
+ mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >>
+ SDHCI_MAX_BLOCK_SHIFT;
+ if (mmc->max_blk_size >= 3) {
+ printk(KERN_WARNING "%s: Invalid maximum block size, "
+ "assuming 512 bytes\n", mmc_hostname(mmc));
+ mmc->max_blk_size = 0;
+ }
+ }
+
+ mmc->max_blk_size = 512 << mmc->max_blk_size;
/*
* Maximum block count.
@@ -1746,6 +1839,8 @@ int sdhci_add_host(struct sdhci_host *host)
(host->flags & SDHCI_USE_ADMA)?"A":"",
(host->flags & SDHCI_USE_DMA)?"DMA":"PIO");
+ sdhci_enable_card_detection(host);
+
return 0;
#ifdef SDHCI_USE_LEDS_CLASS
@@ -1782,6 +1877,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
spin_unlock_irqrestore(&host->lock, flags);
}
+ sdhci_disable_card_detection(host);
+
mmc_remove_host(host->mmc);
#ifdef SDHCI_USE_LEDS_CLASS
@@ -1838,7 +1935,7 @@ module_exit(sdhci_drv_exit);
module_param(debug_quirks, uint, 0444);
-MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
+MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
MODULE_DESCRIPTION("Secure Digital Host Controller Interface core driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 43c37c68d07..f20a834f430 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -10,6 +10,9 @@
*/
#include <linux/scatterlist.h>
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/io.h>
/*
* Controller registers
@@ -123,6 +126,7 @@
SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
SDHCI_INT_DATA_END_BIT)
+#define SDHCI_INT_ALL_MASK ((unsigned int)-1)
#define SDHCI_ACMD12_ERR 0x3C
@@ -210,6 +214,18 @@ struct sdhci_host {
#define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13)
/* Controller does not provide transfer-complete interrupt when not busy */
#define SDHCI_QUIRK_NO_BUSY_IRQ (1<<14)
+/* Controller has unreliable card detection */
+#define SDHCI_QUIRK_BROKEN_CARD_DETECTION (1<<15)
+/* Controller reports inverted write-protect state */
+#define SDHCI_QUIRK_INVERTED_WRITE_PROTECT (1<<16)
+/* Controller has nonstandard clock management */
+#define SDHCI_QUIRK_NONSTANDARD_CLOCK (1<<17)
+/* Controller does not like fast PIO transfers */
+#define SDHCI_QUIRK_PIO_NEEDS_DELAY (1<<18)
+/* Controller losing signal/interrupt enable states after reset */
+#define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET (1<<19)
+/* Controller has to be forced to use block size of 2048 bytes */
+#define SDHCI_QUIRK_FORCE_BLK_SZ_2048 (1<<20)
int irq; /* Device IRQ */
void __iomem * ioaddr; /* Mapped address */
@@ -267,9 +283,105 @@ struct sdhci_host {
struct sdhci_ops {
+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+ u32 (*readl)(struct sdhci_host *host, int reg);
+ u16 (*readw)(struct sdhci_host *host, int reg);
+ u8 (*readb)(struct sdhci_host *host, int reg);
+ void (*writel)(struct sdhci_host *host, u32 val, int reg);
+ void (*writew)(struct sdhci_host *host, u16 val, int reg);
+ void (*writeb)(struct sdhci_host *host, u8 val, int reg);
+#endif
+
+ void (*set_clock)(struct sdhci_host *host, unsigned int clock);
+
int (*enable_dma)(struct sdhci_host *host);
+ unsigned int (*get_max_clock)(struct sdhci_host *host);
+ unsigned int (*get_timeout_clock)(struct sdhci_host *host);
};
+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+
+static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+ if (unlikely(host->ops->writel))
+ host->ops->writel(host, val, reg);
+ else
+ writel(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+ if (unlikely(host->ops->writew))
+ host->ops->writew(host, val, reg);
+ else
+ writew(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+ if (unlikely(host->ops->writeb))
+ host->ops->writeb(host, val, reg);
+ else
+ writeb(val, host->ioaddr + reg);
+}
+
+static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
+{
+ if (unlikely(host->ops->readl))
+ return host->ops->readl(host, reg);
+ else
+ return readl(host->ioaddr + reg);
+}
+
+static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
+{
+ if (unlikely(host->ops->readw))
+ return host->ops->readw(host, reg);
+ else
+ return readw(host->ioaddr + reg);
+}
+
+static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
+{
+ if (unlikely(host->ops->readb))
+ return host->ops->readb(host, reg);
+ else
+ return readb(host->ioaddr + reg);
+}
+
+#else
+
+static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+ writel(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+ writew(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+ writeb(val, host->ioaddr + reg);
+}
+
+static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
+{
+ return readl(host->ioaddr + reg);
+}
+
+static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
+{
+ return readw(host->ioaddr + reg);
+}
+
+static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
+{
+ return readb(host->ioaddr + reg);
+}
+
+#endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */
extern struct sdhci_host *sdhci_alloc_host(struct device *dev,
size_t priv_size);
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index 6a7a6190483..63fbd5b7d31 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -568,11 +568,11 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
host->mmc = mmc;
platform_set_drvdata(dev, mmc);
- host->ctl = ioremap(res_ctl->start, res_ctl->end - res_ctl->start);
+ host->ctl = ioremap(res_ctl->start, resource_size(res_ctl));
if (!host->ctl)
goto host_free;
- host->cnf = ioremap(res_cnf->start, res_cnf->end - res_cnf->start);
+ host->cnf = ioremap(res_cnf->start, resource_size(res_cnf));
if (!host->cnf)
goto unmap_ctl;
@@ -650,10 +650,10 @@ static int __devexit tmio_mmc_remove(struct platform_device *dev)
if (mmc) {
struct tmio_mmc_host *host = mmc_priv(mmc);
mmc_remove_host(mmc);
- mmc_free_host(mmc);
free_irq(host->irq, host);
iounmap(host->ctl);
iounmap(host->cnf);
+ mmc_free_host(mmc);
}
return 0;
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index ba2b4240a86..9c831ab2ece 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -8,6 +8,9 @@
* published by the Free Software Foundation.
*
*/
+
+#include <linux/highmem.h>
+
#define CNF_CMD 0x04
#define CNF_CTL_BASE 0x10
#define CNF_INT_PIN 0x3d
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index adda3795203..89bf8cd25ca 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -2036,7 +2036,7 @@ module_param_named(irq, param_irq, uint, 0444);
module_param_named(dma, param_dma, int, 0444);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
+MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver");
#ifdef CONFIG_PNP
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 4521b1ecce4..82d1e4de475 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -4,7 +4,7 @@
# Core functionality.
obj-$(CONFIG_MTD) += mtd.o
-mtd-y := mtdcore.o mtdsuper.o
+mtd-y := mtdcore.o mtdsuper.o mtdbdi.o
mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o
diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c
index ecf170b55c3..6697a1ec72d 100644
--- a/drivers/mtd/ar7part.c
+++ b/drivers/mtd/ar7part.c
@@ -44,8 +44,6 @@ struct ar7_bin_rec {
unsigned int address;
};
-static struct mtd_partition ar7_parts[AR7_PARTS];
-
static int create_mtd_partitions(struct mtd_info *master,
struct mtd_partition **pparts,
unsigned long origin)
@@ -57,7 +55,11 @@ static int create_mtd_partitions(struct mtd_info *master,
unsigned int root_offset = ROOT_OFFSET;
int retries = 10;
+ struct mtd_partition *ar7_parts;
+ ar7_parts = kzalloc(sizeof(*ar7_parts) * AR7_PARTS, GFP_KERNEL);
+ if (!ar7_parts)
+ return -ENOMEM;
ar7_parts[0].name = "loader";
ar7_parts[0].offset = 0;
ar7_parts[0].size = master->erasesize;
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index f5ab6fa1057..c240454fd11 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -1236,10 +1236,14 @@ static int inval_cache_and_wait_for_operation(
remove_wait_queue(&chip->wq, &wait);
spin_lock(chip->mutex);
}
- if (chip->erase_suspended || chip->write_suspended) {
- /* Suspend has occured while sleep: reset timeout */
+ if (chip->erase_suspended && chip_state == FL_ERASING) {
+ /* Erase suspend occured while sleep: reset timeout */
timeo = reset_timeo;
chip->erase_suspended = 0;
+ }
+ if (chip->write_suspended && chip_state == FL_WRITING) {
+ /* Write suspend occured while sleep: reset timeout */
+ timeo = reset_timeo;
chip->write_suspended = 0;
}
}
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 94bb61e1904..61ea833e090 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -282,6 +282,16 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param)
}
}
+static void fixup_M29W128G_write_buffer(struct mtd_info *mtd, void *param)
+{
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ if (cfi->cfiq->BufWriteTimeoutTyp) {
+ pr_warning("Don't use write buffer on ST flash M29W128G\n");
+ cfi->cfiq->BufWriteTimeoutTyp = 0;
+ }
+}
+
static struct cfi_fixup cfi_fixup_table[] = {
{ CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
#ifdef AMD_BOOTLOC_BUG
@@ -298,6 +308,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
{ CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, },
{ CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, },
{ CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, },
+ { CFI_MFR_ST, 0x227E, fixup_M29W128G_write_buffer, NULL, },
#if !FORCE_WORD_WRITE
{ CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
#endif
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index 2f3f2f719ba..e824b9b9b05 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -159,6 +159,7 @@
#define SST39LF800 0x2781
#define SST39LF160 0x2782
#define SST39VF1601 0x234b
+#define SST39VF3201 0x235b
#define SST39LF512 0x00D4
#define SST39LF010 0x00D5
#define SST39LF020 0x00D6
@@ -1490,6 +1491,21 @@ static const struct amd_flash_info jedec_table[] = {
ERASEINFO(0x1000,256)
}
}, {
+ .mfr_id = MANUFACTURER_SST, /* should be CFI */
+ .dev_id = SST39VF3201,
+ .name = "SST 39VF3201",
+ .devtypes = CFI_DEVICETYPE_X16,
+ .uaddr = MTD_UADDR_0xAAAA_0x5555,
+ .dev_size = SIZE_4MiB,
+ .cmd_set = P_ID_AMD_STD,
+ .nr_regions = 4,
+ .regions = {
+ ERASEINFO(0x1000,256),
+ ERASEINFO(0x1000,256),
+ ERASEINFO(0x1000,256),
+ ERASEINFO(0x1000,256)
+ }
+ }, {
.mfr_id = MANUFACTURER_SST,
.dev_id = SST36VF3203,
.name = "SST 36VF3203",
diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c
index 072dd8abf33..6bdc50c727e 100644
--- a/drivers/mtd/chips/map_ram.c
+++ b/drivers/mtd/chips/map_ram.c
@@ -21,6 +21,8 @@ static int mapram_write (struct mtd_info *, loff_t, size_t, size_t *, const u_ch
static int mapram_erase (struct mtd_info *, struct erase_info *);
static void mapram_nop (struct mtd_info *);
static struct mtd_info *map_ram_probe(struct map_info *map);
+static unsigned long mapram_unmapped_area(struct mtd_info *, unsigned long,
+ unsigned long, unsigned long);
static struct mtd_chip_driver mapram_chipdrv = {
@@ -64,6 +66,7 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
mtd->type = MTD_RAM;
mtd->size = map->size;
mtd->erase = mapram_erase;
+ mtd->get_unmapped_area = mapram_unmapped_area;
mtd->read = mapram_read;
mtd->write = mapram_write;
mtd->sync = mapram_nop;
@@ -79,6 +82,20 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
}
+/*
+ * Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+static unsigned long mapram_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ struct map_info *map = mtd->priv;
+ return (unsigned long) map->virt + offset;
+}
+
static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
{
struct map_info *map = mtd->priv;
diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c
index c76d6e5f47e..076090a67b9 100644
--- a/drivers/mtd/chips/map_rom.c
+++ b/drivers/mtd/chips/map_rom.c
@@ -20,6 +20,8 @@ static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_ch
static void maprom_nop (struct mtd_info *);
static struct mtd_info *map_rom_probe(struct map_info *map);
static int maprom_erase (struct mtd_info *mtd, struct erase_info *info);
+static unsigned long maprom_unmapped_area(struct mtd_info *, unsigned long,
+ unsigned long, unsigned long);
static struct mtd_chip_driver maprom_chipdrv = {
.probe = map_rom_probe,
@@ -40,6 +42,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
mtd->name = map->name;
mtd->type = MTD_ROM;
mtd->size = map->size;
+ mtd->get_unmapped_area = maprom_unmapped_area;
mtd->read = maprom_read;
mtd->write = maprom_write;
mtd->sync = maprom_nop;
@@ -53,6 +56,20 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
}
+/*
+ * Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+static unsigned long maprom_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ struct map_info *map = mtd->priv;
+ return (unsigned long) map->virt + offset;
+}
+
static int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
{
struct map_info *map = mtd->priv;
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index 50a340388e7..5011fa73f91 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -335,7 +335,11 @@ static int parse_cmdline_partitions(struct mtd_info *master,
}
offset += part->parts[i].size;
}
- *pparts = part->parts;
+ *pparts = kmemdup(part->parts,
+ sizeof(*part->parts) * part->num_parts,
+ GFP_KERNEL);
+ if (!*pparts)
+ return -ENOMEM;
return part->num_parts;
}
}
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 50de839c77a..5bf5f460e13 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -10,7 +10,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/sched.h>
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index e32c568c114..0990f780362 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -10,7 +10,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index d853f891b58..719b2915dc3 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -14,7 +14,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c
index 874e51b110a..a19cda52da5 100644
--- a/drivers/mtd/devices/docecc.c
+++ b/drivers/mtd/devices/docecc.c
@@ -26,7 +26,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 7c3fc766dcf..8185b1f3e5e 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -65,12 +65,6 @@
#define FAST_READ_DUMMY_BYTE 0
#endif
-#ifdef CONFIG_MTD_PARTITIONS
-#define mtd_has_partitions() (1)
-#else
-#define mtd_has_partitions() (0)
-#endif
-
/****************************************************************************/
struct m25p {
@@ -678,6 +672,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
flash->mtd.erasesize = info->sector_size;
}
+ flash->mtd.dev.parent = &spi->dev;
+
dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name,
(long long)flash->mtd.size >> 10);
@@ -708,12 +704,13 @@ static int __devinit m25p_probe(struct spi_device *spi)
struct mtd_partition *parts = NULL;
int nr_parts = 0;
-#ifdef CONFIG_MTD_CMDLINE_PARTS
- static const char *part_probes[] = { "cmdlinepart", NULL, };
+ if (mtd_has_cmdlinepart()) {
+ static const char *part_probes[]
+ = { "cmdlinepart", NULL, };
- nr_parts = parse_mtd_partitions(&flash->mtd,
- part_probes, &parts, 0);
-#endif
+ nr_parts = parse_mtd_partitions(&flash->mtd,
+ part_probes, &parts, 0);
+ }
if (nr_parts <= 0 && data && data->parts) {
parts = data->parts;
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 6d9f810565c..62dee54af0a 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -98,12 +98,6 @@ struct dataflash {
struct mtd_info mtd;
};
-#ifdef CONFIG_MTD_PARTITIONS
-#define mtd_has_partitions() (1)
-#else
-#define mtd_has_partitions() (0)
-#endif
-
/* ......................................................................... */
/*
@@ -670,6 +664,8 @@ add_dataflash_otp(struct spi_device *spi, char *name,
device->write = dataflash_write;
device->priv = priv;
+ device->dev.parent = &spi->dev;
+
if (revision >= 'c')
otp_tag = otp_setup(device, revision);
@@ -682,11 +678,13 @@ add_dataflash_otp(struct spi_device *spi, char *name,
struct mtd_partition *parts;
int nr_parts = 0;
-#ifdef CONFIG_MTD_CMDLINE_PARTS
- static const char *part_probes[] = { "cmdlinepart", NULL, };
+ if (mtd_has_cmdlinepart()) {
+ static const char *part_probes[]
+ = { "cmdlinepart", NULL, };
- nr_parts = parse_mtd_partitions(device, part_probes, &parts, 0);
-#endif
+ nr_parts = parse_mtd_partitions(device,
+ part_probes, &parts, 0);
+ }
if (nr_parts <= 0 && pdata && pdata->parts) {
parts = pdata->parts;
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
index 3aaca88847d..fce5ff7589a 100644
--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -65,6 +65,19 @@ static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
{
}
+/*
+ * Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+static unsigned long ram_get_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ return (unsigned long) mtd->priv + offset;
+}
+
static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
@@ -116,6 +129,7 @@ int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
mtd->erase = ram_erase;
mtd->point = ram_point;
mtd->unpoint = ram_unpoint;
+ mtd->get_unmapped_area = ram_get_unmapped_area;
mtd->read = ram_read;
mtd->write = ram_write;
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index f751dd97c54..32e82aef3e5 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -28,7 +28,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
diff --git a/drivers/mtd/internal.h b/drivers/mtd/internal.h
new file mode 100644
index 00000000000..c658fe7216b
--- /dev/null
+++ b/drivers/mtd/internal.h
@@ -0,0 +1,17 @@
+/* Internal MTD definitions
+ *
+ * Copyright © 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * mtdbdi.c
+ */
+extern struct backing_dev_info mtd_bdi_unmappable;
+extern struct backing_dev_info mtd_bdi_ro_mappable;
+extern struct backing_dev_info mtd_bdi_rw_mappable;
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 729f899a5cd..82923bd2d9c 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -529,12 +529,6 @@ config MTD_DMV182
help
Map driver for Dy-4 SVME/DMV-182 board.
-config MTD_SHARP_SL
- tristate "ROM mapped on Sharp SL Series"
- depends on ARCH_PXA
- help
- This enables access to the flash chip on the Sharp SL Series of PDAs.
-
config MTD_INTEL_VR_NOR
tristate "NOR flash on Intel Vermilion Range Expansion Bus CS0"
depends on PCI
@@ -542,6 +536,12 @@ config MTD_INTEL_VR_NOR
Map driver for a NOR flash bank located on the Expansion Bus of the
Intel Vermilion Range chipset.
+config MTD_RBTX4939
+ tristate "Map driver for RBTX4939 board"
+ depends on TOSHIBA_RBTX4939 && MTD_CFI && MTD_COMPLEX_MAPPINGS
+ help
+ Map driver for NOR flash chips on RBTX4939 board.
+
config MTD_PLATRAM
tristate "Map driver for platform device RAM (mtd-ram)"
select MTD_RAM
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 26b28a7a90b..2dbc1bec848 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -56,9 +56,9 @@ obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o
obj-$(CONFIG_MTD_IXP2000) += ixp2000.o
obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
obj-$(CONFIG_MTD_DMV182) += dmv182.o
-obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o
obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o
+obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o
obj-$(CONFIG_MTD_VMU) += vmu-flash.o
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index 7e50e9b1b78..a24478102b1 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -115,6 +115,8 @@ static int __init omapflash_probe(struct platform_device *pdev)
}
info->mtd->owner = THIS_MODULE;
+ info->mtd->dev.parent = &pdev->dev;
+
#ifdef CONFIG_MTD_PARTITIONS
err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0);
if (err > 0)
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index 229718222db..29a90115735 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -147,6 +147,7 @@ static int physmap_flash_probe(struct platform_device *dev)
devices_found++;
}
info->mtd[i]->owner = THIS_MODULE;
+ info->mtd[i]->dev.parent = &dev->dev;
}
if (devices_found == 1) {
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index fbf0ca939d7..c83a60fada5 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -219,6 +219,7 @@ static int __devinit of_flash_probe(struct of_device *dev,
goto err_out;
}
info->mtd->owner = THIS_MODULE;
+ info->mtd->dev.parent = &dev->dev;
#ifdef CONFIG_MTD_PARTITIONS
/* First look for RedBoot table or partitions on the command
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index e7dd9c8a965..49c9ece7647 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -224,6 +224,7 @@ static int platram_probe(struct platform_device *pdev)
}
info->mtd->owner = THIS_MODULE;
+ info->mtd->dev.parent = &pdev->dev;
platram_setrw(info, PLATRAM_RW);
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index e9026cb1c5b..572d32fdf38 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -117,7 +117,7 @@ static int __init pxa2xx_flash_probe(struct platform_device *pdev)
return 0;
}
-static int __exit pxa2xx_flash_remove(struct platform_device *dev)
+static int __devexit pxa2xx_flash_remove(struct platform_device *dev)
{
struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
diff --git a/drivers/mtd/maps/rbtx4939-flash.c b/drivers/mtd/maps/rbtx4939-flash.c
new file mode 100644
index 00000000000..d39f0adac84
--- /dev/null
+++ b/drivers/mtd/maps/rbtx4939-flash.c
@@ -0,0 +1,208 @@
+/*
+ * rbtx4939-flash (based on physmap.c)
+ *
+ * This is a simplified physmap driver with map_init callback function.
+ *
+ * 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.
+ *
+ * Copyright (C) 2009 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <asm/txx9/rbtx4939.h>
+
+struct rbtx4939_flash_info {
+ struct mtd_info *mtd;
+ struct map_info map;
+#ifdef CONFIG_MTD_PARTITIONS
+ int nr_parts;
+ struct mtd_partition *parts;
+#endif
+};
+
+static int rbtx4939_flash_remove(struct platform_device *dev)
+{
+ struct rbtx4939_flash_info *info;
+
+ info = platform_get_drvdata(dev);
+ if (!info)
+ return 0;
+ platform_set_drvdata(dev, NULL);
+
+ if (info->mtd) {
+#ifdef CONFIG_MTD_PARTITIONS
+ struct rbtx4939_flash_data *pdata = dev->dev.platform_data;
+
+ if (info->nr_parts) {
+ del_mtd_partitions(info->mtd);
+ kfree(info->parts);
+ } else if (pdata->nr_parts)
+ del_mtd_partitions(info->mtd);
+ else
+ del_mtd_device(info->mtd);
+#else
+ del_mtd_device(info->mtd);
+#endif
+ map_destroy(info->mtd);
+ }
+ return 0;
+}
+
+static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probe_types[] = { "cmdlinepart", NULL };
+#endif
+
+static int rbtx4939_flash_probe(struct platform_device *dev)
+{
+ struct rbtx4939_flash_data *pdata;
+ struct rbtx4939_flash_info *info;
+ struct resource *res;
+ const char **probe_type;
+ int err = 0;
+ unsigned long size;
+
+ pdata = dev->dev.platform_data;
+ if (!pdata)
+ return -ENODEV;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+ info = devm_kzalloc(&dev->dev, sizeof(struct rbtx4939_flash_info),
+ GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ platform_set_drvdata(dev, info);
+
+ size = resource_size(res);
+ pr_notice("rbtx4939 platform flash device: %pR\n", res);
+
+ if (!devm_request_mem_region(&dev->dev, res->start, size,
+ dev_name(&dev->dev)))
+ return -EBUSY;
+
+ info->map.name = dev_name(&dev->dev);
+ info->map.phys = res->start;
+ info->map.size = size;
+ info->map.bankwidth = pdata->width;
+
+ info->map.virt = devm_ioremap(&dev->dev, info->map.phys, size);
+ if (!info->map.virt)
+ return -EBUSY;
+
+ if (pdata->map_init)
+ (*pdata->map_init)(&info->map);
+ else
+ simple_map_init(&info->map);
+
+ probe_type = rom_probe_types;
+ for (; !info->mtd && *probe_type; probe_type++)
+ info->mtd = do_map_probe(*probe_type, &info->map);
+ if (!info->mtd) {
+ dev_err(&dev->dev, "map_probe failed\n");
+ err = -ENXIO;
+ goto err_out;
+ }
+ info->mtd->owner = THIS_MODULE;
+ if (err)
+ goto err_out;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ err = parse_mtd_partitions(info->mtd, part_probe_types,
+ &info->parts, 0);
+ if (err > 0) {
+ add_mtd_partitions(info->mtd, info->parts, err);
+ info->nr_parts = err;
+ return 0;
+ }
+
+ if (pdata->nr_parts) {
+ pr_notice("Using rbtx4939 partition information\n");
+ add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
+ return 0;
+ }
+#endif
+
+ add_mtd_device(info->mtd);
+ return 0;
+
+err_out:
+ rbtx4939_flash_remove(dev);
+ return err;
+}
+
+#ifdef CONFIG_PM
+static int rbtx4939_flash_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
+
+ if (info->mtd->suspend)
+ return info->mtd->suspend(info->mtd);
+ return 0;
+}
+
+static int rbtx4939_flash_resume(struct platform_device *dev)
+{
+ struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
+
+ if (info->mtd->resume)
+ info->mtd->resume(info->mtd);
+ return 0;
+}
+
+static void rbtx4939_flash_shutdown(struct platform_device *dev)
+{
+ struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
+
+ if (info->mtd->suspend && info->mtd->resume)
+ if (info->mtd->suspend(info->mtd) == 0)
+ info->mtd->resume(info->mtd);
+}
+#else
+#define rbtx4939_flash_suspend NULL
+#define rbtx4939_flash_resume NULL
+#define rbtx4939_flash_shutdown NULL
+#endif
+
+static struct platform_driver rbtx4939_flash_driver = {
+ .probe = rbtx4939_flash_probe,
+ .remove = rbtx4939_flash_remove,
+ .suspend = rbtx4939_flash_suspend,
+ .resume = rbtx4939_flash_resume,
+ .shutdown = rbtx4939_flash_shutdown,
+ .driver = {
+ .name = "rbtx4939-flash",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init rbtx4939_flash_init(void)
+{
+ return platform_driver_register(&rbtx4939_flash_driver);
+}
+
+static void __exit rbtx4939_flash_exit(void)
+{
+ platform_driver_unregister(&rbtx4939_flash_driver);
+}
+
+module_init(rbtx4939_flash_init);
+module_exit(rbtx4939_flash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RBTX4939 MTD map driver");
+MODULE_ALIAS("platform:rbtx4939-flash");
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 8f57b6f40aa..05e9362dc7f 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -351,7 +351,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat)
static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
-static int __init sa1100_mtd_probe(struct platform_device *pdev)
+static int __devinit sa1100_mtd_probe(struct platform_device *pdev)
{
struct flash_platform_data *plat = pdev->dev.platform_data;
struct mtd_partition *parts;
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
deleted file mode 100644
index b392f096c70..00000000000
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * sharpsl-flash.c
- *
- * Copyright (C) 2001 Lineo Japan, Inc.
- * Copyright (C) 2002 SHARP
- *
- * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp
- * Handle mapping of the flash on the RPX Lite and CLLF boards
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <asm/mach-types.h>
-
-#define WINDOW_ADDR 0x00000000
-#define WINDOW_SIZE 0x00800000
-#define BANK_WIDTH 2
-
-static struct mtd_info *mymtd;
-
-struct map_info sharpsl_map = {
- .name = "sharpsl-flash",
- .size = WINDOW_SIZE,
- .bankwidth = BANK_WIDTH,
- .phys = WINDOW_ADDR
-};
-
-static struct mtd_partition sharpsl_partitions[1] = {
- {
- name: "Boot PROM Filesystem",
- }
-};
-
-static int __init init_sharpsl(void)
-{
- struct mtd_partition *parts;
- int nb_parts = 0;
- char *part_type = "static";
-
- printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
- WINDOW_SIZE, WINDOW_ADDR);
- sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
- if (!sharpsl_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-
- simple_map_init(&sharpsl_map);
-
- mymtd = do_map_probe("map_rom", &sharpsl_map);
- if (!mymtd) {
- iounmap(sharpsl_map.virt);
- return -ENXIO;
- }
-
- mymtd->owner = THIS_MODULE;
-
- if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
- || machine_is_poodle()) {
- sharpsl_partitions[0].size=0x006d0000;
- sharpsl_partitions[0].offset=0x00120000;
- } else if (machine_is_tosa()) {
- sharpsl_partitions[0].size=0x006a0000;
- sharpsl_partitions[0].offset=0x00160000;
- } else if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi()) {
- sharpsl_partitions[0].size=0x006b0000;
- sharpsl_partitions[0].offset=0x00140000;
- } else {
- map_destroy(mymtd);
- iounmap(sharpsl_map.virt);
- return -ENODEV;
- }
-
- parts = sharpsl_partitions;
- nb_parts = ARRAY_SIZE(sharpsl_partitions);
-
- printk(KERN_NOTICE "Using %s partition definition\n", part_type);
- add_mtd_partitions(mymtd, parts, nb_parts);
-
- return 0;
-}
-
-static void __exit cleanup_sharpsl(void)
-{
- if (mymtd) {
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
- if (sharpsl_map.virt) {
- iounmap(sharpsl_map.virt);
- sharpsl_map.virt = 0;
- }
-}
-
-module_init(init_sharpsl);
-module_exit(cleanup_sharpsl);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("SHARP (Original: Arnold Christensen <AKC@pel.dk>)");
-MODULE_DESCRIPTION("MTD map driver for SHARP SL series");
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 1409f01406f..a49a9c8f2cb 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -286,6 +286,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
gd->private_data = new;
new->blkcore_priv = gd;
gd->queue = tr->blkcore_priv->rq;
+ gd->driverfs_dev = new->mtd->dev.parent;
if (new->readonly)
set_disk_ro(gd, 1);
@@ -382,11 +383,12 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread, tr,
"%sd", tr->name);
if (IS_ERR(tr->blkcore_priv->thread)) {
+ int ret = PTR_ERR(tr->blkcore_priv->thread);
blk_cleanup_queue(tr->blkcore_priv->rq);
unregister_blkdev(tr->major, tr->name);
kfree(tr->blkcore_priv);
mutex_unlock(&mtd_table_mutex);
- return PTR_ERR(tr->blkcore_priv->thread);
+ return ret;
}
INIT_LIST_HEAD(&tr->devs);
diff --git a/drivers/mtd/mtdbdi.c b/drivers/mtd/mtdbdi.c
new file mode 100644
index 00000000000..5ca5aed0b22
--- /dev/null
+++ b/drivers/mtd/mtdbdi.c
@@ -0,0 +1,43 @@
+/* MTD backing device capabilities
+ *
+ * Copyright © 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/backing-dev.h>
+#include <linux/mtd/mtd.h>
+#include "internal.h"
+
+/*
+ * backing device capabilities for non-mappable devices (such as NAND flash)
+ * - permits private mappings, copies are taken of the data
+ */
+struct backing_dev_info mtd_bdi_unmappable = {
+ .capabilities = BDI_CAP_MAP_COPY,
+};
+
+/*
+ * backing device capabilities for R/O mappable devices (such as ROM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_ro_mappable = {
+ .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+ BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
+};
+
+/*
+ * backing device capabilities for writable mappable devices (such as RAM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_rw_mappable = {
+ .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+ BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
+ BDI_CAP_WRITE_MAP),
+};
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index e9ec59e9a56..763d3f0a1f4 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -13,39 +13,13 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
+#include <linux/backing-dev.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/compatmac.h>
#include <asm/uaccess.h>
-static struct class *mtd_class;
-
-static void mtd_notify_add(struct mtd_info* mtd)
-{
- if (!mtd)
- return;
-
- device_create(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+1),
- NULL, "mtd%dro", mtd->index);
-}
-
-static void mtd_notify_remove(struct mtd_info* mtd)
-{
- if (!mtd)
- return;
-
- device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2));
- device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1));
-}
-
-static struct mtd_notifier notifier = {
- .add = mtd_notify_add,
- .remove = mtd_notify_remove,
-};
/*
* Data structure to hold the pointer to the mtd device as well
@@ -107,12 +81,15 @@ static int mtd_open(struct inode *inode, struct file *file)
goto out;
}
- if (MTD_ABSENT == mtd->type) {
+ if (mtd->type == MTD_ABSENT) {
put_mtd_device(mtd);
ret = -ENODEV;
goto out;
}
+ if (mtd->backing_dev_info)
+ file->f_mapping->backing_dev_info = mtd->backing_dev_info;
+
/* You can't open it RW if it's not a writeable device */
if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) {
put_mtd_device(mtd);
@@ -781,6 +758,59 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
return ret;
} /* memory_ioctl */
+/*
+ * try to determine where a shared mapping can be made
+ * - only supported for NOMMU at the moment (MMU can't doesn't copy private
+ * mappings)
+ */
+#ifndef CONFIG_MMU
+static unsigned long mtd_get_unmapped_area(struct file *file,
+ unsigned long addr,
+ unsigned long len,
+ unsigned long pgoff,
+ unsigned long flags)
+{
+ struct mtd_file_info *mfi = file->private_data;
+ struct mtd_info *mtd = mfi->mtd;
+
+ if (mtd->get_unmapped_area) {
+ unsigned long offset;
+
+ if (addr != 0)
+ return (unsigned long) -EINVAL;
+
+ if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT))
+ return (unsigned long) -EINVAL;
+
+ offset = pgoff << PAGE_SHIFT;
+ if (offset > mtd->size - len)
+ return (unsigned long) -EINVAL;
+
+ return mtd->get_unmapped_area(mtd, len, offset, flags);
+ }
+
+ /* can't map directly */
+ return (unsigned long) -ENOSYS;
+}
+#endif
+
+/*
+ * set up a mapping for shared memory segments
+ */
+static int mtd_mmap(struct file *file, struct vm_area_struct *vma)
+{
+#ifdef CONFIG_MMU
+ struct mtd_file_info *mfi = file->private_data;
+ struct mtd_info *mtd = mfi->mtd;
+
+ if (mtd->type == MTD_RAM || mtd->type == MTD_ROM)
+ return 0;
+ return -ENOSYS;
+#else
+ return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
+#endif
+}
+
static const struct file_operations mtd_fops = {
.owner = THIS_MODULE,
.llseek = mtd_lseek,
@@ -789,39 +819,36 @@ static const struct file_operations mtd_fops = {
.ioctl = mtd_ioctl,
.open = mtd_open,
.release = mtd_close,
+ .mmap = mtd_mmap,
+#ifndef CONFIG_MMU
+ .get_unmapped_area = mtd_get_unmapped_area,
+#endif
};
static int __init init_mtdchar(void)
{
- if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) {
+ int status;
+
+ status = register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops);
+ if (status < 0) {
printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
MTD_CHAR_MAJOR);
- return -EAGAIN;
}
- mtd_class = class_create(THIS_MODULE, "mtd");
-
- if (IS_ERR(mtd_class)) {
- printk(KERN_ERR "Error creating mtd class.\n");
- unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
- return PTR_ERR(mtd_class);
- }
-
- register_mtd_user(&notifier);
- return 0;
+ return status;
}
static void __exit cleanup_mtdchar(void)
{
- unregister_mtd_user(&notifier);
- class_destroy(mtd_class);
unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
}
module_init(init_mtdchar);
module_exit(cleanup_mtdchar);
+MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
MODULE_DESCRIPTION("Direct character-device access to MTD devices");
+MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 3dbb1b38db6..792b547786b 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -13,6 +13,7 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/types.h>
+#include <linux/backing-dev.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/concat.h>
@@ -684,6 +685,40 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
}
/*
+ * try to support NOMMU mmaps on concatenated devices
+ * - we don't support subdev spanning as we can't guarantee it'll work
+ */
+static unsigned long concat_get_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ struct mtd_concat *concat = CONCAT(mtd);
+ int i;
+
+ for (i = 0; i < concat->num_subdev; i++) {
+ struct mtd_info *subdev = concat->subdev[i];
+
+ if (offset >= subdev->size) {
+ offset -= subdev->size;
+ continue;
+ }
+
+ /* we've found the subdev over which the mapping will reside */
+ if (offset + len > subdev->size)
+ return (unsigned long) -EINVAL;
+
+ if (subdev->get_unmapped_area)
+ return subdev->get_unmapped_area(subdev, len, offset,
+ flags);
+
+ break;
+ }
+
+ return (unsigned long) -ENOSYS;
+}
+
+/*
* This function constructs a virtual MTD device by concatenating
* num_devs MTD devices. A pointer to the new device object is
* stored to *new_dev upon success. This function does _not_
@@ -740,6 +775,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks;
+ concat->mtd.backing_dev_info = subdev[0]->backing_dev_info;
+
concat->subdev[0] = subdev[0];
for (i = 1; i < num_devs; i++) {
@@ -766,6 +803,15 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat->mtd.flags |=
subdev[i]->flags & MTD_WRITEABLE;
}
+
+ /* only permit direct mapping if the BDIs are all the same
+ * - copy-mapping is still permitted
+ */
+ if (concat->mtd.backing_dev_info !=
+ subdev[i]->backing_dev_info)
+ concat->mtd.backing_dev_info =
+ &default_backing_dev_info;
+
concat->mtd.size += subdev[i]->size;
concat->mtd.ecc_stats.badblocks +=
subdev[i]->ecc_stats.badblocks;
@@ -796,6 +842,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat->mtd.unlock = concat_unlock;
concat->mtd.suspend = concat_suspend;
concat->mtd.resume = concat_resume;
+ concat->mtd.get_unmapped_area = concat_get_unmapped_area;
/*
* Combine the erase block size info of the subdevices:
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 76fe0a1e7a5..fdd6ae85939 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -19,9 +19,13 @@
#include <linux/proc_fs.h>
#include <linux/mtd/mtd.h>
+#include "internal.h"
#include "mtdcore.h"
+
+static struct class *mtd_class;
+
/* These are exported solely for the purpose of mtd_blkdevs.c. You
should not use them for _anything_ else */
DEFINE_MUTEX(mtd_table_mutex);
@@ -32,6 +36,160 @@ EXPORT_SYMBOL_GPL(mtd_table);
static LIST_HEAD(mtd_notifiers);
+
+#if defined(CONFIG_MTD_CHAR) || defined(CONFIG_MTD_CHAR_MODULE)
+#define MTD_DEVT(index) MKDEV(MTD_CHAR_MAJOR, (index)*2)
+#else
+#define MTD_DEVT(index) 0
+#endif
+
+/* REVISIT once MTD uses the driver model better, whoever allocates
+ * the mtd_info will probably want to use the release() hook...
+ */
+static void mtd_release(struct device *dev)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ /* remove /dev/mtdXro node if needed */
+ if (MTD_DEVT(mtd->index))
+ device_destroy(mtd_class, MTD_DEVT(mtd->index) + 1);
+}
+
+static ssize_t mtd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+ char *type;
+
+ switch (mtd->type) {
+ case MTD_ABSENT:
+ type = "absent";
+ break;
+ case MTD_RAM:
+ type = "ram";
+ break;
+ case MTD_ROM:
+ type = "rom";
+ break;
+ case MTD_NORFLASH:
+ type = "nor";
+ break;
+ case MTD_NANDFLASH:
+ type = "nand";
+ break;
+ case MTD_DATAFLASH:
+ type = "dataflash";
+ break;
+ case MTD_UBIVOLUME:
+ type = "ubi";
+ break;
+ default:
+ type = "unknown";
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", type);
+}
+static DEVICE_ATTR(type, S_IRUGO, mtd_type_show, NULL);
+
+static ssize_t mtd_flags_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)mtd->flags);
+
+}
+static DEVICE_ATTR(flags, S_IRUGO, mtd_flags_show, NULL);
+
+static ssize_t mtd_size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%llu\n",
+ (unsigned long long)mtd->size);
+
+}
+static DEVICE_ATTR(size, S_IRUGO, mtd_size_show, NULL);
+
+static ssize_t mtd_erasesize_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->erasesize);
+
+}
+static DEVICE_ATTR(erasesize, S_IRUGO, mtd_erasesize_show, NULL);
+
+static ssize_t mtd_writesize_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->writesize);
+
+}
+static DEVICE_ATTR(writesize, S_IRUGO, mtd_writesize_show, NULL);
+
+static ssize_t mtd_oobsize_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->oobsize);
+
+}
+static DEVICE_ATTR(oobsize, S_IRUGO, mtd_oobsize_show, NULL);
+
+static ssize_t mtd_numeraseregions_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", mtd->numeraseregions);
+
+}
+static DEVICE_ATTR(numeraseregions, S_IRUGO, mtd_numeraseregions_show,
+ NULL);
+
+static ssize_t mtd_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", mtd->name);
+
+}
+static DEVICE_ATTR(name, S_IRUGO, mtd_name_show, NULL);
+
+static struct attribute *mtd_attrs[] = {
+ &dev_attr_type.attr,
+ &dev_attr_flags.attr,
+ &dev_attr_size.attr,
+ &dev_attr_erasesize.attr,
+ &dev_attr_writesize.attr,
+ &dev_attr_oobsize.attr,
+ &dev_attr_numeraseregions.attr,
+ &dev_attr_name.attr,
+ NULL,
+};
+
+struct attribute_group mtd_group = {
+ .attrs = mtd_attrs,
+};
+
+struct attribute_group *mtd_groups[] = {
+ &mtd_group,
+ NULL,
+};
+
+static struct device_type mtd_devtype = {
+ .name = "mtd",
+ .groups = mtd_groups,
+ .release = mtd_release,
+};
+
/**
* add_mtd_device - register an MTD device
* @mtd: pointer to new MTD device info structure
@@ -40,12 +198,27 @@ static LIST_HEAD(mtd_notifiers);
* notify each currently active MTD 'user' of its arrival. Returns
* zero on success or 1 on failure, which currently will only happen
* if the number of present devices exceeds MAX_MTD_DEVICES (i.e. 16)
+ * or there's a sysfs error.
*/
int add_mtd_device(struct mtd_info *mtd)
{
int i;
+ if (!mtd->backing_dev_info) {
+ switch (mtd->type) {
+ case MTD_RAM:
+ mtd->backing_dev_info = &mtd_bdi_rw_mappable;
+ break;
+ case MTD_ROM:
+ mtd->backing_dev_info = &mtd_bdi_ro_mappable;
+ break;
+ default:
+ mtd->backing_dev_info = &mtd_bdi_unmappable;
+ break;
+ }
+ }
+
BUG_ON(mtd->writesize == 0);
mutex_lock(&mtd_table_mutex);
@@ -80,6 +253,23 @@ int add_mtd_device(struct mtd_info *mtd)
mtd->name);
}
+ /* Caller should have set dev.parent to match the
+ * physical device.
+ */
+ mtd->dev.type = &mtd_devtype;
+ mtd->dev.class = mtd_class;
+ mtd->dev.devt = MTD_DEVT(i);
+ dev_set_name(&mtd->dev, "mtd%d", i);
+ if (device_register(&mtd->dev) != 0) {
+ mtd_table[i] = NULL;
+ break;
+ }
+
+ if (MTD_DEVT(i))
+ device_create(mtd_class, mtd->dev.parent,
+ MTD_DEVT(i) + 1,
+ NULL, "mtd%dro", i);
+
DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name);
/* No need to get a refcount on the module containing
the notifier, since we hold the mtd_table_mutex */
@@ -124,6 +314,8 @@ int del_mtd_device (struct mtd_info *mtd)
} else {
struct mtd_notifier *not;
+ device_unregister(&mtd->dev);
+
/* No need to get a refcount on the module containing
the notifier, since we hold the mtd_table_mutex */
list_for_each_entry(not, &mtd_notifiers, list)
@@ -393,28 +585,38 @@ done:
return ((count < begin+len-off) ? count : begin+len-off);
}
+#endif /* CONFIG_PROC_FS */
+
/*====================================================================*/
/* Init code */
static int __init init_mtd(void)
{
+ mtd_class = class_create(THIS_MODULE, "mtd");
+
+ if (IS_ERR(mtd_class)) {
+ pr_err("Error creating mtd class.\n");
+ return PTR_ERR(mtd_class);
+ }
+#ifdef CONFIG_PROC_FS
if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
proc_mtd->read_proc = mtd_read_proc;
+#endif /* CONFIG_PROC_FS */
return 0;
}
static void __exit cleanup_mtd(void)
{
+#ifdef CONFIG_PROC_FS
if (proc_mtd)
remove_proc_entry( "mtd", NULL);
+#endif /* CONFIG_PROC_FS */
+ class_destroy(mtd_class);
}
module_init(init_mtd);
module_exit(cleanup_mtd);
-#endif /* CONFIG_PROC_FS */
-
-
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
MODULE_DESCRIPTION("Core MTD registration and access routines");
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 1a6b3beabe8..1060337c06d 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -44,6 +44,7 @@ static struct mtdoops_context {
int oops_pages;
int nextpage;
int nextcount;
+ char *name;
void *oops_buf;
@@ -273,6 +274,9 @@ static void mtdoops_notify_add(struct mtd_info *mtd)
{
struct mtdoops_context *cxt = &oops_cxt;
+ if (cxt->name && !strcmp(mtd->name, cxt->name))
+ cxt->mtd_index = mtd->index;
+
if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0)
return;
@@ -357,8 +361,10 @@ mtdoops_console_write(struct console *co, const char *s, unsigned int count)
spin_lock_irqsave(&cxt->writecount_lock, flags);
/* Check ready status didn't change whilst waiting for the lock */
- if (!cxt->ready)
+ if (!cxt->ready) {
+ spin_unlock_irqrestore(&cxt->writecount_lock, flags);
return;
+ }
if (cxt->writecount == 0) {
u32 *stamp = cxt->oops_buf;
@@ -383,8 +389,12 @@ static int __init mtdoops_console_setup(struct console *co, char *options)
{
struct mtdoops_context *cxt = co->data;
- if (cxt->mtd_index != -1)
+ if (cxt->mtd_index != -1 || cxt->name)
return -EBUSY;
+ if (options) {
+ cxt->name = kstrdup(options, GFP_KERNEL);
+ return 0;
+ }
if (co->index == -1)
return -EINVAL;
@@ -412,6 +422,7 @@ static int __init mtdoops_console_init(void)
cxt->mtd_index = -1;
cxt->oops_buf = vmalloc(OOPS_PAGE_SIZE);
+ spin_lock_init(&cxt->writecount_lock);
if (!cxt->oops_buf) {
printk(KERN_ERR "Failed to allocate mtdoops buffer workspace\n");
@@ -432,6 +443,7 @@ static void __exit mtdoops_console_exit(void)
unregister_mtd_user(&mtdoops_notifier);
unregister_console(&mtdoops_console);
+ kfree(cxt->name);
vfree(cxt->oops_buf);
}
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 144e6b613a7..29675edb44b 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -48,8 +48,11 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
struct mtd_part *part = PART(mtd);
+ struct mtd_ecc_stats stats;
int res;
+ stats = part->master->ecc_stats;
+
if (from >= mtd->size)
len = 0;
else if (from + len > mtd->size)
@@ -58,9 +61,9 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
len, retlen, buf);
if (unlikely(res)) {
if (res == -EUCLEAN)
- mtd->ecc_stats.corrected++;
+ mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected;
if (res == -EBADMSG)
- mtd->ecc_stats.failed++;
+ mtd->ecc_stats.failed += part->master->ecc_stats.failed - stats.failed;
}
return res;
}
@@ -84,6 +87,18 @@ static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
part->master->unpoint(part->master, from + part->offset, len);
}
+static unsigned long part_get_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ struct mtd_part *part = PART(mtd);
+
+ offset += part->offset;
+ return part->master->get_unmapped_area(part->master, len, offset,
+ flags);
+}
+
static int part_read_oob(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops)
{
@@ -342,6 +357,12 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
slave->mtd.name = part->name;
slave->mtd.owner = master->owner;
+ slave->mtd.backing_dev_info = master->backing_dev_info;
+
+ /* NOTE: we don't arrange MTDs as a tree; it'd be error-prone
+ * to have the same data be in two different partitions.
+ */
+ slave->mtd.dev.parent = master->dev.parent;
slave->mtd.read = part_read;
slave->mtd.write = part_write;
@@ -354,6 +375,8 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
slave->mtd.unpoint = part_unpoint;
}
+ if (master->get_unmapped_area)
+ slave->mtd.get_unmapped_area = part_get_unmapped_area;
if (master->read_oob)
slave->mtd.read_oob = part_read_oob;
if (master->write_oob)
@@ -493,7 +516,9 @@ out_register:
* This function, given a master MTD object and a partition table, creates
* and registers slave MTD objects which are bound to the master according to
* the partition definitions.
- * (Q: should we register the master MTD object as well?)
+ *
+ * We don't register the master, or expect the caller to have done so,
+ * for reasons of data integrity.
*/
int add_mtd_partitions(struct mtd_info *master,
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 2ff88791ceb..890936d0275 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -334,7 +334,7 @@ config MTD_NAND_ATMEL_ECC_NONE
endchoice
config MTD_NAND_PXA3xx
- bool "Support for NAND flash devices on PXA3xx"
+ tristate "Support for NAND flash devices on PXA3xx"
depends on MTD_NAND && PXA3xx
help
This enables the driver for the NAND flash device found on
@@ -427,4 +427,23 @@ config MTD_NAND_SH_FLCTL
Several Renesas SuperH CPU has FLCTL. This option enables support
for NAND Flash using FLCTL. This driver support SH7723.
+config MTD_NAND_DAVINCI
+ tristate "Support NAND on DaVinci SoC"
+ depends on ARCH_DAVINCI
+ help
+ Enable the driver for NAND flash chips on Texas Instruments
+ DaVinci processors.
+
+config MTD_NAND_TXX9NDFMC
+ tristate "NAND Flash support for TXx9 SoC"
+ depends on SOC_TX4938 || SOC_TX4939
+ help
+ This enables the NAND flash controller on the TXx9 SoCs.
+
+config MTD_NAND_SOCRATES
+ tristate "Support for NAND on Socrates board"
+ depends on MTD_NAND && SOCRATES
+ help
+ Enables support for NAND Flash chips wired onto Socrates board.
+
endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index b661586afbf..d33860ac42c 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o
obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o
obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o
+obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o
obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o
obj-$(CONFIG_MTD_NAND_H1900) += h1910.o
obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o
@@ -36,5 +37,7 @@ 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
+obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o
+obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o
nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c
index 9af2a2cc115..4c2a67ca801 100644
--- a/drivers/mtd/nand/bf5xx_nand.c
+++ b/drivers/mtd/nand/bf5xx_nand.c
@@ -552,7 +552,6 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd,
static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
{
int ret;
- unsigned short val;
/* Do not use dma */
if (!hardware_ecc)
@@ -560,13 +559,6 @@ static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
init_completion(&info->dma_completion);
-#ifdef CONFIG_BF54x
- /* Setup DMAC1 channel mux for NFC which shared with SDH */
- val = bfin_read_DMAC1_PERIMUX();
- val &= 0xFFFE;
- bfin_write_DMAC1_PERIMUX(val);
- SSYNC();
-#endif
/* Request NFC DMA channel */
ret = request_dma(CH_NFC, "BF5XX NFC driver");
if (ret < 0) {
@@ -574,7 +566,13 @@ static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
return ret;
}
- set_dma_callback(CH_NFC, (void *) bf5xx_nand_dma_irq, (void *) info);
+#ifdef CONFIG_BF54x
+ /* Setup DMAC1 channel mux for NFC which shared with SDH */
+ bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() & ~1);
+ SSYNC();
+#endif
+
+ set_dma_callback(CH_NFC, bf5xx_nand_dma_irq, info);
/* Turn off the DMA channel first */
disable_dma(CH_NFC);
@@ -632,7 +630,7 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info)
/*
* Device management interface
*/
-static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
+static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
{
struct mtd_info *mtd = &info->mtd;
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index 22a6b2e50e9..7c5b257ce8e 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -654,6 +654,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
}
cafe = (void *)(&mtd[1]);
+ mtd->dev.parent = &pdev->dev;
mtd->priv = cafe;
mtd->owner = THIS_MODULE;
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
new file mode 100644
index 00000000000..0119220de7d
--- /dev/null
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -0,0 +1,570 @@
+/*
+ * davinci_nand.c - NAND Flash Driver for DaVinci family chips
+ *
+ * Copyright © 2006 Texas Instruments.
+ *
+ * Port to 2.6.23 Copyright © 2008 by:
+ * Sander Huijsen <Shuijsen@optelecom-nkf.com>
+ * Troy Kisky <troy.kisky@boundarydevices.com>
+ * Dirk Behme <Dirk.Behme@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <mach/nand.h>
+
+#include <asm/mach-types.h>
+
+
+/*
+ * This is a device driver for the NAND flash controller found on the
+ * various DaVinci family chips. It handles up to four SoC chipselects,
+ * and some flavors of secondary chipselect (e.g. based on A12) as used
+ * with multichip packages.
+ *
+ * The 1-bit ECC hardware is supported, but not yet the newer 4-bit ECC
+ * available on chips like the DM355 and OMAP-L137 and needed with the
+ * more error-prone MLC NAND chips.
+ *
+ * This driver assumes EM_WAIT connects all the NAND devices' RDY/nBUSY
+ * outputs in a "wire-AND" configuration, with no per-chip signals.
+ */
+struct davinci_nand_info {
+ struct mtd_info mtd;
+ struct nand_chip chip;
+
+ struct device *dev;
+ struct clk *clk;
+ bool partitioned;
+
+ void __iomem *base;
+ void __iomem *vaddr;
+
+ uint32_t ioaddr;
+ uint32_t current_cs;
+
+ uint32_t mask_chipsel;
+ uint32_t mask_ale;
+ uint32_t mask_cle;
+
+ uint32_t core_chipsel;
+};
+
+static DEFINE_SPINLOCK(davinci_nand_lock);
+
+#define to_davinci_nand(m) container_of(m, struct davinci_nand_info, mtd)
+
+
+static inline unsigned int davinci_nand_readl(struct davinci_nand_info *info,
+ int offset)
+{
+ return __raw_readl(info->base + offset);
+}
+
+static inline void davinci_nand_writel(struct davinci_nand_info *info,
+ int offset, unsigned long value)
+{
+ __raw_writel(value, info->base + offset);
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Access to hardware control lines: ALE, CLE, secondary chipselect.
+ */
+
+static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct davinci_nand_info *info = to_davinci_nand(mtd);
+ uint32_t addr = info->current_cs;
+ struct nand_chip *nand = mtd->priv;
+
+ /* Did the control lines change? */
+ if (ctrl & NAND_CTRL_CHANGE) {
+ if ((ctrl & NAND_CTRL_CLE) == NAND_CTRL_CLE)
+ addr |= info->mask_cle;
+ else if ((ctrl & NAND_CTRL_ALE) == NAND_CTRL_ALE)
+ addr |= info->mask_ale;
+
+ nand->IO_ADDR_W = (void __iomem __force *)addr;
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ iowrite8(cmd, nand->IO_ADDR_W);
+}
+
+static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
+{
+ struct davinci_nand_info *info = to_davinci_nand(mtd);
+ uint32_t addr = info->ioaddr;
+
+ /* maybe kick in a second chipselect */
+ if (chip > 0)
+ addr |= info->mask_chipsel;
+ info->current_cs = addr;
+
+ info->chip.IO_ADDR_W = (void __iomem __force *)addr;
+ info->chip.IO_ADDR_R = info->chip.IO_ADDR_W;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * 1-bit hardware ECC ... context maintained for each core chipselect
+ */
+
+static inline uint32_t nand_davinci_readecc_1bit(struct mtd_info *mtd)
+{
+ struct davinci_nand_info *info = to_davinci_nand(mtd);
+
+ return davinci_nand_readl(info, NANDF1ECC_OFFSET
+ + 4 * info->core_chipsel);
+}
+
+static void nand_davinci_hwctl_1bit(struct mtd_info *mtd, int mode)
+{
+ struct davinci_nand_info *info;
+ uint32_t nandcfr;
+ unsigned long flags;
+
+ info = to_davinci_nand(mtd);
+
+ /* Reset ECC hardware */
+ nand_davinci_readecc_1bit(mtd);
+
+ spin_lock_irqsave(&davinci_nand_lock, flags);
+
+ /* Restart ECC hardware */
+ nandcfr = davinci_nand_readl(info, NANDFCR_OFFSET);
+ nandcfr |= BIT(8 + info->core_chipsel);
+ davinci_nand_writel(info, NANDFCR_OFFSET, nandcfr);
+
+ spin_unlock_irqrestore(&davinci_nand_lock, flags);
+}
+
+/*
+ * Read hardware ECC value and pack into three bytes
+ */
+static int nand_davinci_calculate_1bit(struct mtd_info *mtd,
+ const u_char *dat, u_char *ecc_code)
+{
+ unsigned int ecc_val = nand_davinci_readecc_1bit(mtd);
+ unsigned int ecc24 = (ecc_val & 0x0fff) | ((ecc_val & 0x0fff0000) >> 4);
+
+ /* invert so that erased block ecc is correct */
+ ecc24 = ~ecc24;
+ ecc_code[0] = (u_char)(ecc24);
+ ecc_code[1] = (u_char)(ecc24 >> 8);
+ ecc_code[2] = (u_char)(ecc24 >> 16);
+
+ return 0;
+}
+
+static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat,
+ u_char *read_ecc, u_char *calc_ecc)
+{
+ struct nand_chip *chip = mtd->priv;
+ uint32_t eccNand = read_ecc[0] | (read_ecc[1] << 8) |
+ (read_ecc[2] << 16);
+ uint32_t eccCalc = calc_ecc[0] | (calc_ecc[1] << 8) |
+ (calc_ecc[2] << 16);
+ uint32_t diff = eccCalc ^ eccNand;
+
+ if (diff) {
+ if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
+ /* Correctable error */
+ if ((diff >> (12 + 3)) < chip->ecc.size) {
+ dat[diff >> (12 + 3)] ^= BIT((diff >> 12) & 7);
+ return 1;
+ } else {
+ return -1;
+ }
+ } else if (!(diff & (diff - 1))) {
+ /* Single bit ECC error in the ECC itself,
+ * nothing to fix */
+ return 1;
+ } else {
+ /* Uncorrectable error */
+ return -1;
+ }
+
+ }
+ return 0;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * NOTE: NAND boot requires ALE == EM_A[1], CLE == EM_A[2], so that's
+ * how these chips are normally wired. This translates to both 8 and 16
+ * bit busses using ALE == BIT(3) in byte addresses, and CLE == BIT(4).
+ *
+ * For now we assume that configuration, or any other one which ignores
+ * the two LSBs for NAND access ... so we can issue 32-bit reads/writes
+ * and have that transparently morphed into multiple NAND operations.
+ */
+static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
+ ioread32_rep(chip->IO_ADDR_R, buf, len >> 2);
+ else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
+ ioread16_rep(chip->IO_ADDR_R, buf, len >> 1);
+ else
+ ioread8_rep(chip->IO_ADDR_R, buf, len);
+}
+
+static void nand_davinci_write_buf(struct mtd_info *mtd,
+ const uint8_t *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
+ iowrite32_rep(chip->IO_ADDR_R, buf, len >> 2);
+ else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
+ iowrite16_rep(chip->IO_ADDR_R, buf, len >> 1);
+ else
+ iowrite8_rep(chip->IO_ADDR_R, buf, len);
+}
+
+/*
+ * Check hardware register for wait status. Returns 1 if device is ready,
+ * 0 if it is still busy.
+ */
+static int nand_davinci_dev_ready(struct mtd_info *mtd)
+{
+ struct davinci_nand_info *info = to_davinci_nand(mtd);
+
+ return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0);
+}
+
+static void __init nand_dm6446evm_flash_init(struct davinci_nand_info *info)
+{
+ uint32_t regval, a1cr;
+
+ /*
+ * NAND FLASH timings @ PLL1 == 459 MHz
+ * - AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz
+ * - AEMIF.CLK period = 1/76.5 MHz = 13.1 ns
+ */
+ regval = 0
+ | (0 << 31) /* selectStrobe */
+ | (0 << 30) /* extWait (never with NAND) */
+ | (1 << 26) /* writeSetup 10 ns */
+ | (3 << 20) /* writeStrobe 40 ns */
+ | (1 << 17) /* writeHold 10 ns */
+ | (0 << 13) /* readSetup 10 ns */
+ | (3 << 7) /* readStrobe 60 ns */
+ | (0 << 4) /* readHold 10 ns */
+ | (3 << 2) /* turnAround ?? ns */
+ | (0 << 0) /* asyncSize 8-bit bus */
+ ;
+ a1cr = davinci_nand_readl(info, A1CR_OFFSET);
+ if (a1cr != regval) {
+ dev_dbg(info->dev, "Warning: NAND config: Set A1CR " \
+ "reg to 0x%08x, was 0x%08x, should be done by " \
+ "bootloader.\n", regval, a1cr);
+ davinci_nand_writel(info, A1CR_OFFSET, regval);
+ }
+}
+
+/*----------------------------------------------------------------------*/
+
+static int __init nand_davinci_probe(struct platform_device *pdev)
+{
+ struct davinci_nand_pdata *pdata = pdev->dev.platform_data;
+ struct davinci_nand_info *info;
+ struct resource *res1;
+ struct resource *res2;
+ void __iomem *vaddr;
+ void __iomem *base;
+ int ret;
+ uint32_t val;
+ nand_ecc_modes_t ecc_mode;
+
+ /* which external chipselect will we be managing? */
+ if (pdev->id < 0 || pdev->id > 3)
+ return -ENODEV;
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info) {
+ dev_err(&pdev->dev, "unable to allocate memory\n");
+ ret = -ENOMEM;
+ goto err_nomem;
+ }
+
+ platform_set_drvdata(pdev, info);
+
+ res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res1 || !res2) {
+ dev_err(&pdev->dev, "resource missing\n");
+ ret = -EINVAL;
+ goto err_nomem;
+ }
+
+ vaddr = ioremap(res1->start, res1->end - res1->start);
+ base = ioremap(res2->start, res2->end - res2->start);
+ if (!vaddr || !base) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -EINVAL;
+ goto err_ioremap;
+ }
+
+ info->dev = &pdev->dev;
+ info->base = base;
+ info->vaddr = vaddr;
+
+ info->mtd.priv = &info->chip;
+ info->mtd.name = dev_name(&pdev->dev);
+ info->mtd.owner = THIS_MODULE;
+
+ info->mtd.dev.parent = &pdev->dev;
+
+ info->chip.IO_ADDR_R = vaddr;
+ info->chip.IO_ADDR_W = vaddr;
+ info->chip.chip_delay = 0;
+ info->chip.select_chip = nand_davinci_select_chip;
+
+ /* options such as NAND_USE_FLASH_BBT or 16-bit widths */
+ info->chip.options = pdata ? pdata->options : 0;
+
+ info->ioaddr = (uint32_t __force) vaddr;
+
+ info->current_cs = info->ioaddr;
+ info->core_chipsel = pdev->id;
+ info->mask_chipsel = pdata->mask_chipsel;
+
+ /* use nandboot-capable ALE/CLE masks by default */
+ if (pdata && pdata->mask_ale)
+ info->mask_ale = pdata->mask_cle;
+ else
+ info->mask_ale = MASK_ALE;
+ if (pdata && pdata->mask_cle)
+ info->mask_cle = pdata->mask_cle;
+ else
+ info->mask_cle = MASK_CLE;
+
+ /* Set address of hardware control function */
+ info->chip.cmd_ctrl = nand_davinci_hwcontrol;
+ info->chip.dev_ready = nand_davinci_dev_ready;
+
+ /* Speed up buffer I/O */
+ info->chip.read_buf = nand_davinci_read_buf;
+ info->chip.write_buf = nand_davinci_write_buf;
+
+ /* use board-specific ECC config; else, the best available */
+ if (pdata)
+ ecc_mode = pdata->ecc_mode;
+ else
+ ecc_mode = NAND_ECC_HW;
+
+ switch (ecc_mode) {
+ case NAND_ECC_NONE:
+ case NAND_ECC_SOFT:
+ break;
+ case NAND_ECC_HW:
+ info->chip.ecc.calculate = nand_davinci_calculate_1bit;
+ info->chip.ecc.correct = nand_davinci_correct_1bit;
+ info->chip.ecc.hwctl = nand_davinci_hwctl_1bit;
+ info->chip.ecc.size = 512;
+ info->chip.ecc.bytes = 3;
+ break;
+ case NAND_ECC_HW_SYNDROME:
+ /* FIXME implement */
+ info->chip.ecc.size = 512;
+ info->chip.ecc.bytes = 10;
+
+ dev_warn(&pdev->dev, "4-bit ECC nyet supported\n");
+ /* FALL THROUGH */
+ default:
+ ret = -EINVAL;
+ goto err_ecc;
+ }
+ info->chip.ecc.mode = ecc_mode;
+
+ info->clk = clk_get(&pdev->dev, "AEMIFCLK");
+ if (IS_ERR(info->clk)) {
+ ret = PTR_ERR(info->clk);
+ dev_dbg(&pdev->dev, "unable to get AEMIFCLK, err %d\n", ret);
+ goto err_clk;
+ }
+
+ ret = clk_enable(info->clk);
+ if (ret < 0) {
+ dev_dbg(&pdev->dev, "unable to enable AEMIFCLK, err %d\n", ret);
+ goto err_clk_enable;
+ }
+
+ /* EMIF timings should normally be set by the boot loader,
+ * especially after boot-from-NAND. The *only* reason to
+ * have this special casing for the DM6446 EVM is to work
+ * with boot-from-NOR ... with CS0 manually re-jumpered
+ * (after startup) so it addresses the NAND flash, not NOR.
+ * Even for dev boards, that's unusually rude...
+ */
+ if (machine_is_davinci_evm())
+ nand_dm6446evm_flash_init(info);
+
+ spin_lock_irq(&davinci_nand_lock);
+
+ /* put CSxNAND into NAND mode */
+ val = davinci_nand_readl(info, NANDFCR_OFFSET);
+ val |= BIT(info->core_chipsel);
+ davinci_nand_writel(info, NANDFCR_OFFSET, val);
+
+ spin_unlock_irq(&davinci_nand_lock);
+
+ /* Scan to find existence of the device(s) */
+ ret = nand_scan(&info->mtd, pdata->mask_chipsel ? 2 : 1);
+ if (ret < 0) {
+ dev_dbg(&pdev->dev, "no NAND chip(s) found\n");
+ goto err_scan;
+ }
+
+ if (mtd_has_partitions()) {
+ struct mtd_partition *mtd_parts = NULL;
+ int mtd_parts_nb = 0;
+
+ if (mtd_has_cmdlinepart()) {
+ static const char *probes[] __initconst =
+ { "cmdlinepart", NULL };
+
+ const char *master_name;
+
+ /* Set info->mtd.name = 0 temporarily */
+ master_name = info->mtd.name;
+ info->mtd.name = (char *)0;
+
+ /* info->mtd.name == 0, means: don't bother checking
+ <mtd-id> */
+ mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes,
+ &mtd_parts, 0);
+
+ /* Restore info->mtd.name */
+ info->mtd.name = master_name;
+ }
+
+ if (mtd_parts_nb <= 0 && pdata) {
+ mtd_parts = pdata->parts;
+ mtd_parts_nb = pdata->nr_parts;
+ }
+
+ /* Register any partitions */
+ if (mtd_parts_nb > 0) {
+ ret = add_mtd_partitions(&info->mtd,
+ mtd_parts, mtd_parts_nb);
+ if (ret == 0)
+ info->partitioned = true;
+ }
+
+ } else if (pdata && pdata->nr_parts) {
+ dev_warn(&pdev->dev, "ignoring %d default partitions on %s\n",
+ pdata->nr_parts, info->mtd.name);
+ }
+
+ /* If there's no partition info, just package the whole chip
+ * as a single MTD device.
+ */
+ if (!info->partitioned)
+ ret = add_mtd_device(&info->mtd) ? -ENODEV : 0;
+
+ if (ret < 0)
+ goto err_scan;
+
+ val = davinci_nand_readl(info, NRCSR_OFFSET);
+ dev_info(&pdev->dev, "controller rev. %d.%d\n",
+ (val >> 8) & 0xff, val & 0xff);
+
+ return 0;
+
+err_scan:
+ clk_disable(info->clk);
+
+err_clk_enable:
+ clk_put(info->clk);
+
+err_ecc:
+err_clk:
+err_ioremap:
+ if (base)
+ iounmap(base);
+ if (vaddr)
+ iounmap(vaddr);
+
+err_nomem:
+ kfree(info);
+ return ret;
+}
+
+static int __exit nand_davinci_remove(struct platform_device *pdev)
+{
+ struct davinci_nand_info *info = platform_get_drvdata(pdev);
+ int status;
+
+ if (mtd_has_partitions() && info->partitioned)
+ status = del_mtd_partitions(&info->mtd);
+ else
+ status = del_mtd_device(&info->mtd);
+
+ iounmap(info->base);
+ iounmap(info->vaddr);
+
+ nand_release(&info->mtd);
+
+ clk_disable(info->clk);
+ clk_put(info->clk);
+
+ kfree(info);
+
+ return 0;
+}
+
+static struct platform_driver nand_davinci_driver = {
+ .remove = __exit_p(nand_davinci_remove),
+ .driver = {
+ .name = "davinci_nand",
+ },
+};
+MODULE_ALIAS("platform:davinci_nand");
+
+static int __init nand_davinci_init(void)
+{
+ return platform_driver_probe(&nand_davinci_driver, nand_davinci_probe);
+}
+module_init(nand_davinci_init);
+
+static void __exit nand_davinci_exit(void)
+{
+ platform_driver_unregister(&nand_davinci_driver);
+}
+module_exit(nand_davinci_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("Davinci NAND flash driver");
+
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index e4226e02d63..e51c1ed7ac1 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -1773,4 +1773,4 @@ module_exit(cleanup_nanddoc);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver\n");
+MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver");
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index 7815a404a63..d120cd8d726 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -23,6 +23,10 @@
#include <linux/io.h>
#include <asm/fsl_lbc.h>
+#define FSL_UPM_WAIT_RUN_PATTERN 0x1
+#define FSL_UPM_WAIT_WRITE_BYTE 0x2
+#define FSL_UPM_WAIT_WRITE_BUFFER 0x4
+
struct fsl_upm_nand {
struct device *dev;
struct mtd_info mtd;
@@ -36,8 +40,12 @@ struct fsl_upm_nand {
uint8_t upm_addr_offset;
uint8_t upm_cmd_offset;
void __iomem *io_base;
- int rnb_gpio;
+ int rnb_gpio[NAND_MAX_CHIPS];
+ uint32_t mchip_offsets[NAND_MAX_CHIPS];
+ uint32_t mchip_count;
+ uint32_t mchip_number;
int chip_delay;
+ uint32_t wait_flags;
};
#define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd)
@@ -46,7 +54,7 @@ static int fun_chip_ready(struct mtd_info *mtd)
{
struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
- if (gpio_get_value(fun->rnb_gpio))
+ if (gpio_get_value(fun->rnb_gpio[fun->mchip_number]))
return 1;
dev_vdbg(fun->dev, "busy\n");
@@ -55,9 +63,9 @@ static int fun_chip_ready(struct mtd_info *mtd)
static void fun_wait_rnb(struct fsl_upm_nand *fun)
{
- int cnt = 1000000;
+ if (fun->rnb_gpio[fun->mchip_number] >= 0) {
+ int cnt = 1000000;
- if (fun->rnb_gpio >= 0) {
while (--cnt && !fun_chip_ready(&fun->mtd))
cpu_relax();
if (!cnt)
@@ -69,7 +77,9 @@ static void fun_wait_rnb(struct fsl_upm_nand *fun)
static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
+ struct nand_chip *chip = mtd->priv;
struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
+ u32 mar;
if (!(ctrl & fun->last_ctrl)) {
fsl_upm_end_pattern(&fun->upm);
@@ -87,9 +97,28 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset);
}
- fsl_upm_run_pattern(&fun->upm, fun->io_base, cmd);
+ mar = (cmd << (32 - fun->upm.width)) |
+ fun->mchip_offsets[fun->mchip_number];
+ fsl_upm_run_pattern(&fun->upm, chip->IO_ADDR_R, mar);
+
+ if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN)
+ fun_wait_rnb(fun);
+}
+
+static void fun_select_chip(struct mtd_info *mtd, int mchip_nr)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
- fun_wait_rnb(fun);
+ if (mchip_nr == -1) {
+ chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
+ } else if (mchip_nr >= 0) {
+ fun->mchip_number = mchip_nr;
+ chip->IO_ADDR_R = fun->io_base + fun->mchip_offsets[mchip_nr];
+ chip->IO_ADDR_W = chip->IO_ADDR_R;
+ } else {
+ BUG();
+ }
}
static uint8_t fun_read_byte(struct mtd_info *mtd)
@@ -115,8 +144,11 @@ 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]);
- fun_wait_rnb(fun);
+ if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BYTE)
+ fun_wait_rnb(fun);
}
+ if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BUFFER)
+ fun_wait_rnb(fun);
}
static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
@@ -137,8 +169,10 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
fun->chip.read_buf = fun_read_buf;
fun->chip.write_buf = fun_write_buf;
fun->chip.ecc.mode = NAND_ECC_SOFT;
+ if (fun->mchip_count > 1)
+ fun->chip.select_chip = fun_select_chip;
- if (fun->rnb_gpio >= 0)
+ if (fun->rnb_gpio[0] >= 0)
fun->chip.dev_ready = fun_chip_ready;
fun->mtd.priv = &fun->chip;
@@ -155,7 +189,7 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
goto err;
}
- ret = nand_scan(&fun->mtd, 1);
+ ret = nand_scan(&fun->mtd, fun->mchip_count);
if (ret)
goto err;
@@ -185,8 +219,10 @@ static int __devinit fun_probe(struct of_device *ofdev,
struct fsl_upm_nand *fun;
struct resource io_res;
const uint32_t *prop;
+ int rnb_gpio;
int ret;
int size;
+ int i;
fun = kzalloc(sizeof(*fun), GFP_KERNEL);
if (!fun)
@@ -208,7 +244,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
if (!prop || size != sizeof(uint32_t)) {
dev_err(&ofdev->dev, "can't get UPM address offset\n");
ret = -EINVAL;
- goto err2;
+ goto err1;
}
fun->upm_addr_offset = *prop;
@@ -216,21 +252,40 @@ static int __devinit fun_probe(struct of_device *ofdev,
if (!prop || size != sizeof(uint32_t)) {
dev_err(&ofdev->dev, "can't get UPM command offset\n");
ret = -EINVAL;
- goto err2;
+ goto err1;
}
fun->upm_cmd_offset = *prop;
- fun->rnb_gpio = of_get_gpio(ofdev->node, 0);
- if (fun->rnb_gpio >= 0) {
- ret = gpio_request(fun->rnb_gpio, dev_name(&ofdev->dev));
- if (ret) {
- dev_err(&ofdev->dev, "can't request RNB gpio\n");
+ prop = of_get_property(ofdev->node,
+ "fsl,upm-addr-line-cs-offsets", &size);
+ if (prop && (size / sizeof(uint32_t)) > 0) {
+ fun->mchip_count = size / sizeof(uint32_t);
+ if (fun->mchip_count >= NAND_MAX_CHIPS) {
+ dev_err(&ofdev->dev, "too much multiple chips\n");
+ goto err1;
+ }
+ for (i = 0; i < fun->mchip_count; i++)
+ fun->mchip_offsets[i] = prop[i];
+ } else {
+ fun->mchip_count = 1;
+ }
+
+ for (i = 0; i < fun->mchip_count; i++) {
+ fun->rnb_gpio[i] = -1;
+ rnb_gpio = of_get_gpio(ofdev->node, i);
+ if (rnb_gpio >= 0) {
+ ret = gpio_request(rnb_gpio, dev_name(&ofdev->dev));
+ if (ret) {
+ dev_err(&ofdev->dev,
+ "can't request RNB gpio #%d\n", i);
+ goto err2;
+ }
+ gpio_direction_input(rnb_gpio);
+ fun->rnb_gpio[i] = rnb_gpio;
+ } else if (rnb_gpio == -EINVAL) {
+ dev_err(&ofdev->dev, "RNB gpio #%d is invalid\n", i);
goto err2;
}
- gpio_direction_input(fun->rnb_gpio);
- } else if (fun->rnb_gpio == -EINVAL) {
- dev_err(&ofdev->dev, "specified RNB gpio is invalid\n");
- goto err2;
}
prop = of_get_property(ofdev->node, "chip-delay", NULL);
@@ -239,8 +294,15 @@ static int __devinit fun_probe(struct of_device *ofdev,
else
fun->chip_delay = 50;
+ prop = of_get_property(ofdev->node, "fsl,upm-wait-flags", &size);
+ if (prop && size == sizeof(uint32_t))
+ fun->wait_flags = *prop;
+ else
+ fun->wait_flags = FSL_UPM_WAIT_RUN_PATTERN |
+ FSL_UPM_WAIT_WRITE_BYTE;
+
fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start,
- io_res.end - io_res.start + 1);
+ io_res.end - io_res.start + 1);
if (!fun->io_base) {
ret = -ENOMEM;
goto err2;
@@ -257,8 +319,11 @@ static int __devinit fun_probe(struct of_device *ofdev,
return 0;
err2:
- if (fun->rnb_gpio >= 0)
- gpio_free(fun->rnb_gpio);
+ for (i = 0; i < fun->mchip_count; i++) {
+ if (fun->rnb_gpio[i] < 0)
+ break;
+ gpio_free(fun->rnb_gpio[i]);
+ }
err1:
kfree(fun);
@@ -268,12 +333,16 @@ err1:
static int __devexit fun_remove(struct of_device *ofdev)
{
struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev);
+ int i;
nand_release(&fun->mtd);
kfree(fun->mtd.name);
- if (fun->rnb_gpio >= 0)
- gpio_free(fun->rnb_gpio);
+ for (i = 0; i < fun->mchip_count; i++) {
+ if (fun->rnb_gpio[i] < 0)
+ break;
+ gpio_free(fun->rnb_gpio[i]);
+ }
kfree(fun);
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index bad048aca89..f3548d04801 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -866,6 +866,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
mtd = &host->mtd;
mtd->priv = this;
mtd->owner = THIS_MODULE;
+ mtd->dev.parent = &pdev->dev;
/* 50 us command delay time */
this->chip_delay = 5;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 0c3afccde8a..3d7ed432fa4 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -82,6 +82,20 @@ static struct nand_ecclayout nand_oob_64 = {
.length = 38}}
};
+static struct nand_ecclayout nand_oob_128 = {
+ .eccbytes = 48,
+ .eccpos = {
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127},
+ .oobfree = {
+ {.offset = 2,
+ .length = 78}}
+};
+
static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
int new_state);
@@ -748,6 +762,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ *
+ * Not for syndrome calculating ecc controllers, which use a special oob layout
*/
static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *buf)
@@ -758,6 +774,47 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
}
/**
+ * nand_read_page_raw_syndrome - [Intern] read raw page data without ecc
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ *
+ * We need a special oob layout and handling even when OOB isn't used.
+ */
+static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+ uint8_t *buf)
+{
+ int eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ uint8_t *oob = chip->oob_poi;
+ int steps, size;
+
+ for (steps = chip->ecc.steps; steps > 0; steps--) {
+ chip->read_buf(mtd, buf, eccsize);
+ buf += eccsize;
+
+ if (chip->ecc.prepad) {
+ chip->read_buf(mtd, oob, chip->ecc.prepad);
+ oob += chip->ecc.prepad;
+ }
+
+ chip->read_buf(mtd, oob, eccbytes);
+ oob += eccbytes;
+
+ if (chip->ecc.postpad) {
+ chip->read_buf(mtd, oob, chip->ecc.postpad);
+ oob += chip->ecc.postpad;
+ }
+ }
+
+ size = mtd->oobsize - (oob - chip->oob_poi);
+ if (size)
+ chip->read_buf(mtd, oob, size);
+
+ return 0;
+}
+
+/**
* nand_read_page_swecc - [REPLACABLE] software ecc based page read function
* @mtd: mtd info structure
* @chip: nand chip info structure
@@ -1482,6 +1539,8 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: data buffer
+ *
+ * Not for syndrome calculating ecc controllers, which use a special oob layout
*/
static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf)
@@ -1491,6 +1550,44 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
}
/**
+ * nand_write_page_raw_syndrome - [Intern] raw page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
+ *
+ * We need a special oob layout and handling even when ECC isn't checked.
+ */
+static void nand_write_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+ const uint8_t *buf)
+{
+ int eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ uint8_t *oob = chip->oob_poi;
+ int steps, size;
+
+ for (steps = chip->ecc.steps; steps > 0; steps--) {
+ chip->write_buf(mtd, buf, eccsize);
+ buf += eccsize;
+
+ if (chip->ecc.prepad) {
+ chip->write_buf(mtd, oob, chip->ecc.prepad);
+ oob += chip->ecc.prepad;
+ }
+
+ chip->read_buf(mtd, oob, eccbytes);
+ oob += eccbytes;
+
+ if (chip->ecc.postpad) {
+ chip->write_buf(mtd, oob, chip->ecc.postpad);
+ oob += chip->ecc.postpad;
+ }
+ }
+
+ size = mtd->oobsize - (oob - chip->oob_poi);
+ if (size)
+ chip->write_buf(mtd, oob, size);
+}
+/**
* nand_write_page_swecc - [REPLACABLE] software ecc based page write function
* @mtd: mtd info structure
* @chip: nand chip info structure
@@ -1863,7 +1960,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
}
if (unlikely(ops->ooboffs >= len)) {
- DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+ DEBUG(MTD_DEBUG_LEVEL0, "nand_do_write_oob: "
"Attempt to start write outside oob\n");
return -EINVAL;
}
@@ -1873,7 +1970,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
ops->ooboffs + ops->ooblen >
((mtd->size >> chip->page_shift) -
(to >> chip->page_shift)) * len)) {
- DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+ DEBUG(MTD_DEBUG_LEVEL0, "nand_do_write_oob: "
"Attempt write beyond end of device\n");
return -EINVAL;
}
@@ -1929,8 +2026,8 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
/* Do not allow writes past end of device */
if (ops->datbuf && (to + ops->len) > mtd->size) {
- DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
- "Attempt read beyond end of device\n");
+ DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
+ "Attempt write beyond end of device\n");
return -EINVAL;
}
@@ -2555,6 +2652,9 @@ int nand_scan_tail(struct mtd_info *mtd)
case 64:
chip->ecc.layout = &nand_oob_64;
break;
+ case 128:
+ chip->ecc.layout = &nand_oob_128;
+ break;
default:
printk(KERN_WARNING "No oob scheme defined for "
"oobsize %d\n", mtd->oobsize);
@@ -2569,10 +2669,6 @@ int nand_scan_tail(struct mtd_info *mtd)
* check ECC mode, default to software if 3byte/512byte hardware ECC is
* selected and we have 256 byte pagesize fallback to software ECC
*/
- if (!chip->ecc.read_page_raw)
- chip->ecc.read_page_raw = nand_read_page_raw;
- if (!chip->ecc.write_page_raw)
- chip->ecc.write_page_raw = nand_write_page_raw;
switch (chip->ecc.mode) {
case NAND_ECC_HW:
@@ -2581,6 +2677,10 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.read_page = nand_read_page_hwecc;
if (!chip->ecc.write_page)
chip->ecc.write_page = nand_write_page_hwecc;
+ if (!chip->ecc.read_page_raw)
+ chip->ecc.read_page_raw = nand_read_page_raw;
+ if (!chip->ecc.write_page_raw)
+ chip->ecc.write_page_raw = nand_write_page_raw;
if (!chip->ecc.read_oob)
chip->ecc.read_oob = nand_read_oob_std;
if (!chip->ecc.write_oob)
@@ -2602,6 +2702,10 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.read_page = nand_read_page_syndrome;
if (!chip->ecc.write_page)
chip->ecc.write_page = nand_write_page_syndrome;
+ if (!chip->ecc.read_page_raw)
+ chip->ecc.read_page_raw = nand_read_page_raw_syndrome;
+ if (!chip->ecc.write_page_raw)
+ chip->ecc.write_page_raw = nand_write_page_raw_syndrome;
if (!chip->ecc.read_oob)
chip->ecc.read_oob = nand_read_oob_syndrome;
if (!chip->ecc.write_oob)
@@ -2620,6 +2724,8 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.read_page = nand_read_page_swecc;
chip->ecc.read_subpage = nand_read_subpage;
chip->ecc.write_page = nand_write_page_swecc;
+ chip->ecc.read_page_raw = nand_read_page_raw;
+ chip->ecc.write_page_raw = nand_write_page_raw;
chip->ecc.read_oob = nand_read_oob_std;
chip->ecc.write_oob = nand_write_oob_std;
chip->ecc.size = 256;
@@ -2632,6 +2738,8 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.read_page = nand_read_page_raw;
chip->ecc.write_page = nand_write_page_raw;
chip->ecc.read_oob = nand_read_oob_std;
+ chip->ecc.read_page_raw = nand_read_page_raw;
+ chip->ecc.write_page_raw = nand_write_page_raw;
chip->ecc.write_oob = nand_write_oob_std;
chip->ecc.size = mtd->writesize;
chip->ecc.bytes = 0;
@@ -2676,6 +2784,7 @@ int nand_scan_tail(struct mtd_info *mtd)
break;
case 4:
case 8:
+ case 16:
mtd->subpage_sft = 2;
break;
}
@@ -2720,14 +2829,14 @@ int nand_scan_tail(struct mtd_info *mtd)
return chip->scan_bbt(mtd);
}
-/* module_text_address() isn't exported, and it's mostly a pointless
+/* is_module_text_address() isn't exported, and it's mostly a pointless
test if this is a module _anyway_ -- they'd have to try _really_ hard
to call us from in-kernel code if the core NAND support is modular. */
#ifdef MODULE
#define caller_is_module() (1)
#else
#define caller_is_module() \
- module_text_address((unsigned long)__builtin_return_address(0))
+ is_module_text_address((unsigned long)__builtin_return_address(0))
#endif
/**
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c
index 75f9f4874ec..86e1d08eee0 100644
--- a/drivers/mtd/nand/plat_nand.c
+++ b/drivers/mtd/nand/plat_nand.c
@@ -30,7 +30,7 @@ struct plat_nand_data {
/*
* Probe for the NAND device.
*/
-static int __init plat_nand_probe(struct platform_device *pdev)
+static int __devinit plat_nand_probe(struct platform_device *pdev)
{
struct platform_nand_data *pdata = pdev->dev.platform_data;
struct plat_nand_data *data;
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 61b69cc4000..30a8ce6d3e6 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -170,7 +170,13 @@ 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
+/*
+ * Default NAND flash controller configuration setup by the
+ * bootloader. This configuration is used only when pdata->keep_config is set
+ */
+static struct pxa3xx_nand_timing default_timing;
+static struct pxa3xx_nand_flash default_flash;
+
static struct pxa3xx_nand_cmdset smallpage_cmdset = {
.read1 = 0x0000,
.read2 = 0x0050,
@@ -197,6 +203,7 @@ static struct pxa3xx_nand_cmdset largepage_cmdset = {
.lock_status = 0x007A,
};
+#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN
static struct pxa3xx_nand_timing samsung512MbX16_timing = {
.tCH = 10,
.tCS = 0,
@@ -296,9 +303,23 @@ static struct pxa3xx_nand_flash *builtin_flash_types[] = {
#define NDTR1_tWHR(c) (min((c), 15) << 4)
#define NDTR1_tAR(c) (min((c), 15) << 0)
+#define tCH_NDTR0(r) (((r) >> 19) & 0x7)
+#define tCS_NDTR0(r) (((r) >> 16) & 0x7)
+#define tWH_NDTR0(r) (((r) >> 11) & 0x7)
+#define tWP_NDTR0(r) (((r) >> 8) & 0x7)
+#define tRH_NDTR0(r) (((r) >> 3) & 0x7)
+#define tRP_NDTR0(r) (((r) >> 0) & 0x7)
+
+#define tR_NDTR1(r) (((r) >> 16) & 0xffff)
+#define tWHR_NDTR1(r) (((r) >> 4) & 0xf)
+#define tAR_NDTR1(r) (((r) >> 0) & 0xf)
+
/* convert nano-seconds to nand flash controller clock cycles */
#define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) - 1)
+/* convert nand flash controller clock cycles to nano-seconds */
+#define cycle2ns(c, clk) ((((c) + 1) * 1000000 + clk / 500) / (clk / 1000))
+
static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
const struct pxa3xx_nand_timing *t)
{
@@ -920,6 +941,82 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
return 0;
}
+static void pxa3xx_nand_detect_timing(struct pxa3xx_nand_info *info,
+ struct pxa3xx_nand_timing *t)
+{
+ unsigned long nand_clk = clk_get_rate(info->clk);
+ uint32_t ndtr0 = nand_readl(info, NDTR0CS0);
+ uint32_t ndtr1 = nand_readl(info, NDTR1CS0);
+
+ t->tCH = cycle2ns(tCH_NDTR0(ndtr0), nand_clk);
+ t->tCS = cycle2ns(tCS_NDTR0(ndtr0), nand_clk);
+ t->tWH = cycle2ns(tWH_NDTR0(ndtr0), nand_clk);
+ t->tWP = cycle2ns(tWP_NDTR0(ndtr0), nand_clk);
+ t->tRH = cycle2ns(tRH_NDTR0(ndtr0), nand_clk);
+ t->tRP = cycle2ns(tRP_NDTR0(ndtr0), nand_clk);
+
+ t->tR = cycle2ns(tR_NDTR1(ndtr1), nand_clk);
+ t->tWHR = cycle2ns(tWHR_NDTR1(ndtr1), nand_clk);
+ t->tAR = cycle2ns(tAR_NDTR1(ndtr1), nand_clk);
+}
+
+static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
+{
+ uint32_t ndcr = nand_readl(info, NDCR);
+ struct nand_flash_dev *type = NULL;
+ uint32_t id = -1;
+ int i;
+
+ default_flash.page_per_block = ndcr & NDCR_PG_PER_BLK ? 64 : 32;
+ default_flash.page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
+ default_flash.flash_width = ndcr & NDCR_DWIDTH_M ? 16 : 8;
+ default_flash.dfc_width = ndcr & NDCR_DWIDTH_C ? 16 : 8;
+
+ if (default_flash.page_size == 2048)
+ default_flash.cmdset = &largepage_cmdset;
+ else
+ default_flash.cmdset = &smallpage_cmdset;
+
+ /* set info fields needed to __readid */
+ info->flash_info = &default_flash;
+ info->read_id_bytes = (default_flash.page_size == 2048) ? 4 : 2;
+ info->reg_ndcr = ndcr;
+
+ if (__readid(info, &id))
+ return -ENODEV;
+
+ /* Lookup the flash id */
+ id = (id >> 8) & 0xff; /* device id is byte 2 */
+ for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+ if (id == nand_flash_ids[i].id) {
+ type = &nand_flash_ids[i];
+ break;
+ }
+ }
+
+ if (!type)
+ return -ENODEV;
+
+ /* fill the missing flash information */
+ i = __ffs(default_flash.page_per_block * default_flash.page_size);
+ default_flash.num_blocks = type->chipsize << (20 - i);
+
+ info->oob_size = (default_flash.page_size == 2048) ? 64 : 16;
+
+ /* calculate addressing information */
+ info->col_addr_cycles = (default_flash.page_size == 2048) ? 2 : 1;
+
+ if (default_flash.num_blocks * default_flash.page_per_block > 65536)
+ info->row_addr_cycles = 3;
+ else
+ info->row_addr_cycles = 2;
+
+ pxa3xx_nand_detect_timing(info, &default_timing);
+ default_flash.timing = &default_timing;
+
+ return 0;
+}
+
static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info,
const struct pxa3xx_nand_platform_data *pdata)
{
@@ -927,6 +1024,10 @@ static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info,
uint32_t id = -1;
int i;
+ if (pdata->keep_config)
+ if (pxa3xx_nand_detect_config(info) == 0)
+ return 0;
+
for (i = 0; i<pdata->num_flash; ++i) {
f = pdata->flash + i;
@@ -1078,6 +1179,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
this = &info->nand_chip;
mtd->priv = info;
+ mtd->owner = THIS_MODULE;
info->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(info->clk)) {
@@ -1117,14 +1219,14 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
goto fail_put_clk;
}
- r = request_mem_region(r->start, r->end - r->start + 1, pdev->name);
+ r = request_mem_region(r->start, resource_size(r), pdev->name);
if (r == NULL) {
dev_err(&pdev->dev, "failed to request memory resource\n");
ret = -EBUSY;
goto fail_put_clk;
}
- info->mmio_base = ioremap(r->start, r->end - r->start + 1);
+ info->mmio_base = ioremap(r->start, resource_size(r));
if (info->mmio_base == NULL) {
dev_err(&pdev->dev, "ioremap() failed\n");
ret = -ENODEV;
@@ -1173,7 +1275,7 @@ fail_free_buf:
fail_free_io:
iounmap(info->mmio_base);
fail_free_res:
- release_mem_region(r->start, r->end - r->start + 1);
+ release_mem_region(r->start, resource_size(r));
fail_put_clk:
clk_disable(info->clk);
clk_put(info->clk);
@@ -1186,6 +1288,7 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
{
struct mtd_info *mtd = platform_get_drvdata(pdev);
struct pxa3xx_nand_info *info = mtd->priv;
+ struct resource *r;
platform_set_drvdata(pdev, NULL);
@@ -1198,6 +1301,14 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
info->data_buff, info->data_buff_phys);
} else
kfree(info->data_buff);
+
+ iounmap(info->mmio_base);
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(r->start, resource_size(r));
+
+ clk_disable(info->clk);
+ clk_put(info->clk);
+
kfree(mtd);
return 0;
}
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 821acb08ff1..2bc896623e2 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -58,7 +58,7 @@ static struct nand_bbt_descr flctl_4secc_smallpage = {
};
static struct nand_bbt_descr flctl_4secc_largepage = {
- .options = 0,
+ .options = NAND_BBT_SCAN2NDPAGE,
.offs = 58,
.len = 2,
.pattern = scan_ff_pattern,
@@ -149,7 +149,7 @@ static void wait_wfifo_ready(struct sh_flctl *flctl)
printk(KERN_ERR "wait_wfifo_ready(): Timeout occured \n");
}
-static int wait_recfifo_ready(struct sh_flctl *flctl)
+static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
{
uint32_t timeout = LOOP_TIMEOUT_MAX;
int checked[4];
@@ -183,7 +183,12 @@ static int wait_recfifo_ready(struct sh_flctl *flctl)
uint8_t org;
int index;
- index = data >> 16;
+ if (flctl->page_size)
+ index = (512 * sector_number) +
+ (data >> 16);
+ else
+ index = data >> 16;
+
org = flctl->done_buff[index];
flctl->done_buff[index] = org ^ (data & 0xFF);
checked[i] = 1;
@@ -238,14 +243,14 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
}
}
-static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff)
+static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff, int sector)
{
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))
+ if (wait_recfifo_ready(flctl , sector))
return 1;
ecc_buf[i] = readl(fifo_addr);
ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
@@ -384,7 +389,8 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
read_fiforeg(flctl, 512, 512 * sector);
ret = read_ecfiforeg(flctl,
- &flctl->done_buff[mtd->writesize + 16 * sector]);
+ &flctl->done_buff[mtd->writesize + 16 * sector],
+ sector);
if (ret)
flctl->hwecc_cant_correct[sector] = 1;
diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c
new file mode 100644
index 00000000000..a4519a7bd68
--- /dev/null
+++ b/drivers/mtd/nand/socrates_nand.c
@@ -0,0 +1,325 @@
+/*
+ * drivers/mtd/nand/socrates_nand.c
+ *
+ * Copyright © 2008 Ilya Yanok, Emcraft Systems
+ *
+ *
+ * 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/slab.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+
+#define FPGA_NAND_CMD_MASK (0x7 << 28)
+#define FPGA_NAND_CMD_COMMAND (0x0 << 28)
+#define FPGA_NAND_CMD_ADDR (0x1 << 28)
+#define FPGA_NAND_CMD_READ (0x2 << 28)
+#define FPGA_NAND_CMD_WRITE (0x3 << 28)
+#define FPGA_NAND_BUSY (0x1 << 15)
+#define FPGA_NAND_ENABLE (0x1 << 31)
+#define FPGA_NAND_DATA_SHIFT 16
+
+struct socrates_nand_host {
+ struct nand_chip nand_chip;
+ struct mtd_info mtd;
+ void __iomem *io_base;
+ struct device *dev;
+};
+
+/**
+ * socrates_nand_write_buf - write buffer to chip
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
+ */
+static void socrates_nand_write_buf(struct mtd_info *mtd,
+ const uint8_t *buf, int len)
+{
+ int i;
+ struct nand_chip *this = mtd->priv;
+ struct socrates_nand_host *host = this->priv;
+
+ for (i = 0; i < len; i++) {
+ out_be32(host->io_base, FPGA_NAND_ENABLE |
+ FPGA_NAND_CMD_WRITE |
+ (buf[i] << FPGA_NAND_DATA_SHIFT));
+ }
+}
+
+/**
+ * socrates_nand_read_buf - read chip data into buffer
+ * @mtd: MTD device structure
+ * @buf: buffer to store date
+ * @len: number of bytes to read
+ */
+static void socrates_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ int i;
+ struct nand_chip *this = mtd->priv;
+ struct socrates_nand_host *host = this->priv;
+ uint32_t val;
+
+ val = FPGA_NAND_ENABLE | FPGA_NAND_CMD_READ;
+
+ out_be32(host->io_base, val);
+ for (i = 0; i < len; i++) {
+ buf[i] = (in_be32(host->io_base) >>
+ FPGA_NAND_DATA_SHIFT) & 0xff;
+ }
+}
+
+/**
+ * socrates_nand_read_byte - read one byte from the chip
+ * @mtd: MTD device structure
+ */
+static uint8_t socrates_nand_read_byte(struct mtd_info *mtd)
+{
+ uint8_t byte;
+ socrates_nand_read_buf(mtd, &byte, sizeof(byte));
+ return byte;
+}
+
+/**
+ * socrates_nand_read_word - read one word from the chip
+ * @mtd: MTD device structure
+ */
+static uint16_t socrates_nand_read_word(struct mtd_info *mtd)
+{
+ uint16_t word;
+ socrates_nand_read_buf(mtd, (uint8_t *)&word, sizeof(word));
+ return word;
+}
+
+/**
+ * socrates_nand_verify_buf - Verify chip data against buffer
+ * @mtd: MTD device structure
+ * @buf: buffer containing the data to compare
+ * @len: number of bytes to compare
+ */
+static int socrates_nand_verify_buf(struct mtd_info *mtd, const u8 *buf,
+ int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (buf[i] != socrates_nand_read_byte(mtd))
+ return -EFAULT;
+ }
+ return 0;
+}
+
+/*
+ * Hardware specific access to control-lines
+ */
+static void socrates_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct socrates_nand_host *host = nand_chip->priv;
+ uint32_t val;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ if (ctrl & NAND_CLE)
+ val = FPGA_NAND_CMD_COMMAND;
+ else
+ val = FPGA_NAND_CMD_ADDR;
+
+ if (ctrl & NAND_NCE)
+ val |= FPGA_NAND_ENABLE;
+
+ val |= (cmd & 0xff) << FPGA_NAND_DATA_SHIFT;
+
+ out_be32(host->io_base, val);
+}
+
+/*
+ * Read the Device Ready pin.
+ */
+static int socrates_nand_device_ready(struct mtd_info *mtd)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct socrates_nand_host *host = nand_chip->priv;
+
+ if (in_be32(host->io_base) & FPGA_NAND_BUSY)
+ return 0; /* busy */
+ return 1;
+}
+
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probes[] = { "cmdlinepart", NULL };
+#endif
+
+/*
+ * Probe for the NAND device.
+ */
+static int __devinit socrates_nand_probe(struct of_device *ofdev,
+ const struct of_device_id *ofid)
+{
+ struct socrates_nand_host *host;
+ struct mtd_info *mtd;
+ struct nand_chip *nand_chip;
+ int res;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ struct mtd_partition *partitions = NULL;
+ int num_partitions = 0;
+#endif
+
+ /* Allocate memory for the device structure (and zero it) */
+ host = kzalloc(sizeof(struct socrates_nand_host), GFP_KERNEL);
+ if (!host) {
+ printk(KERN_ERR
+ "socrates_nand: failed to allocate device structure.\n");
+ return -ENOMEM;
+ }
+
+ host->io_base = of_iomap(ofdev->node, 0);
+ if (host->io_base == NULL) {
+ printk(KERN_ERR "socrates_nand: ioremap failed\n");
+ kfree(host);
+ return -EIO;
+ }
+
+ mtd = &host->mtd;
+ nand_chip = &host->nand_chip;
+ host->dev = &ofdev->dev;
+
+ nand_chip->priv = host; /* link the private data structures */
+ mtd->priv = nand_chip;
+ mtd->name = "socrates_nand";
+ mtd->owner = THIS_MODULE;
+ mtd->dev.parent = &ofdev->dev;
+
+ /*should never be accessed directly */
+ nand_chip->IO_ADDR_R = (void *)0xdeadbeef;
+ nand_chip->IO_ADDR_W = (void *)0xdeadbeef;
+
+ nand_chip->cmd_ctrl = socrates_nand_cmd_ctrl;
+ nand_chip->read_byte = socrates_nand_read_byte;
+ nand_chip->read_word = socrates_nand_read_word;
+ nand_chip->write_buf = socrates_nand_write_buf;
+ nand_chip->read_buf = socrates_nand_read_buf;
+ nand_chip->verify_buf = socrates_nand_verify_buf;
+ nand_chip->dev_ready = socrates_nand_device_ready;
+
+ nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */
+
+ /* TODO: I have no idea what real delay is. */
+ nand_chip->chip_delay = 20; /* 20us command delay time */
+
+ dev_set_drvdata(&ofdev->dev, host);
+
+ /* first scan to find the device and get the page size */
+ if (nand_scan_ident(mtd, 1)) {
+ res = -ENXIO;
+ goto out;
+ }
+
+ /* second phase scan */
+ if (nand_scan_tail(mtd)) {
+ res = -ENXIO;
+ goto out;
+ }
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+ num_partitions = parse_mtd_partitions(mtd, part_probes,
+ &partitions, 0);
+ if (num_partitions < 0) {
+ res = num_partitions;
+ goto release;
+ }
+#endif
+
+#ifdef CONFIG_MTD_OF_PARTS
+ if (num_partitions == 0) {
+ num_partitions = of_mtd_parse_partitions(&ofdev->dev,
+ ofdev->node,
+ &partitions);
+ if (num_partitions < 0) {
+ res = num_partitions;
+ goto release;
+ }
+ }
+#endif
+ if (partitions && (num_partitions > 0))
+ res = add_mtd_partitions(mtd, partitions, num_partitions);
+ else
+#endif
+ res = add_mtd_device(mtd);
+
+ if (!res)
+ return res;
+
+#ifdef CONFIG_MTD_PARTITIONS
+release:
+#endif
+ nand_release(mtd);
+
+out:
+ dev_set_drvdata(&ofdev->dev, NULL);
+ iounmap(host->io_base);
+ kfree(host);
+ return res;
+}
+
+/*
+ * Remove a NAND device.
+ */
+static int __devexit socrates_nand_remove(struct of_device *ofdev)
+{
+ struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev);
+ struct mtd_info *mtd = &host->mtd;
+
+ nand_release(mtd);
+
+ dev_set_drvdata(&ofdev->dev, NULL);
+ iounmap(host->io_base);
+ kfree(host);
+
+ return 0;
+}
+
+static struct of_device_id socrates_nand_match[] =
+{
+ {
+ .compatible = "abb,socrates-nand",
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, socrates_nand_match);
+
+static struct of_platform_driver socrates_nand_driver = {
+ .name = "socrates_nand",
+ .match_table = socrates_nand_match,
+ .probe = socrates_nand_probe,
+ .remove = __devexit_p(socrates_nand_remove),
+};
+
+static int __init socrates_nand_init(void)
+{
+ return of_register_platform_driver(&socrates_nand_driver);
+}
+
+static void __exit socrates_nand_exit(void)
+{
+ of_unregister_platform_driver(&socrates_nand_driver);
+}
+
+module_init(socrates_nand_init);
+module_exit(socrates_nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ilya Yanok");
+MODULE_DESCRIPTION("NAND driver for Socrates board");
diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c
new file mode 100644
index 00000000000..81247926489
--- /dev/null
+++ b/drivers/mtd/nand/txx9ndfmc.c
@@ -0,0 +1,428 @@
+/*
+ * TXx9 NAND flash memory controller driver
+ * Based on RBTX49xx patch from CELF patch archive.
+ *
+ * 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.
+ *
+ * (C) Copyright TOSHIBA CORPORATION 2004-2007
+ * All Rights Reserved.
+ */
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+#include <asm/txx9/ndfmc.h>
+
+/* TXX9 NDFMC Registers */
+#define TXX9_NDFDTR 0x00
+#define TXX9_NDFMCR 0x04
+#define TXX9_NDFSR 0x08
+#define TXX9_NDFISR 0x0c
+#define TXX9_NDFIMR 0x10
+#define TXX9_NDFSPR 0x14
+#define TXX9_NDFRSTR 0x18 /* not TX4939 */
+
+/* NDFMCR : NDFMC Mode Control */
+#define TXX9_NDFMCR_WE 0x80
+#define TXX9_NDFMCR_ECC_ALL 0x60
+#define TXX9_NDFMCR_ECC_RESET 0x60
+#define TXX9_NDFMCR_ECC_READ 0x40
+#define TXX9_NDFMCR_ECC_ON 0x20
+#define TXX9_NDFMCR_ECC_OFF 0x00
+#define TXX9_NDFMCR_CE 0x10
+#define TXX9_NDFMCR_BSPRT 0x04 /* TX4925/TX4926 only */
+#define TXX9_NDFMCR_ALE 0x02
+#define TXX9_NDFMCR_CLE 0x01
+/* TX4939 only */
+#define TXX9_NDFMCR_X16 0x0400
+#define TXX9_NDFMCR_DMAREQ_MASK 0x0300
+#define TXX9_NDFMCR_DMAREQ_NODMA 0x0000
+#define TXX9_NDFMCR_DMAREQ_128 0x0100
+#define TXX9_NDFMCR_DMAREQ_256 0x0200
+#define TXX9_NDFMCR_DMAREQ_512 0x0300
+#define TXX9_NDFMCR_CS_MASK 0x0c
+#define TXX9_NDFMCR_CS(ch) ((ch) << 2)
+
+/* NDFMCR : NDFMC Status */
+#define TXX9_NDFSR_BUSY 0x80
+/* TX4939 only */
+#define TXX9_NDFSR_DMARUN 0x40
+
+/* NDFMCR : NDFMC Reset */
+#define TXX9_NDFRSTR_RST 0x01
+
+struct txx9ndfmc_priv {
+ struct platform_device *dev;
+ struct nand_chip chip;
+ struct mtd_info mtd;
+ int cs;
+ char mtdname[BUS_ID_SIZE + 2];
+};
+
+#define MAX_TXX9NDFMC_DEV 4
+struct txx9ndfmc_drvdata {
+ struct mtd_info *mtds[MAX_TXX9NDFMC_DEV];
+ void __iomem *base;
+ unsigned char hold; /* in gbusclock */
+ unsigned char spw; /* in gbusclock */
+ struct nand_hw_control hw_control;
+#ifdef CONFIG_MTD_PARTITIONS
+ struct mtd_partition *parts[MAX_TXX9NDFMC_DEV];
+#endif
+};
+
+static struct platform_device *mtd_to_platdev(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct txx9ndfmc_priv *txx9_priv = chip->priv;
+ return txx9_priv->dev;
+}
+
+static void __iomem *ndregaddr(struct platform_device *dev, unsigned int reg)
+{
+ struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
+ struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+
+ return drvdata->base + (reg << plat->shift);
+}
+
+static u32 txx9ndfmc_read(struct platform_device *dev, unsigned int reg)
+{
+ return __raw_readl(ndregaddr(dev, reg));
+}
+
+static void txx9ndfmc_write(struct platform_device *dev,
+ u32 val, unsigned int reg)
+{
+ __raw_writel(val, ndregaddr(dev, reg));
+}
+
+static uint8_t txx9ndfmc_read_byte(struct mtd_info *mtd)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+
+ return txx9ndfmc_read(dev, TXX9_NDFDTR);
+}
+
+static void txx9ndfmc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
+ int len)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
+ u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_WE, TXX9_NDFMCR);
+ while (len--)
+ __raw_writel(*buf++, ndfdtr);
+ txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
+}
+
+static void txx9ndfmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
+
+ while (len--)
+ *buf++ = __raw_readl(ndfdtr);
+}
+
+static int txx9ndfmc_verify_buf(struct mtd_info *mtd, const uint8_t *buf,
+ int len)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
+
+ while (len--)
+ if (*buf++ != (uint8_t)__raw_readl(ndfdtr))
+ return -EFAULT;
+ return 0;
+}
+
+static void txx9ndfmc_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct txx9ndfmc_priv *txx9_priv = chip->priv;
+ struct platform_device *dev = txx9_priv->dev;
+ struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+ mcr &= ~(TXX9_NDFMCR_CLE | TXX9_NDFMCR_ALE | TXX9_NDFMCR_CE);
+ mcr |= ctrl & NAND_CLE ? TXX9_NDFMCR_CLE : 0;
+ mcr |= ctrl & NAND_ALE ? TXX9_NDFMCR_ALE : 0;
+ /* TXX9_NDFMCR_CE bit is 0:high 1:low */
+ mcr |= ctrl & NAND_NCE ? TXX9_NDFMCR_CE : 0;
+ if (txx9_priv->cs >= 0 && (ctrl & NAND_NCE)) {
+ mcr &= ~TXX9_NDFMCR_CS_MASK;
+ mcr |= TXX9_NDFMCR_CS(txx9_priv->cs);
+ }
+ txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
+ }
+ if (cmd != NAND_CMD_NONE)
+ txx9ndfmc_write(dev, cmd & 0xff, TXX9_NDFDTR);
+ if (plat->flags & NDFMC_PLAT_FLAG_DUMMYWRITE) {
+ /* dummy write to update external latch */
+ if ((ctrl & NAND_CTRL_CHANGE) && cmd == NAND_CMD_NONE)
+ txx9ndfmc_write(dev, 0, TXX9_NDFDTR);
+ }
+ mmiowb();
+}
+
+static int txx9ndfmc_dev_ready(struct mtd_info *mtd)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+
+ return !(txx9ndfmc_read(dev, TXX9_NDFSR) & TXX9_NDFSR_BUSY);
+}
+
+static int txx9ndfmc_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
+ uint8_t *ecc_code)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+ mcr &= ~TXX9_NDFMCR_ECC_ALL;
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_READ, TXX9_NDFMCR);
+ ecc_code[1] = txx9ndfmc_read(dev, TXX9_NDFDTR);
+ ecc_code[0] = txx9ndfmc_read(dev, TXX9_NDFDTR);
+ ecc_code[2] = txx9ndfmc_read(dev, TXX9_NDFDTR);
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
+ return 0;
+}
+
+static void txx9ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+ mcr &= ~TXX9_NDFMCR_ECC_ALL;
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_RESET, TXX9_NDFMCR);
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_ON, TXX9_NDFMCR);
+}
+
+static void txx9ndfmc_initialize(struct platform_device *dev)
+{
+ struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+ struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
+ int tmout = 100;
+
+ if (plat->flags & NDFMC_PLAT_FLAG_NO_RSTR)
+ ; /* no NDFRSTR. Write to NDFSPR resets the NDFMC. */
+ else {
+ /* reset NDFMC */
+ txx9ndfmc_write(dev,
+ txx9ndfmc_read(dev, TXX9_NDFRSTR) |
+ TXX9_NDFRSTR_RST,
+ TXX9_NDFRSTR);
+ while (txx9ndfmc_read(dev, TXX9_NDFRSTR) & TXX9_NDFRSTR_RST) {
+ if (--tmout == 0) {
+ dev_err(&dev->dev, "reset failed.\n");
+ break;
+ }
+ udelay(1);
+ }
+ }
+ /* setup Hold Time, Strobe Pulse Width */
+ txx9ndfmc_write(dev, (drvdata->hold << 4) | drvdata->spw, TXX9_NDFSPR);
+ txx9ndfmc_write(dev,
+ (plat->flags & NDFMC_PLAT_FLAG_USE_BSPRT) ?
+ TXX9_NDFMCR_BSPRT : 0, TXX9_NDFMCR);
+}
+
+#define TXX9NDFMC_NS_TO_CYC(gbusclk, ns) \
+ DIV_ROUND_UP((ns) * DIV_ROUND_UP(gbusclk, 1000), 1000000)
+
+static int __init txx9ndfmc_probe(struct platform_device *dev)
+{
+ struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+#ifdef CONFIG_MTD_PARTITIONS
+ static const char *probes[] = { "cmdlinepart", NULL };
+#endif
+ int hold, spw;
+ int i;
+ struct txx9ndfmc_drvdata *drvdata;
+ unsigned long gbusclk = plat->gbus_clock;
+ struct resource *res;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+ drvdata = devm_kzalloc(&dev->dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+ if (!devm_request_mem_region(&dev->dev, res->start,
+ resource_size(res), dev_name(&dev->dev)))
+ return -EBUSY;
+ drvdata->base = devm_ioremap(&dev->dev, res->start,
+ resource_size(res));
+ if (!drvdata->base)
+ return -EBUSY;
+
+ hold = plat->hold ?: 20; /* tDH */
+ spw = plat->spw ?: 90; /* max(tREADID, tWP, tRP) */
+
+ hold = TXX9NDFMC_NS_TO_CYC(gbusclk, hold);
+ spw = TXX9NDFMC_NS_TO_CYC(gbusclk, spw);
+ if (plat->flags & NDFMC_PLAT_FLAG_HOLDADD)
+ hold -= 2; /* actual hold time : (HOLD + 2) BUSCLK */
+ spw -= 1; /* actual wait time : (SPW + 1) BUSCLK */
+ hold = clamp(hold, 1, 15);
+ drvdata->hold = hold;
+ spw = clamp(spw, 1, 15);
+ drvdata->spw = spw;
+ dev_info(&dev->dev, "CLK:%ldMHz HOLD:%d SPW:%d\n",
+ (gbusclk + 500000) / 1000000, hold, spw);
+
+ spin_lock_init(&drvdata->hw_control.lock);
+ init_waitqueue_head(&drvdata->hw_control.wq);
+
+ platform_set_drvdata(dev, drvdata);
+ txx9ndfmc_initialize(dev);
+
+ for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
+ struct txx9ndfmc_priv *txx9_priv;
+ struct nand_chip *chip;
+ struct mtd_info *mtd;
+#ifdef CONFIG_MTD_PARTITIONS
+ int nr_parts;
+#endif
+
+ if (!(plat->ch_mask & (1 << i)))
+ continue;
+ txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv),
+ GFP_KERNEL);
+ if (!txx9_priv) {
+ dev_err(&dev->dev, "Unable to allocate "
+ "TXx9 NDFMC MTD device structure.\n");
+ continue;
+ }
+ chip = &txx9_priv->chip;
+ mtd = &txx9_priv->mtd;
+ mtd->owner = THIS_MODULE;
+
+ mtd->priv = chip;
+
+ chip->read_byte = txx9ndfmc_read_byte;
+ chip->read_buf = txx9ndfmc_read_buf;
+ chip->write_buf = txx9ndfmc_write_buf;
+ chip->verify_buf = txx9ndfmc_verify_buf;
+ chip->cmd_ctrl = txx9ndfmc_cmd_ctrl;
+ chip->dev_ready = txx9ndfmc_dev_ready;
+ chip->ecc.calculate = txx9ndfmc_calculate_ecc;
+ chip->ecc.correct = nand_correct_data;
+ chip->ecc.hwctl = txx9ndfmc_enable_hwecc;
+ chip->ecc.mode = NAND_ECC_HW;
+ chip->ecc.size = 256;
+ chip->ecc.bytes = 3;
+ chip->chip_delay = 100;
+ chip->controller = &drvdata->hw_control;
+
+ chip->priv = txx9_priv;
+ txx9_priv->dev = dev;
+
+ if (plat->ch_mask != 1) {
+ txx9_priv->cs = i;
+ sprintf(txx9_priv->mtdname, "%s.%u",
+ dev_name(&dev->dev), i);
+ } else {
+ txx9_priv->cs = -1;
+ strcpy(txx9_priv->mtdname, dev_name(&dev->dev));
+ }
+ if (plat->wide_mask & (1 << i))
+ chip->options |= NAND_BUSWIDTH_16;
+
+ if (nand_scan(mtd, 1)) {
+ kfree(txx9_priv);
+ continue;
+ }
+ mtd->name = txx9_priv->mtdname;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ nr_parts = parse_mtd_partitions(mtd, probes,
+ &drvdata->parts[i], 0);
+ if (nr_parts > 0)
+ add_mtd_partitions(mtd, drvdata->parts[i], nr_parts);
+#endif
+ add_mtd_device(mtd);
+ drvdata->mtds[i] = mtd;
+ }
+
+ return 0;
+}
+
+static int __exit txx9ndfmc_remove(struct platform_device *dev)
+{
+ struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
+ int i;
+
+ platform_set_drvdata(dev, NULL);
+ if (!drvdata)
+ return 0;
+ for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
+ struct mtd_info *mtd = drvdata->mtds[i];
+ struct nand_chip *chip;
+ struct txx9ndfmc_priv *txx9_priv;
+
+ if (!mtd)
+ continue;
+ chip = mtd->priv;
+ txx9_priv = chip->priv;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ del_mtd_partitions(mtd);
+ kfree(drvdata->parts[i]);
+#endif
+ del_mtd_device(mtd);
+ kfree(txx9_priv);
+ }
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int txx9ndfmc_resume(struct platform_device *dev)
+{
+ if (platform_get_drvdata(dev))
+ txx9ndfmc_initialize(dev);
+ return 0;
+}
+#else
+#define txx9ndfmc_resume NULL
+#endif
+
+static struct platform_driver txx9ndfmc_driver = {
+ .remove = __exit_p(txx9ndfmc_remove),
+ .resume = txx9ndfmc_resume,
+ .driver = {
+ .name = "txx9ndfmc",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init txx9ndfmc_init(void)
+{
+ return platform_driver_probe(&txx9ndfmc_driver, txx9ndfmc_probe);
+}
+
+static void __exit txx9ndfmc_exit(void)
+{
+ platform_driver_unregister(&txx9ndfmc_driver);
+}
+
+module_init(txx9ndfmc_init);
+module_exit(txx9ndfmc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TXx9 SoC NAND flash controller driver");
+MODULE_ALIAS("platform:txx9ndfmc");
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index d1c4546513f..e3f8495a94c 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -15,11 +15,11 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/hdreg.h>
+#include <linux/blkdev.h>
#include <linux/kmod.h>
#include <linux/mtd/mtd.h>
@@ -818,3 +818,4 @@ module_exit(cleanup_nftl);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>, Fabrice Bellard <fabrice.bellard@netgem.com> et al.");
MODULE_DESCRIPTION("Support code for NAND Flash Translation Layer, used on M-Systems DiskOnChip 2000 and Millennium");
+MODULE_ALIAS_BLOCKDEV_MAJOR(NFTL_MAJOR);
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 9e45b3f39c0..3e164f0c929 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -46,6 +46,13 @@ int __devinit of_mtd_parse_partitions(struct device *dev,
const u32 *reg;
int len;
+ /* check if this is a partition node */
+ partname = of_get_property(pp, "name", &len);
+ if (strcmp(partname, "partition") != 0) {
+ nr_parts--;
+ continue;
+ }
+
reg = of_get_property(pp, "reg", &len);
if (!reg || (len != 2 * sizeof(u32))) {
of_node_put(pp);
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 77a4f144615..f2e9de1414d 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -294,6 +294,10 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
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;
@@ -672,6 +676,8 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
c->mtd.priv = &c->onenand;
c->mtd.owner = THIS_MODULE;
+ c->mtd.dev.parent = &pdev->dev;
+
if (c->dma_channel >= 0) {
struct onenand_chip *this = &c->onenand;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 529af271db1..30d6999e5f9 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1455,7 +1455,8 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops)
{
struct onenand_chip *this = mtd->priv;
- int written = 0, column, thislen, subpage;
+ int written = 0, column, thislen = 0, subpage = 0;
+ int prev = 0, prevlen = 0, prev_subpage = 0, first = 1;
int oobwritten = 0, oobcolumn, thisooblen, oobsize;
size_t len = ops->len;
size_t ooblen = ops->ooblen;
@@ -1482,6 +1483,10 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
return -EINVAL;
}
+ /* Check zero length */
+ if (!len)
+ return 0;
+
if (ops->mode == MTD_OOB_AUTO)
oobsize = this->ecclayout->oobavail;
else
@@ -1492,79 +1497,121 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
column = to & (mtd->writesize - 1);
/* Loop until all data write */
- while (written < len) {
- u_char *wbuf = (u_char *) buf;
+ while (1) {
+ if (written < len) {
+ u_char *wbuf = (u_char *) buf;
- thislen = min_t(int, mtd->writesize - column, len - written);
- thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
+ thislen = min_t(int, mtd->writesize - column, len - written);
+ thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
- cond_resched();
+ cond_resched();
- this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
+ this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
- /* Partial page write */
- subpage = thislen < mtd->writesize;
- if (subpage) {
- memset(this->page_buf, 0xff, mtd->writesize);
- memcpy(this->page_buf + column, buf, thislen);
- wbuf = this->page_buf;
- }
+ /* Partial page write */
+ subpage = thislen < mtd->writesize;
+ if (subpage) {
+ memset(this->page_buf, 0xff, mtd->writesize);
+ memcpy(this->page_buf + column, buf, thislen);
+ wbuf = this->page_buf;
+ }
- this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
+ this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
- if (oob) {
- oobbuf = this->oob_buf;
+ if (oob) {
+ oobbuf = this->oob_buf;
- /* We send data to spare ram with oobsize
- * to prevent byte access */
- memset(oobbuf, 0xff, mtd->oobsize);
- if (ops->mode == MTD_OOB_AUTO)
- onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
- else
- memcpy(oobbuf + oobcolumn, oob, thisooblen);
+ /* We send data to spare ram with oobsize
+ * to prevent byte access */
+ memset(oobbuf, 0xff, mtd->oobsize);
+ if (ops->mode == MTD_OOB_AUTO)
+ onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
+ else
+ memcpy(oobbuf + oobcolumn, oob, thisooblen);
- oobwritten += thisooblen;
- oob += thisooblen;
- oobcolumn = 0;
+ oobwritten += thisooblen;
+ oob += thisooblen;
+ oobcolumn = 0;
+ } else
+ oobbuf = (u_char *) ffchars;
+
+ this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
} else
- oobbuf = (u_char *) ffchars;
+ ONENAND_SET_NEXT_BUFFERRAM(this);
- this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
+ /*
+ * 2 PLANE, MLC, and Flex-OneNAND doesn't support
+ * write-while-programe feature.
+ */
+ if (!ONENAND_IS_2PLANE(this) && !first) {
+ ONENAND_SET_PREV_BUFFERRAM(this);
- this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
+ ret = this->wait(mtd, FL_WRITING);
- ret = this->wait(mtd, FL_WRITING);
+ /* In partial page write we don't update bufferram */
+ onenand_update_bufferram(mtd, prev, !ret && !prev_subpage);
+ if (ret) {
+ written -= prevlen;
+ printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
+ break;
+ }
- /* In partial page write we don't update bufferram */
- onenand_update_bufferram(mtd, to, !ret && !subpage);
- if (ONENAND_IS_2PLANE(this)) {
- ONENAND_SET_BUFFERRAM1(this);
- onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage);
- }
+ if (written == len) {
+ /* Only check verify write turn on */
+ ret = onenand_verify(mtd, buf - len, to - len, len);
+ if (ret)
+ printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
+ break;
+ }
- if (ret) {
- printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
- break;
+ ONENAND_SET_NEXT_BUFFERRAM(this);
}
- /* Only check verify write turn on */
- ret = onenand_verify(mtd, buf, to, thislen);
- if (ret) {
- printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
- break;
- }
+ this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
- written += thislen;
+ /*
+ * 2 PLANE, MLC, and Flex-OneNAND wait here
+ */
+ if (ONENAND_IS_2PLANE(this)) {
+ ret = this->wait(mtd, FL_WRITING);
- if (written == len)
- break;
+ /* In partial page write we don't update bufferram */
+ onenand_update_bufferram(mtd, to, !ret && !subpage);
+ if (ret) {
+ printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
+ break;
+ }
+
+ /* Only check verify write turn on */
+ ret = onenand_verify(mtd, buf, to, thislen);
+ if (ret) {
+ printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
+ break;
+ }
+
+ written += thislen;
+
+ if (written == len)
+ break;
+
+ } else
+ written += thislen;
column = 0;
+ prev_subpage = subpage;
+ prev = to;
+ prevlen = thislen;
to += thislen;
buf += thislen;
+ first = 0;
}
+ /* In error case, clear all bufferrams */
+ if (written != len)
+ onenand_invalidate_bufferram(mtd, 0, -1);
+
ops->retlen = written;
+ ops->oobretlen = oobwritten;
return ret;
}
diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c
index afbc3f8126d..a18e8d2f255 100644
--- a/drivers/mtd/tests/mtd_oobtest.c
+++ b/drivers/mtd/tests/mtd_oobtest.c
@@ -136,7 +136,7 @@ static int write_eraseblock(int ebnum)
ops.ooblen = use_len;
ops.oobretlen = 0;
ops.ooboffs = use_offset;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
err = mtd->write_oob(mtd, addr, &ops);
if (err || ops.oobretlen != use_len) {
@@ -189,7 +189,7 @@ static int verify_eraseblock(int ebnum)
ops.ooblen = use_len;
ops.oobretlen = 0;
ops.ooboffs = use_offset;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
err = mtd->read_oob(mtd, addr, &ops);
if (err || ops.oobretlen != use_len) {
@@ -216,7 +216,7 @@ static int verify_eraseblock(int ebnum)
ops.ooblen = mtd->ecclayout->oobavail;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
err = mtd->read_oob(mtd, addr, &ops);
if (err || ops.oobretlen != mtd->ecclayout->oobavail) {
@@ -281,7 +281,7 @@ static int verify_eraseblock_in_one_go(int ebnum)
ops.ooblen = len;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
err = mtd->read_oob(mtd, addr, &ops);
if (err || ops.oobretlen != len) {
@@ -522,7 +522,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = 1;
ops.oobretlen = 0;
ops.ooboffs = mtd->ecclayout->oobavail;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
printk(PRINT_PREF "attempting to start write past end of OOB\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -542,7 +542,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = 1;
ops.oobretlen = 0;
ops.ooboffs = mtd->ecclayout->oobavail;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
printk(PRINT_PREF "attempting to start read past end of OOB\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -566,7 +566,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail + 1;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
printk(PRINT_PREF "attempting to write past end of device\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -586,7 +586,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail + 1;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
printk(PRINT_PREF "attempting to read past end of device\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -610,7 +610,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail;
ops.oobretlen = 0;
ops.ooboffs = 1;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
printk(PRINT_PREF "attempting to write past end of device\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -630,7 +630,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail;
ops.oobretlen = 0;
ops.ooboffs = 1;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
printk(PRINT_PREF "attempting to read past end of device\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -670,7 +670,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = sz;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
err = mtd->write_oob(mtd, addr, &ops);
if (err)
@@ -698,7 +698,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail * 2;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
err = mtd->read_oob(mtd, addr, &ops);
if (err)
diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c
index 645e77fdc63..79fc4530987 100644
--- a/drivers/mtd/tests/mtd_readtest.c
+++ b/drivers/mtd/tests/mtd_readtest.c
@@ -71,7 +71,7 @@ static int read_eraseblock_by_page(int ebnum)
ops.ooblen = mtd->oobsize;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = oobbuf;
ret = mtd->read_oob(mtd, addr, &ops);
if (ret || ops.oobretlen != mtd->oobsize) {
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index e63c8fc3df3..f8e0f68f218 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -186,6 +186,16 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin)
return new_offset;
}
+static int vol_cdev_fsync(struct file *file, struct dentry *dentry,
+ int datasync)
+{
+ struct ubi_volume_desc *desc = file->private_data;
+ struct ubi_device *ubi = desc->vol->ubi;
+
+ return ubi_sync(ubi->ubi_num);
+}
+
+
static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
loff_t *offp)
{
@@ -1073,6 +1083,7 @@ const struct file_operations ubi_vol_cdev_operations = {
.llseek = vol_cdev_llseek,
.read = vol_cdev_read,
.write = vol_cdev_write,
+ .fsync = vol_cdev_fsync,
.unlocked_ioctl = vol_cdev_ioctl,
.compat_ioctl = vol_cdev_compat_ioctl,
};
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index a09e3a7cac4..02330f3d5a5 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -1530,7 +1530,7 @@ static void cp_get_ethtool_stats (struct net_device *dev,
/* begin NIC statistics dump */
cpw32(StatsAddr + 4, (u64)dma >> 32);
- cpw32(StatsAddr, ((u64)dma & DMA_32BIT_MASK) | DumpStats);
+ cpw32(StatsAddr, ((u64)dma & DMA_BIT_MASK(32)) | DumpStats);
cpr32(StatsAddr);
for (i = 0; i < 1000; i++) {
@@ -1929,19 +1929,19 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
/* Configure DMA attributes. */
if ((sizeof(dma_addr_t) > 4) &&
- !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) &&
- !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) &&
+ !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
} else {
pci_using_dac = 0;
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev,
"No usable DMA configuration, aborting.\n");
goto err_out_res;
}
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_err(&pdev->dev,
"No usable consistent DMA configuration, "
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 16899eee397..9e921544ba2 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -977,6 +977,8 @@ config ETHOC
depends on NET_ETHERNET && HAS_IOMEM
select MII
select PHYLIB
+ select CRC32
+ select BITREVERSE
help
Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC.
@@ -2056,6 +2058,27 @@ config IGB_DCA
driver. DCA is a method for warming the CPU cache before data
is used, with the intent of lessening the impact of cache misses.
+config IGBVF
+ tristate "Intel(R) 82576 Virtual Function Ethernet support"
+ depends on PCI
+ ---help---
+ This driver supports Intel(R) 82576 virtual functions. For more
+ information on how to identify your adapter, go to the Adapter &
+ Driver ID Guide at:
+
+ <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+ For general information and support, go to the Intel support
+ website at:
+
+ <http://support.intel.com>
+
+ More specific information on configuring the driver is in
+ <file:Documentation/networking/e1000.txt>.
+
+ To compile this driver as a module, choose M here. The module
+ will be called igbvf.
+
source "drivers/net/ixp2000/Kconfig"
config MYRI_SBUS
@@ -2234,7 +2257,7 @@ config BNX2
tristate "Broadcom NetXtremeII support"
depends on PCI
select CRC32
- select ZLIB_INFLATE
+ select FW_LOADER
help
This driver supports Broadcom NetXtremeII gigabit Ethernet cards.
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index edc9a0d6171..1fc4602a6ff 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_E1000) += e1000/
obj-$(CONFIG_E1000E) += e1000e/
obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
obj-$(CONFIG_IGB) += igb/
+obj-$(CONFIG_IGBVF) += igbvf/
obj-$(CONFIG_IXGBE) += ixgbe/
obj-$(CONFIG_IXGB) += ixgb/
obj-$(CONFIG_IP1000) += ipg.o
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 06a9f11669f..57bc7152785 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -1161,9 +1161,9 @@ static int __devinit ace_init(struct net_device *dev)
/*
* Configure DMA attributes.
*/
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
ap->pci_using_dac = 1;
- } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
ap->pci_using_dac = 0;
} else {
ecode = -ENODEV;
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index cb9c95d3ed0..19831bd6401 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -1871,7 +1871,7 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
}
/* Initialize DMA */
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) < 0) {
printk(KERN_ERR "amd8111e: DMA not supported,"
"exiting.\n");
goto err_free_reg;
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
index deb7b53167e..83a12125b94 100644
--- a/drivers/net/atl1c/atl1c_main.c
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -2532,8 +2532,8 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
* various kernel subsystems to support the mechanics required by a
* fixed-high-32-bit system.
*/
- if ((pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) ||
- (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) != 0)) {
+ if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
+ (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
goto err_dma;
}
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index c758884728a..fb57b750866 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -2326,8 +2326,8 @@ static int __devinit atl1e_probe(struct pci_dev *pdev,
* various kernel subsystems to support the mechanics required by a
* fixed-high-32-bit system.
*/
- if ((pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) ||
- (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) != 0)) {
+ if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
+ (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
goto err_dma;
}
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 43fc1b2ca3c..0ab22540bf5 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -2929,7 +2929,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
* various kernel subsystems to support the mechanics required by a
* fixed-high-32-bit system.
*/
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "no usable DMA configuration\n");
goto err_dma;
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index 9fe06c3f409..c734b1983ec 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -1358,8 +1358,8 @@ static int __devinit atl2_probe(struct pci_dev *pdev,
* until the kernel has the proper infrastructure to support 64-bit DMA
* on these devices.
*/
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) &&
- pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) &&
+ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_ERR "atl2: No usable DMA configuration, aborting\n");
goto err_dma;
}
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 5c84541e073..b70b81ec34c 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -660,7 +660,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
/* Hardware bug work-around, the chip is unable to do PCI DMA
to/from anything above 1GB :-( */
if (ssb_dma_mapping_error(bp->sdev, mapping) ||
- mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
+ mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
/* Sigh... */
if (!ssb_dma_mapping_error(bp->sdev, mapping))
ssb_dma_unmap_single(bp->sdev, mapping,
@@ -673,7 +673,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
RX_PKT_BUF_SZ,
DMA_FROM_DEVICE);
if (ssb_dma_mapping_error(bp->sdev, mapping) ||
- mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
+ mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
if (!ssb_dma_mapping_error(bp->sdev, mapping))
ssb_dma_unmap_single(bp->sdev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
@@ -703,7 +703,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
if (bp->flags & B44_FLAG_RX_RING_HACK)
b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
- dest_idx * sizeof(dp),
+ dest_idx * sizeof(*dp),
DMA_BIDIRECTIONAL);
return RX_PKT_BUF_SZ;
@@ -731,7 +731,7 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
if (bp->flags & B44_FLAG_RX_RING_HACK)
b44_sync_dma_desc_for_cpu(bp->sdev, bp->rx_ring_dma,
- src_idx * sizeof(src_desc),
+ src_idx * sizeof(*src_desc),
DMA_BIDIRECTIONAL);
ctrl = src_desc->ctrl;
@@ -747,10 +747,10 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
if (bp->flags & B44_FLAG_RX_RING_HACK)
b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
- dest_idx * sizeof(dest_desc),
+ dest_idx * sizeof(*dest_desc),
DMA_BIDIRECTIONAL);
- ssb_dma_sync_single_for_device(bp->sdev, le32_to_cpu(src_desc->addr),
+ ssb_dma_sync_single_for_device(bp->sdev, dest_map->mapping,
RX_PKT_BUF_SZ,
DMA_FROM_DEVICE);
}
@@ -965,7 +965,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
mapping = ssb_dma_map_single(bp->sdev, skb->data, len, DMA_TO_DEVICE);
- if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) {
+ if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
struct sk_buff *bounce_skb;
/* Chip can't handle DMA to/from >1GB, use bounce buffer */
@@ -979,7 +979,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
mapping = ssb_dma_map_single(bp->sdev, bounce_skb->data,
len, DMA_TO_DEVICE);
- if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) {
+ if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
if (!ssb_dma_mapping_error(bp->sdev, mapping))
ssb_dma_unmap_single(bp->sdev, mapping,
len, DMA_TO_DEVICE);
@@ -1204,7 +1204,7 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
DMA_BIDIRECTIONAL);
if (ssb_dma_mapping_error(bp->sdev, rx_ring_dma) ||
- rx_ring_dma + size > DMA_30BIT_MASK) {
+ rx_ring_dma + size > DMA_BIT_MASK(30)) {
kfree(rx_ring);
goto out_err;
}
@@ -1231,7 +1231,7 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
DMA_TO_DEVICE);
if (ssb_dma_mapping_error(bp->sdev, tx_ring_dma) ||
- tx_ring_dma + size > DMA_30BIT_MASK) {
+ tx_ring_dma + size > DMA_BIT_MASK(30)) {
kfree(tx_ring);
goto out_err;
}
@@ -2180,7 +2180,7 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
"Failed to powerup the bus\n");
goto err_out_free_dev;
}
- err = ssb_dma_set_mask(sdev, DMA_30BIT_MASK);
+ err = ssb_dma_set_mask(sdev, DMA_BIT_MASK(30));
if (err) {
dev_err(sdev->dev,
"Required 30BIT DMA mask unsupported by the system.\n");
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 9b75aa63006..30d0c81c989 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1821,11 +1821,11 @@ static int __devinit be_probe(struct pci_dev *pdev,
be_msix_enable(adapter);
- status = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ status = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (!status) {
netdev->features |= NETIF_F_HIGHDMA;
} else {
- status = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ status = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (status) {
dev_err(&pdev->dev, "Could not set PCI DMA Mask\n");
goto free_netdev;
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index ad446db8e18..d47839184a0 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -46,19 +46,20 @@
#include <linux/crc32.h>
#include <linux/prefetch.h>
#include <linux/cache.h>
-#include <linux/zlib.h>
+#include <linux/firmware.h>
#include <linux/log2.h>
#include "bnx2.h"
#include "bnx2_fw.h"
-#include "bnx2_fw2.h"
-
-#define FW_BUF_SIZE 0x10000
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.9.3"
-#define DRV_MODULE_RELDATE "March 17, 2009"
+#define DRV_MODULE_VERSION "2.0.0"
+#define DRV_MODULE_RELDATE "April 2, 2009"
+#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-4.6.16.fw"
+#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-4.6.16.fw"
+#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-4.6.17.fw"
+#define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-4.6.15.fw"
#define RUN_AT(x) (jiffies + (x))
@@ -72,6 +73,10 @@ MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>");
MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709/5716 Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
+MODULE_FIRMWARE(FW_MIPS_FILE_06);
+MODULE_FIRMWARE(FW_RV2P_FILE_06);
+MODULE_FIRMWARE(FW_MIPS_FILE_09);
+MODULE_FIRMWARE(FW_RV2P_FILE_09);
static int disable_msi = 0;
@@ -3391,33 +3396,143 @@ bnx2_set_rx_mode(struct net_device *dev)
spin_unlock_bh(&bp->phy_lock);
}
-static void
-load_rv2p_fw(struct bnx2 *bp, __le32 *rv2p_code, u32 rv2p_code_len,
- u32 rv2p_proc)
+static int __devinit
+check_fw_section(const struct firmware *fw,
+ const struct bnx2_fw_file_section *section,
+ u32 alignment, bool non_empty)
+{
+ u32 offset = be32_to_cpu(section->offset);
+ u32 len = be32_to_cpu(section->len);
+
+ if ((offset == 0 && len != 0) || offset >= fw->size || offset & 3)
+ return -EINVAL;
+ if ((non_empty && len == 0) || len > fw->size - offset ||
+ len & (alignment - 1))
+ return -EINVAL;
+ return 0;
+}
+
+static int __devinit
+check_mips_fw_entry(const struct firmware *fw,
+ const struct bnx2_mips_fw_file_entry *entry)
+{
+ if (check_fw_section(fw, &entry->text, 4, true) ||
+ check_fw_section(fw, &entry->data, 4, false) ||
+ check_fw_section(fw, &entry->rodata, 4, false))
+ return -EINVAL;
+ return 0;
+}
+
+static int __devinit
+bnx2_request_firmware(struct bnx2 *bp)
{
+ const char *mips_fw_file, *rv2p_fw_file;
+ const struct bnx2_mips_fw_file *mips_fw;
+ const struct bnx2_rv2p_fw_file *rv2p_fw;
+ int rc;
+
+ if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ mips_fw_file = FW_MIPS_FILE_09;
+ rv2p_fw_file = FW_RV2P_FILE_09;
+ } else {
+ mips_fw_file = FW_MIPS_FILE_06;
+ rv2p_fw_file = FW_RV2P_FILE_06;
+ }
+
+ rc = request_firmware(&bp->mips_firmware, mips_fw_file, &bp->pdev->dev);
+ if (rc) {
+ printk(KERN_ERR PFX "Can't load firmware file \"%s\"\n",
+ mips_fw_file);
+ return rc;
+ }
+
+ rc = request_firmware(&bp->rv2p_firmware, rv2p_fw_file, &bp->pdev->dev);
+ if (rc) {
+ printk(KERN_ERR PFX "Can't load firmware file \"%s\"\n",
+ rv2p_fw_file);
+ return rc;
+ }
+ mips_fw = (const struct bnx2_mips_fw_file *) bp->mips_firmware->data;
+ rv2p_fw = (const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data;
+ if (bp->mips_firmware->size < sizeof(*mips_fw) ||
+ check_mips_fw_entry(bp->mips_firmware, &mips_fw->com) ||
+ check_mips_fw_entry(bp->mips_firmware, &mips_fw->cp) ||
+ check_mips_fw_entry(bp->mips_firmware, &mips_fw->rxp) ||
+ check_mips_fw_entry(bp->mips_firmware, &mips_fw->tpat) ||
+ check_mips_fw_entry(bp->mips_firmware, &mips_fw->txp)) {
+ printk(KERN_ERR PFX "Firmware file \"%s\" is invalid\n",
+ mips_fw_file);
+ return -EINVAL;
+ }
+ if (bp->rv2p_firmware->size < sizeof(*rv2p_fw) ||
+ check_fw_section(bp->rv2p_firmware, &rv2p_fw->proc1.rv2p, 8, true) ||
+ check_fw_section(bp->rv2p_firmware, &rv2p_fw->proc2.rv2p, 8, true)) {
+ printk(KERN_ERR PFX "Firmware file \"%s\" is invalid\n",
+ rv2p_fw_file);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static u32
+rv2p_fw_fixup(u32 rv2p_proc, int idx, u32 loc, u32 rv2p_code)
+{
+ switch (idx) {
+ case RV2P_P1_FIXUP_PAGE_SIZE_IDX:
+ rv2p_code &= ~RV2P_BD_PAGE_SIZE_MSK;
+ rv2p_code |= RV2P_BD_PAGE_SIZE;
+ break;
+ }
+ return rv2p_code;
+}
+
+static int
+load_rv2p_fw(struct bnx2 *bp, u32 rv2p_proc,
+ const struct bnx2_rv2p_fw_file_entry *fw_entry)
+{
+ u32 rv2p_code_len, file_offset;
+ __be32 *rv2p_code;
int i;
- u32 val;
+ u32 val, cmd, addr;
+
+ rv2p_code_len = be32_to_cpu(fw_entry->rv2p.len);
+ file_offset = be32_to_cpu(fw_entry->rv2p.offset);
+
+ rv2p_code = (__be32 *)(bp->rv2p_firmware->data + file_offset);
- if (rv2p_proc == RV2P_PROC2 && CHIP_NUM(bp) == CHIP_NUM_5709) {
- val = le32_to_cpu(rv2p_code[XI_RV2P_PROC2_MAX_BD_PAGE_LOC]);
- val &= ~XI_RV2P_PROC2_BD_PAGE_SIZE_MSK;
- val |= XI_RV2P_PROC2_BD_PAGE_SIZE;
- rv2p_code[XI_RV2P_PROC2_MAX_BD_PAGE_LOC] = cpu_to_le32(val);
+ if (rv2p_proc == RV2P_PROC1) {
+ cmd = BNX2_RV2P_PROC1_ADDR_CMD_RDWR;
+ addr = BNX2_RV2P_PROC1_ADDR_CMD;
+ } else {
+ cmd = BNX2_RV2P_PROC2_ADDR_CMD_RDWR;
+ addr = BNX2_RV2P_PROC2_ADDR_CMD;
}
for (i = 0; i < rv2p_code_len; i += 8) {
- REG_WR(bp, BNX2_RV2P_INSTR_HIGH, le32_to_cpu(*rv2p_code));
+ REG_WR(bp, BNX2_RV2P_INSTR_HIGH, be32_to_cpu(*rv2p_code));
rv2p_code++;
- REG_WR(bp, BNX2_RV2P_INSTR_LOW, le32_to_cpu(*rv2p_code));
+ REG_WR(bp, BNX2_RV2P_INSTR_LOW, be32_to_cpu(*rv2p_code));
rv2p_code++;
- if (rv2p_proc == RV2P_PROC1) {
- val = (i / 8) | BNX2_RV2P_PROC1_ADDR_CMD_RDWR;
- REG_WR(bp, BNX2_RV2P_PROC1_ADDR_CMD, val);
- }
- else {
- val = (i / 8) | BNX2_RV2P_PROC2_ADDR_CMD_RDWR;
- REG_WR(bp, BNX2_RV2P_PROC2_ADDR_CMD, val);
+ val = (i / 8) | cmd;
+ REG_WR(bp, addr, val);
+ }
+
+ rv2p_code = (__be32 *)(bp->rv2p_firmware->data + file_offset);
+ for (i = 0; i < 8; i++) {
+ u32 loc, code;
+
+ loc = be32_to_cpu(fw_entry->fixup[i]);
+ if (loc && ((loc * 4) < rv2p_code_len)) {
+ code = be32_to_cpu(*(rv2p_code + loc - 1));
+ REG_WR(bp, BNX2_RV2P_INSTR_HIGH, code);
+ code = be32_to_cpu(*(rv2p_code + loc));
+ code = rv2p_fw_fixup(rv2p_proc, i, loc, code);
+ REG_WR(bp, BNX2_RV2P_INSTR_LOW, code);
+
+ val = (loc / 2) | cmd;
+ REG_WR(bp, addr, val);
}
}
@@ -3428,14 +3543,18 @@ load_rv2p_fw(struct bnx2 *bp, __le32 *rv2p_code, u32 rv2p_code_len,
else {
REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC2_RESET);
}
+
+ return 0;
}
static int
-load_cpu_fw(struct bnx2 *bp, const struct cpu_reg *cpu_reg, struct fw_info *fw)
+load_cpu_fw(struct bnx2 *bp, const struct cpu_reg *cpu_reg,
+ const struct bnx2_mips_fw_file_entry *fw_entry)
{
+ u32 addr, len, file_offset;
+ __be32 *data;
u32 offset;
u32 val;
- int rc;
/* Halt the CPU. */
val = bnx2_reg_rd_ind(bp, cpu_reg->mode);
@@ -3444,64 +3563,52 @@ load_cpu_fw(struct bnx2 *bp, const struct cpu_reg *cpu_reg, struct fw_info *fw)
bnx2_reg_wr_ind(bp, cpu_reg->state, cpu_reg->state_value_clear);
/* Load the Text area. */
- offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
- if (fw->gz_text) {
- int j;
-
- rc = zlib_inflate_blob(fw->text, FW_BUF_SIZE, fw->gz_text,
- fw->gz_text_len);
- if (rc < 0)
- return rc;
+ addr = be32_to_cpu(fw_entry->text.addr);
+ len = be32_to_cpu(fw_entry->text.len);
+ file_offset = be32_to_cpu(fw_entry->text.offset);
+ data = (__be32 *)(bp->mips_firmware->data + file_offset);
- for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
- bnx2_reg_wr_ind(bp, offset, le32_to_cpu(fw->text[j]));
- }
- }
-
- /* Load the Data area. */
- offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
- if (fw->data) {
+ offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base);
+ if (len) {
int j;
- for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
- bnx2_reg_wr_ind(bp, offset, fw->data[j]);
- }
+ for (j = 0; j < (len / 4); j++, offset += 4)
+ bnx2_reg_wr_ind(bp, offset, be32_to_cpu(data[j]));
}
- /* Load the SBSS area. */
- offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
- if (fw->sbss_len) {
- int j;
-
- for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
- bnx2_reg_wr_ind(bp, offset, 0);
- }
- }
+ /* Load the Data area. */
+ addr = be32_to_cpu(fw_entry->data.addr);
+ len = be32_to_cpu(fw_entry->data.len);
+ file_offset = be32_to_cpu(fw_entry->data.offset);
+ data = (__be32 *)(bp->mips_firmware->data + file_offset);
- /* Load the BSS area. */
- offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
- if (fw->bss_len) {
+ offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base);
+ if (len) {
int j;
- for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
- bnx2_reg_wr_ind(bp, offset, 0);
- }
+ for (j = 0; j < (len / 4); j++, offset += 4)
+ bnx2_reg_wr_ind(bp, offset, be32_to_cpu(data[j]));
}
/* Load the Read-Only area. */
- offset = cpu_reg->spad_base +
- (fw->rodata_addr - cpu_reg->mips_view_base);
- if (fw->rodata) {
+ addr = be32_to_cpu(fw_entry->rodata.addr);
+ len = be32_to_cpu(fw_entry->rodata.len);
+ file_offset = be32_to_cpu(fw_entry->rodata.offset);
+ data = (__be32 *)(bp->mips_firmware->data + file_offset);
+
+ offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base);
+ if (len) {
int j;
- for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
- bnx2_reg_wr_ind(bp, offset, fw->rodata[j]);
- }
+ for (j = 0; j < (len / 4); j++, offset += 4)
+ bnx2_reg_wr_ind(bp, offset, be32_to_cpu(data[j]));
}
/* Clear the pre-fetch instruction. */
bnx2_reg_wr_ind(bp, cpu_reg->inst, 0);
- bnx2_reg_wr_ind(bp, cpu_reg->pc, fw->start_addr);
+
+ val = be32_to_cpu(fw_entry->start_addr);
+ bnx2_reg_wr_ind(bp, cpu_reg->pc, val);
/* Start the CPU. */
val = bnx2_reg_rd_ind(bp, cpu_reg->mode);
@@ -3515,95 +3622,40 @@ load_cpu_fw(struct bnx2 *bp, const struct cpu_reg *cpu_reg, struct fw_info *fw)
static int
bnx2_init_cpus(struct bnx2 *bp)
{
- struct fw_info *fw;
- int rc, rv2p_len;
- void *text, *rv2p;
+ const struct bnx2_mips_fw_file *mips_fw =
+ (const struct bnx2_mips_fw_file *) bp->mips_firmware->data;
+ const struct bnx2_rv2p_fw_file *rv2p_fw =
+ (const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data;
+ int rc;
/* Initialize the RV2P processor. */
- text = vmalloc(FW_BUF_SIZE);
- if (!text)
- return -ENOMEM;
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
- rv2p = bnx2_xi_rv2p_proc1;
- rv2p_len = sizeof(bnx2_xi_rv2p_proc1);
- } else {
- rv2p = bnx2_rv2p_proc1;
- rv2p_len = sizeof(bnx2_rv2p_proc1);
- }
- rc = zlib_inflate_blob(text, FW_BUF_SIZE, rv2p, rv2p_len);
- if (rc < 0)
- goto init_cpu_err;
-
- load_rv2p_fw(bp, text, rc /* == len */, RV2P_PROC1);
-
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
- rv2p = bnx2_xi_rv2p_proc2;
- rv2p_len = sizeof(bnx2_xi_rv2p_proc2);
- } else {
- rv2p = bnx2_rv2p_proc2;
- rv2p_len = sizeof(bnx2_rv2p_proc2);
- }
- rc = zlib_inflate_blob(text, FW_BUF_SIZE, rv2p, rv2p_len);
- if (rc < 0)
- goto init_cpu_err;
-
- load_rv2p_fw(bp, text, rc /* == len */, RV2P_PROC2);
+ load_rv2p_fw(bp, RV2P_PROC1, &rv2p_fw->proc1);
+ load_rv2p_fw(bp, RV2P_PROC2, &rv2p_fw->proc2);
/* Initialize the RX Processor. */
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- fw = &bnx2_rxp_fw_09;
- else
- fw = &bnx2_rxp_fw_06;
-
- fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg_rxp, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_rxp, &mips_fw->rxp);
if (rc)
goto init_cpu_err;
/* Initialize the TX Processor. */
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- fw = &bnx2_txp_fw_09;
- else
- fw = &bnx2_txp_fw_06;
-
- fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg_txp, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_txp, &mips_fw->txp);
if (rc)
goto init_cpu_err;
/* Initialize the TX Patch-up Processor. */
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- fw = &bnx2_tpat_fw_09;
- else
- fw = &bnx2_tpat_fw_06;
-
- fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg_tpat, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_tpat, &mips_fw->tpat);
if (rc)
goto init_cpu_err;
/* Initialize the Completion Processor. */
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- fw = &bnx2_com_fw_09;
- else
- fw = &bnx2_com_fw_06;
-
- fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg_com, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_com, &mips_fw->com);
if (rc)
goto init_cpu_err;
/* Initialize the Command Processor. */
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- fw = &bnx2_cp_fw_09;
- else
- fw = &bnx2_cp_fw_06;
-
- fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg_cp, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_cp, &mips_fw->cp);
init_cpu_err:
- vfree(text);
return rc;
}
@@ -7473,9 +7525,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
/* 5708 cannot support DMA addresses > 40-bit. */
if (CHIP_NUM(bp) == CHIP_NUM_5708)
- persist_dma_mask = dma_mask = DMA_40BIT_MASK;
+ persist_dma_mask = dma_mask = DMA_BIT_MASK(40);
else
- persist_dma_mask = dma_mask = DMA_64BIT_MASK;
+ persist_dma_mask = dma_mask = DMA_BIT_MASK(64);
/* Configure DMA attributes. */
if (pci_set_dma_mask(pdev, dma_mask) == 0) {
@@ -7486,7 +7538,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
"pci_set_consistent_dma_mask failed, aborting.\n");
goto err_out_unmap;
}
- } else if ((rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
+ } else if ((rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) {
dev_err(&pdev->dev, "System does not support DMA, aborting.\n");
goto err_out_unmap;
}
@@ -7807,6 +7859,10 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, dev);
+ rc = bnx2_request_firmware(bp);
+ if (rc)
+ goto error;
+
memcpy(dev->dev_addr, bp->mac_addr, 6);
memcpy(dev->perm_addr, bp->mac_addr, 6);
@@ -7823,13 +7879,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if ((rc = register_netdev(dev))) {
dev_err(&pdev->dev, "Cannot register net device\n");
- if (bp->regview)
- iounmap(bp->regview);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
- free_netdev(dev);
- return rc;
+ goto error;
}
printk(KERN_INFO "%s: %s (%c%d) %s found at mem %lx, "
@@ -7843,6 +7893,20 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
bp->pdev->irq, dev->dev_addr);
return 0;
+
+error:
+ if (bp->mips_firmware)
+ release_firmware(bp->mips_firmware);
+ if (bp->rv2p_firmware)
+ release_firmware(bp->rv2p_firmware);
+
+ if (bp->regview)
+ iounmap(bp->regview);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+ free_netdev(dev);
+ return rc;
}
static void __devexit
@@ -7855,6 +7919,11 @@ bnx2_remove_one(struct pci_dev *pdev)
unregister_netdev(dev);
+ if (bp->mips_firmware)
+ release_firmware(bp->mips_firmware);
+ if (bp->rv2p_firmware)
+ release_firmware(bp->rv2p_firmware);
+
if (bp->regview)
iounmap(bp->regview);
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 704cbbcbf97..5b570e17c83 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -6885,6 +6885,8 @@ struct bnx2 {
u32 idle_chk_status_idx;
+ const struct firmware *mips_firmware;
+ const struct firmware *rv2p_firmware;
};
#define REG_RD(bp, offset) \
@@ -6915,44 +6917,41 @@ struct cpu_reg {
u32 mips_view_base;
};
-struct fw_info {
- const u32 ver_major;
- const u32 ver_minor;
- const u32 ver_fix;
-
- const u32 start_addr;
-
- /* Text section. */
- const u32 text_addr;
- const u32 text_len;
- const u32 text_index;
- __le32 *text;
- u8 *gz_text;
- const u32 gz_text_len;
-
- /* Data section. */
- const u32 data_addr;
- const u32 data_len;
- const u32 data_index;
- const u32 *data;
-
- /* SBSS section. */
- const u32 sbss_addr;
- const u32 sbss_len;
- const u32 sbss_index;
-
- /* BSS section. */
- const u32 bss_addr;
- const u32 bss_len;
- const u32 bss_index;
-
- /* Read-only section. */
- const u32 rodata_addr;
- const u32 rodata_len;
- const u32 rodata_index;
- const u32 *rodata;
+struct bnx2_fw_file_section {
+ __be32 addr;
+ __be32 len;
+ __be32 offset;
};
+struct bnx2_mips_fw_file_entry {
+ __be32 start_addr;
+ struct bnx2_fw_file_section text;
+ struct bnx2_fw_file_section data;
+ struct bnx2_fw_file_section rodata;
+};
+
+struct bnx2_rv2p_fw_file_entry {
+ struct bnx2_fw_file_section rv2p;
+ __be32 fixup[8];
+};
+
+struct bnx2_mips_fw_file {
+ struct bnx2_mips_fw_file_entry com;
+ struct bnx2_mips_fw_file_entry cp;
+ struct bnx2_mips_fw_file_entry rxp;
+ struct bnx2_mips_fw_file_entry tpat;
+ struct bnx2_mips_fw_file_entry txp;
+};
+
+struct bnx2_rv2p_fw_file {
+ struct bnx2_rv2p_fw_file_entry proc1;
+ struct bnx2_rv2p_fw_file_entry proc2;
+};
+
+#define RV2P_P1_FIXUP_PAGE_SIZE_IDX 0
+#define RV2P_BD_PAGE_SIZE_MSK 0xffff
+#define RV2P_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1)
+
#define RV2P_PROC1 0
#define RV2P_PROC2 1
diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h
index 6a4f1d695de..940eb91f209 100644
--- a/drivers/net/bnx2_fw.h
+++ b/drivers/net/bnx2_fw.h
@@ -4,883 +4,9 @@
*
* 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, except as noted below.
- *
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
+ * the Free Software Foundation.
*/
-static u8 bnx2_COM_b06FwText[] = {
- 0xcd, 0x7c, 0x0d, 0x70, 0x5c, 0xd7, 0x75, 0xde, 0xd9, 0xb7, 0xbb, 0xc0,
- 0x12, 0x04, 0xc1, 0x07, 0x68, 0x05, 0xad, 0x24, 0x24, 0xde, 0x87, 0x7d,
- 0x00, 0x56, 0x22, 0xe4, 0x3c, 0x32, 0x10, 0x0d, 0xb9, 0x5b, 0x72, 0xbd,
- 0x0b, 0x50, 0x90, 0x43, 0x23, 0x90, 0x84, 0x28, 0x6a, 0x86, 0xe3, 0x41,
- 0x97, 0xa0, 0x62, 0x69, 0xdc, 0x86, 0x1e, 0x2b, 0x29, 0xe5, 0x2a, 0xe6,
- 0x6a, 0x01, 0xca, 0x94, 0x02, 0x72, 0x61, 0x12, 0x04, 0xd5, 0x54, 0x6d,
- 0xd7, 0x0b, 0x80, 0x54, 0xd4, 0x25, 0x97, 0x94, 0xfc, 0xa3, 0x99, 0xd8,
- 0x21, 0x4a, 0xd1, 0x92, 0xed, 0x71, 0xa7, 0x92, 0xc7, 0x9d, 0xaa, 0x33,
- 0x9a, 0x94, 0xa5, 0xe4, 0xda, 0xf1, 0x34, 0x8d, 0x6a, 0x7b, 0x1a, 0x25,
- 0xb1, 0xf3, 0xfa, 0x7d, 0xf7, 0xdd, 0x0b, 0x2c, 0x20, 0x48, 0x56, 0x92,
- 0xf1, 0x4c, 0x30, 0xb3, 0xbc, 0xef, 0xde, 0x77, 0x7f, 0xcf, 0x39, 0xf7,
- 0x9c, 0xef, 0x9c, 0x7b, 0x1f, 0x77, 0x89, 0xb4, 0x88, 0xfe, 0xdb, 0x82,
- 0xdf, 0xc0, 0xbf, 0xf8, 0x9d, 0xfd, 0xdb, 0x3f, 0xb8, 0xf3, 0x83, 0x78,
- 0xdc, 0x69, 0xd9, 0x4d, 0x11, 0x96, 0x87, 0xf1, 0x8b, 0xe3, 0xb7, 0x43,
- 0x3f, 0x6f, 0xf4, 0x67, 0xb3, 0x41, 0x48, 0x64, 0xe2, 0x87, 0x22, 0xa1,
- 0x75, 0xef, 0x62, 0xef, 0xd2, 0xe6, 0xbd, 0xfe, 0xac, 0xf7, 0x59, 0xcf,
- 0xfe, 0x7b, 0xf4, 0x6d, 0xfe, 0xc2, 0xba, 0xf9, 0x16, 0xfd, 0x93, 0x98,
- 0x95, 0xb9, 0xfa, 0xb1, 0x9c, 0x2b, 0xb1, 0x70, 0xe6, 0xbb, 0xa3, 0xfb,
- 0x5d, 0x91, 0x6c, 0x6d, 0x5b, 0x32, 0x2f, 0x3f, 0xf3, 0x8b, 0xf1, 0x88,
- 0xb0, 0xfc, 0x97, 0x32, 0x3f, 0x3d, 0xfc, 0xb5, 0x0f, 0x39, 0x6f, 0x55,
- 0xc2, 0x12, 0xb3, 0x33, 0x6f, 0x8b, 0xdd, 0x2b, 0xb1, 0x2e, 0xb4, 0x79,
- 0xba, 0xef, 0x59, 0x4b, 0xda, 0x4c, 0x5f, 0xf6, 0x44, 0x38, 0x23, 0x63,
- 0x93, 0x33, 0x87, 0x7d, 0xcb, 0x95, 0xe2, 0x4d, 0x19, 0x37, 0x59, 0x92,
- 0xd6, 0xc1, 0xe9, 0x81, 0x0f, 0x09, 0xf2, 0x63, 0x93, 0xb5, 0x98, 0xe4,
- 0xea, 0xc5, 0x56, 0xcb, 0x75, 0x91, 0xc6, 0x8a, 0x37, 0x67, 0x24, 0xd6,
- 0x94, 0x79, 0xba, 0xf9, 0x25, 0x97, 0xe3, 0x27, 0x46, 0x73, 0xee, 0xcd,
- 0x12, 0x71, 0x7d, 0x7f, 0x1a, 0xe3, 0xef, 0xa9, 0xfd, 0xcc, 0x7f, 0x2c,
- 0x12, 0x8c, 0x6d, 0x65, 0x8a, 0x61, 0xa6, 0xa1, 0x4c, 0x72, 0xb4, 0xbb,
- 0xa6, 0xf2, 0x4d, 0x41, 0xde, 0x35, 0xf9, 0x2d, 0x41, 0x7e, 0x42, 0xe7,
- 0xed, 0x96, 0x60, 0x2d, 0xb1, 0x4d, 0x58, 0x4b, 0x2c, 0x92, 0x19, 0xda,
- 0x84, 0x3e, 0x63, 0xd1, 0x8c, 0x9b, 0x59, 0x52, 0xf5, 0x3e, 0xa1, 0xeb,
- 0x1d, 0x8c, 0x06, 0xed, 0x26, 0x47, 0x7b, 0x6b, 0x4c, 0x1f, 0x1e, 0xed,
- 0x51, 0xe9, 0xa3, 0xa3, 0x29, 0x95, 0x16, 0x55, 0xbd, 0x50, 0x66, 0x7a,
- 0xd4, 0x55, 0x69, 0x97, 0x2e, 0x4f, 0x8f, 0x26, 0x55, 0xda, 0xaf, 0x53,
- 0x4f, 0xa7, 0x03, 0x3a, 0x1d, 0xd4, 0x69, 0x46, 0xa7, 0x59, 0x9d, 0x0e,
- 0xe9, 0x7e, 0x46, 0x74, 0x7e, 0xaf, 0x4e, 0xc7, 0x74, 0x3a, 0xae, 0xd3,
- 0xfb, 0x75, 0xba, 0x4f, 0xcf, 0xeb, 0x93, 0x3a, 0x7f, 0x50, 0xcf, 0xef,
- 0x10, 0xe6, 0xf1, 0x93, 0x26, 0x2d, 0xbf, 0x58, 0x67, 0x52, 0xf6, 0xcf,
- 0xc4, 0xa4, 0x54, 0x0e, 0x4b, 0x5e, 0xf1, 0xb5, 0x3f, 0x2a, 0x2d, 0x31,
- 0x99, 0xaa, 0xc7, 0xe4, 0xaa, 0x12, 0xdb, 0x1f, 0xf8, 0x5f, 0xeb, 0xb3,
- 0xe5, 0x42, 0x3d, 0x2e, 0x97, 0xea, 0x12, 0x1a, 0xeb, 0xdb, 0x24, 0xd6,
- 0x89, 0x9b, 0x24, 0x6b, 0x87, 0x24, 0xac, 0xe8, 0x9b, 0x94, 0xdc, 0x4c,
- 0x27, 0xf2, 0x4e, 0x42, 0x64, 0x32, 0x1a, 0xf0, 0x33, 0x26, 0xe1, 0x79,
- 0xf2, 0x67, 0x7e, 0xf4, 0xa5, 0xb9, 0x84, 0x44, 0x8e, 0x27, 0xd1, 0x7f,
- 0xab, 0x44, 0xe7, 0xa5, 0x2b, 0x2c, 0x3d, 0x89, 0x07, 0x50, 0x63, 0xa8,
- 0x16, 0x91, 0xe1, 0x5a, 0x08, 0x3c, 0x8b, 0x41, 0x5e, 0x5a, 0xf1, 0xb3,
- 0xf1, 0x8b, 0xe3, 0x97, 0xc0, 0xef, 0x09, 0xf4, 0xd3, 0x25, 0xf9, 0x1a,
- 0xfb, 0xc4, 0xb8, 0x65, 0x8c, 0x5f, 0x76, 0xec, 0x09, 0xe1, 0x9c, 0x12,
- 0xf2, 0xb5, 0xbe, 0x60, 0x4e, 0x97, 0xea, 0xb1, 0x50, 0xee, 0xb4, 0x1c,
- 0xcc, 0x7b, 0x92, 0xb4, 0xdc, 0x16, 0x29, 0xd8, 0xa1, 0xe4, 0x64, 0xba,
- 0x43, 0x8a, 0xe3, 0x78, 0x57, 0x96, 0xac, 0x85, 0xbe, 0x0b, 0xb6, 0x4c,
- 0x04, 0xef, 0x58, 0xf6, 0x37, 0xd8, 0xb7, 0x8e, 0x4d, 0x01, 0xbe, 0x54,
- 0xfe, 0x63, 0x3c, 0xb3, 0xaf, 0xff, 0x17, 0x0e, 0xe6, 0xfc, 0xd7, 0xc8,
- 0xb3, 0xfc, 0xcb, 0x5b, 0x83, 0x3c, 0x9f, 0x59, 0xd7, 0x8c, 0x69, 0xd6,
- 0xca, 0xb1, 0xfb, 0xb0, 0x5e, 0x8e, 0xbf, 0xb2, 0x5e, 0xcc, 0xa3, 0x35,
- 0x94, 0x3f, 0x9d, 0x94, 0x23, 0xe5, 0x5d, 0x92, 0xf3, 0x7c, 0x7f, 0xbf,
- 0x27, 0x71, 0x4b, 0x7a, 0xec, 0x3c, 0xde, 0x56, 0x6b, 0x12, 0xca, 0x95,
- 0x0d, 0x3d, 0xd8, 0x6f, 0x04, 0x65, 0x9d, 0xa8, 0xdf, 0x16, 0x1a, 0x3a,
- 0x8d, 0xb9, 0x67, 0x48, 0x17, 0xc8, 0xae, 0xd7, 0x93, 0x98, 0xc4, 0x78,
- 0x0b, 0xb5, 0x1e, 0xef, 0xb2, 0xd8, 0xe8, 0xb3, 0x03, 0x75, 0x48, 0x23,
- 0xf6, 0xc5, 0x3e, 0xd9, 0x5f, 0x2b, 0xda, 0xc6, 0xf1, 0x8e, 0x73, 0xf2,
- 0xfd, 0x9c, 0x67, 0x33, 0x2f, 0x15, 0xd0, 0xad, 0x42, 0xba, 0xb5, 0x74,
- 0xc9, 0x99, 0x1a, 0xc7, 0xd8, 0x68, 0xde, 0xb7, 0xfe, 0x23, 0x9b, 0x77,
- 0x02, 0xfd, 0xc7, 0x91, 0x6e, 0x0e, 0xe5, 0x4e, 0xfa, 0x18, 0x3f, 0x81,
- 0xe7, 0x8d, 0xd6, 0x70, 0x55, 0xcb, 0x60, 0x02, 0x73, 0x8f, 0xcb, 0x45,
- 0x25, 0x87, 0x9b, 0x25, 0x0c, 0x39, 0x24, 0x8f, 0xdb, 0xe7, 0x6f, 0x97,
- 0x42, 0xdc, 0x49, 0x52, 0x87, 0x76, 0xef, 0xd8, 0x84, 0x35, 0x6a, 0x6d,
- 0x78, 0x3c, 0x0e, 0x39, 0xbc, 0xdc, 0x6e, 0xa1, 0xc4, 0x12, 0xc7, 0xfe,
- 0x2d, 0x29, 0x4a, 0x7e, 0xf1, 0x91, 0x90, 0xb4, 0x58, 0xa8, 0xb7, 0x2d,
- 0x14, 0xd0, 0x80, 0xf4, 0xc9, 0x82, 0x3e, 0x21, 0x09, 0xf6, 0x73, 0x56,
- 0xba, 0x6b, 0xea, 0x7d, 0xd2, 0x52, 0xef, 0x86, 0xf0, 0x2e, 0x22, 0xa9,
- 0x1d, 0xe6, 0xfd, 0x10, 0xde, 0xdf, 0x24, 0x13, 0x36, 0xe6, 0x52, 0x7e,
- 0xc1, 0xca, 0x61, 0x8e, 0x1f, 0x89, 0xa8, 0xb5, 0xa2, 0xee, 0x44, 0x43,
- 0x3f, 0x13, 0xa8, 0xf7, 0x34, 0xc6, 0xc2, 0x7c, 0xcb, 0x49, 0xcc, 0xa5,
- 0x13, 0x73, 0xe1, 0x1c, 0x8b, 0x56, 0xae, 0x1e, 0x41, 0x7e, 0xda, 0xca,
- 0x9f, 0x3d, 0x8a, 0x67, 0xb1, 0xad, 0xcc, 0x0b, 0x4c, 0xd1, 0x7e, 0x5f,
- 0x43, 0xfb, 0x7d, 0x68, 0xcf, 0x31, 0xd8, 0x3e, 0x90, 0xff, 0xa2, 0x92,
- 0xc5, 0xe4, 0x7b, 0xd0, 0x23, 0xfc, 0xf7, 0xa0, 0xc7, 0xd7, 0x34, 0x3d,
- 0x7e, 0x26, 0xbf, 0x78, 0x7a, 0x5c, 0xfd, 0x05, 0xd1, 0x43, 0xa4, 0x70,
- 0x92, 0xcf, 0x11, 0x29, 0x2a, 0xbd, 0xc5, 0x7d, 0x4b, 0x79, 0xa7, 0xce,
- 0x22, 0x9d, 0x28, 0xc7, 0xd8, 0x03, 0xf5, 0x08, 0xd2, 0x67, 0x90, 0x6e,
- 0x0e, 0x8d, 0x9d, 0x7c, 0x13, 0xfc, 0xf7, 0xc5, 0xde, 0x61, 0xec, 0x47,
- 0x31, 0x61, 0x4b, 0x97, 0xd8, 0x1f, 0x84, 0xf1, 0xee, 0x74, 0xec, 0x82,
- 0x7c, 0x9f, 0xef, 0x43, 0xc6, 0xce, 0xe7, 0x66, 0x36, 0xbd, 0x9d, 0x55,
- 0x4f, 0x51, 0xd2, 0x33, 0x6b, 0x65, 0x22, 0xa1, 0x7c, 0x39, 0x39, 0x61,
- 0x65, 0xe2, 0xd0, 0x53, 0xcc, 0x0f, 0x86, 0x82, 0x39, 0x0f, 0xa0, 0xae,
- 0xd1, 0x59, 0x66, 0xee, 0x03, 0x98, 0xfb, 0x7a, 0xdd, 0x95, 0xc5, 0x5c,
- 0x38, 0x07, 0xce, 0xab, 0xa8, 0x75, 0x10, 0xfb, 0x39, 0xa4, 0xfa, 0x09,
- 0x67, 0x06, 0x85, 0xb6, 0xb4, 0x30, 0xc3, 0x7d, 0xc0, 0x76, 0xec, 0x2b,
- 0xd0, 0xc9, 0x85, 0x9a, 0xe9, 0xa3, 0xd8, 0xd8, 0x07, 0xe6, 0x23, 0x5b,
- 0x2d, 0x37, 0x0a, 0xde, 0xb3, 0xab, 0xa3, 0x78, 0xf7, 0xb4, 0xe4, 0xce,
- 0xde, 0x61, 0x61, 0x0d, 0xe8, 0x97, 0x34, 0x1a, 0x83, 0xce, 0xe6, 0x3e,
- 0x8b, 0x49, 0x3e, 0xce, 0xb2, 0x49, 0x3d, 0x6e, 0x44, 0xb2, 0x2a, 0x9f,
- 0x6b, 0x5b, 0x9d, 0xc7, 0x0b, 0x7a, 0x3d, 0x19, 0xac, 0x87, 0x73, 0x30,
- 0x6b, 0xc9, 0x34, 0xac, 0xc5, 0xd0, 0x9a, 0xb4, 0xb0, 0xa1, 0xe3, 0x63,
- 0xda, 0x86, 0xb0, 0xdd, 0x74, 0x03, 0xef, 0xa6, 0xd1, 0x86, 0xb4, 0x47,
- 0x9d, 0x75, 0x76, 0x85, 0x36, 0x65, 0x08, 0xfd, 0x94, 0xe6, 0x2c, 0xc9,
- 0x7b, 0xb0, 0xd9, 0xde, 0xcd, 0x5a, 0x5e, 0x57, 0x65, 0x29, 0xba, 0xa1,
- 0x2c, 0x3d, 0x66, 0x05, 0xfa, 0x1a, 0xb6, 0x05, 0xf6, 0x67, 0x6a, 0xce,
- 0x49, 0x1b, 0x59, 0x2a, 0xcd, 0xbc, 0x1f, 0x59, 0x32, 0xed, 0x63, 0x90,
- 0x5d, 0x33, 0xc6, 0xfa, 0x39, 0x9b, 0x3a, 0x98, 0x63, 0x79, 0x48, 0x63,
- 0x15, 0x8e, 0x13, 0xd8, 0x86, 0xca, 0x1a, 0xdb, 0x70, 0x14, 0x6d, 0x25,
- 0x94, 0xef, 0x6b, 0x95, 0x03, 0x73, 0xa6, 0x8f, 0xa3, 0x4a, 0x66, 0x27,
- 0x67, 0x1c, 0x7b, 0x38, 0x2c, 0xd9, 0xe1, 0xd9, 0x41, 0x19, 0xaa, 0x77,
- 0x81, 0xa7, 0x6f, 0xfb, 0xb0, 0x9d, 0x1f, 0x8c, 0x8a, 0x0b, 0xbd, 0x88,
- 0x35, 0x0f, 0x80, 0xc6, 0xf5, 0xa8, 0x58, 0x19, 0x0f, 0x69, 0x23, 0xd6,
- 0x8a, 0x44, 0x86, 0xd7, 0xe4, 0x9b, 0x50, 0x07, 0x7d, 0x0f, 0xac, 0xaf,
- 0x07, 0xf9, 0x04, 0x6d, 0x73, 0xde, 0xcf, 0x7c, 0xd8, 0x61, 0x6d, 0xb3,
- 0x58, 0x4a, 0x3d, 0x61, 0x74, 0xc4, 0x6f, 0x60, 0x7f, 0xab, 0xbd, 0x50,
- 0x04, 0x76, 0x41, 0x1f, 0xa2, 0xe4, 0xb4, 0x54, 0x7f, 0xce, 0xec, 0x7b,
- 0x55, 0xbe, 0x67, 0x80, 0xb2, 0x57, 0x01, 0x26, 0xe0, 0x9a, 0x16, 0xd5,
- 0x5e, 0xcf, 0xdb, 0x71, 0x99, 0x2e, 0x73, 0x3d, 0x8b, 0x92, 0xaa, 0xfd,
- 0x7b, 0xc9, 0x9f, 0x15, 0xf9, 0xd6, 0x0c, 0xeb, 0x7d, 0x55, 0xd7, 0x7b,
- 0x01, 0xf5, 0x52, 0xc9, 0xa1, 0x90, 0x03, 0x3b, 0xe0, 0x60, 0x9b, 0x6c,
- 0x4b, 0x22, 0xb5, 0x47, 0xf0, 0x1b, 0xa2, 0x91, 0x41, 0xbd, 0x00, 0xfb,
- 0xbc, 0x00, 0x7a, 0x88, 0xdc, 0x5d, 0x6e, 0x86, 0x3e, 0xf9, 0x9f, 0x98,
- 0x6b, 0x5c, 0x9e, 0xc4, 0x3a, 0x5e, 0x9a, 0x21, 0xbe, 0xfa, 0xaa, 0x2c,
- 0xcd, 0x10, 0x6f, 0xbd, 0x20, 0xd3, 0x33, 0x29, 0xef, 0x5b, 0xa0, 0xf3,
- 0x19, 0xe1, 0x5a, 0xb6, 0x79, 0x48, 0x81, 0x05, 0x9d, 0xe4, 0xe3, 0xd0,
- 0x67, 0x7d, 0x3b, 0x82, 0xfe, 0x7a, 0x74, 0x7f, 0x6e, 0xcd, 0x91, 0xab,
- 0x36, 0xf5, 0xd3, 0x3b, 0xf7, 0x78, 0x4e, 0xef, 0xf1, 0x31, 0xaf, 0x4b,
- 0x2c, 0xec, 0xeb, 0xec, 0x78, 0x11, 0xd6, 0x8f, 0xfb, 0xfa, 0x6d, 0x6b,
- 0x15, 0xff, 0x24, 0x80, 0x59, 0x1d, 0x65, 0xef, 0xfe, 0x6e, 0x7b, 0xbc,
- 0x71, 0x6f, 0x73, 0xfc, 0x36, 0xb4, 0x89, 0x20, 0x7d, 0xef, 0x7d, 0x8d,
- 0x3e, 0x1a, 0xda, 0x0e, 0x72, 0x5f, 0xa0, 0xcd, 0xbf, 0x05, 0x2d, 0x48,
- 0xff, 0xf7, 0xb3, 0x9f, 0x6f, 0x0b, 0xbf, 0xaf, 0xfd, 0x3c, 0xfe, 0x5e,
- 0xfb, 0xb9, 0x71, 0x2f, 0x5f, 0x20, 0x2d, 0x30, 0xb6, 0xcc, 0x06, 0xb2,
- 0xd5, 0x03, 0x5a, 0x27, 0x21, 0xa7, 0x98, 0x43, 0xf9, 0x6f, 0xfd, 0x6c,
- 0x24, 0xc0, 0x73, 0x81, 0x3c, 0xb1, 0x9e, 0xa9, 0x13, 0xe8, 0xde, 0xa1,
- 0xfa, 0x55, 0xa5, 0x67, 0x2f, 0x2a, 0x3d, 0xeb, 0x1c, 0x2d, 0x0a, 0xe5,
- 0xed, 0xf6, 0x30, 0xe9, 0x7e, 0xc1, 0xfb, 0x7d, 0xcc, 0xd1, 0x49, 0x26,
- 0xad, 0x9e, 0xa2, 0x65, 0xfd, 0xbe, 0x1c, 0x5c, 0x78, 0x58, 0x0e, 0x96,
- 0xd9, 0xc7, 0x2e, 0xbc, 0x77, 0x51, 0xb6, 0x09, 0xba, 0x96, 0x3a, 0xfd,
- 0xed, 0x50, 0x30, 0x96, 0x05, 0xfb, 0xb5, 0x1c, 0xba, 0xbb, 0x7e, 0x25,
- 0x94, 0x5b, 0xe0, 0xde, 0x45, 0x79, 0xbd, 0x51, 0xe7, 0x1b, 0x7d, 0xff,
- 0x0a, 0xc6, 0x34, 0x72, 0xee, 0x35, 0xe8, 0xd4, 0x69, 0xe2, 0x41, 0x2b,
- 0xe7, 0x91, 0x7f, 0xb4, 0x2d, 0x8f, 0xd8, 0xc1, 0xfa, 0x0f, 0x81, 0x66,
- 0xb4, 0x49, 0xa4, 0x21, 0xec, 0x61, 0x84, 0xfb, 0x97, 0xcf, 0xe2, 0x87,
- 0x33, 0xdc, 0x83, 0x12, 0x09, 0x67, 0x80, 0x7f, 0xe3, 0xac, 0xb3, 0x0b,
- 0x73, 0x0e, 0xf6, 0x77, 0x71, 0x65, 0x7f, 0x77, 0xcb, 0xc4, 0x42, 0x16,
- 0x3a, 0x20, 0xaf, 0xfa, 0x89, 0xba, 0x6b, 0x6c, 0x0b, 0xea, 0x27, 0x35,
- 0x1f, 0x36, 0x1b, 0xfd, 0x87, 0x32, 0x4f, 0x97, 0x35, 0x35, 0x94, 0x19,
- 0x7e, 0x15, 0x30, 0x16, 0x6d, 0xc4, 0x88, 0xc6, 0x3d, 0xbe, 0x9f, 0x27,
- 0x9f, 0xfb, 0xf7, 0x09, 0xf7, 0xc4, 0xa5, 0x72, 0xd1, 0x0e, 0x2b, 0xd9,
- 0x5c, 0xfc, 0xd8, 0xaa, 0x6c, 0x02, 0x27, 0xab, 0x5e, 0x48, 0x5b, 0xce,
- 0xa5, 0x15, 0xb4, 0x1c, 0xc2, 0x1a, 0x40, 0xb3, 0xce, 0x10, 0xe8, 0xd6,
- 0x2a, 0x85, 0xfa, 0x2e, 0xfd, 0x8e, 0xe5, 0x11, 0x19, 0x8b, 0x1b, 0x3b,
- 0xf4, 0xe7, 0x5b, 0x03, 0xac, 0x8b, 0x3a, 0xe5, 0xff, 0x1d, 0x0e, 0x64,
- 0xdf, 0x96, 0xc2, 0xe9, 0x21, 0xc8, 0x18, 0xb1, 0xd8, 0x26, 0x2d, 0x63,
- 0xec, 0x07, 0xe5, 0x67, 0x29, 0xc3, 0xa2, 0xf5, 0xe7, 0x20, 0xd2, 0x1f,
- 0x87, 0x69, 0xb7, 0xd9, 0x57, 0xe1, 0xb4, 0x69, 0x6f, 0xe6, 0xd1, 0xb1,
- 0xd2, 0xcf, 0x98, 0x67, 0x49, 0x58, 0xcd, 0x05, 0x65, 0x67, 0xd7, 0xce,
- 0xc5, 0xea, 0x34, 0x73, 0x79, 0x34, 0x1c, 0xcc, 0xa5, 0xa3, 0xa1, 0xaf,
- 0x78, 0xc3, 0x5c, 0x9a, 0x30, 0x97, 0xb8, 0xb2, 0x37, 0x9c, 0xcb, 0x05,
- 0xf0, 0xbe, 0x70, 0xf6, 0xc6, 0xeb, 0x82, 0x36, 0xf1, 0x86, 0x36, 0x9d,
- 0xeb, 0xda, 0xb0, 0xbe, 0x19, 0x03, 0xef, 0xce, 0x5e, 0xdd, 0x1c, 0xb4,
- 0x61, 0xbd, 0x26, 0xd8, 0x37, 0xbe, 0x53, 0x7e, 0x5b, 0x83, 0xfc, 0x1f,
- 0x84, 0xfc, 0x1b, 0xb9, 0x32, 0xb6, 0xd9, 0xf0, 0x75, 0x53, 0x28, 0x7f,
- 0xf2, 0x03, 0xf4, 0x3d, 0x43, 0x63, 0xe5, 0x25, 0xf8, 0x0f, 0x49, 0x29,
- 0xa4, 0xe1, 0x9b, 0xd8, 0x83, 0xa2, 0xfc, 0x89, 0x34, 0x7c, 0x16, 0x7b,
- 0xb3, 0xc2, 0x5b, 0x85, 0x74, 0xbf, 0xb6, 0x59, 0xdf, 0x97, 0x09, 0xc8,
- 0x70, 0x21, 0x9d, 0xc6, 0x78, 0xd0, 0xd5, 0x6e, 0x2f, 0xda, 0x71, 0xdc,
- 0xb7, 0x22, 0xb4, 0x23, 0x17, 0xca, 0x1f, 0x47, 0x7e, 0x33, 0xde, 0xff,
- 0xa9, 0x9e, 0x4f, 0x1b, 0xea, 0x7c, 0x5a, 0xf9, 0x26, 0x17, 0x54, 0x1d,
- 0xf6, 0x71, 0x19, 0xf9, 0x3b, 0x50, 0x07, 0x9b, 0x1c, 0x12, 0x68, 0xb9,
- 0x3b, 0xf1, 0xfb, 0x36, 0xca, 0x3e, 0x84, 0xb2, 0x2f, 0xa3, 0xec, 0x76,
- 0xe4, 0x5f, 0x5c, 0xd7, 0xef, 0x36, 0xe4, 0x1f, 0xc3, 0x7b, 0xac, 0xd3,
- 0xfe, 0x06, 0xde, 0xdf, 0x81, 0xdf, 0x97, 0xd7, 0xd5, 0xf9, 0x37, 0xeb,
- 0xf2, 0xc6, 0x2f, 0xf8, 0x63, 0x2d, 0x73, 0xc6, 0x27, 0x08, 0xf4, 0xe8,
- 0x54, 0xb9, 0x35, 0x34, 0x7c, 0x3a, 0x16, 0xda, 0x73, 0x9a, 0x78, 0x23,
- 0xa2, 0xfc, 0x80, 0x08, 0xfc, 0x80, 0xe9, 0x39, 0x3a, 0x88, 0x11, 0x94,
- 0x11, 0xbb, 0xcb, 0x40, 0x93, 0xf4, 0x78, 0x57, 0xb0, 0x4f, 0x0a, 0xb5,
- 0x2e, 0xe4, 0xb9, 0x7f, 0x20, 0x63, 0xb5, 0x16, 0xc8, 0x75, 0x4f, 0xba,
- 0x0a, 0x19, 0x3b, 0x00, 0xdf, 0x64, 0x02, 0x36, 0x70, 0xa2, 0xd6, 0x25,
- 0x0f, 0xd4, 0xae, 0x44, 0x02, 0x39, 0x32, 0x63, 0x3f, 0xbd, 0x6e, 0xec,
- 0x18, 0xfd, 0x0a, 0xc8, 0xfd, 0xfc, 0xe8, 0xfe, 0x39, 0x8e, 0x6f, 0x75,
- 0x47, 0xa4, 0x0d, 0x73, 0xa0, 0xff, 0x28, 0xbd, 0x11, 0xe9, 0x49, 0x4e,
- 0x29, 0x07, 0xb5, 0x28, 0xe1, 0x4c, 0x0f, 0xec, 0x83, 0xca, 0xc3, 0x5f,
- 0x84, 0xbe, 0xab, 0xad, 0xfa, 0x91, 0xc3, 0x2b, 0x7e, 0x64, 0x17, 0xfc,
- 0xcc, 0x17, 0x23, 0xc1, 0xde, 0x6f, 0x85, 0x6e, 0xb8, 0x9e, 0x38, 0x47,
- 0xe9, 0x77, 0xee, 0xf1, 0x9c, 0xd7, 0xae, 0xf3, 0x94, 0x65, 0xe8, 0x0b,
- 0x2b, 0xaa, 0xf4, 0x95, 0x58, 0x78, 0x37, 0x40, 0xf9, 0x45, 0x7e, 0xa1,
- 0x71, 0x7f, 0xff, 0x0e, 0xf6, 0x32, 0xdf, 0x1b, 0x39, 0xc3, 0x3f, 0x4a,
- 0xc6, 0x18, 0xbf, 0xf8, 0x8b, 0x75, 0x6b, 0x3b, 0xb0, 0x6e, 0x6d, 0x91,
- 0x15, 0xba, 0x72, 0x8d, 0x51, 0xac, 0x71, 0x69, 0x8e, 0xb4, 0xed, 0x87,
- 0x7c, 0x8a, 0x1b, 0x11, 0xca, 0x31, 0xf5, 0x6a, 0x1b, 0x74, 0x35, 0x69,
- 0x17, 0x11, 0xc6, 0x3c, 0x26, 0xb0, 0xa6, 0x09, 0xac, 0x69, 0xa2, 0x81,
- 0x8e, 0x07, 0x56, 0xd6, 0x64, 0xe6, 0x8d, 0x7a, 0x6a, 0xbf, 0xf1, 0x99,
- 0x3f, 0xe8, 0xa9, 0x36, 0x83, 0x69, 0x38, 0x97, 0xdc, 0xba, 0xb9, 0x90,
- 0x16, 0x9c, 0xcb, 0xca, 0x3c, 0xe2, 0x8c, 0x1c, 0x1d, 0xac, 0x91, 0xaf,
- 0x1c, 0x73, 0xaf, 0x4c, 0x96, 0x3f, 0xa0, 0xe7, 0xd1, 0x8a, 0x79, 0x8c,
- 0x41, 0x6f, 0x70, 0x3c, 0xec, 0xff, 0xda, 0x38, 0x9e, 0xe3, 0xe4, 0xbf,
- 0x9e, 0x8b, 0xa1, 0x05, 0xfd, 0xb6, 0x84, 0xc6, 0xe2, 0x86, 0x5e, 0xae,
- 0xc2, 0x0e, 0x97, 0xca, 0xff, 0x6d, 0x6b, 0x30, 0xb7, 0xa4, 0x9e, 0x47,
- 0x40, 0x63, 0x60, 0x78, 0x60, 0xa9, 0xbc, 0xd6, 0x07, 0x8d, 0x74, 0xbd,
- 0xbb, 0x49, 0xeb, 0x2b, 0xc8, 0x40, 0x63, 0xf9, 0xa7, 0x9a, 0x56, 0xeb,
- 0x32, 0x3f, 0xaf, 0xf3, 0x5b, 0x42, 0xc3, 0x27, 0x4d, 0xd9, 0xd5, 0xa6,
- 0x77, 0xf6, 0xf7, 0xd5, 0x26, 0xa3, 0x3f, 0x2e, 0x95, 0x1b, 0xf7, 0xfb,
- 0x21, 0x2b, 0xb0, 0x3b, 0x45, 0x29, 0x0d, 0x64, 0xa1, 0xe7, 0x68, 0x7f,
- 0x86, 0xac, 0xc0, 0xf6, 0xb0, 0xce, 0x21, 0x85, 0x1d, 0x23, 0x99, 0x2a,
- 0xe5, 0x1e, 0xb4, 0xac, 0x8d, 0xe6, 0x66, 0x7c, 0x7f, 0xca, 0x5b, 0x4e,
- 0x84, 0x85, 0x7a, 0x99, 0xb8, 0x8d, 0xe5, 0xcf, 0xa0, 0x1c, 0x76, 0xbd,
- 0x3e, 0x26, 0x6c, 0xb7, 0x31, 0x3e, 0x4b, 0x6a, 0x7c, 0x16, 0x00, 0xbb,
- 0x9c, 0xc2, 0x53, 0x4f, 0x8d, 0xc2, 0xfe, 0xeb, 0xe7, 0xa7, 0xf1, 0x9c,
- 0x6c, 0xc4, 0x80, 0xe8, 0xb7, 0x32, 0x9a, 0x9b, 0x53, 0x76, 0x00, 0xfb,
- 0x81, 0xbc, 0x3a, 0x03, 0x5e, 0x85, 0x64, 0x5a, 0xd9, 0x04, 0xce, 0x83,
- 0xed, 0x2a, 0xa3, 0xdd, 0x8b, 0x4c, 0xab, 0xa3, 0xee, 0x62, 0x58, 0x0e,
- 0xc4, 0x83, 0xb6, 0xcc, 0x27, 0x17, 0x8d, 0xdd, 0x6e, 0x91, 0x68, 0x86,
- 0xba, 0xcd, 0x49, 0x03, 0x87, 0x62, 0x3d, 0x47, 0x47, 0xa7, 0x5d, 0xda,
- 0xcb, 0xff, 0x03, 0x79, 0x68, 0x91, 0x26, 0x25, 0x27, 0x4f, 0xea, 0xb1,
- 0xce, 0x60, 0xac, 0xad, 0x98, 0x6b, 0x18, 0x3a, 0x32, 0x92, 0xc0, 0x38,
- 0x87, 0x2d, 0x77, 0x1b, 0xc6, 0xa3, 0xd7, 0xd8, 0x25, 0x53, 0x75, 0xca,
- 0xfa, 0xdf, 0x44, 0x56, 0x7d, 0xc5, 0x13, 0x68, 0x67, 0x7c, 0x14, 0x8e,
- 0x57, 0x05, 0x46, 0x69, 0xc1, 0x3a, 0x1c, 0x3b, 0x17, 0x86, 0xed, 0x9b,
- 0x33, 0x75, 0x38, 0xa7, 0xe3, 0xa3, 0xa9, 0xc5, 0x14, 0xfa, 0xea, 0xa2,
- 0xec, 0x41, 0xe6, 0xc2, 0xf8, 0xb1, 0x6f, 0xb6, 0x83, 0x4e, 0x1e, 0x34,
- 0x76, 0x7c, 0xb5, 0xbd, 0x69, 0xd7, 0xbd, 0x38, 0xa2, 0x65, 0xf7, 0xaf,
- 0xfc, 0xec, 0x38, 0xdf, 0x37, 0xc6, 0x07, 0x4c, 0x3b, 0x53, 0x27, 0xac,
- 0xf5, 0xf1, 0x7d, 0xd1, 0xd5, 0x79, 0x3e, 0x35, 0x1a, 0xf8, 0x31, 0x12,
- 0xc9, 0xf7, 0x0d, 0x6a, 0xbe, 0x3d, 0x8d, 0x32, 0xb6, 0xc7, 0x5e, 0xa8,
- 0x37, 0x62, 0xf0, 0xa0, 0xdf, 0x22, 0xb0, 0x47, 0xa9, 0xdc, 0x04, 0x5d,
- 0x93, 0x6d, 0x0f, 0x62, 0x22, 0xef, 0x85, 0xbb, 0xc1, 0x53, 0xf4, 0x53,
- 0x5a, 0x69, 0xab, 0xe2, 0x93, 0xa3, 0x2f, 0xa1, 0xff, 0x23, 0xe5, 0x60,
- 0xaf, 0x05, 0x74, 0x20, 0x5e, 0x0a, 0xc9, 0x92, 0x9b, 0x84, 0x7f, 0x47,
- 0x3b, 0x94, 0x94, 0x97, 0x5d, 0x83, 0x9f, 0x88, 0x9d, 0x50, 0xbf, 0xce,
- 0xf9, 0x70, 0xdd, 0x27, 0xb0, 0x6e, 0x5f, 0x66, 0xbd, 0x40, 0x3e, 0xfa,
- 0xb0, 0x37, 0xff, 0x53, 0xc4, 0x39, 0x4a, 0x3f, 0xe0, 0x6a, 0xa4, 0x71,
- 0x5d, 0xc6, 0x9e, 0x3d, 0xa5, 0x63, 0x93, 0x27, 0x34, 0x2f, 0x2b, 0xe0,
- 0xe5, 0xb6, 0xa4, 0x2d, 0xbd, 0x98, 0x3b, 0xea, 0xf4, 0xf7, 0x00, 0x8f,
- 0xd3, 0xd7, 0x4b, 0x60, 0x3e, 0x36, 0x64, 0x7d, 0xab, 0xb6, 0xfb, 0x9f,
- 0x89, 0x52, 0x5f, 0xb4, 0xab, 0xb8, 0xe7, 0x09, 0x25, 0x6b, 0x81, 0xec,
- 0x85, 0xf5, 0x7b, 0xc3, 0xef, 0x30, 0xcd, 0xae, 0xac, 0xc6, 0xf9, 0x8c,
- 0xae, 0x66, 0xfd, 0x39, 0xd4, 0x0f, 0x61, 0x4d, 0xbe, 0x3f, 0xa9, 0xe6,
- 0x3b, 0x0f, 0x5e, 0x87, 0xa5, 0xb4, 0x22, 0x8f, 0xf3, 0x90, 0xc7, 0x26,
- 0x91, 0x8e, 0x46, 0xb9, 0xa1, 0xac, 0xbc, 0x1e, 0x65, 0x4c, 0x2e, 0x69,
- 0x19, 0xde, 0x45, 0x88, 0xdd, 0x90, 0x37, 0xbc, 0xe3, 0xf3, 0x46, 0x18,
- 0x90, 0x71, 0x27, 0xdf, 0x5f, 0xf2, 0x18, 0x23, 0x6c, 0x96, 0xa2, 0x1d,
- 0xe0, 0x97, 0x92, 0x47, 0x39, 0xcd, 0x25, 0x23, 0xe2, 0x24, 0x0e, 0xc8,
- 0x9b, 0xe8, 0x3b, 0x9b, 0x8e, 0x4a, 0xe0, 0xa7, 0x4e, 0x80, 0x6e, 0xcb,
- 0xb6, 0xef, 0xbf, 0x04, 0xbf, 0xba, 0x0a, 0xbf, 0x66, 0x09, 0x69, 0xa9,
- 0x86, 0x3d, 0xd0, 0x12, 0xc1, 0x9e, 0x32, 0x7b, 0x25, 0x26, 0x15, 0xd4,
- 0x59, 0xc0, 0xbb, 0xc7, 0x6b, 0x86, 0xcb, 0xbe, 0x6f, 0x61, 0x5d, 0xfb,
- 0xdd, 0xbf, 0xf6, 0x0b, 0xf1, 0xc6, 0xba, 0x06, 0x77, 0x11, 0x33, 0x11,
- 0xf3, 0x10, 0xab, 0xf0, 0x1d, 0xf1, 0xc7, 0x61, 0xcc, 0x85, 0x32, 0xdc,
- 0x26, 0xb1, 0x8c, 0x93, 0x18, 0x11, 0xa3, 0x8b, 0x5f, 0x03, 0xff, 0x8b,
- 0x7e, 0xb3, 0xdb, 0x25, 0xcf, 0x83, 0xd7, 0xcf, 0xd5, 0x0d, 0xef, 0x93,
- 0xe0, 0xbd, 0x53, 0x2c, 0x8a, 0x2f, 0x17, 0x3d, 0x37, 0xf9, 0x39, 0xa4,
- 0xdf, 0xf1, 0x7e, 0x85, 0xb4, 0x78, 0x0a, 0x26, 0x0f, 0x38, 0x1b, 0x7a,
- 0x75, 0xd6, 0xe0, 0xc7, 0x36, 0xe2, 0x7d, 0x4d, 0xc7, 0xab, 0xe8, 0xd3,
- 0xb1, 0x2d, 0x80, 0xa5, 0x3b, 0x51, 0x2f, 0x90, 0x6b, 0x53, 0x76, 0x18,
- 0x75, 0x39, 0x07, 0xfa, 0x62, 0xdf, 0xc5, 0x5e, 0xf2, 0xfd, 0x7b, 0xbd,
- 0xc9, 0x86, 0x3d, 0x31, 0x0f, 0x1e, 0x28, 0xd9, 0x1c, 0x68, 0x17, 0xc6,
- 0xee, 0xa4, 0xbf, 0x43, 0xf9, 0x0a, 0x7c, 0x86, 0x8c, 0x0e, 0xd0, 0x26,
- 0x24, 0x55, 0xdc, 0x8f, 0xb6, 0xe7, 0x39, 0xd0, 0xfe, 0xd3, 0x35, 0xf2,
- 0xa1, 0x55, 0xe9, 0xfe, 0xe7, 0xcb, 0xb4, 0xef, 0x01, 0x46, 0x9b, 0x50,
- 0xb1, 0x5c, 0xda, 0x84, 0x34, 0x78, 0x13, 0xc4, 0xf0, 0x1e, 0x50, 0x6d,
- 0x59, 0x8f, 0x6d, 0x1b, 0xf9, 0xc7, 0x3a, 0x5b, 0x81, 0xaf, 0x28, 0x83,
- 0x6d, 0xc0, 0x25, 0xed, 0x72, 0x20, 0xdd, 0x0c, 0xba, 0x77, 0x28, 0x3c,
- 0x65, 0xb9, 0x1f, 0x86, 0xed, 0x02, 0xa6, 0xb3, 0x1d, 0x6f, 0xd5, 0xf7,
- 0xb8, 0x1d, 0x65, 0x3f, 0x05, 0xfd, 0x59, 0xb6, 0x49, 0xc7, 0xaf, 0x1f,
- 0xc6, 0xfe, 0xab, 0x6c, 0x0d, 0xe2, 0x22, 0xe4, 0x83, 0xd1, 0x03, 0xc6,
- 0xfe, 0xd9, 0x1a, 0x47, 0x92, 0x37, 0x41, 0x0c, 0xc5, 0x52, 0x75, 0x89,
- 0xe7, 0x1b, 0xfd, 0x16, 0xee, 0x3b, 0xdf, 0xbf, 0xe8, 0x29, 0x7b, 0x0a,
- 0x1e, 0xec, 0x86, 0x0d, 0x8b, 0x68, 0x5a, 0xb7, 0x82, 0xd6, 0x81, 0x8d,
- 0x4d, 0x76, 0x40, 0xef, 0xb8, 0x56, 0x53, 0x40, 0x3f, 0x62, 0x85, 0xbf,
- 0x85, 0x1f, 0x4f, 0xff, 0x81, 0x38, 0x81, 0x73, 0x47, 0xbb, 0x05, 0xd6,
- 0xa5, 0x2d, 0x7e, 0x0c, 0x63, 0x84, 0x25, 0xd9, 0xc9, 0xfc, 0x03, 0xba,
- 0x0d, 0x9f, 0x7d, 0xe9, 0xdd, 0xd1, 0x28, 0xcf, 0x83, 0x98, 0x27, 0xd7,
- 0x63, 0xe2, 0x7a, 0x5d, 0x4a, 0x07, 0xac, 0xca, 0x85, 0x99, 0x93, 0x19,
- 0x97, 0x73, 0x4b, 0x48, 0x07, 0xe6, 0x76, 0x37, 0x74, 0xf4, 0x8e, 0x0e,
- 0xf6, 0x69, 0xc6, 0x6e, 0x9c, 0x93, 0xc1, 0x2f, 0x81, 0xdd, 0x8d, 0xba,
- 0xcd, 0xb2, 0xa3, 0x93, 0xb4, 0xeb, 0x52, 0xba, 0x7a, 0x95, 0x1f, 0xb4,
- 0xbf, 0x1c, 0x7b, 0x7d, 0xf9, 0x1d, 0x0d, 0xf3, 0x6a, 0x3c, 0x03, 0x20,
- 0x76, 0xd8, 0x89, 0x77, 0x9c, 0x13, 0x9c, 0xe4, 0xb8, 0x2f, 0x7b, 0x14,
- 0xdd, 0x38, 0xb7, 0xc6, 0x79, 0x10, 0x43, 0x71, 0xce, 0x9c, 0xc3, 0x7a,
- 0x6c, 0xc2, 0xf9, 0xfc, 0x57, 0xcd, 0xc3, 0x4d, 0x7a, 0x5d, 0x06, 0xcb,
- 0xa4, 0xd0, 0xf6, 0x3f, 0x60, 0x0d, 0x7c, 0xe6, 0x3a, 0x8c, 0xcd, 0x4e,
- 0x05, 0xfd, 0xb4, 0x98, 0x78, 0xb0, 0x89, 0x6b, 0x70, 0x5e, 0xdc, 0x33,
- 0x86, 0x4e, 0x1d, 0x9a, 0x47, 0xbb, 0xd7, 0x8d, 0xeb, 0x78, 0x6b, 0xf5,
- 0xc8, 0xed, 0x0d, 0xeb, 0xeb, 0x97, 0xe2, 0x02, 0xe5, 0xe2, 0x36, 0xa4,
- 0x06, 0x13, 0x0c, 0x40, 0xf7, 0xbf, 0x2b, 0x26, 0xe0, 0x59, 0xd5, 0x78,
- 0x01, 0x3e, 0x99, 0xd2, 0xfd, 0x6a, 0x2f, 0xc6, 0x90, 0x87, 0x3e, 0xa9,
- 0xdf, 0x43, 0x19, 0x1b, 0x9f, 0xa8, 0x79, 0xe3, 0x93, 0xb5, 0x81, 0x71,
- 0xe2, 0xa9, 0x40, 0xe6, 0x50, 0xbf, 0x26, 0x13, 0xf0, 0xb3, 0xc7, 0x73,
- 0xaa, 0x9d, 0x8a, 0x31, 0x6c, 0xd0, 0x8f, 0x70, 0x3f, 0x4e, 0x04, 0x63,
- 0xc5, 0xc6, 0xf3, 0xd0, 0x41, 0x0b, 0xb3, 0xb0, 0x4b, 0xae, 0x93, 0xa5,
- 0x5c, 0xee, 0xf7, 0x9c, 0x11, 0x25, 0x7b, 0x71, 0x67, 0x8c, 0xbc, 0xac,
- 0xce, 0xfe, 0xb2, 0x2c, 0xcc, 0xf9, 0x72, 0x17, 0x74, 0xe1, 0x43, 0x90,
- 0x55, 0x39, 0x07, 0x45, 0x78, 0x0e, 0xca, 0xeb, 0x5c, 0x5c, 0xac, 0x53,
- 0x5d, 0x12, 0x3d, 0x96, 0x90, 0xc8, 0x31, 0x62, 0xcb, 0x94, 0x7d, 0x97,
- 0x08, 0xec, 0xd8, 0x8b, 0x1f, 0xb2, 0xc4, 0x19, 0xcc, 0x4a, 0x2a, 0xf9,
- 0x38, 0x6c, 0x6f, 0x15, 0x69, 0x49, 0x52, 0xe9, 0xb3, 0xe8, 0x2b, 0x7a,
- 0x0e, 0x75, 0xd1, 0x6e, 0xd3, 0x52, 0x12, 0xbf, 0x4e, 0x69, 0x59, 0x0a,
- 0xf6, 0x4a, 0xcb, 0xd2, 0x5a, 0xff, 0x7c, 0x68, 0xc5, 0x3f, 0xe7, 0xfb,
- 0xb7, 0x75, 0x5c, 0xe1, 0x8b, 0xfa, 0x8c, 0x81, 0x32, 0x42, 0x7b, 0xa4,
- 0x7c, 0x63, 0xe8, 0xfd, 0x2f, 0xc2, 0xc7, 0x02, 0x0e, 0x2c, 0xc3, 0x97,
- 0xca, 0xf8, 0xf2, 0xac, 0x57, 0xf4, 0x73, 0x03, 0xbe, 0xbc, 0xe6, 0xb9,
- 0xc5, 0x82, 0x38, 0x6f, 0x53, 0xdf, 0xfd, 0x85, 0xf7, 0x4f, 0xe4, 0xfe,
- 0x76, 0xe7, 0xfe, 0x6c, 0xa8, 0xe8, 0xb7, 0xc2, 0xb7, 0xba, 0x31, 0x73,
- 0x58, 0xf6, 0x6f, 0x5f, 0x86, 0x0f, 0x9c, 0xbd, 0x11, 0x38, 0x2b, 0x51,
- 0x50, 0xba, 0xea, 0x75, 0xe5, 0xb7, 0x7d, 0xa2, 0xe7, 0xb0, 0x6c, 0xd9,
- 0xee, 0xd8, 0xd7, 0xc2, 0xc4, 0x40, 0x87, 0x25, 0x0f, 0xfd, 0x9f, 0x0f,
- 0xbb, 0xf6, 0x5e, 0x71, 0x46, 0x1e, 0x11, 0x9e, 0x0d, 0xba, 0xd2, 0x7d,
- 0xcc, 0x4d, 0x7c, 0x32, 0xd4, 0x7b, 0xf0, 0x93, 0xc0, 0xae, 0xdd, 0xe7,
- 0x98, 0xf7, 0x25, 0xb6, 0xdd, 0xc6, 0x73, 0x5c, 0xba, 0x4f, 0x25, 0x25,
- 0x05, 0xba, 0xf4, 0x29, 0x9a, 0xf0, 0x6c, 0x22, 0x21, 0xbd, 0xc7, 0x88,
- 0x49, 0x14, 0x6d, 0xfa, 0x40, 0x9b, 0x34, 0x68, 0x03, 0x9f, 0x66, 0x9b,
- 0x7d, 0x0d, 0xe9, 0x65, 0x49, 0x0d, 0x7e, 0x0f, 0xb4, 0xe9, 0x03, 0x6d,
- 0x7a, 0xcf, 0x25, 0xd1, 0x1e, 0x7d, 0x2c, 0x75, 0x23, 0x6d, 0x91, 0x5f,
- 0xbb, 0xbe, 0x13, 0xcf, 0xae, 0xa4, 0x8e, 0xc5, 0x30, 0x46, 0x48, 0xf6,
- 0xf4, 0x14, 0x65, 0x78, 0x3b, 0x30, 0x74, 0xfc, 0xb0, 0x5c, 0x81, 0x1d,
- 0x2a, 0xc3, 0x7f, 0x7b, 0x76, 0xd0, 0x19, 0x5b, 0x86, 0x2e, 0xad, 0xdf,
- 0xed, 0xcb, 0x37, 0xb6, 0x7f, 0xd3, 0x4f, 0x5c, 0xef, 0xdc, 0x2f, 0xa1,
- 0x01, 0x99, 0x2e, 0x2b, 0xfb, 0x90, 0xc8, 0x85, 0x15, 0xd6, 0xc1, 0x1a,
- 0x8b, 0xb0, 0x31, 0x3c, 0xf3, 0x74, 0xa1, 0xeb, 0x1f, 0x91, 0x87, 0x2a,
- 0x53, 0xf8, 0x01, 0x77, 0xcf, 0xb0, 0xee, 0x41, 0xe0, 0xed, 0x87, 0xe5,
- 0xc0, 0x0c, 0xb0, 0x58, 0x06, 0xf3, 0x1e, 0x70, 0x81, 0xcb, 0x33, 0xcd,
- 0xd2, 0x86, 0x32, 0xd0, 0x76, 0xac, 0xbe, 0x1e, 0xd7, 0x2e, 0x83, 0x0f,
- 0x83, 0xf2, 0x27, 0xf5, 0x01, 0xf9, 0x4a, 0xbd, 0x5f, 0xbe, 0x04, 0xdb,
- 0xf2, 0x5c, 0xbd, 0x0b, 0x7b, 0x25, 0x01, 0x9e, 0x64, 0xc0, 0x1f, 0x4f,
- 0xbe, 0x5c, 0x4f, 0xcb, 0x17, 0x41, 0xab, 0xe7, 0xf1, 0x1b, 0x2e, 0xa7,
- 0x65, 0x4f, 0xb9, 0x5f, 0xf3, 0x88, 0xfc, 0x71, 0x31, 0x1f, 0x17, 0x6b,
- 0x77, 0x9e, 0x29, 0x62, 0xff, 0x2d, 0xd4, 0xdd, 0xb7, 0xaa, 0x34, 0xb2,
- 0x6d, 0xb6, 0x9c, 0x59, 0xb1, 0x2f, 0x45, 0xdf, 0x76, 0x9d, 0xa3, 0x13,
- 0xe0, 0x43, 0x15, 0xfb, 0x74, 0x4c, 0xd1, 0x7e, 0xd5, 0xf6, 0x54, 0x03,
- 0xdb, 0x63, 0xd6, 0x37, 0x5b, 0x90, 0xef, 0x48, 0xee, 0xc4, 0xb4, 0xec,
- 0x3f, 0xe9, 0xcb, 0x6f, 0x7a, 0x3e, 0xe4, 0x98, 0xba, 0x78, 0x80, 0x3a,
- 0x3e, 0x39, 0x11, 0xb6, 0x94, 0x9f, 0x1b, 0x60, 0x8d, 0xef, 0x75, 0x60,
- 0xcf, 0xa6, 0xb3, 0xd6, 0x94, 0xa4, 0x4e, 0x4c, 0x49, 0xf7, 0x09, 0xc8,
- 0x82, 0xc7, 0xbe, 0x96, 0x6d, 0xeb, 0x1d, 0xf2, 0xc0, 0x71, 0x9c, 0xc1,
- 0xbc, 0xb8, 0xf6, 0x5b, 0x92, 0xc6, 0xf8, 0x87, 0xa4, 0x07, 0x6d, 0x5c,
- 0xb4, 0xb9, 0xa6, 0xc6, 0x6e, 0xc5, 0xd8, 0xcd, 0x72, 0x24, 0xee, 0x40,
- 0xd6, 0x68, 0xc3, 0xff, 0xaf, 0xe4, 0xaa, 0x4c, 0x7f, 0x24, 0xb9, 0x33,
- 0x6f, 0x37, 0x4b, 0x0b, 0x9f, 0xa1, 0x1a, 0xe6, 0x59, 0xde, 0x8d, 0x94,
- 0xe5, 0xae, 0x58, 0xc7, 0x7f, 0x22, 0xb9, 0xf3, 0x1c, 0xfb, 0x2d, 0x94,
- 0x7f, 0x43, 0x72, 0xc7, 0x7f, 0x8a, 0xfc, 0x15, 0xa4, 0x6f, 0x23, 0x1d,
- 0x93, 0xee, 0xe3, 0xf0, 0x91, 0xcf, 0x7f, 0x1b, 0x79, 0xf8, 0x74, 0xe7,
- 0x8f, 0xa0, 0xde, 0x6e, 0xcc, 0xef, 0xde, 0x18, 0xb0, 0x06, 0x74, 0x5e,
- 0xec, 0xba, 0x60, 0xfe, 0x2c, 0x67, 0x19, 0xdf, 0x1d, 0x81, 0x4e, 0xfb,
- 0x1f, 0xd0, 0x69, 0xfa, 0x79, 0x81, 0x79, 0xea, 0x36, 0x3e, 0x4f, 0x81,
- 0x26, 0x87, 0x90, 0xf7, 0xe5, 0x61, 0x8f, 0xf6, 0x66, 0xa7, 0x8c, 0xdb,
- 0x45, 0xbf, 0x05, 0xb8, 0xa2, 0x15, 0xfb, 0x60, 0x6a, 0xc7, 0xc6, 0xfb,
- 0xe0, 0x68, 0xef, 0x61, 0xd9, 0xb4, 0xdd, 0xac, 0xdf, 0xac, 0xd7, 0xb5,
- 0x7f, 0xa8, 0xe8, 0xe0, 0x14, 0x3f, 0x29, 0x5c, 0x87, 0x9b, 0x78, 0xd2,
- 0xea, 0xbd, 0xff, 0x21, 0xec, 0x03, 0xeb, 0x3c, 0xf3, 0xc1, 0x3e, 0xb0,
- 0xce, 0x43, 0x37, 0xcc, 0xc3, 0x47, 0x9b, 0xef, 0x92, 0xe6, 0xe3, 0xab,
- 0xfb, 0xa0, 0xe9, 0xf8, 0xcf, 0xdf, 0x07, 0xcd, 0xe7, 0x51, 0xef, 0x3c,
- 0x69, 0x86, 0x3e, 0xce, 0x90, 0x66, 0x9d, 0x48, 0x1f, 0xc1, 0x5a, 0x39,
- 0xf7, 0x66, 0xcc, 0x3d, 0xc0, 0x45, 0x1f, 0x82, 0xbc, 0x7f, 0x62, 0xfb,
- 0x21, 0x5d, 0xfe, 0x9f, 0xfd, 0x91, 0xb8, 0x53, 0x91, 0x10, 0x69, 0x8a,
- 0xba, 0x55, 0xd2, 0xf0, 0x79, 0xd0, 0xe6, 0xa0, 0x74, 0x93, 0x7e, 0xd5,
- 0xbd, 0xc8, 0x17, 0xfd, 0x28, 0x7d, 0x74, 0x45, 0x4f, 0xe0, 0xa4, 0x01,
- 0x96, 0xbf, 0x0a, 0x99, 0x21, 0xc6, 0x7c, 0x5d, 0xf6, 0xcf, 0xf8, 0x32,
- 0xee, 0x71, 0xfd, 0x6f, 0x62, 0xfd, 0xd9, 0xed, 0x71, 0x59, 0x4e, 0xc6,
- 0x41, 0x93, 0x05, 0xe8, 0xf6, 0x2b, 0x12, 0xd0, 0x81, 0x31, 0xe7, 0x3d,
- 0xe2, 0x26, 0x86, 0xc5, 0x4d, 0x7f, 0x0f, 0x74, 0x18, 0x86, 0xec, 0xe7,
- 0xeb, 0x94, 0x9d, 0x57, 0x64, 0x08, 0x32, 0xf1, 0x86, 0xe7, 0xa4, 0x81,
- 0x85, 0xa0, 0x2f, 0x28, 0x17, 0x94, 0x89, 0x36, 0xa5, 0x93, 0xe6, 0x3d,
- 0xe7, 0xa9, 0xaa, 0xdc, 0x2a, 0xf3, 0x0a, 0x9b, 0xe2, 0xdd, 0x71, 0x65,
- 0x2f, 0xd2, 0x13, 0x56, 0x0f, 0x74, 0x74, 0x5a, 0xec, 0xde, 0x9b, 0x9b,
- 0xcd, 0x3d, 0x85, 0xc2, 0x89, 0x90, 0x4c, 0xf5, 0x92, 0x57, 0xec, 0x17,
- 0xf9, 0x6a, 0xd1, 0x8f, 0xb8, 0x6f, 0xf9, 0xa7, 0x3b, 0x93, 0xf2, 0xe9,
- 0xde, 0x15, 0xb9, 0xac, 0x88, 0x04, 0xfb, 0x62, 0x48, 0xf1, 0xc3, 0xcc,
- 0xdb, 0xac, 0xc5, 0xbc, 0xeb, 0x6f, 0x78, 0xc7, 0xb5, 0x50, 0xd6, 0x57,
- 0xf6, 0x4e, 0xf2, 0x9d, 0x73, 0xfd, 0x5d, 0xd0, 0xcc, 0x79, 0xaa, 0x24,
- 0xaf, 0x41, 0xf6, 0x40, 0xc3, 0xf3, 0x4c, 0x49, 0xc3, 0x29, 0xc8, 0xfd,
- 0xab, 0xb2, 0xe7, 0x04, 0xf7, 0xcc, 0xab, 0x58, 0xab, 0xd2, 0x25, 0xd0,
- 0x11, 0xec, 0xcf, 0x97, 0x69, 0x8f, 0xb1, 0x92, 0x5b, 0x13, 0x93, 0xf0,
- 0xe1, 0x26, 0x6c, 0x5f, 0x96, 0xbc, 0xa2, 0x2c, 0x0d, 0xa2, 0x4d, 0xf5,
- 0x11, 0xfc, 0xda, 0xf4, 0xda, 0x3e, 0x0b, 0xba, 0x3b, 0xc9, 0x8a, 0xf5,
- 0x19, 0xd0, 0xfd, 0x61, 0x49, 0x1d, 0x5f, 0xd1, 0x35, 0x90, 0xbb, 0x40,
- 0xd7, 0xa4, 0xce, 0xdb, 0x52, 0x2d, 0xbb, 0xf2, 0x71, 0xea, 0x90, 0x32,
- 0xd7, 0x05, 0x1d, 0xc3, 0xf3, 0xdb, 0x32, 0xf4, 0x4c, 0x19, 0x3a, 0x05,
- 0x3a, 0xe4, 0x4b, 0x28, 0xff, 0x22, 0xea, 0x3c, 0x0f, 0x9f, 0xe7, 0x39,
- 0x60, 0xbf, 0x8b, 0xc0, 0x14, 0x17, 0xca, 0x59, 0xed, 0x1b, 0xaa, 0xf5,
- 0xc2, 0x66, 0x29, 0x7f, 0x45, 0xaa, 0x15, 0xd2, 0xe3, 0x27, 0x8a, 0xb7,
- 0x39, 0x6f, 0x2b, 0x71, 0x16, 0x66, 0x26, 0x52, 0xa9, 0x18, 0x9a, 0x50,
- 0xf7, 0x31, 0xf6, 0x6f, 0x74, 0x65, 0xeb, 0x3a, 0x5d, 0x29, 0xf2, 0x62,
- 0x2d, 0xc0, 0x93, 0xc4, 0xc7, 0xa5, 0x99, 0xe4, 0xca, 0x19, 0x59, 0x09,
- 0x76, 0xf3, 0x32, 0xfc, 0x92, 0x58, 0xe6, 0x5b, 0x12, 0x3b, 0xe5, 0xfb,
- 0xdf, 0x87, 0xdd, 0x2c, 0x82, 0x27, 0x56, 0x08, 0xe5, 0x8b, 0x7c, 0x47,
- 0xb9, 0xa7, 0x6c, 0x87, 0x18, 0x2b, 0x97, 0x97, 0x51, 0x56, 0x55, 0x3e,
- 0xd3, 0xb7, 0x31, 0x1f, 0x3d, 0x3f, 0x55, 0xc6, 0x7a, 0xcd, 0x92, 0x1f,
- 0x4f, 0xcb, 0xe3, 0xe5, 0x6d, 0x76, 0x33, 0xda, 0x57, 0x16, 0xd9, 0xc6,
- 0x19, 0xe4, 0x95, 0x9d, 0x97, 0x17, 0x59, 0xde, 0x25, 0x57, 0x66, 0x32,
- 0x6a, 0x0e, 0xd5, 0xb9, 0x8c, 0x04, 0x31, 0x49, 0xea, 0x2b, 0xce, 0x15,
- 0x79, 0xfa, 0x96, 0x65, 0xda, 0xd9, 0x88, 0x14, 0x13, 0xa4, 0x75, 0x42,
- 0x2e, 0xcf, 0xc4, 0x37, 0x31, 0x86, 0x93, 0x73, 0xf9, 0x6c, 0x62, 0x07,
- 0xf6, 0xfb, 0x88, 0x1d, 0x30, 0x5e, 0x10, 0x81, 0x2d, 0x53, 0x31, 0x04,
- 0xa4, 0xc9, 0x06, 0x9f, 0x95, 0xef, 0x03, 0x6c, 0xb4, 0x8a, 0x1f, 0x89,
- 0x27, 0xb9, 0x5e, 0xa7, 0xb8, 0x0c, 0xfd, 0xd1, 0x91, 0x79, 0x49, 0xee,
- 0x99, 0x0f, 0xd6, 0x67, 0x9d, 0x11, 0xde, 0xd3, 0x90, 0x6b, 0x73, 0x8e,
- 0x77, 0x15, 0x98, 0x22, 0x1f, 0xf7, 0xc0, 0xaf, 0x3f, 0x8b, 0x41, 0x7f,
- 0x0d, 0x66, 0xad, 0x3d, 0x9b, 0x02, 0x7c, 0x16, 0x91, 0xa9, 0x19, 0x9e,
- 0xa9, 0x41, 0xb7, 0x01, 0x43, 0xfe, 0xf3, 0x08, 0x9e, 0x6b, 0xcc, 0xc3,
- 0x4f, 0x0b, 0x7c, 0x50, 0x3c, 0x07, 0xfd, 0x91, 0xe6, 0xd6, 0x3c, 0xd7,
- 0x1e, 0x92, 0x7b, 0x80, 0x4e, 0x04, 0xfd, 0x77, 0xeb, 0xb1, 0xba, 0xcf,
- 0xa4, 0x19, 0xc3, 0x93, 0x14, 0xf4, 0x45, 0x6e, 0x2e, 0x82, 0xb1, 0xba,
- 0x34, 0x36, 0xe7, 0xbb, 0xf5, 0xd8, 0xd3, 0xf8, 0x78, 0x69, 0x79, 0xa2,
- 0x6c, 0xb0, 0x5e, 0x1a, 0x36, 0x56, 0x22, 0x23, 0x7d, 0xbe, 0x7c, 0xdf,
- 0x23, 0xbd, 0xfa, 0x91, 0xf7, 0xe4, 0x68, 0xfd, 0xdd, 0xce, 0xce, 0x1a,
- 0xff, 0x5a, 0x31, 0x47, 0xfe, 0x30, 0x3f, 0xe0, 0x23, 0xce, 0xdd, 0x82,
- 0x3d, 0x2f, 0x01, 0x77, 0x59, 0xe7, 0xba, 0xd4, 0x3b, 0x0b, 0xd8, 0xa0,
- 0x3a, 0x03, 0xdd, 0x78, 0x8e, 0xe7, 0x89, 0xd0, 0x6d, 0xe7, 0xa2, 0x52,
- 0x9a, 0xa5, 0x5c, 0x4a, 0x87, 0x05, 0x7e, 0xb1, 0x7e, 0x75, 0xa6, 0x0b,
- 0x69, 0x2b, 0xd2, 0xa4, 0xea, 0xa7, 0x3a, 0xe3, 0xaa, 0xf6, 0xd5, 0x99,
- 0xb4, 0x6a, 0x57, 0x9d, 0xe9, 0x47, 0xea, 0x49, 0xd3, 0x39, 0x38, 0x4e,
- 0xe7, 0x7a, 0x65, 0xea, 0x34, 0xec, 0xcb, 0x80, 0xa5, 0xce, 0xe2, 0x27,
- 0x60, 0x7f, 0x22, 0xf0, 0xb2, 0xae, 0xda, 0x83, 0xc0, 0x58, 0x3b, 0x81,
- 0x41, 0x76, 0x8a, 0x7b, 0x8a, 0xeb, 0xa7, 0xee, 0xbd, 0xcc, 0x78, 0x52,
- 0xe2, 0x41, 0xc9, 0xca, 0x81, 0xd9, 0x66, 0xec, 0xd7, 0x88, 0x5d, 0x92,
- 0x1e, 0x7b, 0x18, 0xf9, 0x42, 0x85, 0x74, 0xbb, 0x4f, 0xf9, 0x6e, 0x39,
- 0xef, 0x1c, 0x78, 0x92, 0xc1, 0x18, 0xef, 0xa7, 0x7d, 0x1f, 0xe4, 0xcf,
- 0xd5, 0x7d, 0x64, 0x30, 0x9f, 0x46, 0x7a, 0xf0, 0x1c, 0x31, 0xfb, 0x73,
- 0xce, 0x11, 0x29, 0xd7, 0xa4, 0xef, 0x7d, 0x72, 0xd9, 0xcd, 0xc8, 0xcb,
- 0x6e, 0x5a, 0xae, 0xb8, 0x3b, 0xe4, 0xeb, 0xb0, 0xd3, 0x2f, 0xb9, 0x7d,
- 0x9b, 0x88, 0x05, 0xaa, 0xea, 0x6c, 0xc6, 0xf0, 0xca, 0xd5, 0xf1, 0xc4,
- 0x1f, 0xc8, 0xd2, 0x0c, 0xb1, 0xb3, 0xbf, 0x7b, 0xbf, 0x57, 0xa4, 0xdd,
- 0xc2, 0x1c, 0x88, 0xd5, 0x8a, 0xb0, 0x7f, 0x87, 0x65, 0xd8, 0xa3, 0xdd,
- 0x53, 0x36, 0x2a, 0x31, 0x1c, 0xec, 0x67, 0xaf, 0x00, 0xbd, 0x7a, 0x79,
- 0x16, 0xfb, 0x49, 0x28, 0xff, 0x78, 0xae, 0x90, 0xef, 0xae, 0x3c, 0x59,
- 0xe6, 0x3a, 0x4b, 0xd7, 0xb5, 0x48, 0x58, 0x46, 0x14, 0x5e, 0x68, 0x93,
- 0x17, 0x17, 0x37, 0x8b, 0x05, 0x0b, 0x65, 0xdd, 0x12, 0x55, 0xb7, 0x18,
- 0xe8, 0x7f, 0x4b, 0x3b, 0xef, 0x22, 0xbd, 0x05, 0xda, 0x30, 0x16, 0x80,
- 0xb5, 0xb5, 0x73, 0x25, 0x26, 0xdf, 0x8f, 0xfd, 0xf5, 0x96, 0xda, 0x6b,
- 0x79, 0x37, 0x8e, 0x67, 0xa6, 0xdc, 0x73, 0x8c, 0x3b, 0x85, 0x75, 0xfc,
- 0xf7, 0xaf, 0xd4, 0xfb, 0x66, 0x77, 0x17, 0x70, 0x1d, 0xe5, 0x15, 0xe9,
- 0x52, 0x30, 0x6e, 0x1e, 0x38, 0xae, 0xd0, 0xcf, 0x3b, 0x14, 0x4e, 0xba,
- 0x88, 0xbd, 0x30, 0xa1, 0xea, 0xef, 0xc4, 0x7e, 0xda, 0xd4, 0x42, 0xfc,
- 0xb0, 0x07, 0xb2, 0xf8, 0xd2, 0x0c, 0x9f, 0xf9, 0x9e, 0xfe, 0x15, 0xe3,
- 0x6b, 0x17, 0x46, 0xa7, 0xdd, 0xdf, 0xd2, 0xfb, 0x47, 0x42, 0x77, 0xf5,
- 0x01, 0x87, 0x1e, 0x6b, 0xc2, 0x5a, 0x9c, 0x64, 0x32, 0x64, 0x75, 0x5a,
- 0xc0, 0xf1, 0xc3, 0xca, 0xe6, 0xf6, 0x61, 0xfe, 0x69, 0x39, 0x93, 0x6e,
- 0x93, 0xaa, 0xed, 0xaa, 0x3b, 0x57, 0xcb, 0xf6, 0x76, 0x62, 0x7d, 0xfc,
- 0x36, 0xa1, 0xac, 0x07, 0x69, 0x33, 0xd2, 0xdb, 0xa4, 0x74, 0xb2, 0xaf,
- 0x25, 0xe8, 0x2f, 0xba, 0x2e, 0xff, 0x75, 0x3d, 0xce, 0x5f, 0x6a, 0x7f,
- 0x8a, 0xe3, 0x44, 0xc5, 0xfd, 0x7c, 0xab, 0xf4, 0x1c, 0xb3, 0x81, 0x6d,
- 0x13, 0xc0, 0xba, 0x5d, 0x92, 0x3e, 0x96, 0x94, 0x5b, 0x8e, 0x99, 0x38,
- 0xd1, 0x97, 0x47, 0x53, 0x2a, 0x66, 0xf8, 0xa5, 0x51, 0xb7, 0xa2, 0xce,
- 0x53, 0xf5, 0xdd, 0xb0, 0x65, 0x7d, 0x67, 0xec, 0x1b, 0xa3, 0x7d, 0x2a,
- 0xfd, 0xf6, 0x68, 0x5a, 0xa5, 0xaf, 0x8c, 0xde, 0x52, 0x0b, 0xfc, 0xa3,
- 0xd2, 0x42, 0x5a, 0x3e, 0x57, 0x26, 0xbe, 0x1c, 0x00, 0x76, 0xf4, 0xa0,
- 0x67, 0xfa, 0xa1, 0x67, 0xd2, 0xd0, 0x33, 0x83, 0xd4, 0x33, 0xd0, 0xdb,
- 0xaf, 0x40, 0x6f, 0x7b, 0xf2, 0x06, 0xe4, 0xf5, 0x82, 0xd7, 0x0c, 0x5c,
- 0xe8, 0xfb, 0xc1, 0x5a, 0x9d, 0xa7, 0x96, 0xc1, 0xdf, 0xea, 0x59, 0x89,
- 0xb5, 0x43, 0x07, 0x6d, 0x9f, 0x6f, 0x92, 0x85, 0xb8, 0xef, 0x9f, 0xf0,
- 0x5c, 0xb9, 0x86, 0xfa, 0x39, 0x97, 0xfb, 0x78, 0xa2, 0x85, 0xfe, 0xd8,
- 0xb5, 0x99, 0x1d, 0xd0, 0x49, 0x94, 0xf7, 0x98, 0x54, 0xc7, 0x13, 0xb2,
- 0x08, 0xff, 0x6c, 0xb5, 0x4e, 0x1a, 0xcf, 0xdc, 0xff, 0xff, 0x12, 0x75,
- 0xd3, 0xb0, 0x0f, 0xb6, 0x2c, 0xf5, 0x25, 0xe5, 0x4c, 0x9f, 0x33, 0x98,
- 0xb4, 0xa8, 0xbb, 0x92, 0x52, 0x81, 0xaf, 0x5f, 0x2d, 0xb3, 0x3e, 0xeb,
- 0x61, 0x7f, 0x96, 0x83, 0x76, 0xd3, 0x65, 0xa3, 0x27, 0x20, 0x9f, 0x73,
- 0x8c, 0x03, 0x06, 0x36, 0xc0, 0xb2, 0x9a, 0x21, 0x07, 0x1e, 0xe8, 0x3f,
- 0x8e, 0xf2, 0x01, 0xde, 0x25, 0x40, 0x19, 0xb1, 0x50, 0x49, 0xf1, 0x38,
- 0xef, 0x8d, 0xa3, 0x8c, 0x6d, 0x9c, 0x44, 0x0a, 0xe5, 0x63, 0x92, 0x4a,
- 0x14, 0xd4, 0xbd, 0xa6, 0x4e, 0x94, 0xb1, 0x8f, 0xb0, 0x8e, 0xc7, 0xcc,
- 0xb6, 0x50, 0x8e, 0xc2, 0xae, 0x29, 0xdf, 0xa6, 0x62, 0x03, 0x59, 0xdb,
- 0xc3, 0x7e, 0x60, 0x59, 0xca, 0x66, 0xbb, 0xbc, 0xe7, 0x29, 0x5d, 0x78,
- 0xaf, 0x3e, 0xb7, 0xb8, 0xa7, 0xd6, 0x2a, 0xf9, 0x5a, 0xd3, 0x7b, 0xe8,
- 0x7f, 0xb3, 0x27, 0x2f, 0x27, 0x6c, 0xe1, 0x19, 0x7b, 0xb0, 0xcf, 0x23,
- 0x3b, 0xb8, 0x27, 0x40, 0x77, 0xd8, 0xdf, 0xe7, 0xb1, 0xde, 0xe7, 0x60,
- 0x7f, 0x2f, 0xc2, 0xfe, 0x5e, 0x28, 0xaf, 0xea, 0x8f, 0xc0, 0xee, 0x52,
- 0x07, 0x3c, 0x03, 0x9e, 0x8d, 0x01, 0xf7, 0xef, 0x85, 0x3f, 0x30, 0x02,
- 0xec, 0x3f, 0x04, 0xfe, 0x65, 0xc0, 0xbb, 0x71, 0xde, 0x45, 0x01, 0x1f,
- 0x07, 0xd5, 0x59, 0xe6, 0xac, 0x3a, 0xcf, 0xff, 0x81, 0xb2, 0xbd, 0x8f,
- 0x97, 0x2d, 0xd8, 0x87, 0xa2, 0x7f, 0x9d, 0xeb, 0x00, 0xff, 0xad, 0xec,
- 0xe7, 0xc1, 0x17, 0xa1, 0x57, 0x7e, 0x8c, 0x79, 0x3d, 0x37, 0x4b, 0x7b,
- 0x8e, 0x3a, 0x01, 0xde, 0xf6, 0x18, 0xeb, 0xc2, 0x7e, 0x3e, 0x7a, 0x59,
- 0x96, 0x81, 0x3b, 0xb2, 0x94, 0x63, 0xf8, 0x0f, 0xce, 0x85, 0x8a, 0xf4,
- 0x52, 0x07, 0x02, 0x13, 0x0d, 0xca, 0xc0, 0xf1, 0x04, 0xb0, 0x1e, 0x90,
- 0xbc, 0x3a, 0xaf, 0xc3, 0xf3, 0xf9, 0x2d, 0x62, 0x11, 0xef, 0x79, 0x3c,
- 0x9b, 0xa1, 0xde, 0x30, 0x18, 0x69, 0x79, 0xb0, 0x43, 0xb2, 0xdb, 0x3b,
- 0x94, 0xee, 0x70, 0xbc, 0x97, 0x31, 0xee, 0x1e, 0xb8, 0x20, 0x6f, 0x00,
- 0x21, 0x58, 0x99, 0x43, 0xf2, 0xbf, 0x3c, 0xc6, 0xa8, 0x02, 0xdf, 0x0f,
- 0x73, 0x89, 0x81, 0x66, 0x9b, 0xf6, 0xbb, 0x76, 0x6c, 0x4f, 0x9d, 0xfd,
- 0xc7, 0x14, 0xc6, 0xca, 0x0b, 0xfb, 0x87, 0x9d, 0xc0, 0x98, 0xa9, 0xe3,
- 0x94, 0xfd, 0x6d, 0xe0, 0xdb, 0x3f, 0x05, 0x06, 0x22, 0x55, 0x87, 0x36,
- 0x07, 0xfb, 0x85, 0xf3, 0x5f, 0x26, 0x9e, 0x60, 0x4c, 0x3d, 0xf0, 0xcb,
- 0x57, 0xe6, 0xb6, 0x13, 0xf6, 0xeb, 0xb6, 0xcd, 0x94, 0x81, 0x71, 0x0f,
- 0x7e, 0xdf, 0xf1, 0xc0, 0x5e, 0x77, 0x9f, 0x47, 0xab, 0x13, 0xd2, 0xc9,
- 0xd3, 0x4e, 0x4b, 0x6e, 0x91, 0x8f, 0x44, 0x82, 0x7e, 0xac, 0x79, 0x1b,
- 0xb2, 0x4a, 0x3d, 0xd0, 0x09, 0x39, 0x67, 0x9e, 0x3a, 0x85, 0x3a, 0x81,
- 0xb2, 0xe0, 0x4a, 0xa9, 0x0e, 0x9d, 0xd0, 0xd6, 0x25, 0x15, 0xd2, 0x6c,
- 0x9e, 0x7a, 0xe2, 0x07, 0x32, 0xbd, 0x4e, 0x57, 0x0e, 0x89, 0xf1, 0x6b,
- 0x5b, 0x25, 0x9a, 0x71, 0xed, 0x7b, 0xd5, 0x1a, 0x03, 0x7d, 0x79, 0x80,
- 0xf8, 0x73, 0x36, 0xeb, 0x74, 0x88, 0xc6, 0x9e, 0x0a, 0x3f, 0xbd, 0x89,
- 0xb5, 0xb2, 0x0f, 0x45, 0xa7, 0xc1, 0xa1, 0xc0, 0x17, 0x50, 0x31, 0x3f,
- 0xe0, 0xe0, 0xc4, 0x8f, 0xa1, 0x6b, 0xf3, 0xc4, 0x25, 0xa0, 0x73, 0xf7,
- 0x09, 0xca, 0xd1, 0x75, 0xea, 0x6c, 0xbc, 0x62, 0xa5, 0xa9, 0xaf, 0x65,
- 0xf1, 0x38, 0x30, 0x97, 0xb5, 0x4b, 0x0a, 0x94, 0x57, 0x9e, 0x7d, 0x2f,
- 0x5a, 0x32, 0x3d, 0xd7, 0x26, 0x3d, 0xf3, 0x8c, 0xaf, 0xee, 0x6e, 0x91,
- 0x36, 0xc6, 0x58, 0x69, 0x83, 0x06, 0x24, 0x8f, 0xf2, 0xee, 0xf9, 0xb0,
- 0x8a, 0x87, 0x55, 0x2c, 0xd2, 0xa8, 0x1f, 0xfa, 0xc0, 0x49, 0x2f, 0x5b,
- 0xff, 0x25, 0x16, 0x60, 0x48, 0xc8, 0x52, 0x19, 0x32, 0x56, 0x86, 0x8c,
- 0x95, 0x21, 0x63, 0x65, 0xc8, 0x18, 0xb0, 0xdf, 0x73, 0xd8, 0x7f, 0x17,
- 0xcb, 0x83, 0xda, 0xae, 0xdf, 0xaf, 0xec, 0xfa, 0x91, 0x32, 0xcf, 0xf0,
- 0xe9, 0x83, 0x26, 0x95, 0x0e, 0xb9, 0xa4, 0x7c, 0x51, 0xe3, 0xa3, 0xbe,
- 0x22, 0xcf, 0xcc, 0xbe, 0x2a, 0x67, 0x66, 0x57, 0x71, 0xe0, 0x54, 0xd9,
- 0x97, 0x97, 0x3d, 0xf8, 0x9f, 0x0b, 0xc4, 0x54, 0xd9, 0xf6, 0x66, 0x85,
- 0xad, 0x0e, 0x4b, 0x41, 0xe1, 0x64, 0x65, 0x47, 0x80, 0xaf, 0x14, 0x2e,
- 0xe4, 0xde, 0x94, 0x8e, 0xed, 0xaf, 0xc9, 0x45, 0xd8, 0xf1, 0xc5, 0xfa,
- 0xeb, 0xf2, 0xbc, 0xc2, 0xe3, 0xa4, 0xc3, 0x07, 0xe4, 0x47, 0x76, 0x70,
- 0x4e, 0x7c, 0x06, 0x58, 0x63, 0xb1, 0x8f, 0xba, 0x23, 0x02, 0x5b, 0xe0,
- 0x14, 0xbb, 0xb1, 0xaf, 0x0f, 0x5a, 0x37, 0x00, 0xd3, 0xf0, 0xfd, 0x16,
- 0x79, 0x71, 0xb6, 0xd8, 0x20, 0x13, 0xd4, 0x0f, 0xce, 0x51, 0xb1, 0x68,
- 0xa7, 0x68, 0x37, 0xb9, 0x5e, 0xda, 0xa9, 0x3f, 0xd8, 0xcc, 0xb3, 0xd4,
- 0xea, 0xc9, 0x73, 0x2d, 0x8c, 0x37, 0xc6, 0x5d, 0xd2, 0xf4, 0x35, 0x39,
- 0x58, 0x63, 0xd9, 0xab, 0xe0, 0x0f, 0xd3, 0xef, 0xf9, 0xf7, 0xc4, 0x39,
- 0x1e, 0xfb, 0x05, 0x6e, 0xea, 0xc4, 0x5a, 0xcb, 0x7f, 0xa9, 0x63, 0x5e,
- 0xfd, 0x0a, 0x47, 0xbf, 0x13, 0x2f, 0x9b, 0x7b, 0x0d, 0xaf, 0xa9, 0x78,
- 0xe0, 0x06, 0x71, 0xe2, 0xa7, 0xb0, 0xaf, 0x8a, 0x57, 0x85, 0x31, 0x4b,
- 0xc6, 0x73, 0x19, 0x2b, 0x6e, 0xd4, 0x18, 0xea, 0xbc, 0x54, 0xee, 0x86,
- 0x7e, 0xb9, 0x07, 0xfa, 0xe5, 0xde, 0x77, 0xdc, 0xaf, 0x35, 0x71, 0xfb,
- 0x9e, 0x62, 0xd8, 0xea, 0x92, 0xb1, 0x5a, 0x63, 0x5b, 0xc6, 0x71, 0x37,
- 0x8a, 0xdb, 0x32, 0xa6, 0x9b, 0x5e, 0x17, 0x0b, 0xa4, 0x6c, 0xf8, 0xf2,
- 0x92, 0xc7, 0xb8, 0x9b, 0xb9, 0x9b, 0xbd, 0x11, 0xfe, 0xfa, 0xc3, 0xcd,
- 0x26, 0xe6, 0x1c, 0xc9, 0x5c, 0x15, 0xde, 0xd1, 0x2e, 0xcd, 0x10, 0x0f,
- 0xa8, 0xb3, 0x40, 0x15, 0xbb, 0xce, 0x07, 0xf1, 0x03, 0x94, 0xc3, 0xea,
- 0xc2, 0xdf, 0x61, 0xec, 0xda, 0xde, 0xe1, 0xd8, 0x63, 0xe1, 0xe0, 0xae,
- 0x1f, 0xf7, 0x72, 0xa0, 0xcb, 0x20, 0x8b, 0xf5, 0xd5, 0x3b, 0x74, 0x43,
- 0x4a, 0x5f, 0x5c, 0xc5, 0x1e, 0x20, 0xbf, 0xe0, 0x2f, 0x60, 0x9f, 0x4c,
- 0x41, 0x3f, 0x15, 0x54, 0x7f, 0x31, 0xca, 0x45, 0x36, 0x17, 0xb6, 0x24,
- 0x7a, 0x8a, 0xbe, 0x50, 0x10, 0x6b, 0xc9, 0x87, 0x1d, 0xa5, 0xbf, 0x31,
- 0x77, 0xe0, 0x33, 0xee, 0xcf, 0xe4, 0x44, 0x73, 0xa6, 0x09, 0x76, 0x15,
- 0xfc, 0xab, 0x33, 0x26, 0x80, 0xbd, 0xbb, 0xf4, 0x5d, 0x39, 0x30, 0x77,
- 0x69, 0x73, 0x20, 0xff, 0x8c, 0x23, 0x73, 0x7d, 0x66, 0x0e, 0x6b, 0xfb,
- 0xb6, 0x4e, 0x49, 0xac, 0x05, 0x36, 0xed, 0xa3, 0xa7, 0x88, 0x07, 0x9a,
- 0x65, 0x39, 0xce, 0x7e, 0x83, 0x3d, 0x33, 0x5d, 0x66, 0xdf, 0xdf, 0x95,
- 0xe1, 0xb9, 0x74, 0x2b, 0xf5, 0xc8, 0x12, 0xf4, 0xc0, 0x65, 0x9b, 0x36,
- 0x74, 0x1c, 0x36, 0xae, 0x53, 0xde, 0x9c, 0xa3, 0x7d, 0x4c, 0xd9, 0x67,
- 0x64, 0x5b, 0xe2, 0x0c, 0xe6, 0xf4, 0x84, 0x17, 0xa1, 0x8f, 0xe6, 0x0f,
- 0xa1, 0xec, 0xeb, 0x92, 0xb2, 0xbb, 0x43, 0x7c, 0xde, 0x66, 0x3f, 0x29,
- 0xbc, 0x6f, 0x90, 0xb2, 0x6f, 0x0d, 0x51, 0x8e, 0xe0, 0x73, 0x2f, 0xad,
- 0xce, 0xf3, 0x7b, 0x73, 0xca, 0x4f, 0x52, 0x7a, 0x66, 0xc9, 0xe3, 0x78,
- 0x97, 0xb4, 0x6e, 0xbb, 0x15, 0xfa, 0x24, 0xa6, 0xcf, 0xc2, 0xd0, 0x86,
- 0xd8, 0xc6, 0x8b, 0xe8, 0xfc, 0x67, 0x25, 0x77, 0x3a, 0x0e, 0x7d, 0xc6,
- 0xbe, 0x8c, 0xef, 0x40, 0x1b, 0x69, 0xf0, 0x36, 0xed, 0xdd, 0x2e, 0xd8,
- 0xbd, 0x9b, 0xd4, 0x7c, 0x46, 0xbc, 0x7e, 0x99, 0x3a, 0xc9, 0xb1, 0xfb,
- 0xa0, 0xcb, 0x13, 0x4a, 0x6e, 0x4b, 0xe5, 0xcb, 0x89, 0x18, 0x74, 0x72,
- 0x6c, 0x3b, 0xe9, 0xf9, 0x61, 0xb9, 0xd3, 0x1d, 0x97, 0xbb, 0x20, 0x3b,
- 0x43, 0xae, 0x27, 0xc3, 0xe0, 0xc5, 0x1e, 0x17, 0x76, 0x47, 0x61, 0xe8,
- 0x66, 0xf8, 0x5d, 0x1c, 0x9b, 0xf7, 0xc4, 0xd9, 0x36, 0xc0, 0x8f, 0x7f,
- 0x54, 0x0f, 0x68, 0x94, 0x9b, 0xfb, 0x88, 0xa2, 0xcd, 0x88, 0xb7, 0x53,
- 0xdb, 0xd9, 0x36, 0xc9, 0xab, 0x7a, 0x3b, 0x95, 0x3d, 0x2e, 0x2d, 0xde,
- 0x87, 0x14, 0xb6, 0x79, 0x11, 0xfa, 0x06, 0x98, 0xbb, 0x54, 0xdb, 0x81,
- 0x3c, 0x6c, 0xe8, 0x62, 0x06, 0xe9, 0x87, 0x91, 0xb2, 0x6e, 0xa8, 0x35,
- 0x88, 0xe5, 0x1a, 0x3c, 0xba, 0x7a, 0xbf, 0xf0, 0xa3, 0x0a, 0x97, 0x5e,
- 0x55, 0xf7, 0xcb, 0x2c, 0x60, 0x9d, 0x1c, 0xf4, 0x4a, 0x2b, 0x30, 0xd0,
- 0xcc, 0x29, 0x27, 0x3d, 0x1c, 0xda, 0x2d, 0xbf, 0x06, 0x5f, 0xbe, 0xea,
- 0x91, 0x97, 0x3b, 0xe4, 0xc1, 0x3b, 0x28, 0x23, 0xbb, 0x65, 0xff, 0x1d,
- 0x21, 0xd9, 0xdf, 0xef, 0x64, 0x39, 0xef, 0x5b, 0x6e, 0x33, 0xfe, 0x74,
- 0xcf, 0x48, 0x2a, 0x34, 0x20, 0x4f, 0x42, 0xc6, 0x8a, 0x90, 0xaf, 0xe1,
- 0x3a, 0x69, 0x4e, 0x7d, 0x4f, 0x3d, 0x9f, 0x06, 0x56, 0x36, 0xd8, 0xcf,
- 0x95, 0x99, 0x7a, 0x93, 0x24, 0xaf, 0x67, 0x3c, 0x39, 0x19, 0x9c, 0x71,
- 0x5c, 0x4f, 0x99, 0x80, 0x0f, 0x72, 0x7d, 0xb0, 0x3f, 0xd5, 0xbd, 0x2e,
- 0xf5, 0x1c, 0xa7, 0xff, 0xeb, 0x13, 0xe7, 0x15, 0x14, 0x5f, 0x68, 0x23,
- 0x98, 0xfe, 0xbb, 0xd6, 0x15, 0x7c, 0xd7, 0x46, 0xff, 0x61, 0x67, 0xeb,
- 0xea, 0xbd, 0xf4, 0xf5, 0xb2, 0x68, 0xe2, 0x6e, 0x15, 0xac, 0x99, 0x36,
- 0xdd, 0xb1, 0xa9, 0x0b, 0xdb, 0xdd, 0xfb, 0xe5, 0x4f, 0x60, 0xdf, 0xbf,
- 0xb2, 0x62, 0xdf, 0xf7, 0x81, 0x1e, 0xeb, 0x31, 0x80, 0x6b, 0xdf, 0x8d,
- 0xb5, 0x8c, 0x80, 0x9f, 0x77, 0xe1, 0x77, 0x67, 0x79, 0x4d, 0x1c, 0x6f,
- 0xb6, 0x08, 0x3c, 0xd9, 0xe4, 0xb2, 0xbf, 0x35, 0xf1, 0xbc, 0x62, 0x41,
- 0x56, 0x62, 0x85, 0x83, 0xd7, 0x84, 0x76, 0xef, 0x2d, 0x89, 0xf6, 0xba,
- 0x6f, 0x75, 0x87, 0xdc, 0x17, 0xac, 0x10, 0xcf, 0x95, 0x3d, 0x39, 0x5b,
- 0x27, 0x0e, 0xbb, 0x22, 0xd6, 0x79, 0x62, 0xb0, 0x6f, 0xa8, 0x18, 0x54,
- 0xb5, 0xfc, 0x6d, 0xa4, 0xa8, 0x0f, 0xfd, 0x18, 0x0e, 0xe2, 0x14, 0x0a,
- 0xab, 0x50, 0xcf, 0xde, 0x05, 0x3e, 0x4c, 0xe1, 0xd7, 0xbd, 0xfd, 0x56,
- 0xec, 0x5f, 0xca, 0x29, 0x63, 0x5f, 0xbd, 0xf6, 0xf6, 0x10, 0xdf, 0x6d,
- 0x14, 0x07, 0xfb, 0x8e, 0x44, 0x4e, 0xc0, 0xd6, 0x59, 0xd4, 0x0f, 0x5c,
- 0x07, 0xed, 0xa4, 0x2d, 0x0b, 0x27, 0xb9, 0xd7, 0x37, 0xaa, 0x6f, 0xea,
- 0x9a, 0xb5, 0x28, 0xbb, 0x91, 0x2d, 0x30, 0xc6, 0x59, 0x26, 0x0f, 0x3c,
- 0xf0, 0xc0, 0x97, 0x53, 0x5e, 0x3b, 0xf4, 0x76, 0x5c, 0xc2, 0xa7, 0x7c,
- 0x19, 0x52, 0xd8, 0x75, 0x1b, 0x30, 0xd7, 0x16, 0x8d, 0x1b, 0xe2, 0x12,
- 0x39, 0xd5, 0x25, 0xcd, 0xc0, 0xd5, 0x4d, 0xc7, 0x68, 0x23, 0x53, 0xc9,
- 0x21, 0x08, 0x41, 0x44, 0xdd, 0x55, 0x74, 0x06, 0xdf, 0x94, 0x6d, 0xc9,
- 0x37, 0x85, 0x78, 0xe9, 0x86, 0x2d, 0xf0, 0x09, 0xbc, 0x2b, 0x1b, 0xd4,
- 0x2f, 0xad, 0xd6, 0x87, 0x1c, 0x31, 0xb6, 0xc6, 0x36, 0x8c, 0xb5, 0xa5,
- 0x06, 0xdf, 0x60, 0x8c, 0x0d, 0xbe, 0x66, 0xd3, 0xb9, 0x60, 0x0e, 0xd6,
- 0x52, 0x87, 0x54, 0x4f, 0x73, 0x8f, 0x32, 0xce, 0x62, 0x07, 0x7e, 0x6a,
- 0x99, 0xfe, 0x2a, 0xdf, 0x27, 0xf5, 0xfb, 0x6e, 0xfd, 0x9e, 0xfe, 0x68,
- 0xd1, 0x6f, 0x02, 0x4d, 0xf7, 0x40, 0x7f, 0xde, 0xb7, 0xc3, 0x55, 0xb8,
- 0xe1, 0xbe, 0x15, 0x9e, 0xed, 0x15, 0xeb, 0x38, 0xfc, 0xd4, 0xf2, 0x61,
- 0x71, 0xb7, 0x2f, 0xa7, 0x23, 0x32, 0x06, 0x5e, 0x30, 0x9f, 0xe5, 0x7c,
- 0xd2, 0x47, 0xe4, 0xa0, 0xe2, 0x4d, 0xf5, 0xa4, 0x73, 0x34, 0x19, 0x9a,
- 0x12, 0xab, 0xca, 0xe7, 0x47, 0x90, 0x1e, 0x01, 0xde, 0x09, 0x62, 0x97,
- 0x56, 0x75, 0x2d, 0x2d, 0x81, 0x31, 0xec, 0x3d, 0x6b, 0xe2, 0x58, 0xab,
- 0x31, 0x2e, 0xbe, 0x1f, 0x52, 0xef, 0xd3, 0x6b, 0xe2, 0x5c, 0x79, 0x8b,
- 0x58, 0xc6, 0xbc, 0x27, 0x2f, 0xc8, 0x2f, 0xd8, 0xe2, 0x93, 0x26, 0xe6,
- 0xd5, 0xa6, 0xf9, 0x42, 0xfe, 0xcc, 0xc8, 0x45, 0xdb, 0x19, 0xa1, 0xfc,
- 0xfd, 0xea, 0x8e, 0x1b, 0x65, 0xa2, 0x93, 0xf1, 0xb6, 0xc6, 0x39, 0xac,
- 0x8f, 0xa3, 0x35, 0x8e, 0xbf, 0x3e, 0xfe, 0xc6, 0xb1, 0x83, 0x18, 0x5b,
- 0x6e, 0x4d, 0x8c, 0xad, 0x71, 0x3c, 0x8e, 0xb5, 0x05, 0xfe, 0x53, 0xd1,
- 0x8f, 0xbb, 0xe4, 0x51, 0x4f, 0x72, 0x8e, 0xf9, 0x2f, 0x58, 0xe0, 0x63,
- 0x1c, 0x76, 0x84, 0xbc, 0x34, 0x67, 0xcf, 0xe4, 0x69, 0x2a, 0x79, 0x24,
- 0xe0, 0xe7, 0x60, 0xc0, 0xf7, 0x80, 0xff, 0x57, 0x56, 0xf8, 0x48, 0xfb,
- 0x40, 0x3e, 0x76, 0x8a, 0x40, 0xcf, 0x5a, 0xc7, 0xc8, 0x43, 0xa6, 0xe4,
- 0x21, 0xdf, 0x91, 0x87, 0xdd, 0xfa, 0x1d, 0xf9, 0x07, 0x9c, 0xf6, 0x79,
- 0x60, 0x0c, 0x2f, 0xa7, 0xbe, 0xb1, 0xe9, 0xee, 0x35, 0x7b, 0x31, 0x2d,
- 0xcf, 0x2f, 0xb4, 0x88, 0x9d, 0x09, 0xd6, 0x35, 0xbe, 0x26, 0xde, 0xce,
- 0xf3, 0xab, 0x7e, 0x62, 0x4f, 0xb3, 0xae, 0x04, 0xd7, 0x75, 0x50, 0x5e,
- 0x93, 0xc2, 0x4c, 0x04, 0x3e, 0x60, 0x1a, 0x38, 0xa7, 0x1f, 0xfa, 0x96,
- 0xf1, 0x51, 0x94, 0xd5, 0x88, 0x57, 0x68, 0xeb, 0xd2, 0xd8, 0x2b, 0xd4,
- 0xc1, 0xc4, 0x23, 0xaf, 0x4a, 0xbe, 0x62, 0x74, 0x0c, 0xfa, 0xb7, 0x4c,
- 0xff, 0xa4, 0x73, 0xf6, 0x96, 0xeb, 0x64, 0x39, 0x79, 0x9d, 0x38, 0xc9,
- 0x45, 0x59, 0xe5, 0xeb, 0xf8, 0xc6, 0x74, 0xf7, 0xee, 0x0b, 0xaf, 0xca,
- 0xc6, 0xf8, 0x06, 0xbc, 0x9f, 0x14, 0xf3, 0xde, 0xf0, 0x7e, 0x43, 0x3e,
- 0x14, 0x5f, 0x11, 0xf2, 0x82, 0x34, 0x20, 0x1e, 0x8e, 0xca, 0xef, 0xc6,
- 0xb9, 0x1f, 0x8b, 0xea, 0x7c, 0x33, 0x65, 0xf5, 0x2a, 0x9d, 0x31, 0xe4,
- 0x05, 0xf2, 0x5a, 0xc4, 0x38, 0xb1, 0x9e, 0xdf, 0xf3, 0x87, 0xe2, 0xf0,
- 0x73, 0x7b, 0xa8, 0x5f, 0xcc, 0x9e, 0x6e, 0x51, 0x7b, 0xfa, 0x09, 0x2f,
- 0x24, 0x25, 0x37, 0x24, 0x53, 0xee, 0x61, 0x85, 0xf1, 0x7f, 0x03, 0x7d,
- 0x3d, 0xa8, 0xfb, 0x9a, 0x92, 0x5e, 0xad, 0x7f, 0x0e, 0x41, 0xce, 0x7d,
- 0xb9, 0xd7, 0xdb, 0x21, 0xbf, 0xda, 0xce, 0x3d, 0x60, 0xd6, 0x7f, 0x58,
- 0x7a, 0x76, 0x2c, 0x27, 0xe1, 0x19, 0xdc, 0x12, 0x5d, 0xa1, 0x01, 0xf7,
- 0x99, 0x91, 0xef, 0x80, 0x0e, 0xc1, 0xfa, 0xd7, 0xac, 0x55, 0xaf, 0x93,
- 0x6b, 0x66, 0x3d, 0xae, 0x35, 0xc0, 0xf2, 0xab, 0x6b, 0x35, 0xf5, 0x5b,
- 0x21, 0x4b, 0x4e, 0x52, 0x42, 0x8d, 0xb4, 0x59, 0xd1, 0x51, 0x23, 0x8c,
- 0x91, 0x2c, 0xdb, 0x4e, 0x3a, 0x19, 0x32, 0xb1, 0xe8, 0x00, 0xeb, 0x76,
- 0x03, 0x87, 0xbb, 0xbd, 0xbd, 0xe9, 0x82, 0x8a, 0x91, 0x5a, 0x6a, 0x5d,
- 0x53, 0xc0, 0x64, 0x0b, 0xde, 0x2b, 0xfe, 0xa7, 0x81, 0x59, 0x27, 0xe4,
- 0x61, 0x09, 0xaf, 0x89, 0xe5, 0x22, 0x7f, 0x9e, 0xf1, 0x5c, 0x27, 0x99,
- 0x05, 0x8f, 0x7f, 0x13, 0x3e, 0x7c, 0x15, 0x7a, 0xff, 0xe3, 0xb4, 0x0d,
- 0x65, 0xd8, 0x0b, 0xe0, 0x92, 0xaf, 0xbc, 0x27, 0x86, 0x9f, 0x68, 0x88,
- 0xe5, 0x06, 0xf8, 0xf4, 0xa2, 0xc2, 0xa4, 0xc4, 0xed, 0x47, 0x43, 0x77,
- 0xf7, 0x85, 0xe1, 0x67, 0x14, 0xfd, 0x98, 0x4b, 0x1c, 0x77, 0x58, 0xee,
- 0x04, 0x7f, 0xce, 0x2e, 0x14, 0x43, 0x7b, 0xca, 0x46, 0x56, 0xe1, 0x57,
- 0xd6, 0x9d, 0xf4, 0x65, 0xd0, 0xe3, 0x19, 0x8d, 0xf9, 0x78, 0x5e, 0x53,
- 0xd5, 0x3e, 0x0b, 0x63, 0x43, 0xa5, 0xfa, 0x61, 0x99, 0xf6, 0x18, 0xdb,
- 0xe9, 0x91, 0x52, 0x3c, 0x7b, 0x63, 0xf3, 0x0a, 0x8d, 0x1c, 0x1b, 0x3e,
- 0x5f, 0x9a, 0xfa, 0xbb, 0xaa, 0xcf, 0x3b, 0x9e, 0x51, 0xf2, 0x65, 0xe2,
- 0xc2, 0xf4, 0x8f, 0x78, 0x5e, 0xd5, 0x63, 0x8f, 0xf0, 0xb9, 0x42, 0x19,
- 0x50, 0x3e, 0x13, 0x68, 0xf9, 0x90, 0x64, 0xc7, 0x92, 0x0a, 0xb7, 0x3c,
- 0x5e, 0xe6, 0x7e, 0x21, 0xfe, 0x7f, 0x0d, 0xd8, 0x3f, 0x02, 0x9e, 0xd1,
- 0x0f, 0xe0, 0xd8, 0xdc, 0x17, 0x28, 0xab, 0xd9, 0xef, 0xb2, 0x2f, 0x5e,
- 0x6b, 0x23, 0xc6, 0xb8, 0x54, 0x16, 0x45, 0xbf, 0x65, 0x31, 0xb1, 0x73,
- 0x85, 0x05, 0x8b, 0xb9, 0x70, 0x48, 0x52, 0x27, 0xfe, 0x35, 0x64, 0xe8,
- 0xd7, 0xe1, 0x23, 0xa9, 0x7a, 0xea, 0xfc, 0x6a, 0x08, 0x98, 0xcb, 0x72,
- 0x6f, 0x90, 0x92, 0x1d, 0x95, 0x92, 0xba, 0xa3, 0xc9, 0xf3, 0xdc, 0xb0,
- 0x8a, 0xed, 0x94, 0x6c, 0x62, 0xfe, 0xff, 0xde, 0x16, 0xd8, 0xfa, 0x0e,
- 0xe4, 0xd9, 0x8e, 0x79, 0x96, 0x4f, 0x49, 0xf4, 0xc4, 0x21, 0x69, 0x3a,
- 0xf1, 0xb0, 0x34, 0x1f, 0x27, 0xc6, 0x63, 0xec, 0xde, 0xda, 0xd5, 0x2c,
- 0xc4, 0xdc, 0x43, 0x18, 0xfb, 0xb0, 0x7c, 0xdf, 0x33, 0x73, 0x5a, 0xc4,
- 0x1c, 0x59, 0xc7, 0xe4, 0x0d, 0x1e, 0xdf, 0x85, 0xf9, 0x70, 0xfd, 0x49,
- 0x8d, 0xfb, 0x76, 0x35, 0xf8, 0xae, 0x4d, 0xda, 0x77, 0x65, 0xbb, 0x4f,
- 0x61, 0xad, 0x27, 0x25, 0xea, 0x9a, 0xf6, 0xbb, 0x51, 0x2f, 0xd1, 0x70,
- 0x07, 0x82, 0x75, 0xf4, 0x9d, 0x80, 0x36, 0xe2, 0x1e, 0x9e, 0xb7, 0xb3,
- 0x2c, 0x38, 0xf3, 0xb7, 0xaa, 0xbb, 0xc2, 0x6b, 0xc7, 0xdf, 0xd9, 0x50,
- 0xd7, 0x94, 0x99, 0x36, 0xd1, 0xc0, 0xe7, 0x1f, 0x88, 0x36, 0xb4, 0x83,
- 0x71, 0x53, 0x69, 0xe0, 0x7b, 0x04, 0x7e, 0x10, 0xd7, 0x90, 0x6e, 0xc0,
- 0x39, 0x6b, 0xbf, 0x45, 0xcc, 0xa3, 0xbc, 0x30, 0x67, 0xee, 0x91, 0x59,
- 0x58, 0x8b, 0x53, 0xa4, 0xff, 0x62, 0xf3, 0x4e, 0xee, 0x5c, 0x11, 0xf3,
- 0xbe, 0x49, 0xdd, 0x25, 0xe2, 0xdd, 0x0d, 0xd4, 0x4b, 0x06, 0xf8, 0x93,
- 0xf9, 0x04, 0x78, 0x7e, 0x5b, 0x97, 0x95, 0xf9, 0xf3, 0x1b, 0x73, 0x03,
- 0xc4, 0x37, 0x5b, 0x79, 0x0e, 0x09, 0xdc, 0x4c, 0x39, 0xfb, 0x2e, 0xe4,
- 0xac, 0x59, 0x9d, 0xfb, 0x94, 0xca, 0xf4, 0xe7, 0x0a, 0x90, 0x1f, 0xde,
- 0x87, 0xa3, 0xdf, 0x57, 0xd0, 0xf1, 0x58, 0xce, 0x93, 0x98, 0xde, 0xf8,
- 0x07, 0xec, 0x73, 0xfd, 0x19, 0x6c, 0xe3, 0xfd, 0x12, 0xca, 0x5b, 0x42,
- 0xcd, 0x79, 0x78, 0x9d, 0xbf, 0x72, 0x04, 0xba, 0x60, 0x01, 0xf2, 0x3c,
- 0x09, 0x1d, 0x38, 0x14, 0xe6, 0xfe, 0x6c, 0xd1, 0xbe, 0xac, 0x4b, 0xbf,
- 0x3d, 0x34, 0x86, 0x3e, 0xac, 0xe3, 0xaf, 0xcb, 0x14, 0xf4, 0xff, 0x74,
- 0x3d, 0xa5, 0xbe, 0x17, 0xc9, 0x26, 0x78, 0x07, 0x8c, 0xe5, 0x63, 0x18,
- 0xff, 0x75, 0xe0, 0xe1, 0xcd, 0xa0, 0xa7, 0xa5, 0x79, 0xf5, 0x2b, 0x3a,
- 0x16, 0x15, 0x63, 0x2c, 0x1e, 0x7a, 0xb3, 0x14, 0x60, 0xcd, 0xf8, 0x34,
- 0xd2, 0xcd, 0x2d, 0x81, 0xbc, 0x4e, 0x6e, 0xd5, 0x77, 0x2f, 0x50, 0xfe,
- 0x98, 0x8a, 0x41, 0x06, 0x6b, 0x72, 0xb4, 0xaf, 0x12, 0x85, 0xcc, 0x71,
- 0x5d, 0xf7, 0xa2, 0x1e, 0x65, 0xad, 0x4f, 0x9f, 0xcd, 0xb6, 0x28, 0xfd,
- 0x98, 0x87, 0x2c, 0x15, 0x94, 0x1f, 0x01, 0x7c, 0xef, 0xb1, 0xdd, 0xaf,
- 0x6f, 0xe5, 0xd9, 0x67, 0x93, 0xab, 0x7c, 0x8b, 0xce, 0xb0, 0x98, 0xb2,
- 0x8f, 0xa0, 0x8c, 0x72, 0x76, 0x03, 0x78, 0xc3, 0xb2, 0x1c, 0xf2, 0x1c,
- 0xeb, 0x46, 0x3d, 0x0e, 0xc7, 0xb8, 0xb4, 0x79, 0xed, 0x9c, 0xb8, 0x96,
- 0xce, 0x75, 0x77, 0xe7, 0x59, 0x76, 0x83, 0x2e, 0x8b, 0xe8, 0xf5, 0xfd,
- 0xa9, 0xfe, 0xb6, 0xc1, 0x39, 0x9a, 0x5d, 0xc1, 0xc6, 0x9c, 0x5f, 0x4c,
- 0xb5, 0xcb, 0xda, 0x81, 0xec, 0x1c, 0x01, 0x3f, 0x22, 0x99, 0xaf, 0xf1,
- 0x4c, 0x19, 0xf4, 0x35, 0x7b, 0x22, 0xa1, 0xfc, 0xce, 0xa4, 0x15, 0xdc,
- 0x5d, 0xba, 0x58, 0x6e, 0xf4, 0x19, 0xcc, 0xfd, 0x6f, 0x57, 0xc6, 0x56,
- 0x78, 0x45, 0xbe, 0x91, 0x5f, 0xef, 0xc6, 0x2b, 0xf2, 0x91, 0xfc, 0x2a,
- 0x48, 0x69, 0x96, 0x7c, 0xa2, 0xbc, 0x8c, 0x29, 0x79, 0x29, 0x55, 0x0c,
- 0x4e, 0xa6, 0x2e, 0xe1, 0x37, 0x0f, 0x1b, 0x9d, 0xd7, 0x9b, 0xbb, 0x61,
- 0xbf, 0x44, 0xfa, 0x85, 0x86, 0xe1, 0x1e, 0x2d, 0xcc, 0x2a, 0x9d, 0x02,
- 0xbb, 0x98, 0x50, 0xba, 0xa2, 0x30, 0xce, 0xfc, 0xd2, 0x56, 0x7e, 0x9b,
- 0x8b, 0x79, 0xa0, 0xbc, 0x53, 0xf3, 0xf5, 0x06, 0x75, 0xbf, 0x89, 0x7b,
- 0xb0, 0x54, 0xa9, 0xab, 0xf7, 0x67, 0xe7, 0x9a, 0x54, 0xfd, 0xb3, 0x73,
- 0xeb, 0xef, 0x28, 0xb1, 0xec, 0x66, 0xc6, 0x55, 0x64, 0x71, 0xa6, 0x49,
- 0x96, 0xe6, 0xfe, 0x90, 0x7e, 0x22, 0x8c, 0xc1, 0xca, 0xf7, 0x1d, 0xfa,
- 0x5b, 0x2c, 0x5f, 0x86, 0x21, 0x37, 0x0b, 0x83, 0xd3, 0x52, 0x1d, 0xa4,
- 0x1f, 0xa4, 0xee, 0x0e, 0x62, 0xbd, 0x4d, 0xc0, 0xc0, 0xc0, 0x85, 0x2e,
- 0xe3, 0xcf, 0x5b, 0xb4, 0x3e, 0x79, 0xb0, 0x75, 0x25, 0x2e, 0x1d, 0x2f,
- 0xfa, 0x55, 0xd7, 0x7c, 0x33, 0xc3, 0x3e, 0xf9, 0xdd, 0x0c, 0x79, 0x66,
- 0xa1, 0x3d, 0xef, 0x64, 0x76, 0x33, 0xae, 0xad, 0xf9, 0x1c, 0x46, 0x7d,
- 0xa6, 0xbf, 0xa7, 0xf3, 0x73, 0x3a, 0xfd, 0xac, 0xec, 0x3f, 0xf9, 0x19,
- 0xcc, 0x7b, 0x53, 0x70, 0xef, 0x4a, 0x1a, 0xbf, 0x9b, 0x88, 0xe8, 0x6f,
- 0x34, 0x3e, 0x8b, 0x32, 0xc6, 0xe2, 0x3e, 0xab, 0xd6, 0xc4, 0xbb, 0x7d,
- 0x45, 0xf9, 0x79, 0x77, 0x54, 0x8c, 0x3f, 0xc8, 0xfb, 0x53, 0x2d, 0xba,
- 0xbf, 0x3d, 0x5a, 0x96, 0xc6, 0x65, 0x3f, 0xec, 0x5d, 0x01, 0xb8, 0x98,
- 0x77, 0xce, 0x26, 0xc2, 0x8d, 0x63, 0x9a, 0xfd, 0x14, 0xc4, 0x1a, 0xcc,
- 0xdd, 0x87, 0xb0, 0xf2, 0x89, 0x56, 0xe2, 0x16, 0xba, 0x7c, 0x5c, 0x0e,
- 0x94, 0x55, 0xfc, 0x42, 0x9d, 0x59, 0x4e, 0x43, 0x2f, 0x0c, 0x29, 0x9b,
- 0x16, 0x0b, 0x0d, 0xd7, 0x32, 0x52, 0x38, 0xbd, 0x17, 0xe3, 0x30, 0x16,
- 0x98, 0xd5, 0x67, 0x83, 0xfb, 0x64, 0x7f, 0x3d, 0x18, 0x7b, 0xb2, 0xcc,
- 0xf7, 0x29, 0xe0, 0x04, 0xbe, 0xcf, 0x27, 0xc2, 0xea, 0x74, 0xe3, 0x56,
- 0xb4, 0x6d, 0xd2, 0x74, 0xe6, 0xbd, 0x6b, 0xb6, 0xa7, 0x0e, 0x00, 0xc0,
- 0x69, 0xc9, 0xe3, 0x3d, 0xdb, 0x98, 0xfe, 0x26, 0x61, 0xb7, 0xe8, 0x9f,
- 0x3f, 0x2a, 0xcb, 0x95, 0x69, 0xb9, 0x5c, 0x31, 0xb2, 0xce, 0xbb, 0xd7,
- 0x9c, 0xfb, 0x5d, 0xc1, 0xb7, 0xbf, 0xe5, 0x2c, 0xf8, 0xb3, 0x96, 0x56,
- 0xf9, 0x35, 0xdf, 0xdb, 0xfc, 0x2b, 0x3b, 0xf8, 0xe6, 0x6d, 0xb7, 0xba,
- 0xc3, 0xb5, 0x76, 0xcf, 0xb1, 0x9f, 0xfd, 0x36, 0xcf, 0x3a, 0x82, 0x7b,
- 0x68, 0x9d, 0x0d, 0xef, 0xe3, 0xfa, 0xee, 0xd7, 0xa7, 0xec, 0x80, 0x8f,
- 0xa4, 0xe7, 0x98, 0x9e, 0xef, 0xad, 0xd8, 0xff, 0xec, 0xf3, 0x31, 0xcd,
- 0x37, 0xa4, 0x0b, 0x7c, 0xe6, 0xfe, 0x5a, 0xd6, 0xe7, 0xbf, 0xb6, 0x1e,
- 0xa3, 0xf1, 0xee, 0x5d, 0x53, 0xc3, 0xb8, 0x6c, 0x4f, 0xfb, 0x64, 0xee,
- 0x80, 0xb3, 0xec, 0xa4, 0xbe, 0xe3, 0x77, 0xb5, 0xa1, 0xcc, 0xdc, 0x45,
- 0x23, 0xbd, 0x18, 0xd3, 0x44, 0x5a, 0x1f, 0xd3, 0xcf, 0x63, 0x0d, 0xdf,
- 0xc8, 0x98, 0x3e, 0x23, 0xe8, 0xc3, 0xdc, 0x41, 0x6f, 0xbc, 0x53, 0xcc,
- 0xef, 0x83, 0x28, 0x8b, 0x16, 0xbf, 0x61, 0xa6, 0x1f, 0x08, 0xec, 0xb6,
- 0x45, 0x26, 0xd5, 0x7c, 0x8a, 0xea, 0xbe, 0x06, 0xbf, 0x9b, 0x19, 0xb2,
- 0x83, 0xfc, 0xe4, 0xc2, 0x7a, 0x39, 0x65, 0xf9, 0x33, 0xcd, 0xd2, 0x52,
- 0xc4, 0x38, 0x7c, 0xbf, 0xd1, 0xf7, 0xf4, 0x51, 0xfd, 0x9d, 0x90, 0x87,
- 0x36, 0x4f, 0x50, 0xde, 0x8b, 0xc5, 0x95, 0x7b, 0xa2, 0xc5, 0xe0, 0x1b,
- 0x26, 0xcb, 0xdc, 0xd7, 0xe4, 0x37, 0xda, 0x22, 0x17, 0x6a, 0xfc, 0x3e,
- 0x69, 0xb7, 0xba, 0x47, 0x13, 0x9c, 0x4d, 0x72, 0x5e, 0x3d, 0xca, 0x2e,
- 0x54, 0x6b, 0x25, 0xd2, 0x54, 0xdb, 0xf6, 0xa8, 0xb6, 0xed, 0xa4, 0xf1,
- 0x08, 0x68, 0xfc, 0x25, 0xcd, 0x17, 0xb6, 0xcf, 0xaa, 0xfb, 0xdd, 0xd9,
- 0x38, 0xcf, 0xc7, 0x1e, 0x53, 0x6b, 0xa1, 0x9d, 0x40, 0xdb, 0x5f, 0x0e,
- 0xab, 0x78, 0xa7, 0xfa, 0x06, 0x1c, 0xf2, 0xc9, 0x6f, 0xba, 0xa1, 0xe3,
- 0xcb, 0xfc, 0x76, 0x7b, 0x04, 0x29, 0xbf, 0xd9, 0xde, 0xab, 0xee, 0xff,
- 0x57, 0xd5, 0x37, 0x01, 0x46, 0x1e, 0xc3, 0x7a, 0xac, 0x6f, 0x62, 0x8c,
- 0x80, 0xef, 0x85, 0x32, 0xbf, 0xe5, 0x36, 0x77, 0x4c, 0x37, 0x2f, 0x73,
- 0x4f, 0x88, 0xf2, 0xf3, 0x83, 0x6f, 0xfb, 0xab, 0xea, 0x3b, 0x82, 0x24,
- 0xbf, 0x2b, 0x84, 0xfd, 0xba, 0x1f, 0xcf, 0x3c, 0x57, 0xde, 0x87, 0x14,
- 0xfa, 0xa7, 0x36, 0x81, 0xf4, 0x61, 0xc9, 0xab, 0xb8, 0x5f, 0x2b, 0xf2,
- 0x93, 0x6a, 0xec, 0x52, 0xed, 0x13, 0xb2, 0xff, 0xf4, 0x43, 0xfc, 0x5e,
- 0x42, 0x7d, 0x77, 0x9e, 0xf3, 0x38, 0xc7, 0xb8, 0x4c, 0xa9, 0x75, 0x17,
- 0x35, 0xed, 0xcd, 0x59, 0xcc, 0xcf, 0xd4, 0xb7, 0x19, 0xc5, 0x5a, 0x2b,
- 0xe6, 0x18, 0xd2, 0xf7, 0x4c, 0xe9, 0x0f, 0x98, 0xf5, 0xb7, 0xf0, 0xee,
- 0xa2, 0xcf, 0xf3, 0xc3, 0xfd, 0x65, 0xde, 0x23, 0x4d, 0xe9, 0x38, 0x01,
- 0x63, 0x87, 0x3c, 0x9f, 0xa0, 0x8c, 0x3b, 0xe9, 0x09, 0x58, 0xa0, 0xa8,
- 0x24, 0x78, 0xb6, 0xad, 0xd7, 0xd2, 0xda, 0xb0, 0x16, 0xde, 0x9d, 0x0d,
- 0xd6, 0xc3, 0xef, 0x21, 0x0a, 0xe5, 0xc6, 0x6f, 0x2a, 0xd4, 0x37, 0xd0,
- 0xfc, 0x76, 0x46, 0x26, 0x6a, 0x9f, 0x94, 0x07, 0xca, 0x5b, 0xf4, 0xf7,
- 0x14, 0x31, 0x79, 0xa0, 0xf6, 0xba, 0xa2, 0x69, 0x41, 0x7d, 0xd7, 0x11,
- 0xd5, 0x3c, 0x33, 0xdf, 0x54, 0x04, 0xfd, 0x1d, 0xa8, 0x39, 0x0d, 0xdf,
- 0x2f, 0x44, 0x65, 0x62, 0xe1, 0x47, 0x91, 0x8d, 0xbf, 0x61, 0x78, 0x54,
- 0x72, 0xa7, 0x69, 0xa3, 0xa7, 0xe5, 0xf1, 0x8a, 0xef, 0xdf, 0xe9, 0x11,
- 0x5b, 0x6e, 0x96, 0xcb, 0xf1, 0xb1, 0x3d, 0x6f, 0xb8, 0x1d, 0xa1, 0xea,
- 0x6c, 0x33, 0x74, 0x2f, 0xf1, 0x8c, 0xb4, 0x30, 0xbf, 0x30, 0xcb, 0x7d,
- 0x1a, 0xc1, 0x1a, 0x1d, 0xfb, 0x9a, 0xdc, 0xde, 0xce, 0xb8, 0xdb, 0x9d,
- 0xf0, 0x65, 0x7f, 0xdb, 0x0b, 0xf4, 0xf5, 0xe7, 0x16, 0xf7, 0xca, 0xe7,
- 0x6a, 0xb1, 0x50, 0x75, 0x86, 0xf7, 0x0d, 0x9d, 0x91, 0x8a, 0xa4, 0x50,
- 0x8f, 0xfd, 0x43, 0x5e, 0x12, 0xd7, 0xc9, 0xb3, 0x27, 0x7f, 0xea, 0x5f,
- 0x73, 0xf1, 0x1e, 0xba, 0xe6, 0xb2, 0x67, 0x62, 0x8b, 0x63, 0xf0, 0x5d,
- 0x59, 0xef, 0x3a, 0xc8, 0x01, 0xb0, 0x03, 0xf6, 0x1c, 0xfd, 0xdc, 0x6b,
- 0x5a, 0x6f, 0x59, 0xc7, 0x6e, 0x92, 0x6b, 0x2b, 0xf7, 0x95, 0x5f, 0x83,
- 0x6c, 0x27, 0x03, 0xfa, 0xab, 0x58, 0xfc, 0x21, 0x09, 0x7f, 0x1e, 0x36,
- 0xe5, 0xf3, 0x4d, 0x4a, 0xb7, 0xd3, 0xb6, 0xc1, 0x07, 0x82, 0x9f, 0x13,
- 0x41, 0x3f, 0xa9, 0xf6, 0x40, 0x66, 0xa7, 0x45, 0xbe, 0xb0, 0x49, 0xb2,
- 0xed, 0xf4, 0xa3, 0xe5, 0xe7, 0xe8, 0xaf, 0xc6, 0x7d, 0x96, 0x96, 0x3f,
- 0xe2, 0x1e, 0xaf, 0x73, 0x2d, 0xa9, 0xc4, 0x9f, 0xc9, 0xa7, 0x65, 0x22,
- 0xc1, 0xb5, 0x3c, 0x2a, 0xc5, 0xca, 0x63, 0xf8, 0x71, 0x9d, 0x9c, 0xf7,
- 0xc7, 0xf4, 0x5d, 0x86, 0x31, 0x29, 0xcd, 0x64, 0x64, 0x6a, 0x6e, 0x92,
- 0xdf, 0xa0, 0x8e, 0xdc, 0xa9, 0xce, 0xf8, 0x9c, 0x44, 0x2a, 0xb4, 0x2d,
- 0x39, 0xc5, 0xbb, 0x1b, 0x6a, 0x3d, 0x93, 0x58, 0xcf, 0xe3, 0xed, 0xbc,
- 0xb3, 0x7e, 0x0d, 0xfa, 0xd7, 0x3a, 0x45, 0x39, 0x74, 0xec, 0xee, 0x10,
- 0xf3, 0xfb, 0xe0, 0xbf, 0xb3, 0x6c, 0x9f, 0x84, 0x8f, 0xad, 0xe8, 0x79,
- 0x94, 0xeb, 0xb3, 0x66, 0xd5, 0xfe, 0x14, 0xda, 0xa2, 0xde, 0x31, 0xd3,
- 0xd6, 0xd4, 0x61, 0x5b, 0xae, 0x73, 0xaf, 0x34, 0x9f, 0x33, 0xf3, 0x82,
- 0x1c, 0x26, 0x1a, 0xe9, 0xdd, 0xb2, 0x8e, 0xde, 0x11, 0x62, 0x5e, 0xd0,
- 0x8b, 0x34, 0x0e, 0x6b, 0x1a, 0x7f, 0x05, 0xfd, 0x1b, 0x1e, 0xdc, 0x89,
- 0x32, 0x5b, 0x7f, 0x93, 0xf4, 0x7e, 0xe8, 0x4e, 0x9a, 0xb3, 0x3e, 0xe9,
- 0x4e, 0xd9, 0xe2, 0x7c, 0x36, 0xa2, 0xf9, 0xeb, 0x9a, 0x2f, 0xfb, 0x40,
- 0x2f, 0xde, 0x2b, 0xdd, 0xa6, 0xbe, 0x2f, 0xc8, 0x8e, 0xef, 0x83, 0xec,
- 0x98, 0x75, 0x6d, 0x83, 0x8c, 0xf1, 0xdc, 0x84, 0xf5, 0x1b, 0x69, 0x12,
- 0xd8, 0xbd, 0x30, 0x63, 0x1f, 0x2e, 0xd7, 0x0a, 0x5c, 0xfa, 0x05, 0xda,
- 0x28, 0x7e, 0x63, 0x7d, 0xb3, 0xb6, 0x51, 0x3f, 0x8f, 0xc7, 0x3f, 0x6a,
- 0x0f, 0x6c, 0x94, 0x0d, 0x9a, 0xb4, 0xe9, 0x36, 0xfb, 0x80, 0x91, 0x19,
- 0x0f, 0x4e, 0x25, 0x1e, 0x14, 0x33, 0x8e, 0xbf, 0x9b, 0x7e, 0xef, 0xd0,
- 0xc0, 0x36, 0xa0, 0x16, 0x75, 0x67, 0x27, 0xc1, 0x3b, 0x40, 0xa9, 0xd0,
- 0x3e, 0x75, 0x7f, 0x63, 0xed, 0xf7, 0x23, 0x69, 0x79, 0x76, 0x55, 0x56,
- 0x46, 0x7e, 0x28, 0x8e, 0x24, 0x6f, 0xa4, 0xac, 0xb0, 0xdf, 0x49, 0xae,
- 0x33, 0xf1, 0x90, 0x5a, 0xa7, 0x0d, 0x3f, 0x92, 0x77, 0x2d, 0xec, 0x50,
- 0x75, 0x8e, 0x7c, 0x47, 0xba, 0xc8, 0x67, 0x73, 0xde, 0xab, 0xf4, 0x0a,
- 0xc6, 0x65, 0x19, 0x75, 0x23, 0xdf, 0x67, 0xf4, 0x79, 0x70, 0x7b, 0x07,
- 0xef, 0x24, 0x14, 0x50, 0x56, 0x59, 0xdc, 0x78, 0x6e, 0xbf, 0xad, 0xe4,
- 0xe0, 0x51, 0xd0, 0xfd, 0x9f, 0xa1, 0xee, 0x63, 0x48, 0xb9, 0xc6, 0xcc,
- 0x0a, 0xdf, 0x49, 0xef, 0x8f, 0xca, 0x20, 0xe4, 0x82, 0xf9, 0x47, 0x81,
- 0x37, 0x69, 0x4f, 0x91, 0x56, 0xf8, 0x4c, 0x5d, 0xef, 0x6a, 0x7b, 0xca,
- 0xb9, 0xec, 0xc3, 0x5c, 0xd4, 0x3a, 0xb5, 0x3c, 0xdd, 0xaf, 0xdb, 0x8d,
- 0xaf, 0xd0, 0xea, 0xa1, 0x77, 0xe0, 0x8d, 0xe8, 0x0a, 0xde, 0x08, 0xc6,
- 0xca, 0x76, 0x18, 0xac, 0x11, 0xac, 0x21, 0xc0, 0x1a, 0x81, 0x9c, 0x4f,
- 0x4a, 0x04, 0x72, 0x1c, 0x5e, 0x95, 0x63, 0xe0, 0x9e, 0x60, 0xcf, 0x4c,
- 0xf1, 0x1c, 0x53, 0xd1, 0x99, 0x72, 0x48, 0xf9, 0x25, 0x1f, 0x1b, 0x79,
- 0x7d, 0xfb, 0xbb, 0xf0, 0xba, 0xd4, 0x61, 0xf0, 0xc3, 0x3f, 0x6c, 0x1f,
- 0x3c, 0xd2, 0xb1, 0xba, 0x0f, 0x6e, 0xfa, 0x05, 0xed, 0x83, 0xf5, 0x72,
- 0xd9, 0x28, 0x53, 0x36, 0xe4, 0x89, 0xfc, 0xa2, 0x3c, 0x51, 0x8e, 0x48,
- 0x4b, 0xea, 0xd3, 0x66, 0xfa, 0x6f, 0x89, 0xab, 0xea, 0xdb, 0x91, 0x69,
- 0xe8, 0xa0, 0x8e, 0x50, 0xa5, 0x12, 0x97, 0xd2, 0xe2, 0x4f, 0x94, 0x4c,
- 0x3f, 0x5b, 0xa7, 0x5e, 0x7a, 0xaf, 0xb5, 0xaf, 0xd5, 0xb9, 0x85, 0x75,
- 0x3a, 0xb7, 0xb0, 0xa2, 0x73, 0xdb, 0xb5, 0xcf, 0xf6, 0x0f, 0xd1, 0xb9,
- 0xf1, 0x86, 0xb3, 0x21, 0x73, 0x2e, 0x24, 0xa1, 0x5c, 0x5f, 0x8b, 0xec,
- 0x81, 0x1d, 0x19, 0x99, 0xd9, 0x2b, 0x7f, 0x30, 0x33, 0xad, 0xee, 0x49,
- 0x7d, 0xd3, 0x4b, 0x25, 0x3e, 0x11, 0xf2, 0xe5, 0xa3, 0xf0, 0xb9, 0x27,
- 0xba, 0x9a, 0x64, 0xcf, 0x6d, 0xea, 0xbc, 0xd3, 0xce, 0x85, 0x3a, 0x85,
- 0x91, 0xf8, 0xbc, 0xe7, 0x78, 0xc9, 0x10, 0xef, 0xcc, 0x35, 0xcb, 0x44,
- 0xbc, 0x55, 0xf6, 0x02, 0x3b, 0x15, 0xaf, 0xf7, 0xd4, 0x37, 0xd3, 0x59,
- 0x75, 0x9e, 0xf4, 0x86, 0xe6, 0x3b, 0xe8, 0xd0, 0x66, 0xcb, 0x7f, 0xac,
- 0x33, 0xcf, 0xf2, 0x07, 0xd7, 0xe5, 0xf9, 0xfc, 0x04, 0xfc, 0xb9, 0x38,
- 0x68, 0xd5, 0x78, 0xff, 0x28, 0xac, 0xe8, 0x59, 0xaa, 0x8c, 0xab, 0x7b,
- 0x5d, 0x57, 0xc3, 0xa4, 0x97, 0xf2, 0xa1, 0x12, 0xb9, 0x30, 0x30, 0xce,
- 0x2c, 0x90, 0xb4, 0x4b, 0xbf, 0x53, 0xe3, 0x4f, 0xe8, 0xff, 0xfd, 0xea,
- 0x7c, 0x79, 0x19, 0xb4, 0xf1, 0x55, 0xfc, 0xb9, 0x10, 0x27, 0xae, 0x5f,
- 0xbd, 0xc3, 0xfc, 0x4e, 0x7c, 0xaf, 0xb0, 0xbd, 0x39, 0x0b, 0xd1, 0xf1,
- 0x2a, 0x1d, 0x07, 0x50, 0x67, 0x7b, 0x1b, 0xfd, 0xbf, 0x0b, 0xc4, 0x7a,
- 0xfc, 0xae, 0x9f, 0xd8, 0xce, 0x39, 0x5a, 0x91, 0x1f, 0x2a, 0x5f, 0x34,
- 0x4b, 0xfa, 0x56, 0xc1, 0xa7, 0xe3, 0x09, 0x63, 0xcf, 0x43, 0xdd, 0xe7,
- 0x1b, 0x7d, 0x51, 0xf6, 0x11, 0x53, 0x77, 0x42, 0x56, 0xff, 0x9f, 0x17,
- 0xc6, 0x98, 0xb2, 0xa1, 0xbb, 0xcb, 0xd3, 0x12, 0x3e, 0x31, 0x26, 0x91,
- 0xe3, 0x8c, 0xe7, 0x67, 0xa5, 0x14, 0xf7, 0xe5, 0x01, 0x6f, 0xad, 0x6f,
- 0xd2, 0x6d, 0xad, 0x9f, 0xfb, 0xa3, 0x32, 0x74, 0xfa, 0x31, 0x89, 0x9e,
- 0xe0, 0xbb, 0x35, 0x67, 0x39, 0xd0, 0x47, 0x9b, 0xa5, 0x12, 0x67, 0x4c,
- 0x3b, 0xaa, 0xce, 0xc6, 0x2f, 0x8f, 0xbf, 0x1e, 0x2d, 0x01, 0x2b, 0x14,
- 0x94, 0x6e, 0x41, 0xba, 0xe2, 0x4b, 0xe4, 0xae, 0xe3, 0x9e, 0x82, 0xbf,
- 0x19, 0x9a, 0xa8, 0x44, 0xd5, 0x1d, 0xa5, 0xcb, 0x71, 0xd6, 0x7d, 0x0c,
- 0x7e, 0x37, 0x71, 0x06, 0x74, 0xc7, 0x98, 0xb4, 0x30, 0x1f, 0x3e, 0xb1,
- 0x8a, 0x33, 0xa8, 0x13, 0x86, 0xbc, 0xb8, 0x44, 0xce, 0x04, 0x6b, 0xe7,
- 0x7f, 0x1c, 0x64, 0xcd, 0xef, 0x95, 0xf0, 0x71, 0x3e, 0x37, 0xfa, 0x43,
- 0xc4, 0xee, 0xb0, 0x0d, 0xe7, 0x7f, 0x1f, 0xfd, 0xf1, 0x5d, 0x56, 0x7f,
- 0x87, 0x8b, 0x7c, 0xf5, 0xef, 0xfa, 0x7f, 0x04, 0x50, 0xf6, 0xff, 0x3f,
- 0xc3, 0x8e, 0xbb, 0xb0, 0xa8, 0x4d, 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_COM_b06FwRodata[(0x14/4) + 1] = {
- 0x08000e7c, 0x08000ec4, 0x08000f04, 0x08000f50, 0x08000f84, 0x00000000
-};
-
-static struct fw_info bnx2_com_fw_06 = {
- /* Firmware version: 4.6.16 */
- .ver_major = 0x4,
- .ver_minor = 0x6,
- .ver_fix = 0x10,
-
- .start_addr = 0x080000f8,
-
- .text_addr = 0x08000000,
- .text_len = 0x4da4,
- .text_index = 0x0,
- .gz_text = bnx2_COM_b06FwText,
- .gz_text_len = sizeof(bnx2_COM_b06FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_COM_b06FwData,
-
- .sbss_addr = 0x08004de0,
- .sbss_len = 0x38,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08004e18,
- .bss_len = 0xbc,
- .bss_index = 0x0,
-
- .rodata_addr = 0x08004da4,
- .rodata_len = 0x14,
- .rodata_index = 0x0,
- .rodata = bnx2_COM_b06FwRodata,
-};
-
/* Initialized Values for the Completion Processor. */
static const struct cpu_reg cpu_reg_com = {
.mode = BNX2_COM_CPU_MODE,
@@ -897,1277 +23,6 @@ static const struct cpu_reg cpu_reg_com = {
.mips_view_base = 0x8000000,
};
-static u8 bnx2_CP_b06FwText[] = {
- 0x9d, 0xbc, 0x0d, 0x7c, 0x1b, 0xe5, 0x95, 0x2e, 0xfe, 0xcc, 0x48, 0xb2,
- 0x65, 0x5b, 0xb6, 0xc7, 0x8e, 0x92, 0x28, 0xac, 0x37, 0xd1, 0xc4, 0x23,
- 0x47, 0xc1, 0xa6, 0x8c, 0x12, 0x27, 0xa8, 0xac, 0x4a, 0x54, 0xc7, 0x24,
- 0x4e, 0x48, 0xc1, 0x29, 0x69, 0x6b, 0xb8, 0x2d, 0xa8, 0xf9, 0xc2, 0x84,
- 0x40, 0x43, 0xcb, 0xde, 0x6b, 0xee, 0xed, 0xae, 0x55, 0xdb, 0x49, 0x9c,
- 0x44, 0x96, 0x6c, 0xc7, 0x24, 0xa1, 0xdb, 0xff, 0xa2, 0xc4, 0xce, 0x07,
- 0x54, 0xb6, 0xd2, 0x96, 0xee, 0x86, 0xde, 0x74, 0xd1, 0x4d, 0x02, 0x18,
- 0xca, 0x47, 0xda, 0xe5, 0x76, 0x69, 0x7f, 0xbd, 0xc5, 0x97, 0x42, 0x08,
- 0x5b, 0x0a, 0xe9, 0xe7, 0x86, 0x7e, 0x30, 0xf7, 0x39, 0x23, 0x29, 0x31,
- 0x2c, 0xdb, 0x76, 0xff, 0xfa, 0xfd, 0xe6, 0x27, 0xcd, 0xe8, 0xfd, 0x38,
- 0xef, 0x79, 0xcf, 0x79, 0xce, 0x73, 0xde, 0x79, 0x67, 0xfc, 0x40, 0x39,
- 0x0a, 0x9f, 0x4a, 0x1e, 0x1f, 0x6a, 0xde, 0xb6, 0x61, 0x69, 0xe8, 0x43,
- 0x4b, 0xe5, 0xdc, 0xa9, 0x95, 0x38, 0xf1, 0x67, 0x7e, 0xfc, 0x7f, 0x6e,
- 0xc1, 0xc2, 0x47, 0xe1, 0xd1, 0x58, 0xf8, 0xed, 0x00, 0xb4, 0x62, 0xff,
- 0x72, 0xc0, 0xad, 0x46, 0xc6, 0x3a, 0x5a, 0x0c, 0xb8, 0x1d, 0x91, 0x6d,
- 0xb7, 0x6f, 0x30, 0x80, 0x68, 0xa6, 0xd1, 0xbf, 0x1c, 0x7f, 0xb0, 0xe2,
- 0x5e, 0x27, 0xe4, 0xfa, 0x5f, 0x46, 0x7e, 0xdf, 0xfd, 0xed, 0x6b, 0xf4,
- 0x0b, 0x69, 0x07, 0xdc, 0x5a, 0x24, 0x0e, 0xad, 0x01, 0xee, 0x3a, 0xd6,
- 0xf9, 0xca, 0x82, 0xaf, 0x28, 0xa8, 0x2a, 0xb6, 0x75, 0xde, 0xfa, 0xf6,
- 0x02, 0x5f, 0xac, 0x2c, 0xa2, 0xe1, 0xf1, 0x2c, 0xda, 0x9b, 0x06, 0xba,
- 0xad, 0x4a, 0x23, 0x04, 0xb7, 0x61, 0x74, 0x0c, 0x28, 0x9e, 0xf0, 0x96,
- 0x25, 0xf0, 0x94, 0x1a, 0x88, 0x5f, 0x11, 0x41, 0xfb, 0x95, 0xe3, 0xe5,
- 0x71, 0x67, 0xc4, 0x8d, 0xb6, 0xac, 0x3b, 0xfe, 0x17, 0x11, 0x03, 0x2b,
- 0xb3, 0x46, 0x19, 0xaa, 0x34, 0xf4, 0x65, 0x5f, 0x77, 0xe7, 0xdb, 0x6b,
- 0x2e, 0x7c, 0xdf, 0x56, 0x9b, 0xff, 0x9e, 0x15, 0x73, 0x46, 0x80, 0xed,
- 0x09, 0xcb, 0x2a, 0x89, 0xdc, 0x7c, 0xb3, 0x1a, 0x31, 0x7c, 0x47, 0xb0,
- 0x0c, 0xeb, 0x35, 0x7c, 0x71, 0x47, 0xf3, 0x2f, 0x94, 0x53, 0x23, 0x4d,
- 0x88, 0x1f, 0x75, 0x20, 0xaa, 0x3d, 0xcb, 0xef, 0xb9, 0x73, 0x3b, 0xc2,
- 0x4d, 0x38, 0x70, 0xf4, 0x22, 0xaf, 0x3b, 0xed, 0x6b, 0xbd, 0xfb, 0xe7,
- 0xce, 0xbd, 0x25, 0xfc, 0x2c, 0x1e, 0x3c, 0x2a, 0xbf, 0xef, 0x40, 0x77,
- 0x93, 0x82, 0xa9, 0x9b, 0x37, 0xc3, 0x61, 0x34, 0xa1, 0x6f, 0xbf, 0xe2,
- 0xec, 0x69, 0x52, 0x11, 0xf5, 0xea, 0xc1, 0x18, 0x27, 0xc1, 0x69, 0x20,
- 0x56, 0x1a, 0x09, 0x3b, 0xdf, 0x48, 0x44, 0x34, 0x87, 0x61, 0x59, 0xc1,
- 0xd0, 0x6c, 0x38, 0x6a, 0x2c, 0xeb, 0x31, 0xd3, 0x03, 0xff, 0xa7, 0x9e,
- 0x47, 0x7c, 0xb4, 0x1d, 0xaa, 0xf1, 0x3c, 0x7a, 0x46, 0x9f, 0xc7, 0x43,
- 0x7b, 0xcb, 0x31, 0x35, 0x83, 0xe3, 0x4d, 0xf9, 0xf0, 0xed, 0x05, 0xd2,
- 0xb7, 0xc8, 0xd1, 0xcc, 0xc3, 0x8d, 0x29, 0xc7, 0x39, 0x7e, 0x4b, 0x99,
- 0x8b, 0xd6, 0xd4, 0xec, 0xcb, 0x65, 0xb6, 0xb3, 0x4c, 0xdf, 0xfb, 0xca,
- 0xc4, 0x47, 0x23, 0xf8, 0x4e, 0x42, 0xc1, 0x96, 0x50, 0x15, 0xa2, 0x35,
- 0x32, 0x5e, 0xcb, 0x3a, 0x6a, 0x9e, 0xb3, 0xa6, 0x34, 0xe9, 0x6b, 0x12,
- 0xcf, 0xf2, 0xbf, 0x1d, 0xa1, 0x57, 0xad, 0x9c, 0x57, 0xda, 0xfb, 0x3c,
- 0x6d, 0x68, 0x2d, 0xaf, 0x3b, 0x91, 0x4a, 0x20, 0x56, 0x15, 0xf9, 0x04,
- 0xcf, 0x75, 0xf3, 0x2d, 0xc5, 0xed, 0x7e, 0x3b, 0xe1, 0xfe, 0x54, 0xa5,
- 0xa1, 0xde, 0x57, 0x0d, 0x27, 0x9e, 0xa3, 0xcc, 0x27, 0xcc, 0xcd, 0x70,
- 0x19, 0x5f, 0x10, 0x9b, 0xe3, 0xb8, 0x5e, 0xb4, 0x30, 0xbb, 0x58, 0x5f,
- 0xda, 0xd5, 0xb0, 0x23, 0x65, 0x59, 0xbb, 0xcc, 0xe8, 0x87, 0xcb, 0x68,
- 0x10, 0xa7, 0x13, 0xed, 0x70, 0x47, 0x02, 0xfe, 0xf3, 0x08, 0x63, 0x79,
- 0xd6, 0x8b, 0x27, 0x12, 0x70, 0xb6, 0x2c, 0xa8, 0x43, 0x4f, 0x36, 0x82,
- 0xeb, 0xb3, 0x26, 0x5a, 0xb3, 0x7f, 0xda, 0xca, 0x6e, 0x48, 0xf9, 0x39,
- 0x86, 0x3f, 0x58, 0xf9, 0x31, 0xc8, 0xf8, 0xe4, 0x9b, 0xf3, 0x9a, 0xba,
- 0x02, 0xbb, 0x47, 0x0c, 0xec, 0xe4, 0xfc, 0xad, 0x0a, 0xe5, 0xa2, 0x65,
- 0xd0, 0xcd, 0xf3, 0x88, 0x60, 0x45, 0xd6, 0xe0, 0x9c, 0x46, 0xb0, 0x3c,
- 0x55, 0xaf, 0x8d, 0x62, 0x21, 0xa2, 0xbe, 0xbc, 0x6d, 0xef, 0xe1, 0x78,
- 0xd7, 0x07, 0xda, 0x51, 0x49, 0x1b, 0xc9, 0x2c, 0x09, 0xa3, 0x85, 0xfd,
- 0xaf, 0xf9, 0x33, 0xfa, 0xbf, 0x89, 0xfd, 0xbf, 0xc5, 0xfe, 0x73, 0x76,
- 0xff, 0x70, 0xae, 0xe6, 0xb9, 0x9b, 0xf6, 0xb8, 0x3b, 0xe3, 0x74, 0xae,
- 0x4a, 0x79, 0xb1, 0x2b, 0x63, 0xd2, 0xe6, 0xe4, 0x2f, 0x1f, 0x76, 0x8c,
- 0xd4, 0x61, 0xe7, 0x88, 0xee, 0x7b, 0x8a, 0xbf, 0x7b, 0xc7, 0xae, 0xc0,
- 0xf6, 0x11, 0x05, 0x87, 0x8c, 0x2b, 0xd0, 0xc3, 0xdf, 0x07, 0x46, 0xe6,
- 0xe2, 0xc1, 0x11, 0x07, 0xc2, 0x33, 0xa6, 0x8f, 0x43, 0xbe, 0xaf, 0x40,
- 0x7c, 0xcc, 0x8f, 0x9e, 0xc4, 0xb3, 0xb6, 0x0e, 0x2b, 0x23, 0xdf, 0x2e,
- 0xfa, 0x33, 0x7d, 0xc7, 0x8f, 0x0d, 0x09, 0x1f, 0x7a, 0x52, 0xe2, 0x07,
- 0x6e, 0xda, 0xa6, 0xf8, 0xc1, 0xaf, 0x80, 0x2a, 0xb6, 0x9f, 0x2d, 0xfe,
- 0xaf, 0xc0, 0xc9, 0x79, 0xdb, 0xc8, 0xff, 0x76, 0xa5, 0xc4, 0x26, 0xa4,
- 0x4d, 0xb1, 0x0b, 0xf9, 0x5d, 0x4b, 0xbb, 0x2b, 0x87, 0xff, 0x70, 0x39,
- 0x82, 0x0f, 0x68, 0x78, 0xad, 0x59, 0xae, 0xd3, 0xde, 0x43, 0x52, 0x66,
- 0x10, 0x47, 0x32, 0xe2, 0xa7, 0x7e, 0xb4, 0x24, 0x26, 0xd9, 0x7e, 0x33,
- 0xdb, 0x36, 0xf1, 0x4f, 0xd9, 0x26, 0xfc, 0x63, 0x36, 0x88, 0x7f, 0xa0,
- 0x1e, 0xbf, 0x99, 0xf5, 0xe3, 0xd1, 0x6c, 0x1d, 0xbe, 0x91, 0xf5, 0xe1,
- 0xeb, 0x9c, 0xbf, 0xaf, 0x65, 0xdb, 0x69, 0xfb, 0x1a, 0x8e, 0x67, 0x45,
- 0xff, 0x25, 0x1c, 0x6f, 0x39, 0x7a, 0x47, 0xea, 0x83, 0xa7, 0x69, 0x5b,
- 0xff, 0x60, 0xae, 0x46, 0xae, 0xb6, 0xd9, 0xb6, 0xc9, 0x5d, 0xbc, 0xbe,
- 0x7b, 0xa4, 0x3e, 0x7a, 0xa5, 0x62, 0x59, 0x6a, 0xa8, 0x31, 0x7c, 0x4a,
- 0x55, 0x31, 0xe5, 0xd5, 0xfd, 0x39, 0x55, 0xf7, 0x47, 0xe1, 0x42, 0x82,
- 0xbe, 0x11, 0x9f, 0xa9, 0xa7, 0xe3, 0xb4, 0x29, 0xaf, 0x31, 0xca, 0xf1,
- 0xe8, 0xfe, 0xb8, 0xaa, 0x61, 0x67, 0x4a, 0x3f, 0x10, 0x57, 0xbd, 0x88,
- 0x67, 0xcb, 0xf1, 0xb3, 0x11, 0xbd, 0x3f, 0xae, 0xde, 0x88, 0x78, 0xad,
- 0x65, 0x7d, 0x3d, 0x84, 0x6d, 0xb3, 0x23, 0x88, 0xce, 0x8c, 0x20, 0x36,
- 0x37, 0x52, 0x87, 0x54, 0x0a, 0x78, 0x6b, 0xc0, 0xf0, 0xfd, 0x8b, 0xd2,
- 0x8e, 0xbf, 0x6e, 0xd7, 0xfd, 0x7e, 0xb5, 0x31, 0x3e, 0xaa, 0x2e, 0xa1,
- 0x4b, 0xc3, 0xef, 0x8b, 0xac, 0x44, 0x97, 0x7d, 0x4d, 0x81, 0x66, 0x78,
- 0xd1, 0x9b, 0xfa, 0x30, 0x62, 0xde, 0xfa, 0x8e, 0x21, 0xb5, 0xfe, 0xa2,
- 0xa9, 0xea, 0x93, 0xed, 0xaa, 0x65, 0xfd, 0x7c, 0xf1, 0x5b, 0x96, 0x7f,
- 0x96, 0x65, 0x2d, 0x5a, 0x2c, 0x7d, 0xfa, 0x51, 0x13, 0x31, 0xb1, 0xd6,
- 0x9e, 0xc3, 0x72, 0x9c, 0x1b, 0xa9, 0x65, 0x1f, 0x1a, 0xfe, 0xf7, 0x35,
- 0x7a, 0x70, 0xb3, 0x5a, 0x8e, 0xd7, 0xc6, 0xca, 0xf1, 0x0a, 0xc7, 0xf3,
- 0x8b, 0x11, 0x1f, 0x7e, 0x35, 0x62, 0x59, 0x9f, 0x32, 0xff, 0x0a, 0xc3,
- 0xb5, 0x83, 0xf8, 0xc7, 0x09, 0x2f, 0x7e, 0x96, 0xd0, 0xf0, 0x6a, 0x22,
- 0x7a, 0xef, 0x0c, 0xe8, 0xd1, 0x09, 0xe5, 0xf4, 0xed, 0x55, 0x68, 0x6c,
- 0xaf, 0x52, 0xf4, 0xb6, 0x3d, 0xd0, 0x7d, 0x57, 0x2a, 0x5e, 0x9c, 0xcf,
- 0x68, 0xf8, 0x49, 0xa6, 0x3e, 0xfc, 0xcf, 0xec, 0xf3, 0x37, 0xe6, 0x63,
- 0x56, 0x6e, 0x96, 0xe8, 0x4d, 0x74, 0x44, 0x3d, 0xa7, 0xa8, 0xe7, 0x14,
- 0xf5, 0x9c, 0xa2, 0x9e, 0x29, 0xc3, 0xa3, 0x29, 0xea, 0x99, 0xba, 0xfb,
- 0x3a, 0x6d, 0xea, 0x6b, 0x9c, 0xc7, 0xe3, 0xf6, 0x3c, 0x86, 0x39, 0x5f,
- 0x7f, 0x81, 0xbf, 0xb5, 0xb1, 0xf5, 0x59, 0xeb, 0xbf, 0x79, 0x65, 0x4c,
- 0x0f, 0xcf, 0xcc, 0xe3, 0x97, 0x8c, 0xed, 0x3b, 0x56, 0x4c, 0x93, 0x71,
- 0xc9, 0xf8, 0x6c, 0xfd, 0xf9, 0xb7, 0x29, 0x3b, 0x15, 0x94, 0x5b, 0xd6,
- 0x5e, 0xb3, 0xf0, 0xbf, 0xb7, 0x38, 0xbe, 0x9b, 0x95, 0xbc, 0x5d, 0xfd,
- 0x5d, 0x29, 0xf5, 0x1d, 0x8c, 0xaa, 0x2b, 0x79, 0xae, 0xc7, 0xa3, 0xf8,
- 0xa8, 0xe3, 0xbd, 0xe7, 0xf7, 0x7a, 0x65, 0x3e, 0xfc, 0x97, 0xce, 0x69,
- 0x8f, 0x76, 0x7f, 0x77, 0xf2, 0x5c, 0xc6, 0x22, 0xb6, 0x28, 0x36, 0xe0,
- 0xa5, 0xbd, 0x5c, 0x53, 0xf8, 0x0f, 0x71, 0x35, 0xb2, 0x0d, 0xed, 0xcd,
- 0x8f, 0xd8, 0x7d, 0x94, 0x24, 0xc5, 0x6f, 0x14, 0xbc, 0xf5, 0x61, 0x05,
- 0xa7, 0x42, 0x06, 0x6d, 0xe6, 0x18, 0x71, 0x01, 0x28, 0x4d, 0xc2, 0xed,
- 0x89, 0x44, 0x90, 0x18, 0x80, 0xbb, 0x2c, 0x12, 0xc6, 0xc2, 0x81, 0xfa,
- 0xce, 0x73, 0xd0, 0x83, 0x03, 0x8a, 0xde, 0xce, 0x58, 0x62, 0x8e, 0x53,
- 0x8f, 0x57, 0x2a, 0xba, 0xbf, 0x44, 0x81, 0x5b, 0x61, 0xb9, 0x40, 0xe6,
- 0x18, 0x76, 0x66, 0xe5, 0x77, 0x18, 0x46, 0xe6, 0x37, 0xc5, 0xbe, 0x24,
- 0xa6, 0xd0, 0xee, 0xcf, 0x71, 0xec, 0xba, 0x9f, 0xf8, 0xea, 0x76, 0x45,
- 0x3a, 0x71, 0x38, 0x01, 0x77, 0x49, 0x64, 0x2b, 0x9e, 0x4c, 0x84, 0x67,
- 0x16, 0xcb, 0x29, 0x2c, 0xe7, 0xcf, 0x4c, 0x97, 0xe5, 0xc7, 0x56, 0xd4,
- 0x9b, 0x97, 0xa5, 0x3c, 0x79, 0x0c, 0x7b, 0x52, 0x52, 0x37, 0x62, 0xd7,
- 0x75, 0xb2, 0x8f, 0xbe, 0x44, 0x7d, 0xdb, 0x0d, 0x8a, 0x1e, 0x7e, 0x98,
- 0xf3, 0xd7, 0x83, 0xc6, 0xe8, 0x1b, 0xd0, 0xb5, 0x4e, 0xe4, 0x65, 0x59,
- 0x90, 0xc9, 0xcb, 0x31, 0x3f, 0x03, 0xe5, 0xf6, 0x14, 0xac, 0x39, 0x06,
- 0x3c, 0x3e, 0xc3, 0xf0, 0xbf, 0xe3, 0xa8, 0xc5, 0x01, 0xce, 0x4f, 0x1f,
- 0x7d, 0x45, 0xf0, 0xec, 0xee, 0xbd, 0x7e, 0x78, 0x0c, 0x0b, 0x47, 0x42,
- 0xb5, 0x78, 0x96, 0x58, 0x5b, 0x45, 0xdf, 0x7c, 0x5e, 0x43, 0x74, 0x4e,
- 0x24, 0xac, 0xdc, 0x92, 0x1d, 0x2d, 0xcc, 0xc1, 0x8b, 0x35, 0x05, 0x19,
- 0xdf, 0x77, 0xbd, 0x5a, 0xf9, 0xe0, 0xeb, 0x50, 0x3a, 0x52, 0x7a, 0x30,
- 0x0e, 0x0b, 0xd5, 0x8b, 0x75, 0xff, 0x94, 0xf2, 0x96, 0x8a, 0x2a, 0x62,
- 0x75, 0xf6, 0xfd, 0xe5, 0x1a, 0xb5, 0x31, 0xc6, 0x65, 0x07, 0x43, 0x5f,
- 0x54, 0xd3, 0x4d, 0x36, 0x13, 0x74, 0xd9, 0xd7, 0x1c, 0x48, 0x3b, 0xa3,
- 0x3e, 0x07, 0x7e, 0x6f, 0x45, 0xd7, 0xc9, 0xb5, 0x72, 0xc4, 0xda, 0x1b,
- 0x7d, 0x4e, 0x34, 0x86, 0xb7, 0xd3, 0x07, 0xa7, 0xd6, 0xb5, 0xf0, 0xbf,
- 0x80, 0x79, 0x1a, 0xf5, 0xfe, 0xed, 0x90, 0xdf, 0xef, 0xd0, 0x6e, 0x5a,
- 0xa4, 0x2e, 0xcb, 0x88, 0x1d, 0xea, 0x9a, 0xf8, 0x78, 0x9f, 0x69, 0x59,
- 0x87, 0xcd, 0x13, 0x4a, 0x4b, 0xea, 0x5d, 0x2b, 0xea, 0x8c, 0x47, 0x4b,
- 0x23, 0x01, 0x73, 0x27, 0xc1, 0xd8, 0x11, 0x89, 0x2b, 0xd1, 0x6c, 0x9f,
- 0x72, 0x7d, 0xb6, 0x5f, 0x59, 0x91, 0x95, 0xf2, 0x27, 0x94, 0xe5, 0x59,
- 0x29, 0x5f, 0x2c, 0x1b, 0x66, 0x59, 0xe0, 0x48, 0x22, 0x10, 0x2c, 0x96,
- 0x5f, 0xc1, 0xb2, 0xd7, 0x5f, 0x2a, 0x1b, 0xa6, 0xad, 0x9a, 0x9c, 0x97,
- 0x0a, 0x6c, 0xd6, 0xf4, 0x68, 0x9c, 0x3a, 0x2f, 0x8d, 0xf8, 0x6e, 0x7d,
- 0xdd, 0xc8, 0x05, 0x1d, 0x9c, 0x83, 0xa3, 0x1c, 0x59, 0x2b, 0x71, 0x6e,
- 0x83, 0xe1, 0x42, 0xbf, 0x56, 0x8d, 0x0d, 0xe6, 0x6f, 0xad, 0xcd, 0xeb,
- 0xe4, 0xbf, 0xbc, 0x6c, 0xb0, 0xcb, 0xd7, 0xb1, 0xbc, 0x6e, 0x1e, 0x2d,
- 0x60, 0xeb, 0xa9, 0x04, 0x06, 0x1d, 0x11, 0x62, 0x7e, 0x73, 0xc0, 0xdf,
- 0x03, 0x99, 0x1b, 0x3f, 0xae, 0xa7, 0x2c, 0x69, 0xe7, 0x74, 0xfc, 0x45,
- 0xfc, 0x72, 0x19, 0xb9, 0x26, 0xe5, 0xa6, 0x68, 0xdf, 0x82, 0x75, 0x96,
- 0x35, 0x64, 0x8a, 0x9d, 0xfb, 0x68, 0xe7, 0x33, 0xe1, 0xaf, 0xd5, 0xe3,
- 0x69, 0x56, 0x38, 0x9c, 0x98, 0x81, 0xb4, 0xa6, 0x12, 0x73, 0xef, 0xf2,
- 0xa0, 0x2a, 0xaa, 0x94, 0x90, 0xdb, 0x60, 0x42, 0xc6, 0x59, 0x89, 0xa8,
- 0x53, 0x0f, 0xca, 0xdc, 0x95, 0x30, 0xe6, 0x35, 0xa8, 0xac, 0x77, 0xc9,
- 0x97, 0x65, 0xcc, 0x7e, 0xfa, 0x72, 0xdc, 0xd6, 0x51, 0xeb, 0xa5, 0x71,
- 0x4b, 0x7b, 0x45, 0x1d, 0xfd, 0x67, 0xea, 0x59, 0xd6, 0x8e, 0x4b, 0xba,
- 0x2d, 0x89, 0x96, 0x51, 0xb7, 0xc7, 0x12, 0x81, 0xf0, 0xd3, 0x88, 0x2b,
- 0x6d, 0x59, 0x27, 0xc6, 0x12, 0x52, 0xaf, 0x8f, 0xe5, 0xfb, 0x95, 0x95,
- 0x97, 0xea, 0x4c, 0x15, 0xfc, 0x56, 0xc6, 0x23, 0xe3, 0xbb, 0x0e, 0x1b,
- 0xf6, 0xea, 0xf1, 0x38, 0xc4, 0xae, 0xa2, 0x58, 0x6f, 0xea, 0x7e, 0xda,
- 0x1f, 0xed, 0x06, 0xa8, 0x49, 0xc6, 0xdc, 0x79, 0x0c, 0x00, 0xee, 0xd8,
- 0xdb, 0xce, 0xb1, 0x5a, 0x78, 0xcd, 0xac, 0xc5, 0x18, 0xbd, 0xb4, 0x3a,
- 0x29, 0xd7, 0xa7, 0xcb, 0x18, 0x51, 0xd6, 0x1f, 0xf5, 0x97, 0xa1, 0x5c,
- 0xe4, 0xfc, 0x1b, 0x35, 0x6f, 0xbf, 0x1f, 0x54, 0xff, 0x17, 0xd6, 0x98,
- 0x37, 0x7f, 0xad, 0x3a, 0x29, 0x9c, 0xaf, 0x1d, 0x5a, 0xd2, 0xc3, 0x78,
- 0x17, 0xb7, 0x2a, 0x0c, 0xbd, 0xfd, 0x82, 0xd2, 0x8d, 0x1b, 0x43, 0x7a,
- 0xec, 0x87, 0x8a, 0x1e, 0x1d, 0x50, 0x0c, 0xfa, 0x61, 0x10, 0xab, 0xb2,
- 0xef, 0xef, 0xeb, 0xfb, 0x50, 0x0f, 0x4b, 0x3f, 0xd2, 0xdf, 0x59, 0xf4,
- 0xdb, 0x63, 0x2a, 0x8e, 0x47, 0xc6, 0xa6, 0x60, 0xb3, 0x3d, 0xa6, 0x15,
- 0xb6, 0x7f, 0x7c, 0xd7, 0x74, 0x61, 0xe3, 0xde, 0x53, 0x0b, 0xc5, 0x40,
- 0x36, 0x1d, 0x8d, 0xa2, 0xb7, 0xd9, 0x85, 0x0d, 0xa3, 0x37, 0xa9, 0x22,
- 0x1b, 0xd4, 0xf9, 0x65, 0xf9, 0x6f, 0x85, 0xbc, 0xc5, 0x83, 0xf5, 0x59,
- 0xce, 0x1d, 0x31, 0x74, 0xfd, 0x51, 0x99, 0xdb, 0x5a, 0x7e, 0xcb, 0xdc,
- 0x7a, 0xf9, 0x2d, 0xf3, 0x3c, 0x8b, 0xdf, 0xd5, 0xf0, 0xcf, 0x12, 0x59,
- 0x9a, 0x91, 0xd8, 0x0f, 0x77, 0x45, 0xa4, 0x0b, 0x77, 0x0d, 0x58, 0x56,
- 0x7f, 0xc0, 0xb2, 0xca, 0x42, 0xe4, 0x59, 0x81, 0xc6, 0xf0, 0x95, 0x4a,
- 0x09, 0xa6, 0xb4, 0x66, 0xf4, 0x1f, 0x2d, 0x89, 0x55, 0x47, 0x66, 0xd1,
- 0xf7, 0x35, 0xfc, 0x6c, 0x49, 0x3b, 0x26, 0xc6, 0xa7, 0x8f, 0x21, 0x6f,
- 0x67, 0xdf, 0x5e, 0x50, 0xb4, 0x33, 0x91, 0x5f, 0x64, 0xd7, 0xfb, 0xd3,
- 0xf4, 0xcb, 0xb8, 0x86, 0x18, 0xfd, 0x83, 0x32, 0xd5, 0xa2, 0xe7, 0x12,
- 0xa7, 0xfe, 0xa0, 0xfa, 0x17, 0x1b, 0x3b, 0x13, 0xef, 0x5a, 0x0c, 0xa7,
- 0xfc, 0xe4, 0x1a, 0xef, 0xcd, 0xbc, 0xd7, 0x6e, 0xca, 0x6c, 0xbb, 0x91,
- 0xb2, 0x17, 0x1b, 0xef, 0xcc, 0xac, 0xb0, 0xc7, 0x9c, 0x66, 0xe1, 0x4d,
- 0x7b, 0x45, 0xa7, 0xa2, 0x03, 0x0b, 0xc7, 0xcd, 0xeb, 0x88, 0x15, 0xaf,
- 0x5b, 0x8e, 0x59, 0xd2, 0x46, 0x97, 0xd2, 0x4a, 0x7b, 0x8a, 0x3b, 0x4b,
- 0x41, 0x4e, 0xad, 0x95, 0x44, 0xa2, 0xca, 0x5a, 0x5b, 0xff, 0xad, 0xca,
- 0xca, 0xd1, 0xe9, 0x6d, 0x77, 0xd1, 0x77, 0x1f, 0x57, 0xf3, 0xf3, 0x7d,
- 0xde, 0x1e, 0x43, 0x5e, 0x7e, 0x3f, 0xda, 0x53, 0xd2, 0x8e, 0xe8, 0x35,
- 0xef, 0x6f, 0xed, 0x12, 0x23, 0x2e, 0xc9, 0x9c, 0xe7, 0x1e, 0x97, 0x31,
- 0x61, 0xc9, 0x7b, 0xf0, 0xe3, 0x7a, 0xe2, 0x47, 0xf4, 0x3f, 0xc4, 0x8f,
- 0xa5, 0x7f, 0xa2, 0xec, 0x59, 0xca, 0x21, 0x3c, 0x45, 0xe2, 0x9e, 0xf0,
- 0x16, 0xe1, 0x2b, 0x41, 0xca, 0x25, 0xfc, 0xa5, 0x68, 0x1b, 0x96, 0xf5,
- 0x4d, 0x73, 0x01, 0x62, 0xb5, 0xfa, 0x20, 0x50, 0x87, 0x41, 0xca, 0xea,
- 0x48, 0x22, 0xce, 0x71, 0x52, 0xd7, 0xea, 0x75, 0x0e, 0xa8, 0x4d, 0x0e,
- 0x74, 0xe3, 0x55, 0xd3, 0xe8, 0xdf, 0x8c, 0xbf, 0x44, 0x8f, 0xd7, 0xc2,
- 0x61, 0x33, 0x48, 0x5c, 0x2a, 0x47, 0x67, 0x13, 0x27, 0x62, 0xad, 0x17,
- 0x43, 0xa9, 0x78, 0x07, 0x61, 0x83, 0x31, 0xec, 0xd9, 0x4f, 0x26, 0x02,
- 0x7a, 0xfb, 0x56, 0xa6, 0x40, 0xab, 0x06, 0xdc, 0xf0, 0x4b, 0x2a, 0xc4,
- 0x98, 0xf1, 0x75, 0xc6, 0xf9, 0x4d, 0xe6, 0x15, 0xd4, 0x6d, 0x1f, 0x6d,
- 0x48, 0xa5, 0xbd, 0x48, 0x3f, 0x41, 0xf2, 0x19, 0xa9, 0xcb, 0xb8, 0xd0,
- 0xa0, 0xe0, 0x86, 0x06, 0xda, 0x27, 0x79, 0xd1, 0xe7, 0x43, 0x4e, 0xfb,
- 0xff, 0x44, 0xb6, 0x31, 0x7a, 0xb3, 0xfa, 0x23, 0x0b, 0x33, 0xed, 0x36,
- 0xb4, 0xa8, 0x4a, 0xb9, 0xff, 0x28, 0x27, 0x30, 0x21, 0x5c, 0xad, 0xd2,
- 0xf8, 0x0d, 0xc6, 0xbd, 0x52, 0xa7, 0x0a, 0x15, 0xc3, 0xf1, 0x59, 0xe5,
- 0xb4, 0xe1, 0xd2, 0x88, 0x8e, 0xbb, 0x46, 0x2b, 0xe1, 0x18, 0xd6, 0x2f,
- 0xae, 0x74, 0x20, 0x56, 0x22, 0xfc, 0x70, 0xb4, 0x16, 0x35, 0xfb, 0xac,
- 0x6e, 0x77, 0xc4, 0xb2, 0x3c, 0x4b, 0x22, 0xb8, 0xf7, 0xa8, 0x06, 0x75,
- 0x9f, 0x0b, 0x15, 0xcc, 0x43, 0xd6, 0x99, 0x7d, 0xb8, 0x8f, 0xfc, 0x6e,
- 0x4e, 0x32, 0x88, 0xd5, 0xc4, 0xa2, 0x8b, 0xa9, 0xb6, 0xd6, 0x17, 0x12,
- 0x0d, 0xdb, 0xe6, 0x38, 0x84, 0xfb, 0xaf, 0xc1, 0xe6, 0xec, 0x1a, 0xdc,
- 0xc9, 0xd8, 0xf9, 0x9c, 0x81, 0xee, 0x39, 0xf4, 0xd7, 0x3b, 0xc9, 0xff,
- 0x36, 0xa6, 0xd6, 0x61, 0x63, 0x76, 0x1b, 0xff, 0xeb, 0xc0, 0xdd, 0x3c,
- 0x36, 0xa5, 0xc4, 0xbf, 0x3f, 0x8d, 0x4d, 0xd9, 0x7a, 0xc4, 0x46, 0x37,
- 0x62, 0x2b, 0x39, 0xc1, 0x5d, 0xa3, 0x5e, 0xea, 0xb6, 0x0d, 0x1b, 0xb2,
- 0x6d, 0xb8, 0x97, 0x63, 0xb9, 0x97, 0xf3, 0xa1, 0x26, 0xb7, 0xd2, 0xc7,
- 0x3c, 0xf0, 0x0e, 0x2f, 0xc5, 0x7d, 0xa3, 0xd7, 0x61, 0x0b, 0xe3, 0xe4,
- 0xed, 0x4b, 0xae, 0x43, 0xf7, 0xe8, 0x7d, 0xe8, 0x4a, 0x19, 0x5d, 0x73,
- 0x98, 0x6a, 0xbd, 0xb5, 0xe4, 0x3e, 0xdc, 0x43, 0x39, 0xb6, 0xed, 0xb5,
- 0x50, 0xb6, 0x68, 0xb1, 0x6a, 0xd4, 0xc4, 0x2d, 0x9f, 0x21, 0xb1, 0xf9,
- 0xc0, 0xad, 0x7d, 0xc6, 0xee, 0x02, 0xb6, 0x38, 0x51, 0x62, 0x28, 0x62,
- 0xa3, 0xf9, 0xeb, 0x89, 0xbf, 0xc1, 0xe6, 0x51, 0x17, 0xee, 0x18, 0xed,
- 0x52, 0x56, 0x8b, 0xad, 0xb8, 0x54, 0xce, 0x67, 0x94, 0xd8, 0xd7, 0xaa,
- 0xb4, 0x8c, 0xda, 0xf3, 0xac, 0x79, 0x23, 0x5d, 0xca, 0xba, 0xec, 0x9d,
- 0x0e, 0x94, 0xcb, 0x5c, 0x5c, 0x83, 0xf1, 0xa6, 0xaf, 0x58, 0xe9, 0xfc,
- 0x7c, 0xa6, 0xe9, 0x3e, 0x6e, 0x5f, 0xe4, 0x57, 0x9f, 0xf4, 0x2d, 0xd0,
- 0xbb, 0x0e, 0xa8, 0xc2, 0x2b, 0xdd, 0xc8, 0xd9, 0xf3, 0x59, 0xc2, 0x7e,
- 0x6a, 0x70, 0xc4, 0x9b, 0xe7, 0x12, 0xf3, 0xd8, 0x97, 0x95, 0x72, 0x71,
- 0xac, 0x94, 0x9b, 0xe3, 0x99, 0x93, 0xf4, 0xe1, 0x7e, 0xea, 0xa7, 0x8b,
- 0x73, 0xd4, 0x45, 0xbd, 0x7c, 0x2e, 0x75, 0x8a, 0x31, 0x62, 0x1b, 0x3e,
- 0x57, 0xe8, 0xa7, 0x2f, 0x5b, 0x8a, 0x72, 0xa3, 0x0f, 0x8f, 0x68, 0x25,
- 0xf4, 0x31, 0xe1, 0x19, 0x07, 0x6e, 0x3d, 0x6c, 0xac, 0xe3, 0x18, 0xbe,
- 0xc4, 0x36, 0x44, 0xae, 0x46, 0xad, 0x06, 0xf9, 0xb2, 0x3d, 0xc4, 0xec,
- 0x72, 0xe3, 0x37, 0xd6, 0x23, 0xde, 0x76, 0xbb, 0x6c, 0x15, 0xcb, 0x3e,
- 0x3f, 0xe0, 0xc7, 0x8d, 0xb4, 0xef, 0xb2, 0x64, 0x94, 0x7a, 0x77, 0x93,
- 0x53, 0xb5, 0x52, 0xe7, 0x9c, 0x63, 0xea, 0xf5, 0x0e, 0xda, 0xb3, 0x33,
- 0xb9, 0x86, 0xf3, 0xa0, 0xa1, 0x32, 0xd9, 0xc7, 0x79, 0xf0, 0xc2, 0x9d,
- 0x6c, 0x47, 0x27, 0xe5, 0x72, 0x25, 0xd7, 0x71, 0x2e, 0xea, 0xe0, 0x49,
- 0x76, 0x70, 0x2e, 0x80, 0xbb, 0xa8, 0xcb, 0xfb, 0x42, 0xbf, 0x56, 0x7a,
- 0x6b, 0x65, 0x18, 0x6d, 0x9c, 0xbf, 0x28, 0x36, 0xa7, 0xea, 0xc3, 0x3b,
- 0x24, 0xee, 0x3b, 0x99, 0x90, 0x19, 0x3f, 0x26, 0x17, 0xa6, 0xf5, 0x1b,
- 0x3d, 0xfc, 0x5d, 0x94, 0xb3, 0x88, 0xe3, 0x22, 0xa7, 0xc4, 0xd7, 0xa2,
- 0x9c, 0x2e, 0x94, 0x19, 0xcf, 0x5a, 0x0f, 0x7b, 0xe1, 0x77, 0xb1, 0x6c,
- 0x39, 0xcb, 0xae, 0xa6, 0x9c, 0xab, 0x29, 0xff, 0xbc, 0xe4, 0xa7, 0xd1,
- 0x4d, 0x39, 0xe7, 0x0c, 0xbb, 0xc9, 0x51, 0x75, 0xdc, 0x4f, 0xdd, 0x1f,
- 0x48, 0x95, 0xa1, 0x9a, 0xf3, 0xfc, 0x39, 0xfe, 0xde, 0x41, 0x3f, 0x7a,
- 0x7e, 0xd0, 0xc2, 0x99, 0x90, 0x86, 0x41, 0xad, 0x0c, 0xbd, 0xc1, 0xad,
- 0xe4, 0xe5, 0x32, 0x57, 0xcc, 0xa7, 0x8c, 0x0a, 0xc6, 0x75, 0xc4, 0x5d,
- 0xcd, 0x3a, 0xb6, 0x07, 0xdd, 0x48, 0x7b, 0x11, 0x75, 0x19, 0x51, 0xda,
- 0xb8, 0x0b, 0x03, 0x9a, 0x02, 0x17, 0xf1, 0xb0, 0x94, 0xfe, 0xb4, 0x93,
- 0x71, 0xd7, 0x15, 0x91, 0xff, 0x68, 0x27, 0xe4, 0x60, 0xd5, 0x11, 0x23,
- 0xfe, 0x82, 0x12, 0x68, 0x73, 0xa9, 0xf7, 0x51, 0x47, 0x15, 0x38, 0x33,
- 0xf8, 0x25, 0x6c, 0x64, 0x5f, 0x7d, 0x29, 0x0f, 0x73, 0x93, 0xbf, 0x53,
- 0x72, 0x36, 0x7e, 0x7a, 0x90, 0x1c, 0x79, 0xdc, 0x9a, 0x67, 0x88, 0xdd,
- 0x44, 0x70, 0xcf, 0xd1, 0x2a, 0x0c, 0x0e, 0x5e, 0x87, 0x6d, 0x2c, 0xb7,
- 0x2b, 0x55, 0x0d, 0x63, 0x68, 0x99, 0x5d, 0x67, 0x84, 0xfe, 0x35, 0x90,
- 0xbc, 0x0f, 0x2b, 0x53, 0xf5, 0xc1, 0xa3, 0x4a, 0x8c, 0x3a, 0xf4, 0xa2,
- 0x3f, 0xb9, 0xd1, 0xd6, 0x69, 0x62, 0x5f, 0x27, 0xb6, 0x1e, 0xbd, 0x02,
- 0x7b, 0xf6, 0x6d, 0xc1, 0x5d, 0x47, 0x99, 0xbf, 0xda, 0xb6, 0xac, 0xa2,
- 0x77, 0xdf, 0x75, 0xca, 0x06, 0xb6, 0xb7, 0x7b, 0x98, 0xf6, 0x4c, 0x9b,
- 0xbe, 0x7f, 0xaf, 0x91, 0x5b, 0xe6, 0xd8, 0xa2, 0xf8, 0x6b, 0xaf, 0x43,
- 0x97, 0x6d, 0x7b, 0x79, 0xbd, 0xed, 0xc8, 0xce, 0x67, 0x9e, 0xf3, 0xb7,
- 0xd6, 0xa3, 0xde, 0x52, 0x7b, 0x7e, 0x55, 0xea, 0xad, 0x25, 0xc1, 0xdc,
- 0xbf, 0x96, 0xb9, 0x57, 0xc1, 0x5e, 0x7a, 0xb3, 0x8b, 0xc9, 0x1b, 0xbd,
- 0xc8, 0x68, 0x41, 0xea, 0xa3, 0x38, 0x0f, 0x0d, 0x05, 0x7b, 0x79, 0x8b,
- 0x65, 0x6c, 0x5b, 0x7e, 0x9f, 0x2f, 0xc8, 0xfc, 0xb6, 0xa3, 0x86, 0xf1,
- 0x75, 0x43, 0x68, 0x9d, 0x72, 0xaf, 0x76, 0x69, 0xce, 0x7c, 0xc5, 0x39,
- 0x93, 0x3c, 0xd1, 0x6e, 0x2b, 0xf1, 0x25, 0xdb, 0x76, 0xaf, 0xcf, 0x36,
- 0xa3, 0x73, 0x74, 0x7a, 0xfb, 0xc5, 0x3a, 0x65, 0x9c, 0x8b, 0xe2, 0x3c,
- 0xeb, 0xfd, 0x82, 0x65, 0x81, 0x45, 0x45, 0x2c, 0xbb, 0xb3, 0xd0, 0xff,
- 0x41, 0x8b, 0x31, 0xc9, 0xe9, 0x32, 0x1c, 0x18, 0x09, 0xfe, 0x57, 0x25,
- 0x5e, 0xeb, 0xa4, 0xcc, 0x0a, 0xb1, 0xe4, 0xef, 0xac, 0x3d, 0xeb, 0x64,
- 0x5e, 0x3e, 0x42, 0x43, 0x86, 0xe2, 0xba, 0xe4, 0xb3, 0x6b, 0xb0, 0x3e,
- 0x25, 0xb2, 0xb6, 0x63, 0x43, 0xca, 0x96, 0xcb, 0x5f, 0x94, 0xab, 0x8f,
- 0x36, 0xa3, 0x25, 0x77, 0xdb, 0x32, 0xb5, 0xd3, 0xae, 0xee, 0xd9, 0xab,
- 0xe2, 0xe9, 0xd0, 0x26, 0xc5, 0x3f, 0x53, 0xe2, 0x70, 0x3d, 0xba, 0xf6,
- 0xca, 0xb7, 0x9f, 0x7c, 0x37, 0xa6, 0x4c, 0xcd, 0x1c, 0x60, 0xb9, 0x65,
- 0x58, 0xbf, 0xb7, 0x16, 0x73, 0x38, 0xd6, 0xdb, 0xcd, 0xff, 0xa2, 0xbc,
- 0x33, 0x43, 0xc6, 0xb3, 0xa2, 0x10, 0xcb, 0xeb, 0x71, 0xdf, 0x5e, 0xf1,
- 0x21, 0xf9, 0xdd, 0x82, 0xde, 0xa5, 0xf5, 0x85, 0x38, 0xff, 0x37, 0x9c,
- 0x97, 0x2e, 0xe5, 0x06, 0xe2, 0x42, 0x8c, 0xb8, 0x40, 0x9b, 0x52, 0xda,
- 0x89, 0x0b, 0xd7, 0x17, 0x70, 0xc1, 0x43, 0x5c, 0x58, 0x93, 0x7d, 0x9b,
- 0xf2, 0x88, 0x2f, 0xbe, 0x57, 0x9e, 0xbb, 0x29, 0xcf, 0xb1, 0xd0, 0x1c,
- 0xc0, 0x96, 0x67, 0x19, 0x79, 0x4c, 0x2d, 0xe7, 0xd0, 0x62, 0x7c, 0x50,
- 0x94, 0x11, 0x5b, 0xcf, 0xcb, 0x28, 0xb3, 0xd8, 0x94, 0x45, 0xb9, 0x7f,
- 0x8f, 0x06, 0x7b, 0x7d, 0xe0, 0xb2, 0x3c, 0xeb, 0xf7, 0xbe, 0xcb, 0x1c,
- 0x41, 0x7e, 0x13, 0x2f, 0x9a, 0xeb, 0x89, 0x73, 0xcb, 0x88, 0x7b, 0x2e,
- 0x8e, 0x4b, 0xb0, 0x4e, 0x64, 0x73, 0xd1, 0x2f, 0xa4, 0x6d, 0xd1, 0xc9,
- 0x52, 0x47, 0x7e, 0x1e, 0x8a, 0xf3, 0xec, 0xa4, 0x1f, 0xbb, 0x51, 0x1d,
- 0xd1, 0xa3, 0x37, 0x39, 0x64, 0xce, 0x88, 0xf2, 0x43, 0xed, 0x85, 0xbe,
- 0xfe, 0xbb, 0xd2, 0x50, 0xd3, 0x4f, 0x39, 0x4f, 0x28, 0xb7, 0x70, 0x5c,
- 0xfe, 0xd2, 0xaa, 0xa8, 0x27, 0x12, 0xe8, 0x48, 0xbc, 0x2f, 0x36, 0xde,
- 0x90, 0xcd, 0xf3, 0x4b, 0x75, 0x28, 0x6e, 0x95, 0xd3, 0xf6, 0x9d, 0x46,
- 0xe0, 0xe2, 0x6a, 0xf6, 0x30, 0xef, 0xa0, 0xf0, 0x19, 0x93, 0x6d, 0x15,
- 0xfb, 0xaa, 0x23, 0x96, 0x84, 0x0a, 0x76, 0xb0, 0x46, 0x61, 0xde, 0xd0,
- 0x16, 0xb5, 0xed, 0x61, 0x17, 0xf5, 0x75, 0x42, 0xf9, 0x98, 0x70, 0x66,
- 0x9b, 0x63, 0xc4, 0x95, 0x55, 0xc4, 0x95, 0xea, 0xa4, 0x12, 0xf5, 0x46,
- 0x1a, 0xb7, 0xd5, 0x20, 0xd0, 0xf6, 0x28, 0xfb, 0xac, 0x21, 0xcf, 0xbc,
- 0x89, 0xb1, 0x36, 0xc9, 0x3e, 0x57, 0xb1, 0xcf, 0xb5, 0xd9, 0x2d, 0x6c,
- 0x57, 0xb0, 0x55, 0xc5, 0x9c, 0x7d, 0x70, 0x7b, 0x69, 0x07, 0x23, 0x0d,
- 0x4e, 0x84, 0x17, 0xff, 0x02, 0x98, 0x81, 0x98, 0xca, 0xfc, 0x7d, 0x5e,
- 0x52, 0x72, 0xa9, 0x03, 0xb7, 0x2e, 0xcb, 0x08, 0x96, 0x6a, 0xf0, 0x0c,
- 0x7b, 0x25, 0x1e, 0xa1, 0x2f, 0x54, 0xa7, 0xec, 0xb1, 0xf1, 0x56, 0x45,
- 0xd9, 0x3e, 0x05, 0x57, 0x85, 0xbe, 0xae, 0xa4, 0x67, 0xe6, 0x31, 0x5f,
- 0xa5, 0x3e, 0x7a, 0x26, 0x04, 0x1b, 0xd3, 0xc4, 0xc6, 0x63, 0x4a, 0x7e,
- 0x3d, 0x86, 0x7e, 0x9f, 0x42, 0xbc, 0x2a, 0x22, 0x6b, 0x20, 0x81, 0xce,
- 0x0f, 0x29, 0xf7, 0x11, 0x0b, 0x5d, 0x8c, 0x43, 0x1e, 0x62, 0xa3, 0xc4,
- 0xe9, 0xf4, 0xad, 0x89, 0x81, 0x3a, 0xf4, 0xd3, 0xb7, 0x37, 0x1e, 0x3d,
- 0x75, 0x8b, 0x07, 0xb5, 0xfc, 0xf6, 0xf2, 0x98, 0xc5, 0xc3, 0x4d, 0x5f,
- 0x76, 0xc3, 0x31, 0x20, 0x7c, 0xaf, 0x89, 0xb1, 0xca, 0x83, 0xf2, 0x01,
- 0x13, 0x5b, 0x28, 0x4f, 0xe9, 0x50, 0x33, 0xe3, 0x09, 0xfd, 0x3c, 0x55,
- 0x83, 0xeb, 0x07, 0x97, 0x60, 0x93, 0x8d, 0x5f, 0xb5, 0x38, 0x3b, 0xb8,
- 0xd4, 0xc6, 0x8d, 0x87, 0x52, 0x33, 0xf0, 0xce, 0xde, 0x6b, 0x6c, 0x8c,
- 0x1b, 0x64, 0x6c, 0xf6, 0xed, 0x0b, 0xa3, 0x8b, 0x6d, 0x7a, 0xf7, 0x5d,
- 0x8b, 0xfb, 0x8e, 0xfa, 0xa8, 0x23, 0x83, 0x71, 0x40, 0x7d, 0xd7, 0xff,
- 0x49, 0xb1, 0xf3, 0xe9, 0xd8, 0x2f, 0x73, 0x2d, 0x75, 0x32, 0x34, 0x56,
- 0xf9, 0xed, 0xb4, 0xb9, 0x70, 0x5e, 0x47, 0x79, 0x9d, 0x5c, 0x4d, 0x9d,
- 0xdc, 0x94, 0xa5, 0x39, 0x0c, 0x3b, 0x39, 0xd7, 0xe4, 0x10, 0x35, 0xb5,
- 0xf4, 0xcb, 0x12, 0x1e, 0xb4, 0xff, 0xd1, 0xbf, 0x60, 0x6c, 0xcf, 0x71,
- 0x3e, 0xf9, 0xdb, 0x94, 0xf9, 0x94, 0xf8, 0xe9, 0x20, 0xe6, 0x2a, 0xd4,
- 0xef, 0xff, 0x02, 0x66, 0xe7, 0x73, 0x9b, 0xa2, 0xae, 0x54, 0x8e, 0xbf,
- 0x25, 0x91, 0xb3, 0x39, 0x3d, 0x33, 0x22, 0x5d, 0xe5, 0x7f, 0x1b, 0x8f,
- 0x92, 0x73, 0x27, 0xc5, 0x67, 0xbd, 0xb4, 0xe7, 0x26, 0xea, 0x4b, 0x63,
- 0xec, 0x30, 0x89, 0x73, 0xb3, 0xe0, 0xe2, 0x38, 0x36, 0x51, 0x3f, 0x1e,
- 0x8e, 0x63, 0x2b, 0xcb, 0xdd, 0xc5, 0xff, 0xee, 0x3a, 0x5a, 0xcb, 0xc3,
- 0xcb, 0x63, 0x16, 0x8f, 0x9f, 0x12, 0xb3, 0x9a, 0x69, 0xc7, 0x0e, 0x94,
- 0x0c, 0xab, 0x78, 0xca, 0x54, 0x70, 0xa1, 0x89, 0xfd, 0x35, 0x5c, 0xc6,
- 0x3a, 0x89, 0x65, 0xde, 0xe4, 0x97, 0x88, 0x73, 0x7e, 0xac, 0x23, 0x27,
- 0xe8, 0xdc, 0xab, 0xc1, 0x15, 0xca, 0x30, 0x67, 0x12, 0x19, 0x4e, 0x14,
- 0x38, 0xe6, 0x3c, 0xe6, 0x3a, 0x8d, 0x61, 0xda, 0x90, 0xb6, 0xd9, 0xb6,
- 0xa1, 0x38, 0xe3, 0x73, 0x90, 0xb9, 0x7e, 0xde, 0x76, 0x5b, 0xde, 0x63,
- 0x47, 0xf4, 0x31, 0x8e, 0x67, 0x4e, 0x44, 0xf7, 0xdf, 0x42, 0x5f, 0x10,
- 0xce, 0x57, 0x9a, 0x04, 0x0e, 0x0c, 0xb6, 0xa3, 0x9a, 0x36, 0xe3, 0x5d,
- 0x7c, 0x14, 0xa9, 0xda, 0x7e, 0xdb, 0x56, 0xf3, 0x6d, 0x97, 0x45, 0x2b,
- 0x23, 0x8d, 0x31, 0x69, 0x7b, 0xbc, 0xd0, 0xf6, 0x0a, 0xb6, 0x9d, 0x60,
- 0xdb, 0x2b, 0xff, 0x5d, 0xdb, 0xd3, 0xe3, 0x5d, 0x4f, 0x21, 0x2e, 0x4b,
- 0xde, 0x5c, 0xc4, 0xed, 0x22, 0xc7, 0xf8, 0x8d, 0xf7, 0x32, 0x4e, 0xee,
- 0x90, 0xb9, 0xf3, 0xe5, 0x7d, 0xf6, 0xbd, 0xd8, 0x7c, 0xb9, 0xad, 0x3d,
- 0xc5, 0x18, 0x6f, 0xd6, 0x4c, 0x6b, 0x6b, 0x0e, 0xff, 0xff, 0x70, 0x4a,
- 0xb8, 0x44, 0x3b, 0x2c, 0xca, 0xfa, 0xac, 0xa1, 0x77, 0x2d, 0x73, 0x18,
- 0xdb, 0x2e, 0x32, 0xd7, 0xb9, 0xf1, 0x52, 0x5f, 0xb2, 0x36, 0xd2, 0x8e,
- 0x85, 0x03, 0x7a, 0xe7, 0x2e, 0xf2, 0xd1, 0xc3, 0x21, 0x3d, 0xfa, 0x2d,
- 0xe8, 0xf1, 0x52, 0xe5, 0x25, 0x94, 0x4c, 0x9c, 0xc5, 0x60, 0xf6, 0x47,
- 0x92, 0x6f, 0xb2, 0x4d, 0xb7, 0xe2, 0x99, 0xe8, 0x43, 0x8c, 0xf5, 0xdc,
- 0xac, 0xe7, 0x1e, 0x80, 0xbb, 0x92, 0xf5, 0xc6, 0x07, 0xe2, 0x96, 0x8b,
- 0x5c, 0x50, 0x8d, 0xe8, 0x1d, 0x95, 0x8a, 0x11, 0xdb, 0xc4, 0xb6, 0xd7,
- 0x30, 0x96, 0x95, 0x27, 0xbb, 0xc9, 0x03, 0x74, 0xdf, 0x97, 0x55, 0xbd,
- 0x6b, 0x3d, 0x5e, 0xc2, 0xbf, 0x92, 0x3c, 0xce, 0x4b, 0x9e, 0x45, 0x8a,
- 0xed, 0x59, 0xe3, 0x1a, 0xf9, 0xcc, 0xbb, 0x56, 0x78, 0x41, 0x85, 0x53,
- 0xda, 0xbd, 0x38, 0xbe, 0xe0, 0xdd, 0xc4, 0x65, 0x3c, 0xd7, 0x5c, 0x46,
- 0xe3, 0xfb, 0xf0, 0xa9, 0xa9, 0x75, 0x45, 0x62, 0xfd, 0x56, 0x57, 0x64,
- 0xdb, 0xfd, 0xc7, 0x9b, 0xf3, 0x76, 0xeb, 0xcf, 0xb8, 0x71, 0xd6, 0x2b,
- 0xbe, 0xc4, 0xfc, 0x67, 0x7f, 0x13, 0x76, 0xef, 0x67, 0x5e, 0xa9, 0x36,
- 0x86, 0xcb, 0x95, 0x1a, 0xe6, 0x44, 0xc3, 0x36, 0x1f, 0x76, 0x1a, 0xbb,
- 0xec, 0x9c, 0x59, 0xe2, 0x83, 0xd4, 0x99, 0x9f, 0x91, 0xf8, 0x27, 0xeb,
- 0x39, 0x07, 0x6e, 0xdd, 0x90, 0xa0, 0xdf, 0x6a, 0xbd, 0x2c, 0xb3, 0xae,
- 0xb0, 0x4e, 0x2f, 0x6b, 0x18, 0xbd, 0xd3, 0x38, 0xc9, 0xba, 0x69, 0xb1,
- 0xaa, 0xd1, 0x5f, 0x73, 0x29, 0x8e, 0x74, 0x14, 0xca, 0x33, 0xd9, 0xb3,
- 0x65, 0x73, 0x4f, 0xc3, 0xb3, 0x1d, 0xbc, 0x96, 0xf7, 0x85, 0xcb, 0xf1,
- 0x6e, 0x67, 0x61, 0x6e, 0x0e, 0xb9, 0xf2, 0xb8, 0xff, 0x69, 0x77, 0x71,
- 0xbd, 0x28, 0x5f, 0xe6, 0xda, 0x12, 0x94, 0xef, 0xb9, 0x14, 0x5b, 0xe2,
- 0xc4, 0xf2, 0x6d, 0x7b, 0xf3, 0xeb, 0x93, 0x95, 0x4b, 0x05, 0xb7, 0xeb,
- 0x71, 0xb7, 0xed, 0xf7, 0x5f, 0x75, 0xe5, 0xed, 0xc0, 0x59, 0x18, 0x97,
- 0x49, 0x1b, 0xbc, 0x52, 0xd6, 0xfc, 0x0b, 0xf8, 0x39, 0x9b, 0xff, 0xf7,
- 0x42, 0xe6, 0xc2, 0x45, 0xff, 0x7c, 0xdc, 0x74, 0x60, 0x6a, 0x46, 0x9e,
- 0xaf, 0xab, 0xfb, 0x9a, 0xd0, 0x33, 0x46, 0xbc, 0xa1, 0x0f, 0xb5, 0x85,
- 0xd6, 0x5a, 0xa8, 0x91, 0x75, 0x83, 0x5a, 0x54, 0xec, 0x13, 0xde, 0x4c,
- 0x9e, 0x31, 0x76, 0xca, 0x1e, 0x4b, 0x6f, 0x26, 0xbf, 0x2e, 0xb2, 0x33,
- 0xd5, 0xf7, 0xee, 0x1d, 0x9a, 0xe0, 0x85, 0xd8, 0x46, 0xdd, 0xad, 0x0b,
- 0x03, 0x39, 0xbf, 0x03, 0xba, 0xb9, 0x4b, 0x56, 0x92, 0x12, 0xb7, 0x61,
- 0x7b, 0xad, 0x82, 0x2e, 0xa3, 0x1a, 0x8e, 0xc5, 0xbf, 0xb5, 0xee, 0x58,
- 0x27, 0xff, 0xbd, 0x5b, 0xc0, 0x97, 0x0f, 0xb2, 0x6f, 0x19, 0xb7, 0x70,
- 0x3a, 0x37, 0x2a, 0xe8, 0x53, 0x37, 0x38, 0x84, 0x73, 0x2a, 0x8c, 0x9d,
- 0xf6, 0x5c, 0xa0, 0x37, 0xad, 0x60, 0x77, 0x5a, 0x30, 0xd3, 0x49, 0x1c,
- 0xf4, 0x61, 0x67, 0x5a, 0x70, 0xd0, 0x45, 0x1c, 0x9c, 0x83, 0xed, 0x69,
- 0xc1, 0xc1, 0x12, 0xbc, 0x3c, 0x78, 0x05, 0x1e, 0xe2, 0xef, 0x07, 0x53,
- 0xa5, 0x08, 0xef, 0xfd, 0x0b, 0x1c, 0x48, 0x0b, 0x7f, 0x72, 0x23, 0x35,
- 0x5c, 0x87, 0x54, 0x3a, 0xcf, 0x25, 0xaa, 0x86, 0xff, 0x12, 0x49, 0xfe,
- 0x1e, 0x20, 0xef, 0xcb, 0x0c, 0xcd, 0x45, 0x82, 0xbf, 0x65, 0xbd, 0xcd,
- 0x43, 0xf9, 0x13, 0x81, 0x0a, 0x6c, 0x18, 0x92, 0x1c, 0xda, 0x77, 0xeb,
- 0x5d, 0x81, 0x79, 0xec, 0xb3, 0x0e, 0xbb, 0xc9, 0xd9, 0xda, 0x86, 0xfc,
- 0xe8, 0xe7, 0xef, 0x9d, 0xa9, 0x4a, 0xbc, 0x36, 0xa8, 0xdb, 0xfd, 0xf5,
- 0xa4, 0x56, 0xac, 0x70, 0x19, 0x55, 0x58, 0x31, 0x38, 0x1f, 0x3b, 0xd2,
- 0x82, 0xbd, 0xd5, 0xc4, 0xde, 0x7a, 0x3c, 0x98, 0x16, 0x7e, 0xa9, 0xc1,
- 0xbb, 0xd7, 0xc0, 0x48, 0x5a, 0xd6, 0x84, 0x6b, 0x70, 0x61, 0x28, 0x80,
- 0x41, 0xbb, 0x7f, 0x13, 0xc9, 0x54, 0x98, 0xf2, 0x79, 0x51, 0xb9, 0x2f,
- 0xe7, 0xab, 0x82, 0x82, 0xc9, 0x40, 0x10, 0x03, 0x63, 0xb3, 0x50, 0xbe,
- 0x4f, 0x37, 0xb7, 0x42, 0xbf, 0x78, 0x17, 0xae, 0xc4, 0xee, 0x31, 0x1f,
- 0x4a, 0xf7, 0x55, 0xc3, 0x1d, 0x6a, 0xc2, 0xce, 0xb1, 0x0f, 0x61, 0xfb,
- 0x58, 0x1d, 0xb1, 0x13, 0x78, 0x3a, 0x63, 0xa2, 0x9f, 0x18, 0x3c, 0x87,
- 0x31, 0xe6, 0x95, 0xac, 0xcc, 0xa3, 0xcc, 0x8f, 0x02, 0x4f, 0xa0, 0x9a,
- 0x31, 0x4a, 0x7e, 0xcb, 0xb5, 0xb0, 0x8d, 0xed, 0xf9, 0x75, 0x2a, 0x3d,
- 0xbe, 0x13, 0xb6, 0xbe, 0x91, 0xcb, 0x88, 0xee, 0x65, 0x4d, 0x68, 0xba,
- 0x3d, 0xed, 0xb4, 0xd7, 0xe8, 0x2f, 0xdb, 0xe5, 0x5f, 0x15, 0xec, 0xd2,
- 0x5e, 0x53, 0xc3, 0x93, 0x97, 0xf2, 0x5c, 0xb4, 0x96, 0x20, 0x60, 0x3a,
- 0x15, 0xf8, 0x99, 0xef, 0xfa, 0x9f, 0x7a, 0xdf, 0xda, 0xda, 0xe5, 0xf5,
- 0x9f, 0xe9, 0x6b, 0xb0, 0x72, 0x6f, 0x49, 0x65, 0x3c, 0x2f, 0x41, 0x5c,
- 0x93, 0x35, 0xaa, 0x46, 0x8d, 0x5a, 0x79, 0x5f, 0xde, 0x5d, 0x15, 0x2b,
- 0x8b, 0x34, 0xc3, 0x3f, 0x5e, 0xe7, 0x7f, 0x2d, 0x21, 0x3a, 0xfd, 0xbd,
- 0xe5, 0x36, 0x0c, 0xdf, 0x31, 0xd4, 0xf9, 0x7f, 0x92, 0x79, 0xbb, 0x04,
- 0x55, 0x1e, 0x5c, 0x9f, 0xf8, 0xe0, 0x7a, 0x6a, 0x04, 0xca, 0xca, 0x66,
- 0x1f, 0x79, 0x3f, 0x9c, 0xab, 0x17, 0x60, 0xda, 0x87, 0x7c, 0x24, 0x02,
- 0xf5, 0x74, 0x73, 0x98, 0xb9, 0x7e, 0xfe, 0x7e, 0xce, 0xf2, 0xac, 0xee,
- 0x8b, 0x2a, 0xf9, 0x7b, 0x36, 0x9d, 0xa1, 0x3f, 0xd0, 0xae, 0xbb, 0x85,
- 0xb3, 0xb0, 0x2f, 0x60, 0x6b, 0xc2, 0xb2, 0x9e, 0xa4, 0x0e, 0xe4, 0x5e,
- 0xe0, 0x9b, 0x99, 0xdf, 0x59, 0x93, 0x5e, 0x27, 0x5e, 0x37, 0xa6, 0xb7,
- 0x47, 0xae, 0x17, 0x31, 0x19, 0xfb, 0xec, 0x13, 0x75, 0xdc, 0x68, 0xdc,
- 0x76, 0x98, 0x79, 0xf2, 0xc2, 0x80, 0xee, 0x4f, 0xe2, 0xff, 0x5a, 0xc2,
- 0x0b, 0xd3, 0x4a, 0x71, 0xdd, 0xee, 0xfd, 0x6b, 0x27, 0x55, 0x31, 0x17,
- 0xc7, 0x77, 0x28, 0xa1, 0xf7, 0xc7, 0x99, 0xb7, 0x45, 0xbd, 0x88, 0x39,
- 0x23, 0x75, 0xfe, 0x9d, 0x09, 0x7b, 0x9c, 0xe6, 0x79, 0xce, 0xdd, 0xe9,
- 0xe6, 0x3a, 0x7f, 0x6f, 0x46, 0x6c, 0x50, 0xe1, 0x58, 0x9a, 0xf1, 0x70,
- 0x46, 0xc5, 0x9d, 0x0f, 0x78, 0xb1, 0x69, 0xc0, 0x83, 0x6d, 0x03, 0x5f,
- 0x82, 0x71, 0x95, 0x13, 0x77, 0x30, 0xf7, 0xdb, 0x3c, 0x50, 0x4a, 0x3d,
- 0x6a, 0xd8, 0x32, 0xe0, 0x44, 0xd3, 0x55, 0x55, 0x88, 0xcf, 0x2c, 0xc5,
- 0xf3, 0xf4, 0xdd, 0xab, 0x42, 0x15, 0x48, 0xdb, 0x9c, 0x43, 0xb0, 0x41,
- 0x78, 0x9b, 0xe8, 0x8d, 0x71, 0xd0, 0x10, 0x0c, 0xf9, 0xa0, 0xf5, 0x99,
- 0xdf, 0x58, 0xb9, 0x99, 0x7b, 0x6c, 0x3e, 0xe9, 0x88, 0x88, 0x6e, 0xa4,
- 0xae, 0xac, 0x35, 0x79, 0x19, 0x23, 0xdf, 0xa3, 0x47, 0x65, 0x5e, 0x24,
- 0x30, 0xb9, 0x4c, 0x71, 0x20, 0x1c, 0xa8, 0x8a, 0x55, 0x47, 0xc2, 0x58,
- 0x99, 0xed, 0xf1, 0xf9, 0xec, 0x7b, 0x59, 0x11, 0x9c, 0x5f, 0x62, 0xe2,
- 0x96, 0x2c, 0x9c, 0x2b, 0xa9, 0xfb, 0x56, 0xea, 0x75, 0x87, 0xf9, 0x07,
- 0x2b, 0x9f, 0xd7, 0xb8, 0x89, 0x97, 0x96, 0xb5, 0x99, 0xfa, 0x65, 0x4e,
- 0x81, 0x9f, 0x16, 0xf4, 0x2b, 0x3a, 0xad, 0x18, 0xff, 0x9d, 0x75, 0x9a,
- 0xfa, 0x75, 0xb3, 0x3d, 0x37, 0xdb, 0x2b, 0x1b, 0x7f, 0xaf, 0x9e, 0x4b,
- 0x29, 0xcf, 0x4a, 0x5b, 0x86, 0xd9, 0x72, 0x2f, 0xc0, 0x1f, 0x55, 0x8a,
- 0x3c, 0xf4, 0x4f, 0x8d, 0xe9, 0x25, 0x7b, 0xbd, 0xed, 0xeb, 0x59, 0xcb,
- 0x1a, 0x36, 0x45, 0xff, 0x7e, 0xea, 0x5f, 0xd6, 0x5d, 0x64, 0x0e, 0x9a,
- 0x10, 0xad, 0xd5, 0xfb, 0x01, 0x49, 0x7c, 0x15, 0xcc, 0x60, 0xae, 0xf5,
- 0x8d, 0x76, 0x0f, 0x5e, 0x4b, 0x54, 0xda, 0xe3, 0xbe, 0xaa, 0xc1, 0xb2,
- 0xbe, 0x16, 0xf2, 0xe3, 0x4d, 0xa3, 0x31, 0xbc, 0x48, 0xd5, 0x19, 0x13,
- 0x64, 0xed, 0x83, 0xba, 0x48, 0xcd, 0xe5, 0x7c, 0x89, 0xcf, 0x63, 0x1b,
- 0xed, 0xc9, 0xef, 0x88, 0x00, 0xaf, 0x26, 0x8c, 0xe0, 0x0e, 0xf6, 0x3f,
- 0xea, 0x8d, 0x60, 0x7b, 0x4a, 0x6d, 0x75, 0x92, 0x7c, 0x96, 0x31, 0xd7,
- 0xdb, 0x85, 0x7f, 0xb5, 0xd2, 0x5e, 0x0b, 0x25, 0x21, 0x89, 0x25, 0xf3,
- 0x70, 0x46, 0x73, 0xe0, 0x99, 0xe0, 0x2c, 0x44, 0x6b, 0x1c, 0xe4, 0x33,
- 0xaf, 0x5b, 0xff, 0xec, 0x95, 0x7e, 0x64, 0x2c, 0x7f, 0xe0, 0x38, 0x14,
- 0x1b, 0xef, 0x76, 0xa6, 0x22, 0xd4, 0xf7, 0xfb, 0xfb, 0xff, 0xbf, 0xd6,
- 0x94, 0x57, 0xfa, 0xd7, 0x35, 0x3f, 0xf9, 0xf9, 0xe3, 0x1f, 0xb8, 0xce,
- 0x12, 0xe4, 0x78, 0xbf, 0x67, 0x7d, 0xc7, 0x6e, 0xf3, 0x23, 0xa5, 0x79,
- 0x5e, 0x2f, 0xed, 0x3d, 0xcd, 0xf1, 0x49, 0x9b, 0xc5, 0x7e, 0x44, 0x6f,
- 0x93, 0xa5, 0x82, 0xd7, 0x3b, 0x53, 0xa2, 0x3f, 0xc9, 0x97, 0x4e, 0x5b,
- 0x98, 0x25, 0xe7, 0x0f, 0xdb, 0x65, 0xe3, 0xd4, 0x57, 0x0f, 0x6d, 0x88,
- 0xb1, 0x81, 0xf1, 0x42, 0xee, 0xb2, 0x6a, 0xc4, 0x5c, 0x0b, 0xdb, 0x19,
- 0xb2, 0xd2, 0xde, 0x6a, 0xec, 0x34, 0x69, 0x77, 0x86, 0x3a, 0xdf, 0x09,
- 0x0b, 0xa7, 0x4d, 0x39, 0x77, 0x61, 0xca, 0xeb, 0xc0, 0x2e, 0xd3, 0x89,
- 0x4e, 0x43, 0xd5, 0xe5, 0xba, 0x23, 0x24, 0xe7, 0x2e, 0xf8, 0x67, 0x2a,
- 0xd8, 0x13, 0x56, 0xb1, 0xc5, 0xe8, 0xf1, 0xcb, 0xf5, 0xe5, 0x21, 0x39,
- 0x57, 0xb0, 0x91, 0x3a, 0x89, 0x33, 0x57, 0xde, 0xca, 0x76, 0x7b, 0x43,
- 0xf9, 0x75, 0xf1, 0x18, 0x2c, 0x6b, 0x8f, 0xd9, 0xf2, 0xe1, 0x0a, 0x96,
- 0x3b, 0x67, 0x4a, 0xec, 0x38, 0x70, 0xcb, 0xc2, 0x40, 0x3c, 0x5a, 0x02,
- 0x3d, 0x56, 0x46, 0x3f, 0xdd, 0x39, 0x30, 0x8f, 0xf5, 0x04, 0xfb, 0x9d,
- 0xbe, 0xdd, 0x90, 0xf5, 0xae, 0x80, 0xff, 0x27, 0xe4, 0xde, 0x69, 0xef,
- 0x02, 0x6a, 0xd6, 0xf0, 0xbf, 0xc2, 0x79, 0xab, 0x36, 0x9c, 0xdb, 0x5e,
- 0x80, 0xde, 0x59, 0xa6, 0x2c, 0x08, 0x56, 0xc1, 0x85, 0x38, 0xf9, 0xf9,
- 0xd8, 0x38, 0xf3, 0xeb, 0x94, 0xa1, 0x1d, 0xb1, 0xd7, 0xcc, 0x3d, 0xd4,
- 0x85, 0x87, 0xf1, 0x22, 0xa0, 0x4d, 0x2a, 0xc5, 0xf3, 0x79, 0x82, 0x0d,
- 0x31, 0x47, 0x44, 0xf0, 0x2d, 0x6e, 0x3d, 0xd1, 0x4c, 0xd5, 0x19, 0x6e,
- 0x7f, 0x2c, 0xe3, 0xe1, 0xa1, 0xf1, 0xf0, 0xfa, 0x37, 0x65, 0x7c, 0xfe,
- 0x8d, 0x19, 0xf8, 0xd7, 0x67, 0x8a, 0x76, 0x59, 0xf4, 0x6d, 0xc1, 0x36,
- 0xcb, 0x92, 0x7b, 0xc9, 0x8f, 0x67, 0xa5, 0xad, 0x7c, 0x1c, 0x2b, 0xa1,
- 0xec, 0x4f, 0xd2, 0xd6, 0x5d, 0x8c, 0x55, 0xbb, 0x8c, 0x38, 0xa1, 0xd2,
- 0xb2, 0x0c, 0xf2, 0x99, 0x12, 0xc5, 0x8f, 0x9d, 0x4d, 0xbf, 0xe5, 0x7c,
- 0x02, 0x9b, 0x32, 0x01, 0x77, 0x7e, 0x3e, 0xc4, 0xcf, 0x04, 0x03, 0xfc,
- 0x8c, 0xbf, 0x3e, 0x7f, 0x0f, 0xfb, 0xd9, 0x9e, 0x99, 0xee, 0x03, 0x0a,
- 0x56, 0xb3, 0xad, 0x96, 0x10, 0x9c, 0x2b, 0x9a, 0xfe, 0xcd, 0xca, 0x79,
- 0xa7, 0xdf, 0x37, 0x75, 0x33, 0xe6, 0xc2, 0xb9, 0xbe, 0x49, 0xce, 0x15,
- 0xb4, 0x84, 0xe5, 0x5c, 0xc1, 0x7a, 0x43, 0xce, 0x89, 0xd9, 0x59, 0x39,
- 0xb7, 0xac, 0xcb, 0xe7, 0xef, 0xc7, 0x22, 0x13, 0x77, 0xa5, 0x64, 0xed,
- 0x4d, 0xb0, 0xc8, 0xed, 0xff, 0x4e, 0xa6, 0x09, 0x5b, 0x52, 0x72, 0x7f,
- 0x8c, 0xb9, 0x86, 0xe1, 0xf1, 0x3f, 0x93, 0xb9, 0x16, 0x77, 0xee, 0x0f,
- 0xa3, 0x73, 0x3f, 0x9a, 0xca, 0x38, 0x86, 0xd2, 0x50, 0xc0, 0x7f, 0x14,
- 0x9a, 0xff, 0x0c, 0x75, 0x72, 0x8a, 0x72, 0x9e, 0x7e, 0x8f, 0x9c, 0xa2,
- 0x43, 0xf8, 0xef, 0x4e, 0xb8, 0x91, 0x09, 0xbd, 0x63, 0xc5, 0xed, 0x5c,
- 0xc8, 0xeb, 0xbf, 0x27, 0xe1, 0x47, 0xce, 0xce, 0xc9, 0xde, 0x28, 0x15,
- 0xec, 0xee, 0x4b, 0xc5, 0xa3, 0x2a, 0x8a, 0xf3, 0xab, 0x87, 0x65, 0x6e,
- 0x5f, 0x4d, 0xc8, 0x7f, 0xd1, 0x2f, 0xa9, 0x8c, 0x4b, 0x2a, 0x73, 0xf9,
- 0x41, 0x59, 0xdf, 0x57, 0x4b, 0x45, 0x3f, 0x72, 0x8f, 0x22, 0x2e, 0x39,
- 0x63, 0x13, 0xaf, 0x6b, 0x8b, 0x10, 0xab, 0xa1, 0x9e, 0xca, 0x0d, 0xaf,
- 0xbf, 0x71, 0xc2, 0xe7, 0x37, 0x27, 0xe0, 0xbf, 0x72, 0x62, 0xba, 0x08,
- 0xe4, 0x0a, 0xea, 0x07, 0x61, 0x81, 0xd7, 0xbf, 0x39, 0x31, 0x8f, 0x3c,
- 0x33, 0x6e, 0x2d, 0x6f, 0x3e, 0x6f, 0xcd, 0x8b, 0x18, 0xb9, 0xd3, 0x94,
- 0xe1, 0x9d, 0x6b, 0xf4, 0xf8, 0x1c, 0xc7, 0xa9, 0xfb, 0xb5, 0x69, 0x7d,
- 0x5c, 0x08, 0xfd, 0xff, 0xed, 0xa3, 0x18, 0xe7, 0x68, 0x0f, 0xcd, 0x32,
- 0x06, 0x89, 0x77, 0xcc, 0x85, 0x6a, 0x65, 0x2c, 0x81, 0x02, 0x6f, 0x2b,
- 0x8e, 0x4b, 0xe1, 0x5c, 0xbb, 0xa9, 0x8b, 0x62, 0x0c, 0xb3, 0xac, 0x5e,
- 0xc3, 0x57, 0x58, 0x03, 0xe7, 0x9c, 0x65, 0x4f, 0x7d, 0xd8, 0xc9, 0x9c,
- 0xfd, 0x9c, 0xd9, 0xf2, 0x57, 0x4e, 0x44, 0x7d, 0xa5, 0x8c, 0xad, 0xb2,
- 0xf6, 0x74, 0xa6, 0x69, 0xca, 0x9a, 0x64, 0x1e, 0xd4, 0x92, 0x95, 0xfb,
- 0x4b, 0x0e, 0xda, 0xb7, 0x85, 0x87, 0x4d, 0xf9, 0x5f, 0x70, 0x26, 0x1e,
- 0x73, 0xd0, 0x56, 0xdc, 0x86, 0xde, 0xf1, 0x65, 0xa5, 0x8a, 0xae, 0xec,
- 0x0c, 0x4e, 0x42, 0x0f, 0x6f, 0x51, 0xe8, 0x87, 0x35, 0x0b, 0x4c, 0x99,
- 0x82, 0x37, 0x12, 0x01, 0x33, 0x50, 0x88, 0x4b, 0xe7, 0x38, 0x77, 0x6f,
- 0x25, 0x8c, 0xce, 0x27, 0x0b, 0xe7, 0x3f, 0xcb, 0x4c, 0x5f, 0x1f, 0x17,
- 0x7b, 0x74, 0xbb, 0xb7, 0x27, 0x70, 0xc1, 0xd1, 0x8c, 0x0b, 0x87, 0xcc,
- 0x12, 0x2c, 0x6f, 0x17, 0x3b, 0x75, 0xbb, 0x77, 0x26, 0x30, 0xe5, 0xe4,
- 0xb5, 0x73, 0xe6, 0x5c, 0x62, 0x9a, 0xbd, 0x7e, 0x29, 0x31, 0x22, 0xa6,
- 0x31, 0xbe, 0x96, 0x47, 0xbc, 0xee, 0xf2, 0x09, 0x68, 0x65, 0xe4, 0x40,
- 0xee, 0x08, 0x5a, 0x1d, 0x49, 0xdd, 0xdf, 0xe6, 0x68, 0xc2, 0xaa, 0xac,
- 0x9f, 0x3c, 0xfa, 0x05, 0xf2, 0x4e, 0xfb, 0x3e, 0x1f, 0x6d, 0xd2, 0xc9,
- 0x0a, 0x43, 0xb3, 0xd4, 0x88, 0xe4, 0x76, 0x55, 0xb8, 0x4b, 0xdb, 0xfa,
- 0x11, 0x35, 0x32, 0x88, 0x9b, 0x9a, 0xdd, 0xad, 0xd5, 0x13, 0x45, 0x9d,
- 0x20, 0xe6, 0x89, 0x40, 0xab, 0x32, 0xa0, 0x56, 0x46, 0x44, 0x37, 0xfe,
- 0xd6, 0xe4, 0xb8, 0xc8, 0xaa, 0xb9, 0x07, 0xc6, 0x7f, 0xe3, 0x46, 0x79,
- 0x94, 0x58, 0xf5, 0x43, 0xdf, 0x7f, 0xae, 0xde, 0x33, 0x6e, 0xc1, 0x7b,
- 0x97, 0x21, 0xdf, 0xb6, 0x6d, 0x31, 0x1f, 0x19, 0xfb, 0x8c, 0x3b, 0x60,
- 0x59, 0x8c, 0x93, 0x3e, 0x28, 0x73, 0x39, 0x1e, 0xfa, 0x1a, 0xe3, 0xd2,
- 0xc6, 0xcc, 0x1f, 0xac, 0x8f, 0x3a, 0x6d, 0x0e, 0x40, 0xde, 0xe4, 0xbf,
- 0xed, 0x75, 0xe3, 0xf7, 0x96, 0xf0, 0x11, 0x27, 0x7d, 0xba, 0x84, 0x78,
- 0xbe, 0xdb, 0x74, 0xb6, 0xad, 0x50, 0x14, 0xf4, 0x19, 0x0b, 0xb4, 0x32,
- 0xc6, 0xa9, 0x5e, 0xfa, 0x75, 0xcc, 0x6b, 0x04, 0x0f, 0x81, 0xe5, 0x32,
- 0x9b, 0x37, 0xbb, 0x22, 0xf7, 0x7c, 0x76, 0xac, 0x59, 0xb0, 0x60, 0xea,
- 0xb6, 0x27, 0x8d, 0x0e, 0xf2, 0xaf, 0xaf, 0x90, 0xa7, 0xe5, 0xfb, 0xc9,
- 0x61, 0xde, 0x07, 0xf4, 0xb3, 0x79, 0x73, 0x69, 0x44, 0x78, 0x58, 0xfa,
- 0xb6, 0xc3, 0x46, 0x1b, 0x73, 0xb0, 0x7b, 0x3e, 0x7b, 0xae, 0xf9, 0x00,
- 0xbf, 0xf3, 0x75, 0xd2, 0xa8, 0xfe, 0xc0, 0x3a, 0x15, 0x11, 0xe9, 0xc3,
- 0xcf, 0x3e, 0xee, 0xf9, 0x6c, 0xe7, 0x92, 0x31, 0x6c, 0xcf, 0x6e, 0xfb,
- 0x93, 0xfd, 0x54, 0x46, 0x64, 0x3d, 0x34, 0x76, 0xfb, 0xea, 0xc0, 0x3d,
- 0x9f, 0xcd, 0x2c, 0x19, 0x64, 0x1f, 0x9f, 0x66, 0x7c, 0xc9, 0xd7, 0x89,
- 0x2a, 0x8e, 0x0f, 0xd4, 0x41, 0x59, 0x64, 0xdb, 0xed, 0x0b, 0x03, 0xbf,
- 0xb7, 0x16, 0x0c, 0x94, 0xd8, 0x3a, 0x70, 0x51, 0x07, 0x0f, 0x9a, 0xce,
- 0x5c, 0xc0, 0x61, 0xeb, 0xa0, 0xcb, 0x47, 0x1d, 0x24, 0xa9, 0x83, 0xdc,
- 0x4c, 0x23, 0xfc, 0x36, 0x75, 0xb0, 0x60, 0x7c, 0xf3, 0xe6, 0xb2, 0x08,
- 0x9c, 0x0e, 0xe3, 0x47, 0x0e, 0xe6, 0x45, 0xaa, 0xcb, 0xd8, 0x4c, 0xbd,
- 0xdd, 0xf3, 0xd9, 0xf9, 0x4b, 0x6c, 0x9d, 0xdf, 0xea, 0x0e, 0xdc, 0x47,
- 0xbb, 0x69, 0xa5, 0xad, 0x6f, 0xe5, 0xd1, 0xce, 0xa3, 0x8f, 0x47, 0x02,
- 0xbb, 0xb3, 0x1b, 0xa9, 0xab, 0x35, 0x1c, 0xc7, 0x3a, 0xca, 0xd5, 0xc5,
- 0xdf, 0x31, 0xfe, 0x8e, 0xf3, 0xb7, 0xcc, 0x8f, 0x7a, 0x49, 0xb6, 0xd8,
- 0x25, 0xd9, 0x1c, 0x94, 0xc7, 0x63, 0xaf, 0x55, 0x96, 0x47, 0x8e, 0xdf,
- 0xba, 0x3a, 0xd0, 0xc9, 0x36, 0xfe, 0xbf, 0x32, 0xd9, 0x57, 0xe0, 0x32,
- 0xe2, 0x3e, 0x27, 0x44, 0x3e, 0xbd, 0xa3, 0x13, 0x39, 0x62, 0xef, 0xef,
- 0xf2, 0xd8, 0x4b, 0xd9, 0xaa, 0x38, 0x3f, 0xcf, 0x2d, 0x49, 0xcf, 0xf6,
- 0x18, 0xf0, 0xb9, 0x8d, 0x7e, 0x0c, 0x64, 0x47, 0xa8, 0x03, 0xb1, 0x93,
- 0x2f, 0x52, 0x7f, 0xdd, 0xac, 0x73, 0x8a, 0xb1, 0x4c, 0x8f, 0xd2, 0x67,
- 0x69, 0xb3, 0x7a, 0x98, 0x07, 0xed, 0xe5, 0x51, 0xb6, 0x9b, 0xa6, 0x4c,
- 0x25, 0xb4, 0x5f, 0x05, 0x72, 0x0f, 0xf7, 0x0c, 0xdb, 0x3f, 0x6c, 0xfc,
- 0xba, 0xe2, 0x14, 0xc7, 0x1e, 0xf5, 0x6e, 0xc6, 0x68, 0x93, 0xe8, 0x2a,
- 0x46, 0x5d, 0xe9, 0x3e, 0xff, 0x34, 0x5d, 0x5e, 0x96, 0xf7, 0x0a, 0xf2,
- 0x09, 0xcb, 0xfa, 0x89, 0xd1, 0xb2, 0x90, 0x49, 0x21, 0xd2, 0x76, 0xae,
- 0x64, 0x59, 0x25, 0xf6, 0xfe, 0xb3, 0xd8, 0xed, 0x1b, 0x0c, 0x91, 0xb7,
- 0xb1, 0x7d, 0x3b, 0x8d, 0x73, 0x73, 0x86, 0xfe, 0x1c, 0xf8, 0x9d, 0x15,
- 0x9d, 0x29, 0xf5, 0xe6, 0xe1, 0x15, 0xc6, 0xde, 0xa8, 0x16, 0xef, 0x74,
- 0x0b, 0xbf, 0x37, 0x9c, 0xe1, 0x35, 0x88, 0x33, 0xa1, 0xd4, 0x83, 0x77,
- 0x92, 0x7b, 0x9e, 0x33, 0xf2, 0x7e, 0x7c, 0x24, 0xa3, 0x47, 0x1f, 0xe6,
- 0x39, 0x39, 0x30, 0xb9, 0x54, 0x31, 0x4e, 0x05, 0xc9, 0x7b, 0x3d, 0x70,
- 0x32, 0x87, 0x6a, 0x75, 0xf4, 0x04, 0x5d, 0xa0, 0x2f, 0x96, 0xcb, 0xb8,
- 0xe2, 0x1c, 0xa3, 0xe0, 0xb6, 0x5b, 0xdb, 0x68, 0x63, 0x79, 0x7c, 0xa1,
- 0x0b, 0x1e, 0x6d, 0x53, 0xa6, 0x18, 0xe3, 0x3c, 0xda, 0xfa, 0x84, 0xe0,
- 0x82, 0xdc, 0x77, 0x0d, 0x53, 0xcf, 0x82, 0x0f, 0xaf, 0xda, 0x7b, 0xd5,
- 0x88, 0x11, 0x55, 0x4e, 0x23, 0xdf, 0xae, 0xc6, 0x76, 0xdb, 0x1d, 0x1a,
- 0x2e, 0xfb, 0xb8, 0xae, 0xb5, 0x3b, 0x64, 0x1f, 0x1d, 0xd1, 0x2b, 0x53,
- 0xa8, 0x97, 0xc7, 0xb9, 0x65, 0x2e, 0x1b, 0xe7, 0xd8, 0x06, 0xf3, 0x8e,
- 0xe5, 0x89, 0xf7, 0xf7, 0x2f, 0xfd, 0x49, 0xbf, 0x3d, 0x35, 0x2a, 0x64,
- 0x9f, 0x8f, 0xdc, 0x13, 0xeb, 0x64, 0xbe, 0x36, 0x7d, 0xaf, 0x8f, 0x7e,
- 0x82, 0xed, 0x1f, 0x8f, 0x73, 0x3e, 0xe7, 0x1a, 0xb2, 0x0f, 0x48, 0xee,
- 0xa1, 0x4d, 0xdf, 0xf7, 0x63, 0xdf, 0x9f, 0x2c, 0x17, 0x2e, 0x73, 0x98,
- 0x38, 0x19, 0x6d, 0x97, 0xfa, 0x96, 0xf5, 0xe3, 0x05, 0x41, 0xe4, 0x66,
- 0x38, 0x31, 0xd2, 0x00, 0x0c, 0x27, 0x45, 0xd7, 0xe9, 0xcf, 0x6c, 0x30,
- 0xfe, 0xcd, 0x8a, 0xd6, 0x36, 0x6a, 0xbd, 0xaa, 0xac, 0x67, 0x8c, 0xdd,
- 0xda, 0x67, 0xd4, 0x6b, 0x7d, 0x6a, 0xee, 0x18, 0xe3, 0xd0, 0x01, 0xe6,
- 0xe8, 0xe5, 0x82, 0x15, 0x35, 0x46, 0xb4, 0xbf, 0x06, 0x0d, 0xf0, 0xdb,
- 0xf7, 0x24, 0xf4, 0xf8, 0x37, 0x54, 0x23, 0xb8, 0x56, 0xf8, 0xa7, 0xfa,
- 0x8e, 0x95, 0xa6, 0x0d, 0x7c, 0xa1, 0xe1, 0x67, 0x65, 0x79, 0x6c, 0x8f,
- 0x76, 0xce, 0xe2, 0xbc, 0xbc, 0xb9, 0x48, 0xf7, 0x67, 0x14, 0xd1, 0x91,
- 0x70, 0xae, 0x11, 0xec, 0x62, 0x3c, 0xfe, 0xb7, 0x86, 0x08, 0x8e, 0xf0,
- 0xfb, 0xa7, 0xd7, 0xca, 0x1e, 0x37, 0xcb, 0x0a, 0x06, 0x16, 0x84, 0x6b,
- 0x38, 0x86, 0x67, 0xf8, 0x7f, 0x7f, 0xf6, 0x75, 0xeb, 0xdc, 0x2c, 0x63,
- 0x70, 0x25, 0x83, 0xe2, 0xf0, 0x84, 0xae, 0x4d, 0xa9, 0xff, 0xd9, 0x3d,
- 0x37, 0xf6, 0x3a, 0xe3, 0x67, 0x9e, 0x0f, 0x34, 0x6a, 0x49, 0xb5, 0xae,
- 0x5c, 0xf4, 0x3a, 0x3c, 0xf1, 0x52, 0x21, 0xce, 0xe7, 0xef, 0x75, 0x3e,
- 0x7e, 0x49, 0x3f, 0x72, 0xdf, 0x76, 0x1e, 0x6d, 0x2e, 0x1a, 0xa7, 0xde,
- 0xdd, 0x33, 0x38, 0xe6, 0x2f, 0x34, 0xdc, 0x69, 0x8f, 0xb3, 0xd6, 0x98,
- 0xc3, 0x31, 0x2a, 0xd0, 0x1a, 0x9c, 0xe5, 0x79, 0xfe, 0xd8, 0x42, 0x96,
- 0x96, 0xb6, 0x5a, 0xe9, 0x43, 0x25, 0xac, 0x73, 0xbd, 0x79, 0x70, 0x76,
- 0x4f, 0x93, 0xee, 0xfb, 0x02, 0x6d, 0x35, 0xd4, 0xf0, 0x2b, 0x2b, 0xaa,
- 0x39, 0xcd, 0xaf, 0x73, 0xd4, 0x77, 0x26, 0xa4, 0xac, 0xcc, 0xab, 0x11,
- 0x6d, 0x50, 0xde, 0xb2, 0x30, 0x33, 0x10, 0x6e, 0xb0, 0xc7, 0x0f, 0xdc,
- 0x91, 0x19, 0x61, 0xae, 0x2c, 0x6d, 0x2a, 0x58, 0x19, 0x78, 0xc3, 0xf2,
- 0xcf, 0x1a, 0xc1, 0xce, 0xec, 0x1f, 0xe3, 0xb0, 0x5f, 0x21, 0x87, 0xd6,
- 0x3b, 0xe2, 0x79, 0xbf, 0x6b, 0x03, 0xfb, 0x2d, 0x37, 0xec, 0x3c, 0xfc,
- 0xb6, 0x44, 0x40, 0xd6, 0x8c, 0xc6, 0x3e, 0x33, 0x1e, 0x90, 0xbd, 0x19,
- 0x5e, 0xe4, 0xda, 0xa5, 0x4c, 0xbd, 0x36, 0x8e, 0x1c, 0x19, 0xa6, 0xec,
- 0x23, 0x39, 0x54, 0x9e, 0x5f, 0x47, 0x70, 0xc8, 0x3a, 0xb8, 0xf6, 0x2a,
- 0x39, 0x61, 0x9b, 0x21, 0x6d, 0x28, 0x58, 0x18, 0x98, 0x81, 0xc6, 0xb5,
- 0x3f, 0x7a, 0xb9, 0x24, 0x90, 0xf7, 0xdb, 0x3e, 0xc3, 0xd8, 0x76, 0x1a,
- 0xbf, 0x26, 0x56, 0xc9, 0x3e, 0x93, 0xb4, 0xd4, 0x63, 0x5b, 0x0d, 0xc8,
- 0x68, 0x4e, 0x8c, 0x1a, 0xb2, 0x0f, 0xd2, 0xb2, 0x56, 0x07, 0x5e, 0xa3,
- 0xdf, 0x51, 0x9e, 0xac, 0xb3, 0x50, 0x57, 0xca, 0x14, 0xf6, 0x70, 0x28,
- 0x2d, 0x9f, 0x15, 0x9d, 0x3c, 0x61, 0xc6, 0x99, 0x35, 0x48, 0x7c, 0x18,
- 0xfb, 0xcc, 0xeb, 0x86, 0x70, 0x78, 0xdd, 0x5c, 0xa9, 0x54, 0x33, 0xde,
- 0x3a, 0xfd, 0x63, 0xf6, 0x7a, 0x86, 0x9f, 0x58, 0x2e, 0x3c, 0x54, 0x72,
- 0x43, 0x27, 0x9e, 0x34, 0x6a, 0xf0, 0x84, 0x96, 0xe7, 0x74, 0xc4, 0x44,
- 0xbc, 0x90, 0x58, 0x90, 0xa3, 0x87, 0x90, 0x1b, 0x1b, 0x9d, 0x17, 0x95,
- 0x5f, 0x33, 0x6f, 0x04, 0x9e, 0xcb, 0x74, 0xe1, 0x41, 0xb9, 0x8f, 0xa5,
- 0xd4, 0xb7, 0x35, 0x3a, 0xa4, 0xbf, 0x2e, 0xec, 0xb2, 0xd7, 0x65, 0xc7,
- 0x3e, 0x73, 0xd8, 0x78, 0xa4, 0x20, 0xab, 0x60, 0xfe, 0xd8, 0x67, 0x9e,
- 0x34, 0x4e, 0xdb, 0x73, 0x27, 0x7b, 0x16, 0xfa, 0x4d, 0xc1, 0xc6, 0x72,
- 0xa8, 0xcc, 0x2f, 0x1c, 0xc6, 0xa7, 0xe1, 0xa8, 0x19, 0xa3, 0xed, 0xc9,
- 0x7a, 0xcf, 0xed, 0x70, 0xd6, 0xb8, 0xe8, 0x9b, 0x77, 0xc0, 0x55, 0x23,
- 0x9c, 0xbe, 0xc8, 0xb7, 0xdb, 0xf8, 0xbf, 0xe8, 0x76, 0xca, 0xd6, 0xad,
- 0x93, 0xd8, 0xd3, 0x27, 0xf9, 0x9f, 0x51, 0x4d, 0x1d, 0xe9, 0x1d, 0xb2,
- 0xae, 0x5d, 0x49, 0x6c, 0x65, 0x1c, 0x75, 0x57, 0xb3, 0xcc, 0xdb, 0xd4,
- 0xfb, 0x82, 0x81, 0x0a, 0x72, 0x7d, 0xcb, 0x7a, 0x87, 0x5c, 0x7f, 0x61,
- 0xa0, 0x31, 0x67, 0x30, 0xfe, 0xe1, 0x66, 0xbd, 0x4d, 0xee, 0x11, 0x6f,
- 0x30, 0x2e, 0x5a, 0xb1, 0x75, 0x52, 0x46, 0xf7, 0xc5, 0x94, 0x62, 0x1f,
- 0x8b, 0xe0, 0x9f, 0x61, 0xc1, 0x15, 0xb1, 0x88, 0x5d, 0xba, 0x19, 0x45,
- 0x8b, 0xec, 0xf5, 0x69, 0x97, 0xf1, 0xbb, 0xe4, 0x7e, 0x03, 0xa2, 0x93,
- 0x2e, 0x18, 0xb9, 0x23, 0x32, 0x67, 0xb3, 0x2d, 0x04, 0x16, 0xff, 0x8e,
- 0x39, 0x93, 0xcc, 0x4f, 0x7d, 0xae, 0x49, 0xc9, 0x05, 0x7d, 0xe4, 0xfe,
- 0x8f, 0x40, 0x6f, 0x4f, 0x50, 0xd7, 0xad, 0x21, 0x1b, 0xf3, 0x7c, 0x09,
- 0xd8, 0x7c, 0xdf, 0x7c, 0x05, 0x1f, 0x45, 0x25, 0x73, 0xdc, 0x86, 0xf1,
- 0x35, 0xa8, 0xaa, 0x89, 0xfa, 0xca, 0xb1, 0x94, 0xe7, 0x5b, 0x99, 0xc7,
- 0x7c, 0x12, 0x55, 0x6b, 0x63, 0x48, 0x70, 0xec, 0x95, 0xc6, 0xad, 0xbc,
- 0xd6, 0x87, 0x64, 0xca, 0xc5, 0x71, 0xfc, 0xd0, 0xaa, 0x9a, 0x29, 0xb2,
- 0x99, 0xde, 0x0a, 0x83, 0x79, 0xb7, 0xad, 0x0b, 0x62, 0x79, 0x4a, 0xb8,
- 0x54, 0x63, 0x74, 0x0b, 0xfe, 0x40, 0xdb, 0xd5, 0x3b, 0x36, 0x2a, 0x71,
- 0xda, 0x6c, 0x82, 0x3a, 0x97, 0xb2, 0x96, 0xb5, 0x2a, 0xf0, 0x5b, 0xea,
- 0x38, 0xce, 0x73, 0xc3, 0xff, 0x1a, 0xd4, 0xa5, 0xa5, 0x38, 0x6b, 0xc5,
- 0x35, 0x1f, 0xed, 0x52, 0x5d, 0x27, 0xbc, 0x6b, 0x45, 0x48, 0xad, 0x40,
- 0xb9, 0x56, 0xb0, 0xd3, 0x74, 0x41, 0x97, 0x53, 0xb7, 0xf5, 0x19, 0x6f,
- 0x94, 0xcb, 0x75, 0x87, 0x7d, 0xdd, 0x5f, 0xb8, 0x9e, 0xe6, 0xf5, 0xf3,
- 0xbc, 0x3e, 0x48, 0xdd, 0xab, 0x57, 0x48, 0xfd, 0xcd, 0xa6, 0xd4, 0x27,
- 0x1d, 0x31, 0x12, 0x85, 0xf9, 0x88, 0xdd, 0x9e, 0x2f, 0xbb, 0xed, 0xf6,
- 0x7c, 0x1b, 0x4e, 0xb6, 0x11, 0x8f, 0x96, 0xc3, 0x44, 0x45, 0x40, 0x70,
- 0x5e, 0xe4, 0xe2, 0xdc, 0x65, 0x45, 0xae, 0xad, 0x8c, 0x8b, 0x3d, 0x4f,
- 0x97, 0x23, 0xde, 0x35, 0xc7, 0xb6, 0xc3, 0x34, 0x79, 0x8a, 0xee, 0x7f,
- 0x5d, 0x69, 0xf1, 0xc9, 0xb2, 0x4e, 0x8a, 0x9c, 0xf7, 0x7e, 0xd3, 0x19,
- 0x6e, 0x72, 0x2c, 0xc8, 0x95, 0xc2, 0x88, 0x5d, 0x54, 0x66, 0x57, 0x08,
- 0x3e, 0x24, 0x32, 0x2d, 0xcc, 0xd0, 0xe2, 0x41, 0xe6, 0x56, 0xc1, 0x2c,
- 0x75, 0xbb, 0x9e, 0x88, 0x7d, 0xc2, 0xde, 0xb3, 0xe4, 0x9c, 0x5c, 0x83,
- 0x16, 0xdd, 0x81, 0x05, 0xe1, 0x39, 0xcc, 0xd0, 0x68, 0x97, 0x66, 0xa9,
- 0x43, 0xf7, 0xdf, 0x84, 0xff, 0x62, 0xd7, 0x3b, 0x92, 0xc9, 0x75, 0x96,
- 0x73, 0x4e, 0xbf, 0x4a, 0x39, 0x76, 0x07, 0x44, 0x8e, 0xb1, 0x82, 0x1c,
- 0x31, 0xc6, 0x5c, 0x53, 0xbb, 0x21, 0x30, 0x78, 0x49, 0x6f, 0x4f, 0xdb,
- 0x7a, 0xeb, 0xe3, 0x79, 0x29, 0x76, 0x90, 0x3f, 0x9e, 0x6a, 0xf2, 0x16,
- 0xd6, 0xf6, 0x25, 0xa7, 0x13, 0xfc, 0x3d, 0xfb, 0xa9, 0x0d, 0x86, 0x1e,
- 0x76, 0xd8, 0xfc, 0xdf, 0x8d, 0xb8, 0xcd, 0xad, 0x1d, 0x10, 0xee, 0xf8,
- 0xb0, 0x5d, 0xce, 0x45, 0x9d, 0x54, 0xe0, 0x91, 0x82, 0xbf, 0x54, 0x30,
- 0xbe, 0x7d, 0xd5, 0xfe, 0x9d, 0xe6, 0xdc, 0xba, 0xe8, 0xab, 0xc5, 0x18,
- 0x25, 0xeb, 0x83, 0xfd, 0xb6, 0xef, 0xa7, 0xf1, 0x7d, 0xfb, 0x3b, 0x97,
- 0xcf, 0xcb, 0xd0, 0x47, 0x9f, 0x70, 0xb0, 0x8d, 0x5e, 0x7b, 0x2f, 0xaa,
- 0xac, 0x15, 0x5c, 0x8b, 0x1d, 0x1c, 0x95, 0xdb, 0xe8, 0x44, 0xbf, 0x26,
- 0x36, 0xd1, 0x8d, 0xa4, 0x66, 0x7a, 0xb3, 0x4d, 0xd3, 0x73, 0x2a, 0x13,
- 0x87, 0x9a, 0x7e, 0xcf, 0x58, 0x2e, 0xd7, 0xce, 0x5a, 0x87, 0x8d, 0x53,
- 0x21, 0x7a, 0x70, 0x67, 0x89, 0xad, 0xdf, 0xa9, 0xdb, 0xec, 0x7d, 0x5b,
- 0x94, 0xf9, 0xe9, 0x84, 0xc4, 0xd1, 0x79, 0xc8, 0x98, 0x22, 0x9b, 0xb3,
- 0x7d, 0x0f, 0xe7, 0xa4, 0x2f, 0x15, 0x88, 0x5e, 0xc9, 0xff, 0x26, 0x19,
- 0xcb, 0x7a, 0xa9, 0xcf, 0x58, 0xbb, 0xf0, 0xb8, 0xad, 0x38, 0x40, 0x1b,
- 0x9b, 0x30, 0x2d, 0xeb, 0x08, 0x31, 0xa2, 0x7a, 0x81, 0x8a, 0xdc, 0xcc,
- 0xad, 0x48, 0x31, 0x36, 0x1d, 0x31, 0x5a, 0x3e, 0x5a, 0x82, 0xb8, 0x9f,
- 0x31, 0xdc, 0xb7, 0x93, 0xa3, 0xb9, 0x9f, 0xf3, 0x75, 0xca, 0x14, 0x7e,
- 0xe9, 0xbc, 0xb8, 0x02, 0x46, 0x78, 0x99, 0xe3, 0x87, 0xd6, 0x94, 0xc8,
- 0x9e, 0xea, 0xf9, 0x5f, 0x94, 0x61, 0x9b, 0x38, 0x6f, 0x35, 0xe7, 0xf8,
- 0xed, 0x80, 0xde, 0xf6, 0x02, 0xfb, 0x69, 0x1c, 0x68, 0xe9, 0x14, 0x19,
- 0x0e, 0x87, 0x9c, 0xb1, 0x23, 0x08, 0xb4, 0x6f, 0x55, 0x8a, 0x39, 0x04,
- 0x70, 0xe5, 0xb8, 0x89, 0xa3, 0x4d, 0xcf, 0x90, 0xef, 0x48, 0xfd, 0x52,
- 0x3c, 0x66, 0x3e, 0x65, 0xd5, 0xcf, 0x7e, 0xde, 0x3a, 0x66, 0xa8, 0x5b,
- 0xa8, 0xed, 0x58, 0x25, 0x64, 0x4d, 0x33, 0x7d, 0xdb, 0x5d, 0x01, 0xdd,
- 0xdc, 0xc3, 0xb6, 0xce, 0x24, 0x4e, 0x05, 0xdd, 0x6c, 0xeb, 0x11, 0x53,
- 0x72, 0x08, 0x67, 0x5b, 0x1b, 0xe7, 0xb6, 0x27, 0x15, 0xf0, 0xc9, 0xba,
- 0xad, 0xe4, 0x79, 0xb7, 0x27, 0x64, 0xcf, 0xf8, 0x18, 0xc7, 0x13, 0xdd,
- 0xe6, 0x42, 0xcb, 0xfd, 0x55, 0xb4, 0x9f, 0x6a, 0x14, 0x6d, 0x5d, 0xf7,
- 0x11, 0xef, 0x70, 0x17, 0xcb, 0xbc, 0x1c, 0x98, 0x87, 0xe7, 0x42, 0x2d,
- 0x6b, 0xe7, 0xc1, 0x19, 0x3b, 0xa6, 0x04, 0xda, 0xb6, 0x2a, 0x71, 0x4d,
- 0x6c, 0xf1, 0xce, 0x8c, 0x1e, 0x6c, 0x85, 0x60, 0x77, 0x8c, 0xfa, 0x98,
- 0x87, 0x77, 0x16, 0x8b, 0x5c, 0xce, 0x70, 0xd0, 0x11, 0xe8, 0x7a, 0x8a,
- 0xf3, 0x5b, 0xb5, 0x40, 0x64, 0x07, 0xb2, 0x19, 0x91, 0x3f, 0x86, 0x64,
- 0xf6, 0xec, 0xdb, 0x87, 0x0d, 0x38, 0x4f, 0x34, 0x3d, 0x68, 0xc1, 0xde,
- 0x63, 0xde, 0x22, 0xf3, 0xd0, 0x21, 0xf3, 0x50, 0x4e, 0x7f, 0x5a, 0x4d,
- 0xb9, 0xb7, 0xd8, 0x72, 0xcf, 0xc3, 0xa8, 0x29, 0xeb, 0x64, 0x4e, 0xed,
- 0x4e, 0x0c, 0x12, 0x3b, 0x03, 0x17, 0x7b, 0xd8, 0xcf, 0xcb, 0x94, 0x79,
- 0x01, 0xf5, 0x3e, 0xd5, 0x2e, 0xfc, 0xb6, 0x0f, 0x03, 0xa9, 0xe2, 0x1e,
- 0x74, 0x05, 0x92, 0x7a, 0x4f, 0x39, 0xfa, 0xc8, 0xf7, 0x7a, 0xac, 0xa9,
- 0x99, 0x72, 0x3d, 0x8d, 0x1d, 0xa9, 0xa8, 0x46, 0x7f, 0xa0, 0xde, 0xa1,
- 0xcf, 0x83, 0x3e, 0xf9, 0xaa, 0x23, 0x4a, 0x1f, 0x30, 0xbd, 0x17, 0x89,
- 0x0d, 0x27, 0xd0, 0x65, 0xa1, 0xc6, 0xb6, 0x87, 0x9f, 0x8e, 0x19, 0x0e,
- 0x59, 0x6b, 0x0f, 0xe6, 0xa8, 0x03, 0x95, 0x73, 0x22, 0x3a, 0xa8, 0xa4,
- 0xcf, 0x8e, 0x07, 0x74, 0xff, 0x73, 0x94, 0x67, 0x0f, 0xe5, 0x59, 0x93,
- 0x9f, 0x43, 0xdf, 0x0e, 0x45, 0x7c, 0x3a, 0xd0, 0xbe, 0x81, 0xd7, 0x77,
- 0x53, 0x9e, 0xc0, 0x80, 0x82, 0x34, 0xd1, 0xac, 0x8f, 0x7c, 0xf6, 0xc0,
- 0x34, 0x79, 0xdc, 0xf6, 0x9c, 0xc5, 0xc9, 0x05, 0x4a, 0x71, 0xd8, 0x14,
- 0xfc, 0xd6, 0x30, 0x4a, 0x3b, 0x3d, 0xc4, 0x19, 0x89, 0x7a, 0x55, 0x94,
- 0x1a, 0x82, 0x01, 0x33, 0x79, 0xcd, 0xc5, 0xb9, 0xa9, 0xc6, 0x31, 0x2d,
- 0xcd, 0x38, 0x59, 0xe4, 0x76, 0x7f, 0xb0, 0x8e, 0x7a, 0x85, 0x9f, 0xc9,
- 0x3a, 0x9a, 0xac, 0x35, 0x7d, 0xb9, 0x22, 0xbf, 0xbf, 0x52, 0xf6, 0x3f,
- 0xe4, 0xaf, 0x3f, 0xad, 0x09, 0x47, 0x2e, 0x96, 0xff, 0xb9, 0xf5, 0x84,
- 0x5d, 0x5e, 0xca, 0xb9, 0x6c, 0x2e, 0x5f, 0x6e, 0x97, 0xfb, 0xb9, 0xf5,
- 0x8c, 0xe6, 0x9c, 0x56, 0xae, 0xb8, 0x07, 0xef, 0xd4, 0x97, 0x5c, 0xc4,
- 0x3c, 0x47, 0xc3, 0x32, 0x3c, 0x61, 0x9c, 0xad, 0x5f, 0xdf, 0xd4, 0xcd,
- 0x38, 0x56, 0xe4, 0x5a, 0x75, 0xf4, 0x2b, 0x0b, 0x43, 0xe6, 0xa9, 0xa1,
- 0x12, 0xf4, 0x90, 0x3b, 0x0a, 0x17, 0x10, 0x8e, 0x2a, 0xeb, 0x7c, 0xb7,
- 0x96, 0x5f, 0xce, 0x79, 0xf5, 0xa0, 0x5f, 0x6d, 0xb3, 0xb9, 0x61, 0x54,
- 0x15, 0xdc, 0xad, 0xb3, 0xc7, 0x7e, 0x39, 0xfe, 0x4b, 0xac, 0x98, 0xbe,
- 0x6e, 0xd7, 0x8d, 0x43, 0x46, 0x91, 0xb3, 0x9c, 0x7a, 0x50, 0x25, 0x4e,
- 0x0e, 0x9b, 0xcb, 0x24, 0x36, 0xfb, 0x59, 0x3f, 0x18, 0x53, 0xa7, 0x73,
- 0x9b, 0xbf, 0xa9, 0x40, 0x55, 0xcf, 0x2e, 0x07, 0x64, 0xff, 0xaf, 0xec,
- 0xd9, 0x96, 0xbe, 0xca, 0x0a, 0xeb, 0x57, 0x1f, 0xc4, 0x35, 0x8a, 0x7d,
- 0x09, 0xdf, 0xa8, 0x28, 0xca, 0x18, 0x8c, 0xda, 0x72, 0xfe, 0xd2, 0x5a,
- 0xab, 0xe5, 0xe6, 0x68, 0x78, 0xaf, 0xec, 0xd1, 0x82, 0xec, 0xb1, 0x0f,
- 0x5c, 0x7f, 0x93, 0x7e, 0xa6, 0xb7, 0x59, 0xdc, 0x7b, 0x2a, 0x6b, 0xb3,
- 0xf2, 0x9f, 0x82, 0x1e, 0xe2, 0x50, 0x54, 0x6b, 0x61, 0x9c, 0xd7, 0x7d,
- 0x9b, 0x38, 0x1f, 0x71, 0xaf, 0xec, 0x6b, 0x2d, 0xc6, 0xc8, 0x52, 0xe4,
- 0xd7, 0x48, 0x81, 0x43, 0x85, 0x75, 0x51, 0xda, 0x3d, 0x7a, 0x32, 0xbf,
- 0xb3, 0x72, 0x5e, 0x27, 0x63, 0xe1, 0xe5, 0xfd, 0xf7, 0x69, 0xea, 0x75,
- 0x94, 0xff, 0xed, 0xb8, 0xb4, 0xee, 0x22, 0x6b, 0x4f, 0x12, 0x7b, 0x7f,
- 0x6b, 0xad, 0x7f, 0x4f, 0xd9, 0xe9, 0x7b, 0x5f, 0x67, 0xc6, 0x64, 0x3f,
- 0xda, 0xd1, 0xc2, 0xfa, 0x7c, 0xeb, 0xbf, 0xdf, 0x8f, 0x46, 0x5b, 0x42,
- 0x74, 0x07, 0xb9, 0x5d, 0x1c, 0x7d, 0x38, 0x9a, 0x68, 0xd4, 0x76, 0x42,
- 0x93, 0x75, 0x69, 0x7e, 0xfa, 0x70, 0x2c, 0x81, 0x68, 0xc9, 0x55, 0xd5,
- 0xe4, 0x5b, 0x88, 0x3a, 0x64, 0x8f, 0x50, 0xa2, 0xb1, 0x6d, 0x37, 0xc7,
- 0xe4, 0x5f, 0xdb, 0x87, 0xd1, 0x44, 0xcb, 0xad, 0x8c, 0x23, 0xfe, 0x8a,
- 0x3c, 0xd7, 0xe9, 0x38, 0x4c, 0x1c, 0xd8, 0x5e, 0x58, 0x1b, 0x5b, 0x9f,
- 0xf8, 0x15, 0xe5, 0xb7, 0x85, 0x64, 0xbd, 0x3f, 0x56, 0xee, 0x2c, 0x7a,
- 0x53, 0x67, 0xb1, 0x79, 0x50, 0x11, 0xfb, 0xc2, 0xa6, 0xb4, 0xc8, 0x73,
- 0x16, 0x1b, 0x07, 0xbf, 0x87, 0x43, 0x83, 0xb3, 0xd1, 0x6a, 0xeb, 0xa6,
- 0x0b, 0x5b, 0xf7, 0x9e, 0xc4, 0x9e, 0x94, 0x85, 0xdd, 0x21, 0x0f, 0xb6,
- 0x1c, 0x54, 0xb0, 0x2a, 0x70, 0x06, 0x3b, 0xf7, 0x5a, 0x98, 0x1f, 0xea,
- 0x46, 0x9b, 0x59, 0x81, 0xd2, 0x9a, 0x05, 0x9d, 0x2a, 0xcb, 0xad, 0x1f,
- 0xed, 0x52, 0x6e, 0xe4, 0xb8, 0x73, 0xae, 0xe3, 0xc4, 0x02, 0x15, 0x3e,
- 0x03, 0x5a, 0x75, 0x24, 0xaa, 0xdc, 0x92, 0x6d, 0x55, 0x3a, 0x46, 0x6d,
- 0x3e, 0xa5, 0xdc, 0x94, 0xf5, 0x55, 0x4a, 0x4c, 0x3f, 0x14, 0x3a, 0x8b,
- 0x74, 0xba, 0xaa, 0x32, 0xef, 0x2f, 0x67, 0xc9, 0x1d, 0x24, 0xe7, 0x30,
- 0x69, 0x53, 0x7f, 0xec, 0xb9, 0x02, 0xb1, 0xbb, 0x29, 0xfc, 0x64, 0xe4,
- 0x15, 0xbc, 0x32, 0xf2, 0x2f, 0x58, 0xae, 0x49, 0x9e, 0x69, 0x75, 0x3b,
- 0x23, 0x96, 0xb5, 0xbf, 0x39, 0x6e, 0xcd, 0x34, 0x2c, 0xb6, 0x57, 0x85,
- 0x59, 0x91, 0xef, 0x62, 0xb7, 0xc6, 0xb6, 0x52, 0xc7, 0xed, 0x7b, 0xb7,
- 0xbe, 0xc8, 0xa7, 0xe1, 0x4b, 0xe5, 0xcc, 0x5a, 0x44, 0x87, 0x6a, 0xa1,
- 0x6f, 0xab, 0x71, 0x18, 0x5d, 0xff, 0x5b, 0x69, 0xc2, 0x4d, 0xd9, 0x57,
- 0xf0, 0xe6, 0x48, 0x37, 0x31, 0x53, 0xef, 0xf8, 0x96, 0x62, 0x75, 0xef,
- 0x0e, 0xe9, 0x6d, 0xff, 0x55, 0x89, 0xc6, 0xcb, 0x69, 0x53, 0x65, 0xcc,
- 0x09, 0x6e, 0x1e, 0x91, 0x7c, 0xb9, 0x03, 0xee, 0x01, 0x3d, 0xb7, 0x82,
- 0x3c, 0xfb, 0x0b, 0x8b, 0xe2, 0x73, 0x66, 0xd0, 0x2e, 0x1d, 0x8a, 0x1e,
- 0x34, 0xd4, 0x6e, 0x3c, 0x6e, 0xea, 0x93, 0xbf, 0x75, 0x18, 0xe9, 0x6f,
- 0xa2, 0x09, 0xeb, 0xb2, 0x7a, 0x7a, 0x29, 0xf3, 0xb0, 0x9d, 0x49, 0x13,
- 0xa9, 0xa4, 0xde, 0xd1, 0xe5, 0xe8, 0xc7, 0xdd, 0x81, 0xfa, 0x6d, 0x6f,
- 0x93, 0xcb, 0x79, 0x88, 0x29, 0xc9, 0x89, 0x0c, 0xf3, 0xdc, 0x7e, 0x6c,
- 0x3d, 0x18, 0xc1, 0x96, 0xfd, 0x26, 0xfa, 0x92, 0x19, 0xca, 0xf6, 0x1a,
- 0x6d, 0xdb, 0xb2, 0xda, 0x43, 0xf1, 0x1b, 0x54, 0x04, 0xa2, 0xec, 0xb3,
- 0x45, 0x8d, 0x04, 0xfc, 0xaa, 0xc2, 0xe8, 0x3f, 0xe1, 0x44, 0x2f, 0xcb,
- 0x0c, 0xa4, 0x68, 0x73, 0x49, 0x37, 0xe3, 0x65, 0x1d, 0x46, 0xc7, 0x7d,
- 0x38, 0x32, 0xee, 0x41, 0x7a, 0x5c, 0xe3, 0x51, 0x8e, 0x87, 0x86, 0x2d,
- 0x62, 0xb9, 0x17, 0x8f, 0x1d, 0x76, 0x63, 0xfb, 0x3e, 0x0f, 0xe6, 0x45,
- 0x66, 0xe1, 0xf0, 0xe1, 0x72, 0x1c, 0xe0, 0xf5, 0x9a, 0xc5, 0x7e, 0x7c,
- 0x8d, 0xd7, 0x07, 0xf7, 0xb9, 0x38, 0x0f, 0xf3, 0x71, 0x9c, 0x86, 0x9d,
- 0x1e, 0xaf, 0x40, 0x6a, 0x98, 0x26, 0x4f, 0xce, 0xfa, 0x3a, 0x33, 0x8c,
- 0xa3, 0x87, 0x19, 0x1b, 0x0f, 0x9a, 0x48, 0xb0, 0x9f, 0x3d, 0xd4, 0x55,
- 0x1f, 0x71, 0x6d, 0xeb, 0xb8, 0x60, 0xfc, 0x3a, 0xac, 0x1e, 0xd0, 0xdb,
- 0x5a, 0x15, 0x23, 0xba, 0x44, 0x09, 0xca, 0x73, 0x2b, 0x6e, 0x95, 0xd7,
- 0x5a, 0x12, 0xba, 0xd9, 0x8a, 0x6e, 0x9c, 0xe6, 0xb8, 0xff, 0x3b, 0xfd,
- 0x76, 0x99, 0x43, 0xef, 0xbf, 0x5e, 0x3d, 0x89, 0xa1, 0x6c, 0x8e, 0x5c,
- 0x1d, 0x08, 0x1f, 0x3a, 0x49, 0xfe, 0xf6, 0x38, 0xf1, 0xe7, 0x65, 0xcb,
- 0x67, 0xa8, 0xb8, 0xe9, 0x01, 0x23, 0x7c, 0x41, 0x09, 0x6c, 0xfb, 0x25,
- 0x75, 0x70, 0xe3, 0x61, 0x15, 0x1f, 0x1b, 0x5a, 0x86, 0x4c, 0x28, 0x8a,
- 0x3d, 0x4b, 0x54, 0xdc, 0x70, 0xf0, 0x24, 0x71, 0xff, 0xac, 0xcd, 0x93,
- 0x73, 0x99, 0x2f, 0x22, 0x38, 0x20, 0x6b, 0xf7, 0x6e, 0xc6, 0xef, 0x4a,
- 0x9c, 0x19, 0xec, 0xa6, 0xdf, 0x56, 0xe2, 0x54, 0xfa, 0x24, 0xed, 0xb1,
- 0x12, 0x8f, 0x0f, 0x1a, 0x93, 0x3f, 0x71, 0x54, 0xe2, 0x31, 0x9e, 0x0f,
- 0xf1, 0x7c, 0xf1, 0xb0, 0x31, 0xd8, 0xa5, 0x56, 0x62, 0xd1, 0xa1, 0x66,
- 0x0c, 0x26, 0xc5, 0x36, 0x35, 0x6c, 0x1b, 0x6f, 0x2a, 0xe8, 0x5e, 0x74,
- 0xee, 0xc5, 0x3d, 0xd4, 0xd5, 0xdd, 0x43, 0xdd, 0xec, 0xcf, 0x47, 0x9d,
- 0x9f, 0xc4, 0x43, 0xcc, 0xeb, 0x76, 0x27, 0x7d, 0x38, 0x9f, 0x32, 0xfc,
- 0x9f, 0x52, 0x0c, 0xb3, 0x4c, 0x09, 0x68, 0x67, 0xe0, 0xc3, 0x2b, 0xd9,
- 0x72, 0xf4, 0x0e, 0xd7, 0xe1, 0x27, 0xb4, 0xcf, 0x07, 0xf7, 0x9d, 0xb4,
- 0xed, 0xff, 0x40, 0x6a, 0x2e, 0x1e, 0x1b, 0x33, 0xd9, 0xb6, 0xcc, 0x93,
- 0xc3, 0xde, 0xdb, 0xe4, 0x4a, 0x89, 0x6f, 0x44, 0x87, 0x68, 0x16, 0xc4,
- 0xc4, 0x93, 0xc8, 0x0e, 0xea, 0xfd, 0x37, 0xab, 0xc2, 0xab, 0x55, 0xea,
- 0xd2, 0x81, 0x29, 0x4d, 0x8f, 0xd7, 0xa8, 0xf1, 0x41, 0xe6, 0xaf, 0xf1,
- 0x5a, 0xea, 0xe4, 0xb1, 0x41, 0x27, 0x16, 0x2c, 0x56, 0x79, 0x3d, 0x7e,
- 0x91, 0xb1, 0x2d, 0x3e, 0x4f, 0x35, 0x71, 0xc0, 0x96, 0x15, 0xf1, 0x12,
- 0x72, 0xfb, 0xea, 0xc5, 0xf5, 0x8c, 0x5f, 0x0e, 0xb1, 0xbd, 0x58, 0xa5,
- 0xea, 0xa4, 0xde, 0x5f, 0xc1, 0x18, 0xed, 0xfa, 0x11, 0x1e, 0xc7, 0x47,
- 0xac, 0xee, 0x55, 0xe4, 0xdc, 0xf3, 0x03, 0x56, 0xf7, 0xcd, 0xa6, 0xe1,
- 0x2b, 0x51, 0x03, 0xd1, 0x2f, 0xe0, 0x15, 0x1c, 0x1b, 0x93, 0x32, 0xb2,
- 0x0f, 0x24, 0x86, 0x91, 0xa4, 0xd5, 0x3d, 0x64, 0xce, 0x47, 0xb3, 0x9d,
- 0x1b, 0xbb, 0x2a, 0xf3, 0x98, 0x29, 0x7e, 0x24, 0x6b, 0x25, 0x53, 0xf8,
- 0x25, 0xdb, 0xb9, 0x30, 0x52, 0x8d, 0x19, 0xb5, 0xe2, 0x07, 0x67, 0xf1,
- 0xc6, 0xe0, 0x77, 0x71, 0x7e, 0xd0, 0xc2, 0xa2, 0x90, 0x05, 0x67, 0xa8,
- 0xd1, 0x6c, 0x55, 0x97, 0x12, 0x23, 0x14, 0xac, 0x6e, 0xf8, 0x1e, 0xde,
- 0x1a, 0x94, 0xfd, 0xa6, 0x96, 0x2d, 0xcb, 0x00, 0x16, 0x5b, 0x7b, 0x66,
- 0x8a, 0xdf, 0x48, 0xbd, 0x3f, 0x95, 0x07, 0xeb, 0x8c, 0x86, 0xc5, 0x5c,
- 0xf8, 0x15, 0x8c, 0x8e, 0x18, 0xd1, 0xcd, 0x45, 0x39, 0x07, 0x5f, 0xa1,
- 0x0e, 0xec, 0xf8, 0x74, 0xb0, 0x06, 0x0b, 0x2e, 0x32, 0x6b, 0xfc, 0xf0,
- 0x3c, 0xda, 0xce, 0xa2, 0xc5, 0x01, 0x73, 0xa5, 0xfa, 0x6f, 0xf4, 0xd3,
- 0x57, 0x70, 0x24, 0x5d, 0xc4, 0x6b, 0x1f, 0x5a, 0xe9, 0xe7, 0xf9, 0x7d,
- 0xfe, 0x5e, 0xb4, 0xa4, 0x4e, 0xd8, 0xeb, 0x0f, 0xc7, 0x89, 0x8f, 0x83,
- 0x29, 0x29, 0xa3, 0x61, 0x2c, 0xdb, 0x4a, 0x6c, 0x88, 0xe2, 0x9f, 0xb2,
- 0x11, 0xe2, 0x43, 0x98, 0xf8, 0xd0, 0x4c, 0x7c, 0x30, 0x89, 0x0f, 0x4d,
- 0xc4, 0x87, 0x20, 0xf1, 0xc1, 0xb0, 0xd7, 0xd6, 0xd3, 0x47, 0xbf, 0x8b,
- 0x92, 0xe1, 0xb3, 0x70, 0xd1, 0x07, 0xce, 0x98, 0x16, 0xf9, 0x49, 0xa3,
- 0xb6, 0x11, 0xf3, 0x95, 0xa8, 0xe6, 0x45, 0x9a, 0xed, 0x95, 0x0d, 0x6b,
- 0x1c, 0x8b, 0x85, 0x60, 0xa8, 0x3e, 0xdc, 0x4f, 0xac, 0xfe, 0x95, 0xd1,
- 0xd8, 0xef, 0x45, 0xe3, 0x81, 0x99, 0x30, 0x06, 0x17, 0xab, 0x0d, 0x4a,
- 0xf4, 0xe3, 0x5e, 0x8e, 0xb3, 0x16, 0x73, 0xf7, 0x69, 0x98, 0xc7, 0xe3,
- 0x1f, 0x53, 0xf5, 0x93, 0x2f, 0x3b, 0xe0, 0x9d, 0x4d, 0xba, 0x33, 0x87,
- 0x4c, 0x80, 0xac, 0xd6, 0xeb, 0xc3, 0x95, 0xc7, 0x5f, 0x51, 0x15, 0xe4,
- 0x3e, 0x2e, 0x31, 0xaf, 0x31, 0xd8, 0xa7, 0xaa, 0xb2, 0x96, 0x44, 0x0c,
- 0xe7, 0xa1, 0x22, 0x42, 0x16, 0x51, 0xc7, 0xfc, 0xc2, 0xda, 0x68, 0x96,
- 0x61, 0x47, 0x13, 0x39, 0xa7, 0x57, 0x3f, 0x21, 0x31, 0x6a, 0x36, 0x63,
- 0x44, 0x79, 0x32, 0x7e, 0xe7, 0x6c, 0x78, 0x50, 0x96, 0xb4, 0xac, 0xaf,
- 0x86, 0x34, 0x78, 0x22, 0x81, 0xe8, 0x56, 0xa6, 0x91, 0x1f, 0x5f, 0x10,
- 0xc6, 0xea, 0xec, 0x09, 0x0c, 0x73, 0x7c, 0xab, 0xb2, 0xc5, 0x67, 0xc5,
- 0xfe, 0xf8, 0xe7, 0xf2, 0x33, 0x67, 0x57, 0x1e, 0x98, 0x0d, 0x43, 0xbb,
- 0x57, 0x1d, 0xae, 0x22, 0x07, 0x3f, 0xce, 0xb8, 0xa7, 0x4c, 0x7d, 0x42,
- 0x41, 0xc7, 0x70, 0x1c, 0x33, 0x42, 0x2f, 0x28, 0xb1, 0x5a, 0xdd, 0xef,
- 0x57, 0x6a, 0xf1, 0x89, 0x7d, 0xd4, 0xf5, 0xa2, 0x1f, 0x7a, 0xe4, 0xb9,
- 0xb0, 0x6f, 0x1e, 0x15, 0xdd, 0xd6, 0xa7, 0x87, 0x38, 0x8e, 0xc9, 0x86,
- 0x13, 0x82, 0x93, 0x8f, 0xba, 0xe1, 0x78, 0x74, 0x16, 0xa2, 0x68, 0x6a,
- 0xb8, 0xb2, 0xeb, 0x5f, 0x54, 0xd1, 0x8b, 0xf0, 0x6b, 0x7d, 0x30, 0xae,
- 0x18, 0xda, 0xcf, 0x95, 0x13, 0xf6, 0x7d, 0xb8, 0xaf, 0x66, 0x4f, 0x52,
- 0x97, 0xc7, 0x0b, 0xf9, 0xd2, 0x3a, 0x24, 0x06, 0x64, 0x5f, 0xfe, 0x59,
- 0xcc, 0x1d, 0xd6, 0xdb, 0x77, 0x29, 0x46, 0xf0, 0x06, 0xe5, 0x2c, 0xe6,
- 0x0c, 0x07, 0x39, 0x97, 0x1a, 0x56, 0x26, 0x8b, 0xf8, 0x29, 0x18, 0xbc,
- 0x8e, 0x18, 0x6c, 0x2d, 0xfb, 0x89, 0x19, 0xd7, 0x65, 0x4f, 0x82, 0x53,
- 0xd1, 0x3b, 0x1a, 0x94, 0x38, 0x63, 0xa8, 0x71, 0x71, 0x3d, 0xeb, 0x78,
- 0x86, 0x9b, 0x70, 0x3b, 0xc7, 0xdc, 0xc6, 0x79, 0xfb, 0xee, 0x62, 0x0b,
- 0x4b, 0x16, 0xeb, 0x07, 0xca, 0x1c, 0xd1, 0x7b, 0x6b, 0x90, 0xeb, 0x9a,
- 0x49, 0xbb, 0xb9, 0x7b, 0x91, 0x1e, 0x7e, 0x81, 0xb8, 0x4b, 0x9c, 0x46,
- 0x2f, 0xe3, 0xce, 0x46, 0xc6, 0xa2, 0xf2, 0x88, 0xde, 0xcf, 0x1c, 0xf5,
- 0xc2, 0x1d, 0x8e, 0x68, 0x48, 0x9e, 0xff, 0xf8, 0x32, 0x96, 0xc1, 0x1d,
- 0xaa, 0x22, 0x0e, 0xea, 0xb9, 0xef, 0x42, 0x3f, 0x70, 0x3b, 0xfa, 0xf1,
- 0x03, 0xf2, 0xbb, 0x99, 0x57, 0xe5, 0x88, 0x51, 0x19, 0x3c, 0x98, 0x3d,
- 0x89, 0x03, 0xd9, 0x47, 0xb1, 0x37, 0xbb, 0x5b, 0x49, 0xdb, 0xf7, 0x20,
- 0x15, 0x79, 0xee, 0x26, 0x5a, 0xa5, 0x7c, 0x06, 0x95, 0xa1, 0xaf, 0x5b,
- 0xe9, 0x1a, 0x15, 0xd5, 0xa1, 0x20, 0x56, 0x27, 0xe3, 0x70, 0x44, 0xde,
- 0xb6, 0xe4, 0xb9, 0xcf, 0x2d, 0x13, 0x06, 0xae, 0x4f, 0x96, 0x23, 0x76,
- 0xc8, 0xb2, 0xfa, 0x9b, 0x9d, 0xd8, 0x34, 0xd1, 0x84, 0x95, 0xc3, 0x0f,
- 0x59, 0xf3, 0x18, 0x73, 0xde, 0xbd, 0xc6, 0x83, 0x3b, 0x0e, 0x79, 0xb0,
- 0x3e, 0x19, 0x85, 0x2f, 0x52, 0xc1, 0xdf, 0x01, 0x73, 0x39, 0x8c, 0xc9,
- 0x49, 0x18, 0xfd, 0xd7, 0x39, 0x02, 0xc7, 0xc2, 0xaa, 0x07, 0x7f, 0x4d,
- 0x1c, 0x5f, 0x45, 0xdc, 0x89, 0x4d, 0x58, 0xa8, 0x8e, 0x78, 0x71, 0x27,
- 0xeb, 0x7f, 0x8c, 0x73, 0xff, 0xd6, 0x92, 0xe3, 0xc4, 0x02, 0x23, 0x36,
- 0xa1, 0x68, 0xd8, 0x3a, 0xe1, 0xa6, 0xae, 0xdc, 0x88, 0x1d, 0xa9, 0xc5,
- 0xf5, 0xfb, 0xfc, 0xb8, 0x63, 0xc2, 0x83, 0x96, 0xa4, 0xb5, 0xec, 0xb8,
- 0x19, 0x5f, 0xab, 0xc1, 0xc0, 0xfa, 0x09, 0x2f, 0x6e, 0x4b, 0xea, 0xbe,
- 0x1b, 0x98, 0xf3, 0x8f, 0x99, 0x41, 0xfc, 0xed, 0x84, 0x0f, 0xb7, 0x24,
- 0x4f, 0x49, 0x1e, 0xb9, 0xdc, 0xc9, 0xd8, 0x73, 0xff, 0x44, 0x1d, 0xd6,
- 0x26, 0xf5, 0x8b, 0x93, 0xe4, 0x76, 0xdd, 0x47, 0x4c, 0xdc, 0x3b, 0xa1,
- 0xa2, 0x83, 0xed, 0x7c, 0x22, 0x39, 0x17, 0x5d, 0x47, 0x9a, 0x29, 0xc3,
- 0x62, 0xac, 0x1a, 0x76, 0xc2, 0x24, 0x8b, 0xc7, 0x27, 0x81, 0x76, 0xfa,
- 0x47, 0x22, 0xf5, 0x45, 0xec, 0x19, 0x30, 0x71, 0xd7, 0x84, 0x9c, 0x9f,
- 0xb4, 0x9f, 0x95, 0xbb, 0x70, 0x70, 0x31, 0x6e, 0x1c, 0x56, 0x89, 0x03,
- 0xa5, 0x48, 0xaf, 0x55, 0x70, 0x1b, 0xaf, 0xef, 0x4a, 0xd9, 0x7b, 0xab,
- 0x11, 0x1a, 0x0a, 0x1c, 0xab, 0x21, 0x67, 0x58, 0x72, 0x30, 0x7f, 0xfd,
- 0x41, 0xe2, 0x7c, 0x19, 0x71, 0xbe, 0x82, 0x1c, 0xf6, 0xba, 0xd1, 0x93,
- 0x78, 0x80, 0xb8, 0x7c, 0x62, 0xb8, 0x9b, 0x71, 0xa7, 0x12, 0x5f, 0x63,
- 0x1c, 0x48, 0xf2, 0xfc, 0xec, 0x90, 0xd1, 0x55, 0x46, 0x9c, 0x7e, 0x81,
- 0xf8, 0xdb, 0x4f, 0xcc, 0xb8, 0x3b, 0x49, 0xb7, 0x1f, 0x62, 0x0e, 0x70,
- 0x55, 0x74, 0xa1, 0x87, 0x39, 0xd6, 0x0d, 0x4a, 0xc0, 0xf7, 0x1a, 0x2a,
- 0xe1, 0x38, 0x58, 0x8b, 0x96, 0x7d, 0x52, 0x46, 0xf0, 0x4b, 0x85, 0x7a,
- 0xd8, 0x49, 0x9d, 0x9f, 0x84, 0x35, 0xe8, 0xe0, 0x78, 0xeb, 0x4d, 0x32,
- 0x70, 0xfc, 0xd8, 0xd4, 0xb5, 0x7f, 0x22, 0xd6, 0xbe, 0x43, 0x4c, 0xf5,
- 0xcf, 0x6e, 0x46, 0xab, 0x61, 0xf2, 0x38, 0x89, 0x57, 0x06, 0x0d, 0xf3,
- 0x10, 0x9c, 0x78, 0x99, 0x3c, 0x6f, 0x6a, 0x36, 0x63, 0xa6, 0x21, 0x7e,
- 0x98, 0xe1, 0x78, 0x54, 0xc9, 0x4b, 0xe0, 0x18, 0x07, 0xde, 0x38, 0xb8,
- 0x8c, 0xe3, 0x92, 0x58, 0x2a, 0xf1, 0x2e, 0x43, 0x59, 0x97, 0x61, 0x0d,
- 0xf5, 0xd1, 0x9a, 0x54, 0x91, 0x39, 0x12, 0xc1, 0x5d, 0xfb, 0xf3, 0x71,
- 0x78, 0x5b, 0x28, 0x7e, 0x33, 0xe3, 0x70, 0xb8, 0x9c, 0x71, 0xd8, 0x15,
- 0x11, 0xd9, 0x9c, 0x18, 0x65, 0xdc, 0xde, 0x91, 0x0a, 0xa3, 0x8d, 0x73,
- 0x38, 0x99, 0x61, 0xbf, 0xc9, 0x3a, 0x9c, 0xc9, 0x78, 0x18, 0xb3, 0x34,
- 0x1e, 0x44, 0xb5, 0xb1, 0x59, 0x3c, 0xfc, 0x3c, 0xe6, 0xf3, 0x30, 0xec,
- 0x6b, 0x1b, 0x93, 0x0a, 0xe2, 0xed, 0x8a, 0xcd, 0xe7, 0xcf, 0x64, 0x04,
- 0x9b, 0x65, 0x2d, 0x73, 0x7b, 0x95, 0x3c, 0x8b, 0x32, 0x98, 0xfa, 0x1e,
- 0xaa, 0xa9, 0xff, 0xaa, 0x02, 0x0e, 0xfd, 0x34, 0x24, 0xb8, 0x5b, 0x4f,
- 0xdc, 0x95, 0xe7, 0x04, 0x2c, 0x6b, 0x5d, 0x60, 0x3a, 0x1e, 0xfd, 0x9f,
- 0x77, 0xa3, 0xf6, 0x33, 0x17, 0x82, 0x49, 0xc4, 0xbf, 0x14, 0xf1, 0x8f,
- 0x63, 0xe8, 0xb9, 0x96, 0x18, 0x48, 0x99, 0xfe, 0x21, 0x45, 0x0c, 0x24,
- 0x4e, 0x3f, 0x4a, 0x9c, 0xfe, 0x06, 0x71, 0xfa, 0xeb, 0xc4, 0xe9, 0xaf,
- 0x11, 0x13, 0xf2, 0x6b, 0x7a, 0x6d, 0x72, 0xff, 0x85, 0xf3, 0xf1, 0x96,
- 0xbd, 0xb6, 0x38, 0x93, 0xba, 0x9a, 0x3b, 0xac, 0x60, 0x9e, 0xa1, 0x1f,
- 0x13, 0xbb, 0xff, 0x01, 0xe7, 0xc9, 0x3f, 0xa3, 0xce, 0x7e, 0x26, 0xa6,
- 0x35, 0xd9, 0x07, 0x77, 0xb2, 0x51, 0xeb, 0x87, 0xfd, 0x2c, 0xb2, 0x29,
- 0x5c, 0xb4, 0x24, 0xb9, 0x11, 0x8e, 0x64, 0xe3, 0xb1, 0xd3, 0x72, 0x9f,
- 0x77, 0x96, 0xe4, 0xf5, 0x1b, 0xe1, 0x4c, 0xea, 0xc7, 0xe2, 0x94, 0x65,
- 0x25, 0xff, 0x73, 0x25, 0x1b, 0xcd, 0xd7, 0x60, 0x63, 0x9b, 0x7f, 0xca,
- 0xfe, 0xaf, 0xfe, 0xc2, 0x03, 0xd4, 0x57, 0x8e, 0x6d, 0x66, 0xa8, 0xfb,
- 0x72, 0xf2, 0x95, 0x47, 0xb2, 0xf2, 0xbb, 0xb1, 0x23, 0xa1, 0x1e, 0x43,
- 0x6c, 0xa6, 0xf0, 0xf1, 0x30, 0x6e, 0x4a, 0x7a, 0x68, 0x07, 0x71, 0x54,
- 0xd1, 0xb7, 0x3e, 0x37, 0xd1, 0x4c, 0x5f, 0x7b, 0xc8, 0xd2, 0x22, 0x81,
- 0x8e, 0x09, 0x72, 0x9e, 0x2d, 0x13, 0xcb, 0xb0, 0x62, 0xd8, 0xb2, 0x3c,
- 0x4b, 0x8d, 0xf0, 0x56, 0xc5, 0x0f, 0x17, 0x7d, 0xd0, 0x41, 0xbf, 0xda,
- 0x7c, 0x28, 0xa0, 0xbd, 0x46, 0x3c, 0xed, 0x6c, 0x3e, 0x41, 0xfb, 0x30,
- 0x2e, 0xb6, 0x11, 0x4b, 0x9d, 0x91, 0x00, 0xf3, 0x44, 0x0f, 0x6d, 0xdf,
- 0x8b, 0x8b, 0x09, 0xf1, 0x2f, 0xbd, 0xeb, 0x9f, 0x98, 0x9b, 0x74, 0xd1,
- 0x37, 0x7e, 0x9e, 0xa8, 0xa3, 0x0f, 0xb8, 0xf1, 0x46, 0xc2, 0xa0, 0xbf,
- 0x79, 0xf0, 0x56, 0xa2, 0x89, 0x7d, 0x05, 0x59, 0xc6, 0x8f, 0x7b, 0x26,
- 0xc2, 0xf4, 0xb3, 0x6b, 0x79, 0xc8, 0x73, 0x99, 0xf5, 0xf1, 0x6f, 0x2a,
- 0xf5, 0x83, 0x73, 0xd5, 0x1a, 0x44, 0x6b, 0x35, 0x7c, 0x7e, 0xe2, 0x23,
- 0xf8, 0x57, 0xc6, 0xed, 0x4d, 0x49, 0x70, 0x0e, 0x11, 0x22, 0x0f, 0x9c,
- 0x3c, 0x22, 0xf7, 0x1c, 0xd1, 0x18, 0x6d, 0x70, 0xe8, 0xcc, 0x6d, 0xf5,
- 0xdc, 0x79, 0x87, 0x93, 0x7d, 0x92, 0x15, 0xb3, 0xec, 0xcf, 0x07, 0xcb,
- 0x71, 0xef, 0xa1, 0x13, 0xf4, 0x91, 0x12, 0x2c, 0x7a, 0xc0, 0x8d, 0xcf,
- 0x1f, 0xc9, 0x90, 0x3b, 0xa8, 0x90, 0xfd, 0xbc, 0x69, 0x12, 0x85, 0x39,
- 0xa3, 0x11, 0xdc, 0xb9, 0x3f, 0x83, 0xe1, 0x02, 0xcf, 0x0b, 0x85, 0xe2,
- 0xff, 0x43, 0xc5, 0x09, 0xf2, 0x88, 0x40, 0xe7, 0xd5, 0xb4, 0xb1, 0xaa,
- 0x48, 0x20, 0x2e, 0xe3, 0x6e, 0xa7, 0x8d, 0xf5, 0x71, 0x3e, 0x33, 0x1c,
- 0x47, 0x82, 0x36, 0xf6, 0x55, 0xca, 0xbf, 0x87, 0x36, 0x16, 0xa7, 0x8d,
- 0xc5, 0x69, 0x4f, 0x71, 0xda, 0x98, 0x3c, 0xfb, 0x1b, 0xa7, 0x8d, 0xc5,
- 0x69, 0x63, 0xf1, 0xcc, 0x32, 0x1c, 0x25, 0xd3, 0xd8, 0x39, 0xd6, 0x4c,
- 0x1c, 0x53, 0xec, 0xa8, 0x94, 0xbb, 0xf9, 0x23, 0xe4, 0xec, 0xd7, 0xf1,
- 0x50, 0xd0, 0x46, 0x9f, 0xec, 0x4f, 0x67, 0xc8, 0x79, 0xdc, 0xf8, 0x75,
- 0x56, 0x38, 0x7e, 0x33, 0xf3, 0xd8, 0x93, 0xe4, 0xf9, 0x2a, 0x9e, 0x30,
- 0x25, 0x0f, 0x36, 0x79, 0xce, 0x58, 0x93, 0x12, 0xbe, 0x76, 0x12, 0x77,
- 0x0f, 0x02, 0x37, 0x90, 0x17, 0xd6, 0x92, 0x97, 0x1c, 0x5e, 0xc4, 0xdf,
- 0x07, 0x4f, 0xd0, 0xe6, 0x4f, 0xda, 0x7b, 0xbb, 0x54, 0xb6, 0x75, 0x66,
- 0xb0, 0xde, 0x77, 0x3d, 0x7d, 0xf0, 0x7e, 0xd6, 0x75, 0x1e, 0x94, 0x3a,
- 0x27, 0xd8, 0xb6, 0x1e, 0xfe, 0x35, 0xe7, 0xbf, 0xe3, 0x81, 0x5a, 0xbc,
- 0xb1, 0x5f, 0x0f, 0xbf, 0x43, 0xcc, 0xab, 0x75, 0x58, 0xcb, 0xae, 0x0e,
- 0x05, 0xb6, 0x5d, 0xad, 0xe6, 0xf9, 0x5e, 0xfb, 0x90, 0x13, 0xc7, 0x42,
- 0xcb, 0xe0, 0x59, 0x54, 0xe4, 0x7c, 0xb4, 0xa5, 0x5a, 0xe1, 0x58, 0x7a,
- 0xf8, 0x3c, 0xb9, 0x4a, 0x92, 0xed, 0x1f, 0xcd, 0x3c, 0x4e, 0x0c, 0xf9,
- 0x22, 0x9e, 0x63, 0x7e, 0x3e, 0xf6, 0xa1, 0x97, 0xc9, 0x1d, 0xdd, 0x18,
- 0x27, 0x07, 0x3c, 0x3e, 0x18, 0xfd, 0xa8, 0x93, 0xb8, 0xef, 0x59, 0x54,
- 0x89, 0x4c, 0x5a, 0xb8, 0x62, 0x25, 0x9e, 0x19, 0x34, 0xb4, 0x1b, 0x94,
- 0x3c, 0x2f, 0xcc, 0xef, 0xfd, 0x32, 0x2e, 0x8e, 0x22, 0x30, 0x79, 0x9e,
- 0xdc, 0xf0, 0x9d, 0xb4, 0xc4, 0xb0, 0x93, 0xf4, 0x71, 0x3f, 0xc2, 0x49,
- 0x0d, 0x27, 0xc6, 0x0d, 0x2c, 0x4c, 0x7a, 0xf1, 0xf0, 0x78, 0x10, 0x57,
- 0xd3, 0x77, 0xb3, 0xe4, 0x87, 0x1f, 0x4a, 0x8a, 0x2f, 0xd6, 0x61, 0x62,
- 0xbc, 0x8e, 0x3e, 0x22, 0xbc, 0xfc, 0x67, 0xf0, 0xd4, 0x9e, 0xb5, 0xf7,
- 0x36, 0x8f, 0xa6, 0xf4, 0xfe, 0x18, 0xc7, 0x13, 0xf3, 0xea, 0xc7, 0x62,
- 0xd0, 0xd3, 0xc0, 0x87, 0xdf, 0x4d, 0x7f, 0x52, 0xe2, 0xa3, 0xf8, 0xa3,
- 0x86, 0x09, 0xf2, 0x9d, 0x52, 0x62, 0x6a, 0x79, 0xa4, 0xfe, 0xc2, 0xf7,
- 0x15, 0x3d, 0xf7, 0x94, 0x6a, 0x59, 0xdf, 0x5b, 0xac, 0xc1, 0x77, 0x44,
- 0x23, 0xf7, 0x30, 0xed, 0xe7, 0x62, 0xe4, 0x79, 0xf3, 0xd9, 0xfb, 0x6a,
- 0x31, 0x63, 0x5f, 0x12, 0xff, 0xad, 0x36, 0xfe, 0xd1, 0x59, 0x8c, 0xf3,
- 0xb3, 0x64, 0x7f, 0x76, 0xf2, 0xf4, 0x6c, 0xb9, 0x57, 0x34, 0xa9, 0x36,
- 0x76, 0x1c, 0x83, 0x7e, 0xec, 0x15, 0x45, 0xf7, 0x7d, 0x95, 0xb1, 0xc1,
- 0x45, 0x1b, 0x75, 0x4c, 0x68, 0xf4, 0xdd, 0xc6, 0x13, 0x33, 0x60, 0xc4,
- 0xaf, 0x51, 0x5d, 0x16, 0x6c, 0x79, 0x6e, 0xa8, 0xca, 0xe7, 0x45, 0x82,
- 0x3b, 0x12, 0x17, 0xc8, 0x17, 0x89, 0xc1, 0x9d, 0xf4, 0x97, 0x35, 0x76,
- 0x2c, 0x3a, 0x61, 0xef, 0xfd, 0xde, 0x3a, 0x11, 0xa7, 0x8f, 0x2c, 0x43,
- 0xc5, 0xb0, 0x07, 0x9f, 0xb3, 0xe3, 0xd0, 0x43, 0x56, 0x0d, 0xfd, 0xe5,
- 0xae, 0x43, 0x81, 0xce, 0xeb, 0xe9, 0x2f, 0xf5, 0x4b, 0x25, 0x86, 0x31,
- 0x6e, 0xa7, 0x0c, 0x73, 0x94, 0xd8, 0xf2, 0x50, 0xb3, 0x31, 0xf9, 0x32,
- 0xf2, 0x3e, 0xb3, 0x6b, 0xa0, 0x16, 0x7f, 0xff, 0xc0, 0x71, 0x7b, 0x2d,
- 0xe4, 0x4e, 0x9e, 0x27, 0x07, 0x7c, 0xb6, 0x7f, 0xc4, 0xf8, 0xfb, 0x1e,
- 0xc6, 0xbc, 0x18, 0xfd, 0x68, 0xe7, 0x80, 0xb5, 0xec, 0xf9, 0xc5, 0xf1,
- 0xb5, 0x55, 0x08, 0x32, 0x26, 0xb9, 0xd1, 0x3f, 0xa0, 0x0f, 0x76, 0x30,
- 0x06, 0x9d, 0x5d, 0x6c, 0x52, 0x16, 0x0f, 0x86, 0x06, 0x04, 0x53, 0x4f,
- 0xdd, 0x52, 0x8b, 0xf8, 0xff, 0xd0, 0x38, 0xbe, 0xcf, 0xd9, 0xf7, 0x08,
- 0xeb, 0xb0, 0xe9, 0xc8, 0x52, 0xca, 0xdc, 0x44, 0x1f, 0x64, 0x5e, 0xcd,
- 0x7c, 0x67, 0xc3, 0x7e, 0xf1, 0x0b, 0xb4, 0x48, 0x9e, 0xd6, 0x6d, 0x06,
- 0xcc, 0x57, 0xe9, 0x43, 0x25, 0xe4, 0x3a, 0x0f, 0xa6, 0xec, 0xe7, 0x73,
- 0x72, 0x15, 0x46, 0x18, 0x8b, 0x69, 0xa3, 0x25, 0x86, 0x0f, 0x33, 0xc8,
- 0xeb, 0x16, 0x72, 0x3e, 0xca, 0xb2, 0x1e, 0x80, 0x1c, 0x02, 0xc4, 0x27,
- 0x1c, 0x25, 0x08, 0x1e, 0xf5, 0xf3, 0x98, 0xcf, 0x83, 0x8a, 0xc8, 0xaa,
- 0x98, 0x79, 0x94, 0x75, 0x47, 0x33, 0xb6, 0x2d, 0xfe, 0x3d, 0xe7, 0x3d,
- 0x41, 0x5b, 0xff, 0x04, 0xb1, 0x7e, 0x72, 0x2f, 0xd0, 0x7f, 0x30, 0x6f,
- 0xdb, 0x29, 0xb6, 0xdf, 0x4e, 0xcc, 0xbb, 0x40, 0x9b, 0xed, 0xe3, 0x7c,
- 0x0f, 0x8d, 0x18, 0xc1, 0x46, 0x35, 0xa0, 0x4d, 0x70, 0x9e, 0x7b, 0xc6,
- 0x54, 0x0c, 0x0c, 0x2e, 0xc3, 0x28, 0xf3, 0xa0, 0xde, 0xb4, 0xf8, 0x88,
- 0x94, 0x39, 0x89, 0x6e, 0xfa, 0xc8, 0x2f, 0x17, 0x2b, 0x88, 0x7d, 0x5c,
- 0xf6, 0xbe, 0x3b, 0x99, 0xef, 0x7f, 0x11, 0x9b, 0x12, 0x8f, 0x5b, 0x95,
- 0x86, 0xde, 0x9f, 0x56, 0x99, 0x67, 0xd1, 0x36, 0x7b, 0x98, 0x9f, 0x2c,
- 0x67, 0x7e, 0xd2, 0x5b, 0xb0, 0xcb, 0x33, 0xb4, 0xc3, 0x01, 0xc6, 0xb1,
- 0x97, 0xd3, 0xf9, 0xb8, 0xf7, 0x83, 0x21, 0x3f, 0x16, 0x5e, 0x53, 0x89,
- 0xa7, 0x0f, 0xe6, 0x65, 0xdb, 0x4b, 0x9b, 0x7c, 0x8a, 0x7a, 0xbe, 0x83,
- 0x7a, 0x7d, 0x29, 0x25, 0x18, 0x15, 0xc4, 0x33, 0xe4, 0xd1, 0x5b, 0xc8,
- 0x05, 0xbe, 0x97, 0xca, 0xdb, 0xe4, 0xe7, 0x27, 0xd6, 0x68, 0xf9, 0xf8,
- 0xe0, 0x85, 0xba, 0x4f, 0xf6, 0x00, 0x5a, 0xd6, 0x72, 0x33, 0xd7, 0x49,
- 0x5e, 0xc3, 0xb6, 0x23, 0xe4, 0x46, 0x4e, 0xcc, 0x49, 0x46, 0xb0, 0x22,
- 0x55, 0xdf, 0xd6, 0x20, 0x9b, 0x3d, 0xe6, 0xe4, 0x39, 0xa0, 0x2b, 0x29,
- 0xef, 0x0e, 0xd0, 0x50, 0xc1, 0xdc, 0xe9, 0xaf, 0x0b, 0xef, 0x2b, 0xf8,
- 0xc4, 0x9f, 0xc1, 0x1d, 0xd7, 0x50, 0xa6, 0x14, 0xb9, 0xe3, 0x54, 0xe1,
- 0x7d, 0x05, 0x37, 0xdb, 0xef, 0x2b, 0x70, 0x63, 0xc6, 0x84, 0xd3, 0xf9,
- 0xa9, 0x94, 0x07, 0xb3, 0x27, 0x2e, 0x71, 0x50, 0x77, 0x49, 0xa4, 0x15,
- 0x4f, 0x26, 0x14, 0xcc, 0x32, 0xfe, 0x27, 0xbe, 0x6f, 0xaf, 0x09, 0xd4,
- 0xda, 0x7b, 0xf6, 0x5d, 0x91, 0x28, 0x0e, 0x27, 0xf4, 0xb6, 0xc7, 0x78,
- 0x5e, 0x46, 0x3c, 0xad, 0xda, 0xa7, 0xe0, 0xa9, 0x80, 0x17, 0xa5, 0x47,
- 0x64, 0xaf, 0xbb, 0x65, 0x39, 0x17, 0xaf, 0xb2, 0x76, 0xac, 0x13, 0xfb,
- 0xe6, 0x1c, 0x1e, 0x09, 0x54, 0x09, 0x06, 0x1e, 0x36, 0x65, 0xdd, 0xd2,
- 0x40, 0x5f, 0xa2, 0x96, 0xfc, 0xba, 0xbe, 0xb3, 0x15, 0xf5, 0xe6, 0xcf,
- 0x1c, 0xb5, 0x28, 0x39, 0x72, 0x87, 0x26, 0x6b, 0xf6, 0xdf, 0xe0, 0x9c,
- 0xf5, 0x12, 0xbb, 0x7a, 0x52, 0xf9, 0xf8, 0xd9, 0x9a, 0xb1, 0xaa, 0x45,
- 0x2f, 0xbd, 0xe4, 0x27, 0x6a, 0xf2, 0xa2, 0x5d, 0xa6, 0x22, 0x92, 0x23,
- 0xfe, 0xd4, 0xe1, 0x04, 0xf9, 0x82, 0xc4, 0xd2, 0x0a, 0x1e, 0x95, 0xe4,
- 0x8d, 0x3f, 0x67, 0x2c, 0xbd, 0x27, 0x94, 0x0b, 0xca, 0x9b, 0x2c, 0x6a,
- 0xc8, 0xc5, 0xe9, 0x03, 0x38, 0x12, 0xd2, 0xdb, 0x37, 0x38, 0xa2, 0x4f,
- 0x33, 0x07, 0x0b, 0x2f, 0x63, 0x4e, 0xbe, 0x2a, 0x90, 0xc1, 0x2e, 0xf2,
- 0xc0, 0x9d, 0xcc, 0xc5, 0x3b, 0x68, 0x9b, 0x9d, 0xfb, 0x19, 0xdb, 0x1c,
- 0x97, 0x73, 0x71, 0x2d, 0x14, 0xdf, 0x40, 0x0e, 0xd0, 0xe5, 0x51, 0xc5,
- 0x5e, 0xc5, 0x77, 0x02, 0x1d, 0xaf, 0x12, 0xa3, 0x1b, 0x19, 0x37, 0xc4,
- 0xde, 0xf7, 0xa4, 0xf4, 0x4e, 0x2a, 0xa0, 0xa6, 0x92, 0xb9, 0xe3, 0xbd,
- 0xe3, 0xcd, 0xf4, 0x9b, 0xfc, 0x33, 0x73, 0xce, 0x25, 0x75, 0xcc, 0x39,
- 0xaf, 0x43, 0xef, 0x10, 0xed, 0x9f, 0xbe, 0x74, 0xff, 0x00, 0xc8, 0xcf,
- 0xd4, 0x9d, 0x9c, 0xbf, 0xdc, 0x11, 0x04, 0x2e, 0xb6, 0xa3, 0xb1, 0xad,
- 0xc4, 0x21, 0x32, 0xe8, 0xed, 0x6f, 0x90, 0xa7, 0x75, 0x31, 0x3f, 0xdd,
- 0xc2, 0x5c, 0x3e, 0xc6, 0x5c, 0x3e, 0xc6, 0x7a, 0xa9, 0x21, 0xb9, 0x4f,
- 0x64, 0xb4, 0x9f, 0x61, 0xfe, 0xf3, 0x39, 0xf2, 0x9f, 0xa1, 0x07, 0x44,
- 0xae, 0x59, 0xb8, 0xf7, 0xf0, 0x75, 0x48, 0xd2, 0x9e, 0xee, 0xe1, 0xb5,
- 0x81, 0x07, 0xe6, 0xe3, 0x6e, 0xe6, 0xf1, 0xb1, 0xf1, 0x65, 0x18, 0x64,
- 0x26, 0xba, 0xed, 0xf0, 0x47, 0xd0, 0x43, 0x3e, 0xb5, 0x9c, 0x18, 0xbd,
- 0xe1, 0x60, 0xc6, 0xc6, 0x6c, 0xc1, 0xfc, 0x1f, 0x67, 0x80, 0xd7, 0xc8,
- 0xc9, 0x06, 0x53, 0x27, 0x6c, 0x9e, 0xe6, 0x62, 0x7c, 0x28, 0x25, 0x2e,
- 0x85, 0xf7, 0x1b, 0x5d, 0x2b, 0x55, 0x6b, 0x59, 0xd9, 0xe2, 0x40, 0xff,
- 0x1b, 0xf4, 0xd5, 0x9a, 0x23, 0x2a, 0x6a, 0x87, 0x25, 0x57, 0x27, 0x3f,
- 0x22, 0x46, 0x3f, 0x47, 0x8c, 0xae, 0x3c, 0x94, 0xcf, 0xcb, 0x13, 0xcc,
- 0xbb, 0x6a, 0x8d, 0x7c, 0x6e, 0xbe, 0x67, 0x40, 0xf6, 0xe8, 0xb8, 0xf1,
- 0x1d, 0xda, 0xfe, 0xa9, 0x82, 0xed, 0x9f, 0x2e, 0x60, 0xb0, 0xc5, 0xdc,
- 0xfc, 0x35, 0x1b, 0x7f, 0xf3, 0xb9, 0xf9, 0xc2, 0x61, 0xa3, 0x2b, 0x4c,
- 0x8c, 0xbe, 0xfa, 0x90, 0xf4, 0xaf, 0xa1, 0x96, 0x78, 0x32, 0x93, 0x58,
- 0x52, 0x35, 0x2c, 0xeb, 0x33, 0x81, 0xce, 0x09, 0xd5, 0x67, 0xf7, 0xb1,
- 0x9d, 0xb2, 0xf5, 0xd2, 0x07, 0xbe, 0x9a, 0x30, 0xb4, 0xad, 0x4a, 0xc0,
- 0x5c, 0x4d, 0x7d, 0x1e, 0xc9, 0x5c, 0x87, 0xce, 0xc1, 0x3a, 0x1c, 0x4b,
- 0x4b, 0x7c, 0x91, 0xf6, 0x25, 0x17, 0x77, 0xe2, 0x9d, 0xfd, 0x73, 0xf1,
- 0xce, 0xd8, 0xe5, 0x3c, 0x7c, 0x47, 0x2a, 0x7a, 0x3f, 0xc3, 0xeb, 0x2a,
- 0xc9, 0xc3, 0xbf, 0xc7, 0x3c, 0xfc, 0x0d, 0x45, 0xd6, 0x10, 0x55, 0x7c,
- 0x62, 0x91, 0x83, 0xf1, 0x45, 0xf7, 0x7f, 0xd7, 0x11, 0x97, 0xfb, 0xc8,
- 0xfe, 0x07, 0xf8, 0xff, 0xb3, 0x8c, 0xe7, 0xc3, 0x9c, 0x89, 0x68, 0xad,
- 0x03, 0x4f, 0x2f, 0x8e, 0x47, 0x65, 0x9d, 0xb4, 0x9f, 0x3c, 0x65, 0x0e,
- 0xe3, 0xe1, 0xdf, 0xa7, 0xea, 0xc3, 0x0b, 0x1d, 0x0e, 0x5c, 0x34, 0xf5,
- 0xf6, 0x03, 0xbc, 0xf6, 0x4c, 0x56, 0x7c, 0x31, 0x4c, 0xfc, 0x5a, 0x59,
- 0xf0, 0xc5, 0x5a, 0x94, 0xd3, 0xce, 0xe7, 0xd2, 0x5e, 0x7f, 0x9c, 0xd2,
- 0x07, 0x9f, 0xa1, 0x9d, 0xd6, 0x5e, 0xb2, 0x53, 0x59, 0xa3, 0x95, 0xbc,
- 0xa6, 0x9d, 0x79, 0xcd, 0xf4, 0xe7, 0xa5, 0x8f, 0xa3, 0x2f, 0x7b, 0x1f,
- 0xee, 0xdd, 0xab, 0x77, 0x39, 0x1d, 0x71, 0x4b, 0x33, 0xba, 0x99, 0xa3,
- 0x75, 0x23, 0xb0, 0xc8, 0xe8, 0xb8, 0xa0, 0xe8, 0x9d, 0x3f, 0x54, 0xca,
- 0x99, 0xf3, 0x9d, 0xc1, 0xf6, 0x51, 0x3d, 0x98, 0x51, 0x0c, 0xdc, 0x40,
- 0x8c, 0x7b, 0x78, 0xa4, 0x84, 0x76, 0xb8, 0x1e, 0x47, 0x06, 0xf5, 0x70,
- 0x1c, 0x26, 0x31, 0xb4, 0xde, 0x5f, 0xa6, 0x5c, 0xc0, 0x69, 0xf3, 0x2c,
- 0xb6, 0x67, 0xe7, 0x60, 0xbd, 0x26, 0x7b, 0x9a, 0xd6, 0x63, 0x62, 0xf0,
- 0x02, 0x71, 0xa8, 0x9d, 0xdc, 0x4a, 0xf2, 0x06, 0x0b, 0x7b, 0x42, 0x57,
- 0x63, 0x8b, 0xed, 0xbf, 0xa5, 0xf2, 0x4e, 0x0b, 0xcf, 0x3c, 0xc3, 0x20,
- 0x4e, 0x48, 0x6e, 0xee, 0x9b, 0xb6, 0x3f, 0x57, 0xd6, 0x75, 0x1b, 0xab,
- 0xf2, 0xf7, 0x95, 0xff, 0x58, 0x99, 0x29, 0x1c, 0x1a, 0x91, 0xf5, 0x85,
- 0x19, 0xca, 0xe3, 0x83, 0x0d, 0xbe, 0x1e, 0xc6, 0x8f, 0xfb, 0xcd, 0x1c,
- 0x5e, 0x5f, 0x5c, 0x86, 0x29, 0xaf, 0x82, 0xd0, 0xd5, 0x61, 0xe9, 0x83,
- 0x9f, 0x73, 0x96, 0xff, 0x93, 0xd2, 0xce, 0x82, 0xc2, 0x9a, 0xc3, 0x3b,
- 0x35, 0x8c, 0x55, 0x3c, 0x97, 0xe7, 0x03, 0xe5, 0xbc, 0x78, 0xfd, 0x47,
- 0x56, 0xd4, 0x2b, 0xd7, 0x89, 0xd9, 0xb3, 0xc4, 0x7f, 0x67, 0x28, 0x77,
- 0x12, 0x6f, 0xe7, 0x87, 0x66, 0x28, 0xeb, 0xd3, 0xc5, 0x3a, 0x2f, 0x22,
- 0x3b, 0xf2, 0x22, 0xe7, 0x53, 0x0f, 0x4e, 0xc1, 0x55, 0x78, 0x56, 0x5e,
- 0xf6, 0x81, 0xb9, 0xc8, 0x43, 0x65, 0x2d, 0xfe, 0x1c, 0x86, 0xf6, 0x0b,
- 0x6f, 0xb4, 0xac, 0x40, 0xc3, 0x39, 0x6c, 0x3f, 0x7a, 0x42, 0xe9, 0x48,
- 0xbd, 0x6b, 0xa1, 0x74, 0x46, 0x6c, 0x8e, 0xbd, 0xdf, 0x59, 0xda, 0xe8,
- 0x53, 0xda, 0xb3, 0x81, 0xf0, 0xfd, 0x0c, 0xbe, 0x5a, 0x44, 0x9e, 0x63,
- 0x97, 0xb1, 0x9d, 0xe0, 0x35, 0xc3, 0x7e, 0x66, 0xe8, 0xb8, 0x3d, 0xce,
- 0xf7, 0xeb, 0xe1, 0x9b, 0x56, 0xb4, 0x5d, 0xea, 0x16, 0xe5, 0x9a, 0xcf,
- 0x89, 0x16, 0xd9, 0x8a, 0xff, 0x8f, 0x17, 0x64, 0x2f, 0x25, 0x77, 0xce,
- 0x97, 0xe9, 0xa4, 0xec, 0x25, 0xa1, 0x28, 0x4e, 0x35, 0x4f, 0x97, 0xbf,
- 0x38, 0xd6, 0x83, 0xef, 0x69, 0x2f, 0x5f, 0xf6, 0xe3, 0xb5, 0xb2, 0x4f,
- 0xea, 0x54, 0xf3, 0x24, 0xfe, 0xce, 0x5e, 0xd7, 0x78, 0xd3, 0xde, 0xdf,
- 0xb9, 0xcb, 0x6c, 0x89, 0x96, 0xe1, 0xa3, 0x50, 0xaf, 0x8a, 0x2f, 0x2c,
- 0xb3, 0xf9, 0x76, 0xb4, 0xbd, 0x8c, 0x39, 0xb7, 0xdb, 0x88, 0xde, 0xef,
- 0x46, 0x2e, 0x47, 0x9e, 0xd0, 0x71, 0x51, 0x39, 0xa6, 0xdc, 0x11, 0xd0,
- 0xb7, 0xbd, 0x4d, 0xfe, 0xf3, 0x6c, 0x20, 0xce, 0x39, 0x37, 0x7c, 0x03,
- 0x8a, 0x6e, 0x6e, 0x62, 0x8c, 0x7d, 0x86, 0x39, 0xed, 0xc6, 0x40, 0xbf,
- 0x7d, 0xcf, 0x53, 0x89, 0xac, 0xc1, 0x95, 0xf6, 0xfb, 0x26, 0xda, 0x61,
- 0x64, 0x5e, 0x94, 0x35, 0x38, 0xfe, 0x8e, 0x61, 0xa1, 0x7d, 0x6d, 0x23,
- 0x82, 0xf6, 0xf7, 0xba, 0xc2, 0x3b, 0x29, 0x3a, 0x50, 0x6f, 0x7f, 0x7f,
- 0x1a, 0x0d, 0x99, 0x4b, 0x6b, 0xd5, 0xe8, 0x35, 0x2d, 0xeb, 0x49, 0x53,
- 0x9e, 0x57, 0xbb, 0xb4, 0xb7, 0x7c, 0x8d, 0x83, 0x39, 0x10, 0x21, 0x25,
- 0x96, 0x7f, 0x27, 0xcf, 0xe5, 0xe7, 0xc5, 0x56, 0xbc, 0x67, 0x6f, 0xb9,
- 0xfd, 0xac, 0x93, 0xfd, 0xce, 0xa5, 0x05, 0x4b, 0x9c, 0xf8, 0x4e, 0xa2,
- 0x2a, 0xe6, 0xe1, 0xef, 0xed, 0x4b, 0x4a, 0xb0, 0x25, 0x44, 0x0e, 0x7a,
- 0xd5, 0x19, 0x9c, 0xcf, 0x38, 0x71, 0x26, 0x11, 0x0f, 0x8d, 0xb1, 0xbf,
- 0x53, 0x09, 0x15, 0xa7, 0x47, 0xfa, 0x42, 0x87, 0xec, 0xbe, 0x5f, 0x45,
- 0xef, 0x51, 0xb9, 0x0f, 0xd9, 0x8e, 0x0d, 0x89, 0xf3, 0x8c, 0xbb, 0xd2,
- 0x96, 0xac, 0x05, 0xe8, 0xb9, 0x8d, 0xcc, 0x9f, 0x55, 0x47, 0x10, 0xb7,
- 0x30, 0xde, 0x3d, 0x97, 0xe8, 0x86, 0x6b, 0xb1, 0xde, 0xf5, 0x2d, 0x72,
- 0x96, 0xaa, 0x88, 0x1e, 0x7c, 0x4b, 0xe9, 0x20, 0x37, 0x74, 0x63, 0x32,
- 0x21, 0x7e, 0x21, 0xef, 0xac, 0xf9, 0x34, 0x8e, 0x91, 0x23, 0x3f, 0x9b,
- 0xd0, 0x70, 0xbe, 0xd9, 0x83, 0x0c, 0x39, 0xf3, 0x77, 0x12, 0x6e, 0x7c,
- 0x95, 0x9c, 0xf9, 0x91, 0x11, 0x59, 0xb3, 0x6c, 0x45, 0x4b, 0x42, 0xd6,
- 0xab, 0xc9, 0x03, 0xc7, 0xbc, 0xb4, 0x6d, 0xcb, 0xea, 0x35, 0x67, 0xd3,
- 0x9f, 0xce, 0xb2, 0x4f, 0x59, 0xe7, 0x8c, 0x62, 0x35, 0x79, 0xd0, 0x23,
- 0x63, 0x3e, 0x3c, 0xcf, 0x5c, 0x21, 0xc9, 0x7a, 0xcf, 0x25, 0xfc, 0x18,
- 0xc8, 0xf8, 0xf0, 0x14, 0x73, 0x86, 0x9d, 0x3c, 0x97, 0xf7, 0x1f, 0x95,
- 0x18, 0x41, 0xf2, 0xf2, 0x93, 0xa8, 0x18, 0xb8, 0x02, 0x9b, 0xd7, 0x3e,
- 0x0a, 0x75, 0xe0, 0x04, 0x8f, 0x6b, 0xc9, 0x21, 0xae, 0x45, 0x6a, 0x24,
- 0x82, 0xd4, 0xd8, 0x8b, 0xe8, 0x1f, 0x91, 0x71, 0xc9, 0x7b, 0x6c, 0x64,
- 0x0f, 0x12, 0xb9, 0xe7, 0x80, 0x17, 0xe9, 0x31, 0xe9, 0xa7, 0x96, 0x7d,
- 0xff, 0xb9, 0xed, 0xff, 0xab, 0xb5, 0xf9, 0x13, 0xd2, 0xf6, 0xa3, 0x7f,
- 0xa4, 0x7d, 0xd1, 0x95, 0xac, 0xbd, 0xb4, 0x17, 0xd6, 0x5e, 0xdc, 0x6c,
- 0xd3, 0x03, 0x47, 0x24, 0xb7, 0xb6, 0x12, 0x7a, 0x74, 0xb7, 0x62, 0xb4,
- 0x55, 0x28, 0xe7, 0xb1, 0x3b, 0x2b, 0xef, 0x45, 0x28, 0xc5, 0x53, 0xc4,
- 0x6b, 0x57, 0x48, 0xd7, 0xbe, 0x45, 0xdb, 0x59, 0x4e, 0x8c, 0x7b, 0xd5,
- 0xbc, 0x1a, 0x71, 0x4d, 0xf4, 0x57, 0x8a, 0x17, 0x06, 0xdd, 0xc4, 0xa6,
- 0x08, 0xf2, 0xcf, 0xc8, 0x79, 0xf0, 0x83, 0x84, 0x97, 0xf3, 0xd5, 0x98,
- 0x33, 0x1c, 0x0d, 0xf2, 0x0c, 0x9e, 0x7d, 0xed, 0x54, 0x62, 0x23, 0x0e,
- 0x51, 0xde, 0xe7, 0x12, 0x17, 0x39, 0x3f, 0x9d, 0xd4, 0xbf, 0xe8, 0x3b,
- 0x5e, 0xd0, 0x75, 0x1f, 0x75, 0x5d, 0x87, 0x67, 0x12, 0x5f, 0xc4, 0x23,
- 0x94, 0xff, 0xe1, 0x41, 0x23, 0x3a, 0x5f, 0x39, 0x49, 0xfc, 0x2e, 0xc5,
- 0x69, 0xb6, 0x7d, 0x07, 0x33, 0xf7, 0x29, 0xe9, 0x2b, 0x25, 0xeb, 0xa5,
- 0x0a, 0xde, 0x5a, 0x72, 0x12, 0x13, 0xfc, 0xef, 0x07, 0x83, 0xf2, 0x1c,
- 0x5a, 0x35, 0xfb, 0x10, 0xfd, 0xf8, 0xed, 0xdc, 0xa4, 0x87, 0xbc, 0x6b,
- 0x55, 0xf3, 0x49, 0xec, 0x4a, 0xcb, 0xb5, 0xf5, 0xe8, 0x1f, 0xbc, 0x00,
- 0x47, 0xa8, 0x04, 0x77, 0x78, 0x9b, 0x69, 0xeb, 0x39, 0xec, 0xce, 0x34,
- 0xcf, 0xc8, 0x73, 0xe2, 0xaa, 0x19, 0xf2, 0x4c, 0xd6, 0xa9, 0x44, 0x29,
- 0xbe, 0xc3, 0x3a, 0x9b, 0x89, 0x15, 0xf9, 0x7b, 0x38, 0xe4, 0xfe, 0xc4,
- 0xfa, 0x0c, 0xfb, 0x48, 0xd8, 0x6d, 0xcc, 0x50, 0x0e, 0xd0, 0x0f, 0xab,
- 0x17, 0xcf, 0x50, 0x52, 0x69, 0xc9, 0x35, 0x5e, 0xc4, 0x13, 0x0f, 0xe4,
- 0x75, 0x78, 0xc8, 0xdc, 0x88, 0x74, 0xa6, 0xba, 0xd0, 0xde, 0x4b, 0x85,
- 0x7b, 0x6d, 0xf2, 0x3c, 0x88, 0x51, 0x78, 0x17, 0xc0, 0xe5, 0x7b, 0x6c,
- 0xdf, 0xc8, 0x56, 0x91, 0xcf, 0x97, 0xd3, 0xd6, 0x4a, 0x62, 0x5e, 0xc6,
- 0xf9, 0x8d, 0x8b, 0x34, 0xec, 0x5d, 0xfa, 0xd9, 0x5a, 0x54, 0x69, 0xce,
- 0x5f, 0x35, 0xbf, 0xc8, 0x7e, 0xaa, 0x62, 0x35, 0x91, 0x47, 0xec, 0x7d,
- 0x59, 0xa1, 0xa5, 0x33, 0x19, 0xe7, 0xe4, 0x5e, 0x75, 0x0c, 0xaf, 0x27,
- 0x6a, 0x63, 0xb5, 0x91, 0x6a, 0xe6, 0xf6, 0x17, 0x30, 0x30, 0xea, 0x44,
- 0x15, 0x79, 0x7c, 0x65, 0xb2, 0x16, 0x6e, 0x7b, 0x5d, 0xf1, 0x0a, 0xf2,
- 0xa7, 0xb9, 0xe4, 0x48, 0x75, 0xa8, 0x26, 0x4f, 0xf2, 0x84, 0x2c, 0xeb,
- 0xa7, 0x8b, 0x2d, 0xeb, 0x4a, 0x1e, 0x65, 0x3c, 0xce, 0x85, 0xc4, 0x4f,
- 0xa3, 0x68, 0xb4, 0xfd, 0xd5, 0x40, 0x93, 0xfd, 0xdd, 0x4a, 0x5f, 0xef,
- 0x0a, 0x2d, 0x9c, 0xf8, 0x62, 0xa8, 0x61, 0x62, 0x26, 0xd4, 0xe1, 0x59,
- 0x70, 0xb0, 0xad, 0x8f, 0x2f, 0xb5, 0xd0, 0x6a, 0xca, 0xfb, 0x04, 0x84,
- 0xa7, 0x6d, 0x24, 0x4f, 0xeb, 0x0f, 0x19, 0x13, 0x8f, 0xe2, 0x7a, 0xc6,
- 0x5d, 0xf7, 0xb0, 0x8f, 0xfd, 0x48, 0xce, 0xef, 0xcc, 0xcd, 0x23, 0xff,
- 0xbf, 0x7a, 0xb1, 0x70, 0xb6, 0x0e, 0x79, 0x97, 0x08, 0x3a, 0x26, 0x4e,
- 0xe2, 0x26, 0x96, 0xf1, 0x0c, 0xbf, 0x84, 0x64, 0xf6, 0x47, 0x18, 0xc8,
- 0x4a, 0x3c, 0xc9, 0xe1, 0x06, 0xb6, 0x5d, 0x3e, 0xdc, 0x46, 0xae, 0xba,
- 0x06, 0x9b, 0x27, 0x2c, 0xac, 0x0a, 0x4d, 0x62, 0xd5, 0x04, 0x39, 0xf0,
- 0x44, 0xd1, 0x5f, 0x85, 0xbf, 0xad, 0x81, 0x3c, 0x7f, 0xe6, 0x26, 0xb6,
- 0xc8, 0xda, 0x9e, 0x4a, 0x3f, 0x6c, 0xa1, 0x7d, 0x3f, 0x9e, 0x8a, 0x63,
- 0xc3, 0x84, 0x60, 0xee, 0x7d, 0xe8, 0x9d, 0x90, 0xb5, 0xe2, 0xaf, 0x84,
- 0xe6, 0x4f, 0xfc, 0x08, 0x2d, 0x13, 0xe9, 0xd0, 0x82, 0x89, 0x31, 0xca,
- 0x9d, 0xa0, 0x6c, 0x83, 0xa1, 0xfa, 0x89, 0x91, 0x50, 0x70, 0xe2, 0x40,
- 0x28, 0x30, 0xd1, 0x8e, 0x9d, 0x13, 0xeb, 0xb0, 0x63, 0x62, 0x1b, 0xb6,
- 0x4f, 0x08, 0x6e, 0x4f, 0x61, 0xe5, 0xc4, 0xab, 0x58, 0x31, 0xf1, 0x2c,
- 0x5a, 0x27, 0xce, 0x62, 0xf9, 0xc4, 0x8b, 0x68, 0x9b, 0x78, 0x89, 0x63,
- 0x91, 0xb5, 0x67, 0x59, 0x77, 0x2e, 0xde, 0xe7, 0x9b, 0xbe, 0x97, 0x5a,
- 0xd6, 0x56, 0xe4, 0x59, 0x30, 0x99, 0x43, 0x17, 0xd6, 0x6a, 0xe7, 0xd0,
- 0xb7, 0x5f, 0xde, 0xb5, 0xd6, 0xa8, 0xf5, 0x42, 0xee, 0xe1, 0xbe, 0x28,
- 0xcf, 0x06, 0xd0, 0xc6, 0xa6, 0xef, 0x1b, 0xd6, 0xb5, 0xa9, 0x4b, 0xf7,
- 0x3c, 0xe5, 0x99, 0x2c, 0x89, 0x3d, 0xe7, 0xd1, 0x93, 0xfd, 0x8d, 0x15,
- 0xd5, 0xa4, 0xac, 0x3c, 0x2b, 0x26, 0xf6, 0x70, 0x0e, 0x0f, 0xed, 0x3f,
- 0x4f, 0x0e, 0x35, 0x69, 0xaf, 0x1d, 0xbd, 0xbd, 0x40, 0xde, 0xd3, 0xe3,
- 0x27, 0x36, 0x9d, 0x43, 0xea, 0x28, 0x30, 0x71, 0x50, 0xfc, 0x70, 0x23,
- 0xfd, 0x70, 0x52, 0x7c, 0x32, 0x4e, 0x4c, 0xbe, 0xcd, 0x83, 0xfb, 0xc8,
- 0x93, 0x4a, 0x90, 0x1b, 0x2b, 0xc7, 0xd3, 0x23, 0x71, 0x6b, 0x9e, 0x21,
- 0xef, 0x2e, 0x31, 0x72, 0x57, 0x32, 0xee, 0xbf, 0xc4, 0x6b, 0x93, 0x83,
- 0xf0, 0xfb, 0x8c, 0x80, 0x6f, 0x1e, 0xcf, 0x4f, 0xa7, 0x27, 0xc9, 0x71,
- 0xba, 0x30, 0xc5, 0x6f, 0xc9, 0x89, 0x81, 0x5e, 0xa4, 0xd3, 0xa2, 0xcf,
- 0x76, 0xea, 0x53, 0x70, 0x51, 0xef, 0x6a, 0x25, 0x1e, 0x5a, 0x8a, 0xe0,
- 0xa1, 0x8a, 0x8a, 0x7d, 0xc2, 0x25, 0xec, 0x77, 0x9f, 0x98, 0x03, 0xca,
- 0x8b, 0xf8, 0x0e, 0x73, 0x98, 0xf2, 0x7d, 0xe4, 0x43, 0xc4, 0xca, 0xaa,
- 0x88, 0x62, 0xac, 0x0a, 0x9c, 0xc3, 0xd3, 0x63, 0x4e, 0xb8, 0x93, 0x4e,
- 0x4c, 0x12, 0x27, 0x1d, 0x49, 0xd9, 0x3f, 0xa0, 0x51, 0x16, 0x59, 0xa7,
- 0x3a, 0x8b, 0x9c, 0x7d, 0x7f, 0x4f, 0xee, 0xcf, 0x7c, 0xd7, 0xee, 0xc7,
- 0x49, 0xd9, 0xfb, 0x88, 0xa5, 0x3d, 0xa9, 0xef, 0xa1, 0x35, 0xed, 0xb1,
- 0x9f, 0xf3, 0xdb, 0x9d, 0x7a, 0x15, 0xa9, 0xfd, 0x75, 0xb8, 0xdd, 0x7e,
- 0xd6, 0xcf, 0x84, 0x46, 0xbd, 0xdd, 0x32, 0x6e, 0x22, 0x7a, 0x78, 0x1d,
- 0xd6, 0x1e, 0xfe, 0x24, 0x8f, 0x59, 0xb8, 0xe9, 0x70, 0x27, 0x6e, 0x1c,
- 0x8f, 0xa3, 0x63, 0xbc, 0x8f, 0xc7, 0x7a, 0x7c, 0x6c, 0xa8, 0x1a, 0x99,
- 0x90, 0xc6, 0x1c, 0x7f, 0x3d, 0x73, 0x7c, 0xe1, 0x67, 0x1b, 0xf0, 0x34,
- 0x71, 0x27, 0x18, 0xda, 0x80, 0x49, 0xdb, 0x17, 0x65, 0x8f, 0xe5, 0x06,
- 0x6c, 0x67, 0xfe, 0x3e, 0x8a, 0x0d, 0xe8, 0xe1, 0xb5, 0x21, 0x7b, 0x0e,
- 0x4e, 0x62, 0x19, 0xf3, 0xb3, 0x77, 0xae, 0x39, 0x89, 0x0f, 0x1f, 0x92,
- 0xbe, 0x2f, 0x20, 0xb5, 0x77, 0x23, 0xdb, 0xcc, 0xa1, 0x7d, 0xfc, 0x9f,
- 0x71, 0xe3, 0x10, 0xee, 0xac, 0x46, 0x35, 0x9e, 0x0d, 0x05, 0x3a, 0x06,
- 0x94, 0x7f, 0xb6, 0xdb, 0xde, 0x9e, 0xfa, 0x11, 0x76, 0xa5, 0xce, 0xe3,
- 0xe1, 0xcc, 0x4b, 0xe8, 0x4f, 0x4d, 0x9f, 0x53, 0x99, 0xcb, 0x37, 0x19,
- 0x0f, 0xbe, 0x8f, 0x23, 0x63, 0x53, 0xc4, 0xde, 0x57, 0x78, 0xbc, 0xff,
- 0x7e, 0x7a, 0xfe, 0x39, 0xdc, 0xbc, 0xdd, 0x48, 0x3e, 0x55, 0xe4, 0x6f,
- 0x71, 0xab, 0xda, 0xc8, 0xed, 0x9a, 0x03, 0x7d, 0x5b, 0x58, 0x95, 0xfb,
- 0x81, 0x46, 0xec, 0x05, 0x45, 0x6f, 0xff, 0x96, 0xe2, 0x61, 0xae, 0x21,
- 0xcf, 0x45, 0xea, 0xd1, 0x1b, 0xa8, 0xef, 0xb2, 0x07, 0xbe, 0x0f, 0xe7,
- 0x03, 0x4e, 0x94, 0x26, 0x65, 0x2d, 0x47, 0xde, 0x2b, 0x23, 0xef, 0x30,
- 0xc9, 0xe9, 0xa5, 0xf2, 0xae, 0x89, 0xe4, 0x24, 0x63, 0x7f, 0x6e, 0x61,
- 0x09, 0xe4, 0x39, 0xec, 0xeb, 0xb0, 0x71, 0x30, 0x8a, 0x1e, 0x53, 0x9e,
- 0x31, 0xca, 0x8f, 0x7f, 0x5e, 0xf3, 0xf7, 0xd1, 0xcb, 0xf8, 0xb3, 0x9e,
- 0x98, 0x78, 0xbb, 0x7d, 0x6f, 0xf6, 0xfb, 0xe8, 0x1b, 0xf9, 0x47, 0xb7,
- 0xf0, 0x9d, 0x3e, 0x53, 0x9e, 0xe3, 0xd6, 0xcd, 0xf7, 0xbe, 0xc3, 0x66,
- 0xbe, 0xec, 0x69, 0xa3, 0x4d, 0xe4, 0x16, 0xba, 0xb0, 0xbd, 0x36, 0xff,
- 0x1e, 0x95, 0x0f, 0x7a, 0xe7, 0xd0, 0x5f, 0xda, 0xef, 0x1c, 0x92, 0xfb,
- 0xfa, 0xf2, 0xbe, 0xaa, 0x27, 0x12, 0xf2, 0x1e, 0x09, 0x75, 0x99, 0x0b,
- 0xaa, 0xd7, 0x45, 0x5e, 0xf8, 0xaa, 0x39, 0x13, 0xbd, 0x5e, 0x0b, 0xd7,
- 0x53, 0x96, 0x63, 0x4d, 0x1f, 0x63, 0xe6, 0x12, 0xef, 0x70, 0xd9, 0xef,
- 0x26, 0x39, 0xff, 0xa9, 0x7f, 0xff, 0x6e, 0x92, 0x37, 0x89, 0x93, 0x0a,
- 0x2a, 0x8d, 0x5b, 0xf0, 0x9c, 0x1d, 0x13, 0x14, 0x54, 0x34, 0xc8, 0xba,
- 0xa8, 0x1f, 0xcf, 0x18, 0x8d, 0xfe, 0x1a, 0xb9, 0xdf, 0xa5, 0x9c, 0xb3,
- 0xe2, 0xde, 0x3a, 0xc6, 0x97, 0xff, 0x68, 0x2f, 0xfe, 0xf3, 0xd8, 0xb9,
- 0x37, 0x4c, 0xce, 0xe8, 0x95, 0x67, 0x23, 0x67, 0x14, 0x9f, 0xc5, 0xdc,
- 0x91, 0x92, 0x3d, 0xec, 0x0c, 0x8a, 0xe5, 0x6f, 0xd2, 0xcf, 0xde, 0x94,
- 0x3d, 0x58, 0xe4, 0x3c, 0x7f, 0x85, 0x60, 0xcd, 0x8c, 0xfc, 0x73, 0x52,
- 0xf6, 0x5e, 0x5f, 0x59, 0x0f, 0xd8, 0x5e, 0x78, 0xef, 0xa2, 0x94, 0x95,
- 0x7a, 0x6f, 0xda, 0x6b, 0xc2, 0x2e, 0xe3, 0x37, 0xd6, 0x6b, 0xde, 0x5a,
- 0x96, 0xfd, 0x45, 0xe1, 0xff, 0xf3, 0xe2, 0x33, 0x66, 0x14, 0x72, 0x4d,
- 0xea, 0x88, 0xae, 0x2e, 0xd7, 0xe9, 0x4d, 0x39, 0x88, 0x7b, 0x67, 0xad,
- 0x6e, 0xaf, 0x8c, 0x61, 0xec, 0x7d, 0x75, 0x54, 0xfb, 0x1d, 0x84, 0x79,
- 0xfd, 0x8a, 0x3c, 0xff, 0xbe, 0x4f, 0x59, 0x3f, 0x2e, 0x31, 0x2a, 0x70,
- 0xae, 0x26, 0xbf, 0xae, 0x73, 0x59, 0xc6, 0x47, 0xbc, 0xb2, 0xef, 0xaf,
- 0xd4, 0x3e, 0xb7, 0xfb, 0x35, 0x2f, 0xd7, 0xfb, 0x46, 0x61, 0xbc, 0xb5,
- 0xf6, 0xb3, 0x4a, 0x0f, 0xda, 0xbc, 0xc6, 0x31, 0x6d, 0xdc, 0xcb, 0xbc,
- 0xef, 0xed, 0x67, 0xa4, 0xd0, 0xaf, 0x6a, 0x3f, 0xef, 0x75, 0xb9, 0x0f,
- 0x91, 0xeb, 0xa9, 0x42, 0x1d, 0x3d, 0x1c, 0xb5, 0xfb, 0x57, 0x99, 0xbf,
- 0x15, 0xfb, 0xa4, 0x3f, 0x2d, 0x2e, 0xb6, 0x31, 0x29, 0xf6, 0xd5, 0x5d,
- 0xca, 0xd8, 0x74, 0xae, 0xf9, 0x3e, 0x6c, 0x4f, 0x88, 0x9e, 0xe5, 0x1d,
- 0x95, 0xc4, 0x60, 0x9b, 0x6b, 0xb9, 0xe8, 0x6f, 0x4b, 0x91, 0xd6, 0xe2,
- 0x38, 0xd4, 0x24, 0xcf, 0xe6, 0xb9, 0x68, 0xd3, 0x71, 0x94, 0x91, 0xdb,
- 0x46, 0x79, 0x4d, 0xf6, 0xb4, 0x1c, 0x31, 0xf5, 0xe8, 0x13, 0xf8, 0x12,
- 0x1c, 0x57, 0xd9, 0xeb, 0x5f, 0x6d, 0x69, 0xc8, 0x75, 0x93, 0xb9, 0xc9,
- 0xf4, 0x15, 0x83, 0x32, 0xda, 0x8e, 0xbd, 0x17, 0xdb, 0x94, 0x67, 0xf7,
- 0x06, 0x12, 0xf2, 0x0c, 0x59, 0x63, 0x8c, 0xfc, 0x10, 0xcf, 0x65, 0x64,
- 0xff, 0xc3, 0x6f, 0xad, 0xf8, 0x4c, 0xd9, 0x67, 0x39, 0xbd, 0x4e, 0x09,
- 0x71, 0x29, 0x10, 0xae, 0x52, 0x8a, 0xcf, 0x91, 0x5d, 0xfe, 0xdc, 0x44,
- 0x9b, 0x39, 0x6f, 0x3f, 0xfb, 0x27, 0x67, 0x11, 0xb4, 0xa4, 0xe4, 0x5d,
- 0x8c, 0xfa, 0xe4, 0x2a, 0x34, 0xe6, 0xea, 0x1d, 0xce, 0x02, 0xff, 0x08,
- 0x63, 0x0d, 0xed, 0x66, 0x47, 0x20, 0x6c, 0x3f, 0xe3, 0x26, 0xef, 0xdc,
- 0x78, 0x18, 0x7a, 0xe7, 0x1b, 0x2c, 0xff, 0xb1, 0xec, 0xf3, 0x56, 0xda,
- 0x2b, 0x63, 0x2a, 0xfa, 0xb8, 0xbc, 0xdb, 0x87, 0x7a, 0x8c, 0x88, 0x7f,
- 0x78, 0x50, 0x13, 0x09, 0xd3, 0x0f, 0x25, 0x7e, 0xcb, 0xf3, 0x71, 0xfa,
- 0x01, 0xc9, 0xab, 0x5a, 0xb2, 0xf2, 0xfc, 0xb7, 0xec, 0x9b, 0xd6, 0xfd,
- 0x6b, 0x1d, 0xc1, 0xc2, 0xfe, 0xe5, 0x62, 0xbc, 0xb7, 0xbc, 0x85, 0xbd,
- 0xd5, 0xee, 0x79, 0x8c, 0x6f, 0x96, 0xbd, 0x6f, 0x60, 0xa3, 0x8d, 0x0d,
- 0x9a, 0xa1, 0x1f, 0xfb, 0xa5, 0xa3, 0x1b, 0x8f, 0x2d, 0x32, 0xba, 0x8e,
- 0xab, 0xb9, 0xb4, 0x8f, 0x38, 0x71, 0xad, 0x23, 0x3a, 0xc4, 0x6f, 0xff,
- 0x77, 0x89, 0xcd, 0x37, 0xd9, 0x75, 0xf5, 0xe0, 0x3a, 0xb5, 0xf8, 0x6c,
- 0xb5, 0x3c, 0x73, 0xa1, 0x77, 0x7c, 0x43, 0xe9, 0xc6, 0xd6, 0x90, 0xd1,
- 0xbe, 0x4d, 0xd1, 0xdb, 0xbe, 0xac, 0xe8, 0xfe, 0x90, 0x22, 0xe5, 0xec,
- 0x77, 0xe8, 0x5c, 0x8a, 0x9d, 0x2e, 0xf6, 0x71, 0x38, 0xa1, 0x87, 0x67,
- 0xb0, 0xec, 0x39, 0xd3, 0xf0, 0x5d, 0x60, 0x9b, 0x3f, 0xe4, 0x31, 0x84,
- 0x20, 0x96, 0xdb, 0xed, 0x46, 0x17, 0xba, 0xec, 0xf7, 0xa4, 0x76, 0x30,
- 0x26, 0xc8, 0xfb, 0xb0, 0x62, 0xd0, 0x92, 0x75, 0x34, 0x31, 0xbd, 0xff,
- 0x66, 0x48, 0x4e, 0xdd, 0xc3, 0x80, 0xed, 0x81, 0x37, 0xd2, 0x8d, 0x86,
- 0x45, 0x86, 0x6f, 0x89, 0x6a, 0xd7, 0x0f, 0xca, 0xfb, 0x81, 0x96, 0x73,
- 0x9c, 0x23, 0x90, 0x36, 0x72, 0x96, 0xd6, 0x50, 0x6d, 0xd7, 0x59, 0xa4,
- 0x7e, 0x14, 0xae, 0x0f, 0xfd, 0xca, 0x4a, 0x6b, 0xd0, 0x6a, 0x0d, 0xa9,
- 0x13, 0x1f, 0xd2, 0xf0, 0x1f, 0xd5, 0x13, 0x5c, 0xf9, 0xa5, 0x85, 0x59,
- 0x52, 0x4f, 0xf6, 0xac, 0x7d, 0x1a, 0x77, 0x0d, 0xc8, 0x7b, 0x22, 0xc4,
- 0x1f, 0xf5, 0xe8, 0x17, 0xc8, 0x35, 0xcb, 0xed, 0xf7, 0x6f, 0x49, 0x2c,
- 0x59, 0x4f, 0x3c, 0xeb, 0x86, 0x16, 0xd2, 0xfb, 0xaf, 0x50, 0xe5, 0x1d,
- 0x43, 0x8f, 0xc9, 0xbe, 0x9d, 0x03, 0x0b, 0xd4, 0xfc, 0xfe, 0x9e, 0xd8,
- 0x1f, 0x7d, 0x5f, 0x11, 0xfb, 0x2a, 0x97, 0xf7, 0x15, 0xd5, 0xd9, 0xcf,
- 0xa7, 0xac, 0x4f, 0x38, 0x0a, 0xfb, 0x15, 0x2f, 0xbf, 0xc7, 0x73, 0x23,
- 0x79, 0xfd, 0x26, 0x79, 0x67, 0x1f, 0xc7, 0xba, 0x39, 0x21, 0x4b, 0x5a,
- 0xff, 0x0f, 0xdd, 0x0f, 0x6b, 0xf2, 0xd0, 0x56, 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_CP_b06FwData[(0x84/4) + 1] = {
- 0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006,
- 0x00000005, 0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000003,
- 0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000002,
- 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
- 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
- 0x00000001, 0x00000001, 0x00000001, 0x00000000 };
-static const u32 bnx2_CP_b06FwRodata[(0x134/4) + 1] = {
- 0x08000f30, 0x08000d88, 0x08000fc4, 0x0800106c, 0x08000f58, 0x08000f98,
- 0x080011a4, 0x08000da4, 0x080011c8, 0x08000df4, 0x08001498, 0x08001440,
- 0x08000da4, 0x08000da4, 0x08000da4, 0x08001254, 0x08001254, 0x08000da4,
- 0x08000da4, 0x080016e0, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
- 0x080013d4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
- 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
- 0x08000da4, 0x08000da4, 0x08000da4, 0x08000fb8, 0x08000da4, 0x08000da4,
- 0x08001690, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
- 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
- 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
- 0x080015bc, 0x08000da4, 0x08000da4, 0x08001348, 0x080012b8, 0x08002e50,
- 0x08002e58, 0x08002e20, 0x08002e2c, 0x08002e38, 0x08002e44, 0x0800532c,
- 0x080052ec, 0x080052b8, 0x0800528c, 0x08005268, 0x08005224, 0x00000000
-};
-
-static struct fw_info bnx2_cp_fw_06 = {
- /* Firmware version: 4.6.16 */
- .ver_major = 0x4,
- .ver_minor = 0x6,
- .ver_fix = 0x10,
-
- .start_addr = 0x08000080,
-
- .text_addr = 0x08000000,
- .text_len = 0x56cc,
- .text_index = 0x0,
- .gz_text = bnx2_CP_b06FwText,
- .gz_text_len = sizeof(bnx2_CP_b06FwText),
-
- .data_addr = 0x08005820,
- .data_len = 0x84,
- .data_index = 0x0,
- .data = bnx2_CP_b06FwData,
-
- .sbss_addr = 0x080058a4,
- .sbss_len = 0xf1,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08005998,
- .bss_len = 0x5d8,
- .bss_index = 0x0,
-
- .rodata_addr = 0x080056cc,
- .rodata_len = 0x134,
- .rodata_index = 0x0,
- .rodata = bnx2_CP_b06FwRodata,
-};
-
/* Initialized Values the Command Processor. */
static const struct cpu_reg cpu_reg_cp = {
.mode = BNX2_CP_CPU_MODE,
@@ -2184,771 +39,6 @@ static const struct cpu_reg cpu_reg_cp = {
.mips_view_base = 0x8000000,
};
-static u8 bnx2_RXP_b06FwText[] = {
- 0xec, 0x5b, 0x5d, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0x33, 0x3b, 0x24, 0x57,
- 0x14, 0x45, 0x8e, 0xa8, 0x15, 0xb5, 0xb2, 0x99, 0x64, 0x97, 0x1c, 0x89,
- 0x1b, 0x93, 0x50, 0x86, 0xec, 0x5a, 0x66, 0x92, 0x45, 0xbc, 0x59, 0x52,
- 0x16, 0x53, 0x08, 0xf0, 0xda, 0x56, 0x5c, 0xa3, 0x31, 0x90, 0xc5, 0x92,
- 0x76, 0xd2, 0x37, 0xc9, 0xa9, 0x5d, 0x21, 0xb1, 0xab, 0xf5, 0x92, 0x91,
- 0x15, 0x75, 0xc5, 0x61, 0x24, 0x26, 0x72, 0x1b, 0xb7, 0xa0, 0xf9, 0x23,
- 0xaa, 0xc1, 0x4a, 0xe3, 0x9f, 0xd8, 0xf5, 0x43, 0x64, 0x31, 0xb2, 0xad,
- 0xfa, 0xa5, 0x80, 0xd3, 0x1f, 0xc0, 0x28, 0x8c, 0x56, 0x90, 0x6b, 0xd9,
- 0x68, 0x81, 0x42, 0x6d, 0x51, 0xd4, 0x6d, 0x64, 0x4d, 0xbf, 0xef, 0xce,
- 0x0c, 0xb9, 0x22, 0x94, 0xc6, 0x2f, 0x7d, 0x9b, 0x0b, 0x2c, 0xee, 0xdc,
- 0x3b, 0xe7, 0x9e, 0x7b, 0xce, 0xb9, 0xe7, 0xf7, 0x0e, 0xf9, 0x44, 0x9b,
- 0xb4, 0x4a, 0xd0, 0x36, 0xe1, 0x97, 0x3d, 0x70, 0xe8, 0xb1, 0xc1, 0x5d,
- 0xbb, 0x77, 0xe1, 0x71, 0x77, 0xcc, 0x6c, 0x36, 0x38, 0xaf, 0x49, 0xd4,
- 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2,
- 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16,
- 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5,
- 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8,
- 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45,
- 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xfe, 0x3f, 0x5a, 0x4c, 0xc4, 0x64,
- 0xbf, 0x29, 0xf8, 0x49, 0x5c, 0xcf, 0xa5, 0x0e, 0x16, 0x2c, 0x89, 0xc7,
- 0x72, 0x6f, 0x3f, 0x3e, 0x6e, 0x89, 0xe4, 0xeb, 0xfd, 0xa9, 0x11, 0xf9,
- 0xc4, 0xab, 0x24, 0x0c, 0xe1, 0xfc, 0x67, 0x72, 0xd7, 0x0f, 0x9f, 0xbf,
- 0x2b, 0x7d, 0x6d, 0x2e, 0x26, 0x71, 0x33, 0xf7, 0xee, 0xa0, 0xb9, 0x53,
- 0xe2, 0xdd, 0x58, 0xf3, 0x5c, 0xdf, 0xc4, 0x66, 0x69, 0x0f, 0x71, 0x79,
- 0xde, 0x92, 0xed, 0xc9, 0x25, 0xbb, 0xa2, 0x8d, 0xf4, 0xbd, 0xa6, 0x15,
- 0x9c, 0x1b, 0x5e, 0xde, 0xd0, 0x45, 0x07, 0xbe, 0x89, 0x7a, 0x5c, 0x1e,
- 0x59, 0x6c, 0x95, 0x47, 0xe7, 0x36, 0x4a, 0x79, 0x4e, 0x4c, 0x3d, 0x97,
- 0x94, 0x6f, 0x61, 0xee, 0x72, 0x0c, 0x70, 0xae, 0x94, 0x62, 0xb9, 0x8f,
- 0xef, 0x2d, 0xd7, 0x08, 0x2f, 0xba, 0x9e, 0x5b, 0xb9, 0x77, 0xa2, 0xfe,
- 0xe6, 0xbd, 0xe5, 0x3a, 0xe1, 0x08, 0x83, 0x77, 0xf5, 0x8f, 0xbc, 0xf3,
- 0x7d, 0x09, 0xb9, 0xe0, 0x9a, 0xf2, 0x82, 0xfb, 0x32, 0xf6, 0x4c, 0x57,
- 0x2a, 0xd2, 0x24, 0xe5, 0x93, 0x37, 0xbc, 0x98, 0x95, 0x4e, 0x61, 0x13,
- 0x73, 0x44, 0xf0, 0xde, 0xc1, 0x7b, 0x07, 0xf3, 0x0b, 0x3f, 0xdf, 0x2c,
- 0xad, 0x49, 0x39, 0xdf, 0xc7, 0x75, 0x5c, 0xc3, 0xb5, 0x8b, 0xed, 0xfe,
- 0x3a, 0xc1, 0xba, 0xa2, 0xc4, 0x2c, 0x4f, 0x0a, 0xb6, 0x21, 0x23, 0x09,
- 0xd1, 0x74, 0xab, 0x02, 0x3a, 0x7e, 0xd1, 0x26, 0xad, 0xc4, 0x55, 0xd1,
- 0xf2, 0x2e, 0xfb, 0x10, 0xdf, 0x53, 0x1d, 0x3e, 0xae, 0x67, 0x81, 0xab,
- 0x24, 0xaf, 0xbb, 0x0f, 0xcb, 0x5f, 0xb8, 0x63, 0xf2, 0x92, 0x3b, 0x01,
- 0x9c, 0x0f, 0xc9, 0xab, 0xee, 0x7e, 0x79, 0xc5, 0x2d, 0xca, 0xcf, 0xdc,
- 0x7d, 0xf2, 0xb2, 0x3b, 0x2a, 0x2f, 0xba, 0x79, 0xec, 0x97, 0xd1, 0x8a,
- 0xce, 0xdd, 0x32, 0x7e, 0x92, 0x34, 0xa6, 0xaf, 0x41, 0x36, 0xf2, 0x98,
- 0xdd, 0x67, 0xea, 0xa2, 0x61, 0xcf, 0xf4, 0x6b, 0x22, 0x8f, 0x4a, 0x3e,
- 0x31, 0x2c, 0x73, 0x6e, 0x97, 0x56, 0x38, 0xd9, 0xa9, 0x8d, 0x9c, 0x24,
- 0x2d, 0x9e, 0x8c, 0xdb, 0xe9, 0x54, 0x21, 0x96, 0x36, 0x47, 0x62, 0x92,
- 0xdf, 0x03, 0xb9, 0x55, 0x9d, 0xa4, 0xe4, 0x4d, 0xc9, 0x1f, 0xb5, 0x0c,
- 0xc8, 0x53, 0x93, 0x58, 0x8e, 0x7c, 0x6e, 0xe1, 0x1c, 0x5a, 0x9b, 0x2c,
- 0xd4, 0x6c, 0x29, 0x3b, 0xf3, 0x5a, 0x39, 0xa1, 0x51, 0x04, 0x18, 0x0f,
- 0x60, 0xfc, 0x67, 0xc1, 0xf8, 0x4b, 0x52, 0x3e, 0x25, 0xf9, 0xc9, 0x59,
- 0xcf, 0x2b, 0xd8, 0x7f, 0x1c, 0xcc, 0x0d, 0x63, 0x4e, 0x97, 0xd8, 0x8f,
- 0x38, 0x37, 0x1b, 0xcc, 0x51, 0x1e, 0x9e, 0x8c, 0xd8, 0x14, 0x23, 0xe8,
- 0x35, 0x8b, 0xe8, 0x9b, 0xd1, 0x73, 0x8f, 0x8d, 0x9b, 0xfc, 0xff, 0x03,
- 0xe2, 0xf9, 0x26, 0xf0, 0x6c, 0x83, 0x66, 0x89, 0x7f, 0x36, 0x77, 0xf4,
- 0xe0, 0x3f, 0xf4, 0xad, 0x8d, 0xf5, 0xdc, 0x7b, 0x52, 0xa8, 0x69, 0x4a,
- 0x57, 0x34, 0x3c, 0xf7, 0xd4, 0x9f, 0xea, 0xf4, 0xf5, 0xc2, 0x69, 0x97,
- 0x56, 0xc8, 0xc9, 0x21, 0xfd, 0x29, 0xd0, 0xbf, 0x49, 0xb6, 0xfc, 0x90,
- 0x3c, 0xf4, 0xa7, 0x74, 0xc9, 0xa7, 0x0d, 0xb1, 0x65, 0xd1, 0x35, 0xb4,
- 0x11, 0x27, 0x2f, 0x7a, 0xce, 0x4a, 0x96, 0x45, 0x97, 0x52, 0x22, 0x2f,
- 0xcf, 0x64, 0xd3, 0xc3, 0x15, 0x49, 0x49, 0x79, 0xc8, 0x96, 0x65, 0x17,
- 0x90, 0x89, 0x8a, 0x5c, 0xcd, 0xa6, 0xed, 0xcb, 0xb2, 0x51, 0x56, 0x4c,
- 0x5b, 0x4e, 0xbb, 0x71, 0x79, 0xeb, 0xe4, 0x3e, 0xf9, 0x96, 0xc3, 0x73,
- 0x92, 0xfe, 0x26, 0x79, 0x5a, 0x96, 0xb2, 0x4f, 0x5f, 0x5b, 0xb2, 0x8f,
- 0xb7, 0x49, 0x3b, 0x75, 0xb0, 0xd6, 0xee, 0xd3, 0xfd, 0x15, 0xf0, 0x96,
- 0x87, 0x6c, 0xdb, 0x21, 0x33, 0x43, 0xf1, 0x55, 0x78, 0xb0, 0x13, 0x3d,
- 0xd7, 0xfd, 0xfd, 0x16, 0xe8, 0x83, 0x2d, 0x5a, 0x48, 0x63, 0x93, 0x14,
- 0xba, 0xb8, 0xe6, 0x25, 0xe0, 0xc0, 0xfb, 0x55, 0xda, 0x6f, 0xd3, 0x0a,
- 0xa7, 0xda, 0xc5, 0xf8, 0xd1, 0x9d, 0x38, 0x4f, 0x43, 0x1e, 0x19, 0xf2,
- 0xbc, 0xaf, 0xdb, 0x46, 0x6a, 0x42, 0x72, 0xa4, 0x5d, 0x36, 0x1f, 0xdf,
- 0x2a, 0x73, 0x66, 0x5c, 0x12, 0xc7, 0xc3, 0xbd, 0x5a, 0x82, 0xf3, 0xf9,
- 0x32, 0xf1, 0xa7, 0x52, 0xfa, 0xa6, 0x60, 0x1c, 0xd2, 0x34, 0x8a, 0x33,
- 0xea, 0x35, 0x7b, 0xf4, 0x21, 0x2d, 0xaf, 0xfe, 0x8f, 0x6a, 0x2c, 0x18,
- 0xef, 0xd2, 0xbe, 0x6a, 0x74, 0x89, 0x61, 0xcd, 0x43, 0xae, 0x86, 0x5c,
- 0x74, 0xc2, 0xf9, 0xb8, 0xf8, 0x70, 0x94, 0xb3, 0x0c, 0xae, 0xc9, 0x59,
- 0x06, 0x7b, 0xea, 0x4f, 0x07, 0x38, 0xf3, 0x01, 0xec, 0x06, 0xc9, 0x27,
- 0xdb, 0x78, 0xa6, 0x01, 0xec, 0x75, 0xf9, 0xce, 0x50, 0xfa, 0x0c, 0xff,
- 0x57, 0x6b, 0x6d, 0x0d, 0xdf, 0xdb, 0x32, 0xef, 0xaa, 0x35, 0xc9, 0xfb,
- 0x70, 0xb6, 0xa5, 0xe4, 0x1d, 0xe6, 0x82, 0x1e, 0xd3, 0xf2, 0x09, 0xe2,
- 0x6a, 0x96, 0xc7, 0x13, 0xbd, 0x18, 0x6b, 0x52, 0xfe, 0x12, 0xf5, 0xf5,
- 0x13, 0xf1, 0xe7, 0x39, 0x97, 0x3e, 0xda, 0xab, 0x1f, 0x03, 0x7d, 0x94,
- 0x41, 0x3a, 0x29, 0x10, 0x7e, 0x79, 0xe8, 0x36, 0xf0, 0x67, 0xa2, 0x0f,
- 0xf9, 0xdf, 0x2c, 0xf9, 0x22, 0xe9, 0x57, 0x76, 0x0a, 0x39, 0x27, 0xb1,
- 0xdf, 0xdd, 0xb0, 0xc9, 0xf5, 0xf6, 0x0a, 0x1b, 0x6d, 0xa7, 0xad, 0x7e,
- 0x11, 0x3c, 0xa7, 0x33, 0x22, 0x16, 0xe4, 0x95, 0x94, 0x66, 0x6b, 0x1a,
- 0x3c, 0x51, 0x2f, 0xb7, 0x61, 0x7e, 0xc3, 0xc7, 0x79, 0xc5, 0x7a, 0x38,
- 0xf7, 0x41, 0x20, 0xcb, 0x7d, 0x32, 0xe1, 0xec, 0x57, 0x3c, 0x57, 0xf5,
- 0xcb, 0x92, 0xef, 0xee, 0x35, 0xa7, 0x40, 0x6f, 0xc1, 0x48, 0xcf, 0x55,
- 0x24, 0x29, 0x0b, 0xf0, 0x13, 0x2f, 0xc2, 0xe6, 0x5f, 0x71, 0x53, 0xb0,
- 0xaf, 0xbc, 0x3c, 0xea, 0xe4, 0x64, 0xe2, 0x14, 0x6d, 0x2c, 0x9d, 0x29,
- 0xc4, 0x72, 0x32, 0xef, 0xa4, 0x33, 0x0b, 0xd0, 0xbd, 0x05, 0xc7, 0xf3,
- 0xa6, 0xec, 0xfe, 0xd4, 0x28, 0x30, 0x5e, 0x74, 0x76, 0x24, 0x27, 0x20,
- 0xc8, 0x25, 0x2b, 0x25, 0x4b, 0x6e, 0x06, 0x3a, 0x86, 0xf7, 0xae, 0x85,
- 0x7e, 0x00, 0x3a, 0x9e, 0x85, 0x7d, 0x93, 0x16, 0x53, 0x16, 0xfb, 0x20,
- 0x3b, 0x47, 0x07, 0x2e, 0x4d, 0xf2, 0xfb, 0x6f, 0x40, 0xbe, 0x21, 0xdf,
- 0x77, 0x81, 0xb6, 0x04, 0x70, 0x92, 0xae, 0xdb, 0xa4, 0xda, 0x05, 0xf9,
- 0x0d, 0x25, 0x94, 0x5d, 0x16, 0x3a, 0xb7, 0x4a, 0xe1, 0x8e, 0x66, 0xbc,
- 0xef, 0xc2, 0x98, 0xf2, 0x6f, 0xc1, 0x1c, 0xdf, 0xff, 0x4b, 0x60, 0x5f,
- 0x4d, 0xeb, 0xc6, 0x57, 0xd1, 0xb7, 0xcb, 0x36, 0x8b, 0xbd, 0x89, 0xfe,
- 0x9f, 0xd1, 0x77, 0xa2, 0xef, 0xc5, 0x5e, 0xe7, 0x21, 0x43, 0xca, 0x0f,
- 0xcf, 0x0b, 0x5c, 0xb3, 0x3d, 0xd8, 0x97, 0x78, 0xdb, 0x81, 0x67, 0x53,
- 0xb0, 0x57, 0x3b, 0xc6, 0xad, 0xc1, 0x5e, 0x16, 0x68, 0x8e, 0x29, 0x19,
- 0x16, 0xac, 0xf8, 0xba, 0xb1, 0x86, 0x3e, 0x0e, 0xdc, 0x84, 0xd7, 0xe5,
- 0x4a, 0x57, 0x17, 0x9e, 0xb9, 0x27, 0x61, 0xf8, 0x1e, 0xbd, 0x4b, 0xfc,
- 0x1c, 0xe7, 0xe5, 0x09, 0x07, 0xfe, 0x89, 0xfa, 0xe6, 0x52, 0x8e, 0xbb,
- 0x65, 0x02, 0xbc, 0x8f, 0x3b, 0xe9, 0x99, 0xaa, 0xee, 0x79, 0x7a, 0xd6,
- 0x30, 0xab, 0x92, 0x86, 0x1d, 0x8f, 0xc9, 0x38, 0xe4, 0x77, 0xda, 0x89,
- 0xcb, 0x45, 0x65, 0x7b, 0xe4, 0xe9, 0x21, 0xc8, 0x05, 0xf1, 0xa4, 0x8b,
- 0xf6, 0x49, 0x9b, 0x82, 0xfc, 0x8a, 0xa6, 0x5c, 0xca, 0xd2, 0x96, 0xb3,
- 0xb2, 0xbc, 0x6a, 0xcb, 0x15, 0xd8, 0x32, 0xed, 0xb8, 0x02, 0x7b, 0xf6,
- 0xf5, 0xfa, 0x41, 0xd9, 0x06, 0xbd, 0x4e, 0x62, 0x3f, 0xea, 0xf5, 0xb3,
- 0xd0, 0x6b, 0xc8, 0xd4, 0x86, 0xae, 0x9b, 0xd4, 0x89, 0x6f, 0xc3, 0xa7,
- 0x81, 0xdf, 0x44, 0xf0, 0xbc, 0xfc, 0x5d, 0x29, 0x9c, 0x6a, 0x05, 0xdd,
- 0x7b, 0xdb, 0x29, 0xb3, 0xf2, 0x32, 0x7f, 0xa1, 0x2e, 0x3e, 0x05, 0xf9,
- 0xc1, 0x8f, 0x2a, 0x1d, 0x04, 0x6f, 0xd9, 0x3d, 0x80, 0x19, 0xc6, 0x39,
- 0xb7, 0x02, 0x3f, 0x69, 0xbc, 0x15, 0x1c, 0xdf, 0x83, 0xee, 0x2c, 0xf5,
- 0x15, 0xf3, 0x0b, 0xe1, 0x79, 0xb7, 0xa9, 0x3d, 0xcb, 0x43, 0xad, 0x01,
- 0x7f, 0x94, 0x03, 0xf5, 0x3e, 0x09, 0xbd, 0xd5, 0x64, 0x5c, 0xe9, 0x6e,
- 0x5e, 0xc9, 0x61, 0xde, 0xa1, 0xfe, 0x02, 0x87, 0x4d, 0x19, 0x98, 0x72,
- 0xbf, 0x82, 0x4f, 0xae, 0xd9, 0x77, 0x37, 0x69, 0xe7, 0x78, 0x83, 0xf4,
- 0x28, 0x1f, 0xd4, 0x1d, 0xe8, 0x76, 0x13, 0x6c, 0x9f, 0xef, 0x1e, 0x92,
- 0xc7, 0xdc, 0x61, 0x9c, 0x43, 0x52, 0x0e, 0xba, 0xdd, 0xf2, 0xfb, 0xee,
- 0x46, 0xb9, 0xdc, 0x09, 0xba, 0x56, 0x6d, 0xec, 0x6e, 0xf9, 0x03, 0xc6,
- 0x3c, 0xf5, 0x0c, 0x3f, 0xa9, 0xdf, 0x05, 0x1a, 0x68, 0x4f, 0xb4, 0x2b,
- 0xc2, 0xc5, 0xa4, 0xa4, 0xf6, 0xfc, 0x89, 0xef, 0xdb, 0x80, 0x77, 0xae,
- 0x93, 0xf6, 0x4b, 0xda, 0x8c, 0xc0, 0x66, 0xd3, 0x66, 0x49, 0xc8, 0x33,
- 0x69, 0xe5, 0x73, 0xa3, 0x2c, 0xd8, 0x37, 0xca, 0x20, 0xc4, 0x13, 0xda,
- 0xe5, 0xa8, 0xe4, 0x5d, 0xf6, 0xf4, 0x97, 0x88, 0x91, 0x0e, 0x62, 0xa4,
- 0x83, 0xd8, 0x08, 0x5b, 0x78, 0xc5, 0x41, 0x6c, 0x74, 0x10, 0x1b, 0xe1,
- 0xcf, 0x5e, 0x72, 0x10, 0x1f, 0xa1, 0x43, 0x2f, 0x38, 0x8c, 0xeb, 0xdf,
- 0x46, 0x4c, 0x35, 0xe4, 0x99, 0x9a, 0xc8, 0x91, 0x5a, 0x1a, 0xd4, 0xa5,
- 0x87, 0x3f, 0x90, 0xfe, 0xcc, 0x07, 0x92, 0xb6, 0x2f, 0xe2, 0xf7, 0x96,
- 0xe0, 0x9d, 0xca, 0x11, 0xf0, 0xbe, 0x1e, 0xe6, 0x13, 0x38, 0x7f, 0x8b,
- 0x39, 0x83, 0x3f, 0x0f, 0x97, 0x88, 0xb8, 0x41, 0x9b, 0x1e, 0x93, 0xf9,
- 0x59, 0xda, 0xf2, 0xed, 0x38, 0x8b, 0x4e, 0x99, 0xb2, 0xfc, 0x71, 0xc1,
- 0xbe, 0xc3, 0x1c, 0xa5, 0xee, 0x98, 0x31, 0xd0, 0x76, 0x1b, 0x7e, 0x29,
- 0xc4, 0xda, 0x3f, 0xd2, 0x0a, 0x0b, 0x71, 0xc4, 0x56, 0xc6, 0x5b, 0xc9,
- 0xfb, 0x7a, 0x74, 0xc3, 0x1b, 0x5f, 0x5d, 0xd3, 0x0f, 0xfd, 0x86, 0xdc,
- 0x13, 0x09, 0xc0, 0xcc, 0x6a, 0x23, 0xcb, 0x6f, 0xfb, 0x76, 0x92, 0xe5,
- 0xf8, 0x46, 0x60, 0x7b, 0xdc, 0x1f, 0x63, 0x97, 0x78, 0xf9, 0x4c, 0x9c,
- 0x97, 0x91, 0x1f, 0x24, 0x91, 0x17, 0x24, 0xe0, 0x7b, 0x98, 0x73, 0x74,
- 0x23, 0x3f, 0xf0, 0xbc, 0x17, 0x6d, 0xcf, 0x7b, 0x07, 0xbf, 0x7f, 0xb7,
- 0x57, 0x79, 0x40, 0xab, 0x68, 0xa3, 0x6e, 0x4a, 0x46, 0xdd, 0x9f, 0xb6,
- 0xfb, 0x72, 0x8c, 0xcb, 0xa4, 0x93, 0x90, 0x29, 0xa7, 0xa6, 0xdd, 0xb7,
- 0x3c, 0xad, 0x15, 0x97, 0x67, 0xb0, 0xaf, 0x81, 0x39, 0xa9, 0x54, 0xed,
- 0x33, 0xda, 0x88, 0x7b, 0x54, 0xbb, 0x7f, 0xb9, 0x5d, 0xd9, 0x79, 0xd5,
- 0x61, 0xce, 0x70, 0x5d, 0xe5, 0x2e, 0x05, 0x2b, 0x6d, 0xfe, 0x2e, 0x14,
- 0xaf, 0x50, 0x23, 0xdd, 0xcd, 0x01, 0xcd, 0xb0, 0xc3, 0x9c, 0x77, 0xb8,
- 0x90, 0xb5, 0x60, 0x8b, 0xa4, 0x51, 0xcd, 0x5d, 0xf0, 0xe9, 0x3e, 0xad,
- 0x15, 0x96, 0xdb, 0xb4, 0x91, 0x53, 0x8c, 0xc7, 0xd2, 0x1d, 0x13, 0xae,
- 0xdb, 0x01, 0x7b, 0xad, 0x63, 0x0f, 0xe6, 0x5b, 0x94, 0x2d, 0xe8, 0x86,
- 0x0e, 0xbf, 0x04, 0x7a, 0x5e, 0x54, 0xf9, 0x0f, 0xf9, 0x4b, 0xe1, 0xac,
- 0x42, 0xfe, 0x3c, 0xef, 0xaf, 0xed, 0x90, 0xfe, 0x74, 0x2a, 0xaf, 0x87,
- 0xfc, 0x7a, 0xde, 0xbf, 0xd9, 0xe4, 0x99, 0x3c, 0x79, 0xde, 0x0b, 0x76,
- 0x02, 0xf4, 0x7b, 0x17, 0x74, 0xab, 0x06, 0x7e, 0x18, 0xdb, 0x29, 0xf3,
- 0x69, 0xf0, 0x71, 0x14, 0x3c, 0x9e, 0x06, 0x7f, 0x33, 0xa0, 0xe5, 0x37,
- 0xed, 0xd9, 0x98, 0x4b, 0x4a, 0x8a, 0xb2, 0x2e, 0x2f, 0x32, 0xa7, 0x64,
- 0x1e, 0x69, 0x4a, 0x69, 0x31, 0x5c, 0x1f, 0xea, 0xc3, 0x01, 0xd9, 0xeb,
- 0x74, 0x42, 0x3e, 0x94, 0xe7, 0x35, 0xd0, 0x4b, 0x9f, 0x5f, 0xcd, 0xe8,
- 0x08, 0x80, 0x65, 0x1b, 0xb1, 0x5e, 0x46, 0x94, 0x2e, 0x2c, 0x5a, 0x92,
- 0x2f, 0xdb, 0x26, 0xed, 0x36, 0x55, 0xb6, 0x2b, 0xc8, 0x0c, 0x7c, 0x39,
- 0x8e, 0xd4, 0x0c, 0xbc, 0xe3, 0x58, 0x60, 0xf3, 0xa1, 0x6c, 0x0d, 0xd8,
- 0x5d, 0x28, 0xf3, 0x70, 0xee, 0xc1, 0x0e, 0xfa, 0xcc, 0x79, 0xf7, 0x0b,
- 0xc0, 0x41, 0xbc, 0xbf, 0x09, 0x47, 0x1c, 0x31, 0x84, 0x78, 0xe2, 0x72,
- 0xc6, 0x21, 0x3c, 0xf3, 0x8b, 0xb8, 0xb4, 0x22, 0x26, 0x6f, 0xc8, 0x89,
- 0xf6, 0xf9, 0x1d, 0x69, 0x73, 0x31, 0x16, 0x93, 0x63, 0x09, 0xb9, 0xc3,
- 0x60, 0x00, 0xd8, 0xec, 0x67, 0xea, 0x85, 0x19, 0x0d, 0xba, 0xdc, 0x26,
- 0x93, 0x03, 0x69, 0x73, 0x1e, 0x7b, 0xe8, 0xd8, 0xe3, 0x6b, 0x9c, 0xaf,
- 0xfd, 0x87, 0x57, 0x4a, 0xec, 0x84, 0x9d, 0x48, 0xdc, 0xc8, 0x19, 0x83,
- 0x53, 0xb5, 0x03, 0xc2, 0xfc, 0x6a, 0x72, 0x60, 0x03, 0xec, 0xbc, 0x77,
- 0x78, 0xaf, 0x30, 0x97, 0x8f, 0x0f, 0x8e, 0x5b, 0x3e, 0x5d, 0x23, 0xb0,
- 0xeb, 0x49, 0xe4, 0x79, 0x7b, 0xeb, 0xcc, 0x01, 0x8c, 0xc1, 0xde, 0xba,
- 0x21, 0x47, 0x60, 0xaf, 0xcd, 0xd0, 0x9f, 0x15, 0xa5, 0xcb, 0x26, 0x64,
- 0x4d, 0xdf, 0x3a, 0x0c, 0xdc, 0xef, 0x40, 0x6e, 0x16, 0x62, 0x67, 0x37,
- 0xf2, 0xd9, 0x0c, 0xce, 0x33, 0x85, 0xd8, 0xd7, 0xa8, 0xd7, 0x12, 0xdf,
- 0x0a, 0xb8, 0x57, 0x76, 0x32, 0x2f, 0xf3, 0xbc, 0x07, 0xac, 0xf4, 0xb3,
- 0xe4, 0x65, 0xca, 0x91, 0x7c, 0xd5, 0x56, 0xbe, 0x10, 0x3a, 0x9b, 0x62,
- 0x3e, 0x07, 0xfd, 0x83, 0x4e, 0x16, 0x39, 0x5e, 0xd5, 0xc1, 0xe4, 0xa4,
- 0xcc, 0x43, 0x76, 0x62, 0x16, 0xb2, 0x84, 0x0d, 0xe1, 0x5a, 0x02, 0xdd,
- 0xf6, 0xbc, 0x18, 0x74, 0x77, 0x3c, 0x4b, 0x38, 0xa9, 0x28, 0x9b, 0x83,
- 0xcc, 0x26, 0xdd, 0x5d, 0x1d, 0x7e, 0x3e, 0x09, 0x5f, 0x99, 0xe0, 0x5e,
- 0x9f, 0x85, 0x0e, 0x77, 0x23, 0x86, 0x78, 0x1e, 0x6c, 0x38, 0xa1, 0x0b,
- 0x75, 0x18, 0xf6, 0xe2, 0xf2, 0x5d, 0x1b, 0xe6, 0xc5, 0x9c, 0x84, 0x4f,
- 0x2b, 0x99, 0x9e, 0x77, 0x0f, 0x68, 0xa9, 0xda, 0x1d, 0x58, 0xd7, 0x24,
- 0x08, 0x7b, 0xa6, 0xbf, 0xdf, 0x46, 0x15, 0x3b, 0x30, 0x6e, 0xc7, 0x7e,
- 0x9b, 0x98, 0x7b, 0x4e, 0xd2, 0x16, 0xb2, 0xb4, 0x7d, 0x23, 0xf0, 0xe7,
- 0x6f, 0x82, 0x4e, 0xae, 0x51, 0x70, 0xf1, 0xa6, 0x5c, 0x56, 0x96, 0x6a,
- 0xdb, 0x65, 0x6e, 0x3f, 0xf7, 0xe8, 0xa6, 0x1d, 0x22, 0xfe, 0xf3, 0x99,
- 0x74, 0xd3, 0x8f, 0x74, 0x06, 0x63, 0xed, 0x73, 0xfe, 0x1e, 0x62, 0x32,
- 0xdf, 0x1d, 0x51, 0xf4, 0x8a, 0x7e, 0xd1, 0xde, 0xe8, 0xc7, 0xa8, 0x5c,
- 0xbb, 0x76, 0x0f, 0x72, 0xf0, 0xbd, 0xbb, 0xa9, 0x03, 0x86, 0x5c, 0xb2,
- 0x3c, 0xef, 0x92, 0xdd, 0x04, 0xfe, 0x74, 0x69, 0xb2, 0x8e, 0x9b, 0xd2,
- 0x0a, 0x99, 0x3b, 0x5a, 0x20, 0x97, 0x36, 0x25, 0x97, 0x49, 0x15, 0xf7,
- 0xde, 0xc5, 0xd9, 0x70, 0x6d, 0x45, 0xc5, 0x97, 0x82, 0x5a, 0xc7, 0x35,
- 0x3c, 0xd3, 0x77, 0x91, 0x73, 0x1f, 0xc3, 0xda, 0x98, 0xb4, 0x28, 0xdd,
- 0x66, 0xfc, 0x27, 0xaf, 0xd2, 0xe1, 0xe3, 0x61, 0xac, 0xa5, 0x0e, 0x87,
- 0xfc, 0x8f, 0x06, 0x3c, 0x12, 0xaf, 0x0d, 0xbc, 0x6d, 0xaa, 0xce, 0x28,
- 0xfb, 0xe7, 0xd7, 0x11, 0x53, 0xf2, 0x40, 0x5d, 0x94, 0x0b, 0x7d, 0x21,
- 0x41, 0x43, 0xba, 0x9f, 0xc1, 0x3e, 0xa4, 0x61, 0x13, 0xf2, 0x5e, 0xd1,
- 0xaa, 0xe4, 0xcb, 0x0c, 0xf7, 0x11, 0x3d, 0x96, 0x6b, 0x91, 0x11, 0x68,
- 0x5d, 0xd5, 0xb1, 0xcc, 0x07, 0xa0, 0x7b, 0x5f, 0x07, 0x8f, 0x85, 0x19,
- 0xfa, 0xaa, 0x2f, 0x61, 0xdd, 0x4a, 0x5a, 0xf7, 0xb7, 0x95, 0x23, 0x0e,
- 0x65, 0xfa, 0x0e, 0x64, 0xaa, 0x77, 0x35, 0x4b, 0x87, 0x14, 0x91, 0x4f,
- 0xcd, 0x0f, 0x83, 0xaf, 0x81, 0x36, 0x89, 0xed, 0xa2, 0xaf, 0x42, 0xed,
- 0x93, 0x58, 0x41, 0x60, 0xb8, 0xee, 0xe9, 0x3b, 0xb1, 0x7e, 0x20, 0x01,
- 0xf9, 0x52, 0x66, 0x7a, 0x00, 0x47, 0x18, 0x14, 0x4a, 0x66, 0xa1, 0xb3,
- 0x59, 0x88, 0x9b, 0xef, 0xfa, 0x93, 0xa6, 0x70, 0x1e, 0x3e, 0xbd, 0xc8,
- 0xb5, 0xa4, 0xd9, 0x5f, 0xd3, 0x64, 0x85, 0xb2, 0xfe, 0x2b, 0xf8, 0xa7,
- 0x5f, 0x79, 0x7b, 0x87, 0xc2, 0xf7, 0xe4, 0x87, 0x7c, 0xe1, 0x0c, 0x41,
- 0xd3, 0xe6, 0x9c, 0x25, 0x83, 0xd3, 0xa2, 0x15, 0x90, 0x7b, 0x50, 0x47,
- 0x7a, 0x86, 0xd2, 0x95, 0x94, 0xbe, 0x0d, 0xbc, 0x1a, 0xb2, 0x7f, 0x88,
- 0xfc, 0x6e, 0x0d, 0xf2, 0x8e, 0x46, 0x9e, 0x3b, 0x02, 0x9e, 0xd5, 0x7e,
- 0xc3, 0x79, 0x7d, 0x8d, 0xf7, 0xd1, 0x99, 0x70, 0x5f, 0x03, 0xb6, 0xbc,
- 0x82, 0x9a, 0x87, 0xfb, 0x93, 0x9e, 0x1b, 0x9e, 0x6e, 0x59, 0x95, 0x1e,
- 0xfd, 0x57, 0xde, 0xfd, 0x43, 0x9a, 0xca, 0xd3, 0x74, 0xe4, 0x8c, 0xfa,
- 0x10, 0x78, 0x1d, 0xe2, 0x79, 0xe9, 0x72, 0xff, 0x6e, 0xe2, 0x3b, 0x42,
- 0xde, 0x80, 0xb3, 0xd5, 0xaf, 0x61, 0x86, 0xc2, 0x3d, 0x1a, 0xf5, 0x27,
- 0xc4, 0x49, 0x5c, 0x84, 0xe1, 0x99, 0xd0, 0xdf, 0x4a, 0xbc, 0x60, 0xc7,
- 0x83, 0xb3, 0x0e, 0xd7, 0x89, 0x66, 0x58, 0xeb, 0xd7, 0xc1, 0x68, 0x1f,
- 0xa4, 0xde, 0xf5, 0x04, 0x76, 0x16, 0xea, 0x21, 0xf7, 0x64, 0x7f, 0x2b,
- 0x9d, 0xe5, 0x3a, 0xae, 0x27, 0x3c, 0x61, 0xe0, 0x33, 0xe0, 0x83, 0x7e,
- 0x06, 0xdb, 0x78, 0xf9, 0x26, 0x5f, 0xce, 0xd8, 0x4e, 0x1f, 0x63, 0xaf,
- 0xf7, 0xe7, 0xac, 0x7d, 0xf0, 0xac, 0xc3, 0x7e, 0x1b, 0xfd, 0x3a, 0xe7,
- 0x50, 0x4f, 0x2c, 0x8e, 0xa2, 0xb7, 0x64, 0xed, 0x1e, 0x80, 0x7e, 0x3e,
- 0xac, 0xe7, 0xdb, 0x4a, 0x46, 0x8e, 0x35, 0xbd, 0x14, 0xab, 0xb5, 0xc3,
- 0x88, 0xc9, 0x52, 0xb9, 0x4d, 0xd5, 0xc6, 0x6d, 0xc3, 0x85, 0x2c, 0xe6,
- 0xea, 0x8c, 0xcb, 0x30, 0x7f, 0xac, 0x43, 0x6c, 0x88, 0xeb, 0xd3, 0xf1,
- 0xca, 0xed, 0x39, 0xda, 0x49, 0x4a, 0x52, 0xf5, 0x6b, 0x88, 0x79, 0xc8,
- 0x1f, 0x95, 0x0e, 0x7d, 0xf1, 0x76, 0xd2, 0x5f, 0x45, 0xec, 0x32, 0x72,
- 0x62, 0xe8, 0xb9, 0xe6, 0xf8, 0x64, 0xb6, 0x0d, 0xb1, 0x7e, 0x6c, 0xbb,
- 0x7e, 0x6e, 0xdf, 0xf6, 0xd8, 0xb9, 0xae, 0x52, 0x53, 0xae, 0xb2, 0x5d,
- 0x9f, 0x86, 0x2f, 0xaf, 0x89, 0x8e, 0x98, 0x8a, 0x1a, 0x01, 0xe3, 0x73,
- 0x0f, 0x3c, 0xa0, 0xe7, 0x62, 0x52, 0x4e, 0xc8, 0x93, 0x8b, 0x59, 0xf8,
- 0xf5, 0x5a, 0x3a, 0x55, 0x94, 0x27, 0xa5, 0x5a, 0x3b, 0x24, 0x93, 0xb5,
- 0xf0, 0xde, 0x80, 0x77, 0x06, 0x49, 0xe5, 0xbf, 0xe8, 0x5f, 0x27, 0x03,
- 0xda, 0x41, 0x73, 0x7e, 0x84, 0x31, 0x3a, 0x4b, 0xdf, 0x7d, 0x0d, 0x3a,
- 0xd1, 0x12, 0xd4, 0xda, 0xbe, 0xfe, 0x19, 0xb9, 0x8f, 0x30, 0x47, 0xfd,
- 0xdb, 0xb0, 0x7a, 0x6e, 0x7b, 0x4e, 0xfd, 0x89, 0x8a, 0xa9, 0x4b, 0x36,
- 0x9f, 0x09, 0xf3, 0xf6, 0xe0, 0x94, 0x75, 0xdd, 0x64, 0x6d, 0x70, 0xc1,
- 0x21, 0x3e, 0x53, 0x9d, 0xb5, 0x91, 0xbb, 0x8c, 0xb5, 0xad, 0xa4, 0x0b,
- 0xcd, 0xc0, 0x3c, 0xf6, 0x77, 0x9a, 0x83, 0x71, 0xb8, 0xf6, 0xb5, 0x86,
- 0xb5, 0x9c, 0x63, 0x4f, 0xdc, 0xd8, 0xa3, 0xe1, 0xce, 0xe4, 0x82, 0x9b,
- 0x51, 0x35, 0x7b, 0xc1, 0x55, 0xb9, 0x02, 0x6a, 0x74, 0xe8, 0x93, 0xba,
- 0x43, 0x81, 0x3f, 0x72, 0xff, 0xce, 0xf4, 0xcf, 0x9d, 0xfe, 0x63, 0x45,
- 0x18, 0xdf, 0xa8, 0x6f, 0x53, 0xca, 0x4f, 0xbd, 0xd9, 0x70, 0x17, 0xf0,
- 0x26, 0xfc, 0xd2, 0x9d, 0x9b, 0xfd, 0x9a, 0xc6, 0x0c, 0x7c, 0x5a, 0xab,
- 0xca, 0x53, 0x7c, 0x9f, 0x96, 0x6a, 0x80, 0x4d, 0xf1, 0xde, 0xa0, 0xc3,
- 0xaf, 0xbd, 0x7f, 0x2b, 0x58, 0xc3, 0xfc, 0xc1, 0x32, 0x99, 0x3b, 0xf8,
- 0xb2, 0xf0, 0x9e, 0x59, 0x1d, 0x27, 0x4a, 0x01, 0xbe, 0xa6, 0xe0, 0xdd,
- 0x5b, 0x6d, 0x3e, 0x4d, 0xe1, 0xda, 0x3f, 0x0d, 0xee, 0xa6, 0x94, 0x2f,
- 0xcc, 0x03, 0x16, 0x3c, 0xa4, 0x4a, 0x3a, 0xf4, 0x66, 0xa4, 0xee, 0xcb,
- 0x1b, 0xf1, 0x8e, 0xf7, 0x4f, 0x8a, 0xb6, 0x0b, 0x2a, 0xe7, 0x68, 0xe4,
- 0x3f, 0x4f, 0xbe, 0xf3, 0x06, 0x69, 0x74, 0xc7, 0xb0, 0x56, 0x0e, 0xf8,
- 0x77, 0x14, 0xa6, 0x4c, 0x98, 0xfd, 0xe6, 0x24, 0xf1, 0x26, 0x04, 0xf8,
- 0x90, 0x97, 0xe4, 0xc2, 0x33, 0xfc, 0x26, 0xf7, 0x06, 0xde, 0x8d, 0x1c,
- 0xa3, 0xff, 0x66, 0x40, 0xcb, 0x8f, 0x03, 0x79, 0x85, 0xef, 0x7f, 0xb1,
- 0xf9, 0xe6, 0xf1, 0x3d, 0xb7, 0x07, 0xf2, 0xc4, 0xf3, 0xa1, 0x5f, 0x43,
- 0x13, 0xf5, 0xfd, 0x34, 0xf0, 0xa8, 0x18, 0x5c, 0xd1, 0x73, 0x88, 0xf9,
- 0x59, 0x64, 0x34, 0x35, 0xd8, 0xb4, 0x20, 0xf6, 0xbb, 0x69, 0xbb, 0x84,
- 0x55, 0x1f, 0xd5, 0xe8, 0x57, 0xaf, 0xc3, 0xaf, 0xf2, 0xac, 0x3f, 0x96,
- 0xa9, 0x5a, 0xaf, 0xdd, 0xac, 0xa9, 0xfc, 0x3a, 0x73, 0x5a, 0xfa, 0xed,
- 0xd3, 0xc8, 0x3d, 0x50, 0xa3, 0xa5, 0x8e, 0x08, 0x65, 0x7e, 0x5d, 0x76,
- 0xa8, 0x9c, 0xe0, 0x63, 0xb1, 0x20, 0x93, 0x22, 0xea, 0x04, 0x7d, 0xe8,
- 0x5f, 0x3d, 0x95, 0xd3, 0x68, 0xa8, 0x42, 0x6f, 0x81, 0xeb, 0x6d, 0x85,
- 0x87, 0xf8, 0x1a, 0x71, 0x69, 0xd2, 0x32, 0x14, 0xe2, 0x4b, 0xc9, 0x51,
- 0x37, 0xc4, 0x69, 0xc8, 0x65, 0x64, 0x2d, 0xfa, 0x90, 0x17, 0xf0, 0xcf,
- 0xe7, 0x5f, 0x7a, 0xcc, 0x09, 0xf4, 0xdc, 0xdd, 0x81, 0x0c, 0x7e, 0x8f,
- 0x32, 0xc0, 0x18, 0x3a, 0xef, 0x7c, 0xc5, 0xaf, 0x45, 0x54, 0x2d, 0x37,
- 0x86, 0x9a, 0x82, 0x73, 0x2b, 0x2d, 0x05, 0x3b, 0x3c, 0xe3, 0x7d, 0x98,
- 0x2b, 0xe2, 0x47, 0xb9, 0x10, 0x66, 0x3f, 0x9e, 0xf3, 0x01, 0x9c, 0x0c,
- 0xfb, 0x35, 0x79, 0x58, 0x8b, 0x84, 0x39, 0xa1, 0xcc, 0xe8, 0x39, 0xe6,
- 0xef, 0x3b, 0x40, 0x2b, 0x73, 0x56, 0x9c, 0xe7, 0xaa, 0xff, 0x59, 0x85,
- 0xa9, 0xac, 0xc1, 0xf8, 0xb9, 0xe7, 0xa8, 0x1b, 0xe6, 0xbb, 0xcc, 0x69,
- 0xc3, 0xdc, 0x27, 0xaf, 0x15, 0x9d, 0x31, 0xed, 0x3e, 0x87, 0xf0, 0xfa,
- 0xec, 0x66, 0xb1, 0x52, 0x3d, 0xba, 0x27, 0x23, 0x43, 0xac, 0x9d, 0x8f,
- 0xe1, 0xcc, 0x3b, 0xa4, 0x9c, 0x41, 0x1e, 0x60, 0xde, 0x85, 0xbe, 0x19,
- 0x73, 0x5f, 0xc6, 0x1c, 0x74, 0x23, 0xc3, 0xfc, 0x66, 0x83, 0xaa, 0x41,
- 0x4a, 0x2a, 0x76, 0xec, 0x08, 0xf4, 0xe5, 0x89, 0x4e, 0x5f, 0x3f, 0xbe,
- 0x87, 0xf1, 0x46, 0xcc, 0x7f, 0x03, 0xbd, 0xe7, 0xf5, 0x0c, 0x85, 0xf3,
- 0xd4, 0xfb, 0x61, 0xcc, 0xdf, 0x09, 0x1c, 0x15, 0x3c, 0x7f, 0x0e, 0xcf,
- 0x7f, 0xb8, 0x6e, 0xed, 0x77, 0x31, 0xae, 0x60, 0xbe, 0xb0, 0x6e, 0x3e,
- 0xf4, 0xb3, 0xdc, 0xaf, 0xa2, 0x15, 0xdd, 0x29, 0x2d, 0xaf, 0xea, 0x88,
- 0x63, 0xa8, 0x55, 0xe8, 0x6b, 0x59, 0xb3, 0xcc, 0x20, 0x17, 0xa7, 0x9f,
- 0x3d, 0x88, 0x35, 0x8b, 0xd0, 0xbb, 0x56, 0x95, 0x65, 0xea, 0xca, 0x1e,
- 0x0f, 0x1d, 0xec, 0x99, 0x63, 0x5f, 0x39, 0x68, 0xd7, 0x09, 0xc3, 0xe7,
- 0x27, 0x0f, 0xf6, 0xd4, 0x0f, 0x01, 0x96, 0xf9, 0x7a, 0xe3, 0x1d, 0xef,
- 0x37, 0xd6, 0xed, 0xe9, 0xd7, 0x38, 0x45, 0x75, 0x37, 0x78, 0xe8, 0x60,
- 0x61, 0x86, 0x71, 0x9a, 0xf5, 0x26, 0xf3, 0xd2, 0xca, 0xc1, 0xf1, 0xda,
- 0x54, 0x50, 0xd3, 0x84, 0xef, 0xf9, 0x8e, 0xf2, 0xbf, 0x15, 0x6d, 0xa4,
- 0xab, 0x11, 0x8f, 0xca, 0x6b, 0x80, 0xe7, 0x49, 0xe0, 0x61, 0x6d, 0xa4,
- 0xee, 0x90, 0x15, 0xbd, 0xa9, 0xb9, 0x5b, 0xd1, 0x46, 0x5c, 0xdc, 0x2b,
- 0xc4, 0x77, 0x02, 0x75, 0xc7, 0x77, 0x48, 0x2f, 0xf0, 0x7c, 0x26, 0xc8,
- 0x6d, 0x78, 0x37, 0x65, 0xf8, 0x77, 0x38, 0x6a, 0x1c, 0xd6, 0xbe, 0x4d,
- 0xeb, 0x6a, 0xdf, 0xa6, 0xe0, 0x1e, 0x8b, 0xb0, 0x7a, 0x00, 0xab, 0xee,
- 0xd0, 0x31, 0x97, 0x0a, 0xee, 0x94, 0xe3, 0xbc, 0x53, 0x6e, 0x90, 0x45,
- 0x53, 0x20, 0x7f, 0xd2, 0x11, 0xd6, 0x2b, 0x8d, 0xf4, 0xf1, 0xbe, 0x79,
- 0x0a, 0xef, 0xc3, 0xb3, 0x09, 0x79, 0x5f, 0xc4, 0x3c, 0xe9, 0x3d, 0x03,
- 0xf8, 0x90, 0xde, 0x4f, 0x7b, 0xa6, 0x5c, 0x7b, 0x06, 0xbf, 0x70, 0xbf,
- 0x50, 0x2e, 0xa4, 0xf5, 0xd7, 0xd5, 0x5a, 0xa1, 0xdf, 0x5b, 0x0c, 0x62,
- 0x3a, 0xe9, 0xa2, 0x0f, 0xa2, 0x3f, 0x0e, 0xef, 0xc0, 0x59, 0x63, 0x33,
- 0x56, 0xf0, 0xbc, 0x5a, 0xa0, 0x2b, 0x84, 0xd3, 0x90, 0x5f, 0xeb, 0xcc,
- 0xc3, 0x52, 0xa8, 0x35, 0x92, 0x8f, 0xc8, 0x0f, 0xb0, 0x57, 0x3e, 0xd3,
- 0xa4, 0xec, 0x88, 0xf7, 0x08, 0xcd, 0xb2, 0x02, 0x9d, 0xbe, 0x84, 0xfa,
- 0x63, 0x1e, 0xb5, 0xd1, 0x12, 0xef, 0xb5, 0xeb, 0x27, 0x3b, 0x79, 0x1f,
- 0x32, 0x65, 0xad, 0xd5, 0xf1, 0x73, 0x80, 0x59, 0xb0, 0x58, 0xeb, 0x4b,
- 0xd0, 0x10, 0x23, 0x91, 0x67, 0x8c, 0x5b, 0xff, 0xe3, 0x95, 0x13, 0x8d,
- 0xb0, 0xb7, 0xaa, 0xb3, 0xdb, 0xa4, 0x3a, 0x9b, 0x3e, 0x3a, 0x87, 0x7a,
- 0x77, 0xc6, 0xd2, 0xb7, 0xe8, 0x7e, 0xad, 0x34, 0x03, 0xdf, 0xa4, 0x6a,
- 0xad, 0x39, 0x79, 0xae, 0x93, 0x67, 0xd7, 0x64, 0xf5, 0x9b, 0x9d, 0xfa,
- 0xef, 0x50, 0x17, 0x15, 0xe5, 0xb1, 0x13, 0x1b, 0xa4, 0x3c, 0x70, 0x1f,
- 0x72, 0x2d, 0xc8, 0xf3, 0x44, 0x05, 0x95, 0x21, 0xf5, 0xea, 0xbd, 0x03,
- 0xe3, 0x16, 0x6b, 0x26, 0xf1, 0xe3, 0x9a, 0xf8, 0x3c, 0xc6, 0x4e, 0xb4,
- 0x29, 0x9f, 0xe4, 0xdf, 0x99, 0xf7, 0x9a, 0x45, 0xe4, 0x63, 0x85, 0x01,
- 0x24, 0x8d, 0xc8, 0x5e, 0xcc, 0x9d, 0x22, 0x3d, 0xcc, 0x19, 0xe1, 0x8f,
- 0x7b, 0xce, 0xc1, 0xcb, 0x9d, 0x20, 0xbc, 0x2e, 0xc6, 0x89, 0x98, 0x34,
- 0x9d, 0x60, 0x9d, 0x2d, 0x5d, 0xa8, 0x51, 0x88, 0xb3, 0xc7, 0x40, 0x3f,
- 0x8a, 0xdf, 0x1e, 0xe4, 0x51, 0x26, 0xf2, 0xda, 0x5b, 0xc0, 0x03, 0x96,
- 0x6b, 0x6e, 0x05, 0xff, 0x6a, 0x27, 0xeb, 0xce, 0x9e, 0x73, 0x84, 0xe7,
- 0x7d, 0x76, 0x17, 0xe8, 0xf1, 0xf7, 0x27, 0x0e, 0xe3, 0x84, 0x48, 0xef,
- 0xb4, 0x74, 0xea, 0x6a, 0x8d, 0x21, 0xe3, 0x59, 0xbe, 0x6b, 0x03, 0xfc,
- 0xab, 0xca, 0x3e, 0x7b, 0xd5, 0x3a, 0xff, 0xce, 0xa2, 0xbc, 0x46, 0x37,
- 0xe6, 0x34, 0x3c, 0x23, 0x57, 0xca, 0x9a, 0xd2, 0x3b, 0xef, 0xc3, 0xf6,
- 0x9c, 0xeb, 0xd8, 0xe2, 0xdf, 0xed, 0xf8, 0xb4, 0xf1, 0x6e, 0xb0, 0x0c,
- 0xa9, 0x1a, 0x3b, 0x59, 0xf3, 0x13, 0x86, 0xdf, 0x52, 0xd8, 0x73, 0x2d,
- 0xe5, 0xe7, 0xcf, 0xe9, 0xfa, 0xff, 0xa5, 0x5f, 0xeb, 0xbf, 0xe1, 0x84,
- 0x77, 0x4b, 0xa9, 0x86, 0xbb, 0xa5, 0x74, 0xc3, 0xb7, 0x97, 0x9f, 0xb4,
- 0x05, 0x7a, 0x27, 0x93, 0xb6, 0x27, 0xe1, 0xf7, 0xa5, 0xbd, 0x37, 0xe5,
- 0x90, 0x19, 0x15, 0xa7, 0xc7, 0x21, 0xfb, 0x2b, 0x75, 0xd2, 0x8b, 0x98,
- 0x53, 0x8f, 0xcb, 0xfb, 0x8b, 0xad, 0x72, 0x65, 0xce, 0xcf, 0x29, 0xaf,
- 0xa8, 0x6f, 0x4e, 0xa6, 0x7c, 0x80, 0xc2, 0xff, 0x72, 0x3d, 0x83, 0x5f,
- 0xa7, 0x5c, 0x5d, 0xbc, 0x39, 0xa7, 0xbc, 0xe0, 0xde, 0x0d, 0x5a, 0x3a,
- 0x03, 0x1b, 0x46, 0xdd, 0x86, 0x18, 0x58, 0x09, 0xee, 0xea, 0x55, 0xce,
- 0x62, 0xd0, 0x16, 0x78, 0x27, 0x1f, 0xde, 0x57, 0xf7, 0x9a, 0x17, 0x21,
- 0xe3, 0xaf, 0x1a, 0x9d, 0xa8, 0xa3, 0x79, 0xd7, 0x16, 0xc6, 0xec, 0x30,
- 0xf6, 0x90, 0xee, 0xb7, 0x81, 0x7b, 0x00, 0x7a, 0x4a, 0xdd, 0xb4, 0xa1,
- 0xb3, 0xa6, 0x2c, 0xf5, 0xa5, 0x67, 0x2a, 0xc2, 0xef, 0x02, 0x59, 0xec,
- 0xb9, 0x0c, 0xbd, 0xcc, 0x40, 0x1e, 0xcc, 0xf5, 0x28, 0x57, 0x9c, 0xed,
- 0xf4, 0x94, 0x94, 0xdd, 0xad, 0xc0, 0x97, 0x97, 0x92, 0x3b, 0x8c, 0xbd,
- 0x8e, 0x43, 0x6f, 0x7f, 0xb9, 0x85, 0x77, 0x99, 0xcd, 0x56, 0x16, 0x34,
- 0xde, 0x25, 0xe3, 0x27, 0xa7, 0x64, 0xc2, 0x59, 0xfd, 0x66, 0x94, 0xe1,
- 0xf7, 0x94, 0x45, 0xd4, 0xb4, 0xbe, 0x3d, 0xe6, 0x64, 0xfc, 0x14, 0x70,
- 0x38, 0xac, 0x8d, 0x7b, 0xa1, 0x37, 0xfd, 0xaa, 0x36, 0x2e, 0x29, 0x9f,
- 0xc4, 0xf9, 0xef, 0x01, 0x57, 0x6f, 0x65, 0x0f, 0xe0, 0xca, 0xa8, 0x9f,
- 0x8b, 0xc8, 0x85, 0x17, 0x1c, 0x43, 0xca, 0x36, 0x7c, 0x6b, 0x31, 0xa9,
- 0xeb, 0xbb, 0xba, 0x65, 0xde, 0xe9, 0x37, 0x75, 0xde, 0x3d, 0x26, 0x7c,
- 0xdf, 0x57, 0x56, 0xf6, 0x9d, 0xd4, 0x0d, 0xab, 0x5b, 0x16, 0x9d, 0x8a,
- 0x54, 0x07, 0x38, 0xe6, 0xf9, 0x55, 0xc4, 0xb4, 0x7c, 0x5f, 0x99, 0xd7,
- 0x35, 0x75, 0xb7, 0x5d, 0x76, 0xd5, 0xfd, 0x68, 0xca, 0x94, 0xc3, 0xa0,
- 0x0f, 0xcf, 0x0b, 0xd0, 0xf1, 0x69, 0xe6, 0x78, 0xfe, 0x9d, 0xf1, 0x81,
- 0xe5, 0x22, 0x68, 0x68, 0x97, 0xde, 0x1f, 0xd3, 0xc6, 0x1e, 0xc2, 0x1c,
- 0xc7, 0x69, 0xe8, 0xeb, 0xc3, 0x78, 0x26, 0x6c, 0x12, 0x3d, 0xe5, 0xd0,
- 0x8d, 0xde, 0x04, 0x2d, 0xd0, 0x4b, 0xd6, 0xa5, 0xfb, 0x53, 0x32, 0x7f,
- 0x72, 0xb7, 0x94, 0x16, 0x76, 0x03, 0xff, 0x3f, 0x22, 0xe7, 0xbf, 0x33,
- 0xb8, 0x8b, 0x65, 0xde, 0xcf, 0x7d, 0x5e, 0xdc, 0xa2, 0x6c, 0x63, 0x9a,
- 0xf3, 0xec, 0xf7, 0x61, 0x3d, 0xea, 0x07, 0x47, 0xdd, 0x4f, 0x03, 0x06,
- 0x67, 0xe7, 0x36, 0x7e, 0xfb, 0xeb, 0x84, 0x9f, 0xae, 0xb0, 0x76, 0x40,
- 0x6c, 0x99, 0x1b, 0x2c, 0xd4, 0xd2, 0x66, 0x41, 0x7d, 0x97, 0xc8, 0x88,
- 0x1f, 0x6f, 0x38, 0x17, 0x17, 0x6b, 0x1a, 0xf5, 0x68, 0x8e, 0xef, 0x0e,
- 0xab, 0xfb, 0x1f, 0xf5, 0x7d, 0x4e, 0xde, 0x95, 0x51, 0xe8, 0x58, 0xef,
- 0x74, 0x06, 0x39, 0xf1, 0x7b, 0xc8, 0x27, 0x7f, 0x1e, 0xc8, 0x60, 0x38,
- 0xd0, 0x8d, 0xd6, 0x06, 0x9d, 0xc0, 0x39, 0x3b, 0x38, 0x7b, 0x07, 0x7a,
- 0xe0, 0xe0, 0xac, 0x57, 0xf5, 0x63, 0xb8, 0xc1, 0xe7, 0x6e, 0x92, 0xbf,
- 0x9c, 0x49, 0x67, 0x56, 0xa0, 0x3f, 0x57, 0xc1, 0xeb, 0x0a, 0xea, 0xbc,
- 0x2b, 0x88, 0x23, 0x0b, 0x35, 0x7e, 0x4b, 0xe0, 0xb7, 0x38, 0x8e, 0xb7,
- 0xe1, 0x3c, 0x42, 0x7f, 0xfc, 0x52, 0x60, 0x17, 0x9b, 0xd4, 0x7d, 0xe7,
- 0xfb, 0x38, 0xc3, 0x15, 0xd3, 0xcf, 0x17, 0xfd, 0x35, 0x9b, 0x24, 0xfc,
- 0xde, 0xe7, 0xeb, 0x0f, 0x69, 0xa1, 0xfe, 0x7c, 0xb2, 0xc5, 0xcf, 0xfb,
- 0xf9, 0x0d, 0x8c, 0xf5, 0x0b, 0x9f, 0xef, 0xdf, 0xe2, 0xe3, 0x6a, 0xd4,
- 0xdb, 0x8f, 0x3d, 0xd6, 0x6a, 0x85, 0x3e, 0xf8, 0x6c, 0xd7, 0x93, 0x63,
- 0xf6, 0xcd, 0xf6, 0x76, 0x8f, 0x13, 0xca, 0x87, 0xf2, 0x2b, 0xca, 0x11,
- 0x37, 0x0d, 0x5b, 0xa0, 0xec, 0xac, 0x06, 0xd9, 0x89, 0xfc, 0xb9, 0x23,
- 0xbc, 0xef, 0xc2, 0x3b, 0x25, 0xbb, 0x64, 0x21, 0xd6, 0xca, 0xfb, 0x5a,
- 0xe8, 0xe3, 0xdf, 0xca, 0xc4, 0xac, 0xc8, 0x32, 0xde, 0x2f, 0x39, 0xb4,
- 0xd1, 0x0c, 0xf2, 0xd7, 0x8d, 0x32, 0x3f, 0x87, 0x3a, 0xcb, 0x91, 0x52,
- 0xe1, 0x4e, 0xc6, 0x99, 0xb8, 0x5c, 0x51, 0xf7, 0x7b, 0x22, 0x3b, 0xcf,
- 0x1a, 0x62, 0x9c, 0x45, 0x41, 0x07, 0x99, 0x9f, 0xef, 0x0b, 0xef, 0xfb,
- 0x7c, 0x5b, 0xaf, 0xd6, 0xb0, 0xd6, 0xe9, 0x55, 0xfe, 0xb1, 0x5a, 0x1f,
- 0x97, 0xf2, 0x0c, 0xf7, 0x42, 0x3f, 0x97, 0xc2, 0x3b, 0x5b, 0x26, 0x4f,
- 0x66, 0xe4, 0xfb, 0xfc, 0x5e, 0x93, 0x1d, 0xc5, 0x1e, 0x05, 0xa9, 0x2c,
- 0x63, 0xbe, 0xfe, 0x4f, 0x32, 0xb7, 0x38, 0x2e, 0xf3, 0x33, 0x17, 0x1a,
- 0xee, 0x73, 0x31, 0x9e, 0x6b, 0xac, 0x4f, 0x8b, 0xac, 0xa9, 0x50, 0x7f,
- 0x5a, 0x18, 0xc3, 0x06, 0xea, 0x93, 0xa5, 0x9b, 0xef, 0x1f, 0x1b, 0xeb,
- 0xd2, 0x51, 0x39, 0x8a, 0x33, 0xae, 0x9e, 0xcc, 0xa8, 0xba, 0xa6, 0x25,
- 0x37, 0xfb, 0xf8, 0x87, 0x88, 0x11, 0x63, 0x42, 0x3d, 0xbb, 0x2e, 0x5f,
- 0xb3, 0x8f, 0xca, 0x23, 0x88, 0x1d, 0x47, 0x90, 0x5f, 0xff, 0x36, 0xea,
- 0xba, 0xd4, 0x66, 0x9e, 0x21, 0xe8, 0xb5, 0x58, 0x57, 0x7a, 0x32, 0x6a,
- 0xdf, 0x61, 0xfe, 0x00, 0x92, 0x7d, 0xbf, 0xce, 0xf8, 0xf8, 0xdf, 0x5e,
- 0x1e, 0xf1, 0xee, 0x43, 0x0b, 0x3e, 0x41, 0xc1, 0x69, 0x3e, 0xdc, 0x0c,
- 0xe1, 0xfa, 0xcd, 0x63, 0x84, 0x9b, 0xd3, 0x02, 0x38, 0x0d, 0x70, 0x31,
- 0xb9, 0x68, 0x1b, 0xd0, 0x8d, 0x51, 0xf0, 0x09, 0xdf, 0x3e, 0x18, 0x7e,
- 0x6f, 0xdc, 0x80, 0x98, 0xba, 0xb6, 0xfe, 0x8d, 0x60, 0xfd, 0xf7, 0x83,
- 0xf5, 0x97, 0x56, 0xd7, 0x87, 0x71, 0xf5, 0x13, 0x4f, 0x1a, 0xe8, 0x7a,
- 0xa3, 0xe6, 0xc3, 0x1f, 0x0d, 0xe8, 0xba, 0xb4, 0x4a, 0x57, 0x08, 0x0f,
- 0x79, 0x2a, 0x9e, 0xe9, 0x93, 0xe9, 0x9b, 0x7b, 0x21, 0x47, 0x7e, 0x47,
- 0x86, 0x4d, 0x38, 0xfc, 0x7e, 0x4b, 0x3b, 0xd1, 0x65, 0x25, 0x71, 0x54,
- 0xc6, 0xac, 0xf4, 0xf0, 0xa4, 0xc4, 0xa0, 0xc3, 0xf4, 0x29, 0x31, 0x99,
- 0xa7, 0xaf, 0x41, 0x5f, 0xb6, 0x6f, 0x4d, 0xeb, 0xfb, 0x0d, 0xb4, 0xc6,
- 0x9e, 0x27, 0x8d, 0x3e, 0xad, 0xf1, 0x1d, 0x6b, 0xb4, 0xfa, 0xf0, 0x3e,
- 0xad, 0xef, 0xd7, 0x1a, 0xe0, 0xcf, 0x1a, 0x01, 0xbc, 0xd1, 0x00, 0x4f,
- 0x7d, 0x66, 0x3e, 0x41, 0x7d, 0x26, 0x6d, 0x5f, 0x50, 0xf7, 0x66, 0x1b,
- 0x72, 0xb3, 0x07, 0x3f, 0xbf, 0xc3, 0x93, 0x38, 0xf2, 0x8c, 0x66, 0xbc,
- 0xbb, 0x32, 0xc3, 0x1c, 0x44, 0xef, 0x69, 0x96, 0x9d, 0xd0, 0x59, 0x9e,
- 0x5d, 0xe3, 0x9d, 0xab, 0x27, 0x8f, 0xd8, 0xa4, 0xe5, 0x3f, 0xbd, 0x33,
- 0x89, 0x9d, 0x76, 0x55, 0xfa, 0xcc, 0x66, 0xe1, 0x9d, 0xae, 0xc2, 0x99,
- 0x21, 0x2d, 0xa7, 0xfb, 0x7a, 0xcd, 0xb7, 0xc0, 0xe7, 0xe8, 0x8c, 0x26,
- 0xf3, 0x56, 0x3a, 0x79, 0x1e, 0x38, 0xf6, 0xe0, 0x6c, 0xe6, 0x07, 0x48,
- 0x8f, 0xc8, 0x04, 0xf4, 0x7b, 0x5e, 0xc5, 0x43, 0xea, 0x71, 0x7a, 0xac,
- 0x82, 0x1c, 0xe7, 0xa7, 0x2a, 0xa6, 0x79, 0xde, 0x87, 0x88, 0x6b, 0x63,
- 0xeb, 0x74, 0x4f, 0x3f, 0xeb, 0xeb, 0x9e, 0x7e, 0x16, 0xb5, 0xf1, 0xf1,
- 0xb8, 0xb4, 0x2c, 0xc1, 0x7e, 0x9e, 0xef, 0x52, 0xfa, 0xa7, 0x3f, 0xcf,
- 0x6f, 0x19, 0xf0, 0x73, 0xc7, 0x0d, 0xb1, 0x8e, 0xab, 0x38, 0x00, 0x79,
- 0x17, 0x64, 0xf2, 0x14, 0x7d, 0xa9, 0x25, 0x3b, 0x8e, 0xf3, 0x3c, 0x98,
- 0xcf, 0xcc, 0x0d, 0x8e, 0xc3, 0x46, 0xa6, 0xf8, 0x7d, 0x70, 0xe9, 0x23,
- 0x19, 0xb7, 0x28, 0x07, 0x94, 0xfa, 0x4b, 0xa6, 0xc4, 0x96, 0xe0, 0x13,
- 0x96, 0x92, 0xd2, 0x04, 0xdb, 0xd2, 0xcf, 0x26, 0xb4, 0xea, 0xec, 0x7f,
- 0xc1, 0x1e, 0xf8, 0x4d, 0x20, 0x83, 0x71, 0x52, 0xab, 0xd6, 0x06, 0xd0,
- 0x53, 0xcf, 0x91, 0x46, 0x9d, 0xa5, 0x9e, 0x93, 0x8e, 0xd0, 0x5e, 0xf0,
- 0x7c, 0x36, 0xa3, 0xee, 0x6c, 0x3f, 0xb4, 0xc9, 0xcb, 0xdf, 0x48, 0x61,
- 0x26, 0xfc, 0x1b, 0x10, 0xd9, 0x8c, 0x1c, 0xa6, 0xa3, 0x60, 0xef, 0x18,
- 0xbe, 0x22, 0x9f, 0x96, 0xaf, 0x6d, 0x9f, 0x82, 0x2f, 0xf2, 0xd1, 0xc8,
- 0x17, 0x79, 0x6a, 0x97, 0x26, 0xc5, 0x57, 0xc8, 0x0f, 0x04, 0x0d, 0x7e,
- 0x7a, 0x8e, 0x27, 0x81, 0xff, 0x61, 0xf8, 0x80, 0x6e, 0xf4, 0x0f, 0xa1,
- 0x47, 0x28, 0x3b, 0x4b, 0xde, 0xc9, 0xeb, 0x55, 0xe4, 0x8b, 0x21, 0x9f,
- 0x25, 0x3c, 0xbf, 0x2e, 0x93, 0xb3, 0xde, 0x61, 0xc4, 0x53, 0xde, 0x27,
- 0x77, 0xea, 0x4a, 0x77, 0xd7, 0xf3, 0xfe, 0xba, 0xf8, 0xf2, 0xe1, 0x5d,
- 0x3c, 0x9e, 0x17, 0xd7, 0xcb, 0xa2, 0xd1, 0x77, 0x24, 0x83, 0xbf, 0x7b,
- 0xa1, 0x9f, 0xa0, 0x8c, 0xae, 0x4a, 0x61, 0x96, 0x77, 0x5a, 0x3e, 0xbe,
- 0xd2, 0xea, 0xdf, 0xbe, 0x34, 0xae, 0x19, 0x00, 0x5c, 0x37, 0xe0, 0x48,
- 0xd7, 0x0a, 0xe5, 0x07, 0x9f, 0xb3, 0xbd, 0xc1, 0xd7, 0x34, 0xae, 0xcb,
- 0xca, 0x33, 0x88, 0xff, 0x6f, 0xd8, 0x37, 0xc9, 0xb5, 0xc4, 0x1c, 0x68,
- 0xbe, 0xbe, 0x0f, 0x36, 0xd9, 0x04, 0x5f, 0x66, 0xca, 0x95, 0x5a, 0xb3,
- 0xcc, 0x23, 0xcf, 0x59, 0x58, 0xa4, 0x2f, 0x24, 0xed, 0xad, 0x98, 0xf7,
- 0xfd, 0x17, 0x7d, 0xed, 0x95, 0x1a, 0xe2, 0x2b, 0x6c, 0xfb, 0x4a, 0x2d,
- 0x81, 0xbe, 0x1b, 0xbd, 0x85, 0x3e, 0x85, 0x3e, 0x83, 0x7e, 0x00, 0xfd,
- 0x00, 0x7a, 0x0b, 0x6b, 0x93, 0xe8, 0xc3, 0x5a, 0x82, 0xb8, 0xd6, 0xf8,
- 0xae, 0xaa, 0xfd, 0xf8, 0xdd, 0x90, 0xb1, 0xcc, 0xb0, 0x47, 0x50, 0x63,
- 0x17, 0x06, 0xc2, 0xbf, 0xb9, 0xb9, 0xe1, 0x99, 0x16, 0x6b, 0xf7, 0x8a,
- 0xb6, 0x47, 0x7d, 0x5f, 0x98, 0x41, 0x5c, 0x78, 0x6e, 0xab, 0xb4, 0x5a,
- 0xe6, 0x3d, 0xea, 0xee, 0x68, 0x16, 0x63, 0x3e, 0xa3, 0x3e, 0x4e, 0x4c,
- 0x21, 0x3e, 0xd1, 0x7f, 0xfe, 0x6f, 0xe7, 0xd6, 0x1b, 0xdb, 0xc6, 0x59,
- 0xc6, 0x1f, 0x9f, 0x9d, 0x34, 0xe9, 0x9a, 0xf6, 0x92, 0x38, 0xa9, 0x93,
- 0x85, 0xcd, 0x8e, 0x2f, 0xad, 0x45, 0xd2, 0x71, 0xed, 0x2c, 0x16, 0xa6,
- 0x8c, 0x78, 0x76, 0x92, 0x76, 0x30, 0xa6, 0xb4, 0x74, 0xd3, 0x84, 0x10,
- 0x58, 0xc9, 0xba, 0x75, 0x13, 0xd2, 0x28, 0x30, 0x34, 0x89, 0xa2, 0x18,
- 0x27, 0x61, 0x19, 0x18, 0xc7, 0x0b, 0x81, 0x4e, 0xf0, 0xc5, 0x38, 0xd1,
- 0x06, 0x22, 0x4a, 0x3a, 0x8d, 0x0f, 0x08, 0x6d, 0x74, 0xb8, 0x83, 0xef,
- 0xfc, 0x11, 0x62, 0x12, 0x1f, 0xaa, 0xa8, 0x63, 0x20, 0x21, 0xe0, 0x23,
- 0xd2, 0x98, 0x8e, 0xdf, 0xef, 0x79, 0xef, 0x12, 0xc7, 0x64, 0x54, 0xf0,
- 0xc1, 0x3a, 0xbf, 0x77, 0xf7, 0xbe, 0xf7, 0xde, 0xfb, 0x3c, 0xef, 0xef,
- 0xf9, 0x3d, 0x7f, 0xce, 0x43, 0x9f, 0x19, 0xe0, 0xf8, 0x11, 0x61, 0x0c,
- 0x36, 0x9b, 0xc6, 0xff, 0xea, 0xc5, 0x1e, 0x63, 0x4b, 0xc1, 0xdb, 0x77,
- 0xb8, 0x61, 0x60, 0xab, 0x46, 0xd0, 0x67, 0x3f, 0x9f, 0x00, 0x36, 0xb0,
- 0x92, 0xa8, 0x54, 0xb1, 0x07, 0x7f, 0xed, 0xce, 0x29, 0xa7, 0xa3, 0x2c,
- 0x16, 0xc1, 0x4d, 0x73, 0x65, 0x72, 0x97, 0xcb, 0xf0, 0x47, 0xe0, 0xcb,
- 0x45, 0xe9, 0xbb, 0xd3, 0x16, 0x90, 0x83, 0xfe, 0x12, 0x73, 0xa3, 0x1d,
- 0xf8, 0x26, 0x9e, 0x87, 0xf7, 0x5a, 0xf3, 0xb0, 0x66, 0xa7, 0xc1, 0x05,
- 0x3d, 0x2f, 0xe2, 0x4c, 0x4a, 0xfc, 0x1c, 0x31, 0x47, 0xd0, 0xdf, 0xc4,
- 0xb2, 0xc8, 0xab, 0x32, 0xd3, 0x9a, 0x83, 0x84, 0x72, 0xfd, 0x0e, 0x7d,
- 0x7b, 0xc4, 0xc4, 0xa7, 0x18, 0x7f, 0x16, 0x99, 0x2c, 0x1b, 0x2e, 0x0b,
- 0xbf, 0xac, 0x61, 0xbc, 0xbb, 0xfd, 0xf1, 0x78, 0xdd, 0xd2, 0x71, 0x6a,
- 0xd2, 0x6b, 0x62, 0xbb, 0x63, 0x23, 0xb0, 0x11, 0x51, 0xa9, 0x43, 0x2e,
- 0xd7, 0x21, 0x93, 0x37, 0x4b, 0xd4, 0xf5, 0x61, 0xe8, 0x7d, 0x0b, 0xf3,
- 0xb3, 0x18, 0x6b, 0x44, 0x9f, 0x5d, 0x2f, 0x01, 0x3b, 0x6d, 0xf5, 0x4f,
- 0x7b, 0xc9, 0x0b, 0x69, 0x07, 0xcd, 0x38, 0x03, 0xe6, 0x3e, 0x09, 0xae,
- 0x75, 0xeb, 0x7c, 0x6a, 0x1a, 0x03, 0xe3, 0x3a, 0x41, 0x07, 0x4b, 0xdd,
- 0xfe, 0x3d, 0x5e, 0x8f, 0xa9, 0x77, 0xe2, 0x39, 0xbe, 0xc7, 0x88, 0x64,
- 0xcb, 0x41, 0xbf, 0x4e, 0xf4, 0x6b, 0x6f, 0x18, 0xeb, 0x68, 0xd3, 0x3b,
- 0x58, 0xfe, 0x3b, 0xf0, 0x7a, 0x33, 0xdf, 0x4f, 0xd8, 0x05, 0x09, 0x38,
- 0x3f, 0xed, 0x2f, 0x65, 0x93, 0xd6, 0xfc, 0xb6, 0x91, 0xcf, 0x80, 0xef,
- 0x03, 0x24, 0x96, 0x0a, 0x02, 0xbe, 0x18, 0xa5, 0x8c, 0xd2, 0xd8, 0xd7,
- 0x3f, 0x89, 0xca, 0x61, 0x57, 0x2a, 0xa5, 0x03, 0x62, 0x75, 0xb5, 0x68,
- 0x8d, 0x4e, 0xdc, 0x6a, 0x7c, 0xe6, 0x67, 0xfd, 0x67, 0xc2, 0xf7, 0x5e,
- 0x69, 0xd7, 0xb8, 0x34, 0xec, 0x0c, 0xee, 0x39, 0xd4, 0x34, 0xb7, 0x87,
- 0xfd, 0xfb, 0x78, 0xdd, 0x91, 0x02, 0xf8, 0x67, 0xae, 0x0c, 0x26, 0x0f,
- 0xfc, 0xb6, 0xc6, 0x98, 0xe3, 0x61, 0x0c, 0x6f, 0x38, 0x3e, 0x8f, 0x39,
- 0x16, 0xec, 0x31, 0xc6, 0xcd, 0x30, 0x46, 0x5f, 0xd3, 0x18, 0x13, 0xfe,
- 0x18, 0x59, 0x29, 0x5e, 0x99, 0xc0, 0x5e, 0x1b, 0x83, 0x7d, 0x4f, 0xda,
- 0xa7, 0xe5, 0x23, 0x22, 0x9d, 0x38, 0xf7, 0x72, 0x0a, 0x72, 0xf2, 0xbc,
- 0x49, 0x77, 0x1a, 0xf3, 0x7e, 0x0d, 0xb6, 0x35, 0xe0, 0x3c, 0xc5, 0x58,
- 0x18, 0x36, 0xec, 0xf3, 0x2e, 0xe3, 0x62, 0x05, 0x30, 0xb2, 0x84, 0x6d,
- 0x85, 0x86, 0x53, 0x35, 0xf0, 0xba, 0x2a, 0x2c, 0x69, 0xd1, 0xe1, 0x7b,
- 0x76, 0x48, 0xd1, 0x0e, 0x8d, 0x87, 0xc1, 0x6b, 0xb2, 0x65, 0xee, 0x23,
- 0x19, 0x0a, 0x8f, 0xb5, 0x82, 0x8b, 0x7a, 0xf2, 0x36, 0xa0, 0xa6, 0x58,
- 0x5a, 0x92, 0xfa, 0x86, 0x8d, 0xe3, 0x05, 0xc8, 0xe1, 0x45, 0xfc, 0x7f,
- 0x3e, 0xaa, 0x75, 0x4a, 0xe0, 0xeb, 0x8b, 0x78, 0x1f, 0xf2, 0x19, 0xf2,
- 0x88, 0x1a, 0xec, 0xad, 0x05, 0x5b, 0x03, 0x5e, 0x35, 0x4a, 0xde, 0xf5,
- 0xdc, 0xda, 0x4d, 0x79, 0x73, 0x35, 0x81, 0x67, 0xd1, 0x2e, 0x9f, 0x21,
- 0x1e, 0xd8, 0x0b, 0x69, 0x9c, 0x5b, 0x37, 0xdc, 0xb7, 0xb8, 0x85, 0x0d,
- 0xd4, 0x05, 0x8e, 0x00, 0x8e, 0xbd, 0x0d, 0x0c, 0x2c, 0xe2, 0xfe, 0xfa,
- 0x6a, 0x44, 0xd6, 0x1c, 0xf2, 0x22, 0x89, 0x67, 0x71, 0x6f, 0x7d, 0x7d,
- 0xb1, 0xd7, 0xe4, 0x51, 0xd8, 0x7f, 0x42, 0x0a, 0xe0, 0x75, 0xa7, 0xb5,
- 0xef, 0xad, 0xe4, 0xcc, 0x39, 0x35, 0xfa, 0x77, 0xb3, 0x52, 0xe7, 0x7e,
- 0xd2, 0xdc, 0x03, 0xb9, 0xc1, 0x65, 0xe8, 0x2c, 0x39, 0x3b, 0xfd, 0x00,
- 0xfc, 0xdf, 0xe0, 0x75, 0xbe, 0x3b, 0x8e, 0xd5, 0x24, 0xd6, 0x86, 0xfb,
- 0xbe, 0x10, 0x9a, 0x3e, 0x0e, 0x3b, 0x6a, 0x71, 0xaf, 0x17, 0x15, 0x0b,
- 0x8a, 0xcb, 0xb3, 0xb0, 0x29, 0xac, 0xb5, 0xe8, 0x83, 0x2e, 0x3e, 0x08,
- 0x59, 0xa6, 0x71, 0x5f, 0x93, 0x2d, 0xd9, 0x2c, 0x2a, 0x2f, 0xb3, 0x5e,
- 0x32, 0xb8, 0x66, 0xd5, 0xc0, 0xd1, 0xb0, 0x7f, 0xac, 0x4d, 0xe8, 0x16,
- 0xf6, 0x90, 0xb5, 0x19, 0xc5, 0x11, 0x78, 0xbc, 0x09, 0xbf, 0x02, 0xf8,
- 0x66, 0x6d, 0xc2, 0x27, 0x00, 0xbe, 0x59, 0x9b, 0x29, 0x1c, 0x81, 0xf1,
- 0x9b, 0x01, 0xae, 0x71, 0xfc, 0x94, 0xe6, 0xe1, 0x0d, 0xbe, 0x90, 0x4b,
- 0x12, 0x5f, 0x02, 0x3e, 0x69, 0x74, 0xe1, 0xeb, 0xcb, 0xc4, 0x10, 0xea,
- 0x75, 0x12, 0xb8, 0x45, 0x5d, 0x30, 0x5c, 0x72, 0xbd, 0x62, 0xd6, 0x6c,
- 0x7e, 0xeb, 0x9a, 0xda, 0x88, 0x29, 0x71, 0xa0, 0x63, 0x5c, 0x3b, 0x5c,
- 0x53, 0x1b, 0xf0, 0xba, 0x64, 0xf4, 0xc8, 0x35, 0xfb, 0xb9, 0x64, 0xd6,
- 0x53, 0xf2, 0x0d, 0xc5, 0xad, 0x00, 0xb3, 0xc8, 0x21, 0x63, 0x58, 0x3f,
- 0x47, 0x9e, 0xff, 0xf6, 0x4d, 0xc9, 0x7e, 0x87, 0xb8, 0x35, 0x1c, 0x6b,
- 0x0f, 0x11, 0xab, 0x3c, 0xd9, 0x80, 0x6d, 0x3a, 0xed, 0x26, 0x1e, 0x65,
- 0xfd, 0x66, 0x1e, 0xba, 0xd2, 0x7a, 0x32, 0xe1, 0xc6, 0x43, 0xc9, 0x47,
- 0xdb, 0x43, 0xb4, 0x8d, 0xc3, 0xf6, 0x45, 0x39, 0xe5, 0xc7, 0xa3, 0x0e,
- 0xc8, 0x45, 0xe5, 0xfe, 0x2c, 0xcf, 0x78, 0x57, 0x73, 0x23, 0xef, 0xa4,
- 0xb9, 0xd6, 0x68, 0x6f, 0x6a, 0xdc, 0xa8, 0xed, 0x9d, 0x74, 0x8b, 0x14,
- 0x7b, 0x3c, 0xef, 0xc2, 0xc9, 0xb7, 0xa2, 0x26, 0xce, 0xd5, 0x7f, 0xd4,
- 0x60, 0x01, 0x00, 0x4c, 0xdb, 0x9f, 0xc0, 0x91, 0xba, 0x4d, 0x7b, 0x4b,
- 0xfb, 0x48, 0xb9, 0xe1, 0xb8, 0xce, 0xff, 0xb4, 0xbd, 0x4b, 0xb0, 0xbd,
- 0xb4, 0x97, 0x47, 0x24, 0xc7, 0x9c, 0x9c, 0xa5, 0xe7, 0x0b, 0x86, 0x4b,
- 0xfb, 0xf7, 0x55, 0xf2, 0x32, 0x5f, 0x21, 0x87, 0xaa, 0xc3, 0x96, 0xb1,
- 0xf6, 0x91, 0x36, 0x6d, 0x0e, 0xf6, 0x9c, 0xb9, 0x5a, 0x5c, 0xab, 0xb2,
- 0x5f, 0x22, 0x15, 0xb7, 0xf0, 0xce, 0x3b, 0x3a, 0x55, 0x82, 0xfe, 0x51,
- 0x9f, 0x20, 0xf7, 0x17, 0xe8, 0x5b, 0x0c, 0xa9, 0x8e, 0x64, 0x7f, 0xc0,
- 0xb5, 0xf7, 0xbc, 0x33, 0x2e, 0xd4, 0xb0, 0xd3, 0xec, 0x01, 0xf2, 0x80,
- 0x8f, 0x63, 0x5d, 0xa6, 0xdc, 0x9b, 0xb4, 0xdd, 0x7f, 0xb7, 0x9c, 0xe1,
- 0xd4, 0xc5, 0x10, 0xf7, 0x36, 0xda, 0xeb, 0x61, 0xa9, 0x46, 0xf9, 0xfe,
- 0x58, 0xaf, 0x10, 0xf7, 0xce, 0x7e, 0xeb, 0xd0, 0xbc, 0x06, 0x59, 0xac,
- 0x01, 0xd7, 0x32, 0x58, 0x03, 0xfe, 0x9f, 0x80, 0xbc, 0xe8, 0x33, 0x10,
- 0x87, 0xf1, 0x7f, 0xcb, 0x3c, 0x9b, 0x75, 0x99, 0xbb, 0x73, 0xe6, 0x7c,
- 0x29, 0xd3, 0xd7, 0x25, 0xa7, 0xf2, 0x5d, 0x92, 0x5c, 0xe5, 0x75, 0x99,
- 0xac, 0x2c, 0xc9, 0x03, 0xce, 0x38, 0xde, 0xf7, 0x86, 0x37, 0xeb, 0xa8,
- 0xaf, 0x32, 0x3a, 0x83, 0x67, 0xcf, 0x8e, 0xf4, 0xc9, 0x9f, 0x5d, 0x47,
- 0x16, 0xd7, 0x6c, 0xc9, 0xdb, 0x69, 0x79, 0x5e, 0x63, 0xf9, 0xf4, 0x4f,
- 0x42, 0xe0, 0xa4, 0xcc, 0xc9, 0xb7, 0x89, 0xf4, 0x38, 0xb1, 0x6d, 0x21,
- 0xa7, 0x6c, 0x81, 0xac, 0xe3, 0x86, 0x37, 0xdb, 0xe6, 0xfa, 0xb1, 0x17,
- 0xc0, 0xdd, 0xdd, 0xb7, 0x7a, 0x83, 0xf8, 0xb0, 0xe1, 0xb7, 0x7f, 0xf0,
- 0xf3, 0x62, 0x69, 0xa9, 0x30, 0x07, 0xa7, 0x38, 0xeb, 0x40, 0x97, 0x98,
- 0xc3, 0x8f, 0x69, 0xdc, 0xa1, 0xa5, 0x4c, 0x8c, 0xba, 0x0a, 0x8c, 0x1a,
- 0x25, 0x76, 0x8d, 0xaf, 0xb9, 0x8c, 0x0b, 0x44, 0xe5, 0xb7, 0x25, 0xe2,
- 0x70, 0x5c, 0x7e, 0x53, 0x7a, 0x16, 0xf3, 0x49, 0x54, 0x19, 0xcf, 0xbc,
- 0x5e, 0x29, 0x90, 0x27, 0x29, 0x9f, 0xcf, 0xba, 0x5f, 0x54, 0x3b, 0x10,
- 0xb7, 0x8a, 0xdd, 0x2d, 0x8a, 0x37, 0x4f, 0x6b, 0x1e, 0x36, 0x6e, 0x0d,
- 0xc8, 0xf5, 0x55, 0xbe, 0x6f, 0x0a, 0x63, 0x47, 0x43, 0xb9, 0x75, 0xda,
- 0xa5, 0x64, 0x6c, 0xc6, 0x3a, 0x20, 0x17, 0xa2, 0x8c, 0x53, 0x8f, 0x11,
- 0x9f, 0x61, 0x0b, 0x87, 0xed, 0x19, 0xd6, 0x38, 0xa9, 0xfd, 0x89, 0x35,
- 0xe1, 0xec, 0xd3, 0x3e, 0xce, 0xf2, 0xda, 0x18, 0x64, 0x4a, 0x5b, 0x94,
- 0xa8, 0x4c, 0x58, 0x49, 0xd8, 0x3c, 0xfc, 0xdf, 0xe0, 0xf8, 0x71, 0xf9,
- 0xc2, 0xc6, 0x45, 0xf0, 0xef, 0x61, 0xfb, 0x1c, 0xed, 0xaa, 0x3d, 0x8a,
- 0x7b, 0xf9, 0xfc, 0x0f, 0x34, 0x8d, 0xf5, 0x69, 0x7f, 0x2c, 0x5e, 0xc7,
- 0x3e, 0x2f, 0x3b, 0x32, 0x5b, 0x62, 0x2e, 0xda, 0xcc, 0x75, 0xef, 0xbd,
- 0x67, 0x77, 0x9e, 0xbb, 0xb0, 0x4c, 0x7e, 0x63, 0xea, 0xdc, 0x8a, 0xe0,
- 0x42, 0x9f, 0xec, 0xe2, 0x33, 0xf9, 0xbc, 0xc3, 0x92, 0x7d, 0x04, 0xf8,
- 0x52, 0xe6, 0xaf, 0xe0, 0xd7, 0xde, 0xc2, 0x5f, 0x89, 0xf6, 0xef, 0x63,
- 0x9b, 0xee, 0xf3, 0xc7, 0xfb, 0x3d, 0x74, 0x28, 0xda, 0x70, 0x3f, 0x63,
- 0x2a, 0x6c, 0xc7, 0xa5, 0xb0, 0xc1, 0xa3, 0xe7, 0x75, 0x39, 0xad, 0x72,
- 0xce, 0xbe, 0xbd, 0x69, 0x8c, 0x13, 0x38, 0x67, 0x38, 0x41, 0xb8, 0x1c,
- 0xf2, 0xb9, 0xc5, 0x9d, 0xe4, 0x4d, 0xfe, 0xff, 0x36, 0x8d, 0xc5, 0xc4,
- 0xad, 0xfe, 0xa6, 0xf7, 0xb8, 0x73, 0xc7, 0x0e, 0xc7, 0x2d, 0x62, 0xe7,
- 0x8f, 0x71, 0x8d, 0x3a, 0xe4, 0x29, 0x8f, 0x8f, 0x80, 0xe7, 0xe7, 0x80,
- 0x05, 0x51, 0xe7, 0xb6, 0x18, 0x8b, 0x4d, 0xae, 0x2d, 0x9b, 0x7a, 0x54,
- 0x72, 0xe0, 0x6b, 0xfb, 0xe6, 0x6a, 0x53, 0xd0, 0x65, 0x8c, 0x7f, 0x90,
- 0xe3, 0x8f, 0xf8, 0xeb, 0x9c, 0x70, 0x0b, 0xd6, 0x87, 0x65, 0x66, 0xd5,
- 0xe8, 0x5f, 0xd6, 0x81, 0xee, 0x1d, 0x46, 0x7b, 0x9d, 0x36, 0xe1, 0xfd,
- 0xc6, 0x09, 0x6c, 0x43, 0x4a, 0x6d, 0xc3, 0xfc, 0x32, 0xf5, 0x93, 0x7a,
- 0x19, 0xe8, 0x63, 0x80, 0x79, 0xd4, 0x51, 0xe2, 0x6c, 0x5a, 0x5e, 0x58,
- 0xe6, 0xda, 0x64, 0x34, 0xa7, 0x35, 0xb4, 0x32, 0xab, 0xf5, 0x3d, 0x83,
- 0xe5, 0xc4, 0x8b, 0x05, 0x19, 0x97, 0xab, 0x2e, 0xd7, 0x2c, 0x51, 0xcd,
- 0x87, 0x3b, 0x1a, 0xde, 0xff, 0x9c, 0xbf, 0x66, 0x29, 0xd5, 0xab, 0xc1,
- 0xf2, 0xe5, 0x1d, 0x79, 0xe7, 0xad, 0xc3, 0x4d, 0xeb, 0x14, 0x70, 0xb8,
- 0xb8, 0x90, 0x3f, 0x44, 0xba, 0xd8, 0x87, 0xcf, 0x25, 0xe7, 0xe3, 0xb3,
- 0x68, 0x5b, 0xef, 0x60, 0x3d, 0x83, 0xd0, 0x8f, 0x8b, 0x3c, 0x62, 0xb8,
- 0x45, 0xde, 0x7a, 0x18, 0xeb, 0x76, 0x50, 0xeb, 0x28, 0xe7, 0xbf, 0xfb,
- 0x1e, 0xfa, 0xe7, 0x7d, 0x7e, 0x9e, 0xc6, 0x78, 0x7c, 0x77, 0xee, 0xa9,
- 0xd2, 0x49, 0xea, 0xe6, 0xa4, 0xe6, 0x03, 0xd9, 0x87, 0xfb, 0x96, 0x6b,
- 0x44, 0x39, 0x5c, 0x8e, 0x19, 0x7b, 0x7a, 0xa2, 0x69, 0x3e, 0x49, 0x7f,
- 0x3e, 0xc1, 0xf5, 0x16, 0x89, 0xf4, 0xa6, 0xb4, 0x96, 0x24, 0x59, 0xa6,
- 0x8f, 0x02, 0x5b, 0x35, 0xcd, 0xb1, 0x6e, 0x8d, 0xbd, 0xf9, 0xff, 0x13,
- 0x7b, 0xf3, 0x56, 0x49, 0xe7, 0xd8, 0xe2, 0xfc, 0x2f, 0x72, 0x6c, 0xac,
- 0xa7, 0x37, 0x72, 0x7b, 0x6e, 0x99, 0xf6, 0x29, 0xa3, 0xb1, 0xe3, 0x3f,
- 0x95, 0xb8, 0x96, 0x9c, 0xe3, 0x55, 0xce, 0x71, 0xbc, 0xae, 0xb5, 0x74,
- 0x0f, 0xe9, 0x9e, 0x5d, 0x5c, 0x26, 0xa6, 0x74, 0xc8, 0x5a, 0x25, 0xc0,
- 0x95, 0x07, 0x7c, 0x4e, 0x5b, 0xec, 0x6e, 0xc5, 0x3e, 0x39, 0xe3, 0x5a,
- 0x5a, 0x47, 0x68, 0x3d, 0xcc, 0x73, 0x03, 0x52, 0x5b, 0xa5, 0x9d, 0x4d,
- 0xc2, 0xaf, 0x88, 0x86, 0x6a, 0xeb, 0xcc, 0x45, 0xb2, 0x4e, 0x64, 0x5c,
- 0x98, 0xbb, 0xcf, 0xd9, 0xf3, 0xd8, 0x5f, 0x31, 0xf8, 0xfd, 0xe4, 0xf0,
- 0x8c, 0x8f, 0x35, 0xcb, 0x7b, 0x74, 0x87, 0x03, 0xee, 0x95, 0xf3, 0x2f,
- 0xb0, 0xde, 0xd4, 0x6b, 0xc7, 0xbe, 0x0e, 0x3b, 0x99, 0x8b, 0xf2, 0xff,
- 0x0c, 0xb8, 0x3f, 0x7d, 0x8d, 0xb8, 0xfa, 0x1a, 0xb5, 0x6a, 0x46, 0x96,
- 0x54, 0xf7, 0x3b, 0xfc, 0x58, 0x52, 0x87, 0xea, 0x07, 0x75, 0x2c, 0xaf,
- 0x9c, 0x7b, 0x54, 0x71, 0xaa, 0x58, 0x1a, 0x36, 0x75, 0x26, 0x76, 0xcc,
- 0xaf, 0x27, 0x6f, 0x7c, 0x7e, 0xcc, 0x7f, 0xfe, 0x5f, 0x7c, 0xf9, 0xda,
- 0x8a, 0x31, 0xba, 0xd6, 0x56, 0x52, 0x7d, 0xcb, 0xf9, 0x65, 0xea, 0x07,
- 0xf5, 0x84, 0x38, 0x17, 0xdc, 0x17, 0xc8, 0x24, 0x68, 0xf3, 0x7e, 0xea,
- 0x7c, 0x63, 0x4d, 0x41, 0xb0, 0x3f, 0x83, 0x73, 0x81, 0x8c, 0x78, 0xad,
- 0xd1, 0x0e, 0x70, 0xaf, 0xc5, 0x21, 0xa7, 0xdd, 0xfd, 0xd6, 0x55, 0xde,
- 0x95, 0x4d, 0xf6, 0x14, 0xe7, 0x7f, 0x99, 0x71, 0x5c, 0xec, 0xb1, 0xfd,
- 0xe4, 0xf3, 0x65, 0x95, 0x4f, 0x1e, 0xf2, 0xe9, 0x52, 0xdc, 0xa7, 0x8f,
- 0x77, 0xc9, 0xd7, 0xb9, 0x0e, 0xac, 0x19, 0xe3, 0xb2, 0xc0, 0xb7, 0xf3,
- 0xc4, 0xf9, 0xbe, 0x3e, 0xe2, 0x0b, 0x63, 0x8a, 0x99, 0xe9, 0x43, 0xc0,
- 0x30, 0xb6, 0x8f, 0x2b, 0x07, 0x31, 0x3e, 0x56, 0x5c, 0x63, 0x8b, 0x61,
- 0x60, 0x72, 0xad, 0x04, 0x7e, 0xc6, 0xba, 0xaf, 0x3d, 0xf2, 0x7a, 0xca,
- 0x5f, 0xaf, 0x89, 0x3e, 0xca, 0x87, 0xfb, 0x80, 0x58, 0xd9, 0x89, 0xf1,
- 0xce, 0x46, 0x53, 0xd0, 0xb1, 0x71, 0x9c, 0x1f, 0x52, 0x1f, 0x22, 0x8c,
- 0x7d, 0xbe, 0x5d, 0xea, 0xf5, 0xfd, 0x36, 0x07, 0x6d, 0xf8, 0xaa, 0xa5,
- 0x2e, 0xfa, 0x11, 0x1a, 0x47, 0x6c, 0x2d, 0xc3, 0x67, 0x05, 0x76, 0xd7,
- 0xd5, 0x06, 0x8d, 0xe0, 0xfa, 0x6d, 0xac, 0x89, 0xd3, 0xda, 0xe0, 0x6d,
- 0x95, 0x19, 0x7d, 0xcd, 0x63, 0xba, 0xa6, 0xb5, 0x52, 0x22, 0xf6, 0xb8,
- 0xf8, 0xe7, 0xa6, 0xf9, 0xdc, 0xc1, 0x86, 0x79, 0x4d, 0xca, 0xd9, 0x1d,
- 0x1b, 0x41, 0xdf, 0x19, 0xbc, 0xbd, 0x62, 0x6c, 0x40, 0xb1, 0x9a, 0xd2,
- 0xfa, 0xa5, 0xf0, 0xd8, 0x06, 0xd6, 0x92, 0x3c, 0xf4, 0x06, 0xb8, 0xf7,
- 0x08, 0xd6, 0x90, 0x5c, 0xdb, 0x9b, 0x5b, 0x70, 0x33, 0xcc, 0x85, 0xc1,
- 0x86, 0xcd, 0x49, 0x0e, 0xbe, 0x40, 0x2e, 0x7c, 0x98, 0x31, 0x64, 0xf0,
- 0xc1, 0x82, 0x1f, 0x6f, 0x1c, 0x61, 0x9c, 0x54, 0x56, 0xd6, 0x39, 0x77,
- 0xee, 0x6f, 0xe3, 0x6f, 0xd7, 0x4a, 0x9c, 0xaf, 0x89, 0x3d, 0xb0, 0x6d,
- 0x95, 0x5d, 0x1c, 0xb9, 0x16, 0x69, 0x1c, 0xef, 0xc5, 0x9e, 0xe0, 0xbd,
- 0x38, 0xae, 0xdf, 0x90, 0x5f, 0xad, 0x06, 0xf6, 0x3c, 0x24, 0x6f, 0x3a,
- 0xde, 0xdc, 0xbc, 0xdb, 0xcd, 0x35, 0x70, 0x0b, 0xcc, 0x65, 0x3b, 0x8e,
- 0x5b, 0x14, 0xcf, 0xab, 0xbb, 0xf5, 0x6e, 0x4b, 0x65, 0x49, 0x0c, 0xf8,
- 0x1a, 0xd6, 0xf0, 0x8d, 0xbb, 0x2d, 0x31, 0xf2, 0xa3, 0x6c, 0xae, 0xfd,
- 0x57, 0xfc, 0x0f, 0x30, 0x90, 0xfa, 0x48, 0xbd, 0xbc, 0x21, 0x53, 0x8a,
- 0xf9, 0xfb, 0xf5, 0x6b, 0xc4, 0x89, 0x80, 0xd3, 0x12, 0xd3, 0xa9, 0x8b,
- 0x31, 0xf5, 0x09, 0x8e, 0x95, 0x9b, 0x71, 0xe1, 0x33, 0x7e, 0x0e, 0x61,
- 0x3f, 0xdd, 0x7b, 0xd4, 0xc7, 0x86, 0x31, 0xe5, 0xcb, 0x19, 0x9b, 0x18,
- 0xc1, 0xf9, 0x1c, 0x94, 0xd9, 0x2b, 0x8d, 0x38, 0x4c, 0x5f, 0xcf, 0xe0,
- 0x87, 0x7e, 0xe3, 0xa1, 0xfc, 0xd7, 0x92, 0xc1, 0x15, 0xf2, 0x25, 0x07,
- 0x58, 0xda, 0x23, 0xf9, 0xe9, 0xb0, 0x24, 0x57, 0x7e, 0xd6, 0x67, 0xf8,
- 0x2d, 0xf5, 0x0f, 0xfb, 0x4d, 0xcf, 0xb1, 0x5d, 0xc7, 0xf9, 0x23, 0xc2,
- 0x67, 0x1b, 0x7d, 0xc6, 0x7e, 0x3e, 0x1f, 0x5c, 0xb3, 0x9b, 0x74, 0xf4,
- 0x5e, 0x5f, 0x47, 0x79, 0xdd, 0x32, 0xb9, 0x0e, 0xdc, 0x3b, 0xb8, 0xc2,
- 0x39, 0x9a, 0x7e, 0x83, 0x2b, 0xc6, 0x47, 0xdf, 0xdb, 0x6f, 0x64, 0xa7,
- 0x1f, 0xae, 0x83, 0xef, 0x9a, 0xb1, 0xa7, 0x46, 0xc1, 0xe3, 0x46, 0x58,
- 0x83, 0x44, 0x9b, 0x3d, 0xe4, 0x4e, 0x09, 0xf5, 0x3d, 0xe1, 0xeb, 0x1c,
- 0xf1, 0xa6, 0xcb, 0xc7, 0x9b, 0x5d, 0x1b, 0x93, 0x33, 0x35, 0x27, 0x8c,
- 0x83, 0x34, 0xd8, 0x18, 0xe9, 0xff, 0x4f, 0x1b, 0x73, 0xc4, 0x1f, 0x27,
- 0xb8, 0x16, 0xe0, 0x4a, 0xd0, 0x0e, 0x70, 0xa5, 0x99, 0xc7, 0x06, 0xb2,
- 0x6f, 0x3c, 0xdf, 0xe8, 0xe7, 0x65, 0x7c, 0x7f, 0xde, 0xd2, 0xfd, 0xf3,
- 0xca, 0x8e, 0x1f, 0x4f, 0x19, 0x27, 0xa0, 0x7a, 0x25, 0xec, 0xed, 0xf7,
- 0xd4, 0x6f, 0x5e, 0xbc, 0x32, 0xa1, 0xb1, 0x9c, 0x9a, 0xca, 0xfa, 0xab,
- 0x58, 0x9f, 0x33, 0xd8, 0x47, 0x0f, 0x46, 0x77, 0xeb, 0x86, 0x56, 0x9f,
- 0xc9, 0xfa, 0xbc, 0x25, 0x23, 0x5d, 0x98, 0x5f, 0x5a, 0xeb, 0xb0, 0xda,
- 0x9d, 0xaf, 0xc8, 0x03, 0x66, 0xee, 0x6d, 0x6d, 0x63, 0xeb, 0xcf, 0xb4,
- 0x7d, 0x2b, 0xd0, 0x73, 0xea, 0xcf, 0xea, 0x33, 0xb3, 0x15, 0x6f, 0x3c,
- 0x72, 0x72, 0xd8, 0x2e, 0x0a, 0x6b, 0xbd, 0xc7, 0xe5, 0x09, 0x97, 0xd7,
- 0x7f, 0x88, 0xeb, 0xd3, 0xf4, 0x21, 0x13, 0x11, 0xfd, 0xfe, 0x20, 0x11,
- 0x7b, 0x0c, 0x7b, 0x6f, 0x46, 0xbf, 0xf7, 0x38, 0xa4, 0x35, 0xe2, 0x35,
- 0x21, 0x97, 0x62, 0x8d, 0xc1, 0xb3, 0xf2, 0xb8, 0x3b, 0xe4, 0xd6, 0xc5,
- 0x70, 0xdc, 0x19, 0xcd, 0xf7, 0x1c, 0x90, 0xc7, 0xdc, 0x48, 0x5b, 0x76,
- 0xcb, 0xe8, 0xfc, 0x44, 0x38, 0xd3, 0xbe, 0xe0, 0x44, 0xdb, 0xa6, 0xb6,
- 0xb0, 0xa7, 0xb7, 0x80, 0xf7, 0x5b, 0xb1, 0x50, 0x6e, 0x83, 0xef, 0x1e,
- 0x36, 0x35, 0x1d, 0xea, 0x5f, 0x11, 0x43, 0xee, 0x93, 0x6d, 0xfb, 0xb8,
- 0x6c, 0xa7, 0xf8, 0x4d, 0xd6, 0x29, 0xb4, 0x07, 0x35, 0xe7, 0xb2, 0x0d,
- 0xbc, 0xd9, 0x4e, 0xb5, 0xa9, 0x0e, 0xaa, 0x1f, 0x06, 0x9c, 0xda, 0xb6,
- 0x89, 0x4f, 0x77, 0xf0, 0x88, 0x77, 0x9e, 0x83, 0x1c, 0x58, 0xef, 0x71,
- 0x02, 0x6d, 0xe2, 0x9a, 0xdd, 0x74, 0xbe, 0x1f, 0xed, 0xbb, 0x31, 0x46,
- 0xab, 0xbe, 0xa3, 0xe5, 0x9c, 0x34, 0x79, 0xcc, 0x3d, 0xf7, 0x74, 0x36,
- 0xb5, 0x3f, 0x77, 0xd4, 0x7c, 0x6f, 0xf4, 0x3d, 0xca, 0xb8, 0x90, 0x91,
- 0xbf, 0xc5, 0xf6, 0xb6, 0x97, 0xfb, 0xf6, 0xb6, 0x0f, 0x4b, 0x7b, 0x0f,
- 0x45, 0xd1, 0xdd, 0x74, 0x5f, 0xa0, 0x43, 0x41, 0xfb, 0x28, 0x71, 0x85,
- 0x76, 0x4b, 0x7d, 0xa6, 0xed, 0x28, 0x9f, 0xb5, 0xd8, 0xd4, 0x87, 0xff,
- 0xd9, 0x87, 0x7d, 0x19, 0xbf, 0xfb, 0xbe, 0xd1, 0x33, 0x8b, 0xbe, 0x3f,
- 0xe3, 0x17, 0xd4, 0xd3, 0xfd, 0xfc, 0xa9, 0x84, 0x7e, 0x1f, 0xb4, 0xbf,
- 0xae, 0x05, 0x38, 0x12, 0xf3, 0x63, 0x0a, 0x26, 0xef, 0x64, 0xe2, 0xbe,
- 0x94, 0x9d, 0xe6, 0x9d, 0x62, 0xd7, 0x21, 0xe7, 0x0b, 0x90, 0xf3, 0x64,
- 0x98, 0xbe, 0x1f, 0xf3, 0x4b, 0x8e, 0xe4, 0xb6, 0x28, 0x6f, 0xda, 0x75,
- 0xea, 0x26, 0x78, 0xc4, 0x16, 0x31, 0xc5, 0x02, 0x07, 0xca, 0x60, 0x8e,
- 0xaf, 0xe1, 0xbc, 0xe5, 0xd7, 0x6f, 0xa4, 0x61, 0xd3, 0x5c, 0xfc, 0x28,
- 0x77, 0xf8, 0xf4, 0x6b, 0x94, 0x31, 0xeb, 0xd9, 0x18, 0x0b, 0xe0, 0xfc,
- 0x98, 0x63, 0x77, 0xa1, 0xd3, 0x13, 0xd0, 0xdd, 0x88, 0x38, 0xe5, 0x13,
- 0x52, 0x98, 0x9e, 0x50, 0xfb, 0x3f, 0x08, 0xfb, 0x34, 0xef, 0x66, 0x65,
- 0xe1, 0xe5, 0x3b, 0xb1, 0x4f, 0xe9, 0xe7, 0x6b, 0x0c, 0xc3, 0x6b, 0x51,
- 0x9d, 0x26, 0xe7, 0x60, 0xdc, 0xcd, 0xe4, 0x92, 0xfd, 0xef, 0xaa, 0xfa,
- 0xe5, 0x70, 0x56, 0x2a, 0x57, 0x6c, 0xad, 0x85, 0xc9, 0xc8, 0x7b, 0x1e,
- 0x65, 0x38, 0x73, 0x3e, 0x0e, 0x9c, 0x22, 0x77, 0xff, 0x60, 0xd4, 0xac,
- 0xe9, 0x5f, 0xfb, 0xe9, 0x03, 0x27, 0xcb, 0x8d, 0x63, 0x68, 0xfd, 0x0c,
- 0xae, 0x3d, 0x74, 0xd4, 0xec, 0x1f, 0xfa, 0xc3, 0x37, 0xbd, 0x4c, 0x94,
- 0xcf, 0xe4, 0xbd, 0xcc, 0xd1, 0x52, 0x57, 0x38, 0xb7, 0x77, 0x7d, 0xbd,
- 0xfe, 0x28, 0xc6, 0x8b, 0xcb, 0xe0, 0xe6, 0x84, 0xfa, 0xf1, 0xf3, 0x7b,
- 0x7c, 0x56, 0x13, 0x1f, 0x30, 0x7e, 0xeb, 0x1b, 0xf2, 0xd8, 0x06, 0xe5,
- 0x44, 0xfb, 0x1e, 0x92, 0x1f, 0x39, 0xc3, 0xf6, 0x93, 0x5a, 0x77, 0x9c,
- 0xc8, 0x30, 0x1f, 0x73, 0xd0, 0x49, 0xda, 0x6b, 0x12, 0x19, 0xfd, 0x98,
- 0xf0, 0x9b, 0x16, 0xd6, 0x7a, 0x0c, 0xbb, 0x4f, 0x4a, 0x50, 0xef, 0x31,
- 0x94, 0x39, 0x10, 0xfa, 0xa7, 0xf7, 0xc6, 0x79, 0xde, 0x63, 0xea, 0x3d,
- 0x24, 0x44, 0xb9, 0xfd, 0xf1, 0x0e, 0x7e, 0xe3, 0xb9, 0x37, 0xde, 0x77,
- 0xff, 0xd3, 0xe7, 0xd2, 0x89, 0x25, 0xfa, 0xac, 0x2d, 0xce, 0xbf, 0xfa,
- 0xcd, 0xbb, 0x16, 0x0a, 0x9d, 0xa2, 0xf9, 0xb2, 0x4b, 0xef, 0x38, 0xac,
- 0x7b, 0x48, 0xc4, 0x0e, 0x58, 0x8c, 0x7b, 0x13, 0xdf, 0x98, 0x43, 0x61,
- 0x8c, 0x0d, 0x6d, 0x70, 0x86, 0x97, 0x46, 0x2c, 0xb9, 0x3f, 0x92, 0x89,
- 0x5b, 0x72, 0x2c, 0xbe, 0x22, 0x78, 0x26, 0xf3, 0x29, 0x1b, 0x89, 0x02,
- 0xef, 0x8f, 0x94, 0x39, 0x5e, 0x5c, 0xfd, 0x93, 0xe4, 0x31, 0xcf, 0xbb,
- 0xe4, 0x4a, 0x28, 0x79, 0xd7, 0xdb, 0x1e, 0x73, 0xde, 0xd6, 0xe6, 0xfb,
- 0xd5, 0x23, 0x10, 0x37, 0x16, 0x9e, 0x32, 0xb5, 0x87, 0x4b, 0x97, 0x06,
- 0x37, 0xf4, 0x9b, 0xb9, 0x69, 0xd3, 0x2e, 0xa1, 0xdd, 0xea, 0xd7, 0x41,
- 0x55, 0x2e, 0x0d, 0x56, 0x8f, 0xdc, 0x6e, 0xfc, 0x6d, 0xf2, 0xab, 0xc0,
- 0x87, 0x89, 0xef, 0xa9, 0x0b, 0x3b, 0xbb, 0x7c, 0x26, 0x74, 0x66, 0xd9,
- 0x5a, 0x6d, 0x63, 0x0e, 0xec, 0x94, 0x27, 0xdd, 0x27, 0x83, 0x38, 0x15,
- 0xe3, 0x5a, 0x22, 0x9d, 0x9b, 0x13, 0x26, 0xe7, 0xb1, 0x69, 0x29, 0x17,
- 0xea, 0x7a, 0x89, 0xb1, 0xaa, 0xa8, 0x62, 0x43, 0xf7, 0x26, 0xeb, 0xc1,
- 0x7a, 0x64, 0x46, 0x31, 0xa3, 0x47, 0xf1, 0xc0, 0xe8, 0x5d, 0x97, 0xc6,
- 0x61, 0xc9, 0x97, 0xae, 0x2d, 0xbb, 0x03, 0xac, 0xe1, 0x79, 0x75, 0xf9,
- 0x09, 0xb4, 0x89, 0x33, 0xf7, 0x34, 0x9d, 0x6f, 0xcc, 0xc9, 0x26, 0xec,
- 0x41, 0xab, 0x39, 0x1f, 0xcb, 0x73, 0xcd, 0x79, 0xd8, 0x57, 0x25, 0xdf,
- 0xcb, 0xdc, 0x6b, 0x10, 0x6f, 0x77, 0xfd, 0x78, 0xfb, 0x87, 0x06, 0xa8,
- 0x83, 0xf0, 0x6f, 0xf2, 0x91, 0xb1, 0xb6, 0x91, 0xf9, 0x52, 0xf8, 0x1f,
- 0xbb, 0xb1, 0x53, 0xb4, 0x37, 0x76, 0xf2, 0xe3, 0xb8, 0xf6, 0x25, 0x70,
- 0x92, 0x22, 0xf8, 0x45, 0xc1, 0xaf, 0xc3, 0xe7, 0xf5, 0x9d, 0xfe, 0xb7,
- 0x98, 0xd3, 0x41, 0xcd, 0xad, 0x0f, 0xee, 0xc9, 0xad, 0xdf, 0x35, 0xc0,
- 0xda, 0xe3, 0xe2, 0xd6, 0x6e, 0xdf, 0x88, 0xdf, 0x77, 0xe2, 0x96, 0xef,
- 0x63, 0xf6, 0x4c, 0x51, 0xf7, 0xcc, 0x65, 0x8d, 0x11, 0xcf, 0x6f, 0x2d,
- 0xc9, 0x8c, 0xd3, 0x25, 0xb9, 0xd5, 0xc0, 0x4e, 0x78, 0xe3, 0xb3, 0x6e,
- 0xa1, 0x2f, 0x2c, 0xec, 0xcf, 0xe7, 0x29, 0x47, 0x8b, 0xe5, 0xc2, 0x1c,
- 0xff, 0x90, 0x44, 0xc6, 0x68, 0x3b, 0x68, 0x13, 0x3e, 0x05, 0x2c, 0x03,
- 0x4f, 0xdf, 0x6a, 0xcc, 0x7d, 0xbf, 0x9f, 0x1c, 0x29, 0xc3, 0xe0, 0x9d,
- 0x0b, 0x5e, 0x2b, 0xf6, 0xdf, 0x31, 0xd6, 0xb4, 0xec, 0xcc, 0x95, 0x36,
- 0x4b, 0x6d, 0x93, 0xbe, 0xc7, 0x94, 0xff, 0x1e, 0x61, 0xcc, 0x67, 0xb6,
- 0x14, 0xdc, 0x33, 0x27, 0xc7, 0x4f, 0x25, 0x62, 0x49, 0x4b, 0xe7, 0xa5,
- 0xf6, 0x2b, 0xeb, 0xce, 0xc1, 0x2e, 0xd1, 0x86, 0x29, 0xae, 0x81, 0xab,
- 0x12, 0xd7, 0x68, 0x9f, 0xd4, 0xa6, 0xc5, 0x8b, 0x98, 0x67, 0x6e, 0x4b,
- 0xf3, 0x0f, 0xb1, 0xd3, 0xe1, 0x44, 0x65, 0x46, 0xb1, 0x0e, 0x7c, 0x55,
- 0xe7, 0x0e, 0x7b, 0x1c, 0x6a, 0xcc, 0x2d, 0xd1, 0xbf, 0x64, 0x1e, 0xa6,
- 0x43, 0xb2, 0x15, 0x91, 0x57, 0xa0, 0xdf, 0x57, 0xd7, 0xb9, 0xe7, 0xc2,
- 0xbd, 0xc6, 0x47, 0xac, 0xdf, 0x63, 0x49, 0xaf, 0xe6, 0x6b, 0x8b, 0x58,
- 0x2f, 0xf0, 0xab, 0xf1, 0xf0, 0x29, 0xf8, 0x09, 0x5a, 0x27, 0xc1, 0x18,
- 0xeb, 0x2c, 0x7c, 0xca, 0xc6, 0xb8, 0x10, 0x30, 0x62, 0x9a, 0xe7, 0x67,
- 0xc0, 0x8b, 0x77, 0x73, 0x35, 0xc5, 0xea, 0x82, 0xc6, 0x63, 0x6b, 0xeb,
- 0x1d, 0x6a, 0x2f, 0x6a, 0xd5, 0x3e, 0xac, 0x8b, 0x1c, 0xb7, 0xc6, 0x8a,
- 0xfe, 0xf9, 0x16, 0xa9, 0x56, 0xd9, 0x96, 0x81, 0x56, 0xd5, 0x97, 0x20,
- 0x1f, 0x65, 0xcb, 0x1a, 0xb8, 0x6e, 0x75, 0xc3, 0xc1, 0x2f, 0x85, 0xdf,
- 0x08, 0x7e, 0x0f, 0x4a, 0xb6, 0x4c, 0xfe, 0xcd, 0xfc, 0x53, 0x47, 0xd3,
- 0xf3, 0x5b, 0xf4, 0xfb, 0x11, 0xd6, 0xb4, 0x15, 0x7d, 0x3f, 0xad, 0x58,
- 0xdd, 0x8f, 0x9b, 0x32, 0xbe, 0x9b, 0xf2, 0xb1, 0xee, 0xa7, 0x7e, 0x6d,
- 0xed, 0xbf, 0x01, 0x17, 0x24, 0x5e, 0x9d, 0xe0, 0x70, 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_RXP_b06FwRodata[(0x24/4) + 1] = {
- 0x08004c28, 0x08004c28, 0x08004ba0, 0x08004bd8, 0x08004c0c, 0x08004c30,
- 0x08004c30, 0x08004c30, 0x08004b10, 0x00000000 };
-
-static struct fw_info bnx2_rxp_fw_06 = {
- /* Firmware version: 4.6.16 */
- .ver_major = 0x4,
- .ver_minor = 0x6,
- .ver_fix = 0x10,
-
- .start_addr = 0x080031d8,
-
- .text_addr = 0x08000000,
- .text_len = 0x70dc,
- .text_index = 0x0,
- .gz_text = bnx2_RXP_b06FwText,
- .gz_text_len = sizeof(bnx2_RXP_b06FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_RXP_b06FwData,
-
- .sbss_addr = 0x08007120,
- .sbss_len = 0x54,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08007178,
- .bss_len = 0x450,
- .bss_index = 0x0,
-
- .rodata_addr = 0x080070dc,
- .rodata_len = 0x24,
- .rodata_index = 0x0,
- .rodata = bnx2_RXP_b06FwRodata,
-};
-
/* Initialized Values for the RX Processor. */
static const struct cpu_reg cpu_reg_rxp = {
.mode = BNX2_RXP_CPU_MODE,
@@ -2965,595 +55,6 @@ static const struct cpu_reg cpu_reg_rxp = {
.mips_view_base = 0x8000000,
};
-static u8 bnx2_rv2p_proc1[] = {
- /* Date: 02/03/2009 14:20 */
- 0xa5, 0x56, 0x4f, 0x68, 0x14, 0x67, 0x14, 0x7f, 0x33, 0xbb, 0xb3, 0xb3,
- 0x99, 0x9d, 0xd9, 0xdd, 0x92, 0x18, 0x96, 0x18, 0xcc, 0x1a, 0x84, 0x92,
- 0x75, 0xb7, 0x6e, 0x6c, 0x0f, 0x42, 0x03, 0x29, 0xb9, 0x08, 0x35, 0x87,
- 0x12, 0x11, 0x8a, 0x2d, 0x68, 0xb7, 0x22, 0x14, 0x0a, 0xa5, 0x07, 0x8f,
- 0xa5, 0x83, 0x71, 0x53, 0x5a, 0xbc, 0xe4, 0xd0, 0x80, 0x42, 0x35, 0x27,
- 0x5b, 0x62, 0x0e, 0x3b, 0xe0, 0xa1, 0x88, 0xe0, 0x41, 0x8f, 0x7a, 0xaa,
- 0x7f, 0x5a, 0x28, 0x46, 0x29, 0xb5, 0x87, 0x82, 0xc7, 0xde, 0x9a, 0xe9,
- 0xf7, 0xfe, 0x7c, 0xbb, 0x33, 0x5f, 0x66, 0x13, 0xa1, 0x42, 0xfc, 0xf1,
- 0xbd, 0x79, 0xef, 0xfb, 0xde, 0x9f, 0xdf, 0x7b, 0x6f, 0xab, 0x00, 0x60,
- 0x43, 0x18, 0x4d, 0x29, 0x04, 0x2b, 0x67, 0x15, 0x11, 0x00, 0x36, 0x81,
- 0xff, 0x39, 0x3e, 0x9d, 0xc3, 0x23, 0x72, 0x3e, 0xcc, 0x10, 0x1e, 0xae,
- 0xaa, 0xff, 0x3f, 0x85, 0xf9, 0x3a, 0x62, 0x0e, 0xe6, 0x0f, 0x22, 0x1e,
- 0x85, 0xbb, 0xf5, 0x9a, 0xc2, 0x7f, 0x63, 0x08, 0xf1, 0x1c, 0xf4, 0x7e,
- 0x8e, 0x4a, 0x74, 0xff, 0x96, 0xd8, 0xff, 0x9a, 0x63, 0x3c, 0xd6, 0xac,
- 0x12, 0x3e, 0x5a, 0xc5, 0xf7, 0x4e, 0x9d, 0x82, 0x02, 0xda, 0x5d, 0x50,
- 0x17, 0x23, 0x96, 0xd4, 0x83, 0x45, 0xb2, 0x03, 0xbb, 0xa2, 0x70, 0x12,
- 0x9e, 0x2f, 0xa0, 0xfe, 0x1b, 0xde, 0xa5, 0x55, 0xc4, 0x12, 0x74, 0x9a,
- 0xa8, 0x77, 0x00, 0xb2, 0xf5, 0x6a, 0x4a, 0x0f, 0xe5, 0x11, 0x84, 0x4d,
- 0xc4, 0x11, 0x80, 0x56, 0xf2, 0x3d, 0xd7, 0x0a, 0x5b, 0x68, 0xff, 0x85,
- 0xbc, 0xb7, 0x4f, 0xee, 0x51, 0x71, 0x47, 0x88, 0x3d, 0xb1, 0x53, 0x7f,
- 0x2d, 0x96, 0xb3, 0xfe, 0x67, 0x4a, 0x4f, 0xc7, 0xe3, 0x73, 0xde, 0xa6,
- 0x38, 0x1e, 0x57, 0xe2, 0x79, 0xb6, 0xaa, 0xf3, 0x86, 0xfa, 0xbf, 0xc7,
- 0x69, 0x7d, 0xd8, 0x43, 0xff, 0x89, 0xd2, 0x4f, 0xdf, 0xcb, 0xf2, 0x5f,
- 0x06, 0xf2, 0x99, 0xf4, 0xf7, 0xad, 0x06, 0xfa, 0xe7, 0x00, 0x34, 0x24,
- 0x8f, 0xa4, 0xff, 0x30, 0xe6, 0x78, 0xe6, 0xe0, 0x90, 0x5d, 0x23, 0xbd,
- 0x3c, 0xd4, 0x28, 0x3f, 0x1c, 0xef, 0x01, 0xc1, 0x25, 0xc1, 0x6b, 0x82,
- 0x3f, 0x08, 0xc2, 0xff, 0xc4, 0xad, 0x21, 0xf2, 0x7d, 0x82, 0xfb, 0x0d,
- 0xf9, 0x2d, 0xc1, 0xb7, 0x0c, 0x7b, 0xcf, 0x62, 0x7c, 0xac, 0xbf, 0xcb,
- 0xf9, 0x5d, 0xc3, 0xfe, 0x4b, 0xe0, 0xfc, 0x58, 0x46, 0xde, 0x36, 0x85,
- 0x87, 0x58, 0x77, 0xf9, 0x3e, 0xa3, 0xf5, 0x84, 0x37, 0x8d, 0xa4, 0xfe,
- 0x8d, 0x5d, 0xf4, 0x59, 0x6d, 0x61, 0x26, 0xcb, 0xee, 0x7a, 0x2c, 0x79,
- 0x14, 0x7b, 0xaf, 0x77, 0x67, 0x08, 0xef, 0xe7, 0x32, 0x79, 0x3f, 0x2e,
- 0x71, 0xa8, 0xa6, 0x23, 0xfb, 0xdb, 0x16, 0xf3, 0xdb, 0x11, 0x5e, 0xee,
- 0xc6, 0x63, 0xe1, 0xd5, 0x8c, 0xe6, 0x57, 0x9a, 0x57, 0xcc, 0x8f, 0x82,
- 0xc1, 0x8f, 0x6f, 0xf7, 0xc8, 0x4b, 0xc9, 0x88, 0x6f, 0x39, 0xd6, 0xf9,
- 0xb6, 0x45, 0x7c, 0xb1, 0x50, 0xa5, 0x7b, 0xbf, 0x8b, 0xe8, 0x38, 0xe6,
- 0xaf, 0xe0, 0x39, 0x0f, 0x97, 0x23, 0x6d, 0x27, 0xfd, 0xd4, 0xd0, 0xef,
- 0xb0, 0x7d, 0x20, 0x9f, 0x6d, 0x47, 0xfb, 0xc9, 0x72, 0x0f, 0xf0, 0x3c,
- 0xda, 0x5b, 0x37, 0xf2, 0x56, 0xa7, 0xb8, 0x41, 0xe2, 0x07, 0x23, 0x7e,
- 0x9d, 0xbf, 0x57, 0xc2, 0xf7, 0x49, 0x95, 0x0f, 0xfe, 0x3e, 0x05, 0xfa,
- 0x7e, 0x9c, 0x0b, 0x45, 0x38, 0x7b, 0xbc, 0x42, 0xfe, 0x94, 0x0b, 0x7c,
- 0xcd, 0x87, 0x15, 0xc6, 0x73, 0x1e, 0xe3, 0x9f, 0x9e, 0xca, 0x2d, 0xc4,
- 0xf1, 0xf9, 0x12, 0x9f, 0x3f, 0x09, 0xf0, 0xde, 0x51, 0xf5, 0xb0, 0xb6,
- 0xd7, 0x7e, 0xed, 0xe6, 0x0f, 0xbe, 0xaf, 0xdf, 0xd1, 0x7e, 0xe8, 0xf7,
- 0xd2, 0x75, 0x19, 0xfe, 0x2e, 0x63, 0xc7, 0x4e, 0xe7, 0x21, 0x3f, 0xcb,
- 0x78, 0xb5, 0x4d, 0x50, 0x5b, 0xf3, 0xd9, 0xee, 0x8a, 0x9f, 0xc7, 0xf3,
- 0x3b, 0x57, 0x1e, 0xe0, 0xfd, 0xf6, 0xd1, 0xb5, 0x48, 0xfc, 0xab, 0xe8,
- 0xba, 0x92, 0x1c, 0xa6, 0x81, 0xcf, 0x4b, 0xc2, 0x93, 0x25, 0xe2, 0x71,
- 0x59, 0x7d, 0x42, 0x9c, 0x80, 0xd0, 0x26, 0x3d, 0xef, 0x3e, 0xd9, 0xe7,
- 0x44, 0xae, 0xea, 0x37, 0x9d, 0xe6, 0xff, 0x16, 0xf3, 0xa2, 0x98, 0xe6,
- 0xd3, 0x7c, 0x62, 0xce, 0x25, 0xf3, 0x61, 0xf5, 0x79, 0xb4, 0xb3, 0x8e,
- 0xe9, 0x7a, 0x3d, 0x5a, 0xd5, 0xf9, 0x61, 0xbe, 0xb2, 0x9e, 0x2a, 0x56,
- 0x8b, 0xd5, 0xc3, 0xb6, 0x24, 0x72, 0x56, 0xbe, 0xb7, 0x4c, 0xde, 0x66,
- 0xf1, 0xbe, 0x6a, 0xf0, 0xb8, 0x21, 0xbc, 0x1f, 0xe9, 0xad, 0xbf, 0xd6,
- 0x7e, 0xb8, 0x29, 0xbc, 0xaf, 0x0e, 0xf6, 0xc3, 0x26, 0xed, 0x27, 0x75,
- 0x26, 0xf5, 0x5e, 0x98, 0x4b, 0xd5, 0xe9, 0x3d, 0xc8, 0xec, 0xef, 0xab,
- 0x72, 0x4f, 0x5b, 0xfa, 0xbc, 0x90, 0xd8, 0x23, 0xa4, 0x5e, 0x06, 0xf2,
- 0xc3, 0x35, 0xfa, 0x74, 0x2c, 0x96, 0x77, 0x54, 0xbf, 0x65, 0xc5, 0xeb,
- 0xc2, 0x5f, 0xc2, 0x83, 0x0e, 0xf5, 0x93, 0x33, 0xf6, 0xf9, 0xed, 0x54,
- 0x9d, 0x00, 0x0e, 0xea, 0xfd, 0x90, 0xf4, 0x2b, 0xb9, 0xdf, 0xf0, 0xbe,
- 0x1a, 0x74, 0x66, 0x93, 0x7b, 0xee, 0x72, 0xbf, 0xdf, 0x03, 0xea, 0xa3,
- 0xf2, 0x8e, 0xbe, 0xd4, 0xf3, 0xac, 0xde, 0x4c, 0xf6, 0xf7, 0x98, 0xcc,
- 0x2f, 0x5b, 0xf6, 0x73, 0xc9, 0x8c, 0x53, 0xed, 0xbd, 0xec, 0x7a, 0x71,
- 0xbc, 0xff, 0x6c, 0xbf, 0xde, 0xbc, 0xdb, 0xab, 0xee, 0x9e, 0x51, 0xf7,
- 0xbf, 0xb7, 0x75, 0x1e, 0x6d, 0x27, 0x6b, 0xbf, 0x7f, 0xa0, 0xee, 0x15,
- 0x7d, 0x99, 0x1b, 0x67, 0xea, 0x59, 0x7c, 0x2d, 0xee, 0xd0, 0x4b, 0xcf,
- 0x2f, 0xed, 0xe7, 0xc6, 0x06, 0xd7, 0xfd, 0xa3, 0xb8, 0xbf, 0x97, 0x52,
- 0xf3, 0x75, 0x44, 0xea, 0xac, 0xf4, 0xc8, 0xbf, 0xa7, 0xdb, 0x83, 0x79,
- 0x9c, 0xe4, 0xcd, 0x49, 0xe1, 0xab, 0x3d, 0xb7, 0x4e, 0xfd, 0xe1, 0x76,
- 0x5e, 0x1a, 0x75, 0x98, 0x6d, 0x62, 0xfd, 0xbf, 0x86, 0x48, 0xfc, 0xfc,
- 0x2d, 0xe5, 0x6f, 0x20, 0xfd, 0x55, 0x80, 0x9f, 0x22, 0x1d, 0x97, 0xae,
- 0x1b, 0xe3, 0x8f, 0x4d, 0xe9, 0x93, 0x7e, 0x7c, 0xf8, 0xee, 0xa2, 0xbc,
- 0x5b, 0x85, 0x1b, 0x91, 0x9e, 0x63, 0x38, 0xd7, 0x5c, 0x68, 0xcb, 0xdc,
- 0x3c, 0x2b, 0xf3, 0xeb, 0x85, 0xc7, 0xf3, 0xb1, 0x73, 0x82, 0x78, 0x08,
- 0xe3, 0x32, 0xc7, 0x3a, 0x01, 0x9f, 0x27, 0x02, 0xfe, 0x7d, 0xd8, 0x76,
- 0x7d, 0xd2, 0x9b, 0x08, 0x18, 0xc7, 0x4b, 0x68, 0x57, 0x83, 0x3f, 0x16,
- 0x49, 0xbd, 0x39, 0x98, 0x63, 0xe6, 0xfc, 0x92, 0x38, 0xdf, 0x46, 0xb9,
- 0xda, 0x93, 0xd3, 0x7c, 0xe6, 0x3a, 0xfb, 0x7d, 0x5e, 0x5f, 0x97, 0xaa,
- 0xd4, 0x2b, 0xc9, 0x3c, 0xeb, 0x3e, 0xba, 0x69, 0xe4, 0x57, 0xd7, 0xe7,
- 0xcd, 0x58, 0xcf, 0xf7, 0xe9, 0xe3, 0xe8, 0x6f, 0x05, 0xca, 0x2e, 0xf3,
- 0x82, 0x51, 0xdd, 0x63, 0xbb, 0x68, 0x36, 0xd9, 0x95, 0x79, 0xd8, 0xbd,
- 0x48, 0xd7, 0x2c, 0x76, 0xb5, 0x7c, 0x81, 0x1a, 0x61, 0x69, 0xe3, 0x1e,
- 0xc9, 0xcb, 0x51, 0x8e, 0xe5, 0xee, 0x09, 0x9d, 0xaf, 0x0a, 0xc5, 0xbf,
- 0xc6, 0xf9, 0xfa, 0xf8, 0x7b, 0xc6, 0xd3, 0xf0, 0x3e, 0xa1, 0x37, 0x98,
- 0xe3, 0x45, 0x42, 0x08, 0x92, 0x73, 0xdc, 0x51, 0xee, 0x55, 0xc9, 0x9f,
- 0x41, 0xfd, 0xcc, 0xfd, 0xb8, 0x5b, 0x1d, 0x47, 0x13, 0xfc, 0xd3, 0x75,
- 0x34, 0xe7, 0x39, 0xf1, 0xc4, 0xe0, 0x63, 0x77, 0x08, 0x1f, 0xad, 0x21,
- 0x7c, 0x36, 0xe7, 0xd6, 0x57, 0xd2, 0xc7, 0x79, 0x70, 0x72, 0xb4, 0x70,
- 0xfd, 0xfc, 0x32, 0xd5, 0xd5, 0xee, 0xf2, 0x0f, 0x08, 0xdf, 0x59, 0xb1,
- 0x28, 0x5f, 0xfe, 0x0a, 0xeb, 0xe5, 0x59, 0x5e, 0xd3, 0xf8, 0xcd, 0xb2,
- 0xfe, 0xbd, 0xf1, 0x1f, 0xb6, 0x34, 0x9b, 0xb9, 0xa0, 0x0c, 0x00, 0x00,
- 0x00 };
-
-static u8 bnx2_rv2p_proc2[] = {
- /* Date: 02/03/2009 14:20 */
- 0xad, 0x57, 0x4d, 0x68, 0x5c, 0x55, 0x14, 0x3e, 0xf3, 0xe6, 0xef, 0xcd,
- 0xcc, 0x9b, 0xcc, 0x34, 0x8d, 0x93, 0x31, 0x29, 0x26, 0x4d, 0x68, 0xea,
- 0xc8, 0x44, 0xf3, 0x47, 0x05, 0x5d, 0x18, 0x46, 0x48, 0x7f, 0x2c, 0x34,
- 0x8d, 0x2e, 0x8a, 0x9b, 0x36, 0x53, 0x3b, 0x3a, 0x6d, 0xed, 0xc2, 0xec,
- 0xdc, 0xf8, 0xb0, 0x35, 0x41, 0x98, 0x45, 0x53, 0x4c, 0x13, 0x44, 0xa8,
- 0xe8, 0xce, 0xdd, 0x88, 0x9a, 0xd6, 0x8d, 0x50, 0x68, 0x28, 0x76, 0x51,
- 0x04, 0x05, 0xed, 0x42, 0x10, 0xad, 0xa1, 0x15, 0x41, 0x51, 0xb3, 0x92,
- 0x8c, 0xf7, 0x9e, 0xef, 0xdc, 0x37, 0xef, 0x4d, 0xa6, 0xa4, 0x0b, 0x67,
- 0xf3, 0xe5, 0xdc, 0x77, 0xee, 0xb9, 0xe7, 0xe7, 0x3b, 0xe7, 0xde, 0x64,
- 0x89, 0x28, 0x42, 0x6e, 0xbd, 0x4f, 0x21, 0x85, 0xc2, 0x21, 0x5b, 0x41,
- 0x83, 0x28, 0x9a, 0xd7, 0x32, 0x59, 0x24, 0xbf, 0x27, 0xb2, 0x0c, 0xdf,
- 0xd6, 0x1d, 0xad, 0x46, 0x6e, 0x41, 0xeb, 0xd9, 0xf4, 0x92, 0x05, 0xbd,
- 0x08, 0x69, 0x54, 0x3a, 0xae, 0xc6, 0x1d, 0x82, 0xcf, 0x08, 0x46, 0x42,
- 0xc0, 0xb0, 0xa0, 0xd5, 0x82, 0x24, 0x7a, 0x5d, 0x22, 0x6f, 0x8a, 0xec,
- 0x08, 0xe6, 0x65, 0xfd, 0xb4, 0xe0, 0xab, 0xb2, 0x7e, 0x47, 0x70, 0x5d,
- 0xa1, 0xf1, 0x53, 0xcb, 0xbf, 0x35, 0x9a, 0xb2, 0x03, 0xf3, 0x05, 0xf8,
- 0xff, 0x62, 0x3f, 0xeb, 0x37, 0x82, 0xfa, 0x77, 0x1b, 0xc6, 0x0f, 0x13,
- 0xaf, 0x15, 0xd5, 0xfa, 0xbb, 0x27, 0x2e, 0x2f, 0x62, 0xdf, 0xf1, 0x7e,
- 0xac, 0x3f, 0x56, 0xd4, 0x71, 0xc7, 0xc8, 0x15, 0xa4, 0x61, 0x9b, 0xe3,
- 0x70, 0x87, 0x4d, 0xa2, 0xa0, 0xff, 0xe3, 0x22, 0xa4, 0xd9, 0x34, 0xec,
- 0x26, 0x03, 0x76, 0x73, 0x5b, 0xec, 0x7e, 0x9f, 0xf0, 0xdb, 0xff, 0x54,
- 0xec, 0x27, 0xb7, 0xb5, 0x5f, 0x4e, 0x03, 0x77, 0x16, 0xdb, 0x9d, 0x93,
- 0xd8, 0xc6, 0xff, 0xd3, 0xdb, 0xda, 0x7f, 0xd3, 0xf3, 0xdf, 0xac, 0x03,
- 0xfb, 0xf0, 0xf9, 0x13, 0xf7, 0x29, 0x93, 0x47, 0x13, 0xaf, 0xf8, 0x15,
- 0x06, 0x4e, 0x16, 0x19, 0x6a, 0x27, 0x25, 0xb1, 0x53, 0x43, 0xfa, 0xbc,
- 0x4e, 0x8a, 0x58, 0xda, 0xce, 0x5e, 0x3b, 0x76, 0x0d, 0xeb, 0xc7, 0x32,
- 0xc0, 0x57, 0x24, 0x80, 0xbb, 0x49, 0x9d, 0x90, 0x46, 0xa3, 0x92, 0x12,
- 0xfb, 0x28, 0x23, 0xb9, 0x29, 0xec, 0x5f, 0x73, 0xb4, 0x5f, 0xb7, 0x54,
- 0xdd, 0xb4, 0x1c, 0x26, 0x37, 0x13, 0xf4, 0xff, 0x0a, 0x41, 0x6f, 0xc7,
- 0x5e, 0xac, 0x5e, 0xac, 0x40, 0xee, 0xfd, 0x38, 0xcb, 0xfa, 0x2b, 0x75,
- 0x13, 0x87, 0x5e, 0x57, 0xfc, 0xcf, 0xc0, 0x0e, 0x0d, 0xd8, 0x7c, 0x18,
- 0xf2, 0xa3, 0x0e, 0x1d, 0x36, 0xf6, 0xf0, 0xbb, 0xbc, 0xc7, 0xf0, 0x09,
- 0x72, 0x25, 0xc6, 0x90, 0x9f, 0x9d, 0xd7, 0xfe, 0x66, 0xe8, 0x84, 0xa5,
- 0x1d, 0xb1, 0x24, 0xbe, 0xb0, 0xed, 0x7c, 0x01, 0xfd, 0xaf, 0xfa, 0x1c,
- 0xf6, 0xad, 0x32, 0x8e, 0x7d, 0x5d, 0x63, 0xc0, 0xa5, 0xb1, 0xa8, 0x86,
- 0x62, 0x65, 0x8e, 0xc5, 0x27, 0x7f, 0x1e, 0xb5, 0x59, 0xcf, 0x1d, 0x36,
- 0x7c, 0x35, 0x79, 0xd7, 0xf1, 0x5e, 0x6c, 0xf2, 0x76, 0x10, 0xf9, 0xf9,
- 0x75, 0x8f, 0xd6, 0x57, 0x49, 0x1a, 0xc0, 0x39, 0x33, 0xd5, 0x76, 0x7c,
- 0x7f, 0x57, 0xed, 0x7b, 0xb8, 0xfa, 0x4d, 0x72, 0xdc, 0x93, 0x12, 0x7f,
- 0xbf, 0xf0, 0x63, 0x57, 0x1b, 0x7e, 0x64, 0xf8, 0xef, 0xfb, 0xa5, 0x2c,
- 0xe7, 0xef, 0x08, 0xd6, 0x2f, 0x4d, 0xad, 0x22, 0xcf, 0x07, 0x39, 0x7e,
- 0x4a, 0x5e, 0xf8, 0x1c, 0xbb, 0x66, 0xd3, 0x5a, 0x7e, 0x79, 0xa2, 0xf2,
- 0x25, 0xe4, 0x72, 0x58, 0xcb, 0xc7, 0x9c, 0x93, 0x57, 0xa1, 0x1f, 0x3d,
- 0x9f, 0xe5, 0xbc, 0x1d, 0x91, 0x53, 0x0e, 0xaa, 0x51, 0xa1, 0x7e, 0xb5,
- 0xd8, 0x79, 0x16, 0x9d, 0x35, 0xfe, 0x9e, 0xa5, 0x85, 0x3a, 0xbe, 0x9f,
- 0x4b, 0xe9, 0xb8, 0xce, 0xa8, 0xb8, 0x58, 0xaf, 0xab, 0x1a, 0xc3, 0xfe,
- 0xda, 0xa2, 0xb6, 0x17, 0xa2, 0x7b, 0x9f, 0x69, 0xf9, 0x70, 0xf1, 0x1e,
- 0xf4, 0x8b, 0xd5, 0x79, 0x31, 0x6c, 0x21, 0x6f, 0xf7, 0x2d, 0xe8, 0x0b,
- 0xad, 0x92, 0x11, 0xae, 0x5b, 0x88, 0x9c, 0x29, 0xe0, 0x3b, 0xfc, 0xfd,
- 0xdf, 0x50, 0x8d, 0xf3, 0xf5, 0x7c, 0x47, 0x64, 0xd5, 0xe4, 0x47, 0x30,
- 0x63, 0xe2, 0x02, 0x3e, 0x2c, 0x6f, 0xe7, 0x1d, 0xc3, 0x57, 0xa9, 0x57,
- 0xe1, 0x41, 0x7c, 0x05, 0x4e, 0x0d, 0x01, 0x63, 0x83, 0x5a, 0x2f, 0xda,
- 0x86, 0xb7, 0xc1, 0xba, 0x48, 0x5d, 0x7d, 0xfc, 0x62, 0x50, 0xbc, 0x0a,
- 0xf0, 0x4c, 0xf1, 0x98, 0xe7, 0x90, 0xca, 0xa7, 0xe1, 0x8b, 0x36, 0x14,
- 0xa7, 0x33, 0x62, 0xaf, 0x2a, 0x71, 0x9d, 0x95, 0xb8, 0x7e, 0x4f, 0x9a,
- 0xbc, 0x9b, 0x78, 0x80, 0x0b, 0x5e, 0x3c, 0x86, 0x6f, 0xb8, 0x1f, 0x66,
- 0xaa, 0x01, 0x7f, 0x6a, 0x37, 0x06, 0xf0, 0x47, 0xef, 0x20, 0xd0, 0x8b,
- 0x73, 0x88, 0xfb, 0xa4, 0xa3, 0xfb, 0xaa, 0xf1, 0x43, 0xd7, 0x75, 0x43,
- 0xf8, 0x6a, 0xa9, 0x78, 0xfd, 0xfd, 0xd9, 0xd3, 0xa6, 0x3f, 0x83, 0xfd,
- 0x62, 0xe2, 0x3f, 0x97, 0xe6, 0x01, 0x34, 0x71, 0x7b, 0x3d, 0xd8, 0x0f,
- 0xe0, 0x7f, 0xdc, 0xe3, 0x51, 0xd7, 0x3e, 0xc9, 0x93, 0x60, 0xee, 0x69,
- 0x6d, 0x6f, 0x5a, 0xec, 0x8f, 0x88, 0x7d, 0xc7, 0xd7, 0x8f, 0xda, 0xbf,
- 0x3e, 0xaf, 0x0f, 0x4d, 0x7d, 0x9a, 0xfd, 0x68, 0xf2, 0xc4, 0xe7, 0x17,
- 0x6f, 0xaf, 0xeb, 0xfd, 0xbd, 0xdb, 0xf4, 0xe7, 0x23, 0x9e, 0xbd, 0xef,
- 0xbc, 0x7e, 0xd4, 0xdf, 0x53, 0xf4, 0x9c, 0x88, 0xc1, 0x39, 0xf3, 0x87,
- 0x9a, 0x33, 0x1c, 0x87, 0xed, 0xac, 0xca, 0x5c, 0x99, 0xd3, 0xe7, 0xe4,
- 0xc5, 0xef, 0xbc, 0x99, 0xeb, 0xca, 0x6f, 0x99, 0x3f, 0xc7, 0xfd, 0x73,
- 0x24, 0xde, 0xe6, 0x3c, 0xc0, 0x64, 0xb1, 0x35, 0x5f, 0xc8, 0x3b, 0xec,
- 0xaa, 0xfc, 0x9b, 0x39, 0x30, 0x6e, 0xec, 0x43, 0x74, 0x47, 0xfd, 0xfa,
- 0xad, 0xf5, 0x89, 0x3c, 0x60, 0x9e, 0x6d, 0x6c, 0xe2, 0xde, 0xfd, 0x67,
- 0xb3, 0x79, 0x1f, 0x07, 0xea, 0xe8, 0x12, 0xd7, 0x3d, 0xae, 0xea, 0xcf,
- 0xef, 0x03, 0xef, 0x9e, 0xb7, 0xa2, 0x7a, 0x5d, 0xe5, 0x42, 0x78, 0xf5,
- 0xfa, 0xe3, 0xb2, 0xbf, 0x80, 0xb9, 0xf4, 0xda, 0x29, 0xce, 0xff, 0x7b,
- 0x67, 0x37, 0x78, 0x3e, 0x7d, 0xf8, 0xc6, 0x35, 0x1d, 0xd7, 0xa3, 0xb4,
- 0x3e, 0xe7, 0xb0, 0x3f, 0xa5, 0xdd, 0x50, 0xdf, 0x78, 0xb6, 0xb5, 0x1e,
- 0x78, 0xd7, 0xa0, 0x5e, 0x4a, 0x6f, 0x36, 0x78, 0xaf, 0x36, 0xfd, 0x43,
- 0xbf, 0xec, 0xcf, 0x40, 0xdf, 0xf4, 0x73, 0xb0, 0xae, 0x77, 0x36, 0x9b,
- 0x73, 0xd7, 0xe4, 0x3b, 0xc8, 0xd3, 0xa3, 0xe3, 0x7e, 0xbb, 0x83, 0xb4,
- 0x56, 0x87, 0xdd, 0x69, 0xe9, 0xc3, 0x13, 0x72, 0xf0, 0x4f, 0xc9, 0x0c,
- 0x9f, 0x53, 0x7e, 0x81, 0x79, 0x46, 0xb9, 0x14, 0xe2, 0x2c, 0x1f, 0xc6,
- 0xf7, 0x72, 0x1a, 0xeb, 0x3d, 0x69, 0xdc, 0x6f, 0xd3, 0x71, 0x87, 0xf5,
- 0x7b, 0xd2, 0xc0, 0x9c, 0xf4, 0xeb, 0x9a, 0x37, 0x8f, 0x80, 0x2b, 0x31,
- 0x7f, 0xff, 0x46, 0xe8, 0x7a, 0x4c, 0x2b, 0xa8, 0xcb, 0xba, 0x80, 0xfe,
- 0x2b, 0x0d, 0x39, 0xfc, 0x7d, 0xa6, 0x80, 0xb9, 0x4a, 0x03, 0xc1, 0xfb,
- 0x50, 0xfa, 0xb9, 0xa7, 0x39, 0xb7, 0xfc, 0x73, 0x2d, 0x31, 0xb6, 0x5c,
- 0x0f, 0xde, 0x97, 0x2b, 0x31, 0xff, 0x9c, 0xd0, 0x76, 0x59, 0x54, 0xf3,
- 0xc1, 0x3f, 0xd7, 0xc2, 0x52, 0xef, 0xbf, 0x64, 0x0e, 0xec, 0xa4, 0x9b,
- 0x75, 0xc4, 0xb5, 0x56, 0x6f, 0xcd, 0xb3, 0x39, 0xcf, 0xd8, 0x83, 0xdf,
- 0x26, 0x8e, 0xa6, 0x7d, 0x9c, 0x7f, 0x4a, 0xfc, 0xfc, 0x85, 0xdf, 0x21,
- 0x39, 0x89, 0x47, 0xdb, 0xc5, 0xfa, 0x01, 0x99, 0xb3, 0xae, 0x27, 0x07,
- 0xe7, 0xe3, 0x34, 0xfb, 0xd5, 0x49, 0x78, 0x77, 0xe4, 0xbc, 0xbe, 0x36,
- 0xf1, 0x75, 0x8d, 0x00, 0x97, 0x46, 0x4c, 0x1d, 0x4c, 0xbd, 0x4c, 0x7d,
- 0x50, 0xc7, 0xdc, 0x28, 0xab, 0x4d, 0x94, 0x47, 0x99, 0xa7, 0x23, 0xe5,
- 0x3f, 0x83, 0xef, 0xb4, 0xa3, 0x45, 0xad, 0xff, 0x16, 0x7d, 0xc3, 0x7d,
- 0x44, 0xf4, 0x83, 0x60, 0x73, 0x1e, 0x49, 0x01, 0x02, 0xef, 0xb2, 0x30,
- 0x5d, 0x8f, 0xca, 0xf2, 0xb8, 0xe9, 0x9b, 0x60, 0xdf, 0x5d, 0xe1, 0x77,
- 0xfa, 0xc2, 0xe6, 0xd6, 0xfe, 0x37, 0xf1, 0x69, 0xbd, 0x61, 0xe1, 0xa1,
- 0x4d, 0xa5, 0xfd, 0x78, 0xd7, 0x74, 0xc4, 0xc1, 0xf3, 0x8e, 0xb8, 0xbf,
- 0x4e, 0x8a, 0x0f, 0x89, 0xb8, 0x16, 0x77, 0x75, 0x26, 0x38, 0x8e, 0x4b,
- 0x5f, 0xdf, 0xe2, 0xcf, 0x1f, 0x2d, 0xa7, 0xb0, 0xde, 0x5d, 0x82, 0xf9,
- 0x08, 0xf3, 0x35, 0x4c, 0x17, 0xc0, 0xe7, 0x0f, 0x96, 0x80, 0xef, 0xd3,
- 0x21, 0xd8, 0xe9, 0x7c, 0x9b, 0xef, 0x71, 0xbb, 0x1b, 0xe9, 0xac, 0x2d,
- 0x0b, 0x4f, 0xf3, 0x16, 0xff, 0x3f, 0xd2, 0xa0, 0xb4, 0xbc, 0x5b, 0xa5,
- 0xcf, 0xc0, 0xcf, 0x88, 0xaf, 0xce, 0xdb, 0xf1, 0x55, 0xa3, 0xa3, 0xf8,
- 0x88, 0xed, 0xc2, 0x5b, 0xbb, 0x95, 0xb7, 0xa6, 0x8e, 0x79, 0xab, 0x2d,
- 0x4f, 0xf7, 0x05, 0x79, 0x1a, 0x13, 0x9e, 0xfe, 0xed, 0xcd, 0xd3, 0xad,
- 0x76, 0x31, 0xc7, 0x6f, 0xfe, 0x6f, 0xbc, 0x05, 0x1e, 0x18, 0xd4, 0xe7,
- 0x77, 0xfb, 0xf8, 0x67, 0xfc, 0xf2, 0xcf, 0x9f, 0x43, 0x6a, 0xae, 0xfe,
- 0x07, 0x92, 0xe2, 0x88, 0x7c, 0xe0, 0x0d, 0x00, 0x00, 0x00 };
-
-static u8 bnx2_TPAT_b06FwText[] = {
- 0xbd, 0x58, 0x6d, 0x70, 0x5c, 0xd5, 0x79, 0x7e, 0xce, 0xbd, 0x77, 0xb5,
- 0xd7, 0xd2, 0x4a, 0xba, 0xb2, 0xd6, 0x66, 0x5d, 0xdc, 0xfa, 0x1e, 0x74,
- 0x57, 0x52, 0x58, 0x01, 0x77, 0x6d, 0x01, 0xeb, 0xe6, 0xb6, 0xbe, 0xc8,
- 0xb2, 0xbc, 0xfe, 0x00, 0xe4, 0xc0, 0x4c, 0xe4, 0x96, 0x8e, 0x37, 0xc6,
- 0x18, 0xd9, 0x90, 0xa9, 0x28, 0xfc, 0x58, 0x37, 0x4c, 0xbd, 0x95, 0x65,
- 0x63, 0xc3, 0x4a, 0x6b, 0x0c, 0xb1, 0x4c, 0xda, 0x99, 0x78, 0x84, 0xb1,
- 0x4c, 0x22, 0x7b, 0x0d, 0xe4, 0x07, 0x49, 0xc3, 0xa0, 0xc1, 0x0e, 0x08,
- 0x06, 0xf3, 0x31, 0x6d, 0x67, 0x98, 0xe9, 0xa4, 0xf5, 0x18, 0xf3, 0x11,
- 0x92, 0x18, 0x87, 0x4e, 0x3a, 0xa2, 0x10, 0x9f, 0x3e, 0x67, 0x77, 0xc5,
- 0x57, 0x32, 0xd3, 0xfe, 0xaa, 0x66, 0x56, 0x7b, 0xf7, 0xec, 0xf9, 0x78,
- 0xcf, 0xfb, 0x3e, 0xef, 0xf3, 0x3e, 0xef, 0x5e, 0x21, 0x50, 0x8f, 0xda,
- 0x5f, 0x23, 0x5f, 0xdd, 0xdf, 0x1a, 0xba, 0x2f, 0x7d, 0xf5, 0x75, 0x57,
- 0xf3, 0xf1, 0x3a, 0xe1, 0xd4, 0x59, 0xf8, 0x7f, 0xfc, 0x33, 0x01, 0x67,
- 0xce, 0x0e, 0xfd, 0x82, 0x6d, 0x04, 0x85, 0xcb, 0x7b, 0x3c, 0xd8, 0x66,
- 0x10, 0x77, 0x6f, 0xf7, 0x80, 0x70, 0x2a, 0xe5, 0xae, 0xc4, 0xef, 0x54,
- 0x21, 0x6e, 0x41, 0x8f, 0xff, 0x71, 0xf0, 0xe9, 0x35, 0xcf, 0x5d, 0x2f,
- 0x2f, 0x1e, 0x36, 0x61, 0x3b, 0xc1, 0x5e, 0xcb, 0x69, 0x87, 0xbd, 0x98,
- 0x6b, 0xfe, 0xb1, 0xe3, 0x2f, 0x04, 0x9a, 0xe6, 0xf6, 0x52, 0x6a, 0xc4,
- 0x8f, 0x62, 0xd8, 0x4f, 0x60, 0x77, 0xc9, 0x40, 0xe8, 0x44, 0xb1, 0xcb,
- 0x9b, 0x55, 0x5b, 0x7c, 0xe9, 0xef, 0x86, 0x5a, 0x72, 0xda, 0x97, 0x89,
- 0x5e, 0x13, 0xe1, 0x77, 0xbc, 0xc5, 0xd8, 0x5d, 0x4e, 0x60, 0xa4, 0x6c,
- 0xe3, 0xac, 0x39, 0x82, 0xde, 0xf2, 0xdc, 0x3a, 0x97, 0xeb, 0x3a, 0xb1,
- 0xe7, 0xcb, 0x6b, 0xdd, 0xdd, 0x48, 0x25, 0xf6, 0xc0, 0x40, 0x2e, 0xee,
- 0x71, 0x5d, 0x9b, 0xbb, 0x07, 0xb2, 0x93, 0xfb, 0x14, 0xea, 0xba, 0x5d,
- 0xee, 0x51, 0xe0, 0x7a, 0xe9, 0x1e, 0x85, 0xde, 0x2b, 0xc3, 0xcf, 0x6f,
- 0xa9, 0xe7, 0x3a, 0x16, 0xe3, 0x19, 0xee, 0xff, 0x74, 0xd9, 0xc1, 0xc9,
- 0xb2, 0x87, 0xe7, 0xcb, 0x2e, 0x7e, 0x54, 0x8e, 0xe3, 0xa9, 0xb2, 0x9d,
- 0xb3, 0x03, 0xf4, 0xc7, 0x47, 0x77, 0xaa, 0x84, 0x87, 0xc2, 0x1f, 0x05,
- 0xde, 0xa1, 0x43, 0x46, 0x2c, 0xf3, 0x37, 0xd7, 0xa1, 0x7f, 0xfe, 0x71,
- 0x1b, 0x1b, 0x4a, 0x8b, 0x73, 0xd1, 0x00, 0x9c, 0x23, 0xe0, 0x5f, 0x67,
- 0xa3, 0x9f, 0x7b, 0x14, 0xb8, 0x7f, 0x58, 0x1e, 0xe1, 0xcb, 0xc6, 0xbb,
- 0x45, 0xdb, 0x6e, 0x1e, 0x5d, 0xa8, 0xe7, 0xe0, 0x57, 0xc5, 0x8b, 0xea,
- 0x42, 0xda, 0xc1, 0x2b, 0xcb, 0x95, 0x6a, 0x0c, 0x50, 0x68, 0xe8, 0x2e,
- 0xc0, 0x0c, 0x64, 0x76, 0x9d, 0x29, 0xd0, 0x7b, 0x95, 0xd7, 0x39, 0x2a,
- 0x6e, 0xb9, 0xc5, 0x08, 0x60, 0x8b, 0xc0, 0xb5, 0xda, 0xa6, 0x32, 0xd8,
- 0x57, 0xe6, 0xbd, 0x68, 0xcf, 0x48, 0x19, 0xe1, 0x5f, 0x76, 0x98, 0x98,
- 0x88, 0xe3, 0xfe, 0xb7, 0xbb, 0x2d, 0x7c, 0x5c, 0x94, 0x89, 0x4e, 0xf3,
- 0x7e, 0xec, 0x2c, 0xe6, 0x71, 0x47, 0x11, 0x05, 0x23, 0x18, 0xc2, 0x37,
- 0xba, 0x03, 0xde, 0x33, 0xc4, 0xf7, 0xcb, 0xb0, 0x5b, 0x83, 0xd3, 0x97,
- 0xdf, 0xdb, 0x2e, 0x0f, 0x87, 0x06, 0x90, 0x1d, 0x03, 0xfa, 0x4a, 0x02,
- 0xa7, 0x32, 0x02, 0x5b, 0xfc, 0xcb, 0x50, 0x70, 0xba, 0xb1, 0xb7, 0x2c,
- 0xb3, 0x05, 0x7e, 0x77, 0xd5, 0x28, 0xec, 0x45, 0xc1, 0x6d, 0xd6, 0xf2,
- 0x12, 0xec, 0x96, 0x60, 0xc0, 0x4a, 0x8f, 0xb5, 0xcd, 0x1e, 0x13, 0x32,
- 0xbf, 0xc2, 0x94, 0x21, 0x20, 0x33, 0x9d, 0x46, 0xaa, 0xa0, 0x84, 0x1c,
- 0xba, 0x08, 0x6d, 0xd3, 0x6d, 0xd6, 0x35, 0x53, 0xfa, 0x7d, 0xc0, 0xba,
- 0x7a, 0x0a, 0x58, 0xcf, 0x3d, 0x1f, 0x5a, 0x2e, 0xb0, 0x3d, 0xfd, 0x6b,
- 0x15, 0x2e, 0x90, 0xe1, 0x61, 0xd1, 0x8d, 0xd1, 0x32, 0x70, 0xd3, 0x18,
- 0xec, 0x18, 0xe7, 0x16, 0xb9, 0x77, 0x3d, 0xe7, 0xae, 0x1d, 0x6d, 0x1b,
- 0x9c, 0x11, 0x92, 0x77, 0x93, 0x03, 0x40, 0xca, 0x3f, 0x0e, 0xe9, 0xae,
- 0x13, 0xd2, 0xd9, 0x53, 0xdb, 0x33, 0x59, 0xdb, 0xf3, 0x8a, 0x29, 0x5b,
- 0xac, 0x2a, 0x41, 0xf4, 0x96, 0xe0, 0x3e, 0xe9, 0x83, 0x77, 0x89, 0xf1,
- 0xde, 0xf5, 0x70, 0x5b, 0xa4, 0x7f, 0x98, 0x73, 0xa3, 0x41, 0x97, 0xf5,
- 0x5e, 0x51, 0xe0, 0x43, 0x4f, 0xcf, 0xef, 0xd2, 0xb6, 0x84, 0x4e, 0x90,
- 0x11, 0xfd, 0xe5, 0xfd, 0x73, 0x39, 0x62, 0x9c, 0xf4, 0xe3, 0xc0, 0x42,
- 0x34, 0xb7, 0x78, 0xf3, 0xf1, 0xb0, 0x83, 0xc6, 0xa8, 0xb7, 0xcc, 0x78,
- 0xc0, 0xa9, 0xc3, 0x49, 0xff, 0xb7, 0x0a, 0xdf, 0xd0, 0xf3, 0x81, 0x6f,
- 0x3f, 0xe2, 0x20, 0xe6, 0x5d, 0xc4, 0xd1, 0xf4, 0x36, 0xe3, 0x55, 0x67,
- 0x08, 0x4d, 0xde, 0xcf, 0x8d, 0xd7, 0x9c, 0x38, 0x1e, 0xe2, 0x7d, 0xee,
- 0x4c, 0xc6, 0xf1, 0x40, 0xf9, 0xab, 0xfb, 0x5a, 0x22, 0x3b, 0xfe, 0x8e,
- 0x42, 0x4b, 0x65, 0x7d, 0xf8, 0xac, 0x3f, 0x01, 0x5c, 0xa6, 0xc7, 0xf3,
- 0x62, 0x63, 0xe9, 0x92, 0x72, 0xa3, 0x19, 0x3c, 0x50, 0xb2, 0x31, 0x8f,
- 0x76, 0x45, 0x3c, 0x1b, 0x6f, 0x17, 0xf3, 0x62, 0x55, 0x39, 0x14, 0x6b,
- 0x26, 0x7b, 0x44, 0x38, 0x69, 0x89, 0x9e, 0x71, 0x10, 0x9b, 0x4a, 0xad,
- 0xf1, 0x05, 0xfe, 0xc3, 0xff, 0x57, 0xe3, 0x6c, 0xab, 0x0c, 0x5d, 0x71,
- 0x49, 0x79, 0x49, 0x03, 0xf5, 0x5e, 0x9f, 0x58, 0x3b, 0xa9, 0xd4, 0x5e,
- 0x3f, 0x2b, 0x7a, 0x27, 0x61, 0x37, 0x04, 0x81, 0x75, 0xd7, 0xe8, 0x69,
- 0x23, 0xb7, 0x20, 0x86, 0x52, 0xc9, 0xc5, 0x29, 0x5f, 0xe3, 0x77, 0x1e,
- 0x2c, 0x4f, 0xf0, 0x85, 0xd8, 0x19, 0x1f, 0x56, 0x8c, 0xcf, 0x53, 0x1b,
- 0x2c, 0x8c, 0x74, 0xaf, 0xad, 0xac, 0x89, 0x10, 0x2b, 0x4f, 0x14, 0xb3,
- 0x30, 0x88, 0xbf, 0x45, 0x41, 0x72, 0x76, 0x82, 0x98, 0x7f, 0xcb, 0x4f,
- 0x76, 0x7e, 0x6c, 0x92, 0x1c, 0x5a, 0x65, 0x82, 0x86, 0x0a, 0x2b, 0x48,
- 0x76, 0x1e, 0x81, 0x80, 0xe9, 0x59, 0x78, 0xc5, 0x8f, 0x20, 0xdc, 0x60,
- 0x63, 0x17, 0x71, 0x55, 0xc7, 0xf1, 0xa3, 0x95, 0x71, 0xfd, 0x19, 0xce,
- 0xaa, 0xf2, 0x57, 0x73, 0x9e, 0xe3, 0xa5, 0x36, 0xe4, 0x2a, 0x79, 0x0f,
- 0x67, 0x1d, 0xef, 0xfb, 0xad, 0x88, 0x7e, 0xfc, 0x93, 0xcf, 0xc6, 0x6e,
- 0xa4, 0x9d, 0x66, 0xe0, 0xe5, 0x1e, 0x17, 0x8b, 0x50, 0x68, 0x01, 0xed,
- 0x36, 0x70, 0x21, 0xbd, 0x10, 0xd3, 0x2d, 0xfa, 0xeb, 0xb8, 0xd3, 0x3f,
- 0xde, 0xaa, 0x63, 0xa2, 0xf7, 0x72, 0x56, 0x8d, 0x2b, 0xf5, 0xbc, 0x5f,
- 0x87, 0xd9, 0x8e, 0xe1, 0x19, 0x66, 0x89, 0xbf, 0x88, 0x39, 0xf9, 0x12,
- 0xcf, 0x6f, 0x59, 0x66, 0xc2, 0x5c, 0xe6, 0x9a, 0xee, 0x7c, 0x60, 0xa2,
- 0xa8, 0x39, 0x41, 0xce, 0xbe, 0xc4, 0xff, 0xe7, 0xca, 0x1a, 0x9f, 0x3e,
- 0xf1, 0x29, 0xd0, 0xde, 0xa1, 0xe3, 0xee, 0x5b, 0xed, 0xc4, 0xde, 0x76,
- 0xfa, 0x33, 0xc2, 0x3c, 0x78, 0x90, 0xf6, 0x9e, 0x2b, 0x7e, 0xcf, 0x58,
- 0xe5, 0x48, 0x57, 0x9f, 0xf0, 0x4e, 0x11, 0xe2, 0x79, 0xff, 0xef, 0xb4,
- 0x8f, 0x5d, 0x6e, 0x4b, 0xcc, 0xdc, 0x47, 0xcc, 0x68, 0xee, 0x59, 0x6f,
- 0x39, 0x63, 0x72, 0xe0, 0x7d, 0x1a, 0x91, 0x08, 0x86, 0xac, 0x44, 0x29,
- 0xb5, 0x77, 0x90, 0xdf, 0xdb, 0x41, 0xd6, 0xb2, 0x47, 0x65, 0x9e, 0xe7,
- 0xe5, 0x2c, 0x43, 0x26, 0x9a, 0xcd, 0xd4, 0xd0, 0x88, 0x90, 0x83, 0xcd,
- 0x42, 0xf6, 0xdf, 0x03, 0xe9, 0x9c, 0x10, 0xfa, 0xcc, 0xf5, 0x56, 0x57,
- 0x05, 0xa3, 0x59, 0x62, 0x54, 0xbf, 0xdf, 0x67, 0xa5, 0x2a, 0xef, 0x43,
- 0xd6, 0x95, 0x53, 0x09, 0x8c, 0x96, 0xa4, 0xef, 0x8a, 0x28, 0xbe, 0x96,
- 0xb6, 0x71, 0x22, 0xa9, 0x96, 0xbc, 0x90, 0x96, 0xb9, 0x1e, 0x73, 0x31,
- 0x73, 0x21, 0x81, 0x61, 0x62, 0xe9, 0x1f, 0x92, 0x23, 0xe8, 0x29, 0x9b,
- 0xc4, 0xb1, 0x8b, 0xfd, 0xa5, 0x28, 0x66, 0xc8, 0x4f, 0x75, 0xe9, 0x4e,
- 0x8c, 0x94, 0x64, 0xe7, 0x1b, 0x48, 0xe5, 0x8f, 0x30, 0x5e, 0x67, 0x17,
- 0x78, 0xd8, 0x5f, 0x6e, 0x63, 0x8c, 0xa4, 0xbb, 0x8a, 0x1c, 0x65, 0x76,
- 0x4b, 0x67, 0x17, 0x7d, 0x5b, 0x17, 0x90, 0xdb, 0xca, 0x19, 0xee, 0x53,
- 0xc0, 0xaa, 0x72, 0x5e, 0xf4, 0x95, 0xe7, 0x70, 0xfa, 0x73, 0x62, 0x53,
- 0x63, 0xd5, 0xc6, 0xe6, 0x12, 0x70, 0x67, 0xc9, 0x47, 0x8b, 0x67, 0xbc,
- 0x18, 0xc5, 0x45, 0xfa, 0x71, 0x02, 0xf7, 0x38, 0x21, 0x16, 0x79, 0xeb,
- 0xd4, 0x8e, 0xb8, 0x9e, 0x9f, 0x17, 0x6b, 0x19, 0xb7, 0x30, 0x02, 0x63,
- 0xd2, 0x37, 0x71, 0x36, 0x3e, 0x3c, 0x3f, 0x52, 0xe1, 0x5d, 0xfd, 0x6e,
- 0xa2, 0xdf, 0xc7, 0x1a, 0x07, 0x72, 0xc8, 0x17, 0x85, 0xc1, 0x26, 0xfa,
- 0xe1, 0xa4, 0x28, 0x0c, 0xc4, 0x20, 0x0b, 0xf7, 0x0a, 0x3a, 0x6b, 0x8c,
- 0x24, 0xb1, 0x60, 0x8e, 0xa7, 0x2d, 0xfc, 0x75, 0xe9, 0x29, 0xe3, 0x5c,
- 0xa4, 0x0e, 0xe6, 0x81, 0x08, 0xa2, 0x07, 0x2c, 0x34, 0x1f, 0x10, 0xc4,
- 0x5d, 0xa1, 0x33, 0xaa, 0xd7, 0x21, 0x81, 0x7d, 0xa3, 0x36, 0xee, 0xe9,
- 0x88, 0xe0, 0x42, 0x52, 0x0e, 0x5e, 0x21, 0x86, 0xfd, 0x26, 0x8e, 0x8d,
- 0x1e, 0x97, 0xae, 0x6b, 0x14, 0x22, 0x68, 0x8a, 0x23, 0xd2, 0x5e, 0x87,
- 0x06, 0xae, 0xdb, 0x59, 0x52, 0x3b, 0xed, 0xa0, 0xe0, 0x36, 0x40, 0xfa,
- 0x0f, 0x73, 0xdf, 0x53, 0x45, 0xa5, 0xea, 0xaf, 0xf5, 0x66, 0x3e, 0x30,
- 0xe5, 0xf4, 0x0e, 0x7e, 0x7e, 0x6b, 0xaa, 0xba, 0xff, 0xbc, 0x03, 0x36,
- 0x1a, 0x0f, 0x56, 0xf6, 0x9f, 0x7d, 0x8a, 0x16, 0x7c, 0x58, 0xd2, 0xf9,
- 0xa4, 0x54, 0x34, 0xf0, 0xfa, 0xdf, 0x13, 0x4a, 0xdd, 0xe4, 0xcb, 0xdc,
- 0xcb, 0xa2, 0x6d, 0x60, 0x94, 0xcf, 0x83, 0xe9, 0xa4, 0x9b, 0xa5, 0xcd,
- 0xe7, 0xcb, 0x51, 0xda, 0xc7, 0x5c, 0xf0, 0xb6, 0x19, 0x3b, 0x1c, 0x13,
- 0x75, 0xde, 0x0e, 0x63, 0x6b, 0x05, 0xab, 0x0e, 0x16, 0x8d, 0xd5, 0x63,
- 0x89, 0x17, 0x8a, 0x4d, 0xcc, 0xcd, 0x8d, 0x93, 0x16, 0xe7, 0xe9, 0xdc,
- 0x14, 0x88, 0x7a, 0xbd, 0x62, 0xe5, 0x64, 0x5f, 0x25, 0x5f, 0x07, 0xc6,
- 0x0d, 0xbc, 0xe9, 0xdf, 0x80, 0x48, 0x90, 0x15, 0x03, 0x93, 0x3a, 0x7f,
- 0xd6, 0x8a, 0xd5, 0x93, 0x8c, 0xdf, 0x7c, 0x9d, 0x3b, 0x37, 0x88, 0x48,
- 0xa0, 0xf3, 0xe5, 0xf3, 0x1c, 0xb2, 0x99, 0x43, 0xc7, 0xfe, 0x97, 0x1c,
- 0x7a, 0xa8, 0x64, 0x21, 0xd7, 0x52, 0xcd, 0x97, 0x5e, 0xc6, 0xe2, 0xef,
- 0x6b, 0x75, 0x7b, 0x3b, 0xc7, 0xa3, 0x07, 0x74, 0x0e, 0xf7, 0x32, 0x87,
- 0x35, 0x9e, 0x2d, 0xb1, 0x69, 0x1c, 0x76, 0x73, 0x10, 0x5a, 0x1f, 0x8e,
- 0x2a, 0xbc, 0xed, 0x2b, 0xf5, 0xf1, 0x32, 0xed, 0x13, 0x39, 0xf8, 0x2c,
- 0xf1, 0x08, 0x12, 0xd2, 0xbb, 0x9e, 0x52, 0x33, 0x7e, 0x2a, 0xfb, 0x2c,
- 0x79, 0xf9, 0x9c, 0xd0, 0xf7, 0x8f, 0xc2, 0x49, 0x6b, 0x3c, 0xf6, 0x5a,
- 0x57, 0x55, 0x70, 0x19, 0x12, 0xaf, 0xac, 0xd5, 0xf3, 0x35, 0x36, 0xa3,
- 0x68, 0x48, 0xce, 0xd2, 0x37, 0x72, 0xa8, 0x51, 0xa8, 0x25, 0xaf, 0xa6,
- 0xab, 0xb8, 0x2c, 0xb2, 0x36, 0xad, 0xe7, 0x59, 0xbd, 0xe3, 0xb2, 0xb0,
- 0xde, 0xac, 0xd6, 0xd1, 0xbd, 0xc4, 0x86, 0xe6, 0xb8, 0xcb, 0xdb, 0xa3,
- 0xd8, 0x47, 0x8c, 0x7a, 0x69, 0x17, 0xc3, 0xac, 0xab, 0xbb, 0x4b, 0xd2,
- 0x1d, 0x26, 0x4e, 0x77, 0xd7, 0x70, 0x3a, 0xcc, 0x5a, 0xba, 0x1b, 0x72,
- 0xaf, 0xae, 0xa5, 0x11, 0xe2, 0x94, 0x34, 0x56, 0xc1, 0xe9, 0x48, 0x0d,
- 0xa7, 0xbd, 0x15, 0x9c, 0xee, 0x36, 0x34, 0x3e, 0x35, 0xf6, 0x36, 0xf1,
- 0xbe, 0x67, 0xa3, 0x30, 0x7e, 0xc0, 0xfd, 0xc3, 0x05, 0xc3, 0x3d, 0x35,
- 0xec, 0xf5, 0x68, 0xec, 0x19, 0x69, 0xdc, 0x63, 0xf0, 0x6e, 0x2f, 0x88,
- 0x42, 0xae, 0x11, 0x32, 0x3b, 0x2c, 0x0a, 0x9d, 0xf3, 0x88, 0xbd, 0x67,
- 0x38, 0xa3, 0x81, 0xd8, 0xab, 0xfa, 0x4c, 0xcf, 0x8f, 0x11, 0x7b, 0xff,
- 0x29, 0xce, 0x46, 0x34, 0xd7, 0xea, 0xd8, 0x02, 0x8b, 0x4e, 0x68, 0xae,
- 0x8d, 0x92, 0x30, 0x2c, 0xe4, 0x4b, 0xc6, 0xe2, 0x04, 0x14, 0xb6, 0x92,
- 0xdb, 0xde, 0xf4, 0x76, 0xf9, 0x2d, 0xb8, 0x01, 0xa7, 0xbb, 0x0c, 0x68,
- 0x1d, 0x62, 0x4e, 0x54, 0xb1, 0x7b, 0x17, 0x39, 0xa3, 0x29, 0x90, 0x9d,
- 0x67, 0xa9, 0x37, 0xb6, 0xa4, 0x1b, 0x50, 0xf2, 0x86, 0xc3, 0x66, 0x56,
- 0x43, 0x9b, 0xe7, 0xae, 0x86, 0xae, 0x85, 0x71, 0x58, 0xed, 0x36, 0x1a,
- 0x8e, 0x7a, 0xb9, 0x13, 0x42, 0xe3, 0x15, 0xe8, 0x3a, 0x6e, 0xd3, 0x7e,
- 0x38, 0xf5, 0x81, 0x97, 0xf9, 0xc0, 0x7c, 0x5c, 0x9c, 0x75, 0xaa, 0xf5,
- 0xa0, 0x6f, 0x5c, 0x63, 0xec, 0x57, 0xea, 0x4d, 0xcf, 0xc0, 0x1d, 0xdd,
- 0x4a, 0x79, 0x4b, 0xa3, 0x88, 0x4c, 0xd8, 0xa8, 0x3b, 0xd8, 0x8a, 0x97,
- 0xba, 0x22, 0x38, 0x7b, 0xab, 0xfe, 0x3e, 0x8a, 0x7a, 0xe2, 0x70, 0xd3,
- 0xb5, 0x51, 0x2c, 0x99, 0xa8, 0x62, 0xb2, 0xc1, 0xfb, 0x89, 0xb8, 0x8b,
- 0x98, 0x9c, 0xe7, 0x9d, 0x11, 0xdb, 0x9c, 0x0c, 0xf6, 0xd2, 0xa6, 0xd7,
- 0xc9, 0xf1, 0xe7, 0x93, 0xbb, 0x66, 0x2c, 0xda, 0xbf, 0x62, 0x59, 0xa1,
- 0x73, 0x09, 0x22, 0x58, 0x34, 0x21, 0x07, 0x8e, 0xe9, 0x0a, 0x33, 0x6a,
- 0x89, 0x0d, 0xc4, 0xbb, 0xe6, 0x57, 0x93, 0x71, 0xba, 0x62, 0x69, 0xdb,
- 0xd0, 0xcd, 0xb8, 0xa4, 0xce, 0x24, 0x93, 0xd9, 0x51, 0x62, 0x7d, 0xdb,
- 0xf1, 0x08, 0xea, 0x0e, 0xfc, 0x97, 0x32, 0x02, 0xe6, 0x42, 0xb7, 0x22,
- 0x3e, 0x0b, 0x99, 0x7a, 0x72, 0xc8, 0x45, 0xc4, 0xf1, 0xd8, 0xfe, 0x9d,
- 0x6a, 0x09, 0xc7, 0xdf, 0xbb, 0xbe, 0x19, 0x6d, 0xcb, 0x64, 0x7e, 0x2b,
- 0xf7, 0x9f, 0x4d, 0x17, 0x3a, 0x13, 0x8c, 0xdd, 0x49, 0xb8, 0xb8, 0x6a,
- 0x4c, 0xe6, 0x8e, 0xa1, 0x0e, 0xcd, 0x13, 0x5e, 0xf6, 0x84, 0x88, 0xa1,
- 0xf1, 0x44, 0x0c, 0xfb, 0x8e, 0xeb, 0xfc, 0x8c, 0xc1, 0x1a, 0xf3, 0x66,
- 0x3b, 0x44, 0xa1, 0x9f, 0xf9, 0x39, 0xd3, 0x2f, 0xda, 0xd1, 0x3e, 0x2e,
- 0xa7, 0xb3, 0xc2, 0x0b, 0x1f, 0x80, 0x87, 0x76, 0xd6, 0x65, 0xfb, 0x84,
- 0x8b, 0x15, 0xba, 0x7e, 0x94, 0x75, 0xfe, 0xe8, 0x7a, 0x6a, 0xf0, 0x4e,
- 0xa1, 0x58, 0x5f, 0xa9, 0x79, 0xbd, 0x7c, 0xf5, 0xb1, 0xfe, 0x59, 0x62,
- 0xdd, 0xb8, 0xce, 0x2d, 0x03, 0x33, 0xfe, 0x25, 0xb5, 0x3d, 0x99, 0x65,
- 0xad, 0x9b, 0xc7, 0xbc, 0xaa, 0xe6, 0x13, 0x5a, 0x74, 0x6e, 0xcd, 0xab,
- 0xe5, 0x93, 0x85, 0x33, 0x8c, 0xdd, 0xe1, 0xff, 0x73, 0x5d, 0xb2, 0x90,
- 0x38, 0x60, 0xa0, 0xa5, 0x23, 0x8a, 0x6b, 0x96, 0xb6, 0x39, 0xcd, 0x88,
- 0xe2, 0x26, 0xdf, 0x41, 0x13, 0x31, 0xb1, 0x9f, 0x39, 0x85, 0xf9, 0xd5,
- 0x5c, 0x5b, 0xa9, 0xeb, 0x55, 0x2d, 0xd7, 0xf2, 0xa5, 0x04, 0x6b, 0x93,
- 0xae, 0x05, 0xbd, 0xac, 0x05, 0x16, 0x0e, 0x95, 0xb5, 0x6f, 0x1d, 0xbc,
- 0x4b, 0xce, 0x7e, 0xc5, 0xd7, 0xbe, 0x5d, 0x8c, 0x12, 0x73, 0xe3, 0x41,
- 0xe6, 0xc6, 0xda, 0xf2, 0x25, 0xb5, 0xc6, 0xd3, 0xf5, 0x38, 0x64, 0x3d,
- 0xb6, 0xc4, 0x4d, 0xe3, 0x72, 0xd0, 0x15, 0xa7, 0xee, 0x24, 0x36, 0x3b,
- 0x1b, 0x0d, 0xa5, 0x5e, 0x4e, 0xa7, 0x42, 0xea, 0x98, 0xcc, 0xdd, 0x42,
- 0xba, 0xef, 0x93, 0x9b, 0xd6, 0x9a, 0x51, 0x2c, 0xaf, 0xe5, 0x60, 0xb2,
- 0x96, 0x83, 0x1e, 0x73, 0xd0, 0x6d, 0x45, 0xf8, 0x09, 0x6d, 0x6c, 0x63,
- 0x0e, 0x6e, 0xa3, 0x4e, 0xfd, 0x7e, 0xa9, 0xc2, 0xfb, 0x99, 0x15, 0x22,
- 0x35, 0x73, 0x9e, 0xf9, 0xe4, 0x5e, 0xe6, 0x51, 0xaf, 0xb5, 0x65, 0xce,
- 0x33, 0x66, 0xab, 0x6b, 0xf9, 0xb4, 0xbb, 0xc6, 0xfb, 0x0f, 0xd4, 0xf2,
- 0x69, 0xf5, 0x97, 0xf2, 0x49, 0xf3, 0xd3, 0x0b, 0xbf, 0x43, 0xab, 0xd6,
- 0x22, 0x79, 0xa1, 0xef, 0x97, 0xb3, 0x10, 0xfe, 0xd8, 0xd7, 0x67, 0xd9,
- 0xb0, 0x82, 0xc6, 0x0a, 0xdf, 0x58, 0x41, 0x28, 0x7a, 0x59, 0x3b, 0x6d,
- 0x2f, 0x2f, 0xb2, 0xf4, 0x9d, 0x5e, 0xb7, 0x96, 0xb1, 0xd8, 0x99, 0xfe,
- 0x05, 0xce, 0xb6, 0x2a, 0xd5, 0x97, 0xbe, 0xa4, 0xde, 0x60, 0x5c, 0x62,
- 0xd4, 0x1f, 0xeb, 0x27, 0xb3, 0xa2, 0x7f, 0x52, 0xfb, 0xa6, 0x11, 0x11,
- 0x6f, 0xad, 0x58, 0x35, 0x09, 0xdc, 0x43, 0x3d, 0x73, 0x8e, 0x7e, 0x59,
- 0xe3, 0xcb, 0xa1, 0x35, 0xbc, 0xdb, 0x19, 0xdf, 0xc2, 0xc3, 0xe5, 0xaa,
- 0x7f, 0xf6, 0x95, 0x65, 0x66, 0x1a, 0x23, 0x58, 0xc3, 0x9a, 0x76, 0x98,
- 0x7c, 0xf1, 0x6f, 0xc9, 0x28, 0x5e, 0x24, 0x5f, 0xbc, 0xc4, 0xfb, 0x1d,
- 0xaa, 0xde, 0xcf, 0x9f, 0x45, 0x2a, 0x73, 0x5a, 0xf3, 0x05, 0xb5, 0xf7,
- 0xa1, 0x72, 0x9b, 0x7f, 0x9a, 0x78, 0x7c, 0xb0, 0x24, 0x07, 0xfa, 0x78,
- 0x47, 0xbb, 0x5b, 0xce, 0x0e, 0x0a, 0x81, 0x8d, 0x49, 0x38, 0x66, 0xa0,
- 0xef, 0xe1, 0x52, 0xe3, 0x66, 0xe8, 0x87, 0x02, 0xfa, 0x78, 0xd7, 0x95,
- 0xac, 0x71, 0x8f, 0x95, 0xbf, 0xa4, 0xeb, 0xb0, 0xad, 0xa4, 0xb9, 0x4a,
- 0xa9, 0x8e, 0xb4, 0xd6, 0x4a, 0x79, 0x71, 0xb3, 0xe6, 0x94, 0x48, 0x14,
- 0xca, 0x6f, 0x4b, 0x2c, 0x61, 0xec, 0xf3, 0xc4, 0xd7, 0xbb, 0x5e, 0x3d,
- 0x79, 0x21, 0x24, 0xaf, 0xf7, 0x90, 0xb7, 0x7b, 0x45, 0x5f, 0x85, 0xcf,
- 0xb3, 0x22, 0x3b, 0x69, 0x8b, 0x1e, 0x6a, 0x94, 0x0d, 0xcc, 0x33, 0x77,
- 0xe1, 0x3c, 0x62, 0x4a, 0xe3, 0xca, 0xc0, 0x0f, 0xfc, 0xb5, 0xe4, 0xfc,
- 0x1b, 0xe8, 0x2b, 0xf2, 0x52, 0x05, 0x8b, 0x37, 0x50, 0x27, 0x55, 0xb1,
- 0xf8, 0x43, 0x62, 0x31, 0x57, 0xc3, 0x62, 0x24, 0x48, 0x92, 0xef, 0x3e,
- 0xc7, 0x62, 0xef, 0x1f, 0xe0, 0xf7, 0x2f, 0x62, 0x6e, 0xbd, 0xe6, 0xf7,
- 0xc8, 0x1c, 0xe6, 0x58, 0x9f, 0x3b, 0x02, 0xf2, 0xb0, 0xc6, 0x9b, 0x8d,
- 0xbe, 0x47, 0xeb, 0xb1, 0xe1, 0xd1, 0x18, 0x6e, 0x7e, 0x54, 0xa9, 0xd7,
- 0x7c, 0x78, 0x2d, 0xe4, 0xa2, 0x5f, 0xa4, 0x27, 0x70, 0xa6, 0x25, 0xe9,
- 0xee, 0x83, 0xee, 0xa3, 0x7a, 0xad, 0xdb, 0x8b, 0x5a, 0xa3, 0x84, 0xd4,
- 0x28, 0xb2, 0xff, 0x7d, 0xe6, 0xfa, 0xa6, 0xa4, 0xcc, 0xef, 0xac, 0x70,
- 0x7f, 0xca, 0xa7, 0x16, 0xdf, 0x6b, 0x98, 0x32, 0xdb, 0x6e, 0x54, 0xb1,
- 0x76, 0x4d, 0x0d, 0x6b, 0x5f, 0x9b, 0xb2, 0xf1, 0x4b, 0xd6, 0x85, 0xcd,
- 0xe9, 0x28, 0x56, 0xeb, 0x1a, 0xef, 0xe8, 0x5e, 0x2a, 0x8a, 0x7e, 0xc6,
- 0xc5, 0x58, 0xaa, 0xa8, 0x37, 0xa8, 0x3b, 0x18, 0xcb, 0x55, 0xec, 0xa7,
- 0xce, 0x50, 0x9f, 0xdc, 0x68, 0x56, 0x7b, 0xa9, 0xd1, 0x9a, 0x3e, 0xb9,
- 0xb1, 0xac, 0xf3, 0xd1, 0x25, 0x06, 0xa2, 0x38, 0xcd, 0x35, 0x7b, 0xfc,
- 0xaa, 0x3e, 0x79, 0x1d, 0xa9, 0xac, 0xd6, 0x27, 0x2e, 0x79, 0xbf, 0x54,
- 0xd1, 0x27, 0x5a, 0x8f, 0x68, 0x2d, 0xa2, 0xfb, 0x85, 0x6e, 0xf6, 0x0b,
- 0x72, 0x5a, 0xeb, 0x15, 0xa3, 0x5b, 0xfa, 0x86, 0x19, 0x61, 0x8d, 0xcc,
- 0x30, 0x96, 0x97, 0x61, 0xd7, 0x23, 0x4d, 0x8c, 0x45, 0x23, 0x76, 0x38,
- 0x2b, 0xac, 0x25, 0x9e, 0xe6, 0x4f, 0x6a, 0x90, 0xdf, 0xd3, 0x2e, 0x47,
- 0x35, 0xc7, 0x32, 0xfe, 0x73, 0xe3, 0xff, 0x5e, 0x1b, 0xd7, 0xf3, 0xb3,
- 0xac, 0xd1, 0x7a, 0xcd, 0x8f, 0xac, 0x2a, 0xee, 0xd1, 0xdc, 0xe4, 0xfd,
- 0x19, 0x2e, 0xd0, 0xc6, 0x37, 0xbf, 0x14, 0x47, 0x9b, 0x79, 0xa1, 0xe3,
- 0xf8, 0x09, 0xd7, 0xea, 0x78, 0xdb, 0x78, 0x87, 0x3e, 0x3e, 0x47, 0x1f,
- 0xff, 0xf2, 0xd1, 0x80, 0xdc, 0x84, 0x4f, 0x0d, 0xfa, 0x78, 0x3b, 0x71,
- 0xf3, 0x63, 0xff, 0x7a, 0xb4, 0xb7, 0x26, 0xdd, 0x0f, 0xcc, 0xb9, 0x7a,
- 0x0b, 0x7b, 0x09, 0x7d, 0xa7, 0xe8, 0x67, 0xdd, 0xeb, 0x1c, 0xa3, 0x7f,
- 0x99, 0xcb, 0x15, 0x0d, 0xd2, 0x6e, 0x56, 0xfd, 0xdb, 0x51, 0xf3, 0x6f,
- 0x66, 0x6a, 0x1b, 0xcf, 0xd1, 0xf5, 0x54, 0xeb, 0xd1, 0xfb, 0x2b, 0xfd,
- 0x92, 0x19, 0xdc, 0x5a, 0x89, 0x55, 0x5d, 0x90, 0xb7, 0x5e, 0x2c, 0xea,
- 0x9a, 0xdd, 0xcf, 0x9a, 0xcd, 0x9e, 0xc9, 0x94, 0x83, 0x83, 0x48, 0x4d,
- 0x73, 0xaf, 0xbd, 0xa7, 0x91, 0x0a, 0xd9, 0x4f, 0x0d, 0x9d, 0x67, 0xef,
- 0x93, 0x31, 0x64, 0x6e, 0xa6, 0xa2, 0x27, 0x6f, 0xad, 0xd5, 0xe9, 0xfe,
- 0x9a, 0xae, 0xbc, 0xbf, 0x76, 0x4e, 0x9e, 0xba, 0x72, 0xee, 0x1c, 0x7d,
- 0x97, 0xcb, 0x2d, 0xfd, 0xac, 0xfb, 0x80, 0x37, 0xfc, 0x9f, 0x29, 0x2c,
- 0x6c, 0xac, 0xe8, 0x8e, 0xcf, 0xef, 0x6c, 0x89, 0x8d, 0xe3, 0x17, 0x55,
- 0xa6, 0xe3, 0x2e, 0x13, 0xf5, 0x4a, 0x59, 0xcb, 0x42, 0x14, 0x4b, 0x33,
- 0xaa, 0x18, 0x97, 0x05, 0x0d, 0xca, 0x96, 0xe0, 0x6e, 0xc6, 0x07, 0xb6,
- 0x15, 0x0c, 0x5a, 0x23, 0x45, 0x39, 0xc4, 0x5e, 0x2e, 0xcf, 0x3e, 0x2c,
- 0xdc, 0x0f, 0xad, 0x6f, 0xf5, 0x79, 0x77, 0xeb, 0x3e, 0x8e, 0xef, 0x83,
- 0xb4, 0x67, 0xee, 0xdc, 0x10, 0x8f, 0x95, 0xfe, 0x4a, 0x3d, 0x16, 0x97,
- 0x39, 0xbd, 0x47, 0x84, 0x73, 0x9e, 0xa8, 0xe8, 0xe7, 0x41, 0xad, 0x9f,
- 0x5d, 0x8d, 0xc7, 0x31, 0x4f, 0xce, 0x9e, 0x40, 0x6a, 0xe0, 0x82, 0x29,
- 0xfb, 0x63, 0xd4, 0xcc, 0xeb, 0x6a, 0x7b, 0xad, 0xa8, 0xed, 0xd5, 0x36,
- 0xf5, 0x10, 0xed, 0xd6, 0x78, 0xac, 0xd6, 0x37, 0x23, 0x88, 0xa1, 0x69,
- 0xd4, 0x63, 0x8d, 0x4f, 0xe6, 0x8e, 0xb0, 0xce, 0xc4, 0x8e, 0xef, 0xa8,
- 0xd8, 0xfb, 0xba, 0xff, 0xa4, 0x59, 0xc9, 0xef, 0x13, 0xba, 0x4e, 0x58,
- 0xb0, 0x58, 0x77, 0xae, 0x1c, 0x93, 0xe1, 0x16, 0xf1, 0x91, 0x5a, 0x92,
- 0xf4, 0x12, 0xab, 0x85, 0xd6, 0x3e, 0x49, 0x6a, 0x9f, 0x18, 0x32, 0x27,
- 0xfe, 0x85, 0xf6, 0x69, 0xfd, 0xa6, 0x6b, 0xa1, 0x83, 0x96, 0x51, 0xaf,
- 0xb3, 0xcd, 0x48, 0x52, 0x3b, 0x3b, 0x68, 0xfe, 0x6c, 0x3f, 0x4b, 0xac,
- 0xe2, 0x3e, 0x75, 0x07, 0x1c, 0x5c, 0x33, 0x26, 0x9d, 0xa3, 0xb8, 0x40,
- 0x0e, 0xf7, 0x06, 0xb5, 0x4e, 0xbc, 0x3a, 0x9d, 0x64, 0x4d, 0x77, 0xd0,
- 0xf5, 0xd9, 0x3e, 0x31, 0xd4, 0x8d, 0xe9, 0xb3, 0x0b, 0xd3, 0x26, 0xe3,
- 0xe4, 0x98, 0x47, 0x39, 0xee, 0xa2, 0xfd, 0x44, 0x23, 0xfb, 0x2d, 0xa5,
- 0xfa, 0x59, 0x0f, 0x2c, 0xd6, 0xdc, 0x5e, 0xb4, 0x0f, 0x8e, 0x88, 0xd4,
- 0x40, 0x23, 0x52, 0xfd, 0x31, 0x78, 0xce, 0x3a, 0xa1, 0x7f, 0x63, 0x98,
- 0xd3, 0x24, 0xc0, 0xe3, 0xc5, 0x3f, 0xe7, 0xba, 0xa4, 0xb3, 0x85, 0x18,
- 0x6b, 0xf9, 0xd3, 0x54, 0xbe, 0x05, 0xa9, 0x21, 0x07, 0x9e, 0xfb, 0x3a,
- 0xe7, 0x15, 0xbe, 0x30, 0xef, 0xd9, 0xca, 0x3c, 0xfa, 0xe2, 0x7a, 0xad,
- 0xb5, 0x94, 0x7a, 0x82, 0x7a, 0xab, 0xe0, 0x68, 0xce, 0x11, 0x18, 0xf6,
- 0xf5, 0x9e, 0x3d, 0xae, 0x05, 0x99, 0xb8, 0x03, 0x9f, 0xa8, 0x42, 0x3c,
- 0xec, 0x8c, 0x54, 0x7e, 0x97, 0x90, 0x4e, 0x8e, 0xdc, 0x36, 0x5d, 0xed,
- 0xb3, 0xd8, 0x17, 0x29, 0xf5, 0x22, 0xb9, 0xe9, 0x09, 0x6a, 0x9f, 0xe1,
- 0xa9, 0x4f, 0xd4, 0x34, 0xb5, 0xcd, 0x88, 0xa7, 0xe7, 0x55, 0x39, 0xe8,
- 0xb0, 0xa3, 0xd4, 0xe3, 0xfc, 0x6e, 0xcf, 0xd4, 0x1c, 0x2f, 0xf1, 0x3c,
- 0x72, 0xc2, 0xed, 0xde, 0x7f, 0xab, 0xcd, 0x5f, 0x9a, 0xab, 0xd4, 0x18,
- 0x6d, 0x78, 0xcb, 0xc7, 0xfd, 0x11, 0x24, 0x73, 0xb3, 0xf4, 0xcf, 0x99,
- 0xe5, 0xb2, 0x7f, 0x8a, 0xf7, 0x5c, 0x2f, 0x64, 0x96, 0x77, 0xec, 0x9d,
- 0x07, 0xcd, 0xb5, 0x92, 0xf9, 0x60, 0x78, 0x75, 0x7c, 0xfe, 0x99, 0x2f,
- 0x13, 0x47, 0xf8, 0xbe, 0x39, 0xa3, 0xf7, 0x50, 0xaa, 0xc7, 0xd7, 0x3d,
- 0xfe, 0x08, 0x7b, 0xfc, 0x82, 0x6a, 0xf0, 0xde, 0x50, 0xcf, 0x75, 0xc8,
- 0xfe, 0x11, 0xe1, 0x71, 0xad, 0xcb, 0xba, 0xa0, 0xfb, 0xaa, 0x11, 0xf6,
- 0x55, 0x2e, 0x9e, 0x26, 0xc7, 0x9c, 0x2c, 0x77, 0xe2, 0xf9, 0xb2, 0x87,
- 0x67, 0x58, 0x3f, 0x9e, 0x2a, 0x5b, 0xd8, 0xfa, 0x88, 0xcc, 0x58, 0x62,
- 0x27, 0xce, 0xfb, 0xd2, 0xf9, 0x1e, 0xed, 0x36, 0x03, 0xb9, 0x7f, 0x25,
- 0x79, 0x85, 0x67, 0x14, 0x72, 0x66, 0x8b, 0xb0, 0x03, 0x1b, 0xdf, 0xe9,
- 0x30, 0x70, 0x38, 0x3e, 0x84, 0xbe, 0xf6, 0xbb, 0xf9, 0xb2, 0xd0, 0x7a,
- 0x40, 0xd7, 0x6a, 0xdd, 0x6f, 0x34, 0xe3, 0x4e, 0xf2, 0xd9, 0xd5, 0x4b,
- 0x43, 0xfc, 0x3a, 0xdd, 0xd6, 0xf9, 0x92, 0xa0, 0x66, 0x68, 0x91, 0x59,
- 0xe0, 0xa7, 0xd8, 0xc8, 0x7e, 0x21, 0xb3, 0x6c, 0x7f, 0xad, 0x37, 0xff,
- 0x29, 0x56, 0xea, 0x3e, 0xc3, 0x6f, 0x66, 0xbd, 0xab, 0xc6, 0xe1, 0x70,
- 0xc5, 0x8f, 0x06, 0x9a, 0x0e, 0x16, 0x54, 0xbd, 0x27, 0x73, 0x93, 0x15,
- 0x1d, 0xb5, 0xd0, 0xb9, 0x91, 0x7d, 0x40, 0xc3, 0x01, 0xcf, 0x5d, 0x27,
- 0x14, 0x63, 0xb1, 0x9b, 0xb1, 0x48, 0x86, 0x31, 0xb6, 0xdb, 0xcd, 0x41,
- 0x32, 0x6c, 0x16, 0x79, 0x71, 0x8b, 0xae, 0xb1, 0x75, 0xf5, 0xec, 0xbf,
- 0x59, 0x53, 0x27, 0x0d, 0xf6, 0x23, 0xba, 0x1f, 0x8f, 0x62, 0x2a, 0xdd,
- 0xc6, 0x3e, 0x29, 0x8a, 0xed, 0xe9, 0x1e, 0xea, 0x1a, 0x03, 0xc6, 0xc1,
- 0x4b, 0x6a, 0xe5, 0x17, 0xfa, 0x88, 0x4d, 0xe3, 0x9a, 0xc3, 0x6c, 0xb1,
- 0x91, 0xf9, 0x9b, 0x59, 0x46, 0xb1, 0x76, 0x8b, 0xee, 0xe1, 0xf5, 0x1d,
- 0x1c, 0xf6, 0xc7, 0x06, 0xa6, 0x17, 0x38, 0xd8, 0xd5, 0x2d, 0x13, 0x05,
- 0xe8, 0x5c, 0xfe, 0x6a, 0x4d, 0x81, 0x93, 0xfd, 0xbd, 0x3a, 0x03, 0x67,
- 0x03, 0x6d, 0x91, 0x75, 0x4a, 0xb5, 0xa6, 0x4d, 0xe4, 0x2a, 0xf5, 0x26,
- 0xe1, 0x64, 0xd9, 0xff, 0xcd, 0x4c, 0xb1, 0x27, 0x3b, 0xa8, 0xd4, 0x4e,
- 0x62, 0xe9, 0xe3, 0x8e, 0xe1, 0x43, 0xec, 0xc4, 0xf7, 0xb6, 0xb2, 0xb7,
- 0xfa, 0x3a, 0xdb, 0xb7, 0xb7, 0x8a, 0xdf, 0x24, 0x7f, 0x1b, 0xdd, 0x09,
- 0xe8, 0x7e, 0xa7, 0xa0, 0x22, 0x9e, 0x37, 0xfb, 0x38, 0xb5, 0xe0, 0x6f,
- 0x96, 0x75, 0xc1, 0x9d, 0x5f, 0xf5, 0xd5, 0x6a, 0x6a, 0xa9, 0x8f, 0xc8,
- 0xf9, 0x61, 0xe5, 0x73, 0xcc, 0x59, 0x37, 0x7e, 0x49, 0x6d, 0xa6, 0x6f,
- 0x7a, 0xaa, 0x76, 0x59, 0xf5, 0x01, 0x9b, 0xc4, 0x6b, 0xe1, 0xac, 0xf9,
- 0x03, 0x36, 0x7d, 0x5e, 0xef, 0x62, 0xce, 0x9a, 0xf1, 0xc5, 0xb4, 0x51,
- 0xba, 0xd3, 0x15, 0xfc, 0xf8, 0xf8, 0xc8, 0x1b, 0x4e, 0xcc, 0x47, 0xa1,
- 0x93, 0x39, 0x36, 0xfb, 0x4f, 0x1c, 0x6b, 0x5f, 0x0a, 0xfc, 0xa6, 0xfc,
- 0x5d, 0xf2, 0xbe, 0xd1, 0xd5, 0x82, 0xc2, 0x0c, 0x6d, 0x3c, 0xf4, 0x75,
- 0x62, 0x32, 0x3f, 0x86, 0xfb, 0xd8, 0x46, 0xe0, 0x59, 0xd6, 0xdb, 0x63,
- 0xe4, 0x8c, 0xe6, 0xb4, 0x83, 0x32, 0x9f, 0x8f, 0x94, 0x92, 0x83, 0xa7,
- 0x99, 0xb7, 0xc7, 0xf9, 0x7c, 0x94, 0xf7, 0xdc, 0x4a, 0x7d, 0x77, 0xef,
- 0x78, 0x3d, 0xbe, 0x3d, 0x1e, 0xc3, 0xd6, 0xf1, 0x80, 0x9a, 0x02, 0xb7,
- 0x35, 0x72, 0xdf, 0x57, 0x89, 0xe7, 0xcd, 0x4b, 0xaf, 0xc3, 0x5a, 0x27,
- 0xe9, 0xde, 0xcd, 0xdc, 0xab, 0x3b, 0x08, 0xc7, 0x21, 0x8e, 0xfe, 0xd9,
- 0x5b, 0x2e, 0xd0, 0x44, 0xbd, 0xbf, 0xd4, 0x12, 0xeb, 0xc7, 0x57, 0x57,
- 0x9e, 0x47, 0xd2, 0x79, 0x6a, 0x0b, 0x62, 0xb2, 0x44, 0x4c, 0x32, 0x36,
- 0x4f, 0x97, 0x88, 0x4b, 0x6a, 0xc3, 0x93, 0x25, 0x8d, 0x6d, 0x1f, 0xcf,
- 0x75, 0x0c, 0xa9, 0x2a, 0x56, 0x3e, 0x55, 0x4f, 0x78, 0xaf, 0x45, 0x50,
- 0x6f, 0xe9, 0xdf, 0x76, 0xf0, 0x66, 0x31, 0xe1, 0x6c, 0x28, 0x6b, 0x3c,
- 0xfc, 0x6d, 0x0d, 0x0f, 0x6f, 0x47, 0xaa, 0xfa, 0x44, 0xce, 0x4c, 0x42,
- 0x73, 0xdd, 0x62, 0xe7, 0xa6, 0xd2, 0xf0, 0x34, 0x7d, 0x9f, 0xa7, 0xc6,
- 0x76, 0xdf, 0x67, 0xc8, 0xc7, 0xa6, 0x8c, 0x2e, 0xf6, 0xd4, 0xf4, 0x87,
- 0xbe, 0x33, 0xf3, 0x37, 0x2d, 0x3b, 0x75, 0x4c, 0x8e, 0x17, 0x71, 0x2b,
- 0xfb, 0x1e, 0x3f, 0x44, 0xf5, 0x6e, 0x53, 0xbc, 0xf3, 0x43, 0xbc, 0xf3,
- 0x0f, 0xf9, 0x3c, 0x51, 0x4a, 0x66, 0x7b, 0x78, 0xe7, 0x27, 0xf9, 0x3c,
- 0x59, 0x6a, 0xad, 0xd3, 0x67, 0x4c, 0x4e, 0x85, 0xac, 0x03, 0x2f, 0xab,
- 0x52, 0xbc, 0x12, 0x0e, 0xf6, 0xc0, 0x06, 0x1a, 0x0e, 0xce, 0xf1, 0xb3,
- 0xfe, 0x6d, 0x49, 0xd7, 0x38, 0xcd, 0xf9, 0x83, 0xba, 0x26, 0x67, 0xae,
- 0x14, 0x97, 0xd4, 0x47, 0x9e, 0x0c, 0x9f, 0xc6, 0x29, 0x35, 0x1f, 0xa9,
- 0x99, 0xf9, 0x42, 0x4e, 0xaf, 0x30, 0xa4, 0xbb, 0xc8, 0xac, 0x72, 0x75,
- 0x67, 0x8d, 0xab, 0xbd, 0xa9, 0x1b, 0xeb, 0xaa, 0x77, 0x48, 0x39, 0x47,
- 0x30, 0x8f, 0xd8, 0xd7, 0x35, 0x55, 0xf3, 0x8f, 0xfe, 0x4c, 0x7d, 0x67,
- 0x85, 0x09, 0x93, 0x7e, 0x08, 0x6f, 0xd5, 0x63, 0xd1, 0xda, 0x6f, 0x3e,
- 0x29, 0x5f, 0xf7, 0x82, 0xd3, 0xf1, 0x1e, 0x7e, 0xa7, 0x7b, 0xc1, 0x4f,
- 0x54, 0x2e, 0xde, 0xf3, 0x19, 0x67, 0x15, 0xd0, 0x45, 0xed, 0xf1, 0x3e,
- 0x39, 0xa1, 0x83, 0x2a, 0x4a, 0xe0, 0x14, 0xfb, 0xb0, 0x23, 0x5d, 0x49,
- 0x67, 0x17, 0xf7, 0x0b, 0x1d, 0x87, 0x5c, 0xb0, 0x93, 0x3a, 0x93, 0x73,
- 0xca, 0x1d, 0x5c, 0xa3, 0xb9, 0xf0, 0x3e, 0xfa, 0xe6, 0xb7, 0xed, 0x96,
- 0xe7, 0x63, 0x57, 0xe9, 0x39, 0xc3, 0xf2, 0xb4, 0x5f, 0x52, 0x99, 0x5d,
- 0xb4, 0xe7, 0x2c, 0xed, 0x89, 0x78, 0x21, 0xb9, 0x31, 0x55, 0x59, 0x5f,
- 0xb0, 0xb4, 0x1d, 0x15, 0x7b, 0x38, 0xa6, 0x39, 0x4f, 0xf6, 0x9f, 0x62,
- 0x8d, 0xdd, 0x02, 0xfd, 0x3b, 0x85, 0xb6, 0xa1, 0x2d, 0xb1, 0x85, 0xf6,
- 0x1c, 0x8e, 0x57, 0xf8, 0x94, 0xdf, 0xf1, 0xbc, 0x92, 0xb1, 0xbe, 0x9e,
- 0x78, 0xbf, 0x22, 0x9d, 0x60, 0x6c, 0xbb, 0xa8, 0xef, 0xab, 0x71, 0xde,
- 0x57, 0xc1, 0xf2, 0xff, 0x00, 0xb0, 0x60, 0x72, 0xf9, 0x60, 0x17, 0x00,
- 0x00, 0x00 };
-
-static const u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 };
-
-static struct fw_info bnx2_tpat_fw_06 = {
- /* Firmware version: 4.6.16 */
- .ver_major = 0x4,
- .ver_minor = 0x6,
- .ver_fix = 0x10,
-
- .start_addr = 0x08000488,
-
- .text_addr = 0x08000400,
- .text_len = 0x175c,
- .text_index = 0x0,
- .gz_text = bnx2_TPAT_b06FwText,
- .gz_text_len = sizeof(bnx2_TPAT_b06FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_TPAT_b06FwData,
-
- .sbss_addr = 0x08001b80,
- .sbss_len = 0x44,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08001bc4,
- .bss_len = 0x450,
- .bss_index = 0x0,
-
- .rodata_addr = 0x00000000,
- .rodata_len = 0x0,
- .rodata_index = 0x0,
- .rodata = bnx2_TPAT_b06FwRodata,
-};
-
/* Initialized Values for the TX Patch-up Processor. */
static const struct cpu_reg cpu_reg_tpat = {
.mode = BNX2_TPAT_CPU_MODE,
@@ -3570,882 +71,6 @@ static const struct cpu_reg cpu_reg_tpat = {
.mips_view_base = 0x8000000,
};
-static u8 bnx2_TXP_b06FwText[] = {
- 0xad, 0x7b, 0x0f, 0x70, 0x54, 0xe7, 0x75, 0xef, 0xef, 0xee, 0x1f, 0x69,
- 0x57, 0x5a, 0xad, 0x2e, 0x78, 0xc1, 0xab, 0x54, 0x29, 0x7b, 0xd9, 0xbb,
- 0xd2, 0x1a, 0x09, 0xb8, 0x0b, 0xc2, 0x88, 0xe8, 0xd6, 0x6c, 0x85, 0x00,
- 0x21, 0x64, 0x2c, 0x63, 0x25, 0x15, 0x7d, 0x9e, 0x5a, 0x0f, 0x64, 0x23,
- 0xdb, 0xd8, 0x16, 0x35, 0x6d, 0xe5, 0xd4, 0xad, 0xd6, 0x92, 0xc0, 0xc2,
- 0xac, 0xb8, 0x22, 0x0b, 0x11, 0xee, 0xf4, 0xbd, 0xc8, 0x96, 0xb0, 0xb0,
- 0xb3, 0x62, 0xed, 0xa4, 0xaf, 0xd3, 0xcc, 0x34, 0xe3, 0x7d, 0xfe, 0x83,
- 0x49, 0x1e, 0xb6, 0xd3, 0x4e, 0xe7, 0x3d, 0xa7, 0xf3, 0xde, 0x84, 0x17,
- 0x63, 0x62, 0xa7, 0x89, 0xed, 0xe6, 0xa5, 0xf3, 0x44, 0xea, 0xf8, 0xbe,
- 0xdf, 0xb9, 0x77, 0x17, 0x88, 0x9b, 0x4e, 0x67, 0x3a, 0x4f, 0x33, 0x9a,
- 0xd5, 0xde, 0x3f, 0xdf, 0x77, 0xce, 0xf9, 0xce, 0xf9, 0x9d, 0xdf, 0x39,
- 0xdf, 0xa7, 0x06, 0xa0, 0x0a, 0xa5, 0x9f, 0x1a, 0xfe, 0xb6, 0x0c, 0x0d,
- 0x1f, 0x4a, 0xad, 0xb9, 0x75, 0x0d, 0xff, 0xbc, 0x15, 0x6a, 0x85, 0x4f,
- 0x6e, 0xde, 0xaa, 0x00, 0xfd, 0x3f, 0xc6, 0xbf, 0xeb, 0xe7, 0xf3, 0xff,
- 0xbe, 0xd7, 0x9c, 0x1f, 0x2f, 0xa0, 0x96, 0xe5, 0x92, 0x5f, 0x04, 0x3c,
- 0xe6, 0xcc, 0x17, 0xda, 0x75, 0x04, 0xbc, 0x66, 0xaf, 0xb9, 0x4f, 0x07,
- 0xd2, 0xf9, 0xa6, 0xd8, 0x16, 0xfc, 0xd2, 0xce, 0x44, 0x7c, 0x90, 0xeb,
- 0x9f, 0x37, 0x3f, 0x19, 0xf9, 0xf6, 0x46, 0xed, 0xe3, 0x19, 0x2f, 0x02,
- 0xaa, 0x79, 0x1a, 0x6a, 0x03, 0x02, 0xf5, 0x7c, 0xe7, 0xcf, 0x1b, 0xfd,
- 0x5e, 0x84, 0xcb, 0x63, 0xb5, 0x62, 0xcc, 0x42, 0x26, 0x60, 0x0e, 0xa1,
- 0x72, 0x03, 0xf0, 0x5e, 0x36, 0x61, 0x8c, 0x01, 0x53, 0x1e, 0x33, 0x11,
- 0x7b, 0x05, 0x06, 0x0e, 0x17, 0x62, 0xe8, 0xe0, 0xef, 0x0e, 0xeb, 0x53,
- 0x3b, 0xe6, 0x47, 0xc6, 0xcb, 0xe7, 0xf6, 0xb6, 0x00, 0x5b, 0xb3, 0x06,
- 0x8e, 0x58, 0x08, 0xd4, 0x99, 0x8f, 0x63, 0x13, 0x3f, 0xc3, 0xe6, 0x30,
- 0xde, 0x9a, 0x8c, 0xc7, 0x9e, 0x83, 0xd6, 0xa7, 0x7b, 0xb5, 0x61, 0xa0,
- 0x69, 0x70, 0x40, 0xd1, 0xfa, 0xdf, 0x56, 0xb4, 0x9e, 0x49, 0x05, 0x01,
- 0x85, 0xcf, 0x35, 0xe5, 0xe5, 0x73, 0x18, 0xab, 0xf2, 0x01, 0x5c, 0xf2,
- 0xca, 0xfc, 0xbf, 0x45, 0x7b, 0x2b, 0xf0, 0xe9, 0xad, 0x18, 0xa7, 0x0c,
- 0x7e, 0x53, 0xc1, 0xb3, 0x2d, 0x89, 0xe8, 0x28, 0xe4, 0x7e, 0x0c, 0x5b,
- 0x0a, 0xf2, 0xa9, 0x51, 0x6b, 0xdb, 0x1e, 0x37, 0x6c, 0xfb, 0x8c, 0x51,
- 0x89, 0x8c, 0xaa, 0x45, 0x01, 0x05, 0xa3, 0x86, 0x07, 0x69, 0xb5, 0x3d,
- 0xe6, 0x83, 0x16, 0xbd, 0x17, 0xff, 0x4c, 0x9d, 0xd3, 0x49, 0x3f, 0xdc,
- 0xe7, 0xfb, 0x51, 0x89, 0xa2, 0xea, 0x5a, 0xed, 0xd9, 0xac, 0x6d, 0x9f,
- 0xd7, 0x7d, 0x38, 0x43, 0xfb, 0x8c, 0xe6, 0xff, 0xd9, 0x2e, 0xd2, 0x36,
- 0xe3, 0x7a, 0x79, 0xfe, 0x00, 0x66, 0x54, 0xdb, 0x9e, 0xe5, 0xbd, 0x23,
- 0xf9, 0xb2, 0x9d, 0x6d, 0xdb, 0xa3, 0xdb, 0xf6, 0x3e, 0xfd, 0x17, 0xf6,
- 0xde, 0x5f, 0x79, 0xd6, 0xb6, 0x9f, 0x32, 0x6e, 0xc2, 0xd9, 0x5c, 0x87,
- 0xd2, 0x35, 0xbf, 0x3c, 0xbc, 0x63, 0xda, 0xc6, 0x79, 0x03, 0xaa, 0xc7,
- 0xdc, 0xa6, 0xec, 0x98, 0xef, 0x54, 0xb6, 0x16, 0x76, 0x2b, 0xdb, 0x66,
- 0x7f, 0x57, 0xe9, 0x9c, 0xef, 0x57, 0xb6, 0x17, 0xa2, 0x98, 0xb3, 0x22,
- 0x98, 0xb5, 0xfa, 0x94, 0x8e, 0xf9, 0x5e, 0xc5, 0xd5, 0x63, 0x58, 0x69,
- 0x2f, 0x94, 0xc7, 0xba, 0x6e, 0xc7, 0x1d, 0x59, 0x13, 0x13, 0x56, 0x25,
- 0xe7, 0x59, 0xb4, 0xbf, 0xdd, 0xb8, 0x48, 0x3d, 0x0d, 0x1c, 0x2d, 0x3c,
- 0x85, 0xdb, 0xa7, 0x6d, 0x3b, 0x9f, 0x02, 0xf2, 0x05, 0xe0, 0xeb, 0x56,
- 0xbc, 0x67, 0x50, 0xb1, 0xed, 0xed, 0x09, 0x7b, 0xc5, 0x15, 0xa3, 0x29,
- 0xf9, 0x1a, 0xfe, 0xaf, 0x3d, 0x13, 0x41, 0x26, 0xc4, 0x31, 0x8e, 0x71,
- 0xcd, 0x1e, 0x98, 0x44, 0xa0, 0xd2, 0x1c, 0xc7, 0x8f, 0xb2, 0x08, 0x54,
- 0x98, 0x19, 0x9c, 0xcf, 0x8e, 0xaa, 0x01, 0xc4, 0xa3, 0x3b, 0x94, 0xcc,
- 0xb0, 0x07, 0xda, 0xd0, 0xbb, 0xd0, 0x62, 0x5c, 0x8f, 0x0b, 0xaf, 0x2a,
- 0x5a, 0xf1, 0x35, 0x68, 0xe9, 0x5f, 0x28, 0x5a, 0x67, 0x9d, 0x17, 0x69,
- 0x4f, 0x22, 0x80, 0x6f, 0x37, 0xca, 0x9a, 0x8c, 0x63, 0x8d, 0xb3, 0x36,
- 0x19, 0xdc, 0x72, 0x6d, 0x6d, 0x4c, 0x8c, 0x52, 0xae, 0x23, 0x94, 0xeb,
- 0x75, 0x43, 0x8b, 0x3e, 0x0b, 0x7b, 0xc5, 0x80, 0x21, 0xf7, 0x4c, 0x8c,
- 0x17, 0xec, 0x58, 0xd8, 0xbc, 0x44, 0x79, 0x91, 0xf9, 0x9c, 0x19, 0xc8,
- 0xd4, 0x9a, 0xbf, 0xb4, 0xdf, 0xdc, 0x10, 0xc5, 0xcb, 0x85, 0x08, 0x5e,
- 0x2a, 0xa8, 0x78, 0xb1, 0xd0, 0x01, 0xab, 0x80, 0xf0, 0xed, 0x85, 0x5f,
- 0xe7, 0xc7, 0x36, 0x42, 0x7c, 0x9e, 0x72, 0x87, 0x77, 0x16, 0x7c, 0xfd,
- 0x15, 0x26, 0x7a, 0xbe, 0x93, 0x1d, 0xb1, 0xab, 0x74, 0xf4, 0x2f, 0x31,
- 0xf5, 0xf4, 0x2a, 0x25, 0xd4, 0x4a, 0x3f, 0xec, 0x79, 0x23, 0xdf, 0xea,
- 0xd3, 0x8f, 0x07, 0xe1, 0xa7, 0xfd, 0xb7, 0x16, 0x6c, 0x7b, 0xcc, 0x38,
- 0xb8, 0x76, 0x6f, 0xeb, 0x37, 0x8b, 0x3d, 0x7a, 0x37, 0x32, 0x85, 0x01,
- 0x20, 0x6c, 0xf2, 0x93, 0xa1, 0xb8, 0xbb, 0xb9, 0x23, 0x76, 0xae, 0xdf,
- 0xe7, 0xfa, 0x33, 0x65, 0xa0, 0xdd, 0x5f, 0xb2, 0x28, 0x83, 0xf5, 0x47,
- 0x61, 0x54, 0xc5, 0xa8, 0xdf, 0xf7, 0x28, 0x67, 0x12, 0xdf, 0x28, 0xe8,
- 0x94, 0xad, 0x99, 0x32, 0xc6, 0x28, 0x5f, 0x00, 0x7b, 0x73, 0xda, 0x54,
- 0x06, 0xda, 0xc4, 0x0c, 0x56, 0x23, 0x1d, 0x51, 0xe9, 0x83, 0x7f, 0x06,
- 0x77, 0x8c, 0x6e, 0x1c, 0xb7, 0xb0, 0x4e, 0x35, 0xb9, 0xbe, 0x29, 0x3c,
- 0x5e, 0x81, 0x44, 0xff, 0xc7, 0x8a, 0x82, 0x37, 0x13, 0xdd, 0x98, 0xa4,
- 0x3e, 0xdd, 0xf9, 0x20, 0x1e, 0xcc, 0x55, 0xe1, 0xfe, 0x9c, 0x8d, 0x07,
- 0x52, 0x30, 0xab, 0xa8, 0x4f, 0x32, 0x95, 0x88, 0xbd, 0x0f, 0x1f, 0x3a,
- 0xf2, 0xdd, 0x8c, 0xa5, 0x2d, 0x48, 0x57, 0x04, 0xb0, 0x25, 0x1f, 0x62,
- 0x3c, 0xa6, 0x71, 0x7a, 0x3a, 0x00, 0xff, 0x7a, 0x0f, 0x66, 0x22, 0x15,
- 0x48, 0x36, 0x78, 0xf8, 0x1b, 0x09, 0xb7, 0x4f, 0xd7, 0x87, 0xb7, 0x5a,
- 0x3e, 0xec, 0xb7, 0x3c, 0x18, 0xc9, 0xd9, 0x76, 0x87, 0x61, 0xe3, 0xea,
- 0x7a, 0x15, 0xdf, 0xa2, 0xfd, 0x0e, 0x5a, 0x51, 0x9c, 0x2d, 0x3c, 0x49,
- 0x59, 0x22, 0xae, 0xbc, 0x16, 0x65, 0xb7, 0x28, 0xbb, 0x45, 0xb9, 0x2d,
- 0x91, 0xf3, 0x55, 0xc6, 0x8c, 0x41, 0xbd, 0x82, 0x94, 0xa1, 0x1a, 0x83,
- 0x94, 0x23, 0x9e, 0xb2, 0xe1, 0x49, 0x69, 0x99, 0xbd, 0x04, 0xaf, 0x15,
- 0x0d, 0xb6, 0xfd, 0xf1, 0x7a, 0xd1, 0x85, 0x6b, 0xee, 0xe9, 0x96, 0x18,
- 0xfd, 0xed, 0x1a, 0xc6, 0xd5, 0xf7, 0x69, 0xb7, 0xa7, 0x0b, 0x41, 0x0c,
- 0xe7, 0x1c, 0xbf, 0x3d, 0x54, 0x41, 0xb9, 0x45, 0xae, 0x82, 0x9e, 0x60,
- 0x8c, 0x26, 0xfa, 0x18, 0xa3, 0xd8, 0x49, 0x99, 0x1f, 0xb0, 0x22, 0xe1,
- 0x8e, 0xe9, 0x44, 0xeb, 0x6e, 0xc5, 0x87, 0xed, 0xf9, 0xeb, 0x72, 0x52,
- 0x5f, 0x89, 0x41, 0xea, 0xaa, 0x52, 0xbe, 0x08, 0xf6, 0x51, 0xce, 0x97,
- 0x4a, 0x72, 0xce, 0x16, 0x64, 0xae, 0xcf, 0xca, 0x5a, 0x96, 0x13, 0x99,
- 0xa5, 0x66, 0x44, 0x41, 0x55, 0x08, 0xbb, 0xf3, 0xef, 0x70, 0x2d, 0xea,
- 0xf1, 0x4d, 0xae, 0xc1, 0xcb, 0x8c, 0x91, 0x6f, 0x5c, 0xf3, 0x17, 0x59,
- 0x8f, 0x27, 0xb8, 0x0e, 0xda, 0xe9, 0x0c, 0x42, 0xe8, 0x2f, 0xa4, 0x71,
- 0x78, 0x1a, 0xe9, 0x39, 0xe3, 0x18, 0xe3, 0x7d, 0x39, 0xbc, 0x7a, 0x65,
- 0x5a, 0xd5, 0xab, 0xb0, 0x6f, 0x36, 0x82, 0xa1, 0x42, 0x3b, 0xac, 0x5c,
- 0x04, 0x07, 0xe8, 0x9b, 0x1f, 0xa6, 0xd2, 0x0f, 0x84, 0x21, 0xb2, 0x47,
- 0xf0, 0x20, 0xdf, 0x79, 0x6a, 0x3a, 0x82, 0x41, 0xda, 0x68, 0x47, 0x2a,
- 0xd1, 0x1a, 0xe4, 0xb5, 0xfd, 0xbc, 0x76, 0x84, 0xf6, 0x7f, 0xd5, 0x98,
- 0x44, 0x7f, 0x8f, 0x96, 0x04, 0x22, 0xb8, 0xcf, 0x82, 0x4a, 0x17, 0x7e,
- 0x82, 0xf8, 0x96, 0x7c, 0x95, 0xdf, 0xef, 0x2d, 0x54, 0x51, 0xdf, 0x30,
- 0xa2, 0xfa, 0x27, 0xb6, 0xbf, 0xc5, 0xb6, 0xbf, 0x66, 0x24, 0x2e, 0xfc,
- 0xd0, 0xeb, 0xc3, 0x63, 0x05, 0x0f, 0x86, 0x67, 0xab, 0xf0, 0xfb, 0x39,
- 0x1f, 0xee, 0x6c, 0xa8, 0xc2, 0xc1, 0xd9, 0x34, 0xc6, 0xa6, 0xab, 0x30,
- 0x90, 0xc3, 0x8a, 0xfb, 0x8c, 0xb1, 0x25, 0x15, 0xd0, 0x16, 0x3b, 0x90,
- 0xc4, 0x55, 0xae, 0xc3, 0x63, 0xb3, 0xa1, 0x70, 0xdf, 0xb4, 0x8a, 0xe1,
- 0xf9, 0x20, 0x9f, 0xf7, 0xf0, 0xf9, 0x4a, 0x18, 0xeb, 0xe2, 0xc3, 0x2a,
- 0x44, 0xc6, 0x6a, 0x3c, 0x3c, 0x1b, 0xc4, 0x43, 0x39, 0x15, 0x07, 0xa6,
- 0x5b, 0x30, 0x65, 0xa5, 0x71, 0x94, 0xd8, 0xf1, 0xf5, 0x94, 0xd6, 0x73,
- 0x40, 0xd1, 0xd2, 0x5b, 0x95, 0x34, 0x1a, 0x53, 0x7e, 0x5c, 0x22, 0x0e,
- 0xf9, 0x53, 0x4d, 0xad, 0x2f, 0x12, 0x1b, 0x2a, 0xcc, 0x08, 0xbf, 0x6b,
- 0x13, 0x8c, 0xd9, 0xb4, 0xdf, 0xb3, 0x1e, 0x58, 0x26, 0xf1, 0x1b, 0x09,
- 0x77, 0x59, 0x6a, 0xb8, 0xab, 0x50, 0x1f, 0xde, 0x61, 0x45, 0xc3, 0x3b,
- 0x18, 0x5f, 0x5b, 0xc5, 0x1f, 0xad, 0x00, 0x8e, 0xa5, 0x7e, 0x69, 0xf7,
- 0x2f, 0x71, 0xf0, 0x2c, 0x7c, 0xfb, 0xb4, 0x96, 0x99, 0x81, 0x66, 0x30,
- 0x1b, 0x60, 0x72, 0xde, 0xc7, 0xf5, 0x53, 0xb0, 0x44, 0x6f, 0x21, 0x8e,
- 0xab, 0x78, 0x98, 0x98, 0xf2, 0xb7, 0xc4, 0x94, 0x81, 0xe3, 0x71, 0x75,
- 0x0a, 0x41, 0xda, 0x1b, 0xd8, 0x7b, 0x2e, 0xc2, 0x35, 0xef, 0xc4, 0x93,
- 0x94, 0x6b, 0xc7, 0x86, 0x08, 0xee, 0x2f, 0xa8, 0xe1, 0x4e, 0xae, 0xdf,
- 0xfb, 0xf9, 0x68, 0x78, 0x0b, 0xd7, 0xf2, 0xdd, 0xbc, 0x16, 0x2b, 0xe2,
- 0x9f, 0xc4, 0x9f, 0x92, 0xf0, 0x00, 0xf7, 0x1d, 0xf7, 0xa3, 0x18, 0x91,
- 0xb9, 0x68, 0x73, 0xeb, 0x65, 0x3b, 0xa4, 0xeb, 0xa7, 0x0f, 0xd0, 0xd6,
- 0x8f, 0x16, 0x42, 0x78, 0xc8, 0xd2, 0x92, 0xdf, 0x50, 0x42, 0xb4, 0x69,
- 0x80, 0x76, 0x20, 0xc0, 0x2c, 0x97, 0xe7, 0x52, 0x88, 0x2d, 0x77, 0xb1,
- 0xf6, 0xe0, 0xac, 0xf8, 0x09, 0xd7, 0xde, 0xa2, 0x0f, 0xd0, 0x7f, 0xbe,
- 0x71, 0x2d, 0x56, 0x35, 0x35, 0xe3, 0x60, 0x77, 0x92, 0xfe, 0xe2, 0xda,
- 0xe8, 0xc4, 0xb4, 0xd8, 0x41, 0x9b, 0x82, 0x27, 0x8d, 0xb5, 0xeb, 0xfe,
- 0xd6, 0xbe, 0xb4, 0x4c, 0xec, 0xa1, 0x62, 0x84, 0x36, 0x3c, 0x6d, 0xd9,
- 0xf6, 0xd5, 0xf5, 0x3f, 0xb5, 0x5b, 0x6f, 0x16, 0xbb, 0x88, 0xae, 0xdf,
- 0x52, 0x24, 0x8f, 0x2c, 0xd1, 0xc3, 0xff, 0x1f, 0x7c, 0xe5, 0x0f, 0xed,
- 0x7e, 0x47, 0x3f, 0xf1, 0x17, 0x1f, 0x7d, 0xf1, 0x49, 0x8e, 0xed, 0x41,
- 0x3f, 0xc7, 0x7b, 0xc4, 0xb2, 0x3f, 0xaa, 0x33, 0x3f, 0xb5, 0x5b, 0x37,
- 0xea, 0x43, 0x8b, 0xca, 0xff, 0xe0, 0xf5, 0x08, 0x1e, 0x2e, 0xb4, 0xd2,
- 0x76, 0x1d, 0x78, 0xca, 0x12, 0x3c, 0xec, 0x64, 0xbc, 0x45, 0xe9, 0xcf,
- 0xf5, 0xf4, 0x6f, 0x9f, 0xb2, 0xd5, 0xca, 0x63, 0xc7, 0x64, 0x06, 0xdb,
- 0xe9, 0xef, 0x17, 0xb2, 0xf1, 0xd6, 0xe7, 0xa1, 0x65, 0xa8, 0x43, 0xb8,
- 0x93, 0x36, 0xee, 0xb0, 0xb4, 0x4e, 0x59, 0xd3, 0x0e, 0xe2, 0xd2, 0x2b,
- 0xd9, 0x68, 0xb8, 0xbd, 0x20, 0xf6, 0xae, 0x0f, 0x6f, 0x29, 0xdc, 0xca,
- 0xb5, 0x57, 0xb0, 0x69, 0x75, 0x80, 0x38, 0x73, 0x07, 0xdc, 0x75, 0x75,
- 0xd7, 0xee, 0xcd, 0x54, 0x53, 0xff, 0x4f, 0xd1, 0x85, 0xcc, 0x32, 0xf7,
- 0xda, 0x30, 0xaf, 0xd5, 0xae, 0x47, 0xf8, 0x0e, 0xfa, 0xc1, 0x3d, 0xf4,
- 0x83, 0xab, 0xeb, 0x7f, 0x69, 0xc7, 0x6e, 0x72, 0xfd, 0xa0, 0x7d, 0xda,
- 0x17, 0xde, 0x46, 0x3b, 0x6d, 0x35, 0x14, 0xcc, 0x1a, 0x4f, 0xa1, 0xff,
- 0x1a, 0x77, 0x48, 0xcf, 0x9c, 0x35, 0xd2, 0xc4, 0x91, 0x36, 0xf8, 0x96,
- 0x60, 0xe6, 0x79, 0xe3, 0x30, 0x62, 0xae, 0xef, 0xe0, 0x40, 0x2e, 0x88,
- 0xcc, 0x9d, 0x2a, 0xe6, 0x1a, 0x55, 0x3c, 0xc2, 0xb1, 0x3f, 0x4c, 0x35,
- 0x0d, 0xbe, 0x45, 0x1b, 0xcc, 0x2c, 0x91, 0x6b, 0x69, 0xfc, 0x95, 0xf1,
- 0x65, 0xe0, 0x26, 0x77, 0xee, 0x79, 0x89, 0xd1, 0xf9, 0x16, 0x1c, 0x29,
- 0xf4, 0x29, 0x2e, 0x6e, 0x6a, 0x9d, 0x69, 0x7c, 0xcf, 0x16, 0x2c, 0x9d,
- 0x27, 0x86, 0xb4, 0xd3, 0xa7, 0xc6, 0xe9, 0x47, 0xa3, 0xc4, 0x90, 0xed,
- 0xf4, 0xa3, 0x27, 0xf3, 0xa2, 0x53, 0xc2, 0x30, 0xbc, 0x37, 0x33, 0x37,
- 0xd3, 0x3e, 0x96, 0x93, 0xf3, 0x6b, 0x55, 0xfd, 0x30, 0xa6, 0x1c, 0xd9,
- 0x86, 0x95, 0x3b, 0xc8, 0x31, 0x2e, 0xf9, 0x51, 0x1b, 0xd5, 0x1f, 0xc1,
- 0x69, 0xe7, 0x5a, 0x84, 0xef, 0xa6, 0x3d, 0x1e, 0x1d, 0xaa, 0x6a, 0x76,
- 0x30, 0xaf, 0x8a, 0xef, 0x77, 0x2a, 0x3b, 0x98, 0x6b, 0xd3, 0xcc, 0xb5,
- 0x69, 0xe6, 0xda, 0x34, 0xe7, 0x4f, 0x33, 0xc7, 0xb6, 0x17, 0x86, 0x95,
- 0x1e, 0xb1, 0xbb, 0xd8, 0xdf, 0x72, 0xf9, 0x03, 0xb1, 0x27, 0xbc, 0xbd,
- 0xb0, 0xc6, 0xe3, 0x72, 0xba, 0x61, 0xa5, 0xc4, 0x61, 0x02, 0x55, 0x3a,
- 0x73, 0x98, 0x35, 0xac, 0x74, 0x31, 0xcf, 0xf6, 0x39, 0x36, 0x8c, 0x0f,
- 0x5d, 0x66, 0x7e, 0x7d, 0x93, 0xf9, 0x35, 0x9f, 0x62, 0x3c, 0xad, 0xbe,
- 0x6a, 0xf7, 0x2f, 0x73, 0x73, 0xc1, 0x18, 0xe5, 0xfc, 0x1a, 0xd7, 0xaa,
- 0xc8, 0x1c, 0xda, 0xe1, 0x55, 0x70, 0x9f, 0x8e, 0xda, 0x3a, 0x62, 0xe9,
- 0x91, 0x02, 0xf1, 0xdf, 0x88, 0xb7, 0x7e, 0x40, 0x83, 0x1e, 0xd1, 0xfd,
- 0xb8, 0x7a, 0x13, 0x49, 0x8e, 0xde, 0x8e, 0x63, 0xb9, 0x4a, 0x0c, 0xa6,
- 0xd2, 0x4b, 0x03, 0xe4, 0x28, 0x9d, 0x2d, 0x78, 0x9c, 0x53, 0x2b, 0x51,
- 0x33, 0x41, 0x7f, 0x41, 0xfa, 0x38, 0xf3, 0xc3, 0xa4, 0x75, 0x2b, 0xf2,
- 0xcc, 0xa3, 0x73, 0x86, 0x0f, 0x6f, 0xe6, 0xd7, 0x10, 0xdf, 0x12, 0x46,
- 0x48, 0xa9, 0x62, 0xdc, 0x9a, 0xc8, 0x5a, 0x82, 0x4b, 0xb6, 0x3d, 0x27,
- 0x32, 0x24, 0x12, 0xe9, 0x51, 0x08, 0x56, 0xd9, 0x2b, 0xee, 0x4d, 0x55,
- 0x60, 0x53, 0x22, 0x8c, 0x15, 0x7a, 0xbf, 0xd2, 0x59, 0x48, 0x18, 0xaf,
- 0xe2, 0x77, 0x95, 0x7b, 0xe6, 0x4d, 0xc6, 0x74, 0x9f, 0xb2, 0x67, 0xbe,
- 0x0a, 0x97, 0x22, 0x22, 0x23, 0x6a, 0xfd, 0xba, 0x07, 0xef, 0xdd, 0xa5,
- 0x40, 0xd5, 0xd3, 0x38, 0xdf, 0xa2, 0xd2, 0x9f, 0x3a, 0xc9, 0x2d, 0x62,
- 0xf0, 0x2e, 0x44, 0xc3, 0x3b, 0xb9, 0x06, 0xd5, 0x0b, 0xb2, 0x2e, 0x1d,
- 0xb4, 0x55, 0x3d, 0xfd, 0xaf, 0x53, 0xe9, 0xa0, 0x1d, 0xbb, 0x66, 0xa1,
- 0x56, 0x99, 0xbd, 0xca, 0xb6, 0x82, 0x46, 0x3b, 0x89, 0x4d, 0x86, 0xc9,
- 0x91, 0xc4, 0x47, 0xca, 0x6b, 0x28, 0x7e, 0x7a, 0xe3, 0x3a, 0xf6, 0x79,
- 0x24, 0xd6, 0x36, 0xad, 0x36, 0x19, 0x87, 0x1e, 0xca, 0x25, 0x32, 0x04,
- 0x50, 0xdb, 0x68, 0xaf, 0xf8, 0x30, 0xb5, 0xc0, 0x7b, 0x26, 0x8e, 0x17,
- 0xba, 0xb9, 0x2e, 0xcd, 0x25, 0xbf, 0x52, 0xe9, 0x87, 0x1d, 0x1c, 0x5f,
- 0xfc, 0x3b, 0x0d, 0x77, 0x2d, 0x3b, 0xc9, 0x89, 0xfe, 0xb5, 0x35, 0x3c,
- 0xc8, 0x31, 0x64, 0x1d, 0x2b, 0xca, 0x7e, 0x19, 0xbe, 0x67, 0x3a, 0x8d,
- 0xf7, 0x9c, 0x1c, 0x5a, 0xf6, 0xe1, 0x61, 0xa5, 0x93, 0x6b, 0x09, 0xbf,
- 0x3b, 0xfe, 0xae, 0x69, 0xf8, 0x6b, 0x4c, 0xc4, 0xbc, 0xe4, 0x6d, 0x17,
- 0x53, 0x09, 0x75, 0x52, 0xe9, 0xe6, 0x58, 0x8c, 0x2d, 0x62, 0x7d, 0x35,
- 0xfd, 0xa6, 0x83, 0xfa, 0x76, 0x51, 0xdf, 0x2e, 0x67, 0x4e, 0xf1, 0xbb,
- 0x5f, 0x9d, 0x77, 0x4b, 0xe1, 0x1e, 0x47, 0xf7, 0x9d, 0x7c, 0x67, 0x0f,
- 0x65, 0xdd, 0xc3, 0xe7, 0xb7, 0x58, 0xdf, 0xe7, 0x35, 0x91, 0x57, 0xe2,
- 0xfa, 0xc6, 0x5c, 0x25, 0xb1, 0xfd, 0xdd, 0x12, 0x57, 0x40, 0xc6, 0x63,
- 0x4a, 0xec, 0x0f, 0xa1, 0xa7, 0x05, 0x81, 0xa5, 0xe6, 0x50, 0xdb, 0xee,
- 0x06, 0xe2, 0x14, 0x71, 0x32, 0x70, 0x9c, 0x1c, 0x99, 0xd8, 0x3b, 0xd7,
- 0xaa, 0x60, 0xcc, 0xb8, 0x99, 0xf1, 0x67, 0x60, 0xa2, 0xa0, 0x75, 0xc6,
- 0x78, 0xaf, 0x79, 0x52, 0xb8, 0xfb, 0x01, 0xb4, 0x93, 0xaf, 0x45, 0xcd,
- 0x41, 0x44, 0xad, 0x78, 0x74, 0x42, 0xd1, 0x06, 0xb7, 0x40, 0xbb, 0x40,
- 0xcc, 0x1f, 0x9e, 0x55, 0xb4, 0xa1, 0x3a, 0xaf, 0x96, 0x7e, 0xdb, 0xe1,
- 0xcd, 0x07, 0xb0, 0xda, 0xe1, 0x66, 0x83, 0x48, 0x92, 0xa3, 0xee, 0xe4,
- 0x98, 0xfb, 0x37, 0x29, 0xb8, 0x62, 0xfc, 0x94, 0xeb, 0xa4, 0xa5, 0x33,
- 0x8a, 0x81, 0x2c, 0xe3, 0x3f, 0x7a, 0x5c, 0x38, 0xf8, 0x01, 0x72, 0x70,
- 0x04, 0x42, 0x7c, 0x36, 0x3b, 0x19, 0x1f, 0x0e, 0x78, 0xb5, 0x24, 0xf9,
- 0x77, 0x9a, 0x63, 0x1a, 0x05, 0xf2, 0x72, 0xce, 0x11, 0xbb, 0xaf, 0x34,
- 0x66, 0xa2, 0x34, 0xa6, 0x9e, 0x07, 0xe3, 0x62, 0x02, 0xdb, 0x13, 0xcc,
- 0x01, 0xc4, 0xb2, 0xa3, 0xc2, 0xf5, 0x39, 0x5e, 0xe5, 0x71, 0x83, 0xdf,
- 0x87, 0x95, 0x3d, 0x12, 0x33, 0x95, 0x2e, 0x73, 0xab, 0xe5, 0x1c, 0x35,
- 0xe6, 0x21, 0x2c, 0x38, 0x73, 0x0c, 0xc9, 0x1c, 0x43, 0x3f, 0x52, 0xb4,
- 0xe4, 0x39, 0x45, 0x30, 0xb8, 0xa9, 0xef, 0x1c, 0x63, 0xe4, 0x88, 0xa2,
- 0xb5, 0x1e, 0xa3, 0xfa, 0x41, 0x5d, 0xc6, 0x3f, 0x54, 0x9a, 0x67, 0x08,
- 0x8d, 0x79, 0xc6, 0x5f, 0x21, 0xa0, 0x6c, 0xc9, 0xb5, 0x63, 0x6c, 0xb6,
- 0x1d, 0xa3, 0x39, 0x05, 0xf7, 0x18, 0xcb, 0x70, 0xe9, 0x66, 0xa7, 0xfe,
- 0xa8, 0x59, 0xa1, 0xd7, 0x61, 0x44, 0x45, 0xad, 0x47, 0xff, 0x3c, 0xf6,
- 0x96, 0xb8, 0xfb, 0xf6, 0x13, 0x3d, 0xc4, 0x73, 0x1b, 0x1f, 0x30, 0x56,
- 0xe2, 0x4b, 0x90, 0xf6, 0x9b, 0xad, 0xe4, 0xd9, 0x4b, 0xbd, 0x6e, 0x3c,
- 0xff, 0x7d, 0xc0, 0x5d, 0x03, 0xb1, 0xff, 0x67, 0xef, 0xb5, 0xe3, 0xe9,
- 0x5c, 0x05, 0x5a, 0xd7, 0xe3, 0xce, 0x28, 0x6a, 0x3c, 0xcc, 0x5d, 0xef,
- 0xec, 0x56, 0x1e, 0xe6, 0x3d, 0xe7, 0xd9, 0xc0, 0x6f, 0x98, 0x1f, 0xb7,
- 0xfd, 0x71, 0xa3, 0x5c, 0x97, 0x67, 0x6f, 0xbc, 0xae, 0x9a, 0xff, 0xf2,
- 0xba, 0x82, 0x17, 0x08, 0x50, 0x5f, 0x67, 0xae, 0xc8, 0x67, 0x6d, 0x78,
- 0x4d, 0x1f, 0x06, 0x27, 0x63, 0x38, 0xb0, 0x10, 0xc1, 0x42, 0x56, 0xeb,
- 0xbf, 0xc4, 0xba, 0x60, 0x6f, 0x8b, 0x8e, 0x87, 0x16, 0xa2, 0x98, 0xcf,
- 0xc2, 0x0e, 0x9a, 0x7a, 0x31, 0xa8, 0x24, 0xb1, 0x7f, 0xa1, 0x1e, 0xe7,
- 0xb2, 0xfa, 0x85, 0x51, 0x25, 0x31, 0x5c, 0x47, 0x3e, 0xf1, 0xc8, 0x42,
- 0x33, 0x1e, 0x5e, 0x08, 0xf0, 0x1d, 0x1b, 0x5d, 0xa9, 0x7a, 0x3e, 0xef,
- 0xc1, 0xf3, 0x27, 0x6d, 0x5b, 0xf8, 0xd4, 0xe0, 0x02, 0x30, 0x3f, 0xc5,
- 0x1c, 0x73, 0x86, 0xf9, 0xe6, 0x19, 0x60, 0xff, 0x33, 0x1e, 0xcc, 0x4e,
- 0xd9, 0xd8, 0x6b, 0x8c, 0xd6, 0x79, 0xe8, 0xe4, 0xfd, 0xcc, 0x07, 0x7e,
- 0xe6, 0xb6, 0x7b, 0x55, 0x17, 0xa7, 0x2f, 0x11, 0x87, 0x1e, 0x78, 0x26,
- 0x89, 0x77, 0xb2, 0x19, 0x74, 0x91, 0x77, 0x0f, 0x53, 0x96, 0xb7, 0xb3,
- 0xcc, 0x4f, 0x0b, 0x06, 0xde, 0xca, 0x06, 0x38, 0x4f, 0x33, 0x5e, 0xcb,
- 0xca, 0x33, 0xf2, 0x6c, 0x08, 0x03, 0x94, 0xe5, 0xcd, 0x6c, 0x94, 0x73,
- 0x46, 0xf0, 0x1d, 0x3e, 0x77, 0xff, 0x82, 0xce, 0x7c, 0x14, 0xe0, 0xbc,
- 0x31, 0xbc, 0x91, 0x0d, 0x51, 0xd6, 0x08, 0x73, 0xd0, 0x00, 0xc6, 0xb2,
- 0x4d, 0x17, 0xb6, 0x90, 0xb3, 0xb8, 0x39, 0x44, 0xae, 0x5d, 0xb6, 0xbb,
- 0x9d, 0x98, 0x93, 0x79, 0xca, 0xf3, 0x0e, 0x60, 0x34, 0xfb, 0x9a, 0xb7,
- 0x5c, 0x27, 0xbf, 0x30, 0xb5, 0xe8, 0x70, 0xba, 0xe7, 0x2d, 0xfe, 0x3d,
- 0x0b, 0x9c, 0xb3, 0x32, 0x76, 0xad, 0x49, 0x0e, 0xcb, 0xdc, 0xf3, 0xc3,
- 0x0d, 0xcd, 0x9c, 0x57, 0xef, 0x7f, 0x45, 0x91, 0x3a, 0xc6, 0x87, 0xd8,
- 0x33, 0x62, 0x2f, 0xc6, 0xf1, 0x3c, 0xf0, 0x57, 0xe4, 0x95, 0x8d, 0x93,
- 0x9a, 0xf8, 0x7d, 0x1f, 0xf9, 0x4a, 0x4f, 0x11, 0x0d, 0xc9, 0x87, 0x30,
- 0x62, 0x57, 0x90, 0x77, 0xd7, 0x92, 0xaf, 0x2e, 0x34, 0x33, 0xff, 0x6c,
- 0xb0, 0xed, 0xef, 0xb7, 0xc0, 0xf6, 0x98, 0xba, 0x51, 0xe7, 0x2d, 0x7e,
- 0xbe, 0x06, 0xfa, 0x85, 0xb0, 0xa2, 0x17, 0x7f, 0x88, 0xc4, 0xd0, 0xab,
- 0x10, 0xbb, 0x02, 0x6b, 0x16, 0x7c, 0x58, 0x4b, 0x7d, 0xb6, 0x4e, 0x72,
- 0x6e, 0xf2, 0x8e, 0x04, 0x75, 0xba, 0x7d, 0x92, 0x5c, 0x4a, 0x0f, 0x61,
- 0x35, 0x6d, 0x3c, 0x78, 0xca, 0xb6, 0x2b, 0x69, 0xe3, 0x46, 0xae, 0xcf,
- 0x7d, 0x27, 0x6c, 0xbc, 0x62, 0xbc, 0x42, 0x9b, 0x2a, 0xe4, 0x83, 0x2d,
- 0x7c, 0x27, 0xc2, 0xe7, 0x03, 0xd8, 0x3f, 0x29, 0x75, 0x50, 0x3d, 0x9f,
- 0xb9, 0x88, 0x63, 0xd9, 0x24, 0x9a, 0x69, 0xbf, 0x18, 0xc7, 0x6c, 0xe2,
- 0x3b, 0xb1, 0x05, 0x37, 0x97, 0xc4, 0x16, 0x7e, 0x1d, 0x0e, 0x00, 0xa7,
- 0xa7, 0xb4, 0x89, 0x22, 0xb9, 0x74, 0x8d, 0x39, 0x02, 0xe6, 0x62, 0xbc,
- 0x3d, 0xa3, 0xe0, 0xf8, 0x14, 0x6b, 0xb7, 0x0d, 0xb0, 0xab, 0xa8, 0xc7,
- 0x5b, 0x33, 0xbf, 0x89, 0xe7, 0x4e, 0x52, 0xf7, 0x67, 0x23, 0xf8, 0x7a,
- 0xd6, 0x87, 0x5b, 0x8e, 0x0b, 0x3f, 0xd3, 0x93, 0x07, 0x14, 0xa9, 0x75,
- 0xa4, 0x06, 0x49, 0xc4, 0xfc, 0x8a, 0x07, 0x0d, 0xcf, 0xf9, 0xa0, 0x9f,
- 0x8b, 0xc1, 0xdf, 0x10, 0x80, 0xde, 0xf0, 0xfb, 0xc4, 0x17, 0x0f, 0x2a,
- 0x58, 0x97, 0x6e, 0xff, 0x4a, 0x92, 0xd7, 0x22, 0xbc, 0x86, 0xdf, 0xac,
- 0x84, 0x77, 0xb9, 0x97, 0xf9, 0xb8, 0x42, 0x27, 0xb7, 0xf2, 0xd9, 0xb6,
- 0x97, 0x78, 0xbf, 0xe7, 0xab, 0xb6, 0x1d, 0x5f, 0x2f, 0xcf, 0xab, 0x88,
- 0x9f, 0xd3, 0xf9, 0x9c, 0x9b, 0x03, 0xaf, 0x73, 0x2b, 0x2f, 0x7d, 0x47,
- 0xe2, 0xf3, 0x71, 0xb8, 0xf5, 0x90, 0xcb, 0xc1, 0x5f, 0x2a, 0x08, 0x4f,
- 0x89, 0x39, 0x3a, 0x9c, 0x9d, 0x52, 0x88, 0x73, 0x26, 0x9f, 0xdd, 0x0c,
- 0x6f, 0x4a, 0x9b, 0xc8, 0x70, 0xed, 0xf7, 0xaa, 0xad, 0x78, 0xc1, 0xf2,
- 0xa3, 0x5a, 0x5f, 0x8e, 0x07, 0x7b, 0x54, 0xbc, 0x40, 0x8e, 0xcf, 0x75,
- 0x4a, 0x16, 0x51, 0xc9, 0x5a, 0x8b, 0xe3, 0x79, 0xfe, 0x1a, 0xfa, 0x57,
- 0x3c, 0xc4, 0x36, 0xaf, 0x83, 0x6d, 0x15, 0x0d, 0x40, 0x31, 0xef, 0xc3,
- 0x79, 0xdd, 0xe5, 0x77, 0x2f, 0x39, 0x79, 0x58, 0x53, 0x8b, 0xd7, 0x78,
- 0x9d, 0xd6, 0x9a, 0x56, 0x0e, 0x7b, 0x45, 0xce, 0x17, 0x0b, 0x3b, 0x7d,
- 0xae, 0xff, 0x5c, 0xf4, 0x4a, 0xfd, 0x70, 0xfd, 0x7b, 0x15, 0x3c, 0xa6,
- 0x16, 0x6d, 0xf7, 0x22, 0xe0, 0x33, 0x03, 0x6d, 0xe3, 0xfa, 0xe7, 0x6e,
- 0x90, 0xbd, 0x19, 0x63, 0x85, 0xeb, 0x75, 0x73, 0x67, 0xd6, 0xf1, 0x9b,
- 0x4e, 0xb1, 0xfd, 0x53, 0x86, 0x60, 0xeb, 0xb0, 0xd2, 0x41, 0xac, 0xca,
- 0xf8, 0xdc, 0xba, 0xf8, 0x08, 0xeb, 0xe2, 0xd7, 0xb3, 0xd2, 0x1b, 0x39,
- 0x84, 0x7d, 0x0e, 0xce, 0x0e, 0x09, 0xce, 0xc6, 0xce, 0x42, 0x1b, 0x1c,
- 0x28, 0xe1, 0xec, 0x9c, 0x8b, 0xb3, 0xfd, 0x2e, 0xce, 0x1e, 0x2a, 0xe1,
- 0xec, 0x10, 0x9a, 0xf3, 0x11, 0x72, 0xe0, 0x0e, 0xe6, 0xda, 0x6e, 0x72,
- 0x0e, 0xc9, 0x91, 0x7d, 0xca, 0xce, 0xf9, 0x80, 0xb2, 0x2d, 0x17, 0xc0,
- 0xeb, 0xe4, 0x53, 0x33, 0xbd, 0x50, 0x6f, 0xd9, 0x80, 0xe0, 0xce, 0x5c,
- 0x0f, 0x2a, 0x75, 0xa9, 0x03, 0x2b, 0xb1, 0xdd, 0xc9, 0x55, 0x52, 0x2f,
- 0x49, 0x2f, 0xa0, 0x97, 0x58, 0x07, 0x35, 0x68, 0xba, 0x75, 0xbf, 0xe0,
- 0xde, 0xed, 0x7c, 0xf7, 0x2c, 0xfd, 0x10, 0x6e, 0x4e, 0x53, 0xee, 0x60,
- 0x3d, 0xf0, 0x61, 0x4a, 0x41, 0xf1, 0xce, 0x00, 0x38, 0x16, 0xf5, 0x3d,
- 0xd0, 0x36, 0x3e, 0xd5, 0xa3, 0x74, 0xcc, 0xce, 0x05, 0x99, 0xb7, 0x99,
- 0x93, 0x66, 0x82, 0x6e, 0xae, 0xfe, 0xec, 0x58, 0xd2, 0x73, 0x49, 0xb6,
- 0x6d, 0x22, 0xc7, 0x69, 0x5d, 0xff, 0x8f, 0x36, 0x7e, 0x47, 0xde, 0xff,
- 0xcf, 0x25, 0xfb, 0xa5, 0x29, 0x4f, 0x24, 0xb0, 0xbd, 0xa0, 0x06, 0xd2,
- 0x85, 0x0e, 0xbe, 0xdf, 0xc3, 0xb1, 0x7a, 0x83, 0x1d, 0xd6, 0xdd, 0xc1,
- 0xad, 0x56, 0x77, 0x70, 0x9b, 0xc5, 0xd8, 0x2d, 0xf4, 0xd2, 0x8e, 0x3d,
- 0xac, 0xe1, 0xef, 0x26, 0x7f, 0x90, 0x31, 0xfb, 0xc9, 0x65, 0x82, 0xd4,
- 0x6d, 0x84, 0xba, 0x15, 0xa3, 0x7e, 0xa4, 0x35, 0x3f, 0x34, 0x75, 0xcc,
- 0x59, 0xb7, 0x09, 0xa7, 0x8f, 0x54, 0x65, 0xae, 0x6e, 0xeb, 0x3a, 0x41,
- 0x4c, 0x37, 0x1b, 0xda, 0x6e, 0x39, 0x85, 0x25, 0x7e, 0x53, 0xea, 0x5e,
- 0xd6, 0xb2, 0x89, 0x84, 0xf1, 0x3e, 0x12, 0xd1, 0xd7, 0xf9, 0xec, 0x28,
- 0x7d, 0x75, 0xcc, 0xe9, 0x1d, 0x70, 0x01, 0xf2, 0xcd, 0xe8, 0xb2, 0x02,
- 0xc1, 0xdb, 0x59, 0x57, 0x85, 0x4d, 0xad, 0x75, 0x97, 0x57, 0x7a, 0x19,
- 0xc5, 0xdf, 0x0e, 0xa1, 0x19, 0x9d, 0x85, 0x40, 0x70, 0xcb, 0xf4, 0xe7,
- 0xf0, 0x0f, 0x27, 0x99, 0xbb, 0x20, 0x7e, 0x67, 0xdb, 0xf7, 0xb3, 0x26,
- 0x39, 0x9a, 0xaf, 0xc7, 0x15, 0x67, 0x4d, 0x7d, 0x38, 0x92, 0x8f, 0xe1,
- 0x32, 0xf1, 0xc9, 0xb7, 0x50, 0x87, 0x77, 0xa7, 0xbc, 0xd8, 0x67, 0xdc,
- 0x56, 0xca, 0x09, 0x1e, 0xdc, 0x9b, 0x3c, 0x48, 0x1e, 0xe0, 0x41, 0x2d,
- 0x39, 0xd8, 0x23, 0xce, 0x35, 0x2f, 0x6b, 0xb7, 0x2f, 0x62, 0xd8, 0xcd,
- 0x19, 0x94, 0xb1, 0x9e, 0x32, 0xb6, 0x04, 0xb7, 0xe4, 0xb4, 0xe0, 0x1d,
- 0x39, 0x04, 0xfc, 0xe6, 0xca, 0xb6, 0x33, 0x27, 0x6d, 0x0c, 0x18, 0xab,
- 0xf0, 0xe1, 0xc9, 0xd1, 0x41, 0x1f, 0xfd, 0xe5, 0x27, 0xa9, 0x3e, 0x58,
- 0xd3, 0x38, 0x4f, 0x26, 0x71, 0x31, 0x44, 0xfc, 0x6e, 0x24, 0x67, 0xa0,
- 0x1f, 0x18, 0xf3, 0x8c, 0xc5, 0x6d, 0xf4, 0x0f, 0xfa, 0x43, 0xda, 0x6b,
- 0x26, 0xfa, 0xc7, 0x48, 0x00, 0x6b, 0x28, 0x4f, 0x90, 0xf8, 0x1c, 0x5a,
- 0x88, 0x05, 0xf7, 0x30, 0xa7, 0x44, 0x59, 0x9b, 0x05, 0x13, 0xb8, 0xad,
- 0x0e, 0x89, 0xe4, 0x22, 0xf5, 0xf6, 0x2f, 0x34, 0x07, 0x77, 0x31, 0x47,
- 0x5c, 0x49, 0xd8, 0x23, 0xaf, 0x18, 0x21, 0x84, 0x17, 0x0c, 0xda, 0xbb,
- 0x0f, 0xa3, 0xf3, 0x2c, 0x97, 0x12, 0xac, 0xd7, 0x17, 0x5a, 0x83, 0xb7,
- 0x33, 0x16, 0x6b, 0x88, 0x53, 0x4d, 0x0b, 0xe9, 0xa0, 0xd4, 0x6b, 0xcd,
- 0x0b, 0x1b, 0x29, 0x9f, 0xac, 0x63, 0x73, 0xdb, 0x26, 0xfa, 0x41, 0x6c,
- 0x01, 0xdb, 0x09, 0x65, 0xaf, 0x71, 0xcc, 0xbe, 0x28, 0x79, 0xe8, 0xfe,
- 0x0d, 0x21, 0x62, 0x91, 0xd8, 0x92, 0x76, 0x2c, 0x94, 0x75, 0x92, 0xdc,
- 0xdb, 0xd0, 0xb6, 0x70, 0x4a, 0x72, 0x6f, 0xb4, 0x2d, 0x7b, 0x4a, 0xc7,
- 0x65, 0xe6, 0x8f, 0x35, 0x29, 0xcd, 0x38, 0xa7, 0xc4, 0xa3, 0x17, 0xa9,
- 0x8b, 0x0f, 0x3f, 0xb3, 0xf7, 0xea, 0x89, 0xe2, 0x4a, 0xc6, 0x4f, 0x2d,
- 0xf1, 0x2f, 0x4a, 0x5c, 0xaf, 0x5d, 0xa0, 0x61, 0x16, 0x7e, 0x46, 0xff,
- 0x88, 0x22, 0x90, 0xd0, 0xf1, 0xde, 0xc9, 0x24, 0xed, 0x70, 0x6d, 0xcc,
- 0x03, 0xa4, 0x50, 0x03, 0x4c, 0x77, 0x4f, 0x3c, 0x47, 0x1f, 0x1c, 0xe7,
- 0xbc, 0x15, 0x0b, 0x22, 0xb3, 0x3c, 0x1f, 0xe1, 0xf3, 0xd7, 0xe7, 0xae,
- 0xe5, 0xdc, 0x1f, 0x9d, 0x92, 0xfe, 0x52, 0xb4, 0xed, 0xfc, 0x49, 0x77,
- 0xee, 0x44, 0x2a, 0x89, 0x9f, 0x9e, 0xd4, 0x86, 0xde, 0x53, 0xe2, 0xfd,
- 0xe7, 0x15, 0x99, 0x1f, 0xf5, 0x35, 0xf8, 0xd0, 0x1e, 0x4d, 0x24, 0x86,
- 0xf7, 0x72, 0xcc, 0xd6, 0x8d, 0xb4, 0xbf, 0x23, 0x07, 0x13, 0x3b, 0xb1,
- 0xd4, 0x4f, 0x79, 0x5c, 0x59, 0xea, 0x39, 0xf6, 0xc9, 0x52, 0x9d, 0xc5,
- 0x1a, 0xf3, 0xba, 0x3c, 0x11, 0xda, 0x21, 0xb0, 0xa7, 0x25, 0x84, 0x3a,
- 0xe7, 0x39, 0x95, 0xcf, 0x89, 0x1d, 0x7e, 0xae, 0x78, 0xf4, 0xf7, 0x89,
- 0x5b, 0x82, 0x1d, 0x11, 0x62, 0xd6, 0xdd, 0x52, 0x8f, 0x66, 0x32, 0xf4,
- 0x77, 0x3f, 0xfd, 0x7d, 0xab, 0xf8, 0xb4, 0x45, 0x9f, 0xb6, 0xe8, 0xd3,
- 0x96, 0x16, 0x1d, 0x42, 0x5c, 0x1d, 0xe0, 0xba, 0xa5, 0xa3, 0xe2, 0xeb,
- 0xbd, 0xd8, 0xc7, 0xdf, 0xfb, 0x78, 0xff, 0x08, 0x6b, 0x54, 0x2c, 0x95,
- 0x39, 0x0f, 0xa1, 0xc3, 0x7a, 0x02, 0x83, 0x39, 0xfc, 0x22, 0xd8, 0x52,
- 0x89, 0xca, 0xd5, 0x52, 0x7f, 0x6b, 0xea, 0x51, 0x3c, 0xc1, 0x1a, 0xe8,
- 0xe7, 0x4a, 0xb5, 0xee, 0xeb, 0x39, 0xa6, 0x68, 0x6a, 0x07, 0x6b, 0xd9,
- 0xbd, 0x85, 0xbb, 0xb9, 0xbe, 0xf1, 0xc1, 0xd7, 0x15, 0xd6, 0x41, 0x75,
- 0x9c, 0x9b, 0xb1, 0x74, 0x07, 0xe7, 0xb1, 0x44, 0x0e, 0x07, 0x5f, 0x7f,
- 0x0f, 0x62, 0xdb, 0x6f, 0x37, 0x0e, 0x70, 0x7e, 0x57, 0x8e, 0x51, 0xd6,
- 0x83, 0x03, 0x8c, 0xb1, 0x7d, 0x4e, 0x7c, 0xf5, 0x72, 0x8c, 0xeb, 0xb8,
- 0xb5, 0x25, 0x2b, 0xf9, 0xd2, 0xc6, 0x93, 0x86, 0x8d, 0xe7, 0xf9, 0x7b,
- 0x81, 0xd8, 0x35, 0x76, 0x03, 0x76, 0x79, 0xf8, 0xdc, 0x1e, 0x3e, 0xd7,
- 0x4a, 0xdc, 0x9e, 0x9f, 0x95, 0xbe, 0xde, 0x21, 0xe9, 0xeb, 0x21, 0x6f,
- 0x89, 0xed, 0x87, 0x70, 0x3e, 0x1b, 0x1f, 0xf6, 0x7a, 0xed, 0x11, 0xc6,
- 0xd5, 0x85, 0x8f, 0xe8, 0xbb, 0x6f, 0x6e, 0xd0, 0x7a, 0x68, 0xc3, 0xe4,
- 0xa4, 0xa2, 0x45, 0xbf, 0x8b, 0xe2, 0xf6, 0x00, 0x9a, 0x62, 0x6b, 0xbd,
- 0x09, 0x95, 0x38, 0x57, 0x1c, 0xa0, 0xa6, 0xcf, 0x16, 0x5c, 0x6c, 0xdb,
- 0x54, 0xc2, 0xb6, 0xd6, 0x7c, 0x15, 0xb1, 0x87, 0x39, 0x78, 0xd6, 0xce,
- 0x84, 0x99, 0x9f, 0x0a, 0xb3, 0x32, 0xf6, 0x08, 0x9a, 0x52, 0x32, 0x96,
- 0xde, 0x39, 0xa9, 0xe0, 0x4b, 0xd5, 0x48, 0x30, 0x37, 0xc1, 0xa8, 0xd4,
- 0x33, 0x36, 0x73, 0x90, 0xea, 0x37, 0x25, 0x3f, 0x76, 0x13, 0x0f, 0x7b,
- 0x89, 0x87, 0xc2, 0x99, 0xa5, 0xd7, 0xe9, 0xe2, 0xd1, 0xd6, 0x82, 0xac,
- 0x8b, 0xac, 0x89, 0xac, 0xcd, 0x21, 0xdc, 0x6b, 0x49, 0xdd, 0x6e, 0x63,
- 0xca, 0x48, 0xc4, 0x9e, 0x83, 0xac, 0xd3, 0x21, 0xda, 0xc2, 0x8f, 0x7d,
- 0xc4, 0xbf, 0xbd, 0x2d, 0xb4, 0x55, 0xd8, 0x8f, 0xbd, 0x4e, 0x1f, 0xa0,
- 0x6c, 0x3f, 0x3f, 0xd7, 0x50, 0x61, 0x4e, 0xfb, 0xaa, 0xdf, 0xb5, 0xa3,
- 0xdb, 0x57, 0xf4, 0x9a, 0x32, 0x5e, 0xb9, 0xa7, 0xe8, 0xda, 0x6e, 0x7b,
- 0x56, 0xc6, 0xb5, 0x71, 0xd6, 0x70, 0xb9, 0x69, 0xd9, 0x66, 0x82, 0xed,
- 0x4b, 0x36, 0x02, 0x6b, 0x6f, 0xe0, 0xa7, 0x55, 0xbc, 0xd6, 0x75, 0x9d,
- 0x9f, 0xf6, 0x09, 0x07, 0x26, 0x3f, 0xed, 0xdc, 0x49, 0x7e, 0xda, 0xa0,
- 0x94, 0xb9, 0xa9, 0xf4, 0x14, 0xca, 0xfc, 0xb4, 0xb6, 0x84, 0xcd, 0x87,
- 0xb0, 0x97, 0xdc, 0xa5, 0xae, 0x61, 0x04, 0x81, 0x75, 0x9e, 0x4f, 0x3d,
- 0x18, 0x61, 0xed, 0x51, 0x01, 0x2c, 0xb3, 0xb1, 0x72, 0x7d, 0xc6, 0xae,
- 0xd4, 0x1b, 0x62, 0x95, 0x1e, 0xe9, 0x19, 0x27, 0x32, 0x63, 0xc4, 0x12,
- 0xcf, 0x3a, 0x2d, 0x93, 0x46, 0x40, 0x5d, 0xa2, 0xdf, 0x5d, 0xaa, 0x09,
- 0xa2, 0x81, 0x1d, 0xe4, 0x36, 0x89, 0xd4, 0x2f, 0xed, 0x99, 0xc8, 0x08,
- 0xa2, 0xeb, 0x8a, 0xc3, 0x51, 0xa4, 0x0f, 0x46, 0x1d, 0x5c, 0x99, 0x40,
- 0x3e, 0x11, 0x0d, 0x74, 0x17, 0x32, 0xc1, 0xae, 0xc6, 0x18, 0x76, 0x4e,
- 0x76, 0xb0, 0xe6, 0xd0, 0xb1, 0x6d, 0xb2, 0x93, 0xf5, 0x51, 0x8f, 0xd2,
- 0x33, 0x2b, 0xf6, 0x11, 0xfb, 0x6a, 0x6a, 0xcc, 0x73, 0x63, 0x2f, 0xb3,
- 0x5c, 0xcf, 0xbe, 0xef, 0xf8, 0xce, 0xb8, 0xa1, 0xd2, 0x2e, 0xff, 0xdb,
- 0x8f, 0xb0, 0x8d, 0x33, 0x86, 0xf8, 0x1c, 0xbf, 0xb3, 0xb6, 0xda, 0xda,
- 0x32, 0x65, 0xfb, 0x74, 0xe9, 0x49, 0x47, 0x9d, 0xf5, 0x92, 0x1a, 0xab,
- 0x63, 0xb6, 0x97, 0x6b, 0x54, 0xee, 0x3f, 0xdf, 0xb8, 0x56, 0x9b, 0x83,
- 0x5b, 0x89, 0x67, 0xac, 0xc7, 0x02, 0x01, 0x62, 0x64, 0xe0, 0x94, 0x8d,
- 0x59, 0xe3, 0x1d, 0xfb, 0x49, 0xdd, 0xc7, 0xf5, 0xb8, 0x95, 0x78, 0x2b,
- 0xfc, 0xc3, 0x0c, 0xee, 0x9a, 0xf6, 0x79, 0x58, 0x5b, 0xb5, 0x54, 0xc0,
- 0xa9, 0xad, 0x9c, 0x3e, 0xe1, 0xb1, 0xfc, 0x6d, 0xc1, 0xae, 0x1c, 0xeb,
- 0x04, 0xd6, 0xa9, 0x6e, 0x8d, 0x76, 0x6b, 0xf0, 0x9e, 0x9c, 0x57, 0xa9,
- 0x33, 0xe1, 0x6d, 0xdd, 0x68, 0xe3, 0xe3, 0xf5, 0x89, 0xe1, 0xa8, 0x87,
- 0xd8, 0xc8, 0xb1, 0xac, 0x7c, 0x4b, 0xb0, 0x8f, 0x58, 0x7c, 0x7b, 0x0e,
- 0x69, 0xe9, 0xa9, 0x86, 0xd7, 0x8f, 0xf6, 0x87, 0x21, 0xfd, 0x2f, 0x7c,
- 0x89, 0xd1, 0x18, 0xa1, 0xaf, 0x45, 0xdb, 0x95, 0xc4, 0xe2, 0x20, 0x12,
- 0x17, 0x3e, 0xf6, 0xbe, 0x63, 0x3f, 0x9d, 0xdf, 0xc8, 0xe7, 0x3b, 0x89,
- 0x93, 0x69, 0xe2, 0xe6, 0xe8, 0xb0, 0x1f, 0xf2, 0x8e, 0xd6, 0xf7, 0xb6,
- 0x12, 0xa7, 0x8f, 0xe3, 0x77, 0xf8, 0xbc, 0xba, 0x8d, 0x18, 0x39, 0x6b,
- 0x24, 0xd2, 0x5b, 0x90, 0xe9, 0xac, 0x85, 0x66, 0x34, 0x2a, 0xd2, 0xaf,
- 0x12, 0xfb, 0x27, 0xf1, 0x3d, 0xce, 0xe9, 0xd3, 0xc5, 0x8e, 0x9b, 0x31,
- 0x30, 0xab, 0xa9, 0xd7, 0xfd, 0x4c, 0x6c, 0x20, 0x76, 0xe9, 0xa8, 0x40,
- 0xd5, 0x52, 0xea, 0xf6, 0x3d, 0x07, 0x4f, 0x82, 0xba, 0x8e, 0xff, 0x42,
- 0x1e, 0xf4, 0x17, 0x05, 0xe9, 0x4b, 0x96, 0xb9, 0x9d, 0xf8, 0x44, 0x73,
- 0xdb, 0x2d, 0x33, 0xc9, 0x52, 0x9f, 0x32, 0x10, 0xec, 0x9c, 0xb6, 0x71,
- 0xd2, 0x08, 0x43, 0xea, 0xf3, 0xca, 0x54, 0x91, 0x19, 0xbf, 0x19, 0xdb,
- 0x78, 0xbd, 0x63, 0xba, 0x5a, 0xe9, 0xc8, 0xd9, 0xf8, 0xa6, 0xa1, 0x65,
- 0xda, 0xbd, 0x8c, 0x65, 0x43, 0x3b, 0x0b, 0x5c, 0x26, 0x27, 0x12, 0xdf,
- 0xf2, 0x21, 0xa4, 0xbb, 0x63, 0x35, 0xcf, 0xdc, 0x46, 0xbe, 0x20, 0xb1,
- 0xe5, 0x5d, 0x53, 0x85, 0x94, 0x32, 0xe3, 0x13, 0xbb, 0x75, 0x22, 0x5d,
- 0xa8, 0x56, 0x76, 0xd3, 0x96, 0x77, 0xac, 0xab, 0xc0, 0x25, 0xc7, 0x96,
- 0xb7, 0xd1, 0x96, 0x78, 0x6b, 0x05, 0xbc, 0xe7, 0xeb, 0xd0, 0xa9, 0xc0,
- 0xa9, 0xbd, 0xaa, 0x99, 0x9f, 0xd3, 0xe4, 0xae, 0xe4, 0x7d, 0x6a, 0x2f,
- 0xbe, 0x42, 0x9c, 0x79, 0x92, 0x3e, 0xfa, 0x33, 0xbd, 0x19, 0x55, 0x5f,
- 0x6d, 0xe1, 0x3a, 0x6e, 0x0c, 0xee, 0xc8, 0xf5, 0xe1, 0xa9, 0x79, 0x1b,
- 0xcf, 0x31, 0x3e, 0x1a, 0x53, 0x19, 0xb5, 0x92, 0xb5, 0x18, 0x73, 0xd9,
- 0xe2, 0x09, 0xc7, 0xbf, 0x57, 0xb6, 0x6d, 0x9e, 0x8b, 0xc2, 0xfb, 0x15,
- 0xf9, 0xbb, 0xbe, 0x2d, 0x36, 0x27, 0x9f, 0x51, 0x7e, 0xda, 0x18, 0x32,
- 0xb4, 0xf4, 0xc7, 0xde, 0x2a, 0x54, 0x27, 0x6c, 0x7b, 0x28, 0x25, 0xd7,
- 0xf5, 0xb6, 0xa4, 0x73, 0xbf, 0x81, 0x9f, 0xe5, 0x3e, 0xf2, 0xeb, 0xc2,
- 0xf9, 0x62, 0x69, 0xea, 0xbc, 0x93, 0x79, 0xbd, 0x8f, 0x79, 0xbd, 0xce,
- 0xd4, 0xd2, 0x7b, 0xbc, 0xd2, 0x3b, 0x29, 0x1e, 0xac, 0xe5, 0xf5, 0x5d,
- 0xa5, 0xbc, 0x5e, 0x73, 0x4a, 0xfa, 0x70, 0xe4, 0x7a, 0x70, 0xf7, 0x2f,
- 0xba, 0x99, 0xd7, 0xab, 0x26, 0x7d, 0xe8, 0x62, 0x4e, 0xf7, 0x93, 0x67,
- 0x6f, 0xcd, 0xd7, 0x21, 0x78, 0xc2, 0x8b, 0x78, 0xea, 0xdb, 0x38, 0x48,
- 0x1f, 0x3b, 0x98, 0xf4, 0x2a, 0xb1, 0xe5, 0x1e, 0xda, 0xe9, 0x9f, 0x70,
- 0x40, 0xf5, 0xa2, 0x46, 0xff, 0x2e, 0x1e, 0xfa, 0x35, 0xb9, 0xbc, 0x2f,
- 0x27, 0x31, 0xbd, 0xb2, 0xad, 0xeb, 0x94, 0x9b, 0xcb, 0x43, 0xa7, 0x46,
- 0x17, 0x25, 0x97, 0xd7, 0xad, 0xef, 0xc3, 0xe9, 0x69, 0xfc, 0xe1, 0x0a,
- 0x92, 0xc4, 0x3a, 0xce, 0xd9, 0x90, 0x4a, 0xb0, 0x6e, 0xd6, 0x06, 0xb7,
- 0x29, 0x89, 0x89, 0x1a, 0xc6, 0xfe, 0x69, 0xe6, 0xf2, 0x80, 0x99, 0x50,
- 0x93, 0x1e, 0x74, 0xfb, 0xb9, 0x1e, 0x1f, 0xb0, 0x86, 0xfe, 0x61, 0x3e,
- 0xc6, 0x31, 0x2b, 0xe0, 0x63, 0x2e, 0xff, 0x40, 0xc7, 0xa7, 0x5e, 0xfa,
- 0xde, 0x65, 0x6f, 0x00, 0x57, 0xf3, 0x6e, 0x2e, 0xaf, 0x6d, 0xb4, 0x47,
- 0xae, 0xa4, 0x42, 0xf8, 0x30, 0x6f, 0xd0, 0x07, 0xfb, 0x70, 0x84, 0xb9,
- 0xfc, 0x8a, 0xae, 0xe2, 0xa7, 0xf9, 0x56, 0xfa, 0x65, 0x04, 0x3f, 0x21,
- 0xcf, 0x5d, 0xc7, 0x5c, 0x7e, 0x27, 0x7d, 0x2a, 0xc5, 0x5c, 0xde, 0xee,
- 0xf0, 0x8c, 0xe6, 0xb6, 0x33, 0x53, 0x4e, 0x2e, 0x6f, 0x64, 0x89, 0x5f,
- 0xef, 0x47, 0x62, 0x91, 0xf8, 0x60, 0xff, 0x6c, 0x63, 0x88, 0xcf, 0xd2,
- 0x6e, 0x85, 0xf5, 0x98, 0x71, 0x72, 0xcf, 0xe6, 0xe0, 0x6e, 0xce, 0xbd,
- 0xcc, 0x89, 0x33, 0x1b, 0x3b, 0xd7, 0xbd, 0x89, 0x3f, 0x58, 0xe2, 0xa1,
- 0x1f, 0x9a, 0xc1, 0x3b, 0x18, 0x6b, 0x61, 0xfa, 0xd7, 0x4f, 0x53, 0x89,
- 0xfe, 0x73, 0xac, 0x21, 0x7f, 0xc2, 0x38, 0xbb, 0x93, 0xbe, 0xb1, 0x72,
- 0x5d, 0x80, 0xeb, 0xee, 0xc6, 0x59, 0x07, 0xe3, 0x2c, 0xca, 0x38, 0x5b,
- 0xc1, 0x38, 0x7b, 0xda, 0x48, 0x24, 0x37, 0x93, 0x6f, 0xbd, 0x9e, 0x97,
- 0x58, 0x6b, 0xe1, 0xb8, 0x1a, 0xf5, 0x1a, 0xed, 0x97, 0x98, 0xd9, 0xb9,
- 0x6e, 0xf4, 0x6c, 0x35, 0xc4, 0x56, 0xf8, 0x74, 0x19, 0xb9, 0x05, 0x11,
- 0xe9, 0xc2, 0xa2, 0x37, 0x31, 0xbc, 0xca, 0x9b, 0x18, 0x7a, 0x5f, 0x79,
- 0xc7, 0x7e, 0x8b, 0x71, 0x76, 0x3b, 0xe3, 0x6c, 0x37, 0xe3, 0xac, 0xdd,
- 0xb2, 0xf1, 0x52, 0x4a, 0xeb, 0x6b, 0xf6, 0xc4, 0x8d, 0x76, 0x0f, 0x56,
- 0x54, 0x33, 0x25, 0x04, 0x91, 0xe8, 0xfc, 0x03, 0xca, 0x7f, 0xc1, 0x48,
- 0xf4, 0x24, 0x15, 0x89, 0xad, 0x18, 0x7e, 0x4c, 0xbd, 0x2b, 0x4b, 0xb1,
- 0xb5, 0x7f, 0xf6, 0xd5, 0x92, 0x6f, 0x94, 0x75, 0xf7, 0xe2, 0x45, 0x83,
- 0x18, 0xba, 0x54, 0x8b, 0x65, 0x3c, 0xbd, 0x98, 0xa0, 0x1d, 0x83, 0x89,
- 0x5e, 0x1c, 0x65, 0x1e, 0xbc, 0x9f, 0xf9, 0xf7, 0x01, 0x2b, 0xde, 0xba,
- 0x83, 0x75, 0xce, 0xa5, 0xa8, 0x16, 0x8b, 0x29, 0xbd, 0x18, 0xa0, 0x0f,
- 0x0f, 0x30, 0x5f, 0xb4, 0x5b, 0x3f, 0x57, 0xb6, 0x91, 0x23, 0xdc, 0x57,
- 0x90, 0xf7, 0xb4, 0x64, 0xbf, 0x67, 0x10, 0xfd, 0xf3, 0x82, 0x6d, 0x50,
- 0x6f, 0x32, 0x7b, 0x71, 0xdc, 0xaa, 0x40, 0x6f, 0x4b, 0xb7, 0xb2, 0xab,
- 0x20, 0xbd, 0x33, 0xc6, 0xa3, 0xc5, 0x78, 0x75, 0xe4, 0x55, 0x88, 0xa5,
- 0xdd, 0xc8, 0x4a, 0x7c, 0x5a, 0xbb, 0x95, 0x3b, 0x67, 0x25, 0xc6, 0x7b,
- 0x95, 0x5e, 0x89, 0x61, 0x6b, 0x58, 0xb9, 0x4b, 0x62, 0xda, 0xe9, 0x33,
- 0x4b, 0xdc, 0xcb, 0x3e, 0xc4, 0x6d, 0xe4, 0x6f, 0x60, 0x4c, 0x79, 0xbf,
- 0x1a, 0x65, 0xdc, 0xb5, 0x57, 0x78, 0xe8, 0xa7, 0x71, 0xae, 0x9d, 0x07,
- 0x1d, 0xc6, 0x6f, 0xda, 0x19, 0xb5, 0x9f, 0x31, 0xd5, 0x8b, 0x23, 0xd6,
- 0x6f, 0xd8, 0x57, 0x1c, 0x5e, 0x52, 0xc6, 0xf3, 0xcd, 0xb8, 0x37, 0xb7,
- 0x1c, 0x01, 0x5d, 0xf2, 0x75, 0x08, 0xc9, 0x25, 0x01, 0x54, 0xe9, 0x92,
- 0x67, 0x9a, 0xdb, 0x16, 0x4e, 0x50, 0x86, 0x0d, 0xe5, 0xf8, 0xde, 0x8c,
- 0x07, 0x89, 0x03, 0xfb, 0x52, 0xf7, 0xe2, 0x01, 0xb5, 0x0a, 0x61, 0xda,
- 0xe9, 0x61, 0x35, 0x44, 0x7c, 0xfd, 0xbd, 0xd2, 0x38, 0xff, 0xa9, 0xa2,
- 0x54, 0x33, 0x5f, 0xe3, 0x54, 0x75, 0x8c, 0xb1, 0x4d, 0xd3, 0x52, 0x9b,
- 0x44, 0xdb, 0xa2, 0xd3, 0x3a, 0xc2, 0xac, 0x55, 0x37, 0xa7, 0xb4, 0xe1,
- 0xcd, 0xde, 0xf8, 0xe0, 0xa2, 0x82, 0x6c, 0x98, 0x7c, 0x2e, 0x9f, 0x48,
- 0xf4, 0x34, 0x8b, 0x8d, 0xf5, 0x28, 0xb6, 0xd3, 0x4e, 0x5d, 0xf9, 0x08,
- 0x63, 0xe8, 0xbd, 0x0a, 0xe1, 0x46, 0xe9, 0xfc, 0xf5, 0xb1, 0xa2, 0x1c,
- 0x2b, 0x3a, 0x2d, 0x3c, 0x2d, 0x4a, 0x9e, 0xa6, 0x33, 0x0e, 0x6d, 0x7b,
- 0x13, 0xf9, 0x59, 0xe8, 0x94, 0xd4, 0x38, 0xf1, 0x09, 0x72, 0xda, 0x66,
- 0xf2, 0xdd, 0x5e, 0x7a, 0xb5, 0xbd, 0xb2, 0x21, 0x61, 0xb4, 0x2b, 0x78,
- 0x62, 0xae, 0x85, 0xf5, 0x11, 0xc7, 0xbc, 0x9c, 0x57, 0x71, 0x25, 0x1f,
- 0xc5, 0xbb, 0x1c, 0xfb, 0x92, 0x33, 0x76, 0x3d, 0x7e, 0x54, 0xc2, 0xad,
- 0x14, 0x71, 0x6b, 0x4b, 0x4e, 0xa1, 0xbf, 0xc6, 0x30, 0x62, 0xfc, 0xdd,
- 0xa7, 0x97, 0x6e, 0x0e, 0xd0, 0x6e, 0xa2, 0x8b, 0x8f, 0x9f, 0xe3, 0x78,
- 0xd8, 0xc1, 0xe9, 0x37, 0x3f, 0x9d, 0x59, 0xc2, 0xb5, 0xa2, 0xed, 0x6b,
- 0x4b, 0xef, 0xad, 0x9d, 0xf9, 0xf3, 0x92, 0xbe, 0x3a, 0x3c, 0xa7, 0x92,
- 0xa8, 0x38, 0x75, 0x4d, 0x56, 0x5d, 0xe2, 0x83, 0x19, 0xf5, 0x89, 0xaf,
- 0x71, 0xfe, 0xc7, 0xc8, 0xf5, 0x6c, 0xce, 0x7f, 0xd5, 0x99, 0x37, 0xc2,
- 0x79, 0x95, 0x6b, 0xbc, 0x30, 0x7a, 0xed, 0x1d, 0x95, 0xba, 0xe3, 0xf1,
- 0x28, 0x6d, 0xf7, 0xe1, 0x06, 0x79, 0x2e, 0x84, 0x5d, 0xf9, 0x15, 0x95,
- 0x82, 0xe3, 0x41, 0xd6, 0x01, 0xae, 0x2f, 0x91, 0xe7, 0x59, 0xcf, 0xf1,
- 0x9e, 0xf0, 0xae, 0xcd, 0xe4, 0x18, 0x9f, 0xb5, 0x7b, 0x84, 0x6b, 0xf1,
- 0x7f, 0xf8, 0x8e, 0xdc, 0xfb, 0x75, 0x79, 0xf4, 0x4f, 0x31, 0xcc, 0x1a,
- 0xe8, 0xb1, 0x5c, 0x06, 0x0f, 0xe7, 0xbe, 0xec, 0xec, 0xab, 0xad, 0x5d,
- 0x8f, 0xfb, 0x38, 0xe7, 0x81, 0x5a, 0xc6, 0xd1, 0x7f, 0x4b, 0x25, 0x84,
- 0x1b, 0xed, 0xae, 0x86, 0xe4, 0xda, 0x44, 0xeb, 0x2a, 0xc5, 0x46, 0x45,
- 0x0a, 0x43, 0x1d, 0x2d, 0x89, 0xe4, 0x15, 0x3c, 0x61, 0x4b, 0x5f, 0xd3,
- 0x5b, 0xca, 0xbb, 0x52, 0xff, 0x49, 0x6f, 0xb5, 0xbd, 0xc4, 0x91, 0xb6,
- 0x14, 0xde, 0xf9, 0x4c, 0xef, 0x40, 0xea, 0x6e, 0xc9, 0x37, 0x41, 0xa5,
- 0x9d, 0xf3, 0x1c, 0x21, 0x66, 0xbf, 0x68, 0xbc, 0x12, 0x65, 0x36, 0x86,
- 0x6f, 0x9d, 0x82, 0x83, 0x86, 0x1f, 0x99, 0x88, 0x8d, 0xdd, 0xfc, 0xdc,
- 0x4f, 0xde, 0xf4, 0x9e, 0x51, 0x83, 0x19, 0x55, 0x25, 0x57, 0x24, 0x06,
- 0x7b, 0xde, 0xf4, 0xcb, 0x5e, 0x4c, 0xcc, 0x23, 0xfb, 0xe6, 0xff, 0xd6,
- 0x5e, 0xca, 0x3a, 0xf2, 0x16, 0xd1, 0x3d, 0xa8, 0x10, 0x43, 0x93, 0x20,
- 0x97, 0xd9, 0x6b, 0x14, 0x63, 0x1e, 0xa4, 0xaf, 0x7a, 0xa0, 0x9d, 0xbe,
- 0xcc, 0xfa, 0xee, 0xb1, 0x06, 0xed, 0x74, 0x9b, 0x57, 0xc7, 0xf0, 0xf1,
- 0x00, 0x1e, 0x39, 0xbe, 0x0d, 0xb5, 0x4e, 0xef, 0x67, 0x9c, 0x36, 0xf5,
- 0xb0, 0xae, 0x1a, 0xfd, 0xa5, 0x8f, 0xf5, 0xd5, 0xd5, 0xf5, 0x8f, 0xa3,
- 0xd5, 0xb9, 0x3e, 0x86, 0xfb, 0x72, 0x41, 0xa5, 0x2b, 0xe7, 0xc3, 0xb6,
- 0x3b, 0x1f, 0x87, 0x7f, 0x5d, 0x3f, 0xe5, 0x92, 0xeb, 0xf2, 0xf7, 0x5d,
- 0xac, 0xcb, 0x44, 0xbe, 0x0a, 0xc4, 0x96, 0x53, 0xb6, 0x75, 0x3a, 0x46,
- 0x8e, 0xfb, 0x94, 0x3d, 0xd6, 0x7f, 0xb7, 0xaf, 0x3a, 0xfb, 0x34, 0x72,
- 0xad, 0x4a, 0xf6, 0xef, 0xf9, 0x8c, 0x60, 0xce, 0x00, 0x72, 0x8c, 0xed,
- 0xbb, 0x9c, 0xf7, 0xff, 0xb8, 0xc2, 0xd5, 0x29, 0xcd, 0x7a, 0xb5, 0x83,
- 0xeb, 0x27, 0xcf, 0x24, 0x4b, 0xd7, 0x9a, 0x03, 0xee, 0x19, 0x01, 0xf1,
- 0x85, 0x01, 0xdc, 0xc2, 0x45, 0x68, 0x48, 0x88, 0x8f, 0x0d, 0xa0, 0x21,
- 0x4f, 0x40, 0x5d, 0xee, 0xca, 0xfb, 0x90, 0x55, 0x64, 0xad, 0xa9, 0x13,
- 0x37, 0x69, 0xbb, 0x65, 0xf2, 0xfe, 0x2f, 0x2a, 0x7f, 0xf5, 0x7d, 0xc1,
- 0x5b, 0x72, 0xcc, 0xb0, 0x70, 0xcd, 0x5f, 0x77, 0xff, 0xb7, 0x20, 0xf7,
- 0x7c, 0xfa, 0x9f, 0x30, 0x8e, 0x13, 0x3d, 0xd5, 0x1e, 0xf1, 0x9f, 0x3f,
- 0xc1, 0x03, 0xb3, 0x8f, 0xf0, 0xbe, 0x8c, 0x7f, 0x88, 0x35, 0x84, 0x4f,
- 0xe9, 0x24, 0xfe, 0xec, 0x3f, 0xee, 0xd9, 0x55, 0x81, 0xbf, 0xb4, 0x2b,
- 0x97, 0x8d, 0xa0, 0x21, 0x35, 0xc6, 0xe7, 0x15, 0x74, 0x90, 0x2f, 0x3e,
- 0x65, 0x6c, 0xc1, 0xb6, 0x25, 0x82, 0x01, 0x2f, 0xda, 0x03, 0xbd, 0x62,
- 0x43, 0x05, 0x5b, 0x79, 0xfd, 0x25, 0xae, 0xef, 0xb3, 0x86, 0x0f, 0x0d,
- 0x4b, 0xa5, 0x8f, 0xa7, 0x4d, 0xa5, 0xd1, 0x1e, 0x70, 0xf7, 0xab, 0x32,
- 0x76, 0xad, 0xae, 0x0f, 0xdd, 0xe1, 0x69, 0x98, 0x7a, 0x9b, 0xfe, 0xd4,
- 0xbe, 0xee, 0xc6, 0x7b, 0x65, 0x9b, 0x18, 0xe4, 0x90, 0x2f, 0xd8, 0xb8,
- 0x69, 0x14, 0xea, 0xba, 0x1b, 0xd7, 0xbf, 0x2c, 0xf7, 0x21, 0xc6, 0x20,
- 0x32, 0xb5, 0xa6, 0xf4, 0x79, 0x12, 0x1c, 0xe7, 0x10, 0x7e, 0xbf, 0x30,
- 0x86, 0x83, 0xb9, 0x12, 0xa7, 0xa6, 0x6f, 0xeb, 0xeb, 0xae, 0xeb, 0xf6,
- 0x50, 0x2e, 0xd1, 0x5f, 0x53, 0xd2, 0xed, 0x00, 0xeb, 0x8b, 0x6a, 0x62,
- 0xec, 0x83, 0xb4, 0xe9, 0x90, 0x63, 0xd3, 0x5e, 0x18, 0xf9, 0xeb, 0xe3,
- 0x0e, 0x72, 0xdc, 0xa0, 0x29, 0x76, 0x93, 0x3d, 0xb2, 0x43, 0xd8, 0xcf,
- 0x71, 0xf7, 0xdd, 0x30, 0xee, 0x80, 0x71, 0x7d, 0xdc, 0xbd, 0xb9, 0xc4,
- 0x69, 0x4f, 0x69, 0xdc, 0x47, 0x67, 0xcb, 0x63, 0x64, 0x70, 0xfb, 0xba,
- 0x0c, 0xf2, 0x9b, 0x0e, 0xd8, 0x07, 0x1c, 0x7b, 0x9c, 0x72, 0xae, 0x6f,
- 0x6d, 0x10, 0xee, 0xc5, 0x3f, 0x4d, 0xd9, 0x8f, 0x4f, 0x92, 0x7b, 0xe9,
- 0xce, 0x9e, 0xf0, 0x37, 0x0a, 0xe5, 0xbe, 0x94, 0xf6, 0x4e, 0x97, 0x37,
- 0xcd, 0xd8, 0x8e, 0x04, 0x76, 0x7c, 0xa6, 0x97, 0xb1, 0x8d, 0xf5, 0xd7,
- 0x76, 0xab, 0x3b, 0xd8, 0x69, 0x05, 0xc8, 0xbb, 0xaa, 0x95, 0xad, 0x39,
- 0xe9, 0x69, 0x48, 0x2c, 0x97, 0xb8, 0x70, 0x41, 0xea, 0xbc, 0xbb, 0x59,
- 0x1f, 0x2c, 0x0f, 0x20, 0xdc, 0x8f, 0x89, 0xc2, 0xef, 0x2a, 0xe9, 0x88,
- 0xec, 0x4d, 0x4b, 0x5e, 0x01, 0x73, 0x5e, 0x0f, 0xaa, 0xe9, 0x4b, 0x11,
- 0xd3, 0x30, 0x4f, 0x36, 0xd8, 0x20, 0x47, 0x09, 0x2c, 0x35, 0xd3, 0xe6,
- 0xee, 0x06, 0x2f, 0x8e, 0x39, 0xfc, 0x4b, 0x9b, 0xe1, 0xef, 0x94, 0xc4,
- 0xcc, 0x1d, 0x39, 0xc9, 0x63, 0xa4, 0x90, 0xfa, 0x08, 0xfe, 0x31, 0x55,
- 0x1c, 0x5a, 0x82, 0xf4, 0xfd, 0x4b, 0x20, 0xf5, 0xc4, 0x04, 0xfe, 0x4a,
- 0x8f, 0x06, 0xfa, 0x0a, 0x3e, 0xa5, 0xcb, 0x9a, 0x0b, 0xee, 0xb4, 0xc2,
- 0x08, 0xb1, 0x1e, 0xeb, 0xf6, 0xc6, 0x59, 0x5f, 0x88, 0x1d, 0x03, 0x6d,
- 0xb7, 0xe4, 0xfb, 0x82, 0x1d, 0x96, 0x8b, 0x85, 0x2b, 0x67, 0x02, 0xc1,
- 0x6d, 0xd3, 0xf1, 0xe8, 0x84, 0xc3, 0xc5, 0x42, 0x6d, 0xf1, 0xbc, 0x6d,
- 0xbf, 0x61, 0x14, 0xaf, 0x56, 0x3a, 0xdf, 0x8d, 0xb6, 0x64, 0xbe, 0x19,
- 0xf7, 0x90, 0x3f, 0xb5, 0x4f, 0x37, 0xc3, 0x98, 0x06, 0x4e, 0x1c, 0x8f,
- 0x62, 0x6d, 0x4e, 0x3b, 0x3d, 0xec, 0xed, 0xc3, 0xd4, 0x7c, 0x27, 0x72,
- 0x85, 0xe0, 0x62, 0xcc, 0x43, 0x5e, 0x9d, 0xf2, 0x60, 0x97, 0x71, 0x5c,
- 0x29, 0x2e, 0x53, 0x70, 0x17, 0x11, 0xbc, 0xdf, 0xe1, 0x13, 0x73, 0xac,
- 0x47, 0x15, 0xdc, 0xe4, 0xe0, 0x6e, 0x4b, 0xdb, 0x5a, 0xf2, 0xed, 0x3b,
- 0xc9, 0x07, 0x77, 0x11, 0x57, 0x12, 0xeb, 0x6c, 0xbc, 0x99, 0xca, 0xf4,
- 0xd7, 0x40, 0xeb, 0x39, 0xcc, 0x1a, 0xa8, 0x47, 0x71, 0xf9, 0x5d, 0xd3,
- 0x9c, 0xcb, 0x09, 0x57, 0xcd, 0xb5, 0x90, 0x37, 0xb2, 0xae, 0x49, 0x69,
- 0x31, 0x8f, 0x47, 0xc5, 0x94, 0x33, 0x46, 0xac, 0xcd, 0x98, 0xab, 0x60,
- 0xbe, 0xeb, 0xc5, 0xd3, 0x8e, 0xfc, 0x49, 0xca, 0x77, 0x37, 0xbe, 0x66,
- 0xf5, 0x05, 0xfb, 0x2c, 0xd9, 0xbf, 0x8c, 0x27, 0xaf, 0x7a, 0x4d, 0xf2,
- 0xd7, 0x78, 0xac, 0xce, 0xfb, 0x05, 0x25, 0xe3, 0x6b, 0x6a, 0x9d, 0x83,
- 0xa9, 0x5c, 0x2a, 0x71, 0x36, 0xd1, 0x2f, 0x41, 0x8e, 0xd5, 0x7e, 0x3c,
- 0xb8, 0x98, 0x86, 0xdb, 0xb3, 0xd9, 0x66, 0xfc, 0x2f, 0x14, 0x23, 0xda,
- 0x44, 0x9a, 0x18, 0xb0, 0x85, 0x98, 0xdb, 0xdf, 0xeb, 0xe3, 0x7d, 0xe9,
- 0x79, 0xa9, 0x6d, 0xe3, 0x59, 0x14, 0x83, 0x66, 0x22, 0x73, 0x94, 0x9e,
- 0xd3, 0x53, 0x90, 0xfd, 0x8d, 0x00, 0x1e, 0x60, 0xed, 0x94, 0x2e, 0xed,
- 0xfd, 0x6c, 0x9d, 0x76, 0xf7, 0xb3, 0x0e, 0xcf, 0xfb, 0xc2, 0xdd, 0x56,
- 0x0b, 0xf3, 0xbd, 0xef, 0x86, 0xb1, 0x13, 0x13, 0x2b, 0x3d, 0x1e, 0xac,
- 0x5e, 0xb7, 0x47, 0x99, 0x59, 0x56, 0xce, 0xad, 0x51, 0x27, 0x1f, 0x56,
- 0x50, 0xcf, 0xf3, 0x27, 0x65, 0x8e, 0xcf, 0xb5, 0x8d, 0x9f, 0x94, 0x5c,
- 0xab, 0xb6, 0x6d, 0xb2, 0xb4, 0x3e, 0xa9, 0xfd, 0xa2, 0xb4, 0x53, 0x94,
- 0xba, 0xad, 0x30, 0xd7, 0xb4, 0xd9, 0xd3, 0x5a, 0x74, 0x40, 0x49, 0x93,
- 0xf7, 0x69, 0xc9, 0x5b, 0xbc, 0x1e, 0x3c, 0xa2, 0x6b, 0x83, 0xd2, 0x13,
- 0x7c, 0x19, 0x2e, 0x07, 0x6e, 0x9a, 0x1b, 0x60, 0x5e, 0x73, 0x6d, 0xeb,
- 0xf6, 0x07, 0xeb, 0xdb, 0x9a, 0x1d, 0x5e, 0x6c, 0xdb, 0x97, 0x53, 0xdd,
- 0xe4, 0x0c, 0xc2, 0x8b, 0xe5, 0xfa, 0xea, 0xb6, 0xc6, 0x99, 0x00, 0x65,
- 0x53, 0xf0, 0x3e, 0x73, 0xd2, 0x44, 0xa1, 0x2c, 0xa3, 0xcb, 0x99, 0x77,
- 0x90, 0x33, 0x57, 0x99, 0x5a, 0x6b, 0x17, 0x39, 0xb3, 0x9e, 0x2a, 0xd6,
- 0xf9, 0xd0, 0x8b, 0xa7, 0xac, 0x66, 0x39, 0xe3, 0xe4, 0xf0, 0xe6, 0x2b,
- 0x27, 0xb5, 0xb4, 0x70, 0xe6, 0x1f, 0x18, 0xc0, 0x3d, 0xe4, 0xcc, 0x57,
- 0xb3, 0x3e, 0xec, 0x21, 0x67, 0x5e, 0xcc, 0x06, 0xd0, 0x47, 0xce, 0xfc,
- 0x11, 0xf9, 0xd5, 0xbb, 0xa9, 0x2b, 0x78, 0xb4, 0xd4, 0x07, 0xdb, 0x9b,
- 0xf4, 0xd0, 0xaf, 0x85, 0x37, 0xff, 0xbc, 0xc4, 0x9b, 0xe7, 0xff, 0x05,
- 0x6f, 0xde, 0x4a, 0x3e, 0xd8, 0x9d, 0x13, 0x4e, 0xb0, 0x92, 0x9c, 0xc0,
- 0xc6, 0xcb, 0xa5, 0x1e, 0xd8, 0x0a, 0xe6, 0xb3, 0xa7, 0x53, 0x7d, 0xc8,
- 0x4e, 0x63, 0x79, 0x8d, 0xd3, 0x77, 0x12, 0x99, 0x34, 0xe3, 0xb2, 0x92,
- 0xe8, 0xec, 0x43, 0x82, 0xf5, 0xb1, 0x96, 0xbc, 0xe8, 0xf6, 0xc0, 0x16,
- 0xdf, 0x85, 0xf4, 0x88, 0x7c, 0xa8, 0x59, 0x00, 0x56, 0xdc, 0xd0, 0x03,
- 0xab, 0x49, 0xe0, 0x4f, 0xeb, 0x20, 0xfb, 0x9a, 0x0c, 0xb3, 0x85, 0x66,
- 0xc6, 0xa7, 0x82, 0x23, 0x89, 0x10, 0xba, 0x8f, 0x93, 0xf3, 0x38, 0x3d,
- 0x30, 0x7b, 0xe4, 0x3b, 0x46, 0x1f, 0x8e, 0xce, 0xbb, 0x3d, 0xb0, 0xed,
- 0xe4, 0x6e, 0xbe, 0x44, 0x04, 0x95, 0x0b, 0x3e, 0xbc, 0x40, 0xee, 0xbc,
- 0x95, 0xeb, 0x7c, 0xa6, 0xd4, 0x07, 0x5b, 0xc1, 0x18, 0xb1, 0x73, 0x2a,
- 0x66, 0x16, 0xf0, 0x86, 0x17, 0xb8, 0xb8, 0xc2, 0xe9, 0xed, 0x4b, 0xff,
- 0x3f, 0x84, 0x73, 0x0e, 0x77, 0x0e, 0x2e, 0x66, 0x14, 0x57, 0xb7, 0x0a,
- 0xae, 0x89, 0xac, 0xab, 0x87, 0xeb, 0xda, 0x7e, 0x52, 0xeb, 0x7c, 0x85,
- 0xb6, 0x68, 0x4a, 0xbc, 0xea, 0xac, 0xc7, 0x40, 0x4a, 0x6a, 0xd9, 0x40,
- 0x5b, 0xc0, 0x39, 0x0f, 0xa5, 0xb6, 0xfd, 0x28, 0x1b, 0xef, 0xa9, 0x2c,
- 0xc5, 0xe3, 0xaa, 0x7c, 0x05, 0xd2, 0x25, 0x1f, 0x09, 0xd0, 0xa7, 0x03,
- 0x93, 0x69, 0x54, 0x6d, 0x70, 0xfd, 0x7b, 0x55, 0x7e, 0x9c, 0xbc, 0xb5,
- 0x53, 0xea, 0xe8, 0xf0, 0x76, 0xab, 0x13, 0x53, 0x56, 0x0c, 0x95, 0xe7,
- 0x4a, 0x7b, 0xa6, 0xe7, 0xe4, 0xec, 0x5c, 0x7d, 0x9b, 0xfa, 0xd5, 0x32,
- 0x1f, 0x4c, 0x93, 0xe3, 0x44, 0x02, 0x77, 0x14, 0x84, 0x2b, 0xf6, 0xe0,
- 0xa8, 0xa5, 0x45, 0xbf, 0x87, 0xf8, 0xd0, 0xfd, 0xb4, 0x51, 0xb1, 0xee,
- 0x7a, 0xbf, 0x69, 0x40, 0xfa, 0x51, 0x9f, 0xe9, 0x37, 0x0d, 0xe7, 0xf0,
- 0x8b, 0xba, 0x96, 0x4a, 0x78, 0xd6, 0xfa, 0xc9, 0xe7, 0xb5, 0xe8, 0xd3,
- 0x78, 0x02, 0x23, 0xb9, 0x9f, 0x2b, 0x21, 0xdd, 0x37, 0xf8, 0x13, 0xaf,
- 0x16, 0x9d, 0x53, 0x42, 0x7c, 0xf7, 0xee, 0x60, 0x97, 0x75, 0x37, 0x71,
- 0x27, 0x9e, 0xec, 0x54, 0xbc, 0x98, 0x89, 0x3a, 0x5c, 0x34, 0xd8, 0xc3,
- 0x6b, 0x53, 0x85, 0x32, 0xa7, 0x71, 0x6b, 0xfe, 0xed, 0xc7, 0x5d, 0xfc,
- 0x88, 0xe7, 0x83, 0x8b, 0x97, 0xe0, 0xea, 0x56, 0x4d, 0x5d, 0x1f, 0x9c,
- 0x54, 0xed, 0xfe, 0x65, 0x12, 0xc3, 0x3a, 0xf6, 0xd0, 0xf7, 0xee, 0x99,
- 0x1e, 0xa0, 0x9c, 0xc2, 0xa5, 0x57, 0x10, 0xa7, 0xfa, 0x30, 0x4e, 0x9c,
- 0xb1, 0x28, 0x5f, 0x8e, 0x35, 0xe4, 0xe2, 0xfa, 0x8c, 0x3d, 0xb9, 0x41,
- 0x37, 0x56, 0x7b, 0x8b, 0x4b, 0xa2, 0xe4, 0x36, 0xeb, 0x98, 0xb7, 0xdb,
- 0x0b, 0xcd, 0xb8, 0x7c, 0x46, 0x67, 0x7d, 0xdb, 0x41, 0xee, 0xde, 0x83,
- 0x87, 0xa9, 0xcf, 0xa3, 0x85, 0xc7, 0x91, 0xfe, 0x92, 0x0f, 0x87, 0x8f,
- 0xa7, 0xb1, 0x6a, 0x5d, 0x0a, 0xe9, 0x2f, 0x06, 0x88, 0x53, 0x21, 0x4c,
- 0x30, 0x16, 0xa1, 0xb8, 0x7e, 0x2e, 0xe7, 0x7f, 0xfe, 0x82, 0x36, 0xfb,
- 0x26, 0xed, 0xf7, 0x8d, 0x6b, 0x7b, 0x00, 0x65, 0xfe, 0x7d, 0x9d, 0xab,
- 0x7a, 0xb9, 0x86, 0xfb, 0x9c, 0xd8, 0x8c, 0x32, 0x36, 0x75, 0x5c, 0x2d,
- 0xf5, 0x12, 0x17, 0x4f, 0x6a, 0x8b, 0xf7, 0x22, 0x3e, 0x7c, 0xd9, 0x8b,
- 0x81, 0x3a, 0xfa, 0x5d, 0x94, 0x5c, 0xf5, 0xc3, 0x44, 0xc2, 0x38, 0x47,
- 0xae, 0x3a, 0xba, 0xc1, 0xe5, 0xaa, 0x9e, 0x05, 0x15, 0x15, 0x0b, 0xac,
- 0x65, 0x9d, 0x5e, 0xe2, 0x37, 0x83, 0x6e, 0x2f, 0x51, 0xf8, 0x4d, 0xab,
- 0x9c, 0x75, 0xba, 0x8d, 0xb5, 0x5c, 0xfa, 0x0a, 0x32, 0xe8, 0x2c, 0xcc,
- 0x04, 0xef, 0x21, 0x36, 0xf7, 0x49, 0x6f, 0xa4, 0x10, 0x09, 0xdf, 0x43,
- 0xde, 0xf5, 0x2d, 0xae, 0xaf, 0xec, 0xed, 0xf6, 0x15, 0x56, 0xf3, 0xbd,
- 0x28, 0x3f, 0x05, 0x57, 0x45, 0xf6, 0x1b, 0xf5, 0xe8, 0xa9, 0x92, 0xbd,
- 0x86, 0x97, 0xa9, 0x43, 0xff, 0xdc, 0x4a, 0x3c, 0x3a, 0xe7, 0xaf, 0x12,
- 0xc2, 0xff, 0x68, 0xde, 0xc5, 0xb6, 0x58, 0xfe, 0xae, 0xa0, 0xf0, 0xc9,
- 0xf6, 0xe3, 0xee, 0x77, 0xfd, 0x86, 0xef, 0x65, 0xfd, 0x56, 0x50, 0x3f,
- 0x7b, 0x5a, 0xea, 0xa2, 0x68, 0xdb, 0x19, 0xea, 0xb7, 0x78, 0xd2, 0x89,
- 0x2f, 0xd6, 0x98, 0xf1, 0xe1, 0x84, 0x57, 0xf4, 0xfa, 0x99, 0xe8, 0x45,
- 0xae, 0xc2, 0x78, 0xe1, 0xb8, 0x1e, 0x3d, 0xe2, 0xe8, 0xe5, 0xea, 0xe3,
- 0xf6, 0x69, 0xaf, 0x9c, 0x4c, 0xde, 0xd8, 0x17, 0xd5, 0xc9, 0x97, 0x3f,
- 0x61, 0x6c, 0x3c, 0x71, 0x98, 0x9c, 0xf9, 0x2a, 0x6b, 0x4a, 0x3f, 0x9f,
- 0xaf, 0x73, 0x9e, 0x97, 0x3e, 0xad, 0xe7, 0x1a, 0x67, 0x5e, 0xbc, 0xfe,
- 0x4e, 0x89, 0x2f, 0x4b, 0x4f, 0x5a, 0x9e, 0x53, 0x1d, 0x3b, 0xed, 0x76,
- 0x78, 0xa0, 0x70, 0x2b, 0x1b, 0x1d, 0xeb, 0xfe, 0xad, 0x35, 0x0b, 0x2e,
- 0xce, 0x38, 0x6e, 0xd5, 0x55, 0x25, 0x7b, 0xe1, 0xab, 0xd6, 0x3d, 0x68,
- 0xbb, 0xfe, 0x1c, 0x09, 0xef, 0x62, 0x9c, 0x7c, 0x85, 0xef, 0xec, 0x3a,
- 0x57, 0x1f, 0xbe, 0xcb, 0x6a, 0x71, 0x6c, 0x74, 0xd7, 0xb9, 0x28, 0x46,
- 0x2d, 0xe9, 0xeb, 0x43, 0xf1, 0x99, 0x87, 0xb1, 0x7d, 0x2a, 0x86, 0x77,
- 0x8d, 0x60, 0xe9, 0xec, 0x89, 0xc4, 0xa4, 0xc1, 0x98, 0x8c, 0xd0, 0x77,
- 0xe3, 0xb1, 0x77, 0xc9, 0x51, 0x33, 0x3e, 0xe0, 0x68, 0x8e, 0xb8, 0x46,
- 0xde, 0x08, 0xc5, 0x3d, 0xbb, 0xe9, 0xbe, 0x5b, 0xfe, 0xbb, 0x1a, 0xb1,
- 0x25, 0xf1, 0xd6, 0xfd, 0xa8, 0x47, 0x96, 0xd8, 0x1f, 0xd4, 0xff, 0x1a,
- 0xc7, 0x4e, 0x78, 0x98, 0x1f, 0x08, 0x4e, 0x77, 0x1a, 0xfc, 0xde, 0x34,
- 0xf8, 0x01, 0xfe, 0xd1, 0x9e, 0x91, 0xf3, 0x51, 0x8a, 0x9c, 0xc5, 0xf8,
- 0xc4, 0xae, 0xd3, 0xf5, 0xe2, 0xb7, 0xa0, 0x0f, 0x5f, 0x45, 0xd3, 0xd0,
- 0x22, 0x7e, 0x6c, 0x17, 0x79, 0xef, 0x7d, 0xc6, 0xd1, 0x2b, 0x46, 0x3c,
- 0xea, 0xa1, 0xf0, 0xc5, 0x88, 0x17, 0xf7, 0x1b, 0xb2, 0xa7, 0xa4, 0x0d,
- 0x3d, 0x0f, 0x6d, 0xf0, 0xbc, 0x22, 0x67, 0x6a, 0x2e, 0xd9, 0x99, 0x25,
- 0x32, 0xaf, 0x82, 0xb5, 0xab, 0x9b, 0x3a, 0x2b, 0xa0, 0xb5, 0xfa, 0x15,
- 0xdd, 0xf8, 0x40, 0xf9, 0x7b, 0xbb, 0x18, 0xf9, 0xc4, 0xbe, 0xac, 0x97,
- 0xc7, 0xd5, 0x62, 0x01, 0x6f, 0x59, 0xb6, 0x7a, 0x1c, 0xb3, 0x64, 0x2f,
- 0xee, 0xaf, 0xf1, 0xc0, 0x09, 0x1f, 0x3a, 0x52, 0x3f, 0xb1, 0x33, 0x11,
- 0x19, 0xf3, 0x13, 0xda, 0x42, 0xc6, 0x77, 0xfb, 0xd5, 0x2f, 0x17, 0xa0,
- 0x6c, 0xb3, 0x84, 0x33, 0x8b, 0x5f, 0x4c, 0xc1, 0xb6, 0xa4, 0x87, 0x68,
- 0xe3, 0x8e, 0xd4, 0x08, 0xde, 0x4f, 0xa5, 0xff, 0x63, 0x00, 0xda, 0x85,
- 0x2b, 0x5e, 0xad, 0xd8, 0xec, 0x8d, 0x29, 0xc1, 0x46, 0x7d, 0xa8, 0xd1,
- 0xdd, 0x9f, 0x67, 0xfd, 0x14, 0x0a, 0xec, 0x2a, 0x48, 0x9d, 0x39, 0x85,
- 0x85, 0xc9, 0x0c, 0x7c, 0xe4, 0x77, 0xa3, 0x2d, 0x5a, 0xdf, 0x73, 0x8a,
- 0x16, 0x3d, 0xa0, 0xc4, 0x94, 0x7b, 0xf5, 0x61, 0xbc, 0x60, 0x24, 0xd2,
- 0xed, 0x4a, 0x7d, 0xa0, 0xb3, 0x50, 0x1e, 0xbb, 0x83, 0xb8, 0xa1, 0x15,
- 0xaf, 0x78, 0x2b, 0x51, 0xb7, 0x5e, 0xef, 0xac, 0xf4, 0x6a, 0xc3, 0x5f,
- 0x60, 0x1d, 0xb0, 0xa3, 0x50, 0x0c, 0x7e, 0x90, 0xf0, 0x60, 0x8d, 0xb3,
- 0x87, 0x90, 0x2d, 0xf5, 0x47, 0xa7, 0xd0, 0x35, 0x69, 0x6f, 0xbe, 0x98,
- 0xd2, 0xa2, 0xcf, 0x29, 0x99, 0x3d, 0x21, 0xf2, 0x9a, 0x07, 0xa1, 0xc7,
- 0xe6, 0x19, 0xc7, 0x1d, 0x05, 0x0f, 0x56, 0x3a, 0x7e, 0x9c, 0xe5, 0x98,
- 0x87, 0x51, 0x79, 0xc2, 0xde, 0xbc, 0xc7, 0xd0, 0x86, 0xaf, 0x78, 0x33,
- 0xff, 0xb5, 0x8e, 0x76, 0xdb, 0xa6, 0x68, 0xac, 0x4f, 0x47, 0x70, 0x91,
- 0x3a, 0x7c, 0x3d, 0xa5, 0x25, 0xff, 0x4c, 0xd1, 0x7a, 0xbe, 0x4c, 0x5f,
- 0xf6, 0x9a, 0x61, 0xca, 0xa9, 0x25, 0x67, 0x21, 0xbd, 0xf3, 0x18, 0xae,
- 0x18, 0x99, 0xe0, 0xf6, 0xc6, 0x24, 0xf9, 0x59, 0x94, 0xf9, 0x30, 0x86,
- 0xa3, 0xe4, 0x77, 0x87, 0x0b, 0x15, 0x28, 0xaa, 0x3a, 0xf9, 0x59, 0x0f,
- 0x3c, 0x93, 0x21, 0x65, 0x2e, 0x1b, 0x37, 0x3a, 0xf0, 0x47, 0x28, 0x3a,
- 0x38, 0x77, 0x18, 0xa1, 0x13, 0x3f, 0xb0, 0x6b, 0x74, 0xbd, 0x75, 0x52,
- 0xe1, 0xbc, 0xcf, 0x44, 0x69, 0x63, 0xbe, 0x27, 0xe7, 0x4e, 0xac, 0x6e,
- 0xdc, 0x3b, 0x19, 0xe1, 0xfb, 0x35, 0x58, 0x7b, 0x22, 0x86, 0x0f, 0x53,
- 0x37, 0xa3, 0xe8, 0x70, 0x04, 0x85, 0x7e, 0x40, 0x3f, 0x62, 0xad, 0x95,
- 0x21, 0x8f, 0x94, 0x7d, 0xa3, 0xc3, 0x96, 0xd4, 0xe8, 0x3e, 0x7e, 0x0f,
- 0xf1, 0x57, 0xec, 0xf9, 0x39, 0x72, 0x1d, 0xf9, 0x5c, 0xd3, 0x16, 0x9b,
- 0xfb, 0x5e, 0x95, 0xb3, 0x7f, 0x89, 0x18, 0x9f, 0x53, 0x9d, 0xde, 0xe0,
- 0x28, 0xc7, 0x3c, 0x3b, 0x25, 0xb5, 0x5b, 0xfb, 0xa6, 0x40, 0x69, 0x7f,
- 0xfd, 0x87, 0x86, 0x07, 0x9b, 0x59, 0xdf, 0x47, 0x75, 0x39, 0x9b, 0x39,
- 0xaa, 0xd5, 0x61, 0x13, 0x4e, 0xab, 0x2c, 0xc4, 0xf5, 0xff, 0x80, 0x09,
- 0x35, 0x49, 0xac, 0xd1, 0xf1, 0x5e, 0xf6, 0x37, 0x58, 0xf3, 0xd4, 0xcb,
- 0xd9, 0x1b, 0xac, 0x3c, 0xe1, 0xe7, 0x9c, 0x9b, 0xc9, 0x75, 0xb6, 0xe3,
- 0xbb, 0xaa, 0x5b, 0x6f, 0x10, 0x8f, 0x30, 0x3e, 0x1b, 0x22, 0x1f, 0x0d,
- 0xf0, 0xf7, 0x46, 0xd9, 0x7e, 0x9d, 0x4c, 0xa2, 0xcb, 0xbf, 0x25, 0x53,
- 0x80, 0x7c, 0x80, 0x78, 0x99, 0x7d, 0x0d, 0x1f, 0x72, 0xec, 0xcc, 0xac,
- 0x3b, 0xe6, 0xf1, 0x82, 0x8c, 0x2b, 0xf3, 0xc5, 0x99, 0x37, 0x65, 0xfc,
- 0x90, 0x9c, 0xbf, 0xfd, 0x77, 0xce, 0x41, 0x86, 0x77, 0x82, 0x35, 0xb2,
- 0xd1, 0x88, 0x0e, 0x95, 0xeb, 0x65, 0xc9, 0x1c, 0x1a, 0xeb, 0x51, 0x79,
- 0x37, 0x8a, 0x35, 0x93, 0xf6, 0x48, 0xd4, 0x94, 0xeb, 0xb6, 0x5d, 0xbb,
- 0x51, 0x8f, 0xbe, 0xad, 0xf8, 0x98, 0xf3, 0x7c, 0xb4, 0xc1, 0x38, 0xce,
- 0x66, 0x9b, 0x2e, 0xbc, 0x4f, 0x0e, 0x15, 0x63, 0xbd, 0x77, 0xc9, 0x3b,
- 0x8e, 0xb9, 0xec, 0xb1, 0x6a, 0xe9, 0x13, 0x30, 0x0f, 0x2a, 0xb3, 0xd9,
- 0xfb, 0xab, 0x05, 0xab, 0xc6, 0xe8, 0x0b, 0xcd, 0x93, 0x22, 0xab, 0x3d,
- 0x52, 0xc3, 0x71, 0x8e, 0x72, 0x9c, 0xd9, 0x0d, 0x7a, 0xdf, 0x98, 0x22,
- 0x36, 0x0b, 0xe1, 0x58, 0xe1, 0xa2, 0xf4, 0xd0, 0x68, 0xb7, 0x69, 0x3e,
- 0x2f, 0x76, 0x8b, 0xe0, 0xbb, 0xa5, 0x71, 0x9e, 0x2a, 0x5c, 0xc0, 0x6c,
- 0xf6, 0x2d, 0xe7, 0xef, 0x31, 0xd6, 0x0d, 0xe3, 0xac, 0x21, 0xf3, 0xc4,
- 0x93, 0xc9, 0x6c, 0x53, 0xdf, 0x24, 0xe5, 0x70, 0xcf, 0xca, 0x0d, 0xe0,
- 0xd9, 0xd2, 0x33, 0xa3, 0x7c, 0x77, 0xf4, 0xda, 0xdf, 0x62, 0x23, 0x77,
- 0x0f, 0xdf, 0xdd, 0x53, 0xa8, 0xe4, 0xda, 0xb9, 0xb5, 0xf8, 0x11, 0xcb,
- 0x2f, 0x7d, 0x70, 0xbc, 0x36, 0xb5, 0x19, 0x63, 0xc6, 0x5f, 0x62, 0x2f,
- 0xf5, 0x1e, 0xa7, 0x3d, 0x4f, 0x58, 0xce, 0x5e, 0xbd, 0x9c, 0xcb, 0x22,
- 0x96, 0x87, 0xda, 0xce, 0x90, 0x93, 0x1d, 0x63, 0xcc, 0xdc, 0x97, 0x6a,
- 0xea, 0x79, 0x9d, 0x7e, 0x97, 0xfe, 0xa2, 0xec, 0x87, 0x03, 0x93, 0xb9,
- 0x47, 0x31, 0xb3, 0xa4, 0x69, 0xf1, 0x45, 0x62, 0xc2, 0x69, 0xe2, 0x94,
- 0x8f, 0x98, 0x50, 0x9b, 0xf3, 0x94, 0xf6, 0x77, 0x0d, 0x7e, 0x6f, 0xba,
- 0x30, 0x87, 0xbf, 0xa1, 0x5d, 0x44, 0xbe, 0x78, 0x72, 0x0e, 0xf2, 0xac,
- 0xdb, 0x83, 0xd5, 0xe7, 0x06, 0x71, 0xe9, 0x66, 0xb7, 0x8f, 0xe6, 0x65,
- 0xee, 0xde, 0x97, 0x6d, 0x52, 0xc7, 0x64, 0xec, 0x5e, 0x2d, 0x9a, 0xe1,
- 0x5a, 0x4d, 0x38, 0x1c, 0x5c, 0x65, 0x8e, 0x97, 0x73, 0x58, 0x35, 0xf0,
- 0xd1, 0xf7, 0xc7, 0x0c, 0x39, 0xbf, 0x10, 0x0d, 0xef, 0xe0, 0x1a, 0x8e,
- 0x59, 0x4d, 0xad, 0x71, 0x65, 0x0f, 0xca, 0xfc, 0xdb, 0xe5, 0xd4, 0x5a,
- 0xdf, 0x51, 0x34, 0xf5, 0x3c, 0x88, 0x2f, 0x21, 0xbd, 0xa4, 0xa9, 0x7f,
- 0x0a, 0x71, 0xe3, 0x7e, 0xc8, 0x39, 0x4e, 0x77, 0xac, 0x86, 0x3c, 0x33,
- 0xc9, 0xd2, 0x4f, 0xec, 0x15, 0xfa, 0x53, 0x98, 0x22, 0x77, 0x6c, 0x5c,
- 0xa7, 0x5f, 0xf8, 0x5a, 0xe9, 0x9e, 0xbb, 0x4f, 0x24, 0xfe, 0x12, 0xa0,
- 0x0d, 0x2a, 0xe1, 0x5b, 0x5a, 0xcf, 0x39, 0x68, 0x0b, 0xe7, 0x8c, 0xef,
- 0x45, 0x1c, 0xa4, 0xbf, 0x4d, 0x15, 0x14, 0x18, 0x0d, 0x17, 0x31, 0x24,
- 0xb9, 0x8b, 0xef, 0xb4, 0x67, 0x43, 0xe4, 0xb2, 0x51, 0x54, 0xea, 0xf1,
- 0xd8, 0x28, 0xf5, 0x6b, 0x27, 0x96, 0x8f, 0x13, 0x43, 0x32, 0x6a, 0xc8,
- 0x39, 0x77, 0x5a, 0xa9, 0x47, 0x9d, 0xff, 0x15, 0x90, 0x5a, 0xa8, 0x71,
- 0x46, 0xf6, 0xa8, 0x0f, 0xe3, 0xe2, 0x54, 0x11, 0xc7, 0x52, 0x69, 0xec,
- 0x5f, 0xa2, 0x62, 0xd2, 0x5a, 0xe6, 0xf4, 0x0e, 0xa4, 0xe6, 0xea, 0xca,
- 0x1d, 0x72, 0xfa, 0x91, 0x5b, 0x53, 0x9e, 0x06, 0x39, 0xa7, 0x31, 0xcb,
- 0xda, 0x6b, 0xca, 0x18, 0xc1, 0x41, 0xe3, 0xcb, 0x30, 0x96, 0x0a, 0x76,
- 0x8e, 0xe1, 0xd5, 0x19, 0xc9, 0x71, 0xc9, 0xb6, 0x5b, 0x26, 0xc5, 0x3e,
- 0x1e, 0x72, 0xdf, 0x00, 0x9a, 0x1d, 0x2e, 0xf7, 0x50, 0xdb, 0xea, 0x19,
- 0x97, 0xd3, 0x35, 0xe7, 0xe5, 0xac, 0x74, 0x0d, 0xc2, 0xb4, 0xd7, 0xf9,
- 0x94, 0x9f, 0x98, 0x23, 0xf6, 0x94, 0x33, 0x7a, 0xae, 0x9e, 0xc9, 0xbc,
- 0x82, 0xb1, 0x96, 0x1b, 0xf7, 0x58, 0xe4, 0xff, 0x06, 0xae, 0x9d, 0x1b,
- 0x2c, 0xf5, 0xc7, 0xff, 0xcc, 0xbe, 0x74, 0x93, 0xe8, 0xbd, 0x22, 0x44,
- 0x4c, 0x8f, 0xcd, 0x5c, 0xb3, 0xaf, 0xd8, 0xf4, 0x9c, 0xe4, 0x0c, 0xc7,
- 0xe6, 0x6e, 0xcf, 0x4d, 0x1b, 0xba, 0xac, 0x34, 0x31, 0x9f, 0xd0, 0xaf,
- 0x96, 0xd0, 0xdf, 0x9a, 0xd1, 0xbf, 0xc2, 0xf4, 0xf5, 0x5e, 0xb5, 0x36,
- 0xa3, 0x75, 0xfd, 0x7b, 0x36, 0x6e, 0x6e, 0x87, 0x57, 0x97, 0xeb, 0x33,
- 0x76, 0x5a, 0x95, 0xbf, 0xff, 0x24, 0x24, 0xb9, 0xfe, 0x65, 0xab, 0x68,
- 0xaf, 0x5e, 0xe6, 0x72, 0xc4, 0x1f, 0x64, 0x65, 0xdf, 0x2b, 0x63, 0xb3,
- 0xde, 0xbe, 0xf0, 0xae, 0xf7, 0x10, 0xbe, 0x9f, 0x3f, 0x8c, 0x77, 0xa6,
- 0x7c, 0x08, 0xeb, 0xa2, 0xcb, 0x66, 0xd4, 0xae, 0x4f, 0xa4, 0xdf, 0x23,
- 0x2e, 0x5e, 0x98, 0x29, 0xfb, 0xc5, 0x43, 0x6d, 0x6b, 0x66, 0x14, 0x8e,
- 0x55, 0x83, 0x0a, 0xea, 0xf9, 0x1d, 0xc3, 0x8b, 0x58, 0x89, 0xe3, 0x7a,
- 0x29, 0xa7, 0x9c, 0x7b, 0x10, 0xee, 0x1b, 0xcf, 0x1f, 0x0a, 0xb9, 0x3d,
- 0xb0, 0x10, 0x71, 0x74, 0x1c, 0x13, 0xd9, 0xa6, 0xe4, 0xfb, 0x72, 0x0e,
- 0x87, 0x35, 0xd9, 0x25, 0x8c, 0xe3, 0x44, 0xb6, 0x8c, 0xa1, 0x51, 0x39,
- 0x97, 0x9a, 0x8c, 0x79, 0x5c, 0x8c, 0x8c, 0x79, 0xb4, 0x4c, 0xcc, 0xe3,
- 0x0f, 0x09, 0x77, 0x18, 0x2d, 0xc4, 0xa3, 0x95, 0xf0, 0xe2, 0x3e, 0xc3,
- 0xf5, 0x8f, 0x86, 0x39, 0x3f, 0x62, 0x4b, 0x25, 0x2f, 0x4b, 0x4e, 0xf6,
- 0x31, 0x27, 0x2f, 0x23, 0xbf, 0xf6, 0xe1, 0x4d, 0x5d, 0xec, 0xb1, 0xa6,
- 0x6c, 0x0f, 0xe3, 0x1c, 0x1e, 0xb6, 0x8b, 0x3d, 0xe2, 0x4b, 0x7e, 0x1c,
- 0x6e, 0x9e, 0xb5, 0x67, 0x22, 0xa2, 0xbb, 0x17, 0xa7, 0x89, 0xaf, 0xb8,
- 0x39, 0x1e, 0x3d, 0xcd, 0x9c, 0x3d, 0xa6, 0x97, 0x7d, 0xfc, 0xb7, 0x4b,
- 0x72, 0xea, 0x7d, 0xf3, 0xb8, 0x9f, 0x7f, 0x37, 0x44, 0xf7, 0x2b, 0xee,
- 0x7c, 0xab, 0xe7, 0xfe, 0x26, 0x54, 0xee, 0x9f, 0xca, 0xb3, 0xb1, 0xfc,
- 0xe3, 0xfc, 0x2e, 0x63, 0x85, 0xe8, 0x9f, 0x95, 0xe8, 0x8f, 0xc8, 0xff,
- 0x89, 0x88, 0x5d, 0x64, 0x3f, 0x11, 0xb4, 0x87, 0x8d, 0xd7, 0x68, 0x8f,
- 0xc3, 0xd7, 0xce, 0x4c, 0xb9, 0xf8, 0x55, 0xc5, 0xeb, 0x3b, 0x52, 0xaf,
- 0x6c, 0x0a, 0xe2, 0x17, 0xf6, 0xa5, 0x48, 0x94, 0x98, 0x50, 0xe6, 0xa1,
- 0x62, 0x33, 0xc3, 0xb1, 0x99, 0x5b, 0x2b, 0x5e, 0xd3, 0xa3, 0x38, 0x40,
- 0xbe, 0xbd, 0x90, 0x2d, 0x9f, 0x15, 0x89, 0x13, 0x6b, 0x3e, 0x8f, 0xfe,
- 0x3a, 0x19, 0xaf, 0x9e, 0xfe, 0x95, 0xa4, 0x0d, 0xd4, 0xf0, 0xce, 0x69,
- 0xa9, 0xb5, 0xc9, 0x8f, 0x27, 0xe3, 0xc6, 0x43, 0xe4, 0x91, 0x13, 0x93,
- 0xb6, 0xfd, 0x96, 0x81, 0x3b, 0xc3, 0xcc, 0xef, 0x2f, 0x90, 0x4f, 0x90,
- 0x6f, 0xc4, 0x2a, 0x95, 0xa6, 0xe8, 0x2a, 0xe6, 0xfa, 0x31, 0xd6, 0x0a,
- 0x4f, 0x13, 0xe3, 0x4e, 0x2f, 0x54, 0xc1, 0x3a, 0x21, 0xfb, 0x82, 0x55,
- 0x98, 0x7c, 0x26, 0x49, 0xd9, 0x97, 0x72, 0x9c, 0x00, 0xaa, 0xcf, 0xb4,
- 0xa2, 0xea, 0x94, 0x82, 0x1d, 0x89, 0x56, 0x04, 0xcf, 0xd4, 0x30, 0xff,
- 0x06, 0x70, 0xa5, 0x85, 0x6b, 0xfc, 0x4c, 0x59, 0x0f, 0x67, 0x8f, 0x14,
- 0x4f, 0xe6, 0x62, 0xe4, 0xf1, 0x11, 0x2c, 0x58, 0xb2, 0x1f, 0x1c, 0x70,
- 0xb0, 0xf4, 0xc2, 0x86, 0x7a, 0x67, 0xcf, 0xea, 0xc5, 0x82, 0x1e, 0x3d,
- 0xab, 0xd4, 0xe0, 0xc7, 0x27, 0x8a, 0x37, 0x57, 0xc2, 0x7e, 0x79, 0x85,
- 0x99, 0xe8, 0xdb, 0x4b, 0xff, 0x5f, 0xb3, 0x3a, 0xc2, 0xfa, 0xc6, 0xb6,
- 0xaf, 0x6e, 0x94, 0x3a, 0xd8, 0x70, 0xea, 0x60, 0x77, 0x6f, 0x5f, 0x1f,
- 0x7c, 0x4c, 0xc9, 0x6c, 0x0f, 0xc3, 0xfe, 0xa8, 0xd2, 0xb4, 0x3f, 0xf6,
- 0x9b, 0x09, 0xbe, 0x2f, 0x7b, 0x7c, 0xb6, 0xfd, 0xc3, 0x16, 0xdb, 0xce,
- 0xb7, 0xc4, 0xfb, 0x54, 0xaf, 0x8a, 0x33, 0x8d, 0xb2, 0x2f, 0xe8, 0xc1,
- 0x8f, 0x13, 0x7a, 0x74, 0x2f, 0x64, 0x0f, 0x9e, 0x78, 0xbf, 0x4c, 0xce,
- 0x18, 0xd6, 0x87, 0x3b, 0xad, 0xa5, 0x78, 0x61, 0x7e, 0x23, 0xfa, 0xfd,
- 0x70, 0xce, 0xc5, 0xd8, 0x06, 0xde, 0x5e, 0x01, 0xc9, 0xe1, 0x89, 0xd6,
- 0xc7, 0x10, 0xc1, 0x7c, 0xe1, 0x30, 0x1e, 0x39, 0x21, 0xf5, 0xd7, 0xea,
- 0xb6, 0xc0, 0x09, 0xfb, 0x07, 0x51, 0xb3, 0x48, 0x8c, 0xb4, 0xed, 0xaa,
- 0x8d, 0x4d, 0x51, 0xa6, 0x26, 0xf2, 0x8d, 0x18, 0x79, 0xb3, 0x3e, 0xf8,
- 0x63, 0x2c, 0xc1, 0xd9, 0xd9, 0xf4, 0xcd, 0xe4, 0xf2, 0x9d, 0xcf, 0x2a,
- 0xc2, 0xdb, 0x23, 0x78, 0xbe, 0x20, 0x9c, 0x65, 0x6d, 0x5b, 0xd7, 0x89,
- 0xe5, 0x78, 0x79, 0x3e, 0x82, 0xb3, 0x96, 0x4e, 0xce, 0x04, 0xa5, 0xda,
- 0xb4, 0x6b, 0x6b, 0x29, 0x6b, 0xb5, 0xd7, 0x8b, 0xed, 0x29, 0xa9, 0x19,
- 0xf5, 0xc1, 0x90, 0x82, 0xe5, 0x95, 0xd0, 0x17, 0x1f, 0x06, 0x86, 0x82,
- 0x66, 0xe2, 0xc2, 0xb3, 0x4a, 0xa2, 0xef, 0x03, 0x6f, 0x04, 0xdf, 0x22,
- 0x16, 0x7d, 0xbd, 0x20, 0x67, 0xa5, 0x88, 0x37, 0xb3, 0x31, 0xae, 0x5b,
- 0x00, 0x9e, 0x86, 0x1a, 0x1c, 0x61, 0xec, 0xbc, 0x66, 0x54, 0x10, 0xaf,
- 0xe4, 0xec, 0x94, 0x60, 0x7d, 0xbd, 0x9c, 0x19, 0xb1, 0x5f, 0xd4, 0xdd,
- 0x7a, 0xdf, 0x98, 0xbb, 0xf1, 0x4c, 0xb1, 0x4a, 0x8c, 0x6f, 0xea, 0x89,
- 0x2a, 0x6f, 0xd8, 0xe9, 0x2f, 0x2a, 0xd4, 0xb3, 0xb7, 0x06, 0x55, 0x8e,
- 0xae, 0x18, 0xcd, 0x95, 0xf3, 0x4b, 0xad, 0xd4, 0x77, 0x3d, 0x99, 0x92,
- 0x3f, 0x56, 0x33, 0xee, 0x8f, 0x32, 0x5f, 0x57, 0x9e, 0x90, 0xbc, 0x42,
- 0xfe, 0xad, 0x6c, 0x26, 0x2f, 0x16, 0x0e, 0x11, 0xc0, 0x83, 0xaa, 0xf8,
- 0x86, 0x4a, 0xfd, 0x36, 0xf9, 0xe4, 0x2c, 0xd4, 0x0b, 0x05, 0xc9, 0xeb,
- 0x82, 0x0b, 0xe5, 0xf9, 0xa2, 0xa8, 0x9b, 0x94, 0x35, 0x52, 0xdb, 0x3e,
- 0x9a, 0x0c, 0xc9, 0xd9, 0xf7, 0x11, 0x0f, 0xeb, 0xef, 0x00, 0xfd, 0xeb,
- 0x9e, 0x16, 0x7d, 0x70, 0xb3, 0x57, 0x63, 0x0d, 0x1e, 0x67, 0x2d, 0xa1,
- 0xb5, 0x4e, 0x28, 0x37, 0x8e, 0xf3, 0x6c, 0x8d, 0xc4, 0x4b, 0x86, 0x7a,
- 0x3e, 0xe9, 0xe8, 0xb4, 0x86, 0x3a, 0x09, 0x5e, 0x27, 0x89, 0xd7, 0x35,
- 0xb8, 0x32, 0x05, 0x9d, 0x11, 0x8c, 0x57, 0x0d, 0x02, 0x95, 0x9a, 0x48,
- 0x77, 0x40, 0x62, 0x41, 0xeb, 0x17, 0x3e, 0x55, 0x4d, 0x7c, 0x9e, 0x9d,
- 0x92, 0x7c, 0xa3, 0x08, 0x57, 0xc9, 0xd4, 0x9a, 0x43, 0xf8, 0x70, 0x03,
- 0xf0, 0xc6, 0xa4, 0xbb, 0xef, 0xde, 0x27, 0x67, 0x6f, 0x2b, 0xdd, 0x33,
- 0x0d, 0x8f, 0x39, 0x67, 0x15, 0x64, 0xfc, 0x43, 0x38, 0x93, 0x15, 0x7e,
- 0x39, 0x44, 0x7e, 0x19, 0x1f, 0x26, 0xf7, 0x6c, 0x2d, 0x40, 0x62, 0xb2,
- 0xc9, 0xf8, 0x88, 0xbe, 0xff, 0x2c, 0x79, 0xeb, 0x11, 0xb8, 0xfb, 0xee,
- 0x8d, 0xa5, 0xb3, 0x08, 0xf1, 0x7c, 0xa7, 0xb2, 0xd3, 0x39, 0xcf, 0x64,
- 0x30, 0xde, 0x3a, 0x94, 0x1d, 0xf3, 0xdb, 0x94, 0xae, 0xf9, 0x6e, 0x65,
- 0x4f, 0x41, 0xea, 0xd8, 0xd5, 0x6d, 0x0f, 0x9e, 0xd8, 0xad, 0xec, 0x9c,
- 0xed, 0x55, 0xc8, 0x6f, 0xd5, 0x80, 0xd9, 0xa7, 0x74, 0xcf, 0xbb, 0xfd,
- 0xf4, 0x4e, 0xd6, 0x70, 0x3b, 0x2d, 0xf1, 0x07, 0xb5, 0xad, 0x6b, 0x52,
- 0xfe, 0x17, 0x2b, 0x22, 0xff, 0xf7, 0xd0, 0xbf, 0x55, 0xb1, 0xed, 0x55,
- 0xa9, 0xd7, 0x65, 0x3d, 0xec, 0xe7, 0x53, 0xcc, 0x93, 0x56, 0x0d, 0x06,
- 0x58, 0x83, 0x8c, 0x1a, 0xb7, 0x94, 0xf6, 0xcf, 0x44, 0x27, 0x39, 0x2f,
- 0x21, 0xfe, 0x8a, 0x4c, 0x25, 0x65, 0xf8, 0x07, 0xca, 0xbf, 0xbf, 0xa4,
- 0x57, 0xb7, 0x9c, 0x27, 0xf0, 0x23, 0x23, 0x3a, 0xe4, 0xa9, 0xef, 0xb1,
- 0xc9, 0xeb, 0x7a, 0xf9, 0x78, 0x6d, 0x9c, 0x5c, 0x75, 0xbf, 0xa2, 0x0d,
- 0x3f, 0xe7, 0xea, 0x75, 0xe1, 0x8a, 0xa2, 0x15, 0x47, 0x21, 0xb8, 0xe0,
- 0xea, 0xb5, 0xb6, 0xa4, 0xd7, 0x9a, 0x7c, 0xa7, 0x73, 0x4e, 0xab, 0x86,
- 0x7a, 0x2d, 0x4c, 0x76, 0x28, 0x9d, 0xf3, 0xd2, 0xcb, 0x14, 0xdd, 0x44,
- 0x8f, 0x13, 0x76, 0x95, 0xde, 0xad, 0xdc, 0xee, 0x9c, 0x2b, 0x93, 0xb3,
- 0x5d, 0xb2, 0xdf, 0x5f, 0xd6, 0x4b, 0x72, 0xfa, 0xd2, 0xf0, 0xb6, 0x69,
- 0x35, 0xbc, 0x75, 0xda, 0xb6, 0xbf, 0x6b, 0xfc, 0xb3, 0xa3, 0xcb, 0x59,
- 0x43, 0x74, 0x91, 0x73, 0x23, 0x65, 0x7d, 0xbe, 0x50, 0xd2, 0x47, 0xd6,
- 0xea, 0xfa, 0x3a, 0x95, 0xff, 0x87, 0xef, 0xdd, 0xac, 0x7b, 0xa6, 0xa4,
- 0xac, 0x4f, 0xd8, 0x2c, 0x9f, 0x2f, 0x1b, 0xc2, 0x1b, 0xbc, 0xff, 0x93,
- 0x6c, 0x59, 0x2f, 0x2f, 0xe6, 0x66, 0xc5, 0xfe, 0x43, 0xf2, 0x3f, 0x7c,
- 0xc4, 0x91, 0xb8, 0x31, 0x46, 0x3f, 0x72, 0xf5, 0xd3, 0x86, 0x57, 0x7a,
- 0x9b, 0x8a, 0x57, 0xa0, 0xf5, 0x2f, 0x2a, 0x89, 0x34, 0x6b, 0x70, 0x9c,
- 0x2d, 0xfc, 0xea, 0xfa, 0x35, 0xe7, 0xab, 0x94, 0x6d, 0x39, 0x19, 0xfb,
- 0x21, 0x8e, 0x2d, 0x67, 0x4a, 0x14, 0x3c, 0x37, 0x0b, 0xcc, 0x5a, 0x9c,
- 0xd6, 0x1c, 0xc1, 0xd3, 0x86, 0x6d, 0x3f, 0xdb, 0xa2, 0xcb, 0x59, 0xa0,
- 0xf3, 0x6e, 0xaf, 0x08, 0x46, 0x8d, 0x2e, 0x7b, 0x79, 0x72, 0x9e, 0xa4,
- 0x97, 0x36, 0x10, 0xdd, 0xc5, 0x07, 0xca, 0x6b, 0x2f, 0xe7, 0xdc, 0x32,
- 0xb4, 0x8f, 0xd8, 0xa6, 0x7c, 0xde, 0x4d, 0xfa, 0x30, 0x37, 0xda, 0x64,
- 0x6d, 0xd8, 0x59, 0x5f, 0x43, 0xfc, 0x95, 0xe8, 0x43, 0x5f, 0x9d, 0x23,
- 0x97, 0x18, 0x33, 0xfc, 0x0e, 0x6f, 0x3b, 0x42, 0xae, 0x32, 0xc1, 0xd8,
- 0x79, 0xd2, 0xba, 0x80, 0x0b, 0xf9, 0xd7, 0xf0, 0xc6, 0xb5, 0xff, 0x67,
- 0x13, 0x7f, 0xb9, 0xb8, 0xb1, 0xcb, 0x39, 0xd3, 0x74, 0xba, 0xf5, 0x96,
- 0x84, 0xe0, 0x50, 0x77, 0xb3, 0x9c, 0x71, 0xaa, 0x34, 0xf3, 0x9b, 0x64,
- 0xbf, 0xab, 0xc2, 0x34, 0x6f, 0x3d, 0xaf, 0x8b, 0x6d, 0xfe, 0x62, 0xfd,
- 0x19, 0x5d, 0xf4, 0xfa, 0x9f, 0x6b, 0xc7, 0x9d, 0xff, 0xaf, 0xfc, 0xbb,
- 0x5b, 0xf7, 0xe9, 0x12, 0x3b, 0x67, 0x5b, 0xda, 0x1d, 0x4c, 0x68, 0x35,
- 0x57, 0x39, 0x36, 0x68, 0x31, 0x6f, 0x71, 0x3e, 0x0d, 0x33, 0xe9, 0x7c,
- 0x9a, 0xa6, 0x6b, 0x9b, 0x6e, 0xb3, 0xc1, 0xf9, 0xec, 0x30, 0xdd, 0xf3,
- 0xcf, 0x69, 0x53, 0x77, 0x3e, 0x7b, 0xcc, 0xb8, 0xf3, 0xd9, 0x69, 0xae,
- 0xbc, 0x2e, 0x17, 0x7f, 0xfe, 0x1f, 0x9b, 0x97, 0x53, 0xd9, 0x78, 0x3a,
- 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
-
-static struct fw_info bnx2_txp_fw_06 = {
- /* Firmware version: 4.6.16 */
- .ver_major = 0x4,
- .ver_minor = 0x6,
- .ver_fix = 0x10,
-
- .start_addr = 0x08000098,
-
- .text_addr = 0x08000000,
- .text_len = 0x3a74,
- .text_index = 0x0,
- .gz_text = bnx2_TXP_b06FwText,
- .gz_text_len = sizeof(bnx2_TXP_b06FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_TXP_b06FwData,
-
- .sbss_addr = 0x08003aa0,
- .sbss_len = 0x68,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08003b08,
- .bss_len = 0x14c,
- .bss_index = 0x0,
-
- .rodata_addr = 0x00000000,
- .rodata_len = 0x0,
- .rodata_index = 0x0,
- .rodata = bnx2_TXP_b06FwRodata,
-};
-
/* Initialized Values for the TX Processor. */
static const struct cpu_reg cpu_reg_txp = {
.mode = BNX2_TXP_CPU_MODE,
@@ -4461,4 +86,3 @@ static const struct cpu_reg cpu_reg_txp = {
.spad_base = BNX2_TXP_SCRATCH,
.mips_view_base = 0x8000000,
};
-
diff --git a/drivers/net/bnx2_fw2.h b/drivers/net/bnx2_fw2.h
deleted file mode 100644
index c54e4886b8b..00000000000
--- a/drivers/net/bnx2_fw2.h
+++ /dev/null
@@ -1,4547 +0,0 @@
-/* bnx2_fw2.h: Broadcom NX2 network driver.
- *
- * Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, except as noted below.
- *
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
-
-static u8 bnx2_COM_b09FwText[] = {
- 0xcd, 0x7c, 0x7b, 0x6c, 0x5c, 0xd7, 0x99, 0xdf, 0x77, 0xef, 0xcc, 0x90,
- 0x43, 0x6a, 0x44, 0x5d, 0x32, 0x13, 0x66, 0x1c, 0x33, 0xcd, 0x3c, 0x2e,
- 0x29, 0xda, 0x64, 0x92, 0x31, 0x77, 0xa4, 0xd0, 0xc9, 0xad, 0x3d, 0x99,
- 0x19, 0xc9, 0x4c, 0xa8, 0x0d, 0xe8, 0x44, 0x2e, 0x52, 0x54, 0x28, 0xd8,
- 0x21, 0xe5, 0x28, 0x8b, 0xec, 0xae, 0xf2, 0x28, 0x9a, 0x2e, 0xd2, 0xd5,
- 0x64, 0x48, 0x29, 0xca, 0x62, 0xc4, 0x19, 0xd3, 0x34, 0x93, 0xa2, 0x01,
- 0x32, 0x19, 0x92, 0x72, 0x76, 0x31, 0x12, 0x15, 0xdb, 0xcd, 0x1a, 0x41,
- 0xe2, 0xb0, 0xd4, 0x23, 0xde, 0x20, 0x2d, 0xb4, 0x1b, 0x17, 0x4d, 0xd3,
- 0x45, 0x21, 0xc8, 0x4e, 0x6c, 0x6c, 0xb3, 0x6d, 0x50, 0x2c, 0x10, 0x77,
- 0x91, 0x64, 0xfa, 0xfb, 0x9d, 0x73, 0xee, 0x70, 0x44, 0x31, 0x4e, 0xba,
- 0x7f, 0x95, 0xc0, 0xe0, 0xdc, 0x7b, 0x9e, 0xdf, 0xf9, 0xce, 0xf7, 0x3e,
- 0xdf, 0xe5, 0x43, 0x22, 0xbd, 0x62, 0xfe, 0xf6, 0xe3, 0x97, 0xf9, 0xfd,
- 0x3f, 0x9c, 0x7b, 0xe0, 0x9d, 0x87, 0xdf, 0x89, 0xc7, 0x43, 0xf6, 0x81,
- 0xae, 0x20, 0xeb, 0x03, 0xf8, 0x45, 0xf1, 0x9b, 0x30, 0xcf, 0x7b, 0xfd,
- 0x39, 0xf8, 0x1d, 0xb6, 0x44, 0x66, 0xff, 0x46, 0xc4, 0xda, 0xd5, 0x16,
- 0xfe, 0x35, 0x63, 0xde, 0xe8, 0xcf, 0xfe, 0x2d, 0xfb, 0x39, 0xff, 0x80,
- 0xb9, 0xfd, 0xbf, 0x80, 0x19, 0xbe, 0xdf, 0xfc, 0x24, 0x6c, 0x7b, 0xb7,
- 0x3e, 0x90, 0x73, 0x25, 0x1c, 0xf0, 0x7e, 0x38, 0x3d, 0xe7, 0x8a, 0x64,
- 0x9b, 0x63, 0xf1, 0xbc, 0xfc, 0xb2, 0x55, 0x8a, 0x06, 0x85, 0xf5, 0x6f,
- 0xf3, 0x7e, 0xf1, 0x95, 0x6f, 0xbf, 0x3b, 0xf1, 0xb3, 0x7a, 0x40, 0xc2,
- 0x8e, 0xf7, 0xba, 0x38, 0x23, 0x12, 0x1e, 0xc2, 0x98, 0x2f, 0x1f, 0x9c,
- 0xb5, 0xa5, 0xcf, 0x9f, 0xeb, 0xb5, 0xd6, 0xb7, 0x0f, 0x4a, 0xc9, 0xf6,
- 0x1c, 0xb9, 0xb2, 0x19, 0x95, 0xef, 0x6c, 0x8a, 0x35, 0x93, 0xe9, 0x11,
- 0x7b, 0xf9, 0xad, 0x92, 0x75, 0x2c, 0x09, 0xb8, 0x5c, 0x27, 0x2e, 0xb9,
- 0xca, 0x20, 0xde, 0x13, 0x31, 0x91, 0x7f, 0xbe, 0x5f, 0x8f, 0x0d, 0x4b,
- 0x60, 0x55, 0xc2, 0x5d, 0xde, 0x0b, 0xd3, 0x37, 0x56, 0x62, 0x12, 0x5c,
- 0x1a, 0x97, 0x72, 0x35, 0x22, 0xa1, 0x55, 0x19, 0x0a, 0xc8, 0x70, 0xec,
- 0x71, 0xf4, 0x28, 0x34, 0x83, 0x72, 0xa4, 0x69, 0x49, 0xd0, 0x0d, 0x03,
- 0xb6, 0x08, 0x7e, 0x0e, 0x7e, 0x51, 0xfc, 0x62, 0xf8, 0x9d, 0xc5, 0x3c,
- 0x43, 0x92, 0x6f, 0x72, 0x4e, 0xac, 0x5b, 0xc5, 0xfa, 0xd5, 0x84, 0x33,
- 0x8b, 0x79, 0x6f, 0x05, 0x62, 0xf2, 0xed, 0x83, 0x84, 0xcb, 0x21, 0x3c,
- 0x80, 0x2d, 0x6c, 0xe5, 0x56, 0xe4, 0x74, 0x3e, 0x2d, 0x71, 0xdb, 0xed,
- 0x95, 0xa2, 0x63, 0xc5, 0xe7, 0x47, 0x07, 0xa4, 0x74, 0x1c, 0xed, 0x55,
- 0xc9, 0xda, 0x98, 0xbf, 0xe8, 0xc8, 0xac, 0x6e, 0x63, 0xdd, 0x17, 0x41,
- 0x27, 0x09, 0x87, 0x08, 0xfb, 0x4e, 0xf5, 0x31, 0x3c, 0x73, 0xbe, 0x78,
- 0x50, 0xc3, 0xbd, 0x8a, 0x77, 0xd6, 0xff, 0x41, 0x44, 0xbf, 0xf3, 0x99,
- 0x7d, 0xfd, 0x75, 0xfd, 0xfd, 0x72, 0xfd, 0x51, 0xec, 0x99, 0x30, 0xf8,
- 0x7b, 0x96, 0x52, 0x08, 0xb0, 0x34, 0x56, 0x22, 0xd6, 0xda, 0xca, 0xb8,
- 0x9c, 0xab, 0x3e, 0x24, 0xb9, 0x74, 0xab, 0x35, 0x97, 0x96, 0xa8, 0x2d,
- 0xc3, 0x4e, 0x1e, 0x1d, 0xb6, 0x9b, 0x62, 0x35, 0x2a, 0x12, 0xee, 0x06,
- 0x5e, 0x5e, 0x5d, 0xe1, 0xdc, 0x41, 0xd4, 0x0d, 0xa2, 0x7f, 0x9f, 0xb5,
- 0xbe, 0x02, 0xf8, 0x3d, 0xe2, 0xa7, 0xd5, 0x5a, 0x4c, 0x0f, 0xc7, 0xe6,
- 0xb1, 0xe6, 0xd5, 0xe6, 0xf0, 0xe4, 0x6d, 0x71, 0x30, 0xe7, 0x00, 0xfa,
- 0x10, 0x57, 0x9c, 0x8b, 0x73, 0x72, 0xbe, 0x08, 0xc6, 0x46, 0xd1, 0x46,
- 0xb8, 0x5a, 0xad, 0x5c, 0xda, 0xe1, 0xbb, 0x6c, 0x01, 0x7f, 0x5b, 0xc4,
- 0x5f, 0xef, 0x90, 0x7c, 0xb7, 0xc9, 0x35, 0xda, 0xb0, 0x97, 0xba, 0xbc,
- 0xe7, 0xed, 0xed, 0x0a, 0xcf, 0x2d, 0x2c, 0xef, 0x0b, 0x26, 0x46, 0x4b,
- 0x8a, 0x4e, 0x66, 0xb1, 0x1f, 0x4b, 0xd1, 0x84, 0x85, 0xe7, 0x64, 0x93,
- 0xfd, 0x89, 0xeb, 0xb8, 0x2c, 0xe0, 0x5c, 0xcb, 0x2b, 0x25, 0xfb, 0x6a,
- 0xf3, 0x17, 0xad, 0x9c, 0xbb, 0x68, 0x6f, 0xaf, 0xb3, 0xff, 0x09, 0xf4,
- 0x0f, 0xca, 0x62, 0xa5, 0x4f, 0x08, 0x93, 0x1e, 0x77, 0x02, 0xe3, 0xc4,
- 0xb1, 0xbd, 0x73, 0xf6, 0xd5, 0xf5, 0xf3, 0xf6, 0x35, 0x75, 0x6e, 0x58,
- 0xab, 0x3d, 0x57, 0x27, 0xde, 0xc6, 0xfe, 0x3f, 0xc4, 0x5b, 0x0c, 0xf3,
- 0x47, 0x51, 0xee, 0xb3, 0x1a, 0xb5, 0x16, 0xd6, 0x8f, 0xe1, 0x79, 0x2f,
- 0x1c, 0xde, 0x52, 0x74, 0x77, 0x05, 0x74, 0xe7, 0x78, 0x31, 0x79, 0x66,
- 0x73, 0x08, 0xfb, 0x88, 0xca, 0xd7, 0xc1, 0x17, 0x03, 0x87, 0xf7, 0x49,
- 0x1e, 0x7c, 0x41, 0x7a, 0x7b, 0x74, 0xf5, 0x9f, 0x49, 0x31, 0x9a, 0x18,
- 0xa5, 0xfc, 0x48, 0x4e, 0x80, 0x9e, 0x0d, 0x6b, 0xe7, 0x96, 0xb2, 0x29,
- 0x5b, 0x1e, 0x16, 0xdb, 0xc3, 0xba, 0x99, 0x31, 0xa7, 0x20, 0x41, 0xb4,
- 0x65, 0x25, 0xe0, 0x45, 0x25, 0xb7, 0xfa, 0x5e, 0x0b, 0x74, 0x19, 0x5f,
- 0xc0, 0xa0, 0xc0, 0x92, 0x58, 0xb6, 0xdb, 0x25, 0xc5, 0xe3, 0xac, 0x0f,
- 0x83, 0xc6, 0xc1, 0xb3, 0x2b, 0x07, 0x00, 0x97, 0x0c, 0xdb, 0xc2, 0xba,
- 0x61, 0xa7, 0x2c, 0x25, 0xb1, 0x2f, 0xff, 0xa1, 0x65, 0x64, 0x9e, 0xc1,
- 0xef, 0xa8, 0x59, 0xab, 0xcd, 0x87, 0x96, 0xbd, 0x1a, 0xb1, 0x02, 0xab,
- 0xe3, 0x72, 0x76, 0x0f, 0xbc, 0x36, 0x80, 0x57, 0x7b, 0xc9, 0xe7, 0xd3,
- 0x20, 0xde, 0x07, 0xd1, 0xb7, 0xcf, 0x0a, 0xae, 0xde, 0x8d, 0xd3, 0xb5,
- 0xe6, 0x70, 0x7a, 0x1b, 0x38, 0xb5, 0x57, 0x07, 0xd0, 0xe7, 0x6e, 0x9c,
- 0x36, 0x80, 0x53, 0x7b, 0x55, 0xe3, 0xb3, 0x01, 0x7c, 0xda, 0x4b, 0x51,
- 0x94, 0xfb, 0x2c, 0x7b, 0x59, 0xe3, 0xb3, 0x61, 0x78, 0xfa, 0x62, 0x93,
- 0xb0, 0x66, 0x3b, 0x68, 0x2e, 0x4b, 0xda, 0x81, 0x9c, 0x2a, 0xc8, 0x5c,
- 0xc5, 0x06, 0xbe, 0x82, 0xe2, 0x4e, 0x58, 0x32, 0xa7, 0xda, 0x0a, 0x92,
- 0x02, 0x0d, 0x95, 0x9c, 0xb1, 0x51, 0x5b, 0x12, 0xf1, 0xac, 0x0d, 0x7c,
- 0x57, 0x81, 0xf7, 0x2a, 0x70, 0xae, 0x64, 0xc2, 0x8b, 0xe0, 0xd7, 0x38,
- 0xce, 0x65, 0x77, 0x7d, 0xc2, 0xa9, 0x2b, 0x9e, 0x8d, 0x9b, 0x33, 0x23,
- 0xed, 0xf3, 0x9c, 0x62, 0x38, 0x2f, 0x75, 0x7e, 0xd6, 0x5f, 0x66, 0xf6,
- 0x49, 0x6a, 0x39, 0xa0, 0xce, 0x2b, 0xbd, 0xfa, 0xae, 0xf6, 0x79, 0xd9,
- 0x13, 0x94, 0x65, 0x3c, 0x23, 0x91, 0xd4, 0x12, 0xcf, 0x29, 0x9b, 0x0a,
- 0x08, 0xcf, 0x2a, 0x24, 0xd9, 0x19, 0x9e, 0x4b, 0x54, 0x92, 0xab, 0x3c,
- 0xb3, 0x0d, 0x73, 0x5e, 0xfa, 0x9c, 0x92, 0x7b, 0x9c, 0x53, 0xd2, 0x9c,
- 0xd3, 0x76, 0xf3, 0x8a, 0x39, 0xa7, 0x7f, 0x2b, 0x86, 0xe6, 0xdf, 0x10,
- 0x07, 0x36, 0x70, 0x10, 0xbc, 0x03, 0x07, 0xdd, 0x6d, 0x1c, 0xc4, 0x6d,
- 0xec, 0xe1, 0xae, 0xfd, 0x77, 0xd6, 0x75, 0xee, 0x5d, 0x4a, 0x41, 0x4f,
- 0xac, 0x85, 0x0a, 0xe1, 0x0e, 0x48, 0x71, 0x86, 0x30, 0x52, 0xae, 0x6b,
- 0x58, 0xf3, 0x2b, 0x94, 0x6d, 0x07, 0x04, 0x34, 0xf1, 0xb6, 0x80, 0x1a,
- 0x53, 0x92, 0x85, 0x26, 0xdb, 0x4a, 0x92, 0xcb, 0x80, 0x5e, 0x6b, 0xac,
- 0x03, 0x83, 0x6e, 0x6a, 0x3e, 0xde, 0xd1, 0x07, 0xd1, 0x36, 0x1e, 0xf3,
- 0x95, 0x38, 0xe4, 0x74, 0x10, 0xe5, 0xd7, 0x50, 0xee, 0xb3, 0x66, 0x6a,
- 0x7f, 0x65, 0x49, 0x5f, 0x4b, 0x9c, 0x09, 0xee, 0x31, 0x36, 0x9d, 0x73,
- 0x4b, 0x31, 0x47, 0xde, 0x26, 0xce, 0x3b, 0x43, 0x22, 0x83, 0x09, 0xa7,
- 0x28, 0xff, 0x05, 0xed, 0x89, 0x58, 0x56, 0xfe, 0xb7, 0x4f, 0xbb, 0xc0,
- 0x43, 0xcf, 0xeb, 0x59, 0xf5, 0xc4, 0x7a, 0x8e, 0xcb, 0xa0, 0x2e, 0x24,
- 0xb3, 0xd0, 0x31, 0x05, 0x97, 0xeb, 0x71, 0xfe, 0xf8, 0x2c, 0xd7, 0xcd,
- 0x37, 0x7d, 0x7d, 0x20, 0xd9, 0x80, 0xc7, 0x36, 0xf2, 0xe5, 0xa4, 0x95,
- 0x6f, 0x12, 0x57, 0x19, 0x71, 0x9b, 0x1a, 0x66, 0x0d, 0x6b, 0x1b, 0x4e,
- 0xf0, 0x6b, 0x16, 0x34, 0x49, 0xd8, 0xe2, 0xe0, 0x9b, 0x73, 0x01, 0xff,
- 0x1c, 0x82, 0xde, 0xa4, 0x2c, 0x42, 0x3f, 0x96, 0x2b, 0x9c, 0xef, 0x33,
- 0x56, 0xe0, 0xb2, 0x3f, 0x3f, 0xcf, 0x86, 0x73, 0xeb, 0xf9, 0xca, 0xcd,
- 0xd7, 0x0c, 0xef, 0x2b, 0x3d, 0x88, 0xf9, 0x4a, 0x1d, 0xf3, 0x95, 0xc8,
- 0xb3, 0x07, 0x94, 0xae, 0x39, 0x4e, 0xfc, 0x9d, 0x47, 0xdb, 0x2d, 0xd0,
- 0x08, 0xf9, 0x81, 0xfc, 0x41, 0x5e, 0x7d, 0xb7, 0x8d, 0xfd, 0x76, 0xe0,
- 0x76, 0x06, 0x72, 0x98, 0xbc, 0x11, 0x96, 0x7c, 0x94, 0xf5, 0x8f, 0x1b,
- 0x98, 0x20, 0x13, 0xd4, 0xfb, 0xf1, 0x1e, 0x5f, 0x3e, 0x82, 0x16, 0x01,
- 0xdb, 0xf3, 0x6a, 0x8f, 0xb6, 0xe7, 0x01, 0x37, 0x9d, 0x30, 0x72, 0xdf,
- 0x9e, 0x91, 0xdb, 0x3e, 0xbc, 0x3c, 0x2b, 0xca, 0x55, 0xb1, 0xd6, 0x33,
- 0x61, 0xc8, 0x70, 0x5b, 0xf2, 0x69, 0xd0, 0x66, 0x3a, 0x60, 0xe4, 0xc3,
- 0x8b, 0xc6, 0x56, 0xd2, 0x38, 0x0e, 0x2a, 0x3d, 0xbe, 0x88, 0x79, 0x4f,
- 0x00, 0x46, 0xce, 0x19, 0xb4, 0xd6, 0x2a, 0x11, 0xe8, 0x6c, 0xc0, 0xe6,
- 0x24, 0xe2, 0x80, 0x09, 0xef, 0x7e, 0x9f, 0x88, 0x2c, 0x6c, 0xfa, 0xeb,
- 0x2e, 0xb6, 0xf5, 0x45, 0x49, 0xe1, 0xdb, 0x99, 0x0d, 0xec, 0xd0, 0xc6,
- 0xcc, 0xc9, 0xca, 0x99, 0x96, 0xed, 0x92, 0x06, 0xdd, 0xd1, 0x86, 0x44,
- 0x26, 0x37, 0x32, 0xef, 0x06, 0xbf, 0xa1, 0x1e, 0x63, 0xca, 0xcd, 0x52,
- 0xc4, 0x76, 0x5d, 0x94, 0x94, 0x3f, 0x27, 0xba, 0x6f, 0xb8, 0x3e, 0xbd,
- 0x0c, 0x49, 0xc8, 0x6d, 0xb5, 0x36, 0x70, 0x26, 0x47, 0x9b, 0xbf, 0x6c,
- 0x7d, 0x35, 0xa8, 0xed, 0x15, 0xdb, 0xfb, 0xa9, 0xa5, 0xd7, 0x8c, 0x4f,
- 0x27, 0x15, 0x1e, 0x62, 0x5d, 0xfa, 0xdd, 0x35, 0xef, 0xd7, 0x22, 0x46,
- 0x87, 0x99, 0xf7, 0xf9, 0xa0, 0xb6, 0x7f, 0xc2, 0x3d, 0xe4, 0xa3, 0xa0,
- 0xe7, 0xf4, 0xe0, 0x9c, 0xc3, 0x21, 0x6f, 0x6a, 0x7c, 0x43, 0xf5, 0x2b,
- 0x99, 0x7e, 0xd1, 0x6e, 0x3d, 0xee, 0xd4, 0xf4, 0x88, 0xa2, 0xa1, 0x4f,
- 0x4f, 0x0f, 0xab, 0xf2, 0xb3, 0xd3, 0x29, 0x55, 0x2e, 0x4e, 0xbb, 0xaa,
- 0x3c, 0xaf, 0xfa, 0x5b, 0xde, 0x90, 0xa9, 0x1f, 0x9d, 0x8e, 0xab, 0x72,
- 0xdc, 0x94, 0x69, 0x53, 0x66, 0x4c, 0x39, 0x69, 0x4a, 0xcf, 0x94, 0x59,
- 0x53, 0x16, 0xcc, 0x7c, 0x53, 0xe6, 0xfd, 0x98, 0x29, 0x67, 0x4c, 0x79,
- 0xdc, 0x94, 0x1f, 0x31, 0xe5, 0x09, 0x03, 0xd7, 0xbc, 0x29, 0x3f, 0x6e,
- 0xea, 0x4f, 0x1b, 0x38, 0x3f, 0x03, 0x78, 0x1e, 0x09, 0xed, 0xd0, 0xca,
- 0x69, 0x4d, 0x5f, 0x15, 0x47, 0xca, 0x9b, 0xdc, 0x7f, 0x1c, 0x32, 0x25,
- 0x88, 0xb3, 0x04, 0xbf, 0x3b, 0xa4, 0x09, 0x17, 0x72, 0x38, 0x88, 0x33,
- 0xe4, 0xf3, 0x69, 0xf9, 0x53, 0xf4, 0x1d, 0xbd, 0xe0, 0xc8, 0x62, 0x95,
- 0xfa, 0xf5, 0x5b, 0xf2, 0x6a, 0x85, 0xe7, 0xf1, 0xbc, 0xdc, 0xa8, 0xa4,
- 0xe2, 0x41, 0x8b, 0x74, 0x94, 0x98, 0x7c, 0x45, 0x12, 0x90, 0xfd, 0x63,
- 0x71, 0x96, 0xd7, 0xa8, 0x54, 0xd0, 0xef, 0xa0, 0x5a, 0xfb, 0x79, 0x01,
- 0x4c, 0x72, 0xa5, 0xd2, 0x0d, 0x99, 0xf5, 0x4a, 0x8b, 0x7a, 0xfd, 0xfc,
- 0xa6, 0xc8, 0xc8, 0x05, 0xe2, 0xf9, 0x5b, 0xb2, 0x51, 0x21, 0xde, 0x9f,
- 0x87, 0xad, 0x90, 0x4a, 0xbf, 0x28, 0x89, 0xd1, 0x8b, 0xc2, 0xf9, 0xc6,
- 0xd2, 0x28, 0xe3, 0x65, 0xfc, 0xce, 0x41, 0xde, 0x76, 0x4f, 0xe8, 0xf9,
- 0x86, 0xcd, 0x7c, 0x2e, 0xec, 0xc2, 0x5b, 0x0e, 0x65, 0xe0, 0x7f, 0xb5,
- 0xf4, 0x9e, 0xb4, 0x3c, 0xcc, 0x3a, 0x41, 0x96, 0xb6, 0xcf, 0x23, 0xf6,
- 0xc4, 0xf5, 0x16, 0xe4, 0x31, 0xf9, 0xdf, 0xd4, 0x6d, 0x1b, 0xfe, 0x92,
- 0x9a, 0xed, 0x81, 0x3e, 0x33, 0xc3, 0x58, 0x83, 0xef, 0x71, 0xd8, 0x9a,
- 0x52, 0x22, 0x1e, 0x8a, 0x95, 0x5f, 0xb5, 0xb2, 0x41, 0x6d, 0x9f, 0x6a,
- 0x19, 0xc1, 0x76, 0x4b, 0xf2, 0xe8, 0xbb, 0x60, 0x64, 0x66, 0xa1, 0x79,
- 0x4b, 0xc9, 0x8d, 0xaf, 0x2b, 0x1a, 0x4e, 0x9c, 0x2f, 0x09, 0x75, 0x86,
- 0x1d, 0xa0, 0x4c, 0xbb, 0x92, 0xae, 0xb7, 0x16, 0xaa, 0x94, 0xc1, 0xc3,
- 0x52, 0xac, 0x0d, 0x97, 0x6c, 0x94, 0xa7, 0xeb, 0x31, 0x39, 0x5d, 0xe1,
- 0x3c, 0xfb, 0xd1, 0xc7, 0x45, 0x1d, 0x18, 0x6b, 0x90, 0xf2, 0x98, 0x6b,
- 0xbe, 0x6e, 0xe9, 0x35, 0xb1, 0x07, 0x77, 0xcb, 0xfa, 0x44, 0xf3, 0x9a,
- 0x55, 0xac, 0xd3, 0x4e, 0x42, 0x7d, 0xb3, 0x53, 0x66, 0xfb, 0xf2, 0xfa,
- 0x79, 0xac, 0x5d, 0xc0, 0x7a, 0x59, 0x25, 0xb3, 0xba, 0x21, 0xf7, 0x7e,
- 0x52, 0xf9, 0x72, 0xab, 0x5c, 0x1d, 0x95, 0x8b, 0x9b, 0x71, 0x39, 0x52,
- 0x19, 0x97, 0x8d, 0x4d, 0x4f, 0x0a, 0x95, 0xb4, 0xac, 0xa3, 0x4f, 0xbe,
- 0x92, 0x91, 0xb5, 0xcd, 0x63, 0xea, 0xac, 0x2f, 0x42, 0x2e, 0x6d, 0xa0,
- 0x4f, 0x63, 0x73, 0x12, 0x3f, 0xdf, 0x1e, 0x88, 0xa1, 0xdf, 0x10, 0xfa,
- 0x88, 0xf5, 0xb3, 0xca, 0x3d, 0xc0, 0x21, 0xe6, 0xae, 0xfa, 0xb6, 0xc1,
- 0xb8, 0x2c, 0x54, 0x79, 0x4e, 0x2f, 0x4c, 0x6f, 0xac, 0xc4, 0xb2, 0xd4,
- 0x77, 0xa7, 0x9b, 0xc3, 0xe0, 0x53, 0xe8, 0xef, 0x2a, 0x65, 0x42, 0x50,
- 0x8a, 0x90, 0xb5, 0x0d, 0xc0, 0x46, 0x58, 0x1b, 0xb0, 0xdf, 0x8b, 0xcd,
- 0x21, 0x94, 0x0e, 0x4a, 0xac, 0x03, 0xd8, 0x8b, 0x4d, 0x17, 0x65, 0x0c,
- 0xa5, 0xd6, 0xed, 0x27, 0x9b, 0x9c, 0x3f, 0xab, 0x74, 0x90, 0xc6, 0xf1,
- 0xd4, 0x1d, 0xb6, 0x7a, 0xc0, 0x5b, 0xb4, 0x8a, 0x2b, 0x62, 0xe7, 0xd2,
- 0x21, 0xfa, 0x0b, 0x90, 0x2b, 0x37, 0x0f, 0x68, 0x58, 0x3e, 0x1b, 0xa0,
- 0xdc, 0x09, 0xba, 0xe7, 0x81, 0xaf, 0x5e, 0xc9, 0x06, 0x69, 0x73, 0xf1,
- 0x59, 0x5a, 0x01, 0xcf, 0xa5, 0xad, 0x12, 0x0c, 0x50, 0x5f, 0x45, 0xd9,
- 0xa7, 0xde, 0xa2, 0x5c, 0xca, 0xd5, 0xb4, 0x6d, 0x5e, 0x6a, 0xdb, 0xe6,
- 0xeb, 0xa8, 0xb7, 0x20, 0x3b, 0xe0, 0x9b, 0xd4, 0x79, 0x1e, 0x03, 0x98,
- 0x33, 0x6b, 0x15, 0x2a, 0xfe, 0x79, 0xd6, 0x5b, 0x4f, 0x54, 0x69, 0xaf,
- 0xd1, 0x6e, 0x53, 0xf2, 0x49, 0x92, 0xcb, 0x71, 0x23, 0x83, 0x23, 0x8a,
- 0x37, 0x88, 0x83, 0xe4, 0x72, 0xda, 0xd4, 0x75, 0x77, 0xd4, 0xf9, 0xb2,
- 0xfa, 0x73, 0x80, 0x61, 0x48, 0x9d, 0xad, 0xed, 0x4d, 0x59, 0x39, 0x65,
- 0x2b, 0xb6, 0x5a, 0x79, 0x37, 0x24, 0xc5, 0xf1, 0x3f, 0xc2, 0x9e, 0xd8,
- 0x56, 0x72, 0x40, 0x5a, 0xe0, 0xbb, 0xca, 0x07, 0xe6, 0xdc, 0x84, 0xb2,
- 0xb3, 0x72, 0x15, 0xf8, 0x38, 0x5a, 0xd5, 0x95, 0xfa, 0xa1, 0x87, 0xdc,
- 0x25, 0xd2, 0x53, 0xbd, 0xb5, 0x0c, 0x9c, 0xce, 0x2c, 0x15, 0xac, 0xe4,
- 0x12, 0xe8, 0x63, 0x10, 0xb6, 0x87, 0x1b, 0x91, 0xdc, 0x65, 0xd2, 0x11,
- 0xfb, 0xb0, 0xbe, 0x4b, 0x66, 0xa2, 0xbb, 0x6d, 0x9b, 0x87, 0x0e, 0x68,
- 0x9d, 0x8f, 0xbe, 0x4b, 0x70, 0xe6, 0x7a, 0xb5, 0x9f, 0x92, 0x5c, 0xa5,
- 0x9c, 0x2d, 0x40, 0xd7, 0x53, 0xe7, 0xf4, 0xc0, 0x9e, 0x61, 0x3d, 0xe7,
- 0x44, 0xdb, 0xc5, 0xac, 0x05, 0xfd, 0x66, 0x97, 0x95, 0x8d, 0x3e, 0x89,
- 0xf2, 0xde, 0x20, 0x6d, 0x5b, 0xea, 0x90, 0xe4, 0xaa, 0x3f, 0x47, 0x27,
- 0x3e, 0xf6, 0x29, 0x9d, 0x34, 0xe0, 0x0d, 0xa8, 0x79, 0x61, 0x97, 0x58,
- 0x73, 0x6a, 0xde, 0x58, 0xc7, 0xbc, 0x68, 0xbb, 0xf8, 0xb7, 0x01, 0x3d,
- 0x0f, 0xf0, 0xac, 0xf6, 0xc4, 0x36, 0x8e, 0x29, 0x58, 0x79, 0xd8, 0x4e,
- 0x33, 0x69, 0x5b, 0x02, 0x83, 0x7e, 0x5f, 0xbd, 0xaf, 0x02, 0xf6, 0x95,
- 0xc3, 0xbe, 0xec, 0xc1, 0xdd, 0xfb, 0x2a, 0x05, 0xf4, 0xbe, 0x06, 0x3a,
- 0x60, 0x8a, 0xee, 0x5a, 0xbf, 0x73, 0x5f, 0x68, 0xbb, 0xb8, 0x7b, 0x8e,
- 0xc7, 0x06, 0xf4, 0x1c, 0xd1, 0x8e, 0x39, 0x06, 0x77, 0xcd, 0x01, 0x7a,
- 0x8e, 0x72, 0xfc, 0xe0, 0x1e, 0xe3, 0x5f, 0xef, 0xd5, 0xe3, 0x39, 0xa6,
- 0x0b, 0x7a, 0x58, 0x9d, 0x75, 0x58, 0xc9, 0xd4, 0xb6, 0xad, 0x76, 0x1a,
- 0x3a, 0xaf, 0x73, 0xcc, 0x9d, 0x76, 0xa6, 0xad, 0xec, 0xcc, 0x3b, 0xe8,
- 0xcc, 0x7a, 0x14, 0x3e, 0x73, 0x6a, 0x19, 0xbe, 0x73, 0xe5, 0xed, 0x58,
- 0xf7, 0xcf, 0xe0, 0x87, 0x42, 0x16, 0x8d, 0xd2, 0x2f, 0x98, 0x14, 0xe5,
- 0x97, 0x8e, 0xc2, 0xff, 0x75, 0xf6, 0x29, 0x5b, 0xb4, 0x38, 0x3a, 0xee,
- 0xfb, 0x0b, 0xd6, 0x2c, 0xe4, 0x46, 0x71, 0x14, 0x36, 0x7d, 0x14, 0xf8,
- 0x72, 0x47, 0x30, 0x8e, 0xf0, 0xbc, 0x3b, 0x44, 0x9f, 0xf5, 0x99, 0xea,
- 0x2c, 0xde, 0xf7, 0xa1, 0xfd, 0xe7, 0x06, 0xce, 0x3e, 0xf4, 0xf9, 0x57,
- 0xa8, 0x63, 0x1b, 0xfb, 0x70, 0x8a, 0x1f, 0xe0, 0xfd, 0x41, 0xf4, 0x01,
- 0x4f, 0x81, 0x53, 0x6c, 0xf7, 0x30, 0x7e, 0x2f, 0xa3, 0xee, 0xdd, 0xa8,
- 0xbb, 0x8e, 0xba, 0x43, 0x78, 0xff, 0xe1, 0xae, 0x79, 0xdf, 0x81, 0xf7,
- 0xcf, 0xa1, 0x1d, 0xfb, 0x77, 0x5e, 0x44, 0xfb, 0x83, 0xf8, 0xfd, 0xc5,
- 0xae, 0x3e, 0x8d, 0x5d, 0xef, 0xbe, 0xbc, 0x79, 0xc9, 0xf0, 0xc0, 0x8e,
- 0x6f, 0x07, 0xfe, 0xb1, 0xa8, 0x8f, 0x0a, 0x15, 0xca, 0x9b, 0xb0, 0x3c,
- 0xb2, 0xe2, 0xcb, 0x1c, 0x91, 0x79, 0xc8, 0xfa, 0x42, 0x45, 0xbc, 0x6e,
- 0x19, 0x9e, 0xfc, 0x31, 0x64, 0xfa, 0x3c, 0xf0, 0x5a, 0x80, 0x7d, 0x71,
- 0x74, 0x25, 0x8c, 0xe7, 0x21, 0xc8, 0x3b, 0xc9, 0x74, 0x09, 0x79, 0x3e,
- 0x02, 0xd9, 0xd2, 0x0b, 0x9e, 0x57, 0x3e, 0x88, 0x3c, 0x0e, 0xb9, 0x34,
- 0x8b, 0xbe, 0xb3, 0xe8, 0xf3, 0xd1, 0xe6, 0xff, 0x31, 0xb4, 0xec, 0xc3,
- 0xf0, 0xec, 0x2e, 0x18, 0xc2, 0xe2, 0xae, 0x92, 0x1f, 0x5f, 0x98, 0x9e,
- 0x5b, 0x89, 0xc8, 0xf0, 0xaa, 0x9d, 0xa4, 0xb3, 0x3f, 0xb2, 0xca, 0x98,
- 0x84, 0x8c, 0x04, 0x85, 0xb2, 0x5f, 0xc6, 0x43, 0xb0, 0xd1, 0x02, 0xde,
- 0x30, 0x74, 0x94, 0x7a, 0x97, 0x2c, 0x60, 0xcb, 0x36, 0x77, 0x62, 0x13,
- 0x47, 0xda, 0xb1, 0x89, 0x21, 0xe8, 0x88, 0xd7, 0x83, 0x5a, 0x5e, 0x45,
- 0x40, 0x27, 0x6f, 0x01, 0xfe, 0x29, 0x5b, 0x42, 0xe0, 0x1f, 0x07, 0xbc,
- 0xf3, 0x26, 0xda, 0x6f, 0xd4, 0x5b, 0xa0, 0x77, 0xc8, 0x38, 0x9b, 0xf5,
- 0x2c, 0xd1, 0x96, 0x21, 0x0f, 0xe0, 0xbd, 0xd1, 0xc9, 0x6b, 0xe7, 0xb4,
- 0x8d, 0x75, 0x97, 0x6f, 0xf3, 0xa0, 0xa3, 0x69, 0x91, 0xf6, 0xfa, 0xe1,
- 0xd0, 0x9d, 0x7b, 0xfc, 0xa3, 0x5d, 0x7b, 0x0c, 0x4a, 0x72, 0x89, 0xf8,
- 0x8d, 0xa8, 0xbd, 0xfa, 0xf8, 0x2d, 0x2a, 0x5b, 0x7e, 0x1c, 0x3e, 0x89,
- 0x40, 0x9a, 0x2b, 0x5b, 0x14, 0x3a, 0xb1, 0x0f, 0xb2, 0x9e, 0x72, 0x9e,
- 0xf8, 0x0e, 0x03, 0x87, 0x11, 0xfc, 0x1c, 0xfc, 0x76, 0x70, 0x7a, 0xb2,
- 0xbd, 0x3f, 0x7f, 0x0f, 0xeb, 0x90, 0x55, 0x2c, 0x09, 0x3f, 0xf0, 0x71,
- 0x91, 0xcf, 0x90, 0xaf, 0x7d, 0x94, 0xb7, 0x3e, 0x4c, 0x8f, 0xed, 0x82,
- 0x89, 0xb8, 0x21, 0x4c, 0xf5, 0x16, 0x6c, 0x8b, 0x28, 0xa3, 0x60, 0xa7,
- 0x9b, 0xd4, 0x29, 0x5c, 0x73, 0x92, 0xf6, 0xb6, 0x81, 0x93, 0x7a, 0xc5,
- 0x93, 0x73, 0x95, 0xb7, 0x1b, 0xb8, 0x78, 0xbe, 0xb0, 0xf9, 0x96, 0xb8,
- 0x7e, 0x54, 0xe9, 0x1e, 0x0d, 0xd3, 0x6e, 0xfc, 0xd0, 0x3f, 0x27, 0x7e,
- 0xa8, 0x0f, 0x88, 0x4b, 0xda, 0xd4, 0xc4, 0xe7, 0xef, 0x00, 0x9f, 0xec,
- 0xeb, 0x1a, 0xdd, 0xf2, 0x2e, 0x03, 0xd7, 0xdd, 0xfa, 0xf8, 0xf4, 0x1d,
- 0xfa, 0xd8, 0xc7, 0xf1, 0x5e, 0x67, 0xf1, 0xfb, 0x7d, 0xbe, 0xcc, 0x1d,
- 0x5e, 0xdd, 0xab, 0x7d, 0xd9, 0xb4, 0xb3, 0xad, 0xb3, 0xfe, 0xdb, 0x7d,
- 0xfe, 0x19, 0x0e, 0x2f, 0xef, 0x6e, 0xeb, 0x3b, 0xb0, 0x33, 0x66, 0xf7,
- 0x7c, 0x3f, 0xee, 0xdb, 0xdb, 0xaf, 0xdd, 0xf1, 0xeb, 0xe0, 0xab, 0xd8,
- 0x3b, 0x7b, 0xc9, 0xda, 0xf3, 0xcd, 0x82, 0xad, 0xf7, 0xc2, 0x3e, 0x68,
- 0x6b, 0x6e, 0xf5, 0x07, 0x95, 0x6e, 0xcc, 0xda, 0xf4, 0x63, 0x4a, 0x6b,
- 0x7c, 0xbe, 0x07, 0x65, 0xe7, 0xd8, 0x21, 0xf0, 0x40, 0x16, 0x7d, 0x39,
- 0xc7, 0xee, 0xf1, 0xbe, 0x8d, 0x94, 0x96, 0x85, 0x5a, 0x08, 0xed, 0x89,
- 0x6c, 0x49, 0x1e, 0x86, 0xaf, 0x98, 0x98, 0xa2, 0xdf, 0x00, 0x7f, 0x79,
- 0x46, 0xe4, 0x98, 0x94, 0x6b, 0x1f, 0x94, 0x85, 0x95, 0x96, 0xbc, 0x1f,
- 0x7a, 0xf0, 0xf7, 0xa0, 0x47, 0xe5, 0x12, 0x84, 0xd7, 0x25, 0x1c, 0xc6,
- 0xa5, 0xa8, 0xd8, 0x4f, 0xc1, 0x96, 0xbf, 0x10, 0x93, 0xe0, 0x05, 0xd2,
- 0x5e, 0xca, 0x79, 0xbf, 0x48, 0xbf, 0x2d, 0x57, 0xe1, 0x08, 0x25, 0x26,
- 0xb3, 0x92, 0x82, 0xfd, 0x37, 0xe6, 0x34, 0x50, 0x96, 0x25, 0x35, 0xfa,
- 0xb4, 0xa0, 0xef, 0x25, 0xf4, 0xc5, 0xb8, 0x9e, 0x8d, 0x38, 0x7e, 0x83,
- 0xd2, 0xbb, 0x41, 0x18, 0x92, 0xa6, 0x24, 0x2c, 0x3f, 0x6c, 0xd1, 0xd7,
- 0x7d, 0x66, 0x33, 0x0c, 0xdd, 0x14, 0x97, 0xe7, 0x20, 0x67, 0x9f, 0x55,
- 0xf1, 0x17, 0xb7, 0xed, 0x8f, 0x3e, 0x7a, 0x18, 0x74, 0xb7, 0x2c, 0xe1,
- 0xa8, 0xf7, 0x73, 0x59, 0x59, 0x6e, 0xc1, 0xef, 0xa1, 0xac, 0x7f, 0x00,
- 0xf2, 0x2a, 0xf1, 0xa5, 0x12, 0x6d, 0x49, 0x37, 0x03, 0xd8, 0x4b, 0x32,
- 0x73, 0xf8, 0x5d, 0x03, 0x9a, 0x3e, 0x8e, 0x49, 0x70, 0xb9, 0x00, 0xfb,
- 0xf9, 0x8c, 0x2c, 0xa6, 0xe1, 0x9f, 0xda, 0xa5, 0x56, 0xc0, 0x75, 0x63,
- 0xd0, 0xdb, 0xd0, 0xa7, 0x2b, 0xf4, 0x87, 0xe5, 0xc8, 0x32, 0xfb, 0x9c,
- 0x01, 0x6d, 0x75, 0x01, 0x77, 0xdd, 0x72, 0x36, 0x9a, 0x28, 0xe5, 0xc1,
- 0x4f, 0xb6, 0xdb, 0x0f, 0x5e, 0x66, 0x49, 0xfd, 0xf6, 0x34, 0xe8, 0x87,
- 0xcf, 0x38, 0xce, 0x55, 0xd6, 0x27, 0x51, 0xb2, 0xde, 0x15, 0x7b, 0x29,
- 0x8c, 0xb9, 0xa0, 0x93, 0x2e, 0x97, 0xe4, 0x6c, 0xe6, 0x98, 0x34, 0x6a,
- 0xf0, 0xc9, 0x33, 0xb0, 0xa3, 0xea, 0x9e, 0x34, 0x2a, 0xb4, 0x9f, 0x4e,
- 0x81, 0x1f, 0x5e, 0x41, 0x39, 0x8f, 0xf2, 0x16, 0xca, 0x8f, 0xa3, 0x7c,
- 0x0d, 0x25, 0x61, 0x3f, 0x25, 0x8d, 0xfa, 0x55, 0xcc, 0xcd, 0x39, 0xa6,
- 0x0c, 0xcc, 0xf0, 0x21, 0x0f, 0x9f, 0x82, 0x9d, 0xe3, 0xd7, 0x9f, 0x12,
- 0x69, 0x7c, 0x0c, 0xbf, 0x96, 0x7a, 0xa7, 0x8f, 0xb9, 0x90, 0x99, 0x84,
- 0xbd, 0x2b, 0xd6, 0xd9, 0xcc, 0xc7, 0xcd, 0x3c, 0x1f, 0xc3, 0x7a, 0xd7,
- 0xb1, 0x76, 0x18, 0xe7, 0xd9, 0x92, 0x47, 0xd3, 0x67, 0xe4, 0x93, 0xe9,
- 0x7b, 0x65, 0x62, 0x20, 0x5c, 0x0a, 0x7b, 0xdc, 0x3f, 0xed, 0xda, 0xbd,
- 0xf6, 0xef, 0xef, 0x9b, 0x7b, 0x8e, 0x60, 0x2f, 0xfb, 0xb5, 0xed, 0x66,
- 0xff, 0x13, 0xe3, 0x73, 0x58, 0x92, 0x1c, 0xe1, 0x7c, 0x9e, 0x04, 0x96,
- 0x47, 0x9c, 0x8c, 0x3d, 0x06, 0xeb, 0x3d, 0x85, 0xdf, 0x19, 0xd0, 0x8a,
- 0x7b, 0x3e, 0x69, 0xff, 0x47, 0xc0, 0x84, 0xb6, 0x06, 0xd7, 0x11, 0x2b,
- 0x78, 0xe8, 0x26, 0xf6, 0x56, 0x92, 0xee, 0x43, 0x9e, 0xdc, 0x6e, 0xf2,
- 0x19, 0x92, 0xf2, 0xd2, 0x31, 0xf9, 0x71, 0xed, 0xba, 0x9c, 0xab, 0x1d,
- 0x93, 0x97, 0x51, 0x2e, 0xd6, 0x4a, 0xc0, 0x23, 0x7d, 0x46, 0xce, 0xd1,
- 0xc2, 0xb9, 0x50, 0x2e, 0xdf, 0x1f, 0x9b, 0xc7, 0xf9, 0xcd, 0x3a, 0x2d,
- 0xd9, 0x48, 0x97, 0x64, 0x63, 0x12, 0x63, 0xea, 0x3d, 0x12, 0xfa, 0x2a,
- 0xf7, 0xdb, 0x27, 0xf9, 0x5a, 0x49, 0x0a, 0x19, 0xfa, 0x34, 0xbd, 0x92,
- 0x87, 0x4d, 0x0e, 0x3b, 0xe8, 0x8c, 0x8e, 0xb3, 0xb9, 0xb1, 0x22, 0x6c,
- 0xf8, 0x85, 0xe6, 0xeb, 0x56, 0xa3, 0x6d, 0xff, 0x6f, 0x59, 0xcf, 0xc2,
- 0x76, 0xfd, 0x0e, 0xe4, 0xc6, 0x73, 0xb0, 0x09, 0x9f, 0xbd, 0x83, 0xc7,
- 0x48, 0x23, 0xd7, 0xac, 0x46, 0x7d, 0x94, 0x7c, 0x66, 0xf8, 0x01, 0x63,
- 0xe1, 0xe7, 0x34, 0x6a, 0xb7, 0x0c, 0xfd, 0x29, 0x5b, 0x00, 0xe7, 0x42,
- 0xbd, 0xf2, 0x77, 0xf0, 0xaf, 0x28, 0x77, 0x7c, 0xbd, 0xaf, 0xfd, 0x86,
- 0x3a, 0x60, 0xcd, 0x47, 0x13, 0x80, 0x4a, 0xa4, 0x5e, 0x2f, 0x28, 0x5c,
- 0xb9, 0xcb, 0x43, 0x52, 0xab, 0x12, 0xbf, 0x09, 0xc7, 0xb6, 0x95, 0x5d,
- 0x0b, 0xbc, 0xba, 0x38, 0x1f, 0xbf, 0x3d, 0x01, 0xff, 0xe1, 0x8c, 0x38,
- 0x13, 0xbd, 0xd8, 0x13, 0x9f, 0x45, 0x66, 0x2e, 0xff, 0x3a, 0x19, 0xd0,
- 0x05, 0xbf, 0x3e, 0x84, 0xb3, 0x8c, 0xc8, 0x59, 0xd8, 0xff, 0xe7, 0x40,
- 0x47, 0x9f, 0xaf, 0x0c, 0xc9, 0xf9, 0x4a, 0x1c, 0xfe, 0x16, 0xed, 0x94,
- 0xe5, 0xe9, 0xe4, 0x3a, 0xcb, 0x27, 0xa6, 0x53, 0x75, 0x96, 0x5f, 0x32,
- 0xfe, 0xe2, 0x97, 0x8d, 0x1f, 0xb9, 0x3e, 0xad, 0x7d, 0xb8, 0xaf, 0x4d,
- 0x8f, 0xaa, 0xb2, 0x39, 0xbd, 0x13, 0x3b, 0x09, 0x1b, 0xbd, 0x9d, 0xa1,
- 0x7e, 0x06, 0x8c, 0x12, 0x3c, 0x09, 0x7a, 0x9a, 0x87, 0xdc, 0xce, 0xc1,
- 0xf7, 0x38, 0x0b, 0x1f, 0xa4, 0xd8, 0x84, 0x4c, 0xf0, 0xd2, 0x28, 0xc5,
- 0xfc, 0xf9, 0x63, 0xbb, 0x18, 0xdf, 0xe4, 0x99, 0x19, 0xff, 0x2b, 0x4d,
- 0xff, 0xab, 0xf3, 0x8f, 0xf3, 0x81, 0x36, 0xa9, 0x2b, 0x7f, 0x09, 0x9f,
- 0x51, 0x82, 0xc5, 0x0c, 0xc7, 0xa6, 0xe9, 0xaf, 0xca, 0x36, 0xec, 0x83,
- 0xb0, 0xf7, 0x3d, 0x09, 0x3f, 0xd5, 0x6a, 0xbd, 0x0a, 0x59, 0x53, 0x82,
- 0xcf, 0x68, 0x5b, 0xa8, 0x5f, 0x67, 0x1b, 0xe5, 0xc8, 0x98, 0x73, 0x1b,
- 0x34, 0x97, 0x3d, 0x2e, 0xf2, 0x5d, 0xd4, 0x35, 0x56, 0x78, 0x06, 0xdf,
- 0xc7, 0x19, 0x98, 0x33, 0x51, 0x75, 0xec, 0x07, 0xfb, 0x3d, 0xca, 0x7d,
- 0x8c, 0x39, 0xdd, 0x18, 0x5f, 0x5f, 0xe7, 0x98, 0xc4, 0x24, 0xaf, 0x74,
- 0xbe, 0xbb, 0xae, 0xf7, 0x77, 0x34, 0x33, 0x2a, 0x57, 0x2b, 0x6a, 0x0e,
- 0xd0, 0xfa, 0xaf, 0x30, 0x66, 0x0b, 0x74, 0xcb, 0x18, 0x95, 0x27, 0x65,
- 0xe8, 0xa4, 0x72, 0x25, 0x05, 0xda, 0x09, 0xca, 0x6c, 0x8c, 0x60, 0xbb,
- 0xb2, 0x5d, 0xf9, 0x72, 0x97, 0x8e, 0x8f, 0xf0, 0x19, 0x3a, 0xac, 0x39,
- 0x23, 0xbc, 0x1b, 0x81, 0x7d, 0x83, 0x3d, 0x75, 0xe2, 0x42, 0xff, 0x15,
- 0x71, 0x16, 0x66, 0x8f, 0xea, 0x4f, 0xaf, 0x83, 0xf1, 0x66, 0x9d, 0x02,
- 0x14, 0x77, 0x1e, 0xeb, 0xa7, 0x2e, 0x05, 0x83, 0x8c, 0xa9, 0x27, 0x2f,
- 0x81, 0xad, 0x3c, 0x83, 0x8b, 0xa6, 0x4f, 0x6b, 0xbe, 0x2f, 0x4a, 0xda,
- 0x22, 0x0e, 0x12, 0xa5, 0x2d, 0x20, 0x7b, 0xc0, 0xbb, 0x21, 0x1f, 0x5a,
- 0xd5, 0x7b, 0xb6, 0x2f, 0x0a, 0xef, 0x5b, 0xe4, 0xf6, 0x4a, 0x22, 0x7d,
- 0x0b, 0xb2, 0x39, 0x1f, 0x4d, 0x83, 0x56, 0x3e, 0xd1, 0x05, 0x9e, 0x9e,
- 0xcc, 0xda, 0x3f, 0xe8, 0xd2, 0xb6, 0x20, 0x7c, 0x7e, 0xc6, 0x01, 0x2a,
- 0x59, 0x8c, 0xe9, 0x96, 0x7f, 0x11, 0xc4, 0x73, 0x93, 0xef, 0xb0, 0x73,
- 0x82, 0x1a, 0xbe, 0xb2, 0xc1, 0x21, 0xfc, 0x04, 0xd1, 0xb1, 0x5c, 0x4b,
- 0x3e, 0x04, 0x29, 0x2f, 0x98, 0x3f, 0x69, 0xd6, 0x4a, 0x5e, 0x0c, 0xb7,
- 0x6d, 0xba, 0xd4, 0xaa, 0x07, 0xdb, 0x22, 0x68, 0x7c, 0x22, 0xca, 0x18,
- 0xd9, 0xc3, 0xa6, 0xee, 0xb4, 0x8f, 0xc3, 0x2a, 0x5e, 0xc7, 0x7b, 0x24,
- 0xd2, 0xd6, 0x94, 0xa1, 0xad, 0x8f, 0x81, 0xb6, 0x4e, 0x29, 0xda, 0x6a,
- 0xc9, 0xab, 0xe9, 0xb4, 0x7c, 0x61, 0x4f, 0xfa, 0xda, 0xfd, 0x17, 0x01,
- 0xbc, 0xfc, 0x0d, 0xca, 0xc2, 0x17, 0xb1, 0x2e, 0xf4, 0x4e, 0xb9, 0x92,
- 0xc8, 0xce, 0xd2, 0x16, 0x82, 0x1e, 0x29, 0xc3, 0xe7, 0x4a, 0x5e, 0x1a,
- 0x52, 0x7d, 0x92, 0xd0, 0x29, 0x0d, 0xd0, 0x1b, 0xf1, 0x5b, 0xae, 0x40,
- 0x0e, 0x5f, 0x0a, 0x41, 0x6f, 0x91, 0x67, 0x65, 0xc0, 0x86, 0x6c, 0x60,
- 0xff, 0x06, 0x78, 0x27, 0x79, 0x29, 0x82, 0x32, 0xae, 0xe6, 0x6a, 0x54,
- 0x5c, 0x35, 0xbe, 0x51, 0x19, 0x55, 0xe3, 0x1a, 0xb0, 0x5f, 0x93, 0x97,
- 0x20, 0xdf, 0x33, 0x69, 0x19, 0xb9, 0x94, 0x91, 0xf8, 0x25, 0x4b, 0x8a,
- 0x33, 0xad, 0x56, 0x18, 0xb0, 0x8f, 0x5e, 0xea, 0x97, 0x5b, 0x2a, 0xb6,
- 0x1a, 0x56, 0xf1, 0xd6, 0xc5, 0xcc, 0x0c, 0x78, 0x93, 0xf8, 0xf3, 0x30,
- 0xa6, 0x00, 0xfd, 0x58, 0x90, 0xb3, 0x2b, 0xc4, 0x0f, 0xe3, 0xe5, 0xdb,
- 0xb1, 0x80, 0x24, 0x20, 0xcb, 0x8e, 0xcb, 0x7c, 0xad, 0x1b, 0xb2, 0x2c,
- 0x08, 0x1d, 0xf8, 0x50, 0xb7, 0xf4, 0x0e, 0x93, 0x1e, 0x80, 0x17, 0x0f,
- 0x73, 0x17, 0x24, 0x8f, 0x31, 0x85, 0x95, 0x9d, 0xfe, 0x45, 0xe9, 0x06,
- 0x4f, 0x1d, 0x97, 0x93, 0x35, 0xce, 0x13, 0x74, 0xca, 0x72, 0x10, 0x34,
- 0xe4, 0x3a, 0x47, 0x30, 0x0f, 0xf4, 0x76, 0xc7, 0x1f, 0xf9, 0x2f, 0xfb,
- 0x06, 0x34, 0xe9, 0xf3, 0x5d, 0xb8, 0xd4, 0xe5, 0xcd, 0x58, 0xdb, 0x19,
- 0x09, 0xce, 0x65, 0x3e, 0x60, 0x7d, 0x37, 0x93, 0xb1, 0xae, 0x65, 0xb2,
- 0xd6, 0xf5, 0x4c, 0xc1, 0xba, 0x01, 0xdd, 0xd4, 0xd8, 0x7c, 0x0e, 0xf4,
- 0x03, 0xdd, 0xcf, 0x98, 0x79, 0xfb, 0x0c, 0xa3, 0x26, 0x66, 0xf0, 0x9a,
- 0x6c, 0x54, 0x68, 0x3b, 0xb4, 0x1e, 0x9e, 0x4b, 0x97, 0xee, 0x01, 0x7c,
- 0x80, 0x83, 0xbe, 0xee, 0x8e, 0xee, 0x08, 0x79, 0xa3, 0xb2, 0xa6, 0x74,
- 0x47, 0x84, 0xba, 0x23, 0x9d, 0x97, 0xfd, 0xb2, 0x5d, 0x03, 0xff, 0x89,
- 0xb2, 0x83, 0x65, 0xbb, 0x1e, 0x95, 0x2f, 0x54, 0x7d, 0x5a, 0xe2, 0x7e,
- 0xcb, 0x6f, 0xea, 0x91, 0x80, 0x4c, 0x29, 0x7d, 0xdd, 0x27, 0x57, 0xd7,
- 0xe1, 0x0f, 0xc1, 0x5a, 0xb0, 0xef, 0x63, 0xac, 0xc0, 0x56, 0xbe, 0xb1,
- 0xf4, 0xf3, 0xee, 0xea, 0x2c, 0x70, 0xc5, 0xfb, 0x25, 0xec, 0xb3, 0x9f,
- 0x3b, 0xf2, 0xdf, 0xc7, 0xc1, 0x93, 0x7c, 0xb6, 0x24, 0x0f, 0xbb, 0x91,
- 0xf7, 0x5c, 0x79, 0xd8, 0x3d, 0xdb, 0x95, 0x31, 0xc0, 0x15, 0x80, 0x4d,
- 0x1e, 0x06, 0x1c, 0x55, 0xd5, 0xde, 0xed, 0x8a, 0x35, 0x07, 0x3d, 0x5c,
- 0x54, 0xf7, 0x57, 0x28, 0xd7, 0xf5, 0xda, 0x79, 0xf8, 0xab, 0xc5, 0xf1,
- 0x1e, 0xea, 0xb7, 0xd1, 0x12, 0xf9, 0x5e, 0xd9, 0xf1, 0x19, 0xf0, 0xdc,
- 0x57, 0xba, 0xa9, 0xdb, 0x8f, 0xa6, 0x27, 0xe5, 0x46, 0x85, 0xcf, 0x6c,
- 0x4f, 0xa4, 0x45, 0xc5, 0x8f, 0x2b, 0xd3, 0x8b, 0xee, 0x6b, 0x86, 0xc7,
- 0x6a, 0xa0, 0xf1, 0x53, 0xf2, 0x8d, 0xcd, 0x79, 0xf9, 0xf7, 0x9b, 0xb3,
- 0xb0, 0x4f, 0x4e, 0xc0, 0x3e, 0xf9, 0x08, 0x78, 0xf8, 0x38, 0x78, 0xf8,
- 0xe3, 0xa0, 0xfb, 0x19, 0x15, 0x77, 0xa8, 0x55, 0x12, 0x57, 0x4a, 0x2a,
- 0xce, 0xfd, 0x1a, 0x68, 0x7e, 0x42, 0x82, 0xab, 0x43, 0xc0, 0x6b, 0xa9,
- 0x15, 0x75, 0x5b, 0x0f, 0xc3, 0x06, 0xc1, 0x59, 0x97, 0x12, 0x41, 0x45,
- 0x23, 0xae, 0xf3, 0x69, 0xe0, 0xf2, 0x4d, 0x5e, 0xa2, 0xc6, 0x23, 0xde,
- 0xa8, 0x8d, 0x4a, 0xf1, 0x32, 0xfa, 0x2f, 0x47, 0x80, 0x37, 0xea, 0xc6,
- 0xc4, 0xf9, 0xa2, 0x6c, 0x81, 0x2e, 0xb2, 0xc0, 0xcf, 0x3b, 0xa4, 0x1c,
- 0x4d, 0x7c, 0x4d, 0x64, 0x52, 0x0e, 0x2d, 0x81, 0xa6, 0x97, 0x6c, 0xec,
- 0x99, 0xb8, 0xc4, 0xf3, 0x65, 0x4f, 0xec, 0x65, 0xca, 0xa2, 0x03, 0xc6,
- 0x37, 0xd1, 0xfa, 0xbe, 0x2e, 0x5c, 0x97, 0xeb, 0x7d, 0x46, 0xe6, 0xa1,
- 0x53, 0x61, 0x7f, 0x43, 0x66, 0xbb, 0x31, 0xac, 0x19, 0x9e, 0xbb, 0xec,
- 0x84, 0xe7, 0x2f, 0x73, 0x9e, 0xb0, 0x04, 0x96, 0x78, 0xb6, 0x9c, 0x07,
- 0x3c, 0x80, 0xb9, 0x53, 0x4b, 0xc4, 0xdb, 0x18, 0xc6, 0xfd, 0x63, 0xe8,
- 0x63, 0x4d, 0x57, 0xb9, 0x65, 0x2d, 0x1f, 0x72, 0x8d, 0x4e, 0x9d, 0x88,
- 0x33, 0x80, 0xfc, 0xc8, 0x36, 0xb4, 0x7e, 0x2b, 0x28, 0xfd, 0xa7, 0x75,
- 0xdf, 0x71, 0x81, 0x51, 0xd7, 0xeb, 0xaa, 0xfd, 0x04, 0x96, 0xb7, 0xa8,
- 0xef, 0xb1, 0x06, 0xc7, 0x84, 0x3a, 0xe0, 0xce, 0x40, 0xee, 0xdc, 0x1b,
- 0x26, 0xee, 0x1f, 0x83, 0x7e, 0x4d, 0x2e, 0xe9, 0x98, 0x7c, 0xf2, 0x72,
- 0x1a, 0xfb, 0x91, 0x41, 0x46, 0x17, 0x6c, 0xec, 0xe1, 0x7d, 0x4a, 0x7e,
- 0x4d, 0x40, 0x66, 0x39, 0xb2, 0x7e, 0x90, 0x67, 0x33, 0x28, 0x8d, 0xa7,
- 0xf9, 0xce, 0x33, 0xe2, 0x79, 0x93, 0x17, 0xa3, 0xd0, 0x2f, 0x38, 0xa7,
- 0xbe, 0x21, 0xa9, 0x6f, 0xb2, 0x6d, 0x48, 0xd1, 0x72, 0x10, 0x67, 0xb0,
- 0x58, 0x69, 0x3d, 0x9c, 0x4b, 0x97, 0x40, 0x6d, 0xc4, 0x39, 0xf1, 0x41,
- 0xbc, 0x8f, 0x03, 0x36, 0xe2, 0xb8, 0x8f, 0xba, 0x18, 0x75, 0xfb, 0xa5,
- 0x58, 0x23, 0x3d, 0xa3, 0xac, 0xef, 0x37, 0xbe, 0xde, 0x67, 0x78, 0x27,
- 0x84, 0xbd, 0x6b, 0x3a, 0x2e, 0x80, 0xa6, 0xca, 0xf0, 0xbb, 0xae, 0x2e,
- 0x49, 0xf8, 0x4d, 0x90, 0xcf, 0x9f, 0xa2, 0x0c, 0x05, 0x7d, 0x95, 0xd7,
- 0x27, 0x40, 0x6b, 0x7d, 0x90, 0x97, 0xad, 0xd6, 0x71, 0xd8, 0xc9, 0xa7,
- 0xd3, 0xc4, 0xd1, 0x4d, 0xe0, 0xa8, 0x3b, 0x76, 0x1a, 0xe7, 0xb5, 0xf6,
- 0xf4, 0x43, 0x4a, 0x5e, 0xc0, 0xd6, 0x51, 0x7a, 0x4b, 0xc7, 0x38, 0xd2,
- 0xb4, 0x8d, 0x14, 0x0f, 0xe7, 0x5c, 0xca, 0xc3, 0x3c, 0xf0, 0x30, 0xae,
- 0xe4, 0xb7, 0x96, 0x2d, 0x3d, 0x52, 0x3c, 0x9e, 0xc5, 0x7e, 0x27, 0x77,
- 0xf5, 0xcb, 0xe0, 0x1d, 0xb6, 0x5f, 0xf3, 0x43, 0x61, 0xc6, 0x43, 0x03,
- 0xde, 0xa4, 0x6c, 0x1c, 0x9c, 0x92, 0x8b, 0x07, 0x13, 0x93, 0xb3, 0x36,
- 0x75, 0xc2, 0x94, 0xd4, 0x9f, 0xce, 0xca, 0x5a, 0x55, 0xeb, 0xe6, 0x39,
- 0x77, 0x52, 0xf2, 0xcd, 0x02, 0xde, 0x3d, 0x94, 0xec, 0xef, 0xcb, 0x5d,
- 0x7f, 0x4f, 0x39, 0xee, 0x09, 0x32, 0x42, 0xeb, 0x5e, 0xdb, 0xee, 0xc6,
- 0xf9, 0x50, 0x2e, 0x7c, 0x10, 0xf5, 0x39, 0xc8, 0x36, 0x9e, 0x67, 0x0a,
- 0x67, 0x77, 0x4a, 0x9d, 0x53, 0x3e, 0x4d, 0x7f, 0x80, 0x63, 0x12, 0xb1,
- 0x39, 0xd4, 0xcf, 0x08, 0x75, 0x28, 0xf7, 0xe6, 0xcf, 0xe7, 0x19, 0xf8,
- 0x03, 0x8c, 0x31, 0xe1, 0xef, 0x33, 0x61, 0xf2, 0x64, 0xc0, 0xf5, 0xeb,
- 0xc7, 0xa0, 0x7f, 0x43, 0x6a, 0x8d, 0x72, 0x95, 0x75, 0x29, 0x87, 0xe3,
- 0xf3, 0x69, 0xbe, 0x8b, 0x3c, 0x66, 0xfc, 0xf2, 0xe3, 0xf0, 0x5b, 0xf3,
- 0xcd, 0xae, 0xdf, 0xa0, 0x7f, 0x77, 0x64, 0x9d, 0x96, 0xcb, 0xdb, 0x31,
- 0xc7, 0xc8, 0xde, 0x93, 0x35, 0xc6, 0xac, 0x2d, 0xe9, 0x82, 0x2c, 0x3d,
- 0x2a, 0xc3, 0x46, 0x8e, 0x72, 0x3f, 0x7d, 0x4a, 0xd7, 0xe5, 0x67, 0x62,
- 0x72, 0x6e, 0xed, 0xff, 0x85, 0xae, 0x7f, 0xbd, 0x5d, 0x57, 0xd8, 0xc3,
- 0xae, 0xbb, 0x79, 0x19, 0xf2, 0xa0, 0x0a, 0x59, 0x51, 0x85, 0xac, 0xa8,
- 0x42, 0x56, 0x54, 0x21, 0x2b, 0xaa, 0x90, 0x15, 0x55, 0xc8, 0x8a, 0xea,
- 0x8c, 0xd1, 0x9b, 0xa7, 0x21, 0x73, 0xe9, 0xf3, 0xd0, 0xcf, 0xe9, 0xb4,
- 0x05, 0xe2, 0x90, 0x25, 0xf4, 0x67, 0x12, 0xa5, 0x5b, 0xc0, 0xcd, 0xd7,
- 0xd3, 0xf4, 0xb9, 0x5b, 0xf2, 0x57, 0xe9, 0xce, 0xdd, 0xab, 0xf8, 0x86,
- 0x3c, 0x0a, 0x7c, 0x7d, 0x08, 0xf8, 0xfa, 0xf0, 0x5d, 0x39, 0x16, 0x7e,
- 0x4c, 0x64, 0xb8, 0x14, 0x80, 0xff, 0x39, 0x73, 0x07, 0xee, 0xe8, 0x7b,
- 0x63, 0x8d, 0xbb, 0x6c, 0x63, 0xfa, 0xdc, 0xa3, 0xea, 0xde, 0x7c, 0x03,
- 0x76, 0xf9, 0x8d, 0x74, 0x29, 0x12, 0x50, 0xf7, 0x73, 0x2e, 0x69, 0x67,
- 0x8f, 0xbf, 0x6f, 0x84, 0xb5, 0x5c, 0xd4, 0x67, 0x9f, 0xcf, 0xf4, 0x81,
- 0x0f, 0x68, 0xdf, 0xdd, 0x50, 0xf6, 0xdd, 0xd1, 0x74, 0x50, 0xb6, 0xa2,
- 0xd4, 0xa9, 0x3f, 0x92, 0x93, 0x2b, 0x91, 0x1e, 0xfa, 0xdf, 0x8b, 0xd5,
- 0x83, 0xb2, 0xad, 0x64, 0xca, 0x07, 0xd1, 0xd7, 0x93, 0x79, 0xd0, 0xc4,
- 0x11, 0xf8, 0x8e, 0x17, 0x65, 0x2c, 0x76, 0x11, 0x7b, 0xfd, 0x3c, 0xc6,
- 0xc0, 0x07, 0x68, 0x15, 0x50, 0x77, 0x1d, 0x7e, 0xc6, 0x6d, 0xe1, 0xf3,
- 0x98, 0x73, 0x1e, 0x88, 0xce, 0x3a, 0x29, 0xe7, 0x35, 0xf1, 0xe9, 0x8c,
- 0x34, 0xc5, 0xbb, 0xb6, 0x41, 0xc9, 0xaf, 0xd3, 0x2f, 0xeb, 0x03, 0x1f,
- 0xfe, 0x08, 0x7a, 0x98, 0x6b, 0x50, 0x2e, 0x70, 0x0f, 0xff, 0x0d, 0xf0,
- 0xc5, 0x67, 0xbb, 0xbd, 0xfb, 0xa1, 0x7b, 0x29, 0xf7, 0xb5, 0xef, 0x94,
- 0xc7, 0x18, 0xa5, 0x1b, 0xd2, 0xbc, 0x77, 0xe0, 0xfe, 0xfe, 0x18, 0x76,
- 0x4e, 0x14, 0x74, 0x80, 0xfa, 0x75, 0xdf, 0xce, 0xf5, 0xed, 0x19, 0x1d,
- 0xeb, 0xbb, 0xa2, 0x6c, 0x9a, 0x1c, 0xf4, 0xd8, 0x31, 0xf4, 0x65, 0xac,
- 0xbd, 0xd5, 0x3a, 0x95, 0x86, 0xdf, 0xf1, 0x24, 0x65, 0xd9, 0x7d, 0xe0,
- 0x69, 0xda, 0x45, 0xd4, 0xb9, 0x62, 0xdd, 0xcc, 0x6c, 0x3b, 0x61, 0xe8,
- 0xcb, 0x19, 0xd0, 0x5c, 0x0e, 0x74, 0x18, 0x78, 0x60, 0x0a, 0xfa, 0x57,
- 0xc5, 0x9c, 0x41, 0xeb, 0x5c, 0xf7, 0x83, 0xd6, 0x5f, 0x64, 0xc6, 0xa1,
- 0x8f, 0x1f, 0x82, 0x3e, 0xe6, 0x7d, 0x74, 0x0e, 0x3a, 0x99, 0xfa, 0xd8,
- 0x91, 0x3f, 0xdd, 0xcc, 0x41, 0x76, 0xdd, 0xd7, 0x43, 0x5e, 0x9b, 0x6a,
- 0xf3, 0x54, 0xc1, 0xf0, 0xdc, 0x01, 0x13, 0xfb, 0x28, 0x28, 0xde, 0x2c,
- 0xaf, 0xd3, 0x0e, 0x01, 0x9f, 0xae, 0x53, 0x46, 0xd0, 0xa6, 0xa4, 0xec,
- 0x80, 0xac, 0x59, 0xff, 0x00, 0xca, 0x29, 0x94, 0xda, 0x56, 0xbb, 0x52,
- 0x7d, 0x35, 0xec, 0xdf, 0x23, 0xef, 0xd8, 0x6b, 0x75, 0xec, 0xef, 0x18,
- 0x73, 0x1b, 0x4a, 0xfd, 0xde, 0x47, 0xb0, 0xc7, 0xe3, 0xa0, 0xc1, 0x19,
- 0xd0, 0xe0, 0x14, 0xf6, 0x7a, 0xde, 0x1a, 0x39, 0x1c, 0x80, 0x3e, 0x3f,
- 0x23, 0x85, 0x34, 0x64, 0xee, 0x5a, 0xc9, 0x9a, 0x58, 0x12, 0xf5, 0x9e,
- 0x4f, 0xf3, 0x4e, 0xfd, 0xbd, 0x2a, 0x3e, 0xb8, 0xbc, 0x19, 0x34, 0x71,
- 0xc4, 0x20, 0xea, 0xa8, 0xc3, 0x21, 0xb3, 0x1c, 0xcc, 0x55, 0xfd, 0x59,
- 0xaf, 0xf4, 0x62, 0xbe, 0xea, 0x34, 0xde, 0x19, 0x5b, 0x38, 0x66, 0xdd,
- 0x59, 0xcf, 0xd8, 0x45, 0xc2, 0xc9, 0xc1, 0x17, 0x0d, 0xba, 0x8c, 0x5f,
- 0xb8, 0x38, 0x9f, 0xac, 0xe4, 0x47, 0x60, 0x93, 0x29, 0x99, 0xdc, 0x6b,
- 0x64, 0x32, 0xe4, 0x5d, 0xcd, 0x93, 0xb5, 0x4d, 0xda, 0x4e, 0x9e, 0xf2,
- 0xa7, 0x29, 0xc7, 0x8a, 0x35, 0xd8, 0x3f, 0xe9, 0xdf, 0xb3, 0xb2, 0x6a,
- 0xce, 0xb0, 0xca, 0xd5, 0x28, 0xad, 0x89, 0xe5, 0x1c, 0xbe, 0x09, 0xff,
- 0x35, 0x03, 0x1e, 0xf6, 0x20, 0x37, 0x1d, 0xc8, 0x45, 0xea, 0xb5, 0xaf,
- 0x76, 0x4b, 0x1f, 0xea, 0x2f, 0xc3, 0xe6, 0x79, 0x92, 0x7c, 0x7b, 0x5d,
- 0xec, 0xc6, 0x1b, 0xc5, 0x47, 0x18, 0x1b, 0x19, 0x32, 0x77, 0xb3, 0xff,
- 0x0b, 0xf0, 0xea, 0x35, 0x42, 0xb0, 0xeb, 0xaf, 0xd6, 0xf6, 0xc1, 0x47,
- 0x3c, 0x66, 0xe5, 0xa3, 0xac, 0x2b, 0xc9, 0x7a, 0x86, 0x76, 0x28, 0x63,
- 0x24, 0x61, 0xd4, 0xef, 0xf6, 0x49, 0xa9, 0xff, 0x9f, 0x53, 0x77, 0x34,
- 0x0b, 0x4a, 0xee, 0xfa, 0xf1, 0xe5, 0xe7, 0x24, 0xd9, 0xf4, 0xe3, 0x54,
- 0x5c, 0x7f, 0xcb, 0x2a, 0x36, 0xff, 0x1c, 0xeb, 0x10, 0x06, 0xee, 0x45,
- 0xaf, 0x63, 0x2f, 0x4f, 0x98, 0x75, 0x1c, 0x2b, 0x74, 0x38, 0x86, 0xfd,
- 0xec, 0xef, 0x93, 0xbe, 0x00, 0xe4, 0xd9, 0x28, 0x9e, 0x6f, 0xa1, 0x6e,
- 0xe7, 0xbd, 0x51, 0x15, 0x2b, 0x70, 0x18, 0xde, 0x33, 0xf4, 0x77, 0x03,
- 0x32, 0xc7, 0x86, 0xfe, 0x6c, 0x54, 0x3f, 0x8e, 0x12, 0xe3, 0x9e, 0xbc,
- 0x2e, 0x73, 0xda, 0xdf, 0x86, 0x4d, 0x39, 0xac, 0x74, 0xf0, 0x4c, 0x9a,
- 0xb1, 0x90, 0x33, 0x90, 0x8f, 0xf7, 0xa3, 0x8e, 0x7e, 0x53, 0x49, 0x9c,
- 0xf7, 0x14, 0x8c, 0xbf, 0xaf, 0xcf, 0x25, 0xa0, 0xf4, 0xf5, 0x0a, 0xce,
- 0x83, 0x73, 0x50, 0xdf, 0xfd, 0x5c, 0x3e, 0xd5, 0x11, 0x47, 0xc9, 0xd9,
- 0xed, 0xb8, 0x41, 0x36, 0x0f, 0x1d, 0xbd, 0x56, 0x25, 0x0f, 0x66, 0x70,
- 0xde, 0x59, 0xf9, 0xda, 0xe6, 0x3d, 0xc0, 0x75, 0x54, 0x02, 0x4f, 0xb5,
- 0x40, 0x3f, 0xd4, 0x0d, 0x63, 0x90, 0xc9, 0x8e, 0xb1, 0x25, 0xa2, 0x12,
- 0x7c, 0x6a, 0x48, 0xba, 0x2f, 0xc4, 0xa4, 0xeb, 0x02, 0xf3, 0x4f, 0x52,
- 0x71, 0xd8, 0xc5, 0xb4, 0x87, 0x78, 0x0f, 0xc9, 0xfb, 0xc3, 0xb8, 0xbe,
- 0x8f, 0xe4, 0x5d, 0x24, 0xfa, 0xc1, 0x76, 0xef, 0xba, 0xe4, 0x00, 0x3f,
- 0x7a, 0xce, 0xdd, 0x63, 0xcb, 0x7a, 0x2c, 0xef, 0x31, 0x63, 0x25, 0x49,
- 0x99, 0x7b, 0xcc, 0x14, 0xc6, 0xa6, 0x26, 0x5f, 0x6e, 0x8f, 0xe7, 0x58,
- 0xea, 0xc4, 0x28, 0xf8, 0xfb, 0xad, 0xd2, 0xf8, 0x22, 0xf9, 0xdc, 0xbf,
- 0xeb, 0x1a, 0x32, 0x77, 0x5f, 0xec, 0x13, 0x37, 0xed, 0x49, 0xd3, 0xee,
- 0x2a, 0x3d, 0x19, 0x6c, 0xc7, 0x5b, 0x78, 0x2f, 0x96, 0x38, 0xcf, 0xe4,
- 0x11, 0x7d, 0x47, 0x46, 0x5f, 0x0a, 0xbe, 0xc5, 0x93, 0xb0, 0x31, 0xeb,
- 0x2c, 0x7b, 0xa4, 0x5c, 0x3f, 0x25, 0xb3, 0xea, 0xf9, 0x43, 0xf2, 0xa8,
- 0x43, 0xdc, 0x9d, 0x91, 0xf4, 0x84, 0xb6, 0xc7, 0xc4, 0xd6, 0xb8, 0xed,
- 0x76, 0xcf, 0xc8, 0xd1, 0xb4, 0xd2, 0x21, 0xce, 0x23, 0xc0, 0x71, 0xb1,
- 0xd9, 0x45, 0x7a, 0x07, 0xec, 0x1e, 0x78, 0x2c, 0x2b, 0x17, 0x37, 0xd1,
- 0x17, 0x67, 0xf5, 0x08, 0xdf, 0xeb, 0xc0, 0x27, 0x63, 0x16, 0x4f, 0x11,
- 0x9f, 0xdc, 0x3b, 0x75, 0x28, 0x71, 0x4a, 0x1c, 0x50, 0x2f, 0x33, 0xe6,
- 0x96, 0x98, 0xbc, 0x2d, 0xf4, 0x9b, 0x89, 0x33, 0xce, 0xe3, 0xef, 0x5b,
- 0x8f, 0xb3, 0x37, 0x06, 0x85, 0xe6, 0x98, 0x7d, 0xc1, 0x11, 0xfb, 0x12,
- 0xcb, 0x08, 0x4a, 0xb6, 0x01, 0xa4, 0x8d, 0xa4, 0x69, 0x73, 0x51, 0x07,
- 0x3b, 0xf2, 0x09, 0xf2, 0x96, 0xce, 0xff, 0x4b, 0x8e, 0x4c, 0xca, 0x95,
- 0xb5, 0xbb, 0xf9, 0x2b, 0x70, 0x41, 0xdb, 0x25, 0x77, 0xf2, 0xd7, 0xe4,
- 0x3f, 0x80, 0xbf, 0xb8, 0xc6, 0x19, 0x95, 0xbb, 0xf0, 0xa9, 0x68, 0x22,
- 0x9e, 0xd5, 0xfe, 0x85, 0x93, 0xb2, 0x47, 0xe2, 0xb4, 0x47, 0x1b, 0x4f,
- 0x8e, 0xe3, 0xdc, 0x5b, 0xf2, 0x44, 0xda, 0xa7, 0x2f, 0xe6, 0xf8, 0xb5,
- 0xa4, 0x06, 0xfd, 0x5c, 0x76, 0x2d, 0x59, 0x70, 0xcf, 0x28, 0x7b, 0xf2,
- 0xc3, 0xd1, 0x96, 0x9c, 0x4e, 0xeb, 0xb1, 0x0b, 0x32, 0x62, 0x68, 0x5c,
- 0xf9, 0x6b, 0x90, 0xbf, 0x3c, 0x2f, 0xbe, 0xdf, 0x23, 0xe9, 0x81, 0x33,
- 0x92, 0x9c, 0xd8, 0x22, 0xbe, 0x70, 0x0e, 0x94, 0x3b, 0xbf, 0x36, 0x16,
- 0xa6, 0x72, 0x9e, 0xf2, 0x15, 0xc2, 0xb4, 0x0f, 0x74, 0x9b, 0x85, 0xbf,
- 0xb4, 0x13, 0x0f, 0x4b, 0x8d, 0x94, 0x5a, 0x21, 0xac, 0x5d, 0x84, 0x3f,
- 0xf1, 0xe1, 0xa8, 0x1b, 0x1f, 0xb6, 0x47, 0x62, 0x67, 0xa5, 0xa6, 0x60,
- 0xfd, 0x44, 0x5a, 0xd3, 0xcb, 0x62, 0x66, 0xaf, 0x18, 0x55, 0x67, 0x8c,
- 0x9a, 0x73, 0x6d, 0x59, 0x9f, 0x6c, 0xea, 0x78, 0xd4, 0x4e, 0x9c, 0x7a,
- 0x47, 0xe6, 0x04, 0x8d, 0x2c, 0x28, 0xd7, 0xde, 0x25, 0xbe, 0xcc, 0xa9,
- 0x65, 0x70, 0x56, 0xcb, 0x3c, 0xa3, 0xb8, 0xb9, 0x47, 0x0a, 0x77, 0xd8,
- 0xca, 0x21, 0xe6, 0xfd, 0xc5, 0xb3, 0xf6, 0x32, 0x64, 0xc3, 0x93, 0x12,
- 0x72, 0xfd, 0xb9, 0x98, 0xd3, 0x19, 0x33, 0xf7, 0x11, 0xfb, 0x19, 0xb7,
- 0x42, 0x9f, 0x07, 0xd1, 0x7e, 0x3f, 0xfa, 0x51, 0x57, 0xf2, 0x1e, 0x80,
- 0x7a, 0x93, 0xb1, 0xf6, 0x01, 0xf4, 0xeb, 0x91, 0x7c, 0x7d, 0xbf, 0xa9,
- 0xf3, 0xe7, 0x38, 0xdc, 0xd1, 0xdf, 0xaf, 0xd3, 0xf7, 0x07, 0x59, 0x1b,
- 0x32, 0x7e, 0x99, 0x7d, 0xe3, 0xed, 0x3b, 0x10, 0xbb, 0xf1, 0xa0, 0xa3,
- 0xc7, 0xb3, 0x1f, 0x65, 0x3e, 0x74, 0x4b, 0x15, 0xfa, 0xa6, 0x3a, 0xc5,
- 0xbb, 0x40, 0x63, 0x57, 0xcc, 0x9a, 0x7c, 0x16, 0xda, 0x17, 0xaf, 0x19,
- 0x7d, 0xbb, 0x93, 0x8b, 0x7a, 0x24, 0xe3, 0xe7, 0xf5, 0x30, 0x17, 0x91,
- 0xeb, 0xf2, 0x3c, 0x40, 0x53, 0x9b, 0xda, 0x96, 0xb6, 0x33, 0x5d, 0xbc,
- 0x6b, 0x83, 0x7e, 0xd7, 0xfa, 0xbf, 0x01, 0xfd, 0xbf, 0xb1, 0x02, 0x9d,
- 0xdf, 0x47, 0xdd, 0xaf, 0xf3, 0x4f, 0xec, 0x76, 0xbe, 0x8f, 0x7f, 0x8f,
- 0xbc, 0xa5, 0xee, 0xf1, 0x7a, 0x3c, 0xca, 0xf4, 0x8c, 0xfc, 0x39, 0x6c,
- 0xad, 0x67, 0x36, 0x27, 0xb1, 0x5e, 0x1a, 0x7e, 0xdd, 0x38, 0xfc, 0xba,
- 0x51, 0xf8, 0x75, 0x2e, 0x74, 0xe1, 0x90, 0xca, 0x27, 0xa3, 0xde, 0x9f,
- 0x38, 0x24, 0xd6, 0xd7, 0x32, 0x62, 0x1d, 0xbc, 0x00, 0x1b, 0x61, 0xe9,
- 0x25, 0xd0, 0x7f, 0xe2, 0x79, 0x11, 0xf2, 0x04, 0xf9, 0xef, 0x31, 0xc9,
- 0xc6, 0x86, 0xe4, 0xf3, 0x9b, 0x6c, 0x23, 0x3d, 0x65, 0xe5, 0x15, 0xf7,
- 0x25, 0xc5, 0x67, 0x17, 0x6b, 0xd7, 0x25, 0xf4, 0x84, 0x96, 0xb5, 0x3f,
- 0x80, 0x3d, 0xd5, 0x48, 0x6b, 0xda, 0xbb, 0x2d, 0xa4, 0x3d, 0xe8, 0xa7,
- 0x35, 0xca, 0xd8, 0x9b, 0x12, 0xbd, 0xf0, 0x92, 0xbc, 0xf9, 0x82, 0xab,
- 0xe2, 0x12, 0x6b, 0x4f, 0x2a, 0xdd, 0x07, 0xb9, 0x16, 0x95, 0xf5, 0xcd,
- 0xdf, 0x91, 0x4f, 0x39, 0x89, 0x2b, 0x94, 0x99, 0x94, 0x5d, 0x5a, 0xa7,
- 0x41, 0xc6, 0x56, 0x12, 0xa5, 0x32, 0x6c, 0xef, 0x2b, 0xf6, 0x98, 0x64,
- 0x83, 0xa5, 0x56, 0x3f, 0xfd, 0x82, 0x9a, 0xeb, 0x24, 0x6d, 0x9e, 0xef,
- 0xbd, 0xb0, 0xad, 0x13, 0x75, 0x25, 0xa3, 0xa8, 0x27, 0x33, 0xd4, 0x9b,
- 0xd4, 0x7d, 0xd4, 0x3f, 0x8c, 0x97, 0xe3, 0x79, 0x8d, 0xba, 0xe9, 0xef,
- 0xd4, 0x9d, 0x67, 0x71, 0xc6, 0x91, 0xfa, 0x1a, 0xe5, 0x13, 0xf4, 0xfc,
- 0x93, 0xb4, 0x73, 0x45, 0xd1, 0x3f, 0xed, 0xdc, 0x47, 0xc5, 0xb7, 0x71,
- 0xd9, 0xb6, 0xdb, 0xc6, 0xfd, 0x83, 0x7d, 0xd2, 0x1b, 0x05, 0x7e, 0xc8,
- 0xff, 0x3b, 0x36, 0x60, 0x2e, 0x73, 0x13, 0xb6, 0x26, 0xf7, 0x61, 0xc9,
- 0xa0, 0x7b, 0x1d, 0x74, 0xc4, 0xb5, 0x6f, 0xb6, 0x3e, 0x1c, 0xe5, 0x1e,
- 0x2c, 0x65, 0x23, 0x6c, 0x0f, 0xfe, 0xa6, 0x3b, 0x0a, 0xca, 0x88, 0x7d,
- 0xb0, 0xcd, 0x6d, 0x43, 0xb3, 0x9f, 0x34, 0xbe, 0x04, 0xf8, 0x79, 0x95,
- 0x7b, 0x28, 0xf3, 0x4e, 0x04, 0x36, 0xd7, 0x22, 0x63, 0x52, 0x6a, 0xdd,
- 0xf7, 0x67, 0x22, 0x92, 0xbc, 0xd0, 0x25, 0xa9, 0xa7, 0xec, 0x41, 0x9d,
- 0xb7, 0xf8, 0x30, 0x74, 0xcf, 0x41, 0xb4, 0x1f, 0x90, 0xb2, 0x13, 0x85,
- 0x3f, 0x33, 0x2a, 0xe5, 0xd1, 0x30, 0x78, 0xe6, 0x01, 0xde, 0x75, 0x28,
- 0x38, 0xca, 0xce, 0x30, 0xca, 0x6e, 0x94, 0xf7, 0x48, 0xf9, 0xc9, 0x4b,
- 0xfb, 0xb4, 0x2d, 0xbb, 0xfb, 0xfd, 0x9f, 0x76, 0xab, 0xd8, 0xb9, 0xf5,
- 0x8e, 0x88, 0xb9, 0x47, 0xff, 0x2d, 0x60, 0xf7, 0xfb, 0x12, 0x9e, 0x90,
- 0xb8, 0x4f, 0x44, 0x64, 0x18, 0xb2, 0x77, 0x04, 0x7a, 0xeb, 0xe0, 0x85,
- 0x21, 0x19, 0xbd, 0x10, 0x97, 0xfb, 0x2e, 0xf8, 0xf6, 0xc0, 0xf2, 0x74,
- 0xca, 0xc4, 0x71, 0xdd, 0xdf, 0x32, 0x8e, 0x7b, 0x9f, 0x9a, 0x1f, 0x30,
- 0xae, 0x41, 0x1e, 0x46, 0x3f, 0xa7, 0xec, 0x06, 0x8d, 0xfb, 0x1f, 0xc9,
- 0x91, 0x95, 0x90, 0x1c, 0x55, 0xbc, 0xe8, 0xdb, 0xf0, 0xff, 0x13, 0xfb,
- 0x48, 0x80, 0x47, 0x4e, 0x18, 0xbf, 0xb3, 0x17, 0x78, 0x25, 0x0e, 0xa1,
- 0xeb, 0xe0, 0x8b, 0x32, 0x3f, 0xb5, 0x98, 0xee, 0x1c, 0xcf, 0xb1, 0x3f,
- 0xc5, 0x98, 0x2c, 0x6c, 0x0b, 0xb6, 0xcb, 0x60, 0x40, 0xf6, 0x6a, 0x7f,
- 0x1f, 0xda, 0x29, 0x73, 0x8e, 0x42, 0xe6, 0xec, 0x6e, 0xcf, 0xa1, 0x8d,
- 0xeb, 0xdf, 0x83, 0x75, 0xc9, 0x8f, 0x5c, 0xd7, 0xc7, 0x09, 0xcf, 0x75,
- 0x10, 0xfe, 0x07, 0xcf, 0xb5, 0x4b, 0x0a, 0x0e, 0x73, 0x37, 0x59, 0xf7,
- 0x16, 0x73, 0xd6, 0x13, 0xe6, 0xac, 0x05, 0xb6, 0x31, 0xed, 0x2d, 0x9d,
- 0xaf, 0x50, 0x88, 0x26, 0x4a, 0x22, 0x71, 0x15, 0xbf, 0x5b, 0xaf, 0xf8,
- 0xf6, 0x49, 0xb6, 0x9f, 0xf7, 0x10, 0x8b, 0x69, 0x15, 0x5b, 0x8b, 0x07,
- 0x3c, 0xda, 0x37, 0xe9, 0x30, 0xf3, 0x92, 0x1b, 0x2b, 0xbc, 0x93, 0x0c,
- 0xe0, 0x07, 0x3c, 0x07, 0x2d, 0x71, 0x5c, 0xd6, 0x95, 0xb4, 0x6e, 0x9b,
- 0x01, 0xff, 0xda, 0xaa, 0x4f, 0x3c, 0x97, 0x1e, 0x34, 0xef, 0x31, 0x59,
- 0xab, 0xbc, 0x63, 0xc8, 0xf6, 0xfe, 0xf6, 0x9e, 0x5c, 0xa6, 0x9f, 0xf7,
- 0x49, 0xa8, 0x23, 0x9f, 0xbc, 0xa4, 0x72, 0x15, 0xb5, 0xef, 0x10, 0xe4,
- 0x3d, 0x24, 0xf6, 0xf9, 0x53, 0xd0, 0xf5, 0xee, 0x3d, 0x77, 0x99, 0x3d,
- 0x73, 0xbf, 0xc4, 0x37, 0xc7, 0xfb, 0x7a, 0x8e, 0x38, 0x0f, 0x77, 0xf8,
- 0x1b, 0x91, 0x81, 0x9d, 0xfb, 0x73, 0xca, 0x42, 0xca, 0xbf, 0x49, 0x95,
- 0xef, 0x72, 0xcb, 0x86, 0x1c, 0xaa, 0x42, 0x2e, 0x55, 0x21, 0x8b, 0xaa,
- 0x90, 0x45, 0xb0, 0x41, 0x9e, 0x85, 0x5c, 0x7d, 0x06, 0xbe, 0xda, 0xd7,
- 0xab, 0xbe, 0xfd, 0x9e, 0x85, 0x1c, 0x53, 0x36, 0x1d, 0xed, 0x9f, 0x9a,
- 0xed, 0x75, 0xff, 0xd6, 0xf9, 0x50, 0x01, 0xcf, 0x1f, 0xd7, 0x2d, 0x45,
- 0x35, 0x26, 0x2e, 0xf3, 0xcd, 0xbd, 0xfa, 0x72, 0x7f, 0xa1, 0x8e, 0xfd,
- 0x9a, 0xbb, 0x7e, 0x15, 0x8b, 0xa0, 0x0c, 0xfe, 0x4d, 0x3c, 0xd0, 0x99,
- 0xa7, 0xc9, 0x33, 0x56, 0x39, 0x42, 0x38, 0x53, 0xe2, 0x9d, 0x76, 0x61,
- 0x59, 0x16, 0x26, 0x17, 0xa5, 0x3c, 0x69, 0xc9, 0xdc, 0x38, 0xce, 0x68,
- 0x7c, 0x18, 0x3a, 0x32, 0x0d, 0x5d, 0xbb, 0x80, 0x79, 0xc8, 0x7f, 0x0f,
- 0xe2, 0x5c, 0x1c, 0x73, 0x27, 0xfe, 0xa5, 0xe9, 0x5c, 0x4d, 0xac, 0x6b,
- 0x2a, 0x47, 0x7c, 0x79, 0xfa, 0xd5, 0x95, 0x87, 0x61, 0x3f, 0x4d, 0xc8,
- 0xd5, 0xc9, 0x87, 0x65, 0xfb, 0x8e, 0xf1, 0x38, 0x07, 0xc8, 0xe1, 0xcf,
- 0x6f, 0xf2, 0x1e, 0xb4, 0x4b, 0x66, 0xa3, 0x8c, 0x81, 0xc1, 0xc6, 0x71,
- 0xfb, 0x65, 0x5b, 0xf9, 0xa1, 0x07, 0xe4, 0xb6, 0xa2, 0x2d, 0xd6, 0x85,
- 0x50, 0xa7, 0xed, 0xd1, 0xb5, 0x8a, 0x6f, 0x5b, 0x28, 0x1c, 0x99, 0x98,
- 0x1f, 0xf5, 0x0d, 0xe3, 0x49, 0x8c, 0x2f, 0xad, 0x45, 0x76, 0x64, 0x01,
- 0x4b, 0xff, 0x5c, 0x3b, 0xfd, 0xe3, 0xbf, 0x8e, 0xe8, 0x6f, 0x0b, 0xba,
- 0xa4, 0x1c, 0x2d, 0xb5, 0xca, 0x6e, 0xd0, 0xba, 0xda, 0xce, 0x69, 0xf5,
- 0xdb, 0x48, 0xcb, 0x36, 0x60, 0x25, 0x1d, 0x24, 0x55, 0xee, 0xce, 0x77,
- 0xaa, 0x03, 0xfb, 0xf4, 0x37, 0x0a, 0x01, 0x8c, 0xe3, 0xfb, 0x89, 0x88,
- 0x7e, 0xf7, 0xef, 0xdd, 0xdf, 0x86, 0xbe, 0x31, 0x25, 0xaf, 0xd6, 0x6a,
- 0x01, 0xf0, 0xf0, 0x20, 0x9e, 0x5f, 0x44, 0x9f, 0x30, 0xce, 0x86, 0xb1,
- 0xa4, 0xb7, 0xa8, 0xfc, 0x9b, 0x80, 0xeb, 0xe7, 0xf5, 0x52, 0x77, 0xff,
- 0x67, 0xd5, 0xfe, 0xf4, 0x4a, 0x37, 0xf3, 0x55, 0x51, 0x52, 0xaf, 0xff,
- 0x0a, 0xbe, 0x56, 0x48, 0xf2, 0x35, 0x17, 0xb6, 0x78, 0x88, 0xf4, 0x8b,
- 0xfa, 0x7b, 0xa1, 0xa3, 0x04, 0xfc, 0xd4, 0x05, 0xbd, 0xa9, 0x70, 0x0d,
- 0x4a, 0xa2, 0x4f, 0xef, 0xe7, 0x99, 0x6a, 0x38, 0x42, 0xde, 0xf7, 0x98,
- 0x6f, 0x10, 0x0e, 0x78, 0x2f, 0x4d, 0xcf, 0x55, 0x68, 0x2b, 0xb5, 0x5a,
- 0xd0, 0x65, 0xd8, 0xc9, 0xcf, 0x94, 0x5f, 0xb1, 0x2d, 0xda, 0x57, 0x5b,
- 0x50, 0xf9, 0x96, 0x37, 0xa7, 0x35, 0x8d, 0x74, 0xde, 0x9f, 0xbc, 0xd1,
- 0xdd, 0x49, 0x58, 0xb6, 0xd3, 0x3d, 0x86, 0x2f, 0xc2, 0xc1, 0x62, 0x25,
- 0x12, 0x9c, 0x53, 0xf7, 0x5b, 0x5b, 0x26, 0x1f, 0xf3, 0xda, 0x74, 0xaa,
- 0x19, 0x56, 0xb9, 0x00, 0xbc, 0x4b, 0xc8, 0x57, 0x78, 0x97, 0xa2, 0xdb,
- 0x53, 0xa6, 0x3d, 0xd9, 0x54, 0x6d, 0x2a, 0xde, 0xc5, 0x18, 0x57, 0x37,
- 0xca, 0xdb, 0x15, 0xca, 0x07, 0xcc, 0xaf, 0x65, 0x09, 0x60, 0x7f, 0x71,
- 0x7a, 0x6e, 0x85, 0xf0, 0x7d, 0x7f, 0x3a, 0xb7, 0xc2, 0x1c, 0xc8, 0xff,
- 0x34, 0x7d, 0x63, 0xc5, 0x92, 0x0d, 0x37, 0xa1, 0xe2, 0x57, 0xeb, 0x8c,
- 0xb1, 0x72, 0x9c, 0x9a, 0xf3, 0x45, 0x23, 0x93, 0xbf, 0x37, 0x3d, 0xbc,
- 0x1e, 0x90, 0x73, 0x66, 0x0e, 0xbe, 0xc7, 0xd7, 0xef, 0xa0, 0x6b, 0xd0,
- 0xca, 0x15, 0xd0, 0x4a, 0x2f, 0x6c, 0x09, 0xd2, 0x37, 0x7d, 0xb2, 0x5e,
- 0xc8, 0x01, 0xae, 0xf3, 0x8c, 0x5a, 0x27, 0x80, 0x75, 0xe6, 0x54, 0xce,
- 0x78, 0x80, 0x79, 0xb7, 0xb0, 0x35, 0x61, 0x13, 0xba, 0x8c, 0x59, 0xdb,
- 0xd8, 0xf3, 0x28, 0xf4, 0x12, 0xf3, 0x3f, 0xfe, 0x7b, 0x64, 0x27, 0x6f,
- 0xfc, 0x39, 0x33, 0xee, 0x9b, 0x18, 0xc7, 0x33, 0x51, 0xf9, 0xe6, 0x6f,
- 0xb6, 0x65, 0x58, 0xd9, 0x90, 0x3a, 0x07, 0x89, 0x30, 0xd4, 0xb1, 0x57,
- 0xea, 0xe2, 0x2e, 0xc9, 0xab, 0x7d, 0x7d, 0x53, 0x8d, 0xb3, 0xbc, 0x6f,
- 0x00, 0x76, 0xda, 0x25, 0x98, 0xbb, 0xaa, 0xe3, 0x6d, 0x79, 0xc5, 0xd3,
- 0xe0, 0x91, 0x49, 0x3f, 0x57, 0x4f, 0x8f, 0xf3, 0xfb, 0x27, 0xd7, 0x8f,
- 0x98, 0x9c, 0x8e, 0xbf, 0x6f, 0x65, 0x8f, 0xf7, 0x2a, 0x1b, 0x6c, 0xe7,
- 0x9b, 0x08, 0x7f, 0x8c, 0xdf, 0xc7, 0xcf, 0x31, 0x7e, 0x74, 0xff, 0x0e,
- 0xcc, 0x5b, 0xe6, 0xcc, 0x39, 0x8e, 0xb1, 0x49, 0x95, 0xaf, 0xcb, 0xba,
- 0xe0, 0x7c, 0x86, 0x73, 0x74, 0xde, 0xf7, 0x8c, 0x83, 0x47, 0xb5, 0xcd,
- 0x57, 0x82, 0x9d, 0x55, 0x06, 0xbf, 0x04, 0x3c, 0xca, 0xf1, 0x61, 0x13,
- 0x57, 0x7b, 0xa3, 0x38, 0x1f, 0xef, 0x12, 0xc7, 0x21, 0x7b, 0xfc, 0xf1,
- 0x3c, 0xc7, 0x6b, 0xd3, 0x37, 0x2a, 0xae, 0x9c, 0xad, 0xea, 0x7c, 0x47,
- 0x8d, 0x07, 0xc6, 0x6e, 0x78, 0xb6, 0x71, 0x99, 0x73, 0xa9, 0x67, 0xe3,
- 0xf2, 0x5d, 0xd7, 0x8f, 0xad, 0xf1, 0x7e, 0x0a, 0xfd, 0x61, 0xeb, 0x2d,
- 0x6c, 0x72, 0xff, 0xdf, 0xc4, 0xfe, 0xe9, 0x53, 0x68, 0x5a, 0x3a, 0x08,
- 0xb9, 0xf5, 0x1f, 0x82, 0xf0, 0x19, 0xa0, 0xbb, 0x6f, 0x05, 0x3b, 0xf7,
- 0xe7, 0xeb, 0x6b, 0x4d, 0x97, 0x41, 0xd0, 0xc8, 0x62, 0x1b, 0xef, 0x96,
- 0x04, 0xde, 0x39, 0x02, 0x1d, 0x64, 0x49, 0x61, 0xdc, 0x8d, 0x2d, 0xf0,
- 0x6e, 0xc1, 0x19, 0x73, 0x1c, 0x95, 0xc7, 0x16, 0x07, 0xbc, 0x7c, 0xe6,
- 0xb7, 0x02, 0xcc, 0x39, 0x8b, 0xab, 0x5c, 0xdd, 0x6c, 0xd4, 0x05, 0xbc,
- 0x8e, 0xb2, 0x4f, 0xb4, 0x5e, 0xfe, 0x97, 0xfb, 0x29, 0x6b, 0xfa, 0x5d,
- 0xff, 0xec, 0x39, 0xf7, 0x8b, 0x98, 0x3b, 0x60, 0xda, 0x7d, 0x1a, 0x09,
- 0x30, 0xe5, 0x4d, 0x76, 0xbe, 0x01, 0xf1, 0xe3, 0x7c, 0xec, 0xff, 0x2d,
- 0x05, 0xcb, 0x1c, 0xf4, 0xd0, 0xbc, 0xda, 0xcf, 0x0b, 0xa0, 0x05, 0xca,
- 0x15, 0x9f, 0x7e, 0x5f, 0x00, 0xfd, 0xee, 0x63, 0x0a, 0xdf, 0x1e, 0xb4,
- 0xe6, 0xd3, 0x18, 0xe9, 0x8b, 0xb4, 0xf5, 0x8a, 0xe2, 0xb9, 0x52, 0xfb,
- 0xdc, 0x29, 0xb3, 0x12, 0x4e, 0xdc, 0xf6, 0xcf, 0x9d, 0xcf, 0x7b, 0xe5,
- 0xb8, 0xfa, 0xfc, 0x91, 0xf9, 0x07, 0x9c, 0x6d, 0xda, 0x9c, 0x6d, 0xa6,
- 0xe3, 0x9b, 0x04, 0x7f, 0x3e, 0xfa, 0xfb, 0xd4, 0xaf, 0xbc, 0x0b, 0xe2,
- 0xf7, 0x12, 0xca, 0x44, 0x90, 0x72, 0x9a, 0x7c, 0x94, 0x8b, 0xf3, 0x3e,
- 0xe5, 0xa4, 0x04, 0xfa, 0x60, 0xb7, 0x8c, 0x86, 0xc4, 0xff, 0x2e, 0xa9,
- 0x4b, 0xb6, 0x9c, 0x56, 0xeb, 0x06, 0xef, 0x8d, 0x2b, 0x41, 0xd9, 0x50,
- 0x77, 0x9f, 0xe0, 0xd1, 0xde, 0xa0, 0x2c, 0xba, 0x6d, 0x3d, 0x27, 0x75,
- 0xf4, 0x59, 0x43, 0xdb, 0xb9, 0x36, 0x6c, 0xd4, 0x07, 0xb0, 0x21, 0xdd,
- 0xbf, 0x6f, 0x15, 0xa3, 0x77, 0xf4, 0x35, 0x32, 0x96, 0xb1, 0x47, 0xc6,
- 0xa7, 0x1d, 0xc9, 0xaf, 0x0f, 0xe0, 0x07, 0x19, 0xaf, 0xe4, 0x02, 0x63,
- 0x91, 0x8c, 0xe7, 0x96, 0xe0, 0x9f, 0x6a, 0x3f, 0x9f, 0xf6, 0xf6, 0x95,
- 0xcd, 0x44, 0xa9, 0x24, 0x6e, 0xfc, 0x91, 0xf6, 0x77, 0x3c, 0x7d, 0xa5,
- 0xb0, 0xd7, 0x19, 0xf3, 0x8d, 0xab, 0xfc, 0xd9, 0x1e, 0x2f, 0x11, 0x3b,
- 0x05, 0xdf, 0xf5, 0xeb, 0x69, 0xc6, 0x7a, 0xef, 0x23, 0xbe, 0xbf, 0xc4,
- 0x4d, 0xda, 0x23, 0xe3, 0xe2, 0x5e, 0x72, 0x47, 0x1f, 0x11, 0xfa, 0xa7,
- 0x89, 0xf8, 0x14, 0xf1, 0xd6, 0xfe, 0xbe, 0x20, 0x68, 0xec, 0xa5, 0x71,
- 0x19, 0xbe, 0xf4, 0x23, 0x15, 0x63, 0xff, 0x70, 0x7a, 0x37, 0x6d, 0xa8,
- 0x58, 0xf1, 0x78, 0xbf, 0x0c, 0x8f, 0xae, 0x89, 0x40, 0x5b, 0xf0, 0x7b,
- 0x03, 0x0b, 0x3e, 0xaa, 0x7a, 0x87, 0xbd, 0x1e, 0x57, 0xdf, 0x5c, 0x65,
- 0x55, 0xde, 0x23, 0x63, 0xc9, 0x3c, 0xd3, 0x88, 0xca, 0x85, 0x7b, 0x16,
- 0x67, 0x5b, 0x68, 0xf2, 0x7c, 0x19, 0x57, 0x66, 0xdc, 0x98, 0xb1, 0x65,
- 0xc6, 0x88, 0xf5, 0xf7, 0x53, 0x47, 0x9a, 0x7b, 0xc5, 0x91, 0x89, 0x8b,
- 0x51, 0xf3, 0x4d, 0x9a, 0x58, 0xdb, 0xd0, 0xbb, 0xf9, 0x9a, 0xa3, 0xee,
- 0xfd, 0x8a, 0x4e, 0xbf, 0x9c, 0x1c, 0xed, 0x06, 0xce, 0x07, 0x54, 0x3e,
- 0xa4, 0xed, 0xbe, 0x07, 0x7e, 0x25, 0xfd, 0x38, 0xea, 0x5b, 0x1f, 0xcf,
- 0x87, 0x50, 0xf7, 0x0b, 0xe0, 0x9e, 0x75, 0xf0, 0x39, 0x95, 0xee, 0xfd,
- 0xb4, 0x6c, 0x57, 0x98, 0x9f, 0x5d, 0x3f, 0x90, 0x53, 0xe7, 0xc1, 0x98,
- 0x8d, 0x2f, 0x9b, 0xfc, 0x5c, 0x35, 0xfa, 0xcc, 0x8e, 0xb9, 0xab, 0x66,
- 0xcc, 0x66, 0x40, 0x8a, 0xeb, 0x94, 0x3f, 0x96, 0x5a, 0xeb, 0x56, 0xe0,
- 0xad, 0x52, 0xaa, 0xef, 0x75, 0xef, 0xde, 0x6a, 0x3d, 0x93, 0x56, 0xbe,
- 0xec, 0xf9, 0x92, 0x39, 0x63, 0xfd, 0x1d, 0x64, 0x70, 0x27, 0x7f, 0x38,
- 0xaa, 0xe3, 0x09, 0xd9, 0x81, 0x5e, 0xfa, 0x0f, 0x7d, 0x1a, 0xbf, 0xf4,
- 0x7b, 0x7f, 0x65, 0x6c, 0x51, 0xfa, 0xbc, 0x03, 0x4a, 0x4f, 0xdb, 0x0d,
- 0x9f, 0x4e, 0x98, 0x73, 0x43, 0x7f, 0xf8, 0xa0, 0x64, 0xeb, 0x90, 0x9b,
- 0x83, 0x7c, 0x3f, 0x6b, 0xc6, 0xf2, 0xb9, 0x25, 0x47, 0x27, 0x76, 0xdf,
- 0xa7, 0x4f, 0x6a, 0x3f, 0xbb, 0xd7, 0xbf, 0x53, 0xf7, 0x73, 0x4d, 0x7d,
- 0x78, 0x15, 0x9c, 0xa0, 0x27, 0x1f, 0x06, 0xbd, 0xd6, 0x11, 0xc0, 0xcb,
- 0x18, 0xe4, 0x80, 0xcb, 0x5c, 0x9d, 0x80, 0x4c, 0x0c, 0x24, 0x98, 0xc3,
- 0xa7, 0xe0, 0x69, 0xd4, 0x43, 0x68, 0xf3, 0xe1, 0xd4, 0xfe, 0x79, 0xa3,
- 0xce, 0xf6, 0x38, 0xd6, 0xea, 0x96, 0x89, 0x41, 0xe2, 0x79, 0x37, 0x1c,
- 0x03, 0x81, 0xbd, 0x73, 0xd4, 0x1e, 0xec, 0x80, 0xef, 0xee, 0xef, 0x47,
- 0x73, 0xf0, 0xc3, 0x72, 0x2b, 0x8c, 0x15, 0x10, 0xc6, 0x01, 0xc8, 0x39,
- 0xec, 0x31, 0xed, 0xe7, 0x0e, 0xfb, 0x78, 0xf1, 0x63, 0x0c, 0x21, 0x45,
- 0x17, 0x73, 0x19, 0xee, 0x25, 0x64, 0x62, 0x0e, 0x84, 0x2b, 0x61, 0xf2,
- 0x0f, 0x09, 0x9f, 0x7d, 0x40, 0x9f, 0xff, 0xfd, 0x66, 0xbf, 0x7e, 0xce,
- 0x22, 0xe7, 0xba, 0x17, 0xe3, 0xbf, 0xd2, 0xc2, 0x5a, 0x34, 0xe8, 0xc0,
- 0xff, 0xbe, 0xaf, 0x7f, 0xaf, 0x9e, 0xab, 0xd7, 0xff, 0xa6, 0x2f, 0x66,
- 0xbe, 0xe3, 0x23, 0x9c, 0xe4, 0x2f, 0x1f, 0x87, 0x9c, 0x63, 0xc0, 0xdc,
- 0x23, 0x10, 0x86, 0x9e, 0x5d, 0x30, 0x24, 0xd2, 0x77, 0xca, 0xb8, 0x43,
- 0x1d, 0x7b, 0x27, 0xad, 0xf5, 0xc9, 0x42, 0xad, 0x57, 0xca, 0x35, 0xe6,
- 0x53, 0xf3, 0xfb, 0x32, 0xda, 0x59, 0xe4, 0x4b, 0x95, 0x37, 0x69, 0xf2,
- 0x15, 0x7d, 0xfe, 0xec, 0x43, 0x3f, 0xea, 0x10, 0x94, 0x75, 0x2d, 0x9f,
- 0xea, 0x72, 0x77, 0xce, 0xe2, 0x7c, 0x3b, 0x67, 0x51, 0xe7, 0x25, 0x15,
- 0xdb, 0x79, 0x22, 0xcc, 0x89, 0xeb, 0xcc, 0x41, 0x2a, 0xc9, 0xa3, 0x87,
- 0x7b, 0x24, 0xb9, 0xdc, 0x6b, 0x68, 0xf4, 0x3d, 0x66, 0x1d, 0xac, 0xb7,
- 0x34, 0x29, 0xc9, 0xa5, 0x3f, 0x86, 0x6f, 0xaf, 0xf2, 0x22, 0x3b, 0xf2,
- 0xdb, 0x87, 0xcd, 0xb7, 0x48, 0x59, 0x8b, 0xf9, 0x28, 0xf9, 0x25, 0x9c,
- 0xd7, 0xe1, 0xc4, 0x68, 0xdc, 0xe6, 0xb7, 0xb8, 0x27, 0x24, 0xb9, 0x3a,
- 0xa9, 0xbf, 0x89, 0x4b, 0xf3, 0x46, 0x3e, 0xa1, 0xec, 0xe9, 0xd4, 0x65,
- 0x3d, 0x9f, 0xbb, 0xc4, 0xf6, 0x14, 0x6c, 0x47, 0xb6, 0xe7, 0x63, 0x01,
- 0x75, 0x6b, 0x7f, 0x3f, 0xe8, 0xa9, 0xcb, 0xd8, 0x03, 0xcc, 0xe9, 0xe4,
- 0x78, 0xda, 0x1e, 0xa7, 0x71, 0x66, 0xf9, 0xb8, 0x2d, 0x1c, 0xa3, 0xe6,
- 0xc3, 0xb3, 0x7f, 0x47, 0x44, 0x5c, 0x8f, 0xcb, 0x7a, 0xd3, 0x05, 0x4f,
- 0xe8, 0x9c, 0xf8, 0x62, 0xdd, 0xcf, 0xe5, 0x7c, 0xb4, 0x9d, 0xcb, 0x49,
- 0x18, 0x0b, 0x95, 0xdd, 0xb4, 0x77, 0xc8, 0xe4, 0x54, 0xf6, 0xa8, 0xfb,
- 0xd9, 0x0e, 0xf9, 0x67, 0xfa, 0x3f, 0x73, 0x80, 0x77, 0xf7, 0x22, 0x6c,
- 0x1f, 0x34, 0xed, 0xb0, 0x8f, 0xa2, 0x51, 0xc5, 0x07, 0xc9, 0x86, 0xdf,
- 0xef, 0xfa, 0x01, 0x9d, 0x0b, 0x4a, 0x3c, 0x79, 0x06, 0xe6, 0x09, 0xf8,
- 0xb1, 0xac, 0x3b, 0x88, 0xb1, 0x3c, 0x27, 0x94, 0x8d, 0x83, 0x2a, 0xd7,
- 0x30, 0xe0, 0x4d, 0x99, 0x7b, 0xc1, 0x41, 0xb5, 0x96, 0xe3, 0x71, 0x7e,
- 0x5f, 0x36, 0xf4, 0x74, 0xac, 0xbf, 0x1b, 0x5e, 0xc6, 0xe0, 0xfc, 0xdc,
- 0x51, 0xb6, 0xf3, 0x7d, 0x77, 0x1f, 0x3f, 0x4f, 0x34, 0x6b, 0x05, 0xdb,
- 0x39, 0xf6, 0xc4, 0x25, 0xef, 0x96, 0x51, 0x5e, 0xf6, 0x00, 0x23, 0x9f,
- 0x51, 0x9a, 0x6f, 0x07, 0x82, 0x4b, 0xfc, 0xed, 0x9e, 0x27, 0x88, 0xb9,
- 0x7d, 0x9e, 0xdd, 0x3b, 0xa7, 0xb4, 0xcb, 0x3b, 0x6f, 0x6d, 0x57, 0x98,
- 0x27, 0x51, 0x92, 0x93, 0x99, 0x3e, 0x99, 0xab, 0xd9, 0xfc, 0xc6, 0x93,
- 0x31, 0x7a, 0xde, 0x83, 0xcb, 0xbc, 0x92, 0x71, 0x23, 0xc6, 0xe7, 0xee,
- 0x81, 0x6f, 0x4e, 0x7a, 0x1e, 0x91, 0xf5, 0xfa, 0x4c, 0x47, 0xfe, 0x6d,
- 0x97, 0xa1, 0xb3, 0x7f, 0x1d, 0x92, 0xde, 0x12, 0x7c, 0x32, 0x9f, 0xa7,
- 0x47, 0xa4, 0x50, 0xef, 0xbc, 0x3b, 0x63, 0xae, 0x4f, 0xe7, 0x37, 0xb4,
- 0x4a, 0x0f, 0xd6, 0x4a, 0xb4, 0xab, 0xa2, 0x8c, 0x4b, 0xb0, 0xdf, 0x7e,
- 0xa3, 0x6f, 0xe1, 0x08, 0xf5, 0xbe, 0xc5, 0x12, 0x97, 0xb0, 0x41, 0x47,
- 0xa8, 0x75, 0x52, 0x72, 0x34, 0x5a, 0x82, 0x8f, 0x3a, 0x62, 0xd6, 0x7d,
- 0x3b, 0xde, 0xd9, 0xf7, 0x80, 0x69, 0xbf, 0xd7, 0xbc, 0xf7, 0x9a, 0xf7,
- 0x00, 0xde, 0xeb, 0xad, 0x5a, 0x95, 0x73, 0xb2, 0xe4, 0xf7, 0x22, 0xbc,
- 0xdb, 0xf2, 0x24, 0x74, 0x59, 0xa0, 0xa7, 0x7a, 0xe5, 0xf1, 0xba, 0xc2,
- 0xaf, 0xe5, 0x2e, 0xd1, 0x20, 0xd8, 0x6f, 0x9e, 0xef, 0xe6, 0xc1, 0x4f,
- 0xde, 0x91, 0x37, 0x3c, 0xec, 0x98, 0xdc, 0xec, 0x0e, 0x78, 0xb3, 0x80,
- 0xf5, 0xd7, 0xe5, 0x41, 0x51, 0x47, 0x69, 0x5f, 0xb9, 0x50, 0xd1, 0xf9,
- 0x3e, 0x27, 0x2b, 0x80, 0xb5, 0xf6, 0x3f, 0x0e, 0xe8, 0xdc, 0x14, 0x3f,
- 0x9f, 0x91, 0xf9, 0xee, 0x23, 0x26, 0x27, 0x82, 0x63, 0x99, 0x57, 0xe9,
- 0xdf, 0x39, 0x76, 0xda, 0xaa, 0xd4, 0x45, 0xd4, 0x33, 0xfc, 0x6e, 0x25,
- 0x8d, 0xbe, 0x8b, 0x94, 0x35, 0xd0, 0x53, 0xbe, 0x2d, 0xf1, 0x39, 0xe5,
- 0x1f, 0x76, 0x7e, 0xf7, 0x73, 0x0e, 0xb0, 0xfe, 0x65, 0x93, 0x71, 0xe1,
- 0x1e, 0x09, 0x2c, 0xfb, 0x79, 0x50, 0x3c, 0x63, 0xda, 0x61, 0xfc, 0xb6,
- 0xfa, 0x77, 0x77, 0xc5, 0x8c, 0x7d, 0x5b, 0x81, 0x74, 0x3e, 0xe7, 0x30,
- 0xc7, 0xd4, 0xf1, 0xfc, 0x38, 0x33, 0x73, 0x6b, 0x68, 0x73, 0x1d, 0x14,
- 0x5b, 0xc5, 0x8d, 0xd8, 0x56, 0x92, 0xfe, 0xc3, 0xbf, 0x4b, 0xde, 0xf8,
- 0x47, 0xfc, 0x16, 0x46, 0xe7, 0x79, 0xab, 0x75, 0xa2, 0xda, 0x86, 0xe4,
- 0x37, 0xda, 0x69, 0xf0, 0xd5, 0xbe, 0x2d, 0x9d, 0xf3, 0x1d, 0xc1, 0x7b,
- 0x06, 0x74, 0x0c, 0x99, 0x2a, 0xfc, 0x1e, 0x9b, 0x7c, 0xc7, 0xef, 0xb1,
- 0x3d, 0x95, 0x6f, 0xb2, 0x6d, 0xbe, 0x2f, 0xba, 0xde, 0x0c, 0x8a, 0xbd,
- 0x34, 0xce, 0x6f, 0xd5, 0xf8, 0x6d, 0x23, 0x6c, 0xb5, 0x38, 0xda, 0x99,
- 0xc7, 0x36, 0xa4, 0xf2, 0x54, 0xca, 0xcd, 0x8f, 0xa0, 0xfc, 0x34, 0xfc,
- 0x75, 0x1d, 0x9f, 0x2f, 0x37, 0x99, 0xaf, 0xe2, 0xa8, 0x7b, 0xcf, 0xe4,
- 0x52, 0x01, 0xeb, 0xf9, 0xdf, 0x3e, 0x47, 0x51, 0x47, 0xf8, 0x4a, 0x86,
- 0x47, 0xfd, 0x5c, 0x84, 0x0d, 0x87, 0x3a, 0xa1, 0xd4, 0x8c, 0xa8, 0x1c,
- 0x17, 0x6d, 0x8f, 0xd0, 0xd6, 0x0b, 0xa3, 0x2f, 0xf7, 0xda, 0x4b, 0x7d,
- 0xd5, 0xa2, 0x4c, 0x4a, 0x61, 0x9d, 0x86, 0xca, 0x0f, 0x24, 0x9e, 0x5d,
- 0xa7, 0x48, 0x7f, 0x4d, 0xc9, 0xf8, 0xc4, 0xe8, 0xac, 0xe4, 0x9d, 0x10,
- 0x7c, 0xb1, 0xb2, 0xf2, 0x73, 0x5e, 0x80, 0x0d, 0x1d, 0xd9, 0x0a, 0x78,
- 0xdc, 0x1b, 0xd7, 0xa6, 0x1f, 0xa2, 0xf7, 0xa3, 0xef, 0x8e, 0xc4, 0x2a,
- 0xab, 0xef, 0xf5, 0x58, 0xcf, 0x7b, 0x01, 0xff, 0x7b, 0x6c, 0xe6, 0xef,
- 0xc3, 0x4f, 0x68, 0x4e, 0xc9, 0xd9, 0xca, 0x7e, 0xe6, 0xc6, 0xa7, 0xb7,
- 0x81, 0xb7, 0x93, 0xed, 0x7c, 0x7d, 0xe6, 0xb0, 0xf9, 0xba, 0x87, 0x67,
- 0xc5, 0x5c, 0x79, 0xd2, 0x19, 0xf3, 0xe5, 0x69, 0x87, 0x0d, 0xc9, 0xe3,
- 0x4d, 0x3f, 0x47, 0x7e, 0x2f, 0x3b, 0x9c, 0x34, 0xf8, 0x59, 0xf8, 0x86,
- 0x7e, 0x2e, 0x24, 0x73, 0x36, 0x5b, 0xad, 0x93, 0x69, 0xde, 0xc7, 0xce,
- 0x1c, 0x5d, 0xc3, 0x1e, 0xaf, 0xd5, 0x81, 0xc3, 0xe3, 0xac, 0x63, 0xee,
- 0x56, 0xb7, 0xe4, 0xc6, 0x55, 0xbc, 0xaf, 0x77, 0xcd, 0xdd, 0x2f, 0x57,
- 0x6b, 0x51, 0x95, 0x87, 0x56, 0x84, 0x9d, 0xdf, 0x90, 0xdb, 0x0e, 0xef,
- 0xa3, 0x8f, 0xa8, 0xf1, 0x3e, 0xbf, 0x73, 0x9d, 0xa8, 0x1c, 0x59, 0xd7,
- 0xf2, 0xe4, 0x54, 0x06, 0x76, 0xcb, 0x25, 0xb1, 0x3e, 0x9a, 0x19, 0x82,
- 0xef, 0xcd, 0xb5, 0x52, 0x18, 0x07, 0xda, 0x89, 0x91, 0xd7, 0x7f, 0xd1,
- 0x6a, 0x00, 0xde, 0xdb, 0x4d, 0xda, 0xeb, 0xb0, 0xa1, 0x66, 0x38, 0xc6,
- 0x13, 0xfb, 0x02, 0xfb, 0x0c, 0x80, 0xfe, 0x42, 0xfa, 0x7b, 0xb4, 0xca,
- 0x01, 0x69, 0x38, 0x6c, 0xe3, 0x73, 0x4c, 0x1a, 0x51, 0xdf, 0x4f, 0xf9,
- 0x21, 0xf0, 0x17, 0x57, 0x32, 0xc9, 0xbf, 0xc3, 0x67, 0x4e, 0xe9, 0x5c,
- 0xed, 0x18, 0x78, 0x28, 0x68, 0x6c, 0xb3, 0x20, 0xe6, 0xf8, 0xbe, 0xa3,
- 0x6d, 0x05, 0xde, 0xf1, 0x6b, 0x5b, 0x44, 0xeb, 0x18, 0xde, 0xfb, 0x05,
- 0xe1, 0x0b, 0xf8, 0x7c, 0x79, 0xc8, 0xd8, 0x14, 0x9d, 0xbe, 0x7c, 0x2a,
- 0x76, 0x91, 0xff, 0x0f, 0x62, 0xf3, 0x83, 0x32, 0x0b, 0x98, 0xcf, 0x9b,
- 0x7d, 0x3e, 0x92, 0x71, 0xe5, 0x56, 0x9d, 0x77, 0xf0, 0x07, 0x51, 0x32,
- 0xdf, 0x90, 0x30, 0x8f, 0x99, 0x9c, 0x4a, 0x0f, 0x7b, 0x3d, 0x21, 0x2f,
- 0xc3, 0xbe, 0x7e, 0xa5, 0x92, 0x4a, 0x1f, 0x51, 0x71, 0xe7, 0x44, 0xec,
- 0xaa, 0x8c, 0xc5, 0xe9, 0x03, 0x96, 0x9c, 0x44, 0xec, 0x16, 0xe8, 0xe1,
- 0x76, 0xe5, 0x50, 0x3f, 0xff, 0x27, 0x45, 0x03, 0xfa, 0xf0, 0xb6, 0xca,
- 0x81, 0x49, 0x30, 0x66, 0x82, 0xf7, 0x21, 0x93, 0x87, 0xc3, 0x75, 0xd8,
- 0x36, 0x24, 0x2f, 0x57, 0xda, 0xfa, 0x97, 0xeb, 0xe8, 0xdc, 0x36, 0xa5,
- 0x5f, 0x8f, 0xf6, 0x53, 0x0e, 0x71, 0x3d, 0x3d, 0x87, 0xdf, 0x87, 0x78,
- 0xf5, 0x63, 0x91, 0x8e, 0xfe, 0xbe, 0xc1, 0x62, 0xde, 0x0b, 0xf7, 0xfe,
- 0x13, 0x47, 0xdb, 0x40, 0x1c, 0x97, 0x72, 0x8e, 0xaa, 0xf9, 0x78, 0xdf,
- 0x3b, 0x24, 0x3f, 0x6e, 0xfa, 0xf3, 0x30, 0x1f, 0x87, 0x39, 0x3f, 0x94,
- 0x7d, 0x9d, 0x30, 0x68, 0xfd, 0xff, 0xb2, 0x8a, 0xeb, 0x4d, 0xa2, 0x3f,
- 0x75, 0x34, 0xe8, 0xa5, 0x1e, 0xd3, 0xff, 0xdf, 0xa1, 0x2d, 0xe3, 0xf8,
- 0x4c, 0x7c, 0x72, 0x1d, 0xd8, 0xf8, 0x0f, 0x38, 0xa6, 0xdd, 0xb7, 0x4b,
- 0x87, 0xc0, 0xaf, 0x27, 0xa4, 0xb1, 0x92, 0x8a, 0x3d, 0x2e, 0xfe, 0xbc,
- 0xad, 0x87, 0x79, 0x2f, 0x56, 0xc8, 0x8c, 0x39, 0x0b, 0x0a, 0x1e, 0xde,
- 0xdd, 0x26, 0x9c, 0xab, 0x58, 0xaf, 0xd1, 0xdc, 0x1d, 0x7b, 0x48, 0x64,
- 0xb7, 0x24, 0x95, 0xd6, 0x67, 0x33, 0x22, 0x5b, 0x38, 0x9b, 0x3f, 0x31,
- 0x67, 0xf3, 0x7e, 0xcc, 0xed, 0x5e, 0x18, 0x97, 0xd4, 0x85, 0x54, 0xfc,
- 0xbc, 0xf0, 0x8e, 0xf9, 0x00, 0xef, 0x98, 0xad, 0x47, 0x32, 0x71, 0xec,
- 0x37, 0x81, 0xfd, 0xa2, 0x6c, 0xf2, 0x99, 0xdf, 0xf7, 0xef, 0x23, 0x6f,
- 0x3f, 0x4c, 0x99, 0x49, 0x5c, 0x14, 0x54, 0x1b, 0xec, 0x93, 0xa7, 0x08,
- 0xd3, 0xbf, 0xe3, 0xf9, 0xa8, 0x58, 0xe8, 0xad, 0x26, 0xbf, 0x5b, 0xd5,
- 0xf0, 0xe5, 0x01, 0xdf, 0xbc, 0x86, 0x2f, 0x3e, 0xdb, 0xb6, 0x5d, 0x13,
- 0xb1, 0xb3, 0x42, 0x7b, 0x89, 0xf6, 0x0b, 0xed, 0xfa, 0xbf, 0xe9, 0xd7,
- 0xb1, 0x3d, 0xf8, 0xb1, 0x0f, 0x64, 0xdb, 0x7b, 0xef, 0x42, 0xdf, 0x6b,
- 0x19, 0x95, 0x63, 0xec, 0x4c, 0xc9, 0x7b, 0x25, 0xfb, 0x91, 0x44, 0x3c,
- 0x6b, 0xb9, 0xc6, 0x06, 0x44, 0x59, 0xe7, 0x33, 0x65, 0xae, 0x6b, 0x6c,
- 0x0b, 0x9e, 0x4d, 0x06, 0x6b, 0x29, 0xdc, 0xc2, 0x67, 0x1a, 0x02, 0xcd,
- 0x93, 0xd6, 0xde, 0x05, 0x1e, 0xd2, 0xff, 0x13, 0xe3, 0x2a, 0xf0, 0x58,
- 0x06, 0x1e, 0x4f, 0xdd, 0x65, 0x83, 0x85, 0xda, 0x36, 0xd8, 0xb6, 0x5a,
- 0xef, 0x26, 0x60, 0xca, 0x3b, 0xb4, 0xbf, 0xca, 0x6d, 0x5a, 0x21, 0x4c,
- 0xe3, 0xfc, 0x2e, 0x5b, 0xae, 0x67, 0x78, 0x1e, 0xb0, 0xc1, 0x30, 0xdf,
- 0xda, 0x0e, 0x2d, 0x61, 0xff, 0x8a, 0x7e, 0x41, 0xbb, 0x09, 0x27, 0x68,
- 0xf1, 0x2c, 0x38, 0x9f, 0x58, 0x37, 0x00, 0xcb, 0xb6, 0xa2, 0x03, 0x4d,
- 0x03, 0xdb, 0xf5, 0xde, 0x37, 0xa0, 0x01, 0xee, 0x93, 0xf4, 0xe7, 0xd3,
- 0x5e, 0xfb, 0xbb, 0x75, 0xf8, 0xb7, 0x25, 0xb9, 0xff, 0x90, 0x27, 0xb9,
- 0x0b, 0x2d, 0x59, 0x48, 0x8b, 0x35, 0x76, 0x88, 0x34, 0x49, 0x3b, 0x01,
- 0x36, 0x64, 0x8c, 0x38, 0xd6, 0xf6, 0xe0, 0xec, 0x57, 0xf7, 0xe3, 0xf7,
- 0x6f, 0xfa, 0x79, 0xbf, 0x94, 0xdb, 0xa0, 0xbc, 0x12, 0xeb, 0xbe, 0x43,
- 0xda, 0x3f, 0xbc, 0x1d, 0x05, 0xce, 0xd1, 0x9e, 0x7c, 0xa2, 0xcb, 0xc4,
- 0x51, 0xb5, 0x5e, 0x4e, 0x3e, 0x41, 0xbc, 0xa2, 0xfc, 0xea, 0x4f, 0x1c,
- 0x3f, 0x27, 0x49, 0xc7, 0x04, 0xc9, 0x17, 0x25, 0x99, 0xcf, 0x30, 0x27,
- 0xb4, 0x57, 0x8e, 0x40, 0xae, 0x4d, 0x55, 0x26, 0xe5, 0x0b, 0x95, 0x88,
- 0xb2, 0x1b, 0xfe, 0x2c, 0x9d, 0x8a, 0x8d, 0x5a, 0x2d, 0x79, 0x04, 0xf6,
- 0xcf, 0xec, 0x50, 0x97, 0xbc, 0x32, 0xae, 0xf3, 0x6f, 0x6f, 0x33, 0xb9,
- 0xce, 0x61, 0xce, 0x28, 0xf7, 0x03, 0xb9, 0x6f, 0xc1, 0x17, 0xb0, 0xba,
- 0x65, 0x36, 0x1a, 0x91, 0xe9, 0x34, 0xca, 0x37, 0xa7, 0xd5, 0x37, 0xa4,
- 0xd9, 0x68, 0xa7, 0x1c, 0x21, 0xcc, 0x2c, 0xdf, 0x62, 0xca, 0x9f, 0xf5,
- 0x77, 0xc0, 0x62, 0xcd, 0x67, 0x02, 0x6a, 0x7f, 0xe5, 0x3a, 0xe5, 0x1b,
- 0xc7, 0x40, 0x9e, 0x34, 0x79, 0x0f, 0x59, 0x92, 0x35, 0xc8, 0x97, 0x62,
- 0x4d, 0xac, 0x8d, 0x0c, 0x2c, 0x6a, 0x57, 0xdb, 0x9f, 0x45, 0xd0, 0xd7,
- 0x5c, 0x8d, 0xf2, 0x6f, 0x4a, 0xe5, 0x4e, 0xcf, 0xc1, 0xd6, 0x85, 0x4f,
- 0x3c, 0xdb, 0xed, 0x99, 0x7b, 0xce, 0x5e, 0xc6, 0x43, 0x3a, 0x65, 0x98,
- 0xff, 0x3f, 0x73, 0x0e, 0x0f, 0x48, 0x5f, 0x09, 0xe7, 0xe2, 0xdb, 0xdc,
- 0xc0, 0x29, 0xd6, 0xcc, 0xa9, 0x73, 0xf2, 0xcf, 0x84, 0xb2, 0xa7, 0x33,
- 0x67, 0xdb, 0xb7, 0x39, 0xc8, 0xb3, 0xd4, 0x17, 0x52, 0x0a, 0xc3, 0xa6,
- 0xed, 0xb9, 0x00, 0xdd, 0x5d, 0xf3, 0x40, 0x2b, 0x93, 0xd0, 0x87, 0x93,
- 0x52, 0x86, 0xed, 0xf6, 0xd1, 0xf4, 0x67, 0xc5, 0x7e, 0xea, 0xa0, 0xac,
- 0xd5, 0x7a, 0x80, 0x0f, 0xea, 0x85, 0x90, 0xf2, 0xaf, 0x6f, 0x1f, 0xa7,
- 0xbe, 0xa3, 0x2e, 0xd1, 0x67, 0xb1, 0x5d, 0xff, 0xc4, 0x80, 0xfe, 0x7e,
- 0x65, 0xbf, 0x6c, 0xd5, 0x7d, 0x5d, 0x08, 0xff, 0xb0, 0x16, 0x32, 0x7a,
- 0xb9, 0x17, 0xb2, 0xfb, 0xaf, 0x43, 0x0d, 0xe5, 0xab, 0x73, 0xff, 0xd4,
- 0x41, 0xea, 0xff, 0x70, 0xf4, 0x36, 0x5c, 0xee, 0xbd, 0x53, 0x07, 0x69,
- 0xbb, 0xc3, 0x39, 0xcc, 0xf5, 0x78, 0x1f, 0xc7, 0x3d, 0x46, 0x25, 0x74,
- 0xf1, 0x84, 0xd8, 0xf0, 0x5b, 0x02, 0x4b, 0xb4, 0xf5, 0xee, 0xf4, 0x5d,
- 0x02, 0x97, 0x6d, 0xf3, 0xad, 0xed, 0xb0, 0xb6, 0x65, 0x32, 0x28, 0x1b,
- 0xfe, 0xf7, 0xb7, 0xfc, 0xdd, 0xe1, 0xdb, 0x1d, 0x78, 0x03, 0x5d, 0x8a,
- 0xbf, 0xff, 0x0b, 0xc4, 0xbf, 0x6d, 0x24, 0x80, 0x4a, 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_COM_b09FwRodata[(0x30/4) + 1] = {
- 0x80080100, 0x80080080, 0x80080000, 0x80080240, 0x08000ea4, 0x08000efc,
- 0x08000f40, 0x08000fd4, 0x08001018, 0x80080100, 0x80080080, 0x80080000,
- 0x00000000 };
-
-static struct fw_info bnx2_com_fw_09 = {
- /* Firmware version: 4.6.15 */
- .ver_major = 0x4,
- .ver_minor = 0x6,
- .ver_fix = 0xf,
-
- .start_addr = 0x080000f8,
-
- .text_addr = 0x08000000,
- .text_len = 0x4a7c,
- .text_index = 0x0,
- .gz_text = bnx2_COM_b09FwText,
- .gz_text_len = sizeof(bnx2_COM_b09FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_COM_b09FwData,
-
- .sbss_addr = 0x08004ae0,
- .sbss_len = 0x38,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08004b18,
- .bss_len = 0xc0,
- .bss_index = 0x0,
-
- .rodata_addr = 0x08004a7c,
- .rodata_len = 0x30,
- .rodata_index = 0x0,
- .rodata = bnx2_COM_b09FwRodata,
-};
-
-static u8 bnx2_CP_b09FwText[] = {
- 0xa5, 0xbc, 0x0d, 0x74, 0x1c, 0xe5, 0x95, 0x26, 0xfc, 0x54, 0x75, 0xb7,
- 0xd4, 0x92, 0x5a, 0x52, 0x49, 0x6e, 0x8b, 0x36, 0x68, 0x70, 0xb5, 0x55,
- 0x2d, 0x0b, 0x4b, 0x40, 0xb5, 0x24, 0x3b, 0xed, 0x6c, 0x83, 0x3b, 0xb6,
- 0x6c, 0x64, 0x63, 0x40, 0x36, 0x06, 0xc4, 0xb7, 0xfe, 0x3e, 0x7a, 0xfc,
- 0x03, 0x86, 0x38, 0x19, 0x91, 0xcd, 0xce, 0x0a, 0xd6, 0x59, 0x55, 0xe4,
- 0x3f, 0xd9, 0x6e, 0x75, 0x4b, 0x42, 0xfe, 0xe1, 0xec, 0x9c, 0xa5, 0x2d,
- 0xcb, 0x96, 0x21, 0xad, 0x16, 0x24, 0x6c, 0xc6, 0x39, 0x27, 0x09, 0x1a,
- 0x63, 0x83, 0x0d, 0x18, 0xc8, 0x24, 0xf9, 0x86, 0xc9, 0xd9, 0x5d, 0x34,
- 0xc6, 0xfc, 0x19, 0x70, 0x1c, 0x92, 0xc9, 0x9a, 0x19, 0x4c, 0xed, 0x73,
- 0xab, 0xd5, 0xb6, 0xec, 0x30, 0xc9, 0xcc, 0x59, 0x9d, 0xd3, 0xa7, 0xab,
- 0xab, 0xde, 0x9f, 0xfb, 0xde, 0xf7, 0xde, 0xe7, 0x3e, 0xf7, 0x7d, 0xdf,
- 0x92, 0x0e, 0x14, 0x63, 0xf2, 0xaf, 0x94, 0x9f, 0x9b, 0x9a, 0x3b, 0xd6,
- 0xce, 0x0d, 0xdf, 0x34, 0x4f, 0x7e, 0xbb, 0xcb, 0x0b, 0xdc, 0xf8, 0xb2,
- 0xbf, 0x28, 0x22, 0x57, 0xdf, 0xd2, 0xbf, 0xb4, 0xe0, 0xbf, 0xf0, 0x17,
- 0x41, 0x50, 0xe1, 0x57, 0xfd, 0xe4, 0x4f, 0x17, 0xa0, 0xe5, 0xfb, 0x97,
- 0x0f, 0xbc, 0x6a, 0xd4, 0xb8, 0x77, 0xa1, 0x01, 0xaf, 0x2b, 0xba, 0xaa,
- 0x7d, 0xad, 0x01, 0xc4, 0x32, 0xf5, 0xfa, 0x22, 0x5c, 0xb4, 0x2d, 0xbf,
- 0x1b, 0x72, 0xff, 0xcf, 0xa2, 0x9f, 0x3f, 0xf5, 0x93, 0xaf, 0x04, 0xcf,
- 0xa7, 0x5d, 0xf0, 0x6a, 0x51, 0x0b, 0x5a, 0x2d, 0xbc, 0xd5, 0xac, 0xf3,
- 0x57, 0xb3, 0xb7, 0xa9, 0x28, 0xcb, 0xb7, 0x15, 0x0c, 0xa4, 0x11, 0xd4,
- 0x2c, 0x04, 0xeb, 0x2c, 0x20, 0xee, 0x8e, 0x22, 0x5e, 0x18, 0xf5, 0xa2,
- 0xc0, 0x28, 0x40, 0x5c, 0xeb, 0xd4, 0xb7, 0x34, 0x03, 0x0b, 0x13, 0x5e,
- 0xfd, 0x74, 0x06, 0x58, 0x9b, 0xf0, 0x62, 0xc2, 0xe5, 0xd3, 0xdf, 0xc9,
- 0x44, 0xca, 0x72, 0xfa, 0x88, 0xc1, 0x65, 0x20, 0xae, 0x46, 0xe5, 0x3e,
- 0xf4, 0x45, 0x19, 0xa9, 0x0b, 0x6c, 0x4b, 0x7d, 0x5b, 0x7f, 0x37, 0x11,
- 0xd4, 0xb6, 0xa1, 0x3e, 0x30, 0x84, 0x42, 0xc4, 0xfd, 0xc1, 0x3a, 0xe0,
- 0xf3, 0x8b, 0x3b, 0x53, 0x0a, 0x3c, 0xc6, 0x34, 0xb4, 0xec, 0x07, 0x76,
- 0xa4, 0x82, 0x31, 0x83, 0xc3, 0xeb, 0x19, 0x93, 0xba, 0x41, 0x2d, 0xcd,
- 0xe7, 0x5b, 0x52, 0xc0, 0xd6, 0xd4, 0x34, 0x6c, 0xeb, 0xb3, 0xf1, 0xa2,
- 0x59, 0xa3, 0x1d, 0x60, 0x0f, 0xdd, 0xce, 0xf3, 0x69, 0xb0, 0xd2, 0xf2,
- 0xfc, 0x03, 0xfb, 0x27, 0xb3, 0x35, 0x3c, 0x3b, 0xe6, 0xc7, 0x0b, 0x63,
- 0x15, 0xd8, 0xd1, 0x57, 0x81, 0xed, 0x7d, 0x75, 0x50, 0x0d, 0x1b, 0x75,
- 0xe1, 0x3a, 0x14, 0xcc, 0xb7, 0xf1, 0x8e, 0xd9, 0x80, 0xad, 0x6c, 0xf8,
- 0xcd, 0x86, 0x2a, 0xac, 0xd1, 0xaa, 0xb1, 0xc5, 0xf8, 0x0a, 0x72, 0x63,
- 0xfd, 0xfc, 0x62, 0x2a, 0x85, 0xb8, 0x27, 0xea, 0x56, 0x55, 0xe3, 0x56,
- 0x9c, 0xdb, 0x1d, 0xc5, 0x27, 0xbb, 0xb1, 0xba, 0x0c, 0xb6, 0x9d, 0x09,
- 0x87, 0xda, 0x36, 0x2a, 0x9a, 0xfe, 0x4c, 0x86, 0x02, 0xad, 0x74, 0xb3,
- 0x3d, 0xe8, 0x43, 0x99, 0xa9, 0x53, 0xc1, 0xfe, 0x52, 0xec, 0x37, 0x25,
- 0xb2, 0x04, 0xf0, 0x93, 0xd9, 0x7f, 0x41, 0x7b, 0xc8, 0x8d, 0x69, 0x6b,
- 0xea, 0x2d, 0xca, 0xa4, 0x53, 0x9e, 0x6a, 0xfc, 0x60, 0x2c, 0x80, 0xef,
- 0x53, 0xb6, 0xe7, 0xc6, 0x44, 0xc6, 0xe0, 0x3e, 0x0b, 0x15, 0x18, 0xee,
- 0xab, 0xc6, 0xb3, 0x46, 0x03, 0x9e, 0xa3, 0x8c, 0x9b, 0xcd, 0x3a, 0xac,
- 0x89, 0xdc, 0x4f, 0x79, 0x14, 0xac, 0x6c, 0xf8, 0xf3, 0x49, 0xb9, 0x82,
- 0x3a, 0x54, 0x15, 0xb1, 0xca, 0x60, 0x9d, 0xae, 0x4a, 0x9b, 0x97, 0xe5,
- 0xed, 0x4d, 0xc1, 0xf2, 0x46, 0x45, 0xe6, 0x5b, 0x91, 0xa1, 0xbc, 0xdf,
- 0xdb, 0x1d, 0x32, 0x37, 0xa8, 0x58, 0xee, 0xa3, 0xcc, 0x8f, 0x84, 0x43,
- 0x91, 0x39, 0x94, 0x79, 0x24, 0xa3, 0x72, 0x3c, 0x7e, 0xfd, 0x10, 0x65,
- 0x8f, 0xad, 0x54, 0x29, 0x3b, 0x65, 0x49, 0x51, 0x96, 0x14, 0x65, 0x49,
- 0x51, 0x16, 0x47, 0xee, 0x3a, 0xca, 0x9c, 0x9b, 0xa3, 0xa1, 0xcc, 0x04,
- 0xe5, 0x9d, 0x2a, 0x67, 0x35, 0x65, 0x47, 0xbc, 0x22, 0xfa, 0x6d, 0xbd,
- 0x26, 0x49, 0x7d, 0xa7, 0x6c, 0xfb, 0x4d, 0xd3, 0xb6, 0x3f, 0x35, 0x7d,
- 0xd4, 0x5f, 0x8a, 0x76, 0x90, 0x97, 0x67, 0xa6, 0x55, 0x10, 0x45, 0x0b,
- 0x4d, 0xd0, 0x3e, 0xde, 0x1c, 0x8a, 0x54, 0x2a, 0x2a, 0xdc, 0x86, 0xa6,
- 0xcf, 0xce, 0x06, 0x4d, 0xea, 0x47, 0x0f, 0x65, 0xa1, 0x1b, 0x59, 0xb6,
- 0x75, 0x45, 0xbf, 0x41, 0x6d, 0x1c, 0xd2, 0xaf, 0xce, 0xfe, 0x27, 0x26,
- 0xe7, 0x4e, 0xda, 0x0f, 0xb0, 0x4f, 0xe9, 0x5f, 0xda, 0xb6, 0xed, 0xdf,
- 0x98, 0x30, 0x34, 0x84, 0xac, 0x7e, 0xda, 0x9f, 0x2b, 0xaa, 0xe9, 0x1d,
- 0x19, 0x3e, 0xbf, 0xd4, 0x46, 0x6e, 0x3e, 0xd6, 0x64, 0xf4, 0xc9, 0x31,
- 0x04, 0x29, 0x82, 0xd8, 0x41, 0x20, 0xee, 0x8b, 0x6a, 0x22, 0x7b, 0xdb,
- 0xbe, 0xde, 0x2e, 0x7b, 0x86, 0x21, 0xba, 0x32, 0x3a, 0x67, 0xb8, 0x7c,
- 0x91, 0x73, 0x73, 0x1f, 0xb5, 0x4a, 0x9b, 0xc3, 0x28, 0x36, 0xe0, 0x2b,
- 0x32, 0xd0, 0x96, 0x1c, 0x2d, 0xb6, 0x4a, 0xa2, 0x3f, 0xbe, 0xbb, 0x77,
- 0xd4, 0x8b, 0xe2, 0x51, 0x03, 0x45, 0xa3, 0x4f, 0xbb, 0x51, 0xd6, 0x80,
- 0x5d, 0x63, 0x0f, 0xb9, 0x73, 0x63, 0x5b, 0x32, 0x39, 0x46, 0xc7, 0xf6,
- 0xbd, 0xef, 0x26, 0xce, 0xdb, 0x05, 0x46, 0xd1, 0x7d, 0xae, 0xa8, 0xa1,
- 0x1f, 0x02, 0xce, 0xaf, 0x69, 0x5e, 0x84, 0x6e, 0x4d, 0xc1, 0x4c, 0xe3,
- 0x95, 0x12, 0x94, 0x45, 0x60, 0x8d, 0x55, 0xc5, 0x0b, 0xa2, 0xfe, 0x38,
- 0xe7, 0x06, 0x2f, 0x27, 0xd2, 0xf0, 0xf4, 0xda, 0xb6, 0x94, 0x7d, 0x07,
- 0x77, 0xdf, 0xad, 0x46, 0x8f, 0xde, 0xec, 0x41, 0x0b, 0xcb, 0x63, 0xd3,
- 0x89, 0xe6, 0x4f, 0x15, 0x75, 0x77, 0x1b, 0xac, 0x11, 0x17, 0x62, 0x5a,
- 0x9c, 0xdf, 0xd7, 0x5f, 0xbf, 0x3c, 0xd2, 0x86, 0xc4, 0xc8, 0x05, 0xde,
- 0x77, 0xf3, 0x5e, 0x04, 0xc9, 0xd4, 0xf5, 0xd7, 0xdf, 0x11, 0x89, 0xa3,
- 0x77, 0x44, 0xae, 0xdd, 0x18, 0xaf, 0x88, 0x63, 0xfb, 0x5e, 0x1d, 0xe5,
- 0x46, 0x1b, 0x52, 0x23, 0x72, 0x6d, 0xdb, 0x67, 0xcc, 0xef, 0x62, 0x5f,
- 0x03, 0xfd, 0xff, 0x9a, 0x36, 0x6c, 0xdb, 0x6b, 0xa1, 0xd0, 0xb0, 0xa8,
- 0x7b, 0xc5, 0xfd, 0xf7, 0x0d, 0x0a, 0xf4, 0xbb, 0xe1, 0x2e, 0x30, 0x44,
- 0x6f, 0x11, 0xf7, 0xfa, 0x44, 0x54, 0x9b, 0x69, 0xd8, 0xf6, 0x90, 0x39,
- 0x07, 0x0f, 0xb4, 0xad, 0x81, 0x75, 0xc0, 0x07, 0x6b, 0x95, 0x7c, 0xb7,
- 0x51, 0x87, 0x6b, 0xd0, 0x7d, 0x60, 0x0d, 0x7a, 0x9e, 0xa0, 0xe3, 0x56,
- 0x68, 0xce, 0x3c, 0xfd, 0x64, 0xb6, 0xc8, 0x24, 0xf2, 0xb5, 0xf3, 0x23,
- 0xba, 0xfd, 0x4b, 0x7e, 0x4b, 0x99, 0x0b, 0x36, 0xa6, 0x5f, 0x2e, 0xb3,
- 0x9d, 0x65, 0xb6, 0x5d, 0x51, 0x26, 0x82, 0xa7, 0xc6, 0x44, 0x17, 0xa2,
- 0xb2, 0x3f, 0xa5, 0x8b, 0x9f, 0xda, 0xdd, 0x7e, 0xd1, 0x85, 0xd5, 0xee,
- 0x41, 0xb0, 0xed, 0x41, 0xc5, 0x8d, 0xa5, 0xbd, 0x60, 0x1d, 0x3a, 0x41,
- 0x71, 0x30, 0x56, 0xab, 0x44, 0x51, 0xdc, 0xab, 0x60, 0x69, 0xb8, 0x08,
- 0x7a, 0x85, 0xb4, 0xf7, 0x4b, 0xdb, 0xd2, 0x44, 0xde, 0x13, 0x28, 0xe1,
- 0xfd, 0x75, 0xe1, 0x9f, 0x13, 0xcf, 0x44, 0xa6, 0x30, 0xcb, 0xaf, 0xe0,
- 0xfd, 0x37, 0xa6, 0xfc, 0x96, 0x72, 0xb6, 0xbd, 0x99, 0x3e, 0xdf, 0x43,
- 0x1b, 0xdf, 0x9e, 0x8a, 0x05, 0xa9, 0x25, 0xcb, 0x13, 0xe5, 0xfd, 0x68,
- 0xa8, 0xb5, 0x1b, 0xd2, 0x0f, 0x94, 0xe2, 0x28, 0xdc, 0x99, 0xe6, 0x09,
- 0xef, 0xa9, 0x84, 0xd1, 0xfe, 0x8c, 0xe2, 0xa1, 0xb1, 0x4b, 0x3f, 0x13,
- 0xde, 0x37, 0x12, 0x0a, 0xde, 0x37, 0x42, 0x1d, 0x67, 0x95, 0x09, 0xef,
- 0xeb, 0x19, 0x0d, 0x33, 0x7a, 0x83, 0xed, 0x96, 0x12, 0xc1, 0x8f, 0x32,
- 0x7e, 0x04, 0x7a, 0xa3, 0x38, 0x92, 0x31, 0xf1, 0xf4, 0x15, 0x38, 0xf0,
- 0xa5, 0x7f, 0x96, 0x8b, 0x63, 0x5f, 0x97, 0xd0, 0xd1, 0x6d, 0x5e, 0xb4,
- 0x63, 0x1a, 0xe2, 0xe5, 0xd1, 0x09, 0xef, 0x27, 0xbd, 0x50, 0xca, 0xa2,
- 0x46, 0x20, 0xab, 0xfc, 0x83, 0x1d, 0xf7, 0x4b, 0x31, 0xca, 0xe7, 0x60,
- 0x59, 0x94, 0x76, 0x47, 0x8c, 0x4a, 0x9d, 0xb7, 0x4b, 0x68, 0xb3, 0x05,
- 0xd1, 0x6b, 0x31, 0x32, 0x68, 0xe0, 0xe9, 0x84, 0x6d, 0x7f, 0x6c, 0x8e,
- 0x47, 0x7c, 0x30, 0xda, 0x3e, 0x42, 0x30, 0x36, 0x87, 0x7a, 0x39, 0x91,
- 0x31, 0x30, 0x9c, 0x88, 0xe2, 0xc5, 0x44, 0x8d, 0xb6, 0x19, 0x4d, 0x88,
- 0x05, 0x72, 0x31, 0x64, 0x94, 0x72, 0x0f, 0x85, 0xda, 0x50, 0x1e, 0x8d,
- 0xe0, 0x28, 0xe5, 0x3e, 0x37, 0x57, 0xda, 0x31, 0xf1, 0xfa, 0xbf, 0x42,
- 0x56, 0xe2, 0x3b, 0x9e, 0xa4, 0xac, 0x91, 0xa6, 0x8b, 0x36, 0xa6, 0x79,
- 0x71, 0xda, 0xbc, 0x86, 0x76, 0x08, 0xab, 0x28, 0xea, 0x75, 0xf7, 0x24,
- 0x34, 0x1c, 0xce, 0xf8, 0xdc, 0x9b, 0x13, 0x7e, 0x1c, 0xa0, 0xbf, 0xcd,
- 0x88, 0xc2, 0x0a, 0xb0, 0xdd, 0x19, 0xc4, 0xb5, 0xec, 0x60, 0x35, 0xc6,
- 0x06, 0x83, 0xe6, 0x1b, 0x4a, 0x00, 0x87, 0x86, 0xaf, 0xc5, 0xe8, 0xa0,
- 0x82, 0x91, 0x10, 0x65, 0xe7, 0xf5, 0xf7, 0x06, 0xaf, 0x47, 0x66, 0xd0,
- 0x85, 0x5d, 0x8e, 0x5e, 0x1d, 0x9c, 0x99, 0xfc, 0xbe, 0x16, 0xe9, 0x61,
- 0xb8, 0xe7, 0xf4, 0x6a, 0x78, 0x26, 0xe3, 0x76, 0x1b, 0xbd, 0x7e, 0x0c,
- 0x67, 0x7e, 0xca, 0x79, 0x93, 0xb6, 0x75, 0x0c, 0x25, 0x0e, 0x39, 0x73,
- 0x58, 0x1e, 0x65, 0x63, 0xb9, 0xf8, 0xca, 0x58, 0xa6, 0x33, 0xce, 0x34,
- 0x13, 0x87, 0xc4, 0xc7, 0xbd, 0xc4, 0x20, 0xf1, 0xf1, 0xb7, 0x14, 0x94,
- 0x35, 0x63, 0xf3, 0x58, 0xfe, 0xb9, 0x42, 0xfb, 0x77, 0x63, 0x9d, 0xd6,
- 0x80, 0x44, 0x4a, 0xec, 0x34, 0x8f, 0xcb, 0x72, 0x2d, 0xf3, 0x5f, 0x0c,
- 0xeb, 0x60, 0x31, 0x76, 0xd1, 0xc7, 0x76, 0xee, 0x96, 0xfb, 0xb6, 0xfd,
- 0x50, 0xb8, 0x9c, 0x36, 0x86, 0xc5, 0x45, 0x08, 0x99, 0x1f, 0x38, 0xb2,
- 0x59, 0x38, 0x94, 0x91, 0x18, 0xaa, 0x33, 0xbe, 0x9d, 0x60, 0x5f, 0xcd,
- 0xec, 0xc7, 0xc4, 0x4f, 0x39, 0x37, 0x7f, 0x3d, 0x56, 0x87, 0x1f, 0x8e,
- 0x19, 0xf8, 0xef, 0x63, 0x3a, 0x9e, 0xbf, 0x02, 0xd7, 0xef, 0xa6, 0xae,
- 0x04, 0xc3, 0x1a, 0xb0, 0x25, 0x55, 0x80, 0x6d, 0x83, 0xc5, 0xd8, 0x3c,
- 0x58, 0x53, 0xf7, 0x22, 0xf1, 0xf8, 0x87, 0xe6, 0x1d, 0x18, 0xaf, 0x6c,
- 0x76, 0x7c, 0x66, 0x07, 0xef, 0xef, 0x1c, 0xac, 0xe1, 0x1c, 0xda, 0xb6,
- 0x1a, 0xae, 0x8f, 0x1c, 0x25, 0xbe, 0x4f, 0xf8, 0x83, 0xfa, 0xb8, 0x1a,
- 0xd4, 0x63, 0xf0, 0x20, 0xd1, 0xa0, 0xc2, 0x9a, 0x1e, 0x4c, 0xd3, 0x8b,
- 0xe1, 0x37, 0x1e, 0xe2, 0xd8, 0x82, 0xba, 0xa5, 0x36, 0xd0, 0x7e, 0x19,
- 0x33, 0x54, 0x93, 0xf8, 0x52, 0x8c, 0x4f, 0x06, 0x83, 0x3d, 0x96, 0xba,
- 0x02, 0x56, 0xa5, 0x6d, 0x7f, 0x3f, 0x8c, 0x8e, 0x6b, 0xa2, 0x88, 0x4d,
- 0x67, 0x2c, 0xb8, 0x3e, 0x1a, 0x05, 0xe3, 0x18, 0xce, 0xf5, 0x1a, 0x81,
- 0xbf, 0x53, 0xee, 0xc6, 0x7f, 0x6c, 0x0b, 0xea, 0xba, 0x5a, 0x6f, 0x1d,
- 0x50, 0x49, 0x36, 0xaa, 0xa0, 0x07, 0xa2, 0xcb, 0xd0, 0xe9, 0xf0, 0x04,
- 0x05, 0x9a, 0x61, 0x62, 0x73, 0x8a, 0x95, 0xfc, 0x35, 0xed, 0xfd, 0x6a,
- 0xcd, 0x05, 0x53, 0x0d, 0x9e, 0x68, 0x53, 0x89, 0xb7, 0x4d, 0xe7, 0x6c,
- 0xbd, 0xca, 0xb6, 0x1b, 0x9b, 0xa4, 0x4f, 0x1d, 0x95, 0x9c, 0xe7, 0x0a,
- 0xce, 0x73, 0x63, 0xb6, 0x18, 0x67, 0x07, 0x61, 0x5d, 0x13, 0x0d, 0xb6,
- 0x3e, 0xa2, 0x16, 0xe3, 0xc3, 0xe1, 0x62, 0xbc, 0x33, 0xe8, 0xc6, 0x07,
- 0x83, 0xb6, 0xbd, 0xde, 0x2c, 0x47, 0x41, 0x18, 0xd3, 0x0b, 0x10, 0x3a,
- 0x3f, 0x04, 0x0b, 0x5f, 0xb0, 0xec, 0xef, 0x06, 0x03, 0xf8, 0xc7, 0xc1,
- 0xaf, 0xe2, 0xf9, 0xca, 0xd8, 0xc9, 0x69, 0x8c, 0x91, 0x17, 0x68, 0x3f,
- 0xe7, 0x12, 0xc1, 0xf6, 0x19, 0xae, 0x60, 0x27, 0x79, 0xcb, 0x86, 0xc7,
- 0x94, 0x60, 0xfc, 0x0d, 0x25, 0xa8, 0xf7, 0x2a, 0x7e, 0x7c, 0x44, 0x3b,
- 0x3d, 0x93, 0xa9, 0x89, 0xfc, 0x9c, 0xfd, 0xff, 0xde, 0xfc, 0xa1, 0x3d,
- 0x5e, 0x25, 0x3a, 0x14, 0x7d, 0x51, 0xe7, 0x29, 0xea, 0x9c, 0xfe, 0xfb,
- 0xc3, 0x14, 0x75, 0x4e, 0x79, 0x9e, 0xff, 0x83, 0xf8, 0x25, 0xf3, 0x15,
- 0xe1, 0x3c, 0x5e, 0x87, 0xff, 0xe2, 0x8c, 0xed, 0xa4, 0xfd, 0x9f, 0xfc,
- 0x32, 0xbe, 0xcf, 0xfd, 0x39, 0x0c, 0x92, 0x71, 0x9e, 0xb0, 0xe3, 0x9a,
- 0x8c, 0x51, 0xc6, 0xea, 0xe8, 0x52, 0xef, 0x50, 0x1e, 0x55, 0x51, 0x6c,
- 0xdb, 0x4f, 0x98, 0x93, 0xcf, 0xfd, 0xf9, 0xb1, 0x7e, 0x95, 0xf7, 0x65,
- 0xbc, 0x67, 0x5d, 0xa2, 0x7b, 0x5d, 0xbd, 0x89, 0xbf, 0x83, 0x56, 0x0c,
- 0xa7, 0x0b, 0xf9, 0xbb, 0x2e, 0x76, 0xe9, 0xf7, 0x93, 0xa5, 0x57, 0x3e,
- 0xa7, 0x9d, 0x3a, 0xfd, 0xdd, 0xcd, 0xdf, 0x32, 0x96, 0x37, 0x69, 0x37,
- 0x5f, 0x66, 0x27, 0x62, 0x23, 0x75, 0xb4, 0xa7, 0x33, 0x12, 0x57, 0x2c,
- 0x7f, 0xd4, 0x6b, 0xa9, 0x51, 0xe8, 0x74, 0x7d, 0xaf, 0x12, 0xed, 0x80,
- 0x9e, 0xb1, 0x70, 0x4f, 0xb3, 0x0b, 0xdf, 0x6a, 0x56, 0x30, 0xcd, 0xe8,
- 0x40, 0xdf, 0x3c, 0xcb, 0xae, 0x30, 0xf6, 0xab, 0xe2, 0x03, 0x05, 0x49,
- 0x58, 0xf4, 0x3b, 0x44, 0xc8, 0x95, 0xca, 0xff, 0x9d, 0x82, 0xd3, 0xe1,
- 0x10, 0x6d, 0x6e, 0x0b, 0x39, 0x15, 0x50, 0x98, 0x84, 0xb7, 0x94, 0xf3,
- 0x3f, 0xda, 0x0b, 0x6f, 0x31, 0x7d, 0x7f, 0x59, 0x6f, 0x4d, 0xc7, 0x7b,
- 0xc4, 0x8a, 0xac, 0x12, 0x6c, 0xa7, 0xbe, 0xcd, 0x32, 0x25, 0xd8, 0x7a,
- 0x3b, 0xf5, 0x5d, 0xab, 0x48, 0x3f, 0x51, 0xd4, 0x65, 0xb6, 0x10, 0x73,
- 0xe4, 0x3a, 0x02, 0x23, 0xf3, 0xab, 0x49, 0xd9, 0xe1, 0xf5, 0x50, 0x86,
- 0x83, 0x89, 0x77, 0xed, 0xb4, 0x16, 0xd4, 0xd3, 0xce, 0xef, 0x0d, 0xfc,
- 0x0d, 0x6f, 0x41, 0x74, 0x23, 0x5e, 0x4a, 0x3c, 0xe5, 0xcf, 0x97, 0xcb,
- 0xc9, 0x7a, 0xb5, 0x3c, 0xff, 0xd3, 0x8e, 0xf9, 0x73, 0xf2, 0xf8, 0x92,
- 0x5b, 0x40, 0x8e, 0xe2, 0x2d, 0x64, 0x5f, 0xef, 0x3b, 0xf5, 0x23, 0xac,
- 0x5f, 0xd3, 0xde, 0xab, 0x04, 0xeb, 0x3e, 0x42, 0xbd, 0xfe, 0x3d, 0x04,
- 0x5b, 0x8f, 0x92, 0x5b, 0x1a, 0x93, 0xf2, 0x84, 0x32, 0x0e, 0x9f, 0x71,
- 0xe4, 0x99, 0x95, 0x81, 0xe2, 0xea, 0x85, 0x6f, 0xa6, 0x51, 0x8b, 0x2e,
- 0x67, 0x4e, 0xa1, 0x04, 0x7a, 0x75, 0x94, 0x91, 0xbf, 0x04, 0x46, 0x81,
- 0xb1, 0x01, 0x72, 0xb9, 0x70, 0x0d, 0xbe, 0xc9, 0x58, 0x30, 0x83, 0x65,
- 0x1e, 0xd3, 0x2e, 0xe1, 0x97, 0xd2, 0x93, 0x20, 0xc0, 0x4c, 0xcf, 0xf1,
- 0xb2, 0xf8, 0xbd, 0x88, 0xc9, 0xbd, 0x27, 0x13, 0x50, 0x52, 0x89, 0xe0,
- 0x3e, 0xc0, 0x18, 0x0f, 0xbb, 0x62, 0x0f, 0x07, 0xd0, 0x85, 0x73, 0xe1,
- 0x50, 0x3c, 0xab, 0x84, 0xda, 0x07, 0x14, 0xd3, 0xbb, 0x8b, 0xfd, 0x6d,
- 0x67, 0x99, 0x1d, 0xfc, 0x9c, 0x35, 0x0c, 0x73, 0x85, 0x12, 0xbb, 0xa1,
- 0x80, 0x65, 0x6a, 0xc2, 0x21, 0xf2, 0xcc, 0xd0, 0x85, 0x95, 0x30, 0xbd,
- 0x4f, 0x65, 0xa4, 0xad, 0x88, 0xb2, 0x25, 0xfb, 0xa4, 0x9a, 0xc3, 0xa3,
- 0xdf, 0x4f, 0xea, 0xec, 0x1d, 0xf9, 0xed, 0xf4, 0xed, 0xee, 0xfd, 0xaf,
- 0x85, 0x7f, 0x78, 0xef, 0xaf, 0xa7, 0x5d, 0x79, 0xaf, 0x5e, 0x1b, 0xa6,
- 0xff, 0xb9, 0x8c, 0x22, 0xce, 0x9d, 0xf0, 0xa3, 0x58, 0x9d, 0x07, 0x72,
- 0xcf, 0x85, 0xb4, 0x3b, 0x16, 0x70, 0xe1, 0x73, 0x3b, 0xb6, 0x4a, 0xee,
- 0x15, 0x23, 0xde, 0x56, 0x1f, 0x70, 0xa3, 0x3e, 0xb2, 0x95, 0x58, 0x30,
- 0xb1, 0x6a, 0x21, 0x9f, 0x85, 0xcc, 0x17, 0x51, 0xa3, 0x6f, 0x85, 0x5c,
- 0x7f, 0x46, 0x9b, 0x5d, 0x28, 0x75, 0x59, 0x26, 0xc7, 0x7d, 0x04, 0x6b,
- 0xb6, 0x98, 0x36, 0x5e, 0x22, 0x4c, 0x14, 0x46, 0x8f, 0x28, 0xa7, 0x13,
- 0x5f, 0xd8, 0x31, 0x37, 0x96, 0xd3, 0x2f, 0x4d, 0xea, 0x59, 0xf7, 0x46,
- 0x43, 0xfa, 0x09, 0x66, 0x0a, 0xae, 0xa8, 0xa5, 0x4c, 0x64, 0xb6, 0x28,
- 0xef, 0x66, 0x7a, 0x94, 0x33, 0x19, 0xa9, 0x7b, 0x44, 0x79, 0x27, 0x23,
- 0xf1, 0xb0, 0x5a, 0x3f, 0x4e, 0x7e, 0x43, 0x4e, 0xa5, 0x6e, 0x36, 0xa1,
- 0x6c, 0x33, 0xcb, 0xc8, 0xf3, 0x8d, 0xba, 0x21, 0xca, 0x7b, 0xb0, 0x19,
- 0xe6, 0x76, 0xd3, 0x83, 0x09, 0x0d, 0xbe, 0xcd, 0xa6, 0x5b, 0x7e, 0x33,
- 0x1f, 0x90, 0xba, 0xd5, 0xfa, 0xd6, 0xcc, 0x45, 0xfa, 0x57, 0xee, 0xf7,
- 0xc1, 0xe6, 0xfc, 0xbd, 0xdf, 0xda, 0xe3, 0xab, 0x54, 0xfe, 0xfe, 0x77,
- 0x2e, 0x0e, 0x85, 0x75, 0xa7, 0xf2, 0x73, 0xe1, 0x52, 0x2a, 0xf9, 0x63,
- 0x05, 0x2c, 0x2d, 0x68, 0xa5, 0x99, 0x0e, 0x6d, 0x4e, 0x35, 0xd2, 0xdf,
- 0x02, 0x8c, 0x95, 0x51, 0xe2, 0x3b, 0x79, 0x2f, 0xfb, 0x2c, 0x30, 0x7c,
- 0x58, 0x9c, 0xa8, 0x71, 0xe5, 0xf4, 0xa7, 0x12, 0xc3, 0x5c, 0x8c, 0xe9,
- 0xc2, 0xf1, 0xae, 0xe6, 0xdc, 0xd5, 0xfa, 0x07, 0x94, 0xbb, 0xc8, 0x30,
- 0xea, 0x8a, 0x94, 0x6a, 0xfd, 0xdd, 0x4c, 0x94, 0x3e, 0xde, 0xce, 0x7e,
- 0x7d, 0x78, 0x37, 0x51, 0xc6, 0x1c, 0x24, 0x18, 0xb3, 0xd8, 0xe0, 0x92,
- 0xe6, 0x00, 0xc8, 0xf9, 0xa6, 0xfc, 0xb5, 0x81, 0xf1, 0x5f, 0x62, 0xb4,
- 0x7a, 0xdb, 0xdc, 0x08, 0x36, 0x64, 0xe0, 0x5e, 0xd7, 0x1c, 0xc5, 0x7a,
- 0xc6, 0xf6, 0x87, 0x18, 0x2f, 0x37, 0x32, 0x16, 0xee, 0x0a, 0x73, 0x6c,
- 0x15, 0xb6, 0x5d, 0x68, 0x74, 0x49, 0x3e, 0x83, 0x5e, 0xc6, 0xe2, 0xb5,
- 0x8c, 0x2f, 0x5b, 0x78, 0x7d, 0x2a, 0xf3, 0xcf, 0xf6, 0x43, 0xcc, 0xa7,
- 0x5e, 0xba, 0xa2, 0x4d, 0xa8, 0xc3, 0x46, 0x7d, 0xdd, 0x56, 0xc6, 0x62,
- 0xb6, 0x6b, 0x95, 0x45, 0x6d, 0xfb, 0x86, 0x50, 0x30, 0xe6, 0x51, 0x4c,
- 0xbc, 0x38, 0x3a, 0x61, 0xeb, 0xd3, 0x25, 0x97, 0xca, 0xc7, 0x41, 0x19,
- 0xab, 0xe4, 0x08, 0x82, 0x0f, 0x92, 0x27, 0x4c, 0xc5, 0x08, 0x15, 0x4b,
- 0x06, 0x25, 0x4f, 0x08, 0x60, 0x65, 0xe2, 0xbb, 0x78, 0xb1, 0xc1, 0x8d,
- 0x56, 0xe6, 0x58, 0xb7, 0x25, 0x7c, 0x58, 0x41, 0x2c, 0x5d, 0x9a, 0x60,
- 0xee, 0xa4, 0xf9, 0xb1, 0x2c, 0xe1, 0xc6, 0xb1, 0x06, 0xe6, 0x40, 0xfe,
- 0x42, 0x7c, 0x64, 0xba, 0x70, 0xdc, 0xd4, 0x90, 0x76, 0xfc, 0x61, 0x17,
- 0x31, 0x90, 0x7a, 0x54, 0x25, 0x77, 0x10, 0x1d, 0xba, 0xa8, 0x4f, 0x15,
- 0xf1, 0x4b, 0x3a, 0xfc, 0xb2, 0x5c, 0x40, 0xe4, 0x92, 0x7c, 0xe0, 0x37,
- 0x76, 0x7c, 0xba, 0xd4, 0x87, 0xe5, 0x8b, 0xca, 0x38, 0x84, 0xdf, 0x12,
- 0x27, 0x47, 0x4d, 0x72, 0xbb, 0xa9, 0x43, 0x3d, 0x4f, 0x6e, 0x5d, 0x8e,
- 0xb7, 0x0c, 0xe1, 0xd6, 0x6f, 0x42, 0xa3, 0xef, 0xf6, 0x8c, 0x86, 0x3a,
- 0xce, 0x2b, 0x2e, 0x9c, 0x32, 0xca, 0xc8, 0xfb, 0x38, 0x0f, 0xa3, 0x70,
- 0x6f, 0x9d, 0x6b, 0x22, 0x39, 0xda, 0x1d, 0x29, 0xe5, 0x78, 0xdd, 0x73,
- 0x73, 0x9c, 0xe8, 0xeb, 0xd4, 0xed, 0x9a, 0xb0, 0xc3, 0x89, 0x72, 0x7c,
- 0x40, 0xb3, 0xed, 0x77, 0x0c, 0xd1, 0x33, 0x70, 0x78, 0x52, 0xc7, 0x07,
- 0x79, 0xdd, 0x33, 0xa9, 0xe3, 0x2d, 0x6c, 0x8f, 0xfe, 0x87, 0x6d, 0x57,
- 0xf0, 0x18, 0x1d, 0xcc, 0x29, 0xc9, 0x6f, 0x88, 0xc3, 0xc4, 0x95, 0x18,
- 0x75, 0xfc, 0x72, 0x66, 0x83, 0xe0, 0x36, 0xa7, 0xbb, 0xd1, 0xc1, 0xef,
- 0x98, 0x7a, 0x98, 0x76, 0x20, 0x7a, 0x78, 0x6b, 0x32, 0xb7, 0xb1, 0xed,
- 0x01, 0x53, 0x74, 0x9c, 0xcf, 0xcb, 0x44, 0xd7, 0x37, 0x4a, 0x8e, 0xd5,
- 0x03, 0x7c, 0xc1, 0xb2, 0x2e, 0xe2, 0xee, 0x42, 0xfc, 0xa0, 0x4d, 0x6c,
- 0xa7, 0xd4, 0x89, 0x95, 0xf3, 0x6b, 0x6d, 0x3b, 0xdc, 0xa4, 0xe3, 0x82,
- 0x51, 0x1f, 0x69, 0x54, 0x67, 0x51, 0xd6, 0x28, 0xf6, 0x91, 0x0f, 0x74,
- 0xa7, 0x66, 0x22, 0xe6, 0x17, 0x5b, 0x43, 0x47, 0x41, 0x0e, 0xc3, 0x71,
- 0x26, 0x61, 0xd4, 0x6d, 0xc3, 0x0c, 0x1c, 0xf0, 0xb7, 0x90, 0xc7, 0xa9,
- 0x2d, 0x4c, 0xff, 0xc9, 0x9f, 0x0c, 0x6b, 0x07, 0xce, 0xda, 0x69, 0xbf,
- 0xcd, 0x38, 0x49, 0x18, 0xa0, 0x2e, 0x5f, 0xd1, 0x5c, 0x78, 0xb5, 0xee,
- 0x9a, 0x49, 0xbe, 0x29, 0x9c, 0xe5, 0x3d, 0xfb, 0x98, 0x5f, 0xfa, 0x62,
- 0x9e, 0xa7, 0x2e, 0x73, 0x49, 0x1e, 0xe8, 0x36, 0xa4, 0x6d, 0xe6, 0x0b,
- 0x63, 0x57, 0xcb, 0x30, 0x61, 0x4f, 0xf8, 0x45, 0x86, 0xa0, 0xa6, 0xab,
- 0x7f, 0x6c, 0x1e, 0xaf, 0xc3, 0xcf, 0x35, 0x37, 0x7c, 0xe4, 0xc5, 0xaf,
- 0xf9, 0x73, 0x6d, 0xf4, 0x9a, 0xe3, 0x33, 0x4a, 0x1d, 0xac, 0x3c, 0xa2,
- 0x24, 0x89, 0x0f, 0xe3, 0x1e, 0x68, 0xe5, 0x51, 0xb7, 0xae, 0x11, 0x13,
- 0x36, 0x13, 0x13, 0x2c, 0x62, 0x42, 0x5f, 0xe6, 0x88, 0x92, 0xca, 0x7c,
- 0x46, 0x5d, 0x48, 0x1d, 0xb1, 0x9d, 0x2d, 0x94, 0xe5, 0x27, 0x36, 0xaa,
- 0x44, 0x9e, 0x0b, 0xbc, 0xdf, 0x42, 0x1e, 0x92, 0x97, 0x53, 0x7c, 0x95,
- 0x10, 0x54, 0x2c, 0xcf, 0x52, 0xb9, 0xdf, 0xaa, 0x5c, 0xcf, 0x70, 0x4b,
- 0xb9, 0xee, 0xb1, 0xa3, 0x4b, 0xdd, 0x58, 0x80, 0xd9, 0xe1, 0x85, 0x8b,
- 0x44, 0x17, 0x6a, 0x34, 0xa6, 0x7b, 0x61, 0x55, 0xb9, 0x88, 0xe5, 0xef,
- 0x35, 0x34, 0x60, 0x11, 0x73, 0xce, 0xb3, 0x04, 0xa7, 0x6e, 0xc3, 0x85,
- 0x71, 0xea, 0xe7, 0x69, 0x53, 0xd6, 0x1b, 0x6c, 0xdc, 0x16, 0xb6, 0xe2,
- 0xf4, 0x78, 0xab, 0x94, 0xb6, 0x57, 0x6c, 0x08, 0x4f, 0x28, 0x43, 0x49,
- 0xd4, 0x5d, 0x77, 0x16, 0x41, 0x73, 0x17, 0x79, 0x92, 0x5e, 0x31, 0x3b,
- 0xe2, 0xa1, 0xe6, 0x5e, 0x4f, 0x84, 0x22, 0xc7, 0x95, 0x9c, 0x3f, 0xbd,
- 0x4c, 0xdb, 0x78, 0x2b, 0x61, 0x74, 0x16, 0xba, 0x72, 0xbf, 0xdf, 0x70,
- 0xf2, 0xd9, 0xbc, 0x3f, 0x05, 0x26, 0x71, 0xc7, 0xeb, 0x3d, 0x93, 0xc0,
- 0x79, 0xb5, 0x59, 0xf2, 0x5a, 0x9c, 0xdf, 0x6c, 0x8e, 0x2b, 0x1e, 0xa3,
- 0x8c, 0xfa, 0x10, 0x2c, 0x2e, 0x20, 0xa7, 0x14, 0xee, 0xe0, 0xf5, 0x9e,
- 0x65, 0x19, 0x72, 0xc2, 0x89, 0xba, 0xf9, 0xf5, 0x11, 0x2f, 0x62, 0x56,
- 0x21, 0xfd, 0xba, 0x34, 0xea, 0xf7, 0xde, 0x98, 0xb5, 0xaa, 0x7c, 0xf4,
- 0x8b, 0x12, 0xe6, 0xbb, 0xb3, 0x93, 0x0b, 0xcb, 0x24, 0x57, 0xdc, 0x38,
- 0xca, 0x91, 0x55, 0xf6, 0x57, 0xa9, 0x51, 0x59, 0xc3, 0xd0, 0xe0, 0xa9,
- 0xdc, 0x78, 0x8b, 0x1a, 0x9d, 0x40, 0x7b, 0xb3, 0xb7, 0x25, 0x92, 0x85,
- 0xb7, 0x22, 0xba, 0x09, 0xe1, 0xa4, 0xe4, 0xad, 0x82, 0xb1, 0xb1, 0xad,
- 0x44, 0xbd, 0xaa, 0xf2, 0x79, 0xf9, 0xb9, 0x82, 0x5a, 0x16, 0x95, 0xfc,
- 0x55, 0x6f, 0x79, 0xc3, 0xc1, 0x62, 0x8d, 0xf9, 0xc6, 0xaf, 0x02, 0xff,
- 0x77, 0xf5, 0x5b, 0xdd, 0x32, 0x77, 0x1e, 0x43, 0xbe, 0x65, 0xdd, 0x00,
- 0x6e, 0x95, 0x58, 0xda, 0x3d, 0xe2, 0x66, 0x7e, 0x26, 0xf3, 0x25, 0xf1,
- 0xf8, 0xc8, 0xbd, 0x2f, 0xd1, 0xdf, 0x3c, 0xd4, 0xfd, 0x0e, 0xc3, 0x62,
- 0x98, 0xb0, 0x6d, 0x23, 0x1c, 0x0c, 0x14, 0x28, 0x3a, 0xb6, 0x37, 0xfc,
- 0x13, 0xed, 0x0b, 0xc4, 0x41, 0x90, 0x98, 0x97, 0x61, 0xcb, 0x48, 0xc1,
- 0x94, 0x7a, 0x91, 0xfb, 0xf2, 0xf5, 0x7a, 0x0d, 0x2b, 0x2e, 0xf5, 0x86,
- 0xc3, 0xc1, 0xf6, 0x6d, 0xac, 0xb7, 0x93, 0xf5, 0x62, 0x8c, 0xbd, 0xeb,
- 0x47, 0x35, 0x27, 0x1f, 0xb4, 0x46, 0x8a, 0xa7, 0xf6, 0x77, 0xa9, 0xde,
- 0x93, 0x86, 0x35, 0xee, 0xf4, 0xd7, 0x14, 0xec, 0x2c, 0x70, 0xb9, 0x91,
- 0x64, 0xbd, 0x71, 0xd6, 0x7b, 0x77, 0x54, 0xd6, 0x33, 0x70, 0xcb, 0x48,
- 0x22, 0x35, 0xe1, 0x32, 0x0c, 0xed, 0x1d, 0xc4, 0x88, 0xd9, 0xce, 0x5c,
- 0xde, 0x72, 0x28, 0xd3, 0x85, 0xed, 0xc6, 0xd1, 0x70, 0x21, 0xeb, 0x1d,
- 0x37, 0x8e, 0x06, 0x3c, 0xf4, 0x99, 0x75, 0x6c, 0xaf, 0x9b, 0x79, 0x91,
- 0x4a, 0x8c, 0xdc, 0x32, 0x22, 0xdc, 0xc1, 0xc4, 0x6c, 0xe6, 0x67, 0x8e,
- 0x6d, 0xca, 0xda, 0x09, 0x64, 0x4e, 0x65, 0x7c, 0xc1, 0xba, 0x11, 0x67,
- 0x7c, 0xca, 0x35, 0x87, 0x25, 0x57, 0xae, 0xb0, 0xb0, 0xb9, 0x41, 0xe2,
- 0xa7, 0x42, 0xec, 0x0e, 0xd6, 0x8d, 0x33, 0x9e, 0x6c, 0x1b, 0xfb, 0x33,
- 0x8c, 0x6b, 0x95, 0xcc, 0x65, 0x6d, 0xfb, 0x15, 0x63, 0x61, 0x05, 0x43,
- 0xbc, 0xd7, 0x4b, 0x99, 0xbd, 0xa1, 0x62, 0x89, 0xd3, 0x4e, 0x5b, 0x31,
- 0x08, 0x3e, 0x29, 0x48, 0x1a, 0xd6, 0x06, 0x91, 0xff, 0x58, 0x38, 0x18,
- 0x3f, 0xac, 0xd4, 0xb7, 0x6f, 0xc3, 0x3f, 0x11, 0x2f, 0x41, 0xac, 0x9b,
- 0x89, 0x21, 0x93, 0xd6, 0xd2, 0x66, 0x31, 0x42, 0x4a, 0x8c, 0x77, 0x9f,
- 0x58, 0xc4, 0x08, 0xe7, 0x46, 0xb0, 0xb3, 0x95, 0xe5, 0x23, 0xb9, 0x75,
- 0x16, 0x5c, 0x18, 0x0d, 0x32, 0x0e, 0x8b, 0x2e, 0x80, 0xad, 0x99, 0x7c,
- 0x2c, 0xb0, 0xed, 0x83, 0xa6, 0x6d, 0xbf, 0x64, 0xce, 0xc4, 0x61, 0x33,
- 0x18, 0x17, 0x1f, 0x78, 0xdf, 0x5c, 0x78, 0x83, 0xe4, 0xc5, 0x80, 0xc8,
- 0xa6, 0x30, 0x76, 0x29, 0x28, 0xe1, 0x27, 0x10, 0x72, 0xeb, 0x25, 0x8a,
- 0x0d, 0x6f, 0x53, 0x6d, 0x67, 0x2d, 0xf5, 0x5e, 0x36, 0x5f, 0xc1, 0x27,
- 0x37, 0x2a, 0x38, 0x7a, 0x63, 0x28, 0x30, 0xa4, 0x94, 0x32, 0x2e, 0x84,
- 0xda, 0x5a, 0x14, 0xeb, 0x04, 0xeb, 0xc6, 0x1a, 0x5c, 0xc1, 0x00, 0x94,
- 0x72, 0x62, 0xd6, 0x6c, 0x5d, 0x68, 0x8b, 0xbb, 0x37, 0x14, 0xd8, 0xc9,
- 0x6f, 0xd7, 0xa8, 0x82, 0x51, 0x23, 0x18, 0x83, 0xd3, 0x3e, 0xfb, 0x66,
- 0xca, 0x7c, 0x53, 0xc8, 0xb6, 0x4f, 0x86, 0xeb, 0xb5, 0x93, 0x78, 0x9f,
- 0xb8, 0x2c, 0xfd, 0xe4, 0x65, 0x03, 0xf3, 0x70, 0x23, 0xd6, 0xa2, 0xdc,
- 0x24, 0xb4, 0x84, 0x71, 0x52, 0x62, 0x79, 0x5e, 0xde, 0x7c, 0x4c, 0xb7,
- 0xed, 0xf7, 0xcd, 0x5c, 0x5b, 0x5a, 0x73, 0x30, 0x0e, 0xcc, 0xc4, 0x98,
- 0x11, 0x6c, 0x1d, 0xa7, 0x1e, 0x02, 0xf4, 0xf5, 0x19, 0x46, 0x15, 0x26,
- 0x3c, 0x41, 0x6d, 0x42, 0x59, 0xf4, 0x99, 0x8a, 0x39, 0x1b, 0x9e, 0x52,
- 0xea, 0x3b, 0x8a, 0x60, 0x90, 0x9f, 0x5e, 0x23, 0xf3, 0x11, 0xf0, 0x91,
- 0x0b, 0xae, 0x83, 0xc3, 0x2f, 0x70, 0x7b, 0xc2, 0x1d, 0xbb, 0x80, 0x1a,
- 0xfa, 0x9d, 0xd1, 0xfe, 0x90, 0x12, 0x64, 0xf2, 0xf2, 0x35, 0x26, 0x38,
- 0x22, 0x6b, 0x15, 0xe2, 0xf7, 0xd8, 0xf6, 0xc3, 0x94, 0x75, 0x17, 0x65,
- 0xdd, 0x18, 0xfe, 0xd8, 0xfe, 0x07, 0xa7, 0xcd, 0x5b, 0x31, 0x64, 0x5c,
- 0xdd, 0xee, 0x47, 0x36, 0xa6, 0x4b, 0xbb, 0x1e, 0x2c, 0x99, 0xce, 0x5c,
- 0xab, 0x59, 0xf0, 0xaa, 0xd2, 0x43, 0x7c, 0x62, 0x7b, 0x8c, 0x7f, 0xea,
- 0xd5, 0x1c, 0xc2, 0x05, 0xc6, 0xe6, 0x40, 0x5c, 0x51, 0xab, 0x4b, 0xa0,
- 0xc1, 0x6b, 0xd8, 0x78, 0x84, 0x7c, 0x27, 0x36, 0xbd, 0x1c, 0xdf, 0xe4,
- 0x9c, 0x96, 0x86, 0xd4, 0x6b, 0x5d, 0x9c, 0x93, 0xc3, 0x61, 0xf9, 0xed,
- 0xc1, 0xf8, 0x74, 0x17, 0xba, 0x38, 0xcb, 0x5a, 0x48, 0x9d, 0x21, 0xf7,
- 0xbd, 0x8d, 0xf2, 0x9b, 0xf2, 0x5f, 0xa3, 0xe0, 0x61, 0x5a, 0xa4, 0x1a,
- 0xea, 0x0e, 0xc8, 0xfd, 0x56, 0x53, 0x7e, 0x2b, 0xe4, 0x92, 0x6e, 0xce,
- 0x8b, 0x0d, 0x97, 0x2c, 0x4d, 0x84, 0x78, 0x3f, 0x2c, 0xd7, 0xb1, 0x87,
- 0x39, 0xee, 0xd8, 0x01, 0x45, 0x30, 0xee, 0x97, 0xf6, 0x2b, 0x8c, 0x81,
- 0x1a, 0x9f, 0x7f, 0x93, 0x7d, 0x9f, 0x08, 0xbf, 0x64, 0xcf, 0xa8, 0x50,
- 0x70, 0x32, 0xa2, 0x63, 0xe6, 0x8d, 0xd5, 0x98, 0xb8, 0x5b, 0xc6, 0xac,
- 0xa0, 0xd4, 0x38, 0xe8, 0x91, 0x1c, 0xb9, 0xcc, 0xb8, 0x06, 0x4b, 0x56,
- 0xe4, 0xee, 0x15, 0x85, 0x64, 0x8d, 0x53, 0x47, 0xd1, 0x8d, 0x95, 0xd0,
- 0x27, 0xef, 0x2d, 0x0a, 0xb9, 0xdb, 0x4a, 0x15, 0x43, 0xbb, 0x5d, 0x91,
- 0xe7, 0xbf, 0x23, 0x2f, 0xb7, 0xed, 0x47, 0x38, 0x5f, 0xb3, 0xc3, 0x3e,
- 0x9c, 0x63, 0x3f, 0xdd, 0xd4, 0xdf, 0xf2, 0x4b, 0xf3, 0x95, 0xaf, 0xff,
- 0xa9, 0xad, 0xdf, 0x23, 0x75, 0xa5, 0x8d, 0xda, 0xd6, 0x25, 0xca, 0x03,
- 0x1e, 0xc9, 0x91, 0x36, 0x86, 0x1d, 0x9d, 0xb1, 0xec, 0x73, 0xce, 0x6f,
- 0xad, 0xf9, 0xad, 0x4b, 0xeb, 0x75, 0xe7, 0x9d, 0x58, 0xba, 0x70, 0xbe,
- 0x86, 0x09, 0xbb, 0xa2, 0xd1, 0xd2, 0x0a, 0x21, 0x31, 0xb5, 0xa6, 0xee,
- 0x39, 0xb6, 0xfb, 0x73, 0x33, 0x17, 0x6f, 0x0f, 0x9a, 0xc1, 0x3e, 0x8b,
- 0xfe, 0x13, 0x67, 0x8e, 0xdb, 0x22, 0xbc, 0x63, 0xec, 0x16, 0xce, 0xc3,
- 0x4c, 0x14, 0x36, 0x06, 0x7b, 0x66, 0x31, 0xe7, 0x73, 0x35, 0x4b, 0x9c,
- 0x96, 0xf9, 0x71, 0xca, 0xb0, 0xaf, 0x22, 0x2c, 0xa2, 0x8c, 0xe1, 0xc6,
- 0x3f, 0x15, 0xdf, 0xa4, 0x1d, 0xb1, 0xce, 0x60, 0x4f, 0x0c, 0x7f, 0xaa,
- 0x2c, 0xc8, 0x28, 0x64, 0x2d, 0xcc, 0x7b, 0x4b, 0x3c, 0xa3, 0x92, 0x23,
- 0x15, 0x68, 0xdd, 0xcd, 0x55, 0xfc, 0xc8, 0x73, 0xf7, 0x2d, 0x6b, 0x32,
- 0x97, 0xd6, 0x20, 0xd1, 0x67, 0x16, 0x40, 0xbd, 0x49, 0xe2, 0x05, 0x7d,
- 0x59, 0x93, 0xf1, 0x59, 0xb4, 0x72, 0x59, 0x5f, 0x30, 0x56, 0xad, 0x25,
- 0x5e, 0xbc, 0xc8, 0x1e, 0x87, 0xc9, 0xc5, 0x2c, 0xc7, 0x33, 0x9c, 0xf8,
- 0x37, 0x65, 0x4d, 0x52, 0xe2, 0x57, 0x7e, 0x5d, 0xb3, 0x12, 0xfd, 0x7b,
- 0x57, 0x40, 0xaf, 0xca, 0x61, 0xa0, 0x1a, 0x6d, 0xc2, 0xc2, 0xbe, 0x40,
- 0x41, 0x2e, 0x7f, 0x28, 0x43, 0xef, 0xde, 0x30, 0xd2, 0xd3, 0x9d, 0xfa,
- 0xbc, 0xe7, 0x85, 0x60, 0xf4, 0xf6, 0xbd, 0xd7, 0xca, 0x7a, 0x40, 0x40,
- 0xda, 0x8d, 0xd3, 0x77, 0x54, 0xe3, 0x43, 0xdb, 0xd2, 0xa4, 0xfd, 0xa3,
- 0x37, 0x10, 0x47, 0xcc, 0xc5, 0xa8, 0x6f, 0x3f, 0x84, 0x33, 0xe4, 0xa4,
- 0x4e, 0xbe, 0xa4, 0x17, 0x46, 0xc7, 0x1f, 0xf6, 0x20, 0x14, 0x1f, 0x21,
- 0x0e, 0xf8, 0x46, 0xbd, 0xe4, 0x56, 0x33, 0x9d, 0x75, 0xaf, 0x85, 0xc4,
- 0x96, 0x38, 0x79, 0xf9, 0xd7, 0xdc, 0x6e, 0xac, 0x25, 0x66, 0x1c, 0x34,
- 0xea, 0x3b, 0x0e, 0xe1, 0x1f, 0x89, 0xb3, 0x52, 0x5e, 0x65, 0x7f, 0xd2,
- 0xa6, 0x9b, 0xfd, 0xc1, 0x4b, 0x2e, 0x70, 0x2f, 0xf9, 0xac, 0xdb, 0x63,
- 0xfc, 0xc4, 0x23, 0xbc, 0x43, 0x78, 0xf7, 0xae, 0xbd, 0x0a, 0x5a, 0xd8,
- 0xce, 0x4e, 0xda, 0xcc, 0xc3, 0x21, 0xb8, 0x5b, 0x6f, 0x24, 0xbf, 0x02,
- 0x5d, 0x70, 0xba, 0x0f, 0x3b, 0x46, 0x10, 0xc9, 0x18, 0xe3, 0x33, 0x7c,
- 0xa8, 0x62, 0x3b, 0x12, 0x53, 0x0a, 0x26, 0xdb, 0x89, 0xdc, 0x77, 0x65,
- 0x3b, 0x65, 0x78, 0x72, 0xb2, 0x9d, 0x7d, 0x6c, 0xe7, 0xe6, 0xd9, 0x70,
- 0x97, 0xdd, 0x2c, 0x73, 0xd5, 0x40, 0xff, 0x29, 0x43, 0xca, 0x89, 0x2b,
- 0xe4, 0xa3, 0x5f, 0x85, 0x62, 0xd4, 0x4a, 0xee, 0x72, 0xd6, 0xa9, 0xb7,
- 0xb8, 0x61, 0xfc, 0x02, 0x69, 0x91, 0x72, 0x7e, 0xf6, 0x38, 0x1d, 0x35,
- 0xaf, 0x9b, 0x2a, 0x6c, 0xdd, 0x5b, 0x9c, 0x97, 0x97, 0xfd, 0xe4, 0xfb,
- 0xa8, 0xe4, 0x3d, 0x3f, 0x76, 0x30, 0x07, 0x5d, 0xcc, 0x7e, 0x0e, 0x9b,
- 0xc2, 0x23, 0xeb, 0xcd, 0x22, 0x45, 0x72, 0xf2, 0x00, 0x39, 0x45, 0x25,
- 0x36, 0x3b, 0x71, 0x28, 0xc0, 0xfa, 0x0d, 0x65, 0x39, 0x7e, 0x02, 0xcf,
- 0x32, 0x96, 0x6d, 0x09, 0xe7, 0xfa, 0x23, 0x0e, 0x33, 0xcf, 0x6d, 0xc4,
- 0xc1, 0xc1, 0x4b, 0xcf, 0x83, 0x8b, 0x8d, 0xa9, 0xf3, 0x35, 0x1e, 0xf4,
- 0xa0, 0x8d, 0xdf, 0x05, 0x12, 0x67, 0xae, 0x18, 0xfb, 0x96, 0x91, 0x47,
- 0xf8, 0x5d, 0x8c, 0xad, 0x23, 0x36, 0xb6, 0x38, 0x39, 0x4e, 0x01, 0xba,
- 0x1b, 0x04, 0x0f, 0xc5, 0x96, 0xa6, 0x4b, 0xec, 0x88, 0xa4, 0x21, 0xf1,
- 0x55, 0xec, 0x27, 0xea, 0xd8, 0x8f, 0x4b, 0x99, 0x6a, 0x3f, 0x5d, 0x78,
- 0xcd, 0x38, 0xba, 0xa2, 0x10, 0x47, 0xef, 0x97, 0xb5, 0xfb, 0x8e, 0x30,
- 0x8e, 0xdd, 0x46, 0xdf, 0x7c, 0x97, 0xd8, 0xb2, 0x65, 0x36, 0xe3, 0x97,
- 0x83, 0x59, 0x0a, 0x0a, 0xc9, 0x2b, 0xb6, 0xed, 0x0d, 0xea, 0x05, 0xaa,
- 0xc6, 0x3e, 0xaf, 0xc6, 0x2e, 0x91, 0xdf, 0x64, 0x9e, 0x7e, 0xf4, 0xb1,
- 0x42, 0xf8, 0x24, 0x5f, 0x7a, 0xfb, 0x0c, 0xdb, 0x58, 0x6c, 0xe6, 0x75,
- 0xe5, 0xe8, 0x69, 0xb2, 0x9d, 0x4a, 0x24, 0xf7, 0xe6, 0xeb, 0x2b, 0x38,
- 0x15, 0x0a, 0x4c, 0xae, 0x9d, 0x57, 0xa2, 0x77, 0xe4, 0xe8, 0x49, 0xf2,
- 0x1c, 0xc6, 0xa9, 0xa3, 0x9d, 0x01, 0xca, 0x72, 0x3e, 0x9c, 0x9f, 0x53,
- 0xf1, 0xcd, 0xa9, 0x6d, 0x88, 0xed, 0x42, 0x29, 0xab, 0xc5, 0x96, 0x32,
- 0xda, 0x68, 0x26, 0x84, 0x78, 0x49, 0xb4, 0x0c, 0x89, 0x11, 0xfa, 0xd6,
- 0x68, 0x01, 0xdc, 0xf3, 0x24, 0xee, 0x0a, 0xd7, 0x72, 0xdf, 0x72, 0x3a,
- 0x51, 0x80, 0x07, 0xcc, 0x8b, 0xb6, 0xe0, 0xe2, 0x49, 0x03, 0xd7, 0x15,
- 0x10, 0x13, 0x6b, 0xc3, 0xa1, 0xd8, 0x3a, 0xe6, 0xb4, 0xc7, 0x1b, 0xdc,
- 0xb7, 0x7c, 0x90, 0xf9, 0x3d, 0x79, 0xf1, 0xd5, 0xe3, 0x11, 0x7d, 0xe0,
- 0xc4, 0xd2, 0x90, 0xf4, 0x29, 0xfd, 0xe5, 0x6d, 0x54, 0xfa, 0xb7, 0xed,
- 0x50, 0xd8, 0xe7, 0xcc, 0x79, 0x7e, 0x0c, 0xef, 0x19, 0xf9, 0x31, 0xf8,
- 0x9c, 0xf8, 0xcd, 0x1c, 0x98, 0x98, 0x23, 0x79, 0xc1, 0x11, 0xe5, 0xa8,
- 0x93, 0x03, 0x5b, 0x31, 0xe6, 0xbe, 0x91, 0x9e, 0xc9, 0xdc, 0x77, 0x9c,
- 0x3c, 0xf7, 0x38, 0x79, 0xee, 0xcb, 0x93, 0xb9, 0xef, 0x8b, 0x19, 0xa9,
- 0x33, 0xb5, 0x7c, 0x24, 0x26, 0x6b, 0xd6, 0x23, 0x89, 0x50, 0x5d, 0xbe,
- 0xce, 0xcb, 0x2c, 0x7f, 0xfc, 0x52, 0xf9, 0xd5, 0xcc, 0x57, 0x57, 0x61,
- 0x5b, 0xaa, 0x04, 0x0f, 0x6a, 0x4e, 0x6e, 0xe9, 0x2d, 0x8c, 0x9e, 0xb8,
- 0xef, 0x7d, 0x63, 0xbc, 0xce, 0x45, 0x1c, 0x1a, 0xe1, 0xe0, 0x5b, 0x12,
- 0x0a, 0xfd, 0xce, 0x83, 0x1e, 0xad, 0x1c, 0x6b, 0xcd, 0x7f, 0xb2, 0x1f,
- 0x5c, 0x25, 0xcf, 0xf2, 0x7b, 0x14, 0x52, 0xfe, 0x35, 0x96, 0x0f, 0x9a,
- 0x23, 0x93, 0xb9, 0xe0, 0xd1, 0x04, 0xfa, 0x24, 0xcf, 0x5a, 0xd3, 0x1c,
- 0xd2, 0xbb, 0x9d, 0x75, 0x63, 0x1d, 0xeb, 0x32, 0x3a, 0xd6, 0x53, 0x9e,
- 0xb4, 0x7b, 0x32, 0x47, 0xca, 0xc5, 0x62, 0x4b, 0x78, 0xe6, 0x22, 0x96,
- 0xdb, 0x3c, 0x89, 0x33, 0x2d, 0x97, 0x78, 0xae, 0x6d, 0xf7, 0x9b, 0x79,
- 0xae, 0xcb, 0x58, 0x50, 0x29, 0xb9, 0x35, 0x68, 0x17, 0x15, 0x48, 0xfb,
- 0x65, 0x4f, 0x66, 0xea, 0x18, 0x11, 0x2b, 0x8c, 0x86, 0xf4, 0xd9, 0xea,
- 0x54, 0xec, 0x92, 0xb1, 0x0a, 0x6e, 0x59, 0x8e, 0x7e, 0x8e, 0x5d, 0x1a,
- 0x6f, 0x7d, 0xa1, 0x60, 0xd6, 0xc1, 0x44, 0x77, 0x01, 0x6d, 0x4b, 0x2d,
- 0x10, 0x7b, 0x40, 0xee, 0x1e, 0xb2, 0xb6, 0xbd, 0xfd, 0x0a, 0xdd, 0x15,
- 0xc4, 0x98, 0x0a, 0xe0, 0xe9, 0x44, 0x28, 0x76, 0x16, 0x96, 0x72, 0x32,
- 0xe3, 0xa6, 0xad, 0x4b, 0xbb, 0x5b, 0xd8, 0x5e, 0x8f, 0x72, 0xe2, 0x52,
- 0x9b, 0x17, 0x2e, 0x6e, 0x76, 0xd6, 0x71, 0xf3, 0xbe, 0xe2, 0xc5, 0x43,
- 0x7d, 0xf9, 0xbd, 0xc6, 0x18, 0xde, 0x33, 0x05, 0x17, 0xbd, 0xe4, 0x3d,
- 0xcc, 0xd2, 0x13, 0xdb, 0x90, 0xf3, 0x4b, 0xf9, 0xe4, 0xe7, 0xfd, 0xa0,
- 0x5b, 0x30, 0xec, 0x27, 0xb3, 0x63, 0x93, 0x6b, 0x2e, 0x7f, 0xac, 0x4c,
- 0x1e, 0xdb, 0x2f, 0x5c, 0xec, 0x4b, 0x55, 0x4f, 0xc9, 0xb3, 0x69, 0x5f,
- 0x03, 0xc1, 0x1e, 0x0b, 0x95, 0x6c, 0xc3, 0x8d, 0xbf, 0x65, 0xfc, 0x76,
- 0x0f, 0x1c, 0xbd, 0x41, 0x52, 0x32, 0xcf, 0xa1, 0x18, 0x36, 0x37, 0x7b,
- 0xe0, 0x1a, 0xaa, 0x2e, 0xcc, 0xad, 0xf3, 0x91, 0x3c, 0x3b, 0xdf, 0x8a,
- 0x83, 0xd3, 0x6a, 0x56, 0xf2, 0x6a, 0xd2, 0x88, 0x43, 0xa2, 0xd7, 0x4a,
- 0x7e, 0x8b, 0x5e, 0xfc, 0xfc, 0x16, 0x1d, 0x55, 0xf1, 0xbb, 0x1c, 0xb1,
- 0x2a, 0xd9, 0xf3, 0x6a, 0x47, 0x82, 0x98, 0x55, 0x12, 0xed, 0xc4, 0xd7,
- 0x7b, 0x6d, 0xbb, 0x87, 0x7e, 0x59, 0xc4, 0x18, 0xff, 0x48, 0xa8, 0x3e,
- 0x32, 0x47, 0x29, 0x20, 0xdf, 0x69, 0x47, 0xcf, 0x48, 0x41, 0xbc, 0x3c,
- 0x5a, 0xc5, 0x98, 0xae, 0xe1, 0x93, 0xb9, 0x6d, 0xc8, 0x8e, 0x5e, 0xbd,
- 0x57, 0x36, 0x75, 0x9f, 0x2c, 0xbf, 0x3f, 0x26, 0xe3, 0x11, 0xb9, 0x45,
- 0xfe, 0x0b, 0x17, 0xb7, 0xa6, 0x44, 0x36, 0x0f, 0x0e, 0xf4, 0x89, 0xbc,
- 0x36, 0x3a, 0xcc, 0x5b, 0x29, 0x27, 0x91, 0xbe, 0x72, 0xea, 0xfc, 0xe6,
- 0xdb, 0x91, 0x75, 0xf0, 0x4e, 0x65, 0x98, 0xf3, 0x65, 0xb9, 0x0b, 0xc5,
- 0xbf, 0x34, 0xe6, 0x15, 0xca, 0x73, 0x19, 0x69, 0xa3, 0x45, 0x19, 0x49,
- 0x4f, 0xad, 0xd3, 0xa9, 0x1c, 0xca, 0x3c, 0x5c, 0x28, 0x9c, 0xe3, 0xb2,
- 0x1e, 0xf3, 0x32, 0x90, 0xdc, 0xd2, 0x5e, 0x2a, 0x92, 0xa2, 0x7f, 0xd1,
- 0x8f, 0x0e, 0x77, 0x96, 0xbf, 0xb3, 0x5f, 0xd6, 0xe7, 0xd5, 0x3e, 0x36,
- 0xf7, 0x0a, 0x9f, 0x3c, 0x4e, 0x9f, 0x1c, 0xff, 0xa3, 0x3e, 0x39, 0xef,
- 0x4f, 0x94, 0xcf, 0xaf, 0xb7, 0xda, 0xf6, 0x6e, 0x53, 0xd6, 0xe8, 0x65,
- 0xdd, 0xb5, 0xe1, 0x4b, 0xf6, 0x5e, 0x65, 0x3d, 0x7e, 0x36, 0xd2, 0x95,
- 0xc1, 0xb4, 0xac, 0xbf, 0x0c, 0xa4, 0x80, 0x45, 0x49, 0xe9, 0x27, 0x46,
- 0x7d, 0xa9, 0xb7, 0x32, 0x1a, 0x31, 0x43, 0xe8, 0xc2, 0x19, 0xd3, 0xd8,
- 0xf7, 0x20, 0x79, 0x77, 0x37, 0x73, 0xd2, 0x83, 0xe6, 0x72, 0xfa, 0x7b,
- 0x31, 0x36, 0x34, 0xd0, 0x18, 0x57, 0x98, 0xf4, 0x7b, 0xab, 0x9d, 0xae,
- 0xe8, 0xf5, 0x45, 0xdb, 0x57, 0x25, 0x42, 0xc1, 0xb6, 0x8d, 0xc4, 0xf3,
- 0xa5, 0xbd, 0x5e, 0xe8, 0x8a, 0xc3, 0x07, 0x5a, 0x7f, 0xa1, 0x0a, 0x46,
- 0x9d, 0x29, 0xc8, 0xe5, 0xcd, 0xb2, 0xe6, 0x22, 0xfd, 0x2c, 0x67, 0x5e,
- 0x22, 0x75, 0x75, 0xb4, 0xd7, 0x2a, 0x48, 0xd5, 0x06, 0xfb, 0xe0, 0xb2,
- 0xed, 0xdf, 0x91, 0x17, 0x8e, 0x3b, 0xb9, 0x7c, 0x7d, 0xdd, 0x6e, 0xf5,
- 0x7f, 0x10, 0x0b, 0x9d, 0x36, 0x34, 0x59, 0xf3, 0x7f, 0xe1, 0x4f, 0xae,
- 0x7b, 0x9b, 0x90, 0xbd, 0x89, 0x42, 0x63, 0x89, 0x32, 0xe2, 0xcf, 0x71,
- 0x8a, 0xdb, 0x06, 0x3e, 0xbf, 0xf8, 0x64, 0x4a, 0xec, 0x1c, 0x55, 0x01,
- 0x63, 0x06, 0x66, 0x1f, 0x28, 0xc5, 0xb2, 0x01, 0xe1, 0x0a, 0x3e, 0xab,
- 0x30, 0x1a, 0xc0, 0x9c, 0x03, 0x95, 0x68, 0xd9, 0x23, 0xfb, 0x50, 0x76,
- 0x57, 0x45, 0x74, 0x35, 0xdc, 0x87, 0x34, 0x3c, 0xb0, 0xc7, 0xb6, 0x67,
- 0xcd, 0x23, 0xb5, 0x63, 0x4c, 0x7c, 0xb7, 0x69, 0x15, 0x3c, 0xd9, 0x6a,
- 0x2c, 0x49, 0xd6, 0x39, 0x6b, 0xad, 0x1f, 0x26, 0x5a, 0x5b, 0xce, 0xf5,
- 0xd6, 0x6e, 0xa8, 0x55, 0x82, 0xe6, 0x29, 0x25, 0x82, 0x82, 0x6c, 0x04,
- 0xae, 0xa4, 0x82, 0x57, 0x0d, 0x74, 0x95, 0x45, 0xa3, 0x70, 0x65, 0xa3,
- 0xf0, 0x25, 0xdd, 0x68, 0xa0, 0xbe, 0x4b, 0x38, 0xf7, 0xd3, 0x92, 0xd5,
- 0x98, 0x96, 0xbd, 0x0e, 0xfa, 0x81, 0x06, 0xfa, 0x48, 0x25, 0xfb, 0xf3,
- 0xa3, 0x25, 0xd9, 0x86, 0x69, 0x46, 0x33, 0x6d, 0xa3, 0x19, 0x33, 0x93,
- 0x7e, 0x2c, 0xe0, 0x7c, 0x2c, 0x4e, 0xb6, 0xb2, 0x1f, 0x1f, 0xda, 0x07,
- 0xee, 0x44, 0x60, 0xc8, 0x8b, 0xf2, 0x01, 0x1d, 0x1f, 0xce, 0xf5, 0xa2,
- 0x68, 0x28, 0x80, 0xd2, 0xa4, 0xec, 0x8d, 0x21, 0xb6, 0xb1, 0x39, 0x00,
- 0x5f, 0x16, 0x28, 0x19, 0xb0, 0xf1, 0xad, 0xf0, 0xa8, 0x7a, 0x77, 0xa5,
- 0x65, 0x4f, 0x73, 0x62, 0x41, 0x6b, 0xfb, 0x16, 0xe3, 0xce, 0x49, 0xbf,
- 0x77, 0x33, 0xcf, 0x52, 0xc8, 0xd7, 0x25, 0x06, 0xb6, 0xb6, 0x1f, 0x4c,
- 0xc8, 0xda, 0x46, 0x88, 0x7e, 0xeb, 0x81, 0x77, 0xa8, 0x53, 0xe9, 0xa3,
- 0xed, 0xa0, 0x40, 0xf4, 0xaf, 0xd2, 0xbf, 0xa0, 0x95, 0xd2, 0xce, 0xb7,
- 0x66, 0x5a, 0x94, 0x64, 0xba, 0x53, 0xe9, 0xcd, 0x94, 0x78, 0x51, 0x2c,
- 0xf3, 0xf2, 0x15, 0x8c, 0x36, 0x3c, 0x69, 0xa7, 0x2b, 0x9c, 0xb9, 0xb5,
- 0x3c, 0x90, 0x9c, 0xdb, 0x5a, 0x15, 0xae, 0x0d, 0x76, 0x56, 0xa8, 0xb2,
- 0x9f, 0x42, 0x1c, 0x52, 0x72, 0x7d, 0x69, 0x46, 0x12, 0xcf, 0xfa, 0x65,
- 0x7d, 0x55, 0xe6, 0xbf, 0xb5, 0x3d, 0xd1, 0x7b, 0xe1, 0xa2, 0xcc, 0xe9,
- 0xc7, 0xb4, 0xc3, 0xdb, 0x93, 0x9f, 0x5f, 0xdc, 0x97, 0x6a, 0x63, 0x9e,
- 0x66, 0xe2, 0x55, 0xfe, 0x5e, 0xc4, 0x71, 0xbf, 0x98, 0xf1, 0x61, 0x61,
- 0xb2, 0xd9, 0xd9, 0x8b, 0x5b, 0x96, 0x8c, 0xe0, 0x15, 0x7e, 0xb7, 0x24,
- 0x57, 0xe1, 0x18, 0xf3, 0xd4, 0x07, 0x92, 0x51, 0xbc, 0x9d, 0x09, 0xe0,
- 0x7e, 0xea, 0x6f, 0x06, 0xed, 0xf4, 0xae, 0xa4, 0x8e, 0x37, 0x32, 0xc0,
- 0xcf, 0xfa, 0x6c, 0x84, 0x1a, 0xbf, 0xa3, 0x3e, 0xed, 0xac, 0x8d, 0x35,
- 0xe3, 0x67, 0x09, 0x13, 0x6f, 0x24, 0x6a, 0xcc, 0x9b, 0xd5, 0xdf, 0x62,
- 0xdc, 0x9d, 0xa0, 0x4d, 0x9d, 0x47, 0xbc, 0x52, 0xd6, 0xf1, 0x72, 0xf2,
- 0x77, 0x8f, 0x79, 0x98, 0x63, 0x6d, 0xc0, 0x11, 0xbf, 0xb3, 0x2e, 0x71,
- 0x85, 0x5c, 0xb2, 0x36, 0xb1, 0x88, 0x72, 0x3d, 0x95, 0x22, 0x57, 0x34,
- 0xaa, 0x29, 0x8f, 0x17, 0x0b, 0x07, 0xbc, 0xa8, 0xa4, 0x6d, 0x9c, 0x3e,
- 0x10, 0xc5, 0xce, 0x54, 0x11, 0x5a, 0xfa, 0x03, 0x38, 0xc3, 0xeb, 0xad,
- 0xb4, 0xf1, 0x1f, 0xb1, 0x6f, 0xa3, 0x49, 0xc3, 0x80, 0x56, 0x84, 0x9e,
- 0xba, 0x1f, 0x93, 0xef, 0xa9, 0xcc, 0x39, 0x98, 0x1b, 0x18, 0x25, 0xd8,
- 0xc1, 0xb4, 0xbe, 0xb0, 0x39, 0x88, 0xfe, 0x3a, 0xda, 0x7a, 0x15, 0xe3,
- 0x87, 0x11, 0x43, 0x39, 0x31, 0x26, 0xc5, 0x5c, 0xb1, 0x30, 0x6a, 0x51,
- 0x06, 0x15, 0xfb, 0x34, 0x55, 0xd6, 0xe4, 0xf8, 0x2c, 0x80, 0x63, 0x09,
- 0xd8, 0xc5, 0x51, 0xe3, 0xc2, 0x4e, 0x84, 0x4e, 0xbc, 0xcf, 0xb8, 0xfe,
- 0xf7, 0x99, 0x12, 0x7c, 0xbf, 0x6f, 0x36, 0xfe, 0x36, 0x2d, 0xeb, 0xbd,
- 0x3e, 0xac, 0x1f, 0x0c, 0xab, 0xb9, 0xb5, 0x4a, 0x1f, 0x1e, 0x1a, 0x84,
- 0x35, 0x93, 0xf6, 0xf8, 0xf2, 0x70, 0x19, 0xd6, 0xf4, 0xbd, 0x60, 0x33,
- 0x77, 0xa6, 0x5d, 0x7b, 0x71, 0x34, 0x2d, 0x32, 0x96, 0x53, 0xc6, 0x22,
- 0x1c, 0xe3, 0x75, 0x0f, 0x6d, 0xbf, 0xb2, 0xf7, 0xdb, 0xf8, 0x2c, 0x55,
- 0x53, 0x77, 0xbf, 0xda, 0x8e, 0xe3, 0xce, 0x7e, 0x6c, 0x03, 0xde, 0xa2,
- 0x1e, 0xcb, 0x77, 0xdb, 0xf6, 0x6f, 0xc2, 0x31, 0xfc, 0x2c, 0x73, 0x2d,
- 0x8a, 0x78, 0x6d, 0x86, 0x5b, 0xf0, 0x66, 0xa6, 0x1a, 0x65, 0xbd, 0xad,
- 0x78, 0x9d, 0x9c, 0xbf, 0x74, 0x77, 0x27, 0x4e, 0xb1, 0x7d, 0x5f, 0xbf,
- 0x17, 0xaf, 0xa5, 0xbd, 0x78, 0xb5, 0xcf, 0xd0, 0xd6, 0x2a, 0x7f, 0xa7,
- 0xc4, 0x2b, 0x73, 0xfd, 0x0c, 0xa4, 0x72, 0xfa, 0xdc, 0x3e, 0x56, 0x00,
- 0xc1, 0xf2, 0x43, 0x7e, 0x59, 0xbf, 0x95, 0xf3, 0x31, 0xad, 0xed, 0x5a,
- 0xf2, 0x77, 0x17, 0x13, 0xd4, 0xe7, 0x9b, 0xa3, 0x01, 0xdc, 0x91, 0x14,
- 0xdd, 0x7e, 0x7e, 0x71, 0x17, 0xb1, 0xa3, 0x77, 0x34, 0x82, 0x13, 0x09,
- 0x8f, 0xb3, 0xe7, 0xd8, 0x33, 0x2a, 0xfb, 0xb1, 0xdf, 0xe5, 0xdc, 0x00,
- 0x6b, 0x47, 0x73, 0x6d, 0x6d, 0x19, 0x2b, 0xa4, 0xee, 0x6e, 0xc7, 0xd3,
- 0x5a, 0x81, 0xc4, 0xdf, 0x9c, 0x8d, 0x1a, 0x41, 0xda, 0xee, 0x77, 0x9d,
- 0xf5, 0xbd, 0x81, 0x54, 0xbd, 0x36, 0x0d, 0xf9, 0x79, 0xac, 0xc1, 0x4c,
- 0xe3, 0xf7, 0xf6, 0x0b, 0x7e, 0x59, 0x77, 0x15, 0xbe, 0xd8, 0xda, 0xbe,
- 0x36, 0x21, 0xfd, 0xe8, 0xd8, 0x3c, 0x7a, 0xe1, 0x62, 0x3f, 0xf9, 0xfa,
- 0x12, 0xda, 0xc8, 0xba, 0x90, 0x1f, 0x8b, 0x6b, 0xeb, 0x50, 0x9b, 0x95,
- 0x35, 0xdd, 0x08, 0x39, 0xab, 0x89, 0x8e, 0x50, 0xd4, 0xd9, 0xd7, 0x82,
- 0x9a, 0xbf, 0xe7, 0xc5, 0xbb, 0x7f, 0xe0, 0x2b, 0xc0, 0xac, 0x81, 0x36,
- 0xf6, 0x6b, 0x63, 0x99, 0xf9, 0x0f, 0x76, 0xcb, 0x3d, 0xd2, 0x7f, 0x4d,
- 0x59, 0xee, 0x19, 0x27, 0xbc, 0x58, 0x7e, 0x37, 0xd1, 0x97, 0x1a, 0x71,
- 0xd8, 0x2f, 0x3c, 0x43, 0xfc, 0xa0, 0xb5, 0x3d, 0x4c, 0xfb, 0xd9, 0x41,
- 0x19, 0x56, 0xd0, 0x76, 0x96, 0x11, 0x17, 0xca, 0x8d, 0x0b, 0x17, 0x7b,
- 0x53, 0x26, 0xe6, 0x8c, 0xfa, 0x68, 0xcb, 0x45, 0xec, 0xaf, 0x19, 0xc6,
- 0x28, 0x71, 0x84, 0xf6, 0xbd, 0x60, 0xd4, 0x4f, 0x7b, 0xd6, 0x31, 0x7f,
- 0x54, 0x7c, 0xdc, 0x40, 0x88, 0xb1, 0xac, 0x9d, 0x75, 0x22, 0xa3, 0x15,
- 0xb8, 0x79, 0xbf, 0x1b, 0x77, 0x26, 0xc3, 0xd4, 0x4f, 0x1d, 0x63, 0xdc,
- 0x65, 0x7d, 0x6f, 0x1b, 0x9b, 0x85, 0x0a, 0xe3, 0x88, 0xfd, 0x9c, 0x83,
- 0x61, 0x85, 0x8e, 0x9e, 0x02, 0xec, 0x37, 0x90, 0x82, 0x55, 0xce, 0xf8,
- 0x72, 0x61, 0xf4, 0xb9, 0x2f, 0xe2, 0xf7, 0x8a, 0x2e, 0xa7, 0x8e, 0x47,
- 0x30, 0xe5, 0x02, 0xb1, 0x0e, 0x68, 0x7c, 0xc2, 0xc6, 0xe2, 0xc6, 0x8d,
- 0xca, 0x0f, 0x1c, 0x5b, 0x92, 0x76, 0x85, 0x3b, 0xe4, 0xf5, 0x9f, 0xd7,
- 0xf9, 0x6f, 0x0a, 0x72, 0x3a, 0xcf, 0x8f, 0x33, 0xb8, 0x4f, 0x70, 0x7a,
- 0x7d, 0x63, 0x1e, 0xa7, 0xa5, 0xbc, 0xdc, 0x5f, 0x61, 0xf7, 0x6a, 0x70,
- 0x17, 0x1a, 0x2e, 0x6c, 0xaf, 0x7b, 0x46, 0x99, 0xd0, 0xc4, 0xe7, 0x15,
- 0x62, 0xc7, 0xed, 0x36, 0xdd, 0x96, 0x76, 0xfd, 0x12, 0xcb, 0x41, 0x29,
- 0xbc, 0x34, 0x97, 0xc2, 0x3f, 0xba, 0x27, 0xe7, 0x52, 0x78, 0x6f, 0x7e,
- 0x4c, 0x79, 0x59, 0x23, 0xe4, 0x76, 0x22, 0xaf, 0xd8, 0x86, 0x94, 0x79,
- 0xb0, 0xc8, 0x59, 0x8f, 0x46, 0xf7, 0x14, 0x7b, 0xc8, 0x73, 0x18, 0xa7,
- 0x0d, 0x0d, 0x97, 0xec, 0xc1, 0x8d, 0xb6, 0xa4, 0xcc, 0x3b, 0xac, 0x62,
- 0xea, 0xa1, 0x6d, 0xd4, 0xc3, 0xf9, 0x13, 0x2e, 0xae, 0x62, 0x89, 0xb9,
- 0x5d, 0x19, 0xf7, 0xef, 0x64, 0x1b, 0x9f, 0x5f, 0x64, 0x1d, 0xde, 0xeb,
- 0xe5, 0xf5, 0x75, 0xb8, 0x9d, 0x38, 0xba, 0x36, 0x6c, 0x29, 0xb9, 0x73,
- 0x05, 0x45, 0xb8, 0x71, 0xa0, 0x12, 0x3e, 0x43, 0xd6, 0x2d, 0xfe, 0xb3,
- 0xe2, 0xab, 0x90, 0xf1, 0x3b, 0x9c, 0x81, 0x76, 0x72, 0x1d, 0x16, 0x0f,
- 0x30, 0x64, 0x3b, 0x7b, 0x04, 0x0b, 0xf1, 0x74, 0xf3, 0x75, 0x58, 0xea,
- 0x70, 0x9d, 0x10, 0x6e, 0x1a, 0x12, 0x0c, 0xed, 0x54, 0xfa, 0x89, 0x9d,
- 0x4c, 0x38, 0xe8, 0xd7, 0x31, 0xa5, 0x8f, 0x98, 0xb9, 0xcf, 0xf1, 0x11,
- 0x59, 0x2f, 0xee, 0x54, 0x52, 0x99, 0x0a, 0x8e, 0x43, 0x6c, 0xf7, 0xb2,
- 0x8c, 0x33, 0x29, 0xe3, 0x79, 0x62, 0xd1, 0xfc, 0x49, 0x19, 0x67, 0x37,
- 0x49, 0x2e, 0x2b, 0x32, 0x16, 0xa1, 0x96, 0x72, 0x54, 0x52, 0x8e, 0x63,
- 0x66, 0x85, 0x32, 0xa0, 0xe5, 0x64, 0xab, 0x61, 0xff, 0x8c, 0x39, 0x58,
- 0x63, 0xfa, 0x94, 0x65, 0xce, 0xbd, 0xbc, 0x6c, 0x9f, 0x5f, 0xec, 0x49,
- 0x7d, 0x61, 0xfb, 0x8c, 0x9c, 0x9c, 0x65, 0xfd, 0x3a, 0x4e, 0xcd, 0xbd,
- 0x0e, 0xa5, 0xfb, 0x8b, 0xd0, 0x48, 0x5c, 0xaf, 0x1f, 0x30, 0xfa, 0x36,
- 0x2a, 0x22, 0xab, 0x87, 0xbf, 0x9d, 0x75, 0x03, 0xea, 0xf3, 0xff, 0x2f,
- 0xbc, 0xd2, 0x8e, 0xdd, 0x58, 0x91, 0xcc, 0xd9, 0xb0, 0xe3, 0xbf, 0xb5,
- 0x62, 0xbf, 0xb2, 0x46, 0x48, 0x7b, 0xce, 0xb8, 0xb0, 0x84, 0x7d, 0x1f,
- 0x33, 0x1f, 0x56, 0x2c, 0xed, 0xc2, 0x45, 0xd9, 0xaf, 0x57, 0x29, 0x63,
- 0x77, 0xfa, 0x3a, 0xdc, 0x31, 0x30, 0x6e, 0x7b, 0x8d, 0x05, 0xc8, 0x84,
- 0x43, 0xed, 0x3d, 0x8a, 0x17, 0xbb, 0xd2, 0x2e, 0x2c, 0x1a, 0x20, 0x5f,
- 0x33, 0xe3, 0x4a, 0x6c, 0x7a, 0x8e, 0x87, 0x2f, 0x4c, 0x32, 0x1f, 0xcd,
- 0x4a, 0x7e, 0xd8, 0xd6, 0xbe, 0x30, 0xf1, 0x80, 0x12, 0xd3, 0x3e, 0xbf,
- 0x98, 0x4c, 0x1d, 0xfd, 0xae, 0xea, 0xf0, 0x30, 0x1f, 0xde, 0x3c, 0xe8,
- 0xa3, 0x2f, 0x28, 0xf4, 0x13, 0x3f, 0x7d, 0xbf, 0x01, 0x6f, 0xd3, 0x37,
- 0xee, 0x67, 0x5c, 0xfc, 0xfb, 0xd1, 0x2a, 0xdc, 0xb6, 0x27, 0x8a, 0x97,
- 0x0f, 0xfa, 0xd1, 0xbe, 0xe7, 0x56, 0xbc, 0xc5, 0x72, 0x63, 0x8c, 0x07,
- 0x63, 0xc3, 0x95, 0xfc, 0xf8, 0xf9, 0xa9, 0xe2, 0x67, 0x2d, 0xf1, 0xa8,
- 0x02, 0x27, 0xf7, 0xbb, 0xd0, 0x32, 0xa0, 0x62, 0xc0, 0x54, 0x70, 0xf7,
- 0x4d, 0x32, 0x1e, 0x2f, 0xd6, 0xd4, 0x5e, 0xb6, 0x8b, 0x25, 0x49, 0xe1,
- 0x70, 0x5e, 0xce, 0x93, 0x8e, 0x43, 0xf4, 0xcb, 0xdb, 0xc8, 0xc1, 0x76,
- 0xf4, 0xb5, 0xd1, 0x8f, 0x6c, 0xcc, 0x0a, 0xff, 0x18, 0x2b, 0xb4, 0x1e,
- 0xc9, 0x6b, 0x9d, 0x75, 0xfe, 0x14, 0xe7, 0x71, 0xc2, 0x53, 0x6f, 0x4d,
- 0x43, 0x51, 0x2c, 0x10, 0x0d, 0x69, 0x47, 0xb0, 0x1c, 0x7d, 0x63, 0xd0,
- 0x64, 0xcd, 0x7f, 0x1b, 0x79, 0xd4, 0x76, 0xf2, 0xa8, 0xee, 0xcc, 0x11,
- 0xce, 0xb1, 0xcf, 0x2b, 0x7b, 0xdf, 0xdb, 0xa8, 0xbb, 0xc5, 0x0e, 0x27,
- 0xf2, 0x5a, 0x45, 0x6c, 0xff, 0x38, 0x63, 0xd2, 0x82, 0xfe, 0x1c, 0x6e,
- 0x7c, 0xd6, 0xf4, 0x3c, 0x8c, 0x69, 0x3d, 0xf4, 0xf9, 0x5c, 0xdb, 0x3b,
- 0x85, 0x9b, 0x79, 0xca, 0x62, 0x65, 0xd1, 0xd0, 0x86, 0xd7, 0xa9, 0x7c,
- 0x2f, 0xdb, 0xdc, 0x3a, 0xb9, 0x8f, 0xd0, 0xcb, 0x36, 0x7b, 0x58, 0xb7,
- 0xbe, 0xdf, 0xe2, 0x5c, 0xba, 0x59, 0x3f, 0x14, 0xd8, 0xa8, 0x98, 0xac,
- 0xeb, 0xe4, 0x11, 0xa8, 0xd9, 0x7f, 0x79, 0xae, 0xda, 0x88, 0x31, 0xfd,
- 0x93, 0xfe, 0x7e, 0x7e, 0xf4, 0x3a, 0x84, 0x68, 0x24, 0x4f, 0x9b, 0x9b,
- 0xa0, 0xd3, 0x66, 0x5d, 0x93, 0x7d, 0x6d, 0x97, 0x71, 0xb8, 0x67, 0xc6,
- 0x66, 0xb2, 0x8f, 0xbe, 0x4c, 0x48, 0xeb, 0x42, 0xfd, 0x89, 0x69, 0x90,
- 0x71, 0x48, 0x7f, 0xcb, 0xf1, 0xe4, 0xd8, 0xd5, 0xe3, 0xa8, 0x26, 0x3e,
- 0x5d, 0x2c, 0x98, 0x3c, 0x33, 0xe7, 0xe4, 0xe2, 0x31, 0xc7, 0xc7, 0x76,
- 0x38, 0xf2, 0x7b, 0xd8, 0x66, 0x36, 0xb7, 0x07, 0x22, 0x69, 0x95, 0x32,
- 0xc2, 0x58, 0xd1, 0x96, 0x54, 0x62, 0x15, 0xd1, 0xfa, 0xce, 0x69, 0x08,
- 0x45, 0x7e, 0xc6, 0xb6, 0xa7, 0xb1, 0xed, 0x67, 0xd9, 0x76, 0x8a, 0x6d,
- 0x8f, 0xb0, 0xed, 0x1f, 0x5c, 0x6a, 0x5b, 0xc5, 0xfd, 0x7b, 0xf2, 0xb6,
- 0xe5, 0x46, 0xa4, 0x89, 0x59, 0xdf, 0x34, 0xd9, 0x03, 0xad, 0xe6, 0xdc,
- 0x8b, 0xee, 0x74, 0xc6, 0xf6, 0x9c, 0xbd, 0x2d, 0x60, 0xec, 0xb9, 0x6b,
- 0x8f, 0x82, 0xf7, 0xc3, 0xef, 0x63, 0xc2, 0x9f, 0xe3, 0x11, 0x79, 0x1b,
- 0xd2, 0x68, 0x43, 0x5a, 0xf2, 0x7f, 0xd2, 0xf4, 0xa5, 0x8e, 0xd8, 0x8f,
- 0xec, 0x3f, 0x90, 0x3f, 0x27, 0x44, 0x1f, 0xbf, 0x23, 0xee, 0x86, 0x4e,
- 0xbc, 0xc7, 0xd8, 0xf9, 0xa3, 0x8c, 0x07, 0xe9, 0xb4, 0x0f, 0xcf, 0x66,
- 0x04, 0x1b, 0xdb, 0x88, 0x8d, 0x82, 0xf7, 0xe4, 0x81, 0xc3, 0x47, 0x1f,
- 0x0b, 0xb0, 0xf2, 0xb3, 0xb4, 0x9f, 0x67, 0x69, 0x3f, 0xcf, 0x0e, 0xfb,
- 0x70, 0xf3, 0x21, 0x2f, 0xce, 0x11, 0x6b, 0x7a, 0x59, 0x26, 0x91, 0x6a,
- 0xc0, 0x4d, 0xe4, 0x59, 0x87, 0x7b, 0x19, 0x97, 0x19, 0xff, 0xeb, 0xb2,
- 0x1a, 0x76, 0xf5, 0x57, 0xa0, 0x7e, 0x48, 0x62, 0x70, 0x05, 0x1e, 0xe9,
- 0xf3, 0x62, 0xce, 0x7e, 0xd9, 0x87, 0x24, 0x2f, 0xec, 0xbb, 0x13, 0xc3,
- 0x8e, 0x8f, 0x4f, 0xa3, 0x7f, 0x54, 0xa2, 0x76, 0x48, 0xae, 0xc9, 0x53,
- 0x68, 0xb3, 0x0b, 0x0e, 0x55, 0x71, 0xbc, 0xb7, 0x62, 0xfe, 0xa1, 0x00,
- 0xf1, 0xdc, 0x8f, 0x48, 0x76, 0xf9, 0x45, 0xc1, 0xe4, 0xed, 0x63, 0x53,
- 0x63, 0x9a, 0xf8, 0xa1, 0x83, 0x61, 0x91, 0x3c, 0x86, 0x5d, 0x7e, 0x3e,
- 0x15, 0x27, 0x7f, 0xcb, 0x67, 0x52, 0x26, 0x1f, 0x7b, 0xa6, 0xe2, 0xe2,
- 0x65, 0x7c, 0x6a, 0x1c, 0x90, 0x6f, 0x0d, 0xed, 0xf3, 0xc4, 0xd7, 0xaf,
- 0x43, 0xc4, 0x91, 0xe7, 0xfe, 0x62, 0x96, 0x0b, 0xe4, 0xfc, 0x7d, 0x2a,
- 0x9e, 0xfb, 0x26, 0xfd, 0xd4, 0x85, 0x58, 0x45, 0x8e, 0x0b, 0xdf, 0xbe,
- 0xa7, 0x01, 0xbb, 0xa8, 0x8f, 0x56, 0xfa, 0x91, 0x2f, 0x1c, 0xb5, 0xad,
- 0x0a, 0xc9, 0x5b, 0x2b, 0x71, 0xe7, 0x1e, 0x3f, 0x63, 0xf8, 0xb5, 0x48,
- 0x0e, 0xcf, 0x66, 0x5b, 0xd5, 0xe8, 0x9d, 0xcc, 0xe7, 0xb7, 0xa7, 0x96,
- 0xd9, 0x0f, 0x39, 0x7b, 0xf2, 0xb2, 0xf6, 0xff, 0xda, 0x7d, 0xde, 0xd0,
- 0xb8, 0xce, 0x7c, 0xde, 0x64, 0xce, 0x41, 0x0e, 0x76, 0x02, 0xa1, 0x4a,
- 0xe6, 0xe7, 0x46, 0x39, 0x16, 0x31, 0x9f, 0x7f, 0xc8, 0x2f, 0xcf, 0x6e,
- 0x15, 0x59, 0x9c, 0xf2, 0x97, 0xc7, 0xb8, 0x6b, 0xca, 0x18, 0xeb, 0x23,
- 0xd3, 0x90, 0xe7, 0x63, 0x5f, 0xd8, 0x7f, 0x6f, 0x40, 0xe9, 0x0f, 0xd1,
- 0x6a, 0x1b, 0x83, 0x7d, 0x0f, 0x29, 0x86, 0xd6, 0xa4, 0x12, 0xba, 0x46,
- 0xdf, 0xc4, 0x92, 0xec, 0x2f, 0x10, 0xcb, 0xae, 0xf6, 0x8a, 0x2c, 0xf7,
- 0x67, 0x57, 0x61, 0x9c, 0x73, 0x5c, 0xc4, 0x3a, 0x37, 0xf4, 0xfa, 0x68,
- 0xa3, 0x50, 0x0e, 0x37, 0xd7, 0xe1, 0x43, 0xf2, 0x9c, 0xb6, 0xe4, 0x9b,
- 0xd0, 0x18, 0x5f, 0xef, 0x4c, 0xfe, 0x02, 0x65, 0xc4, 0x94, 0x3b, 0x92,
- 0x5f, 0xd8, 0x23, 0xa1, 0x7d, 0x4e, 0xbd, 0xc2, 0xd1, 0x03, 0x17, 0xfb,
- 0x2e, 0xc7, 0x27, 0xad, 0xd0, 0x78, 0xe5, 0x2a, 0x3c, 0x6c, 0x68, 0xd9,
- 0x9c, 0x18, 0xfd, 0x5f, 0x9e, 0xe8, 0xaf, 0x7f, 0xfa, 0xfd, 0xe6, 0x9c,
- 0x5d, 0xea, 0x99, 0xbb, 0xf0, 0x2d, 0x07, 0x77, 0xd7, 0x6c, 0x74, 0x47,
- 0x3b, 0x1e, 0x93, 0xb5, 0xd0, 0x35, 0xce, 0x3a, 0x41, 0x3b, 0x76, 0xee,
- 0x6d, 0xc3, 0xe6, 0xbd, 0x82, 0xad, 0xf5, 0xad, 0x8b, 0x94, 0x19, 0xf4,
- 0xc3, 0x01, 0x27, 0x97, 0x71, 0x1b, 0x9f, 0xca, 0x9a, 0xab, 0xea, 0x71,
- 0xf6, 0xc0, 0x74, 0xac, 0x19, 0xcd, 0xb5, 0x35, 0x2b, 0x53, 0x4a, 0xff,
- 0x8a, 0x22, 0xc9, 0x9c, 0xc5, 0xc7, 0xd8, 0xc9, 0x79, 0xc1, 0xa9, 0x7e,
- 0x89, 0x3b, 0x0a, 0x7c, 0xf7, 0xc8, 0x5e, 0xe6, 0x32, 0xe4, 0xf9, 0x7a,
- 0x4c, 0xdb, 0xcc, 0xdf, 0x3b, 0x8a, 0x73, 0x72, 0x6d, 0xbe, 0x8a, 0x17,
- 0xe5, 0xed, 0x41, 0x74, 0x97, 0xb7, 0xa1, 0x4f, 0x39, 0x06, 0xe6, 0xd8,
- 0xe4, 0x83, 0x97, 0xfd, 0xf9, 0x8b, 0x22, 0x67, 0x5d, 0x30, 0x3b, 0x35,
- 0xbe, 0x6f, 0x9f, 0xd4, 0xfd, 0x75, 0xc5, 0xf9, 0xd8, 0x94, 0x93, 0xd7,
- 0x24, 0x16, 0x5e, 0x83, 0x98, 0x3f, 0xef, 0xff, 0xdf, 0xe4, 0xf3, 0xcd,
- 0x82, 0x01, 0x93, 0x75, 0xef, 0x2e, 0x41, 0xf1, 0x76, 0x87, 0xc3, 0x5d,
- 0x6e, 0x9f, 0x64, 0xf8, 0x8a, 0xf6, 0xa7, 0xda, 0xaf, 0xb4, 0x2f, 0x71,
- 0x5a, 0x74, 0xda, 0xc8, 0xba, 0xa2, 0x3f, 0x07, 0xa3, 0x65, 0x4d, 0x96,
- 0xdc, 0xad, 0xcd, 0xd9, 0xa7, 0x29, 0x26, 0x6f, 0xee, 0x66, 0x0e, 0x55,
- 0xb2, 0x9f, 0xd7, 0xe4, 0x3e, 0x4b, 0x07, 0x02, 0x28, 0xda, 0xef, 0x21,
- 0xae, 0xcf, 0x80, 0x7b, 0x7f, 0x01, 0xed, 0x55, 0x38, 0xc2, 0x6b, 0xf7,
- 0x6d, 0x31, 0xae, 0x85, 0x6b, 0x7f, 0x21, 0x79, 0xb9, 0x70, 0xbe, 0x13,
- 0xf7, 0xad, 0x65, 0x1c, 0x57, 0xf7, 0x7b, 0x19, 0x9f, 0xab, 0xe1, 0x61,
- 0xcc, 0x5b, 0x32, 0xf0, 0x67, 0x28, 0xd8, 0x5f, 0x8c, 0x07, 0x06, 0xae,
- 0xc7, 0xcc, 0xfd, 0x25, 0xb8, 0x7f, 0x60, 0x26, 0x66, 0xec, 0x97, 0xdc,
- 0x49, 0x47, 0x60, 0x7f, 0x29, 0x56, 0x0c, 0x04, 0x51, 0xb1, 0xbf, 0x0c,
- 0x6d, 0x03, 0xb3, 0xa0, 0xed, 0x2f, 0xc7, 0x5d, 0x03, 0x35, 0x28, 0xdf,
- 0xaf, 0xe1, 0xce, 0x01, 0x03, 0x65, 0xfb, 0x2b, 0x18, 0xd3, 0x42, 0x8c,
- 0x9d, 0x7e, 0x2c, 0xdf, 0xc3, 0xb9, 0x39, 0x58, 0x45, 0xbf, 0x58, 0x45,
- 0x4e, 0xbd, 0x1a, 0xfb, 0x52, 0x73, 0x50, 0x72, 0x30, 0x80, 0xa5, 0x7b,
- 0xc6, 0x35, 0x52, 0x1a, 0x2c, 0x0e, 0x35, 0xa0, 0xe8, 0xa0, 0xe4, 0x7e,
- 0xc1, 0x13, 0x2d, 0x08, 0x5e, 0x58, 0x84, 0x72, 0xe6, 0xbe, 0xc0, 0x7b,
- 0x63, 0xc0, 0xec, 0x31, 0x17, 0x8e, 0x68, 0xab, 0xb0, 0x75, 0xec, 0x9b,
- 0x93, 0x36, 0x2f, 0xfb, 0x47, 0xe5, 0x9c, 0x5f, 0xb9, 0x96, 0x7b, 0xab,
- 0xd1, 0x33, 0x96, 0x5f, 0x07, 0x0b, 0xf6, 0x6d, 0xa7, 0x06, 0xc7, 0x33,
- 0xf2, 0x4c, 0x7c, 0x04, 0xb4, 0x6f, 0xa5, 0x5b, 0xce, 0x8f, 0xbb, 0xa2,
- 0x6a, 0x59, 0x77, 0xf3, 0x86, 0x5b, 0xe2, 0x99, 0x4d, 0xcc, 0xbb, 0x24,
- 0x87, 0xdd, 0x78, 0xcb, 0x9a, 0xcc, 0x07, 0x97, 0xf6, 0x13, 0xfa, 0xcc,
- 0x85, 0x01, 0x0d, 0x5f, 0xc3, 0x1a, 0x67, 0x0d, 0x55, 0xe5, 0x9c, 0xc9,
- 0x79, 0x56, 0xe7, 0x2c, 0x39, 0xed, 0x2c, 0x0e, 0xd3, 0xc1, 0xd4, 0x75,
- 0xa8, 0xc9, 0x38, 0x6b, 0xb5, 0x75, 0x71, 0xbc, 0xa0, 0xb6, 0x1a, 0xd6,
- 0xe4, 0xd9, 0x0f, 0x6b, 0xbe, 0x86, 0x98, 0xa9, 0x5d, 0x3a, 0x1f, 0x12,
- 0xd4, 0x47, 0x10, 0x0c, 0x6c, 0xc3, 0x3a, 0xe7, 0x7c, 0xa0, 0x12, 0x6d,
- 0x97, 0x73, 0x46, 0xfc, 0x5e, 0x0d, 0x23, 0x93, 0x5f, 0x6b, 0x94, 0xb3,
- 0xd7, 0xb2, 0x8f, 0x65, 0x33, 0xe7, 0x97, 0x3c, 0xf9, 0x88, 0xa2, 0xf6,
- 0x3a, 0xeb, 0x63, 0xab, 0x5c, 0x8c, 0x01, 0x2d, 0x0a, 0xe2, 0x45, 0xd1,
- 0x90, 0xfe, 0xe1, 0xe4, 0xba, 0x83, 0x67, 0x74, 0x8b, 0x52, 0x30, 0xda,
- 0xa3, 0xb8, 0x47, 0x73, 0xeb, 0x0e, 0x2e, 0xf2, 0xd8, 0x6d, 0xa9, 0x4a,
- 0x96, 0xd1, 0x30, 0x7b, 0xae, 0x1b, 0xaf, 0x26, 0xca, 0x9c, 0xb3, 0xc7,
- 0x5b, 0xe7, 0x16, 0xe0, 0x11, 0xda, 0x7e, 0xeb, 0x8d, 0xc7, 0xf0, 0x41,
- 0x86, 0x5c, 0x23, 0x61, 0x85, 0x87, 0xd9, 0xe7, 0xd1, 0x84, 0x8a, 0x17,
- 0x07, 0xb7, 0x84, 0x87, 0x9c, 0xfe, 0xbf, 0x8d, 0xcd, 0x23, 0x92, 0x77,
- 0xb5, 0xd9, 0xdb, 0x53, 0xed, 0xb6, 0xc4, 0xdd, 0x6c, 0xa2, 0x92, 0xb9,
- 0xb9, 0x86, 0x0f, 0xe6, 0x6e, 0xc0, 0x39, 0x96, 0x19, 0x4d, 0x6c, 0xc4,
- 0x27, 0xe4, 0x08, 0x99, 0xc4, 0x72, 0xbc, 0xc6, 0x5c, 0xf2, 0x7b, 0x89,
- 0x56, 0xe6, 0x96, 0xab, 0xf0, 0xca, 0xa0, 0xf0, 0x8f, 0x16, 0x2c, 0x4c,
- 0x28, 0x58, 0x1a, 0x5a, 0x85, 0x93, 0xc3, 0xcc, 0x29, 0x07, 0xe5, 0xbc,
- 0xeb, 0x35, 0x58, 0x93, 0x3b, 0x0f, 0xc5, 0xe7, 0x31, 0x3e, 0x5f, 0x89,
- 0xa3, 0xc3, 0x01, 0x1c, 0x60, 0x0e, 0xf9, 0x0e, 0x31, 0x64, 0x28, 0xd1,
- 0x80, 0xd3, 0xcc, 0x95, 0x7e, 0x94, 0x88, 0xe0, 0x33, 0xfe, 0x3e, 0x92,
- 0x90, 0xf5, 0xef, 0x66, 0x5c, 0xc8, 0xfc, 0x18, 0x05, 0xbd, 0x33, 0x70,
- 0xbc, 0xed, 0x79, 0x52, 0xc9, 0x23, 0xfc, 0xb4, 0xe2, 0xf4, 0x70, 0x2b,
- 0xce, 0x0c, 0x2e, 0xc3, 0x99, 0xe1, 0x5f, 0xe1, 0x83, 0x41, 0x91, 0x57,
- 0xce, 0x2c, 0x3a, 0xef, 0x16, 0xb0, 0x5d, 0xe2, 0xd4, 0xf0, 0xbf, 0xa5,
- 0xed, 0x8f, 0xec, 0xe3, 0xab, 0xa4, 0xdd, 0xe7, 0xff, 0x48, 0xdb, 0xa2,
- 0x4b, 0x89, 0xf5, 0x5e, 0x9c, 0x4c, 0x78, 0x99, 0x57, 0x8d, 0xdf, 0x50,
- 0x84, 0xf1, 0xf9, 0xcc, 0x36, 0xb1, 0x3d, 0x53, 0x88, 0x17, 0xfb, 0xdc,
- 0xe4, 0x8a, 0x5f, 0x25, 0x7e, 0x74, 0xd2, 0x0e, 0x0b, 0x99, 0xbf, 0x79,
- 0xa9, 0xe3, 0xf9, 0xc4, 0xfb, 0x55, 0xd4, 0x9f, 0x0f, 0xa7, 0x12, 0x7e,
- 0xbc, 0x9e, 0xa8, 0x8f, 0x67, 0x95, 0x46, 0x58, 0x15, 0xb9, 0xbc, 0xf2,
- 0x68, 0xa2, 0xc3, 0x91, 0xe9, 0xd5, 0x44, 0x9b, 0xbd, 0x95, 0x3a, 0xee,
- 0x49, 0x7d, 0xdb, 0x39, 0x6f, 0xf8, 0x4a, 0xe2, 0x82, 0x2d, 0xe7, 0x88,
- 0x9f, 0xa1, 0x4e, 0x4f, 0x26, 0xe2, 0x28, 0x62, 0x9e, 0x72, 0x2c, 0x31,
- 0x8e, 0x61, 0xda, 0xe5, 0x3b, 0x7d, 0xc6, 0x89, 0x35, 0xd8, 0x84, 0xcf,
- 0xd2, 0x85, 0x78, 0x8b, 0x7d, 0x94, 0x37, 0xb9, 0x31, 0xe1, 0xb4, 0xb7,
- 0x09, 0x9f, 0xf4, 0x29, 0xc8, 0xcc, 0xdd, 0x84, 0x8f, 0xf9, 0xec, 0x0d,
- 0x5e, 0x9f, 0x0b, 0x53, 0xc2, 0xc9, 0x67, 0x67, 0xfa, 0x54, 0x27, 0x07,
- 0xee, 0x6e, 0xde, 0x84, 0xd3, 0xe9, 0x8f, 0x71, 0x80, 0xb9, 0xf4, 0x63,
- 0xe6, 0x34, 0x44, 0xa6, 0x11, 0x70, 0x8d, 0x42, 0x9c, 0xe4, 0xf3, 0x5a,
- 0x59, 0xef, 0xd1, 0x72, 0xe5, 0x3f, 0xe2, 0x78, 0x1e, 0x61, 0x5b, 0x67,
- 0xd3, 0xdf, 0x61, 0xbb, 0xc2, 0x39, 0xbf, 0xc3, 0x76, 0x7f, 0x85, 0x91,
- 0x49, 0x7d, 0x9c, 0x36, 0x65, 0x5c, 0x1b, 0x7c, 0x28, 0xf6, 0x73, 0x1c,
- 0x0f, 0xf3, 0xbb, 0x03, 0x13, 0x99, 0x9d, 0xfc, 0x7e, 0x0d, 0x87, 0x33,
- 0x12, 0xdb, 0xf3, 0x67, 0x87, 0x64, 0x7d, 0x4b, 0xfc, 0x47, 0x9f, 0x5c,
- 0x97, 0x9b, 0x8e, 0x54, 0x7f, 0x59, 0x7c, 0x1a, 0xed, 0xe8, 0x3f, 0xcc,
- 0x2b, 0xc7, 0x47, 0x61, 0x0b, 0xbb, 0x0e, 0xb8, 0x91, 0xea, 0x25, 0x9f,
- 0xed, 0xad, 0xc4, 0x53, 0xbb, 0x35, 0x3c, 0xb9, 0xfb, 0x5a, 0x6c, 0xd9,
- 0x7d, 0x3d, 0xf6, 0xed, 0xae, 0x46, 0x92, 0xb9, 0xf2, 0x27, 0x4d, 0xb6,
- 0x3d, 0x87, 0x9f, 0x1d, 0xf4, 0x05, 0x2f, 0xbf, 0x5f, 0x0e, 0x8b, 0x9f,
- 0x18, 0xb8, 0xd1, 0xf1, 0x97, 0x16, 0xdc, 0xe0, 0x7c, 0xc7, 0x30, 0x27,
- 0xd3, 0x19, 0xde, 0x90, 0xdd, 0x14, 0x7e, 0x28, 0x3b, 0x1d, 0x5b, 0xfb,
- 0xab, 0xd0, 0xbf, 0xbb, 0x32, 0x5e, 0xc9, 0x7e, 0x56, 0xce, 0xb3, 0x31,
- 0xc4, 0xba, 0x66, 0x63, 0x4f, 0x78, 0x4d, 0xf6, 0x79, 0xb4, 0x65, 0xfd,
- 0xd8, 0xdc, 0x1f, 0x60, 0x5f, 0xb2, 0x86, 0xef, 0x3e, 0xf1, 0x20, 0x6c,
- 0xfb, 0x42, 0xd3, 0x11, 0xc6, 0xb7, 0x1f, 0xa3, 0x9d, 0xcf, 0x92, 0xfd,
- 0x1b, 0xc8, 0xa9, 0x0a, 0xe2, 0xde, 0xa8, 0x8d, 0x53, 0xe1, 0x71, 0xdc,
- 0xc1, 0xf6, 0x76, 0xf6, 0x97, 0x51, 0xa6, 0xe2, 0x78, 0x21, 0xef, 0x2d,
- 0x0d, 0x6f, 0xc4, 0xae, 0x31, 0x59, 0x03, 0x3c, 0x81, 0xa5, 0xe4, 0x2c,
- 0x15, 0x73, 0x7f, 0x56, 0x82, 0x32, 0xcd, 0x7d, 0xbe, 0x59, 0xec, 0x2f,
- 0x4e, 0xfb, 0x13, 0xac, 0x5c, 0x87, 0xb5, 0xce, 0xd9, 0xc2, 0x76, 0xbc,
- 0x94, 0x10, 0x9c, 0x5e, 0x8d, 0x83, 0x89, 0x75, 0xd8, 0x92, 0x92, 0x7d,
- 0xc0, 0xe5, 0xa8, 0xc9, 0xfe, 0x55, 0x78, 0x3d, 0xe3, 0xa9, 0x2b, 0xfb,
- 0x3f, 0xb0, 0x38, 0x9b, 0xa6, 0x5c, 0xc3, 0xe1, 0xb5, 0xd9, 0x7d, 0xe1,
- 0x07, 0xb3, 0xad, 0x98, 0x95, 0x95, 0xf5, 0xb4, 0x36, 0xe2, 0xbb, 0xac,
- 0xa7, 0x4d, 0x60, 0x61, 0xf6, 0x0c, 0x16, 0x65, 0xdf, 0x62, 0x2c, 0x16,
- 0xdc, 0x90, 0x75, 0xb6, 0x5f, 0x31, 0x39, 0x91, 0x7d, 0xc3, 0xbf, 0xc4,
- 0xd6, 0xbd, 0x71, 0xc6, 0xc2, 0x3c, 0x46, 0xd5, 0x6b, 0x07, 0x04, 0x5f,
- 0xc6, 0x3c, 0x4e, 0x2c, 0xe8, 0x4b, 0xdd, 0x43, 0x7b, 0x54, 0xc9, 0xf3,
- 0x25, 0xce, 0xac, 0xa3, 0x2f, 0x77, 0x92, 0x9f, 0x4b, 0xfc, 0xbb, 0x6b,
- 0xf2, 0xbe, 0xf0, 0x3a, 0x89, 0x7d, 0x3a, 0x8e, 0x66, 0x9c, 0xbd, 0x0c,
- 0xdd, 0x6b, 0xdc, 0xc1, 0x67, 0x52, 0xff, 0x2f, 0x91, 0xdc, 0xbb, 0xca,
- 0xde, 0xe9, 0xac, 0x19, 0x29, 0x38, 0x1e, 0x62, 0x5f, 0xa4, 0x91, 0x4b,
- 0xf7, 0xcb, 0x59, 0xce, 0x75, 0x72, 0x96, 0xd3, 0x72, 0x19, 0x6d, 0xf6,
- 0x96, 0x14, 0x1e, 0x2c, 0x45, 0x00, 0xcb, 0x47, 0x0b, 0x10, 0x3b, 0x58,
- 0x8c, 0xdb, 0x77, 0xb7, 0xd3, 0x96, 0x2d, 0xda, 0xaf, 0x61, 0xae, 0x55,
- 0x8a, 0xb1, 0x84, 0xf7, 0x1e, 0xe8, 0x0f, 0xb6, 0x02, 0xa1, 0x13, 0xa7,
- 0x5d, 0xc5, 0xb8, 0x9f, 0xb1, 0x23, 0x9d, 0x5e, 0x8e, 0xd8, 0xfe, 0xe3,
- 0xb0, 0xd2, 0xb4, 0xc9, 0x3d, 0xc4, 0x99, 0xbd, 0x6e, 0xa8, 0xd1, 0x5f,
- 0x61, 0xdf, 0xb0, 0x8a, 0xf2, 0x3d, 0x2f, 0xd8, 0x01, 0x43, 0x31, 0xce,
- 0x85, 0xb2, 0xe4, 0x40, 0x6e, 0x94, 0x26, 0x5b, 0x30, 0x4a, 0xac, 0xf1,
- 0x25, 0x63, 0xc8, 0x64, 0xda, 0x90, 0x26, 0x96, 0xa4, 0xc9, 0x9b, 0x4a,
- 0x92, 0x26, 0x63, 0x79, 0x1d, 0x76, 0xd1, 0x5f, 0x0a, 0x98, 0xcb, 0x6f,
- 0xcb, 0xdc, 0x0a, 0x6b, 0xf8, 0x4e, 0x6c, 0x1f, 0x6e, 0xe3, 0x87, 0xfc,
- 0x71, 0xf8, 0xdb, 0x58, 0x38, 0x7a, 0x02, 0x3d, 0x99, 0x38, 0xed, 0xf1,
- 0x63, 0x6c, 0x4f, 0x1f, 0xc3, 0x53, 0x7d, 0x5d, 0xcc, 0x11, 0x8e, 0xe1,
- 0x49, 0x5e, 0xf7, 0xf5, 0x19, 0x9d, 0x01, 0xf5, 0x18, 0x52, 0xe9, 0x4d,
- 0xb8, 0xb3, 0x5f, 0x61, 0x0e, 0xb7, 0x09, 0x77, 0xec, 0xa7, 0x2d, 0x3e,
- 0xd1, 0x81, 0xd6, 0xd1, 0xd7, 0x90, 0xc8, 0xbc, 0xc4, 0xfc, 0x6a, 0x23,
- 0x7a, 0x52, 0x1b, 0xc8, 0xbd, 0x9e, 0x67, 0x3b, 0x47, 0xe8, 0xe7, 0x9d,
- 0x1c, 0xe3, 0xe3, 0xfc, 0x5c, 0xc2, 0x70, 0x4d, 0x57, 0xf2, 0x58, 0x4d,
- 0xbf, 0x4f, 0x49, 0xee, 0xb0, 0x8e, 0x38, 0x71, 0x6f, 0x29, 0x8a, 0x45,
- 0xbf, 0xf9, 0x35, 0x69, 0x99, 0x0b, 0xb1, 0x7d, 0x59, 0x9b, 0x76, 0xa3,
- 0x28, 0x29, 0xeb, 0xd1, 0xe3, 0xc1, 0x22, 0x72, 0x00, 0x6f, 0x52, 0x74,
- 0xd8, 0x6e, 0x77, 0xa7, 0x04, 0x4b, 0x72, 0xdc, 0xfc, 0xe5, 0xcc, 0xaf,
- 0xb0, 0x75, 0x70, 0x1a, 0x16, 0xf5, 0x55, 0x23, 0xee, 0xb7, 0xed, 0xe7,
- 0xe8, 0x6b, 0x09, 0xe6, 0x58, 0xbb, 0xfa, 0x63, 0xc4, 0x94, 0x12, 0xe4,
- 0x72, 0x3d, 0xd1, 0x4d, 0xd0, 0xd4, 0xaf, 0xd8, 0x23, 0x99, 0xc5, 0x79,
- 0x13, 0xee, 0x3a, 0x7e, 0x43, 0x29, 0xce, 0x97, 0xe4, 0xd6, 0xc5, 0xff,
- 0xfc, 0x12, 0xb7, 0xf9, 0xd7, 0x95, 0xbf, 0xff, 0xdf, 0x58, 0x7e, 0x62,
- 0xca, 0xd9, 0xb5, 0xfc, 0x7b, 0x39, 0x32, 0xd6, 0xeb, 0xe5, 0xdc, 0x9a,
- 0x25, 0x7c, 0x49, 0xce, 0xdc, 0x1e, 0x4f, 0x14, 0x30, 0x4e, 0xaa, 0x0b,
- 0x3c, 0x50, 0xfd, 0x1e, 0x14, 0x32, 0x9e, 0x55, 0x61, 0xb3, 0xdf, 0xc6,
- 0x62, 0xb3, 0x00, 0x87, 0x1b, 0x62, 0x72, 0xce, 0xa2, 0xdd, 0xe3, 0xf0,
- 0xd1, 0xd5, 0xf7, 0xfc, 0xe1, 0xba, 0xf5, 0x26, 0x72, 0x37, 0x39, 0x5f,
- 0xd0, 0x86, 0x53, 0x15, 0xf2, 0xae, 0xd0, 0x26, 0xe7, 0xdc, 0x59, 0x51,
- 0xad, 0xac, 0xa3, 0xe9, 0x38, 0x61, 0xd4, 0xeb, 0x95, 0x2a, 0xe3, 0xb9,
- 0xf2, 0xae, 0x6d, 0xf9, 0xa3, 0x8c, 0xf5, 0x72, 0x86, 0xe2, 0x5f, 0xda,
- 0xa7, 0x58, 0x83, 0xed, 0x4f, 0x34, 0x63, 0x62, 0x95, 0xc4, 0xff, 0xff,
- 0xe6, 0xcb, 0x73, 0xba, 0x6d, 0xa9, 0x1f, 0x96, 0xca, 0xb9, 0x24, 0x69,
- 0x7b, 0x3b, 0xf3, 0x27, 0x8f, 0x11, 0xc6, 0xbb, 0xc2, 0xd2, 0x9c, 0xfd,
- 0xa4, 0x1c, 0xa7, 0x28, 0x34, 0xce, 0x4f, 0xbe, 0x3b, 0xf2, 0xd7, 0xa5,
- 0xc2, 0x0f, 0xb7, 0xa5, 0x36, 0x91, 0x9b, 0x8b, 0x3c, 0xbf, 0xb7, 0xd7,
- 0xf8, 0x2b, 0x59, 0xf6, 0xee, 0xc9, 0xf6, 0xc4, 0x16, 0xe4, 0x4c, 0x8e,
- 0xdc, 0x93, 0x3a, 0xa2, 0xb3, 0xa9, 0x75, 0x5c, 0xcc, 0x85, 0x6f, 0xc0,
- 0xa3, 0xf4, 0xc1, 0x99, 0xc6, 0xeb, 0x76, 0x97, 0x9c, 0x9f, 0xa9, 0xd5,
- 0xa6, 0xf4, 0xf5, 0x0b, 0x47, 0x96, 0x42, 0xca, 0xd2, 0x9f, 0x92, 0xb3,
- 0xa8, 0x9f, 0xd9, 0xb5, 0x55, 0xf2, 0xfc, 0xc2, 0x64, 0xfb, 0x35, 0xce,
- 0xd9, 0xbe, 0x7d, 0xa9, 0xbc, 0xdc, 0xb2, 0xde, 0xea, 0xcf, 0xf7, 0x55,
- 0x77, 0x79, 0x3c, 0x22, 0x5b, 0xbc, 0xf4, 0x4a, 0x99, 0xe1, 0xcb, 0x9f,
- 0x59, 0x9d, 0xe1, 0xd4, 0xc9, 0xf7, 0x29, 0x32, 0x6e, 0x62, 0x9e, 0x7a,
- 0xf5, 0x18, 0xb5, 0x29, 0x63, 0x92, 0x3a, 0x32, 0x2e, 0x6d, 0xd2, 0x0e,
- 0x4a, 0xcb, 0x50, 0x2c, 0x75, 0x84, 0xbb, 0x6a, 0x0e, 0x07, 0x2f, 0x17,
- 0x5e, 0x2e, 0xb6, 0x51, 0x66, 0xdb, 0xef, 0x39, 0x31, 0x53, 0xda, 0xe1,
- 0x38, 0xc6, 0x56, 0xd1, 0xce, 0xed, 0x2e, 0xe2, 0xa7, 0xfd, 0x5e, 0x73,
- 0x00, 0x5b, 0x13, 0xa2, 0x6b, 0x23, 0x70, 0x88, 0xd8, 0xb1, 0xd9, 0xe1,
- 0x1b, 0x1e, 0x74, 0xa7, 0xf3, 0xfb, 0xa3, 0x85, 0x72, 0xf6, 0x36, 0x20,
- 0x3a, 0xef, 0x36, 0xc9, 0xb3, 0xb4, 0x85, 0xba, 0x9b, 0x5c, 0x69, 0x3d,
- 0xfe, 0x99, 0xf3, 0x2b, 0xe7, 0x8f, 0x73, 0x7b, 0x95, 0x71, 0xda, 0x51,
- 0x2e, 0x5e, 0x81, 0xf1, 0x9d, 0x3c, 0x69, 0xf2, 0x5c, 0x66, 0x77, 0xe6,
- 0x9f, 0xed, 0x71, 0xe7, 0x5c, 0xe6, 0xe5, 0x77, 0x3a, 0xd2, 0x9a, 0x6d,
- 0x1f, 0xe0, 0xb3, 0xcb, 0x67, 0x34, 0x19, 0xd3, 0x0d, 0x39, 0xcb, 0xf9,
- 0x4f, 0x9c, 0xbb, 0xa9, 0x65, 0xc7, 0x2b, 0x72, 0x67, 0x96, 0x63, 0xea,
- 0x42, 0x23, 0x8f, 0xab, 0x41, 0xcb, 0x72, 0x70, 0xf5, 0x0e, 0x67, 0x0f,
- 0x3e, 0x8d, 0x60, 0x6b, 0x1b, 0x2c, 0xbb, 0xd8, 0xc8, 0xe3, 0x80, 0x61,
- 0xce, 0x51, 0xba, 0x30, 0x3b, 0x5c, 0x2c, 0x1c, 0x3b, 0xe8, 0x8e, 0x06,
- 0xb5, 0x0f, 0x10, 0xaa, 0x3b, 0xe6, 0xec, 0x95, 0x0a, 0x36, 0x18, 0x58,
- 0x9f, 0x21, 0xdf, 0x1e, 0x93, 0x77, 0x1d, 0xe5, 0xda, 0x69, 0x9f, 0xd7,
- 0x82, 0xa5, 0xed, 0xc4, 0x52, 0xeb, 0xcf, 0x3d, 0x4e, 0x7b, 0xc1, 0xf6,
- 0x61, 0x25, 0xd8, 0xba, 0x51, 0xc9, 0xb7, 0xe7, 0xfb, 0x92, 0xf6, 0xea,
- 0x58, 0xbf, 0x7a, 0xf2, 0xfd, 0x42, 0x83, 0x6d, 0x5c, 0xbd, 0x9f, 0x3c,
- 0x3d, 0x2e, 0x7b, 0x51, 0x87, 0x27, 0x39, 0xe1, 0xb1, 0x3f, 0xd8, 0x8b,
- 0xfa, 0xd2, 0x3e, 0x63, 0xec, 0xb3, 0xb5, 0x58, 0x89, 0x91, 0x31, 0x74,
- 0xa1, 0x30, 0x1c, 0xaa, 0x7b, 0x19, 0xd0, 0xdd, 0xd1, 0x50, 0x60, 0xd8,
- 0xd9, 0xd3, 0x35, 0xbd, 0x8b, 0x9c, 0xfa, 0xd5, 0xe4, 0xc5, 0x7f, 0x5c,
- 0x27, 0x25, 0x86, 0xd1, 0x56, 0xaf, 0xc4, 0xe6, 0x17, 0xb3, 0x9d, 0xba,
- 0x30, 0xf4, 0x82, 0x68, 0x5e, 0x47, 0xa1, 0xba, 0x0f, 0x38, 0x9f, 0x47,
- 0x9b, 0x43, 0x81, 0x21, 0xe7, 0x8c, 0xa7, 0xe8, 0xc5, 0xf4, 0xe6, 0xe6,
- 0x5e, 0x17, 0xbe, 0xcd, 0x7c, 0x32, 0x8e, 0x91, 0x84, 0x97, 0x63, 0xa9,
- 0xd7, 0xb6, 0xa3, 0x82, 0x36, 0x8e, 0xd8, 0xe6, 0x06, 0xe2, 0x77, 0x02,
- 0x31, 0xd7, 0x8d, 0xe5, 0x88, 0x93, 0x40, 0xbb, 0x8c, 0x38, 0x39, 0x51,
- 0x7d, 0xdd, 0x0e, 0xda, 0x6f, 0xda, 0x1f, 0x0c, 0x58, 0x88, 0xe3, 0xc5,
- 0xc4, 0xc2, 0xff, 0xc7, 0x05, 0xcb, 0x2c, 0x81, 0xbc, 0x5f, 0x90, 0xbe,
- 0x67, 0x59, 0x28, 0xa8, 0xbf, 0x32, 0xb9, 0x27, 0xdd, 0x9d, 0xf8, 0xad,
- 0xbc, 0xc7, 0xc4, 0x7a, 0x7f, 0xac, 0x8c, 0xf4, 0xed, 0xc5, 0xa1, 0xbe,
- 0x3e, 0x6c, 0x79, 0x82, 0x32, 0x1a, 0x36, 0x16, 0x9a, 0x5d, 0xcc, 0xa5,
- 0x7d, 0x58, 0xa7, 0xcd, 0x8e, 0xa8, 0x2c, 0x37, 0x94, 0xce, 0xad, 0x3b,
- 0x6e, 0x75, 0xf6, 0xbc, 0x7b, 0x98, 0xa3, 0x38, 0xf1, 0x53, 0xf3, 0x46,
- 0x63, 0xca, 0xce, 0x4c, 0x8b, 0xb2, 0x23, 0x2d, 0x6d, 0x75, 0x2a, 0x3d,
- 0x99, 0xbf, 0xa5, 0x4f, 0x58, 0x38, 0x6d, 0xca, 0xbb, 0x39, 0xd2, 0xae,
- 0x85, 0xe1, 0xe6, 0x7f, 0xcd, 0x3b, 0x3a, 0xa2, 0xd3, 0x4e, 0x6c, 0x1e,
- 0x7c, 0x1c, 0xdd, 0x83, 0xa7, 0x9c, 0x33, 0x46, 0x1e, 0xc3, 0x6b, 0x5d,
- 0x1f, 0x0d, 0x1e, 0xb1, 0x90, 0x2d, 0x97, 0xf3, 0xf9, 0x55, 0xd1, 0x13,
- 0xd8, 0xa9, 0xc9, 0xbb, 0x27, 0x3d, 0xe4, 0x11, 0xb2, 0x6f, 0xbb, 0x1a,
- 0x5f, 0xef, 0x95, 0x39, 0x2c, 0xb3, 0x0a, 0xa3, 0xc1, 0xd8, 0x3a, 0x67,
- 0x0e, 0x1b, 0x70, 0x32, 0xfb, 0x38, 0xde, 0xdb, 0xd3, 0x05, 0x35, 0x1c,
- 0x0c, 0xdc, 0x06, 0xbb, 0xeb, 0xb8, 0x19, 0xb3, 0x3c, 0x08, 0x1e, 0x76,
- 0xa9, 0xc0, 0x0b, 0x7b, 0xe0, 0x9d, 0xc1, 0xf9, 0x9f, 0xcf, 0x18, 0x5d,
- 0x6e, 0xd8, 0x0b, 0xfe, 0xb1, 0x29, 0xd8, 0x63, 0xb8, 0xac, 0xbf, 0x99,
- 0x8e, 0x60, 0x5f, 0x44, 0x35, 0xda, 0xef, 0x52, 0xa1, 0xf8, 0xa2, 0xf2,
- 0x5e, 0x69, 0x17, 0xee, 0x6c, 0xf4, 0x59, 0xa5, 0xd1, 0x60, 0xdf, 0x29,
- 0x25, 0x58, 0x67, 0xa9, 0x6d, 0x9c, 0xe7, 0x3a, 0xbc, 0x42, 0x0e, 0xd2,
- 0xca, 0xd8, 0xbb, 0x34, 0xa9, 0x3b, 0xeb, 0x4c, 0xaa, 0x51, 0x13, 0x29,
- 0x52, 0x34, 0xdc, 0x96, 0x05, 0x8e, 0xa6, 0x57, 0xe3, 0x9d, 0x3d, 0x26,
- 0xf3, 0x54, 0x9d, 0xb8, 0xf5, 0xbd, 0x32, 0xc1, 0x80, 0x0e, 0xd3, 0xaa,
- 0x57, 0x19, 0xfb, 0x3d, 0x2a, 0x16, 0xce, 0x8c, 0x86, 0xc6, 0x17, 0xb8,
- 0xdc, 0x88, 0x64, 0x65, 0xfd, 0x53, 0x97, 0xb3, 0xc9, 0xb8, 0x2b, 0xe9,
- 0x25, 0xff, 0xac, 0xc6, 0x6f, 0xc8, 0x83, 0x7f, 0x4d, 0xbe, 0x3b, 0xc1,
- 0x78, 0x3e, 0x91, 0x29, 0x66, 0xbe, 0xe8, 0x91, 0x1c, 0x78, 0xdc, 0xc3,
- 0xb9, 0x28, 0x6b, 0xf4, 0xe3, 0xdc, 0xb0, 0x17, 0x77, 0xec, 0x09, 0xee,
- 0x9b, 0x50, 0xab, 0xf0, 0xc9, 0x70, 0x31, 0x96, 0x0f, 0x78, 0x29, 0x9b,
- 0x8d, 0x5d, 0xc4, 0xff, 0x8f, 0xf8, 0xac, 0x65, 0x0f, 0x94, 0xcc, 0xdc,
- 0x59, 0xe4, 0xec, 0x06, 0xeb, 0x97, 0x60, 0xd9, 0x80, 0xf0, 0x34, 0x15,
- 0x1f, 0x0e, 0x2b, 0xf8, 0x20, 0x6d, 0x62, 0x21, 0xfb, 0xdb, 0x9c, 0x7a,
- 0xc1, 0xf6, 0xd2, 0xcf, 0xd7, 0x64, 0x4c, 0x3c, 0x98, 0xd6, 0x19, 0x53,
- 0xde, 0xb6, 0x5d, 0x46, 0x23, 0xde, 0xde, 0x6d, 0x9c, 0x78, 0xd7, 0x15,
- 0x1a, 0x9f, 0xeb, 0x6a, 0xc4, 0x5b, 0x07, 0x1b, 0xf1, 0xb3, 0xfe, 0x05,
- 0xb8, 0xb9, 0x31, 0x86, 0xf3, 0x73, 0x1b, 0xf1, 0xe6, 0x7e, 0x1d, 0x3b,
- 0x52, 0xcd, 0xd0, 0x47, 0xc7, 0xc9, 0x4f, 0x23, 0xa8, 0x67, 0x4e, 0x65,
- 0xf4, 0xdb, 0x5d, 0x25, 0xd1, 0x2e, 0xec, 0x34, 0xa3, 0x98, 0xb3, 0x5f,
- 0xf4, 0x60, 0xdb, 0xeb, 0xe6, 0x46, 0xf1, 0x72, 0x9f, 0x41, 0x3f, 0x8d,
- 0x52, 0x0f, 0x3a, 0x9e, 0x24, 0x36, 0x87, 0x9e, 0x30, 0x2e, 0x1c, 0xe0,
- 0xef, 0x05, 0x07, 0x9a, 0xd1, 0xce, 0xfe, 0x13, 0xa9, 0x18, 0xf6, 0x8d,
- 0x36, 0x70, 0xcc, 0x26, 0xc7, 0x5f, 0x63, 0xfd, 0x46, 0x69, 0x41, 0xdf,
- 0x68, 0x2b, 0xf9, 0x66, 0x17, 0x79, 0x66, 0x2b, 0x7a, 0xd9, 0xd6, 0xd6,
- 0x94, 0x89, 0x65, 0xc9, 0x56, 0x3c, 0x9d, 0x90, 0x33, 0x8d, 0x46, 0x64,
- 0x9e, 0x22, 0xef, 0x7d, 0xb5, 0xe2, 0x10, 0x75, 0xb2, 0x70, 0x60, 0x39,
- 0xed, 0xd0, 0x8b, 0x45, 0x7b, 0x74, 0x3c, 0x95, 0xba, 0x13, 0xef, 0x8c,
- 0x98, 0x68, 0x4b, 0x8a, 0xbe, 0xe5, 0x5c, 0x4d, 0x1c, 0xc7, 0x19, 0x5b,
- 0x7e, 0x33, 0x10, 0xfb, 0x1b, 0x4e, 0xf3, 0x49, 0x15, 0xc1, 0xce, 0x19,
- 0x9c, 0xf0, 0x9b, 0x1a, 0xe5, 0x6c, 0x94, 0x8b, 0xa8, 0x16, 0xb4, 0xca,
- 0x55, 0x4b, 0xe7, 0x7d, 0xcb, 0xad, 0x6e, 0xc2, 0x37, 0x06, 0xdc, 0xe4,
- 0xf4, 0x2a, 0x73, 0x11, 0xab, 0x83, 0xb6, 0x61, 0x95, 0xa9, 0xb9, 0x79,
- 0xdb, 0x2e, 0xef, 0xa1, 0x19, 0x2e, 0xec, 0x32, 0x6b, 0xda, 0x4a, 0x58,
- 0x6f, 0x69, 0x38, 0x18, 0x2b, 0x52, 0x9b, 0x99, 0x27, 0x3e, 0x8e, 0x75,
- 0x7b, 0x1e, 0xc7, 0x1a, 0x7e, 0x3a, 0xf6, 0xd8, 0x5d, 0x4b, 0x4c, 0x05,
- 0x2f, 0x1a, 0x76, 0x57, 0x97, 0x69, 0x70, 0x6e, 0x65, 0x5e, 0x1f, 0x47,
- 0xe7, 0xa1, 0xc7, 0xf1, 0x28, 0xed, 0xab, 0x92, 0x7e, 0xbc, 0x32, 0x69,
- 0x77, 0xdd, 0xdc, 0x58, 0x87, 0x4f, 0x9d, 0xfc, 0x43, 0xec, 0x75, 0xab,
- 0x93, 0x13, 0xa7, 0x55, 0xb9, 0xde, 0xed, 0x5c, 0x5b, 0xea, 0x2b, 0x65,
- 0xf9, 0xd8, 0xf2, 0x5b, 0xb6, 0xfb, 0xbb, 0x3d, 0xe5, 0x78, 0xa2, 0x52,
- 0xe2, 0x87, 0xac, 0xed, 0x42, 0x31, 0xe6, 0x32, 0xcf, 0x7a, 0xe2, 0x38,
- 0xb6, 0x93, 0xb7, 0xf9, 0xc3, 0x92, 0x03, 0xd7, 0x9b, 0x5b, 0xd4, 0x5b,
- 0x89, 0xed, 0x0a, 0x76, 0xd6, 0xf6, 0xa1, 0x97, 0xbe, 0xba, 0xab, 0x36,
- 0x18, 0xef, 0x45, 0xd4, 0xde, 0x35, 0xbd, 0xe7, 0xdf, 0xf0, 0x5e, 0x96,
- 0xbc, 0xb7, 0x9d, 0x7f, 0x37, 0xeb, 0x71, 0x74, 0xed, 0x91, 0xf9, 0x7f,
- 0x1c, 0x8f, 0x51, 0xfe, 0xce, 0x81, 0xc7, 0xf1, 0x4d, 0xda, 0x4e, 0x45,
- 0xd3, 0xd1, 0xc7, 0x2a, 0x30, 0xbb, 0xaf, 0x1c, 0xe3, 0x0f, 0x57, 0xca,
- 0x39, 0x28, 0x62, 0x62, 0xaf, 0xf2, 0x38, 0xd6, 0x0f, 0x1d, 0xa0, 0x2f,
- 0x3a, 0xfe, 0x47, 0x2c, 0xce, 0xc7, 0xab, 0x00, 0xd6, 0x11, 0x93, 0x73,
- 0xb8, 0xee, 0xc7, 0x9a, 0xc4, 0x61, 0xc7, 0xf7, 0x0b, 0xa2, 0xab, 0xe8,
- 0xf7, 0x6d, 0xf4, 0xfb, 0xe5, 0xf4, 0xfb, 0x56, 0xfa, 0x7d, 0x0b, 0xfd,
- 0x3e, 0x46, 0xbf, 0x8f, 0xd2, 0xef, 0x23, 0xf4, 0xfb, 0x66, 0xfa, 0xbd,
- 0x49, 0xbf, 0x87, 0x72, 0xa2, 0xf9, 0x38, 0x3c, 0xfd, 0x5e, 0xda, 0x50,
- 0xee, 0x3d, 0x99, 0x83, 0xc4, 0x9f, 0xd3, 0xe6, 0x9c, 0xc0, 0x62, 0xc6,
- 0xd5, 0x61, 0x62, 0x44, 0x7a, 0xe4, 0xaf, 0x9c, 0x77, 0x2a, 0xd2, 0xc4,
- 0xfd, 0x57, 0xa8, 0x8f, 0xa5, 0xe1, 0x1a, 0xf3, 0x69, 0xc6, 0xb0, 0x5f,
- 0x18, 0xf5, 0x3d, 0x7e, 0x96, 0xf9, 0x41, 0xaa, 0xbe, 0x6f, 0x1a, 0x0c,
- 0xab, 0x51, 0xdd, 0x0a, 0xac, 0xf4, 0x73, 0xcc, 0x72, 0xde, 0x6e, 0x25,
- 0x1e, 0x1b, 0x6c, 0xc3, 0x7f, 0x19, 0xd4, 0xa8, 0x8b, 0x9a, 0xf1, 0x5b,
- 0x5d, 0xf8, 0x71, 0x00, 0x2e, 0xff, 0x35, 0xc0, 0xe7, 0x55, 0x98, 0x73,
- 0x58, 0xde, 0xef, 0x4b, 0x57, 0xb9, 0x1a, 0x66, 0x42, 0x6c, 0x04, 0x44,
- 0x6a, 0x17, 0x33, 0xc1, 0x39, 0xce, 0x3b, 0x40, 0xb1, 0x55, 0x82, 0xe9,
- 0x45, 0xd8, 0x5a, 0xe7, 0xe0, 0xec, 0xb3, 0x72, 0x6e, 0xb0, 0x8a, 0x78,
- 0xe4, 0x8b, 0xb6, 0x62, 0x5b, 0xaf, 0x75, 0x7f, 0x15, 0x96, 0xa3, 0xa7,
- 0x37, 0xa7, 0x83, 0x87, 0xc3, 0x1a, 0xa9, 0x42, 0x48, 0x9f, 0xa3, 0xc0,
- 0xdd, 0xd1, 0x1c, 0xc1, 0x83, 0x99, 0x04, 0xfa, 0x38, 0xc6, 0x0d, 0xf4,
- 0xb3, 0x75, 0x7f, 0xfa, 0xdd, 0x4e, 0x7c, 0x33, 0xa1, 0xd3, 0xfe, 0x2f,
- 0xda, 0xe9, 0x8a, 0x39, 0x7d, 0x55, 0x30, 0x3a, 0x57, 0xa8, 0xf3, 0x98,
- 0xd3, 0x06, 0x8f, 0xc8, 0xc2, 0xf7, 0xf4, 0xa8, 0xd7, 0xaa, 0x20, 0x36,
- 0xcf, 0x1a, 0x80, 0x32, 0x9c, 0x94, 0xf7, 0x20, 0xba, 0xf0, 0xff, 0x99,
- 0x6d, 0x8e, 0xfd, 0x8c, 0xbb, 0x34, 0xcc, 0x4c, 0xca, 0x7d, 0x7b, 0xc1,
- 0x67, 0x4d, 0xc1, 0x3a, 0xdd, 0xb5, 0x81, 0xf7, 0xab, 0xf1, 0x23, 0xc6,
- 0xd9, 0xc0, 0xc0, 0x02, 0xa8, 0x4d, 0x5e, 0xdc, 0xdd, 0x50, 0x8a, 0xf8,
- 0x4a, 0xe1, 0xa1, 0x92, 0xef, 0xbb, 0xa9, 0xcf, 0xff, 0x17, 0x0f, 0x99,
- 0xcf, 0x61, 0xc2, 0x9f, 0x70, 0xf6, 0xdd, 0xd7, 0x99, 0x77, 0x28, 0x16,
- 0xaf, 0xb7, 0xa5, 0x2c, 0x6c, 0x30, 0x99, 0x0b, 0xdd, 0x53, 0xc9, 0x9c,
- 0x44, 0xca, 0x4b, 0xbb, 0x5b, 0x9d, 0xf6, 0x0e, 0xa6, 0xe4, 0x7a, 0xf7,
- 0x64, 0x9f, 0x77, 0x01, 0x95, 0x5e, 0xe2, 0xad, 0x82, 0x33, 0xb5, 0x09,
- 0xfa, 0x34, 0x7e, 0xec, 0x46, 0x4d, 0xba, 0x5f, 0x75, 0xfd, 0xf8, 0x1a,
- 0xcc, 0x31, 0x7f, 0xaf, 0xca, 0x7c, 0xc4, 0xf0, 0x54, 0x48, 0x41, 0xa5,
- 0x61, 0x9c, 0xff, 0x19, 0x7d, 0x6b, 0xc2, 0x95, 0xc0, 0x53, 0x63, 0xa7,
- 0xec, 0xf1, 0x6b, 0xfc, 0x9c, 0x73, 0xa9, 0xdb, 0x86, 0x0f, 0x06, 0x65,
- 0xce, 0x64, 0x9d, 0x9f, 0xb1, 0x5d, 0xd5, 0x51, 0xca, 0x7b, 0xa7, 0x87,
- 0x4d, 0xe6, 0x3a, 0x6d, 0xf8, 0xc7, 0xc1, 0x95, 0xf8, 0xfd, 0x60, 0x4d,
- 0xdb, 0x7f, 0x52, 0x6d, 0x7b, 0x69, 0xf8, 0x6b, 0xf8, 0x65, 0xa5, 0x86,
- 0xa7, 0x69, 0x43, 0xbf, 0x4f, 0x58, 0x4b, 0xaf, 0x21, 0x16, 0xfc, 0xef,
- 0x44, 0xf0, 0xc2, 0x49, 0x67, 0x5f, 0xa9, 0xde, 0xfc, 0xd0, 0x15, 0x8c,
- 0x9f, 0x51, 0x83, 0xd6, 0x36, 0x65, 0x39, 0xec, 0x4c, 0x2b, 0xce, 0x67,
- 0xa6, 0xda, 0x42, 0x97, 0x8d, 0x2a, 0xb1, 0x03, 0xb1, 0x07, 0xda, 0x22,
- 0x73, 0xb9, 0x9f, 0x92, 0x47, 0x77, 0x7f, 0x95, 0xf6, 0x98, 0xa2, 0x3d,
- 0xa6, 0x68, 0x8f, 0xc4, 0xa4, 0xe7, 0x89, 0x55, 0x3f, 0x48, 0xd1, 0x1e,
- 0xe9, 0x3f, 0xcf, 0xd1, 0x7f, 0x72, 0x5c, 0xb9, 0xdd, 0x39, 0xb7, 0xf6,
- 0x06, 0x63, 0x62, 0xe2, 0x09, 0x79, 0x27, 0xad, 0x66, 0x43, 0x16, 0xc1,
- 0xf6, 0x5e, 0xe5, 0xb3, 0x72, 0x39, 0x67, 0xfb, 0xed, 0x90, 0xf8, 0x40,
- 0x6e, 0x3f, 0xe0, 0xc8, 0xc8, 0x63, 0x65, 0xf2, 0x7e, 0xd4, 0xc1, 0xbd,
- 0xff, 0x92, 0xce, 0xfe, 0x3b, 0xe5, 0x10, 0x7d, 0xfd, 0x5b, 0xc7, 0x2e,
- 0xba, 0xfc, 0x1b, 0xfb, 0x97, 0x55, 0x32, 0xfe, 0x55, 0xf8, 0x62, 0xb0,
- 0x05, 0xe7, 0x19, 0x7f, 0xdf, 0x6a, 0x1a, 0xef, 0x0c, 0x20, 0xd8, 0x51,
- 0xae, 0x46, 0x91, 0xcd, 0xb4, 0xe0, 0xb3, 0x44, 0x14, 0x07, 0x12, 0x35,
- 0xed, 0x35, 0xae, 0xb3, 0x6a, 0x7c, 0x86, 0x58, 0x54, 0x0c, 0x9f, 0x92,
- 0x5f, 0x2e, 0xac, 0x8d, 0x60, 0x88, 0x6d, 0x7a, 0xa2, 0x1a, 0x46, 0x9a,
- 0xc5, 0x56, 0x73, 0xef, 0x4e, 0xfd, 0xa9, 0xbf, 0x2e, 0xda, 0xe3, 0x7b,
- 0x4d, 0x17, 0xed, 0x71, 0xcd, 0x6b, 0x69, 0xf4, 0xe1, 0xd2, 0x3d, 0xf2,
- 0x6e, 0xa9, 0xf8, 0xb3, 0x82, 0x1f, 0x84, 0xc7, 0xdb, 0xa6, 0x21, 0xf8,
- 0xec, 0x7d, 0xb4, 0xf5, 0x93, 0x49, 0x59, 0x53, 0x6c, 0xc1, 0xfb, 0x2c,
- 0xef, 0xa6, 0x5f, 0x9c, 0xcc, 0xb8, 0xdd, 0xbf, 0x4c, 0x2a, 0xcc, 0x4b,
- 0x97, 0xe3, 0x97, 0x99, 0x37, 0xd5, 0x8f, 0x35, 0x13, 0x67, 0xb2, 0x2b,
- 0x69, 0x4f, 0x92, 0xff, 0xc7, 0x98, 0xff, 0x07, 0x3b, 0x8f, 0x60, 0x25,
- 0xca, 0x0f, 0xad, 0x42, 0xd9, 0x1e, 0xe2, 0x67, 0x88, 0xf9, 0x3f, 0xaf,
- 0x67, 0xec, 0x91, 0xf7, 0x0d, 0xca, 0xed, 0xed, 0xab, 0x44, 0x2f, 0x82,
- 0x27, 0x7f, 0x57, 0x8e, 0xb2, 0x55, 0xc0, 0x21, 0xa9, 0x67, 0xb0, 0xde,
- 0x4a, 0x54, 0xee, 0xa9, 0x89, 0x2c, 0x46, 0xcd, 0xf9, 0xdb, 0xd4, 0x95,
- 0xb8, 0xfe, 0xd0, 0x3f, 0x73, 0x0e, 0xa4, 0x6c, 0x35, 0x9e, 0xa0, 0xdd,
- 0x16, 0x92, 0x13, 0xb6, 0x24, 0x7f, 0x6d, 0xcf, 0xa4, 0x2f, 0x7e, 0xf6,
- 0x15, 0x60, 0x5d, 0xd6, 0x60, 0xbc, 0x2b, 0x46, 0x7c, 0xe8, 0x29, 0xbb,
- 0x3c, 0xea, 0xc6, 0x9a, 0x6c, 0x03, 0x16, 0x0f, 0xd8, 0xf6, 0xb9, 0xb9,
- 0x31, 0xf8, 0xa2, 0x3e, 0x62, 0x98, 0x0f, 0x8f, 0x26, 0x4b, 0xf8, 0x2d,
- 0xc7, 0x4f, 0x42, 0xe3, 0xb3, 0x55, 0x63, 0xc3, 0x0c, 0x97, 0xd1, 0x9e,
- 0x55, 0x24, 0xee, 0xfb, 0xf0, 0x08, 0xe3, 0xf3, 0xd2, 0x64, 0x00, 0xf1,
- 0xac, 0x6d, 0xbf, 0xd9, 0xec, 0xc7, 0xc3, 0xac, 0xdf, 0x9a, 0xec, 0x41,
- 0x37, 0xed, 0x22, 0x7e, 0xc8, 0xd0, 0x35, 0xc6, 0xfb, 0x75, 0x59, 0x2f,
- 0x63, 0x58, 0x25, 0x6e, 0x63, 0x2c, 0x7a, 0x54, 0xce, 0xca, 0xd0, 0x07,
- 0xdf, 0x31, 0xad, 0x1b, 0x5c, 0x30, 0xd0, 0x99, 0xf5, 0x63, 0x79, 0x32,
- 0x78, 0x41, 0xde, 0xcd, 0xfb, 0xcc, 0xac, 0xc3, 0xc6, 0x6c, 0x00, 0xb7,
- 0x27, 0x8f, 0x3e, 0x3a, 0x13, 0xd6, 0x7f, 0x9e, 0x81, 0x06, 0x7c, 0x3d,
- 0x5b, 0xcd, 0xf6, 0x83, 0x1b, 0xde, 0x50, 0xaa, 0xf1, 0x8d, 0x43, 0x26,
- 0xdb, 0x57, 0xb1, 0x8c, 0xed, 0x2c, 0x49, 0x5e, 0x8f, 0x47, 0x0e, 0x35,
- 0xe3, 0xc1, 0x6c, 0x13, 0x16, 0x31, 0x3e, 0x75, 0x30, 0x37, 0xc4, 0xbd,
- 0xc0, 0xed, 0x03, 0xa2, 0x7b, 0x28, 0x6f, 0x36, 0x8f, 0x33, 0x5f, 0x36,
- 0x41, 0x43, 0x74, 0xf6, 0x92, 0x77, 0xd2, 0x56, 0x6f, 0xdf, 0xdf, 0x84,
- 0xa5, 0x03, 0x2a, 0x6a, 0xc2, 0x85, 0x88, 0xb7, 0x29, 0x68, 0x19, 0x90,
- 0x38, 0x2b, 0xdc, 0xc6, 0x64, 0x5c, 0x0d, 0xb1, 0x0f, 0x93, 0x71, 0x35,
- 0x77, 0xbf, 0x3b, 0x25, 0x6b, 0x0b, 0x6f, 0x93, 0x2f, 0x85, 0xd1, 0xe2,
- 0xc4, 0x68, 0x59, 0x13, 0xb7, 0xe0, 0x66, 0xec, 0x0e, 0xd3, 0xc6, 0x17,
- 0x34, 0x4a, 0xac, 0xd6, 0x9d, 0xbd, 0xa9, 0xb1, 0x7e, 0xa3, 0xe3, 0x82,
- 0x42, 0xfb, 0xda, 0x2f, 0x31, 0xd1, 0x8f, 0x8d, 0xc9, 0x28, 0xde, 0xe9,
- 0x63, 0xbc, 0xb9, 0x31, 0xb6, 0xb4, 0x04, 0x86, 0xf9, 0x08, 0x42, 0xd6,
- 0x49, 0xc6, 0xf6, 0xf3, 0xe9, 0x4a, 0x2c, 0xde, 0x23, 0x65, 0x1a, 0xf1,
- 0xee, 0xb0, 0xec, 0x4d, 0x6e, 0xc2, 0x53, 0x7d, 0x2e, 0x0c, 0x99, 0x35,
- 0x3d, 0x2a, 0xe3, 0xe7, 0xfc, 0xc6, 0xa0, 0xf6, 0x23, 0x72, 0xd5, 0x0b,
- 0x4d, 0x8c, 0xca, 0xd7, 0x34, 0xa3, 0x85, 0x72, 0xb5, 0x18, 0xe2, 0x93,
- 0x16, 0x1e, 0x6c, 0xde, 0x84, 0x93, 0x7d, 0x86, 0xf5, 0xb4, 0xac, 0x03,
- 0x34, 0xf2, 0xf9, 0x74, 0x37, 0x36, 0x1b, 0xc2, 0x69, 0x75, 0xfa, 0x16,
- 0x59, 0xa7, 0xd1, 0x8c, 0x77, 0x68, 0xaf, 0x3d, 0xe9, 0x05, 0x8c, 0xfd,
- 0x12, 0xf3, 0xbd, 0x56, 0x80, 0xf5, 0xca, 0xbf, 0xa2, 0xe0, 0xf4, 0x01,
- 0xe1, 0x58, 0x0b, 0x70, 0xff, 0x80, 0xec, 0x0b, 0xa8, 0x98, 0x7f, 0x68,
- 0x35, 0xce, 0xed, 0xce, 0x71, 0xae, 0x37, 0xc3, 0xd6, 0xd7, 0xc9, 0xb9,
- 0xda, 0x4b, 0xc9, 0xb9, 0xc8, 0xe5, 0xea, 0x36, 0x2a, 0x6e, 0x84, 0xb2,
- 0x11, 0xf2, 0x0a, 0xe1, 0x17, 0x01, 0x3c, 0x93, 0x69, 0xc6, 0x6d, 0xc9,
- 0x6a, 0x8c, 0x90, 0x6f, 0xa5, 0x89, 0x17, 0xe9, 0x0c, 0xe3, 0xca, 0x70,
- 0x15, 0x3f, 0x3a, 0x3f, 0xb3, 0xf8, 0x31, 0x9c, 0x7b, 0x6b, 0x68, 0xcb,
- 0xb1, 0x36, 0xc5, 0xd9, 0xdb, 0x18, 0xca, 0x48, 0xac, 0x56, 0x98, 0xb7,
- 0xde, 0xa5, 0x49, 0x6e, 0x2a, 0xe7, 0x0e, 0x7e, 0xde, 0xa7, 0xe3, 0x5b,
- 0x8d, 0x3b, 0x95, 0x58, 0xa5, 0xf3, 0x5e, 0x92, 0x55, 0x4c, 0xd9, 0x6e,
- 0x9b, 0x2b, 0x6b, 0x94, 0x62, 0x97, 0x6c, 0x83, 0x39, 0xfa, 0xc3, 0x66,
- 0x05, 0xf4, 0x0a, 0x5d, 0xce, 0x50, 0xd2, 0xdf, 0xfd, 0x78, 0x35, 0x11,
- 0x47, 0x26, 0x51, 0xdf, 0xb3, 0x51, 0x71, 0xc9, 0xd9, 0xf3, 0xba, 0xb8,
- 0x22, 0x3e, 0x16, 0x87, 0x27, 0xe9, 0xb5, 0xca, 0x59, 0xff, 0x9d, 0xb9,
- 0x1d, 0x8c, 0x07, 0xf5, 0x9c, 0x62, 0xd5, 0x39, 0x7f, 0x9e, 0x46, 0x07,
- 0xd6, 0x25, 0x0c, 0xc6, 0xc0, 0xd5, 0x76, 0x37, 0xe7, 0xe1, 0x58, 0xa2,
- 0x03, 0xf7, 0x27, 0xea, 0xc7, 0x9f, 0xa4, 0x6d, 0xe1, 0xee, 0x0e, 0xb4,
- 0xf0, 0xd9, 0x50, 0xaa, 0xe6, 0x42, 0x37, 0x75, 0x3d, 0x31, 0xad, 0xce,
- 0x59, 0x97, 0x77, 0x1b, 0x3a, 0xcb, 0xeb, 0xc4, 0xb3, 0xfa, 0xd8, 0x80,
- 0xfa, 0xef, 0x15, 0x4c, 0x97, 0x5c, 0x32, 0x82, 0xe3, 0x09, 0x1f, 0xbe,
- 0x9e, 0xb4, 0xe8, 0x03, 0xc0, 0xfa, 0x6c, 0x33, 0xf3, 0x88, 0xa7, 0xec,
- 0x0a, 0x87, 0xeb, 0xba, 0x69, 0x83, 0x0b, 0x70, 0x82, 0xb1, 0xb7, 0x66,
- 0x9e, 0xa1, 0x2d, 0x52, 0xe4, 0x7d, 0xeb, 0x5f, 0xdb, 0xee, 0x68, 0x09,
- 0x36, 0x0c, 0x85, 0x22, 0x2b, 0x19, 0x67, 0x9f, 0x6a, 0x36, 0xc6, 0x6d,
- 0xc6, 0xc0, 0x19, 0xd1, 0x04, 0xe7, 0x3a, 0x24, 0xff, 0xaf, 0x03, 0x7f,
- 0x41, 0x3b, 0xff, 0x24, 0x21, 0x7e, 0x62, 0x10, 0x37, 0xfd, 0xf8, 0x06,
- 0xed, 0xfc, 0x7c, 0xa2, 0x0e, 0x59, 0xfa, 0x65, 0x07, 0xfd, 0xe3, 0xdd,
- 0x44, 0x30, 0x7e, 0x93, 0xca, 0x7c, 0x8f, 0xfe, 0xf1, 0x51, 0x22, 0x42,
- 0xdf, 0xf9, 0x2a, 0x3f, 0x0d, 0xf4, 0x87, 0x3a, 0xd6, 0xd1, 0xe9, 0x07,
- 0x7e, 0x9c, 0x65, 0xf9, 0x03, 0xa9, 0x9a, 0xd6, 0x15, 0x4a, 0x8d, 0x59,
- 0xa3, 0x54, 0x30, 0x9f, 0xd5, 0x68, 0xff, 0xb7, 0xe0, 0x43, 0x59, 0x4f,
- 0x4e, 0x12, 0x8b, 0x92, 0xe8, 0x2f, 0x22, 0x97, 0x5b, 0xe9, 0x9c, 0xe5,
- 0xaf, 0x3f, 0xf1, 0xa9, 0x12, 0x1c, 0x3f, 0xe3, 0x0a, 0x76, 0xcc, 0x20,
- 0x8f, 0xfe, 0x0b, 0xfa, 0xc1, 0x37, 0x59, 0xf6, 0x93, 0xbe, 0x62, 0x7c,
- 0x63, 0x88, 0x31, 0x37, 0x55, 0x80, 0x82, 0x3d, 0x5e, 0x3c, 0x78, 0x48,
- 0xc7, 0x3e, 0x27, 0x57, 0x17, 0x9d, 0x52, 0x77, 0xc4, 0x88, 0x73, 0x73,
- 0x81, 0x19, 0x07, 0x56, 0xe3, 0xd4, 0x6e, 0x9d, 0x71, 0x2f, 0x67, 0x27,
- 0xcf, 0x86, 0x1d, 0x6e, 0x1e, 0x17, 0x6e, 0x5e, 0xc0, 0x71, 0x6d, 0x4d,
- 0x85, 0xda, 0xb7, 0x51, 0x17, 0xb7, 0x67, 0xc5, 0xfe, 0x22, 0x78, 0x8e,
- 0x63, 0xeb, 0xa7, 0xad, 0x1c, 0x48, 0x54, 0x33, 0x47, 0xf7, 0xc1, 0xa2,
- 0xad, 0x58, 0xf2, 0x0e, 0x13, 0x6d, 0xc5, 0xa2, 0xad, 0x58, 0xb4, 0x15,
- 0x8b, 0xb6, 0x62, 0x65, 0x16, 0xe0, 0x99, 0x3e, 0x03, 0x23, 0xec, 0x73,
- 0xe7, 0x30, 0x39, 0xbc, 0xf3, 0x3e, 0x50, 0x9d, 0xe4, 0x29, 0xca, 0xc4,
- 0xdd, 0xb7, 0x60, 0xa8, 0xef, 0x56, 0x7e, 0x14, 0xb4, 0xd2, 0x66, 0x7a,
- 0xd2, 0x62, 0x83, 0x22, 0x93, 0x17, 0xc3, 0x99, 0x9b, 0x2b, 0x51, 0x2c,
- 0xf1, 0x5d, 0xc1, 0x0e, 0xe7, 0x7e, 0xde, 0xd6, 0xe4, 0x9e, 0x85, 0x9a,
- 0x79, 0x9b, 0xf0, 0x48, 0x9f, 0x8a, 0xdb, 0xc2, 0xf2, 0x7f, 0x08, 0x9a,
- 0x99, 0x0f, 0xc8, 0xfe, 0x7c, 0x82, 0xfe, 0x99, 0xb3, 0x15, 0x19, 0x53,
- 0xa6, 0x7f, 0x13, 0x4e, 0xf4, 0x1b, 0x8c, 0x59, 0x26, 0x32, 0xe9, 0x04,
- 0x7d, 0x42, 0xfc, 0xdc, 0xc0, 0x33, 0x6c, 0x6b, 0xf6, 0x80, 0x0b, 0x95,
- 0x8d, 0x6e, 0x94, 0xd0, 0xdf, 0x6f, 0x4b, 0xd7, 0x04, 0xbe, 0xa5, 0x24,
- 0x9c, 0xf5, 0xd7, 0x5d, 0x29, 0x8c, 0xcf, 0x34, 0x2a, 0xb1, 0x6f, 0xb0,
- 0x11, 0x8f, 0xed, 0x76, 0xd1, 0x46, 0xed, 0x05, 0xe5, 0x4d, 0x46, 0xc7,
- 0x02, 0x97, 0xe0, 0x45, 0x23, 0xbe, 0xc1, 0x1c, 0x60, 0x7d, 0x7f, 0xd0,
- 0x7c, 0x05, 0x41, 0xf3, 0x24, 0x16, 0xe0, 0x59, 0x93, 0xb8, 0x39, 0xaf,
- 0x11, 0x1b, 0xf7, 0x1b, 0xb4, 0x29, 0x37, 0xf3, 0x63, 0xf9, 0xbf, 0x37,
- 0xba, 0xb3, 0xc6, 0xf3, 0x32, 0xe4, 0x9c, 0x43, 0xb3, 0xfc, 0x4f, 0x06,
- 0xa5, 0x87, 0xf8, 0x34, 0xa3, 0xd7, 0xe0, 0xb8, 0x5f, 0xb0, 0x4b, 0x0d,
- 0xf9, 0x7f, 0x1c, 0xc4, 0x11, 0x8e, 0xfb, 0xc2, 0xcd, 0x6f, 0xdb, 0x95,
- 0x86, 0xc4, 0x50, 0xe2, 0x49, 0x5a, 0xfa, 0x8f, 0xed, 0x08, 0x10, 0x3b,
- 0x3a, 0xfa, 0x8d, 0x78, 0x29, 0x63, 0xd8, 0x46, 0x07, 0x63, 0x04, 0x5f,
- 0x8c, 0xb6, 0x6f, 0x21, 0xa4, 0xad, 0x20, 0xee, 0x9c, 0xe6, 0x58, 0x7a,
- 0x52, 0x82, 0x51, 0x3a, 0x8a, 0x7a, 0x63, 0xb8, 0x81, 0x39, 0x63, 0x41,
- 0x6f, 0x0b, 0x6a, 0x99, 0x3f, 0xba, 0x7b, 0x5b, 0x61, 0x30, 0x97, 0x9c,
- 0xd9, 0xbb, 0x1c, 0x0b, 0xc6, 0xf2, 0x1c, 0x5a, 0xc7, 0x11, 0x67, 0xdd,
- 0xea, 0x29, 0x78, 0xee, 0xd3, 0x69, 0x53, 0x72, 0xe6, 0xc5, 0x6b, 0x55,
- 0x12, 0x37, 0xcf, 0x50, 0xd7, 0xed, 0x03, 0xab, 0xed, 0x81, 0x94, 0xf0,
- 0xa6, 0x2e, 0x78, 0x9a, 0x24, 0xf7, 0xd1, 0x31, 0x46, 0x8e, 0x3c, 0xcc,
- 0x1c, 0xec, 0x8d, 0xfd, 0xab, 0x71, 0xff, 0x9e, 0xcb, 0x39, 0x9b, 0xd9,
- 0x64, 0xfd, 0x7b, 0xda, 0xc5, 0x86, 0x12, 0xda, 0x85, 0x97, 0x76, 0xb1,
- 0x2b, 0x15, 0x32, 0x0f, 0xd3, 0x2e, 0x6a, 0x89, 0x21, 0x1d, 0xbd, 0x92,
- 0xef, 0x38, 0xef, 0xed, 0x55, 0x78, 0x10, 0xc0, 0x9b, 0xb4, 0x8f, 0x8d,
- 0xbd, 0x76, 0x97, 0x9b, 0xb1, 0xa7, 0xa7, 0xb9, 0x1a, 0xaf, 0x65, 0x6e,
- 0xc5, 0xa3, 0xfd, 0xd5, 0x78, 0x85, 0xb6, 0xf3, 0x76, 0x02, 0xf3, 0x2b,
- 0xa0, 0xce, 0xac, 0x60, 0xac, 0xbe, 0x4d, 0x09, 0xb5, 0x2e, 0x42, 0xfd,
- 0xf8, 0xcb, 0x4a, 0xb0, 0x93, 0x9c, 0xe5, 0xc4, 0x05, 0x62, 0xff, 0xeb,
- 0x19, 0x39, 0x77, 0xe7, 0xc3, 0x38, 0xed, 0x6a, 0x9c, 0xf5, 0xbe, 0xd1,
- 0x5f, 0xc7, 0x79, 0xf3, 0xa0, 0xd0, 0xf0, 0xe3, 0x14, 0xb1, 0xb4, 0x63,
- 0x37, 0xc6, 0x03, 0x86, 0x71, 0xa2, 0x55, 0xa9, 0xc2, 0x9b, 0xc3, 0xb7,
- 0x62, 0x63, 0x7f, 0x50, 0x8f, 0xd1, 0x37, 0x5f, 0xe3, 0xb3, 0xf5, 0xbb,
- 0x67, 0xe1, 0x38, 0x6d, 0x6f, 0x9c, 0xb6, 0xb7, 0xb6, 0x5f, 0xc5, 0x8b,
- 0xc3, 0xb7, 0xb0, 0x5f, 0x05, 0xb3, 0x6a, 0x15, 0x27, 0xff, 0xda, 0x91,
- 0x72, 0xfe, 0x77, 0x81, 0xf3, 0x8e, 0xde, 0x9c, 0x51, 0x13, 0xb3, 0xf7,
- 0xcb, 0xf8, 0xc8, 0xc3, 0x9c, 0xb5, 0xe9, 0x46, 0xdc, 0xbc, 0xa7, 0x12,
- 0xe7, 0xf6, 0x1a, 0x56, 0xb9, 0xcb, 0x5e, 0x70, 0x2a, 0x1c, 0xe2, 0x3c,
- 0x34, 0xa2, 0xe1, 0x50, 0x23, 0x42, 0x03, 0xb9, 0x18, 0xa1, 0x19, 0x0b,
- 0xf0, 0x3d, 0xce, 0xfb, 0x5a, 0xe6, 0x80, 0x35, 0x43, 0x82, 0xbd, 0x36,
- 0x73, 0xc5, 0x66, 0x4c, 0x8c, 0x8d, 0x73, 0x6c, 0x11, 0x9c, 0x25, 0xbf,
- 0x7d, 0x9f, 0x31, 0xe3, 0x43, 0xe6, 0x80, 0x1f, 0x3a, 0x31, 0x43, 0xde,
- 0xa5, 0xbd, 0x32, 0x6e, 0xec, 0xe2, 0x9c, 0x6e, 0xec, 0x37, 0xea, 0xfa,
- 0xf8, 0x7b, 0xbd, 0x33, 0xc7, 0x31, 0xe2, 0xb9, 0x60, 0x85, 0xe0, 0x7f,
- 0x0b, 0x73, 0xde, 0x56, 0x9c, 0xed, 0x0b, 0x99, 0x0b, 0x95, 0x56, 0xbc,
- 0x47, 0x99, 0xfb, 0x28, 0x5f, 0x92, 0xbc, 0x6c, 0x66, 0xd2, 0x18, 0xff,
- 0xd0, 0x25, 0x18, 0xd3, 0x8a, 0xf2, 0xec, 0xad, 0x38, 0xd5, 0xbf, 0x1c,
- 0xa5, 0x43, 0xc2, 0x35, 0xa5, 0x4d, 0x37, 0xb6, 0xee, 0xbe, 0x13, 0xeb,
- 0x0f, 0xe6, 0x72, 0xbe, 0xf5, 0x89, 0x4d, 0xcc, 0x75, 0x85, 0xbf, 0xd7,
- 0xe1, 0x50, 0x2a, 0x26, 0x47, 0x42, 0x77, 0x30, 0x9f, 0x8b, 0xac, 0x20,
- 0x7e, 0x2e, 0x0d, 0x13, 0x63, 0x2b, 0x82, 0x81, 0x97, 0x61, 0xe9, 0xbc,
- 0x17, 0x58, 0x07, 0xd1, 0x89, 0x85, 0x65, 0x8c, 0x3b, 0xb7, 0xf5, 0xbb,
- 0x29, 0xbb, 0x3c, 0xaf, 0xc3, 0x8f, 0x52, 0x56, 0x5c, 0x9e, 0x6f, 0x84,
- 0xf8, 0x8a, 0xe8, 0xc9, 0x05, 0xb3, 0xa9, 0x26, 0xd6, 0x41, 0x8c, 0x2e,
- 0x0d, 0x07, 0xcd, 0x6f, 0xa0, 0x99, 0x73, 0x2f, 0x32, 0x47, 0xb0, 0xfe,
- 0x10, 0x9c, 0x7d, 0x7f, 0x79, 0x47, 0xe4, 0x3f, 0xf4, 0xed, 0x76, 0xec,
- 0x69, 0x7d, 0xe3, 0x65, 0x1b, 0x3c, 0x90, 0xaa, 0xef, 0x74, 0xa1, 0xc6,
- 0x2a, 0x87, 0x91, 0xee, 0x23, 0x2f, 0x8d, 0x23, 0xd8, 0x13, 0x87, 0xc4,
- 0x8c, 0x7a, 0x4b, 0x43, 0x35, 0xdb, 0x8e, 0xe0, 0xad, 0x84, 0x4b, 0xb0,
- 0x09, 0xf2, 0x4f, 0x8a, 0x22, 0xc4, 0xe1, 0x37, 0x12, 0xc5, 0xd0, 0x87,
- 0x12, 0xce, 0xff, 0x11, 0xba, 0x39, 0x6b, 0x91, 0xaf, 0x2d, 0xc0, 0xab,
- 0xfd, 0x3e, 0xcc, 0x27, 0x4f, 0xa9, 0x4b, 0x3e, 0x65, 0x97, 0x12, 0x87,
- 0xeb, 0x87, 0x42, 0x9a, 0x47, 0xb1, 0xed, 0x03, 0x73, 0x7f, 0x6d, 0x4f,
- 0x8b, 0x4a, 0x59, 0x23, 0xb2, 0x48, 0xfe, 0x9f, 0xd4, 0x3c, 0xa3, 0xf5,
- 0x2c, 0x7c, 0xb8, 0x81, 0x58, 0x7a, 0xac, 0xb7, 0x12, 0x6f, 0xed, 0xee,
- 0x91, 0x35, 0x4b, 0x18, 0xfc, 0xfd, 0x5a, 0x6f, 0x00, 0x3a, 0xb1, 0x4c,
- 0xe7, 0x75, 0x03, 0x31, 0x5a, 0x27, 0x3e, 0xbf, 0xdd, 0x6b, 0x2f, 0xf0,
- 0x35, 0x59, 0x6c, 0xbd, 0x0e, 0x0b, 0x88, 0xd1, 0x6f, 0xf4, 0x06, 0x4f,
- 0x2c, 0x51, 0x15, 0x94, 0x34, 0x99, 0xec, 0xdb, 0x87, 0x17, 0x69, 0xdf,
- 0x4f, 0xa4, 0x8e, 0x7e, 0x6d, 0x06, 0xac, 0xfa, 0x12, 0x04, 0x37, 0x78,
- 0x14, 0x59, 0xe3, 0x90, 0xd8, 0x56, 0x8d, 0x1b, 0xc9, 0x4d, 0x74, 0xe2,
- 0x77, 0x4d, 0x56, 0xe2, 0x1c, 0xb0, 0x66, 0x68, 0x35, 0x3e, 0x1c, 0x14,
- 0x1f, 0xc5, 0x42, 0xb1, 0xff, 0x05, 0xe1, 0x90, 0x79, 0x86, 0xb8, 0x5c,
- 0x3b, 0x96, 0x20, 0xfe, 0xca, 0xb9, 0x3c, 0x8c, 0xab, 0xc4, 0x81, 0xca,
- 0x94, 0x60, 0x57, 0x00, 0x8d, 0xcc, 0xf7, 0xca, 0x53, 0xe2, 0x93, 0x96,
- 0x9c, 0x1b, 0xc1, 0xcd, 0x63, 0x3e, 0xe8, 0x63, 0x1a, 0x3f, 0x7e, 0xe8,
- 0x23, 0x55, 0xfc, 0x50, 0xd6, 0x91, 0x59, 0xfc, 0x50, 0x56, 0xc6, 0x31,
- 0x73, 0x44, 0xc1, 0x4d, 0x8e, 0x6d, 0x89, 0x0f, 0x7a, 0xf1, 0xec, 0x28,
- 0xb0, 0xa1, 0xdf, 0xc4, 0xe1, 0xfd, 0x39, 0x9c, 0xdb, 0xcc, 0x3e, 0x42,
- 0x03, 0x61, 0xac, 0x4f, 0x8b, 0x7d, 0x36, 0xe2, 0xb7, 0x7b, 0x8d, 0xb6,
- 0x35, 0x6a, 0x28, 0xb2, 0x9c, 0x18, 0xf6, 0xfe, 0x48, 0x23, 0x3e, 0x7c,
- 0x62, 0x01, 0x8c, 0x70, 0x23, 0xce, 0x1c, 0xd8, 0x84, 0xf2, 0x27, 0x54,
- 0xe2, 0x8f, 0x8a, 0xf1, 0xe9, 0x82, 0xed, 0x82, 0xa3, 0x5e, 0xab, 0x8c,
- 0xb8, 0xb5, 0x8d, 0xb8, 0xf5, 0xb3, 0xb9, 0xe3, 0x98, 0x9f, 0x94, 0x73,
- 0xad, 0xcc, 0xaf, 0xd4, 0x08, 0x9e, 0x24, 0x6e, 0xed, 0xea, 0x93, 0xf9,
- 0xe2, 0xdc, 0x12, 0xb3, 0xb6, 0xa6, 0x73, 0x9c, 0xe8, 0x70, 0xbf, 0xa1,
- 0xb9, 0x68, 0xcb, 0x43, 0x93, 0x78, 0xf5, 0x5b, 0xc6, 0xff, 0x47, 0xe6,
- 0x45, 0x71, 0x36, 0x2d, 0x7e, 0x25, 0x71, 0x45, 0xc7, 0x87, 0xb4, 0xf1,
- 0xa5, 0xd4, 0xf5, 0x19, 0xe6, 0x16, 0x2d, 0x8c, 0x73, 0x1f, 0xd3, 0x9e,
- 0x97, 0x93, 0x3f, 0xbe, 0x97, 0x12, 0x1b, 0x59, 0x8e, 0x25, 0x59, 0xb1,
- 0x05, 0x67, 0x9d, 0x95, 0xdf, 0x31, 0x9c, 0x4e, 0xfc, 0xb1, 0xb8, 0xb0,
- 0x12, 0xaf, 0x0e, 0xca, 0x79, 0x17, 0x03, 0xde, 0xde, 0xa0, 0x56, 0xa2,
- 0xc8, 0x9e, 0x6e, 0x9e, 0xfb, 0x4e, 0x38, 0x39, 0x76, 0x69, 0x34, 0xbf,
- 0xbf, 0x98, 0xdf, 0x77, 0xb0, 0xf0, 0xfd, 0xb9, 0x01, 0xf2, 0x4f, 0x28,
- 0x87, 0xe7, 0x16, 0xe0, 0xf6, 0x3d, 0x6d, 0x18, 0xd9, 0xfd, 0x31, 0x8a,
- 0xfa, 0xd5, 0x7b, 0x7d, 0xa8, 0xa9, 0x7b, 0x48, 0xe9, 0xc2, 0xa2, 0xb0,
- 0xbc, 0xe7, 0x23, 0x6b, 0xe6, 0x7d, 0xd8, 0x7c, 0x80, 0x79, 0xcc, 0xd8,
- 0x75, 0x38, 0xaa, 0x31, 0x1e, 0x9a, 0x1f, 0xa3, 0xa0, 0xdf, 0xe3, 0x9c,
- 0x05, 0x3c, 0x6a, 0x36, 0x61, 0xe5, 0xe4, 0x59, 0x40, 0x54, 0x5d, 0xbd,
- 0x97, 0x00, 0x5f, 0xe9, 0xe4, 0xff, 0x1f, 0xc8, 0xbd, 0xdb, 0x63, 0xa0,
- 0x77, 0xf4, 0x7f, 0x95, 0xe7, 0xce, 0x06, 0xfd, 0x6b, 0xca, 0x76, 0xa2,
- 0x7d, 0xcf, 0xe3, 0x58, 0xb1, 0xe7, 0x3b, 0xb8, 0x73, 0xa0, 0xb6, 0x33,
- 0xc2, 0x5c, 0xe7, 0x83, 0xf0, 0x38, 0x8e, 0x85, 0x8b, 0x60, 0xf9, 0xc9,
- 0xb1, 0x6e, 0xfc, 0x8a, 0xbc, 0x4e, 0xca, 0xbf, 0xd3, 0xb6, 0x7e, 0xaf,
- 0xb4, 0xf7, 0xf6, 0xa4, 0x7f, 0xfd, 0x7c, 0x9a, 0x9c, 0xa7, 0x79, 0x21,
- 0xf5, 0x2b, 0x5b, 0x77, 0x9e, 0xe7, 0xef, 0xbf, 0x65, 0xc7, 0xfc, 0x72,
- 0x7f, 0xd6, 0x64, 0xbd, 0xef, 0xe0, 0x01, 0xe6, 0xbf, 0xa7, 0x9b, 0xbe,
- 0x83, 0x85, 0x43, 0x97, 0xea, 0xa0, 0x68, 0xf7, 0x3a, 0x07, 0xbb, 0xe9,
- 0x61, 0xe4, 0x48, 0xb2, 0x57, 0x25, 0xfb, 0x27, 0x7f, 0x89, 0xcd, 0x7b,
- 0x65, 0x6d, 0xd3, 0xb6, 0xd7, 0x1b, 0xb2, 0xc7, 0x97, 0x3f, 0x37, 0x27,
- 0xed, 0x58, 0x8a, 0x95, 0x91, 0xba, 0x5b, 0x94, 0xbe, 0xcc, 0xd4, 0x31,
- 0x4d, 0x93, 0xff, 0x97, 0xa7, 0x95, 0x44, 0xa7, 0x8e, 0xad, 0x47, 0xd9,
- 0x9e, 0x39, 0xa2, 0xec, 0xca, 0x5c, 0xad, 0x8f, 0xe7, 0xec, 0x58, 0x9b,
- 0xb4, 0x21, 0x32, 0xc1, 0x8f, 0x62, 0x91, 0x2b, 0xff, 0xec, 0x99, 0x49,
- 0xb9, 0x0b, 0xa1, 0x57, 0xe6, 0xe4, 0xbe, 0x9f, 0x72, 0x9b, 0x4d, 0x31,
- 0xa8, 0xf3, 0xa6, 0xca, 0x9e, 0x1f, 0xe7, 0x7f, 0xbb, 0xd4, 0x56, 0xae,
- 0xdc, 0xcd, 0x7e, 0xb1, 0x21, 0x75, 0xde, 0xd4, 0x35, 0xfb, 0x02, 0xe2,
- 0x47, 0x48, 0xdb, 0x8a, 0x5c, 0xbe, 0xb7, 0xe6, 0xca, 0x7c, 0x4f, 0xb0,
- 0x0b, 0x23, 0x09, 0x0d, 0xef, 0x99, 0x92, 0xdf, 0xc9, 0xad, 0x28, 0xbe,
- 0xc7, 0xfc, 0xf1, 0x99, 0x44, 0xb0, 0x75, 0x9d, 0x52, 0x1f, 0x9b, 0xc3,
- 0x38, 0x87, 0x0a, 0x59, 0x4f, 0x8f, 0x38, 0xff, 0xaf, 0x2a, 0x13, 0x8a,
- 0x20, 0x43, 0x7f, 0x78, 0x23, 0x11, 0xec, 0x38, 0xa3, 0xe4, 0xfe, 0x0f,
- 0xd6, 0xeb, 0xce, 0xfb, 0x1c, 0x79, 0xbb, 0x13, 0xce, 0x39, 0x75, 0x3d,
- 0x57, 0x6c, 0x30, 0xd8, 0x97, 0x46, 0xa5, 0xac, 0x9b, 0x58, 0x16, 0xf3,
- 0xa1, 0xee, 0x94, 0x15, 0x50, 0xf1, 0x15, 0xc4, 0xfd, 0xb2, 0x47, 0x72,
- 0xcb, 0xe4, 0xff, 0xa9, 0x11, 0x7e, 0xf4, 0x2f, 0xaf, 0x4f, 0xc9, 0xff,
- 0x06, 0xca, 0xdb, 0x8b, 0x35, 0x76, 0x3d, 0xd2, 0x9a, 0xac, 0x7d, 0xc0,
- 0x9a, 0x46, 0x5d, 0xfb, 0x8d, 0x4d, 0x1c, 0xb7, 0x07, 0xd3, 0x99, 0xdb,
- 0x85, 0x6b, 0xeb, 0xdb, 0x1a, 0xd5, 0x6b, 0x10, 0xab, 0x08, 0x6a, 0x31,
- 0x72, 0xcd, 0x1e, 0xe7, 0xff, 0xed, 0xc8, 0xb9, 0x14, 0xab, 0xd5, 0x4b,
- 0x4c, 0x6f, 0x52, 0x14, 0x14, 0x84, 0xe0, 0x7e, 0x28, 0xe3, 0x86, 0x56,
- 0xfb, 0x5b, 0xfb, 0x17, 0x7e, 0x03, 0xdb, 0xc6, 0x6e, 0xb9, 0xf4, 0xff,
- 0x87, 0xfe, 0x63, 0xf6, 0xea, 0xec, 0x37, 0xdf, 0xe6, 0xc7, 0x76, 0x6c,
- 0xba, 0xf4, 0x2d, 0xed, 0xfe, 0x31, 0x59, 0xf3, 0xef, 0x7a, 0xd4, 0xe8,
- 0x2e, 0x94, 0x63, 0xab, 0xb9, 0xde, 0x2f, 0x67, 0xe5, 0xd6, 0x43, 0xf6,
- 0xff, 0x65, 0x0e, 0xe4, 0x1d, 0xc3, 0x08, 0xf3, 0x6e, 0xd1, 0x4b, 0x14,
- 0x0f, 0x66, 0xe4, 0x9d, 0xa0, 0x59, 0x90, 0xff, 0xfb, 0xf5, 0x60, 0x26,
- 0xa7, 0xbf, 0x47, 0x33, 0x3e, 0xe6, 0x00, 0x3e, 0xda, 0x60, 0x07, 0xf9,
- 0x0b, 0xf9, 0xd3, 0x25, 0x5d, 0xde, 0xeb, 0x97, 0x75, 0x85, 0xef, 0xd3,
- 0xa7, 0xdd, 0xb5, 0x72, 0x6d, 0xc9, 0xb9, 0x51, 0x25, 0x77, 0x7d, 0xde,
- 0x79, 0x37, 0x52, 0x8d, 0xae, 0xc3, 0xc2, 0xc4, 0x34, 0x39, 0x3f, 0x29,
- 0x6b, 0x36, 0x96, 0x3f, 0x2a, 0xef, 0x61, 0xf8, 0x88, 0xb1, 0x5f, 0xf5,
- 0x4f, 0xbe, 0x73, 0xd5, 0xba, 0x82, 0x38, 0x36, 0x27, 0x6c, 0xc4, 0x9a,
- 0x94, 0xa0, 0xbe, 0x52, 0x69, 0x63, 0xbd, 0x3a, 0xf4, 0x64, 0xa5, 0x0d,
- 0xc5, 0xf9, 0xdf, 0x92, 0x1e, 0xb6, 0x71, 0x30, 0x51, 0xaf, 0x7b, 0xd4,
- 0x4f, 0x6d, 0xcb, 0x39, 0x03, 0x29, 0xfb, 0xf6, 0x71, 0xbc, 0x94, 0x98,
- 0x4e, 0x94, 0xba, 0xba, 0xdd, 0x4b, 0xeb, 0xe7, 0x7f, 0xa3, 0x21, 0xc6,
- 0xb6, 0x82, 0x9d, 0x61, 0x57, 0x70, 0xc3, 0x05, 0xe2, 0x4a, 0x36, 0x6c,
- 0xc4, 0x7f, 0xc0, 0x3e, 0xfe, 0x56, 0xa9, 0x43, 0x62, 0x4a, 0xfb, 0xb9,
- 0xb6, 0xea, 0xdb, 0x0b, 0xd4, 0xf3, 0xce, 0xbb, 0xf8, 0xd2, 0xbe, 0x16,
- 0x5d, 0x0d, 0x2d, 0x69, 0xd9, 0x7e, 0xb6, 0x39, 0x33, 0x1a, 0xdc, 0x57,
- 0x41, 0x30, 0xfa, 0xb6, 0xda, 0x85, 0x35, 0x72, 0x3c, 0x24, 0x1a, 0xd4,
- 0x1f, 0xa0, 0x7d, 0x34, 0x3a, 0x6d, 0xc4, 0xea, 0x0a, 0x20, 0x9c, 0xf2,
- 0x4b, 0xed, 0x84, 0x39, 0x81, 0x70, 0x31, 0x96, 0x73, 0xce, 0x03, 0xc8,
- 0xb9, 0x49, 0xe6, 0x0d, 0x09, 0xf9, 0xbf, 0x7d, 0x4e, 0x37, 0x93, 0x7b,
- 0x5a, 0xcc, 0xd7, 0x19, 0xaf, 0xd7, 0xcb, 0xff, 0x48, 0x2a, 0xf6, 0xe1,
- 0xc1, 0x84, 0xac, 0x81, 0xfc, 0x1f, 0x05, 0x3f, 0x96, 0xb4, 0x1c, 0x54,
- 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_CP_b09FwData[(0x84/4) + 1] = {
- 0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006,
- 0x00000005, 0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000003,
- 0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000002,
- 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
- 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
- 0x00000001, 0x00000001, 0x00000001, 0x00000000 };
-static const u32 bnx2_CP_b09FwRodata[(0x16c/4) + 1] = {
- 0x80080100, 0x80080080, 0x80080000, 0x08001800, 0x08001800, 0x08001838,
- 0x08001838, 0x0800184c, 0x0800181c, 0x08001a74, 0x08001a40, 0x08001acc,
- 0x08001acc, 0x08001b54, 0x08001a84, 0x80080240, 0x080021c4, 0x08002010,
- 0x080021ec, 0x08002284, 0x080023d4, 0x08002420, 0x08002544, 0x0800244c,
- 0x080024d0, 0x08002080, 0x080029f8, 0x0800299c, 0x0800202c, 0x0800202c,
- 0x0800202c, 0x080025b8, 0x080025b8, 0x0800202c, 0x0800202c, 0x08002874,
- 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x080028d4, 0x0800202c,
- 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c,
- 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c,
- 0x0800202c, 0x08002440, 0x0800202c, 0x0800202c, 0x08002944, 0x0800202c,
- 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c,
- 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c,
- 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x08002798, 0x0800202c,
- 0x0800202c, 0x08002700, 0x0800265c, 0x080037c0, 0x08003794, 0x08003760,
- 0x08003734, 0x08003714, 0x080036c8, 0x80080100, 0x80080080, 0x80080000,
- 0x80080080, 0x00000000 };
-
-static struct fw_info bnx2_cp_fw_09 = {
- /* Firmware version: 4.6.15 */
- .ver_major = 0x4,
- .ver_minor = 0x6,
- .ver_fix = 0xf,
-
- .start_addr = 0x08000080,
-
- .text_addr = 0x08000000,
- .text_len = 0x5418,
- .text_index = 0x0,
- .gz_text = bnx2_CP_b09FwText,
- .gz_text_len = sizeof(bnx2_CP_b09FwText),
-
- .data_addr = 0x080055a0,
- .data_len = 0x84,
- .data_index = 0x0,
- .data = bnx2_CP_b09FwData,
-
- .sbss_addr = 0x08005624,
- .sbss_len = 0x91,
- .sbss_index = 0x0,
-
- .bss_addr = 0x080056b8,
- .bss_len = 0x19c,
- .bss_index = 0x0,
-
- .rodata_addr = 0x08005418,
- .rodata_len = 0x16c,
- .rodata_index = 0x0,
- .rodata = bnx2_CP_b09FwRodata,
-};
-
-static u8 bnx2_RXP_b09FwText[] = {
- 0xec, 0x5c, 0x7d, 0x70, 0x1c, 0xe5, 0x79, 0xff, 0xbd, 0x7b, 0x7b, 0xd2,
- 0x4a, 0x3a, 0x9d, 0x56, 0xa7, 0x93, 0x7c, 0x22, 0x04, 0xef, 0xa2, 0x3d,
- 0xf9, 0xb0, 0x0c, 0xec, 0x9d, 0x4f, 0xb6, 0xa0, 0xdb, 0xb2, 0x83, 0x0d,
- 0x11, 0x21, 0x13, 0x84, 0x4d, 0x52, 0x33, 0x49, 0x27, 0x37, 0xc6, 0x18,
- 0x81, 0x4d, 0x70, 0x0d, 0x6d, 0x55, 0x86, 0x19, 0x6f, 0x2c, 0x7f, 0x01,
- 0x27, 0x9d, 0x62, 0x64, 0x63, 0xd2, 0x0e, 0x68, 0x6c, 0x59, 0x08, 0x7c,
- 0xd2, 0x61, 0x20, 0xad, 0xe8, 0x84, 0xfa, 0x26, 0xd8, 0xe0, 0x94, 0xcf,
- 0x21, 0x0c, 0xc3, 0x1f, 0xcd, 0xa0, 0x62, 0x3e, 0xcc, 0x94, 0xa1, 0x26,
- 0x38, 0xa9, 0xdd, 0xb8, 0x7e, 0xfb, 0x3c, 0x7b, 0x3a, 0x9b, 0x90, 0x26,
- 0x9d, 0xfc, 0xd1, 0xff, 0xf6, 0x99, 0xb9, 0xb9, 0xbd, 0x77, 0xdf, 0xf7,
- 0xf9, 0xfe, 0x7c, 0x3d, 0xf2, 0x5f, 0x47, 0x50, 0x8f, 0x39, 0x68, 0xa4,
- 0x4f, 0x76, 0xc3, 0xc0, 0xc6, 0xf4, 0x65, 0x4b, 0x2e, 0xa3, 0xc7, 0xee,
- 0x50, 0x53, 0x8d, 0xca, 0xeb, 0x02, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01,
- 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10,
- 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00,
- 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04,
- 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40,
- 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0xfc, 0x7f, 0x40, 0x08, 0xd0,
- 0xf9, 0xbb, 0x71, 0xee, 0x03, 0x4d, 0x71, 0xdc, 0x7b, 0xaf, 0xb6, 0xa0,
- 0x85, 0x9c, 0x99, 0x7b, 0x6f, 0xb1, 0x00, 0xb7, 0xd8, 0x65, 0x2c, 0xc3,
- 0x7f, 0x4b, 0x2f, 0xae, 0x82, 0xd7, 0xbf, 0xea, 0x9c, 0x79, 0xec, 0xf9,
- 0xa5, 0xe6, 0x89, 0xb1, 0x10, 0x34, 0xdd, 0x79, 0x27, 0xad, 0x77, 0x42,
- 0xbb, 0x90, 0xce, 0xfc, 0xfd, 0x82, 0x95, 0x31, 0x44, 0xab, 0xb8, 0xe0,
- 0x29, 0x8e, 0x94, 0xfb, 0x6d, 0x89, 0x17, 0x6d, 0x4f, 0x2c, 0xcb, 0xc2,
- 0xd3, 0x9c, 0x19, 0x51, 0x37, 0x74, 0x56, 0x1a, 0xe1, 0x0a, 0xe5, 0x35,
- 0x45, 0x05, 0xaa, 0xa5, 0xe1, 0xd6, 0xf1, 0x7a, 0xac, 0x1d, 0x6b, 0xc0,
- 0x9a, 0xb1, 0x04, 0x6e, 0x2b, 0x42, 0x0f, 0x39, 0x1a, 0x66, 0x43, 0x33,
- 0x22, 0x34, 0x85, 0x5c, 0xd8, 0x39, 0x75, 0xc3, 0xde, 0xfc, 0x59, 0xe9,
- 0xfa, 0x7f, 0x63, 0x52, 0xbe, 0x61, 0xdc, 0x7f, 0x0f, 0x45, 0x75, 0x0e,
- 0xd3, 0x33, 0xef, 0x3b, 0x75, 0xc3, 0xbe, 0xe2, 0x71, 0xf9, 0xfc, 0x82,
- 0x38, 0x0e, 0x95, 0x74, 0x3c, 0x55, 0xda, 0x4f, 0x3c, 0x98, 0x9e, 0x07,
- 0xcd, 0x53, 0x1d, 0x0f, 0x5b, 0xb3, 0x61, 0x4c, 0x8c, 0x9c, 0x95, 0x21,
- 0xcb, 0x34, 0xa0, 0x58, 0xfa, 0x0b, 0xa0, 0x7d, 0x05, 0xda, 0x57, 0x08,
- 0x63, 0xef, 0x58, 0x29, 0x86, 0xfa, 0x04, 0x9e, 0x5f, 0xc0, 0xe7, 0xf9,
- 0x2c, 0xe3, 0x78, 0x3b, 0x5a, 0x3d, 0x5f, 0x43, 0xe7, 0x8f, 0x64, 0x81,
- 0xf1, 0x91, 0x3e, 0x3a, 0x2a, 0x31, 0x68, 0xd7, 0x62, 0xb5, 0x0e, 0xaf,
- 0xce, 0x61, 0x5c, 0x55, 0x3c, 0x9e, 0x30, 0xa6, 0x8e, 0x34, 0x55, 0xf0,
- 0x40, 0x68, 0x16, 0xbc, 0xda, 0x2f, 0xbd, 0x3f, 0x5e, 0xac, 0xbe, 0xdf,
- 0x41, 0x74, 0x34, 0xd2, 0xc3, 0x06, 0xfc, 0x73, 0xa9, 0x1f, 0xff, 0x50,
- 0xca, 0xe1, 0xd9, 0x52, 0x1f, 0xd1, 0xbd, 0x87, 0xe8, 0xae, 0xc7, 0x3f,
- 0x96, 0xd6, 0xe0, 0xc7, 0xa5, 0xef, 0xe2, 0x99, 0xd2, 0x2a, 0x3c, 0x5d,
- 0xba, 0x09, 0x07, 0x4b, 0x1e, 0xc2, 0xdd, 0x8c, 0x2f, 0x25, 0x3e, 0xcb,
- 0xd7, 0x11, 0x1f, 0x5b, 0x30, 0x5b, 0x64, 0x79, 0x24, 0x46, 0x6c, 0x73,
- 0x0c, 0x58, 0x90, 0xa8, 0x81, 0xc0, 0x6a, 0xdb, 0x7c, 0x0a, 0xb8, 0x0d,
- 0x6e, 0xdc, 0x3c, 0xc1, 0x5a, 0x7a, 0x62, 0xc4, 0x40, 0x98, 0xf8, 0xb5,
- 0xd2, 0x6d, 0xd8, 0xaa, 0xf7, 0xa1, 0xde, 0x1a, 0xc2, 0x03, 0xbe, 0x8d,
- 0xa1, 0x45, 0x9c, 0x7f, 0x45, 0x7e, 0x48, 0xe0, 0xc1, 0x24, 0x34, 0x41,
- 0xcf, 0x5d, 0xc5, 0xbf, 0x6b, 0xa9, 0xd8, 0x8c, 0x78, 0x28, 0x10, 0x5f,
- 0x05, 0xe2, 0xa3, 0x40, 0xbc, 0x15, 0x88, 0x97, 0x02, 0xf1, 0x57, 0x20,
- 0x7e, 0x0a, 0xc4, 0x4f, 0x81, 0xf8, 0x29, 0x10, 0xaf, 0x05, 0xd6, 0xf9,
- 0x00, 0xc9, 0x52, 0xb1, 0x71, 0xab, 0x63, 0x63, 0xac, 0xd4, 0x26, 0xf6,
- 0xee, 0x56, 0xc5, 0x73, 0xc3, 0x06, 0xe6, 0x3b, 0x88, 0x3c, 0xbd, 0xc4,
- 0x2a, 0x5f, 0x15, 0xea, 0x9a, 0x49, 0xc0, 0x4d, 0xcf, 0x83, 0x8d, 0x89,
- 0x92, 0x2a, 0xa6, 0x87, 0xa5, 0x5c, 0x69, 0xbb, 0x68, 0x72, 0xcc, 0x9e,
- 0x8d, 0x8a, 0xd5, 0xff, 0xba, 0x68, 0xc4, 0x2f, 0x47, 0x7a, 0x31, 0xd6,
- 0xec, 0xe2, 0x70, 0xd6, 0xc0, 0xb2, 0x8c, 0x82, 0x5c, 0xdc, 0xc3, 0xb6,
- 0xac, 0x69, 0x7b, 0x18, 0x45, 0x39, 0xce, 0xe7, 0x34, 0xd2, 0xb5, 0x87,
- 0x64, 0xb7, 0x86, 0xc9, 0x11, 0x17, 0x35, 0xe9, 0x1a, 0x94, 0xfb, 0x58,
- 0x7f, 0x2a, 0xc9, 0xb4, 0x0f, 0xf5, 0xb1, 0x18, 0x1a, 0xac, 0x4b, 0xd0,
- 0x10, 0xe3, 0x35, 0x88, 0x56, 0xd2, 0xd5, 0x3c, 0xe7, 0x02, 0xf1, 0xf9,
- 0xee, 0x28, 0x3e, 0x1d, 0xd5, 0x50, 0xda, 0xa9, 0xe2, 0x1b, 0x19, 0x29,
- 0xff, 0x2a, 0xa3, 0xf6, 0x7f, 0x2a, 0x1c, 0x4c, 0x95, 0x54, 0x7c, 0x9e,
- 0x4f, 0xc3, 0x6b, 0xd6, 0xf0, 0x9f, 0x79, 0x0f, 0x21, 0xc2, 0x3b, 0x40,
- 0x78, 0x6b, 0x17, 0xa7, 0x30, 0x1b, 0x67, 0x71, 0xfa, 0xb0, 0x31, 0xdf,
- 0xb1, 0x63, 0xa3, 0x52, 0x03, 0xa3, 0x06, 0x64, 0xff, 0x2c, 0x36, 0xe5,
- 0x3b, 0x8e, 0x6e, 0x52, 0xb6, 0xe0, 0xe2, 0x5a, 0x0d, 0x9b, 0x87, 0x79,
- 0x6d, 0x39, 0xca, 0x45, 0x41, 0xfe, 0xf0, 0xc7, 0xea, 0x6b, 0x26, 0x42,
- 0x7e, 0x65, 0xfc, 0xf1, 0x7a, 0x4e, 0x34, 0xa2, 0xde, 0x34, 0xca, 0x58,
- 0x1f, 0xe7, 0xf3, 0x39, 0xe5, 0x5d, 0xe9, 0xc6, 0x99, 0x0f, 0xcd, 0x0b,
- 0x91, 0x6e, 0x6e, 0xc9, 0x66, 0xb1, 0x26, 0xdf, 0xa1, 0xaf, 0x51, 0x48,
- 0xdb, 0x6a, 0xc5, 0xc6, 0x71, 0x07, 0xe9, 0xd1, 0x61, 0x81, 0x91, 0x4e,
- 0xb6, 0x31, 0xd2, 0x76, 0xd1, 0x8f, 0x09, 0xc3, 0x50, 0x2a, 0x31, 0xf1,
- 0x58, 0x36, 0x89, 0xb3, 0x0f, 0xf1, 0x6f, 0x15, 0x3f, 0x5b, 0x9a, 0xc4,
- 0xc7, 0xfb, 0x4a, 0x73, 0x71, 0xfb, 0x68, 0xa4, 0xb2, 0xef, 0x1a, 0xa2,
- 0xc9, 0x32, 0x32, 0xae, 0xc9, 0x7b, 0x47, 0x3b, 0x6b, 0xe9, 0x77, 0xc5,
- 0xd6, 0xfd, 0xf9, 0x0e, 0xbb, 0x5f, 0xd1, 0x50, 0x4e, 0x44, 0x48, 0xf7,
- 0xd0, 0xea, 0x08, 0xff, 0x25, 0x43, 0x67, 0xb0, 0x22, 0x63, 0x4e, 0xf2,
- 0xdf, 0x80, 0x25, 0x93, 0x15, 0x9a, 0xc9, 0xa2, 0x8d, 0x03, 0x25, 0x1b,
- 0x77, 0xe4, 0x3b, 0xdc, 0x95, 0x62, 0x16, 0x68, 0x5f, 0x98, 0x9b, 0x54,
- 0x7e, 0x21, 0xbd, 0x56, 0xa6, 0xb3, 0x10, 0x93, 0xb1, 0x8e, 0x81, 0x49,
- 0xc5, 0xdc, 0xd3, 0xaf, 0x48, 0xf9, 0xab, 0xb4, 0x82, 0xaf, 0x65, 0xb2,
- 0x98, 0xd5, 0x75, 0xdc, 0x9c, 0xd1, 0xbc, 0x16, 0xe2, 0x71, 0xc3, 0x12,
- 0x0d, 0x17, 0xed, 0x74, 0xf1, 0xf6, 0xe2, 0x9f, 0xa3, 0xbc, 0x82, 0x75,
- 0xcf, 0x7c, 0xb1, 0x1c, 0x09, 0xc4, 0xac, 0x3a, 0xc4, 0xf6, 0x86, 0x31,
- 0x6f, 0xe7, 0x59, 0x99, 0xb0, 0x78, 0xdd, 0x9a, 0x3c, 0xa5, 0xb0, 0x0c,
- 0x61, 0xb4, 0xee, 0xbd, 0x82, 0x72, 0x8a, 0x99, 0x02, 0xbe, 0x16, 0xe7,
- 0xbd, 0x35, 0x56, 0x55, 0x96, 0x08, 0x76, 0xef, 0xac, 0xc8, 0xff, 0x68,
- 0xb6, 0x07, 0x2f, 0x15, 0xb0, 0xaf, 0x0d, 0x3f, 0xc0, 0xc8, 0x12, 0xce,
- 0x4f, 0x8c, 0x63, 0x88, 0x64, 0xff, 0xc1, 0x89, 0x70, 0xa6, 0x6a, 0xe3,
- 0xea, 0x39, 0x81, 0x6f, 0x5e, 0x29, 0xf0, 0x6a, 0x7a, 0x5a, 0x8e, 0xb5,
- 0x32, 0xbf, 0x0f, 0x37, 0x56, 0xfe, 0x16, 0xae, 0xee, 0x94, 0x8b, 0x36,
- 0xa2, 0x55, 0xdd, 0xc7, 0x38, 0x2e, 0x69, 0x25, 0xfd, 0xa5, 0x66, 0xf1,
- 0x5f, 0x11, 0xd4, 0xb3, 0x9d, 0xef, 0x96, 0x46, 0x4b, 0x85, 0xe6, 0xfd,
- 0x44, 0xb3, 0x63, 0x48, 0xc5, 0xe6, 0x7c, 0xc7, 0xa9, 0xf7, 0x94, 0xef,
- 0xcb, 0xd9, 0xf9, 0x4c, 0xa7, 0xc3, 0x3e, 0xa6, 0x08, 0xfc, 0x54, 0x35,
- 0x67, 0x72, 0x48, 0x60, 0xb2, 0x04, 0xaf, 0xdd, 0xd1, 0x29, 0xfe, 0xe3,
- 0x94, 0x07, 0x0c, 0xd1, 0xf9, 0xb0, 0x8d, 0x85, 0x43, 0xdf, 0x85, 0xb5,
- 0xcb, 0xc1, 0x4c, 0xc1, 0xc6, 0x54, 0x41, 0xca, 0xed, 0xb6, 0x94, 0xef,
- 0xda, 0xe6, 0x86, 0xe3, 0x21, 0xb8, 0x97, 0x2f, 0xed, 0x4a, 0xd5, 0x86,
- 0x54, 0xd6, 0x4d, 0xee, 0x75, 0x91, 0x5c, 0xb5, 0x5f, 0xf4, 0xe2, 0x89,
- 0x92, 0x81, 0x62, 0x29, 0x85, 0x27, 0x4b, 0xac, 0x7f, 0x8b, 0xbe, 0x17,
- 0x51, 0x7c, 0x66, 0x29, 0xb7, 0x30, 0xbf, 0x3a, 0xc6, 0x17, 0xd8, 0x98,
- 0x2c, 0x28, 0x08, 0x91, 0xce, 0x73, 0x3a, 0xed, 0x2f, 0x9c, 0x25, 0xdb,
- 0x69, 0xe8, 0xf8, 0xa1, 0x8b, 0xdb, 0xed, 0x16, 0x18, 0x37, 0x5a, 0x18,
- 0x2f, 0x68, 0x94, 0xbb, 0x55, 0xf4, 0xe6, 0xc7, 0x31, 0xaf, 0x39, 0x4e,
- 0xb1, 0x26, 0xb0, 0x2a, 0x13, 0x01, 0x56, 0xf2, 0xbb, 0x08, 0xda, 0xad,
- 0x32, 0xda, 0x63, 0x8d, 0x98, 0xbf, 0xf0, 0x9f, 0x30, 0xdb, 0x12, 0x25,
- 0x1d, 0xd7, 0x93, 0x1e, 0x04, 0x54, 0xb2, 0x53, 0x9b, 0x65, 0x11, 0x4e,
- 0x01, 0x2b, 0x49, 0x7b, 0x29, 0x7e, 0x13, 0x24, 0x7b, 0x78, 0x69, 0x1c,
- 0x8f, 0x13, 0xff, 0xa5, 0xbc, 0x94, 0x91, 0xac, 0xb9, 0x61, 0x3b, 0xe5,
- 0x84, 0xe9, 0x62, 0x0f, 0x4a, 0xa5, 0x6f, 0x62, 0x6a, 0x84, 0xf8, 0xcc,
- 0x3b, 0xc4, 0x93, 0xaa, 0x17, 0x85, 0xd9, 0xb7, 0x5a, 0x64, 0xf1, 0x24,
- 0xf9, 0xce, 0x44, 0xc1, 0x34, 0x8e, 0x93, 0x9f, 0xbd, 0x60, 0x37, 0x10,
- 0x9f, 0x2e, 0xe1, 0x32, 0xf0, 0x5c, 0xbe, 0x00, 0xab, 0x85, 0xed, 0x15,
- 0xc1, 0xfd, 0x3b, 0xb3, 0x84, 0x13, 0x83, 0x75, 0xf0, 0xa0, 0x2e, 0xf1,
- 0x4e, 0x6c, 0xb5, 0x87, 0x22, 0x55, 0x1f, 0xaf, 0x27, 0x9a, 0x7d, 0xdd,
- 0x36, 0x42, 0xc3, 0x3d, 0x84, 0x97, 0xfc, 0x15, 0xb7, 0x92, 0xbf, 0x7a,
- 0xb8, 0x9c, 0xe2, 0x21, 0xea, 0xec, 0x49, 0xbf, 0x36, 0xe4, 0xc9, 0x5a,
- 0xcb, 0xea, 0xff, 0x48, 0x6c, 0xc2, 0x27, 0x69, 0xb6, 0x83, 0x4a, 0xf2,
- 0xea, 0x78, 0x39, 0x3d, 0x82, 0x57, 0x8b, 0x7f, 0x82, 0x5c, 0xb3, 0x99,
- 0xda, 0x2c, 0xd6, 0x61, 0x66, 0xe4, 0x0a, 0xe0, 0xcf, 0xd9, 0x7e, 0x02,
- 0xf3, 0xad, 0x75, 0x38, 0x34, 0x76, 0x2f, 0x8e, 0x8c, 0xd6, 0xe3, 0x39,
- 0x2b, 0x86, 0xf6, 0x89, 0x0a, 0x9d, 0x6b, 0xe6, 0x72, 0x93, 0x9e, 0xa6,
- 0xe0, 0x6b, 0xe3, 0x98, 0x14, 0xb8, 0x3e, 0xb3, 0x0e, 0x39, 0xdf, 0xcf,
- 0x3d, 0xac, 0xa1, 0xdc, 0x96, 0xcf, 0xbb, 0x14, 0xd7, 0x75, 0xd8, 0xd9,
- 0x0c, 0x71, 0x0b, 0xd5, 0x93, 0x3b, 0x29, 0x5e, 0xef, 0x54, 0x62, 0x70,
- 0x13, 0x2e, 0xd9, 0x55, 0xe0, 0x22, 0xcb, 0xc0, 0x9e, 0x22, 0x70, 0x77,
- 0x51, 0xc5, 0xdf, 0x14, 0x2f, 0x45, 0xb9, 0x8d, 0xcf, 0x2e, 0x40, 0x79,
- 0x1e, 0x7f, 0x87, 0x31, 0x16, 0x33, 0x13, 0x20, 0x9d, 0xed, 0x2f, 0xa8,
- 0xf8, 0xb1, 0xbd, 0xeb, 0xec, 0xd8, 0x0a, 0x53, 0xcf, 0x51, 0xac, 0x85,
- 0xac, 0xd3, 0xe4, 0x67, 0xfc, 0x0c, 0x7c, 0x3f, 0xff, 0x99, 0xfc, 0xb9,
- 0x4f, 0x53, 0xc5, 0x6d, 0xf9, 0x8e, 0x81, 0x8f, 0x94, 0x8f, 0xe5, 0xbf,
- 0x85, 0x19, 0xff, 0x77, 0xa2, 0x15, 0x7f, 0xdd, 0xc3, 0x79, 0xc4, 0xad,
- 0xf8, 0xed, 0xbc, 0x2f, 0xf8, 0x6d, 0xc5, 0x3f, 0x47, 0xb2, 0xcc, 0x47,
- 0x35, 0xc6, 0x62, 0xb8, 0x68, 0x22, 0x89, 0xba, 0x9d, 0xfc, 0x9b, 0xd7,
- 0x05, 0x2e, 0xee, 0xe6, 0xf8, 0x4a, 0x42, 0xd9, 0x7b, 0x2d, 0xe1, 0x63,
- 0xd9, 0xab, 0xb9, 0xe2, 0x7b, 0x73, 0xf8, 0xcf, 0xe7, 0x98, 0x76, 0xc2,
- 0xb7, 0x74, 0x29, 0x3f, 0xf3, 0x99, 0x3a, 0xfc, 0x7a, 0xaf, 0x69, 0x97,
- 0x95, 0xa5, 0x44, 0x93, 0x63, 0x92, 0x63, 0xf3, 0x2f, 0xe6, 0xce, 0x24,
- 0xc8, 0xce, 0xd3, 0xb2, 0xbc, 0x8a, 0xf1, 0x55, 0xcf, 0x27, 0x11, 0x3a,
- 0x47, 0x57, 0xc5, 0xea, 0xec, 0x97, 0xe9, 0xda, 0x94, 0xf7, 0x5b, 0xd1,
- 0xb0, 0xd0, 0x22, 0x3b, 0xb5, 0xa1, 0x91, 0xe2, 0x3a, 0x62, 0xad, 0x92,
- 0x91, 0x6f, 0xb3, 0x8f, 0x6a, 0x5e, 0xd8, 0xf9, 0x0a, 0x4a, 0x23, 0xcf,
- 0x93, 0x7d, 0xa3, 0xec, 0x8b, 0x1b, 0x3e, 0x12, 0x5f, 0xc1, 0xf4, 0x98,
- 0x88, 0xb2, 0xac, 0xab, 0x28, 0xb6, 0xe7, 0x53, 0x7d, 0xf8, 0xe0, 0xe1,
- 0xbb, 0xe4, 0x58, 0x9f, 0x8e, 0x17, 0xb3, 0x49, 0x5a, 0x67, 0x5f, 0xb2,
- 0xf1, 0x4c, 0x5e, 0xc3, 0xee, 0xe1, 0x84, 0xef, 0xc7, 0xf7, 0x74, 0xd6,
- 0x9d, 0x2a, 0x2b, 0x36, 0x9e, 0x25, 0x3f, 0x3c, 0x58, 0x60, 0x1d, 0xab,
- 0xb8, 0x38, 0xf3, 0x75, 0x59, 0xd3, 0xc6, 0xbe, 0x1d, 0xa1, 0x33, 0x3a,
- 0xe1, 0x8e, 0x42, 0xb7, 0x96, 0xcb, 0x37, 0x56, 0xf0, 0x73, 0x03, 0xad,
- 0xb5, 0xd1, 0xf7, 0x12, 0xd9, 0xf8, 0x3b, 0x7c, 0xe8, 0xff, 0x1b, 0x1f,
- 0xf4, 0x1d, 0xa3, 0x75, 0x90, 0xbf, 0xcc, 0x88, 0xd5, 0x95, 0xfe, 0x46,
- 0x53, 0xad, 0x19, 0xb1, 0xc6, 0xef, 0x69, 0xfc, 0x34, 0x4e, 0x38, 0x7a,
- 0xb1, 0x77, 0x54, 0xca, 0x2d, 0x76, 0x3b, 0x5c, 0x3d, 0x86, 0x2d, 0x16,
- 0xc5, 0xeb, 0x28, 0x9f, 0x91, 0x32, 0x95, 0x5e, 0xd8, 0xa3, 0x8a, 0x16,
- 0xca, 0x99, 0x9e, 0x58, 0x9b, 0x35, 0xc4, 0x9d, 0xa3, 0x2a, 0xf2, 0x85,
- 0x0b, 0x28, 0x27, 0x4b, 0xf9, 0x64, 0x1a, 0xee, 0x60, 0xba, 0x01, 0x2f,
- 0x8f, 0xe9, 0x14, 0x3b, 0x67, 0xe5, 0xf2, 0x64, 0x2f, 0x4a, 0x84, 0xe7,
- 0xd3, 0x74, 0x57, 0xea, 0xb0, 0x88, 0x60, 0x2c, 0x1e, 0xc1, 0x9e, 0x42,
- 0x1c, 0x87, 0xc7, 0x23, 0xd8, 0x46, 0xfe, 0xf7, 0xd3, 0x2c, 0xd3, 0x8c,
- 0x60, 0x73, 0x89, 0x7b, 0x8d, 0x10, 0xe9, 0xc0, 0x13, 0xef, 0xf9, 0x6b,
- 0x0d, 0x58, 0x3e, 0xc6, 0x7b, 0xcf, 0xca, 0x76, 0xcb, 0xd2, 0xdb, 0x43,
- 0xd5, 0x7d, 0xef, 0x50, 0x1f, 0x63, 0x50, 0xef, 0x72, 0x21, 0xe5, 0xaa,
- 0x04, 0xf5, 0x2a, 0x71, 0xea, 0x55, 0xac, 0xb9, 0xfe, 0xcb, 0xa4, 0x48,
- 0x93, 0xf2, 0x19, 0xca, 0x53, 0x6f, 0xd2, 0xe7, 0xa4, 0x4d, 0xe5, 0x96,
- 0x64, 0xbc, 0x78, 0x98, 0x65, 0xf4, 0x84, 0xbd, 0x84, 0x3a, 0xce, 0x69,
- 0xd3, 0x70, 0x95, 0x5f, 0x50, 0x9f, 0x65, 0xa0, 0x63, 0x9a, 0x79, 0x50,
- 0xb1, 0xb5, 0x00, 0x0c, 0x16, 0xe0, 0x1d, 0xa6, 0xd8, 0x6e, 0x99, 0x88,
- 0x22, 0x36, 0xa1, 0x23, 0x3c, 0x91, 0xa2, 0xbd, 0x1a, 0xe2, 0xf4, 0xdb,
- 0xa3, 0xbe, 0xab, 0xc9, 0x69, 0x13, 0x8b, 0x76, 0x9f, 0x91, 0x0f, 0x52,
- 0xac, 0xdd, 0x91, 0x34, 0x7b, 0x6f, 0x14, 0x70, 0x53, 0x43, 0x52, 0xd6,
- 0xa6, 0x6b, 0xa9, 0x7e, 0xcb, 0x43, 0x71, 0x92, 0x3d, 0xea, 0xc8, 0x4d,
- 0xaf, 0x76, 0x5b, 0xf6, 0xab, 0x20, 0xbc, 0x25, 0x3e, 0xc3, 0xeb, 0x9e,
- 0xf8, 0xac, 0xdb, 0xda, 0xf3, 0x16, 0x3a, 0xb1, 0x78, 0x42, 0x15, 0xbf,
- 0x1c, 0x5a, 0x84, 0xcc, 0x34, 0xf4, 0x1a, 0xe2, 0xeb, 0xc3, 0x29, 0xe2,
- 0xbb, 0x40, 0xb2, 0x14, 0x48, 0x96, 0x02, 0xc9, 0x42, 0x7a, 0x39, 0xe8,
- 0xf7, 0x6d, 0x2c, 0x6b, 0x8a, 0xea, 0xef, 0x3b, 0x7e, 0x6f, 0x79, 0xb0,
- 0xc4, 0x72, 0x98, 0xae, 0x07, 0x96, 0x9b, 0xe5, 0x94, 0xf2, 0x2d, 0x9b,
- 0xe5, 0x31, 0x0d, 0x4f, 0x21, 0x6b, 0x4d, 0x1b, 0x48, 0x4d, 0x57, 0xf5,
- 0x21, 0xe5, 0xe7, 0x36, 0xeb, 0x83, 0x65, 0x94, 0xf2, 0x69, 0x92, 0x69,
- 0x2b, 0xc9, 0x38, 0x58, 0x90, 0x87, 0x6a, 0x2c, 0xcb, 0x98, 0x20, 0xde,
- 0x62, 0x24, 0x53, 0x7c, 0x42, 0x23, 0x59, 0x3b, 0xa1, 0x92, 0xac, 0xa1,
- 0x09, 0xe8, 0x0a, 0xeb, 0x69, 0xfa, 0xff, 0xe2, 0x87, 0xfb, 0x6a, 0x4f,
- 0x5c, 0x43, 0xfd, 0xb4, 0x4a, 0xfb, 0x07, 0xc9, 0x77, 0x72, 0x2a, 0x8c,
- 0x5a, 0x4b, 0xa1, 0x3c, 0xac, 0xe1, 0xf1, 0xf1, 0x06, 0x4c, 0x90, 0xdd,
- 0xc7, 0xc6, 0xa1, 0x87, 0xe9, 0xfd, 0xd6, 0x73, 0xfe, 0x04, 0xf2, 0xa7,
- 0x0d, 0x18, 0xa7, 0xfc, 0xf3, 0x40, 0x3e, 0x26, 0x26, 0x46, 0x54, 0x6c,
- 0x29, 0x9c, 0x20, 0xd9, 0x24, 0xe5, 0xd8, 0xcd, 0x09, 0xda, 0x22, 0x36,
- 0xdb, 0x66, 0x0f, 0x70, 0x05, 0xf9, 0x5a, 0x08, 0x6b, 0x2d, 0xb8, 0xdb,
- 0xed, 0x2b, 0x30, 0xdb, 0x07, 0x63, 0x87, 0xed, 0xe9, 0x35, 0x30, 0x8f,
- 0x5e, 0x43, 0xa3, 0xc0, 0xe5, 0x24, 0xc7, 0x80, 0xe5, 0x6d, 0xa0, 0x84,
- 0x44, 0xf9, 0xdb, 0xec, 0x3f, 0x42, 0x36, 0x28, 0x52, 0x5d, 0x2b, 0x52,
- 0x0f, 0x78, 0x60, 0xf4, 0x8c, 0xbc, 0x3d, 0x6d, 0xba, 0x49, 0x5a, 0x0b,
- 0x0f, 0x69, 0xd8, 0x5f, 0xd2, 0x28, 0x5e, 0x4c, 0x1b, 0xe0, 0x98, 0x87,
- 0x56, 0x4b, 0x3d, 0xda, 0x47, 0xd6, 0xa3, 0xd4, 0x0b, 0x6b, 0xa0, 0x3e,
- 0x19, 0x57, 0x8f, 0x08, 0xec, 0xa7, 0xf8, 0x9d, 0x5a, 0x64, 0x1e, 0x5d,
- 0x0d, 0xaf, 0xdc, 0x0e, 0x73, 0xa0, 0x96, 0x18, 0xf9, 0x74, 0xa8, 0x86,
- 0xfa, 0xc2, 0x4e, 0xfb, 0x35, 0x98, 0xfa, 0xfe, 0xd0, 0xaf, 0xe4, 0x64,
- 0x1c, 0x17, 0x84, 0x71, 0x52, 0x1a, 0xdf, 0xe2, 0x33, 0x2c, 0xf7, 0x06,
- 0x6c, 0xcf, 0x42, 0x0b, 0x3b, 0x6a, 0x7a, 0x7f, 0x1e, 0x38, 0x96, 0x37,
- 0x30, 0xb9, 0xa8, 0x0e, 0x68, 0xee, 0xe8, 0xb9, 0x03, 0xde, 0xaa, 0xb0,
- 0xdf, 0xe7, 0x6a, 0xe9, 0x3c, 0xf9, 0xc8, 0x7a, 0x21, 0xf0, 0x24, 0xd1,
- 0x5a, 0x30, 0xc5, 0x7d, 0x89, 0x9a, 0x5e, 0x48, 0x79, 0x76, 0x5b, 0x49,
- 0xa0, 0xd6, 0x32, 0xf5, 0x59, 0xb0, 0x6e, 0x74, 0xd2, 0xe9, 0x19, 0x89,
- 0x66, 0x96, 0xdd, 0xcb, 0x91, 0x9c, 0xab, 0xb6, 0x12, 0xff, 0x6b, 0x48,
- 0xa6, 0xdb, 0x2d, 0xaf, 0x87, 0xb0, 0x52, 0xed, 0x31, 0x13, 0x1f, 0x90,
- 0xec, 0x6b, 0x29, 0x47, 0x8c, 0x95, 0x86, 0x9b, 0x38, 0x1f, 0x4c, 0x94,
- 0x78, 0x4e, 0xea, 0xc1, 0xd5, 0xf9, 0x6a, 0x2c, 0xb0, 0xdd, 0xd9, 0xe6,
- 0x17, 0xfa, 0xf5, 0xfb, 0xa0, 0xef, 0x23, 0xdc, 0x3f, 0xf5, 0x60, 0xb4,
- 0x53, 0xa1, 0xde, 0x5c, 0xca, 0x15, 0x96, 0x39, 0xc2, 0xf9, 0x99, 0x7c,
- 0xdd, 0xdd, 0x67, 0x37, 0x51, 0x6c, 0xc2, 0x7b, 0xc2, 0x36, 0x50, 0xe3,
- 0xb0, 0x4f, 0x34, 0x90, 0x8f, 0x47, 0xb0, 0x9d, 0x7c, 0x44, 0xb3, 0xac,
- 0x14, 0x35, 0x53, 0xfa, 0xb1, 0x2c, 0xed, 0x2d, 0xc1, 0x28, 0xd9, 0xf5,
- 0x98, 0x6d, 0x55, 0xd1, 0xec, 0x1c, 0x92, 0x2d, 0xd6, 0x7f, 0x10, 0x7d,
- 0x4b, 0xbf, 0x1b, 0xab, 0x61, 0xb4, 0x1a, 0x68, 0x70, 0xf8, 0xfd, 0x69,
- 0x39, 0xdb, 0x1c, 0x21, 0xff, 0xe2, 0x3d, 0x96, 0x77, 0x10, 0xbf, 0x96,
- 0x88, 0xf1, 0x5e, 0x97, 0xf2, 0x27, 0xc4, 0x0c, 0xd1, 0x42, 0x0b, 0xc7,
- 0x2d, 0xf7, 0xe7, 0xd6, 0xd1, 0x43, 0x54, 0x53, 0x8c, 0x16, 0x50, 0x2e,
- 0x55, 0x11, 0x72, 0x2c, 0x7d, 0x1f, 0x8e, 0x92, 0xcd, 0xd9, 0x45, 0x2e,
- 0x12, 0xd7, 0xed, 0xba, 0x50, 0xf4, 0xee, 0x92, 0xb2, 0x33, 0x0d, 0x9a,
- 0xc2, 0x92, 0xc6, 0x4b, 0xb4, 0xba, 0x85, 0x7c, 0xbf, 0xd1, 0x89, 0x88,
- 0xe2, 0x2e, 0xe8, 0x07, 0x6c, 0x8d, 0xf2, 0xae, 0x94, 0xdb, 0xd2, 0x06,
- 0xa6, 0x6d, 0xea, 0xc7, 0x5b, 0xc3, 0x68, 0xb6, 0xa0, 0xeb, 0x8e, 0x35,
- 0xf0, 0x14, 0xee, 0x26, 0x3e, 0x11, 0x99, 0x4f, 0x35, 0x90, 0xd6, 0xc4,
- 0x5e, 0xbb, 0x0e, 0xee, 0x4d, 0x02, 0x11, 0x27, 0x4e, 0xbc, 0xd5, 0x20,
- 0xe7, 0x3f, 0xb3, 0x8c, 0x70, 0xdf, 0xb7, 0x7f, 0x44, 0xf2, 0x8a, 0xf9,
- 0xf5, 0x0e, 0xaf, 0x59, 0x76, 0x11, 0xeb, 0xa9, 0xe7, 0xa7, 0x25, 0x7a,
- 0xbf, 0x85, 0xde, 0x3f, 0x44, 0xb8, 0x73, 0x31, 0x7f, 0xd6, 0x6b, 0x6a,
- 0x77, 0xac, 0xf2, 0x73, 0x78, 0x90, 0x64, 0xe0, 0xfc, 0xcd, 0x6b, 0xcc,
- 0xf3, 0x22, 0xe6, 0x99, 0x6a, 0x37, 0xfb, 0x95, 0x8d, 0x8f, 0xf2, 0x77,
- 0x73, 0x0f, 0xef, 0xee, 0xb0, 0x21, 0x26, 0xec, 0x3d, 0x28, 0xeb, 0x68,
- 0x8a, 0x3a, 0x56, 0xff, 0x34, 0xa0, 0x44, 0x9c, 0x51, 0x14, 0x9b, 0x81,
- 0x87, 0x0a, 0x96, 0xb7, 0x51, 0x31, 0x07, 0xe2, 0xd4, 0xf7, 0x9e, 0xfc,
- 0xa1, 0x8a, 0x9d, 0x9d, 0x65, 0x33, 0x46, 0x46, 0x8f, 0x3a, 0x51, 0xf1,
- 0xe2, 0x2e, 0x05, 0x0b, 0x96, 0xa8, 0x78, 0x8b, 0x72, 0xc8, 0x36, 0x9a,
- 0x45, 0xc2, 0x96, 0xda, 0x54, 0xe9, 0x89, 0x7f, 0x5f, 0x3c, 0x9a, 0xa4,
- 0xb1, 0x6a, 0x4c, 0x5a, 0x7d, 0x07, 0xf0, 0xa8, 0x74, 0x9b, 0xd9, 0x16,
- 0x11, 0xca, 0xc3, 0xe7, 0xf2, 0x50, 0x6a, 0x8a, 0xf0, 0x0f, 0x76, 0xbf,
- 0xeb, 0xfb, 0x0c, 0xd9, 0xd2, 0x7d, 0x23, 0x0f, 0xd1, 0x94, 0x71, 0x30,
- 0xdb, 0xcc, 0x76, 0xe1, 0xf9, 0x99, 0x94, 0x37, 0x4c, 0xc3, 0x47, 0x8b,
- 0x8a, 0xc5, 0x19, 0x34, 0x29, 0x8e, 0x75, 0x6a, 0x2f, 0xf1, 0xdc, 0xee,
- 0x34, 0xe1, 0x74, 0x0b, 0xe7, 0xc4, 0xa8, 0xf8, 0xd9, 0xa8, 0xd9, 0x43,
- 0x3d, 0xee, 0xaa, 0x8d, 0x30, 0xfb, 0xee, 0x11, 0xd4, 0x97, 0x11, 0xef,
- 0x56, 0x92, 0xf8, 0xb4, 0x55, 0xc4, 0x93, 0x65, 0x33, 0x8e, 0x2a, 0xbf,
- 0x67, 0x65, 0xcc, 0xb2, 0xbc, 0x98, 0xf2, 0x1b, 0x99, 0xce, 0xb0, 0x8f,
- 0xdf, 0x85, 0xda, 0x98, 0x40, 0x4d, 0x66, 0xc4, 0xd7, 0x6d, 0x94, 0xec,
- 0xdd, 0x94, 0x51, 0x89, 0xb6, 0x4a, 0x39, 0x9d, 0x68, 0x2f, 0x1e, 0xa0,
- 0x9e, 0x85, 0x75, 0xfa, 0x92, 0xcc, 0x7d, 0x9b, 0xe5, 0xbc, 0x65, 0x4e,
- 0x66, 0xd2, 0x6c, 0x3d, 0xff, 0x96, 0x0d, 0xac, 0xfb, 0x43, 0x94, 0xcf,
- 0x17, 0x2f, 0xed, 0xda, 0x31, 0xa0, 0x3c, 0x20, 0x8d, 0x15, 0x6c, 0xdb,
- 0x46, 0x7a, 0xef, 0xdb, 0x9d, 0xfa, 0xa9, 0x77, 0xf0, 0xda, 0x50, 0x54,
- 0x34, 0xed, 0xf6, 0xfc, 0xda, 0xf9, 0x2a, 0xf1, 0xf5, 0x61, 0x9a, 0xf9,
- 0xe1, 0x78, 0x7b, 0x07, 0x97, 0x16, 0xff, 0x94, 0xf6, 0x86, 0x88, 0x17,
- 0x68, 0x31, 0x92, 0x75, 0x05, 0xcd, 0x25, 0x57, 0x67, 0x0e, 0x48, 0x57,
- 0x67, 0xfc, 0xa4, 0xf7, 0x51, 0xd6, 0x3b, 0xcf, 0x45, 0x55, 0xdd, 0xf3,
- 0x7e, 0x3e, 0x3f, 0x4c, 0x31, 0xc9, 0xb6, 0x44, 0x53, 0x83, 0xc3, 0xfa,
- 0x85, 0xa8, 0x73, 0xba, 0x8c, 0x85, 0x62, 0x87, 0xf4, 0xe2, 0xd5, 0x7c,
- 0x16, 0x15, 0x13, 0xfe, 0x79, 0xa6, 0xfd, 0xe5, 0xf3, 0x6d, 0xe2, 0xd8,
- 0xc3, 0x54, 0x7c, 0xeb, 0x7d, 0x7f, 0xe9, 0x7d, 0x92, 0xe2, 0x49, 0x73,
- 0x6e, 0x95, 0xa9, 0x56, 0xf6, 0x37, 0x28, 0x2f, 0xdb, 0xb7, 0xc8, 0x5c,
- 0x2b, 0xfb, 0x1d, 0xbc, 0x38, 0xe1, 0xd9, 0xb9, 0xfb, 0x3c, 0x1f, 0xd7,
- 0x74, 0x4a, 0x39, 0x61, 0x5f, 0x45, 0xba, 0x60, 0x3c, 0x55, 0x5d, 0xfc,
- 0xe5, 0x9c, 0x6e, 0xa8, 0x89, 0xae, 0xaf, 0xd4, 0x2b, 0xce, 0x69, 0x35,
- 0xce, 0x1b, 0x78, 0x31, 0xaf, 0xb4, 0x85, 0xd1, 0x84, 0x3e, 0x5b, 0xe0,
- 0xdd, 0x1e, 0x81, 0xd3, 0x97, 0x47, 0x10, 0xba, 0xcc, 0x2a, 0x77, 0x84,
- 0xfa, 0x25, 0xe6, 0x95, 0xc9, 0x51, 0xce, 0x48, 0xad, 0x53, 0x45, 0xed,
- 0xa5, 0x5c, 0xa7, 0xd8, 0x0e, 0x0a, 0xfe, 0x85, 0xf6, 0x5d, 0x77, 0xa9,
- 0x65, 0x74, 0x50, 0x4b, 0xe0, 0xf5, 0x5d, 0x9d, 0x09, 0x9f, 0xf3, 0x43,
- 0xe6, 0xe1, 0x4a, 0x5f, 0x06, 0xf6, 0xc7, 0xc5, 0x64, 0xc7, 0xdc, 0x0a,
- 0x05, 0xe9, 0x25, 0xf0, 0x22, 0xf4, 0x7e, 0xdb, 0x2e, 0xf6, 0x85, 0x47,
- 0x74, 0x9e, 0x09, 0x81, 0xae, 0x84, 0x0e, 0x6b, 0xd5, 0x0b, 0x44, 0x9b,
- 0xfa, 0x4d, 0xd2, 0x07, 0xd3, 0xaa, 0xe2, 0xa9, 0xe2, 0x88, 0x8a, 0xd3,
- 0x0f, 0xf3, 0x19, 0x08, 0xd6, 0x51, 0x7a, 0x01, 0xc5, 0x76, 0x46, 0x9d,
- 0x93, 0x6d, 0x40, 0xaf, 0xf4, 0x61, 0x51, 0x31, 0x35, 0xca, 0xf8, 0x7c,
- 0x3f, 0x42, 0x91, 0x7d, 0x2b, 0xcd, 0x7b, 0x7e, 0x23, 0x17, 0x64, 0xfe,
- 0x9d, 0xf6, 0x30, 0xde, 0xa8, 0x38, 0xe2, 0xd3, 0xae, 0xe8, 0x68, 0x8a,
- 0x74, 0x3d, 0x91, 0xae, 0xe2, 0xd9, 0x48, 0x7b, 0xd8, 0xe7, 0x98, 0x87,
- 0x5e, 0xf1, 0x78, 0x9e, 0xf2, 0x0a, 0xd5, 0xdc, 0x89, 0xac, 0x62, 0xd5,
- 0x42, 0x62, 0xb3, 0xad, 0x63, 0x99, 0x5e, 0xa9, 0x57, 0xf7, 0xe7, 0xab,
- 0xf7, 0x3f, 0xbd, 0xa2, 0x90, 0x57, 0xa8, 0x7f, 0x83, 0x5e, 0xef, 0x28,
- 0xf7, 0x34, 0x51, 0x2c, 0xbd, 0x46, 0xb5, 0xeb, 0xd5, 0xb1, 0x5e, 0x91,
- 0xcf, 0xeb, 0x78, 0x65, 0x7c, 0xb9, 0x78, 0x30, 0x6f, 0xe1, 0xe5, 0x62,
- 0xe5, 0x2e, 0xe8, 0x81, 0xa2, 0x2b, 0xc6, 0xf3, 0xdc, 0xfb, 0x98, 0xa9,
- 0x32, 0x66, 0xc4, 0x5a, 0xc2, 0x53, 0x56, 0x2f, 0xf4, 0xeb, 0xc8, 0x78,
- 0xb1, 0x01, 0x93, 0x63, 0x95, 0x7a, 0x77, 0xeb, 0xb9, 0x7a, 0xf7, 0xc5,
- 0x3b, 0x9d, 0x48, 0x4e, 0x77, 0xd0, 0xd7, 0x38, 0xbc, 0x49, 0x46, 0xad,
- 0x10, 0xd5, 0x49, 0x2b, 0x37, 0x2d, 0x22, 0x3d, 0x3b, 0xba, 0x99, 0x5f,
- 0xf4, 0x69, 0xd4, 0x63, 0x4c, 0x14, 0xd9, 0x5f, 0x0d, 0x18, 0xc5, 0x6f,
- 0xb5, 0x56, 0xec, 0xdc, 0x96, 0xd3, 0x1c, 0xa0, 0x9e, 0xfa, 0x8b, 0x06,
- 0x9a, 0x0d, 0xea, 0x9c, 0x1b, 0xbd, 0x8e, 0x6e, 0xe4, 0x54, 0xc7, 0xea,
- 0xb9, 0x5e, 0xac, 0x5c, 0xa9, 0x38, 0xf7, 0xad, 0x0c, 0x4d, 0x1b, 0xc6,
- 0x16, 0xbf, 0x0e, 0x9d, 0x1c, 0xd8, 0x4f, 0x33, 0x50, 0x0d, 0xcd, 0xa5,
- 0xef, 0xe9, 0xb8, 0x2f, 0xd4, 0x7d, 0x1f, 0x36, 0xe5, 0x07, 0xf0, 0xb7,
- 0x79, 0xce, 0x13, 0x3a, 0x1e, 0x63, 0x1e, 0x0a, 0x7c, 0xff, 0x73, 0xb0,
- 0x85, 0x6b, 0xdf, 0x23, 0x25, 0x8a, 0xc3, 0x21, 0xe4, 0x12, 0x8e, 0x9f,
- 0x47, 0x12, 0xa7, 0xc4, 0xf9, 0xfd, 0xbf, 0xbb, 0x97, 0xf5, 0x46, 0xfd,
- 0x1c, 0xcd, 0x4e, 0x4a, 0xf6, 0x4a, 0xbe, 0x7f, 0xf2, 0x03, 0x74, 0x3b,
- 0xe5, 0x91, 0x0f, 0x6c, 0x13, 0x63, 0x7a, 0xc5, 0x7e, 0xdb, 0x47, 0xb9,
- 0x1e, 0x7d, 0x42, 0xf5, 0x28, 0x2a, 0xb6, 0xd2, 0x73, 0xa3, 0xf3, 0x4a,
- 0x7a, 0x8a, 0x78, 0x3f, 0x46, 0x39, 0x26, 0xe1, 0x1c, 0x47, 0xa2, 0xc0,
- 0xb3, 0xfa, 0x51, 0x9a, 0xd5, 0xcd, 0xdc, 0x32, 0x8a, 0xe7, 0x03, 0x76,
- 0xd7, 0xc0, 0xa0, 0x30, 0x8f, 0x52, 0x6d, 0x4e, 0x1c, 0xa0, 0xb9, 0x8b,
- 0xbe, 0x37, 0xb4, 0x87, 0xba, 0xec, 0x75, 0x30, 0xdd, 0x85, 0xc2, 0x34,
- 0x5e, 0x17, 0xa6, 0x5e, 0x23, 0x58, 0x27, 0x9f, 0x60, 0x91, 0xaf, 0x9b,
- 0xe3, 0xb0, 0xfc, 0xef, 0x57, 0xd2, 0x1d, 0xfe, 0xf7, 0xd1, 0xf4, 0xc5,
- 0xe7, 0x7b, 0x0b, 0x77, 0x07, 0xd5, 0xc6, 0x7c, 0x21, 0x83, 0x48, 0x33,
- 0xd7, 0x8a, 0xa8, 0x38, 0xb0, 0x0b, 0x5a, 0xbd, 0xf3, 0x3e, 0xbe, 0x3e,
- 0x04, 0x4d, 0x73, 0xa8, 0xd2, 0x12, 0x2f, 0xd4, 0x1b, 0xa4, 0xae, 0x13,
- 0xdc, 0x0f, 0x74, 0xe5, 0x9e, 0x80, 0xd9, 0x53, 0x43, 0x34, 0x3e, 0x01,
- 0xe3, 0x7a, 0x1f, 0x49, 0x1f, 0xe7, 0x2c, 0xce, 0xe3, 0x8c, 0x8a, 0xc1,
- 0xd1, 0xa8, 0xd8, 0x4c, 0xb2, 0xb4, 0x3b, 0x27, 0x71, 0x85, 0xcf, 0xff,
- 0x2b, 0xc4, 0x3f, 0xe7, 0x9c, 0x13, 0x94, 0x73, 0x18, 0xef, 0xd1, 0x34,
- 0xe3, 0x1d, 0xa0, 0x3e, 0xf3, 0x7a, 0xdb, 0x4c, 0xf5, 0x84, 0xcc, 0x44,
- 0x97, 0x30, 0x29, 0xa9, 0xb1, 0x3c, 0x5d, 0xfd, 0x33, 0xe0, 0xb9, 0xd8,
- 0x97, 0xa9, 0xa7, 0x9e, 0x64, 0x1a, 0x22, 0x7a, 0x1f, 0xfa, 0xf4, 0x4e,
- 0xce, 0xd1, 0x3b, 0xf1, 0x07, 0x64, 0x52, 0xdd, 0xfb, 0xc9, 0x1e, 0xdb,
- 0x0a, 0xaf, 0xc8, 0xce, 0xd6, 0x8a, 0x4c, 0x83, 0x3e, 0x2f, 0x3f, 0x49,
- 0x33, 0x2f, 0x51, 0x67, 0x86, 0xe6, 0x48, 0xa6, 0x6d, 0xae, 0x22, 0xba,
- 0x44, 0xb3, 0xcb, 0x18, 0x10, 0x66, 0x3f, 0xe9, 0xad, 0x6f, 0xdc, 0xd7,
- 0xdb, 0x4f, 0xd2, 0x5d, 0x3e, 0xce, 0x19, 0xea, 0x39, 0xbe, 0xe8, 0x93,
- 0xec, 0x73, 0xd5, 0xbb, 0xca, 0x94, 0x78, 0x8a, 0x7a, 0x97, 0xa7, 0x8a,
- 0xaa, 0xd8, 0x47, 0xf6, 0x1c, 0xa7, 0xb8, 0x19, 0xf4, 0xef, 0x1f, 0xa9,
- 0x06, 0x96, 0xbe, 0xd7, 0x3c, 0x97, 0x6f, 0xc8, 0xae, 0x65, 0xb2, 0x6b,
- 0x27, 0x65, 0x65, 0xee, 0xd9, 0xb8, 0xde, 0x1d, 0xa6, 0x7a, 0x27, 0xf0,
- 0xa1, 0x9f, 0x63, 0x0f, 0xa3, 0xb3, 0xc8, 0x3d, 0xa1, 0x25, 0x96, 0xe7,
- 0x8d, 0xdc, 0x7c, 0xc2, 0xfd, 0x7e, 0xa9, 0x92, 0x1f, 0xa9, 0x36, 0xba,
- 0x21, 0xa7, 0x47, 0xbc, 0x50, 0xe4, 0x9f, 0x54, 0x4c, 0x62, 0xec, 0x5b,
- 0xae, 0x68, 0xea, 0xf4, 0xd0, 0xde, 0xe9, 0x49, 0xd5, 0xb2, 0xca, 0xef,
- 0x0b, 0xeb, 0x94, 0x15, 0x72, 0x6f, 0x9f, 0x8f, 0x4d, 0xb8, 0x6c, 0xb1,
- 0x7b, 0x73, 0x02, 0xfe, 0x4c, 0x6c, 0x50, 0x4c, 0xa2, 0xb7, 0x3b, 0xd9,
- 0x33, 0x2d, 0x92, 0xd4, 0x43, 0x25, 0xbd, 0x94, 0x48, 0xa6, 0x8e, 0xc3,
- 0xd6, 0x8e, 0x14, 0x6d, 0xed, 0x8d, 0x62, 0xf5, 0x6e, 0x93, 0xe5, 0x62,
- 0x5f, 0xe5, 0xf8, 0xb0, 0xdc, 0xfb, 0x29, 0x0f, 0xc1, 0xef, 0x43, 0xe4,
- 0xa1, 0x46, 0x8a, 0xb1, 0x3b, 0x51, 0x4b, 0x4d, 0xb3, 0xdc, 0xde, 0x44,
- 0xf3, 0xcf, 0x5d, 0x44, 0xbf, 0xdc, 0x9a, 0x03, 0xd7, 0x93, 0x47, 0xf8,
- 0xc2, 0xb9, 0x85, 0x79, 0x7a, 0x33, 0x52, 0x91, 0x91, 0xca, 0x70, 0xe5,
- 0xff, 0x17, 0xd2, 0x1a, 0x28, 0x06, 0xd7, 0x0d, 0x09, 0xea, 0xef, 0x2b,
- 0xf1, 0xb8, 0x90, 0xef, 0x4e, 0xfd, 0x7b, 0xb3, 0x57, 0x64, 0xa5, 0xde,
- 0x7f, 0xdc, 0xcc, 0x77, 0x51, 0x8a, 0x33, 0x1c, 0xfb, 0xed, 0xb3, 0x15,
- 0xdd, 0xf2, 0x1c, 0x7f, 0xa8, 0xe4, 0x8a, 0x6b, 0xf3, 0xd8, 0x40, 0xbd,
- 0x83, 0x1b, 0x26, 0x1c, 0xd7, 0x16, 0x7b, 0x49, 0x37, 0x96, 0x31, 0x48,
- 0x44, 0xb7, 0xea, 0x5d, 0xfa, 0x38, 0xf5, 0x5a, 0x84, 0xcb, 0xa0, 0x7e,
- 0x94, 0x62, 0x7c, 0x1e, 0x76, 0xcc, 0xc5, 0x54, 0xbd, 0xc3, 0x77, 0xbb,
- 0x03, 0x62, 0xe1, 0x54, 0x25, 0xcd, 0x1f, 0x3a, 0x27, 0xdf, 0x69, 0xb9,
- 0xfd, 0x26, 0x7e, 0x5f, 0x3f, 0x67, 0x93, 0x2b, 0x99, 0x26, 0xfd, 0x7e,
- 0x76, 0x8e, 0x87, 0x3f, 0x74, 0xf6, 0x8e, 0xaf, 0xfe, 0xf6, 0x99, 0x59,
- 0xe2, 0x93, 0x7b, 0x45, 0x78, 0x31, 0x87, 0xfb, 0xc4, 0x0b, 0xe7, 0x7c,
- 0xe1, 0x52, 0xc2, 0xbd, 0x01, 0x37, 0xd2, 0x7c, 0xd4, 0x49, 0x73, 0x28,
- 0xcd, 0x2e, 0x48, 0x0d, 0xb3, 0x3e, 0xce, 0x90, 0x3e, 0xd8, 0xe6, 0xa7,
- 0xc8, 0xe6, 0x1d, 0x39, 0x8a, 0x99, 0xd4, 0x7a, 0x61, 0xf6, 0x92, 0xbf,
- 0x51, 0xed, 0x32, 0x13, 0x1f, 0xc3, 0x34, 0xd6, 0xfa, 0x3e, 0x7d, 0x66,
- 0xce, 0xa7, 0x4f, 0xb1, 0x4f, 0xa3, 0x6f, 0x38, 0x04, 0x25, 0xf3, 0x29,
- 0xe9, 0x8c, 0xe2, 0x4d, 0x30, 0x4e, 0xce, 0x53, 0x67, 0x40, 0xfd, 0xb2,
- 0x36, 0x9f, 0xf6, 0xc8, 0x42, 0x47, 0xe2, 0x28, 0xf5, 0xdb, 0xfb, 0xc0,
- 0x25, 0xa3, 0xeb, 0xe8, 0x31, 0x61, 0x96, 0xdf, 0x0b, 0x71, 0x0e, 0x10,
- 0x68, 0xcc, 0x54, 0xf0, 0x5d, 0x5e, 0x4c, 0x60, 0x47, 0xa9, 0x82, 0xf3,
- 0x32, 0xf2, 0xe1, 0x31, 0xff, 0x7e, 0x41, 0x81, 0x96, 0x79, 0x9b, 0x6b,
- 0x33, 0xc1, 0x25, 0x73, 0xf2, 0x7f, 0x67, 0xce, 0x06, 0x6f, 0xce, 0xe9,
- 0x67, 0x4b, 0x8c, 0x6b, 0x8f, 0x96, 0xe1, 0x7c, 0x0d, 0xb1, 0x26, 0xff,
- 0x67, 0x54, 0x03, 0x34, 0xea, 0x81, 0xfd, 0xbc, 0x8f, 0x5c, 0x11, 0x94,
- 0xbf, 0xcb, 0xb5, 0x47, 0xec, 0xf0, 0x5c, 0xfe, 0xfa, 0x06, 0xad, 0xf5,
- 0xd1, 0x87, 0x75, 0xc6, 0x77, 0x12, 0x37, 0xd1, 0xb3, 0xeb, 0xef, 0xeb,
- 0xcf, 0xa3, 0xa7, 0x36, 0x4d, 0xfd, 0xad, 0xbf, 0xcf, 0xbf, 0xaf, 0xa0,
- 0x3d, 0xcb, 0xf9, 0xdd, 0x08, 0xdf, 0xb5, 0xac, 0xce, 0x26, 0x8d, 0xcd,
- 0x60, 0x3a, 0x06, 0xd6, 0x14, 0x0d, 0xdc, 0x4a, 0x75, 0x61, 0xcc, 0xbf,
- 0x07, 0x3d, 0x3f, 0xf7, 0x28, 0xb4, 0x6f, 0x19, 0xed, 0x1b, 0xf4, 0xd7,
- 0x0c, 0x2c, 0x2f, 0x9e, 0x9f, 0xe9, 0x54, 0x3a, 0x77, 0xe8, 0xdc, 0x1c,
- 0xcb, 0x76, 0x70, 0xc5, 0xce, 0x7c, 0xaf, 0x18, 0xc9, 0x47, 0x89, 0x96,
- 0x42, 0x19, 0x40, 0xa2, 0x23, 0x73, 0x33, 0xe5, 0x5d, 0x2b, 0xa5, 0x2a,
- 0x4d, 0x58, 0x9b, 0x22, 0x3f, 0xd6, 0x97, 0xe2, 0x8e, 0x54, 0x0d, 0xf5,
- 0x34, 0xc3, 0xb8, 0x4d, 0xaf, 0x45, 0x7f, 0xea, 0x52, 0xe0, 0xc6, 0x3a,
- 0xea, 0x41, 0x06, 0xfc, 0x9e, 0xbe, 0x86, 0xe8, 0xd5, 0x59, 0x4f, 0xe1,
- 0xf6, 0x73, 0xff, 0xae, 0x42, 0x34, 0x7e, 0xef, 0x3c, 0x77, 0x33, 0xdc,
- 0xe6, 0x1e, 0xaa, 0x83, 0xdd, 0x58, 0x97, 0x0a, 0x53, 0x6f, 0xcd, 0xf9,
- 0x61, 0x3e, 0x22, 0xd6, 0x67, 0x72, 0xfd, 0xb9, 0x3e, 0x67, 0x46, 0xcc,
- 0x90, 0x5c, 0xa8, 0xf5, 0xc4, 0x73, 0x34, 0xbf, 0x65, 0x4a, 0x7c, 0x1f,
- 0xa5, 0x20, 0x66, 0xf1, 0xcc, 0x48, 0xc3, 0x1f, 0xcd, 0x59, 0xe9, 0xc7,
- 0xeb, 0x71, 0xd5, 0xbe, 0x06, 0x64, 0xf6, 0xe9, 0xb0, 0x1f, 0xb7, 0x68,
- 0x2d, 0x45, 0x9f, 0x19, 0xb1, 0xb7, 0xf8, 0x87, 0x68, 0x77, 0x60, 0x8d,
- 0xfe, 0x3f, 0x95, 0x7d, 0x0b, 0x70, 0x54, 0xe7, 0x95, 0xe6, 0x77, 0xfb,
- 0x21, 0xb5, 0x9e, 0x5c, 0x09, 0x09, 0x5a, 0x20, 0x9b, 0x6e, 0xf7, 0x6d,
- 0xa9, 0x8d, 0x3a, 0xe1, 0x36, 0x88, 0xb5, 0x9c, 0xed, 0x2d, 0x1a, 0x2c,
- 0x8c, 0x08, 0x60, 0xcb, 0xb6, 0x3c, 0x83, 0x77, 0x32, 0x6b, 0xc5, 0x36,
- 0x18, 0x3f, 0x92, 0x91, 0x09, 0x5b, 0x25, 0x53, 0x53, 0xd1, 0x1d, 0x01,
- 0x42, 0x40, 0xbf, 0x24, 0xc1, 0x00, 0x33, 0x53, 0xe3, 0x46, 0x0f, 0x20,
- 0xb8, 0x5b, 0xc2, 0x71, 0x66, 0x4a, 0xc9, 0xd4, 0x56, 0x34, 0x20, 0x0c,
- 0x04, 0x63, 0x3c, 0x93, 0x99, 0x29, 0xb2, 0xeb, 0x2d, 0x13, 0x1c, 0xc0,
- 0x0f, 0xfc, 0x4c, 0xb2, 0x16, 0xf1, 0xc4, 0x77, 0xbf, 0x73, 0xbb, 0x1b,
- 0x04, 0x45, 0x3c, 0x35, 0x54, 0x75, 0xb5, 0x6e, 0xdf, 0xff, 0xfe, 0x8f,
- 0xf3, 0x9f, 0xf3, 0x9d, 0xef, 0x9c, 0xf3, 0xdf, 0xa2, 0x84, 0xfe, 0xfb,
- 0xdf, 0xcc, 0x75, 0x8c, 0x4f, 0xdc, 0x0b, 0x69, 0x66, 0xb3, 0x65, 0xbc,
- 0x0b, 0x5f, 0x0e, 0x24, 0x9c, 0xe8, 0xea, 0x77, 0xe0, 0xda, 0xa2, 0x73,
- 0xa6, 0x67, 0xf6, 0x8d, 0xfc, 0x4e, 0xc4, 0xe6, 0xc4, 0x33, 0xfd, 0xf2,
- 0xed, 0x40, 0x60, 0x71, 0x36, 0xe7, 0xba, 0x61, 0xd0, 0x89, 0xa7, 0xd9,
- 0xf6, 0xa2, 0x6e, 0xcb, 0xed, 0xb1, 0x55, 0x1b, 0xc0, 0x73, 0xfd, 0x8c,
- 0x6d, 0x34, 0x13, 0xcf, 0x86, 0x8a, 0x71, 0x7f, 0x75, 0x76, 0x1d, 0xc3,
- 0x5c, 0x87, 0xe1, 0x30, 0x94, 0x4c, 0xa3, 0x13, 0xe5, 0x9c, 0x3f, 0xb9,
- 0x18, 0x7e, 0x98, 0x29, 0xc1, 0xe8, 0x81, 0x71, 0x25, 0x9d, 0xce, 0xb6,
- 0x19, 0xb2, 0x62, 0x5a, 0x43, 0x19, 0x6b, 0xb4, 0x61, 0x26, 0xfd, 0xfb,
- 0x85, 0x8c, 0x03, 0x9f, 0x65, 0x5c, 0xf8, 0x74, 0xa4, 0x18, 0xbf, 0x3e,
- 0x50, 0xc2, 0x8f, 0x8a, 0x4f, 0x46, 0x34, 0xfe, 0xde, 0xac, 0xbc, 0x12,
- 0x95, 0xd8, 0x23, 0x80, 0x4f, 0x33, 0xe3, 0xca, 0xd1, 0xaf, 0x5c, 0x6b,
- 0xc6, 0xfc, 0x8e, 0x6a, 0x70, 0xcc, 0xbf, 0x36, 0xbf, 0x3b, 0x4d, 0xae,
- 0xd3, 0xc7, 0xaa, 0xd4, 0x4a, 0xf0, 0xd9, 0x01, 0x19, 0x47, 0xfa, 0x6f,
- 0x56, 0x5e, 0x8d, 0x8a, 0x7c, 0x2b, 0xf1, 0xeb, 0x11, 0x91, 0xe3, 0x27,
- 0xd4, 0x69, 0xe9, 0x7f, 0x5c, 0x39, 0x9e, 0x7b, 0xe6, 0xe7, 0xdc, 0x8b,
- 0x8d, 0xa3, 0x0e, 0x90, 0x4c, 0xf0, 0x59, 0x17, 0x5e, 0x38, 0x68, 0x23,
- 0x27, 0x2e, 0xc6, 0xc6, 0xc1, 0x12, 0xbc, 0x30, 0xa8, 0xa2, 0xe3, 0x60,
- 0xb3, 0x42, 0xbe, 0xaf, 0xce, 0x20, 0xef, 0xed, 0x18, 0x0d, 0xb0, 0xdd,
- 0xb8, 0x72, 0x2e, 0xdd, 0x30, 0x33, 0xdb, 0x4f, 0x36, 0xf7, 0x93, 0xe5,
- 0x31, 0x86, 0xc2, 0x38, 0x8d, 0x5c, 0x72, 0xdf, 0xe6, 0xd7, 0x18, 0x21,
- 0x3e, 0x9c, 0xb6, 0x53, 0xc7, 0x24, 0x1e, 0x15, 0xbb, 0x4f, 0x6d, 0xbe,
- 0x12, 0x95, 0xb9, 0x1a, 0xca, 0x91, 0x46, 0x9b, 0xc5, 0xb1, 0x5f, 0x67,
- 0x5c, 0xb8, 0x82, 0xb6, 0xf2, 0x10, 0xe5, 0xb1, 0x9a, 0xf2, 0x68, 0xa6,
- 0x3c, 0x5a, 0x39, 0xdf, 0x97, 0xa3, 0x82, 0x93, 0xde, 0x40, 0x44, 0xd1,
- 0xb0, 0x2a, 0x23, 0x7d, 0x58, 0xe3, 0xb8, 0x1c, 0xe1, 0xbf, 0xd9, 0xbc,
- 0x35, 0x7a, 0xab, 0x5c, 0xa0, 0x96, 0x87, 0xc5, 0xaf, 0x89, 0x6c, 0x02,
- 0xe4, 0x50, 0xe3, 0xca, 0xa8, 0x15, 0x23, 0xef, 0xdb, 0xec, 0x49, 0xe5,
- 0x6d, 0xa7, 0x44, 0xec, 0x53, 0xf2, 0xe1, 0xca, 0x3e, 0x72, 0xb5, 0x1a,
- 0x2d, 0x7b, 0xff, 0xde, 0x94, 0x7c, 0xa7, 0x36, 0x2f, 0xb4, 0xf0, 0xe6,
- 0x6f, 0x36, 0x37, 0x5d, 0x5f, 0xd3, 0xb8, 0xf2, 0x36, 0xd7, 0x73, 0x81,
- 0x7a, 0x7a, 0x92, 0x73, 0x2d, 0x92, 0xbd, 0x4b, 0x73, 0xef, 0x38, 0xd7,
- 0x4f, 0x87, 0x8b, 0xf1, 0x5e, 0xaa, 0x84, 0x1f, 0xca, 0x76, 0x98, 0x7b,
- 0x97, 0x6e, 0x56, 0x4e, 0x59, 0xf2, 0x0d, 0xe0, 0x5d, 0x8e, 0x7d, 0xec,
- 0x7a, 0x1f, 0x59, 0xde, 0x96, 0xad, 0xc3, 0xe5, 0xed, 0x57, 0xf0, 0x54,
- 0xd6, 0x66, 0x28, 0x91, 0xeb, 0xb5, 0x34, 0xc9, 0x8b, 0x49, 0x7d, 0x91,
- 0x3e, 0x46, 0x95, 0xfc, 0xa8, 0x42, 0x8c, 0xa1, 0xfe, 0xa9, 0xcb, 0x3c,
- 0x0e, 0xe2, 0xe2, 0x3a, 0x7c, 0xc1, 0x38, 0x21, 0x42, 0x8b, 0x92, 0xb5,
- 0x48, 0x8e, 0xb4, 0x50, 0x62, 0x42, 0xeb, 0xdf, 0x20, 0xb9, 0xd4, 0x6b,
- 0xe4, 0xb9, 0x54, 0x21, 0x74, 0xa7, 0xbf, 0x30, 0x27, 0xaa, 0xe8, 0x57,
- 0xb5, 0xeb, 0x79, 0x37, 0xae, 0xd9, 0x34, 0x87, 0x78, 0xaf, 0x27, 0x8d,
- 0xdc, 0x3f, 0x72, 0x2f, 0xf2, 0xdd, 0x27, 0xb5, 0xdf, 0x99, 0x4f, 0xdc,
- 0xd4, 0x36, 0x8f, 0xe5, 0xf9, 0x78, 0x5f, 0xb0, 0xbc, 0x14, 0x3d, 0xbb,
- 0xbd, 0xc9, 0x14, 0xaa, 0x90, 0xd4, 0x6c, 0x73, 0x0b, 0x38, 0x3b, 0x3b,
- 0xbc, 0xbd, 0xcd, 0xb0, 0xf2, 0x20, 0x9e, 0x14, 0xfe, 0x61, 0xa6, 0xd8,
- 0x8c, 0x53, 0x6b, 0xf0, 0x54, 0xd8, 0x2a, 0x65, 0xee, 0xd6, 0xac, 0xec,
- 0xfd, 0x45, 0x58, 0x17, 0x2c, 0x42, 0xaa, 0x95, 0x18, 0xd7, 0x6f, 0xb4,
- 0xb0, 0x7b, 0xf2, 0xa7, 0xc0, 0x8b, 0xdf, 0xf4, 0x0b, 0x1f, 0x03, 0x0a,
- 0x63, 0x1c, 0x13, 0x39, 0x0c, 0xec, 0xf7, 0x1a, 0x36, 0x9b, 0x3c, 0xff,
- 0x99, 0x69, 0xb4, 0xc9, 0xb3, 0xd2, 0x47, 0xad, 0xc5, 0x1b, 0x6f, 0xd6,
- 0x7b, 0x0f, 0xe5, 0xf4, 0xaf, 0x33, 0x25, 0xe7, 0xa8, 0xd6, 0x31, 0xee,
- 0xe9, 0x97, 0x9a, 0x4d, 0x04, 0xbb, 0xaa, 0x7d, 0x1d, 0xba, 0xad, 0x18,
- 0x67, 0xbf, 0xf6, 0xdf, 0x88, 0xe9, 0x05, 0x70, 0xd5, 0x01, 0xf7, 0xc5,
- 0x6d, 0xb0, 0xd5, 0x11, 0xab, 0xa9, 0xd3, 0xcd, 0xa3, 0x36, 0xcc, 0xeb,
- 0x57, 0xf0, 0x58, 0xd2, 0x86, 0x07, 0x92, 0x76, 0xac, 0x4a, 0xe2, 0xfb,
- 0xf3, 0x80, 0xc9, 0x1a, 0xf8, 0xdb, 0xa7, 0xe8, 0x9a, 0xcb, 0xe1, 0x6f,
- 0x8d, 0x91, 0x17, 0xac, 0x62, 0x2c, 0xba, 0x72, 0x94, 0x38, 0xc8, 0xb6,
- 0xce, 0x3e, 0xea, 0x66, 0x9f, 0x1d, 0x35, 0x7d, 0xb8, 0xb3, 0x10, 0xa0,
- 0x75, 0xfb, 0xa7, 0xe8, 0x97, 0x2a, 0x1d, 0xf0, 0xd3, 0xaf, 0xf8, 0x3b,
- 0x6b, 0xec, 0x0c, 0xc4, 0xea, 0xfe, 0xd5, 0xe2, 0xb4, 0x0f, 0xd2, 0x5e,
- 0xe6, 0xf5, 0xb3, 0x7d, 0x9d, 0x0d, 0x2a, 0xf5, 0xf9, 0x93, 0x3f, 0x96,
- 0x7c, 0xaf, 0xdc, 0x93, 0xba, 0xab, 0x82, 0xf2, 0x7e, 0x3b, 0xf1, 0xf0,
- 0x8c, 0x79, 0xb6, 0xda, 0xaa, 0x41, 0xe1, 0x31, 0xce, 0xcd, 0xcd, 0xdf,
- 0xd4, 0x3a, 0x17, 0x16, 0xdc, 0xa3, 0x62, 0xed, 0xa0, 0xb4, 0x85, 0xd5,
- 0x8f, 0x93, 0xb8, 0x53, 0xa0, 0x4d, 0x98, 0x07, 0xab, 0xa4, 0xad, 0x8d,
- 0x6b, 0xb4, 0xa3, 0xa4, 0x1f, 0x58, 0x19, 0xc7, 0xc3, 0xa5, 0xf0, 0x47,
- 0x64, 0x8e, 0xf5, 0x8b, 0x1d, 0x7c, 0xb6, 0x14, 0x2d, 0xa3, 0xd9, 0xe7,
- 0x56, 0x8c, 0xbe, 0x37, 0x33, 0x9b, 0xfb, 0xfe, 0xc3, 0x75, 0xe3, 0x2d,
- 0x8d, 0x7e, 0xac, 0x4b, 0x52, 0xe7, 0x6c, 0x1e, 0x0c, 0xe6, 0x72, 0xd0,
- 0x4f, 0xa4, 0xbc, 0xd3, 0xea, 0xba, 0x7f, 0x5b, 0x9a, 0xab, 0xf9, 0xd2,
- 0x8e, 0xa7, 0xd8, 0x8f, 0x65, 0xc3, 0x18, 0x1c, 0x33, 0x11, 0xd5, 0x4d,
- 0x64, 0xf8, 0x79, 0x43, 0x87, 0x51, 0x42, 0x1b, 0x7f, 0x2a, 0x26, 0x98,
- 0x97, 0xd5, 0xa4, 0x1f, 0x24, 0x02, 0xca, 0x86, 0x18, 0x70, 0x84, 0xf1,
- 0xe3, 0x21, 0x7e, 0x86, 0x13, 0x5c, 0x03, 0xe7, 0x6d, 0x23, 0x6e, 0x6c,
- 0x4b, 0x01, 0x43, 0x09, 0x44, 0xf6, 0x2f, 0x96, 0x58, 0xa6, 0x84, 0xe3,
- 0x01, 0xe3, 0x6c, 0x93, 0xe6, 0xe7, 0x20, 0x3f, 0x63, 0xdc, 0x53, 0x8e,
- 0x87, 0x00, 0xf1, 0x30, 0x92, 0xd1, 0x60, 0x64, 0x02, 0x98, 0xa0, 0x6d,
- 0x5d, 0x1b, 0x56, 0x51, 0x76, 0xa8, 0x12, 0x1f, 0x8d, 0x64, 0x63, 0xa5,
- 0x75, 0x19, 0xa9, 0x5d, 0xcb, 0xda, 0xa4, 0x7e, 0x2d, 0xb6, 0x54, 0x84,
- 0x43, 0xc9, 0x4a, 0xab, 0x86, 0xfd, 0x8e, 0xce, 0x7e, 0x55, 0xa9, 0xb1,
- 0xb6, 0xe2, 0x70, 0xd4, 0xe7, 0xe9, 0xa5, 0xbe, 0x1b, 0x0e, 0xb1, 0xaf,
- 0x46, 0x1c, 0x89, 0xe6, 0x6b, 0x67, 0xbe, 0x96, 0x9f, 0x49, 0x8e, 0xc8,
- 0x59, 0x49, 0xd9, 0xca, 0xbd, 0xbc, 0xdf, 0x95, 0xf5, 0x4a, 0x0e, 0x3f,
- 0xcf, 0x71, 0xa6, 0xff, 0x7e, 0x8a, 0xe3, 0x05, 0x69, 0x07, 0xde, 0xde,
- 0x14, 0x74, 0xcb, 0x97, 0x8e, 0xd4, 0x7b, 0x93, 0x06, 0x64, 0x6f, 0x1b,
- 0x39, 0x87, 0xd7, 0xa8, 0xf7, 0x01, 0xca, 0xf9, 0x2f, 0xe8, 0x23, 0x5c,
- 0x8c, 0x65, 0x2b, 0xb0, 0xab, 0xaf, 0x12, 0x3b, 0xfb, 0x0c, 0xf4, 0x2c,
- 0x6e, 0xc3, 0xa9, 0xa8, 0x89, 0x75, 0x21, 0x13, 0x2b, 0x19, 0x23, 0xfc,
- 0x00, 0x0d, 0x4d, 0x87, 0xf1, 0x20, 0x63, 0x65, 0x95, 0xf2, 0xf8, 0x16,
- 0xde, 0xde, 0xed, 0xc0, 0x7a, 0xfd, 0x8f, 0x68, 0xbf, 0xa6, 0xf9, 0xab,
- 0x45, 0xb5, 0x18, 0x4c, 0x34, 0xa8, 0xdd, 0x9c, 0x5f, 0xa4, 0x8d, 0xfb,
- 0x14, 0x74, 0xe0, 0x69, 0xfd, 0xfb, 0x6c, 0xeb, 0xb6, 0x39, 0x34, 0xb9,
- 0x96, 0xba, 0x96, 0xec, 0xa3, 0x41, 0xdd, 0xca, 0xfb, 0xac, 0x6c, 0xad,
- 0x74, 0x7d, 0xa3, 0xe4, 0x44, 0x4a, 0x71, 0x92, 0x32, 0x3b, 0x96, 0x8c,
- 0xd0, 0x55, 0x43, 0x79, 0xba, 0xb1, 0x0b, 0x8f, 0x93, 0x9b, 0xbc, 0x4d,
- 0xd2, 0x70, 0x6f, 0x5c, 0x41, 0x53, 0xbd, 0x8e, 0xf3, 0xe9, 0x6f, 0xe1,
- 0xcd, 0xe1, 0x30, 0xde, 0x20, 0x07, 0x58, 0xf0, 0x97, 0xc2, 0xe9, 0x3d,
- 0x38, 0x9b, 0x0e, 0xe3, 0x4c, 0xd4, 0xdb, 0xfa, 0xbc, 0x52, 0x8b, 0x9f,
- 0x11, 0xd3, 0xee, 0x8e, 0x03, 0xef, 0xb1, 0x1f, 0x7f, 0xdc, 0x81, 0x4b,
- 0x69, 0x15, 0x87, 0xb9, 0x37, 0x8e, 0xd0, 0x02, 0x18, 0x6d, 0x1e, 0x1c,
- 0x1c, 0x78, 0x00, 0x13, 0xa9, 0x07, 0x70, 0x22, 0xf9, 0xb6, 0xe9, 0xd2,
- 0xa4, 0x06, 0xe6, 0xc2, 0x25, 0x62, 0xea, 0x24, 0xa5, 0x51, 0x7a, 0x4f,
- 0x2b, 0x71, 0x51, 0x33, 0x44, 0xee, 0x6f, 0xf2, 0xb7, 0x7b, 0xe3, 0x4d,
- 0xd8, 0x9f, 0xa1, 0x48, 0x13, 0x3a, 0x12, 0x31, 0x19, 0xab, 0x11, 0x31,
- 0x72, 0xc8, 0x5d, 0x7d, 0xe2, 0x37, 0xef, 0xc6, 0xca, 0x0a, 0x28, 0x2d,
- 0x75, 0x63, 0xb9, 0x75, 0x34, 0x4d, 0xab, 0x6d, 0x4a, 0xbc, 0x49, 0xb9,
- 0xf2, 0xb9, 0x1f, 0x26, 0x28, 0xf7, 0x04, 0x65, 0x7b, 0x7d, 0x3f, 0x9a,
- 0xb8, 0x1f, 0xdf, 0xc2, 0xf9, 0xdd, 0x6d, 0x78, 0x93, 0x58, 0x57, 0xbe,
- 0xc8, 0xd7, 0xe9, 0xb4, 0x35, 0xb0, 0xef, 0xb4, 0x99, 0xaa, 0x16, 0x99,
- 0xb6, 0xe1, 0x17, 0x51, 0x91, 0x69, 0x9a, 0xd8, 0xe7, 0xf3, 0xf8, 0xed,
- 0x23, 0x55, 0xd4, 0x65, 0x5b, 0x77, 0x30, 0x5b, 0xaf, 0x2b, 0xbd, 0xc7,
- 0x85, 0xcb, 0xd6, 0xdc, 0x64, 0xae, 0x5f, 0x35, 0xbf, 0x5f, 0x98, 0x2b,
- 0xab, 0x65, 0x7e, 0x86, 0xc9, 0x98, 0x3a, 0xc0, 0x78, 0x91, 0xb6, 0x13,
- 0x80, 0xe4, 0x9c, 0xeb, 0xe3, 0x5d, 0xb0, 0x87, 0x4a, 0x0d, 0x35, 0xec,
- 0x9d, 0xea, 0xc0, 0x9b, 0xb8, 0x42, 0x8e, 0x72, 0x57, 0x5c, 0x63, 0x7c,
- 0x7b, 0x81, 0x63, 0xfd, 0x0b, 0x2e, 0xf2, 0xda, 0x17, 0xcf, 0xda, 0x5a,
- 0x77, 0x63, 0x1b, 0xee, 0x4b, 0xcb, 0xfa, 0xfe, 0x0b, 0x07, 0xd2, 0x11,
- 0x49, 0xcb, 0x3a, 0x63, 0xb4, 0x0b, 0x59, 0x67, 0xe5, 0x7f, 0xb0, 0xce,
- 0x23, 0xec, 0xaf, 0x96, 0x76, 0x94, 0xf7, 0x1b, 0x65, 0x38, 0x98, 0x54,
- 0x71, 0x52, 0x2f, 0xc5, 0x05, 0x55, 0xf2, 0xf5, 0xd9, 0x5a, 0x66, 0x33,
- 0xe3, 0xd3, 0x21, 0x7e, 0x9e, 0x62, 0x0c, 0x75, 0x5a, 0x77, 0xe0, 0x84,
- 0x5e, 0x4b, 0x9c, 0xbf, 0x55, 0x87, 0xe5, 0x1e, 0x03, 0x83, 0x8a, 0x4a,
- 0x9c, 0x91, 0x9c, 0xaa, 0x75, 0x5f, 0xce, 0x16, 0xb8, 0x20, 0x39, 0x8d,
- 0x82, 0xd8, 0x6f, 0xcd, 0xcb, 0x16, 0xce, 0xdc, 0x3a, 0xbf, 0x5b, 0xfb,
- 0x21, 0x55, 0xd0, 0xde, 0x33, 0x9f, 0xad, 0xce, 0xf9, 0x2d, 0x65, 0x47,
- 0x55, 0x16, 0x2b, 0xc4, 0x87, 0x8d, 0xe7, 0x71, 0x83, 0x7c, 0x7c, 0xdf,
- 0xa3, 0xf4, 0x41, 0xf4, 0xcf, 0xcd, 0xdf, 0xdb, 0xaa, 0x49, 0x9c, 0x97,
- 0x7a, 0x74, 0x99, 0x56, 0x00, 0xbb, 0xe5, 0x67, 0x0f, 0x6f, 0xce, 0xf2,
- 0xf9, 0xf4, 0xe6, 0x6c, 0x8c, 0x7a, 0x74, 0xf3, 0x5d, 0xd6, 0xf7, 0x8f,
- 0x36, 0xfb, 0x52, 0x37, 0x7c, 0x55, 0x96, 0x2f, 0x5b, 0x67, 0x6d, 0xd0,
- 0xab, 0x1b, 0xca, 0x8a, 0x46, 0xf1, 0xd7, 0x79, 0x8e, 0x22, 0x6d, 0x02,
- 0xca, 0x89, 0xa8, 0x61, 0xba, 0xb5, 0x62, 0xfa, 0x7a, 0x28, 0x63, 0x8c,
- 0xc5, 0xa6, 0xac, 0xba, 0xa7, 0x86, 0x37, 0xd2, 0x12, 0x13, 0x83, 0xfa,
- 0xfb, 0xbf, 0xb1, 0x6b, 0x37, 0xda, 0x8b, 0x16, 0x93, 0xb3, 0xd3, 0xcf,
- 0x3d, 0x1b, 0x72, 0xe0, 0xfd, 0x74, 0x76, 0x3d, 0xef, 0x0d, 0x97, 0xe0,
- 0xdd, 0x94, 0xf8, 0x6b, 0xa8, 0x85, 0xec, 0xf7, 0x64, 0x5a, 0x63, 0x6c,
- 0x2a, 0xe3, 0xb6, 0x61, 0xdb, 0x98, 0x03, 0xfb, 0xa3, 0x1a, 0x62, 0x89,
- 0x9f, 0x9a, 0x45, 0x9a, 0x6f, 0xc2, 0x6f, 0x77, 0x60, 0x5f, 0x7a, 0x12,
- 0x63, 0x7d, 0x1f, 0x9b, 0x76, 0xad, 0x0b, 0x1f, 0x85, 0x26, 0xc9, 0xeb,
- 0xa4, 0xfe, 0xa9, 0x63, 0xd7, 0x80, 0xc6, 0x58, 0xda, 0x86, 0x9d, 0x8b,
- 0x5b, 0xb0, 0x6b, 0xac, 0x19, 0xc6, 0x21, 0x0f, 0x76, 0x92, 0xf0, 0x4d,
- 0x0c, 0x4f, 0xe2, 0x54, 0x52, 0x6b, 0x2a, 0x52, 0x26, 0x71, 0x92, 0xe3,
- 0x6c, 0x4d, 0xbc, 0x05, 0x83, 0x7d, 0x6c, 0x4b, 0x4a, 0x8e, 0x57, 0xc6,
- 0x99, 0x44, 0x77, 0xea, 0x76, 0x35, 0x8f, 0x36, 0xec, 0x48, 0x6c, 0x69,
- 0xcf, 0xd6, 0x3d, 0x88, 0xab, 0x69, 0x4d, 0xe9, 0xe5, 0x1e, 0x1d, 0x4e,
- 0xe7, 0x6b, 0x20, 0x82, 0xa1, 0x59, 0x3c, 0xdc, 0x96, 0xd6, 0xd1, 0x3b,
- 0xd0, 0xc2, 0xf6, 0x1a, 0xba, 0x13, 0x52, 0x3f, 0xf6, 0x71, 0x3c, 0x13,
- 0xef, 0xe9, 0x5e, 0xf7, 0x5d, 0xfc, 0x1e, 0xd1, 0x3b, 0xb1, 0x81, 0xfd,
- 0x08, 0xe7, 0xd2, 0x14, 0x6f, 0x93, 0x01, 0x3b, 0x7e, 0xa5, 0xdb, 0x61,
- 0x54, 0xd9, 0x71, 0x44, 0x2f, 0x23, 0x3f, 0xb7, 0xa3, 0x21, 0x44, 0xdf,
- 0x9c, 0xf3, 0xd5, 0x1f, 0x26, 0x15, 0x3c, 0x40, 0x2c, 0x3d, 0x16, 0x6a,
- 0x68, 0x5f, 0x2e, 0x6c, 0xf7, 0x80, 0x82, 0x2b, 0xda, 0x35, 0xd3, 0xa0,
- 0xbf, 0x72, 0xf9, 0xf3, 0x7b, 0xf3, 0x6b, 0x33, 0x5b, 0x03, 0xfe, 0xc2,
- 0xcc, 0x3f, 0x37, 0xc5, 0xf9, 0x3d, 0xc6, 0xe7, 0xee, 0x5a, 0xd4, 0xd0,
- 0x29, 0xcf, 0xb9, 0x89, 0xe3, 0xf2, 0x9c, 0xe4, 0xf6, 0x6f, 0x3c, 0xa7,
- 0x63, 0xdb, 0x40, 0xc4, 0x9a, 0xef, 0xf6, 0x04, 0x16, 0x3a, 0x20, 0x76,
- 0xd4, 0xa0, 0x5e, 0x02, 0xba, 0x26, 0xf5, 0x19, 0xe4, 0x37, 0xfe, 0xc0,
- 0x53, 0x10, 0x39, 0x49, 0xbc, 0xf9, 0x16, 0x76, 0x46, 0x87, 0xc1, 0x98,
- 0x93, 0xf8, 0xe6, 0x5f, 0x3b, 0x84, 0x14, 0x9e, 0x4b, 0xa7, 0xf0, 0xbc,
- 0x70, 0x6c, 0x2b, 0xc7, 0x96, 0xc6, 0x77, 0xa2, 0x6f, 0x21, 0x66, 0xc5,
- 0x55, 0x87, 0xf1, 0x44, 0xf4, 0xdd, 0x6a, 0xc9, 0x65, 0x6e, 0x4d, 0x2c,
- 0x65, 0xff, 0x22, 0x53, 0x6f, 0xab, 0x81, 0x2f, 0xd9, 0xff, 0x52, 0x6c,
- 0x19, 0x92, 0x9c, 0x90, 0x89, 0xd7, 0xc9, 0xa9, 0xae, 0x50, 0x8f, 0x5a,
- 0x1a, 0xa5, 0xff, 0x71, 0x45, 0xb3, 0x7c, 0x57, 0x1b, 0xf7, 0x78, 0x16,
- 0xdc, 0x94, 0x73, 0x59, 0x46, 0x53, 0xee, 0x8a, 0xc9, 0x9e, 0x3b, 0x60,
- 0xcb, 0x78, 0xf0, 0x18, 0x79, 0x49, 0xe1, 0xc8, 0x8f, 0x14, 0xf1, 0x5f,
- 0x35, 0xe4, 0xa2, 0xee, 0x03, 0x1e, 0x65, 0xc1, 0x1e, 0x17, 0x1e, 0x88,
- 0x91, 0xa3, 0xc6, 0x9a, 0xb1, 0x65, 0xaf, 0xc6, 0x36, 0x5e, 0xfd, 0x1c,
- 0xe3, 0xd6, 0x93, 0xf0, 0x79, 0x86, 0xc8, 0xa5, 0xdc, 0xc4, 0x60, 0xc7,
- 0x48, 0x39, 0x4a, 0xc8, 0xb3, 0xa5, 0xdc, 0x5c, 0x3a, 0xe2, 0x46, 0x0d,
- 0xfd, 0x99, 0x3b, 0x73, 0x1e, 0x63, 0x7b, 0xa0, 0x96, 0x84, 0x3f, 0x37,
- 0x0b, 0x35, 0xa9, 0x57, 0x06, 0x50, 0x9e, 0xd9, 0x84, 0x74, 0x2c, 0x88,
- 0x52, 0xf2, 0xfb, 0x06, 0x8e, 0x77, 0x7f, 0x4c, 0x63, 0x3f, 0x59, 0x6e,
- 0xb3, 0x9c, 0xcf, 0xf4, 0x26, 0xbc, 0x6b, 0xa5, 0xde, 0x78, 0x45, 0x7f,
- 0x0d, 0x45, 0x7d, 0x37, 0xce, 0x9c, 0x69, 0x21, 0xcc, 0x21, 0xf7, 0x68,
- 0x7d, 0x1a, 0xd9, 0xf3, 0x67, 0x2b, 0x72, 0xeb, 0x09, 0xca, 0x7a, 0x9c,
- 0x6d, 0xd4, 0x83, 0xd9, 0x98, 0xc1, 0xf5, 0x5c, 0xa4, 0xde, 0xdc, 0xcb,
- 0xb9, 0x5e, 0x63, 0xec, 0xd0, 0xc9, 0xb5, 0xbc, 0x3f, 0xfc, 0x23, 0xa5,
- 0x86, 0x6b, 0x99, 0x22, 0x57, 0xfd, 0x38, 0xe5, 0x51, 0x7c, 0x5c, 0xcb,
- 0x77, 0x79, 0xff, 0x3b, 0x5c, 0xcb, 0xd6, 0xbd, 0xde, 0xd6, 0xe3, 0x8a,
- 0xb7, 0x7d, 0x8d, 0xe2, 0x53, 0xb7, 0x2a, 0xa5, 0xb8, 0x38, 0x5c, 0x8e,
- 0x4b, 0xf4, 0xbd, 0xd7, 0x86, 0x2b, 0x71, 0x79, 0xb8, 0x8a, 0x36, 0xa2,
- 0xb1, 0x0f, 0xd3, 0x2c, 0xd3, 0xdc, 0x98, 0x4a, 0x3f, 0x8f, 0x19, 0xb1,
- 0x5a, 0x7c, 0x9c, 0xde, 0x80, 0xf2, 0x98, 0xc4, 0x00, 0x1e, 0x7c, 0xc4,
- 0xfb, 0x1f, 0xa6, 0x47, 0x51, 0xbc, 0xe7, 0x73, 0xb6, 0x31, 0xcd, 0xfb,
- 0xb9, 0xbe, 0xcb, 0xe9, 0x0e, 0x94, 0xee, 0xd9, 0x08, 0xc7, 0x1e, 0xb3,
- 0x6b, 0x4b, 0x08, 0x3f, 0xb3, 0x73, 0x2d, 0xdd, 0xba, 0x77, 0xe2, 0x2e,
- 0x7b, 0x90, 0x7d, 0x8c, 0x2b, 0x0b, 0x32, 0x1b, 0x51, 0xbe, 0xc7, 0x83,
- 0x67, 0x29, 0xc3, 0x51, 0x68, 0x81, 0x35, 0xca, 0x46, 0x14, 0x8c, 0x64,
- 0xd7, 0xbf, 0x2e, 0x93, 0xb5, 0x8b, 0xfb, 0x1b, 0xa7, 0xc7, 0x32, 0x6e,
- 0x8b, 0x77, 0x4f, 0xa6, 0x4b, 0x70, 0x3a, 0x25, 0xf2, 0x81, 0xea, 0x08,
- 0x8f, 0xa2, 0x70, 0x0f, 0x31, 0x71, 0x58, 0xb7, 0xf8, 0x82, 0xd8, 0xc4,
- 0x70, 0xfa, 0x76, 0x36, 0x15, 0xc4, 0xce, 0x44, 0x0d, 0xed, 0xa9, 0x16,
- 0x2b, 0xf7, 0x48, 0x8d, 0x79, 0xe2, 0x5e, 0x17, 0xb5, 0xe8, 0x50, 0xfa,
- 0x56, 0x7b, 0x6a, 0xa4, 0x6e, 0x0a, 0xb6, 0x9a, 0x98, 0xd4, 0xb3, 0x78,
- 0x73, 0xcc, 0xaa, 0x61, 0x8b, 0x4d, 0xb6, 0x62, 0xcb, 0x00, 0xda, 0xf7,
- 0x37, 0x8a, 0x4d, 0x3a, 0x31, 0x44, 0xbe, 0x7f, 0x91, 0xb1, 0xc3, 0x0c,
- 0xed, 0x73, 0x62, 0x42, 0x01, 0x06, 0x87, 0x5d, 0xf8, 0xf1, 0xb0, 0x07,
- 0xee, 0x58, 0x31, 0xc6, 0x29, 0xe3, 0x31, 0x72, 0x9c, 0x8f, 0x18, 0x65,
- 0x8f, 0xd2, 0xa7, 0x7e, 0x18, 0xad, 0x42, 0x26, 0x5d, 0x8b, 0xab, 0xc4,
- 0x94, 0x34, 0xf7, 0xe3, 0x83, 0x68, 0x00, 0x2f, 0xa7, 0x83, 0x78, 0x3f,
- 0x2a, 0xd8, 0x13, 0xc4, 0x11, 0xca, 0xaf, 0x28, 0xe6, 0x66, 0xbf, 0x82,
- 0x43, 0x1e, 0x38, 0x63, 0x9a, 0x67, 0x28, 0xa7, 0x0b, 0x8e, 0x4c, 0x2b,
- 0xed, 0x46, 0xce, 0x44, 0x88, 0x1f, 0x70, 0xe8, 0x43, 0x8c, 0xb9, 0x07,
- 0x83, 0xf9, 0xfc, 0xaf, 0xd7, 0x3d, 0x81, 0x99, 0xb4, 0x9d, 0x2f, 0x4d,
- 0x55, 0x93, 0x98, 0x2a, 0x19, 0xba, 0x12, 0xd5, 0x24, 0x17, 0x48, 0x6c,
- 0x37, 0x14, 0xe7, 0x62, 0x72, 0x89, 0xaa, 0xad, 0x92, 0x17, 0xe6, 0xfc,
- 0xe5, 0x6c, 0x99, 0xc9, 0x76, 0x57, 0x31, 0xff, 0xc0, 0xd6, 0x59, 0xb9,
- 0x1c, 0x93, 0x7a, 0x83, 0xf7, 0xe5, 0x31, 0x5e, 0xe2, 0xb5, 0xdd, 0xa1,
- 0xd7, 0xa2, 0x7f, 0x3f, 0x4b, 0xea, 0x71, 0xc7, 0x11, 0xa4, 0x4c, 0x6e,
- 0x17, 0x0f, 0x98, 0x78, 0x93, 0x18, 0x72, 0x39, 0x29, 0xbc, 0x48, 0xf8,
- 0x50, 0x17, 0x7d, 0x4f, 0x19, 0xf9, 0x80, 0x86, 0x6d, 0xe4, 0xeb, 0xbe,
- 0xf8, 0x04, 0xe3, 0x91, 0xaf, 0x93, 0x93, 0x95, 0xb3, 0x9b, 0x1f, 0x70,
- 0xbc, 0x56, 0xec, 0xa4, 0x2d, 0x16, 0x69, 0x77, 0x61, 0x25, 0xf9, 0x8e,
- 0x43, 0xa3, 0xcb, 0x78, 0x58, 0xfc, 0x86, 0xe4, 0x70, 0x54, 0xa9, 0x95,
- 0xad, 0x7d, 0x1d, 0xf7, 0xa2, 0xbd, 0xda, 0x05, 0xa9, 0x6f, 0xbd, 0x81,
- 0x25, 0x48, 0x3d, 0x2a, 0xbe, 0x93, 0x1c, 0x39, 0xac, 0x19, 0xe7, 0x31,
- 0xcf, 0x62, 0xdd, 0xc5, 0x61, 0x99, 0x4f, 0x15, 0x65, 0xaf, 0xe2, 0x1d,
- 0xca, 0xf5, 0x52, 0xd4, 0x37, 0x75, 0x1f, 0x1a, 0x4e, 0x5d, 0xb2, 0x4b,
- 0xed, 0x4f, 0xda, 0x07, 0xa1, 0xb1, 0xbf, 0x4f, 0xa3, 0x21, 0xf4, 0xa9,
- 0x72, 0x2d, 0xfc, 0xb0, 0x15, 0xdd, 0x43, 0x32, 0x07, 0xd3, 0xac, 0x24,
- 0x1e, 0x3e, 0x6c, 0x8d, 0x2f, 0x63, 0xdf, 0x1a, 0x5b, 0x78, 0x19, 0x49,
- 0xe7, 0xe3, 0x8b, 0x49, 0x1c, 0x4e, 0x52, 0xfe, 0x8b, 0xdf, 0xa6, 0x1c,
- 0x26, 0x31, 0x9c, 0xd2, 0xc8, 0x1d, 0x4b, 0xe0, 0xa9, 0x0e, 0x62, 0x17,
- 0xfd, 0x75, 0x8c, 0xed, 0xd3, 0xb1, 0x12, 0x18, 0xd5, 0xd9, 0x31, 0xbf,
- 0x1e, 0xbf, 0x6a, 0x4e, 0x3c, 0x64, 0xc5, 0xa9, 0xbc, 0xfe, 0x1d, 0x9f,
- 0x99, 0x2d, 0xc7, 0x32, 0xb1, 0x3e, 0x76, 0xd9, 0x9c, 0x68, 0x9d, 0xfe,
- 0x7b, 0x85, 0x75, 0xa6, 0x2a, 0x62, 0xab, 0xe6, 0x77, 0x56, 0x2e, 0xdd,
- 0x94, 0xcb, 0x0c, 0xed, 0x2d, 0xf3, 0x41, 0x6b, 0x5e, 0xef, 0xcd, 0x12,
- 0x2e, 0x5f, 0x17, 0xf7, 0xcc, 0x46, 0x71, 0x15, 0xdb, 0x10, 0x43, 0xc3,
- 0x5a, 0xd3, 0x29, 0xfc, 0x8b, 0x79, 0xe1, 0xa6, 0x7e, 0x66, 0xf2, 0x9e,
- 0xf8, 0x9e, 0x0b, 0xb9, 0x9c, 0x8f, 0x3b, 0xc7, 0xf7, 0x27, 0x71, 0x3c,
- 0x29, 0xd8, 0xef, 0xc1, 0x13, 0x92, 0x9b, 0x52, 0xbd, 0xbd, 0x06, 0x26,
- 0xc8, 0xf1, 0xde, 0xa6, 0xec, 0x25, 0xff, 0x38, 0x41, 0x9e, 0x37, 0xdd,
- 0x37, 0x45, 0x90, 0xaa, 0x92, 0x1a, 0x8c, 0xe0, 0xe7, 0x24, 0xb6, 0x27,
- 0x7f, 0x4a, 0x1c, 0xfb, 0x98, 0xbc, 0xa7, 0x8b, 0x9c, 0x7a, 0x12, 0x5b,
- 0x52, 0xcd, 0x78, 0x69, 0x6f, 0x0b, 0x71, 0x45, 0xb0, 0xd1, 0x77, 0xea,
- 0xa2, 0xbd, 0x19, 0xfb, 0x0f, 0xa5, 0x91, 0x1a, 0x11, 0x7f, 0x28, 0x3e,
- 0x57, 0x7c, 0xa1, 0x86, 0x68, 0xe2, 0x24, 0x0c, 0x7e, 0xef, 0x4c, 0x6c,
- 0x44, 0x64, 0xe4, 0x2d, 0xf2, 0xf8, 0x49, 0x2c, 0xef, 0xd3, 0xd6, 0x1e,
- 0xc4, 0x24, 0x56, 0xd1, 0x57, 0x26, 0x13, 0x2d, 0xec, 0xbf, 0x19, 0x3d,
- 0x7b, 0xbd, 0x56, 0xbe, 0x49, 0x62, 0xf8, 0x6d, 0x63, 0x11, 0x18, 0x43,
- 0x72, 0x36, 0xc3, 0x85, 0x60, 0xdc, 0xa3, 0x7c, 0x48, 0x3e, 0xdc, 0x10,
- 0xf7, 0x32, 0x06, 0xf3, 0x1a, 0xab, 0x14, 0x9f, 0xa7, 0xc0, 0x26, 0xb5,
- 0xc0, 0x19, 0x38, 0xa5, 0x2b, 0x28, 0xba, 0x57, 0x41, 0x88, 0xbe, 0xca,
- 0x33, 0x8b, 0x3e, 0x64, 0x48, 0x47, 0xcf, 0x00, 0xd7, 0x7b, 0x7d, 0xdf,
- 0x64, 0xbf, 0x56, 0xb3, 0x3f, 0xd9, 0xbb, 0x16, 0xf4, 0x8c, 0xf9, 0x3a,
- 0x4e, 0xc1, 0x6d, 0x71, 0xab, 0x9e, 0x81, 0xeb, 0x79, 0x81, 0xd2, 0x8f,
- 0x1b, 0xbd, 0x81, 0x19, 0x8a, 0xb4, 0xdd, 0x4a, 0xcc, 0x9a, 0xde, 0xde,
- 0x50, 0x92, 0x8b, 0xc9, 0x3f, 0x6d, 0x62, 0x17, 0xdd, 0x96, 0xbd, 0x88,
- 0x2c, 0x7a, 0x92, 0x11, 0xea, 0xf4, 0x4f, 0xcc, 0x54, 0x6b, 0x2b, 0xe7,
- 0xd9, 0x28, 0xb5, 0x31, 0x0b, 0x13, 0xce, 0x4a, 0x2e, 0xce, 0x29, 0x98,
- 0xd0, 0xdd, 0xee, 0xa2, 0x3e, 0x15, 0x12, 0x97, 0x8a, 0x46, 0x5d, 0x70,
- 0x1d, 0x2c, 0x41, 0xe1, 0xa0, 0xf0, 0x31, 0xc9, 0x41, 0xa8, 0xb0, 0x8f,
- 0x96, 0xd2, 0x06, 0xb8, 0x87, 0xa3, 0xb4, 0xb1, 0xa8, 0x1b, 0xf3, 0x46,
- 0xdd, 0xf8, 0x31, 0x31, 0xa0, 0x66, 0x54, 0xc3, 0x38, 0x31, 0xc0, 0x3d,
- 0x1a, 0xc0, 0x58, 0x34, 0x88, 0x19, 0xa3, 0xe3, 0xca, 0x1b, 0xe9, 0x66,
- 0xee, 0xb7, 0x8c, 0x23, 0x32, 0xcc, 0xef, 0xa9, 0xec, 0x67, 0x0b, 0xb1,
- 0x4e, 0xf6, 0x36, 0x80, 0x1d, 0x03, 0x69, 0x2c, 0xdb, 0x63, 0xe2, 0x9f,
- 0xf4, 0x06, 0x77, 0x91, 0x22, 0xb1, 0x80, 0x89, 0x34, 0xfd, 0xda, 0x0a,
- 0xdd, 0xbb, 0x56, 0xce, 0x3b, 0xb7, 0x57, 0x99, 0x28, 0x08, 0x79, 0x75,
- 0xa2, 0xfb, 0xda, 0x22, 0x45, 0x7c, 0x54, 0x83, 0x67, 0x03, 0xe6, 0x22,
- 0x5b, 0x57, 0xbc, 0x0f, 0x1b, 0x54, 0x85, 0xb6, 0xd8, 0x82, 0x9d, 0x15,
- 0x86, 0xeb, 0x4a, 0xa3, 0x69, 0xae, 0x0b, 0xd5, 0xcd, 0xb2, 0x72, 0xd0,
- 0xb6, 0xf5, 0xfc, 0x6e, 0xe3, 0x9a, 0x65, 0xdd, 0x1d, 0x88, 0xed, 0x56,
- 0x90, 0xf6, 0x77, 0x20, 0x3a, 0xdc, 0x21, 0xfc, 0x89, 0x78, 0xd0, 0x4b,
- 0x3c, 0x30, 0xbb, 0x9e, 0x0e, 0x3d, 0x88, 0xcb, 0x96, 0xc7, 0x97, 0x67,
- 0xbc, 0x01, 0x8f, 0x6d, 0xfa, 0x1e, 0xe8, 0xb3, 0x25, 0xcf, 0x21, 0x76,
- 0xd3, 0xdc, 0x27, 0xbc, 0xd9, 0xdf, 0xdb, 0xc3, 0xbd, 0x7f, 0xe8, 0x80,
- 0xf8, 0x17, 0xd3, 0xec, 0x25, 0x2f, 0x45, 0x85, 0xac, 0x41, 0x43, 0x3c,
- 0x61, 0x7e, 0x5c, 0xa3, 0xf9, 0xa6, 0x76, 0xd1, 0x8f, 0x9f, 0xdf, 0xd3,
- 0xb0, 0x61, 0x83, 0x70, 0x96, 0x45, 0x1a, 0x63, 0xe9, 0x34, 0xce, 0x8d,
- 0xcc, 0x47, 0xea, 0x21, 0xae, 0x87, 0xfb, 0xe4, 0x8c, 0x7f, 0xc1, 0x38,
- 0x43, 0xb0, 0x4f, 0x53, 0x0f, 0x13, 0xf7, 0x6c, 0xa3, 0x7e, 0x6c, 0xa9,
- 0x80, 0x71, 0xa5, 0x51, 0xc6, 0xbf, 0x3e, 0x7f, 0xae, 0xb7, 0x19, 0xbb,
- 0xf6, 0x0a, 0xaf, 0x10, 0xfe, 0xe5, 0x33, 0x3e, 0x40, 0x0b, 0x92, 0x63,
- 0xd9, 0xb1, 0xa2, 0x89, 0x5b, 0xf5, 0x44, 0xf6, 0xfc, 0x24, 0x76, 0x50,
- 0x27, 0x5d, 0xec, 0x9f, 0x3e, 0x85, 0xfd, 0x69, 0x81, 0x22, 0x19, 0x6f,
- 0xf4, 0x27, 0xe6, 0xce, 0x6a, 0x91, 0x8d, 0xf4, 0xff, 0x9b, 0x6a, 0xc1,
- 0x8b, 0x75, 0xa1, 0xaf, 0x5a, 0xeb, 0x15, 0x7e, 0x4b, 0xce, 0x3a, 0x3f,
- 0x1f, 0x79, 0xe6, 0x76, 0xf3, 0xf9, 0x9c, 0xed, 0x64, 0x4e, 0x1d, 0xd8,
- 0xb1, 0x1b, 0x46, 0xb1, 0xa6, 0x45, 0xe6, 0x2b, 0x1d, 0xe8, 0xa5, 0x7c,
- 0xb7, 0x25, 0x3b, 0xb0, 0x9f, 0xf6, 0x3a, 0xa8, 0x1f, 0xab, 0xb1, 0xa1,
- 0x7e, 0xca, 0x8e, 0x89, 0x7f, 0x94, 0x9a, 0xc5, 0x82, 0x45, 0x7e, 0xda,
- 0x56, 0x07, 0xe2, 0xa9, 0x73, 0xb3, 0xad, 0x9a, 0xa8, 0x4d, 0x7c, 0x9e,
- 0xc8, 0xa2, 0x13, 0xc5, 0x7d, 0x27, 0xe1, 0xec, 0xeb, 0x44, 0x91, 0x7f,
- 0x09, 0x56, 0x84, 0x2e, 0x98, 0x97, 0x35, 0x87, 0xfb, 0x38, 0xe5, 0x73,
- 0x2c, 0x58, 0xc3, 0x98, 0x91, 0x71, 0xca, 0xd0, 0x1c, 0xda, 0x7d, 0x23,
- 0x76, 0x8c, 0xc9, 0x59, 0x08, 0x1b, 0x56, 0x2d, 0x96, 0x58, 0x5c, 0xa1,
- 0x5e, 0xcf, 0x62, 0x3c, 0xa9, 0xa9, 0xcf, 0x59, 0xe7, 0x56, 0xc8, 0xb9,
- 0xaa, 0x3c, 0x78, 0xd2, 0x3a, 0xaf, 0x21, 0xf7, 0x37, 0x31, 0x0e, 0xd8,
- 0x84, 0x9a, 0x98, 0x61, 0x8a, 0xbc, 0x8f, 0x23, 0xf2, 0xa2, 0x8d, 0xf3,
- 0x68, 0x5a, 0xe4, 0xdf, 0x30, 0xa5, 0x88, 0x3e, 0xfb, 0xdb, 0x47, 0x15,
- 0xdd, 0xb5, 0x3a, 0xa3, 0x20, 0xd0, 0xc7, 0xbe, 0x42, 0x23, 0xb3, 0xb3,
- 0xb9, 0xf1, 0x3c, 0xbf, 0xdb, 0x44, 0x5e, 0xb0, 0x09, 0x65, 0x31, 0xe1,
- 0xe4, 0x82, 0x0b, 0x91, 0xa5, 0xe5, 0x7c, 0x3e, 0x1d, 0xf2, 0xb7, 0x96,
- 0x2a, 0xc2, 0x7d, 0xfc, 0x4d, 0xab, 0x14, 0xe1, 0x2a, 0xf2, 0x9c, 0xee,
- 0xaa, 0xcf, 0x9c, 0xcf, 0xd5, 0x31, 0x1b, 0x89, 0x0d, 0x72, 0xce, 0x24,
- 0x7f, 0xd6, 0xea, 0x46, 0xce, 0xda, 0x19, 0x97, 0xd8, 0xe1, 0x68, 0x68,
- 0x59, 0xb4, 0x89, 0x38, 0x67, 0x2e, 0x39, 0x44, 0xbd, 0xbf, 0x88, 0x2a,
- 0xfc, 0x73, 0x54, 0x30, 0xcd, 0x83, 0x9f, 0x47, 0x0b, 0x25, 0x26, 0x4e,
- 0x49, 0x5e, 0xf6, 0x4c, 0xd2, 0x30, 0x29, 0xd7, 0x96, 0x55, 0xd4, 0xa5,
- 0x40, 0xa8, 0x14, 0xa8, 0xee, 0x7e, 0xd2, 0x69, 0xc5, 0xe8, 0x65, 0xa8,
- 0x20, 0xfe, 0xf7, 0x0d, 0xfd, 0xa1, 0xf3, 0x0e, 0xc4, 0xe0, 0x62, 0xc9,
- 0x15, 0xda, 0xb1, 0x2d, 0xf4, 0x1b, 0x33, 0xd5, 0x26, 0xcf, 0xd4, 0xe2,
- 0xdc, 0x6e, 0xd1, 0xd3, 0x00, 0x0a, 0xe3, 0xe7, 0xa9, 0x93, 0x2a, 0xce,
- 0x46, 0x7d, 0xfa, 0x1a, 0xdb, 0xb7, 0xa8, 0xff, 0xf3, 0x6e, 0xc2, 0xed,
- 0x79, 0xda, 0x03, 0x78, 0xdc, 0xc2, 0xed, 0x30, 0xb6, 0xd0, 0x2f, 0x90,
- 0xb7, 0xed, 0x7b, 0xd2, 0xa6, 0xd2, 0x9f, 0xfb, 0x54, 0x1f, 0x63, 0xea,
- 0x2d, 0x1c, 0x43, 0xf8, 0xe4, 0x4c, 0xf2, 0xbd, 0xa7, 0xa3, 0x0d, 0x9e,
- 0x5f, 0xe3, 0x09, 0xda, 0xa3, 0x8c, 0x21, 0x6b, 0xd2, 0x50, 0xca, 0xd8,
- 0xf1, 0x04, 0xd7, 0xb1, 0xad, 0x22, 0x3b, 0x6e, 0x79, 0xae, 0xef, 0xf8,
- 0x90, 0xf0, 0xad, 0x7b, 0xb0, 0xc6, 0xea, 0x3b, 0x68, 0xd9, 0xe6, 0xbe,
- 0xa8, 0x82, 0x19, 0xf5, 0x1a, 0x12, 0xe9, 0x66, 0x6c, 0xac, 0xac, 0xc5,
- 0xfe, 0xc4, 0x26, 0x2c, 0x24, 0xe7, 0x7d, 0xa4, 0xd2, 0xa0, 0x5f, 0x24,
- 0x06, 0xc5, 0x35, 0x75, 0xbe, 0xf2, 0x8d, 0x5c, 0xae, 0xba, 0x0a, 0x8e,
- 0xb8, 0xf8, 0xbb, 0x02, 0xf4, 0xab, 0x73, 0x51, 0x62, 0x9d, 0x81, 0xcc,
- 0xf6, 0xbd, 0x6b, 0xc8, 0x9b, 0xf3, 0x81, 0x44, 0x8d, 0xb8, 0x75, 0x4e,
- 0x25, 0xf0, 0x3c, 0x79, 0x44, 0x8a, 0xde, 0xaf, 0x20, 0xac, 0xa5, 0xd6,
- 0xa3, 0x08, 0xc6, 0x2c, 0xc1, 0x43, 0x79, 0x66, 0xce, 0x2d, 0x73, 0xaa,
- 0xcc, 0xcd, 0x29, 0x7f, 0xff, 0x34, 0xef, 0x89, 0x6e, 0x09, 0xb7, 0x90,
- 0xdf, 0x8b, 0xd1, 0x4a, 0x7d, 0xaa, 0xe2, 0x9c, 0x13, 0x09, 0xb9, 0xef,
- 0xd5, 0x0d, 0x5b, 0x23, 0x3e, 0xdb, 0x93, 0xd5, 0xc1, 0xb5, 0x75, 0xdc,
- 0xff, 0xf2, 0x46, 0x4c, 0x8d, 0x88, 0x2f, 0xfb, 0xc3, 0x67, 0x50, 0x8c,
- 0xeb, 0x67, 0x50, 0x44, 0xae, 0xde, 0x53, 0xef, 0xa0, 0x61, 0xe2, 0x31,
- 0xdb, 0x61, 0x13, 0x33, 0x45, 0xc6, 0x71, 0xb7, 0xc4, 0x9a, 0x36, 0x72,
- 0x08, 0x23, 0x3d, 0xee, 0x16, 0x3f, 0xe9, 0x88, 0x03, 0xf3, 0xe2, 0x06,
- 0x0a, 0xc3, 0xda, 0xbe, 0x2b, 0xf6, 0x6b, 0x66, 0xfb, 0xac, 0x39, 0x8c,
- 0xf9, 0x6e, 0xac, 0xb9, 0x97, 0x73, 0xb7, 0x6b, 0x3f, 0x31, 0xef, 0xab,
- 0x92, 0x39, 0xfe, 0xd2, 0x9d, 0x3d, 0xfb, 0x70, 0x07, 0xe5, 0x92, 0x97,
- 0x89, 0x49, 0xfd, 0xf9, 0x2b, 0xf3, 0x9b, 0x37, 0xdd, 0x17, 0x2e, 0x23,
- 0x7a, 0x3a, 0xfd, 0x3c, 0xa0, 0xe8, 0xac, 0xd4, 0x56, 0x26, 0x71, 0x28,
- 0x29, 0xba, 0x2b, 0x32, 0x8e, 0xe0, 0x22, 0x79, 0x61, 0x41, 0xff, 0x24,
- 0x06, 0xc9, 0x0b, 0xed, 0x71, 0xef, 0x3e, 0x4a, 0x12, 0x1b, 0xd5, 0x25,
- 0xc4, 0xea, 0x32, 0xce, 0x23, 0x3f, 0x87, 0x3a, 0x4b, 0xee, 0xe2, 0x5f,
- 0x76, 0x72, 0xbd, 0x45, 0xe4, 0x48, 0xcd, 0xb1, 0x42, 0x68, 0x15, 0xe5,
- 0x28, 0xd5, 0xe4, 0x0c, 0x7c, 0xb6, 0x5d, 0x94, 0x73, 0x29, 0xd1, 0xe6,
- 0x62, 0x95, 0xd5, 0xd6, 0x63, 0x9d, 0x01, 0xd1, 0x2a, 0xc5, 0xff, 0x8a,
- 0xcf, 0x25, 0xdf, 0x5e, 0x2c, 0x3e, 0x37, 0xcc, 0xb9, 0xcd, 0xc9, 0xd5,
- 0x99, 0x56, 0x59, 0xf7, 0xf7, 0x25, 0x2e, 0x7c, 0xd9, 0x9f, 0xf8, 0x3d,
- 0x9f, 0xe9, 0x80, 0xba, 0xb7, 0x18, 0x0f, 0xfd, 0x65, 0x09, 0xf4, 0xca,
- 0x6c, 0xae, 0x7c, 0x5e, 0x38, 0x1a, 0x32, 0x13, 0xc2, 0x93, 0xee, 0x84,
- 0x67, 0xb6, 0x8c, 0x25, 0x18, 0x20, 0x7b, 0x21, 0x7b, 0x27, 0x39, 0xdc,
- 0xdb, 0xd5, 0x18, 0xbc, 0xea, 0xc4, 0xf5, 0x7d, 0x98, 0x0f, 0xed, 0xe1,
- 0x2a, 0xae, 0x2d, 0xeb, 0x23, 0x76, 0xd0, 0x47, 0x04, 0xfc, 0x59, 0x0c,
- 0x93, 0x1a, 0xbd, 0x93, 0x3e, 0x62, 0x84, 0x3e, 0xe2, 0xa2, 0x5e, 0x8e,
- 0xe5, 0x39, 0x1f, 0xd1, 0x6e, 0xd3, 0xad, 0xfe, 0x9d, 0xda, 0x7d, 0x35,
- 0xc4, 0x30, 0x8e, 0xf1, 0xb5, 0x9b, 0xb8, 0xd8, 0x4c, 0xed, 0x97, 0xe6,
- 0x23, 0x55, 0xb2, 0xc6, 0xe6, 0x9a, 0x6c, 0x8e, 0xbc, 0x03, 0xfb, 0x88,
- 0x8f, 0x35, 0x9a, 0x3c, 0xa3, 0x25, 0x6b, 0xec, 0x1d, 0xe8, 0x67, 0xff,
- 0x7d, 0xc4, 0xc8, 0x18, 0x31, 0x52, 0x5f, 0x78, 0xec, 0x45, 0x15, 0xf5,
- 0x1d, 0x64, 0x0f, 0xdf, 0x16, 0x6c, 0x79, 0x99, 0xd8, 0xf2, 0x3c, 0x31,
- 0x72, 0x67, 0x4a, 0xc6, 0x91, 0xf1, 0xf2, 0xe3, 0x48, 0x9f, 0xff, 0x66,
- 0xae, 0xaf, 0x92, 0xb9, 0xde, 0x6e, 0x1e, 0xf2, 0xdb, 0x9f, 0xf2, 0xef,
- 0x62, 0x8b, 0x43, 0xf5, 0x26, 0xa6, 0x9f, 0xa9, 0x98, 0x24, 0xbe, 0x5a,
- 0x71, 0x00, 0xfd, 0x6b, 0x04, 0x2b, 0x17, 0xab, 0xb8, 0x1c, 0x9d, 0x44,
- 0xd1, 0x81, 0x3c, 0x16, 0x99, 0x4b, 0x4e, 0x10, 0x87, 0x06, 0x21, 0xd8,
- 0xd3, 0xc4, 0x3d, 0x30, 0x68, 0x13, 0x65, 0x18, 0x4d, 0xca, 0xd9, 0x0b,
- 0x13, 0xbb, 0x42, 0x2e, 0x72, 0xd8, 0xee, 0xe3, 0x05, 0x96, 0x4f, 0x28,
- 0x23, 0x5e, 0xe7, 0xf9, 0xb5, 0x70, 0x6b, 0xc1, 0x1a, 0xc6, 0x11, 0x43,
- 0x76, 0x14, 0x2c, 0xca, 0xc6, 0x0e, 0xe7, 0xda, 0xa4, 0x5d, 0x2d, 0x06,
- 0x77, 0x8b, 0xae, 0xf9, 0x50, 0xa3, 0x9d, 0x67, 0x2c, 0x01, 0xbc, 0x1b,
- 0xb5, 0xdd, 0xe9, 0x22, 0x07, 0xee, 0xd2, 0x17, 0xe3, 0xda, 0xcc, 0x2d,
- 0xb4, 0x6f, 0x37, 0x7f, 0x9b, 0xc0, 0xc1, 0xa8, 0x0b, 0x05, 0x56, 0x8d,
- 0xb2, 0x9c, 0xeb, 0xc9, 0xea, 0xcb, 0x36, 0xea, 0x4b, 0x21, 0x63, 0xb3,
- 0x15, 0x96, 0x5d, 0x4a, 0x3f, 0x93, 0xd6, 0xbb, 0x32, 0xda, 0x62, 0xe1,
- 0xad, 0x41, 0xfa, 0xc0, 0x32, 0xc4, 0xfb, 0xba, 0x70, 0x36, 0x54, 0x86,
- 0xd8, 0x01, 0xb1, 0xa7, 0x5a, 0xc1, 0x4d, 0x8e, 0xdb, 0x44, 0xf9, 0xa8,
- 0xc4, 0x95, 0x86, 0x4e, 0xbb, 0xbd, 0x0c, 0x17, 0x2a, 0x18, 0xaf, 0x5a,
- 0xef, 0x13, 0xb5, 0x62, 0x7f, 0x6e, 0x8f, 0x54, 0xf2, 0x9b, 0xd6, 0xeb,
- 0x7c, 0x39, 0xbf, 0x96, 0xbc, 0x7d, 0x66, 0x6b, 0xe4, 0x3d, 0xe4, 0x30,
- 0x2f, 0x49, 0x3e, 0xc8, 0xe6, 0xa3, 0xdf, 0x60, 0x5c, 0x34, 0x26, 0xb2,
- 0xce, 0xeb, 0xd6, 0xeb, 0x35, 0xd9, 0x33, 0x3d, 0xf9, 0x3d, 0xc8, 0x5f,
- 0x6b, 0x6b, 0x8b, 0x95, 0x5f, 0x98, 0xcf, 0x56, 0xcb, 0xfc, 0xae, 0x32,
- 0x0e, 0xfb, 0x31, 0x7f, 0x5f, 0x86, 0x9e, 0xa1, 0xe9, 0x7e, 0x41, 0x6c,
- 0xce, 0x73, 0xd3, 0xd9, 0xc3, 0x8a, 0xb8, 0xbc, 0xbf, 0x75, 0x34, 0xf4,
- 0x24, 0xf7, 0xc1, 0xbf, 0xb0, 0xc1, 0xca, 0xa5, 0x90, 0xe3, 0x32, 0xfe,
- 0x10, 0x3c, 0x35, 0xe8, 0xcf, 0xcb, 0xf0, 0xb3, 0xa4, 0xf8, 0x57, 0x13,
- 0x85, 0xa1, 0x12, 0xfa, 0xbb, 0xee, 0xe7, 0x2a, 0x2c, 0xce, 0x5c, 0x86,
- 0x4a, 0xea, 0x5e, 0xff, 0xd0, 0xed, 0xf4, 0xfc, 0x86, 0x0f, 0x48, 0x87,
- 0x14, 0x62, 0xc2, 0x6f, 0xcc, 0x5d, 0x8f, 0x66, 0x9f, 0x39, 0x97, 0x74,
- 0xe1, 0xa3, 0x50, 0x3b, 0x26, 0x2a, 0xc2, 0x18, 0x48, 0x14, 0xa1, 0x7d,
- 0x56, 0xbd, 0xf5, 0xce, 0x45, 0x4d, 0xdc, 0x83, 0xf3, 0x51, 0x27, 0x9a,
- 0x66, 0x7b, 0xac, 0x7c, 0x92, 0x8d, 0x76, 0xf1, 0x76, 0x34, 0x42, 0x5f,
- 0xe0, 0xb9, 0xc9, 0x3f, 0x14, 0x68, 0x8b, 0x70, 0x7f, 0x0e, 0xc3, 0xf7,
- 0x27, 0x3e, 0x27, 0xc6, 0x94, 0x1b, 0x33, 0xc3, 0x65, 0xb8, 0x7b, 0x40,
- 0xce, 0x29, 0x48, 0x9d, 0x4a, 0x9b, 0x9a, 0xaf, 0x94, 0x61, 0xc9, 0x90,
- 0xe0, 0xb9, 0x9c, 0xfd, 0x48, 0x87, 0x5c, 0xb1, 0x36, 0xee, 0x51, 0x27,
- 0xea, 0xf7, 0x5a, 0x72, 0x55, 0xed, 0x8a, 0xd9, 0x75, 0x49, 0x8f, 0xe8,
- 0xf4, 0x67, 0x9d, 0xf7, 0x53, 0xef, 0xa7, 0x42, 0xde, 0xf6, 0x99, 0x76,
- 0xad, 0xe3, 0x57, 0x4a, 0x10, 0xa3, 0x19, 0xa0, 0x6f, 0x24, 0x80, 0x0f,
- 0x12, 0xc2, 0xed, 0x03, 0x78, 0x7f, 0x2c, 0x88, 0x77, 0xe8, 0x87, 0x8a,
- 0xe2, 0xde, 0xc8, 0x33, 0x8c, 0xdd, 0xde, 0xe5, 0x75, 0x61, 0x5c, 0xc7,
- 0x15, 0xca, 0xcf, 0x19, 0x6f, 0xc4, 0xa5, 0xb1, 0x6f, 0xe0, 0xf2, 0x5e,
- 0x05, 0xc7, 0xb4, 0x6f, 0xe0, 0xe2, 0xa1, 0x4e, 0x2c, 0xda, 0x2b, 0x67,
- 0xf5, 0x8e, 0x86, 0x54, 0xfa, 0x81, 0x27, 0xeb, 0xcc, 0xae, 0x17, 0xf4,
- 0x7a, 0x62, 0x86, 0x57, 0x6f, 0x67, 0x6c, 0x24, 0xf8, 0x1d, 0xb1, 0xc9,
- 0x9e, 0xc9, 0xde, 0x75, 0xe2, 0xb2, 0x85, 0xd9, 0xb7, 0xc7, 0x89, 0x1b,
- 0x78, 0x2d, 0xe3, 0x88, 0x6d, 0xdf, 0x81, 0x57, 0x19, 0x94, 0x6e, 0x61,
- 0x3b, 0x17, 0x71, 0xee, 0xe9, 0x68, 0x11, 0x0a, 0xab, 0xcb, 0x2d, 0x7b,
- 0x2b, 0x8e, 0x07, 0x70, 0x9a, 0xb2, 0x5b, 0x59, 0xed, 0xe5, 0xb5, 0xf8,
- 0xd8, 0x20, 0xe3, 0x93, 0x99, 0xf8, 0xe0, 0x26, 0xdf, 0xfa, 0xaa, 0x85,
- 0x0d, 0x0e, 0xed, 0x81, 0x39, 0x59, 0x6c, 0x20, 0xa0, 0x13, 0x93, 0x25,
- 0x27, 0x58, 0xae, 0x69, 0x1b, 0xbe, 0x4b, 0x1b, 0x4f, 0x87, 0x8e, 0xfd,
- 0x49, 0x29, 0x39, 0xf0, 0x0b, 0xa1, 0x7a, 0xa3, 0x02, 0x2b, 0x78, 0x7f,
- 0x62, 0x91, 0x8a, 0x75, 0xfc, 0xf6, 0xb3, 0x5d, 0x90, 0xf3, 0xb8, 0x6a,
- 0xa6, 0x54, 0x1f, 0xff, 0xae, 0xa5, 0x2f, 0xdf, 0x84, 0xb3, 0xb1, 0x86,
- 0xf6, 0x11, 0xe5, 0x8a, 0x69, 0x54, 0xd7, 0xf1, 0xb7, 0x2a, 0x9c, 0x8b,
- 0x7a, 0x27, 0x0e, 0xa1, 0xc1, 0x33, 0xa5, 0xec, 0x37, 0x0d, 0x55, 0xf6,
- 0x47, 0xd6, 0x2b, 0xcf, 0xdf, 0xc5, 0xfb, 0x17, 0xa6, 0xe9, 0xe1, 0x8d,
- 0xf8, 0xca, 0x79, 0x5d, 0xff, 0x84, 0x83, 0x98, 0x4b, 0x86, 0xf5, 0x06,
- 0x75, 0x0b, 0xb1, 0x20, 0xa2, 0xde, 0x4e, 0xff, 0x8a, 0xa8, 0x7f, 0x61,
- 0xc6, 0x8b, 0x65, 0x50, 0x2d, 0x5f, 0xd4, 0x8a, 0xe4, 0xd0, 0x74, 0x1e,
- 0x29, 0x7a, 0x97, 0xe5, 0xa4, 0xed, 0x15, 0xdd, 0xc7, 0x9d, 0xf4, 0x87,
- 0x09, 0x62, 0x78, 0x9c, 0x18, 0x5e, 0x48, 0x0c, 0xbf, 0xba, 0xa7, 0x18,
- 0x67, 0xf7, 0x34, 0x21, 0x5d, 0x21, 0xcf, 0xd8, 0xe1, 0xe4, 0xea, 0x52,
- 0x96, 0x6f, 0xb7, 0xa1, 0xa6, 0x7f, 0xa9, 0x9c, 0x75, 0x85, 0xf8, 0xd0,
- 0x82, 0x38, 0x11, 0xb1, 0xd5, 0x0e, 0x87, 0xf5, 0x7e, 0xc1, 0x8c, 0x9b,
- 0xf4, 0xcf, 0xa5, 0x15, 0xa2, 0xa5, 0x4a, 0xf0, 0xe1, 0xe2, 0x1c, 0xf1,
- 0x99, 0x3f, 0xe5, 0x5c, 0x8e, 0x53, 0xa7, 0x9f, 0xd2, 0xef, 0x91, 0x1a,
- 0x1d, 0xdb, 0xcb, 0x73, 0x12, 0xc3, 0x98, 0xd8, 0x41, 0x0d, 0xab, 0xaf,
- 0x36, 0x91, 0xd0, 0xc3, 0xf4, 0x4f, 0x21, 0x44, 0x2a, 0x82, 0xf4, 0x4b,
- 0x72, 0xad, 0xe2, 0x12, 0xe3, 0xaf, 0x4c, 0x50, 0xc1, 0x47, 0x5f, 0x13,
- 0xbf, 0xef, 0xd7, 0xcf, 0x2a, 0xa7, 0x67, 0x65, 0xdf, 0x6b, 0x10, 0x8c,
- 0x28, 0xb7, 0x30, 0xa2, 0xd0, 0xe2, 0x40, 0xb3, 0x2d, 0x6c, 0xf1, 0xd8,
- 0xe4, 0x4c, 0x51, 0x34, 0x74, 0x6f, 0xa2, 0x61, 0xc2, 0x67, 0x27, 0x1f,
- 0xfb, 0xe3, 0xaf, 0x91, 0x87, 0x59, 0x7c, 0x60, 0xba, 0xdf, 0x69, 0x02,
- 0xa6, 0xcb, 0x23, 0x7f, 0x76, 0xd9, 0x93, 0xc5, 0xca, 0x72, 0xe1, 0x6d,
- 0xff, 0xcf, 0x6c, 0xbd, 0x69, 0xfe, 0x79, 0x1c, 0xf9, 0x25, 0xaf, 0xe5,
- 0x79, 0xb1, 0x3b, 0xea, 0x45, 0xfc, 0x1f, 0xcd, 0xc7, 0x2d, 0xee, 0x76,
- 0x6c, 0x8e, 0x9c, 0xcb, 0x74, 0xf4, 0xff, 0xfd, 0x1c, 0x79, 0x9f, 0xc1,
- 0x36, 0x8d, 0x03, 0x64, 0xfd, 0xea, 0x3b, 0xe6, 0x2a, 0x6b, 0xae, 0xa7,
- 0x73, 0xed, 0x24, 0x56, 0x96, 0xb9, 0x28, 0xf8, 0x81, 0xd6, 0xa0, 0x9e,
- 0x46, 0xa9, 0xe0, 0x49, 0x44, 0xea, 0x91, 0xc5, 0x9a, 0xcf, 0x7d, 0x90,
- 0xdf, 0xbb, 0x78, 0xff, 0x35, 0xcd, 0xd1, 0xf4, 0x2c, 0xa4, 0x06, 0x6b,
- 0xe3, 0x5e, 0x35, 0xb8, 0x4f, 0xc3, 0x1f, 0x29, 0x54, 0xa6, 0xcc, 0xf6,
- 0x2a, 0x69, 0x93, 0xad, 0xc5, 0x42, 0x39, 0x6f, 0xe5, 0x49, 0xb2, 0x3a,
- 0x53, 0x4b, 0x9d, 0x11, 0xec, 0x12, 0xde, 0xb1, 0x80, 0x6b, 0x57, 0x31,
- 0x34, 0x26, 0x1c, 0xc1, 0x65, 0xf1, 0x20, 0xb5, 0xae, 0xce, 0xb3, 0x1e,
- 0xca, 0x5c, 0x62, 0x2c, 0xb6, 0xea, 0xb8, 0xd3, 0x86, 0xb7, 0xee, 0xb4,
- 0x85, 0x97, 0xfe, 0xd9, 0xfd, 0x8d, 0x77, 0xcf, 0x95, 0x77, 0x5f, 0xc8,
- 0xe6, 0x24, 0x2f, 0xeb, 0x96, 0xba, 0xe1, 0x72, 0xf2, 0xaa, 0x41, 0xc6,
- 0xf2, 0xcb, 0x83, 0xbf, 0x33, 0xbf, 0xed, 0x88, 0x78, 0xec, 0xa8, 0xf3,
- 0xf4, 0xe0, 0x9a, 0x99, 0xaa, 0xb2, 0xee, 0xcf, 0x95, 0xf7, 0x0d, 0x9c,
- 0xd2, 0x3f, 0xb9, 0xc8, 0xdd, 0x75, 0x26, 0xe3, 0x64, 0xdb, 0x32, 0x3b,
- 0xed, 0x82, 0x32, 0x33, 0xeb, 0x67, 0xd5, 0xb9, 0x6d, 0x4a, 0x3d, 0xb5,
- 0xa3, 0x0a, 0x47, 0xa8, 0xbf, 0x47, 0xc6, 0xc4, 0xff, 0xa9, 0x38, 0x4c,
- 0x3b, 0x3d, 0x54, 0xef, 0xeb, 0xbc, 0xcc, 0xb8, 0xf1, 0x43, 0xf2, 0xf9,
- 0x37, 0x34, 0x6f, 0xfb, 0x29, 0xc9, 0x29, 0x86, 0x1c, 0x38, 0x13, 0xbc,
- 0x66, 0xe5, 0x78, 0x63, 0x07, 0x54, 0x0c, 0x26, 0xb2, 0xf6, 0xfe, 0x0a,
- 0xed, 0xf8, 0xc6, 0x99, 0x03, 0x1d, 0x5b, 0x06, 0xc4, 0x3e, 0x1a, 0x2d,
- 0x3b, 0xba, 0x91, 0x13, 0x12, 0xbc, 0x16, 0xbb, 0x78, 0x42, 0x6a, 0x71,
- 0x46, 0x0a, 0x0e, 0xca, 0x77, 0x39, 0xf9, 0xae, 0xf8, 0xd8, 0x00, 0x63,
- 0x5b, 0x07, 0xed, 0xe7, 0x14, 0xe3, 0x0c, 0xce, 0x2d, 0x6c, 0x9a, 0xef,
- 0x30, 0xee, 0x1a, 0x42, 0x83, 0x7a, 0x02, 0x6b, 0xc8, 0x59, 0xc9, 0x67,
- 0xc6, 0x9a, 0xb1, 0xd3, 0x8a, 0x9b, 0x7c, 0xea, 0x0a, 0x65, 0x21, 0xd7,
- 0xdf, 0x8c, 0xee, 0x43, 0xb5, 0xe4, 0x35, 0xa6, 0xb9, 0x5a, 0xff, 0x73,
- 0x54, 0x0e, 0x74, 0x77, 0x56, 0x52, 0x1e, 0x9f, 0x86, 0x8c, 0x0e, 0x62,
- 0xfa, 0x86, 0x13, 0x4a, 0xc3, 0xda, 0x98, 0xf2, 0x6d, 0xee, 0x87, 0xe4,
- 0x41, 0x3c, 0x8c, 0xc7, 0x57, 0xd3, 0x9f, 0xfd, 0x0f, 0xec, 0x50, 0x95,
- 0x25, 0xb6, 0xb0, 0xf0, 0x41, 0xf8, 0xd5, 0xb0, 0x76, 0xea, 0xa2, 0x7d,
- 0x33, 0xbd, 0x4f, 0x23, 0xef, 0x89, 0x5f, 0x97, 0xb6, 0x72, 0xb6, 0xbe,
- 0x13, 0xc7, 0xd3, 0xd4, 0xeb, 0x68, 0x2f, 0x4e, 0xa4, 0x65, 0x4c, 0xe1,
- 0x53, 0x01, 0xc4, 0x06, 0xec, 0x18, 0xd5, 0x7d, 0x91, 0x72, 0xca, 0xa5,
- 0x38, 0xe4, 0x8d, 0xac, 0x51, 0x02, 0xe4, 0x6d, 0x69, 0x9c, 0xd9, 0xed,
- 0x6d, 0xaf, 0x67, 0x8c, 0x18, 0x1d, 0x83, 0xfa, 0xcc, 0xe2, 0x34, 0x4e,
- 0x0f, 0x3f, 0x04, 0xcf, 0x2c, 0xaf, 0x67, 0xb9, 0xd2, 0x82, 0xad, 0x63,
- 0xff, 0x51, 0x2e, 0xc9, 0xc3, 0xb1, 0x5b, 0x60, 0x50, 0xf6, 0xdb, 0xd1,
- 0x3f, 0x57, 0x6c, 0xbe, 0x67, 0xac, 0x14, 0xf3, 0xe8, 0x8f, 0x5e, 0xb2,
- 0xfc, 0x6c, 0xd6, 0x8e, 0x6a, 0xb4, 0x8f, 0xcc, 0xc7, 0x72, 0x3e, 0xfc,
- 0xab, 0xe5, 0xf5, 0x77, 0x66, 0x44, 0x15, 0x79, 0xc9, 0x73, 0x35, 0x28,
- 0x62, 0x3f, 0x3b, 0x72, 0xfe, 0xba, 0x42, 0xfb, 0xbf, 0xe6, 0x43, 0x56,
- 0x1f, 0x4f, 0xcd, 0x95, 0xa0, 0x60, 0x9b, 0x15, 0xd3, 0xcb, 0xba, 0x75,
- 0x7c, 0x16, 0x95, 0x9c, 0x86, 0x8a, 0x13, 0xba, 0xe0, 0x48, 0x0b, 0x6d,
- 0xd5, 0x89, 0x0d, 0x41, 0x9a, 0xa3, 0x95, 0xcf, 0x9f, 0xc4, 0xce, 0xe4,
- 0xbf, 0x9b, 0xcf, 0x51, 0x8f, 0x56, 0x92, 0xc3, 0x78, 0x88, 0x03, 0x4f,
- 0x85, 0x56, 0x93, 0x73, 0x72, 0xcd, 0x09, 0x07, 0x31, 0x48, 0x41, 0xa2,
- 0x89, 0xf6, 0x1f, 0x5a, 0x80, 0x09, 0xab, 0x7d, 0xd5, 0xdc, 0x6c, 0x0e,
- 0xf1, 0x83, 0xb9, 0xd9, 0x38, 0x50, 0xe4, 0xff, 0x9f, 0x91, 0xdf, 0x2b,
- 0xa6, 0xa7, 0x52, 0xe4, 0xe7, 0x80, 0x9b, 0x7e, 0x6b, 0x1f, 0xdb, 0x9c,
- 0xdb, 0xed, 0x40, 0xbf, 0xd6, 0x82, 0xfe, 0x31, 0x78, 0x3e, 0x65, 0x9b,
- 0x7f, 0x1a, 0x1e, 0x98, 0x9b, 0xe5, 0x0a, 0x6f, 0xa1, 0x3b, 0xfa, 0xbc,
- 0xb9, 0xac, 0x52, 0xd6, 0xeb, 0x84, 0x9b, 0xeb, 0xdd, 0x77, 0x3d, 0x9f,
- 0xb7, 0xde, 0x7c, 0xd8, 0xf2, 0x13, 0xbb, 0xe7, 0x4a, 0xbd, 0xec, 0xa7,
- 0x09, 0x13, 0x97, 0xf4, 0xa3, 0x56, 0x1c, 0x2e, 0xd8, 0xd0, 0x93, 0x90,
- 0xbd, 0x95, 0xb9, 0x6d, 0xcd, 0xc9, 0xe3, 0xff, 0x54, 0xdf, 0x3c, 0xef,
- 0x65, 0x39, 0x5d, 0x96, 0x5a, 0x75, 0x9e, 0xe3, 0x8b, 0x2e, 0x8b, 0x1e,
- 0x5b, 0xef, 0xfd, 0x24, 0xe5, 0xfd, 0xd9, 0x27, 0xd4, 0xdf, 0x73, 0x0c,
- 0xc9, 0xa9, 0xb4, 0xb0, 0x0f, 0xd3, 0x5c, 0xaf, 0x37, 0x78, 0x4e, 0xe0,
- 0x8f, 0xa8, 0xdb, 0x3a, 0xb6, 0x0f, 0x48, 0xbe, 0xd5, 0xa3, 0x38, 0xf6,
- 0xac, 0xc1, 0x25, 0xfa, 0xff, 0x9d, 0x96, 0x1e, 0x0a, 0xae, 0xc8, 0x3c,
- 0x04, 0x5b, 0xda, 0xe8, 0xc7, 0xad, 0xb3, 0x2e, 0x91, 0x9a, 0x70, 0xa7,
- 0xf2, 0x61, 0x7d, 0x27, 0x8e, 0x86, 0x0c, 0xb3, 0x5c, 0xf3, 0xaf, 0x65,
- 0xd0, 0x5f, 0x34, 0xd6, 0x58, 0x88, 0xf1, 0x90, 0xf0, 0x47, 0xb8, 0xd2,
- 0x69, 0xaf, 0x31, 0xc3, 0xae, 0xba, 0x5e, 0x4e, 0xe7, 0xb0, 0xd2, 0xf6,
- 0xc0, 0x5c, 0x89, 0x97, 0x92, 0x16, 0x8e, 0x7c, 0x1d, 0xf7, 0x59, 0x7b,
- 0xab, 0xd2, 0x87, 0x4a, 0xbe, 0xf7, 0x68, 0xe8, 0x4a, 0x54, 0x30, 0xc5,
- 0x5c, 0xd2, 0x1c, 0x6a, 0x50, 0xb7, 0xe3, 0x4e, 0x62, 0xd7, 0x12, 0x9c,
- 0xd1, 0xa5, 0xae, 0x61, 0x7c, 0xdb, 0x01, 0xa9, 0xc1, 0x1d, 0x0e, 0x6d,
- 0x8d, 0x2e, 0xc5, 0xbe, 0x01, 0x43, 0x71, 0x86, 0xbd, 0x91, 0x18, 0xb9,
- 0x10, 0xe3, 0x71, 0x2b, 0xdf, 0x27, 0xf9, 0x84, 0xc1, 0xc6, 0x4e, 0x6c,
- 0xd7, 0x0b, 0xd1, 0xa3, 0x47, 0x8a, 0xb6, 0x2c, 0xee, 0xc2, 0x7e, 0xbd,
- 0xd4, 0x98, 0x17, 0x36, 0x88, 0xe9, 0xda, 0x86, 0x24, 0xfc, 0x2d, 0x17,
- 0xc9, 0x39, 0x8e, 0xc3, 0xdb, 0xb1, 0xc4, 0x4e, 0xcc, 0xbd, 0xc7, 0xe1,
- 0x8a, 0x65, 0x9a, 0x90, 0x18, 0xab, 0x72, 0xed, 0xc8, 0x04, 0x11, 0x1f,
- 0xe3, 0x7e, 0x33, 0xae, 0x75, 0x64, 0x96, 0x92, 0x83, 0x8a, 0x1c, 0xed,
- 0xd4, 0xc5, 0x7a, 0x3c, 0xd3, 0x7a, 0xc1, 0x7c, 0xd2, 0x2f, 0xf8, 0x59,
- 0x8b, 0x67, 0x55, 0x9f, 0xc5, 0x29, 0x23, 0xb6, 0xaf, 0xb2, 0x0f, 0x3b,
- 0x75, 0xee, 0x55, 0xd3, 0xf3, 0xa8, 0xc8, 0x8d, 0xc1, 0x56, 0xf1, 0x6a,
- 0xe2, 0xa7, 0xfc, 0x2d, 0xb2, 0x13, 0x19, 0x9a, 0x58, 0xa7, 0x4b, 0x2e,
- 0xaf, 0x91, 0x36, 0xe3, 0xc6, 0xdb, 0xea, 0x8d, 0x7d, 0x78, 0x5a, 0xf7,
- 0xe9, 0x87, 0x20, 0x39, 0xbc, 0xff, 0xce, 0xe7, 0x24, 0xdf, 0xd2, 0x84,
- 0x17, 0x2b, 0xb2, 0xf1, 0x87, 0xc7, 0x56, 0x42, 0xdc, 0xcd, 0xfb, 0x11,
- 0xb9, 0xef, 0x4d, 0x46, 0xa8, 0xa7, 0x1b, 0x83, 0x53, 0x66, 0xa4, 0xd2,
- 0xe8, 0x94, 0xb3, 0x28, 0xee, 0xf0, 0xea, 0x17, 0xdd, 0xf5, 0xde, 0x8e,
- 0x29, 0x05, 0x38, 0x13, 0xa3, 0x1f, 0xb6, 0xfe, 0xbb, 0x47, 0xe9, 0xdb,
- 0x89, 0xa1, 0xe0, 0x1d, 0x68, 0x6f, 0x93, 0xb1, 0x9a, 0xd1, 0xbb, 0xd7,
- 0x34, 0x4b, 0x43, 0x3e, 0x35, 0x0d, 0x27, 0x56, 0x04, 0xed, 0xb8, 0xa0,
- 0x9a, 0x70, 0x84, 0xfe, 0xdd, 0xcc, 0xd0, 0x3f, 0x0e, 0xd3, 0x4e, 0x76,
- 0x50, 0xc7, 0xe4, 0x5d, 0x28, 0x3f, 0xed, 0x24, 0x4e, 0x3b, 0x39, 0x13,
- 0x9a, 0x9f, 0x7b, 0x57, 0x52, 0x23, 0xaf, 0x98, 0xc4, 0x92, 0x01, 0x15,
- 0x9f, 0xde, 0x33, 0x89, 0xd0, 0x50, 0x7e, 0xee, 0x62, 0x97, 0xf9, 0xf9,
- 0x4b, 0x6d, 0x50, 0xe6, 0x2e, 0x73, 0x94, 0xb5, 0xc8, 0xdf, 0xf9, 0x7b,
- 0xf9, 0xdf, 0xc4, 0xcf, 0x3a, 0xd1, 0x6a, 0xad, 0xed, 0x2f, 0x6a, 0xb2,
- 0x98, 0x91, 0x5f, 0x93, 0xeb, 0x96, 0xeb, 0x4b, 0xb7, 0x5c, 0x3f, 0xee,
- 0xbe, 0xf9, 0x7a, 0xfb, 0x9c, 0x9b, 0xaf, 0xf3, 0x36, 0x71, 0x43, 0xae,
- 0x1d, 0xba, 0x6f, 0xe2, 0x28, 0xd7, 0x3a, 0x63, 0xc1, 0x21, 0xf3, 0x42,
- 0x85, 0xcc, 0x45, 0x62, 0xd6, 0xec, 0x5c, 0x97, 0x65, 0xa6, 0xcf, 0xf5,
- 0xcd, 0x5c, 0x6d, 0xc0, 0x3a, 0xf7, 0x4b, 0xbb, 0xd1, 0xe4, 0x1d, 0xdf,
- 0xdc, 0x3b, 0x74, 0xd9, 0xb3, 0x88, 0xa5, 0xe1, 0x80, 0xd2, 0x1b, 0x33,
- 0xcc, 0x19, 0x5a, 0xb1, 0x21, 0xef, 0x4a, 0xa9, 0x7e, 0x03, 0x25, 0x7e,
- 0x6d, 0xc3, 0x0c, 0x5b, 0x17, 0x9c, 0x0b, 0xb5, 0x8e, 0x3f, 0x53, 0x92,
- 0x88, 0x67, 0xbc, 0x81, 0x43, 0x94, 0x55, 0x2c, 0x73, 0x95, 0x71, 0x75,
- 0x17, 0x9e, 0x09, 0x39, 0x8c, 0xe2, 0xb0, 0xd7, 0x3d, 0x5f, 0x59, 0x86,
- 0xed, 0x43, 0x7f, 0x8e, 0xf5, 0x49, 0xe1, 0xf8, 0xb5, 0xd8, 0x32, 0x66,
- 0xc3, 0x31, 0xea, 0x77, 0x2f, 0xc7, 0x21, 0xfe, 0xb9, 0x53, 0x90, 0xb3,
- 0x79, 0x8d, 0x8c, 0x91, 0x75, 0xeb, 0xb3, 0x75, 0xe8, 0x75, 0xac, 0x8f,
- 0x9a, 0xf8, 0x54, 0xa7, 0xef, 0xd1, 0x64, 0x7e, 0x12, 0x3b, 0xb7, 0x5a,
- 0x58, 0xfa, 0x48, 0x9c, 0xfb, 0x39, 0x4b, 0x6c, 0x75, 0x29, 0x6d, 0x56,
- 0xc1, 0x67, 0x52, 0x77, 0xac, 0xe4, 0x9c, 0xc9, 0x0d, 0xc7, 0xa3, 0x9b,
- 0x30, 0x1c, 0x35, 0xe4, 0x7d, 0xc0, 0xde, 0x1a, 0x7b, 0xe4, 0x85, 0x0a,
- 0xf2, 0xec, 0x84, 0xee, 0x6f, 0x3f, 0xa7, 0xc0, 0x53, 0x16, 0xf6, 0xd3,
- 0xcf, 0x7c, 0x89, 0xdf, 0xea, 0x92, 0x4f, 0xd3, 0x5d, 0xab, 0xa8, 0xef,
- 0x7b, 0x86, 0x02, 0x56, 0x7e, 0xe0, 0xef, 0x6e, 0x9b, 0xbf, 0x90, 0x1a,
- 0xb3, 0x9e, 0xcb, 0x35, 0xbe, 0x8e, 0x83, 0x69, 0x17, 0x1e, 0x8b, 0x7b,
- 0x94, 0x79, 0x7b, 0x54, 0xdc, 0x1f, 0xf7, 0x4e, 0x2c, 0xb1, 0x93, 0x7f,
- 0x2c, 0x9a, 0xc1, 0xfe, 0x14, 0xfc, 0x68, 0xa1, 0xf8, 0x82, 0xff, 0x0a,
- 0x63, 0x56, 0x84, 0x7d, 0xa2, 0xb4, 0x60, 0xb1, 0x57, 0x3d, 0x68, 0xf3,
- 0xb9, 0x7f, 0x8b, 0xad, 0xb0, 0x67, 0x56, 0xa3, 0x9b, 0xf3, 0x5f, 0x19,
- 0x97, 0x9a, 0x55, 0x03, 0x50, 0xd1, 0x8c, 0x1d, 0x87, 0xc4, 0x36, 0xe5,
- 0x9d, 0x75, 0x78, 0xaa, 0xc2, 0x2d, 0x77, 0xa0, 0xf8, 0x4b, 0x72, 0xed,
- 0x49, 0x89, 0x3f, 0x37, 0x94, 0xdb, 0x4c, 0xc6, 0x2f, 0xf3, 0x73, 0x35,
- 0x89, 0xa5, 0xd8, 0x3a, 0x20, 0xf9, 0x76, 0xe2, 0xb6, 0xce, 0x38, 0xa8,
- 0x42, 0x0b, 0x3c, 0x65, 0x93, 0x3a, 0xd0, 0x26, 0xf8, 0x62, 0x9b, 0x10,
- 0x88, 0x89, 0xcd, 0x6a, 0x6a, 0x07, 0x22, 0xa7, 0x25, 0xcf, 0x37, 0x2f,
- 0xe4, 0xe7, 0xbc, 0xfc, 0xbd, 0x55, 0x76, 0xdd, 0xf5, 0xca, 0xa8, 0x8a,
- 0x09, 0x35, 0x1b, 0x47, 0x1e, 0x4a, 0x6a, 0x6b, 0x0b, 0x6d, 0x72, 0x26,
- 0xe2, 0xb2, 0x19, 0xb1, 0xfa, 0x55, 0x6a, 0x51, 0xde, 0x8c, 0xbe, 0xbd,
- 0xef, 0xd2, 0x07, 0xc9, 0x18, 0xbf, 0x37, 0x9d, 0xd4, 0xcb, 0xe5, 0x6d,
- 0x1e, 0xdc, 0x17, 0x97, 0x3c, 0x69, 0x4f, 0x75, 0xf6, 0x4c, 0x87, 0x5c,
- 0x3b, 0xd0, 0xa1, 0x13, 0x64, 0x67, 0x7d, 0x61, 0x56, 0x59, 0x71, 0xe9,
- 0x97, 0x59, 0x9d, 0x49, 0xdc, 0x7d, 0x87, 0xd8, 0x78, 0xcf, 0x58, 0x83,
- 0x3b, 0xab, 0x77, 0x4d, 0xbc, 0x96, 0xbe, 0xb4, 0x7d, 0x9b, 0xe4, 0x34,
- 0x2e, 0xf9, 0xcc, 0x23, 0xa3, 0xd3, 0xdb, 0xe7, 0x73, 0x30, 0x55, 0x39,
- 0x4e, 0x95, 0xd7, 0x37, 0xa9, 0xf5, 0x45, 0x94, 0x87, 0xa3, 0x2d, 0xca,
- 0xaa, 0xa8, 0xd4, 0xfb, 0x6c, 0xd1, 0x12, 0xeb, 0x5c, 0xab, 0x89, 0xef,
- 0x85, 0xc6, 0x95, 0x6d, 0xd6, 0x99, 0x59, 0x43, 0x49, 0x36, 0x02, 0x95,
- 0xa3, 0xcd, 0xca, 0xf6, 0xe8, 0x27, 0xe6, 0x53, 0x56, 0x5d, 0x7d, 0xa6,
- 0x75, 0xbe, 0xa6, 0x70, 0xd4, 0x85, 0x8a, 0x83, 0x25, 0x28, 0x18, 0xd4,
- 0x30, 0x73, 0xf4, 0x41, 0xf2, 0x56, 0xe1, 0x3a, 0x46, 0x8b, 0xc3, 0x3a,
- 0xa3, 0xf6, 0xfa, 0xf5, 0x33, 0x6a, 0x0e, 0xe2, 0x82, 0x01, 0xeb, 0x1f,
- 0x63, 0xa5, 0xc3, 0x8c, 0x95, 0xcc, 0x25, 0xdf, 0x0b, 0x19, 0x3b, 0x66,
- 0xc2, 0x1b, 0xa8, 0xb4, 0x19, 0xa6, 0xe4, 0x6e, 0x5e, 0x21, 0x61, 0x5c,
- 0x53, 0x67, 0x60, 0x45, 0x9d, 0xbc, 0x9b, 0xe9, 0x30, 0xec, 0xe1, 0x2e,
- 0x1c, 0x0e, 0x75, 0xe1, 0x3d, 0xbd, 0x0b, 0x3b, 0xf5, 0x62, 0xa3, 0x3c,
- 0x5c, 0x2a, 0x67, 0xd9, 0x27, 0xa2, 0xd0, 0xf4, 0xb4, 0xa2, 0x9d, 0xba,
- 0x0a, 0xef, 0x3e, 0x9f, 0xe2, 0x35, 0x96, 0x29, 0x1a, 0x2e, 0x67, 0xbc,
- 0x53, 0xe5, 0xb4, 0x81, 0x6b, 0x99, 0x00, 0xa6, 0x88, 0xab, 0xc9, 0x31,
- 0x39, 0x4f, 0x52, 0x8b, 0x81, 0xb1, 0xff, 0x29, 0xdc, 0xc0, 0x20, 0x26,
- 0x59, 0x67, 0x2a, 0x9f, 0x93, 0x5a, 0xa6, 0x33, 0x98, 0xe3, 0x30, 0x86,
- 0xb2, 0xae, 0xb1, 0x0c, 0xd7, 0xe8, 0x9d, 0x7e, 0x98, 0xee, 0x64, 0x3c,
- 0x87, 0xd7, 0x6a, 0x60, 0xff, 0xbe, 0x1b, 0xf5, 0xc9, 0x19, 0x38, 0x56,
- 0x5f, 0x89, 0x02, 0x1c, 0x1d, 0xee, 0x20, 0xc7, 0xef, 0x6e, 0x2f, 0x67,
- 0x7c, 0x3a, 0x3a, 0xec, 0x44, 0x2a, 0x25, 0x39, 0x07, 0xab, 0x36, 0x39,
- 0xe9, 0xa0, 0x2d, 0xed, 0x4a, 0xa0, 0xbe, 0x26, 0xec, 0x4f, 0xd6, 0xd8,
- 0x55, 0xf6, 0x51, 0x85, 0x54, 0x5a, 0xe3, 0x27, 0xc0, 0x4f, 0x90, 0x9f,
- 0x26, 0x7c, 0x8f, 0x36, 0x5b, 0x41, 0xbc, 0x7d, 0x35, 0x5d, 0x86, 0x4f,
- 0x92, 0x5a, 0x40, 0xa7, 0x1e, 0x0c, 0x33, 0x46, 0x30, 0x2c, 0x39, 0x95,
- 0xe1, 0x2a, 0xed, 0xf4, 0xa5, 0x50, 0x19, 0xcc, 0xd4, 0xed, 0x62, 0x42,
- 0x79, 0xff, 0x25, 0x7f, 0x0e, 0x33, 0x5b, 0x5f, 0x3d, 0x92, 0x81, 0xf2,
- 0x78, 0x9d, 0x41, 0x7d, 0x61, 0x0c, 0xbb, 0x48, 0x6a, 0x29, 0x5a, 0xe7,
- 0x25, 0x7b, 0xb1, 0x51, 0x13, 0xf6, 0x7a, 0x6a, 0xec, 0x1a, 0xce, 0xa5,
- 0x27, 0x11, 0x4f, 0xca, 0xbb, 0x6d, 0xa2, 0xc7, 0xef, 0x9b, 0x46, 0x85,
- 0x9c, 0xc9, 0xe8, 0x44, 0x5c, 0xab, 0x64, 0x1c, 0x24, 0xef, 0x3e, 0x1e,
- 0x0e, 0x45, 0x63, 0xa5, 0xf2, 0x9e, 0xf0, 0x92, 0x97, 0x43, 0xde, 0x96,
- 0x7e, 0xc5, 0x78, 0xa8, 0xc4, 0x7a, 0xaf, 0xa3, 0x8b, 0x58, 0xac, 0xa9,
- 0x4e, 0xc5, 0xdb, 0xb4, 0x05, 0x01, 0x1c, 0x4b, 0x8b, 0xdc, 0x28, 0xa7,
- 0xb1, 0xac, 0xdc, 0x6e, 0x9c, 0x9d, 0xce, 0xea, 0xc1, 0xc6, 0xa8, 0x83,
- 0xdf, 0xb2, 0xf7, 0x72, 0xae, 0x95, 0x3e, 0xc2, 0xda, 0xff, 0x9f, 0xdf,
- 0x91, 0x3b, 0xbf, 0xda, 0x5e, 0x19, 0x76, 0x05, 0x97, 0xc7, 0xed, 0x9f,
- 0xc8, 0xfb, 0xc8, 0x4f, 0x34, 0xca, 0x7b, 0x6b, 0xae, 0xe0, 0xe3, 0xa3,
- 0xae, 0xe0, 0xda, 0xf8, 0x51, 0x85, 0xf2, 0xda, 0x57, 0x63, 0x77, 0x05,
- 0x1f, 0xb9, 0xd1, 0x9e, 0xfb, 0xde, 0x85, 0xb1, 0x50, 0xb1, 0xa1, 0x86,
- 0xc5, 0xa7, 0x7b, 0x03, 0x9f, 0x28, 0x96, 0x2f, 0x37, 0x4a, 0xe8, 0x63,
- 0x9f, 0xcf, 0x8c, 0x9b, 0xed, 0xb3, 0x04, 0xab, 0xec, 0x1c, 0xeb, 0x2a,
- 0x5e, 0x49, 0xdd, 0x78, 0xae, 0x85, 0xcf, 0x15, 0xf3, 0xb9, 0x92, 0xb0,
- 0xc4, 0x8d, 0x5e, 0x7d, 0x95, 0xa2, 0x79, 0x8a, 0x14, 0xa9, 0x87, 0x69,
- 0xf8, 0x55, 0xfa, 0x9f, 0xef, 0x90, 0x78, 0xb7, 0x67, 0xac, 0x12, 0x6b,
- 0x76, 0x9b, 0x4b, 0xe6, 0x2d, 0x34, 0x97, 0xa4, 0x43, 0x31, 0xf3, 0xa5,
- 0x6a, 0xd9, 0x4f, 0xa9, 0xf1, 0xc9, 0x33, 0x9a, 0xea, 0x63, 0x9c, 0xf9,
- 0x4d, 0x7d, 0xbb, 0xbc, 0xa3, 0x07, 0x79, 0x7f, 0xa9, 0x90, 0x63, 0x9c,
- 0x4c, 0x89, 0x8e, 0x6c, 0x6d, 0x77, 0x31, 0x16, 0x95, 0x77, 0x67, 0x0f,
- 0x73, 0xef, 0x0f, 0xa6, 0xfe, 0xd7, 0x1d, 0x72, 0x76, 0x5d, 0xce, 0x06,
- 0x00, 0xff, 0x1f, 0x17, 0x23, 0xca, 0x76, 0xf8, 0x78, 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_RXP_b09FwRodata[(0x124/4) + 1] = {
- 0x5f865437, 0xe4ac62cc, 0x50103a45, 0x36621985, 0xbf14c0e8, 0x1bc27a1e,
- 0x84f4b556, 0x094ea6fe, 0x7dda01e7, 0xc04d7481, 0x80080100, 0x80080080,
- 0x80080000, 0x08004fbc, 0x08004fbc, 0x08005098, 0x0800506c, 0x08005050,
- 0x08004f8c, 0x08004f8c, 0x08004f8c, 0x08004fc4, 0x080072ac, 0x080072f8,
- 0x080072b8, 0x080071dc, 0x080072b8, 0x080072e8, 0x080072b8, 0x080071dc,
- 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc,
- 0x080071dc, 0x080071dc, 0x080071dc, 0x080072d8, 0x080072c8, 0x080071dc,
- 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc,
- 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080072c8,
- 0x0800787c, 0x08007748, 0x08007844, 0x08007748, 0x08007814, 0x08007630,
- 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748,
- 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748,
- 0x08007770, 0x00000000 };
-
-static struct fw_info bnx2_rxp_fw_09 = {
- /* Firmware version: 4.6.15 */
- .ver_major = 0x4,
- .ver_minor = 0x6,
- .ver_fix = 0xf,
-
- .start_addr = 0x080031d8,
-
- .text_addr = 0x08000000,
- .text_len = 0x78f4,
- .text_index = 0x0,
- .gz_text = bnx2_RXP_b09FwText,
- .gz_text_len = sizeof(bnx2_RXP_b09FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_RXP_b09FwData,
-
- .sbss_addr = 0x08007a40,
- .sbss_len = 0x58,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08007a98,
- .bss_len = 0x20,
- .bss_index = 0x0,
-
- .rodata_addr = 0x080078f4,
- .rodata_len = 0x124,
- .rodata_index = 0x0,
- .rodata = bnx2_RXP_b09FwRodata,
-};
-
-static u8 bnx2_xi_rv2p_proc1[] = {
- /* Date: 01/27/2009 19:01 */
-#define XI_RV2P_PROC1_POST_WAIT_TIMEOUT_MSK 0xffff
- 0xa5, 0x56, 0xdd, 0x6b, 0x1c, 0x55, 0x14, 0x3f, 0x33, 0xbb, 0x33, 0xb3,
- 0xd9, 0x9d, 0xd9, 0x5d, 0x9a, 0x34, 0x8e, 0xb1, 0x34, 0xdb, 0x20, 0xca,
- 0xa6, 0x13, 0xdd, 0x68, 0x1f, 0x04, 0x03, 0x2d, 0x01, 0x29, 0x98, 0xe2,
- 0x43, 0xa0, 0x52, 0x8a, 0x60, 0x5c, 0xb4, 0x08, 0xf6, 0x2f, 0x10, 0xc1,
- 0x21, 0x31, 0x11, 0xc4, 0xaf, 0x7d, 0xe8, 0x42, 0x02, 0x6a, 0x40, 0x50,
- 0x09, 0x11, 0x77, 0xdf, 0x24, 0x16, 0x7c, 0x68, 0xf1, 0x41, 0xda, 0xa7,
- 0x16, 0xd4, 0x97, 0x46, 0x11, 0xbf, 0x5e, 0x04, 0xd1, 0xc7, 0x9a, 0xf1,
- 0x9e, 0x8f, 0xbb, 0x3b, 0x73, 0xb3, 0x9b, 0x14, 0x5c, 0x48, 0x7e, 0x9c,
- 0x7b, 0xcf, 0x39, 0xf7, 0x7c, 0x9f, 0xa9, 0x02, 0x80, 0x0d, 0x71, 0x77,
- 0x52, 0x21, 0x58, 0xb9, 0x5c, 0x01, 0x01, 0x60, 0x1b, 0xf8, 0xe7, 0xf8,
- 0x44, 0xc7, 0x8f, 0x0a, 0x7d, 0x92, 0x21, 0x3e, 0x59, 0x55, 0xff, 0x2f,
- 0xc3, 0xe9, 0x1a, 0x62, 0x0e, 0x4e, 0x9f, 0x40, 0x7c, 0x12, 0xbe, 0xae,
- 0x85, 0x0a, 0xff, 0x4d, 0x20, 0x46, 0xfa, 0x68, 0xe7, 0xcb, 0x6e, 0x89,
- 0xf4, 0xef, 0x8a, 0xfc, 0xf7, 0x39, 0xc6, 0x27, 0xa2, 0x02, 0xeb, 0x11,
- 0x84, 0x99, 0x2a, 0xc1, 0xed, 0x16, 0xd2, 0xe7, 0xcf, 0x83, 0x8b, 0x7a,
- 0xde, 0x53, 0x0c, 0x48, 0x1f, 0xb3, 0xe2, 0x19, 0xb1, 0xcb, 0x66, 0xbe,
- 0x3b, 0xad, 0x0a, 0x9e, 0xc3, 0x8f, 0xf3, 0x48, 0xdf, 0x57, 0x7c, 0xa3,
- 0x85, 0x38, 0x0e, 0x97, 0x0a, 0x3e, 0xfb, 0x53, 0x17, 0x9c, 0x64, 0xf5,
- 0xbb, 0xd3, 0x28, 0xaf, 0x64, 0xa6, 0x45, 0xbf, 0x83, 0xfa, 0x7f, 0x4f,
- 0x58, 0x3f, 0xea, 0x4d, 0xeb, 0xbb, 0x5f, 0xe9, 0xc3, 0x73, 0x57, 0xec,
- 0x73, 0x0d, 0xfb, 0x5c, 0x65, 0x0f, 0xca, 0xaf, 0x00, 0xfb, 0x39, 0xaa,
- 0xde, 0x45, 0xfa, 0xaf, 0xbe, 0xbe, 0x2e, 0xa2, 0x6f, 0xb1, 0xbc, 0xfa,
- 0x13, 0xfb, 0x59, 0xee, 0x35, 0x25, 0xa7, 0xe3, 0x92, 0xb5, 0xd3, 0x8b,
- 0xb4, 0x7f, 0x3a, 0xfe, 0xc8, 0x7f, 0x2b, 0xc9, 0xf2, 0xc3, 0x21, 0xfc,
- 0x37, 0x15, 0x7f, 0x56, 0x2f, 0x9f, 0x7f, 0xdb, 0x3f, 0x1f, 0x18, 0x1f,
- 0xc7, 0x88, 0xcf, 0x75, 0xf1, 0xe7, 0x29, 0x78, 0xd0, 0x0e, 0x89, 0x2f,
- 0x0f, 0x21, 0xc5, 0x09, 0x62, 0xc4, 0xe3, 0x82, 0x2f, 0x09, 0x7e, 0x2e,
- 0xb8, 0x2d, 0x08, 0xff, 0x13, 0xff, 0x1e, 0x72, 0x7e, 0x54, 0xf0, 0x01,
- 0xe3, 0xfc, 0x9a, 0xe0, 0x23, 0x86, 0xfc, 0x71, 0x8b, 0xf1, 0x0f, 0xa1,
- 0xe7, 0x85, 0x7e, 0xc6, 0x90, 0x8f, 0x81, 0xe3, 0x63, 0x19, 0x71, 0xfb,
- 0x58, 0xea, 0x19, 0xf3, 0x2f, 0xf7, 0x75, 0xcd, 0x57, 0xa0, 0x38, 0xc2,
- 0x74, 0x9a, 0xff, 0x83, 0x03, 0xf8, 0x99, 0x6d, 0xbe, 0x3e, 0x48, 0xae,
- 0x9d, 0xb0, 0x1d, 0x57, 0x44, 0xbe, 0xd8, 0xb9, 0x3a, 0xa4, 0x7f, 0xe6,
- 0xa2, 0x41, 0xfd, 0x52, 0x17, 0x3f, 0xbe, 0x92, 0xba, 0xdc, 0xb1, 0x9a,
- 0x51, 0xc8, 0x79, 0xa5, 0x3c, 0x06, 0x52, 0x8f, 0x23, 0x46, 0x3d, 0x7b,
- 0xaa, 0x9e, 0xa5, 0xae, 0xea, 0xba, 0xbe, 0xb2, 0x75, 0xc5, 0xf5, 0xe1,
- 0x1a, 0xf5, 0x11, 0x1f, 0x12, 0x97, 0x92, 0xe1, 0xdf, 0xab, 0x09, 0x86,
- 0x18, 0x7f, 0xb6, 0xcd, 0xb8, 0xc1, 0x18, 0xf9, 0x6e, 0x1e, 0xf1, 0x94,
- 0xff, 0x0d, 0xeb, 0x9b, 0x04, 0x44, 0x3f, 0x6c, 0x53, 0x1f, 0xe5, 0xa1,
- 0xed, 0x2a, 0x9b, 0xe1, 0x6e, 0xf2, 0x0e, 0xf3, 0x4d, 0x38, 0x37, 0x09,
- 0xc3, 0x8d, 0x1b, 0xcc, 0xff, 0x5d, 0x8d, 0xed, 0x7e, 0x56, 0xe6, 0x53,
- 0xff, 0xa7, 0xef, 0xa5, 0xff, 0x2a, 0x48, 0xff, 0x63, 0xc5, 0x5d, 0xfd,
- 0x8e, 0xc8, 0xbd, 0xa2, 0xeb, 0x9b, 0x7f, 0xcb, 0x6e, 0x95, 0xfc, 0x7d,
- 0xab, 0x4b, 0xe4, 0x98, 0xbf, 0x56, 0xa5, 0xdb, 0xb7, 0xbb, 0xda, 0x1f,
- 0xe9, 0xf3, 0x69, 0xed, 0x3f, 0xcb, 0x07, 0x72, 0x6d, 0x3b, 0x3a, 0x7e,
- 0x7c, 0x5e, 0x24, 0x3b, 0x46, 0x3b, 0x9b, 0x46, 0x3e, 0x6b, 0xf7, 0x34,
- 0x07, 0xff, 0x4c, 0xfa, 0x73, 0x30, 0x1d, 0x1f, 0x3d, 0x07, 0x0b, 0xb0,
- 0x74, 0xb6, 0x42, 0xf6, 0x94, 0x5d, 0x56, 0x73, 0xa1, 0xc2, 0xf8, 0x62,
- 0x91, 0xf1, 0x97, 0x22, 0xc6, 0x2f, 0x49, 0x2e, 0x95, 0x98, 0x7e, 0x21,
- 0x40, 0xbd, 0xa3, 0xea, 0x61, 0x2d, 0xaf, 0xed, 0x3a, 0xc8, 0x1e, 0x7c,
- 0x5f, 0xbf, 0xa3, 0xed, 0xd0, 0xef, 0x65, 0xeb, 0x65, 0xf8, 0xbb, 0x8c,
- 0x4d, 0x3b, 0x1b, 0x87, 0xfc, 0x2c, 0xe3, 0x46, 0x03, 0xed, 0xba, 0x9a,
- 0xf4, 0xfa, 0xb0, 0x5e, 0x25, 0xbe, 0x29, 0x60, 0x7a, 0x51, 0xea, 0x73,
- 0x91, 0xfa, 0xa7, 0xac, 0xae, 0x10, 0x27, 0x20, 0xa6, 0xbd, 0x60, 0x17,
- 0xaf, 0x53, 0xbd, 0xe4, 0xe4, 0x5c, 0xe5, 0x67, 0x2a, 0xdb, 0x77, 0xbb,
- 0x5c, 0x8f, 0x85, 0x6c, 0x1d, 0x3f, 0x9c, 0x9a, 0xaf, 0x69, 0x7f, 0xad,
- 0x5e, 0xfd, 0xee, 0xcf, 0x53, 0x36, 0x1f, 0xb7, 0x5b, 0xda, 0x7f, 0x73,
- 0x6f, 0x30, 0x7b, 0xdc, 0x90, 0x40, 0xcd, 0xca, 0xfd, 0x8c, 0xd9, 0x2f,
- 0x83, 0xfa, 0xad, 0x6a, 0xf4, 0xcf, 0x11, 0xe9, 0xb7, 0x91, 0xce, 0x66,
- 0xeb, 0xb0, 0x7e, 0x46, 0xfe, 0x2f, 0x64, 0x9e, 0x54, 0xa1, 0xb7, 0x97,
- 0xb6, 0x91, 0x2e, 0x81, 0xf4, 0x61, 0x27, 0xce, 0x65, 0xf2, 0x70, 0x06,
- 0x06, 0xce, 0x95, 0x0f, 0x45, 0x4f, 0x43, 0xe6, 0x8b, 0x9b, 0xda, 0x5f,
- 0xc4, 0x5e, 0x06, 0xb2, 0xc3, 0x33, 0xe6, 0xc3, 0xdd, 0x3d, 0xdd, 0xef,
- 0xcb, 0xee, 0x20, 0x7f, 0x3d, 0xf8, 0xcd, 0xe7, 0xfa, 0x68, 0x52, 0xbf,
- 0x38, 0x63, 0x97, 0x77, 0x32, 0x79, 0x02, 0x38, 0xa1, 0xf7, 0x52, 0xda,
- 0xae, 0xf4, 0x5e, 0x45, 0x7d, 0x21, 0x34, 0x67, 0xd3, 0xfb, 0xf5, 0xfd,
- 0x44, 0xcf, 0xf5, 0x80, 0xfa, 0xa4, 0xbc, 0xaf, 0xef, 0xf4, 0x1c, 0xad,
- 0x45, 0xe9, 0xfe, 0x1d, 0x93, 0xb9, 0x69, 0x03, 0xcf, 0xcd, 0x92, 0xe9,
- 0xa7, 0xda, 0xb7, 0x83, 0xf3, 0xc5, 0xfe, 0xde, 0xd9, 0xbb, 0xb7, 0x39,
- 0x7b, 0x58, 0xde, 0x8b, 0x46, 0xde, 0x6f, 0xf5, 0xe2, 0x68, 0x3b, 0x83,
- 0xbe, 0x2b, 0x4e, 0x29, 0xbd, 0xc2, 0x2f, 0x73, 0xe1, 0x79, 0x9a, 0x77,
- 0x67, 0x84, 0x6f, 0x2e, 0x55, 0xaf, 0x83, 0xf8, 0x62, 0xa3, 0xae, 0x0b,
- 0xfb, 0xf8, 0xb2, 0x73, 0x4c, 0xfb, 0xb3, 0xb5, 0xc5, 0xf5, 0x71, 0x31,
- 0xd5, 0xaf, 0xe9, 0xf9, 0x3f, 0x22, 0xf5, 0xa0, 0xf8, 0xc8, 0x8f, 0x9d,
- 0xbd, 0xfe, 0xbe, 0x48, 0xd7, 0xd7, 0xa2, 0xd4, 0xb5, 0x3d, 0xb7, 0x49,
- 0x7d, 0xe4, 0x35, 0x7f, 0x35, 0xf2, 0x35, 0x1b, 0x61, 0x9d, 0xbc, 0x0e,
- 0x5d, 0xb1, 0xf3, 0x87, 0x8c, 0xbd, 0x81, 0xf4, 0xa1, 0x0b, 0x9f, 0x75,
- 0xb5, 0x5f, 0x7c, 0x5d, 0x8b, 0x18, 0x3f, 0x8d, 0xa4, 0x9f, 0x7a, 0xfe,
- 0xe1, 0xbb, 0x0b, 0xf2, 0x6e, 0x15, 0x3e, 0xe9, 0xed, 0x03, 0x9c, 0x6f,
- 0x1e, 0x34, 0x64, 0x7e, 0x2e, 0xc9, 0x1c, 0xfb, 0xa9, 0xc8, 0x73, 0xb2,
- 0xb9, 0x40, 0xf5, 0x0a, 0xe3, 0x32, 0xcf, 0x9a, 0x01, 0xd3, 0x13, 0x01,
- 0x7f, 0x07, 0x37, 0x3c, 0x9f, 0xf8, 0x26, 0x02, 0xc6, 0xf1, 0x12, 0xca,
- 0x85, 0xf0, 0xf3, 0x39, 0x62, 0x8f, 0xd6, 0x7d, 0xde, 0x73, 0xeb, 0x37,
- 0x64, 0x9e, 0x54, 0x74, 0xdc, 0xc4, 0xcf, 0xc7, 0xf1, 0x7c, 0x5c, 0xcd,
- 0x2d, 0xa6, 0xb9, 0x1e, 0xfc, 0x5e, 0xfd, 0x7f, 0x24, 0x59, 0xa9, 0x55,
- 0xd2, 0x71, 0xd6, 0xfd, 0xf6, 0xae, 0x11, 0x5f, 0x9d, 0x9f, 0x87, 0x12,
- 0x3d, 0xe7, 0xa7, 0xce, 0xa2, 0xbd, 0x15, 0x28, 0x7b, 0x5c, 0x3f, 0x8c,
- 0x4a, 0x8f, 0xed, 0xa1, 0xd8, 0xb1, 0x55, 0x99, 0x9b, 0xab, 0xcb, 0xa4,
- 0xe6, 0xdc, 0xaa, 0x3e, 0x9f, 0xa7, 0x86, 0x59, 0xdc, 0xba, 0x46, 0xe7,
- 0xe5, 0x6e, 0x8e, 0xcf, 0xbd, 0x05, 0x1d, 0xaf, 0x0a, 0xf9, 0xdf, 0xe6,
- 0x78, 0x3d, 0x77, 0x85, 0xf1, 0x22, 0x3c, 0x4d, 0x58, 0x6c, 0x4b, 0x9f,
- 0xaf, 0xfb, 0x05, 0x42, 0xa0, 0x78, 0xd9, 0x8f, 0xf1, 0x7e, 0x77, 0x64,
- 0x2f, 0x17, 0x52, 0xf9, 0x33, 0xf7, 0xe4, 0x41, 0x79, 0x3c, 0x62, 0xec,
- 0x0b, 0xbd, 0xd7, 0x2d, 0xe3, 0xfb, 0x36, 0x30, 0xea, 0xf1, 0xe5, 0x21,
- 0xf5, 0x08, 0x43, 0xea, 0xd9, 0x9c, 0x6f, 0x4b, 0xd2, 0xef, 0x79, 0x70,
- 0x72, 0xb4, 0x78, 0xfd, 0xfc, 0x0a, 0xe5, 0xd5, 0x5e, 0xe5, 0xef, 0x1a,
- 0xdf, 0x59, 0xb3, 0x28, 0x5e, 0xfe, 0x1a, 0xf3, 0xe5, 0xf9, 0x3c, 0xd4,
- 0xf8, 0xe6, 0x0a, 0xf7, 0x95, 0x0d, 0xff, 0x01, 0xd7, 0x0e, 0x41, 0x60,
- 0x88, 0x0d, 0x00, 0x00, 0x00 };
-
-static u8 bnx2_xi_rv2p_proc2[] = {
- /* Date: 01/27/2009 19:01 */
-#define XI_RV2P_PROC2_MAX_BD_PAGE_LOC 5
-#define XI_RV2P_PROC2_BD_PAGE_SIZE_MSK 0xffff
-#define XI_RV2P_PROC2_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1)
- 0xad, 0x57, 0x4d, 0x68, 0x5c, 0x55, 0x14, 0xbe, 0x33, 0x6f, 0x7e, 0xde,
- 0xcc, 0xbc, 0xc9, 0x4c, 0x93, 0x38, 0x99, 0x26, 0xc5, 0xa4, 0x09, 0x8d,
- 0x4e, 0x9d, 0x69, 0x27, 0x3f, 0x44, 0xb0, 0x42, 0x43, 0x90, 0xb4, 0xb5,
- 0x4a, 0xd3, 0x28, 0xc5, 0x5d, 0x92, 0xa9, 0x1d, 0x8c, 0x69, 0x23, 0x18,
- 0x70, 0xe1, 0xc6, 0x47, 0x5a, 0xd3, 0xcd, 0x2c, 0x4c, 0x31, 0x3f, 0x8a,
- 0xa0, 0xd8, 0x9d, 0xb8, 0x19, 0x50, 0xdb, 0x8a, 0x22, 0x14, 0x0c, 0x52,
- 0x17, 0x45, 0xb0, 0x58, 0x37, 0x8a, 0x58, 0x1b, 0x1a, 0x11, 0x8d, 0x8b,
- 0xae, 0x24, 0xe3, 0xbd, 0xe7, 0x3b, 0xf7, 0xcd, 0xbc, 0xc9, 0x8b, 0x89,
- 0x62, 0x36, 0x27, 0xe7, 0xbe, 0x73, 0xcf, 0x39, 0xf7, 0x9c, 0xef, 0x7c,
- 0xf7, 0x4e, 0x52, 0x08, 0x11, 0x10, 0x76, 0xb9, 0x5d, 0x4a, 0xe1, 0x33,
- 0x0c, 0x53, 0x8a, 0x8a, 0x10, 0xc1, 0xb4, 0xd2, 0x85, 0x5f, 0xf0, 0xdf,
- 0xfe, 0x24, 0x89, 0x6f, 0xcb, 0x96, 0x32, 0x13, 0x76, 0x46, 0xd9, 0x45,
- 0xc4, 0xb3, 0xfe, 0x88, 0x94, 0x87, 0xc5, 0x68, 0x06, 0xf6, 0x01, 0xa1,
- 0xa4, 0xb4, 0xb5, 0x95, 0xdc, 0xc5, 0xf2, 0x38, 0xcb, 0xc7, 0x7d, 0x90,
- 0x87, 0x58, 0x3e, 0x56, 0x27, 0x05, 0xdb, 0x3d, 0xcd, 0xfa, 0x00, 0x4b,
- 0x8b, 0xd7, 0x47, 0x59, 0xff, 0x90, 0xa5, 0xcd, 0xeb, 0x61, 0xd6, 0x1f,
- 0xf0, 0xa9, 0x25, 0xe4, 0xab, 0xf4, 0xb5, 0x4a, 0x55, 0xb7, 0xe0, 0x3e,
- 0x83, 0x73, 0x3c, 0xd3, 0xa1, 0xbe, 0xdf, 0xad, 0xb8, 0xed, 0xef, 0x38,
- 0xfa, 0xac, 0xa1, 0xf4, 0x1f, 0xa5, 0xee, 0x53, 0x6a, 0x73, 0x0a, 0xdb,
- 0x9b, 0xd3, 0x25, 0xb5, 0xdf, 0x10, 0xcb, 0xf3, 0x26, 0x55, 0x67, 0xd1,
- 0x82, 0x6e, 0x97, 0x4d, 0xaa, 0xcb, 0xa2, 0xc5, 0xfe, 0x58, 0xee, 0x8e,
- 0x23, 0xde, 0xa9, 0x0e, 0xd4, 0xed, 0xbb, 0x47, 0x60, 0x67, 0x27, 0x74,
- 0x61, 0xf1, 0xbd, 0x5d, 0xf0, 0xf7, 0x29, 0xa5, 0xaf, 0xfb, 0x9a, 0x7c,
- 0xa8, 0x47, 0x98, 0xad, 0xfc, 0x41, 0xb5, 0xbe, 0xb7, 0x7f, 0x71, 0x1e,
- 0xf6, 0x63, 0x1d, 0x58, 0x7f, 0x30, 0xab, 0xfc, 0x85, 0x84, 0xcd, 0x52,
- 0xe4, 0x28, 0x2f, 0x9f, 0x9d, 0x73, 0xfb, 0xff, 0x61, 0x1e, 0xda, 0x44,
- 0x1c, 0x7e, 0xa3, 0x2e, 0xbf, 0xa9, 0x4d, 0x7e, 0x6f, 0x47, 0x6a, 0xfd,
- 0x37, 0xf8, 0xe0, 0x3f, 0xba, 0xad, 0xff, 0x42, 0x1c, 0xb2, 0x29, 0xeb,
- 0x15, 0x27, 0xb2, 0x4d, 0xfe, 0x2f, 0x6e, 0xeb, 0xff, 0x55, 0x27, 0x7f,
- 0xbd, 0x5e, 0x5f, 0x3f, 0x52, 0x3f, 0xb0, 0x0f, 0xf2, 0xf6, 0xfd, 0xfa,
- 0xdc, 0x9c, 0x9f, 0x01, 0x39, 0x98, 0x25, 0x51, 0x3a, 0xcd, 0x00, 0x1f,
- 0xee, 0x56, 0x71, 0x1b, 0x45, 0xc0, 0xaf, 0xfc, 0x1d, 0x30, 0x43, 0xd7,
- 0xb0, 0xfe, 0x1c, 0xf7, 0xe9, 0x79, 0x3e, 0xc8, 0x2f, 0x51, 0x55, 0x98,
- 0x4a, 0xa5, 0x18, 0x63, 0xff, 0xdc, 0x67, 0x3b, 0x86, 0xfd, 0x2b, 0x96,
- 0xca, 0xef, 0x86, 0xc4, 0x8d, 0x57, 0xdf, 0x8d, 0x7f, 0xe8, 0x3b, 0xf6,
- 0xef, 0x7a, 0x08, 0x5f, 0xdf, 0x28, 0x42, 0x6f, 0xbb, 0x9c, 0xa4, 0xfa,
- 0x2c, 0x97, 0xbd, 0x70, 0x52, 0xef, 0x5f, 0xce, 0x71, 0x02, 0x71, 0x44,
- 0xa7, 0x49, 0xc9, 0xa1, 0xae, 0xd2, 0x26, 0xe7, 0x59, 0x27, 0xb1, 0xb8,
- 0x4f, 0xcf, 0x05, 0xf4, 0x62, 0x88, 0x44, 0x7a, 0x62, 0x4e, 0x9d, 0x33,
- 0x21, 0xc6, 0xfd, 0x2a, 0x61, 0x3f, 0xd7, 0xc5, 0x30, 0xad, 0x4f, 0x60,
- 0xff, 0x45, 0xbb, 0x45, 0x67, 0x28, 0xf6, 0x61, 0x5f, 0x73, 0x2f, 0xe4,
- 0x42, 0x6f, 0x50, 0x89, 0x6c, 0x71, 0x86, 0xd4, 0x03, 0x3f, 0xf7, 0x98,
- 0x64, 0x67, 0xe7, 0xf4, 0xdc, 0xe9, 0xbe, 0xa9, 0x3a, 0xbd, 0x52, 0x9d,
- 0xbf, 0x2e, 0xd4, 0xf5, 0xee, 0x3e, 0x65, 0x2f, 0x8b, 0xdb, 0x89, 0x38,
- 0xa3, 0x93, 0x5e, 0x73, 0xfb, 0x92, 0x53, 0xdf, 0x9d, 0xf6, 0x7f, 0x90,
- 0xea, 0x30, 0xc8, 0xf5, 0xe8, 0x60, 0x9c, 0xed, 0xf1, 0xc0, 0x59, 0x82,
- 0xfe, 0x5f, 0x1b, 0x4a, 0x52, 0x3d, 0x4f, 0x60, 0xfd, 0xd2, 0xf0, 0x15,
- 0xf4, 0xe3, 0x18, 0xd5, 0x41, 0x44, 0x2f, 0x7c, 0x8c, 0x5d, 0x13, 0x34,
- 0xdf, 0xe7, 0xfa, 0x8b, 0x9f, 0x42, 0x2f, 0x18, 0x4a, 0x9f, 0xb2, 0x4e,
- 0x5f, 0x85, 0x7d, 0xf0, 0x7c, 0x92, 0xea, 0x77, 0x82, 0xa3, 0x1c, 0x33,
- 0x88, 0x4f, 0x4a, 0xa1, 0xf3, 0xa4, 0x5a, 0x2b, 0xf4, 0x3d, 0x29, 0x2e,
- 0x96, 0xf1, 0x7d, 0x3a, 0xa6, 0xce, 0x37, 0xe2, 0xf0, 0xce, 0x64, 0x08,
- 0xfb, 0x4b, 0xf3, 0xe0, 0x8d, 0x7b, 0x1f, 0x29, 0x7d, 0x2c, 0x7b, 0x0f,
- 0xf6, 0xd9, 0xc9, 0x39, 0x76, 0xec, 0x47, 0xfd, 0xd6, 0xfc, 0xb0, 0x67,
- 0x58, 0x46, 0x03, 0xd4, 0x3f, 0x9f, 0xb0, 0x86, 0x21, 0x5f, 0xa7, 0xef,
- 0x7f, 0xf9, 0x4a, 0x54, 0xb7, 0x53, 0x0d, 0x81, 0x2b, 0xba, 0x3e, 0x2c,
- 0x13, 0xfa, 0x5c, 0x90, 0x3b, 0xc5, 0xfd, 0x9c, 0xb5, 0x15, 0xde, 0xb9,
- 0x8f, 0x99, 0xed, 0xf0, 0x0e, 0x39, 0xdc, 0x0d, 0x19, 0xea, 0x22, 0xbe,
- 0xf8, 0x17, 0xb8, 0xe7, 0xbc, 0x36, 0xcd, 0x15, 0x56, 0xab, 0xf8, 0x24,
- 0x21, 0x71, 0xe9, 0xc2, 0xa9, 0x9c, 0x03, 0xe2, 0x57, 0xd9, 0x07, 0x8d,
- 0x37, 0xe5, 0x30, 0x2c, 0xa6, 0xd8, 0xef, 0x24, 0xd7, 0xe3, 0x2c, 0xd7,
- 0xe3, 0x37, 0x96, 0xd3, 0x31, 0x5d, 0x07, 0xc8, 0x8b, 0x34, 0xff, 0x69,
- 0x8f, 0x7b, 0x43, 0xdf, 0x0f, 0xe8, 0xcf, 0x32, 0xf7, 0xf3, 0x2d, 0xe7,
- 0x9e, 0xd0, 0x75, 0xdd, 0xea, 0xbe, 0xd0, 0xf8, 0xc7, 0xfa, 0xe8, 0xa4,
- 0xe7, 0x39, 0x4b, 0x5f, 0x76, 0xc2, 0x4d, 0x63, 0x17, 0xa4, 0x53, 0xdf,
- 0x6e, 0x9a, 0xdf, 0x86, 0x96, 0xab, 0xfa, 0x7c, 0x2a, 0xcf, 0x5f, 0xf5,
- 0xfc, 0x35, 0x2c, 0xcd, 0x92, 0x8c, 0x36, 0x5e, 0x56, 0xf1, 0x5a, 0x3d,
- 0xf8, 0xc3, 0x3d, 0xc7, 0xf5, 0xf5, 0x9d, 0x8e, 0x13, 0xb1, 0xf6, 0xdf,
- 0x5c, 0x75, 0xcf, 0x2b, 0xe6, 0x33, 0xec, 0xe0, 0xbb, 0x79, 0x80, 0xfb,
- 0xc0, 0x32, 0xf5, 0xa8, 0xf2, 0x3b, 0xc2, 0x71, 0xf2, 0x1c, 0xc7, 0xaa,
- 0xe1, 0x0b, 0x95, 0xe7, 0xfa, 0x86, 0xe6, 0x09, 0x8d, 0x8f, 0x2a, 0x5f,
- 0xe8, 0x3e, 0x50, 0xfc, 0xec, 0xcd, 0x55, 0xb5, 0xbf, 0x6d, 0x1b, 0xfe,
- 0x58, 0x75, 0xfc, 0xdd, 0x72, 0x78, 0x22, 0x49, 0x71, 0x0f, 0xb3, 0xea,
- 0xe6, 0xc1, 0x3f, 0x24, 0x0f, 0xaa, 0xef, 0xa6, 0x69, 0x39, 0xf3, 0xc2,
- 0xfc, 0x37, 0xa3, 0xe2, 0xa5, 0x39, 0xff, 0xb4, 0xbe, 0xbf, 0x64, 0xfe,
- 0xcc, 0x93, 0x63, 0xb5, 0x7c, 0x77, 0xdb, 0x23, 0xee, 0x7f, 0xf5, 0xc7,
- 0xf3, 0x95, 0x65, 0xbe, 0xcf, 0x51, 0x9e, 0x95, 0xf1, 0x3c, 0xe3, 0x25,
- 0x57, 0xdf, 0x07, 0xf4, 0x15, 0xf6, 0xb2, 0xbf, 0x9a, 0xf7, 0xfa, 0xb4,
- 0x7f, 0xa8, 0x76, 0x4f, 0xad, 0x7d, 0x7d, 0xff, 0x03, 0x5b, 0xf0, 0xf8,
- 0xe7, 0x1b, 0x78, 0x7f, 0x7d, 0xb6, 0x51, 0x7d, 0x4f, 0x79, 0xe2, 0xc4,
- 0x16, 0x74, 0x3f, 0x85, 0x25, 0x9e, 0xe9, 0xbd, 0x26, 0xb4, 0xbd, 0x3f,
- 0x88, 0xf7, 0xa4, 0x60, 0xfc, 0x9e, 0x7b, 0x98, 0xfd, 0x64, 0xc0, 0xc7,
- 0x2f, 0x9c, 0xa1, 0xfe, 0xbe, 0x79, 0xf6, 0x3e, 0xf1, 0xf2, 0x7b, 0x2f,
- 0x5f, 0x53, 0x7e, 0x77, 0x8b, 0xd5, 0x19, 0x8b, 0xf2, 0x1a, 0xda, 0x0b,
- 0xf3, 0xfb, 0x87, 0xea, 0xfb, 0xad, 0xfc, 0x9a, 0x8c, 0x07, 0x69, 0x37,
- 0xe1, 0x7e, 0x97, 0x6c, 0xce, 0x13, 0x73, 0x7f, 0x24, 0x81, 0x7d, 0x9a,
- 0xbf, 0xdc, 0xf8, 0x79, 0x77, 0xa3, 0x7a, 0xff, 0xc0, 0xcd, 0xad, 0x83,
- 0xde, 0x73, 0x71, 0xb2, 0xaf, 0x36, 0x4e, 0x46, 0xac, 0x94, 0xe1, 0x7f,
- 0x84, 0x79, 0x65, 0x9c, 0x13, 0xf9, 0x29, 0x9a, 0xa0, 0x78, 0x85, 0xe3,
- 0x84, 0x6b, 0x91, 0x8a, 0xe1, 0xdc, 0x85, 0xa7, 0xf0, 0xbd, 0x10, 0xc7,
- 0x7a, 0x6b, 0x1c, 0xef, 0xcd, 0x91, 0xb0, 0x45, 0xf6, 0xad, 0x71, 0xc8,
- 0x14, 0xf3, 0xcf, 0x8a, 0xc3, 0xcb, 0x90, 0xcb, 0xa1, 0xad, 0x78, 0x19,
- 0xf7, 0xdb, 0xf5, 0x90, 0x5a, 0x97, 0x8f, 0xa0, 0x0c, 0x78, 0x69, 0xa8,
- 0xdb, 0xa2, 0xef, 0xa3, 0x19, 0xe0, 0x48, 0x74, 0x7a, 0x9f, 0xab, 0x0d,
- 0xfc, 0xd2, 0x5a, 0xe5, 0xef, 0x5a, 0x9e, 0xb7, 0x7a, 0x97, 0x1c, 0x1e,
- 0x75, 0xe7, 0x01, 0xfe, 0x52, 0xfe, 0x49, 0x95, 0x7c, 0xb5, 0x13, 0x7e,
- 0x37, 0x18, 0x2f, 0xbf, 0xf3, 0xbd, 0xdf, 0x24, 0xbe, 0x2a, 0xa3, 0x0e,
- 0x2b, 0xe5, 0xfa, 0xfe, 0xe8, 0x3c, 0x74, 0x1c, 0x9c, 0x4b, 0x9f, 0xb3,
- 0x1a, 0x17, 0x79, 0x9d, 0xe1, 0xfc, 0xef, 0xd0, 0xfb, 0x2f, 0xc5, 0xe7,
- 0x55, 0x7e, 0xb1, 0x7e, 0x94, 0xee, 0xa1, 0xa0, 0x7c, 0xdf, 0x6b, 0xdd,
- 0x7d, 0x3f, 0x8c, 0x50, 0x5e, 0x8d, 0x72, 0x41, 0xef, 0x77, 0x9f, 0xbb,
- 0x39, 0x0f, 0xb9, 0x90, 0xd7, 0x7d, 0xd3, 0xfd, 0xd5, 0xfd, 0x44, 0xdf,
- 0x53, 0x3d, 0x64, 0xd6, 0x5f, 0xe8, 0x21, 0x9c, 0xe7, 0x0b, 0xeb, 0xee,
- 0x77, 0xf2, 0xc9, 0xac, 0xb2, 0x7f, 0x4d, 0x7c, 0x43, 0xf3, 0x28, 0xc4,
- 0xf7, 0x2c, 0xab, 0x7c, 0x29, 0xf8, 0xaf, 0x96, 0x77, 0x0d, 0x71, 0x3d,
- 0xc8, 0xcb, 0x7d, 0x7a, 0xee, 0xdc, 0xf3, 0x5b, 0xad, 0xbb, 0x3a, 0xc7,
- 0x13, 0x1e, 0xfc, 0xa4, 0xcf, 0xa9, 0xec, 0xf3, 0x8c, 0x5f, 0x53, 0x0c,
- 0x1d, 0xc1, 0xfb, 0xb0, 0x21, 0x8c, 0x39, 0x69, 0x08, 0x7b, 0xdd, 0xef,
- 0x12, 0x3f, 0x11, 0xfa, 0x05, 0xb3, 0xa7, 0x31, 0x42, 0xe7, 0xba, 0x74,
- 0xe3, 0x6b, 0x32, 0x7b, 0x7f, 0x29, 0x86, 0xf5, 0x96, 0x21, 0x84, 0x09,
- 0x10, 0xde, 0x0d, 0x71, 0x01, 0xf3, 0xf0, 0xce, 0x02, 0xe4, 0xdb, 0xe2,
- 0x49, 0xf8, 0x69, 0x9c, 0xa5, 0xfb, 0xd4, 0x6c, 0x41, 0x79, 0x4b, 0x4b,
- 0x8c, 0xf3, 0xb4, 0x9f, 0x7e, 0xaf, 0x56, 0x44, 0x9c, 0x7f, 0x47, 0xf0,
- 0xbc, 0x02, 0xcf, 0x81, 0x9a, 0xbe, 0xef, 0x14, 0xdf, 0x4a, 0x8f, 0x4b,
- 0xfc, 0xc2, 0x0d, 0xe3, 0xdc, 0xac, 0xc7, 0xb9, 0xee, 0x6f, 0xda, 0xef,
- 0x89, 0xeb, 0x81, 0xcd, 0xb8, 0xd6, 0xf9, 0xa9, 0x3a, 0xff, 0xe9, 0xbc,
- 0x7b, 0x37, 0xfb, 0x57, 0xfb, 0x62, 0x12, 0xdf, 0xff, 0x17, 0xae, 0x21,
- 0x8f, 0x76, 0xa9, 0xf8, 0x2d, 0x35, 0xf8, 0xf4, 0x9e, 0x3b, 0xf0, 0x9b,
- 0x21, 0x79, 0xfc, 0x6f, 0x6a, 0x8c, 0x09, 0xd0, 0x18, 0x10, 0x00, 0x00,
- 0x00 };
-
-static u8 bnx2_TPAT_b09FwText[] = {
- 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0x73, 0xe7, 0xee, 0xee,
- 0x78, 0xb1, 0xe3, 0x71, 0x3b, 0xa4, 0xdb, 0x62, 0xc8, 0x8c, 0x7d, 0xfd,
- 0x03, 0xb6, 0xc2, 0x94, 0x6e, 0xdb, 0xad, 0x18, 0x45, 0xc3, 0xec, 0xda,
- 0xb1, 0xa2, 0x3c, 0xb8, 0x52, 0xa4, 0x46, 0x6a, 0x04, 0x66, 0x1d, 0x93,
- 0x3e, 0xa6, 0x88, 0x07, 0xa4, 0x3e, 0x64, 0x59, 0x3b, 0xa9, 0x1f, 0x96,
- 0x2c, 0xb8, 0xc8, 0x7e, 0x41, 0x28, 0x72, 0x6a, 0xbb, 0x48, 0x8b, 0x37,
- 0x11, 0x48, 0x3c, 0x45, 0x8d, 0x1c, 0x14, 0x55, 0xea, 0x0b, 0x0f, 0xfc,
- 0x3d, 0x46, 0x6a, 0x45, 0xfb, 0x50, 0x90, 0x55, 0xa9, 0xa8, 0x82, 0xe0,
- 0xcb, 0x77, 0x66, 0x67, 0x9c, 0x4d, 0xec, 0x08, 0x9e, 0xb0, 0xb4, 0xba,
- 0x33, 0x73, 0xef, 0x39, 0xf7, 0xdc, 0x73, 0xbe, 0xef, 0x9c, 0x73, 0x3d,
- 0x64, 0x50, 0x9e, 0x92, 0xbf, 0x3e, 0xfc, 0x8a, 0xdf, 0xbd, 0xf8, 0x83,
- 0x67, 0x8f, 0xbf, 0x70, 0x1c, 0x8f, 0xcf, 0x1b, 0xfd, 0x59, 0x49, 0xff,
- 0xc7, 0x3f, 0x93, 0xc8, 0x4e, 0xed, 0xe0, 0x1f, 0x59, 0x22, 0xb8, 0xfd,
- 0x54, 0xa4, 0xc8, 0x32, 0x83, 0xdf, 0x7c, 0x6d, 0x5e, 0x11, 0x85, 0xad,
- 0x09, 0xb7, 0x4c, 0xff, 0xd6, 0x35, 0x47, 0x12, 0x7f, 0xff, 0x72, 0x70,
- 0xff, 0xeb, 0xb7, 0x5e, 0xf4, 0x76, 0xaf, 0x99, 0x64, 0xd9, 0xc1, 0xb2,
- 0xb4, 0x47, 0xc9, 0x1a, 0x84, 0xcc, 0xcf, 0xc7, 0xbe, 0x2d, 0xe8, 0x48,
- 0xaa, 0xab, 0xa6, 0x85, 0xba, 0xa7, 0x6f, 0x8d, 0x29, 0xbb, 0x8e, 0x0d,
- 0x6e, 0xb4, 0x5d, 0x8a, 0xda, 0x05, 0x7a, 0xb7, 0xed, 0xd0, 0xcd, 0xb6,
- 0xa4, 0x85, 0xb7, 0x2e, 0xd1, 0x92, 0xef, 0x15, 0x2a, 0xa6, 0x45, 0x22,
- 0xf0, 0x0a, 0x55, 0x72, 0x69, 0xc3, 0xf7, 0x6a, 0x73, 0xe6, 0x80, 0x61,
- 0x05, 0x16, 0xbd, 0x31, 0x26, 0xe8, 0x9a, 0x73, 0x8e, 0xbe, 0xa7, 0xce,
- 0xe2, 0x27, 0x49, 0xac, 0x48, 0xa3, 0xbc, 0x26, 0x49, 0xae, 0xf4, 0xd3,
- 0x49, 0x5f, 0xeb, 0x79, 0x3f, 0x84, 0xfc, 0xf0, 0xf8, 0x05, 0xea, 0xa1,
- 0x9a, 0xed, 0xcd, 0x10, 0x65, 0x78, 0x0d, 0x45, 0x7e, 0x86, 0x42, 0xbb,
- 0x73, 0xae, 0x6b, 0xf1, 0x78, 0x5f, 0x6f, 0x40, 0xbe, 0x47, 0xa5, 0xf3,
- 0x4f, 0x24, 0xf3, 0x76, 0x32, 0x2f, 0x48, 0xac, 0x7a, 0xee, 0x16, 0x8d,
- 0x84, 0xd2, 0xd8, 0xd3, 0x91, 0x3a, 0x6a, 0x47, 0x5b, 0x92, 0xcc, 0x15,
- 0xb6, 0x5f, 0xd9, 0x65, 0xd2, 0x90, 0x31, 0x59, 0x46, 0x8a, 0xe0, 0xfb,
- 0x88, 0xdb, 0x48, 0x28, 0x0c, 0xa2, 0x9d, 0x46, 0xc1, 0x8e, 0xda, 0x3f,
- 0x34, 0xa2, 0xe6, 0x9e, 0x0e, 0x65, 0x9e, 0x84, 0x0a, 0x8d, 0x68, 0x8b,
- 0x75, 0xf5, 0x90, 0x54, 0x39, 0xc8, 0x0c, 0xdb, 0x82, 0x78, 0x8c, 0x92,
- 0xef, 0xac, 0xbb, 0x82, 0xe7, 0x69, 0x23, 0xdc, 0x92, 0x46, 0xb4, 0x36,
- 0x83, 0x67, 0x0b, 0xf2, 0xf0, 0x8b, 0x6f, 0x50, 0x38, 0x6b, 0x40, 0x8e,
- 0xcf, 0x69, 0xe3, 0x5d, 0x50, 0xe8, 0xd8, 0xb4, 0x58, 0xf4, 0x0a, 0x35,
- 0x3a, 0x65, 0x94, 0xb7, 0x0e, 0x04, 0xcd, 0x9e, 0x69, 0x1f, 0xfc, 0xc6,
- 0xb6, 0x7c, 0x4b, 0x6a, 0x2d, 0x9e, 0xcd, 0x25, 0x67, 0x64, 0x7d, 0x61,
- 0xc7, 0x7e, 0x87, 0xdf, 0x61, 0x73, 0x13, 0xb6, 0xb7, 0xb2, 0xb0, 0x47,
- 0x6b, 0xde, 0x27, 0x52, 0x65, 0xd8, 0x19, 0xe2, 0xe7, 0x2d, 0x57, 0x01,
- 0x85, 0xa1, 0xd5, 0x3e, 0x72, 0x07, 0xb4, 0xae, 0xf8, 0x9e, 0xbd, 0x45,
- 0x01, 0x2d, 0x36, 0x07, 0xed, 0xa9, 0x66, 0x1d, 0xf3, 0x35, 0x5e, 0x03,
- 0x7f, 0x10, 0x4d, 0xb5, 0xb4, 0xde, 0xf4, 0x7f, 0x9b, 0xa1, 0x23, 0x62,
- 0x32, 0x43, 0x9e, 0x1b, 0xe2, 0xdb, 0xd0, 0xe6, 0xa3, 0x3e, 0x3b, 0x96,
- 0xd8, 0xc0, 0x7e, 0xc7, 0x3e, 0xfe, 0x97, 0x92, 0xf7, 0x5e, 0x3b, 0x5a,
- 0x4b, 0xfd, 0x1c, 0xdb, 0x0d, 0xbf, 0xfa, 0x14, 0x15, 0x61, 0xff, 0x63,
- 0xcf, 0x94, 0xca, 0xb1, 0x2d, 0x6c, 0x37, 0xd6, 0xab, 0x07, 0x36, 0xbd,
- 0x7a, 0xc0, 0x26, 0xb6, 0x47, 0x90, 0x5c, 0xb5, 0x68, 0x49, 0x7d, 0x64,
- 0xd0, 0x11, 0xad, 0x97, 0x7c, 0x69, 0x54, 0xd6, 0x3e, 0x4b, 0x9e, 0x81,
- 0xc3, 0x26, 0x70, 0xd8, 0x04, 0x2e, 0x9b, 0x64, 0x8b, 0xc0, 0xa5, 0x5b,
- 0x63, 0x16, 0xdd, 0x33, 0x11, 0xcf, 0x36, 0xcf, 0xe7, 0xa8, 0xee, 0x2b,
- 0xba, 0xdc, 0x64, 0xcf, 0xe4, 0x68, 0x51, 0x7d, 0xae, 0xcf, 0xc3, 0x1f,
- 0x6f, 0x93, 0x3e, 0x16, 0x01, 0xb3, 0x11, 0xdc, 0xf9, 0x86, 0x1a, 0xa7,
- 0xcb, 0x6d, 0x45, 0xf5, 0x36, 0xcb, 0x2d, 0x51, 0x47, 0xae, 0x1f, 0x72,
- 0x93, 0x90, 0x2b, 0xd2, 0x95, 0x58, 0xb6, 0x1f, 0xb2, 0xbb, 0x89, 0xec,
- 0x44, 0x61, 0x9a, 0x7c, 0xc8, 0x0c, 0xbb, 0xd3, 0xc0, 0xdc, 0x9c, 0x33,
- 0x09, 0xd9, 0x49, 0x5a, 0xc2, 0xaf, 0xde, 0xa4, 0x9a, 0x2c, 0xb2, 0x5e,
- 0xaf, 0x70, 0x9e, 0x7d, 0x1e, 0xeb, 0xac, 0x41, 0xa7, 0x83, 0x39, 0x0b,
- 0x7a, 0x24, 0xc6, 0x0f, 0x75, 0xbd, 0x09, 0x6c, 0x3b, 0xfc, 0xfc, 0xae,
- 0x16, 0x01, 0xfc, 0x50, 0x54, 0x6e, 0x9d, 0xf8, 0x3d, 0x4b, 0x65, 0xc4,
- 0x52, 0xa8, 0x7e, 0xaa, 0xda, 0x86, 0x21, 0x02, 0x93, 0xaa, 0xf0, 0x42,
- 0x38, 0x2b, 0xe3, 0x6f, 0x73, 0xb6, 0x01, 0x8e, 0x1d, 0x17, 0x9d, 0x9c,
- 0x93, 0xc1, 0x1a, 0xc4, 0x5f, 0xf5, 0x52, 0xd5, 0x19, 0xc0, 0x5a, 0x10,
- 0x2d, 0x3f, 0x02, 0x8e, 0x0e, 0x60, 0x0d, 0x8f, 0x1c, 0x07, 0xac, 0x57,
- 0xbc, 0xbe, 0x17, 0x36, 0xa6, 0xdf, 0x7a, 0xa9, 0xf6, 0x50, 0x7c, 0xd8,
- 0xc6, 0x38, 0x2e, 0xd8, 0x5f, 0x26, 0xb1, 0xed, 0x8e, 0x57, 0x3a, 0x6f,
- 0x63, 0x7e, 0xe7, 0xab, 0x82, 0x76, 0xf5, 0x75, 0x15, 0x15, 0xf0, 0xe9,
- 0xf3, 0x8a, 0x0a, 0x07, 0xcc, 0x18, 0x4b, 0x29, 0xa6, 0x78, 0xe4, 0x7c,
- 0x43, 0x85, 0x79, 0x65, 0x98, 0x4b, 0x93, 0x4f, 0x52, 0xcd, 0xf1, 0xfc,
- 0x32, 0x15, 0x68, 0xa9, 0x39, 0x01, 0xdf, 0xf5, 0xe3, 0xdc, 0x9e, 0x4f,
- 0x34, 0x8c, 0xe7, 0xf0, 0x69, 0xc8, 0x20, 0x5f, 0xd4, 0xa0, 0x8b, 0xc7,
- 0x41, 0xe8, 0xf7, 0x60, 0x23, 0xfc, 0xa1, 0x26, 0xec, 0x29, 0xf8, 0x23,
- 0x74, 0x78, 0x8e, 0xf3, 0x98, 0xf3, 0x4c, 0xa4, 0x3c, 0xbf, 0x1a, 0xdb,
- 0xe2, 0xd9, 0xb7, 0x89, 0xf3, 0x51, 0x9a, 0x83, 0x38, 0x27, 0x59, 0x73,
- 0x32, 0xa0, 0xd9, 0x7a, 0xe3, 0x92, 0x36, 0x15, 0xcd, 0x65, 0x03, 0xc6,
- 0x6e, 0x6f, 0x09, 0x58, 0x9c, 0xad, 0xb7, 0x06, 0x4f, 0xef, 0x34, 0xa8,
- 0xf6, 0x4c, 0x20, 0x8e, 0x0a, 0xec, 0x1f, 0xf9, 0xcc, 0x29, 0xec, 0xd5,
- 0x1e, 0x3c, 0x7d, 0xa7, 0x71, 0x0c, 0xbe, 0xa2, 0xfb, 0xf0, 0x3f, 0xf6,
- 0xdf, 0x79, 0xda, 0x84, 0x9d, 0x1c, 0x33, 0x70, 0x2b, 0x7c, 0x75, 0xcc,
- 0x00, 0x96, 0xf1, 0x0c, 0x6c, 0xd4, 0xda, 0x83, 0x73, 0x22, 0xa8, 0x51,
- 0xd8, 0x5e, 0xc2, 0xcf, 0xa2, 0xa9, 0x86, 0x65, 0xdd, 0x81, 0x4e, 0x51,
- 0xf4, 0xdc, 0xc8, 0xdc, 0x65, 0xae, 0xf0, 0x39, 0x58, 0x97, 0x65, 0x04,
- 0xae, 0x1c, 0x6a, 0xf5, 0xbc, 0x22, 0x82, 0x00, 0x98, 0x90, 0x88, 0x4d,
- 0x11, 0x58, 0xe1, 0x38, 0x5c, 0x45, 0x1c, 0x80, 0x03, 0xd8, 0x0c, 0xff,
- 0xd7, 0x44, 0x70, 0x91, 0x2a, 0x45, 0xa2, 0xc5, 0x06, 0x61, 0x3f, 0xec,
- 0x55, 0xc2, 0x0f, 0x78, 0x0e, 0xed, 0x12, 0x6c, 0xf0, 0xc2, 0x1a, 0x79,
- 0xfe, 0x1c, 0xbc, 0x9e, 0xfb, 0x31, 0x59, 0x99, 0xe0, 0x9c, 0xdc, 0x68,
- 0x90, 0x25, 0x83, 0xb3, 0x72, 0xa9, 0x31, 0xec, 0xff, 0x15, 0xbe, 0x26,
- 0xf2, 0xc6, 0x37, 0x69, 0xc2, 0xdf, 0x04, 0x6f, 0xeb, 0xf8, 0x5d, 0x21,
- 0xde, 0xfb, 0x9c, 0x1c, 0x69, 0xf1, 0x78, 0x56, 0xaa, 0x56, 0xb7, 0xde,
- 0xbf, 0x69, 0xf6, 0xfb, 0x3d, 0x2a, 0xd1, 0x9b, 0xc9, 0xde, 0xf0, 0x0d,
- 0x9d, 0x6c, 0x94, 0x80, 0xef, 0x03, 0xfa, 0x4b, 0xa9, 0xfe, 0xad, 0x58,
- 0x37, 0x63, 0x77, 0xc2, 0xdf, 0x3a, 0x74, 0x8f, 0xa3, 0x69, 0x7e, 0x42,
- 0x1e, 0xec, 0xe4, 0xeb, 0xc5, 0x66, 0x0e, 0x9c, 0xd0, 0xba, 0xaa, 0x7e,
- 0x8f, 0xf3, 0xe6, 0x81, 0x5f, 0x1b, 0x3f, 0xc4, 0x72, 0x96, 0xe7, 0x0c,
- 0xaa, 0xa2, 0x0e, 0xd5, 0xdb, 0xfc, 0xcc, 0x73, 0x9c, 0xcf, 0x72, 0x18,
- 0xff, 0x8c, 0xb5, 0x1f, 0xea, 0x5a, 0x9b, 0xb9, 0xc6, 0xbe, 0x02, 0x47,
- 0xda, 0x96, 0x51, 0x6e, 0x92, 0x51, 0x69, 0x92, 0x5b, 0xf5, 0x65, 0x1c,
- 0x97, 0xd0, 0xb6, 0xe1, 0x53, 0xc6, 0xc3, 0xa4, 0x8c, 0x1a, 0x46, 0x5c,
- 0xc3, 0x0c, 0x3c, 0x0f, 0xb5, 0x7e, 0x9d, 0x01, 0x27, 0x42, 0xf8, 0x5f,
- 0x2c, 0x20, 0x47, 0x5e, 0x73, 0xa8, 0x5f, 0xa8, 0x39, 0x51, 0x77, 0xa8,
- 0x4f, 0x28, 0xb6, 0xed, 0x3d, 0x01, 0xdb, 0x78, 0x3e, 0xac, 0xfa, 0xbf,
- 0xc2, 0x9e, 0x41, 0xcc, 0xc7, 0x4a, 0x23, 0xcd, 0xfb, 0xd0, 0xa9, 0x38,
- 0x67, 0x58, 0x49, 0xfe, 0x8f, 0x92, 0xdc, 0x2e, 0x81, 0x5b, 0xad, 0x5f,
- 0x46, 0x5e, 0xaf, 0xc7, 0xb8, 0xf1, 0x6a, 0xae, 0xd8, 0xd3, 0xc3, 0xa3,
- 0xcc, 0x51, 0xad, 0x2f, 0xfa, 0xd3, 0x58, 0x2b, 0x4d, 0xca, 0xcf, 0x20,
- 0xb7, 0x73, 0x3d, 0x60, 0xdb, 0x02, 0xd8, 0xd6, 0xd7, 0xc9, 0xfb, 0xa8,
- 0x09, 0xf5, 0xb8, 0x06, 0xf4, 0x90, 0xa9, 0x0c, 0xfc, 0x3c, 0x77, 0x8e,
- 0xf8, 0x3b, 0xf5, 0x08, 0xbc, 0x57, 0xc1, 0xeb, 0xa5, 0xe2, 0x29, 0xa3,
- 0xb2, 0x75, 0xcc, 0x4c, 0xfa, 0x08, 0xd8, 0x0d, 0x5e, 0x3b, 0x2c, 0x97,
- 0x85, 0x5c, 0x1f, 0x64, 0xbe, 0x82, 0xb9, 0x0c, 0xc6, 0x6e, 0x3d, 0x71,
- 0x2d, 0xc1, 0x5e, 0x2e, 0xf6, 0x9a, 0x21, 0x19, 0xe4, 0x51, 0xaf, 0x47,
- 0xdc, 0x0a, 0x3d, 0x97, 0xd4, 0x6d, 0xe6, 0xf2, 0x89, 0x2e, 0x2e, 0xbb,
- 0x64, 0xc6, 0x9c, 0x78, 0x29, 0xc9, 0x41, 0x9c, 0xc7, 0x5f, 0x48, 0xe6,
- 0x1d, 0xe4, 0xe3, 0xe7, 0x92, 0xba, 0x62, 0xe1, 0x39, 0xa0, 0xe5, 0x38,
- 0x37, 0x67, 0x39, 0x37, 0x17, 0x90, 0x9b, 0x4b, 0xe0, 0xa7, 0xff, 0x31,
- 0x19, 0xc8, 0x4d, 0x44, 0xbf, 0x6b, 0x48, 0xe4, 0x21, 0x13, 0xf2, 0xdc,
- 0x1b, 0xcc, 0xc1, 0x36, 0xcf, 0xfe, 0x18, 0x67, 0x0a, 0xcf, 0x70, 0xde,
- 0xd4, 0x3a, 0x13, 0x28, 0xf7, 0x32, 0x8d, 0x16, 0x2e, 0x23, 0x4f, 0x9a,
- 0x34, 0x81, 0xdd, 0x78, 0xdf, 0xb4, 0x96, 0xa7, 0x3d, 0x05, 0xff, 0xbd,
- 0x6f, 0x90, 0xe2, 0xfa, 0xfb, 0x1d, 0xe8, 0x18, 0x71, 0xa7, 0xc0, 0xfb,
- 0xc5, 0xd2, 0x7f, 0x93, 0xf9, 0x43, 0x22, 0x83, 0xba, 0x56, 0xe4, 0x7d,
- 0x89, 0x2a, 0x2d, 0xf6, 0x83, 0xdf, 0x85, 0x07, 0x1f, 0x78, 0x20, 0xaa,
- 0x36, 0xc1, 0x3f, 0xc4, 0x38, 0xc6, 0x1a, 0xd6, 0x8b, 0x22, 0x72, 0xaa,
- 0xc3, 0xb8, 0x66, 0xbc, 0x9f, 0x49, 0xf0, 0x3e, 0x0b, 0xbc, 0x7b, 0xe3,
- 0x37, 0xc0, 0xa3, 0x1b, 0x0f, 0xf1, 0xe8, 0x4c, 0x82, 0xf1, 0x59, 0x60,
- 0xfc, 0x97, 0xc0, 0x96, 0x85, 0x9a, 0x0e, 0xdc, 0x36, 0xc8, 0x88, 0x50,
- 0x1b, 0x80, 0x83, 0x44, 0xcf, 0xe9, 0x44, 0xcf, 0xcc, 0x63, 0xf4, 0x9c,
- 0x4e, 0xf4, 0xcc, 0x74, 0xeb, 0x81, 0x5c, 0x25, 0x91, 0x0b, 0x1f, 0x23,
- 0x57, 0x49, 0xe4, 0xc2, 0x2e, 0x39, 0x0b, 0x67, 0xe2, 0x73, 0x71, 0x1e,
- 0xdb, 0x45, 0x2c, 0x7c, 0x8a, 0xb1, 0x62, 0x87, 0x18, 0xef, 0x61, 0x04,
- 0x66, 0x9a, 0x37, 0xb1, 0x96, 0xfd, 0x90, 0x61, 0x0e, 0x3c, 0xe2, 0xbb,
- 0x3d, 0xf8, 0x6e, 0x1f, 0xef, 0xf8, 0xfb, 0x66, 0x82, 0x15, 0xae, 0x45,
- 0x5e, 0x2d, 0x7c, 0x68, 0x6d, 0x46, 0xb0, 0x9f, 0xc5, 0xd5, 0xc3, 0x62,
- 0x60, 0x61, 0x0e, 0x35, 0xa7, 0x69, 0x52, 0x59, 0x32, 0x57, 0x5f, 0x91,
- 0x31, 0x76, 0xb7, 0xb1, 0x7e, 0xbb, 0xc3, 0xab, 0x99, 0x46, 0x8e, 0x68,
- 0xbd, 0x97, 0x16, 0x50, 0x4f, 0xce, 0x03, 0x4b, 0xd7, 0x7d, 0xb0, 0x90,
- 0x86, 0x81, 0x0b, 0x0d, 0x5c, 0x7b, 0x71, 0x6c, 0x23, 0xb5, 0x08, 0x66,
- 0xfc, 0x88, 0x76, 0x26, 0xf3, 0x94, 0xd9, 0xec, 0xd4, 0x43, 0xb9, 0xde,
- 0xbd, 0x8f, 0x8b, 0x7d, 0x02, 0xd4, 0xe0, 0x3f, 0xa2, 0x17, 0x70, 0x48,
- 0x8e, 0x22, 0x97, 0x36, 0x39, 0x27, 0x80, 0xa3, 0x9b, 0x5c, 0xeb, 0x39,
- 0xe7, 0x5a, 0xc0, 0x62, 0x9a, 0x7f, 0x72, 0xe8, 0x5b, 0x3e, 0x41, 0xed,
- 0x10, 0x34, 0x5f, 0xd4, 0x7a, 0xca, 0xff, 0x04, 0xb8, 0xc2, 0xb7, 0x75,
- 0x9e, 0xdb, 0xc5, 0x77, 0xfe, 0x66, 0x51, 0x76, 0xf5, 0x49, 0xec, 0x89,
- 0xfd, 0xce, 0xf0, 0xfa, 0x1c, 0x7a, 0x1a, 0xce, 0xf3, 0x18, 0xd7, 0xf9,
- 0xdd, 0x48, 0x7c, 0x6a, 0x62, 0xfc, 0x02, 0x46, 0x3e, 0x4f, 0x0f, 0xce,
- 0xa7, 0xf5, 0x5d, 0x9f, 0x9f, 0xb5, 0x96, 0x41, 0x2f, 0x95, 0x1b, 0x0a,
- 0xf5, 0x7d, 0xa4, 0xb0, 0x00, 0x9e, 0x95, 0x5b, 0xe9, 0x3c, 0xcf, 0xd9,
- 0x5d, 0x73, 0x78, 0x6e, 0xf1, 0x77, 0x41, 0x3b, 0x6a, 0x11, 0x75, 0x11,
- 0xfd, 0xd3, 0x3a, 0xf7, 0x61, 0xdc, 0x53, 0xc5, 0xf5, 0x72, 0x9c, 0x7b,
- 0xb0, 0x77, 0x90, 0xff, 0xd7, 0xc1, 0x29, 0xf0, 0xfb, 0x29, 0x41, 0x4f,
- 0x50, 0xd9, 0x49, 0xcf, 0xa3, 0x35, 0x38, 0x5b, 0x30, 0x0d, 0xe6, 0xe2,
- 0xb0, 0x3d, 0x4d, 0xdc, 0x6b, 0x8d, 0x84, 0x55, 0x96, 0x69, 0x21, 0x1f,
- 0xac, 0x68, 0xaa, 0x76, 0xf4, 0xd8, 0xb3, 0xc8, 0xd1, 0xd1, 0x4f, 0xb8,
- 0xb6, 0xb1, 0x6f, 0x4f, 0xc0, 0x1e, 0xf4, 0x05, 0xeb, 0x92, 0xde, 0x6e,
- 0xb0, 0x9e, 0x3c, 0x99, 0xe8, 0x11, 0x97, 0xfd, 0x54, 0xcf, 0x9f, 0xa0,
- 0x87, 0x1c, 0x41, 0xdc, 0xff, 0x4a, 0xe8, 0x62, 0x1f, 0x64, 0xd0, 0x8f,
- 0x8f, 0xd3, 0xbc, 0x5a, 0x8c, 0x6b, 0xf1, 0x79, 0xd4, 0xde, 0xa8, 0x98,
- 0x85, 0xef, 0x72, 0xb1, 0x9e, 0x7a, 0xf3, 0x5f, 0x9a, 0xf3, 0x0f, 0xea,
- 0x24, 0xf4, 0xe3, 0xbd, 0x8d, 0xb9, 0x95, 0x80, 0xde, 0x6c, 0xc6, 0xb5,
- 0xdb, 0xbe, 0x88, 0x9e, 0xbf, 0xd2, 0xf8, 0x47, 0xda, 0xcb, 0x84, 0xc0,
- 0x71, 0xe1, 0x02, 0x7c, 0x23, 0xb7, 0x7b, 0xe9, 0x35, 0xf4, 0xa8, 0x99,
- 0x15, 0xd4, 0x65, 0xf8, 0x4d, 0x5c, 0xad, 0x8d, 0x73, 0x9f, 0x79, 0x03,
- 0x5c, 0x9f, 0x2f, 0x2a, 0xdf, 0x34, 0x46, 0x69, 0xf9, 0x67, 0x5c, 0x67,
- 0xe2, 0x7a, 0x0d, 0xfc, 0xb8, 0x74, 0xa5, 0xa5, 0x68, 0xb9, 0x65, 0xc3,
- 0x2e, 0xfb, 0x41, 0x2f, 0xae, 0x38, 0x1f, 0x57, 0xf0, 0x8b, 0xf3, 0x2d,
- 0xce, 0x04, 0x3e, 0x04, 0xec, 0x0f, 0xee, 0xbd, 0x39, 0x66, 0x9c, 0xff,
- 0x4e, 0xe1, 0x99, 0xcf, 0xca, 0xbd, 0x32, 0xfb, 0x81, 0x7b, 0xe2, 0xee,
- 0xfe, 0x9d, 0x73, 0x23, 0x74, 0x6e, 0x33, 0x87, 0xb8, 0x47, 0xa9, 0xc8,
- 0xf9, 0x86, 0x1d, 0xf3, 0xaa, 0xde, 0xee, 0xf8, 0x3b, 0xf2, 0x59, 0xa7,
- 0x57, 0x0a, 0xe9, 0xce, 0x8b, 0x22, 0xee, 0x3b, 0x42, 0xe4, 0x15, 0x3e,
- 0xcb, 0x04, 0xee, 0x27, 0x1e, 0x7c, 0xe7, 0xa1, 0x2f, 0xe9, 0xf0, 0x73,
- 0x38, 0xe1, 0xe7, 0x50, 0xeb, 0x44, 0x26, 0xed, 0xc7, 0x0e, 0x72, 0xee,
- 0x17, 0xe2, 0x7f, 0xe7, 0xdc, 0x46, 0xc2, 0xb9, 0x6c, 0x8c, 0x4d, 0xb1,
- 0xd2, 0x3d, 0xf7, 0x0e, 0xe6, 0x72, 0x5d, 0xf7, 0xa2, 0xc3, 0x62, 0x12,
- 0xf3, 0x03, 0x9c, 0xe4, 0x75, 0x88, 0xff, 0x4a, 0x2f, 0x99, 0x57, 0x99,
- 0x97, 0x29, 0x46, 0x5c, 0xe0, 0x31, 0xd5, 0xd1, 0x83, 0x3d, 0x70, 0xd7,
- 0x59, 0xcd, 0xc4, 0xf8, 0x37, 0x83, 0x74, 0x4d, 0x81, 0xa6, 0x1b, 0x9e,
- 0x7f, 0x87, 0xc7, 0x16, 0xcf, 0x4b, 0xca, 0xae, 0x58, 0xf4, 0xfa, 0x98,
- 0xe7, 0xba, 0xc2, 0xf3, 0x77, 0x60, 0xf7, 0x5d, 0xe5, 0x50, 0x66, 0x94,
- 0x39, 0xc9, 0x15, 0x2a, 0x0b, 0xdc, 0xe0, 0x0e, 0xd8, 0xd4, 0x97, 0xd0,
- 0x1f, 0xb9, 0x12, 0xb1, 0xfd, 0x29, 0x6c, 0xe1, 0x7c, 0x0b, 0xbb, 0xc6,
- 0xd7, 0x81, 0x83, 0x05, 0x7e, 0xdf, 0xc7, 0x18, 0xdf, 0x2d, 0x78, 0x7f,
- 0x07, 0x67, 0xb0, 0x28, 0xb7, 0xaa, 0x71, 0xf7, 0x7b, 0x20, 0x77, 0x25,
- 0xc1, 0x6b, 0x06, 0xdf, 0xe7, 0x63, 0xbc, 0x72, 0x1c, 0xd9, 0xe7, 0x5a,
- 0x7f, 0x80, 0x38, 0x96, 0xe9, 0x2f, 0x31, 0x8f, 0xef, 0xfa, 0x31, 0x7e,
- 0x61, 0x0f, 0x64, 0x5a, 0x9f, 0xca, 0x98, 0xe7, 0xe0, 0xc3, 0x65, 0x3f,
- 0xc6, 0xd7, 0xf8, 0x4d, 0x1c, 0xbb, 0x83, 0xfd, 0x6e, 0x3d, 0xc3, 0xf6,
- 0x49, 0x8a, 0x39, 0xe5, 0x2e, 0x72, 0x8f, 0xe9, 0x8f, 0x20, 0xdf, 0x62,
- 0x5d, 0x2b, 0xe5, 0x7d, 0x16, 0x7c, 0x67, 0x5f, 0x33, 0xf7, 0x07, 0x92,
- 0xe7, 0x2f, 0x22, 0xb6, 0x36, 0xfc, 0xd8, 0xe9, 0x05, 0xcc, 0x15, 0xb6,
- 0xad, 0x97, 0xd4, 0xd5, 0xd4, 0xae, 0x4f, 0x63, 0x7b, 0x1e, 0xd6, 0x89,
- 0xf9, 0xed, 0xc3, 0xe4, 0xec, 0x2e, 0xb9, 0xbf, 0x1f, 0x22, 0x87, 0xf9,
- 0x6d, 0x96, 0xc9, 0xef, 0xf7, 0x20, 0xe5, 0x7d, 0x3c, 0x87, 0xc0, 0x3b,
- 0xcb, 0x3e, 0x7a, 0xef, 0xec, 0xc6, 0x7e, 0x5a, 0xfb, 0x19, 0xdf, 0xbc,
- 0xa7, 0xe7, 0x72, 0xef, 0xde, 0xc1, 0x76, 0x1e, 0x79, 0x2f, 0xf6, 0x03,
- 0x72, 0xa6, 0x37, 0x3e, 0x47, 0x29, 0xfe, 0x1f, 0x60, 0x7c, 0x01, 0x76,
- 0x55, 0x68, 0xa2, 0xc4, 0xe3, 0xc9, 0x03, 0x18, 0xe7, 0xfb, 0x3a, 0xd7,
- 0xa6, 0x3c, 0xee, 0x61, 0x5c, 0xe7, 0xf9, 0x2e, 0xd6, 0xc9, 0x53, 0x95,
- 0x35, 0x7e, 0xff, 0x2c, 0x79, 0xe7, 0xbc, 0xcc, 0x7d, 0xd4, 0x0d, 0x9c,
- 0x9f, 0xeb, 0xd1, 0x18, 0xd5, 0x1d, 0xf8, 0xd5, 0x67, 0x1b, 0x2e, 0xd0,
- 0x83, 0x1e, 0xec, 0xb0, 0xba, 0xb2, 0x6a, 0x76, 0x71, 0xe5, 0xb0, 0x7e,
- 0x8c, 0xef, 0x27, 0x46, 0x79, 0xcd, 0x48, 0x7a, 0x78, 0xee, 0xbf, 0xf6,
- 0xb4, 0x19, 0xf7, 0x62, 0x9c, 0x17, 0xb8, 0x07, 0x7b, 0x0d, 0xfb, 0xf6,
- 0xc5, 0xef, 0xe1, 0x16, 0x8f, 0xec, 0x17, 0x8a, 0x79, 0xd1, 0xe1, 0x79,
- 0x6a, 0x77, 0x84, 0x75, 0xf0, 0x8f, 0x88, 0x52, 0x9b, 0xa8, 0xfa, 0x16,
- 0xd7, 0x54, 0x3b, 0xc9, 0xff, 0x17, 0x31, 0x3e, 0x9f, 0x60, 0x20, 0x3d,
- 0x4b, 0xec, 0x57, 0xec, 0xaf, 0xf5, 0x2c, 0x30, 0xf5, 0xba, 0x9f, 0xda,
- 0x0a, 0x6c, 0x7f, 0x23, 0xcd, 0x31, 0x88, 0x97, 0xda, 0xd3, 0x72, 0x34,
- 0x84, 0x2d, 0xfc, 0xff, 0x82, 0x0a, 0x7a, 0x3b, 0xb6, 0x65, 0xc6, 0x78,
- 0x79, 0xff, 0x7f, 0x04, 0x8f, 0xf6, 0x71, 0x1c, 0x3f, 0x8e, 0xef, 0x7e,
- 0xfc, 0xac, 0x1c, 0x7c, 0xff, 0x51, 0xc3, 0xb3, 0x07, 0x04, 0xe7, 0x23,
- 0xb2, 0xb2, 0x88, 0xc1, 0x5d, 0xc4, 0x28, 0x24, 0xaf, 0xf4, 0x41, 0xdc,
- 0x9b, 0x13, 0x38, 0x37, 0x11, 0xe2, 0x19, 0x1c, 0xc0, 0xd9, 0x46, 0x3d,
- 0xff, 0x3d, 0xe2, 0x38, 0x58, 0xb8, 0x6b, 0x74, 0x62, 0x37, 0x96, 0xc4,
- 0x6e, 0xb4, 0xf5, 0xf0, 0x99, 0x5d, 0xf1, 0x52, 0xf2, 0xce, 0x67, 0xe2,
- 0x5e, 0xc1, 0xe5, 0x1e, 0x09, 0x3e, 0x28, 0x19, 0x9d, 0x7b, 0x7b, 0x93,
- 0xef, 0x97, 0x35, 0xce, 0xe5, 0xdc, 0xcf, 0x81, 0x6b, 0xa8, 0x96, 0x23,
- 0xb8, 0x6b, 0x68, 0x5d, 0x2f, 0x31, 0x76, 0x27, 0xc6, 0xa7, 0x62, 0x0c,
- 0x8b, 0x41, 0x41, 0x29, 0xb7, 0xba, 0x9f, 0x31, 0x96, 0xf8, 0x9e, 0xc6,
- 0xef, 0x1d, 0x1d, 0x1b, 0xc0, 0x1d, 0x6e, 0x32, 0xb8, 0x1d, 0xb2, 0x7e,
- 0xa3, 0xd3, 0x13, 0xdb, 0x11, 0xf3, 0x1e, 0xb8, 0x7b, 0x1f, 0x76, 0x85,
- 0xe0, 0x6d, 0xe7, 0x6e, 0x37, 0x87, 0x9c, 0x72, 0x1b, 0xb1, 0xbd, 0xab,
- 0x3a, 0x75, 0x71, 0x83, 0xfb, 0xae, 0x16, 0xf2, 0x4d, 0x1e, 0xbd, 0xb2,
- 0x4a, 0xef, 0xa2, 0x16, 0x5d, 0xc3, 0x9a, 0xeb, 0x98, 0xbb, 0xd2, 0x4a,
- 0x71, 0x84, 0x1e, 0x0f, 0xd8, 0x9c, 0x57, 0xff, 0xd4, 0x55, 0xa7, 0x7b,
- 0x2d, 0xff, 0xfd, 0x07, 0x5d, 0xe7, 0x92, 0xbb, 0xa8, 0x13, 0x00, 0x00,
- 0x00 };
-
-static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_TPAT_b09FwRodata[(0x4/4) + 1] = {
- 0x00000001, 0x00000000 };
-
-static struct fw_info bnx2_tpat_fw_09 = {
- /* Firmware version: 4.6.15 */
- .ver_major = 0x4,
- .ver_minor = 0x6,
- .ver_fix = 0xf,
-
- .start_addr = 0x08000488,
-
- .text_addr = 0x08000400,
- .text_len = 0x13a4,
- .text_index = 0x0,
- .gz_text = bnx2_TPAT_b09FwText,
- .gz_text_len = sizeof(bnx2_TPAT_b09FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_TPAT_b09FwData,
-
- .sbss_addr = 0x080017c0,
- .sbss_len = 0x40,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08001800,
- .bss_len = 0x12b4,
- .bss_index = 0x0,
-
- .rodata_addr = 0x080017a4,
- .rodata_len = 0x4,
- .rodata_index = 0x0,
- .rodata = bnx2_TPAT_b09FwRodata,
-};
-
-static u8 bnx2_TXP_b09FwText[] = {
- 0xc5, 0x7b, 0x7d, 0x70, 0x1b, 0xe7, 0x79, 0xe7, 0xef, 0xc5, 0x02, 0xe4,
- 0x02, 0x04, 0x41, 0x90, 0x82, 0x64, 0xf0, 0xca, 0x44, 0x58, 0x61, 0x41,
- 0xc1, 0x26, 0x2d, 0x2f, 0x28, 0x50, 0x82, 0xcb, 0x55, 0x85, 0x4a, 0xb4,
- 0x44, 0xc7, 0x74, 0x43, 0x3b, 0x6a, 0x4b, 0x67, 0x3c, 0x09, 0x2a, 0x51,
- 0x16, 0x2d, 0xcb, 0x16, 0xed, 0xf8, 0x7a, 0xec, 0x9c, 0x27, 0xda, 0x50,
- 0x1f, 0x96, 0x25, 0x10, 0x00, 0x3f, 0x64, 0xca, 0x9d, 0xce, 0x19, 0x26,
- 0x29, 0x51, 0xb6, 0xf1, 0x21, 0xc7, 0x4a, 0x6a, 0xcf, 0x24, 0x11, 0x4e,
- 0x96, 0x65, 0xd9, 0x89, 0x3f, 0x92, 0xf8, 0x7a, 0x4e, 0xa7, 0x37, 0xd5,
- 0x48, 0xfe, 0x90, 0x2c, 0xf9, 0xa3, 0x69, 0x6f, 0x2a, 0xb5, 0x4e, 0xf7,
- 0x9e, 0x67, 0x17, 0x94, 0x15, 0xd7, 0x9d, 0x9b, 0xf6, 0xfe, 0x38, 0xce,
- 0x70, 0x00, 0xec, 0xbe, 0xfb, 0xbe, 0xcf, 0xf7, 0xf3, 0x7b, 0x9e, 0xf7,
- 0xdd, 0x56, 0xc0, 0x83, 0xea, 0x5f, 0x3d, 0xfd, 0xc7, 0x87, 0x86, 0x1f,
- 0x8e, 0x2d, 0x5b, 0xb1, 0x8c, 0xbe, 0x76, 0xa2, 0xa1, 0xc6, 0xc9, 0x37,
- 0x57, 0x08, 0x20, 0xf5, 0x21, 0xfe, 0x43, 0x7f, 0x5f, 0xf9, 0x8f, 0x3d,
- 0x66, 0xfd, 0x49, 0x80, 0x7f, 0x9e, 0x2e, 0xfe, 0x87, 0xec, 0xd0, 0x93,
- 0x5d, 0x6b, 0x54, 0xc8, 0x92, 0x7e, 0x79, 0xd5, 0x26, 0x15, 0x48, 0x16,
- 0xda, 0x42, 0x6b, 0xf1, 0x1b, 0xd3, 0x08, 0x38, 0xc1, 0xd7, 0xbf, 0xa2,
- 0x7f, 0xb6, 0xe3, 0xc7, 0x2b, 0x95, 0x4f, 0xf3, 0x12, 0x64, 0xbf, 0x7e,
- 0x10, 0xfe, 0x56, 0xc8, 0x2d, 0xf4, 0xcc, 0x5f, 0x2c, 0x2d, 0x39, 0xe1,
- 0x9b, 0x9f, 0x0b, 0x86, 0x4b, 0xd7, 0xb0, 0x33, 0x3b, 0x84, 0x23, 0x71,
- 0xa0, 0x76, 0x34, 0xa2, 0xed, 0x04, 0x72, 0x0e, 0x3d, 0x12, 0x3a, 0x81,
- 0x10, 0x66, 0x0b, 0x2a, 0x1e, 0x2d, 0xc3, 0x70, 0xea, 0x21, 0x3c, 0x96,
- 0xfe, 0x17, 0x33, 0xe4, 0xe2, 0x47, 0x86, 0xb0, 0x8b, 0xc6, 0xee, 0x4e,
- 0x43, 0x0e, 0xea, 0x8f, 0x20, 0x98, 0x85, 0x5c, 0xaf, 0x0f, 0xa3, 0x38,
- 0x1a, 0x3e, 0x3d, 0x07, 0xa5, 0xaf, 0x59, 0x52, 0x86, 0x80, 0xb6, 0xd4,
- 0x5d, 0x42, 0xe9, 0x2f, 0x09, 0x25, 0xb1, 0x4d, 0x40, 0x16, 0x34, 0xee,
- 0x86, 0x02, 0x7f, 0x0e, 0x63, 0x69, 0x41, 0xc6, 0x19, 0x89, 0xe7, 0x59,
- 0x45, 0xf2, 0x16, 0x70, 0xaa, 0x1a, 0x76, 0x67, 0x79, 0x0d, 0x81, 0x9d,
- 0xf1, 0x88, 0x7f, 0x06, 0x7c, 0x3f, 0x84, 0x11, 0x6b, 0x9c, 0x42, 0x5c,
- 0x9b, 0xe6, 0x2e, 0xcd, 0x34, 0x0f, 0x69, 0xb5, 0x30, 0xfc, 0x4a, 0x10,
- 0x10, 0x18, 0xd1, 0x1c, 0x48, 0xfa, 0xd7, 0x84, 0x9c, 0x50, 0x82, 0x9b,
- 0xf1, 0xcf, 0xc4, 0x73, 0x32, 0xea, 0x82, 0x3d, 0x3e, 0x85, 0x5a, 0x54,
- 0xfc, 0xb6, 0xd4, 0xa6, 0xd3, 0xa6, 0x79, 0x4a, 0x75, 0xe2, 0x10, 0xc9,
- 0x67, 0xa4, 0xf0, 0xcf, 0x66, 0x85, 0x64, 0xb3, 0x4b, 0x9d, 0x5f, 0x5f,
- 0x46, 0xde, 0x6f, 0x9a, 0x33, 0x74, 0x6f, 0x4f, 0x61, 0x5e, 0xce, 0xa6,
- 0xe9, 0x50, 0x4d, 0x73, 0x93, 0xfa, 0x4f, 0xe6, 0xc6, 0xdf, 0x1a, 0x1b,
- 0xc3, 0x33, 0x39, 0x3f, 0x9e, 0xcd, 0x26, 0x51, 0x48, 0x9b, 0x90, 0x74,
- 0x27, 0x06, 0x47, 0x43, 0xd8, 0x56, 0xec, 0x46, 0x31, 0xad, 0xa4, 0xce,
- 0xd0, 0x73, 0x1b, 0xe3, 0x2a, 0xee, 0x2f, 0xf6, 0x60, 0x2e, 0x0d, 0xd3,
- 0xad, 0xab, 0x15, 0xb7, 0x88, 0x62, 0x4b, 0xb1, 0x17, 0xa5, 0xb4, 0x7a,
- 0x7a, 0x44, 0x44, 0x86, 0x9b, 0x25, 0x27, 0xb6, 0x17, 0xdb, 0xf1, 0x40,
- 0x31, 0x41, 0xcf, 0x98, 0xf8, 0x5a, 0xac, 0x85, 0xc6, 0x77, 0xe0, 0xe9,
- 0x49, 0xd3, 0x8c, 0xc6, 0xfc, 0x18, 0x2c, 0x6a, 0x98, 0xcb, 0x39, 0x90,
- 0x3a, 0xe4, 0x44, 0xea, 0x29, 0x60, 0xcb, 0x53, 0x1d, 0x98, 0xc9, 0x99,
- 0xd8, 0xa8, 0x8d, 0x34, 0x3b, 0xe0, 0x42, 0xca, 0x2f, 0xe0, 0x52, 0x7d,
- 0xd8, 0xec, 0xb7, 0x69, 0x3f, 0x23, 0x09, 0x6c, 0x7d, 0x2a, 0x8a, 0x77,
- 0xd2, 0x06, 0xbe, 0xd6, 0x19, 0xc4, 0x70, 0x31, 0x80, 0x37, 0xd3, 0x01,
- 0x5a, 0x43, 0xc3, 0x1b, 0x69, 0x99, 0xd6, 0x69, 0xc7, 0xc9, 0x34, 0x8f,
- 0xe1, 0xb1, 0x5e, 0x0c, 0x14, 0x5b, 0xf0, 0x7a, 0x3a, 0x48, 0x6b, 0x06,
- 0xf0, 0x2a, 0x8d, 0xbb, 0xb7, 0xa8, 0xe2, 0x34, 0x8d, 0x1b, 0x2c, 0x86,
- 0xf0, 0x4a, 0xda, 0x4b, 0xb4, 0x06, 0x70, 0x22, 0x3d, 0x84, 0x9d, 0xe9,
- 0xb6, 0xd3, 0x6b, 0x49, 0x86, 0xa1, 0x05, 0xbc, 0x0e, 0x5f, 0x7b, 0xd7,
- 0xec, 0x0d, 0x58, 0xa6, 0x42, 0xeb, 0xcc, 0xaf, 0x3b, 0x84, 0x91, 0xf4,
- 0xa9, 0xaa, 0xbf, 0x68, 0x78, 0x2c, 0x77, 0xd9, 0xfc, 0xf1, 0xd2, 0x16,
- 0x1c, 0xc9, 0x02, 0x4f, 0xcf, 0x00, 0x33, 0x59, 0xc3, 0xac, 0xd7, 0x4d,
- 0x73, 0xba, 0xb3, 0x9d, 0xe4, 0xa5, 0xf6, 0x6f, 0xa4, 0x51, 0xcf, 0x96,
- 0x9d, 0xc0, 0x53, 0x4a, 0x7f, 0x05, 0x0e, 0xe4, 0xe7, 0x9c, 0xa8, 0x19,
- 0x55, 0x7a, 0xf2, 0x50, 0x4e, 0x6f, 0x21, 0x8f, 0x3a, 0x94, 0x55, 0xfa,
- 0x0c, 0xec, 0x30, 0x83, 0x7a, 0x6b, 0xa8, 0x5d, 0x32, 0xe1, 0x23, 0x5b,
- 0x48, 0xb7, 0x9b, 0x66, 0xc3, 0x4a, 0xd3, 0x7c, 0xbd, 0x13, 0xa6, 0x43,
- 0x57, 0x4f, 0x97, 0xa1, 0x56, 0x3e, 0x82, 0x3a, 0x7c, 0x02, 0x95, 0xaf,
- 0x78, 0x11, 0x19, 0x0c, 0x4b, 0x91, 0xa1, 0xcb, 0xf4, 0x6c, 0x7d, 0x91,
- 0xcc, 0x99, 0x78, 0x51, 0x47, 0x81, 0x62, 0x59, 0x86, 0x93, 0xf8, 0x69,
- 0x1f, 0x35, 0x4d, 0xa7, 0xea, 0x85, 0x97, 0xe4, 0xbb, 0xfe, 0x80, 0x69,
- 0xbe, 0xaf, 0xf9, 0x51, 0x43, 0xba, 0xb9, 0x65, 0xcc, 0xc4, 0xb4, 0x76,
- 0x82, 0xe4, 0x29, 0x90, 0xea, 0x8b, 0xd3, 0x33, 0x01, 0x1a, 0x9f, 0xc0,
- 0xfa, 0xd1, 0x20, 0x9e, 0xc9, 0xca, 0xf8, 0xf1, 0xd2, 0x28, 0xea, 0x68,
- 0x2e, 0x0f, 0xc9, 0xaa, 0x96, 0xe4, 0x87, 0x22, 0x99, 0x5b, 0xd1, 0xb6,
- 0x47, 0x14, 0xcf, 0x10, 0x8f, 0x41, 0x7c, 0xbf, 0x1c, 0xc0, 0x73, 0x65,
- 0x3f, 0x8e, 0x96, 0x5b, 0x70, 0xbc, 0xac, 0xe1, 0x60, 0x4e, 0xd9, 0x5b,
- 0x81, 0x89, 0x7a, 0x7d, 0x07, 0x1a, 0x96, 0x03, 0x6f, 0xe6, 0x63, 0xc8,
- 0xe4, 0x4c, 0xb3, 0x40, 0x74, 0x7b, 0x88, 0x8f, 0x37, 0xf2, 0x5f, 0xc5,
- 0xe1, 0x49, 0x27, 0x42, 0xd3, 0x01, 0x3c, 0x9b, 0x76, 0xe2, 0xfa, 0x8c,
- 0x62, 0xe4, 0xa1, 0x46, 0xb7, 0x09, 0x35, 0x79, 0x83, 0x50, 0x72, 0x06,
- 0x22, 0x21, 0x97, 0x70, 0xa0, 0xf5, 0xb0, 0x13, 0x6a, 0x29, 0x04, 0x57,
- 0xab, 0x0c, 0xb5, 0xf5, 0x21, 0xc0, 0xe7, 0x40, 0x0d, 0xf9, 0xc6, 0xfa,
- 0xf1, 0x28, 0x5d, 0x0b, 0xd0, 0x35, 0x7c, 0xb5, 0x16, 0xd2, 0x22, 0x09,
- 0x24, 0x3b, 0x55, 0x42, 0xd2, 0x69, 0x9a, 0x92, 0xda, 0x81, 0xbb, 0x1e,
- 0x37, 0xcd, 0xf0, 0x72, 0x1e, 0xef, 0x47, 0xb8, 0x44, 0x72, 0x68, 0x25,
- 0xba, 0xb2, 0x44, 0x67, 0x96, 0xe8, 0xcc, 0x12, 0x9d, 0x59, 0x89, 0xec,
- 0x46, 0xd1, 0x80, 0x47, 0x48, 0x5f, 0x21, 0xe2, 0xf1, 0x1d, 0x4b, 0x57,
- 0xcf, 0x95, 0x83, 0xc4, 0x43, 0xc8, 0xe2, 0xe1, 0xe9, 0x9c, 0x80, 0x43,
- 0x55, 0xfa, 0xce, 0x60, 0x35, 0xc2, 0x31, 0x25, 0x99, 0x47, 0x92, 0x9e,
- 0x53, 0xf6, 0x1a, 0x50, 0x7a, 0x2a, 0x64, 0x03, 0x1b, 0xfd, 0x09, 0xcc,
- 0x65, 0x5d, 0xa8, 0x53, 0x95, 0x10, 0xe9, 0x2c, 0x5a, 0xc1, 0x02, 0xdc,
- 0xe7, 0xa7, 0x39, 0x1d, 0xb2, 0xb0, 0x63, 0xc9, 0x23, 0x88, 0x8c, 0x3b,
- 0x30, 0xab, 0x49, 0xe4, 0xa3, 0x1a, 0xa4, 0x56, 0x5a, 0xae, 0x14, 0xa7,
- 0x4f, 0x9a, 0x3f, 0x4b, 0x6b, 0x11, 0x3d, 0x34, 0x1f, 0xf9, 0x26, 0xcb,
- 0x32, 0x4a, 0x34, 0x3c, 0x6a, 0xd1, 0x7b, 0xb4, 0xfc, 0x75, 0x61, 0xdb,
- 0x90, 0x4e, 0x36, 0xa3, 0x84, 0x20, 0x94, 0x68, 0x48, 0x28, 0x5a, 0x52,
- 0xf8, 0x31, 0x53, 0x7e, 0x83, 0xc6, 0x04, 0xae, 0x19, 0xd3, 0x87, 0x91,
- 0xac, 0xc0, 0x5a, 0xd5, 0xc4, 0x1a, 0xad, 0x0f, 0x3b, 0xcb, 0xf3, 0xbe,
- 0xc9, 0x31, 0xcc, 0xef, 0x9b, 0x49, 0x77, 0x63, 0x57, 0x36, 0x84, 0x9d,
- 0x85, 0xa0, 0x6f, 0x3a, 0xcd, 0xf7, 0x54, 0xf2, 0x79, 0xbe, 0x17, 0xb8,
- 0xe6, 0x5e, 0xcb, 0x35, 0xf7, 0x12, 0x18, 0x99, 0xf8, 0x1d, 0x8a, 0x23,
- 0x0d, 0xd8, 0xa9, 0x7e, 0x4a, 0xf6, 0xa2, 0x26, 0x06, 0xd0, 0x8c, 0x33,
- 0xfe, 0x76, 0xec, 0x9f, 0xea, 0xc5, 0xae, 0xa9, 0x65, 0x78, 0x6c, 0xa2,
- 0x25, 0xe5, 0xd1, 0x49, 0x38, 0x9e, 0x70, 0x72, 0x40, 0x28, 0x43, 0x92,
- 0x08, 0x47, 0x07, 0xc8, 0x7e, 0x5b, 0x1b, 0x4d, 0xf3, 0x44, 0x8c, 0xec,
- 0x5b, 0x6b, 0xd3, 0xd6, 0x93, 0x00, 0x2a, 0x7d, 0x4a, 0xcf, 0xbb, 0xf0,
- 0xe2, 0x76, 0xb2, 0xbb, 0x99, 0x18, 0x06, 0x24, 0x48, 0xed, 0x5e, 0xfc,
- 0xbd, 0xf9, 0x94, 0x93, 0xe5, 0x6e, 0xee, 0xd8, 0xa4, 0xed, 0x15, 0x1c,
- 0xeb, 0x6a, 0xae, 0xc6, 0x13, 0x9e, 0x9f, 0x9f, 0x21, 0xdd, 0xd1, 0x3c,
- 0x83, 0xb1, 0xb6, 0xc4, 0x20, 0x2e, 0x9b, 0x67, 0x36, 0xf4, 0x62, 0xe7,
- 0xdc, 0x32, 0xec, 0x9b, 0x70, 0x21, 0xd9, 0x28, 0xd0, 0xa0, 0x86, 0x2b,
- 0xf7, 0x61, 0x19, 0x8c, 0x19, 0x7e, 0xae, 0x17, 0x07, 0xe7, 0xec, 0xdf,
- 0xd9, 0xab, 0xbf, 0xe7, 0xe7, 0x3b, 0x4f, 0x3a, 0x65, 0x79, 0x72, 0xac,
- 0x24, 0x15, 0xe8, 0x6d, 0x38, 0x32, 0x11, 0x20, 0xdd, 0x76, 0x0b, 0xe7,
- 0xe1, 0x45, 0x3e, 0xcf, 0xe3, 0x26, 0x4e, 0x69, 0xa4, 0xe7, 0xec, 0x3a,
- 0xe1, 0x39, 0xdc, 0x23, 0x5c, 0xa5, 0x3b, 0x45, 0xcd, 0xf4, 0x37, 0x85,
- 0x7c, 0x38, 0x25, 0x6a, 0x4b, 0xed, 0x24, 0xfb, 0x7e, 0xe1, 0x3e, 0xac,
- 0x84, 0x42, 0xe2, 0x11, 0xd2, 0xe7, 0x06, 0x21, 0x95, 0xe0, 0x77, 0xe8,
- 0xc3, 0xc2, 0x51, 0xa2, 0x39, 0x2c, 0x1b, 0xe2, 0x75, 0x82, 0xa4, 0x37,
- 0x18, 0x92, 0x3e, 0x84, 0x8d, 0x14, 0xff, 0x6f, 0x4d, 0xeb, 0x78, 0x34,
- 0x5b, 0x4b, 0x31, 0x92, 0x7d, 0xff, 0x32, 0xad, 0xab, 0xe2, 0x31, 0xca,
- 0x15, 0xb2, 0xbe, 0x0f, 0x3e, 0xf2, 0xb9, 0xd7, 0x63, 0xec, 0x8f, 0x40,
- 0x21, 0x1b, 0xee, 0x7f, 0x54, 0x98, 0xe6, 0xd6, 0x88, 0xb9, 0x78, 0x5d,
- 0xac, 0x2d, 0x7a, 0x12, 0xff, 0x68, 0xe6, 0x03, 0x43, 0xa8, 0xef, 0xa4,
- 0x7b, 0xa3, 0x90, 0x5d, 0xfa, 0x2e, 0x1c, 0xa2, 0x5c, 0xe2, 0xd1, 0x29,
- 0xbe, 0x8c, 0x86, 0xfb, 0x1f, 0x13, 0x1c, 0xf3, 0x95, 0xca, 0xb3, 0x18,
- 0x39, 0x5d, 0x0b, 0x25, 0xb4, 0x46, 0xb4, 0x69, 0x75, 0x92, 0x91, 0x68,
- 0xa6, 0x14, 0xe7, 0xee, 0x54, 0x86, 0xf7, 0x40, 0xf1, 0x5f, 0x00, 0xfb,
- 0x2a, 0xe7, 0x93, 0x5d, 0x48, 0x58, 0x79, 0xc5, 0xc0, 0x4d, 0x57, 0xf3,
- 0x8a, 0x4e, 0x76, 0x52, 0x8b, 0x3d, 0x44, 0xd7, 0xcb, 0x9a, 0x12, 0x9c,
- 0x86, 0xb9, 0x78, 0x40, 0xe3, 0x7b, 0x3a, 0x76, 0x95, 0xcd, 0x90, 0xa4,
- 0xb3, 0xac, 0x90, 0xaa, 0xd5, 0x99, 0x56, 0x3f, 0xf9, 0xc6, 0x6f, 0xcc,
- 0x81, 0xb8, 0xac, 0xbd, 0x57, 0xf0, 0x93, 0xbc, 0xe0, 0x73, 0x16, 0xbf,
- 0x2c, 0xff, 0x9a, 0x70, 0xe8, 0xbf, 0x31, 0xbf, 0x1d, 0x87, 0x6f, 0x71,
- 0xd1, 0x99, 0xaa, 0xd3, 0xd1, 0x37, 0x3c, 0xba, 0xc3, 0x6c, 0x56, 0x1d,
- 0x14, 0xab, 0x54, 0x8a, 0xed, 0xde, 0xc4, 0xa5, 0x4e, 0xb7, 0x78, 0xbd,
- 0x33, 0xd8, 0xfb, 0x51, 0xc1, 0x4d, 0x7a, 0x46, 0xdf, 0xb6, 0x62, 0xc2,
- 0xf9, 0x21, 0xd9, 0x5a, 0x0d, 0xc5, 0x55, 0x14, 0x5b, 0x7a, 0x2f, 0x50,
- 0x2e, 0xba, 0x25, 0xe6, 0xfe, 0xe3, 0x1a, 0xdd, 0xf1, 0x55, 0x37, 0x1e,
- 0xbc, 0x69, 0x36, 0xd1, 0x40, 0xb1, 0xdd, 0x8f, 0xd3, 0xf1, 0x1e, 0x8c,
- 0x94, 0x6b, 0xc9, 0x0e, 0x9f, 0xaf, 0xec, 0x56, 0x5b, 0x7a, 0x2f, 0xa6,
- 0x17, 0x53, 0x2c, 0xc1, 0x67, 0x85, 0x4e, 0xb5, 0x6f, 0x9b, 0x38, 0x71,
- 0xab, 0x07, 0x71, 0x92, 0xab, 0x2c, 0x5f, 0x49, 0xe3, 0xd3, 0xc5, 0xaa,
- 0x5a, 0x59, 0x2d, 0xb5, 0x0e, 0xc9, 0x52, 0xeb, 0x70, 0x0d, 0xc5, 0xe1,
- 0xf3, 0x37, 0x0a, 0x9c, 0xba, 0x31, 0x92, 0xa8, 0x11, 0x6e, 0x9c, 0xe9,
- 0x4b, 0x90, 0x9d, 0xb4, 0xa4, 0xdc, 0x3a, 0xc5, 0x8f, 0x51, 0x01, 0x49,
- 0x4d, 0x60, 0xe7, 0x0c, 0x1e, 0x19, 0xd1, 0x7a, 0x61, 0xcc, 0xb1, 0x0d,
- 0xb5, 0x63, 0x64, 0xae, 0x0f, 0x46, 0x59, 0x42, 0x3e, 0x40, 0xcc, 0x97,
- 0x91, 0x72, 0xe9, 0xed, 0xdd, 0xf9, 0xc2, 0x5d, 0x2e, 0xdb, 0x87, 0x89,
- 0xff, 0xec, 0xa4, 0x0f, 0x1e, 0xd6, 0xf3, 0x69, 0x92, 0x51, 0x3b, 0x9e,
- 0x2f, 0x47, 0x29, 0xde, 0x69, 0x24, 0x17, 0x95, 0xe2, 0x45, 0x88, 0xec,
- 0x4b, 0xc6, 0xc6, 0x09, 0xe5, 0x20, 0xc5, 0x85, 0x5c, 0x9e, 0x40, 0x51,
- 0x32, 0xe0, 0xa7, 0xfc, 0xfd, 0x6a, 0x35, 0x06, 0x0c, 0xd2, 0xa7, 0x62,
- 0x24, 0x81, 0x93, 0x0e, 0xa0, 0xa3, 0x59, 0x8f, 0xec, 0x6d, 0x26, 0x7d,
- 0x34, 0x96, 0xdc, 0xd8, 0x3e, 0xd1, 0x84, 0x07, 0xa6, 0x3c, 0xd8, 0x3a,
- 0x61, 0xe2, 0x52, 0x8c, 0x6d, 0x43, 0xe9, 0x27, 0x12, 0xbb, 0xeb, 0x48,
- 0xae, 0xb7, 0xc6, 0x22, 0x09, 0xb7, 0x70, 0xa2, 0xb6, 0xd4, 0x47, 0x38,
- 0x20, 0xc9, 0x7e, 0xa1, 0xd1, 0x1c, 0xa1, 0x9d, 0xda, 0xed, 0x48, 0x05,
- 0x64, 0xb8, 0x4a, 0x5e, 0x8a, 0x25, 0xec, 0xc7, 0x7c, 0xef, 0xeb, 0xd8,
- 0x58, 0xe3, 0x85, 0x94, 0x91, 0x91, 0x23, 0x0c, 0x80, 0x45, 0x35, 0xe8,
- 0x69, 0x75, 0xd0, 0x7f, 0xc0, 0x37, 0x3b, 0xd9, 0xe2, 0x3b, 0x44, 0xf1,
- 0x75, 0x4b, 0xd6, 0xc1, 0xeb, 0x30, 0x66, 0xa0, 0xb9, 0xfd, 0x78, 0x9a,
- 0xe2, 0xf5, 0x43, 0x14, 0x7f, 0x8e, 0x94, 0xcb, 0x82, 0xe3, 0x89, 0xc5,
- 0x4f, 0x96, 0x78, 0xcb, 0x12, 0x6f, 0x59, 0xe2, 0x8b, 0xe2, 0xc2, 0xd1,
- 0x2c, 0xf3, 0xf1, 0x6b, 0xf2, 0xd1, 0x04, 0xf1, 0xee, 0xc6, 0x66, 0xa2,
- 0xf7, 0xc1, 0xa9, 0x3a, 0x6c, 0x23, 0x7a, 0x8b, 0x9a, 0xa2, 0x3d, 0x27,
- 0x4c, 0xec, 0x8f, 0x29, 0xc6, 0x4f, 0x29, 0x10, 0x39, 0x5a, 0x4d, 0xb3,
- 0x4f, 0x63, 0x9e, 0x29, 0x5e, 0x39, 0x2c, 0x9e, 0xf7, 0x26, 0xe1, 0xc6,
- 0x20, 0x3d, 0x33, 0x30, 0x85, 0xcf, 0x1c, 0xc4, 0x93, 0x9b, 0x78, 0xdc,
- 0xa7, 0x29, 0x89, 0x1b, 0x28, 0xae, 0x9f, 0x53, 0x23, 0x95, 0x73, 0x12,
- 0x7e, 0x9f, 0xe4, 0x31, 0xcc, 0xf2, 0xb8, 0x89, 0xf8, 0x79, 0x80, 0xf0,
- 0x4e, 0x3d, 0xc5, 0xa5, 0xc2, 0x81, 0x48, 0xf4, 0x97, 0xc4, 0x7b, 0xa4,
- 0x44, 0xb4, 0x8f, 0xda, 0xb4, 0xdf, 0xc7, 0xb4, 0xc7, 0x4c, 0xdc, 0x43,
- 0xb4, 0x1f, 0x26, 0xda, 0x07, 0xb3, 0x2c, 0x0f, 0xce, 0x3b, 0x36, 0xfd,
- 0x47, 0xca, 0xbc, 0xee, 0x97, 0xf1, 0x30, 0x4f, 0x7f, 0x13, 0x36, 0x4e,
- 0xcd, 0xcb, 0xcb, 0x34, 0xbf, 0xad, 0x1d, 0x33, 0xff, 0x84, 0x64, 0xb6,
- 0xb8, 0xc4, 0x72, 0x83, 0x51, 0xab, 0x47, 0x0e, 0x6e, 0xc1, 0x7d, 0x0e,
- 0x78, 0xbc, 0x58, 0x50, 0xe2, 0x5c, 0x10, 0xc2, 0x31, 0xd2, 0xef, 0x71,
- 0xca, 0x67, 0xcf, 0x97, 0xaf, 0xcd, 0x6f, 0xac, 0xeb, 0x49, 0xd2, 0xb1,
- 0x92, 0x37, 0x28, 0xb6, 0xa5, 0xca, 0x49, 0xec, 0x9e, 0x42, 0x72, 0x56,
- 0xfb, 0x6f, 0x14, 0x60, 0x16, 0x91, 0x7d, 0xd5, 0x26, 0xfd, 0xaa, 0x07,
- 0x9b, 0x66, 0x02, 0x18, 0x2a, 0xaf, 0x41, 0x96, 0xe2, 0xcd, 0x36, 0x8a,
- 0xcf, 0x1f, 0xc7, 0x92, 0x5b, 0x7d, 0x88, 0x90, 0x7e, 0x03, 0xb8, 0x8f,
- 0x9e, 0xd9, 0x37, 0xc5, 0x3c, 0xf8, 0xab, 0x7a, 0x0e, 0x60, 0x0b, 0x5d,
- 0xdb, 0x33, 0x25, 0xe3, 0x25, 0xed, 0x49, 0xc2, 0x34, 0x36, 0xc6, 0xb8,
- 0x27, 0x0b, 0x3f, 0xb9, 0x27, 0x61, 0xc0, 0x48, 0xf4, 0x25, 0xfa, 0xbd,
- 0xb9, 0xec, 0xf1, 0x8d, 0x4c, 0xe2, 0x7b, 0x8b, 0x75, 0x1f, 0x16, 0x10,
- 0x1e, 0xbb, 0x4b, 0x8b, 0x90, 0xdd, 0x3b, 0x31, 0x5c, 0x76, 0xe0, 0x3b,
- 0x33, 0x1e, 0x3c, 0x34, 0xf1, 0x99, 0x59, 0x13, 0x77, 0xe2, 0x8e, 0x56,
- 0x0f, 0x1e, 0x9c, 0x49, 0x62, 0xef, 0x14, 0x42, 0xb5, 0xb1, 0x31, 0x8a,
- 0xdd, 0x76, 0x3e, 0xa8, 0x23, 0xde, 0x1f, 0x9b, 0xf2, 0xfa, 0x06, 0x0f,
- 0xb0, 0x0c, 0xd6, 0x04, 0xdd, 0x40, 0xa5, 0x36, 0x26, 0x61, 0xb3, 0x26,
- 0x2d, 0xa8, 0x25, 0x43, 0x7f, 0x92, 0xe6, 0x9b, 0x86, 0xf4, 0xda, 0x62,
- 0x44, 0x0e, 0x36, 0x4b, 0x95, 0xdc, 0x02, 0x34, 0xe1, 0xa1, 0xb9, 0x24,
- 0xc6, 0xc8, 0x46, 0xb7, 0x4f, 0x8c, 0x7c, 0xaf, 0x91, 0x62, 0x88, 0xaf,
- 0x43, 0x19, 0x7c, 0x53, 0xe8, 0x28, 0x44, 0xdc, 0xd8, 0x36, 0xe3, 0xf5,
- 0x6d, 0x3d, 0x60, 0xae, 0x66, 0x7b, 0xba, 0x77, 0xae, 0x09, 0xf7, 0x4f,
- 0xd1, 0xb5, 0x09, 0xb6, 0x61, 0xb2, 0xb5, 0x48, 0x2d, 0xf1, 0x16, 0x4e,
- 0xba, 0x09, 0x33, 0x49, 0xb1, 0x3a, 0x92, 0x87, 0x1b, 0x5b, 0x2c, 0x5b,
- 0xf0, 0x63, 0xf3, 0x94, 0x89, 0xb3, 0x5a, 0x14, 0x39, 0xb2, 0xeb, 0x83,
- 0x53, 0xca, 0xe5, 0x6e, 0xc2, 0x3b, 0xef, 0x49, 0xca, 0xc1, 0x56, 0x29,
- 0x89, 0xa6, 0xe5, 0x14, 0xe3, 0x9b, 0x4c, 0xf3, 0x9e, 0x8e, 0xb6, 0xa1,
- 0xb7, 0x88, 0xe6, 0x46, 0x7d, 0x11, 0x2a, 0x8d, 0x4a, 0x8e, 0xb0, 0xf3,
- 0x70, 0x8d, 0xe3, 0x46, 0x9c, 0x59, 0x48, 0x7a, 0x06, 0xc7, 0xf2, 0x80,
- 0xaf, 0x29, 0x63, 0xe7, 0xb8, 0x26, 0xb2, 0x93, 0xc6, 0x4c, 0xd0, 0xd7,
- 0x58, 0x82, 0xaf, 0xa6, 0x04, 0xbc, 0x40, 0xf1, 0x65, 0xc1, 0xf2, 0xdf,
- 0x98, 0xa9, 0x26, 0x0b, 0x13, 0xfa, 0x5e, 0x9c, 0x54, 0x8c, 0x0a, 0x94,
- 0xbd, 0x14, 0x2a, 0xf1, 0xc4, 0x9c, 0xd3, 0x77, 0x98, 0xf0, 0x5f, 0x93,
- 0x1a, 0xc5, 0x1e, 0xd2, 0xe7, 0x0e, 0xb2, 0x85, 0xbf, 0x27, 0x7c, 0xf2,
- 0x58, 0x26, 0x1c, 0xd2, 0x44, 0x3f, 0x4d, 0x0c, 0xec, 0x2a, 0x51, 0xcc,
- 0x77, 0xac, 0xa5, 0x20, 0xa6, 0x44, 0x29, 0xad, 0x21, 0x9d, 0x71, 0xc1,
- 0x58, 0x68, 0xeb, 0xe4, 0xfe, 0xec, 0x71, 0xd3, 0xa7, 0xaa, 0xf9, 0x12,
- 0xe9, 0xec, 0xe1, 0xb2, 0x17, 0xc3, 0x84, 0x07, 0x16, 0x10, 0x8e, 0x7c,
- 0x90, 0xec, 0x62, 0xfb, 0x84, 0x44, 0xf4, 0xf1, 0xb8, 0x24, 0x92, 0x8b,
- 0x6c, 0x3c, 0xfa, 0xd0, 0x0c, 0xdb, 0x25, 0xd9, 0x11, 0xd9, 0xe2, 0x31,
- 0xca, 0xf9, 0xcf, 0xff, 0x16, 0x06, 0x51, 0xfc, 0xc6, 0xd5, 0xdc, 0x6f,
- 0xcb, 0x63, 0x64, 0x8a, 0x79, 0x56, 0x0e, 0xc2, 0x91, 0xc4, 0x2d, 0xda,
- 0xaf, 0x28, 0x27, 0x30, 0xef, 0x84, 0x83, 0xa7, 0xa2, 0x94, 0x57, 0x08,
- 0xdb, 0xc4, 0x2e, 0x99, 0x5b, 0x02, 0x2c, 0x03, 0xe6, 0xe7, 0x66, 0x89,
- 0xf3, 0x67, 0x13, 0xe1, 0xdf, 0xff, 0x77, 0xbb, 0xdb, 0x64, 0xa6, 0x2c,
- 0x3c, 0x4b, 0x38, 0x9b, 0xec, 0x29, 0x75, 0xd5, 0x7e, 0x1e, 0x34, 0xcf,
- 0x04, 0x38, 0x5f, 0x37, 0x21, 0x75, 0xd5, 0x16, 0xd8, 0x96, 0xb0, 0x58,
- 0xeb, 0xd8, 0xf9, 0xa0, 0x1f, 0x6c, 0x0f, 0xd1, 0x6b, 0xec, 0xc1, 0x43,
- 0x34, 0xf9, 0xb1, 0x75, 0x8e, 0xed, 0xd7, 0xfc, 0x64, 0xb1, 0xfe, 0x2f,
- 0xe6, 0x95, 0x95, 0xea, 0xc1, 0x5f, 0xe1, 0xeb, 0x74, 0x3d, 0x80, 0xef,
- 0x90, 0x1f, 0xdd, 0x47, 0x7c, 0x6e, 0xed, 0x7c, 0xc0, 0xf2, 0xdb, 0xad,
- 0xe5, 0xdf, 0xa3, 0xeb, 0x2c, 0xef, 0x6e, 0x8a, 0x73, 0x1a, 0xf6, 0x65,
- 0x2b, 0x9c, 0x87, 0xc8, 0xe6, 0xe3, 0xf8, 0x4b, 0x8a, 0xb3, 0xc7, 0xca,
- 0x8c, 0xc9, 0x12, 0x16, 0x1e, 0xfb, 0x61, 0xb9, 0x1d, 0x3f, 0x20, 0x9f,
- 0x7c, 0x9e, 0x62, 0xee, 0xf7, 0x2d, 0x9c, 0xe6, 0x14, 0x8f, 0xa6, 0x55,
- 0x3c, 0x4d, 0x58, 0x7f, 0x5f, 0x21, 0x84, 0x23, 0xe9, 0xf0, 0xde, 0x0b,
- 0x50, 0x5e, 0x20, 0x79, 0xf9, 0xf6, 0x52, 0x8d, 0x76, 0x38, 0xad, 0xe4,
- 0x81, 0xa0, 0x6f, 0x4f, 0xc1, 0xef, 0x1b, 0x49, 0x07, 0x7c, 0x23, 0x84,
- 0x81, 0x76, 0xa6, 0x5b, 0x7c, 0x3b, 0x0b, 0xcb, 0x11, 0x6a, 0x82, 0xb1,
- 0x88, 0x72, 0xc2, 0x7d, 0x13, 0x1b, 0x90, 0x6a, 0xb4, 0xe3, 0xfc, 0x03,
- 0x53, 0x1c, 0x83, 0xdb, 0x52, 0x37, 0x3a, 0xbe, 0x5e, 0xd5, 0xb7, 0x1f,
- 0x43, 0x74, 0xad, 0xa1, 0x03, 0xbe, 0x37, 0xad, 0x58, 0x0b, 0x3c, 0x4f,
- 0xb6, 0xf5, 0x50, 0xc7, 0x6f, 0xcc, 0x64, 0xd5, 0xb6, 0x7e, 0x30, 0xe9,
- 0xa4, 0xf8, 0x6a, 0x9a, 0x47, 0x3b, 0x04, 0x02, 0x1d, 0xdd, 0x30, 0x9a,
- 0xe6, 0x6b, 0xc8, 0x64, 0xbe, 0xb9, 0x83, 0x22, 0x94, 0x7a, 0x0b, 0x12,
- 0x0b, 0x28, 0xb5, 0x74, 0xac, 0xae, 0xde, 0x93, 0xf1, 0x9d, 0x09, 0x37,
- 0x52, 0x4d, 0x7e, 0xcc, 0x12, 0x36, 0xd9, 0x68, 0xc5, 0xa2, 0xb6, 0xd3,
- 0xc7, 0xa9, 0x96, 0x09, 0x7d, 0xc3, 0x4f, 0xbc, 0x26, 0x21, 0x77, 0x10,
- 0x90, 0xa8, 0xd2, 0xc4, 0xbf, 0x73, 0x73, 0x51, 0xec, 0x2e, 0xff, 0xd8,
- 0x61, 0xe7, 0x13, 0x25, 0x9f, 0xc4, 0x4f, 0x28, 0x2f, 0xd2, 0xbd, 0xec,
- 0x9b, 0x66, 0xc8, 0xb2, 0x33, 0x81, 0xc7, 0x97, 0x45, 0xf6, 0xfe, 0x4f,
- 0xc7, 0x75, 0xc4, 0x17, 0xc9, 0x2a, 0x6b, 0xd5, 0x8e, 0x0d, 0xd7, 0xa9,
- 0x0f, 0xe2, 0x2f, 0xfd, 0x2c, 0xcb, 0x61, 0x91, 0xa5, 0x3a, 0xf5, 0x8c,
- 0x0b, 0x0d, 0x41, 0x35, 0x8b, 0x17, 0xfa, 0xf8, 0x5a, 0xc0, 0xf7, 0x44,
- 0x3a, 0xe9, 0x08, 0xa8, 0xf0, 0xbb, 0xf4, 0x6e, 0xf1, 0x04, 0x61, 0xc0,
- 0x89, 0x74, 0x8f, 0x98, 0x28, 0xdc, 0x29, 0x8c, 0xfc, 0x37, 0x85, 0x31,
- 0x9b, 0x12, 0x46, 0xa1, 0x9f, 0x3e, 0x37, 0x88, 0xc9, 0xc2, 0xb0, 0xd8,
- 0x5d, 0xe0, 0x79, 0x49, 0x27, 0x34, 0xf7, 0x0f, 0x29, 0xc6, 0xfe, 0x80,
- 0x62, 0xec, 0x31, 0x8a, 0xb1, 0xcf, 0x93, 0x5d, 0x7f, 0xff, 0x2a, 0x96,
- 0x65, 0x5b, 0x4e, 0x32, 0x06, 0xf1, 0xfd, 0xbc, 0xf4, 0x12, 0xe9, 0x95,
- 0x65, 0xf6, 0x13, 0xb2, 0x61, 0x96, 0xc5, 0x7f, 0xe6, 0x9c, 0x40, 0xfa,
- 0xf8, 0xd0, 0xb2, 0xd9, 0xc7, 0x97, 0x31, 0x66, 0x1a, 0x16, 0x3b, 0x98,
- 0xae, 0x5a, 0xaa, 0xdb, 0x55, 0xc2, 0x21, 0xd9, 0x61, 0xb1, 0xb1, 0xc0,
- 0xd7, 0xf7, 0xe1, 0x3e, 0xaa, 0xff, 0xb6, 0xc6, 0xc2, 0x89, 0x6e, 0xc2,
- 0x48, 0x17, 0x54, 0x73, 0x71, 0x34, 0x46, 0x98, 0xe1, 0xc6, 0x2b, 0x54,
- 0xab, 0x22, 0xb9, 0x2d, 0xae, 0xe4, 0xf3, 0x76, 0x5e, 0xcd, 0xa5, 0xc1,
- 0x75, 0x3a, 0x1a, 0x9c, 0xaa, 0x72, 0x24, 0x89, 0xf0, 0xde, 0xb8, 0x03,
- 0x46, 0x8d, 0xee, 0xc2, 0x80, 0x55, 0x17, 0xae, 0x41, 0x66, 0x42, 0xe0,
- 0x65, 0xf2, 0x01, 0x17, 0xc9, 0xe8, 0x50, 0x27, 0x3e, 0x23, 0xb5, 0x0a,
- 0xaa, 0xe3, 0x4f, 0x9f, 0xa5, 0x9c, 0x73, 0x17, 0xe5, 0xd6, 0x89, 0xec,
- 0x0a, 0x04, 0x3b, 0x64, 0x34, 0x74, 0x38, 0xf1, 0x8d, 0xd2, 0xef, 0xe3,
- 0x4c, 0x63, 0xe4, 0xe0, 0x0b, 0xf0, 0xf8, 0x5e, 0x9a, 0x64, 0x7a, 0xf0,
- 0xbd, 0x3a, 0xaa, 0xd7, 0xb6, 0x12, 0x4e, 0x1a, 0x27, 0x1a, 0x7a, 0x3a,
- 0x22, 0x3d, 0xb7, 0x09, 0xf8, 0x6b, 0xf5, 0x1a, 0x8c, 0xb7, 0xfa, 0xe0,
- 0x57, 0x53, 0xe2, 0xd5, 0x02, 0xe5, 0x0d, 0xc7, 0x37, 0xc5, 0x5b, 0xb3,
- 0x3a, 0xf6, 0x96, 0xfb, 0xc5, 0x2f, 0x66, 0x65, 0x90, 0x4e, 0x28, 0x3e,
- 0x69, 0xc8, 0x10, 0x5d, 0x2e, 0xc2, 0x42, 0x2f, 0xdf, 0x21, 0x70, 0x9d,
- 0x9a, 0xc4, 0x77, 0x56, 0xb0, 0xcd, 0xdb, 0xb1, 0x2b, 0x98, 0x51, 0x42,
- 0x49, 0x47, 0xb7, 0x08, 0x52, 0xec, 0x6a, 0xc8, 0xf4, 0x88, 0x06, 0xc2,
- 0x9e, 0x0b, 0xa7, 0x37, 0x88, 0x05, 0x25, 0xc6, 0x9a, 0xf0, 0x2f, 0x24,
- 0xd9, 0x2c, 0x2c, 0x7d, 0x20, 0xd9, 0x18, 0xdf, 0xc5, 0xb6, 0x43, 0x39,
- 0x4a, 0xf6, 0xfd, 0x7a, 0x32, 0x89, 0x5b, 0x3b, 0xd6, 0x20, 0x64, 0xd9,
- 0xc7, 0xb0, 0xd8, 0x47, 0xf2, 0x4b, 0x5a, 0xfd, 0x07, 0xbf, 0xef, 0xc0,
- 0x24, 0x5c, 0x7e, 0x1d, 0x21, 0x89, 0x72, 0x43, 0xa9, 0x23, 0x32, 0xf8,
- 0x96, 0xe8, 0x15, 0xa3, 0x85, 0x80, 0x2f, 0x9d, 0x86, 0xbf, 0x8e, 0x74,
- 0x9c, 0x26, 0x1d, 0xef, 0x21, 0x1d, 0xef, 0xf9, 0x12, 0x1d, 0xef, 0x24,
- 0x1d, 0xef, 0x2f, 0xfc, 0x9d, 0xa5, 0x33, 0xa7, 0xae, 0x63, 0x94, 0x72,
- 0xee, 0x78, 0xab, 0xcd, 0x4f, 0x81, 0x30, 0xea, 0x9e, 0x58, 0xaf, 0x13,
- 0x1e, 0x9d, 0x62, 0x66, 0x2f, 0x3d, 0xd3, 0x5c, 0xb5, 0x65, 0xbf, 0xef,
- 0xc9, 0x74, 0xb7, 0x78, 0xd2, 0xf2, 0x2b, 0xc6, 0x8d, 0x49, 0x34, 0xaa,
- 0x3d, 0x34, 0x17, 0xdb, 0xca, 0x9d, 0x02, 0x4f, 0xb1, 0xbd, 0x7c, 0x93,
- 0x04, 0xcf, 0x36, 0x93, 0x12, 0x28, 0xb2, 0xdd, 0xf4, 0xd3, 0x6f, 0xb6,
- 0x9d, 0x0d, 0xa2, 0xb1, 0xf8, 0x45, 0xfb, 0x81, 0xdf, 0xa9, 0xb3, 0xfd,
- 0xb0, 0x1d, 0x0d, 0x0b, 0x67, 0x91, 0x7c, 0x96, 0xe6, 0x1f, 0x21, 0xba,
- 0x77, 0xa6, 0xf7, 0x3b, 0x99, 0x36, 0x59, 0x67, 0x3b, 0x62, 0xfb, 0xb9,
- 0x48, 0xb4, 0xb2, 0xcd, 0x5f, 0xed, 0xd9, 0xd0, 0xdf, 0xef, 0x4a, 0x50,
- 0xb7, 0x38, 0x6d, 0x1e, 0x38, 0x87, 0x73, 0xce, 0xe6, 0x78, 0xea, 0xb7,
- 0x6a, 0xba, 0x63, 0x57, 0x73, 0x39, 0xe7, 0x75, 0xc8, 0x0b, 0xf4, 0x80,
- 0xfe, 0x9d, 0xd6, 0x2b, 0x34, 0xdf, 0x10, 0xb4, 0x15, 0x90, 0x03, 0xfa,
- 0xa4, 0x3e, 0xd9, 0x4a, 0xf1, 0x96, 0xe6, 0x94, 0x33, 0x80, 0x9a, 0x11,
- 0xd8, 0x99, 0x10, 0x84, 0x47, 0x17, 0x91, 0xbf, 0xc1, 0xf0, 0xe8, 0x4a,
- 0x4f, 0x92, 0xee, 0x2d, 0x25, 0x7c, 0xbe, 0x58, 0xdf, 0x06, 0x33, 0x0b,
- 0xb9, 0x41, 0x1f, 0xc4, 0x27, 0xa3, 0x61, 0xff, 0x79, 0x28, 0xa9, 0xb3,
- 0x92, 0x52, 0xa1, 0x3c, 0x35, 0x34, 0x22, 0x94, 0xc1, 0xcb, 0x42, 0x49,
- 0x96, 0xac, 0x1e, 0xcf, 0x36, 0xb4, 0x5b, 0x58, 0x7c, 0x10, 0xd1, 0x02,
- 0x70, 0x1b, 0x01, 0xbc, 0x7b, 0x6e, 0x26, 0x9b, 0xd4, 0x3e, 0xe2, 0xd8,
- 0x9e, 0x3c, 0x43, 0x54, 0x2f, 0xce, 0x70, 0xcf, 0x68, 0x5b, 0xb5, 0x67,
- 0x34, 0x68, 0xf5, 0x8c, 0xce, 0x4b, 0x4a, 0x62, 0xbe, 0x67, 0x74, 0x05,
- 0x3c, 0x97, 0xd2, 0xef, 0xad, 0xce, 0xb7, 0xb4, 0x3a, 0x5f, 0x5b, 0x01,
- 0x22, 0x9a, 0x31, 0xcc, 0x1a, 0xd5, 0x43, 0xfc, 0x26, 0x1d, 0xae, 0x88,
- 0xda, 0x73, 0x18, 0x21, 0x44, 0xa9, 0xde, 0xbd, 0x9e, 0xf2, 0xa0, 0x3b,
- 0xb3, 0x03, 0x33, 0x9a, 0xd2, 0x37, 0x00, 0xb6, 0x9d, 0x6e, 0xec, 0xa3,
- 0x18, 0xba, 0xb7, 0xcc, 0xf5, 0xc8, 0xb0, 0x38, 0xcb, 0x76, 0xe3, 0xb4,
- 0xa5, 0x66, 0xaf, 0xff, 0x70, 0x75, 0xfd, 0x21, 0x6b, 0xfd, 0x0b, 0x92,
- 0xd2, 0x5f, 0x5d, 0x5f, 0xfb, 0x33, 0xa1, 0xa4, 0x68, 0xfd, 0x9e, 0x3d,
- 0xb4, 0xbe, 0x4b, 0xe5, 0xb5, 0x1f, 0xe6, 0xb5, 0xe9, 0x73, 0x08, 0xd7,
- 0x93, 0xdd, 0xbc, 0x57, 0x90, 0xc5, 0xbb, 0xb9, 0x35, 0xd8, 0x35, 0xb3,
- 0x06, 0x3b, 0xc9, 0xdf, 0xb6, 0x6a, 0x0d, 0x54, 0xa7, 0xa1, 0xde, 0xa7,
- 0xe2, 0xb2, 0x23, 0x22, 0xa4, 0xf5, 0xed, 0x2d, 0x84, 0x41, 0x4e, 0x34,
- 0xcb, 0xf8, 0xd4, 0x1c, 0x50, 0xd7, 0xf4, 0x39, 0x91, 0xfc, 0x7d, 0x0f,
- 0xfe, 0x5c, 0x22, 0xff, 0x7d, 0x67, 0x81, 0x40, 0xd2, 0x63, 0xd5, 0x1c,
- 0x09, 0xe1, 0x29, 0xfe, 0xd8, 0x69, 0xdb, 0x7b, 0x2b, 0x7c, 0x8d, 0x68,
- 0x68, 0x50, 0x6f, 0x40, 0x43, 0xa3, 0x6c, 0x38, 0xa8, 0x8e, 0x59, 0x4f,
- 0x21, 0xd1, 0xcc, 0xf5, 0x51, 0x3c, 0x35, 0x71, 0x65, 0xf9, 0xdf, 0x9b,
- 0x89, 0xeb, 0xf8, 0x39, 0x02, 0x15, 0x56, 0x4c, 0xfc, 0xb2, 0x39, 0xe2,
- 0xe4, 0xbf, 0x6d, 0x54, 0x97, 0xd6, 0x51, 0xf0, 0xed, 0xc1, 0x9e, 0xac,
- 0x92, 0xda, 0x43, 0x75, 0xe5, 0xfe, 0x48, 0x5b, 0xcf, 0x26, 0x51, 0x83,
- 0xd0, 0xc2, 0xf0, 0xe0, 0x00, 0x92, 0xcd, 0xf5, 0x55, 0x3a, 0x1e, 0x46,
- 0xb3, 0x8b, 0x9e, 0xe3, 0x79, 0xae, 0xb1, 0xa7, 0x22, 0xd9, 0x13, 0xdf,
- 0xe7, 0xef, 0x57, 0xef, 0xcb, 0xbf, 0xa3, 0x4f, 0xae, 0xfa, 0xaf, 0x4b,
- 0xbf, 0xec, 0xfa, 0xb1, 0x2f, 0xb9, 0xfe, 0x6f, 0xd5, 0xe7, 0x95, 0x46,
- 0xa7, 0x95, 0xfb, 0x93, 0x0e, 0xee, 0x4b, 0x3a, 0xf5, 0x42, 0xd7, 0x2e,
- 0xf5, 0x3f, 0x51, 0xcc, 0xe2, 0x7e, 0x04, 0xe7, 0xdb, 0x33, 0x56, 0x3f,
- 0xe2, 0xf8, 0x6f, 0x61, 0x4f, 0x8e, 0x1d, 0x6e, 0x51, 0x37, 0x6e, 0x98,
- 0x4d, 0xea, 0x1f, 0x51, 0x7d, 0xb2, 0x03, 0x03, 0x31, 0x0d, 0x63, 0x59,
- 0xa5, 0xef, 0x0e, 0xa8, 0xc9, 0x3b, 0x05, 0x4d, 0x54, 0x72, 0x0b, 0x69,
- 0xbc, 0x7a, 0x4f, 0x33, 0xa8, 0xe6, 0xaa, 0xa0, 0x96, 0x62, 0x8f, 0x53,
- 0xf5, 0xcb, 0x28, 0x05, 0x64, 0x67, 0x29, 0x28, 0xd7, 0x94, 0x5a, 0xe4,
- 0x5a, 0x1a, 0xe7, 0x1d, 0x57, 0x2e, 0xdf, 0x81, 0x1d, 0xb8, 0xbc, 0xdc,
- 0x63, 0x34, 0xeb, 0x8a, 0xbf, 0x59, 0xda, 0x81, 0x5d, 0x31, 0x7e, 0xb6,
- 0x9b, 0x6a, 0x2f, 0x88, 0xc6, 0x0c, 0x21, 0x5c, 0x5d, 0x60, 0x37, 0xd5,
- 0x97, 0x4b, 0x1c, 0x6a, 0xcf, 0xaf, 0x85, 0x53, 0x76, 0x97, 0x20, 0x7c,
- 0x19, 0x07, 0x0e, 0x76, 0xc2, 0xed, 0x5e, 0xa1, 0x0c, 0x9e, 0x10, 0xc3,
- 0x78, 0x36, 0x16, 0xe9, 0xdb, 0x2c, 0x42, 0xb2, 0x87, 0xee, 0xb9, 0x32,
- 0x10, 0x72, 0xc6, 0x70, 0xbb, 0x56, 0x28, 0x41, 0x87, 0x48, 0x62, 0x40,
- 0x55, 0xb5, 0x71, 0xc8, 0xb4, 0x26, 0x44, 0x6d, 0x46, 0xb9, 0x7c, 0x96,
- 0xb0, 0xd1, 0x95, 0xa5, 0xc3, 0xe8, 0x58, 0x1e, 0xd9, 0xdb, 0xef, 0x50,
- 0x65, 0xc2, 0x6c, 0xc2, 0x99, 0xf1, 0xe2, 0xa6, 0x03, 0xf3, 0xfd, 0x19,
- 0xd3, 0xfc, 0x38, 0x56, 0xb9, 0x97, 0x44, 0x28, 0xd7, 0x97, 0xa2, 0xb2,
- 0x97, 0xf0, 0x79, 0xdb, 0x01, 0xc6, 0x4b, 0x9c, 0x0f, 0x2a, 0x64, 0x37,
- 0xed, 0xc4, 0x63, 0x1f, 0x66, 0xd2, 0x8c, 0x9f, 0x74, 0x4c, 0x53, 0x6d,
- 0xa3, 0x8e, 0xb6, 0x50, 0xae, 0x4f, 0x60, 0x2e, 0xcd, 0x7d, 0x9c, 0x41,
- 0x92, 0x71, 0x3f, 0xd1, 0xbf, 0x81, 0xea, 0xda, 0x14, 0xc5, 0x2b, 0x96,
- 0xf1, 0x00, 0xf7, 0x6b, 0xa9, 0x96, 0xfe, 0x79, 0xd7, 0xd7, 0xc6, 0x20,
- 0xbb, 0xf5, 0xd7, 0xba, 0xae, 0x3f, 0x80, 0x46, 0xca, 0xe7, 0x3a, 0x55,
- 0x2e, 0x88, 0x46, 0x22, 0xda, 0x79, 0x44, 0x82, 0x2f, 0x93, 0x3e, 0x46,
- 0x54, 0x60, 0xa7, 0x55, 0x33, 0x3b, 0x61, 0x14, 0xd8, 0xa6, 0xe0, 0xae,
- 0xed, 0x6c, 0xc4, 0xfb, 0xb9, 0xa8, 0xd5, 0x0b, 0x32, 0xa8, 0x8e, 0x79,
- 0x49, 0x53, 0x52, 0x79, 0x7a, 0x6e, 0xa3, 0xff, 0x7f, 0xed, 0xa9, 0x8b,
- 0x43, 0xae, 0x53, 0xd9, 0xbf, 0xfe, 0xdc, 0x73, 0x96, 0x6c, 0xf4, 0xae,
- 0xc9, 0xbf, 0xf0, 0x7c, 0x12, 0xcf, 0x7b, 0x3e, 0x8a, 0x9b, 0x66, 0x82,
- 0x70, 0x65, 0x3f, 0xd5, 0xcd, 0x1f, 0x8f, 0x1a, 0x9e, 0xf3, 0x71, 0xee,
- 0xe9, 0x3a, 0xf1, 0x07, 0xf4, 0xfb, 0xe9, 0x51, 0x19, 0xb7, 0x16, 0x9b,
- 0xe1, 0x1a, 0x93, 0xc8, 0x3f, 0xd7, 0x52, 0xae, 0x72, 0xe0, 0x9e, 0xe8,
- 0x51, 0x54, 0x02, 0x0e, 0x1a, 0xb3, 0x9f, 0x7e, 0x73, 0x6f, 0xea, 0x71,
- 0x6c, 0xf6, 0xcf, 0x7a, 0xde, 0x8f, 0x33, 0xbd, 0x15, 0xa6, 0x97, 0x72,
- 0xe4, 0xed, 0xd8, 0x78, 0x07, 0x0c, 0x9f, 0x6e, 0xfd, 0xbb, 0x5f, 0xee,
- 0x6c, 0xc2, 0xe1, 0x5c, 0x33, 0x5e, 0xcc, 0x19, 0xee, 0x9f, 0x76, 0x46,
- 0x31, 0x38, 0x6a, 0xe2, 0x15, 0xcd, 0x18, 0xae, 0x25, 0x3b, 0x4f, 0x50,
- 0xad, 0x14, 0x5e, 0xae, 0xf8, 0x2f, 0x0b, 0x44, 0x24, 0x44, 0x86, 0x08,
- 0x2c, 0xde, 0x4d, 0xa1, 0x2b, 0x55, 0xaf, 0x47, 0xb4, 0xd7, 0x85, 0x59,
- 0x73, 0x6f, 0xa7, 0x93, 0x68, 0x00, 0xd6, 0x51, 0x4c, 0x9e, 0x4b, 0x47,
- 0x71, 0x6b, 0x44, 0xc6, 0xfa, 0xa2, 0x86, 0x17, 0xd3, 0x5e, 0xdc, 0x55,
- 0x8c, 0x13, 0x86, 0xf6, 0x13, 0xed, 0x09, 0x94, 0xd3, 0x01, 0x7c, 0xbd,
- 0xd8, 0x42, 0xf2, 0x0e, 0x62, 0x6d, 0x91, 0x31, 0x16, 0xe7, 0x67, 0xdd,
- 0xbd, 0x31, 0xde, 0x82, 0x1e, 0x8a, 0xdf, 0xb3, 0x69, 0xb8, 0xb7, 0xc7,
- 0x43, 0xe8, 0x2e, 0x46, 0x51, 0x24, 0x2c, 0x76, 0x3b, 0xcd, 0x79, 0x17,
- 0xe9, 0xa4, 0x9d, 0xea, 0xfb, 0x25, 0x11, 0x42, 0xa8, 0x45, 0xaf, 0x18,
- 0x26, 0xcc, 0x94, 0x28, 0x36, 0xe1, 0xfc, 0x18, 0xdb, 0xf9, 0x5b, 0x5d,
- 0xbb, 0x72, 0x7e, 0x84, 0x8a, 0xb8, 0x49, 0x06, 0xb6, 0x51, 0x95, 0x97,
- 0x2a, 0x12, 0xbd, 0xfb, 0x3a, 0xed, 0x7e, 0xec, 0x0d, 0xc5, 0xcf, 0xf9,
- 0x6d, 0x20, 0x3d, 0x7d, 0x72, 0x60, 0xd6, 0x73, 0x85, 0x64, 0xe0, 0xd3,
- 0x7f, 0xd4, 0xf5, 0xc6, 0x01, 0x20, 0x3a, 0xc5, 0xbc, 0x71, 0x7c, 0x0d,
- 0x27, 0x28, 0xbe, 0xb6, 0xcb, 0xf8, 0xb5, 0x49, 0xb5, 0x64, 0x68, 0x86,
- 0x7b, 0xff, 0xaa, 0x97, 0xe8, 0xf0, 0x23, 0x49, 0x6b, 0xdf, 0x56, 0xfc,
- 0xa1, 0xb9, 0x71, 0x61, 0x10, 0x5f, 0x8b, 0xd8, 0xb2, 0x7a, 0x9d, 0x74,
- 0x38, 0x3d, 0xd6, 0x8c, 0xb9, 0x31, 0xee, 0xad, 0x9c, 0xea, 0x3a, 0x34,
- 0x69, 0x62, 0x9d, 0x66, 0x78, 0x7e, 0xda, 0x79, 0x03, 0x1e, 0x38, 0x30,
- 0x72, 0xba, 0x86, 0xf4, 0x7a, 0x59, 0xbb, 0x1b, 0x8f, 0x4e, 0xe1, 0xab,
- 0xcd, 0xc0, 0x23, 0x41, 0x70, 0xff, 0x59, 0x09, 0x1d, 0x41, 0xa4, 0x67,
- 0x3b, 0x22, 0x7e, 0x55, 0x28, 0xda, 0x2b, 0x14, 0xab, 0xea, 0x08, 0x3b,
- 0xdc, 0x46, 0xb5, 0x7c, 0x0d, 0x79, 0xf0, 0x5d, 0x45, 0x27, 0xc9, 0x28,
- 0x88, 0xf2, 0x58, 0x0d, 0x24, 0xf2, 0x93, 0x0b, 0x2a, 0xd6, 0x35, 0x90,
- 0xac, 0x25, 0x21, 0x93, 0x9e, 0xdb, 0x71, 0x68, 0x74, 0x5e, 0x56, 0x5e,
- 0xdc, 0x42, 0x32, 0x7c, 0x76, 0xd4, 0xdc, 0xa1, 0xc6, 0x02, 0x24, 0x6b,
- 0x3f, 0xd1, 0x37, 0x2f, 0x27, 0x96, 0xdf, 0xbc, 0x9c, 0xee, 0xc6, 0xae,
- 0x39, 0x96, 0xdb, 0xbf, 0x47, 0x5e, 0xb3, 0x96, 0xdd, 0xad, 0x9b, 0x8c,
- 0xa2, 0xf9, 0xc0, 0x55, 0xd9, 0x31, 0x7d, 0x8f, 0x10, 0x1f, 0xdf, 0xf3,
- 0xad, 0x8c, 0x0c, 0x5e, 0x14, 0x5e, 0xa2, 0xc7, 0x4f, 0xba, 0x39, 0xeb,
- 0x62, 0x0c, 0x4e, 0x32, 0xb9, 0x2a, 0xe3, 0x20, 0xc9, 0x38, 0x38, 0xc5,
- 0xb2, 0xfe, 0x11, 0xc9, 0x1a, 0x78, 0x83, 0x70, 0xd7, 0xcd, 0xb1, 0x28,
- 0xea, 0x0f, 0x28, 0xc9, 0x66, 0x29, 0x9c, 0x68, 0x10, 0xa0, 0xea, 0x02,
- 0xed, 0xf5, 0xf8, 0x98, 0xe5, 0xac, 0x91, 0x9c, 0xbf, 0x37, 0x42, 0xfc,
- 0xac, 0xa1, 0xf9, 0xd6, 0x91, 0x9c, 0x93, 0xc4, 0xff, 0x6d, 0xd6, 0xbc,
- 0x2d, 0x34, 0xef, 0x06, 0xaa, 0x21, 0x66, 0x3d, 0x17, 0x88, 0x9e, 0xe8,
- 0xe7, 0xb4, 0x10, 0xca, 0x8e, 0x04, 0x2f, 0x52, 0xad, 0xbc, 0xd6, 0x1a,
- 0xe7, 0xa7, 0x71, 0x4c, 0xfb, 0x5b, 0xb5, 0x0e, 0xf5, 0xcb, 0x7a, 0xc7,
- 0x77, 0x83, 0x7b, 0x07, 0x06, 0xfa, 0xb1, 0x37, 0xbb, 0x81, 0x6a, 0x1e,
- 0x99, 0x30, 0xa4, 0x81, 0xef, 0xc7, 0x95, 0x68, 0xa3, 0xe0, 0xf8, 0x67,
- 0x90, 0x1f, 0x56, 0xa8, 0xde, 0x09, 0x87, 0xe6, 0x10, 0x94, 0x1d, 0x25,
- 0x99, 0xf0, 0x5e, 0x8b, 0x2c, 0x95, 0xc8, 0x5f, 0x83, 0xfd, 0x84, 0x93,
- 0x9d, 0x78, 0xb9, 0xe0, 0xc4, 0xab, 0xe9, 0x0d, 0x94, 0xe7, 0xdc, 0x84,
- 0x87, 0x0d, 0xb7, 0x73, 0xc5, 0x81, 0x1a, 0x3b, 0x26, 0x2f, 0x45, 0xef,
- 0xf8, 0xc3, 0xa8, 0xcb, 0x38, 0xfb, 0x28, 0x47, 0x6b, 0xb7, 0x91, 0x5c,
- 0xd6, 0x95, 0xf8, 0x7e, 0x0b, 0x32, 0xe9, 0x14, 0xb2, 0xd9, 0x30, 0xd5,
- 0x32, 0x4e, 0xe4, 0x9b, 0x5b, 0xac, 0xfe, 0x6c, 0x8e, 0xae, 0xe5, 0xca,
- 0x5f, 0xec, 0x1b, 0x7f, 0xab, 0xda, 0x2f, 0x1e, 0xa4, 0x9c, 0xd2, 0x4f,
- 0xd8, 0x73, 0x03, 0xc5, 0x77, 0x9b, 0xc6, 0xd9, 0x78, 0x1f, 0xf6, 0x14,
- 0xf4, 0xab, 0xf1, 0x63, 0xba, 0x60, 0xf7, 0x05, 0xb7, 0x90, 0x3c, 0xce,
- 0xa5, 0x4d, 0x3c, 0xaa, 0xb1, 0x3e, 0x29, 0x2e, 0xa5, 0xb9, 0x37, 0x68,
- 0xe2, 0x19, 0x4d, 0x70, 0xbc, 0xa1, 0x3c, 0xba, 0x01, 0x4b, 0x0a, 0x26,
- 0x4e, 0x6b, 0x2a, 0xc5, 0x2e, 0x18, 0x6e, 0xc2, 0x7e, 0x91, 0xd1, 0x7f,
- 0x31, 0xf3, 0xce, 0x21, 0xb4, 0x75, 0x02, 0x9b, 0x47, 0x25, 0xcc, 0xcd,
- 0x5c, 0xcd, 0xd1, 0x78, 0xf1, 0xf3, 0x3c, 0x9d, 0x98, 0x81, 0xb9, 0xc3,
- 0xa9, 0x2b, 0xc3, 0xbc, 0xd7, 0x32, 0x12, 0x57, 0x12, 0xb5, 0x56, 0xce,
- 0x56, 0xfb, 0x97, 0x48, 0x8a, 0x56, 0x12, 0x6d, 0xa9, 0x4f, 0x50, 0x59,
- 0x2f, 0x43, 0x09, 0xfe, 0x0c, 0x91, 0xe8, 0x20, 0xef, 0x29, 0x94, 0xed,
- 0xfc, 0xbd, 0xb4, 0x9a, 0xbf, 0xc3, 0x05, 0x8f, 0x50, 0xc7, 0x1c, 0xc8,
- 0xcf, 0x98, 0x94, 0x67, 0x05, 0x66, 0x49, 0xc1, 0x2f, 0x64, 0x77, 0xe0,
- 0xeb, 0x31, 0xd3, 0xbc, 0x2b, 0xae, 0x0e, 0x36, 0x4b, 0xf8, 0xd3, 0x06,
- 0xc2, 0x14, 0x64, 0xf7, 0x84, 0x01, 0x10, 0xda, 0xda, 0x69, 0x98, 0x32,
- 0xd5, 0x0c, 0x35, 0x3a, 0xf7, 0x1a, 0x7b, 0x45, 0x7b, 0x71, 0x83, 0xb8,
- 0xa1, 0xd8, 0x2f, 0x42, 0x87, 0xee, 0x14, 0xd1, 0xa7, 0x6c, 0xdc, 0xd6,
- 0x5a, 0xfc, 0xbc, 0x1f, 0xda, 0x43, 0x7c, 0xef, 0xd3, 0x4c, 0x3c, 0x4d,
- 0xbc, 0xed, 0x2d, 0xdb, 0xb5, 0xc8, 0xee, 0xb4, 0xcd, 0xdb, 0xa3, 0x74,
- 0xff, 0x62, 0x9a, 0xfd, 0xf1, 0x61, 0xab, 0xd7, 0xd9, 0x4c, 0xcf, 0xdc,
- 0x9c, 0x0d, 0x87, 0x06, 0x85, 0x32, 0x34, 0x0b, 0xee, 0x77, 0xb6, 0x55,
- 0x4e, 0x0a, 0xca, 0x3d, 0x12, 0xc7, 0x57, 0xf6, 0x79, 0x9b, 0xf6, 0x65,
- 0x05, 0x58, 0x71, 0x91, 0xe9, 0xbf, 0x91, 0xea, 0xbe, 0x9f, 0xa5, 0xdb,
- 0xfa, 0xdd, 0x24, 0xb6, 0xf3, 0xf1, 0x6e, 0x71, 0x89, 0xea, 0xbe, 0x57,
- 0xd3, 0xc9, 0x85, 0x75, 0xe8, 0x11, 0x17, 0x0a, 0x7d, 0xe2, 0xc3, 0x7c,
- 0x2f, 0x9c, 0x63, 0xf7, 0x8b, 0x77, 0xf3, 0x4c, 0x5b, 0xbf, 0x38, 0x33,
- 0x7b, 0xde, 0x92, 0xfd, 0x2e, 0x8d, 0xfb, 0x9a, 0xf5, 0xb5, 0xf0, 0x99,
- 0x04, 0x4f, 0x59, 0x8f, 0xdc, 0xe7, 0xb3, 0xfb, 0x43, 0xeb, 0xe2, 0x39,
- 0xd3, 0xa9, 0x72, 0xaf, 0x37, 0x68, 0xf1, 0x38, 0x43, 0x78, 0x79, 0x36,
- 0xbf, 0x41, 0x1c, 0x2e, 0xd8, 0xfc, 0x4d, 0x17, 0xd8, 0x6e, 0x65, 0xca,
- 0x0d, 0x5f, 0xcc, 0xcf, 0x06, 0xfc, 0x9d, 0x41, 0xd4, 0x58, 0xfd, 0x24,
- 0x13, 0xe3, 0x5a, 0x24, 0xf4, 0x0a, 0x82, 0x70, 0x96, 0xd8, 0xa6, 0x4d,
- 0x3c, 0xa7, 0xb9, 0x20, 0x8d, 0xcb, 0x24, 0x17, 0xb2, 0x21, 0x9f, 0x0b,
- 0x8e, 0x69, 0xae, 0x01, 0xe2, 0xb5, 0xdc, 0x67, 0x08, 0x39, 0xf8, 0xfb,
- 0x17, 0x6d, 0xcd, 0x45, 0x79, 0x80, 0xfb, 0xe3, 0x6f, 0xd6, 0xd8, 0x36,
- 0xc7, 0xf9, 0x68, 0xbe, 0xa7, 0x4d, 0x39, 0xb6, 0x93, 0x7b, 0xd9, 0x6e,
- 0xcc, 0xe5, 0x6a, 0xb8, 0xc5, 0xe0, 0xae, 0xe9, 0x34, 0x71, 0x4e, 0x73,
- 0x52, 0x5d, 0xf2, 0x10, 0xe5, 0x26, 0x07, 0x64, 0xf5, 0x6e, 0x94, 0x26,
- 0x9d, 0x0e, 0xde, 0x73, 0xfa, 0x59, 0x8c, 0x7b, 0x00, 0xc0, 0x7e, 0xe2,
- 0xe1, 0x99, 0x5c, 0x88, 0xea, 0x7f, 0xb9, 0x5a, 0x43, 0xfc, 0x01, 0x8e,
- 0xe7, 0x24, 0xd1, 0xac, 0x43, 0x4a, 0xac, 0x34, 0xf1, 0xc9, 0xf2, 0x48,
- 0xf4, 0x32, 0xc5, 0x2f, 0x3f, 0xe5, 0xaa, 0xdd, 0x85, 0x46, 0xfc, 0x2c,
- 0xd7, 0x88, 0x57, 0x73, 0xa4, 0xc3, 0xd8, 0x48, 0xbf, 0x87, 0x62, 0xe4,
- 0xd2, 0x98, 0x0b, 0x5b, 0x23, 0x86, 0xdf, 0x83, 0x28, 0xce, 0x25, 0xae,
- 0x47, 0x2a, 0x10, 0xee, 0x19, 0x41, 0x13, 0xde, 0xcc, 0x81, 0x30, 0x04,
- 0xdc, 0x4b, 0x68, 0x8e, 0xf7, 0x62, 0xc6, 0x90, 0x0b, 0x0a, 0xd5, 0x1f,
- 0x88, 0xd7, 0xc3, 0xac, 0x39, 0x19, 0xa7, 0x1c, 0x5d, 0x6c, 0x44, 0x6f,
- 0xae, 0x09, 0xfd, 0x94, 0xab, 0x56, 0xaf, 0x8c, 0xe3, 0xdd, 0xac, 0x57,
- 0xdc, 0x94, 0x1d, 0xe9, 0xf7, 0xd3, 0x9c, 0xae, 0xe5, 0xca, 0xd0, 0xb3,
- 0x04, 0xd8, 0x64, 0x84, 0xd9, 0xbc, 0xb7, 0xfb, 0x28, 0xde, 0x1e, 0x16,
- 0x9f, 0xe1, 0x49, 0xb2, 0xc1, 0x2d, 0x9a, 0x52, 0xb9, 0x20, 0x45, 0x4e,
- 0xaf, 0x87, 0x32, 0x7c, 0x9b, 0x30, 0xa2, 0x0d, 0x14, 0x47, 0x9a, 0xed,
- 0x18, 0x61, 0x44, 0x84, 0x4c, 0x98, 0xdc, 0x09, 0xb7, 0x6a, 0xa0, 0xa7,
- 0x93, 0x65, 0xea, 0x86, 0xfb, 0x29, 0xb2, 0x1b, 0xc7, 0x17, 0xfb, 0xf3,
- 0x8d, 0x78, 0x83, 0xf2, 0xe4, 0xeb, 0x39, 0xc8, 0xb5, 0x14, 0xfb, 0x3f,
- 0xa0, 0xd8, 0x7f, 0x2a, 0x36, 0x12, 0xe2, 0x98, 0x5f, 0x88, 0xe1, 0x5b,
- 0x04, 0x83, 0x5b, 0xbc, 0xb4, 0xe6, 0x26, 0xc1, 0xeb, 0x20, 0xb9, 0x58,
- 0xe7, 0xbe, 0x9a, 0xc5, 0x0f, 0xc5, 0x61, 0xe6, 0xe9, 0xff, 0x27, 0xed,
- 0xdb, 0x6b, 0xe1, 0x69, 0x22, 0x5d, 0xce, 0xf7, 0x24, 0xaf, 0xed, 0x47,
- 0x72, 0x1d, 0x63, 0xe3, 0xc2, 0x1a, 0xbd, 0x4e, 0xbc, 0x94, 0x63, 0x9b,
- 0x33, 0xf1, 0xbc, 0xa6, 0x51, 0xcd, 0xc2, 0xb5, 0xf6, 0x10, 0xd5, 0x2d,
- 0xdc, 0x27, 0x32, 0xdc, 0x27, 0x89, 0xc2, 0xbd, 0x39, 0xfc, 0x9e, 0x0c,
- 0x69, 0x59, 0x2d, 0xa6, 0x90, 0x77, 0x3a, 0x09, 0x6b, 0x70, 0x8c, 0x65,
- 0x3f, 0x7a, 0xab, 0x4b, 0xcd, 0xc3, 0xf0, 0xea, 0x3d, 0x30, 0x2c, 0xdf,
- 0xad, 0x13, 0x0f, 0x90, 0x8d, 0xbc, 0x1c, 0xab, 0x45, 0x9e, 0xea, 0x1e,
- 0xc2, 0xdf, 0xee, 0x3f, 0xa3, 0xe7, 0x13, 0x13, 0xd8, 0x13, 0x84, 0xf4,
- 0x5d, 0x3f, 0xfe, 0x02, 0x67, 0x5d, 0x8c, 0xcb, 0xe1, 0xee, 0x8b, 0x1b,
- 0x9e, 0xf5, 0xf1, 0x3a, 0x71, 0x7b, 0xae, 0x1d, 0x17, 0x27, 0x1b, 0xc9,
- 0xbe, 0x9b, 0xb0, 0x78, 0x3c, 0x88, 0xf7, 0x88, 0x96, 0x61, 0x8d, 0xb1,
- 0xba, 0x31, 0xdc, 0x0c, 0x65, 0x88, 0xea, 0xa1, 0xbe, 0x9f, 0x0b, 0xf6,
- 0x01, 0xa5, 0xe7, 0x0e, 0xe1, 0x81, 0x1a, 0x49, 0x92, 0xec, 0x4d, 0x73,
- 0x4c, 0x6b, 0xd3, 0xbc, 0xe0, 0xfe, 0xcf, 0xdd, 0xd8, 0x3f, 0xc7, 0xb4,
- 0x9c, 0xea, 0xba, 0x61, 0x96, 0x3f, 0x4f, 0x77, 0x5d, 0x6f, 0x7d, 0xbe,
- 0x56, 0xfd, 0xac, 0x74, 0x85, 0xac, 0xcf, 0x1f, 0xd1, 0x27, 0xf7, 0x99,
- 0xc3, 0x46, 0x8d, 0xf8, 0xbe, 0x8b, 0xfb, 0xcd, 0x49, 0xf0, 0xff, 0x71,
- 0x97, 0xdd, 0xaf, 0xbb, 0x1b, 0x86, 0xd5, 0x13, 0xf9, 0xb5, 0xd5, 0x8b,
- 0x0e, 0x91, 0x1b, 0xc8, 0xc4, 0x9f, 0x4c, 0x58, 0x2b, 0x10, 0xa3, 0xc2,
- 0xbc, 0x49, 0x36, 0x16, 0xeb, 0xfd, 0x54, 0x1b, 0xc8, 0xc4, 0xaf, 0x81,
- 0x3d, 0x9d, 0x02, 0xfb, 0x55, 0x1d, 0x3f, 0x2d, 0x70, 0x0c, 0x77, 0xe2,
- 0x99, 0xb4, 0x12, 0x4a, 0x89, 0x30, 0xd5, 0xf9, 0x0e, 0x84, 0x9a, 0xfb,
- 0xb1, 0x9f, 0xf2, 0xc9, 0x6c, 0x9a, 0xf3, 0x07, 0x7d, 0x52, 0x3c, 0x6f,
- 0xa0, 0xf8, 0xf3, 0xf1, 0xa8, 0x1d, 0xef, 0x8b, 0x71, 0x65, 0xef, 0x1f,
- 0x90, 0x4e, 0x9f, 0x2b, 0xf2, 0x9c, 0x06, 0xae, 0xac, 0x64, 0x1f, 0x56,
- 0xa2, 0x29, 0xc7, 0x7d, 0x08, 0xcd, 0x70, 0x6c, 0xa1, 0xe5, 0x68, 0xad,
- 0x83, 0xd9, 0x1a, 0xf4, 0xc5, 0x7b, 0x45, 0x7f, 0xa9, 0x8f, 0xf7, 0x14,
- 0xfc, 0x0b, 0xf4, 0x3b, 0xc5, 0x9a, 0x69, 0xee, 0x09, 0x6e, 0x10, 0x7d,
- 0x25, 0xee, 0x0b, 0x0e, 0x8b, 0x6f, 0x94, 0xd8, 0xe7, 0xe7, 0xfb, 0x83,
- 0xf3, 0xfa, 0xe7, 0xbe, 0xa0, 0xe1, 0x7e, 0x89, 0x64, 0xbf, 0x3d, 0xc7,
- 0x71, 0x58, 0x7a, 0xc0, 0x87, 0xe5, 0xc8, 0xbb, 0xe0, 0x3e, 0x11, 0xff,
- 0x1d, 0xdc, 0x45, 0xb8, 0x60, 0xb1, 0x6a, 0xeb, 0x6f, 0x75, 0xde, 0x81,
- 0xc4, 0x72, 0x12, 0xfa, 0x02, 0xd6, 0xe9, 0x00, 0xc5, 0xb3, 0x8c, 0x39,
- 0x18, 0x60, 0x5d, 0xb2, 0xbd, 0x59, 0x7d, 0x27, 0xca, 0x2b, 0x06, 0x22,
- 0x9d, 0x6e, 0xcc, 0xe6, 0x16, 0x51, 0x4d, 0x60, 0x62, 0xaf, 0x56, 0x8f,
- 0x5a, 0x2b, 0x06, 0xb8, 0x09, 0x47, 0x42, 0xf6, 0xd2, 0x3c, 0xe9, 0x31,
- 0x19, 0x1e, 0xba, 0x77, 0x92, 0x72, 0xd3, 0xfe, 0x4e, 0x7b, 0xee, 0xb6,
- 0xfc, 0x4d, 0xd8, 0x47, 0x1e, 0x5f, 0xaf, 0x46, 0x31, 0xea, 0xf7, 0x52,
- 0xac, 0xf9, 0x56, 0x75, 0xce, 0xcf, 0xc8, 0x36, 0x79, 0xbd, 0x4d, 0xb5,
- 0xb6, 0x1e, 0x96, 0xc9, 0x76, 0xed, 0x25, 0x1b, 0x75, 0xb4, 0xd6, 0xd6,
- 0xce, 0x0d, 0xe8, 0x19, 0xf5, 0x8a, 0x57, 0xd3, 0xf7, 0x98, 0xa1, 0x46,
- 0x1a, 0x47, 0x36, 0x5b, 0x53, 0xa5, 0xb7, 0x35, 0xff, 0xcf, 0xb5, 0x5c,
- 0xa7, 0x7b, 0x29, 0x8f, 0x3c, 0x98, 0x73, 0x20, 0x50, 0xbd, 0x1e, 0xcf,
- 0x87, 0xa0, 0x75, 0xd4, 0x01, 0x4d, 0x82, 0xae, 0xf1, 0xdc, 0xbc, 0x86,
- 0x8c, 0x46, 0xf2, 0x93, 0x6f, 0xc7, 0x13, 0xf8, 0x20, 0xeb, 0xc4, 0x7a,
- 0xca, 0xef, 0x6b, 0xd3, 0x3a, 0xce, 0x95, 0x6b, 0x79, 0x3d, 0xb2, 0xc3,
- 0xf9, 0x71, 0x4e, 0x1a, 0xe7, 0xc6, 0x74, 0xfe, 0x8b, 0xf4, 0x05, 0x88,
- 0xe6, 0x22, 0x8d, 0xe5, 0x7b, 0xe7, 0xad, 0xbe, 0xc0, 0xf1, 0x6b, 0xea,
- 0x29, 0xc7, 0x38, 0xf7, 0x8a, 0xec, 0x5c, 0xd0, 0xad, 0xb1, 0x2e, 0x7d,
- 0xb8, 0x3c, 0x61, 0xe0, 0xdc, 0xca, 0x06, 0x5c, 0x99, 0x68, 0xc5, 0x03,
- 0x39, 0x0f, 0x2e, 0x4c, 0x98, 0xb8, 0x69, 0x39, 0xee, 0x09, 0x12, 0x06,
- 0x6b, 0x20, 0xbf, 0xff, 0x29, 0xd5, 0x3c, 0x14, 0x4f, 0x89, 0xd2, 0x48,
- 0x62, 0x1d, 0xd9, 0x75, 0x34, 0x86, 0xd4, 0x2d, 0xf1, 0x48, 0xe8, 0x3c,
- 0xbe, 0x67, 0x52, 0x2c, 0xf6, 0x4b, 0x7a, 0xaf, 0x70, 0x5a, 0xfb, 0x84,
- 0x1b, 0xac, 0x7d, 0x45, 0xc7, 0xf4, 0xb0, 0x90, 0x4a, 0xd7, 0xfa, 0xf5,
- 0x97, 0xe5, 0x21, 0xce, 0x3d, 0x9c, 0x23, 0xc7, 0x4d, 0x97, 0xba, 0xc1,
- 0xea, 0xd3, 0xec, 0xce, 0x5f, 0xcd, 0x4d, 0x57, 0xf3, 0xd1, 0xce, 0x6a,
- 0x1e, 0x1a, 0x29, 0xbc, 0xf3, 0x05, 0xfc, 0x14, 0xaa, 0xee, 0x57, 0x70,
- 0xfe, 0x71, 0x8b, 0xb3, 0x64, 0x0e, 0x7b, 0xc8, 0x07, 0x8f, 0x6a, 0x27,
- 0x82, 0x94, 0x21, 0xe0, 0xec, 0x10, 0x78, 0x90, 0xcf, 0x8b, 0x04, 0x4c,
- 0xdc, 0xa9, 0xd9, 0xf6, 0xb0, 0xbc, 0xd3, 0x85, 0x41, 0xca, 0x49, 0xae,
- 0x98, 0x97, 0x7c, 0xdd, 0x8f, 0xd7, 0x34, 0xb6, 0xe1, 0x5b, 0xaa, 0x39,
- 0x89, 0xf7, 0xbf, 0xed, 0xbd, 0xea, 0xdf, 0xee, 0x5b, 0xcf, 0xdb, 0xa6,
- 0x86, 0xe4, 0x42, 0x78, 0xde, 0x8b, 0xab, 0x54, 0x37, 0xc8, 0x54, 0x33,
- 0xac, 0x47, 0x62, 0x81, 0x92, 0x64, 0xfd, 0xfb, 0x68, 0xee, 0x5f, 0x76,
- 0x0e, 0xe2, 0xfe, 0x71, 0x07, 0xea, 0x54, 0x8e, 0xb3, 0x06, 0xf6, 0x37,
- 0x72, 0x9c, 0xea, 0xc5, 0x8e, 0x71, 0xb7, 0x38, 0x99, 0x73, 0xe2, 0xc9,
- 0xbe, 0x47, 0xb0, 0xa0, 0x63, 0x4b, 0xb5, 0xd7, 0xc9, 0xdf, 0xbf, 0x89,
- 0xd4, 0x22, 0x5e, 0x9f, 0x7b, 0x68, 0x02, 0xde, 0x0e, 0xe6, 0x03, 0x9e,
- 0x8b, 0x34, 0xff, 0xe6, 0x51, 0xa7, 0x38, 0x9f, 0xfe, 0x1b, 0xf3, 0x48,
- 0x80, 0x71, 0x01, 0xdf, 0xab, 0x87, 0xd1, 0xc8, 0x63, 0x59, 0x87, 0x5e,
- 0xaa, 0x49, 0x07, 0x31, 0x4a, 0x74, 0xbd, 0x6e, 0xcd, 0x75, 0xb6, 0x4a,
- 0xbf, 0x57, 0x34, 0x64, 0x64, 0x23, 0x48, 0xb4, 0xf8, 0x57, 0xf6, 0xa1,
- 0xa1, 0x74, 0x6d, 0xbe, 0x25, 0xa3, 0xf7, 0x30, 0x7f, 0x9c, 0x13, 0x06,
- 0xf0, 0x41, 0x5a, 0xe0, 0x7d, 0xcb, 0x06, 0x07, 0xd0, 0x5a, 0xa0, 0xfa,
- 0xdf, 0x8a, 0x21, 0x3c, 0x2e, 0x6e, 0xdb, 0xb6, 0x63, 0x10, 0xdb, 0x89,
- 0x97, 0x7a, 0xe2, 0xe5, 0xe3, 0xd8, 0x12, 0x5a, 0x87, 0xaf, 0x1d, 0x93,
- 0xab, 0xfd, 0x87, 0xea, 0x5c, 0xab, 0xc0, 0xbd, 0x29, 0xa7, 0x1a, 0xc1,
- 0xb6, 0xf1, 0x48, 0xbf, 0xd7, 0xc1, 0x76, 0x18, 0xc1, 0x7d, 0xd3, 0x49,
- 0xba, 0xcf, 0x73, 0x05, 0xb1, 0x29, 0xe3, 0x14, 0xef, 0x52, 0x9d, 0x74,
- 0x3c, 0xed, 0x58, 0x24, 0xe1, 0x07, 0xe6, 0x93, 0x81, 0x1d, 0xb8, 0x45,
- 0xeb, 0xc5, 0xbd, 0x64, 0x83, 0xdd, 0xad, 0x3b, 0x30, 0x41, 0x36, 0xb0,
- 0xb9, 0x89, 0x6a, 0xb7, 0x58, 0xd9, 0x1c, 0x08, 0xb0, 0x1c, 0x05, 0x7a,
- 0xe8, 0x7a, 0x23, 0xd5, 0x73, 0x8e, 0x18, 0x59, 0x1b, 0xf9, 0x85, 0xac,
- 0x2a, 0xb9, 0x24, 0xea, 0xad, 0x35, 0x1b, 0x29, 0x4f, 0xbb, 0x18, 0x1f,
- 0xf8, 0x18, 0x27, 0x7c, 0x91, 0x1e, 0xc3, 0xac, 0x55, 0xd5, 0xe8, 0x7a,
- 0x47, 0x6b, 0x6e, 0x8e, 0x6c, 0x76, 0x4d, 0xc7, 0xb5, 0xcf, 0xcd, 0xcb,
- 0x48, 0x43, 0x4d, 0xc7, 0x8c, 0x59, 0xf1, 0x8f, 0xc0, 0xdf, 0x71, 0xad,
- 0xee, 0xe7, 0xe7, 0x60, 0x9a, 0xed, 0xb8, 0x16, 0x72, 0x44, 0xfc, 0xf7,
- 0xe0, 0xaf, 0x68, 0x8d, 0x20, 0x36, 0x96, 0x7a, 0x31, 0x30, 0x2e, 0x7d,
- 0x8e, 0x4f, 0x7c, 0x6c, 0xcb, 0x9f, 0xf3, 0xbf, 0x75, 0x3c, 0xd2, 0xe3,
- 0xa9, 0xf2, 0x7f, 0xef, 0xf4, 0xe7, 0x73, 0x0d, 0x67, 0x38, 0xaf, 0xf2,
- 0x7c, 0xbc, 0xef, 0x37, 0x2f, 0xdf, 0x20, 0xb6, 0x5b, 0xf3, 0xed, 0x75,
- 0xb3, 0x0f, 0xbb, 0xc8, 0xd7, 0xd7, 0x75, 0x18, 0x78, 0x2d, 0xf1, 0x80,
- 0xb9, 0xd5, 0x92, 0xc1, 0x9f, 0x58, 0xcf, 0xf7, 0xb4, 0x56, 0x2c, 0x7b,
- 0xb7, 0xfd, 0x96, 0xf7, 0x04, 0x78, 0x8f, 0x60, 0x7e, 0x5f, 0x20, 0x6a,
- 0xed, 0xd7, 0xd9, 0x7b, 0x03, 0xdf, 0xa2, 0x38, 0xcb, 0xfb, 0x06, 0xb2,
- 0x70, 0x8e, 0xd7, 0x09, 0xd7, 0x38, 0xd3, 0xf6, 0x81, 0x6c, 0xfb, 0xd8,
- 0x5f, 0x21, 0x19, 0xe0, 0xfe, 0xa4, 0x6d, 0xff, 0xd1, 0xce, 0xfb, 0x80,
- 0xa7, 0x0c, 0x77, 0xed, 0x0a, 0x50, 0x8d, 0xdf, 0x67, 0xd9, 0xc3, 0x75,
- 0xfa, 0xdb, 0xab, 0xfe, 0xb1, 0x95, 0xeb, 0x7c, 0xee, 0x09, 0xbe, 0xbb,
- 0x6a, 0xb2, 0x55, 0x22, 0x3c, 0xc5, 0x6b, 0xf2, 0xde, 0x02, 0xe7, 0x55,
- 0x2b, 0xee, 0x7a, 0x1a, 0x57, 0x18, 0xee, 0x05, 0x2b, 0x9c, 0x62, 0x51,
- 0xa6, 0x9f, 0x6c, 0x4f, 0x45, 0x22, 0x63, 0x78, 0x9a, 0x57, 0x84, 0xf0,
- 0x50, 0x66, 0x3e, 0x26, 0xb7, 0xa3, 0x7d, 0x0a, 0xf8, 0xdf, 0x99, 0x20,
- 0xda, 0x26, 0xc2, 0x43, 0xb7, 0x3b, 0xc2, 0xc3, 0xef, 0x38, 0xf8, 0x5e,
- 0xa1, 0xeb, 0x26, 0x0b, 0x7f, 0x1f, 0xed, 0x5a, 0x66, 0x7d, 0xbe, 0xdd,
- 0x75, 0x63, 0xe1, 0x6e, 0xa4, 0xe7, 0xdc, 0x97, 0xf3, 0x0e, 0x13, 0x0f,
- 0xc5, 0x1c, 0xf8, 0x9a, 0xf6, 0xd7, 0xe4, 0x5b, 0x82, 0x6c, 0xe3, 0x18,
- 0xe7, 0x60, 0x4b, 0xa7, 0xae, 0x15, 0x2a, 0xda, 0x32, 0x8d, 0x84, 0xd7,
- 0x9a, 0xa8, 0xe6, 0x6f, 0xc4, 0x0f, 0x73, 0x8c, 0xd7, 0x4c, 0x8a, 0xfb,
- 0x26, 0x5e, 0xef, 0x30, 0x86, 0x82, 0x50, 0x8c, 0x37, 0x85, 0x92, 0xba,
- 0xdd, 0xa1, 0x1c, 0x69, 0x72, 0xf8, 0xb1, 0x2f, 0x62, 0xe7, 0xd1, 0x4e,
- 0x2b, 0x6f, 0xbe, 0xd3, 0x65, 0xf7, 0xec, 0x4e, 0x56, 0xf3, 0xeb, 0xa9,
- 0x2e, 0x6d, 0x56, 0x39, 0x9a, 0x22, 0xff, 0x59, 0x48, 0xf1, 0x73, 0x3c,
- 0x9b, 0xb2, 0xce, 0x82, 0xfc, 0x32, 0x53, 0x43, 0xb6, 0x11, 0xd6, 0xc6,
- 0x11, 0x8e, 0x3e, 0x64, 0xd1, 0xfa, 0xb3, 0xae, 0x58, 0xa1, 0x8c, 0x8a,
- 0x53, 0x39, 0x08, 0x14, 0x09, 0x37, 0xb4, 0xf9, 0x5f, 0x46, 0x99, 0xfb,
- 0xa1, 0x56, 0xa0, 0x67, 0x1e, 0x5a, 0x0b, 0x40, 0x2e, 0xe3, 0xbe, 0x0c,
- 0xab, 0x17, 0xeb, 0xc0, 0x5a, 0x6d, 0x3b, 0xe1, 0x42, 0xde, 0xff, 0x15,
- 0x54, 0x63, 0x37, 0xa2, 0xb2, 0xc1, 0x89, 0xf1, 0x0c, 0xe7, 0xe1, 0x63,
- 0x5d, 0xf2, 0x28, 0x2a, 0x6e, 0x7b, 0x4f, 0x33, 0xe1, 0xa6, 0x0c, 0x3d,
- 0x57, 0x22, 0x4c, 0x4a, 0xb1, 0x63, 0x6b, 0xec, 0x37, 0x66, 0xb2, 0xd1,
- 0xde, 0x53, 0x19, 0x9d, 0x14, 0x58, 0xa0, 0x26, 0x31, 0x3a, 0xe7, 0xf4,
- 0xa5, 0xd3, 0x51, 0xa4, 0xcb, 0xfc, 0xbc, 0xfb, 0x72, 0xd2, 0x9a, 0x3f,
- 0xb2, 0x77, 0x89, 0xc3, 0x81, 0x65, 0x1d, 0x87, 0x50, 0x59, 0x68, 0xd3,
- 0x10, 0x24, 0x4c, 0xc0, 0x35, 0x6c, 0x13, 0xf1, 0x7a, 0xe7, 0xe3, 0x5c,
- 0x47, 0xfc, 0xa4, 0xeb, 0xe6, 0x29, 0xf6, 0xeb, 0x63, 0x5d, 0x1f, 0xa4,
- 0x95, 0x64, 0x93, 0x04, 0xb9, 0x8e, 0xf8, 0xbf, 0x6f, 0x94, 0xfb, 0x08,
- 0xbf, 0xe0, 0x3e, 0x02, 0xe5, 0x65, 0x65, 0xb8, 0x59, 0x78, 0xc5, 0xba,
- 0x0c, 0xd5, 0x15, 0x44, 0xf3, 0xa5, 0x88, 0xd2, 0x53, 0x22, 0x8c, 0xb2,
- 0x45, 0x50, 0x5d, 0x57, 0xb6, 0xe5, 0x65, 0x9f, 0xcd, 0xab, 0x5c, 0xc5,
- 0x21, 0x51, 0x0b, 0x77, 0xf0, 0x3e, 0x34, 0xe7, 0x71, 0x6b, 0x4f, 0x9f,
- 0xae, 0xff, 0xbc, 0x6b, 0x09, 0xd5, 0x16, 0x23, 0x4c, 0x1f, 0x78, 0xaf,
- 0x8f, 0x6a, 0xd0, 0xec, 0xf1, 0x2a, 0x2e, 0xf1, 0x56, 0xe5, 0xc2, 0xdf,
- 0xf9, 0x4c, 0xe2, 0x6b, 0x5d, 0x9b, 0x26, 0xf9, 0x8c, 0xe2, 0x4f, 0xba,
- 0xd6, 0x4c, 0x2a, 0xa1, 0x8d, 0xb4, 0xee, 0x6e, 0xde, 0x5f, 0xa7, 0x39,
- 0x67, 0x35, 0xa6, 0xbb, 0xd0, 0x75, 0x73, 0x96, 0x7b, 0xcb, 0xc7, 0xba,
- 0xcc, 0x6c, 0x98, 0x31, 0xa8, 0x65, 0x2b, 0x89, 0x02, 0x55, 0xf3, 0xd7,
- 0xd9, 0xbc, 0xba, 0x48, 0x1f, 0x87, 0xd2, 0x84, 0x76, 0xe2, 0xb6, 0x6e,
- 0x56, 0x17, 0xd6, 0x20, 0xd5, 0xd4, 0x4d, 0x35, 0xa8, 0xdf, 0xb7, 0x36,
- 0xd3, 0x8d, 0x09, 0xd2, 0xe1, 0xa6, 0x52, 0xd0, 0xd7, 0x9d, 0x51, 0x31,
- 0x50, 0xe2, 0x7a, 0xb3, 0xd2, 0xb5, 0x6b, 0x72, 0xaa, 0x5a, 0xff, 0xf6,
- 0x53, 0xcd, 0x4a, 0x76, 0x91, 0xb1, 0x6d, 0xae, 0xb5, 0x40, 0x34, 0x0b,
- 0x7b, 0x5e, 0x37, 0xad, 0x73, 0xfd, 0xe8, 0x77, 0xcd, 0xd0, 0x42, 0xb6,
- 0x85, 0xbb, 0xf1, 0xf8, 0x94, 0xcf, 0x08, 0xe8, 0x7e, 0x74, 0x76, 0x9c,
- 0xa2, 0x67, 0xdb, 0xf1, 0xf8, 0xe1, 0x5b, 0x90, 0xff, 0x23, 0x27, 0x2e,
- 0x66, 0x92, 0x58, 0xda, 0xf1, 0x55, 0x9c, 0xd9, 0x20, 0xe3, 0xef, 0x32,
- 0x5e, 0x5c, 0x22, 0xfe, 0x0c, 0x6b, 0x8e, 0x7f, 0xcf, 0xfe, 0x90, 0x5b,
- 0xb8, 0xc7, 0x35, 0xc6, 0x9e, 0xbf, 0xe7, 0x06, 0xf7, 0xde, 0x0c, 0xd4,
- 0x10, 0x0e, 0x0a, 0x13, 0xcd, 0x6a, 0x86, 0xcf, 0x38, 0x05, 0x7c, 0x9c,
- 0x2b, 0xa7, 0x89, 0x27, 0x47, 0xa9, 0xc5, 0xe7, 0x24, 0x7e, 0x9c, 0xa5,
- 0x73, 0x14, 0x03, 0xd8, 0x07, 0xdc, 0x97, 0x43, 0x96, 0x1d, 0x5c, 0xbb,
- 0xf6, 0x7e, 0x0f, 0xef, 0xf1, 0x1f, 0xcf, 0x72, 0x6c, 0x14, 0x54, 0xbb,
- 0x84, 0x90, 0x9c, 0x5d, 0x82, 0x9e, 0xd9, 0xed, 0x74, 0x5d, 0x45, 0x5f,
- 0xd5, 0xd7, 0x42, 0x05, 0x8f, 0x87, 0xf1, 0x49, 0x2e, 0x63, 0xff, 0x8e,
- 0x5c, 0xfd, 0xed, 0x16, 0x8d, 0xe3, 0x84, 0x1d, 0x11, 0xb7, 0xf2, 0xb0,
- 0xda, 0xf1, 0xef, 0xe2, 0xe5, 0x72, 0xca, 0xa2, 0x61, 0x37, 0xcd, 0xc5,
- 0xb2, 0x79, 0xce, 0x4c, 0xdd, 0xc9, 0xf2, 0x0b, 0xf8, 0x7e, 0x48, 0xfa,
- 0x98, 0xa4, 0x67, 0x1e, 0x27, 0x1e, 0xca, 0xc4, 0x5b, 0xb6, 0xf4, 0x5d,
- 0x1a, 0xc3, 0xf7, 0x40, 0xfa, 0x32, 0x14, 0x67, 0xf5, 0x6c, 0xe6, 0x08,
- 0xe5, 0xcb, 0x5a, 0x8a, 0x45, 0x67, 0xe3, 0xf7, 0x62, 0x6d, 0x4e, 0x49,
- 0x1a, 0x14, 0x2e, 0x53, 0x7e, 0x08, 0xa7, 0xce, 0x36, 0xfc, 0x36, 0xd9,
- 0x70, 0x0b, 0x61, 0x80, 0x70, 0xe8, 0x1c, 0x8d, 0x37, 0x9c, 0x32, 0x1e,
- 0x9b, 0x90, 0x70, 0x8e, 0xf7, 0x80, 0x85, 0xfd, 0xbc, 0x01, 0x1e, 0x3b,
- 0xff, 0xbd, 0x8e, 0xea, 0xba, 0x70, 0x82, 0xb2, 0xaa, 0x51, 0x4f, 0xb8,
- 0xbd, 0xd0, 0xf9, 0x08, 0xf6, 0x53, 0x7d, 0xbf, 0x35, 0x46, 0x32, 0x69,
- 0x8c, 0x53, 0xbd, 0xd1, 0x36, 0x74, 0x01, 0x7f, 0x67, 0x56, 0x78, 0x1f,
- 0x5d, 0x84, 0x13, 0x17, 0xf0, 0x99, 0x29, 0xa9, 0xea, 0xe9, 0x19, 0xa8,
- 0x95, 0x73, 0x68, 0x1b, 0xbe, 0x82, 0x0f, 0x4d, 0xde, 0x63, 0x97, 0x25,
- 0x89, 0x30, 0x60, 0xd8, 0xef, 0x44, 0x00, 0x95, 0x80, 0x84, 0x5b, 0x35,
- 0xee, 0x49, 0x2b, 0xc3, 0x4f, 0x13, 0x96, 0x7f, 0x5f, 0xb4, 0x0d, 0x7e,
- 0x8c, 0x33, 0x66, 0xbe, 0x91, 0xd7, 0x15, 0x48, 0xdc, 0xd8, 0x76, 0xba,
- 0x06, 0x4a, 0x8f, 0x4b, 0xa8, 0x89, 0x66, 0xe9, 0xaf, 0xcd, 0x33, 0x81,
- 0xcf, 0x4c, 0x35, 0xf2, 0x19, 0xe1, 0x20, 0x35, 0x38, 0x4d, 0x3e, 0x31,
- 0x88, 0x79, 0xda, 0xfe, 0x81, 0xf8, 0xd7, 0x88, 0x06, 0xc6, 0x7d, 0x86,
- 0x7b, 0x0f, 0xd1, 0xf6, 0x53, 0xc2, 0x01, 0x5b, 0x63, 0x17, 0xcc, 0xe4,
- 0x42, 0xeb, 0xfc, 0x5e, 0x9d, 0xdd, 0xfb, 0x66, 0x5f, 0xb9, 0x1b, 0x9b,
- 0xd2, 0x4e, 0x92, 0xd3, 0x3c, 0x5e, 0x73, 0x51, 0x0c, 0x66, 0x8c, 0x53,
- 0xb9, 0x9e, 0x4a, 0x33, 0xc7, 0xac, 0x0a, 0xec, 0xa2, 0xb8, 0xb0, 0xd3,
- 0xca, 0x05, 0xf0, 0x2c, 0x5e, 0xd1, 0x81, 0x2b, 0x53, 0xff, 0xc3, 0x43,
- 0xfa, 0x5b, 0xad, 0x2e, 0x87, 0x08, 0x66, 0x0c, 0xd1, 0xa0, 0x4b, 0xf8,
- 0xb8, 0x53, 0xe9, 0x71, 0x48, 0xc3, 0xb8, 0x31, 0x66, 0x98, 0x5e, 0x55,
- 0xed, 0x6f, 0x17, 0x91, 0xbe, 0x92, 0x88, 0xa2, 0xae, 0xe4, 0x95, 0xeb,
- 0x4a, 0xed, 0xb2, 0xa7, 0x64, 0xb8, 0xfd, 0x2b, 0xee, 0xa5, 0xba, 0x65,
- 0x07, 0xd5, 0xb6, 0x5e, 0xaa, 0xaf, 0x15, 0xb2, 0xc7, 0x1a, 0x92, 0x7f,
- 0x88, 0xe2, 0x80, 0x0e, 0x67, 0x66, 0x1b, 0x5c, 0x99, 0xb0, 0x7f, 0x37,
- 0x76, 0x20, 0x19, 0xb4, 0xb1, 0xad, 0x4c, 0xba, 0xaa, 0xed, 0x64, 0x2c,
- 0x73, 0x2f, 0xce, 0xe4, 0x19, 0x9f, 0x27, 0xb0, 0x31, 0xcd, 0xbf, 0xe1,
- 0x79, 0x39, 0xae, 0xe3, 0x28, 0xd5, 0x4e, 0xee, 0x8e, 0x66, 0xd2, 0x43,
- 0x0b, 0x46, 0xca, 0x82, 0x4d, 0x90, 0x74, 0x01, 0xcf, 0xd1, 0x4e, 0x19,
- 0xfb, 0x66, 0x28, 0x91, 0x50, 0x9e, 0x72, 0x92, 0x9d, 0xef, 0x26, 0x1b,
- 0xf2, 0xaa, 0x5e, 0xfa, 0x1d, 0xe0, 0x73, 0x47, 0x64, 0x93, 0x3f, 0xe9,
- 0x6a, 0xb7, 0x62, 0xcd, 0x2f, 0xa8, 0xc6, 0xf9, 0x15, 0xf1, 0xc2, 0xb2,
- 0xd0, 0x51, 0x37, 0x3e, 0x5f, 0x13, 0xae, 0xb9, 0xa3, 0x0e, 0x41, 0x9a,
- 0x33, 0x58, 0xdd, 0x23, 0x13, 0x58, 0x13, 0xeb, 0x40, 0x31, 0x27, 0xaa,
- 0x18, 0x6b, 0x44, 0xf1, 0x62, 0x35, 0xf6, 0x53, 0xed, 0xef, 0x53, 0x37,
- 0x22, 0xe3, 0xaf, 0x78, 0xde, 0x89, 0x73, 0x0d, 0x00, 0xcf, 0x00, 0x61,
- 0xa8, 0xd1, 0xf4, 0x57, 0x90, 0x5f, 0x08, 0xf7, 0x3d, 0x71, 0x3e, 0x9f,
- 0x49, 0x21, 0x4a, 0x5d, 0x8d, 0x86, 0xe5, 0xbd, 0xf8, 0xb8, 0x91, 0xf1,
- 0xaf, 0x97, 0x62, 0x83, 0x8c, 0xdd, 0x33, 0x01, 0xeb, 0x5c, 0x04, 0xc5,
- 0xc0, 0x2a, 0xcd, 0xd7, 0xd2, 0xfa, 0x65, 0x34, 0xb2, 0x4c, 0xfe, 0x6f,
- 0x34, 0x92, 0xcd, 0x12, 0xe6, 0xc9, 0xa5, 0x07, 0xf0, 0x4a, 0x9a, 0xe7,
- 0x0d, 0x27, 0x35, 0xe1, 0xe7, 0x9e, 0xbc, 0x25, 0x13, 0x63, 0x86, 0xd7,
- 0xf0, 0x5a, 0xb1, 0xc9, 0x5e, 0x27, 0xc0, 0xbd, 0xa2, 0xff, 0xe0, 0x5a,
- 0x1a, 0xe5, 0xc7, 0xd5, 0x54, 0x77, 0x46, 0xa1, 0x7e, 0xa3, 0x42, 0xfa,
- 0xe0, 0x1e, 0xf5, 0x12, 0xc2, 0xbc, 0x70, 0xbf, 0x1a, 0xe7, 0x73, 0xc8,
- 0xe6, 0x0e, 0x59, 0x37, 0x4d, 0x57, 0xa7, 0xea, 0x7f, 0x0f, 0x6c, 0x87,
- 0x5e, 0xde, 0xeb, 0x70, 0xef, 0xee, 0xf4, 0x62, 0x1f, 0xe5, 0xc0, 0x67,
- 0xd3, 0x6d, 0x06, 0xd7, 0x7e, 0x60, 0x1c, 0x2a, 0x52, 0xf4, 0xec, 0x50,
- 0x1d, 0x9f, 0x09, 0xda, 0x55, 0xde, 0x06, 0x47, 0xe6, 0xb6, 0x3a, 0xae,
- 0x37, 0x6a, 0xa8, 0x4e, 0x1e, 0x49, 0x33, 0xbd, 0xdc, 0x7b, 0x33, 0xcd,
- 0x9d, 0x71, 0xf5, 0xf2, 0x5a, 0xb2, 0x8b, 0x66, 0x9d, 0xe5, 0x18, 0xc0,
- 0x93, 0x34, 0x36, 0x54, 0x66, 0x59, 0x7e, 0xb7, 0x8e, 0xfb, 0x9d, 0x7b,
- 0x48, 0xbf, 0x0d, 0x59, 0x7b, 0x9e, 0x6c, 0x79, 0x10, 0x4b, 0x46, 0x5f,
- 0xa8, 0xb3, 0x6b, 0x1f, 0xae, 0xcb, 0x87, 0xb0, 0x27, 0x1d, 0xc0, 0x4c,
- 0xba, 0xcd, 0xff, 0x12, 0x9c, 0xd5, 0xbc, 0xca, 0xe7, 0x88, 0xe7, 0xc7,
- 0x04, 0x30, 0x7d, 0xf5, 0x3b, 0xcb, 0xc7, 0xee, 0x99, 0x1e, 0xb7, 0x30,
- 0xbf, 0x8c, 0x7c, 0xc0, 0xae, 0x63, 0x28, 0x56, 0x78, 0x1e, 0x25, 0xbd,
- 0xbe, 0x4f, 0x7a, 0x75, 0x90, 0x5e, 0x5f, 0xd2, 0xfe, 0x92, 0x31, 0x8b,
- 0x7b, 0x57, 0xdc, 0xcb, 0xfb, 0x43, 0x06, 0x81, 0x16, 0x6b, 0x4c, 0x26,
- 0xee, 0xc4, 0xeb, 0x94, 0x07, 0x6b, 0x28, 0xfe, 0x9d, 0x4a, 0x9b, 0xab,
- 0xe7, 0x62, 0x6d, 0xa9, 0xf7, 0x29, 0x4f, 0x1b, 0x7f, 0xa8, 0x68, 0x67,
- 0xc8, 0x4f, 0xb3, 0x13, 0x7f, 0x8a, 0x33, 0x8d, 0x6d, 0xfe, 0xb7, 0x60,
- 0xb8, 0x9f, 0x88, 0x3f, 0x42, 0x35, 0x3f, 0xd5, 0x0d, 0xcb, 0xff, 0x0b,
- 0x39, 0x59, 0x1c, 0x92, 0xda, 0x76, 0xf9, 0x25, 0xfc, 0x15, 0xce, 0x5c,
- 0x17, 0xd6, 0x5e, 0x02, 0x8f, 0xb1, 0xeb, 0xf1, 0xf0, 0xec, 0xfd, 0x7c,
- 0x1e, 0x2a, 0x48, 0xe9, 0xcc, 0xde, 0xc7, 0x4a, 0xf3, 0xbe, 0x9b, 0x40,
- 0x7e, 0x03, 0xd5, 0xd2, 0xd6, 0x39, 0x54, 0x78, 0x9e, 0x26, 0xbf, 0x88,
- 0x8e, 0xf1, 0xf8, 0x63, 0x5d, 0x6a, 0x21, 0x04, 0x89, 0x30, 0x0e, 0x61,
- 0x84, 0x1e, 0x3e, 0x9f, 0xf1, 0x74, 0x3a, 0x48, 0xb9, 0xa0, 0xad, 0x2f,
- 0x2a, 0xbe, 0x0d, 0x1b, 0x03, 0x70, 0x9e, 0x3b, 0x46, 0x79, 0x4e, 0x49,
- 0x3d, 0x8d, 0xb6, 0x7e, 0xaf, 0xb8, 0x1b, 0xa9, 0xc6, 0xb6, 0xc1, 0xa3,
- 0x08, 0x13, 0x66, 0x50, 0xa2, 0x67, 0x60, 0xcf, 0xb3, 0xb4, 0x20, 0x51,
- 0x9d, 0xc8, 0x71, 0x26, 0x8d, 0xa3, 0x7e, 0x09, 0x37, 0x74, 0xa8, 0x97,
- 0xa7, 0x31, 0x6f, 0x2f, 0xf6, 0x98, 0xd5, 0x05, 0x1a, 0x2f, 0xf9, 0x09,
- 0xdb, 0xd4, 0xc0, 0x49, 0xb5, 0xbf, 0xa4, 0x6f, 0xc3, 0xd6, 0x34, 0xe7,
- 0x69, 0x92, 0x0b, 0xf9, 0x66, 0x5f, 0x64, 0x1b, 0x86, 0x0a, 0x01, 0xec,
- 0xcf, 0x86, 0xf7, 0xee, 0x26, 0x5c, 0x37, 0x56, 0x0e, 0x87, 0x36, 0x8b,
- 0x00, 0xe9, 0x9b, 0xea, 0xff, 0xa6, 0x20, 0xd5, 0xc9, 0x7e, 0xfa, 0xb7,
- 0xeb, 0x99, 0x53, 0x54, 0xcf, 0xbc, 0x4e, 0xbe, 0xe6, 0xad, 0xd6, 0xaa,
- 0x4b, 0xf3, 0x26, 0xe6, 0x62, 0xeb, 0x71, 0xc9, 0xd2, 0x59, 0x90, 0x6c,
- 0x8c, 0x73, 0x08, 0x9f, 0x8d, 0x71, 0x8b, 0xcd, 0x63, 0x86, 0xfb, 0xc1,
- 0xce, 0x20, 0xe5, 0x34, 0xc6, 0x9c, 0x8e, 0x3f, 0x92, 0x48, 0x1e, 0x33,
- 0xea, 0x0e, 0xac, 0x8b, 0xed, 0xc0, 0x90, 0xf6, 0x5d, 0xd4, 0x34, 0x71,
- 0x3c, 0x92, 0x8d, 0x06, 0x9a, 0xf7, 0x42, 0x67, 0x2f, 0xc2, 0x4f, 0x31,
- 0x3e, 0xfa, 0x19, 0xe1, 0x23, 0xf6, 0x5d, 0x9e, 0xbf, 0x51, 0x5f, 0x46,
- 0xb8, 0xa2, 0xbe, 0xd3, 0xce, 0xf3, 0x37, 0x16, 0xf8, 0x4c, 0x26, 0xa8,
- 0x36, 0x85, 0xe7, 0xdd, 0x95, 0x3a, 0x9e, 0xa0, 0x18, 0x93, 0x58, 0xee,
- 0x02, 0x16, 0xf0, 0xd9, 0x63, 0xbb, 0x8e, 0x61, 0x7e, 0x97, 0x14, 0x04,
- 0x66, 0xe3, 0x64, 0x1f, 0xff, 0xea, 0x8c, 0x51, 0xa8, 0x7a, 0x36, 0x94,
- 0xfb, 0x27, 0x07, 0xcc, 0x24, 0xbf, 0x33, 0xe0, 0xa8, 0xf3, 0x52, 0xbc,
- 0x0d, 0x56, 0x20, 0x79, 0x39, 0x2e, 0x4b, 0xea, 0xbc, 0xdc, 0x59, 0xd6,
- 0x47, 0x38, 0xbe, 0x5b, 0xba, 0x70, 0xd2, 0x33, 0xbb, 0x26, 0x95, 0xe1,
- 0xdd, 0x68, 0x1b, 0xfa, 0x40, 0xd4, 0x5a, 0x3b, 0x97, 0xd3, 0xed, 0x48,
- 0x2d, 0xd6, 0x9d, 0x1b, 0xae, 0x64, 0x57, 0x13, 0x1d, 0xe7, 0x4c, 0x5c,
- 0xb7, 0xc6, 0xda, 0xdf, 0x9a, 0x6e, 0xff, 0x73, 0x9a, 0x9b, 0xbf, 0x3f,
- 0xe0, 0xe5, 0x33, 0x93, 0xc7, 0xb3, 0x2f, 0x9a, 0xd1, 0x85, 0xb6, 0x7c,
- 0x4e, 0x90, 0xef, 0x07, 0x75, 0x07, 0x9a, 0xd5, 0xc8, 0xe5, 0x7e, 0xfa,
- 0xfd, 0xb7, 0x05, 0x42, 0xfb, 0x2b, 0x07, 0xf1, 0xab, 0xbc, 0x8e, 0xc7,
- 0x28, 0x0f, 0x34, 0xa8, 0x8a, 0x3f, 0xcf, 0xfb, 0xd7, 0x31, 0x9b, 0xff,
- 0x9b, 0xf2, 0xe4, 0x87, 0x8d, 0x7e, 0xab, 0xc6, 0xb0, 0xf9, 0x2b, 0x10,
- 0x7f, 0x03, 0x5e, 0xf6, 0x85, 0xc5, 0xe4, 0x17, 0x7b, 0xc9, 0x5f, 0x1f,
- 0x23, 0x5b, 0xa3, 0x0a, 0x9e, 0xfc, 0x40, 0xd9, 0x0b, 0xf2, 0xd7, 0xb1,
- 0x34, 0xcb, 0x3f, 0xe8, 0x1b, 0x18, 0xe5, 0xb8, 0x6b, 0xf5, 0x55, 0xb5,
- 0x90, 0x83, 0xe3, 0xae, 0x15, 0x4f, 0x8d, 0x90, 0xe3, 0xd7, 0x75, 0x4c,
- 0xd7, 0x48, 0x39, 0x1c, 0xf4, 0xf0, 0x79, 0x7e, 0x02, 0x87, 0x03, 0x9a,
- 0x9d, 0x2b, 0xe7, 0x28, 0x1f, 0x5d, 0x22, 0x3a, 0xf6, 0xc7, 0x9a, 0x91,
- 0xa2, 0x7c, 0x94, 0x51, 0x6d, 0x5b, 0x52, 0x67, 0x19, 0x63, 0xfe, 0x82,
- 0x30, 0xa6, 0x12, 0x72, 0x49, 0x6d, 0xc3, 0x27, 0xb1, 0xcd, 0x3c, 0xd3,
- 0xc8, 0x36, 0xe5, 0xc2, 0xe1, 0xf6, 0x59, 0xb3, 0x12, 0x60, 0x7e, 0x25,
- 0xbc, 0xa8, 0x91, 0xcd, 0x5c, 0x17, 0x0e, 0xbe, 0x48, 0x39, 0x75, 0xa6,
- 0xaa, 0x8f, 0x70, 0x61, 0xde, 0x1e, 0x63, 0x2c, 0xeb, 0x68, 0x0a, 0x6a,
- 0xa2, 0x80, 0x3f, 0xa6, 0xef, 0xad, 0xc1, 0x4b, 0x55, 0x5b, 0x5d, 0x36,
- 0xfb, 0xdf, 0xbd, 0xd5, 0x77, 0x6c, 0xac, 0x67, 0x42, 0x85, 0xfb, 0xe9,
- 0x37, 0xcf, 0x19, 0xe0, 0xb3, 0x2d, 0x7c, 0xd6, 0xca, 0xb3, 0xb5, 0xb3,
- 0x86, 0xfd, 0xc5, 0xcf, 0xef, 0x15, 0xac, 0x1b, 0xe3, 0xbe, 0x30, 0xf7,
- 0x68, 0x24, 0xec, 0xbe, 0xfa, 0xde, 0x03, 0x7f, 0xf6, 0xe0, 0xd6, 0x31,
- 0xee, 0x45, 0x9c, 0xb8, 0x59, 0xc6, 0x3f, 0x51, 0x1e, 0x96, 0xd9, 0xe7,
- 0xc9, 0xd7, 0x7f, 0xd4, 0x75, 0x6a, 0x92, 0x73, 0xea, 0xdb, 0x5d, 0x9b,
- 0xd2, 0xf3, 0x3a, 0xbe, 0xca, 0xd3, 0xe9, 0x7b, 0x28, 0xee, 0x64, 0xd2,
- 0xca, 0x70, 0x44, 0xb2, 0xf6, 0xd5, 0x52, 0x25, 0xf1, 0x15, 0x2a, 0xd2,
- 0x78, 0xbe, 0x5e, 0xf4, 0x8f, 0x85, 0xa8, 0xb6, 0xf1, 0xfb, 0x1e, 0x38,
- 0x60, 0x52, 0xae, 0x70, 0xe2, 0xe9, 0xd1, 0xb0, 0xf6, 0x26, 0xe1, 0x9d,
- 0x67, 0x46, 0x4d, 0xf3, 0x4d, 0x0d, 0x7f, 0xd2, 0x40, 0x35, 0x72, 0xbb,
- 0x50, 0x12, 0x84, 0x0d, 0x42, 0xeb, 0x45, 0x5b, 0xb0, 0x00, 0xe5, 0xf4,
- 0x4e, 0x9a, 0xef, 0x50, 0x11, 0x78, 0xb1, 0xe8, 0xc1, 0x0b, 0x63, 0xdc,
- 0xfb, 0xf3, 0xa0, 0xf4, 0x54, 0x93, 0x6f, 0xdb, 0x81, 0x10, 0xc5, 0x58,
- 0x19, 0xbd, 0x87, 0x12, 0xb8, 0xf5, 0x80, 0x40, 0x34, 0x92, 0x40, 0xcf,
- 0xa1, 0x7a, 0xac, 0x1f, 0x93, 0x71, 0x31, 0x5e, 0x8f, 0xdb, 0x9e, 0x9a,
- 0xe7, 0xe3, 0x9d, 0x6a, 0x9d, 0x27, 0x5b, 0xe7, 0xd8, 0x8e, 0x66, 0x39,
- 0x66, 0x53, 0xbe, 0xc8, 0x72, 0x0c, 0x34, 0xcd, 0x60, 0xa7, 0xdd, 0xe7,
- 0x78, 0x8e, 0xf2, 0xc7, 0x13, 0x9d, 0x6a, 0x30, 0xe8, 0xd0, 0x71, 0xc3,
- 0x44, 0xe5, 0xdb, 0x0d, 0x30, 0x8f, 0xf3, 0x1e, 0xc6, 0xa7, 0xed, 0xa6,
- 0x79, 0x6b, 0x3c, 0x72, 0x99, 0x2a, 0x3b, 0xf2, 0xa9, 0xb7, 0xc9, 0xa7,
- 0x5a, 0xf0, 0x44, 0x76, 0x7e, 0xaf, 0x4b, 0xed, 0xbf, 0x20, 0x19, 0x3b,
- 0xfc, 0x30, 0x3f, 0xa9, 0xd5, 0xcd, 0x4f, 0x5d, 0x7a, 0x24, 0xb8, 0x5d,
- 0xf0, 0x19, 0x11, 0xee, 0x89, 0x9b, 0xe6, 0xd9, 0xb8, 0x69, 0x16, 0xe3,
- 0x86, 0x7b, 0xd9, 0x0a, 0x3f, 0x0e, 0x2d, 0xe5, 0x77, 0x0d, 0xc2, 0xc9,
- 0x66, 0xb2, 0x2f, 0xcf, 0x52, 0x35, 0xb8, 0x91, 0xea, 0x2b, 0x83, 0x82,
- 0x5c, 0x68, 0xa1, 0xd2, 0x0f, 0xb4, 0xf8, 0xf6, 0x8f, 0x36, 0xe1, 0x99,
- 0xb9, 0xdf, 0xe5, 0xe3, 0x39, 0x56, 0x3f, 0xed, 0x13, 0x0d, 0xab, 0x1b,
- 0x10, 0x49, 0x6e, 0x01, 0xf7, 0x46, 0xf9, 0x4c, 0xaa, 0x81, 0xdb, 0xe2,
- 0x83, 0xd8, 0x3a, 0xc6, 0xfb, 0x6b, 0x3f, 0xef, 0xfa, 0x64, 0xcc, 0xfc,
- 0x5b, 0x37, 0xd1, 0xbf, 0xba, 0xb3, 0x2d, 0xe5, 0xb1, 0xde, 0x55, 0x3a,
- 0x49, 0x75, 0x40, 0x23, 0xca, 0x33, 0x6a, 0x65, 0xb1, 0x48, 0xbe, 0xe9,
- 0x45, 0x24, 0xd8, 0x4c, 0xb1, 0x6a, 0x8e, 0x7c, 0x77, 0xa6, 0xcc, 0x75,
- 0xc0, 0x2f, 0xbb, 0xcc, 0x89, 0x45, 0x98, 0x9e, 0xa3, 0xb9, 0xb2, 0x6a,
- 0xcf, 0x47, 0x84, 0xf3, 0xea, 0x74, 0xb3, 0xc1, 0xa3, 0x47, 0x4e, 0xb7,
- 0x09, 0x09, 0x97, 0x97, 0x9b, 0x66, 0x6f, 0xa7, 0x3a, 0x5c, 0x2f, 0x30,
- 0xe4, 0xd0, 0xd5, 0x44, 0xbb, 0x84, 0xaf, 0x06, 0x11, 0xe9, 0x39, 0x8b,
- 0x48, 0xff, 0x39, 0x8a, 0x61, 0xcf, 0x96, 0xf9, 0x9c, 0xef, 0x23, 0xf8,
- 0xdb, 0xb1, 0x85, 0x38, 0x3e, 0xf3, 0x50, 0xb5, 0x27, 0x06, 0xcf, 0x8d,
- 0x2b, 0x74, 0x1c, 0x26, 0xbd, 0x9e, 0xd4, 0x6a, 0x28, 0xae, 0xcb, 0x70,
- 0xb4, 0x42, 0x6e, 0xa4, 0x3a, 0x21, 0xf6, 0xb8, 0x69, 0x2e, 0x6b, 0xb5,
- 0x6b, 0x9e, 0x65, 0xb3, 0xd7, 0xbe, 0xa3, 0x30, 0xdf, 0xef, 0x09, 0x92,
- 0xfe, 0xda, 0x52, 0x5b, 0xc5, 0x49, 0xd3, 0xf8, 0x43, 0x41, 0x3c, 0xdf,
- 0x56, 0x0f, 0x0f, 0xf3, 0x2d, 0x63, 0xe7, 0x04, 0xf7, 0xe1, 0x58, 0x6f,
- 0xf0, 0xf4, 0xc4, 0x79, 0x9f, 0x9c, 0x75, 0x54, 0xf1, 0xac, 0x8b, 0x53,
- 0x4c, 0x14, 0x3e, 0xc2, 0x53, 0x86, 0xbb, 0x9b, 0xf2, 0x53, 0xed, 0x18,
- 0xbf, 0x2f, 0xe1, 0xc5, 0x63, 0x14, 0x37, 0x2e, 0x69, 0x75, 0xd8, 0xdf,
- 0xc8, 0xb6, 0xc3, 0x74, 0x72, 0xcf, 0x70, 0x1b, 0xee, 0xe5, 0x77, 0x4e,
- 0xca, 0xbf, 0x6b, 0x9d, 0x0d, 0xa4, 0x6b, 0x84, 0x0d, 0x98, 0x8e, 0xf9,
- 0xf5, 0x7b, 0xb0, 0x78, 0x94, 0xf5, 0x78, 0xac, 0x2b, 0x48, 0x32, 0x7a,
- 0x82, 0xec, 0xc2, 0xa1, 0x77, 0x43, 0x26, 0x5b, 0x5c, 0x1b, 0xbf, 0x76,
- 0x0e, 0x75, 0xe8, 0x9c, 0x44, 0xf5, 0x9d, 0xc4, 0xfb, 0x79, 0x4a, 0xe2,
- 0x88, 0xb8, 0x76, 0xce, 0x7c, 0x3d, 0xf7, 0x13, 0x8d, 0x19, 0x3b, 0x2f,
- 0x1d, 0xa6, 0xbc, 0xf4, 0x4a, 0x8e, 0x7d, 0xe4, 0x17, 0x96, 0x8f, 0x38,
- 0x28, 0xd6, 0xae, 0x49, 0x87, 0x70, 0x4e, 0x83, 0x5a, 0x83, 0x18, 0xd1,
- 0x1d, 0xe9, 0xe9, 0xae, 0x62, 0x3e, 0x17, 0xc5, 0xff, 0x99, 0x9c, 0x32,
- 0x68, 0xf5, 0x9f, 0x54, 0xa5, 0x8f, 0x3f, 0x79, 0xef, 0x3f, 0xa8, 0x0f,
- 0xa1, 0x61, 0x25, 0x70, 0x7e, 0x94, 0xfb, 0x55, 0xbc, 0xcf, 0x35, 0x2c,
- 0xae, 0xf0, 0x7b, 0x61, 0xb5, 0x43, 0x78, 0x2f, 0xce, 0xef, 0x5b, 0xb1,
- 0xef, 0x3d, 0x0c, 0xf6, 0xbd, 0x06, 0x1a, 0xfb, 0xc9, 0x68, 0x38, 0xd4,
- 0x43, 0x7e, 0x33, 0x00, 0xeb, 0xbc, 0x90, 0x36, 0x6b, 0xf7, 0xc7, 0x93,
- 0xa7, 0xaa, 0xfb, 0x5b, 0x91, 0xea, 0xde, 0x5c, 0xb4, 0xd0, 0x23, 0x2e,
- 0x15, 0x98, 0xa6, 0xb7, 0x89, 0xa6, 0x6e, 0xf1, 0xe1, 0xec, 0x3a, 0x71,
- 0x71, 0xb6, 0x57, 0x9c, 0x2d, 0x70, 0x4c, 0xfe, 0x79, 0xd7, 0xae, 0x1c,
- 0xe7, 0xb3, 0x3b, 0xc5, 0xbb, 0xf9, 0x0d, 0xe2, 0x42, 0xa1, 0x5f, 0x7c,
- 0x34, 0x6b, 0xe0, 0xfe, 0x78, 0x2f, 0x0a, 0x63, 0xf0, 0xbb, 0xf5, 0xfb,
- 0xc5, 0xa5, 0xbc, 0xdd, 0x27, 0xbc, 0x50, 0x68, 0xf1, 0x15, 0xd2, 0x5c,
- 0x03, 0x1f, 0xa3, 0x1a, 0x78, 0x91, 0xef, 0x99, 0xc9, 0x80, 0xaf, 0x34,
- 0xa9, 0x0c, 0xde, 0x23, 0x4c, 0xf3, 0xb6, 0xd8, 0x69, 0xd6, 0xa1, 0xf9,
- 0x5a, 0xcc, 0xc6, 0x07, 0x3b, 0x49, 0x1e, 0x9b, 0x29, 0xb7, 0x4c, 0x6b,
- 0x6d, 0x55, 0x2c, 0xc2, 0xb6, 0xce, 0xbc, 0x72, 0xae, 0xe6, 0xfd, 0xa7,
- 0x21, 0x38, 0x3b, 0x81, 0xbd, 0xe9, 0xcf, 0x79, 0xbd, 0x44, 0xbc, 0x1a,
- 0xae, 0x21, 0x7c, 0x4c, 0xbc, 0xbe, 0x3e, 0xfa, 0xf9, 0x7e, 0x9e, 0x93,
- 0xc6, 0xee, 0x4a, 0x87, 0x53, 0x47, 0x84, 0x52, 0x29, 0xd8, 0xfb, 0x79,
- 0x9a, 0x57, 0x52, 0x4e, 0x8f, 0x50, 0x1d, 0xd1, 0x2a, 0xd9, 0xbc, 0x26,
- 0xaa, 0xbc, 0xde, 0x44, 0xbc, 0x5e, 0x2c, 0x70, 0x7d, 0xfe, 0x76, 0xd7,
- 0x1b, 0xa3, 0x63, 0x66, 0x3d, 0xd5, 0xff, 0x75, 0x6a, 0xb7, 0xb8, 0x40,
- 0x3c, 0x7f, 0x48, 0x3c, 0x7f, 0x5c, 0xb8, 0x53, 0x7c, 0x44, 0x7c, 0x5e,
- 0x2c, 0xf0, 0x1e, 0x9e, 0x5b, 0x7c, 0x98, 0xb3, 0x79, 0xfc, 0xf0, 0x2a,
- 0x8f, 0x41, 0xdf, 0xfe, 0x74, 0x93, 0xef, 0xd1, 0x49, 0xbf, 0x6f, 0xcf,
- 0xa4, 0x69, 0x7e, 0xa8, 0x49, 0x3e, 0xe6, 0xeb, 0x55, 0xed, 0x8b, 0x7c,
- 0xdd, 0x4c, 0x7c, 0xf1, 0xfe, 0xeb, 0x6f, 0xeb, 0x70, 0x9e, 0xaf, 0xc7,
- 0xac, 0x73, 0x6c, 0xf6, 0x19, 0xa9, 0x7a, 0xde, 0x83, 0x25, 0xbe, 0x7c,
- 0x74, 0xfd, 0x95, 0x7f, 0xcd, 0xd7, 0xe0, 0x05, 0xd2, 0x5f, 0xb1, 0xca,
- 0x57, 0xfd, 0xbf, 0xc9, 0x17, 0xd5, 0xba, 0x63, 0xcc, 0x57, 0xa3, 0xfe,
- 0xc6, 0x98, 0x49, 0xfa, 0x92, 0xac, 0x77, 0xc1, 0x8a, 0xd9, 0x1d, 0x78,
- 0x25, 0xc6, 0xef, 0xc7, 0x45, 0x42, 0x47, 0x28, 0x9e, 0xce, 0x96, 0x3d,
- 0xa2, 0xc6, 0xda, 0x87, 0xc5, 0x1b, 0xb5, 0x44, 0xd3, 0xe1, 0x19, 0x7e,
- 0xff, 0x0b, 0x1a, 0x61, 0x01, 0x3f, 0xbf, 0x37, 0x37, 0x0d, 0xee, 0x97,
- 0xf5, 0x8a, 0x86, 0x22, 0xef, 0xbb, 0x6e, 0x10, 0xbe, 0x22, 0x9f, 0xa3,
- 0xeb, 0x11, 0xde, 0x62, 0xb7, 0xf0, 0x1c, 0x32, 0x4c, 0x8f, 0xba, 0x4e,
- 0xd4, 0x1d, 0xba, 0x53, 0x78, 0xaa, 0x7b, 0xb0, 0xee, 0x62, 0xd0, 0x97,
- 0xbe, 0x46, 0x1e, 0x17, 0xb5, 0x9b, 0x2d, 0x79, 0xbc, 0xa6, 0xcd, 0xef,
- 0x1f, 0x5a, 0xe7, 0x10, 0xf9, 0x1c, 0x9c, 0x27, 0x48, 0xb5, 0x53, 0x43,
- 0xb5, 0x76, 0x7a, 0x37, 0xc6, 0xe7, 0x7b, 0x0c, 0x92, 0x3f, 0x42, 0x4e,
- 0x5d, 0xe9, 0x3f, 0x21, 0xd4, 0xd4, 0xfd, 0x22, 0x79, 0xab, 0x97, 0xea,
- 0x9f, 0xad, 0xb1, 0x48, 0xf2, 0x06, 0x11, 0x49, 0x38, 0x05, 0xe7, 0x15,
- 0x4d, 0xae, 0x2d, 0x19, 0xd8, 0x43, 0xf1, 0xed, 0xe5, 0x9c, 0x83, 0xb0,
- 0x03, 0xbf, 0x43, 0xe6, 0xc4, 0x5a, 0xbf, 0x17, 0x4f, 0x12, 0xee, 0x78,
- 0x22, 0x3b, 0x88, 0x27, 0x0b, 0x03, 0x78, 0xa2, 0xf0, 0xaf, 0xde, 0x95,
- 0x91, 0x3d, 0xfa, 0xf9, 0x95, 0xd5, 0x33, 0x08, 0x89, 0xeb, 0x23, 0x1c,
- 0xa3, 0x1f, 0x6e, 0x97, 0x23, 0x5c, 0xeb, 0xbe, 0x75, 0xf3, 0x07, 0x2a,
- 0xfb, 0xa2, 0xba, 0xe2, 0x94, 0x85, 0x45, 0x1e, 0x59, 0x7e, 0xc8, 0x3a,
- 0x1b, 0x95, 0xbe, 0x69, 0x97, 0xf5, 0x4e, 0xe7, 0x3b, 0x2b, 0x36, 0xa9,
- 0xec, 0x0f, 0x0f, 0xc7, 0xd7, 0x58, 0xf9, 0xf5, 0x6f, 0x56, 0xd9, 0x3d,
- 0x9a, 0x77, 0x56, 0x5d, 0x6f, 0xf7, 0xd1, 0x56, 0x45, 0xad, 0xcf, 0x33,
- 0xab, 0xec, 0xfd, 0xed, 0x4f, 0x57, 0xb5, 0x5a, 0x9f, 0xe7, 0x57, 0xd9,
- 0x3e, 0xf5, 0xee, 0x2a, 0xd5, 0xfa, 0xfc, 0x87, 0x55, 0x76, 0x5e, 0xbe,
- 0xb4, 0x6a, 0xc9, 0xd5, 0xf7, 0x63, 0xf8, 0xef, 0xff, 0x00, 0x88, 0xf4,
- 0x23, 0x6f, 0xec, 0x3a, 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_TXP_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
- 0x80000940, 0x80000900, 0x80080100, 0x80080080, 0x80080000, 0x800e0000,
- 0x80080080, 0x80080000, 0x80000a80, 0x80000a00, 0x80000980, 0x80000900,
- 0x00000000 };
-
-static struct fw_info bnx2_txp_fw_09 = {
- /* Firmware version: 4.6.15 */
- .ver_major = 0x4,
- .ver_minor = 0x6,
- .ver_fix = 0xf,
-
- .start_addr = 0x08000098,
-
- .text_addr = 0x08000000,
- .text_len = 0x3ae8,
- .text_index = 0x0,
- .gz_text = bnx2_TXP_b09FwText,
- .gz_text_len = sizeof(bnx2_TXP_b09FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_TXP_b09FwData,
-
- .sbss_addr = 0x08003b40,
- .sbss_len = 0x6c,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08003bac,
- .bss_len = 0x24c,
- .bss_index = 0x0,
-
- .rodata_addr = 0x08003ae8,
- .rodata_len = 0x30,
- .rodata_index = 0x0,
- .rodata = bnx2_TXP_b09FwRodata,
-};
-
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 00a78e8677b..ad5ef25add3 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -10979,16 +10979,16 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
goto err_out_release;
}
- if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) {
bp->flags |= USING_DAC_FLAG;
- if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
+ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
printk(KERN_ERR PFX "pci_set_consistent_dma_mask"
" failed, aborting\n");
rc = -EIO;
goto err_out_release;
}
- } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) {
+ } else if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
printk(KERN_ERR PFX "System does not support DMA,"
" aborting\n");
rc = -EIO;
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 0effefa1b88..f5222764061 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -5074,10 +5074,10 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
/* Configure DMA attributes. */
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
err = pci_set_consistent_dma_mask(pdev,
- DMA_64BIT_MASK);
+ DMA_BIT_MASK(64));
if (err < 0) {
dev_err(&pdev->dev, "Unable to obtain 64-bit DMA "
"for consistent allocations\n");
@@ -5085,7 +5085,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
}
} else {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "No usable DMA configuration, "
"aborting.\n");
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 9b6011e7678..fa06994f973 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -1056,17 +1056,17 @@ static int __devinit init_one(struct pci_dev *pdev,
goto out_disable_pdev;
}
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
- if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
CH_ERR("%s: unable to obtain 64-bit DMA for "
"consistent allocations\n", pci_name(pdev));
err = -ENODEV;
goto out_disable_pdev;
}
- } else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
+ } else if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) {
CH_ERR("%s: no usable DMA configuration\n", pci_name(pdev));
goto out_disable_pdev;
}
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 2c2aaa74145..ab0e5febef8 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -3038,15 +3038,15 @@ static int __devinit init_one(struct pci_dev *pdev,
goto out_release_regions;
}
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (err) {
dev_err(&pdev->dev, "unable to obtain 64-bit DMA for "
"coherent allocations\n");
goto out_disable_device;
}
- } else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
+ } else if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) {
dev_err(&pdev->dev, "no usable DMA configuration\n");
goto out_disable_device;
}
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index c749e9fb47e..4a1b554654e 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -714,7 +714,7 @@ rio_interrupt (int irq, void *dev_instance)
static inline dma_addr_t desc_to_dma(struct netdev_desc *desc)
{
- return le64_to_cpu(desc->fraginfo) & DMA_48BIT_MASK;
+ return le64_to_cpu(desc->fraginfo) & DMA_BIT_MASK(48);
}
static void
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 0504db9ad64..5c0b457c786 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -2604,7 +2604,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
goto err_out_disable_pdev;
}
- if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
+ if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
DPRINTK(PROBE, ERR, "No usable DMA configuration, aborting.\n");
goto err_out_free_res;
}
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 93b861d032b..ddc5c533e89 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -962,13 +962,13 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (err)
return err;
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
- !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) &&
+ !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
} else {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
E1000_ERR("No usable DMA configuration, "
"aborting\n");
@@ -2335,6 +2335,12 @@ static void e1000_set_rx_mode(struct net_device *netdev)
int mta_reg_count = (hw->mac_type == e1000_ich8lan) ?
E1000_NUM_MTA_REGISTERS_ICH8LAN :
E1000_NUM_MTA_REGISTERS;
+ u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
+
+ if (!mcarray) {
+ DPRINTK(PROBE, ERR, "memory allocation failed\n");
+ return;
+ }
if (hw->mac_type == e1000_ich8lan)
rar_entries = E1000_RAR_ENTRIES_ICH8LAN;
@@ -2401,22 +2407,34 @@ static void e1000_set_rx_mode(struct net_device *netdev)
}
WARN_ON(uc_ptr != NULL);
- /* clear the old settings from the multicast hash table */
-
- for (i = 0; i < mta_reg_count; i++) {
- E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
- E1000_WRITE_FLUSH();
- }
-
/* load any remaining addresses into the hash table */
for (; mc_ptr; mc_ptr = mc_ptr->next) {
+ u32 hash_reg, hash_bit, mta;
hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
- e1000_mta_set(hw, hash_value);
+ hash_reg = (hash_value >> 5) & 0x7F;
+ hash_bit = hash_value & 0x1F;
+ mta = (1 << hash_bit);
+ mcarray[hash_reg] |= mta;
}
+ /* write the hash table completely, write from bottom to avoid
+ * both stupid write combining chipsets, and flushing each write */
+ for (i = mta_reg_count - 1; i >= 0 ; i--) {
+ /*
+ * If we are on an 82544 has an errata where writing odd
+ * offsets overwrites the previous even offset, but writing
+ * backwards over the range solves the issue by always
+ * writing the odd offset first
+ */
+ E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]);
+ }
+ E1000_WRITE_FLUSH();
+
if (hw->mac_type == e1000_82542_rev2_0)
e1000_leave_82542_rst(adapter);
+
+ kfree(mcarray);
}
/* Need to wait a few seconds after link up to get diagnostic information from
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index bfb2d6c85c5..409b58cad0e 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2203,7 +2203,7 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
/* Setup the HW Tx Head and Tail descriptor pointers */
tdba = tx_ring->dma;
tdlen = tx_ring->count * sizeof(struct e1000_tx_desc);
- ew32(TDBAL, (tdba & DMA_32BIT_MASK));
+ ew32(TDBAL, (tdba & DMA_BIT_MASK(32)));
ew32(TDBAH, (tdba >> 32));
ew32(TDLEN, tdlen);
ew32(TDH, 0);
@@ -2459,7 +2459,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
* the Base and Length of the Rx Descriptor Ring
*/
rdba = rx_ring->dma;
- ew32(RDBAL, (rdba & DMA_32BIT_MASK));
+ ew32(RDBAL, (rdba & DMA_BIT_MASK(32)));
ew32(RDBAH, (rdba >> 32));
ew32(RDLEN, rdlen);
ew32(RDH, 0);
@@ -4763,16 +4763,16 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
return err;
pci_using_dac = 0;
- err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (!err) {
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (!err)
pci_using_dac = 1;
} else {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
err = pci_set_consistent_dma_mask(pdev,
- DMA_32BIT_MASK);
+ DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "No usable DMA "
"configuration, aborting\n");
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 03403a51f7e..9080f07da8f 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1685,15 +1685,15 @@ static int __devinit enic_probe(struct pci_dev *pdev,
* fail to 32-bit.
*/
- err = pci_set_dma_mask(pdev, DMA_40BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(40));
if (err) {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
printk(KERN_ERR PFX
"No usable DMA configuration, aborting.\n");
goto err_out_release_regions;
}
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
printk(KERN_ERR PFX
"Unable to obtain 32-bit DMA "
@@ -1701,7 +1701,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
goto err_out_release_regions;
}
} else {
- err = pci_set_consistent_dma_mask(pdev, DMA_40BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40));
if (err) {
printk(KERN_ERR PFX
"Unable to obtain 40-bit DMA "
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
index 51ead7941f8..5210bb1027c 100644
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -542,6 +542,8 @@ static int eql_s_slave_cfg(struct net_device *dev, slave_config_t __user *scp)
}
spin_unlock_bh(&eql->queue.lock);
+ dev_put(slave_dev);
+
return ret;
}
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index a515acccc61..682e7f0b558 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1240,6 +1240,7 @@ static void __inline__ fec_phy_ack_intr(void)
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
*icrp = 0x0d000000;
}
+#endif
#ifdef CONFIG_M5272
static void __inline__ fec_get_mac(struct net_device *dev)
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index a858c6ff80d..d37465020bc 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -5632,12 +5632,12 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->desc_ver = DESC_VER_3;
np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
if (dma_64bit) {
- if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK))
+ if (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(39)))
dev_printk(KERN_INFO, &pci_dev->dev,
"64-bit DMA failed, using 32-bit addressing\n");
else
dev->features |= NETIF_F_HIGHDMA;
- if (pci_set_consistent_dma_mask(pci_dev, DMA_39BIT_MASK)) {
+ if (pci_set_consistent_dma_mask(pci_dev, DMA_BIT_MASK(39))) {
dev_printk(KERN_INFO, &pci_dev->dev,
"64-bit DMA (consistent) failed, using 32-bit ring buffers\n");
}
@@ -6117,6 +6117,9 @@ static int nv_resume(struct pci_dev *pdev)
pci_write_config_dword(pdev, NV_MSI_PRIV_OFFSET, NV_MSI_PRIV_VALUE);
+ /* restore phy state, including autoneg */
+ phy_init(dev);
+
netif_device_attach(dev);
if (netif_running(dev)) {
rc = nv_open(dev);
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index ad8be7e7829..de3f49f991a 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -580,7 +580,7 @@ static int __devinit hp100_probe1(struct net_device *dev, int ioaddr,
* Also, we can have EISA Busmaster cards (not tested),
* so beware !!! - Jean II */
if((bus == HP100_BUS_PCI) &&
- (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK))) {
+ (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32)))) {
/* Gracefully fallback to shared memory */
goto busmasterfail;
}
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index a815e17a0ab..77e4b5b52fc 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -1229,7 +1229,7 @@ static int emac_link_differs(struct emac_instance *dev)
static void emac_link_timer(struct work_struct *work)
{
struct emac_instance *dev =
- container_of((struct delayed_work *)work,
+ container_of(to_delayed_work(work),
struct emac_instance, link_work);
int link_poll_interval;
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 03aa9593dd9..db7274e6222 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -152,14 +152,13 @@ static struct notifier_block dca_notifier = {
/* for netdump / net console */
static void igb_netpoll(struct net_device *);
#endif
-
#ifdef CONFIG_PCI_IOV
-static ssize_t igb_set_num_vfs(struct device *, struct device_attribute *,
- const char *, size_t);
-static ssize_t igb_show_num_vfs(struct device *, struct device_attribute *,
- char *);
-DEVICE_ATTR(num_vfs, S_IRUGO | S_IWUSR, igb_show_num_vfs, igb_set_num_vfs);
-#endif
+static unsigned int max_vfs = 0;
+module_param(max_vfs, uint, 0);
+MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate "
+ "per physical function");
+#endif /* CONFIG_PCI_IOV */
+
static pci_ers_result_t igb_io_error_detected(struct pci_dev *,
pci_channel_state_t);
static pci_ers_result_t igb_io_slot_reset(struct pci_dev *);
@@ -671,6 +670,21 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter)
/* If we can't do MSI-X, try MSI */
msi_only:
+#ifdef CONFIG_PCI_IOV
+ /* disable SR-IOV for non MSI-X configurations */
+ if (adapter->vf_data) {
+ struct e1000_hw *hw = &adapter->hw;
+ /* disable iov and allow time for transactions to clear */
+ pci_disable_sriov(adapter->pdev);
+ msleep(500);
+
+ kfree(adapter->vf_data);
+ adapter->vf_data = NULL;
+ wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
+ msleep(100);
+ dev_info(&adapter->pdev->dev, "IOV Disabled\n");
+ }
+#endif
adapter->num_rx_queues = 1;
adapter->num_tx_queues = 1;
if (!pci_enable_msi(adapter->pdev))
@@ -1154,15 +1168,15 @@ static int __devinit igb_probe(struct pci_dev *pdev,
return err;
pci_using_dac = 0;
- err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (!err) {
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (!err)
pci_using_dac = 1;
} else {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "No usable DMA "
"configuration, aborting\n");
@@ -1238,6 +1252,39 @@ static int __devinit igb_probe(struct pci_dev *pdev,
if (err)
goto err_sw_init;
+#ifdef CONFIG_PCI_IOV
+ /* since iov functionality isn't critical to base device function we
+ * can accept failure. If it fails we don't allow iov to be enabled */
+ if (hw->mac.type == e1000_82576) {
+ /* 82576 supports a maximum of 7 VFs in addition to the PF */
+ unsigned int num_vfs = (max_vfs > 7) ? 7 : max_vfs;
+ int i;
+ unsigned char mac_addr[ETH_ALEN];
+
+ if (num_vfs)
+ adapter->vf_data = kcalloc(num_vfs,
+ sizeof(struct vf_data_storage),
+ GFP_KERNEL);
+ if (!adapter->vf_data) {
+ dev_err(&pdev->dev, "Could not allocate VF private "
+ "data - IOV enable failed\n");
+ } else {
+ err = pci_enable_sriov(pdev, num_vfs);
+ if (!err) {
+ adapter->vfs_allocated_count = num_vfs;
+ dev_info(&pdev->dev, "%d vfs allocated\n", num_vfs);
+ for (i = 0; i < adapter->vfs_allocated_count; i++) {
+ random_ether_addr(mac_addr);
+ igb_set_vf_mac(adapter, i, mac_addr);
+ }
+ } else {
+ kfree(adapter->vf_data);
+ adapter->vf_data = NULL;
+ }
+ }
+ }
+
+#endif
/* setup the private structure */
err = igb_sw_init(adapter);
if (err)
@@ -1397,19 +1444,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
if (err)
goto err_register;
-#ifdef CONFIG_PCI_IOV
- /* since iov functionality isn't critical to base device function we
- * can accept failure. If it fails we don't allow iov to be enabled */
- if (hw->mac.type == e1000_82576) {
- err = pci_enable_sriov(pdev, 0);
- if (!err)
- err = device_create_file(&netdev->dev,
- &dev_attr_num_vfs);
- if (err)
- dev_err(&pdev->dev, "Failed to initialize IOV\n");
- }
-
-#endif
#ifdef CONFIG_IGB_DCA
if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IGB_FLAG_DCA_ENABLED;
@@ -5422,89 +5456,4 @@ static void igb_vmm_control(struct igb_adapter *adapter)
igb_vmdq_set_replication_pf(hw, true);
}
-#ifdef CONFIG_PCI_IOV
-static ssize_t igb_show_num_vfs(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct igb_adapter *adapter = netdev_priv(to_net_dev(dev));
-
- return sprintf(buf, "%d\n", adapter->vfs_allocated_count);
-}
-
-static ssize_t igb_set_num_vfs(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct net_device *netdev = to_net_dev(dev);
- struct igb_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- struct pci_dev *pdev = adapter->pdev;
- unsigned int num_vfs, i;
- unsigned char mac_addr[ETH_ALEN];
- int err;
-
- sscanf(buf, "%u", &num_vfs);
-
- if (num_vfs > 7)
- num_vfs = 7;
-
- /* value unchanged do nothing */
- if (num_vfs == adapter->vfs_allocated_count)
- return count;
-
- if (netdev->flags & IFF_UP)
- igb_close(netdev);
-
- igb_reset_interrupt_capability(adapter);
- igb_free_queues(adapter);
- adapter->tx_ring = NULL;
- adapter->rx_ring = NULL;
- adapter->vfs_allocated_count = 0;
-
- /* reclaim resources allocated to VFs since we are changing count */
- if (adapter->vf_data) {
- /* disable iov and allow time for transactions to clear */
- pci_disable_sriov(pdev);
- msleep(500);
-
- kfree(adapter->vf_data);
- adapter->vf_data = NULL;
- wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
- msleep(100);
- dev_info(&pdev->dev, "IOV Disabled\n");
- }
-
- if (num_vfs) {
- adapter->vf_data = kcalloc(num_vfs,
- sizeof(struct vf_data_storage),
- GFP_KERNEL);
- if (!adapter->vf_data) {
- dev_err(&pdev->dev, "Could not allocate VF private "
- "data - IOV enable failed\n");
- } else {
- err = pci_enable_sriov(pdev, num_vfs);
- if (!err) {
- adapter->vfs_allocated_count = num_vfs;
- dev_info(&pdev->dev, "%d vfs allocated\n", num_vfs);
- for (i = 0; i < adapter->vfs_allocated_count; i++) {
- random_ether_addr(mac_addr);
- igb_set_vf_mac(adapter, i, mac_addr);
- }
- } else {
- kfree(adapter->vf_data);
- adapter->vf_data = NULL;
- }
- }
- }
-
- igb_set_interrupt_capability(adapter);
- igb_alloc_queues(adapter);
- igb_reset(adapter);
-
- if (netdev->flags & IFF_UP)
- igb_open(netdev);
-
- return count;
-}
-#endif /* CONFIG_PCI_IOV */
/* igb_main.c */
diff --git a/drivers/net/igbvf/Makefile b/drivers/net/igbvf/Makefile
new file mode 100644
index 00000000000..c2f150d8f2d
--- /dev/null
+++ b/drivers/net/igbvf/Makefile
@@ -0,0 +1,38 @@
+################################################################################
+#
+# Intel(R) 82576 Virtual Function Linux driver
+# Copyright(c) 2009 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.,
+# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
+# Contact Information:
+# e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+#
+################################################################################
+
+#
+# Makefile for the Intel(R) 82576 VF ethernet driver
+#
+
+obj-$(CONFIG_IGBVF) += igbvf.o
+
+igbvf-objs := vf.o \
+ mbx.o \
+ ethtool.o \
+ netdev.o
+
diff --git a/drivers/net/igbvf/defines.h b/drivers/net/igbvf/defines.h
new file mode 100644
index 00000000000..88a47537518
--- /dev/null
+++ b/drivers/net/igbvf/defines.h
@@ -0,0 +1,125 @@
+/*******************************************************************************
+
+ Intel(R) 82576 Virtual Function Linux driver
+ Copyright(c) 1999 - 2009 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_DEFINES_H_
+#define _E1000_DEFINES_H_
+
+/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
+#define REQ_TX_DESCRIPTOR_MULTIPLE 8
+#define REQ_RX_DESCRIPTOR_MULTIPLE 8
+
+/* IVAR valid bit */
+#define E1000_IVAR_VALID 0x80
+
+/* Receive Descriptor bit definitions */
+#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
+#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
+#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
+#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
+#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
+#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
+#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
+#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
+#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
+
+#define E1000_RXDEXT_STATERR_CE 0x01000000
+#define E1000_RXDEXT_STATERR_SE 0x02000000
+#define E1000_RXDEXT_STATERR_SEQ 0x04000000
+#define E1000_RXDEXT_STATERR_CXE 0x10000000
+#define E1000_RXDEXT_STATERR_TCPE 0x20000000
+#define E1000_RXDEXT_STATERR_IPE 0x40000000
+#define E1000_RXDEXT_STATERR_RXE 0x80000000
+
+
+/* Same mask, but for extended and packet split descriptors */
+#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
+ E1000_RXDEXT_STATERR_CE | \
+ E1000_RXDEXT_STATERR_SE | \
+ E1000_RXDEXT_STATERR_SEQ | \
+ E1000_RXDEXT_STATERR_CXE | \
+ E1000_RXDEXT_STATERR_RXE)
+
+/* Device Control */
+#define E1000_CTRL_RST 0x04000000 /* Global reset */
+
+/* Device Status */
+#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
+#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
+#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */
+#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
+#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
+#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
+
+#define SPEED_10 10
+#define SPEED_100 100
+#define SPEED_1000 1000
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+/* Transmit Descriptor bit definitions */
+#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
+#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
+#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */
+#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
+
+#define MAX_JUMBO_FRAME_SIZE 0x3F00
+
+/* 802.1q VLAN Packet Size */
+#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMA'd) */
+
+/* Error Codes */
+#define E1000_SUCCESS 0
+#define E1000_ERR_CONFIG 3
+#define E1000_ERR_MAC_INIT 5
+#define E1000_ERR_MBX 15
+
+#ifndef ETH_ADDR_LEN
+#define ETH_ADDR_LEN 6
+#endif
+
+/* SRRCTL bit definitions */
+#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
+#define E1000_SRRCTL_BSIZEHDRSIZE_MASK 0x00000F00
+#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
+#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
+#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
+#define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000
+#define E1000_SRRCTL_DROP_EN 0x80000000
+
+#define E1000_SRRCTL_BSIZEPKT_MASK 0x0000007F
+#define E1000_SRRCTL_BSIZEHDR_MASK 0x00003F00
+
+/* Additional Descriptor Control definitions */
+#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */
+#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
+
+/* Direct Cache Access (DCA) definitions */
+#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
+
+#define E1000_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */
+
+#endif /* _E1000_DEFINES_H_ */
diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c
new file mode 100644
index 00000000000..1dcaa690531
--- /dev/null
+++ b/drivers/net/igbvf/ethtool.c
@@ -0,0 +1,540 @@
+/*******************************************************************************
+
+ Intel(R) 82576 Virtual Function Linux driver
+ Copyright(c) 2009 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+/* ethtool support for igbvf */
+
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+
+#include "igbvf.h"
+#include <linux/if_vlan.h>
+
+
+struct igbvf_stats {
+ char stat_string[ETH_GSTRING_LEN];
+ int sizeof_stat;
+ int stat_offset;
+ int base_stat_offset;
+};
+
+#define IGBVF_STAT(current, base) \
+ sizeof(((struct igbvf_adapter *)0)->current), \
+ offsetof(struct igbvf_adapter, current), \
+ offsetof(struct igbvf_adapter, base)
+
+static const struct igbvf_stats igbvf_gstrings_stats[] = {
+ { "rx_packets", IGBVF_STAT(stats.gprc, stats.base_gprc) },
+ { "tx_packets", IGBVF_STAT(stats.gptc, stats.base_gptc) },
+ { "rx_bytes", IGBVF_STAT(stats.gorc, stats.base_gorc) },
+ { "tx_bytes", IGBVF_STAT(stats.gotc, stats.base_gotc) },
+ { "multicast", IGBVF_STAT(stats.mprc, stats.base_mprc) },
+ { "lbrx_bytes", IGBVF_STAT(stats.gorlbc, stats.base_gorlbc) },
+ { "lbrx_packets", IGBVF_STAT(stats.gprlbc, stats.base_gprlbc) },
+ { "tx_restart_queue", IGBVF_STAT(restart_queue, zero_base) },
+ { "rx_long_byte_count", IGBVF_STAT(stats.gorc, stats.base_gorc) },
+ { "rx_csum_offload_good", IGBVF_STAT(hw_csum_good, zero_base) },
+ { "rx_csum_offload_errors", IGBVF_STAT(hw_csum_err, zero_base) },
+ { "rx_header_split", IGBVF_STAT(rx_hdr_split, zero_base) },
+ { "alloc_rx_buff_failed", IGBVF_STAT(alloc_rx_buff_failed, zero_base) },
+};
+
+#define IGBVF_GLOBAL_STATS_LEN ARRAY_SIZE(igbvf_gstrings_stats)
+
+static const char igbvf_gstrings_test[][ETH_GSTRING_LEN] = {
+ "Link test (on/offline)"
+};
+
+#define IGBVF_TEST_LEN ARRAY_SIZE(igbvf_gstrings_test)
+
+static int igbvf_get_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ u32 status;
+
+ ecmd->supported = SUPPORTED_1000baseT_Full;
+
+ ecmd->advertising = ADVERTISED_1000baseT_Full;
+
+ ecmd->port = -1;
+ ecmd->transceiver = XCVR_DUMMY1;
+
+ status = er32(STATUS);
+ if (status & E1000_STATUS_LU) {
+ if (status & E1000_STATUS_SPEED_1000)
+ ecmd->speed = 1000;
+ else if (status & E1000_STATUS_SPEED_100)
+ ecmd->speed = 100;
+ else
+ ecmd->speed = 10;
+
+ if (status & E1000_STATUS_FD)
+ ecmd->duplex = DUPLEX_FULL;
+ else
+ ecmd->duplex = DUPLEX_HALF;
+ } else {
+ ecmd->speed = -1;
+ ecmd->duplex = -1;
+ }
+
+ ecmd->autoneg = AUTONEG_DISABLE;
+
+ return 0;
+}
+
+static u32 igbvf_get_link(struct net_device *netdev)
+{
+ return netif_carrier_ok(netdev);
+}
+
+static int igbvf_set_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ return -EOPNOTSUPP;
+}
+
+static void igbvf_get_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ return;
+}
+
+static int igbvf_set_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ return -EOPNOTSUPP;
+}
+
+static u32 igbvf_get_tx_csum(struct net_device *netdev)
+{
+ return ((netdev->features & NETIF_F_IP_CSUM) != 0);
+}
+
+static int igbvf_set_tx_csum(struct net_device *netdev, u32 data)
+{
+ if (data)
+ netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+ else
+ netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+ return 0;
+}
+
+static int igbvf_set_tso(struct net_device *netdev, u32 data)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ int i;
+ struct net_device *v_netdev;
+
+ if (data) {
+ netdev->features |= NETIF_F_TSO;
+ netdev->features |= NETIF_F_TSO6;
+ } else {
+ netdev->features &= ~NETIF_F_TSO;
+ netdev->features &= ~NETIF_F_TSO6;
+ /* disable TSO on all VLANs if they're present */
+ if (!adapter->vlgrp)
+ goto tso_out;
+ for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ v_netdev = vlan_group_get_device(adapter->vlgrp, i);
+ if (!v_netdev)
+ continue;
+
+ v_netdev->features &= ~NETIF_F_TSO;
+ v_netdev->features &= ~NETIF_F_TSO6;
+ vlan_group_set_device(adapter->vlgrp, i, v_netdev);
+ }
+ }
+
+tso_out:
+ dev_info(&adapter->pdev->dev, "TSO is %s\n",
+ data ? "Enabled" : "Disabled");
+ adapter->flags |= FLAG_TSO_FORCE;
+ return 0;
+}
+
+static u32 igbvf_get_msglevel(struct net_device *netdev)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ return adapter->msg_enable;
+}
+
+static void igbvf_set_msglevel(struct net_device *netdev, u32 data)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ adapter->msg_enable = data;
+}
+
+static int igbvf_get_regs_len(struct net_device *netdev)
+{
+#define IGBVF_REGS_LEN 8
+ return IGBVF_REGS_LEN * sizeof(u32);
+}
+
+static void igbvf_get_regs(struct net_device *netdev,
+ struct ethtool_regs *regs, void *p)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ u32 *regs_buff = p;
+ u8 revision_id;
+
+ memset(p, 0, IGBVF_REGS_LEN * sizeof(u32));
+
+ pci_read_config_byte(adapter->pdev, PCI_REVISION_ID, &revision_id);
+
+ regs->version = (1 << 24) | (revision_id << 16) | adapter->pdev->device;
+
+ regs_buff[0] = er32(CTRL);
+ regs_buff[1] = er32(STATUS);
+
+ regs_buff[2] = er32(RDLEN(0));
+ regs_buff[3] = er32(RDH(0));
+ regs_buff[4] = er32(RDT(0));
+
+ regs_buff[5] = er32(TDLEN(0));
+ regs_buff[6] = er32(TDH(0));
+ regs_buff[7] = er32(TDT(0));
+}
+
+static int igbvf_get_eeprom_len(struct net_device *netdev)
+{
+ return 0;
+}
+
+static int igbvf_get_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+ return -EOPNOTSUPP;
+}
+
+static int igbvf_set_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+ return -EOPNOTSUPP;
+}
+
+static void igbvf_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ char firmware_version[32] = "N/A";
+
+ strncpy(drvinfo->driver, igbvf_driver_name, 32);
+ strncpy(drvinfo->version, igbvf_driver_version, 32);
+ strncpy(drvinfo->fw_version, firmware_version, 32);
+ strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+ drvinfo->regdump_len = igbvf_get_regs_len(netdev);
+ drvinfo->eedump_len = igbvf_get_eeprom_len(netdev);
+}
+
+static void igbvf_get_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct igbvf_ring *tx_ring = adapter->tx_ring;
+ struct igbvf_ring *rx_ring = adapter->rx_ring;
+
+ ring->rx_max_pending = IGBVF_MAX_RXD;
+ ring->tx_max_pending = IGBVF_MAX_TXD;
+ ring->rx_mini_max_pending = 0;
+ ring->rx_jumbo_max_pending = 0;
+ ring->rx_pending = rx_ring->count;
+ ring->tx_pending = tx_ring->count;
+ ring->rx_mini_pending = 0;
+ ring->rx_jumbo_pending = 0;
+}
+
+static int igbvf_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct igbvf_ring *temp_ring;
+ int err;
+ u32 new_rx_count, new_tx_count;
+
+ if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
+ return -EINVAL;
+
+ new_rx_count = max(ring->rx_pending, (u32)IGBVF_MIN_RXD);
+ new_rx_count = min(new_rx_count, (u32)IGBVF_MAX_RXD);
+ new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE);
+
+ new_tx_count = max(ring->tx_pending, (u32)IGBVF_MIN_TXD);
+ new_tx_count = min(new_tx_count, (u32)IGBVF_MAX_TXD);
+ new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);
+
+ if ((new_tx_count == adapter->tx_ring->count) &&
+ (new_rx_count == adapter->rx_ring->count)) {
+ /* nothing to do */
+ return 0;
+ }
+
+ temp_ring = vmalloc(sizeof(struct igbvf_ring));
+ if (!temp_ring)
+ return -ENOMEM;
+
+ while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state))
+ msleep(1);
+
+ if (netif_running(adapter->netdev))
+ igbvf_down(adapter);
+
+ /*
+ * We can't just free everything and then setup again,
+ * because the ISRs in MSI-X mode get passed pointers
+ * to the tx and rx ring structs.
+ */
+ if (new_tx_count != adapter->tx_ring->count) {
+ memcpy(temp_ring, adapter->tx_ring, sizeof(struct igbvf_ring));
+
+ temp_ring->count = new_tx_count;
+ err = igbvf_setup_tx_resources(adapter, temp_ring);
+ if (err)
+ goto err_setup;
+
+ igbvf_free_tx_resources(adapter->tx_ring);
+
+ memcpy(adapter->tx_ring, temp_ring, sizeof(struct igbvf_ring));
+ }
+
+ if (new_rx_count != adapter->rx_ring->count) {
+ memcpy(temp_ring, adapter->rx_ring, sizeof(struct igbvf_ring));
+
+ temp_ring->count = new_rx_count;
+ err = igbvf_setup_rx_resources(adapter, temp_ring);
+ if (err)
+ goto err_setup;
+
+ igbvf_free_rx_resources(adapter->rx_ring);
+
+ memcpy(adapter->rx_ring, temp_ring,sizeof(struct igbvf_ring));
+ }
+
+ err = 0;
+err_setup:
+ if (netif_running(adapter->netdev))
+ igbvf_up(adapter);
+
+ clear_bit(__IGBVF_RESETTING, &adapter->state);
+ vfree(temp_ring);
+ return err;
+}
+
+static int igbvf_link_test(struct igbvf_adapter *adapter, u64 *data)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ *data = 0;
+
+ hw->mac.ops.check_for_link(hw);
+
+ if (!(er32(STATUS) & E1000_STATUS_LU))
+ *data = 1;
+
+ return *data;
+}
+
+static int igbvf_get_self_test_count(struct net_device *netdev)
+{
+ return IGBVF_TEST_LEN;
+}
+
+static int igbvf_get_stats_count(struct net_device *netdev)
+{
+ return IGBVF_GLOBAL_STATS_LEN;
+}
+
+static void igbvf_diag_test(struct net_device *netdev,
+ struct ethtool_test *eth_test, u64 *data)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ set_bit(__IGBVF_TESTING, &adapter->state);
+
+ /*
+ * Link test performed before hardware reset so autoneg doesn't
+ * interfere with test result
+ */
+ if (igbvf_link_test(adapter, &data[0]))
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
+ clear_bit(__IGBVF_TESTING, &adapter->state);
+ msleep_interruptible(4 * 1000);
+}
+
+static void igbvf_get_wol(struct net_device *netdev,
+ struct ethtool_wolinfo *wol)
+{
+ wol->supported = 0;
+ wol->wolopts = 0;
+
+ return;
+}
+
+static int igbvf_set_wol(struct net_device *netdev,
+ struct ethtool_wolinfo *wol)
+{
+ return -EOPNOTSUPP;
+}
+
+static int igbvf_phys_id(struct net_device *netdev, u32 data)
+{
+ return 0;
+}
+
+static int igbvf_get_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *ec)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ if (adapter->itr_setting <= 3)
+ ec->rx_coalesce_usecs = adapter->itr_setting;
+ else
+ ec->rx_coalesce_usecs = adapter->itr_setting >> 2;
+
+ return 0;
+}
+
+static int igbvf_set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *ec)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+
+ if ((ec->rx_coalesce_usecs > IGBVF_MAX_ITR_USECS) ||
+ ((ec->rx_coalesce_usecs > 3) &&
+ (ec->rx_coalesce_usecs < IGBVF_MIN_ITR_USECS)) ||
+ (ec->rx_coalesce_usecs == 2))
+ return -EINVAL;
+
+ /* convert to rate of irq's per second */
+ if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) {
+ adapter->itr = IGBVF_START_ITR;
+ adapter->itr_setting = ec->rx_coalesce_usecs;
+ } else {
+ adapter->itr = ec->rx_coalesce_usecs << 2;
+ adapter->itr_setting = adapter->itr;
+ }
+
+ writel(adapter->itr,
+ hw->hw_addr + adapter->rx_ring[0].itr_register);
+
+ return 0;
+}
+
+static int igbvf_nway_reset(struct net_device *netdev)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ if (netif_running(netdev))
+ igbvf_reinit_locked(adapter);
+ return 0;
+}
+
+
+static void igbvf_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *stats,
+ u64 *data)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ int i;
+
+ igbvf_update_stats(adapter);
+ for (i = 0; i < IGBVF_GLOBAL_STATS_LEN; i++) {
+ char *p = (char *)adapter +
+ igbvf_gstrings_stats[i].stat_offset;
+ char *b = (char *)adapter +
+ igbvf_gstrings_stats[i].base_stat_offset;
+ data[i] = ((igbvf_gstrings_stats[i].sizeof_stat ==
+ sizeof(u64)) ? (*(u64 *)p - *(u64 *)b) :
+ (*(u32 *)p - *(u32 *)b));
+ }
+
+}
+
+static void igbvf_get_strings(struct net_device *netdev, u32 stringset,
+ u8 *data)
+{
+ u8 *p = data;
+ int i;
+
+ switch (stringset) {
+ case ETH_SS_TEST:
+ memcpy(data, *igbvf_gstrings_test, sizeof(igbvf_gstrings_test));
+ break;
+ case ETH_SS_STATS:
+ for (i = 0; i < IGBVF_GLOBAL_STATS_LEN; i++) {
+ memcpy(p, igbvf_gstrings_stats[i].stat_string,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ }
+ break;
+ }
+}
+
+static const struct ethtool_ops igbvf_ethtool_ops = {
+ .get_settings = igbvf_get_settings,
+ .set_settings = igbvf_set_settings,
+ .get_drvinfo = igbvf_get_drvinfo,
+ .get_regs_len = igbvf_get_regs_len,
+ .get_regs = igbvf_get_regs,
+ .get_wol = igbvf_get_wol,
+ .set_wol = igbvf_set_wol,
+ .get_msglevel = igbvf_get_msglevel,
+ .set_msglevel = igbvf_set_msglevel,
+ .nway_reset = igbvf_nway_reset,
+ .get_link = igbvf_get_link,
+ .get_eeprom_len = igbvf_get_eeprom_len,
+ .get_eeprom = igbvf_get_eeprom,
+ .set_eeprom = igbvf_set_eeprom,
+ .get_ringparam = igbvf_get_ringparam,
+ .set_ringparam = igbvf_set_ringparam,
+ .get_pauseparam = igbvf_get_pauseparam,
+ .set_pauseparam = igbvf_set_pauseparam,
+ .get_tx_csum = igbvf_get_tx_csum,
+ .set_tx_csum = igbvf_set_tx_csum,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = igbvf_set_tso,
+ .self_test = igbvf_diag_test,
+ .get_strings = igbvf_get_strings,
+ .phys_id = igbvf_phys_id,
+ .get_ethtool_stats = igbvf_get_ethtool_stats,
+ .self_test_count = igbvf_get_self_test_count,
+ .get_stats_count = igbvf_get_stats_count,
+ .get_coalesce = igbvf_get_coalesce,
+ .set_coalesce = igbvf_set_coalesce,
+};
+
+void igbvf_set_ethtool_ops(struct net_device *netdev)
+{
+ /* have to "undeclare" const on this struct to remove warnings */
+ SET_ETHTOOL_OPS(netdev, (struct ethtool_ops *)&igbvf_ethtool_ops);
+}
diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h
new file mode 100644
index 00000000000..936ed2a9435
--- /dev/null
+++ b/drivers/net/igbvf/igbvf.h
@@ -0,0 +1,335 @@
+/*******************************************************************************
+
+ Intel(R) 82576 Virtual Function Linux driver
+ Copyright(c) 2009 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+/* Linux PRO/1000 Ethernet Driver main header file */
+
+#ifndef _IGBVF_H_
+#define _IGBVF_H_
+
+#include <linux/types.h>
+#include <linux/timer.h>
+#include <linux/io.h>
+#include <linux/netdevice.h>
+
+
+#include "vf.h"
+
+/* Forward declarations */
+struct igbvf_info;
+struct igbvf_adapter;
+
+/* Interrupt defines */
+#define IGBVF_START_ITR 648 /* ~6000 ints/sec */
+
+/* Interrupt modes, as used by the IntMode paramter */
+#define IGBVF_INT_MODE_LEGACY 0
+#define IGBVF_INT_MODE_MSI 1
+#define IGBVF_INT_MODE_MSIX 2
+
+/* Tx/Rx descriptor defines */
+#define IGBVF_DEFAULT_TXD 256
+#define IGBVF_MAX_TXD 4096
+#define IGBVF_MIN_TXD 80
+
+#define IGBVF_DEFAULT_RXD 256
+#define IGBVF_MAX_RXD 4096
+#define IGBVF_MIN_RXD 80
+
+#define IGBVF_MIN_ITR_USECS 10 /* 100000 irq/sec */
+#define IGBVF_MAX_ITR_USECS 10000 /* 100 irq/sec */
+
+/* RX descriptor control thresholds.
+ * PTHRESH - MAC will consider prefetch if it has fewer than this number of
+ * descriptors available in its onboard memory.
+ * Setting this to 0 disables RX descriptor prefetch.
+ * HTHRESH - MAC will only prefetch if there are at least this many descriptors
+ * available in host memory.
+ * If PTHRESH is 0, this should also be 0.
+ * WTHRESH - RX descriptor writeback threshold - MAC will delay writing back
+ * descriptors until either it has this many to write back, or the
+ * ITR timer expires.
+ */
+#define IGBVF_RX_PTHRESH 16
+#define IGBVF_RX_HTHRESH 8
+#define IGBVF_RX_WTHRESH 1
+
+/* this is the size past which hardware will drop packets when setting LPE=0 */
+#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
+
+#define IGBVF_FC_PAUSE_TIME 0x0680 /* 858 usec */
+
+/* How many Tx Descriptors do we need to call netif_wake_queue ? */
+#define IGBVF_TX_QUEUE_WAKE 32
+/* How many Rx Buffers do we bundle into one write to the hardware ? */
+#define IGBVF_RX_BUFFER_WRITE 16 /* Must be power of 2 */
+
+#define AUTO_ALL_MODES 0
+#define IGBVF_EEPROM_APME 0x0400
+
+#define IGBVF_MNG_VLAN_NONE (-1)
+
+/* Number of packet split data buffers (not including the header buffer) */
+#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
+
+enum igbvf_boards {
+ board_vf,
+};
+
+struct igbvf_queue_stats {
+ u64 packets;
+ u64 bytes;
+};
+
+/*
+ * wrappers around a pointer to a socket buffer,
+ * so a DMA handle can be stored along with the buffer
+ */
+struct igbvf_buffer {
+ dma_addr_t dma;
+ struct sk_buff *skb;
+ union {
+ /* Tx */
+ struct {
+ unsigned long time_stamp;
+ u16 length;
+ u16 next_to_watch;
+ };
+ /* Rx */
+ struct {
+ struct page *page;
+ u64 page_dma;
+ unsigned int page_offset;
+ };
+ };
+ struct page *page;
+};
+
+union igbvf_desc {
+ union e1000_adv_rx_desc rx_desc;
+ union e1000_adv_tx_desc tx_desc;
+ struct e1000_adv_tx_context_desc tx_context_desc;
+};
+
+struct igbvf_ring {
+ struct igbvf_adapter *adapter; /* backlink */
+ union igbvf_desc *desc; /* pointer to ring memory */
+ dma_addr_t dma; /* phys address of ring */
+ unsigned int size; /* length of ring in bytes */
+ unsigned int count; /* number of desc. in ring */
+
+ u16 next_to_use;
+ u16 next_to_clean;
+
+ u16 head;
+ u16 tail;
+
+ /* array of buffer information structs */
+ struct igbvf_buffer *buffer_info;
+ struct napi_struct napi;
+
+ char name[IFNAMSIZ + 5];
+ u32 eims_value;
+ u32 itr_val;
+ u16 itr_register;
+ int set_itr;
+
+ struct sk_buff *rx_skb_top;
+
+ struct igbvf_queue_stats stats;
+};
+
+/* board specific private data structure */
+struct igbvf_adapter {
+ struct timer_list watchdog_timer;
+ struct timer_list blink_timer;
+
+ struct work_struct reset_task;
+ struct work_struct watchdog_task;
+
+ const struct igbvf_info *ei;
+
+ struct vlan_group *vlgrp;
+ u32 bd_number;
+ u32 rx_buffer_len;
+ u32 polling_interval;
+ u16 mng_vlan_id;
+ u16 link_speed;
+ u16 link_duplex;
+
+ spinlock_t tx_queue_lock; /* prevent concurrent tail updates */
+
+ /* track device up/down/testing state */
+ unsigned long state;
+
+ /* Interrupt Throttle Rate */
+ u32 itr;
+ u32 itr_setting;
+ u16 tx_itr;
+ u16 rx_itr;
+
+ /*
+ * Tx
+ */
+ struct igbvf_ring *tx_ring /* One per active queue */
+ ____cacheline_aligned_in_smp;
+
+ unsigned long tx_queue_len;
+ unsigned int restart_queue;
+ u32 txd_cmd;
+
+ bool detect_tx_hung;
+ u8 tx_timeout_factor;
+
+ u32 tx_int_delay;
+ u32 tx_abs_int_delay;
+
+ unsigned int total_tx_bytes;
+ unsigned int total_tx_packets;
+ unsigned int total_rx_bytes;
+ unsigned int total_rx_packets;
+
+ /* Tx stats */
+ u32 tx_timeout_count;
+ u32 tx_fifo_head;
+ u32 tx_head_addr;
+ u32 tx_fifo_size;
+ u32 tx_dma_failed;
+
+ /*
+ * Rx
+ */
+ struct igbvf_ring *rx_ring;
+
+ u32 rx_int_delay;
+ u32 rx_abs_int_delay;
+
+ /* Rx stats */
+ u64 hw_csum_err;
+ u64 hw_csum_good;
+ u64 rx_hdr_split;
+ u32 alloc_rx_buff_failed;
+ u32 rx_dma_failed;
+
+ unsigned int rx_ps_hdr_size;
+ u32 max_frame_size;
+ u32 min_frame_size;
+
+ /* OS defined structs */
+ struct net_device *netdev;
+ struct pci_dev *pdev;
+ struct net_device_stats net_stats;
+ spinlock_t stats_lock; /* prevent concurrent stats updates */
+
+ /* structs defined in e1000_hw.h */
+ struct e1000_hw hw;
+
+ /* The VF counters don't clear on read so we have to get a base
+ * count on driver start up and always subtract that base on
+ * on the first update, thus the flag..
+ */
+ struct e1000_vf_stats stats;
+ u64 zero_base;
+
+ struct igbvf_ring test_tx_ring;
+ struct igbvf_ring test_rx_ring;
+ u32 test_icr;
+
+ u32 msg_enable;
+ struct msix_entry *msix_entries;
+ int int_mode;
+ u32 eims_enable_mask;
+ u32 eims_other;
+ u32 int_counter0;
+ u32 int_counter1;
+
+ u32 eeprom_wol;
+ u32 wol;
+ u32 pba;
+
+ bool fc_autoneg;
+
+ unsigned long led_status;
+
+ unsigned int flags;
+};
+
+struct igbvf_info {
+ enum e1000_mac_type mac;
+ unsigned int flags;
+ u32 pba;
+ void (*init_ops)(struct e1000_hw *);
+ s32 (*get_variants)(struct igbvf_adapter *);
+};
+
+/* hardware capability, feature, and workaround flags */
+#define FLAG_HAS_HW_VLAN_FILTER (1 << 0)
+#define FLAG_HAS_JUMBO_FRAMES (1 << 1)
+#define FLAG_MSI_ENABLED (1 << 2)
+#define FLAG_RX_CSUM_ENABLED (1 << 3)
+#define FLAG_TSO_FORCE (1 << 4)
+
+#define IGBVF_RX_DESC_ADV(R, i) \
+ (&((((R).desc))[i].rx_desc))
+#define IGBVF_TX_DESC_ADV(R, i) \
+ (&((((R).desc))[i].tx_desc))
+#define IGBVF_TX_CTXTDESC_ADV(R, i) \
+ (&((((R).desc))[i].tx_context_desc))
+
+enum igbvf_state_t {
+ __IGBVF_TESTING,
+ __IGBVF_RESETTING,
+ __IGBVF_DOWN
+};
+
+enum latency_range {
+ lowest_latency = 0,
+ low_latency = 1,
+ bulk_latency = 2,
+ latency_invalid = 255
+};
+
+extern char igbvf_driver_name[];
+extern const char igbvf_driver_version[];
+
+extern void igbvf_check_options(struct igbvf_adapter *);
+extern void igbvf_set_ethtool_ops(struct net_device *);
+
+extern int igbvf_up(struct igbvf_adapter *);
+extern void igbvf_down(struct igbvf_adapter *);
+extern void igbvf_reinit_locked(struct igbvf_adapter *);
+extern void igbvf_reset(struct igbvf_adapter *);
+extern int igbvf_setup_rx_resources(struct igbvf_adapter *, struct igbvf_ring *);
+extern int igbvf_setup_tx_resources(struct igbvf_adapter *, struct igbvf_ring *);
+extern void igbvf_free_rx_resources(struct igbvf_ring *);
+extern void igbvf_free_tx_resources(struct igbvf_ring *);
+extern void igbvf_update_stats(struct igbvf_adapter *);
+extern void igbvf_set_interrupt_capability(struct igbvf_adapter *);
+extern void igbvf_reset_interrupt_capability(struct igbvf_adapter *);
+
+extern unsigned int copybreak;
+
+#endif /* _IGBVF_H_ */
diff --git a/drivers/net/igbvf/mbx.c b/drivers/net/igbvf/mbx.c
new file mode 100644
index 00000000000..819a8ec901d
--- /dev/null
+++ b/drivers/net/igbvf/mbx.c
@@ -0,0 +1,350 @@
+/*******************************************************************************
+
+ Intel(R) 82576 Virtual Function Linux driver
+ Copyright(c) 2009 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include "mbx.h"
+
+/**
+ * e1000_poll_for_msg - Wait for message notification
+ * @hw: pointer to the HW structure
+ *
+ * returns SUCCESS if it successfully received a message notification
+ **/
+static s32 e1000_poll_for_msg(struct e1000_hw *hw)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ int countdown = mbx->timeout;
+
+ if (!mbx->ops.check_for_msg)
+ goto out;
+
+ while (countdown && mbx->ops.check_for_msg(hw)) {
+ countdown--;
+ udelay(mbx->usec_delay);
+ }
+
+ /* if we failed, all future posted messages fail until reset */
+ if (!countdown)
+ mbx->timeout = 0;
+out:
+ return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
+}
+
+/**
+ * e1000_poll_for_ack - Wait for message acknowledgement
+ * @hw: pointer to the HW structure
+ *
+ * returns SUCCESS if it successfully received a message acknowledgement
+ **/
+static s32 e1000_poll_for_ack(struct e1000_hw *hw)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ int countdown = mbx->timeout;
+
+ if (!mbx->ops.check_for_ack)
+ goto out;
+
+ while (countdown && mbx->ops.check_for_ack(hw)) {
+ countdown--;
+ udelay(mbx->usec_delay);
+ }
+
+ /* if we failed, all future posted messages fail until reset */
+ if (!countdown)
+ mbx->timeout = 0;
+out:
+ return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
+}
+
+/**
+ * e1000_read_posted_mbx - Wait for message notification and receive message
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ *
+ * returns SUCCESS if it successfully received a message notification and
+ * copied it into the receive buffer.
+ **/
+static s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (!mbx->ops.read)
+ goto out;
+
+ ret_val = e1000_poll_for_msg(hw);
+
+ /* if ack received read message, otherwise we timed out */
+ if (!ret_val)
+ ret_val = mbx->ops.read(hw, msg, size);
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_write_posted_mbx - Write a message to the mailbox, wait for ack
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ *
+ * returns SUCCESS if it successfully copied message into the buffer and
+ * received an ack to that message within delay * timeout period
+ **/
+static s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = -E1000_ERR_MBX;
+
+ /* exit if we either can't write or there isn't a defined timeout */
+ if (!mbx->ops.write || !mbx->timeout)
+ goto out;
+
+ /* send msg*/
+ ret_val = mbx->ops.write(hw, msg, size);
+
+ /* if msg sent wait until we receive an ack */
+ if (!ret_val)
+ ret_val = e1000_poll_for_ack(hw);
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_read_v2p_mailbox - read v2p mailbox
+ * @hw: pointer to the HW structure
+ *
+ * This function is used to read the v2p mailbox without losing the read to
+ * clear status bits.
+ **/
+static u32 e1000_read_v2p_mailbox(struct e1000_hw *hw)
+{
+ u32 v2p_mailbox = er32(V2PMAILBOX(0));
+
+ v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox;
+ hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS;
+
+ return v2p_mailbox;
+}
+
+/**
+ * e1000_check_for_bit_vf - Determine if a status bit was set
+ * @hw: pointer to the HW structure
+ * @mask: bitmask for bits to be tested and cleared
+ *
+ * This function is used to check for the read to clear bits within
+ * the V2P mailbox.
+ **/
+static s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask)
+{
+ u32 v2p_mailbox = e1000_read_v2p_mailbox(hw);
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (v2p_mailbox & mask)
+ ret_val = E1000_SUCCESS;
+
+ hw->dev_spec.vf.v2p_mailbox &= ~mask;
+
+ return ret_val;
+}
+
+/**
+ * e1000_check_for_msg_vf - checks to see if the PF has sent mail
+ * @hw: pointer to the HW structure
+ *
+ * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
+ **/
+static s32 e1000_check_for_msg_vf(struct e1000_hw *hw)
+{
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) {
+ ret_val = E1000_SUCCESS;
+ hw->mbx.stats.reqs++;
+ }
+
+ return ret_val;
+}
+
+/**
+ * e1000_check_for_ack_vf - checks to see if the PF has ACK'd
+ * @hw: pointer to the HW structure
+ *
+ * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
+ **/
+static s32 e1000_check_for_ack_vf(struct e1000_hw *hw)
+{
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) {
+ ret_val = E1000_SUCCESS;
+ hw->mbx.stats.acks++;
+ }
+
+ return ret_val;
+}
+
+/**
+ * e1000_check_for_rst_vf - checks to see if the PF has reset
+ * @hw: pointer to the HW structure
+ *
+ * returns true if the PF has set the reset done bit or else false
+ **/
+static s32 e1000_check_for_rst_vf(struct e1000_hw *hw)
+{
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD |
+ E1000_V2PMAILBOX_RSTI))) {
+ ret_val = E1000_SUCCESS;
+ hw->mbx.stats.rsts++;
+ }
+
+ return ret_val;
+}
+
+/**
+ * e1000_obtain_mbx_lock_vf - obtain mailbox lock
+ * @hw: pointer to the HW structure
+ *
+ * return SUCCESS if we obtained the mailbox lock
+ **/
+static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw)
+{
+ s32 ret_val = -E1000_ERR_MBX;
+
+ /* Take ownership of the buffer */
+ ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
+
+ /* reserve mailbox for vf use */
+ if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU)
+ ret_val = E1000_SUCCESS;
+
+ return ret_val;
+}
+
+/**
+ * e1000_write_mbx_vf - Write a message to the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ *
+ * returns SUCCESS if it successfully copied message into the buffer
+ **/
+static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size)
+{
+ s32 err;
+ u16 i;
+
+ /* lock the mailbox to prevent pf/vf race condition */
+ err = e1000_obtain_mbx_lock_vf(hw);
+ if (err)
+ goto out_no_write;
+
+ /* flush any ack or msg as we are going to overwrite mailbox */
+ e1000_check_for_ack_vf(hw);
+ e1000_check_for_msg_vf(hw);
+
+ /* copy the caller specified message to the mailbox memory buffer */
+ for (i = 0; i < size; i++)
+ array_ew32(VMBMEM(0), i, msg[i]);
+
+ /* update stats */
+ hw->mbx.stats.msgs_tx++;
+
+ /* Drop VFU and interrupt the PF to tell it a message has been sent */
+ ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_REQ);
+
+out_no_write:
+ return err;
+}
+
+/**
+ * e1000_read_mbx_vf - Reads a message from the inbox intended for vf
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ *
+ * returns SUCCESS if it successfuly read message from buffer
+ **/
+static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size)
+{
+ s32 err;
+ u16 i;
+
+ /* lock the mailbox to prevent pf/vf race condition */
+ err = e1000_obtain_mbx_lock_vf(hw);
+ if (err)
+ goto out_no_read;
+
+ /* copy the message from the mailbox memory buffer */
+ for (i = 0; i < size; i++)
+ msg[i] = array_er32(VMBMEM(0), i);
+
+ /* Acknowledge receipt and release mailbox, then we're done */
+ ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_ACK);
+
+ /* update stats */
+ hw->mbx.stats.msgs_rx++;
+
+out_no_read:
+ return err;
+}
+
+/**
+ * e1000_init_mbx_params_vf - set initial values for vf mailbox
+ * @hw: pointer to the HW structure
+ *
+ * Initializes the hw->mbx struct to correct values for vf mailbox
+ */
+s32 e1000_init_mbx_params_vf(struct e1000_hw *hw)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+
+ /* start mailbox as timed out and let the reset_hw call set the timeout
+ * value to being communications */
+ mbx->timeout = 0;
+ mbx->usec_delay = E1000_VF_MBX_INIT_DELAY;
+
+ mbx->size = E1000_VFMAILBOX_SIZE;
+
+ mbx->ops.read = e1000_read_mbx_vf;
+ mbx->ops.write = e1000_write_mbx_vf;
+ mbx->ops.read_posted = e1000_read_posted_mbx;
+ mbx->ops.write_posted = e1000_write_posted_mbx;
+ mbx->ops.check_for_msg = e1000_check_for_msg_vf;
+ mbx->ops.check_for_ack = e1000_check_for_ack_vf;
+ mbx->ops.check_for_rst = e1000_check_for_rst_vf;
+
+ mbx->stats.msgs_tx = 0;
+ mbx->stats.msgs_rx = 0;
+ mbx->stats.reqs = 0;
+ mbx->stats.acks = 0;
+ mbx->stats.rsts = 0;
+
+ return E1000_SUCCESS;
+}
+
diff --git a/drivers/net/igbvf/mbx.h b/drivers/net/igbvf/mbx.h
new file mode 100644
index 00000000000..4938609dbfb
--- /dev/null
+++ b/drivers/net/igbvf/mbx.h
@@ -0,0 +1,75 @@
+/*******************************************************************************
+
+ Intel(R) 82576 Virtual Function Linux driver
+ Copyright(c) 1999 - 2009 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_MBX_H_
+#define _E1000_MBX_H_
+
+#include "vf.h"
+
+#define E1000_V2PMAILBOX_REQ 0x00000001 /* Request for PF Ready bit */
+#define E1000_V2PMAILBOX_ACK 0x00000002 /* Ack PF message received */
+#define E1000_V2PMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
+#define E1000_V2PMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
+#define E1000_V2PMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the MB */
+#define E1000_V2PMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg */
+#define E1000_V2PMAILBOX_RSTI 0x00000040 /* PF has reset indication */
+#define E1000_V2PMAILBOX_RSTD 0x00000080 /* PF has indicated reset done */
+#define E1000_V2PMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */
+
+#define E1000_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */
+
+/* If it's a E1000_VF_* msg then it originates in the VF and is sent to the
+ * PF. The reverse is true if it is E1000_PF_*.
+ * Message ACK's are the value or'd with 0xF0000000
+ */
+#define E1000_VT_MSGTYPE_ACK 0x80000000 /* Messages below or'd with
+ * this are the ACK */
+#define E1000_VT_MSGTYPE_NACK 0x40000000 /* Messages below or'd with
+ * this are the NACK */
+#define E1000_VT_MSGTYPE_CTS 0x20000000 /* Indicates that VF is still
+ clear to send requests */
+
+/* We have a total wait time of 1s for vf mailbox posted messages */
+#define E1000_VF_MBX_INIT_TIMEOUT 2000 /* retry count for mailbox timeout */
+#define E1000_VF_MBX_INIT_DELAY 500 /* usec delay between retries */
+
+#define E1000_VT_MSGINFO_SHIFT 16
+/* bits 23:16 are used for exra info for certain messages */
+#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT)
+
+#define E1000_VF_RESET 0x01 /* VF requests reset */
+#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */
+#define E1000_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
+#define E1000_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
+#define E1000_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
+
+#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */
+
+void e1000_init_mbx_ops_generic(struct e1000_hw *hw);
+s32 e1000_init_mbx_params_vf(struct e1000_hw *);
+
+#endif /* _E1000_MBX_H_ */
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
new file mode 100644
index 00000000000..c5648420ded
--- /dev/null
+++ b/drivers/net/igbvf/netdev.c
@@ -0,0 +1,2919 @@
+/*******************************************************************************
+
+ Intel(R) 82576 Virtual Function Linux driver
+ Copyright(c) 2009 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/tcp.h>
+#include <linux/ipv6.h>
+#include <net/checksum.h>
+#include <net/ip6_checksum.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/pm_qos_params.h>
+
+#include "igbvf.h"
+
+#define DRV_VERSION "1.0.0-k0"
+char igbvf_driver_name[] = "igbvf";
+const char igbvf_driver_version[] = DRV_VERSION;
+static const char igbvf_driver_string[] =
+ "Intel(R) Virtual Function Network Driver";
+static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation.";
+
+static int igbvf_poll(struct napi_struct *napi, int budget);
+
+static struct igbvf_info igbvf_vf_info = {
+ .mac = e1000_vfadapt,
+ .flags = FLAG_HAS_JUMBO_FRAMES
+ | FLAG_RX_CSUM_ENABLED,
+ .pba = 10,
+ .init_ops = e1000_init_function_pointers_vf,
+};
+
+static const struct igbvf_info *igbvf_info_tbl[] = {
+ [board_vf] = &igbvf_vf_info,
+};
+
+/**
+ * igbvf_desc_unused - calculate if we have unused descriptors
+ **/
+static int igbvf_desc_unused(struct igbvf_ring *ring)
+{
+ if (ring->next_to_clean > ring->next_to_use)
+ return ring->next_to_clean - ring->next_to_use - 1;
+
+ return ring->count + ring->next_to_clean - ring->next_to_use - 1;
+}
+
+/**
+ * igbvf_receive_skb - helper function to handle Rx indications
+ * @adapter: board private structure
+ * @status: descriptor status field as written by hardware
+ * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
+ * @skb: pointer to sk_buff to be indicated to stack
+ **/
+static void igbvf_receive_skb(struct igbvf_adapter *adapter,
+ struct net_device *netdev,
+ struct sk_buff *skb,
+ u32 status, u16 vlan)
+{
+ if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
+ vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+ le16_to_cpu(vlan) &
+ E1000_RXD_SPC_VLAN_MASK);
+ else
+ netif_receive_skb(skb);
+
+ netdev->last_rx = jiffies;
+}
+
+static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
+ u32 status_err, struct sk_buff *skb)
+{
+ skb->ip_summed = CHECKSUM_NONE;
+
+ /* Ignore Checksum bit is set or checksum is disabled through ethtool */
+ if ((status_err & E1000_RXD_STAT_IXSM))
+ return;
+ /* TCP/UDP checksum error bit is set */
+ if (status_err &
+ (E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) {
+ /* let the stack verify checksum errors */
+ adapter->hw_csum_err++;
+ return;
+ }
+ /* It must be a TCP or UDP packet with a valid checksum */
+ if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ adapter->hw_csum_good++;
+}
+
+/**
+ * igbvf_alloc_rx_buffers - Replace used receive buffers; packet split
+ * @rx_ring: address of ring structure to repopulate
+ * @cleaned_count: number of buffers to repopulate
+ **/
+static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,
+ int cleaned_count)
+{
+ struct igbvf_adapter *adapter = rx_ring->adapter;
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ union e1000_adv_rx_desc *rx_desc;
+ struct igbvf_buffer *buffer_info;
+ struct sk_buff *skb;
+ unsigned int i;
+ int bufsz;
+
+ i = rx_ring->next_to_use;
+ buffer_info = &rx_ring->buffer_info[i];
+
+ if (adapter->rx_ps_hdr_size)
+ bufsz = adapter->rx_ps_hdr_size;
+ else
+ bufsz = adapter->rx_buffer_len;
+ bufsz += NET_IP_ALIGN;
+
+ while (cleaned_count--) {
+ rx_desc = IGBVF_RX_DESC_ADV(*rx_ring, i);
+
+ if (adapter->rx_ps_hdr_size && !buffer_info->page_dma) {
+ if (!buffer_info->page) {
+ buffer_info->page = alloc_page(GFP_ATOMIC);
+ if (!buffer_info->page) {
+ adapter->alloc_rx_buff_failed++;
+ goto no_buffers;
+ }
+ buffer_info->page_offset = 0;
+ } else {
+ buffer_info->page_offset ^= PAGE_SIZE / 2;
+ }
+ buffer_info->page_dma =
+ pci_map_page(pdev, buffer_info->page,
+ buffer_info->page_offset,
+ PAGE_SIZE / 2,
+ PCI_DMA_FROMDEVICE);
+ }
+
+ if (!buffer_info->skb) {
+ skb = netdev_alloc_skb(netdev, bufsz);
+ if (!skb) {
+ adapter->alloc_rx_buff_failed++;
+ goto no_buffers;
+ }
+
+ /* Make buffer alignment 2 beyond a 16 byte boundary
+ * this will result in a 16 byte aligned IP header after
+ * the 14 byte MAC header is removed
+ */
+ skb_reserve(skb, NET_IP_ALIGN);
+
+ buffer_info->skb = skb;
+ buffer_info->dma = pci_map_single(pdev, skb->data,
+ bufsz,
+ PCI_DMA_FROMDEVICE);
+ }
+ /* Refresh the desc even if buffer_addrs didn't change because
+ * each write-back erases this info. */
+ if (adapter->rx_ps_hdr_size) {
+ rx_desc->read.pkt_addr =
+ cpu_to_le64(buffer_info->page_dma);
+ rx_desc->read.hdr_addr = cpu_to_le64(buffer_info->dma);
+ } else {
+ rx_desc->read.pkt_addr =
+ cpu_to_le64(buffer_info->dma);
+ rx_desc->read.hdr_addr = 0;
+ }
+
+ i++;
+ if (i == rx_ring->count)
+ i = 0;
+ buffer_info = &rx_ring->buffer_info[i];
+ }
+
+no_buffers:
+ if (rx_ring->next_to_use != i) {
+ rx_ring->next_to_use = i;
+ if (i == 0)
+ i = (rx_ring->count - 1);
+ else
+ i--;
+
+ /* Force memory writes to complete before letting h/w
+ * know there are new descriptors to fetch. (Only
+ * applicable for weak-ordered memory model archs,
+ * such as IA-64). */
+ wmb();
+ writel(i, adapter->hw.hw_addr + rx_ring->tail);
+ }
+}
+
+/**
+ * igbvf_clean_rx_irq - Send received data up the network stack; legacy
+ * @adapter: board private structure
+ *
+ * the return value indicates whether actual cleaning was done, there
+ * is no guarantee that everything was cleaned
+ **/
+static bool igbvf_clean_rx_irq(struct igbvf_adapter *adapter,
+ int *work_done, int work_to_do)
+{
+ struct igbvf_ring *rx_ring = adapter->rx_ring;
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ union e1000_adv_rx_desc *rx_desc, *next_rxd;
+ struct igbvf_buffer *buffer_info, *next_buffer;
+ struct sk_buff *skb;
+ bool cleaned = false;
+ int cleaned_count = 0;
+ unsigned int total_bytes = 0, total_packets = 0;
+ unsigned int i;
+ u32 length, hlen, staterr;
+
+ i = rx_ring->next_to_clean;
+ rx_desc = IGBVF_RX_DESC_ADV(*rx_ring, i);
+ staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+
+ while (staterr & E1000_RXD_STAT_DD) {
+ if (*work_done >= work_to_do)
+ break;
+ (*work_done)++;
+
+ buffer_info = &rx_ring->buffer_info[i];
+
+ /* HW will not DMA in data larger than the given buffer, even
+ * if it parses the (NFS, of course) header to be larger. In
+ * that case, it fills the header buffer and spills the rest
+ * into the page.
+ */
+ hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.hdr_info) &
+ E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
+ if (hlen > adapter->rx_ps_hdr_size)
+ hlen = adapter->rx_ps_hdr_size;
+
+ length = le16_to_cpu(rx_desc->wb.upper.length);
+ cleaned = true;
+ cleaned_count++;
+
+ skb = buffer_info->skb;
+ prefetch(skb->data - NET_IP_ALIGN);
+ buffer_info->skb = NULL;
+ if (!adapter->rx_ps_hdr_size) {
+ pci_unmap_single(pdev, buffer_info->dma,
+ adapter->rx_buffer_len,
+ PCI_DMA_FROMDEVICE);
+ buffer_info->dma = 0;
+ skb_put(skb, length);
+ goto send_up;
+ }
+
+ if (!skb_shinfo(skb)->nr_frags) {
+ pci_unmap_single(pdev, buffer_info->dma,
+ adapter->rx_ps_hdr_size + NET_IP_ALIGN,
+ PCI_DMA_FROMDEVICE);
+ skb_put(skb, hlen);
+ }
+
+ if (length) {
+ pci_unmap_page(pdev, buffer_info->page_dma,
+ PAGE_SIZE / 2,
+ PCI_DMA_FROMDEVICE);
+ buffer_info->page_dma = 0;
+
+ skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags++,
+ buffer_info->page,
+ buffer_info->page_offset,
+ length);
+
+ if ((adapter->rx_buffer_len > (PAGE_SIZE / 2)) ||
+ (page_count(buffer_info->page) != 1))
+ buffer_info->page = NULL;
+ else
+ get_page(buffer_info->page);
+
+ skb->len += length;
+ skb->data_len += length;
+ skb->truesize += length;
+ }
+send_up:
+ i++;
+ if (i == rx_ring->count)
+ i = 0;
+ next_rxd = IGBVF_RX_DESC_ADV(*rx_ring, i);
+ prefetch(next_rxd);
+ next_buffer = &rx_ring->buffer_info[i];
+
+ if (!(staterr & E1000_RXD_STAT_EOP)) {
+ buffer_info->skb = next_buffer->skb;
+ buffer_info->dma = next_buffer->dma;
+ next_buffer->skb = skb;
+ next_buffer->dma = 0;
+ goto next_desc;
+ }
+
+ if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
+ dev_kfree_skb_irq(skb);
+ goto next_desc;
+ }
+
+ total_bytes += skb->len;
+ total_packets++;
+
+ igbvf_rx_checksum_adv(adapter, staterr, skb);
+
+ skb->protocol = eth_type_trans(skb, netdev);
+
+ igbvf_receive_skb(adapter, netdev, skb, staterr,
+ rx_desc->wb.upper.vlan);
+
+ netdev->last_rx = jiffies;
+
+next_desc:
+ rx_desc->wb.upper.status_error = 0;
+
+ /* return some buffers to hardware, one at a time is too slow */
+ if (cleaned_count >= IGBVF_RX_BUFFER_WRITE) {
+ igbvf_alloc_rx_buffers(rx_ring, cleaned_count);
+ cleaned_count = 0;
+ }
+
+ /* use prefetched values */
+ rx_desc = next_rxd;
+ buffer_info = next_buffer;
+
+ staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+ }
+
+ rx_ring->next_to_clean = i;
+ cleaned_count = igbvf_desc_unused(rx_ring);
+
+ if (cleaned_count)
+ igbvf_alloc_rx_buffers(rx_ring, cleaned_count);
+
+ adapter->total_rx_packets += total_packets;
+ adapter->total_rx_bytes += total_bytes;
+ adapter->net_stats.rx_bytes += total_bytes;
+ adapter->net_stats.rx_packets += total_packets;
+ return cleaned;
+}
+
+static void igbvf_put_txbuf(struct igbvf_adapter *adapter,
+ struct igbvf_buffer *buffer_info)
+{
+ buffer_info->dma = 0;
+ if (buffer_info->skb) {
+ skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
+ DMA_TO_DEVICE);
+ dev_kfree_skb_any(buffer_info->skb);
+ buffer_info->skb = NULL;
+ }
+ buffer_info->time_stamp = 0;
+}
+
+static void igbvf_print_tx_hang(struct igbvf_adapter *adapter)
+{
+ struct igbvf_ring *tx_ring = adapter->tx_ring;
+ unsigned int i = tx_ring->next_to_clean;
+ unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
+ union e1000_adv_tx_desc *eop_desc = IGBVF_TX_DESC_ADV(*tx_ring, eop);
+
+ /* detected Tx unit hang */
+ dev_err(&adapter->pdev->dev,
+ "Detected Tx Unit Hang:\n"
+ " TDH <%x>\n"
+ " TDT <%x>\n"
+ " next_to_use <%x>\n"
+ " next_to_clean <%x>\n"
+ "buffer_info[next_to_clean]:\n"
+ " time_stamp <%lx>\n"
+ " next_to_watch <%x>\n"
+ " jiffies <%lx>\n"
+ " next_to_watch.status <%x>\n",
+ readl(adapter->hw.hw_addr + tx_ring->head),
+ readl(adapter->hw.hw_addr + tx_ring->tail),
+ tx_ring->next_to_use,
+ tx_ring->next_to_clean,
+ tx_ring->buffer_info[eop].time_stamp,
+ eop,
+ jiffies,
+ eop_desc->wb.status);
+}
+
+/**
+ * igbvf_setup_tx_resources - allocate Tx resources (Descriptors)
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ **/
+int igbvf_setup_tx_resources(struct igbvf_adapter *adapter,
+ struct igbvf_ring *tx_ring)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ int size;
+
+ size = sizeof(struct igbvf_buffer) * tx_ring->count;
+ tx_ring->buffer_info = vmalloc(size);
+ if (!tx_ring->buffer_info)
+ goto err;
+ memset(tx_ring->buffer_info, 0, size);
+
+ /* round up to nearest 4K */
+ tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
+ tx_ring->size = ALIGN(tx_ring->size, 4096);
+
+ tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
+ &tx_ring->dma);
+
+ if (!tx_ring->desc)
+ goto err;
+
+ tx_ring->adapter = adapter;
+ tx_ring->next_to_use = 0;
+ tx_ring->next_to_clean = 0;
+
+ return 0;
+err:
+ vfree(tx_ring->buffer_info);
+ dev_err(&adapter->pdev->dev,
+ "Unable to allocate memory for the transmit descriptor ring\n");
+ return -ENOMEM;
+}
+
+/**
+ * igbvf_setup_rx_resources - allocate Rx resources (Descriptors)
+ * @adapter: board private structure
+ *
+ * Returns 0 on success, negative on failure
+ **/
+int igbvf_setup_rx_resources(struct igbvf_adapter *adapter,
+ struct igbvf_ring *rx_ring)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ int size, desc_len;
+
+ size = sizeof(struct igbvf_buffer) * rx_ring->count;
+ rx_ring->buffer_info = vmalloc(size);
+ if (!rx_ring->buffer_info)
+ goto err;
+ memset(rx_ring->buffer_info, 0, size);
+
+ desc_len = sizeof(union e1000_adv_rx_desc);
+
+ /* Round up to nearest 4K */
+ rx_ring->size = rx_ring->count * desc_len;
+ rx_ring->size = ALIGN(rx_ring->size, 4096);
+
+ rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size,
+ &rx_ring->dma);
+
+ if (!rx_ring->desc)
+ goto err;
+
+ rx_ring->next_to_clean = 0;
+ rx_ring->next_to_use = 0;
+
+ rx_ring->adapter = adapter;
+
+ return 0;
+
+err:
+ vfree(rx_ring->buffer_info);
+ rx_ring->buffer_info = NULL;
+ dev_err(&adapter->pdev->dev,
+ "Unable to allocate memory for the receive descriptor ring\n");
+ return -ENOMEM;
+}
+
+/**
+ * igbvf_clean_tx_ring - Free Tx Buffers
+ * @tx_ring: ring to be cleaned
+ **/
+static void igbvf_clean_tx_ring(struct igbvf_ring *tx_ring)
+{
+ struct igbvf_adapter *adapter = tx_ring->adapter;
+ struct igbvf_buffer *buffer_info;
+ unsigned long size;
+ unsigned int i;
+
+ if (!tx_ring->buffer_info)
+ return;
+
+ /* Free all the Tx ring sk_buffs */
+ for (i = 0; i < tx_ring->count; i++) {
+ buffer_info = &tx_ring->buffer_info[i];
+ igbvf_put_txbuf(adapter, buffer_info);
+ }
+
+ size = sizeof(struct igbvf_buffer) * tx_ring->count;
+ memset(tx_ring->buffer_info, 0, size);
+
+ /* Zero out the descriptor ring */
+ memset(tx_ring->desc, 0, tx_ring->size);
+
+ tx_ring->next_to_use = 0;
+ tx_ring->next_to_clean = 0;
+
+ writel(0, adapter->hw.hw_addr + tx_ring->head);
+ writel(0, adapter->hw.hw_addr + tx_ring->tail);
+}
+
+/**
+ * igbvf_free_tx_resources - Free Tx Resources per Queue
+ * @tx_ring: ring to free resources from
+ *
+ * Free all transmit software resources
+ **/
+void igbvf_free_tx_resources(struct igbvf_ring *tx_ring)
+{
+ struct pci_dev *pdev = tx_ring->adapter->pdev;
+
+ igbvf_clean_tx_ring(tx_ring);
+
+ vfree(tx_ring->buffer_info);
+ tx_ring->buffer_info = NULL;
+
+ pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
+
+ tx_ring->desc = NULL;
+}
+
+/**
+ * igbvf_clean_rx_ring - Free Rx Buffers per Queue
+ * @adapter: board private structure
+ **/
+static void igbvf_clean_rx_ring(struct igbvf_ring *rx_ring)
+{
+ struct igbvf_adapter *adapter = rx_ring->adapter;
+ struct igbvf_buffer *buffer_info;
+ struct pci_dev *pdev = adapter->pdev;
+ unsigned long size;
+ unsigned int i;
+
+ if (!rx_ring->buffer_info)
+ return;
+
+ /* Free all the Rx ring sk_buffs */
+ for (i = 0; i < rx_ring->count; i++) {
+ buffer_info = &rx_ring->buffer_info[i];
+ if (buffer_info->dma) {
+ if (adapter->rx_ps_hdr_size){
+ pci_unmap_single(pdev, buffer_info->dma,
+ adapter->rx_ps_hdr_size,
+ PCI_DMA_FROMDEVICE);
+ } else {
+ pci_unmap_single(pdev, buffer_info->dma,
+ adapter->rx_buffer_len,
+ PCI_DMA_FROMDEVICE);
+ }
+ buffer_info->dma = 0;
+ }
+
+ if (buffer_info->skb) {
+ dev_kfree_skb(buffer_info->skb);
+ buffer_info->skb = NULL;
+ }
+
+ if (buffer_info->page) {
+ if (buffer_info->page_dma)
+ pci_unmap_page(pdev, buffer_info->page_dma,
+ PAGE_SIZE / 2,
+ PCI_DMA_FROMDEVICE);
+ put_page(buffer_info->page);
+ buffer_info->page = NULL;
+ buffer_info->page_dma = 0;
+ buffer_info->page_offset = 0;
+ }
+ }
+
+ size = sizeof(struct igbvf_buffer) * rx_ring->count;
+ memset(rx_ring->buffer_info, 0, size);
+
+ /* Zero out the descriptor ring */
+ memset(rx_ring->desc, 0, rx_ring->size);
+
+ rx_ring->next_to_clean = 0;
+ rx_ring->next_to_use = 0;
+
+ writel(0, adapter->hw.hw_addr + rx_ring->head);
+ writel(0, adapter->hw.hw_addr + rx_ring->tail);
+}
+
+/**
+ * igbvf_free_rx_resources - Free Rx Resources
+ * @rx_ring: ring to clean the resources from
+ *
+ * Free all receive software resources
+ **/
+
+void igbvf_free_rx_resources(struct igbvf_ring *rx_ring)
+{
+ struct pci_dev *pdev = rx_ring->adapter->pdev;
+
+ igbvf_clean_rx_ring(rx_ring);
+
+ vfree(rx_ring->buffer_info);
+ rx_ring->buffer_info = NULL;
+
+ dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
+ rx_ring->dma);
+ rx_ring->desc = NULL;
+}
+
+/**
+ * igbvf_update_itr - update the dynamic ITR value based on statistics
+ * @adapter: pointer to adapter
+ * @itr_setting: current adapter->itr
+ * @packets: the number of packets during this measurement interval
+ * @bytes: the number of bytes during this measurement interval
+ *
+ * Stores a new ITR value based on packets and byte
+ * counts during the last interrupt. The advantage of per interrupt
+ * computation is faster updates and more accurate ITR for the current
+ * traffic pattern. Constants in this function were computed
+ * based on theoretical maximum wire speed and thresholds were set based
+ * on testing data as well as attempting to minimize response time
+ * while increasing bulk throughput. This functionality is controlled
+ * by the InterruptThrottleRate module parameter.
+ **/
+static unsigned int igbvf_update_itr(struct igbvf_adapter *adapter,
+ u16 itr_setting, int packets,
+ int bytes)
+{
+ unsigned int retval = itr_setting;
+
+ if (packets == 0)
+ goto update_itr_done;
+
+ switch (itr_setting) {
+ case lowest_latency:
+ /* handle TSO and jumbo frames */
+ if (bytes/packets > 8000)
+ retval = bulk_latency;
+ else if ((packets < 5) && (bytes > 512))
+ retval = low_latency;
+ break;
+ case low_latency: /* 50 usec aka 20000 ints/s */
+ if (bytes > 10000) {
+ /* this if handles the TSO accounting */
+ if (bytes/packets > 8000)
+ retval = bulk_latency;
+ else if ((packets < 10) || ((bytes/packets) > 1200))
+ retval = bulk_latency;
+ else if ((packets > 35))
+ retval = lowest_latency;
+ } else if (bytes/packets > 2000) {
+ retval = bulk_latency;
+ } else if (packets <= 2 && bytes < 512) {
+ retval = lowest_latency;
+ }
+ break;
+ case bulk_latency: /* 250 usec aka 4000 ints/s */
+ if (bytes > 25000) {
+ if (packets > 35)
+ retval = low_latency;
+ } else if (bytes < 6000) {
+ retval = low_latency;
+ }
+ break;
+ }
+
+update_itr_done:
+ return retval;
+}
+
+static void igbvf_set_itr(struct igbvf_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u16 current_itr;
+ u32 new_itr = adapter->itr;
+
+ adapter->tx_itr = igbvf_update_itr(adapter, adapter->tx_itr,
+ adapter->total_tx_packets,
+ adapter->total_tx_bytes);
+ /* conservative mode (itr 3) eliminates the lowest_latency setting */
+ if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
+ adapter->tx_itr = low_latency;
+
+ adapter->rx_itr = igbvf_update_itr(adapter, adapter->rx_itr,
+ adapter->total_rx_packets,
+ adapter->total_rx_bytes);
+ /* conservative mode (itr 3) eliminates the lowest_latency setting */
+ if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
+ adapter->rx_itr = low_latency;
+
+ current_itr = max(adapter->rx_itr, adapter->tx_itr);
+
+ switch (current_itr) {
+ /* counts and packets in update_itr are dependent on these numbers */
+ case lowest_latency:
+ new_itr = 70000;
+ break;
+ case low_latency:
+ new_itr = 20000; /* aka hwitr = ~200 */
+ break;
+ case bulk_latency:
+ new_itr = 4000;
+ break;
+ default:
+ break;
+ }
+
+ if (new_itr != adapter->itr) {
+ /*
+ * this attempts to bias the interrupt rate towards Bulk
+ * by adding intermediate steps when interrupt rate is
+ * increasing
+ */
+ new_itr = new_itr > adapter->itr ?
+ min(adapter->itr + (new_itr >> 2), new_itr) :
+ new_itr;
+ adapter->itr = new_itr;
+ adapter->rx_ring->itr_val = 1952;
+
+ if (adapter->msix_entries)
+ adapter->rx_ring->set_itr = 1;
+ else
+ ew32(ITR, 1952);
+ }
+}
+
+/**
+ * igbvf_clean_tx_irq - Reclaim resources after transmit completes
+ * @adapter: board private structure
+ * returns true if ring is completely cleaned
+ **/
+static bool igbvf_clean_tx_irq(struct igbvf_ring *tx_ring)
+{
+ struct igbvf_adapter *adapter = tx_ring->adapter;
+ struct e1000_hw *hw = &adapter->hw;
+ struct net_device *netdev = adapter->netdev;
+ struct igbvf_buffer *buffer_info;
+ struct sk_buff *skb;
+ union e1000_adv_tx_desc *tx_desc, *eop_desc;
+ unsigned int total_bytes = 0, total_packets = 0;
+ unsigned int i, eop, count = 0;
+ bool cleaned = false;
+
+ i = tx_ring->next_to_clean;
+ eop = tx_ring->buffer_info[i].next_to_watch;
+ eop_desc = IGBVF_TX_DESC_ADV(*tx_ring, eop);
+
+ while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+ (count < tx_ring->count)) {
+ for (cleaned = false; !cleaned; count++) {
+ tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
+ buffer_info = &tx_ring->buffer_info[i];
+ cleaned = (i == eop);
+ skb = buffer_info->skb;
+
+ if (skb) {
+ unsigned int segs, bytecount;
+
+ /* gso_segs is currently only valid for tcp */
+ segs = skb_shinfo(skb)->gso_segs ?: 1;
+ /* multiply data chunks by size of headers */
+ bytecount = ((segs - 1) * skb_headlen(skb)) +
+ skb->len;
+ total_packets += segs;
+ total_bytes += bytecount;
+ }
+
+ igbvf_put_txbuf(adapter, buffer_info);
+ tx_desc->wb.status = 0;
+
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+ }
+ eop = tx_ring->buffer_info[i].next_to_watch;
+ eop_desc = IGBVF_TX_DESC_ADV(*tx_ring, eop);
+ }
+
+ tx_ring->next_to_clean = i;
+
+ if (unlikely(count &&
+ netif_carrier_ok(netdev) &&
+ igbvf_desc_unused(tx_ring) >= IGBVF_TX_QUEUE_WAKE)) {
+ /* Make sure that anybody stopping the queue after this
+ * sees the new next_to_clean.
+ */
+ smp_mb();
+ if (netif_queue_stopped(netdev) &&
+ !(test_bit(__IGBVF_DOWN, &adapter->state))) {
+ netif_wake_queue(netdev);
+ ++adapter->restart_queue;
+ }
+ }
+
+ if (adapter->detect_tx_hung) {
+ /* Detect a transmit hang in hardware, this serializes the
+ * check with the clearing of time_stamp and movement of i */
+ adapter->detect_tx_hung = false;
+ if (tx_ring->buffer_info[i].time_stamp &&
+ time_after(jiffies, tx_ring->buffer_info[i].time_stamp +
+ (adapter->tx_timeout_factor * HZ))
+ && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
+
+ tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
+ /* detected Tx unit hang */
+ igbvf_print_tx_hang(adapter);
+
+ netif_stop_queue(netdev);
+ }
+ }
+ adapter->net_stats.tx_bytes += total_bytes;
+ adapter->net_stats.tx_packets += total_packets;
+ return (count < tx_ring->count);
+}
+
+static irqreturn_t igbvf_msix_other(int irq, void *data)
+{
+ struct net_device *netdev = data;
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+
+ adapter->int_counter1++;
+
+ netif_carrier_off(netdev);
+ hw->mac.get_link_status = 1;
+ if (!test_bit(__IGBVF_DOWN, &adapter->state))
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
+
+ ew32(EIMS, adapter->eims_other);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t igbvf_intr_msix_tx(int irq, void *data)
+{
+ struct net_device *netdev = data;
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ struct igbvf_ring *tx_ring = adapter->tx_ring;
+
+
+ adapter->total_tx_bytes = 0;
+ adapter->total_tx_packets = 0;
+
+ /* auto mask will automatically reenable the interrupt when we write
+ * EICS */
+ if (!igbvf_clean_tx_irq(tx_ring))
+ /* Ring was not completely cleaned, so fire another interrupt */
+ ew32(EICS, tx_ring->eims_value);
+ else
+ ew32(EIMS, tx_ring->eims_value);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t igbvf_intr_msix_rx(int irq, void *data)
+{
+ struct net_device *netdev = data;
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ adapter->int_counter0++;
+
+ /* Write the ITR value calculated at the end of the
+ * previous interrupt.
+ */
+ if (adapter->rx_ring->set_itr) {
+ writel(adapter->rx_ring->itr_val,
+ adapter->hw.hw_addr + adapter->rx_ring->itr_register);
+ adapter->rx_ring->set_itr = 0;
+ }
+
+ if (napi_schedule_prep(&adapter->rx_ring->napi)) {
+ adapter->total_rx_bytes = 0;
+ adapter->total_rx_packets = 0;
+ __napi_schedule(&adapter->rx_ring->napi);
+ }
+
+ return IRQ_HANDLED;
+}
+
+#define IGBVF_NO_QUEUE -1
+
+static void igbvf_assign_vector(struct igbvf_adapter *adapter, int rx_queue,
+ int tx_queue, int msix_vector)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 ivar, index;
+
+ /* 82576 uses a table-based method for assigning vectors.
+ Each queue has a single entry in the table to which we write
+ a vector number along with a "valid" bit. Sadly, the layout
+ of the table is somewhat counterintuitive. */
+ if (rx_queue > IGBVF_NO_QUEUE) {
+ index = (rx_queue >> 1);
+ ivar = array_er32(IVAR0, index);
+ if (rx_queue & 0x1) {
+ /* vector goes into third byte of register */
+ ivar = ivar & 0xFF00FFFF;
+ ivar |= (msix_vector | E1000_IVAR_VALID) << 16;
+ } else {
+ /* vector goes into low byte of register */
+ ivar = ivar & 0xFFFFFF00;
+ ivar |= msix_vector | E1000_IVAR_VALID;
+ }
+ adapter->rx_ring[rx_queue].eims_value = 1 << msix_vector;
+ array_ew32(IVAR0, index, ivar);
+ }
+ if (tx_queue > IGBVF_NO_QUEUE) {
+ index = (tx_queue >> 1);
+ ivar = array_er32(IVAR0, index);
+ if (tx_queue & 0x1) {
+ /* vector goes into high byte of register */
+ ivar = ivar & 0x00FFFFFF;
+ ivar |= (msix_vector | E1000_IVAR_VALID) << 24;
+ } else {
+ /* vector goes into second byte of register */
+ ivar = ivar & 0xFFFF00FF;
+ ivar |= (msix_vector | E1000_IVAR_VALID) << 8;
+ }
+ adapter->tx_ring[tx_queue].eims_value = 1 << msix_vector;
+ array_ew32(IVAR0, index, ivar);
+ }
+}
+
+/**
+ * igbvf_configure_msix - Configure MSI-X hardware
+ *
+ * igbvf_configure_msix sets up the hardware to properly
+ * generate MSI-X interrupts.
+ **/
+static void igbvf_configure_msix(struct igbvf_adapter *adapter)
+{
+ u32 tmp;
+ struct e1000_hw *hw = &adapter->hw;
+ struct igbvf_ring *tx_ring = adapter->tx_ring;
+ struct igbvf_ring *rx_ring = adapter->rx_ring;
+ int vector = 0;
+
+ adapter->eims_enable_mask = 0;
+
+ igbvf_assign_vector(adapter, IGBVF_NO_QUEUE, 0, vector++);
+ adapter->eims_enable_mask |= tx_ring->eims_value;
+ if (tx_ring->itr_val)
+ writel(tx_ring->itr_val,
+ hw->hw_addr + tx_ring->itr_register);
+ else
+ writel(1952, hw->hw_addr + tx_ring->itr_register);
+
+ igbvf_assign_vector(adapter, 0, IGBVF_NO_QUEUE, vector++);
+ adapter->eims_enable_mask |= rx_ring->eims_value;
+ if (rx_ring->itr_val)
+ writel(rx_ring->itr_val,
+ hw->hw_addr + rx_ring->itr_register);
+ else
+ writel(1952, hw->hw_addr + rx_ring->itr_register);
+
+ /* set vector for other causes, i.e. link changes */
+
+ tmp = (vector++ | E1000_IVAR_VALID);
+
+ ew32(IVAR_MISC, tmp);
+
+ adapter->eims_enable_mask = (1 << (vector)) - 1;
+ adapter->eims_other = 1 << (vector - 1);
+ e1e_flush();
+}
+
+void igbvf_reset_interrupt_capability(struct igbvf_adapter *adapter)
+{
+ if (adapter->msix_entries) {
+ pci_disable_msix(adapter->pdev);
+ kfree(adapter->msix_entries);
+ adapter->msix_entries = NULL;
+ }
+}
+
+/**
+ * igbvf_set_interrupt_capability - set MSI or MSI-X if supported
+ *
+ * Attempt to configure interrupts using the best available
+ * capabilities of the hardware and kernel.
+ **/
+void igbvf_set_interrupt_capability(struct igbvf_adapter *adapter)
+{
+ int err = -ENOMEM;
+ int i;
+
+ /* we allocate 3 vectors, 1 for tx, 1 for rx, one for pf messages */
+ adapter->msix_entries = kcalloc(3, sizeof(struct msix_entry),
+ GFP_KERNEL);
+ if (adapter->msix_entries) {
+ for (i = 0; i < 3; i++)
+ adapter->msix_entries[i].entry = i;
+
+ err = pci_enable_msix(adapter->pdev,
+ adapter->msix_entries, 3);
+ }
+
+ if (err) {
+ /* MSI-X failed */
+ dev_err(&adapter->pdev->dev,
+ "Failed to initialize MSI-X interrupts.\n");
+ igbvf_reset_interrupt_capability(adapter);
+ }
+}
+
+/**
+ * igbvf_request_msix - Initialize MSI-X interrupts
+ *
+ * igbvf_request_msix allocates MSI-X vectors and requests interrupts from the
+ * kernel.
+ **/
+static int igbvf_request_msix(struct igbvf_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ int err = 0, vector = 0;
+
+ if (strlen(netdev->name) < (IFNAMSIZ - 5)) {
+ sprintf(adapter->tx_ring->name, "%s-tx-0", netdev->name);
+ sprintf(adapter->rx_ring->name, "%s-rx-0", netdev->name);
+ } else {
+ memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
+ memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
+ }
+
+ err = request_irq(adapter->msix_entries[vector].vector,
+ &igbvf_intr_msix_tx, 0, adapter->tx_ring->name,
+ netdev);
+ if (err)
+ goto out;
+
+ adapter->tx_ring->itr_register = E1000_EITR(vector);
+ adapter->tx_ring->itr_val = 1952;
+ vector++;
+
+ err = request_irq(adapter->msix_entries[vector].vector,
+ &igbvf_intr_msix_rx, 0, adapter->rx_ring->name,
+ netdev);
+ if (err)
+ goto out;
+
+ adapter->rx_ring->itr_register = E1000_EITR(vector);
+ adapter->rx_ring->itr_val = 1952;
+ vector++;
+
+ err = request_irq(adapter->msix_entries[vector].vector,
+ &igbvf_msix_other, 0, netdev->name, netdev);
+ if (err)
+ goto out;
+
+ igbvf_configure_msix(adapter);
+ return 0;
+out:
+ return err;
+}
+
+/**
+ * igbvf_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ **/
+static int __devinit igbvf_alloc_queues(struct igbvf_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ adapter->tx_ring = kzalloc(sizeof(struct igbvf_ring), GFP_KERNEL);
+ if (!adapter->tx_ring)
+ return -ENOMEM;
+
+ adapter->rx_ring = kzalloc(sizeof(struct igbvf_ring), GFP_KERNEL);
+ if (!adapter->rx_ring) {
+ kfree(adapter->tx_ring);
+ return -ENOMEM;
+ }
+
+ netif_napi_add(netdev, &adapter->rx_ring->napi, igbvf_poll, 64);
+
+ return 0;
+}
+
+/**
+ * igbvf_request_irq - initialize interrupts
+ *
+ * Attempts to configure interrupts using the best available
+ * capabilities of the hardware and kernel.
+ **/
+static int igbvf_request_irq(struct igbvf_adapter *adapter)
+{
+ int err = -1;
+
+ /* igbvf supports msi-x only */
+ if (adapter->msix_entries)
+ err = igbvf_request_msix(adapter);
+
+ if (!err)
+ return err;
+
+ dev_err(&adapter->pdev->dev,
+ "Unable to allocate interrupt, Error: %d\n", err);
+
+ return err;
+}
+
+static void igbvf_free_irq(struct igbvf_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ int vector;
+
+ if (adapter->msix_entries) {
+ for (vector = 0; vector < 3; vector++)
+ free_irq(adapter->msix_entries[vector].vector, netdev);
+ }
+}
+
+/**
+ * igbvf_irq_disable - Mask off interrupt generation on the NIC
+ **/
+static void igbvf_irq_disable(struct igbvf_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+
+ ew32(EIMC, ~0);
+
+ if (adapter->msix_entries)
+ ew32(EIAC, 0);
+}
+
+/**
+ * igbvf_irq_enable - Enable default interrupt generation settings
+ **/
+static void igbvf_irq_enable(struct igbvf_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+
+ ew32(EIAC, adapter->eims_enable_mask);
+ ew32(EIAM, adapter->eims_enable_mask);
+ ew32(EIMS, adapter->eims_enable_mask);
+}
+
+/**
+ * igbvf_poll - NAPI Rx polling callback
+ * @napi: struct associated with this polling callback
+ * @budget: amount of packets driver is allowed to process this poll
+ **/
+static int igbvf_poll(struct napi_struct *napi, int budget)
+{
+ struct igbvf_ring *rx_ring = container_of(napi, struct igbvf_ring, napi);
+ struct igbvf_adapter *adapter = rx_ring->adapter;
+ struct e1000_hw *hw = &adapter->hw;
+ int work_done = 0;
+
+ igbvf_clean_rx_irq(adapter, &work_done, budget);
+
+ /* If not enough Rx work done, exit the polling mode */
+ if (work_done < budget) {
+ napi_complete(napi);
+
+ if (adapter->itr_setting & 3)
+ igbvf_set_itr(adapter);
+
+ if (!test_bit(__IGBVF_DOWN, &adapter->state))
+ ew32(EIMS, adapter->rx_ring->eims_value);
+ }
+
+ return work_done;
+}
+
+/**
+ * igbvf_set_rlpml - set receive large packet maximum length
+ * @adapter: board private structure
+ *
+ * Configure the maximum size of packets that will be received
+ */
+static void igbvf_set_rlpml(struct igbvf_adapter *adapter)
+{
+ int max_frame_size = adapter->max_frame_size;
+ struct e1000_hw *hw = &adapter->hw;
+
+ if (adapter->vlgrp)
+ max_frame_size += VLAN_TAG_SIZE;
+
+ e1000_rlpml_set_vf(hw, max_frame_size);
+}
+
+static void igbvf_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+
+ if (hw->mac.ops.set_vfta(hw, vid, true))
+ dev_err(&adapter->pdev->dev, "Failed to add vlan id %d\n", vid);
+}
+
+static void igbvf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+
+ igbvf_irq_disable(adapter);
+ vlan_group_set_device(adapter->vlgrp, vid, NULL);
+
+ if (!test_bit(__IGBVF_DOWN, &adapter->state))
+ igbvf_irq_enable(adapter);
+
+ if (hw->mac.ops.set_vfta(hw, vid, false))
+ dev_err(&adapter->pdev->dev,
+ "Failed to remove vlan id %d\n", vid);
+}
+
+static void igbvf_vlan_rx_register(struct net_device *netdev,
+ struct vlan_group *grp)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ adapter->vlgrp = grp;
+}
+
+static void igbvf_restore_vlan(struct igbvf_adapter *adapter)
+{
+ u16 vid;
+
+ if (!adapter->vlgrp)
+ return;
+
+ for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+ if (!vlan_group_get_device(adapter->vlgrp, vid))
+ continue;
+ igbvf_vlan_rx_add_vid(adapter->netdev, vid);
+ }
+
+ igbvf_set_rlpml(adapter);
+}
+
+/**
+ * igbvf_configure_tx - Configure Transmit Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx unit of the MAC after a reset.
+ **/
+static void igbvf_configure_tx(struct igbvf_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ struct igbvf_ring *tx_ring = adapter->tx_ring;
+ u64 tdba;
+ u32 txdctl, dca_txctrl;
+
+ /* disable transmits */
+ txdctl = er32(TXDCTL(0));
+ ew32(TXDCTL(0), txdctl & ~E1000_TXDCTL_QUEUE_ENABLE);
+ msleep(10);
+
+ /* Setup the HW Tx Head and Tail descriptor pointers */
+ ew32(TDLEN(0), tx_ring->count * sizeof(union e1000_adv_tx_desc));
+ tdba = tx_ring->dma;
+ ew32(TDBAL(0), (tdba & DMA_32BIT_MASK));
+ ew32(TDBAH(0), (tdba >> 32));
+ ew32(TDH(0), 0);
+ ew32(TDT(0), 0);
+ tx_ring->head = E1000_TDH(0);
+ tx_ring->tail = E1000_TDT(0);
+
+ /* Turn off Relaxed Ordering on head write-backs. The writebacks
+ * MUST be delivered in order or it will completely screw up
+ * our bookeeping.
+ */
+ dca_txctrl = er32(DCA_TXCTRL(0));
+ dca_txctrl &= ~E1000_DCA_TXCTRL_TX_WB_RO_EN;
+ ew32(DCA_TXCTRL(0), dca_txctrl);
+
+ /* enable transmits */
+ txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
+ ew32(TXDCTL(0), txdctl);
+
+ /* Setup Transmit Descriptor Settings for eop descriptor */
+ adapter->txd_cmd = E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_IFCS;
+
+ /* enable Report Status bit */
+ adapter->txd_cmd |= E1000_ADVTXD_DCMD_RS;
+
+ adapter->tx_queue_len = adapter->netdev->tx_queue_len;
+}
+
+/**
+ * igbvf_setup_srrctl - configure the receive control registers
+ * @adapter: Board private structure
+ **/
+static void igbvf_setup_srrctl(struct igbvf_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 srrctl = 0;
+
+ srrctl &= ~(E1000_SRRCTL_DESCTYPE_MASK |
+ E1000_SRRCTL_BSIZEHDR_MASK |
+ E1000_SRRCTL_BSIZEPKT_MASK);
+
+ /* Enable queue drop to avoid head of line blocking */
+ srrctl |= E1000_SRRCTL_DROP_EN;
+
+ /* Setup buffer sizes */
+ srrctl |= ALIGN(adapter->rx_buffer_len, 1024) >>
+ E1000_SRRCTL_BSIZEPKT_SHIFT;
+
+ if (adapter->rx_buffer_len < 2048) {
+ adapter->rx_ps_hdr_size = 0;
+ srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
+ } else {
+ adapter->rx_ps_hdr_size = 128;
+ srrctl |= adapter->rx_ps_hdr_size <<
+ E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
+ srrctl |= E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
+ }
+
+ ew32(SRRCTL(0), srrctl);
+}
+
+/**
+ * igbvf_configure_rx - Configure Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+static void igbvf_configure_rx(struct igbvf_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ struct igbvf_ring *rx_ring = adapter->rx_ring;
+ u64 rdba;
+ u32 rdlen, rxdctl;
+
+ /* disable receives */
+ rxdctl = er32(RXDCTL(0));
+ ew32(RXDCTL(0), rxdctl & ~E1000_RXDCTL_QUEUE_ENABLE);
+ msleep(10);
+
+ rdlen = rx_ring->count * sizeof(union e1000_adv_rx_desc);
+
+ /*
+ * Setup the HW Rx Head and Tail Descriptor Pointers and
+ * the Base and Length of the Rx Descriptor Ring
+ */
+ rdba = rx_ring->dma;
+ ew32(RDBAL(0), (rdba & DMA_32BIT_MASK));
+ ew32(RDBAH(0), (rdba >> 32));
+ ew32(RDLEN(0), rx_ring->count * sizeof(union e1000_adv_rx_desc));
+ rx_ring->head = E1000_RDH(0);
+ rx_ring->tail = E1000_RDT(0);
+ ew32(RDH(0), 0);
+ ew32(RDT(0), 0);
+
+ rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
+ rxdctl &= 0xFFF00000;
+ rxdctl |= IGBVF_RX_PTHRESH;
+ rxdctl |= IGBVF_RX_HTHRESH << 8;
+ rxdctl |= IGBVF_RX_WTHRESH << 16;
+
+ igbvf_set_rlpml(adapter);
+
+ /* enable receives */
+ ew32(RXDCTL(0), rxdctl);
+}
+
+/**
+ * igbvf_set_multi - Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_multi entry point is called whenever the multicast address
+ * list or the network interface flags are updated. This routine is
+ * responsible for configuring the hardware for proper multicast,
+ * promiscuous mode, and all-multi behavior.
+ **/
+static void igbvf_set_multi(struct net_device *netdev)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ struct dev_mc_list *mc_ptr;
+ u8 *mta_list = NULL;
+ int i;
+
+ if (netdev->mc_count) {
+ mta_list = kmalloc(netdev->mc_count * 6, GFP_ATOMIC);
+ if (!mta_list) {
+ dev_err(&adapter->pdev->dev,
+ "failed to allocate multicast filter list\n");
+ return;
+ }
+ }
+
+ /* prepare a packed array of only addresses. */
+ mc_ptr = netdev->mc_list;
+
+ for (i = 0; i < netdev->mc_count; i++) {
+ if (!mc_ptr)
+ break;
+ memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr,
+ ETH_ALEN);
+ mc_ptr = mc_ptr->next;
+ }
+
+ hw->mac.ops.update_mc_addr_list(hw, mta_list, i, 0, 0);
+ kfree(mta_list);
+}
+
+/**
+ * igbvf_configure - configure the hardware for Rx and Tx
+ * @adapter: private board structure
+ **/
+static void igbvf_configure(struct igbvf_adapter *adapter)
+{
+ igbvf_set_multi(adapter->netdev);
+
+ igbvf_restore_vlan(adapter);
+
+ igbvf_configure_tx(adapter);
+ igbvf_setup_srrctl(adapter);
+ igbvf_configure_rx(adapter);
+ igbvf_alloc_rx_buffers(adapter->rx_ring,
+ igbvf_desc_unused(adapter->rx_ring));
+}
+
+/* igbvf_reset - bring the hardware into a known good state
+ *
+ * This function boots the hardware and enables some settings that
+ * require a configuration cycle of the hardware - those cannot be
+ * set/changed during runtime. After reset the device needs to be
+ * properly configured for Rx, Tx etc.
+ */
+void igbvf_reset(struct igbvf_adapter *adapter)
+{
+ struct e1000_mac_info *mac = &adapter->hw.mac;
+ struct net_device *netdev = adapter->netdev;
+ struct e1000_hw *hw = &adapter->hw;
+
+ /* Allow time for pending master requests to run */
+ if (mac->ops.reset_hw(hw))
+ dev_err(&adapter->pdev->dev, "PF still resetting\n");
+
+ mac->ops.init_hw(hw);
+
+ if (is_valid_ether_addr(adapter->hw.mac.addr)) {
+ memcpy(netdev->dev_addr, adapter->hw.mac.addr,
+ netdev->addr_len);
+ memcpy(netdev->perm_addr, adapter->hw.mac.addr,
+ netdev->addr_len);
+ }
+}
+
+int igbvf_up(struct igbvf_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+
+ /* hardware has been reset, we need to reload some things */
+ igbvf_configure(adapter);
+
+ clear_bit(__IGBVF_DOWN, &adapter->state);
+
+ napi_enable(&adapter->rx_ring->napi);
+ if (adapter->msix_entries)
+ igbvf_configure_msix(adapter);
+
+ /* Clear any pending interrupts. */
+ er32(EICR);
+ igbvf_irq_enable(adapter);
+
+ /* start the watchdog */
+ hw->mac.get_link_status = 1;
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
+
+
+ return 0;
+}
+
+void igbvf_down(struct igbvf_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct e1000_hw *hw = &adapter->hw;
+ u32 rxdctl, txdctl;
+
+ /*
+ * signal that we're down so the interrupt handler does not
+ * reschedule our watchdog timer
+ */
+ set_bit(__IGBVF_DOWN, &adapter->state);
+
+ /* disable receives in the hardware */
+ rxdctl = er32(RXDCTL(0));
+ ew32(RXDCTL(0), rxdctl & ~E1000_RXDCTL_QUEUE_ENABLE);
+
+ netif_stop_queue(netdev);
+
+ /* disable transmits in the hardware */
+ txdctl = er32(TXDCTL(0));
+ ew32(TXDCTL(0), txdctl & ~E1000_TXDCTL_QUEUE_ENABLE);
+
+ /* flush both disables and wait for them to finish */
+ e1e_flush();
+ msleep(10);
+
+ napi_disable(&adapter->rx_ring->napi);
+
+ igbvf_irq_disable(adapter);
+
+ del_timer_sync(&adapter->watchdog_timer);
+
+ netdev->tx_queue_len = adapter->tx_queue_len;
+ netif_carrier_off(netdev);
+
+ /* record the stats before reset*/
+ igbvf_update_stats(adapter);
+
+ adapter->link_speed = 0;
+ adapter->link_duplex = 0;
+
+ igbvf_reset(adapter);
+ igbvf_clean_tx_ring(adapter->tx_ring);
+ igbvf_clean_rx_ring(adapter->rx_ring);
+}
+
+void igbvf_reinit_locked(struct igbvf_adapter *adapter)
+{
+ might_sleep();
+ while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state))
+ msleep(1);
+ igbvf_down(adapter);
+ igbvf_up(adapter);
+ clear_bit(__IGBVF_RESETTING, &adapter->state);
+}
+
+/**
+ * igbvf_sw_init - Initialize general software structures (struct igbvf_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * igbvf_sw_init initializes the Adapter private data structure.
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ **/
+static int __devinit igbvf_sw_init(struct igbvf_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ s32 rc;
+
+ adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN;
+ adapter->rx_ps_hdr_size = 0;
+ adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
+ adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
+
+ adapter->tx_int_delay = 8;
+ adapter->tx_abs_int_delay = 32;
+ adapter->rx_int_delay = 0;
+ adapter->rx_abs_int_delay = 8;
+ adapter->itr_setting = 3;
+ adapter->itr = 20000;
+
+ /* Set various function pointers */
+ adapter->ei->init_ops(&adapter->hw);
+
+ rc = adapter->hw.mac.ops.init_params(&adapter->hw);
+ if (rc)
+ return rc;
+
+ rc = adapter->hw.mbx.ops.init_params(&adapter->hw);
+ if (rc)
+ return rc;
+
+ igbvf_set_interrupt_capability(adapter);
+
+ if (igbvf_alloc_queues(adapter))
+ return -ENOMEM;
+
+ spin_lock_init(&adapter->tx_queue_lock);
+
+ /* Explicitly disable IRQ since the NIC can be in any state. */
+ igbvf_irq_disable(adapter);
+
+ spin_lock_init(&adapter->stats_lock);
+
+ set_bit(__IGBVF_DOWN, &adapter->state);
+ return 0;
+}
+
+static void igbvf_initialize_last_counter_stats(struct igbvf_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+
+ adapter->stats.last_gprc = er32(VFGPRC);
+ adapter->stats.last_gorc = er32(VFGORC);
+ adapter->stats.last_gptc = er32(VFGPTC);
+ adapter->stats.last_gotc = er32(VFGOTC);
+ adapter->stats.last_mprc = er32(VFMPRC);
+ adapter->stats.last_gotlbc = er32(VFGOTLBC);
+ adapter->stats.last_gptlbc = er32(VFGPTLBC);
+ adapter->stats.last_gorlbc = er32(VFGORLBC);
+ adapter->stats.last_gprlbc = er32(VFGPRLBC);
+
+ adapter->stats.base_gprc = er32(VFGPRC);
+ adapter->stats.base_gorc = er32(VFGORC);
+ adapter->stats.base_gptc = er32(VFGPTC);
+ adapter->stats.base_gotc = er32(VFGOTC);
+ adapter->stats.base_mprc = er32(VFMPRC);
+ adapter->stats.base_gotlbc = er32(VFGOTLBC);
+ adapter->stats.base_gptlbc = er32(VFGPTLBC);
+ adapter->stats.base_gorlbc = er32(VFGORLBC);
+ adapter->stats.base_gprlbc = er32(VFGPRLBC);
+}
+
+/**
+ * igbvf_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * The open entry point is called when a network interface is made
+ * active by the system (IFF_UP). At this point all resources needed
+ * for transmit and receive operations are allocated, the interrupt
+ * handler is registered with the OS, the watchdog timer is started,
+ * and the stack is notified that the interface is ready.
+ **/
+static int igbvf_open(struct net_device *netdev)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ int err;
+
+ /* disallow open during test */
+ if (test_bit(__IGBVF_TESTING, &adapter->state))
+ return -EBUSY;
+
+ /* allocate transmit descriptors */
+ err = igbvf_setup_tx_resources(adapter, adapter->tx_ring);
+ if (err)
+ goto err_setup_tx;
+
+ /* allocate receive descriptors */
+ err = igbvf_setup_rx_resources(adapter, adapter->rx_ring);
+ if (err)
+ goto err_setup_rx;
+
+ /*
+ * before we allocate an interrupt, we must be ready to handle it.
+ * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
+ * as soon as we call pci_request_irq, so we have to setup our
+ * clean_rx handler before we do so.
+ */
+ igbvf_configure(adapter);
+
+ err = igbvf_request_irq(adapter);
+ if (err)
+ goto err_req_irq;
+
+ /* From here on the code is the same as igbvf_up() */
+ clear_bit(__IGBVF_DOWN, &adapter->state);
+
+ napi_enable(&adapter->rx_ring->napi);
+
+ /* clear any pending interrupts */
+ er32(EICR);
+
+ igbvf_irq_enable(adapter);
+
+ /* start the watchdog */
+ hw->mac.get_link_status = 1;
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
+
+ return 0;
+
+err_req_irq:
+ igbvf_free_rx_resources(adapter->rx_ring);
+err_setup_rx:
+ igbvf_free_tx_resources(adapter->tx_ring);
+err_setup_tx:
+ igbvf_reset(adapter);
+
+ return err;
+}
+
+/**
+ * igbvf_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * The close entry point is called when an interface is de-activated
+ * by the OS. The hardware is still under the drivers control, but
+ * needs to be disabled. A global MAC reset is issued to stop the
+ * hardware, and all transmit and receive resources are freed.
+ **/
+static int igbvf_close(struct net_device *netdev)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ WARN_ON(test_bit(__IGBVF_RESETTING, &adapter->state));
+ igbvf_down(adapter);
+
+ igbvf_free_irq(adapter);
+
+ igbvf_free_tx_resources(adapter->tx_ring);
+ igbvf_free_rx_resources(adapter->rx_ring);
+
+ return 0;
+}
+/**
+ * igbvf_set_mac - Change the Ethernet Address of the NIC
+ * @netdev: network interface device structure
+ * @p: pointer to an address structure
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int igbvf_set_mac(struct net_device *netdev, void *p)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
+
+ hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
+
+ if (memcmp(addr->sa_data, hw->mac.addr, 6))
+ return -EADDRNOTAVAIL;
+
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+
+ return 0;
+}
+
+#define UPDATE_VF_COUNTER(reg, name) \
+ { \
+ u32 current_counter = er32(reg); \
+ if (current_counter < adapter->stats.last_##name) \
+ adapter->stats.name += 0x100000000LL; \
+ adapter->stats.last_##name = current_counter; \
+ adapter->stats.name &= 0xFFFFFFFF00000000LL; \
+ adapter->stats.name |= current_counter; \
+ }
+
+/**
+ * igbvf_update_stats - Update the board statistics counters
+ * @adapter: board private structure
+**/
+void igbvf_update_stats(struct igbvf_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ struct pci_dev *pdev = adapter->pdev;
+
+ /*
+ * Prevent stats update while adapter is being reset, link is down
+ * or if the pci connection is down.
+ */
+ if (adapter->link_speed == 0)
+ return;
+
+ if (test_bit(__IGBVF_RESETTING, &adapter->state))
+ return;
+
+ if (pci_channel_offline(pdev))
+ return;
+
+ UPDATE_VF_COUNTER(VFGPRC, gprc);
+ UPDATE_VF_COUNTER(VFGORC, gorc);
+ UPDATE_VF_COUNTER(VFGPTC, gptc);
+ UPDATE_VF_COUNTER(VFGOTC, gotc);
+ UPDATE_VF_COUNTER(VFMPRC, mprc);
+ UPDATE_VF_COUNTER(VFGOTLBC, gotlbc);
+ UPDATE_VF_COUNTER(VFGPTLBC, gptlbc);
+ UPDATE_VF_COUNTER(VFGORLBC, gorlbc);
+ UPDATE_VF_COUNTER(VFGPRLBC, gprlbc);
+
+ /* Fill out the OS statistics structure */
+ adapter->net_stats.multicast = adapter->stats.mprc;
+}
+
+static void igbvf_print_link_info(struct igbvf_adapter *adapter)
+{
+ dev_info(&adapter->pdev->dev, "Link is Up %d Mbps %s\n",
+ adapter->link_speed,
+ ((adapter->link_duplex == FULL_DUPLEX) ?
+ "Full Duplex" : "Half Duplex"));
+}
+
+static bool igbvf_has_link(struct igbvf_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ s32 ret_val = E1000_SUCCESS;
+ bool link_active;
+
+ ret_val = hw->mac.ops.check_for_link(hw);
+ link_active = !hw->mac.get_link_status;
+
+ /* if check for link returns error we will need to reset */
+ if (ret_val)
+ schedule_work(&adapter->reset_task);
+
+ return link_active;
+}
+
+/**
+ * igbvf_watchdog - Timer Call-back
+ * @data: pointer to adapter cast into an unsigned long
+ **/
+static void igbvf_watchdog(unsigned long data)
+{
+ struct igbvf_adapter *adapter = (struct igbvf_adapter *) data;
+
+ /* Do the rest outside of interrupt context */
+ schedule_work(&adapter->watchdog_task);
+}
+
+static void igbvf_watchdog_task(struct work_struct *work)
+{
+ struct igbvf_adapter *adapter = container_of(work,
+ struct igbvf_adapter,
+ watchdog_task);
+ struct net_device *netdev = adapter->netdev;
+ struct e1000_mac_info *mac = &adapter->hw.mac;
+ struct igbvf_ring *tx_ring = adapter->tx_ring;
+ struct e1000_hw *hw = &adapter->hw;
+ u32 link;
+ int tx_pending = 0;
+
+ link = igbvf_has_link(adapter);
+
+ if (link) {
+ if (!netif_carrier_ok(netdev)) {
+ bool txb2b = 1;
+
+ mac->ops.get_link_up_info(&adapter->hw,
+ &adapter->link_speed,
+ &adapter->link_duplex);
+ igbvf_print_link_info(adapter);
+
+ /*
+ * tweak tx_queue_len according to speed/duplex
+ * and adjust the timeout factor
+ */
+ netdev->tx_queue_len = adapter->tx_queue_len;
+ adapter->tx_timeout_factor = 1;
+ switch (adapter->link_speed) {
+ case SPEED_10:
+ txb2b = 0;
+ netdev->tx_queue_len = 10;
+ adapter->tx_timeout_factor = 16;
+ break;
+ case SPEED_100:
+ txb2b = 0;
+ netdev->tx_queue_len = 100;
+ /* maybe add some timeout factor ? */
+ break;
+ }
+
+ netif_carrier_on(netdev);
+ netif_wake_queue(netdev);
+ }
+ } else {
+ if (netif_carrier_ok(netdev)) {
+ adapter->link_speed = 0;
+ adapter->link_duplex = 0;
+ dev_info(&adapter->pdev->dev, "Link is Down\n");
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+ }
+ }
+
+ if (netif_carrier_ok(netdev)) {
+ igbvf_update_stats(adapter);
+ } else {
+ tx_pending = (igbvf_desc_unused(tx_ring) + 1 <
+ tx_ring->count);
+ if (tx_pending) {
+ /*
+ * We've lost link, so the controller stops DMA,
+ * but we've got queued Tx work that's never going
+ * to get done, so reset controller to flush Tx.
+ * (Do the reset outside of interrupt context).
+ */
+ adapter->tx_timeout_count++;
+ schedule_work(&adapter->reset_task);
+ }
+ }
+
+ /* Cause software interrupt to ensure Rx ring is cleaned */
+ ew32(EICS, adapter->rx_ring->eims_value);
+
+ /* Force detection of hung controller every watchdog period */
+ adapter->detect_tx_hung = 1;
+
+ /* Reset the timer */
+ if (!test_bit(__IGBVF_DOWN, &adapter->state))
+ mod_timer(&adapter->watchdog_timer,
+ round_jiffies(jiffies + (2 * HZ)));
+}
+
+#define IGBVF_TX_FLAGS_CSUM 0x00000001
+#define IGBVF_TX_FLAGS_VLAN 0x00000002
+#define IGBVF_TX_FLAGS_TSO 0x00000004
+#define IGBVF_TX_FLAGS_IPV4 0x00000008
+#define IGBVF_TX_FLAGS_VLAN_MASK 0xffff0000
+#define IGBVF_TX_FLAGS_VLAN_SHIFT 16
+
+static int igbvf_tso(struct igbvf_adapter *adapter,
+ struct igbvf_ring *tx_ring,
+ struct sk_buff *skb, u32 tx_flags, u8 *hdr_len)
+{
+ struct e1000_adv_tx_context_desc *context_desc;
+ unsigned int i;
+ int err;
+ struct igbvf_buffer *buffer_info;
+ u32 info = 0, tu_cmd = 0;
+ u32 mss_l4len_idx, l4len;
+ *hdr_len = 0;
+
+ if (skb_header_cloned(skb)) {
+ err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+ if (err) {
+ dev_err(&adapter->pdev->dev,
+ "igbvf_tso returning an error\n");
+ return err;
+ }
+ }
+
+ l4len = tcp_hdrlen(skb);
+ *hdr_len += l4len;
+
+ if (skb->protocol == htons(ETH_P_IP)) {
+ struct iphdr *iph = ip_hdr(skb);
+ iph->tot_len = 0;
+ iph->check = 0;
+ tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
+ iph->daddr, 0,
+ IPPROTO_TCP,
+ 0);
+ } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) {
+ ipv6_hdr(skb)->payload_len = 0;
+ tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+ &ipv6_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0);
+ }
+
+ i = tx_ring->next_to_use;
+
+ buffer_info = &tx_ring->buffer_info[i];
+ context_desc = IGBVF_TX_CTXTDESC_ADV(*tx_ring, i);
+ /* VLAN MACLEN IPLEN */
+ if (tx_flags & IGBVF_TX_FLAGS_VLAN)
+ info |= (tx_flags & IGBVF_TX_FLAGS_VLAN_MASK);
+ info |= (skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT);
+ *hdr_len += skb_network_offset(skb);
+ info |= (skb_transport_header(skb) - skb_network_header(skb));
+ *hdr_len += (skb_transport_header(skb) - skb_network_header(skb));
+ context_desc->vlan_macip_lens = cpu_to_le32(info);
+
+ /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
+ tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT);
+
+ if (skb->protocol == htons(ETH_P_IP))
+ tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
+ tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+
+ context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
+
+ /* MSS L4LEN IDX */
+ mss_l4len_idx = (skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT);
+ mss_l4len_idx |= (l4len << E1000_ADVTXD_L4LEN_SHIFT);
+
+ context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
+ context_desc->seqnum_seed = 0;
+
+ buffer_info->time_stamp = jiffies;
+ buffer_info->next_to_watch = i;
+ buffer_info->dma = 0;
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+
+ tx_ring->next_to_use = i;
+
+ return true;
+}
+
+static inline bool igbvf_tx_csum(struct igbvf_adapter *adapter,
+ struct igbvf_ring *tx_ring,
+ struct sk_buff *skb, u32 tx_flags)
+{
+ struct e1000_adv_tx_context_desc *context_desc;
+ unsigned int i;
+ struct igbvf_buffer *buffer_info;
+ u32 info = 0, tu_cmd = 0;
+
+ if ((skb->ip_summed == CHECKSUM_PARTIAL) ||
+ (tx_flags & IGBVF_TX_FLAGS_VLAN)) {
+ i = tx_ring->next_to_use;
+ buffer_info = &tx_ring->buffer_info[i];
+ context_desc = IGBVF_TX_CTXTDESC_ADV(*tx_ring, i);
+
+ if (tx_flags & IGBVF_TX_FLAGS_VLAN)
+ info |= (tx_flags & IGBVF_TX_FLAGS_VLAN_MASK);
+
+ info |= (skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT);
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ info |= (skb_transport_header(skb) -
+ skb_network_header(skb));
+
+
+ context_desc->vlan_macip_lens = cpu_to_le32(info);
+
+ tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT);
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP):
+ tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
+ if (ip_hdr(skb)->protocol == IPPROTO_TCP)
+ tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+ break;
+ case __constant_htons(ETH_P_IPV6):
+ if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
+ tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+ break;
+ default:
+ break;
+ }
+ }
+
+ context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
+ context_desc->seqnum_seed = 0;
+ context_desc->mss_l4len_idx = 0;
+
+ buffer_info->time_stamp = jiffies;
+ buffer_info->next_to_watch = i;
+ buffer_info->dma = 0;
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+ tx_ring->next_to_use = i;
+
+ return true;
+ }
+
+ return false;
+}
+
+static int igbvf_maybe_stop_tx(struct net_device *netdev, int size)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ /* there is enough descriptors then we don't need to worry */
+ if (igbvf_desc_unused(adapter->tx_ring) >= size)
+ return 0;
+
+ netif_stop_queue(netdev);
+
+ smp_mb();
+
+ /* We need to check again just in case room has been made available */
+ if (igbvf_desc_unused(adapter->tx_ring) < size)
+ return -EBUSY;
+
+ netif_wake_queue(netdev);
+
+ ++adapter->restart_queue;
+ return 0;
+}
+
+#define IGBVF_MAX_TXD_PWR 16
+#define IGBVF_MAX_DATA_PER_TXD (1 << IGBVF_MAX_TXD_PWR)
+
+static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter,
+ struct igbvf_ring *tx_ring,
+ struct sk_buff *skb,
+ unsigned int first)
+{
+ struct igbvf_buffer *buffer_info;
+ unsigned int len = skb_headlen(skb);
+ unsigned int count = 0, i;
+ unsigned int f;
+ dma_addr_t *map;
+
+ i = tx_ring->next_to_use;
+
+ if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+ return 0;
+ }
+
+ map = skb_shinfo(skb)->dma_maps;
+
+ buffer_info = &tx_ring->buffer_info[i];
+ BUG_ON(len >= IGBVF_MAX_DATA_PER_TXD);
+ buffer_info->length = len;
+ /* set time_stamp *before* dma to help avoid a possible race */
+ buffer_info->time_stamp = jiffies;
+ buffer_info->next_to_watch = i;
+ buffer_info->dma = map[count];
+ count++;
+
+ for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
+ struct skb_frag_struct *frag;
+
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+
+ frag = &skb_shinfo(skb)->frags[f];
+ len = frag->size;
+
+ buffer_info = &tx_ring->buffer_info[i];
+ BUG_ON(len >= IGBVF_MAX_DATA_PER_TXD);
+ buffer_info->length = len;
+ buffer_info->time_stamp = jiffies;
+ buffer_info->next_to_watch = i;
+ buffer_info->dma = map[count];
+ count++;
+ }
+
+ tx_ring->buffer_info[i].skb = skb;
+ tx_ring->buffer_info[first].next_to_watch = i;
+
+ return count;
+}
+
+static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter,
+ struct igbvf_ring *tx_ring,
+ int tx_flags, int count, u32 paylen,
+ u8 hdr_len)
+{
+ union e1000_adv_tx_desc *tx_desc = NULL;
+ struct igbvf_buffer *buffer_info;
+ u32 olinfo_status = 0, cmd_type_len;
+ unsigned int i;
+
+ cmd_type_len = (E1000_ADVTXD_DTYP_DATA | E1000_ADVTXD_DCMD_IFCS |
+ E1000_ADVTXD_DCMD_DEXT);
+
+ if (tx_flags & IGBVF_TX_FLAGS_VLAN)
+ cmd_type_len |= E1000_ADVTXD_DCMD_VLE;
+
+ if (tx_flags & IGBVF_TX_FLAGS_TSO) {
+ cmd_type_len |= E1000_ADVTXD_DCMD_TSE;
+
+ /* insert tcp checksum */
+ olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
+
+ /* insert ip checksum */
+ if (tx_flags & IGBVF_TX_FLAGS_IPV4)
+ olinfo_status |= E1000_TXD_POPTS_IXSM << 8;
+
+ } else if (tx_flags & IGBVF_TX_FLAGS_CSUM) {
+ olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
+ }
+
+ olinfo_status |= ((paylen - hdr_len) << E1000_ADVTXD_PAYLEN_SHIFT);
+
+ i = tx_ring->next_to_use;
+ while (count--) {
+ buffer_info = &tx_ring->buffer_info[i];
+ tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
+ tx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
+ tx_desc->read.cmd_type_len =
+ cpu_to_le32(cmd_type_len | buffer_info->length);
+ tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+ }
+
+ tx_desc->read.cmd_type_len |= cpu_to_le32(adapter->txd_cmd);
+ /* Force memory writes to complete before letting h/w
+ * know there are new descriptors to fetch. (Only
+ * applicable for weak-ordered memory model archs,
+ * such as IA-64). */
+ wmb();
+
+ tx_ring->next_to_use = i;
+ writel(i, adapter->hw.hw_addr + tx_ring->tail);
+ /* we need this if more than one processor can write to our tail
+ * at a time, it syncronizes IO on IA64/Altix systems */
+ mmiowb();
+}
+
+static int igbvf_xmit_frame_ring_adv(struct sk_buff *skb,
+ struct net_device *netdev,
+ struct igbvf_ring *tx_ring)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ unsigned int first, tx_flags = 0;
+ u8 hdr_len = 0;
+ int count = 0;
+ int tso = 0;
+
+ if (test_bit(__IGBVF_DOWN, &adapter->state)) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ if (skb->len <= 0) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ /*
+ * need: count + 4 desc gap to keep tail from touching
+ * + 2 desc gap to keep tail from touching head,
+ * + 1 desc for skb->data,
+ * + 1 desc for context descriptor,
+ * head, otherwise try next time
+ */
+ if (igbvf_maybe_stop_tx(netdev, skb_shinfo(skb)->nr_frags + 4)) {
+ /* this is a hard error */
+ return NETDEV_TX_BUSY;
+ }
+
+ if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+ tx_flags |= IGBVF_TX_FLAGS_VLAN;
+ tx_flags |= (vlan_tx_tag_get(skb) << IGBVF_TX_FLAGS_VLAN_SHIFT);
+ }
+
+ if (skb->protocol == htons(ETH_P_IP))
+ tx_flags |= IGBVF_TX_FLAGS_IPV4;
+
+ first = tx_ring->next_to_use;
+
+ tso = skb_is_gso(skb) ?
+ igbvf_tso(adapter, tx_ring, skb, tx_flags, &hdr_len) : 0;
+ if (unlikely(tso < 0)) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ if (tso)
+ tx_flags |= IGBVF_TX_FLAGS_TSO;
+ else if (igbvf_tx_csum(adapter, tx_ring, skb, tx_flags) &&
+ (skb->ip_summed == CHECKSUM_PARTIAL))
+ tx_flags |= IGBVF_TX_FLAGS_CSUM;
+
+ /*
+ * count reflects descriptors mapped, if 0 then mapping error
+ * has occured and we need to rewind the descriptor queue
+ */
+ count = igbvf_tx_map_adv(adapter, tx_ring, skb, first);
+
+ if (count) {
+ igbvf_tx_queue_adv(adapter, tx_ring, tx_flags, count,
+ skb->len, hdr_len);
+ netdev->trans_start = jiffies;
+ /* Make sure there is space in the ring for the next send. */
+ igbvf_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 4);
+ } else {
+ dev_kfree_skb_any(skb);
+ tx_ring->buffer_info[first].time_stamp = 0;
+ tx_ring->next_to_use = first;
+ }
+
+ return NETDEV_TX_OK;
+}
+
+static int igbvf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct igbvf_ring *tx_ring;
+ int retval;
+
+ if (test_bit(__IGBVF_DOWN, &adapter->state)) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ tx_ring = &adapter->tx_ring[0];
+
+ retval = igbvf_xmit_frame_ring_adv(skb, netdev, tx_ring);
+
+ return retval;
+}
+
+/**
+ * igbvf_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ **/
+static void igbvf_tx_timeout(struct net_device *netdev)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ /* Do the reset outside of interrupt context */
+ adapter->tx_timeout_count++;
+ schedule_work(&adapter->reset_task);
+}
+
+static void igbvf_reset_task(struct work_struct *work)
+{
+ struct igbvf_adapter *adapter;
+ adapter = container_of(work, struct igbvf_adapter, reset_task);
+
+ igbvf_reinit_locked(adapter);
+}
+
+/**
+ * igbvf_get_stats - Get System Network Statistics
+ * @netdev: network interface device structure
+ *
+ * Returns the address of the device statistics structure.
+ * The statistics are actually updated from the timer callback.
+ **/
+static struct net_device_stats *igbvf_get_stats(struct net_device *netdev)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ /* only return the current stats */
+ return &adapter->net_stats;
+}
+
+/**
+ * igbvf_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int igbvf_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
+
+ if ((new_mtu < 68) || (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+ dev_err(&adapter->pdev->dev, "Invalid MTU setting\n");
+ return -EINVAL;
+ }
+
+ /* Jumbo frame size limits */
+ if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
+ if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
+ dev_err(&adapter->pdev->dev,
+ "Jumbo Frames not supported.\n");
+ return -EINVAL;
+ }
+ }
+
+#define MAX_STD_JUMBO_FRAME_SIZE 9234
+ if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
+ dev_err(&adapter->pdev->dev, "MTU > 9216 not supported.\n");
+ return -EINVAL;
+ }
+
+ while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state))
+ msleep(1);
+ /* igbvf_down has a dependency on max_frame_size */
+ adapter->max_frame_size = max_frame;
+ if (netif_running(netdev))
+ igbvf_down(adapter);
+
+ /*
+ * NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
+ * means we reserve 2 more, this pushes us to allocate from the next
+ * larger slab size.
+ * i.e. RXBUFFER_2048 --> size-4096 slab
+ * However with the new *_jumbo_rx* routines, jumbo receives will use
+ * fragmented skbs
+ */
+
+ if (max_frame <= 1024)
+ adapter->rx_buffer_len = 1024;
+ else if (max_frame <= 2048)
+ adapter->rx_buffer_len = 2048;
+ else
+#if (PAGE_SIZE / 2) > 16384
+ adapter->rx_buffer_len = 16384;
+#else
+ adapter->rx_buffer_len = PAGE_SIZE / 2;
+#endif
+
+
+ /* adjust allocation if LPE protects us, and we aren't using SBP */
+ if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
+ (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN))
+ adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN +
+ ETH_FCS_LEN;
+
+ dev_info(&adapter->pdev->dev, "changing MTU from %d to %d\n",
+ netdev->mtu, new_mtu);
+ netdev->mtu = new_mtu;
+
+ if (netif_running(netdev))
+ igbvf_up(adapter);
+ else
+ igbvf_reset(adapter);
+
+ clear_bit(__IGBVF_RESETTING, &adapter->state);
+
+ return 0;
+}
+
+static int igbvf_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+ switch (cmd) {
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int igbvf_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+#ifdef CONFIG_PM
+ int retval = 0;
+#endif
+
+ netif_device_detach(netdev);
+
+ if (netif_running(netdev)) {
+ WARN_ON(test_bit(__IGBVF_RESETTING, &adapter->state));
+ igbvf_down(adapter);
+ igbvf_free_irq(adapter);
+ }
+
+#ifdef CONFIG_PM
+ retval = pci_save_state(pdev);
+ if (retval)
+ return retval;
+#endif
+
+ pci_disable_device(pdev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int igbvf_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ u32 err;
+
+ pci_restore_state(pdev);
+ err = pci_enable_device_mem(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n");
+ return err;
+ }
+
+ pci_set_master(pdev);
+
+ if (netif_running(netdev)) {
+ err = igbvf_request_irq(adapter);
+ if (err)
+ return err;
+ }
+
+ igbvf_reset(adapter);
+
+ if (netif_running(netdev))
+ igbvf_up(adapter);
+
+ netif_device_attach(netdev);
+
+ return 0;
+}
+#endif
+
+static void igbvf_shutdown(struct pci_dev *pdev)
+{
+ igbvf_suspend(pdev, PMSG_SUSPEND);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void igbvf_netpoll(struct net_device *netdev)
+{
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ disable_irq(adapter->pdev->irq);
+
+ igbvf_clean_tx_irq(adapter->tx_ring);
+
+ enable_irq(adapter->pdev->irq);
+}
+#endif
+
+/**
+ * igbvf_io_error_detected - called when PCI error is 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.
+ */
+static pci_ers_result_t igbvf_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ netif_device_detach(netdev);
+
+ if (netif_running(netdev))
+ igbvf_down(adapter);
+ pci_disable_device(pdev);
+
+ /* Request a slot slot reset. */
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * igbvf_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot. Implementation
+ * resembles the first-half of the igbvf_resume routine.
+ */
+static pci_ers_result_t igbvf_io_slot_reset(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ if (pci_enable_device_mem(pdev)) {
+ dev_err(&pdev->dev,
+ "Cannot re-enable PCI device after reset.\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+ pci_set_master(pdev);
+
+ igbvf_reset(adapter);
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * igbvf_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation. Implementation resembles the
+ * second-half of the igbvf_resume routine.
+ */
+static void igbvf_io_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+ if (netif_running(netdev)) {
+ if (igbvf_up(adapter)) {
+ dev_err(&pdev->dev,
+ "can't bring device back up after reset\n");
+ return;
+ }
+ }
+
+ netif_device_attach(netdev);
+}
+
+static void igbvf_print_device_info(struct igbvf_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+
+ dev_info(&pdev->dev, "Intel(R) 82576 Virtual Function\n");
+ dev_info(&pdev->dev, "Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ /* MAC address */
+ netdev->dev_addr[0], netdev->dev_addr[1],
+ netdev->dev_addr[2], netdev->dev_addr[3],
+ netdev->dev_addr[4], netdev->dev_addr[5]);
+ dev_info(&pdev->dev, "MAC: %d\n", hw->mac.type);
+}
+
+static const struct net_device_ops igbvf_netdev_ops = {
+ .ndo_open = igbvf_open,
+ .ndo_stop = igbvf_close,
+ .ndo_start_xmit = igbvf_xmit_frame,
+ .ndo_get_stats = igbvf_get_stats,
+ .ndo_set_multicast_list = igbvf_set_multi,
+ .ndo_set_mac_address = igbvf_set_mac,
+ .ndo_change_mtu = igbvf_change_mtu,
+ .ndo_do_ioctl = igbvf_ioctl,
+ .ndo_tx_timeout = igbvf_tx_timeout,
+ .ndo_vlan_rx_register = igbvf_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = igbvf_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = igbvf_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = igbvf_netpoll,
+#endif
+};
+
+/**
+ * igbvf_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in igbvf_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * igbvf_probe initializes an adapter identified by a pci_dev structure.
+ * The OS initialization, configuring of the adapter private structure,
+ * and a hardware reset occur.
+ **/
+static int __devinit igbvf_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct net_device *netdev;
+ struct igbvf_adapter *adapter;
+ struct e1000_hw *hw;
+ const struct igbvf_info *ei = igbvf_info_tbl[ent->driver_data];
+
+ static int cards_found;
+ int err, pci_using_dac;
+
+ err = pci_enable_device_mem(pdev);
+ if (err)
+ return err;
+
+ pci_using_dac = 0;
+ err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ if (!err) {
+ err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ if (!err)
+ pci_using_dac = 1;
+ } else {
+ err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (err) {
+ err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (err) {
+ dev_err(&pdev->dev, "No usable DMA "
+ "configuration, aborting\n");
+ goto err_dma;
+ }
+ }
+ }
+
+ err = pci_request_regions(pdev, igbvf_driver_name);
+ if (err)
+ goto err_pci_reg;
+
+ pci_set_master(pdev);
+
+ err = -ENOMEM;
+ netdev = alloc_etherdev(sizeof(struct igbvf_adapter));
+ if (!netdev)
+ goto err_alloc_etherdev;
+
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+
+ pci_set_drvdata(pdev, netdev);
+ adapter = netdev_priv(netdev);
+ hw = &adapter->hw;
+ adapter->netdev = netdev;
+ adapter->pdev = pdev;
+ adapter->ei = ei;
+ adapter->pba = ei->pba;
+ adapter->flags = ei->flags;
+ adapter->hw.back = adapter;
+ adapter->hw.mac.type = ei->mac;
+ adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
+
+ /* PCI config space info */
+
+ hw->vendor_id = pdev->vendor;
+ hw->device_id = pdev->device;
+ hw->subsystem_vendor_id = pdev->subsystem_vendor;
+ hw->subsystem_device_id = pdev->subsystem_device;
+
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
+
+ err = -EIO;
+ adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+
+ if (!adapter->hw.hw_addr)
+ goto err_ioremap;
+
+ if (ei->get_variants) {
+ err = ei->get_variants(adapter);
+ if (err)
+ goto err_ioremap;
+ }
+
+ /* setup adapter struct */
+ err = igbvf_sw_init(adapter);
+ if (err)
+ goto err_sw_init;
+
+ /* construct the net_device struct */
+ netdev->netdev_ops = &igbvf_netdev_ops;
+
+ igbvf_set_ethtool_ops(netdev);
+ netdev->watchdog_timeo = 5 * HZ;
+ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
+
+ adapter->bd_number = cards_found++;
+
+ netdev->features = NETIF_F_SG |
+ NETIF_F_IP_CSUM |
+ NETIF_F_HW_VLAN_TX |
+ NETIF_F_HW_VLAN_RX |
+ NETIF_F_HW_VLAN_FILTER;
+
+ netdev->features |= NETIF_F_IPV6_CSUM;
+ netdev->features |= NETIF_F_TSO;
+ netdev->features |= NETIF_F_TSO6;
+
+ if (pci_using_dac)
+ netdev->features |= NETIF_F_HIGHDMA;
+
+ netdev->vlan_features |= NETIF_F_TSO;
+ netdev->vlan_features |= NETIF_F_TSO6;
+ netdev->vlan_features |= NETIF_F_IP_CSUM;
+ netdev->vlan_features |= NETIF_F_IPV6_CSUM;
+ netdev->vlan_features |= NETIF_F_SG;
+
+ /*reset the controller to put the device in a known good state */
+ err = hw->mac.ops.reset_hw(hw);
+ if (err) {
+ dev_info(&pdev->dev,
+ "PF still in reset state, assigning new address\n");
+ random_ether_addr(hw->mac.addr);
+ } else {
+ err = hw->mac.ops.read_mac_addr(hw);
+ if (err) {
+ dev_err(&pdev->dev, "Error reading MAC address\n");
+ goto err_hw_init;
+ }
+ }
+
+ memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
+ memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
+
+ if (!is_valid_ether_addr(netdev->perm_addr)) {
+ dev_err(&pdev->dev, "Invalid MAC Address: "
+ "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ netdev->dev_addr[0], netdev->dev_addr[1],
+ netdev->dev_addr[2], netdev->dev_addr[3],
+ netdev->dev_addr[4], netdev->dev_addr[5]);
+ err = -EIO;
+ goto err_hw_init;
+ }
+
+ setup_timer(&adapter->watchdog_timer, &igbvf_watchdog,
+ (unsigned long) adapter);
+
+ INIT_WORK(&adapter->reset_task, igbvf_reset_task);
+ INIT_WORK(&adapter->watchdog_task, igbvf_watchdog_task);
+
+ /* ring size defaults */
+ adapter->rx_ring->count = 1024;
+ adapter->tx_ring->count = 1024;
+
+ /* reset the hardware with the new settings */
+ igbvf_reset(adapter);
+
+ /* tell the stack to leave us alone until igbvf_open() is called */
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+
+ strcpy(netdev->name, "eth%d");
+ err = register_netdev(netdev);
+ if (err)
+ goto err_hw_init;
+
+ igbvf_print_device_info(adapter);
+
+ igbvf_initialize_last_counter_stats(adapter);
+
+ return 0;
+
+err_hw_init:
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+err_sw_init:
+ igbvf_reset_interrupt_capability(adapter);
+ iounmap(adapter->hw.hw_addr);
+err_ioremap:
+ free_netdev(netdev);
+err_alloc_etherdev:
+ pci_release_regions(pdev);
+err_pci_reg:
+err_dma:
+ pci_disable_device(pdev);
+ return err;
+}
+
+/**
+ * igbvf_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * igbvf_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device. The could be caused by a
+ * Hot-Plug event, or because the driver is going to be removed from
+ * memory.
+ **/
+static void __devexit igbvf_remove(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct igbvf_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+
+ /*
+ * flush_scheduled work may reschedule our watchdog task, so
+ * explicitly disable watchdog tasks from being rescheduled
+ */
+ set_bit(__IGBVF_DOWN, &adapter->state);
+ del_timer_sync(&adapter->watchdog_timer);
+
+ flush_scheduled_work();
+
+ unregister_netdev(netdev);
+
+ igbvf_reset_interrupt_capability(adapter);
+
+ /*
+ * it is important to delete the napi struct prior to freeing the
+ * rx ring so that you do not end up with null pointer refs
+ */
+ netif_napi_del(&adapter->rx_ring->napi);
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+
+ iounmap(hw->hw_addr);
+ if (hw->flash_address)
+ iounmap(hw->flash_address);
+ pci_release_regions(pdev);
+
+ free_netdev(netdev);
+
+ pci_disable_device(pdev);
+}
+
+/* PCI Error Recovery (ERS) */
+static struct pci_error_handlers igbvf_err_handler = {
+ .error_detected = igbvf_io_error_detected,
+ .slot_reset = igbvf_io_slot_reset,
+ .resume = igbvf_io_resume,
+};
+
+static struct pci_device_id igbvf_pci_tbl[] = {
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_VF), board_vf },
+ { } /* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, igbvf_pci_tbl);
+
+/* PCI Device API Driver */
+static struct pci_driver igbvf_driver = {
+ .name = igbvf_driver_name,
+ .id_table = igbvf_pci_tbl,
+ .probe = igbvf_probe,
+ .remove = __devexit_p(igbvf_remove),
+#ifdef CONFIG_PM
+ /* Power Management Hooks */
+ .suspend = igbvf_suspend,
+ .resume = igbvf_resume,
+#endif
+ .shutdown = igbvf_shutdown,
+ .err_handler = &igbvf_err_handler
+};
+
+/**
+ * igbvf_init_module - Driver Registration Routine
+ *
+ * igbvf_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ **/
+static int __init igbvf_init_module(void)
+{
+ int ret;
+ printk(KERN_INFO "%s - version %s\n",
+ igbvf_driver_string, igbvf_driver_version);
+ printk(KERN_INFO "%s\n", igbvf_copyright);
+
+ ret = pci_register_driver(&igbvf_driver);
+ pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name,
+ PM_QOS_DEFAULT_VALUE);
+
+ return ret;
+}
+module_init(igbvf_init_module);
+
+/**
+ * igbvf_exit_module - Driver Exit Cleanup Routine
+ *
+ * igbvf_exit_module is called just before the driver is removed
+ * from memory.
+ **/
+static void __exit igbvf_exit_module(void)
+{
+ pci_unregister_driver(&igbvf_driver);
+ pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name);
+}
+module_exit(igbvf_exit_module);
+
+
+MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
+MODULE_DESCRIPTION("Intel(R) 82576 Virtual Function Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+/* netdev.c */
diff --git a/drivers/net/igbvf/regs.h b/drivers/net/igbvf/regs.h
new file mode 100644
index 00000000000..b9e24ed70d0
--- /dev/null
+++ b/drivers/net/igbvf/regs.h
@@ -0,0 +1,108 @@
+/*******************************************************************************
+
+ Intel(R) 82576 Virtual Function Linux driver
+ Copyright(c) 2009 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_REGS_H_
+#define _E1000_REGS_H_
+
+#define E1000_CTRL 0x00000 /* Device Control - RW */
+#define E1000_STATUS 0x00008 /* Device Status - RO */
+#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
+#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */
+#define E1000_EITR(_n) (0x01680 + (0x4 * (_n)))
+#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */
+#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */
+#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
+#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
+#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
+#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation (array) - RW */
+#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
+/*
+ * Convenience macros
+ *
+ * Note: "_n" is the queue number of the register to be written to.
+ *
+ * Example usage:
+ * E1000_RDBAL_REG(current_rx_queue)
+ */
+#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : \
+ (0x0C000 + ((_n) * 0x40)))
+#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : \
+ (0x0C004 + ((_n) * 0x40)))
+#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : \
+ (0x0C008 + ((_n) * 0x40)))
+#define E1000_SRRCTL(_n) ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : \
+ (0x0C00C + ((_n) * 0x40)))
+#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : \
+ (0x0C010 + ((_n) * 0x40)))
+#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : \
+ (0x0C018 + ((_n) * 0x40)))
+#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : \
+ (0x0C028 + ((_n) * 0x40)))
+#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : \
+ (0x0E000 + ((_n) * 0x40)))
+#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : \
+ (0x0E004 + ((_n) * 0x40)))
+#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : \
+ (0x0E008 + ((_n) * 0x40)))
+#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : \
+ (0x0E010 + ((_n) * 0x40)))
+#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : \
+ (0x0E018 + ((_n) * 0x40)))
+#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : \
+ (0x0E028 + ((_n) * 0x40)))
+#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8))
+#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
+#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
+ (0x054E0 + ((_i - 16) * 8)))
+#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
+ (0x054E4 + ((_i - 16) * 8)))
+
+/* Statistics registers */
+#define E1000_VFGPRC 0x00F10
+#define E1000_VFGORC 0x00F18
+#define E1000_VFMPRC 0x00F3C
+#define E1000_VFGPTC 0x00F14
+#define E1000_VFGOTC 0x00F34
+#define E1000_VFGOTLBC 0x00F50
+#define E1000_VFGPTLBC 0x00F44
+#define E1000_VFGORLBC 0x00F48
+#define E1000_VFGPRLBC 0x00F40
+
+/* These act per VF so an array friendly macro is used */
+#define E1000_V2PMAILBOX(_n) (0x00C40 + (4 * (_n)))
+#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
+
+/* Define macros for handling registers */
+#define er32(reg) readl(hw->hw_addr + E1000_##reg)
+#define ew32(reg, val) writel((val), hw->hw_addr + E1000_##reg)
+#define array_er32(reg, offset) \
+ readl(hw->hw_addr + E1000_##reg + (offset << 2))
+#define array_ew32(reg, offset, val) \
+ writel((val), hw->hw_addr + E1000_##reg + (offset << 2))
+#define e1e_flush() er32(STATUS)
+
+#endif
diff --git a/drivers/net/igbvf/vf.c b/drivers/net/igbvf/vf.c
new file mode 100644
index 00000000000..aa246c93279
--- /dev/null
+++ b/drivers/net/igbvf/vf.c
@@ -0,0 +1,398 @@
+/*******************************************************************************
+
+ Intel(R) 82576 Virtual Function Linux driver
+ Copyright(c) 2009 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+
+#include "vf.h"
+
+static s32 e1000_check_for_link_vf(struct e1000_hw *hw);
+static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
+ u16 *duplex);
+static s32 e1000_init_hw_vf(struct e1000_hw *hw);
+static s32 e1000_reset_hw_vf(struct e1000_hw *hw);
+
+static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *,
+ u32, u32, u32);
+static void e1000_rar_set_vf(struct e1000_hw *, u8 *, u32);
+static s32 e1000_read_mac_addr_vf(struct e1000_hw *);
+static s32 e1000_set_vfta_vf(struct e1000_hw *, u16, bool);
+
+/**
+ * e1000_init_mac_params_vf - Inits MAC params
+ * @hw: pointer to the HW structure
+ **/
+s32 e1000_init_mac_params_vf(struct e1000_hw *hw)
+{
+ struct e1000_mac_info *mac = &hw->mac;
+
+ /* VF's have no MTA Registers - PF feature only */
+ mac->mta_reg_count = 128;
+ /* VF's have no access to RAR entries */
+ mac->rar_entry_count = 1;
+
+ /* Function pointers */
+ /* reset */
+ mac->ops.reset_hw = e1000_reset_hw_vf;
+ /* hw initialization */
+ mac->ops.init_hw = e1000_init_hw_vf;
+ /* check for link */
+ mac->ops.check_for_link = e1000_check_for_link_vf;
+ /* link info */
+ mac->ops.get_link_up_info = e1000_get_link_up_info_vf;
+ /* multicast address update */
+ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_vf;
+ /* set mac address */
+ mac->ops.rar_set = e1000_rar_set_vf;
+ /* read mac address */
+ mac->ops.read_mac_addr = e1000_read_mac_addr_vf;
+ /* set vlan filter table array */
+ mac->ops.set_vfta = e1000_set_vfta_vf;
+
+ return E1000_SUCCESS;
+}
+
+/**
+ * e1000_init_function_pointers_vf - Inits function pointers
+ * @hw: pointer to the HW structure
+ **/
+void e1000_init_function_pointers_vf(struct e1000_hw *hw)
+{
+ hw->mac.ops.init_params = e1000_init_mac_params_vf;
+ hw->mbx.ops.init_params = e1000_init_mbx_params_vf;
+}
+
+/**
+ * e1000_get_link_up_info_vf - Gets link info.
+ * @hw: pointer to the HW structure
+ * @speed: pointer to 16 bit value to store link speed.
+ * @duplex: pointer to 16 bit value to store duplex.
+ *
+ * Since we cannot read the PHY and get accurate link info, we must rely upon
+ * the status register's data which is often stale and inaccurate.
+ **/
+static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
+ u16 *duplex)
+{
+ s32 status;
+
+ status = er32(STATUS);
+ if (status & E1000_STATUS_SPEED_1000)
+ *speed = SPEED_1000;
+ else if (status & E1000_STATUS_SPEED_100)
+ *speed = SPEED_100;
+ else
+ *speed = SPEED_10;
+
+ if (status & E1000_STATUS_FD)
+ *duplex = FULL_DUPLEX;
+ else
+ *duplex = HALF_DUPLEX;
+
+ return E1000_SUCCESS;
+}
+
+/**
+ * e1000_reset_hw_vf - Resets the HW
+ * @hw: pointer to the HW structure
+ *
+ * VF's provide a function level reset. This is done using bit 26 of ctrl_reg.
+ * This is all the reset we can perform on a VF.
+ **/
+static s32 e1000_reset_hw_vf(struct e1000_hw *hw)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ u32 timeout = E1000_VF_INIT_TIMEOUT;
+ u32 ret_val = -E1000_ERR_MAC_INIT;
+ u32 msgbuf[3];
+ u8 *addr = (u8 *)(&msgbuf[1]);
+ u32 ctrl;
+
+ /* assert vf queue/interrupt reset */
+ ctrl = er32(CTRL);
+ ew32(CTRL, ctrl | E1000_CTRL_RST);
+
+ /* we cannot initialize while the RSTI / RSTD bits are asserted */
+ while (!mbx->ops.check_for_rst(hw) && timeout) {
+ timeout--;
+ udelay(5);
+ }
+
+ if (timeout) {
+ /* mailbox timeout can now become active */
+ mbx->timeout = E1000_VF_MBX_INIT_TIMEOUT;
+
+ /* notify pf of vf reset completion */
+ msgbuf[0] = E1000_VF_RESET;
+ mbx->ops.write_posted(hw, msgbuf, 1);
+
+ msleep(10);
+
+ /* set our "perm_addr" based on info provided by PF */
+ ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
+ if (!ret_val) {
+ if (msgbuf[0] == (E1000_VF_RESET | E1000_VT_MSGTYPE_ACK))
+ memcpy(hw->mac.perm_addr, addr, 6);
+ else
+ ret_val = -E1000_ERR_MAC_INIT;
+ }
+ }
+
+ return ret_val;
+}
+
+/**
+ * e1000_init_hw_vf - Inits the HW
+ * @hw: pointer to the HW structure
+ *
+ * Not much to do here except clear the PF Reset indication if there is one.
+ **/
+static s32 e1000_init_hw_vf(struct e1000_hw *hw)
+{
+ /* attempt to set and restore our mac address */
+ e1000_rar_set_vf(hw, hw->mac.addr, 0);
+
+ return E1000_SUCCESS;
+}
+
+/**
+ * e1000_hash_mc_addr_vf - Generate a multicast hash value
+ * @hw: pointer to the HW structure
+ * @mc_addr: pointer to a multicast address
+ *
+ * Generates a multicast address hash value which is used to determine
+ * the multicast filter table array address and new table value. See
+ * e1000_mta_set_generic()
+ **/
+static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr)
+{
+ u32 hash_value, hash_mask;
+ u8 bit_shift = 0;
+
+ /* Register count multiplied by bits per register */
+ hash_mask = (hw->mac.mta_reg_count * 32) - 1;
+
+ /*
+ * The bit_shift is the number of left-shifts
+ * where 0xFF would still fall within the hash mask.
+ */
+ while (hash_mask >> bit_shift != 0xFF)
+ bit_shift++;
+
+ hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
+ (((u16) mc_addr[5]) << bit_shift)));
+
+ return hash_value;
+}
+
+/**
+ * e1000_update_mc_addr_list_vf - Update Multicast addresses
+ * @hw: pointer to the HW structure
+ * @mc_addr_list: array of multicast addresses to program
+ * @mc_addr_count: number of multicast addresses to program
+ * @rar_used_count: the first RAR register free to program
+ * @rar_count: total number of supported Receive Address Registers
+ *
+ * Updates the Receive Address Registers and Multicast Table Array.
+ * The caller must have a packed mc_addr_list of multicast addresses.
+ * The parameter rar_count will usually be hw->mac.rar_entry_count
+ * unless there are workarounds that change this.
+ **/
+void e1000_update_mc_addr_list_vf(struct e1000_hw *hw,
+ u8 *mc_addr_list, u32 mc_addr_count,
+ u32 rar_used_count, u32 rar_count)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ u32 msgbuf[E1000_VFMAILBOX_SIZE];
+ u16 *hash_list = (u16 *)&msgbuf[1];
+ u32 hash_value;
+ u32 cnt, i;
+
+ /* Each entry in the list uses 1 16 bit word. We have 30
+ * 16 bit words available in our HW msg buffer (minus 1 for the
+ * msg type). That's 30 hash values if we pack 'em right. If
+ * there are more than 30 MC addresses to add then punt the
+ * extras for now and then add code to handle more than 30 later.
+ * It would be unusual for a server to request that many multi-cast
+ * addresses except for in large enterprise network environments.
+ */
+
+ cnt = (mc_addr_count > 30) ? 30 : mc_addr_count;
+ msgbuf[0] = E1000_VF_SET_MULTICAST;
+ msgbuf[0] |= cnt << E1000_VT_MSGINFO_SHIFT;
+
+ for (i = 0; i < cnt; i++) {
+ hash_value = e1000_hash_mc_addr_vf(hw, mc_addr_list);
+ hash_list[i] = hash_value & 0x0FFFF;
+ mc_addr_list += ETH_ADDR_LEN;
+ }
+
+ mbx->ops.write_posted(hw, msgbuf, E1000_VFMAILBOX_SIZE);
+}
+
+/**
+ * e1000_set_vfta_vf - Set/Unset vlan filter table address
+ * @hw: pointer to the HW structure
+ * @vid: determines the vfta register and bit to set/unset
+ * @set: if true then set bit, else clear bit
+ **/
+static s32 e1000_set_vfta_vf(struct e1000_hw *hw, u16 vid, bool set)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ u32 msgbuf[2];
+ s32 err;
+
+ msgbuf[0] = E1000_VF_SET_VLAN;
+ msgbuf[1] = vid;
+ /* Setting the 8 bit field MSG INFO to true indicates "add" */
+ if (set)
+ msgbuf[0] |= 1 << E1000_VT_MSGINFO_SHIFT;
+
+ mbx->ops.write_posted(hw, msgbuf, 2);
+
+ err = mbx->ops.read_posted(hw, msgbuf, 2);
+
+ /* if nacked the vlan was rejected */
+ if (!err && (msgbuf[0] == (E1000_VF_SET_VLAN | E1000_VT_MSGTYPE_NACK)))
+ err = -E1000_ERR_MAC_INIT;
+
+ return err;
+}
+
+/** e1000_rlpml_set_vf - Set the maximum receive packet length
+ * @hw: pointer to the HW structure
+ * @max_size: value to assign to max frame size
+ **/
+void e1000_rlpml_set_vf(struct e1000_hw *hw, u16 max_size)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ u32 msgbuf[2];
+
+ msgbuf[0] = E1000_VF_SET_LPE;
+ msgbuf[1] = max_size;
+
+ mbx->ops.write_posted(hw, msgbuf, 2);
+}
+
+/**
+ * e1000_rar_set_vf - set device MAC address
+ * @hw: pointer to the HW structure
+ * @addr: pointer to the receive address
+ * @index receive address array register
+ **/
+static void e1000_rar_set_vf(struct e1000_hw *hw, u8 * addr, u32 index)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ u32 msgbuf[3];
+ u8 *msg_addr = (u8 *)(&msgbuf[1]);
+ s32 ret_val;
+
+ memset(msgbuf, 0, 12);
+ msgbuf[0] = E1000_VF_SET_MAC_ADDR;
+ memcpy(msg_addr, addr, 6);
+ ret_val = mbx->ops.write_posted(hw, msgbuf, 3);
+
+ if (!ret_val)
+ ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
+
+ /* if nacked the address was rejected, use "perm_addr" */
+ if (!ret_val &&
+ (msgbuf[0] == (E1000_VF_SET_MAC_ADDR | E1000_VT_MSGTYPE_NACK)))
+ e1000_read_mac_addr_vf(hw);
+}
+
+/**
+ * e1000_read_mac_addr_vf - Read device MAC address
+ * @hw: pointer to the HW structure
+ **/
+static s32 e1000_read_mac_addr_vf(struct e1000_hw *hw)
+{
+ int i;
+
+ for (i = 0; i < ETH_ADDR_LEN; i++)
+ hw->mac.addr[i] = hw->mac.perm_addr[i];
+
+ return E1000_SUCCESS;
+}
+
+/**
+ * e1000_check_for_link_vf - Check for link for a virtual interface
+ * @hw: pointer to the HW structure
+ *
+ * Checks to see if the underlying PF is still talking to the VF and
+ * if it is then it reports the link state to the hardware, otherwise
+ * it reports link down and returns an error.
+ **/
+static s32 e1000_check_for_link_vf(struct e1000_hw *hw)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ struct e1000_mac_info *mac = &hw->mac;
+ s32 ret_val = E1000_SUCCESS;
+ u32 in_msg = 0;
+
+ /*
+ * We only want to run this if there has been a rst asserted.
+ * in this case that could mean a link change, device reset,
+ * or a virtual function reset
+ */
+
+ /* If we were hit with a reset drop the link */
+ if (!mbx->ops.check_for_rst(hw))
+ mac->get_link_status = true;
+
+ if (!mac->get_link_status)
+ goto out;
+
+ /* if link status is down no point in checking to see if pf is up */
+ if (!(er32(STATUS) & E1000_STATUS_LU))
+ goto out;
+
+ /* if the read failed it could just be a mailbox collision, best wait
+ * until we are called again and don't report an error */
+ if (mbx->ops.read(hw, &in_msg, 1))
+ goto out;
+
+ /* if incoming message isn't clear to send we are waiting on response */
+ if (!(in_msg & E1000_VT_MSGTYPE_CTS)) {
+ /* message is not CTS and is NACK we must have lost CTS status */
+ if (in_msg & E1000_VT_MSGTYPE_NACK)
+ ret_val = -E1000_ERR_MAC_INIT;
+ goto out;
+ }
+
+ /* the pf is talking, if we timed out in the past we reinit */
+ if (!mbx->timeout) {
+ ret_val = -E1000_ERR_MAC_INIT;
+ goto out;
+ }
+
+ /* if we passed all the tests above then the link is up and we no
+ * longer need to check for link */
+ mac->get_link_status = false;
+
+out:
+ return ret_val;
+}
+
diff --git a/drivers/net/igbvf/vf.h b/drivers/net/igbvf/vf.h
new file mode 100644
index 00000000000..ec07228f947
--- /dev/null
+++ b/drivers/net/igbvf/vf.h
@@ -0,0 +1,265 @@
+/*******************************************************************************
+
+ Intel(R) 82576 Virtual Function Linux driver
+ Copyright(c) 2009 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.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_VF_H_
+#define _E1000_VF_H_
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+
+#include "regs.h"
+#include "defines.h"
+
+struct e1000_hw;
+
+#define E1000_DEV_ID_82576_VF 0x10CA
+#define E1000_REVISION_0 0
+#define E1000_REVISION_1 1
+#define E1000_REVISION_2 2
+#define E1000_REVISION_3 3
+#define E1000_REVISION_4 4
+
+#define E1000_FUNC_0 0
+#define E1000_FUNC_1 1
+
+/*
+ * Receive Address Register Count
+ * Number of high/low register pairs in the RAR. The RAR (Receive Address
+ * Registers) holds the directed and multicast addresses that we monitor.
+ * These entries are also used for MAC-based filtering.
+ */
+#define E1000_RAR_ENTRIES_VF 1
+
+/* Receive Descriptor - Advanced */
+union e1000_adv_rx_desc {
+ struct {
+ u64 pkt_addr; /* Packet buffer address */
+ u64 hdr_addr; /* Header buffer address */
+ } read;
+ struct {
+ struct {
+ union {
+ u32 data;
+ struct {
+ u16 pkt_info; /* RSS/Packet type */
+ u16 hdr_info; /* Split Header,
+ * hdr buffer length */
+ } hs_rss;
+ } lo_dword;
+ union {
+ u32 rss; /* RSS Hash */
+ struct {
+ u16 ip_id; /* IP id */
+ u16 csum; /* Packet Checksum */
+ } csum_ip;
+ } hi_dword;
+ } lower;
+ struct {
+ u32 status_error; /* ext status/error */
+ u16 length; /* Packet length */
+ u16 vlan; /* VLAN tag */
+ } upper;
+ } wb; /* writeback */
+};
+
+#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0
+#define E1000_RXDADV_HDRBUFLEN_SHIFT 5
+
+/* Transmit Descriptor - Advanced */
+union e1000_adv_tx_desc {
+ struct {
+ u64 buffer_addr; /* Address of descriptor's data buf */
+ u32 cmd_type_len;
+ u32 olinfo_status;
+ } read;
+ struct {
+ u64 rsvd; /* Reserved */
+ u32 nxtseq_seed;
+ u32 status;
+ } wb;
+};
+
+/* Adv Transmit Descriptor Config Masks */
+#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
+#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
+#define E1000_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */
+#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
+#define E1000_ADVTXD_DCMD_RS 0x08000000 /* Report Status */
+#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
+#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
+#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
+#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
+
+/* Context descriptors */
+struct e1000_adv_tx_context_desc {
+ u32 vlan_macip_lens;
+ u32 seqnum_seed;
+ u32 type_tucmd_mlhl;
+ u32 mss_l4len_idx;
+};
+
+#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
+#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
+#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
+#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
+#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
+
+enum e1000_mac_type {
+ e1000_undefined = 0,
+ e1000_vfadapt,
+ e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
+};
+
+struct e1000_vf_stats {
+ u64 base_gprc;
+ u64 base_gptc;
+ u64 base_gorc;
+ u64 base_gotc;
+ u64 base_mprc;
+ u64 base_gotlbc;
+ u64 base_gptlbc;
+ u64 base_gorlbc;
+ u64 base_gprlbc;
+
+ u32 last_gprc;
+ u32 last_gptc;
+ u32 last_gorc;
+ u32 last_gotc;
+ u32 last_mprc;
+ u32 last_gotlbc;
+ u32 last_gptlbc;
+ u32 last_gorlbc;
+ u32 last_gprlbc;
+
+ u64 gprc;
+ u64 gptc;
+ u64 gorc;
+ u64 gotc;
+ u64 mprc;
+ u64 gotlbc;
+ u64 gptlbc;
+ u64 gorlbc;
+ u64 gprlbc;
+};
+
+#include "mbx.h"
+
+struct e1000_mac_operations {
+ /* Function pointers for the MAC. */
+ s32 (*init_params)(struct e1000_hw *);
+ s32 (*check_for_link)(struct e1000_hw *);
+ void (*clear_vfta)(struct e1000_hw *);
+ s32 (*get_bus_info)(struct e1000_hw *);
+ s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
+ void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32, u32);
+ s32 (*reset_hw)(struct e1000_hw *);
+ s32 (*init_hw)(struct e1000_hw *);
+ s32 (*setup_link)(struct e1000_hw *);
+ void (*write_vfta)(struct e1000_hw *, u32, u32);
+ void (*mta_set)(struct e1000_hw *, u32);
+ void (*rar_set)(struct e1000_hw *, u8*, u32);
+ s32 (*read_mac_addr)(struct e1000_hw *);
+ s32 (*set_vfta)(struct e1000_hw *, u16, bool);
+};
+
+struct e1000_mac_info {
+ struct e1000_mac_operations ops;
+ u8 addr[6];
+ u8 perm_addr[6];
+
+ enum e1000_mac_type type;
+
+ u16 mta_reg_count;
+ u16 rar_entry_count;
+
+ bool get_link_status;
+};
+
+struct e1000_mbx_operations {
+ s32 (*init_params)(struct e1000_hw *hw);
+ s32 (*read)(struct e1000_hw *, u32 *, u16);
+ s32 (*write)(struct e1000_hw *, u32 *, u16);
+ s32 (*read_posted)(struct e1000_hw *, u32 *, u16);
+ s32 (*write_posted)(struct e1000_hw *, u32 *, u16);
+ s32 (*check_for_msg)(struct e1000_hw *);
+ s32 (*check_for_ack)(struct e1000_hw *);
+ s32 (*check_for_rst)(struct e1000_hw *);
+};
+
+struct e1000_mbx_stats {
+ u32 msgs_tx;
+ u32 msgs_rx;
+
+ u32 acks;
+ u32 reqs;
+ u32 rsts;
+};
+
+struct e1000_mbx_info {
+ struct e1000_mbx_operations ops;
+ struct e1000_mbx_stats stats;
+ u32 timeout;
+ u32 usec_delay;
+ u16 size;
+};
+
+struct e1000_dev_spec_vf {
+ u32 vf_number;
+ u32 v2p_mailbox;
+};
+
+struct e1000_hw {
+ void *back;
+
+ u8 __iomem *hw_addr;
+ u8 __iomem *flash_address;
+ unsigned long io_base;
+
+ struct e1000_mac_info mac;
+ struct e1000_mbx_info mbx;
+
+ union {
+ struct e1000_dev_spec_vf vf;
+ } dev_spec;
+
+ u16 device_id;
+ u16 subsystem_vendor_id;
+ u16 subsystem_device_id;
+ u16 vendor_id;
+
+ u8 revision_id;
+};
+
+/* These functions must be implemented by drivers */
+void e1000_rlpml_set_vf(struct e1000_hw *, u16);
+void e1000_init_function_pointers_vf(struct e1000_hw *hw);
+s32 e1000_init_mac_params_vf(struct e1000_hw *hw);
+
+
+#endif /* _E1000_VF_H_ */
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 170b12d1d70..cbc63ff13ad 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -1226,17 +1226,17 @@ static int __devinit ioc3_probe(struct pci_dev *pdev,
int err, pci_using_dac;
/* Configure DMA attributes. */
- err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (!err) {
pci_using_dac = 1;
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (err < 0) {
printk(KERN_ERR "%s: Unable to obtain 64 bit DMA "
"for consistent allocations\n", pci_name(pdev));
goto out;
}
} else {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
printk(KERN_ERR "%s: No usable DMA configuration, "
"aborting.\n", pci_name(pdev));
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index 360aa5e35fd..43019461b77 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -2240,9 +2240,9 @@ static int __devinit ipg_probe(struct pci_dev *pdev,
pci_set_master(pdev);
- rc = pci_set_dma_mask(pdev, DMA_40BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(40));
if (rc < 0) {
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc < 0) {
printk(KERN_ERR "%s: DMA config failed.\n",
pci_name(pdev));
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 4b0ea66d7a4..4a0826b8f6f 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -365,12 +365,12 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
return err;
- if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
- !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
+ if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) &&
+ !(err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))) {
pci_using_dac = 1;
} else {
- if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
- (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) {
+ if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) ||
+ (err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))) {
printk(KERN_ERR
"ixgb: No usable DMA configuration, aborting\n");
goto err_dma_mask;
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 286ecc0e6ab..9ef128ae645 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -1643,7 +1643,7 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
tdba = ring->dma;
tdlen = ring->count * sizeof(union ixgbe_adv_tx_desc);
IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j),
- (tdba & DMA_32BIT_MASK));
+ (tdba & DMA_BIT_MASK(32)));
IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32));
IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), tdlen);
IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0);
@@ -1782,7 +1782,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
for (i = 0; i < adapter->num_rx_queues; i++) {
rdba = adapter->rx_ring[i].dma;
j = adapter->rx_ring[i].reg_idx;
- IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j), (rdba & DMA_32BIT_MASK));
+ IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j), (rdba & DMA_BIT_MASK(32)));
IXGBE_WRITE_REG(hw, IXGBE_RDBAH(j), (rdba >> 32));
IXGBE_WRITE_REG(hw, IXGBE_RDLEN(j), rdlen);
IXGBE_WRITE_REG(hw, IXGBE_RDH(j), 0);
@@ -4509,13 +4509,13 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (err)
return err;
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
- !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) &&
+ !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
} else {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "No usable DMA "
"configuration, aborting\n");
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index 860dcd98a07..621a7c0c46b 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -2591,17 +2591,17 @@ static int
jme_pci_dma64(struct pci_dev *pdev)
{
if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 &&
- !pci_set_dma_mask(pdev, DMA_64BIT_MASK))
- if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
+ !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
+ if (!pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
return 1;
if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 &&
- !pci_set_dma_mask(pdev, DMA_40BIT_MASK))
- if (!pci_set_consistent_dma_mask(pdev, DMA_40BIT_MASK))
+ !pci_set_dma_mask(pdev, DMA_BIT_MASK(40)))
+ if (!pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40)))
return 1;
- if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK))
- if (!pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
+ if (!pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
return 0;
return -1;
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index a66f5b2fd28..102bac90a30 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -1076,20 +1076,20 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_master(pdev);
- err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (err) {
dev_warn(&pdev->dev, "Warning: couldn't set 64-bit PCI DMA mask.\n");
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "Can't set PCI DMA mask, aborting.\n");
goto err_release_bar2;
}
}
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (err) {
dev_warn(&pdev->dev, "Warning: couldn't set 64-bit "
"consistent PCI DMA mask.\n");
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "Can't set consistent PCI DMA mask, "
"aborting.\n");
diff --git a/drivers/net/mlx4/port.c b/drivers/net/mlx4/port.c
index 7cce3342ef8..606aa58afde 100644
--- a/drivers/net/mlx4/port.c
+++ b/drivers/net/mlx4/port.c
@@ -299,13 +299,14 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
struct mlx4_cmd_mailbox *mailbox;
int err;
+ if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
+ return 0;
+
mailbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(mailbox))
return PTR_ERR(mailbox);
memset(mailbox->buf, 0, 256);
- if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
- return 0;
((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT,
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index a56d9d2df73..b3185bf2c15 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -2274,8 +2274,6 @@ static void port_start(struct mv643xx_eth_private *mp)
pscr |= FORCE_LINK_PASS;
wrlp(mp, PORT_SERIAL_CONTROL, pscr);
- wrlp(mp, SDMA_CONFIG, PORT_SDMA_CONFIG_DEFAULT_VALUE);
-
/*
* Configure TX path and queues.
*/
@@ -2957,6 +2955,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
netif_carrier_off(dev);
+ wrlp(mp, SDMA_CONFIG, PORT_SDMA_CONFIG_DEFAULT_VALUE);
+
set_rx_coal(mp, 250);
set_tx_coal(mp, 0);
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index aea9fdaa3cd..9eed126a82f 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1130,7 +1130,7 @@ myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst,
__be32 low;
low = src->addr_low;
- src->addr_low = htonl(DMA_32BIT_MASK);
+ src->addr_low = htonl(DMA_BIT_MASK(32));
myri10ge_pio_copy(dst, src, 4 * sizeof(*src));
mb();
myri10ge_pio_copy(dst + 4, src + 4, 4 * sizeof(*src));
@@ -3792,19 +3792,19 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
dac_enabled = 1;
- status = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ status = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (status != 0) {
dac_enabled = 0;
dev_err(&pdev->dev,
"64-bit pci address mask was refused, "
"trying 32-bit\n");
- status = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ status = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
}
if (status != 0) {
dev_err(&pdev->dev, "Error %d setting DMA mask\n", status);
goto abort_with_enabled;
}
- (void)pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ (void)pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd),
&mgp->cmd_bus, GFP_KERNEL);
if (mgp->cmd == NULL)
diff --git a/drivers/net/myri_code.h b/drivers/net/myri_code.h
deleted file mode 100644
index ba7b8652c50..00000000000
--- a/drivers/net/myri_code.h
+++ /dev/null
@@ -1,5006 +0,0 @@
-/* This is the Myrinet MCP code for LANai4.x */
-/* Generated by cat $MYRI_HOME/lib/lanai/mcp4.dat > myri_code4.h */
-
-static unsigned int __devinitdata lanai4_code_off = 0x0000; /* half-word offset */
-static unsigned char __devinitdata lanai4_code[76256] = {
-0xF2,0x0E,
-0xFE,0x00, 0xC2,0x90, 0x00,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x01,0x4C, 0x97,0x93,
-0xFF,0xFC, 0xE0,0x00, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x06, 0x2A,0x6C, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x2C,0x10, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x48, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x02, 0x05,0x3C, 0x97,0x13, 0xFF,0xFC, 0xF7,0x02, 0x00,0x03, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x29,0xE0, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x2B,0x84, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x2C,0x1C, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x48, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x02, 0x0A,0xBC, 0x97,0x13, 0xFF,0xFC, 0xF7,0x02, 0x00,0x02, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x2A,0xF8, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0xF7,0x04, 0x4A,0x9C, 0x85,0x16, 0x00,0x00, 0x20,0x3A, 0x00,0x01, 0xEE,0x00,
-0x01,0x01, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x01,0x00, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xF0, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x01,0x2D, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39,
-0x00,0x02, 0xF4,0x82, 0x00,0x12, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x01,0xE0, 0xB4,0xBA,
-0x68,0x02, 0xE0,0x00, 0x01,0xE0, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04, 0x3B,0x64, 0xF5,0x84,
-0x4F,0x54, 0xF7,0x05, 0x7A,0x10, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0x01,0x99, 0x97,0x2A,
-0x00,0x20, 0x95,0xAA, 0x00,0x1C, 0xF6,0x06, 0x4A,0x98, 0x26,0xAC, 0x00,0x01, 0x77,0x35,
-0x00,0x01, 0xC7,0x38, 0x68,0x00, 0x77,0x39, 0x00,0x02, 0x07,0x38, 0x00,0x0C, 0xA4,0xBA,
-0x60,0x02, 0x00,0x00, 0x00,0x01, 0x94,0xAA, 0x00,0x10, 0xC7,0x38, 0x60,0x00, 0x87,0x3A,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0x97,0x2A, 0x00,0x14, 0xF7,0x04, 0x4A,0x9C, 0x00,0x00,
-0x00,0x01, 0x27,0x38, 0x00,0x01, 0xC0,0x2E, 0x72,0x00, 0xD7,0x00, 0x0A,0x01, 0xE0,0x00,
-0x01,0xD0, 0xF7,0x05, 0x7A,0x18, 0x95,0xAA, 0x00,0x1C, 0xF6,0x06, 0x4A,0x98, 0x06,0xAC,
-0x00,0x01, 0x77,0x35, 0x00,0x01, 0xC7,0x38, 0x68,0x00, 0x77,0x39, 0x00,0x02, 0x07,0x38,
-0x00,0x0C, 0xA4,0xBA, 0x60,0x02, 0x00,0x00, 0x00,0x01, 0x94,0xAA, 0x00,0x10, 0xC7,0x38,
-0x60,0x00, 0x87,0x3A, 0x00,0x04, 0xF0,0x05, 0x7A,0x18, 0x97,0x2A, 0x00,0x14, 0xF5,0x05,
-0x79,0xD8, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x01,0xF4, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x38, 0xF7,0x04,
-0x7A,0x10, 0xF6,0x84, 0x3B,0x64, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0x47,0x0C,
-0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x02,0x4C, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x02,0x4C, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xF0, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x02,0x85, 0xF4,0x82, 0x00,0x00, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86,
-0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02,
-0x00,0x12, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x02,0x74, 0xB3,0x3A, 0x68,0x02, 0xF0,0x05,
-0x2D,0x38, 0xF3,0x06, 0x2A,0x6C, 0xF3,0x05, 0x2C,0x10, 0xE0,0x00, 0x05,0x28, 0xF0,0x05,
-0x7A,0x18, 0xF3,0x84, 0x79,0xD8, 0xF6,0x84, 0x4A,0xA0, 0x23,0x14, 0x00,0x20, 0x93,0x16,
-0xFF,0xC4, 0x84,0x1E, 0x00,0x10, 0x96,0x96, 0xFF,0xD4, 0xF7,0x04, 0x4A,0x9C, 0x94,0x16,
-0xFF,0xE0, 0x85,0x1E, 0x00,0x14, 0xC0,0x36, 0x72,0x00, 0xEC,0x00, 0x03,0x6C, 0x95,0x16,
-0xFF,0xE4, 0x77,0x35, 0x00,0x01, 0xC7,0x38, 0x68,0x00, 0x77,0x39, 0x00,0x02, 0xF3,0x06,
-0x4A,0x98, 0xC6,0xB8, 0x30,0x00, 0x06,0xB4, 0x00,0x0C, 0xC5,0x84, 0x00,0x00, 0x87,0x36,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x42,0x00, 0xE6,0x00, 0x02,0xFC, 0xC6,0x24,
-0x00,0x00, 0x87,0x36, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x52,0x00, 0xE6,0x00,
-0x03,0x00, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0x03,0x0D, 0x00,0x00, 0x00,0x01, 0xF5,0x82, 0x00,0x00, 0x86,0x36, 0x00,0x00, 0x87,0x16,
-0xFF,0xE0, 0x00,0x00, 0x00,0x01, 0xC0,0x32, 0x72,0x00, 0xE2,0x00, 0x03,0x48, 0xF5,0x02,
-0x00,0x00, 0xC0,0x32, 0x72,0x00, 0xE6,0x00, 0x03,0x50, 0x20,0x2A, 0x00,0x00, 0x86,0xB6,
-0x00,0x04, 0x87,0x16, 0xFF,0xE4, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00,
-0x03,0x51, 0x20,0x2A, 0x00,0x00, 0xF5,0x02, 0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x00,
-0x03,0x61, 0x20,0x2E, 0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00,
-0x03,0x70, 0x20,0x26, 0x00,0x00, 0xF4,0x82, 0x00,0x01, 0x20,0x26, 0x00,0x00, 0xE6,0x00,
-0x03,0xA5, 0xF6,0x02, 0x00,0x01, 0x87,0x16, 0xFF,0xD4, 0xF3,0x06, 0x4A,0x98, 0x76,0xB9,
-0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4, 0x30,0x00, 0x06,0xB4,
-0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16, 0xFF,0xD8, 0xE0,0x00, 0x04,0x18, 0x96,0x96,
-0xFF,0xDC, 0x27,0x14, 0x00,0x2C, 0x97,0x13, 0xFF,0xFC, 0x83,0x16, 0xFF,0xC4, 0x00,0x00,
-0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0xF3,0x06, 0x4A,0x98, 0x93,0x13, 0xFF,0xFC, 0x93,0x96,
-0xFF,0xCC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x25,0x68, 0x97,0x93, 0xFF,0xFC, 0x83,0x96,
-0xFF,0xCC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x04,0x15, 0xF6,0x02, 0x00,0x01, 0x87,0x16,
-0xFF,0xD4, 0xF3,0x06, 0x4A,0x98, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5,
-0x00,0x02, 0xC6,0xB4, 0x30,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16,
-0xFF,0xD8, 0x96,0x96, 0xFF,0xDC, 0xF7,0x05, 0x4A,0xA0, 0xE0,0x00, 0x04,0x1C, 0x20,0x32,
-0x00,0x00, 0xF6,0x02, 0x00,0x00, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x04,0x2C, 0xF4,0x82,
-0x00,0x01, 0xE0,0x00, 0x04,0x84, 0xF4,0x82, 0x00,0x00, 0x86,0x96, 0xFF,0xD8, 0x00,0x00,
-0x00,0x01, 0x77,0x35, 0x00,0x02, 0xC7,0x38, 0x68,0x00, 0x77,0x39, 0x00,0x02, 0xF6,0x86,
-0x42,0xC8, 0xA6,0x3A, 0x68,0x02, 0xC7,0x38, 0x68,0x00, 0x75,0x39, 0x00,0x1E, 0x75,0x28,
-0xFF,0xE5, 0x05,0xB8, 0x00,0x02, 0x86,0xAE, 0x00,0x00, 0x07,0x38, 0x00,0x04, 0x97,0x16,
-0xFF,0xEC, 0xC6,0x30, 0x57,0xC0, 0x76,0x30, 0xFF,0xF0, 0x96,0x16, 0xFF,0xF4, 0x75,0xAD,
-0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0xC6,0xB4, 0x5F,0xC0, 0x76,0xB4, 0xFF,0xF0, 0x96,0x96,
-0xFF,0xF0, 0x20,0x26, 0x00,0x00, 0xE6,0x00, 0x05,0x25, 0xF3,0x06, 0x29,0xE0, 0x86,0x96,
-0xFF,0xF0, 0xF5,0x82, 0x00,0x00, 0xC7,0x34, 0x68,0x00, 0xC4,0x9C, 0x72,0x00, 0xC0,0x2E,
-0x6A,0x00, 0xEC,0x00, 0x04,0xF0, 0xC5,0x24, 0x00,0x00, 0xC6,0x2C, 0x00,0x00, 0x87,0x16,
-0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0xA6,0xB2, 0x70,0x02, 0x05,0xAC, 0x00,0x01, 0xC7,0x30,
-0x70,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB4,
-0xFF,0xF0, 0xF6,0xAB, 0x28,0x00, 0x05,0x28, 0x00,0x02, 0x87,0x16, 0xFF,0xF0, 0x00,0x00,
-0x00,0x01, 0xC0,0x2E, 0x72,0x00, 0xEC,0x00, 0x04,0xB1, 0x06,0x30, 0x00,0x02, 0xF3,0x02,
-0x00,0x03, 0xF3,0x05, 0x76,0xF4, 0x87,0x16, 0xFF,0xF0, 0x86,0x9E, 0x00,0x04, 0xC7,0x38,
-0x70,0x00, 0xC7,0x38, 0x48,0x00, 0xC6,0xB4, 0x70,0x00, 0x87,0x16, 0xFF,0xF4, 0x06,0xB4,
-0x00,0x20, 0x97,0x02, 0xFF,0x6C, 0x94,0x82, 0xFF,0x50, 0x96,0x82, 0xFF,0x58, 0xF3,0x06,
-0x29,0xE0, 0xF3,0x05, 0x2C,0x10, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0xF7,0x04, 0x7A,0x18, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x05,0xCD, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x7A,0x10, 0xF6,0x84, 0x3B,0x64, 0x00,0x00,
-0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x05,0xCD, 0xF5,0x86, 0x4A,0x98, 0xF6,0x04, 0x79,0xD8, 0xF6,0x84, 0x4F,0x54, 0x00,0x00,
-0x00,0x01, 0x96,0xB2, 0x00,0x1C, 0x06,0xB4, 0x00,0x01, 0x77,0x35, 0x00,0x01, 0xC7,0x38,
-0x68,0x00, 0x77,0x39, 0x00,0x02, 0x07,0x38, 0x00,0x0C, 0xA5,0x3A, 0x58,0x02, 0x00,0x00,
-0x00,0x01, 0x95,0x32, 0x00,0x10, 0xC7,0x38, 0x58,0x00, 0x87,0x3A, 0x00,0x04, 0xF0,0x05,
-0x7A,0x18, 0x97,0x32, 0x00,0x14, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x01,0xF4, 0x97,0x93,
-0xFF,0xFC, 0xE0,0x00, 0x05,0xFC, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86,
-0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF5,0x02,
-0x00,0x12, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x05,0xF4, 0xB5,0x3A, 0x68,0x02, 0xF0,0x05,
-0x2D,0x38, 0xF5,0x06, 0x2A,0x6C, 0xF5,0x05, 0x2C,0x10, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x85,0x96, 0x00,0x00, 0xF7,0x04, 0x75,0xEC, 0x85,0x2E,
-0x00,0x20, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x06,0xCC, 0xF5,0x05, 0x7A,0x08, 0xF7,0x04,
-0x75,0xF0, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x06,0xCC, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x7A,0x08, 0xF6,0x84, 0x3B,0x64, 0x00,0x00, 0x00,0x01, 0xC0,0x3A,
-0x6A,0x00, 0x47,0x0C, 0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x06,0xCC, 0x00,0x00, 0x00,0x01, 0x87,0x2E, 0x00,0x1C, 0xF6,0x84, 0x4F,0x54, 0xF7,0x05,
-0x7A,0x00, 0xC7,0x34, 0x72,0x00, 0x20,0x3A, 0x00,0x00, 0xEE,0x00, 0x06,0x8D, 0xF5,0x02,
-0x00,0x01, 0xE0,0x00, 0x06,0x90, 0xF5,0x05, 0x79,0xF8, 0xF0,0x85, 0x79,0xF8, 0xF6,0x84,
-0x7A,0x00, 0xC7,0x38, 0x70,0x00, 0xC6,0xB4, 0x70,0x00, 0xF7,0x04, 0x79,0xF8, 0xF6,0x85,
-0x79,0xE8, 0xC7,0x38, 0x70,0x00, 0xC6,0x34, 0x70,0x00, 0xF7,0x04, 0x4A,0x9C, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xEC,0x00, 0x06,0xCC, 0xF6,0x05, 0x79,0xF0, 0x20,0x36,
-0x00,0x00, 0xEC,0x00, 0x06,0xF8, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86,
-0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF5,0x02,
-0x00,0x13, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x07,0x38, 0xB5,0x3A, 0x68,0x02, 0xE0,0x00,
-0x07,0x38, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04, 0x4A,0x9C, 0x00,0x00, 0x00,0x01, 0xC0,0x32,
-0x72,0x00, 0xEE,0x00, 0x07,0x19, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x4A,0x9C, 0xE0,0x00,
-0x07,0x28, 0xF7,0x05, 0x79,0xF0, 0x20,0x32, 0x00,0x00, 0xEC,0x00, 0x07,0x28, 0x00,0x00,
-0x00,0x01, 0xF0,0x85, 0x79,0xF0, 0xF5,0x85, 0x79,0xE0, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x07,0x4C, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x22,0x10, 0x00,0x38, 0xF7,0x04, 0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x07,0xA4, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xF0, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x07,0xA4, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x7A,0x08, 0xF6,0x84, 0x3B,0x64, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0x47,0x0C,
-0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x07,0xD5, 0xF4,0x02,
-0x00,0x00, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02, 0x00,0x13, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x07,0xCC, 0xB3,0x3A, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xE0,0x00, 0x0A,0xA4, 0xF3,0x06,
-0x2B,0x84, 0xF6,0x84, 0x79,0xE8, 0xF6,0x06, 0x4A,0x98, 0x77,0x35, 0x00,0x01, 0xC7,0x38,
-0x68,0x00, 0x77,0x39, 0x00,0x02, 0xF6,0x84, 0x79,0xE0, 0x07,0x38, 0x00,0x0C, 0xA3,0x3A,
-0x60,0x02, 0xC3,0xB4, 0x00,0x00, 0x93,0x36, 0x00,0x10, 0xC7,0x38, 0x60,0x00, 0x87,0x3A,
-0x00,0x04, 0x23,0x14, 0x00,0x20, 0x93,0x16, 0xFF,0xC4, 0x97,0x36, 0x00,0x14, 0x84,0x9E,
-0x00,0x10, 0xF6,0x84, 0x4A,0xA0, 0x94,0x96, 0xFF,0xE0, 0x96,0x96, 0xFF,0xD4, 0x85,0x1E,
-0x00,0x14, 0xF7,0x04, 0x4A,0x9C, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xEC,0x00,
-0x08,0xEC, 0x95,0x16, 0xFF,0xE4, 0x77,0x35, 0x00,0x01, 0xC7,0x38, 0x68,0x00, 0x77,0x39,
-0x00,0x02, 0xC6,0xB8, 0x60,0x00, 0x06,0xB4, 0x00,0x0C, 0xC5,0x84, 0x00,0x00, 0x87,0x36,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x4A,0x00, 0xE6,0x00, 0x08,0x7C, 0xC6,0x20,
-0x00,0x00, 0x87,0x36, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x52,0x00, 0xE6,0x00,
-0x08,0x80, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0x08,0x8D, 0x00,0x00, 0x00,0x01, 0xF5,0x82, 0x00,0x00, 0x86,0x36, 0x00,0x00, 0x87,0x16,
-0xFF,0xE0, 0x00,0x00, 0x00,0x01, 0xC0,0x32, 0x72,0x00, 0xE2,0x00, 0x08,0xC8, 0xF5,0x02,
-0x00,0x00, 0xC0,0x32, 0x72,0x00, 0xE6,0x00, 0x08,0xD0, 0x20,0x2A, 0x00,0x00, 0x86,0xB6,
-0x00,0x04, 0x87,0x16, 0xFF,0xE4, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00,
-0x08,0xD1, 0x20,0x2A, 0x00,0x00, 0xF5,0x02, 0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x00,
-0x08,0xE1, 0x20,0x2E, 0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00,
-0x08,0xF0, 0x20,0x22, 0x00,0x00, 0xF4,0x02, 0x00,0x01, 0x20,0x22, 0x00,0x00, 0xE6,0x00,
-0x09,0x25, 0xF6,0x02, 0x00,0x01, 0x87,0x16, 0xFF,0xD4, 0xF3,0x06, 0x4A,0x98, 0x76,0xB9,
-0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4, 0x30,0x00, 0x06,0xB4,
-0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16, 0xFF,0xD8, 0xE0,0x00, 0x09,0x98, 0x96,0x96,
-0xFF,0xDC, 0x27,0x14, 0x00,0x2C, 0x97,0x13, 0xFF,0xFC, 0x83,0x16, 0xFF,0xC4, 0x00,0x00,
-0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0xF3,0x06, 0x4A,0x98, 0x93,0x13, 0xFF,0xFC, 0x93,0x96,
-0xFF,0xCC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x25,0x68, 0x97,0x93, 0xFF,0xFC, 0x83,0x96,
-0xFF,0xCC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x09,0x95, 0xF6,0x02, 0x00,0x01, 0x87,0x16,
-0xFF,0xD4, 0xF3,0x06, 0x4A,0x98, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5,
-0x00,0x02, 0xC6,0xB4, 0x30,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16,
-0xFF,0xD8, 0x96,0x96, 0xFF,0xDC, 0xF7,0x05, 0x4A,0xA0, 0xE0,0x00, 0x09,0x9C, 0x20,0x32,
-0x00,0x00, 0xF6,0x02, 0x00,0x00, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x09,0xAC, 0xF4,0x82,
-0x00,0x01, 0xE0,0x00, 0x0A,0x04, 0xF4,0x82, 0x00,0x00, 0x86,0x96, 0xFF,0xD8, 0x00,0x00,
-0x00,0x01, 0x77,0x35, 0x00,0x02, 0xC7,0x38, 0x68,0x00, 0x77,0x39, 0x00,0x02, 0xF6,0x86,
-0x42,0xC8, 0xA6,0x3A, 0x68,0x02, 0xC7,0x38, 0x68,0x00, 0x75,0x39, 0x00,0x1E, 0x75,0x28,
-0xFF,0xE5, 0x05,0xB8, 0x00,0x02, 0x86,0xAE, 0x00,0x00, 0x07,0x38, 0x00,0x04, 0x97,0x16,
-0xFF,0xEC, 0xC6,0x30, 0x57,0xC0, 0x76,0x30, 0xFF,0xF0, 0x96,0x16, 0xFF,0xF4, 0x75,0xAD,
-0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0xC6,0xB4, 0x5F,0xC0, 0x76,0xB4, 0xFF,0xF0, 0x96,0x96,
-0xFF,0xF0, 0x20,0x26, 0x00,0x00, 0xE6,0x00, 0x0A,0xA5, 0xF3,0x06, 0x2A,0xF8, 0x86,0x96,
-0xFF,0xF0, 0xF5,0x82, 0x00,0x00, 0xC7,0x34, 0x68,0x00, 0xC4,0x9C, 0x72,0x00, 0xC0,0x2E,
-0x6A,0x00, 0xEC,0x00, 0x0A,0x70, 0xC5,0x24, 0x00,0x00, 0xC6,0x2C, 0x00,0x00, 0x87,0x16,
-0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0xA6,0xB2, 0x70,0x02, 0x05,0xAC, 0x00,0x01, 0xC7,0x30,
-0x70,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB4,
-0xFF,0xF0, 0xF6,0xAB, 0x28,0x00, 0x05,0x28, 0x00,0x02, 0x87,0x16, 0xFF,0xF0, 0x00,0x00,
-0x00,0x01, 0xC0,0x2E, 0x72,0x00, 0xEC,0x00, 0x0A,0x31, 0x06,0x30, 0x00,0x02, 0xF3,0x02,
-0x00,0x02, 0xF3,0x05, 0x76,0xF4, 0x87,0x16, 0xFF,0xF0, 0x86,0x9E, 0x00,0x04, 0xC7,0x38,
-0x70,0x00, 0xC7,0x38, 0x48,0x00, 0xC6,0xB4, 0x70,0x00, 0x87,0x16, 0xFF,0xF4, 0x06,0xB4,
-0x00,0x20, 0x97,0x02, 0xFF,0x6C, 0x94,0x82, 0xFF,0x50, 0x96,0x82, 0xFF,0x58, 0xF3,0x06,
-0x2A,0xF8, 0xF3,0x05, 0x2C,0x1C, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0xF6,0x84, 0x79,0xE8, 0xF7,0x04, 0x79,0xF8, 0x00,0x00, 0x00,0x01, 0xC6,0xB4,
-0x70,0x00, 0xF7,0x04, 0x7A,0x20, 0xF6,0x85, 0x79,0xE8, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x7A,0x20, 0xF7,0x04, 0x79,0xF0, 0xF6,0x04, 0x7A,0x20, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0x0B,0x2C, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF5,0x82, 0x00,0x13, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x0B,0x20, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF5,0x86,
-0x2B,0x84, 0xE0,0x00, 0x0B,0x38, 0xF5,0x85, 0x2C,0x1C, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x07,0x4C, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0xF7,0x06, 0x2C,0x10, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x29,0xE0, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06,
-0x2C,0x10, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x2A,0x6C, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x2C,0x1C, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x2A,0xF8, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x2C,0x1C, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x2B,0x84, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93,
-0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF0,0x05,
-0x2D,0x38, 0xF0,0x05, 0x2D,0x3C, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x22,0x10, 0x00,0x18, 0xFF,0x85, 0x2E,0xDC, 0xF7,0x06, 0x0C,0x3E, 0xC7,0x7C,
-0x74,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x14,0x29, 0x97,0x16, 0xFF,0xF4, 0x47,0x38,
-0xFF,0xFB, 0xF6,0x84, 0x6F,0x50, 0xCF,0xB8, 0x00,0x00, 0x83,0x96, 0xFF,0xF4, 0xF7,0x02,
-0x00,0x3F, 0xC3,0x9C, 0x6D,0x80, 0xC7,0x1C, 0x74,0x00, 0x20,0x3A, 0x00,0x3F, 0xE2,0x00,
-0x12,0x60, 0x93,0x96, 0xFF,0xF4, 0x77,0x39, 0x00,0x02, 0xF6,0x82, 0x0C,0x5C, 0xA6,0xB6,
-0x70,0x02, 0x00,0x00, 0x00,0x01, 0xC1,0x34, 0x00,0x00, 0x00,0x00, 0x12,0x60, 0x00,0x00,
-0x12,0x60, 0x00,0x00, 0x0D,0x68, 0x00,0x00, 0x0D,0x68, 0x00,0x00, 0x0D,0x5C, 0x00,0x00,
-0x0D,0x5C, 0x00,0x00, 0x0D,0x68, 0x00,0x00, 0x0D,0x68, 0x00,0x00, 0x12,0x50, 0x00,0x00,
-0x12,0x50, 0x00,0x00, 0x12,0x3C, 0x00,0x00, 0x12,0x3C, 0x00,0x00, 0x0D,0xE0, 0x00,0x00,
-0x0D,0xE0, 0x00,0x00, 0x12,0x3C, 0x00,0x00, 0x12,0x3C, 0x00,0x00, 0x0D,0xE8, 0x00,0x00,
-0x0D,0xF4, 0x00,0x00, 0x0E,0x00, 0x00,0x00, 0x0E,0x20, 0x00,0x00, 0x0E,0x40, 0x00,0x00,
-0x0E,0x60, 0x00,0x00, 0x0E,0x80, 0x00,0x00, 0x0E,0xA0, 0x00,0x00, 0x0E,0xC0, 0x00,0x00,
-0x0E,0xC8, 0x00,0x00, 0x0E,0xD0, 0x00,0x00, 0x12,0x28, 0x00,0x00, 0x0E,0xD8, 0x00,0x00,
-0x0E,0xF4, 0x00,0x00, 0x0F,0x10, 0x00,0x00, 0x12,0x28, 0x00,0x00, 0x0F,0x18, 0x00,0x00,
-0x0F,0x18, 0x00,0x00, 0x0F,0x24, 0x00,0x00, 0x0F,0x24, 0x00,0x00, 0x0F,0x44, 0x00,0x00,
-0x0F,0x44, 0x00,0x00, 0x0F,0x64, 0x00,0x00, 0x0F,0x64, 0x00,0x00, 0x0F,0x84, 0x00,0x00,
-0x0F,0x84, 0x00,0x00, 0x0F,0x8C, 0x00,0x00, 0x0F,0x8C, 0x00,0x00, 0x0F,0x94, 0x00,0x00,
-0x0F,0x94, 0x00,0x00, 0x0F,0xB0, 0x00,0x00, 0x0F,0xB0, 0x00,0x00, 0x0F,0xB8, 0x00,0x00,
-0x0F,0xD8, 0x00,0x00, 0x0F,0xF8, 0x00,0x00, 0x10,0x2C, 0x00,0x00, 0x10,0x60, 0x00,0x00,
-0x10,0x94, 0x00,0x00, 0x10,0xC8, 0x00,0x00, 0x10,0xFC, 0x00,0x00, 0x11,0x30, 0x00,0x00,
-0x11,0x4C, 0x00,0x00, 0x11,0x68, 0x00,0x00, 0x12,0x14, 0x00,0x00, 0x11,0x84, 0x00,0x00,
-0x11,0xB4, 0x00,0x00, 0x11,0xE4, 0x00,0x00, 0x12,0x14, 0xF3,0x82, 0x00,0x06, 0xE0,0x00,
-0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF6,0x02, 0x00,0x05, 0x20,0x32, 0x00,0x14, 0xE6,0x00,
-0x0D,0xB5, 0x27,0x00, 0x00,0x10, 0x20,0x3A, 0x00,0x01, 0xE2,0x00, 0x0D,0xB5, 0xF7,0x06,
-0x2D,0xCC, 0xF6,0x84, 0x2E,0xCC, 0x00,0x00, 0x00,0x01, 0x75,0xB5, 0x00,0x02, 0xB6,0x2E,
-0x70,0x02, 0x06,0xB4, 0x00,0x01, 0xF6,0x85, 0x2E,0xCC, 0x86,0x02, 0xFF,0x34, 0xF7,0x06,
-0x2E,0x4C, 0x20,0x36, 0x00,0x1F, 0xE2,0x00, 0x0D,0xB5, 0xB6,0x2E, 0x70,0x02, 0xF0,0x05,
-0x2E,0xCC, 0xF7,0x04, 0x2D,0x58, 0x00,0x00, 0x00,0x01, 0x87,0x3A, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x87,0x3A, 0x00,0x18, 0x00,0x00, 0x00,0x01, 0x07,0x88, 0x00,0x08, 0xC1,0x38,
-0x00,0x00, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x12,0x60, 0x00,0x00, 0x00,0x01, 0xE0,0x00,
-0x12,0x40, 0xF3,0x82, 0x00,0x06, 0xF3,0x82, 0x00,0x0B, 0xE0,0x00, 0x12,0x54, 0x93,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x07, 0xE0,0x00, 0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x0B, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x05, 0xE0,0x00, 0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x07, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x05, 0xE0,0x00, 0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x0B, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x06, 0xE0,0x00, 0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x07, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x06, 0xE0,0x00, 0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x0B, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x05, 0xE0,0x00, 0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x07, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x05, 0xE0,0x00, 0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xE0,0x00,
-0x12,0x40, 0xF3,0x82, 0x00,0x0B, 0xE0,0x00, 0x12,0x40, 0xF3,0x82, 0x00,0x07, 0xE0,0x00,
-0x12,0x2C, 0xF3,0x82, 0x00,0x0B, 0xF3,0x82, 0x00,0x0B, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x12,0x40, 0xF3,0x82,
-0x00,0x06, 0xF3,0x82, 0x00,0x07, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x12,0x40, 0xF3,0x82, 0x00,0x06, 0xE0,0x00,
-0x12,0x2C, 0xF3,0x82, 0x00,0x0B, 0xF3,0x82, 0x00,0x14, 0xE0,0x00, 0x12,0x54, 0x93,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x05, 0xE0,0x00, 0x12,0x54, 0x93,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x06, 0xE0,0x00, 0x12,0x54, 0x93,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x05, 0xE0,0x00, 0x12,0x54, 0x93,0x93,
-0xFF,0xFC, 0xE0,0x00, 0x12,0x40, 0xF3,0x82, 0x00,0x14, 0xE0,0x00, 0x12,0x2C, 0xF3,0x82,
-0x00,0x14, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x12,0x40, 0xF3,0x82, 0x00,0x06, 0xE0,0x00,
-0x12,0x2C, 0xF3,0x82, 0x00,0x14, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x0B, 0xE0,0x00,
-0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x07, 0xE0,0x00,
-0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x0B, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x05, 0xE0,0x00, 0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x14, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x07, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x05, 0xE0,0x00, 0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x0B, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x06, 0xE0,0x00, 0x12,0x54, 0x93,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x07, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x06, 0xE0,0x00,
-0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x0B, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x05, 0xE0,0x00, 0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x14, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x07, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x05, 0xE0,0x00, 0x12,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93,
-0xFF,0xFC, 0xE0,0x00, 0x12,0x40, 0xF3,0x82, 0x00,0x0B, 0xF3,0x82, 0x00,0x14, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00,
-0x12,0x40, 0xF3,0x82, 0x00,0x07, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x12,0x2C, 0xF3,0x82,
-0x00,0x0B, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x0B, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x12,0x40, 0xF3,0x82,
-0x00,0x06, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x07, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x12,0x40, 0xF3,0x82,
-0x00,0x06, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x12,0x2C, 0xF3,0x82, 0x00,0x0B, 0xF7,0x04,
-0x35,0x28, 0xF6,0x82, 0x00,0x01, 0x07,0x38, 0x00,0x08, 0xE0,0x00, 0x13,0xCC, 0xF7,0x05,
-0x35,0x44, 0xF3,0x82, 0x00,0x14, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x07, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x05, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0x90,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0x83,0x96,
-0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0x77,0x9C, 0x00,0x14, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x00,
-0x12,0x9D, 0xF7,0x06, 0x04,0x00, 0xF7,0x04, 0x6F,0x5C, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x6F,0x5C, 0xF7,0x04, 0x6F,0x5C, 0xE0,0x00, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x83,0x96, 0xFF,0xF4, 0xF7,0x06, 0x04,0x00, 0xC0,0x1E, 0x74,0x00, 0xE6,0x00,
-0x14,0x29, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x2E,0xD0, 0xF6,0x84, 0x35,0x24, 0x07,0x38,
-0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x14,0x05, 0xF7,0x05, 0x2E,0xD0, 0xF7,0x04,
-0xE0,0x14, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x14,0x05, 0xF6,0x82,
-0x00,0x00, 0xF6,0x85, 0xE0,0x14, 0xF7,0x04, 0x2E,0xD8, 0xC5,0x34, 0x00,0x00, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x2E,0xD8, 0x20,0x2A, 0x00,0x02, 0xEE,0x00, 0x13,0xCC, 0xF6,0x82,
-0x00,0x00, 0xF6,0x84, 0x35,0x28, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x02, 0xE6,0x00, 0x13,0xA0, 0x05,0xB4, 0x00,0x08, 0x95,0x93,
-0xFF,0xFC, 0x95,0x16, 0xFF,0xE8, 0x95,0x96, 0xFF,0xE4, 0x96,0x96, 0xFF,0xE0, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x64, 0x97,0x93, 0xFF,0xFC, 0x85,0x16, 0xFF,0xE8, 0x85,0x96,
-0xFF,0xE4, 0x86,0x96, 0xFF,0xE0, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x13,0x90, 0xF7,0x02,
-0x00,0x00, 0x86,0x36, 0x00,0x0C, 0x00,0x00, 0x00,0x01, 0x20,0x32, 0x00,0x0F, 0xE2,0x00,
-0x13,0x75, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0x97,0x36, 0x00,0x14, 0x87,0x36, 0x00,0x14, 0xE0,0x00, 0x13,0x90, 0xF7,0x02,
-0x00,0x00, 0x76,0xB1, 0x00,0x02, 0xC6,0xB4, 0x60,0x00, 0x77,0x35, 0x00,0x05, 0xC7,0x38,
-0x6A,0x00, 0xC7,0x38, 0x60,0x00, 0x07,0x38, 0x00,0x10, 0xC7,0x2C, 0x70,0x00, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x12,0x00, 0xF7,0x05, 0x35,0x2C, 0xF6,0x84, 0x35,0x28, 0xF7,0x04,
-0x6F,0x4C, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x13,0xC0, 0x07,0x34,
-0x14,0x94, 0xF3,0x84, 0x6F,0x44, 0xE0,0x00, 0x13,0xC4, 0xF3,0x85, 0x35,0x28, 0xF7,0x05,
-0x35,0x28, 0xE0,0x00, 0x12,0xE8, 0x05,0x28, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00,
-0x14,0x29, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0xF0,0x05, 0x35,0x24, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x82, 0x00,0x0D, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x14,0x28, 0xB3,0xBA, 0x68,0x02, 0xE0,0x00, 0x14,0x28, 0xF0,0x05,
-0x2D,0x38, 0xF7,0x04, 0xE0,0x10, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x14,0x29, 0xF7,0x02, 0x00,0x00, 0xF7,0x05, 0xE0,0x10, 0x07,0x88, 0x00,0x08, 0xE0,0x01,
-0x02,0x98, 0x97,0x93, 0xFF,0xFC, 0xF4,0x84, 0x2D,0x38, 0xF7,0x04, 0x2D,0x3C, 0x00,0x00,
-0x00,0x01, 0xC0,0x3A, 0x4A,0x00, 0xE6,0x00, 0x0C,0x09, 0xF6,0x86, 0x2C,0x28, 0x77,0x39,
-0x00,0x02, 0xA5,0x3A, 0x68,0x02, 0x00,0x00, 0x00,0x01, 0x20,0x2A, 0x00,0x14, 0xE6,0x00,
-0x14,0x91, 0x27,0x28, 0x00,0x15, 0x20,0x3A, 0x00,0x01, 0xE2,0x00, 0x14,0x91, 0xF7,0x06,
-0x2D,0xCC, 0xF6,0x84, 0x2E,0xCC, 0x86,0x02, 0xFF,0x34, 0x75,0xB5, 0x00,0x02, 0xB5,0x2E,
-0x70,0x02, 0x06,0xB4, 0x00,0x01, 0xF6,0x85, 0x2E,0xCC, 0xF7,0x06, 0x2E,0x4C, 0x20,0x36,
-0x00,0x1F, 0xE2,0x00, 0x14,0x91, 0xB6,0x2E, 0x70,0x02, 0xF0,0x05, 0x2E,0xCC, 0xF7,0x06,
-0x2D,0x44, 0x76,0xA9, 0x00,0x02, 0xA7,0x36, 0x70,0x02, 0x00,0x00, 0x00,0x01, 0x87,0x3A,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x87,0x36, 0x00,0x04, 0x94,0x96,
-0xFF,0xEC, 0x07,0x88, 0x00,0x08, 0xC1,0x38, 0x00,0x00, 0x97,0x93, 0xFF,0xFC, 0xF7,0x04,
-0x2D,0x3C, 0x84,0x96, 0xFF,0xEC, 0x07,0x38, 0x00,0x01, 0x20,0x3A, 0x00,0x44, 0xE6,0x00,
-0x14,0x2C, 0xF7,0x05, 0x2D,0x3C, 0xE0,0x00, 0x14,0x2C, 0xF0,0x05, 0x2D,0x3C, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x84,0x16, 0x00,0x00, 0xF7,0x02,
-0x00,0x00, 0x85,0x96, 0x00,0x04, 0x20,0x3A, 0x00,0x21, 0xEE,0x00, 0x15,0x34, 0x95,0xA2,
-0x00,0x00, 0xF6,0x06, 0x23,0x38, 0x07,0x20, 0x00,0x84, 0xC6,0xA0, 0x00,0x00, 0x96,0x3A,
-0x00,0x04, 0x27,0x38, 0x00,0x04, 0xC0,0x3A, 0x6A,0x00, 0xEC,0x00, 0x15,0x20, 0x00,0x00,
-0x00,0x01, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x08, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x86,0x96,
-0x00,0x00, 0x87,0x16, 0x00,0x04, 0xF6,0x04, 0x2D,0x40, 0x97,0x36, 0x00,0x00, 0x97,0x36,
-0x00,0x04, 0x07,0x30, 0x00,0x01, 0xF7,0x05, 0x2D,0x40, 0x96,0x36, 0x00,0x08, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x08, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x85,0x16, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x20,0x2A, 0x00,0x14, 0xE6,0x00, 0x15,0xD9, 0x27,0x28, 0x00,0x15, 0x20,0x3A,
-0x00,0x01, 0xE2,0x00, 0x15,0xD9, 0xF7,0x06, 0x2D,0xCC, 0xF6,0x84, 0x2E,0xCC, 0x86,0x02,
-0xFF,0x34, 0x75,0xB5, 0x00,0x02, 0xB5,0x2E, 0x70,0x02, 0x06,0xB4, 0x00,0x01, 0xF6,0x85,
-0x2E,0xCC, 0xF7,0x06, 0x2E,0x4C, 0x20,0x36, 0x00,0x1F, 0xE2,0x00, 0x15,0xD9, 0xB6,0x2E,
-0x70,0x02, 0xF0,0x05, 0x2E,0xCC, 0xF6,0x86, 0x2D,0x44, 0x77,0x29, 0x00,0x02, 0xA6,0xBA,
-0x68,0x02, 0x00,0x00, 0x00,0x01, 0x86,0xB6, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC7,0x38,
-0x68,0x00, 0x87,0x3A, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x07,0x88, 0x00,0x08, 0xC1,0x38,
-0x00,0x00, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x87,0x16, 0x00,0x00, 0x86,0x96, 0x00,0x04, 0xF6,0x06, 0x2D,0x44, 0x76,0xB5,
-0x00,0x02, 0x85,0xBA, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0xB5,0xB6, 0x60,0x02, 0xC6,0xB4,
-0x70,0x00, 0x85,0x96, 0x00,0x08, 0x00,0x00, 0x00,0x01, 0x95,0xB6, 0x00,0x04, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x0C, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x86,0x16, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x87,0x32, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x0F, 0x86,0xB2,
-0x00,0x00, 0xC5,0x38, 0x00,0x00, 0xEE,0x00, 0x16,0xB4, 0xC5,0xB4, 0x00,0x00, 0x20,0x36,
-0x00,0x0F, 0xEE,0x00, 0x16,0xB4, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xEC,0x00,
-0x16,0xB5, 0x00,0x00, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xEC,0x00, 0x16,0xD0, 0x00,0x00,
-0x00,0x01, 0x87,0x32, 0x00,0x0C, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x32,
-0x00,0x0C, 0x87,0x32, 0x00,0x0C, 0xE0,0x00, 0x16,0xD8, 0xF4,0x02, 0x00,0x00, 0xC0,0x2A,
-0x5A,0x00, 0x44,0x0C, 0x00,0x01, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x06, 0x2E,0xE0, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x32,0xD4, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x48, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x02, 0x18,0x2C, 0x97,0x13, 0xFF,0xFC, 0xF7,0x82, 0x00,0x09, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x06, 0x2E,0xE0, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF7,0x02, 0x34,0x58, 0x97,0x13, 0xFF,0xFC, 0xF7,0x02,
-0x00,0x0C, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x2F,0x6C, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF7,0x02, 0x3F,0x94, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x82, 0x00,0x0B, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x2F,0xF8, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF7,0x02,
-0x3B,0x84, 0x97,0x13, 0xFF,0xFC, 0xF7,0x82, 0x00,0x0B, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06,
-0x32,0x28, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x02, 0x26,0xE4, 0x97,0x13, 0xFF,0xFC, 0xF7,0x02, 0x00,0x13, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x30,0x84, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF7,0x02, 0x26,0xA0, 0x97,0x13, 0xFF,0xFC, 0xF7,0x02,
-0x00,0x11, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x31,0x10, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF7,0x02, 0x18,0x2C, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x82, 0x00,0x09, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x31,0x9C, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF0,0x05,
-0x7A,0x78, 0xF0,0x05, 0x32,0xE8, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x22,0x10, 0x00,0x50, 0xF7,0x04, 0x71,0xC8, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x18,0x55, 0xF6,0x86, 0x71,0xC4, 0xE0,0x00, 0x18,0x6C, 0xF6,0x02,
-0x00,0x00, 0xF7,0x04, 0x71,0xD4, 0x00,0x00, 0x00,0x01, 0x77,0x39, 0x00,0x02, 0xC7,0x38,
-0x68,0x00, 0x86,0x3A, 0x00,0x18, 0x00,0x00, 0x00,0x01, 0xF6,0x05, 0x32,0xC4, 0x86,0xB2,
-0x00,0x08, 0x07,0x01, 0x80,0x00, 0xC5,0xB4, 0x74,0x00, 0xF5,0x85, 0x32,0xD0, 0x87,0x32,
-0x00,0x18, 0xF6,0x86, 0x6F,0x44, 0x77,0x39, 0x00,0x02, 0xA7,0x3A, 0x68,0x02, 0x20,0x2E,
-0x00,0x00, 0xF7,0x05, 0x32,0xC0, 0x07,0x38, 0x09,0xD8, 0x86,0xB2, 0x00,0x04, 0xF7,0x05,
-0x32,0xCC, 0xE6,0x00, 0x19,0x41, 0xF6,0x85, 0x32,0xC8, 0xF7,0x04, 0x71,0x98, 0xF6,0x84,
-0x7A,0x78, 0x27,0x38, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x19,0x10, 0xF7,0x05,
-0x71,0x98, 0xF7,0x04, 0x76,0xFC, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x18,0xE8, 0xF3,0x02, 0x00,0x11, 0xF3,0x06, 0x32,0xD4, 0xF3,0x05, 0x76,0xFC, 0xE0,0x00,
-0x18,0xF8, 0xF7,0x02, 0x00,0x01, 0xF3,0x05, 0x76,0xF8, 0xF3,0x06, 0x32,0xD4, 0xF3,0x05,
-0x77,0x00, 0xF7,0x02, 0x00,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x19,0x14, 0xF3,0x02,
-0x00,0x01, 0xF3,0x06, 0x31,0x10, 0xE0,0x00, 0x26,0x8C, 0xF3,0x05, 0x32,0xD4, 0xF3,0x02,
-0x00,0x01, 0xF3,0x05, 0x7A,0x78, 0xF3,0x06, 0x30,0x84, 0xF3,0x05, 0x32,0xD4, 0xF3,0x04,
-0x32,0xC4, 0x00,0x00, 0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x06,0x10, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x26,0x8C, 0x00,0x00, 0x00,0x01, 0xF3,0x02,
-0x00,0x00, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0x1C,0xB9, 0x93,0x16, 0xFF,0xE4, 0x87,0x32,
-0x00,0x08, 0x86,0x96, 0xFF,0xE4, 0xC3,0x04, 0x00,0x00, 0xC0,0x3A, 0x32,0x00, 0xE6,0x00,
-0x19,0x84, 0x20,0x36, 0x00,0x00, 0x87,0x32, 0x00,0x0C, 0x00,0x00, 0x00,0x01, 0xC0,0x3A,
-0x32,0x00, 0xE6,0x00, 0x19,0x84, 0x20,0x36, 0x00,0x00, 0xF6,0x82, 0x00,0x01, 0x20,0x36,
-0x00,0x00, 0xE6,0x00, 0x1C,0xB8, 0xF3,0x02, 0x00,0x00, 0xF7,0x04, 0x32,0xC0, 0x93,0x16,
-0xFF,0xAC, 0xF5,0x84, 0x32,0xC4, 0x86,0x3A, 0x14,0x28, 0x03,0xB8, 0x14,0x20, 0x04,0x2C,
-0x00,0x08, 0x86,0xBA, 0x14,0x24, 0x00,0x00, 0x00,0x01, 0xC0,0x32, 0x6A,0x00, 0xEC,0x00,
-0x1A,0x70, 0x96,0x16, 0xFF,0xEC, 0x77,0x31, 0x00,0x01, 0xC7,0x38, 0x60,0x00, 0x77,0x39,
-0x00,0x02, 0xC6,0x38, 0x38,0x00, 0x06,0x30, 0x00,0x0C, 0x86,0xB2, 0x00,0x00, 0x87,0x2E,
-0x00,0x08, 0x85,0x16, 0xFF,0xAC, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x1A,0x00, 0xC4,0x84,
-0x00,0x00, 0x86,0xB2, 0x00,0x04, 0x87,0x2E, 0x00,0x0C, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x1A,0x04, 0x20,0x2A, 0x00,0x00, 0xF5,0x02, 0x00,0x01, 0x20,0x2A,
-0x00,0x00, 0xE6,0x00, 0x1A,0x11, 0x00,0x00, 0x00,0x01, 0xF4,0x82, 0x00,0x00, 0x86,0xB2,
-0x00,0x00, 0x87,0x22, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00,
-0x1A,0x4C, 0xF5,0x82, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x1A,0x54, 0x20,0x2E,
-0x00,0x00, 0x86,0xB2, 0x00,0x04, 0x87,0x22, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE2,0x00, 0x1A,0x55, 0x20,0x2E, 0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E,
-0x00,0x00, 0xE6,0x00, 0x1A,0x65, 0x20,0x26, 0x00,0x00, 0xF4,0x82, 0x00,0x01, 0x20,0x26,
-0x00,0x00, 0xE6,0x00, 0x1A,0x70, 0xF3,0x02, 0x00,0x01, 0x93,0x16, 0xFF,0xAC, 0x83,0x16,
-0xFF,0xAC, 0x00,0x00, 0x00,0x01, 0x20,0x1A, 0x00,0x00, 0xE6,0x00, 0x1A,0xB1, 0xF6,0x02,
-0x00,0x01, 0x87,0x16, 0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4,
-0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4, 0x38,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6,
-0x00,0x00, 0x97,0x16, 0xFF,0xF0, 0xE0,0x00, 0x1B,0x18, 0x96,0x96, 0xFF,0xF4, 0x27,0x14,
-0x00,0x14, 0x97,0x13, 0xFF,0xFC, 0x94,0x13, 0xFF,0xFC, 0x93,0x93, 0xFF,0xFC, 0x93,0x96,
-0xFF,0xBC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x25,0x68, 0x97,0x93, 0xFF,0xFC, 0x83,0x96,
-0xFF,0xBC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x1B,0x15, 0xF6,0x02, 0x00,0x01, 0x87,0x16,
-0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5,
-0x00,0x02, 0xC6,0xB4, 0x38,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16,
-0xFF,0xF0, 0x96,0x96, 0xFF,0xF4, 0x97,0x1E, 0x00,0x08, 0xE0,0x00, 0x1B,0x1C, 0x20,0x32,
-0x00,0x00, 0xF6,0x02, 0x00,0x00, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x1C,0xB8, 0xF3,0x02,
-0x00,0x00, 0xF6,0x04, 0x32,0xC0, 0x93,0x16, 0xFF,0xAC, 0x86,0xB2, 0x14,0x28, 0x03,0xB0,
-0x14,0x20, 0x04,0x30, 0x14,0x8C, 0x87,0x32, 0x14,0x24, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xEC,0x00, 0x1C,0x04, 0x96,0x96, 0xFF,0xEC, 0x77,0x35, 0x00,0x01, 0xC7,0x38,
-0x68,0x00, 0x77,0x39, 0x00,0x02, 0xC5,0xB8, 0x38,0x00, 0x05,0xAC, 0x00,0x0C, 0x86,0xAE,
-0x00,0x00, 0x87,0x32, 0x14,0x8C, 0x85,0x16, 0xFF,0xAC, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0x1B,0x94, 0xC4,0x84, 0x00,0x00, 0x86,0xAE, 0x00,0x04, 0x87,0x32, 0x14,0x90, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x1B,0x98, 0x20,0x2A, 0x00,0x00, 0xF5,0x02,
-0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x00, 0x1B,0xA5, 0x00,0x00, 0x00,0x01, 0xF4,0x82,
-0x00,0x00, 0x86,0xAE, 0x00,0x00, 0x87,0x22, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE2,0x00, 0x1B,0xE0, 0xF6,0x02, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0x1B,0xE8, 0x20,0x32, 0x00,0x00, 0x86,0xAE, 0x00,0x04, 0x87,0x22, 0x00,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0x1B,0xE9, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x1B,0xF9, 0x20,0x26, 0x00,0x00, 0xF4,0x82,
-0x00,0x01, 0x20,0x26, 0x00,0x00, 0xE6,0x00, 0x1C,0x04, 0xF3,0x02, 0x00,0x01, 0x93,0x16,
-0xFF,0xAC, 0x83,0x16, 0xFF,0xAC, 0x00,0x00, 0x00,0x01, 0x20,0x1A, 0x00,0x00, 0xE6,0x00,
-0x1C,0x45, 0xF6,0x02, 0x00,0x01, 0x87,0x16, 0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0x76,0xB9,
-0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4, 0x38,0x00, 0x06,0xB4,
-0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16, 0xFF,0xF0, 0xE0,0x00, 0x1C,0xAC, 0x96,0x96,
-0xFF,0xF4, 0x27,0x14, 0x00,0x14, 0x97,0x13, 0xFF,0xFC, 0x94,0x13, 0xFF,0xFC, 0x93,0x93,
-0xFF,0xFC, 0x93,0x96, 0xFF,0xBC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x25,0x68, 0x97,0x93,
-0xFF,0xFC, 0x83,0x96, 0xFF,0xBC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x1C,0xA9, 0xF6,0x02,
-0x00,0x01, 0x87,0x16, 0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4,
-0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4, 0x38,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6,
-0x00,0x00, 0x97,0x16, 0xFF,0xF0, 0x96,0x96, 0xFF,0xF4, 0x97,0x1E, 0x00,0x08, 0xE0,0x00,
-0x1C,0xB0, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x00, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0x1E,0x15, 0xF3,0x02, 0x00,0x01, 0xF6,0x84, 0x32,0xC0, 0x00,0x00, 0x00,0x01, 0x85,0xB6,
-0x0E,0xF4, 0x86,0x36, 0x0E,0xF8, 0x20,0x2E, 0x00,0x10, 0xE2,0x00, 0x1C,0xDC, 0x20,0x32,
-0x00,0x10, 0xE2,0x00, 0x1C,0xF9, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x0F,0x00, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36, 0x0F,0x00, 0x87,0x36, 0x0F,0x00, 0xE0,0x00,
-0x1D,0x24, 0xF7,0x02, 0x00,0x00, 0x07,0x30, 0x00,0x01, 0xC0,0x3A, 0x5A,0x00, 0xE6,0x00,
-0x1D,0x1D, 0xF6,0x82, 0x00,0x00, 0x20,0x32, 0x00,0x10, 0xE6,0x00, 0x1D,0x20, 0x20,0x2E,
-0x00,0x00, 0xE6,0x00, 0x1D,0x24, 0xC7,0x34, 0x00,0x00, 0xF6,0x82, 0x00,0x01, 0xC7,0x34,
-0x00,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x1E,0x14, 0xF3,0x02, 0x00,0x01, 0xF3,0x04,
-0x32,0xCC, 0x00,0x00, 0x00,0x01, 0x93,0x16, 0xFF,0xDC, 0x93,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x43,0x68, 0x97,0x93, 0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00,
-0x1D,0xFC, 0xF3,0x02, 0x00,0x00, 0x83,0x16, 0xFF,0xDC, 0x00,0x00, 0x00,0x01, 0x86,0x1A,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x32, 0x00,0x10, 0xE2,0x00, 0x1D,0x91, 0x76,0xB1,
-0x00,0x02, 0x87,0x1A, 0x00,0x0C, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x1A,
-0x00,0x0C, 0x87,0x1A, 0x00,0x0C, 0xE0,0x00, 0x1D,0xFC, 0xF3,0x02, 0x00,0x00, 0xF3,0x02,
-0x00,0x4C, 0x93,0x13, 0xFF,0xFC, 0xC6,0xB4, 0x60,0x00, 0x77,0x35, 0x00,0x04, 0xC7,0x38,
-0x6A,0x00, 0x83,0x16, 0xFF,0xDC, 0xC7,0x38, 0x60,0x00, 0xC7,0x38, 0x30,0x00, 0x07,0x38,
-0x00,0x10, 0x97,0x13, 0xFF,0xFC, 0xF3,0x06, 0x7A,0x28, 0x93,0x13, 0xFF,0xFC, 0x96,0x16,
-0xFF,0xB4, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x26,0xF8, 0x97,0x93, 0xFF,0xFC, 0x86,0x16,
-0xFF,0xB4, 0x00,0x00, 0x00,0x01, 0x06,0x30, 0x00,0x01, 0x20,0x32, 0x00,0x11, 0xE6,0x00,
-0x1D,0xEC, 0x00,0x00, 0x00,0x01, 0xF6,0x02, 0x00,0x00, 0x83,0x16, 0xFF,0xDC, 0x00,0x00,
-0x00,0x01, 0x96,0x1A, 0x00,0x00, 0xF3,0x02, 0x00,0x01, 0x93,0x16, 0xFF,0xD4, 0x83,0x16,
-0xFF,0xD4, 0x00,0x00, 0x00,0x01, 0x20,0x1A, 0x00,0x00, 0xE6,0x00, 0x1E,0x18, 0xF3,0x02,
-0x00,0x01, 0x93,0x16, 0xFF,0xE4, 0x83,0x16, 0xFF,0xE4, 0x00,0x00, 0x00,0x01, 0x20,0x1A,
-0x00,0x00, 0xE6,0x00, 0x1F,0x35, 0xF6,0x82, 0x0C,0xAB, 0xF7,0x04, 0x32,0xB4, 0x83,0x16,
-0xFF,0xD4, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x32,0xB4, 0xF7,0x04, 0x32,0xB4, 0x20,0x1A,
-0x00,0x00, 0xE6,0x00, 0x1E,0x70, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x32,0xC0, 0xF3,0x06,
-0xE0,0x30, 0xC0,0x3A, 0x32,0x00, 0xE6,0x00, 0x1E,0x70, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x32,0xE8, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x32,0xE8, 0xF7,0x04,
-0x71,0xC4, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x1E,0xAD, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02, 0x00,0x0A, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x1E,0xAC, 0xB3,0x3A, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04, 0x71,0xD4, 0xF6,0x84,
-0x71,0xCC, 0x07,0x38, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00, 0x1E,0xC8, 0xF7,0x05,
-0x71,0xD4, 0xF0,0x05, 0x71,0xD4, 0xF6,0x84, 0x71,0xD4, 0xF7,0x04, 0x71,0xD0, 0xF0,0x05,
-0x71,0xC4, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0xF6,0x84, 0x32,0xD0, 0x00,0x00,
-0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x25,0xD9, 0xF7,0x05, 0x71,0xC8, 0xF7,0x04,
-0x71,0x98, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x25,0x79, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x25,0x78, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xF0, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x25,0x78, 0x00,0x00, 0x00,0x01, 0xE0,0x00, 0x25,0xDC, 0xF3,0x06,
-0x31,0x9C, 0xF0,0x05, 0x32,0xE8, 0xF7,0x04, 0x32,0xC0, 0xF6,0x04, 0x6F,0x54, 0x96,0xBA,
-0x00,0x04, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x1F,0x60, 0xF3,0x02, 0x00,0x0C, 0xF3,0x02,
-0x00,0x01, 0xF3,0x05, 0x6F,0x54, 0xE0,0x00, 0x1F,0x68, 0xF7,0x02, 0x00,0x01, 0xF3,0x05,
-0x6F,0x58, 0xF7,0x02, 0x00,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x1F,0x7C, 0xF3,0x06,
-0x2F,0x6C, 0xE0,0x00, 0x26,0x8C, 0xF3,0x05, 0x32,0xD4, 0xF5,0x84, 0x7A,0x70, 0x24,0x94,
-0x00,0x10, 0x20,0x2E, 0x00,0x01, 0xE6,0x00, 0x22,0x84, 0xF5,0x85, 0x7A,0xA0, 0xF7,0x02,
-0x00,0x01, 0xF6,0x04, 0x32,0xC8, 0xF7,0x05, 0x7A,0x70, 0xF7,0x04, 0x32,0xC4, 0xF6,0x84,
-0x32,0xC0, 0xF6,0x05, 0x7A,0x2C, 0x90,0x02, 0xFF,0x80, 0x90,0x02, 0xFF,0x38, 0xF5,0x84,
-0x7A,0x28, 0x07,0x38, 0x00,0x24, 0x95,0x82, 0xFF,0x3C, 0x97,0x02, 0xFF,0x40, 0x96,0x02,
-0xFF,0x44, 0x87,0x36, 0x14,0x10, 0x00,0x00, 0x00,0x01, 0xC7,0x38, 0x60,0x00, 0x97,0x36,
-0x14,0x10, 0x87,0x36, 0x14,0x18, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x14,0x18, 0x87,0x36, 0x14,0x18, 0xF0,0x05, 0x6F,0x50, 0xF7,0x04, 0x32,0xB8, 0x95,0x96,
-0xFF,0xEC, 0xC7,0x38, 0x60,0x00, 0xF7,0x05, 0x32,0xB8, 0xF7,0x04, 0x32,0xBC, 0xF3,0x06,
-0x2F,0xF8, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x32,0xBC, 0xF7,0x04, 0x32,0xBC, 0xF3,0x05,
-0x32,0xD4, 0xF7,0x06, 0x0C,0x3E, 0xC0,0x7E, 0x74,0x00, 0xE6,0x00, 0x20,0x34, 0x00,0x00,
-0x00,0x01, 0xC0,0x7E, 0x74,0x00, 0xE6,0x00, 0x20,0x25, 0x00,0x00, 0x00,0x01, 0xF7,0x06,
-0x0C,0x3E, 0xC7,0x7C, 0x74,0x00, 0x20,0x3A, 0x00,0x10, 0xE6,0x00, 0x26,0x8C, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x32,0xE4, 0xFF,0x82, 0x00,0x10, 0xF5,0x84, 0x6F,0x58, 0x07,0x38,
-0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00, 0x20,0x90, 0xF7,0x05, 0x32,0xE4, 0xF7,0x04,
-0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39,
-0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x20,0x84, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05,
-0x2D,0x38, 0xF3,0x02, 0x00,0x22, 0xE0,0x00, 0x20,0x94, 0xF3,0x05, 0x6F,0x58, 0xF0,0x05,
-0x6F,0x54, 0xF5,0x84, 0x32,0xC0, 0x00,0x00, 0x00,0x01, 0x90,0x2E, 0x00,0x04, 0x87,0x2E,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x02, 0xE6,0x00, 0x21,0xC0, 0x00,0x00,
-0x00,0x01, 0x87,0x02, 0xFF,0x38, 0x03,0x2C, 0x0E,0xF4, 0x93,0x16, 0xFF,0xCC, 0xF7,0x05,
-0x7A,0x68, 0x93,0x13, 0xFF,0xFC, 0x95,0x96, 0xFF,0xB8, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x43,0xA0, 0x97,0x93, 0xFF,0xFC, 0x85,0x96, 0xFF,0xB8, 0x20,0x22, 0x00,0x00, 0xE6,0x00,
-0x21,0x7C, 0x00,0x00, 0x00,0x01, 0x86,0x2E, 0x0E,0xF8, 0x00,0x00, 0x00,0x01, 0x20,0x32,
-0x00,0x10, 0xE2,0x00, 0x21,0x19, 0xF3,0x02, 0x00,0x4C, 0x87,0x2E, 0x0F,0x00, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x2E, 0x0F,0x00, 0x87,0x2E, 0x0F,0x00, 0xE0,0x00,
-0x21,0x7C, 0x00,0x00, 0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0xF3,0x06, 0x7A,0x28, 0x93,0x13,
-0xFF,0xFC, 0x76,0xB1, 0x00,0x02, 0xC6,0xB4, 0x60,0x00, 0x77,0x35, 0x00,0x04, 0xC7,0x38,
-0x6A,0x00, 0x83,0x16, 0xFF,0xCC, 0xC7,0x38, 0x60,0x00, 0xC7,0x38, 0x30,0x00, 0x07,0x38,
-0x00,0x10, 0x97,0x13, 0xFF,0xFC, 0x95,0x96, 0xFF,0xB8, 0x96,0x16, 0xFF,0xB4, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x26,0xF8, 0x97,0x93, 0xFF,0xFC, 0x86,0x16, 0xFF,0xB4, 0x85,0x96,
-0xFF,0xB8, 0x06,0x30, 0x00,0x01, 0x20,0x32, 0x00,0x11, 0xE6,0x00, 0x21,0x78, 0x00,0x00,
-0x00,0x01, 0xF6,0x02, 0x00,0x00, 0x96,0x2E, 0x0E,0xF8, 0xF7,0x04, 0x32,0xC0, 0xF3,0x06,
-0xE0,0x30, 0xC0,0x3A, 0x32,0x00, 0xE6,0x00, 0x21,0xC0, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0xE0,0x18, 0x00,0x00, 0x00,0x01, 0x77,0xB8, 0x00,0x1E, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x00,
-0x21,0xC1, 0x00,0x00, 0x00,0x01, 0x0F,0x81, 0x40,0x00, 0xF7,0x04, 0x79,0xC8, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x79,0xC8, 0xF7,0x04, 0x79,0xC8, 0xF7,0x04,
-0x71,0xC4, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x21,0xFD, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02, 0x00,0x0A, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x21,0xFC, 0xB3,0x3A, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04, 0x71,0xD4, 0xF6,0x84,
-0x71,0xCC, 0x07,0x38, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00, 0x22,0x18, 0xF7,0x05,
-0x71,0xD4, 0xF0,0x05, 0x71,0xD4, 0xF6,0x84, 0x71,0xD4, 0xF7,0x04, 0x71,0xD0, 0xF0,0x05,
-0x71,0xC4, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0xF6,0x84, 0x32,0xD0, 0x00,0x00,
-0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x25,0xD9, 0xF7,0x05, 0x71,0xC8, 0xF7,0x04,
-0x71,0x98, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x25,0x79, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x25,0x78, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xF0, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x25,0x78, 0x00,0x00, 0x00,0x01, 0xE0,0x00, 0x25,0xDC, 0xF3,0x06,
-0x31,0x9C, 0xF0,0x05, 0x7A,0x88, 0x90,0x02, 0xFF,0x38, 0xF0,0x05, 0x6F,0x50, 0x90,0x02,
-0xFF,0x80, 0xF7,0x04, 0x32,0xC4, 0xF3,0x06, 0x32,0x28, 0xF3,0x05, 0x32,0xD4, 0xF6,0x04,
-0x32,0xC8, 0xF6,0x84, 0x7A,0x2C, 0xF5,0x02, 0x00,0x00, 0x07,0x38, 0x00,0x24, 0xF7,0x05,
-0x7A,0x98, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x22,0xD5, 0xF6,0x05, 0x7A,0x90, 0xC0,0x2A,
-0x5A,0x00, 0xE6,0x00, 0x26,0x20, 0xC0,0x32, 0x6A,0x00, 0xEE,0x00, 0x26,0x21, 0x00,0x00,
-0x00,0x01, 0xF6,0x84, 0x32,0xC0, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x14,0x10, 0x00,0x00,
-0x00,0x01, 0xC7,0x38, 0x60,0x00, 0x97,0x36, 0x14,0x10, 0x87,0x36, 0x14,0x18, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36, 0x14,0x18, 0x87,0x36, 0x14,0x18, 0xF7,0x04,
-0x32,0xB8, 0x00,0x00, 0x00,0x01, 0xC7,0x38, 0x60,0x00, 0xF7,0x05, 0x32,0xB8, 0xF7,0x04,
-0x32,0xBC, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x32,0xBC, 0xF7,0x04,
-0x32,0xBC, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x23,0x45, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x32,0xE0, 0xF5,0x05, 0x7A,0x70, 0x07,0x38, 0x00,0x01, 0xE0,0x00, 0x23,0x48, 0xF7,0x05,
-0x32,0xE0, 0xF5,0x05, 0x7A,0x70, 0xF5,0x84, 0x6F,0x58, 0x00,0x00, 0x00,0x01, 0x20,0x2E,
-0x00,0x21, 0xE2,0x00, 0x23,0x8C, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00,
-0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x23,0x80, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF3,0x02,
-0x00,0x22, 0xE0,0x00, 0x23,0x90, 0xF3,0x05, 0x6F,0x58, 0xF0,0x05, 0x6F,0x54, 0xF5,0x84,
-0x32,0xC0, 0x00,0x00, 0x00,0x01, 0x90,0x2E, 0x00,0x04, 0x87,0x2E, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x02, 0xE6,0x00, 0x24,0xBC, 0x00,0x00, 0x00,0x01, 0x87,0x02,
-0xFF,0x38, 0x03,0x2C, 0x0E,0xF4, 0x93,0x16, 0xFF,0xC4, 0xF7,0x05, 0x7A,0x68, 0x93,0x13,
-0xFF,0xFC, 0x95,0x96, 0xFF,0xB8, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x43,0xA0, 0x97,0x93,
-0xFF,0xFC, 0x85,0x96, 0xFF,0xB8, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x24,0x78, 0x00,0x00,
-0x00,0x01, 0x86,0x2E, 0x0E,0xF8, 0x00,0x00, 0x00,0x01, 0x20,0x32, 0x00,0x10, 0xE2,0x00,
-0x24,0x15, 0xF3,0x02, 0x00,0x4C, 0x87,0x2E, 0x0F,0x00, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0x97,0x2E, 0x0F,0x00, 0x87,0x2E, 0x0F,0x00, 0xE0,0x00, 0x24,0x78, 0x00,0x00,
-0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0xF3,0x06, 0x7A,0x28, 0x93,0x13, 0xFF,0xFC, 0x76,0xB1,
-0x00,0x02, 0xC6,0xB4, 0x60,0x00, 0x77,0x35, 0x00,0x04, 0xC7,0x38, 0x6A,0x00, 0x83,0x16,
-0xFF,0xC4, 0xC7,0x38, 0x60,0x00, 0xC7,0x38, 0x30,0x00, 0x07,0x38, 0x00,0x10, 0x97,0x13,
-0xFF,0xFC, 0x95,0x96, 0xFF,0xB8, 0x96,0x16, 0xFF,0xB4, 0x07,0x88, 0x00,0x08, 0xE0,0x01,
-0x26,0xF8, 0x97,0x93, 0xFF,0xFC, 0x86,0x16, 0xFF,0xB4, 0x85,0x96, 0xFF,0xB8, 0x06,0x30,
-0x00,0x01, 0x20,0x32, 0x00,0x11, 0xE6,0x00, 0x24,0x74, 0x00,0x00, 0x00,0x01, 0xF6,0x02,
-0x00,0x00, 0x96,0x2E, 0x0E,0xF8, 0xF7,0x04, 0x32,0xC0, 0xF3,0x06, 0xE0,0x30, 0xC0,0x3A,
-0x32,0x00, 0xE6,0x00, 0x24,0xBC, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0xE0,0x18, 0x00,0x00,
-0x00,0x01, 0x77,0xB8, 0x00,0x1E, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x00, 0x24,0xBD, 0x00,0x00,
-0x00,0x01, 0x0F,0x81, 0x40,0x00, 0xF7,0x04, 0x79,0xC8, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x79,0xC8, 0xF7,0x04, 0x79,0xC8, 0xF7,0x04, 0x71,0xC4, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x24,0xF9, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04,
-0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39,
-0x00,0x02, 0xF3,0x02, 0x00,0x0A, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x24,0xF8, 0xB3,0x3A,
-0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04, 0x71,0xD4, 0xF6,0x84, 0x71,0xCC, 0x07,0x38,
-0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00, 0x25,0x14, 0xF7,0x05, 0x71,0xD4, 0xF0,0x05,
-0x71,0xD4, 0xF6,0x84, 0x71,0xD4, 0xF7,0x04, 0x71,0xD0, 0xF0,0x05, 0x71,0xC4, 0xC0,0x36,
-0x72,0x00, 0x47,0x0C, 0x00,0x01, 0xF6,0x84, 0x32,0xD0, 0x00,0x00, 0x00,0x01, 0x20,0x36,
-0x00,0x00, 0xE6,0x00, 0x25,0xD9, 0xF7,0x05, 0x71,0xC8, 0xF7,0x04, 0x71,0x98, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x25,0x79, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x25,0x78, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x75,0xF0, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x25,0xD1, 0x00,0x00, 0x00,0x01, 0xF5,0x84, 0x76,0xF8, 0x00,0x00, 0x00,0x01, 0x20,0x2E,
-0x00,0x21, 0xE2,0x00, 0x25,0xC4, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00,
-0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x25,0xB0, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF3,0x02,
-0x00,0x22, 0xF3,0x05, 0x76,0xF8, 0xF3,0x04, 0x77,0x00, 0xE0,0x00, 0x25,0xC8, 0xF3,0x05,
-0x76,0xFC, 0xF0,0x05, 0x76,0xFC, 0xE0,0x00, 0x25,0xD8, 0xF0,0x05, 0x7A,0x78, 0xE0,0x00,
-0x25,0xDC, 0xF3,0x06, 0x31,0x9C, 0xF3,0x06, 0x2E,0xE0, 0xF3,0x05, 0x32,0xD4, 0xF7,0x04,
-0x71,0xC8, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x26,0x8C, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02, 0x00,0x09, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x26,0x8C, 0xB3,0x3A, 0x68,0x02, 0xE0,0x00, 0x26,0x8C, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04,
-0x7A,0x90, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xEE,0x00, 0x26,0x41, 0xC5,0xB4,
-0x00,0x00, 0xC7,0x38, 0x5A,0x00, 0xE0,0x00, 0x26,0x48, 0xF7,0x05, 0x7A,0x90, 0xC5,0xB8,
-0x00,0x00, 0xF0,0x05, 0x7A,0x90, 0xF6,0x84, 0x7A,0x88, 0xF7,0x06, 0x7A,0x28, 0x76,0x35,
-0x00,0x03, 0xA7,0x32, 0x70,0x02, 0x06,0xB4, 0x00,0x01, 0x97,0x16, 0xFF,0xEC, 0x84,0xA6,
-0xFF,0xFC, 0xF7,0x06, 0x7A,0x2C, 0xF3,0x04, 0x7A,0x98, 0x94,0x82, 0xFF,0x3C, 0x93,0x02,
-0xFF,0x40, 0x95,0x82, 0xFF,0x44, 0xB5,0xB2, 0x70,0x02, 0xF7,0x04, 0x7A,0x98, 0xF6,0x85,
-0x7A,0x88, 0xC7,0x38, 0x58,0x00, 0xF7,0x05, 0x7A,0x98, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x02, 0x00,0x01, 0xF7,0x05, 0x7A,0x78, 0xF7,0x06,
-0x30,0x84, 0xF7,0x05, 0x32,0xD4, 0xF7,0x04, 0x32,0xC4, 0x00,0x00, 0x00,0x01, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x06,0x10, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x50, 0xF7,0x04,
-0x32,0xD0, 0xF3,0x02, 0x00,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x2A,0x71, 0x93,0x16,
-0xFF,0xE4, 0xF6,0x84, 0x32,0xC4, 0x86,0x16, 0xFF,0xE4, 0x87,0x36, 0x00,0x08, 0xC3,0x04,
-0x00,0x00, 0xC0,0x3A, 0x32,0x00, 0xE6,0x00, 0x27,0x3C, 0x20,0x32, 0x00,0x00, 0x87,0x36,
-0x00,0x0C, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x32,0x00, 0xE6,0x00, 0x27,0x3C, 0x20,0x32,
-0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x2A,0x70, 0xF3,0x02,
-0x00,0x00, 0xF7,0x04, 0x32,0xC0, 0x93,0x16, 0xFF,0xAC, 0xF5,0x84, 0x32,0xC4, 0x86,0x3A,
-0x14,0x28, 0x03,0xB8, 0x14,0x20, 0x04,0x2C, 0x00,0x08, 0x86,0xBA, 0x14,0x24, 0x00,0x00,
-0x00,0x01, 0xC0,0x32, 0x6A,0x00, 0xEC,0x00, 0x28,0x28, 0x96,0x16, 0xFF,0xEC, 0x77,0x31,
-0x00,0x01, 0xC7,0x38, 0x60,0x00, 0x77,0x39, 0x00,0x02, 0xC6,0x38, 0x38,0x00, 0x06,0x30,
-0x00,0x0C, 0x86,0xB2, 0x00,0x00, 0x87,0x2E, 0x00,0x08, 0x85,0x16, 0xFF,0xAC, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x27,0xB8, 0xC4,0x84, 0x00,0x00, 0x86,0xB2, 0x00,0x04, 0x87,0x2E,
-0x00,0x0C, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x27,0xBC, 0x20,0x2A,
-0x00,0x00, 0xF5,0x02, 0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x00, 0x27,0xC9, 0x00,0x00,
-0x00,0x01, 0xF4,0x82, 0x00,0x00, 0x86,0xB2, 0x00,0x00, 0x87,0x22, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0x28,0x04, 0xF5,0x82, 0x00,0x00, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x28,0x0C, 0x20,0x2E, 0x00,0x00, 0x86,0xB2, 0x00,0x04, 0x87,0x22,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0x28,0x0D, 0x20,0x2E,
-0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0x28,0x1D, 0x20,0x26,
-0x00,0x00, 0xF4,0x82, 0x00,0x01, 0x20,0x26, 0x00,0x00, 0xE6,0x00, 0x28,0x28, 0xF3,0x02,
-0x00,0x01, 0x93,0x16, 0xFF,0xAC, 0x83,0x16, 0xFF,0xAC, 0x00,0x00, 0x00,0x01, 0x20,0x1A,
-0x00,0x00, 0xE6,0x00, 0x28,0x69, 0xF6,0x02, 0x00,0x01, 0x87,0x16, 0xFF,0xEC, 0x00,0x00,
-0x00,0x01, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4,
-0x38,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16, 0xFF,0xF0, 0xE0,0x00,
-0x28,0xD0, 0x96,0x96, 0xFF,0xF4, 0x27,0x14, 0x00,0x14, 0x97,0x13, 0xFF,0xFC, 0x94,0x13,
-0xFF,0xFC, 0x93,0x93, 0xFF,0xFC, 0x93,0x96, 0xFF,0xBC, 0x07,0x88, 0x00,0x08, 0xE0,0x01,
-0x25,0x68, 0x97,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0xBC, 0x20,0x22, 0x00,0x00, 0xE6,0x00,
-0x28,0xCD, 0xF6,0x02, 0x00,0x01, 0x87,0x16, 0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0x76,0xB9,
-0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4, 0x38,0x00, 0x06,0xB4,
-0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16, 0xFF,0xF0, 0x96,0x96, 0xFF,0xF4, 0x97,0x1E,
-0x00,0x08, 0xE0,0x00, 0x28,0xD4, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x00, 0x20,0x32,
-0x00,0x00, 0xE6,0x00, 0x2A,0x70, 0xF3,0x02, 0x00,0x00, 0xF6,0x04, 0x32,0xC0, 0x93,0x16,
-0xFF,0xAC, 0x86,0xB2, 0x14,0x28, 0x03,0xB0, 0x14,0x20, 0x04,0x30, 0x14,0x8C, 0x87,0x32,
-0x14,0x24, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xEC,0x00, 0x29,0xBC, 0x96,0x96,
-0xFF,0xEC, 0x77,0x35, 0x00,0x01, 0xC7,0x38, 0x68,0x00, 0x77,0x39, 0x00,0x02, 0xC5,0xB8,
-0x38,0x00, 0x05,0xAC, 0x00,0x0C, 0x86,0xAE, 0x00,0x00, 0x87,0x32, 0x14,0x8C, 0x85,0x16,
-0xFF,0xAC, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x29,0x4C, 0xC4,0x84, 0x00,0x00, 0x86,0xAE,
-0x00,0x04, 0x87,0x32, 0x14,0x90, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0x29,0x50, 0x20,0x2A, 0x00,0x00, 0xF5,0x02, 0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x00,
-0x29,0x5D, 0x00,0x00, 0x00,0x01, 0xF4,0x82, 0x00,0x00, 0x86,0xAE, 0x00,0x00, 0x87,0x22,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0x29,0x98, 0xF6,0x02,
-0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x29,0xA0, 0x20,0x32, 0x00,0x00, 0x86,0xAE,
-0x00,0x04, 0x87,0x22, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00,
-0x29,0xA1, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0x29,0xB1, 0x20,0x26, 0x00,0x00, 0xF4,0x82, 0x00,0x01, 0x20,0x26, 0x00,0x00, 0xE6,0x00,
-0x29,0xBC, 0xF3,0x02, 0x00,0x01, 0x93,0x16, 0xFF,0xAC, 0x83,0x16, 0xFF,0xAC, 0x00,0x00,
-0x00,0x01, 0x20,0x1A, 0x00,0x00, 0xE6,0x00, 0x29,0xFD, 0xF6,0x02, 0x00,0x01, 0x87,0x16,
-0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5,
-0x00,0x02, 0xC6,0xB4, 0x38,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16,
-0xFF,0xF0, 0xE0,0x00, 0x2A,0x64, 0x96,0x96, 0xFF,0xF4, 0x27,0x14, 0x00,0x14, 0x97,0x13,
-0xFF,0xFC, 0x94,0x13, 0xFF,0xFC, 0x93,0x93, 0xFF,0xFC, 0x93,0x96, 0xFF,0xBC, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x25,0x68, 0x97,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0xBC, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0x2A,0x61, 0xF6,0x02, 0x00,0x01, 0x87,0x16, 0xFF,0xEC, 0x00,0x00,
-0x00,0x01, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4,
-0x38,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16, 0xFF,0xF0, 0x96,0x96,
-0xFF,0xF4, 0x97,0x1E, 0x00,0x08, 0xE0,0x00, 0x2A,0x68, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x00, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x2B,0xCD, 0xF3,0x02, 0x00,0x01, 0xF6,0x84,
-0x32,0xC0, 0x00,0x00, 0x00,0x01, 0x85,0xB6, 0x0E,0xF4, 0x86,0x36, 0x0E,0xF8, 0x20,0x2E,
-0x00,0x10, 0xE2,0x00, 0x2A,0x94, 0x20,0x32, 0x00,0x10, 0xE2,0x00, 0x2A,0xB1, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x0F,0x00, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x0F,0x00, 0x87,0x36, 0x0F,0x00, 0xE0,0x00, 0x2A,0xDC, 0xF7,0x02, 0x00,0x00, 0x07,0x30,
-0x00,0x01, 0xC0,0x3A, 0x5A,0x00, 0xE6,0x00, 0x2A,0xD5, 0xF6,0x82, 0x00,0x00, 0x20,0x32,
-0x00,0x10, 0xE6,0x00, 0x2A,0xD8, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0x2A,0xDC, 0xC7,0x34,
-0x00,0x00, 0xF6,0x82, 0x00,0x01, 0xC7,0x34, 0x00,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x2B,0xCC, 0xF3,0x02, 0x00,0x01, 0xF3,0x04, 0x32,0xCC, 0x00,0x00, 0x00,0x01, 0x93,0x16,
-0xFF,0xDC, 0x93,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x43,0x68, 0x97,0x93,
-0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x2B,0xB4, 0xF3,0x02, 0x00,0x00, 0x83,0x16,
-0xFF,0xDC, 0x00,0x00, 0x00,0x01, 0x86,0x1A, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x32,
-0x00,0x10, 0xE2,0x00, 0x2B,0x49, 0x76,0xB1, 0x00,0x02, 0x87,0x1A, 0x00,0x0C, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x1A, 0x00,0x0C, 0x87,0x1A, 0x00,0x0C, 0xE0,0x00,
-0x2B,0xB4, 0xF3,0x02, 0x00,0x00, 0xF3,0x02, 0x00,0x4C, 0x93,0x13, 0xFF,0xFC, 0xC6,0xB4,
-0x60,0x00, 0x77,0x35, 0x00,0x04, 0xC7,0x38, 0x6A,0x00, 0x83,0x16, 0xFF,0xDC, 0xC7,0x38,
-0x60,0x00, 0xC7,0x38, 0x30,0x00, 0x07,0x38, 0x00,0x10, 0x97,0x13, 0xFF,0xFC, 0xF3,0x06,
-0x7A,0x28, 0x93,0x13, 0xFF,0xFC, 0x96,0x16, 0xFF,0xB4, 0x07,0x88, 0x00,0x08, 0xE0,0x01,
-0x26,0xF8, 0x97,0x93, 0xFF,0xFC, 0x86,0x16, 0xFF,0xB4, 0x00,0x00, 0x00,0x01, 0x06,0x30,
-0x00,0x01, 0x20,0x32, 0x00,0x11, 0xE6,0x00, 0x2B,0xA4, 0x00,0x00, 0x00,0x01, 0xF6,0x02,
-0x00,0x00, 0x83,0x16, 0xFF,0xDC, 0x00,0x00, 0x00,0x01, 0x96,0x1A, 0x00,0x00, 0xF3,0x02,
-0x00,0x01, 0x93,0x16, 0xFF,0xD4, 0x83,0x16, 0xFF,0xD4, 0x00,0x00, 0x00,0x01, 0x20,0x1A,
-0x00,0x00, 0xE6,0x00, 0x2B,0xD0, 0xF3,0x02, 0x00,0x01, 0x93,0x16, 0xFF,0xE4, 0x83,0x16,
-0xFF,0xE4, 0x00,0x00, 0x00,0x01, 0x20,0x1A, 0x00,0x00, 0xE6,0x00, 0x2C,0xED, 0xF6,0x82,
-0x0C,0xAB, 0xF7,0x04, 0x32,0xB4, 0x83,0x16, 0xFF,0xD4, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x32,0xB4, 0xF7,0x04, 0x32,0xB4, 0x20,0x1A, 0x00,0x00, 0xE6,0x00, 0x2C,0x28, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x32,0xC0, 0xF3,0x06, 0xE0,0x30, 0xC0,0x3A, 0x32,0x00, 0xE6,0x00,
-0x2C,0x28, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x32,0xE8, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x32,0xE8, 0xF7,0x04, 0x71,0xC4, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x2C,0x65, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00,
-0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02,
-0x00,0x0A, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x2C,0x64, 0xB3,0x3A, 0x68,0x02, 0xF0,0x05,
-0x2D,0x38, 0xF7,0x04, 0x71,0xD4, 0xF6,0x84, 0x71,0xCC, 0x07,0x38, 0x00,0x01, 0xC0,0x3A,
-0x6A,0x00, 0xE6,0x00, 0x2C,0x80, 0xF7,0x05, 0x71,0xD4, 0xF0,0x05, 0x71,0xD4, 0xF6,0x84,
-0x71,0xD4, 0xF7,0x04, 0x71,0xD0, 0xF0,0x05, 0x71,0xC4, 0xC0,0x36, 0x72,0x00, 0x47,0x0C,
-0x00,0x01, 0xF6,0x84, 0x32,0xD0, 0x00,0x00, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00,
-0x33,0x91, 0xF7,0x05, 0x71,0xC8, 0xF7,0x04, 0x71,0x98, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x33,0x31, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xEC, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x33,0x30, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x75,0xF0, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x33,0x30, 0x00,0x00,
-0x00,0x01, 0xE0,0x00, 0x33,0x94, 0xF3,0x06, 0x31,0x9C, 0xF0,0x05, 0x32,0xE8, 0xF7,0x04,
-0x32,0xC0, 0xF6,0x04, 0x6F,0x54, 0x96,0xBA, 0x00,0x04, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0x2D,0x18, 0xF3,0x02, 0x00,0x0C, 0xF3,0x02, 0x00,0x01, 0xF3,0x05, 0x6F,0x54, 0xE0,0x00,
-0x2D,0x20, 0xF7,0x02, 0x00,0x01, 0xF3,0x05, 0x6F,0x58, 0xF7,0x02, 0x00,0x00, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x2D,0x34, 0xF3,0x06, 0x2F,0x6C, 0xE0,0x00, 0x34,0x44, 0xF3,0x05,
-0x32,0xD4, 0xF5,0x84, 0x7A,0x70, 0x24,0x94, 0x00,0x10, 0x20,0x2E, 0x00,0x01, 0xE6,0x00,
-0x30,0x3C, 0xF5,0x85, 0x7A,0xA0, 0xF7,0x02, 0x00,0x01, 0xF6,0x04, 0x32,0xC8, 0xF7,0x05,
-0x7A,0x70, 0xF7,0x04, 0x32,0xC4, 0xF6,0x84, 0x32,0xC0, 0xF6,0x05, 0x7A,0x2C, 0x90,0x02,
-0xFF,0x80, 0x90,0x02, 0xFF,0x38, 0xF5,0x84, 0x7A,0x28, 0x07,0x38, 0x00,0x24, 0x95,0x82,
-0xFF,0x3C, 0x97,0x02, 0xFF,0x40, 0x96,0x02, 0xFF,0x44, 0x87,0x36, 0x14,0x10, 0x00,0x00,
-0x00,0x01, 0xC7,0x38, 0x60,0x00, 0x97,0x36, 0x14,0x10, 0x87,0x36, 0x14,0x18, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36, 0x14,0x18, 0x87,0x36, 0x14,0x18, 0xF0,0x05,
-0x6F,0x50, 0xF7,0x04, 0x32,0xB8, 0x95,0x96, 0xFF,0xEC, 0xC7,0x38, 0x60,0x00, 0xF7,0x05,
-0x32,0xB8, 0xF7,0x04, 0x32,0xBC, 0xF3,0x06, 0x2F,0xF8, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x32,0xBC, 0xF7,0x04, 0x32,0xBC, 0xF3,0x05, 0x32,0xD4, 0xF7,0x06, 0x0C,0x3E, 0xC0,0x7E,
-0x74,0x00, 0xE6,0x00, 0x2D,0xEC, 0x00,0x00, 0x00,0x01, 0xC0,0x7E, 0x74,0x00, 0xE6,0x00,
-0x2D,0xDD, 0x00,0x00, 0x00,0x01, 0xF7,0x06, 0x0C,0x3E, 0xC7,0x7C, 0x74,0x00, 0x20,0x3A,
-0x00,0x10, 0xE6,0x00, 0x34,0x44, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x32,0xE4, 0xFF,0x82,
-0x00,0x10, 0xF5,0x84, 0x6F,0x58, 0x07,0x38, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00,
-0x2E,0x48, 0xF7,0x05, 0x32,0xE4, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x2E,0x3C, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF3,0x02, 0x00,0x22, 0xE0,0x00,
-0x2E,0x4C, 0xF3,0x05, 0x6F,0x58, 0xF0,0x05, 0x6F,0x54, 0xF5,0x84, 0x32,0xC0, 0x00,0x00,
-0x00,0x01, 0x90,0x2E, 0x00,0x04, 0x87,0x2E, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x02, 0xE6,0x00, 0x2F,0x78, 0x00,0x00, 0x00,0x01, 0x87,0x02, 0xFF,0x38, 0x03,0x2C,
-0x0E,0xF4, 0x93,0x16, 0xFF,0xCC, 0xF7,0x05, 0x7A,0x68, 0x93,0x13, 0xFF,0xFC, 0x95,0x96,
-0xFF,0xB8, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x43,0xA0, 0x97,0x93, 0xFF,0xFC, 0x85,0x96,
-0xFF,0xB8, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x2F,0x34, 0x00,0x00, 0x00,0x01, 0x86,0x2E,
-0x0E,0xF8, 0x00,0x00, 0x00,0x01, 0x20,0x32, 0x00,0x10, 0xE2,0x00, 0x2E,0xD1, 0xF3,0x02,
-0x00,0x4C, 0x87,0x2E, 0x0F,0x00, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x2E,
-0x0F,0x00, 0x87,0x2E, 0x0F,0x00, 0xE0,0x00, 0x2F,0x34, 0x00,0x00, 0x00,0x01, 0x93,0x13,
-0xFF,0xFC, 0xF3,0x06, 0x7A,0x28, 0x93,0x13, 0xFF,0xFC, 0x76,0xB1, 0x00,0x02, 0xC6,0xB4,
-0x60,0x00, 0x77,0x35, 0x00,0x04, 0xC7,0x38, 0x6A,0x00, 0x83,0x16, 0xFF,0xCC, 0xC7,0x38,
-0x60,0x00, 0xC7,0x38, 0x30,0x00, 0x07,0x38, 0x00,0x10, 0x97,0x13, 0xFF,0xFC, 0x95,0x96,
-0xFF,0xB8, 0x96,0x16, 0xFF,0xB4, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x26,0xF8, 0x97,0x93,
-0xFF,0xFC, 0x86,0x16, 0xFF,0xB4, 0x85,0x96, 0xFF,0xB8, 0x06,0x30, 0x00,0x01, 0x20,0x32,
-0x00,0x11, 0xE6,0x00, 0x2F,0x30, 0x00,0x00, 0x00,0x01, 0xF6,0x02, 0x00,0x00, 0x96,0x2E,
-0x0E,0xF8, 0xF7,0x04, 0x32,0xC0, 0xF3,0x06, 0xE0,0x30, 0xC0,0x3A, 0x32,0x00, 0xE6,0x00,
-0x2F,0x78, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0xE0,0x18, 0x00,0x00, 0x00,0x01, 0x77,0xB8,
-0x00,0x1E, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x00, 0x2F,0x79, 0x00,0x00, 0x00,0x01, 0x0F,0x81,
-0x40,0x00, 0xF7,0x04, 0x79,0xC8, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x79,0xC8, 0xF7,0x04, 0x79,0xC8, 0xF7,0x04, 0x71,0xC4, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x2F,0xB5, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00,
-0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02,
-0x00,0x0A, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x2F,0xB4, 0xB3,0x3A, 0x68,0x02, 0xF0,0x05,
-0x2D,0x38, 0xF7,0x04, 0x71,0xD4, 0xF6,0x84, 0x71,0xCC, 0x07,0x38, 0x00,0x01, 0xC0,0x3A,
-0x6A,0x00, 0xE6,0x00, 0x2F,0xD0, 0xF7,0x05, 0x71,0xD4, 0xF0,0x05, 0x71,0xD4, 0xF6,0x84,
-0x71,0xD4, 0xF7,0x04, 0x71,0xD0, 0xF0,0x05, 0x71,0xC4, 0xC0,0x36, 0x72,0x00, 0x47,0x0C,
-0x00,0x01, 0xF6,0x84, 0x32,0xD0, 0x00,0x00, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00,
-0x33,0x91, 0xF7,0x05, 0x71,0xC8, 0xF7,0x04, 0x71,0x98, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x33,0x31, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xEC, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x33,0x30, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x75,0xF0, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x33,0x30, 0x00,0x00,
-0x00,0x01, 0xE0,0x00, 0x33,0x94, 0xF3,0x06, 0x31,0x9C, 0xF0,0x05, 0x7A,0x88, 0x90,0x02,
-0xFF,0x38, 0xF0,0x05, 0x6F,0x50, 0x90,0x02, 0xFF,0x80, 0xF7,0x04, 0x32,0xC4, 0xF3,0x06,
-0x32,0x28, 0xF3,0x05, 0x32,0xD4, 0xF6,0x04, 0x32,0xC8, 0xF6,0x84, 0x7A,0x2C, 0xF5,0x02,
-0x00,0x00, 0x07,0x38, 0x00,0x24, 0xF7,0x05, 0x7A,0x98, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0x30,0x8D, 0xF6,0x05, 0x7A,0x90, 0xC0,0x2A, 0x5A,0x00, 0xE6,0x00, 0x33,0xD8, 0xC0,0x32,
-0x6A,0x00, 0xEE,0x00, 0x33,0xD9, 0x00,0x00, 0x00,0x01, 0xF6,0x84, 0x32,0xC0, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x14,0x10, 0x00,0x00, 0x00,0x01, 0xC7,0x38, 0x60,0x00, 0x97,0x36,
-0x14,0x10, 0x87,0x36, 0x14,0x18, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x14,0x18, 0x87,0x36, 0x14,0x18, 0xF7,0x04, 0x32,0xB8, 0x00,0x00, 0x00,0x01, 0xC7,0x38,
-0x60,0x00, 0xF7,0x05, 0x32,0xB8, 0xF7,0x04, 0x32,0xBC, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x32,0xBC, 0xF7,0x04, 0x32,0xBC, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0x30,0xFD, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x32,0xE0, 0xF5,0x05, 0x7A,0x70, 0x07,0x38,
-0x00,0x01, 0xE0,0x00, 0x31,0x00, 0xF7,0x05, 0x32,0xE0, 0xF5,0x05, 0x7A,0x70, 0xF5,0x84,
-0x6F,0x58, 0x00,0x00, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00, 0x31,0x44, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x31,0x38, 0xB5,0xBA,
-0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF3,0x02, 0x00,0x22, 0xE0,0x00, 0x31,0x48, 0xF3,0x05,
-0x6F,0x58, 0xF0,0x05, 0x6F,0x54, 0xF5,0x84, 0x32,0xC0, 0x00,0x00, 0x00,0x01, 0x90,0x2E,
-0x00,0x04, 0x87,0x2E, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x02, 0xE6,0x00,
-0x32,0x74, 0x00,0x00, 0x00,0x01, 0x87,0x02, 0xFF,0x38, 0x03,0x2C, 0x0E,0xF4, 0x93,0x16,
-0xFF,0xC4, 0xF7,0x05, 0x7A,0x68, 0x93,0x13, 0xFF,0xFC, 0x95,0x96, 0xFF,0xB8, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x43,0xA0, 0x97,0x93, 0xFF,0xFC, 0x85,0x96, 0xFF,0xB8, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0x32,0x30, 0x00,0x00, 0x00,0x01, 0x86,0x2E, 0x0E,0xF8, 0x00,0x00,
-0x00,0x01, 0x20,0x32, 0x00,0x10, 0xE2,0x00, 0x31,0xCD, 0xF3,0x02, 0x00,0x4C, 0x87,0x2E,
-0x0F,0x00, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x2E, 0x0F,0x00, 0x87,0x2E,
-0x0F,0x00, 0xE0,0x00, 0x32,0x30, 0x00,0x00, 0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0xF3,0x06,
-0x7A,0x28, 0x93,0x13, 0xFF,0xFC, 0x76,0xB1, 0x00,0x02, 0xC6,0xB4, 0x60,0x00, 0x77,0x35,
-0x00,0x04, 0xC7,0x38, 0x6A,0x00, 0x83,0x16, 0xFF,0xC4, 0xC7,0x38, 0x60,0x00, 0xC7,0x38,
-0x30,0x00, 0x07,0x38, 0x00,0x10, 0x97,0x13, 0xFF,0xFC, 0x95,0x96, 0xFF,0xB8, 0x96,0x16,
-0xFF,0xB4, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x26,0xF8, 0x97,0x93, 0xFF,0xFC, 0x86,0x16,
-0xFF,0xB4, 0x85,0x96, 0xFF,0xB8, 0x06,0x30, 0x00,0x01, 0x20,0x32, 0x00,0x11, 0xE6,0x00,
-0x32,0x2C, 0x00,0x00, 0x00,0x01, 0xF6,0x02, 0x00,0x00, 0x96,0x2E, 0x0E,0xF8, 0xF7,0x04,
-0x32,0xC0, 0xF3,0x06, 0xE0,0x30, 0xC0,0x3A, 0x32,0x00, 0xE6,0x00, 0x32,0x74, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0xE0,0x18, 0x00,0x00, 0x00,0x01, 0x77,0xB8, 0x00,0x1E, 0x70,0x3E,
-0xFF,0xE1, 0xE6,0x00, 0x32,0x75, 0x00,0x00, 0x00,0x01, 0x0F,0x81, 0x40,0x00, 0xF7,0x04,
-0x79,0xC8, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x79,0xC8, 0xF7,0x04,
-0x79,0xC8, 0xF7,0x04, 0x71,0xC4, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x32,0xB1, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02, 0x00,0x0A, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x32,0xB0, 0xB3,0x3A, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04,
-0x71,0xD4, 0xF6,0x84, 0x71,0xCC, 0x07,0x38, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00,
-0x32,0xCC, 0xF7,0x05, 0x71,0xD4, 0xF0,0x05, 0x71,0xD4, 0xF6,0x84, 0x71,0xD4, 0xF7,0x04,
-0x71,0xD0, 0xF0,0x05, 0x71,0xC4, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0xF6,0x84,
-0x32,0xD0, 0x00,0x00, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x33,0x91, 0xF7,0x05,
-0x71,0xC8, 0xF7,0x04, 0x71,0x98, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x33,0x31, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x33,0x30, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xF0, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x33,0x89, 0x00,0x00, 0x00,0x01, 0xF5,0x84,
-0x76,0xF8, 0x00,0x00, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00, 0x33,0x7C, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x33,0x68, 0xB5,0xBA,
-0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF3,0x02, 0x00,0x22, 0xF3,0x05, 0x76,0xF8, 0xF3,0x04,
-0x77,0x00, 0xE0,0x00, 0x33,0x80, 0xF3,0x05, 0x76,0xFC, 0xF0,0x05, 0x76,0xFC, 0xE0,0x00,
-0x33,0x90, 0xF0,0x05, 0x7A,0x78, 0xE0,0x00, 0x33,0x94, 0xF3,0x06, 0x31,0x9C, 0xF3,0x06,
-0x2E,0xE0, 0xF3,0x05, 0x32,0xD4, 0xF7,0x04, 0x71,0xC8, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x34,0x44, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00,
-0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02,
-0x00,0x09, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x34,0x44, 0xB3,0x3A, 0x68,0x02, 0xE0,0x00,
-0x34,0x44, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04, 0x7A,0x90, 0x00,0x00, 0x00,0x01, 0xC0,0x3A,
-0x6A,0x00, 0xEE,0x00, 0x33,0xF9, 0xC5,0xB4, 0x00,0x00, 0xC7,0x38, 0x5A,0x00, 0xE0,0x00,
-0x34,0x00, 0xF7,0x05, 0x7A,0x90, 0xC5,0xB8, 0x00,0x00, 0xF0,0x05, 0x7A,0x90, 0xF6,0x84,
-0x7A,0x88, 0xF7,0x06, 0x7A,0x28, 0x76,0x35, 0x00,0x03, 0xA7,0x32, 0x70,0x02, 0x06,0xB4,
-0x00,0x01, 0x97,0x16, 0xFF,0xEC, 0x84,0xA6, 0xFF,0xFC, 0xF7,0x06, 0x7A,0x2C, 0xF3,0x04,
-0x7A,0x98, 0x94,0x82, 0xFF,0x3C, 0x93,0x02, 0xFF,0x40, 0x95,0x82, 0xFF,0x44, 0xB5,0xB2,
-0x70,0x02, 0xF7,0x04, 0x7A,0x98, 0xF6,0x85, 0x7A,0x88, 0xC7,0x38, 0x58,0x00, 0xF7,0x05,
-0x7A,0x98, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10,
-0x00,0x20, 0xF5,0x84, 0x7A,0x70, 0x00,0x00, 0x00,0x01, 0x20,0x2E, 0x00,0x01, 0xE6,0x00,
-0x37,0x6C, 0xF5,0x85, 0x7A,0xA0, 0xF7,0x02, 0x00,0x01, 0xF6,0x04, 0x32,0xC8, 0xF7,0x05,
-0x7A,0x70, 0xF7,0x04, 0x32,0xC4, 0xF6,0x84, 0x32,0xC0, 0xF6,0x05, 0x7A,0x2C, 0x90,0x02,
-0xFF,0x80, 0x90,0x02, 0xFF,0x38, 0xF5,0x84, 0x7A,0x28, 0x07,0x38, 0x00,0x24, 0x95,0x82,
-0xFF,0x3C, 0x97,0x02, 0xFF,0x40, 0x96,0x02, 0xFF,0x44, 0x87,0x36, 0x14,0x10, 0x00,0x00,
-0x00,0x01, 0xC7,0x38, 0x60,0x00, 0x97,0x36, 0x14,0x10, 0x87,0x36, 0x14,0x18, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36, 0x14,0x18, 0x87,0x36, 0x14,0x18, 0xF0,0x05,
-0x6F,0x50, 0xF7,0x04, 0x32,0xB8, 0x95,0x96, 0xFF,0xF4, 0xC7,0x38, 0x60,0x00, 0xF7,0x05,
-0x32,0xB8, 0xF7,0x04, 0x32,0xBC, 0xF4,0x86, 0x2F,0xF8, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x32,0xBC, 0xF7,0x04, 0x32,0xBC, 0xF4,0x85, 0x32,0xD4, 0xF7,0x06, 0x0C,0x3E, 0xC0,0x7E,
-0x74,0x00, 0xE6,0x00, 0x35,0x1C, 0x00,0x00, 0x00,0x01, 0xC0,0x7E, 0x74,0x00, 0xE6,0x00,
-0x35,0x0D, 0x00,0x00, 0x00,0x01, 0xF7,0x06, 0x0C,0x3E, 0xC7,0x7C, 0x74,0x00, 0x20,0x3A,
-0x00,0x10, 0xE6,0x00, 0x3B,0x70, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x32,0xE4, 0xFF,0x82,
-0x00,0x10, 0xF5,0x84, 0x6F,0x58, 0x07,0x38, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00,
-0x35,0x78, 0xF7,0x05, 0x32,0xE4, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x35,0x6C, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF4,0x82, 0x00,0x22, 0xE0,0x00,
-0x35,0x7C, 0xF4,0x85, 0x6F,0x58, 0xF0,0x05, 0x6F,0x54, 0xF5,0x84, 0x32,0xC0, 0x00,0x00,
-0x00,0x01, 0x90,0x2E, 0x00,0x04, 0x87,0x2E, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x02, 0xE6,0x00, 0x36,0xA8, 0x00,0x00, 0x00,0x01, 0x87,0x02, 0xFF,0x38, 0x04,0xAC,
-0x0E,0xF4, 0x94,0x96, 0xFF,0xEC, 0xF7,0x05, 0x7A,0x68, 0x94,0x93, 0xFF,0xFC, 0x95,0x96,
-0xFF,0xDC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x43,0xA0, 0x97,0x93, 0xFF,0xFC, 0x85,0x96,
-0xFF,0xDC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x36,0x64, 0x00,0x00, 0x00,0x01, 0x86,0x2E,
-0x0E,0xF8, 0x00,0x00, 0x00,0x01, 0x20,0x32, 0x00,0x10, 0xE2,0x00, 0x36,0x01, 0xF4,0x82,
-0x00,0x4C, 0x87,0x2E, 0x0F,0x00, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x2E,
-0x0F,0x00, 0x87,0x2E, 0x0F,0x00, 0xE0,0x00, 0x36,0x64, 0x00,0x00, 0x00,0x01, 0x94,0x93,
-0xFF,0xFC, 0xF4,0x86, 0x7A,0x28, 0x94,0x93, 0xFF,0xFC, 0x76,0xB1, 0x00,0x02, 0xC6,0xB4,
-0x60,0x00, 0x77,0x35, 0x00,0x04, 0xC7,0x38, 0x6A,0x00, 0x84,0x96, 0xFF,0xEC, 0xC7,0x38,
-0x60,0x00, 0xC7,0x38, 0x48,0x00, 0x07,0x38, 0x00,0x10, 0x97,0x13, 0xFF,0xFC, 0x95,0x96,
-0xFF,0xDC, 0x96,0x16, 0xFF,0xD8, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x26,0xF8, 0x97,0x93,
-0xFF,0xFC, 0x86,0x16, 0xFF,0xD8, 0x85,0x96, 0xFF,0xDC, 0x06,0x30, 0x00,0x01, 0x20,0x32,
-0x00,0x11, 0xE6,0x00, 0x36,0x60, 0x00,0x00, 0x00,0x01, 0xF6,0x02, 0x00,0x00, 0x96,0x2E,
-0x0E,0xF8, 0xF7,0x04, 0x32,0xC0, 0xF4,0x86, 0xE0,0x30, 0xC0,0x3A, 0x4A,0x00, 0xE6,0x00,
-0x36,0xA8, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0xE0,0x18, 0x00,0x00, 0x00,0x01, 0x77,0xB8,
-0x00,0x1E, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x00, 0x36,0xA9, 0x00,0x00, 0x00,0x01, 0x0F,0x81,
-0x40,0x00, 0xF7,0x04, 0x79,0xC8, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x79,0xC8, 0xF7,0x04, 0x79,0xC8, 0xF7,0x04, 0x71,0xC4, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x36,0xE5, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00,
-0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF4,0x82,
-0x00,0x0A, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x36,0xE4, 0xB4,0xBA, 0x68,0x02, 0xF0,0x05,
-0x2D,0x38, 0xF7,0x04, 0x71,0xD4, 0xF6,0x84, 0x71,0xCC, 0x07,0x38, 0x00,0x01, 0xC0,0x3A,
-0x6A,0x00, 0xE6,0x00, 0x37,0x00, 0xF7,0x05, 0x71,0xD4, 0xF0,0x05, 0x71,0xD4, 0xF6,0x84,
-0x71,0xD4, 0xF7,0x04, 0x71,0xD0, 0xF0,0x05, 0x71,0xC4, 0xC0,0x36, 0x72,0x00, 0x47,0x0C,
-0x00,0x01, 0xF6,0x84, 0x32,0xD0, 0x00,0x00, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00,
-0x3A,0xC1, 0xF7,0x05, 0x71,0xC8, 0xF7,0x04, 0x71,0x98, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x3A,0x61, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xEC, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x3A,0x60, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x75,0xF0, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x3A,0x60, 0x00,0x00,
-0x00,0x01, 0xE0,0x00, 0x3A,0xC4, 0xF4,0x86, 0x31,0x9C, 0xF0,0x05, 0x7A,0x88, 0x90,0x02,
-0xFF,0x38, 0xF0,0x05, 0x6F,0x50, 0x90,0x02, 0xFF,0x80, 0xF7,0x04, 0x32,0xC4, 0xF4,0x86,
-0x32,0x28, 0xF4,0x85, 0x32,0xD4, 0xF6,0x04, 0x32,0xC8, 0xF6,0x84, 0x7A,0x2C, 0xF5,0x02,
-0x00,0x00, 0x07,0x38, 0x00,0x24, 0xF7,0x05, 0x7A,0x98, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0x37,0xBD, 0xF6,0x05, 0x7A,0x90, 0xC0,0x2A, 0x5A,0x00, 0xE6,0x00, 0x3B,0x08, 0xC0,0x32,
-0x6A,0x00, 0xEE,0x00, 0x3B,0x09, 0x00,0x00, 0x00,0x01, 0xF6,0x84, 0x32,0xC0, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x14,0x10, 0x00,0x00, 0x00,0x01, 0xC7,0x38, 0x60,0x00, 0x97,0x36,
-0x14,0x10, 0x87,0x36, 0x14,0x18, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x14,0x18, 0x87,0x36, 0x14,0x18, 0xF7,0x04, 0x32,0xB8, 0x00,0x00, 0x00,0x01, 0xC7,0x38,
-0x60,0x00, 0xF7,0x05, 0x32,0xB8, 0xF7,0x04, 0x32,0xBC, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x32,0xBC, 0xF7,0x04, 0x32,0xBC, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0x38,0x2D, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x32,0xE0, 0xF5,0x05, 0x7A,0x70, 0x07,0x38,
-0x00,0x01, 0xE0,0x00, 0x38,0x30, 0xF7,0x05, 0x32,0xE0, 0xF5,0x05, 0x7A,0x70, 0xF5,0x84,
-0x6F,0x58, 0x00,0x00, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00, 0x38,0x74, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x38,0x68, 0xB5,0xBA,
-0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF4,0x82, 0x00,0x22, 0xE0,0x00, 0x38,0x78, 0xF4,0x85,
-0x6F,0x58, 0xF0,0x05, 0x6F,0x54, 0xF5,0x84, 0x32,0xC0, 0x00,0x00, 0x00,0x01, 0x90,0x2E,
-0x00,0x04, 0x87,0x2E, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x02, 0xE6,0x00,
-0x39,0xA4, 0x00,0x00, 0x00,0x01, 0x87,0x02, 0xFF,0x38, 0x04,0xAC, 0x0E,0xF4, 0x94,0x96,
-0xFF,0xE4, 0xF7,0x05, 0x7A,0x68, 0x94,0x93, 0xFF,0xFC, 0x95,0x96, 0xFF,0xDC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x43,0xA0, 0x97,0x93, 0xFF,0xFC, 0x85,0x96, 0xFF,0xDC, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0x39,0x60, 0x00,0x00, 0x00,0x01, 0x86,0x2E, 0x0E,0xF8, 0x00,0x00,
-0x00,0x01, 0x20,0x32, 0x00,0x10, 0xE2,0x00, 0x38,0xFD, 0xF4,0x82, 0x00,0x4C, 0x87,0x2E,
-0x0F,0x00, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x2E, 0x0F,0x00, 0x87,0x2E,
-0x0F,0x00, 0xE0,0x00, 0x39,0x60, 0x00,0x00, 0x00,0x01, 0x94,0x93, 0xFF,0xFC, 0xF4,0x86,
-0x7A,0x28, 0x94,0x93, 0xFF,0xFC, 0x76,0xB1, 0x00,0x02, 0xC6,0xB4, 0x60,0x00, 0x77,0x35,
-0x00,0x04, 0xC7,0x38, 0x6A,0x00, 0x84,0x96, 0xFF,0xE4, 0xC7,0x38, 0x60,0x00, 0xC7,0x38,
-0x48,0x00, 0x07,0x38, 0x00,0x10, 0x97,0x13, 0xFF,0xFC, 0x95,0x96, 0xFF,0xDC, 0x96,0x16,
-0xFF,0xD8, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x26,0xF8, 0x97,0x93, 0xFF,0xFC, 0x86,0x16,
-0xFF,0xD8, 0x85,0x96, 0xFF,0xDC, 0x06,0x30, 0x00,0x01, 0x20,0x32, 0x00,0x11, 0xE6,0x00,
-0x39,0x5C, 0x00,0x00, 0x00,0x01, 0xF6,0x02, 0x00,0x00, 0x96,0x2E, 0x0E,0xF8, 0xF7,0x04,
-0x32,0xC0, 0xF4,0x86, 0xE0,0x30, 0xC0,0x3A, 0x4A,0x00, 0xE6,0x00, 0x39,0xA4, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0xE0,0x18, 0x00,0x00, 0x00,0x01, 0x77,0xB8, 0x00,0x1E, 0x70,0x3E,
-0xFF,0xE1, 0xE6,0x00, 0x39,0xA5, 0x00,0x00, 0x00,0x01, 0x0F,0x81, 0x40,0x00, 0xF7,0x04,
-0x79,0xC8, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x79,0xC8, 0xF7,0x04,
-0x79,0xC8, 0xF7,0x04, 0x71,0xC4, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x39,0xE1, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF4,0x82, 0x00,0x0A, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x39,0xE0, 0xB4,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04,
-0x71,0xD4, 0xF6,0x84, 0x71,0xCC, 0x07,0x38, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00,
-0x39,0xFC, 0xF7,0x05, 0x71,0xD4, 0xF0,0x05, 0x71,0xD4, 0xF6,0x84, 0x71,0xD4, 0xF7,0x04,
-0x71,0xD0, 0xF0,0x05, 0x71,0xC4, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0xF6,0x84,
-0x32,0xD0, 0x00,0x00, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x3A,0xC1, 0xF7,0x05,
-0x71,0xC8, 0xF7,0x04, 0x71,0x98, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x3A,0x61, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x3A,0x60, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xF0, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x3A,0xB9, 0x00,0x00, 0x00,0x01, 0xF5,0x84,
-0x76,0xF8, 0x00,0x00, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00, 0x3A,0xAC, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x3A,0x98, 0xB5,0xBA,
-0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF4,0x82, 0x00,0x22, 0xF4,0x85, 0x76,0xF8, 0xF4,0x84,
-0x77,0x00, 0xE0,0x00, 0x3A,0xB0, 0xF4,0x85, 0x76,0xFC, 0xF0,0x05, 0x76,0xFC, 0xE0,0x00,
-0x3A,0xC0, 0xF0,0x05, 0x7A,0x78, 0xE0,0x00, 0x3A,0xC4, 0xF4,0x86, 0x31,0x9C, 0xF4,0x86,
-0x2E,0xE0, 0xF4,0x85, 0x32,0xD4, 0xF7,0x04, 0x71,0xC8, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x3B,0x70, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00,
-0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF4,0x82,
-0x00,0x09, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x3B,0x70, 0xB4,0xBA, 0x68,0x02, 0xE0,0x00,
-0x3B,0x70, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04, 0x7A,0x90, 0x00,0x00, 0x00,0x01, 0xC0,0x3A,
-0x6A,0x00, 0xEE,0x00, 0x3B,0x29, 0xC5,0xB4, 0x00,0x00, 0xC7,0x38, 0x5A,0x00, 0xE0,0x00,
-0x3B,0x30, 0xF7,0x05, 0x7A,0x90, 0xC5,0xB8, 0x00,0x00, 0xF0,0x05, 0x7A,0x90, 0xF7,0x04,
-0x7A,0x88, 0xF6,0x86, 0x7A,0x28, 0x76,0x39, 0x00,0x03, 0xA6,0xB2, 0x68,0x02, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x7A,0x88, 0xF7,0x04, 0x7A,0x98, 0x96,0x96, 0xFF,0xF4, 0x96,0x82,
-0xFF,0x3C, 0xF4,0x84, 0x7A,0x98, 0xF6,0x86, 0x7A,0x2C, 0xC7,0x38, 0x58,0x00, 0x94,0x82,
-0xFF,0x40, 0x95,0x82, 0xFF,0x44, 0xB5,0xB2, 0x68,0x02, 0xF7,0x05, 0x7A,0x98, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x18, 0xF5,0x04,
-0x7A,0x88, 0xF7,0x06, 0x7A,0x2C, 0xF5,0x84, 0x7A,0x90, 0x76,0xA9, 0x00,0x03, 0xA6,0xB6,
-0x70,0x02, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0x3B,0xCD, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x7A,0xA0, 0x00,0x00, 0x00,0x01, 0xC0,0x2A, 0x72,0x00, 0xE6,0x00, 0x3F,0x18, 0xC0,0x2E,
-0x6A,0x00, 0xEE,0x00, 0x3F,0x19, 0x00,0x00, 0x00,0x01, 0xF6,0x84, 0x32,0xC0, 0xF6,0x04,
-0x32,0xC8, 0x87,0x36, 0x14,0x10, 0x00,0x00, 0x00,0x01, 0xC7,0x38, 0x60,0x00, 0x97,0x36,
-0x14,0x10, 0x87,0x36, 0x14,0x18, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x14,0x18, 0x87,0x36, 0x14,0x18, 0xF7,0x04, 0x32,0xB8, 0x00,0x00, 0x00,0x01, 0xC7,0x38,
-0x60,0x00, 0xF7,0x05, 0x32,0xB8, 0xF7,0x04, 0x32,0xBC, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x32,0xBC, 0xF7,0x04, 0x32,0xBC, 0x20,0x2E, 0x00,0x00, 0xE6,0x00,
-0x3C,0x3D, 0xF6,0x82, 0x00,0x00, 0xF7,0x04, 0x32,0xE0, 0xF6,0x85, 0x7A,0x70, 0x07,0x38,
-0x00,0x01, 0xE0,0x00, 0x3C,0x40, 0xF7,0x05, 0x32,0xE0, 0xF5,0x05, 0x7A,0x70, 0xF5,0x84,
-0x6F,0x58, 0x00,0x00, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00, 0x3C,0x84, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x3C,0x78, 0xB5,0xBA,
-0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF4,0x82, 0x00,0x22, 0xE0,0x00, 0x3C,0x88, 0xF4,0x85,
-0x6F,0x58, 0xF0,0x05, 0x6F,0x54, 0xF5,0x84, 0x32,0xC0, 0x00,0x00, 0x00,0x01, 0x90,0x2E,
-0x00,0x04, 0x87,0x2E, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x02, 0xE6,0x00,
-0x3D,0xB4, 0x00,0x00, 0x00,0x01, 0x87,0x02, 0xFF,0x38, 0x04,0xAC, 0x0E,0xF4, 0x94,0x96,
-0xFF,0xEC, 0xF7,0x05, 0x7A,0x68, 0x94,0x93, 0xFF,0xFC, 0x95,0x96, 0xFF,0xE4, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x43,0xA0, 0x97,0x93, 0xFF,0xFC, 0x85,0x96, 0xFF,0xE4, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0x3D,0x70, 0x00,0x00, 0x00,0x01, 0x86,0x2E, 0x0E,0xF8, 0x00,0x00,
-0x00,0x01, 0x20,0x32, 0x00,0x10, 0xE2,0x00, 0x3D,0x0D, 0xF4,0x82, 0x00,0x4C, 0x87,0x2E,
-0x0F,0x00, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x2E, 0x0F,0x00, 0x87,0x2E,
-0x0F,0x00, 0xE0,0x00, 0x3D,0x70, 0x00,0x00, 0x00,0x01, 0x94,0x93, 0xFF,0xFC, 0xF4,0x86,
-0x7A,0x28, 0x94,0x93, 0xFF,0xFC, 0x76,0xB1, 0x00,0x02, 0xC6,0xB4, 0x60,0x00, 0x77,0x35,
-0x00,0x04, 0xC7,0x38, 0x6A,0x00, 0x84,0x96, 0xFF,0xEC, 0xC7,0x38, 0x60,0x00, 0xC7,0x38,
-0x48,0x00, 0x07,0x38, 0x00,0x10, 0x97,0x13, 0xFF,0xFC, 0x95,0x96, 0xFF,0xE4, 0x96,0x16,
-0xFF,0xE0, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x26,0xF8, 0x97,0x93, 0xFF,0xFC, 0x86,0x16,
-0xFF,0xE0, 0x85,0x96, 0xFF,0xE4, 0x06,0x30, 0x00,0x01, 0x20,0x32, 0x00,0x11, 0xE6,0x00,
-0x3D,0x6C, 0x00,0x00, 0x00,0x01, 0xF6,0x02, 0x00,0x00, 0x96,0x2E, 0x0E,0xF8, 0xF7,0x04,
-0x32,0xC0, 0xF4,0x86, 0xE0,0x30, 0xC0,0x3A, 0x4A,0x00, 0xE6,0x00, 0x3D,0xB4, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0xE0,0x18, 0x00,0x00, 0x00,0x01, 0x77,0xB8, 0x00,0x1E, 0x70,0x3E,
-0xFF,0xE1, 0xE6,0x00, 0x3D,0xB5, 0x00,0x00, 0x00,0x01, 0x0F,0x81, 0x40,0x00, 0xF7,0x04,
-0x79,0xC8, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x79,0xC8, 0xF7,0x04,
-0x79,0xC8, 0xF7,0x04, 0x71,0xC4, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x3D,0xF1, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF4,0x82, 0x00,0x0A, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x3D,0xF0, 0xB4,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04,
-0x71,0xD4, 0xF6,0x84, 0x71,0xCC, 0x07,0x38, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00,
-0x3E,0x0C, 0xF7,0x05, 0x71,0xD4, 0xF0,0x05, 0x71,0xD4, 0xF6,0x84, 0x71,0xD4, 0xF7,0x04,
-0x71,0xD0, 0xF0,0x05, 0x71,0xC4, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0xF6,0x84,
-0x32,0xD0, 0x00,0x00, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x3E,0xD1, 0xF7,0x05,
-0x71,0xC8, 0xF7,0x04, 0x71,0x98, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x3E,0x71, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x3E,0x70, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xF0, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x3E,0xC9, 0x00,0x00, 0x00,0x01, 0xF5,0x84,
-0x76,0xF8, 0x00,0x00, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00, 0x3E,0xBC, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x3E,0xA8, 0xB5,0xBA,
-0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF4,0x82, 0x00,0x22, 0xF4,0x85, 0x76,0xF8, 0xF4,0x84,
-0x77,0x00, 0xE0,0x00, 0x3E,0xC0, 0xF4,0x85, 0x76,0xFC, 0xF0,0x05, 0x76,0xFC, 0xE0,0x00,
-0x3E,0xD0, 0xF0,0x05, 0x7A,0x78, 0xE0,0x00, 0x3E,0xD4, 0xF4,0x86, 0x31,0x9C, 0xF4,0x86,
-0x2E,0xE0, 0xF4,0x85, 0x32,0xD4, 0xF7,0x04, 0x71,0xC8, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x3F,0x80, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00,
-0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF4,0x82,
-0x00,0x09, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x3F,0x80, 0xB4,0xBA, 0x68,0x02, 0xE0,0x00,
-0x3F,0x80, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04, 0x7A,0x90, 0x00,0x00, 0x00,0x01, 0xC0,0x3A,
-0x6A,0x00, 0xEE,0x00, 0x3F,0x39, 0xC5,0xB4, 0x00,0x00, 0xC7,0x38, 0x5A,0x00, 0xE0,0x00,
-0x3F,0x40, 0xF7,0x05, 0x7A,0x90, 0xC5,0xB8, 0x00,0x00, 0xF0,0x05, 0x7A,0x90, 0xF7,0x04,
-0x7A,0x88, 0xF6,0x86, 0x7A,0x28, 0x76,0x39, 0x00,0x03, 0xA6,0xB2, 0x68,0x02, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x7A,0x88, 0xF7,0x04, 0x7A,0x98, 0x96,0x96, 0xFF,0xF4, 0x96,0x82,
-0xFF,0x3C, 0xF4,0x84, 0x7A,0x98, 0xF6,0x86, 0x7A,0x2C, 0xC7,0x38, 0x58,0x00, 0x94,0x82,
-0xFF,0x40, 0x95,0x82, 0xFF,0x44, 0xB5,0xB2, 0x68,0x02, 0xF7,0x05, 0x7A,0x98, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x10, 0xF5,0x84,
-0x6F,0x58, 0x00,0x00, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00, 0x3F,0xE4, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x3F,0xD8, 0xB5,0xBA,
-0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF5,0x02, 0x00,0x22, 0xE0,0x00, 0x3F,0xE8, 0xF5,0x05,
-0x6F,0x58, 0xF0,0x05, 0x6F,0x54, 0xF5,0x84, 0x32,0xC0, 0x00,0x00, 0x00,0x01, 0x90,0x2E,
-0x00,0x04, 0x87,0x2E, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x02, 0xE6,0x00,
-0x41,0x14, 0x00,0x00, 0x00,0x01, 0x87,0x02, 0xFF,0x38, 0x05,0x2C, 0x0E,0xF4, 0x95,0x16,
-0xFF,0xF4, 0xF7,0x05, 0x7A,0x68, 0x95,0x13, 0xFF,0xFC, 0x95,0x96, 0xFF,0xEC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x43,0xA0, 0x97,0x93, 0xFF,0xFC, 0x85,0x96, 0xFF,0xEC, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0x40,0xD0, 0x00,0x00, 0x00,0x01, 0x86,0x2E, 0x0E,0xF8, 0x00,0x00,
-0x00,0x01, 0x20,0x32, 0x00,0x10, 0xE2,0x00, 0x40,0x6D, 0xF5,0x02, 0x00,0x4C, 0x87,0x2E,
-0x0F,0x00, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x2E, 0x0F,0x00, 0x87,0x2E,
-0x0F,0x00, 0xE0,0x00, 0x40,0xD0, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0xF5,0x06,
-0x7A,0x28, 0x95,0x13, 0xFF,0xFC, 0x76,0xB1, 0x00,0x02, 0xC6,0xB4, 0x60,0x00, 0x77,0x35,
-0x00,0x04, 0xC7,0x38, 0x6A,0x00, 0x85,0x16, 0xFF,0xF4, 0xC7,0x38, 0x60,0x00, 0xC7,0x38,
-0x50,0x00, 0x07,0x38, 0x00,0x10, 0x97,0x13, 0xFF,0xFC, 0x95,0x96, 0xFF,0xEC, 0x96,0x16,
-0xFF,0xE8, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x26,0xF8, 0x97,0x93, 0xFF,0xFC, 0x86,0x16,
-0xFF,0xE8, 0x85,0x96, 0xFF,0xEC, 0x06,0x30, 0x00,0x01, 0x20,0x32, 0x00,0x11, 0xE6,0x00,
-0x40,0xCC, 0x00,0x00, 0x00,0x01, 0xF6,0x02, 0x00,0x00, 0x96,0x2E, 0x0E,0xF8, 0xF7,0x04,
-0x32,0xC0, 0xF5,0x06, 0xE0,0x30, 0xC0,0x3A, 0x52,0x00, 0xE6,0x00, 0x41,0x14, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0xE0,0x18, 0x00,0x00, 0x00,0x01, 0x77,0xB8, 0x00,0x1E, 0x70,0x3E,
-0xFF,0xE1, 0xE6,0x00, 0x41,0x15, 0x00,0x00, 0x00,0x01, 0x0F,0x81, 0x40,0x00, 0xF7,0x04,
-0x79,0xC8, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x79,0xC8, 0xF7,0x04,
-0x79,0xC8, 0xF7,0x04, 0x71,0xC4, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x41,0x51, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF5,0x02, 0x00,0x0A, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x41,0x50, 0xB5,0x3A, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04,
-0x71,0xD4, 0xF6,0x84, 0x71,0xCC, 0x07,0x38, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00,
-0x41,0x6C, 0xF7,0x05, 0x71,0xD4, 0xF0,0x05, 0x71,0xD4, 0xF6,0x84, 0x71,0xD4, 0xF7,0x04,
-0x71,0xD0, 0xF0,0x05, 0x71,0xC4, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0xF6,0x84,
-0x32,0xD0, 0x00,0x00, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x42,0x31, 0xF7,0x05,
-0x71,0xC8, 0xF7,0x04, 0x71,0x98, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x41,0xD1, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x41,0xD0, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xF0, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x42,0x29, 0x00,0x00, 0x00,0x01, 0xF5,0x84,
-0x76,0xF8, 0x00,0x00, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00, 0x42,0x1C, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x42,0x08, 0xB5,0xBA,
-0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF5,0x02, 0x00,0x22, 0xF5,0x05, 0x76,0xF8, 0xF5,0x04,
-0x77,0x00, 0xE0,0x00, 0x42,0x20, 0xF5,0x05, 0x76,0xFC, 0xF0,0x05, 0x76,0xFC, 0xE0,0x00,
-0x42,0x30, 0xF0,0x05, 0x7A,0x78, 0xE0,0x00, 0x42,0x34, 0xF5,0x06, 0x31,0x9C, 0xF5,0x06,
-0x2E,0xE0, 0xF5,0x05, 0x32,0xD4, 0xF7,0x04, 0x71,0xC8, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x42,0x74, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00,
-0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF5,0x02,
-0x00,0x09, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x42,0x74, 0xB5,0x3A, 0x68,0x02, 0xF0,0x05,
-0x2D,0x38, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x06,
-0x32,0xD4, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x2E,0xE0, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x32,0xD4, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x2F,0x6C, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x32,0xD4, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x2F,0xF8, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x06, 0x32,0xD4, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x30,0x84, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06,
-0x32,0xD4, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x31,0x10, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x32,0xD4, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x31,0x9C, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x32,0xD4, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x32,0x28, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93,
-0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x87,0x16,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x86,0xBA, 0x00,0x00, 0x87,0x3A, 0x00,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0x44,0x0C, 0x00,0x01, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x85,0x96, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x86,0x2E,
-0x00,0x00, 0x86,0xAE, 0x00,0x04, 0x20,0x32, 0x00,0x10, 0xE2,0x00, 0x43,0xD0, 0x00,0x00,
-0x00,0x01, 0x20,0x36, 0x00,0x10, 0xE2,0x00, 0x43,0xED, 0x07,0x34, 0x00,0x01, 0x87,0x2E,
-0x00,0x0C, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x2E, 0x00,0x0C, 0x87,0x2E,
-0x00,0x0C, 0xE0,0x00, 0x44,0x14, 0xF4,0x02, 0x00,0x00, 0xC0,0x3A, 0x62,0x00, 0xE6,0x00,
-0x44,0x11, 0xF4,0x02, 0x00,0x00, 0x20,0x36, 0x00,0x10, 0xE6,0x00, 0x44,0x14, 0x00,0x00,
-0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x44,0x14, 0x00,0x00, 0x00,0x01, 0xF4,0x02,
-0x00,0x01, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x02,
-0x00,0x01, 0xF7,0x05, 0x35,0x24, 0xF7,0x04, 0x6F,0x44, 0x00,0x00, 0x00,0x01, 0xF7,0x05,
-0x35,0x28, 0xF7,0x06, 0x32,0xF4, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x35,0x30, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x48, 0x97,0x93, 0xFF,0xFC, 0xF7,0x02,
-0x45,0x04, 0x97,0x13, 0xFF,0xFC, 0xF7,0x02, 0x00,0x0D, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x32,0xF4, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x02, 0x4A,0x04, 0x97,0x13, 0xFF,0xFC, 0xF7,0x02, 0x00,0x0F, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x33,0x80, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF7,0x02, 0x4E,0xEC, 0x97,0x13, 0xFF,0xFC, 0xF7,0x02,
-0x00,0x08, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x34,0x0C, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF7,0x02, 0x57,0x64, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x02, 0x00,0x07, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x34,0x98, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x14, 0xF7,0x04,
-0x75,0xF8, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x45,0x2D, 0xF6,0x86,
-0x75,0xF8, 0xE0,0x00, 0x45,0x44, 0xF7,0x02, 0x00,0x00, 0xF7,0x04, 0x76,0x04, 0x00,0x00,
-0x00,0x01, 0x77,0x39, 0x00,0x02, 0xC7,0x38, 0x68,0x00, 0x87,0x3A, 0x00,0x18, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x45,0x5C, 0xF7,0x05, 0x35,0x48, 0xF4,0x86,
-0x33,0x80, 0xE0,0x00, 0x49,0xF0, 0xF4,0x85, 0x35,0x30, 0xF7,0x04, 0x6F,0x54, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x45,0x80, 0xF4,0x82, 0x00,0x08, 0xF4,0x82,
-0x00,0x01, 0xF4,0x85, 0x6F,0x54, 0xE0,0x00, 0x45,0x88, 0xF7,0x02, 0x00,0x01, 0xF4,0x85,
-0x6F,0x58, 0xF7,0x02, 0x00,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x45,0xA0, 0xF4,0x82,
-0x00,0x04, 0xF4,0x86, 0x34,0x0C, 0xE0,0x00, 0x49,0xF0, 0xF4,0x85, 0x35,0x30, 0xF6,0x84,
-0x35,0x48, 0xF6,0x04, 0x35,0x2C, 0xF4,0xB7, 0x28,0x00, 0x07,0x34, 0x00,0x02, 0xF4,0x82,
-0x00,0x01, 0xF4,0xBB, 0x28,0x00, 0x87,0x32, 0x00,0x8C, 0xF4,0x82, 0x00,0x01, 0x97,0x36,
-0x00,0x18, 0x87,0x32, 0x00,0x90, 0xF4,0x85, 0x6F,0x50, 0x97,0x36, 0x00,0x04, 0x84,0xB2,
-0x00,0x84, 0x00,0x00, 0x00,0x01, 0x94,0xB6, 0x00,0x10, 0x84,0xB2, 0x00,0x88, 0x00,0x00,
-0x00,0x01, 0x94,0xB6, 0x00,0x14, 0x84,0xB6, 0x00,0x10, 0x00,0x00, 0x00,0x01, 0x94,0xB6,
-0x00,0x08, 0x84,0xB6, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x94,0xB6, 0x00,0x0C, 0x84,0xB2,
-0x00,0x98, 0x00,0x00, 0x00,0x01, 0xF4,0x85, 0x35,0x54, 0xF4,0x82, 0x00,0x01, 0x94,0x82,
-0xFF,0x80, 0xF5,0x04, 0x35,0x54, 0xF4,0x86, 0x34,0x98, 0xF4,0x85, 0x35,0x30, 0x95,0x02,
-0xFF,0x38, 0x85,0xB2, 0x00,0x00, 0x06,0xB4, 0x00,0x24, 0x95,0x82, 0xFF,0x3C, 0x96,0x82,
-0xFF,0x40, 0x87,0x32, 0x00,0x04, 0xF6,0x85, 0x35,0x50, 0x97,0x02, 0xFF,0x44, 0x86,0xB2,
-0x00,0x04, 0xF0,0x05, 0x35,0x4C, 0xF7,0x04, 0x35,0x40, 0x95,0x16, 0xFF,0xF4, 0x95,0x96,
-0xFF,0xF4, 0xC7,0x38, 0x68,0x00, 0xF7,0x05, 0x35,0x40, 0xF5,0x84, 0x35,0x28, 0x86,0xB2,
-0x00,0x04, 0x87,0x2E, 0x14,0x14, 0x00,0x00, 0x00,0x01, 0xC7,0x38, 0x68,0x00, 0x97,0x2E,
-0x14,0x14, 0x87,0x32, 0x00,0x80, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x01, 0xEE,0x00,
-0x49,0xF0, 0xF7,0x06, 0x0C,0x3E, 0xC0,0x7E, 0x74,0x00, 0xE6,0x00, 0x46,0xA4, 0x00,0x00,
-0x00,0x01, 0xC0,0x7E, 0x74,0x00, 0xE6,0x00, 0x46,0x95, 0x00,0x00, 0x00,0x01, 0xF7,0x06,
-0x0C,0x3E, 0xC7,0x7C, 0x74,0x00, 0x20,0x3A, 0x00,0x10, 0xE6,0x00, 0x49,0xF0, 0x00,0x00,
-0x00,0x01, 0xFF,0x82, 0x00,0x10, 0x86,0x82, 0xFF,0x38, 0xF7,0x04, 0x35,0x58, 0xF5,0x84,
-0x6F,0x58, 0xF6,0x85, 0x35,0x54, 0x07,0x38, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00,
-0x47,0x08, 0xF7,0x05, 0x35,0x58, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x46,0xFC, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF4,0x82, 0x00,0x22, 0xE0,0x00,
-0x47,0x0C, 0xF4,0x85, 0x6F,0x58, 0xF0,0x05, 0x6F,0x54, 0xF6,0x84, 0x35,0x2C, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x00,0x94, 0xC4,0x84, 0x00,0x00, 0xC0,0x3A, 0x4A,0x00, 0xE6,0x00,
-0x47,0x71, 0x00,0x00, 0x00,0x01, 0x86,0x36, 0x00,0x94, 0xF6,0x84, 0x35,0x54, 0x00,0x00,
-0x00,0x01, 0x76,0xB4, 0xFF,0xF0, 0xF7,0x04, 0x35,0x54, 0x96,0x96, 0xFF,0xF4, 0x47,0x39,
-0x00,0x00, 0x97,0x16, 0xFF,0xF0, 0xC6,0xB4, 0x70,0x00, 0xF7,0x04, 0x35,0x48, 0x77,0xB4,
-0x00,0x0F, 0x70,0x3E, 0xFF,0xE1, 0x07,0x38, 0x00,0x24, 0xE6,0x00, 0x47,0x69, 0xC6,0x38,
-0x60,0x00, 0x06,0xB4, 0x00,0x01, 0xC7,0x04, 0x6E,0x00, 0xF7,0x33, 0x28,0x00, 0xF6,0x84,
-0x35,0x44, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x0F, 0xE2,0x00, 0x47,0xBD, 0x07,0x38, 0x00,0x01, 0x87,0x36, 0x00,0x0C, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36, 0x00,0x0C, 0x87,0x36, 0x00,0x0C, 0xE0,0x00,
-0x47,0xD0, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x35,0x28, 0xF6,0x82, 0x00,0x01, 0x07,0x38,
-0x00,0x08, 0xE0,0x00, 0x49,0x68, 0xF7,0x05, 0x35,0x44, 0x20,0x3A, 0x00,0x10, 0xE6,0x00,
-0x47,0xCC, 0x00,0x00, 0x00,0x01, 0xF7,0x02, 0x00,0x00, 0x97,0x36, 0x00,0x04, 0xF7,0x04,
-0x35,0x3C, 0xF6,0x84, 0x35,0x28, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x35,0x3C, 0xF7,0x04,
-0x35,0x3C, 0x87,0x36, 0x14,0x1C, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x14,0x1C, 0xF7,0x04, 0x76,0x04, 0x86,0xB6, 0x14,0x1C, 0xF6,0x04, 0x75,0xFC, 0x07,0x38,
-0x00,0x01, 0xF6,0x84, 0x76,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00,
-0x48,0x1C, 0xF7,0x05, 0x76,0x04, 0xF0,0x05, 0x76,0x04, 0xF6,0x84, 0x76,0x04, 0xF7,0x04,
-0x76,0x08, 0xF0,0x05, 0x75,0xFC, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x32,
-0x00,0x00, 0xE6,0x00, 0x48,0x81, 0xF7,0x05, 0x75,0xF8, 0xF7,0x04, 0x76,0x48, 0xF4,0x86,
-0x72,0x18, 0xC0,0x3A, 0x4A,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x48,0x81, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF4,0x82, 0x00,0x0E, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x48,0x80, 0xB4,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF5,0x02,
-0x00,0x00, 0x20,0x2A, 0x00,0x02, 0xEE,0x00, 0x49,0x68, 0xF6,0x82, 0x00,0x00, 0xF6,0x84,
-0x35,0x28, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x02, 0xE6,0x00, 0x49,0x3C, 0x05,0xB4, 0x00,0x08, 0x95,0x93, 0xFF,0xFC, 0x95,0x16,
-0xFF,0xEC, 0x95,0x96, 0xFF,0xE8, 0x96,0x96, 0xFF,0xE4, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x5E,0xDC, 0x97,0x93, 0xFF,0xFC, 0x85,0x16, 0xFF,0xEC, 0x85,0x96, 0xFF,0xE8, 0x86,0x96,
-0xFF,0xE4, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x49,0x2C, 0xF7,0x02, 0x00,0x00, 0x86,0x36,
-0x00,0x0C, 0x00,0x00, 0x00,0x01, 0x20,0x32, 0x00,0x0F, 0xE2,0x00, 0x49,0x11, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x00,0x14, 0x87,0x36, 0x00,0x14, 0xE0,0x00, 0x49,0x2C, 0xF7,0x02, 0x00,0x00, 0x76,0xB1,
-0x00,0x02, 0xC6,0xB4, 0x60,0x00, 0x77,0x35, 0x00,0x05, 0xC7,0x38, 0x6A,0x00, 0xC7,0x38,
-0x60,0x00, 0x07,0x38, 0x00,0x10, 0xC7,0x2C, 0x70,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x47,0xA8, 0xF7,0x05, 0x35,0x2C, 0xF6,0x84, 0x35,0x28, 0xF7,0x04, 0x6F,0x4C, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x49,0x5C, 0x07,0x34, 0x14,0x94, 0xF4,0x84,
-0x6F,0x44, 0xE0,0x00, 0x49,0x60, 0xF4,0x85, 0x35,0x28, 0xF7,0x05, 0x35,0x28, 0xE0,0x00,
-0x48,0x84, 0x05,0x28, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x49,0xA1, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF4,0x82, 0x00,0x0D, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x49,0xA8, 0xB4,0xBA, 0x68,0x02, 0xE0,0x00, 0x49,0xA8, 0xF0,0x05, 0x2D,0x38, 0xF4,0x82,
-0x00,0x01, 0xF4,0x85, 0x35,0x24, 0xF6,0x84, 0x35,0x28, 0xF7,0x04, 0x6F,0x44, 0xF4,0x86,
-0x32,0xF4, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x49,0xF0, 0xF4,0x85, 0x35,0x30, 0xF7,0x04,
-0xE0,0x18, 0x00,0x00, 0x00,0x01, 0x77,0xB8, 0x00,0x1F, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x00,
-0x49,0xF1, 0x00,0x00, 0x00,0x01, 0x0F,0x81, 0x40,0x00, 0xF7,0x04, 0x79,0xC8, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x79,0xC8, 0xF7,0x04, 0x79,0xC8, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x14, 0xF7,0x04,
-0x75,0xF8, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x4A,0x2D, 0xF6,0x86,
-0x75,0xF8, 0xE0,0x00, 0x4A,0x40, 0xF6,0x82, 0x00,0x00, 0xF7,0x04, 0x76,0x04, 0x00,0x00,
-0x00,0x01, 0x77,0x39, 0x00,0x02, 0xC7,0x38, 0x68,0x00, 0x86,0xBA, 0x00,0x18, 0xF7,0x04,
-0x6F,0x54, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x4A,0x64, 0xF6,0x85,
-0x35,0x48, 0xF4,0x82, 0x00,0x01, 0xF4,0x85, 0x6F,0x54, 0xE0,0x00, 0x4A,0x70, 0xF7,0x02,
-0x00,0x01, 0xF4,0x82, 0x00,0x08, 0xF4,0x85, 0x6F,0x58, 0xF7,0x02, 0x00,0x00, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x4A,0x88, 0xF4,0x82, 0x00,0x04, 0xF4,0x86, 0x34,0x0C, 0xE0,0x00,
-0x4E,0xD8, 0xF4,0x85, 0x35,0x30, 0xF6,0x84, 0x35,0x48, 0xF6,0x04, 0x35,0x2C, 0xF4,0xB7,
-0x28,0x00, 0x07,0x34, 0x00,0x02, 0xF4,0x82, 0x00,0x01, 0xF4,0xBB, 0x28,0x00, 0x87,0x32,
-0x00,0x8C, 0xF4,0x82, 0x00,0x01, 0x97,0x36, 0x00,0x18, 0x87,0x32, 0x00,0x90, 0xF4,0x85,
-0x6F,0x50, 0x97,0x36, 0x00,0x04, 0x84,0xB2, 0x00,0x84, 0x00,0x00, 0x00,0x01, 0x94,0xB6,
-0x00,0x10, 0x84,0xB2, 0x00,0x88, 0x00,0x00, 0x00,0x01, 0x94,0xB6, 0x00,0x14, 0x84,0xB6,
-0x00,0x10, 0x00,0x00, 0x00,0x01, 0x94,0xB6, 0x00,0x08, 0x84,0xB6, 0x00,0x14, 0x00,0x00,
-0x00,0x01, 0x94,0xB6, 0x00,0x0C, 0x84,0xB2, 0x00,0x98, 0x00,0x00, 0x00,0x01, 0xF4,0x85,
-0x35,0x54, 0xF4,0x82, 0x00,0x01, 0x94,0x82, 0xFF,0x80, 0xF5,0x04, 0x35,0x54, 0xF4,0x86,
-0x34,0x98, 0xF4,0x85, 0x35,0x30, 0x95,0x02, 0xFF,0x38, 0x85,0xB2, 0x00,0x00, 0x06,0xB4,
-0x00,0x24, 0x95,0x82, 0xFF,0x3C, 0x96,0x82, 0xFF,0x40, 0x87,0x32, 0x00,0x04, 0xF6,0x85,
-0x35,0x50, 0x97,0x02, 0xFF,0x44, 0x86,0xB2, 0x00,0x04, 0xF0,0x05, 0x35,0x4C, 0xF7,0x04,
-0x35,0x40, 0x95,0x16, 0xFF,0xF4, 0x95,0x96, 0xFF,0xF4, 0xC7,0x38, 0x68,0x00, 0xF7,0x05,
-0x35,0x40, 0xF5,0x84, 0x35,0x28, 0x86,0xB2, 0x00,0x04, 0x87,0x2E, 0x14,0x14, 0x00,0x00,
-0x00,0x01, 0xC7,0x38, 0x68,0x00, 0x97,0x2E, 0x14,0x14, 0x87,0x32, 0x00,0x80, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x01, 0xEE,0x00, 0x4E,0xD8, 0xF7,0x06, 0x0C,0x3E, 0xC0,0x7E,
-0x74,0x00, 0xE6,0x00, 0x4B,0x8C, 0x00,0x00, 0x00,0x01, 0xC0,0x7E, 0x74,0x00, 0xE6,0x00,
-0x4B,0x7D, 0x00,0x00, 0x00,0x01, 0xF7,0x06, 0x0C,0x3E, 0xC7,0x7C, 0x74,0x00, 0x20,0x3A,
-0x00,0x10, 0xE6,0x00, 0x4E,0xD8, 0x00,0x00, 0x00,0x01, 0xFF,0x82, 0x00,0x10, 0x86,0x82,
-0xFF,0x38, 0xF7,0x04, 0x35,0x58, 0xF5,0x84, 0x6F,0x58, 0xF6,0x85, 0x35,0x54, 0x07,0x38,
-0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00, 0x4B,0xF0, 0xF7,0x05, 0x35,0x58, 0xF7,0x04,
-0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39,
-0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x4B,0xE4, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05,
-0x2D,0x38, 0xF4,0x82, 0x00,0x22, 0xE0,0x00, 0x4B,0xF4, 0xF4,0x85, 0x6F,0x58, 0xF0,0x05,
-0x6F,0x54, 0xF6,0x84, 0x35,0x2C, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x94, 0xC4,0x84,
-0x00,0x00, 0xC0,0x3A, 0x4A,0x00, 0xE6,0x00, 0x4C,0x59, 0x00,0x00, 0x00,0x01, 0x86,0x36,
-0x00,0x94, 0xF6,0x84, 0x35,0x54, 0x00,0x00, 0x00,0x01, 0x76,0xB4, 0xFF,0xF0, 0xF7,0x04,
-0x35,0x54, 0x96,0x96, 0xFF,0xF4, 0x47,0x39, 0x00,0x00, 0x97,0x16, 0xFF,0xF0, 0xC6,0xB4,
-0x70,0x00, 0xF7,0x04, 0x35,0x48, 0x77,0xB4, 0x00,0x0F, 0x70,0x3E, 0xFF,0xE1, 0x07,0x38,
-0x00,0x24, 0xE6,0x00, 0x4C,0x51, 0xC6,0x38, 0x60,0x00, 0x06,0xB4, 0x00,0x01, 0xC7,0x04,
-0x6E,0x00, 0xF7,0x33, 0x28,0x00, 0xF6,0x84, 0x35,0x44, 0x00,0x00, 0x00,0x01, 0x87,0x36,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x0F, 0xE2,0x00, 0x4C,0xA5, 0x07,0x38,
-0x00,0x01, 0x87,0x36, 0x00,0x0C, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x00,0x0C, 0x87,0x36, 0x00,0x0C, 0xE0,0x00, 0x4C,0xB8, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x35,0x28, 0xF6,0x82, 0x00,0x01, 0x07,0x38, 0x00,0x08, 0xE0,0x00, 0x4E,0x50, 0xF7,0x05,
-0x35,0x44, 0x20,0x3A, 0x00,0x10, 0xE6,0x00, 0x4C,0xB4, 0x00,0x00, 0x00,0x01, 0xF7,0x02,
-0x00,0x00, 0x97,0x36, 0x00,0x04, 0xF7,0x04, 0x35,0x3C, 0xF6,0x84, 0x35,0x28, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x35,0x3C, 0xF7,0x04, 0x35,0x3C, 0x87,0x36, 0x14,0x1C, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36, 0x14,0x1C, 0xF7,0x04, 0x76,0x04, 0x86,0xB6,
-0x14,0x1C, 0xF6,0x04, 0x75,0xFC, 0x07,0x38, 0x00,0x01, 0xF6,0x84, 0x76,0x00, 0x00,0x00,
-0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00, 0x4D,0x04, 0xF7,0x05, 0x76,0x04, 0xF0,0x05,
-0x76,0x04, 0xF6,0x84, 0x76,0x04, 0xF7,0x04, 0x76,0x08, 0xF0,0x05, 0x75,0xFC, 0xC0,0x36,
-0x72,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x4D,0x69, 0xF7,0x05,
-0x75,0xF8, 0xF7,0x04, 0x76,0x48, 0xF4,0x86, 0x72,0x18, 0xC0,0x3A, 0x4A,0x00, 0x47,0x0C,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x4D,0x69, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04,
-0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39,
-0x00,0x02, 0xF4,0x82, 0x00,0x0E, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x4D,0x68, 0xB4,0xBA,
-0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF5,0x02, 0x00,0x00, 0x20,0x2A, 0x00,0x02, 0xEE,0x00,
-0x4E,0x50, 0xF6,0x82, 0x00,0x00, 0xF6,0x84, 0x35,0x28, 0x00,0x00, 0x00,0x01, 0x87,0x36,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x02, 0xE6,0x00, 0x4E,0x24, 0x05,0xB4,
-0x00,0x08, 0x95,0x93, 0xFF,0xFC, 0x95,0x16, 0xFF,0xEC, 0x95,0x96, 0xFF,0xE8, 0x96,0x96,
-0xFF,0xE4, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x5E,0xDC, 0x97,0x93, 0xFF,0xFC, 0x85,0x16,
-0xFF,0xEC, 0x85,0x96, 0xFF,0xE8, 0x86,0x96, 0xFF,0xE4, 0x20,0x22, 0x00,0x00, 0xE6,0x00,
-0x4E,0x14, 0xF7,0x02, 0x00,0x00, 0x86,0x36, 0x00,0x0C, 0x00,0x00, 0x00,0x01, 0x20,0x32,
-0x00,0x0F, 0xE2,0x00, 0x4D,0xF9, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x14, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36, 0x00,0x14, 0x87,0x36, 0x00,0x14, 0xE0,0x00,
-0x4E,0x14, 0xF7,0x02, 0x00,0x00, 0x76,0xB1, 0x00,0x02, 0xC6,0xB4, 0x60,0x00, 0x77,0x35,
-0x00,0x05, 0xC7,0x38, 0x6A,0x00, 0xC7,0x38, 0x60,0x00, 0x07,0x38, 0x00,0x10, 0xC7,0x2C,
-0x70,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x4C,0x90, 0xF7,0x05, 0x35,0x2C, 0xF6,0x84,
-0x35,0x28, 0xF7,0x04, 0x6F,0x4C, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0x4E,0x44, 0x07,0x34, 0x14,0x94, 0xF4,0x84, 0x6F,0x44, 0xE0,0x00, 0x4E,0x48, 0xF4,0x85,
-0x35,0x28, 0xF7,0x05, 0x35,0x28, 0xE0,0x00, 0x4D,0x6C, 0x05,0x28, 0x00,0x01, 0x20,0x36,
-0x00,0x00, 0xE6,0x00, 0x4E,0x89, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00,
-0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF4,0x82,
-0x00,0x0D, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x4E,0x90, 0xB4,0xBA, 0x68,0x02, 0xE0,0x00,
-0x4E,0x90, 0xF0,0x05, 0x2D,0x38, 0xF4,0x82, 0x00,0x01, 0xF4,0x85, 0x35,0x24, 0xF6,0x84,
-0x35,0x28, 0xF7,0x04, 0x6F,0x44, 0xF4,0x86, 0x32,0xF4, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0x4E,0xD8, 0xF4,0x85, 0x35,0x30, 0xF7,0x04, 0xE0,0x18, 0x00,0x00, 0x00,0x01, 0x77,0xB8,
-0x00,0x1F, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x00, 0x4E,0xD9, 0x00,0x00, 0x00,0x01, 0x0F,0x81,
-0x40,0x00, 0xF7,0x04, 0x79,0xC8, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x79,0xC8, 0xF7,0x04, 0x79,0xC8, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x22,0x10, 0x00,0x14, 0xF6,0x84, 0x35,0x48, 0xF6,0x04, 0x35,0x2C, 0xF4,0x82,
-0x00,0x04, 0xF4,0xB7, 0x28,0x00, 0x07,0x34, 0x00,0x02, 0xF4,0x82, 0x00,0x01, 0xF4,0xBB,
-0x28,0x00, 0x87,0x32, 0x00,0x8C, 0xF4,0x82, 0x00,0x01, 0x97,0x36, 0x00,0x18, 0x87,0x32,
-0x00,0x90, 0xF4,0x85, 0x6F,0x50, 0x97,0x36, 0x00,0x04, 0x84,0xB2, 0x00,0x84, 0x00,0x00,
-0x00,0x01, 0x94,0xB6, 0x00,0x10, 0x84,0xB2, 0x00,0x88, 0x00,0x00, 0x00,0x01, 0x94,0xB6,
-0x00,0x14, 0x84,0xB6, 0x00,0x10, 0x00,0x00, 0x00,0x01, 0x94,0xB6, 0x00,0x08, 0x84,0xB6,
-0x00,0x14, 0x00,0x00, 0x00,0x01, 0x94,0xB6, 0x00,0x0C, 0x84,0xB2, 0x00,0x98, 0x00,0x00,
-0x00,0x01, 0xF4,0x85, 0x35,0x54, 0xF4,0x82, 0x00,0x01, 0x94,0x82, 0xFF,0x80, 0xF5,0x04,
-0x35,0x54, 0xF4,0x86, 0x34,0x98, 0xF4,0x85, 0x35,0x30, 0x95,0x02, 0xFF,0x38, 0x85,0xB2,
-0x00,0x00, 0x06,0xB4, 0x00,0x24, 0x95,0x82, 0xFF,0x3C, 0x96,0x82, 0xFF,0x40, 0x87,0x32,
-0x00,0x04, 0xF6,0x85, 0x35,0x50, 0x97,0x02, 0xFF,0x44, 0x86,0xB2, 0x00,0x04, 0xF0,0x05,
-0x35,0x4C, 0xF7,0x04, 0x35,0x40, 0x95,0x16, 0xFF,0xF4, 0x95,0x96, 0xFF,0xF4, 0xC7,0x38,
-0x68,0x00, 0xF7,0x05, 0x35,0x40, 0xF5,0x84, 0x35,0x28, 0x86,0xB2, 0x00,0x04, 0x87,0x2E,
-0x14,0x14, 0x00,0x00, 0x00,0x01, 0xC7,0x38, 0x68,0x00, 0x97,0x2E, 0x14,0x14, 0x87,0x32,
-0x00,0x80, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x01, 0xEE,0x00, 0x53,0x4C, 0xF7,0x06,
-0x0C,0x3E, 0xC0,0x7E, 0x74,0x00, 0xE6,0x00, 0x50,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x7E,
-0x74,0x00, 0xE6,0x00, 0x4F,0xF1, 0x00,0x00, 0x00,0x01, 0xF7,0x06, 0x0C,0x3E, 0xC7,0x7C,
-0x74,0x00, 0x20,0x3A, 0x00,0x10, 0xE6,0x00, 0x53,0x4C, 0x00,0x00, 0x00,0x01, 0xFF,0x82,
-0x00,0x10, 0x86,0x82, 0xFF,0x38, 0xF7,0x04, 0x35,0x58, 0xF5,0x84, 0x6F,0x58, 0xF6,0x85,
-0x35,0x54, 0x07,0x38, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00, 0x50,0x64, 0xF7,0x05,
-0x35,0x58, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x50,0x58, 0xB5,0xBA,
-0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF4,0x82, 0x00,0x22, 0xE0,0x00, 0x50,0x68, 0xF4,0x85,
-0x6F,0x58, 0xF0,0x05, 0x6F,0x54, 0xF6,0x84, 0x35,0x2C, 0x00,0x00, 0x00,0x01, 0x87,0x36,
-0x00,0x94, 0xC4,0x84, 0x00,0x00, 0xC0,0x3A, 0x4A,0x00, 0xE6,0x00, 0x50,0xCD, 0x00,0x00,
-0x00,0x01, 0x86,0x36, 0x00,0x94, 0xF6,0x84, 0x35,0x54, 0x00,0x00, 0x00,0x01, 0x76,0xB4,
-0xFF,0xF0, 0xF7,0x04, 0x35,0x54, 0x96,0x96, 0xFF,0xF4, 0x47,0x39, 0x00,0x00, 0x97,0x16,
-0xFF,0xF0, 0xC6,0xB4, 0x70,0x00, 0xF7,0x04, 0x35,0x48, 0x77,0xB4, 0x00,0x0F, 0x70,0x3E,
-0xFF,0xE1, 0x07,0x38, 0x00,0x24, 0xE6,0x00, 0x50,0xC5, 0xC6,0x38, 0x60,0x00, 0x06,0xB4,
-0x00,0x01, 0xC7,0x04, 0x6E,0x00, 0xF7,0x33, 0x28,0x00, 0xF6,0x84, 0x35,0x44, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x0F, 0xE2,0x00,
-0x51,0x19, 0x07,0x38, 0x00,0x01, 0x87,0x36, 0x00,0x0C, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0x97,0x36, 0x00,0x0C, 0x87,0x36, 0x00,0x0C, 0xE0,0x00, 0x51,0x2C, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x35,0x28, 0xF6,0x82, 0x00,0x01, 0x07,0x38, 0x00,0x08, 0xE0,0x00,
-0x52,0xC4, 0xF7,0x05, 0x35,0x44, 0x20,0x3A, 0x00,0x10, 0xE6,0x00, 0x51,0x28, 0x00,0x00,
-0x00,0x01, 0xF7,0x02, 0x00,0x00, 0x97,0x36, 0x00,0x04, 0xF7,0x04, 0x35,0x3C, 0xF6,0x84,
-0x35,0x28, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x35,0x3C, 0xF7,0x04, 0x35,0x3C, 0x87,0x36,
-0x14,0x1C, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36, 0x14,0x1C, 0xF7,0x04,
-0x76,0x04, 0x86,0xB6, 0x14,0x1C, 0xF6,0x04, 0x75,0xFC, 0x07,0x38, 0x00,0x01, 0xF6,0x84,
-0x76,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00, 0x51,0x78, 0xF7,0x05,
-0x76,0x04, 0xF0,0x05, 0x76,0x04, 0xF6,0x84, 0x76,0x04, 0xF7,0x04, 0x76,0x08, 0xF0,0x05,
-0x75,0xFC, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0x51,0xDD, 0xF7,0x05, 0x75,0xF8, 0xF7,0x04, 0x76,0x48, 0xF4,0x86, 0x72,0x18, 0xC0,0x3A,
-0x4A,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x51,0xDD, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF4,0x82, 0x00,0x0E, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x51,0xDC, 0xB4,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF5,0x02, 0x00,0x00, 0x20,0x2A,
-0x00,0x02, 0xEE,0x00, 0x52,0xC4, 0xF6,0x82, 0x00,0x00, 0xF6,0x84, 0x35,0x28, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x02, 0xE6,0x00,
-0x52,0x98, 0x05,0xB4, 0x00,0x08, 0x95,0x93, 0xFF,0xFC, 0x95,0x16, 0xFF,0xEC, 0x95,0x96,
-0xFF,0xE8, 0x96,0x96, 0xFF,0xE4, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x5E,0xDC, 0x97,0x93,
-0xFF,0xFC, 0x85,0x16, 0xFF,0xEC, 0x85,0x96, 0xFF,0xE8, 0x86,0x96, 0xFF,0xE4, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0x52,0x88, 0xF7,0x02, 0x00,0x00, 0x86,0x36, 0x00,0x0C, 0x00,0x00,
-0x00,0x01, 0x20,0x32, 0x00,0x0F, 0xE2,0x00, 0x52,0x6D, 0x00,0x00, 0x00,0x01, 0x87,0x36,
-0x00,0x14, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36, 0x00,0x14, 0x87,0x36,
-0x00,0x14, 0xE0,0x00, 0x52,0x88, 0xF7,0x02, 0x00,0x00, 0x76,0xB1, 0x00,0x02, 0xC6,0xB4,
-0x60,0x00, 0x77,0x35, 0x00,0x05, 0xC7,0x38, 0x6A,0x00, 0xC7,0x38, 0x60,0x00, 0x07,0x38,
-0x00,0x10, 0xC7,0x2C, 0x70,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x51,0x04, 0xF7,0x05,
-0x35,0x2C, 0xF6,0x84, 0x35,0x28, 0xF7,0x04, 0x6F,0x4C, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x52,0xB8, 0x07,0x34, 0x14,0x94, 0xF4,0x84, 0x6F,0x44, 0xE0,0x00,
-0x52,0xBC, 0xF4,0x85, 0x35,0x28, 0xF7,0x05, 0x35,0x28, 0xE0,0x00, 0x51,0xE0, 0x05,0x28,
-0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x52,0xFD, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04,
-0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39,
-0x00,0x02, 0xF4,0x82, 0x00,0x0D, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x53,0x04, 0xB4,0xBA,
-0x68,0x02, 0xE0,0x00, 0x53,0x04, 0xF0,0x05, 0x2D,0x38, 0xF4,0x82, 0x00,0x01, 0xF4,0x85,
-0x35,0x24, 0xF6,0x84, 0x35,0x28, 0xF7,0x04, 0x6F,0x44, 0xF4,0x86, 0x32,0xF4, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x53,0x4C, 0xF4,0x85, 0x35,0x30, 0xF7,0x04, 0xE0,0x18, 0x00,0x00,
-0x00,0x01, 0x77,0xB8, 0x00,0x1F, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x00, 0x53,0x4D, 0x00,0x00,
-0x00,0x01, 0x0F,0x81, 0x40,0x00, 0xF7,0x04, 0x79,0xC8, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x79,0xC8, 0xF7,0x04, 0x79,0xC8, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x14, 0xF4,0x84, 0x35,0x54, 0xF6,0x84,
-0x35,0x4C, 0xF5,0x84, 0x35,0x2C, 0x94,0x82, 0xFF,0x38, 0x76,0xB5, 0x00,0x03, 0xA5,0x2E,
-0x68,0x02, 0x00,0x00, 0x00,0x01, 0x95,0x02, 0xFF,0x3C, 0xF3,0x84, 0x35,0x50, 0xC6,0xAC,
-0x68,0x00, 0x93,0x82, 0xFF,0x40, 0x87,0x36, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x97,0x02,
-0xFF,0x44, 0x86,0x36, 0x00,0x04, 0xF7,0x04, 0x35,0x40, 0x00,0x00, 0x00,0x01, 0xC7,0x38,
-0x60,0x00, 0xF7,0x05, 0x35,0x40, 0xF6,0x04, 0x35,0x28, 0x86,0xB6, 0x00,0x04, 0x87,0x32,
-0x14,0x14, 0x94,0x96, 0xFF,0xF4, 0xC7,0x38, 0x68,0x00, 0x97,0x32, 0x14,0x14, 0x87,0x2E,
-0x00,0x80, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x01, 0xEE,0x00, 0x57,0x50, 0x95,0x16,
-0xFF,0xF4, 0xF7,0x06, 0x0C,0x3E, 0xC0,0x7E, 0x74,0x00, 0xE6,0x00, 0x54,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x7E, 0x74,0x00, 0xE6,0x00, 0x53,0xF5, 0x00,0x00, 0x00,0x01, 0xF7,0x06,
-0x0C,0x3E, 0xC7,0x7C, 0x74,0x00, 0x20,0x3A, 0x00,0x10, 0xE6,0x00, 0x57,0x50, 0x00,0x00,
-0x00,0x01, 0xFF,0x82, 0x00,0x10, 0x86,0x82, 0xFF,0x38, 0xF7,0x04, 0x35,0x58, 0xF5,0x84,
-0x6F,0x58, 0xF6,0x85, 0x35,0x54, 0x07,0x38, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00,
-0x54,0x68, 0xF7,0x05, 0x35,0x58, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x54,0x5C, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF3,0x82, 0x00,0x22, 0xE0,0x00,
-0x54,0x6C, 0xF3,0x85, 0x6F,0x58, 0xF0,0x05, 0x6F,0x54, 0xF6,0x84, 0x35,0x2C, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x00,0x94, 0xC3,0x84, 0x00,0x00, 0xC0,0x3A, 0x3A,0x00, 0xE6,0x00,
-0x54,0xD1, 0x00,0x00, 0x00,0x01, 0x86,0x36, 0x00,0x94, 0xF6,0x84, 0x35,0x54, 0x00,0x00,
-0x00,0x01, 0x76,0xB4, 0xFF,0xF0, 0xF7,0x04, 0x35,0x54, 0x96,0x96, 0xFF,0xF4, 0x47,0x39,
-0x00,0x00, 0x97,0x16, 0xFF,0xF0, 0xC6,0xB4, 0x70,0x00, 0xF7,0x04, 0x35,0x48, 0x77,0xB4,
-0x00,0x0F, 0x70,0x3E, 0xFF,0xE1, 0x07,0x38, 0x00,0x24, 0xE6,0x00, 0x54,0xC9, 0xC6,0x38,
-0x60,0x00, 0x06,0xB4, 0x00,0x01, 0xC7,0x04, 0x6E,0x00, 0xF7,0x33, 0x28,0x00, 0xF6,0x84,
-0x35,0x44, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x0F, 0xE2,0x00, 0x55,0x1D, 0x07,0x38, 0x00,0x01, 0x87,0x36, 0x00,0x0C, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36, 0x00,0x0C, 0x87,0x36, 0x00,0x0C, 0xE0,0x00,
-0x55,0x30, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x35,0x28, 0xF6,0x82, 0x00,0x01, 0x07,0x38,
-0x00,0x08, 0xE0,0x00, 0x56,0xC8, 0xF7,0x05, 0x35,0x44, 0x20,0x3A, 0x00,0x10, 0xE6,0x00,
-0x55,0x2C, 0x00,0x00, 0x00,0x01, 0xF7,0x02, 0x00,0x00, 0x97,0x36, 0x00,0x04, 0xF7,0x04,
-0x35,0x3C, 0xF6,0x84, 0x35,0x28, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x35,0x3C, 0xF7,0x04,
-0x35,0x3C, 0x87,0x36, 0x14,0x1C, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x14,0x1C, 0xF7,0x04, 0x76,0x04, 0x86,0xB6, 0x14,0x1C, 0xF6,0x04, 0x75,0xFC, 0x07,0x38,
-0x00,0x01, 0xF6,0x84, 0x76,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00,
-0x55,0x7C, 0xF7,0x05, 0x76,0x04, 0xF0,0x05, 0x76,0x04, 0xF6,0x84, 0x76,0x04, 0xF7,0x04,
-0x76,0x08, 0xF0,0x05, 0x75,0xFC, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x32,
-0x00,0x00, 0xE6,0x00, 0x55,0xE1, 0xF7,0x05, 0x75,0xF8, 0xF7,0x04, 0x76,0x48, 0xF3,0x86,
-0x72,0x18, 0xC0,0x3A, 0x3A,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x55,0xE1, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x82, 0x00,0x0E, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x55,0xE0, 0xB3,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF5,0x02,
-0x00,0x00, 0x20,0x2A, 0x00,0x02, 0xEE,0x00, 0x56,0xC8, 0xF6,0x82, 0x00,0x00, 0xF6,0x84,
-0x35,0x28, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x02, 0xE6,0x00, 0x56,0x9C, 0x05,0xB4, 0x00,0x08, 0x95,0x93, 0xFF,0xFC, 0x95,0x16,
-0xFF,0xEC, 0x95,0x96, 0xFF,0xE8, 0x96,0x96, 0xFF,0xE4, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x5E,0xDC, 0x97,0x93, 0xFF,0xFC, 0x85,0x16, 0xFF,0xEC, 0x85,0x96, 0xFF,0xE8, 0x86,0x96,
-0xFF,0xE4, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x56,0x8C, 0xF7,0x02, 0x00,0x00, 0x86,0x36,
-0x00,0x0C, 0x00,0x00, 0x00,0x01, 0x20,0x32, 0x00,0x0F, 0xE2,0x00, 0x56,0x71, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x00,0x14, 0x87,0x36, 0x00,0x14, 0xE0,0x00, 0x56,0x8C, 0xF7,0x02, 0x00,0x00, 0x76,0xB1,
-0x00,0x02, 0xC6,0xB4, 0x60,0x00, 0x77,0x35, 0x00,0x05, 0xC7,0x38, 0x6A,0x00, 0xC7,0x38,
-0x60,0x00, 0x07,0x38, 0x00,0x10, 0xC7,0x2C, 0x70,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x55,0x08, 0xF7,0x05, 0x35,0x2C, 0xF6,0x84, 0x35,0x28, 0xF7,0x04, 0x6F,0x4C, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x56,0xBC, 0x07,0x34, 0x14,0x94, 0xF3,0x84,
-0x6F,0x44, 0xE0,0x00, 0x56,0xC0, 0xF3,0x85, 0x35,0x28, 0xF7,0x05, 0x35,0x28, 0xE0,0x00,
-0x55,0xE4, 0x05,0x28, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x57,0x01, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x82, 0x00,0x0D, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x57,0x08, 0xB3,0xBA, 0x68,0x02, 0xE0,0x00, 0x57,0x08, 0xF0,0x05, 0x2D,0x38, 0xF3,0x82,
-0x00,0x01, 0xF3,0x85, 0x35,0x24, 0xF6,0x84, 0x35,0x28, 0xF7,0x04, 0x6F,0x44, 0xF3,0x86,
-0x32,0xF4, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x57,0x50, 0xF3,0x85, 0x35,0x30, 0xF7,0x04,
-0xE0,0x18, 0x00,0x00, 0x00,0x01, 0x77,0xB8, 0x00,0x1F, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x00,
-0x57,0x51, 0x00,0x00, 0x00,0x01, 0x0F,0x81, 0x40,0x00, 0xF7,0x04, 0x79,0xC8, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x79,0xC8, 0xF7,0x04, 0x79,0xC8, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x14, 0x87,0x02,
-0xFF,0x38, 0xF3,0x84, 0x35,0x2C, 0xF7,0x05, 0x35,0x54, 0x87,0x1E, 0x00,0x80, 0xF5,0x04,
-0x35,0x4C, 0x27,0x38, 0x00,0x01, 0xC0,0x2A, 0x72,0x00, 0xE6,0x00, 0x5A,0x4C, 0x00,0x00,
-0x00,0x01, 0xF5,0x84, 0x6F,0x58, 0x00,0x00, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00,
-0x57,0xD8, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x57,0xCC, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF3,0x02, 0x00,0x22, 0xE0,0x00,
-0x57,0xDC, 0xF3,0x05, 0x6F,0x58, 0xF0,0x05, 0x6F,0x54, 0xF6,0x84, 0x35,0x2C, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x00,0x94, 0xC3,0x04, 0x00,0x00, 0xC0,0x3A, 0x32,0x00, 0xE6,0x00,
-0x58,0x41, 0x00,0x00, 0x00,0x01, 0x86,0x36, 0x00,0x94, 0xF6,0x84, 0x35,0x54, 0x00,0x00,
-0x00,0x01, 0x76,0xB4, 0xFF,0xF0, 0xF7,0x04, 0x35,0x54, 0x96,0x96, 0xFF,0xF4, 0x47,0x39,
-0x00,0x00, 0x97,0x16, 0xFF,0xF0, 0xC6,0xB4, 0x70,0x00, 0xF7,0x04, 0x35,0x48, 0x77,0xB4,
-0x00,0x0F, 0x70,0x3E, 0xFF,0xE1, 0x07,0x38, 0x00,0x24, 0xE6,0x00, 0x58,0x39, 0xC6,0x38,
-0x60,0x00, 0x06,0xB4, 0x00,0x01, 0xC7,0x04, 0x6E,0x00, 0xF7,0x33, 0x28,0x00, 0xF6,0x84,
-0x35,0x44, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x0F, 0xE2,0x00, 0x58,0x8D, 0x07,0x38, 0x00,0x01, 0x87,0x36, 0x00,0x0C, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36, 0x00,0x0C, 0x87,0x36, 0x00,0x0C, 0xE0,0x00,
-0x58,0xA0, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x35,0x28, 0xF6,0x82, 0x00,0x01, 0x07,0x38,
-0x00,0x08, 0xE0,0x00, 0x5A,0x38, 0xF7,0x05, 0x35,0x44, 0x20,0x3A, 0x00,0x10, 0xE6,0x00,
-0x58,0x9C, 0x00,0x00, 0x00,0x01, 0xF7,0x02, 0x00,0x00, 0x97,0x36, 0x00,0x04, 0xF7,0x04,
-0x35,0x3C, 0xF6,0x84, 0x35,0x28, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x35,0x3C, 0xF7,0x04,
-0x35,0x3C, 0x87,0x36, 0x14,0x1C, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x14,0x1C, 0xF7,0x04, 0x76,0x04, 0x86,0xB6, 0x14,0x1C, 0xF6,0x04, 0x75,0xFC, 0x07,0x38,
-0x00,0x01, 0xF6,0x84, 0x76,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00,
-0x58,0xEC, 0xF7,0x05, 0x76,0x04, 0xF0,0x05, 0x76,0x04, 0xF6,0x84, 0x76,0x04, 0xF7,0x04,
-0x76,0x08, 0xF0,0x05, 0x75,0xFC, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x32,
-0x00,0x00, 0xE6,0x00, 0x59,0x51, 0xF7,0x05, 0x75,0xF8, 0xF7,0x04, 0x76,0x48, 0xF3,0x06,
-0x72,0x18, 0xC0,0x3A, 0x32,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x59,0x51, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02, 0x00,0x0E, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x59,0x50, 0xB3,0x3A, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF5,0x02,
-0x00,0x00, 0x20,0x2A, 0x00,0x02, 0xEE,0x00, 0x5A,0x38, 0xF6,0x82, 0x00,0x00, 0xF6,0x84,
-0x35,0x28, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x02, 0xE6,0x00, 0x5A,0x0C, 0x05,0xB4, 0x00,0x08, 0x95,0x93, 0xFF,0xFC, 0x95,0x16,
-0xFF,0xEC, 0x95,0x96, 0xFF,0xE8, 0x96,0x96, 0xFF,0xE4, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x5E,0xDC, 0x97,0x93, 0xFF,0xFC, 0x85,0x16, 0xFF,0xEC, 0x85,0x96, 0xFF,0xE8, 0x86,0x96,
-0xFF,0xE4, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x59,0xFC, 0xF7,0x02, 0x00,0x00, 0x86,0x36,
-0x00,0x0C, 0x00,0x00, 0x00,0x01, 0x20,0x32, 0x00,0x0F, 0xE2,0x00, 0x59,0xE1, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x00,0x14, 0x87,0x36, 0x00,0x14, 0xE0,0x00, 0x59,0xFC, 0xF7,0x02, 0x00,0x00, 0x76,0xB1,
-0x00,0x02, 0xC6,0xB4, 0x60,0x00, 0x77,0x35, 0x00,0x05, 0xC7,0x38, 0x6A,0x00, 0xC7,0x38,
-0x60,0x00, 0x07,0x38, 0x00,0x10, 0xC7,0x2C, 0x70,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x58,0x78, 0xF7,0x05, 0x35,0x2C, 0xF6,0x84, 0x35,0x28, 0xF7,0x04, 0x6F,0x4C, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x5A,0x2C, 0x07,0x34, 0x14,0x94, 0xF3,0x04,
-0x6F,0x44, 0xE0,0x00, 0x5A,0x30, 0xF3,0x05, 0x35,0x28, 0xF7,0x05, 0x35,0x28, 0xE0,0x00,
-0x59,0x54, 0x05,0x28, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x5D,0xC4, 0xF3,0x02,
-0x00,0x01, 0xE0,0x00, 0x5D,0xF0, 0x00,0x00, 0x00,0x01, 0x77,0x29, 0x00,0x03, 0xC7,0x1C,
-0x70,0x00, 0x87,0x3A, 0x00,0x04, 0x05,0x28, 0x00,0x01, 0x76,0xA9, 0x00,0x03, 0xF4,0x84,
-0x35,0x54, 0xF6,0x04, 0x35,0x50, 0x94,0x82, 0xFF,0x38, 0xA4,0x1E, 0x68,0x02, 0xC6,0x30,
-0x70,0x00, 0x94,0x02, 0xFF,0x3C, 0x96,0x02, 0xFF,0x40, 0xC6,0x9C, 0x68,0x00, 0x87,0x36,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0x97,0x02, 0xFF,0x44, 0x85,0xB6, 0x00,0x04, 0xF7,0x04,
-0x35,0x40, 0x00,0x00, 0x00,0x01, 0xC7,0x38, 0x58,0x00, 0xF7,0x05, 0x35,0x40, 0x85,0xB6,
-0x00,0x04, 0xF5,0x05, 0x35,0x4C, 0xF6,0x84, 0x35,0x28, 0xF6,0x05, 0x35,0x50, 0x87,0x36,
-0x14,0x14, 0x94,0x96, 0xFF,0xF4, 0xC7,0x38, 0x58,0x00, 0x97,0x36, 0x14,0x14, 0x87,0x1E,
-0x00,0x80, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x01, 0xEE,0x00, 0x5E,0x3C, 0x94,0x16,
-0xFF,0xF4, 0xF7,0x06, 0x0C,0x3E, 0xC0,0x7E, 0x74,0x00, 0xE6,0x00, 0x5A,0xF4, 0x00,0x00,
-0x00,0x01, 0xC0,0x7E, 0x74,0x00, 0xE6,0x00, 0x5A,0xE5, 0x00,0x00, 0x00,0x01, 0xF7,0x06,
-0x0C,0x3E, 0xC7,0x7C, 0x74,0x00, 0x20,0x3A, 0x00,0x10, 0xE6,0x00, 0x5E,0x3C, 0x00,0x00,
-0x00,0x01, 0xFF,0x82, 0x00,0x10, 0x86,0x82, 0xFF,0x38, 0xF7,0x04, 0x35,0x58, 0xF5,0x84,
-0x6F,0x58, 0xF6,0x85, 0x35,0x54, 0x07,0x38, 0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x00,
-0x5B,0x58, 0xF7,0x05, 0x35,0x58, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x5B,0x4C, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF3,0x02, 0x00,0x22, 0xE0,0x00,
-0x5B,0x5C, 0xF3,0x05, 0x6F,0x58, 0xF0,0x05, 0x6F,0x54, 0xF6,0x84, 0x35,0x2C, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x00,0x94, 0xC3,0x04, 0x00,0x00, 0xC0,0x3A, 0x32,0x00, 0xE6,0x00,
-0x5B,0xC1, 0x00,0x00, 0x00,0x01, 0x86,0x36, 0x00,0x94, 0xF6,0x84, 0x35,0x54, 0x00,0x00,
-0x00,0x01, 0x76,0xB4, 0xFF,0xF0, 0xF7,0x04, 0x35,0x54, 0x96,0x96, 0xFF,0xF4, 0x47,0x39,
-0x00,0x00, 0x97,0x16, 0xFF,0xF0, 0xC6,0xB4, 0x70,0x00, 0xF7,0x04, 0x35,0x48, 0x77,0xB4,
-0x00,0x0F, 0x70,0x3E, 0xFF,0xE1, 0x07,0x38, 0x00,0x24, 0xE6,0x00, 0x5B,0xB9, 0xC6,0x38,
-0x60,0x00, 0x06,0xB4, 0x00,0x01, 0xC7,0x04, 0x6E,0x00, 0xF7,0x33, 0x28,0x00, 0xF6,0x84,
-0x35,0x44, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x0F, 0xE2,0x00, 0x5C,0x0D, 0x07,0x38, 0x00,0x01, 0x87,0x36, 0x00,0x0C, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36, 0x00,0x0C, 0x87,0x36, 0x00,0x0C, 0xE0,0x00,
-0x5C,0x20, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x35,0x28, 0xF6,0x82, 0x00,0x01, 0x07,0x38,
-0x00,0x08, 0xE0,0x00, 0x5D,0xB8, 0xF7,0x05, 0x35,0x44, 0x20,0x3A, 0x00,0x10, 0xE6,0x00,
-0x5C,0x1C, 0x00,0x00, 0x00,0x01, 0xF7,0x02, 0x00,0x00, 0x97,0x36, 0x00,0x04, 0xF7,0x04,
-0x35,0x3C, 0xF6,0x84, 0x35,0x28, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x35,0x3C, 0xF7,0x04,
-0x35,0x3C, 0x87,0x36, 0x14,0x1C, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x14,0x1C, 0xF7,0x04, 0x76,0x04, 0x86,0xB6, 0x14,0x1C, 0xF6,0x04, 0x75,0xFC, 0x07,0x38,
-0x00,0x01, 0xF6,0x84, 0x76,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00,
-0x5C,0x6C, 0xF7,0x05, 0x76,0x04, 0xF0,0x05, 0x76,0x04, 0xF6,0x84, 0x76,0x04, 0xF7,0x04,
-0x76,0x08, 0xF0,0x05, 0x75,0xFC, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x32,
-0x00,0x00, 0xE6,0x00, 0x5C,0xD1, 0xF7,0x05, 0x75,0xF8, 0xF7,0x04, 0x76,0x48, 0xF3,0x06,
-0x72,0x18, 0xC0,0x3A, 0x32,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x5C,0xD1, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02, 0x00,0x0E, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x5C,0xD0, 0xB3,0x3A, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF5,0x02,
-0x00,0x00, 0x20,0x2A, 0x00,0x02, 0xEE,0x00, 0x5D,0xB8, 0xF6,0x82, 0x00,0x00, 0xF6,0x84,
-0x35,0x28, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x02, 0xE6,0x00, 0x5D,0x8C, 0x05,0xB4, 0x00,0x08, 0x95,0x93, 0xFF,0xFC, 0x95,0x16,
-0xFF,0xEC, 0x95,0x96, 0xFF,0xE8, 0x96,0x96, 0xFF,0xE4, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x5E,0xDC, 0x97,0x93, 0xFF,0xFC, 0x85,0x16, 0xFF,0xEC, 0x85,0x96, 0xFF,0xE8, 0x86,0x96,
-0xFF,0xE4, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x5D,0x7C, 0xF7,0x02, 0x00,0x00, 0x86,0x36,
-0x00,0x0C, 0x00,0x00, 0x00,0x01, 0x20,0x32, 0x00,0x0F, 0xE2,0x00, 0x5D,0x61, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36,
-0x00,0x14, 0x87,0x36, 0x00,0x14, 0xE0,0x00, 0x5D,0x7C, 0xF7,0x02, 0x00,0x00, 0x76,0xB1,
-0x00,0x02, 0xC6,0xB4, 0x60,0x00, 0x77,0x35, 0x00,0x05, 0xC7,0x38, 0x6A,0x00, 0xC7,0x38,
-0x60,0x00, 0x07,0x38, 0x00,0x10, 0xC7,0x2C, 0x70,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x5B,0xF8, 0xF7,0x05, 0x35,0x2C, 0xF6,0x84, 0x35,0x28, 0xF7,0x04, 0x6F,0x4C, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x5D,0xAC, 0x07,0x34, 0x14,0x94, 0xF3,0x04,
-0x6F,0x44, 0xE0,0x00, 0x5D,0xB0, 0xF3,0x05, 0x35,0x28, 0xF7,0x05, 0x35,0x28, 0xE0,0x00,
-0x5C,0xD4, 0x05,0x28, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x5D,0xF1, 0xF3,0x02,
-0x00,0x01, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02, 0x00,0x0D, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x5D,0xF4, 0xB3,0x3A, 0x68,0x02, 0xE0,0x00, 0x5D,0xF4, 0xF0,0x05, 0x2D,0x38, 0xF3,0x05,
-0x35,0x24, 0xF6,0x84, 0x35,0x28, 0xF7,0x04, 0x6F,0x44, 0xF3,0x06, 0x32,0xF4, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x5E,0x3C, 0xF3,0x05, 0x35,0x30, 0xF7,0x04, 0xE0,0x18, 0x00,0x00,
-0x00,0x01, 0x77,0xB8, 0x00,0x1F, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x00, 0x5E,0x3D, 0x00,0x00,
-0x00,0x01, 0x0F,0x81, 0x40,0x00, 0xF7,0x04, 0x79,0xC8, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x79,0xC8, 0xF7,0x04, 0x79,0xC8, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x06, 0x35,0x30, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x32,0xF4, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x06, 0x35,0x30, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x33,0x80, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06,
-0x35,0x30, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x34,0x0C, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x35,0x30, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x34,0x98, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x86,0x16, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x87,0x32, 0x00,0x04, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x0F, 0x86,0xB2, 0x00,0x00, 0xC5,0x38, 0x00,0x00, 0xEE,0x00,
-0x5F,0x2C, 0xC5,0xB4, 0x00,0x00, 0x20,0x36, 0x00,0x0F, 0xEE,0x00, 0x5F,0x2C, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xEC,0x00, 0x5F,0x2D, 0x00,0x00, 0x00,0x01, 0x20,0x36,
-0x00,0x00, 0xEC,0x00, 0x5F,0x48, 0x00,0x00, 0x00,0x01, 0x87,0x32, 0x00,0x0C, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x32, 0x00,0x0C, 0x87,0x32, 0x00,0x0C, 0xE0,0x00,
-0x5F,0x50, 0xF4,0x02, 0x00,0x00, 0xC0,0x2A, 0x5A,0x00, 0x44,0x0C, 0x00,0x01, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF6,0x86,
-0x35,0x60, 0x96,0x93, 0xFF,0xFC, 0xF6,0x86, 0x42,0x30, 0x96,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x15,0x48, 0x97,0x93, 0xFF,0xFC, 0xF6,0x82, 0x66,0xF8, 0x96,0x93,
-0xFF,0xFC, 0xF7,0x82, 0x00,0x17, 0x97,0x93, 0xFF,0xFC, 0xF6,0x86, 0x35,0x60, 0x96,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF6,0x82,
-0x69,0x80, 0x96,0x93, 0xFF,0xFC, 0xF7,0x82, 0x00,0x18, 0x97,0x93, 0xFF,0xFC, 0xF6,0x86,
-0x35,0x60, 0x96,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF6,0x82, 0x6B,0x50, 0x96,0x93, 0xFF,0xFC, 0xF7,0x82, 0x00,0x16, 0x97,0x93,
-0xFF,0xFC, 0xF6,0x86, 0x35,0x60, 0x96,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF6,0x82, 0x61,0x78, 0x96,0x93, 0xFF,0xFC, 0xF7,0x82,
-0x00,0x1F, 0x97,0x93, 0xFF,0xFC, 0xF6,0x86, 0x35,0x60, 0x96,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF6,0x82, 0x62,0x7C, 0x96,0x93,
-0xFF,0xFC, 0xF7,0x82, 0x00,0x20, 0x97,0x93, 0xFF,0xFC, 0xF6,0x86, 0x35,0x60, 0x96,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF6,0x82,
-0x66,0xF8, 0x96,0x93, 0xFF,0xFC, 0xF7,0x82, 0x00,0x17, 0x97,0x93, 0xFF,0xFC, 0xF6,0x86,
-0x35,0xEC, 0x96,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF6,0x82, 0x69,0x80, 0x96,0x93, 0xFF,0xFC, 0xF7,0x82, 0x00,0x18, 0x97,0x93,
-0xFF,0xFC, 0xF6,0x86, 0x35,0xEC, 0x96,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF6,0x82, 0x6B,0x50, 0x96,0x93, 0xFF,0xFC, 0xF7,0x82,
-0x00,0x16, 0x97,0x93, 0xFF,0xFC, 0xF6,0x86, 0x35,0xEC, 0x96,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF6,0x82, 0x61,0x78, 0x96,0x93,
-0xFF,0xFC, 0xF7,0x82, 0x00,0x1F, 0x97,0x93, 0xFF,0xFC, 0xF6,0x86, 0x35,0xEC, 0x96,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF6,0x82,
-0x62,0x7C, 0x96,0x93, 0xFF,0xFC, 0xF7,0x82, 0x00,0x20, 0x97,0x93, 0xFF,0xFC, 0xF6,0x86,
-0x35,0xEC, 0x96,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x04, 0xE0,0x28, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x61,0x15, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0xE0,0x28, 0xE0,0x00, 0x61,0x18, 0x77,0x39,
-0x00,0x02, 0xF7,0x02, 0x00,0xF0, 0xF7,0x05, 0x42,0x28, 0xF7,0x06, 0x40,0x8A, 0xF0,0x3B,
-0x28,0x00, 0xF7,0x06, 0x40,0x8C, 0xF0,0x3B, 0x28,0x00, 0xF7,0x02, 0x00,0x00, 0xF7,0x05,
-0x7A,0xC0, 0xF7,0x05, 0x7A,0xB8, 0xF7,0x05, 0x7A,0xB0, 0xF7,0x05, 0x7A,0xC8, 0xF6,0x82,
-0xC3,0x50, 0x96,0x93, 0xFF,0xFC, 0xF6,0x82, 0x00,0x16, 0x96,0x93, 0xFF,0xFC, 0xF6,0x86,
-0x42,0x30, 0x96,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x1E,0xC0, 0x97,0x93,
-0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF6,0x04,
-0x6F,0x34, 0x00,0x00, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x61,0xED, 0x76,0xB1,
-0x00,0x1E, 0x87,0x32, 0x00,0x00, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x20,0x3A, 0x00,0x07, 0xE6,0x00, 0x61,0xEC, 0x06,0xB0, 0x00,0x02, 0x87,0x36,
-0x00,0x00, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x20,0x3A, 0x00,0x01, 0xE6,0x00, 0x61,0xEC, 0xF5,0x06, 0x35,0xEC, 0xF7,0x04,
-0x42,0x30, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x52,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x62,0x11, 0xF5,0x82, 0x00,0x00, 0xF7,0x04, 0x42,0xA0, 0xF6,0x06,
-0x42,0xA2, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xE0,0x00, 0x62,0x68, 0xF7,0x33, 0x28,0x00, 0x87,0x32,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0xF7,0x05, 0xE0,0x00, 0x86,0xB2, 0x00,0x08, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x62,0x3C, 0xF6,0x85, 0xE0,0x04, 0x20,0x36, 0x00,0x00, 0xE6,0x00,
-0x62,0x40, 0x20,0x2E, 0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00,
-0x62,0x65, 0xF6,0x06, 0x42,0xA2, 0xF7,0x04, 0x42,0xA0, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33,
-0x28,0x00, 0xF0,0x05, 0x42,0x28, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0xF7,0x04, 0x42,0x3C, 0xF6,0x84, 0x6F,0x34, 0x07,0x38, 0x00,0x01, 0x20,0x36,
-0x00,0x00, 0xE6,0x00, 0x62,0xB1, 0xF7,0x05, 0x42,0x3C, 0x87,0x36, 0x00,0x00, 0xF5,0x9E,
-0x00,0x02, 0xC0,0x3A, 0x5A,0x00, 0xE6,0x00, 0x62,0xBD, 0xF5,0x86, 0x35,0xEC, 0xF7,0x04,
-0x42,0xA0, 0xE0,0x00, 0x62,0xDC, 0xF6,0x06, 0x42,0xA2, 0xF7,0x04, 0x42,0x30, 0x00,0x00,
-0x00,0x01, 0xC0,0x3A, 0x5A,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x62,0xF9, 0xF6,0x06, 0x42,0xA4, 0xF7,0x04, 0x42,0xA4, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xE0,0x00,
-0x63,0x0C, 0xF7,0x33, 0x28,0x00, 0x96,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x63,0x20, 0x97,0x93, 0xFF,0xFC, 0xF0,0x05, 0x42,0x28, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x20, 0x83,0x16, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x87,0x1A, 0x00,0x18, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x63,0x6C, 0xF7,0x02, 0x00,0x00, 0x83,0x9A, 0x00,0x1C, 0x00,0x00, 0x00,0x01, 0xF3,0x85,
-0x7A,0xC0, 0x84,0x9A, 0x00,0x14, 0xF7,0x05, 0x7A,0xC8, 0xF4,0x85, 0x7A,0xB0, 0xF7,0x05,
-0x7A,0xB8, 0x83,0x16, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x86,0x9A, 0x00,0x14, 0xF7,0x04,
-0x7A,0xB0, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x63,0xD0, 0xF6,0x02,
-0x00,0x00, 0x86,0x9A, 0x00,0x1C, 0xF7,0x04, 0x7A,0xC0, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x63,0xD0, 0x00,0x00, 0x00,0x01, 0x86,0x9A, 0x00,0x18, 0xF7,0x04,
-0x7A,0xB8, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x63,0xD0, 0x00,0x00,
-0x00,0x01, 0x86,0x9A, 0x00,0x20, 0xF7,0x04, 0x7A,0xC8, 0x00,0x00, 0x00,0x01, 0xC7,0x38,
-0x68,0x00, 0x20,0x3A, 0x00,0x64, 0xEE,0x00, 0x63,0xD9, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x64,0x58, 0x00,0x00, 0x00,0x01, 0x83,0x96,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x87,0x1E, 0x00,0x18, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x64,0x3C, 0xF7,0x02, 0x00,0x00, 0xF7,0x05, 0x40,0x80, 0xF7,0x05,
-0x40,0x84, 0xF6,0x84, 0x6E,0x50, 0xF4,0x82, 0xFF,0xFF, 0x83,0x1E, 0x00,0x0C, 0xF4,0x85,
-0x4F,0x54, 0x93,0x36, 0x00,0x10, 0x83,0x9E, 0x00,0x10, 0x84,0x96, 0x00,0x00, 0x93,0xB6,
-0x00,0x14, 0x84,0xA6, 0x00,0x08, 0x00,0x00, 0x00,0x01, 0x94,0xB6, 0x1D,0xDC, 0xF6,0x82,
-0x00,0x64, 0xF6,0x85, 0x4A,0x98, 0xF7,0x05, 0x4A,0x9C, 0x83,0x16, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x87,0x1A, 0x00,0x20, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xEE,0x00,
-0x64,0x7C, 0xF3,0x82, 0x00,0x00, 0xF7,0x04, 0x42,0xA4, 0xF6,0x06, 0x42,0xA6, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xE0,0x00, 0x66,0xE4, 0xF7,0x33, 0x28,0x00, 0x93,0x96, 0xFF,0xF4, 0x84,0x16,
-0x00,0x00, 0xF4,0x86, 0x42,0xC8, 0x94,0x96, 0xFF,0xEC, 0xF3,0x02, 0x00,0x0C, 0x93,0x16,
-0xFF,0xE4, 0x83,0x96, 0x00,0x00, 0x84,0x96, 0xFF,0xF4, 0x87,0x1E, 0x00,0x20, 0x00,0x00,
-0x00,0x01, 0xC0,0x26, 0x72,0x00, 0xEC,0x00, 0x66,0x48, 0xF3,0x86, 0x4A,0x98, 0x84,0xA2,
-0x00,0x24, 0x83,0x16, 0xFF,0xE4, 0xC5,0x04, 0x00,0x00, 0xB4,0x9A, 0x38,0x02, 0xC7,0x18,
-0x38,0x00, 0x83,0x22, 0x00,0x28, 0x83,0x96, 0xFF,0xF4, 0x84,0x96, 0xFF,0xE4, 0x93,0x3A,
-0x00,0x04, 0x93,0xBA, 0x00,0x08, 0xF6,0x04, 0xE0,0x00, 0xF3,0x06, 0x4A,0x98, 0xA6,0xA6,
-0x30,0x02, 0xF5,0x82, 0x00,0x00, 0xC0,0x32, 0x6A,0x00, 0xE6,0x00, 0x65,0x10, 0xC6,0x38,
-0x00,0x00, 0xF6,0x84, 0xE0,0x04, 0x87,0x32, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x65,0x14, 0x20,0x2E, 0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E,
-0x00,0x00, 0xE6,0x00, 0x65,0x21, 0x00,0x00, 0x00,0x01, 0xF5,0x02, 0x00,0x00, 0xF6,0x84,
-0xE0,0x00, 0x87,0x32, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00,
-0x65,0x5C, 0xF5,0x82, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x65,0x64, 0x20,0x2E,
-0x00,0x00, 0xF6,0x84, 0xE0,0x04, 0x87,0x32, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE2,0x00, 0x65,0x65, 0x20,0x2E, 0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E,
-0x00,0x00, 0xE6,0x00, 0x65,0x75, 0x20,0x2A, 0x00,0x00, 0xF5,0x02, 0x00,0x01, 0x20,0x2A,
-0x00,0x00, 0xE6,0x00, 0x65,0x88, 0x00,0x00, 0x00,0x01, 0x83,0x96, 0xFF,0xF4, 0x00,0x00,
-0x00,0x01, 0xF3,0x85, 0x4F,0x54, 0x87,0x22, 0x00,0x2C, 0x76,0xA1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0x05,0xA0, 0x00,0x2E, 0x76,0x2D, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xF4,0x82,
-0x00,0x00, 0x94,0x96, 0xFF,0xDC, 0x83,0x16, 0xFF,0xEC, 0x20,0x26, 0x00,0x07, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B, 0x28,0x00, 0x87,0x2E, 0x00,0x00, 0x06,0x98,
-0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xE2,0x00, 0x66,0x1C, 0xF7,0x37,
-0x28,0x00, 0x85,0x16, 0xFF,0xEC, 0x85,0x96, 0xFF,0xDC, 0x00,0x00, 0x00,0x01, 0xC7,0x2C,
-0x40,0x00, 0x86,0xBA, 0x00,0x30, 0x06,0x28, 0x00,0x04, 0x05,0x28, 0x00,0x02, 0x05,0xAC,
-0x00,0x02, 0x83,0x96, 0xFF,0xDC, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0x03,0x9C,
-0x00,0x01, 0x93,0x96, 0xFF,0xDC, 0x20,0x1E, 0x00,0x07, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB4,
-0xFF,0xF0, 0xE2,0x00, 0x65,0xE1, 0xF6,0xB3, 0x28,0x00, 0x04,0x20, 0x00,0x1C, 0x84,0x96,
-0xFF,0xEC, 0x83,0x16, 0xFF,0xE4, 0x83,0x96, 0xFF,0xF4, 0x04,0xA4, 0x00,0x14, 0x94,0x96,
-0xFF,0xEC, 0x03,0x18, 0x00,0x0C, 0x93,0x16, 0xFF,0xE4, 0x03,0x9C, 0x00,0x01, 0xE0,0x00,
-0x64,0x94, 0x93,0x96, 0xFF,0xF4, 0x84,0x96, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x87,0x26,
-0x00,0x20, 0x00,0x00, 0x00,0x01, 0xF7,0x05, 0x4A,0x9C, 0x85,0xA6, 0x00,0x20, 0xF7,0x04,
-0x7A,0xB8, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x7A,0xB8, 0xF7,0x04,
-0x7A,0xB8, 0xF6,0x84, 0x7A,0xC8, 0x86,0x26, 0x00,0x18, 0xC6,0xB4, 0x58,0x00, 0x87,0x26,
-0x00,0x1C, 0x00,0x00, 0x00,0x01, 0x27,0x38, 0x00,0x01, 0xC0,0x32, 0x72,0x00, 0x47,0x0C,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x66,0xE5, 0xF6,0x85, 0x7A,0xC8, 0x83,0x26,
-0x00,0x08, 0xF7,0x04, 0x6E,0x50, 0xF3,0x05, 0x3B,0x64, 0x83,0xA6, 0x00,0x08, 0xF6,0x82,
-0x00,0x00, 0x93,0xBA, 0x1D,0xDC, 0x84,0xA6, 0x00,0x0C, 0x83,0x16, 0x00,0x00, 0x94,0xBA,
-0x00,0x10, 0x83,0x1A, 0x00,0x10, 0xF6,0x85, 0x7A,0xC8, 0x93,0x3A, 0x00,0x14, 0xF7,0x02,
-0x00,0x01, 0xF7,0x05, 0x40,0x84, 0xF6,0x85, 0x7A,0xC0, 0xF6,0x85, 0x7A,0xB8, 0xF6,0x85,
-0x7A,0xB0, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10,
-0x00,0x08, 0xF3,0x84, 0x6F,0x34, 0x00,0x00, 0x00,0x01, 0x87,0x1E, 0x00,0x18, 0xF6,0x84,
-0xE0,0x1C, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xEC,0x00, 0x67,0x29, 0xF7,0x02,
-0x00,0x01, 0xF7,0x02, 0x00,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x67,0xE8, 0xF5,0x82,
-0x00,0x01, 0xF7,0x04, 0xE0,0x1C, 0x86,0x9E, 0x00,0x18, 0x00,0x00, 0x00,0x01, 0xC0,0x3A,
-0x6A,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x67,0xE9, 0xC5,0x84,
-0x00,0x00, 0x86,0x9E, 0x00,0x10, 0xF7,0x04, 0xE0,0x00, 0xF6,0x02, 0x00,0x00, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x67,0x88, 0x05,0x1C, 0x00,0x10, 0x86,0x9E, 0x00,0x14, 0xF7,0x04,
-0xE0,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x67,0x8C, 0x20,0x32,
-0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x67,0x99, 0x00,0x00,
-0x00,0x01, 0xF5,0x82, 0x00,0x00, 0x86,0xAA, 0x00,0x00, 0xF7,0x04, 0xE0,0x00, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0x67,0xD4, 0xF6,0x02, 0x00,0x00, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x67,0xDC, 0x20,0x32, 0x00,0x00, 0x86,0xAA, 0x00,0x04, 0xF7,0x04,
-0xE0,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0x67,0xDD, 0x20,0x32,
-0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x67,0xED, 0x20,0x2E,
-0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0x68,0x10, 0xF6,0x06,
-0x42,0x9C, 0xF7,0x04, 0x42,0x9C, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33, 0x28,0x00, 0xF7,0x04,
-0x75,0xF4, 0x75,0xAC, 0xFF,0xE1, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x68,0x45, 0x95,0x96,
-0xFF,0xF4, 0xF7,0x04, 0x42,0x98, 0xF6,0x06, 0x42,0x98, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33,
-0x28,0x00, 0x87,0x1E, 0x00,0x20, 0x04,0x1C, 0x00,0x20, 0x76,0xA1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x20,0x3A, 0x00,0x08, 0xEE,0x00,
-0x68,0xC4, 0xF3,0x06, 0x15,0x54, 0xF5,0x02, 0x00,0x00, 0x05,0x9C, 0x00,0x22, 0xC4,0xAC,
-0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x87,0x22, 0x00,0x00, 0x76,0xA1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0xC0,0x2A, 0x72,0x00, 0xEC,0x00,
-0x68,0xC0, 0xC6,0xA4, 0x60,0x00, 0xA7,0x26, 0x60,0x02, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0x05,0x28, 0x00,0x01, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xE8, 0xF7,0x2F,
-0x68,0x00, 0x05,0xAC, 0x00,0x01, 0xE0,0x00, 0x68,0x78, 0x06,0x30, 0x00,0x02, 0xF3,0x06,
-0x15,0x54, 0x93,0x13, 0xFF,0xFC, 0xF7,0x04, 0xE0,0x24, 0x00,0x00, 0x00,0x01, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x04, 0xE0,0x1C, 0x00,0x00, 0x00,0x01, 0x97,0x13, 0xFF,0xFC, 0xF3,0x06,
-0xE0,0x00, 0x93,0x13, 0xFF,0xFC, 0x93,0x93, 0xFF,0xFC, 0xF3,0x02, 0x00,0x01, 0x93,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xEE,0x64, 0x97,0x93, 0xFF,0xFC, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0x69,0x28, 0xF6,0x06, 0x42,0x9E, 0xF7,0x04, 0x42,0x9C, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xF7,0x33, 0x28,0x00, 0x83,0x16, 0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0x20,0x1A,
-0x00,0x00, 0xE6,0x00, 0x69,0x6C, 0xF3,0x06, 0x35,0xEC, 0xF7,0x04, 0x42,0x30, 0x00,0x00,
-0x00,0x01, 0xC0,0x3A, 0x32,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x69,0x6D, 0xF0,0x05, 0x42,0x28, 0xF3,0x06, 0x35,0x60, 0xF3,0x05, 0x42,0x30, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x78,0x9C, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x04, 0xF5,0x04, 0x6F,0x34, 0xF7,0x04,
-0x42,0x40, 0x86,0x2A, 0x00,0x18, 0x07,0x38, 0x00,0x01, 0xF6,0x84, 0xE0,0x1C, 0xF7,0x05,
-0x42,0x40, 0xC0,0x36, 0x62,0x00, 0xEC,0x00, 0x69,0xB5, 0xF7,0x02, 0x00,0x01, 0xF7,0x02,
-0x00,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x6A,0x80, 0xF7,0x02, 0x00,0x01, 0xF7,0x04,
-0xE0,0x1C, 0x86,0xAA, 0x00,0x18, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0x47,0x0C,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x6A,0x7D, 0xC5,0x84, 0x00,0x00, 0x86,0xAA,
-0x00,0x10, 0xF7,0x04, 0xE0,0x00, 0xF6,0x02, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0x6A,0x14, 0x04,0xA8, 0x00,0x10, 0x86,0xAA, 0x00,0x14, 0xF7,0x04, 0xE0,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x6A,0x18, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x6A,0x25, 0x00,0x00, 0x00,0x01, 0xF5,0x82,
-0x00,0x00, 0x86,0xA6, 0x00,0x00, 0xF7,0x04, 0xE0,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE2,0x00, 0x6A,0x60, 0xF6,0x02, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0x6A,0x68, 0x20,0x32, 0x00,0x00, 0x86,0xA6, 0x00,0x04, 0xF7,0x04, 0xE0,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0x6A,0x69, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x6A,0x81, 0xC7,0x2C, 0x00,0x00, 0xF5,0x82,
-0x00,0x01, 0xE0,0x00, 0x6A,0x80, 0xC7,0x2C, 0x00,0x00, 0xC7,0x04, 0x00,0x00, 0x20,0x3A,
-0x00,0x00, 0xEE,0x00, 0x6B,0x3D, 0xF6,0x86, 0x40,0x8A, 0xF7,0x04, 0x40,0x88, 0x76,0xB5,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x6B,0x3C, 0xF6,0x82, 0x00,0x00, 0xF6,0x85, 0x40,0x80, 0xF6,0x85,
-0x40,0x84, 0x96,0x93, 0xFF,0xFC, 0x96,0x93, 0xFF,0xFC, 0xF7,0x04, 0xE0,0x1C, 0x00,0x00,
-0x00,0x01, 0x97,0x13, 0xFF,0xFC, 0xF3,0x86, 0xE0,0x00, 0x93,0x93, 0xFF,0xFC, 0x95,0x13,
-0xFF,0xFC, 0xF3,0x82, 0x00,0x02, 0x93,0x93, 0xFF,0xFC, 0x96,0x96, 0xFF,0xF4, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xEE,0x64, 0x97,0x93, 0xFF,0xFC, 0xF4,0x05, 0x40,0x84, 0x86,0x96,
-0xFF,0xF4, 0xF7,0x04, 0x6E,0x50, 0xF3,0x86, 0x35,0xEC, 0xF6,0x85, 0x40,0x90, 0xF6,0x85,
-0x40,0x94, 0x87,0x3A, 0x1D,0xDC, 0xF6,0x85, 0x42,0x28, 0xF7,0x05, 0x3B,0x64, 0xF7,0x04,
-0x42,0x30, 0xF4,0x05, 0x40,0x80, 0xC0,0x3A, 0x3A,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x6B,0x3D, 0xF3,0x86, 0x35,0x60, 0xF3,0x85, 0x42,0x30, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x78,0x9C, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF4,0x86, 0x42,0x30, 0x94,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x20,0xE4, 0x97,0x93, 0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00,
-0x6D,0xD9, 0xF5,0x82, 0x00,0x00, 0xF7,0x04, 0x40,0x8C, 0xF6,0x06, 0x40,0x8C, 0x76,0x31,
-0x00,0x1E, 0xF6,0x84, 0x42,0x28, 0x76,0x30, 0xFF,0xE5, 0x06,0xB4, 0x00,0x01, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x6B,0xC8, 0xF6,0x85,
-0x42,0x28, 0xF7,0x04, 0x40,0x88, 0xF6,0x86, 0x40,0x8A, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x6D,0x0D, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x40,0x8C, 0xF6,0x86, 0x40,0x8C, 0x76,0xB5,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x6C,0x35, 0xF6,0x06, 0x40,0x8A, 0xF7,0x04, 0x40,0x88, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x6C,0x34, 0xF4,0x86, 0x36,0x78, 0xF7,0x04, 0x42,0x44, 0x00,0x00,
-0x00,0x01, 0xC0,0x3A, 0x4A,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x6C,0x35, 0xF4,0x82, 0x00,0x01, 0xF4,0xB3, 0x28,0x00, 0xE0,0x00, 0x6D,0x10, 0xF0,0x05,
-0x42,0x2C, 0xF7,0x04, 0x40,0x8C, 0xF5,0x06, 0x40,0x8C, 0x76,0xA9, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x6C,0xC1, 0xF6,0x06, 0x40,0x8A, 0xF7,0x04, 0x40,0x88, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x6C,0xC1, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x42,0x2C, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0x20,0x3A, 0x00,0x09, 0xEE,0x00, 0x6D,0x11, 0xF7,0x05, 0x42,0x2C, 0xF0,0x2B,
-0x28,0x00, 0xF0,0x33, 0x28,0x00, 0xF5,0x82, 0x00,0x01, 0xF7,0x04, 0x42,0x94, 0xF6,0x06,
-0x42,0x94, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xE0,0x00, 0x6D,0x10, 0xF7,0x33, 0x28,0x00, 0xF7,0x04,
-0x40,0x8C, 0xF6,0x86, 0x40,0x8C, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x6D,0x14, 0x20,0x2E,
-0x00,0x00, 0xF7,0x04, 0x40,0x88, 0xF6,0x06, 0x40,0x8A, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x6D,0x15, 0x20,0x2E, 0x00,0x00, 0xF0,0x33, 0x28,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E,
-0x00,0x00, 0xE6,0x00, 0x6D,0xB5, 0xF4,0x86, 0x35,0xEC, 0xF7,0x04, 0x42,0x30, 0x00,0x00,
-0x00,0x01, 0xC0,0x3A, 0x4A,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x6D,0x59, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0xE0,0x28, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x6D,0x79, 0xF6,0x82, 0x00,0x3C, 0xF6,0x84, 0xE0,0x28, 0xE0,0x00,
-0x6D,0x78, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0xE0,0x28, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x6D,0x79, 0xF6,0x82, 0x00,0xF0, 0xF7,0x04, 0xE0,0x28, 0x00,0x00,
-0x00,0x01, 0x76,0xB9, 0x00,0x02, 0xF7,0x04, 0x42,0x28, 0x00,0x00, 0x00,0x01, 0xC0,0x3A,
-0x6A,0x00, 0xEC,0x00, 0x6D,0xB5, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0xF0,0x05,
-0x42,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF4,0x82,
-0x00,0x19, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x6D,0xB4, 0xB4,0xBA, 0x68,0x02, 0xF0,0x05,
-0x2D,0x38, 0xF4,0x82, 0xC3,0x50, 0x94,0x93, 0xFF,0xFC, 0xF4,0x82, 0x00,0x16, 0x94,0x93,
-0xFF,0xFC, 0xF4,0x86, 0x42,0x30, 0x94,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01,
-0x1E,0xC0, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x22,0x10, 0x00,0x04, 0xF5,0x86, 0x36,0x78, 0x95,0x93, 0xFF,0xFC, 0xF5,0x86,
-0x42,0x44, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x48, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x82, 0x74,0x18, 0x95,0x93, 0xFF,0xFC, 0xF5,0x82, 0x00,0x19, 0x95,0x93,
-0xFF,0xFC, 0xF5,0x86, 0x36,0x78, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x82, 0x74,0xAC, 0x95,0x93, 0xFF,0xFC, 0xF7,0x82,
-0x00,0x1D, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86, 0x37,0x04, 0x95,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x82, 0x78,0x00, 0x95,0x93,
-0xFF,0xFC, 0xF7,0x82, 0x00,0x1B, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86, 0x37,0x04, 0x95,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x82,
-0x78,0xFC, 0x95,0x93, 0xFF,0xFC, 0xF7,0x82, 0x00,0x1A, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86,
-0x37,0x90, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x82, 0x80,0xD8, 0x95,0x93, 0xFF,0xFC, 0xF7,0x82, 0x00,0x1B, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x86, 0x37,0x90, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x82, 0x81,0x74, 0x95,0x93, 0xFF,0xFC, 0xF7,0x82,
-0x00,0x1D, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86, 0x38,0x1C, 0x95,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x82, 0x87,0x74, 0x95,0x93,
-0xFF,0xFC, 0xF7,0x82, 0x00,0x1B, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86, 0x38,0x1C, 0x95,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x82,
-0x94,0xF8, 0x95,0x93, 0xFF,0xFC, 0xF7,0x82, 0x00,0x1B, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86,
-0x39,0x34, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x82, 0x8A,0x00, 0x95,0x93, 0xFF,0xFC, 0xF7,0x82, 0x00,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x86, 0x39,0x34, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x82, 0x8E,0x08, 0x95,0x93, 0xFF,0xFC, 0xF7,0x82,
-0x00,0x1A, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86, 0x39,0x34, 0x95,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x82, 0x96,0x9C, 0x95,0x93,
-0xFF,0xFC, 0xF7,0x82, 0x00,0x1E, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86, 0x38,0xA8, 0x95,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x82,
-0x9B,0x2C, 0x95,0x93, 0xFF,0xFC, 0xF7,0x82, 0x00,0x1B, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86,
-0x38,0xA8, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x82, 0xA2,0xDC, 0x95,0x93, 0xFF,0xFC, 0xF7,0x82, 0x00,0x1E, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x86, 0x3A,0xD8, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x82, 0x9E,0x54, 0x95,0x93, 0xFF,0xFC, 0xF7,0x82,
-0x00,0x1B, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86, 0x3A,0xD8, 0x95,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x82, 0xA3,0xC0, 0x95,0x93,
-0xFF,0xFC, 0xF7,0x82, 0x00,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86, 0x39,0xC0, 0x95,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x82,
-0xA7,0x64, 0x95,0x93, 0xFF,0xFC, 0xF7,0x82, 0x00,0x1E, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86,
-0x39,0xC0, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x82, 0xAA,0x04, 0x95,0x93, 0xFF,0xFC, 0xF7,0x82, 0x00,0x1B, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x86, 0x39,0xC0, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x82, 0xAE,0xF8, 0x95,0x93, 0xFF,0xFC, 0xF7,0x82,
-0x00,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86, 0x3A,0x4C, 0x95,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x42,0x50, 0xF0,0x3B,
-0x28,0x00, 0xF7,0x06, 0x40,0x88, 0xF0,0x3B, 0x28,0x00, 0xF6,0x02, 0x00,0x00, 0xF6,0x05,
-0x40,0x80, 0xF6,0x05, 0x40,0x84, 0xF7,0x06, 0x3B,0x70, 0xF6,0x3B, 0x28,0x00, 0xF7,0x06,
-0x3B,0x72, 0xF0,0xBB, 0x28,0x00, 0xF5,0x82, 0xCA,0x20, 0xF5,0x85, 0x3B,0x74, 0xF7,0x06,
-0x3B,0x78, 0xF0,0x3B, 0x28,0x00, 0xF7,0x06, 0x3B,0x7A, 0xF0,0xBB, 0x28,0x00, 0xF5,0x82,
-0xB1,0x94, 0xF5,0x85, 0x3B,0x7C, 0xF7,0x06, 0x3B,0x80, 0xF0,0x3B, 0x28,0x00, 0xF7,0x06,
-0x3B,0x82, 0xF0,0xBB, 0x28,0x00, 0xF5,0x82, 0xC7,0x54, 0xF5,0x85, 0x3B,0x84, 0xF7,0x06,
-0x3B,0x88, 0xF0,0x3B, 0x28,0x00, 0xF7,0x06, 0x3B,0x8A, 0xF0,0xBB, 0x28,0x00, 0xF5,0x82,
-0xBE,0xF8, 0xF5,0x85, 0x3B,0x8C, 0xF7,0x06, 0x3B,0x90, 0xF0,0x3B, 0x28,0x00, 0xF7,0x06,
-0x3B,0x92, 0xF0,0xBB, 0x28,0x00, 0xF5,0x82, 0xC8,0xF8, 0xF5,0x85, 0x3B,0x94, 0xF7,0x06,
-0x3B,0x98, 0xF0,0x3B, 0x28,0x00, 0xF7,0x06, 0x3B,0x9A, 0xF0,0xBB, 0x28,0x00, 0xF5,0x82,
-0xC5,0xD8, 0xF5,0x85, 0x3B,0x9C, 0xF7,0x06, 0x3B,0xA0, 0xF0,0x3B, 0x28,0x00, 0xF7,0x06,
-0x3B,0xA2, 0xF0,0xBB, 0x28,0x00, 0xF5,0x82, 0xC7,0x70, 0xF5,0x85, 0x3B,0xA4, 0xF7,0x06,
-0x3B,0xA8, 0xF0,0x3B, 0x28,0x00, 0xF7,0x06, 0x3B,0xAA, 0xF0,0xBB, 0x28,0x00, 0xF5,0x82,
-0xC1,0xB4, 0xF5,0x85, 0x3B,0xAC, 0x96,0x16, 0xFF,0xF4, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xD5,0x40, 0x97,0x93, 0xFF,0xFC, 0xF6,0x84, 0x6E,0x50, 0x86,0x16, 0xFF,0xF4, 0x00,0x00,
-0x00,0x01, 0x96,0x36, 0x1D,0xDC, 0xF6,0x05, 0x3B,0x64, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x30, 0x25,0x94, 0x00,0x20, 0xF0,0x2F,
-0x28,0x00, 0x26,0x14, 0x00,0x38, 0xF0,0x33, 0x28,0x00, 0x90,0x13, 0xFF,0xFC, 0xF7,0x04,
-0x42,0x50, 0xF6,0x86, 0x42,0x50, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x97,0x13, 0xFF,0xFC, 0x96,0x13, 0xFF,0xFC, 0x95,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xF5,0xF4, 0x97,0x93, 0xFF,0xFC, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0x72,0x1D, 0xF5,0x02, 0x17,0x70, 0xF7,0x04, 0x42,0x54, 0x00,0x00,
-0x00,0x01, 0x27,0x38, 0x00,0x01, 0xF7,0x05, 0x42,0x54, 0x95,0x13, 0xFF,0xFC, 0xF5,0x02,
-0x00,0x1B, 0x95,0x13, 0xFF,0xFC, 0xF5,0x06, 0x42,0x44, 0x95,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x1E,0xC0, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x04, 0xE0,0x04, 0x86,0x16, 0x00,0x00, 0xF6,0x82,
-0x00,0xFF, 0x77,0x39, 0xFF,0xF0, 0xC7,0x38, 0x6C,0x00, 0xF7,0x33, 0x28,0x00, 0xF7,0x06,
-0xE0,0x06, 0x87,0x3A, 0x00,0x00, 0x06,0xB0, 0x00,0x02, 0xF7,0x37, 0x28,0x00, 0xF6,0x84,
-0x3B,0x64, 0x07,0x30, 0x00,0x04, 0xF6,0xBB, 0x28,0x00, 0x87,0x02, 0xFF,0x34, 0x06,0x30,
-0x00,0x06, 0xF7,0x33, 0x28,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x22,0x10, 0x00,0x30, 0x26,0x14, 0x00,0x20, 0xF0,0x33, 0x28,0x00, 0x27,0x14,
-0x00,0x38, 0xF0,0x3B, 0x28,0x00, 0x97,0x13, 0xFF,0xFC, 0x90,0x93, 0xFF,0xFC, 0xF7,0x04,
-0x42,0x50, 0xF6,0x86, 0x42,0x50, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x97,0x13, 0xFF,0xFC, 0x96,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xF3,0x38, 0x97,0x93, 0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00,
-0x73,0x19, 0xF5,0x82, 0x17,0x70, 0xF7,0x04, 0x42,0x54, 0x00,0x00, 0x00,0x01, 0x27,0x38,
-0x00,0x01, 0xF7,0x05, 0x42,0x54, 0x95,0x93, 0xFF,0xFC, 0xF5,0x82, 0x00,0x1B, 0x95,0x93,
-0xFF,0xFC, 0xF5,0x86, 0x42,0x44, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01,
-0x1E,0xC0, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x22,0x10, 0x00,0x40, 0x26,0x14, 0x00,0x20, 0x96,0x16, 0xFF,0xC4, 0xF0,0x33,
-0x28,0x00, 0x90,0x13, 0xFF,0xFC, 0x96,0x13, 0xFF,0xFC, 0x26,0x14, 0x00,0x38, 0x96,0x16,
-0xFF,0xBC, 0x96,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xD0,0xDC, 0x97,0x93,
-0xFF,0xFC, 0x90,0x13, 0xFF,0xFC, 0xF7,0x04, 0x42,0x50, 0xF6,0x86, 0x42,0x50, 0x76,0xB5,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x97,0x13,
-0xFF,0xFC, 0x86,0x16, 0xFF,0xBC, 0x00,0x00, 0x00,0x01, 0x96,0x13, 0xFF,0xFC, 0x86,0x16,
-0xFF,0xC4, 0x00,0x00, 0x00,0x01, 0x96,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xF5,0xF4, 0x97,0x93, 0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x73,0xE5, 0xF6,0x02,
-0x17,0x70, 0xF7,0x04, 0x42,0x54, 0x00,0x00, 0x00,0x01, 0x27,0x38, 0x00,0x01, 0xF7,0x05,
-0x42,0x54, 0x96,0x13, 0xFF,0xFC, 0xF6,0x02, 0x00,0x1B, 0x96,0x13, 0xFF,0xFC, 0xF6,0x06,
-0x42,0x44, 0x96,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x1E,0xC0, 0x97,0x93,
-0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10,
-0x00,0x04, 0xF5,0x82, 0x00,0x00, 0xF5,0x85, 0x40,0x80, 0x95,0x96, 0xFF,0xF4, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xCB,0x50, 0x97,0x93, 0xFF,0xFC, 0x85,0x96, 0xFF,0xF4, 0xF5,0x02,
-0x00,0x64, 0xF5,0x05, 0x3B,0xB4, 0xF7,0x04, 0x42,0x50, 0xF4,0x86, 0x42,0x50, 0x76,0xA5,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xF6,0x04, 0x4F,0x5C, 0xF4,0x02, 0x00,0x06, 0xF4,0x05,
-0x42,0x54, 0xF5,0x85, 0x3B,0x6C, 0xF5,0x85, 0x3B,0xB8, 0x95,0x32, 0x00,0x00, 0x95,0xB2,
-0x00,0x04, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x27,
-0x28,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x71,0xB0, 0x97,0x93, 0xFF,0xFC, 0xF4,0x06,
-0x37,0x04, 0xF4,0x05, 0x42,0x44, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x22,0x10, 0x00,0x50, 0xF7,0x04, 0x42,0x50, 0xF6,0x86, 0x42,0x50, 0x76,0xB5,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xF6,0x04, 0x6F,0x34, 0xC7,0x38, 0x6F,0xC0, 0x86,0xB2,
-0x00,0x0C, 0x77,0x39, 0xFF,0xF0, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x77,0xEC, 0xC5,0x04,
-0x00,0x00, 0x86,0xB2, 0x00,0x10, 0xF7,0x04, 0xE0,0x00, 0xF3,0x02, 0x00,0x00, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x75,0x18, 0x04,0xB0, 0x00,0x10, 0x86,0xB2, 0x00,0x14, 0xF7,0x04,
-0xE0,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x75,0x1C, 0x20,0x1A,
-0x00,0x00, 0xF3,0x02, 0x00,0x01, 0x20,0x1A, 0x00,0x00, 0xE6,0x00, 0x75,0x29, 0x00,0x00,
-0x00,0x01, 0xF5,0x02, 0x00,0x00, 0x86,0xA6, 0x00,0x00, 0xF7,0x04, 0xE0,0x00, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0x75,0x64, 0xF6,0x02, 0x00,0x00, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x75,0x6C, 0x20,0x32, 0x00,0x00, 0x86,0xA6, 0x00,0x04, 0xF7,0x04,
-0xE0,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0x75,0x6D, 0x20,0x32,
-0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x75,0x7D, 0x20,0x2A,
-0x00,0x00, 0xF5,0x02, 0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x00, 0x77,0xEC, 0x00,0x00,
-0x00,0x01, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCB,0xCC, 0x97,0x93, 0xFF,0xFC, 0x26,0x14,
-0x00,0x20, 0xF0,0x33, 0x28,0x00, 0x04,0xA0, 0x00,0x02, 0xF0,0x27, 0x28,0x00, 0xF5,0x82,
-0x00,0x00, 0x23,0x94, 0x00,0x22, 0xF5,0x9F, 0x28,0x00, 0x03,0xA0, 0x00,0x1A, 0x93,0x96,
-0xFF,0xD4, 0x25,0x94, 0x00,0x22, 0x85,0xAE, 0x00,0x00, 0x77,0xAD, 0x00,0x1E, 0x77,0xBC,
-0xFF,0xE5, 0xC5,0xAC, 0x7F,0xC0, 0x75,0xAD, 0xFF,0xF0, 0x76,0x31, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0x06,0xA4, 0x00,0x02, 0x23,0x14, 0x00,0x1E, 0x75,0x15, 0x00,0x1E, 0xF5,0x9F,
-0x28,0x00, 0xF3,0x84, 0xE0,0x00, 0x75,0x28, 0xFF,0xE5, 0x93,0xA2, 0x00,0x1C, 0xF5,0x84,
-0xE0,0x04, 0x73,0x99, 0x00,0x1E, 0x73,0x9C, 0xFF,0xE5, 0x93,0x96, 0xFF,0xAC, 0x73,0x95,
-0x00,0x1E, 0x73,0x9C, 0xFF,0xE5, 0x93,0x96, 0xFF,0xCC, 0x23,0x94, 0x00,0x42, 0x95,0xA2,
-0x00,0x20, 0x87,0x16, 0xFF,0xE0, 0x75,0x95, 0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0x95,0x96,
-0xFF,0xB4, 0x75,0x95, 0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0x95,0x96, 0xFF,0xC4, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0xF4,0x84, 0x4F,0x58, 0x87,0x1A,
-0x00,0x00, 0xC4,0xA0, 0x4A,0x00, 0x74,0xA4, 0xFF,0xFA, 0xC5,0xA4, 0x00,0x00, 0xF5,0x9F,
-0x28,0x00, 0x83,0x96, 0xFF,0xAC, 0x23,0x14, 0x00,0x1A, 0x76,0x19, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0x85,0x96, 0xFF,0xB4, 0xC7,0x38, 0x3F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16, 0xFF,0xE4, 0x83,0x96, 0xFF,0xCC, 0xC7,0x38,
-0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4,
-0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4,
-0x00,0x02, 0x87,0x16, 0xFF,0xE8, 0x23,0x14, 0x00,0x16, 0x76,0x19, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1A,
-0x00,0x00, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16, 0xFF,0xEC, 0x23,0x14, 0x00,0x12, 0x76,0x19,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x3F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4, 0x00,0x02, 0x85,0x96, 0xFF,0xC4, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x16, 0xFF,0xF0, 0x06,0xB4,
-0x00,0x02, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0xF3,0x82,
-0x00,0x02, 0xF3,0xA3, 0x28,0x00, 0x04,0x20, 0x00,0x18, 0x25,0x94, 0x00,0x22, 0x85,0xAE,
-0x00,0x00, 0x77,0xAD, 0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC5,0xAC, 0x7F,0xC0, 0x75,0xAD,
-0xFF,0xF0, 0x83,0x96, 0xFF,0xD4, 0xF5,0xA3, 0x28,0x00, 0xF4,0x9F, 0x28,0x00, 0x25,0x94,
-0x00,0x42, 0x85,0xAE, 0x00,0x00, 0x77,0xAD, 0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC5,0xAC,
-0x7F,0xC0, 0x75,0xAD, 0xFF,0xF0, 0x44,0xAD, 0x00,0x00, 0x94,0x93, 0xFF,0xFC, 0xF7,0x86,
-0xE0,0x00, 0x97,0x93, 0xFF,0xFC, 0xF3,0x84, 0x4F,0x5C, 0x00,0x00, 0x00,0x01, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x23,0x40, 0x97,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x78,0xD8, 0x97,0x93, 0xFF,0xFC, 0xF0,0x05, 0x40,0x84, 0xF7,0x86,
-0xE0,0x00, 0x97,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xD5,0xA0, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x04, 0x6E,0x50, 0xF4,0x05, 0x40,0x84, 0x87,0x3A, 0x1D,0xDC, 0x00,0x00,
-0x00,0x01, 0xF7,0x05, 0x3B,0x64, 0xF5,0x86, 0x36,0x78, 0xF5,0x85, 0x42,0x44, 0xF3,0x86,
-0x35,0x60, 0xF3,0x85, 0x42,0x30, 0xF5,0x86, 0x42,0x44, 0x95,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x1F,0x48, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF5,0x86, 0x42,0x44, 0x95,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x20,0xE4, 0x97,0x93, 0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00,
-0x78,0x89, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x42,0x54, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xEE,0x00, 0x78,0x51, 0xF6,0x06, 0x42,0x50, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x71,0xB0, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x78,0x88, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x42,0x50, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xF5,0x82, 0x00,0x06, 0xF5,0x85,
-0x42,0x54, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33,
-0x28,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x72,0xAC, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86,
-0x37,0x90, 0xF5,0x85, 0x42,0x44, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0xF6,0x06, 0x36,0x78, 0xF6,0x05, 0x42,0x44, 0xF7,0x02, 0x00,0x00, 0xF7,0x05,
-0x40,0x80, 0xF7,0x05, 0x40,0x94, 0xF6,0x84, 0x6E,0x50, 0xF7,0x05, 0x40,0x90, 0x97,0x36,
-0x1D,0xDC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x02,
-0x00,0x01, 0xF7,0x05, 0x40,0x80, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x22,0x10, 0x00,0xA8, 0xF7,0x04, 0x42,0x50, 0xF5,0x86, 0x42,0x50, 0x76,0xAD,
-0x00,0x1E, 0xF4,0x84, 0x6F,0x34, 0x76,0xB4, 0xFF,0xE5, 0x94,0x96, 0xFF,0xC4, 0xC7,0x38,
-0x6F,0xC0, 0x86,0xA6, 0x00,0x0C, 0x77,0x39, 0xFF,0xF0, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0x79,0x55, 0xF6,0x06, 0x42,0x9A, 0xF7,0x04, 0x42,0x98, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33,
-0x28,0x00, 0xF7,0x04, 0x42,0x50, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x85,0x16,
-0xFF,0xC4, 0xC7,0x38, 0x6F,0xC0, 0x86,0xAA, 0x00,0x0C, 0x77,0x39, 0xFF,0xF0, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x80,0xA8, 0xF6,0x06, 0x42,0x9A, 0x87,0x2A, 0x00,0x10, 0x86,0x2A,
-0x00,0x1C, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x79,0xA8, 0xF6,0x82, 0x00,0x00, 0x87,0x2A,
-0x00,0x14, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x79,0xAC, 0x20,0x36,
-0x00,0x00, 0xF6,0x82, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0x7A,0x05, 0x24,0x94,
-0x00,0x20, 0x94,0x96, 0xFF,0xBC, 0x85,0x16, 0xFF,0xC4, 0xF0,0x27, 0x28,0x00, 0x05,0x28,
-0x00,0x10, 0x95,0x16, 0xFF,0xB4, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x72,0x50, 0x97,0x93, 0xFF,0xFC, 0x84,0x96, 0xFF,0xB4, 0x00,0x00, 0x00,0x01, 0x94,0x93,
-0xFF,0xFC, 0x85,0x16, 0xFF,0xBC, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xF9,0x34, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x80,0xC4, 0x00,0x00,
-0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x80,0x6C, 0x00,0x00, 0x00,0x01, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xCB,0xCC, 0x97,0x93, 0xFF,0xFC, 0x25,0x94, 0x00,0x20, 0xF0,0x2F,
-0x28,0x00, 0x04,0xA0, 0x00,0x02, 0x94,0x96, 0xFF,0x5C, 0xF0,0x27, 0x28,0x00, 0xF4,0x82,
-0x00,0x00, 0x25,0x14, 0x00,0x5A, 0xF4,0xAB, 0x28,0x00, 0x07,0x20, 0x00,0x1A, 0x25,0x14,
-0x00,0x5A, 0x85,0x2A, 0x00,0x00, 0x77,0xA9, 0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC5,0x28,
-0x7F,0xC0, 0x75,0x29, 0xFF,0xF0, 0x75,0xAD, 0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0x23,0x14,
-0x00,0x1E, 0x76,0x19, 0x00,0x1E, 0xF5,0x3B, 0x28,0x00, 0xF4,0x84, 0xE0,0x00, 0x76,0x30,
-0xFF,0xE5, 0x94,0xA2, 0x00,0x1C, 0xF5,0x04, 0xE0,0x04, 0x84,0x96, 0xFF,0x5C, 0x95,0x22,
-0x00,0x20, 0x87,0x16, 0xFF,0xE0, 0x06,0xA4, 0x00,0x02, 0x75,0x15, 0x00,0x1E, 0x75,0x28,
-0xFF,0xE5, 0x95,0x16, 0xFF,0x54, 0x74,0x95, 0x00,0x1E, 0x74,0xA4, 0xFF,0xE5, 0x94,0x96,
-0xFF,0x9C, 0x75,0x15, 0x00,0x1E, 0x75,0x28, 0xFF,0xE5, 0x95,0x16, 0xFF,0x94, 0x74,0x95,
-0x00,0x1E, 0x85,0x16, 0xFF,0x5C, 0x74,0xA4, 0xFF,0xE5, 0x94,0x96, 0xFF,0x8C, 0x84,0x96,
-0xFF,0x54, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x87,0x1A,
-0x00,0x00, 0x85,0x16, 0xFF,0x9C, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16, 0xFF,0xE4, 0x23,0x14, 0x00,0x1A, 0x76,0x19,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4, 0x00,0x02, 0x84,0x96, 0xFF,0x94, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16,
-0xFF,0xE8, 0x23,0x14, 0x00,0x16, 0x76,0x19, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38,
-0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4,
-0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4,
-0x00,0x02, 0x87,0x16, 0xFF,0xEC, 0x23,0x14, 0x00,0x12, 0x76,0x19, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1A,
-0x00,0x00, 0x06,0xB4, 0x00,0x02, 0x85,0x16, 0xFF,0x8C, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x16, 0xFF,0xF0, 0x06,0xB4, 0x00,0x02, 0xC7,0x38,
-0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0xF4,0x82, 0x00,0x02, 0xF4,0xA3,
-0x28,0x00, 0x25,0x14, 0x00,0x5A, 0x85,0x2A, 0x00,0x00, 0x77,0xA9, 0x00,0x1E, 0x77,0xBC,
-0xFF,0xE5, 0xC5,0x28, 0x7F,0xC0, 0x75,0x29, 0xFF,0xF0, 0x07,0x20, 0x00,0x18, 0xF5,0x3B,
-0x28,0x00, 0x94,0x16, 0xFF,0xAC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCB,0xCC, 0x97,0x93,
-0xFF,0xFC, 0x26,0x14, 0x00,0x38, 0x24,0x94, 0x00,0x5A, 0x84,0xA6, 0x00,0x00, 0x77,0xA5,
-0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC4,0xA4, 0x7F,0xC0, 0x74,0xA5, 0xFF,0xF0, 0x05,0xA0,
-0x00,0x02, 0x06,0xAC, 0x00,0x02, 0x23,0x94, 0x00,0x36, 0x75,0x1D, 0x00,0x1E, 0x75,0x28,
-0xFF,0xE5, 0x07,0x20, 0x00,0x1A, 0xF4,0xB3, 0x28,0x00, 0x76,0x31, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0x95,0x16, 0xFF,0x54, 0x74,0x95, 0x00,0x1E, 0x74,0xA4, 0xFF,0xE5, 0x94,0x96,
-0xFF,0x5C, 0x75,0x15, 0x00,0x1E, 0x75,0x28, 0xFF,0xE5, 0x95,0x16, 0xFF,0x7C, 0x74,0x95,
-0x00,0x1E, 0x85,0x16, 0xFF,0xC4, 0x74,0xA4, 0xFF,0xE5, 0x94,0x96, 0xFF,0x74, 0x85,0x2A,
-0x00,0x34, 0x24,0x94, 0x00,0x5A, 0x95,0x16, 0xFF,0x84, 0x84,0xA6, 0x00,0x00, 0x77,0xA5,
-0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC4,0xA4, 0x7F,0xC0, 0x74,0xA5, 0xFF,0xF0, 0x25,0x14,
-0x00,0x5A, 0xF4,0xAF, 0x28,0x00, 0x85,0x2A, 0x00,0x00, 0x77,0xA9, 0x00,0x1E, 0x77,0xBC,
-0xFF,0xE5, 0xC5,0x28, 0x7F,0xC0, 0x75,0x29, 0xFF,0xF0, 0x84,0x96, 0xFF,0xC4, 0xF5,0x3B,
-0x28,0x00, 0x84,0xA6, 0x00,0x10, 0x85,0x16, 0xFF,0xC4, 0x94,0xA2, 0x00,0x1C, 0x85,0x2A,
-0x00,0x14, 0x74,0x95, 0x00,0x1E, 0x74,0xA4, 0xFF,0xE5, 0x94,0x96, 0xFF,0x6C, 0x95,0x22,
-0x00,0x20, 0x87,0x16, 0xFF,0xC8, 0x85,0x16, 0xFF,0x54, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x87,0x1E, 0x00,0x00, 0x84,0x96, 0xFF,0x5C, 0xC7,0x38,
-0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16,
-0xFF,0xCC, 0x23,0x94, 0x00,0x32, 0x76,0x1D, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0x85,0x16,
-0xFF,0x7C, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1E,
-0x00,0x00, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16, 0xFF,0xD0, 0x23,0x94, 0x00,0x2E, 0x76,0x1D,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x87,0x1E, 0x00,0x00, 0x06,0xB4, 0x00,0x02, 0x84,0x96, 0xFF,0x74, 0x85,0x16,
-0xFF,0x6C, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4,
-0x00,0x02, 0x87,0x16, 0xFF,0xD4, 0x23,0x94, 0x00,0x2A, 0x76,0x1D, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1E,
-0x00,0x00, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x87,0x16, 0xFF,0xD8, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x57,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0xF4,0x82, 0x00,0x02, 0xF4,0xA3, 0x28,0x00, 0x07,0x20,
-0x00,0x18, 0x25,0x14, 0x00,0x7A, 0x85,0x2A, 0x00,0x00, 0x77,0xA9, 0x00,0x1E, 0x77,0xBC,
-0xFF,0xE5, 0xC5,0x28, 0x7F,0xC0, 0x75,0x29, 0xFF,0xF0, 0x84,0x96, 0xFF,0xC4, 0xF5,0x3B,
-0x28,0x00, 0x87,0x26, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x24, 0xF7,0x04,
-0x4F,0x58, 0xE6,0x00, 0x7E,0xF9, 0x94,0x16, 0xFF,0x54, 0xC7,0x20, 0x72,0x00, 0xF6,0x84,
-0x6E,0x50, 0x86,0x26, 0x00,0x2C, 0x77,0x38, 0xFF,0xFA, 0x25,0x14, 0x00,0x5A, 0x84,0x2A,
-0x00,0x00, 0x77,0xA9, 0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC4,0x20, 0x7F,0xC0, 0x74,0x21,
-0xFF,0xF0, 0x47,0x39, 0x00,0x00, 0x86,0xB6, 0x1D,0xDC, 0x77,0x39, 0x00,0x02, 0xC0,0x32,
-0x6A,0x00, 0x46,0x8C, 0x00,0x01, 0xD6,0x80, 0x0A,0x68, 0x20,0x36, 0x00,0x00, 0xF6,0x86,
-0x40,0x98, 0xE6,0x00, 0x7E,0xC0, 0xC3,0xB8, 0x68,0x00, 0xC5,0x84, 0x00,0x00, 0x86,0xA6,
-0x00,0x24, 0xF7,0x04, 0xE0,0x00, 0xF6,0x02, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0x7E,0x54, 0x03,0x24, 0x00,0x24, 0x86,0xA6, 0x00,0x28, 0xF7,0x04, 0xE0,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x7E,0x58, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x7E,0x65, 0x00,0x00, 0x00,0x01, 0xF5,0x82,
-0x00,0x00, 0x86,0x9A, 0x00,0x00, 0xF7,0x04, 0xE0,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE2,0x00, 0x7E,0xA0, 0xF6,0x02, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0x7E,0xA8, 0x20,0x32, 0x00,0x00, 0x86,0x9A, 0x00,0x04, 0xF7,0x04, 0xE0,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0x7E,0xA9, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x7E,0xB9, 0x20,0x2E, 0x00,0x00, 0xF5,0x82,
-0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0x7E,0xC5, 0x00,0x00, 0x00,0x01, 0xF4,0x02,
-0x00,0x01, 0xF7,0x04, 0x4F,0x58, 0xF4,0x1F, 0x28,0x00, 0x84,0x96, 0xFF,0x54, 0x85,0x16,
-0xFF,0xC4, 0xF6,0x86, 0x40,0x9A, 0xC7,0x24, 0x72,0x00, 0x77,0x38, 0xFF,0xFA, 0x86,0x2A,
-0x00,0x30, 0x47,0x39, 0x00,0x00, 0x77,0x39, 0x00,0x02, 0xC7,0x38, 0x68,0x00, 0xE0,0x00,
-0x7F,0x4C, 0xF6,0x3B, 0x28,0x00, 0x84,0x96, 0xFF,0x54, 0xF6,0x06, 0x40,0x98, 0xC7,0x24,
-0x72,0x00, 0x77,0x38, 0xFF,0xFA, 0xC6,0xB8, 0x00,0x00, 0x46,0xB5, 0x00,0x00, 0x76,0xB5,
-0x00,0x02, 0xC6,0xB4, 0x60,0x00, 0xF5,0x02, 0x00,0x01, 0xF5,0x37, 0x28,0x00, 0x47,0x39,
-0x00,0x00, 0x77,0x39, 0x00,0x02, 0xC7,0x38, 0x60,0x00, 0x24,0x94, 0x00,0x5A, 0x84,0xA6,
-0x00,0x00, 0x77,0xA5, 0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC4,0xA4, 0x7F,0xC0, 0x74,0xA5,
-0xFF,0xF0, 0x07,0x38, 0x00,0x02, 0xF4,0xBB, 0x28,0x00, 0xF7,0x04, 0x4F,0x58, 0x85,0x16,
-0xFF,0x54, 0x84,0x96, 0xFF,0xAC, 0xC6,0xA8, 0x72,0x00, 0x76,0xB4, 0xFF,0xFA, 0x06,0x24,
-0x00,0x1A, 0xF6,0xB3, 0x28,0x00, 0xC7,0x24, 0x72,0x00, 0x77,0x38, 0xFF,0xFA, 0x06,0xA8,
-0x00,0x1A, 0xF7,0x37, 0x28,0x00, 0x47,0x39, 0x00,0x00, 0x97,0x13, 0xFF,0xFC, 0x07,0x24,
-0x00,0x1C, 0x97,0x13, 0xFF,0xFC, 0xF5,0x04, 0x4F,0x5C, 0x00,0x00, 0x00,0x01, 0x95,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x23,0x40, 0x97,0x93, 0xFF,0xFC, 0xF7,0x04,
-0x4F,0x58, 0x84,0x96, 0xFF,0x54, 0x00,0x00, 0x00,0x01, 0xC7,0x24, 0x72,0x00, 0x77,0x38,
-0xFF,0xFA, 0x47,0x39, 0x00,0x00, 0x97,0x13, 0xFF,0xFC, 0x07,0x24, 0x00,0x1C, 0x97,0x13,
-0xFF,0xFC, 0xF5,0x04, 0x4F,0x5C, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x23,0x40, 0x97,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x78,0xD8, 0x97,0x93, 0xFF,0xFC, 0xF6,0x84, 0x6E,0x50, 0x00,0x00, 0x00,0x01, 0x87,0x36,
-0x1D,0xDC, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x36, 0x1D,0xDC, 0x87,0x36,
-0x1D,0xDC, 0xF0,0x05, 0x40,0x84, 0xF4,0x86, 0xE0,0x00, 0x94,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xD5,0xA0, 0x97,0x93, 0xFF,0xFC, 0xF4,0x05, 0x40,0x84, 0xF7,0x04,
-0x6E,0x50, 0xF0,0x05, 0x42,0x5C, 0x87,0x3A, 0x1D,0xDC, 0xF6,0x86, 0x2C,0x28, 0xF7,0x05,
-0x3B,0x64, 0xF7,0x04, 0x2D,0x38, 0xF5,0x06, 0x3A,0x4C, 0xF5,0x05, 0x42,0x44, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF4,0x82, 0x00,0x1C, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x80,0x60, 0xB4,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF5,0x06,
-0x35,0xEC, 0xE0,0x00, 0x80,0x8C, 0xF5,0x05, 0x42,0x30, 0x20,0x32, 0x00,0x01, 0xE6,0x00,
-0x80,0xC4, 0x00,0x00, 0x00,0x01, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x78,0x9C, 0x97,0x93,
-0xFF,0xFC, 0xF4,0x86, 0x35,0x60, 0xF4,0x85, 0x42,0x30, 0xF5,0x06, 0x42,0x44, 0x95,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x1F,0x48, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00,
-0x80,0xC4, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x42,0x98, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33,
-0x28,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF5,0x86,
-0x42,0x44, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x20,0xE4, 0x97,0x93,
-0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x81,0x61, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x42,0x54, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xEE,0x00, 0x81,0x29, 0xF6,0x06,
-0x42,0x50, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x72,0xAC, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00,
-0x81,0x60, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x42,0x50, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xF5,0x82, 0x00,0x06, 0xF5,0x85, 0x42,0x54, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33, 0x28,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x73,0x4C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x86, 0x38,0x1C, 0xF5,0x85, 0x42,0x44, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x58, 0xF7,0x04,
-0x42,0x50, 0xF6,0x86, 0x42,0x50, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xF6,0x04,
-0x6F,0x34, 0xC7,0x38, 0x6F,0xC0, 0x86,0xB2, 0x00,0x0C, 0x77,0x39, 0xFF,0xF0, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x82,0x50, 0xF4,0x82, 0x00,0x00, 0xC5,0x04, 0x00,0x00, 0x86,0xB2,
-0x00,0x10, 0xF7,0x04, 0xE0,0x00, 0xC5,0xA4, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0x81,0xE4, 0x04,0x30, 0x00,0x10, 0x86,0xB2, 0x00,0x14, 0xF7,0x04, 0xE0,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x81,0xE8, 0x20,0x2E, 0x00,0x00, 0xF5,0x82,
-0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0x81,0xF5, 0x00,0x00, 0x00,0x01, 0xF5,0x02,
-0x00,0x00, 0x86,0xA2, 0x00,0x00, 0xF7,0x04, 0xE0,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE2,0x00, 0x82,0x30, 0xF6,0x02, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0x82,0x38, 0x20,0x32, 0x00,0x00, 0x86,0xA2, 0x00,0x04, 0xF7,0x04, 0xE0,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0x82,0x39, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x82,0x49, 0x20,0x2A, 0x00,0x00, 0xF5,0x02,
-0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x00, 0x82,0x59, 0x20,0x26, 0x00,0x00, 0xF4,0x82,
-0x00,0x01, 0x20,0x26, 0x00,0x00, 0xE6,0x00, 0x87,0x60, 0x00,0x00, 0x00,0x01, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xCB,0xCC, 0x97,0x93, 0xFF,0xFC, 0x07,0x20, 0x00,0x02, 0xF0,0x3B,
-0x28,0x00, 0xF7,0x04, 0x4F,0x58, 0xF4,0x05, 0x3B,0xB0, 0x06,0xA0, 0x00,0x14, 0xC7,0x20,
-0x72,0x00, 0x77,0x38, 0xFF,0xFA, 0xF7,0x37, 0x28,0x00, 0x06,0xA0, 0x00,0x16, 0xF7,0x37,
-0x28,0x00, 0xF3,0x02, 0x00,0x01, 0xF3,0x23, 0x28,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xCB,0xCC, 0x97,0x93, 0xFF,0xFC, 0x26,0x14, 0x00,0x20, 0xF0,0x33, 0x28,0x00, 0x04,0xA0,
-0x00,0x02, 0xF0,0x27, 0x28,0x00, 0xF3,0x02, 0x00,0x00, 0x23,0x94, 0x00,0x2A, 0xF3,0x1F,
-0x28,0x00, 0x07,0x20, 0x00,0x1A, 0x23,0x94, 0x00,0x2A, 0x83,0x9E, 0x00,0x00, 0x77,0x9D,
-0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC3,0x9C, 0x7F,0xC0, 0x73,0x9D, 0xFF,0xF0, 0x76,0x31,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0x06,0xA4, 0x00,0x02, 0x75,0x15, 0x00,0x1E, 0xF3,0xBB,
-0x28,0x00, 0xF3,0x04, 0xE0,0x00, 0x75,0x28, 0xFF,0xE5, 0x93,0x22, 0x00,0x1C, 0xF3,0x84,
-0xE0,0x04, 0x23,0x14, 0x00,0x1E, 0x93,0x16, 0xFF,0xA4, 0x75,0x99, 0x00,0x1E, 0x75,0xAC,
-0xFF,0xE5, 0x73,0x15, 0x00,0x1E, 0x73,0x18, 0xFF,0xE5, 0x93,0x16, 0xFF,0xCC, 0x83,0x16,
-0xFF,0xA4, 0x93,0xA2, 0x00,0x20, 0x87,0x16, 0xFF,0xE0, 0x73,0x95, 0x00,0x1E, 0x73,0x9C,
-0xFF,0xE5, 0x93,0x96, 0xFF,0xAC, 0x73,0x95, 0x00,0x1E, 0x73,0x9C, 0xFF,0xE5, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x93,0x96,
-0xFF,0xC4, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4,
-0x00,0x02, 0x87,0x16, 0xFF,0xE4, 0x23,0x94, 0x00,0x1A, 0x93,0x96, 0xFF,0xA4, 0x76,0x1D,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x87,0x1E, 0x00,0x00, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16, 0xFF,0xE8, 0x23,0x14,
-0x00,0x16, 0x93,0x16, 0xFF,0xA4, 0x76,0x19, 0x00,0x1E, 0x83,0x96, 0xFF,0xAC, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x3F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1A,
-0x00,0x00, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16, 0xFF,0xEC, 0x23,0x14, 0x00,0x12, 0x93,0x16,
-0xFF,0xA4, 0x76,0x19, 0x00,0x1E, 0x83,0x96, 0xFF,0xCC, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38,
-0x3F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4,
-0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x16,
-0xFF,0xF0, 0x83,0x16, 0xFF,0xC4, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x37,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0xF3,0x82, 0x00,0x02, 0xF3,0xA3, 0x28,0x00, 0x23,0x14,
-0x00,0x2A, 0x83,0x1A, 0x00,0x00, 0x77,0x99, 0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC3,0x18,
-0x7F,0xC0, 0x73,0x19, 0xFF,0xF0, 0x07,0x20, 0x00,0x18, 0xF3,0x3B, 0x28,0x00, 0x94,0x16,
-0xFF,0xDC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCB,0xCC, 0x97,0x93, 0xFF,0xFC, 0x07,0x20,
-0x00,0x02, 0x23,0x94, 0x00,0x2A, 0x83,0x9E, 0x00,0x00, 0x77,0x9D, 0x00,0x1E, 0x77,0xBC,
-0xFF,0xE5, 0xC3,0x9C, 0x7F,0xC0, 0x73,0x9D, 0xFF,0xF0, 0x24,0x80, 0x00,0x07, 0x05,0x20,
-0x00,0x0A, 0xF3,0xBB, 0x28,0x00, 0x20,0x26, 0x00,0x07, 0xEE,0x00, 0x84,0xE0, 0x06,0x28,
-0x00,0x0E, 0x86,0xB2, 0x00,0x00, 0x77,0x31, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0x75,0xB1,
-0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0x05,0x28, 0x00,0x02, 0x04,0xA4, 0x00,0x01, 0xC6,0xB4,
-0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02, 0xFF,0x00, 0xC6,0xB4, 0x74,0x00, 0xF6,0xB3,
-0x28,0x00, 0x87,0x32, 0x00,0x00, 0xF3,0x02, 0x00,0xFF, 0xC7,0x38, 0x5F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0xC7,0x38, 0x34,0x00, 0xE0,0x00, 0x84,0x88, 0xF7,0x33, 0x28,0x00, 0x05,0x20,
-0x00,0x26, 0x86,0x2A, 0x00,0x00, 0x76,0xA9, 0x00,0x1E, 0xF5,0x84, 0x4F,0x58, 0x76,0xB4,
-0xFF,0xE5, 0x83,0x96, 0xFF,0xDC, 0xF3,0x02, 0x00,0xFF, 0x94,0x16, 0xFF,0xBC, 0xC7,0x1C,
-0x5A,0x00, 0x77,0x38, 0xFF,0xFA, 0xC6,0x30, 0x6F,0xC0, 0x76,0x31, 0xFF,0xF0, 0x47,0x39,
-0x00,0x00, 0xC7,0x38, 0x34,0x00, 0xF6,0x82, 0xFF,0x00, 0xC6,0x30, 0x6C,0x00, 0xC7,0x38,
-0x60,0x00, 0xF6,0x84, 0x3B,0x6C, 0xF7,0x2B, 0x28,0x00, 0xC5,0xA0, 0x5A,0x00, 0x75,0xAC,
-0xFF,0xFA, 0x83,0x16, 0xFF,0xDC, 0x07,0x34, 0x00,0x01, 0xF7,0x05, 0x3B,0x6C, 0x07,0x20,
-0x00,0x3A, 0xF6,0xBB, 0x28,0x00, 0x07,0x20, 0x00,0x36, 0xF0,0x3B, 0x28,0x00, 0xF3,0x82,
-0x00,0x03, 0xF3,0xA3, 0x28,0x00, 0x07,0x18, 0x00,0x1A, 0xF5,0xBB, 0x28,0x00, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xCB,0xCC, 0x97,0x93, 0xFF,0xFC, 0x07,0x20, 0x00,0x02, 0xF0,0x3B,
-0x28,0x00, 0x24,0x80, 0x00,0x07, 0x05,0x20, 0x00,0x0A, 0x20,0x26, 0x00,0x07, 0xEE,0x00,
-0x85,0xD4, 0x06,0x28, 0x00,0x0E, 0x86,0xB2, 0x00,0x00, 0x77,0x31, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0x75,0xB1, 0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0x05,0x28, 0x00,0x02, 0x04,0xA4,
-0x00,0x01, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02, 0xFF,0x00, 0xC6,0xB4,
-0x74,0x00, 0xF6,0xB3, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0xF3,0x82, 0x00,0xFF, 0xC7,0x38,
-0x5F,0xC0, 0x77,0x39, 0xFF,0xF0, 0xC7,0x38, 0x3C,0x00, 0xE0,0x00, 0x85,0x7C, 0xF7,0x33,
-0x28,0x00, 0x05,0xA0, 0x00,0x26, 0x86,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC5,0x20, 0x00,0x00, 0x24,0x00, 0x00,0x07, 0xF3,0x02, 0x00,0x01, 0x93,0x16,
-0xFF,0xA4, 0xF7,0x04, 0x4F,0x58, 0x83,0x96, 0xFF,0xBC, 0x24,0x80, 0x00,0x0E, 0xC7,0x1C,
-0x72,0x00, 0x77,0x38, 0xFF,0xFA, 0xC6,0x30, 0x6F,0xC0, 0x76,0x31, 0xFF,0xF0, 0x47,0x39,
-0x00,0x00, 0xF6,0x82, 0x00,0xFF, 0xC7,0x38, 0x6C,0x00, 0xF6,0x82, 0xFF,0x00, 0xC6,0x30,
-0x6C,0x00, 0xC7,0x38, 0x60,0x00, 0xF6,0x84, 0x3B,0x6C, 0xF7,0x2F, 0x28,0x00, 0x07,0x34,
-0x00,0x01, 0xF7,0x05, 0x3B,0x6C, 0x07,0x28, 0x00,0x3A, 0xF6,0xBB, 0x28,0x00, 0x07,0x28,
-0x00,0x36, 0xF0,0x3B, 0x28,0x00, 0xF3,0x02, 0x00,0x03, 0xF3,0x2B, 0x28,0x00, 0x20,0x22,
-0x00,0x07, 0xEE,0x00, 0x86,0x94, 0xC6,0x28, 0x48,0x00, 0x06,0x30, 0x00,0x26, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x04,0xA4, 0x00,0x02, 0x04,0x20,
-0x00,0x01, 0x83,0x96, 0xFF,0xA4, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0xF6,0x82,
-0xFF,0x00, 0xC7,0x38, 0x6C,0x00, 0xC7,0x1C, 0x70,0x00, 0xE0,0x00, 0x86,0x50, 0xF7,0x33,
-0x28,0x00, 0x06,0x28, 0x00,0x26, 0x86,0xB2, 0x00,0x00, 0x77,0x31, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02, 0xFF,0x00, 0xC6,0xB4,
-0x74,0x00, 0xF6,0xB3, 0x28,0x00, 0x95,0x13, 0xFF,0xFC, 0xF3,0x04, 0x3B,0xB0, 0x00,0x00,
-0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0x95,0x16, 0xFF,0xB4, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xD4,0x2C, 0x97,0x93, 0xFF,0xFC, 0x85,0x16, 0xFF,0xB4, 0xF0,0x05, 0x40,0x7C, 0x83,0x96,
-0xFF,0xBC, 0x23,0x00, 0x00,0x07, 0xF3,0x05, 0x42,0x58, 0xF7,0x04, 0x42,0x50, 0xF6,0x06,
-0x42,0x50, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xF3,0x06, 0x39,0x34, 0xF3,0x05,
-0x42,0x44, 0xF5,0x05, 0x40,0x74, 0xF3,0x85, 0x42,0x60, 0xF3,0x82, 0x00,0x06, 0xF3,0x85,
-0x42,0x54, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0xF6,0x84, 0x2D,0x38, 0x07,0x38,
-0x00,0x01, 0xF7,0x33, 0x28,0x00, 0x06,0x34, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0xF7,0x06,
-0x2C,0x28, 0x76,0xB5, 0x00,0x02, 0xF3,0x82, 0x00,0x1C, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0x87,0x4C, 0xB3,0xB6, 0x70,0x02, 0xF0,0x05, 0x2D,0x38, 0xF3,0x06, 0x42,0x44, 0x93,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x1F,0x48, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x48, 0xF3,0x86,
-0x42,0x44, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x20,0xE4, 0x97,0x93,
-0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x89,0xED, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x42,0x54, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xEE,0x00, 0x87,0xC9, 0x00,0x00,
-0x00,0x01, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x73,0x4C, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00,
-0x89,0xEC, 0x00,0x00, 0x00,0x01, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCB,0xCC, 0x97,0x93,
-0xFF,0xFC, 0x26,0x14, 0x00,0x20, 0xF0,0x33, 0x28,0x00, 0x05,0xA0, 0x00,0x02, 0xF0,0x2F,
-0x28,0x00, 0xF3,0x82, 0x00,0x00, 0x24,0x94, 0x00,0x22, 0xF3,0xA7, 0x28,0x00, 0x04,0xA0,
-0x00,0x1A, 0x94,0x96, 0xFF,0xD4, 0x23,0x94, 0x00,0x22, 0x83,0x9E, 0x00,0x00, 0x77,0x9D,
-0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC3,0x9C, 0x7F,0xC0, 0x73,0x9D, 0xFF,0xF0, 0x76,0x31,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0x06,0xAC, 0x00,0x02, 0x23,0x14, 0x00,0x1E, 0x75,0x19,
-0x00,0x1E, 0xF3,0xA7, 0x28,0x00, 0xF4,0x84, 0xE0,0x00, 0x75,0x28, 0xFF,0xE5, 0x94,0xA2,
-0x00,0x1C, 0xF3,0x84, 0xE0,0x04, 0x74,0x95, 0x00,0x1E, 0x74,0xA4, 0xFF,0xE5, 0x94,0x96,
-0xFF,0xB4, 0x74,0x95, 0x00,0x1E, 0x74,0xA4, 0xFF,0xE5, 0x94,0x96, 0xFF,0xCC, 0x84,0x96,
-0xFF,0xB4, 0x93,0xA2, 0x00,0x20, 0x87,0x16, 0xFF,0xE0, 0x73,0x95, 0x00,0x1E, 0x73,0x9C,
-0xFF,0xE5, 0x93,0x96, 0xFF,0xBC, 0x73,0x95, 0x00,0x1E, 0x73,0x9C, 0xFF,0xE5, 0x93,0x96,
-0xFF,0xC4, 0x83,0x96, 0xFF,0xBC, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F,
-0x28,0x00, 0xF5,0x84, 0x4F,0x58, 0x87,0x1A, 0x00,0x00, 0xC5,0xA0, 0x5A,0x00, 0x75,0xAC,
-0xFF,0xFA, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4,
-0x00,0x02, 0x87,0x16, 0xFF,0xE4, 0x23,0x14, 0x00,0x1A, 0x76,0x19, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0x45,0xAD, 0x00,0x00, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4, 0x00,0x02, 0x84,0x96, 0xFF,0xCC, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16,
-0xFF,0xE8, 0x23,0x14, 0x00,0x16, 0x76,0x19, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38,
-0x3F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4,
-0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4,
-0x00,0x02, 0x87,0x16, 0xFF,0xEC, 0x23,0x14, 0x00,0x12, 0x76,0x19, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1A,
-0x00,0x00, 0x06,0xB4, 0x00,0x02, 0x83,0x96, 0xFF,0xC4, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x16, 0xFF,0xF0, 0x06,0xB4, 0x00,0x02, 0xC7,0x38,
-0x3F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0xF4,0x82, 0x00,0x02, 0xF4,0xA3,
-0x28,0x00, 0x04,0x20, 0x00,0x18, 0x23,0x94, 0x00,0x22, 0x83,0x9E, 0x00,0x00, 0x77,0x9D,
-0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC3,0x9C, 0x7F,0xC0, 0x73,0x9D, 0xFF,0xF0, 0x84,0x96,
-0xFF,0xD4, 0xF3,0xA3, 0x28,0x00, 0xF3,0x82, 0x00,0x01, 0xF3,0xA7, 0x28,0x00, 0x95,0x93,
-0xFF,0xFC, 0xF4,0x86, 0xE0,0x00, 0x94,0x93, 0xFF,0xFC, 0xF3,0x84, 0x4F,0x5C, 0x00,0x00,
-0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x23,0x40, 0x97,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x78,0xD8, 0x97,0x93, 0xFF,0xFC, 0xF4,0x86,
-0x36,0x78, 0xF4,0x85, 0x42,0x44, 0xF0,0x05, 0x40,0x84, 0xF6,0x84, 0x4F,0x5C, 0xF7,0x02,
-0x00,0x64, 0x97,0x36, 0x00,0x00, 0x90,0x36, 0x00,0x04, 0xF7,0x02, 0x00,0x01, 0xF7,0x05,
-0x40,0x84, 0xF3,0x86, 0x35,0xEC, 0xF3,0x85, 0x42,0x30, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x90, 0xF7,0x04, 0x42,0x60, 0xF5,0x02,
-0x00,0x00, 0x05,0xB8, 0x00,0x18, 0xF6,0x04, 0x42,0x58, 0x00,0x00, 0x00,0x01, 0x20,0x32,
-0x00,0x07, 0xEE,0x00, 0x8A,0x70, 0xC7,0x30, 0x60,0x00, 0xC7,0x38, 0x58,0x00, 0x07,0x38,
-0x00,0x0E, 0x86,0xBA, 0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4,
-0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02, 0x00,0xFF, 0xC6,0xB4, 0x74,0x00, 0xC0,0x36,
-0x52,0x00, 0x47,0x0C, 0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x8A,0x71, 0x07,0x30, 0x00,0x01, 0xE0,0x00, 0x8A,0x18, 0xF7,0x05, 0x42,0x58, 0xF4,0x04,
-0x42,0x58, 0x00,0x00, 0x00,0x01, 0x20,0x22, 0x00,0x07, 0xEE,0x00, 0x8D,0x94, 0x24,0x94,
-0x00,0x36, 0xF6,0x04, 0x42,0x60, 0x25,0x14, 0x00,0x38, 0x23,0x94, 0x00,0x20, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x06,0x30,
-0x00,0x02, 0x75,0xB1, 0x00,0x1E, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B,
-0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x34, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x32, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x30, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x2E, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x2C, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x2A, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x24,0x94,
-0x00,0x28, 0x76,0x31, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x94,0x13, 0xFF,0xFC, 0x95,0x13, 0xFF,0xFC, 0x93,0x96,
-0xFF,0x7C, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xD0,0xDC, 0x97,0x93,
-0xFF,0xFC, 0xF6,0x04, 0x42,0x60, 0x24,0x94, 0x00,0x7E, 0x25,0x14, 0x00,0x80, 0x23,0x94,
-0x00,0x68, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0x06,0x30, 0x00,0x02, 0x75,0xB1, 0x00,0x1E, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38,
-0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x7C, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x7A, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x78, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x76, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x74, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x72, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x24,0x94, 0x00,0x70, 0x76,0x31, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x95,0x13, 0xFF,0xFC, 0x93,0x96,
-0xFF,0x74, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xD2,0x58, 0x97,0x93,
-0xFF,0xFC, 0x83,0x96, 0xFF,0x74, 0x00,0x00, 0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0xF7,0x04,
-0x42,0x58, 0x23,0x94, 0x00,0x50, 0xC7,0x00, 0x72,0x00, 0x97,0x13, 0xFF,0xFC, 0x93,0x96,
-0xFF,0x6C, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCF,0x24, 0x97,0x93,
-0xFF,0xFC, 0x83,0x96, 0xFF,0x6C, 0xF6,0x86, 0x42,0x50, 0x93,0x93, 0xFF,0xFC, 0xF3,0x84,
-0x42,0x58, 0x76,0xB5, 0x00,0x1E, 0x93,0x93, 0xFF,0xFC, 0xF7,0x04, 0x42,0x50, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x97,0x13, 0xFF,0xFC, 0x83,0x96,
-0xFF,0x7C, 0x00,0x00, 0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xF3,0x38, 0x97,0x93, 0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x8D,0x95, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x42,0x58, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x42,0x58, 0xF7,0x04, 0x42,0x58, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x07, 0xEE,0x00,
-0x8D,0xD4, 0xF3,0x82, 0x17,0x70, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x82, 0x00,0x1C, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0x8D,0xF4, 0xB3,0xBA, 0x68,0x02, 0xE0,0x00, 0x8D,0xF4, 0xF0,0x05,
-0x2D,0x38, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x1B, 0x93,0x93, 0xFF,0xFC, 0xF3,0x86,
-0x42,0x44, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x1E,0xC0, 0x97,0x93,
-0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10,
-0x00,0x88, 0xF7,0x04, 0x42,0x50, 0xF6,0x86, 0x42,0x50, 0x76,0xB5, 0x00,0x1E, 0xF3,0x84,
-0x6F,0x34, 0x76,0xB4, 0xFF,0xE5, 0x93,0x96, 0xFF,0xC4, 0xC7,0x38, 0x6F,0xC0, 0x86,0x9E,
-0x00,0x0C, 0x77,0x39, 0xFF,0xF0, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x8E,0x65, 0xF6,0x06,
-0x42,0xA0, 0xF7,0x04, 0x42,0xA0, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xE0,0x00, 0x94,0xE4, 0xF7,0x33,
-0x28,0x00, 0xF6,0x04, 0x42,0x60, 0x24,0x94, 0x00,0x36, 0x85,0x16, 0xFF,0xC4, 0x23,0x94,
-0x00,0x38, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0x85,0x2A, 0x00,0x1C, 0x06,0x30, 0x00,0x02, 0x75,0xB1, 0x00,0x1E, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x95,0x16, 0xFF,0xBC, 0xF7,0x1F, 0x28,0x00, 0x87,0x32,
-0x00,0x00, 0x75,0xAC, 0xFF,0xE5, 0x85,0x16, 0xFF,0xC4, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x34, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x32, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x30, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x2E, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x2C, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x2A, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x24,0x94,
-0x00,0x28, 0x76,0x31, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x87,0x2A, 0x00,0x20, 0x00,0x00, 0x00,0x01, 0x97,0x13,
-0xFF,0xFC, 0x93,0x93, 0xFF,0xFC, 0x27,0x14, 0x00,0x20, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xD0,0xDC, 0x97,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0xC4, 0x00,0x00,
-0x00,0x01, 0x87,0x1E, 0x00,0x10, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0x8F,0xF0, 0xF6,0x82, 0x00,0x00, 0x87,0x1E, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0x8F,0xF4, 0x20,0x36, 0x00,0x00, 0xF6,0x82, 0x00,0x01, 0x20,0x36,
-0x00,0x00, 0xE6,0x00, 0x90,0x41, 0x00,0x00, 0x00,0x01, 0x85,0x16, 0xFF,0xC4, 0x00,0x00,
-0x00,0x01, 0x05,0x28, 0x00,0x10, 0x95,0x16, 0xFF,0xB4, 0x95,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x72,0x50, 0x97,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0xB4, 0x27,0x14,
-0x00,0x20, 0x93,0x93, 0xFF,0xFC, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xF9,0x34, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x94,0xE4, 0x00,0x00, 0x00,0x01, 0x85,0x16,
-0xFF,0xBC, 0x00,0x00, 0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x00, 0x94,0xBC, 0x00,0x00,
-0x00,0x01, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCB,0xCC, 0x97,0x93, 0xFF,0xFC, 0xF5,0x02,
-0x00,0x00, 0x23,0x94, 0x00,0x62, 0xF5,0x1F, 0x28,0x00, 0x75,0x95, 0x00,0x1E, 0x75,0xAC,
-0xFF,0xE5, 0x06,0x20, 0x00,0x02, 0x06,0xB0, 0x00,0x02, 0x23,0x14, 0x00,0x1E, 0x73,0x99,
-0x00,0x1E, 0x73,0x9C, 0xFF,0xE5, 0x93,0x96, 0xFF,0x74, 0x75,0x15, 0x00,0x1E, 0x75,0x28,
-0xFF,0xE5, 0x95,0x16, 0xFF,0x7C, 0x73,0x95, 0x00,0x1E, 0x73,0x9C, 0xFF,0xE5, 0x93,0x96,
-0xFF,0x8C, 0x85,0x16, 0xFF,0xC4, 0x73,0x95, 0x00,0x1E, 0x93,0x96, 0xFF,0x84, 0x85,0x2A,
-0x00,0x34, 0x23,0x94, 0x00,0x62, 0x95,0x16, 0xFF,0xAC, 0xF0,0x33, 0x28,0x00, 0x05,0x20,
-0x00,0x1A, 0x95,0x16, 0xFF,0x94, 0x83,0x9E, 0x00,0x00, 0x77,0x9D, 0x00,0x1E, 0x77,0xBC,
-0xFF,0xE5, 0xC3,0x9C, 0x7F,0xC0, 0x73,0x9D, 0xFF,0xF0, 0x74,0x95, 0x00,0x1E, 0xF3,0xAB,
-0x28,0x00, 0x85,0x16, 0xFF,0xC4, 0x74,0xA4, 0xFF,0xE5, 0x85,0x2A, 0x00,0x10, 0x83,0x96,
-0xFF,0xC4, 0x95,0x22, 0x00,0x1C, 0x83,0x9E, 0x00,0x14, 0x85,0x16, 0xFF,0x84, 0x93,0xA2,
-0x00,0x20, 0x87,0x16, 0xFF,0xE0, 0x75,0x28, 0xFF,0xE5, 0x95,0x16, 0xFF,0x84, 0xF3,0x84,
-0x4F,0x58, 0x85,0x16, 0xFF,0x74, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33,
-0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x93,0x96, 0xFF,0xA4, 0xC0,0x22, 0x3A,0x00, 0x83,0x96,
-0xFF,0x7C, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4,
-0x00,0x02, 0x87,0x16, 0xFF,0xE4, 0x23,0x14, 0x00,0x1A, 0x76,0x19, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1A,
-0x00,0x00, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16, 0xFF,0xE8, 0x23,0x14, 0x00,0x16, 0x76,0x19,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x3F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4, 0x00,0x02, 0x85,0x16, 0xFF,0x8C, 0x83,0x96,
-0xFF,0x84, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4,
-0x00,0x02, 0x87,0x16, 0xFF,0xEC, 0x23,0x14, 0x00,0x12, 0x76,0x19, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1A,
-0x00,0x00, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x87,0x16, 0xFF,0xF0, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x3F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0xF5,0x02, 0x00,0x02, 0xF5,0x23, 0x28,0x00, 0x23,0x94,
-0x00,0x52, 0x83,0x9E, 0x00,0x00, 0x77,0x9D, 0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC3,0x9C,
-0x7F,0xC0, 0x73,0x9D, 0xFF,0xF0, 0x03,0x20, 0x00,0x18, 0xE6,0x00, 0x92,0x30, 0xF3,0x9B,
-0x28,0x00, 0xF7,0x04, 0x42,0x70, 0xE0,0x00, 0x92,0x9C, 0xF6,0x06, 0x42,0x72, 0x85,0x16,
-0xFF,0xC4, 0x00,0x00, 0x00,0x01, 0x86,0xAA, 0x00,0x20, 0x00,0x00, 0x00,0x01, 0x07,0x34,
-0x00,0x07, 0x20,0x3A, 0x00,0x0E, 0xE2,0x00, 0x92,0x94, 0xC7,0x34, 0x68,0x00, 0xF5,0x84,
-0x42,0x60, 0xF3,0x82, 0x00,0xFF, 0xC7,0x2C, 0x70,0x00, 0x07,0x38, 0x00,0x26, 0x86,0xBA,
-0x00,0x00, 0x97,0x16, 0xFF,0x74, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4,
-0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xC6,0xB4, 0x3C,0x00, 0x20,0x36, 0x00,0x00, 0x47,0x0C,
-0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0x92,0xC9, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x42,0x74, 0xF6,0x06, 0x42,0x74, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33,
-0x28,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x78,0x9C, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00,
-0x94,0xE4, 0x00,0x00, 0x00,0x01, 0x85,0x16, 0xFF,0xA4, 0x83,0x96, 0xFF,0x74, 0xC7,0x20,
-0x52,0x00, 0x74,0xB8, 0xFF,0xFA, 0xC6,0x24, 0x00,0x00, 0x87,0x1E, 0x00,0x00, 0x76,0x9D,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC5,0xAC, 0x52,0x00, 0x75,0xAC, 0xFF,0xFA, 0x46,0x31,
-0x00,0x00, 0xF5,0x02, 0x00,0xFF, 0xC6,0x30, 0x54,0x00, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0xF6,0x82, 0xFF,0x00, 0xC7,0x38, 0x6C,0x00, 0xC6,0x30, 0x70,0x00, 0xF6,0x1F,
-0x28,0x00, 0x83,0x96, 0xFF,0x94, 0x85,0x16, 0xFF,0xC4, 0xF5,0x9F, 0x28,0x00, 0x87,0x2A,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x24, 0xE6,0x00, 0x94,0x69, 0xF6,0x86,
-0x40,0x98, 0xF7,0x04, 0x6E,0x50, 0x86,0x2A, 0x00,0x2C, 0xC6,0xA4, 0x00,0x00, 0x23,0x94,
-0x00,0x62, 0x84,0x9E, 0x00,0x00, 0x77,0x9D, 0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC4,0xA4,
-0x7F,0xC0, 0x74,0xA5, 0xFF,0xF0, 0x46,0xB5, 0x00,0x00, 0x87,0x3A, 0x1D,0xDC, 0x76,0xB5,
-0x00,0x02, 0xC0,0x32, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A,
-0x00,0x00, 0xF7,0x06, 0x40,0x98, 0xE6,0x00, 0x94,0x34, 0xC3,0x34, 0x70,0x00, 0xC5,0x84,
-0x00,0x00, 0x86,0xAA, 0x00,0x24, 0xF7,0x04, 0xE0,0x00, 0xF6,0x02, 0x00,0x00, 0xC0,0x36,
-0x72,0x00, 0x05,0x28, 0x00,0x24, 0xE6,0x00, 0x93,0xC4, 0x95,0x16, 0xFF,0x74, 0x83,0x96,
-0xFF,0xC4, 0x00,0x00, 0x00,0x01, 0x86,0x9E, 0x00,0x28, 0xF7,0x04, 0xE0,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x93,0xC8, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x93,0xD5, 0x00,0x00, 0x00,0x01, 0xF5,0x82,
-0x00,0x00, 0x85,0x16, 0xFF,0x74, 0xF7,0x04, 0xE0,0x00, 0x86,0xAA, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0x94,0x14, 0xF6,0x02, 0x00,0x00, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0x94,0x1C, 0x20,0x32, 0x00,0x00, 0x86,0xAA, 0x00,0x04, 0xF7,0x04,
-0xE0,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0x94,0x1D, 0x20,0x32,
-0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0x94,0x2D, 0x20,0x2E,
-0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0x94,0x39, 0x00,0x00,
-0x00,0x01, 0xF4,0x82, 0x00,0x01, 0xF7,0x04, 0x4F,0x58, 0xF4,0x9B, 0x28,0x00, 0x83,0x96,
-0xFF,0xC4, 0xF6,0x86, 0x40,0x9A, 0xC7,0x20, 0x72,0x00, 0x77,0x38, 0xFF,0xFA, 0x86,0x1E,
-0x00,0x30, 0x47,0x39, 0x00,0x00, 0x77,0x39, 0x00,0x02, 0xC7,0x38, 0x68,0x00, 0xE0,0x00,
-0x94,0xE4, 0xF6,0x3B, 0x28,0x00, 0x47,0x25, 0x00,0x00, 0x77,0x39, 0x00,0x02, 0xC7,0x38,
-0x68,0x00, 0xF5,0x02, 0x00,0x01, 0xF5,0x3B, 0x28,0x00, 0x07,0x38, 0x00,0x02, 0x23,0x94,
-0x00,0x62, 0x83,0x9E, 0x00,0x00, 0x77,0x9D, 0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC3,0x9C,
-0x7F,0xC0, 0x73,0x9D, 0xFF,0xF0, 0x25,0x14, 0x00,0x62, 0xF3,0xBB, 0x28,0x00, 0x85,0x2A,
-0x00,0x00, 0x77,0xA9, 0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC5,0x28, 0x7F,0xC0, 0x75,0x29,
-0xFF,0xF0, 0xE0,0x00, 0x94,0xE4, 0xF5,0x1B, 0x28,0x00, 0x83,0x96, 0xFF,0xBC, 0x00,0x00,
-0x00,0x01, 0x20,0x1E, 0x00,0x01, 0xE6,0x00, 0x94,0xE4, 0x00,0x00, 0x00,0x01, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x78,0x9C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06, 0x35,0x60, 0xF5,0x05,
-0x42,0x30, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF5,0x06,
-0x42,0x44, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x20,0xE4, 0x97,0x93,
-0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0x96,0x89, 0x00,0x00, 0x00,0x01, 0xF6,0x84,
-0x42,0x54, 0x00,0x00, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xEE,0x00, 0x95,0x8D, 0xF5,0x86,
-0x42,0x50, 0xF7,0x04, 0x42,0x50, 0x76,0x2D, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0x26,0xB4,
-0x00,0x01, 0xF6,0x85, 0x42,0x54, 0x25,0x00, 0x00,0x07, 0xF5,0x05, 0x42,0x58, 0xF6,0x84,
-0x2D,0x38, 0xC7,0x38, 0x67,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x2F,
-0x28,0x00, 0x06,0x34, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0xF7,0x06, 0x2C,0x28, 0x76,0xB5,
-0x00,0x02, 0xF5,0x02, 0x00,0x1C, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x96,0x88, 0xB5,0x36,
-0x70,0x02, 0xE0,0x00, 0x96,0x88, 0xF0,0x05, 0x2D,0x38, 0xF5,0x04, 0x42,0x60, 0x00,0x00,
-0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xB2,0x84, 0x97,0x93,
-0xFF,0xFC, 0xF6,0x84, 0x4F,0x58, 0x00,0x00, 0x00,0x01, 0x07,0x34, 0x00,0x40, 0xC0,0x22,
-0x72,0x00, 0xE6,0x00, 0x95,0xEC, 0xF6,0x06, 0x42,0x76, 0xF7,0x04, 0x42,0x74, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xF7,0x33, 0x28,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x78,0x9C, 0x97,0x93,
-0xFF,0xFC, 0xE0,0x00, 0x96,0x88, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x42,0x60, 0x00,0x00,
-0x00,0x01, 0xC0,0x22, 0x72,0x00, 0xE6,0x00, 0x96,0x24, 0x00,0x00, 0x00,0x01, 0x97,0x13,
-0xFF,0xFC, 0xF5,0x04, 0x3B,0xB0, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xD4,0x2C, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x96,0x40, 0x00,0x00,
-0x00,0x01, 0xC0,0x22, 0x6A,0x00, 0xE6,0x00, 0x96,0x71, 0x00,0x00, 0x00,0x01, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCC,0x60, 0x97,0x93, 0xFF,0xFC, 0xF7,0x04,
-0x40,0x7C, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x13, 0xFF,0xFC, 0xF5,0x04,
-0x40,0x74, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xBE,0xF8, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x96,0x88, 0x00,0x00, 0x00,0x01, 0xF5,0x04,
-0x40,0x74, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xC1,0xB4, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x22,0x10, 0x00,0x70, 0xF6,0x04, 0x6F,0x34, 0xF7,0x04, 0x42,0x64, 0x86,0xB2,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0x9B,0x18, 0x06,0xB0,
-0x00,0x02, 0x87,0x36, 0x00,0x00, 0xF4,0x04, 0x40,0x7C, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0xC0,0x3A, 0x42,0x00, 0xE6,0x00,
-0x9B,0x18, 0x24,0x94, 0x00,0x36, 0xF6,0x04, 0x40,0x74, 0x23,0x94, 0x00,0x38, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x06,0x30,
-0x00,0x02, 0x75,0xB1, 0x00,0x1E, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F,
-0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x34, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x32, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x30, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x2E, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x2C, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x2A, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x24,0x94,
-0x00,0x28, 0x76,0x31, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x94,0x13, 0xFF,0xFC, 0x93,0x93, 0xFF,0xFC, 0x27,0x14,
-0x00,0x20, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xD0,0xDC, 0x97,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCB,0xCC, 0x97,0x93, 0xFF,0xFC, 0xF5,0x04,
-0x40,0x74, 0x94,0x16, 0xFF,0xC4, 0x07,0x20, 0x00,0x02, 0xF0,0x3B, 0x28,0x00, 0x24,0x80,
-0x00,0x07, 0xF4,0x02, 0x00,0xFF, 0x83,0x96, 0xFF,0xC4, 0x95,0x16, 0xFF,0xBC, 0x03,0x1C,
-0x00,0x0A, 0x20,0x26, 0x00,0x07, 0xEE,0x00, 0x98,0xA8, 0x06,0x18, 0x00,0x0E, 0x86,0xB2,
-0x00,0x00, 0x77,0x31, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0x75,0xB1, 0x00,0x1E, 0x75,0xAC,
-0xFF,0xE5, 0x03,0x18, 0x00,0x02, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02,
-0xFF,0x00, 0xC6,0xB4, 0x74,0x00, 0xF6,0xB3, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x04,0xA4,
-0x00,0x01, 0xC7,0x38, 0x5F,0xC0, 0x77,0x39, 0xFF,0xF0, 0xC7,0x38, 0x44,0x00, 0xE0,0x00,
-0x98,0x54, 0xF7,0x33, 0x28,0x00, 0x85,0x16, 0xFF,0xC4, 0x74,0x95, 0x00,0x1E, 0x74,0xA4,
-0xFF,0xE5, 0x83,0x96, 0xFF,0xC4, 0x23,0x14, 0x00,0x1E, 0x74,0x19, 0x00,0x1E, 0x74,0x20,
-0xFF,0xE5, 0x05,0x28, 0x00,0x26, 0x95,0x16, 0xFF,0x8C, 0x85,0xAA, 0x00,0x00, 0x76,0xA9,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x03,0x9C, 0x00,0x02, 0x93,0x96, 0xFF,0xB4, 0x06,0x1C,
-0x00,0x02, 0x73,0x95, 0x00,0x1E, 0x73,0x9C, 0xFF,0xE5, 0x93,0x96, 0xFF,0xAC, 0x73,0x95,
-0x00,0x1E, 0x73,0x9C, 0xFF,0xE5, 0x93,0x96, 0xFF,0x9C, 0x83,0x96, 0xFF,0xBC, 0x75,0x15,
-0x00,0x1E, 0x75,0x28, 0xFF,0xE5, 0x95,0x16, 0xFF,0x94, 0x75,0x15, 0x00,0x1E, 0x75,0x28,
-0xFF,0xE5, 0x95,0x16, 0xFF,0xA4, 0x85,0x16, 0xFF,0xC4, 0xC5,0xAC, 0x6F,0xC0, 0x75,0xAD,
-0xFF,0xF0, 0xF5,0x05, 0x42,0x60, 0xF5,0x04, 0x4F,0x58, 0xF6,0x82, 0x00,0xFF, 0xC7,0x1C,
-0x52,0x00, 0x77,0x38, 0xFF,0xFA, 0x47,0x39, 0x00,0x00, 0xC7,0x38, 0x6C,0x00, 0xF6,0x82,
-0xFF,0x00, 0xC5,0xAC, 0x6C,0x00, 0xC7,0x38, 0x58,0x00, 0x83,0x96, 0xFF,0x8C, 0xF5,0x84,
-0x3B,0x6C, 0x85,0x16, 0xFF,0xB4, 0xF7,0x1F, 0x28,0x00, 0x87,0x16, 0xFF,0xE0, 0x06,0xAC,
-0x00,0x01, 0xF6,0x85, 0x3B,0x6C, 0x83,0x96, 0xFF,0xC4, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0xF5,0x04, 0x4F,0x58, 0x87,0x1A, 0x00,0x00, 0xC0,0x1E,
-0x52,0x00, 0xC7,0x38, 0x47,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x06,0x30,
-0x00,0x02, 0x87,0x16, 0xFF,0xE4, 0x23,0x14, 0x00,0x1A, 0x76,0x99, 0x00,0x1E, 0x83,0x96,
-0xFF,0x94, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x3F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33,
-0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0x30, 0x00,0x02, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x16, 0xFF,0xE8, 0x23,0x14,
-0x00,0x16, 0x76,0x99, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x85,0x16, 0xFF,0xAC, 0x83,0x96,
-0xFF,0xA4, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x87,0x1A,
-0x00,0x00, 0x06,0x30, 0x00,0x02, 0x85,0x16, 0xFF,0x9C, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x16, 0xFF,0xEC, 0x23,0x14,
-0x00,0x12, 0x76,0x99, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x3F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0x30, 0x00,0x02, 0x83,0x96,
-0xFF,0xC4, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x87,0x16,
-0xFF,0xF0, 0x06,0x30, 0x00,0x02, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33,
-0x28,0x00, 0x07,0x1C, 0x00,0x3A, 0xF5,0xBB, 0x28,0x00, 0x07,0x1C, 0x00,0x36, 0xF0,0x3B,
-0x28,0x00, 0xF5,0x02, 0x00,0x03, 0xE6,0x00, 0x9A,0xA4, 0xF5,0x1F, 0x28,0x00, 0xF7,0x04,
-0x42,0x78, 0xF6,0x06, 0x42,0x78, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33, 0x28,0x00, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x78,0x9C, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x9B,0x18, 0x00,0x00,
-0x00,0x01, 0xF3,0x86, 0x42,0x44, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01,
-0x1F,0x48, 0x97,0x93, 0xFF,0xFC, 0x25,0x00, 0x00,0x07, 0xF5,0x05, 0x42,0x58, 0xF7,0x04,
-0x42,0x50, 0xF6,0x06, 0x42,0x50, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xF3,0x82,
-0x00,0x06, 0xF3,0x85, 0x42,0x54, 0xF5,0x06, 0x39,0x34, 0xF5,0x05, 0x42,0x44, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0xF6,0x84, 0x2D,0x38, 0x07,0x38, 0x00,0x01, 0xF7,0x33,
-0x28,0x00, 0x06,0x34, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0xF7,0x06, 0x2C,0x28, 0x76,0xB5,
-0x00,0x02, 0xF3,0x82, 0x00,0x1C, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0x9B,0x18, 0xB3,0xB6,
-0x70,0x02, 0xF0,0x05, 0x2D,0x38, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x22,0x10, 0x00,0x78, 0xF3,0x86, 0x42,0x44, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x20,0xE4, 0x97,0x93, 0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00,
-0x9E,0x41, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x42,0x54, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xEE,0x00, 0x9D,0x85, 0x24,0x94, 0x00,0x36, 0xF6,0x04, 0x40,0x74, 0x25,0x14,
-0x00,0x38, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0x06,0x30, 0x00,0x02, 0x75,0xB1, 0x00,0x1E, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38,
-0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x34, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x32, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x30, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x2E, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x2C, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94, 0x00,0x2A, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x24,0x94, 0x00,0x28, 0x76,0x31, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0xF3,0x84, 0x40,0x7C, 0x00,0x00,
-0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x95,0x13, 0xFF,0xFC, 0x23,0x94, 0x00,0x20, 0x93,0x96,
-0xFF,0x94, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xD0,0xDC, 0x97,0x93,
-0xFF,0xFC, 0x83,0x96, 0xFF,0x94, 0x00,0x00, 0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x23,0x94,
-0x00,0x68, 0x93,0x96, 0xFF,0x8C, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xD2,0x58, 0x97,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0x8C, 0x00,0x00, 0x00,0x01, 0x93,0x93,
-0xFF,0xFC, 0x90,0x13, 0xFF,0xFC, 0x23,0x94, 0x00,0x50, 0x93,0x96, 0xFF,0x84, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCF,0x24, 0x97,0x93, 0xFF,0xFC, 0x87,0x02,
-0xFF,0x34, 0x00,0x00, 0x00,0x01, 0xF7,0x05, 0x42,0x64, 0xF3,0x84, 0x40,0x7C, 0x00,0x00,
-0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x97,0x13, 0xFF,0xFC, 0x83,0x96, 0xFF,0x84, 0x00,0x00,
-0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0x94, 0x00,0x00, 0x00,0x01, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xF7,0xC8, 0x97,0x93, 0xFF,0xFC, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0x9D,0x5D, 0xF3,0x82, 0x17,0x70, 0xF7,0x04, 0x42,0x54, 0x00,0x00,
-0x00,0x01, 0x27,0x38, 0x00,0x01, 0xF7,0x05, 0x42,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x1B, 0x93,0x93, 0xFF,0xFC, 0xF3,0x86, 0x42,0x44, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x1E,0xC0, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0x9E,0x40, 0x00,0x00,
-0x00,0x01, 0xF5,0x04, 0x40,0x7C, 0xF4,0x84, 0x40,0x74, 0xC7,0x28, 0x50,0x00, 0xC7,0x24,
-0x70,0x00, 0x05,0xB8, 0x00,0x26, 0x86,0xAE, 0x00,0x00, 0x77,0x2D, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x77,0xB4, 0x00,0x08, 0x70,0x3E, 0xFF,0xE8, 0x47,0x0C,
-0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A, 0x00,0x00, 0xF7,0x04, 0x4F,0x58, 0xE6,0x00,
-0x9D,0xFD, 0xF6,0x02, 0x00,0xFF, 0xF7,0x04, 0x42,0x78, 0xF6,0x06, 0x42,0x7A, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xF7,0x33, 0x28,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x78,0x9C, 0x97,0x93,
-0xFF,0xFC, 0xE0,0x00, 0x9E,0x40, 0x00,0x00, 0x00,0x01, 0x86,0xAE, 0x00,0x00, 0x77,0x2D,
-0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02,
-0x00,0x01, 0xC7,0x38, 0x64,0x00, 0xF6,0x02, 0xFF,0x00, 0xC6,0xB4, 0x64,0x00, 0xC7,0x38,
-0x68,0x00, 0xF7,0x2F, 0x28,0x00, 0x07,0x28, 0x00,0x01, 0x97,0x13, 0xFF,0xFC, 0x94,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xBE,0xF8, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0xD8, 0xF3,0x86,
-0x42,0x44, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x20,0xE4, 0x97,0x93,
-0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0xA2,0xC9, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x42,0x54, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xEE,0x00, 0xA0,0x35, 0x24,0x94,
-0x00,0x36, 0xF6,0x04, 0x40,0x74, 0x25,0x14, 0x00,0x38, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x06,0x30, 0x00,0x02, 0x75,0xB1,
-0x00,0x1E, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x87,0x32,
-0x00,0x00, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x24,0x94, 0x00,0x34, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x24,0x94, 0x00,0x32, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x24,0x94, 0x00,0x30, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x24,0x94, 0x00,0x2E, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x24,0x94, 0x00,0x2C, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x24,0x94, 0x00,0x2A, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x24,0x94, 0x00,0x28, 0x76,0x31,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0xF3,0x84, 0x40,0x7C, 0x00,0x00, 0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x95,0x13,
-0xFF,0xFC, 0x23,0x94, 0x00,0x20, 0x93,0x96, 0xFF,0x4C, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xD0,0xDC, 0x97,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0x4C, 0x00,0x00,
-0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x23,0x94, 0x00,0x50, 0x93,0x96, 0xFF,0x44, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xD2,0x58, 0x97,0x93, 0xFF,0xFC, 0x87,0x02,
-0xFF,0x34, 0x00,0x00, 0x00,0x01, 0xF7,0x05, 0x42,0x64, 0xF3,0x84, 0x40,0x7C, 0x00,0x00,
-0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x97,0x13, 0xFF,0xFC, 0x83,0x96, 0xFF,0x44, 0x00,0x00,
-0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0x4C, 0xE0,0x00, 0xA2,0x80, 0x93,0x93,
-0xFF,0xFC, 0xF4,0x04, 0x40,0x7C, 0xF6,0x04, 0x40,0x74, 0xF3,0x82, 0x00,0x00, 0xC7,0x20,
-0x40,0x00, 0xC7,0x30, 0x70,0x00, 0x07,0x38, 0x00,0x26, 0x86,0xBA, 0x00,0x00, 0x77,0x39,
-0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x77,0xB4, 0x00,0x08, 0x70,0x3E,
-0xFF,0xE8, 0x47,0x0C, 0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0xA0,0xAD, 0x93,0x96, 0xFF,0x3C, 0xF7,0x04, 0x42,0xA0, 0xF6,0x06, 0x42,0xA0, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xF7,0x33, 0x28,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x78,0x9C, 0x97,0x93,
-0xFF,0xFC, 0xE0,0x00, 0xA2,0xC8, 0x00,0x00, 0x00,0x01, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x24,0x94, 0x00,0x7E, 0x25,0x14,
-0x00,0x80, 0x23,0x94, 0x00,0x68, 0x06,0x30, 0x00,0x02, 0x75,0xB1, 0x00,0x1E, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0xAC,
-0xFF,0xE5, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94,
-0x00,0x7C, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94,
-0x00,0x7A, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94,
-0x00,0x78, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94,
-0x00,0x76, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94,
-0x00,0x74, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x24,0x94,
-0x00,0x72, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x24,0x94, 0x00,0x70, 0x76,0x31, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x94,0x13,
-0xFF,0xFC, 0x95,0x13, 0xFF,0xFC, 0x93,0x96, 0xFF,0x34, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xD0,0xDC, 0x97,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0x34, 0x00,0x00,
-0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x23,0x94, 0x00,0xB0, 0x93,0x96, 0xFF,0x2C, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xD2,0x58, 0x97,0x93, 0xFF,0xFC, 0x83,0x96,
-0xFF,0x2C, 0x00,0x00, 0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0x3C, 0x00,0x00,
-0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x23,0x94, 0x00,0x98, 0x93,0x96, 0xFF,0x24, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCF,0x24, 0x97,0x93, 0xFF,0xFC, 0xF3,0x82,
-0x00,0x06, 0xF3,0x85, 0x42,0x54, 0x87,0x02, 0xFF,0x34, 0xF3,0x86, 0x38,0xA8, 0xF3,0x85,
-0x42,0x44, 0xF7,0x05, 0x42,0x64, 0xF3,0x84, 0x40,0x7C, 0x00,0x00, 0x00,0x01, 0x93,0x93,
-0xFF,0xFC, 0x97,0x13, 0xFF,0xFC, 0x83,0x96, 0xFF,0x24, 0x00,0x00, 0x00,0x01, 0x93,0x93,
-0xFF,0xFC, 0x83,0x96, 0xFF,0x34, 0x00,0x00, 0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xF7,0xC8, 0x97,0x93, 0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00,
-0xA2,0xA9, 0xF3,0x82, 0x17,0x70, 0xF7,0x04, 0x42,0x54, 0x00,0x00, 0x00,0x01, 0x27,0x38,
-0x00,0x01, 0xF7,0x05, 0x42,0x54, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0x1B, 0x93,0x93,
-0xFF,0xFC, 0xF3,0x86, 0x42,0x44, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01,
-0x1E,0xC0, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0xF6,0x04, 0x6F,0x34, 0xF7,0x04, 0x42,0x64, 0x86,0xB2, 0x00,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0xA3,0xAC, 0x06,0xB0, 0x00,0x02, 0x87,0x36,
-0x00,0x00, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0xF6,0x84,
-0x40,0x7C, 0x77,0x39, 0xFF,0xF0, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x00, 0xA3,0xAC, 0xC7,0x34,
-0x68,0x00, 0xF5,0x84, 0x40,0x74, 0xF6,0x04, 0x4F,0x58, 0x00,0x00, 0x00,0x01, 0xC6,0x2C,
-0x62,0x00, 0x76,0x30, 0xFF,0xFA, 0xC5,0xAC, 0x70,0x00, 0x05,0xAC, 0x00,0x26, 0x86,0xAE,
-0x00,0x00, 0x77,0x2D, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0x46,0x31, 0x00,0x00, 0xC6,0xB4,
-0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02, 0x00,0xFF, 0xC6,0x30, 0x74,0x00, 0xF7,0x02,
-0xFF,0x00, 0xC6,0xB4, 0x74,0x00, 0xC6,0x30, 0x68,0x00, 0xF6,0x2F, 0x28,0x00, 0xF5,0x06,
-0x42,0x44, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x1F,0x48, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x04, 0x40,0x7C, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x13,
-0xFF,0xFC, 0xF5,0x04, 0x40,0x74, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xBE,0xF8, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x80, 0xF7,0x04, 0x42,0x58, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0xA3,0xF4, 0x20,0x3A, 0x00,0x07, 0xF5,0x02,
-0x00,0x01, 0xF5,0x05, 0x42,0x58, 0xF7,0x04, 0x42,0x58, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x07, 0xEE,0x00, 0xA6,0xF0, 0x23,0x94, 0x00,0x1E, 0xF6,0x04, 0x42,0x60, 0x23,0x14,
-0x00,0x66, 0xF4,0x84, 0x40,0x78, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x04,0xA4, 0x00,0x02, 0x74,0x25, 0x00,0x1E, 0x74,0x20,
-0xFF,0xE5, 0x06,0x30, 0x00,0x02, 0x75,0x31, 0x00,0x1E, 0x75,0x28, 0xFF,0xE5, 0x95,0x16,
-0xFF,0x7C, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x25,0x14, 0x00,0x20, 0x95,0x16,
-0xFF,0x94, 0xF7,0x2B, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x85,0x16, 0xFF,0x7C, 0x05,0xA4,
-0x00,0x02, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F, 0x28,0x00, 0x23,0x94,
-0x00,0x1C, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0x25,0x14, 0x00,0x50, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F,
-0x28,0x00, 0x23,0x94, 0x00,0x1A, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F,
-0x28,0x00, 0x23,0x94, 0x00,0x18, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F,
-0x28,0x00, 0x23,0x94, 0x00,0x16, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F,
-0x28,0x00, 0x23,0x94, 0x00,0x14, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F,
-0x28,0x00, 0x23,0x94, 0x00,0x12, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F,
-0x28,0x00, 0x23,0x94, 0x00,0x10, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0x31, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x1F, 0x28,0x00, 0x87,0x26, 0x00,0x00, 0x26,0x14, 0x00,0x68, 0xC7,0x38,
-0x47,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x87,0x2E, 0x00,0x00, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B, 0x28,0x00, 0x23,0x14,
-0x00,0x64, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B, 0x28,0x00, 0x23,0x14,
-0x00,0x62, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B, 0x28,0x00, 0x23,0x14,
-0x00,0x60, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B, 0x28,0x00, 0x23,0x14,
-0x00,0x5E, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B, 0x28,0x00, 0x23,0x14,
-0x00,0x5C, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B, 0x28,0x00, 0x23,0x14,
-0x00,0x5A, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B, 0x28,0x00, 0x05,0xAC,
-0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x23,0x14, 0x00,0x58, 0x75,0xAD, 0x00,0x1E, 0x75,0xAC,
-0xFF,0xE5, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B, 0x28,0x00, 0x96,0x13,
-0xFF,0xFC, 0x95,0x16, 0xFF,0x8C, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xD2,0x58, 0x97,0x93, 0xFF,0xFC, 0x85,0x16, 0xFF,0x8C, 0x00,0x00, 0x00,0x01, 0x95,0x13,
-0xFF,0xFC, 0xF5,0x04, 0x42,0x58, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x25,0x14,
-0x00,0x38, 0x95,0x16, 0xFF,0x84, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xCF,0x24, 0x97,0x93, 0xFF,0xFC, 0xF5,0x04, 0x42,0x58, 0x00,0x00, 0x00,0x01, 0x95,0x13,
-0xFF,0xFC, 0xF5,0x04, 0x42,0x64, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x85,0x16,
-0xFF,0x84, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x85,0x16, 0xFF,0x94, 0x00,0x00,
-0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xF7,0xC8, 0x97,0x93,
-0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0xA6,0xF1, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x42,0x58, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x42,0x58, 0xF7,0x04,
-0x42,0x58, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x07, 0xEE,0x00, 0xA7,0x30, 0xF5,0x02,
-0x17,0x70, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF5,0x02, 0x00,0x1C, 0x20,0x32, 0x00,0x44, 0xE6,0x00,
-0xA7,0x50, 0xB5,0x3A, 0x68,0x02, 0xE0,0x00, 0xA7,0x50, 0xF0,0x05, 0x2D,0x38, 0x95,0x13,
-0xFF,0xFC, 0xF5,0x02, 0x00,0x1B, 0x95,0x13, 0xFF,0xFC, 0xF5,0x06, 0x42,0x44, 0x95,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x1E,0xC0, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x30, 0xF6,0x04,
-0x6F,0x34, 0xF7,0x04, 0x42,0x64, 0x86,0xB2, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0xA9,0xF0, 0x07,0x30, 0x00,0x02, 0x86,0x3A, 0x00,0x00, 0xF5,0x82,
-0x00,0x00, 0xF6,0x84, 0x40,0x7C, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0x30,
-0x77,0xC0, 0xF7,0x04, 0x40,0x74, 0xC6,0xB4, 0x68,0x00, 0x76,0x31, 0xFF,0xF0, 0xC6,0x00,
-0x62,0x00, 0x96,0x16, 0xFF,0xF4, 0xC7,0x38, 0x68,0x00, 0x07,0x38, 0x00,0x26, 0x86,0xBA,
-0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x77,0xB4,
-0x00,0x08, 0x70,0x3E, 0xFF,0xE8, 0x47,0x0C, 0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0xA8,0x34, 0xF6,0x02, 0x00,0xFF, 0x83,0x16, 0xFF,0xF4, 0x83,0x96,
-0xFF,0xF4, 0xF7,0x04, 0x40,0x78, 0xC6,0x98, 0x38,0x00, 0xC7,0x38, 0x68,0x00, 0x07,0x38,
-0x00,0x26, 0x86,0xBA, 0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4,
-0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xC6,0xB4, 0x64,0x00, 0xC0,0x36, 0x5A,0x00, 0x47,0x0C,
-0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0xA8,0x3D, 0x20,0x2E,
-0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0xA8,0x75, 0xF6,0x06,
-0x42,0x7C, 0xF7,0x04, 0x42,0x7C, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33, 0x28,0x00, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x78,0x9C, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0xA9,0xF0, 0x00,0x00,
-0x00,0x01, 0xF3,0x04, 0x42,0x60, 0x00,0x00, 0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xCC,0x60, 0x97,0x93, 0xFF,0xFC, 0xF4,0x04, 0x40,0x78, 0xF7,0x04,
-0x4F,0x58, 0xF5,0x04, 0x40,0x74, 0xF3,0x84, 0x40,0x7C, 0xF3,0x04, 0x40,0x7C, 0xC6,0x20,
-0x72,0x00, 0x76,0x30, 0xFF,0xFA, 0xC5,0x9C, 0x30,0x00, 0xC5,0xA8, 0x58,0x00, 0x05,0xAC,
-0x00,0x26, 0x86,0xAE, 0x00,0x00, 0x74,0xAD, 0x00,0x1E, 0x74,0xA4, 0xFF,0xE5, 0x73,0xAD,
-0x00,0x1E, 0x73,0x9C, 0xFF,0xE5, 0x93,0x96, 0xFF,0xD4, 0xC5,0x28, 0x72,0x00, 0x75,0x28,
-0xFF,0xFA, 0x83,0x16, 0xFF,0xF4, 0x83,0x96, 0xFF,0xF4, 0x46,0x31, 0x00,0x00, 0x45,0x29,
-0x00,0x00, 0xC7,0x18, 0x38,0x00, 0xC4,0x20, 0x70,0x00, 0x04,0x20, 0x00,0x26, 0x73,0x21,
-0x00,0x1E, 0xC6,0xB4, 0x4F,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF4,0x82, 0x00,0xFF, 0xC6,0x30,
-0x4C,0x00, 0xF3,0x82, 0xFF,0x00, 0xC6,0xB4, 0x3C,0x00, 0xC6,0x30, 0x68,0x00, 0xF6,0x2F,
-0x28,0x00, 0x87,0x2E, 0x00,0x00, 0x73,0x18, 0xFF,0xE5, 0x93,0x16, 0xFF,0xCC, 0x83,0x16,
-0xFF,0xD4, 0x83,0x96, 0xFF,0xF4, 0xC5,0x28, 0x4C,0x00, 0xC7,0x38, 0x37,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x76,0x9D, 0x00,0x10, 0x76,0xB5, 0xFF,0xF8, 0xC7,0x38, 0x4C,0x00, 0xC6,0xB4,
-0x70,0x00, 0xF6,0xAF, 0x28,0x00, 0x87,0x22, 0x00,0x00, 0x76,0xA1, 0x00,0x1E, 0x83,0x16,
-0xFF,0xCC, 0xF3,0x82, 0xFF,0x00, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x37,0xC0, 0x77,0x39,
-0xFF,0xF0, 0xC7,0x38, 0x3C,0x00, 0xC5,0x28, 0x70,0x00, 0xF5,0x23, 0x28,0x00, 0x87,0x22,
-0x00,0x00, 0xF3,0x04, 0x40,0x7C, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x73,0x19,
-0x00,0x10, 0x93,0x16, 0xFF,0xEC, 0x73,0x99, 0xFF,0xF8, 0xC7,0x38, 0x4C,0x00, 0xC7,0x1C,
-0x70,0x00, 0x97,0x16, 0xFF,0xDC, 0x23,0x14, 0x00,0x22, 0x83,0x1A, 0x00,0x00, 0x77,0x99,
-0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC3,0x18, 0x7F,0xC0, 0x73,0x19, 0xFF,0xF0, 0xF3,0x23,
-0x28,0x00, 0xF3,0x86, 0x42,0x44, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01,
-0x1F,0x48, 0x97,0x93, 0xFF,0xFC, 0xF7,0x04, 0x40,0x7C, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0x97,0x13, 0xFF,0xFC, 0xF3,0x04, 0x40,0x74, 0x00,0x00, 0x00,0x01, 0x93,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xBE,0xF8, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x98, 0xF3,0x06,
-0x42,0x44, 0x93,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x20,0xE4, 0x97,0x93,
-0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0xAE,0xE5, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x42,0x54, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xEE,0x00, 0xAD,0x89, 0x27,0x38,
-0x00,0x01, 0xF7,0x05, 0x42,0x54, 0x23,0x94, 0x00,0x1E, 0xF6,0x04, 0x42,0x60, 0x24,0x94,
-0x00,0x66, 0x94,0x96, 0xFF,0x64, 0xF3,0x04, 0x40,0x78, 0x24,0x94, 0x00,0x20, 0x94,0x96,
-0xFF,0x94, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0x03,0x18, 0x00,0x02, 0x93,0x16, 0xFF,0x74, 0x74,0x19, 0x00,0x1E, 0x74,0x20,
-0xFF,0xE5, 0x05,0x98, 0x00,0x02, 0x06,0x30, 0x00,0x02, 0x75,0x31, 0x00,0x1E, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0x28,
-0xFF,0xE5, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F, 0x28,0x00, 0x23,0x94,
-0x00,0x1C, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0x85,0x16, 0xFF,0x64, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F,
-0x28,0x00, 0x23,0x94, 0x00,0x1A, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F,
-0x28,0x00, 0x23,0x94, 0x00,0x18, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F,
-0x28,0x00, 0x23,0x94, 0x00,0x16, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F,
-0x28,0x00, 0x23,0x94, 0x00,0x14, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F,
-0x28,0x00, 0x23,0x94, 0x00,0x12, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F,
-0x28,0x00, 0x23,0x94, 0x00,0x10, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0x31, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x1F, 0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x26,0x14, 0x00,0x68, 0xC7,0x38,
-0x47,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x87,0x2E, 0x00,0x00, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x23,0x14,
-0x00,0x64, 0x93,0x16, 0xFF,0x64, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B,
-0x28,0x00, 0x24,0x94, 0x00,0x62, 0x94,0x96, 0xFF,0x64, 0x05,0xAC, 0x00,0x02, 0x87,0x2E,
-0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x25,0x14, 0x00,0x60, 0x95,0x16, 0xFF,0x64, 0x05,0xAC,
-0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x23,0x14, 0x00,0x5E, 0x93,0x16,
-0xFF,0x64, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B, 0x28,0x00, 0x24,0x94,
-0x00,0x5C, 0x94,0x96, 0xFF,0x64, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x25,0x14, 0x00,0x5A, 0x95,0x16, 0xFF,0x64, 0x05,0xAC, 0x00,0x02, 0x87,0x2E,
-0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x24,0x94, 0x00,0x50, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x23,0x14, 0x00,0x58, 0x05,0xAC,
-0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x93,0x16, 0xFF,0x64, 0x75,0xAD, 0x00,0x1E, 0x75,0xAC,
-0xFF,0xE5, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B, 0x28,0x00, 0x96,0x13,
-0xFF,0xFC, 0x94,0x96, 0xFF,0x8C, 0x94,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xD2,0x58, 0x97,0x93, 0xFF,0xFC, 0x85,0x16, 0xFF,0x8C, 0x23,0x14, 0x00,0x38, 0x95,0x13,
-0xFF,0xFC, 0x27,0x80, 0x00,0x07, 0x97,0x93, 0xFF,0xFC, 0x93,0x16, 0xFF,0x84, 0x93,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCF,0x24, 0x97,0x93, 0xFF,0xFC, 0x27,0x80,
-0x00,0x07, 0xF7,0x85, 0x42,0x58, 0x27,0x80, 0x00,0x07, 0x97,0x93, 0xFF,0xFC, 0xF4,0x84,
-0x42,0x64, 0x00,0x00, 0x00,0x01, 0x94,0x93, 0xFF,0xFC, 0x85,0x16, 0xFF,0x84, 0x00,0x00,
-0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x83,0x16, 0xFF,0x94, 0x00,0x00, 0x00,0x01, 0x93,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xF7,0xC8, 0x97,0x93, 0xFF,0xFC, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0xAD,0x5D, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x42,0x58, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x42,0x58, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86,
-0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF4,0x82,
-0x00,0x1C, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0xAE,0xE4, 0xB4,0xBA, 0x68,0x02, 0xE0,0x00,
-0xAE,0xE4, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04, 0x40,0x78, 0xF5,0x84, 0x4F,0x58, 0x07,0x38,
-0x00,0x16, 0x86,0xBA, 0x00,0x00, 0xF4,0x06, 0x3B,0x90, 0x77,0x39, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB4, 0xFF,0xF0, 0x76,0x35, 0x00,0x06, 0xA7,0x2E,
-0x60,0x02, 0xC5,0x2C, 0x60,0x00, 0x76,0xA9, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39, 0x00,0x03, 0xC7,0x38, 0x40,0x00, 0x07,0x38,
-0x00,0x02, 0x86,0xBA, 0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4,
-0x77,0xC0, 0x73,0xB7, 0xFF,0xF0, 0xEE,0x00, 0xAE,0x55, 0x95,0x16, 0xFF,0x64, 0xA7,0x2E,
-0x60,0x02, 0x76,0xA9, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x77,0x39, 0x00,0x03, 0xC7,0x38, 0x40,0x00, 0x86,0xBA, 0x00,0x04, 0x23,0x14,
-0x00,0x88, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5,
-0xFF,0xF0, 0xA6,0xAA, 0x68,0x02, 0x77,0x1D, 0x00,0x03, 0xC7,0x38, 0x68,0x00, 0x27,0x38,
-0x00,0x08, 0x85,0x3A, 0x00,0x04, 0x84,0xBA, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x95,0x1A,
-0x00,0x04, 0x94,0x9A, 0x00,0x00, 0x85,0x96, 0xFF,0x7C, 0xE0,0x00, 0xAE,0x78, 0x00,0x00,
-0x00,0x01, 0x84,0x96, 0xFF,0x64, 0xA7,0x2E, 0x60,0x02, 0x76,0xA5, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39, 0x00,0x03, 0xC7,0x38,
-0x40,0x00, 0x85,0xBA, 0x00,0x04, 0x85,0x16, 0xFF,0x64, 0xF6,0x06, 0x3B,0x90, 0x87,0x2A,
-0x00,0x00, 0x76,0xA9, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x77,0x39, 0x00,0x03, 0xA6,0xBA, 0x60,0x02, 0x20,0x1E, 0x00,0x00, 0xC7,0x38,
-0x60,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0xEE,0x00,
-0xAE,0xC9, 0x76,0xB5, 0xFF,0xF0, 0x83,0x16, 0xFF,0x78, 0x00,0x00, 0x00,0x01, 0x77,0x19,
-0xFF,0xF0, 0xC6,0xB8, 0x68,0x00, 0x84,0x96, 0xFF,0x64, 0x00,0x00, 0x00,0x01, 0xC7,0x24,
-0x68,0x00, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xC1,0x2C, 0x00,0x00, 0x97,0x93,
-0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10,
-0x00,0x10, 0xF7,0x04, 0x40,0x84, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0xAF,0x3C, 0xF6,0x06, 0x42,0xB8, 0xF7,0x04, 0x42,0xB8, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xF3,0x06, 0x36,0x78, 0xF3,0x05, 0x42,0x44, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33, 0x28,0x00, 0xF7,0x04, 0x4F,0x5C, 0xF3,0x84,
-0x42,0x5C, 0x83,0x3A, 0x00,0x04, 0xC4,0x38, 0x00,0x00, 0x93,0x16, 0xFF,0xEC, 0x77,0x1D,
-0x00,0x01, 0xC7,0x38, 0x38,0x00, 0x77,0x39, 0x00,0x02, 0x04,0xB8, 0x00,0x0C, 0x83,0x16,
-0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0xC0,0x1E, 0x32,0x00, 0xEC,0x00, 0xB0,0x70, 0xC5,0x04,
-0x00,0x00, 0xA6,0xA2, 0x48,0x02, 0xF7,0x04, 0xE0,0x00, 0xF5,0x82, 0x00,0x00, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0xAF,0xA8, 0xC6,0x20, 0x48,0x00, 0x86,0xB2, 0x00,0x04, 0xF7,0x04,
-0xE0,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0xAF,0xAC, 0x20,0x2E,
-0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0xAF,0xB9, 0x00,0x00,
-0x00,0x01, 0xF5,0x02, 0x00,0x00, 0x86,0xB2, 0x00,0x00, 0xF7,0x04, 0xE0,0x00, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0xAF,0xF4, 0xF5,0x82, 0x00,0x00, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0xAF,0xFC, 0x20,0x2E, 0x00,0x00, 0x86,0xB2, 0x00,0x04, 0xF7,0x04,
-0xE0,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0xAF,0xFD, 0x20,0x2E,
-0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0xB0,0x0D, 0x20,0x2A,
-0x00,0x00, 0xF5,0x02, 0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x00, 0xB0,0x59, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x7A,0xD0, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0xB0,0x64, 0xC7,0x20, 0x48,0x00, 0x87,0x3A, 0x00,0x08, 0xF6,0x06, 0x40,0x98, 0x77,0x39,
-0x00,0x02, 0xA6,0xBA, 0x60,0x02, 0xC7,0x38, 0x60,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0x20,0x36, 0x00,0x00, 0xE6,0x00,
-0xB0,0x64, 0x00,0x00, 0x00,0x01, 0x04,0xA4, 0x00,0x0C, 0xE0,0x00, 0xAF,0x60, 0x03,0x9C,
-0x00,0x01, 0x83,0x16, 0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0xC0,0x1E, 0x32,0x00, 0xEC,0x00,
-0xB1,0x04, 0xF3,0x06, 0x36,0x78, 0xF6,0x84, 0x4F,0x5C, 0x77,0x1D, 0x00,0x01, 0xC7,0x38,
-0x38,0x00, 0x77,0x39, 0x00,0x02, 0x07,0x38, 0x00,0x0C, 0xC6,0xB4, 0x70,0x00, 0x87,0x36,
-0x00,0x08, 0xF6,0x84, 0x4F,0x58, 0x77,0x39, 0x00,0x06, 0xC6,0xB4, 0x70,0x00, 0x96,0x93,
-0xFF,0xFC, 0x93,0x96, 0xFF,0xF4, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xFA,0x98, 0x97,0x93,
-0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xF6,0x84, 0x42,0x6C, 0x83,0x96, 0xFF,0xF4, 0x47,0x0C,
-0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0xC7,0x1C, 0x70,0x00, 0xF7,0x05, 0x42,0x5C, 0x06,0xB4,
-0x00,0x01, 0xF7,0x04, 0x2D,0x38, 0xF6,0x85, 0x42,0x6C, 0xF6,0x86, 0x2C,0x28, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02, 0x00,0x1C, 0x20,0x32,
-0x00,0x44, 0xE6,0x00, 0xB1,0x08, 0xB3,0x3A, 0x68,0x02, 0xE0,0x00, 0xB1,0x08, 0xF0,0x05,
-0x2D,0x38, 0xF3,0x05, 0x42,0x44, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0xF4,0x02, 0x00,0x00, 0xC5,0xA0, 0x00,0x00, 0xF6,0x82, 0x07,0x70, 0xF7,0x04,
-0x6E,0x50, 0x20,0x36, 0x00,0x00, 0xE6,0x00, 0xB1,0x6D, 0x06,0x38, 0x00,0x1C, 0x87,0x32,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC4,0x20, 0x70,0x00, 0xC0,0x22, 0x72,0x00, 0xE4,0x00,
-0xB1,0x5D, 0x00,0x00, 0x00,0x01, 0x05,0xAC, 0x00,0x01, 0x26,0xB4, 0x00,0x01, 0x20,0x36,
-0x00,0x00, 0xE6,0x00, 0xB1,0x40, 0x06,0x30, 0x00,0x04, 0xC4,0x20, 0x58,0x00, 0xC0,0x22,
-0x5A,0x00, 0xE4,0x00, 0xB1,0x81, 0x00,0x00, 0x00,0x01, 0x04,0x20, 0x00,0x01, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x78,0xD8, 0x97,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xB1,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x04, 0x40,0x94, 0x00,0x00, 0x00,0x01, 0xC0,0x22, 0x72,0x00, 0xE6,0x00,
-0xB1,0xED, 0xF4,0x05, 0x40,0x90, 0xF7,0x04, 0x6E,0x50, 0x00,0x00, 0x00,0x01, 0x86,0xBA,
-0x1D,0xDC, 0xF5,0x82, 0x00,0x01, 0x06,0xB4, 0x00,0x01, 0x96,0xBA, 0x1D,0xDC, 0x87,0x3A,
-0x1D,0xDC, 0xE0,0x00, 0xB1,0xF0, 0xF5,0x85, 0x7A,0xD0, 0xF0,0x05, 0x7A,0xD0, 0xF5,0x84,
-0x40,0x90, 0xF0,0x05, 0x40,0x84, 0xF5,0x85, 0x40,0x94, 0xF5,0x86, 0xE0,0x00, 0x95,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xD5,0xA0, 0x97,0x93, 0xFF,0xFC, 0xF7,0x04,
-0x6E,0x50, 0xF4,0x05, 0x40,0x84, 0x85,0xBA, 0x1D,0xDC, 0x00,0x00, 0x00,0x01, 0xF5,0x85,
-0x3B,0x64, 0xF5,0x84, 0xE0,0x00, 0xF0,0x05, 0x42,0x5C, 0x95,0xBA, 0x00,0x10, 0xF5,0x84,
-0xE0,0x04, 0xF6,0x86, 0x2C,0x28, 0x95,0xBA, 0x00,0x14, 0xF7,0x04, 0x2D,0x38, 0xF5,0x86,
-0x3A,0x4C, 0xF5,0x85, 0x42,0x44, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39,
-0x00,0x02, 0xF5,0x82, 0x00,0x1C, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0xB2,0x68, 0xB5,0xBA,
-0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF5,0x86, 0x35,0xEC, 0xF5,0x85, 0x42,0x30, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x08, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0xC8, 0xF3,0x02,
-0x00,0x00, 0x93,0x16, 0xFF,0x94, 0x24,0x80, 0x00,0x08, 0x94,0x96, 0xFF,0x84, 0x23,0x80,
-0x00,0x07, 0x83,0x16, 0xFF,0x94, 0x00,0x00, 0x00,0x01, 0x93,0x16, 0xFF,0x54, 0x20,0x1E,
-0x00,0x07, 0xEE,0x00, 0xB5,0x64, 0xC7,0x1C, 0x38,0x00, 0x84,0x96, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0xC7,0x24, 0x70,0x00, 0x07,0x38, 0x00,0x26, 0x86,0xBA, 0x00,0x00, 0xF5,0x84,
-0x4F,0x58, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5,
-0xFF,0xF0, 0xF7,0x02, 0x00,0xFF, 0xC6,0xB6, 0x74,0x00, 0xE6,0x00, 0xB3,0x2D, 0x20,0x36,
-0x00,0x01, 0xE6,0x00, 0xB3,0x2D, 0x77,0x35, 0x00,0x06, 0xA6,0xBA, 0x58,0x02, 0xC7,0x38,
-0x58,0x00, 0x76,0x39, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC6,0xB4, 0x67,0xC0, 0x76,0xB5,
-0xFF,0xF0, 0x20,0x36, 0x00,0x02, 0xE6,0x00, 0xB3,0x31, 0xC6,0xB8, 0x00,0x00, 0xC7,0x2C,
-0x00,0x00, 0xE0,0x00, 0xB3,0x30, 0xC6,0xB8, 0x00,0x00, 0xF6,0x84, 0x4F,0x58, 0xF7,0x04,
-0x4F,0x58, 0xC5,0x34, 0x00,0x00, 0xC0,0x2A, 0x72,0x00, 0xE6,0x00, 0xB5,0x5D, 0x00,0x00,
-0x00,0x01, 0xF6,0x84, 0x3B,0xBC, 0xF3,0x02, 0x00,0x00, 0x93,0x16, 0xFF,0x3C, 0x04,0x28,
-0x00,0x1C, 0xF7,0x04, 0x3B,0xB8, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xEC,0x00,
-0xB4,0x40, 0x96,0x96, 0xFF,0xAC, 0x77,0x35, 0x00,0x01, 0xC7,0x38, 0x68,0x00, 0x77,0x39,
-0x00,0x02, 0xF4,0x86, 0x3B,0xB4, 0xC6,0x38, 0x48,0x00, 0x06,0x30, 0x00,0x0C, 0xC3,0x04,
-0x00,0x00, 0x93,0x16, 0xFF,0x34, 0x86,0xB2, 0x00,0x00, 0x87,0x2A, 0x00,0x1C, 0x85,0x96,
-0xFF,0x3C, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0xB3,0xC0, 0x20,0x2E, 0x00,0x00, 0x86,0xB2,
-0x00,0x04, 0x87,0x2A, 0x00,0x20, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0xB3,0xC0, 0x20,0x2E, 0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00,
-0xB3,0xD1, 0x00,0x00, 0x00,0x01, 0xF4,0x82, 0x00,0x00, 0x94,0x96, 0xFF,0x34, 0x86,0xB2,
-0x00,0x00, 0x87,0x22, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00,
-0xB4,0x0C, 0xF5,0x82, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0xB4,0x14, 0x20,0x2E,
-0x00,0x00, 0x86,0xB2, 0x00,0x04, 0x87,0x22, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE2,0x00, 0xB4,0x15, 0x20,0x2E, 0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E,
-0x00,0x00, 0xE6,0x00, 0xB4,0x25, 0x00,0x00, 0x00,0x01, 0xF3,0x02, 0x00,0x01, 0x93,0x16,
-0xFF,0x34, 0x84,0x96, 0xFF,0x34, 0x00,0x00, 0x00,0x01, 0x20,0x26, 0x00,0x00, 0xE6,0x00,
-0xB4,0x40, 0x00,0x00, 0x00,0x01, 0xF3,0x02, 0x00,0x01, 0x93,0x16, 0xFF,0x3C, 0x84,0x96,
-0xFF,0x3C, 0x00,0x00, 0x00,0x01, 0x20,0x26, 0x00,0x00, 0xE6,0x00, 0xB4,0x81, 0xF6,0x02,
-0x00,0x01, 0x87,0x16, 0xFF,0xAC, 0xF3,0x06, 0x3B,0xB4, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4,
-0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4, 0x30,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6,
-0x00,0x00, 0x97,0x16, 0xFF,0xB0, 0xE0,0x00, 0xB4,0xF4, 0x96,0x96, 0xFF,0xB4, 0x27,0x14,
-0x00,0x54, 0x97,0x13, 0xFF,0xFC, 0x94,0x13, 0xFF,0xFC, 0xF4,0x86, 0x3B,0xB4, 0x94,0x93,
-0xFF,0xFC, 0x93,0x96, 0xFF,0x4C, 0x95,0x16, 0xFF,0x44, 0x07,0x88, 0x00,0x08, 0xE0,0x01,
-0x25,0x68, 0x97,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0x4C, 0x85,0x16, 0xFF,0x44, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0xB4,0xF1, 0xF6,0x02, 0x00,0x01, 0x87,0x16, 0xFF,0xAC, 0xF3,0x06,
-0x3B,0xB4, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4,
-0x30,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16, 0xFF,0xB0, 0x96,0x96,
-0xFF,0xB4, 0xF7,0x05, 0x3B,0xBC, 0xE0,0x00, 0xB4,0xF8, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x00, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0xB5,0x2D, 0x27,0x14, 0x00,0x08, 0x84,0x96,
-0xFF,0x54, 0x00,0x00, 0x00,0x01, 0xC7,0x24, 0x70,0x00, 0x83,0x16, 0xFF,0xB4, 0x04,0xA4,
-0x00,0x04, 0x94,0x96, 0xFF,0x54, 0x84,0x96, 0xFF,0x94, 0x93,0x3A, 0xFF,0xC0, 0x04,0xA4,
-0x00,0x01, 0xE0,0x00, 0xB5,0x54, 0x94,0x96, 0xFF,0x94, 0x83,0x16, 0xFF,0x54, 0x00,0x00,
-0x00,0x01, 0xC7,0x18, 0x70,0x00, 0xF4,0x84, 0x4F,0x58, 0x03,0x18, 0x00,0x04, 0x93,0x16,
-0xFF,0x54, 0x83,0x16, 0xFF,0x94, 0x94,0xBA, 0xFF,0xC0, 0x03,0x18, 0x00,0x01, 0x93,0x16,
-0xFF,0x94, 0x95,0x16, 0xFF,0x3C, 0x93,0x96, 0xFF,0x8C, 0xE0,0x00, 0xB2,0xB0, 0x03,0x9C,
-0x00,0x01, 0x84,0x96, 0xFF,0x94, 0x00,0x00, 0x00,0x01, 0x20,0x26, 0x00,0x00, 0xE6,0x00,
-0xB5,0x84, 0xF3,0x82, 0x00,0x01, 0xF4,0x04, 0x4F,0x58, 0xE0,0x00, 0xBE,0xE4, 0x00,0x00,
-0x00,0x01, 0x83,0x16, 0xFF,0xB8, 0x84,0x96, 0xFF,0x94, 0x00,0x00, 0x00,0x01, 0xC0,0x1E,
-0x4A,0x00, 0xEC,0x00, 0xB5,0xCC, 0x93,0x16, 0xFF,0x7C, 0x26,0x94, 0x00,0x04, 0x87,0x36,
-0xFF,0xC0, 0x83,0x16, 0xFF,0x7C, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x32,0x00, 0xE6,0x00,
-0xBB,0x98, 0x03,0x9C, 0x00,0x01, 0x84,0x96, 0xFF,0x94, 0x00,0x00, 0x00,0x01, 0xC0,0x1E,
-0x4A,0x00, 0xEC,0x00, 0xB5,0xA1, 0x06,0xB4, 0x00,0x04, 0xF4,0x04, 0x4F,0x58, 0x83,0x16,
-0xFF,0x7C, 0x00,0x00, 0x00,0x01, 0xC0,0x1A, 0x42,0x00, 0xE6,0x00, 0xBA,0x2D, 0xF4,0x82,
-0x00,0x00, 0x94,0x96, 0xFF,0x74, 0x23,0x80, 0x00,0x07, 0x20,0x1E, 0x00,0x07, 0xEE,0x00,
-0xB7,0x48, 0xC7,0x1C, 0x38,0x00, 0x83,0x16, 0xFF,0x7C, 0x00,0x00, 0x00,0x01, 0xC7,0x18,
-0x70,0x00, 0x07,0x38, 0x00,0x26, 0x86,0xBA, 0x00,0x00, 0xF5,0x84, 0x4F,0x58, 0x77,0x39,
-0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02,
-0x00,0xFF, 0xC6,0xB6, 0x74,0x00, 0xE6,0x00, 0xB6,0x69, 0x20,0x36, 0x00,0x01, 0xE6,0x00,
-0xB6,0x69, 0x77,0x35, 0x00,0x06, 0xA6,0xBA, 0x58,0x02, 0xC7,0x38, 0x58,0x00, 0x76,0x39,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC6,0xB4, 0x67,0xC0, 0x76,0xB5, 0xFF,0xF0, 0x20,0x36,
-0x00,0x02, 0xE6,0x00, 0xB6,0x6D, 0xC6,0xB8, 0x00,0x00, 0xC7,0x2C, 0x00,0x00, 0xE0,0x00,
-0xB6,0x6C, 0xC6,0xB8, 0x00,0x00, 0xF6,0x84, 0x4F,0x58, 0xF7,0x04, 0x4F,0x58, 0xC5,0x34,
-0x00,0x00, 0xC0,0x2A, 0x72,0x00, 0xE6,0x00, 0xB7,0x41, 0xC5,0x84, 0x00,0x00, 0x84,0x96,
-0xFF,0x74, 0x86,0xAA, 0x00,0x1C, 0x83,0x16, 0xFF,0x3C, 0xF6,0x02, 0x00,0x00, 0x04,0xA4,
-0x00,0x01, 0x94,0x96, 0xFF,0x74, 0x87,0x1A, 0x00,0x1C, 0x04,0xA8, 0x00,0x1C, 0x94,0x96,
-0xFF,0x34, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0xB6,0xCC, 0x04,0x18, 0x00,0x1C, 0x86,0xAA,
-0x00,0x20, 0x87,0x1A, 0x00,0x20, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0xB6,0xD0, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0xB6,0xDD, 0x00,0x00, 0x00,0x01, 0xF5,0x82, 0x00,0x00, 0x83,0x16, 0xFF,0x34, 0x87,0x22,
-0x00,0x00, 0x86,0x9A, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00,
-0xB7,0x1C, 0xF6,0x02, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0xB7,0x24, 0x20,0x32,
-0x00,0x00, 0x86,0x9A, 0x00,0x04, 0x87,0x22, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE2,0x00, 0xB7,0x25, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32,
-0x00,0x00, 0xE6,0x00, 0xB7,0x35, 0x20,0x2E, 0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E,
-0x00,0x00, 0xE6,0x00, 0xB7,0x40, 0x00,0x00, 0x00,0x01, 0x93,0x96, 0xFF,0x84, 0xE0,0x00,
-0xB5,0xEC, 0x03,0x9C, 0x00,0x01, 0x84,0x96, 0xFF,0x74, 0x83,0x16, 0xFF,0x94, 0x00,0x00,
-0x00,0x01, 0xC0,0x26, 0x32,0x00, 0xE6,0x00, 0xBB,0x98, 0x23,0x00, 0x00,0x08, 0x84,0x96,
-0xFF,0x84, 0x00,0x00, 0x00,0x01, 0xC0,0x26, 0x32,0x00, 0xE6,0x00, 0xBB,0x99, 0xF6,0x02,
-0x00,0x00, 0xF6,0x84, 0x40,0x7C, 0xF7,0x04, 0x40,0x74, 0xC6,0xB4, 0x68,0x00, 0xC7,0x38,
-0x68,0x00, 0x07,0x38, 0x00,0x26, 0x86,0xBA, 0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x77,0xB4, 0x00,0x08, 0x70,0x3E, 0xFF,0xE8, 0x47,0x0C,
-0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0xB8,0x04, 0xF5,0x82,
-0x00,0xFF, 0x84,0x96, 0xFF,0x84, 0x83,0x16, 0xFF,0x8C, 0x00,0x00, 0x00,0x01, 0xC7,0x24,
-0x32,0x00, 0x84,0x96, 0xFF,0x7C, 0xC7,0x38, 0x70,0x00, 0xC7,0x24, 0x70,0x00, 0x07,0x38,
-0x00,0x26, 0x86,0xBA, 0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4,
-0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xC6,0xB4, 0x5C,0x00, 0xC0,0x36, 0x62,0x00, 0x47,0x0C,
-0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0xB8,0x0D, 0x20,0x32,
-0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0xBB,0x98, 0x23,0x80,
-0x00,0x07, 0x20,0x1E, 0x00,0x07, 0xEE,0x00, 0xB8,0xC8, 0xC7,0x1C, 0x38,0x00, 0x83,0x16,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC7,0x18, 0x70,0x00, 0x07,0x38, 0x00,0x26, 0x86,0xBA,
-0x00,0x00, 0xF5,0x84, 0x4F,0x58, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4,
-0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02, 0x00,0xFF, 0xC6,0xB6, 0x74,0x00, 0xE6,0x00,
-0xB8,0x91, 0x20,0x36, 0x00,0x01, 0xE6,0x00, 0xB8,0x91, 0x77,0x35, 0x00,0x06, 0xA6,0xBA,
-0x58,0x02, 0xC7,0x38, 0x58,0x00, 0x76,0x39, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC6,0xB4,
-0x67,0xC0, 0x76,0xB5, 0xFF,0xF0, 0x20,0x36, 0x00,0x02, 0xE6,0x00, 0xB8,0x95, 0xC6,0xB8,
-0x00,0x00, 0xC7,0x2C, 0x00,0x00, 0xE0,0x00, 0xB8,0x94, 0xC6,0xB8, 0x00,0x00, 0xF6,0x84,
-0x4F,0x58, 0xF7,0x04, 0x4F,0x58, 0xC5,0x34, 0x00,0x00, 0xC0,0x2A, 0x72,0x00, 0xE6,0x00,
-0xB8,0xC1, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x93,0x96, 0xFF,0x4C, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xCC,0x60, 0x97,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0x4C, 0xE0,0x00,
-0xB8,0x14, 0x03,0x9C, 0x00,0x01, 0x84,0x96, 0xFF,0x84, 0x83,0x16, 0xFF,0x8C, 0xF3,0x84,
-0x40,0x7C, 0xF5,0x04, 0x40,0x74, 0xC4,0xA4, 0x32,0x00, 0x94,0x96, 0xFF,0x34, 0x83,0x16,
-0xFF,0x34, 0xC5,0x9C, 0x38,0x00, 0xC5,0xA8, 0x58,0x00, 0x05,0xAC, 0x00,0x26, 0x86,0xAE,
-0x00,0x00, 0x77,0x2D, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0x74,0x2D, 0x00,0x1E, 0x74,0x20,
-0xFF,0xE5, 0x73,0x9D, 0x00,0x10, 0x73,0x9D, 0xFF,0xF8, 0xC4,0xA4, 0x30,0x00, 0x94,0x96,
-0xFF,0x3C, 0x83,0x16, 0xFF,0x7C, 0xC6,0xB4, 0x77,0xC0, 0xC4,0x98, 0x48,0x00, 0x94,0x96,
-0xFF,0x3C, 0x04,0xA4, 0x00,0x26, 0x94,0x96, 0xFF,0x3C, 0x73,0x25, 0x00,0x1E, 0x73,0x18,
-0xFF,0xE5, 0x93,0x16, 0xFF,0x6C, 0x74,0xA5, 0x00,0x1E, 0x94,0x96, 0xFF,0x64, 0x74,0xA4,
-0xFF,0xE5, 0x94,0x96, 0xFF,0x64, 0x83,0x16, 0xFF,0x7C, 0xF4,0x84, 0x4F,0x58, 0x76,0xB5,
-0xFF,0xF0, 0xC6,0x18, 0x4A,0x00, 0x76,0x30, 0xFF,0xFA, 0x46,0x31, 0x00,0x00, 0xF3,0x02,
-0x00,0xFF, 0xC6,0x30, 0x34,0x00, 0xF4,0x82, 0xFF,0x00, 0xC6,0xB4, 0x4C,0x00, 0xC6,0x30,
-0x68,0x00, 0xF6,0x2F, 0x28,0x00, 0x87,0x2E, 0x00,0x00, 0x83,0x16, 0xFF,0x34, 0xC7,0x38,
-0x47,0xC0, 0x77,0x39, 0xFF,0xF0, 0x73,0x19, 0x00,0x10, 0x93,0x16, 0xFF,0x34, 0x74,0x99,
-0xFF,0xF8, 0xF3,0x02, 0x00,0xFF, 0xC7,0x38, 0x34,0x00, 0xC7,0x24, 0x70,0x00, 0x97,0x16,
-0xFF,0x34, 0x24,0x94, 0x00,0xCA, 0x84,0xA6, 0x00,0x00, 0x77,0xA5, 0x00,0x1E, 0x77,0xBC,
-0xFF,0xE5, 0xC4,0xA4, 0x7F,0xC0, 0x74,0xA5, 0xFF,0xF0, 0x83,0x16, 0xFF,0x3C, 0xF4,0xAF,
-0x28,0x00, 0xF4,0x84, 0x4F,0x58, 0x87,0x1A, 0x00,0x00, 0xC5,0x28, 0x4A,0x00, 0x75,0x28,
-0xFF,0xFA, 0x83,0x16, 0xFF,0x6C, 0x45,0x29, 0x00,0x00, 0xF4,0x82, 0x00,0xFF, 0xC5,0x28,
-0x4C,0x00, 0x84,0x96, 0xFF,0x3C, 0xC7,0x38, 0x37,0xC0, 0x77,0x39, 0xFF,0xF0, 0xF3,0x02,
-0xFF,0x00, 0xC7,0x38, 0x34,0x00, 0xC5,0x28, 0x70,0x00, 0xF5,0x27, 0x28,0x00, 0x87,0x26,
-0x00,0x00, 0x83,0x16, 0xFF,0x64, 0x84,0x16, 0xFF,0x7C, 0xC7,0x38, 0x37,0xC0, 0x77,0x39,
-0xFF,0xF0, 0xF4,0x82, 0x00,0xFF, 0xC7,0x38, 0x4C,0x00, 0x83,0x16, 0xFF,0x3C, 0xC3,0x9C,
-0x70,0x00, 0xE0,0x00, 0xBE,0xE4, 0xF3,0x9B, 0x28,0x00, 0xF7,0x04, 0x40,0x7C, 0xF6,0x04,
-0x40,0x74, 0xC7,0x38, 0x70,0x00, 0xC7,0x30, 0x70,0x00, 0x07,0x38, 0x00,0x26, 0x86,0xBA,
-0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x77,0xB4,
-0x00,0x08, 0x70,0x3E, 0xFF,0xE8, 0x47,0x0C, 0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0xBA,0x7D, 0x25,0x80, 0x00,0x07, 0xE0,0x00, 0xBE,0xE4, 0x04,0x20,
-0x00,0x40, 0xE0,0x00, 0xBA,0xD8, 0xC4,0x2C, 0x00,0x00, 0xC7,0x30, 0x42,0x00, 0x84,0x96,
-0x00,0x00, 0x75,0x38, 0xFF,0xFA, 0x06,0x24, 0x00,0x0A, 0x20,0x2E, 0x00,0x07, 0xEE,0x00,
-0xBA,0xD4, 0x07,0x30, 0x00,0x0E, 0x86,0xBA, 0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02, 0x00,0xFF, 0xC6,0xB4,
-0x74,0x00, 0x47,0x29, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0xBA,0x74, 0x06,0x30, 0x00,0x02, 0xE0,0x00, 0xBA,0x8C, 0x05,0xAC,
-0x00,0x01, 0xF4,0x02, 0x00,0x08, 0x07,0x20, 0x00,0x07, 0x20,0x3A, 0x00,0x0E, 0xE2,0x00,
-0xBB,0xA4, 0xC5,0xA0, 0x40,0x00, 0x83,0x16, 0x00,0x00, 0xF5,0x04, 0x40,0x7C, 0xF4,0x82,
-0x00,0xFF, 0xF6,0x04, 0x4F,0x58, 0xC5,0x98, 0x58,0x00, 0x05,0xAC, 0x00,0x26, 0x86,0xAE,
-0x00,0x00, 0x77,0x2D, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0x18, 0x62,0x00, 0x76,0x30,
-0xFF,0xFA, 0x46,0x31, 0x00,0x00, 0xC6,0x30, 0x4C,0x00, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5,
-0xFF,0xF0, 0x77,0x29, 0x00,0x10, 0x77,0x39, 0xFF,0xF8, 0xC6,0xB4, 0x4C,0x00, 0xC7,0x38,
-0x68,0x00, 0xF7,0x2F, 0x28,0x00, 0xF5,0x84, 0x40,0x74, 0xC5,0x28, 0x50,0x00, 0xC5,0xAC,
-0x50,0x00, 0x05,0xAC, 0x00,0x26, 0x86,0xAE, 0x00,0x00, 0x77,0x2D, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0x75,0x2D, 0x00,0x1E, 0x75,0x28, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5,
-0xFF,0xF0, 0xF7,0x02, 0xFF,0x00, 0xC6,0xB4, 0x74,0x00, 0xC6,0x30, 0x68,0x00, 0xF6,0x2F,
-0x28,0x00, 0x87,0x2E, 0x00,0x00, 0x76,0xA1, 0x00,0x10, 0x76,0xB5, 0xFF,0xF8, 0xC7,0x38,
-0x57,0xC0, 0x77,0x39, 0xFF,0xF0, 0xC7,0x38, 0x4C,0x00, 0xC6,0xB4, 0x70,0x00, 0xE0,0x00,
-0xBB,0xF8, 0xF6,0xAF, 0x28,0x00, 0xF4,0x04, 0x4F,0x58, 0xE0,0x00, 0xBE,0xE4, 0x04,0x20,
-0x00,0x40, 0xF6,0x04, 0x4F,0x58, 0x83,0x16, 0x00,0x00, 0xF7,0x04, 0x40,0x7C, 0xF5,0x84,
-0x40,0x74, 0xC6,0x18, 0x62,0x00, 0x76,0x30, 0xFF,0xFA, 0xC7,0x38, 0x70,0x00, 0xC5,0xAC,
-0x70,0x00, 0x05,0xAC, 0x00,0x26, 0x86,0xAE, 0x00,0x00, 0x77,0x2D, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0x46,0x31, 0x00,0x00, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02,
-0x00,0xFF, 0xC6,0x30, 0x74,0x00, 0xF7,0x02, 0xFF,0x00, 0xC6,0xB4, 0x74,0x00, 0xC6,0x30,
-0x68,0x00, 0xF6,0x2F, 0x28,0x00, 0x23,0x80, 0x00,0x07, 0x20,0x1E, 0x00,0x07, 0xEE,0x00,
-0xBE,0xE0, 0xC7,0x1C, 0x38,0x00, 0x84,0x96, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC7,0x24,
-0x70,0x00, 0x07,0x38, 0x00,0x26, 0x86,0xBA, 0x00,0x00, 0xF5,0x84, 0x4F,0x58, 0x77,0x39,
-0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02,
-0x00,0xFF, 0xC6,0xB6, 0x74,0x00, 0xE6,0x00, 0xBC,0x79, 0x20,0x36, 0x00,0x01, 0xE6,0x00,
-0xBC,0x79, 0x77,0x35, 0x00,0x06, 0xA6,0xBA, 0x58,0x02, 0xC7,0x38, 0x58,0x00, 0x76,0x39,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC6,0xB4, 0x67,0xC0, 0x76,0xB5, 0xFF,0xF0, 0x20,0x36,
-0x00,0x02, 0xE6,0x00, 0xBC,0x7D, 0xC6,0xB8, 0x00,0x00, 0xC7,0x2C, 0x00,0x00, 0xE0,0x00,
-0xBC,0x7C, 0xC6,0xB8, 0x00,0x00, 0xF6,0x84, 0x4F,0x58, 0xF7,0x04, 0x4F,0x58, 0xC5,0x34,
-0x00,0x00, 0xC0,0x2A, 0x72,0x00, 0xE6,0x00, 0xBE,0xD9, 0x06,0xA8, 0x00,0x1C, 0x83,0x16,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0x96,0x93, 0xFF,0xFC, 0xF4,0x86,
-0x3B,0xB4, 0x94,0x93, 0xFF,0xFC, 0x93,0x96, 0xFF,0x4C, 0x95,0x16, 0xFF,0x44, 0x96,0x96,
-0xFF,0x40, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x23,0x40, 0x97,0x93, 0xFF,0xFC, 0xF3,0x04,
-0x4F,0x5C, 0xF4,0x82, 0x00,0x00, 0x94,0x96, 0xFF,0x5C, 0x86,0x96, 0xFF,0x40, 0x83,0x96,
-0xFF,0x4C, 0x85,0x16, 0xFF,0x44, 0x93,0x16, 0xFF,0x34, 0x86,0x1A, 0x00,0x08, 0x96,0x96,
-0xFF,0x3C, 0x87,0x1A, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x32, 0x72,0x00, 0xEC,0x00,
-0xBD,0xB8, 0x96,0x16, 0xFF,0x9C, 0x77,0x31, 0x00,0x01, 0xC7,0x38, 0x60,0x00, 0x77,0x39,
-0x00,0x02, 0xC6,0x38, 0x30,0x00, 0x06,0x30, 0x00,0x0C, 0x86,0xB2, 0x00,0x00, 0x87,0x2A,
-0x00,0x1C, 0x85,0x96, 0xFF,0x5C, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0xBD,0x40, 0xC4,0x04,
-0x00,0x00, 0x86,0xB2, 0x00,0x04, 0x87,0x2A, 0x00,0x20, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0xBD,0x44, 0x20,0x2E, 0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E,
-0x00,0x00, 0xE6,0x00, 0xBD,0x51, 0x00,0x00, 0x00,0x01, 0xF4,0x02, 0x00,0x00, 0x83,0x16,
-0xFF,0x3C, 0x86,0xB2, 0x00,0x00, 0x87,0x1A, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE2,0x00, 0xBD,0x90, 0xF5,0x82, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0xBD,0x98, 0x20,0x2E, 0x00,0x00, 0x86,0xB2, 0x00,0x04, 0x87,0x1A, 0x00,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0xBD,0x99, 0x20,0x2E, 0x00,0x00, 0xF5,0x82,
-0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0xBD,0xA9, 0x20,0x22, 0x00,0x00, 0xF4,0x02,
-0x00,0x01, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0xBD,0xB8, 0x00,0x00, 0x00,0x01, 0xF4,0x82,
-0x00,0x01, 0x94,0x96, 0xFF,0x5C, 0x83,0x16, 0xFF,0x5C, 0x00,0x00, 0x00,0x01, 0x20,0x1A,
-0x00,0x00, 0xE6,0x00, 0xBD,0xF9, 0xF6,0x02, 0x00,0x01, 0x87,0x16, 0xFF,0x9C, 0x84,0x96,
-0xFF,0x34, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4,
-0x48,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16, 0xFF,0xA0, 0xE0,0x00,
-0xBE,0x70, 0x96,0x96, 0xFF,0xA4, 0x27,0x14, 0x00,0x64, 0x97,0x13, 0xFF,0xFC, 0x83,0x16,
-0xFF,0x3C, 0x00,0x00, 0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0x84,0x96, 0xFF,0x34, 0x00,0x00,
-0x00,0x01, 0x94,0x93, 0xFF,0xFC, 0x93,0x96, 0xFF,0x4C, 0x95,0x16, 0xFF,0x44, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x25,0x68, 0x97,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0x4C, 0x85,0x16,
-0xFF,0x44, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0xBE,0x71, 0xF6,0x02, 0x00,0x00, 0x87,0x16,
-0xFF,0x9C, 0x83,0x16, 0xFF,0x34, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5,
-0x00,0x02, 0xC6,0xB4, 0x30,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16,
-0xFF,0xA0, 0x96,0x96, 0xFF,0xA4, 0x97,0x1A, 0x00,0x08, 0xF6,0x02, 0x00,0x01, 0x20,0x32,
-0x00,0x00, 0xE6,0x00, 0xBE,0x99, 0xF6,0x06, 0x42,0x9C, 0xF7,0x04, 0x42,0x9C, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xF7,0x33, 0x28,0x00, 0xF7,0x04, 0x4F,0x58, 0x00,0x00, 0x00,0x01, 0xC7,0x28,
-0x72,0x00, 0x77,0x38, 0xFF,0xFA, 0x47,0x39, 0x00,0x00, 0x97,0x13, 0xFF,0xFC, 0x07,0x28,
-0x00,0x1C, 0x97,0x13, 0xFF,0xFC, 0xF4,0x84, 0x4F,0x5C, 0x00,0x00, 0x00,0x01, 0x94,0x93,
-0xFF,0xFC, 0x93,0x96, 0xFF,0x4C, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x23,0x40, 0x97,0x93,
-0xFF,0xFC, 0x83,0x96, 0xFF,0x4C, 0xE0,0x00, 0xBB,0xFC, 0x03,0x9C, 0x00,0x01, 0x84,0x16,
-0x00,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10,
-0x00,0x60, 0x85,0x16, 0x00,0x00, 0x86,0x16, 0x00,0x04, 0x06,0xA8, 0x00,0x18, 0xC7,0x30,
-0x60,0x00, 0xC5,0xB8, 0x68,0x00, 0x20,0x32, 0x00,0x07, 0xEE,0x00, 0xBF,0x64, 0x07,0x2C,
-0x00,0x0E, 0x86,0xBA, 0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4,
-0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02, 0x00,0xFF, 0xC6,0xB4, 0x74,0x00, 0x20,0x36,
-0x00,0x00, 0x47,0x0C, 0x00,0x01, 0xD7,0x00, 0x0A,0x70, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0xBF,0x61, 0x05,0xAC, 0x00,0x02, 0xE0,0x00, 0xBF,0x18, 0x06,0x30, 0x00,0x01, 0x20,0x32,
-0x00,0x07, 0xEE,0x00, 0xC0,0x4C, 0x06,0xA8, 0x00,0x16, 0xF5,0x05, 0x40,0x74, 0xF6,0x05,
-0x40,0x7C, 0xF3,0x02, 0x00,0x06, 0xF3,0x05, 0x42,0x54, 0x96,0x13, 0xFF,0xFC, 0x05,0x28,
-0x00,0x02, 0x95,0x16, 0xFF,0xC4, 0x95,0x13, 0xFF,0xFC, 0x23,0x94, 0x00,0x20, 0x93,0x96,
-0xFF,0xBC, 0x93,0x93, 0xFF,0xFC, 0x96,0x16, 0xFF,0xAC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xD0,0xDC, 0x97,0x93, 0xFF,0xFC, 0x84,0x96, 0xFF,0xC4, 0x23,0x14, 0x00,0x38, 0x94,0x93,
-0xFF,0xFC, 0x93,0x16, 0xFF,0xB4, 0x93,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xD2,0x58, 0x97,0x93, 0xFF,0xFC, 0x87,0x02, 0xFF,0x34, 0x86,0x16, 0xFF,0xAC, 0xF7,0x05,
-0x42,0x64, 0x96,0x13, 0xFF,0xFC, 0x97,0x13, 0xFF,0xFC, 0x83,0x96, 0xFF,0xB4, 0x00,0x00,
-0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x84,0x96, 0xFF,0xBC, 0x00,0x00, 0x00,0x01, 0x94,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xF7,0xC8, 0x97,0x93, 0xFF,0xFC, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0xC0,0x1D, 0xF3,0x06, 0x3A,0xD8, 0xF7,0x04, 0x42,0x54, 0x00,0x00,
-0x00,0x01, 0x27,0x38, 0x00,0x01, 0xF7,0x05, 0x42,0x54, 0xF3,0x05, 0x42,0x44, 0xF3,0x82,
-0x17,0x70, 0x93,0x93, 0xFF,0xFC, 0xF4,0x82, 0x00,0x1B, 0x94,0x93, 0xFF,0xFC, 0xF3,0x06,
-0x42,0x44, 0x93,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x1E,0xC0, 0x97,0x93,
-0xFF,0xFC, 0xE0,0x00, 0xC1,0xA0, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x00, 0xF5,0x84,
-0x4F,0x58, 0xF4,0x06, 0x3B,0x70, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x76,0x39, 0x00,0x06, 0xA7,0x2E, 0x60,0x02, 0xC5,0x2C,
-0x60,0x00, 0x76,0xA9, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x77,0x39, 0x00,0x03, 0xC7,0x38, 0x40,0x00, 0x07,0x38, 0x00,0x02, 0x86,0xBA,
-0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB7,
-0xFF,0xF0, 0xEE,0x00, 0xC1,0x15, 0x96,0x96, 0xFF,0x9C, 0xA7,0x2E, 0x60,0x02, 0x76,0xA9,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x83,0x96, 0xFF,0x9C, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x77,0x39, 0x00,0x03, 0xC7,0x38, 0x40,0x00, 0x86,0xBA, 0x00,0x04, 0x24,0x94,
-0x00,0x60, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5,
-0xFF,0xF0, 0xA6,0xAA, 0x68,0x02, 0x77,0x1D, 0x00,0x03, 0xC7,0x38, 0x68,0x00, 0x27,0x38,
-0x00,0x08, 0x83,0xBA, 0x00,0x04, 0x83,0x3A, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x93,0xA6,
-0x00,0x04, 0x93,0x26, 0x00,0x00, 0x85,0x96, 0xFF,0xA4, 0xE0,0x00, 0xC1,0x38, 0x23,0x00,
-0x00,0x07, 0xA7,0x2E, 0x60,0x02, 0x76,0xA9, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39, 0x00,0x03, 0xC7,0x38, 0x40,0x00, 0x85,0xBA,
-0x00,0x04, 0x23,0x00, 0x00,0x07, 0x93,0x13, 0xFF,0xFC, 0x87,0x2A, 0x00,0x00, 0x76,0xA9,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x83,0x96, 0xFF,0x9C, 0xF6,0x06, 0x3B,0x70, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39, 0x00,0x03, 0xA6,0xBA, 0x60,0x02, 0x20,0x1E,
-0x00,0x00, 0xC7,0x38, 0x60,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4,
-0x77,0xC0, 0xEE,0x00, 0xC1,0x8D, 0x76,0xB5, 0xFF,0xF0, 0x84,0x96, 0xFF,0xA0, 0x00,0x00,
-0x00,0x01, 0x77,0x25, 0xFF,0xF0, 0xC6,0xB8, 0x68,0x00, 0xC7,0x28, 0x68,0x00, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xC1,0x2C, 0x00,0x00, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x08, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x70, 0x25,0x00,
-0x00,0x07, 0x20,0x2A, 0x00,0x07, 0xEE,0x00, 0xC3,0xB8, 0xC7,0x28, 0x50,0x00, 0x83,0x16,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC7,0x18, 0x70,0x00, 0x07,0x38, 0x00,0x26, 0x86,0xBA,
-0x00,0x00, 0xF5,0x84, 0x4F,0x58, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4,
-0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02, 0x00,0xFF, 0xC6,0xB6, 0x74,0x00, 0xE6,0x00,
-0xC2,0x3D, 0x20,0x36, 0x00,0x01, 0xE6,0x00, 0xC2,0x3D, 0x77,0x35, 0x00,0x06, 0xA6,0xBA,
-0x58,0x02, 0xC7,0x38, 0x58,0x00, 0x76,0x39, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC6,0xB4,
-0x67,0xC0, 0x76,0xB5, 0xFF,0xF0, 0x20,0x36, 0x00,0x02, 0xE6,0x00, 0xC2,0x4D, 0xC0,0x3A,
-0x5A,0x00, 0xE0,0x00, 0xC2,0x48, 0xC7,0x2C, 0x00,0x00, 0xF7,0x04, 0x4F,0x58, 0xF5,0x84,
-0x4F,0x58, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x5A,0x00, 0xE6,0x00, 0xC3,0xB1, 0xF4,0x86,
-0x3B,0x90, 0x83,0x96, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x06,0x9C, 0x00,0x16, 0x87,0x36,
-0x00,0x00, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0x76,0x39, 0x00,0x06, 0xA7,0x2E, 0x60,0x02, 0xC5,0x2C, 0x60,0x00, 0x76,0xA9,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39,
-0x00,0x03, 0xC7,0x38, 0x48,0x00, 0x07,0x38, 0x00,0x02, 0x86,0xBA, 0x00,0x00, 0x77,0x39,
-0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB7, 0xFF,0xF0, 0xEE,0x00,
-0xC3,0x21, 0x96,0x96, 0xFF,0x8C, 0xA7,0x2E, 0x60,0x02, 0x76,0xA9, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0x83,0x16, 0xFF,0x8C, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39,
-0x00,0x03, 0xC7,0x38, 0x48,0x00, 0x86,0xBA, 0x00,0x04, 0x24,0x94, 0x00,0x70, 0x77,0x39,
-0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xA6,0xAA,
-0x68,0x02, 0x77,0x19, 0x00,0x03, 0xC7,0x38, 0x68,0x00, 0x27,0x38, 0x00,0x08, 0x83,0xBA,
-0x00,0x04, 0x83,0x3A, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x93,0xA6, 0x00,0x04, 0x93,0x26,
-0x00,0x00, 0x86,0x16, 0xFF,0x94, 0xE0,0x00, 0xC3,0x44, 0x00,0x00, 0x00,0x01, 0xA7,0x2E,
-0x60,0x02, 0x76,0xA9, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xF3,0x06, 0x3B,0x90, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39, 0x00,0x03, 0xC7,0x38, 0x30,0x00, 0x86,0x3A,
-0x00,0x04, 0x87,0x2A, 0x00,0x00, 0x76,0xA9, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x83,0x96,
-0xFF,0x8C, 0xF4,0x86, 0x3B,0x90, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39,
-0x00,0x03, 0xA6,0xBA, 0x48,0x02, 0x20,0x1E, 0x00,0x00, 0xC7,0x38, 0x48,0x00, 0x77,0x39,
-0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0xEE,0x00, 0xC3,0x95, 0x76,0xB5,
-0xFF,0xF0, 0x83,0x16, 0xFF,0x90, 0x00,0x00, 0x00,0x01, 0x77,0x19, 0xFF,0xF0, 0xC6,0xB8,
-0x68,0x00, 0xC7,0x28, 0x68,0x00, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xC1,0x30,
-0x00,0x00, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0xC5,0xC4, 0x00,0x00, 0x00,0x01, 0xE0,0x00,
-0xC1,0xC4, 0x05,0x28, 0x00,0x01, 0x83,0x96, 0x00,0x00, 0xF4,0x82, 0x00,0x06, 0xF4,0x85,
-0x42,0x54, 0xF6,0x04, 0x42,0x60, 0x25,0x14, 0x00,0x1E, 0x23,0x14, 0x00,0x20, 0x93,0x16,
-0xFF,0xAC, 0xF3,0x85, 0x40,0x78, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x06,0x30, 0x00,0x02, 0x75,0xB1, 0x00,0x1E, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0xAC,
-0xFF,0xE5, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14,
-0x00,0x1C, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14,
-0x00,0x1A, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14,
-0x00,0x18, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14,
-0x00,0x16, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14,
-0x00,0x14, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14,
-0x00,0x12, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x25,0x14, 0x00,0x10, 0x76,0x31, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x07,0x1C,
-0x00,0x02, 0x97,0x13, 0xFF,0xFC, 0x23,0x94, 0x00,0x50, 0x93,0x96, 0xFF,0xA4, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xD2,0x58, 0x97,0x93, 0xFF,0xFC, 0x84,0x96,
-0xFF,0xA4, 0x23,0x14, 0x00,0x38, 0x94,0x93, 0xFF,0xFC, 0x27,0x80, 0x00,0x07, 0x97,0x93,
-0xFF,0xFC, 0x93,0x16, 0xFF,0x9C, 0x93,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xCF,0x24, 0x97,0x93, 0xFF,0xFC, 0x87,0x02, 0xFF,0x34, 0x27,0x80, 0x00,0x07, 0xF7,0x85,
-0x42,0x58, 0xF7,0x05, 0x42,0x64, 0x27,0x80, 0x00,0x07, 0x97,0x93, 0xFF,0xFC, 0x97,0x13,
-0xFF,0xFC, 0x83,0x96, 0xFF,0x9C, 0x00,0x00, 0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x84,0x96,
-0xFF,0xAC, 0x00,0x00, 0x00,0x01, 0x94,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xF5,0xF4, 0x97,0x93, 0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0xC5,0x95, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x42,0x58, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x42,0x58, 0xF7,0x04, 0x2D,0x38, 0xF3,0x06, 0x39,0xC0, 0xF3,0x05, 0x42,0x44, 0xF6,0x86,
-0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x82,
-0x00,0x1C, 0x20,0x32, 0x00,0x44, 0xE6,0x00, 0xC5,0xC4, 0xB3,0xBA, 0x68,0x02, 0xF0,0x05,
-0x2D,0x38, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x25,0x00,
-0x00,0x07, 0xF7,0x04, 0x40,0x74, 0xF6,0x84, 0x4F,0x58, 0xF6,0x04, 0x42,0x60, 0xC7,0x38,
-0x6A,0x00, 0x75,0xB8, 0xFF,0xFA, 0x06,0x30, 0x00,0x0A, 0x20,0x2A, 0x00,0x07, 0xEE,0x00,
-0xC6,0x48, 0x07,0x30, 0x00,0x0E, 0x86,0xBA, 0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02, 0x00,0xFF, 0xC6,0xB4,
-0x74,0x00, 0x47,0x2D, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0xC6,0x4C, 0xC3,0x28, 0x00,0x00, 0x06,0x30, 0x00,0x02, 0xE0,0x00,
-0xC5,0xFC, 0x05,0x28, 0x00,0x01, 0xF3,0x02, 0x00,0x08, 0xC5,0x18, 0x30,0x00, 0xF3,0x84,
-0x42,0x60, 0xF6,0x04, 0x4F,0x58, 0xF7,0x04, 0x40,0x7C, 0xF4,0x84, 0x40,0x74, 0xC5,0x1C,
-0x50,0x00, 0x05,0x28, 0x00,0x26, 0x85,0xAA, 0x00,0x00, 0x74,0x29, 0x00,0x1E, 0x74,0x20,
-0xFF,0xE5, 0xC6,0x1C, 0x62,0x00, 0x76,0x30, 0xFF,0xFA, 0xC6,0xB8, 0x70,0x00, 0xC4,0xA4,
-0x68,0x00, 0x04,0xA4, 0x00,0x26, 0x76,0xA5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x77,0x39,
-0x00,0x10, 0x77,0x39, 0xFF,0xF8, 0x46,0x31, 0x00,0x00, 0xC5,0xAC, 0x47,0xC0, 0x75,0xAD,
-0xFF,0xF0, 0xF4,0x02, 0x00,0xFF, 0xC5,0xAC, 0x44,0x00, 0xC7,0x38, 0x58,0x00, 0xF7,0x2B,
-0x28,0x00, 0x87,0x26, 0x00,0x00, 0x75,0xA5, 0x00,0x1E, 0xC6,0x30, 0x44,0x00, 0x75,0xAC,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0xF6,0x82, 0xFF,0x00, 0xC7,0x38,
-0x6C,0x00, 0xC6,0x30, 0x70,0x00, 0xF6,0x27, 0x28,0x00, 0x87,0x26, 0x00,0x00, 0x76,0x99,
-0x00,0x10, 0x76,0xB5, 0xFF,0xF8, 0xC7,0x38, 0x5F,0xC0, 0x77,0x39, 0xFF,0xF0, 0xC7,0x38,
-0x44,0x00, 0xC6,0xB4, 0x70,0x00, 0xF6,0xA7, 0x28,0x00, 0x93,0x93, 0xFF,0xFC, 0xF3,0x84,
-0x3B,0xB0, 0x00,0x00, 0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xD4,0x2C, 0x97,0x93, 0xFF,0xFC, 0xF7,0x04, 0x40,0x7C, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0x97,0x13, 0xFF,0xFC, 0xF3,0x84, 0x40,0x74, 0x00,0x00, 0x00,0x01, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xBE,0xF8, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x08, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x06,
-0x42,0x30, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x35,0x60, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x42,0x30, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x35,0xEC, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x42,0x44, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x36,0x78, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x06, 0x42,0x44, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x37,0x04, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06,
-0x42,0x44, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x37,0x90, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x42,0x44, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x38,0x1C, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x42,0x44, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x38,0xA8, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x06, 0x42,0x44, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x39,0x34, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06,
-0x42,0x44, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x39,0xC0, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x42,0x44, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x3A,0x4C, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x42,0x44, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x3A,0xD8, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93,
-0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x85,0x96,
-0x00,0x00, 0xF5,0x06, 0x3B,0x90, 0x87,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39, 0x00,0x03, 0xC7,0x38,
-0x50,0x00, 0x07,0x38, 0x00,0x02, 0x86,0xBA, 0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0x37, 0xFF,0xF0, 0xEE,0x00, 0xC9,0x95, 0x00,0x00,
-0x00,0x01, 0x87,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39, 0x00,0x03, 0xC7,0x38, 0x50,0x00, 0x86,0xBA,
-0x00,0x04, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5,
-0xFF,0xF0, 0xA6,0xAE, 0x68,0x02, 0x77,0x31, 0x00,0x03, 0xC7,0x38, 0x68,0x00, 0x27,0x38,
-0x00,0x08, 0x84,0xBA, 0x00,0x04, 0x84,0x3A, 0x00,0x00, 0xE0,0x00, 0xC9,0xB4, 0xC5,0x24,
-0x00,0x00, 0x87,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39, 0x00,0x03, 0xC7,0x38, 0x50,0x00, 0x85,0x3A,
-0x00,0x04, 0x87,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x20,0x32,
-0x00,0x00, 0xF6,0x06, 0x3B,0x90, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39,
-0x00,0x03, 0xA6,0xBA, 0x60,0x02, 0xC7,0x38, 0x60,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0xEE,0x00, 0xC9,0xF9, 0x76,0xB5, 0xFF,0xF0, 0x77,0x21,
-0xFF,0xF0, 0xC6,0xB8, 0x68,0x00, 0xC7,0x2C, 0x68,0x00, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xC1,0x28, 0x00,0x00, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x85,0x96, 0x00,0x00, 0xF5,0x06, 0x3B,0x70, 0x87,0x2E,
-0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x77,0x39, 0x00,0x03, 0xC7,0x38, 0x50,0x00, 0x07,0x38, 0x00,0x02, 0x86,0xBA,
-0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0x37,
-0xFF,0xF0, 0xEE,0x00, 0xCA,0xBD, 0x00,0x00, 0x00,0x01, 0x87,0x2E, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39,
-0x00,0x03, 0xC7,0x38, 0x50,0x00, 0x86,0xBA, 0x00,0x04, 0x77,0x39, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xA6,0xAE, 0x68,0x02, 0x77,0x31,
-0x00,0x03, 0xC7,0x38, 0x68,0x00, 0x27,0x38, 0x00,0x08, 0x84,0xBA, 0x00,0x04, 0x84,0x3A,
-0x00,0x00, 0xE0,0x00, 0xCA,0xDC, 0xC5,0x24, 0x00,0x00, 0x87,0x2E, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39,
-0x00,0x03, 0xC7,0x38, 0x50,0x00, 0x85,0x3A, 0x00,0x04, 0x83,0x96, 0x00,0x04, 0x76,0xAD,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x20,0x32, 0x00,0x00, 0x93,0x93, 0xFF,0xFC, 0x87,0x2E,
-0x00,0x00, 0xF6,0x06, 0x3B,0x70, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0x39,
-0x00,0x03, 0xA6,0xBA, 0x60,0x02, 0xC7,0x38, 0x60,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0xEE,0x00, 0xCB,0x29, 0x76,0xB5, 0xFF,0xF0, 0x77,0x21,
-0xFF,0xF0, 0xC6,0xB8, 0x68,0x00, 0xC7,0x2C, 0x68,0x00, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xC1,0x28, 0x00,0x00, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x08, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF5,0x04, 0x4F,0x58, 0xF5,0x82, 0x00,0x02, 0x06,0x28,
-0x00,0x80, 0x20,0x2E, 0x00,0x62, 0xEE,0x00, 0xCB,0x90, 0x07,0x30, 0x00,0x40, 0xF0,0x33,
-0x28,0x00, 0xC6,0xB8, 0x52,0x00, 0x76,0xB4, 0xFF,0xFA, 0x06,0x30, 0x00,0x14, 0xF6,0xB3,
-0x28,0x00, 0xC6,0x38, 0x00,0x00, 0xE0,0x00, 0xCB,0x64, 0x05,0xAC, 0x00,0x01, 0xF7,0x04,
-0x4F,0x58, 0x00,0x00, 0x00,0x01, 0x06,0xB8, 0x18,0xD4, 0xF4,0x82, 0x00,0x01, 0xF4,0xB7,
-0x28,0x00, 0x07,0x38, 0x18,0xC0, 0xF0,0x3B, 0x28,0x00, 0xF7,0x06, 0x42,0xC0, 0xF4,0x82,
-0x00,0x02, 0xF4,0xBB, 0x28,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0xF6,0x84, 0x42,0xC0, 0xF6,0x06, 0x42,0xC0, 0x77,0x31, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0x75,0xB1, 0x00,0x1E, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB4, 0xFF,0xF0, 0xF7,0x04,
-0x4F,0x58, 0x76,0xB5, 0x00,0x06, 0xC4,0x38, 0x68,0x00, 0x87,0x22, 0x00,0x14, 0x76,0xA1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33,
-0x28,0x00, 0xF7,0x04, 0x42,0xC0, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0x20,0x3A, 0x00,0x01, 0xE6,0x00, 0xCC,0x4C, 0xF6,0x06, 0x42,0x90, 0xF7,0x04,
-0x42,0x90, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33, 0x28,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x04, 0x85,0x16, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x95,0x16, 0xFF,0xF4, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xCD,0x00, 0x97,0x93, 0xFF,0xFC, 0x85,0x16, 0xFF,0xF4, 0x20,0x22, 0x00,0x00, 0xE6,0x00,
-0xCC,0xBC, 0xF5,0x86, 0x42,0xC0, 0xF7,0x04, 0x42,0x90, 0xF6,0x06, 0x42,0x92, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xE0,0x00, 0xCC,0xEC, 0xF7,0x33, 0x28,0x00, 0xF0,0x2B, 0x28,0x00, 0xF6,0x84,
-0x42,0xC0, 0x77,0x2D, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0x06,0x28, 0x00,0x14, 0xC6,0xB4,
-0x77,0xC0, 0x76,0xB4, 0xFF,0xF0, 0xF7,0x04, 0x4F,0x58, 0xF6,0xB3, 0x28,0x00, 0xC7,0x28,
-0x72,0x00, 0x77,0x38, 0xFF,0xFA, 0xF7,0x2F, 0x28,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x86,0x96, 0x00,0x00, 0xF7,0x04, 0x4F,0x58, 0xF4,0x02,
-0x00,0x00, 0xC6,0xB4, 0x72,0x00, 0x77,0x34, 0xFF,0xFA, 0x27,0x38, 0x00,0x02, 0x20,0x3A,
-0x00,0x61, 0xF7,0x02, 0x00,0x3F, 0xE2,0x00, 0xCD,0x40, 0xC6,0xB4, 0x74,0x00, 0x20,0x36,
-0x00,0x00, 0xE6,0x00, 0xCD,0x40, 0x00,0x00, 0x00,0x01, 0xF4,0x02, 0x00,0x01, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x86,0x16, 0x00,0x00, 0x87,0x16,
-0x00,0x08, 0x85,0x96, 0x00,0x04, 0xC5,0x30, 0x70,0x00, 0xC0,0x32, 0x52,0x00, 0xE6,0x00,
-0xCD,0xA1, 0x00,0x00, 0x00,0x01, 0x86,0xB2, 0x00,0x00, 0x77,0x31, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xE8, 0xF6,0xAF, 0x68,0x00, 0x06,0x30,
-0x00,0x01, 0xC0,0x32, 0x52,0x00, 0xE6,0x00, 0xCD,0x78, 0x05,0xAC, 0x00,0x01, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x0C, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x84,0x96,
-0x00,0x00, 0x84,0x16, 0x00,0x04, 0x85,0x96, 0x00,0x08, 0x86,0xA6, 0x00,0x00, 0x77,0x25,
-0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x75,0x35, 0xFF,0xF0, 0x20,0x2A,
-0x00,0x10, 0xE2,0x00, 0xCE,0x0D, 0xF6,0x06, 0x42,0x8E, 0xF5,0x02, 0x00,0x10, 0xF7,0x04,
-0x42,0x8C, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33, 0x28,0x00, 0x20,0x2E, 0x00,0x01, 0xE6,0x00,
-0xCE,0x70, 0x20,0x2A, 0x00,0x00, 0xEE,0x00, 0xCE,0x71, 0x07,0x24, 0x00,0x02, 0x25,0x28,
-0x00,0x01, 0xA5,0xBA, 0x50,0x02, 0x86,0x22, 0x00,0x00, 0x76,0xA1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x50,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC5,0xAC,
-0x77,0xC0, 0xC6,0x30, 0x6F,0xC0, 0x76,0x31, 0xFF,0xF0, 0x75,0xAD, 0xFF,0xE8, 0xF6,0x82,
-0x00,0xFF, 0xF7,0x02, 0xF1,0x54, 0x75,0xAD, 0x00,0x02, 0xA7,0x2E, 0x70,0x02, 0xC6,0x30,
-0x6C,0x00, 0xC6,0x30, 0x75,0x80, 0xF6,0x23, 0x28,0x00, 0x24,0x20, 0x00,0x02, 0x25,0xA8,
-0x00,0x01, 0xF3,0x02, 0xF2,0x46, 0x03,0xA4, 0x00,0x02, 0xC4,0xAC, 0x38,0x00, 0x25,0x2C,
-0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xEC,0x00, 0xCF,0x11, 0x00,0x00, 0x00,0x01, 0xE6,0x00,
-0xCE,0xA0, 0xC7,0x1C, 0x50,0x00, 0xE0,0x00, 0xCE,0xB4, 0xF6,0x02, 0x00,0x00, 0xA6,0x9E,
-0x50,0x02, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0x35,
-0xFF,0xE8, 0x86,0xA6, 0x00,0x00, 0x77,0x25, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0x25,0x28,
-0x00,0x02, 0x25,0xAC, 0x00,0x02, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xE8, 0x77,0x31,
-0x00,0x04, 0xC7,0x38, 0x62,0x00, 0x77,0x39, 0x00,0x01, 0xC7,0x38, 0x30,0x00, 0xC6,0xB4,
-0x68,0x00, 0xC6,0xB4, 0x70,0x00, 0x06,0xB4, 0x00,0x0E, 0x87,0x36, 0x00,0x00, 0x24,0xA4,
-0x00,0x02, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0xE0,0x00, 0xCE,0x84, 0x24,0x20, 0x00,0x02, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x0C, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x86,0x16, 0x00,0x08, 0x83,0x16,
-0x00,0x04, 0x83,0x96, 0x00,0x00, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0x05,0x9C, 0x00,0x02, 0x74,0x9D, 0x00,0x1E, 0x74,0xA4, 0xFF,0xE5, 0x74,0x1D,
-0x00,0x1E, 0x06,0x30, 0x00,0x02, 0x75,0x31, 0x00,0x1E, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x1F, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0x28, 0xFF,0xE5, 0xC7,0x38,
-0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x05,0xAC, 0x00,0x02, 0x76,0x31, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x87,0x1E, 0x00,0x00, 0x74,0x20,
-0xFF,0xE5, 0xC7,0x38, 0x4F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x1F,
-0x28,0x00, 0x87,0x1E, 0x00,0x00, 0x04,0x9C, 0x00,0x02, 0xC7,0x38, 0x47,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x25,0x38, 0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xEE,0x00, 0xD0,0xBD, 0x26,0x28,
-0x00,0x01, 0xA7,0x26, 0x60,0x02, 0xC6,0xA4, 0x60,0x00, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC5,0xA4, 0x50,0x00, 0xC5,0x30, 0x00,0x00, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xE8, 0xE0,0x00, 0xD0,0x88, 0xF7,0x2F, 0x68,0x00, 0x07,0x1C, 0x00,0x02, 0xF3,0x3B,
-0x68,0x00, 0xC4,0x1C, 0x00,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x0C, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x86,0x16, 0x00,0x04, 0x84,0x16, 0x00,0x00, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x05,0xA0, 0x00,0x02, 0x74,0xA1, 0x00,0x1E, 0x74,0xA4,
-0xFF,0xE5, 0x06,0x30, 0x00,0x02, 0x75,0x31, 0x00,0x1E, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0x28, 0xFF,0xE5, 0xC7,0x38,
-0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x06,0xA0, 0x00,0x02, 0x76,0x31, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2F, 0x28,0x00, 0x87,0x22,
-0x00,0x00, 0x76,0x21, 0x00,0x1E, 0x85,0x96, 0x00,0x08, 0xC7,0x38, 0x4F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0xC6,0xB4, 0x70,0x00, 0xF5,0xB7, 0x68,0x00, 0x87,0x22, 0x00,0x00, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x23,
-0x28,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x0C, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10,
-0x00,0x20, 0x27,0x14, 0x00,0x20, 0xF0,0x3B, 0x28,0x00, 0x84,0x96, 0x00,0x04, 0xF5,0x02,
-0x00,0x00, 0x86,0xA6, 0x00,0x00, 0x76,0x25, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0x04,0x24,
-0x00,0x02, 0xC6,0xB4, 0x67,0xC0, 0x76,0xB4, 0xFF,0xF0, 0xF6,0xBB, 0x28,0x00, 0x87,0x26,
-0x00,0x00, 0x76,0xA5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0xC0,0x2A, 0x72,0x00, 0xEC,0x00, 0xD2,0xF8, 0x76,0xA5, 0x00,0x1E, 0x87,0x26,
-0x00,0x00, 0x76,0xB4, 0xFF,0xE5, 0x06,0x28, 0x00,0x01, 0x25,0x94, 0x00,0x1E, 0xC5,0xAC,
-0x50,0x00, 0xC5,0x30, 0x00,0x00, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0xC7,0x38,
-0x52,0x00, 0xA6,0xA2, 0x70,0x02, 0xC7,0x20, 0x70,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xE8, 0xC6,0x80, 0x6A,0x00, 0xE0,0x00,
-0xD2,0x90, 0xF6,0xAF, 0x68,0x00, 0x87,0x16, 0xFF,0xE0, 0x76,0x15, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0x83,0x96, 0x00,0x00, 0x23,0x14, 0x00,0x1E, 0x75,0x99, 0x00,0x1E, 0x75,0xAC,
-0xFF,0xE5, 0x75,0x15, 0x00,0x1E, 0x75,0x28, 0xFF,0xE5, 0x74,0x95, 0x00,0x1E, 0x74,0xA4,
-0xFF,0xE5, 0x74,0x15, 0x00,0x1E, 0x74,0x20, 0xFF,0xE5, 0x06,0x9C, 0x00,0x02, 0x73,0x95,
-0x00,0x1E, 0x93,0x96, 0xFF,0xDC, 0xC7,0x38, 0x67,0xC0, 0x83,0x96, 0x00,0x00, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x1F, 0x28,0x00, 0x83,0x96, 0xFF,0xDC, 0x87,0x1A, 0x00,0x00, 0x73,0x9C,
-0xFF,0xE5, 0x93,0x96, 0xFF,0xDC, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16, 0xFF,0xE4, 0x23,0x14, 0x00,0x1A, 0x76,0x19,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16, 0xFF,0xE8, 0x23,0x14,
-0x00,0x16, 0x76,0x19, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4, 0x00,0x02, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16,
-0xFF,0xEC, 0x23,0x14, 0x00,0x12, 0x76,0x19, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38,
-0x47,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4,
-0x00,0x02, 0x84,0x16, 0x00,0x00, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x87,0x16, 0xFF,0xF0, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x3F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x08, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x86,0x16, 0x00,0x00, 0x84,0x16, 0x00,0x04, 0xF6,0x84, 0x4F,0x58, 0x87,0x32,
-0x00,0x14, 0x03,0x30, 0x00,0x14, 0x75,0x19, 0x00,0x1E, 0x75,0x28, 0xFF,0xE5, 0xC3,0xA0,
-0x6A,0x00, 0x73,0x9C, 0xFF,0xFA, 0x04,0xA0, 0x00,0x14, 0x75,0xA5, 0x00,0x1E, 0xC6,0x30,
-0x6A,0x00, 0x76,0x30, 0xFF,0xFA, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0xF3,0x9B, 0x28,0x00, 0x07,0x20, 0x00,0x16, 0xF6,0x3B, 0x28,0x00, 0x87,0x22,
-0x00,0x14, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x77,0x39,
-0x00,0x06, 0xC6,0xB4, 0x70,0x00, 0x06,0xB4, 0x00,0x16, 0xF3,0xB7, 0x28,0x00, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x08, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x86,0x16, 0x00,0x00, 0xF5,0x84,
-0x4F,0x58, 0x05,0x30, 0x00,0x16, 0x87,0x2A, 0x00,0x00, 0x76,0xA9, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x77,0x39, 0x00,0x06, 0xC4,0x2C,
-0x70,0x00, 0xC0,0x22, 0x62,0x00, 0xE6,0x00, 0xD5,0x29, 0x06,0xA0, 0x00,0x16, 0x87,0x36,
-0x00,0x00, 0xC6,0x30, 0x5A,0x00, 0x76,0x30, 0xFF,0xFA, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x77,0x39, 0x00,0x06, 0x76,0xB8,
-0xFF,0xFA, 0xF6,0xAB, 0x28,0x00, 0xC7,0x2C, 0x70,0x00, 0x07,0x38, 0x00,0x14, 0xE0,0x00,
-0xD5,0x2C, 0xF6,0x3B, 0x28,0x00, 0xC4,0x2C, 0x00,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x06, 0x4F,0x84, 0x47,0x38, 0xFF,0xFC, 0xF7,0x05,
-0x6F,0x30, 0xF6,0x86, 0x50,0x5C, 0x46,0xB4, 0xFF,0xFC, 0xF6,0x85, 0x6E,0x50, 0xF7,0x06,
-0x6E,0x7C, 0x47,0x38, 0xFF,0xFC, 0xF7,0x05, 0x6E,0x54, 0x07,0x34, 0x19,0x1C, 0xF7,0x05,
-0x4F,0x5C, 0xF7,0x02, 0x00,0x64, 0x97,0x36, 0x19,0x1C, 0xF7,0x02, 0x00,0x00, 0x97,0x36,
-0x19,0x20, 0x06,0xB4, 0x00,0x1C, 0xF6,0x85, 0x4F,0x58, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x90, 0xF3,0x02, 0xFF,0xFF, 0xF3,0x05,
-0x4F,0x54, 0xF3,0x82, 0x00,0x00, 0x93,0x96, 0xFF,0xAC, 0x23,0x14, 0x00,0x20, 0x93,0x16,
-0xFF,0x9C, 0x23,0x94, 0x00,0x38, 0x93,0x96, 0xFF,0x94, 0x83,0x16, 0xFF,0xAC, 0xF7,0x04,
-0x4F,0x5C, 0xF3,0x82, 0x00,0x0C, 0x93,0x96, 0xFF,0x74, 0x93,0x16, 0xFF,0x8C, 0x87,0x3A,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0x97,0x16, 0xFF,0xA4, 0x83,0x16, 0xFF,0xAC, 0x83,0x96,
-0xFF,0xA4, 0x00,0x00, 0x00,0x01, 0xC0,0x1A, 0x3A,0x00, 0xEC,0x00, 0xDB,0x78, 0xF3,0x02,
-0x04,0xBC, 0xF7,0x04, 0x4F,0x5C, 0x83,0x16, 0xFF,0x74, 0x00,0x00, 0x00,0x01, 0xC7,0x38,
-0x30,0x00, 0x87,0x3A, 0x00,0x08, 0xF6,0x84, 0x4F,0x58, 0x77,0x39, 0x00,0x06, 0xC4,0xB4,
-0x70,0x00, 0x94,0x93, 0xFF,0xFC, 0x94,0x96, 0xFF,0x7C, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xCD,0x00, 0x97,0x93, 0xFF,0xFC, 0x84,0x96, 0xFF,0x7C, 0x20,0x22, 0x00,0x00, 0xE6,0x00,
-0xD6,0x54, 0xC5,0x04, 0x00,0x00, 0xF7,0x04, 0x42,0x88, 0xE0,0x00, 0xD8,0x7C, 0xF6,0x06,
-0x42,0x88, 0xF6,0x04, 0x4F,0x5C, 0x83,0x96, 0x00,0x00, 0x83,0x16, 0xFF,0x74, 0x86,0x9E,
-0x00,0x00, 0xA7,0x32, 0x30,0x02, 0xF5,0x82, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0xD6,0x94, 0xC6,0x30, 0x30,0x00, 0x86,0x9E, 0x00,0x04, 0x87,0x32, 0x00,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0xD6,0x98, 0x20,0x2E, 0x00,0x00, 0xF5,0x82,
-0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0xD6,0xA5, 0x00,0x00, 0x00,0x01, 0xF5,0x02,
-0x00,0x00, 0x83,0x96, 0x00,0x00, 0x87,0x32, 0x00,0x00, 0x86,0x9E, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0xD6,0xE4, 0xF5,0x82, 0x00,0x00, 0xC0,0x36,
-0x72,0x00, 0xE6,0x00, 0xD6,0xEC, 0x20,0x2E, 0x00,0x00, 0x86,0x9E, 0x00,0x04, 0x87,0x32,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0xD6,0xED, 0x20,0x2E,
-0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0xD6,0xFD, 0x20,0x2A,
-0x00,0x00, 0xF5,0x02, 0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x00, 0xD7,0x28, 0x04,0xA4,
-0x00,0x02, 0x83,0x16, 0xFF,0xAC, 0xF7,0x06, 0x42,0xC8, 0x83,0x96, 0xFF,0x8C, 0xF3,0x05,
-0x4F,0x54, 0xC7,0x1C, 0x70,0x00, 0xF0,0x3B, 0x28,0x00, 0x07,0x38, 0x00,0x02, 0xE0,0x00,
-0xDB,0x50, 0xF0,0x3B, 0x28,0x00, 0x94,0x96, 0xFF,0x6C, 0x87,0x26, 0x00,0x00, 0x76,0xA5,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x83,0x16, 0xFF,0x6C, 0x83,0x96, 0xFF,0x9C, 0x24,0x94,
-0x00,0x1E, 0x06,0x18, 0x00,0x02, 0x75,0xB1, 0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1F, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0x1D,
-0x00,0x1E, 0x75,0x28, 0xFF,0xE5, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x24,0x94, 0x00,0x1C, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x24,0x94, 0x00,0x1A, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x24,0x94, 0x00,0x18, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x24,0x94, 0x00,0x16, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x24,0x94, 0x00,0x14, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x24,0x94, 0x00,0x12, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x24,0x94, 0x00,0x10, 0x76,0x31,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x87,0x16, 0xFF,0xE0, 0xF6,0x82, 0xFF,0xFC, 0xC7,0x38, 0x57,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x07,0x38, 0x00,0x03, 0xC4,0xB8, 0x6C,0x00, 0x20,0x26, 0x00,0x10, 0xE2,0x00,
-0xD8,0x9D, 0xF6,0x06, 0x42,0x8A, 0xF7,0x04, 0x42,0x88, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xF4,0x02, 0x00,0x00, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xE0,0x00, 0xDB,0xA0, 0xF7,0x33, 0x28,0x00, 0x83,0x16, 0xFF,0x6C, 0x25,0x14,
-0x00,0x36, 0x83,0x96, 0xFF,0x94, 0x87,0x1A, 0x00,0x00, 0x76,0x99, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0x06,0x18, 0x00,0x02, 0x75,0xB1, 0x00,0x1E, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x1F, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38,
-0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x34, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x32, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x30, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x2E, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x2C, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x2A, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x28, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x26,0xA4, 0x00,0x02, 0x74,0xA4, 0xFF,0xFF, 0x76,0x31,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B,
-0x28,0x00, 0x90,0x13, 0xFF,0xFC, 0x83,0x16, 0xFF,0x8C, 0xF7,0x06, 0x42,0xCC, 0xC7,0x18,
-0x70,0x00, 0xC7,0x38, 0x68,0x00, 0x97,0x13, 0xFF,0xFC, 0x93,0x93, 0xFF,0xFC, 0x94,0x96,
-0xFF,0x7C, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCD,0xB8, 0x97,0x93, 0xFF,0xFC, 0x83,0x96,
-0xFF,0x6C, 0x24,0x14, 0x00,0x4E, 0x25,0x14, 0x00,0x50, 0x83,0x16, 0xFF,0x8C, 0x84,0x96,
-0xFF,0x7C, 0x87,0x1E, 0x00,0x00, 0x76,0x9D, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x06,0x1C,
-0x00,0x02, 0x75,0xB1, 0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0x29, 0x00,0x1E, 0x75,0x28,
-0xFF,0xE5, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x24,0x14,
-0x00,0x4C, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x24,0x14,
-0x00,0x4A, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x24,0x14,
-0x00,0x48, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x24,0x14,
-0x00,0x46, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x24,0x14,
-0x00,0x44, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x24,0x14,
-0x00,0x42, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x24,0x14, 0x00,0x40, 0x76,0x31, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x86,0x96,
-0xFF,0xB0, 0xF6,0x06, 0x42,0xC8, 0xC6,0x18, 0x60,0x00, 0xF7,0x02, 0x00,0x03, 0xC6,0xB4,
-0x57,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xC6,0xB4, 0x74,0x00, 0xF7,0x02, 0x00,0x04, 0xC7,0x38,
-0x6A,0x00, 0xF7,0x33, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0xF4,0xB3, 0x28,0x00, 0x83,0x96,
-0xFF,0x8C, 0x83,0x16, 0xFF,0x74, 0x03,0x9C, 0x00,0x14, 0x93,0x96, 0xFF,0x8C, 0x03,0x18,
-0x00,0x0C, 0x83,0x96, 0xFF,0xAC, 0x93,0x16, 0xFF,0x74, 0x03,0x9C, 0x00,0x01, 0xE0,0x00,
-0xD5,0xEC, 0x93,0x96, 0xFF,0xAC, 0x93,0x13, 0xFF,0xFC, 0xF3,0x84, 0x4F,0x5C, 0x00,0x00,
-0x00,0x01, 0x93,0x93, 0xFF,0xFC, 0xF3,0x06, 0x4A,0x98, 0x93,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x26,0xF8, 0x97,0x93, 0xFF,0xFC, 0xF4,0x02, 0x00,0x01, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x01,0xA0, 0xF5,0x02,
-0x00,0x00, 0xF3,0x84, 0x6E,0x50, 0xF6,0x02, 0x00,0x1C, 0x20,0x2A, 0x00,0x63, 0xEE,0x00,
-0xDC,0x08, 0xC5,0x9C, 0x60,0x00, 0xA6,0x9E, 0x60,0x02, 0x77,0x2D, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0x20,0x36, 0x00,0x03, 0xE6,0x00,
-0xDB,0xFC, 0x07,0x2C, 0x00,0x36, 0xF0,0x3B, 0x28,0x00, 0x06,0x30, 0x00,0x40, 0xE0,0x00,
-0xDB,0xCC, 0x05,0x28, 0x00,0x01, 0xF5,0x84, 0x4F,0x5C, 0x00,0x00, 0x00,0x01, 0x86,0xAE,
-0x00,0x08, 0xF4,0x02, 0x00,0x00, 0x87,0x2E, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xEC,0x00, 0xDC,0xF0, 0x96,0x96, 0xFF,0xEC, 0x77,0x35, 0x00,0x01, 0xC7,0x38,
-0x68,0x00, 0x77,0x39, 0x00,0x02, 0xC6,0x38, 0x58,0x00, 0x06,0x30, 0x00,0x0C, 0xC3,0x84,
-0x00,0x00, 0x83,0x16, 0x00,0x00, 0x86,0xB2, 0x00,0x00, 0x87,0x1A, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0xDC,0x7C, 0xC5,0x20, 0x00,0x00, 0x86,0xB2,
-0x00,0x04, 0x87,0x1A, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0xDC,0x80, 0x20,0x2A, 0x00,0x00, 0xF5,0x02, 0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x00,
-0xDC,0x8D, 0x00,0x00, 0x00,0x01, 0xF3,0x82, 0x00,0x00, 0x84,0x96, 0x00,0x00, 0x86,0xB2,
-0x00,0x00, 0x87,0x26, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00,
-0xDC,0xCC, 0xF5,0x02, 0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0xDC,0xD4, 0x20,0x2A,
-0x00,0x00, 0x86,0xB2, 0x00,0x04, 0x87,0x26, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE2,0x00, 0xDC,0xD5, 0x20,0x2A, 0x00,0x00, 0xF5,0x02, 0x00,0x01, 0x20,0x2A,
-0x00,0x00, 0xE6,0x00, 0xDC,0xE5, 0x20,0x1E, 0x00,0x00, 0xF3,0x82, 0x00,0x01, 0x20,0x1E,
-0x00,0x00, 0xE6,0x00, 0xDC,0xF4, 0x20,0x22, 0x00,0x00, 0xF4,0x02, 0x00,0x01, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0xDD,0x29, 0xF6,0x02, 0x00,0x01, 0x87,0x16, 0xFF,0xEC, 0x00,0x00,
-0x00,0x01, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4,
-0x58,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16, 0xFF,0xF0, 0xE0,0x00,
-0xDD,0x98, 0x96,0x96, 0xFF,0xF4, 0x27,0x14, 0x00,0x14, 0x97,0x13, 0xFF,0xFC, 0x83,0x16,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0x95,0x93, 0xFF,0xFC, 0x95,0x96,
-0xFE,0x70, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x25,0x68, 0x97,0x93, 0xFF,0xFC, 0x85,0x96,
-0xFE,0x70, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0xDD,0x95, 0xF6,0x02, 0x00,0x01, 0x87,0x16,
-0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5,
-0x00,0x02, 0xC6,0xB4, 0x58,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16,
-0xFF,0xF0, 0x96,0x96, 0xFF,0xF4, 0x97,0x2E, 0x00,0x08, 0xE0,0x00, 0xDD,0x9C, 0x20,0x32,
-0x00,0x00, 0xF6,0x02, 0x00,0x00, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0xDD,0xB0, 0xF4,0x82,
-0x00,0x00, 0xF7,0x04, 0x42,0x7C, 0xE0,0x00, 0xE0,0x9C, 0xF6,0x06, 0x42,0x7E, 0x94,0x96,
-0xFF,0x44, 0x87,0x16, 0xFF,0xF4, 0xF6,0x04, 0x4F,0x58, 0x77,0x39, 0x00,0x06, 0xC7,0x30,
-0x70,0x00, 0x97,0x16, 0xFF,0x54, 0x06,0xB8, 0x00,0x1A, 0x87,0x36, 0x00,0x00, 0x83,0x16,
-0xFF,0x54, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x93,0x13,
-0xFF,0xFC, 0x77,0x38, 0xFF,0xF0, 0x77,0x39, 0x00,0x06, 0xC6,0x30, 0x70,0x00, 0x96,0x16,
-0xFF,0x4C, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCD,0x00, 0x97,0x93, 0xFF,0xFC, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0xDE,0x35, 0xF3,0x02, 0x00,0x01, 0x84,0x96, 0xFF,0x4C, 0x00,0x00,
-0x00,0x01, 0x94,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCD,0x00, 0x97,0x93,
-0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0xDE,0x38, 0x00,0x00, 0x00,0x01, 0xF3,0x02,
-0x00,0x01, 0x93,0x16, 0xFF,0x44, 0x84,0x96, 0xFF,0x44, 0x00,0x00, 0x00,0x01, 0x20,0x26,
-0x00,0x00, 0xE6,0x00, 0xDE,0x59, 0xF6,0x06, 0x42,0xA4, 0xF7,0x04, 0x42,0xA4, 0xE0,0x00,
-0xE0,0xA0, 0x76,0xB1, 0x00,0x1E, 0x83,0x16, 0xFF,0x4C, 0x86,0x16, 0xFF,0x4C, 0x87,0x1A,
-0x00,0x00, 0x76,0x99, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x20,0x3A, 0x00,0x02, 0xE6,0x00, 0xDE,0x85, 0x00,0x00, 0x00,0x01, 0xF6,0x04,
-0x4F,0x58, 0xF5,0x84, 0x4F,0x58, 0x00,0x00, 0x00,0x01, 0xC0,0x32, 0x5A,0x00, 0xE6,0x00,
-0xE0,0x25, 0x00,0x00, 0x00,0x01, 0x84,0x96, 0xFF,0x4C, 0x00,0x00, 0x00,0x01, 0x06,0xA4,
-0x00,0x1A, 0x87,0x36, 0x00,0x00, 0x83,0x16, 0xFF,0x54, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x77,0x39, 0x00,0x06, 0xC7,0x2C,
-0x70,0x00, 0xC0,0x3A, 0x32,0x00, 0xE6,0x00, 0xDE,0xDD, 0xF6,0x06, 0x42,0x80, 0xF7,0x04,
-0x42,0x80, 0xE0,0x00, 0xE0,0xA0, 0x76,0xB1, 0x00,0x1E, 0x26,0x14, 0x00,0x30, 0xF0,0x33,
-0x28,0x00, 0x87,0x16, 0xFF,0xD0, 0x76,0x31, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0x84,0x96,
-0xFF,0x4C, 0x23,0x14, 0x00,0x2E, 0x93,0x16, 0xFE,0x64, 0x75,0x99, 0x00,0x1E, 0x75,0xAC,
-0xFF,0xE5, 0x75,0x15, 0x00,0x1E, 0x75,0x28, 0xFF,0xE5, 0x73,0x15, 0x00,0x1E, 0x73,0x18,
-0xFF,0xE5, 0x93,0x16, 0xFF,0x34, 0x83,0x16, 0xFE,0x64, 0x04,0x24, 0x00,0x02, 0x06,0xA0,
-0x00,0x02, 0x74,0x95, 0x00,0x1E, 0x74,0xA4, 0xFF,0xE5, 0x94,0x96, 0xFF,0x3C, 0x74,0x95,
-0x00,0x1E, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x87,0x1A,
-0x00,0x00, 0x74,0xA4, 0xFF,0xE5, 0x94,0x96, 0xFF,0x2C, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16, 0xFF,0xD4, 0x24,0x94,
-0x00,0x2A, 0x94,0x96, 0xFE,0x64, 0x76,0x25, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38,
-0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x26, 0x00,0x00, 0x06,0xB4,
-0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4,
-0x00,0x02, 0x87,0x16, 0xFF,0xD8, 0x23,0x14, 0x00,0x26, 0x93,0x16, 0xFE,0x64, 0x76,0x19,
-0x00,0x1E, 0x84,0x96, 0xFF,0x3C, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4, 0x00,0x02, 0x84,0x96,
-0xFF,0x34, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4,
-0x00,0x02, 0x87,0x16, 0xFF,0xDC, 0x23,0x14, 0x00,0x22, 0x93,0x16, 0xFE,0x64, 0x76,0x19,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x16, 0xFF,0xE0, 0x83,0x16, 0xFF,0x2C, 0x06,0xB4,
-0x00,0x02, 0xC7,0x38, 0x37,0xC0, 0x77,0x38, 0xFF,0xF0, 0xE0,0x00, 0xEA,0xA0, 0xF7,0x37,
-0x28,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCB,0xCC, 0x97,0x93, 0xFF,0xFC, 0x06,0xA0,
-0x00,0x02, 0xF7,0x04, 0x4F,0x58, 0xF0,0x37, 0x28,0x00, 0x06,0xA0, 0x00,0x14, 0x94,0x16,
-0xFF,0x24, 0xC7,0x20, 0x72,0x00, 0x77,0x38, 0xFF,0xFA, 0xF7,0x37, 0x28,0x00, 0x06,0xA0,
-0x00,0x16, 0xF7,0x37, 0x28,0x00, 0xF4,0x82, 0x00,0x01, 0xF4,0xA3, 0x28,0x00, 0x94,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCD,0x00, 0x97,0x93, 0xFF,0xFC, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0xE0,0xBC, 0x26,0x94, 0x00,0x48, 0xF7,0x04, 0x42,0x80, 0xE0,0x00,
-0xE0,0x9C, 0xF6,0x06, 0x42,0x82, 0x86,0x96, 0xFE,0xF4, 0xE0,0x00, 0xE2,0x94, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x42,0x84, 0xF6,0x06, 0x42,0x84, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xF4,0x02, 0x00,0x00, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xE0,0x00, 0xEA,0xA4, 0xF7,0x33, 0x28,0x00, 0x83,0x16, 0xFF,0x4C, 0x75,0x15,
-0x00,0x1E, 0x75,0x28, 0xFF,0xE5, 0x93,0x16, 0xFF,0x1C, 0x07,0x18, 0x00,0x36, 0xF4,0x82,
-0x00,0x01, 0xF4,0xBB, 0x28,0x00, 0xF0,0x37, 0x28,0x00, 0x87,0x16, 0xFF,0xB8, 0x76,0xB5,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x04,0x18, 0x00,0x02, 0x06,0x20, 0x00,0x02, 0x23,0x14,
-0x00,0x46, 0x93,0x16, 0xFF,0x14, 0x75,0x99, 0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0x74,0x95,
-0x00,0x1E, 0x74,0xA4, 0xFF,0xE5, 0x94,0x96, 0xFF,0x0C, 0x73,0x15, 0x00,0x1E, 0x73,0x18,
-0xFF,0xE5, 0x93,0x16, 0xFF,0x04, 0x74,0x95, 0x00,0x1E, 0x74,0xA4, 0xFF,0xE5, 0x94,0x96,
-0xFE,0xFC, 0x23,0x00, 0x00,0x07, 0x93,0x16, 0xFE,0xF4, 0x84,0x96, 0xFF,0x1C, 0x83,0x16,
-0xFF,0x14, 0x04,0xA4, 0x00,0x0A, 0x94,0x96, 0xFE,0x7C, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0xF6,0x84, 0x4F,0x58, 0x84,0x96, 0xFF,0x54, 0x87,0x1A,
-0x00,0x00, 0xC6,0xA4, 0x6A,0x00, 0x74,0x34, 0xFF,0xFA, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x16, 0xFF,0xBC, 0x23,0x14,
-0x00,0x42, 0x93,0x16, 0xFF,0x14, 0x76,0x99, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0x30,
-0x00,0x02, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x06,0x30,
-0x00,0x02, 0x87,0x16, 0xFF,0xC0, 0x24,0x94, 0x00,0x3E, 0x94,0x96, 0xFF,0x14, 0x76,0xA5,
-0x00,0x1E, 0x83,0x16, 0xFF,0x0C, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x37,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x87,0x26, 0x00,0x00, 0x06,0x30, 0x00,0x02, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x16,
-0xFF,0xC4, 0x24,0x94, 0x00,0x3A, 0x94,0x96, 0xFF,0x14, 0x76,0xA5, 0x00,0x1E, 0x83,0x16,
-0xFF,0x04, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x37,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33,
-0x28,0x00, 0x87,0x26, 0x00,0x00, 0x06,0x30, 0x00,0x02, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x87,0x16, 0xFF,0xC8, 0x84,0x96, 0xFE,0xFC, 0x06,0x30,
-0x00,0x02, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x83,0x16,
-0xFE,0xF4, 0x00,0x00, 0x00,0x01, 0x20,0x1A, 0x00,0x07, 0xEE,0x00, 0xE2,0x94, 0xF6,0x82,
-0x00,0x08, 0x84,0x96, 0xFE,0x7C, 0x00,0x00, 0x00,0x01, 0x07,0x24, 0x00,0x0E, 0x86,0xBA,
-0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5,
-0xFF,0xF0, 0xF7,0x02, 0x00,0xFF, 0xC6,0xB4, 0x74,0x00, 0x47,0x21, 0x00,0x00, 0xC0,0x36,
-0x72,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0xE0,0x88, 0x04,0xA4,
-0x00,0x02, 0x94,0x96, 0xFE,0x7C, 0x03,0x18, 0x00,0x01, 0xE0,0x00, 0xE2,0x30, 0x93,0x16,
-0xFE,0xF4, 0x83,0x16, 0xFF,0x1C, 0x00,0x00, 0x00,0x01, 0x07,0x18, 0x00,0x38, 0xF6,0xBB,
-0x28,0x00, 0x93,0x13, 0xFF,0xFC, 0x84,0x96, 0xFF,0x24, 0x00,0x00, 0x00,0x01, 0x94,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xD4,0x2C, 0x97,0x93, 0xFF,0xFC, 0x23,0x14,
-0x00,0x78, 0x93,0x16, 0xFE,0xBC, 0x84,0x96, 0x00,0x00, 0x23,0x14, 0x00,0xA8, 0x86,0xA6,
-0x00,0x04, 0x87,0x26, 0x00,0x00, 0x93,0x16, 0xFE,0x9C, 0xC6,0xB4, 0x70,0x00, 0x96,0x96,
-0xFE,0xEC, 0xF7,0x02, 0x00,0x01, 0xC7,0x34, 0x74,0x00, 0x97,0x16, 0xFE,0xE4, 0x84,0x96,
-0xFF,0x24, 0x00,0x00, 0x00,0x01, 0x94,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xD4,0xB4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x04, 0x4F,0x58, 0x00,0x00, 0x00,0x01, 0xC0,0x22,
-0x72,0x00, 0xE6,0x00, 0xEA,0xA1, 0x94,0x16, 0xFF,0x1C, 0x86,0xA2, 0x00,0x38, 0x77,0x21,
-0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xF3,0x02, 0x00,0x00, 0x93,0x16, 0xFE,0xD4, 0xC6,0xB4,
-0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0x96,0x96, 0xFE,0xDC, 0x84,0x96, 0xFE,0xD4, 0x00,0x00,
-0x00,0x01, 0x20,0x26, 0x00,0x0E, 0xEE,0x00, 0xE2,0xF0, 0xF3,0x02, 0x00,0x0F, 0x93,0x13,
-0xFF,0xFC, 0x83,0x16, 0xFE,0xEC, 0x00,0x00, 0x00,0x01, 0xC7,0x18, 0x48,0x00, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x27,0xE8, 0x97,0x93, 0xFF,0xFC, 0xC3,0xA0,
-0x00,0x00, 0x84,0x96, 0xFE,0xE4, 0x00,0x00, 0x00,0x01, 0x20,0x26, 0x00,0x00, 0xE6,0x00,
-0xE3,0x8D, 0x23,0x9C, 0x00,0x07, 0xC3,0x80, 0x3A,0x00, 0xC7,0x1C, 0x38,0x00, 0x83,0x16,
-0xFF,0x1C, 0xF4,0x82, 0x00,0xFF, 0xF6,0x04, 0x4F,0x58, 0xC7,0x18, 0x70,0x00, 0x07,0x38,
-0x00,0x26, 0x86,0xBA, 0x00,0x00, 0x97,0x16, 0xFE,0xC4, 0x77,0x39, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xC6,0xB4, 0x4C,0x00, 0x76,0xB5,
-0x00,0x06, 0xC3,0x30, 0x68,0x00, 0x07,0x30, 0x00,0x40, 0xC0,0x1A, 0x72,0x00, 0xE6,0x00,
-0xE4,0x0D, 0x93,0x16, 0xFE,0xCC, 0x93,0x13, 0xFF,0xFC, 0x93,0x96, 0xFE,0x74, 0x96,0x16,
-0xFE,0x6C, 0x96,0x96, 0xFE,0x68, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCD,0x00, 0x97,0x93,
-0xFF,0xFC, 0x83,0x96, 0xFE,0x74, 0x86,0x16, 0xFE,0x6C, 0x86,0x96, 0xFE,0x68, 0x20,0x22,
-0x00,0x00, 0xE6,0x00, 0xE0,0x95, 0x00,0x00, 0x00,0x01, 0xF5,0x84, 0x4F,0x58, 0x84,0x96,
-0xFE,0xCC, 0x07,0x2C, 0x00,0x40, 0xC0,0x26, 0x72,0x00, 0xE6,0x00, 0xEA,0x8D, 0x00,0x00,
-0x00,0x01, 0xA7,0x32, 0x68,0x02, 0x76,0xA5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x86,0x16,
-0xFE,0xCC, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x20,0x3A, 0x00,0x02, 0xE6,0x00,
-0xE4,0x51, 0xC0,0x32, 0x5A,0x00, 0xC6,0x2C, 0x00,0x00, 0xC0,0x32, 0x5A,0x00, 0xE6,0x00,
-0xE6,0xE5, 0x25,0x14, 0x00,0x76, 0x83,0x16, 0xFF,0x1C, 0x84,0x96, 0xFE,0xBC, 0x06,0x18,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x83,0x16,
-0xFE,0xDC, 0x06,0x30, 0x00,0x02, 0x75,0xB1, 0x00,0x1E, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38,
-0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x74, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x72, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x70, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x6E, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x6C, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x6A, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x25,0x14, 0x00,0x68, 0x76,0x31, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0xC7,0x1C, 0x32,0x00, 0x97,0x13,
-0xFF,0xFC, 0x94,0x93, 0xFF,0xFC, 0x26,0x14, 0x00,0x60, 0x96,0x13, 0xFF,0xFC, 0x96,0x16,
-0xFE,0x6C, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xD0,0xDC, 0x97,0x93, 0xFF,0xFC, 0x87,0x16,
-0xFF,0xA0, 0x86,0x16, 0xFE,0x6C, 0x84,0x96, 0xFE,0xCC, 0x23,0x14, 0x00,0x5E, 0x93,0x16,
-0xFE,0x5C, 0x75,0x99, 0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0x74,0x15, 0x00,0x1E, 0x74,0x20,
-0xFF,0xE5, 0x73,0x15, 0x00,0x1E, 0x73,0x18, 0xFF,0xE5, 0x93,0x16, 0xFE,0xAC, 0x83,0x16,
-0xFE,0x5C, 0x76,0x31, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0x05,0x24, 0x00,0x02, 0x06,0xA8,
-0x00,0x02, 0x74,0x95, 0x00,0x1E, 0x74,0xA4, 0xFF,0xE5, 0x94,0x96, 0xFE,0xB4, 0x74,0x95,
-0x00,0x1E, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x87,0x1A,
-0x00,0x00, 0x74,0xA4, 0xFF,0xE5, 0x94,0x96, 0xFE,0xA4, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16, 0xFF,0xA4, 0x24,0x94,
-0x00,0x5A, 0x94,0x96, 0xFE,0x5C, 0x76,0x25, 0x00,0x1E, 0x83,0x16, 0xFE,0xB4, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x37,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x26,
-0x00,0x00, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16, 0xFF,0xA8, 0x24,0x94, 0x00,0x56, 0x94,0x96,
-0xFE,0x5C, 0x76,0x25, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x47,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x26, 0x00,0x00, 0x06,0xB4, 0x00,0x02, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16,
-0xFF,0xAC, 0x23,0x14, 0x00,0x52, 0x93,0x16, 0xFE,0x5C, 0x76,0x19, 0x00,0x1E, 0x84,0x96,
-0xFE,0xAC, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x87,0x1A, 0x00,0x00, 0x06,0xB4, 0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x16, 0xFF,0xB0, 0x83,0x16, 0xFE,0xA4, 0x06,0xB4,
-0x00,0x02, 0xC7,0x38, 0x37,0xC0, 0x77,0x38, 0xFF,0xF0, 0xE0,0x00, 0xEA,0x8C, 0xF7,0x37,
-0x28,0x00, 0x84,0x96, 0xFE,0xCC, 0x00,0x00, 0x00,0x01, 0x04,0xA4, 0x00,0x36, 0x94,0x96,
-0xFE,0x5C, 0x87,0x26, 0x00,0x00, 0x76,0xA5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x20,0x3A, 0x00,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0xEA,0x8D, 0x00,0x00, 0x00,0x01, 0x83,0x16, 0xFE,0xCC, 0x84,0x96,
-0xFF,0x1C, 0x06,0x18, 0x00,0x3A, 0x85,0xB2, 0x00,0x00, 0x07,0x24, 0x00,0x3A, 0x86,0xBA,
-0x00,0x00, 0x76,0x31, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0x77,0x39, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC5,0xAC, 0x67,0xC0, 0xC6,0xB4, 0x77,0xC0, 0x75,0xAD, 0xFF,0xF0, 0x76,0xB5,
-0xFF,0xF0, 0xC0,0x2E, 0x6A,0x00, 0xEC,0x00, 0xE7,0x64, 0xF5,0x02, 0x00,0x02, 0xF5,0x02,
-0x00,0x01, 0x83,0x16, 0xFF,0x1C, 0x00,0x00, 0x00,0x01, 0x07,0x18, 0x00,0x36, 0x86,0xBA,
-0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5,
-0xFF,0xF0, 0x20,0x36, 0x00,0x02, 0xE6,0x00, 0xE7,0x9C, 0x00,0x00, 0x00,0x01, 0x20,0x2A,
-0x00,0x01, 0xE6,0x00, 0xEA,0x8D, 0x00,0x00, 0x00,0x01, 0x84,0x96, 0xFE,0x5C, 0x83,0x16,
-0xFF,0x1C, 0xF5,0x27, 0x28,0x00, 0x06,0x18, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x25,0x14, 0x00,0xA6, 0x84,0x96, 0xFE,0x9C, 0x83,0x16,
-0xFE,0xDC, 0x06,0x30, 0x00,0x02, 0x75,0xB1, 0x00,0x1E, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38,
-0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0xA4, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0xA2, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0xA0, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x9E, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x9C, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x25,0x14, 0x00,0x9A, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x32,
-0x00,0x00, 0x25,0x14, 0x00,0x98, 0x76,0x31, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B, 0x28,0x00, 0xC7,0x1C, 0x32,0x00, 0x97,0x13,
-0xFF,0xFC, 0x94,0x93, 0xFF,0xFC, 0x26,0x14, 0x00,0x90, 0x96,0x13, 0xFF,0xFC, 0x96,0x16,
-0xFE,0x6C, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xD0,0xDC, 0x97,0x93, 0xFF,0xFC, 0x87,0x16,
-0xFF,0x70, 0x86,0x16, 0xFE,0x6C, 0x84,0x96, 0xFE,0xCC, 0x23,0x94, 0x00,0x8E, 0x75,0x9D,
-0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0x73,0x15, 0x00,0x1E, 0x73,0x18, 0xFF,0xE5, 0x93,0x16,
-0xFE,0x94, 0x74,0x15, 0x00,0x1E, 0x74,0x20, 0xFF,0xE5, 0x73,0x15, 0x00,0x1E, 0x73,0x18,
-0xFF,0xE5, 0x93,0x16, 0xFE,0x84, 0x83,0x16, 0xFE,0x94, 0x76,0x31, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0x05,0x24, 0x00,0x02, 0x06,0xA8, 0x00,0x02, 0x74,0x95, 0x00,0x1E, 0x74,0xA4,
-0xFF,0xE5, 0x94,0x96, 0xFE,0x8C, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x2B,
-0x28,0x00, 0x84,0x96, 0xFE,0xC4, 0x87,0x1E, 0x00,0x00, 0x75,0x25, 0x00,0x1E, 0xC7,0x38,
-0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16,
-0xFF,0x74, 0x23,0x94, 0x00,0x8A, 0x76,0x1D, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0x84,0x96,
-0xFE,0x8C, 0x75,0x28, 0xFF,0xE5, 0xC7,0x38, 0x37,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37,
-0x28,0x00, 0x87,0x1E, 0x00,0x00, 0x06,0xB4, 0x00,0x02, 0x83,0x16, 0xFE,0x84, 0xC7,0x38,
-0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4, 0x00,0x02, 0x87,0x16,
-0xFF,0x78, 0x23,0x94, 0x00,0x86, 0x76,0x1D, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38,
-0x47,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1E, 0x00,0x00, 0x06,0xB4,
-0x00,0x02, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x06,0xB4,
-0x00,0x02, 0x87,0x16, 0xFF,0x7C, 0x23,0x94, 0x00,0x82, 0x76,0x1D, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x4F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1E,
-0x00,0x00, 0x06,0xB4, 0x00,0x02, 0x84,0x96, 0xFE,0xC4, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x16, 0xFF,0x80, 0x06,0xB4, 0x00,0x02, 0xC7,0x38,
-0x37,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x26, 0x00,0x00, 0xF3,0x02,
-0x00,0xFF, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xE8, 0xC6,0xB8, 0x34,0x00, 0xF7,0x02,
-0x00,0x80, 0xC7,0x34, 0x74,0x00, 0x77,0x39, 0x00,0x10, 0x77,0x39, 0xFF,0xF0, 0x20,0x3A,
-0x00,0x00, 0xE6,0x00, 0xEA,0x61, 0x27,0x00, 0x01,0x00, 0xC6,0xB4, 0x75,0x80, 0x84,0x96,
-0xFE,0xCC, 0x00,0x00, 0x00,0x01, 0x07,0x24, 0x00,0x38, 0xF6,0xBB, 0x28,0x00, 0x94,0x93,
-0xFF,0xFC, 0x83,0x16, 0xFF,0x24, 0x00,0x00, 0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xD4,0x2C, 0x97,0x93, 0xFF,0xFC, 0x84,0x96, 0xFE,0xD4, 0x00,0x00,
-0x00,0x01, 0x04,0xA4, 0x00,0x01, 0xE0,0x00, 0xE3,0x3C, 0x94,0x96, 0xFE,0xD4, 0xF4,0x02,
-0x00,0x01, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x86,0x16,
-0x00,0x08, 0x86,0x96, 0x00,0x0C, 0xF5,0x02, 0xFF,0xFC, 0x85,0x96, 0x00,0x04, 0x84,0x16,
-0x00,0x10, 0xF4,0x84, 0xE0,0x00, 0x07,0x30, 0x00,0x02, 0x94,0xB2, 0x00,0x10, 0xF4,0x84,
-0xE0,0x04, 0x06,0xB4, 0x00,0x03, 0x94,0xB2, 0x00,0x14, 0xF4,0x84, 0xE0,0x1C, 0xC6,0xB4,
-0x54,0x00, 0x94,0xB2, 0x00,0x18, 0xF4,0x82, 0x00,0x05, 0xF4,0xB3, 0x28,0x00, 0xF4,0x82,
-0x00,0x01, 0xF4,0xBB, 0x28,0x00, 0x27,0x34, 0x00,0x08, 0x97,0x32, 0x00,0x04, 0x86,0x16,
-0x00,0x00, 0x07,0x2C, 0x00,0x03, 0xC7,0x38, 0x54,0x00, 0xC6,0xB8, 0x68,0x00, 0x96,0x93,
-0xFF,0xFC, 0xC6,0x30, 0x72,0x00, 0x96,0x13, 0xFF,0xFC, 0xF7,0x02, 0x00,0x03, 0xC5,0xAC,
-0x74,0x00, 0xF7,0x02, 0x00,0x04, 0xC7,0x38, 0x5A,0x00, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xC1,0x20, 0x00,0x00, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x14, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x18, 0x87,0x16, 0x00,0x04, 0x00,0x00,
-0x00,0x01, 0x83,0xBA, 0x00,0x00, 0x84,0x96, 0x00,0x00, 0x93,0x96, 0xFF,0xF0, 0xF3,0x84,
-0x6E,0x54, 0x87,0x3A, 0x00,0x04, 0x93,0x96, 0xFF,0xEC, 0x97,0x16, 0xFF,0xF4, 0x90,0x13,
-0xFF,0xFC, 0x27,0x1C, 0x00,0x02, 0x97,0x13, 0xFF,0xFC, 0x07,0x24, 0x00,0x20, 0x97,0x13,
-0xFF,0xFC, 0x94,0x96, 0xFF,0xE4, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCD,0xB8, 0x97,0x93,
-0xFF,0xFC, 0x84,0x96, 0xFF,0xE4, 0x83,0x96, 0x00,0x08, 0x87,0x26, 0x00,0x18, 0x85,0x16,
-0xFF,0xEC, 0xC0,0x3A, 0x3A,0x00, 0xEE,0x00, 0xEC,0x7C, 0xF5,0x82, 0x00,0x01, 0x87,0x26,
-0x00,0x18, 0x83,0x96, 0x00,0x08, 0x00,0x00, 0x00,0x01, 0xC0,0x1E, 0x72,0x00, 0xE6,0x00,
-0xEC,0x7C, 0xC5,0x84, 0x00,0x00, 0x86,0xA6, 0x00,0x10, 0x87,0x16, 0xFF,0xF0, 0xF6,0x02,
-0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0xEC,0x1C, 0x04,0x24, 0x00,0x10, 0x86,0xA6,
-0x00,0x14, 0x87,0x16, 0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x00,
-0xEC,0x20, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0xEC,0x2D, 0x00,0x00, 0x00,0x01, 0xF5,0x82, 0x00,0x00, 0x86,0xA2, 0x00,0x00, 0x87,0x16,
-0xFF,0xF0, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0xEC,0x68, 0xF6,0x02,
-0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x00, 0xEC,0x70, 0x20,0x32, 0x00,0x00, 0x86,0xA2,
-0x00,0x04, 0x87,0x16, 0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00,
-0xEC,0x71, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0xEC,0x81, 0x20,0x2E, 0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00,
-0xEC,0xAC, 0xF7,0x02, 0x00,0x01, 0xF7,0x04, 0x42,0x9C, 0xF6,0x06, 0x42,0x9C, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xF7,0x33, 0x28,0x00, 0xF7,0x02, 0x00,0x01, 0x97,0x2A, 0x00,0x08, 0x83,0xA6,
-0x00,0x0C, 0x77,0x2C, 0xFF,0xE1, 0x93,0xAA, 0x00,0x0C, 0x97,0x2A, 0x00,0x1C, 0x83,0xA6,
-0x00,0x1C, 0xF7,0x04, 0x6E,0x50, 0x93,0xAA, 0x00,0x20, 0x83,0xBA, 0x1D,0xDC, 0xF6,0x82,
-0x00,0x00, 0x93,0xAA, 0x00,0x2C, 0x83,0x96, 0x00,0x0C, 0xC5,0xB4, 0x00,0x00, 0x93,0xAA,
-0x00,0x30, 0x83,0xBA, 0x00,0x10, 0xC6,0x34, 0x00,0x00, 0x93,0xAA, 0x00,0x24, 0x87,0x3A,
-0x00,0x14, 0x00,0x00, 0x00,0x01, 0x97,0x2A, 0x00,0x28, 0x20,0x36, 0x00,0x1F, 0xEE,0x00,
-0xED,0x1C, 0xC7,0x30, 0x50,0x00, 0x07,0x38, 0x00,0x34, 0x95,0xBA, 0x00,0x00, 0x06,0x30,
-0x00,0x04, 0xE0,0x00, 0xEC,0xFC, 0x06,0xB4, 0x00,0x01, 0x83,0x96, 0x00,0x10, 0x76,0xA5,
-0x00,0x1E, 0x93,0x93, 0xFF,0xFC, 0xF3,0x82, 0x00,0xB4, 0x93,0x93, 0xFF,0xFC, 0x95,0x13,
-0xFF,0xFC, 0x87,0x26, 0x00,0x20, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x97,0x13, 0xFF,0xFC, 0x83,0x96, 0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xEA,0xB8, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x14, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x18, 0x87,0x16,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0x86,0x3A, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x96,0x16,
-0xFF,0xF0, 0x87,0x3A, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x97,0x16, 0xFF,0xF4, 0xF6,0x02,
-0x1D,0xE0, 0x96,0x13, 0xFF,0xFC, 0x86,0x16, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x96,0x13,
-0xFF,0xFC, 0xF6,0x04, 0x6E,0x50, 0x00,0x00, 0x00,0x01, 0x96,0x13, 0xFF,0xFC, 0x26,0x14,
-0x00,0x10, 0x96,0x16, 0xFF,0xEC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x26,0xF8, 0x97,0x93,
-0xFF,0xFC, 0xF6,0x84, 0x6E,0x50, 0xF6,0x02, 0x00,0x00, 0x87,0x36, 0x1D,0xD8, 0x96,0x16,
-0xFF,0xE4, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF6,0x86, 0x42,0xC0, 0xF7,0x37, 0x28,0x00, 0x86,0x16, 0xFF,0xEC, 0x00,0x00,
-0x00,0x01, 0x96,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xDB,0xB4, 0x97,0x93,
-0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0xEE,0x4D, 0x00,0x00, 0x00,0x01, 0x86,0x16,
-0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0x96,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xD5,0xA0, 0x97,0x93, 0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00, 0xEE,0x4D, 0x00,0x00,
-0x00,0x01, 0xF6,0x02, 0x00,0x01, 0x96,0x16, 0xFF,0xE4, 0x84,0x16, 0xFF,0xE4, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x08, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x86,0x96, 0x00,0x04, 0x86,0x16,
-0x00,0x00, 0x87,0x36, 0x00,0x08, 0x85,0x96, 0x00,0x08, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0xEE,0x99, 0x20,0x3A, 0x00,0x03, 0xE6,0x00, 0xEE,0xE9, 0xF4,0x02, 0x00,0x00, 0xE0,0x00,
-0xEF,0x0C, 0x00,0x00, 0x00,0x01, 0x77,0xB0, 0x00,0x1F, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x00,
-0xEF,0x0D, 0xF4,0x02, 0x00,0x00, 0x85,0x16, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x95,0x13,
-0xFF,0xFC, 0x85,0x16, 0x00,0x10, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x85,0x16,
-0x00,0x0C, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x95,0x93, 0xFF,0xFC, 0x96,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xEB,0x60, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00,
-0xEF,0x0C, 0x00,0x00, 0x00,0x01, 0x77,0xB0, 0x00,0x1E, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x00,
-0xEF,0x0D, 0x00,0x00, 0x00,0x01, 0x95,0x93, 0xFF,0xFC, 0x96,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xED,0x74, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x18, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x18, 0xF4,0x82, 0x00,0x00, 0x86,0x96,
-0x00,0x00, 0xF6,0x04, 0x4A,0xA0, 0x23,0x94, 0x00,0x10, 0x84,0x36, 0x00,0x00, 0x96,0x16,
-0xFF,0xE4, 0xF7,0x04, 0x4A,0x9C, 0x94,0x16, 0xFF,0xF0, 0x85,0x36, 0x00,0x04, 0xC0,0x32,
-0x72,0x00, 0xEC,0x00, 0xF0,0x14, 0x95,0x16, 0xFF,0xF4, 0x77,0x31, 0x00,0x01, 0xC7,0x38,
-0x60,0x00, 0x77,0x39, 0x00,0x02, 0xF3,0x06, 0x4A,0x98, 0xC6,0xB8, 0x30,0x00, 0x06,0xB4,
-0x00,0x0C, 0xC5,0x84, 0x00,0x00, 0x87,0x36, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x3A,
-0x42,0x00, 0xE6,0x00, 0xEF,0xA4, 0xC6,0x24, 0x00,0x00, 0x87,0x36, 0x00,0x04, 0x00,0x00,
-0x00,0x01, 0xC0,0x3A, 0x52,0x00, 0xE6,0x00, 0xEF,0xA8, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00, 0xEF,0xB5, 0x00,0x00, 0x00,0x01, 0xF5,0x82,
-0x00,0x00, 0x86,0x36, 0x00,0x00, 0x87,0x16, 0xFF,0xF0, 0x00,0x00, 0x00,0x01, 0xC0,0x32,
-0x72,0x00, 0xE2,0x00, 0xEF,0xF0, 0xF5,0x02, 0x00,0x00, 0xC0,0x32, 0x72,0x00, 0xE6,0x00,
-0xEF,0xF8, 0x20,0x2A, 0x00,0x00, 0x86,0xB6, 0x00,0x04, 0x87,0x16, 0xFF,0xF4, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x00, 0xEF,0xF9, 0x20,0x2A, 0x00,0x00, 0xF5,0x02,
-0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x00, 0xF0,0x09, 0x20,0x2E, 0x00,0x00, 0xF5,0x82,
-0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x00, 0xF0,0x18, 0x20,0x26, 0x00,0x00, 0xF4,0x82,
-0x00,0x01, 0x20,0x26, 0x00,0x00, 0xE6,0x00, 0xF0,0x4D, 0xF6,0x02, 0x00,0x01, 0x87,0x16,
-0xFF,0xE4, 0xF3,0x06, 0x4A,0x98, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5,
-0x00,0x02, 0xC6,0xB4, 0x30,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16,
-0xFF,0xE8, 0xE0,0x00, 0xF0,0xB0, 0x96,0x96, 0xFF,0xEC, 0x27,0x14, 0x00,0x1C, 0x97,0x13,
-0xFF,0xFC, 0x93,0x93, 0xFF,0xFC, 0xF3,0x06, 0x4A,0x98, 0x93,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x25,0x68, 0x97,0x93, 0xFF,0xFC, 0x20,0x22, 0x00,0x00, 0xE6,0x00,
-0xF0,0xAD, 0xF6,0x02, 0x00,0x01, 0x87,0x16, 0xFF,0xE4, 0xF3,0x06, 0x4A,0x98, 0x76,0xB9,
-0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4, 0x30,0x00, 0x06,0xB4,
-0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16, 0xFF,0xE8, 0x96,0x96, 0xFF,0xEC, 0xF7,0x05,
-0x4A,0xA0, 0xE0,0x00, 0xF0,0xB4, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x00, 0x20,0x32,
-0x00,0x00, 0xE6,0x00, 0xF1,0x21, 0xF4,0x02, 0x00,0x01, 0x87,0x16, 0xFF,0xE8, 0xF6,0x06,
-0x42,0xC8, 0x76,0xB9, 0x00,0x02, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xA7,0x36,
-0x60,0x02, 0x83,0x16, 0x00,0x04, 0xC6,0xB4, 0x60,0x00, 0x76,0x35, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0x05,0x34, 0x00,0x02, 0x75,0xA9, 0x00,0x1E, 0xC7,0x38, 0x67,0xC0, 0x77,0x38,
-0xFF,0xF0, 0x97,0x1A, 0x00,0x00, 0x87,0x2A, 0x00,0x00, 0x75,0xAC, 0xFF,0xE5, 0x83,0x16,
-0x00,0x08, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x97,0x1A, 0x00,0x00, 0x83,0x16,
-0x00,0x0C, 0x06,0xB4, 0x00,0x04, 0xE0,0x00, 0xF1,0x24, 0x96,0x9A, 0x00,0x00, 0xF4,0x02,
-0x00,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x10, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0xB9,0x00, 0x00,0x00, 0xBA,0x00, 0x00,0x00,
-0xBB,0x00, 0x00,0x00, 0xBC,0x00, 0x00,0x00, 0xBD,0x00, 0x00,0x00, 0xBE,0x00, 0x00,0x00,
-0xBF,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x81,0x00, 0x00,0x00, 0x82,0x00, 0x00,0x00,
-0x83,0x00, 0x00,0x00, 0x84,0x00, 0x00,0x00, 0x85,0x00, 0x00,0x00, 0x86,0x00, 0x00,0x00,
-0x87,0x00, 0xB9,0xB9, 0xB9,0xBA, 0xB9,0xBB, 0xB9,0xBC, 0xB9,0xBD, 0xB9,0xBE, 0xB9,0xBF,
-0xB9,0x80, 0xB9,0x81, 0xB9,0x82, 0xB9,0x83, 0xB9,0x84, 0xB9,0x85, 0xB9,0x86, 0xB9,0x87,
-0xBA,0xB9, 0xBA,0xBA, 0xBA,0xBB, 0xBA,0xBC, 0xBA,0xBD, 0xBA,0xBE, 0xBA,0xBF, 0xBA,0x80,
-0xBA,0x81, 0xBA,0x82, 0xBA,0x83, 0xBA,0x84, 0xBA,0x85, 0xBA,0x86, 0xBA,0x87, 0xBB,0xB9,
-0xBB,0xBA, 0xBB,0xBB, 0xBB,0xBC, 0xBB,0xBD, 0xBB,0xBE, 0xBB,0xBF, 0xBB,0x80, 0xBB,0x81,
-0xBB,0x82, 0xBB,0x83, 0xBB,0x84, 0xBB,0x85, 0xBB,0x86, 0xBB,0x87, 0xBC,0xB9, 0xBC,0xBA,
-0xBC,0xBB, 0xBC,0xBC, 0xBC,0xBD, 0xBC,0xBE, 0xBC,0xBF, 0xBC,0x80, 0xBC,0x81, 0xBC,0x82,
-0xBC,0x83, 0xBC,0x84, 0xBC,0x85, 0xBC,0x86, 0xBC,0x87, 0xBD,0xB9, 0xBD,0xBA, 0xBD,0xBB,
-0xBD,0xBC, 0xBD,0xBD, 0xBD,0xBE, 0xBD,0xBF, 0xBD,0x80, 0xBD,0x81, 0xBD,0x82, 0xBD,0x83,
-0xBD,0x84, 0xBD,0x85, 0xBD,0x86, 0xBD,0x87, 0xBE,0xB9, 0xBE,0xBA, 0xBE,0xBB, 0xBE,0xBC,
-0xBE,0xBD, 0xBE,0xBE, 0xBE,0xBF, 0xBE,0x80, 0xBE,0x81, 0xBE,0x82, 0xBE,0x83, 0xBE,0x84,
-0xBE,0x85, 0xBE,0x86, 0xBE,0x87, 0xBF,0xB9, 0xBF,0xBA, 0xBF,0xBB, 0xBF,0xBC, 0xBF,0xBD,
-0xBF,0xBE, 0xBF,0xBF, 0xBF,0x80, 0xBF,0x81, 0xBF,0x82, 0xBF,0x83, 0xBF,0x84, 0xBF,0x85,
-0xBF,0x86, 0xBF,0x87, 0x80,0xB9, 0x80,0xBA, 0x80,0xBB, 0x80,0xBC, 0x80,0xBD, 0x80,0xBE,
-0x80,0xBF, 0x80,0x80, 0x80,0x81, 0x80,0x82, 0x80,0x83, 0x80,0x84, 0x80,0x85, 0x80,0x86,
-0x80,0x87, 0x81,0xB9, 0x81,0xBA, 0x81,0xBB, 0x81,0xBC, 0x81,0xBD, 0x81,0xBE, 0x81,0xBF,
-0x81,0x80, 0x81,0x81, 0x81,0x82, 0x81,0x83, 0x81,0x84, 0x81,0x85, 0x81,0x86, 0x81,0x87,
-0x82,0xB9, 0x82,0xBA, 0x82,0xBB, 0x82,0xBC, 0x82,0xBD, 0x82,0xBE, 0x82,0xBF, 0x82,0x80,
-0x82,0x81, 0x82,0x82, 0x82,0x83, 0x82,0x84, 0x82,0x85, 0x82,0x86, 0x82,0x87, 0x83,0xB9,
-0x83,0xBA, 0x83,0xBB, 0x83,0xBC, 0x83,0xBD, 0x83,0xBE, 0x83,0xBF, 0x83,0x80, 0x83,0x81,
-0x83,0x82, 0x83,0x83, 0x83,0x84, 0x83,0x85, 0x83,0x86, 0x83,0x87, 0x84,0xB9, 0x84,0xBA,
-0x84,0xBB, 0x84,0xBC, 0x84,0xBD, 0x84,0xBE, 0x84,0xBF, 0x84,0x80, 0x84,0x81, 0x84,0x82,
-0x84,0x83, 0x84,0x84, 0x84,0x85, 0x84,0x86, 0x84,0x87, 0x85,0xB9, 0x85,0xBA, 0x85,0xBB,
-0x85,0xBC, 0x85,0xBD, 0x85,0xBE, 0x85,0xBF, 0x85,0x80, 0x85,0x81, 0x85,0x82, 0x85,0x83,
-0x85,0x84, 0x85,0x85, 0x85,0x86, 0x85,0x87, 0x86,0xB9, 0x86,0xBA, 0x86,0xBB, 0x86,0xBC,
-0x86,0xBD, 0x86,0xBE, 0x86,0xBF, 0x86,0x80, 0x86,0x81, 0x86,0x82, 0x86,0x83, 0x86,0x84,
-0x86,0x85, 0x86,0x86, 0x86,0x87, 0x87,0xB9, 0x87,0xBA, 0x87,0xBB, 0x87,0xBC, 0x87,0xBD,
-0x87,0xBE, 0x87,0xBF, 0x87,0x80, 0x87,0x81, 0x87,0x82, 0x87,0x83, 0x87,0x84, 0x87,0x85,
-0x87,0x86, 0x87,0x87, 0x00,0x00, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10,
-0x00,0x18, 0xF7,0x04, 0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0xF3,0x7D, 0xF6,0x06, 0x42,0x96, 0xF7,0x04, 0x42,0x94, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xF4,0x02, 0x00,0x00, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xE0,0x00, 0xF5,0xE0, 0xF7,0x33, 0x28,0x00, 0xF3,0x84, 0x6F,0x30, 0x90,0x13,
-0xFF,0xFC, 0x27,0x1C, 0x00,0x02, 0x97,0x13, 0xFF,0xFC, 0x83,0x16, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0x93,0x96, 0xFF,0xEC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xCD,0xB8, 0x97,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0xEC, 0xF7,0x02, 0x00,0x00, 0x97,0x1E,
-0x00,0x08, 0x83,0x16, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x93,0x1E, 0x00,0x0C, 0x83,0x16,
-0x00,0x08, 0x04,0x9C, 0x00,0x22, 0x93,0x1E, 0x00,0x1C, 0x83,0x16, 0x00,0x0C, 0x93,0x96,
-0xFF,0xF4, 0x87,0x1A, 0x00,0x00, 0x76,0x99, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x06,0x18,
-0x00,0x02, 0x75,0xB1, 0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0x06,0x9C, 0x00,0x20, 0xF7,0x37, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x96,0x96,
-0xFF,0xE4, 0x75,0x35, 0x00,0x1E, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x04,0x9C, 0x00,0x24, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x04,0x9C, 0x00,0x26, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x04,0x9C, 0x00,0x28, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x04,0x9C, 0x00,0x2A, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x04,0x9C, 0x00,0x2C, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x04,0x9C, 0x00,0x2E, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x04,0x9C, 0x00,0x30, 0x76,0x31,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27,
-0x28,0x00, 0x87,0x1E, 0x00,0x20, 0x75,0x28, 0xFF,0xE5, 0xC7,0x38, 0x57,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x20,0x3A, 0x00,0x08, 0xEE,0x00, 0xF5,0x98, 0xF3,0x06, 0x14,0xD8, 0x83,0x16,
-0xFF,0xE4, 0x87,0x1E, 0x00,0x20, 0x76,0x99, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x25,0xB8, 0x00,0x01, 0xC4,0xAC, 0x58,0x00, 0x04,0x24,
-0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xEC,0x00, 0xF5,0x95, 0xF5,0x02, 0x00,0x00, 0x83,0x16,
-0xFF,0xE4, 0x00,0x00, 0x00,0x01, 0x06,0x18, 0x00,0x02, 0xA7,0x32, 0x58,0x02, 0xC6,0xB0,
-0x58,0x00, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xE8, 0xC6,0xB0, 0x40,0x00, 0x77,0xB8, 0x00,0x18, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x00,
-0xF5,0x7D, 0xF7,0x37, 0x68,0x00, 0xF5,0x02, 0xFF,0xFF, 0xC7,0x30, 0x48,0x00, 0xF5,0x3B,
-0x68,0x00, 0x24,0xA4, 0x00,0x02, 0x24,0x20, 0x00,0x02, 0xE0,0x00, 0xF5,0x34, 0x25,0xAC,
-0x00,0x01, 0xF3,0x06, 0x14,0xD8, 0x93,0x13, 0xFF,0xFC, 0xF3,0x02, 0x00,0x34, 0x93,0x13,
-0xFF,0xFC, 0x83,0x16, 0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0x83,0x16,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x87,0x1A, 0x00,0x00, 0x76,0x99, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x97,0x13, 0xFF,0xFC, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xEA,0xB8, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x10, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x10, 0xF7,0x04,
-0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0xF6,0x39, 0xF6,0x06,
-0x42,0x96, 0xF7,0x04, 0x42,0x94, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xF4,0x02,
-0x00,0x00, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xE0,0x00,
-0xF7,0x48, 0xF7,0x33, 0x28,0x00, 0xF5,0x04, 0x6F,0x30, 0x00,0x00, 0x00,0x01, 0x95,0x16,
-0xFF,0xF4, 0x90,0x13, 0xFF,0xFC, 0x27,0x28, 0x00,0x02, 0x97,0x13, 0xFF,0xFC, 0x85,0x96,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xCD,0xB8, 0x97,0x93, 0xFF,0xFC, 0x85,0x16, 0x00,0x04, 0xF6,0x02, 0x00,0x00, 0x86,0xAA,
-0x00,0x00, 0x77,0x29, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5,
-0xFF,0xF0, 0xF7,0x02, 0x00,0x01, 0xC0,0x36, 0x74,0x00, 0xE6,0x00, 0xF6,0x99, 0x96,0x96,
-0xFF,0xEC, 0xC6,0x38, 0x00,0x00, 0x96,0x13, 0xFF,0xFC, 0x85,0x96, 0xFF,0xEC, 0x85,0x16,
-0xFF,0xF4, 0x47,0x2C, 0xFF,0xFE, 0x07,0x38, 0x00,0x02, 0xC7,0x28, 0x72,0x00, 0x97,0x13,
-0xFF,0xFC, 0x85,0x96, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x95,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xCD,0xB8, 0x97,0x93, 0xFF,0xFC, 0x85,0x16, 0xFF,0xF4, 0xF7,0x02,
-0x00,0x02, 0x97,0x2A, 0x00,0x08, 0x85,0x96, 0x00,0x08, 0x00,0x00, 0x00,0x01, 0x95,0xAA,
-0x00,0x0C, 0x85,0x96, 0x00,0x0C, 0x00,0x00, 0x00,0x01, 0x95,0xAA, 0x00,0x1C, 0xF5,0x06,
-0x14,0xD8, 0x95,0x13, 0xFF,0xFC, 0xF5,0x82, 0x00,0x20, 0x95,0x93, 0xFF,0xFC, 0x85,0x16,
-0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x85,0x96, 0x00,0x00, 0x85,0x16,
-0xFF,0xEC, 0x87,0x2E, 0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0xC7,0x38, 0x50,0x00, 0x97,0x13, 0xFF,0xFC, 0x85,0x96,
-0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xEA,0xB8, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x10, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x85,0x96, 0x00,0x00, 0x85,0x16, 0x00,0x04, 0x87,0x16, 0x00,0x08, 0xF6,0x02,
-0xFF,0xFC, 0x06,0xA8, 0x00,0x03, 0xC6,0xB4, 0x64,0x00, 0x07,0x38, 0x00,0x03, 0xC7,0x38,
-0x64,0x00, 0xC7,0x34, 0x70,0x00, 0x97,0x13, 0xFF,0xFC, 0xC5,0xAC, 0x6A,0x00, 0x95,0x93,
-0xFF,0xFC, 0xF7,0x02, 0x00,0x03, 0xC5,0x28, 0x74,0x00, 0xF7,0x02, 0x00,0x04, 0xC7,0x38,
-0x52,0x00, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x14,0xD8, 0x97,0x93,
-0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x10, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10,
-0x00,0x10, 0xF7,0x04, 0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0xF8,0x0D, 0xF6,0x06, 0x42,0x96, 0xF7,0x04, 0x42,0x94, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xF4,0x02, 0x00,0x00, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xE0,0x00, 0xF9,0x20, 0xF7,0x33, 0x28,0x00, 0xF5,0x04, 0x6F,0x30, 0x00,0x00,
-0x00,0x01, 0x95,0x16, 0xFF,0xF4, 0x90,0x13, 0xFF,0xFC, 0x27,0x28, 0x00,0x02, 0x97,0x13,
-0xFF,0xFC, 0x85,0x96, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x95,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xCD,0xB8, 0x97,0x93, 0xFF,0xFC, 0x85,0x16, 0x00,0x04, 0xF6,0x02,
-0x00,0x00, 0x86,0xAA, 0x00,0x00, 0x77,0x29, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4,
-0x77,0xC0, 0x76,0xB5, 0xFF,0xF0, 0xF7,0x02, 0x00,0x01, 0xC0,0x36, 0x74,0x00, 0xE6,0x00,
-0xF8,0x6D, 0x96,0x96, 0xFF,0xEC, 0xC6,0x38, 0x00,0x00, 0x96,0x13, 0xFF,0xFC, 0x85,0x96,
-0xFF,0xEC, 0x85,0x16, 0xFF,0xF4, 0x47,0x2C, 0xFF,0xFE, 0x07,0x38, 0x00,0x02, 0xC7,0x28,
-0x72,0x00, 0x97,0x13, 0xFF,0xFC, 0x85,0x96, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x95,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCD,0xB8, 0x97,0x93, 0xFF,0xFC, 0x85,0x16,
-0xFF,0xF4, 0xF5,0x82, 0x00,0x06, 0xF5,0xAB, 0x28,0x00, 0x85,0x96, 0x00,0x08, 0x07,0x28,
-0x00,0x02, 0x95,0xAA, 0x00,0x04, 0x05,0x14, 0x00,0x0E, 0x85,0x2A, 0x00,0x00, 0x77,0xA9,
-0x00,0x1E, 0x77,0xBC, 0xFF,0xE5, 0xC5,0x28, 0x7F,0xC0, 0x75,0x29, 0xFF,0xF0, 0xF5,0x3B,
-0x28,0x00, 0xF5,0x86, 0x14,0xD8, 0x95,0x93, 0xFF,0xFC, 0xF5,0x02, 0x00,0x08, 0x95,0x13,
-0xFF,0xFC, 0x85,0x96, 0x00,0x00, 0x85,0x16, 0xFF,0xEC, 0x87,0x2E, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0xC7,0x38,
-0x50,0x00, 0x97,0x13, 0xFF,0xFC, 0x85,0x96, 0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0x95,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xF7,0x5C, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x10, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x08, 0xF7,0x04,
-0x75,0xEC, 0x83,0x96, 0x00,0x04, 0x20,0x3A, 0x00,0x00, 0xE6,0x00, 0xFA,0x64, 0xF6,0x06,
-0x42,0x96, 0xF5,0x04, 0x6F,0x30, 0x90,0x13, 0xFF,0xFC, 0x27,0x28, 0x00,0x02, 0x97,0x13,
-0xFF,0xFC, 0x83,0x16, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0x93,0x96,
-0xFF,0xF4, 0x95,0x16, 0xFF,0xF0, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCD,0xB8, 0x97,0x93,
-0xFF,0xFC, 0x85,0x16, 0xFF,0xF0, 0xF3,0x02, 0x00,0x07, 0x83,0x96, 0xFF,0xF4, 0xF3,0x2B,
-0x28,0x00, 0x07,0x28, 0x00,0x02, 0xF3,0x02, 0x00,0x01, 0xF3,0x3B, 0x28,0x00, 0x87,0x1E,
-0x00,0x00, 0x76,0x9D, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x05,0x9C, 0x00,0x02, 0x76,0x2D,
-0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0x74,0x9D, 0x00,0x1E, 0x74,0xA4, 0xFF,0xE5, 0x04,0x1C,
-0x00,0x06, 0x83,0x16, 0x00,0x00, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0x06,0xA8,
-0x00,0x04, 0xF7,0x37, 0x28,0x00, 0x87,0x2E, 0x00,0x00, 0x06,0xA8, 0x00,0x06, 0x75,0xA1,
-0x00,0x1E, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x1E,
-0x00,0x04, 0x75,0xAC, 0xFF,0xE5, 0x06,0xA8, 0x00,0x08, 0x76,0x19, 0x00,0x1E, 0xC7,0x38,
-0x4F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0x87,0x22, 0x00,0x00, 0x06,0xA8,
-0x00,0x0A, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x37, 0x28,0x00, 0xF3,0x06,
-0x14,0xD8, 0x93,0x13, 0xFF,0xFC, 0xF3,0x02, 0x00,0x0C, 0x93,0x13, 0xFF,0xFC, 0x83,0x16,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x87,0x1A, 0x00,0x00, 0x76,0x30, 0xFF,0xE5, 0xC7,0x38,
-0x67,0xC0, 0x77,0x39, 0xFF,0xF0, 0x97,0x13, 0xFF,0xFC, 0x95,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xF7,0x5C, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00, 0xFA,0x84, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x42,0x94, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xF4,0x02,
-0x00,0x00, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xF7,0x33,
-0x28,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x08, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10,
-0x00,0x48, 0xF7,0x04, 0x75,0xEC, 0x85,0x96, 0x00,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x00,
-0xFD,0x98, 0xF6,0x06, 0x42,0x96, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0x24,0x14, 0x00,0x1E, 0x06,0x2C, 0x00,0x02, 0x75,0x31,
-0x00,0x1E, 0x24,0x94, 0x00,0x20, 0x75,0x28, 0xFF,0xE5, 0xF3,0x84, 0x6E,0x50, 0xC7,0x38,
-0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x87,0x32, 0x00,0x00, 0x93,0x96,
-0xFF,0xC4, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x24,0x14,
-0x00,0x1C, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x24,0x14,
-0x00,0x1A, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x24,0x14,
-0x00,0x18, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x24,0x14,
-0x00,0x16, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x24,0x14,
-0x00,0x14, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x24,0x14,
-0x00,0x12, 0x06,0x30, 0x00,0x02, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x06,0x30,
-0x00,0x02, 0x87,0x32, 0x00,0x00, 0x24,0x14, 0x00,0x10, 0x76,0x31, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x23, 0x28,0x00, 0x90,0x13,
-0xFF,0xFC, 0x27,0x1C, 0x00,0x02, 0x97,0x13, 0xFF,0xFC, 0x94,0x93, 0xFF,0xFC, 0x95,0x96,
-0xFF,0xBC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xCD,0xB8, 0x97,0x93, 0xFF,0xFC, 0x85,0x96,
-0xFF,0xBC, 0x23,0x14, 0x00,0x36, 0x24,0x94, 0x00,0x38, 0x73,0xA5, 0x00,0x1E, 0x73,0x9C,
-0xFF,0xE5, 0xF4,0x04, 0x42,0xC0, 0xF6,0x86, 0x42,0xC0, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0x87,0x2E, 0x00,0x00, 0x76,0x2D, 0x00,0x1E, 0x76,0x30, 0xFF,0xE5, 0xC4,0x20,
-0x6F,0xC0, 0x74,0x20, 0xFF,0xF0, 0x05,0xAC, 0x00,0x02, 0x75,0x2D, 0x00,0x1E, 0x75,0x28,
-0xFF,0xE5, 0xC7,0x38, 0x67,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x27, 0x28,0x00, 0x87,0x2E,
-0x00,0x00, 0xF6,0x04, 0x6E,0x50, 0xC7,0x38, 0x57,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B,
-0x28,0x00, 0x23,0x14, 0x00,0x34, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B,
-0x28,0x00, 0x23,0x14, 0x00,0x32, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B,
-0x28,0x00, 0x23,0x14, 0x00,0x30, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B,
-0x28,0x00, 0x23,0x14, 0x00,0x2E, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B,
-0x28,0x00, 0x23,0x14, 0x00,0x2C, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B,
-0x28,0x00, 0x23,0x14, 0x00,0x2A, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x76,0xAD,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B,
-0x28,0x00, 0x05,0xAC, 0x00,0x02, 0x87,0x2E, 0x00,0x00, 0x23,0x14, 0x00,0x28, 0x75,0xAD,
-0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0xC7,0x38, 0x5F,0xC0, 0x77,0x38, 0xFF,0xF0, 0xF7,0x1B,
-0x28,0x00, 0x87,0x16, 0xFF,0xC8, 0xF6,0x82, 0x00,0x03, 0xC7,0x38, 0x3F,0xC0, 0x96,0xB2,
-0x00,0x08, 0x06,0xB0, 0x1D,0xD8, 0xF4,0x37, 0x28,0x00, 0xF3,0x86, 0x14,0xD8, 0x93,0x93,
-0xFF,0xFC, 0xF3,0x82, 0x1D,0xE0, 0x93,0x93, 0xFF,0xFC, 0x96,0x13, 0xFF,0xFC, 0x77,0x39,
-0xFF,0xF0, 0x97,0x13, 0xFF,0xFC, 0x83,0x96, 0xFF,0xC4, 0x00,0x00, 0x00,0x01, 0x93,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xEA,0xB8, 0x97,0x93, 0xFF,0xFC, 0xE0,0x00,
-0xFD,0xB8, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x42,0x94, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xF4,0x02, 0x00,0x00, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xF7,0x33, 0x28,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x86,0x16, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x87,0x32, 0x00,0x00, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x20,0x3A,
-0x00,0x06, 0xE6,0x00, 0xFE,0x21, 0xF5,0x82, 0x00,0x1E, 0xF7,0x04, 0x42,0xA8, 0xF6,0x06,
-0x42,0xA8, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39,
-0xFF,0xF0, 0x07,0x38, 0x00,0x01, 0xE0,0x00, 0xFE,0x34, 0xF7,0x33, 0x28,0x00, 0xF6,0x05,
-0x6F,0x34, 0x95,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93,
-0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x04, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x86,0x16,
-0x00,0x00, 0x85,0x96, 0x00,0x04, 0x87,0x32, 0x00,0x00, 0x76,0xB1, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x20,0x3A, 0x00,0x07, 0xE6,0x00,
-0xFE,0x9D, 0xF4,0x02, 0x00,0x00, 0xF7,0x04, 0x42,0xA8, 0xF6,0x06, 0x42,0xAA, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xE0,0x00, 0xFF,0x1C, 0xF7,0x33, 0x28,0x00, 0x07,0x30, 0x00,0x02, 0x86,0xBA,
-0x00,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5,
-0xFF,0xF0, 0x20,0x36, 0x00,0x01, 0xE6,0x00, 0xFE,0xD5, 0xF6,0x05, 0x6F,0x34, 0x20,0x36,
-0x00,0x02, 0xE6,0x00, 0xFE,0xE5, 0xF5,0x02, 0x00,0x20, 0xE0,0x00, 0xFE,0xFC, 0xF6,0x06,
-0x42,0xAC, 0x20,0x2E, 0x00,0x0C, 0xE6,0x00, 0xFF,0x1C, 0xF4,0x02, 0x00,0x00, 0xF5,0x02,
-0x00,0x1F, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93,
-0xFF,0xFC, 0xE0,0x00, 0xFF,0x1C, 0xF4,0x02, 0x00,0x01, 0xF7,0x04, 0x42,0xAC, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xF7,0x33, 0x28,0x00, 0xF4,0x02, 0x00,0x01, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x08, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x86,0x96, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x87,0x36,
-0x00,0x04, 0xF6,0x02, 0x00,0x00, 0x07,0x38, 0x00,0x08, 0x97,0x36, 0x00,0x04, 0x87,0x36,
-0x00,0x08, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xEC,0x00, 0xFF,0x7D, 0xF6,0x85,
-0x6F,0x34, 0x87,0x36, 0x00,0x08, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x03, 0xEE,0x00,
-0xFF,0x80, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x00,
-0xFF,0xBD, 0xF6,0x06, 0x42,0xAE, 0xF7,0x04, 0x6F,0x34, 0x00,0x00, 0x00,0x01, 0x87,0x3A,
-0x00,0x08, 0xF6,0x82, 0xFF,0xEC, 0x77,0x39, 0x00,0x02, 0xA7,0x3A, 0x68,0x02, 0x00,0x00,
-0x00,0x01, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93,
-0xFF,0xFC, 0xE0,0x00, 0xFF,0xD8, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x42,0xAC, 0x76,0xB1,
-0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x07,0x38,
-0x00,0x01, 0xF7,0x33, 0x28,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x17, 0x00,0x00,
-0x00,0x1A, 0x00,0x00, 0x00,0x1D, 0x00,0x00, 0x00,0x18, 0x00,0x00, 0x00,0x00, 0x56,0x65,
-0x72,0x73, 0x69,0x6F, 0x6E,0x53, 0x74,0x72, 0x69,0x6E, 0x67,0x3A, 0x20,0x6D, 0x63,0x70,
-0x2D,0x6C, 0x34,0x76, 0x33,0x20, 0x33,0x2E, 0x30,0x38, 0x63,0x20, 0x44,0x65, 0x63,0x20,
-0x31,0x31, 0x20,0x31, 0x39,0x39, 0x36,0x20, 0x31,0x33, 0x3A,0x30, 0x36,0x3A, 0x31,0x36,
-0x00,0x00, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x04, 0xE0,0x0C, 0xFF,0x02,
-0x00,0x00, 0x97,0x02, 0xFF,0x84, 0xF7,0x06, 0x0C,0x3E, 0xCF,0xFC, 0x75,0x80, 0xF6,0x02,
-0x00,0x02, 0x96,0x02, 0xFF,0x8C, 0x90,0x02, 0xFF,0x88, 0xF7,0x04, 0xE0,0x20, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x00,0x74, 0xF6,0x82, 0x00,0x00, 0xF6,0x82,
-0x00,0x03, 0x96,0x82, 0xFF,0x98, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x22,0x10, 0x00,0x0C, 0xF5,0x02, 0x14,0x94, 0xF5,0x05, 0x7B,0x00, 0xF5,0x0E,
-0xF0,0x14, 0xF5,0x05, 0x7B,0x08, 0xF7,0x06, 0xE0,0x00, 0xF6,0x86, 0x7B,0x68, 0xC7,0x38,
-0x6A,0x00, 0xF7,0x05, 0x7A,0xF0, 0xF5,0x02, 0x00,0x4C, 0xF6,0x82, 0x00,0x00, 0x20,0x36,
-0x00,0x02, 0xEE,0x01, 0x01,0x24, 0xF5,0x05, 0x7A,0xF8, 0xC5,0xB4, 0x00,0x00, 0xC6,0x34,
-0x00,0x00, 0xF7,0x06, 0xE0,0x30, 0xC7,0x2C, 0x70,0x00, 0xF5,0x06, 0x6F,0x44, 0xB7,0x32,
-0x50,0x02, 0x90,0x13, 0xFF,0xFC, 0x97,0x13, 0xFF,0xFC, 0x95,0x96, 0xFF,0xF4, 0x96,0x16,
-0xFF,0xF0, 0x96,0x96, 0xFF,0xEC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x03,0x1C, 0x97,0x93,
-0xFF,0xFC, 0x85,0x96, 0xFF,0xF4, 0x86,0x16, 0xFF,0xF0, 0x86,0x96, 0xFF,0xEC, 0x05,0xAC,
-0x14,0x94, 0x06,0xB4, 0x00,0x01, 0x20,0x36, 0x00,0x02, 0xEE,0x01, 0x00,0xD5, 0x06,0x30,
-0x00,0x04, 0xF5,0x02, 0x00,0x22, 0xF5,0x05, 0x6F,0x58, 0xF0,0x05, 0x6F,0x54, 0xF0,0x05,
-0x6F,0x50, 0xF0,0x05, 0x2D,0x40, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x29,0x58, 0x97,0x93, 0xFF,0xFC, 0xF7,0x02,
-0x00,0x03, 0xF7,0x05, 0xE0,0x08, 0xF7,0x04, 0x7A,0xD8, 0xF6,0x02, 0x00,0x01, 0x96,0x02,
-0xFF,0x94, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x01,0x91, 0xF7,0x06, 0x7A,0xE8, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x03,0xDC, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x7A,0xE8, 0xF6,0x02,
-0x00,0x05, 0xF6,0x3B, 0x28,0x00, 0xF7,0x06, 0x7A,0xE0, 0x86,0x82, 0xFF,0x44, 0xF6,0x02,
-0x00,0x03, 0x20,0x36, 0x00,0x00, 0xE6,0x01, 0x01,0xC9, 0xF6,0x3B, 0x28,0x00, 0xF7,0x04,
-0x6F,0x64, 0x86,0x82, 0xFF,0x44, 0x07,0x38, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x01,
-0x01,0xB0, 0xF7,0x05, 0x6F,0x64, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x00,0x34, 0x97,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x00,0x8C, 0x97,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x44,0x28, 0x97,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0xF0, 0x97,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x0C,0x60, 0x97,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x04,0x08, 0x97,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x00,0x20, 0x97,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x0B,0xD8, 0x97,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x1D,0x68, 0x97,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x1E,0x50, 0x97,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x5F,0x68, 0x97,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x6D,0xEC, 0x97,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x21,0xD0, 0x97,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x22,0x2C, 0x97,0x93, 0xFF,0xFC, 0x90,0x02,
-0xFF,0x94, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x0B,0xFC, 0x97,0x93, 0xFF,0xFC, 0xF4,0x02,
-0x00,0x00, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10,
-0x00,0x08, 0xF6,0x02, 0x00,0x00, 0xC5,0xB0, 0x00,0x00, 0x20,0x32, 0x00,0x02, 0xEE,0x01,
-0x03,0x08, 0xF5,0x06, 0x6F,0x44, 0xA6,0xAE, 0x50,0x02, 0x00,0x00, 0x00,0x01, 0x87,0x36,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x01, 0xE6,0x01, 0x02,0xFC, 0xF5,0x02,
-0x00,0x02, 0x95,0x13, 0xFF,0xFC, 0x96,0x93, 0xFF,0xFC, 0x95,0x96, 0xFF,0xF4, 0x96,0x16,
-0xFF,0xF0, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x03,0x1C, 0x97,0x93, 0xFF,0xFC, 0x86,0x16,
-0xFF,0xF0, 0x85,0x96, 0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0x05,0xAC, 0x00,0x04, 0xE0,0x01,
-0x02,0xAC, 0x06,0x30, 0x00,0x01, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x87,0x16, 0x00,0x00, 0xF6,0x02, 0x00,0x00, 0xF6,0x82, 0x00,0x08, 0x96,0x3A,
-0x00,0x08, 0x96,0x3A, 0x00,0x0C, 0x96,0x3A, 0x09,0xD8, 0x96,0x3A, 0x09,0xDC, 0x96,0x3A,
-0x0E,0xF4, 0x96,0x3A, 0x0E,0xF8, 0x96,0xBA, 0x14,0x20, 0x96,0x3A, 0x14,0x24, 0x90,0xBA,
-0x14,0x8C, 0x86,0x96, 0x00,0x04, 0x90,0xBA, 0x14,0x90, 0x96,0xBA, 0x00,0x00, 0x96,0x3A,
-0x00,0x04, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x08, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x85,0x96,
-0x00,0x00, 0x87,0x16, 0x00,0x08, 0x86,0x16, 0x00,0x04, 0x77,0x38, 0xFF,0xFF, 0xC5,0x30,
-0x70,0x00, 0xC0,0x32, 0x52,0x00, 0xE4,0x01, 0x03,0xC9, 0x00,0x00, 0x00,0x01, 0x87,0x2E,
-0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0xC0,0x32, 0x52,0x00, 0xE4,0x01,
-0x03,0xA0, 0x05,0xAC, 0x00,0x02, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x0C, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0xF7,0x02, 0x00,0x01, 0xE0,0x01, 0x03,0xE8, 0xF7,0x05, 0x7A,0xD8, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF5,0x02,
-0x00,0x0A, 0xF5,0x05, 0x71,0xCC, 0xF0,0x05, 0x71,0xD4, 0xF0,0x05, 0x71,0xD0, 0xF0,0x05,
-0x71,0xC4, 0xF5,0x02, 0x00,0x01, 0xF6,0x82, 0x00,0x00, 0x20,0x36, 0x00,0x0A, 0xEC,0x01,
-0x04,0x64, 0xF5,0x05, 0x71,0xC8, 0xF5,0x8A, 0x1E,0x00, 0xF6,0x06, 0x71,0xC4, 0x47,0x2C,
-0xFF,0xFC, 0x97,0x32, 0x00,0x18, 0x06,0x30, 0x00,0x04, 0x06,0xB4, 0x00,0x01, 0xF7,0x04,
-0x71,0xCC, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xEC,0x01, 0x04,0x41, 0x05,0xAC,
-0x21,0x4C, 0xF0,0x05, 0x71,0x98, 0xF5,0x06, 0x6F,0x68, 0x95,0x13, 0xFF,0xFC, 0xF5,0x06,
-0x7B,0x18, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x48, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x06, 0x05,0xD4, 0x95,0x13, 0xFF,0xFC, 0xF7,0x82, 0x00,0x05, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x06, 0x6F,0x68, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06, 0x0B,0x70, 0x95,0x13, 0xFF,0xFC, 0xF7,0x82,
-0x00,0x06, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06, 0x6F,0x68, 0x95,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06, 0x0B,0xA0, 0x95,0x13,
-0xFF,0xFC, 0xF7,0x82, 0x00,0x05, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06, 0x70,0x80, 0x95,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06,
-0x0B,0x70, 0x95,0x13, 0xFF,0xFC, 0xF7,0x82, 0x00,0x06, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06,
-0x70,0x80, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x06, 0x05,0x58, 0x95,0x13, 0xFF,0xFC, 0xF5,0x02, 0x00,0x0A, 0x95,0x13,
-0xFF,0xFC, 0xF5,0x06, 0x71,0x0C, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x05,0x58, 0x97,0x93,
-0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x04,
-0x71,0xC4, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x05,0x7D, 0xF6,0x86,
-0x71,0xC4, 0xE0,0x01, 0x05,0x94, 0xF7,0x02, 0x00,0x00, 0xF7,0x04, 0x71,0xD0, 0x00,0x00,
-0x00,0x01, 0x77,0x39, 0x00,0x02, 0xC7,0x38, 0x68,0x00, 0x87,0x3A, 0x00,0x18, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x05,0xAC, 0xF7,0x05, 0x7B,0x10, 0xF6,0x06,
-0x71,0x0C, 0xE0,0x01, 0x05,0xC0, 0xF6,0x05, 0x7B,0x18, 0xF6,0x06, 0x6F,0x68, 0xF6,0x05,
-0x7B,0x18, 0x97,0x02, 0xFF,0x48, 0x07,0x38, 0x21,0x28, 0x97,0x02, 0xFF,0x4C, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x10, 0x86,0x82,
-0xFF,0x48, 0xF4,0x86, 0x6F,0x68, 0xF4,0x85, 0x7B,0x18, 0xF5,0x04, 0x7B,0x10, 0x26,0xB4,
-0x00,0x02, 0x85,0xB6, 0x00,0x00, 0x87,0x2A, 0x00,0x00, 0x76,0x29, 0x00,0x1E, 0x76,0x30,
-0xFF,0xE5, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC5,0xAC, 0x6F,0xC0, 0xC7,0x38,
-0x67,0xC0, 0x77,0x39, 0xFF,0xF0, 0x77,0xB8, 0x00,0x10, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x01,
-0x06,0x45, 0x75,0xAC, 0xFF,0xF0, 0xF7,0x04, 0x71,0xAC, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x71,0xAC, 0xF7,0x04, 0x71,0xAC, 0xE0,0x01, 0x08,0xC4, 0xF7,0x02,
-0x00,0x01, 0x77,0x2C, 0xFF,0xF8, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x06,0x71, 0x76,0xA9,
-0x00,0x1E, 0xF7,0x04, 0x71,0xA8, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x71,0xA8, 0xF7,0x04, 0x71,0xA8, 0xE0,0x01, 0x08,0xC4, 0xF7,0x02, 0x00,0x01, 0x87,0x2A,
-0x00,0x00, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x27,0x38,
-0x00,0x04, 0x20,0x3A, 0x00,0x03, 0xE2,0x01, 0x08,0xA4, 0x00,0x00, 0x00,0x01, 0x77,0x39,
-0x00,0x02, 0xF6,0x86, 0x06,0xA4, 0xA6,0xB6, 0x70,0x02, 0x00,0x00, 0x00,0x01, 0xC1,0x34,
-0x00,0x00, 0x00,0x01, 0x06,0xB4, 0x00,0x01, 0x07,0x7C, 0x00,0x01, 0x07,0xEC, 0x00,0x01,
-0x08,0x44, 0x87,0x2A, 0x00,0x04, 0xC4,0x84, 0x00,0x00, 0xC0,0x3A, 0x4A,0x00, 0xE6,0x01,
-0x06,0xD8, 0x00,0x00, 0x00,0x01, 0x87,0x02, 0xFF,0x48, 0x00,0x00, 0x00,0x01, 0xC7,0x38,
-0x52,0x00, 0x97,0x2A, 0x00,0x04, 0x87,0x2A, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x21,0x00, 0xEE,0x01, 0x07,0x3C, 0xF6,0x02, 0x00,0x00, 0x86,0xAA, 0x00,0x04, 0x87,0x02,
-0xFF,0x48, 0x00,0x00, 0x00,0x01, 0xC7,0x38, 0x52,0x00, 0x27,0x38, 0x00,0x28, 0xC0,0x36,
-0x72,0x00, 0xE6,0x01, 0x07,0x3C, 0x00,0x00, 0x00,0x01, 0x77,0xFC, 0x00,0x1D, 0x70,0x3E,
-0xFF,0xE1, 0xE6,0x01, 0x07,0x3C, 0x00,0x00, 0x00,0x01, 0x77,0xFC, 0x00,0x17, 0x70,0x3E,
-0xFF,0xE1, 0xE6,0x01, 0x07,0x3D, 0x00,0x00, 0x00,0x01, 0x77,0xFC, 0x00,0x16, 0x70,0x3E,
-0xFF,0xE1, 0xE6,0x01, 0x07,0x44, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32,
-0x00,0x00, 0xE6,0x01, 0x08,0x88, 0x00,0x00, 0x00,0x01, 0x87,0x2A, 0x00,0x18, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x02, 0xEE,0x01, 0x08,0xC1, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x71,0xA4, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x71,0xA4, 0xF7,0x04,
-0x71,0xA4, 0xE0,0x01, 0x08,0xC4, 0xF7,0x02, 0x00,0x01, 0x87,0x2A, 0x00,0x04, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x21,0x00, 0xEE,0x01, 0x07,0xE0, 0xF6,0x02, 0x00,0x00, 0x86,0xAA,
-0x00,0x04, 0x87,0x02, 0xFF,0x48, 0x00,0x00, 0x00,0x01, 0xC7,0x38, 0x52,0x00, 0x27,0x38,
-0x00,0x0C, 0xC0,0x36, 0x72,0x00, 0xE6,0x01, 0x07,0xE0, 0x00,0x00, 0x00,0x01, 0x77,0xFC,
-0x00,0x1D, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x01, 0x07,0xE0, 0x00,0x00, 0x00,0x01, 0x77,0xFC,
-0x00,0x17, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x01, 0x07,0xE1, 0x00,0x00, 0x00,0x01, 0x77,0xFC,
-0x00,0x16, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x01, 0x08,0x80, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x01, 0xE0,0x01, 0x08,0x80, 0x20,0x32, 0x00,0x00, 0x87,0x02, 0xFF,0x48, 0x00,0x00,
-0x00,0x01, 0xC7,0x38, 0x52,0x00, 0x27,0x38, 0x00,0x04, 0x20,0x3A, 0x00,0x08, 0xE6,0x01,
-0x08,0x38, 0xF6,0x82, 0x00,0x00, 0x77,0xFC, 0x00,0x1D, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x01,
-0x08,0x38, 0x00,0x00, 0x00,0x01, 0x77,0xFC, 0x00,0x17, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x01,
-0x08,0x39, 0x00,0x00, 0x00,0x01, 0x77,0xFC, 0x00,0x16, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x01,
-0x08,0x80, 0x20,0x36, 0x00,0x00, 0xF6,0x82, 0x00,0x01, 0xE0,0x01, 0x08,0x80, 0x20,0x36,
-0x00,0x00, 0xF7,0x02, 0x00,0x00, 0x77,0xFC, 0x00,0x1D, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x01,
-0x08,0x78, 0x00,0x00, 0x00,0x01, 0x77,0xFC, 0x00,0x17, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x01,
-0x08,0x79, 0x00,0x00, 0x00,0x01, 0x77,0xFC, 0x00,0x16, 0x70,0x3E, 0xFF,0xE1, 0xE6,0x01,
-0x08,0x80, 0x20,0x3A, 0x00,0x00, 0xF7,0x02, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01,
-0x08,0xC1, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x71,0xA0, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x71,0xA0, 0xF7,0x04, 0x71,0xA0, 0xE0,0x01, 0x08,0xC4, 0xF7,0x02,
-0x00,0x01, 0xF7,0x04, 0x71,0x9C, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x71,0x9C, 0xF7,0x04, 0x71,0x9C, 0xE0,0x01, 0x08,0xC4, 0xF7,0x02, 0x00,0x01, 0xF7,0x02,
-0x00,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x09,0x68, 0x00,0x00, 0x00,0x01, 0xF6,0x84,
-0x7B,0x10, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x00, 0x76,0xB5, 0x00,0x1E, 0x76,0xB4,
-0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x39, 0xFF,0xF0, 0x27,0x38, 0x00,0x04, 0x20,0x3A,
-0x00,0x03, 0xE2,0x01, 0x0B,0x50, 0x77,0x39, 0x00,0x02, 0xF6,0x86, 0x09,0x0C, 0xA6,0xB6,
-0x70,0x02, 0x00,0x00, 0x00,0x01, 0xC1,0x34, 0x00,0x00, 0x00,0x01, 0x09,0x1C, 0x00,0x01,
-0x0A,0xE0, 0x00,0x01, 0x0A,0xAC, 0x00,0x01, 0x0B,0x14, 0xF7,0x04, 0x71,0xD0, 0xF6,0x04,
-0x71,0xCC, 0x06,0xB8, 0x00,0x01, 0xC0,0x36, 0x62,0x00, 0xE6,0x01, 0x09,0x38, 0xC7,0x34,
-0x00,0x00, 0xF7,0x02, 0x00,0x00, 0xF5,0x84, 0x71,0xD4, 0x00,0x00, 0x00,0x01, 0xC0,0x3A,
-0x5A,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x09,0x85, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x71,0xB0, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x71,0xB0, 0xF7,0x04, 0x71,0xB0, 0xF7,0x04, 0x71,0xB4, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x71,0xB4, 0xF7,0x04, 0x71,0xB4, 0xE0,0x01, 0x0B,0x50, 0x00,0x00,
-0x00,0x01, 0xF4,0x84, 0x71,0xC8, 0xF6,0x85, 0x71,0xD0, 0x94,0x96, 0xFF,0xF4, 0xF4,0x84,
-0x7B,0x10, 0xC0,0x36, 0x62,0x00, 0xE6,0x01, 0x09,0xA4, 0x94,0x96, 0xFF,0xEC, 0xF0,0x05,
-0x71,0xD0, 0xF7,0x04, 0x71,0xD0, 0xF0,0x05, 0x71,0xC8, 0x84,0x96, 0xFF,0xEC, 0xC0,0x3A,
-0x5A,0x00, 0x47,0x0C, 0x00,0x01, 0xF7,0x05, 0x71,0xC4, 0x87,0x26, 0x00,0x08, 0x00,0x00,
-0x00,0x01, 0x70,0x3A, 0xFF,0xE1, 0xE6,0x01, 0x09,0xE1, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x71,0x98, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x71,0x98, 0x84,0x96,
-0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0x20,0x26, 0x00,0x00, 0xE6,0x01, 0x0A,0x71, 0x00,0x00,
-0x00,0x01, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x05,0x58, 0x97,0x93, 0xFF,0xFC, 0xF6,0x02,
-0x00,0x09, 0x20,0x32, 0x00,0x14, 0xE6,0x01, 0x0A,0x4D, 0x27,0x00, 0x00,0x0C, 0x20,0x3A,
-0x00,0x01, 0xE2,0x01, 0x0A,0x4D, 0xF7,0x06, 0x2D,0xCC, 0xF6,0x84, 0x2E,0xCC, 0x00,0x00,
-0x00,0x01, 0x75,0xB5, 0x00,0x02, 0xB6,0x2E, 0x70,0x02, 0x06,0xB4, 0x00,0x01, 0xF6,0x85,
-0x2E,0xCC, 0x86,0x02, 0xFF,0x34, 0xF7,0x06, 0x2E,0x4C, 0x20,0x36, 0x00,0x1F, 0xE2,0x01,
-0x0A,0x4D, 0xB6,0x2E, 0x70,0x02, 0xF0,0x05, 0x2E,0xCC, 0xF7,0x04, 0x2D,0x68, 0x00,0x00,
-0x00,0x01, 0x87,0x3A, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x87,0x3A, 0x00,0x28, 0x00,0x00,
-0x00,0x01, 0x07,0x88, 0x00,0x08, 0xC1,0x38, 0x00,0x00, 0x97,0x93, 0xFF,0xFC, 0xF7,0x04,
-0x71,0xBC, 0x84,0x96, 0xFF,0xEC, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x71,0xBC, 0xF7,0x04,
-0x71,0xBC, 0x86,0xA6, 0x00,0x04, 0x84,0x96, 0xFF,0xF4, 0xF7,0x04, 0x71,0xB8, 0x20,0x26,
-0x00,0x00, 0xC7,0x38, 0x68,0x00, 0xF7,0x05, 0x71,0xB8, 0xE6,0x01, 0x0B,0x51, 0x00,0x00,
-0x00,0x01, 0xE0,0x01, 0x0B,0x5C, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x71,0xC0, 0x00,0x00,
-0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x71,0xC0, 0xF7,0x04, 0x71,0xC0, 0xF4,0x84,
-0x7B,0x10, 0x00,0x00, 0x00,0x01, 0x94,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0xFD,0xCC, 0x97,0x93, 0xFF,0xFC, 0xE0,0x01, 0x0B,0x50, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x71,0xC0, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x71,0xC0, 0xF7,0x04,
-0x71,0xC0, 0xF4,0x84, 0x7B,0x10, 0x00,0x00, 0x00,0x01, 0x94,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0xFF,0x30, 0x97,0x93, 0xFF,0xFC, 0xE0,0x01, 0x0B,0x50, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x71,0xC0, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x71,0xC0, 0xF7,0x04, 0x71,0xC0, 0xF6,0x84, 0x7B,0x10, 0x87,0x02, 0xFF,0x48, 0x00,0x00,
-0x00,0x01, 0xC7,0x38, 0x6A,0x00, 0x27,0x38, 0x00,0x04, 0x97,0x13, 0xFF,0xFC, 0x96,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0xFE,0x48, 0x97,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x05,0x58, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x06, 0x70,0x80, 0xF7,0x05, 0x7B,0x18, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x05,0x58, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x06, 0x6F,0x68, 0xF7,0x05, 0x7B,0x18, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x05,0x58, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x06, 0x7B,0x18, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x6F,0x68, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x06, 0x7B,0x18, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x6F,0xF4, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06,
-0x7B,0x18, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x70,0x80, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x7B,0x18, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x71,0x0C, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF5,0x02, 0x00,0x04, 0xF5,0x05, 0x76,0x00, 0xF0,0x05,
-0x76,0x08, 0xF0,0x05, 0x76,0x04, 0xF0,0x05, 0x75,0xF8, 0xF5,0x02, 0x00,0x01, 0xF6,0x82,
-0x00,0x00, 0x20,0x36, 0x00,0x04, 0xEC,0x01, 0x0C,0xBC, 0xF5,0x05, 0x75,0xFC, 0xF5,0x8E,
-0x6A,0xF8, 0xF6,0x06, 0x75,0xF8, 0x47,0x2C, 0xFF,0xFC, 0x97,0x32, 0x00,0x18, 0x06,0x30,
-0x00,0x04, 0x06,0xB4, 0x00,0x01, 0xF7,0x04, 0x76,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xEC,0x01, 0x0C,0x99, 0x05,0xAC, 0x21,0x4C, 0xF5,0x06, 0x72,0x18, 0x95,0x13,
-0xFF,0xFC, 0xF5,0x06, 0x76,0x48, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x15,0x48, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06, 0x0D,0xF4, 0x95,0x13, 0xFF,0xFC, 0xF7,0x82,
-0x00,0x0E, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06, 0x72,0x18, 0x95,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06, 0x0D,0xF4, 0x95,0x13,
-0xFF,0xFC, 0xF7,0x82, 0x00,0x0E, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06, 0x72,0xA4, 0x95,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06,
-0x13,0x2C, 0x95,0x13, 0xFF,0xFC, 0xF7,0x82, 0x00,0x01, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06,
-0x73,0x30, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x06, 0x16,0xC8, 0x95,0x13, 0xFF,0xFC, 0xF7,0x82, 0x00,0x01, 0x97,0x93,
-0xFF,0xFC, 0xF5,0x06, 0x73,0xBC, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06, 0x18,0x00, 0x95,0x13, 0xFF,0xFC, 0xF7,0x82,
-0x00,0x10, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06, 0x74,0x48, 0x95,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06, 0x16,0x40, 0x95,0x13,
-0xFF,0xFC, 0xF7,0x82, 0x00,0x10, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06, 0x74,0xD4, 0x95,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF5,0x06,
-0x13,0x2C, 0x95,0x13, 0xFF,0xFC, 0xF5,0x02, 0x00,0x12, 0x95,0x13, 0xFF,0xFC, 0xF5,0x06,
-0x75,0x60, 0x95,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93,
-0xFF,0xFC, 0xF0,0x05, 0x75,0xF0, 0xF0,0x05, 0x75,0xEC, 0xF0,0x05, 0x75,0xF4, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x38, 0xF7,0x04,
-0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x0E,0x28, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x75,0xF0, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01,
-0x0E,0x3D, 0x00,0x00, 0x00,0x01, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x15,0xD0, 0x97,0x93,
-0xFF,0xFC, 0xE0,0x01, 0x13,0x18, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x75,0xFC, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x0E,0x59, 0xF6,0x86, 0x75,0xF8, 0xE0,0x01,
-0x0E,0x6C, 0xF6,0x82, 0x00,0x00, 0xF7,0x04, 0x76,0x08, 0x00,0x00, 0x00,0x01, 0x77,0x39,
-0x00,0x02, 0xC7,0x38, 0x68,0x00, 0x86,0xBA, 0x00,0x18, 0xF7,0x04, 0x76,0xFC, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x0E,0x90, 0xF6,0x85, 0x76,0x60, 0xF3,0x06,
-0x76,0x48, 0xF3,0x05, 0x76,0xFC, 0xE0,0x01, 0x0E,0xA4, 0xF7,0x02, 0x00,0x01, 0xF3,0x02,
-0x00,0x10, 0xF3,0x05, 0x76,0xF8, 0xF3,0x06, 0x76,0x48, 0xF3,0x05, 0x77,0x00, 0xF7,0x02,
-0x00,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x13,0x15, 0xF3,0x06, 0x74,0x48, 0xF7,0x04,
-0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x0E,0xD8, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x75,0xF0, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01,
-0x0E,0xED, 0x00,0x00, 0x00,0x01, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x16,0x40, 0x97,0x93,
-0xFF,0xFC, 0xE0,0x01, 0x13,0x18, 0x00,0x00, 0x00,0x01, 0xF6,0x84, 0x76,0x60, 0x00,0x00,
-0x00,0x01, 0x87,0x36, 0x00,0x08, 0x00,0x00, 0x00,0x01, 0x70,0x3A, 0xFF,0xE1, 0xE6,0x01,
-0x0F,0x21, 0xF4,0x82, 0x00,0x00, 0x96,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x00,0xBC, 0x97,0x93, 0xFF,0xFC, 0xE0,0x01, 0x13,0x14, 0xF3,0x06, 0x75,0x60, 0xC3,0xB4,
-0x00,0x00, 0x84,0x1E, 0x00,0x10, 0xF6,0x84, 0x4A,0xA0, 0x23,0x14, 0x00,0x20, 0x93,0x16,
-0xFF,0xC4, 0x94,0x16, 0xFF,0xE0, 0x96,0x96, 0xFF,0xD4, 0x85,0x1E, 0x00,0x14, 0xF7,0x04,
-0x4A,0x9C, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xEC,0x01, 0x10,0x0C, 0x95,0x16,
-0xFF,0xE4, 0x77,0x35, 0x00,0x01, 0xC7,0x38, 0x68,0x00, 0x77,0x39, 0x00,0x02, 0xF3,0x06,
-0x4A,0x98, 0xC6,0xB8, 0x30,0x00, 0x06,0xB4, 0x00,0x0C, 0xC5,0x84, 0x00,0x00, 0x87,0x36,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x42,0x00, 0xE6,0x01, 0x0F,0x9C, 0xC6,0x24,
-0x00,0x00, 0x87,0x36, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x52,0x00, 0xE6,0x01,
-0x0F,0xA0, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x01,
-0x0F,0xAD, 0x00,0x00, 0x00,0x01, 0xF5,0x82, 0x00,0x00, 0x86,0x36, 0x00,0x00, 0x87,0x16,
-0xFF,0xE0, 0x00,0x00, 0x00,0x01, 0xC0,0x32, 0x72,0x00, 0xE2,0x01, 0x0F,0xE8, 0xF5,0x02,
-0x00,0x00, 0xC0,0x32, 0x72,0x00, 0xE6,0x01, 0x0F,0xF0, 0x20,0x2A, 0x00,0x00, 0x86,0xB6,
-0x00,0x04, 0x87,0x16, 0xFF,0xE4, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x01,
-0x0F,0xF1, 0x20,0x2A, 0x00,0x00, 0xF5,0x02, 0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x01,
-0x10,0x01, 0x20,0x2E, 0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x01,
-0x10,0x10, 0x20,0x26, 0x00,0x00, 0xF4,0x82, 0x00,0x01, 0x20,0x26, 0x00,0x00, 0xE6,0x01,
-0x10,0x45, 0xF6,0x02, 0x00,0x01, 0x87,0x16, 0xFF,0xD4, 0xF3,0x06, 0x4A,0x98, 0x76,0xB9,
-0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4, 0x30,0x00, 0x06,0xB4,
-0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16, 0xFF,0xD8, 0xE0,0x01, 0x10,0xB8, 0x96,0x96,
-0xFF,0xDC, 0x27,0x14, 0x00,0x2C, 0x97,0x13, 0xFF,0xFC, 0x83,0x16, 0xFF,0xC4, 0x00,0x00,
-0x00,0x01, 0x93,0x13, 0xFF,0xFC, 0xF3,0x06, 0x4A,0x98, 0x93,0x13, 0xFF,0xFC, 0x93,0x96,
-0xFF,0xCC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x25,0x68, 0x97,0x93, 0xFF,0xFC, 0x83,0x96,
-0xFF,0xCC, 0x20,0x22, 0x00,0x00, 0xE6,0x01, 0x10,0xB5, 0xF6,0x02, 0x00,0x01, 0x87,0x16,
-0xFF,0xD4, 0xF3,0x06, 0x4A,0x98, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5,
-0x00,0x02, 0xC6,0xB4, 0x30,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16,
-0xFF,0xD8, 0x96,0x96, 0xFF,0xDC, 0xF7,0x05, 0x4A,0xA0, 0xE0,0x01, 0x10,0xBC, 0x20,0x32,
-0x00,0x00, 0xF6,0x02, 0x00,0x00, 0x20,0x32, 0x00,0x00, 0xE6,0x01, 0x10,0xCC, 0xF4,0x82,
-0x00,0x01, 0xE0,0x01, 0x11,0x24, 0xF4,0x82, 0x00,0x00, 0x86,0x96, 0xFF,0xD8, 0x00,0x00,
-0x00,0x01, 0x77,0x35, 0x00,0x02, 0xC7,0x38, 0x68,0x00, 0x77,0x39, 0x00,0x02, 0xF6,0x86,
-0x42,0xC8, 0xA6,0x3A, 0x68,0x02, 0xC7,0x38, 0x68,0x00, 0x75,0x39, 0x00,0x1E, 0x75,0x28,
-0xFF,0xE5, 0x05,0xB8, 0x00,0x02, 0x86,0xAE, 0x00,0x00, 0x07,0x38, 0x00,0x04, 0x97,0x16,
-0xFF,0xEC, 0xC6,0x30, 0x57,0xC0, 0x76,0x30, 0xFF,0xF0, 0x96,0x16, 0xFF,0xF4, 0x75,0xAD,
-0x00,0x1E, 0x75,0xAC, 0xFF,0xE5, 0xC6,0xB4, 0x5F,0xC0, 0x76,0xB4, 0xFF,0xF0, 0x96,0x96,
-0xFF,0xF0, 0x20,0x26, 0x00,0x00, 0xE6,0x01, 0x11,0x38, 0xF5,0x82, 0x00,0x00, 0xE0,0x01,
-0x11,0xCC, 0xF6,0x02, 0x00,0x00, 0x86,0x96, 0xFF,0xF0, 0x00,0x00, 0x00,0x01, 0xC7,0x34,
-0x68,0x00, 0xC4,0x9C, 0x72,0x00, 0xC0,0x2E, 0x6A,0x00, 0xEC,0x01, 0x11,0x98, 0xC5,0x24,
-0x00,0x00, 0xC6,0x2C, 0x00,0x00, 0x87,0x16, 0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0xA6,0xB2,
-0x70,0x02, 0x05,0xAC, 0x00,0x01, 0xC7,0x30, 0x70,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38,
-0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB4, 0xFF,0xF0, 0xF6,0xAB, 0x28,0x00, 0x05,0x28,
-0x00,0x02, 0x87,0x16, 0xFF,0xF0, 0x00,0x00, 0x00,0x01, 0xC0,0x2E, 0x72,0x00, 0xEC,0x01,
-0x11,0x59, 0x06,0x30, 0x00,0x02, 0xF3,0x02, 0x00,0x01, 0xF3,0x05, 0x76,0xF4, 0xF6,0x02,
-0x00,0x01, 0x87,0x16, 0xFF,0xF0, 0x86,0x9E, 0x00,0x04, 0xC7,0x38, 0x70,0x00, 0xC7,0x38,
-0x48,0x00, 0xC6,0xB4, 0x70,0x00, 0x87,0x16, 0xFF,0xF4, 0x06,0xB4, 0x00,0x20, 0x97,0x02,
-0xFF,0x6C, 0x94,0x82, 0xFF,0x50, 0x96,0x82, 0xFF,0x58, 0x20,0x32, 0x00,0x00, 0xE6,0x01,
-0x13,0x10, 0x00,0x00, 0x00,0x01, 0xF7,0x04, 0x76,0x5C, 0xF5,0x84, 0x76,0xF8, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x76,0x5C, 0xF7,0x04, 0x76,0x5C, 0x20,0x2E, 0x00,0x21, 0xE2,0x01,
-0x12,0x30, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x01,
-0x12,0x1C, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF3,0x02, 0x00,0x22, 0xF3,0x05,
-0x76,0xF8, 0xF3,0x04, 0x77,0x00, 0xE0,0x01, 0x12,0x34, 0xF3,0x05, 0x76,0xFC, 0xF0,0x05,
-0x76,0xFC, 0xF7,0x04, 0x75,0xF8, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01,
-0x12,0x71, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02, 0x00,0x0F, 0x20,0x32,
-0x00,0x44, 0xE6,0x01, 0x12,0x70, 0xB3,0x3A, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04,
-0x76,0x08, 0xF6,0x84, 0x76,0x00, 0x07,0x38, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x01,
-0x12,0x8C, 0xF7,0x05, 0x76,0x08, 0xF0,0x05, 0x76,0x08, 0xF6,0x84, 0x76,0x08, 0xF7,0x04,
-0x76,0x04, 0xF0,0x05, 0x75,0xF8, 0xF6,0x06, 0x75,0xF8, 0xC0,0x36, 0x72,0x00, 0x47,0x0C,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x12,0xB9, 0xF7,0x05, 0x75,0xFC, 0xE0,0x01,
-0x12,0xC8, 0xF7,0x02, 0x00,0x00, 0x77,0x35, 0x00,0x02, 0xC7,0x38, 0x60,0x00, 0x87,0x3A,
-0x00,0x18, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x13,0x09, 0xF7,0x05,
-0x76,0x60, 0xF7,0x04, 0x2D,0x38, 0xF3,0x06, 0x72,0xA4, 0xF3,0x05, 0x76,0x48, 0xF6,0x86,
-0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02,
-0x00,0x0E, 0x20,0x32, 0x00,0x44, 0xE6,0x01, 0x13,0x18, 0xB3,0x3A, 0x68,0x02, 0xE0,0x01,
-0x13,0x18, 0xF0,0x05, 0x2D,0x38, 0xE0,0x01, 0x13,0x14, 0xF3,0x06, 0x72,0x18, 0xF3,0x06,
-0x73,0x30, 0xF3,0x05, 0x76,0x48, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0xF7,0x04, 0x76,0x60, 0x00,0x00, 0x00,0x01, 0x86,0xBA, 0x00,0x04, 0xF7,0x04,
-0x76,0x54, 0x00,0x00, 0x00,0x01, 0xC7,0x38, 0x68,0x00, 0xF7,0x05, 0x76,0x54, 0xF7,0x04,
-0x76,0x58, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x76,0x58, 0xF7,0x04,
-0x75,0xF8, 0xF6,0x84, 0x76,0x58, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x13,0x9D, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF5,0x02, 0x00,0x0F, 0x20,0x32, 0x00,0x44, 0xE6,0x01,
-0x13,0x9C, 0xB5,0x3A, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04, 0x76,0x08, 0xF6,0x84,
-0x76,0x00, 0x07,0x38, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x01, 0x13,0xB8, 0xF7,0x05,
-0x76,0x08, 0xF0,0x05, 0x76,0x08, 0xF7,0x04, 0x76,0x08, 0xF6,0x84, 0x76,0x04, 0xF0,0x05,
-0x75,0xF8, 0xF5,0x84, 0x76,0xF8, 0xC0,0x3A, 0x6A,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x2E,
-0x00,0x21, 0xE2,0x01, 0x14,0x14, 0xF7,0x05, 0x75,0xFC, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86,
-0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32,
-0x00,0x44, 0xE6,0x01, 0x14,0x00, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF5,0x02,
-0x00,0x22, 0xF5,0x05, 0x76,0xF8, 0xF5,0x04, 0x77,0x00, 0xE0,0x01, 0x14,0x18, 0xF5,0x05,
-0x76,0xFC, 0xF0,0x05, 0x76,0xFC, 0xF7,0x04, 0x75,0xEC, 0xF5,0x06, 0x72,0x18, 0x20,0x3A,
-0x00,0x00, 0xE6,0x01, 0x14,0x40, 0xF5,0x05, 0x76,0x48, 0xF7,0x04, 0x75,0xF0, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x14,0x55, 0x00,0x00, 0x00,0x01, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x15,0xD0, 0x97,0x93, 0xFF,0xFC, 0xE0,0x01, 0x14,0xC4, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x75,0xFC, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01,
-0x14,0x71, 0xF6,0x86, 0x75,0xF8, 0xE0,0x01, 0x14,0x88, 0xF7,0x02, 0x00,0x00, 0xF7,0x04,
-0x76,0x08, 0x00,0x00, 0x00,0x01, 0x77,0x39, 0x00,0x02, 0xC7,0x38, 0x68,0x00, 0x87,0x3A,
-0x00,0x18, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x14,0xC5, 0xF7,0x05,
-0x76,0x60, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF5,0x02, 0x00,0x0E, 0x20,0x32, 0x00,0x44, 0xE6,0x01,
-0x14,0xBC, 0xB5,0x3A, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF5,0x06, 0x72,0xA4, 0xF5,0x05,
-0x76,0x48, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x04,
-0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x15,0x40, 0xF4,0x02,
-0x00,0x00, 0x86,0x96, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xF6,0x85, 0x75,0xEC, 0x86,0x96,
-0x00,0x08, 0x00,0x00, 0x00,0x01, 0xF6,0x85, 0x7B,0x38, 0x86,0x96, 0x00,0x00, 0xF7,0x04,
-0x76,0x48, 0xF6,0x85, 0x7B,0x30, 0xF6,0x86, 0x72,0x18, 0xC0,0x3A, 0x6A,0x00, 0x47,0x0C,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x15,0x41, 0xF4,0x02, 0x00,0x01, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x15,0xD0, 0x97,0x93, 0xFF,0xFC, 0xF4,0x02, 0x00,0x01, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x0C, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x04, 0x75,0xF4, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x15,0xBC, 0xF4,0x02, 0x00,0x00, 0x86,0x96,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0xF6,0x85, 0x75,0xF0, 0x86,0x96, 0x00,0x08, 0x00,0x00,
-0x00,0x01, 0xF6,0x85, 0x7B,0x48, 0x86,0x96, 0x00,0x00, 0xF7,0x04, 0x76,0x48, 0xF6,0x85,
-0x7B,0x40, 0xF6,0x86, 0x72,0x18, 0xC0,0x3A, 0x6A,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x01, 0x15,0xBD, 0xF4,0x02, 0x00,0x01, 0x07,0x88, 0x00,0x08, 0xE0,0x01,
-0x15,0xD0, 0x97,0x93, 0xFF,0xFC, 0xF4,0x02, 0x00,0x01, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x0C, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x04, 0x76,0xFC, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x01, 0x15,0xFC, 0xF6,0x82, 0x00,0x10, 0xF6,0x86, 0x76,0x48, 0xF6,0x85,
-0x76,0xFC, 0xE0,0x01, 0x16,0x0C, 0xF7,0x02, 0x00,0x01, 0xF6,0x85, 0x76,0xF8, 0xF6,0x86,
-0x76,0x48, 0xF6,0x85, 0x77,0x00, 0xF7,0x02, 0x00,0x00, 0x20,0x3A, 0x00,0x00, 0xE6,0x01,
-0x16,0x20, 0xF6,0x86, 0x74,0xD4, 0xE0,0x01, 0x16,0x2C, 0xF6,0x85, 0x76,0x48, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x16,0x40, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF6,0x04, 0x75,0xF0, 0x00,0x00, 0x00,0x01, 0x20,0x32,
-0x00,0x00, 0xE6,0x01, 0x16,0x85, 0xF7,0x02, 0x00,0x01, 0xF7,0x05, 0x75,0xF4, 0xF6,0x84,
-0x7B,0x48, 0xF7,0x05, 0x76,0xF4, 0xF7,0x04, 0x7B,0x40, 0xC6,0xB0, 0x68,0x00, 0x26,0xB4,
-0x00,0x04, 0x97,0x02, 0xFF,0x6C, 0x96,0x02, 0xFF,0x50, 0xE0,0x01, 0x16,0xA8, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x75,0xEC, 0xF6,0x84, 0x7B,0x38, 0xF5,0x82, 0x00,0x01, 0xF5,0x85,
-0x76,0xF4, 0xF6,0x04, 0x7B,0x30, 0xC6,0xB8, 0x68,0x00, 0x26,0xB4, 0x00,0x04, 0x96,0x02,
-0xFF,0x6C, 0x97,0x02, 0xFF,0x50, 0x96,0x82, 0xFF,0x58, 0xF5,0x86, 0x73,0xBC, 0xF5,0x85,
-0x76,0x48, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x04,
-0x7B,0x28, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0xF7,0x05, 0x7B,0x28, 0xF7,0x04,
-0x75,0xF4, 0xF6,0x84, 0x7B,0x28, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x17,0x21, 0x00,0x00,
-0x00,0x01, 0xF0,0x05, 0x75,0xF4, 0xF7,0x04, 0x75,0xEC, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x01, 0x17,0x25, 0xF0,0x05, 0x75,0xF0, 0x07,0x88, 0x00,0x08, 0xE0,0x01,
-0x16,0x40, 0x97,0x93, 0xFF,0xFC, 0xE0,0x01, 0x17,0xEC, 0x00,0x00, 0x00,0x01, 0xF0,0x05,
-0x75,0xEC, 0xF7,0x04, 0x75,0xFC, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01,
-0x17,0x41, 0xF6,0x86, 0x75,0xF8, 0xE0,0x01, 0x17,0x58, 0xF7,0x02, 0x00,0x00, 0xF7,0x04,
-0x76,0x08, 0x00,0x00, 0x00,0x01, 0x77,0x39, 0x00,0x02, 0xC7,0x38, 0x68,0x00, 0x87,0x3A,
-0x00,0x18, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x17,0x95, 0xF7,0x05,
-0x76,0x60, 0xF7,0x04, 0x2D,0x38, 0xF6,0x86, 0x2C,0x28, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF5,0x02, 0x00,0x0E, 0x20,0x32, 0x00,0x44, 0xE6,0x01,
-0x17,0x8C, 0xB5,0x3A, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xE0,0x01, 0x17,0x98, 0xF5,0x06,
-0x72,0xA4, 0xF5,0x06, 0x72,0x18, 0xF5,0x05, 0x76,0x48, 0xF5,0x84, 0x76,0xF8, 0x00,0x00,
-0x00,0x01, 0x20,0x2E, 0x00,0x21, 0xE2,0x01, 0x17,0xE8, 0xF6,0x86, 0x2C,0x28, 0xF7,0x04,
-0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39,
-0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x01, 0x17,0xD4, 0xB5,0xBA, 0x68,0x02, 0xF0,0x05,
-0x2D,0x38, 0xF5,0x02, 0x00,0x22, 0xF5,0x05, 0x76,0xF8, 0xF5,0x04, 0x77,0x00, 0xE0,0x01,
-0x17,0xEC, 0xF5,0x05, 0x76,0xFC, 0xF0,0x05, 0x76,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x38, 0xF7,0x04, 0x75,0xEC, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x18,0x34, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x75,0xF0, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x18,0x49, 0x00,0x00,
-0x00,0x01, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x16,0x40, 0x97,0x93, 0xFF,0xFC, 0xE0,0x01,
-0x1C,0x74, 0x00,0x00, 0x00,0x01, 0xF6,0x84, 0x76,0x60, 0x00,0x00, 0x00,0x01, 0x87,0x36,
-0x00,0x08, 0x00,0x00, 0x00,0x01, 0x70,0x3A, 0xFF,0xE1, 0xE6,0x01, 0x18,0x7D, 0xF4,0x82,
-0x00,0x00, 0x96,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x00,0xBC, 0x97,0x93,
-0xFF,0xFC, 0xE0,0x01, 0x1C,0x70, 0xF3,0x06, 0x75,0x60, 0xC3,0xB4, 0x00,0x00, 0x84,0x1E,
-0x00,0x10, 0xF6,0x84, 0x4A,0xA0, 0x23,0x14, 0x00,0x20, 0x93,0x16, 0xFF,0xC4, 0x94,0x16,
-0xFF,0xE0, 0x96,0x96, 0xFF,0xD4, 0x85,0x1E, 0x00,0x14, 0xF7,0x04, 0x4A,0x9C, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xEC,0x01, 0x19,0x68, 0x95,0x16, 0xFF,0xE4, 0x77,0x35,
-0x00,0x01, 0xC7,0x38, 0x68,0x00, 0x77,0x39, 0x00,0x02, 0xF3,0x06, 0x4A,0x98, 0xC6,0xB8,
-0x30,0x00, 0x06,0xB4, 0x00,0x0C, 0xC5,0x84, 0x00,0x00, 0x87,0x36, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0xC0,0x3A, 0x42,0x00, 0xE6,0x01, 0x18,0xF8, 0xC6,0x24, 0x00,0x00, 0x87,0x36,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x52,0x00, 0xE6,0x01, 0x18,0xFC, 0x20,0x32,
-0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x01, 0x19,0x09, 0x00,0x00,
-0x00,0x01, 0xF5,0x82, 0x00,0x00, 0x86,0x36, 0x00,0x00, 0x87,0x16, 0xFF,0xE0, 0x00,0x00,
-0x00,0x01, 0xC0,0x32, 0x72,0x00, 0xE2,0x01, 0x19,0x44, 0xF5,0x02, 0x00,0x00, 0xC0,0x32,
-0x72,0x00, 0xE6,0x01, 0x19,0x4C, 0x20,0x2A, 0x00,0x00, 0x86,0xB6, 0x00,0x04, 0x87,0x16,
-0xFF,0xE4, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE2,0x01, 0x19,0x4D, 0x20,0x2A,
-0x00,0x00, 0xF5,0x02, 0x00,0x01, 0x20,0x2A, 0x00,0x00, 0xE6,0x01, 0x19,0x5D, 0x20,0x2E,
-0x00,0x00, 0xF5,0x82, 0x00,0x01, 0x20,0x2E, 0x00,0x00, 0xE6,0x01, 0x19,0x6C, 0x20,0x26,
-0x00,0x00, 0xF4,0x82, 0x00,0x01, 0x20,0x26, 0x00,0x00, 0xE6,0x01, 0x19,0xA1, 0xF6,0x02,
-0x00,0x01, 0x87,0x16, 0xFF,0xD4, 0xF3,0x06, 0x4A,0x98, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4,
-0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4, 0x30,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6,
-0x00,0x00, 0x97,0x16, 0xFF,0xD8, 0xE0,0x01, 0x1A,0x14, 0x96,0x96, 0xFF,0xDC, 0x27,0x14,
-0x00,0x2C, 0x97,0x13, 0xFF,0xFC, 0x83,0x16, 0xFF,0xC4, 0x00,0x00, 0x00,0x01, 0x93,0x13,
-0xFF,0xFC, 0xF3,0x06, 0x4A,0x98, 0x93,0x13, 0xFF,0xFC, 0x93,0x96, 0xFF,0xCC, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x25,0x68, 0x97,0x93, 0xFF,0xFC, 0x83,0x96, 0xFF,0xCC, 0x20,0x22,
-0x00,0x00, 0xE6,0x01, 0x1A,0x11, 0xF6,0x02, 0x00,0x01, 0x87,0x16, 0xFF,0xD4, 0xF3,0x06,
-0x4A,0x98, 0x76,0xB9, 0x00,0x01, 0xC6,0xB4, 0x70,0x00, 0x76,0xB5, 0x00,0x02, 0xC6,0xB4,
-0x30,0x00, 0x06,0xB4, 0x00,0x14, 0x86,0xB6, 0x00,0x00, 0x97,0x16, 0xFF,0xD8, 0x96,0x96,
-0xFF,0xDC, 0xF7,0x05, 0x4A,0xA0, 0xE0,0x01, 0x1A,0x18, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x00, 0x20,0x32, 0x00,0x00, 0xE6,0x01, 0x1A,0x28, 0xF4,0x82, 0x00,0x01, 0xE0,0x01,
-0x1A,0x80, 0xF4,0x82, 0x00,0x00, 0x86,0x96, 0xFF,0xD8, 0x00,0x00, 0x00,0x01, 0x77,0x35,
-0x00,0x02, 0xC7,0x38, 0x68,0x00, 0x77,0x39, 0x00,0x02, 0xF6,0x86, 0x42,0xC8, 0xA6,0x3A,
-0x68,0x02, 0xC7,0x38, 0x68,0x00, 0x75,0x39, 0x00,0x1E, 0x75,0x28, 0xFF,0xE5, 0x05,0xB8,
-0x00,0x02, 0x86,0xAE, 0x00,0x00, 0x07,0x38, 0x00,0x04, 0x97,0x16, 0xFF,0xEC, 0xC6,0x30,
-0x57,0xC0, 0x76,0x30, 0xFF,0xF0, 0x96,0x16, 0xFF,0xF4, 0x75,0xAD, 0x00,0x1E, 0x75,0xAC,
-0xFF,0xE5, 0xC6,0xB4, 0x5F,0xC0, 0x76,0xB4, 0xFF,0xF0, 0x96,0x96, 0xFF,0xF0, 0x20,0x26,
-0x00,0x00, 0xE6,0x01, 0x1A,0x94, 0xF5,0x82, 0x00,0x00, 0xE0,0x01, 0x1B,0x28, 0xF6,0x02,
-0x00,0x00, 0x86,0x96, 0xFF,0xF0, 0x00,0x00, 0x00,0x01, 0xC7,0x34, 0x68,0x00, 0xC4,0x9C,
-0x72,0x00, 0xC0,0x2E, 0x6A,0x00, 0xEC,0x01, 0x1A,0xF4, 0xC5,0x24, 0x00,0x00, 0xC6,0x2C,
-0x00,0x00, 0x87,0x16, 0xFF,0xEC, 0x00,0x00, 0x00,0x01, 0xA6,0xB2, 0x70,0x02, 0x05,0xAC,
-0x00,0x01, 0xC7,0x30, 0x70,0x00, 0x77,0x39, 0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4,
-0x77,0xC0, 0x76,0xB4, 0xFF,0xF0, 0xF6,0xAB, 0x28,0x00, 0x05,0x28, 0x00,0x02, 0x87,0x16,
-0xFF,0xF0, 0x00,0x00, 0x00,0x01, 0xC0,0x2E, 0x72,0x00, 0xEC,0x01, 0x1A,0xB5, 0x06,0x30,
-0x00,0x02, 0xF3,0x02, 0x00,0x01, 0xF3,0x05, 0x76,0xF4, 0xF6,0x02, 0x00,0x01, 0x87,0x16,
-0xFF,0xF0, 0x86,0x9E, 0x00,0x04, 0xC7,0x38, 0x70,0x00, 0xC7,0x38, 0x48,0x00, 0xC6,0xB4,
-0x70,0x00, 0x87,0x16, 0xFF,0xF4, 0x06,0xB4, 0x00,0x20, 0x97,0x02, 0xFF,0x6C, 0x94,0x82,
-0xFF,0x50, 0x96,0x82, 0xFF,0x58, 0x20,0x32, 0x00,0x00, 0xE6,0x01, 0x1C,0x6C, 0x00,0x00,
-0x00,0x01, 0xF7,0x04, 0x76,0x5C, 0xF5,0x84, 0x76,0xF8, 0x07,0x38, 0x00,0x01, 0xF7,0x05,
-0x76,0x5C, 0xF7,0x04, 0x76,0x5C, 0x20,0x2E, 0x00,0x21, 0xE2,0x01, 0x1B,0x8C, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x32, 0x00,0x44, 0xE6,0x01, 0x1B,0x78, 0xB5,0xBA,
-0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF3,0x02, 0x00,0x22, 0xF3,0x05, 0x76,0xF8, 0xF3,0x04,
-0x77,0x00, 0xE0,0x01, 0x1B,0x90, 0xF3,0x05, 0x76,0xFC, 0xF0,0x05, 0x76,0xFC, 0xF7,0x04,
-0x75,0xF8, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x1B,0xCD, 0xF6,0x86,
-0x2C,0x28, 0xF7,0x04, 0x2D,0x38, 0x00,0x00, 0x00,0x01, 0x06,0x38, 0x00,0x01, 0xF6,0x05,
-0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02, 0x00,0x0F, 0x20,0x32, 0x00,0x44, 0xE6,0x01,
-0x1B,0xCC, 0xB3,0x3A, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0xF7,0x04, 0x76,0x08, 0xF6,0x84,
-0x76,0x00, 0x07,0x38, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0xE6,0x01, 0x1B,0xE8, 0xF7,0x05,
-0x76,0x08, 0xF0,0x05, 0x76,0x08, 0xF6,0x84, 0x76,0x08, 0xF7,0x04, 0x76,0x04, 0xF0,0x05,
-0x75,0xF8, 0xF6,0x06, 0x75,0xF8, 0xC0,0x36, 0x72,0x00, 0x47,0x0C, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x01, 0x1C,0x15, 0xF7,0x05, 0x75,0xFC, 0xE0,0x01, 0x1C,0x24, 0xF7,0x02,
-0x00,0x00, 0x77,0x35, 0x00,0x02, 0xC7,0x38, 0x60,0x00, 0x87,0x3A, 0x00,0x18, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x1C,0x65, 0xF7,0x05, 0x76,0x60, 0xF7,0x04,
-0x2D,0x38, 0xF3,0x06, 0x72,0xA4, 0xF3,0x05, 0x76,0x48, 0xF6,0x86, 0x2C,0x28, 0x06,0x38,
-0x00,0x01, 0xF6,0x05, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0xF3,0x02, 0x00,0x0E, 0x20,0x32,
-0x00,0x44, 0xE6,0x01, 0x1C,0x74, 0xB3,0x3A, 0x68,0x02, 0xE0,0x01, 0x1C,0x74, 0xF0,0x05,
-0x2D,0x38, 0xE0,0x01, 0x1C,0x70, 0xF3,0x06, 0x72,0x18, 0xF3,0x06, 0x73,0x30, 0xF3,0x05,
-0x76,0x48, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x06,
-0x76,0x48, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x72,0x18, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x76,0x48, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x72,0xA4, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x76,0x48, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x73,0x30, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x06, 0x76,0x48, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x73,0xBC, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06,
-0x76,0x48, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06, 0x74,0x48, 0x97,0x13, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x76,0x48, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x74,0xD4, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x76,0x48, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x75,0x60, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93,
-0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF6,0x86,
-0x76,0x68, 0x96,0x93, 0xFF,0xFC, 0xF6,0x86, 0x77,0x04, 0x96,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x15,0x48, 0x97,0x93, 0xFF,0xFC, 0xF6,0x86, 0x1D,0xD4, 0x96,0x93,
-0xFF,0xFC, 0x90,0x13, 0xFF,0xFC, 0xF6,0x86, 0x76,0x68, 0x96,0x93, 0xFF,0xFC, 0x07,0x88,
-0x00,0x08, 0xE0,0x00, 0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF7,0x02, 0x00,0x22, 0xF7,0x05,
-0x76,0xF4, 0xF7,0x05, 0x76,0xF8, 0xF0,0x05, 0x76,0xFC, 0xF0,0x05, 0x77,0x00, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x04, 0x76,0xF4, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x22, 0xE6,0x01, 0x1E,0x01, 0x00,0x00, 0x00,0x01, 0x97,0x13,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x84, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x06, 0x77,0x04, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x76,0x68, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF6,0x86, 0x78,0x10, 0x96,0x93, 0xFF,0xFC, 0xF6,0x86,
-0x78,0xA4, 0x96,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x48, 0x97,0x93,
-0xFF,0xFC, 0xF6,0x86, 0x1F,0xBC, 0x96,0x93, 0xFF,0xFC, 0xF6,0x82, 0x00,0x14, 0x96,0x93,
-0xFF,0xFC, 0xF6,0x86, 0x78,0x10, 0x96,0x93, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0xF0,0x05, 0x78,0x9C, 0x90,0x02, 0xFF,0x34, 0xF7,0x02,
-0x7F,0xFF, 0xF7,0x05, 0x78,0xA0, 0x97,0x02, 0xFF,0x30, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF6,0x04, 0x78,0x9C, 0x87,0x16, 0x00,0x00, 0x84,0x96,
-0x00,0x08, 0xF5,0x86, 0x77,0x10, 0x87,0x3A, 0x00,0x08, 0xF6,0x86, 0x21,0x8C, 0x75,0x39,
-0x00,0x04, 0x77,0x39, 0x00,0x02, 0xA7,0x3A, 0x68,0x02, 0x20,0x32, 0x00,0x00, 0xC6,0xA8,
-0x58,0x00, 0x84,0x16, 0x00,0x04, 0xC6,0x30, 0x75,0x80, 0x94,0x36, 0x00,0x04, 0xB4,0xAA,
-0x58,0x02, 0x87,0x36, 0x00,0x08, 0xF6,0x05, 0x78,0x9C, 0x07,0x38, 0x00,0x01, 0xE6,0x01,
-0x1F,0x2D, 0x97,0x36, 0x00,0x08, 0x87,0x02, 0xFF,0x30, 0x00,0x00, 0x00,0x01, 0xC0,0x3A,
-0x4A,0x00, 0xEE,0x01, 0x1F,0x35, 0x00,0x00, 0x00,0x01, 0xF4,0x85, 0x78,0xA0, 0x94,0x82,
-0xFF,0x30, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x0C, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x85,0x96,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x87,0x2E, 0x00,0x08, 0xF6,0x86, 0x21,0x8C, 0x77,0x39,
-0x00,0x02, 0xA7,0x3A, 0x68,0x02, 0xF6,0x04, 0x78,0x9C, 0xC7,0x04, 0x76,0x00, 0x86,0xAE,
-0x00,0x08, 0xC6,0x30, 0x74,0x00, 0xF7,0x06, 0x77,0x10, 0xF6,0x05, 0x78,0x9C, 0x76,0xB5,
-0x00,0x04, 0xC6,0xB4, 0x70,0x00, 0x87,0x36, 0x00,0x08, 0x20,0x32, 0x00,0x00, 0x07,0x38,
-0x00,0x01, 0xE6,0x01, 0x1F,0xA8, 0x97,0x36, 0x00,0x08, 0xF7,0x02, 0x7F,0xFF, 0xF7,0x05,
-0x78,0xA0, 0x97,0x02, 0xFF,0x30, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0x22,0x10, 0x00,0x08, 0xF7,0x04, 0x78,0x9C, 0x00,0x00, 0x00,0x01, 0x20,0x3A,
-0x00,0x00, 0xE6,0x01, 0x20,0xD1, 0xF6,0x02, 0x7F,0xFF, 0x96,0x16, 0xFF,0xF4, 0xF6,0x84,
-0x2D,0x40, 0xF6,0x06, 0x77,0x10, 0x26,0xB4, 0x00,0x01, 0x77,0x35, 0x00,0x04, 0xC4,0xB8,
-0x60,0x00, 0xC3,0x38, 0x00,0x00, 0x74,0x35, 0x00,0x02, 0xF6,0x06, 0x77,0x10, 0xC0,0x26,
-0x62,0x00, 0xEC,0x01, 0x20,0xC1, 0xF6,0x06, 0x21,0x8C, 0xF3,0x84, 0x78,0x9C, 0xA7,0x22,
-0x60,0x02, 0x00,0x00, 0x00,0x01, 0xC0,0x1E, 0x74,0x00, 0xE6,0x01, 0x20,0xB1, 0x00,0x00,
-0x00,0x01, 0x86,0xA6, 0x00,0x00, 0xF7,0x04, 0x78,0xA0, 0x00,0x00, 0x00,0x01, 0xC6,0xB4,
-0x72,0x00, 0x20,0x36, 0x00,0x00, 0xEE,0x01, 0x20,0x98, 0x96,0xA6, 0x00,0x00, 0xF7,0x04,
-0x2D,0x38, 0xF6,0x06, 0x77,0x10, 0xC5,0x18, 0x60,0x00, 0xF6,0x86, 0x2C,0x28, 0x86,0x2A,
-0x00,0x04, 0x05,0xB8, 0x00,0x01, 0xF5,0x85, 0x2D,0x38, 0x77,0x39, 0x00,0x02, 0x20,0x2E,
-0x00,0x44, 0xE6,0x01, 0x20,0x70, 0xB6,0x3A, 0x68,0x02, 0xF0,0x05, 0x2D,0x38, 0x86,0x2A,
-0x00,0x08, 0x00,0x00, 0x00,0x01, 0x96,0x2A, 0x00,0x0C, 0xF6,0x06, 0x21,0x8C, 0xA7,0x22,
-0x60,0x02, 0x00,0x00, 0x00,0x01, 0xC7,0x04, 0x76,0x00, 0xC7,0x1C, 0x74,0x00, 0xE0,0x01,
-0x20,0xB0, 0xF7,0x05, 0x78,0x9C, 0x86,0x16, 0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x62,0x00, 0xEC,0x01, 0x20,0xB0, 0x00,0x00, 0x00,0x01, 0x96,0x96, 0xFF,0xF4, 0x24,0xA4,
-0x00,0x10, 0x23,0x18, 0x00,0x10, 0xE0,0x01, 0x1F,0xFC, 0x24,0x20, 0x00,0x04, 0x86,0x16,
-0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0xF6,0x05, 0x78,0xA0, 0x96,0x02, 0xFF,0x30, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x87,0x16, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x87,0x3A, 0x00,0x08, 0xF6,0x86, 0x77,0x10, 0x77,0x39, 0x00,0x04, 0xC7,0x38,
-0x68,0x00, 0x86,0xBA, 0x00,0x0C, 0x87,0x3A, 0x00,0x08, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0x44,0x0C, 0x00,0x01, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x04, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0xF7,0x02, 0x00,0x0F, 0x20,0x3A, 0x00,0x00, 0xEC,0x01, 0x21,0x5D, 0xF6,0x86,
-0x77,0x18, 0x90,0x36, 0x00,0x00, 0x27,0x38, 0x00,0x01, 0xC6,0x04, 0x00,0x00, 0xC0,0x3A,
-0x62,0x00, 0xE6,0x01, 0x21,0x44, 0x06,0xB4, 0x00,0x10, 0xF6,0x06, 0x78,0xA4, 0x96,0x13,
-0xFF,0xFC, 0xF6,0x06, 0x78,0x10, 0x96,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x01, 0x00,0x00,
-0x00,0x02, 0x00,0x00, 0x00,0x04, 0x00,0x00, 0x00,0x08, 0x00,0x00, 0x00,0x10, 0x00,0x00,
-0x00,0x20, 0x00,0x00, 0x00,0x40, 0x00,0x00, 0x00,0x80, 0x00,0x00, 0x01,0x00, 0x00,0x00,
-0x02,0x00, 0x00,0x00, 0x04,0x00, 0x00,0x00, 0x08,0x00, 0x00,0x00, 0x10,0x00, 0x00,0x00,
-0x20,0x00, 0x00,0x00, 0x40,0x00, 0x00,0x00, 0x80,0x00, 0x00,0x00, 0x00,0x00, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x06, 0x78,0xB0, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x79,0xCC, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x15,0x48, 0x97,0x93,
-0xFF,0xFC, 0xF7,0x06, 0x22,0x2C, 0x97,0x13, 0xFF,0xFC, 0xF7,0x02, 0x00,0x15, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x78,0xB0, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x16,0x1C, 0x97,0x93, 0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14,
-0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90,
-0x00,0x08, 0xF6,0x84, 0x6F,0x44, 0x00,0x00, 0x00,0x01, 0x87,0x36, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x20,0x3A, 0x00,0x02, 0xE6,0x01, 0x22,0x70, 0xF6,0x02, 0x00,0x00, 0x87,0x36,
-0x0E,0xF4, 0x86,0xB6, 0x0E,0xF8, 0x00,0x00, 0x00,0x01, 0xC0,0x3A, 0x6A,0x00, 0x47,0x0C,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x22,0x78, 0x20,0x32, 0x00,0x00, 0xF6,0x02,
-0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x01, 0x22,0x94, 0x00,0x00, 0x00,0x01, 0xF7,0x04,
-0x32,0xE8, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x22,0xB1, 0xF5,0x82,
-0x03,0xE8, 0x0F,0x81, 0x40,0x00, 0xF7,0x04, 0x79,0xC8, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0xF7,0x05, 0x79,0xC8, 0xF7,0x04, 0x79,0xC8, 0xF5,0x82, 0x03,0xE8, 0x95,0x93,
-0xFF,0xFC, 0xF5,0x82, 0x00,0x15, 0x95,0x93, 0xFF,0xFC, 0xF5,0x86, 0x79,0xCC, 0x95,0x93,
-0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x1E,0xC0, 0x97,0x93, 0xFF,0xFC, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x06, 0x79,0xCC, 0x97,0x13,
-0xFF,0xFC, 0xF7,0x06, 0x78,0xB0, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00,
-0x14,0xF4, 0x97,0x93, 0xFF,0xFC, 0xF7,0x06, 0x79,0xCC, 0x97,0x13, 0xFF,0xFC, 0xF7,0x06,
-0x79,0x3C, 0x97,0x13, 0xFF,0xFC, 0x07,0x88, 0x00,0x08, 0xE0,0x00, 0x14,0xF4, 0x97,0x93,
-0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC1,0x3C, 0x00,0x00, 0x02,0x10, 0x00,0x04, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x0C, 0x85,0x96, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x86,0xAE, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x01,
-0x23,0x84, 0x27,0x14, 0x00,0x0C, 0x87,0x2E, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x01, 0x97,0x2E, 0x00,0x04, 0x87,0x2E, 0x00,0x04, 0xE0,0x01, 0x24,0x34, 0x96,0x96,
-0xFF,0xF4, 0x97,0x13, 0xFF,0xFC, 0x85,0x16, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x95,0x13,
-0xFF,0xFC, 0x95,0x93, 0xFF,0xFC, 0x95,0x96, 0xFF,0xEC, 0x07,0x88, 0x00,0x08, 0xE0,0x01,
-0x25,0x68, 0x97,0x93, 0xFF,0xFC, 0x85,0x96, 0xFF,0xEC, 0x20,0x22, 0x00,0x00, 0xE6,0x01,
-0x24,0x34, 0x00,0x00, 0x00,0x01, 0x86,0xAE, 0x00,0x04, 0x86,0x16, 0xFF,0xF4, 0x00,0x00,
-0x00,0x01, 0xC0,0x36, 0x62,0x00, 0xEE,0x01, 0x24,0x21, 0x77,0x35, 0x00,0x01, 0xC7,0x38,
-0x68,0x00, 0x77,0x39, 0x00,0x02, 0xC6,0xB8, 0x58,0x00, 0x77,0x31, 0x00,0x01, 0xC7,0x38,
-0x60,0x00, 0x77,0x39, 0x00,0x02, 0xC7,0x38, 0x58,0x00, 0x85,0x36, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x95,0x36, 0x00,0x0C, 0x85,0x36, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x95,0x36,
-0x00,0x10, 0x85,0x36, 0x00,0x08, 0x00,0x00, 0x00,0x01, 0x95,0x36, 0x00,0x14, 0x26,0xB4,
-0x00,0x0C, 0xC0,0x36, 0x72,0x00, 0xEE,0x01, 0x23,0xEC, 0x00,0x00, 0x00,0x01, 0x87,0x2E,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0x07,0x38, 0x00,0x01, 0x97,0x2E, 0x00,0x04, 0x87,0x2E,
-0x00,0x04, 0x86,0x96, 0xFF,0xF4, 0x85,0x16, 0x00,0x04, 0x77,0x35, 0x00,0x01, 0xC7,0x38,
-0x68,0x00, 0x77,0x39, 0x00,0x02, 0xC7,0x2C, 0x70,0x00, 0x85,0x2A, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x95,0x3A, 0x00,0x0C, 0x85,0x16, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x85,0x2A,
-0x00,0x04, 0x00,0x00, 0x00,0x01, 0x95,0x3A, 0x00,0x10, 0x85,0x16, 0x00,0x08, 0xF4,0x02,
-0x00,0x01, 0x95,0x3A, 0x00,0x14, 0x96,0xAE, 0x00,0x08, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x0C, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x0C, 0x85,0x96, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x84,0x2E, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x20,0x22, 0x00,0x00, 0xE6,0x01,
-0x25,0x55, 0x27,0x14, 0x00,0x0C, 0x97,0x13, 0xFF,0xFC, 0x85,0x16, 0x00,0x04, 0x00,0x00,
-0x00,0x01, 0x95,0x13, 0xFF,0xFC, 0x95,0x93, 0xFF,0xFC, 0x95,0x96, 0xFF,0xEC, 0x07,0x88,
-0x00,0x08, 0xE0,0x01, 0x25,0x68, 0x97,0x93, 0xFF,0xFC, 0x85,0x96, 0xFF,0xEC, 0x20,0x22,
-0x00,0x00, 0xE6,0x01, 0x25,0x55, 0x00,0x00, 0x00,0x01, 0x86,0x16, 0xFF,0xF4, 0x00,0x00,
-0x00,0x01, 0x20,0x32, 0x00,0x00, 0xEE,0x01, 0x25,0x45, 0x77,0x31, 0x00,0x01, 0xC6,0xAC,
-0x00,0x00, 0xC7,0x38, 0x60,0x00, 0x77,0x39, 0x00,0x02, 0xC7,0x38, 0x58,0x00, 0x85,0x36,
-0x00,0x18, 0x00,0x00, 0x00,0x01, 0x95,0x36, 0x00,0x0C, 0x85,0x36, 0x00,0x1C, 0x00,0x00,
-0x00,0x01, 0x95,0x36, 0x00,0x10, 0x85,0x36, 0x00,0x20, 0x00,0x00, 0x00,0x01, 0x95,0x36,
-0x00,0x14, 0x06,0xB4, 0x00,0x0C, 0xC0,0x36, 0x72,0x00, 0xEC,0x01, 0x25,0x11, 0x00,0x00,
-0x00,0x01, 0x87,0x2E, 0x00,0x04, 0xF4,0x02, 0x00,0x01, 0x27,0x38, 0x00,0x01, 0x97,0x2E,
-0x00,0x04, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x08, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10,
-0x00,0x08, 0x83,0x96, 0x00,0x04, 0x83,0x16, 0x00,0x00, 0xC5,0x00, 0x00,0x00, 0x84,0x1A,
-0x00,0x04, 0xC4,0xA8, 0x00,0x00, 0x94,0x16, 0xFF,0xF4, 0xC0,0x26, 0x42,0x00, 0xE6,0x01,
-0x26,0xD1, 0x00,0x00, 0x00,0x01, 0x83,0x16, 0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0xC0,0x2A,
-0x32,0x00, 0xE6,0x01, 0x26,0xD1, 0xC7,0x20, 0x4A,0x00, 0x95,0x16, 0xFF,0xF4, 0x76,0xB8,
-0xFF,0xE1, 0xC7,0x38, 0x68,0x00, 0x77,0x39, 0xFF,0xFF, 0xC5,0x24, 0x70,0x00, 0x77,0x29,
-0x00,0x01, 0xC7,0x38, 0x50,0x00, 0x77,0x39, 0x00,0x02, 0x83,0x16, 0x00,0x00, 0x86,0x9E,
-0x00,0x00, 0xC5,0xB8, 0x30,0x00, 0x05,0xAC, 0x00,0x0C, 0x87,0x2E, 0x00,0x00, 0xC6,0x00,
-0x00,0x00, 0xC0,0x36, 0x72,0x00, 0xE6,0x01, 0x26,0x10, 0x20,0x32, 0x00,0x00, 0x86,0x9E,
-0x00,0x04, 0x87,0x2E, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36, 0x72,0x00, 0xE6,0x01,
-0x26,0x10, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32, 0x00,0x00, 0xE6,0x01,
-0x26,0x25, 0x00,0x00, 0x00,0x01, 0xC7,0x00, 0x00,0x00, 0xE0,0x01, 0x26,0x78, 0x20,0x3A,
-0x00,0x00, 0x86,0x9E, 0x00,0x00, 0x87,0x2E, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE2,0x01, 0x26,0x5C, 0x00,0x00, 0x00,0x01, 0xE6,0x01, 0x26,0x64, 0x20,0x32,
-0x00,0x00, 0x86,0x9E, 0x00,0x04, 0x87,0x2E, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC0,0x36,
-0x72,0x00, 0xE2,0x01, 0x26,0x65, 0x20,0x32, 0x00,0x00, 0xF6,0x02, 0x00,0x01, 0x20,0x32,
-0x00,0x00, 0x47,0x04, 0xFF,0xFF, 0xE6,0x01, 0x26,0x79, 0x20,0x3A, 0x00,0x00, 0xF7,0x02,
-0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x26,0xB1, 0x20,0x3A, 0x00,0x00, 0xEE,0x01,
-0x26,0xA0, 0x20,0x3A, 0x00,0x01, 0x43,0x04, 0xFF,0xFF, 0xC0,0x3A, 0x32,0x00, 0xE6,0x01,
-0x26,0xC9, 0xC0,0x26, 0x42,0x00, 0xE0,0x01, 0x25,0x90, 0x00,0x00, 0x00,0x01, 0xE6,0x01,
-0x26,0xC1, 0xC0,0x26, 0x42,0x00, 0xE0,0x01, 0x25,0x90, 0x00,0x00, 0x00,0x01, 0x83,0x16,
-0x00,0x08, 0xF4,0x02, 0x00,0x01, 0xE0,0x01, 0x26,0xE0, 0x95,0x1A, 0x00,0x00, 0xE0,0x01,
-0x25,0x8C, 0xC4,0xA8, 0x00,0x00, 0xE0,0x01, 0x25,0x8C, 0xC4,0x28, 0x00,0x00, 0x83,0x16,
-0x00,0x08, 0x00,0x00, 0x00,0x01, 0x94,0x1A, 0x00,0x00, 0xC4,0x00, 0x00,0x00, 0x87,0x96,
-0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x0C, 0x01,0x3C, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x85,0x96,
-0x00,0x04, 0x84,0x16, 0x00,0x00, 0x84,0x96, 0x00,0x08, 0xF7,0x02, 0x00,0x03, 0xC6,0xA0,
-0x4D,0x80, 0xC6,0xB6, 0x74,0x00, 0xE6,0x01, 0x27,0x71, 0xC6,0x20, 0x00,0x00, 0x20,0x36,
-0x00,0x02, 0xE6,0x01, 0x27,0xA0, 0xC5,0x20, 0x48,0x00, 0xC7,0x20, 0x48,0x00, 0x27,0x38,
-0x00,0x02, 0xC0,0x22, 0x72,0x00, 0xE2,0x01, 0x27,0x9C, 0xC5,0x38, 0x00,0x00, 0x87,0x2E,
-0x00,0x00, 0x76,0xAD, 0x00,0x1E, 0x76,0xB4, 0xFF,0xE5, 0xC7,0x38, 0x6F,0xC0, 0x77,0x38,
-0xFF,0xF0, 0xF7,0x33, 0x28,0x00, 0x06,0x30, 0x00,0x02, 0xC0,0x32, 0x52,0x00, 0xE2,0x01,
-0x27,0x41, 0x05,0xAC, 0x00,0x02, 0xE0,0x01, 0x27,0xA0, 0xC5,0x20, 0x48,0x00, 0xC7,0x20,
-0x48,0x00, 0x27,0x38, 0x00,0x04, 0xC0,0x22, 0x72,0x00, 0xE2,0x01, 0x27,0xA0, 0xC5,0x20,
-0x48,0x00, 0x83,0xAD, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0x93,0xB1, 0x00,0x04, 0xC0,0x32,
-0x72,0x00, 0xE2,0x01, 0x27,0x85, 0x00,0x00, 0x00,0x01, 0xC5,0x20, 0x48,0x00, 0xC0,0x32,
-0x52,0x00, 0xE4,0x01, 0x27,0xD5, 0x00,0x00, 0x00,0x01, 0x86,0xAE, 0x00,0x00, 0x77,0x2D,
-0x00,0x1E, 0x77,0x38, 0xFF,0xE5, 0xC6,0xB4, 0x77,0xC0, 0x76,0xB5, 0xFF,0xE8, 0xF6,0xB3,
-0x68,0x00, 0x06,0x30, 0x00,0x01, 0xC0,0x32, 0x52,0x00, 0xE4,0x01, 0x27,0xAC, 0x05,0xAC,
-0x00,0x01, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x0C, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x84,0x16,
-0x00,0x00, 0x86,0x96, 0x00,0x04, 0x00,0x00, 0x00,0x01, 0xC7,0x22, 0x6D,0x80, 0xE6,0x01,
-0x28,0x10, 0x20,0x36, 0x00,0x00, 0xE0,0x01, 0x28,0x74, 0xC4,0x38, 0x00,0x00, 0xF7,0x02,
-0x00,0x01, 0xEE,0x01, 0x28,0x41, 0xF6,0x02, 0x00,0x00, 0x76,0xB5, 0x00,0x01, 0x20,0x36,
-0x00,0x00, 0xEE,0x01, 0x28,0x1C, 0x77,0x39, 0x00,0x01, 0xE0,0x01, 0x28,0x44, 0x20,0x22,
-0x00,0x00, 0x74,0x21, 0x00,0x01, 0x77,0x38, 0xFF,0xFF, 0x06,0x30, 0x00,0x01, 0x20,0x22,
-0x00,0x00, 0xEE,0x01, 0x28,0x34, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x28,0x71, 0x00,0x00,
-0x00,0x01, 0xC0,0x22, 0x6A,0x00, 0xE4,0x01, 0x28,0x64, 0x00,0x00, 0x00,0x01, 0xC4,0x20,
-0x6A,0x00, 0x77,0x3A, 0xFF,0xFF, 0xE6,0x01, 0x28,0x54, 0x76,0xB4, 0xFF,0xFF, 0xD4,0x20,
-0x07,0x62, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x08, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10,
-0x00,0x04, 0xE0,0x01, 0x28,0xCC, 0xF7,0x06, 0x29,0xDC, 0x86,0xBA, 0x00,0x00, 0x00,0x00,
-0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x01, 0x28,0xC9, 0x00,0x00, 0x00,0x01, 0x97,0x16,
-0xFF,0xF4, 0x07,0x88, 0x00,0x08, 0xC1,0x34, 0x00,0x00, 0x97,0x93, 0xFF,0xFC, 0x87,0x16,
-0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0x27,0x38, 0x00,0x04, 0xF6,0x06, 0x29,0xE0, 0xC0,0x3A,
-0x62,0x00, 0xE4,0x01, 0x28,0x9D, 0x00,0x00, 0x00,0x01, 0x87,0x96, 0xFF,0xFC, 0x82,0x96,
-0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93,
-0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0x22,0x10, 0x00,0x04, 0xE0,0x01, 0x29,0x34, 0xF7,0x06,
-0x29,0x98, 0x86,0xBA, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x20,0x36, 0x00,0x00, 0xE6,0x01,
-0x29,0x31, 0x00,0x00, 0x00,0x01, 0x97,0x16, 0xFF,0xF4, 0x07,0x88, 0x00,0x08, 0xC1,0x34,
-0x00,0x00, 0x97,0x93, 0xFF,0xFC, 0x87,0x16, 0xFF,0xF4, 0x00,0x00, 0x00,0x01, 0x07,0x38,
-0x00,0x04, 0xF6,0x06, 0x29,0xE0, 0xC0,0x3A, 0x62,0x00, 0xE4,0x01, 0x29,0x04, 0x00,0x00,
-0x00,0x01, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x92,0x93, 0xFF,0xFC, 0x02,0x90, 0x00,0x08, 0xF7,0x04,
-0x7B,0x50, 0x00,0x00, 0x00,0x01, 0x20,0x3A, 0x00,0x00, 0xE6,0x01, 0x29,0x84, 0xF6,0x82,
-0x00,0x01, 0xF6,0x85, 0x7B,0x50, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x28,0xF0, 0x97,0x93,
-0xFF,0xFC, 0x87,0x96, 0xFF,0xFC, 0x82,0x96, 0xFF,0xF8, 0x02,0x14, 0x00,0x00, 0x01,0x3C,
-0x00,0x00, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x0B,0x4C, 0x00,0x00, 0x00,0x00, 0x00,0x00,
-0x42,0x88, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x5E,0x50, 0x00,0x00, 0x00,0x00, 0x00,0x00,
-0xC7,0xA8, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x0B,0xD0, 0x00,0x00, 0x00,0x00, 0x00,0x01,
-0x1C,0x88, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x1E,0x14, 0x00,0x00, 0x00,0x00, 0x00,0x01,
-0x21,0x2C, 0x00,0x00, 0x00,0x00, 0x00,0x01, 0x22,0xE4, 0x00,0x00, 0x00,0x00, } ;
-
-
-/* This is the LANai data */
-
-static unsigned int __devinitdata lanai4_data_off = 0x94F0; /* half-word offset */
-static unsigned char __devinitdata lanai4_data[20472];
-
-
-#ifdef SYMBOL_DEFINES_COMPILED
-/* These are half-word addresses - NOT byte offsets */
-#define MYRI_GenerateMapVersion 0xBD08
-#define MYRI_MoreToGenerate 0xBD0C
-#define MYRI_GenerateMessage 0xBCEC
-#define MYRI_RelayMapVersion 0xBD04
-#define MYRI_RelayStart 0xBD00
-#define MYRI_RelayDirection 0xBCFC
-#define MYRI_RelayIndex 0xBCF4
-#define MYRI_RelayStop 0xBCF8
-#define MYRI_RelayMessage 0xBCF0
-#define MYRI_BroadcastRelayMessagesSent 0xBD10
-#define MYRI_SendMultiplexGrabbed 0xBD3C
-#define MYRI_HostReceiveItem 0xBD14
-#define MYRI_HostReceiveNumScatters 0xBD50
-#define MYRI_HostReceiveScatterIndex 0xBD44
-#define MYRI_HostReceiveScatterPointer 0xBD4C
-#define MYRI_HostReceiveScatterLength 0xBD48
-#define MYRI_HostReceiveChecksum 0xBD40
-#define MYRI_RouteNumFragments 0xBD60
-#define MYRI_RouteFragment 0xBD5C
-#define MYRI_RouteStamp 0xBD58
-#define MYRI_RoutesSoFar 0xBD64
-#define MYRI_MapVersionChanged 0xBD68
-#define MYRI_map_c 0xBD54
-#define MYRI_pack_list 0x789C
-#define MYRI_pack_table 0x78BA
-#define MYRI_msg2event 0x7FF6
-#define MYRI_VersionString 0xB7A0
-#define MYRI_SizeofChannel 0xBD80
-#define MYRI_EndOfQueueSpace 0xBD84
-#define MYRI_FreeCode 0xBD78
-#define MYRI_FreeData 0xBD7C
-#define MYRI_Asserting 0xBD6C
-#define MYRI_Version 0xBD74
-#define MYRI_Processor 0xBD70
-#define MYRI_NetReceive 0xBD8C
-#define MYRI_NetReceiveBuffer 0xBD88
-#define MYRI_MapLength 0xBD9C
-#define MYRI_MapSendAlignment 0xBD98
-#define MYRI_HostReplyLength 0xBDA4
-#define MYRI_HostReplySendAlignment 0xBDA0
-#define MYRI_MapSendMessages 0xBD94
-#define MYRI_bitmask 0x90C6
-#define MYRI_HostSendFull 0x99C0
-#define MYRI_HostReplies 0xA04C
-#define MYRI_Interrupts 0xBCE4
-#define MYRI_NetReceiveDrops 0xB8DA
-#define MYRI_SendMultiplexDoneEvent 0xBB7A
-#define MYRI_bEvents 0x96E6
-#define MYRI_bHostReceiveShortcuts 0x9972
-#define MYRI_the_map 0xB728
-#define MYRI_Channels 0xB7A2
-#define MYRI_bEventIndex 0x9766
-#define MYRI_NoBuffersChannel0 0x9974
-#define MYRI_bShakes 0x976A
-#define MYRI_MAPPER 0xA122
-#define MYRI_CORE_timeout_counter 0xA114
-#define MYRI_the_map_is_valid 0xA040
-#define MYRI_bBadScatters 0x9970
-#define MYRI_HostReceiveChannel 0x9960
-#define MYRI_send_space 0xA7B0
-#define MYRI_MapReceiveMessages 0xB8E0
-#define MYRI_wakeup_mask 0xBC4E
-#define MYRI_NetSendBuffer 0xBB30
-#define MYRI_HostReceiveMulticast 0x9968
-#define MYRI_HostSendChannel 0x9A94
-#define MYRI_NetReceiveDmaDone 0xB7FA
-#define MYRI_HostSendChecksum 0x9AAA
-#define MYRI_HostReceiveScatter 0x9914
-#define MYRI_compares 0x9DC8
-#define MYRI_NetSendQueue 0xBAFC
-#define MYRI_HostTable 0xA54C
-#define MYRI_map_h 0x9DB4
-#define MYRI_HostSendBytes 0x9AA0
-#define MYRI_L3_end_loaded_memory 0xBDB4
-#define MYRI_NetSendBytes 0xBB2A
-#define MYRI_map_space 0xA81C
-#define MYRI_MAP_ACK 0xA045
-#define MYRI_NetReceiveMisroutes 0xB8D6
-#define MYRI_HostReceiveBytes 0x995C
-#define MYRI_BroadcastRelayIdle 0x95C2
-#define MYRI_HostReceiveIdle 0x9770
-#define MYRI_timing 0xBC08
-#define MYRI_HostReceive 0x996A
-#define MYRI_routeHandleMessage 0x7732
-#define MYRI_Freses 0xB7AE
-#define MYRI_NextToPut 0x969C
-#define MYRI_HostSendIdle 0x997A
-#define MYRIedata 0xBCEC
-#define MYRI_SendingHostReply 0xBAFA
-#define MYRI_timing_period 0xBC50
-#define MYRI_debug 0xA138
-#define MYRI_NetSendBusy 0xB998
-#define MYRI_routeInitialize 0x6AA0
-#define MYRI_HostReceiveQueue 0x9966
-#define MYRI_bWakes 0x9768
-#define MYRI_NetReceiveBadLengths 0xB8D0
-#define MYRI_NetReceiveQueue 0xB8E2
-#define MYRI_MapBuffer 0xBAF6
-#define MYRI_MapChecksum 0xA048
-#define MYRI_the_routes_are_valid 0xA042
-#define MYRI_MAPPER_probe_stamp 0xA132
-#define MYRI_memory 0xA7AC
-#define MYRI_Events 0x9614
-#define MYRI_switches 0x9DB6
-#define MYRI_Hosts 0xA7AE
-#define MYRI_HostReceiveGoingToBroadcast 0x98CE
-#define MYRI_NetSendIdle 0xB90C
-#define MYRI_host_reply_space 0xB72C
-#define MYRI_HostReceiveWaitingToBroadcast 0x9888
-#define MYRI_bSetRoutes 0xA11E
-#define MYRI_bSends 0x976C
-#define MYRI_BroadcastGenerateIdle 0x9536
-#define MYRI_WatchdogOff 0xBC9E
-#define MYRI_TIMER 0xBC52
-#define MYRI_SendMultiplex 0xBB82
-#define MYRI_HostReplyBuffer 0xBAF8
-#define MYRI_the_new_switch 0xA130
-#define MYRI_current_switch 0xA03A
-#define MYRI_memcpy 0x937C
-#define MYRI_server 0x9AF6
-#define MYRI_WatchdogOn 0xBC58
-#define MYRI_NetSendContinuing 0xB952
-#define MYRI_NetReceiveBadChannels 0xB8D2
-#define MYRI_SendMultiplexFreeMachine 0xBB80
-#define MYRI_NetReceiveFlush 0xB840
-#define MYRI_NetSendBroadcasting 0xBAB0
-#define MYRI_looking_for_a_loopback 0x9D6C
-#define MYRI_HostSendGatherPointer 0x9AA8
-#define MYRI_HostSendItem 0x9A96
-#define MYRI_MAP_REQ 0xA046
-#define MYRI_memory_free_list 0xA160
-#define MYRIend 0xBDB4
-#define MYRI_MapVersion 0x9DB2
-#define MYRI_client 0x9AB0
-#define MYRI_HostReceiveBroadcasting 0x9842
-#define MYRIetext 0x94F0
-#define MYRI_NetSendMapBusy 0xB9DE
-#define MYRI_bRouteMessages 0xA134
-#define MYRI_DmaDirection 0xB7A8
-#define MYRI_SendMultiplexFreeEvent 0xBB7C
-#define MYRI_idle_mapper 0x9B3C
-#define MYRI_NetSend 0xBB24
-#define MYRI_current_port 0xA03E
-#define MYRI_HostConnectedSwitches 0x9DDA
-#define MYRI_try_loopback 0x9B82
-#define MYRI_the_host_reply_message 0xB72A
-#define MYRI_MAPPER_queue 0x9DD8
-#define MYRI_bHostSendShortcuts 0x9AAC
-#define MYRI_BroadcastGenerate 0x9608
-#define MYRI_DmaFreeEvent 0xB7AC
-#define MYRI_host_timeout_counter 0xA116
-#define MYRI_NetReceiveDma 0xB7B4
-#define MYRI_MAPPER_try_port 0xA12C
-#define MYRI_bcopy 0x66AA
-#define MYRI_queue_h 0xBB32
-#define MYRI_bUpdates 0xA120
-#define MYRI_SendMultiplexMachine 0xBB7E
-#define MYRI_MAPPER_repeat 0xA12A
-#define MYRI_the_return_port 0xA038
-#define MYRI_NetReceiveFull 0xB886
-#define MYRI_MyHostTableIndex 0xA7AA
-#define MYRI_CORE 0xA118
-#define MYRI_I_have_a_map 0xA044
-#define MYRI_bWaiting 0xB7B0
-#define MYRI_NetReceiveOverflows 0xB8D8
-#define MYRI_NumMachines 0x96A0
-#define MYRI_MapMessagesSentCounter 0xB79C
-#define MYRI_HostReceiveBuffer 0x9962
-#define MYRI_HostSendDma 0x9A4C
-#define MYRI_NextToGet 0x969E
-#define MYRI_HostReceiveDmaBusy 0x97B6
-#define MYRI_bUpdateMessages 0xA136
-#define MYRI_try_the_switch 0x9C0E
-#define MYRI_BroadcastRelay 0x960E
-#define MYRI_the_msg 0xB798
-#define MYRI_bEventsRTC 0x9726
-#define MYRI_HostReceiveMessages 0x995E
-#define MYRI_CURRENT_MSG 0xB79A
-#define MYRI_MAPPER_phase 0xA128
-#define MYRI_HostReceiveDma 0x97FC
-#define MYRI_Watchdog 0xBCE6
-#define MYRI_HostSendEmpty 0x9A92
-#define MYRI_abort 0x63C6
-#define MYRI_SendMultiplexIdle 0xBB34
-#define MYRI_looking_for_a_switch 0x9C54
-#define MYRI_NetSendMessages 0xBB2C
-#define MYRI_updating 0x9D26
-#define MYRI_BroadcastGenerateSending 0x94F0
-#define MYRI_HostSendBuffer 0x9AA4
-#define MYRI_HostSendMessages 0x9A9E
-#define MYRI_BroadcastRelaySending 0x957C
-#define MYRI_HostSendDmaBusy 0x9A06
-#define MYRI_BroadcastsPending 0xB8CC
-#define MYRI_NetSendMapWaiting 0xBA6A
-#define MYRI_NetReceiveBadTypes 0xB8CE
-#define MYRI_looking_for_hosts 0x9C9A
-#define MYRI_bBadHeader 0x9978
-#define MYRI_HostSendGatherIndex 0x9AA6
-#define MYRI_routeLookup 0x7790
-#define MYRI_NetReceiveMessages 0xB8DE
-#define MYRI_DmaInUse 0xB7AA
-#define MYRI_explores 0x9DB8
-#define MYRI_HostSend 0x9A98
-#define MYRI_DmaResetSpin 0xB7B2
-#define MYRIstart 0x0000
-#define MYRI_RouteTable 0xA164
-#define MYRI_Machines 0x96A2
-#define MYRI_try_the_host 0x9BC8
-#define MYRI_isr_record 0x976E
-#define MYRI_HostReceiveDrops 0x995A
-#define MYRI_HostReceiveLength 0x9964
-#define MYRI_timers 0xBB88
-#define MYRI_NetSendWaiting 0xBA24
-#define MYRI_NetSendDrops 0xBB2E
-#define MYRI_comparing_a_switch 0x9CE0
-#define MYRI_OldMapChecksum 0xA04A
-#define MYRI_HostSendQueue 0x9AA2
-#define MYRI_MAPPER_host 0xA12E
-#define MYRI_compare_switch 0xA03C
-#define MYRI_main 0x80A6
-#define MYRI_NetReceiveBadCrcs 0xB8D4
-#define MYRI_NetReceiveBytes 0xB8DC
-
-#endif /* SYMBOL_DEFINES_COMPILED */
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 08534c08d30..9a802adba9a 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -25,6 +25,7 @@ static char version[] =
#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/firmware.h>
#include <net/dst.h>
#include <net/arp.h>
@@ -43,7 +44,6 @@ static char version[] =
#include <asm/irq.h>
#include "myri_sbus.h"
-#include "myri_code.h"
/* #define DEBUG_DETECT */
/* #define DEBUG_IRQ */
@@ -81,6 +81,9 @@ static char version[] =
#define DHDR(x)
#endif
+/* Firmware name */
+#define FWNAME "myricom/lanai.bin"
+
static void myri_reset_off(void __iomem *lp, void __iomem *cregs)
{
/* Clear IRQ mask. */
@@ -171,10 +174,11 @@ static int myri_do_handshake(struct myri_eth *mp)
static int __devinit myri_load_lanai(struct myri_eth *mp)
{
+ const struct firmware *fw;
struct net_device *dev = mp->dev;
struct myri_shmem __iomem *shmem = mp->shmem;
void __iomem *rptr;
- int i;
+ int i, lanai4_data_size;
myri_disable_irq(mp->lregs, mp->cregs);
myri_reset_on(mp->cregs);
@@ -186,13 +190,27 @@ static int __devinit myri_load_lanai(struct myri_eth *mp)
if (mp->eeprom.cpuvers >= CPUVERS_3_0)
sbus_writel(mp->eeprom.cval, mp->lregs + LANAI_CVAL);
+ i = request_firmware(&fw, FWNAME, &mp->myri_op->dev);
+ if (i) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ FWNAME, i);
+ return i;
+ }
+ if (fw->size < 2) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, FWNAME);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ lanai4_data_size = fw->data[0] << 8 | fw->data[1];
+
/* Load executable code. */
- for (i = 0; i < sizeof(lanai4_code); i++)
- sbus_writeb(lanai4_code[i], rptr + (lanai4_code_off * 2) + i);
+ for (i = 2; i < fw->size; i++)
+ sbus_writeb(fw->data[i], rptr++);
/* Load data segment. */
- for (i = 0; i < sizeof(lanai4_data); i++)
- sbus_writeb(lanai4_data[i], rptr + (lanai4_data_off * 2) + i);
+ for (i = 0; i < lanai4_data_size; i++)
+ sbus_writeb(0, rptr++);
/* Set device address. */
sbus_writeb(0, &shmem->addr[0]);
@@ -228,6 +246,7 @@ static int __devinit myri_load_lanai(struct myri_eth *mp)
if (mp->eeprom.cpuvers == CPUVERS_4_0)
sbus_writel(0, mp->lregs + LANAI_VERS);
+ release_firmware(fw);
return i;
}
@@ -1078,7 +1097,10 @@ static int __devinit myri_sbus_probe(struct of_device *op, const struct of_devic
/* Load code onto the LANai. */
DET(("Loading LANAI firmware\n"));
- myri_load_lanai(mp);
+ if (myri_load_lanai(mp)) {
+ printk(KERN_ERR "MyriCOM: Cannot Load LANAI firmware.\n");
+ goto err_free_irq;
+ }
if (register_netdev(dev)) {
printk("MyriCOM: Cannot register device.\n");
@@ -1159,3 +1181,4 @@ module_init(myri_sbus_init);
module_exit(myri_sbus_exit);
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FWNAME);
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 1af47257ba8..aef77289bd3 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -207,19 +207,19 @@ static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
adapter->pci_using_dac = 0;
- mask = DMA_32BIT_MASK;
+ mask = DMA_BIT_MASK(32);
/*
* Consistent DMA mask is set to 32 bit because it cannot be set to
* 35 bits. For P3 also leave it at 32 bits for now. Only the rings
* come off this pool.
*/
- cmask = DMA_32BIT_MASK;
+ cmask = DMA_BIT_MASK(32);
#ifndef CONFIG_IA64
if (revision_id >= NX_P3_B0)
- mask = DMA_39BIT_MASK;
+ mask = DMA_BIT_MASK(39);
else if (revision_id == NX_P2_C1)
- mask = DMA_35BIT_MASK;
+ mask = DMA_BIT_MASK(35);
#endif
if (pci_set_dma_mask(pdev, mask) == 0 &&
pci_set_consistent_dma_mask(pdev, cmask) == 0) {
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 02c37e2f08a..2b1745328cf 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -4834,6 +4834,7 @@ static int niu_compute_rbr_cfig_b(struct rx_ring_info *rp, u64 *ret)
{
u64 val = 0;
+ *ret = 0;
switch (rp->rbr_block_size) {
case 4 * 1024:
val |= (RBR_BLKSIZE_4K << RBR_CFIG_B_BLKSIZE_SHIFT);
@@ -9542,7 +9543,7 @@ static struct niu_parent * __devinit niu_new_parent(struct niu *np,
plat_dev = platform_device_register_simple("niu", niu_parent_index,
NULL, 0);
- if (!plat_dev)
+ if (IS_ERR(plat_dev))
return NULL;
for (i = 0; attr_name(niu_parent_attributes[i]); i++) {
@@ -9889,8 +9890,8 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev,
goto err_out_release_parent;
}
}
- if (err || dma_mask == DMA_32BIT_MASK) {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (err || dma_mask == DMA_BIT_MASK(32)) {
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, PFX "No usable DMA configuration, "
"aborting.\n");
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 221b0c4c824..d531614a90b 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -1973,9 +1973,9 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev,
/* See if we can set the dma mask early on; failure is fatal. */
if (sizeof(dma_addr_t) == 8 &&
- !pci_set_dma_mask(pci_dev, DMA_64BIT_MASK)) {
+ !pci_set_dma_mask(pci_dev, DMA_BIT_MASK(64))) {
using_dac = 1;
- } else if (!pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) {
+ } else if (!pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32))) {
using_dac = 0;
} else {
dev_warn(&pci_dev->dev, "pci_set_dma_mask failed!\n");
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 501a8d7ac2b..15b8fe61695 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -339,7 +339,7 @@ static int axnet_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
axnet_dev_t *info = PRIV(dev);
- int i, j, last_ret, last_fn;
+ int i, j, j2, last_ret, last_fn;
DEBUG(0, "axnet_config(0x%p)\n", link);
@@ -388,6 +388,8 @@ static int axnet_config(struct pcmcia_device *link)
for (i = 0; i < 32; i++) {
j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
+ j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2);
+ if (j == j2) continue;
if ((j != 0) && (j != 0xffff)) break;
}
@@ -398,6 +400,8 @@ static int axnet_config(struct pcmcia_device *link)
pcmcia_access_configuration_register(link, &reg);
for (i = 0; i < 32; i++) {
j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
+ j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2);
+ if (j == j2) continue;
if ((j != 0) && (j != 0xffff)) break;
}
}
@@ -1767,6 +1771,9 @@ static void AX88190_init(struct net_device *dev, int startp)
ei_local->tx1 = ei_local->tx2 = 0;
ei_local->txing = 0;
+ if (info->flags & IS_AX88790) /* select Internal PHY */
+ outb(0x10, e8390_base + AXNET_GPIO);
+
if (startp)
{
outb_p(0xff, e8390_base + EN0_ISR);
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 8b2823c8dcc..cadc32c94c1 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -3934,12 +3934,12 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
pci_set_master(pdev);
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
- } else if (!(err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+ } else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
pci_using_dac = 0;
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
}
if (err) {
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 170d3540f9c..c92ced24794 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3726,13 +3726,13 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
}
pci_set_master(pdev);
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
set_bit(QL_DMA64, &qdev->flags);
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
} else {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (!err)
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
}
if (err) {
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 0a37f9902a0..6f97b47d74a 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -160,6 +160,7 @@ MODULE_AUTHOR("Sten Wang <sten.wang@rdc.com.tw>,"
"Florian Fainelli <florian@openwrt.org>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver");
+MODULE_VERSION(DRV_VERSION " " DRV_RELDATE);
/* RX and TX interrupts that we handle */
#define RX_INTS (RX_FIFO_FULL | RX_NO_DESC | RX_FINISH)
@@ -1085,13 +1086,13 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
goto err_out;
/* this should always be supported */
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
printk(KERN_ERR DRV_NAME ": 32-bit PCI DMA addresses"
"not supported by the card\n");
goto err_out;
}
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
printk(KERN_ERR DRV_NAME ": 32-bit PCI DMA addresses"
"not supported by the card\n");
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index e1a638a05f8..0b6e8c89683 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1148,7 +1148,7 @@ static void rtl8169_update_counters(struct net_device *dev)
return;
RTL_W32(CounterAddrHigh, (u64)paddr >> 32);
- cmd = (u64)paddr & DMA_32BIT_MASK;
+ cmd = (u64)paddr & DMA_BIT_MASK(32);
RTL_W32(CounterAddrLow, cmd);
RTL_W32(CounterAddrLow, cmd | CounterDump);
@@ -2046,11 +2046,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->cp_cmd = PCIMulRW | RxChkSum;
if ((sizeof(dma_addr_t) > 4) &&
- !pci_set_dma_mask(pdev, DMA_64BIT_MASK) && use_dac) {
+ !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) {
tp->cp_cmd |= PCIDAC;
dev->features |= NETIF_F_HIGHDMA;
} else {
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc < 0) {
if (netif_msg_probe(tp)) {
dev_err(&pdev->dev,
@@ -2343,9 +2343,9 @@ static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp,
* Switching from MMIO to I/O access fixes the issue as well.
*/
RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32);
- RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_32BIT_MASK);
+ RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_BIT_MASK(32));
RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32);
- RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_32BIT_MASK);
+ RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_BIT_MASK(32));
}
static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 16868b7a5d0..1a4979f27fb 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -7775,18 +7775,18 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
return ret;
}
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n");
dma_flag = TRUE;
if (pci_set_consistent_dma_mask
- (pdev, DMA_64BIT_MASK)) {
+ (pdev, DMA_BIT_MASK(64))) {
DBG_PRINT(ERR_DBG,
"Unable to obtain 64bit DMA for \
consistent allocations\n");
pci_disable_device(pdev);
return -ENOMEM;
}
- } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 32bit DMA\n");
} else {
pci_disable_device(pdev);
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 88dd2e09832..ce7551e17ba 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -2299,7 +2299,7 @@ static int sbmac_init(struct platform_device *pldev, long long base)
eaddr = sc->sbm_hwaddr;
/*
- * Read the ethernet address. The firwmare left this programmed
+ * Read the ethernet address. The firmware left this programmed
* for us in the ethernet address register for each mac.
*/
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index c13cbf099b8..18821f217e1 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -1427,11 +1427,11 @@ static int __devinit sc92031_probe(struct pci_dev *pdev,
pci_set_master(pdev);
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (unlikely(err < 0))
goto out_set_dma_mask;
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (unlikely(err < 0))
goto out_set_dma_mask;
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index a9732686134..55ccd51d247 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -1467,7 +1467,7 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev)
goto err_pci_disable_2;
}
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc < 0) {
net_probe(tp, KERN_ERR "%s: DMA configuration failed.\n",
pci_name(pdev));
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 8a70de72ea2..2d4617b3e20 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -432,7 +432,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
ret = pci_enable_device(pci_dev);
if(ret) return ret;
- i = pci_set_dma_mask(pci_dev, DMA_32BIT_MASK);
+ i = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
if(i){
printk(KERN_ERR "sis900.c: architecture does not support "
"32bit PCI busmaster DMA\n");
diff --git a/drivers/net/skfp/h/hwmtm.h b/drivers/net/skfp/h/hwmtm.h
index 1a606d4bfe5..e1a7e5f683d 100644
--- a/drivers/net/skfp/h/hwmtm.h
+++ b/drivers/net/skfp/h/hwmtm.h
@@ -145,7 +145,7 @@ struct hw_modul {
int leave_isr ; /* leave fddi_isr immedeately if set */
int isr_flag ; /* set, when HWM is entered from isr */
/*
- * varaibles for the current transmit frame
+ * variables for the current transmit frame
*/
struct s_smt_tx_queue *tx_p ; /* pointer to the transmit queue */
u_long tx_descr ; /* tx descriptor for FORMAC+ */
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 952d37ffee5..b8978d4af1b 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3912,12 +3912,12 @@ static int __devinit skge_probe(struct pci_dev *pdev,
pci_set_master(pdev);
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
using_dac = 1;
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
- } else if (!(err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+ } else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
using_dac = 0;
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
}
if (err) {
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index d01c56eb962..a2ff9cb1e7a 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -4374,16 +4374,16 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
pci_set_master(pdev);
if (sizeof(dma_addr_t) > sizeof(u32) &&
- !(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
+ !(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))) {
using_dac = 1;
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (err < 0) {
dev_err(&pdev->dev, "unable to obtain 64 bit DMA "
"for consistent allocations\n");
goto err_out_free_regions;
}
} else {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "no usable DMA configuration\n");
goto err_out_free_regions;
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 912308eec86..329f890e290 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -369,7 +369,7 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
* MN10300/AM33 configuration
*/
-#include <asm/unit/smc91111.h>
+#include <unit/smc91111.h>
#else
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index af8f60ca0f5..eb7db032a78 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -43,7 +43,6 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/timer.h>
-#include <linux/version.h>
#include <linux/bug.h>
#include <linux/bitops.h>
#include <linux/irq.h>
@@ -318,7 +317,7 @@ static int smsc911x_mii_read(struct mii_bus *bus, int phyaddr, int regidx)
goto out;
}
- SMSC_WARNING(HW, "Timed out waiting for MII write to finish");
+ SMSC_WARNING(HW, "Timed out waiting for MII read to finish");
reg = -EIO;
out:
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index 5959ae86e57..60abdb1081a 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -1598,7 +1598,7 @@ smsc9420_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto out_free_netdev_2;
}
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_ERR "No usable DMA configuration, aborting.\n");
goto out_free_regions_3;
}
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index c024352c92f..d2dfe0ab510 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -3042,10 +3042,10 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
*/
if (pdev->vendor == PCI_VENDOR_ID_SUN &&
pdev->device == PCI_DEVICE_ID_SUN_GEM &&
- !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
} else {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
printk(KERN_ERR PFX "No usable DMA configuration, "
"aborting.\n");
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 7debd1e4e1f..7f4a9683ba1 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -1941,12 +1941,12 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if ((err = pci_enable_device(pdev))) /* it trigers interrupt, dunno why. */
goto err_pci; /* it's not a problem though */
- if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
- !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
+ if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) &&
+ !(err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))) {
pci_using_dac = 1;
} else {
- if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
- (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) {
+ if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) ||
+ (err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))) {
printk(KERN_ERR "tehuti: No usable DMA configuration"
", aborting\n");
goto err_dma;
diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h
index dec67e0a9ca..4fc875e5dcd 100644
--- a/drivers/net/tehuti.h
+++ b/drivers/net/tehuti.h
@@ -31,6 +31,7 @@
#include <linux/vmalloc.h>
#include <linux/firmware.h>
#include <asm/byteorder.h>
+#include <linux/dma-mapping.h>
/* Compile Time Switches */
/* start */
@@ -98,14 +99,6 @@
#define READ_REG(pp, reg) readl(pp->pBdxRegs + reg)
#define WRITE_REG(pp, reg, val) writel(val, pp->pBdxRegs + reg)
-#ifndef DMA_64BIT_MASK
-# define DMA_64BIT_MASK 0xffffffffffffffffULL
-#endif
-
-#ifndef DMA_32BIT_MASK
-# define DMA_32BIT_MASK 0x00000000ffffffffULL
-#endif
-
#ifndef NET_IP_ALIGN
# define NET_IP_ALIGN 2
#endif
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 1205c2a2265..6a736dda3ee 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -4975,7 +4975,7 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
{
#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG)
- return (((u64) mapping + len) > DMA_40BIT_MASK);
+ return (((u64) mapping + len) > DMA_BIT_MASK(40));
return 0;
#else
return 0;
@@ -11225,7 +11225,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
return tg3_phy_init(tp);
/* Reading the PHY ID register can conflict with ASF
- * firwmare access to the PHY hardware.
+ * firmware access to the PHY hardware.
*/
err = 0;
if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
@@ -13228,17 +13228,17 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
* do DMA address check in tg3_start_xmit().
*/
if (tp->tg3_flags2 & TG3_FLG2_IS_5788)
- persist_dma_mask = dma_mask = DMA_32BIT_MASK;
+ persist_dma_mask = dma_mask = DMA_BIT_MASK(32);
else if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) {
- persist_dma_mask = dma_mask = DMA_40BIT_MASK;
+ persist_dma_mask = dma_mask = DMA_BIT_MASK(40);
#ifdef CONFIG_HIGHMEM
- dma_mask = DMA_64BIT_MASK;
+ dma_mask = DMA_BIT_MASK(64);
#endif
} else
- persist_dma_mask = dma_mask = DMA_64BIT_MASK;
+ persist_dma_mask = dma_mask = DMA_BIT_MASK(64);
/* Configure DMA attributes. */
- if (dma_mask > DMA_32BIT_MASK) {
+ if (dma_mask > DMA_BIT_MASK(32)) {
err = pci_set_dma_mask(pdev, dma_mask);
if (!err) {
dev->features |= NETIF_F_HIGHDMA;
@@ -13251,8 +13251,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
}
}
}
- if (err || dma_mask == DMA_32BIT_MASK) {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (err || dma_mask == DMA_BIT_MASK(32)) {
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
printk(KERN_ERR PFX "No usable DMA configuration, "
"aborting.\n");
@@ -13393,8 +13393,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n",
dev->name, tp->dma_rwctrl,
- (pdev->dma_mask == DMA_32BIT_MASK) ? 32 :
- (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64));
+ (pdev->dma_mask == DMA_BIT_MASK(32)) ? 32 :
+ (((u64) pdev->dma_mask == DMA_BIT_MASK(40)) ? 40 : 64));
return 0;
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 68b967b585a..aa6964922d5 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -570,7 +570,7 @@ static int __devinit TLan_probe1(struct pci_dev *pdev,
priv->adapter = &board_info[ent->driver_data];
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
printk(KERN_ERR "TLAN: No suitable PCI mapping available.\n");
goto err_out_free_dev;
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
index f309b8f703b..2e70ee8f145 100644
--- a/drivers/net/tokenring/lanstreamer.c
+++ b/drivers/net/tokenring/lanstreamer.c
@@ -267,7 +267,7 @@ static int __devinit streamer_init_one(struct pci_dev *pdev,
#endif
#endif
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
printk(KERN_ERR "%s: No suitable PCI mapping available.\n",
dev->name);
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index e2c9d0f5a75..f2e669974c7 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -383,7 +383,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
return -ENOMEM;
SET_NETDEV_DEV(dev, &pdev->dev);
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING DRV_NAME
": 32-bit PCI DMA not available.\n");
err = -ENODEV;
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index c227db07962..8761a5a5bd7 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -282,7 +282,7 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev,
return -ENOMEM;
SET_NETDEV_DEV(dev, &pdev->dev);
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING DRV_NAME ": 32-bit PCI DMA not available.\n");
err = -ENODEV;
goto err_out_free;
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index c61a01b029a..264e61404f3 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -375,7 +375,7 @@ static int __devinit w840_probe1 (struct pci_dev *pdev,
irq = pdev->irq;
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "Winbond-840: Device %s disabled due to DMA limitations.\n",
pci_name(pdev));
return -EIO;
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 9dd4f76a2ff..cf25eb41b1c 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -2406,7 +2406,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
goto error_out_disable;
}
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if(err < 0) {
printk(ERR_PFX "%s: No usable DMA configuration\n",
pci_name(pdev));
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 659654f4588..f3a2fce6166 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1180,7 +1180,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
#if 0
// dma_supported() is deeply broken on almost all architectures
// possible with some EHCI controllers
- if (dma_supported (&udev->dev, DMA_64BIT_MASK))
+ if (dma_supported (&udev->dev, DMA_BIT_MASK(64)))
net->features |= NETIF_F_HIGHDMA;
#endif
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 880eaf07413..45daba726b6 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -686,7 +686,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
goto err_out;
/* this should always be supported */
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
printk(KERN_ERR "32-bit PCI DMA addresses not supported by "
"the card!?\n");
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index a6f1e19159d..9c82a39497e 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -575,8 +575,9 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p)
if (ret)
return ret;
- vdev->config->set(vdev, offsetof(struct virtio_net_config, mac),
- dev->dev_addr, dev->addr_len);
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
+ vdev->config->set(vdev, offsetof(struct virtio_net_config, mac),
+ dev->dev_addr, dev->addr_len);
return 0;
}
@@ -876,11 +877,8 @@ static int virtnet_probe(struct virtio_device *vdev)
vdev->config->get(vdev,
offsetof(struct virtio_net_config, mac),
dev->dev_addr, dev->addr_len);
- } else {
+ } else
random_ether_addr(dev->dev_addr);
- vdev->config->set(vdev, offsetof(struct virtio_net_config, mac),
- dev->dev_addr, dev->addr_len);
- }
/* Set up our device-specific information */
vi = netdev_priv(dev);
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index 61ef1611815..b7f08f3e524 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -43,6 +43,7 @@
#include <linux/if_vlan.h>
#include <linux/pci.h>
+#include <linux/tcp.h>
#include <net/ip.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 00945f7c1e9..25c9ef6a181 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -69,7 +69,7 @@ MODULE_LICENSE("GPL");
#endif
/*
- * Modules parameters and associated varaibles
+ * Modules parameters and associated variables
*/
static int fst_txq_low = FST_LOW_WATER_MARK;
static int fst_txq_high = FST_HIGH_WATER_MARK;
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index 887acb0dc80..8130b79a8a9 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -586,8 +586,8 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
We set both dma_mask and consistent_dma_mask to 28 bits
and pray pci_alloc_consistent() will use this info. It should
work on most platforms */
- if (pci_set_consistent_dma_mask(pdev, DMA_28BIT_MASK) ||
- pci_set_dma_mask(pdev, DMA_28BIT_MASK)) {
+ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(28)) ||
+ pci_set_dma_mask(pdev, DMA_BIT_MASK(28))) {
printk(KERN_ERR "wanXL: No usable DMA configuration\n");
return -EIO;
}
@@ -633,8 +633,8 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
/* FIXME when PCI/DMA subsystems are fixed.
We set both dma_mask and consistent_dma_mask back to 32 bits
to indicate the card can do 32-bit DMA addressing */
- if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) ||
- pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) ||
+ pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_ERR "wanXL: No usable DMA configuration\n");
wanxl_pci_remove_one(pdev);
return -EIO;
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index fc0897fb223..f7182179501 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1804,8 +1804,8 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
return err; /* someone else grabbed it? don't disable it */
}
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
- pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
+ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_ERR "%s (adm8211): No suitable DMA available\n",
pci_name(pdev));
goto err_free_reg;
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 5d57d774e46..a08bc8a4fb6 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -445,7 +445,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
}
/* XXX 32-bit addressing only */
- ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (ret) {
dev_err(&pdev->dev, "32-bit DMA not available\n");
goto err_dis;
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath9k/pci.c
index 6dbc58580ab..168411d322a 100644
--- a/drivers/net/wireless/ath9k/pci.c
+++ b/drivers/net/wireless/ath9k/pci.c
@@ -93,14 +93,14 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (pci_enable_device(pdev))
return -EIO;
- ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (ret) {
printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
goto bad;
}
- ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (ret) {
printk(KERN_ERR "ath9k: 32-bit DMA consistent "
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 0cc804d0a21..e228c1de6e1 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -772,23 +772,23 @@ static u64 supported_dma_mask(struct b43_wldev *dev)
tmp = b43_read32(dev, SSB_TMSHIGH);
if (tmp & SSB_TMSHIGH_DMA64)
- return DMA_64BIT_MASK;
+ return DMA_BIT_MASK(64);
mmio_base = b43_dmacontroller_base(0, 0);
b43_write32(dev, mmio_base + B43_DMA32_TXCTL, B43_DMA32_TXADDREXT_MASK);
tmp = b43_read32(dev, mmio_base + B43_DMA32_TXCTL);
if (tmp & B43_DMA32_TXADDREXT_MASK)
- return DMA_32BIT_MASK;
+ return DMA_BIT_MASK(32);
- return DMA_30BIT_MASK;
+ return DMA_BIT_MASK(30);
}
static enum b43_dmatype dma_mask_to_engine_type(u64 dmamask)
{
- if (dmamask == DMA_30BIT_MASK)
+ if (dmamask == DMA_BIT_MASK(30))
return B43_DMA_30BIT;
- if (dmamask == DMA_32BIT_MASK)
+ if (dmamask == DMA_BIT_MASK(32))
return B43_DMA_32BIT;
- if (dmamask == DMA_64BIT_MASK)
+ if (dmamask == DMA_BIT_MASK(64))
return B43_DMA_64BIT;
B43_WARN_ON(1);
return B43_DMA_30BIT;
@@ -999,13 +999,13 @@ static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask)
err = ssb_dma_set_mask(dev->dev, mask);
if (!err)
break;
- if (mask == DMA_64BIT_MASK) {
- mask = DMA_32BIT_MASK;
+ if (mask == DMA_BIT_MASK(64)) {
+ mask = DMA_BIT_MASK(32);
fallback = 1;
continue;
}
- if (mask == DMA_32BIT_MASK) {
- mask = DMA_30BIT_MASK;
+ if (mask == DMA_BIT_MASK(32)) {
+ mask = DMA_BIT_MASK(30);
fallback = 1;
continue;
}
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index 3649fc36709..2f90fb9f536 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -846,7 +846,7 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev)
tmp = b43legacy_read32(dev, SSB_TMSHIGH);
if (tmp & SSB_TMSHIGH_DMA64)
- return DMA_64BIT_MASK;
+ return DMA_BIT_MASK(64);
mmio_base = b43legacy_dmacontroller_base(0, 0);
b43legacy_write32(dev,
mmio_base + B43legacy_DMA32_TXCTL,
@@ -854,18 +854,18 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev)
tmp = b43legacy_read32(dev, mmio_base +
B43legacy_DMA32_TXCTL);
if (tmp & B43legacy_DMA32_TXADDREXT_MASK)
- return DMA_32BIT_MASK;
+ return DMA_BIT_MASK(32);
- return DMA_30BIT_MASK;
+ return DMA_BIT_MASK(30);
}
static enum b43legacy_dmatype dma_mask_to_engine_type(u64 dmamask)
{
- if (dmamask == DMA_30BIT_MASK)
+ if (dmamask == DMA_BIT_MASK(30))
return B43legacy_DMA_30BIT;
- if (dmamask == DMA_32BIT_MASK)
+ if (dmamask == DMA_BIT_MASK(32))
return B43legacy_DMA_32BIT;
- if (dmamask == DMA_64BIT_MASK)
+ if (dmamask == DMA_BIT_MASK(64))
return B43legacy_DMA_64BIT;
B43legacy_WARN_ON(1);
return B43legacy_DMA_30BIT;
@@ -1042,13 +1042,13 @@ static int b43legacy_dma_set_mask(struct b43legacy_wldev *dev, u64 mask)
err = ssb_dma_set_mask(dev->dev, mask);
if (!err)
break;
- if (mask == DMA_64BIT_MASK) {
- mask = DMA_32BIT_MASK;
+ if (mask == DMA_BIT_MASK(64)) {
+ mask = DMA_BIT_MASK(32);
fallback = 1;
continue;
}
- if (mask == DMA_32BIT_MASK) {
- mask = DMA_30BIT_MASK;
+ if (mask == DMA_BIT_MASK(32)) {
+ mask = DMA_BIT_MASK(30);
fallback = 1;
continue;
}
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 115b7048750..97e5647ff05 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -2362,7 +2362,7 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
i * sizeof(struct ipw2100_status));
#ifdef IPW2100_DEBUG_C3
- /* Halt the fimrware so we can get a good image */
+ /* Halt the firmware so we can get a good image */
write_register(priv->net_dev, IPW_REG_RESET_REG,
IPW_AUX_HOST_RESET_REG_STOP_MASTER);
j = 5;
@@ -6207,7 +6207,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
pci_set_master(pci_dev);
pci_set_drvdata(pci_dev, priv);
- err = pci_set_dma_mask(pci_dev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
if (err) {
printk(KERN_WARNING DRV_NAME
"Error calling pci_set_dma_mask.\n");
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 4a92af1d787..bd4dbcfe1bb 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -8844,7 +8844,7 @@ static int ipw_wx_set_mode(struct net_device *dev,
#endif /* CONFIG_IPW2200_MONITOR */
/* Free the existing firmware and reset the fw_loaded
- * flag so ipw_load() will bring in the new firmawre */
+ * flag so ipw_load() will bring in the new firmware */
free_firmware();
priv->ieee->iw_mode = wrqu->mode;
@@ -11631,9 +11631,9 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
pci_set_master(pdev);
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (!err)
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");
goto out_pci_disable_device;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 663dc83be50..3889158b359 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1337,7 +1337,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
/* api_ver should match the api version forming part of the
* firmware filename ... but we don't check for that and only rely
- * on the API version read from firware header from here on forward */
+ * on the API version read from firmware header from here on forward */
if (api_ver < api_min || api_ver > api_max) {
IWL_ERR(priv, "Driver unable to support your firmware API. "
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index a71b08ca7c7..ce729281ff6 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2562,7 +2562,7 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
/* api_ver should match the api version forming part of the
* firmware filename ... but we don't check for that and only rely
- * on the API version read from firware header from here on forward */
+ * on the API version read from firmware header from here on forward */
if (api_ver < api_min || api_ver > api_max) {
IWL_ERR(priv, "Driver unable to support your firmware API. "
@@ -4998,9 +4998,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
pci_set_master(pdev);
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (!err)
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
IWL_WARN(priv, "No suitable DMA available.\n");
goto out_pci_disable_device;
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 639dd02d3d3..8c3605cdc64 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1649,7 +1649,7 @@ static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
/**
* @brief This function executes next command in command
- * pending queue. It will put fimware back to PS mode
+ * pending queue. It will put firmware back to PS mode
* if applicable.
*
* @param priv A pointer to struct lbs_private structure
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index e3569a0a952..b1610ea4bb3 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -492,8 +492,8 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
goto err_disable_dev;
}
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
- pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
+ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
dev_err(&pdev->dev, "No suitable DMA available\n");
goto err_free_reg;
}
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index 9a72b1e3e16..30876728d7e 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -120,7 +120,7 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* enable PCI DMA */
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_ERR "%s: 32-bit PCI DMA not supported", DRV_NAME);
goto do_pci_disable_device;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index e616c20d4a7..43fa0f84900 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -288,7 +288,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
if (pci_set_mwi(pci_dev))
ERROR_PROBE("MWI not available.\n");
- if (dma_set_mask(&pci_dev->dev, DMA_32BIT_MASK)) {
+ if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) {
ERROR_PROBE("PCI DMA not supported.\n");
retval = -EIO;
goto exit_disable_device;
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index 2c9aa49e43c..8574622e36a 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -154,6 +154,10 @@ int sync_start(void)
{
int err;
+ if (!alloc_cpumask_var(&marked_cpus, GFP_KERNEL))
+ return -ENOMEM;
+ cpumask_clear(marked_cpus);
+
start_cpu_work();
err = task_handoff_register(&task_free_nb);
@@ -179,6 +183,7 @@ out2:
task_handoff_unregister(&task_free_nb);
out1:
end_sync();
+ free_cpumask_var(marked_cpus);
goto out;
}
@@ -190,6 +195,7 @@ void sync_stop(void)
profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
task_handoff_unregister(&task_free_nb);
end_sync();
+ free_cpumask_var(marked_cpus);
}
@@ -565,20 +571,6 @@ void sync_buffer(int cpu)
mutex_unlock(&buffer_mutex);
}
-int __init buffer_sync_init(void)
-{
- if (!alloc_cpumask_var(&marked_cpus, GFP_KERNEL))
- return -ENOMEM;
-
- cpumask_clear(marked_cpus);
- return 0;
-}
-
-void buffer_sync_cleanup(void)
-{
- free_cpumask_var(marked_cpus);
-}
-
/* The function can be used to add a buffer worth of data directly to
* the kernel buffer. The buffer is assumed to be a circular buffer.
* Take the entries from index start and end at index end, wrapping
diff --git a/drivers/oprofile/buffer_sync.h b/drivers/oprofile/buffer_sync.h
index 0ebf5db6267..3110732c183 100644
--- a/drivers/oprofile/buffer_sync.h
+++ b/drivers/oprofile/buffer_sync.h
@@ -19,8 +19,4 @@ void sync_stop(void);
/* sync the given CPU's buffer */
void sync_buffer(int cpu);
-/* initialize/destroy the buffer system. */
-int buffer_sync_init(void);
-void buffer_sync_cleanup(void);
-
#endif /* OPROFILE_BUFFER_SYNC_H */
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index e76d715e434..f0e99d4c066 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -161,7 +161,7 @@ struct op_sample
{
entry->event = ring_buffer_lock_reserve
(op_ring_buffer_write, sizeof(struct op_sample) +
- size * sizeof(entry->sample->data[0]), &entry->irq_flags);
+ size * sizeof(entry->sample->data[0]));
if (entry->event)
entry->sample = ring_buffer_event_data(entry->event);
else
@@ -178,8 +178,7 @@ struct op_sample
int op_cpu_buffer_write_commit(struct op_entry *entry)
{
- return ring_buffer_unlock_commit(op_ring_buffer_write, entry->event,
- entry->irq_flags);
+ return ring_buffer_unlock_commit(op_ring_buffer_write, entry->event);
}
struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu)
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
index ced39f60229..3cffce90f82 100644
--- a/drivers/oprofile/oprof.c
+++ b/drivers/oprofile/oprof.c
@@ -183,10 +183,6 @@ static int __init oprofile_init(void)
{
int err;
- err = buffer_sync_init();
- if (err)
- return err;
-
err = oprofile_arch_init(&oprofile_ops);
if (err < 0 || timer) {
@@ -195,10 +191,8 @@ static int __init oprofile_init(void)
}
err = oprofilefs_register();
- if (err) {
+ if (err)
oprofile_arch_exit();
- buffer_sync_cleanup();
- }
return err;
}
@@ -208,7 +202,6 @@ static void __exit oprofile_exit(void)
{
oprofilefs_unregister();
oprofile_arch_exit();
- buffer_sync_cleanup();
}
diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c
index 7931133526c..9ca21098b14 100644
--- a/drivers/parisc/asp.c
+++ b/drivers/parisc/asp.c
@@ -81,7 +81,7 @@ static int __init asp_init_chip(struct parisc_device *dev)
asp.hpa = ASP_INTERRUPT_ADDR;
printk(KERN_INFO "%s version %d at 0x%lx found.\n",
- asp.name, asp.version, dev->hpa.start);
+ asp.name, asp.version, (unsigned long)dev->hpa.start);
/* the IRQ ASP should use */
ret = -EBUSY;
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index cd4dd7ed2c0..5d610cbcfe8 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -406,8 +406,6 @@ resource_found:
}
ioc->avg_search[ioc->avg_idx++] = cr_start;
ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1;
-#endif
-#ifdef CCIO_COLLECT_STATS
ioc->used_pages += pages_needed;
#endif
/*
@@ -453,10 +451,10 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped)
unsigned long mask = ~(~0UL >> pages_mapped);
CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 8);
#else
- CCIO_FREE_MAPPINGS(ioc, res_idx, 0xff, 8);
+ CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffUL, 8);
#endif
} else if(pages_mapped <= 16) {
- CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffff, 16);
+ CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffffUL, 16);
} else if(pages_mapped <= 32) {
CCIO_FREE_MAPPINGS(ioc, res_idx, ~(unsigned int)0, 32);
#ifdef __LP64__
@@ -1028,8 +1026,10 @@ static int ccio_proc_info(struct seq_file *m, void *p)
while (ioc != NULL) {
unsigned int total_pages = ioc->res_size << 3;
+#ifdef CCIO_COLLECT_STATS
unsigned long avg = 0, min, max;
int j;
+#endif
len += seq_printf(m, "%s\n", ioc->name);
@@ -1060,8 +1060,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
avg /= CCIO_SEARCH_SAMPLE;
len += seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
min, avg, max);
-#endif
-#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));
@@ -1400,7 +1399,7 @@ ccio_init_resource(struct resource *res, char *name, void __iomem *ioaddr)
result = insert_resource(&iomem_resource, res);
if (result < 0) {
printk(KERN_ERR "%s() failed to claim CCIO bus address space (%08lx,%08lx)\n",
- __func__, res->start, res->end);
+ __func__, (unsigned long)res->start, (unsigned long)res->end);
}
}
@@ -1551,7 +1550,8 @@ static int __init ccio_probe(struct parisc_device *dev)
ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
- printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa.start);
+ printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name,
+ (unsigned long)dev->hpa.start);
for (i = 0; i < ioc_count; i++) {
ioc_p = &(*ioc_p)->next;
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index bb5a1c9597c..52ae0b1d470 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -819,7 +819,9 @@ dino_bridge_init(struct dino_device *dino_dev, const char *name)
result = ccio_request_resource(dino_dev->hba.dev, &res[i]);
if (result < 0) {
- printk(KERN_ERR "%s: failed to claim PCI Bus address space %d (0x%lx-0x%lx)!\n", name, i, res[i].start, res[i].end);
+ printk(KERN_ERR "%s: failed to claim PCI Bus address "
+ "space %d (0x%lx-0x%lx)!\n", name, i,
+ (unsigned long)res[i].start, (unsigned long)res[i].end);
return result;
}
}
@@ -899,7 +901,8 @@ static int __init dino_common_init(struct parisc_device *dev,
if (request_resource(&ioport_resource, res) < 0) {
printk(KERN_ERR "%s: request I/O Port region failed "
"0x%lx/%lx (hpa 0x%p)\n",
- name, res->start, res->end, dino_dev->hba.base_addr);
+ name, (unsigned long)res->start, (unsigned long)res->end,
+ dino_dev->hba.base_addr);
return 1;
}
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 7891db50c48..f415fdd9a88 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -314,7 +314,7 @@ static int __init eisa_probe(struct parisc_device *dev)
char *name = is_mongoose(dev) ? "Mongoose" : "Wax";
printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n",
- name, dev->hpa.start);
+ name, (unsigned long)dev->hpa.start);
eisa_dev.hba.dev = dev;
eisa_dev.hba.iommu = ccio_get_iommu(dev);
diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c
index 6d8aae003f6..c709ecc2b7f 100644
--- a/drivers/parisc/eisa_enumerator.c
+++ b/drivers/parisc/eisa_enumerator.c
@@ -98,7 +98,7 @@ static int configure_memory(const unsigned char *buf,
res->start = mem_parent->start + get_24(buf+len+2);
res->end = res->start + get_16(buf+len+5)*1024;
res->flags = IORESOURCE_MEM;
- printk("memory %lx-%lx ", res->start, res->end);
+ printk("memory %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
result = request_resource(mem_parent, res);
if (result < 0) {
printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
@@ -188,7 +188,7 @@ static int configure_port(const unsigned char *buf, struct resource *io_parent,
res->start = get_16(buf+len+1);
res->end = get_16(buf+len+1)+(c&HPEE_PORT_SIZE_MASK)+1;
res->flags = IORESOURCE_IO;
- printk("ioports %lx-%lx ", res->start, res->end);
+ printk("ioports %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
result = request_resource(io_parent, res);
if (result < 0) {
printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 501aaf1f253..73348c4047e 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -714,7 +714,7 @@ static void iosapic_set_affinity_irq(unsigned int irq,
if (dest_cpu < 0)
return;
- irq_desc[irq].affinity = cpumask_of_cpu(dest_cpu);
+ cpumask_copy(irq_desc[irq].affinity, cpumask_of(dest_cpu));
vi->txn_addr = txn_affinity_addr(irq, dest_cpu);
spin_lock_irqsave(&iosapic_lock, flags);
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index 454b6532e40..9581d361945 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -3,7 +3,7 @@
*
* (c) Copyright 2000 Red Hat Software
* (c) Copyright 2000 Helge Deller <hdeller@redhat.com>
- * (c) Copyright 2001-2005 Helge Deller <deller@gmx.de>
+ * (c) Copyright 2001-2009 Helge Deller <deller@gmx.de>
* (c) Copyright 2001 Randolph Chung <tausq@debian.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -243,13 +243,11 @@ static int __init led_create_procfs(void)
proc_pdc_root = proc_mkdir("pdc", 0);
if (!proc_pdc_root) return -1;
- proc_pdc_root->owner = THIS_MODULE;
ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
if (!ent) return -1;
ent->data = (void *)LED_NOLCD; /* LED */
ent->read_proc = led_proc_read;
ent->write_proc = led_proc_write;
- ent->owner = THIS_MODULE;
if (led_type == LED_HASLCD)
{
@@ -258,7 +256,6 @@ static int __init led_create_procfs(void)
ent->data = (void *)LED_HASLCD; /* LCD */
ent->read_proc = led_proc_read;
ent->write_proc = led_proc_write;
- ent->owner = THIS_MODULE;
}
return 0;
@@ -463,9 +460,20 @@ static void led_work_func (struct work_struct *unused)
if (likely(led_lanrxtx)) currentleds |= led_get_net_activity();
if (likely(led_diskio)) currentleds |= led_get_diskio_activity();
- /* blink all LEDs twice a second if we got an Oops (HPMC) */
- if (unlikely(oops_in_progress))
- currentleds = (count_HZ<=(HZ/2)) ? 0 : 0xff;
+ /* blink LEDs if we got an Oops (HPMC) */
+ if (unlikely(oops_in_progress)) {
+ if (boot_cpu_data.cpu_type >= pcxl2) {
+ /* newer machines don't have loadavg. LEDs, so we
+ * let all LEDs blink twice per second instead */
+ currentleds = (count_HZ <= (HZ/2)) ? 0 : 0xff;
+ } else {
+ /* old machines: blink loadavg. LEDs twice per second */
+ if (count_HZ <= (HZ/2))
+ currentleds &= ~(LED4|LED5|LED6|LED7);
+ else
+ currentleds |= (LED4|LED5|LED6|LED7);
+ }
+ }
if (currentleds != lastleds)
{
@@ -511,7 +519,7 @@ static int led_halt(struct notifier_block *nb, unsigned long event, void *buf)
/* Cancel the work item and delete the queue */
if (led_wq) {
- cancel_rearming_delayed_workqueue(led_wq, &led_task);
+ cancel_delayed_work_sync(&led_task);
destroy_workqueue(led_wq);
led_wq = NULL;
}
@@ -630,7 +638,7 @@ int lcd_print( const char *str )
/* temporarily disable the led work task */
if (led_wq)
- cancel_rearming_delayed_workqueue(led_wq, &led_task);
+ cancel_delayed_work_sync(&led_task);
/* copy display string to buffer for procfs */
strlcpy(lcd_text, str, sizeof(lcd_text));
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index 4fa3bb2ddfe..33e5ade774c 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -434,7 +434,8 @@ static void __init superio_parport_init(void)
0 /*base_hi*/,
PAR_IRQ,
PARPORT_DMA_NONE /* dma */,
- NULL /*struct pci_dev* */) )
+ NULL /*struct pci_dev* */),
+ 0 /* shared irq flags */ )
printk(KERN_WARNING PFX "Probing parallel port failed.\n");
#endif /* CONFIG_PARPORT_PC */
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 0cd5fbc7f2c..8fdfa4f537a 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -43,6 +43,7 @@
#include <linux/timer.h>
#include <linux/ioport.h>
#include <linux/major.h>
+#include <linux/interrupt.h>
#include <linux/parport.h>
#include <linux/parport_pc.h>
@@ -192,7 +193,7 @@ static int parport_config(struct pcmcia_device *link)
p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
link->irq.AssignedIRQ, PARPORT_DMA_NONE,
- &link->dev);
+ &link->dev, IRQF_SHARED);
if (p == NULL) {
printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
"0x%3x, irq %u failed\n", link->io.BasePort1,
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 96f3bdf0ec4..4e63cc9e277 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -2170,10 +2170,11 @@ static int parport_dma_probe (struct parport *p)
static LIST_HEAD(ports_list);
static DEFINE_SPINLOCK(ports_lock);
-struct parport *parport_pc_probe_port (unsigned long int base,
- unsigned long int base_hi,
- int irq, int dma,
- struct device *dev)
+struct parport *parport_pc_probe_port(unsigned long int base,
+ unsigned long int base_hi,
+ int irq, int dma,
+ struct device *dev,
+ int irqflags)
{
struct parport_pc_private *priv;
struct parport_operations *ops;
@@ -2194,11 +2195,11 @@ struct parport *parport_pc_probe_port (unsigned long int base,
dev = &pdev->dev;
}
- ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL);
+ ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
if (!ops)
goto out1;
- priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL);
+ priv = kmalloc(sizeof(struct parport_pc_private), GFP_KERNEL);
if (!priv)
goto out2;
@@ -2325,8 +2326,8 @@ struct parport *parport_pc_probe_port (unsigned long int base,
EPP_res = NULL;
}
if (p->irq != PARPORT_IRQ_NONE) {
- if (request_irq (p->irq, parport_irq_handler,
- 0, p->name, p)) {
+ if (request_irq(p->irq, parport_irq_handler,
+ irqflags, p->name, p)) {
printk (KERN_WARNING "%s: irq %d in use, "
"resorting to polled operation\n",
p->name, p->irq);
@@ -2530,7 +2531,7 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq,
*/
release_resource(base_res);
if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi,
- irq, PARPORT_DMA_NONE, &pdev->dev)) {
+ irq, PARPORT_DMA_NONE, &pdev->dev, 0)) {
printk (KERN_INFO
"parport_pc: ITE 8872 parallel port: io=0x%X",
ite8872_lpt);
@@ -2713,7 +2714,7 @@ static int __devinit sio_via_probe (struct pci_dev *pdev, int autoirq,
}
/* finally, do the probe with values obtained */
- if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev)) {
+ if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev, 0)) {
printk (KERN_INFO
"parport_pc: VIA parallel port: io=0x%X", port1);
if (irq != PARPORT_IRQ_NONE)
@@ -3018,6 +3019,7 @@ static int parport_pc_pci_probe (struct pci_dev *dev,
for (n = 0; n < cards[i].numports; n++) {
int lo = cards[i].addr[n].lo;
int hi = cards[i].addr[n].hi;
+ int irq;
unsigned long io_lo, io_hi;
io_lo = pci_resource_start (dev, lo);
io_hi = 0;
@@ -3028,13 +3030,25 @@ static int parport_pc_pci_probe (struct pci_dev *dev,
"hi" as an offset (see SYBA
def.) */
/* TODO: test if sharing interrupts works */
- printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, "
- "I/O at %#lx(%#lx)\n",
- parport_pc_pci_tbl[i + last_sio].vendor,
- parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi);
+ irq = dev->irq;
+ if (irq == IRQ_NONE) {
+ printk (KERN_DEBUG
+ "PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx)\n",
+ parport_pc_pci_tbl[i + last_sio].vendor,
+ parport_pc_pci_tbl[i + last_sio].device,
+ io_lo, io_hi);
+ irq = PARPORT_IRQ_NONE;
+ } else {
+ printk (KERN_DEBUG
+ "PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx), IRQ %d\n",
+ parport_pc_pci_tbl[i + last_sio].vendor,
+ parport_pc_pci_tbl[i + last_sio].device,
+ io_lo, io_hi, irq);
+ }
data->ports[count] =
- parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
- PARPORT_DMA_NONE, &dev->dev);
+ parport_pc_probe_port(io_lo, io_hi, irq,
+ PARPORT_DMA_NONE, &dev->dev,
+ IRQF_SHARED);
if (data->ports[count])
count++;
}
@@ -3143,7 +3157,8 @@ static int parport_pc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id
dma = PARPORT_DMA_NONE;
dev_info(&dev->dev, "reported by %s\n", dev->protocol->name);
- if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, &dev->dev)))
+ if (!(pdata = parport_pc_probe_port(io_lo, io_hi,
+ irq, dma, &dev->dev, 0)))
return -ENODEV;
pnp_set_drvdata(dev,pdata);
@@ -3192,11 +3207,11 @@ parport_pc_find_isa_ports (int autoirq, int autodma)
{
int count = 0;
- if (parport_pc_probe_port(0x3bc, 0x7bc, autoirq, autodma, NULL))
+ if (parport_pc_probe_port(0x3bc, 0x7bc, autoirq, autodma, NULL, 0))
count++;
- if (parport_pc_probe_port(0x378, 0x778, autoirq, autodma, NULL))
+ if (parport_pc_probe_port(0x378, 0x778, autoirq, autodma, NULL, 0))
count++;
- if (parport_pc_probe_port(0x278, 0x678, autoirq, autodma, NULL))
+ if (parport_pc_probe_port(0x278, 0x678, autoirq, autodma, NULL, 0))
count++;
return count;
@@ -3481,7 +3496,7 @@ static int __init parport_pc_init(void)
if ((io_hi[i]) == PARPORT_IOHI_AUTO)
io_hi[i] = 0x400 + io[i];
parport_pc_probe_port(io[i], io_hi[i],
- irqval[i], dmaval[i], NULL);
+ irqval[i], dmaval[i], NULL, 0);
}
} else
parport_pc_find_ports (irqval[0], dmaval[0]);
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index f3492110b1a..c3bb84ac931 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/interrupt.h>
#include <linux/parport.h>
#include <linux/parport_pc.h>
#include <linux/8250_pci.h>
@@ -311,6 +312,7 @@ static int __devinit parport_register (struct pci_dev *dev,
int lo = card->addr[n].lo;
int hi = card->addr[n].hi;
unsigned long io_lo, io_hi;
+ int irq;
if (priv->num_par == ARRAY_SIZE (priv->port)) {
printk (KERN_WARNING
@@ -329,10 +331,20 @@ static int __devinit parport_register (struct pci_dev *dev,
"hi" as an offset (see SYBA
def.) */
/* TODO: test if sharing interrupts works */
- dev_dbg(&dev->dev, "PCI parallel port detected: I/O at "
- "%#lx(%#lx)\n", io_lo, io_hi);
- port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
- PARPORT_DMA_NONE, &dev->dev);
+ irq = dev->irq;
+ if (irq == IRQ_NONE) {
+ dev_dbg(&dev->dev,
+ "PCI parallel port detected: I/O at %#lx(%#lx)\n",
+ io_lo, io_hi);
+ irq = PARPORT_IRQ_NONE;
+ } else {
+ dev_dbg(&dev->dev,
+ "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n",
+ io_lo, io_hi, irq);
+ irq = PARPORT_IRQ_NONE;
+ }
+ port = parport_pc_probe_port (io_lo, io_hi, irq,
+ PARPORT_DMA_NONE, &dev->dev, IRQF_SHARED);
if (port) {
priv->port[priv->num_par++] = port;
success = 1;
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 38144479477..64dd7df90e6 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -356,7 +356,8 @@ int pci_vpd_truncate(struct pci_dev *dev, size_t size)
return -EINVAL;
dev->vpd->len = size;
- dev->vpd->attr->size = size;
+ if (dev->vpd->attr)
+ dev->vpd->attr->size = size;
return 0;
}
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 68f91a25259..97a8194063b 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -184,7 +184,7 @@ void pci_enable_bridges(struct pci_bus *bus)
list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->subordinate) {
- if (atomic_read(&dev->enable_cnt) == 0) {
+ if (!pci_is_enabled(dev)) {
retval = pci_enable_device(dev);
pci_set_master(dev);
}
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index d313039e2fd..fa3a11365ec 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -173,13 +173,23 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
struct dmar_drhd_unit *dmaru;
int ret = 0;
+ drhd = (struct acpi_dmar_hardware_unit *)header;
+ if (!drhd->address) {
+ /* Promote an attitude of violence to a BIOS engineer today */
+ WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n"
+ "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+ dmi_get_system_info(DMI_BIOS_VENDOR),
+ dmi_get_system_info(DMI_BIOS_VERSION),
+ dmi_get_system_info(DMI_PRODUCT_VERSION));
+ return -ENODEV;
+ }
dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL);
if (!dmaru)
return -ENOMEM;
dmaru->hdr = header;
- drhd = (struct acpi_dmar_hardware_unit *)header;
dmaru->reg_base_addr = drhd->address;
+ dmaru->segment = drhd->segment;
dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
ret = alloc_iommu(dmaru);
@@ -790,14 +800,41 @@ end:
}
/*
+ * Enable queued invalidation.
+ */
+static void __dmar_enable_qi(struct intel_iommu *iommu)
+{
+ u32 cmd, sts;
+ unsigned long flags;
+ struct q_inval *qi = iommu->qi;
+
+ qi->free_head = qi->free_tail = 0;
+ qi->free_cnt = QI_LENGTH;
+
+ spin_lock_irqsave(&iommu->register_lock, flags);
+
+ /* write zero to the tail reg */
+ writel(0, iommu->reg + DMAR_IQT_REG);
+
+ dmar_writeq(iommu->reg + DMAR_IQA_REG, virt_to_phys(qi->desc));
+
+ cmd = iommu->gcmd | DMA_GCMD_QIE;
+ iommu->gcmd |= DMA_GCMD_QIE;
+ writel(cmd, iommu->reg + DMAR_GCMD_REG);
+
+ /* Make sure hardware complete it */
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_QIES), sts);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flags);
+}
+
+/*
* Enable Queued Invalidation interface. This is a must to support
* interrupt-remapping. Also used by DMA-remapping, which replaces
* register based IOTLB invalidation.
*/
int dmar_enable_qi(struct intel_iommu *iommu)
{
- u32 cmd, sts;
- unsigned long flags;
struct q_inval *qi;
if (!ecap_qis(iommu->ecap))
@@ -835,19 +872,7 @@ int dmar_enable_qi(struct intel_iommu *iommu)
spin_lock_init(&qi->q_lock);
- spin_lock_irqsave(&iommu->register_lock, flags);
- /* write zero to the tail reg */
- writel(0, iommu->reg + DMAR_IQT_REG);
-
- dmar_writeq(iommu->reg + DMAR_IQA_REG, virt_to_phys(qi->desc));
-
- cmd = iommu->gcmd | DMA_GCMD_QIE;
- iommu->gcmd |= DMA_GCMD_QIE;
- writel(cmd, iommu->reg + DMAR_GCMD_REG);
-
- /* Make sure hardware complete it */
- IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_QIES), sts);
- spin_unlock_irqrestore(&iommu->register_lock, flags);
+ __dmar_enable_qi(iommu);
return 0;
}
@@ -1102,3 +1127,28 @@ int __init enable_drhd_fault_handling(void)
return 0;
}
+
+/*
+ * Re-enable Queued Invalidation interface.
+ */
+int dmar_reenable_qi(struct intel_iommu *iommu)
+{
+ if (!ecap_qis(iommu->ecap))
+ return -ENOENT;
+
+ if (!iommu->qi)
+ return -ENOENT;
+
+ /*
+ * First disable queued invalidation.
+ */
+ dmar_disable_qi(iommu);
+ /*
+ * Then enable queued invalidation again. Since there is no pending
+ * invalidation requests now, it's safe to re-enable queued
+ * invalidation.
+ */
+ __dmar_enable_qi(iommu);
+
+ return 0;
+}
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 803d9ddd6e7..a33794d9e0d 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -38,6 +38,8 @@
* - The one in acpiphp_bridge has its refcount elevated by pci_get_slot()
* when the bridge is scanned and it loses a refcount when the bridge
* is removed.
+ * - When a P2P bridge is present, we elevate the refcount on the subordinate
+ * bus. It loses the refcount when the the driver unloads.
*/
#include <linux/init.h>
@@ -440,6 +442,12 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
goto err;
}
+ /*
+ * Grab a ref to the subordinate PCI bus in case the bus is
+ * removed via PCI core logical hotplug. The ref pins the bus
+ * (which we access during module unload).
+ */
+ get_device(&bridge->pci_bus->dev);
spin_lock_init(&bridge->res_lock);
init_bridge_misc(bridge);
@@ -619,6 +627,12 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
slot = next;
}
+ /*
+ * Only P2P bridges have a pci_dev
+ */
+ if (bridge->pci_dev)
+ put_device(&bridge->pci_bus->dev);
+
pci_dev_put(bridge->pci_dev);
list_del(&bridge->list);
kfree(bridge);
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 9dbd5066aca..001b328adf8 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -36,6 +36,7 @@
#include <linux/iova.h>
#include <linux/iommu.h>
#include <linux/intel-iommu.h>
+#include <linux/sysdev.h>
#include <asm/cacheflush.h>
#include <asm/iommu.h>
#include "pci.h"
@@ -55,8 +56,8 @@
#define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1)
#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
-#define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK)
-#define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK)
+#define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32))
+#define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64))
/* global iommu list, set NULL for ignored DMAR units */
static struct intel_iommu **g_iommus;
@@ -164,7 +165,8 @@ static inline void context_clear_entry(struct context_entry *context)
* 1: writable
* 2-6: reserved
* 7: super page
- * 8-11: available
+ * 8-10: available
+ * 11: snoop behavior
* 12-63: Host physcial address
*/
struct dma_pte {
@@ -186,6 +188,11 @@ static inline void dma_set_pte_writable(struct dma_pte *pte)
pte->val |= DMA_PTE_WRITE;
}
+static inline void dma_set_pte_snp(struct dma_pte *pte)
+{
+ pte->val |= DMA_PTE_SNP;
+}
+
static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot)
{
pte->val = (pte->val & ~3) | (prot & 3);
@@ -231,6 +238,7 @@ struct dmar_domain {
int flags; /* flags to find out type of domain */
int iommu_coherency;/* indicate coherency of iommu access */
+ int iommu_snooping; /* indicate snooping control feature*/
int iommu_count; /* reference count of iommu */
spinlock_t iommu_lock; /* protect iommu set in domain */
u64 max_addr; /* maximum mapped address */
@@ -240,7 +248,8 @@ struct dmar_domain {
struct device_domain_info {
struct list_head link; /* link to domain siblings */
struct list_head global; /* link to global list */
- u8 bus; /* PCI bus numer */
+ int segment; /* PCI domain */
+ u8 bus; /* PCI bus number */
u8 devfn; /* PCI devfn number */
struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */
struct dmar_domain *domain; /* pointer to domain */
@@ -421,7 +430,6 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
return g_iommus[iommu_id];
}
-/* "Coherency" capability may be different across iommus */
static void domain_update_iommu_coherency(struct dmar_domain *domain)
{
int i;
@@ -438,7 +446,30 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain)
}
}
-static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn)
+static void domain_update_iommu_snooping(struct dmar_domain *domain)
+{
+ int i;
+
+ domain->iommu_snooping = 1;
+
+ i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus);
+ for (; i < g_num_of_iommus; ) {
+ if (!ecap_sc_support(g_iommus[i]->ecap)) {
+ domain->iommu_snooping = 0;
+ break;
+ }
+ i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1);
+ }
+}
+
+/* Some capabilities may be different across iommus */
+static void domain_update_iommu_cap(struct dmar_domain *domain)
+{
+ domain_update_iommu_coherency(domain);
+ domain_update_iommu_snooping(domain);
+}
+
+static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn)
{
struct dmar_drhd_unit *drhd = NULL;
int i;
@@ -446,12 +477,20 @@ static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn)
for_each_drhd_unit(drhd) {
if (drhd->ignored)
continue;
+ if (segment != drhd->segment)
+ continue;
- for (i = 0; i < drhd->devices_cnt; i++)
+ for (i = 0; i < drhd->devices_cnt; i++) {
if (drhd->devices[i] &&
drhd->devices[i]->bus->number == bus &&
drhd->devices[i]->devfn == devfn)
return drhd->iommu;
+ if (drhd->devices[i] &&
+ drhd->devices[i]->subordinate &&
+ drhd->devices[i]->subordinate->number <= bus &&
+ drhd->devices[i]->subordinate->subordinate >= bus)
+ return drhd->iommu;
+ }
if (drhd->include_all)
return drhd->iommu;
@@ -689,15 +728,17 @@ static void dma_pte_clear_one(struct dmar_domain *domain, u64 addr)
static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end)
{
int addr_width = agaw_to_width(domain->agaw);
+ int npages;
start &= (((u64)1) << addr_width) - 1;
end &= (((u64)1) << addr_width) - 1;
/* in case it's partial page */
- start = PAGE_ALIGN(start);
- end &= PAGE_MASK;
+ start &= PAGE_MASK;
+ end = PAGE_ALIGN(end);
+ npages = (end - start) / VTD_PAGE_SIZE;
/* we don't need lock here, nobody else touches the iova range */
- while (start < end) {
+ while (npages--) {
dma_pte_clear_one(domain, start);
start += VTD_PAGE_SIZE;
}
@@ -1241,6 +1282,11 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
else
domain->iommu_coherency = 0;
+ if (ecap_sc_support(iommu->ecap))
+ domain->iommu_snooping = 1;
+ else
+ domain->iommu_snooping = 0;
+
domain->iommu_count = 1;
/* always allocate the top pgd */
@@ -1276,7 +1322,7 @@ static void domain_exit(struct dmar_domain *domain)
}
static int domain_context_mapping_one(struct dmar_domain *domain,
- u8 bus, u8 devfn)
+ int segment, u8 bus, u8 devfn)
{
struct context_entry *context;
unsigned long flags;
@@ -1291,7 +1337,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
BUG_ON(!domain->pgd);
- iommu = device_to_iommu(bus, devfn);
+ iommu = device_to_iommu(segment, bus, devfn);
if (!iommu)
return -ENODEV;
@@ -1369,7 +1415,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
spin_lock_irqsave(&domain->iommu_lock, flags);
if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) {
domain->iommu_count++;
- domain_update_iommu_coherency(domain);
+ domain_update_iommu_cap(domain);
}
spin_unlock_irqrestore(&domain->iommu_lock, flags);
return 0;
@@ -1381,8 +1427,8 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
int ret;
struct pci_dev *tmp, *parent;
- ret = domain_context_mapping_one(domain, pdev->bus->number,
- pdev->devfn);
+ ret = domain_context_mapping_one(domain, pci_domain_nr(pdev->bus),
+ pdev->bus->number, pdev->devfn);
if (ret)
return ret;
@@ -1393,18 +1439,23 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
/* Secondary interface's bus number and devfn 0 */
parent = pdev->bus->self;
while (parent != tmp) {
- ret = domain_context_mapping_one(domain, parent->bus->number,
- parent->devfn);
+ ret = domain_context_mapping_one(domain,
+ pci_domain_nr(parent->bus),
+ parent->bus->number,
+ parent->devfn);
if (ret)
return ret;
parent = parent->bus->self;
}
if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
return domain_context_mapping_one(domain,
- tmp->subordinate->number, 0);
+ pci_domain_nr(tmp->subordinate),
+ tmp->subordinate->number, 0);
else /* this is a legacy PCI bridge */
return domain_context_mapping_one(domain,
- tmp->bus->number, tmp->devfn);
+ pci_domain_nr(tmp->bus),
+ tmp->bus->number,
+ tmp->devfn);
}
static int domain_context_mapped(struct pci_dev *pdev)
@@ -1413,12 +1464,12 @@ static int domain_context_mapped(struct pci_dev *pdev)
struct pci_dev *tmp, *parent;
struct intel_iommu *iommu;
- iommu = device_to_iommu(pdev->bus->number, pdev->devfn);
+ iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
+ pdev->devfn);
if (!iommu)
return -ENODEV;
- ret = device_context_mapped(iommu,
- pdev->bus->number, pdev->devfn);
+ ret = device_context_mapped(iommu, pdev->bus->number, pdev->devfn);
if (!ret)
return ret;
/* dependent device mapping */
@@ -1429,17 +1480,17 @@ static int domain_context_mapped(struct pci_dev *pdev)
parent = pdev->bus->self;
while (parent != tmp) {
ret = device_context_mapped(iommu, parent->bus->number,
- parent->devfn);
+ parent->devfn);
if (!ret)
return ret;
parent = parent->bus->self;
}
if (tmp->is_pcie)
- return device_context_mapped(iommu,
- tmp->subordinate->number, 0);
+ return device_context_mapped(iommu, tmp->subordinate->number,
+ 0);
else
- return device_context_mapped(iommu,
- tmp->bus->number, tmp->devfn);
+ return device_context_mapped(iommu, tmp->bus->number,
+ tmp->devfn);
}
static int
@@ -1469,6 +1520,8 @@ domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova,
BUG_ON(dma_pte_addr(pte));
dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT);
dma_set_pte_prot(pte, prot);
+ if (prot & DMA_PTE_SNP)
+ dma_set_pte_snp(pte);
domain_flush_cache(domain, pte, sizeof(*pte));
start_pfn++;
index++;
@@ -1504,7 +1557,7 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
info->dev->dev.archdata.iommu = NULL;
spin_unlock_irqrestore(&device_domain_lock, flags);
- iommu = device_to_iommu(info->bus, info->devfn);
+ iommu = device_to_iommu(info->segment, info->bus, info->devfn);
iommu_detach_dev(iommu, info->bus, info->devfn);
free_devinfo_mem(info);
@@ -1539,11 +1592,14 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
struct pci_dev *dev_tmp;
unsigned long flags;
int bus = 0, devfn = 0;
+ int segment;
domain = find_domain(pdev);
if (domain)
return domain;
+ segment = pci_domain_nr(pdev->bus);
+
dev_tmp = pci_find_upstream_pcie_bridge(pdev);
if (dev_tmp) {
if (dev_tmp->is_pcie) {
@@ -1555,7 +1611,8 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
}
spin_lock_irqsave(&device_domain_lock, flags);
list_for_each_entry(info, &device_domain_list, global) {
- if (info->bus == bus && info->devfn == devfn) {
+ if (info->segment == segment &&
+ info->bus == bus && info->devfn == devfn) {
found = info->domain;
break;
}
@@ -1593,6 +1650,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
domain_exit(domain);
goto error;
}
+ info->segment = segment;
info->bus = bus;
info->devfn = devfn;
info->dev = NULL;
@@ -1604,7 +1662,8 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
found = NULL;
spin_lock_irqsave(&device_domain_lock, flags);
list_for_each_entry(tmp, &device_domain_list, global) {
- if (tmp->bus == bus && tmp->devfn == devfn) {
+ if (tmp->segment == segment &&
+ tmp->bus == bus && tmp->devfn == devfn) {
found = tmp->domain;
break;
}
@@ -1624,6 +1683,7 @@ found_domain:
info = alloc_devinfo_mem();
if (!info)
goto error;
+ info->segment = segment;
info->bus = pdev->bus->number;
info->devfn = pdev->devfn;
info->dev = pdev;
@@ -1908,6 +1968,15 @@ static int __init init_dmars(void)
}
}
+#ifdef CONFIG_INTR_REMAP
+ if (!intr_remapping_enabled) {
+ ret = enable_intr_remapping(0);
+ if (ret)
+ printk(KERN_ERR
+ "IOMMU: enable interrupt remapping failed\n");
+ }
+#endif
+
/*
* For each rmrr
* for each dev attached to rmrr
@@ -2011,15 +2080,15 @@ __intel_alloc_iova(struct device *dev, struct dmar_domain *domain,
struct pci_dev *pdev = to_pci_dev(dev);
struct iova *iova = NULL;
- if (dma_mask <= DMA_32BIT_MASK || dmar_forcedac)
+ if (dma_mask <= DMA_BIT_MASK(32) || dmar_forcedac)
iova = iommu_alloc_iova(domain, size, dma_mask);
else {
/*
* First try to allocate an io virtual address in
- * DMA_32BIT_MASK and if that fails then try allocating
+ * DMA_BIT_MASK(32) and if that fails then try allocating
* from higher range
*/
- iova = iommu_alloc_iova(domain, size, DMA_32BIT_MASK);
+ iova = iommu_alloc_iova(domain, size, DMA_BIT_MASK(32));
if (!iova)
iova = iommu_alloc_iova(domain, size, dma_mask);
}
@@ -2119,7 +2188,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr,
error:
if (iova)
__free_iova(&domain->iovad, iova);
- printk(KERN_ERR"Device %s request: %lx@%llx dir %d --- failed\n",
+ printk(KERN_ERR"Device %s request: %zx@%llx dir %d --- failed\n",
pci_name(pdev), size, (unsigned long long)paddr, dir);
return 0;
}
@@ -2218,7 +2287,7 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
start_addr = iova->pfn_lo << PAGE_SHIFT;
size = aligned_size((u64)dev_addr, size);
- pr_debug("Device %s unmapping: %lx@%llx\n",
+ pr_debug("Device %s unmapping: %zx@%llx\n",
pci_name(pdev), size, (unsigned long long)start_addr);
/* clear the whole page */
@@ -2282,8 +2351,6 @@ static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
free_pages((unsigned long)vaddr, order);
}
-#define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg)))
-
static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
int nelems, enum dma_data_direction dir,
struct dma_attrs *attrs)
@@ -2294,7 +2361,7 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
unsigned long start_addr;
struct iova *iova;
size_t size = 0;
- void *addr;
+ phys_addr_t addr;
struct scatterlist *sg;
struct intel_iommu *iommu;
@@ -2310,7 +2377,7 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
if (!iova)
return;
for_each_sg(sglist, sg, nelems, i) {
- addr = SG_ENT_VIRT_ADDRESS(sg);
+ addr = page_to_phys(sg_page(sg)) + sg->offset;
size += aligned_size((u64)addr, sg->length);
}
@@ -2337,7 +2404,7 @@ static int intel_nontranslate_map_sg(struct device *hddev,
for_each_sg(sglist, sg, nelems, i) {
BUG_ON(!sg_page(sg));
- sg->dma_address = virt_to_bus(SG_ENT_VIRT_ADDRESS(sg));
+ sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
sg->dma_length = sg->length;
}
return nelems;
@@ -2346,7 +2413,7 @@ static int intel_nontranslate_map_sg(struct device *hddev,
static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
enum dma_data_direction dir, struct dma_attrs *attrs)
{
- void *addr;
+ phys_addr_t addr;
int i;
struct pci_dev *pdev = to_pci_dev(hwdev);
struct dmar_domain *domain;
@@ -2370,8 +2437,7 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne
iommu = domain_get_iommu(domain);
for_each_sg(sglist, sg, nelems, i) {
- addr = SG_ENT_VIRT_ADDRESS(sg);
- addr = (void *)virt_to_phys(addr);
+ addr = page_to_phys(sg_page(sg)) + sg->offset;
size += aligned_size((u64)addr, sg->length);
}
@@ -2394,8 +2460,7 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne
start_addr = iova->pfn_lo << PAGE_SHIFT;
offset = 0;
for_each_sg(sglist, sg, nelems, i) {
- addr = SG_ENT_VIRT_ADDRESS(sg);
- addr = (void *)virt_to_phys(addr);
+ addr = page_to_phys(sg_page(sg)) + sg->offset;
size = aligned_size((u64)addr, sg->length);
ret = domain_page_mapping(domain, start_addr + offset,
((u64)addr) & PAGE_MASK,
@@ -2563,6 +2628,150 @@ static void __init init_no_remapping_devices(void)
}
}
+#ifdef CONFIG_SUSPEND
+static int init_iommu_hw(void)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu = NULL;
+
+ for_each_active_iommu(iommu, drhd)
+ if (iommu->qi)
+ dmar_reenable_qi(iommu);
+
+ for_each_active_iommu(iommu, drhd) {
+ iommu_flush_write_buffer(iommu);
+
+ iommu_set_root_entry(iommu);
+
+ iommu->flush.flush_context(iommu, 0, 0, 0,
+ DMA_CCMD_GLOBAL_INVL, 0);
+ iommu->flush.flush_iotlb(iommu, 0, 0, 0,
+ DMA_TLB_GLOBAL_FLUSH, 0);
+ iommu_disable_protect_mem_regions(iommu);
+ iommu_enable_translation(iommu);
+ }
+
+ return 0;
+}
+
+static void iommu_flush_all(void)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu;
+
+ for_each_active_iommu(iommu, drhd) {
+ iommu->flush.flush_context(iommu, 0, 0, 0,
+ DMA_CCMD_GLOBAL_INVL, 0);
+ iommu->flush.flush_iotlb(iommu, 0, 0, 0,
+ DMA_TLB_GLOBAL_FLUSH, 0);
+ }
+}
+
+static int iommu_suspend(struct sys_device *dev, pm_message_t state)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu = NULL;
+ unsigned long flag;
+
+ for_each_active_iommu(iommu, drhd) {
+ iommu->iommu_state = kzalloc(sizeof(u32) * MAX_SR_DMAR_REGS,
+ GFP_ATOMIC);
+ if (!iommu->iommu_state)
+ goto nomem;
+ }
+
+ iommu_flush_all();
+
+ for_each_active_iommu(iommu, drhd) {
+ iommu_disable_translation(iommu);
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+
+ iommu->iommu_state[SR_DMAR_FECTL_REG] =
+ readl(iommu->reg + DMAR_FECTL_REG);
+ iommu->iommu_state[SR_DMAR_FEDATA_REG] =
+ readl(iommu->reg + DMAR_FEDATA_REG);
+ iommu->iommu_state[SR_DMAR_FEADDR_REG] =
+ readl(iommu->reg + DMAR_FEADDR_REG);
+ iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
+ readl(iommu->reg + DMAR_FEUADDR_REG);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+ }
+ return 0;
+
+nomem:
+ for_each_active_iommu(iommu, drhd)
+ kfree(iommu->iommu_state);
+
+ return -ENOMEM;
+}
+
+static int iommu_resume(struct sys_device *dev)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu = NULL;
+ unsigned long flag;
+
+ if (init_iommu_hw()) {
+ WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
+ return -EIO;
+ }
+
+ for_each_active_iommu(iommu, drhd) {
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+
+ writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
+ iommu->reg + DMAR_FECTL_REG);
+ writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
+ iommu->reg + DMAR_FEDATA_REG);
+ writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
+ iommu->reg + DMAR_FEADDR_REG);
+ writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
+ iommu->reg + DMAR_FEUADDR_REG);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+ }
+
+ for_each_active_iommu(iommu, drhd)
+ kfree(iommu->iommu_state);
+
+ return 0;
+}
+
+static struct sysdev_class iommu_sysclass = {
+ .name = "iommu",
+ .resume = iommu_resume,
+ .suspend = iommu_suspend,
+};
+
+static struct sys_device device_iommu = {
+ .cls = &iommu_sysclass,
+};
+
+static int __init init_iommu_sysfs(void)
+{
+ int error;
+
+ error = sysdev_class_register(&iommu_sysclass);
+ if (error)
+ return error;
+
+ error = sysdev_register(&device_iommu);
+ if (error)
+ sysdev_class_unregister(&iommu_sysclass);
+
+ return error;
+}
+
+#else
+static int __init init_iommu_sysfs(void)
+{
+ return 0;
+}
+#endif /* CONFIG_PM */
+
int __init intel_iommu_init(void)
{
int ret = 0;
@@ -2598,6 +2807,7 @@ int __init intel_iommu_init(void)
init_timer(&unmap_timer);
force_iommu = 1;
dma_ops = &intel_dma_ops;
+ init_iommu_sysfs();
register_iommu(&intel_iommu_ops);
@@ -2614,6 +2824,7 @@ static int vm_domain_add_dev_info(struct dmar_domain *domain,
if (!info)
return -ENOMEM;
+ info->segment = pci_domain_nr(pdev->bus);
info->bus = pdev->bus->number;
info->devfn = pdev->devfn;
info->dev = pdev;
@@ -2628,6 +2839,33 @@ static int vm_domain_add_dev_info(struct dmar_domain *domain,
return 0;
}
+static void iommu_detach_dependent_devices(struct intel_iommu *iommu,
+ struct pci_dev *pdev)
+{
+ struct pci_dev *tmp, *parent;
+
+ if (!iommu || !pdev)
+ return;
+
+ /* dependent device detach */
+ tmp = pci_find_upstream_pcie_bridge(pdev);
+ /* Secondary interface's bus number and devfn 0 */
+ if (tmp) {
+ parent = pdev->bus->self;
+ while (parent != tmp) {
+ iommu_detach_dev(iommu, parent->bus->number,
+ parent->devfn);
+ parent = parent->bus->self;
+ }
+ if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
+ iommu_detach_dev(iommu,
+ tmp->subordinate->number, 0);
+ else /* this is a legacy PCI bridge */
+ iommu_detach_dev(iommu, tmp->bus->number,
+ tmp->devfn);
+ }
+}
+
static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
struct pci_dev *pdev)
{
@@ -2637,13 +2875,15 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
int found = 0;
struct list_head *entry, *tmp;
- iommu = device_to_iommu(pdev->bus->number, pdev->devfn);
+ iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
+ pdev->devfn);
if (!iommu)
return;
spin_lock_irqsave(&device_domain_lock, flags);
list_for_each_safe(entry, tmp, &domain->devices) {
info = list_entry(entry, struct device_domain_info, link);
+ /* No need to compare PCI domain; it has to be the same */
if (info->bus == pdev->bus->number &&
info->devfn == pdev->devfn) {
list_del(&info->link);
@@ -2653,6 +2893,7 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
spin_unlock_irqrestore(&device_domain_lock, flags);
iommu_detach_dev(iommu, info->bus, info->devfn);
+ iommu_detach_dependent_devices(iommu, pdev);
free_devinfo_mem(info);
spin_lock_irqsave(&device_domain_lock, flags);
@@ -2667,7 +2908,8 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
* owned by this domain, clear this iommu in iommu_bmp
* update iommu count and coherency
*/
- if (device_to_iommu(info->bus, info->devfn) == iommu)
+ if (iommu == device_to_iommu(info->segment, info->bus,
+ info->devfn))
found = 1;
}
@@ -2676,7 +2918,7 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
spin_lock_irqsave(&domain->iommu_lock, tmp_flags);
clear_bit(iommu->seq_id, &domain->iommu_bmp);
domain->iommu_count--;
- domain_update_iommu_coherency(domain);
+ domain_update_iommu_cap(domain);
spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
}
@@ -2700,17 +2942,18 @@ static void vm_domain_remove_all_dev_info(struct dmar_domain *domain)
spin_unlock_irqrestore(&device_domain_lock, flags1);
- iommu = device_to_iommu(info->bus, info->devfn);
+ iommu = device_to_iommu(info->segment, info->bus, info->devfn);
iommu_detach_dev(iommu, info->bus, info->devfn);
+ iommu_detach_dependent_devices(iommu, info->dev);
/* clear this iommu in iommu_bmp, update iommu count
- * and coherency
+ * and capabilities
*/
spin_lock_irqsave(&domain->iommu_lock, flags2);
if (test_and_clear_bit(iommu->seq_id,
&domain->iommu_bmp)) {
domain->iommu_count--;
- domain_update_iommu_coherency(domain);
+ domain_update_iommu_cap(domain);
}
spin_unlock_irqrestore(&domain->iommu_lock, flags2);
@@ -2887,7 +3130,8 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
}
}
- iommu = device_to_iommu(pdev->bus->number, pdev->devfn);
+ iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
+ pdev->devfn);
if (!iommu)
return -ENODEV;
@@ -2933,6 +3177,8 @@ static int intel_iommu_map_range(struct iommu_domain *domain,
prot |= DMA_PTE_READ;
if (iommu_prot & IOMMU_WRITE)
prot |= DMA_PTE_WRITE;
+ if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
+ prot |= DMA_PTE_SNP;
max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size);
if (dmar_domain->max_addr < max_addr) {
@@ -2986,6 +3232,17 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
return phys;
}
+static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap)
+{
+ struct dmar_domain *dmar_domain = domain->priv;
+
+ if (cap == IOMMU_CAP_CACHE_COHERENCY)
+ return dmar_domain->iommu_snooping;
+
+ return 0;
+}
+
static struct iommu_ops intel_iommu_ops = {
.domain_init = intel_iommu_domain_init,
.domain_destroy = intel_iommu_domain_destroy,
@@ -2994,6 +3251,7 @@ static struct iommu_ops intel_iommu_ops = {
.map = intel_iommu_map_range,
.unmap = intel_iommu_unmap_range,
.iova_to_phys = intel_iommu_iova_to_phys,
+ .domain_has_cap = intel_iommu_domain_has_cap,
};
static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index b041a409f4a..f5e0ea724a6 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -9,6 +9,7 @@
#include <asm/cpu.h>
#include <linux/intel-iommu.h>
#include "intr_remapping.h"
+#include <acpi/acpi.h>
static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
static int ir_ioapic_num;
@@ -415,12 +416,27 @@ static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
/* Set interrupt-remapping table pointer */
cmd = iommu->gcmd | DMA_GCMD_SIRTP;
+ iommu->gcmd |= DMA_GCMD_SIRTP;
writel(cmd, iommu->reg + DMAR_GCMD_REG);
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
readl, (sts & DMA_GSTS_IRTPS), sts);
spin_unlock_irqrestore(&iommu->register_lock, flags);
+ if (mode == 0) {
+ spin_lock_irqsave(&iommu->register_lock, flags);
+
+ /* enable comaptiblity format interrupt pass through */
+ cmd = iommu->gcmd | DMA_GCMD_CFI;
+ iommu->gcmd |= DMA_GCMD_CFI;
+ writel(cmd, iommu->reg + DMAR_GCMD_REG);
+
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+ readl, (sts & DMA_GSTS_CFIS), sts);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flags);
+ }
+
/*
* global invalidation of interrupt entry cache before enabling
* interrupt-remapping.
@@ -470,7 +486,7 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode)
/*
* Disable Interrupt Remapping.
*/
-static void disable_intr_remapping(struct intel_iommu *iommu)
+static void iommu_disable_intr_remapping(struct intel_iommu *iommu)
{
unsigned long flags;
u32 sts;
@@ -478,6 +494,12 @@ static void disable_intr_remapping(struct intel_iommu *iommu)
if (!ecap_ir_support(iommu->ecap))
return;
+ /*
+ * global invalidation of interrupt entry cache before disabling
+ * interrupt-remapping.
+ */
+ qi_global_iec(iommu);
+
spin_lock_irqsave(&iommu->register_lock, flags);
sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
@@ -503,6 +525,13 @@ int __init enable_intr_remapping(int eim)
struct intel_iommu *iommu = drhd->iommu;
/*
+ * If the queued invalidation is already initialized,
+ * shouldn't disable it.
+ */
+ if (iommu->qi)
+ continue;
+
+ /*
* Clear previous faults.
*/
dmar_fault(-1, iommu);
@@ -511,7 +540,7 @@ int __init enable_intr_remapping(int eim)
* Disable intr remapping and queued invalidation, if already
* enabled prior to OS handover.
*/
- disable_intr_remapping(iommu);
+ iommu_disable_intr_remapping(iommu);
dmar_disable_qi(iommu);
}
@@ -639,3 +668,54 @@ int __init parse_ioapics_under_ir(void)
return ir_supported;
}
+
+void disable_intr_remapping(void)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu = NULL;
+
+ /*
+ * Disable Interrupt-remapping for all the DRHD's now.
+ */
+ for_each_iommu(iommu, drhd) {
+ if (!ecap_ir_support(iommu->ecap))
+ continue;
+
+ iommu_disable_intr_remapping(iommu);
+ }
+}
+
+int reenable_intr_remapping(int eim)
+{
+ struct dmar_drhd_unit *drhd;
+ int setup = 0;
+ struct intel_iommu *iommu = NULL;
+
+ for_each_iommu(iommu, drhd)
+ if (iommu->qi)
+ dmar_reenable_qi(iommu);
+
+ /*
+ * Setup Interrupt-remapping for all the DRHD's now.
+ */
+ for_each_iommu(iommu, drhd) {
+ if (!ecap_ir_support(iommu->ecap))
+ continue;
+
+ /* Set up interrupt remapping for iommu.*/
+ iommu_set_intr_remapping(iommu, eim);
+ setup = 1;
+ }
+
+ if (!setup)
+ goto error;
+
+ return 0;
+
+error:
+ /*
+ * handle error condition gracefully here!
+ */
+ return -1;
+}
+
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 7227efc760d..b497daab3d4 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -631,6 +631,7 @@ int pci_iov_bus_range(struct pci_bus *bus)
/**
* pci_enable_sriov - enable the SR-IOV capability
* @dev: the PCI device
+ * @nr_virtfn: number of virtual functions to enable
*
* Returns 0 on success, or negative on failure.
*/
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index fac5eddcefd..ea15b053745 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -171,12 +171,12 @@ static int __init acpi_pci_init(void)
{
int ret;
- if (acpi_gbl_FADT.boot_flags & BAF_MSI_NOT_SUPPORTED) {
+ if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) {
printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n");
pci_no_msi();
}
- if (acpi_gbl_FADT.boot_flags & BAF_PCIE_ASPM_CONTROL) {
+ if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
pcie_no_aspm();
}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index c0cbbb5a245..d76c4c85367 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -277,10 +277,9 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
node = dev_to_node(&dev->dev);
if (node >= 0) {
int cpu;
- node_to_cpumask_ptr(nodecpumask, node);
get_online_cpus();
- cpu = cpumask_any_and(nodecpumask, cpu_online_mask);
+ cpu = cpumask_any_and(cpumask_of_node(node), cpu_online_mask);
if (cpu < nr_cpu_ids)
error = work_on_cpu(cpu, local_pci_probe, &ddi);
else
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index e9a8706a640..a7eb1b46a5a 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -148,7 +148,7 @@ static ssize_t is_enabled_store(struct device *dev,
return -EPERM;
if (!val) {
- if (atomic_read(&pdev->enable_cnt) != 0)
+ if (pci_is_enabled(pdev))
pci_disable_device(pdev);
else
result = -EIO;
@@ -277,14 +277,10 @@ remove_store(struct device *dev, struct device_attribute *dummy,
{
int ret = 0;
unsigned long val;
- struct pci_dev *pdev = to_pci_dev(dev);
if (strict_strtoul(buf, 0, &val) < 0)
return -EINVAL;
- if (pci_is_root_bus(pdev->bus))
- return -EBUSY;
-
/* An attribute cannot be unregistered by one of its own methods,
* so we have to use this roundabout approach.
*/
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index fe7ac2cea7c..16fd0d4c316 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -593,7 +593,7 @@ EXPORT_SYMBOL_GPL(__pci_complete_power_transition);
* @dev: PCI device to handle.
* @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
*
- * Transition a device to a new power state, using the platform formware and/or
+ * Transition a device to a new power state, using the platform firmware and/or
* the device's PCI PM registers.
*
* RETURN VALUE:
@@ -844,7 +844,7 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
*/
int pci_reenable_device(struct pci_dev *dev)
{
- if (atomic_read(&dev->enable_cnt))
+ if (pci_is_enabled(dev))
return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1);
return 0;
}
@@ -1042,7 +1042,7 @@ static void do_pci_disable_device(struct pci_dev *dev)
*/
void pci_disable_enabled_device(struct pci_dev *dev)
{
- if (atomic_read(&dev->enable_cnt))
+ if (pci_is_enabled(dev))
do_pci_disable_device(dev);
}
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e2f3dd098cf..8eb50dffb78 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1220,7 +1220,7 @@ EXPORT_SYMBOL(pci_scan_bus_parented);
*
* Returns the max number of subordinate bus discovered.
*/
-unsigned int __devinit pci_rescan_bus(struct pci_bus *bus)
+unsigned int __ref pci_rescan_bus(struct pci_bus *bus)
{
unsigned int max;
struct pci_dev *dev;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 9b2f0d96900..0254741bece 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -36,17 +36,18 @@ EXPORT_SYMBOL(pcie_mch_quirk);
#ifdef CONFIG_PCI_QUIRKS
/*
- * This quirk function disables the device and releases resources
- * which is specified by kernel's boot parameter 'pci=resource_alignment='.
+ * This quirk function disables memory decoding and releases memory resources
+ * of the device specified by kernel's boot parameter 'pci=resource_alignment='.
* It also rounds up size to specified alignment.
* Later on, the kernel will assign page-aligned memory resource back
- * to that device.
+ * to the device.
*/
static void __devinit quirk_resource_alignment(struct pci_dev *dev)
{
int i;
struct resource *r;
resource_size_t align, size;
+ u16 command;
if (!pci_is_reassigndev(dev))
return;
@@ -58,8 +59,11 @@ static void __devinit quirk_resource_alignment(struct pci_dev *dev)
return;
}
- dev_info(&dev->dev, "Disabling device and release resources.\n");
- pci_disable_device(dev);
+ dev_info(&dev->dev,
+ "Disabling memory decoding and releasing memory resources.\n");
+ pci_read_config_word(dev, PCI_COMMAND, &command);
+ command &= ~PCI_COMMAND_MEMORY;
+ pci_write_config_word(dev, PCI_COMMAND, command);
align = pci_specified_resource_alignment(dev);
for (i=0; i < PCI_BRIDGE_RESOURCES; i++) {
@@ -2411,6 +2415,54 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375,
#endif /* CONFIG_PCI_MSI */
+#ifdef CONFIG_PCI_IOV
+
+/*
+ * For Intel 82576 SR-IOV NIC, if BIOS doesn't allocate resources for the
+ * SR-IOV BARs, zero the Flash BAR and program the SR-IOV BARs to use the
+ * old Flash Memory Space.
+ */
+static void __devinit quirk_i82576_sriov(struct pci_dev *dev)
+{
+ int pos, flags;
+ u32 bar, start, size;
+
+ if (PAGE_SIZE > 0x10000)
+ return;
+
+ flags = pci_resource_flags(dev, 0);
+ if ((flags & PCI_BASE_ADDRESS_SPACE) !=
+ PCI_BASE_ADDRESS_SPACE_MEMORY ||
+ (flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) !=
+ PCI_BASE_ADDRESS_MEM_TYPE_32)
+ return;
+
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
+ if (!pos)
+ return;
+
+ pci_read_config_dword(dev, pos + PCI_SRIOV_BAR, &bar);
+ if (bar & PCI_BASE_ADDRESS_MEM_MASK)
+ return;
+
+ start = pci_resource_start(dev, 1);
+ size = pci_resource_len(dev, 1);
+ if (!start || size != 0x400000 || start & (size - 1))
+ return;
+
+ pci_resource_flags(dev, 1) = 0;
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0);
+ pci_write_config_dword(dev, pos + PCI_SRIOV_BAR, start);
+ pci_write_config_dword(dev, pos + PCI_SRIOV_BAR + 12, start + size / 2);
+
+ dev_info(&dev->dev, "use Flash Memory Space for SR-IOV BARs\n");
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c9, quirk_i82576_sriov);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e6, quirk_i82576_sriov);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov);
+
+#endif /* CONFIG_PCI_IOV */
+
static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
struct pci_fixup *end)
{
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 334285a8e23..8d9da9d30a6 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -144,7 +144,7 @@ static void pci_setup_bridge(struct pci_bus *bus)
struct pci_bus_region region;
u32 l, bu, lu, io_upper16;
- if (!pci_is_root_bus(bus) && bus->is_added)
+ if (pci_is_enabled(bridge))
return;
dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n",
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c
index 4ed64d8e95e..5143a760153 100644
--- a/drivers/pcmcia/pxa2xx_cm_x255.c
+++ b/drivers/pcmcia/pxa2xx_cm_x255.c
@@ -63,7 +63,7 @@ static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
- int rdy = skt->nr ? GPIO_PCMCIA_S0_RDYINT : GPIO_PCMCIA_S1_RDYINT;
+ int rdy = skt->nr ? GPIO_PCMCIA_S1_RDYINT : GPIO_PCMCIA_S0_RDYINT;
state->detect = !gpio_get_value(cd);
state->ready = !!gpio_get_value(rdy);
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 3608081bc3e..284ebaca6e4 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -67,6 +67,16 @@ config DELL_LAPTOP
This driver adds support for rfkill and backlight control to Dell
laptops.
+config DELL_WMI
+ tristate "Dell WMI extras"
+ depends on ACPI_WMI
+ depends on INPUT
+ ---help---
+ Say Y here if you want to support WMI-based hotkeys on Dell laptops.
+
+ To compile this driver as a module, choose M here: the module will
+ be called dell-wmi.
+
config FUJITSU_LAPTOP
tristate "Fujitsu Laptop Extras"
depends on ACPI
@@ -165,6 +175,7 @@ config SONY_LAPTOP
depends on ACPI
select BACKLIGHT_CLASS_DEVICE
depends on INPUT
+ depends on RFKILL
---help---
This mini-driver drives the SNC and SPIC devices present in the ACPI
BIOS of the Sony Vaio laptops.
@@ -226,6 +237,30 @@ config THINKPAD_ACPI_DEBUG
If you are not sure, say N here.
+config THINKPAD_ACPI_UNSAFE_LEDS
+ bool "Allow control of important LEDs (unsafe)"
+ depends on THINKPAD_ACPI
+ default n
+ ---help---
+ Overriding LED state on ThinkPads can mask important
+ firmware alerts (like critical battery condition), or misled
+ the user into damaging the hardware (undocking or ejecting
+ the bay while buses are still active), etc.
+
+ LED control on the ThinkPad is write-only (with very few
+ exceptions on very ancient models), which makes it
+ impossible to know beforehand if important information will
+ be lost when one changes LED state.
+
+ Users that know what they are doing can enable this option
+ and the driver will allow control of every LED, including
+ the ones on the dock stations.
+
+ Never enable this option on a distribution kernel.
+
+ Say N here, unless you are building a kernel for your own
+ use, and need to control the important firmware LEDs.
+
config THINKPAD_ACPI_DOCK
bool "Legacy Docking Station Support"
depends on THINKPAD_ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index e29065120be..e40c7bd1b87 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
+obj-$(CONFIG_DELL_WMI) += dell-wmi.o
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
obj-$(CONFIG_HP_WMI) += hp-wmi.o
obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index a6a42e8c060..0f6e43bf4fc 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -1,7 +1,7 @@
/*
* Acer WMI Laptop Extras
*
- * Copyright (C) 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
+ * Copyright (C) 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk>
*
* Based on acer_acpi:
* Copyright (C) 2005-2007 E.M. Smith
@@ -225,6 +225,25 @@ static struct quirk_entry quirk_fujitsu_amilo_li_1718 = {
.wireless = 2,
};
+/* The Aspire One has a dummy ACPI-WMI interface - disable it */
+static struct dmi_system_id __devinitdata acer_blacklist[] = {
+ {
+ .ident = "Acer Aspire One (SSD)",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
+ },
+ },
+ {
+ .ident = "Acer Aspire One (HDD)",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
+ },
+ },
+ {}
+};
+
static struct dmi_system_id acer_quirks[] = {
{
.callback = dmi_matched,
@@ -1117,11 +1136,17 @@ static int __devinit acer_platform_probe(struct platform_device *device)
}
err = acer_rfkill_init(&device->dev);
+ if (err)
+ goto error_rfkill;
return err;
+error_rfkill:
+ if (has_cap(ACER_CAP_BRIGHTNESS))
+ acer_backlight_exit();
error_brightness:
- acer_led_exit();
+ if (has_cap(ACER_CAP_MAILLED))
+ acer_led_exit();
error_mailled:
return err;
}
@@ -1254,6 +1279,12 @@ static int __init acer_wmi_init(void)
printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n");
+ if (dmi_check_system(acer_blacklist)) {
+ printk(ACER_INFO "Blacklisted hardware detected - "
+ "not loading\n");
+ return -ENODEV;
+ }
+
find_quirks();
/*
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
new file mode 100644
index 00000000000..2fab9416214
--- /dev/null
+++ b/drivers/platform/x86/dell-wmi.c
@@ -0,0 +1,210 @@
+/*
+ * Dell WMI hotkeys
+ *
+ * Copyright (C) 2008 Red Hat <mjg@redhat.com>
+ *
+ * Portions based on wistron_btns.c:
+ * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
+ * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
+ * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
+#include <linux/string.h>
+
+MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
+MODULE_DESCRIPTION("Dell laptop WMI hotkeys driver");
+MODULE_LICENSE("GPL");
+
+#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
+
+MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
+
+struct key_entry {
+ char type; /* See KE_* below */
+ u16 code;
+ u16 keycode;
+};
+
+enum { KE_KEY, KE_SW, KE_END };
+
+static struct key_entry dell_wmi_keymap[] = {
+ {KE_KEY, 0xe045, KEY_PROG1},
+ {KE_END, 0}
+};
+
+static struct input_dev *dell_wmi_input_dev;
+
+static struct key_entry *dell_wmi_get_entry_by_scancode(int code)
+{
+ struct key_entry *key;
+
+ for (key = dell_wmi_keymap; key->type != KE_END; key++)
+ if (code == key->code)
+ return key;
+
+ return NULL;
+}
+
+static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode)
+{
+ struct key_entry *key;
+
+ for (key = dell_wmi_keymap; key->type != KE_END; key++)
+ if (key->type == KE_KEY && keycode == key->keycode)
+ return key;
+
+ return NULL;
+}
+
+static int dell_wmi_getkeycode(struct input_dev *dev, int scancode,
+ int *keycode)
+{
+ struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode);
+
+ if (key && key->type == KE_KEY) {
+ *keycode = key->keycode;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int dell_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
+{
+ struct key_entry *key;
+ int old_keycode;
+
+ if (keycode < 0 || keycode > KEY_MAX)
+ return -EINVAL;
+
+ key = dell_wmi_get_entry_by_scancode(scancode);
+ if (key && key->type == KE_KEY) {
+ old_keycode = key->keycode;
+ key->keycode = keycode;
+ set_bit(keycode, dev->keybit);
+ if (!dell_wmi_get_entry_by_keycode(old_keycode))
+ clear_bit(old_keycode, dev->keybit);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static void dell_wmi_notify(u32 value, void *context)
+{
+ struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+ static struct key_entry *key;
+ union acpi_object *obj;
+
+ wmi_get_event_data(value, &response);
+
+ obj = (union acpi_object *)response.pointer;
+
+ if (obj && obj->type == ACPI_TYPE_BUFFER) {
+ int *buffer = (int *)obj->buffer.pointer;
+ key = dell_wmi_get_entry_by_scancode(buffer[1]);
+ if (key) {
+ input_report_key(dell_wmi_input_dev, key->keycode, 1);
+ input_sync(dell_wmi_input_dev);
+ input_report_key(dell_wmi_input_dev, key->keycode, 0);
+ input_sync(dell_wmi_input_dev);
+ } else
+ printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n",
+ buffer[1]);
+ }
+}
+
+static int __init dell_wmi_input_setup(void)
+{
+ struct key_entry *key;
+ int err;
+
+ dell_wmi_input_dev = input_allocate_device();
+
+ if (!dell_wmi_input_dev)
+ return -ENOMEM;
+
+ dell_wmi_input_dev->name = "Dell WMI hotkeys";
+ dell_wmi_input_dev->phys = "wmi/input0";
+ dell_wmi_input_dev->id.bustype = BUS_HOST;
+ dell_wmi_input_dev->getkeycode = dell_wmi_getkeycode;
+ dell_wmi_input_dev->setkeycode = dell_wmi_setkeycode;
+
+ for (key = dell_wmi_keymap; key->type != KE_END; key++) {
+ switch (key->type) {
+ case KE_KEY:
+ set_bit(EV_KEY, dell_wmi_input_dev->evbit);
+ set_bit(key->keycode, dell_wmi_input_dev->keybit);
+ break;
+ case KE_SW:
+ set_bit(EV_SW, dell_wmi_input_dev->evbit);
+ set_bit(key->keycode, dell_wmi_input_dev->swbit);
+ break;
+ }
+ }
+
+ err = input_register_device(dell_wmi_input_dev);
+
+ if (err) {
+ input_free_device(dell_wmi_input_dev);
+ return err;
+ }
+
+ return 0;
+}
+
+static int __init dell_wmi_init(void)
+{
+ int err;
+
+ if (wmi_has_guid(DELL_EVENT_GUID)) {
+ err = dell_wmi_input_setup();
+
+ if (err)
+ return err;
+
+ err = wmi_install_notify_handler(DELL_EVENT_GUID,
+ dell_wmi_notify, NULL);
+ if (err) {
+ input_unregister_device(dell_wmi_input_dev);
+ printk(KERN_ERR "dell-wmi: Unable to register"
+ " notify handler - %d\n", err);
+ return err;
+ }
+
+ } else
+ printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n");
+
+ return 0;
+}
+
+static void __exit dell_wmi_exit(void)
+{
+ if (wmi_has_guid(DELL_EVENT_GUID)) {
+ wmi_remove_notify_handler(DELL_EVENT_GUID);
+ input_unregister_device(dell_wmi_input_dev);
+ }
+}
+
+module_init(dell_wmi_init);
+module_exit(dell_wmi_exit);
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 45940f31fe9..218b9a16ac3 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -174,8 +174,7 @@ struct fujitsu_hotkey_t {
static struct fujitsu_hotkey_t *fujitsu_hotkey;
-static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
- void *data);
+static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event);
#ifdef CONFIG_LEDS_CLASS
static enum led_brightness logolamp_get(struct led_classdev *cdev);
@@ -203,7 +202,7 @@ struct led_classdev kblamps_led = {
static u32 dbg_level = 0x03;
#endif
-static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data);
+static void acpi_fujitsu_notify(struct acpi_device *device, u32 event);
/* Fujitsu ACPI interface function */
@@ -658,7 +657,6 @@ static struct dmi_system_id fujitsu_dmi_table[] = {
static int acpi_fujitsu_add(struct acpi_device *device)
{
- acpi_status status;
acpi_handle handle;
int result = 0;
int state = 0;
@@ -673,20 +671,10 @@ static int acpi_fujitsu_add(struct acpi_device *device)
sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
device->driver_data = fujitsu;
- status = acpi_install_notify_handler(device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_fujitsu_notify, fujitsu);
-
- if (ACPI_FAILURE(status)) {
- printk(KERN_ERR "Error installing notify handler\n");
- error = -ENODEV;
- goto err_stop;
- }
-
fujitsu->input = input = input_allocate_device();
if (!input) {
error = -ENOMEM;
- goto err_uninstall_notify;
+ goto err_stop;
}
snprintf(fujitsu->phys, sizeof(fujitsu->phys),
@@ -743,9 +731,6 @@ static int acpi_fujitsu_add(struct acpi_device *device)
end:
err_free_input_dev:
input_free_device(input);
-err_uninstall_notify:
- acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
- acpi_fujitsu_notify);
err_stop:
return result;
@@ -753,7 +738,6 @@ err_stop:
static int acpi_fujitsu_remove(struct acpi_device *device, int type)
{
- acpi_status status;
struct fujitsu_t *fujitsu = NULL;
if (!device || !acpi_driver_data(device))
@@ -761,10 +745,6 @@ static int acpi_fujitsu_remove(struct acpi_device *device, int type)
fujitsu = acpi_driver_data(device);
- status = acpi_remove_notify_handler(fujitsu->acpi_handle,
- ACPI_DEVICE_NOTIFY,
- acpi_fujitsu_notify);
-
if (!device || !acpi_driver_data(device))
return -EINVAL;
@@ -775,7 +755,7 @@ static int acpi_fujitsu_remove(struct acpi_device *device, int type)
/* Brightness notify */
-static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_fujitsu_notify(struct acpi_device *device, u32 event)
{
struct input_dev *input;
int keycode;
@@ -829,15 +809,12 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
input_report_key(input, keycode, 0);
input_sync(input);
}
-
- return;
}
/* ACPI device for hotkey handling */
static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
{
- acpi_status status;
acpi_handle handle;
int result = 0;
int state = 0;
@@ -854,17 +831,6 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
device->driver_data = fujitsu_hotkey;
- status = acpi_install_notify_handler(device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_fujitsu_hotkey_notify,
- fujitsu_hotkey);
-
- if (ACPI_FAILURE(status)) {
- printk(KERN_ERR "Error installing notify handler\n");
- error = -ENODEV;
- goto err_stop;
- }
-
/* kfifo */
spin_lock_init(&fujitsu_hotkey->fifo_lock);
fujitsu_hotkey->fifo =
@@ -879,7 +845,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
fujitsu_hotkey->input = input = input_allocate_device();
if (!input) {
error = -ENOMEM;
- goto err_uninstall_notify;
+ goto err_free_fifo;
}
snprintf(fujitsu_hotkey->phys, sizeof(fujitsu_hotkey->phys),
@@ -975,9 +941,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
end:
err_free_input_dev:
input_free_device(input);
-err_uninstall_notify:
- acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
- acpi_fujitsu_hotkey_notify);
+err_free_fifo:
kfifo_free(fujitsu_hotkey->fifo);
err_stop:
@@ -986,7 +950,6 @@ err_stop:
static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
{
- acpi_status status;
struct fujitsu_hotkey_t *fujitsu_hotkey = NULL;
if (!device || !acpi_driver_data(device))
@@ -994,10 +957,6 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
fujitsu_hotkey = acpi_driver_data(device);
- status = acpi_remove_notify_handler(fujitsu_hotkey->acpi_handle,
- ACPI_DEVICE_NOTIFY,
- acpi_fujitsu_hotkey_notify);
-
fujitsu_hotkey->acpi_handle = NULL;
kfifo_free(fujitsu_hotkey->fifo);
@@ -1005,8 +964,7 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
return 0;
}
-static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
- void *data)
+static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event)
{
struct input_dev *input;
int keycode, keycode_r;
@@ -1089,8 +1047,6 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
input_sync(input);
break;
}
-
- return;
}
/* Initialization */
@@ -1107,6 +1063,7 @@ static struct acpi_driver acpi_fujitsu_driver = {
.ops = {
.add = acpi_fujitsu_add,
.remove = acpi_fujitsu_remove,
+ .notify = acpi_fujitsu_notify,
},
};
@@ -1122,6 +1079,7 @@ static struct acpi_driver acpi_fujitsu_hotkey_driver = {
.ops = {
.add = acpi_fujitsu_hotkey_add,
.remove = acpi_fujitsu_hotkey_remove,
+ .notify = acpi_fujitsu_hotkey_notify,
},
};
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index f41135f2fb2..50d9019de2b 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -53,6 +53,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
static int __init hp_wmi_bios_setup(struct platform_device *device);
static int __exit hp_wmi_bios_remove(struct platform_device *device);
+static int hp_wmi_resume_handler(struct platform_device *device);
struct bios_args {
u32 signature;
@@ -101,6 +102,7 @@ static struct platform_driver hp_wmi_driver = {
},
.probe = hp_wmi_bios_setup,
.remove = hp_wmi_bios_remove,
+ .resume = hp_wmi_resume_handler,
};
static int hp_wmi_perform_query(int query, int write, int value)
@@ -487,6 +489,29 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device)
return 0;
}
+static int hp_wmi_resume_handler(struct platform_device *device)
+{
+ struct key_entry *key;
+
+ /*
+ * Docking state may have changed while suspended, so trigger
+ * an input event for the current state. As this is a switch,
+ * the input layer will only actually pass it on if the state
+ * changed.
+ */
+ for (key = hp_wmi_keymap; key->type != KE_END; key++) {
+ switch (key->type) {
+ case KE_SW:
+ input_report_switch(hp_wmi_input_dev, key->keycode,
+ hp_wmi_dock_state());
+ input_sync(hp_wmi_input_dev);
+ break;
+ }
+ }
+
+ return 0;
+}
+
static int __init hp_wmi_init(void)
{
int err;
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c
index 27b7662955b..29432a50be4 100644
--- a/drivers/platform/x86/intel_menlow.c
+++ b/drivers/platform/x86/intel_menlow.c
@@ -57,8 +57,8 @@ MODULE_LICENSE("GPL");
* In that case max_cstate would be n-1
* GTHS returning '0' would mean that no bandwidth control states are supported
*/
-static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
- unsigned long *max_state)
+static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
+ unsigned long *max_state)
{
struct acpi_device *device = cdev->devdata;
acpi_handle handle = device->handle;
@@ -83,22 +83,12 @@ static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
return 0;
}
-static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
- char *buf)
-{
- unsigned long value;
- if (memory_get_int_max_bandwidth(cdev, &value))
- return -EINVAL;
-
- return sprintf(buf, "%ld\n", value);
-}
-
static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
- char *buf)
+ unsigned long *value)
{
struct acpi_device *device = cdev->devdata;
acpi_handle handle = device->handle;
- unsigned long long value;
+ unsigned long long result;
struct acpi_object_list arg_list;
union acpi_object arg;
acpi_status status = AE_OK;
@@ -108,15 +98,16 @@ static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = MEMORY_ARG_CUR_BANDWIDTH;
status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH,
- &arg_list, &value);
+ &arg_list, &result);
if (ACPI_FAILURE(status))
return -EFAULT;
- return sprintf(buf, "%llu\n", value);
+ *value = result;
+ return 0;
}
static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
- unsigned int state)
+ unsigned long state)
{
struct acpi_device *device = cdev->devdata;
acpi_handle handle = device->handle;
@@ -126,7 +117,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
unsigned long long temp;
unsigned long max_state;
- if (memory_get_int_max_bandwidth(cdev, &max_state))
+ if (memory_get_max_bandwidth(cdev, &max_state))
return -EFAULT;
if (state > max_state)
@@ -142,7 +133,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
&temp);
printk(KERN_INFO
- "Bandwidth value was %d: status is %d\n", state, status);
+ "Bandwidth value was %ld: status is %d\n", state, status);
if (ACPI_FAILURE(status))
return -EFAULT;
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index c47a44dcb70..fe7cf0188ac 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -176,6 +176,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0,
static int acpi_pcc_hotkey_add(struct acpi_device *device);
static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type);
static int acpi_pcc_hotkey_resume(struct acpi_device *device);
+static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id pcc_device_ids[] = {
{ "MAT0012", 0},
@@ -184,6 +185,7 @@ static const struct acpi_device_id pcc_device_ids[] = {
{ "MAT0019", 0},
{ "", 0},
};
+MODULE_DEVICE_TABLE(acpi, pcc_device_ids);
static struct acpi_driver acpi_pcc_driver = {
.name = ACPI_PCC_DRIVER_NAME,
@@ -193,6 +195,7 @@ static struct acpi_driver acpi_pcc_driver = {
.add = acpi_pcc_hotkey_add,
.remove = acpi_pcc_hotkey_remove,
.resume = acpi_pcc_hotkey_resume,
+ .notify = acpi_pcc_hotkey_notify,
},
};
@@ -270,7 +273,7 @@ static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc, u32 *sinf)
union acpi_object *hkey = NULL;
int i;
- status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SINF, 0,
+ status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SINF, NULL,
&buffer);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
@@ -366,7 +369,7 @@ static ssize_t show_numbatt(struct device *dev, struct device_attribute *attr,
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
return -EIO;
- return sprintf(buf, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]);
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]);
}
static ssize_t show_lcdtype(struct device *dev, struct device_attribute *attr,
@@ -378,7 +381,7 @@ static ssize_t show_lcdtype(struct device *dev, struct device_attribute *attr,
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
return -EIO;
- return sprintf(buf, "%u\n", pcc->sinf[SINF_LCD_TYPE]);
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_LCD_TYPE]);
}
static ssize_t show_mute(struct device *dev, struct device_attribute *attr,
@@ -390,7 +393,7 @@ static ssize_t show_mute(struct device *dev, struct device_attribute *attr,
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
return -EIO;
- return sprintf(buf, "%u\n", pcc->sinf[SINF_MUTE]);
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_MUTE]);
}
static ssize_t show_sticky(struct device *dev, struct device_attribute *attr,
@@ -402,7 +405,7 @@ static ssize_t show_sticky(struct device *dev, struct device_attribute *attr,
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
return -EIO;
- return sprintf(buf, "%u\n", pcc->sinf[SINF_STICKY_KEY]);
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_STICKY_KEY]);
}
static ssize_t set_sticky(struct device *dev, struct device_attribute *attr,
@@ -526,9 +529,9 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
return;
}
-static void acpi_pcc_hotkey_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event)
{
- struct pcc_acpi *pcc = (struct pcc_acpi *) data;
+ struct pcc_acpi *pcc = acpi_driver_data(device);
switch (event) {
case HKEY_NOTIFY:
@@ -598,7 +601,6 @@ static int acpi_pcc_hotkey_resume(struct acpi_device *device)
static int acpi_pcc_hotkey_add(struct acpi_device *device)
{
- acpi_status status;
struct pcc_acpi *pcc;
int num_sifr, result;
@@ -639,22 +641,11 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
goto out_sinf;
}
- /* initialize hotkey input device */
- status = acpi_install_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
- acpi_pcc_hotkey_notify, pcc);
-
- if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error installing notify handler\n"));
- result = -ENODEV;
- goto out_input;
- }
-
/* initialize backlight */
pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
&pcc_backlight_ops);
if (IS_ERR(pcc->backlight))
- goto out_notify;
+ goto out_input;
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
@@ -679,9 +670,6 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
out_backlight:
backlight_device_unregister(pcc->backlight);
-out_notify:
- acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
- acpi_pcc_hotkey_notify);
out_input:
input_unregister_device(pcc->input_dev);
/* no need to input_free_device() since core input API refcount and
@@ -722,9 +710,6 @@ static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type)
backlight_device_unregister(pcc->backlight);
- acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
- acpi_pcc_hotkey_notify);
-
input_unregister_device(pcc->input_dev);
/* no need to input_free_device() since core input API refcount and
* free()s the device */
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index bc8996c849a..d3c92d777bd 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -2,7 +2,7 @@
* ACPI Sony Notebook Control Driver (SNC and SPIC)
*
* Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net>
- * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
+ * Copyright (C) 2007-2009 Mattia Dongili <malattia@linux.it>
*
* Parts of this driver inspired from asus_acpi.c and ibm_acpi.c
* which are copyrighted by their respective authors.
@@ -46,7 +46,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/backlight.h>
#include <linux/platform_device.h>
@@ -64,6 +63,7 @@
#include <asm/uaccess.h>
#include <linux/sonypi.h>
#include <linux/sony-laptop.h>
+#include <linux/rfkill.h>
#ifdef CONFIG_SONYPI_COMPAT
#include <linux/poll.h>
#include <linux/miscdevice.h>
@@ -123,6 +123,18 @@ MODULE_PARM_DESC(minor,
"default is -1 (automatic)");
#endif
+enum sony_nc_rfkill {
+ SONY_WIFI,
+ SONY_BLUETOOTH,
+ SONY_WWAN,
+ SONY_WIMAX,
+ SONY_RFKILL_MAX,
+};
+
+static struct rfkill *sony_rfkill_devices[SONY_RFKILL_MAX];
+static int sony_rfkill_address[SONY_RFKILL_MAX] = {0x300, 0x500, 0x700, 0x900};
+static void sony_nc_rfkill_update(void);
+
/*********** Input Devices ***********/
#define SONY_LAPTOP_BUF_SIZE 128
@@ -134,6 +146,7 @@ struct sony_laptop_input_s {
spinlock_t fifo_lock;
struct workqueue_struct *wq;
};
+
static struct sony_laptop_input_s sony_laptop_input = {
.users = ATOMIC_INIT(0),
};
@@ -211,6 +224,14 @@ static int sony_laptop_input_index[] = {
48, /* 61 SONYPI_EVENT_WIRELESS_OFF */
49, /* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */
50, /* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+ 51, /* 64 SONYPI_EVENT_CD_EJECT_PRESSED */
+ 52, /* 65 SONYPI_EVENT_MODEKEY_PRESSED */
+ 53, /* 66 SONYPI_EVENT_PKEY_P4 */
+ 54, /* 67 SONYPI_EVENT_PKEY_P5 */
+ 55, /* 68 SONYPI_EVENT_SETTINGKEY_PRESSED */
+ 56, /* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */
+ 57, /* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */
+ -1, /* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */
};
static int sony_laptop_input_keycode_map[] = {
@@ -264,7 +285,14 @@ static int sony_laptop_input_keycode_map[] = {
KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */
KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */
KEY_ZOOMIN, /* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */
- KEY_ZOOMOUT /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+ KEY_ZOOMOUT, /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+ KEY_EJECTCD, /* 51 SONYPI_EVENT_CD_EJECT_PRESSED */
+ KEY_F13, /* 52 SONYPI_EVENT_MODEKEY_PRESSED */
+ KEY_PROG4, /* 53 SONYPI_EVENT_PKEY_P4 */
+ KEY_F14, /* 54 SONYPI_EVENT_PKEY_P5 */
+ KEY_F15, /* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */
+ KEY_VOLUMEUP, /* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */
+ KEY_VOLUMEDOWN, /* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */
};
/* release buttons after a short delay if pressed */
@@ -369,7 +397,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device)
sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop");
if (!sony_laptop_input.wq) {
printk(KERN_ERR DRV_PFX
- "Unabe to create workqueue.\n");
+ "Unable to create workqueue.\n");
error = -ENXIO;
goto err_free_kfifo;
}
@@ -689,6 +717,31 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
return -1;
}
+static int sony_find_snc_handle(int handle)
+{
+ int i;
+ int result;
+
+ for (i = 0x20; i < 0x30; i++) {
+ acpi_callsetfunc(sony_nc_acpi_handle, "SN00", i, &result);
+ if (result == handle)
+ return i-0x20;
+ }
+
+ return -1;
+}
+
+static int sony_call_snc_handle(int handle, int argument, int *result)
+{
+ int offset = sony_find_snc_handle(handle);
+
+ if (offset < 0)
+ return -1;
+
+ return acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument,
+ result);
+}
+
/*
* sony_nc_values input/output validate functions
*/
@@ -809,126 +862,113 @@ struct sony_nc_event {
u8 event;
};
-static struct sony_nc_event *sony_nc_events;
-
-/* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence
- * for Fn keys
- */
-static int sony_nc_C_enable(const struct dmi_system_id *id)
-{
- int result = 0;
-
- printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident);
-
- sony_nc_events = id->driver_data;
-
- if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) {
- printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some "
- "functionalities may be missing\n");
- return 1;
- }
- return 0;
-}
-
-static struct sony_nc_event sony_C_events[] = {
+static struct sony_nc_event sony_100_events[] = {
+ { 0x90, SONYPI_EVENT_PKEY_P1 },
+ { 0x10, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x91, SONYPI_EVENT_PKEY_P2 },
+ { 0x11, SONYPI_EVENT_ANYBUTTON_RELEASED },
{ 0x81, SONYPI_EVENT_FNKEY_F1 },
{ 0x01, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x82, SONYPI_EVENT_FNKEY_F2 },
+ { 0x02, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x83, SONYPI_EVENT_FNKEY_F3 },
+ { 0x03, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x84, SONYPI_EVENT_FNKEY_F4 },
+ { 0x04, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x85, SONYPI_EVENT_FNKEY_F5 },
{ 0x05, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x86, SONYPI_EVENT_FNKEY_F6 },
{ 0x06, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x87, SONYPI_EVENT_FNKEY_F7 },
{ 0x07, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x89, SONYPI_EVENT_FNKEY_F9 },
+ { 0x09, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x8A, SONYPI_EVENT_FNKEY_F10 },
{ 0x0A, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x8C, SONYPI_EVENT_FNKEY_F12 },
{ 0x0C, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED },
+ { 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED },
{ 0, 0 },
};
-/* SNC-only model map */
-static const struct dmi_system_id sony_nc_ids[] = {
- {
- .ident = "Sony Vaio FE Series",
- .callback = sony_nc_C_enable,
- .driver_data = sony_C_events,
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"),
- },
- },
- {
- .ident = "Sony Vaio FZ Series",
- .callback = sony_nc_C_enable,
- .driver_data = sony_C_events,
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"),
- },
- },
- {
- .ident = "Sony Vaio C Series",
- .callback = sony_nc_C_enable,
- .driver_data = sony_C_events,
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"),
- },
- },
- {
- .ident = "Sony Vaio N Series",
- .callback = sony_nc_C_enable,
- .driver_data = sony_C_events,
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-N"),
- },
- },
- { }
+static struct sony_nc_event sony_127_events[] = {
+ { 0x81, SONYPI_EVENT_MODEKEY_PRESSED },
+ { 0x01, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x82, SONYPI_EVENT_PKEY_P1 },
+ { 0x02, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x83, SONYPI_EVENT_PKEY_P2 },
+ { 0x03, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x84, SONYPI_EVENT_PKEY_P3 },
+ { 0x04, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x85, SONYPI_EVENT_PKEY_P4 },
+ { 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x86, SONYPI_EVENT_PKEY_P5 },
+ { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED },
+ { 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0, 0 },
};
/*
* ACPI callbacks
*/
-static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
+static void sony_nc_notify(struct acpi_device *device, u32 event)
{
- struct sony_nc_event *evmap;
u32 ev = event;
- int result;
- if (ev == 0x92) {
- /* read the key pressed from EC.GECR
- * A call to SN07 with 0x0202 will do it as well respecting
- * the current protocol on different OSes
- *
- * Note: the path for GECR may be
- * \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends)
- * \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR)
- *
- * TODO: we may want to do the same for the older GHKE -need
- * dmi list- so this snippet may become one more callback.
- */
- if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0)
- dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev);
- else
- ev = result & 0xFF;
- }
+ if (ev >= 0x90) {
+ /* New-style event */
+ int result;
+ int key_handle = 0;
+ ev -= 0x90;
+
+ if (sony_find_snc_handle(0x100) == ev)
+ key_handle = 0x100;
+ if (sony_find_snc_handle(0x127) == ev)
+ key_handle = 0x127;
+
+ if (key_handle) {
+ struct sony_nc_event *key_event;
+
+ if (sony_call_snc_handle(key_handle, 0x200, &result)) {
+ dprintk("sony_nc_notify, unable to decode"
+ " event 0x%.2x 0x%.2x\n", key_handle,
+ ev);
+ /* restore the original event */
+ ev = event;
+ } else {
+ ev = result & 0xFF;
+
+ if (key_handle == 0x100)
+ key_event = sony_100_events;
+ else
+ key_event = sony_127_events;
+
+ for (; key_event->data; key_event++) {
+ if (key_event->data == ev) {
+ ev = key_event->event;
+ break;
+ }
+ }
- if (sony_nc_events)
- for (evmap = sony_nc_events; evmap->event; evmap++) {
- if (evmap->data == ev) {
- ev = evmap->event;
- break;
+ if (!key_event->data)
+ printk(KERN_INFO DRV_PFX
+ "Unknown event: 0x%x 0x%x\n",
+ key_handle,
+ ev);
+ else
+ sony_laptop_report_input_event(ev);
}
+ } else if (sony_find_snc_handle(0x124) == ev) {
+ sony_nc_rfkill_update();
+ return;
}
+ } else
+ sony_laptop_report_input_event(ev);
- dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);
- sony_laptop_report_input_event(ev);
+ dprintk("sony_nc_notify, event: 0x%.2x\n", ev);
acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev);
}
@@ -953,9 +993,25 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
/*
* ACPI device
*/
+static int sony_nc_function_setup(struct acpi_device *device)
+{
+ int result;
+
+ /* Enable all events */
+ acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0xffff, &result);
+
+ /* Setup hotkeys */
+ sony_call_snc_handle(0x0100, 0, &result);
+ sony_call_snc_handle(0x0101, 0, &result);
+ sony_call_snc_handle(0x0102, 0x100, &result);
+
+ return 0;
+}
+
static int sony_nc_resume(struct acpi_device *device)
{
struct sony_nc_value *item;
+ acpi_handle handle;
for (item = sony_nc_values; item->name; item++) {
int ret;
@@ -970,13 +1026,188 @@ static int sony_nc_resume(struct acpi_device *device)
}
}
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
+ &handle))) {
+ if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
+ dprintk("ECON Method failed\n");
+ }
+
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
+ &handle))) {
+ dprintk("Doing SNC setup\n");
+ sony_nc_function_setup(device);
+ }
+
/* set the last requested brightness level */
if (sony_backlight_device &&
!sony_backlight_update_status(sony_backlight_device))
printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
- /* re-initialize models with specific requirements */
- dmi_check_system(sony_nc_ids);
+ return 0;
+}
+
+static void sony_nc_rfkill_cleanup(void)
+{
+ int i;
+
+ for (i = 0; i < SONY_RFKILL_MAX; i++) {
+ if (sony_rfkill_devices[i])
+ rfkill_unregister(sony_rfkill_devices[i]);
+ }
+}
+
+static int sony_nc_rfkill_get(void *data, enum rfkill_state *state)
+{
+ int result;
+ int argument = sony_rfkill_address[(long) data];
+
+ sony_call_snc_handle(0x124, 0x200, &result);
+ if (result & 0x1) {
+ sony_call_snc_handle(0x124, argument, &result);
+ if (result & 0xf)
+ *state = RFKILL_STATE_UNBLOCKED;
+ else
+ *state = RFKILL_STATE_SOFT_BLOCKED;
+ } else {
+ *state = RFKILL_STATE_HARD_BLOCKED;
+ }
+
+ return 0;
+}
+
+static int sony_nc_rfkill_set(void *data, enum rfkill_state state)
+{
+ int result;
+ int argument = sony_rfkill_address[(long) data] + 0x100;
+
+ if (state == RFKILL_STATE_UNBLOCKED)
+ argument |= 0xff0000;
+
+ return sony_call_snc_handle(0x124, argument, &result);
+}
+
+static int sony_nc_setup_wifi_rfkill(struct acpi_device *device)
+{
+ int err = 0;
+ struct rfkill *sony_wifi_rfkill;
+
+ sony_wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN);
+ if (!sony_wifi_rfkill)
+ return -1;
+ sony_wifi_rfkill->name = "sony-wifi";
+ sony_wifi_rfkill->toggle_radio = sony_nc_rfkill_set;
+ sony_wifi_rfkill->get_state = sony_nc_rfkill_get;
+ sony_wifi_rfkill->user_claim_unsupported = 1;
+ sony_wifi_rfkill->data = (void *)SONY_WIFI;
+ err = rfkill_register(sony_wifi_rfkill);
+ if (err)
+ rfkill_free(sony_wifi_rfkill);
+ else
+ sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill;
+ return err;
+}
+
+static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device)
+{
+ int err = 0;
+ struct rfkill *sony_bluetooth_rfkill;
+
+ sony_bluetooth_rfkill = rfkill_allocate(&device->dev,
+ RFKILL_TYPE_BLUETOOTH);
+ if (!sony_bluetooth_rfkill)
+ return -1;
+ sony_bluetooth_rfkill->name = "sony-bluetooth";
+ sony_bluetooth_rfkill->toggle_radio = sony_nc_rfkill_set;
+ sony_bluetooth_rfkill->get_state = sony_nc_rfkill_get;
+ sony_bluetooth_rfkill->user_claim_unsupported = 1;
+ sony_bluetooth_rfkill->data = (void *)SONY_BLUETOOTH;
+ err = rfkill_register(sony_bluetooth_rfkill);
+ if (err)
+ rfkill_free(sony_bluetooth_rfkill);
+ else
+ sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill;
+ return err;
+}
+
+static int sony_nc_setup_wwan_rfkill(struct acpi_device *device)
+{
+ int err = 0;
+ struct rfkill *sony_wwan_rfkill;
+
+ sony_wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN);
+ if (!sony_wwan_rfkill)
+ return -1;
+ sony_wwan_rfkill->name = "sony-wwan";
+ sony_wwan_rfkill->toggle_radio = sony_nc_rfkill_set;
+ sony_wwan_rfkill->get_state = sony_nc_rfkill_get;
+ sony_wwan_rfkill->user_claim_unsupported = 1;
+ sony_wwan_rfkill->data = (void *)SONY_WWAN;
+ err = rfkill_register(sony_wwan_rfkill);
+ if (err)
+ rfkill_free(sony_wwan_rfkill);
+ else
+ sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill;
+ return err;
+}
+
+static int sony_nc_setup_wimax_rfkill(struct acpi_device *device)
+{
+ int err = 0;
+ struct rfkill *sony_wimax_rfkill;
+
+ sony_wimax_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WIMAX);
+ if (!sony_wimax_rfkill)
+ return -1;
+ sony_wimax_rfkill->name = "sony-wimax";
+ sony_wimax_rfkill->toggle_radio = sony_nc_rfkill_set;
+ sony_wimax_rfkill->get_state = sony_nc_rfkill_get;
+ sony_wimax_rfkill->user_claim_unsupported = 1;
+ sony_wimax_rfkill->data = (void *)SONY_WIMAX;
+ err = rfkill_register(sony_wimax_rfkill);
+ if (err)
+ rfkill_free(sony_wimax_rfkill);
+ else
+ sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill;
+ return err;
+}
+
+static void sony_nc_rfkill_update()
+{
+ int i;
+ enum rfkill_state state;
+
+ for (i = 0; i < SONY_RFKILL_MAX; i++) {
+ if (sony_rfkill_devices[i]) {
+ sony_rfkill_devices[i]->
+ get_state(sony_rfkill_devices[i]->data,
+ &state);
+ rfkill_force_state(sony_rfkill_devices[i], state);
+ }
+ }
+}
+
+static int sony_nc_rfkill_setup(struct acpi_device *device)
+{
+ int result, ret;
+
+ if (sony_find_snc_handle(0x124) == -1)
+ return -1;
+
+ ret = sony_call_snc_handle(0x124, 0xb00, &result);
+ if (ret) {
+ printk(KERN_INFO DRV_PFX
+ "Unable to enumerate rfkill devices: %x\n", ret);
+ return ret;
+ }
+
+ if (result & 0x1)
+ sony_nc_setup_wifi_rfkill(device);
+ if (result & 0x2)
+ sony_nc_setup_bluetooth_rfkill(device);
+ if (result & 0x1c)
+ sony_nc_setup_wwan_rfkill(device);
+ if (result & 0x20)
+ sony_nc_setup_wimax_rfkill(device);
return 0;
}
@@ -1024,23 +1255,27 @@ static int sony_nc_add(struct acpi_device *device)
dprintk("_INI Method failed\n");
}
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
+ &handle))) {
+ if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
+ dprintk("ECON Method failed\n");
+ }
+
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
+ &handle))) {
+ dprintk("Doing SNC setup\n");
+ sony_nc_function_setup(device);
+ sony_nc_rfkill_setup(device);
+ }
+
/* setup input devices and helper fifo */
result = sony_laptop_setup_input(device);
if (result) {
printk(KERN_ERR DRV_PFX
- "Unabe to create input devices.\n");
+ "Unable to create input devices.\n");
goto outwalk;
}
- status = acpi_install_notify_handler(sony_nc_acpi_handle,
- ACPI_DEVICE_NOTIFY,
- sony_acpi_notify, NULL);
- if (ACPI_FAILURE(status)) {
- printk(KERN_WARNING DRV_PFX "unable to install notify handler (%u)\n", status);
- result = -ENODEV;
- goto outinput;
- }
-
if (acpi_video_backlight_support()) {
printk(KERN_INFO DRV_PFX "brightness ignored, must be "
"controlled by ACPI video driver\n");
@@ -1063,9 +1298,6 @@ static int sony_nc_add(struct acpi_device *device)
}
- /* initialize models with specific requirements */
- dmi_check_system(sony_nc_ids);
-
result = sony_pf_add();
if (result)
goto outbacklight;
@@ -1121,22 +1353,15 @@ static int sony_nc_add(struct acpi_device *device)
if (sony_backlight_device)
backlight_device_unregister(sony_backlight_device);
- status = acpi_remove_notify_handler(sony_nc_acpi_handle,
- ACPI_DEVICE_NOTIFY,
- sony_acpi_notify);
- if (ACPI_FAILURE(status))
- printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n");
-
- outinput:
sony_laptop_remove_input();
outwalk:
+ sony_nc_rfkill_cleanup();
return result;
}
static int sony_nc_remove(struct acpi_device *device, int type)
{
- acpi_status status;
struct sony_nc_value *item;
if (sony_backlight_device)
@@ -1144,18 +1369,13 @@ static int sony_nc_remove(struct acpi_device *device, int type)
sony_nc_acpi_device = NULL;
- status = acpi_remove_notify_handler(sony_nc_acpi_handle,
- ACPI_DEVICE_NOTIFY,
- sony_acpi_notify);
- if (ACPI_FAILURE(status))
- printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n");
-
for (item = sony_nc_values; item->name; ++item) {
device_remove_file(&sony_pf_device->dev, &item->devattr);
}
sony_pf_remove();
sony_laptop_remove_input();
+ sony_nc_rfkill_cleanup();
dprintk(SONY_NC_DRIVER_NAME " removed.\n");
return 0;
@@ -1182,6 +1402,7 @@ static struct acpi_driver sony_nc_driver = {
.add = sony_nc_add,
.remove = sony_nc_remove,
.resume = sony_nc_resume,
+ .notify = sony_nc_notify,
},
};
@@ -1195,7 +1416,6 @@ static struct acpi_driver sony_nc_driver = {
#define SONYPI_TYPE1_OFFSET 0x04
#define SONYPI_TYPE2_OFFSET 0x12
#define SONYPI_TYPE3_OFFSET 0x12
-#define SONYPI_TYPE4_OFFSET 0x12
struct sony_pic_ioport {
struct acpi_resource_io io1;
@@ -1328,6 +1548,7 @@ static struct sonypi_event sonypi_pkeyev[] = {
{ 0x01, SONYPI_EVENT_PKEY_P1 },
{ 0x02, SONYPI_EVENT_PKEY_P2 },
{ 0x04, SONYPI_EVENT_PKEY_P3 },
+ { 0x20, SONYPI_EVENT_PKEY_P1 },
{ 0, 0 }
};
@@ -1371,6 +1592,7 @@ static struct sonypi_event sonypi_zoomev[] = {
{ 0x39, SONYPI_EVENT_ZOOM_PRESSED },
{ 0x10, SONYPI_EVENT_ZOOM_IN_PRESSED },
{ 0x20, SONYPI_EVENT_ZOOM_OUT_PRESSED },
+ { 0x04, SONYPI_EVENT_ZOOM_PRESSED },
{ 0, 0 }
};
@@ -1401,6 +1623,19 @@ static struct sonypi_event sonypi_batteryev[] = {
{ 0, 0 }
};
+/* The set of possible volume events */
+static struct sonypi_event sonypi_volumeev[] = {
+ { 0x01, SONYPI_EVENT_VOLUME_INC_PRESSED },
+ { 0x02, SONYPI_EVENT_VOLUME_DEC_PRESSED },
+ { 0, 0 }
+};
+
+/* The set of possible brightness events */
+static struct sonypi_event sonypi_brightnessev[] = {
+ { 0x80, SONYPI_EVENT_BRIGHTNESS_PRESSED },
+ { 0, 0 }
+};
+
static struct sonypi_eventtypes type1_events[] = {
{ 0, 0xffffffff, sonypi_releaseev },
{ 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
@@ -1438,17 +1673,11 @@ static struct sonypi_eventtypes type3_events[] = {
{ 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
{ 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
{ 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
- { 0 },
-};
-static struct sonypi_eventtypes type4_events[] = {
- { 0, 0xffffffff, sonypi_releaseev },
- { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
- { 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
- { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
- { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
{ 0x05, SONYPI_PKEY_MASK, sonypi_pkeyev },
{ 0x05, SONYPI_ZOOM_MASK, sonypi_zoomev },
{ 0x05, SONYPI_CAPTURE_MASK, sonypi_captureev },
+ { 0x05, SONYPI_PKEY_MASK, sonypi_volumeev },
+ { 0x05, SONYPI_PKEY_MASK, sonypi_brightnessev },
{ 0 },
};
@@ -1511,11 +1740,11 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v)
/*
* minidrivers for SPIC models
*/
-static int type4_handle_irq(const u8 data_mask, const u8 ev)
+static int type3_handle_irq(const u8 data_mask, const u8 ev)
{
/*
* 0x31 could mean we have to take some extra action and wait for
- * the next irq for some Type4 models, it will generate a new
+ * the next irq for some Type3 models, it will generate a new
* irq and we can read new data from the device:
* - 0x5c and 0x5f requires 0xA0
* - 0x61 requires 0xB3
@@ -1545,16 +1774,10 @@ static struct device_ctrl spic_types[] = {
},
{
.model = SONYPI_DEVICE_TYPE3,
- .handle_irq = NULL,
+ .handle_irq = type3_handle_irq,
.evport_offset = SONYPI_TYPE3_OFFSET,
.event_types = type3_events,
},
- {
- .model = SONYPI_DEVICE_TYPE4,
- .handle_irq = type4_handle_irq,
- .evport_offset = SONYPI_TYPE4_OFFSET,
- .event_types = type4_events,
- },
};
static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
@@ -1578,14 +1801,21 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_ICH7_1, NULL);
if (pcidev) {
- dev->control = &spic_types[3];
+ dev->control = &spic_types[2];
goto out;
}
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_ICH8_4, NULL);
if (pcidev) {
- dev->control = &spic_types[3];
+ dev->control = &spic_types[2];
+ goto out;
+ }
+
+ pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_ICH9_1, NULL);
+ if (pcidev) {
+ dev->control = &spic_types[2];
goto out;
}
@@ -1598,8 +1828,7 @@ out:
printk(KERN_INFO DRV_PFX "detected Type%d model\n",
dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 :
- dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 :
- dev->control->model == SONYPI_DEVICE_TYPE3 ? 3 : 4);
+ dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
}
/* camera tests and poweron/poweroff */
@@ -1754,17 +1983,14 @@ int sony_pic_camera_command(int command, u8 value)
EXPORT_SYMBOL(sony_pic_camera_command);
/* gprs/edge modem (SZ460N and SZ210P), thanks to Joshua Wise */
-static void sony_pic_set_wwanpower(u8 state)
+static void __sony_pic_set_wwanpower(u8 state)
{
state = !!state;
- mutex_lock(&spic_dev.lock);
- if (spic_dev.wwan_power == state) {
- mutex_unlock(&spic_dev.lock);
+ if (spic_dev.wwan_power == state)
return;
- }
sony_pic_call2(0xB0, state);
+ sony_pic_call1(0x82);
spic_dev.wwan_power = state;
- mutex_unlock(&spic_dev.lock);
}
static ssize_t sony_pic_wwanpower_store(struct device *dev,
@@ -1776,7 +2002,9 @@ static ssize_t sony_pic_wwanpower_store(struct device *dev,
return -EINVAL;
value = simple_strtoul(buffer, NULL, 10);
- sony_pic_set_wwanpower(value);
+ mutex_lock(&spic_dev.lock);
+ __sony_pic_set_wwanpower(value);
+ mutex_unlock(&spic_dev.lock);
return count;
}
@@ -1929,10 +2157,15 @@ static int sonypi_misc_release(struct inode *inode, struct file *file)
static int sonypi_misc_open(struct inode *inode, struct file *file)
{
/* Flush input queue on first open */
- lock_kernel();
+ unsigned long flags;
+
+ spin_lock_irqsave(sonypi_compat.fifo->lock, flags);
+
if (atomic_inc_return(&sonypi_compat.open_count) == 1)
- kfifo_reset(sonypi_compat.fifo);
- unlock_kernel();
+ __kfifo_reset(sonypi_compat.fifo);
+
+ spin_unlock_irqrestore(sonypi_compat.fifo->lock, flags);
+
return 0;
}
@@ -1985,8 +2218,8 @@ static int ec_read16(u8 addr, u16 *value)
return 0;
}
-static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
- unsigned int cmd, unsigned long arg)
+static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd,
+ unsigned long arg)
{
int ret = 0;
void __user *argp = (void __user *)arg;
@@ -2120,7 +2353,7 @@ static const struct file_operations sonypi_misc_fops = {
.open = sonypi_misc_open,
.release = sonypi_misc_release,
.fasync = sonypi_misc_fasync,
- .ioctl = sonypi_misc_ioctl,
+ .unlocked_ioctl = sonypi_misc_ioctl,
};
static struct miscdevice sonypi_misc_device = {
@@ -2561,7 +2794,7 @@ static int sony_pic_add(struct acpi_device *device)
result = sony_pic_possible_resources(device);
if (result) {
printk(KERN_ERR DRV_PFX
- "Unabe to read possible resources.\n");
+ "Unable to read possible resources.\n");
goto err_free_resources;
}
@@ -2569,7 +2802,7 @@ static int sony_pic_add(struct acpi_device *device)
result = sony_laptop_setup_input(device);
if (result) {
printk(KERN_ERR DRV_PFX
- "Unabe to create input devices.\n");
+ "Unable to create input devices.\n");
goto err_free_resources;
}
diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c
index b4a4aa9ee48..44166003d4e 100644
--- a/drivers/platform/x86/tc1100-wmi.c
+++ b/drivers/platform/x86/tc1100-wmi.c
@@ -94,9 +94,8 @@ static int get_state(u32 *out, u8 instance)
return -ENODEV;
obj = (union acpi_object *) result.pointer;
- if (obj && obj->type == ACPI_TYPE_BUFFER &&
- obj->buffer.length == sizeof(u32)) {
- tmp = *((u32 *) obj->buffer.pointer);
+ if (obj && obj->type == ACPI_TYPE_INTEGER) {
+ tmp = obj->integer.value;
} else {
tmp = 0;
}
@@ -109,7 +108,7 @@ static int get_state(u32 *out, u8 instance)
*out = (tmp == 3) ? 1 : 0;
return 0;
case TC1100_INSTANCE_JOGDIAL:
- *out = (tmp == 1) ? 1 : 0;
+ *out = (tmp == 1) ? 0 : 1;
return 0;
default:
return -ENODEV;
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 3dad27a385d..a40b075743d 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -3,7 +3,7 @@
*
*
* Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
- * Copyright (C) 2006-2008 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+ * Copyright (C) 2006-2009 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
*
* 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
@@ -22,7 +22,7 @@
*/
#define TPACPI_VERSION "0.22"
-#define TPACPI_SYSFS_VERSION 0x020200
+#define TPACPI_SYSFS_VERSION 0x020300
/*
* Changelog:
@@ -54,6 +54,7 @@
#include <linux/string.h>
#include <linux/list.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/delay.h>
@@ -172,29 +173,26 @@ enum {
TPACPI_RFK_UWB_SW_ID,
};
-/* Debugging */
+/* printk headers */
#define TPACPI_LOG TPACPI_FILE ": "
-#define TPACPI_ALERT KERN_ALERT TPACPI_LOG
-#define TPACPI_CRIT KERN_CRIT TPACPI_LOG
-#define TPACPI_ERR KERN_ERR TPACPI_LOG
-#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
-#define TPACPI_INFO KERN_INFO TPACPI_LOG
-#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG
-
+#define TPACPI_EMERG KERN_EMERG TPACPI_LOG
+#define TPACPI_ALERT KERN_ALERT TPACPI_LOG
+#define TPACPI_CRIT KERN_CRIT TPACPI_LOG
+#define TPACPI_ERR KERN_ERR TPACPI_LOG
+#define TPACPI_WARN KERN_WARNING TPACPI_LOG
+#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
+#define TPACPI_INFO KERN_INFO TPACPI_LOG
+#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG
+
+/* Debugging printk groups */
#define TPACPI_DBG_ALL 0xffff
+#define TPACPI_DBG_DISCLOSETASK 0x8000
#define TPACPI_DBG_INIT 0x0001
#define TPACPI_DBG_EXIT 0x0002
-#define dbg_printk(a_dbg_level, format, arg...) \
- do { if (dbg_level & a_dbg_level) \
- printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
- } while (0)
-#ifdef CONFIG_THINKPAD_ACPI_DEBUG
-#define vdbg_printk(a_dbg_level, format, arg...) \
- dbg_printk(a_dbg_level, format, ## arg)
-static const char *str_supported(int is_supported);
-#else
-#define vdbg_printk(a_dbg_level, format, arg...)
-#endif
+#define TPACPI_DBG_RFKILL 0x0004
+#define TPACPI_DBG_HKEY 0x0008
+#define TPACPI_DBG_FAN 0x0010
+#define TPACPI_DBG_BRGHT 0x0020
#define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off")
#define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
@@ -277,7 +275,6 @@ static struct {
static struct {
u16 hotkey_mask_ff:1;
- u16 bright_cmos_ec_unsync:1;
} tp_warned;
struct thinkpad_id_data {
@@ -326,6 +323,39 @@ static int tpacpi_uwb_emulstate;
#endif
+/*************************************************************************
+ * Debugging helpers
+ */
+
+#define dbg_printk(a_dbg_level, format, arg...) \
+ do { if (dbg_level & (a_dbg_level)) \
+ printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
+ } while (0)
+
+#ifdef CONFIG_THINKPAD_ACPI_DEBUG
+#define vdbg_printk dbg_printk
+static const char *str_supported(int is_supported);
+#else
+#define vdbg_printk(a_dbg_level, format, arg...) \
+ do { } while (0)
+#endif
+
+static void tpacpi_log_usertask(const char * const what)
+{
+ printk(TPACPI_DEBUG "%s: access by process with PID %d\n",
+ what, task_tgid_vnr(current));
+}
+
+#define tpacpi_disclose_usertask(what, format, arg...) \
+ do { \
+ if (unlikely( \
+ (dbg_level & TPACPI_DBG_DISCLOSETASK) && \
+ (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \
+ printk(TPACPI_DEBUG "%s: PID %d: " format, \
+ what, task_tgid_vnr(current), ## arg); \
+ } \
+ } while (0)
+
/****************************************************************************
****************************************************************************
*
@@ -989,10 +1019,13 @@ static int __init tpacpi_new_rfkill(const unsigned int id,
/* try to set the initial state as the default for the rfkill
* type, since we ask the firmware to preserve it across S5 in
* NVRAM */
- rfkill_set_default(rfktype,
+ if (rfkill_set_default(rfktype,
(initial_state == RFKILL_STATE_UNBLOCKED) ?
RFKILL_STATE_UNBLOCKED :
- RFKILL_STATE_SOFT_BLOCKED);
+ RFKILL_STATE_SOFT_BLOCKED) == -EPERM)
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "Default state for %s cannot be changed\n",
+ name);
}
*rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype);
@@ -1020,6 +1053,21 @@ static int __init tpacpi_new_rfkill(const unsigned int id,
return 0;
}
+static void printk_deprecated_attribute(const char * const what,
+ const char * const details)
+{
+ tpacpi_log_usertask("deprecated sysfs attribute");
+ printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and "
+ "will be removed. %s\n",
+ what, details);
+}
+
+static void printk_deprecated_rfkill_attribute(const char * const what)
+{
+ printk_deprecated_attribute(what,
+ "Please switch to generic rfkill before year 2010");
+}
+
/*************************************************************************
* thinkpad-acpi driver attributes
*/
@@ -1382,7 +1430,6 @@ static enum { /* Reasons for waking up */
static int hotkey_autosleep_ack;
-static int hotkey_orig_status;
static u32 hotkey_orig_mask;
static u32 hotkey_all_mask;
static u32 hotkey_reserved_mask;
@@ -1529,9 +1576,9 @@ static int hotkey_status_get(int *status)
return 0;
}
-static int hotkey_status_set(int status)
+static int hotkey_status_set(bool enable)
{
- if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
+ if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", enable ? 1 : 0))
return -EIO;
return 0;
@@ -1847,6 +1894,9 @@ static ssize_t hotkey_enable_show(struct device *dev,
{
int res, status;
+ printk_deprecated_attribute("hotkey_enable",
+ "Hotkey reporting is always enabled");
+
res = hotkey_status_get(&status);
if (res)
return res;
@@ -1859,14 +1909,17 @@ static ssize_t hotkey_enable_store(struct device *dev,
const char *buf, size_t count)
{
unsigned long t;
- int res;
+
+ printk_deprecated_attribute("hotkey_enable",
+ "Hotkeys can be disabled through hotkey_mask");
if (parse_strtoul(buf, 1, &t))
return -EINVAL;
- res = hotkey_status_set(t);
+ if (t == 0)
+ return -EPERM;
- return (res) ? res : count;
+ return count;
}
static struct device_attribute dev_attr_hotkey_enable =
@@ -1910,6 +1963,8 @@ static ssize_t hotkey_mask_store(struct device *dev,
mutex_unlock(&hotkey_mutex);
+ tpacpi_disclose_usertask("hotkey_mask", "set to 0x%08lx\n", t);
+
return (res) ? res : count;
}
@@ -1922,7 +1977,7 @@ static ssize_t hotkey_bios_enabled_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status);
+ return sprintf(buf, "0\n");
}
static struct device_attribute dev_attr_hotkey_bios_enabled =
@@ -1996,6 +2051,8 @@ static ssize_t hotkey_source_mask_store(struct device *dev,
mutex_unlock(&hotkey_mutex);
+ tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);
+
return count;
}
@@ -2028,6 +2085,8 @@ static ssize_t hotkey_poll_freq_store(struct device *dev,
hotkey_poll_setup(1);
mutex_unlock(&hotkey_mutex);
+ tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t);
+
return count;
}
@@ -2197,11 +2256,11 @@ static void hotkey_exit(void)
kfree(hotkey_keycode_map);
if (tp_features.hotkey) {
- dbg_printk(TPACPI_DBG_EXIT,
+ dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,
"restoring original hot key mask\n");
/* no short-circuit boolean operator below! */
if ((hotkey_mask_set(hotkey_orig_mask) |
- hotkey_status_set(hotkey_orig_status)) != 0)
+ hotkey_status_set(false)) != 0)
printk(TPACPI_ERR
"failed to restore hot key mask "
"to BIOS defaults\n");
@@ -2327,7 +2386,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
int status;
int hkeyv;
- vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "initializing hotkey subdriver\n");
BUG_ON(!tpacpi_inputdev);
BUG_ON(tpacpi_inputdev->open != NULL ||
@@ -2344,7 +2404,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
/* hotkey not supported on 570 */
tp_features.hotkey = hkey_handle != NULL;
- vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "hotkeys are %s\n",
str_supported(tp_features.hotkey));
if (!tp_features.hotkey)
@@ -2376,10 +2437,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
* T4x, X31, and later
*/
tp_features.hotkey_mask = 1;
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "firmware HKEY interface version: 0x%x\n",
+ hkeyv);
}
}
- vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "hotkey masks are %s\n",
str_supported(tp_features.hotkey_mask));
if (tp_features.hotkey_mask) {
@@ -2396,10 +2461,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
/* hotkey_source_mask *must* be zero for
* the first hotkey_mask_get */
- res = hotkey_status_get(&hotkey_orig_status);
- if (res)
- goto err_exit;
-
if (tp_features.hotkey_mask) {
res = hotkey_mask_get();
if (res)
@@ -2422,7 +2483,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK;
}
- vdbg_printk(TPACPI_DBG_INIT,
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"hotkey source mask 0x%08x, polling freq %d\n",
hotkey_source_mask, hotkey_poll_freq);
#endif
@@ -2476,12 +2537,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
}
if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"using Lenovo default hot key map\n");
memcpy(hotkey_keycode_map, &lenovo_keycode_map,
TPACPI_HOTKEY_MAP_SIZE);
} else {
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"using IBM default hot key map\n");
memcpy(hotkey_keycode_map, &ibm_keycode_map,
TPACPI_HOTKEY_MAP_SIZE);
@@ -2538,8 +2599,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
| (1 << TP_ACPI_HOTKEYSCAN_FNEND);
}
- dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n");
- res = hotkey_status_set(1);
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "enabling firmware HKEY event interface...\n");
+ res = hotkey_status_set(true);
if (res) {
hotkey_exit();
return res;
@@ -2552,8 +2614,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
return res;
}
- dbg_printk(TPACPI_DBG_INIT,
- "legacy hot key reporting over procfs %s\n",
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "legacy ibm/hotkey event reporting over procfs %s\n",
(hotkey_report_mode < 2) ?
"enabled" : "disabled");
@@ -2884,9 +2946,17 @@ static int hotkey_read(char *p)
return len;
}
+static void hotkey_enabledisable_warn(void)
+{
+ tpacpi_log_usertask("procfs hotkey enable/disable");
+ WARN(1, TPACPI_WARN
+ "hotkey enable/disable functionality has been "
+ "removed from the driver. Hotkeys are always enabled.\n");
+}
+
static int hotkey_write(char *buf)
{
- int res, status;
+ int res;
u32 mask;
char *cmd;
@@ -2896,17 +2966,16 @@ static int hotkey_write(char *buf)
if (mutex_lock_killable(&hotkey_mutex))
return -ERESTARTSYS;
- status = -1;
mask = hotkey_mask;
res = 0;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) {
- status = 1;
+ hotkey_enabledisable_warn();
} else if (strlencmp(cmd, "disable") == 0) {
- status = 0;
+ hotkey_enabledisable_warn();
+ res = -EPERM;
} else if (strlencmp(cmd, "reset") == 0) {
- status = hotkey_orig_status;
mask = hotkey_orig_mask;
} else if (sscanf(cmd, "0x%x", &mask) == 1) {
/* mask set */
@@ -2917,8 +2986,10 @@ static int hotkey_write(char *buf)
goto errexit;
}
}
- if (status != -1)
- res = hotkey_status_set(status);
+
+ if (!res)
+ tpacpi_disclose_usertask("procfs hotkey",
+ "set mask to 0x%08x\n", mask);
if (!res && mask != hotkey_mask)
res = hotkey_mask_set(mask);
@@ -2971,13 +3042,17 @@ enum {
TP_ACPI_BLTH_SAVE_STATE = 0x05, /* Save state for S4/S5 */
};
+#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"
+
static struct rfkill *tpacpi_bluetooth_rfkill;
static void bluetooth_suspend(pm_message_t state)
{
/* Try to make sure radio will resume powered off */
- acpi_evalf(NULL, NULL, "\\BLTH", "vd",
- TP_ACPI_BLTH_PWR_OFF_ON_RESUME);
+ if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
+ TP_ACPI_BLTH_PWR_OFF_ON_RESUME))
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "bluetooth power down on resume request failed\n");
}
static int bluetooth_get_radiosw(void)
@@ -3015,6 +3090,10 @@ static void bluetooth_update_rfk(void)
if (status < 0)
return;
rfkill_force_state(tpacpi_bluetooth_rfkill, status);
+
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "forced rfkill state to %d\n",
+ status);
}
static int bluetooth_set_radiosw(int radio_on, int update_rfk)
@@ -3030,6 +3109,9 @@ static int bluetooth_set_radiosw(int radio_on, int update_rfk)
&& radio_on)
return -EPERM;
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "will %s bluetooth\n", radio_on ? "enable" : "disable");
+
#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
if (dbg_bluetoothemul) {
tpacpi_bluetooth_emulstate = !!radio_on;
@@ -3060,6 +3142,8 @@ static ssize_t bluetooth_enable_show(struct device *dev,
{
int status;
+ printk_deprecated_rfkill_attribute("bluetooth_enable");
+
status = bluetooth_get_radiosw();
if (status < 0)
return status;
@@ -3075,9 +3159,13 @@ static ssize_t bluetooth_enable_store(struct device *dev,
unsigned long t;
int res;
+ printk_deprecated_rfkill_attribute("bluetooth_enable");
+
if (parse_strtoul(buf, 1, &t))
return -EINVAL;
+ tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t);
+
res = bluetooth_set_radiosw(t, 1);
return (res) ? res : count;
@@ -3111,6 +3199,8 @@ static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state)
static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
{
+ dbg_printk(TPACPI_DBG_RFKILL,
+ "request to change radio state to %d\n", state);
return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
}
@@ -3121,6 +3211,9 @@ static void bluetooth_shutdown(void)
TP_ACPI_BLTH_SAVE_STATE))
printk(TPACPI_NOTICE
"failed to save bluetooth state to NVRAM\n");
+ else
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "bluestooth state saved to NVRAM\n");
}
static void bluetooth_exit(void)
@@ -3139,7 +3232,8 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
int res;
int status = 0;
- vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "initializing bluetooth subdriver\n");
TPACPI_ACPIHANDLE_INIT(hkey);
@@ -3148,7 +3242,8 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
tp_features.bluetooth = hkey_handle &&
acpi_evalf(hkey_handle, &status, "GBDC", "qd");
- vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "bluetooth is %s, status 0x%02x\n",
str_supported(tp_features.bluetooth),
status);
@@ -3163,7 +3258,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
!(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
/* no bluetooth hardware present in system */
tp_features.bluetooth = 0;
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
"bluetooth hardware not installed\n");
}
@@ -3178,7 +3273,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
&tpacpi_bluetooth_rfkill,
RFKILL_TYPE_BLUETOOTH,
- "tpacpi_bluetooth_sw",
+ TPACPI_RFK_BLUETOOTH_SW_NAME,
true,
tpacpi_bluetooth_rfk_set,
tpacpi_bluetooth_rfk_get);
@@ -3211,19 +3306,27 @@ static int bluetooth_read(char *p)
static int bluetooth_write(char *buf)
{
char *cmd;
+ int state = -1;
if (!tp_features.bluetooth)
return -ENODEV;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) {
- bluetooth_set_radiosw(1, 1);
+ state = 1;
} else if (strlencmp(cmd, "disable") == 0) {
- bluetooth_set_radiosw(0, 1);
+ state = 0;
} else
return -EINVAL;
}
+ if (state != -1) {
+ tpacpi_disclose_usertask("procfs bluetooth",
+ "attempt to %s\n",
+ state ? "enable" : "disable");
+ bluetooth_set_radiosw(state, 1);
+ }
+
return 0;
}
@@ -3248,13 +3351,17 @@ enum {
off / last state */
};
+#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
+
static struct rfkill *tpacpi_wan_rfkill;
static void wan_suspend(pm_message_t state)
{
/* Try to make sure radio will resume powered off */
- acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
- TP_ACPI_WGSV_PWR_OFF_ON_RESUME);
+ if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
+ TP_ACPI_WGSV_PWR_OFF_ON_RESUME))
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "WWAN power down on resume request failed\n");
}
static int wan_get_radiosw(void)
@@ -3292,6 +3399,10 @@ static void wan_update_rfk(void)
if (status < 0)
return;
rfkill_force_state(tpacpi_wan_rfkill, status);
+
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "forced rfkill state to %d\n",
+ status);
}
static int wan_set_radiosw(int radio_on, int update_rfk)
@@ -3307,6 +3418,9 @@ static int wan_set_radiosw(int radio_on, int update_rfk)
&& radio_on)
return -EPERM;
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "will %s WWAN\n", radio_on ? "enable" : "disable");
+
#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
if (dbg_wwanemul) {
tpacpi_wwan_emulstate = !!radio_on;
@@ -3337,6 +3451,8 @@ static ssize_t wan_enable_show(struct device *dev,
{
int status;
+ printk_deprecated_rfkill_attribute("wwan_enable");
+
status = wan_get_radiosw();
if (status < 0)
return status;
@@ -3352,9 +3468,13 @@ static ssize_t wan_enable_store(struct device *dev,
unsigned long t;
int res;
+ printk_deprecated_rfkill_attribute("wwan_enable");
+
if (parse_strtoul(buf, 1, &t))
return -EINVAL;
+ tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t);
+
res = wan_set_radiosw(t, 1);
return (res) ? res : count;
@@ -3388,6 +3508,8 @@ static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state)
static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
{
+ dbg_printk(TPACPI_DBG_RFKILL,
+ "request to change radio state to %d\n", state);
return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
}
@@ -3398,6 +3520,9 @@ static void wan_shutdown(void)
TP_ACPI_WGSV_SAVE_STATE))
printk(TPACPI_NOTICE
"failed to save WWAN state to NVRAM\n");
+ else
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "WWAN state saved to NVRAM\n");
}
static void wan_exit(void)
@@ -3416,14 +3541,16 @@ static int __init wan_init(struct ibm_init_struct *iibm)
int res;
int status = 0;
- vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "initializing wan subdriver\n");
TPACPI_ACPIHANDLE_INIT(hkey);
tp_features.wan = hkey_handle &&
acpi_evalf(hkey_handle, &status, "GWAN", "qd");
- vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "wan is %s, status 0x%02x\n",
str_supported(tp_features.wan),
status);
@@ -3438,7 +3565,7 @@ static int __init wan_init(struct ibm_init_struct *iibm)
!(status & TP_ACPI_WANCARD_HWPRESENT)) {
/* no wan hardware present in system */
tp_features.wan = 0;
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
"wan hardware not installed\n");
}
@@ -3453,7 +3580,7 @@ static int __init wan_init(struct ibm_init_struct *iibm)
res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
&tpacpi_wan_rfkill,
RFKILL_TYPE_WWAN,
- "tpacpi_wwan_sw",
+ TPACPI_RFK_WWAN_SW_NAME,
true,
tpacpi_wan_rfk_set,
tpacpi_wan_rfk_get);
@@ -3471,6 +3598,8 @@ static int wan_read(char *p)
int len = 0;
int status = wan_get_radiosw();
+ tpacpi_disclose_usertask("procfs wan", "read");
+
if (!tp_features.wan)
len += sprintf(p + len, "status:\t\tnot supported\n");
else {
@@ -3486,19 +3615,27 @@ static int wan_read(char *p)
static int wan_write(char *buf)
{
char *cmd;
+ int state = -1;
if (!tp_features.wan)
return -ENODEV;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) {
- wan_set_radiosw(1, 1);
+ state = 1;
} else if (strlencmp(cmd, "disable") == 0) {
- wan_set_radiosw(0, 1);
+ state = 0;
} else
return -EINVAL;
}
+ if (state != -1) {
+ tpacpi_disclose_usertask("procfs wan",
+ "attempt to %s\n",
+ state ? "enable" : "disable");
+ wan_set_radiosw(state, 1);
+ }
+
return 0;
}
@@ -3521,6 +3658,8 @@ enum {
TP_ACPI_UWB_RADIOSSW = 0x02, /* UWB radio enabled */
};
+#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw"
+
static struct rfkill *tpacpi_uwb_rfkill;
static int uwb_get_radiosw(void)
@@ -3558,6 +3697,10 @@ static void uwb_update_rfk(void)
if (status < 0)
return;
rfkill_force_state(tpacpi_uwb_rfkill, status);
+
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "forced rfkill state to %d\n",
+ status);
}
static int uwb_set_radiosw(int radio_on, int update_rfk)
@@ -3573,6 +3716,9 @@ static int uwb_set_radiosw(int radio_on, int update_rfk)
&& radio_on)
return -EPERM;
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "will %s UWB\n", radio_on ? "enable" : "disable");
+
#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
if (dbg_uwbemul) {
tpacpi_uwb_emulstate = !!radio_on;
@@ -3607,6 +3753,8 @@ static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state)
static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state)
{
+ dbg_printk(TPACPI_DBG_RFKILL,
+ "request to change radio state to %d\n", state);
return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
}
@@ -3621,14 +3769,16 @@ static int __init uwb_init(struct ibm_init_struct *iibm)
int res;
int status = 0;
- vdbg_printk(TPACPI_DBG_INIT, "initializing uwb subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "initializing uwb subdriver\n");
TPACPI_ACPIHANDLE_INIT(hkey);
tp_features.uwb = hkey_handle &&
acpi_evalf(hkey_handle, &status, "GUWB", "qd");
- vdbg_printk(TPACPI_DBG_INIT, "uwb is %s, status 0x%02x\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "uwb is %s, status 0x%02x\n",
str_supported(tp_features.uwb),
status);
@@ -3653,7 +3803,7 @@ static int __init uwb_init(struct ibm_init_struct *iibm)
res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
&tpacpi_uwb_rfkill,
RFKILL_TYPE_UWB,
- "tpacpi_uwb_sw",
+ TPACPI_RFK_UWB_SW_NAME,
false,
tpacpi_uwb_rfk_set,
tpacpi_uwb_rfk_get);
@@ -4602,6 +4752,16 @@ static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
"tpacpi::unknown_led",
"tpacpi::standby",
};
+#define TPACPI_SAFE_LEDS 0x0081U
+
+static inline bool tpacpi_is_led_restricted(const unsigned int led)
+{
+#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
+ return false;
+#else
+ return (TPACPI_SAFE_LEDS & (1 << led)) == 0;
+#endif
+}
static int led_get_status(const unsigned int led)
{
@@ -4639,16 +4799,20 @@ static int led_set_status(const unsigned int led,
switch (led_supported) {
case TPACPI_LED_570:
/* 570 */
- if (led > 7)
+ if (unlikely(led > 7))
return -EINVAL;
+ if (unlikely(tpacpi_is_led_restricted(led)))
+ return -EPERM;
if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
(1 << led), led_sled_arg1[ledstatus]))
rc = -EIO;
break;
case TPACPI_LED_OLD:
/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
- if (led > 7)
+ if (unlikely(led > 7))
return -EINVAL;
+ if (unlikely(tpacpi_is_led_restricted(led)))
+ return -EPERM;
rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led));
if (rc >= 0)
rc = ec_write(TPACPI_LED_EC_HLBL,
@@ -4659,6 +4823,10 @@ static int led_set_status(const unsigned int led,
break;
case TPACPI_LED_NEW:
/* all others */
+ if (unlikely(led >= TPACPI_LED_NUMLEDS))
+ return -EINVAL;
+ if (unlikely(tpacpi_is_led_restricted(led)))
+ return -EPERM;
if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
led, led_led_arg1[ledstatus]))
rc = -EIO;
@@ -4751,6 +4919,30 @@ static void led_exit(void)
kfree(tpacpi_leds);
}
+static int __init tpacpi_init_led(unsigned int led)
+{
+ int rc;
+
+ tpacpi_leds[led].led = led;
+
+ tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set;
+ tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set;
+ if (led_supported == TPACPI_LED_570)
+ tpacpi_leds[led].led_classdev.brightness_get =
+ &led_sysfs_get;
+
+ tpacpi_leds[led].led_classdev.name = tpacpi_led_names[led];
+
+ INIT_WORK(&tpacpi_leds[led].work, led_set_status_worker);
+
+ rc = led_classdev_register(&tpacpi_pdev->dev,
+ &tpacpi_leds[led].led_classdev);
+ if (rc < 0)
+ tpacpi_leds[led].led_classdev.name = NULL;
+
+ return rc;
+}
+
static int __init led_init(struct ibm_init_struct *iibm)
{
unsigned int i;
@@ -4784,27 +4976,21 @@ static int __init led_init(struct ibm_init_struct *iibm)
}
for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
- tpacpi_leds[i].led = i;
-
- tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set;
- tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set;
- if (led_supported == TPACPI_LED_570)
- tpacpi_leds[i].led_classdev.brightness_get =
- &led_sysfs_get;
-
- tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i];
-
- INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker);
-
- rc = led_classdev_register(&tpacpi_pdev->dev,
- &tpacpi_leds[i].led_classdev);
- if (rc < 0) {
- tpacpi_leds[i].led_classdev.name = NULL;
- led_exit();
- return rc;
+ if (!tpacpi_is_led_restricted(i)) {
+ rc = tpacpi_init_led(i);
+ if (rc < 0) {
+ led_exit();
+ return rc;
+ }
}
}
+#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
+ if (led_supported != TPACPI_LED_NONE)
+ printk(TPACPI_NOTICE
+ "warning: userspace override of important "
+ "firmware LEDs is enabled\n");
+#endif
return (led_supported != TPACPI_LED_NONE)? 0 : 1;
}
@@ -5340,6 +5526,20 @@ static struct ibm_struct ecdump_driver_data = {
#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
+/*
+ * ThinkPads can read brightness from two places: EC HBRV (0x31), or
+ * CMOS NVRAM byte 0x5E, bits 0-3.
+ *
+ * EC HBRV (0x31) has the following layout
+ * Bit 7: unknown function
+ * Bit 6: unknown function
+ * Bit 5: Z: honour scale changes, NZ: ignore scale changes
+ * Bit 4: must be set to zero to avoid problems
+ * Bit 3-0: backlight brightness level
+ *
+ * brightness_get_raw returns status data in the HBRV layout
+ */
+
enum {
TP_EC_BACKLIGHT = 0x31,
@@ -5349,108 +5549,164 @@ enum {
TP_EC_BACKLIGHT_MAPSW = 0x20,
};
+enum tpacpi_brightness_access_mode {
+ TPACPI_BRGHT_MODE_AUTO = 0, /* Not implemented yet */
+ TPACPI_BRGHT_MODE_EC, /* EC control */
+ TPACPI_BRGHT_MODE_UCMS_STEP, /* UCMS step-based control */
+ TPACPI_BRGHT_MODE_ECNVRAM, /* EC control w/ NVRAM store */
+ TPACPI_BRGHT_MODE_MAX
+};
+
static struct backlight_device *ibm_backlight_device;
-static int brightness_mode;
+
+static enum tpacpi_brightness_access_mode brightness_mode =
+ TPACPI_BRGHT_MODE_MAX;
+
static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
static struct mutex brightness_mutex;
-/*
- * ThinkPads can read brightness from two places: EC 0x31, or
- * CMOS NVRAM byte 0x5E, bits 0-3.
- *
- * EC 0x31 has the following layout
- * Bit 7: unknown function
- * Bit 6: unknown function
- * Bit 5: Z: honour scale changes, NZ: ignore scale changes
- * Bit 4: must be set to zero to avoid problems
- * Bit 3-0: backlight brightness level
- *
- * brightness_get_raw returns status data in the EC 0x31 layout
- */
-static int brightness_get_raw(int *status)
+/* NVRAM brightness access,
+ * call with brightness_mutex held! */
+static unsigned int tpacpi_brightness_nvram_get(void)
{
- u8 lec = 0, lcmos = 0, level = 0;
+ u8 lnvram;
- if (brightness_mode & 1) {
- if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec))
- return -EIO;
- level = lec & TP_EC_BACKLIGHT_LVLMSK;
- };
- if (brightness_mode & 2) {
- lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
- & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
- >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
- lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07;
- level = lcmos;
- }
-
- if (brightness_mode == 3) {
- *status = lec; /* Prefer EC, CMOS is just a backing store */
- lec &= TP_EC_BACKLIGHT_LVLMSK;
- if (lec == lcmos)
- tp_warned.bright_cmos_ec_unsync = 0;
- else {
- if (!tp_warned.bright_cmos_ec_unsync) {
- printk(TPACPI_ERR
- "CMOS NVRAM (%u) and EC (%u) do not "
- "agree on display brightness level\n",
- (unsigned int) lcmos,
- (unsigned int) lec);
- tp_warned.bright_cmos_ec_unsync = 1;
- }
+ lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
+ & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
+ >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
+ lnvram &= (tp_features.bright_16levels) ? 0x0f : 0x07;
+
+ return lnvram;
+}
+
+static void tpacpi_brightness_checkpoint_nvram(void)
+{
+ u8 lec = 0;
+ u8 b_nvram;
+
+ if (brightness_mode != TPACPI_BRGHT_MODE_ECNVRAM)
+ return;
+
+ vdbg_printk(TPACPI_DBG_BRGHT,
+ "trying to checkpoint backlight level to NVRAM...\n");
+
+ if (mutex_lock_killable(&brightness_mutex) < 0)
+ return;
+
+ if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
+ goto unlock;
+ lec &= TP_EC_BACKLIGHT_LVLMSK;
+ b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
+
+ if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
+ >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
+ /* NVRAM needs update */
+ b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
+ TP_NVRAM_POS_LEVEL_BRIGHTNESS);
+ b_nvram |= lec;
+ nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
+ dbg_printk(TPACPI_DBG_BRGHT,
+ "updated NVRAM backlight level to %u (0x%02x)\n",
+ (unsigned int) lec, (unsigned int) b_nvram);
+ } else
+ vdbg_printk(TPACPI_DBG_BRGHT,
+ "NVRAM backlight level already is %u (0x%02x)\n",
+ (unsigned int) lec, (unsigned int) b_nvram);
+
+unlock:
+ mutex_unlock(&brightness_mutex);
+}
+
+
+/* call with brightness_mutex held! */
+static int tpacpi_brightness_get_raw(int *status)
+{
+ u8 lec = 0;
+
+ switch (brightness_mode) {
+ case TPACPI_BRGHT_MODE_UCMS_STEP:
+ *status = tpacpi_brightness_nvram_get();
+ return 0;
+ case TPACPI_BRGHT_MODE_EC:
+ case TPACPI_BRGHT_MODE_ECNVRAM:
+ if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
return -EIO;
- }
- } else {
- *status = level;
+ *status = lec;
+ return 0;
+ default:
+ return -ENXIO;
}
+}
+
+/* call with brightness_mutex held! */
+/* do NOT call with illegal backlight level value */
+static int tpacpi_brightness_set_ec(unsigned int value)
+{
+ u8 lec = 0;
+
+ if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
+ return -EIO;
+
+ if (unlikely(!acpi_ec_write(TP_EC_BACKLIGHT,
+ (lec & TP_EC_BACKLIGHT_CMDMSK) |
+ (value & TP_EC_BACKLIGHT_LVLMSK))))
+ return -EIO;
+
+ return 0;
+}
+
+/* call with brightness_mutex held! */
+static int tpacpi_brightness_set_ucmsstep(unsigned int value)
+{
+ int cmos_cmd, inc;
+ unsigned int current_value, i;
+
+ current_value = tpacpi_brightness_nvram_get();
+
+ if (value == current_value)
+ return 0;
+
+ cmos_cmd = (value > current_value) ?
+ TP_CMOS_BRIGHTNESS_UP :
+ TP_CMOS_BRIGHTNESS_DOWN;
+ inc = (value > current_value) ? 1 : -1;
+
+ for (i = current_value; i != value; i += inc)
+ if (issue_thinkpad_cmos_command(cmos_cmd))
+ return -EIO;
return 0;
}
/* May return EINTR which can always be mapped to ERESTARTSYS */
-static int brightness_set(int value)
+static int brightness_set(unsigned int value)
{
- int cmos_cmd, inc, i, res;
- int current_value;
- int command_bits;
+ int res;
if (value > ((tp_features.bright_16levels)? 15 : 7) ||
value < 0)
return -EINVAL;
+ vdbg_printk(TPACPI_DBG_BRGHT,
+ "set backlight level to %d\n", value);
+
res = mutex_lock_killable(&brightness_mutex);
if (res < 0)
return res;
- res = brightness_get_raw(&current_value);
- if (res < 0)
- goto errout;
-
- command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK;
- current_value &= TP_EC_BACKLIGHT_LVLMSK;
-
- cmos_cmd = value > current_value ?
- TP_CMOS_BRIGHTNESS_UP :
- TP_CMOS_BRIGHTNESS_DOWN;
- inc = (value > current_value)? 1 : -1;
-
- res = 0;
- for (i = current_value; i != value; i += inc) {
- if ((brightness_mode & 2) &&
- issue_thinkpad_cmos_command(cmos_cmd)) {
- res = -EIO;
- goto errout;
- }
- if ((brightness_mode & 1) &&
- !acpi_ec_write(TP_EC_BACKLIGHT,
- (i + inc) | command_bits)) {
- res = -EIO;
- goto errout;;
- }
+ switch (brightness_mode) {
+ case TPACPI_BRGHT_MODE_EC:
+ case TPACPI_BRGHT_MODE_ECNVRAM:
+ res = tpacpi_brightness_set_ec(value);
+ break;
+ case TPACPI_BRGHT_MODE_UCMS_STEP:
+ res = tpacpi_brightness_set_ucmsstep(value);
+ break;
+ default:
+ res = -ENXIO;
}
-errout:
mutex_unlock(&brightness_mutex);
return res;
}
@@ -5459,21 +5715,34 @@ errout:
static int brightness_update_status(struct backlight_device *bd)
{
- /* it is the backlight class's job (caller) to handle
- * EINTR and other errors properly */
- return brightness_set(
+ unsigned int level =
(bd->props.fb_blank == FB_BLANK_UNBLANK &&
bd->props.power == FB_BLANK_UNBLANK) ?
- bd->props.brightness : 0);
+ bd->props.brightness : 0;
+
+ dbg_printk(TPACPI_DBG_BRGHT,
+ "backlight: attempt to set level to %d\n",
+ level);
+
+ /* it is the backlight class's job (caller) to handle
+ * EINTR and other errors properly */
+ return brightness_set(level);
}
static int brightness_get(struct backlight_device *bd)
{
int status, res;
- res = brightness_get_raw(&status);
+ res = mutex_lock_killable(&brightness_mutex);
if (res < 0)
- return 0; /* FIXME: teach backlight about error handling */
+ return 0;
+
+ res = tpacpi_brightness_get_raw(&status);
+
+ mutex_unlock(&brightness_mutex);
+
+ if (res < 0)
+ return 0;
return status & TP_EC_BACKLIGHT_LVLMSK;
}
@@ -5523,7 +5792,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
}
if (!brightness_enable) {
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
"brightness support disabled by "
"module parameter\n");
return 1;
@@ -5538,20 +5807,38 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
if (b == 16)
tp_features.bright_16levels = 1;
- if (!brightness_mode) {
- if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
- brightness_mode = 2;
- else
- brightness_mode = 3;
+ /*
+ * Check for module parameter bogosity, note that we
+ * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be
+ * able to detect "unspecified"
+ */
+ if (brightness_mode > TPACPI_BRGHT_MODE_MAX)
+ return -EINVAL;
- dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n",
- brightness_mode);
- }
+ /* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */
+ if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||
+ brightness_mode == TPACPI_BRGHT_MODE_MAX) {
+ if (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) {
+ /*
+ * IBM models that define HBRV probably have
+ * EC-based backlight level control
+ */
+ if (acpi_evalf(ec_handle, NULL, "HBRV", "qd"))
+ /* T40-T43, R50-R52, R50e, R51e, X31-X41 */
+ brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
+ else
+ /* all other IBM ThinkPads */
+ brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
+ } else
+ /* All Lenovo ThinkPads */
+ brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
- if (brightness_mode > 3)
- return -EINVAL;
+ dbg_printk(TPACPI_DBG_BRGHT,
+ "selected brightness_mode=%d\n",
+ brightness_mode);
+ }
- if (brightness_get_raw(&b) < 0)
+ if (tpacpi_brightness_get_raw(&b) < 0)
return 1;
if (tp_features.bright_16levels)
@@ -5565,7 +5852,8 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
printk(TPACPI_ERR "Could not register backlight device\n");
return PTR_ERR(ibm_backlight_device);
}
- vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
+ "brightness is supported\n");
ibm_backlight_device->props.max_brightness =
(tp_features.bright_16levels)? 15 : 7;
@@ -5575,13 +5863,25 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
return 0;
}
+static void brightness_suspend(pm_message_t state)
+{
+ tpacpi_brightness_checkpoint_nvram();
+}
+
+static void brightness_shutdown(void)
+{
+ tpacpi_brightness_checkpoint_nvram();
+}
+
static void brightness_exit(void)
{
if (ibm_backlight_device) {
- vdbg_printk(TPACPI_DBG_EXIT,
+ vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_BRGHT,
"calling backlight_device_unregister()\n");
backlight_device_unregister(ibm_backlight_device);
}
+
+ tpacpi_brightness_checkpoint_nvram();
}
static int brightness_read(char *p)
@@ -5628,6 +5928,9 @@ static int brightness_write(char *buf)
return -EINVAL;
}
+ tpacpi_disclose_usertask("procfs brightness",
+ "set level to %d\n", level);
+
/*
* Now we know what the final level should be, so we try to set it.
* Doing it this way makes the syscall restartable in case of EINTR
@@ -5641,6 +5944,8 @@ static struct ibm_struct brightness_driver_data = {
.read = brightness_read,
.write = brightness_write,
.exit = brightness_exit,
+ .suspend = brightness_suspend,
+ .shutdown = brightness_shutdown,
};
/*************************************************************************
@@ -5811,7 +6116,7 @@ static struct ibm_struct volume_driver_data = {
* ThinkPads from this same time period (and earlier) probably lack the
* tachometer as well.
*
- * Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare
+ * Unfortunately a lot of ThinkPads with new-style ECs but whose firmware
* was never fixed by IBM to report the EC firmware version string
* probably support the tachometer (like the early X models), so
* detecting it is quite hard. We need more data to know for sure.
@@ -6086,6 +6391,9 @@ static int fan_set_level(int level)
default:
return -ENXIO;
}
+
+ vdbg_printk(TPACPI_DBG_FAN,
+ "fan control: set fan control register to 0x%02x\n", level);
return 0;
}
@@ -6163,6 +6471,11 @@ static int fan_set_enable(void)
}
mutex_unlock(&fan_mutex);
+
+ if (!rc)
+ vdbg_printk(TPACPI_DBG_FAN,
+ "fan control: set fan control register to 0x%02x\n",
+ s);
return rc;
}
@@ -6199,6 +6512,9 @@ static int fan_set_disable(void)
rc = -ENXIO;
}
+ if (!rc)
+ vdbg_printk(TPACPI_DBG_FAN,
+ "fan control: set fan control register to 0\n");
mutex_unlock(&fan_mutex);
return rc;
@@ -6327,6 +6643,9 @@ static ssize_t fan_pwm1_enable_store(struct device *dev,
if (parse_strtoul(buf, 2, &t))
return -EINVAL;
+ tpacpi_disclose_usertask("hwmon pwm1_enable",
+ "set fan mode to %lu\n", t);
+
switch (t) {
case 0:
level = TP_EC_FAN_FULLSPEED;
@@ -6392,6 +6711,9 @@ static ssize_t fan_pwm1_store(struct device *dev,
if (parse_strtoul(buf, 255, &s))
return -EINVAL;
+ tpacpi_disclose_usertask("hwmon pwm1",
+ "set fan speed to %lu\n", s);
+
/* scale down from 0-255 to 0-7 */
newlevel = (s >> 5) & 0x07;
@@ -6458,6 +6780,8 @@ static ssize_t fan_fan_watchdog_store(struct device_driver *drv,
fan_watchdog_maxinterval = t;
fan_watchdog_reset();
+ tpacpi_disclose_usertask("fan_watchdog", "set to %lu\n", t);
+
return count;
}
@@ -6479,7 +6803,8 @@ static int __init fan_init(struct ibm_init_struct *iibm)
{
int rc;
- vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
+ "initializing fan subdriver\n");
mutex_init(&fan_mutex);
fan_status_access_mode = TPACPI_FAN_NONE;
@@ -6538,7 +6863,8 @@ static int __init fan_init(struct ibm_init_struct *iibm)
}
}
- vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
+ "fan is %s, modes %d, %d\n",
str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
fan_control_access_mode != TPACPI_FAN_WR_NONE),
fan_status_access_mode, fan_control_access_mode);
@@ -6547,7 +6873,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
if (!fan_control_allowed) {
fan_control_access_mode = TPACPI_FAN_WR_NONE;
fan_control_commands = 0;
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
"fan control features disabled by parameter\n");
}
@@ -6576,7 +6902,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
static void fan_exit(void)
{
- vdbg_printk(TPACPI_DBG_EXIT,
+ vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_FAN,
"cancelling any pending fan watchdog tasks\n");
/* FIXME: can we really do this unconditionally? */
@@ -6757,6 +7083,9 @@ static int fan_write_cmd_level(const char *cmd, int *rc)
if (*rc == -ENXIO)
printk(TPACPI_ERR "level command accepted for unsupported "
"access mode %d", fan_control_access_mode);
+ else if (!*rc)
+ tpacpi_disclose_usertask("procfs fan",
+ "set level to %d\n", level);
return 1;
}
@@ -6770,6 +7099,8 @@ static int fan_write_cmd_enable(const char *cmd, int *rc)
if (*rc == -ENXIO)
printk(TPACPI_ERR "enable command accepted for unsupported "
"access mode %d", fan_control_access_mode);
+ else if (!*rc)
+ tpacpi_disclose_usertask("procfs fan", "enable\n");
return 1;
}
@@ -6783,6 +7114,8 @@ static int fan_write_cmd_disable(const char *cmd, int *rc)
if (*rc == -ENXIO)
printk(TPACPI_ERR "disable command accepted for unsupported "
"access mode %d", fan_control_access_mode);
+ else if (!*rc)
+ tpacpi_disclose_usertask("procfs fan", "disable\n");
return 1;
}
@@ -6801,6 +7134,9 @@ static int fan_write_cmd_speed(const char *cmd, int *rc)
if (*rc == -ENXIO)
printk(TPACPI_ERR "speed command accepted for unsupported "
"access mode %d", fan_control_access_mode);
+ else if (!*rc)
+ tpacpi_disclose_usertask("procfs fan",
+ "set speed to %d\n", speed);
return 1;
}
@@ -6814,8 +7150,12 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc)
if (interval < 0 || interval > 120)
*rc = -EINVAL;
- else
+ else {
fan_watchdog_maxinterval = interval;
+ tpacpi_disclose_usertask("procfs fan",
+ "set watchdog timer to %d\n",
+ interval);
+ }
return 1;
}
@@ -7243,10 +7583,10 @@ module_param_named(fan_control, fan_control_allowed, bool, 0);
MODULE_PARM_DESC(fan_control,
"Enables setting fan parameters features when true");
-module_param_named(brightness_mode, brightness_mode, int, 0);
+module_param_named(brightness_mode, brightness_mode, uint, 0);
MODULE_PARM_DESC(brightness_mode,
"Selects brightness control strategy: "
- "0=auto, 1=EC, 2=CMOS, 3=both");
+ "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM");
module_param(brightness_enable, uint, 0);
MODULE_PARM_DESC(brightness_enable,
@@ -7515,9 +7855,6 @@ static int __init thinkpad_acpi_module_init(void)
return 0;
}
-/* Please remove this in year 2009 */
-MODULE_ALIAS("ibm_acpi");
-
MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
/*
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 2f269e117b8..043b208d971 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -81,6 +81,7 @@ static struct wmi_block wmi_blocks;
static int acpi_wmi_remove(struct acpi_device *device, int type);
static int acpi_wmi_add(struct acpi_device *device);
+static void acpi_wmi_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id wmi_device_ids[] = {
{"PNP0C14", 0},
@@ -96,6 +97,7 @@ static struct acpi_driver acpi_wmi_driver = {
.ops = {
.add = acpi_wmi_add,
.remove = acpi_wmi_remove,
+ .notify = acpi_wmi_notify,
},
};
@@ -643,12 +645,11 @@ acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address,
}
}
-static void acpi_wmi_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_wmi_notify(struct acpi_device *device, u32 event)
{
struct guid_block *block;
struct wmi_block *wblock;
struct list_head *p;
- struct acpi_device *device = data;
list_for_each(p, &wmi_blocks.list) {
wblock = list_entry(p, struct wmi_block, list);
@@ -669,9 +670,6 @@ static void acpi_wmi_notify(acpi_handle handle, u32 event, void *data)
static int acpi_wmi_remove(struct acpi_device *device, int type)
{
- acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
- acpi_wmi_notify);
-
acpi_remove_address_space_handler(device->handle,
ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler);
@@ -683,13 +681,6 @@ static int __init acpi_wmi_add(struct acpi_device *device)
acpi_status status;
int result = 0;
- status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
- acpi_wmi_notify, device);
- if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX "Error installing notify handler\n");
- return -ENODEV;
- }
-
status = acpi_install_address_space_handler(device->handle,
ACPI_ADR_SPACE_EC,
&acpi_wmi_ec_space_handler,
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index efea128f02d..4a651f69e17 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -167,7 +167,7 @@ struct pnp_card *pnp_alloc_card(struct pnp_protocol *protocol, int id, char *pnp
card->dev.parent = &card->protocol->dev;
dev_set_name(&card->dev, "%02x:%02x", card->protocol->number, card->number);
- card->dev.coherent_dma_mask = DMA_24BIT_MASK;
+ card->dev.coherent_dma_mask = DMA_BIT_MASK(24);
card->dev.dma_mask = &card->dev.coherent_dma_mask;
dev_id = pnp_add_card_id(card, pnpid);
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 14814f23173..5dba90995d9 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -137,7 +137,7 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid
INIT_LIST_HEAD(&dev->options);
dev->protocol = protocol;
dev->number = id;
- dev->dma_mask = DMA_24BIT_MASK;
+ dev->dma_mask = DMA_BIT_MASK(24);
dev->dev.parent = &dev->protocol->dev;
dev->dev.bus = &pnp_bus_type;
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 2834846a185..9a3a682c698 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -83,7 +83,6 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
acpi_handle handle = dev->data;
struct acpi_buffer buffer;
int ret;
- acpi_status status;
pnp_dbg(&dev->dev, "set resources\n");
ret = pnpacpi_build_resource_template(dev, &buffer);
@@ -94,21 +93,31 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
kfree(buffer.pointer);
return ret;
}
- status = acpi_set_current_resources(handle, &buffer);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(acpi_set_current_resources(handle, &buffer)))
ret = -EINVAL;
+ else if (acpi_bus_power_manageable(handle))
+ ret = acpi_bus_set_power(handle, ACPI_STATE_D0);
kfree(buffer.pointer);
return ret;
}
static int pnpacpi_disable_resources(struct pnp_dev *dev)
{
- acpi_status status;
+ acpi_handle handle = dev->data;
+ int ret;
+
+ dev_dbg(&dev->dev, "disable resources\n");
/* acpi_unregister_gsi(pnp_irq(dev, 0)); */
- status = acpi_evaluate_object((acpi_handle) dev->data,
- "_DIS", NULL, NULL);
- return ACPI_FAILURE(status) ? -ENODEV : 0;
+ ret = 0;
+ if (acpi_bus_power_manageable(handle)) {
+ ret = acpi_bus_set_power(handle, ACPI_STATE_D3);
+ if (ret)
+ return ret;
+ }
+ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL)))
+ ret = -ENODEV;
+ return ret;
}
#ifdef CONFIG_ACPI_SLEEP
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 0c056fcc01c..62bb98124e2 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -83,7 +83,7 @@ static int bq27x00_read(u8 reg, int *rt_value, int b_single,
}
/*
- * Return the battery temperature in Celcius degrees
+ * Return the battery temperature in Celsius degrees
* Or < 0 if something fails.
*/
static int bq27x00_battery_temperature(struct bq27x00_device_info *di)
diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c
index 41aec2acbb9..e8b278f7178 100644
--- a/drivers/power/pcf50633-charger.c
+++ b/drivers/power/pcf50633-charger.c
@@ -36,6 +36,8 @@ struct pcf50633_mbc {
struct power_supply usb;
struct power_supply adapter;
+
+ struct delayed_work charging_restart_work;
};
int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
@@ -43,6 +45,8 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev);
int ret = 0;
u8 bits;
+ int charging_start = 1;
+ u8 mbcs2, chgmod;
if (ma >= 1000)
bits = PCF50633_MBCC7_USB_1000mA;
@@ -50,8 +54,10 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
bits = PCF50633_MBCC7_USB_500mA;
else if (ma >= 100)
bits = PCF50633_MBCC7_USB_100mA;
- else
+ else {
bits = PCF50633_MBCC7_USB_SUSPEND;
+ charging_start = 0;
+ }
ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC7,
PCF50633_MBCC7_USB_MASK, bits);
@@ -60,6 +66,22 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
else
dev_info(pcf->dev, "usb curlim to %d mA\n", ma);
+ /* Manual charging start */
+ mbcs2 = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
+ chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
+
+ /* If chgmod == BATFULL, setting chgena has no effect.
+ * We need to set resume instead.
+ */
+ if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL)
+ pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1,
+ PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA);
+ else
+ pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1,
+ PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME);
+
+ mbc->usb_active = charging_start;
+
power_supply_changed(&mbc->usb);
return ret;
@@ -84,21 +106,6 @@ int pcf50633_mbc_get_status(struct pcf50633 *pcf)
}
EXPORT_SYMBOL_GPL(pcf50633_mbc_get_status);
-void pcf50633_mbc_set_status(struct pcf50633 *pcf, int what, int status)
-{
- struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev);
-
- if (what & PCF50633_MBC_USB_ONLINE)
- mbc->usb_online = !!status;
- if (what & PCF50633_MBC_USB_ACTIVE)
- mbc->usb_active = !!status;
- if (what & PCF50633_MBC_ADAPTER_ONLINE)
- mbc->adapter_online = !!status;
- if (what & PCF50633_MBC_ADAPTER_ACTIVE)
- mbc->adapter_active = !!status;
-}
-EXPORT_SYMBOL_GPL(pcf50633_mbc_set_status);
-
static ssize_t
show_chgmode(struct device *dev, struct device_attribute *attr, char *buf)
{
@@ -160,10 +167,44 @@ static struct attribute_group mbc_attr_group = {
.attrs = pcf50633_mbc_sysfs_entries,
};
+/* MBC state machine switches into charging mode when the battery voltage
+ * falls below 96% of a battery float voltage. But the voltage drop in Li-ion
+ * batteries is marginal(1~2 %) till about 80% of its capacity - which means,
+ * after a BATFULL, charging won't be restarted until 80%.
+ *
+ * This work_struct function restarts charging at regular intervals to make
+ * sure we don't discharge too much
+ */
+
+static void pcf50633_mbc_charging_restart(struct work_struct *work)
+{
+ struct pcf50633_mbc *mbc;
+ u8 mbcs2, chgmod;
+
+ mbc = container_of(work, struct pcf50633_mbc,
+ charging_restart_work.work);
+
+ mbcs2 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2);
+ chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
+
+ if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL)
+ return;
+
+ /* Restart charging */
+ pcf50633_reg_set_bit_mask(mbc->pcf, PCF50633_REG_MBCC1,
+ PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME);
+ mbc->usb_active = 1;
+ power_supply_changed(&mbc->usb);
+
+ dev_info(mbc->pcf->dev, "Charging restarted\n");
+}
+
static void
pcf50633_mbc_irq_handler(int irq, void *data)
{
struct pcf50633_mbc *mbc = data;
+ int chg_restart_interval =
+ mbc->pcf->pdata->charging_restart_interval;
/* USB */
if (irq == PCF50633_IRQ_USBINS) {
@@ -172,6 +213,7 @@ pcf50633_mbc_irq_handler(int irq, void *data)
mbc->usb_online = 0;
mbc->usb_active = 0;
pcf50633_mbc_usb_curlim_set(mbc->pcf, 0);
+ cancel_delayed_work_sync(&mbc->charging_restart_work);
}
/* Adapter */
@@ -186,7 +228,14 @@ pcf50633_mbc_irq_handler(int irq, void *data)
if (irq == PCF50633_IRQ_BATFULL) {
mbc->usb_active = 0;
mbc->adapter_active = 0;
- }
+
+ if (chg_restart_interval > 0)
+ schedule_delayed_work(&mbc->charging_restart_work,
+ chg_restart_interval);
+ } else if (irq == PCF50633_IRQ_USBLIMON)
+ mbc->usb_active = 0;
+ else if (irq == PCF50633_IRQ_USBLIMOFF)
+ mbc->usb_active = 1;
power_supply_changed(&mbc->usb);
power_supply_changed(&mbc->adapter);
@@ -303,6 +352,9 @@ static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
return ret;
}
+ INIT_DELAYED_WORK(&mbc->charging_restart_work,
+ pcf50633_mbc_charging_restart);
+
ret = sysfs_create_group(&pdev->dev.kobj, &mbc_attr_group);
if (ret)
dev_err(mbc->pcf->dev, "failed to create sysfs entries\n");
@@ -328,6 +380,8 @@ static int __devexit pcf50633_mbc_remove(struct platform_device *pdev)
power_supply_unregister(&mbc->usb);
power_supply_unregister(&mbc->adapter);
+ cancel_delayed_work_sync(&mbc->charging_restart_work);
+
kfree(mbc);
return 0;
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c
index b56a704409d..a232de6a570 100644
--- a/drivers/power/pda_power.c
+++ b/drivers/power/pda_power.c
@@ -12,11 +12,14 @@
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/power_supply.h>
#include <linux/pda_power.h>
+#include <linux/regulator/consumer.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
+#include <linux/usb/otg.h>
static inline unsigned int get_irq_flags(struct resource *res)
{
@@ -35,6 +38,11 @@ static struct timer_list supply_timer;
static struct timer_list polling_timer;
static int polling;
+#ifdef CONFIG_USB_OTG_UTILS
+static struct otg_transceiver *transceiver;
+#endif
+static struct regulator *ac_draw;
+
enum {
PDA_PSY_OFFLINE = 0,
PDA_PSY_ONLINE = 1,
@@ -104,18 +112,35 @@ static void update_status(void)
static void update_charger(void)
{
- if (!pdata->set_charge)
- return;
-
- if (new_ac_status > 0) {
- dev_dbg(dev, "charger on (AC)\n");
- pdata->set_charge(PDA_POWER_CHARGE_AC);
- } else if (new_usb_status > 0) {
- dev_dbg(dev, "charger on (USB)\n");
- pdata->set_charge(PDA_POWER_CHARGE_USB);
- } else {
- dev_dbg(dev, "charger off\n");
- pdata->set_charge(0);
+ static int regulator_enabled;
+ int max_uA = pdata->ac_max_uA;
+
+ if (pdata->set_charge) {
+ if (new_ac_status > 0) {
+ dev_dbg(dev, "charger on (AC)\n");
+ pdata->set_charge(PDA_POWER_CHARGE_AC);
+ } else if (new_usb_status > 0) {
+ dev_dbg(dev, "charger on (USB)\n");
+ pdata->set_charge(PDA_POWER_CHARGE_USB);
+ } else {
+ dev_dbg(dev, "charger off\n");
+ pdata->set_charge(0);
+ }
+ } else if (ac_draw) {
+ if (new_ac_status > 0) {
+ regulator_set_current_limit(ac_draw, max_uA, max_uA);
+ if (!regulator_enabled) {
+ dev_dbg(dev, "charger on (AC)\n");
+ regulator_enable(ac_draw);
+ regulator_enabled = 1;
+ }
+ } else {
+ if (regulator_enabled) {
+ dev_dbg(dev, "charger off\n");
+ regulator_disable(ac_draw);
+ regulator_enabled = 0;
+ }
+ }
}
}
@@ -194,6 +219,13 @@ static void polling_timer_func(unsigned long unused)
jiffies + msecs_to_jiffies(pdata->polling_interval));
}
+#ifdef CONFIG_USB_OTG_UTILS
+static int otg_is_usb_online(void)
+{
+ return (transceiver->state == OTG_STATE_B_PERIPHERAL);
+}
+#endif
+
static int pda_power_probe(struct platform_device *pdev)
{
int ret = 0;
@@ -227,6 +259,9 @@ static int pda_power_probe(struct platform_device *pdev)
if (!pdata->polling_interval)
pdata->polling_interval = 2000;
+ if (!pdata->ac_max_uA)
+ pdata->ac_max_uA = 500000;
+
setup_timer(&charger_timer, charger_timer_func, 0);
setup_timer(&supply_timer, supply_timer_func, 0);
@@ -240,6 +275,13 @@ static int pda_power_probe(struct platform_device *pdev)
pda_psy_usb.num_supplicants = pdata->num_supplicants;
}
+ ac_draw = regulator_get(dev, "ac_draw");
+ if (IS_ERR(ac_draw)) {
+ dev_dbg(dev, "couldn't get ac_draw regulator\n");
+ ac_draw = NULL;
+ ret = PTR_ERR(ac_draw);
+ }
+
if (pdata->is_ac_online) {
ret = power_supply_register(&pdev->dev, &pda_psy_ac);
if (ret) {
@@ -261,6 +303,13 @@ static int pda_power_probe(struct platform_device *pdev)
}
}
+#ifdef CONFIG_USB_OTG_UTILS
+ transceiver = otg_get_transceiver();
+ if (transceiver && !pdata->is_usb_online) {
+ pdata->is_usb_online = otg_is_usb_online;
+ }
+#endif
+
if (pdata->is_usb_online) {
ret = power_supply_register(&pdev->dev, &pda_psy_usb);
if (ret) {
@@ -300,10 +349,18 @@ usb_irq_failed:
usb_supply_failed:
if (pdata->is_ac_online && ac_irq)
free_irq(ac_irq->start, &pda_psy_ac);
+#ifdef CONFIG_USB_OTG_UTILS
+ if (transceiver)
+ otg_put_transceiver(transceiver);
+#endif
ac_irq_failed:
if (pdata->is_ac_online)
power_supply_unregister(&pda_psy_ac);
ac_supply_failed:
+ if (ac_draw) {
+ regulator_put(ac_draw);
+ ac_draw = NULL;
+ }
if (pdata->exit)
pdata->exit(dev);
init_failed:
@@ -327,6 +384,14 @@ static int pda_power_remove(struct platform_device *pdev)
power_supply_unregister(&pda_psy_usb);
if (pdata->is_ac_online)
power_supply_unregister(&pda_psy_ac);
+#ifdef CONFIG_USB_OTG_UTILS
+ if (transceiver)
+ otg_put_transceiver(transceiver);
+#endif
+ if (ac_draw) {
+ regulator_put(ac_draw);
+ ac_draw = NULL;
+ }
if (pdata->exit)
pdata->exit(dev);
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index ac01e06817f..da73591017f 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -93,6 +93,8 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(voltage_avg),
POWER_SUPPLY_ATTR(current_now),
POWER_SUPPLY_ATTR(current_avg),
+ POWER_SUPPLY_ATTR(power_now),
+ POWER_SUPPLY_ATTR(power_avg),
POWER_SUPPLY_ATTR(charge_full_design),
POWER_SUPPLY_ATTR(charge_empty_design),
POWER_SUPPLY_ATTR(charge_full),
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 5c13f61bfb1..74d0bfa3f31 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -381,9 +381,9 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
rdev->dev.release = rio_release_dev;
rio_dev_get(rdev);
- rdev->dma_mask = DMA_32BIT_MASK;
+ rdev->dma_mask = DMA_BIT_MASK(32);
rdev->dev.dma_mask = &rdev->dma_mask;
- rdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+ rdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
if ((rdev->pef & RIO_PEF_INB_DOORBELL) &&
(rdev->dst_ops & RIO_DST_OPS_DOORBELL))
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index e7e0cf102d6..e58c0ce65aa 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -29,8 +29,12 @@ config REGULATOR_DEBUG
Say yes here to enable debugging support.
config REGULATOR_FIXED_VOLTAGE
- tristate
+ tristate "Fixed voltage regulator support"
default n
+ help
+ This driver provides support for fixed voltage regulators,
+ useful for systems which use a combination of software
+ managed regulators and simple non-configurable regulators.
config REGULATOR_VIRTUAL_CONSUMER
tristate "Virtual regulator consumer support"
@@ -52,6 +56,13 @@ config REGULATOR_BQ24022
charging select between 100 mA and 500 mA charging current
limit.
+config REGULATOR_TWL4030
+ bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
+ depends on TWL4030_CORE
+ help
+ This driver supports the voltage regulators provided by
+ this family of companion chips.
+
config REGULATOR_WM8350
tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC"
depends on MFD_WM8350
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 61b30c6ddec..bac133afc06 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
+obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c
index c175e38a4cd..7ecb820ceeb 100644
--- a/drivers/regulator/bq24022.c
+++ b/drivers/regulator/bq24022.c
@@ -105,7 +105,8 @@ static int __init bq24022_probe(struct platform_device *pdev)
ret = gpio_direction_output(pdata->gpio_iset2, 0);
ret = gpio_direction_output(pdata->gpio_nce, 1);
- bq24022 = regulator_register(&bq24022_desc, &pdev->dev, pdata);
+ bq24022 = regulator_register(&bq24022_desc, &pdev->dev,
+ pdata->init_data, pdata);
if (IS_ERR(bq24022)) {
dev_dbg(&pdev->dev, "couldn't register regulator\n");
ret = PTR_ERR(bq24022);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index f511a406fca..01f7702a805 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -28,33 +28,7 @@
static DEFINE_MUTEX(regulator_list_mutex);
static LIST_HEAD(regulator_list);
static LIST_HEAD(regulator_map_list);
-
-/*
- * struct regulator_dev
- *
- * Voltage / Current regulator class device. One for each regulator.
- */
-struct regulator_dev {
- struct regulator_desc *desc;
- int use_count;
-
- /* lists we belong to */
- struct list_head list; /* list of all regulators */
- struct list_head slist; /* list of supplied regulators */
-
- /* lists we own */
- struct list_head consumer_list; /* consumers we supply */
- struct list_head supply_list; /* regulators we supply */
-
- struct blocking_notifier_head notifier;
- struct mutex mutex; /* consumer lock */
- struct module *owner;
- struct device dev;
- struct regulation_constraints *constraints;
- struct regulator_dev *supply; /* for tree */
-
- void *reg_data; /* regulator_dev data */
-};
+static int has_full_constraints;
/*
* struct regulator_map
@@ -79,7 +53,6 @@ struct regulator {
int uA_load;
int min_uV;
int max_uV;
- int enabled; /* count of client enables */
char *supply_name;
struct device_attribute dev_attr;
struct regulator_dev *rdev;
@@ -312,6 +285,47 @@ static ssize_t regulator_state_show(struct device *dev,
}
static DEVICE_ATTR(state, 0444, regulator_state_show, NULL);
+static ssize_t regulator_status_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
+ int status;
+ char *label;
+
+ status = rdev->desc->ops->get_status(rdev);
+ if (status < 0)
+ return status;
+
+ switch (status) {
+ case REGULATOR_STATUS_OFF:
+ label = "off";
+ break;
+ case REGULATOR_STATUS_ON:
+ label = "on";
+ break;
+ case REGULATOR_STATUS_ERROR:
+ label = "error";
+ break;
+ case REGULATOR_STATUS_FAST:
+ label = "fast";
+ break;
+ case REGULATOR_STATUS_NORMAL:
+ label = "normal";
+ break;
+ case REGULATOR_STATUS_IDLE:
+ label = "idle";
+ break;
+ case REGULATOR_STATUS_STANDBY:
+ label = "standby";
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ return sprintf(buf, "%s\n", label);
+}
+static DEVICE_ATTR(status, 0444, regulator_status_show, NULL);
+
static ssize_t regulator_min_uA_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -678,6 +692,73 @@ static int set_machine_constraints(struct regulator_dev *rdev,
else
name = "regulator";
+ /* constrain machine-level voltage specs to fit
+ * the actual range supported by this regulator.
+ */
+ if (ops->list_voltage && rdev->desc->n_voltages) {
+ int count = rdev->desc->n_voltages;
+ int i;
+ int min_uV = INT_MAX;
+ int max_uV = INT_MIN;
+ int cmin = constraints->min_uV;
+ int cmax = constraints->max_uV;
+
+ /* it's safe to autoconfigure fixed-voltage supplies */
+ if (count == 1 && !cmin) {
+ cmin = INT_MIN;
+ cmax = INT_MAX;
+ }
+
+ /* voltage constraints are optional */
+ if ((cmin == 0) && (cmax == 0))
+ goto out;
+
+ /* else require explicit machine-level constraints */
+ if (cmin <= 0 || cmax <= 0 || cmax < cmin) {
+ pr_err("%s: %s '%s' voltage constraints\n",
+ __func__, "invalid", name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* initial: [cmin..cmax] valid, [min_uV..max_uV] not */
+ for (i = 0; i < count; i++) {
+ int value;
+
+ value = ops->list_voltage(rdev, i);
+ if (value <= 0)
+ continue;
+
+ /* maybe adjust [min_uV..max_uV] */
+ if (value >= cmin && value < min_uV)
+ min_uV = value;
+ if (value <= cmax && value > max_uV)
+ max_uV = value;
+ }
+
+ /* final: [min_uV..max_uV] valid iff constraints valid */
+ if (max_uV < min_uV) {
+ pr_err("%s: %s '%s' voltage constraints\n",
+ __func__, "unsupportable", name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* use regulator's subset of machine constraints */
+ if (constraints->min_uV < min_uV) {
+ pr_debug("%s: override '%s' %s, %d -> %d\n",
+ __func__, name, "min_uV",
+ constraints->min_uV, min_uV);
+ constraints->min_uV = min_uV;
+ }
+ if (constraints->max_uV > max_uV) {
+ pr_debug("%s: override '%s' %s, %d -> %d\n",
+ __func__, name, "max_uV",
+ constraints->max_uV, max_uV);
+ constraints->max_uV = max_uV;
+ }
+ }
+
rdev->constraints = constraints;
/* do we need to apply the constraint voltage */
@@ -695,10 +776,6 @@ static int set_machine_constraints(struct regulator_dev *rdev,
}
}
- /* are we enabled at boot time by firmware / bootloader */
- if (rdev->constraints->boot_on)
- rdev->use_count = 1;
-
/* do we need to setup our suspend state */
if (constraints->initial_state) {
ret = suspend_prepare(rdev, constraints->initial_state);
@@ -710,11 +787,27 @@ static int set_machine_constraints(struct regulator_dev *rdev,
}
}
- /* if always_on is set then turn the regulator on if it's not
- * already on. */
- if (constraints->always_on && ops->enable &&
- ((ops->is_enabled && !ops->is_enabled(rdev)) ||
- (!ops->is_enabled && !constraints->boot_on))) {
+ if (constraints->initial_mode) {
+ if (!ops->set_mode) {
+ printk(KERN_ERR "%s: no set_mode operation for %s\n",
+ __func__, name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = ops->set_mode(rdev, constraints->initial_mode);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "%s: failed to set initial mode for %s: %d\n",
+ __func__, name, ret);
+ goto out;
+ }
+ }
+
+ /* If the constraints say the regulator should be on at this point
+ * and we have control then make sure it is enabled.
+ */
+ if ((constraints->always_on || constraints->boot_on) && ops->enable) {
ret = ops->enable(rdev);
if (ret < 0) {
printk(KERN_ERR "%s: failed to enable %s\n",
@@ -817,6 +910,19 @@ static void unset_consumer_device_supply(struct regulator_dev *rdev,
}
}
+static void unset_regulator_supplies(struct regulator_dev *rdev)
+{
+ struct regulator_map *node, *n;
+
+ list_for_each_entry_safe(node, n, &regulator_map_list, list) {
+ if (rdev == node->regulator) {
+ list_del(&node->list);
+ kfree(node);
+ return;
+ }
+ }
+}
+
#define REG_STR_SIZE 32
static struct regulator *create_regulator(struct regulator_dev *rdev,
@@ -898,9 +1004,12 @@ overflow_err:
* @id: Supply name or regulator ID.
*
* Returns a struct regulator corresponding to the regulator producer,
- * or IS_ERR() condition containing errno. Use of supply names
- * configured via regulator_set_device_supply() is strongly
- * encouraged.
+ * or IS_ERR() condition containing errno.
+ *
+ * Use of supply names configured via regulator_set_device_supply() is
+ * strongly encouraged. It is recommended that the supply name used
+ * should match the name used for the supply and/or the relevant
+ * device pins in the datasheet.
*/
struct regulator *regulator_get(struct device *dev, const char *id)
{
@@ -922,8 +1031,6 @@ struct regulator *regulator_get(struct device *dev, const char *id)
goto found;
}
}
- printk(KERN_ERR "regulator: Unable to get requested regulator: %s\n",
- id);
mutex_unlock(&regulator_list_mutex);
return regulator;
@@ -961,10 +1068,6 @@ void regulator_put(struct regulator *regulator)
mutex_lock(&regulator_list_mutex);
rdev = regulator->rdev;
- if (WARN(regulator->enabled, "Releasing supply %s while enabled\n",
- regulator->supply_name))
- _regulator_disable(rdev);
-
/* remove any sysfs entries */
if (regulator->dev) {
sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
@@ -1039,12 +1142,7 @@ int regulator_enable(struct regulator *regulator)
int ret = 0;
mutex_lock(&rdev->mutex);
- if (regulator->enabled == 0)
- ret = _regulator_enable(rdev);
- else if (regulator->enabled < 0)
- ret = -EIO;
- if (ret == 0)
- regulator->enabled++;
+ ret = _regulator_enable(rdev);
mutex_unlock(&rdev->mutex);
return ret;
}
@@ -1055,6 +1153,11 @@ static int _regulator_disable(struct regulator_dev *rdev)
{
int ret = 0;
+ if (WARN(rdev->use_count <= 0,
+ "unbalanced disables for %s\n",
+ rdev->desc->name))
+ return -EIO;
+
/* are we the last user and permitted to disable ? */
if (rdev->use_count == 1 && !rdev->constraints->always_on) {
@@ -1103,16 +1206,7 @@ int regulator_disable(struct regulator *regulator)
int ret = 0;
mutex_lock(&rdev->mutex);
- if (regulator->enabled == 1) {
- ret = _regulator_disable(rdev);
- if (ret == 0)
- regulator->uA_load = 0;
- } else if (WARN(regulator->enabled <= 0,
- "unbalanced disables for supply %s\n",
- regulator->supply_name))
- ret = -EIO;
- if (ret == 0)
- regulator->enabled--;
+ ret = _regulator_disable(rdev);
mutex_unlock(&rdev->mutex);
return ret;
}
@@ -1159,7 +1253,6 @@ int regulator_force_disable(struct regulator *regulator)
int ret;
mutex_lock(&regulator->rdev->mutex);
- regulator->enabled = 0;
regulator->uA_load = 0;
ret = _regulator_force_disable(regulator->rdev);
mutex_unlock(&regulator->rdev->mutex);
@@ -1204,6 +1297,56 @@ int regulator_is_enabled(struct regulator *regulator)
EXPORT_SYMBOL_GPL(regulator_is_enabled);
/**
+ * regulator_count_voltages - count regulator_list_voltage() selectors
+ * @regulator: regulator source
+ *
+ * Returns number of selectors, or negative errno. Selectors are
+ * numbered starting at zero, and typically correspond to bitfields
+ * in hardware registers.
+ */
+int regulator_count_voltages(struct regulator *regulator)
+{
+ struct regulator_dev *rdev = regulator->rdev;
+
+ return rdev->desc->n_voltages ? : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(regulator_count_voltages);
+
+/**
+ * regulator_list_voltage - enumerate supported voltages
+ * @regulator: regulator source
+ * @selector: identify voltage to list
+ * Context: can sleep
+ *
+ * Returns a voltage that can be passed to @regulator_set_voltage(),
+ * zero if this selector code can't be used on this sytem, or a
+ * negative errno.
+ */
+int regulator_list_voltage(struct regulator *regulator, unsigned selector)
+{
+ struct regulator_dev *rdev = regulator->rdev;
+ struct regulator_ops *ops = rdev->desc->ops;
+ int ret;
+
+ if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
+ return -EINVAL;
+
+ mutex_lock(&rdev->mutex);
+ ret = ops->list_voltage(rdev, selector);
+ mutex_unlock(&rdev->mutex);
+
+ if (ret > 0) {
+ if (ret < rdev->constraints->min_uV)
+ ret = 0;
+ else if (ret > rdev->constraints->max_uV)
+ ret = 0;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_list_voltage);
+
+/**
* regulator_set_voltage - set regulator output voltage
* @regulator: regulator source
* @min_uV: Minimum required voltage in uV
@@ -1243,6 +1386,7 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV);
out:
+ _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, NULL);
mutex_unlock(&rdev->mutex);
return ret;
}
@@ -1543,20 +1687,23 @@ int regulator_unregister_notifier(struct regulator *regulator,
}
EXPORT_SYMBOL_GPL(regulator_unregister_notifier);
-/* notify regulator consumers and downstream regulator consumers */
+/* notify regulator consumers and downstream regulator consumers.
+ * Note mutex must be held by caller.
+ */
static void _notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data)
{
struct regulator_dev *_rdev;
/* call rdev chain first */
- mutex_lock(&rdev->mutex);
blocking_notifier_call_chain(&rdev->notifier, event, NULL);
- mutex_unlock(&rdev->mutex);
/* now notify regulator we supply */
- list_for_each_entry(_rdev, &rdev->supply_list, slist)
- _notifier_call_chain(_rdev, event, data);
+ list_for_each_entry(_rdev, &rdev->supply_list, slist) {
+ mutex_lock(&_rdev->mutex);
+ _notifier_call_chain(_rdev, event, data);
+ mutex_unlock(&_rdev->mutex);
+ }
}
/**
@@ -1703,6 +1850,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free);
*
* Called by regulator drivers to notify clients a regulator event has
* occurred. We also notify regulator clients downstream.
+ * Note lock must be held by caller.
*/
int regulator_notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data)
@@ -1744,6 +1892,11 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
if (status < 0)
return status;
}
+ if (ops->get_status) {
+ status = device_create_file(dev, &dev_attr_status);
+ if (status < 0)
+ return status;
+ }
/* some attributes are type-specific */
if (rdev->desc->type == REGULATOR_CURRENT) {
@@ -1828,17 +1981,18 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
* regulator_register - register regulator
* @regulator_desc: regulator to register
* @dev: struct device for the regulator
+ * @init_data: platform provided init data, passed through by driver
* @driver_data: private regulator data
*
* Called by regulator drivers to register a regulator.
* Returns 0 on success.
*/
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
- struct device *dev, void *driver_data)
+ struct device *dev, struct regulator_init_data *init_data,
+ void *driver_data)
{
static atomic_t regulator_no = ATOMIC_INIT(0);
struct regulator_dev *rdev;
- struct regulator_init_data *init_data = dev->platform_data;
int ret, i;
if (regulator_desc == NULL)
@@ -1945,6 +2099,7 @@ void regulator_unregister(struct regulator_dev *rdev)
return;
mutex_lock(&regulator_list_mutex);
+ unset_regulator_supplies(rdev);
list_del(&rdev->list);
if (rdev->supply)
sysfs_remove_link(&rdev->dev.kobj, "supply");
@@ -1989,6 +2144,23 @@ out:
EXPORT_SYMBOL_GPL(regulator_suspend_prepare);
/**
+ * regulator_has_full_constraints - the system has fully specified constraints
+ *
+ * Calling this function will cause the regulator API to disable all
+ * regulators which have a zero use count and don't have an always_on
+ * constraint in a late_initcall.
+ *
+ * The intention is that this will become the default behaviour in a
+ * future kernel release so users are encouraged to use this facility
+ * now.
+ */
+void regulator_has_full_constraints(void)
+{
+ has_full_constraints = 1;
+}
+EXPORT_SYMBOL_GPL(regulator_has_full_constraints);
+
+/**
* rdev_get_drvdata - get rdev regulator driver data
* @rdev: regulator
*
@@ -2055,3 +2227,77 @@ static int __init regulator_init(void)
/* init early to allow our consumers to complete system booting */
core_initcall(regulator_init);
+
+static int __init regulator_init_complete(void)
+{
+ struct regulator_dev *rdev;
+ struct regulator_ops *ops;
+ struct regulation_constraints *c;
+ int enabled, ret;
+ const char *name;
+
+ mutex_lock(&regulator_list_mutex);
+
+ /* If we have a full configuration then disable any regulators
+ * which are not in use or always_on. This will become the
+ * default behaviour in the future.
+ */
+ list_for_each_entry(rdev, &regulator_list, list) {
+ ops = rdev->desc->ops;
+ c = rdev->constraints;
+
+ if (c->name)
+ name = c->name;
+ else if (rdev->desc->name)
+ name = rdev->desc->name;
+ else
+ name = "regulator";
+
+ if (!ops->disable || c->always_on)
+ continue;
+
+ mutex_lock(&rdev->mutex);
+
+ if (rdev->use_count)
+ goto unlock;
+
+ /* If we can't read the status assume it's on. */
+ if (ops->is_enabled)
+ enabled = ops->is_enabled(rdev);
+ else
+ enabled = 1;
+
+ if (!enabled)
+ goto unlock;
+
+ if (has_full_constraints) {
+ /* We log since this may kill the system if it
+ * goes wrong. */
+ printk(KERN_INFO "%s: disabling %s\n",
+ __func__, name);
+ ret = ops->disable(rdev);
+ if (ret != 0) {
+ printk(KERN_ERR
+ "%s: couldn't disable %s: %d\n",
+ __func__, name, ret);
+ }
+ } else {
+ /* The intention is that in future we will
+ * assume that full constraints are provided
+ * so warn even if we aren't going to do
+ * anything here.
+ */
+ printk(KERN_WARNING
+ "%s: incomplete constraints, leaving %s on\n",
+ __func__, name);
+ }
+
+unlock:
+ mutex_unlock(&rdev->mutex);
+ }
+
+ mutex_unlock(&regulator_list_mutex);
+
+ return 0;
+}
+late_initcall(regulator_init_complete);
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c
index fe77730a7ed..72b15495183 100644
--- a/drivers/regulator/da903x.c
+++ b/drivers/regulator/da903x.c
@@ -471,7 +471,8 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)
if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
ri->desc.ops = &da9030_regulator_ldo1_15_ops;
- rdev = regulator_register(&ri->desc, &pdev->dev, ri);
+ rdev = regulator_register(&ri->desc, &pdev->dev,
+ pdev->dev.platform_data, ri);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name);
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index d31db3e1491..23d554628a7 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -73,7 +73,8 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
drvdata->microvolts = config->microvolts;
- drvdata->dev = regulator_register(&drvdata->desc, drvdata);
+ drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
+ config->init_data, drvdata);
if (IS_ERR(drvdata->dev)) {
ret = PTR_ERR(drvdata->dev);
goto err_name;
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
index 4cc85ec6e12..cd761d85c8f 100644
--- a/drivers/regulator/pcf50633-regulator.c
+++ b/drivers/regulator/pcf50633-regulator.c
@@ -284,7 +284,8 @@ static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
/* Already set by core driver */
pcf = platform_get_drvdata(pdev);
- rdev = regulator_register(&regulators[pdev->id], &pdev->dev, pcf);
+ rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
+ pdev->dev.platform_data, pcf);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
diff --git a/drivers/regulator/twl4030-regulator.c b/drivers/regulator/twl4030-regulator.c
new file mode 100644
index 00000000000..e2032fb60b5
--- /dev/null
+++ b/drivers/regulator/twl4030-regulator.c
@@ -0,0 +1,500 @@
+/*
+ * twl4030-regulator.c -- support regulators in twl4030 family chips
+ *
+ * Copyright (C) 2008 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl4030.h>
+
+
+/*
+ * The TWL4030/TW5030/TPS659x0 family chips include power management, a
+ * USB OTG transceiver, an RTC, ADC, PWM, and lots more. Some versions
+ * include an audio codec, battery charger, and more voltage regulators.
+ * These chips are often used in OMAP-based systems.
+ *
+ * This driver implements software-based resource control for various
+ * voltage regulators. This is usually augmented with state machine
+ * based control.
+ */
+
+struct twlreg_info {
+ /* start of regulator's PM_RECEIVER control register bank */
+ u8 base;
+
+ /* twl4030 resource ID, for resource control state machine */
+ u8 id;
+
+ /* voltage in mV = table[VSEL]; table_len must be a power-of-two */
+ u8 table_len;
+ const u16 *table;
+
+ /* chip constraints on regulator behavior */
+ u16 min_mV;
+
+ /* used by regulator core */
+ struct regulator_desc desc;
+};
+
+
+/* LDO control registers ... offset is from the base of its register bank.
+ * The first three registers of all power resource banks help hardware to
+ * manage the various resource groups.
+ */
+#define VREG_GRP 0
+#define VREG_TYPE 1
+#define VREG_REMAP 2
+#define VREG_DEDICATED 3 /* LDO control */
+
+
+static inline int
+twl4030reg_read(struct twlreg_info *info, unsigned offset)
+{
+ u8 value;
+ int status;
+
+ status = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER,
+ &value, info->base + offset);
+ return (status < 0) ? status : value;
+}
+
+static inline int
+twl4030reg_write(struct twlreg_info *info, unsigned offset, u8 value)
+{
+ return twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+ value, info->base + offset);
+}
+
+/*----------------------------------------------------------------------*/
+
+/* generic power resource operations, which work on all regulators */
+
+static int twl4030reg_grp(struct regulator_dev *rdev)
+{
+ return twl4030reg_read(rdev_get_drvdata(rdev), VREG_GRP);
+}
+
+/*
+ * Enable/disable regulators by joining/leaving the P1 (processor) group.
+ * We assume nobody else is updating the DEV_GRP registers.
+ */
+
+#define P3_GRP BIT(7) /* "peripherals" */
+#define P2_GRP BIT(6) /* secondary processor, modem, etc */
+#define P1_GRP BIT(5) /* CPU/Linux */
+
+static int twl4030reg_is_enabled(struct regulator_dev *rdev)
+{
+ int state = twl4030reg_grp(rdev);
+
+ if (state < 0)
+ return state;
+
+ return (state & P1_GRP) != 0;
+}
+
+static int twl4030reg_enable(struct regulator_dev *rdev)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int grp;
+
+ grp = twl4030reg_read(info, VREG_GRP);
+ if (grp < 0)
+ return grp;
+
+ grp |= P1_GRP;
+ return twl4030reg_write(info, VREG_GRP, grp);
+}
+
+static int twl4030reg_disable(struct regulator_dev *rdev)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int grp;
+
+ grp = twl4030reg_read(info, VREG_GRP);
+ if (grp < 0)
+ return grp;
+
+ grp &= ~P1_GRP;
+ return twl4030reg_write(info, VREG_GRP, grp);
+}
+
+static int twl4030reg_get_status(struct regulator_dev *rdev)
+{
+ int state = twl4030reg_grp(rdev);
+
+ if (state < 0)
+ return state;
+ state &= 0x0f;
+
+ /* assume state != WARM_RESET; we'd not be running... */
+ if (!state)
+ return REGULATOR_STATUS_OFF;
+ return (state & BIT(3))
+ ? REGULATOR_STATUS_NORMAL
+ : REGULATOR_STATUS_STANDBY;
+}
+
+static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ unsigned message;
+ int status;
+
+ /* We can only set the mode through state machine commands... */
+ switch (mode) {
+ case REGULATOR_MODE_NORMAL:
+ message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_ACTIVE);
+ break;
+ case REGULATOR_MODE_STANDBY:
+ message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_SLEEP);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Ensure the resource is associated with some group */
+ status = twl4030reg_grp(rdev);
+ if (status < 0)
+ return status;
+ if (!(status & (P3_GRP | P2_GRP | P1_GRP)))
+ return -EACCES;
+
+ status = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ message >> 8, 0x15 /* PB_WORD_MSB */ );
+ if (status >= 0)
+ return status;
+
+ return twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ message, 0x16 /* PB_WORD_LSB */ );
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Support for adjustable-voltage LDOs uses a four bit (or less) voltage
+ * select field in its control register. We use tables indexed by VSEL
+ * to record voltages in milliVolts. (Accuracy is about three percent.)
+ *
+ * Note that VSEL values for VAUX2 changed in twl5030 and newer silicon;
+ * currently handled by listing two slightly different VAUX2 regulators,
+ * only one of which will be configured.
+ *
+ * VSEL values documented as "TI cannot support these values" are flagged
+ * in these tables as UNSUP() values; we normally won't assign them.
+ *
+ * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported.
+ * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting.
+ */
+#ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED
+#define UNSUP_MASK 0x0000
+#else
+#define UNSUP_MASK 0x8000
+#endif
+
+#define UNSUP(x) (UNSUP_MASK | (x))
+#define IS_UNSUP(x) (UNSUP_MASK & (x))
+#define LDO_MV(x) (~UNSUP_MASK & (x))
+
+
+static const u16 VAUX1_VSEL_table[] = {
+ UNSUP(1500), UNSUP(1800), 2500, 2800,
+ 3000, 3000, 3000, 3000,
+};
+static const u16 VAUX2_4030_VSEL_table[] = {
+ UNSUP(1000), UNSUP(1000), UNSUP(1200), 1300,
+ 1500, 1800, UNSUP(1850), 2500,
+ UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
+ UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VAUX2_VSEL_table[] = {
+ 1700, 1700, 1900, 1300,
+ 1500, 1800, 2000, 2500,
+ 2100, 2800, 2200, 2300,
+ 2400, 2400, 2400, 2400,
+};
+static const u16 VAUX3_VSEL_table[] = {
+ 1500, 1800, 2500, 2800,
+ 3000, 3000, 3000, 3000,
+};
+static const u16 VAUX4_VSEL_table[] = {
+ 700, 1000, 1200, UNSUP(1300),
+ 1500, 1800, UNSUP(1850), 2500,
+ UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
+ UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VMMC1_VSEL_table[] = {
+ 1850, 2850, 3000, 3150,
+};
+static const u16 VMMC2_VSEL_table[] = {
+ UNSUP(1000), UNSUP(1000), UNSUP(1200), UNSUP(1300),
+ UNSUP(1500), UNSUP(1800), 1850, UNSUP(2500),
+ 2600, 2800, 2850, 3000,
+ 3150, 3150, 3150, 3150,
+};
+static const u16 VPLL1_VSEL_table[] = {
+ 1000, 1200, 1300, 1800,
+ UNSUP(2800), UNSUP(3000), UNSUP(3000), UNSUP(3000),
+};
+static const u16 VPLL2_VSEL_table[] = {
+ 700, 1000, 1200, 1300,
+ UNSUP(1500), 1800, UNSUP(1850), UNSUP(2500),
+ UNSUP(2600), UNSUP(2800), UNSUP(2850), UNSUP(3000),
+ UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VSIM_VSEL_table[] = {
+ UNSUP(1000), UNSUP(1200), UNSUP(1300), 1800,
+ 2800, 3000, 3000, 3000,
+};
+static const u16 VDAC_VSEL_table[] = {
+ 1200, 1300, 1800, 1800,
+};
+
+
+static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int mV = info->table[index];
+
+ return IS_UNSUP(mV) ? 0 : (LDO_MV(mV) * 1000);
+}
+
+static int
+twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int vsel;
+
+ for (vsel = 0; vsel < info->table_len; vsel++) {
+ int mV = info->table[vsel];
+ int uV;
+
+ if (IS_UNSUP(mV))
+ continue;
+ uV = LDO_MV(mV) * 1000;
+
+ /* REVISIT for VAUX2, first match may not be best/lowest */
+
+ /* use the first in-range value */
+ if (min_uV <= uV && uV <= max_uV)
+ return twl4030reg_write(info, VREG_DEDICATED, vsel);
+ }
+
+ return -EDOM;
+}
+
+static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int vsel = twl4030reg_read(info, VREG_DEDICATED);
+
+ if (vsel < 0)
+ return vsel;
+
+ vsel &= info->table_len - 1;
+ return LDO_MV(info->table[vsel]) * 1000;
+}
+
+static struct regulator_ops twl4030ldo_ops = {
+ .list_voltage = twl4030ldo_list_voltage,
+
+ .set_voltage = twl4030ldo_set_voltage,
+ .get_voltage = twl4030ldo_get_voltage,
+
+ .enable = twl4030reg_enable,
+ .disable = twl4030reg_disable,
+ .is_enabled = twl4030reg_is_enabled,
+
+ .set_mode = twl4030reg_set_mode,
+
+ .get_status = twl4030reg_get_status,
+};
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Fixed voltage LDOs don't have a VSEL field to update.
+ */
+static int twl4030fixed_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+
+ return info->min_mV * 1000;
+}
+
+static int twl4030fixed_get_voltage(struct regulator_dev *rdev)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+
+ return info->min_mV * 1000;
+}
+
+static struct regulator_ops twl4030fixed_ops = {
+ .list_voltage = twl4030fixed_list_voltage,
+
+ .get_voltage = twl4030fixed_get_voltage,
+
+ .enable = twl4030reg_enable,
+ .disable = twl4030reg_disable,
+ .is_enabled = twl4030reg_is_enabled,
+
+ .set_mode = twl4030reg_set_mode,
+
+ .get_status = twl4030reg_get_status,
+};
+
+/*----------------------------------------------------------------------*/
+
+#define TWL_ADJUSTABLE_LDO(label, offset, num) { \
+ .base = offset, \
+ .id = num, \
+ .table_len = ARRAY_SIZE(label##_VSEL_table), \
+ .table = label##_VSEL_table, \
+ .desc = { \
+ .name = #label, \
+ .id = TWL4030_REG_##label, \
+ .n_voltages = ARRAY_SIZE(label##_VSEL_table), \
+ .ops = &twl4030ldo_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ }, \
+ }
+
+#define TWL_FIXED_LDO(label, offset, mVolts, num) { \
+ .base = offset, \
+ .id = num, \
+ .min_mV = mVolts, \
+ .desc = { \
+ .name = #label, \
+ .id = TWL4030_REG_##label, \
+ .n_voltages = 1, \
+ .ops = &twl4030fixed_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ }, \
+ }
+
+/*
+ * We list regulators here if systems need some level of
+ * software control over them after boot.
+ */
+static struct twlreg_info twl4030_regs[] = {
+ TWL_ADJUSTABLE_LDO(VAUX1, 0x17, 1),
+ TWL_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2),
+ TWL_ADJUSTABLE_LDO(VAUX2, 0x1b, 2),
+ TWL_ADJUSTABLE_LDO(VAUX3, 0x1f, 3),
+ TWL_ADJUSTABLE_LDO(VAUX4, 0x23, 4),
+ TWL_ADJUSTABLE_LDO(VMMC1, 0x27, 5),
+ TWL_ADJUSTABLE_LDO(VMMC2, 0x2b, 6),
+ /*
+ TWL_ADJUSTABLE_LDO(VPLL1, 0x2f, 7),
+ */
+ TWL_ADJUSTABLE_LDO(VPLL2, 0x33, 8),
+ TWL_ADJUSTABLE_LDO(VSIM, 0x37, 9),
+ TWL_ADJUSTABLE_LDO(VDAC, 0x3b, 10),
+ /*
+ TWL_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11),
+ TWL_ADJUSTABLE_LDO(VINTANA2, 0x43, 12),
+ TWL_ADJUSTABLE_LDO(VINTDIG, 0x47, 13),
+ TWL_SMPS(VIO, 0x4b, 14),
+ TWL_SMPS(VDD1, 0x55, 15),
+ TWL_SMPS(VDD2, 0x63, 16),
+ */
+ TWL_FIXED_LDO(VUSB1V5, 0x71, 1500, 17),
+ TWL_FIXED_LDO(VUSB1V8, 0x74, 1800, 18),
+ TWL_FIXED_LDO(VUSB3V1, 0x77, 3100, 19),
+ /* VUSBCP is managed *only* by the USB subchip */
+};
+
+static int twl4030reg_probe(struct platform_device *pdev)
+{
+ int i;
+ struct twlreg_info *info;
+ struct regulator_init_data *initdata;
+ struct regulation_constraints *c;
+ struct regulator_dev *rdev;
+
+ for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) {
+ if (twl4030_regs[i].desc.id != pdev->id)
+ continue;
+ info = twl4030_regs + i;
+ break;
+ }
+ if (!info)
+ return -ENODEV;
+
+ initdata = pdev->dev.platform_data;
+ if (!initdata)
+ return -EINVAL;
+
+ /* Constrain board-specific capabilities according to what
+ * this driver and the chip itself can actually do.
+ */
+ c = &initdata->constraints;
+ c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
+ c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS;
+
+ rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "can't register %s, %ld\n",
+ info->desc.name, PTR_ERR(rdev));
+ return PTR_ERR(rdev);
+ }
+ platform_set_drvdata(pdev, rdev);
+
+ /* NOTE: many regulators support short-circuit IRQs (presentable
+ * as REGULATOR_OVER_CURRENT notifications?) configured via:
+ * - SC_CONFIG
+ * - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
+ * - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
+ * - IT_CONFIG
+ */
+
+ return 0;
+}
+
+static int __devexit twl4030reg_remove(struct platform_device *pdev)
+{
+ regulator_unregister(platform_get_drvdata(pdev));
+ return 0;
+}
+
+MODULE_ALIAS("platform:twl4030_reg");
+
+static struct platform_driver twl4030reg_driver = {
+ .probe = twl4030reg_probe,
+ .remove = __devexit_p(twl4030reg_remove),
+ /* NOTE: short name, to work around driver model truncation of
+ * "twl4030_regulator.12" (and friends) to "twl4030_regulator.1".
+ */
+ .driver.name = "twl4030_reg",
+ .driver.owner = THIS_MODULE,
+};
+
+static int __init twl4030reg_init(void)
+{
+ return platform_driver_register(&twl4030reg_driver);
+}
+subsys_initcall(twl4030reg_init);
+
+static void __exit twl4030reg_exit(void)
+{
+ platform_driver_unregister(&twl4030reg_driver);
+}
+module_exit(twl4030reg_exit)
+
+MODULE_DESCRIPTION("TWL4030 regulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c
index 5ddb464b1c3..3d08348584e 100644
--- a/drivers/regulator/virtual.c
+++ b/drivers/regulator/virtual.c
@@ -226,13 +226,17 @@ static ssize_t set_mode(struct device *dev, struct device_attribute *attr,
unsigned int mode;
int ret;
- if (strncmp(buf, "fast", strlen("fast")) == 0)
+ /*
+ * sysfs_streq() doesn't need the \n's, but we add them so the strings
+ * will be shared with show_mode(), above.
+ */
+ if (sysfs_streq(buf, "fast\n") == 0)
mode = REGULATOR_MODE_FAST;
- else if (strncmp(buf, "normal", strlen("normal")) == 0)
+ else if (sysfs_streq(buf, "normal\n") == 0)
mode = REGULATOR_MODE_NORMAL;
- else if (strncmp(buf, "idle", strlen("idle")) == 0)
+ else if (sysfs_streq(buf, "idle\n") == 0)
mode = REGULATOR_MODE_IDLE;
- else if (strncmp(buf, "standby", strlen("standby")) == 0)
+ else if (sysfs_streq(buf, "standby\n") == 0)
mode = REGULATOR_MODE_STANDBY;
else {
dev_err(dev, "Configuring invalid mode\n");
@@ -256,7 +260,7 @@ static DEVICE_ATTR(min_microamps, 0666, show_min_uA, set_min_uA);
static DEVICE_ATTR(max_microamps, 0666, show_max_uA, set_max_uA);
static DEVICE_ATTR(mode, 0666, show_mode, set_mode);
-struct device_attribute *attributes[] = {
+static struct device_attribute *attributes[] = {
&dev_attr_min_microvolts,
&dev_attr_max_microvolts,
&dev_attr_min_microamps,
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 5056e23e441..771eca1066b 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -24,6 +24,9 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
+/* Maximum value possible for VSEL */
+#define WM8350_DCDC_MAX_VSEL 0x66
+
/* Microamps */
static const int isink_cur[] = {
4,
@@ -385,6 +388,14 @@ static int wm8350_dcdc_get_voltage(struct regulator_dev *rdev)
return wm8350_dcdc_val_to_mvolts(val) * 1000;
}
+static int wm8350_dcdc_list_voltage(struct regulator_dev *rdev,
+ unsigned selector)
+{
+ if (selector > WM8350_DCDC_MAX_VSEL)
+ return -EINVAL;
+ return wm8350_dcdc_val_to_mvolts(selector) * 1000;
+}
+
static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV)
{
struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
@@ -775,6 +786,14 @@ static int wm8350_ldo_get_voltage(struct regulator_dev *rdev)
return wm8350_ldo_val_to_mvolts(val) * 1000;
}
+static int wm8350_ldo_list_voltage(struct regulator_dev *rdev,
+ unsigned selector)
+{
+ if (selector > WM8350_LDO1_VSEL_MASK)
+ return -EINVAL;
+ return wm8350_ldo_val_to_mvolts(selector) * 1000;
+}
+
int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start,
u16 stop, u16 fault)
{
@@ -1031,18 +1050,30 @@ static unsigned int wm8350_dcdc_get_mode(struct regulator_dev *rdev)
int dcdc = rdev_get_id(rdev);
u16 mask, sleep, active, force;
int mode = REGULATOR_MODE_NORMAL;
+ int reg;
- if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6)
- return -EINVAL;
-
- if (dcdc == WM8350_DCDC_2 || dcdc == WM8350_DCDC_5)
+ switch (dcdc) {
+ case WM8350_DCDC_1:
+ reg = WM8350_DCDC1_FORCE_PWM;
+ break;
+ case WM8350_DCDC_3:
+ reg = WM8350_DCDC3_FORCE_PWM;
+ break;
+ case WM8350_DCDC_4:
+ reg = WM8350_DCDC4_FORCE_PWM;
+ break;
+ case WM8350_DCDC_6:
+ reg = WM8350_DCDC6_FORCE_PWM;
+ break;
+ default:
return -EINVAL;
+ }
mask = 1 << (dcdc - WM8350_DCDC_1);
active = wm8350_reg_read(wm8350, WM8350_DCDC_ACTIVE_OPTIONS) & mask;
+ force = wm8350_reg_read(wm8350, reg) & WM8350_DCDC1_FORCE_PWM_ENA;
sleep = wm8350_reg_read(wm8350, WM8350_DCDC_SLEEP_OPTIONS) & mask;
- force = wm8350_reg_read(wm8350, WM8350_DCDC1_FORCE_PWM)
- & WM8350_DCDC1_FORCE_PWM_ENA;
+
dev_dbg(wm8350->dev, "mask %x active %x sleep %x force %x",
mask, active, sleep, force);
@@ -1150,6 +1181,7 @@ static int wm8350_ldo_is_enabled(struct regulator_dev *rdev)
static struct regulator_ops wm8350_dcdc_ops = {
.set_voltage = wm8350_dcdc_set_voltage,
.get_voltage = wm8350_dcdc_get_voltage,
+ .list_voltage = wm8350_dcdc_list_voltage,
.enable = wm8350_dcdc_enable,
.disable = wm8350_dcdc_disable,
.get_mode = wm8350_dcdc_get_mode,
@@ -1173,6 +1205,7 @@ static struct regulator_ops wm8350_dcdc2_5_ops = {
static struct regulator_ops wm8350_ldo_ops = {
.set_voltage = wm8350_ldo_set_voltage,
.get_voltage = wm8350_ldo_get_voltage,
+ .list_voltage = wm8350_ldo_list_voltage,
.enable = wm8350_ldo_enable,
.disable = wm8350_ldo_disable,
.is_enabled = wm8350_ldo_is_enabled,
@@ -1197,6 +1230,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC1,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE,
},
{
@@ -1213,6 +1247,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC3,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE,
},
{
@@ -1221,6 +1256,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC4,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE,
},
{
@@ -1237,6 +1273,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC6,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE,
},
{
@@ -1245,6 +1282,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO1,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_LDO1_VSEL_MASK + 1,
.owner = THIS_MODULE,
},
{
@@ -1253,6 +1291,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO2,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_LDO2_VSEL_MASK + 1,
.owner = THIS_MODULE,
},
{
@@ -1261,6 +1300,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO3,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_LDO3_VSEL_MASK + 1,
.owner = THIS_MODULE,
},
{
@@ -1269,6 +1309,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO4,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_LDO4_VSEL_MASK + 1,
.owner = THIS_MODULE,
},
{
@@ -1293,6 +1334,7 @@ static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data)
{
struct regulator_dev *rdev = (struct regulator_dev *)data;
+ mutex_lock(&rdev->mutex);
if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_REGULATION_OUT,
@@ -1301,6 +1343,7 @@ static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data)
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_UNDER_VOLTAGE,
wm8350);
+ mutex_unlock(&rdev->mutex);
}
static int wm8350_regulator_probe(struct platform_device *pdev)
@@ -1333,9 +1376,9 @@ static int wm8350_regulator_probe(struct platform_device *pdev)
break;
}
-
/* register regulator */
rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev,
+ pdev->dev.platform_data,
dev_get_drvdata(&pdev->dev));
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register %s\n",
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c
index 56e23d44ba5..15742602907 100644
--- a/drivers/regulator/wm8400-regulator.c
+++ b/drivers/regulator/wm8400-regulator.c
@@ -43,6 +43,18 @@ static int wm8400_ldo_disable(struct regulator_dev *dev)
WM8400_LDO1_ENA, 0);
}
+static int wm8400_ldo_list_voltage(struct regulator_dev *dev,
+ unsigned selector)
+{
+ if (selector > WM8400_LDO1_VSEL_MASK)
+ return -EINVAL;
+
+ if (selector < 15)
+ return 900000 + (selector * 50000);
+ else
+ return 1600000 + ((selector - 14) * 100000);
+}
+
static int wm8400_ldo_get_voltage(struct regulator_dev *dev)
{
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
@@ -51,10 +63,7 @@ static int wm8400_ldo_get_voltage(struct regulator_dev *dev)
val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev));
val &= WM8400_LDO1_VSEL_MASK;
- if (val < 15)
- return 900000 + (val * 50000);
- else
- return 1600000 + ((val - 14) * 100000);
+ return wm8400_ldo_list_voltage(dev, val);
}
static int wm8400_ldo_set_voltage(struct regulator_dev *dev,
@@ -92,6 +101,7 @@ static struct regulator_ops wm8400_ldo_ops = {
.is_enabled = wm8400_ldo_is_enabled,
.enable = wm8400_ldo_enable,
.disable = wm8400_ldo_disable,
+ .list_voltage = wm8400_ldo_list_voltage,
.get_voltage = wm8400_ldo_get_voltage,
.set_voltage = wm8400_ldo_set_voltage,
};
@@ -124,6 +134,15 @@ static int wm8400_dcdc_disable(struct regulator_dev *dev)
WM8400_DC1_ENA, 0);
}
+static int wm8400_dcdc_list_voltage(struct regulator_dev *dev,
+ unsigned selector)
+{
+ if (selector > WM8400_DC1_VSEL_MASK)
+ return -EINVAL;
+
+ return 850000 + (selector * 25000);
+}
+
static int wm8400_dcdc_get_voltage(struct regulator_dev *dev)
{
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
@@ -237,6 +256,7 @@ static struct regulator_ops wm8400_dcdc_ops = {
.is_enabled = wm8400_dcdc_is_enabled,
.enable = wm8400_dcdc_enable,
.disable = wm8400_dcdc_disable,
+ .list_voltage = wm8400_dcdc_list_voltage,
.get_voltage = wm8400_dcdc_get_voltage,
.set_voltage = wm8400_dcdc_set_voltage,
.get_mode = wm8400_dcdc_get_mode,
@@ -249,6 +269,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO1",
.id = WM8400_LDO1,
.ops = &wm8400_ldo_ops,
+ .n_voltages = WM8400_LDO1_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -256,6 +277,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO2",
.id = WM8400_LDO2,
.ops = &wm8400_ldo_ops,
+ .n_voltages = WM8400_LDO2_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -263,6 +285,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO3",
.id = WM8400_LDO3,
.ops = &wm8400_ldo_ops,
+ .n_voltages = WM8400_LDO3_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -270,6 +293,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO4",
.id = WM8400_LDO4,
.ops = &wm8400_ldo_ops,
+ .n_voltages = WM8400_LDO4_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -277,6 +301,7 @@ static struct regulator_desc regulators[] = {
.name = "DCDC1",
.id = WM8400_DCDC1,
.ops = &wm8400_dcdc_ops,
+ .n_voltages = WM8400_DC1_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -284,6 +309,7 @@ static struct regulator_desc regulators[] = {
.name = "DCDC2",
.id = WM8400_DCDC2,
.ops = &wm8400_dcdc_ops,
+ .n_voltages = WM8400_DC2_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -294,7 +320,7 @@ static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
struct regulator_dev *rdev;
rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
- pdev->dev.driver_data);
+ pdev->dev.platform_data, pdev->dev.driver_data);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 56002f7d26b..ffe34a12f44 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -688,22 +688,16 @@ 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
+config RTC_DRV_GENERIC
+ tristate "Generic RTC support"
+ # Please consider writing a new RTC driver instead of using the generic
+ # RTC abstraction
+ depends on PARISC || M68K || PPC
+ help
+ Say Y or M here to enable RTC support on systems using the generic
+ RTC abstraction. 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
- help
- The PowerPC kernel has machine-specific functions for accessing
- the RTC. This exposes that functionality through the generic RTC
- class.
-
config RTC_DRV_PXA
tristate "PXA27x/PXA3xx"
depends on ARCH_PXA
@@ -747,4 +741,13 @@ config RTC_DRV_MV
This driver can also be built as a module. If so, the module
will be called rtc-mv.
+config RTC_DRV_PS3
+ tristate "PS3 RTC"
+ depends on PPC_PS3
+ help
+ If you say yes here you will get support for the RTC on PS3.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ps3.
+
endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index e7b09986d26..6c0639a14f0 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -56,8 +56,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_GENERIC) += rtc-generic.o
obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o
obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
@@ -77,3 +76,4 @@ obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
+obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o
diff --git a/drivers/rtc/rtc-generic.c b/drivers/rtc/rtc-generic.c
new file mode 100644
index 00000000000..98322004ad2
--- /dev/null
+++ b/drivers/rtc/rtc-generic.c
@@ -0,0 +1,84 @@
+/* rtc-generic: RTC driver using the generic RTC abstraction
+ *
+ * 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 <linux/rtc.h>
+
+#include <asm/rtc.h>
+
+static int generic_get_time(struct device *dev, struct rtc_time *tm)
+{
+ unsigned int ret = get_rtc_time(tm);
+
+ if (ret & RTC_BATT_BAD)
+ return -EOPNOTSUPP;
+
+ return rtc_valid_tm(tm);
+}
+
+static int generic_set_time(struct device *dev, struct rtc_time *tm)
+{
+ if (set_rtc_time(tm) < 0)
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+
+static const struct rtc_class_ops generic_rtc_ops = {
+ .read_time = generic_get_time,
+ .set_time = generic_set_time,
+};
+
+static int __init generic_rtc_probe(struct platform_device *dev)
+{
+ struct rtc_device *rtc;
+
+ rtc = rtc_device_register("rtc-generic", &dev->dev, &generic_rtc_ops,
+ THIS_MODULE);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
+
+ platform_set_drvdata(dev, rtc);
+
+ return 0;
+}
+
+static int __exit generic_rtc_remove(struct platform_device *dev)
+{
+ struct rtc_device *rtc = platform_get_drvdata(dev);
+
+ rtc_device_unregister(rtc);
+
+ return 0;
+}
+
+static struct platform_driver generic_rtc_driver = {
+ .driver = {
+ .name = "rtc-generic",
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(generic_rtc_remove),
+};
+
+static int __init generic_rtc_init(void)
+{
+ return platform_driver_probe(&generic_rtc_driver, generic_rtc_probe);
+}
+
+static void __exit generic_rtc_fini(void)
+{
+ platform_driver_unregister(&generic_rtc_driver);
+}
+
+module_init(generic_rtc_init);
+module_exit(generic_rtc_fini);
+
+MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic RTC driver");
+MODULE_ALIAS("platform:rtc-generic");
diff --git a/drivers/rtc/rtc-parisc.c b/drivers/rtc/rtc-parisc.c
deleted file mode 100644
index b966f56da97..00000000000
--- a/drivers/rtc/rtc-parisc.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* 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 <linux/rtc.h>
-
-#include <asm/rtc.h>
-
-static int parisc_get_time(struct device *dev, struct rtc_time *tm)
-{
- unsigned long ret;
-
- ret = get_rtc_time(tm);
-
- if (ret & RTC_BATT_BAD)
- return -EOPNOTSUPP;
-
- return rtc_valid_tm(tm);
-}
-
-static int parisc_set_time(struct device *dev, struct rtc_time *tm)
-{
- if (set_rtc_time(tm) < 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 __init parisc_rtc_probe(struct platform_device *dev)
-{
- struct rtc_device *rtc;
-
- rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops,
- THIS_MODULE);
- if (IS_ERR(rtc))
- return PTR_ERR(rtc);
-
- platform_set_drvdata(dev, rtc);
-
- return 0;
-}
-
-static int __exit parisc_rtc_remove(struct platform_device *dev)
-{
- struct rtc_device *rtc = platform_get_drvdata(dev);
-
- rtc_device_unregister(rtc);
-
- 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_probe(&parisc_rtc_driver, parisc_rtc_probe);
-}
-
-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-ppc.c b/drivers/rtc/rtc-ppc.c
deleted file mode 100644
index c8e97e25ef7..00000000000
--- a/drivers/rtc/rtc-ppc.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * RTC driver for ppc_md RTC functions
- *
- * © 2007 Red Hat, Inc.
- *
- * Author: David Woodhouse <dwmw2@infradead.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.
- */
-
-
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/rtc.h>
-#include <linux/platform_device.h>
-#include <asm/machdep.h>
-
-static int ppc_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- ppc_md.get_rtc_time(tm);
- return 0;
-}
-
-static int ppc_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- return ppc_md.set_rtc_time(tm);
-}
-
-static const struct rtc_class_ops ppc_rtc_ops = {
- .set_time = ppc_rtc_set_time,
- .read_time = ppc_rtc_read_time,
-};
-
-static struct rtc_device *rtc;
-static struct platform_device *ppc_rtc_pdev;
-
-static int __init ppc_rtc_init(void)
-{
- if (!ppc_md.get_rtc_time || !ppc_md.set_rtc_time)
- return -ENODEV;
-
- ppc_rtc_pdev = platform_device_register_simple("ppc-rtc", 0, NULL, 0);
- if (IS_ERR(ppc_rtc_pdev))
- return PTR_ERR(ppc_rtc_pdev);
-
- rtc = rtc_device_register("ppc_md", &ppc_rtc_pdev->dev,
- &ppc_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc)) {
- platform_device_unregister(ppc_rtc_pdev);
- return PTR_ERR(rtc);
- }
-
- return 0;
-}
-
-static void __exit ppc_rtc_exit(void)
-{
- rtc_device_unregister(rtc);
- platform_device_unregister(ppc_rtc_pdev);
-}
-
-module_init(ppc_rtc_init);
-module_exit(ppc_rtc_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("Generic RTC class driver for PowerPC");
diff --git a/drivers/rtc/rtc-ps3.c b/drivers/rtc/rtc-ps3.c
new file mode 100644
index 00000000000..968133ce1ee
--- /dev/null
+++ b/drivers/rtc/rtc-ps3.c
@@ -0,0 +1,104 @@
+/*
+ * PS3 RTC Driver
+ *
+ * Copyright 2009 Sony Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#include <asm/lv1call.h>
+#include <asm/ps3.h>
+
+
+static u64 read_rtc(void)
+{
+ int result;
+ u64 rtc_val;
+ u64 tb_val;
+
+ result = lv1_get_rtc(&rtc_val, &tb_val);
+ BUG_ON(result);
+
+ return rtc_val;
+}
+
+static int ps3_get_time(struct device *dev, struct rtc_time *tm)
+{
+ rtc_time_to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm);
+ return rtc_valid_tm(tm);
+}
+
+static int ps3_set_time(struct device *dev, struct rtc_time *tm)
+{
+ unsigned long now;
+
+ rtc_tm_to_time(tm, &now);
+ ps3_os_area_set_rtc_diff(now - read_rtc());
+ return 0;
+}
+
+static const struct rtc_class_ops ps3_rtc_ops = {
+ .read_time = ps3_get_time,
+ .set_time = ps3_set_time,
+};
+
+static int __init ps3_rtc_probe(struct platform_device *dev)
+{
+ struct rtc_device *rtc;
+
+ rtc = rtc_device_register("rtc-ps3", &dev->dev, &ps3_rtc_ops,
+ THIS_MODULE);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
+
+ platform_set_drvdata(dev, rtc);
+ return 0;
+}
+
+static int __exit ps3_rtc_remove(struct platform_device *dev)
+{
+ rtc_device_unregister(platform_get_drvdata(dev));
+ return 0;
+}
+
+static struct platform_driver ps3_rtc_driver = {
+ .driver = {
+ .name = "rtc-ps3",
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(ps3_rtc_remove),
+};
+
+static int __init ps3_rtc_init(void)
+{
+ return platform_driver_probe(&ps3_rtc_driver, ps3_rtc_probe);
+}
+
+static void __exit ps3_rtc_fini(void)
+{
+ platform_driver_unregister(&ps3_rtc_driver);
+}
+
+module_init(ps3_rtc_init);
+module_exit(ps3_rtc_fini);
+
+MODULE_AUTHOR("Sony Corporation");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ps3 RTC driver");
+MODULE_ALIAS("platform:rtc-ps3");
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 4898f7fe851..9b1ff12bf94 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -795,10 +795,46 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
return 0;
}
+
+static void sh_rtc_set_irq_wake(struct device *dev, int enabled)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct sh_rtc *rtc = platform_get_drvdata(pdev);
+
+ set_irq_wake(rtc->periodic_irq, enabled);
+ if (rtc->carry_irq > 0) {
+ set_irq_wake(rtc->carry_irq, enabled);
+ set_irq_wake(rtc->alarm_irq, enabled);
+ }
+
+}
+
+static int sh_rtc_suspend(struct device *dev)
+{
+ if (device_may_wakeup(dev))
+ sh_rtc_set_irq_wake(dev, 1);
+
+ return 0;
+}
+
+static int sh_rtc_resume(struct device *dev)
+{
+ if (device_may_wakeup(dev))
+ sh_rtc_set_irq_wake(dev, 0);
+
+ return 0;
+}
+
+static struct dev_pm_ops sh_rtc_dev_pm_ops = {
+ .suspend = sh_rtc_suspend,
+ .resume = sh_rtc_resume,
+};
+
static struct platform_driver sh_rtc_platform_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+ .pm = &sh_rtc_dev_pm_ops,
},
.probe = sh_rtc_probe,
.remove = __devexit_p(sh_rtc_remove),
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index a12783ebb42..8b7983aba8f 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -2016,10 +2016,10 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id
pci_set_master(pdev);
pci_try_set_mwi(pdev);
- if (pci_set_dma_mask(pdev, DMA_64BIT_MASK)
- || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)
- || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+ || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
+ || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
retval = -ENODEV;
goto out_disable_device;
@@ -2234,10 +2234,10 @@ static int twa_resume(struct pci_dev *pdev)
pci_set_master(pdev);
pci_try_set_mwi(pdev);
- if (pci_set_dma_mask(pdev, DMA_64BIT_MASK)
- || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)
- || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+ || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
+ || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
TW_PRINTK(host, TW_DRIVER, 0x40, "Failed to set dma mask during resume");
retval = -ENODEV;
goto out_disable_device;
diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
index 0742e684665..8e71e5e122b 100644
--- a/drivers/scsi/3w-xxxx.h
+++ b/drivers/scsi/3w-xxxx.h
@@ -234,7 +234,7 @@ static unsigned char tw_sense_table[][4] =
#define TW_IOCTL_TIMEOUT 25 /* 25 seconds */
#define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */
#define TW_IOCTL_CHRDEV_FREE -1
-#define TW_DMA_MASK DMA_32BIT_MASK
+#define TW_DMA_MASK DMA_BIT_MASK(32)
#define TW_MAX_CDB_LEN 16
/* Bitmask macros to eliminate bitfields */
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index 2d689af2466..1ddcf4031d4 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -667,7 +667,7 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd
if (pci_enable_device(PCI_Device))
continue;
- if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK ))
+ if (pci_set_dma_mask(PCI_Device, DMA_BIT_MASK(32) ))
continue;
Bus = PCI_Device->bus->number;
@@ -834,7 +834,7 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd
if (pci_enable_device(PCI_Device))
continue;
- if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK))
+ if (pci_set_dma_mask(PCI_Device, DMA_BIT_MASK(32)))
continue;
Bus = PCI_Device->bus->number;
@@ -888,7 +888,7 @@ static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAda
if (pci_enable_device(PCI_Device))
continue;
- if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK))
+ if (pci_set_dma_mask(PCI_Device, DMA_BIT_MASK(32)))
continue;
Bus = PCI_Device->bus->number;
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index e2f44e6c0bc..8ed2990c826 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -121,10 +121,11 @@ config BLK_DEV_SR
tristate "SCSI CDROM support"
depends on SCSI
---help---
- If you want to use a SCSI or FireWire CD-ROM under Linux,
- say Y and read the SCSI-HOWTO and the CDROM-HOWTO at
- <http://www.tldp.org/docs.html#howto>. Also make sure to say
- Y or M to "ISO 9660 CD-ROM file system support" later.
+ If you want to use a CD or DVD drive attached to your computer
+ by SCSI, FireWire, USB or ATAPI, say Y and read the SCSI-HOWTO
+ and the CDROM-HOWTO at <http://www.tldp.org/docs.html#howto>.
+
+ Make sure to say Y or M to "ISO 9660 CD-ROM file system support".
To compile this driver as a module, choose M here and read
<file:Documentation/scsi/scsi.txt>.
@@ -614,10 +615,16 @@ config LIBFC
---help---
Fibre Channel library module
+config LIBFCOE
+ tristate "LibFCoE module"
+ select LIBFC
+ ---help---
+ Library for Fibre Channel over Ethernet module
+
config FCOE
tristate "FCoE module"
depends on PCI
- select LIBFC
+ select LIBFCOE
---help---
Fibre Channel over Ethernet module
@@ -1380,7 +1387,7 @@ config SCSI_LPFC_DEBUG_FS
bool "Emulex LightPulse Fibre Channel debugfs Support"
depends on SCSI_LPFC && DEBUG_FS
help
- This makes debugging infomation from the lpfc driver
+ This makes debugging information from the lpfc driver
available via the debugfs filesystem.
config SCSI_SIM710
@@ -1388,7 +1395,7 @@ config SCSI_SIM710
depends on (EISA || MCA) && SCSI
select SCSI_SPI_ATTRS
---help---
- This driver for NCR53c710 based SCSI host adapters.
+ This driver is for NCR53c710 based SCSI host adapters.
It currently supports Compaq EISA cards and NCR MCA cards
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index cf792963466..e7c861ac417 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_SCSI_SRP_ATTRS) += scsi_transport_srp.o
obj-$(CONFIG_SCSI_DH) += device_handler/
obj-$(CONFIG_LIBFC) += libfc/
+obj-$(CONFIG_LIBFCOE) += fcoe/
obj-$(CONFIG_FCOE) += fcoe/
obj-$(CONFIG_ISCSI_TCP) += libiscsi.o libiscsi_tcp.o iscsi_tcp.o
obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index 964769f66ea..208d6df9ed5 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -1094,7 +1094,7 @@ static int __devinit inia100_probe_one(struct pci_dev *pdev,
if (pci_enable_device(pdev))
goto out;
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "Unable to set 32bit DMA "
"on inia100 adapter, ignoring.\n");
goto out_disable_device;
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index 37dd47136fb..4b38c4750f7 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -23,6 +23,8 @@
#define DMA(ptr) ((a2091_scsiregs *)((ptr)->base))
#define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata))
+static int a2091_release(struct Scsi_Host *instance);
+
static irqreturn_t a2091_intr (int irq, void *_instance)
{
unsigned long flags;
@@ -144,7 +146,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
}
}
-int __init a2091_detect(struct scsi_host_template *tpnt)
+static int __init a2091_detect(struct scsi_host_template *tpnt)
{
static unsigned char called = 0;
struct Scsi_Host *instance;
@@ -233,7 +235,7 @@ static struct scsi_host_template driver_template = {
#include "scsi_module.c"
-int a2091_release(struct Scsi_Host *instance)
+static int a2091_release(struct Scsi_Host *instance)
{
#ifdef MODULE
DMA(instance)->CNTR = 0;
diff --git a/drivers/scsi/a2091.h b/drivers/scsi/a2091.h
index fe809bc88d7..252528f2672 100644
--- a/drivers/scsi/a2091.h
+++ b/drivers/scsi/a2091.h
@@ -11,9 +11,6 @@
#include <linux/types.h>
-int a2091_detect(struct scsi_host_template *);
-int a2091_release(struct Scsi_Host *);
-
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c
index 8b449d8acac..6970ce82c4a 100644
--- a/drivers/scsi/a3000.c
+++ b/drivers/scsi/a3000.c
@@ -25,6 +25,8 @@
static struct Scsi_Host *a3000_host = NULL;
+static int a3000_release(struct Scsi_Host *instance);
+
static irqreturn_t a3000_intr (int irq, void *dummy)
{
unsigned long flags;
@@ -157,7 +159,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
}
}
-int __init a3000_detect(struct scsi_host_template *tpnt)
+static int __init a3000_detect(struct scsi_host_template *tpnt)
{
wd33c93_regs regs;
@@ -232,7 +234,7 @@ static struct scsi_host_template driver_template = {
#include "scsi_module.c"
-int a3000_release(struct Scsi_Host *instance)
+static int a3000_release(struct Scsi_Host *instance)
{
wd33c93_release();
DMA(instance)->CNTR = 0;
diff --git a/drivers/scsi/a3000.h b/drivers/scsi/a3000.h
index 44a4ec7b465..c7afe16fd6e 100644
--- a/drivers/scsi/a3000.h
+++ b/drivers/scsi/a3000.h
@@ -11,9 +11,6 @@
#include <linux/types.h>
-int a3000_detect(struct scsi_host_template *);
-int a3000_release(struct Scsi_Host *);
-
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 90d1d0878cb..2a889853a10 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -143,7 +143,7 @@ static char *aac_get_status_string(u32 status);
*/
static int nondasd = -1;
-static int aac_cache;
+static int aac_cache = 2; /* WCE=0 to avoid performance problems */
static int dacmode = -1;
int aac_msi;
int aac_commit = -1;
@@ -157,7 +157,7 @@ module_param_named(cache, aac_cache, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(cache, "Disable Queue Flush commands:\n"
"\tbit 0 - Disable FUA in WRITE SCSI commands\n"
"\tbit 1 - Disable SYNCHRONIZE_CACHE SCSI command\n"
- "\tbit 2 - Disable only if Battery not protecting Cache");
+ "\tbit 2 - Disable only if Battery is protecting Cache");
module_param(dacmode, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC."
" 0=off, 1=on");
@@ -217,6 +217,14 @@ int aac_reset_devices;
module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization.");
+int aac_wwn = 1;
+module_param_named(wwn, aac_wwn, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(wwn, "Select a WWN type for the arrays:\n"
+ "\t0 - Disable\n"
+ "\t1 - Array Meta Data Signature (default)\n"
+ "\t2 - Adapter Serial Number");
+
+
static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
struct fib *fibptr) {
struct scsi_device *device;
@@ -1206,9 +1214,8 @@ static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
{
- if ((sizeof(dma_addr_t) > 4) &&
- (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
- (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
+ if ((sizeof(dma_addr_t) > 4) && fib->dev->needs_dac &&
+ (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
return FAILED;
return aac_scsi_32(fib, cmd);
}
@@ -1371,8 +1378,11 @@ int aac_get_adapter_info(struct aac_dev* dev)
if (dev->nondasd_support && !dev->in_reset)
printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);
+ if (dma_get_required_mask(&dev->pdev->dev) > DMA_BIT_MASK(32))
+ dev->needs_dac = 1;
dev->dac_support = 0;
- if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
+ if ((sizeof(dma_addr_t) > 4) && dev->needs_dac &&
+ (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)) {
if (!dev->in_reset)
printk(KERN_INFO "%s%d: 64bit support enabled.\n",
dev->name, dev->id);
@@ -1382,14 +1392,23 @@ int aac_get_adapter_info(struct aac_dev* dev)
if(dacmode != -1) {
dev->dac_support = (dacmode!=0);
}
+
+ /* avoid problems with AAC_QUIRK_SCSI_32 controllers */
+ if (dev->dac_support && (aac_get_driver_ident(dev->cardtype)->quirks
+ & AAC_QUIRK_SCSI_32)) {
+ dev->nondasd_support = 0;
+ dev->jbod = 0;
+ expose_physicals = 0;
+ }
+
if(dev->dac_support != 0) {
- if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) &&
- !pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(64)) &&
+ !pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(64))) {
if (!dev->in_reset)
printk(KERN_INFO"%s%d: 64 Bit DAC enabled\n",
dev->name, dev->id);
- } else if (!pci_set_dma_mask(dev->pdev, DMA_32BIT_MASK) &&
- !pci_set_consistent_dma_mask(dev->pdev, DMA_32BIT_MASK)) {
+ } else if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(32)) &&
+ !pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(32))) {
printk(KERN_INFO"%s%d: DMA mask set failed, 64 Bit DAC disabled\n",
dev->name, dev->id);
dev->dac_support = 0;
@@ -2058,7 +2077,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid));
memset(&inq_data, 0, sizeof (struct inquiry_data));
- if (scsicmd->cmnd[1] & 0x1) {
+ if ((scsicmd->cmnd[1] & 0x1) && aac_wwn) {
char *arr = (char *)&inq_data;
/* EVPD bit set */
@@ -2081,7 +2100,12 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
arr[1] = scsicmd->cmnd[2];
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
sizeof(inq_data));
- return aac_get_container_serial(scsicmd);
+ if (aac_wwn != 2)
+ return aac_get_container_serial(
+ scsicmd);
+ /* SLES 10 SP1 special */
+ scsicmd->result = DID_OK << 16 |
+ COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
} else {
/* vpd page not implemented */
scsicmd->result = DID_OK << 16 |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 73916adb8f8..cdbdec9f4fb 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -12,7 +12,7 @@
*----------------------------------------------------------------------------*/
#ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 2456
+# define AAC_DRIVER_BUILD 2461
# define AAC_DRIVER_BRANCH "-ms"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
@@ -865,7 +865,11 @@ struct aac_supplement_adapter_info
u8 MfgPcbaSerialNo[12];
u8 MfgWWNName[8];
__le32 SupportedOptions2;
- __le32 ReservedGrowth[1];
+ __le32 StructExpansion;
+ /* StructExpansion == 1 */
+ __le32 FeatureBits3;
+ __le32 SupportedPerformanceModes;
+ __le32 ReservedForFutureGrowth[80];
};
#define AAC_FEATURE_FALCON cpu_to_le32(0x00000010)
#define AAC_FEATURE_JBOD cpu_to_le32(0x08000000)
@@ -1020,6 +1024,7 @@ struct aac_dev
u8 jbod;
u8 cache_protected;
u8 dac_support;
+ u8 needs_dac;
u8 raid_scsi_mode;
u8 comm_interface;
# define AAC_COMM_PRODUCER 0
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 16310443b55..d598eba630d 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -54,6 +54,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
const unsigned long printfbufsiz = 256;
struct aac_init *init;
dma_addr_t phys;
+ unsigned long aac_max_hostphysmempages;
size = fibsize + sizeof(struct aac_init) + commsize + commalign + printfbufsiz;
@@ -90,7 +91,18 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
init->AdapterFibsSize = cpu_to_le32(fibsize);
init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
- init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
+ /*
+ * number of 4k pages of host physical memory. The aacraid fw needs
+ * this number to be less than 4gb worth of pages. New firmware doesn't
+ * have any issues with the mapping system, but older Firmware did, and
+ * had *troubles* dealing with the math overloading past 32 bits, thus
+ * we must limit this field.
+ */
+ aac_max_hostphysmempages = dma_get_required_mask(&dev->pdev->dev) >> 12;
+ if (aac_max_hostphysmempages < AAC_MAX_HOSTPHYSMEMPAGES)
+ init->HostPhysMemPages = cpu_to_le32(aac_max_hostphysmempages);
+ else
+ init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
init->InitFlags = 0;
if (dev->comm_interface == AAC_COMM_MESSAGE) {
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index d24c2670040..956261f2518 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1206,18 +1206,18 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
aac->fsa_dev = NULL;
quirks = aac_get_driver_ident(index)->quirks;
if (quirks & AAC_QUIRK_31BIT) {
- if (((retval = pci_set_dma_mask(aac->pdev, DMA_31BIT_MASK))) ||
- ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_31BIT_MASK))))
+ if (((retval = pci_set_dma_mask(aac->pdev, DMA_BIT_MASK(31)))) ||
+ ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_BIT_MASK(31)))))
goto out;
} else {
- if (((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK))) ||
- ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_32BIT_MASK))))
+ if (((retval = pci_set_dma_mask(aac->pdev, DMA_BIT_MASK(32)))) ||
+ ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_BIT_MASK(32)))))
goto out;
}
if ((retval = (*(aac_get_driver_ident(index)->init))(aac)))
goto out;
if (quirks & AAC_QUIRK_31BIT)
- if ((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK)))
+ if ((retval = pci_set_dma_mask(aac->pdev, DMA_BIT_MASK(32))))
goto out;
if (jafo) {
aac->thread = kthread_run(aac_command_thread, aac, aac->name);
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 36d8aab97ef..9b97c3e016f 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -86,7 +86,13 @@ char aac_driver_version[] = AAC_DRIVER_FULL_VERSION;
*
* Note: The last field is used to index into aac_drivers below.
*/
-static struct pci_device_id aac_pci_tbl[] = {
+#ifdef DECLARE_PCI_DEVICE_TABLE
+static DECLARE_PCI_DEVICE_TABLE(aac_pci_tbl) = {
+#elif defined(__devinitconst)
+static const struct pci_device_id aac_pci_tbl[] __devinitconst = {
+#else
+static const struct pci_device_id aac_pci_tbl[] __devinitdata = {
+#endif
{ 0x1028, 0x0001, 0x1028, 0x0001, 0, 0, 0 }, /* PERC 2/Si (Iguana/PERC2Si) */
{ 0x1028, 0x0002, 0x1028, 0x0002, 0, 0, 1 }, /* PERC 3/Di (Opal/PERC3Di) */
{ 0x1028, 0x0003, 0x1028, 0x0003, 0, 0, 2 }, /* PERC 3/Si (SlimFast/PERC3Si */
@@ -1089,16 +1095,16 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
goto out;
error = -ENODEV;
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
- pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
+ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
goto out_disable_pdev;
/*
* If the quirk31 bit is set, the adapter needs adapter
* to driver communication memory to be allocated below 2gig
*/
if (aac_drivers[index].quirks & AAC_QUIRK_31BIT)
- if (pci_set_dma_mask(pdev, DMA_31BIT_MASK) ||
- pci_set_consistent_dma_mask(pdev, DMA_31BIT_MASK))
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(31)) ||
+ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(31)))
goto out_disable_pdev;
pci_set_master(pdev);
@@ -1148,7 +1154,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
* address space.
*/
if (aac_drivers[index].quirks & AAC_QUIRK_31BIT)
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK))
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
goto out_deinit;
aac->maximum_num_channels = aac_drivers[index].channels;
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 7507d8bc57a..b756041f0b2 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -38,6 +38,7 @@
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -4519,8 +4520,8 @@ static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
* and is maintained in little-endian order when written to LRAM.
*/
static void
-AscMemWordCopyPtrToLram(PortAddr iop_base,
- ushort s_addr, uchar *s_buffer, int words)
+AscMemWordCopyPtrToLram(PortAddr iop_base, ushort s_addr,
+ const uchar *s_buffer, int words)
{
int i;
@@ -4642,8 +4643,8 @@ static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
}
static ASC_DCNT
-AscLoadMicroCode(PortAddr iop_base,
- ushort s_addr, uchar *mcode_buf, ushort mcode_size)
+AscLoadMicroCode(PortAddr iop_base, ushort s_addr,
+ const uchar *mcode_buf, ushort mcode_size)
{
ASC_DCNT chksum;
ushort mcode_word_size;
@@ -4668,1618 +4669,6 @@ AscLoadMicroCode(PortAddr iop_base,
return chksum;
}
-/* Microcode buffer is kept after initialization for error recovery. */
-static uchar _asc_mcode_buf[] = {
- 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
- 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
- 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
- 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
- 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
- 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
- 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
- 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
- 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
- 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
- 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
- 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
- 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
- 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
- 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
- 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
- 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
- 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
- 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
- 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
- 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
- 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
- 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
- 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
- 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
- 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
- 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
- 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
- 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
- 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
- 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
- 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
- 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
- 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
- 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
- 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
- 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
- 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
- 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
- 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
- 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
- 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
- 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
- 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
- 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
- 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
- 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
- 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
- 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
- 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
- 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
- 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
- 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
- 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
- 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
- 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
- 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
- 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
- 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
- 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
- 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
- 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
- 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
- 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
- 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
- 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
- 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
- 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
- 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
- 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
- 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
- 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
- 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
- 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
- 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
- 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
- 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
- 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
- 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
- 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
- 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
- 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
- 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
- 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
- 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
- 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
- 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
- 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
- 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
- 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
- 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
- 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
- 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
- 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
- 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
- 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
- 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
- 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
- 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
- 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
- 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
- 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
- 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
- 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
- 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
- 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
- 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
- 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
- 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
- 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
- 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
- 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
- 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
- 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
- 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
- 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
- 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
- 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
- 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
- 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
- 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
- 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
- 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
- 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
- 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
- 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
- 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
- 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
- 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
- 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
- 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
- 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
- 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
- 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
- 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
- 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
- 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
- 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
- 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
- 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
- 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
- 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
- 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
- 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
- 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
- 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
- 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
- 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
- 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
- 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
- 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
- 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
- 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
- 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
- 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
- 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
- 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
- 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
- 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
- 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
- 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
- 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
- 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
- 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
- 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
- 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
- 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
- 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
- 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
- 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
- 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
- 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
- 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
- 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
- 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
- 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
- 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
- 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
- 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
- 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
- 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
- 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
-};
-
-static unsigned short _asc_mcode_size = sizeof(_asc_mcode_buf);
-static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
-
-/* Microcode buffer is kept after initialization for error recovery. */
-static unsigned char _adv_asc3550_buf[] = {
- 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
- 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
- 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
- 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
- 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
- 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
- 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
- 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
- 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
- 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
- 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
- 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
- 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
- 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
- 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
- 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
- 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
- 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
- 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
- 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
- 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
- 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
- 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
- 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
- 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
- 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
- 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
- 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
- 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
- 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
- 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
- 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
- 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
- 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
- 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
- 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
- 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
- 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
- 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
- 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
- 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
- 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
- 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
- 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
- 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
- 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
- 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
- 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
- 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
- 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
- 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
- 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
- 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
- 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
- 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
- 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
- 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
- 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
- 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
- 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
- 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
- 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
- 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
- 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
- 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
- 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
- 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
- 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
- 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
- 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
- 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
- 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
- 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
- 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
- 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
- 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
- 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
- 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
- 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
- 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
- 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
- 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
- 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
- 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
- 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
- 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
- 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
- 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
- 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
- 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
- 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
- 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
- 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
- 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
- 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
- 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
- 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
- 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
- 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
- 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
- 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
- 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
- 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
- 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
- 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
- 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
- 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
- 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
- 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
- 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
- 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
- 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
- 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
- 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
- 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
- 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
- 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
- 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
- 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
- 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
- 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
- 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
- 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
- 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
- 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
- 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
- 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
- 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
- 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
- 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
- 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
- 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
- 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
- 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
- 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
- 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
- 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
- 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
- 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
- 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
- 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
- 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
- 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
- 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
- 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
- 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
- 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
- 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
- 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
- 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
- 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
- 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
- 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
- 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
- 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
- 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
- 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
- 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
- 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
- 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
- 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
- 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
- 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
- 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
- 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
- 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
- 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
- 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
- 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
- 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
- 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
- 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
- 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
- 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
- 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
- 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
- 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
- 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
- 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
- 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
- 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
- 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
- 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
- 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
- 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
- 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
- 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
- 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
- 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
- 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
- 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
- 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
- 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
- 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
- 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
- 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
- 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
- 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
- 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
- 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
- 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
- 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
- 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
- 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
- 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
- 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
- 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
- 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
- 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
- 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
- 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
- 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
- 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
- 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
- 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
- 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
- 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
- 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
- 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
- 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
- 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
- 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
- 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
- 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
- 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
- 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
- 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
- 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
- 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
- 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
- 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
- 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
- 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
- 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
- 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
- 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
- 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
- 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
- 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
- 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
- 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
- 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
- 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
- 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
- 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
- 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
- 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
- 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
- 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
- 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
- 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
- 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
- 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
- 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
- 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
- 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
- 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
- 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
- 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
- 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
- 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
- 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
- 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
- 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
- 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
- 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
- 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
- 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
- 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
- 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
- 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
- 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
- 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
- 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
- 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
- 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
- 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
- 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
- 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
- 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
- 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
- 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
- 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
- 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
- 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
- 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
- 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
- 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
- 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
- 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
- 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
- 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
- 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
- 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
- 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
- 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
- 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
- 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
- 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
- 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
- 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
- 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
- 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
- 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
- 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
- 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
- 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
- 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
- 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
- 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
- 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
- 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
- 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
- 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
- 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
- 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
- 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
- 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
- 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
- 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
- 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
- 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
- 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
- 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
- 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
- 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
- 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
- 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
- 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
- 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
- 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
- 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
- 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
- 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
- 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
- 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
- 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
- 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
- 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
- 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
- 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
- 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
- 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
- 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
- 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
- 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
- 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
- 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
- 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
- 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
- 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
- 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
- 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
- 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
- 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
- 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
- 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
- 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
- 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
- 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
- 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
- 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
- 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
- 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
- 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
- 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
- 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
- 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
- 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
- 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
- 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
- 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
- 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
- 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
- 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
- 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
- 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
- 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
- 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
- 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
- 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
- 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
- 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
- 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
- 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
- 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
- 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
- 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
- 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
- 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
- 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
- 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
- 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
- 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
- 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
- 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
- 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
- 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
- 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
- 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
- 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
- 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
- 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
- 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
- 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
- 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
- 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
- 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
- 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
- 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
- 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
- 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
- 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
- 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
- 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
- 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
- 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
- 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
- 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
-};
-
-static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
-static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
-
-/* Microcode buffer is kept after initialization for error recovery. */
-static unsigned char _adv_asc38C0800_buf[] = {
- 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
- 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
- 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
- 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
- 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
- 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
- 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
- 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
- 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
- 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
- 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
- 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
- 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
- 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
- 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
- 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
- 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
- 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
- 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
- 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
- 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
- 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
- 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
- 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
- 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
- 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
- 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
- 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
- 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
- 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
- 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
- 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
- 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
- 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
- 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
- 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
- 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
- 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
- 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
- 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
- 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
- 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
- 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
- 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
- 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
- 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
- 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
- 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
- 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
- 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
- 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
- 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
- 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
- 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
- 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
- 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
- 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
- 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
- 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
- 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
- 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
- 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
- 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
- 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
- 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
- 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
- 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
- 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
- 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
- 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
- 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
- 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
- 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
- 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
- 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
- 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
- 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
- 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
- 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
- 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
- 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
- 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
- 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
- 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
- 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
- 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
- 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
- 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
- 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
- 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
- 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
- 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
- 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
- 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
- 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
- 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
- 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
- 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
- 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
- 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
- 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
- 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
- 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
- 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
- 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
- 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
- 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
- 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
- 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
- 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
- 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
- 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
- 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
- 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
- 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
- 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
- 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
- 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
- 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
- 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
- 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
- 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
- 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
- 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
- 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
- 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
- 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
- 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
- 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
- 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
- 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
- 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
- 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
- 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
- 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
- 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
- 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
- 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
- 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
- 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
- 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
- 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
- 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
- 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
- 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
- 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
- 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
- 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
- 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
- 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
- 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
- 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
- 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
- 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
- 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
- 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
- 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
- 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
- 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
- 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
- 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
- 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
- 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
- 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
- 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
- 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
- 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
- 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
- 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
- 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
- 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
- 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
- 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
- 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
- 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
- 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
- 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
- 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
- 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
- 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
- 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
- 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
- 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
- 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
- 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
- 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
- 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
- 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
- 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
- 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
- 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
- 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
- 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
- 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
- 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
- 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
- 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
- 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
- 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
- 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
- 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
- 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
- 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
- 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
- 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
- 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
- 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
- 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
- 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
- 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
- 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
- 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
- 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
- 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
- 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
- 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
- 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
- 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
- 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
- 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
- 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
- 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
- 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
- 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
- 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
- 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
- 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
- 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
- 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
- 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
- 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
- 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
- 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
- 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
- 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
- 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
- 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
- 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
- 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
- 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
- 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
- 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
- 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
- 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
- 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
- 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
- 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
- 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
- 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
- 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
- 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
- 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
- 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
- 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
- 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
- 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
- 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
- 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
- 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
- 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
- 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
- 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
- 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
- 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
- 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
- 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
- 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
- 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
- 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
- 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
- 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
- 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
- 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
- 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
- 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
- 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
- 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
- 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
- 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
- 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
- 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
- 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
- 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
- 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
- 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
- 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
- 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
- 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
- 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
- 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
- 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
- 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
- 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
- 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
- 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
- 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
- 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
- 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
- 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
- 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
- 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
- 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
- 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
- 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
- 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
- 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
- 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
- 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
- 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
- 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
- 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
- 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
- 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
- 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
- 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
- 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
- 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
- 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
- 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
- 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
- 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
- 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
- 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
- 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
- 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
- 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
- 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
- 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
- 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
- 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
- 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
- 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
- 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
- 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
- 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
- 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
- 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
- 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
- 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
- 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
- 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
- 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
- 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
- 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
- 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
- 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
- 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
- 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
- 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
- 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
- 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
- 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
- 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
- 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
- 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
- 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
- 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
- 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
- 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
- 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
- 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
- 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
- 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
- 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
- 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
- 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
- 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
- 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
- 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
- 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
- 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
- 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
- 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
- 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
- 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
- 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
- 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
- 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
- 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
- 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
- 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
- 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
- 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
- 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
- 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
- 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
- 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
- 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
- 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
- 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
- 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
- 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
- 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
- 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
- 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
- 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
- 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
- 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
- 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
- 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
- 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
- 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
- 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
- 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
- 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
- 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
- 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
- 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
- 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
- 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
- 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
- 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
- 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
- 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
- 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
- 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
- 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
- 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
- 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
- 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
- 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
- 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
- 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
- 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
- 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
- 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
- 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
- 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
- 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
- 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
- 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
- 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
- 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
- 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
- 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
- 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
- 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
- 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
- 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
- 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
- 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
- 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
- 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
- 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
- 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
-};
-
-static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
-static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
-
-/* Microcode buffer is kept after initialization for error recovery. */
-static unsigned char _adv_asc38C1600_buf[] = {
- 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
- 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
- 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
- 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
- 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
- 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
- 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
- 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
- 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
- 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
- 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
- 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
- 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
- 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
- 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
- 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
- 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
- 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
- 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
- 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
- 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
- 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
- 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
- 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
- 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
- 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
- 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
- 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
- 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
- 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
- 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
- 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
- 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
- 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
- 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
- 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
- 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
- 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
- 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
- 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
- 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
- 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
- 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
- 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
- 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
- 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
- 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
- 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
- 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
- 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
- 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
- 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
- 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
- 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
- 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
- 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
- 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
- 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
- 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
- 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
- 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
- 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
- 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
- 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
- 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
- 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
- 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
- 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
- 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
- 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
- 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
- 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
- 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
- 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
- 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
- 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
- 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
- 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
- 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
- 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
- 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
- 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
- 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
- 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
- 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
- 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
- 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
- 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
- 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
- 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
- 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
- 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
- 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
- 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
- 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
- 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
- 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
- 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
- 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
- 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
- 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
- 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
- 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
- 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
- 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
- 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
- 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
- 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
- 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
- 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
- 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
- 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
- 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
- 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
- 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
- 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
- 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
- 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
- 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
- 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
- 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
- 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
- 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
- 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
- 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
- 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
- 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
- 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
- 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
- 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
- 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
- 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
- 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
- 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
- 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
- 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
- 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
- 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
- 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
- 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
- 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
- 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
- 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
- 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
- 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
- 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
- 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
- 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
- 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
- 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
- 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
- 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
- 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
- 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
- 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
- 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
- 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
- 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
- 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
- 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
- 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
- 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
- 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
- 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
- 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
- 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
- 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
- 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
- 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
- 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
- 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
- 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
- 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
- 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
- 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
- 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
- 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
- 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
- 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
- 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
- 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
- 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
- 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
- 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
- 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
- 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
- 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
- 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
- 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
- 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
- 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
- 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
- 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
- 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
- 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
- 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
- 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
- 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
- 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
- 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
- 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
- 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
- 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
- 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
- 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
- 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
- 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
- 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
- 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
- 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
- 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
- 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
- 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
- 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
- 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
- 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
- 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
- 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
- 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
- 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
- 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
- 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
- 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
- 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
- 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
- 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
- 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
- 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
- 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
- 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
- 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
- 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
- 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
- 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
- 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
- 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
- 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
- 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
- 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
- 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
- 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
- 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
- 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
- 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
- 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
- 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
- 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
- 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
- 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
- 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
- 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
- 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
- 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
- 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
- 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
- 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
- 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
- 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
- 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
- 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
- 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
- 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
- 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
- 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
- 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
- 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
- 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
- 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
- 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
- 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
- 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
- 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
- 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
- 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
- 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
- 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
- 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
- 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
- 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
- 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
- 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
- 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
- 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
- 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
- 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
- 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
- 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
- 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
- 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
- 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
- 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
- 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
- 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
- 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
- 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
- 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
- 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
- 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
- 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
- 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
- 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
- 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
- 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
- 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
- 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
- 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
- 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
- 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
- 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
- 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
- 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
- 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
- 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
- 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
- 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
- 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
- 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
- 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
- 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
- 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
- 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
- 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
- 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
- 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
- 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
- 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
- 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
- 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
- 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
- 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
- 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
- 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
- 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
- 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
- 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
- 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
- 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
- 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
- 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
- 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
- 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
- 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
- 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
- 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
- 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
- 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
- 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
- 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
- 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
- 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
- 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
- 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
- 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
- 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
- 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
- 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
- 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
- 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
- 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
- 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
- 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
- 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
- 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
- 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
- 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
- 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
- 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
- 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
- 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
- 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
- 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
- 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
- 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
- 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
- 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
- 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
- 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
- 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
- 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
- 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
- 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
- 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
- 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
- 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
- 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
- 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
- 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
- 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
- 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
- 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
- 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
- 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
- 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
- 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
- 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
- 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
- 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
- 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
- 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
- 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
- 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
- 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
- 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
- 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
- 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
- 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
- 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
- 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
- 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
- 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
- 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
- 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
- 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
- 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
- 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
- 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
- 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
- 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
- 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
- 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
- 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
- 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
- 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
- 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
- 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
- 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
- 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
- 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
- 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
- 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
- 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
- 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
- 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
- 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
- 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
- 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
- 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
- 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
- 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
- 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
- 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
- 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
- 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
- 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
- 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
- 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
- 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
- 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
- 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
- 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
- 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
- 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
- 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
- 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
- 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
- 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
- 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
- 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
- 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
- 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
- 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
- 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
- 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
- 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
- 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
- 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
- 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
- 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
- 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
- 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
- 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
- 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
- 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
- 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
- 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
- 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
- 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
- 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
- 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
- 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
- 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
- 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
- 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
- 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
- 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
- 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
- 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
- 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
- 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
- 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
- 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
- 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
- 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
- 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
- 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
- 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
- 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
- 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
- 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
- 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
- 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
- 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
- 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
- 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
- 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
- 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
- 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
- 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
- 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
- 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
- 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
- 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
- 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
- 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
- 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
-};
-
-static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
-static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
-
static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
{
PortAddr iop_base;
@@ -6362,6 +4751,10 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
{
+ const struct firmware *fw;
+ const char fwname[] = "advansys/mcode.bin";
+ int err;
+ unsigned long chksum;
ushort warn_code;
PortAddr iop_base;
@@ -6383,12 +4776,29 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
warn_code |= AscInitLram(asc_dvc);
if (asc_dvc->err_code != 0)
return UW_ERR;
- ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)_asc_mcode_chksum);
- if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
- _asc_mcode_size) != _asc_mcode_chksum) {
+
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size < 4) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
+ (fw->data[1] << 8) | fw->data[0];
+ ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)chksum);
+ if (AscLoadMicroCode(iop_base, 0, &fw->data[4],
+ fw->size - 4) != chksum) {
asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
+ release_firmware(fw);
return warn_code;
}
+ release_firmware(fw);
warn_code |= AscInitMicroCodeVar(asc_dvc);
asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
AscEnableInterrupt(iop_base);
@@ -6417,8 +4827,8 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
*
* Returns 0 or an error if the checksum doesn't match
*/
-static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
- int memsize, int chksum)
+static int AdvLoadMicrocode(AdvPortAddr iop_base, const unsigned char *buf,
+ int size, int memsize, int chksum)
{
int i, j, end, len = 0;
ADV_DCNT sum;
@@ -6627,6 +5037,8 @@ static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
*/
static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
{
+ const struct firmware *fw;
+ const char fwname[] = "advansys/3550.bin";
AdvPortAddr iop_base;
ushort warn_code;
int begin_addr;
@@ -6634,6 +5046,8 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
ushort code_sum;
int word;
int i;
+ int err;
+ unsigned long chksum;
ushort scsi_cfg1;
uchar tid;
ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
@@ -6692,9 +5106,24 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
max_cmd[tid]);
}
- asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
- _adv_asc3550_size, ADV_3550_MEMSIZE,
- _adv_asc3550_chksum);
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size < 4) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
+ (fw->data[1] << 8) | fw->data[0];
+ asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
+ fw->size - 4, ADV_3550_MEMSIZE,
+ chksum);
+ release_firmware(fw);
if (asc_dvc->err_code)
return ADV_ERROR;
@@ -7065,6 +5494,8 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
*/
static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
{
+ const struct firmware *fw;
+ const char fwname[] = "advansys/38C0800.bin";
AdvPortAddr iop_base;
ushort warn_code;
int begin_addr;
@@ -7072,6 +5503,8 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
ushort code_sum;
int word;
int i;
+ int err;
+ unsigned long chksum;
ushort scsi_cfg1;
uchar byte;
uchar tid;
@@ -7187,9 +5620,24 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
/* We need to reset back to normal mode after LRAM test passes. */
AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
- asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
- _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
- _adv_asc38C0800_chksum);
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size < 4) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
+ (fw->data[1] << 8) | fw->data[0];
+ asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
+ fw->size - 4, ADV_38C0800_MEMSIZE,
+ chksum);
+ release_firmware(fw);
if (asc_dvc->err_code)
return ADV_ERROR;
@@ -7544,6 +5992,8 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
*/
static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
{
+ const struct firmware *fw;
+ const char fwname[] = "advansys/38C1600.bin";
AdvPortAddr iop_base;
ushort warn_code;
int begin_addr;
@@ -7551,6 +6001,8 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
ushort code_sum;
long word;
int i;
+ int err;
+ unsigned long chksum;
ushort scsi_cfg1;
uchar byte;
uchar tid;
@@ -7668,9 +6120,24 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
/* We need to reset back to normal mode after LRAM test passes. */
AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
- asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
- _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
- _adv_asc38C1600_chksum);
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size < 4) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
+ (fw->data[1] << 8) | fw->data[0];
+ asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
+ fw->size - 4, ADV_38C1600_MEMSIZE,
+ chksum);
+ release_firmware(fw);
if (asc_dvc->err_code)
return ADV_ERROR;
@@ -14353,3 +12820,7 @@ module_init(advansys_init);
module_exit(advansys_exit);
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("advansys/mcode.bin");
+MODULE_FIRMWARE("advansys/3550.bin");
+MODULE_FIRMWARE("advansys/38C0800.bin");
+MODULE_FIRMWARE("advansys/38C1600.bin");
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index bdad54ec088..63b521d615f 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -1034,7 +1034,7 @@ ahd_intr(struct ahd_softc *ahd)
}
/******************************** Private Inlines *****************************/
-static __inline void
+static inline void
ahd_assert_atn(struct ahd_softc *ahd)
{
ahd_outb(ahd, SCSISIGO, ATNO);
@@ -1069,7 +1069,7 @@ ahd_currently_packetized(struct ahd_softc *ahd)
return (packetized);
}
-static __inline int
+static inline int
ahd_set_active_fifo(struct ahd_softc *ahd)
{
u_int active_fifo;
@@ -1086,7 +1086,7 @@ ahd_set_active_fifo(struct ahd_softc *ahd)
}
}
-static __inline void
+static inline void
ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl)
{
ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL);
@@ -1096,7 +1096,7 @@ ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl)
* Determine whether the sequencer reported a residual
* for this SCB/transaction.
*/
-static __inline void
+static inline void
ahd_update_residual(struct ahd_softc *ahd, struct scb *scb)
{
uint32_t sgptr;
@@ -1106,7 +1106,7 @@ ahd_update_residual(struct ahd_softc *ahd, struct scb *scb)
ahd_calc_residual(ahd, scb);
}
-static __inline void
+static inline void
ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb)
{
uint32_t sgptr;
@@ -7987,7 +7987,7 @@ ahd_resume(struct ahd_softc *ahd)
* scbid that should be restored once manipualtion
* of the TCL entry is complete.
*/
-static __inline u_int
+static inline u_int
ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl)
{
/*
diff --git a/drivers/scsi/aic7xxx/aic79xx_inline.h b/drivers/scsi/aic7xxx/aic79xx_inline.h
index 5f12cf9d99d..09335a3c869 100644
--- a/drivers/scsi/aic7xxx/aic79xx_inline.h
+++ b/drivers/scsi/aic7xxx/aic79xx_inline.h
@@ -46,21 +46,20 @@
#define _AIC79XX_INLINE_H_
/******************************** Debugging ***********************************/
-static __inline char *ahd_name(struct ahd_softc *ahd);
+static inline char *ahd_name(struct ahd_softc *ahd);
-static __inline char *
-ahd_name(struct ahd_softc *ahd)
+static inline char *ahd_name(struct ahd_softc *ahd)
{
return (ahd->name);
}
/************************ Sequencer Execution Control *************************/
-static __inline void ahd_known_modes(struct ahd_softc *ahd,
+static inline void ahd_known_modes(struct ahd_softc *ahd,
ahd_mode src, ahd_mode dst);
-static __inline ahd_mode_state ahd_build_mode_state(struct ahd_softc *ahd,
+static inline ahd_mode_state ahd_build_mode_state(struct ahd_softc *ahd,
ahd_mode src,
ahd_mode dst);
-static __inline void ahd_extract_mode_state(struct ahd_softc *ahd,
+static inline void ahd_extract_mode_state(struct ahd_softc *ahd,
ahd_mode_state state,
ahd_mode *src, ahd_mode *dst);
@@ -73,7 +72,7 @@ int ahd_is_paused(struct ahd_softc *ahd);
void ahd_pause(struct ahd_softc *ahd);
void ahd_unpause(struct ahd_softc *ahd);
-static __inline void
+static inline void
ahd_known_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst)
{
ahd->src_mode = src;
@@ -82,13 +81,13 @@ ahd_known_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst)
ahd->saved_dst_mode = dst;
}
-static __inline ahd_mode_state
+static inline ahd_mode_state
ahd_build_mode_state(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst)
{
return ((src << SRC_MODE_SHIFT) | (dst << DST_MODE_SHIFT));
}
-static __inline void
+static inline void
ahd_extract_mode_state(struct ahd_softc *ahd, ahd_mode_state state,
ahd_mode *src, ahd_mode *dst)
{
@@ -102,13 +101,12 @@ void *ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb,
bus_size_t len, int last);
/************************** Memory mapping routines ***************************/
-static __inline size_t ahd_sg_size(struct ahd_softc *ahd);
+static inline size_t ahd_sg_size(struct ahd_softc *ahd);
void ahd_sync_sglist(struct ahd_softc *ahd,
struct scb *scb, int op);
-static __inline size_t
-ahd_sg_size(struct ahd_softc *ahd)
+static inline size_t ahd_sg_size(struct ahd_softc *ahd)
{
if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
return (sizeof(struct ahd_dma64_seg));
@@ -141,11 +139,9 @@ struct scb *
ahd_lookup_scb(struct ahd_softc *ahd, u_int tag);
void ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb);
-static __inline uint8_t *
- ahd_get_sense_buf(struct ahd_softc *ahd,
+static inline uint8_t *ahd_get_sense_buf(struct ahd_softc *ahd,
struct scb *scb);
-static __inline uint32_t
- ahd_get_sense_bufaddr(struct ahd_softc *ahd,
+static inline uint32_t ahd_get_sense_bufaddr(struct ahd_softc *ahd,
struct scb *scb);
#if 0 /* unused */
@@ -158,13 +154,13 @@ do { \
#endif
-static __inline uint8_t *
+static inline uint8_t *
ahd_get_sense_buf(struct ahd_softc *ahd, struct scb *scb)
{
return (scb->sense_data);
}
-static __inline uint32_t
+static inline uint32_t
ahd_get_sense_bufaddr(struct ahd_softc *ahd, struct scb *scb)
{
return (scb->sense_busaddr);
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 8d6612c1992..55c1fe07969 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -395,19 +395,19 @@ struct info_str {
};
/******************************** Locking *************************************/
-static __inline void
+static inline void
ahd_lockinit(struct ahd_softc *ahd)
{
spin_lock_init(&ahd->platform_data->spin_lock);
}
-static __inline void
+static inline void
ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
{
spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags);
}
-static __inline void
+static inline void
ahd_unlock(struct ahd_softc *ahd, unsigned long *flags)
{
spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags);
@@ -490,29 +490,29 @@ void ahd_pci_write_config(ahd_dev_softc_t pci,
int reg, uint32_t value,
int width);
-static __inline int ahd_get_pci_function(ahd_dev_softc_t);
-static __inline int
+static inline int ahd_get_pci_function(ahd_dev_softc_t);
+static inline int
ahd_get_pci_function(ahd_dev_softc_t pci)
{
return (PCI_FUNC(pci->devfn));
}
-static __inline int ahd_get_pci_slot(ahd_dev_softc_t);
-static __inline int
+static inline int ahd_get_pci_slot(ahd_dev_softc_t);
+static inline int
ahd_get_pci_slot(ahd_dev_softc_t pci)
{
return (PCI_SLOT(pci->devfn));
}
-static __inline int ahd_get_pci_bus(ahd_dev_softc_t);
-static __inline int
+static inline int ahd_get_pci_bus(ahd_dev_softc_t);
+static inline int
ahd_get_pci_bus(ahd_dev_softc_t pci)
{
return (pci->bus->number);
}
-static __inline void ahd_flush_device_writes(struct ahd_softc *);
-static __inline void
+static inline void ahd_flush_device_writes(struct ahd_softc *);
+static inline void
ahd_flush_device_writes(struct ahd_softc *ahd)
{
/* XXX Is this sufficient for all architectures??? */
@@ -524,81 +524,81 @@ int ahd_linux_proc_info(struct Scsi_Host *, char *, char **,
off_t, int, int);
/*********************** Transaction Access Wrappers **************************/
-static __inline void ahd_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
-static __inline void ahd_set_transaction_status(struct scb *, uint32_t);
-static __inline void ahd_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
-static __inline void ahd_set_scsi_status(struct scb *, uint32_t);
-static __inline uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd);
-static __inline uint32_t ahd_get_transaction_status(struct scb *);
-static __inline uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd);
-static __inline uint32_t ahd_get_scsi_status(struct scb *);
-static __inline void ahd_set_transaction_tag(struct scb *, int, u_int);
-static __inline u_long ahd_get_transfer_length(struct scb *);
-static __inline int ahd_get_transfer_dir(struct scb *);
-static __inline void ahd_set_residual(struct scb *, u_long);
-static __inline void ahd_set_sense_residual(struct scb *scb, u_long resid);
-static __inline u_long ahd_get_residual(struct scb *);
-static __inline u_long ahd_get_sense_residual(struct scb *);
-static __inline int ahd_perform_autosense(struct scb *);
-static __inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *,
+static inline void ahd_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
+static inline void ahd_set_transaction_status(struct scb *, uint32_t);
+static inline void ahd_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
+static inline void ahd_set_scsi_status(struct scb *, uint32_t);
+static inline uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd);
+static inline uint32_t ahd_get_transaction_status(struct scb *);
+static inline uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd);
+static inline uint32_t ahd_get_scsi_status(struct scb *);
+static inline void ahd_set_transaction_tag(struct scb *, int, u_int);
+static inline u_long ahd_get_transfer_length(struct scb *);
+static inline int ahd_get_transfer_dir(struct scb *);
+static inline void ahd_set_residual(struct scb *, u_long);
+static inline void ahd_set_sense_residual(struct scb *scb, u_long resid);
+static inline u_long ahd_get_residual(struct scb *);
+static inline u_long ahd_get_sense_residual(struct scb *);
+static inline int ahd_perform_autosense(struct scb *);
+static inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *,
struct scb *);
-static __inline void ahd_notify_xfer_settings_change(struct ahd_softc *,
+static inline void ahd_notify_xfer_settings_change(struct ahd_softc *,
struct ahd_devinfo *);
-static __inline void ahd_platform_scb_free(struct ahd_softc *ahd,
+static inline void ahd_platform_scb_free(struct ahd_softc *ahd,
struct scb *scb);
-static __inline void ahd_freeze_scb(struct scb *scb);
+static inline void ahd_freeze_scb(struct scb *scb);
-static __inline
+static inline
void ahd_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
{
cmd->result &= ~(CAM_STATUS_MASK << 16);
cmd->result |= status << 16;
}
-static __inline
+static inline
void ahd_set_transaction_status(struct scb *scb, uint32_t status)
{
ahd_cmd_set_transaction_status(scb->io_ctx,status);
}
-static __inline
+static inline
void ahd_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status)
{
cmd->result &= ~0xFFFF;
cmd->result |= status;
}
-static __inline
+static inline
void ahd_set_scsi_status(struct scb *scb, uint32_t status)
{
ahd_cmd_set_scsi_status(scb->io_ctx, status);
}
-static __inline
+static inline
uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd)
{
return ((cmd->result >> 16) & CAM_STATUS_MASK);
}
-static __inline
+static inline
uint32_t ahd_get_transaction_status(struct scb *scb)
{
return (ahd_cmd_get_transaction_status(scb->io_ctx));
}
-static __inline
+static inline
uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd)
{
return (cmd->result & 0xFFFF);
}
-static __inline
+static inline
uint32_t ahd_get_scsi_status(struct scb *scb)
{
return (ahd_cmd_get_scsi_status(scb->io_ctx));
}
-static __inline
+static inline
void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type)
{
/*
@@ -607,43 +607,43 @@ void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type)
*/
}
-static __inline
+static inline
u_long ahd_get_transfer_length(struct scb *scb)
{
return (scb->platform_data->xfer_len);
}
-static __inline
+static inline
int ahd_get_transfer_dir(struct scb *scb)
{
return (scb->io_ctx->sc_data_direction);
}
-static __inline
+static inline
void ahd_set_residual(struct scb *scb, u_long resid)
{
scsi_set_resid(scb->io_ctx, resid);
}
-static __inline
+static inline
void ahd_set_sense_residual(struct scb *scb, u_long resid)
{
scb->platform_data->sense_resid = resid;
}
-static __inline
+static inline
u_long ahd_get_residual(struct scb *scb)
{
return scsi_get_resid(scb->io_ctx);
}
-static __inline
+static inline
u_long ahd_get_sense_residual(struct scb *scb)
{
return (scb->platform_data->sense_resid);
}
-static __inline
+static inline
int ahd_perform_autosense(struct scb *scb)
{
/*
@@ -654,20 +654,20 @@ int ahd_perform_autosense(struct scb *scb)
return (1);
}
-static __inline uint32_t
+static inline uint32_t
ahd_get_sense_bufsize(struct ahd_softc *ahd, struct scb *scb)
{
return (sizeof(struct scsi_sense_data));
}
-static __inline void
+static inline void
ahd_notify_xfer_settings_change(struct ahd_softc *ahd,
struct ahd_devinfo *devinfo)
{
/* Nothing to do here for linux */
}
-static __inline void
+static inline void
ahd_platform_scb_free(struct ahd_softc *ahd, struct scb *scb)
{
ahd->flags &= ~AHD_RESOURCE_SHORTAGE;
@@ -678,7 +678,7 @@ void ahd_platform_free(struct ahd_softc *ahd);
void ahd_platform_init(struct ahd_softc *ahd);
void ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb);
-static __inline void
+static inline void
ahd_freeze_scb(struct scb *scb)
{
if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
index 6593056867f..8f686122d54 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
@@ -194,16 +194,16 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (sizeof(dma_addr_t) > 4) {
const u64 required_mask = dma_get_required_mask(dev);
- if (required_mask > DMA_39BIT_MASK &&
- dma_set_mask(dev, DMA_64BIT_MASK) == 0)
+ if (required_mask > DMA_BIT_MASK(39) &&
+ dma_set_mask(dev, DMA_BIT_MASK(64)) == 0)
ahd->flags |= AHD_64BIT_ADDRESSING;
- else if (required_mask > DMA_32BIT_MASK &&
- dma_set_mask(dev, DMA_39BIT_MASK) == 0)
+ else if (required_mask > DMA_BIT_MASK(32) &&
+ dma_set_mask(dev, DMA_BIT_MASK(39)) == 0)
ahd->flags |= AHD_39BIT_ADDRESSING;
else
- dma_set_mask(dev, DMA_32BIT_MASK);
+ dma_set_mask(dev, DMA_BIT_MASK(32));
} else {
- dma_set_mask(dev, DMA_32BIT_MASK);
+ dma_set_mask(dev, DMA_BIT_MASK(32));
}
ahd->dev_softc = pci;
error = ahd_pci_config(ahd, entry);
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c
index a734d77e880..90a04a37b4f 100644
--- a/drivers/scsi/aic7xxx/aic79xx_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.c
@@ -51,7 +51,7 @@
#include "aic79xx_pci.h"
-static __inline uint64_t
+static inline uint64_t
ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
{
uint64_t id;
@@ -377,14 +377,12 @@ ahd_pci_config(struct ahd_softc *ahd, const struct ahd_pci_identity *entry)
error = ahd_init(ahd);
if (error != 0)
return (error);
+ ahd->init_level++;
/*
* Allow interrupts now that we are completely setup.
*/
- error = ahd_pci_map_int(ahd);
- if (!error)
- ahd->init_level++;
- return error;
+ return ahd_pci_map_int(ahd);
}
#ifdef CONFIG_PM
diff --git a/drivers/scsi/aic7xxx/aic7xxx_inline.h b/drivers/scsi/aic7xxx/aic7xxx_inline.h
index 09bf2f4d78d..0b57b783ef4 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_inline.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_inline.h
@@ -55,10 +55,9 @@ void ahc_sync_sglist(struct ahc_softc *ahc,
struct scb *scb, int op);
/******************************** Debugging ***********************************/
-static __inline char *ahc_name(struct ahc_softc *ahc);
+static inline char *ahc_name(struct ahc_softc *ahc);
-static __inline char *
-ahc_name(struct ahc_softc *ahc)
+static inline char *ahc_name(struct ahc_softc *ahc)
{
return (ahc->name);
}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index 3f7238db35e..56f07e527b4 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -230,7 +230,7 @@ int ahc_dmamap_unload(struct ahc_softc *, bus_dma_tag_t, bus_dmamap_t);
#include "aic7xxx.h"
/***************************** Timer Facilities *******************************/
-static __inline void
+static inline void
ahc_scb_timer_reset(struct scb *scb, u_int usec)
{
}
@@ -401,19 +401,19 @@ struct info_str {
/******************************** Locking *************************************/
/* Lock protecting internal data structures */
-static __inline void
+static inline void
ahc_lockinit(struct ahc_softc *ahc)
{
spin_lock_init(&ahc->platform_data->spin_lock);
}
-static __inline void
+static inline void
ahc_lock(struct ahc_softc *ahc, unsigned long *flags)
{
spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags);
}
-static __inline void
+static inline void
ahc_unlock(struct ahc_softc *ahc, unsigned long *flags)
{
spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags);
@@ -493,22 +493,22 @@ void ahc_pci_write_config(ahc_dev_softc_t pci,
int reg, uint32_t value,
int width);
-static __inline int ahc_get_pci_function(ahc_dev_softc_t);
-static __inline int
+static inline int ahc_get_pci_function(ahc_dev_softc_t);
+static inline int
ahc_get_pci_function(ahc_dev_softc_t pci)
{
return (PCI_FUNC(pci->devfn));
}
-static __inline int ahc_get_pci_slot(ahc_dev_softc_t);
-static __inline int
+static inline int ahc_get_pci_slot(ahc_dev_softc_t);
+static inline int
ahc_get_pci_slot(ahc_dev_softc_t pci)
{
return (PCI_SLOT(pci->devfn));
}
-static __inline int ahc_get_pci_bus(ahc_dev_softc_t);
-static __inline int
+static inline int ahc_get_pci_bus(ahc_dev_softc_t);
+static inline int
ahc_get_pci_bus(ahc_dev_softc_t pci)
{
return (pci->bus->number);
@@ -521,8 +521,8 @@ static inline void ahc_linux_pci_exit(void) {
}
#endif
-static __inline void ahc_flush_device_writes(struct ahc_softc *);
-static __inline void
+static inline void ahc_flush_device_writes(struct ahc_softc *);
+static inline void
ahc_flush_device_writes(struct ahc_softc *ahc)
{
/* XXX Is this sufficient for all architectures??? */
@@ -535,81 +535,81 @@ int ahc_linux_proc_info(struct Scsi_Host *, char *, char **,
/*************************** Domain Validation ********************************/
/*********************** Transaction Access Wrappers *************************/
-static __inline void ahc_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
-static __inline void ahc_set_transaction_status(struct scb *, uint32_t);
-static __inline void ahc_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
-static __inline void ahc_set_scsi_status(struct scb *, uint32_t);
-static __inline uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd);
-static __inline uint32_t ahc_get_transaction_status(struct scb *);
-static __inline uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd);
-static __inline uint32_t ahc_get_scsi_status(struct scb *);
-static __inline void ahc_set_transaction_tag(struct scb *, int, u_int);
-static __inline u_long ahc_get_transfer_length(struct scb *);
-static __inline int ahc_get_transfer_dir(struct scb *);
-static __inline void ahc_set_residual(struct scb *, u_long);
-static __inline void ahc_set_sense_residual(struct scb *scb, u_long resid);
-static __inline u_long ahc_get_residual(struct scb *);
-static __inline u_long ahc_get_sense_residual(struct scb *);
-static __inline int ahc_perform_autosense(struct scb *);
-static __inline uint32_t ahc_get_sense_bufsize(struct ahc_softc *,
+static inline void ahc_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
+static inline void ahc_set_transaction_status(struct scb *, uint32_t);
+static inline void ahc_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
+static inline void ahc_set_scsi_status(struct scb *, uint32_t);
+static inline uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd);
+static inline uint32_t ahc_get_transaction_status(struct scb *);
+static inline uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd);
+static inline uint32_t ahc_get_scsi_status(struct scb *);
+static inline void ahc_set_transaction_tag(struct scb *, int, u_int);
+static inline u_long ahc_get_transfer_length(struct scb *);
+static inline int ahc_get_transfer_dir(struct scb *);
+static inline void ahc_set_residual(struct scb *, u_long);
+static inline void ahc_set_sense_residual(struct scb *scb, u_long resid);
+static inline u_long ahc_get_residual(struct scb *);
+static inline u_long ahc_get_sense_residual(struct scb *);
+static inline int ahc_perform_autosense(struct scb *);
+static inline uint32_t ahc_get_sense_bufsize(struct ahc_softc *,
struct scb *);
-static __inline void ahc_notify_xfer_settings_change(struct ahc_softc *,
+static inline void ahc_notify_xfer_settings_change(struct ahc_softc *,
struct ahc_devinfo *);
-static __inline void ahc_platform_scb_free(struct ahc_softc *ahc,
+static inline void ahc_platform_scb_free(struct ahc_softc *ahc,
struct scb *scb);
-static __inline void ahc_freeze_scb(struct scb *scb);
+static inline void ahc_freeze_scb(struct scb *scb);
-static __inline
+static inline
void ahc_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
{
cmd->result &= ~(CAM_STATUS_MASK << 16);
cmd->result |= status << 16;
}
-static __inline
+static inline
void ahc_set_transaction_status(struct scb *scb, uint32_t status)
{
ahc_cmd_set_transaction_status(scb->io_ctx,status);
}
-static __inline
+static inline
void ahc_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status)
{
cmd->result &= ~0xFFFF;
cmd->result |= status;
}
-static __inline
+static inline
void ahc_set_scsi_status(struct scb *scb, uint32_t status)
{
ahc_cmd_set_scsi_status(scb->io_ctx, status);
}
-static __inline
+static inline
uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd)
{
return ((cmd->result >> 16) & CAM_STATUS_MASK);
}
-static __inline
+static inline
uint32_t ahc_get_transaction_status(struct scb *scb)
{
return (ahc_cmd_get_transaction_status(scb->io_ctx));
}
-static __inline
+static inline
uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd)
{
return (cmd->result & 0xFFFF);
}
-static __inline
+static inline
uint32_t ahc_get_scsi_status(struct scb *scb)
{
return (ahc_cmd_get_scsi_status(scb->io_ctx));
}
-static __inline
+static inline
void ahc_set_transaction_tag(struct scb *scb, int enabled, u_int type)
{
/*
@@ -618,43 +618,43 @@ void ahc_set_transaction_tag(struct scb *scb, int enabled, u_int type)
*/
}
-static __inline
+static inline
u_long ahc_get_transfer_length(struct scb *scb)
{
return (scb->platform_data->xfer_len);
}
-static __inline
+static inline
int ahc_get_transfer_dir(struct scb *scb)
{
return (scb->io_ctx->sc_data_direction);
}
-static __inline
+static inline
void ahc_set_residual(struct scb *scb, u_long resid)
{
scsi_set_resid(scb->io_ctx, resid);
}
-static __inline
+static inline
void ahc_set_sense_residual(struct scb *scb, u_long resid)
{
scb->platform_data->sense_resid = resid;
}
-static __inline
+static inline
u_long ahc_get_residual(struct scb *scb)
{
return scsi_get_resid(scb->io_ctx);
}
-static __inline
+static inline
u_long ahc_get_sense_residual(struct scb *scb)
{
return (scb->platform_data->sense_resid);
}
-static __inline
+static inline
int ahc_perform_autosense(struct scb *scb)
{
/*
@@ -665,20 +665,20 @@ int ahc_perform_autosense(struct scb *scb)
return (1);
}
-static __inline uint32_t
+static inline uint32_t
ahc_get_sense_bufsize(struct ahc_softc *ahc, struct scb *scb)
{
return (sizeof(struct scsi_sense_data));
}
-static __inline void
+static inline void
ahc_notify_xfer_settings_change(struct ahc_softc *ahc,
struct ahc_devinfo *devinfo)
{
/* Nothing to do here for linux */
}
-static __inline void
+static inline void
ahc_platform_scb_free(struct ahc_softc *ahc, struct scb *scb)
{
}
@@ -687,7 +687,7 @@ int ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg);
void ahc_platform_free(struct ahc_softc *ahc);
void ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb);
-static __inline void
+static inline void
ahc_freeze_scb(struct scb *scb)
{
if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
index 00f5b986857..78fc70c24e0 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
@@ -241,10 +241,10 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (sizeof(dma_addr_t) > 4
&& ahc->features & AHC_LARGE_SCBS
&& dma_set_mask(dev, mask_39bit) == 0
- && dma_get_required_mask(dev) > DMA_32BIT_MASK) {
+ && dma_get_required_mask(dev) > DMA_BIT_MASK(32)) {
ahc->flags |= AHC_39BIT_ADDRESSING;
} else {
- if (dma_set_mask(dev, DMA_32BIT_MASK)) {
+ if (dma_set_mask(dev, DMA_BIT_MASK(32))) {
ahc_free(ahc);
printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
return (-ENODEV);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c
index c07cb6eebb0..27014b9de12 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c
@@ -54,7 +54,7 @@
#include "aic7xxx_pci.h"
-static __inline uint64_t
+static inline uint64_t
ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
{
uint64_t id;
@@ -960,16 +960,12 @@ ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry)
error = ahc_init(ahc);
if (error != 0)
return (error);
+ ahc->init_level++;
/*
* Allow interrupts now that we are completely setup.
*/
- error = ahc_pci_map_int(ahc);
- if (error != 0)
- return (error);
-
- ahc->init_level++;
- return (0);
+ return ahc_pci_map_int(ahc);
}
/*
diff --git a/drivers/scsi/aic7xxx/aiclib.h b/drivers/scsi/aic7xxx/aiclib.h
index 3bfbf0fe1ec..f8fd198aafb 100644
--- a/drivers/scsi/aic7xxx/aiclib.h
+++ b/drivers/scsi/aic7xxx/aiclib.h
@@ -133,7 +133,7 @@ struct scsi_sense_data
#define SCSI_STATUS_TASK_ABORTED 0x40
/************************* Large Disk Handling ********************************/
-static __inline int
+static inline int
aic_sector_div(sector_t capacity, int heads, int sectors)
{
/* ugly, ugly sector_div calling convention.. */
@@ -141,7 +141,7 @@ aic_sector_div(sector_t capacity, int heads, int sectors)
return (int)capacity;
}
-static __inline uint32_t
+static inline uint32_t
scsi_4btoul(uint8_t *bytes)
{
uint32_t rv;
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index 2a730c470f6..996f7224f90 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -790,11 +790,11 @@ static int __devinit asd_pci_probe(struct pci_dev *dev,
goto Err_remove;
err = -ENODEV;
- if (!pci_set_dma_mask(dev, DMA_64BIT_MASK)
- && !pci_set_consistent_dma_mask(dev, DMA_64BIT_MASK))
+ if (!pci_set_dma_mask(dev, DMA_BIT_MASK(64))
+ && !pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(64)))
;
- else if (!pci_set_dma_mask(dev, DMA_32BIT_MASK)
- && !pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK))
+ else if (!pci_set_dma_mask(dev, DMA_BIT_MASK(32))
+ && !pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(32)))
;
else {
asd_printk("no suitable DMA mask for %s\n", pci_name(dev));
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 106c04d2d79..80aac01b5a6 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -393,9 +393,9 @@ static int arcmsr_probe(struct pci_dev *pdev,
acb = (struct AdapterControlBlock *)host->hostdata;
memset(acb, 0, sizeof (struct AdapterControlBlock));
- error = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ error = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (error) {
- error = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (error) {
printk(KERN_WARNING
"scsi%d: No suitable DMA mask available\n",
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
index 20ca0a6374b..b137e561f5b 100644
--- a/drivers/scsi/atp870u.c
+++ b/drivers/scsi/atp870u.c
@@ -2568,7 +2568,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_enable_device(pdev))
goto err_eio;
- if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_INFO "atp870u: use 32bit DMA mask.\n");
} else {
printk(KERN_ERR "atp870u: DMA mask required but not available.\n");
diff --git a/drivers/scsi/cxgb3i/Kbuild b/drivers/scsi/cxgb3i/Kbuild
index ee7d6d2f9c3..25a2032bfa2 100644
--- a/drivers/scsi/cxgb3i/Kbuild
+++ b/drivers/scsi/cxgb3i/Kbuild
@@ -1,4 +1,4 @@
EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/cxgb3
-cxgb3i-y := cxgb3i_init.o cxgb3i_iscsi.o cxgb3i_pdu.o cxgb3i_offload.o
-obj-$(CONFIG_SCSI_CXGB3_ISCSI) += cxgb3i_ddp.o cxgb3i.o
+cxgb3i-y := cxgb3i_init.o cxgb3i_iscsi.o cxgb3i_pdu.o cxgb3i_offload.o cxgb3i_ddp.o
+obj-$(CONFIG_SCSI_CXGB3_ISCSI) += cxgb3i.o
diff --git a/drivers/scsi/cxgb3i/cxgb3i.h b/drivers/scsi/cxgb3i/cxgb3i.h
index a7cf550b9cc..d362860e750 100644
--- a/drivers/scsi/cxgb3i/cxgb3i.h
+++ b/drivers/scsi/cxgb3i/cxgb3i.h
@@ -66,10 +66,12 @@ struct cxgb3i_hba {
* @pdev: pointer to pci dev
* @hba_cnt: # of hbas (the same as # of ports)
* @hba: all the hbas on this adapter
+ * @flags: bit flag for adapter event/status
* @tx_max_size: max. tx packet size supported
* @rx_max_size: max. rx packet size supported
* @tag_format: ddp tag format settings
*/
+#define CXGB3I_ADAPTER_FLAG_RESET 0x1
struct cxgb3i_adapter {
struct list_head list_head;
spinlock_t lock;
@@ -78,6 +80,7 @@ struct cxgb3i_adapter {
unsigned char hba_cnt;
struct cxgb3i_hba *hba[MAX_NPORTS];
+ unsigned int flags;
unsigned int tx_max_size;
unsigned int rx_max_size;
@@ -137,10 +140,9 @@ struct cxgb3i_task_data {
int cxgb3i_iscsi_init(void);
void cxgb3i_iscsi_cleanup(void);
-struct cxgb3i_adapter *cxgb3i_adapter_add(struct t3cdev *);
-void cxgb3i_adapter_remove(struct t3cdev *);
-int cxgb3i_adapter_ulp_init(struct cxgb3i_adapter *);
-void cxgb3i_adapter_ulp_cleanup(struct cxgb3i_adapter *);
+struct cxgb3i_adapter *cxgb3i_adapter_find_by_tdev(struct t3cdev *);
+void cxgb3i_adapter_open(struct t3cdev *);
+void cxgb3i_adapter_close(struct t3cdev *);
struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *);
struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *,
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.c b/drivers/scsi/cxgb3i/cxgb3i_ddp.c
index 4eb6f5593b3..d06a661c209 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.c
@@ -23,19 +23,6 @@
#include "cxgb3i_ddp.h"
-#define DRV_MODULE_NAME "cxgb3i_ddp"
-#define DRV_MODULE_VERSION "1.0.0"
-#define DRV_MODULE_RELDATE "Dec. 1, 2008"
-
-static char version[] =
- "Chelsio S3xx iSCSI DDP " DRV_MODULE_NAME
- " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
-
-MODULE_AUTHOR("Karen Xie <kxie@chelsio.com>");
-MODULE_DESCRIPTION("cxgb3i ddp pagepod manager");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_MODULE_VERSION);
-
#define ddp_log_error(fmt...) printk(KERN_ERR "cxgb3i_ddp: ERR! " fmt)
#define ddp_log_warn(fmt...) printk(KERN_WARNING "cxgb3i_ddp: WARN! " fmt)
#define ddp_log_info(fmt...) printk(KERN_INFO "cxgb3i_ddp: " fmt)
@@ -66,9 +53,6 @@ static unsigned char ddp_page_order[DDP_PGIDX_MAX] = {0, 1, 2, 4};
static unsigned char ddp_page_shift[DDP_PGIDX_MAX] = {12, 13, 14, 16};
static unsigned char page_idx = DDP_PGIDX_MAX;
-static LIST_HEAD(cxgb3i_ddp_list);
-static DEFINE_RWLOCK(cxgb3i_ddp_rwlock);
-
/*
* functions to program the pagepod in h/w
*/
@@ -113,8 +97,8 @@ static int set_ddp_map(struct cxgb3i_ddp_info *ddp, struct pagepod_hdr *hdr,
return 0;
}
-static int clear_ddp_map(struct cxgb3i_ddp_info *ddp, unsigned int idx,
- unsigned int npods)
+static void clear_ddp_map(struct cxgb3i_ddp_info *ddp, unsigned int tag,
+ unsigned int idx, unsigned int npods)
{
unsigned int pm_addr = (idx << PPOD_SIZE_SHIFT) + ddp->llimit;
int i;
@@ -122,13 +106,17 @@ static int clear_ddp_map(struct cxgb3i_ddp_info *ddp, unsigned int idx,
for (i = 0; i < npods; i++, idx++, pm_addr += PPOD_SIZE) {
struct sk_buff *skb = ddp->gl_skb[idx];
+ if (!skb) {
+ ddp_log_error("ddp tag 0x%x, 0x%x, %d/%u, skb NULL.\n",
+ tag, idx, i, npods);
+ continue;
+ }
ddp->gl_skb[idx] = NULL;
memset((skb->head + sizeof(struct ulp_mem_io)), 0, PPOD_SIZE);
ulp_mem_io_set_hdr(skb, pm_addr);
skb->priority = CPL_PRIORITY_CONTROL;
cxgb3_ofld_send(ddp->tdev, skb);
}
- return 0;
}
static inline int ddp_find_unused_entries(struct cxgb3i_ddp_info *ddp,
@@ -211,7 +199,6 @@ int cxgb3i_ddp_find_page_index(unsigned long pgsz)
ddp_log_debug("ddp page size 0x%lx not supported.\n", pgsz);
return DDP_PGIDX_MAX;
}
-EXPORT_SYMBOL_GPL(cxgb3i_ddp_find_page_index);
static inline void ddp_gl_unmap(struct pci_dev *pdev,
struct cxgb3i_gather_list *gl)
@@ -334,7 +321,6 @@ error_out:
kfree(gl);
return NULL;
}
-EXPORT_SYMBOL_GPL(cxgb3i_ddp_make_gl);
/**
* cxgb3i_ddp_release_gl - release a page buffer list
@@ -348,7 +334,6 @@ void cxgb3i_ddp_release_gl(struct cxgb3i_gather_list *gl,
ddp_gl_unmap(pdev, gl);
kfree(gl);
}
-EXPORT_SYMBOL_GPL(cxgb3i_ddp_release_gl);
/**
* cxgb3i_ddp_tag_reserve - set up ddp for a data transfer
@@ -430,7 +415,6 @@ unmark_entries:
ddp_unmark_entries(ddp, idx, npods);
return err;
}
-EXPORT_SYMBOL_GPL(cxgb3i_ddp_tag_reserve);
/**
* cxgb3i_ddp_tag_release - release a ddp tag
@@ -453,22 +437,21 @@ void cxgb3i_ddp_tag_release(struct t3cdev *tdev, u32 tag)
struct cxgb3i_gather_list *gl = ddp->gl_map[idx];
unsigned int npods;
- if (!gl) {
- ddp_log_error("release ddp 0x%x, idx 0x%x, gl NULL.\n",
- tag, idx);
+ if (!gl || !gl->nelem) {
+ ddp_log_error("release 0x%x, idx 0x%x, gl 0x%p, %u.\n",
+ tag, idx, gl, gl ? gl->nelem : 0);
return;
}
npods = (gl->nelem + PPOD_PAGES_MAX - 1) >> PPOD_PAGES_SHIFT;
ddp_log_debug("ddp tag 0x%x, release idx 0x%x, npods %u.\n",
tag, idx, npods);
- clear_ddp_map(ddp, idx, npods);
+ clear_ddp_map(ddp, tag, idx, npods);
ddp_unmark_entries(ddp, idx, npods);
cxgb3i_ddp_release_gl(gl, ddp->pdev);
} else
ddp_log_error("ddp tag 0x%x, idx 0x%x > max 0x%x.\n",
tag, idx, ddp->nppods);
}
-EXPORT_SYMBOL_GPL(cxgb3i_ddp_tag_release);
static int setup_conn_pgidx(struct t3cdev *tdev, unsigned int tid, int pg_idx,
int reply)
@@ -509,7 +492,6 @@ int cxgb3i_setup_conn_host_pagesize(struct t3cdev *tdev, unsigned int tid,
{
return setup_conn_pgidx(tdev, tid, page_idx, reply);
}
-EXPORT_SYMBOL_GPL(cxgb3i_setup_conn_host_pagesize);
/**
* cxgb3i_setup_conn_pagesize - setup the conn.'s ddp page size
@@ -526,7 +508,6 @@ int cxgb3i_setup_conn_pagesize(struct t3cdev *tdev, unsigned int tid,
return setup_conn_pgidx(tdev, tid, pgidx, reply);
}
-EXPORT_SYMBOL_GPL(cxgb3i_setup_conn_pagesize);
/**
* cxgb3i_setup_conn_digest - setup conn. digest setting
@@ -562,26 +543,104 @@ int cxgb3i_setup_conn_digest(struct t3cdev *tdev, unsigned int tid,
cxgb3_ofld_send(tdev, skb);
return 0;
}
-EXPORT_SYMBOL_GPL(cxgb3i_setup_conn_digest);
-static int ddp_init(struct t3cdev *tdev)
+
+/**
+ * cxgb3i_adapter_ddp_info - read the adapter's ddp information
+ * @tdev: t3cdev adapter
+ * @tformat: tag format
+ * @txsz: max tx pdu payload size, filled in by this func.
+ * @rxsz: max rx pdu payload size, filled in by this func.
+ * setup the tag format for a given iscsi entity
+ */
+int cxgb3i_adapter_ddp_info(struct t3cdev *tdev,
+ struct cxgb3i_tag_format *tformat,
+ unsigned int *txsz, unsigned int *rxsz)
+{
+ struct cxgb3i_ddp_info *ddp;
+ unsigned char idx_bits;
+
+ if (!tformat)
+ return -EINVAL;
+
+ if (!tdev->ulp_iscsi)
+ return -EINVAL;
+
+ ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;
+
+ idx_bits = 32 - tformat->sw_bits;
+ tformat->rsvd_bits = ddp->idx_bits;
+ tformat->rsvd_shift = PPOD_IDX_SHIFT;
+ tformat->rsvd_mask = (1 << tformat->rsvd_bits) - 1;
+
+ ddp_log_info("tag format: sw %u, rsvd %u,%u, mask 0x%x.\n",
+ tformat->sw_bits, tformat->rsvd_bits,
+ tformat->rsvd_shift, tformat->rsvd_mask);
+
+ *txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
+ ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN);
+ *rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
+ ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN);
+ ddp_log_info("max payload size: %u/%u, %u/%u.\n",
+ *txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz);
+ return 0;
+}
+
+/**
+ * cxgb3i_ddp_cleanup - release the cxgb3 adapter's ddp resource
+ * @tdev: t3cdev adapter
+ * release all the resource held by the ddp pagepod manager for a given
+ * adapter if needed
+ */
+void cxgb3i_ddp_cleanup(struct t3cdev *tdev)
+{
+ int i = 0;
+ struct cxgb3i_ddp_info *ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;
+
+ ddp_log_info("t3dev 0x%p, release ddp 0x%p.\n", tdev, ddp);
+
+ if (ddp) {
+ tdev->ulp_iscsi = NULL;
+ while (i < ddp->nppods) {
+ struct cxgb3i_gather_list *gl = ddp->gl_map[i];
+ if (gl) {
+ int npods = (gl->nelem + PPOD_PAGES_MAX - 1)
+ >> PPOD_PAGES_SHIFT;
+ ddp_log_info("t3dev 0x%p, ddp %d + %d.\n",
+ tdev, i, npods);
+ kfree(gl);
+ ddp_free_gl_skb(ddp, i, npods);
+ i += npods;
+ } else
+ i++;
+ }
+ cxgb3i_free_big_mem(ddp);
+ }
+}
+
+/**
+ * ddp_init - initialize the cxgb3 adapter's ddp resource
+ * @tdev: t3cdev adapter
+ * initialize the ddp pagepod manager for a given adapter
+ */
+static void ddp_init(struct t3cdev *tdev)
{
struct cxgb3i_ddp_info *ddp;
struct ulp_iscsi_info uinfo;
unsigned int ppmax, bits;
int i, err;
- static int vers_printed;
- if (!vers_printed) {
- printk(KERN_INFO "%s", version);
- vers_printed = 1;
+ if (tdev->ulp_iscsi) {
+ ddp_log_warn("t3dev 0x%p, ddp 0x%p already set up.\n",
+ tdev, tdev->ulp_iscsi);
+ return;
}
err = tdev->ctl(tdev, ULP_ISCSI_GET_PARAMS, &uinfo);
if (err < 0) {
ddp_log_error("%s, failed to get iscsi param err=%d.\n",
tdev->name, err);
- return err;
+ return;
}
ppmax = (uinfo.ulimit - uinfo.llimit + 1) >> PPOD_SIZE_SHIFT;
@@ -598,7 +657,7 @@ static int ddp_init(struct t3cdev *tdev)
if (!ddp) {
ddp_log_warn("%s unable to alloc ddp 0x%d, ddp disabled.\n",
tdev->name, ppmax);
- return 0;
+ return;
}
ddp->gl_map = (struct cxgb3i_gather_list **)(ddp + 1);
ddp->gl_skb = (struct sk_buff **)(((char *)ddp->gl_map) +
@@ -632,142 +691,26 @@ static int ddp_init(struct t3cdev *tdev)
tdev->ulp_iscsi = ddp;
- /* add to the list */
- write_lock(&cxgb3i_ddp_rwlock);
- list_add_tail(&ddp->list, &cxgb3i_ddp_list);
- write_unlock(&cxgb3i_ddp_rwlock);
-
- ddp_log_info("nppods %u (0x%x ~ 0x%x), bits %u, mask 0x%x,0x%x "
- "pkt %u/%u, %u/%u.\n",
- ppmax, ddp->llimit, ddp->ulimit, ddp->idx_bits,
- ddp->idx_mask, ddp->rsvd_tag_mask,
- ddp->max_txsz, uinfo.max_txsz,
+ ddp_log_info("tdev 0x%p, nppods %u, bits %u, mask 0x%x,0x%x pkt %u/%u,"
+ " %u/%u.\n",
+ tdev, ppmax, ddp->idx_bits, ddp->idx_mask,
+ ddp->rsvd_tag_mask, ddp->max_txsz, uinfo.max_txsz,
ddp->max_rxsz, uinfo.max_rxsz);
- return 0;
+ return;
free_ddp_map:
cxgb3i_free_big_mem(ddp);
- return err;
-}
-
-/**
- * cxgb3i_adapter_ddp_init - initialize the adapter's ddp resource
- * @tdev: t3cdev adapter
- * @tformat: tag format
- * @txsz: max tx pdu payload size, filled in by this func.
- * @rxsz: max rx pdu payload size, filled in by this func.
- * initialize the ddp pagepod manager for a given adapter if needed and
- * setup the tag format for a given iscsi entity
- */
-int cxgb3i_adapter_ddp_init(struct t3cdev *tdev,
- struct cxgb3i_tag_format *tformat,
- unsigned int *txsz, unsigned int *rxsz)
-{
- struct cxgb3i_ddp_info *ddp;
- unsigned char idx_bits;
-
- if (!tformat)
- return -EINVAL;
-
- if (!tdev->ulp_iscsi) {
- int err = ddp_init(tdev);
- if (err < 0)
- return err;
- }
- ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;
-
- idx_bits = 32 - tformat->sw_bits;
- tformat->rsvd_bits = ddp->idx_bits;
- tformat->rsvd_shift = PPOD_IDX_SHIFT;
- tformat->rsvd_mask = (1 << tformat->rsvd_bits) - 1;
-
- ddp_log_info("tag format: sw %u, rsvd %u,%u, mask 0x%x.\n",
- tformat->sw_bits, tformat->rsvd_bits,
- tformat->rsvd_shift, tformat->rsvd_mask);
-
- *txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
- ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN);
- *rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
- ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN);
- ddp_log_info("max payload size: %u/%u, %u/%u.\n",
- *txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz);
- return 0;
-}
-EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_init);
-
-static void ddp_release(struct cxgb3i_ddp_info *ddp)
-{
- int i = 0;
- struct t3cdev *tdev = ddp->tdev;
-
- tdev->ulp_iscsi = NULL;
- while (i < ddp->nppods) {
- struct cxgb3i_gather_list *gl = ddp->gl_map[i];
- if (gl) {
- int npods = (gl->nelem + PPOD_PAGES_MAX - 1)
- >> PPOD_PAGES_SHIFT;
-
- kfree(gl);
- ddp_free_gl_skb(ddp, i, npods);
- } else
- i++;
- }
- cxgb3i_free_big_mem(ddp);
-}
-
-/**
- * cxgb3i_adapter_ddp_cleanup - release the adapter's ddp resource
- * @tdev: t3cdev adapter
- * release all the resource held by the ddp pagepod manager for a given
- * adapter if needed
- */
-void cxgb3i_adapter_ddp_cleanup(struct t3cdev *tdev)
-{
- struct cxgb3i_ddp_info *ddp;
-
- /* remove from the list */
- write_lock(&cxgb3i_ddp_rwlock);
- list_for_each_entry(ddp, &cxgb3i_ddp_list, list) {
- if (ddp->tdev == tdev) {
- list_del(&ddp->list);
- break;
- }
- }
- write_unlock(&cxgb3i_ddp_rwlock);
-
- if (ddp)
- ddp_release(ddp);
-}
-EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_cleanup);
-
-/**
- * cxgb3i_ddp_init_module - module init entry point
- * initialize any driver wide global data structures
- */
-static int __init cxgb3i_ddp_init_module(void)
-{
- page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE);
- ddp_log_info("system PAGE_SIZE %lu, ddp idx %u.\n",
- PAGE_SIZE, page_idx);
- return 0;
}
/**
- * cxgb3i_ddp_exit_module - module cleanup/exit entry point
- * go through the ddp list and release any resource held.
+ * cxgb3i_ddp_init - initialize ddp functions
*/
-static void __exit cxgb3i_ddp_exit_module(void)
+void cxgb3i_ddp_init(struct t3cdev *tdev)
{
- struct cxgb3i_ddp_info *ddp;
-
- /* release all ddp manager if there is any */
- write_lock(&cxgb3i_ddp_rwlock);
- list_for_each_entry(ddp, &cxgb3i_ddp_list, list) {
- list_del(&ddp->list);
- ddp_release(ddp);
+ if (page_idx == DDP_PGIDX_MAX) {
+ page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE);
+ ddp_log_info("system PAGE_SIZE %lu, ddp idx %u.\n",
+ PAGE_SIZE, page_idx);
}
- write_unlock(&cxgb3i_ddp_rwlock);
+ ddp_init(tdev);
}
-
-module_init(cxgb3i_ddp_init_module);
-module_exit(cxgb3i_ddp_exit_module);
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.h b/drivers/scsi/cxgb3i/cxgb3i_ddp.h
index 75a63a81e87..0d296de7cf3 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.h
@@ -301,7 +301,9 @@ int cxgb3i_setup_conn_pagesize(struct t3cdev *, unsigned int tid, int reply,
int cxgb3i_setup_conn_digest(struct t3cdev *, unsigned int tid,
int hcrc, int dcrc, int reply);
int cxgb3i_ddp_find_page_index(unsigned long pgsz);
-int cxgb3i_adapter_ddp_init(struct t3cdev *, struct cxgb3i_tag_format *,
+int cxgb3i_adapter_ddp_info(struct t3cdev *, struct cxgb3i_tag_format *,
unsigned int *txsz, unsigned int *rxsz);
-void cxgb3i_adapter_ddp_cleanup(struct t3cdev *);
+
+void cxgb3i_ddp_init(struct t3cdev *);
+void cxgb3i_ddp_cleanup(struct t3cdev *);
#endif
diff --git a/drivers/scsi/cxgb3i/cxgb3i_init.c b/drivers/scsi/cxgb3i/cxgb3i_init.c
index 1ce9f244e46..042d9bce991 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_init.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_init.c
@@ -12,8 +12,8 @@
#include "cxgb3i.h"
#define DRV_MODULE_NAME "cxgb3i"
-#define DRV_MODULE_VERSION "1.0.1"
-#define DRV_MODULE_RELDATE "Jan. 2009"
+#define DRV_MODULE_VERSION "1.0.2"
+#define DRV_MODULE_RELDATE "Mar. 2009"
static char version[] =
"Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME
@@ -26,6 +26,7 @@ MODULE_VERSION(DRV_MODULE_VERSION);
static void open_s3_dev(struct t3cdev *);
static void close_s3_dev(struct t3cdev *);
+static void s3_err_handler(struct t3cdev *tdev, u32 status, u32 error);
static cxgb3_cpl_handler_func cxgb3i_cpl_handlers[NUM_CPL_CMDS];
static struct cxgb3_client t3c_client = {
@@ -33,6 +34,7 @@ static struct cxgb3_client t3c_client = {
.handlers = cxgb3i_cpl_handlers,
.add = open_s3_dev,
.remove = close_s3_dev,
+ .err_handler = s3_err_handler,
};
/**
@@ -48,8 +50,9 @@ static void open_s3_dev(struct t3cdev *t3dev)
vers_printed = 1;
}
+ cxgb3i_ddp_init(t3dev);
cxgb3i_sdev_add(t3dev, &t3c_client);
- cxgb3i_adapter_add(t3dev);
+ cxgb3i_adapter_open(t3dev);
}
/**
@@ -58,8 +61,28 @@ static void open_s3_dev(struct t3cdev *t3dev)
*/
static void close_s3_dev(struct t3cdev *t3dev)
{
- cxgb3i_adapter_remove(t3dev);
+ cxgb3i_adapter_close(t3dev);
cxgb3i_sdev_remove(t3dev);
+ cxgb3i_ddp_cleanup(t3dev);
+}
+
+static void s3_err_handler(struct t3cdev *tdev, u32 status, u32 error)
+{
+ struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(tdev);
+
+ cxgb3i_log_info("snic 0x%p, tdev 0x%p, status 0x%x, err 0x%x.\n",
+ snic, tdev, status, error);
+ if (!snic)
+ return;
+
+ switch (status) {
+ case OFFLOAD_STATUS_DOWN:
+ snic->flags |= CXGB3I_ADAPTER_FLAG_RESET;
+ break;
+ case OFFLOAD_STATUS_UP:
+ snic->flags &= ~CXGB3I_ADAPTER_FLAG_RESET;
+ break;
+ }
}
/**
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
index e185dedc4c1..fff8e432764 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
@@ -53,36 +53,52 @@ static LIST_HEAD(cxgb3i_snic_list);
static DEFINE_RWLOCK(cxgb3i_snic_rwlock);
/**
- * cxgb3i_adapter_add - init a s3 adapter structure and any h/w settings
- * @t3dev: t3cdev adapter
- * return the resulting cxgb3i_adapter struct
+ * cxgb3i_adpater_find_by_tdev - find the cxgb3i_adapter structure via t3cdev
+ * @tdev: t3cdev pointer
*/
-struct cxgb3i_adapter *cxgb3i_adapter_add(struct t3cdev *t3dev)
+struct cxgb3i_adapter *cxgb3i_adapter_find_by_tdev(struct t3cdev *tdev)
{
struct cxgb3i_adapter *snic;
- struct adapter *adapter = tdev2adap(t3dev);
- int i;
- snic = kzalloc(sizeof(*snic), GFP_KERNEL);
- if (!snic) {
- cxgb3i_api_debug("cxgb3 %s, OOM.\n", t3dev->name);
- return NULL;
+ read_lock(&cxgb3i_snic_rwlock);
+ list_for_each_entry(snic, &cxgb3i_snic_list, list_head) {
+ if (snic->tdev == tdev) {
+ read_unlock(&cxgb3i_snic_rwlock);
+ return snic;
+ }
}
- spin_lock_init(&snic->lock);
+ read_unlock(&cxgb3i_snic_rwlock);
+ return NULL;
+}
+
+static inline int adapter_update(struct cxgb3i_adapter *snic)
+{
+ cxgb3i_log_info("snic 0x%p, t3dev 0x%p, updating.\n",
+ snic, snic->tdev);
+ return cxgb3i_adapter_ddp_info(snic->tdev, &snic->tag_format,
+ &snic->tx_max_size,
+ &snic->rx_max_size);
+}
+
+static int adapter_add(struct cxgb3i_adapter *snic)
+{
+ struct t3cdev *t3dev = snic->tdev;
+ struct adapter *adapter = tdev2adap(t3dev);
+ int i, err;
- snic->tdev = t3dev;
snic->pdev = adapter->pdev;
snic->tag_format.sw_bits = sw_tag_idx_bits + sw_tag_age_bits;
- if (cxgb3i_adapter_ddp_init(t3dev, &snic->tag_format,
+ err = cxgb3i_adapter_ddp_info(t3dev, &snic->tag_format,
&snic->tx_max_size,
- &snic->rx_max_size) < 0)
- goto free_snic;
+ &snic->rx_max_size);
+ if (err < 0)
+ return err;
for_each_port(adapter, i) {
snic->hba[i] = cxgb3i_hba_host_add(snic, adapter->port[i]);
if (!snic->hba[i])
- goto ulp_cleanup;
+ return -EINVAL;
}
snic->hba_cnt = adapter->params.nports;
@@ -91,46 +107,71 @@ struct cxgb3i_adapter *cxgb3i_adapter_add(struct t3cdev *t3dev)
list_add_tail(&snic->list_head, &cxgb3i_snic_list);
write_unlock(&cxgb3i_snic_rwlock);
- return snic;
+ cxgb3i_log_info("t3dev 0x%p open, snic 0x%p, %u scsi hosts added.\n",
+ t3dev, snic, snic->hba_cnt);
+ return 0;
+}
-ulp_cleanup:
- cxgb3i_adapter_ddp_cleanup(t3dev);
-free_snic:
- kfree(snic);
- return NULL;
+/**
+ * cxgb3i_adapter_open - init a s3 adapter structure and any h/w settings
+ * @t3dev: t3cdev adapter
+ */
+void cxgb3i_adapter_open(struct t3cdev *t3dev)
+{
+ struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(t3dev);
+ int err;
+
+ if (snic)
+ err = adapter_update(snic);
+ else {
+ snic = kzalloc(sizeof(*snic), GFP_KERNEL);
+ if (snic) {
+ spin_lock_init(&snic->lock);
+ snic->tdev = t3dev;
+ err = adapter_add(snic);
+ } else
+ err = -ENOMEM;
+ }
+
+ if (err < 0) {
+ cxgb3i_log_info("snic 0x%p, f 0x%x, t3dev 0x%p open, err %d.\n",
+ snic, snic ? snic->flags : 0, t3dev, err);
+ if (snic) {
+ snic->flags &= ~CXGB3I_ADAPTER_FLAG_RESET;
+ cxgb3i_adapter_close(t3dev);
+ }
+ }
}
/**
- * cxgb3i_adapter_remove - release the resources held and cleanup h/w settings
+ * cxgb3i_adapter_close - release the resources held and cleanup h/w settings
* @t3dev: t3cdev adapter
*/
-void cxgb3i_adapter_remove(struct t3cdev *t3dev)
+void cxgb3i_adapter_close(struct t3cdev *t3dev)
{
+ struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(t3dev);
int i;
- struct cxgb3i_adapter *snic;
+
+ if (!snic || snic->flags & CXGB3I_ADAPTER_FLAG_RESET) {
+ cxgb3i_log_info("t3dev 0x%p close, snic 0x%p, f 0x%x.\n",
+ t3dev, snic, snic ? snic->flags : 0);
+ return;
+ }
/* remove from the list */
write_lock(&cxgb3i_snic_rwlock);
- list_for_each_entry(snic, &cxgb3i_snic_list, list_head) {
- if (snic->tdev == t3dev) {
- list_del(&snic->list_head);
- break;
- }
- }
+ list_del(&snic->list_head);
write_unlock(&cxgb3i_snic_rwlock);
- if (snic) {
- for (i = 0; i < snic->hba_cnt; i++) {
- if (snic->hba[i]) {
- cxgb3i_hba_host_remove(snic->hba[i]);
- snic->hba[i] = NULL;
- }
+ for (i = 0; i < snic->hba_cnt; i++) {
+ if (snic->hba[i]) {
+ cxgb3i_hba_host_remove(snic->hba[i]);
+ snic->hba[i] = NULL;
}
-
- /* release ddp resources */
- cxgb3i_adapter_ddp_cleanup(snic->tdev);
- kfree(snic);
}
+ cxgb3i_log_info("t3dev 0x%p close, snic 0x%p, %u scsi hosts removed.\n",
+ t3dev, snic, snic->hba_cnt);
+ kfree(snic);
}
/**
@@ -170,7 +211,8 @@ struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *snic,
shost = iscsi_host_alloc(&cxgb3i_host_template,
sizeof(struct cxgb3i_hba), 1);
if (!shost) {
- cxgb3i_log_info("iscsi_host_alloc failed.\n");
+ cxgb3i_log_info("snic 0x%p, ndev 0x%p, host_alloc failed.\n",
+ snic, ndev);
return NULL;
}
@@ -188,7 +230,8 @@ struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *snic,
pci_dev_get(snic->pdev);
err = iscsi_host_add(shost, &snic->pdev->dev);
if (err) {
- cxgb3i_log_info("iscsi_host_add failed.\n");
+ cxgb3i_log_info("snic 0x%p, ndev 0x%p, host_add failed.\n",
+ snic, ndev);
goto pci_dev_put;
}
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c
index c2e434e54e2..4d8654cdbda 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c
@@ -94,29 +94,30 @@ static int c3cn_get_port(struct s3_conn *c3cn, struct cxgb3i_sdev_data *cdata)
if (!cdata)
goto error_out;
- if (c3cn->saddr.sin_port != 0) {
- idx = ntohs(c3cn->saddr.sin_port) - cxgb3_sport_base;
- if (idx < 0 || idx >= cxgb3_max_connect)
- return 0;
- if (!test_and_set_bit(idx, cdata->sport_map))
- return -EADDRINUSE;
+ if (c3cn->saddr.sin_port) {
+ cxgb3i_log_error("connect, sin_port NON-ZERO %u.\n",
+ c3cn->saddr.sin_port);
+ return -EADDRINUSE;
}
- /* the sport_map_next may not be accurate but that is okay, sport_map
- should be */
- start = idx = cdata->sport_map_next;
+ spin_lock_bh(&cdata->lock);
+ start = idx = cdata->sport_next;
do {
if (++idx >= cxgb3_max_connect)
idx = 0;
- if (!(test_and_set_bit(idx, cdata->sport_map))) {
+ if (!cdata->sport_conn[idx]) {
c3cn->saddr.sin_port = htons(cxgb3_sport_base + idx);
- cdata->sport_map_next = idx;
+ cdata->sport_next = idx;
+ cdata->sport_conn[idx] = c3cn;
+ spin_unlock_bh(&cdata->lock);
+
c3cn_conn_debug("%s reserve port %u.\n",
cdata->cdev->name,
cxgb3_sport_base + idx);
return 0;
}
} while (idx != start);
+ spin_unlock_bh(&cdata->lock);
error_out:
return -EADDRNOTAVAIL;
@@ -124,15 +125,19 @@ error_out:
static void c3cn_put_port(struct s3_conn *c3cn)
{
- struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(c3cn->cdev);
+ if (!c3cn->cdev)
+ return;
if (c3cn->saddr.sin_port) {
+ struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(c3cn->cdev);
int idx = ntohs(c3cn->saddr.sin_port) - cxgb3_sport_base;
c3cn->saddr.sin_port = 0;
if (idx < 0 || idx >= cxgb3_max_connect)
return;
- clear_bit(idx, cdata->sport_map);
+ spin_lock_bh(&cdata->lock);
+ cdata->sport_conn[idx] = NULL;
+ spin_unlock_bh(&cdata->lock);
c3cn_conn_debug("%s, release port %u.\n",
cdata->cdev->name, cxgb3_sport_base + idx);
}
@@ -1305,11 +1310,7 @@ static void c3cn_release_offload_resources(struct s3_conn *c3cn)
struct t3cdev *cdev = c3cn->cdev;
unsigned int tid = c3cn->tid;
- if (!cdev)
- return;
-
c3cn->qset = 0;
-
c3cn_free_cpl_skbs(c3cn);
if (c3cn->wr_avail != c3cn->wr_max) {
@@ -1317,18 +1318,22 @@ static void c3cn_release_offload_resources(struct s3_conn *c3cn)
reset_wr_list(c3cn);
}
- if (c3cn->l2t) {
- l2t_release(L2DATA(cdev), c3cn->l2t);
- c3cn->l2t = NULL;
- }
-
- if (c3cn->state == C3CN_STATE_CONNECTING) /* we have ATID */
- s3_free_atid(cdev, tid);
- else { /* we have TID */
- cxgb3_remove_tid(cdev, (void *)c3cn, tid);
- c3cn_put(c3cn);
+ if (cdev) {
+ if (c3cn->l2t) {
+ l2t_release(L2DATA(cdev), c3cn->l2t);
+ c3cn->l2t = NULL;
+ }
+ if (c3cn->state == C3CN_STATE_CONNECTING)
+ /* we have ATID */
+ s3_free_atid(cdev, tid);
+ else {
+ /* we have TID */
+ cxgb3_remove_tid(cdev, (void *)c3cn, tid);
+ c3cn_put(c3cn);
+ }
}
+ c3cn->dst_cache = NULL;
c3cn->cdev = NULL;
}
@@ -1417,17 +1422,18 @@ static void c3cn_active_close(struct s3_conn *c3cn)
}
/**
- * cxgb3i_c3cn_release - close and release an iscsi tcp connection
+ * cxgb3i_c3cn_release - close and release an iscsi tcp connection and any
+ * resource held
* @c3cn: the iscsi tcp connection
*/
void cxgb3i_c3cn_release(struct s3_conn *c3cn)
{
c3cn_conn_debug("c3cn 0x%p, s %u, f 0x%lx.\n",
c3cn, c3cn->state, c3cn->flags);
- if (likely(c3cn->state != C3CN_STATE_CONNECTING))
- c3cn_active_close(c3cn);
- else
+ if (unlikely(c3cn->state == C3CN_STATE_CONNECTING))
c3cn_set_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED);
+ else if (likely(c3cn->state != C3CN_STATE_CLOSED))
+ c3cn_active_close(c3cn);
c3cn_put(c3cn);
}
@@ -1656,7 +1662,6 @@ int cxgb3i_c3cn_connect(struct s3_conn *c3cn, struct sockaddr_in *usin)
c3cn_set_state(c3cn, C3CN_STATE_CLOSED);
ip_rt_put(rt);
c3cn_put_port(c3cn);
- c3cn->daddr.sin_port = 0;
return err;
}
@@ -1776,10 +1781,25 @@ out_err:
static void sdev_data_cleanup(struct cxgb3i_sdev_data *cdata)
{
struct adap_ports *ports = &cdata->ports;
+ struct s3_conn *c3cn;
int i;
+ for (i = 0; i < cxgb3_max_connect; i++) {
+ if (cdata->sport_conn[i]) {
+ c3cn = cdata->sport_conn[i];
+ cdata->sport_conn[i] = NULL;
+
+ spin_lock_bh(&c3cn->lock);
+ c3cn->cdev = NULL;
+ c3cn_set_flag(c3cn, C3CN_OFFLOAD_DOWN);
+ c3cn_closed(c3cn);
+ spin_unlock_bh(&c3cn->lock);
+ }
+ }
+
for (i = 0; i < ports->nports; i++)
NDEV2CDATA(ports->lldevs[i]) = NULL;
+
cxgb3i_free_big_mem(cdata);
}
@@ -1821,21 +1841,27 @@ void cxgb3i_sdev_add(struct t3cdev *cdev, struct cxgb3_client *client)
struct cxgb3i_sdev_data *cdata;
struct ofld_page_info rx_page_info;
unsigned int wr_len;
- int mapsize = DIV_ROUND_UP(cxgb3_max_connect,
- 8 * sizeof(unsigned long));
+ int mapsize = cxgb3_max_connect * sizeof(struct s3_conn *);
int i;
cdata = cxgb3i_alloc_big_mem(sizeof(*cdata) + mapsize, GFP_KERNEL);
- if (!cdata)
+ if (!cdata) {
+ cxgb3i_log_warn("t3dev 0x%p, offload up, OOM %d.\n",
+ cdev, mapsize);
return;
+ }
if (cdev->ctl(cdev, GET_WR_LEN, &wr_len) < 0 ||
cdev->ctl(cdev, GET_PORTS, &cdata->ports) < 0 ||
- cdev->ctl(cdev, GET_RX_PAGE_INFO, &rx_page_info) < 0)
+ cdev->ctl(cdev, GET_RX_PAGE_INFO, &rx_page_info) < 0) {
+ cxgb3i_log_warn("t3dev 0x%p, offload up, ioctl failed.\n",
+ cdev);
goto free_cdata;
+ }
s3_init_wr_tab(wr_len);
+ spin_lock_init(&cdata->lock);
INIT_LIST_HEAD(&cdata->list);
cdata->cdev = cdev;
cdata->client = client;
@@ -1847,6 +1873,7 @@ void cxgb3i_sdev_add(struct t3cdev *cdev, struct cxgb3_client *client)
list_add_tail(&cdata->list, &cdata_list);
write_unlock(&cdata_rwlock);
+ cxgb3i_log_info("t3dev 0x%p, offload up, added.\n", cdev);
return;
free_cdata:
@@ -1861,6 +1888,8 @@ void cxgb3i_sdev_remove(struct t3cdev *cdev)
{
struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(cdev);
+ cxgb3i_log_info("t3dev 0x%p, offload down, remove.\n", cdev);
+
write_lock(&cdata_rwlock);
list_del(&cdata->list);
write_unlock(&cdata_rwlock);
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.h b/drivers/scsi/cxgb3i/cxgb3i_offload.h
index 275f23f16eb..ebfca960c0a 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.h
@@ -16,7 +16,7 @@
#define _CXGB3I_OFFLOAD_H
#include <linux/skbuff.h>
-#include <net/tcp.h>
+#include <linux/in.h>
#include "common.h"
#include "adapter.h"
@@ -135,11 +135,11 @@ enum c3cn_flags {
C3CN_ABORT_RPL_PENDING, /* expecting an abort reply */
C3CN_TX_DATA_SENT, /* already sent a TX_DATA WR */
C3CN_ACTIVE_CLOSE_NEEDED, /* need to be closed */
+ C3CN_OFFLOAD_DOWN /* offload function off */
};
/**
* cxgb3i_sdev_data - Per adapter data.
- *
* Linked off of each Ethernet device port on the adapter.
* Also available via the t3cdev structure since we have pointers to our port
* net_device's there ...
@@ -148,16 +148,17 @@ enum c3cn_flags {
* @cdev: t3cdev adapter
* @client: CPL client pointer
* @ports: array of adapter ports
- * @sport_map_next: next index into the port map
- * @sport_map: source port map
+ * @sport_next: next port
+ * @sport_conn: source port connection
*/
struct cxgb3i_sdev_data {
struct list_head list;
struct t3cdev *cdev;
struct cxgb3_client *client;
struct adap_ports ports;
- unsigned int sport_map_next;
- unsigned long sport_map[0];
+ spinlock_t lock;
+ unsigned int sport_next;
+ struct s3_conn *sport_conn[0];
};
#define NDEV2CDATA(ndev) (*(struct cxgb3i_sdev_data **)&(ndev)->ec_ptr)
#define CXGB3_SDEV_DATA(cdev) NDEV2CDATA((cdev)->lldev)
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 6194ed5d02c..b6af63ca980 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -1014,15 +1014,15 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
* See if we should enable dma64 mode.
*/
if (sizeof(dma_addr_t) > 4 &&
- pci_set_dma_mask(pDev, DMA_64BIT_MASK) == 0) {
- if (dma_get_required_mask(&pDev->dev) > DMA_32BIT_MASK)
+ pci_set_dma_mask(pDev, DMA_BIT_MASK(64)) == 0) {
+ if (dma_get_required_mask(&pDev->dev) > DMA_BIT_MASK(32))
dma64 = 1;
}
- if (!dma64 && pci_set_dma_mask(pDev, DMA_32BIT_MASK) != 0)
+ if (!dma64 && pci_set_dma_mask(pDev, DMA_BIT_MASK(32)) != 0)
return -EINVAL;
/* adapter only supports message blocks below 4GB */
- pci_set_consistent_dma_mask(pDev, DMA_32BIT_MASK);
+ pci_set_consistent_dma_mask(pDev, DMA_BIT_MASK(32));
base_addr0_phys = pci_resource_start(pDev,0);
hba_map0_area_size = pci_resource_len(pDev,0);
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index 976cdd5c94e..be5099dd94b 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -1426,7 +1426,7 @@ static int port_detect(unsigned long port_base, unsigned int j,
if (ha->pdev) {
pci_set_master(ha->pdev);
- if (pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK))
+ if (pci_set_dma_mask(ha->pdev, DMA_BIT_MASK(32)))
printk("%s: warning, pci_set_dma_mask failed.\n",
ha->board_name);
}
diff --git a/drivers/scsi/fcoe/Makefile b/drivers/scsi/fcoe/Makefile
index b78da06d7c0..950f27615c7 100644
--- a/drivers/scsi/fcoe/Makefile
+++ b/drivers/scsi/fcoe/Makefile
@@ -1,8 +1,2 @@
-# $Id: Makefile
-
obj-$(CONFIG_FCOE) += fcoe.o
-
-fcoe-y := \
- libfcoe.o \
- fcoe_sw.o \
- fc_transport_fcoe.o
+obj-$(CONFIG_LIBFCOE) += libfcoe.o
diff --git a/drivers/scsi/fcoe/fc_transport_fcoe.c b/drivers/scsi/fcoe/fc_transport_fcoe.c
deleted file mode 100644
index 8862758006c..00000000000
--- a/drivers/scsi/fcoe/fc_transport_fcoe.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Maintained at www.Open-FCoE.org
- */
-
-#include <linux/pci.h>
-#include <scsi/libfcoe.h>
-#include <scsi/fc_transport_fcoe.h>
-
-/* internal fcoe transport */
-struct fcoe_transport_internal {
- struct fcoe_transport *t;
- struct net_device *netdev;
- struct list_head list;
-};
-
-/* fcoe transports list and its lock */
-static LIST_HEAD(fcoe_transports);
-static DEFINE_MUTEX(fcoe_transports_lock);
-
-/**
- * fcoe_transport_default() - Returns ptr to the default transport fcoe_sw
- */
-struct fcoe_transport *fcoe_transport_default(void)
-{
- return &fcoe_sw_transport;
-}
-
-/**
- * fcoe_transport_to_pcidev() - get the pci dev from a netdev
- * @netdev: the netdev that pci dev will be retrived from
- *
- * Returns: NULL or the corrsponding pci_dev
- */
-struct pci_dev *fcoe_transport_pcidev(const struct net_device *netdev)
-{
- if (!netdev->dev.parent)
- return NULL;
- return to_pci_dev(netdev->dev.parent);
-}
-
-/**
- * fcoe_transport_device_lookup() - Lookup a transport
- * @netdev: the netdev the transport to be attached to
- *
- * This will look for existing offload driver, if not found, it falls back to
- * the default sw hba (fcoe_sw) as its fcoe transport.
- *
- * Returns: 0 for success
- */
-static struct fcoe_transport_internal *
-fcoe_transport_device_lookup(struct fcoe_transport *t,
- struct net_device *netdev)
-{
- struct fcoe_transport_internal *ti;
-
- /* assign the transpor to this device */
- mutex_lock(&t->devlock);
- list_for_each_entry(ti, &t->devlist, list) {
- if (ti->netdev == netdev) {
- mutex_unlock(&t->devlock);
- return ti;
- }
- }
- mutex_unlock(&t->devlock);
- return NULL;
-}
-/**
- * fcoe_transport_device_add() - Assign a transport to a device
- * @netdev: the netdev the transport to be attached to
- *
- * This will look for existing offload driver, if not found, it falls back to
- * the default sw hba (fcoe_sw) as its fcoe transport.
- *
- * Returns: 0 for success
- */
-static int fcoe_transport_device_add(struct fcoe_transport *t,
- struct net_device *netdev)
-{
- struct fcoe_transport_internal *ti;
-
- ti = fcoe_transport_device_lookup(t, netdev);
- if (ti) {
- printk(KERN_DEBUG "fcoe_transport_device_add:"
- "device %s is already added to transport %s\n",
- netdev->name, t->name);
- return -EEXIST;
- }
- /* allocate an internal struct to host the netdev and the list */
- ti = kzalloc(sizeof(*ti), GFP_KERNEL);
- if (!ti)
- return -ENOMEM;
-
- ti->t = t;
- ti->netdev = netdev;
- INIT_LIST_HEAD(&ti->list);
- dev_hold(ti->netdev);
-
- mutex_lock(&t->devlock);
- list_add(&ti->list, &t->devlist);
- mutex_unlock(&t->devlock);
-
- printk(KERN_DEBUG "fcoe_transport_device_add:"
- "device %s added to transport %s\n",
- netdev->name, t->name);
-
- return 0;
-}
-
-/**
- * fcoe_transport_device_remove() - Remove a device from its transport
- * @netdev: the netdev the transport to be attached to
- *
- * This removes the device from the transport so the given transport will
- * not manage this device any more
- *
- * Returns: 0 for success
- */
-static int fcoe_transport_device_remove(struct fcoe_transport *t,
- struct net_device *netdev)
-{
- struct fcoe_transport_internal *ti;
-
- ti = fcoe_transport_device_lookup(t, netdev);
- if (!ti) {
- printk(KERN_DEBUG "fcoe_transport_device_remove:"
- "device %s is not managed by transport %s\n",
- netdev->name, t->name);
- return -ENODEV;
- }
- mutex_lock(&t->devlock);
- list_del(&ti->list);
- mutex_unlock(&t->devlock);
- printk(KERN_DEBUG "fcoe_transport_device_remove:"
- "device %s removed from transport %s\n",
- netdev->name, t->name);
- dev_put(ti->netdev);
- kfree(ti);
- return 0;
-}
-
-/**
- * fcoe_transport_device_remove_all() - Remove all from transport devlist
- *
- * This removes the device from the transport so the given transport will
- * not manage this device any more
- *
- * Returns: 0 for success
- */
-static void fcoe_transport_device_remove_all(struct fcoe_transport *t)
-{
- struct fcoe_transport_internal *ti, *tmp;
-
- mutex_lock(&t->devlock);
- list_for_each_entry_safe(ti, tmp, &t->devlist, list) {
- list_del(&ti->list);
- kfree(ti);
- }
- mutex_unlock(&t->devlock);
-}
-
-/**
- * fcoe_transport_match() - Use the bus device match function to match the hw
- * @t: The fcoe transport to check
- * @netdev: The netdev to match against
- *
- * This function is used to check if the given transport wants to manage the
- * input netdev. if the transports implements the match function, it will be
- * called, o.w. we just compare the pci vendor and device id.
- *
- * Returns: true for match up
- */
-static bool fcoe_transport_match(struct fcoe_transport *t,
- struct net_device *netdev)
-{
- /* match transport by vendor and device id */
- struct pci_dev *pci;
-
- pci = fcoe_transport_pcidev(netdev);
-
- if (pci) {
- printk(KERN_DEBUG "fcoe_transport_match:"
- "%s:%x:%x -- %s:%x:%x\n",
- t->name, t->vendor, t->device,
- netdev->name, pci->vendor, pci->device);
-
- /* if transport supports match */
- if (t->match)
- return t->match(netdev);
-
- /* else just compare the vendor and device id: pci only */
- return (t->vendor == pci->vendor) && (t->device == pci->device);
- }
- return false;
-}
-
-/**
- * fcoe_transport_lookup() - Check if the transport is already registered
- * @t: the transport to be looked up
- *
- * This compares the parent device (pci) vendor and device id
- *
- * Returns: NULL if not found
- *
- * TODO: return default sw transport if no other transport is found
- */
-static struct fcoe_transport *
-fcoe_transport_lookup(struct net_device *netdev)
-{
- struct fcoe_transport *t;
-
- mutex_lock(&fcoe_transports_lock);
- list_for_each_entry(t, &fcoe_transports, list) {
- if (fcoe_transport_match(t, netdev)) {
- mutex_unlock(&fcoe_transports_lock);
- return t;
- }
- }
- mutex_unlock(&fcoe_transports_lock);
-
- printk(KERN_DEBUG "fcoe_transport_lookup:"
- "use default transport for %s\n", netdev->name);
- return fcoe_transport_default();
-}
-
-/**
- * fcoe_transport_register() - Adds a fcoe transport to the fcoe transports list
- * @t: ptr to the fcoe transport to be added
- *
- * Returns: 0 for success
- */
-int fcoe_transport_register(struct fcoe_transport *t)
-{
- struct fcoe_transport *tt;
-
- /* TODO - add fcoe_transport specific initialization here */
- mutex_lock(&fcoe_transports_lock);
- list_for_each_entry(tt, &fcoe_transports, list) {
- if (tt == t) {
- mutex_unlock(&fcoe_transports_lock);
- return -EEXIST;
- }
- }
- list_add_tail(&t->list, &fcoe_transports);
- mutex_unlock(&fcoe_transports_lock);
-
- printk(KERN_DEBUG "fcoe_transport_register:%s\n", t->name);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(fcoe_transport_register);
-
-/**
- * fcoe_transport_unregister() - Remove the tranport fro the fcoe transports list
- * @t: ptr to the fcoe transport to be removed
- *
- * Returns: 0 for success
- */
-int fcoe_transport_unregister(struct fcoe_transport *t)
-{
- struct fcoe_transport *tt, *tmp;
-
- mutex_lock(&fcoe_transports_lock);
- list_for_each_entry_safe(tt, tmp, &fcoe_transports, list) {
- if (tt == t) {
- list_del(&t->list);
- mutex_unlock(&fcoe_transports_lock);
- fcoe_transport_device_remove_all(t);
- printk(KERN_DEBUG "fcoe_transport_unregister:%s\n",
- t->name);
- return 0;
- }
- }
- mutex_unlock(&fcoe_transports_lock);
- return -ENODEV;
-}
-EXPORT_SYMBOL_GPL(fcoe_transport_unregister);
-
-/**
- * fcoe_load_transport_driver() - Load an offload driver by alias name
- * @netdev: the target net device
- *
- * Requests for an offload driver module as the fcoe transport, if fails, it
- * falls back to use the SW HBA (fcoe_sw) as its transport
- *
- * TODO -
- * 1. supports only PCI device
- * 2. needs fix for VLAn and bonding
- * 3. pure hw fcoe hba may not have netdev
- *
- * Returns: 0 for success
- */
-int fcoe_load_transport_driver(struct net_device *netdev)
-{
- struct pci_dev *pci;
- struct device *dev = netdev->dev.parent;
-
- if (fcoe_transport_lookup(netdev)) {
- /* load default transport */
- printk(KERN_DEBUG "fcoe: already loaded transport for %s\n",
- netdev->name);
- return -EEXIST;
- }
-
- pci = to_pci_dev(dev);
- if (dev->bus != &pci_bus_type) {
- printk(KERN_DEBUG "fcoe: support noly PCI device\n");
- return -ENODEV;
- }
- printk(KERN_DEBUG "fcoe: loading driver fcoe-pci-0x%04x-0x%04x\n",
- pci->vendor, pci->device);
-
- return request_module("fcoe-pci-0x%04x-0x%04x",
- pci->vendor, pci->device);
-
-}
-EXPORT_SYMBOL_GPL(fcoe_load_transport_driver);
-
-/**
- * fcoe_transport_attach() - Load transport to fcoe
- * @netdev: the netdev the transport to be attached to
- *
- * This will look for existing offload driver, if not found, it falls back to
- * the default sw hba (fcoe_sw) as its fcoe transport.
- *
- * Returns: 0 for success
- */
-int fcoe_transport_attach(struct net_device *netdev)
-{
- struct fcoe_transport *t;
-
- /* find the corresponding transport */
- t = fcoe_transport_lookup(netdev);
- if (!t) {
- printk(KERN_DEBUG "fcoe_transport_attach"
- ":no transport for %s:use %s\n",
- netdev->name, t->name);
- return -ENODEV;
- }
- /* add to the transport */
- if (fcoe_transport_device_add(t, netdev)) {
- printk(KERN_DEBUG "fcoe_transport_attach"
- ":failed to add %s to tramsport %s\n",
- netdev->name, t->name);
- return -EIO;
- }
- /* transport create function */
- if (t->create)
- t->create(netdev);
-
- printk(KERN_DEBUG "fcoe_transport_attach:transport %s for %s\n",
- t->name, netdev->name);
- return 0;
-}
-EXPORT_SYMBOL_GPL(fcoe_transport_attach);
-
-/**
- * fcoe_transport_release() - Unload transport from fcoe
- * @netdev: the net device on which fcoe is to be released
- *
- * Returns: 0 for success
- */
-int fcoe_transport_release(struct net_device *netdev)
-{
- struct fcoe_transport *t;
-
- /* find the corresponding transport */
- t = fcoe_transport_lookup(netdev);
- if (!t) {
- printk(KERN_DEBUG "fcoe_transport_release:"
- "no transport for %s:use %s\n",
- netdev->name, t->name);
- return -ENODEV;
- }
- /* remove the device from the transport */
- if (fcoe_transport_device_remove(t, netdev)) {
- printk(KERN_DEBUG "fcoe_transport_release:"
- "failed to add %s to tramsport %s\n",
- netdev->name, t->name);
- return -EIO;
- }
- /* transport destroy function */
- if (t->destroy)
- t->destroy(netdev);
-
- printk(KERN_DEBUG "fcoe_transport_release:"
- "device %s dettached from transport %s\n",
- netdev->name, t->name);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(fcoe_transport_release);
-
-/**
- * fcoe_transport_init() - Initializes fcoe transport layer
- *
- * This prepares for the fcoe transport layer
- *
- * Returns: none
- */
-int __init fcoe_transport_init(void)
-{
- INIT_LIST_HEAD(&fcoe_transports);
- mutex_init(&fcoe_transports_lock);
- return 0;
-}
-
-/**
- * fcoe_transport_exit() - Cleans up the fcoe transport layer
- *
- * This cleans up the fcoe transport layer. removing any transport on the list,
- * note that the transport destroy func is not called here.
- *
- * Returns: none
- */
-int __exit fcoe_transport_exit(void)
-{
- struct fcoe_transport *t, *tmp;
-
- mutex_lock(&fcoe_transports_lock);
- list_for_each_entry_safe(t, tmp, &fcoe_transports, list) {
- list_del(&t->list);
- mutex_unlock(&fcoe_transports_lock);
- fcoe_transport_device_remove_all(t);
- mutex_lock(&fcoe_transports_lock);
- }
- mutex_unlock(&fcoe_transports_lock);
- return 0;
-}
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
new file mode 100644
index 00000000000..94e1e318977
--- /dev/null
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -0,0 +1,1878 @@
+/*
+ * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/crc32.h>
+#include <linux/cpu.h>
+#include <linux/fs.h>
+#include <linux/sysfs.h>
+#include <linux/ctype.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsicam.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
+#include <net/rtnetlink.h>
+
+#include <scsi/fc/fc_encaps.h>
+#include <scsi/fc/fc_fip.h>
+
+#include <scsi/libfc.h>
+#include <scsi/fc_frame.h>
+#include <scsi/libfcoe.h>
+
+#include "fcoe.h"
+
+static int debug_fcoe;
+
+MODULE_AUTHOR("Open-FCoE.org");
+MODULE_DESCRIPTION("FCoE");
+MODULE_LICENSE("GPL v2");
+
+/* fcoe host list */
+LIST_HEAD(fcoe_hostlist);
+DEFINE_RWLOCK(fcoe_hostlist_lock);
+DEFINE_TIMER(fcoe_timer, NULL, 0, 0);
+DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu);
+
+/* Function Prototyes */
+static int fcoe_reset(struct Scsi_Host *shost);
+static int fcoe_xmit(struct fc_lport *, struct fc_frame *);
+static int fcoe_rcv(struct sk_buff *, struct net_device *,
+ struct packet_type *, struct net_device *);
+static int fcoe_percpu_receive_thread(void *arg);
+static void fcoe_clean_pending_queue(struct fc_lport *lp);
+static void fcoe_percpu_clean(struct fc_lport *lp);
+static int fcoe_link_ok(struct fc_lport *lp);
+
+static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
+static int fcoe_hostlist_add(const struct fc_lport *);
+static int fcoe_hostlist_remove(const struct fc_lport *);
+
+static int fcoe_check_wait_queue(struct fc_lport *);
+static int fcoe_device_notification(struct notifier_block *, ulong, void *);
+static void fcoe_dev_setup(void);
+static void fcoe_dev_cleanup(void);
+
+/* notification function from net device */
+static struct notifier_block fcoe_notifier = {
+ .notifier_call = fcoe_device_notification,
+};
+
+static struct scsi_transport_template *scsi_transport_fcoe_sw;
+
+struct fc_function_template fcoe_transport_function = {
+ .show_host_node_name = 1,
+ .show_host_port_name = 1,
+ .show_host_supported_classes = 1,
+ .show_host_supported_fc4s = 1,
+ .show_host_active_fc4s = 1,
+ .show_host_maxframe_size = 1,
+
+ .show_host_port_id = 1,
+ .show_host_supported_speeds = 1,
+ .get_host_speed = fc_get_host_speed,
+ .show_host_speed = 1,
+ .show_host_port_type = 1,
+ .get_host_port_state = fc_get_host_port_state,
+ .show_host_port_state = 1,
+ .show_host_symbolic_name = 1,
+
+ .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
+ .show_rport_maxframe_size = 1,
+ .show_rport_supported_classes = 1,
+
+ .show_host_fabric_name = 1,
+ .show_starget_node_name = 1,
+ .show_starget_port_name = 1,
+ .show_starget_port_id = 1,
+ .set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
+ .show_rport_dev_loss_tmo = 1,
+ .get_fc_host_stats = fc_get_host_stats,
+ .issue_fc_host_lip = fcoe_reset,
+
+ .terminate_rport_io = fc_rport_terminate_io,
+};
+
+static struct scsi_host_template fcoe_shost_template = {
+ .module = THIS_MODULE,
+ .name = "FCoE Driver",
+ .proc_name = FCOE_NAME,
+ .queuecommand = fc_queuecommand,
+ .eh_abort_handler = fc_eh_abort,
+ .eh_device_reset_handler = fc_eh_device_reset,
+ .eh_host_reset_handler = fc_eh_host_reset,
+ .slave_alloc = fc_slave_alloc,
+ .change_queue_depth = fc_change_queue_depth,
+ .change_queue_type = fc_change_queue_type,
+ .this_id = -1,
+ .cmd_per_lun = 32,
+ .can_queue = FCOE_MAX_OUTSTANDING_COMMANDS,
+ .use_clustering = ENABLE_CLUSTERING,
+ .sg_tablesize = SG_ALL,
+ .max_sectors = 0xffff,
+};
+
+/**
+ * fcoe_lport_config() - sets up the fc_lport
+ * @lp: ptr to the fc_lport
+ * @shost: ptr to the parent scsi host
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_lport_config(struct fc_lport *lp)
+{
+ lp->link_up = 0;
+ lp->qfull = 0;
+ lp->max_retry_count = 3;
+ lp->e_d_tov = 2 * 1000; /* FC-FS default */
+ lp->r_a_tov = 2 * 2 * 1000;
+ lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
+ FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
+
+ fc_lport_init_stats(lp);
+
+ /* lport fc_lport related configuration */
+ fc_lport_config(lp);
+
+ /* offload related configuration */
+ lp->crc_offload = 0;
+ lp->seq_offload = 0;
+ lp->lro_enabled = 0;
+ lp->lro_xid = 0;
+ lp->lso_max = 0;
+
+ return 0;
+}
+
+/**
+ * fcoe_netdev_config() - Set up netdev for SW FCoE
+ * @lp : ptr to the fc_lport
+ * @netdev : ptr to the associated netdevice struct
+ *
+ * Must be called after fcoe_lport_config() as it will use lport mutex
+ *
+ * Returns : 0 for success
+ */
+static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
+{
+ u32 mfs;
+ u64 wwnn, wwpn;
+ struct fcoe_softc *fc;
+ u8 flogi_maddr[ETH_ALEN];
+
+ /* Setup lport private data to point to fcoe softc */
+ fc = lport_priv(lp);
+ fc->ctlr.lp = lp;
+ fc->real_dev = netdev;
+ fc->phys_dev = netdev;
+
+ /* Require support for get_pauseparam ethtool op. */
+ if (netdev->priv_flags & IFF_802_1Q_VLAN)
+ fc->phys_dev = vlan_dev_real_dev(netdev);
+
+ /* Do not support for bonding device */
+ if ((fc->real_dev->priv_flags & IFF_MASTER_ALB) ||
+ (fc->real_dev->priv_flags & IFF_SLAVE_INACTIVE) ||
+ (fc->real_dev->priv_flags & IFF_MASTER_8023AD)) {
+ return -EOPNOTSUPP;
+ }
+
+ /*
+ * Determine max frame size based on underlying device and optional
+ * user-configured limit. If the MFS is too low, fcoe_link_ok()
+ * will return 0, so do this first.
+ */
+ mfs = fc->real_dev->mtu - (sizeof(struct fcoe_hdr) +
+ sizeof(struct fcoe_crc_eof));
+ if (fc_set_mfs(lp, mfs))
+ return -EINVAL;
+
+ /* offload features support */
+ if (fc->real_dev->features & NETIF_F_SG)
+ lp->sg_supp = 1;
+
+#ifdef NETIF_F_FCOE_CRC
+ if (netdev->features & NETIF_F_FCOE_CRC) {
+ lp->crc_offload = 1;
+ printk(KERN_DEBUG "fcoe:%s supports FCCRC offload\n",
+ netdev->name);
+ }
+#endif
+#ifdef NETIF_F_FSO
+ if (netdev->features & NETIF_F_FSO) {
+ lp->seq_offload = 1;
+ lp->lso_max = netdev->gso_max_size;
+ printk(KERN_DEBUG "fcoe:%s supports LSO for max len 0x%x\n",
+ netdev->name, lp->lso_max);
+ }
+#endif
+ if (netdev->fcoe_ddp_xid) {
+ lp->lro_enabled = 1;
+ lp->lro_xid = netdev->fcoe_ddp_xid;
+ printk(KERN_DEBUG "fcoe:%s supports LRO for max xid 0x%x\n",
+ netdev->name, lp->lro_xid);
+ }
+ skb_queue_head_init(&fc->fcoe_pending_queue);
+ fc->fcoe_pending_queue_active = 0;
+
+ /* setup Source Mac Address */
+ memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr,
+ fc->real_dev->addr_len);
+
+ wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
+ fc_set_wwnn(lp, wwnn);
+ /* XXX - 3rd arg needs to be vlan id */
+ wwpn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 2, 0);
+ fc_set_wwpn(lp, wwpn);
+
+ /*
+ * Add FCoE MAC address as second unicast MAC address
+ * or enter promiscuous mode if not capable of listening
+ * for multiple unicast MACs.
+ */
+ rtnl_lock();
+ memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
+ dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN);
+ rtnl_unlock();
+
+ /*
+ * setup the receive function from ethernet driver
+ * on the ethertype for the given device
+ */
+ fc->fcoe_packet_type.func = fcoe_rcv;
+ fc->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE);
+ fc->fcoe_packet_type.dev = fc->real_dev;
+ dev_add_pack(&fc->fcoe_packet_type);
+
+ return 0;
+}
+
+/**
+ * fcoe_shost_config() - Sets up fc_lport->host
+ * @lp : ptr to the fc_lport
+ * @shost : ptr to the associated scsi host
+ * @dev : device associated to scsi host
+ *
+ * Must be called after fcoe_lport_config() and fcoe_netdev_config()
+ *
+ * Returns : 0 for success
+ */
+static int fcoe_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
+ struct device *dev)
+{
+ int rc = 0;
+
+ /* lport scsi host config */
+ lp->host = shost;
+
+ lp->host->max_lun = FCOE_MAX_LUN;
+ lp->host->max_id = FCOE_MAX_FCP_TARGET;
+ lp->host->max_channel = 0;
+ lp->host->transportt = scsi_transport_fcoe_sw;
+
+ /* add the new host to the SCSI-ml */
+ rc = scsi_add_host(lp->host, dev);
+ if (rc) {
+ FC_DBG("fcoe_shost_config:error on scsi_add_host\n");
+ return rc;
+ }
+ sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
+ FCOE_NAME, FCOE_VERSION,
+ fcoe_netdev(lp)->name);
+
+ return 0;
+}
+
+/**
+ * fcoe_em_config() - allocates em for this lport
+ * @lp: the port that em is to allocated for
+ *
+ * Returns : 0 on success
+ */
+static inline int fcoe_em_config(struct fc_lport *lp)
+{
+ BUG_ON(lp->emp);
+
+ lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3,
+ FCOE_MIN_XID, FCOE_MAX_XID);
+ if (!lp->emp)
+ return -ENOMEM;
+
+ return 0;
+}
+
+/**
+ * fcoe_if_destroy() - FCoE software HBA tear-down function
+ * @netdev: ptr to the associated net_device
+ *
+ * Returns: 0 if link is OK for use by FCoE.
+ */
+static int fcoe_if_destroy(struct net_device *netdev)
+{
+ struct fc_lport *lp = NULL;
+ struct fcoe_softc *fc;
+ u8 flogi_maddr[ETH_ALEN];
+
+ BUG_ON(!netdev);
+
+ printk(KERN_DEBUG "fcoe_if_destroy:interface on %s\n",
+ netdev->name);
+
+ lp = fcoe_hostlist_lookup(netdev);
+ if (!lp)
+ return -ENODEV;
+
+ fc = lport_priv(lp);
+
+ /* Logout of the fabric */
+ fc_fabric_logoff(lp);
+
+ /* Remove the instance from fcoe's list */
+ fcoe_hostlist_remove(lp);
+
+ /* Don't listen for Ethernet packets anymore */
+ dev_remove_pack(&fc->fcoe_packet_type);
+ dev_remove_pack(&fc->fip_packet_type);
+ fcoe_ctlr_destroy(&fc->ctlr);
+
+ /* Cleanup the fc_lport */
+ fc_lport_destroy(lp);
+ fc_fcp_destroy(lp);
+
+ /* Detach from the scsi-ml */
+ fc_remove_host(lp->host);
+ scsi_remove_host(lp->host);
+
+ /* There are no more rports or I/O, free the EM */
+ if (lp->emp)
+ fc_exch_mgr_free(lp->emp);
+
+ /* Delete secondary MAC addresses */
+ rtnl_lock();
+ memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
+ dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN);
+ if (!is_zero_ether_addr(fc->ctlr.data_src_addr))
+ dev_unicast_delete(fc->real_dev,
+ fc->ctlr.data_src_addr, ETH_ALEN);
+ dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
+ rtnl_unlock();
+
+ /* Free the per-CPU revieve threads */
+ fcoe_percpu_clean(lp);
+
+ /* Free existing skbs */
+ fcoe_clean_pending_queue(lp);
+
+ /* Free memory used by statistical counters */
+ fc_lport_free_stats(lp);
+
+ /* Release the net_device and Scsi_Host */
+ dev_put(fc->real_dev);
+ scsi_host_put(lp->host);
+
+ return 0;
+}
+
+/*
+ * fcoe_ddp_setup - calls LLD's ddp_setup through net_device
+ * @lp: the corresponding fc_lport
+ * @xid: the exchange id for this ddp transfer
+ * @sgl: the scatterlist describing this transfer
+ * @sgc: number of sg items
+ *
+ * Returns : 0 no ddp
+ */
+static int fcoe_ddp_setup(struct fc_lport *lp, u16 xid,
+ struct scatterlist *sgl, unsigned int sgc)
+{
+ struct net_device *n = fcoe_netdev(lp);
+
+ if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup)
+ return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc);
+
+ return 0;
+}
+
+/*
+ * fcoe_ddp_done - calls LLD's ddp_done through net_device
+ * @lp: the corresponding fc_lport
+ * @xid: the exchange id for this ddp transfer
+ *
+ * Returns : the length of data that have been completed by ddp
+ */
+static int fcoe_ddp_done(struct fc_lport *lp, u16 xid)
+{
+ struct net_device *n = fcoe_netdev(lp);
+
+ if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done)
+ return n->netdev_ops->ndo_fcoe_ddp_done(n, xid);
+ return 0;
+}
+
+static struct libfc_function_template fcoe_libfc_fcn_templ = {
+ .frame_send = fcoe_xmit,
+ .ddp_setup = fcoe_ddp_setup,
+ .ddp_done = fcoe_ddp_done,
+};
+
+/**
+ * fcoe_fip_recv - handle a received FIP frame.
+ * @skb: the receive skb
+ * @dev: associated &net_device
+ * @ptype: the &packet_type structure which was used to register this handler.
+ * @orig_dev: original receive &net_device, in case @dev is a bond.
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *ptype,
+ struct net_device *orig_dev)
+{
+ struct fcoe_softc *fc;
+
+ fc = container_of(ptype, struct fcoe_softc, fip_packet_type);
+ fcoe_ctlr_recv(&fc->ctlr, skb);
+ return 0;
+}
+
+/**
+ * fcoe_fip_send() - send an Ethernet-encapsulated FIP frame.
+ * @fip: FCoE controller.
+ * @skb: FIP Packet.
+ */
+static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
+{
+ skb->dev = fcoe_from_ctlr(fip)->real_dev;
+ dev_queue_xmit(skb);
+}
+
+/**
+ * fcoe_update_src_mac() - Update Ethernet MAC filters.
+ * @fip: FCoE controller.
+ * @old: Unicast MAC address to delete if the MAC is non-zero.
+ * @new: Unicast MAC address to add.
+ *
+ * Remove any previously-set unicast MAC filter.
+ * Add secondary FCoE MAC address filter for our OUI.
+ */
+static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new)
+{
+ struct fcoe_softc *fc;
+
+ fc = fcoe_from_ctlr(fip);
+ rtnl_lock();
+ if (!is_zero_ether_addr(old))
+ dev_unicast_delete(fc->real_dev, old, ETH_ALEN);
+ dev_unicast_add(fc->real_dev, new, ETH_ALEN);
+ rtnl_unlock();
+}
+
+/**
+ * fcoe_if_create() - this function creates the fcoe interface
+ * @netdev: pointer the associated netdevice
+ *
+ * Creates fc_lport struct and scsi_host for lport, configures lport
+ * and starts fabric login.
+ *
+ * Returns : 0 on success
+ */
+static int fcoe_if_create(struct net_device *netdev)
+{
+ int rc;
+ struct fc_lport *lp = NULL;
+ struct fcoe_softc *fc;
+ struct Scsi_Host *shost;
+
+ BUG_ON(!netdev);
+
+ printk(KERN_DEBUG "fcoe_if_create:interface on %s\n",
+ netdev->name);
+
+ lp = fcoe_hostlist_lookup(netdev);
+ if (lp)
+ return -EEXIST;
+
+ shost = libfc_host_alloc(&fcoe_shost_template,
+ sizeof(struct fcoe_softc));
+ if (!shost) {
+ FC_DBG("Could not allocate host structure\n");
+ return -ENOMEM;
+ }
+ lp = shost_priv(shost);
+ fc = lport_priv(lp);
+
+ /* configure fc_lport, e.g., em */
+ rc = fcoe_lport_config(lp);
+ if (rc) {
+ FC_DBG("Could not configure lport\n");
+ goto out_host_put;
+ }
+
+ /* configure lport network properties */
+ rc = fcoe_netdev_config(lp, netdev);
+ if (rc) {
+ FC_DBG("Could not configure netdev for lport\n");
+ goto out_host_put;
+ }
+
+ /*
+ * Initialize FIP.
+ */
+ fcoe_ctlr_init(&fc->ctlr);
+ fc->ctlr.send = fcoe_fip_send;
+ fc->ctlr.update_mac = fcoe_update_src_mac;
+
+ fc->fip_packet_type.func = fcoe_fip_recv;
+ fc->fip_packet_type.type = htons(ETH_P_FIP);
+ fc->fip_packet_type.dev = fc->real_dev;
+ dev_add_pack(&fc->fip_packet_type);
+
+ /* configure lport scsi host properties */
+ rc = fcoe_shost_config(lp, shost, &netdev->dev);
+ if (rc) {
+ FC_DBG("Could not configure shost for lport\n");
+ goto out_host_put;
+ }
+
+ /* lport exch manager allocation */
+ rc = fcoe_em_config(lp);
+ if (rc) {
+ FC_DBG("Could not configure em for lport\n");
+ goto out_host_put;
+ }
+
+ /* Initialize the library */
+ rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ);
+ if (rc) {
+ FC_DBG("Could not configure libfc for lport!\n");
+ goto out_lp_destroy;
+ }
+
+ /* add to lports list */
+ fcoe_hostlist_add(lp);
+
+ lp->boot_time = jiffies;
+
+ fc_fabric_login(lp);
+
+ if (!fcoe_link_ok(lp))
+ fcoe_ctlr_link_up(&fc->ctlr);
+
+ dev_hold(netdev);
+
+ return rc;
+
+out_lp_destroy:
+ fc_exch_mgr_free(lp->emp); /* Free the EM */
+out_host_put:
+ scsi_host_put(lp->host);
+ return rc;
+}
+
+/**
+ * fcoe_if_init() - attach to scsi transport
+ *
+ * Returns : 0 on success
+ */
+static int __init fcoe_if_init(void)
+{
+ /* attach to scsi transport */
+ scsi_transport_fcoe_sw =
+ fc_attach_transport(&fcoe_transport_function);
+
+ if (!scsi_transport_fcoe_sw) {
+ printk(KERN_ERR "fcoe_init:fc_attach_transport() failed\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/**
+ * fcoe_if_exit() - detach from scsi transport
+ *
+ * Returns : 0 on success
+ */
+int __exit fcoe_if_exit(void)
+{
+ fc_release_transport(scsi_transport_fcoe_sw);
+ return 0;
+}
+
+/**
+ * fcoe_percpu_thread_create() - Create a receive thread for an online cpu
+ * @cpu: cpu index for the online cpu
+ */
+static void fcoe_percpu_thread_create(unsigned int cpu)
+{
+ struct fcoe_percpu_s *p;
+ struct task_struct *thread;
+
+ p = &per_cpu(fcoe_percpu, cpu);
+
+ thread = kthread_create(fcoe_percpu_receive_thread,
+ (void *)p, "fcoethread/%d", cpu);
+
+ if (likely(!IS_ERR(p->thread))) {
+ kthread_bind(thread, cpu);
+ wake_up_process(thread);
+
+ spin_lock_bh(&p->fcoe_rx_list.lock);
+ p->thread = thread;
+ spin_unlock_bh(&p->fcoe_rx_list.lock);
+ }
+}
+
+/**
+ * fcoe_percpu_thread_destroy() - removes the rx thread for the given cpu
+ * @cpu: cpu index the rx thread is to be removed
+ *
+ * Destroys a per-CPU Rx thread. Any pending skbs are moved to the
+ * current CPU's Rx thread. If the thread being destroyed is bound to
+ * the CPU processing this context the skbs will be freed.
+ */
+static void fcoe_percpu_thread_destroy(unsigned int cpu)
+{
+ struct fcoe_percpu_s *p;
+ struct task_struct *thread;
+ struct page *crc_eof;
+ struct sk_buff *skb;
+#ifdef CONFIG_SMP
+ struct fcoe_percpu_s *p0;
+ unsigned targ_cpu = smp_processor_id();
+#endif /* CONFIG_SMP */
+
+ printk(KERN_DEBUG "fcoe: Destroying receive thread for CPU %d\n", cpu);
+
+ /* Prevent any new skbs from being queued for this CPU. */
+ p = &per_cpu(fcoe_percpu, cpu);
+ spin_lock_bh(&p->fcoe_rx_list.lock);
+ thread = p->thread;
+ p->thread = NULL;
+ crc_eof = p->crc_eof_page;
+ p->crc_eof_page = NULL;
+ p->crc_eof_offset = 0;
+ spin_unlock_bh(&p->fcoe_rx_list.lock);
+
+#ifdef CONFIG_SMP
+ /*
+ * Don't bother moving the skb's if this context is running
+ * on the same CPU that is having its thread destroyed. This
+ * can easily happen when the module is removed.
+ */
+ if (cpu != targ_cpu) {
+ p0 = &per_cpu(fcoe_percpu, targ_cpu);
+ spin_lock_bh(&p0->fcoe_rx_list.lock);
+ if (p0->thread) {
+ FC_DBG("Moving frames from CPU %d to CPU %d\n",
+ cpu, targ_cpu);
+
+ while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
+ __skb_queue_tail(&p0->fcoe_rx_list, skb);
+ spin_unlock_bh(&p0->fcoe_rx_list.lock);
+ } else {
+ /*
+ * The targeted CPU is not initialized and cannot accept
+ * new skbs. Unlock the targeted CPU and drop the skbs
+ * on the CPU that is going offline.
+ */
+ while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
+ kfree_skb(skb);
+ spin_unlock_bh(&p0->fcoe_rx_list.lock);
+ }
+ } else {
+ /*
+ * This scenario occurs when the module is being removed
+ * and all threads are being destroyed. skbs will continue
+ * to be shifted from the CPU thread that is being removed
+ * to the CPU thread associated with the CPU that is processing
+ * the module removal. Once there is only one CPU Rx thread it
+ * will reach this case and we will drop all skbs and later
+ * stop the thread.
+ */
+ spin_lock_bh(&p->fcoe_rx_list.lock);
+ while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
+ kfree_skb(skb);
+ spin_unlock_bh(&p->fcoe_rx_list.lock);
+ }
+#else
+ /*
+ * This a non-SMP scenario where the singluar Rx thread is
+ * being removed. Free all skbs and stop the thread.
+ */
+ spin_lock_bh(&p->fcoe_rx_list.lock);
+ while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
+ kfree_skb(skb);
+ spin_unlock_bh(&p->fcoe_rx_list.lock);
+#endif
+
+ if (thread)
+ kthread_stop(thread);
+
+ if (crc_eof)
+ put_page(crc_eof);
+}
+
+/**
+ * fcoe_cpu_callback() - fcoe cpu hotplug event callback
+ * @nfb: callback data block
+ * @action: event triggering the callback
+ * @hcpu: index for the cpu of this event
+ *
+ * This creates or destroys per cpu data for fcoe
+ *
+ * Returns NOTIFY_OK always.
+ */
+static int fcoe_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned cpu = (unsigned long)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+ FC_DBG("CPU %x online: Create Rx thread\n", cpu);
+ fcoe_percpu_thread_create(cpu);
+ break;
+ case CPU_DEAD:
+ case CPU_DEAD_FROZEN:
+ FC_DBG("CPU %x offline: Remove Rx thread\n", cpu);
+ fcoe_percpu_thread_destroy(cpu);
+ break;
+ default:
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block fcoe_cpu_notifier = {
+ .notifier_call = fcoe_cpu_callback,
+};
+
+/**
+ * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ
+ * @skb: the receive skb
+ * @dev: associated net device
+ * @ptype: context
+ * @odldev: last device
+ *
+ * this function will receive the packet and build fc frame and pass it up
+ *
+ * Returns: 0 for success
+ */
+int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *ptype, struct net_device *olddev)
+{
+ struct fc_lport *lp;
+ struct fcoe_rcv_info *fr;
+ struct fcoe_softc *fc;
+ struct fc_frame_header *fh;
+ struct fcoe_percpu_s *fps;
+ unsigned short oxid;
+ unsigned int cpu = 0;
+
+ fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type);
+ lp = fc->ctlr.lp;
+ if (unlikely(lp == NULL)) {
+ FC_DBG("cannot find hba structure");
+ goto err2;
+ }
+ if (!lp->link_up)
+ goto err2;
+
+ if (unlikely(debug_fcoe)) {
+ FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p tail:%p "
+ "end:%p sum:%d dev:%s", skb->len, skb->data_len,
+ skb->head, skb->data, skb_tail_pointer(skb),
+ skb_end_pointer(skb), skb->csum,
+ skb->dev ? skb->dev->name : "<NULL>");
+
+ }
+
+ /* check for FCOE packet type */
+ if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
+ FC_DBG("wrong FC type frame");
+ goto err;
+ }
+
+ /*
+ * Check for minimum frame length, and make sure required FCoE
+ * and FC headers are pulled into the linear data area.
+ */
+ if (unlikely((skb->len < FCOE_MIN_FRAME) ||
+ !pskb_may_pull(skb, FCOE_HEADER_LEN)))
+ goto err;
+
+ skb_set_transport_header(skb, sizeof(struct fcoe_hdr));
+ fh = (struct fc_frame_header *) skb_transport_header(skb);
+
+ oxid = ntohs(fh->fh_ox_id);
+
+ fr = fcoe_dev_from_skb(skb);
+ fr->fr_dev = lp;
+ fr->ptype = ptype;
+
+#ifdef CONFIG_SMP
+ /*
+ * The incoming frame exchange id(oxid) is ANDed with num of online
+ * cpu bits to get cpu and then this cpu is used for selecting
+ * a per cpu kernel thread from fcoe_percpu.
+ */
+ cpu = oxid & (num_online_cpus() - 1);
+#endif
+
+ fps = &per_cpu(fcoe_percpu, cpu);
+ spin_lock_bh(&fps->fcoe_rx_list.lock);
+ if (unlikely(!fps->thread)) {
+ /*
+ * The targeted CPU is not ready, let's target
+ * the first CPU now. For non-SMP systems this
+ * will check the same CPU twice.
+ */
+ FC_DBG("CPU is online, but no receive thread ready "
+ "for incoming skb- using first online CPU.\n");
+
+ spin_unlock_bh(&fps->fcoe_rx_list.lock);
+ cpu = first_cpu(cpu_online_map);
+ fps = &per_cpu(fcoe_percpu, cpu);
+ spin_lock_bh(&fps->fcoe_rx_list.lock);
+ if (!fps->thread) {
+ spin_unlock_bh(&fps->fcoe_rx_list.lock);
+ goto err;
+ }
+ }
+
+ /*
+ * We now have a valid CPU that we're targeting for
+ * this skb. We also have this receive thread locked,
+ * so we're free to queue skbs into it's queue.
+ */
+ __skb_queue_tail(&fps->fcoe_rx_list, skb);
+ if (fps->fcoe_rx_list.qlen == 1)
+ wake_up_process(fps->thread);
+
+ spin_unlock_bh(&fps->fcoe_rx_list.lock);
+
+ return 0;
+err:
+ fc_lport_get_stats(lp)->ErrorFrames++;
+
+err2:
+ kfree_skb(skb);
+ return -1;
+}
+EXPORT_SYMBOL_GPL(fcoe_rcv);
+
+/**
+ * fcoe_start_io() - pass to netdev to start xmit for fcoe
+ * @skb: the skb to be xmitted
+ *
+ * Returns: 0 for success
+ */
+static inline int fcoe_start_io(struct sk_buff *skb)
+{
+ int rc;
+
+ skb_get(skb);
+ rc = dev_queue_xmit(skb);
+ if (rc != 0)
+ return rc;
+ kfree_skb(skb);
+ return 0;
+}
+
+/**
+ * fcoe_get_paged_crc_eof() - in case we need alloc a page for crc_eof
+ * @skb: the skb to be xmitted
+ * @tlen: total len
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen)
+{
+ struct fcoe_percpu_s *fps;
+ struct page *page;
+
+ fps = &get_cpu_var(fcoe_percpu);
+ page = fps->crc_eof_page;
+ if (!page) {
+ page = alloc_page(GFP_ATOMIC);
+ if (!page) {
+ put_cpu_var(fcoe_percpu);
+ return -ENOMEM;
+ }
+ fps->crc_eof_page = page;
+ fps->crc_eof_offset = 0;
+ }
+
+ get_page(page);
+ skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page,
+ fps->crc_eof_offset, tlen);
+ skb->len += tlen;
+ skb->data_len += tlen;
+ skb->truesize += tlen;
+ fps->crc_eof_offset += sizeof(struct fcoe_crc_eof);
+
+ if (fps->crc_eof_offset >= PAGE_SIZE) {
+ fps->crc_eof_page = NULL;
+ fps->crc_eof_offset = 0;
+ put_page(page);
+ }
+ put_cpu_var(fcoe_percpu);
+ return 0;
+}
+
+/**
+ * fcoe_fc_crc() - calculates FC CRC in this fcoe skb
+ * @fp: the fc_frame containg data to be checksummed
+ *
+ * This uses crc32() to calculate the crc for fc frame
+ * Return : 32 bit crc
+ */
+u32 fcoe_fc_crc(struct fc_frame *fp)
+{
+ struct sk_buff *skb = fp_skb(fp);
+ struct skb_frag_struct *frag;
+ unsigned char *data;
+ unsigned long off, len, clen;
+ u32 crc;
+ unsigned i;
+
+ crc = crc32(~0, skb->data, skb_headlen(skb));
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ frag = &skb_shinfo(skb)->frags[i];
+ off = frag->page_offset;
+ len = frag->size;
+ while (len > 0) {
+ clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
+ data = kmap_atomic(frag->page + (off >> PAGE_SHIFT),
+ KM_SKB_DATA_SOFTIRQ);
+ crc = crc32(crc, data + (off & ~PAGE_MASK), clen);
+ kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ);
+ off += clen;
+ len -= clen;
+ }
+ }
+ return crc;
+}
+
+/**
+ * fcoe_xmit() - FCoE frame transmit function
+ * @lp: the associated local port
+ * @fp: the fc_frame to be transmitted
+ *
+ * Return : 0 for success
+ */
+int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
+{
+ int wlen, rc = 0;
+ u32 crc;
+ struct ethhdr *eh;
+ struct fcoe_crc_eof *cp;
+ struct sk_buff *skb;
+ struct fcoe_dev_stats *stats;
+ struct fc_frame_header *fh;
+ unsigned int hlen; /* header length implies the version */
+ unsigned int tlen; /* trailer length */
+ unsigned int elen; /* eth header, may include vlan */
+ struct fcoe_softc *fc;
+ u8 sof, eof;
+ struct fcoe_hdr *hp;
+
+ WARN_ON((fr_len(fp) % sizeof(u32)) != 0);
+
+ fc = lport_priv(lp);
+ fh = fc_frame_header_get(fp);
+ skb = fp_skb(fp);
+ wlen = skb->len / FCOE_WORD_TO_BYTE;
+
+ if (!lp->link_up) {
+ kfree(skb);
+ return 0;
+ }
+
+ if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) &&
+ fcoe_ctlr_els_send(&fc->ctlr, skb))
+ return 0;
+
+ sof = fr_sof(fp);
+ eof = fr_eof(fp);
+
+ elen = (fc->real_dev->priv_flags & IFF_802_1Q_VLAN) ?
+ sizeof(struct vlan_ethhdr) : sizeof(struct ethhdr);
+ hlen = sizeof(struct fcoe_hdr);
+ tlen = sizeof(struct fcoe_crc_eof);
+ wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
+
+ /* crc offload */
+ if (likely(lp->crc_offload)) {
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ skb->csum_start = skb_headroom(skb);
+ skb->csum_offset = skb->len;
+ crc = 0;
+ } else {
+ skb->ip_summed = CHECKSUM_NONE;
+ crc = fcoe_fc_crc(fp);
+ }
+
+ /* copy fc crc and eof to the skb buff */
+ if (skb_is_nonlinear(skb)) {
+ skb_frag_t *frag;
+ if (fcoe_get_paged_crc_eof(skb, tlen)) {
+ kfree_skb(skb);
+ return -ENOMEM;
+ }
+ frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
+ cp = kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ)
+ + frag->page_offset;
+ } else {
+ cp = (struct fcoe_crc_eof *)skb_put(skb, tlen);
+ }
+
+ memset(cp, 0, sizeof(*cp));
+ cp->fcoe_eof = eof;
+ cp->fcoe_crc32 = cpu_to_le32(~crc);
+
+ if (skb_is_nonlinear(skb)) {
+ kunmap_atomic(cp, KM_SKB_DATA_SOFTIRQ);
+ cp = NULL;
+ }
+
+ /* adjust skb netowrk/transport offsets to match mac/fcoe/fc */
+ skb_push(skb, elen + hlen);
+ skb_reset_mac_header(skb);
+ skb_reset_network_header(skb);
+ skb->mac_len = elen;
+ skb->protocol = htons(ETH_P_FCOE);
+ skb->dev = fc->real_dev;
+
+ /* fill up mac and fcoe headers */
+ eh = eth_hdr(skb);
+ eh->h_proto = htons(ETH_P_FCOE);
+ if (fc->ctlr.map_dest)
+ fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id);
+ else
+ /* insert GW address */
+ memcpy(eh->h_dest, fc->ctlr.dest_addr, ETH_ALEN);
+
+ if (unlikely(fc->ctlr.flogi_oxid != FC_XID_UNKNOWN))
+ memcpy(eh->h_source, fc->ctlr.ctl_src_addr, ETH_ALEN);
+ else
+ memcpy(eh->h_source, fc->ctlr.data_src_addr, ETH_ALEN);
+
+ hp = (struct fcoe_hdr *)(eh + 1);
+ memset(hp, 0, sizeof(*hp));
+ if (FC_FCOE_VER)
+ FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER);
+ hp->fcoe_sof = sof;
+
+#ifdef NETIF_F_FSO
+ /* fcoe lso, mss is in max_payload which is non-zero for FCP data */
+ if (lp->seq_offload && fr_max_payload(fp)) {
+ skb_shinfo(skb)->gso_type = SKB_GSO_FCOE;
+ skb_shinfo(skb)->gso_size = fr_max_payload(fp);
+ } else {
+ skb_shinfo(skb)->gso_type = 0;
+ skb_shinfo(skb)->gso_size = 0;
+ }
+#endif
+ /* update tx stats: regardless if LLD fails */
+ stats = fc_lport_get_stats(lp);
+ stats->TxFrames++;
+ stats->TxWords += wlen;
+
+ /* send down to lld */
+ fr_dev(fp) = lp;
+ if (fc->fcoe_pending_queue.qlen)
+ rc = fcoe_check_wait_queue(lp);
+
+ if (rc == 0)
+ rc = fcoe_start_io(skb);
+
+ if (rc) {
+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
+ __skb_queue_tail(&fc->fcoe_pending_queue, skb);
+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+ if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
+ lp->qfull = 1;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fcoe_xmit);
+
+/**
+ * fcoe_percpu_receive_thread() - recv thread per cpu
+ * @arg: ptr to the fcoe per cpu struct
+ *
+ * Return: 0 for success
+ */
+int fcoe_percpu_receive_thread(void *arg)
+{
+ struct fcoe_percpu_s *p = arg;
+ u32 fr_len;
+ struct fc_lport *lp;
+ struct fcoe_rcv_info *fr;
+ struct fcoe_dev_stats *stats;
+ struct fc_frame_header *fh;
+ struct sk_buff *skb;
+ struct fcoe_crc_eof crc_eof;
+ struct fc_frame *fp;
+ u8 *mac = NULL;
+ struct fcoe_softc *fc;
+ struct fcoe_hdr *hp;
+
+ set_user_nice(current, -20);
+
+ while (!kthread_should_stop()) {
+
+ spin_lock_bh(&p->fcoe_rx_list.lock);
+ while ((skb = __skb_dequeue(&p->fcoe_rx_list)) == NULL) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ spin_unlock_bh(&p->fcoe_rx_list.lock);
+ schedule();
+ set_current_state(TASK_RUNNING);
+ if (kthread_should_stop())
+ return 0;
+ spin_lock_bh(&p->fcoe_rx_list.lock);
+ }
+ spin_unlock_bh(&p->fcoe_rx_list.lock);
+ fr = fcoe_dev_from_skb(skb);
+ lp = fr->fr_dev;
+ if (unlikely(lp == NULL)) {
+ FC_DBG("invalid HBA Structure");
+ kfree_skb(skb);
+ continue;
+ }
+
+ if (unlikely(debug_fcoe)) {
+ FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p "
+ "tail:%p end:%p sum:%d dev:%s",
+ skb->len, skb->data_len,
+ skb->head, skb->data, skb_tail_pointer(skb),
+ skb_end_pointer(skb), skb->csum,
+ skb->dev ? skb->dev->name : "<NULL>");
+ }
+
+ /*
+ * Save source MAC address before discarding header.
+ */
+ fc = lport_priv(lp);
+ if (skb_is_nonlinear(skb))
+ skb_linearize(skb); /* not ideal */
+ mac = eth_hdr(skb)->h_source;
+
+ /*
+ * Frame length checks and setting up the header pointers
+ * was done in fcoe_rcv already.
+ */
+ hp = (struct fcoe_hdr *) skb_network_header(skb);
+ fh = (struct fc_frame_header *) skb_transport_header(skb);
+
+ stats = fc_lport_get_stats(lp);
+ if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
+ if (stats->ErrorFrames < 5)
+ printk(KERN_WARNING "FCoE version "
+ "mismatch: The frame has "
+ "version %x, but the "
+ "initiator supports version "
+ "%x\n", FC_FCOE_DECAPS_VER(hp),
+ FC_FCOE_VER);
+ stats->ErrorFrames++;
+ kfree_skb(skb);
+ continue;
+ }
+
+ skb_pull(skb, sizeof(struct fcoe_hdr));
+ fr_len = skb->len - sizeof(struct fcoe_crc_eof);
+
+ stats->RxFrames++;
+ stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
+
+ fp = (struct fc_frame *)skb;
+ fc_frame_init(fp);
+ fr_dev(fp) = lp;
+ fr_sof(fp) = hp->fcoe_sof;
+
+ /* Copy out the CRC and EOF trailer for access */
+ if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
+ kfree_skb(skb);
+ continue;
+ }
+ fr_eof(fp) = crc_eof.fcoe_eof;
+ fr_crc(fp) = crc_eof.fcoe_crc32;
+ if (pskb_trim(skb, fr_len)) {
+ kfree_skb(skb);
+ continue;
+ }
+
+ /*
+ * We only check CRC if no offload is available and if it is
+ * it's solicited data, in which case, the FCP layer would
+ * check it during the copy.
+ */
+ if (lp->crc_offload && skb->ip_summed == CHECKSUM_UNNECESSARY)
+ fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
+ else
+ fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
+
+ fh = fc_frame_header_get(fp);
+ if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
+ fh->fh_type == FC_TYPE_FCP) {
+ fc_exch_recv(lp, lp->emp, fp);
+ continue;
+ }
+ if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
+ if (le32_to_cpu(fr_crc(fp)) !=
+ ~crc32(~0, skb->data, fr_len)) {
+ if (debug_fcoe || stats->InvalidCRCCount < 5)
+ printk(KERN_WARNING "fcoe: dropping "
+ "frame with CRC error\n");
+ stats->InvalidCRCCount++;
+ stats->ErrorFrames++;
+ fc_frame_free(fp);
+ continue;
+ }
+ fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
+ }
+ if (unlikely(fc->ctlr.flogi_oxid != FC_XID_UNKNOWN) &&
+ fcoe_ctlr_recv_flogi(&fc->ctlr, fp, mac)) {
+ fc_frame_free(fp);
+ continue;
+ }
+ fc_exch_recv(lp, lp->emp, fp);
+ }
+ return 0;
+}
+
+/**
+ * fcoe_watchdog() - fcoe timer callback
+ * @vp:
+ *
+ * This checks the pending queue length for fcoe and set lport qfull
+ * if the FCOE_MAX_QUEUE_DEPTH is reached. This is done for all fc_lport on the
+ * fcoe_hostlist.
+ *
+ * Returns: 0 for success
+ */
+void fcoe_watchdog(ulong vp)
+{
+ struct fcoe_softc *fc;
+
+ read_lock(&fcoe_hostlist_lock);
+ list_for_each_entry(fc, &fcoe_hostlist, list) {
+ if (fc->ctlr.lp)
+ fcoe_check_wait_queue(fc->ctlr.lp);
+ }
+ read_unlock(&fcoe_hostlist_lock);
+
+ fcoe_timer.expires = jiffies + (1 * HZ);
+ add_timer(&fcoe_timer);
+}
+
+
+/**
+ * fcoe_check_wait_queue() - put the skb into fcoe pending xmit queue
+ * @lp: the fc_port for this skb
+ * @skb: the associated skb to be xmitted
+ *
+ * This empties the wait_queue, dequeue the head of the wait_queue queue
+ * and calls fcoe_start_io() for each packet, if all skb have been
+ * transmitted, return qlen or -1 if a error occurs, then restore
+ * wait_queue and try again later.
+ *
+ * The wait_queue is used when the skb transmit fails. skb will go
+ * in the wait_queue which will be emptied by the time function OR
+ * by the next skb transmit.
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_check_wait_queue(struct fc_lport *lp)
+{
+ struct fcoe_softc *fc = lport_priv(lp);
+ struct sk_buff *skb;
+ int rc = -1;
+
+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
+ if (fc->fcoe_pending_queue_active)
+ goto out;
+ fc->fcoe_pending_queue_active = 1;
+
+ while (fc->fcoe_pending_queue.qlen) {
+ /* keep qlen > 0 until fcoe_start_io succeeds */
+ fc->fcoe_pending_queue.qlen++;
+ skb = __skb_dequeue(&fc->fcoe_pending_queue);
+
+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+ rc = fcoe_start_io(skb);
+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
+
+ if (rc) {
+ __skb_queue_head(&fc->fcoe_pending_queue, skb);
+ /* undo temporary increment above */
+ fc->fcoe_pending_queue.qlen--;
+ break;
+ }
+ /* undo temporary increment above */
+ fc->fcoe_pending_queue.qlen--;
+ }
+
+ if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH)
+ lp->qfull = 0;
+ fc->fcoe_pending_queue_active = 0;
+ rc = fc->fcoe_pending_queue.qlen;
+out:
+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+ return rc;
+}
+
+/**
+ * fcoe_dev_setup() - setup link change notification interface
+ */
+static void fcoe_dev_setup()
+{
+ /*
+ * here setup a interface specific wd time to
+ * monitor the link state
+ */
+ register_netdevice_notifier(&fcoe_notifier);
+}
+
+/**
+ * fcoe_dev_setup() - cleanup link change notification interface
+ */
+static void fcoe_dev_cleanup(void)
+{
+ unregister_netdevice_notifier(&fcoe_notifier);
+}
+
+/**
+ * fcoe_device_notification() - netdev event notification callback
+ * @notifier: context of the notification
+ * @event: type of event
+ * @ptr: fixed array for output parsed ifname
+ *
+ * This function is called by the ethernet driver in case of link change event
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_device_notification(struct notifier_block *notifier,
+ ulong event, void *ptr)
+{
+ struct fc_lport *lp = NULL;
+ struct net_device *real_dev = ptr;
+ struct fcoe_softc *fc;
+ struct fcoe_dev_stats *stats;
+ u32 link_possible = 1;
+ u32 mfs;
+ int rc = NOTIFY_OK;
+
+ read_lock(&fcoe_hostlist_lock);
+ list_for_each_entry(fc, &fcoe_hostlist, list) {
+ if (fc->real_dev == real_dev) {
+ lp = fc->ctlr.lp;
+ break;
+ }
+ }
+ read_unlock(&fcoe_hostlist_lock);
+ if (lp == NULL) {
+ rc = NOTIFY_DONE;
+ goto out;
+ }
+
+ switch (event) {
+ case NETDEV_DOWN:
+ case NETDEV_GOING_DOWN:
+ link_possible = 0;
+ break;
+ case NETDEV_UP:
+ case NETDEV_CHANGE:
+ break;
+ case NETDEV_CHANGEMTU:
+ mfs = fc->real_dev->mtu -
+ (sizeof(struct fcoe_hdr) +
+ sizeof(struct fcoe_crc_eof));
+ if (mfs >= FC_MIN_MAX_FRAME)
+ fc_set_mfs(lp, mfs);
+ break;
+ case NETDEV_REGISTER:
+ break;
+ default:
+ FC_DBG("Unknown event %ld from netdev netlink\n", event);
+ }
+ if (link_possible && !fcoe_link_ok(lp))
+ fcoe_ctlr_link_up(&fc->ctlr);
+ else if (fcoe_ctlr_link_down(&fc->ctlr)) {
+ stats = fc_lport_get_stats(lp);
+ stats->LinkFailureCount++;
+ fcoe_clean_pending_queue(lp);
+ }
+out:
+ return rc;
+}
+
+/**
+ * fcoe_if_to_netdev() - parse a name buffer to get netdev
+ * @ifname: fixed array for output parsed ifname
+ * @buffer: incoming buffer to be copied
+ *
+ * Returns: NULL or ptr to netdeive
+ */
+static struct net_device *fcoe_if_to_netdev(const char *buffer)
+{
+ char *cp;
+ char ifname[IFNAMSIZ + 2];
+
+ if (buffer) {
+ strlcpy(ifname, buffer, IFNAMSIZ);
+ cp = ifname + strlen(ifname);
+ while (--cp >= ifname && *cp == '\n')
+ *cp = '\0';
+ return dev_get_by_name(&init_net, ifname);
+ }
+ return NULL;
+}
+
+/**
+ * fcoe_netdev_to_module_owner() - finds out the nic drive moddule of the netdev
+ * @netdev: the target netdev
+ *
+ * Returns: ptr to the struct module, NULL for failure
+ */
+static struct module *
+fcoe_netdev_to_module_owner(const struct net_device *netdev)
+{
+ struct device *dev;
+
+ if (!netdev)
+ return NULL;
+
+ dev = netdev->dev.parent;
+ if (!dev)
+ return NULL;
+
+ if (!dev->driver)
+ return NULL;
+
+ return dev->driver->owner;
+}
+
+/**
+ * fcoe_ethdrv_get() - Hold the Ethernet driver
+ * @netdev: the target netdev
+ *
+ * Holds the Ethernet driver module by try_module_get() for
+ * the corresponding netdev.
+ *
+ * Returns: 0 for succsss
+ */
+static int fcoe_ethdrv_get(const struct net_device *netdev)
+{
+ struct module *owner;
+
+ owner = fcoe_netdev_to_module_owner(netdev);
+ if (owner) {
+ printk(KERN_DEBUG "fcoe:hold driver module %s for %s\n",
+ module_name(owner), netdev->name);
+ return try_module_get(owner);
+ }
+ return -ENODEV;
+}
+
+/**
+ * fcoe_ethdrv_put() - Release the Ethernet driver
+ * @netdev: the target netdev
+ *
+ * Releases the Ethernet driver module by module_put for
+ * the corresponding netdev.
+ *
+ * Returns: 0 for succsss
+ */
+static int fcoe_ethdrv_put(const struct net_device *netdev)
+{
+ struct module *owner;
+
+ owner = fcoe_netdev_to_module_owner(netdev);
+ if (owner) {
+ printk(KERN_DEBUG "fcoe:release driver module %s for %s\n",
+ module_name(owner), netdev->name);
+ module_put(owner);
+ return 0;
+ }
+ return -ENODEV;
+}
+
+/**
+ * fcoe_destroy() - handles the destroy from sysfs
+ * @buffer: expcted to be a eth if name
+ * @kp: associated kernel param
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
+{
+ int rc;
+ struct net_device *netdev;
+
+ netdev = fcoe_if_to_netdev(buffer);
+ if (!netdev) {
+ rc = -ENODEV;
+ goto out_nodev;
+ }
+ /* look for existing lport */
+ if (!fcoe_hostlist_lookup(netdev)) {
+ rc = -ENODEV;
+ goto out_putdev;
+ }
+ rc = fcoe_if_destroy(netdev);
+ if (rc) {
+ printk(KERN_ERR "fcoe: fcoe_if_destroy(%s) failed\n",
+ netdev->name);
+ rc = -EIO;
+ goto out_putdev;
+ }
+ fcoe_ethdrv_put(netdev);
+ rc = 0;
+out_putdev:
+ dev_put(netdev);
+out_nodev:
+ return rc;
+}
+
+/**
+ * fcoe_create() - Handles the create call from sysfs
+ * @buffer: expcted to be a eth if name
+ * @kp: associated kernel param
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_create(const char *buffer, struct kernel_param *kp)
+{
+ int rc;
+ struct net_device *netdev;
+
+ netdev = fcoe_if_to_netdev(buffer);
+ if (!netdev) {
+ rc = -ENODEV;
+ goto out_nodev;
+ }
+ /* look for existing lport */
+ if (fcoe_hostlist_lookup(netdev)) {
+ rc = -EEXIST;
+ goto out_putdev;
+ }
+ fcoe_ethdrv_get(netdev);
+
+ rc = fcoe_if_create(netdev);
+ if (rc) {
+ printk(KERN_ERR "fcoe: fcoe_if_create(%s) failed\n",
+ netdev->name);
+ fcoe_ethdrv_put(netdev);
+ rc = -EIO;
+ goto out_putdev;
+ }
+ rc = 0;
+out_putdev:
+ dev_put(netdev);
+out_nodev:
+ return rc;
+}
+
+module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
+__MODULE_PARM_TYPE(create, "string");
+MODULE_PARM_DESC(create, "Create fcoe port using net device passed in.");
+module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
+__MODULE_PARM_TYPE(destroy, "string");
+MODULE_PARM_DESC(destroy, "Destroy fcoe port");
+
+/**
+ * fcoe_link_ok() - Check if link is ok for the fc_lport
+ * @lp: ptr to the fc_lport
+ *
+ * Any permanently-disqualifying conditions have been previously checked.
+ * This also updates the speed setting, which may change with link for 100/1000.
+ *
+ * This function should probably be checking for PAUSE support at some point
+ * in the future. Currently Per-priority-pause is not determinable using
+ * ethtool, so we shouldn't be restrictive until that problem is resolved.
+ *
+ * Returns: 0 if link is OK for use by FCoE.
+ *
+ */
+int fcoe_link_ok(struct fc_lport *lp)
+{
+ struct fcoe_softc *fc = lport_priv(lp);
+ struct net_device *dev = fc->real_dev;
+ struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+ int rc = 0;
+
+ if ((dev->flags & IFF_UP) && netif_carrier_ok(dev)) {
+ dev = fc->phys_dev;
+ if (dev->ethtool_ops->get_settings) {
+ dev->ethtool_ops->get_settings(dev, &ecmd);
+ lp->link_supported_speeds &=
+ ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
+ if (ecmd.supported & (SUPPORTED_1000baseT_Half |
+ SUPPORTED_1000baseT_Full))
+ lp->link_supported_speeds |= FC_PORTSPEED_1GBIT;
+ if (ecmd.supported & SUPPORTED_10000baseT_Full)
+ lp->link_supported_speeds |=
+ FC_PORTSPEED_10GBIT;
+ if (ecmd.speed == SPEED_1000)
+ lp->link_speed = FC_PORTSPEED_1GBIT;
+ if (ecmd.speed == SPEED_10000)
+ lp->link_speed = FC_PORTSPEED_10GBIT;
+ }
+ } else
+ rc = -1;
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(fcoe_link_ok);
+
+/**
+ * fcoe_percpu_clean() - Clear the pending skbs for an lport
+ * @lp: the fc_lport
+ */
+void fcoe_percpu_clean(struct fc_lport *lp)
+{
+ struct fcoe_percpu_s *pp;
+ struct fcoe_rcv_info *fr;
+ struct sk_buff_head *list;
+ struct sk_buff *skb, *next;
+ struct sk_buff *head;
+ unsigned int cpu;
+
+ for_each_possible_cpu(cpu) {
+ pp = &per_cpu(fcoe_percpu, cpu);
+ spin_lock_bh(&pp->fcoe_rx_list.lock);
+ list = &pp->fcoe_rx_list;
+ head = list->next;
+ for (skb = head; skb != (struct sk_buff *)list;
+ skb = next) {
+ next = skb->next;
+ fr = fcoe_dev_from_skb(skb);
+ if (fr->fr_dev == lp) {
+ __skb_unlink(skb, list);
+ kfree_skb(skb);
+ }
+ }
+ spin_unlock_bh(&pp->fcoe_rx_list.lock);
+ }
+}
+EXPORT_SYMBOL_GPL(fcoe_percpu_clean);
+
+/**
+ * fcoe_clean_pending_queue() - Dequeue a skb and free it
+ * @lp: the corresponding fc_lport
+ *
+ * Returns: none
+ */
+void fcoe_clean_pending_queue(struct fc_lport *lp)
+{
+ struct fcoe_softc *fc = lport_priv(lp);
+ struct sk_buff *skb;
+
+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
+ while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) {
+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+ kfree_skb(skb);
+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
+ }
+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+}
+EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue);
+
+/**
+ * fcoe_reset() - Resets the fcoe
+ * @shost: shost the reset is from
+ *
+ * Returns: always 0
+ */
+int fcoe_reset(struct Scsi_Host *shost)
+{
+ struct fc_lport *lport = shost_priv(shost);
+ fc_lport_reset(lport);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fcoe_reset);
+
+/**
+ * fcoe_hostlist_lookup_softc() - find the corresponding lport by a given device
+ * @device: this is currently ptr to net_device
+ *
+ * Returns: NULL or the located fcoe_softc
+ */
+static struct fcoe_softc *
+fcoe_hostlist_lookup_softc(const struct net_device *dev)
+{
+ struct fcoe_softc *fc;
+
+ read_lock(&fcoe_hostlist_lock);
+ list_for_each_entry(fc, &fcoe_hostlist, list) {
+ if (fc->real_dev == dev) {
+ read_unlock(&fcoe_hostlist_lock);
+ return fc;
+ }
+ }
+ read_unlock(&fcoe_hostlist_lock);
+ return NULL;
+}
+
+/**
+ * fcoe_hostlist_lookup() - Find the corresponding lport by netdev
+ * @netdev: ptr to net_device
+ *
+ * Returns: 0 for success
+ */
+struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
+{
+ struct fcoe_softc *fc;
+
+ fc = fcoe_hostlist_lookup_softc(netdev);
+
+ return (fc) ? fc->ctlr.lp : NULL;
+}
+EXPORT_SYMBOL_GPL(fcoe_hostlist_lookup);
+
+/**
+ * fcoe_hostlist_add() - Add a lport to lports list
+ * @lp: ptr to the fc_lport to badded
+ *
+ * Returns: 0 for success
+ */
+int fcoe_hostlist_add(const struct fc_lport *lp)
+{
+ struct fcoe_softc *fc;
+
+ fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
+ if (!fc) {
+ fc = lport_priv(lp);
+ write_lock_bh(&fcoe_hostlist_lock);
+ list_add_tail(&fc->list, &fcoe_hostlist);
+ write_unlock_bh(&fcoe_hostlist_lock);
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fcoe_hostlist_add);
+
+/**
+ * fcoe_hostlist_remove() - remove a lport from lports list
+ * @lp: ptr to the fc_lport to badded
+ *
+ * Returns: 0 for success
+ */
+int fcoe_hostlist_remove(const struct fc_lport *lp)
+{
+ struct fcoe_softc *fc;
+
+ fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
+ BUG_ON(!fc);
+ write_lock_bh(&fcoe_hostlist_lock);
+ list_del(&fc->list);
+ write_unlock_bh(&fcoe_hostlist_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fcoe_hostlist_remove);
+
+/**
+ * fcoe_init() - fcoe module loading initialization
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int __init fcoe_init(void)
+{
+ unsigned int cpu;
+ int rc = 0;
+ struct fcoe_percpu_s *p;
+
+ INIT_LIST_HEAD(&fcoe_hostlist);
+ rwlock_init(&fcoe_hostlist_lock);
+
+ for_each_possible_cpu(cpu) {
+ p = &per_cpu(fcoe_percpu, cpu);
+ skb_queue_head_init(&p->fcoe_rx_list);
+ }
+
+ for_each_online_cpu(cpu)
+ fcoe_percpu_thread_create(cpu);
+
+ /* Initialize per CPU interrupt thread */
+ rc = register_hotcpu_notifier(&fcoe_cpu_notifier);
+ if (rc)
+ goto out_free;
+
+ /* Setup link change notification */
+ fcoe_dev_setup();
+
+ setup_timer(&fcoe_timer, fcoe_watchdog, 0);
+
+ mod_timer(&fcoe_timer, jiffies + (10 * HZ));
+
+ fcoe_if_init();
+
+ return 0;
+
+out_free:
+ for_each_online_cpu(cpu) {
+ fcoe_percpu_thread_destroy(cpu);
+ }
+
+ return rc;
+}
+module_init(fcoe_init);
+
+/**
+ * fcoe_exit() - fcoe module unloading cleanup
+ *
+ * Returns 0 on success, negative on failure
+ */
+static void __exit fcoe_exit(void)
+{
+ unsigned int cpu;
+ struct fcoe_softc *fc, *tmp;
+
+ fcoe_dev_cleanup();
+
+ /* Stop the timer */
+ del_timer_sync(&fcoe_timer);
+
+ /* releases the associated fcoe hosts */
+ list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list)
+ fcoe_if_destroy(fc->real_dev);
+
+ unregister_hotcpu_notifier(&fcoe_cpu_notifier);
+
+ for_each_online_cpu(cpu) {
+ fcoe_percpu_thread_destroy(cpu);
+ }
+
+ /* detach from scsi transport */
+ fcoe_if_exit();
+}
+module_exit(fcoe_exit);
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h
new file mode 100644
index 00000000000..917aae88689
--- /dev/null
+++ b/drivers/scsi/fcoe/fcoe.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+#ifndef _FCOE_H_
+#define _FCOE_H_
+
+#include <linux/skbuff.h>
+#include <linux/kthread.h>
+
+#define FCOE_MAX_QUEUE_DEPTH 256
+#define FCOE_LOW_QUEUE_DEPTH 32
+
+#define FCOE_WORD_TO_BYTE 4
+
+#define FCOE_VERSION "0.1"
+#define FCOE_NAME "fcoe"
+#define FCOE_VENDOR "Open-FCoE.org"
+
+#define FCOE_MAX_LUN 255
+#define FCOE_MAX_FCP_TARGET 256
+
+#define FCOE_MAX_OUTSTANDING_COMMANDS 1024
+
+#define FCOE_MIN_XID 0x0001 /* the min xid supported by fcoe_sw */
+#define FCOE_MAX_XID 0x07ef /* the max xid supported by fcoe_sw */
+
+/*
+ * this percpu struct for fcoe
+ */
+struct fcoe_percpu_s {
+ struct task_struct *thread;
+ struct sk_buff_head fcoe_rx_list;
+ struct page *crc_eof_page;
+ int crc_eof_offset;
+};
+
+/*
+ * the fcoe sw transport private data
+ */
+struct fcoe_softc {
+ struct list_head list;
+ struct net_device *real_dev;
+ struct net_device *phys_dev; /* device with ethtool_ops */
+ struct packet_type fcoe_packet_type;
+ struct packet_type fip_packet_type;
+ struct sk_buff_head fcoe_pending_queue;
+ u8 fcoe_pending_queue_active;
+ struct fcoe_ctlr ctlr;
+};
+
+#define fcoe_from_ctlr(fc) container_of(fc, struct fcoe_softc, ctlr)
+
+static inline struct net_device *fcoe_netdev(
+ const struct fc_lport *lp)
+{
+ return ((struct fcoe_softc *)lport_priv(lp))->real_dev;
+}
+
+#endif /* _FCOE_H_ */
diff --git a/drivers/scsi/fcoe/fcoe_sw.c b/drivers/scsi/fcoe/fcoe_sw.c
deleted file mode 100644
index 2bbbe3c0cc7..00000000000
--- a/drivers/scsi/fcoe/fcoe_sw.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Maintained at www.Open-FCoE.org
- */
-
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/if_vlan.h>
-#include <net/rtnetlink.h>
-
-#include <scsi/fc/fc_els.h>
-#include <scsi/fc/fc_encaps.h>
-#include <scsi/fc/fc_fs.h>
-#include <scsi/scsi_transport.h>
-#include <scsi/scsi_transport_fc.h>
-
-#include <scsi/libfc.h>
-#include <scsi/libfcoe.h>
-#include <scsi/fc_transport_fcoe.h>
-
-#define FCOE_SW_VERSION "0.1"
-#define FCOE_SW_NAME "fcoesw"
-#define FCOE_SW_VENDOR "Open-FCoE.org"
-
-#define FCOE_MAX_LUN 255
-#define FCOE_MAX_FCP_TARGET 256
-
-#define FCOE_MAX_OUTSTANDING_COMMANDS 1024
-
-#define FCOE_MIN_XID 0x0001 /* the min xid supported by fcoe_sw */
-#define FCOE_MAX_XID 0x07ef /* the max xid supported by fcoe_sw */
-
-static struct scsi_transport_template *scsi_transport_fcoe_sw;
-
-struct fc_function_template fcoe_sw_transport_function = {
- .show_host_node_name = 1,
- .show_host_port_name = 1,
- .show_host_supported_classes = 1,
- .show_host_supported_fc4s = 1,
- .show_host_active_fc4s = 1,
- .show_host_maxframe_size = 1,
-
- .show_host_port_id = 1,
- .show_host_supported_speeds = 1,
- .get_host_speed = fc_get_host_speed,
- .show_host_speed = 1,
- .show_host_port_type = 1,
- .get_host_port_state = fc_get_host_port_state,
- .show_host_port_state = 1,
- .show_host_symbolic_name = 1,
-
- .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
- .show_rport_maxframe_size = 1,
- .show_rport_supported_classes = 1,
-
- .show_host_fabric_name = 1,
- .show_starget_node_name = 1,
- .show_starget_port_name = 1,
- .show_starget_port_id = 1,
- .set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
- .show_rport_dev_loss_tmo = 1,
- .get_fc_host_stats = fc_get_host_stats,
- .issue_fc_host_lip = fcoe_reset,
-
- .terminate_rport_io = fc_rport_terminate_io,
-};
-
-static struct scsi_host_template fcoe_sw_shost_template = {
- .module = THIS_MODULE,
- .name = "FCoE Driver",
- .proc_name = FCOE_SW_NAME,
- .queuecommand = fc_queuecommand,
- .eh_abort_handler = fc_eh_abort,
- .eh_device_reset_handler = fc_eh_device_reset,
- .eh_host_reset_handler = fc_eh_host_reset,
- .slave_alloc = fc_slave_alloc,
- .change_queue_depth = fc_change_queue_depth,
- .change_queue_type = fc_change_queue_type,
- .this_id = -1,
- .cmd_per_lun = 32,
- .can_queue = FCOE_MAX_OUTSTANDING_COMMANDS,
- .use_clustering = ENABLE_CLUSTERING,
- .sg_tablesize = SG_ALL,
- .max_sectors = 0xffff,
-};
-
-/**
- * fcoe_sw_lport_config() - sets up the fc_lport
- * @lp: ptr to the fc_lport
- * @shost: ptr to the parent scsi host
- *
- * Returns: 0 for success
- */
-static int fcoe_sw_lport_config(struct fc_lport *lp)
-{
- int i = 0;
-
- lp->link_up = 0;
- lp->qfull = 0;
- lp->max_retry_count = 3;
- lp->e_d_tov = 2 * 1000; /* FC-FS default */
- lp->r_a_tov = 2 * 2 * 1000;
- lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
- FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
-
- /*
- * allocate per cpu stats block
- */
- for_each_online_cpu(i)
- lp->dev_stats[i] = kzalloc(sizeof(struct fcoe_dev_stats),
- GFP_KERNEL);
-
- /* lport fc_lport related configuration */
- fc_lport_config(lp);
-
- /* offload related configuration */
- lp->crc_offload = 0;
- lp->seq_offload = 0;
- lp->lro_enabled = 0;
- lp->lro_xid = 0;
- lp->lso_max = 0;
-
- return 0;
-}
-
-/**
- * fcoe_sw_netdev_config() - Set up netdev for SW FCoE
- * @lp : ptr to the fc_lport
- * @netdev : ptr to the associated netdevice struct
- *
- * Must be called after fcoe_sw_lport_config() as it will use lport mutex
- *
- * Returns : 0 for success
- */
-static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev)
-{
- u32 mfs;
- u64 wwnn, wwpn;
- struct fcoe_softc *fc;
- u8 flogi_maddr[ETH_ALEN];
-
- /* Setup lport private data to point to fcoe softc */
- fc = lport_priv(lp);
- fc->lp = lp;
- fc->real_dev = netdev;
- fc->phys_dev = netdev;
-
- /* Require support for get_pauseparam ethtool op. */
- if (netdev->priv_flags & IFF_802_1Q_VLAN)
- fc->phys_dev = vlan_dev_real_dev(netdev);
-
- /* Do not support for bonding device */
- if ((fc->real_dev->priv_flags & IFF_MASTER_ALB) ||
- (fc->real_dev->priv_flags & IFF_SLAVE_INACTIVE) ||
- (fc->real_dev->priv_flags & IFF_MASTER_8023AD)) {
- return -EOPNOTSUPP;
- }
-
- /*
- * Determine max frame size based on underlying device and optional
- * user-configured limit. If the MFS is too low, fcoe_link_ok()
- * will return 0, so do this first.
- */
- mfs = fc->real_dev->mtu - (sizeof(struct fcoe_hdr) +
- sizeof(struct fcoe_crc_eof));
- if (fc_set_mfs(lp, mfs))
- return -EINVAL;
-
- if (!fcoe_link_ok(lp))
- lp->link_up = 1;
-
- /* offload features support */
- if (fc->real_dev->features & NETIF_F_SG)
- lp->sg_supp = 1;
-
-#ifdef NETIF_F_FCOE_CRC
- if (netdev->features & NETIF_F_FCOE_CRC) {
- lp->crc_offload = 1;
- printk(KERN_DEBUG "fcoe:%s supports FCCRC offload\n",
- netdev->name);
- }
-#endif
-#ifdef NETIF_F_FSO
- if (netdev->features & NETIF_F_FSO) {
- lp->seq_offload = 1;
- lp->lso_max = netdev->gso_max_size;
- printk(KERN_DEBUG "fcoe:%s supports LSO for max len 0x%x\n",
- netdev->name, lp->lso_max);
- }
-#endif
- if (netdev->fcoe_ddp_xid) {
- lp->lro_enabled = 1;
- lp->lro_xid = netdev->fcoe_ddp_xid;
- printk(KERN_DEBUG "fcoe:%s supports LRO for max xid 0x%x\n",
- netdev->name, lp->lro_xid);
- }
- skb_queue_head_init(&fc->fcoe_pending_queue);
- fc->fcoe_pending_queue_active = 0;
-
- /* setup Source Mac Address */
- memcpy(fc->ctl_src_addr, fc->real_dev->dev_addr,
- fc->real_dev->addr_len);
-
- wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
- fc_set_wwnn(lp, wwnn);
- /* XXX - 3rd arg needs to be vlan id */
- wwpn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 2, 0);
- fc_set_wwpn(lp, wwpn);
-
- /*
- * Add FCoE MAC address as second unicast MAC address
- * or enter promiscuous mode if not capable of listening
- * for multiple unicast MACs.
- */
- rtnl_lock();
- memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
- dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN);
- rtnl_unlock();
-
- /*
- * setup the receive function from ethernet driver
- * on the ethertype for the given device
- */
- fc->fcoe_packet_type.func = fcoe_rcv;
- fc->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE);
- fc->fcoe_packet_type.dev = fc->real_dev;
- dev_add_pack(&fc->fcoe_packet_type);
-
- return 0;
-}
-
-/**
- * fcoe_sw_shost_config() - Sets up fc_lport->host
- * @lp : ptr to the fc_lport
- * @shost : ptr to the associated scsi host
- * @dev : device associated to scsi host
- *
- * Must be called after fcoe_sw_lport_config() and fcoe_sw_netdev_config()
- *
- * Returns : 0 for success
- */
-static int fcoe_sw_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
- struct device *dev)
-{
- int rc = 0;
-
- /* lport scsi host config */
- lp->host = shost;
-
- lp->host->max_lun = FCOE_MAX_LUN;
- lp->host->max_id = FCOE_MAX_FCP_TARGET;
- lp->host->max_channel = 0;
- lp->host->transportt = scsi_transport_fcoe_sw;
-
- /* add the new host to the SCSI-ml */
- rc = scsi_add_host(lp->host, dev);
- if (rc) {
- FC_DBG("fcoe_sw_shost_config:error on scsi_add_host\n");
- return rc;
- }
- sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
- FCOE_SW_NAME, FCOE_SW_VERSION,
- fcoe_netdev(lp)->name);
-
- return 0;
-}
-
-/**
- * fcoe_sw_em_config() - allocates em for this lport
- * @lp: the port that em is to allocated for
- *
- * Returns : 0 on success
- */
-static inline int fcoe_sw_em_config(struct fc_lport *lp)
-{
- BUG_ON(lp->emp);
-
- lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3,
- FCOE_MIN_XID, FCOE_MAX_XID);
- if (!lp->emp)
- return -ENOMEM;
-
- return 0;
-}
-
-/**
- * fcoe_sw_destroy() - FCoE software HBA tear-down function
- * @netdev: ptr to the associated net_device
- *
- * Returns: 0 if link is OK for use by FCoE.
- */
-static int fcoe_sw_destroy(struct net_device *netdev)
-{
- int cpu;
- struct fc_lport *lp = NULL;
- struct fcoe_softc *fc;
- u8 flogi_maddr[ETH_ALEN];
-
- BUG_ON(!netdev);
-
- printk(KERN_DEBUG "fcoe_sw_destroy:interface on %s\n",
- netdev->name);
-
- lp = fcoe_hostlist_lookup(netdev);
- if (!lp)
- return -ENODEV;
-
- fc = lport_priv(lp);
-
- /* Logout of the fabric */
- fc_fabric_logoff(lp);
-
- /* Remove the instance from fcoe's list */
- fcoe_hostlist_remove(lp);
-
- /* Don't listen for Ethernet packets anymore */
- dev_remove_pack(&fc->fcoe_packet_type);
-
- /* Cleanup the fc_lport */
- fc_lport_destroy(lp);
- fc_fcp_destroy(lp);
-
- /* Detach from the scsi-ml */
- fc_remove_host(lp->host);
- scsi_remove_host(lp->host);
-
- /* There are no more rports or I/O, free the EM */
- if (lp->emp)
- fc_exch_mgr_free(lp->emp);
-
- /* Delete secondary MAC addresses */
- rtnl_lock();
- memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
- dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN);
- if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 }))
- dev_unicast_delete(fc->real_dev, fc->data_src_addr, ETH_ALEN);
- rtnl_unlock();
-
- /* Free the per-CPU revieve threads */
- fcoe_percpu_clean(lp);
-
- /* Free existing skbs */
- fcoe_clean_pending_queue(lp);
-
- /* Free memory used by statistical counters */
- for_each_online_cpu(cpu)
- kfree(lp->dev_stats[cpu]);
-
- /* Release the net_device and Scsi_Host */
- dev_put(fc->real_dev);
- scsi_host_put(lp->host);
-
- return 0;
-}
-
-/*
- * fcoe_sw_ddp_setup - calls LLD's ddp_setup through net_device
- * @lp: the corresponding fc_lport
- * @xid: the exchange id for this ddp transfer
- * @sgl: the scatterlist describing this transfer
- * @sgc: number of sg items
- *
- * Returns : 0 no ddp
- */
-static int fcoe_sw_ddp_setup(struct fc_lport *lp, u16 xid,
- struct scatterlist *sgl, unsigned int sgc)
-{
- struct net_device *n = fcoe_netdev(lp);
-
- if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup)
- return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc);
-
- return 0;
-}
-
-/*
- * fcoe_sw_ddp_done - calls LLD's ddp_done through net_device
- * @lp: the corresponding fc_lport
- * @xid: the exchange id for this ddp transfer
- *
- * Returns : the length of data that have been completed by ddp
- */
-static int fcoe_sw_ddp_done(struct fc_lport *lp, u16 xid)
-{
- struct net_device *n = fcoe_netdev(lp);
-
- if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done)
- return n->netdev_ops->ndo_fcoe_ddp_done(n, xid);
- return 0;
-}
-
-static struct libfc_function_template fcoe_sw_libfc_fcn_templ = {
- .frame_send = fcoe_xmit,
- .ddp_setup = fcoe_sw_ddp_setup,
- .ddp_done = fcoe_sw_ddp_done,
-};
-
-/**
- * fcoe_sw_create() - this function creates the fcoe interface
- * @netdev: pointer the associated netdevice
- *
- * Creates fc_lport struct and scsi_host for lport, configures lport
- * and starts fabric login.
- *
- * Returns : 0 on success
- */
-static int fcoe_sw_create(struct net_device *netdev)
-{
- int rc;
- struct fc_lport *lp = NULL;
- struct fcoe_softc *fc;
- struct Scsi_Host *shost;
-
- BUG_ON(!netdev);
-
- printk(KERN_DEBUG "fcoe_sw_create:interface on %s\n",
- netdev->name);
-
- lp = fcoe_hostlist_lookup(netdev);
- if (lp)
- return -EEXIST;
-
- shost = fcoe_host_alloc(&fcoe_sw_shost_template,
- sizeof(struct fcoe_softc));
- if (!shost) {
- FC_DBG("Could not allocate host structure\n");
- return -ENOMEM;
- }
- lp = shost_priv(shost);
- fc = lport_priv(lp);
-
- /* configure fc_lport, e.g., em */
- rc = fcoe_sw_lport_config(lp);
- if (rc) {
- FC_DBG("Could not configure lport\n");
- goto out_host_put;
- }
-
- /* configure lport network properties */
- rc = fcoe_sw_netdev_config(lp, netdev);
- if (rc) {
- FC_DBG("Could not configure netdev for lport\n");
- goto out_host_put;
- }
-
- /* configure lport scsi host properties */
- rc = fcoe_sw_shost_config(lp, shost, &netdev->dev);
- if (rc) {
- FC_DBG("Could not configure shost for lport\n");
- goto out_host_put;
- }
-
- /* lport exch manager allocation */
- rc = fcoe_sw_em_config(lp);
- if (rc) {
- FC_DBG("Could not configure em for lport\n");
- goto out_host_put;
- }
-
- /* Initialize the library */
- rc = fcoe_libfc_config(lp, &fcoe_sw_libfc_fcn_templ);
- if (rc) {
- FC_DBG("Could not configure libfc for lport!\n");
- goto out_lp_destroy;
- }
-
- /* add to lports list */
- fcoe_hostlist_add(lp);
-
- lp->boot_time = jiffies;
-
- fc_fabric_login(lp);
-
- dev_hold(netdev);
-
- return rc;
-
-out_lp_destroy:
- fc_exch_mgr_free(lp->emp); /* Free the EM */
-out_host_put:
- scsi_host_put(lp->host);
- return rc;
-}
-
-/**
- * fcoe_sw_match() - The FCoE SW transport match function
- *
- * Returns : false always
- */
-static bool fcoe_sw_match(struct net_device *netdev)
-{
- /* FIXME - for sw transport, always return false */
- return false;
-}
-
-/* the sw hba fcoe transport */
-struct fcoe_transport fcoe_sw_transport = {
- .name = "fcoesw",
- .create = fcoe_sw_create,
- .destroy = fcoe_sw_destroy,
- .match = fcoe_sw_match,
- .vendor = 0x0,
- .device = 0xffff,
-};
-
-/**
- * fcoe_sw_init() - Registers fcoe_sw_transport
- *
- * Returns : 0 on success
- */
-int __init fcoe_sw_init(void)
-{
- /* attach to scsi transport */
- scsi_transport_fcoe_sw =
- fc_attach_transport(&fcoe_sw_transport_function);
-
- if (!scsi_transport_fcoe_sw) {
- printk(KERN_ERR "fcoe_sw_init:fc_attach_transport() failed\n");
- return -ENODEV;
- }
-
- mutex_init(&fcoe_sw_transport.devlock);
- INIT_LIST_HEAD(&fcoe_sw_transport.devlist);
-
- /* register sw transport */
- fcoe_transport_register(&fcoe_sw_transport);
- return 0;
-}
-
-/**
- * fcoe_sw_exit() - Unregisters fcoe_sw_transport
- *
- * Returns : 0 on success
- */
-int __exit fcoe_sw_exit(void)
-{
- /* dettach the transport */
- fc_release_transport(scsi_transport_fcoe_sw);
- fcoe_transport_unregister(&fcoe_sw_transport);
- return 0;
-}
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 0d6f5beb7f9..f410f4abb54 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -1,5 +1,6 @@
/*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved.
+ * Copyright (c) 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -17,1200 +18,1260 @@
* Maintained at www.Open-FCoE.org
*/
+#include <linux/types.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/kernel.h>
+#include <linux/list.h>
#include <linux/spinlock.h>
-#include <linux/skbuff.h>
+#include <linux/timer.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
-#include <linux/kthread.h>
-#include <linux/crc32.h>
-#include <linux/cpu.h>
-#include <linux/fs.h>
-#include <linux/sysfs.h>
-#include <linux/ctype.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/scsicam.h>
-#include <scsi/scsi_transport.h>
-#include <scsi/scsi_transport_fc.h>
+#include <linux/netdevice.h>
+#include <linux/errno.h>
+#include <linux/bitops.h>
#include <net/rtnetlink.h>
+#include <scsi/fc/fc_els.h>
+#include <scsi/fc/fc_fs.h>
+#include <scsi/fc/fc_fip.h>
#include <scsi/fc/fc_encaps.h>
+#include <scsi/fc/fc_fcoe.h>
#include <scsi/libfc.h>
-#include <scsi/fc_frame.h>
#include <scsi/libfcoe.h>
-#include <scsi/fc_transport_fcoe.h>
-
-static int debug_fcoe;
-#define FCOE_MAX_QUEUE_DEPTH 256
-#define FCOE_LOW_QUEUE_DEPTH 32
+MODULE_AUTHOR("Open-FCoE.org");
+MODULE_DESCRIPTION("FIP discovery protocol support for FCoE HBAs");
+MODULE_LICENSE("GPL v2");
-/* destination address mode */
-#define FCOE_GW_ADDR_MODE 0x00
-#define FCOE_FCOUI_ADDR_MODE 0x01
+#define FCOE_CTLR_MIN_FKA 500 /* min keep alive (mS) */
+#define FCOE_CTLR_DEF_FKA FIP_DEF_FKA /* default keep alive (mS) */
-#define FCOE_WORD_TO_BYTE 4
+static void fcoe_ctlr_timeout(unsigned long);
+static void fcoe_ctlr_link_work(struct work_struct *);
+static void fcoe_ctlr_recv_work(struct work_struct *);
-MODULE_AUTHOR("Open-FCoE.org");
-MODULE_DESCRIPTION("FCoE");
-MODULE_LICENSE("GPL");
+static u8 fcoe_all_fcfs[ETH_ALEN] = FIP_ALL_FCF_MACS;
-/* fcoe host list */
-LIST_HEAD(fcoe_hostlist);
-DEFINE_RWLOCK(fcoe_hostlist_lock);
-DEFINE_TIMER(fcoe_timer, NULL, 0, 0);
-struct fcoe_percpu_s *fcoe_percpu[NR_CPUS];
+static u32 fcoe_ctlr_debug; /* 1 for basic, 2 for noisy debug */
+#define FIP_DBG_LVL(level, fmt, args...) \
+ do { \
+ if (fcoe_ctlr_debug >= (level)) \
+ FC_DBG(fmt, ##args); \
+ } while (0)
-/* Function Prototyes */
-static int fcoe_check_wait_queue(struct fc_lport *);
-static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *);
-#ifdef CONFIG_HOTPLUG_CPU
-static int fcoe_cpu_callback(struct notifier_block *, ulong, void *);
-#endif /* CONFIG_HOTPLUG_CPU */
-static int fcoe_device_notification(struct notifier_block *, ulong, void *);
-static void fcoe_dev_setup(void);
-static void fcoe_dev_cleanup(void);
+#define FIP_DBG(fmt, args...) FIP_DBG_LVL(1, fmt, ##args)
-/* notification function from net device */
-static struct notifier_block fcoe_notifier = {
- .notifier_call = fcoe_device_notification,
-};
+/*
+ * Return non-zero if FCF fcoe_size has been validated.
+ */
+static inline int fcoe_ctlr_mtu_valid(const struct fcoe_fcf *fcf)
+{
+ return (fcf->flags & FIP_FL_SOL) != 0;
+}
+/*
+ * Return non-zero if the FCF is usable.
+ */
+static inline int fcoe_ctlr_fcf_usable(struct fcoe_fcf *fcf)
+{
+ u16 flags = FIP_FL_SOL | FIP_FL_AVAIL;
-#ifdef CONFIG_HOTPLUG_CPU
-static struct notifier_block fcoe_cpu_notifier = {
- .notifier_call = fcoe_cpu_callback,
-};
+ return (fcf->flags & flags) == flags;
+}
/**
- * fcoe_create_percpu_data() - creates the associated cpu data
- * @cpu: index for the cpu where fcoe cpu data will be created
- *
- * create percpu stats block, from cpu add notifier
- *
- * Returns: none
+ * fcoe_ctlr_init() - Initialize the FCoE Controller instance.
+ * @fip: FCoE controller.
*/
-static void fcoe_create_percpu_data(int cpu)
+void fcoe_ctlr_init(struct fcoe_ctlr *fip)
{
- struct fc_lport *lp;
- struct fcoe_softc *fc;
-
- write_lock_bh(&fcoe_hostlist_lock);
- list_for_each_entry(fc, &fcoe_hostlist, list) {
- lp = fc->lp;
- if (lp->dev_stats[cpu] == NULL)
- lp->dev_stats[cpu] =
- kzalloc(sizeof(struct fcoe_dev_stats),
- GFP_KERNEL);
- }
- write_unlock_bh(&fcoe_hostlist_lock);
+ fip->state = FIP_ST_LINK_WAIT;
+ INIT_LIST_HEAD(&fip->fcfs);
+ spin_lock_init(&fip->lock);
+ fip->flogi_oxid = FC_XID_UNKNOWN;
+ setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip);
+ INIT_WORK(&fip->link_work, fcoe_ctlr_link_work);
+ INIT_WORK(&fip->recv_work, fcoe_ctlr_recv_work);
+ skb_queue_head_init(&fip->fip_recv_list);
}
+EXPORT_SYMBOL(fcoe_ctlr_init);
/**
- * fcoe_destroy_percpu_data() - destroys the associated cpu data
- * @cpu: index for the cpu where fcoe cpu data will destroyed
- *
- * destroy percpu stats block called by cpu add/remove notifier
+ * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller.
+ * @fip: FCoE controller.
*
- * Retuns: none
+ * Called with &fcoe_ctlr lock held.
*/
-static void fcoe_destroy_percpu_data(int cpu)
+static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip)
{
- struct fc_lport *lp;
- struct fcoe_softc *fc;
+ struct fcoe_fcf *fcf;
+ struct fcoe_fcf *next;
- write_lock_bh(&fcoe_hostlist_lock);
- list_for_each_entry(fc, &fcoe_hostlist, list) {
- lp = fc->lp;
- kfree(lp->dev_stats[cpu]);
- lp->dev_stats[cpu] = NULL;
+ fip->sel_fcf = NULL;
+ list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
+ list_del(&fcf->list);
+ kfree(fcf);
}
- write_unlock_bh(&fcoe_hostlist_lock);
+ fip->fcf_count = 0;
+ fip->sel_time = 0;
}
/**
- * fcoe_cpu_callback() - fcoe cpu hotplug event callback
- * @nfb: callback data block
- * @action: event triggering the callback
- * @hcpu: index for the cpu of this event
+ * fcoe_ctrl_destroy() - Disable and tear-down the FCoE controller.
+ * @fip: FCoE controller.
+ *
+ * This is called by FCoE drivers before freeing the &fcoe_ctlr.
*
- * this creates or destroys per cpu data for fcoe
+ * The receive handler will have been deleted before this to guarantee
+ * that no more recv_work will be scheduled.
*
- * Returns NOTIFY_OK always.
+ * The timer routine will simply return once we set FIP_ST_DISABLED.
+ * This guarantees that no further timeouts or work will be scheduled.
*/
-static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action,
- void *hcpu)
+void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
{
- unsigned int cpu = (unsigned long)hcpu;
-
- switch (action) {
- case CPU_ONLINE:
- fcoe_create_percpu_data(cpu);
- break;
- case CPU_DEAD:
- fcoe_destroy_percpu_data(cpu);
- break;
- default:
- break;
- }
- return NOTIFY_OK;
+ flush_work(&fip->recv_work);
+ spin_lock_bh(&fip->lock);
+ fip->state = FIP_ST_DISABLED;
+ fcoe_ctlr_reset_fcfs(fip);
+ spin_unlock_bh(&fip->lock);
+ del_timer_sync(&fip->timer);
+ flush_work(&fip->link_work);
}
-#endif /* CONFIG_HOTPLUG_CPU */
+EXPORT_SYMBOL(fcoe_ctlr_destroy);
/**
- * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ
- * @skb: the receive skb
- * @dev: associated net device
- * @ptype: context
- * @odldev: last device
- *
- * this function will receive the packet and build fc frame and pass it up
+ * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port.
+ * @fip: FCoE controller.
*
- * Returns: 0 for success
+ * Returns the maximum packet size including the FCoE header and trailer,
+ * but not including any Ethernet or VLAN headers.
*/
-int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *ptype, struct net_device *olddev)
+static inline u32 fcoe_ctlr_fcoe_size(struct fcoe_ctlr *fip)
{
- struct fc_lport *lp;
- struct fcoe_rcv_info *fr;
- struct fcoe_softc *fc;
- struct fcoe_dev_stats *stats;
- struct fc_frame_header *fh;
- unsigned short oxid;
- int cpu_idx;
- struct fcoe_percpu_s *fps;
-
- fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type);
- lp = fc->lp;
- if (unlikely(lp == NULL)) {
- FC_DBG("cannot find hba structure");
- goto err2;
- }
-
- if (unlikely(debug_fcoe)) {
- FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p tail:%p "
- "end:%p sum:%d dev:%s", skb->len, skb->data_len,
- skb->head, skb->data, skb_tail_pointer(skb),
- skb_end_pointer(skb), skb->csum,
- skb->dev ? skb->dev->name : "<NULL>");
+ /*
+ * Determine the max FCoE frame size allowed, including
+ * FCoE header and trailer.
+ * Note: lp->mfs is currently the payload size, not the frame size.
+ */
+ return fip->lp->mfs + sizeof(struct fc_frame_header) +
+ sizeof(struct fcoe_hdr) + sizeof(struct fcoe_crc_eof);
+}
- }
+/**
+ * fcoe_ctlr_solicit() - Send a solicitation.
+ * @fip: FCoE controller.
+ * @fcf: Destination FCF. If NULL, a multicast solicitation is sent.
+ */
+static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf)
+{
+ struct sk_buff *skb;
+ struct fip_sol {
+ struct ethhdr eth;
+ struct fip_header fip;
+ struct {
+ struct fip_mac_desc mac;
+ struct fip_wwn_desc wwnn;
+ struct fip_size_desc size;
+ } __attribute__((packed)) desc;
+ } __attribute__((packed)) *sol;
+ u32 fcoe_size;
+
+ skb = dev_alloc_skb(sizeof(*sol));
+ if (!skb)
+ return;
- /* check for FCOE packet type */
- if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
- FC_DBG("wrong FC type frame");
- goto err;
- }
+ sol = (struct fip_sol *)skb->data;
- /*
- * Check for minimum frame length, and make sure required FCoE
- * and FC headers are pulled into the linear data area.
- */
- if (unlikely((skb->len < FCOE_MIN_FRAME) ||
- !pskb_may_pull(skb, FCOE_HEADER_LEN)))
- goto err;
+ memset(sol, 0, sizeof(*sol));
+ memcpy(sol->eth.h_dest, fcf ? fcf->fcf_mac : fcoe_all_fcfs, ETH_ALEN);
+ memcpy(sol->eth.h_source, fip->ctl_src_addr, ETH_ALEN);
+ sol->eth.h_proto = htons(ETH_P_FIP);
- skb_set_transport_header(skb, sizeof(struct fcoe_hdr));
- fh = (struct fc_frame_header *) skb_transport_header(skb);
+ sol->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
+ sol->fip.fip_op = htons(FIP_OP_DISC);
+ sol->fip.fip_subcode = FIP_SC_SOL;
+ sol->fip.fip_dl_len = htons(sizeof(sol->desc) / FIP_BPW);
+ sol->fip.fip_flags = htons(FIP_FL_FPMA);
- oxid = ntohs(fh->fh_ox_id);
+ sol->desc.mac.fd_desc.fip_dtype = FIP_DT_MAC;
+ sol->desc.mac.fd_desc.fip_dlen = sizeof(sol->desc.mac) / FIP_BPW;
+ memcpy(sol->desc.mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);
- fr = fcoe_dev_from_skb(skb);
- fr->fr_dev = lp;
- fr->ptype = ptype;
- cpu_idx = 0;
-#ifdef CONFIG_SMP
- /*
- * The incoming frame exchange id(oxid) is ANDed with num of online
- * cpu bits to get cpu_idx and then this cpu_idx is used for selecting
- * a per cpu kernel thread from fcoe_percpu. In case the cpu is
- * offline or no kernel thread for derived cpu_idx then cpu_idx is
- * initialize to first online cpu index.
- */
- cpu_idx = oxid & (num_online_cpus() - 1);
- if (!fcoe_percpu[cpu_idx] || !cpu_online(cpu_idx))
- cpu_idx = first_cpu(cpu_online_map);
-#endif
- fps = fcoe_percpu[cpu_idx];
+ sol->desc.wwnn.fd_desc.fip_dtype = FIP_DT_NAME;
+ sol->desc.wwnn.fd_desc.fip_dlen = sizeof(sol->desc.wwnn) / FIP_BPW;
+ put_unaligned_be64(fip->lp->wwnn, &sol->desc.wwnn.fd_wwn);
- spin_lock_bh(&fps->fcoe_rx_list.lock);
- __skb_queue_tail(&fps->fcoe_rx_list, skb);
- if (fps->fcoe_rx_list.qlen == 1)
- wake_up_process(fps->thread);
+ fcoe_size = fcoe_ctlr_fcoe_size(fip);
+ sol->desc.size.fd_desc.fip_dtype = FIP_DT_FCOE_SIZE;
+ sol->desc.size.fd_desc.fip_dlen = sizeof(sol->desc.size) / FIP_BPW;
+ sol->desc.size.fd_size = htons(fcoe_size);
- spin_unlock_bh(&fps->fcoe_rx_list.lock);
+ skb_put(skb, sizeof(*sol));
+ skb->protocol = htons(ETH_P_802_3);
+ skb_reset_mac_header(skb);
+ skb_reset_network_header(skb);
+ fip->send(fip, skb);
- return 0;
-err:
-#ifdef CONFIG_SMP
- stats = lp->dev_stats[smp_processor_id()];
-#else
- stats = lp->dev_stats[0];
-#endif
- if (stats)
- stats->ErrorFrames++;
-
-err2:
- kfree_skb(skb);
- return -1;
+ if (!fcf)
+ fip->sol_time = jiffies;
}
-EXPORT_SYMBOL_GPL(fcoe_rcv);
/**
- * fcoe_start_io() - pass to netdev to start xmit for fcoe
- * @skb: the skb to be xmitted
+ * fcoe_ctlr_link_up() - Start FCoE controller.
+ * @fip: FCoE controller.
*
- * Returns: 0 for success
+ * Called from the LLD when the network link is ready.
*/
-static inline int fcoe_start_io(struct sk_buff *skb)
+void fcoe_ctlr_link_up(struct fcoe_ctlr *fip)
{
- int rc;
-
- skb_get(skb);
- rc = dev_queue_xmit(skb);
- if (rc != 0)
- return rc;
- kfree_skb(skb);
- return 0;
+ spin_lock_bh(&fip->lock);
+ if (fip->state == FIP_ST_NON_FIP || fip->state == FIP_ST_AUTO) {
+ fip->last_link = 1;
+ fip->link = 1;
+ spin_unlock_bh(&fip->lock);
+ fc_linkup(fip->lp);
+ } else if (fip->state == FIP_ST_LINK_WAIT) {
+ fip->state = FIP_ST_AUTO;
+ fip->last_link = 1;
+ fip->link = 1;
+ spin_unlock_bh(&fip->lock);
+ FIP_DBG("%s", "setting AUTO mode.\n");
+ fc_linkup(fip->lp);
+ fcoe_ctlr_solicit(fip, NULL);
+ } else
+ spin_unlock_bh(&fip->lock);
}
+EXPORT_SYMBOL(fcoe_ctlr_link_up);
/**
- * fcoe_get_paged_crc_eof() - in case we need alloc a page for crc_eof
- * @skb: the skb to be xmitted
- * @tlen: total len
+ * fcoe_ctlr_reset() - Reset FIP.
+ * @fip: FCoE controller.
+ * @new_state: FIP state to be entered.
*
- * Returns: 0 for success
+ * Returns non-zero if the link was up and now isn't.
*/
-static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen)
+static int fcoe_ctlr_reset(struct fcoe_ctlr *fip, enum fip_state new_state)
{
- struct fcoe_percpu_s *fps;
- struct page *page;
- int cpu_idx;
-
- cpu_idx = get_cpu();
- fps = fcoe_percpu[cpu_idx];
- page = fps->crc_eof_page;
- if (!page) {
- page = alloc_page(GFP_ATOMIC);
- if (!page) {
- put_cpu();
- return -ENOMEM;
- }
- fps->crc_eof_page = page;
- WARN_ON(fps->crc_eof_offset != 0);
+ struct fc_lport *lp = fip->lp;
+ int link_dropped;
+
+ spin_lock_bh(&fip->lock);
+ fcoe_ctlr_reset_fcfs(fip);
+ del_timer(&fip->timer);
+ fip->state = new_state;
+ fip->ctlr_ka_time = 0;
+ fip->port_ka_time = 0;
+ fip->sol_time = 0;
+ fip->flogi_oxid = FC_XID_UNKNOWN;
+ fip->map_dest = 0;
+ fip->last_link = 0;
+ link_dropped = fip->link;
+ fip->link = 0;
+ spin_unlock_bh(&fip->lock);
+
+ if (link_dropped)
+ fc_linkdown(lp);
+
+ if (new_state == FIP_ST_ENABLED) {
+ fcoe_ctlr_solicit(fip, NULL);
+ fc_linkup(lp);
+ link_dropped = 0;
}
-
- get_page(page);
- skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page,
- fps->crc_eof_offset, tlen);
- skb->len += tlen;
- skb->data_len += tlen;
- skb->truesize += tlen;
- fps->crc_eof_offset += sizeof(struct fcoe_crc_eof);
-
- if (fps->crc_eof_offset >= PAGE_SIZE) {
- fps->crc_eof_page = NULL;
- fps->crc_eof_offset = 0;
- put_page(page);
- }
- put_cpu();
- return 0;
+ return link_dropped;
}
/**
- * fcoe_fc_crc() - calculates FC CRC in this fcoe skb
- * @fp: the fc_frame containg data to be checksummed
+ * fcoe_ctlr_link_down() - Stop FCoE controller.
+ * @fip: FCoE controller.
*
- * This uses crc32() to calculate the crc for fc frame
- * Return : 32 bit crc
+ * Returns non-zero if the link was up and now isn't.
+ *
+ * Called from the LLD when the network link is not ready.
+ * There may be multiple calls while the link is down.
*/
-u32 fcoe_fc_crc(struct fc_frame *fp)
+int fcoe_ctlr_link_down(struct fcoe_ctlr *fip)
{
- struct sk_buff *skb = fp_skb(fp);
- struct skb_frag_struct *frag;
- unsigned char *data;
- unsigned long off, len, clen;
- u32 crc;
- unsigned i;
-
- crc = crc32(~0, skb->data, skb_headlen(skb));
-
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- frag = &skb_shinfo(skb)->frags[i];
- off = frag->page_offset;
- len = frag->size;
- while (len > 0) {
- clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
- data = kmap_atomic(frag->page + (off >> PAGE_SHIFT),
- KM_SKB_DATA_SOFTIRQ);
- crc = crc32(crc, data + (off & ~PAGE_MASK), clen);
- kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ);
- off += clen;
- len -= clen;
- }
- }
- return crc;
+ return fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT);
}
-EXPORT_SYMBOL_GPL(fcoe_fc_crc);
+EXPORT_SYMBOL(fcoe_ctlr_link_down);
/**
- * fcoe_xmit() - FCoE frame transmit function
- * @lp: the associated local port
- * @fp: the fc_frame to be transmitted
+ * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF.
+ * @fip: FCoE controller.
+ * @ports: 0 for controller keep-alive, 1 for port keep-alive.
+ * @sa: source MAC address.
*
- * Return : 0 for success
+ * A controller keep-alive is sent every fka_period (typically 8 seconds).
+ * The source MAC is the native MAC address.
+ *
+ * A port keep-alive is sent every 90 seconds while logged in.
+ * The source MAC is the assigned mapped source address.
+ * The destination is the FCF's F-port.
*/
-int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
+static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa)
{
- int wlen, rc = 0;
- u32 crc;
- struct ethhdr *eh;
- struct fcoe_crc_eof *cp;
struct sk_buff *skb;
- struct fcoe_dev_stats *stats;
- struct fc_frame_header *fh;
- unsigned int hlen; /* header length implies the version */
- unsigned int tlen; /* trailer length */
- unsigned int elen; /* eth header, may include vlan */
- int flogi_in_progress = 0;
- struct fcoe_softc *fc;
- u8 sof, eof;
- struct fcoe_hdr *hp;
-
- WARN_ON((fr_len(fp) % sizeof(u32)) != 0);
-
- fc = lport_priv(lp);
- /*
- * if it is a flogi then we need to learn gw-addr
- * and my own fcid
- */
- fh = fc_frame_header_get(fp);
- if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ)) {
- if (fc_frame_payload_op(fp) == ELS_FLOGI) {
- fc->flogi_oxid = ntohs(fh->fh_ox_id);
- fc->address_mode = FCOE_FCOUI_ADDR_MODE;
- fc->flogi_progress = 1;
- flogi_in_progress = 1;
- } else if (fc->flogi_progress && ntoh24(fh->fh_s_id) != 0) {
- /*
- * Here we must've gotten an SID by accepting an FLOGI
- * from a point-to-point connection. Switch to using
- * the source mac based on the SID. The destination
- * MAC in this case would have been set by receving the
- * FLOGI.
- */
- fc_fcoe_set_mac(fc->data_src_addr, fh->fh_s_id);
- fc->flogi_progress = 0;
- }
- }
-
- skb = fp_skb(fp);
- sof = fr_sof(fp);
- eof = fr_eof(fp);
-
- elen = (fc->real_dev->priv_flags & IFF_802_1Q_VLAN) ?
- sizeof(struct vlan_ethhdr) : sizeof(struct ethhdr);
- hlen = sizeof(struct fcoe_hdr);
- tlen = sizeof(struct fcoe_crc_eof);
- wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
-
- /* crc offload */
- if (likely(lp->crc_offload)) {
- skb->ip_summed = CHECKSUM_PARTIAL;
- skb->csum_start = skb_headroom(skb);
- skb->csum_offset = skb->len;
- crc = 0;
- } else {
- skb->ip_summed = CHECKSUM_NONE;
- crc = fcoe_fc_crc(fp);
- }
+ struct fip_kal {
+ struct ethhdr eth;
+ struct fip_header fip;
+ struct fip_mac_desc mac;
+ } __attribute__((packed)) *kal;
+ struct fip_vn_desc *vn;
+ u32 len;
+ struct fc_lport *lp;
+ struct fcoe_fcf *fcf;
- /* copy fc crc and eof to the skb buff */
- if (skb_is_nonlinear(skb)) {
- skb_frag_t *frag;
- if (fcoe_get_paged_crc_eof(skb, tlen)) {
- kfree_skb(skb);
- return -ENOMEM;
- }
- frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
- cp = kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ)
- + frag->page_offset;
- } else {
- cp = (struct fcoe_crc_eof *)skb_put(skb, tlen);
- }
+ fcf = fip->sel_fcf;
+ lp = fip->lp;
+ if (!fcf || !fc_host_port_id(lp->host))
+ return;
- memset(cp, 0, sizeof(*cp));
- cp->fcoe_eof = eof;
- cp->fcoe_crc32 = cpu_to_le32(~crc);
+ len = fcoe_ctlr_fcoe_size(fip) + sizeof(struct ethhdr);
+ BUG_ON(len < sizeof(*kal) + sizeof(*vn));
+ skb = dev_alloc_skb(len);
+ if (!skb)
+ return;
- if (skb_is_nonlinear(skb)) {
- kunmap_atomic(cp, KM_SKB_DATA_SOFTIRQ);
- cp = NULL;
+ kal = (struct fip_kal *)skb->data;
+ memset(kal, 0, len);
+ memcpy(kal->eth.h_dest, fcf->fcf_mac, ETH_ALEN);
+ memcpy(kal->eth.h_source, sa, ETH_ALEN);
+ kal->eth.h_proto = htons(ETH_P_FIP);
+
+ kal->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
+ kal->fip.fip_op = htons(FIP_OP_CTRL);
+ kal->fip.fip_subcode = FIP_SC_KEEP_ALIVE;
+ kal->fip.fip_dl_len = htons((sizeof(kal->mac) +
+ ports * sizeof(*vn)) / FIP_BPW);
+ kal->fip.fip_flags = htons(FIP_FL_FPMA);
+
+ kal->mac.fd_desc.fip_dtype = FIP_DT_MAC;
+ kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW;
+ memcpy(kal->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);
+
+ if (ports) {
+ vn = (struct fip_vn_desc *)(kal + 1);
+ vn->fd_desc.fip_dtype = FIP_DT_VN_ID;
+ vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW;
+ memcpy(vn->fd_mac, fip->data_src_addr, ETH_ALEN);
+ hton24(vn->fd_fc_id, fc_host_port_id(lp->host));
+ put_unaligned_be64(lp->wwpn, &vn->fd_wwpn);
}
- /* adjust skb netowrk/transport offsets to match mac/fcoe/fc */
- skb_push(skb, elen + hlen);
+ skb_put(skb, len);
+ skb->protocol = htons(ETH_P_802_3);
skb_reset_mac_header(skb);
skb_reset_network_header(skb);
- skb->mac_len = elen;
- skb->protocol = htons(ETH_P_FCOE);
- skb->dev = fc->real_dev;
-
- /* fill up mac and fcoe headers */
- eh = eth_hdr(skb);
- eh->h_proto = htons(ETH_P_FCOE);
- if (fc->address_mode == FCOE_FCOUI_ADDR_MODE)
- fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id);
- else
- /* insert GW address */
- memcpy(eh->h_dest, fc->dest_addr, ETH_ALEN);
-
- if (unlikely(flogi_in_progress))
- memcpy(eh->h_source, fc->ctl_src_addr, ETH_ALEN);
- else
- memcpy(eh->h_source, fc->data_src_addr, ETH_ALEN);
-
- hp = (struct fcoe_hdr *)(eh + 1);
- memset(hp, 0, sizeof(*hp));
- if (FC_FCOE_VER)
- FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER);
- hp->fcoe_sof = sof;
-
-#ifdef NETIF_F_FSO
- /* fcoe lso, mss is in max_payload which is non-zero for FCP data */
- if (lp->seq_offload && fr_max_payload(fp)) {
- skb_shinfo(skb)->gso_type = SKB_GSO_FCOE;
- skb_shinfo(skb)->gso_size = fr_max_payload(fp);
- } else {
- skb_shinfo(skb)->gso_type = 0;
- skb_shinfo(skb)->gso_size = 0;
- }
-#endif
- /* update tx stats: regardless if LLD fails */
- stats = lp->dev_stats[smp_processor_id()];
- if (stats) {
- stats->TxFrames++;
- stats->TxWords += wlen;
- }
-
- /* send down to lld */
- fr_dev(fp) = lp;
- if (fc->fcoe_pending_queue.qlen)
- rc = fcoe_check_wait_queue(lp);
-
- if (rc == 0)
- rc = fcoe_start_io(skb);
-
- if (rc) {
- spin_lock_bh(&fc->fcoe_pending_queue.lock);
- __skb_queue_tail(&fc->fcoe_pending_queue, skb);
- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
- if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
- lp->qfull = 1;
- }
-
- return 0;
+ fip->send(fip, skb);
}
-EXPORT_SYMBOL_GPL(fcoe_xmit);
/**
- * fcoe_percpu_receive_thread() - recv thread per cpu
- * @arg: ptr to the fcoe per cpu struct
+ * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it.
+ * @fip: FCoE controller.
+ * @dtype: FIP descriptor type for the frame.
+ * @skb: FCoE ELS frame including FC header but no FCoE headers.
+ *
+ * Returns non-zero error code on failure.
+ *
+ * The caller must check that the length is a multiple of 4.
*
- * Return: 0 for success
+ * The @skb must have enough headroom (28 bytes) and tailroom (8 bytes).
+ * Headroom includes the FIP encapsulation description, FIP header, and
+ * Ethernet header. The tailroom is for the FIP MAC descriptor.
*/
-int fcoe_percpu_receive_thread(void *arg)
+static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
+ u8 dtype, struct sk_buff *skb)
{
- struct fcoe_percpu_s *p = arg;
- u32 fr_len;
- struct fc_lport *lp;
- struct fcoe_rcv_info *fr;
- struct fcoe_dev_stats *stats;
- struct fc_frame_header *fh;
- struct sk_buff *skb;
- struct fcoe_crc_eof crc_eof;
- struct fc_frame *fp;
- u8 *mac = NULL;
- struct fcoe_softc *fc;
- struct fcoe_hdr *hp;
-
- set_user_nice(current, -20);
-
- while (!kthread_should_stop()) {
-
- spin_lock_bh(&p->fcoe_rx_list.lock);
- while ((skb = __skb_dequeue(&p->fcoe_rx_list)) == NULL) {
- set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_bh(&p->fcoe_rx_list.lock);
- schedule();
- set_current_state(TASK_RUNNING);
- if (kthread_should_stop())
- return 0;
- spin_lock_bh(&p->fcoe_rx_list.lock);
- }
- spin_unlock_bh(&p->fcoe_rx_list.lock);
- fr = fcoe_dev_from_skb(skb);
- lp = fr->fr_dev;
- if (unlikely(lp == NULL)) {
- FC_DBG("invalid HBA Structure");
- kfree_skb(skb);
- continue;
- }
-
- stats = lp->dev_stats[smp_processor_id()];
-
- if (unlikely(debug_fcoe)) {
- FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p "
- "tail:%p end:%p sum:%d dev:%s",
- skb->len, skb->data_len,
- skb->head, skb->data, skb_tail_pointer(skb),
- skb_end_pointer(skb), skb->csum,
- skb->dev ? skb->dev->name : "<NULL>");
- }
-
- /*
- * Save source MAC address before discarding header.
- */
- fc = lport_priv(lp);
- if (unlikely(fc->flogi_progress))
- mac = eth_hdr(skb)->h_source;
-
- if (skb_is_nonlinear(skb))
- skb_linearize(skb); /* not ideal */
-
- /*
- * Frame length checks and setting up the header pointers
- * was done in fcoe_rcv already.
- */
- hp = (struct fcoe_hdr *) skb_network_header(skb);
- fh = (struct fc_frame_header *) skb_transport_header(skb);
-
- if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
- if (stats) {
- if (stats->ErrorFrames < 5)
- FC_DBG("unknown FCoE version %x",
- FC_FCOE_DECAPS_VER(hp));
- stats->ErrorFrames++;
- }
- kfree_skb(skb);
- continue;
- }
-
- skb_pull(skb, sizeof(struct fcoe_hdr));
- fr_len = skb->len - sizeof(struct fcoe_crc_eof);
-
- if (stats) {
- stats->RxFrames++;
- stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
- }
-
- fp = (struct fc_frame *)skb;
- fc_frame_init(fp);
- fr_dev(fp) = lp;
- fr_sof(fp) = hp->fcoe_sof;
-
- /* Copy out the CRC and EOF trailer for access */
- if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
- kfree_skb(skb);
- continue;
- }
- fr_eof(fp) = crc_eof.fcoe_eof;
- fr_crc(fp) = crc_eof.fcoe_crc32;
- if (pskb_trim(skb, fr_len)) {
- kfree_skb(skb);
- continue;
- }
-
- /*
- * We only check CRC if no offload is available and if it is
- * it's solicited data, in which case, the FCP layer would
- * check it during the copy.
- */
- if (lp->crc_offload && skb->ip_summed == CHECKSUM_UNNECESSARY)
- fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
- else
- fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
-
- fh = fc_frame_header_get(fp);
- if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
- fh->fh_type == FC_TYPE_FCP) {
- fc_exch_recv(lp, lp->emp, fp);
- continue;
- }
- if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
- if (le32_to_cpu(fr_crc(fp)) !=
- ~crc32(~0, skb->data, fr_len)) {
- if (debug_fcoe || stats->InvalidCRCCount < 5)
- printk(KERN_WARNING "fcoe: dropping "
- "frame with CRC error\n");
- stats->InvalidCRCCount++;
- stats->ErrorFrames++;
- fc_frame_free(fp);
- continue;
- }
- fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
- }
- /* non flogi and non data exchanges are handled here */
- if (unlikely(fc->flogi_progress))
- fcoe_recv_flogi(fc, fp, mac);
- fc_exch_recv(lp, lp->emp, fp);
- }
+ struct fip_encaps_head {
+ struct ethhdr eth;
+ struct fip_header fip;
+ struct fip_encaps encaps;
+ } __attribute__((packed)) *cap;
+ struct fip_mac_desc *mac;
+ struct fcoe_fcf *fcf;
+ size_t dlen;
+
+ fcf = fip->sel_fcf;
+ if (!fcf)
+ return -ENODEV;
+ dlen = sizeof(struct fip_encaps) + skb->len; /* len before push */
+ cap = (struct fip_encaps_head *)skb_push(skb, sizeof(*cap));
+
+ memset(cap, 0, sizeof(*cap));
+ memcpy(cap->eth.h_dest, fcf->fcf_mac, ETH_ALEN);
+ memcpy(cap->eth.h_source, fip->ctl_src_addr, ETH_ALEN);
+ cap->eth.h_proto = htons(ETH_P_FIP);
+
+ cap->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
+ cap->fip.fip_op = htons(FIP_OP_LS);
+ cap->fip.fip_subcode = FIP_SC_REQ;
+ cap->fip.fip_dl_len = htons((dlen + sizeof(*mac)) / FIP_BPW);
+ cap->fip.fip_flags = htons(FIP_FL_FPMA);
+
+ cap->encaps.fd_desc.fip_dtype = dtype;
+ cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW;
+
+ mac = (struct fip_mac_desc *)skb_put(skb, sizeof(*mac));
+ memset(mac, 0, sizeof(mac));
+ mac->fd_desc.fip_dtype = FIP_DT_MAC;
+ mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
+ if (dtype != ELS_FLOGI)
+ memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN);
+
+ skb->protocol = htons(ETH_P_802_3);
+ skb_reset_mac_header(skb);
+ skb_reset_network_header(skb);
return 0;
}
/**
- * fcoe_recv_flogi() - flogi receive function
- * @fc: associated fcoe_softc
- * @fp: the recieved frame
- * @sa: the source address of this flogi
+ * fcoe_ctlr_els_send() - Send an ELS frame encapsulated by FIP if appropriate.
+ * @fip: FCoE controller.
+ * @skb: FCoE ELS frame including FC header but no FCoE headers.
*
- * This is responsible to parse the flogi response and sets the corresponding
- * mac address for the initiator, eitehr OUI based or GW based.
+ * Returns a non-zero error code if the frame should not be sent.
+ * Returns zero if the caller should send the frame with FCoE encapsulation.
*
- * Returns: none
+ * The caller must check that the length is a multiple of 4.
+ * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
*/
-static void fcoe_recv_flogi(struct fcoe_softc *fc, struct fc_frame *fp, u8 *sa)
+int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
struct fc_frame_header *fh;
+ u16 old_xid;
u8 op;
- fh = fc_frame_header_get(fp);
- if (fh->fh_type != FC_TYPE_ELS)
- return;
- op = fc_frame_payload_op(fp);
- if (op == ELS_LS_ACC && fh->fh_r_ctl == FC_RCTL_ELS_REP &&
- fc->flogi_oxid == ntohs(fh->fh_ox_id)) {
- /*
- * FLOGI accepted.
- * If the src mac addr is FC_OUI-based, then we mark the
- * address_mode flag to use FC_OUI-based Ethernet DA.
- * Otherwise we use the FCoE gateway addr
- */
- if (!compare_ether_addr(sa, (u8[6]) FC_FCOE_FLOGI_MAC)) {
- fc->address_mode = FCOE_FCOUI_ADDR_MODE;
- } else {
- memcpy(fc->dest_addr, sa, ETH_ALEN);
- fc->address_mode = FCOE_GW_ADDR_MODE;
- }
+ if (fip->state == FIP_ST_NON_FIP)
+ return 0;
+ fh = (struct fc_frame_header *)skb->data;
+ op = *(u8 *)(fh + 1);
+
+ switch (op) {
+ case ELS_FLOGI:
+ old_xid = fip->flogi_oxid;
+ fip->flogi_oxid = ntohs(fh->fh_ox_id);
+ if (fip->state == FIP_ST_AUTO) {
+ if (old_xid == FC_XID_UNKNOWN)
+ fip->flogi_count = 0;
+ fip->flogi_count++;
+ if (fip->flogi_count < 3)
+ goto drop;
+ fip->map_dest = 1;
+ return 0;
+ }
+ op = FIP_DT_FLOGI;
+ break;
+ case ELS_FDISC:
+ if (ntoh24(fh->fh_s_id))
+ return 0;
+ op = FIP_DT_FDISC;
+ break;
+ case ELS_LOGO:
+ if (fip->state != FIP_ST_ENABLED)
+ return 0;
+ if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI)
+ return 0;
+ op = FIP_DT_LOGO;
+ break;
+ case ELS_LS_ACC:
+ if (fip->flogi_oxid == FC_XID_UNKNOWN)
+ return 0;
+ if (!ntoh24(fh->fh_s_id))
+ return 0;
+ if (fip->state == FIP_ST_AUTO)
+ return 0;
/*
- * Remove any previously-set unicast MAC filter.
- * Add secondary FCoE MAC address filter for our OUI.
- */
- rtnl_lock();
- if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 }))
- dev_unicast_delete(fc->real_dev, fc->data_src_addr,
- ETH_ALEN);
- fc_fcoe_set_mac(fc->data_src_addr, fh->fh_d_id);
- dev_unicast_add(fc->real_dev, fc->data_src_addr, ETH_ALEN);
- rtnl_unlock();
-
- fc->flogi_progress = 0;
- } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
- /*
- * Save source MAC for point-to-point responses.
+ * Here we must've gotten an SID by accepting an FLOGI
+ * from a point-to-point connection. Switch to using
+ * the source mac based on the SID. The destination
+ * MAC in this case would have been set by receving the
+ * FLOGI.
*/
- memcpy(fc->dest_addr, sa, ETH_ALEN);
- fc->address_mode = FCOE_GW_ADDR_MODE;
+ fip->flogi_oxid = FC_XID_UNKNOWN;
+ fc_fcoe_set_mac(fip->data_src_addr, fh->fh_s_id);
+ return 0;
+ default:
+ if (fip->state != FIP_ST_ENABLED)
+ goto drop;
+ return 0;
}
+ if (fcoe_ctlr_encaps(fip, op, skb))
+ goto drop;
+ fip->send(fip, skb);
+ return -EINPROGRESS;
+drop:
+ kfree_skb(skb);
+ return -EINVAL;
}
+EXPORT_SYMBOL(fcoe_ctlr_els_send);
-/**
- * fcoe_watchdog() - fcoe timer callback
- * @vp:
+/*
+ * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller.
+ * @fip: FCoE controller.
*
- * This checks the pending queue length for fcoe and set lport qfull
- * if the FCOE_MAX_QUEUE_DEPTH is reached. This is done for all fc_lport on the
- * fcoe_hostlist.
+ * Called with lock held.
*
- * Returns: 0 for success
+ * An FCF is considered old if we have missed three advertisements.
+ * That is, there have been no valid advertisement from it for three
+ * times its keep-alive period including fuzz.
+ *
+ * In addition, determine the time when an FCF selection can occur.
*/
-void fcoe_watchdog(ulong vp)
+static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
{
- struct fcoe_softc *fc;
-
- read_lock(&fcoe_hostlist_lock);
- list_for_each_entry(fc, &fcoe_hostlist, list) {
- if (fc->lp)
- fcoe_check_wait_queue(fc->lp);
+ struct fcoe_fcf *fcf;
+ struct fcoe_fcf *next;
+ unsigned long sel_time = 0;
+
+ list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
+ if (time_after(jiffies, fcf->time + fcf->fka_period * 3 +
+ msecs_to_jiffies(FIP_FCF_FUZZ * 3))) {
+ if (fip->sel_fcf == fcf)
+ fip->sel_fcf = NULL;
+ list_del(&fcf->list);
+ WARN_ON(!fip->fcf_count);
+ fip->fcf_count--;
+ kfree(fcf);
+ } else if (fcoe_ctlr_mtu_valid(fcf) &&
+ (!sel_time || time_before(sel_time, fcf->time))) {
+ sel_time = fcf->time;
+ }
+ }
+ if (sel_time) {
+ sel_time += msecs_to_jiffies(FCOE_CTLR_START_DELAY);
+ fip->sel_time = sel_time;
+ if (time_before(sel_time, fip->timer.expires))
+ mod_timer(&fip->timer, sel_time);
+ } else {
+ fip->sel_time = 0;
}
- read_unlock(&fcoe_hostlist_lock);
-
- fcoe_timer.expires = jiffies + (1 * HZ);
- add_timer(&fcoe_timer);
}
-
/**
- * fcoe_check_wait_queue() - put the skb into fcoe pending xmit queue
- * @lp: the fc_port for this skb
- * @skb: the associated skb to be xmitted
+ * fcoe_ctlr_parse_adv() - Decode a FIP advertisement into a new FCF entry.
+ * @skb: received FIP advertisement frame
+ * @fcf: resulting FCF entry.
*
- * This empties the wait_queue, dequeue the head of the wait_queue queue
- * and calls fcoe_start_io() for each packet, if all skb have been
- * transmitted, return qlen or -1 if a error occurs, then restore
- * wait_queue and try again later.
- *
- * The wait_queue is used when the skb transmit fails. skb will go
- * in the wait_queue which will be emptied by the time function OR
- * by the next skb transmit.
- *
- * Returns: 0 for success
+ * Returns zero on a valid parsed advertisement,
+ * otherwise returns non zero value.
*/
-static int fcoe_check_wait_queue(struct fc_lport *lp)
+static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf)
{
- struct fcoe_softc *fc = lport_priv(lp);
- struct sk_buff *skb;
- int rc = -1;
-
- spin_lock_bh(&fc->fcoe_pending_queue.lock);
- if (fc->fcoe_pending_queue_active)
- goto out;
- fc->fcoe_pending_queue_active = 1;
-
- while (fc->fcoe_pending_queue.qlen) {
- /* keep qlen > 0 until fcoe_start_io succeeds */
- fc->fcoe_pending_queue.qlen++;
- skb = __skb_dequeue(&fc->fcoe_pending_queue);
-
- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
- rc = fcoe_start_io(skb);
- spin_lock_bh(&fc->fcoe_pending_queue.lock);
-
- if (rc) {
- __skb_queue_head(&fc->fcoe_pending_queue, skb);
- /* undo temporary increment above */
- fc->fcoe_pending_queue.qlen--;
+ struct fip_header *fiph;
+ struct fip_desc *desc = NULL;
+ struct fip_wwn_desc *wwn;
+ struct fip_fab_desc *fab;
+ struct fip_fka_desc *fka;
+ unsigned long t;
+ size_t rlen;
+ size_t dlen;
+
+ memset(fcf, 0, sizeof(*fcf));
+ fcf->fka_period = msecs_to_jiffies(FCOE_CTLR_DEF_FKA);
+
+ fiph = (struct fip_header *)skb->data;
+ fcf->flags = ntohs(fiph->fip_flags);
+
+ rlen = ntohs(fiph->fip_dl_len) * 4;
+ if (rlen + sizeof(*fiph) > skb->len)
+ return -EINVAL;
+
+ desc = (struct fip_desc *)(fiph + 1);
+ while (rlen > 0) {
+ dlen = desc->fip_dlen * FIP_BPW;
+ if (dlen < sizeof(*desc) || dlen > rlen)
+ return -EINVAL;
+ switch (desc->fip_dtype) {
+ case FIP_DT_PRI:
+ if (dlen != sizeof(struct fip_pri_desc))
+ goto len_err;
+ fcf->pri = ((struct fip_pri_desc *)desc)->fd_pri;
break;
+ case FIP_DT_MAC:
+ if (dlen != sizeof(struct fip_mac_desc))
+ goto len_err;
+ memcpy(fcf->fcf_mac,
+ ((struct fip_mac_desc *)desc)->fd_mac,
+ ETH_ALEN);
+ if (!is_valid_ether_addr(fcf->fcf_mac)) {
+ FIP_DBG("invalid MAC addr in FIP adv\n");
+ return -EINVAL;
+ }
+ break;
+ case FIP_DT_NAME:
+ if (dlen != sizeof(struct fip_wwn_desc))
+ goto len_err;
+ wwn = (struct fip_wwn_desc *)desc;
+ fcf->switch_name = get_unaligned_be64(&wwn->fd_wwn);
+ break;
+ case FIP_DT_FAB:
+ if (dlen != sizeof(struct fip_fab_desc))
+ goto len_err;
+ fab = (struct fip_fab_desc *)desc;
+ fcf->fabric_name = get_unaligned_be64(&fab->fd_wwn);
+ fcf->vfid = ntohs(fab->fd_vfid);
+ fcf->fc_map = ntoh24(fab->fd_map);
+ break;
+ case FIP_DT_FKA:
+ if (dlen != sizeof(struct fip_fka_desc))
+ goto len_err;
+ fka = (struct fip_fka_desc *)desc;
+ t = ntohl(fka->fd_fka_period);
+ if (t >= FCOE_CTLR_MIN_FKA)
+ fcf->fka_period = msecs_to_jiffies(t);
+ break;
+ case FIP_DT_MAP_OUI:
+ case FIP_DT_FCOE_SIZE:
+ case FIP_DT_FLOGI:
+ case FIP_DT_FDISC:
+ case FIP_DT_LOGO:
+ case FIP_DT_ELP:
+ default:
+ FIP_DBG("unexpected descriptor type %x in FIP adv\n",
+ desc->fip_dtype);
+ /* standard says ignore unknown descriptors >= 128 */
+ if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
+ return -EINVAL;
+ continue;
}
- /* undo temporary increment above */
- fc->fcoe_pending_queue.qlen--;
+ desc = (struct fip_desc *)((char *)desc + dlen);
+ rlen -= dlen;
}
+ if (!fcf->fc_map || (fcf->fc_map & 0x10000))
+ return -EINVAL;
+ if (!fcf->switch_name || !fcf->fabric_name)
+ return -EINVAL;
+ return 0;
- if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH)
- lp->qfull = 0;
- fc->fcoe_pending_queue_active = 0;
- rc = fc->fcoe_pending_queue.qlen;
-out:
- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
- return rc;
+len_err:
+ FIP_DBG("FIP length error in descriptor type %x len %zu\n",
+ desc->fip_dtype, dlen);
+ return -EINVAL;
}
/**
- * fcoe_dev_setup() - setup link change notification interface
+ * fcoe_ctlr_recv_adv() - Handle an incoming advertisement.
+ * @fip: FCoE controller.
+ * @skb: Received FIP packet.
*/
-static void fcoe_dev_setup()
+static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
+ struct fcoe_fcf *fcf;
+ struct fcoe_fcf new;
+ struct fcoe_fcf *found;
+ unsigned long sol_tov = msecs_to_jiffies(FCOE_CTRL_SOL_TOV);
+ int first = 0;
+ int mtu_valid;
+
+ if (fcoe_ctlr_parse_adv(skb, &new))
+ return;
+
+ spin_lock_bh(&fip->lock);
+ first = list_empty(&fip->fcfs);
+ found = NULL;
+ list_for_each_entry(fcf, &fip->fcfs, list) {
+ if (fcf->switch_name == new.switch_name &&
+ fcf->fabric_name == new.fabric_name &&
+ fcf->fc_map == new.fc_map &&
+ compare_ether_addr(fcf->fcf_mac, new.fcf_mac) == 0) {
+ found = fcf;
+ break;
+ }
+ }
+ if (!found) {
+ if (fip->fcf_count >= FCOE_CTLR_FCF_LIMIT)
+ goto out;
+
+ fcf = kmalloc(sizeof(*fcf), GFP_ATOMIC);
+ if (!fcf)
+ goto out;
+
+ fip->fcf_count++;
+ memcpy(fcf, &new, sizeof(new));
+ list_add(&fcf->list, &fip->fcfs);
+ } else {
+ /*
+ * Flags in advertisements are ignored once the FCF is
+ * selected. Flags in unsolicited advertisements are
+ * ignored after a usable solicited advertisement
+ * has been received.
+ */
+ if (fcf == fip->sel_fcf) {
+ fip->ctlr_ka_time -= fcf->fka_period;
+ fip->ctlr_ka_time += new.fka_period;
+ if (time_before(fip->ctlr_ka_time, fip->timer.expires))
+ mod_timer(&fip->timer, fip->ctlr_ka_time);
+ } else if (!fcoe_ctlr_fcf_usable(fcf))
+ fcf->flags = new.flags;
+ fcf->fka_period = new.fka_period;
+ memcpy(fcf->fcf_mac, new.fcf_mac, ETH_ALEN);
+ }
+ mtu_valid = fcoe_ctlr_mtu_valid(fcf);
+ fcf->time = jiffies;
+ FIP_DBG_LVL(found ? 2 : 1, "%s FCF for fab %llx map %x val %d\n",
+ found ? "old" : "new",
+ fcf->fabric_name, fcf->fc_map, mtu_valid);
+
/*
- * here setup a interface specific wd time to
- * monitor the link state
+ * If this advertisement is not solicited and our max receive size
+ * hasn't been verified, send a solicited advertisement.
*/
- register_netdevice_notifier(&fcoe_notifier);
-}
+ if (!mtu_valid)
+ fcoe_ctlr_solicit(fip, fcf);
-/**
- * fcoe_dev_setup() - cleanup link change notification interface
- */
-static void fcoe_dev_cleanup(void)
-{
- unregister_netdevice_notifier(&fcoe_notifier);
+ /*
+ * If its been a while since we did a solicit, and this is
+ * the first advertisement we've received, do a multicast
+ * solicitation to gather as many advertisements as we can
+ * before selection occurs.
+ */
+ if (first && time_after(jiffies, fip->sol_time + sol_tov))
+ fcoe_ctlr_solicit(fip, NULL);
+
+ /*
+ * If this is the first validated FCF, note the time and
+ * set a timer to trigger selection.
+ */
+ if (mtu_valid && !fip->sel_time && fcoe_ctlr_fcf_usable(fcf)) {
+ fip->sel_time = jiffies +
+ msecs_to_jiffies(FCOE_CTLR_START_DELAY);
+ if (!timer_pending(&fip->timer) ||
+ time_before(fip->sel_time, fip->timer.expires))
+ mod_timer(&fip->timer, fip->sel_time);
+ }
+out:
+ spin_unlock_bh(&fip->lock);
}
/**
- * fcoe_device_notification() - netdev event notification callback
- * @notifier: context of the notification
- * @event: type of event
- * @ptr: fixed array for output parsed ifname
- *
- * This function is called by the ethernet driver in case of link change event
- *
- * Returns: 0 for success
+ * fcoe_ctlr_recv_els() - Handle an incoming FIP-encapsulated ELS frame.
+ * @fip: FCoE controller.
+ * @skb: Received FIP packet.
*/
-static int fcoe_device_notification(struct notifier_block *notifier,
- ulong event, void *ptr)
+static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
- struct fc_lport *lp = NULL;
- struct net_device *real_dev = ptr;
- struct fcoe_softc *fc;
+ struct fc_lport *lp = fip->lp;
+ struct fip_header *fiph;
+ struct fc_frame *fp;
+ struct fc_frame_header *fh = NULL;
+ struct fip_desc *desc;
+ struct fip_encaps *els;
struct fcoe_dev_stats *stats;
- u32 new_link_up;
- u32 mfs;
- int rc = NOTIFY_OK;
-
- read_lock(&fcoe_hostlist_lock);
- list_for_each_entry(fc, &fcoe_hostlist, list) {
- if (fc->real_dev == real_dev) {
- lp = fc->lp;
+ enum fip_desc_type els_dtype = 0;
+ u8 els_op;
+ u8 sub;
+ u8 granted_mac[ETH_ALEN] = { 0 };
+ size_t els_len = 0;
+ size_t rlen;
+ size_t dlen;
+
+ fiph = (struct fip_header *)skb->data;
+ sub = fiph->fip_subcode;
+ if (sub != FIP_SC_REQ && sub != FIP_SC_REP)
+ goto drop;
+
+ rlen = ntohs(fiph->fip_dl_len) * 4;
+ if (rlen + sizeof(*fiph) > skb->len)
+ goto drop;
+
+ desc = (struct fip_desc *)(fiph + 1);
+ while (rlen > 0) {
+ dlen = desc->fip_dlen * FIP_BPW;
+ if (dlen < sizeof(*desc) || dlen > rlen)
+ goto drop;
+ switch (desc->fip_dtype) {
+ case FIP_DT_MAC:
+ if (dlen != sizeof(struct fip_mac_desc))
+ goto len_err;
+ memcpy(granted_mac,
+ ((struct fip_mac_desc *)desc)->fd_mac,
+ ETH_ALEN);
+ if (!is_valid_ether_addr(granted_mac)) {
+ FIP_DBG("invalid MAC addrs in FIP ELS\n");
+ goto drop;
+ }
break;
+ case FIP_DT_FLOGI:
+ case FIP_DT_FDISC:
+ case FIP_DT_LOGO:
+ case FIP_DT_ELP:
+ if (fh)
+ goto drop;
+ if (dlen < sizeof(*els) + sizeof(*fh) + 1)
+ goto len_err;
+ els_len = dlen - sizeof(*els);
+ els = (struct fip_encaps *)desc;
+ fh = (struct fc_frame_header *)(els + 1);
+ els_dtype = desc->fip_dtype;
+ break;
+ default:
+ FIP_DBG("unexpected descriptor type %x "
+ "in FIP adv\n", desc->fip_dtype);
+ /* standard says ignore unknown descriptors >= 128 */
+ if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
+ goto drop;
+ continue;
}
- }
- read_unlock(&fcoe_hostlist_lock);
- if (lp == NULL) {
- rc = NOTIFY_DONE;
- goto out;
+ desc = (struct fip_desc *)((char *)desc + dlen);
+ rlen -= dlen;
}
- new_link_up = lp->link_up;
- switch (event) {
- case NETDEV_DOWN:
- case NETDEV_GOING_DOWN:
- new_link_up = 0;
- break;
- case NETDEV_UP:
- case NETDEV_CHANGE:
- new_link_up = !fcoe_link_ok(lp);
- break;
- case NETDEV_CHANGEMTU:
- mfs = fc->real_dev->mtu -
- (sizeof(struct fcoe_hdr) +
- sizeof(struct fcoe_crc_eof));
- if (mfs >= FC_MIN_MAX_FRAME)
- fc_set_mfs(lp, mfs);
- new_link_up = !fcoe_link_ok(lp);
- break;
- case NETDEV_REGISTER:
- break;
- default:
- FC_DBG("unknown event %ld call", event);
- }
- if (lp->link_up != new_link_up) {
- if (new_link_up)
- fc_linkup(lp);
- else {
- stats = lp->dev_stats[smp_processor_id()];
- if (stats)
- stats->LinkFailureCount++;
- fc_linkdown(lp);
- fcoe_clean_pending_queue(lp);
- }
- }
-out:
- return rc;
-}
+ if (!fh)
+ goto drop;
+ els_op = *(u8 *)(fh + 1);
-/**
- * fcoe_if_to_netdev() - parse a name buffer to get netdev
- * @ifname: fixed array for output parsed ifname
- * @buffer: incoming buffer to be copied
- *
- * Returns: NULL or ptr to netdeive
- */
-static struct net_device *fcoe_if_to_netdev(const char *buffer)
-{
- char *cp;
- char ifname[IFNAMSIZ + 2];
-
- if (buffer) {
- strlcpy(ifname, buffer, IFNAMSIZ);
- cp = ifname + strlen(ifname);
- while (--cp >= ifname && *cp == '\n')
- *cp = '\0';
- return dev_get_by_name(&init_net, ifname);
+ if (els_dtype == FIP_DT_FLOGI && sub == FIP_SC_REP &&
+ fip->flogi_oxid == ntohs(fh->fh_ox_id) &&
+ els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) {
+ fip->flogi_oxid = FC_XID_UNKNOWN;
+ fip->update_mac(fip, fip->data_src_addr, granted_mac);
+ memcpy(fip->data_src_addr, granted_mac, ETH_ALEN);
}
- return NULL;
+
+ /*
+ * Convert skb into an fc_frame containing only the ELS.
+ */
+ skb_pull(skb, (u8 *)fh - skb->data);
+ skb_trim(skb, els_len);
+ fp = (struct fc_frame *)skb;
+ fc_frame_init(fp);
+ fr_sof(fp) = FC_SOF_I3;
+ fr_eof(fp) = FC_EOF_T;
+ fr_dev(fp) = lp;
+
+ stats = fc_lport_get_stats(lp);
+ stats->RxFrames++;
+ stats->RxWords += skb->len / FIP_BPW;
+
+ fc_exch_recv(lp, lp->emp, fp);
+ return;
+
+len_err:
+ FIP_DBG("FIP length error in descriptor type %x len %zu\n",
+ desc->fip_dtype, dlen);
+drop:
+ kfree_skb(skb);
}
/**
- * fcoe_netdev_to_module_owner() - finds out the nic drive moddule of the netdev
- * @netdev: the target netdev
+ * fcoe_ctlr_recv_els() - Handle an incoming link reset frame.
+ * @fip: FCoE controller.
+ * @fh: Received FIP header.
*
- * Returns: ptr to the struct module, NULL for failure
+ * There may be multiple VN_Port descriptors.
+ * The overall length has already been checked.
*/
-static struct module *
-fcoe_netdev_to_module_owner(const struct net_device *netdev)
+static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
+ struct fip_header *fh)
{
- struct device *dev;
-
- if (!netdev)
- return NULL;
-
- dev = netdev->dev.parent;
- if (!dev)
- return NULL;
+ struct fip_desc *desc;
+ struct fip_mac_desc *mp;
+ struct fip_wwn_desc *wp;
+ struct fip_vn_desc *vp;
+ size_t rlen;
+ size_t dlen;
+ struct fcoe_fcf *fcf = fip->sel_fcf;
+ struct fc_lport *lp = fip->lp;
+ u32 desc_mask;
+
+ FIP_DBG("Clear Virtual Link received\n");
+ if (!fcf)
+ return;
+ if (!fcf || !fc_host_port_id(lp->host))
+ return;
- if (!dev->driver)
- return NULL;
+ /*
+ * mask of required descriptors. Validating each one clears its bit.
+ */
+ desc_mask = BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME) | BIT(FIP_DT_VN_ID);
+
+ rlen = ntohs(fh->fip_dl_len) * FIP_BPW;
+ desc = (struct fip_desc *)(fh + 1);
+ while (rlen >= sizeof(*desc)) {
+ dlen = desc->fip_dlen * FIP_BPW;
+ if (dlen > rlen)
+ return;
+ switch (desc->fip_dtype) {
+ case FIP_DT_MAC:
+ mp = (struct fip_mac_desc *)desc;
+ if (dlen < sizeof(*mp))
+ return;
+ if (compare_ether_addr(mp->fd_mac, fcf->fcf_mac))
+ return;
+ desc_mask &= ~BIT(FIP_DT_MAC);
+ break;
+ case FIP_DT_NAME:
+ wp = (struct fip_wwn_desc *)desc;
+ if (dlen < sizeof(*wp))
+ return;
+ if (get_unaligned_be64(&wp->fd_wwn) != fcf->switch_name)
+ return;
+ desc_mask &= ~BIT(FIP_DT_NAME);
+ break;
+ case FIP_DT_VN_ID:
+ vp = (struct fip_vn_desc *)desc;
+ if (dlen < sizeof(*vp))
+ return;
+ if (compare_ether_addr(vp->fd_mac,
+ fip->data_src_addr) == 0 &&
+ get_unaligned_be64(&vp->fd_wwpn) == lp->wwpn &&
+ ntoh24(vp->fd_fc_id) == fc_host_port_id(lp->host))
+ desc_mask &= ~BIT(FIP_DT_VN_ID);
+ break;
+ default:
+ /* standard says ignore unknown descriptors >= 128 */
+ if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
+ return;
+ break;
+ }
+ desc = (struct fip_desc *)((char *)desc + dlen);
+ rlen -= dlen;
+ }
- return dev->driver->owner;
+ /*
+ * reset only if all required descriptors were present and valid.
+ */
+ if (desc_mask) {
+ FIP_DBG("missing descriptors mask %x\n", desc_mask);
+ } else {
+ FIP_DBG("performing Clear Virtual Link\n");
+ fcoe_ctlr_reset(fip, FIP_ST_ENABLED);
+ }
}
/**
- * fcoe_ethdrv_get() - Hold the Ethernet driver
- * @netdev: the target netdev
+ * fcoe_ctlr_recv() - Receive a FIP frame.
+ * @fip: FCoE controller.
+ * @skb: Received FIP packet.
*
- * Holds the Ethernet driver module by try_module_get() for
- * the corresponding netdev.
- *
- * Returns: 0 for succsss
+ * This is called from NET_RX_SOFTIRQ.
*/
-static int fcoe_ethdrv_get(const struct net_device *netdev)
+void fcoe_ctlr_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
- struct module *owner;
-
- owner = fcoe_netdev_to_module_owner(netdev);
- if (owner) {
- printk(KERN_DEBUG "fcoe:hold driver module %s for %s\n",
- module_name(owner), netdev->name);
- return try_module_get(owner);
- }
- return -ENODEV;
+ spin_lock_bh(&fip->fip_recv_list.lock);
+ __skb_queue_tail(&fip->fip_recv_list, skb);
+ spin_unlock_bh(&fip->fip_recv_list.lock);
+ schedule_work(&fip->recv_work);
}
+EXPORT_SYMBOL(fcoe_ctlr_recv);
/**
- * fcoe_ethdrv_put() - Release the Ethernet driver
- * @netdev: the target netdev
+ * fcoe_ctlr_recv_handler() - Receive a FIP frame.
+ * @fip: FCoE controller.
+ * @skb: Received FIP packet.
*
- * Releases the Ethernet driver module by module_put for
- * the corresponding netdev.
- *
- * Returns: 0 for succsss
+ * Returns non-zero if the frame is dropped.
*/
-static int fcoe_ethdrv_put(const struct net_device *netdev)
+static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
- struct module *owner;
+ struct fip_header *fiph;
+ struct ethhdr *eh;
+ enum fip_state state;
+ u16 op;
+ u8 sub;
+
+ if (skb_linearize(skb))
+ goto drop;
+ if (skb->len < sizeof(*fiph))
+ goto drop;
+ eh = eth_hdr(skb);
+ if (compare_ether_addr(eh->h_dest, fip->ctl_src_addr) &&
+ compare_ether_addr(eh->h_dest, FIP_ALL_ENODE_MACS))
+ goto drop;
+ fiph = (struct fip_header *)skb->data;
+ op = ntohs(fiph->fip_op);
+ sub = fiph->fip_subcode;
+
+ FIP_DBG_LVL(2, "ver %x op %x/%x dl %x fl %x\n",
+ FIP_VER_DECAPS(fiph->fip_ver), op, sub,
+ ntohs(fiph->fip_dl_len), ntohs(fiph->fip_flags));
+
+ if (FIP_VER_DECAPS(fiph->fip_ver) != FIP_VER)
+ goto drop;
+ if (ntohs(fiph->fip_dl_len) * FIP_BPW + sizeof(*fiph) > skb->len)
+ goto drop;
+
+ spin_lock_bh(&fip->lock);
+ state = fip->state;
+ if (state == FIP_ST_AUTO) {
+ fip->map_dest = 0;
+ fip->state = FIP_ST_ENABLED;
+ state = FIP_ST_ENABLED;
+ FIP_DBG("using FIP mode\n");
+ }
+ spin_unlock_bh(&fip->lock);
+ if (state != FIP_ST_ENABLED)
+ goto drop;
- owner = fcoe_netdev_to_module_owner(netdev);
- if (owner) {
- printk(KERN_DEBUG "fcoe:release driver module %s for %s\n",
- module_name(owner), netdev->name);
- module_put(owner);
+ if (op == FIP_OP_LS) {
+ fcoe_ctlr_recv_els(fip, skb); /* consumes skb */
return 0;
}
- return -ENODEV;
+ if (op == FIP_OP_DISC && sub == FIP_SC_ADV)
+ fcoe_ctlr_recv_adv(fip, skb);
+ else if (op == FIP_OP_CTRL && sub == FIP_SC_CLR_VLINK)
+ fcoe_ctlr_recv_clr_vlink(fip, fiph);
+ kfree_skb(skb);
+ return 0;
+drop:
+ kfree_skb(skb);
+ return -1;
}
/**
- * fcoe_destroy() - handles the destroy from sysfs
- * @buffer: expcted to be a eth if name
- * @kp: associated kernel param
+ * fcoe_ctlr_select() - Select the best FCF, if possible.
+ * @fip: FCoE controller.
+ *
+ * If there are conflicting advertisements, no FCF can be chosen.
*
- * Returns: 0 for success
+ * Called with lock held.
*/
-static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
+static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
{
- int rc;
- struct net_device *netdev;
-
- netdev = fcoe_if_to_netdev(buffer);
- if (!netdev) {
- rc = -ENODEV;
- goto out_nodev;
- }
- /* look for existing lport */
- if (!fcoe_hostlist_lookup(netdev)) {
- rc = -ENODEV;
- goto out_putdev;
- }
- /* pass to transport */
- rc = fcoe_transport_release(netdev);
- if (rc) {
- printk(KERN_ERR "fcoe: fcoe_transport_release(%s) failed\n",
- netdev->name);
- rc = -EIO;
- goto out_putdev;
+ struct fcoe_fcf *fcf;
+ struct fcoe_fcf *best = NULL;
+
+ list_for_each_entry(fcf, &fip->fcfs, list) {
+ FIP_DBG("consider FCF for fab %llx VFID %d map %x val %d\n",
+ fcf->fabric_name, fcf->vfid,
+ fcf->fc_map, fcoe_ctlr_mtu_valid(fcf));
+ if (!fcoe_ctlr_fcf_usable(fcf)) {
+ FIP_DBG("FCF for fab %llx map %x %svalid %savailable\n",
+ fcf->fabric_name, fcf->fc_map,
+ (fcf->flags & FIP_FL_SOL) ? "" : "in",
+ (fcf->flags & FIP_FL_AVAIL) ? "" : "un");
+ continue;
+ }
+ if (!best) {
+ best = fcf;
+ continue;
+ }
+ if (fcf->fabric_name != best->fabric_name ||
+ fcf->vfid != best->vfid ||
+ fcf->fc_map != best->fc_map) {
+ FIP_DBG("conflicting fabric, VFID, or FC-MAP\n");
+ return;
+ }
+ if (fcf->pri < best->pri)
+ best = fcf;
}
- fcoe_ethdrv_put(netdev);
- rc = 0;
-out_putdev:
- dev_put(netdev);
-out_nodev:
- return rc;
+ fip->sel_fcf = best;
}
/**
- * fcoe_create() - Handles the create call from sysfs
- * @buffer: expcted to be a eth if name
- * @kp: associated kernel param
+ * fcoe_ctlr_timeout() - FIP timer function.
+ * @arg: &fcoe_ctlr pointer.
*
- * Returns: 0 for success
+ * Ages FCFs. Triggers FCF selection if possible. Sends keep-alives.
*/
-static int fcoe_create(const char *buffer, struct kernel_param *kp)
+static void fcoe_ctlr_timeout(unsigned long arg)
{
- int rc;
- struct net_device *netdev;
-
- netdev = fcoe_if_to_netdev(buffer);
- if (!netdev) {
- rc = -ENODEV;
- goto out_nodev;
+ struct fcoe_ctlr *fip = (struct fcoe_ctlr *)arg;
+ struct fcoe_fcf *sel;
+ struct fcoe_fcf *fcf;
+ unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
+ DECLARE_MAC_BUF(buf);
+ u8 send_ctlr_ka;
+ u8 send_port_ka;
+
+ spin_lock_bh(&fip->lock);
+ if (fip->state == FIP_ST_DISABLED) {
+ spin_unlock_bh(&fip->lock);
+ return;
}
- /* look for existing lport */
- if (fcoe_hostlist_lookup(netdev)) {
- rc = -EEXIST;
- goto out_putdev;
+
+ fcf = fip->sel_fcf;
+ fcoe_ctlr_age_fcfs(fip);
+
+ sel = fip->sel_fcf;
+ if (!sel && fip->sel_time && time_after_eq(jiffies, fip->sel_time)) {
+ fcoe_ctlr_select(fip);
+ sel = fip->sel_fcf;
+ fip->sel_time = 0;
}
- fcoe_ethdrv_get(netdev);
-
- /* pass to transport */
- rc = fcoe_transport_attach(netdev);
- if (rc) {
- printk(KERN_ERR "fcoe: fcoe_transport_attach(%s) failed\n",
- netdev->name);
- fcoe_ethdrv_put(netdev);
- rc = -EIO;
- goto out_putdev;
+
+ if (sel != fcf) {
+ fcf = sel; /* the old FCF may have been freed */
+ if (sel) {
+ printk(KERN_INFO "host%d: FIP selected "
+ "Fibre-Channel Forwarder MAC %s\n",
+ fip->lp->host->host_no,
+ print_mac(buf, sel->fcf_mac));
+ memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN);
+ fip->port_ka_time = jiffies +
+ msecs_to_jiffies(FIP_VN_KA_PERIOD);
+ fip->ctlr_ka_time = jiffies + sel->fka_period;
+ fip->link = 1;
+ } else {
+ printk(KERN_NOTICE "host%d: "
+ "FIP Fibre-Channel Forwarder timed out. "
+ "Starting FCF discovery.\n",
+ fip->lp->host->host_no);
+ fip->link = 0;
+ }
+ schedule_work(&fip->link_work);
}
- rc = 0;
-out_putdev:
- dev_put(netdev);
-out_nodev:
- return rc;
-}
-module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
-__MODULE_PARM_TYPE(create, "string");
-MODULE_PARM_DESC(create, "Create fcoe port using net device passed in.");
-module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
-__MODULE_PARM_TYPE(destroy, "string");
-MODULE_PARM_DESC(destroy, "Destroy fcoe port");
+ send_ctlr_ka = 0;
+ send_port_ka = 0;
+ if (sel) {
+ if (time_after_eq(jiffies, fip->ctlr_ka_time)) {
+ fip->ctlr_ka_time = jiffies + sel->fka_period;
+ send_ctlr_ka = 1;
+ }
+ if (time_after(next_timer, fip->ctlr_ka_time))
+ next_timer = fip->ctlr_ka_time;
-/**
- * fcoe_link_ok() - Check if link is ok for the fc_lport
- * @lp: ptr to the fc_lport
- *
- * Any permanently-disqualifying conditions have been previously checked.
- * This also updates the speed setting, which may change with link for 100/1000.
- *
- * This function should probably be checking for PAUSE support at some point
- * in the future. Currently Per-priority-pause is not determinable using
- * ethtool, so we shouldn't be restrictive until that problem is resolved.
- *
- * Returns: 0 if link is OK for use by FCoE.
- *
- */
-int fcoe_link_ok(struct fc_lport *lp)
-{
- struct fcoe_softc *fc = lport_priv(lp);
- struct net_device *dev = fc->real_dev;
- struct ethtool_cmd ecmd = { ETHTOOL_GSET };
- int rc = 0;
-
- if ((dev->flags & IFF_UP) && netif_carrier_ok(dev)) {
- dev = fc->phys_dev;
- if (dev->ethtool_ops->get_settings) {
- dev->ethtool_ops->get_settings(dev, &ecmd);
- lp->link_supported_speeds &=
- ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
- if (ecmd.supported & (SUPPORTED_1000baseT_Half |
- SUPPORTED_1000baseT_Full))
- lp->link_supported_speeds |= FC_PORTSPEED_1GBIT;
- if (ecmd.supported & SUPPORTED_10000baseT_Full)
- lp->link_supported_speeds |=
- FC_PORTSPEED_10GBIT;
- if (ecmd.speed == SPEED_1000)
- lp->link_speed = FC_PORTSPEED_1GBIT;
- if (ecmd.speed == SPEED_10000)
- lp->link_speed = FC_PORTSPEED_10GBIT;
+ if (time_after_eq(jiffies, fip->port_ka_time)) {
+ fip->port_ka_time += jiffies +
+ msecs_to_jiffies(FIP_VN_KA_PERIOD);
+ send_port_ka = 1;
}
- } else
- rc = -1;
+ if (time_after(next_timer, fip->port_ka_time))
+ next_timer = fip->port_ka_time;
+ mod_timer(&fip->timer, next_timer);
+ } else if (fip->sel_time) {
+ next_timer = fip->sel_time +
+ msecs_to_jiffies(FCOE_CTLR_START_DELAY);
+ mod_timer(&fip->timer, next_timer);
+ }
+ spin_unlock_bh(&fip->lock);
- return rc;
+ if (send_ctlr_ka)
+ fcoe_ctlr_send_keep_alive(fip, 0, fip->ctl_src_addr);
+ if (send_port_ka)
+ fcoe_ctlr_send_keep_alive(fip, 1, fip->data_src_addr);
}
-EXPORT_SYMBOL_GPL(fcoe_link_ok);
/**
- * fcoe_percpu_clean() - Clear the pending skbs for an lport
- * @lp: the fc_lport
+ * fcoe_ctlr_link_work() - worker thread function for link changes.
+ * @work: pointer to link_work member inside &fcoe_ctlr.
+ *
+ * See if the link status has changed and if so, report it.
+ *
+ * This is here because fc_linkup() and fc_linkdown() must not
+ * be called from the timer directly, since they use a mutex.
*/
-void fcoe_percpu_clean(struct fc_lport *lp)
+static void fcoe_ctlr_link_work(struct work_struct *work)
{
- int idx;
- struct fcoe_percpu_s *pp;
- struct fcoe_rcv_info *fr;
- struct sk_buff_head *list;
- struct sk_buff *skb, *next;
- struct sk_buff *head;
-
- for (idx = 0; idx < NR_CPUS; idx++) {
- if (fcoe_percpu[idx]) {
- pp = fcoe_percpu[idx];
- spin_lock_bh(&pp->fcoe_rx_list.lock);
- list = &pp->fcoe_rx_list;
- head = list->next;
- for (skb = head; skb != (struct sk_buff *)list;
- skb = next) {
- next = skb->next;
- fr = fcoe_dev_from_skb(skb);
- if (fr->fr_dev == lp) {
- __skb_unlink(skb, list);
- kfree_skb(skb);
- }
- }
- spin_unlock_bh(&pp->fcoe_rx_list.lock);
- }
+ struct fcoe_ctlr *fip;
+ int link;
+ int last_link;
+
+ fip = container_of(work, struct fcoe_ctlr, link_work);
+ spin_lock_bh(&fip->lock);
+ last_link = fip->last_link;
+ link = fip->link;
+ fip->last_link = link;
+ spin_unlock_bh(&fip->lock);
+
+ if (last_link != link) {
+ if (link)
+ fc_linkup(fip->lp);
+ else
+ fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT);
}
}
-EXPORT_SYMBOL_GPL(fcoe_percpu_clean);
/**
- * fcoe_clean_pending_queue() - Dequeue a skb and free it
- * @lp: the corresponding fc_lport
- *
- * Returns: none
+ * fcoe_ctlr_recv_work() - Worker thread function for receiving FIP frames.
+ * @recv_work: pointer to recv_work member inside &fcoe_ctlr.
*/
-void fcoe_clean_pending_queue(struct fc_lport *lp)
+static void fcoe_ctlr_recv_work(struct work_struct *recv_work)
{
- struct fcoe_softc *fc = lport_priv(lp);
+ struct fcoe_ctlr *fip;
struct sk_buff *skb;
- spin_lock_bh(&fc->fcoe_pending_queue.lock);
- while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) {
- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
- kfree_skb(skb);
- spin_lock_bh(&fc->fcoe_pending_queue.lock);
+ fip = container_of(recv_work, struct fcoe_ctlr, recv_work);
+ spin_lock_bh(&fip->fip_recv_list.lock);
+ while ((skb = __skb_dequeue(&fip->fip_recv_list))) {
+ spin_unlock_bh(&fip->fip_recv_list.lock);
+ fcoe_ctlr_recv_handler(fip, skb);
+ spin_lock_bh(&fip->fip_recv_list.lock);
}
- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+ spin_unlock_bh(&fip->fip_recv_list.lock);
}
-EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue);
/**
- * libfc_host_alloc() - Allocate a Scsi_Host with room for the fc_lport
- * @sht: ptr to the scsi host templ
- * @priv_size: size of private data after fc_lport
+ * fcoe_ctlr_recv_flogi() - snoop Pre-FIP receipt of FLOGI response or request.
+ * @fip: FCoE controller.
+ * @fp: FC frame.
+ * @sa: Ethernet source MAC address from received FCoE frame.
*
- * Returns: ptr to Scsi_Host
- * TODO: to libfc?
- */
-static inline struct Scsi_Host *
-libfc_host_alloc(struct scsi_host_template *sht, int priv_size)
-{
- return scsi_host_alloc(sht, sizeof(struct fc_lport) + priv_size);
-}
-
-/**
- * fcoe_host_alloc() - Allocate a Scsi_Host with room for the fcoe_softc
- * @sht: ptr to the scsi host templ
- * @priv_size: size of private data after fc_lport
+ * Snoop potential response to FLOGI or even incoming FLOGI.
*
- * Returns: ptr to Scsi_Host
- */
-struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *sht, int priv_size)
-{
- return libfc_host_alloc(sht, sizeof(struct fcoe_softc) + priv_size);
-}
-EXPORT_SYMBOL_GPL(fcoe_host_alloc);
-
-/**
- * fcoe_reset() - Resets the fcoe
- * @shost: shost the reset is from
+ * The caller has checked that we are waiting for login as indicated
+ * by fip->flogi_oxid != FC_XID_UNKNOWN.
+ *
+ * The caller is responsible for freeing the frame.
*
- * Returns: always 0
+ * Return non-zero if the frame should not be delivered to libfc.
*/
-int fcoe_reset(struct Scsi_Host *shost)
+int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa)
{
- struct fc_lport *lport = shost_priv(shost);
- fc_lport_reset(lport);
+ struct fc_frame_header *fh;
+ u8 op;
+ u8 mac[ETH_ALEN];
+
+ fh = fc_frame_header_get(fp);
+ if (fh->fh_type != FC_TYPE_ELS)
+ return 0;
+
+ op = fc_frame_payload_op(fp);
+ if (op == ELS_LS_ACC && fh->fh_r_ctl == FC_RCTL_ELS_REP &&
+ fip->flogi_oxid == ntohs(fh->fh_ox_id)) {
+
+ spin_lock_bh(&fip->lock);
+ if (fip->state != FIP_ST_AUTO && fip->state != FIP_ST_NON_FIP) {
+ spin_unlock_bh(&fip->lock);
+ return -EINVAL;
+ }
+ fip->state = FIP_ST_NON_FIP;
+ FIP_DBG("received FLOGI LS_ACC using non-FIP mode\n");
+
+ /*
+ * FLOGI accepted.
+ * If the src mac addr is FC_OUI-based, then we mark the
+ * address_mode flag to use FC_OUI-based Ethernet DA.
+ * Otherwise we use the FCoE gateway addr
+ */
+ if (!compare_ether_addr(sa, (u8[6])FC_FCOE_FLOGI_MAC)) {
+ fip->map_dest = 1;
+ } else {
+ memcpy(fip->dest_addr, sa, ETH_ALEN);
+ fip->map_dest = 0;
+ }
+ fip->flogi_oxid = FC_XID_UNKNOWN;
+ memcpy(mac, fip->data_src_addr, ETH_ALEN);
+ fc_fcoe_set_mac(fip->data_src_addr, fh->fh_d_id);
+ spin_unlock_bh(&fip->lock);
+
+ fip->update_mac(fip, mac, fip->data_src_addr);
+ } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
+ /*
+ * Save source MAC for point-to-point responses.
+ */
+ spin_lock_bh(&fip->lock);
+ if (fip->state == FIP_ST_AUTO || fip->state == FIP_ST_NON_FIP) {
+ memcpy(fip->dest_addr, sa, ETH_ALEN);
+ fip->map_dest = 0;
+ if (fip->state == FIP_ST_NON_FIP)
+ FIP_DBG("received FLOGI REQ, "
+ "using non-FIP mode\n");
+ fip->state = FIP_ST_NON_FIP;
+ }
+ spin_unlock_bh(&fip->lock);
+ }
return 0;
}
-EXPORT_SYMBOL_GPL(fcoe_reset);
+EXPORT_SYMBOL(fcoe_ctlr_recv_flogi);
/**
* fcoe_wwn_from_mac() - Converts 48-bit IEEE MAC address to 64-bit FC WWN.
@@ -1254,85 +1315,6 @@ u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac);
/**
- * fcoe_hostlist_lookup_softc() - find the corresponding lport by a given device
- * @device: this is currently ptr to net_device
- *
- * Returns: NULL or the located fcoe_softc
- */
-static struct fcoe_softc *
-fcoe_hostlist_lookup_softc(const struct net_device *dev)
-{
- struct fcoe_softc *fc;
-
- read_lock(&fcoe_hostlist_lock);
- list_for_each_entry(fc, &fcoe_hostlist, list) {
- if (fc->real_dev == dev) {
- read_unlock(&fcoe_hostlist_lock);
- return fc;
- }
- }
- read_unlock(&fcoe_hostlist_lock);
- return NULL;
-}
-
-/**
- * fcoe_hostlist_lookup() - Find the corresponding lport by netdev
- * @netdev: ptr to net_device
- *
- * Returns: 0 for success
- */
-struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
-{
- struct fcoe_softc *fc;
-
- fc = fcoe_hostlist_lookup_softc(netdev);
-
- return (fc) ? fc->lp : NULL;
-}
-EXPORT_SYMBOL_GPL(fcoe_hostlist_lookup);
-
-/**
- * fcoe_hostlist_add() - Add a lport to lports list
- * @lp: ptr to the fc_lport to badded
- *
- * Returns: 0 for success
- */
-int fcoe_hostlist_add(const struct fc_lport *lp)
-{
- struct fcoe_softc *fc;
-
- fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
- if (!fc) {
- fc = lport_priv(lp);
- write_lock_bh(&fcoe_hostlist_lock);
- list_add_tail(&fc->list, &fcoe_hostlist);
- write_unlock_bh(&fcoe_hostlist_lock);
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(fcoe_hostlist_add);
-
-/**
- * fcoe_hostlist_remove() - remove a lport from lports list
- * @lp: ptr to the fc_lport to badded
- *
- * Returns: 0 for success
- */
-int fcoe_hostlist_remove(const struct fc_lport *lp)
-{
- struct fcoe_softc *fc;
-
- fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
- BUG_ON(!fc);
- write_lock_bh(&fcoe_hostlist_lock);
- list_del(&fc->list);
- write_unlock_bh(&fcoe_hostlist_lock);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(fcoe_hostlist_remove);
-
-/**
* fcoe_libfc_config() - sets up libfc related properties for lport
* @lp: ptr to the fc_lport
* @tt: libfc function template
@@ -1354,121 +1336,3 @@ int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt)
return 0;
}
EXPORT_SYMBOL_GPL(fcoe_libfc_config);
-
-/**
- * fcoe_init() - fcoe module loading initialization
- *
- * Initialization routine
- * 1. Will create fc transport software structure
- * 2. initialize the link list of port information structure
- *
- * Returns 0 on success, negative on failure
- */
-static int __init fcoe_init(void)
-{
- int cpu;
- struct fcoe_percpu_s *p;
-
-
- INIT_LIST_HEAD(&fcoe_hostlist);
- rwlock_init(&fcoe_hostlist_lock);
-
-#ifdef CONFIG_HOTPLUG_CPU
- register_cpu_notifier(&fcoe_cpu_notifier);
-#endif /* CONFIG_HOTPLUG_CPU */
-
- /*
- * initialize per CPU interrupt thread
- */
- for_each_online_cpu(cpu) {
- p = kzalloc(sizeof(struct fcoe_percpu_s), GFP_KERNEL);
- if (p) {
- p->thread = kthread_create(fcoe_percpu_receive_thread,
- (void *)p,
- "fcoethread/%d", cpu);
-
- /*
- * if there is no error then bind the thread to the cpu
- * initialize the semaphore and skb queue head
- */
- if (likely(!IS_ERR(p->thread))) {
- p->cpu = cpu;
- fcoe_percpu[cpu] = p;
- skb_queue_head_init(&p->fcoe_rx_list);
- kthread_bind(p->thread, cpu);
- wake_up_process(p->thread);
- } else {
- fcoe_percpu[cpu] = NULL;
- kfree(p);
- }
- }
- }
-
- /*
- * setup link change notification
- */
- fcoe_dev_setup();
-
- setup_timer(&fcoe_timer, fcoe_watchdog, 0);
-
- mod_timer(&fcoe_timer, jiffies + (10 * HZ));
-
- /* initiatlize the fcoe transport */
- fcoe_transport_init();
-
- fcoe_sw_init();
-
- return 0;
-}
-module_init(fcoe_init);
-
-/**
- * fcoe_exit() - fcoe module unloading cleanup
- *
- * Returns 0 on success, negative on failure
- */
-static void __exit fcoe_exit(void)
-{
- u32 idx;
- struct fcoe_softc *fc, *tmp;
- struct fcoe_percpu_s *p;
- struct sk_buff *skb;
-
- /*
- * Stop all call back interfaces
- */
-#ifdef CONFIG_HOTPLUG_CPU
- unregister_cpu_notifier(&fcoe_cpu_notifier);
-#endif /* CONFIG_HOTPLUG_CPU */
- fcoe_dev_cleanup();
-
- /*
- * stop timer
- */
- del_timer_sync(&fcoe_timer);
-
- /* releases the associated fcoe transport for each lport */
- list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list)
- fcoe_transport_release(fc->real_dev);
-
- for (idx = 0; idx < NR_CPUS; idx++) {
- if (fcoe_percpu[idx]) {
- kthread_stop(fcoe_percpu[idx]->thread);
- p = fcoe_percpu[idx];
- spin_lock_bh(&p->fcoe_rx_list.lock);
- while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
- kfree_skb(skb);
- spin_unlock_bh(&p->fcoe_rx_list.lock);
- if (fcoe_percpu[idx]->crc_eof_page)
- put_page(fcoe_percpu[idx]->crc_eof_page);
- kfree(fcoe_percpu[idx]);
- }
- }
-
- /* remove sw trasnport */
- fcoe_sw_exit();
-
- /* detach the transport */
- fcoe_transport_exit();
-}
-module_exit(fcoe_exit);
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index fb247fdfa2b..185e6bc4dd4 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -5023,16 +5023,16 @@ static int __devinit gdth_pci_probe_one(gdth_pci_str *pcistr,
/* 64-bit DMA only supported from FW >= x.43 */
if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) ||
!ha->dma64_support) {
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "GDT-PCI %d: "
"Unable to set 32-bit DMA\n", ha->hanum);
goto out_free_coal_stat;
}
} else {
shp->max_cmd_len = 16;
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum);
- } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ } else if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "GDT-PCI %d: "
"Unable to set 64/32-bit DMA\n", ha->hanum);
goto out_free_coal_stat;
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index af1f0af0c5a..c596ab5f05c 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -958,8 +958,8 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
pci_set_master(pcidev);
/* Enable 64bit DMA if possible */
- if (pci_set_dma_mask(pcidev, DMA_64BIT_MASK)) {
- if (pci_set_dma_mask(pcidev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pcidev, DMA_BIT_MASK(64))) {
+ if (pci_set_dma_mask(pcidev, DMA_BIT_MASK(32))) {
printk(KERN_ERR "hptiop: fail to set dma_mask\n");
goto disable_pci_device;
}
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 93d1fbe4ee5..ea4abee7a2a 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -75,7 +75,7 @@ MODULE_PARM_DESC(max_lun, "Maximum allowed LUN. "
module_param_named(max_targets, max_targets, uint, S_IRUGO);
MODULE_PARM_DESC(max_targets, "Maximum allowed targets. "
"[Default=" __stringify(IBMVFC_MAX_TARGETS) "]");
-module_param_named(disc_threads, disc_threads, uint, S_IRUGO | S_IWUSR);
+module_param_named(disc_threads, disc_threads, uint, S_IRUGO);
MODULE_PARM_DESC(disc_threads, "Number of device discovery threads to use. "
"[Default=" __stringify(IBMVFC_MAX_DISC_THREADS) "]");
module_param_named(debug, ibmvfc_debug, uint, S_IRUGO | S_IWUSR);
@@ -640,6 +640,7 @@ static void ibmvfc_release_crq_queue(struct ibmvfc_host *vhost)
ibmvfc_dbg(vhost, "Releasing CRQ\n");
free_irq(vdev->irq, vhost);
+ tasklet_kill(&vhost->tasklet);
do {
rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
@@ -2699,6 +2700,25 @@ static struct ibmvfc_crq *ibmvfc_next_crq(struct ibmvfc_host *vhost)
static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance)
{
struct ibmvfc_host *vhost = (struct ibmvfc_host *)dev_instance;
+ unsigned long flags;
+
+ spin_lock_irqsave(vhost->host->host_lock, flags);
+ vio_disable_interrupts(to_vio_dev(vhost->dev));
+ tasklet_schedule(&vhost->tasklet);
+ spin_unlock_irqrestore(vhost->host->host_lock, flags);
+ return IRQ_HANDLED;
+}
+
+/**
+ * ibmvfc_tasklet - Interrupt handler tasklet
+ * @data: ibmvfc host struct
+ *
+ * Returns:
+ * Nothing
+ **/
+static void ibmvfc_tasklet(void *data)
+{
+ struct ibmvfc_host *vhost = data;
struct vio_dev *vdev = to_vio_dev(vhost->dev);
struct ibmvfc_crq *crq;
struct ibmvfc_async_crq *async;
@@ -2706,7 +2726,6 @@ static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance)
int done = 0;
spin_lock_irqsave(vhost->host->host_lock, flags);
- vio_disable_interrupts(to_vio_dev(vhost->dev));
while (!done) {
/* Pull all the valid messages off the CRQ */
while ((crq = ibmvfc_next_crq(vhost)) != NULL) {
@@ -2734,7 +2753,6 @@ static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance)
}
spin_unlock_irqrestore(vhost->host->host_lock, flags);
- return IRQ_HANDLED;
}
/**
@@ -3105,6 +3123,7 @@ static void ibmvfc_tgt_adisc_done(struct ibmvfc_event *evt)
vhost->discovery_threads--;
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+ del_timer(&tgt->timer);
switch (status) {
case IBMVFC_MAD_SUCCESS:
@@ -3161,9 +3180,89 @@ static void ibmvfc_init_passthru(struct ibmvfc_event *evt)
}
/**
+ * ibmvfc_tgt_adisc_cancel_done - Completion handler when cancelling an ADISC
+ * @evt: ibmvfc event struct
+ *
+ * Just cleanup this event struct. Everything else is handled by
+ * the ADISC completion handler. If the ADISC never actually comes
+ * back, we still have the timer running on the ADISC event struct
+ * which will fire and cause the CRQ to get reset.
+ *
+ **/
+static void ibmvfc_tgt_adisc_cancel_done(struct ibmvfc_event *evt)
+{
+ struct ibmvfc_host *vhost = evt->vhost;
+ struct ibmvfc_target *tgt = evt->tgt;
+
+ tgt_dbg(tgt, "ADISC cancel complete\n");
+ vhost->abort_threads--;
+ ibmvfc_free_event(evt);
+ kref_put(&tgt->kref, ibmvfc_release_tgt);
+ wake_up(&vhost->work_wait_q);
+}
+
+/**
+ * ibmvfc_adisc_timeout - Handle an ADISC timeout
+ * @tgt: ibmvfc target struct
+ *
+ * If an ADISC times out, send a cancel. If the cancel times
+ * out, reset the CRQ. When the ADISC comes back as cancelled,
+ * log back into the target.
+ **/
+static void ibmvfc_adisc_timeout(struct ibmvfc_target *tgt)
+{
+ struct ibmvfc_host *vhost = tgt->vhost;
+ struct ibmvfc_event *evt;
+ struct ibmvfc_tmf *tmf;
+ unsigned long flags;
+ int rc;
+
+ tgt_dbg(tgt, "ADISC timeout\n");
+ spin_lock_irqsave(vhost->host->host_lock, flags);
+ if (vhost->abort_threads >= disc_threads ||
+ tgt->action != IBMVFC_TGT_ACTION_INIT_WAIT ||
+ vhost->state != IBMVFC_INITIALIZING ||
+ vhost->action != IBMVFC_HOST_ACTION_QUERY_TGTS) {
+ spin_unlock_irqrestore(vhost->host->host_lock, flags);
+ return;
+ }
+
+ vhost->abort_threads++;
+ kref_get(&tgt->kref);
+ evt = ibmvfc_get_event(vhost);
+ ibmvfc_init_event(evt, ibmvfc_tgt_adisc_cancel_done, IBMVFC_MAD_FORMAT);
+
+ evt->tgt = tgt;
+ tmf = &evt->iu.tmf;
+ memset(tmf, 0, sizeof(*tmf));
+ tmf->common.version = 1;
+ tmf->common.opcode = IBMVFC_TMF_MAD;
+ tmf->common.length = sizeof(*tmf);
+ tmf->scsi_id = tgt->scsi_id;
+ tmf->cancel_key = tgt->cancel_key;
+
+ rc = ibmvfc_send_event(evt, vhost, default_timeout);
+
+ if (rc) {
+ tgt_err(tgt, "Failed to send cancel event for ADISC. rc=%d\n", rc);
+ vhost->abort_threads--;
+ kref_put(&tgt->kref, ibmvfc_release_tgt);
+ __ibmvfc_reset_host(vhost);
+ } else
+ tgt_dbg(tgt, "Attempting to cancel ADISC\n");
+ spin_unlock_irqrestore(vhost->host->host_lock, flags);
+}
+
+/**
* ibmvfc_tgt_adisc - Initiate an ADISC for specified target
* @tgt: ibmvfc target struct
*
+ * When sending an ADISC we end up with two timers running. The
+ * first timer is the timer in the ibmvfc target struct. If this
+ * fires, we send a cancel to the target. The second timer is the
+ * timer on the ibmvfc event for the ADISC, which is longer. If that
+ * fires, it means the ADISC timed out and our attempt to cancel it
+ * also failed, so we need to reset the CRQ.
**/
static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt)
{
@@ -3184,6 +3283,7 @@ static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt)
mad = &evt->iu.passthru;
mad->iu.flags = IBMVFC_FC_ELS;
mad->iu.scsi_id = tgt->scsi_id;
+ mad->iu.cancel_key = tgt->cancel_key;
mad->fc_iu.payload[0] = IBMVFC_ADISC;
memcpy(&mad->fc_iu.payload[2], &vhost->login_buf->resp.port_name,
@@ -3192,9 +3292,19 @@ static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt)
sizeof(vhost->login_buf->resp.node_name));
mad->fc_iu.payload[6] = vhost->login_buf->resp.scsi_id & 0x00ffffff;
+ if (timer_pending(&tgt->timer))
+ mod_timer(&tgt->timer, jiffies + (IBMVFC_ADISC_TIMEOUT * HZ));
+ else {
+ tgt->timer.data = (unsigned long) tgt;
+ tgt->timer.expires = jiffies + (IBMVFC_ADISC_TIMEOUT * HZ);
+ tgt->timer.function = (void (*)(unsigned long))ibmvfc_adisc_timeout;
+ add_timer(&tgt->timer);
+ }
+
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
- if (ibmvfc_send_event(evt, vhost, default_timeout)) {
+ if (ibmvfc_send_event(evt, vhost, IBMVFC_ADISC_PLUS_CANCEL_TIMEOUT)) {
vhost->discovery_threads--;
+ del_timer(&tgt->timer);
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
kref_put(&tgt->kref, ibmvfc_release_tgt);
} else
@@ -3322,6 +3432,8 @@ static int ibmvfc_alloc_target(struct ibmvfc_host *vhost, u64 scsi_id)
tgt->new_scsi_id = scsi_id;
tgt->vhost = vhost;
tgt->need_login = 1;
+ tgt->cancel_key = vhost->task_set++;
+ init_timer(&tgt->timer);
kref_init(&tgt->kref);
ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout);
spin_lock_irqsave(vhost->host->host_lock, flags);
@@ -3716,6 +3828,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
spin_unlock_irqrestore(vhost->host->host_lock, flags);
if (rport)
fc_remote_port_delete(rport);
+ del_timer_sync(&tgt->timer);
kref_put(&tgt->kref, ibmvfc_release_tgt);
return;
}
@@ -3859,6 +3972,8 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost)
retrc = 0;
+ tasklet_init(&vhost->tasklet, (void *)ibmvfc_tasklet, (unsigned long)vhost);
+
if ((rc = request_irq(vdev->irq, ibmvfc_interrupt, 0, IBMVFC_NAME, vhost))) {
dev_err(dev, "Couldn't register irq 0x%x. rc=%d\n", vdev->irq, rc);
goto req_irq_failed;
@@ -3874,6 +3989,7 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost)
return retrc;
req_irq_failed:
+ tasklet_kill(&vhost->tasklet);
do {
rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
@@ -4040,6 +4156,7 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
vhost->dev = dev;
vhost->partition_number = -1;
vhost->log_level = log_level;
+ vhost->task_set = 1;
strcpy(vhost->partition_name, "UNKNOWN");
init_waitqueue_head(&vhost->work_wait_q);
init_waitqueue_head(&vhost->init_wait_q);
@@ -4174,6 +4291,7 @@ static struct fc_function_template ibmvfc_transport_functions = {
.show_host_supported_classes = 1,
.show_host_port_type = 1,
.show_host_port_id = 1,
+ .show_host_maxframe_size = 1,
.get_host_port_state = ibmvfc_get_host_port_state,
.show_host_port_state = 1,
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
index b21e071b986..ca1dcf7a756 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -29,10 +29,14 @@
#include "viosrp.h"
#define IBMVFC_NAME "ibmvfc"
-#define IBMVFC_DRIVER_VERSION "1.0.4"
-#define IBMVFC_DRIVER_DATE "(November 14, 2008)"
+#define IBMVFC_DRIVER_VERSION "1.0.5"
+#define IBMVFC_DRIVER_DATE "(March 19, 2009)"
#define IBMVFC_DEFAULT_TIMEOUT 60
+#define IBMVFC_ADISC_CANCEL_TIMEOUT 45
+#define IBMVFC_ADISC_TIMEOUT 15
+#define IBMVFC_ADISC_PLUS_CANCEL_TIMEOUT \
+ (IBMVFC_ADISC_TIMEOUT + IBMVFC_ADISC_CANCEL_TIMEOUT)
#define IBMVFC_INIT_TIMEOUT 120
#define IBMVFC_MAX_REQUESTS_DEFAULT 100
@@ -53,9 +57,9 @@
* Ensure we have resources for ERP and initialization:
* 1 for ERP
* 1 for initialization
- * 1 for each discovery thread
+ * 2 for each discovery thread
*/
-#define IBMVFC_NUM_INTERNAL_REQ (1 + 1 + disc_threads)
+#define IBMVFC_NUM_INTERNAL_REQ (1 + 1 + (disc_threads * 2))
#define IBMVFC_MAD_SUCCESS 0x00
#define IBMVFC_MAD_NOT_SUPPORTED 0xF1
@@ -585,10 +589,12 @@ struct ibmvfc_target {
enum ibmvfc_target_action action;
int need_login;
int init_retries;
+ u32 cancel_key;
struct ibmvfc_service_parms service_parms;
struct ibmvfc_service_parms service_parms_change;
struct fc_rport_identifiers ids;
void (*job_step) (struct ibmvfc_target *);
+ struct timer_list timer;
struct kref kref;
};
@@ -672,6 +678,7 @@ struct ibmvfc_host {
int task_set;
int init_retries;
int discovery_threads;
+ int abort_threads;
int client_migrated;
int reinit;
int delay_init;
@@ -684,6 +691,7 @@ struct ibmvfc_host {
char partition_name[97];
void (*job_step) (struct ibmvfc_host *);
struct task_struct *work_thread;
+ struct tasklet_struct tasklet;
wait_queue_head_t init_wait_q;
wait_queue_head_t work_wait_q;
};
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
index 5529518ff2f..89a59484be0 100644
--- a/drivers/scsi/initio.c
+++ b/drivers/scsi/initio.c
@@ -2856,7 +2856,7 @@ static int initio_probe_one(struct pci_dev *pdev,
reg = 0;
bios_seg = (bios_seg << 8) + ((u16) ((reg & 0xFF00) >> 8));
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "i91u: Could not set 32 bit DMA mask\n");
error = -ENODEV;
goto out_disable_device;
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index def473f0a98..c09d77591f9 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -7498,7 +7498,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
pci_set_master(pdev);
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc < 0) {
dev_err(&pdev->dev, "Failed to set PCI DMA mask\n");
goto cleanup_nomem;
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 457d76a4cfe..f83a116955f 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -7048,10 +7048,10 @@ ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr)
* are guaranteed to be < 4G.
*/
if (IPS_ENABLE_DMA64 && IPS_HAS_ENH_SGLIST(ha) &&
- !pci_set_dma_mask(ha->pcidev, DMA_64BIT_MASK)) {
+ !pci_set_dma_mask(ha->pcidev, DMA_BIT_MASK(64))) {
(ha)->flags |= IPS_HA_ENH_SG;
} else {
- if (pci_set_dma_mask(ha->pcidev, DMA_32BIT_MASK) != 0) {
+ if (pci_set_dma_mask(ha->pcidev, DMA_BIT_MASK(32)) != 0) {
printk(KERN_WARNING "Unable to set DMA Mask\n");
return ips_abort_init(ha, index);
}
diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
index f23c4ca9a2e..b3d31315ac3 100644
--- a/drivers/scsi/lasi700.c
+++ b/drivers/scsi/lasi700.c
@@ -108,7 +108,7 @@ lasi700_probe(struct parisc_device *dev)
}
hostdata->dev = &dev->dev;
- dma_set_mask(&dev->dev, DMA_32BIT_MASK);
+ dma_set_mask(&dev->dev, DMA_BIT_MASK(32));
hostdata->base = ioremap_nocache(base, 0x100);
hostdata->differential = 0;
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index a5725f3b7ce..f555ae99ad4 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -41,7 +41,7 @@
MODULE_AUTHOR("Open-FCoE.org");
MODULE_DESCRIPTION("libfc");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
static int fc_fcp_debug;
@@ -407,10 +407,12 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
if (~crc != le32_to_cpu(fr_crc(fp))) {
crc_err:
- stats = lp->dev_stats[smp_processor_id()];
+ stats = fc_lport_get_stats(lp);
stats->ErrorFrames++;
+ /* FIXME - per cpu count, not total count! */
if (stats->InvalidCRCCount++ < 5)
- FC_DBG("CRC error on data frame\n");
+ printk(KERN_WARNING "CRC error on data frame for port (%6x)\n",
+ fc_host_port_id(lp->host));
/*
* Assume the frame is total garbage.
* We may have copied it over the good part
@@ -1752,7 +1754,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
/*
* setup the data direction
*/
- stats = lp->dev_stats[smp_processor_id()];
+ stats = fc_lport_get_stats(lp);
if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {
fsp->req_flags = FC_SRB_READ;
stats->InputRequests++;
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 7ef44501ecc..b8178ef398d 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -267,10 +267,10 @@ EXPORT_SYMBOL(fc_get_host_speed);
struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
{
- int i;
struct fc_host_statistics *fcoe_stats;
struct fc_lport *lp = shost_priv(shost);
struct timespec v0, v1;
+ unsigned int cpu;
fcoe_stats = &lp->host_stats;
memset(fcoe_stats, 0, sizeof(struct fc_host_statistics));
@@ -279,10 +279,11 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
jiffies_to_timespec(lp->boot_time, &v1);
fcoe_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec);
- for_each_online_cpu(i) {
- struct fcoe_dev_stats *stats = lp->dev_stats[i];
- if (stats == NULL)
- continue;
+ for_each_possible_cpu(cpu) {
+ struct fcoe_dev_stats *stats;
+
+ stats = per_cpu_ptr(lp->dev_stats, cpu);
+
fcoe_stats->tx_frames += stats->TxFrames;
fcoe_stats->tx_words += stats->TxWords;
fcoe_stats->rx_frames += stats->RxFrames;
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index dfaa8adf099..68962835916 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1999,8 +1999,10 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size)
q->queue = kfifo_init((void*)q->pool, max * sizeof(void*),
GFP_KERNEL, NULL);
- if (q->queue == ERR_PTR(-ENOMEM))
+ if (IS_ERR(q->queue)) {
+ q->queue = NULL;
goto enomem;
+ }
for (i = 0; i < max; i++) {
q->pool[i] = kzalloc(item_size, GFP_KERNEL);
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 6c867311cef..06874e6009e 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2660,8 +2660,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
pci_save_state(pdev);
pci_try_set_mwi(pdev);
- if (pci_set_dma_mask(phba->pcidev, DMA_64BIT_MASK) != 0)
- if (pci_set_dma_mask(phba->pcidev, DMA_32BIT_MASK) != 0)
+ if (pci_set_dma_mask(phba->pcidev, DMA_BIT_MASK(64)) != 0)
+ if (pci_set_dma_mask(phba->pcidev, DMA_BIT_MASK(32)) != 0)
goto out_idr_remove;
/*
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index b1bd3fc7bae..36fd2e75da1 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1394,7 +1394,7 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd,
*/
cmd->sense_buffer[8] = 0; /* Information */
cmd->sense_buffer[9] = 0xa; /* Add. length */
- do_div(bghm, cmd->device->sector_size);
+ bghm /= cmd->device->sector_size;
failing_sector = scsi_get_lba(cmd);
failing_sector += bghm;
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 9fdcd60c549..49eb0612d5a 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -2021,7 +2021,7 @@ make_local_pdev(adapter_t *adapter, struct pci_dev **pdev)
memcpy(*pdev, adapter->dev, sizeof(struct pci_dev));
- if( pci_set_dma_mask(*pdev, DMA_32BIT_MASK) != 0 ) {
+ if( pci_set_dma_mask(*pdev, DMA_BIT_MASK(32)) != 0 ) {
kfree(*pdev);
return -1;
}
@@ -4793,10 +4793,10 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Set the Mode of addressing to 64 bit if we can */
if ((adapter->flag & BOARD_64BIT) && (sizeof(dma_addr_t) == 8)) {
- pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
adapter->has_64bit_addr = 1;
} else {
- pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
adapter->has_64bit_addr = 0;
}
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 805bb61dde1..234f0b7eb21 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -473,7 +473,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
// Setup the default DMA mask. This would be changed later on
// depending on hardware capabilities
- if (pci_set_dma_mask(adapter->pdev, DMA_32BIT_MASK) != 0) {
+ if (pci_set_dma_mask(adapter->pdev, DMA_BIT_MASK(32)) != 0) {
con_log(CL_ANN, (KERN_WARNING
"megaraid: pci_set_dma_mask failed:%d\n", __LINE__));
@@ -900,11 +900,11 @@ megaraid_init_mbox(adapter_t *adapter)
adapter->pdev->device == PCI_DEVICE_ID_PERC4_DI_EVERGLADES) ||
(adapter->pdev->vendor == PCI_VENDOR_ID_DELL &&
adapter->pdev->device == PCI_DEVICE_ID_PERC4E_DI_KOBUK)) {
- if (pci_set_dma_mask(adapter->pdev, DMA_64BIT_MASK)) {
+ if (pci_set_dma_mask(adapter->pdev, DMA_BIT_MASK(64))) {
con_log(CL_ANN, (KERN_WARNING
"megaraid: DMA mask for 64-bit failed\n"));
- if (pci_set_dma_mask (adapter->pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask (adapter->pdev, DMA_BIT_MASK(32))) {
con_log(CL_ANN, (KERN_WARNING
"megaraid: 32-bit DMA mask failed\n"));
goto out_free_sysfs_res;
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 17ce7abe17e..7dc3d1894b1 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -2497,13 +2497,13 @@ megasas_set_dma_mask(struct pci_dev *pdev)
* All our contollers are capable of performing 64-bit DMA
*/
if (IS_DMA64) {
- if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
goto fail_set_dma_mask;
}
} else {
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
goto fail_set_dma_mask;
}
return 0;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 52427a8324f..a91f5143cea 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -855,9 +855,9 @@ _base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev)
if (sizeof(dma_addr_t) > 4) {
const uint64_t required_mask =
dma_get_required_mask(&pdev->dev);
- if ((required_mask > DMA_32BIT_MASK) && !pci_set_dma_mask(pdev,
- DMA_64BIT_MASK) && !pci_set_consistent_dma_mask(pdev,
- DMA_64BIT_MASK)) {
+ if ((required_mask > DMA_BIT_MASK(32)) && !pci_set_dma_mask(pdev,
+ DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(pdev,
+ DMA_BIT_MASK(64))) {
ioc->base_add_sg_single = &_base_add_sg_single_64;
ioc->sge_size = sizeof(Mpi2SGESimple64_t);
desc = "64";
@@ -865,8 +865,8 @@ _base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev)
}
}
- if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)
- && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
+ && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
ioc->base_add_sg_single = &_base_add_sg_single_32;
ioc->sge_size = sizeof(Mpi2SGESimple32_t);
desc = "32";
diff --git a/drivers/scsi/mvsas.c b/drivers/scsi/mvsas.c
index 23e5a876bb1..e4acebd10d1 100644
--- a/drivers/scsi/mvsas.c
+++ b/drivers/scsi/mvsas.c
@@ -875,10 +875,10 @@ static int pci_go_64(struct pci_dev *pdev)
{
int rc;
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
- rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (rc) {
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"64-bit DMA enable failed\n");
@@ -886,13 +886,13 @@ static int pci_go_64(struct pci_dev *pdev)
}
}
} else {
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit DMA enable failed\n");
return rc;
}
- rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit consistent DMA enable failed\n");
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index d06ec5aa692..2be7d5b018d 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -2672,7 +2672,7 @@ static int nsp32_detect(struct pci_dev *pdev)
/*
* setup DMA
*/
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
nsp32_msg (KERN_ERR, "failed to set PCI DMA mask");
goto scsi_unregister;
}
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 552f58b655d..2a5f0777148 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -338,20 +338,6 @@ struct osd_request *osd_start_request(struct osd_dev *dev, gfp_t gfp)
}
EXPORT_SYMBOL(osd_start_request);
-/*
- * If osd_finalize_request() was called but the request was not executed through
- * the block layer, then we must release BIOs.
- */
-static void _abort_unexecuted_bios(struct request *rq)
-{
- struct bio *bio;
-
- while ((bio = rq->bio) != NULL) {
- rq->bio = bio->bi_next;
- bio_endio(bio, 0);
- }
-}
-
static void _osd_free_seg(struct osd_request *or __unused,
struct _osd_req_data_segment *seg)
{
@@ -363,9 +349,30 @@ static void _osd_free_seg(struct osd_request *or __unused,
seg->alloc_size = 0;
}
+static void _put_request(struct request *rq , bool is_async)
+{
+ if (is_async) {
+ WARN_ON(rq->bio);
+ __blk_put_request(rq->q, rq);
+ } else {
+ /*
+ * If osd_finalize_request() was called but the request was not
+ * executed through the block layer, then we must release BIOs.
+ * TODO: Keep error code in or->async_error. Need to audit all
+ * code paths.
+ */
+ if (unlikely(rq->bio))
+ blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq));
+ else
+ blk_put_request(rq);
+ }
+}
+
void osd_end_request(struct osd_request *or)
{
struct request *rq = or->request;
+ /* IMPORTANT: make sure this agrees with osd_execute_request_async */
+ bool is_async = (or->request->end_io_data == or);
_osd_free_seg(or, &or->set_attr);
_osd_free_seg(or, &or->enc_get_attr);
@@ -373,12 +380,11 @@ void osd_end_request(struct osd_request *or)
if (rq) {
if (rq->next_rq) {
- _abort_unexecuted_bios(rq->next_rq);
- blk_put_request(rq->next_rq);
+ _put_request(rq->next_rq, is_async);
+ rq->next_rq = NULL;
}
- _abort_unexecuted_bios(rq);
- blk_put_request(rq);
+ _put_request(rq, is_async);
}
_osd_request_free(or);
}
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
index f8b1a749958..f644c9571ea 100644
--- a/drivers/scsi/osd/osd_uld.c
+++ b/drivers/scsi/osd/osd_uld.c
@@ -345,10 +345,6 @@ static int osd_probe(struct device *dev)
}
dev_set_drvdata(oud->class_member, oud);
- error = sysfs_create_link(&scsi_device->sdev_gendev.kobj,
- &oud->class_member->kobj, osd_symlink);
- if (error)
- OSD_ERR("warning: unable to make symlink\n");
OSD_INFO("osd_probe %s\n", disk->disk_name);
return 0;
@@ -377,8 +373,6 @@ static int osd_remove(struct device *dev)
scsi_device);
}
- sysfs_remove_link(&oud->od.scsi_device->sdev_gendev.kobj, osd_symlink);
-
if (oud->class_member)
device_destroy(osd_sysfs_class,
MKDEV(SCSI_OSD_MAJOR, oud->minor));
diff --git a/drivers/scsi/ql1040_fw.h b/drivers/scsi/ql1040_fw.h
deleted file mode 100644
index aaf9284a8b7..00000000000
--- a/drivers/scsi/ql1040_fw.h
+++ /dev/null
@@ -1,2130 +0,0 @@
-/**************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * Copyright (C) 2004 QLogic Corporation
- * (www.qlogic.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, 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.
- *
- *************************************************************************/
-
-/************************************************************************
- * *
- * --- ISP1040 Initiator/Target Firmware --- *
- * 32 LUN Support *
- * *
- ************************************************************************
- */
-
-/*
- * Firmware Version 7.65.06 (14:38 Jan 07, 2002)
- */
-
-static unsigned char firmware_version[] = {7,65,6};
-
-#define FW_VERSION_STRING "7.65.06"
-
-static unsigned short risc_code_addr01 = 0x1000 ;
-
-static unsigned short risc_code01[] = {
- 0x0078, 0x103a, 0x0000, 0x4158, 0x0000, 0x2043, 0x4f50, 0x5952,
- 0x4947, 0x4854, 0x2031, 0x3939, 0x3520, 0x514c, 0x4f47, 0x4943,
- 0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
- 0x3130, 0x3230, 0x2049, 0x2f54, 0x2046, 0x6972, 0x6d77, 0x6172,
- 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, 0x372e, 0x3635,
- 0x2020, 0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20,
- 0x3030, 0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020,
- 0x3031, 0x2024, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x0048,
- 0x1045, 0x0038, 0x104b, 0x0078, 0x1047, 0x0028, 0x104b, 0x20b9,
- 0x1212, 0x0078, 0x104d, 0x20b9, 0x2222, 0x20c1, 0x0008, 0x2071,
- 0x0010, 0x70c3, 0x0004, 0x20c9, 0x78ff, 0x2089, 0x1186, 0x70c7,
- 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x0007, 0x3f00,
- 0x70d6, 0x20c1, 0x0008, 0x2019, 0x0000, 0x2009, 0xfeff, 0x2100,
- 0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64, 0x206b, 0x0a0a, 0xaddc,
- 0x3fff, 0x2b54, 0x205b, 0x5050, 0x2114, 0xa286, 0xa5a5, 0x0040,
- 0x10bf, 0xa386, 0x000f, 0x0040, 0x1085, 0x2c6a, 0x2a5a, 0x20c1,
- 0x0000, 0x2019, 0x000f, 0x0078, 0x1065, 0x2c6a, 0x2a5a, 0x20c1,
- 0x0008, 0x2009, 0x7fff, 0x2148, 0x2944, 0x204b, 0x0a0a, 0xa9bc,
- 0x3fff, 0x2734, 0x203b, 0x5050, 0x2114, 0xa286, 0x0a0a, 0x0040,
- 0x10a9, 0x284a, 0x263a, 0x20c1, 0x0004, 0x2009, 0x3fff, 0x2134,
- 0x200b, 0x5050, 0x2114, 0xa286, 0x5050, 0x0040, 0x10aa, 0x0078,
- 0x118e, 0x284a, 0x263a, 0x98c0, 0xa188, 0x1000, 0x212c, 0x200b,
- 0xa5a5, 0x2114, 0xa286, 0xa5a5, 0x0040, 0x10bc, 0x250a, 0xa18a,
- 0x1000, 0x98c1, 0x0078, 0x10c1, 0x250a, 0x0078, 0x10c1, 0x2c6a,
- 0x2a5a, 0x2130, 0xa18a, 0x0040, 0x2128, 0xa1a2, 0x5200, 0x8424,
- 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0xa192, 0x7900, 0x2009,
- 0x0000, 0x2001, 0x0031, 0x1078, 0x1d26, 0x2218, 0x2079, 0x5200,
- 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109,
- 0x00c0, 0x10dc, 0x7ef2, 0x8528, 0x7de6, 0x7cea, 0x7bee, 0x7883,
- 0x0000, 0x2031, 0x0030, 0x78cf, 0x0101, 0x780b, 0x0002, 0x780f,
- 0x0002, 0x784f, 0x0003, 0x2069, 0x5240, 0x2001, 0x04fd, 0x2004,
- 0xa082, 0x0005, 0x0048, 0x1104, 0x0038, 0x1100, 0x0078, 0x1108,
- 0x681b, 0x003c, 0x0078, 0x110a, 0x00a8, 0x1108, 0x681b, 0x003c,
- 0x681b, 0x0028, 0x6807, 0x0007, 0x680b, 0x00fa, 0x680f, 0x0008,
- 0x6813, 0x0005, 0x6823, 0x0000, 0x6827, 0x0006, 0x6817, 0x0008,
- 0x682b, 0x0000, 0x681f, 0x0019, 0x2069, 0x5480, 0x2011, 0x0020,
- 0x2009, 0x0010, 0x680b, 0x080c, 0x680f, 0x0019, 0x6803, 0xfd00,
- 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004,
- 0x8109, 0x00c0, 0x1122, 0x2069, 0x5500, 0x2009, 0x0002, 0x20a9,
- 0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bf0, 0xa386, 0xfeff,
- 0x00c0, 0x1148, 0x6817, 0x0100, 0x681f, 0x0064, 0x0078, 0x114c,
- 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, 0x0070, 0x1152,
- 0x0078, 0x1139, 0x8109, 0x00c0, 0x1137, 0x1078, 0x22a7, 0x1078,
- 0x493d, 0x1078, 0x19b5, 0x1078, 0x4e33, 0x3200, 0xa085, 0x000d,
- 0x2090, 0x70c3, 0x0000, 0x0090, 0x116c, 0x70c0, 0xa086, 0x0002,
- 0x00c0, 0x116c, 0x1078, 0x1284, 0x1078, 0x1196, 0x78cc, 0xa005,
- 0x00c0, 0x117a, 0x1078, 0x1d4f, 0x0010, 0x1180, 0x0068, 0x1180,
- 0x1078, 0x2186, 0x0010, 0x1180, 0x0068, 0x1180, 0x1078, 0x1ab9,
- 0x00e0, 0x116c, 0x1078, 0x4cba, 0x0078, 0x116c, 0x118e, 0x1190,
- 0x24ac, 0x24ac, 0x49be, 0x49be, 0x24ac, 0x24ac, 0x0078, 0x118e,
- 0x0078, 0x1190, 0x0078, 0x1192, 0x0078, 0x1194, 0x0068, 0x1201,
- 0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1201, 0x7814,
- 0xa005, 0x00c0, 0x11a7, 0x0010, 0x1202, 0x0078, 0x1201, 0x2009,
- 0x525b, 0x2104, 0xa005, 0x00c0, 0x1201, 0x2009, 0x5264, 0x200b,
- 0x0000, 0x7914, 0xa186, 0x0042, 0x00c0, 0x11cc, 0x7816, 0x2009,
- 0x5262, 0x2164, 0x200b, 0x0000, 0x6018, 0x70c6, 0x6014, 0x70ca,
- 0x611c, 0xa18c, 0xff00, 0x6020, 0xa084, 0x00ff, 0xa105, 0x70ce,
- 0x1078, 0x199a, 0x0078, 0x11ff, 0x7814, 0xa086, 0x0018, 0x00c0,
- 0x11d3, 0x1078, 0x1678, 0x7817, 0x0000, 0x2009, 0x5262, 0x2104,
- 0xa065, 0x0040, 0x11ef, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x1a17,
- 0x0c7f, 0x609f, 0x0000, 0x1078, 0x174e, 0x2009, 0x000c, 0x6007,
- 0x0103, 0x1078, 0x1976, 0x00c0, 0x11fb, 0x1078, 0x199a, 0x2009,
- 0x5262, 0x200b, 0x0000, 0x2009, 0x525c, 0x2104, 0x200b, 0x0000,
- 0xa005, 0x0040, 0x11ff, 0x2001, 0x4005, 0x0078, 0x1286, 0x0078,
- 0x1284, 0x007c, 0x70c3, 0x0000, 0x70c7, 0x0000, 0x70cb, 0x0000,
- 0x70cf, 0x0000, 0x70c0, 0xa0bc, 0xffc0, 0x00c0, 0x1252, 0x2038,
- 0x0079, 0x1212, 0x1284, 0x12e5, 0x12a9, 0x12fe, 0x130d, 0x1313,
- 0x12a0, 0x1766, 0x1317, 0x1298, 0x12ad, 0x12af, 0x12b1, 0x12b3,
- 0x176b, 0x1298, 0x1329, 0x1365, 0x1690, 0x1760, 0x12b5, 0x15af,
- 0x15cb, 0x15e7, 0x1612, 0x1568, 0x1576, 0x158a, 0x159e, 0x13e9,
- 0x1298, 0x1397, 0x139d, 0x13a2, 0x13a7, 0x13ad, 0x13b2, 0x13b7,
- 0x13bc, 0x13c1, 0x13c5, 0x13da, 0x13e6, 0x1298, 0x1298, 0x1298,
- 0x1298, 0x13f5, 0x13fe, 0x140d, 0x1451, 0x145b, 0x1462, 0x14a8,
- 0x14b7, 0x14c6, 0x14d8, 0x1548, 0x1558, 0x1298, 0x1298, 0x1298,
- 0x1298, 0x155d, 0xa0bc, 0xffa0, 0x00c0, 0x1298, 0x2038, 0xa084,
- 0x001f, 0x0079, 0x125b, 0x17a4, 0x17a7, 0x17b7, 0x1298, 0x1298,
- 0x1931, 0x194e, 0x1298, 0x1298, 0x1298, 0x1952, 0x195a, 0x1298,
- 0x1298, 0x1298, 0x1298, 0x12db, 0x12f4, 0x131f, 0x135b, 0x1686,
- 0x1782, 0x1796, 0x1298, 0x1847, 0x1960, 0x190d, 0x1917, 0x191b,
- 0x1929, 0x1298, 0x1298, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078,
- 0x1286, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068,
- 0x1287, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x00e0,
- 0x128f, 0x00e0, 0x1291, 0x0068, 0x1291, 0x2091, 0x4080, 0x007c,
- 0x70c3, 0x4001, 0x0078, 0x1287, 0x70c3, 0x4006, 0x0078, 0x1287,
- 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078,
- 0x1284, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x1284, 0x0078,
- 0x1284, 0x0078, 0x1284, 0x0078, 0x1284, 0x2091, 0x8000, 0x70c3,
- 0x0000, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3,
- 0x0007, 0x3f00, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001, 0x2031,
- 0x0030, 0x2059, 0x1000, 0x2029, 0x0457, 0x2051, 0x0470, 0x2061,
- 0x0472, 0x20b9, 0xffff, 0x20c1, 0x0000, 0x2091, 0x5000, 0x2091,
- 0x4080, 0x0078, 0x0455, 0x1078, 0x1bc4, 0x00c0, 0x129c, 0x75d8,
- 0x74dc, 0x75da, 0x74de, 0x0078, 0x12e8, 0x2029, 0x0000, 0x2520,
- 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1afe, 0x0040, 0x1284,
- 0x70c3, 0x4002, 0x0078, 0x1284, 0x1078, 0x1bc4, 0x00c0, 0x129c,
- 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1301, 0x2029, 0x0000,
- 0x2520, 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1b5e, 0x0040,
- 0x1284, 0x70c3, 0x4002, 0x0078, 0x1284, 0x71c4, 0x70c8, 0x2114,
- 0x200a, 0x0078, 0x1282, 0x71c4, 0x2114, 0x0078, 0x1282, 0x70c7,
- 0x0007, 0x70cb, 0x0041, 0x70cf, 0x0006, 0x0078, 0x1284, 0x1078,
- 0x1bc4, 0x00c0, 0x129c, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078,
- 0x132c, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0,
- 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x1355, 0xa40a,
- 0x0040, 0x133c, 0x00c8, 0x1346, 0x8001, 0x7892, 0xa084, 0xfc00,
- 0x0040, 0x134a, 0x78cc, 0xa085, 0x0001, 0x78ce, 0x2001, 0x4005,
- 0x0078, 0x1286, 0x7a9a, 0x7b9e, 0x7da2, 0x7ea6, 0x7c96, 0x78cc,
- 0xa084, 0xfffc, 0x78ce, 0x0078, 0x1359, 0x78cc, 0xa085, 0x0001,
- 0x78ce, 0x0078, 0x1284, 0x1078, 0x1bc4, 0x00c0, 0x129c, 0x75d8,
- 0x76dc, 0x75da, 0x76de, 0x0078, 0x1368, 0x2029, 0x0000, 0x2530,
- 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6,
- 0xa005, 0x0040, 0x1391, 0xa40a, 0x0040, 0x1378, 0x00c8, 0x1382,
- 0x8001, 0x78ae, 0xa084, 0xfc00, 0x0040, 0x1386, 0x78cc, 0xa085,
- 0x0100, 0x78ce, 0x2001, 0x4005, 0x0078, 0x1286, 0x7ab6, 0x7bba,
- 0x7dbe, 0x7ec2, 0x7cb2, 0x78cc, 0xa084, 0xfcff, 0x78ce, 0x0078,
- 0x1395, 0x78cc, 0xa085, 0x0100, 0x78ce, 0x0078, 0x1284, 0x2009,
- 0x5261, 0x210c, 0x7aec, 0x0078, 0x1282, 0x2009, 0x5241, 0x210c,
- 0x0078, 0x1283, 0x2009, 0x5242, 0x210c, 0x0078, 0x1283, 0x2061,
- 0x5240, 0x610c, 0x6210, 0x0078, 0x1282, 0x2009, 0x5245, 0x210c,
- 0x0078, 0x1283, 0x2009, 0x5246, 0x210c, 0x0078, 0x1283, 0x2009,
- 0x5248, 0x210c, 0x0078, 0x1283, 0x2009, 0x5249, 0x210c, 0x0078,
- 0x1283, 0x7908, 0x7a0c, 0x0078, 0x1282, 0x71c4, 0x8107, 0xa084,
- 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8, 0x5480, 0x6a00, 0x6804,
- 0xa084, 0x0008, 0x0040, 0x13d7, 0x6b08, 0x0078, 0x13d8, 0x6b0c,
- 0x0078, 0x1281, 0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6b1c,
- 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x1281, 0x794c, 0x0078,
- 0x1283, 0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6908, 0x6a18,
- 0x6b10, 0x2091, 0x8001, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010,
- 0x00c8, 0x127c, 0x1078, 0x237f, 0x0078, 0x1281, 0x71c4, 0xa182,
- 0x0010, 0x00c8, 0x127c, 0x2011, 0x5241, 0x2204, 0x007e, 0x2112,
- 0x1078, 0x2338, 0x017f, 0x0078, 0x1283, 0x71c4, 0x2019, 0x0100,
- 0x2304, 0xa082, 0x0006, 0x0048, 0x141b, 0x2011, 0x1449, 0x20a9,
- 0x0008, 0x0078, 0x141f, 0x2011, 0x1441, 0x20a9, 0x0008, 0x2204,
- 0xa106, 0x0040, 0x142a, 0x8210, 0x0070, 0x1428, 0x0078, 0x141f,
- 0x0078, 0x127c, 0x2304, 0xa082, 0x0006, 0x0048, 0x1433, 0xa292,
- 0x1449, 0x0078, 0x1435, 0xa292, 0x1441, 0x027e, 0x2011, 0x5242,
- 0x2204, 0x2112, 0x017f, 0x007e, 0x1078, 0x2344, 0x017f, 0x0078,
- 0x1283, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032,
- 0x004b, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0004, 0x0001, 0x0002,
- 0x0003, 0x2061, 0x5240, 0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8,
- 0x6012, 0x0078, 0x1282, 0x2061, 0x5240, 0x6114, 0x70c4, 0x6016,
- 0x0078, 0x1283, 0x2061, 0x5240, 0x71c4, 0x2011, 0x0004, 0x601f,
- 0x0019, 0x2019, 0x1212, 0xa186, 0x0028, 0x0040, 0x1483, 0x2011,
- 0x0005, 0x601f, 0x0019, 0x2019, 0x1212, 0xa186, 0x0032, 0x0040,
- 0x1483, 0x2011, 0x0006, 0x601f, 0x000c, 0x2019, 0x2222, 0xa186,
- 0x003c, 0x00c0, 0x127c, 0x6018, 0x007e, 0x611a, 0x7800, 0xa084,
- 0x0001, 0x00c0, 0x149e, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
- 0x0048, 0x1496, 0x0038, 0x149a, 0x0078, 0x149e, 0x0028, 0x149a,
- 0x0078, 0x149e, 0x2019, 0x2222, 0x0078, 0x14a0, 0x2019, 0x1212,
- 0x23b8, 0x1078, 0x2355, 0x1078, 0x4e33, 0x017f, 0x0078, 0x1283,
- 0x71c4, 0xa184, 0xffcf, 0x00c0, 0x127c, 0x2011, 0x5248, 0x2204,
- 0x2112, 0x007e, 0x1078, 0x2377, 0x017f, 0x0078, 0x1283, 0x71c4,
- 0xa182, 0x0010, 0x00c8, 0x127c, 0x2011, 0x5249, 0x2204, 0x007e,
- 0x2112, 0x1078, 0x2366, 0x017f, 0x0078, 0x1283, 0x71c4, 0x72c8,
- 0xa184, 0xfffd, 0x00c0, 0x127b, 0xa284, 0xfffd, 0x00c0, 0x127b,
- 0x2100, 0x7908, 0x780a, 0x2200, 0x7a0c, 0x780e, 0x0078, 0x1282,
- 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
- 0x5480, 0x2019, 0x0000, 0x72c8, 0xd2bc, 0x0040, 0x14e9, 0xa39d,
- 0x0010, 0xd2b4, 0x0040, 0x14ee, 0xa39d, 0x0008, 0x6800, 0x007e,
- 0xa226, 0x0040, 0x1511, 0x6a02, 0xa484, 0x2000, 0x0040, 0x14fa,
- 0xa39d, 0x0010, 0xa484, 0x1000, 0x0040, 0x1500, 0xa39d, 0x0008,
- 0xa484, 0x4000, 0x0040, 0x1511, 0x810f, 0xa284, 0x4000, 0x0040,
- 0x150d, 0x1078, 0x2399, 0x0078, 0x1511, 0x1078, 0x238b, 0x0078,
- 0x1511, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1540, 0xa2a4, 0x00ff,
- 0x2061, 0x5240, 0x6118, 0xa186, 0x0028, 0x0040, 0x1527, 0xa186,
- 0x0032, 0x0040, 0x152d, 0xa186, 0x003c, 0x0040, 0x1533, 0xa482,
- 0x0064, 0x0048, 0x153d, 0x0078, 0x1537, 0xa482, 0x0050, 0x0048,
- 0x153d, 0x0078, 0x1537, 0xa482, 0x0043, 0x0048, 0x153d, 0x71c4,
- 0x71c6, 0x027f, 0x72ca, 0x0078, 0x127d, 0x6a0a, 0xa39d, 0x000a,
- 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x0078, 0x1281,
- 0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091,
- 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0078, 0x1281,
- 0x70c4, 0x794c, 0x784e, 0x0078, 0x1283, 0x71c4, 0x72c8, 0x73cc,
- 0xa182, 0x0010, 0x00c8, 0x127c, 0x1078, 0x23a7, 0x0078, 0x1281,
- 0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6a08, 0xa295, 0x0002,
- 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282, 0x77c4, 0x1078,
- 0x19c5, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, 0x6804,
- 0xa005, 0x0040, 0x1585, 0x1078, 0x226f, 0x2091, 0x8001, 0x2708,
- 0x0078, 0x1282, 0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6a08,
- 0xa295, 0x0004, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1599, 0x1078,
- 0x226f, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282, 0x77c4, 0x2041,
- 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
- 0x19d2, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, 0x1282, 0x77c4,
- 0x72c8, 0x73cc, 0x77c6, 0x72ca, 0x73ce, 0x1078, 0x1a52, 0x00c0,
- 0x15c7, 0x6818, 0xa005, 0x0040, 0x15c7, 0x2708, 0x1078, 0x23b7,
- 0x00c0, 0x15c7, 0x7817, 0x0015, 0x2091, 0x8001, 0x007c, 0x2091,
- 0x8001, 0x0078, 0x1284, 0x77c4, 0x77c6, 0x2041, 0x0021, 0x2049,
- 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, 0x19d2, 0x2061,
- 0x5240, 0x606f, 0x0003, 0x6782, 0x6093, 0x000f, 0x6073, 0x0000,
- 0x7817, 0x0016, 0x1078, 0x226f, 0x2091, 0x8001, 0x007c, 0x77c8,
- 0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2061,
- 0x5240, 0x606f, 0x0002, 0x6073, 0x0000, 0x6782, 0x6093, 0x000f,
- 0x7817, 0x0017, 0x1078, 0x226f, 0x2091, 0x8001, 0x2041, 0x0021,
- 0x2049, 0x0004, 0x2051, 0x0010, 0x2091, 0x8000, 0x1078, 0x19d2,
- 0x70c8, 0x6836, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1606, 0x2091,
- 0x8001, 0x007c, 0x78cc, 0xa084, 0x0003, 0x00c0, 0x1636, 0x2039,
- 0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x1078,
- 0x19c5, 0x2091, 0x8000, 0x6808, 0xa80d, 0x690a, 0x2091, 0x8001,
- 0x8738, 0xa784, 0x001f, 0x00c0, 0x161f, 0xa7bc, 0xff00, 0x873f,
- 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x161f, 0x2091, 0x8000,
- 0x2069, 0x0100, 0x6830, 0xa084, 0x0040, 0x0040, 0x165f, 0x684b,
- 0x0004, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0004, 0x0040, 0x164c,
- 0x0070, 0x164c, 0x0078, 0x1643, 0x684b, 0x0009, 0x20a9, 0x0014,
- 0x6848, 0xa084, 0x0001, 0x0040, 0x1659, 0x0070, 0x1659, 0x0078,
- 0x1650, 0x20a9, 0x00fa, 0x0070, 0x165f, 0x0078, 0x165b, 0x2079,
- 0x5200, 0x7817, 0x0018, 0x2061, 0x5240, 0x606f, 0x0001, 0x6073,
- 0x0000, 0x6093, 0x000f, 0x78cc, 0xa085, 0x0002, 0x78ce, 0x6808,
- 0xa084, 0xfffd, 0x680a, 0x681b, 0x0048, 0x2091, 0x8001, 0x007c,
- 0x78cc, 0xa084, 0xfffd, 0x78ce, 0xa084, 0x0001, 0x00c0, 0x1682,
- 0x1078, 0x1a9c, 0x71c4, 0x71c6, 0x794a, 0x007c, 0x1078, 0x1bc4,
- 0x00c0, 0x129c, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1693,
- 0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca,
- 0x72ce, 0x2079, 0x5200, 0x2091, 0x8000, 0x1078, 0x1980, 0x2091,
- 0x8001, 0x0040, 0x174a, 0x20a9, 0x0005, 0x20a1, 0x5218, 0x2091,
- 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0020, 0x1078, 0x197b,
- 0x0040, 0x16b6, 0x1078, 0x199a, 0x0078, 0x174a, 0x6004, 0xa084,
- 0xff00, 0x8007, 0x8009, 0x0040, 0x1719, 0x0c7e, 0x2c68, 0x2091,
- 0x8000, 0x1078, 0x1980, 0x2091, 0x8001, 0x0040, 0x16ea, 0x2c00,
- 0x689e, 0x8109, 0x00c0, 0x16be, 0x609f, 0x0000, 0x0c7f, 0x0c7e,
- 0x7218, 0x731c, 0x7420, 0x7524, 0x2c68, 0x689c, 0xa065, 0x0040,
- 0x1718, 0x2009, 0x0020, 0x1078, 0x197b, 0x00c0, 0x1701, 0x6004,
- 0xa084, 0x00ff, 0xa086, 0x0002, 0x00c0, 0x16ea, 0x2d00, 0x6002,
- 0x0078, 0x16d0, 0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x1a17,
- 0x0c7f, 0x609f, 0x0000, 0x1078, 0x174e, 0x2009, 0x000c, 0x6008,
- 0xa085, 0x0200, 0x600a, 0x1078, 0x1976, 0x1078, 0x199a, 0x0078,
- 0x174a, 0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x1a17, 0x0c7f,
- 0x609f, 0x0000, 0x1078, 0x174e, 0x2009, 0x000c, 0x6007, 0x0103,
- 0x601b, 0x0003, 0x1078, 0x1976, 0x1078, 0x199a, 0x0078, 0x174a,
- 0x0c7f, 0x74c4, 0x73c8, 0x72cc, 0x6014, 0x2091, 0x8000, 0x7817,
- 0x0012, 0x0e7e, 0x2071, 0x5240, 0x706f, 0x0005, 0x7073, 0x0000,
- 0x7376, 0x727a, 0x747e, 0x7082, 0x7087, 0x0000, 0x2c00, 0x708a,
- 0x708f, 0x0000, 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184, 0x0060,
- 0x0040, 0x173c, 0x1078, 0x48d3, 0x0e7f, 0x6596, 0x65a6, 0x669a,
- 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x1078, 0x226f, 0x2091,
- 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1287, 0x20a9, 0x0005,
- 0x2099, 0x5218, 0x2091, 0x8000, 0x530a, 0x2091, 0x8001, 0x2100,
- 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c,
- 0x71c4, 0x70c7, 0x0000, 0x7906, 0x0078, 0x1284, 0x71c4, 0x71c6,
- 0x2168, 0x0078, 0x176d, 0x2069, 0x1000, 0x690c, 0xa016, 0x2d04,
- 0xa210, 0x8d68, 0x8109, 0x00c0, 0x176f, 0xa285, 0x0000, 0x00c0,
- 0x177d, 0x70c3, 0x4000, 0x0078, 0x177f, 0x70c3, 0x4003, 0x70ca,
- 0x0078, 0x1287, 0x2011, 0x5267, 0x220c, 0x70c4, 0x8003, 0x0048,
- 0x178f, 0x1078, 0x3c51, 0xa184, 0x7fff, 0x0078, 0x1793, 0x1078,
- 0x3c44, 0xa185, 0x8000, 0x2012, 0x0078, 0x1283, 0x71c4, 0x1078,
- 0x3c3b, 0x6100, 0x2001, 0x5267, 0x2004, 0xa084, 0x8000, 0xa10d,
- 0x6204, 0x6308, 0x0078, 0x1281, 0x79e4, 0x0078, 0x1283, 0x71c4,
- 0x71c6, 0x2198, 0x20a1, 0x0042, 0x20a9, 0x0004, 0x53a3, 0x21a0,
- 0x2099, 0x0042, 0x20a9, 0x0004, 0x53a3, 0x0078, 0x1284, 0x70c4,
- 0x2068, 0x2079, 0x5200, 0x2091, 0x8000, 0x1078, 0x1980, 0x2091,
- 0x8001, 0x0040, 0x1843, 0x6007, 0x0001, 0x600b, 0x0000, 0x602b,
- 0x0000, 0x601b, 0x0006, 0x6a10, 0xa28c, 0x000f, 0xa284, 0x00f0,
- 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x6016, 0xa284, 0x0800,
- 0x0040, 0x17de, 0x601b, 0x000a, 0x0078, 0x17e4, 0xa284, 0x1000,
- 0x0040, 0x17e4, 0x601b, 0x000c, 0xa284, 0x0300, 0x0040, 0x17ed,
- 0x602b, 0x0001, 0x8004, 0x8004, 0x8004, 0xa085, 0x0001, 0x601e,
- 0x6023, 0x0000, 0x6027, 0x0000, 0xa284, 0x0400, 0x0040, 0x17fa,
- 0x602b, 0x0000, 0x20a9, 0x0006, 0xac80, 0x000b, 0x20a0, 0xad80,
- 0x0005, 0x2098, 0x53a3, 0xa284, 0x0300, 0x00c0, 0x180f, 0x6046,
- 0x604a, 0x604e, 0x6052, 0x6096, 0x609a, 0x0078, 0x1819, 0x6800,
- 0x6046, 0x6804, 0x604a, 0x6e08, 0x664e, 0x6d0c, 0x6552, 0x6596,
- 0x669a, 0x6014, 0x2091, 0x8000, 0x7817, 0x0042, 0x2c08, 0x2061,
- 0x5240, 0x606f, 0x0005, 0x6073, 0x0000, 0x6077, 0x0000, 0x607b,
- 0x0000, 0x607f, 0x0000, 0x6082, 0x618a, 0xa284, 0x0400, 0x608e,
- 0x2091, 0x8001, 0x0e7e, 0x2071, 0x0020, 0x7007, 0x000a, 0x7007,
- 0x0002, 0x7003, 0x0000, 0x0e7f, 0x2091, 0x8000, 0x1078, 0x226f,
- 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1287, 0x0c7e,
- 0x0d7e, 0x0e7e, 0x0f7e, 0x2091, 0x8000, 0x2071, 0x5240, 0x2079,
- 0x0100, 0x2061, 0x0010, 0x70a0, 0xa06d, 0x0040, 0x1903, 0x6a04,
- 0xa294, 0x00ff, 0xa286, 0x0007, 0x0040, 0x1862, 0xa286, 0x000f,
- 0x00c0, 0x1903, 0x691c, 0xa184, 0x00c0, 0x0040, 0x1903, 0xa184,
- 0x0080, 0x00c0, 0x18d3, 0x6824, 0xa084, 0xff00, 0xa085, 0x0019,
- 0x6826, 0x71b0, 0x81ff, 0x0040, 0x1889, 0x0d7e, 0x2069, 0x0020,
- 0x6807, 0x0010, 0x6908, 0x6808, 0xa106, 0x00c0, 0x187a, 0x690c,
- 0x680c, 0xa106, 0x00c0, 0x187f, 0xa184, 0x00ff, 0x00c0, 0x187f,
- 0x0d7f, 0x78b8, 0xa084, 0x801f, 0x00c0, 0x1889, 0x7848, 0xa085,
- 0x000c, 0x784a, 0x71b0, 0x81ff, 0x0040, 0x18ac, 0x70b3, 0x0000,
- 0x0d7e, 0x2069, 0x0020, 0x6807, 0x0018, 0x6804, 0xa084, 0x0008,
- 0x00c0, 0x189d, 0x6807, 0x0008, 0x6804, 0xa084, 0x0008, 0x00c0,
- 0x18a4, 0x6807, 0x0002, 0x0d7f, 0x61c4, 0x62c8, 0x63cc, 0x61c6,
- 0x62ca, 0x63ce, 0x0e7e, 0x2071, 0x5200, 0x7266, 0x736a, 0xae80,
- 0x0019, 0x0e7f, 0x7848, 0xa084, 0x000c, 0x00c0, 0x18ba, 0x1078,
- 0x47e1, 0x78a3, 0x0000, 0x7858, 0xa084, 0xedff, 0x785a, 0x70b4,
- 0xa080, 0x00da, 0x781a, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091,
- 0x8001, 0x0078, 0x1284, 0x6824, 0xa084, 0xff00, 0xa085, 0x0019,
- 0x6826, 0x78b8, 0xa084, 0x801f, 0x00c0, 0x18d9, 0x7848, 0xa085,
- 0x000c, 0x784a, 0x7848, 0xa084, 0x000c, 0x00c0, 0x18e2, 0x71b0,
- 0x81ff, 0x0040, 0x1901, 0x70b3, 0x0000, 0x0d7e, 0x2069, 0x0020,
- 0x6807, 0x0018, 0x6804, 0xa084, 0x0008, 0x00c0, 0x18f2, 0x6807,
- 0x0008, 0x6804, 0xa084, 0x0008, 0x00c0, 0x18f9, 0x6807, 0x0002,
- 0x0d7f, 0x0078, 0x18cb, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091,
- 0x8001, 0x2001, 0x4005, 0x0078, 0x1286, 0x7980, 0x71c6, 0x71c4,
- 0xa182, 0x0003, 0x00c8, 0x127c, 0x7982, 0x0078, 0x1284, 0x7980,
- 0x71c6, 0x0078, 0x1284, 0x7974, 0x71c6, 0x71c4, 0x7976, 0x7978,
- 0x71ca, 0x71c8, 0x797a, 0x797c, 0x71ce, 0x71cc, 0x797e, 0x0078,
- 0x1284, 0x7974, 0x71c6, 0x7978, 0x71ca, 0x797c, 0x71ce, 0x0078,
- 0x1284, 0x7900, 0x71c6, 0x71c4, 0x7902, 0x2001, 0x04fd, 0x2004,
- 0xa082, 0x0005, 0x0048, 0x1940, 0x0038, 0x1942, 0x0078, 0x194c,
- 0x00a8, 0x194c, 0xa18c, 0x0001, 0x00c0, 0x194a, 0x20b9, 0x2222,
- 0x0078, 0x194c, 0x20b9, 0x1212, 0x0078, 0x1284, 0x7900, 0x71c6,
- 0x0078, 0x1284, 0x2009, 0x5274, 0x2104, 0x70c6, 0x70c4, 0x200a,
- 0x0078, 0x1284, 0x2009, 0x5274, 0x2104, 0x70c6, 0x0078, 0x1284,
- 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
- 0x5480, 0x6a14, 0xd2b4, 0x0040, 0x1971, 0x2011, 0x0001, 0x0078,
- 0x1973, 0x2011, 0x0000, 0x6b0c, 0x0078, 0x1281, 0xac80, 0x0001,
- 0x1078, 0x1b80, 0x007c, 0xac80, 0x0001, 0x1078, 0x1b20, 0x007c,
- 0x7850, 0xa065, 0x0040, 0x1988, 0x2c04, 0x7852, 0x2063, 0x0000,
- 0x007c, 0x0f7e, 0x2079, 0x5200, 0x7850, 0xa06d, 0x0040, 0x1998,
- 0x2d04, 0x7852, 0x6803, 0x0000, 0x6807, 0x0000, 0x680b, 0x0000,
- 0x0f7f, 0x007c, 0x2091, 0x8000, 0x0f7e, 0x2079, 0x5200, 0x7850,
- 0x2062, 0x2c00, 0xa005, 0x00c0, 0x19a7, 0x1078, 0x248c, 0x7852,
- 0x0f7f, 0x2091, 0x8001, 0x007c, 0x0f7e, 0x2079, 0x5200, 0x7850,
- 0x206a, 0x2d00, 0x7852, 0x0f7f, 0x007c, 0x2011, 0x7900, 0x7a52,
- 0x7bec, 0x8319, 0x0040, 0x19c2, 0xa280, 0x0031, 0x2012, 0x2010,
- 0x0078, 0x19b9, 0x2013, 0x0000, 0x007c, 0xa784, 0x0f00, 0x800b,
- 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e8,
- 0x5500, 0x007c, 0x1078, 0x19c5, 0x2900, 0x682a, 0x2a00, 0x682e,
- 0x6808, 0xa084, 0xffef, 0xa80d, 0x690a, 0x2009, 0x5252, 0x210c,
- 0x6804, 0xa005, 0x0040, 0x1a04, 0xa116, 0x00c0, 0x19ef, 0x2060,
- 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x19f2, 0x2009,
- 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1a01, 0x6000, 0x6806,
- 0x1078, 0x1a31, 0x1078, 0x1ccb, 0x6810, 0x8001, 0x6812, 0x00c0,
- 0x19f2, 0x017f, 0x6902, 0x6906, 0x007c, 0xa065, 0x0040, 0x1a16,
- 0x2008, 0x609c, 0xa005, 0x0040, 0x1a13, 0x2062, 0x609f, 0x0000,
- 0xa065, 0x0078, 0x1a09, 0x7850, 0x7952, 0x2062, 0x007c, 0xa065,
- 0x0040, 0x1a30, 0x2008, 0x609c, 0xa005, 0x0040, 0x1a25, 0x2062,
- 0x609f, 0x0000, 0xa065, 0x0078, 0x1a1b, 0x0f7e, 0x2079, 0x5200,
- 0x2091, 0x8000, 0x7850, 0x7952, 0x0f7f, 0x2062, 0x2091, 0x8001,
- 0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c, 0xac80,
- 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a, 0x682c,
- 0x6022, 0x007c, 0x0e7e, 0x2071, 0x5240, 0x704c, 0xa08c, 0x0200,
- 0x00c0, 0x1a50, 0xa088, 0x5280, 0x2d0a, 0x8000, 0x704e, 0xa006,
- 0x0e7f, 0x007c, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6804, 0x781e,
- 0xa065, 0x0040, 0x1a9b, 0x0078, 0x1a63, 0x2c00, 0x781e, 0x6000,
- 0xa065, 0x0040, 0x1a9b, 0x600c, 0xa306, 0x00c0, 0x1a5d, 0x6010,
- 0xa206, 0x00c0, 0x1a5d, 0x2c28, 0x2001, 0x5252, 0x2004, 0xac06,
- 0x00c0, 0x1a74, 0x0078, 0x1a99, 0x6804, 0xac06, 0x00c0, 0x1a81,
- 0x6000, 0xa065, 0x6806, 0x00c0, 0x1a8b, 0x6803, 0x0000, 0x0078,
- 0x1a8b, 0x6400, 0x781c, 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0,
- 0x1a8b, 0x2c00, 0x6802, 0x2560, 0x1078, 0x1a31, 0x601b, 0x0005,
- 0x6023, 0x0020, 0x1078, 0x1ccb, 0x6810, 0x8001, 0x1050, 0x248c,
- 0x6812, 0xa085, 0xffff, 0x007c, 0x2039, 0x0000, 0x2041, 0x0021,
- 0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x19d2,
- 0x8738, 0xa784, 0x001f, 0x00c0, 0x1aa6, 0xa7bc, 0xff00, 0x873f,
- 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1aa6, 0x2091, 0x8001,
- 0x007c, 0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1aca,
- 0x2091, 0x8000, 0x78e0, 0x78e3, 0x0000, 0x2091, 0x8001, 0xa005,
- 0x00c0, 0x1acb, 0x007c, 0xa08c, 0xfff0, 0x0040, 0x1ad1, 0x1078,
- 0x248c, 0x0079, 0x1ad3, 0x1ae3, 0x1ae6, 0x1aec, 0x1af0, 0x1ae4,
- 0x1af4, 0x1afa, 0x1ae4, 0x1ae4, 0x1c95, 0x1cb9, 0x1cbd, 0x1ae4,
- 0x1ae4, 0x1ae4, 0x1ae4, 0x007c, 0x1078, 0x248c, 0x1078, 0x1a9c,
- 0x2001, 0x8001, 0x0078, 0x1cc3, 0x2001, 0x8003, 0x0078, 0x1cc3,
- 0x2001, 0x8004, 0x0078, 0x1cc3, 0x1078, 0x1a9c, 0x2001, 0x8006,
- 0x0078, 0x1cc3, 0x2001, 0x8007, 0x0078, 0x1cc3, 0x2030, 0x2138,
- 0xa782, 0x0021, 0x0048, 0x1b06, 0x2009, 0x0020, 0x2600, 0x1078,
- 0x1b20, 0x00c0, 0x1b1f, 0xa7ba, 0x0020, 0x0048, 0x1b1e, 0x0040,
- 0x1b1e, 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399, 0x0000,
- 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1b00, 0xa006, 0x007c,
- 0x81ff, 0x0040, 0x1b5b, 0x2099, 0x0030, 0x20a0, 0x700c, 0xa084,
- 0x00ff, 0x0040, 0x1b32, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004,
- 0x00c0, 0x1b2d, 0x21a8, 0x7017, 0x0000, 0x810b, 0x7112, 0x721a,
- 0x731e, 0x7422, 0x7526, 0x780c, 0xa085, 0x0001, 0x7002, 0x7007,
- 0x0001, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x1b4f,
- 0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x1b41, 0x7008,
- 0x800b, 0x00c8, 0x1b41, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0,
- 0x1b5b, 0x53a5, 0xa006, 0x7003, 0x0000, 0x007c, 0x2030, 0x2138,
- 0xa782, 0x0021, 0x0048, 0x1b66, 0x2009, 0x0020, 0x2600, 0x1078,
- 0x1b80, 0x00c0, 0x1b7f, 0xa7ba, 0x0020, 0x0048, 0x1b7e, 0x0040,
- 0x1b7e, 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399, 0x0000,
- 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1b60, 0xa006, 0x007c,
- 0x81ff, 0x0040, 0x1bc1, 0x2098, 0x20a1, 0x0030, 0x700c, 0xa084,
- 0x00ff, 0x0040, 0x1b92, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004,
- 0x00c0, 0x1b8d, 0x21a8, 0x7017, 0x0000, 0x810b, 0x7112, 0x721a,
- 0x731e, 0x7422, 0x7526, 0x780c, 0xa085, 0x0000, 0x7002, 0x53a6,
- 0x7007, 0x0001, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8,
- 0x1bb0, 0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x1ba2,
- 0x7010, 0xa084, 0xf000, 0x0040, 0x1bb9, 0x7007, 0x0008, 0x0078,
- 0x1bbd, 0x7108, 0x8103, 0x00c8, 0x1ba2, 0x7007, 0x0002, 0xa184,
- 0x01e0, 0x7003, 0x0000, 0x007c, 0x2001, 0x04fd, 0x2004, 0xa082,
- 0x0004, 0x00c8, 0x1bcd, 0x0078, 0x1bd0, 0xa006, 0x0078, 0x1bd2,
- 0xa085, 0x0001, 0x007c, 0x0e7e, 0x2071, 0x5200, 0x2d08, 0x7058,
- 0x6802, 0xa005, 0x00c0, 0x1bdd, 0x715e, 0x715a, 0x0e7f, 0x007c,
- 0x2c08, 0x7858, 0x6002, 0xa005, 0x00c0, 0x1be7, 0x795e, 0x795a,
- 0x007c, 0x2091, 0x8000, 0x6114, 0x1078, 0x2180, 0x6900, 0xa184,
- 0x0100, 0x00c0, 0x2035, 0xa184, 0x0200, 0x00c0, 0x2031, 0x681c,
- 0xa005, 0x00c0, 0x203d, 0x6003, 0x0000, 0x2c08, 0x785c, 0xa065,
- 0x00c0, 0x1c05, 0x795a, 0x0078, 0x1c06, 0x6102, 0x795e, 0x2091,
- 0x8001, 0x1078, 0x228c, 0x007c, 0x0e7e, 0x2071, 0x5200, 0x7058,
- 0xa06d, 0x0040, 0x1c1a, 0x6800, 0x705a, 0xa005, 0x00c0, 0x1c19,
- 0x705e, 0x8dff, 0x0e7f, 0x007c, 0x0d7e, 0x0c7e, 0x0f7e, 0x2079,
- 0x5200, 0xaf80, 0x0016, 0x2060, 0x6000, 0xa005, 0x0040, 0x1c43,
- 0x2068, 0x6814, 0xa306, 0x00c0, 0x1c33, 0x6828, 0xa084, 0x00ff,
- 0xa406, 0x0040, 0x1c36, 0x2d60, 0x0078, 0x1c24, 0x6800, 0xa005,
- 0x6002, 0x00c0, 0x1c42, 0xaf80, 0x0016, 0xac06, 0x0040, 0x1c41,
- 0x2c00, 0x785e, 0x2d00, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c,
- 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5200, 0xaf80, 0x0016, 0x2060,
- 0x6000, 0xa005, 0x0040, 0x1c6b, 0x2068, 0x6814, 0xa084, 0x00ff,
- 0xa306, 0x0040, 0x1c5e, 0x2d60, 0x0078, 0x1c50, 0x6800, 0xa005,
- 0x6002, 0x00c0, 0x1c6a, 0xaf80, 0x0016, 0xac06, 0x0040, 0x1c69,
- 0x2c00, 0x785e, 0x2d00, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c,
- 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5200, 0xaf80, 0x0016, 0x2060,
- 0x6000, 0xa06d, 0x0040, 0x1c90, 0x6814, 0xa306, 0x0040, 0x1c83,
- 0x2d60, 0x0078, 0x1c78, 0x6800, 0xa005, 0x6002, 0x00c0, 0x1c8f,
- 0xaf80, 0x0016, 0xac06, 0x0040, 0x1c8e, 0x2c00, 0x785e, 0x2d00,
- 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x2091, 0x8000, 0x2069,
- 0x5240, 0x6800, 0xa086, 0x0000, 0x0040, 0x1ca3, 0x2091, 0x8001,
- 0x78e3, 0x0009, 0x007c, 0x6880, 0xa0bc, 0xff00, 0x2041, 0x0021,
- 0x2049, 0x0004, 0x2051, 0x0010, 0x1078, 0x19d2, 0x8738, 0xa784,
- 0x001f, 0x00c0, 0x1cac, 0x2091, 0x8001, 0x2001, 0x800a, 0x0078,
- 0x1cc3, 0x2001, 0x800c, 0x0078, 0x1cc3, 0x1078, 0x1a9c, 0x2001,
- 0x800d, 0x0078, 0x1cc3, 0x70c2, 0x2061, 0x0000, 0x601b, 0x0001,
- 0x2091, 0x4080, 0x007c, 0x6004, 0x2c08, 0x2063, 0x0000, 0x7884,
- 0x8000, 0x7886, 0x7888, 0xa005, 0x798a, 0x0040, 0x1cda, 0x2c02,
- 0x0078, 0x1cdb, 0x798e, 0x007c, 0x6807, 0x0103, 0x0c7e, 0x2061,
- 0x5200, 0x2d08, 0x206b, 0x0000, 0x6084, 0x8000, 0x6086, 0x6088,
- 0xa005, 0x618a, 0x0040, 0x1cef, 0x2d02, 0x0078, 0x1cf0, 0x618e,
- 0x0c7f, 0x007c, 0x1078, 0x1d03, 0x0040, 0x1d02, 0x0c7e, 0x609c,
- 0xa065, 0x0040, 0x1cfd, 0x1078, 0x1a17, 0x0c7f, 0x609f, 0x0000,
- 0x1078, 0x199a, 0x007c, 0x788c, 0xa065, 0x0040, 0x1d15, 0x2091,
- 0x8000, 0x7884, 0x8001, 0x7886, 0x2c04, 0x788e, 0xa005, 0x00c0,
- 0x1d13, 0x788a, 0x8000, 0x2091, 0x8001, 0x007c, 0x20a9, 0x0010,
- 0xa006, 0x8004, 0x8086, 0x818e, 0x00c8, 0x1d1f, 0xa200, 0x0070,
- 0x1d23, 0x0078, 0x1d1a, 0x8086, 0x818e, 0x007c, 0x157e, 0x20a9,
- 0x0010, 0xa005, 0x0040, 0x1d49, 0xa11a, 0x00c8, 0x1d49, 0x8213,
- 0x818d, 0x0048, 0x1d3a, 0xa11a, 0x00c8, 0x1d3b, 0x0070, 0x1d41,
- 0x0078, 0x1d2f, 0xa11a, 0x2308, 0x8210, 0x0070, 0x1d41, 0x0078,
- 0x1d2f, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f,
- 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x1d45, 0x7994,
- 0x70d0, 0xa106, 0x0040, 0x1dbd, 0x2091, 0x8000, 0x2071, 0x0020,
- 0x7004, 0xa005, 0x00c0, 0x1dbd, 0x7008, 0x7208, 0xa206, 0x00c0,
- 0x1dbd, 0xa286, 0x0008, 0x00c0, 0x1dbd, 0x2071, 0x0010, 0x1078,
- 0x1980, 0x0040, 0x1dbd, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa184,
- 0xff00, 0x0040, 0x1d8b, 0x2031, 0x0000, 0x810b, 0x86b5, 0x810b,
- 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b,
- 0x86b5, 0x2100, 0xa210, 0x2600, 0xa319, 0xa4a1, 0x0000, 0xa5a9,
- 0x0000, 0x0078, 0x1d95, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399,
- 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x2009, 0x0020, 0x1078,
- 0x197b, 0x2091, 0x8001, 0x0040, 0x1db4, 0x1078, 0x199a, 0x78a8,
- 0x8000, 0x78aa, 0xa086, 0x0002, 0x00c0, 0x1dbd, 0x2091, 0x8000,
- 0x78e3, 0x0002, 0x78ab, 0x0000, 0x78cc, 0xa085, 0x0003, 0x78ce,
- 0x2091, 0x8001, 0x0078, 0x1dbd, 0x78ab, 0x0000, 0x1078, 0x2149,
- 0x6004, 0xa084, 0x000f, 0x0079, 0x1dc2, 0x2071, 0x0010, 0x2091,
- 0x8001, 0x007c, 0x1dd2, 0x1df4, 0x1e1a, 0x1dd2, 0x1e37, 0x1de1,
- 0x1fc9, 0x1fe4, 0x1dd2, 0x1dee, 0x1e14, 0x1e7f, 0x1eee, 0x1f57,
- 0x1f69, 0x1fe0, 0x2039, 0x0400, 0x78dc, 0xa705, 0x78de, 0x6008,
- 0xa705, 0x600a, 0x1078, 0x2064, 0x609c, 0x78da, 0x1078, 0x2131,
- 0x007c, 0x78dc, 0xa084, 0x0100, 0x0040, 0x1de8, 0x0078, 0x1dd2,
- 0x601c, 0xa085, 0x0080, 0x601e, 0x0078, 0x1dfb, 0x1078, 0x1bc4,
- 0x00c0, 0x1dd2, 0x1078, 0x2163, 0x78dc, 0xa084, 0x0100, 0x0040,
- 0x1dfb, 0x0078, 0x1dd2, 0x78df, 0x0000, 0x6004, 0x8007, 0xa084,
- 0x00ff, 0x78d2, 0x8001, 0x609f, 0x0000, 0x0040, 0x1e11, 0x1078,
- 0x2064, 0x0040, 0x1e11, 0x78dc, 0xa085, 0x0100, 0x78de, 0x0078,
- 0x1e13, 0x1078, 0x2088, 0x007c, 0x1078, 0x1bc4, 0x00c0, 0x1dd2,
- 0x1078, 0x215f, 0x78dc, 0xa08c, 0x0e00, 0x00c0, 0x1e23, 0xa084,
- 0x0100, 0x00c0, 0x1e25, 0x0078, 0x1dd2, 0x1078, 0x2064, 0x00c0,
- 0x1e36, 0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x2021,
- 0xa186, 0x000f, 0x0040, 0x2021, 0x1078, 0x2088, 0x007c, 0x78dc,
- 0xa084, 0x0100, 0x0040, 0x1e3e, 0x0078, 0x1dd2, 0x78df, 0x0000,
- 0x6714, 0x2011, 0x0001, 0x20a9, 0x0001, 0x6018, 0xa084, 0x00ff,
- 0xa005, 0x0040, 0x1e61, 0x2011, 0x0001, 0xa7bc, 0xff00, 0x20a9,
- 0x0020, 0xa08e, 0x0001, 0x0040, 0x1e61, 0x2039, 0x0000, 0x2011,
- 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0040, 0x1e61, 0x0078,
- 0x1e7c, 0x1078, 0x19c5, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f,
- 0x0000, 0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091,
- 0x8001, 0x0070, 0x1e75, 0x0078, 0x1e63, 0x8211, 0x0040, 0x1e7c,
- 0x20a9, 0x0100, 0x0078, 0x1e63, 0x1078, 0x199a, 0x007c, 0x2001,
- 0x5267, 0x2004, 0xa084, 0x8000, 0x0040, 0x2049, 0x6114, 0x1078,
- 0x2180, 0x6900, 0xa184, 0x0001, 0x0040, 0x1ea0, 0x6028, 0xa084,
- 0x00ff, 0x00c0, 0x2041, 0x6800, 0xa084, 0x0001, 0x0040, 0x2049,
- 0x6803, 0x0000, 0x680b, 0x0000, 0x6807, 0x0000, 0x0078, 0x2051,
- 0x2011, 0x0001, 0x6020, 0xd0f4, 0x0040, 0x1ea8, 0xa295, 0x0002,
- 0xd0c4, 0x0040, 0x1ead, 0xa295, 0x0008, 0xd0cc, 0x0040, 0x1eb2,
- 0xa295, 0x0400, 0x601c, 0xa084, 0x0002, 0x0040, 0x1eb9, 0xa295,
- 0x0004, 0x602c, 0xa08c, 0x00ff, 0xa182, 0x0002, 0x0048, 0x204d,
- 0xa182, 0x001b, 0x00c8, 0x204d, 0x0040, 0x204d, 0x690e, 0x602c,
- 0x8007, 0xa08c, 0x00ff, 0xa182, 0x0002, 0x0048, 0x204d, 0xa182,
- 0x001b, 0x00c8, 0x204d, 0x0040, 0x204d, 0x6912, 0x6030, 0xa005,
- 0x00c0, 0x1edc, 0x2001, 0x001e, 0x8000, 0x6816, 0x6028, 0xa084,
- 0x00ff, 0x0040, 0x2049, 0x6806, 0x6028, 0x8007, 0xa084, 0x00ff,
- 0x0040, 0x2049, 0x680a, 0x6a02, 0x0078, 0x2051, 0x2001, 0x5240,
- 0x2004, 0xa086, 0x0007, 0x00c0, 0x1f53, 0x2001, 0x5267, 0x2004,
- 0xa084, 0x8000, 0x0040, 0x2049, 0x6114, 0x1078, 0x2180, 0x2001,
- 0x5252, 0x2004, 0x2010, 0x82ff, 0x0040, 0x1f0e, 0xa080, 0x0005,
- 0x2004, 0xa084, 0x00ff, 0xa106, 0x00c0, 0x1f53, 0x2091, 0x8000,
- 0x6a04, 0x6b08, 0x6418, 0xa484, 0x0003, 0x0040, 0x1f2d, 0x6128,
- 0xa18c, 0x00ff, 0x8001, 0x00c0, 0x1f23, 0x2100, 0xa210, 0x0048,
- 0x1f53, 0x0078, 0x1f2d, 0x8001, 0x00c0, 0x1f53, 0x2100, 0xa212,
- 0x0048, 0x1f53, 0x82ff, 0x0040, 0x1f53, 0xa484, 0x000c, 0x0040,
- 0x1f47, 0x6128, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x00c0,
- 0x1f3f, 0x2100, 0xa318, 0x0048, 0x1f53, 0x0078, 0x1f47, 0xa082,
- 0x0004, 0x00c0, 0x1f53, 0x2100, 0xa31a, 0x0048, 0x1f53, 0x6030,
- 0xa005, 0x0040, 0x1f4d, 0x8000, 0x6816, 0x6a06, 0x6b0a, 0x2091,
- 0x8001, 0x0078, 0x2051, 0x2091, 0x8001, 0x0078, 0x204d, 0x6114,
- 0x1078, 0x2180, 0x2091, 0x8000, 0x6b08, 0x8318, 0x0048, 0x1f65,
- 0x6b0a, 0x2091, 0x8001, 0x0078, 0x2060, 0x2091, 0x8001, 0x0078,
- 0x204d, 0x6024, 0x8007, 0xa084, 0x00ff, 0x0040, 0x1f87, 0xa086,
- 0x0080, 0x00c0, 0x1fc7, 0x20a9, 0x0008, 0x2069, 0x7610, 0x2091,
- 0x8000, 0x6800, 0xa084, 0xfcff, 0x6802, 0xade8, 0x0008, 0x0070,
- 0x1f83, 0x0078, 0x1f79, 0x2091, 0x8001, 0x0078, 0x2051, 0x6028,
- 0xa015, 0x0040, 0x1fc7, 0x6114, 0x1078, 0x2180, 0x0c7e, 0x0d7e,
- 0xade8, 0x0007, 0x2091, 0x8000, 0x6800, 0xa00d, 0x0040, 0x1fc3,
- 0xa206, 0x0040, 0x1f9e, 0x2168, 0x0078, 0x1f94, 0x2160, 0x6000,
- 0x6802, 0x2c68, 0x1078, 0x19ac, 0x0d7f, 0x6818, 0xa00d, 0x0040,
- 0x1fbb, 0x2060, 0x6200, 0x6a1a, 0x6a1c, 0x6202, 0x681e, 0x1078,
- 0x1989, 0x2da0, 0x2198, 0x20a9, 0x0031, 0x53a3, 0x2d60, 0x1078,
- 0x1ccb, 0x0078, 0x1fbe, 0x6808, 0x8000, 0x680a, 0x2091, 0x8001,
- 0x0c7f, 0x0078, 0x2060, 0x2091, 0x8001, 0x0d7f, 0x0c7f, 0x0078,
- 0x2049, 0x6114, 0x1078, 0x2180, 0x6800, 0xa084, 0x0001, 0x0040,
- 0x2039, 0x2091, 0x8000, 0x6a04, 0x8210, 0x0048, 0x1fdc, 0x6a06,
- 0x2091, 0x8001, 0x0078, 0x2060, 0x2091, 0x8001, 0x0078, 0x204d,
- 0x1078, 0x1bc4, 0x00c0, 0x1dd2, 0x6114, 0x1078, 0x2180, 0x60be,
- 0x60bb, 0x0000, 0x6900, 0xa184, 0x0008, 0x0040, 0x1ff3, 0x6020,
- 0xa085, 0x0100, 0x6022, 0xa184, 0x0001, 0x0040, 0x2049, 0xa184,
- 0x0100, 0x00c0, 0x2035, 0xa184, 0x0200, 0x00c0, 0x2031, 0x681c,
- 0xa005, 0x00c0, 0x203d, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000f,
- 0x00c0, 0x200c, 0x1078, 0x2163, 0x78df, 0x0000, 0x6004, 0x8007,
- 0xa084, 0x00ff, 0x78d2, 0x8001, 0x609f, 0x0000, 0x0040, 0x2021,
- 0x1078, 0x2064, 0x0040, 0x2021, 0x78dc, 0xa085, 0x0100, 0x78de,
- 0x007c, 0x78d7, 0x0000, 0x78db, 0x0000, 0x6024, 0xa084, 0xff00,
- 0x6026, 0x1078, 0x3aac, 0x0040, 0x1d4f, 0x1078, 0x1be9, 0x0078,
- 0x1d4f, 0x2009, 0x0017, 0x0078, 0x2053, 0x2009, 0x000e, 0x0078,
- 0x2053, 0x2009, 0x0007, 0x0078, 0x2053, 0x2009, 0x0035, 0x0078,
- 0x2053, 0x2009, 0x003e, 0x0078, 0x2053, 0x2009, 0x0004, 0x0078,
- 0x2053, 0x2009, 0x0006, 0x0078, 0x2053, 0x2009, 0x0016, 0x0078,
- 0x2053, 0x2009, 0x0001, 0x6024, 0xa084, 0xff00, 0xa105, 0x6026,
- 0x2091, 0x8000, 0x1078, 0x1ccb, 0x2091, 0x8001, 0x0078, 0x1d4f,
- 0x1078, 0x199a, 0x0078, 0x1d4f, 0x78d4, 0xa06d, 0x00c0, 0x206f,
- 0x2c00, 0x78d6, 0x78da, 0x609f, 0x0000, 0x0078, 0x207b, 0x2c00,
- 0x689e, 0x609f, 0x0000, 0x78d6, 0x2d00, 0x6002, 0x78d8, 0xad06,
- 0x00c0, 0x207b, 0x6002, 0x78d0, 0x8001, 0x78d2, 0x00c0, 0x2087,
- 0x78dc, 0xa084, 0xfeff, 0x78de, 0x78d8, 0x2060, 0xa006, 0x007c,
- 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184, 0xe1ff, 0x601e, 0xa184,
- 0x0060, 0x0040, 0x2097, 0x0e7e, 0x1078, 0x48d3, 0x0e7f, 0x6596,
- 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714,
- 0x1078, 0x19c5, 0x2091, 0x8000, 0x60a0, 0xa084, 0x8000, 0x00c0,
- 0x20be, 0x6808, 0xa084, 0x0001, 0x0040, 0x20be, 0x2091, 0x8001,
- 0x1078, 0x1a31, 0x2091, 0x8000, 0x1078, 0x1ccb, 0x2091, 0x8001,
- 0x78d7, 0x0000, 0x78db, 0x0000, 0x0078, 0x2130, 0x6024, 0xa096,
- 0x0001, 0x00c0, 0x20c5, 0x8000, 0x6026, 0x6a10, 0x6814, 0x2091,
- 0x8001, 0xa202, 0x0048, 0x20d4, 0x0040, 0x20d4, 0x2039, 0x0200,
- 0x1078, 0x2131, 0x0078, 0x2130, 0x2c08, 0x2091, 0x8000, 0x60a0,
- 0xa084, 0x8000, 0x0040, 0x2101, 0x6800, 0xa065, 0x0040, 0x2106,
- 0x6a04, 0x0e7e, 0x2071, 0x5240, 0x7000, 0xa084, 0x0001, 0x0040,
- 0x20fb, 0x7048, 0xa206, 0x00c0, 0x20fb, 0x6b04, 0x231c, 0x2160,
- 0x6302, 0x2300, 0xa005, 0x00c0, 0x20f6, 0x6902, 0x2260, 0x6102,
- 0x0e7f, 0x0078, 0x210d, 0x2160, 0x6202, 0x6906, 0x0e7f, 0x0078,
- 0x210d, 0x6800, 0xa065, 0x0040, 0x2106, 0x6102, 0x6902, 0x00c0,
- 0x210a, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160, 0x60a0, 0xa084,
- 0x8000, 0x0040, 0x2117, 0x6808, 0xa084, 0xfffc, 0x680a, 0x6810,
- 0x8000, 0x6812, 0x2091, 0x8001, 0x6808, 0xa08c, 0x0040, 0x0040,
- 0x2126, 0xa086, 0x0040, 0x680a, 0x1078, 0x1a42, 0x2091, 0x8000,
- 0x1078, 0x226f, 0x2091, 0x8001, 0x78db, 0x0000, 0x78d7, 0x0000,
- 0x007c, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x1ccb,
- 0x2091, 0x8001, 0x78d8, 0xa065, 0x0040, 0x2144, 0x609c, 0x78da,
- 0x609f, 0x0000, 0x0078, 0x2134, 0x78d7, 0x0000, 0x78db, 0x0000,
- 0x007c, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8, 0x2150, 0xa006,
- 0x7896, 0x70d2, 0x7804, 0xa005, 0x0040, 0x215e, 0x8001, 0x7806,
- 0x00c0, 0x215e, 0x0068, 0x215e, 0x2091, 0x4080, 0x007c, 0x2039,
- 0x2177, 0x0078, 0x2165, 0x2039, 0x217d, 0x2704, 0xa005, 0x0040,
- 0x2176, 0xac00, 0x2068, 0x6b08, 0x6c0c, 0x6910, 0x6a14, 0x690a,
- 0x6a0e, 0x6b12, 0x6c16, 0x8738, 0x0078, 0x2165, 0x007c, 0x0003,
- 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015, 0x001b, 0x0000,
- 0x0c7e, 0x1078, 0x3c3b, 0x2c68, 0x0c7f, 0x007c, 0x0010, 0x21f7,
- 0x0068, 0x21f7, 0x2029, 0x0000, 0x78cb, 0x0000, 0x788c, 0xa065,
- 0x0040, 0x21f0, 0x2009, 0x5274, 0x2104, 0xa084, 0x0001, 0x0040,
- 0x21be, 0x6004, 0xa086, 0x0103, 0x00c0, 0x21be, 0x6018, 0xa005,
- 0x00c0, 0x21be, 0x6014, 0xa005, 0x00c0, 0x21be, 0x0d7e, 0x2069,
- 0x0000, 0x6818, 0xa084, 0x0001, 0x00c0, 0x21bd, 0x600c, 0x70c6,
- 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091, 0x4080,
- 0x0d7f, 0x1078, 0x1cf2, 0x0078, 0x21f5, 0x0d7f, 0x1078, 0x21f8,
- 0x0040, 0x21f0, 0x6204, 0xa294, 0x00ff, 0xa296, 0x0003, 0x0040,
- 0x21d0, 0x6204, 0xa296, 0x0110, 0x00c0, 0x21de, 0x78cb, 0x0001,
- 0x6204, 0xa294, 0xff00, 0x8217, 0x8211, 0x0040, 0x21de, 0x85ff,
- 0x00c0, 0x21f0, 0x8210, 0xa202, 0x00c8, 0x21f0, 0x057e, 0x1078,
- 0x2207, 0x057f, 0x0040, 0x21eb, 0x78e0, 0xa086, 0x0003, 0x0040,
- 0x21f0, 0x0078, 0x21de, 0x8528, 0x78c8, 0xa005, 0x0040, 0x218e,
- 0x85ff, 0x0040, 0x21f7, 0x2091, 0x4080, 0x78b0, 0x70d6, 0x007c,
- 0x7bac, 0x79b0, 0x70d4, 0xa102, 0x00c0, 0x2201, 0x2300, 0xa005,
- 0x007c, 0x0048, 0x2205, 0xa302, 0x007c, 0x8002, 0x007c, 0x2001,
- 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x2221, 0x2091, 0x8000,
- 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x2256, 0x7008, 0x7208,
- 0xa206, 0x00c0, 0x2256, 0xa286, 0x0008, 0x00c0, 0x2256, 0x2071,
- 0x0010, 0x1078, 0x225b, 0x2009, 0x0020, 0x6004, 0xa086, 0x0103,
- 0x00c0, 0x2230, 0x6028, 0xa005, 0x00c0, 0x2230, 0x2009, 0x000c,
- 0x1078, 0x1976, 0x0040, 0x2249, 0x78c4, 0x8000, 0x78c6, 0xa086,
- 0x0002, 0x00c0, 0x2256, 0x2091, 0x8000, 0x78e3, 0x0003, 0x78c7,
- 0x0000, 0x78cc, 0xa085, 0x0300, 0x78ce, 0x2091, 0x8001, 0x0078,
- 0x2256, 0x78c7, 0x0000, 0x1078, 0x1cf2, 0x79ac, 0x78b0, 0x8000,
- 0xa10a, 0x00c8, 0x2254, 0xa006, 0x78b2, 0xa006, 0x2071, 0x0010,
- 0x2091, 0x8001, 0x007c, 0x8107, 0x8004, 0x8004, 0x7ab8, 0x7bb4,
- 0x7cc0, 0x7dbc, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
- 0x0000, 0x007c, 0x2009, 0x525b, 0x2091, 0x8000, 0x200a, 0x0f7e,
- 0x0e7e, 0x2071, 0x5240, 0x7000, 0xa086, 0x0000, 0x00c0, 0x2289,
- 0x2009, 0x5212, 0x2104, 0xa005, 0x00c0, 0x2289, 0x2079, 0x0100,
- 0x7830, 0xa084, 0x00c0, 0x00c0, 0x2289, 0x0018, 0x2289, 0x781b,
- 0x004b, 0x0e7f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x5240,
- 0x2091, 0x8000, 0x7000, 0xa086, 0x0000, 0x00c0, 0x22a2, 0x2079,
- 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x22a2, 0x0018, 0x22a2,
- 0x781b, 0x004d, 0x2091, 0x8001, 0x0e7f, 0x0f7f, 0x007c, 0x127e,
- 0x2091, 0x2300, 0x2071, 0x5240, 0x2079, 0x0100, 0x784b, 0x000f,
- 0x0098, 0x22b5, 0x7838, 0x0078, 0x22ae, 0x20a9, 0x0040, 0x7800,
- 0xa082, 0x0004, 0x0048, 0x22be, 0x20a9, 0x0060, 0x789b, 0x0000,
- 0x78af, 0x0000, 0x78af, 0x0000, 0x0070, 0x22c8, 0x0078, 0x22c0,
- 0x7800, 0xa082, 0x0004, 0x0048, 0x22d7, 0x70b7, 0x0093, 0x2019,
- 0x4ff0, 0x1078, 0x2313, 0x702f, 0x8001, 0x0078, 0x22e3, 0x70b7,
- 0x0000, 0x2019, 0x4e70, 0x1078, 0x2313, 0x2019, 0x4eaf, 0x1078,
- 0x2313, 0x702f, 0x8000, 0x7003, 0x0000, 0x1078, 0x2420, 0x7004,
- 0xa084, 0x000f, 0x017e, 0x2009, 0x04fd, 0x210c, 0xa18a, 0x0005,
- 0x0048, 0x22f8, 0x0038, 0x22fe, 0xa085, 0x6280, 0x0078, 0x2300,
- 0x0028, 0x22fe, 0xa085, 0x6280, 0x0078, 0x2300, 0xa085, 0x62c0,
- 0x017f, 0x7806, 0x780f, 0xb204, 0x7843, 0x00d8, 0x7853, 0x0080,
- 0x780b, 0x0008, 0x7047, 0x0008, 0x7053, 0x527f, 0x704f, 0x0000,
- 0x127f, 0x2000, 0x007c, 0x137e, 0x147e, 0x157e, 0x047e, 0x20a1,
- 0x012b, 0x2304, 0xa005, 0x789a, 0x0040, 0x2333, 0x8318, 0x2324,
- 0x8318, 0x2398, 0x24a8, 0xa484, 0xff00, 0x0040, 0x232b, 0xa482,
- 0x0100, 0x20a9, 0x0100, 0x2020, 0x53a6, 0xa005, 0x00c0, 0x2322,
- 0x3318, 0x0078, 0x2319, 0x047f, 0x157f, 0x147f, 0x137f, 0x007c,
- 0xa18c, 0x000f, 0x2011, 0x0101, 0x2204, 0xa084, 0xfff0, 0xa105,
- 0x2012, 0x1078, 0x2420, 0x007c, 0x2011, 0x0101, 0x20a9, 0x0009,
- 0x810b, 0x0070, 0x234d, 0x0078, 0x2348, 0xa18c, 0x0e00, 0x2204,
- 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2009, 0x0101, 0x20a9,
- 0x0005, 0x8213, 0x0070, 0x235e, 0x0078, 0x2359, 0xa294, 0x00e0,
- 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x007c, 0x2011, 0x0101,
- 0x20a9, 0x000c, 0x810b, 0x0070, 0x236f, 0x0078, 0x236a, 0xa18c,
- 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x007c, 0x2011,
- 0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x007c, 0x8103,
- 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x62ac,
- 0x63ac, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e,
- 0x2061, 0x0100, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f,
- 0x007c, 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e, 0x2061, 0x0100,
- 0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae, 0x0c7f, 0x007c, 0x8103,
- 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4,
- 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x0c7f, 0x007c, 0x2091,
- 0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005, 0x0040, 0x23fe, 0x2061,
- 0x7600, 0x1078, 0x2406, 0x0040, 0x23e8, 0x20a9, 0x0000, 0x2061,
- 0x7500, 0x0c7e, 0x1078, 0x2406, 0x0040, 0x23d6, 0x0c7f, 0x8c60,
- 0x0070, 0x23d4, 0x0078, 0x23c9, 0x0078, 0x23fe, 0x007f, 0xa082,
- 0x7500, 0x2071, 0x5240, 0x7086, 0x7182, 0x2001, 0x0004, 0x706e,
- 0x7093, 0x000f, 0x7073, 0x0000, 0x1078, 0x226a, 0x0078, 0x23fa,
- 0x60c0, 0xa005, 0x00c0, 0x23fe, 0x2071, 0x5240, 0x7182, 0x2c00,
- 0x708a, 0x2001, 0x0006, 0x706e, 0x7093, 0x000f, 0x7073, 0x0000,
- 0x1078, 0x226a, 0x2001, 0x0000, 0x0078, 0x2400, 0x2001, 0x0001,
- 0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005,
- 0x0040, 0x241d, 0x2060, 0x600c, 0xa306, 0x00c0, 0x241a, 0x6010,
- 0xa206, 0x00c0, 0x241a, 0x6014, 0xa106, 0x00c0, 0x241a, 0xa006,
- 0x0078, 0x241f, 0x6000, 0x0078, 0x2407, 0xa085, 0x0001, 0x007c,
- 0x2011, 0x5241, 0x220c, 0xa18c, 0x000f, 0x2011, 0x013b, 0x2204,
- 0xa084, 0x0100, 0x0040, 0x2436, 0x2021, 0xff04, 0x2122, 0x810b,
- 0x810b, 0x810b, 0x810b, 0xa18d, 0x0f00, 0x2104, 0x007c, 0x0e7e,
- 0x68e4, 0xa08c, 0x0020, 0x0040, 0x248a, 0xa084, 0x0006, 0x00c0,
- 0x248a, 0x6014, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
- 0xa0f0, 0x5480, 0x7004, 0xa084, 0x000a, 0x00c0, 0x248a, 0x7108,
- 0xa194, 0xff00, 0x0040, 0x248a, 0xa18c, 0x00ff, 0x2001, 0x000c,
- 0xa106, 0x0040, 0x2471, 0x2001, 0x0012, 0xa106, 0x0040, 0x2475,
- 0x2001, 0x0014, 0xa106, 0x0040, 0x2479, 0x2001, 0x0019, 0xa106,
- 0x0040, 0x247d, 0x2001, 0x0032, 0xa106, 0x0040, 0x2481, 0x0078,
- 0x2485, 0x2009, 0x0012, 0x0078, 0x2487, 0x2009, 0x0014, 0x0078,
- 0x2487, 0x2009, 0x0019, 0x0078, 0x2487, 0x2009, 0x0020, 0x0078,
- 0x2487, 0x2009, 0x003f, 0x0078, 0x2487, 0x2011, 0x0000, 0x2100,
- 0xa205, 0x700a, 0x0e7f, 0x007c, 0x0068, 0x248c, 0x2091, 0x8000,
- 0x2071, 0x0000, 0x007e, 0x7018, 0xa084, 0x0001, 0x00c0, 0x2493,
- 0x007f, 0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002,
- 0x70db, 0x0741, 0x70df, 0x0006, 0x2071, 0x0000, 0x701b, 0x0001,
- 0x2091, 0x4080, 0x0078, 0x24aa, 0x107e, 0x007e, 0x127e, 0x2091,
- 0x2300, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x77c2, 0x74c6, 0x76ca,
- 0x75ce, 0xa594, 0x003f, 0xa49c, 0x0003, 0xa484, 0x000f, 0x0079,
- 0x24c1, 0x24d3, 0x24d3, 0x24d3, 0x280d, 0x3a09, 0x24d1, 0x2502,
- 0x250c, 0x24d1, 0x24d1, 0x24d1, 0x24d1, 0x24d1, 0x24d1, 0x24d1,
- 0x24d1, 0x1078, 0x248c, 0x8507, 0xa084, 0x001f, 0x0079, 0x24d8,
- 0x2516, 0x280d, 0x29c7, 0x2ac4, 0x2aec, 0x2d8c, 0x3037, 0x309a,
- 0x30fb, 0x3180, 0x3238, 0x32d6, 0x2502, 0x28e9, 0x300c, 0x24f8,
- 0x3dac, 0x3dcc, 0x3f8f, 0x3f9b, 0x4074, 0x24f8, 0x24f8, 0x4149,
- 0x414d, 0x3daa, 0x24f8, 0x3efa, 0x24f8, 0x3c5e, 0x250c, 0x24f8,
- 0x1078, 0x248c, 0x0018, 0x24b1, 0x127f, 0x2091, 0x8001, 0x007f,
- 0x107f, 0x007c, 0x2019, 0x4f49, 0x1078, 0x2313, 0x702f, 0x0001,
- 0x781b, 0x004f, 0x0078, 0x24fa, 0x2019, 0x4eaf, 0x1078, 0x2313,
- 0x702f, 0x8000, 0x781b, 0x00cd, 0x0078, 0x24fa, 0x7242, 0x2009,
- 0x520f, 0x200b, 0x0000, 0xa584, 0x0001, 0x00c0, 0x3c72, 0x0040,
- 0x2533, 0x1078, 0x248c, 0x7003, 0x0000, 0x704b, 0x0000, 0x7043,
- 0x0000, 0x7037, 0x0000, 0x1078, 0x39e0, 0x0018, 0x24b1, 0x2009,
- 0x520f, 0x200b, 0x0000, 0x7068, 0xa005, 0x00c0, 0x25fe, 0x706c,
- 0xa084, 0x0007, 0x0079, 0x253c, 0x2635, 0x2544, 0x2550, 0x256d,
- 0x258f, 0x25dc, 0x25b5, 0x2544, 0x1078, 0x39c8, 0x2009, 0x0048,
- 0x1078, 0x2ed8, 0x00c0, 0x254e, 0x7003, 0x0004, 0x0078, 0x24fa,
- 0x1078, 0x39c8, 0x00c0, 0x256b, 0x7080, 0x8007, 0x7882, 0x789b,
- 0x0010, 0x78ab, 0x000c, 0x789b, 0x0060, 0x78ab, 0x0001, 0x785b,
- 0x0004, 0x2009, 0x00dd, 0x1078, 0x2ecc, 0x00c0, 0x256b, 0x7003,
- 0x0004, 0x7093, 0x000f, 0x0078, 0x24fa, 0x1078, 0x39c8, 0x00c0,
- 0x258d, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f,
- 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab,
- 0x0002, 0x785b, 0x0004, 0x2009, 0x00dd, 0x1078, 0x2ecc, 0x00c0,
- 0x258d, 0x7003, 0x0004, 0x7093, 0x000f, 0x0078, 0x24fa, 0x1078,
- 0x39c8, 0x00c0, 0x25b3, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010,
- 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0020, 0x7184,
- 0x79aa, 0x78ab, 0x000d, 0x789b, 0x0060, 0x78ab, 0x0004, 0x785b,
- 0x0004, 0x2009, 0x00dd, 0x1078, 0x2ecc, 0x00c0, 0x25b3, 0x7003,
- 0x0004, 0x7093, 0x000f, 0x0078, 0x24fa, 0x1078, 0x39c8, 0x00c0,
- 0x25da, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f,
- 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab,
- 0x0002, 0x785b, 0x0004, 0x2009, 0x00dd, 0x1078, 0x2ecc, 0x00c0,
- 0x25da, 0x7088, 0x708b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0002,
- 0x7093, 0x000f, 0x0078, 0x24fa, 0x1078, 0x39c8, 0x00c0, 0x24fa,
- 0x7088, 0x2068, 0x6f14, 0x1078, 0x38bd, 0x2c50, 0x1078, 0x3a7a,
- 0x789b, 0x0010, 0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa,
- 0x6e1c, 0x2041, 0x0001, 0x708c, 0xa084, 0x0400, 0x2001, 0x0004,
- 0x0040, 0x25fc, 0x2001, 0x0006, 0x0078, 0x271d, 0x1078, 0x39c8,
- 0x00c0, 0x24fa, 0x789b, 0x0010, 0x7068, 0x2068, 0x6f14, 0x1078,
- 0x38bd, 0x2c50, 0x1078, 0x3a7a, 0x6008, 0xa085, 0x0010, 0x600a,
- 0x6824, 0xa005, 0x0040, 0x261c, 0xa082, 0x0006, 0x0048, 0x261a,
- 0x0078, 0x261c, 0x6827, 0x0005, 0x6b14, 0xa39c, 0x001f, 0xa39d,
- 0x00c0, 0x7058, 0xa084, 0x8000, 0x0040, 0x262a, 0xa684, 0x0001,
- 0x0040, 0x262c, 0xa39c, 0xffbf, 0x7baa, 0x2031, 0x0020, 0x2041,
- 0x0001, 0x2001, 0x0003, 0x0078, 0x271d, 0x0018, 0x24b1, 0x744c,
- 0xa485, 0x0000, 0x0040, 0x264f, 0xa080, 0x5280, 0x2030, 0x7150,
- 0x8108, 0xa12a, 0x0048, 0x2646, 0x2009, 0x5280, 0x2164, 0x6504,
- 0x85ff, 0x00c0, 0x2660, 0x8421, 0x00c0, 0x2640, 0x7152, 0x7003,
- 0x0000, 0x704b, 0x0000, 0x7040, 0xa005, 0x0040, 0x3c72, 0x0078,
- 0x24fa, 0x764c, 0xa6b0, 0x5280, 0x7150, 0x2600, 0x0078, 0x264b,
- 0x7152, 0x2568, 0x2558, 0x754a, 0x2c50, 0x6034, 0xa085, 0x0000,
- 0x00c0, 0x265d, 0x6708, 0x773a, 0xa784, 0x033f, 0x0040, 0x2696,
- 0xa784, 0x0021, 0x00c0, 0x265d, 0xa784, 0x0002, 0x0040, 0x267f,
- 0xa784, 0x0004, 0x0040, 0x265d, 0xa7bc, 0xfffb, 0x670a, 0xa784,
- 0x0008, 0x00c0, 0x265d, 0xa784, 0x0010, 0x00c0, 0x265d, 0xa784,
- 0x0200, 0x00c0, 0x265d, 0xa784, 0x0100, 0x0040, 0x2696, 0x6018,
- 0xa005, 0x00c0, 0x265d, 0xa7bc, 0xfeff, 0x670a, 0x6823, 0x0000,
- 0x6e1c, 0xa684, 0x000e, 0x6118, 0x0040, 0x26a6, 0x601c, 0xa102,
- 0x0048, 0x26a9, 0x0040, 0x26a9, 0x0078, 0x2659, 0x81ff, 0x00c0,
- 0x2659, 0x68c3, 0x0000, 0xa784, 0x0080, 0x00c0, 0x26b1, 0x700c,
- 0x6022, 0xa7bc, 0xff7f, 0x670a, 0x1078, 0x3a7a, 0x0018, 0x24b1,
- 0x789b, 0x0010, 0xa046, 0x1078, 0x39c8, 0x00c0, 0x24fa, 0x6b14,
- 0xa39c, 0x001f, 0xa39d, 0x00c0, 0x7058, 0xa084, 0x8000, 0x0040,
- 0x26cd, 0xa684, 0x0001, 0x0040, 0x26cf, 0xa39c, 0xffbf, 0xa684,
- 0x0010, 0x0040, 0x26d5, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684,
- 0x000e, 0x00c0, 0x26e0, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x271b,
- 0x7158, 0xa18c, 0x0800, 0x0040, 0x34cb, 0x2011, 0x0020, 0xa684,
- 0x0008, 0x00c0, 0x26f1, 0x8210, 0xa684, 0x0002, 0x00c0, 0x26f1,
- 0x8210, 0x7aaa, 0x8840, 0x1078, 0x39e0, 0x6a14, 0x610c, 0x8108,
- 0xa18c, 0x00ff, 0xa1e0, 0x7500, 0x2c64, 0x8cff, 0x0040, 0x2712,
- 0x6014, 0xa206, 0x00c0, 0x26fc, 0x60b8, 0x8001, 0x60ba, 0x00c0,
- 0x26f7, 0x0c7e, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x0c7f,
- 0x0078, 0x2635, 0x1078, 0x39c8, 0x00c0, 0x24fa, 0x2a60, 0x610e,
- 0x79aa, 0x8840, 0x7132, 0x2001, 0x0001, 0x007e, 0x715c, 0xa184,
- 0x0018, 0x0040, 0x2738, 0xa184, 0x0010, 0x0040, 0x272b, 0x1078,
- 0x36d0, 0x00c0, 0x275b, 0xa184, 0x0008, 0x0040, 0x2738, 0x69a0,
- 0xa184, 0x0600, 0x00c0, 0x2738, 0x1078, 0x35bb, 0x0078, 0x275b,
- 0x69a0, 0xa184, 0x0800, 0x0040, 0x274f, 0x0c7e, 0x027e, 0x2960,
- 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106,
- 0x027f, 0x0c7f, 0x1078, 0x36d0, 0x00c0, 0x275b, 0x69a0, 0xa184,
- 0x0200, 0x0040, 0x2757, 0x1078, 0x360c, 0x0078, 0x275b, 0xa184,
- 0x0400, 0x00c0, 0x2734, 0x69a0, 0xa184, 0x1000, 0x0040, 0x2766,
- 0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x238b, 0x007f, 0x7002,
- 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0040, 0x2774, 0xa086, 0x0060,
- 0x00c0, 0x2774, 0xa18d, 0x4000, 0x88ff, 0x0040, 0x2779, 0xa18d,
- 0x0004, 0x795a, 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x789b,
- 0x0061, 0x6818, 0xa08d, 0x8000, 0xa084, 0x7fff, 0x691a, 0xa68c,
- 0x0080, 0x0040, 0x2798, 0x7097, 0x0000, 0xa08a, 0x000d, 0x0050,
- 0x2796, 0xa08a, 0x000c, 0x7196, 0x2001, 0x000c, 0x800c, 0x719a,
- 0x78aa, 0x8008, 0x810c, 0x0040, 0x34d1, 0xa18c, 0x00f8, 0x00c0,
- 0x34d1, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000,
- 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f,
- 0x157f, 0x6814, 0x8007, 0x7882, 0x6d94, 0x7dd6, 0x7dde, 0x6e98,
- 0x7ed2, 0x7eda, 0x1078, 0x39c8, 0x00c0, 0x27cf, 0x702c, 0x8003,
- 0x0048, 0x27c8, 0x2019, 0x4eaf, 0x1078, 0x2313, 0x702f, 0x8000,
- 0x7830, 0xa084, 0x00c0, 0x00c0, 0x27cf, 0x0098, 0x27d7, 0x6008,
- 0xa084, 0xffef, 0x600a, 0x1078, 0x39e0, 0x0078, 0x2523, 0x7200,
- 0xa284, 0x0007, 0xa086, 0x0001, 0x00c0, 0x27e4, 0x781b, 0x004f,
- 0x1078, 0x39e0, 0x0078, 0x27f5, 0x6ab4, 0xa295, 0x2000, 0x7a5a,
- 0x781b, 0x004f, 0x1078, 0x39e0, 0x7200, 0x2500, 0xa605, 0x0040,
- 0x27f5, 0xa284, 0x0007, 0x1079, 0x2803, 0xad80, 0x0009, 0x7036,
- 0xa284, 0x0007, 0xa086, 0x0001, 0x00c0, 0x24fa, 0x6018, 0x8000,
- 0x601a, 0x0078, 0x24fa, 0x280b, 0x4b4b, 0x4b4b, 0x4b3a, 0x4b4b,
- 0x280b, 0x4b3a, 0x280b, 0x1078, 0x248c, 0x1078, 0x39c8, 0x0f7e,
- 0x2079, 0x5200, 0x78cc, 0x0f7f, 0xa084, 0x0001, 0x0040, 0x2831,
- 0x706c, 0xa086, 0x0001, 0x00c0, 0x2820, 0x706e, 0x0078, 0x28c4,
- 0x706c, 0xa086, 0x0005, 0x00c0, 0x282f, 0x7088, 0x2068, 0x681b,
- 0x0004, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x706f,
- 0x0000, 0x2011, 0x0004, 0x716c, 0xa186, 0x0001, 0x0040, 0x2852,
- 0xa186, 0x0007, 0x00c0, 0x2842, 0x2009, 0x5238, 0x200b, 0x0005,
- 0x0078, 0x2852, 0x2009, 0x5213, 0x2104, 0x2009, 0x5212, 0x200a,
- 0x2009, 0x5238, 0x200b, 0x0001, 0x706f, 0x0000, 0x7073, 0x0001,
- 0x0078, 0x2854, 0x706f, 0x0000, 0x1078, 0x4887, 0x157e, 0x20a9,
- 0x0010, 0x2039, 0x0000, 0x1078, 0x37b0, 0xa7b8, 0x0100, 0x0070,
- 0x2863, 0x0078, 0x285b, 0x157f, 0x7000, 0x0079, 0x2867, 0x2895,
- 0x287c, 0x287c, 0x286f, 0x2895, 0x2895, 0x2895, 0x2895, 0x2021,
- 0x525a, 0x2404, 0xa005, 0x0040, 0x2895, 0xad06, 0x00c0, 0x287c,
- 0x6800, 0x2022, 0x0078, 0x288c, 0x6820, 0xa084, 0x0001, 0x00c0,
- 0x2888, 0x6f14, 0x1078, 0x38bd, 0x1078, 0x34a2, 0x0078, 0x288c,
- 0x7060, 0x2060, 0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000, 0x6820,
- 0xa085, 0x0008, 0x6822, 0x1078, 0x1cdc, 0x2021, 0x7600, 0x1078,
- 0x28d1, 0x2021, 0x525a, 0x1078, 0x28d1, 0x157e, 0x20a9, 0x0000,
- 0x2021, 0x7500, 0x1078, 0x28d1, 0x8420, 0x0070, 0x28a9, 0x0078,
- 0x28a2, 0x2061, 0x5500, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6018,
- 0x6110, 0x81ff, 0x0040, 0x28b8, 0xa102, 0x0050, 0x28b8, 0x6012,
- 0x601b, 0x0000, 0xace0, 0x0010, 0x0070, 0x28c0, 0x0078, 0x28af,
- 0x8421, 0x00c0, 0x28ad, 0x157f, 0x709c, 0xa084, 0x8000, 0x0040,
- 0x28cb, 0x1078, 0x3ace, 0x7003, 0x0000, 0x704b, 0x0000, 0x0078,
- 0x24fa, 0x047e, 0x2404, 0xa005, 0x0040, 0x28e5, 0x2068, 0x6800,
- 0x007e, 0x6a1a, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822,
- 0x1078, 0x1cdc, 0x007f, 0x0078, 0x28d3, 0x047f, 0x2023, 0x0000,
- 0x007c, 0xa282, 0x0003, 0x0050, 0x28ef, 0x1078, 0x248c, 0x2300,
- 0x0079, 0x28f2, 0x28f5, 0x2968, 0x2985, 0xa282, 0x0002, 0x0040,
- 0x28fb, 0x1078, 0x248c, 0x706c, 0x706f, 0x0000, 0x7093, 0x0000,
- 0x0079, 0x2902, 0x290a, 0x290a, 0x290c, 0x2940, 0x34d7, 0x290a,
- 0x2940, 0x290a, 0x1078, 0x248c, 0x7780, 0x1078, 0x37b0, 0x7780,
- 0xa7bc, 0x0f00, 0x1078, 0x38bd, 0x6018, 0xa005, 0x0040, 0x2937,
- 0x2021, 0x7600, 0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x29a0,
- 0x0040, 0x2937, 0x157e, 0x20a9, 0x0000, 0x2021, 0x7500, 0x047e,
- 0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x29a0, 0x047f, 0x0040,
- 0x2936, 0x8420, 0x0070, 0x2936, 0x0078, 0x2927, 0x157f, 0x8738,
- 0xa784, 0x001f, 0x00c0, 0x2912, 0x0078, 0x2523, 0x0078, 0x2523,
- 0x7780, 0x1078, 0x38bd, 0x6018, 0xa005, 0x0040, 0x2966, 0x2021,
- 0x7600, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x29a0, 0x0040,
- 0x2966, 0x157e, 0x20a9, 0x0000, 0x2021, 0x7500, 0x047e, 0x2009,
- 0x0005, 0x2011, 0x0020, 0x1078, 0x29a0, 0x047f, 0x0040, 0x2965,
- 0x8420, 0x0070, 0x2965, 0x0078, 0x2956, 0x157f, 0x0078, 0x2523,
- 0x2200, 0x0079, 0x296b, 0x296e, 0x2970, 0x2970, 0x1078, 0x248c,
- 0x2009, 0x0012, 0x706c, 0xa086, 0x0002, 0x0040, 0x2979, 0x2009,
- 0x000e, 0x6818, 0xa084, 0x8000, 0x0040, 0x297f, 0x691a, 0x706f,
- 0x0000, 0x7073, 0x0001, 0x0078, 0x3956, 0x2200, 0x0079, 0x2988,
- 0x298d, 0x2970, 0x298b, 0x1078, 0x248c, 0x1078, 0x4887, 0x7000,
- 0xa086, 0x0001, 0x00c0, 0x3467, 0x1078, 0x34b8, 0x6008, 0xa084,
- 0xffef, 0x600a, 0x1078, 0x345a, 0x0040, 0x3467, 0x0078, 0x2635,
- 0x2404, 0xa005, 0x0040, 0x29c3, 0x2068, 0x2d04, 0x007e, 0x6814,
- 0xa706, 0x0040, 0x29af, 0x2d20, 0x007f, 0x0078, 0x29a1, 0x007f,
- 0x2022, 0x691a, 0x6817, 0x0000, 0x6820, 0xa205, 0x6822, 0x1078,
- 0x1cdc, 0x6010, 0x8001, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a,
- 0x1078, 0x34b8, 0x007c, 0xa085, 0x0001, 0x0078, 0x29c2, 0x2300,
- 0x0079, 0x29ca, 0x29cf, 0x29cd, 0x2a68, 0x1078, 0x248c, 0x78ec,
- 0xa084, 0x0001, 0x00c0, 0x29e3, 0x7000, 0xa086, 0x0004, 0x00c0,
- 0x29db, 0x0078, 0x2a06, 0x1078, 0x34b8, 0x6008, 0xa084, 0xffef,
- 0x600a, 0x0078, 0x3467, 0x78e4, 0xa005, 0x00d0, 0x2a06, 0x0018,
- 0x24fa, 0x2008, 0xa084, 0x0030, 0x00c0, 0x29f2, 0x781b, 0x004f,
- 0x0078, 0x24fa, 0x78ec, 0xa084, 0x0003, 0x0040, 0x29ee, 0x2100,
- 0xa084, 0x0007, 0x0079, 0x29fc, 0x2a3f, 0x2a4a, 0x2a30, 0x2a04,
- 0x39bb, 0x39bb, 0x2a04, 0x2a59, 0x1078, 0x248c, 0x7000, 0xa086,
- 0x0004, 0x00c0, 0x2a20, 0x706c, 0xa086, 0x0002, 0x00c0, 0x2a16,
- 0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x28e9, 0x706c, 0xa086,
- 0x0006, 0x0040, 0x2a10, 0x706c, 0xa086, 0x0004, 0x0040, 0x2a10,
- 0x79e4, 0xa184, 0x0030, 0x0040, 0x2a2a, 0x78ec, 0xa084, 0x0003,
- 0x00c0, 0x2a2c, 0x0078, 0x300c, 0x2001, 0x0003, 0x0078, 0x2da0,
- 0x6818, 0xa084, 0x8000, 0x0040, 0x2a37, 0x681b, 0x001d, 0x1078,
- 0x378f, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x24fa, 0x6818,
- 0xa084, 0x8000, 0x0040, 0x2a46, 0x681b, 0x001d, 0x1078, 0x378f,
- 0x0078, 0x3986, 0x6818, 0xa084, 0x8000, 0x0040, 0x2a51, 0x681b,
- 0x001d, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b, 0x00ca, 0x0078,
- 0x24fa, 0x6818, 0xa084, 0x8000, 0x0040, 0x2a60, 0x681b, 0x001d,
- 0x1078, 0x378f, 0x782b, 0x3008, 0x781b, 0x008f, 0x0078, 0x24fa,
- 0xa584, 0x000f, 0x00c0, 0x2a85, 0x7000, 0x0079, 0x2a6f, 0x2523,
- 0x2a79, 0x2a77, 0x3467, 0x3467, 0x3467, 0x3467, 0x2a77, 0x1078,
- 0x248c, 0x1078, 0x34b8, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078,
- 0x345a, 0x0040, 0x3467, 0x0078, 0x2635, 0x78e4, 0xa005, 0x00d0,
- 0x2a06, 0x0018, 0x2a06, 0x2008, 0xa084, 0x0030, 0x00c0, 0x2a94,
- 0x781b, 0x004f, 0x0078, 0x24fa, 0x78ec, 0xa084, 0x0003, 0x0040,
- 0x2a90, 0x2100, 0xa184, 0x0007, 0x0079, 0x2a9e, 0x2ab0, 0x2ab4,
- 0x2aa8, 0x2aa6, 0x39bb, 0x39bb, 0x2aa6, 0x39b1, 0x1078, 0x248c,
- 0x1078, 0x3797, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x24fa,
- 0x1078, 0x3797, 0x0078, 0x3986, 0x1078, 0x3797, 0x782b, 0x3008,
- 0x781b, 0x00ca, 0x0078, 0x24fa, 0x1078, 0x3797, 0x782b, 0x3008,
- 0x781b, 0x008f, 0x0078, 0x24fa, 0x2300, 0x0079, 0x2ac7, 0x2acc,
- 0x2aca, 0x2ace, 0x1078, 0x248c, 0x0078, 0x3180, 0x681b, 0x0008,
- 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x3180, 0x78ec,
- 0xa084, 0x0003, 0x0040, 0x3180, 0xa184, 0x0007, 0x0079, 0x2ae0,
- 0x2ae8, 0x2ab4, 0x2a30, 0x3956, 0x39bb, 0x39bb, 0x2ae8, 0x39b1,
- 0x1078, 0x396a, 0x0078, 0x24fa, 0xa282, 0x0005, 0x0050, 0x2af2,
- 0x1078, 0x248c, 0x2300, 0x0079, 0x2af5, 0x2af8, 0x2d4d, 0x2d5b,
- 0x2200, 0x0079, 0x2afb, 0x2b15, 0x2b02, 0x2b15, 0x2b00, 0x2d32,
- 0x1078, 0x248c, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082,
- 0x0020, 0x0048, 0x376b, 0xa08a, 0x0004, 0x00c8, 0x376b, 0x0079,
- 0x2b11, 0x376b, 0x376b, 0x376b, 0x3719, 0x789b, 0x0018, 0x79a8,
- 0xa184, 0x0080, 0x0040, 0x2b26, 0x0078, 0x376b, 0x7000, 0xa005,
- 0x00c0, 0x2b1c, 0x2011, 0x0004, 0x0078, 0x32e9, 0xa184, 0x00ff,
- 0xa08a, 0x0010, 0x00c8, 0x376b, 0x0079, 0x2b2e, 0x2b40, 0x2b3e,
- 0x2b58, 0x2b5c, 0x2c17, 0x376b, 0x376b, 0x2c19, 0x376b, 0x376b,
- 0x2d2e, 0x2d2e, 0x376b, 0x376b, 0x376b, 0x2d30, 0x1078, 0x248c,
- 0xa684, 0x1000, 0x0040, 0x2b4d, 0x2001, 0x0500, 0x8000, 0x8000,
- 0x783a, 0x781b, 0x008d, 0x0078, 0x24fa, 0x6818, 0xa084, 0x8000,
- 0x0040, 0x2b56, 0x681b, 0x001d, 0x0078, 0x2b44, 0x0078, 0x3956,
- 0x681b, 0x001d, 0x0078, 0x377b, 0x6920, 0x6922, 0xa684, 0x1800,
- 0x00c0, 0x2b9d, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2ba5, 0x6818,
- 0xa086, 0x0008, 0x00c0, 0x2b6e, 0x681b, 0x0000, 0xa684, 0x0400,
- 0x0040, 0x2c13, 0xa684, 0x0080, 0x0040, 0x2b99, 0x7097, 0x0000,
- 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d, 0x0050, 0x2b99, 0xa08a,
- 0x000c, 0x7196, 0x2001, 0x000c, 0x800c, 0x719a, 0x789b, 0x0061,
- 0x78aa, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000,
- 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f,
- 0x157f, 0x781b, 0x0058, 0x0078, 0x24fa, 0xa684, 0x1000, 0x0040,
- 0x2ba5, 0x781b, 0x0065, 0x0078, 0x24fa, 0xa684, 0x0060, 0x0040,
- 0x2c0f, 0xa684, 0x0800, 0x0040, 0x2c0f, 0xa684, 0x8000, 0x00c0,
- 0x2bb3, 0x0078, 0x2bcb, 0xa6b4, 0x7fff, 0x7e5a, 0x6eb6, 0x7adc,
- 0x79d8, 0x78d0, 0x801b, 0x00c8, 0x2bbe, 0x8000, 0xa084, 0x003f,
- 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94,
- 0x2200, 0xa303, 0x68ae, 0xa684, 0x4000, 0x0040, 0x2bd3, 0xa6b4,
- 0xbfff, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003, 0x00c0, 0x2be0,
- 0x1078, 0x493d, 0x1078, 0x4b3a, 0x781b, 0x0064, 0x0078, 0x24fa,
- 0xa006, 0x1078, 0x4c41, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200,
- 0xa105, 0x0040, 0x2bef, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa,
- 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x00c0,
- 0x2c01, 0xa6b5, 0x4000, 0x7e5a, 0x6eb6, 0x781b, 0x0064, 0x0078,
- 0x24fa, 0x781b, 0x0064, 0x2200, 0xa115, 0x00c0, 0x2c0b, 0x1078,
- 0x4b4b, 0x0078, 0x24fa, 0x1078, 0x4b96, 0x0078, 0x24fa, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x781b, 0x0058, 0x0078, 0x24fa, 0x1078,
- 0x248c, 0x0078, 0x2c7a, 0x6920, 0xa184, 0x0100, 0x0040, 0x2c31,
- 0xa18c, 0xfeff, 0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084,
- 0xefff, 0x6002, 0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078,
- 0x2c69, 0xa184, 0x0200, 0x0040, 0x2c69, 0xa18c, 0xfdff, 0x6922,
- 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084, 0xdfff, 0x6002, 0x6004,
- 0xa084, 0xffef, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0008,
- 0x0040, 0x2c69, 0x1078, 0x38b9, 0x1078, 0x35bb, 0x88ff, 0x0040,
- 0x2c69, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004,
- 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2c63, 0x782b, 0x3008, 0x781b,
- 0x0056, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078,
- 0x24fa, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x2c72, 0x781b, 0x0058,
- 0x0078, 0x24fa, 0x781b, 0x0065, 0x0078, 0x24fa, 0x0078, 0x3773,
- 0x0078, 0x3773, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x00c0,
- 0x2c88, 0x6820, 0xa084, 0x0100, 0x0040, 0x2c78, 0x2009, 0x0008,
- 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0,
- 0x2cbf, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x2cb7,
- 0x0048, 0x2c9c, 0x0078, 0x2cb9, 0xa380, 0x0002, 0xa102, 0x00c8,
- 0x2cb7, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0c7e, 0x7054, 0x2060,
- 0x6000, 0xa084, 0xefef, 0x6002, 0x6004, 0xa084, 0xffe5, 0x6006,
- 0x0c7f, 0x7e58, 0xa6b4, 0xfffb, 0x7e5a, 0x0078, 0x2c6a, 0x0078,
- 0x2c1b, 0x24a8, 0x7aa8, 0x00f0, 0x2cb9, 0x0078, 0x2c8a, 0xa284,
- 0x00f0, 0xa086, 0x0020, 0x00c0, 0x2d1f, 0x8318, 0x8318, 0x2300,
- 0xa102, 0x0040, 0x2ccf, 0x0048, 0x2ccf, 0x0078, 0x2d1c, 0xa286,
- 0x0023, 0x0040, 0x2c78, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58,
- 0xa684, 0xfff1, 0xa085, 0x0010, 0x2030, 0x7e5a, 0x6008, 0xa085,
- 0x0010, 0x600a, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008, 0x2c48,
- 0x0c7f, 0xa184, 0x0010, 0x0040, 0x2cf3, 0x1078, 0x38b9, 0x1078,
- 0x36d0, 0x0078, 0x2d02, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008,
- 0x2c48, 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2c69, 0x1078, 0x38b9,
- 0x1078, 0x35bb, 0x88ff, 0x0040, 0x2c69, 0x789b, 0x0060, 0x2800,
- 0x78aa, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2d16,
- 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x24fa, 0x782b, 0x3008,
- 0x781b, 0x0065, 0x0078, 0x24fa, 0x7aa8, 0x0078, 0x2c8a, 0x8318,
- 0x2300, 0xa102, 0x0040, 0x2d28, 0x0048, 0x2d28, 0x0078, 0x2c8a,
- 0xa284, 0x0080, 0x00c0, 0x377b, 0x0078, 0x3773, 0x0078, 0x377b,
- 0x0078, 0x376b, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e,
- 0x0001, 0x0040, 0x2d3d, 0x1078, 0x248c, 0x7aa8, 0xa294, 0x00ff,
- 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x376b, 0x0079,
- 0x2d49, 0x376b, 0x3508, 0x376b, 0x3665, 0xa282, 0x0000, 0x00c0,
- 0x2d53, 0x1078, 0x248c, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0xa282, 0x0003, 0x00c0, 0x2d61, 0x1078,
- 0x248c, 0xa484, 0x8000, 0x00c0, 0x2d84, 0x706c, 0xa005, 0x0040,
- 0x2d6b, 0x1078, 0x248c, 0x6f14, 0x7782, 0xa7bc, 0x0f00, 0x1078,
- 0x38bd, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f,
- 0x00c0, 0x2d6f, 0x1078, 0x3793, 0x706f, 0x0002, 0x2009, 0x5238,
- 0x200b, 0x0009, 0x0078, 0x2d86, 0x1078, 0x379f, 0x782b, 0x3008,
- 0x781b, 0x0065, 0x0078, 0x24fa, 0xa282, 0x0004, 0x0050, 0x2d92,
- 0x1078, 0x248c, 0x2300, 0x0079, 0x2d95, 0x2d98, 0x2e81, 0x2eb4,
- 0xa286, 0x0003, 0x0040, 0x2d9e, 0x1078, 0x248c, 0x2001, 0x0000,
- 0x007e, 0x68c0, 0xa005, 0x0040, 0x2da7, 0x7003, 0x0003, 0x68a0,
- 0xa084, 0x2000, 0x0040, 0x2db0, 0x6008, 0xa085, 0x0002, 0x600a,
- 0x007f, 0x703e, 0x7000, 0xa084, 0x0007, 0x0079, 0x2db7, 0x2523,
- 0x2dc1, 0x2dc1, 0x2fb6, 0x2ff2, 0x2523, 0x2ff2, 0x2dbf, 0x1078,
- 0x248c, 0xa684, 0x1000, 0x00c0, 0x2dc9, 0x1078, 0x4887, 0x0040,
- 0x2e5b, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2e11, 0xa186, 0x0008,
- 0x00c0, 0x2de0, 0x1078, 0x34b8, 0x6008, 0xa084, 0xffef, 0x600a,
- 0x1078, 0x345a, 0x0040, 0x2e11, 0x1078, 0x4887, 0x0078, 0x2df8,
- 0xa186, 0x0028, 0x00c0, 0x2e11, 0x1078, 0x4887, 0x6008, 0xa084,
- 0xffef, 0x600a, 0x6018, 0xa005, 0x0040, 0x2df8, 0x8001, 0x601a,
- 0xa005, 0x0040, 0x2df8, 0x8001, 0xa005, 0x0040, 0x2df8, 0x601e,
- 0x6820, 0xa084, 0x0001, 0x0040, 0x2523, 0x6820, 0xa084, 0xfffe,
- 0x6822, 0x7060, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004,
- 0x6802, 0xa005, 0x2d00, 0x00c0, 0x2e0e, 0x6002, 0x6006, 0x0078,
- 0x2523, 0x017e, 0x1078, 0x2ee5, 0x017f, 0xa684, 0xdf00, 0x681e,
- 0x682b, 0x0000, 0x6f14, 0x81ff, 0x0040, 0x2e5b, 0xa186, 0x0002,
- 0x00c0, 0x2e5b, 0xa684, 0x0800, 0x00c0, 0x2e2e, 0xa684, 0x0060,
- 0x0040, 0x2e2e, 0x78d8, 0x7adc, 0x682e, 0x6a32, 0x6820, 0xa084,
- 0x0800, 0x00c0, 0x2e5b, 0x8717, 0xa294, 0x000f, 0x8213, 0x8213,
- 0x8213, 0xa290, 0x5480, 0xa290, 0x0000, 0x221c, 0xa384, 0x0100,
- 0x00c0, 0x2e44, 0x0078, 0x2e4a, 0x8210, 0x2204, 0xa085, 0x0018,
- 0x2012, 0x8211, 0xa384, 0x0400, 0x0040, 0x2e57, 0x68a0, 0xa084,
- 0x0100, 0x00c0, 0x2e57, 0x1078, 0x2f69, 0x0078, 0x2523, 0x6008,
- 0xa085, 0x0002, 0x600a, 0x6916, 0x6818, 0xa084, 0x8000, 0x0040,
- 0x2e63, 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x1078, 0x34a9,
- 0x1078, 0x34b8, 0x00c0, 0x2e70, 0x6008, 0xa084, 0xffef, 0x600a,
- 0x6820, 0xa084, 0x0001, 0x00c0, 0x2e79, 0x1078, 0x34a2, 0x0078,
- 0x2e7d, 0x7060, 0x2060, 0x6800, 0x6002, 0x1078, 0x1cdc, 0x0078,
- 0x2523, 0xa282, 0x0004, 0x0048, 0x2e87, 0x1078, 0x248c, 0x2200,
- 0x0079, 0x2e8a, 0x2e85, 0x2e8e, 0x2e9b, 0x2e8e, 0x7000, 0xa086,
- 0x0005, 0x0040, 0x2e97, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x7890, 0x8007, 0x8001, 0xa084, 0x0007,
- 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186, 0x0003,
- 0x0040, 0x2eb0, 0xa186, 0x0000, 0x0040, 0x2eb0, 0x0078, 0x376b,
- 0x781b, 0x0065, 0x0078, 0x24fa, 0x6820, 0xa085, 0x0004, 0x6822,
- 0x82ff, 0x00c0, 0x2ebf, 0x1078, 0x378f, 0x0078, 0x2ec6, 0x8211,
- 0x0040, 0x2ec4, 0x1078, 0x248c, 0x1078, 0x379f, 0x782b, 0x3008,
- 0x781b, 0x0065, 0x0078, 0x24fa, 0x702c, 0x8003, 0x0048, 0x2ed6,
- 0x2019, 0x4eaf, 0x1078, 0x2313, 0x702f, 0x8000, 0x1078, 0x39e0,
- 0x7830, 0xa084, 0x00c0, 0x00c0, 0x2ee2, 0x0018, 0x2ee2, 0x791a,
- 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684, 0x0060, 0x00c0,
- 0x2eef, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2f68, 0xa684,
- 0x0800, 0x00c0, 0x2f11, 0x68b4, 0xa084, 0x4800, 0xa635, 0xa684,
- 0x0800, 0x00c0, 0x2f11, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x703c,
- 0xa005, 0x00c0, 0x2f09, 0x2200, 0xa105, 0x0040, 0x2f10, 0x703f,
- 0x0015, 0x7000, 0xa086, 0x0006, 0x0040, 0x2f10, 0x1078, 0x4887,
- 0x007c, 0xa684, 0x0020, 0x0040, 0x2f33, 0xa684, 0x4000, 0x0040,
- 0x2f1f, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2f09, 0x68b4,
- 0xa084, 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2f19, 0x703c,
- 0xa005, 0x00c0, 0x2f2d, 0x703f, 0x0015, 0x79d8, 0x7adc, 0x692e,
- 0x6a32, 0x0078, 0x2f09, 0xa684, 0x4000, 0x0040, 0x2f3d, 0x682f,
- 0x0000, 0x6833, 0x0000, 0x0078, 0x2f09, 0x68b4, 0xa084, 0x4800,
- 0xa635, 0xa684, 0x4000, 0x00c0, 0x2f37, 0x703c, 0xa005, 0x00c0,
- 0x2f4b, 0x703f, 0x0015, 0x79d8, 0x7adc, 0x78d0, 0x80fb, 0x00c8,
- 0x2f52, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x692e,
- 0x6a32, 0x2100, 0xa205, 0x00c0, 0x2f5f, 0x0078, 0x2f09, 0x7000,
- 0xa086, 0x0006, 0x0040, 0x2f68, 0x1078, 0x4c41, 0x0078, 0x2f09,
- 0x007c, 0x6008, 0xa085, 0x0200, 0x600a, 0xa384, 0x0200, 0x0040,
- 0x2f75, 0x6008, 0xa085, 0x0002, 0x600a, 0x681b, 0x0006, 0x688f,
- 0x0000, 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f,
- 0x0003, 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b,
- 0x0020, 0x68b3, 0x0000, 0x68af, 0x0000, 0x7000, 0x0079, 0x2f90,
- 0x2523, 0x2f9a, 0x2fa3, 0x2f98, 0x2f98, 0x2f98, 0x2f98, 0x2f98,
- 0x1078, 0x248c, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2fa3, 0x1078,
- 0x34a2, 0x0078, 0x2fa9, 0x7060, 0x2c50, 0x2060, 0x6800, 0x6002,
- 0x2a60, 0x2021, 0x525a, 0x2404, 0xa005, 0x0040, 0x2fb2, 0x2020,
- 0x0078, 0x2fab, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078, 0x34a9,
- 0x1078, 0x34b8, 0x6008, 0xa084, 0xfdff, 0x600a, 0x682b, 0x0000,
- 0x789b, 0x000e, 0x6f14, 0x6817, 0x0002, 0x1078, 0x4c89, 0xa684,
- 0x0800, 0x0040, 0x2fcf, 0x691c, 0xa18d, 0x2000, 0x691e, 0x6818,
- 0xa084, 0x8000, 0x0040, 0x2fdf, 0x7868, 0xa08c, 0x00ff, 0x0040,
- 0x2fdd, 0x681b, 0x001e, 0x0078, 0x2fdf, 0x681b, 0x0000, 0x2021,
- 0x525a, 0x2404, 0xad06, 0x0040, 0x2fe6, 0x7460, 0x6800, 0x2022,
- 0x68c3, 0x0000, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078, 0x1cdc,
- 0x0078, 0x2523, 0x1078, 0x2ee5, 0x682b, 0x0000, 0x2001, 0x000e,
- 0x6f14, 0x1078, 0x39e6, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xa084,
- 0x8000, 0x0040, 0x3005, 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e,
- 0x706f, 0x0000, 0x0078, 0x2523, 0x7000, 0xa005, 0x00c0, 0x3012,
- 0x0078, 0x2523, 0xa006, 0x1078, 0x4887, 0x6817, 0x0000, 0x681b,
- 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa085,
- 0x00ff, 0x6822, 0x7000, 0x0079, 0x3025, 0x2523, 0x302f, 0x302f,
- 0x3031, 0x3031, 0x3031, 0x3031, 0x302d, 0x1078, 0x248c, 0x1078,
- 0x34b8, 0x6008, 0xa084, 0xffef, 0x600a, 0x0078, 0x3472, 0x2300,
- 0x0079, 0x303a, 0x303d, 0x303f, 0x3098, 0x1078, 0x248c, 0xa684,
- 0x8000, 0x00c0, 0x307d, 0x7000, 0x0079, 0x3046, 0x2523, 0x3050,
- 0x3050, 0x306c, 0x3050, 0x3079, 0x306c, 0x304e, 0x1078, 0x248c,
- 0xa684, 0x0060, 0xa086, 0x0060, 0x00c0, 0x3068, 0xa6b4, 0xffdf,
- 0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a, 0x6eb6, 0x681c, 0xa084,
- 0xffdf, 0x681e, 0x1078, 0x4887, 0x1078, 0x4b4b, 0x0078, 0x3956,
- 0xa684, 0x2000, 0x0040, 0x305a, 0x6818, 0xa084, 0x8000, 0x0040,
- 0x3079, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040, 0x3079, 0x681b,
- 0x0007, 0x1078, 0x396a, 0x0078, 0x24fa, 0xa6b4, 0x7fff, 0x7e5a,
- 0x7adc, 0x79d8, 0x78d0, 0x79d2, 0x801b, 0x00c8, 0x3088, 0x8000,
- 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302,
- 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0065, 0x007c,
- 0x1078, 0x248c, 0x2300, 0x0079, 0x309d, 0x30a0, 0x30a2, 0x30eb,
- 0x1078, 0x248c, 0xa684, 0x8000, 0x00c0, 0x30da, 0x7000, 0x0079,
- 0x30a9, 0x2523, 0x30b3, 0x30b3, 0x30cf, 0x30b3, 0x30d6, 0x30cf,
- 0x30b1, 0x1078, 0x248c, 0xa684, 0x0060, 0xa086, 0x0060, 0x00c0,
- 0x30cb, 0xa6b4, 0xffbf, 0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a,
- 0x6eb6, 0x681c, 0xa084, 0xffbf, 0x681e, 0x1078, 0x4887, 0x1078,
- 0x4b4b, 0x0078, 0x3956, 0xa684, 0x2000, 0x0040, 0x30bd, 0x6818,
- 0xa084, 0x8000, 0x0040, 0x30d6, 0x681b, 0x0007, 0x781b, 0x00ca,
- 0x0078, 0x24fa, 0xa6b4, 0x7fff, 0x7e5a, 0x7adc, 0x79d8, 0x6b98,
- 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2,
- 0x781b, 0x0065, 0x007c, 0x6820, 0xa085, 0x0004, 0x6822, 0x1078,
- 0x3921, 0xa6b5, 0x0800, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x2300, 0x0079, 0x30fe, 0x3101, 0x3103,
- 0x3105, 0x1078, 0x248c, 0x0078, 0x377b, 0xa684, 0x0400, 0x00c0,
- 0x312e, 0x79e4, 0xa184, 0x0020, 0x0040, 0x3115, 0x78ec, 0xa084,
- 0x0003, 0x0040, 0x3115, 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab,
- 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, 0xa184, 0x0020, 0x0040,
- 0x3126, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x312a, 0x2001, 0x0014,
- 0x0078, 0x2da0, 0xa184, 0x0007, 0x0079, 0x3166, 0x7a90, 0xa294,
- 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, 0x0040, 0x3164, 0x789b,
- 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0, 0x3155, 0x7ba8, 0x7ba8,
- 0xa386, 0x0001, 0x00c0, 0x3148, 0x2009, 0xfff7, 0x0078, 0x314e,
- 0xa386, 0x0003, 0x00c0, 0x3155, 0x2009, 0xffef, 0x0c7e, 0x7054,
- 0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab,
- 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c,
- 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x3956, 0x2a3f, 0x2a4a,
- 0x3170, 0x3178, 0x316e, 0x316e, 0x3956, 0x3956, 0x1078, 0x248c,
- 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x3960,
- 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x3956,
- 0x79e4, 0xa184, 0x0030, 0x0040, 0x318a, 0x78ec, 0xa084, 0x0003,
- 0x00c0, 0x31b1, 0x7000, 0xa086, 0x0004, 0x00c0, 0x31a4, 0x706c,
- 0xa086, 0x0002, 0x00c0, 0x319a, 0x2011, 0x0002, 0x2019, 0x0000,
- 0x0078, 0x28e9, 0x706c, 0xa086, 0x0006, 0x0040, 0x3194, 0x706c,
- 0xa086, 0x0004, 0x0040, 0x3194, 0x7000, 0xa086, 0x0000, 0x0040,
- 0x24fa, 0x6818, 0xa085, 0x8000, 0x681a, 0x2001, 0x0014, 0x0078,
- 0x2da0, 0xa184, 0x0007, 0x0079, 0x31b5, 0x3956, 0x3956, 0x31bd,
- 0x3956, 0x39bb, 0x39bb, 0x3956, 0x3956, 0xa684, 0x0080, 0x0040,
- 0x31ec, 0x7194, 0x81ff, 0x0040, 0x31ec, 0xa182, 0x000d, 0x00d0,
- 0x31cd, 0x7097, 0x0000, 0x0078, 0x31d2, 0xa182, 0x000c, 0x7096,
- 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa, 0x157e, 0x137e, 0x147e,
- 0x7098, 0x8114, 0xa210, 0x729a, 0xa080, 0x000b, 0xad00, 0x2098,
- 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f,
- 0x137f, 0x157f, 0x0078, 0x3960, 0xa684, 0x0400, 0x00c0, 0x322d,
- 0x6820, 0xa084, 0x0001, 0x0040, 0x3960, 0xa68c, 0x0060, 0xa684,
- 0x0060, 0x0040, 0x3201, 0xa086, 0x0060, 0x00c0, 0x3201, 0xa18d,
- 0x4000, 0xa18c, 0xfffb, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab,
- 0x0000, 0x789b, 0x0061, 0x6818, 0xa085, 0x8000, 0x681a, 0x78aa,
- 0x8008, 0x810c, 0x0040, 0x34d1, 0xa18c, 0x00f8, 0x00c0, 0x34d1,
- 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8000,
- 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f,
- 0x6814, 0x8007, 0x7882, 0x0078, 0x3960, 0x6818, 0xa084, 0x8000,
- 0x0040, 0x3234, 0x681b, 0x0008, 0x781b, 0x00c0, 0x0078, 0x24fa,
- 0x2300, 0x0079, 0x323b, 0x3240, 0x32d4, 0x323e, 0x1078, 0x248c,
- 0x7000, 0xa084, 0x0007, 0x0079, 0x3245, 0x2523, 0x324f, 0x3284,
- 0x325a, 0x324d, 0x2523, 0x324d, 0x324d, 0x1078, 0x248c, 0x681c,
- 0xa084, 0x2000, 0x0040, 0x3268, 0x6008, 0xa085, 0x0002, 0x600a,
- 0x0078, 0x3268, 0x68c0, 0xa005, 0x00c0, 0x3284, 0x6920, 0xa18d,
- 0x0001, 0x6922, 0x68c3, 0x0001, 0x6800, 0x706a, 0x0078, 0x327e,
- 0x6920, 0xa18d, 0x0001, 0x6922, 0x6800, 0x6006, 0xa005, 0x00c0,
- 0x3272, 0x6002, 0x681c, 0xa084, 0x000e, 0x0040, 0x327e, 0x7014,
- 0x68ba, 0x7130, 0xa188, 0x7500, 0x0078, 0x3280, 0x2009, 0x7600,
- 0x2104, 0x6802, 0x2d0a, 0x7162, 0x6eb6, 0xa684, 0x0060, 0x0040,
- 0x32d2, 0xa684, 0x0800, 0x00c0, 0x3298, 0xa684, 0x7fff, 0x68b6,
- 0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078, 0x4887, 0x0078, 0x32d2,
- 0xa684, 0x0020, 0x0040, 0x32ad, 0x68c0, 0xa005, 0x0040, 0x32a4,
- 0x1078, 0x4c89, 0x0078, 0x32a7, 0xa006, 0x1078, 0x4c41, 0x79d8,
- 0x7adc, 0x69aa, 0x6aa6, 0x0078, 0x32b3, 0x1078, 0x38ca, 0x69aa,
- 0x6aa6, 0x1078, 0x4c41, 0xa684, 0x8000, 0x0040, 0x32d2, 0xa684,
- 0x7fff, 0x68b6, 0x7adc, 0x79d8, 0xa684, 0x0020, 0x00c0, 0x32ca,
- 0x78d0, 0x801b, 0x00c8, 0x32c5, 0x8000, 0xa084, 0x003f, 0xa108,
- 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
- 0xa303, 0x68ae, 0x0078, 0x2523, 0x0078, 0x377b, 0x7037, 0x0000,
- 0xa282, 0x0006, 0x0050, 0x32de, 0x1078, 0x248c, 0x7000, 0xa084,
- 0x0007, 0x10c0, 0x3a8c, 0x2300, 0x0079, 0x32e6, 0x32e9, 0x3312,
- 0x3326, 0x2200, 0x0079, 0x32ec, 0x3310, 0x377b, 0x32f2, 0x3310,
- 0x3342, 0x3384, 0x7003, 0x0005, 0x2001, 0x7710, 0x2068, 0x704a,
- 0x157e, 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x3302,
- 0x0078, 0x32fb, 0x157f, 0xad80, 0x0009, 0x7036, 0x6817, 0x0000,
- 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x0078, 0x376b,
- 0x1078, 0x248c, 0x7003, 0x0005, 0x2001, 0x7710, 0x2068, 0x704a,
- 0xad80, 0x0009, 0x7036, 0x2200, 0x0079, 0x331e, 0x377b, 0x3324,
- 0x3324, 0x3342, 0x3324, 0x377b, 0x1078, 0x248c, 0x7003, 0x0005,
- 0x2001, 0x7710, 0x2068, 0x704a, 0xad80, 0x0009, 0x7036, 0x2200,
- 0x0079, 0x3332, 0x333a, 0x3338, 0x3338, 0x333a, 0x3338, 0x333a,
- 0x1078, 0x248c, 0x1078, 0x379f, 0x782b, 0x3008, 0x781b, 0x0065,
- 0x0078, 0x24fa, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b,
- 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x7600, 0x2d04,
- 0x2d08, 0x7162, 0x2068, 0xa005, 0x0040, 0x335d, 0x6814, 0xa206,
- 0x0040, 0x3379, 0x6800, 0x0078, 0x3350, 0x7003, 0x0005, 0x2001,
- 0x7710, 0x2068, 0x704a, 0x7036, 0x157e, 0x20a9, 0x0031, 0x2003,
- 0x0000, 0x8000, 0x0070, 0x336e, 0x0078, 0x3367, 0x157f, 0xad80,
- 0x0009, 0x7036, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827,
- 0x0003, 0x6eb4, 0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040, 0x33d3,
- 0x1078, 0x3797, 0x0078, 0x33d3, 0x7003, 0x0002, 0x7a80, 0xa294,
- 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x79a8,
- 0x79a8, 0xa18c, 0x00ff, 0xa1e8, 0x7500, 0x2d04, 0x2d08, 0x7162,
- 0x2068, 0xa005, 0x0040, 0x33a3, 0x6814, 0xa206, 0x0040, 0x33be,
- 0x6800, 0x0078, 0x3396, 0x7003, 0x0005, 0x2001, 0x7710, 0x2068,
- 0x704a, 0x157e, 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070,
- 0x33b3, 0x0078, 0x33ac, 0x157f, 0xad80, 0x0009, 0x7036, 0x6a16,
- 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a,
- 0x6820, 0xa084, 0x0c00, 0x0040, 0x33d3, 0xa084, 0x0800, 0x0040,
- 0x33cd, 0x1078, 0x379b, 0x0078, 0x33d3, 0x1078, 0x3797, 0x708b,
- 0x0000, 0x0078, 0x33d3, 0x027e, 0x8207, 0xa084, 0x000f, 0x8003,
- 0x8003, 0x8003, 0xa080, 0x5480, 0x2060, 0x7056, 0x6000, 0x705a,
- 0x6004, 0x705e, 0xa684, 0x0060, 0x0040, 0x342b, 0x6b98, 0x6c94,
- 0x69ac, 0x68b0, 0xa105, 0x00c0, 0x340d, 0x7bd2, 0x7bda, 0x7cd6,
- 0x7cde, 0xa6b4, 0xb7ff, 0x7e5a, 0xa684, 0x0060, 0xa086, 0x0060,
- 0x0040, 0x342b, 0x68c0, 0xa005, 0x0040, 0x3406, 0x7003, 0x0003,
- 0x682b, 0x0000, 0x1078, 0x4b3a, 0x0078, 0x3408, 0x1078, 0x4b4b,
- 0xa6b5, 0x2000, 0x7e5a, 0x0078, 0x342b, 0x68b0, 0xa31a, 0x2100,
- 0xa423, 0x2400, 0xa305, 0x0040, 0x342b, 0x7bd2, 0x7bda, 0x7cd6,
- 0x7cde, 0x68b0, 0xa6b4, 0xbfff, 0x7e5a, 0x007e, 0x68c0, 0xa005,
- 0x007f, 0x0040, 0x3429, 0x7003, 0x0003, 0x1078, 0x4b3a, 0x0078,
- 0x342b, 0x1078, 0x4b96, 0x077f, 0x1078, 0x38bd, 0x2009, 0x0065,
- 0xa684, 0x0004, 0x0040, 0x344c, 0x78e4, 0xa084, 0x0030, 0x0040,
- 0x3444, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3444, 0x782b, 0x3008,
- 0x2009, 0x0065, 0x0078, 0x344c, 0x0f7e, 0x2079, 0x5200, 0x1078,
- 0x4887, 0x0f7f, 0x0040, 0x2523, 0x791a, 0x2d00, 0x704a, 0x8207,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x5480, 0x2048,
- 0x0078, 0x24fa, 0x6020, 0xa005, 0x0040, 0x3466, 0x8001, 0x6022,
- 0x6008, 0xa085, 0x0008, 0x600a, 0x7010, 0x6026, 0x007c, 0xa006,
- 0x1078, 0x4887, 0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040,
- 0x681f, 0x0100, 0x7000, 0xa084, 0x0007, 0x0079, 0x3477, 0x2523,
- 0x3481, 0x3481, 0x349e, 0x3489, 0x3487, 0x3489, 0x347f, 0x1078,
- 0x248c, 0x1078, 0x34a9, 0x1078, 0x34a2, 0x1078, 0x1cdc, 0x0078,
- 0x2523, 0x706c, 0x706f, 0x0000, 0x7093, 0x0000, 0x0079, 0x3490,
- 0x349a, 0x349a, 0x3498, 0x3498, 0x3498, 0x349a, 0x3498, 0x349a,
- 0x0079, 0x2902, 0x706f, 0x0000, 0x0078, 0x2523, 0x681b, 0x0000,
- 0x0078, 0x2fb6, 0x6800, 0xa005, 0x00c0, 0x34a7, 0x6002, 0x6006,
- 0x007c, 0x6010, 0xa005, 0x0040, 0x34b2, 0x8001, 0x00d0, 0x34b2,
- 0x1078, 0x248c, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x007c,
- 0x6018, 0xa005, 0x0040, 0x34be, 0x8001, 0x601a, 0x007c, 0x1078,
- 0x39e0, 0x681b, 0x0018, 0x0078, 0x34f5, 0x1078, 0x39e0, 0x681b,
- 0x0019, 0x0078, 0x34f5, 0x1078, 0x39e0, 0x681b, 0x001a, 0x0078,
- 0x34f5, 0x1078, 0x39e0, 0x681b, 0x0003, 0x0078, 0x34f5, 0x7780,
- 0x1078, 0x38bd, 0x7184, 0xa18c, 0x00ff, 0xa1e8, 0x7500, 0x2d04,
- 0x2d08, 0x2068, 0xa005, 0x00c0, 0x34e7, 0x0078, 0x2523, 0x6814,
- 0x7280, 0xa206, 0x0040, 0x34ef, 0x6800, 0x0078, 0x34e0, 0x6800,
- 0x200a, 0x681b, 0x0005, 0x708b, 0x0000, 0x1078, 0x34a9, 0x6820,
- 0xa084, 0x0001, 0x00c0, 0x34fe, 0x1078, 0x34a2, 0x1078, 0x34b8,
- 0x681f, 0x0000, 0x6823, 0x0020, 0x1078, 0x1cdc, 0x0078, 0x2523,
- 0xa282, 0x0003, 0x00c0, 0x376b, 0x7da8, 0xa5ac, 0x00ff, 0x7ca8,
- 0xa4a4, 0x00ff, 0x6920, 0xa18d, 0x0080, 0x6922, 0xa184, 0x0100,
- 0x0040, 0x356c, 0xa18c, 0xfeff, 0x6922, 0xa4a4, 0x00ff, 0x0040,
- 0x3556, 0xa482, 0x000c, 0x0048, 0x3529, 0x0040, 0x3529, 0x2021,
- 0x000c, 0x852b, 0x852b, 0x1078, 0x382e, 0x0040, 0x3533, 0x1078,
- 0x3627, 0x0078, 0x355f, 0x1078, 0x37e9, 0x0c7e, 0x2960, 0x6004,
- 0xa084, 0xfff5, 0x6006, 0x1078, 0x3652, 0x0c7f, 0x6920, 0xa18d,
- 0x0100, 0x6922, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400,
- 0x00c0, 0x3550, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x24fa,
- 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x24fa, 0x0c7e, 0x2960,
- 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3652, 0x0c7f, 0x7e58,
- 0xa684, 0x0400, 0x00c0, 0x3568, 0x781b, 0x0058, 0x0078, 0x24fa,
- 0x781b, 0x0065, 0x0078, 0x24fa, 0x0c7e, 0x7054, 0x2060, 0x6100,
- 0xa18c, 0x1000, 0x0040, 0x35ac, 0x6208, 0x8217, 0xa294, 0x00ff,
- 0xa282, 0x000c, 0x0048, 0x3580, 0x0040, 0x3580, 0x2011, 0x000c,
- 0x2400, 0xa202, 0x00c8, 0x3585, 0x2220, 0x6208, 0xa294, 0x00ff,
- 0x7018, 0xa086, 0x0028, 0x00c0, 0x3595, 0xa282, 0x0019, 0x00c8,
- 0x359b, 0x2011, 0x0019, 0x0078, 0x359b, 0xa282, 0x000c, 0x00c8,
- 0x359b, 0x2011, 0x000c, 0x2200, 0xa502, 0x00c8, 0x35a0, 0x2228,
- 0x1078, 0x37ed, 0x852b, 0x852b, 0x1078, 0x382e, 0x0040, 0x35ac,
- 0x1078, 0x3627, 0x0078, 0x35b0, 0x1078, 0x37e9, 0x1078, 0x3652,
- 0x7858, 0xa085, 0x0004, 0x785a, 0x0c7f, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x0c7e, 0x2960, 0x6000, 0xd0e4, 0x00c0,
- 0x35d5, 0xd0b4, 0x00c0, 0x35cf, 0x6010, 0xa084, 0x000f, 0x00c0,
- 0x35cf, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x0c7f, 0x007c, 0x2011,
- 0x0032, 0x2019, 0x0000, 0x0078, 0x35fc, 0x68a0, 0xa084, 0x0200,
- 0x00c0, 0x35cf, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086, 0x0028,
- 0x00c0, 0x35ea, 0xa282, 0x0019, 0x00c8, 0x35f0, 0x2011, 0x0019,
- 0x0078, 0x35f0, 0xa282, 0x000c, 0x00c8, 0x35f0, 0x2011, 0x000c,
- 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c, 0x0048, 0x35fc,
- 0x0040, 0x35fc, 0x2019, 0x000c, 0x78ab, 0x0001, 0x78ab, 0x0003,
- 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xa085,
- 0x0100, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0xa18c, 0xfff5,
- 0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3617, 0x78ab,
- 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0,
- 0x0005, 0x6820, 0xa085, 0x0100, 0x6822, 0x0c7f, 0x007c, 0x0c7e,
- 0x7154, 0x2160, 0x1078, 0x362e, 0x0c7f, 0x007c, 0x2008, 0xa084,
- 0xfff0, 0xa425, 0x7c86, 0x6018, 0x789a, 0x7cae, 0x6412, 0x78a4,
- 0xa084, 0xfff8, 0xa18c, 0x0007, 0xa105, 0x78a6, 0x6016, 0x788a,
- 0xa4a4, 0x000f, 0x8427, 0x8204, 0x8004, 0xa084, 0x00ff, 0xa405,
- 0x600e, 0x78ec, 0xd08c, 0x00c0, 0x3651, 0x6004, 0xa084, 0xfff5,
- 0x6006, 0x007c, 0x0c7e, 0x7054, 0x2060, 0x1078, 0x3659, 0x0c7f,
- 0x007c, 0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6, 0x6012,
- 0x7884, 0xa084, 0xfff0, 0x7886, 0x007c, 0xa282, 0x0002, 0x00c0,
- 0x376b, 0x7aa8, 0x6920, 0xa18d, 0x0080, 0x6922, 0xa184, 0x0200,
- 0x0040, 0x36ae, 0xa18c, 0xfdff, 0x6922, 0xa294, 0x00ff, 0xa282,
- 0x0002, 0x00c8, 0x376b, 0x1078, 0x36f9, 0x1078, 0x3652, 0xa980,
- 0x0001, 0x200c, 0x1078, 0x38b9, 0x1078, 0x35bb, 0x88ff, 0x0040,
- 0x36a1, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004,
- 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x369b, 0x782b, 0x3008, 0x781b,
- 0x0056, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078,
- 0x24fa, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x36aa, 0x781b, 0x0058,
- 0x0078, 0x24fa, 0x781b, 0x0065, 0x0078, 0x24fa, 0xa282, 0x0002,
- 0x00c8, 0x36b6, 0xa284, 0x0001, 0x0040, 0x36c0, 0x7154, 0xa188,
- 0x0000, 0x210c, 0xa18c, 0x2000, 0x00c0, 0x36c0, 0x2011, 0x0000,
- 0x1078, 0x37db, 0x1078, 0x36f9, 0x1078, 0x3652, 0x7858, 0xa085,
- 0x0004, 0x785a, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x24fa,
- 0x0c7e, 0x027e, 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x00c0,
- 0x36e9, 0xd0bc, 0x00c0, 0x36e7, 0x6014, 0xa084, 0x0040, 0x00c0,
- 0x36e7, 0xa18c, 0xffef, 0x6106, 0xa006, 0x0078, 0x36f6, 0x2011,
- 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa,
- 0xa8c0, 0x0004, 0x6820, 0xa085, 0x0200, 0x6822, 0x027f, 0x0c7f,
- 0x007c, 0x0c7e, 0x7054, 0x2060, 0x1078, 0x3700, 0x0c7f, 0x007c,
- 0x82ff, 0x0040, 0x3705, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002,
- 0x789a, 0x78a4, 0xa084, 0xffbf, 0xa205, 0x78a6, 0x788a, 0x6016,
- 0x78ec, 0xd08c, 0x00c0, 0x3718, 0x6004, 0xa084, 0xffef, 0x6006,
- 0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x3722, 0x007f,
- 0x0078, 0x3725, 0x007f, 0x0078, 0x3767, 0xa684, 0x0020, 0x0040,
- 0x3767, 0x7888, 0xa084, 0x0040, 0x0040, 0x3767, 0x7bb8, 0xa384,
- 0x003f, 0x831b, 0x00c8, 0x3735, 0x8000, 0xa005, 0x0040, 0x374b,
- 0x831b, 0x00c8, 0x373e, 0x8001, 0x0040, 0x3763, 0xa684, 0x4000,
- 0x0040, 0x374b, 0x78b8, 0x801b, 0x00c8, 0x3747, 0x8000, 0xa084,
- 0x003f, 0x00c0, 0x3763, 0xa6b4, 0xbfff, 0x7e5a, 0x79d8, 0x7adc,
- 0x2001, 0x0001, 0xa108, 0x00c8, 0x3757, 0xa291, 0x0000, 0x79d2,
- 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x4c41, 0x781b, 0x0064, 0x1078,
- 0x4ac6, 0x0078, 0x24fa, 0x781b, 0x0064, 0x0078, 0x24fa, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x1078, 0x37a3, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x6827, 0x0002, 0x1078, 0x3797, 0x78e4,
- 0xa084, 0x0030, 0x0040, 0x2523, 0x78ec, 0xa084, 0x0003, 0x0040,
- 0x2523, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x24fa, 0x2001,
- 0x0005, 0x0078, 0x37a5, 0x2001, 0x000c, 0x0078, 0x37a5, 0x2001,
- 0x0006, 0x0078, 0x37a5, 0x2001, 0x000d, 0x0078, 0x37a5, 0x2001,
- 0x0009, 0x0078, 0x37a5, 0x2001, 0x0007, 0x789b, 0x0010, 0x78aa,
- 0x789b, 0x0060, 0x78ab, 0x0001, 0xa6b5, 0x0004, 0x7e5a, 0x007c,
- 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0,
- 0x5480, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040,
- 0x37c9, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004, 0xa085, 0x0008,
- 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040, 0x0040,
- 0x37d9, 0xa184, 0xffbf, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0010,
- 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab,
- 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004,
- 0x007c, 0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab,
- 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b,
- 0x0060, 0x78ab, 0x0005, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff,
- 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0,
- 0x2001, 0x5246, 0x2004, 0xa082, 0x0028, 0x0040, 0x3817, 0x2021,
- 0x38a0, 0x2019, 0x0014, 0x20a9, 0x000c, 0x0078, 0x381d, 0x2021,
- 0x38ac, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064, 0x2404,
- 0xa084, 0xfff0, 0xa106, 0x0040, 0x382c, 0x8420, 0x2300, 0xa210,
- 0x0070, 0x382c, 0x0078, 0x381f, 0x157f, 0x007c, 0x157e, 0x2009,
- 0x5246, 0x210c, 0xa182, 0x0032, 0x0048, 0x3842, 0x0040, 0x3846,
- 0x2009, 0x3892, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032,
- 0x0078, 0x3858, 0xa182, 0x0028, 0x0040, 0x3850, 0x2009, 0x38a0,
- 0x2019, 0x0014, 0x20a9, 0x000c, 0x2011, 0x0064, 0x0078, 0x3858,
- 0x2009, 0x38ac, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064,
- 0x2200, 0xa502, 0x0040, 0x3868, 0x0048, 0x3868, 0x8108, 0x2300,
- 0xa210, 0x0070, 0x3865, 0x0078, 0x3858, 0x157f, 0xa006, 0x007c,
- 0x157f, 0xa582, 0x0064, 0x00c8, 0x3877, 0x7808, 0xa085, 0x0070,
- 0x780a, 0x7044, 0xa085, 0x0070, 0x7046, 0x0078, 0x3877, 0x78ec,
- 0xa084, 0x0300, 0x0040, 0x387f, 0x2104, 0x0078, 0x3890, 0x2104,
- 0xa09e, 0x1102, 0x00c0, 0x3890, 0x2001, 0x04fd, 0x2004, 0xa082,
- 0x0005, 0x0048, 0x388f, 0x2001, 0x1201, 0x0078, 0x3890, 0x2104,
- 0xa005, 0x007c, 0x1102, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404,
- 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, 0x0e07,
- 0x3202, 0x4202, 0x5202, 0x6202, 0x7202, 0x6605, 0x7605, 0x7805,
- 0x7a05, 0x7c05, 0x7e05, 0x7f05, 0x2202, 0x3202, 0x4202, 0x5202,
- 0x5404, 0x6404, 0x7404, 0x7604, 0x7804, 0x7a04, 0x7c04, 0x7e04,
- 0x7f04, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784, 0x0f00, 0x800b,
- 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e0,
- 0x5500, 0x007c, 0x79d8, 0x7adc, 0x78d0, 0x801b, 0x00c8, 0x38d1,
- 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x007c, 0x0f7e,
- 0x2079, 0x0100, 0x2009, 0x5240, 0x2091, 0x8000, 0x2104, 0x0079,
- 0x38e1, 0x3917, 0x38eb, 0x38eb, 0x38eb, 0x38eb, 0x38eb, 0x38eb,
- 0x391b, 0x1078, 0x248c, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
- 0x00c0, 0x38ed, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0,
- 0x38f4, 0x68b4, 0xa085, 0x4000, 0x68b6, 0x7858, 0xa085, 0x4000,
- 0x785a, 0x7830, 0xa084, 0x0080, 0x00c0, 0x3917, 0x0018, 0x3917,
- 0x681c, 0xa084, 0x0020, 0x00c0, 0x3915, 0x0e7e, 0x2071, 0x5240,
- 0x1078, 0x396a, 0x0e7f, 0x0078, 0x3917, 0x781b, 0x00ca, 0x2091,
- 0x8001, 0x0f7f, 0x007c, 0x70b3, 0x0000, 0x1078, 0x3b44, 0x0078,
- 0x3917, 0x0c7e, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003,
- 0x8003, 0xa0e0, 0x5480, 0x6004, 0xa084, 0x000a, 0x00c0, 0x3954,
- 0x6108, 0xa194, 0xff00, 0x0040, 0x3954, 0xa18c, 0x00ff, 0x2001,
- 0x0019, 0xa106, 0x0040, 0x3943, 0x2001, 0x0032, 0xa106, 0x0040,
- 0x3947, 0x0078, 0x394b, 0x2009, 0x0020, 0x0078, 0x394d, 0x2009,
- 0x003f, 0x0078, 0x394d, 0x2011, 0x0000, 0x2100, 0xa205, 0x600a,
- 0x6004, 0xa085, 0x0002, 0x6006, 0x0c7f, 0x007c, 0x781b, 0x0065,
- 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x24fa,
- 0x781b, 0x0058, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x0056,
- 0x0078, 0x24fa, 0x2009, 0x5220, 0x210c, 0xa186, 0x0000, 0x0040,
- 0x397e, 0xa186, 0x0001, 0x0040, 0x3981, 0x2009, 0x5238, 0x200b,
- 0x000b, 0x706f, 0x0001, 0x781b, 0x0048, 0x007c, 0x781b, 0x00c4,
- 0x007c, 0x2009, 0x5238, 0x200b, 0x000a, 0x007c, 0x2009, 0x5220,
- 0x210c, 0xa186, 0x0000, 0x0040, 0x39a1, 0xa186, 0x0001, 0x0040,
- 0x399b, 0x2009, 0x5238, 0x200b, 0x000b, 0x706f, 0x0001, 0x781b,
- 0x0048, 0x0078, 0x24fa, 0x2009, 0x5238, 0x200b, 0x000a, 0x0078,
- 0x24fa, 0x782b, 0x3008, 0x781b, 0x00c4, 0x0078, 0x24fa, 0x781b,
- 0x00ca, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x00ca, 0x0078,
- 0x24fa, 0x781b, 0x008f, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b,
- 0x008f, 0x0078, 0x24fa, 0x6818, 0xa084, 0x8000, 0x0040, 0x39c2,
- 0x681b, 0x001d, 0x706f, 0x0001, 0x781b, 0x0048, 0x0078, 0x24fa,
- 0x007e, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x39de, 0x7808, 0xa084,
- 0xfffc, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084,
- 0x0021, 0x0040, 0x39de, 0x7044, 0x780a, 0xa005, 0x007f, 0x007c,
- 0x7044, 0xa085, 0x0002, 0x7046, 0x780a, 0x007c, 0x007e, 0x7830,
- 0xa084, 0x0040, 0x00c0, 0x39e7, 0x0098, 0x39f2, 0x007f, 0x789a,
- 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005,
- 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, 0x3a01, 0x0098,
- 0x39ff, 0x007f, 0x789a, 0x78ac, 0x007e, 0x7044, 0x780a, 0x007f,
- 0x007c, 0x78ec, 0xa084, 0x0002, 0x00c0, 0x4871, 0xa784, 0x007d,
- 0x00c0, 0x3a15, 0x2700, 0x1078, 0x248c, 0xa784, 0x0001, 0x00c0,
- 0x300c, 0xa784, 0x0070, 0x0040, 0x3a25, 0x0c7e, 0x2d60, 0x2f68,
- 0x1078, 0x2437, 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040,
- 0x3a32, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2523,
- 0x0078, 0x3956, 0xa784, 0x0004, 0x0040, 0x3a65, 0x78b8, 0xa084,
- 0x4001, 0x0040, 0x3a65, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
- 0x0040, 0x2523, 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0,
- 0x3a65, 0x78c0, 0xa085, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00ca,
- 0x0078, 0x24fa, 0x784b, 0x0008, 0x6818, 0xa084, 0x8000, 0x0040,
- 0x3a61, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040, 0x3a61, 0x681b,
- 0x0007, 0x1078, 0x396a, 0x0078, 0x24fa, 0x681b, 0x0003, 0x7858,
- 0xa084, 0x3f00, 0x681e, 0x682f, 0x0000, 0x6833, 0x0000, 0x784b,
- 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2a06, 0x0018, 0x24fa,
- 0x0078, 0x3773, 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003,
- 0x8003, 0xa080, 0x5480, 0x2060, 0x2048, 0x7056, 0x6000, 0x705a,
- 0x6004, 0x705e, 0x2a60, 0x007c, 0x0079, 0x3a8e, 0x3a96, 0x3a97,
- 0x3a96, 0x3a99, 0x3a96, 0x3a96, 0x3a96, 0x3a9e, 0x007c, 0x1078,
- 0x34b8, 0x1078, 0x4887, 0x7038, 0x600a, 0x007c, 0x70a0, 0xa005,
- 0x0040, 0x3aab, 0x2068, 0x1078, 0x1bd3, 0x1078, 0x47fe, 0x1078,
- 0x4805, 0x70a3, 0x0000, 0x007c, 0x0e7e, 0x2091, 0x8000, 0x2071,
- 0x5240, 0x7000, 0xa086, 0x0007, 0x00c0, 0x3ac2, 0x6110, 0x70bc,
- 0xa106, 0x00c0, 0x3ac2, 0x0e7f, 0x1078, 0x1be0, 0x1078, 0x3ac8,
- 0xa006, 0x007c, 0x2091, 0x8001, 0x0e7f, 0xa085, 0x0001, 0x007c,
- 0x0f7e, 0x0e7e, 0x2071, 0x5240, 0x0078, 0x2297, 0x785b, 0x0000,
- 0x70af, 0x000e, 0x2009, 0x0100, 0x017e, 0x70a0, 0xa06d, 0x0040,
- 0x3add, 0x70a3, 0x0000, 0x0078, 0x3ae3, 0x70b3, 0x0000, 0x1078,
- 0x1c0c, 0x0040, 0x3ae9, 0x70ac, 0x6826, 0x1078, 0x3bc6, 0x0078,
- 0x3add, 0x017f, 0x157e, 0x0c7e, 0x0d7e, 0x20a9, 0x0008, 0x2061,
- 0x7610, 0x6000, 0xa105, 0x6002, 0x601c, 0xa06d, 0x0040, 0x3b01,
- 0x6800, 0x601e, 0x1078, 0x19ac, 0x6008, 0x8000, 0x600a, 0x0078,
- 0x3af4, 0x6018, 0xa06d, 0x0040, 0x3b0b, 0x6800, 0x601a, 0x1078,
- 0x19ac, 0x0078, 0x3b01, 0xace0, 0x0008, 0x0070, 0x3b11, 0x0078,
- 0x3af1, 0x709c, 0xa084, 0x8000, 0x0040, 0x3b18, 0x1078, 0x3c44,
- 0x0d7f, 0x0c7f, 0x157f, 0x007c, 0x127e, 0x2091, 0x2300, 0x6804,
- 0xa084, 0x000f, 0x0079, 0x3b24, 0x3b34, 0x3b34, 0x3b34, 0x3b34,
- 0x3b34, 0x3b34, 0x3b36, 0x3b3c, 0x3b34, 0x3b34, 0x3b34, 0x3b34,
- 0x3b34, 0x3b3e, 0x3b34, 0x3b36, 0x1078, 0x248c, 0x1078, 0x45d3,
- 0x1078, 0x19ac, 0x0078, 0x3b42, 0x6827, 0x000b, 0x1078, 0x45d3,
- 0x1078, 0x3bc6, 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x0098,
- 0x3b60, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3b60, 0x0d7e, 0x1078,
- 0x4812, 0x2d00, 0x682e, 0x2009, 0x0004, 0x2001, 0x0000, 0x6827,
- 0x0084, 0x1078, 0x47c7, 0x1078, 0x3bc6, 0x0d7f, 0x0078, 0x3b94,
- 0x7948, 0xa185, 0x4000, 0x784a, 0x0098, 0x3b69, 0x794a, 0x0078,
- 0x3b4e, 0x7828, 0xa086, 0x1834, 0x00c0, 0x3b72, 0xa185, 0x0004,
- 0x0078, 0x3b79, 0x7828, 0xa086, 0x1814, 0x00c0, 0x3b66, 0xa185,
- 0x000c, 0x784a, 0x789b, 0x000e, 0x78ab, 0x0002, 0x7858, 0xa084,
- 0x00ff, 0xa085, 0x0400, 0x785a, 0x70b4, 0xa080, 0x0091, 0x781a,
- 0x6827, 0x0284, 0x682c, 0x6836, 0x6830, 0x683a, 0x2009, 0x0004,
- 0x2001, 0x0000, 0x1078, 0x47c7, 0x127f, 0x007c, 0x0d7e, 0x6b14,
- 0x1078, 0x1c70, 0x0040, 0x3ba3, 0x2068, 0x6827, 0x0002, 0x1078,
- 0x3bc6, 0x0078, 0x3b98, 0x0d7f, 0x007c, 0x0d7e, 0x6b14, 0x6c28,
- 0xa4a4, 0x00ff, 0x1078, 0x1c1c, 0x0040, 0x3bb3, 0x2068, 0x6827,
- 0x0002, 0x1078, 0x3bc6, 0x0d7f, 0x007c, 0x0d7e, 0x6b14, 0xa39c,
- 0x00ff, 0x1078, 0x1c48, 0x0040, 0x3bc4, 0x2068, 0x6827, 0x0002,
- 0x1078, 0x3bc6, 0x0078, 0x3bb9, 0x0d7f, 0x007c, 0x0c7e, 0x6914,
- 0x1078, 0x3c3b, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0006, 0x0040,
- 0x3be1, 0xa186, 0x000d, 0x0040, 0x3c00, 0xa186, 0x0017, 0x00c0,
- 0x3bdd, 0x1078, 0x19ac, 0x0078, 0x3bdf, 0x1078, 0x1cde, 0x0c7f,
- 0x007c, 0x6004, 0x8001, 0x0048, 0x3bfe, 0x6006, 0x2009, 0x0000,
- 0xa684, 0x0001, 0x00c0, 0x3bee, 0xa18d, 0x8000, 0xa684, 0x0004,
- 0x0040, 0x3bf4, 0xa18d, 0x0002, 0x691e, 0x6823, 0x0000, 0x7104,
- 0x810f, 0x6818, 0xa105, 0x681a, 0x0078, 0x3bdd, 0x1078, 0x248c,
- 0x6018, 0xa005, 0x00c0, 0x3c0f, 0x6008, 0x8001, 0x0048, 0x3c0f,
- 0x600a, 0x601c, 0x6802, 0x2d00, 0x601e, 0x0078, 0x3c25, 0xac88,
- 0x0006, 0x2104, 0xa005, 0x0040, 0x3c18, 0x2008, 0x0078, 0x3c11,
- 0x6802, 0x2d0a, 0x6008, 0x8001, 0x0048, 0x3bdf, 0x600a, 0x6018,
- 0x2068, 0x6800, 0x601a, 0x0078, 0x3c09, 0x157e, 0x137e, 0x147e,
- 0x0c7e, 0x0d7e, 0x1078, 0x1989, 0x00c0, 0x3c30, 0x1078, 0x248c,
- 0x2da0, 0x137f, 0x20a9, 0x0031, 0x53a3, 0x0c7f, 0x147f, 0x137f,
- 0x157f, 0x0078, 0x3bdd, 0xa184, 0x001f, 0x8003, 0x8003, 0x8003,
- 0xa080, 0x7610, 0x2060, 0x007c, 0x2019, 0x5251, 0x2304, 0xa085,
- 0x0001, 0x201a, 0x2019, 0x0102, 0x2304, 0xa085, 0x0001, 0x201a,
- 0x007c, 0x2019, 0x5251, 0x2304, 0xa084, 0xfffe, 0x201a, 0x2019,
- 0x0102, 0x2304, 0xa084, 0xfffe, 0x201a, 0x007c, 0x7990, 0xa18c,
- 0xfff8, 0x7992, 0x70b4, 0xa080, 0x00d8, 0x781a, 0x0078, 0x24fa,
- 0x70a3, 0x0000, 0x7003, 0x0000, 0x7043, 0x0001, 0x7037, 0x0000,
- 0x0018, 0x24b1, 0x1078, 0x1c0c, 0x0040, 0x3c99, 0x2009, 0x520f,
- 0x200b, 0x0000, 0x68bc, 0x2060, 0x6100, 0xa184, 0x0300, 0x0040,
- 0x3c8d, 0x6827, 0x000e, 0xa084, 0x0200, 0x0040, 0x3c89, 0x6827,
- 0x0017, 0x1078, 0x3bc6, 0x0078, 0x3c68, 0x7000, 0xa086, 0x0007,
- 0x00c0, 0x3d0d, 0x2d00, 0x70a2, 0xad80, 0x000f, 0x7036, 0x0078,
- 0x3ca0, 0x7040, 0xa086, 0x0001, 0x0040, 0x2533, 0x0078, 0x24fa,
- 0x2031, 0x0000, 0x691c, 0xa184, 0x0002, 0x0040, 0x3ca9, 0xa6b5,
- 0x0004, 0xa184, 0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x3da6,
- 0x2004, 0xa635, 0x6820, 0xa084, 0x0400, 0x0040, 0x3cc1, 0x789b,
- 0x0018, 0x78ab, 0x0003, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5,
- 0x5000, 0x6820, 0xa084, 0x8000, 0x0040, 0x3ccf, 0xa6b5, 0x0400,
- 0x789b, 0x000e, 0x6824, 0x8007, 0x78aa, 0x0078, 0x3cef, 0x681c,
- 0xd0fc, 0x00c0, 0x3cdd, 0xa6b5, 0x0800, 0x6820, 0xd0c4, 0x0040,
- 0x3cef, 0xa6b5, 0x4000, 0x0078, 0x3cef, 0x6820, 0xd0c4, 0x0040,
- 0x3ce5, 0xa6b5, 0x4000, 0x0078, 0x3cef, 0x789b, 0x0018, 0x78ab,
- 0x0002, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5, 0x1000, 0xa684,
- 0x0200, 0x0040, 0x3d09, 0x682c, 0x78d2, 0x6830, 0x78d6, 0xa684,
- 0x0100, 0x0040, 0x3d07, 0x682c, 0xa084, 0x0001, 0x0040, 0x3d07,
- 0x7888, 0xa084, 0x0040, 0x0040, 0x3d07, 0xa6b5, 0x8000, 0x1078,
- 0x47f6, 0x7e5a, 0x6eb6, 0x0078, 0x4835, 0x1078, 0x39c8, 0x00c0,
- 0x3da0, 0x702c, 0x8004, 0x0048, 0x3d1b, 0x2019, 0x4f49, 0x1078,
- 0x2313, 0x702f, 0x0001, 0x2041, 0x0001, 0x2031, 0x1000, 0x789b,
- 0x0018, 0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x691c,
- 0xa184, 0x0002, 0x0040, 0x3d34, 0xa6b5, 0x0004, 0x78ab, 0x0020,
- 0x6828, 0x78aa, 0xa8c0, 0x0002, 0x681c, 0xd0f4, 0x0040, 0x3d3d,
- 0x2c50, 0x1078, 0x3a7a, 0x1078, 0x4702, 0x6820, 0xa084, 0x8000,
- 0x0040, 0x3d4b, 0xa6b5, 0x0400, 0x789b, 0x000e, 0x6824, 0x8007,
- 0x78aa, 0x0078, 0x3d52, 0x681c, 0xa084, 0x8000, 0x00c0, 0x3d52,
- 0xa6b5, 0x0800, 0x6820, 0xa084, 0x0100, 0x0040, 0x3d59, 0xa6b5,
- 0x4000, 0x681c, 0xa084, 0x00c0, 0x8003, 0x8003, 0x8007, 0xa080,
- 0x3da6, 0x2004, 0xa635, 0xa684, 0x0100, 0x0040, 0x3d73, 0x682c,
- 0xa084, 0x0001, 0x0040, 0x3d73, 0x7888, 0xa084, 0x0040, 0x0040,
- 0x3d73, 0xa6b5, 0x8000, 0x789b, 0x007e, 0x7eae, 0x6eb6, 0x6814,
- 0x8007, 0x78aa, 0x7882, 0x2810, 0x7aaa, 0x7830, 0xa084, 0x00c0,
- 0x00c0, 0x3da0, 0x0018, 0x3da0, 0x70b4, 0xa080, 0x00dd, 0x781a,
- 0x1078, 0x39e0, 0xa684, 0x0200, 0x0040, 0x3d94, 0x682c, 0x78d2,
- 0x6830, 0x78d6, 0x1078, 0x47f6, 0x2d00, 0x70a2, 0x704a, 0x6810,
- 0x70be, 0x7003, 0x0007, 0xad80, 0x000f, 0x7036, 0x0078, 0x24fa,
- 0x1078, 0x1bd3, 0x1078, 0x39e0, 0x0078, 0x24fa, 0x0000, 0x0300,
- 0x0200, 0x0000, 0x1078, 0x248c, 0x2300, 0x0079, 0x3daf, 0x3db2,
- 0x3db2, 0x3db4, 0x1078, 0x248c, 0x1078, 0x4805, 0x6924, 0xa184,
- 0x00ff, 0xa086, 0x000a, 0x0040, 0x3dc6, 0xa184, 0xff00, 0xa085,
- 0x000a, 0x6826, 0x1078, 0x1bd3, 0x0078, 0x3c68, 0x2001, 0x000a,
- 0x1078, 0x4797, 0x0078, 0x3c68, 0xa282, 0x0005, 0x0050, 0x3dd2,
- 0x1078, 0x248c, 0x7000, 0xa084, 0x0007, 0x10c0, 0x3a8c, 0x1078,
- 0x1989, 0x00c0, 0x3df4, 0x2069, 0xffff, 0xa684, 0x0004, 0x0040,
- 0x3de5, 0x2001, 0x2800, 0x0078, 0x3de7, 0x2001, 0x0800, 0x71b4,
- 0xa188, 0x0091, 0x789b, 0x000e, 0x8007, 0x78aa, 0x2031, 0x0400,
- 0x7e5a, 0x791a, 0x0078, 0x24fa, 0x6807, 0x0106, 0x680b, 0x0000,
- 0x689f, 0x0000, 0x6827, 0x0000, 0xa386, 0x0002, 0x00c0, 0x3e15,
- 0xa286, 0x0002, 0x00c0, 0x3e15, 0x78a0, 0xa005, 0x00c0, 0x3e15,
- 0xa484, 0x8000, 0x00c0, 0x3e15, 0x78e4, 0xa084, 0x0008, 0x0040,
- 0x3e15, 0xa6b5, 0x0008, 0x2019, 0x0000, 0x1078, 0x4217, 0x2d00,
- 0x70a2, 0x704a, 0x7003, 0x0007, 0x7037, 0x0000, 0x6824, 0xa084,
- 0x0080, 0x0040, 0x3e27, 0x1078, 0x42cd, 0x0078, 0x24fa, 0x2300,
- 0x0079, 0x3e2a, 0x3e2d, 0x3eae, 0x3ec7, 0x2200, 0x0079, 0x3e30,
- 0x3e35, 0x3e45, 0x3e6b, 0x3e77, 0x3e9a, 0x2029, 0x0001, 0xa026,
- 0x2011, 0x0000, 0x1078, 0x43f3, 0x0079, 0x3e3e, 0x3e43, 0x24fa,
- 0x3c68, 0x3e43, 0x3e43, 0x1078, 0x248c, 0x7990, 0xa18c, 0x0007,
- 0x00c0, 0x3e4c, 0x2009, 0x0008, 0x2011, 0x0001, 0xa684, 0x0004,
- 0x0040, 0x3e54, 0x2011, 0x0003, 0x2220, 0xa12a, 0x2011, 0x0001,
- 0x1078, 0x43f3, 0x0079, 0x3e5c, 0x3e61, 0x24fa, 0x3c68, 0x3e69,
- 0x3e63, 0x0078, 0x483b, 0x70ab, 0x3e67, 0x0078, 0x24fa, 0x0078,
- 0x3e61, 0x1078, 0x248c, 0xa684, 0x0010, 0x0040, 0x3e75, 0x1078,
- 0x429c, 0x0040, 0x3e75, 0x0078, 0x24fa, 0x0078, 0x430d, 0x6000,
- 0xa084, 0x0002, 0x0040, 0x3e94, 0x70b4, 0xa080, 0x00cd, 0x781a,
- 0x0d7e, 0x1078, 0x4812, 0x2d00, 0x682e, 0x6827, 0x0000, 0x1078,
- 0x3bc6, 0x0d7f, 0x1078, 0x19ac, 0x7003, 0x0000, 0x7037, 0x0000,
- 0x704b, 0x0000, 0x0078, 0x3c68, 0xa684, 0x0004, 0x00c0, 0x3e9a,
- 0x0078, 0x483b, 0x6000, 0xa084, 0x0004, 0x00c0, 0x3eac, 0x6000,
- 0xa084, 0x0001, 0x0040, 0x3eac, 0x70ab, 0x3eac, 0x2001, 0x0007,
- 0x1078, 0x478f, 0x0078, 0x4841, 0x0078, 0x483b, 0x2200, 0x0079,
- 0x3eb1, 0x3eb6, 0x3eb8, 0x3eb6, 0x3eb6, 0x3eb6, 0x1078, 0x248c,
- 0x70a7, 0x3ebc, 0x0078, 0x4847, 0x78e4, 0xa084, 0x0008, 0x00c0,
- 0x3eb8, 0x1078, 0x4781, 0x70ab, 0x3ec5, 0x0078, 0x483b, 0x2200,
- 0x0079, 0x3eca, 0x3ecf, 0x3ed1, 0x3ed1, 0x3ecf, 0x3ecf, 0x1078,
- 0x248c, 0x78e4, 0xa084, 0x0008, 0x0040, 0x3ee6, 0x70a7, 0x3eda,
- 0x0078, 0x4847, 0x2011, 0x0004, 0x1078, 0x43ed, 0x0079, 0x3ee0,
- 0x3ee6, 0x24fa, 0x3c68, 0x3ee6, 0x3ef0, 0x3ef4, 0x70ab, 0x3eee,
- 0x2001, 0x0003, 0x1078, 0x478f, 0x0078, 0x4841, 0x0078, 0x483b,
- 0x70ab, 0x3ee6, 0x0078, 0x24fa, 0x70ab, 0x3ef8, 0x0078, 0x24fa,
- 0x0078, 0x3eee, 0xa282, 0x0003, 0x0050, 0x3f00, 0x1078, 0x248c,
- 0xa386, 0x0002, 0x00c0, 0x3f19, 0xa286, 0x0002, 0x00c0, 0x3f1f,
- 0x78a0, 0xa005, 0x00c0, 0x3f1f, 0xa484, 0x8000, 0x00c0, 0x3f1f,
- 0x78e4, 0xa084, 0x0008, 0x0040, 0x3f19, 0xa6b5, 0x0008, 0x2019,
- 0x0000, 0xa684, 0x0008, 0x0040, 0x3f1f, 0x1078, 0x4279, 0x6810,
- 0x70be, 0x7003, 0x0007, 0x2300, 0x0079, 0x3f26, 0x3f29, 0x3f56,
- 0x3f5e, 0x2200, 0x0079, 0x3f2c, 0x3f31, 0x3f2f, 0x3f4a, 0x1078,
- 0x248c, 0x7990, 0xa1ac, 0x0007, 0xa026, 0x2011, 0x0001, 0x1078,
- 0x43f3, 0x0079, 0x3f3b, 0x3f40, 0x24fa, 0x3c68, 0x3f48, 0x3f42,
- 0x0078, 0x483b, 0x70ab, 0x3f46, 0x0078, 0x24fa, 0x0078, 0x3f40,
- 0x1078, 0x248c, 0xa684, 0x0010, 0x0040, 0x3f54, 0x1078, 0x429c,
- 0x0040, 0x3f54, 0x0078, 0x24fa, 0x0078, 0x430d, 0x2200, 0x0079,
- 0x3f59, 0x3f5c, 0x3f5c, 0x3f5c, 0x1078, 0x248c, 0x2200, 0x0079,
- 0x3f61, 0x3f64, 0x3f66, 0x3f66, 0x1078, 0x248c, 0x78e4, 0xa084,
- 0x0008, 0x0040, 0x3f7b, 0x70a7, 0x3f6f, 0x0078, 0x4847, 0x2011,
- 0x0004, 0x1078, 0x43ed, 0x0079, 0x3f75, 0x3f7b, 0x24fa, 0x3c68,
- 0x3f7b, 0x3f85, 0x3f89, 0x70ab, 0x3f83, 0x2001, 0x0003, 0x1078,
- 0x478f, 0x0078, 0x4841, 0x0078, 0x483b, 0x70ab, 0x3f7b, 0x0078,
- 0x24fa, 0x70ab, 0x3f8d, 0x0078, 0x24fa, 0x0078, 0x3f83, 0x2300,
- 0x0079, 0x3f92, 0x3f97, 0x3f99, 0x3f95, 0x1078, 0x248c, 0x70a4,
- 0x007a, 0x70a4, 0x007a, 0xa282, 0x0002, 0x0050, 0x3fa1, 0x1078,
- 0x248c, 0xa684, 0x0200, 0x0040, 0x3fab, 0x1078, 0x47fe, 0x1078,
- 0x43d5, 0x1078, 0x4805, 0x2300, 0x0079, 0x3fae, 0x3fb1, 0x3fd9,
- 0x403f, 0xad86, 0xffff, 0x0040, 0x3c68, 0xa286, 0x0001, 0x0040,
- 0x3fbb, 0x1078, 0x248c, 0xa684, 0x0200, 0x0040, 0x3fc3, 0x1078,
- 0x47fe, 0x1078, 0x4805, 0x2001, 0x0001, 0x1078, 0x4797, 0x78b8,
- 0xa084, 0xc001, 0x0040, 0x3fd5, 0x7848, 0xa085, 0x0008, 0x784a,
- 0x7848, 0xa084, 0x0008, 0x00c0, 0x3fd0, 0x7003, 0x0000, 0x0078,
- 0x3c68, 0x2200, 0x0079, 0x3fdc, 0x3fde, 0x400f, 0x70a7, 0x3fe2,
- 0x0078, 0x4847, 0x2011, 0x000d, 0x1078, 0x43ed, 0x0079, 0x3fe8,
- 0x3fef, 0x24fa, 0x3c68, 0x3ff7, 0x3fff, 0x4005, 0x4007, 0xa6b4,
- 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0xa6b4,
- 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0x70ab,
- 0x4003, 0x0078, 0x24fa, 0x0078, 0x3fef, 0x1078, 0x248c, 0x70ab,
- 0x400b, 0x0078, 0x24fa, 0x1078, 0x484d, 0x0078, 0x24fa, 0x70a7,
- 0x4013, 0x0078, 0x4847, 0x2011, 0x0012, 0x1078, 0x43ed, 0x0079,
- 0x4019, 0x401f, 0x24fa, 0x3c68, 0x402b, 0x4033, 0x4039, 0xa6b4,
- 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x70b4, 0xa080, 0x00aa,
- 0x781a, 0x0078, 0x24fa, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6,
- 0x7e5a, 0x0078, 0x4835, 0x70ab, 0x4037, 0x0078, 0x24fa, 0x0078,
- 0x401f, 0x70ab, 0x403d, 0x0078, 0x24fa, 0x0078, 0x402b, 0xa286,
- 0x0001, 0x0040, 0x4045, 0x1078, 0x248c, 0x70a7, 0x4049, 0x0078,
- 0x4847, 0x2011, 0x0015, 0x1078, 0x43ed, 0x0079, 0x404f, 0x4054,
- 0x24fa, 0x3c68, 0x4062, 0x406e, 0xa6b4, 0x00ff, 0xa6b5, 0x0400,
- 0x6eb6, 0x7e5a, 0x783b, 0x1301, 0x70b4, 0xa080, 0x00b5, 0x781a,
- 0x0078, 0x24fa, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
- 0x70b4, 0xa080, 0x00aa, 0x781a, 0x0078, 0x24fa, 0x70ab, 0x4072,
- 0x0078, 0x24fa, 0x0078, 0x4054, 0xa282, 0x0003, 0x0050, 0x407a,
- 0x1078, 0x248c, 0x2300, 0x0079, 0x407d, 0x4080, 0x40b7, 0x4114,
- 0xa286, 0x0001, 0x0040, 0x4086, 0x1078, 0x248c, 0x6804, 0xa084,
- 0x00ff, 0xa086, 0x0006, 0x00c0, 0x4093, 0x1078, 0x3bc6, 0x7003,
- 0x0000, 0x0078, 0x3c68, 0x683b, 0x0000, 0x6837, 0x0000, 0xa684,
- 0x0200, 0x0040, 0x40a1, 0x1078, 0x47fe, 0x1078, 0x43d5, 0x1078,
- 0x4805, 0x2001, 0x0001, 0x1078, 0x4797, 0x78b8, 0xa084, 0xc001,
- 0x0040, 0x40b3, 0x7848, 0xa085, 0x0008, 0x784a, 0x7848, 0xa084,
- 0x0008, 0x00c0, 0x40ae, 0x7003, 0x0000, 0x0078, 0x3c68, 0x2200,
- 0x0079, 0x40ba, 0x40bc, 0x40ef, 0x70a7, 0x40c0, 0x0078, 0x4847,
- 0x2011, 0x000d, 0x1078, 0x43ed, 0x0079, 0x40c6, 0x40cd, 0x24fa,
- 0x3c68, 0x40d5, 0x40dd, 0x40e3, 0x40e5, 0xa6b4, 0x00ff, 0xa6b5,
- 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0xa6b4, 0x00ff, 0xa6b5,
- 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0x70ab, 0x40e1, 0x0078,
- 0x24fa, 0x0078, 0x40cd, 0x1078, 0x248c, 0x70ab, 0x40eb, 0x1078,
- 0x4805, 0x0078, 0x24fa, 0x1078, 0x484d, 0x0078, 0x24fa, 0x70a7,
- 0x40f3, 0x0078, 0x4847, 0x2011, 0x0005, 0x1078, 0x43ed, 0x0079,
- 0x40f9, 0x40fe, 0x24fa, 0x3c68, 0x4106, 0x410e, 0xa6b4, 0x00ff,
- 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0xa6b4, 0x00ff,
- 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0x70ab, 0x4112,
- 0x0078, 0x24fa, 0x0078, 0x40fe, 0xa286, 0x0001, 0x0040, 0x411a,
- 0x1078, 0x248c, 0x70a7, 0x411e, 0x0078, 0x4847, 0x2011, 0x0006,
- 0x1078, 0x43ed, 0x0079, 0x4124, 0x4129, 0x24fa, 0x3c68, 0x412f,
- 0x4139, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0xa6b4,
- 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0xa6b5, 0x4000, 0x7e5a, 0x0078,
- 0x4835, 0x70ab, 0x413d, 0x0078, 0x24fa, 0x0078, 0x4129, 0x2300,
- 0x0079, 0x4142, 0x4147, 0x4145, 0x4145, 0x1078, 0x248c, 0x1078,
- 0x248c, 0x2300, 0x71a8, 0xa005, 0x017a, 0x6810, 0x70be, 0xa282,
- 0x0003, 0x0050, 0x4155, 0x1078, 0x248c, 0x2300, 0x0079, 0x4158,
- 0x415b, 0x4169, 0x418b, 0xa684, 0x0200, 0x0040, 0x4163, 0x1078,
- 0x47fe, 0x1078, 0x4805, 0x2001, 0x0001, 0x1078, 0x4797, 0x0078,
- 0x24fa, 0xa296, 0x0002, 0x0040, 0x4172, 0x82ff, 0x0040, 0x4172,
- 0x1078, 0x248c, 0x70a7, 0x4176, 0x0078, 0x4847, 0x2011, 0x0018,
- 0x1078, 0x43ed, 0x0079, 0x417c, 0x4181, 0x24fa, 0x3c68, 0x4183,
- 0x4185, 0x0078, 0x4835, 0x0078, 0x4835, 0x70ab, 0x4189, 0x0078,
- 0x24fa, 0x0078, 0x4181, 0x2200, 0x0079, 0x418e, 0x4190, 0x41a9,
- 0x70a7, 0x4194, 0x0078, 0x4847, 0x2011, 0x0017, 0x1078, 0x43ed,
- 0x0079, 0x419a, 0x419f, 0x24fa, 0x3c68, 0x41a1, 0x41a3, 0x0078,
- 0x4835, 0x0078, 0x4835, 0x70ab, 0x41a7, 0x0078, 0x24fa, 0x0078,
- 0x419f, 0xa484, 0x8000, 0x00c0, 0x4205, 0xa684, 0x0100, 0x0040,
- 0x41b5, 0x1078, 0x47fe, 0x1078, 0x43d5, 0x78d8, 0x78d2, 0x78dc,
- 0x78d6, 0xa6b4, 0xefff, 0x7e5a, 0x70a7, 0x41c0, 0x0078, 0x4847,
- 0x2011, 0x000d, 0x1078, 0x43ed, 0x0079, 0x41c6, 0x41cd, 0x24fa,
- 0x3c68, 0x41cd, 0x41f3, 0x41f9, 0x41fb, 0x78d8, 0x79dc, 0xa105,
- 0x00c0, 0x41df, 0x78b8, 0xa084, 0x001f, 0x00c0, 0x41df, 0x70b3,
- 0x0000, 0x7858, 0xa084, 0xfdff, 0x785a, 0x0078, 0x4835, 0xa684,
- 0x0100, 0x0040, 0x41f1, 0x7848, 0xa085, 0x0008, 0x784a, 0x1078,
- 0x47bc, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x70b3, 0x0000, 0x1078,
- 0x47f6, 0x0078, 0x4835, 0x70ab, 0x41f7, 0x0078, 0x24fa, 0x0078,
- 0x41cd, 0x1078, 0x248c, 0x70ab, 0x4201, 0x1078, 0x4805, 0x0078,
- 0x24fa, 0x1078, 0x484d, 0x0078, 0x24fa, 0x1078, 0x4805, 0x70ab,
- 0x420f, 0x2001, 0x0003, 0x1078, 0x478f, 0x0078, 0x4841, 0x1078,
- 0x47f6, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x0078, 0x4835, 0x70b8,
- 0x6812, 0x70be, 0x8000, 0x70ba, 0x681b, 0x0000, 0xa684, 0x0008,
- 0x0040, 0x423a, 0x157e, 0x137e, 0x147e, 0x7890, 0x8004, 0x8004,
- 0x8004, 0x8004, 0xa084, 0x000f, 0x681a, 0x80ac, 0x789b, 0x0000,
- 0xaf80, 0x002b, 0x2098, 0xad80, 0x000b, 0x20a0, 0x53a5, 0x147f,
- 0x137f, 0x157f, 0xa6c4, 0x0f00, 0xa684, 0x0002, 0x00c0, 0x4249,
- 0x692c, 0x810d, 0x810d, 0x810d, 0xa184, 0x0007, 0x2008, 0x0078,
- 0x425c, 0x789b, 0x0010, 0x79ac, 0xa184, 0x0020, 0x0040, 0x425c,
- 0x017e, 0x2009, 0x0005, 0x2001, 0x3d00, 0x1078, 0x47c7, 0x6824,
- 0xa085, 0x003b, 0x6826, 0x017f, 0xa184, 0x001f, 0xa805, 0x6816,
- 0x1078, 0x3c3b, 0x68be, 0xa684, 0x0004, 0x0040, 0x426d, 0xa18c,
- 0xff00, 0x78a8, 0xa084, 0x00ff, 0xa105, 0x682a, 0xa6b4, 0x00ff,
- 0x6000, 0xa084, 0x0008, 0x0040, 0x4277, 0xa6b5, 0x4000, 0x6eb6,
- 0x007c, 0x157e, 0x137e, 0x147e, 0x6918, 0x7890, 0x8004, 0x8004,
- 0x8004, 0x8004, 0xa084, 0x000f, 0x007e, 0xa100, 0x681a, 0x007f,
- 0x8000, 0x8004, 0x0040, 0x4298, 0x20a8, 0x8104, 0xa080, 0x000b,
- 0xad00, 0x20a0, 0x789b, 0x0000, 0xaf80, 0x002b, 0x2098, 0x53a5,
- 0x147f, 0x137f, 0x157f, 0x007c, 0x682c, 0xa084, 0x0020, 0x00c0,
- 0x42a4, 0x620c, 0x0078, 0x42a5, 0x6210, 0x6b18, 0x2300, 0xa202,
- 0x0040, 0x42c5, 0x2018, 0xa382, 0x000e, 0x0048, 0x42b5, 0x0040,
- 0x42b5, 0x2019, 0x000e, 0x0078, 0x42b9, 0x7858, 0xa084, 0xffef,
- 0x785a, 0x783b, 0x1b01, 0x7893, 0x0000, 0x7ba2, 0x70b4, 0xa080,
- 0x008e, 0x781a, 0xa085, 0x0001, 0x007c, 0x7858, 0xa084, 0xffef,
- 0x785a, 0x7893, 0x0000, 0xa006, 0x007c, 0x6904, 0xa18c, 0x00ff,
- 0xa196, 0x0007, 0x0040, 0x42da, 0xa196, 0x000f, 0x0040, 0x42da,
- 0x6807, 0x0117, 0x6914, 0x1078, 0x3c3b, 0x6100, 0x8104, 0x00c8,
- 0x42f5, 0x601c, 0xa005, 0x0040, 0x42e9, 0x2001, 0x0800, 0x0078,
- 0x42f7, 0x0d7e, 0x6824, 0x007e, 0x1078, 0x4812, 0x007f, 0x6826,
- 0x2d00, 0x682e, 0x1078, 0x3bc6, 0x0d7f, 0x2001, 0x0200, 0x6924,
- 0xa18c, 0x00ff, 0xa10d, 0x6926, 0x8007, 0x789b, 0x000e, 0x78aa,
- 0x6820, 0xa085, 0x8000, 0x6822, 0x2031, 0x0400, 0x6eb6, 0x7e5a,
- 0x71b4, 0xa188, 0x0091, 0x791a, 0x007c, 0xa6c4, 0x0f00, 0xa684,
- 0x0002, 0x00c0, 0x4321, 0x692c, 0x810d, 0x810d, 0x810d, 0xa184,
- 0x0007, 0x2008, 0xa805, 0x6816, 0x1078, 0x3c3b, 0x68be, 0x0078,
- 0x4324, 0x6914, 0x1078, 0x3c3b, 0x6100, 0x8104, 0x00c8, 0x4382,
- 0xa184, 0x0300, 0x0040, 0x4330, 0x6807, 0x0117, 0x0078, 0x434e,
- 0x6004, 0xa005, 0x00c0, 0x4357, 0x6807, 0x0117, 0x601c, 0xa005,
- 0x00c0, 0x4344, 0x0d7e, 0x1078, 0x4812, 0x6827, 0x0034, 0x2d00,
- 0x682e, 0x1078, 0x3bc6, 0x0d7f, 0xa684, 0x0004, 0x0040, 0x434e,
- 0x2031, 0x0400, 0x2001, 0x2800, 0x0078, 0x4352, 0x2031, 0x0400,
- 0x2001, 0x0800, 0x71b4, 0xa188, 0x0091, 0x0078, 0x43b0, 0x6018,
- 0xa005, 0x00c0, 0x4344, 0x601c, 0xa005, 0x00c0, 0x4344, 0x689f,
- 0x0000, 0x6827, 0x003d, 0xa684, 0x0001, 0x0040, 0x43be, 0xd694,
- 0x00c0, 0x437b, 0x6100, 0xd1d4, 0x0040, 0x437b, 0x692c, 0xa18c,
- 0x00ff, 0x0040, 0x43be, 0xa186, 0x0003, 0x0040, 0x43be, 0xa186,
- 0x0012, 0x0040, 0x43be, 0xa6b5, 0x0800, 0x71b4, 0xa188, 0x00ae,
- 0x0078, 0x43b9, 0x6807, 0x0117, 0x2031, 0x0400, 0x692c, 0xa18c,
- 0x00ff, 0xa186, 0x0012, 0x00c0, 0x4393, 0x2001, 0x43cb, 0x2009,
- 0x0001, 0x0078, 0x43a4, 0xa186, 0x0003, 0x00c0, 0x439d, 0x2001,
- 0x43cc, 0x2009, 0x0012, 0x0078, 0x43a4, 0x2001, 0x0200, 0x71b4,
- 0xa188, 0x0091, 0x0078, 0x43b0, 0x1078, 0x47e1, 0x78a3, 0x0000,
- 0x681c, 0xa085, 0x0040, 0x681e, 0x71b4, 0xa188, 0x00da, 0xa006,
- 0x6826, 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000,
- 0x6822, 0x6eb6, 0x7e5a, 0x791a, 0x0078, 0x24fa, 0x6eb6, 0x1078,
- 0x3bc6, 0x6810, 0x70be, 0x7003, 0x0007, 0x70a3, 0x0000, 0x704b,
- 0x0000, 0x0078, 0x24fa, 0x0023, 0x0070, 0x0005, 0x0000, 0x0a00,
- 0x0000, 0x0000, 0x0025, 0x0000, 0x0000, 0x683b, 0x0000, 0x6837,
- 0x0000, 0xa684, 0x0200, 0x0040, 0x43ec, 0x78b8, 0xa08c, 0x001f,
- 0xa084, 0x8000, 0x0040, 0x43e5, 0x8108, 0x78d8, 0xa100, 0x6836,
- 0x78dc, 0xa081, 0x0000, 0x683a, 0x007c, 0x7990, 0x810f, 0xa5ac,
- 0x0007, 0x2021, 0x0000, 0xa480, 0x0010, 0x789a, 0x79a8, 0xa18c,
- 0x00ff, 0xa184, 0x0080, 0x00c0, 0x441b, 0xa182, 0x0020, 0x00c8,
- 0x4439, 0xa182, 0x0012, 0x00c8, 0x4781, 0x2100, 0x1079, 0x4409,
- 0x007c, 0x4781, 0x45eb, 0x4781, 0x4781, 0x4446, 0x4449, 0x4483,
- 0x44b9, 0x44ed, 0x44f0, 0x4781, 0x4781, 0x44a4, 0x4514, 0x454e,
- 0x4781, 0x4781, 0x4574, 0xa184, 0x0020, 0x00c0, 0x45a8, 0xa18c,
- 0x001f, 0x6814, 0xa084, 0x001f, 0xa106, 0x0040, 0x4436, 0x70b4,
- 0xa080, 0x00cd, 0x781a, 0x2001, 0x0014, 0x1078, 0x4797, 0x1078,
- 0x4805, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x2001, 0x0000,
- 0x007c, 0xa182, 0x0024, 0x00c8, 0x4781, 0xa184, 0x0003, 0x1079,
- 0x4409, 0x007c, 0x4781, 0x4781, 0x4781, 0x4781, 0x1078, 0x4781,
- 0x007c, 0x2200, 0x0079, 0x444c, 0x4577, 0x4577, 0x4470, 0x4470,
- 0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 0x446e, 0x4470,
- 0x4465, 0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 0x4478, 0x447b,
- 0x4577, 0x447b, 0x4470, 0x4470, 0x4470, 0x0c7e, 0x077e, 0x6f14,
- 0x1078, 0x37b0, 0x077f, 0x0c7f, 0x0078, 0x4470, 0x1078, 0x468e,
- 0x6827, 0x02b3, 0x2009, 0x000b, 0x2001, 0x4800, 0x0078, 0x45ab,
- 0x1078, 0x4773, 0x007c, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001,
- 0x4800, 0x0078, 0x4593, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086,
- 0x0006, 0x00c0, 0x448d, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078,
- 0x4812, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078,
- 0x3b96, 0x1078, 0x45d3, 0x2b68, 0x1078, 0x3bc6, 0x0d7f, 0x1078,
- 0x3bc6, 0x2001, 0x0002, 0x007c, 0x1078, 0x45d3, 0x2001, 0x0017,
- 0x1078, 0x4797, 0x70a3, 0x0000, 0x2009, 0x5238, 0x200b, 0x0006,
- 0x70af, 0x0017, 0x2009, 0x0200, 0x1078, 0x3ad4, 0x2001, 0x0001,
- 0x007c, 0x2200, 0x0079, 0x44bc, 0x4577, 0x45a8, 0x45a8, 0x45a8,
- 0x44dd, 0x45ba, 0x44e5, 0x45ba, 0x45ba, 0x45bd, 0x45bd, 0x45c2,
- 0x45c2, 0x44d5, 0x44d5, 0x45a8, 0x45a8, 0x45ba, 0x45a8, 0x44e5,
- 0x4577, 0x44e5, 0x44e5, 0x44e5, 0x44e5, 0x6827, 0x0084, 0x2009,
- 0x000b, 0x2001, 0x4300, 0x0078, 0x45cc, 0x6827, 0x000d, 0x2009,
- 0x000b, 0x2001, 0x4300, 0x0078, 0x45ab, 0x6827, 0x0093, 0x2009,
- 0x000b, 0x2001, 0x4300, 0x0078, 0x4593, 0x2001, 0x0000, 0x007c,
- 0x2200, 0x0079, 0x44f3, 0x4577, 0x450c, 0x450c, 0x450c, 0x450c,
- 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba,
- 0x450c, 0x450c, 0x450c, 0x450c, 0x45ba, 0x450c, 0x450c, 0x45ba,
- 0x45ba, 0x45ba, 0x45ba, 0x4577, 0x6827, 0x0093, 0x2009, 0x000b,
- 0x2001, 0x4300, 0x0078, 0x4593, 0xa684, 0x0004, 0x00c0, 0x4528,
- 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x4781, 0x1078,
- 0x45d3, 0x6807, 0x0117, 0x1078, 0x3bc6, 0x2001, 0x0002, 0x007c,
- 0x6000, 0xa084, 0x0004, 0x0040, 0x4781, 0x2d58, 0x6804, 0xa084,
- 0x00ff, 0xa086, 0x0006, 0x00c0, 0x4537, 0x6807, 0x0117, 0x6827,
- 0x0002, 0x1078, 0x4812, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e,
- 0x0d7e, 0x1078, 0x3ba5, 0x1078, 0x45d3, 0x2b68, 0x1078, 0x3bc6,
- 0x0d7f, 0x1078, 0x3bc6, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084,
- 0x0004, 0x0040, 0x4781, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0006,
- 0x00c0, 0x455c, 0x6807, 0x0117, 0x6827, 0x0002, 0x2d58, 0x1078,
- 0x4812, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078,
- 0x3bb5, 0x1078, 0x45d3, 0x2b68, 0x1078, 0x3bc6, 0x0d7f, 0x1078,
- 0x3bc6, 0x2001, 0x0002, 0x007c, 0x1078, 0x4781, 0x007c, 0x70b4,
- 0xa080, 0x00cd, 0x781a, 0x2001, 0x0001, 0x1078, 0x4797, 0x1078,
- 0x4805, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078, 0x47c7,
- 0x1078, 0x47fe, 0x1078, 0x43d5, 0x1078, 0x42cd, 0x1078, 0x4805,
- 0x2001, 0x0001, 0x007c, 0x1078, 0x47c7, 0x1078, 0x47fe, 0x1078,
- 0x43d5, 0x70b4, 0xa080, 0x00cd, 0x781a, 0x2001, 0x0013, 0x1078,
- 0x4797, 0x1078, 0x4805, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c,
- 0x1078, 0x4781, 0x007c, 0x1078, 0x47c7, 0x1078, 0x47fe, 0x1078,
- 0x43d5, 0x1078, 0x42cd, 0x1078, 0x4805, 0x1078, 0x484d, 0x2001,
- 0x0001, 0x007c, 0x2001, 0x0003, 0x007c, 0x1078, 0x468e, 0x2001,
- 0x0000, 0x007c, 0x0c7e, 0x077e, 0x6f14, 0x1078, 0x37b0, 0x077f,
- 0x0c7f, 0x2001, 0x0000, 0x007c, 0x1078, 0x47c7, 0x1078, 0x4781,
- 0x2001, 0x0006, 0x007c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007,
- 0x0040, 0x45de, 0xa186, 0x000f, 0x00c0, 0x45e2, 0x1078, 0x47fe,
- 0x1078, 0x43d5, 0x70b4, 0xa080, 0x00cd, 0x781a, 0x1078, 0x4805,
- 0x7003, 0x0000, 0x007c, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084,
- 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x4781, 0x1079, 0x45f8, 0x007c,
- 0x4781, 0x45fc, 0x4781, 0x4695, 0xa282, 0x0003, 0x0040, 0x4603,
- 0x1078, 0x4781, 0x007c, 0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4,
- 0x00ff, 0x69b8, 0xa184, 0x0100, 0x0040, 0x4642, 0xa18c, 0xfeff,
- 0x69ba, 0x78a0, 0xa005, 0x00c0, 0x4642, 0xa4a4, 0x00ff, 0x0040,
- 0x4636, 0xa482, 0x000c, 0x0040, 0x461f, 0x00c8, 0x4629, 0x852b,
- 0x852b, 0x1078, 0x382e, 0x0040, 0x4629, 0x1078, 0x3627, 0x0078,
- 0x4638, 0x1078, 0x4760, 0x1078, 0x3652, 0x69b8, 0xa18d, 0x0100,
- 0x69ba, 0xa6b5, 0x1000, 0x7e5a, 0x0078, 0x463b, 0x1078, 0x3652,
- 0xa6b4, 0xefff, 0x7e5a, 0x70b4, 0xa080, 0x0091, 0x781a, 0x2001,
- 0x0001, 0x007c, 0x0c7e, 0x1078, 0x4682, 0x6200, 0xd2e4, 0x0040,
- 0x4673, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048,
- 0x4655, 0x0040, 0x4655, 0x2011, 0x000c, 0x2400, 0xa202, 0x00c8,
- 0x465a, 0x2220, 0x6208, 0xa294, 0x00ff, 0x701c, 0xa202, 0x00c8,
- 0x4662, 0x721c, 0x2200, 0xa502, 0x00c8, 0x4667, 0x2228, 0x1078,
- 0x4764, 0x852b, 0x852b, 0x1078, 0x382e, 0x0040, 0x4673, 0x1078,
- 0x362e, 0x0078, 0x4677, 0x1078, 0x4760, 0x1078, 0x3659, 0xa6b5,
- 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, 0x781a, 0x2001, 0x0004,
- 0x0c7f, 0x007c, 0x007e, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003,
- 0x8003, 0x8003, 0xa0e0, 0x5480, 0x007f, 0x007c, 0x0c7e, 0x1078,
- 0x4682, 0x1078, 0x3659, 0x0c7f, 0x007c, 0xa282, 0x0002, 0x00c0,
- 0x4781, 0x7aa8, 0xa294, 0x00ff, 0x69b8, 0xa184, 0x0200, 0x0040,
- 0x46cc, 0xa18c, 0xfdff, 0x69ba, 0x78a0, 0xa005, 0x00c0, 0x46cc,
- 0xa282, 0x0002, 0x00c8, 0x376b, 0x1078, 0x472a, 0x1078, 0x36f9,
- 0x1078, 0x3652, 0xa684, 0x0100, 0x0040, 0x46c2, 0x682c, 0xa084,
- 0x0001, 0x0040, 0x46c2, 0xc6fc, 0x7888, 0xa084, 0x0040, 0x0040,
- 0x46c2, 0xc6fd, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x0091,
- 0x781a, 0x2001, 0x0001, 0x007c, 0x0c7e, 0x1078, 0x4682, 0xa284,
- 0xfffe, 0x0040, 0x46d7, 0x2011, 0x0001, 0x0078, 0x46db, 0xa284,
- 0x0001, 0x0040, 0x46e1, 0x6100, 0xd1ec, 0x00c0, 0x46e1, 0x2011,
- 0x0000, 0x1078, 0x471c, 0x1078, 0x3700, 0x1078, 0x3659, 0xa684,
- 0x0100, 0x0040, 0x46f7, 0x682c, 0xa084, 0x0001, 0x0040, 0x46f7,
- 0xc6fc, 0x7888, 0xa084, 0x0040, 0x0040, 0x46f7, 0xc6fd, 0xa6b5,
- 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, 0x781a, 0x2001, 0x0004,
- 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0x6000, 0x2011, 0x0001, 0xa084,
- 0x2000, 0x00c0, 0x470d, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
- 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x68b8, 0xa085,
- 0x0200, 0x68ba, 0x0c7f, 0x007c, 0x789b, 0x0018, 0x78ab, 0x0001,
- 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0081, 0x78ab,
- 0x0004, 0x007c, 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084, 0x1000,
- 0x00c0, 0x4738, 0x2029, 0x0032, 0x2021, 0x0000, 0x0078, 0x4758,
- 0x6508, 0xa5ac, 0x00ff, 0x7018, 0xa086, 0x0028, 0x00c0, 0x4748,
- 0xa582, 0x0019, 0x00c8, 0x474e, 0x2029, 0x0019, 0x0078, 0x474e,
- 0xa582, 0x000c, 0x00c8, 0x474e, 0x2029, 0x000c, 0x6408, 0x8427,
- 0xa4a4, 0x00ff, 0xa482, 0x000c, 0x0048, 0x4758, 0x2021, 0x000c,
- 0x1078, 0x4764, 0x68b8, 0xa085, 0x0100, 0x68ba, 0x0c7f, 0x007c,
- 0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0018, 0x78ab, 0x0001,
- 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b, 0x0081,
- 0x78ab, 0x0005, 0x007c, 0x2001, 0x0003, 0x1078, 0x478f, 0xa6b5,
- 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, 0x781a, 0x2001, 0x0005,
- 0x007c, 0x2001, 0x0007, 0x1078, 0x478f, 0xa6b5, 0x1000, 0x7e5a,
- 0x70b4, 0xa080, 0x00b9, 0x781a, 0x2001, 0x0004, 0x007c, 0x789b,
- 0x0018, 0x78aa, 0x789b, 0x0081, 0x78ab, 0x0001, 0x007c, 0x6904,
- 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x47a5, 0xa196, 0x000f,
- 0x0040, 0x47a5, 0x1078, 0x19ac, 0x007c, 0x6924, 0xa194, 0x003f,
- 0x00c0, 0x47ae, 0xa18c, 0xffc0, 0xa105, 0x6826, 0x1078, 0x3bc6,
- 0x691c, 0xa184, 0x0100, 0x0040, 0x47bb, 0x6914, 0x1078, 0x3c3b,
- 0x6204, 0x8210, 0x6206, 0x007c, 0x692c, 0x6834, 0x682e, 0xa112,
- 0x6930, 0x6838, 0x6832, 0xa11b, 0xa200, 0xa301, 0x007c, 0x0c7e,
- 0xade0, 0x0018, 0x6003, 0x0070, 0x6106, 0x600b, 0x0000, 0x600f,
- 0x0a00, 0x6013, 0x0000, 0x6017, 0x0000, 0x8007, 0x601a, 0x601f,
- 0x0000, 0x6023, 0x0000, 0x0c7f, 0x6824, 0xa085, 0x0080, 0x6826,
- 0x007c, 0x157e, 0x137e, 0x147e, 0x2098, 0xaf80, 0x002d, 0x20a0,
- 0x81ac, 0x0040, 0x47ec, 0x53a6, 0xa184, 0x0001, 0x0040, 0x47f2,
- 0x3304, 0x78be, 0x147f, 0x137f, 0x157f, 0x007c, 0x70b0, 0xa005,
- 0x10c0, 0x248c, 0x70b3, 0x8000, 0x0078, 0x4b4b, 0x71b0, 0x81ff,
- 0x0040, 0x4804, 0x1078, 0x4c41, 0x007c, 0x71b0, 0x81ff, 0x0040,
- 0x4811, 0x7848, 0xa085, 0x0008, 0x784a, 0x70b3, 0x0000, 0x1078,
- 0x4887, 0x007c, 0x0c7e, 0x0d7e, 0x1078, 0x1989, 0x00c0, 0x481a,
- 0x1078, 0x248c, 0x0c7f, 0x157e, 0x137e, 0x147e, 0x2da0, 0x2c98,
- 0x20a9, 0x0031, 0x53a3, 0x147f, 0x137f, 0x157f, 0x6807, 0x010d,
- 0x680b, 0x0000, 0x7004, 0x8007, 0x681a, 0x6823, 0x0000, 0x681f,
- 0x0000, 0x689f, 0x0000, 0x0c7f, 0x007c, 0x70b4, 0xa080, 0x0091,
- 0x781a, 0x0078, 0x24fa, 0x70b4, 0xa080, 0x0081, 0x781a, 0x0078,
- 0x24fa, 0x70b4, 0xa080, 0x00b9, 0x781a, 0x0078, 0x24fa, 0x70b4,
- 0xa080, 0x00c3, 0x781a, 0x0078, 0x24fa, 0x6904, 0xa18c, 0x00ff,
- 0xa196, 0x0007, 0x0040, 0x485a, 0xa196, 0x000f, 0x0040, 0x485a,
- 0x6807, 0x0117, 0x6824, 0xa084, 0x00ff, 0xa085, 0x0200, 0x6826,
- 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000, 0x6822,
- 0x2031, 0x0400, 0x6eb6, 0x7e5a, 0x71b4, 0xa188, 0x0091, 0x791a,
- 0x007c, 0x1078, 0x4805, 0x7848, 0xa085, 0x000c, 0x784a, 0x70b4,
- 0xa080, 0x00cd, 0x781a, 0x2009, 0x000b, 0x2001, 0x4400, 0x1078,
- 0x47c7, 0x2001, 0x0013, 0x1078, 0x4797, 0x0078, 0x3c68, 0x127e,
- 0x2091, 0x2200, 0x2049, 0x4887, 0x7000, 0x7204, 0xa205, 0x720c,
- 0xa215, 0x7008, 0xa084, 0xfff7, 0xa205, 0x0040, 0x4899, 0x0078,
- 0x489e, 0x7003, 0x0000, 0x127f, 0x2000, 0x007c, 0x7000, 0xa084,
- 0x0001, 0x00c0, 0x48cc, 0x7108, 0x8103, 0x00c8, 0x48ab, 0x1078,
- 0x49ce, 0x0078, 0x48a3, 0x700c, 0xa08c, 0x00ff, 0x0040, 0x48cc,
- 0x7004, 0x8004, 0x00c8, 0x48c3, 0x7014, 0xa005, 0x00c0, 0x48bf,
- 0x7010, 0xa005, 0x0040, 0x48c3, 0xa102, 0x00c8, 0x48a3, 0x7007,
- 0x0010, 0x0078, 0x48cc, 0x8aff, 0x0040, 0x48cc, 0x1078, 0x4c18,
- 0x00c0, 0x48c6, 0x0040, 0x48a3, 0x1078, 0x4957, 0x7003, 0x0000,
- 0x127f, 0x2000, 0x007c, 0x017e, 0x6104, 0xa18c, 0x00ff, 0xa186,
- 0x0007, 0x0040, 0x48df, 0xa18e, 0x000f, 0x00c0, 0x48e2, 0x6040,
- 0x0078, 0x48e3, 0x6428, 0x017f, 0x84ff, 0x0040, 0x490d, 0x2c70,
- 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x491d, 0x273c, 0x87fb, 0x00c0,
- 0x48fb, 0x0048, 0x48f5, 0x1078, 0x248c, 0x609c, 0xa075, 0x0040,
- 0x490d, 0x0078, 0x48e8, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c,
- 0xa529, 0x8421, 0x0040, 0x490d, 0x8738, 0x2704, 0xa005, 0x00c0,
- 0x48fc, 0x709c, 0xa075, 0x00c0, 0x48e8, 0x007c, 0x0000, 0x0005,
- 0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003,
- 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x4912, 0x490f,
- 0x0000, 0x0000, 0x8000, 0x0000, 0x4912, 0x0000, 0x491a, 0x4917,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x491a, 0x0000, 0x4915, 0x4915,
- 0x0000, 0x0000, 0x8000, 0x0000, 0x4915, 0x0000, 0x491b, 0x491b,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x491b, 0x127e, 0x2091, 0x2200,
- 0x2079, 0x5200, 0x2071, 0x0010, 0x7007, 0x000a, 0x7007, 0x0002,
- 0x7003, 0x0000, 0x2071, 0x0020, 0x7007, 0x000a, 0x7007, 0x0002,
- 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c, 0x2049,
- 0x4957, 0x2019, 0x0000, 0x7004, 0x8004, 0x00c8, 0x49aa, 0x7007,
- 0x0012, 0x7108, 0x7008, 0xa106, 0x00c0, 0x4961, 0xa184, 0x01e0,
- 0x0040, 0x496c, 0x1078, 0x248c, 0x2001, 0x04fd, 0x2004, 0xa082,
- 0x0005, 0x00c8, 0x4977, 0xa184, 0x4000, 0x00c0, 0x4961, 0xa19c,
- 0x300c, 0xa386, 0x2004, 0x0040, 0x4985, 0xa386, 0x0008, 0x0040,
- 0x4990, 0xa386, 0x200c, 0x00c0, 0x4961, 0x7200, 0x8204, 0x0048,
- 0x4990, 0x730c, 0xa384, 0x00ff, 0x0040, 0x4990, 0x1078, 0x248c,
- 0x7007, 0x0012, 0x7000, 0xa084, 0x0001, 0x00c0, 0x49aa, 0x7008,
- 0xa084, 0x01e0, 0x00c0, 0x49aa, 0x7310, 0x7014, 0xa305, 0x0040,
- 0x49aa, 0x710c, 0xa184, 0x0300, 0x00c0, 0x49aa, 0xa184, 0x00ff,
- 0x00c0, 0x4957, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xa084,
- 0x0008, 0x00c0, 0x49ae, 0x7007, 0x0012, 0x7108, 0x8103, 0x0048,
- 0x49b3, 0x7003, 0x0000, 0x2049, 0x0000, 0x007c, 0x107e, 0x007e,
- 0x127e, 0x157e, 0x2091, 0x2200, 0x7108, 0x1078, 0x49ce, 0x157f,
- 0x127f, 0x2091, 0x8001, 0x007f, 0x107f, 0x007c, 0x7204, 0x7500,
- 0x730c, 0xa384, 0x0300, 0x00c0, 0x49f5, 0xa184, 0x01e0, 0x00c0,
- 0x4a19, 0x7108, 0xa184, 0x01e0, 0x00c0, 0x4a19, 0x2001, 0x04fd,
- 0x2004, 0xa082, 0x0005, 0x00c8, 0x49e9, 0xa184, 0x4000, 0x00c0,
- 0x49d9, 0xa184, 0x0007, 0x0079, 0x49ed, 0x49f7, 0x4a09, 0x49f5,
- 0x4a09, 0x49f5, 0x4a55, 0x49f5, 0x4a53, 0x1078, 0x248c, 0x7004,
- 0xa084, 0x0010, 0xa085, 0x0002, 0x7006, 0x8aff, 0x00c0, 0x4a04,
- 0x2049, 0x0000, 0x0078, 0x4a08, 0x1078, 0x4c18, 0x00c0, 0x4a04,
- 0x007c, 0x7004, 0xa084, 0x0010, 0xa085, 0x0002, 0x7006, 0x8aff,
- 0x00c0, 0x4a14, 0x0078, 0x4a18, 0x1078, 0x4c18, 0x00c0, 0x4a14,
- 0x007c, 0x7007, 0x0012, 0x7108, 0x00e0, 0x4a1c, 0x2091, 0x6000,
- 0x00e0, 0x4a20, 0x2091, 0x6000, 0x7007, 0x0012, 0x7007, 0x0008,
- 0x7004, 0xa084, 0x0008, 0x00c0, 0x4a28, 0x7007, 0x0012, 0x7108,
- 0x8103, 0x0048, 0x4a2d, 0x7003, 0x0000, 0x7000, 0xa005, 0x00c0,
- 0x4a41, 0x7004, 0xa005, 0x00c0, 0x4a41, 0x700c, 0xa005, 0x0040,
- 0x4a43, 0x0078, 0x4a24, 0x2049, 0x0000, 0x1078, 0x38d7, 0x6818,
- 0xa084, 0x8000, 0x0040, 0x4a4e, 0x681b, 0x0002, 0x007c, 0x1078,
- 0x248c, 0x1078, 0x248c, 0x1078, 0x4ab1, 0x7210, 0x7114, 0x700c,
- 0xa09c, 0x00ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, 0x1078,
- 0x4ab1, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c,
- 0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x4a78, 0x00c8, 0x4a78,
- 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078, 0x4a5f,
- 0x2b60, 0x8a07, 0x007e, 0x6004, 0xa084, 0x0008, 0x0040, 0x4a84,
- 0xa7ba, 0x4917, 0x0078, 0x4a86, 0xa7ba, 0x490f, 0x007f, 0xa73d,
- 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7007, 0x0012, 0x1078,
- 0x4957, 0x007c, 0x8738, 0x2704, 0xa005, 0x00c0, 0x4aa5, 0x609c,
- 0xa005, 0x0040, 0x4aae, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080,
- 0x491d, 0x203c, 0x87fb, 0x1040, 0x248c, 0x8a51, 0x0040, 0x4aad,
- 0x7008, 0xa084, 0x0003, 0xa086, 0x0003, 0x007c, 0x2051, 0x0000,
- 0x007c, 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x4ac5, 0x6000,
- 0xa064, 0x00c0, 0x4abc, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080,
- 0x492d, 0x203c, 0x87fb, 0x1040, 0x248c, 0x007c, 0x127e, 0x0d7e,
- 0x2091, 0x2200, 0x0d7f, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90,
- 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, 0x6804, 0xa084,
- 0x0008, 0x007f, 0x0040, 0x4ae0, 0xa0b8, 0x4917, 0x0078, 0x4ae2,
- 0xa0b8, 0x490f, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff,
- 0xa186, 0x0007, 0x0040, 0x4af0, 0xa18e, 0x000f, 0x00c0, 0x4af9,
- 0x681c, 0xa084, 0x0040, 0x0040, 0x4b00, 0xa6b5, 0x0001, 0x0078,
- 0x4b00, 0x681c, 0xa084, 0x0040, 0x0040, 0x4b00, 0xa6b5, 0x0001,
- 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4b02, 0x2400,
- 0xa305, 0x00c0, 0x4b0d, 0x0078, 0x4b33, 0x2c58, 0x2704, 0x6104,
- 0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184,
- 0x0008, 0x0040, 0x4b23, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014,
- 0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c,
- 0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078,
- 0x4a92, 0x0078, 0x4b35, 0x1078, 0x4c18, 0x00c0, 0x4b33, 0x127f,
- 0x2000, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x7007,
- 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4b41, 0x7003, 0x0008,
- 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f,
- 0x2049, 0x4b4b, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
- 0x4b54, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186,
- 0x0007, 0x0040, 0x4b67, 0xa18e, 0x000f, 0x00c0, 0x4b72, 0x681c,
- 0xa084, 0x0040, 0x0040, 0x4b6e, 0xa6b5, 0x0001, 0x6840, 0x2050,
- 0x0078, 0x4b7b, 0x681c, 0xa084, 0x0020, 0x00c0, 0x4b79, 0xa6b5,
- 0x0001, 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8,
- 0x491d, 0x273c, 0x87fb, 0x00c0, 0x4b8f, 0x0048, 0x4b89, 0x1078,
- 0x248c, 0x689c, 0xa065, 0x0040, 0x4b93, 0x0078, 0x4b7c, 0x1078,
- 0x4c18, 0x00c0, 0x4b8f, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e,
- 0x017e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x037f, 0x047f, 0x7e08,
- 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040,
- 0x4bad, 0xa18e, 0x000f, 0x00c0, 0x4bb6, 0x681c, 0xa084, 0x0040,
- 0x0040, 0x4bbd, 0xa6b5, 0x0001, 0x0078, 0x4bbd, 0x681c, 0xa084,
- 0x0040, 0x0040, 0x4bbd, 0xa6b5, 0x0001, 0x2049, 0x4b96, 0x017e,
- 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4bcb, 0xa18e,
- 0x000f, 0x00c0, 0x4bce, 0x6840, 0x0078, 0x4bcf, 0x6828, 0x017f,
- 0xa055, 0x0040, 0x4c15, 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f,
- 0xa7b8, 0x491d, 0x273c, 0x87fb, 0x00c0, 0x4be9, 0x0048, 0x4be2,
- 0x1078, 0x248c, 0x709c, 0xa075, 0x2060, 0x0040, 0x4c15, 0x0078,
- 0x4bd5, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048,
- 0x4c02, 0x8a51, 0x00c0, 0x4bf6, 0x1078, 0x248c, 0x8738, 0x2704,
- 0xa005, 0x00c0, 0x4bea, 0x709c, 0xa075, 0x2060, 0x0040, 0x4c15,
- 0x0078, 0x4bd5, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x6908,
- 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8, 0x4c11, 0x1078,
- 0x248c, 0x2071, 0x0020, 0x0078, 0x4b00, 0x127f, 0x2000, 0x007c,
- 0x7008, 0xa084, 0x0003, 0xa086, 0x0003, 0x0040, 0x4c40, 0x2704,
- 0xac08, 0x2104, 0x701a, 0x8108, 0x2104, 0x701e, 0x8108, 0x2104,
- 0x7012, 0x8108, 0x2104, 0x7016, 0x6004, 0xa084, 0x0008, 0x0040,
- 0x4c37, 0x8108, 0x2104, 0x7022, 0x8108, 0x2104, 0x7026, 0x7602,
- 0x7004, 0xa084, 0x0010, 0xa085, 0x0001, 0x7006, 0x1078, 0x4a92,
- 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x2200, 0x2049, 0x4c41,
- 0x0d7f, 0x087f, 0x7108, 0xa184, 0x0003, 0x00c0, 0x4c6b, 0x017e,
- 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4c5b, 0xa18e,
- 0x000f, 0x00c0, 0x4c5e, 0x6840, 0x0078, 0x4c5f, 0x6828, 0x017f,
- 0xa005, 0x0040, 0x4c79, 0x0078, 0x489e, 0x0020, 0x4c6b, 0x1078,
- 0x4a55, 0x0078, 0x4c79, 0x00a0, 0x4c72, 0x7108, 0x1078, 0x49ce,
- 0x0078, 0x4c4a, 0x7007, 0x0010, 0x00a0, 0x4c74, 0x7108, 0x1078,
- 0x49ce, 0x7008, 0xa086, 0x0008, 0x00c0, 0x4c4a, 0x7000, 0xa005,
- 0x00c0, 0x4c4a, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000,
- 0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x2091,
- 0x2200, 0x0d7f, 0x2049, 0x4c89, 0xad80, 0x0011, 0x20a0, 0x2099,
- 0x0031, 0x700c, 0xa084, 0x00ff, 0x682a, 0x7007, 0x0008, 0x7007,
- 0x0002, 0x7003, 0x0001, 0x0040, 0x4ca8, 0x8000, 0x80ac, 0x53a5,
- 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4caa, 0x0c7f,
- 0x2049, 0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f,
- 0x2000, 0x007c, 0x2091, 0x6000, 0x2091, 0x8000, 0x78cc, 0xa005,
- 0x0040, 0x4cd1, 0x7994, 0x70d0, 0xa106, 0x00c0, 0x4cd1, 0x7804,
- 0xa005, 0x0040, 0x4cd1, 0x7807, 0x0000, 0x0068, 0x4cd1, 0x2091,
- 0x4080, 0x7820, 0x8001, 0x7822, 0x00c0, 0x4d2c, 0x7824, 0x7822,
- 0x2069, 0x5240, 0x6800, 0xa084, 0x0007, 0x0040, 0x4cef, 0xa086,
- 0x0002, 0x0040, 0x4cef, 0x6834, 0xa00d, 0x0040, 0x4cef, 0x2104,
- 0xa005, 0x0040, 0x4cef, 0x8001, 0x200a, 0x0040, 0x4dd4, 0x7848,
- 0xa005, 0x0040, 0x4cfd, 0x8001, 0x784a, 0x00c0, 0x4cfd, 0x2009,
- 0x0102, 0x6844, 0x200a, 0x1078, 0x226f, 0x6890, 0xa005, 0x0040,
- 0x4d09, 0x8001, 0x6892, 0x00c0, 0x4d09, 0x686f, 0x0000, 0x6873,
- 0x0001, 0x2061, 0x5500, 0x20a9, 0x0100, 0x2009, 0x0002, 0x6034,
- 0xa005, 0x0040, 0x4d1f, 0x8001, 0x6036, 0x00c0, 0x4d1f, 0x6010,
- 0xa005, 0x0040, 0x4d1f, 0x017e, 0x1078, 0x226f, 0x017f, 0xace0,
- 0x0010, 0x0070, 0x4d25, 0x0078, 0x4d0f, 0x8109, 0x0040, 0x4d2c,
- 0x20a9, 0x0100, 0x0078, 0x4d0f, 0x1078, 0x4d39, 0x1078, 0x4d5e,
- 0x2009, 0x5251, 0x2104, 0x2009, 0x0102, 0x200a, 0x2091, 0x8001,
- 0x007c, 0x7834, 0x8001, 0x7836, 0x00c0, 0x4d5d, 0x7838, 0x7836,
- 0x2091, 0x8000, 0x7844, 0xa005, 0x00c0, 0x4d48, 0x2001, 0x0101,
- 0x8001, 0x7846, 0xa080, 0x7500, 0x2040, 0x2004, 0xa065, 0x0040,
- 0x4d5d, 0x6024, 0xa005, 0x0040, 0x4d59, 0x8001, 0x6026, 0x0040,
- 0x4d8d, 0x6000, 0x2c40, 0x0078, 0x4d4e, 0x007c, 0x7828, 0x8001,
- 0x782a, 0x00c0, 0x4d8c, 0x782c, 0x782a, 0x7830, 0xa005, 0x00c0,
- 0x4d6b, 0x2001, 0x0200, 0x8001, 0x7832, 0x8003, 0x8003, 0x8003,
- 0x8003, 0xa090, 0x5500, 0xa298, 0x0002, 0x2304, 0xa084, 0x0008,
- 0x0040, 0x4d8c, 0xa290, 0x0009, 0x2204, 0xa005, 0x0040, 0x4d84,
- 0x8001, 0x2012, 0x00c0, 0x4d8c, 0x2304, 0xa084, 0xfff7, 0xa085,
- 0x0080, 0x201a, 0x1078, 0x226f, 0x007c, 0x2069, 0x5240, 0x6800,
- 0xa005, 0x0040, 0x4d97, 0x6848, 0xac06, 0x0040, 0x4dd4, 0x601b,
- 0x0006, 0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff,
- 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x6714, 0x6f82, 0x1078,
- 0x19c5, 0x6818, 0xa005, 0x0040, 0x4daf, 0x8001, 0x681a, 0x6808,
- 0xa084, 0xffef, 0x680a, 0x6810, 0x8001, 0x00d0, 0x4db9, 0x1078,
- 0x248c, 0x6812, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078,
- 0x1cdc, 0x2069, 0x5240, 0x7944, 0xa184, 0x0100, 0x2001, 0x0006,
- 0x686e, 0x00c0, 0x4dcf, 0x6986, 0x2001, 0x0004, 0x686e, 0x1078,
- 0x226a, 0x2091, 0x8001, 0x007c, 0x2069, 0x0100, 0x2009, 0x5240,
- 0x2104, 0xa084, 0x0007, 0x0040, 0x4e30, 0xa086, 0x0007, 0x00c0,
- 0x4dea, 0x0d7e, 0x2009, 0x5252, 0x216c, 0x1078, 0x3b1c, 0x0d7f,
- 0x0078, 0x4e30, 0x2009, 0x5252, 0x2164, 0x1078, 0x2437, 0x601b,
- 0x0006, 0x6858, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff,
- 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000, 0x6830,
- 0xa084, 0x0040, 0x0040, 0x4e24, 0x684b, 0x0004, 0x20a9, 0x0014,
- 0x6848, 0xa084, 0x0004, 0x0040, 0x4e11, 0x0070, 0x4e11, 0x0078,
- 0x4e08, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001,
- 0x0040, 0x4e1e, 0x0070, 0x4e1e, 0x0078, 0x4e15, 0x20a9, 0x00fa,
- 0x0070, 0x4e24, 0x0078, 0x4e20, 0x6808, 0xa084, 0xfffd, 0x680a,
- 0x681b, 0x0048, 0x2009, 0x525b, 0x200b, 0x0007, 0x784c, 0x784a,
- 0x2091, 0x8001, 0x007c, 0x2079, 0x5200, 0x1078, 0x4e5e, 0x1078,
- 0x4e42, 0x1078, 0x4e50, 0x7833, 0x0000, 0x7847, 0x0000, 0x784b,
- 0x0000, 0x007c, 0x2019, 0x0003, 0x2011, 0x5246, 0x2204, 0xa086,
- 0x003c, 0x0040, 0x4e4d, 0x2019, 0x0002, 0x7b2a, 0x7b2e, 0x007c,
- 0x2019, 0x0039, 0x2011, 0x5246, 0x2204, 0xa086, 0x003c, 0x0040,
- 0x4e5b, 0x2019, 0x0027, 0x7b36, 0x7b3a, 0x007c, 0x2019, 0x3971,
- 0x2011, 0x5246, 0x2204, 0xa086, 0x003c, 0x0040, 0x4e69, 0x2019,
- 0x2626, 0x7b22, 0x7b26, 0x783f, 0x0000, 0x7843, 0x000a, 0x007c,
- 0x0020, 0x002b, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0014, 0x0014, 0x9849, 0x0014, 0x0014,
- 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0080, 0x000f, 0x0000,
- 0x0201, 0x0604, 0x0c08, 0x2120, 0x4022, 0xf880, 0x0018, 0x300b,
- 0xa201, 0x0014, 0xa200, 0x0014, 0xa200, 0x0214, 0x0000, 0x006c,
- 0x0002, 0x0014, 0x98cd, 0x009e, 0x0093, 0xa202, 0x8838, 0x3806,
- 0x8839, 0x20c3, 0x0864, 0x9885, 0x28c1, 0x9cae, 0xa203, 0x300c,
- 0x2846, 0x8161, 0x846a, 0x8300, 0x1856, 0x883a, 0x9865, 0x28f2,
- 0x9c91, 0x9858, 0x300c, 0x28e1, 0x9c91, 0x2802, 0xa206, 0x64c3,
- 0x282e, 0xa207, 0x64a0, 0x6de0, 0x67a0, 0x6fc0, 0x1814, 0x883b,
- 0x7824, 0x68c1, 0x7864, 0x883e, 0x9879, 0x8576, 0x8677, 0x206b,
- 0x28c1, 0x9cae, 0x2044, 0x2103, 0x20a2, 0x2081, 0x9865, 0xa209,
- 0x2901, 0x988d, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a, 0x883c,
- 0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c91, 0x0014, 0xa204,
- 0xa300, 0x3009, 0x19e2, 0xf864, 0x856e, 0x883f, 0x08e6, 0x9891,
- 0xf881, 0x988c, 0xc801, 0x0014, 0xf8c1, 0x0016, 0x85b2, 0x80f0,
- 0x9532, 0xfb02, 0x1de2, 0x0014, 0x8532, 0xf241, 0x0014, 0x1de2,
- 0x84a8, 0xd7a0, 0x1fe6, 0x0014, 0xa208, 0x6043, 0x8008, 0x1dc1,
- 0x0016, 0x8300, 0x8160, 0x842a, 0xf041, 0x3008, 0x84a8, 0x11d6,
- 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, 0x8000, 0x2847,
- 0x1011, 0x98c0, 0x8000, 0xa000, 0x2802, 0x1011, 0x98c6, 0x9865,
- 0x283e, 0x1011, 0x98ca, 0xa20b, 0x0017, 0x300c, 0xa300, 0x1de2,
- 0xdb81, 0x0014, 0x0210, 0x98d7, 0x0014, 0x26e0, 0x873a, 0xfb02,
- 0x19f2, 0x1fe2, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9cb3, 0x0704,
- 0x0000, 0x006c, 0x0002, 0x984f, 0x0014, 0x009e, 0x00a0, 0x0017,
- 0x60ff, 0x300c, 0x8720, 0xa211, 0x9cd0, 0x8772, 0x8837, 0x2101,
- 0x987a, 0x10d2, 0x78e2, 0x9cd3, 0x9859, 0xd984, 0xf0e2, 0xf0a1,
- 0x98cd, 0x0014, 0x8831, 0xd166, 0x8830, 0x800f, 0x9401, 0xb520,
- 0xc802, 0x8820, 0x987a, 0x2301, 0x987a, 0x10d2, 0x78e4, 0x9cd3,
- 0x8821, 0x8820, 0x9859, 0xf123, 0xf142, 0xf101, 0x98c6, 0x10d2,
- 0x70f6, 0x8832, 0x8203, 0x870c, 0xd99e, 0x6001, 0x0014, 0x6845,
- 0x0214, 0xa21b, 0x9cd0, 0x2001, 0x98c5, 0x8201, 0x1852, 0xd184,
- 0xd163, 0x8834, 0x8001, 0x988d, 0x3027, 0x84a8, 0x1a56, 0x8833,
- 0x0014, 0xa218, 0x6981, 0x9cbc, 0x6926, 0x6902, 0x1a34, 0x9899,
- 0x1a14, 0x7021, 0x0014, 0xa300, 0x6141, 0x6964, 0x8010, 0x8592,
- 0x8026, 0x84b9, 0x69e4, 0x8023, 0x16e1, 0x8001, 0x10f1, 0x6946,
- 0xa213, 0x1462, 0xa213, 0x8000, 0x16e1, 0x98b5, 0x6969, 0xa214,
- 0x61c2, 0x8002, 0x14e1, 0x8004, 0x16e1, 0x0101, 0x300a, 0x8827,
- 0x0014, 0xa217, 0x9cbc, 0x0014, 0xa300, 0x8181, 0x842a, 0x84a8,
- 0x1ce6, 0x882c, 0x0016, 0xa212, 0x9cd0, 0x10d2, 0x70e4, 0x0004,
- 0x8007, 0x9424, 0xcc1a, 0x9cd3, 0x98c5, 0x8827, 0x300a, 0x0013,
- 0x8000, 0x84a4, 0x0016, 0x11c2, 0x211e, 0x870e, 0xa21d, 0x0014,
- 0x878e, 0x0016, 0xa21c, 0x1035, 0x9891, 0xa210, 0xa000, 0x8010,
- 0x8592, 0x853b, 0xd044, 0x8022, 0x3807, 0x84bb, 0x98ea, 0x8021,
- 0x3807, 0x84b9, 0x300c, 0x817e, 0x872b, 0x8772, 0x9891, 0x0000,
- 0x0020, 0x002b, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0014, 0x0014, 0x9849, 0x0014, 0x0014,
- 0x98e2, 0x98cd, 0x0014, 0x0014, 0x0014, 0x0080, 0x0137, 0x0000,
- 0x0201, 0x0604, 0x0c08, 0x2120, 0x4022, 0xf880, 0x0018, 0x300b,
- 0xa201, 0x0014, 0xa200, 0x0014, 0xa200, 0x0214, 0xa202, 0x8838,
- 0x3806, 0x8839, 0x20c3, 0x0864, 0xa82f, 0x28c1, 0x9cae, 0xa203,
- 0x300c, 0x2846, 0x8161, 0x846a, 0x8300, 0x1856, 0x883a, 0xa804,
- 0x28f2, 0x9c91, 0xa8f4, 0x300c, 0x28e1, 0x9c91, 0x2802, 0xa206,
- 0x64c3, 0x282e, 0xa207, 0x64a0, 0x6de0, 0x67a0, 0x6fc0, 0x1814,
- 0x883b, 0x7824, 0x68c1, 0x7864, 0x883e, 0xa802, 0x8576, 0x8677,
- 0x206b, 0x28c1, 0x9cae, 0x2044, 0x2103, 0x20a2, 0x2081, 0xa8e4,
- 0xa209, 0x2901, 0xa809, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a,
- 0x883c, 0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c91, 0x0014,
- 0xa204, 0xa300, 0x3009, 0x19e2, 0xf864, 0x856e, 0x883f, 0x08e6,
- 0xa8f7, 0xf881, 0xa8f0, 0xc801, 0x0014, 0xf8c1, 0x0016, 0x85b2,
- 0x80f0, 0x9532, 0xfb02, 0x1de2, 0x0014, 0x8532, 0xf241, 0x0014,
- 0x1de2, 0x84a8, 0xd7a0, 0x1fe6, 0x0014, 0xa208, 0x6043, 0x8008,
- 0x1dc1, 0x0016, 0x8300, 0x8160, 0x842a, 0xf041, 0x3008, 0x84a8,
- 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, 0x8000,
- 0x2847, 0x1011, 0xa8fc, 0x8000, 0xa000, 0x2802, 0x1011, 0xa8fd,
- 0xa89b, 0x283e, 0x1011, 0xa8fd, 0xa20b, 0x0017, 0x300c, 0xa300,
- 0x1de2, 0xdb81, 0x0014, 0x0210, 0xa801, 0x0014, 0x26e0, 0x873a,
- 0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9cb3,
- 0x0704, 0x0017, 0x60ff, 0x300c, 0x8720, 0xa211, 0x9d63, 0x8772,
- 0x8837, 0x2101, 0xa821, 0x10d2, 0x78e2, 0x9d66, 0xa8fc, 0xd984,
- 0xf0e2, 0xf0a1, 0xa86c, 0x0014, 0x8831, 0xd166, 0x8830, 0x800f,
- 0x9401, 0xb520, 0xc802, 0x8820, 0xa80f, 0x2301, 0xa80d, 0x10d2,
- 0x78e4, 0x9d66, 0x8821, 0x8820, 0xa8e6, 0xf123, 0xf142, 0xf101,
- 0xa84f, 0x10d2, 0x70f6, 0x8832, 0x8203, 0x870c, 0xd99e, 0x6001,
- 0x0014, 0x6845, 0x0214, 0xa21b, 0x9d63, 0x2001, 0xa840, 0x8201,
- 0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0xa801, 0x3027, 0x84a8,
- 0x1a56, 0x8833, 0x0014, 0xa218, 0x6981, 0x9d4f, 0x6926, 0x6902,
- 0x1a34, 0xa801, 0x1a14, 0x7021, 0x0014, 0xa300, 0x6141, 0x6964,
- 0x8010, 0x8592, 0x8026, 0x84b9, 0x69e4, 0x8023, 0x16e1, 0x8001,
- 0x10f1, 0x6946, 0xa213, 0x1462, 0xa213, 0x8000, 0x16e1, 0xa807,
- 0x6969, 0xa214, 0x61c2, 0x8002, 0x14e1, 0x8004, 0x16e1, 0x0101,
- 0x300a, 0x8827, 0x0014, 0xa217, 0x9d4f, 0x0014, 0xa300, 0x8181,
- 0x842a, 0x84a8, 0x1ce6, 0x882c, 0x0016, 0xa212, 0x9d63, 0x10d2,
- 0x70e4, 0x0004, 0x8007, 0x9424, 0xcc1a, 0x9d66, 0xa8f8, 0x8827,
- 0x300a, 0x0013, 0x8000, 0x84a4, 0x0016, 0x11c2, 0x211e, 0x870e,
- 0xa21d, 0x0014, 0x878e, 0x0016, 0xa21c, 0x1035, 0xa8b4, 0xa210,
- 0x3807, 0x300c, 0x817e, 0x872b, 0x8772, 0xa8ad, 0x0000, 0x0d0c
-};
-static unsigned short risc_code_length01 = 0x4158;
diff --git a/drivers/scsi/ql12160_fw.h b/drivers/scsi/ql12160_fw.h
deleted file mode 100644
index d89dac0cc9d..00000000000
--- a/drivers/scsi/ql12160_fw.h
+++ /dev/null
@@ -1,1811 +0,0 @@
-/*****************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP12160 device driver for Linux 2.2.x and 2.4.x
- * Copyright (C) 2002 Qlogic Corporation (www.qlogic.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, 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.
- *
- *****************************************************************************/
-
-/************************************************************************
- * --- ISP12160A Initiator Firmware --- *
- * 32 LUN Support *
- ************************************************************************/
-
-/*
- * Firmware Version 10.04.42 (15:44 Apr 18, 2003)
- */
-
-#ifdef UNIQUE_FW_NAME
-static unsigned char fw12160i_version_str[] = {10,4,42};
-#else
-static unsigned char firmware_version[] = {10,4,42};
-#endif
-
-#ifdef UNIQUE_FW_NAME
-#define fw12160i_VERSION_STRING "10.04.42"
-#else
-#define FW_VERSION_STRING "10.04.42"
-#endif
-
-#ifdef UNIQUE_FW_NAME
-static unsigned short fw12160i_addr01 = 0x1000;
-#else
-static unsigned short risc_code_addr01 = 0x1000;
-#endif
-
-#ifdef UNIQUE_FW_NAME
-static unsigned short fw12160i_code01[] = {
-#else
-static unsigned short risc_code01[] = {
-#endif
- 0x0804, 0x1041, 0x0000, 0x36c9, 0x0000, 0x2043, 0x4f50, 0x5952,
- 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
- 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320,
- 0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350,
- 0x3132, 0x3136, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056,
- 0x6572, 0x7369, 0x6f6e, 0x2031, 0x302e, 0x3034, 0x2020, 0x2043,
- 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050,
- 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020,
- 0x2400, 0x20c9, 0x90ff, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2001,
- 0x01ff, 0x2004, 0xd0fc, 0x1120, 0x2071, 0x0100, 0x70a0, 0x70a2,
- 0x20c1, 0x0020, 0x2089, 0x1221, 0x2071, 0x0010, 0x70c3, 0x0004,
- 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x000a,
- 0x2001, 0x04fd, 0x2004, 0x70d6, 0x2009, 0xfeff, 0x2130, 0x2128,
- 0xa1a2, 0x4700, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
- 0xa192, 0x9100, 0x2009, 0x0000, 0x2001, 0x0032, 0x080c, 0x1e05,
- 0x2218, 0x2079, 0x4700, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
- 0x0040, 0x42a4, 0x8109, 0x1dd8, 0x2009, 0xff00, 0x3400, 0xa102,
- 0x0218, 0x0110, 0x20a8, 0x42a4, 0x781b, 0x0064, 0x7814, 0xc0cd,
- 0xc0d5, 0x7816, 0x2071, 0x0200, 0x00d6, 0x2069, 0x4740, 0x080c,
- 0x465c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1130, 0x2069, 0x4780,
- 0x2071, 0x0100, 0x080c, 0x465c, 0x7814, 0xc0d4, 0x7816, 0x00de,
- 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800, 0xc08d, 0x7802,
- 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002, 0x7827, 0x0002,
- 0x2009, 0x0002, 0x2069, 0x4740, 0x681b, 0x0003, 0x6823, 0x0007,
- 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0006,
- 0x6833, 0x0008, 0x683b, 0x0000, 0x8109, 0x0500, 0x68cf, 0x000a,
- 0x68bf, 0x47c0, 0x2079, 0x4700, 0x68d3, 0x762d, 0x68c3, 0x4cc0,
- 0x68c7, 0x4bc0, 0x68cb, 0x8cc0, 0x68a7, 0x8f44, 0x68ab, 0x8f49,
- 0x68af, 0x8f44, 0x68b3, 0x8f44, 0x68a3, 0x0001, 0x2001, 0x01ff,
- 0x2004, 0xd0fc, 0x11c8, 0x2069, 0x4780, 0x0870, 0x68cf, 0x000a,
- 0x68bf, 0x49c0, 0x68d3, 0x7839, 0x68c3, 0x6cc0, 0x68c7, 0x4c40,
- 0x68cb, 0x8dd0, 0x68a7, 0x8f49, 0x68ab, 0x8f4e, 0x68af, 0x8f49,
- 0x68b3, 0x8f49, 0x68a3, 0x0001, 0x00e6, 0x2069, 0x4bc0, 0x2071,
- 0x0200, 0x70ec, 0xd0e4, 0x2019, 0x1809, 0x2021, 0x0009, 0x1120,
- 0x2019, 0x180c, 0x2021, 0x000c, 0x080c, 0x1d75, 0x2001, 0x01ff,
- 0x2004, 0xd0fc, 0x1188, 0x2069, 0x4c40, 0x2071, 0x0100, 0x70ec,
- 0xd0e4, 0x2019, 0x1809, 0x2021, 0x0009, 0x1120, 0x2019, 0x180c,
- 0x2021, 0x000c, 0x080c, 0x1d75, 0x00ee, 0x2011, 0x0002, 0x2069,
- 0x4cc0, 0x2009, 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b,
- 0x0040, 0x7bc8, 0xa386, 0xfeff, 0x1128, 0x6817, 0x0100, 0x681f,
- 0x0064, 0x0020, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010,
- 0x1f04, 0x1135, 0x8109, 0x1d38, 0x2001, 0x01ff, 0x2004, 0xd0fc,
- 0x1128, 0x8211, 0x0118, 0x2069, 0x6cc0, 0x08d8, 0x080c, 0x22f6,
- 0x080c, 0x403d, 0x080c, 0x1b8c, 0x080c, 0x4615, 0x2091, 0x2200,
- 0x2079, 0x4700, 0x2071, 0x0050, 0x2091, 0x2400, 0x2079, 0x4700,
- 0x2071, 0x0020, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x4740,
- 0x2091, 0x2800, 0x2079, 0x0100, 0x2071, 0x4780, 0x2091, 0x2000,
- 0x2079, 0x4700, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090,
- 0x2071, 0x0010, 0x70c3, 0x0000, 0x1004, 0x118c, 0x70c0, 0xa086,
- 0x0002, 0x1110, 0x080c, 0x13ba, 0x2039, 0x0000, 0x080c, 0x12ab,
- 0x78ac, 0xa005, 0x1180, 0x0e04, 0x119a, 0x786c, 0xa065, 0x0110,
- 0x080c, 0x20a1, 0x080c, 0x1e26, 0x0e04, 0x11af, 0x786c, 0xa065,
- 0x0110, 0x080c, 0x20a1, 0x0e04, 0x11af, 0x2009, 0x4747, 0x2011,
- 0x4787, 0x2104, 0x220c, 0xa105, 0x0110, 0x080c, 0x1c9b, 0x2071,
- 0x4740, 0x70a0, 0xa005, 0x01e8, 0x744c, 0xa485, 0x0000, 0x01c8,
- 0x2079, 0x0200, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d, 0x2190,
- 0x080c, 0x274c, 0x2091, 0x8000, 0x2091, 0x303d, 0x0e04, 0x11d1,
- 0x2079, 0x4700, 0x786c, 0xa065, 0x0120, 0x2071, 0x0010, 0x080c,
- 0x20a1, 0x1d04, 0x11d9, 0x2079, 0x4700, 0x2071, 0x0010, 0x080c,
- 0x4429, 0x2071, 0x4780, 0x70a0, 0xa005, 0x0188, 0x704c, 0xa025,
- 0x0170, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d,
- 0x2190, 0x080c, 0x274c, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079,
- 0x4700, 0x2071, 0x0010, 0x0e04, 0x11fa, 0x786c, 0xa065, 0x0110,
- 0x080c, 0x20a1, 0x1d04, 0x118e, 0x080c, 0x4429, 0x0804, 0x118e,
- 0x3c00, 0xa084, 0x0007, 0x0002, 0x120c, 0x120c, 0x120e, 0x120e,
- 0x1213, 0x1213, 0x1218, 0x1218, 0x080c, 0x2575, 0x2091, 0x2400,
- 0x080c, 0x40d5, 0x0005, 0x2091, 0x2200, 0x080c, 0x40d5, 0x0005,
- 0x2091, 0x2200, 0x080c, 0x40d5, 0x2091, 0x2400, 0x080c, 0x40d5,
- 0x0005, 0x1241, 0x1241, 0x1242, 0x1242, 0x124d, 0x124d, 0x124d,
- 0x124d, 0x1256, 0x1256, 0x1261, 0x1261, 0x124d, 0x124d, 0x124d,
- 0x124d, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270,
- 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270,
- 0x1270, 0x0cf8, 0x0006, 0x0106, 0x0126, 0x2091, 0x2800, 0x080c,
- 0x2592, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106, 0x0126,
- 0x080c, 0x1200, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106,
- 0x0126, 0x2091, 0x2600, 0x080c, 0x2592, 0x012e, 0x010e, 0x000e,
- 0x000d, 0x0006, 0x0106, 0x0126, 0x2091, 0x2600, 0x080c, 0x2592,
- 0x2091, 0x2800, 0x080c, 0x2592, 0x012e, 0x010e, 0x000e, 0x000d,
- 0x0006, 0x0106, 0x0126, 0x00d6, 0x00e6, 0x00f6, 0x2079, 0x4700,
- 0x2071, 0x0200, 0x2069, 0x4740, 0x3d00, 0xd08c, 0x0130, 0x70ec,
- 0xa084, 0x1c00, 0x78e2, 0x080c, 0x465c, 0x3d00, 0xd084, 0x0150,
- 0x2069, 0x4780, 0x2071, 0x0100, 0x70ec, 0xa084, 0x1c00, 0x78e6,
- 0x080c, 0x465c, 0x080c, 0x2526, 0x00fe, 0x00ee, 0x00de, 0x012e,
- 0x010e, 0x000e, 0x000d, 0x7008, 0x800b, 0x1240, 0x7007, 0x0002,
- 0xa08c, 0x01e0, 0x1120, 0xd09c, 0x0108, 0x0887, 0x0897, 0x70c3,
- 0x4002, 0x0804, 0x13bd, 0x0e04, 0x131e, 0x2061, 0x0000, 0x6018,
- 0xd084, 0x1904, 0x131e, 0x7828, 0xa005, 0x1120, 0x0004, 0x131f,
- 0x0804, 0x131e, 0xd0fc, 0x0130, 0x0006, 0x080c, 0x1b29, 0x000e,
- 0x0150, 0x0028, 0x0006, 0x080c, 0x1b1e, 0x000e, 0x0120, 0x2001,
- 0x4007, 0x0804, 0x13bc, 0x7910, 0xd0fc, 0x1128, 0x2061, 0x4740,
- 0xc19c, 0xc7fc, 0x0020, 0x2061, 0x4780, 0xc19d, 0xc7fd, 0x6060,
- 0xa005, 0x1904, 0x131e, 0x7912, 0x607e, 0x7828, 0xc0fc, 0xa086,
- 0x0018, 0x1120, 0x00c6, 0x080c, 0x1926, 0x00ce, 0x782b, 0x0000,
- 0x6078, 0xa065, 0x01e0, 0x00c6, 0x609c, 0x080c, 0x1bf3, 0x00ce,
- 0x609f, 0x0000, 0x080c, 0x1a60, 0x2009, 0x0018, 0x6087, 0x0103,
- 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
- 0x080c, 0x1b34, 0x000e, 0x7812, 0x1198, 0x080c, 0x1b7f, 0x7810,
- 0xd09c, 0x1118, 0x2061, 0x4740, 0x0020, 0x2061, 0x4780, 0xc09c,
- 0x7812, 0x607b, 0x0000, 0x60d0, 0xd0c4, 0x0130, 0xc0c4, 0x60d2,
- 0x2001, 0x4005, 0x0804, 0x13bc, 0x0804, 0x13ba, 0x0005, 0xa006,
- 0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0, 0xa03d, 0xa08a,
- 0x0040, 0x1a04, 0x136c, 0x0002, 0x13ba, 0x1408, 0x13d6, 0x143c,
- 0x1470, 0x1470, 0x13ce, 0x1a78, 0x147a, 0x13c8, 0x13da, 0x13db,
- 0x13dc, 0x13dd, 0x1a7c, 0x13c8, 0x1487, 0x14db, 0x1941, 0x1a72,
- 0x13de, 0x17c8, 0x17fe, 0x1830, 0x1876, 0x1785, 0x1792, 0x17a5,
- 0x17b7, 0x15bf, 0x13c8, 0x150d, 0x1518, 0x1526, 0x1534, 0x154b,
- 0x1559, 0x155c, 0x156e, 0x157c, 0x1586, 0x15a5, 0x15b1, 0x13c8,
- 0x13c8, 0x13c8, 0x13c8, 0x15cc, 0x15dd, 0x15f7, 0x162b, 0x1654,
- 0x1666, 0x1669, 0x1693, 0x16cc, 0x16de, 0x1753, 0x1763, 0x13c8,
- 0x13c8, 0x13c8, 0x13c8, 0x1775, 0x2100, 0xa08a, 0x0040, 0x1a04,
- 0x13c8, 0x0002, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x1a9e,
- 0x1aa4, 0x13c8, 0x13c8, 0x13c8, 0x1aa8, 0x1ae8, 0x13c8, 0x13c8,
- 0x13c8, 0x13c8, 0x1403, 0x146b, 0x1482, 0x14d6, 0x193c, 0x13c8,
- 0x13c8, 0x190b, 0x13c8, 0x1aec, 0x1a90, 0x1a9a, 0x13c8, 0x13c8,
- 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
- 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
- 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
- 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
- 0x13c8, 0x13c8, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0028, 0x73ce,
- 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0e04, 0x13bd, 0x2061,
- 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x0005,
- 0x70c3, 0x4001, 0x0c90, 0x70c3, 0x4006, 0x0c78, 0x2099, 0x0041,
- 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0c20, 0x70c4, 0x70c3,
- 0x0004, 0x0807, 0x08f8, 0x08f0, 0x08e8, 0x08e0, 0x2091, 0x8000,
- 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020,
- 0x70d3, 0x000a, 0x2001, 0x0004, 0x70d6, 0x2079, 0x0000, 0x781b,
- 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051,
- 0x0445, 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091,
- 0x4080, 0x0804, 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0018,
- 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0,
- 0x2099, 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, 0x721e,
- 0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0904, 0x13ba, 0xa182,
- 0x0040, 0x1210, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x7007,
- 0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0de8, 0x7007, 0x0002,
- 0xa084, 0x01e0, 0x0120, 0x70c3, 0x4002, 0x0804, 0x13bd, 0x24a8,
- 0x53a5, 0x0c10, 0x0804, 0x13ba, 0x2029, 0x0000, 0x2520, 0x71d0,
- 0x72c8, 0x73cc, 0x70c4, 0x2098, 0x20a1, 0x0030, 0x7003, 0x0000,
- 0x7007, 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, 0x0040,
- 0x7007, 0x0006, 0x81ff, 0x0904, 0x13ba, 0xa182, 0x0040, 0x1210,
- 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007,
- 0x0001, 0x7008, 0xd0fc, 0x0de8, 0xa084, 0x01e0, 0x0d48, 0x70c3,
- 0x4002, 0x0804, 0x13bd, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0878,
- 0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x1108, 0x200a, 0x72ca,
- 0x0804, 0x13b9, 0x70c7, 0x000a, 0x70cb, 0x0004, 0x70cf, 0x002a,
- 0x0804, 0x13ba, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0018, 0x2029,
- 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca,
- 0x73ce, 0x74d2, 0xa005, 0x05e8, 0xa40a, 0x0108, 0x1240, 0x8001,
- 0x7872, 0xa084, 0xfc00, 0x0138, 0x78ac, 0xc085, 0x78ae, 0x2001,
- 0x4005, 0x0804, 0x13bc, 0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76,
- 0xa48c, 0xff00, 0x0170, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c,
- 0x810f, 0xa118, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000,
- 0x0050, 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1,
- 0x0000, 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605,
- 0x0118, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, 0x78ae,
- 0x0018, 0x78ac, 0xc085, 0x78ae, 0x0804, 0x13ba, 0x75d8, 0x76dc,
- 0x75da, 0x76de, 0x0018, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8,
- 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0500,
- 0xa40a, 0x0110, 0x1a04, 0x13bc, 0x8001, 0x7892, 0xa084, 0xfc00,
- 0x0138, 0x78ac, 0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0804, 0x13bc,
- 0x7a9a, 0x7b9e, 0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0118, 0x7a10,
- 0xc2c5, 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0018,
- 0x78ac, 0xc0c5, 0x78ae, 0x0804, 0x13ba, 0x2009, 0x0000, 0x786c,
- 0xa065, 0x0118, 0x8108, 0x6000, 0x0cd8, 0x7ac4, 0x0804, 0x13b8,
- 0x2009, 0x4748, 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904,
- 0x13b9, 0x2011, 0x4788, 0x2214, 0x0804, 0x13b8, 0x2009, 0x4749,
- 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011,
- 0x4789, 0x2214, 0x0804, 0x13b8, 0x2061, 0x4740, 0x6128, 0x622c,
- 0x8214, 0x8214, 0x8214, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1148,
- 0x2061, 0x4780, 0x6328, 0x73da, 0x632c, 0x831c, 0x831c, 0x831c,
- 0x73de, 0x0804, 0x13b8, 0x2009, 0x474c, 0x210c, 0x2001, 0x01ff,
- 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011, 0x478c, 0x2214, 0x0804,
- 0x13b8, 0x7918, 0x0804, 0x13b9, 0x2009, 0x0202, 0x210c, 0xa18c,
- 0x0f30, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011,
- 0x0102, 0x2214, 0xa294, 0x0f30, 0x0804, 0x13b8, 0x2009, 0x474d,
- 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011,
- 0x478d, 0x2214, 0x0804, 0x13b8, 0x7920, 0x2001, 0x01ff, 0x2004,
- 0xd0fc, 0x1904, 0x13b9, 0x7a24, 0x0804, 0x13b8, 0x2011, 0x4c40,
- 0x71c4, 0xd1fc, 0x1110, 0x2011, 0x4bc0, 0x8107, 0xa084, 0x000f,
- 0x8003, 0x8003, 0x8003, 0xa268, 0x6a00, 0x6b08, 0x6c1c, 0x74da,
- 0xd1fc, 0x1118, 0x2021, 0x023b, 0x0010, 0x2021, 0x013b, 0x2424,
- 0xa4a4, 0x1c00, 0x74de, 0x0804, 0x13b7, 0x77c4, 0x080c, 0x1b9a,
- 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0804,
- 0x13b7, 0x2061, 0x4740, 0x6118, 0x2001, 0x01ff, 0x2004, 0xd0fc,
- 0x1904, 0x13b9, 0x2061, 0x4780, 0x6218, 0x0804, 0x13b8, 0x77c4,
- 0x080c, 0x1b9a, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x77da,
- 0x2091, 0x8001, 0x0804, 0x13b7, 0x71c4, 0x2110, 0xa294, 0x000f,
- 0xa282, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x23b4, 0xa384, 0x4000,
- 0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x71c4, 0x2100, 0xc0bc,
- 0xa082, 0x0010, 0x1a04, 0x13b3, 0xd1bc, 0x1120, 0x2011, 0x4748,
- 0x2204, 0x0020, 0x2011, 0x4788, 0x2204, 0xc0bd, 0x0006, 0x2100,
- 0xc0bc, 0x2012, 0x080c, 0x2358, 0x001e, 0x0804, 0x13b9, 0x71c4,
- 0x2021, 0x4749, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0030, 0x71c8,
- 0x2021, 0x4789, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1623, 0x20a9,
- 0x0008, 0x2204, 0xa106, 0x0138, 0x8210, 0x1f04, 0x1609, 0x71c4,
- 0x72c8, 0x0804, 0x13b2, 0xa292, 0x1623, 0x0026, 0x2122, 0x001e,
- 0x080c, 0x236a, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1110, 0xd3fc,
- 0x09f0, 0x0804, 0x13ba, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0004,
- 0x0001, 0x0002, 0x0003, 0x2061, 0x4740, 0x6128, 0x622c, 0x8214,
- 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003, 0x8003,
- 0x602e, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x11a0, 0x0026, 0x0016,
- 0x2061, 0x4780, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70d8,
- 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, 0x72de,
- 0x001e, 0x002e, 0x0804, 0x13b8, 0x2061, 0x4740, 0x6130, 0x70c4,
- 0x6032, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2061,
- 0x4780, 0x6230, 0x70c8, 0x6032, 0x0804, 0x13b8, 0x7918, 0x0804,
- 0x13b9, 0x71c4, 0xa184, 0xf0cf, 0x0148, 0x2001, 0x01ff, 0x2004,
- 0xd0fc, 0x1904, 0x13b3, 0x72c8, 0x0804, 0x13b2, 0x2019, 0x0000,
- 0x080c, 0x23a6, 0x0036, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118,
- 0x001e, 0x0804, 0x13b9, 0x71c8, 0xa184, 0xf0cf, 0x0128, 0x000e,
- 0x2110, 0x71c4, 0x0804, 0x13b2, 0xc3fd, 0x080c, 0x23a6, 0x2310,
- 0x001e, 0x0804, 0x13b8, 0x71c4, 0xa182, 0x0010, 0x0248, 0x2001,
- 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b3, 0x72c8, 0x0804, 0x13b2,
- 0x2011, 0x474d, 0x2204, 0x0006, 0x8104, 0x1208, 0x8108, 0x2112,
- 0x2019, 0x0000, 0x080c, 0x2393, 0x2001, 0x01ff, 0x2004, 0xd0fc,
- 0x0118, 0x001e, 0x0804, 0x13b9, 0x71c8, 0xa182, 0x0010, 0x0228,
- 0x0006, 0x2110, 0x71c4, 0x0804, 0x13b2, 0x2011, 0x478d, 0x2204,
- 0x0006, 0x8104, 0x1208, 0x8108, 0x2112, 0xc3fd, 0x080c, 0x2393,
- 0x002e, 0x001e, 0x0804, 0x13b8, 0x71c4, 0x72c8, 0xa184, 0xfffd,
- 0x1904, 0x13b2, 0xa284, 0xfffd, 0x1904, 0x13b2, 0x2100, 0x7920,
- 0x7822, 0x2200, 0x7a24, 0x7826, 0x0804, 0x13b8, 0x2011, 0x4c40,
- 0x71c4, 0xd1fc, 0x1110, 0x2011, 0x4bc0, 0x8107, 0xa084, 0x000f,
- 0x8003, 0x8003, 0x8003, 0xa268, 0x72c8, 0x73cc, 0x74d8, 0x71c6,
- 0x6800, 0x70ca, 0x73ce, 0x74da, 0x2091, 0x8000, 0x6a02, 0xd2ac,
- 0x1118, 0x2021, 0x0000, 0x0090, 0xa484, 0x00ff, 0xa082, 0x0002,
- 0x1a04, 0x174f, 0x843f, 0xa7bc, 0x00ff, 0x0140, 0xa786, 0x0002,
- 0x1904, 0x174f, 0xa484, 0x00ff, 0x0904, 0x174f, 0x2061, 0x0200,
- 0xd1fc, 0x0110, 0x2061, 0x0100, 0x2029, 0x0009, 0x2031, 0x0062,
- 0x843f, 0xa7bc, 0x00ff, 0x0130, 0x8307, 0xa084, 0x00ff, 0x1110,
- 0xa73d, 0x1138, 0x2041, 0x0019, 0xa384, 0x00ff, 0xa082, 0x001a,
- 0x0210, 0xa4a4, 0x00ff, 0x8307, 0xa084, 0x00ff, 0x0188, 0xa842,
- 0x02f0, 0xa086, 0x0010, 0x1120, 0xa39c, 0x00ff, 0xa39d, 0x0f00,
- 0xa3bc, 0x00ff, 0x2500, 0xa702, 0x0290, 0x2600, 0xa702, 0x1278,
- 0x2039, 0x003a, 0x6804, 0xa705, 0x6806, 0x6b0a, 0x6b0c, 0x73ce,
- 0x681c, 0x70da, 0x6c1e, 0x2091, 0x8001, 0x0804, 0x13ba, 0x2091,
- 0x8001, 0x0804, 0x13b4, 0x77c4, 0x080c, 0x1b9a, 0x2091, 0x8000,
- 0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e,
- 0x2708, 0x0804, 0x13b7, 0x70c4, 0x2061, 0x4740, 0x6118, 0x601a,
- 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x70c8, 0x2061,
- 0x4780, 0x6218, 0x601a, 0x0804, 0x13b8, 0x71c4, 0x72c8, 0x73cc,
- 0xa182, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x23d8, 0xa384, 0x4000,
- 0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x77c4, 0x080c, 0x1b9a,
- 0x2091, 0x8000, 0x6a08, 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708,
- 0x0804, 0x13b8, 0x77c4, 0x080c, 0x1b9a, 0x2091, 0x8000, 0x6a08,
- 0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0110, 0x080c, 0x22d5,
- 0x2091, 0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4, 0x080c, 0x1b9a,
- 0x2091, 0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005, 0x0110,
- 0x080c, 0x22d5, 0x2091, 0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4,
- 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000,
- 0x080c, 0x1bb2, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0804, 0x13b8,
- 0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1b29, 0x0138, 0x0804, 0x13bc,
- 0x080c, 0x1b1e, 0x0110, 0x0804, 0x13bc, 0x73c8, 0x72cc, 0x77c6,
- 0x73ca, 0x72ce, 0x080c, 0x1c2a, 0x11e8, 0x6818, 0xa005, 0x01a0,
- 0x2708, 0x0076, 0x080c, 0x23f7, 0x007e, 0x1170, 0x2001, 0x0015,
- 0xd7fc, 0x1118, 0x2061, 0x4740, 0x0018, 0xc0fd, 0x2061, 0x4780,
- 0x782a, 0x2091, 0x8001, 0x0005, 0x2091, 0x8001, 0x2001, 0x4005,
- 0x0804, 0x13bc, 0x2091, 0x8001, 0x0804, 0x13ba, 0x77c4, 0xd7fc,
- 0x0128, 0x080c, 0x1b29, 0x0138, 0x0804, 0x13bc, 0x080c, 0x1b1e,
- 0x0110, 0x0804, 0x13bc, 0x77c6, 0x2041, 0x0021, 0x2049, 0x0005,
- 0x2051, 0x0020, 0x2091, 0x8000, 0x080c, 0x1bb2, 0x2009, 0x0016,
- 0xd7fc, 0x1118, 0x2061, 0x4740, 0x0018, 0x2061, 0x4780, 0xc1fd,
- 0x6063, 0x0003, 0x607b, 0x0000, 0x6772, 0x607f, 0x000f, 0x792a,
- 0x61d0, 0xc1c4, 0x61d2, 0x080c, 0x22d5, 0x2091, 0x8001, 0x0005,
- 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xd7fc, 0x0128, 0x080c, 0x1b29,
- 0x0138, 0x0804, 0x13bc, 0x080c, 0x1b1e, 0x0110, 0x0804, 0x13bc,
- 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2009, 0x0017, 0xd7fc, 0x1118,
- 0x2061, 0x4740, 0x0018, 0x2061, 0x4780, 0xc1fd, 0x607b, 0x0000,
- 0x6063, 0x0002, 0x6772, 0x607f, 0x000f, 0x792a, 0x61d0, 0xc1c4,
- 0x61d2, 0x080c, 0x22d5, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049,
- 0x0005, 0x2051, 0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0118,
- 0x60d0, 0xc0fd, 0x60d2, 0x080c, 0x1bb2, 0x70c8, 0x6836, 0x8738,
- 0xa784, 0x001f, 0x1dc0, 0x2091, 0x8001, 0x0005, 0x2019, 0x0000,
- 0x72c8, 0xd284, 0x0128, 0x080c, 0x1b29, 0x0138, 0x0804, 0x13bc,
- 0x080c, 0x1b1e, 0x0110, 0x0804, 0x13bc, 0x72c8, 0x72ca, 0x78ac,
- 0xa084, 0x0003, 0x1518, 0x2039, 0x0000, 0xd284, 0x0108, 0xc7fd,
- 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x080c, 0x1b9a,
- 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d, 0x690a, 0x6837, 0x0000,
- 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x1d80, 0xa7bc, 0xff00,
- 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d40, 0x2091, 0x8000,
- 0x72c8, 0x2069, 0x0100, 0xd284, 0x1110, 0x2069, 0x0200, 0x6808,
- 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x01b0, 0x684b, 0x0004,
- 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x18c2, 0x684b,
- 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04, 0x18cb,
- 0x20a9, 0x00fa, 0x1f04, 0x18d2, 0x2079, 0x4700, 0x2009, 0x0018,
- 0x72c8, 0xd284, 0x1118, 0x2061, 0x4740, 0x0018, 0x2061, 0x4780,
- 0xc1fd, 0x607b, 0x0000, 0x792a, 0x6063, 0x0001, 0x607f, 0x000f,
- 0x60a3, 0x0000, 0x60a4, 0x60ae, 0x60b2, 0x60d0, 0xd0b4, 0x0160,
- 0xc0b4, 0x60d2, 0x00c6, 0x60b4, 0xa065, 0x6008, 0xc0d4, 0x600a,
- 0x6018, 0x8001, 0x601a, 0x00ce, 0x60d0, 0xa084, 0x7eff, 0x60d2,
- 0x78ac, 0xc08d, 0x78ae, 0x83ff, 0x0108, 0x0005, 0x681b, 0x0054,
- 0x2091, 0x8001, 0x0005, 0x73cc, 0x080c, 0x1878, 0x69ec, 0x6a48,
- 0xa185, 0x1800, 0x684a, 0xa185, 0x0040, 0x68ee, 0x73cc, 0x2021,
- 0x0004, 0x20a9, 0x09ff, 0x1f04, 0x191b, 0x8421, 0x1dd0, 0x8319,
- 0x1db0, 0x69ee, 0x6a4a, 0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118,
- 0x2069, 0x4740, 0x0010, 0x2069, 0x4780, 0x71c4, 0x71c6, 0x6916,
- 0x81ff, 0x1110, 0x68a3, 0x0001, 0x78ac, 0xc08c, 0x78ae, 0xd084,
- 0x1110, 0x080c, 0x1c7a, 0x0005, 0x75d8, 0x74dc, 0x75da, 0x74de,
- 0x0010, 0xa02e, 0x2520, 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca,
- 0x72ce, 0x2079, 0x4700, 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x080c,
- 0x1b77, 0x0904, 0x1a5c, 0x20a9, 0x0005, 0x20a1, 0x4714, 0x2091,
- 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0040, 0x080c, 0x1d41,
- 0x0120, 0x080c, 0x1b7f, 0x0804, 0x1a5c, 0x6004, 0xa08c, 0x00ff,
- 0xa18e, 0x0009, 0x1120, 0x0006, 0x080c, 0x2086, 0x000e, 0xa084,
- 0xff00, 0x8007, 0x8009, 0x0904, 0x19f1, 0x00c6, 0x2c68, 0x080c,
- 0x1b77, 0x05a8, 0x2c00, 0x689e, 0x8109, 0x1dc0, 0x609f, 0x0000,
- 0x00ce, 0x00c6, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040,
- 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda,
- 0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0904, 0x19f0, 0x2009,
- 0x0040, 0x080c, 0x1d41, 0x15a0, 0x6004, 0xa084, 0x00ff, 0xa086,
- 0x0002, 0x0150, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000a, 0x1138,
- 0x0016, 0x080c, 0x2083, 0x001e, 0x2d00, 0x6002, 0x0898, 0x00ce,
- 0x00c6, 0x609c, 0x080c, 0x1bf3, 0x00ce, 0x609f, 0x0000, 0x080c,
- 0x1a60, 0x2009, 0x0018, 0x6008, 0xc0cd, 0x600a, 0x6004, 0x6086,
- 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
- 0x080c, 0x1b34, 0x000e, 0x7812, 0x080c, 0x1b7f, 0x0804, 0x1a5c,
- 0x00ce, 0x00c6, 0x609c, 0x080c, 0x1bf3, 0x00ce, 0x609f, 0x0000,
- 0x080c, 0x1a60, 0x2009, 0x0018, 0x6087, 0x0103, 0x601b, 0x0003,
- 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
- 0x080c, 0x1b34, 0x000e, 0x7812, 0x080c, 0x1b7f, 0x0804, 0x1a5c,
- 0x00ce, 0x6114, 0xd1fc, 0x0120, 0x080c, 0x1b29, 0x01f0, 0x0018,
- 0x080c, 0x1b1e, 0x01d0, 0x080c, 0x1a60, 0x2009, 0x0018, 0x6087,
- 0x0103, 0x601b, 0x0021, 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff,
- 0x0110, 0xc0c5, 0x7812, 0x080c, 0x1b34, 0x000e, 0x7812, 0x080c,
- 0x1b7f, 0x2001, 0x4007, 0x0804, 0x13bc, 0x6104, 0xa18c, 0x00ff,
- 0xa186, 0x0005, 0x1118, 0x601c, 0xc0bd, 0x601e, 0x74c4, 0x73c8,
- 0x72cc, 0x6014, 0x2091, 0x8000, 0x00e6, 0x2009, 0x0012, 0xd0fc,
- 0x1118, 0x2071, 0x4740, 0x0018, 0x2071, 0x4780, 0xc1fd, 0x792a,
- 0x7063, 0x0005, 0x71d0, 0xc1c4, 0x71d2, 0x7366, 0x726a, 0x746e,
- 0x7072, 0x7077, 0x0000, 0x2c00, 0x707a, 0xa02e, 0x2530, 0x611c,
- 0xa184, 0x0060, 0x0110, 0x080c, 0x3fe9, 0x00ee, 0x6596, 0x65a6,
- 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714, 0x6023,
- 0x0000, 0x6024, 0xa096, 0x0001, 0x1110, 0x8000, 0x6026, 0x080c,
- 0x22d5, 0x2091, 0x8001, 0x0005, 0x70c3, 0x4005, 0x0804, 0x13bd,
- 0x20a9, 0x0005, 0x2099, 0x4714, 0x2091, 0x8000, 0x530a, 0x2091,
- 0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
- 0x0000, 0x0005, 0x71c4, 0x70c7, 0x0000, 0x791e, 0x0804, 0x13ba,
- 0x71c4, 0x71c6, 0x2168, 0x0010, 0x2069, 0x1000, 0x690c, 0xa016,
- 0x2d04, 0xa210, 0x8d68, 0x8109, 0x1dd8, 0xa285, 0x0000, 0x1118,
- 0x70c3, 0x4000, 0x0010, 0x70c3, 0x4003, 0x70ca, 0x0804, 0x13bd,
- 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x1a04, 0x13b3, 0x7966,
- 0x0804, 0x13ba, 0x7964, 0x71c6, 0x0804, 0x13ba, 0x7900, 0x71c6,
- 0x71c4, 0x7902, 0x0804, 0x13ba, 0x7900, 0x71c6, 0x0804, 0x13ba,
- 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0160, 0x810c, 0x0230,
- 0x8210, 0x810c, 0x810c, 0x0210, 0x8210, 0x810c, 0x81ff, 0x1904,
- 0x13b4, 0x8210, 0x7a0e, 0xd28c, 0x0538, 0x7910, 0xc1cd, 0x7912,
- 0x2009, 0x0021, 0x2019, 0x0003, 0xd284, 0x01c0, 0x8108, 0x2019,
- 0x0041, 0x2011, 0x8f4e, 0x2312, 0x2019, 0x0042, 0x8210, 0x2312,
- 0x2019, 0x0043, 0x8210, 0x2312, 0x2019, 0x0046, 0x8210, 0x2312,
- 0x2019, 0x0047, 0x8210, 0x2312, 0x2019, 0x0006, 0x2011, 0x8f53,
- 0x2112, 0x2011, 0x8f73, 0x2312, 0x7904, 0x7806, 0x0804, 0x13b9,
- 0x7804, 0x70c6, 0x0804, 0x13ba, 0x71c4, 0xd1fc, 0x1118, 0x2011,
- 0x4bc0, 0x0010, 0x2011, 0x4c40, 0x8107, 0xa084, 0x000f, 0x8003,
- 0x8003, 0x8003, 0xa268, 0x2011, 0x0000, 0x6814, 0xd0fc, 0x0110,
- 0xa295, 0x0200, 0xd0b4, 0x0110, 0xa295, 0x0001, 0x6b0c, 0x6800,
- 0x70da, 0x0804, 0x13b7, 0x7814, 0xd0f4, 0x0130, 0x2001, 0x4007,
- 0x70db, 0x0000, 0xa005, 0x0048, 0xd0fc, 0x0130, 0x2001, 0x4007,
- 0x70db, 0x0001, 0xa005, 0x0008, 0xa006, 0x0005, 0x7814, 0xd0f4,
- 0x0130, 0x2001, 0x4007, 0x70db, 0x0000, 0xa005, 0x0008, 0xa006,
- 0x0005, 0x7814, 0xd0fc, 0x0130, 0x2001, 0x4007, 0x70db, 0x0001,
- 0xa005, 0x0008, 0xa006, 0x0005, 0x7112, 0x721a, 0x731e, 0x7810,
- 0xd0c4, 0x0110, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, 0x810c,
- 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084, 0x20a2,
- 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0140, 0x810f,
- 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107,
- 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211, 0x7d10,
- 0xd5c4, 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008, 0xd0fc,
- 0x0de8, 0x7003, 0x0001, 0x7007, 0x0006, 0x711a, 0x721e, 0x7d10,
- 0xd5c4, 0x0110, 0x7322, 0x7426, 0xa084, 0x01e0, 0x0005, 0x7848,
- 0xa065, 0x0120, 0x2c04, 0x784a, 0x2063, 0x0000, 0x0005, 0x00f6,
- 0x2079, 0x4700, 0x7848, 0x2062, 0x2c00, 0xa005, 0x1110, 0x080c,
- 0x2575, 0x784a, 0x00fe, 0x0005, 0x2011, 0x9100, 0x7a4a, 0x7bc4,
- 0x8319, 0x0128, 0xa280, 0x0032, 0x2012, 0x2010, 0x0cc8, 0x2013,
- 0x0000, 0x0005, 0x0016, 0x0026, 0xd7fc, 0x1118, 0x2011, 0x4cc0,
- 0x0010, 0x2011, 0x6cc0, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f,
- 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa268, 0x002e,
- 0x001e, 0x0005, 0x0c39, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808,
- 0xa084, 0xf9ef, 0xa80d, 0x690a, 0x00e6, 0xd7fc, 0x1128, 0x2009,
- 0x4752, 0x2071, 0x4740, 0x0020, 0x2009, 0x4792, 0x2071, 0x4780,
- 0x210c, 0x6804, 0xa005, 0x0148, 0xa116, 0x1138, 0x2060, 0x6000,
- 0x6806, 0x0016, 0x200b, 0x0000, 0x0018, 0x2009, 0x0000, 0x0016,
- 0x6804, 0xa065, 0x0178, 0x6000, 0x6806, 0x0421, 0x080c, 0x1db2,
- 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x6812, 0x1d88, 0x7910,
- 0xc1a5, 0x7912, 0x001e, 0x6902, 0x6906, 0x2d00, 0x2060, 0x080c,
- 0x26bf, 0x00ee, 0x0005, 0xa065, 0x0160, 0x2008, 0x609c, 0xa005,
- 0x0128, 0x2062, 0x609f, 0x0000, 0xa065, 0x0cc0, 0x7848, 0x794a,
- 0x2062, 0x0005, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c,
- 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a,
- 0x682c, 0x6022, 0x0005, 0x00e6, 0xd7fc, 0x1128, 0x2071, 0x4740,
- 0x2031, 0x47c0, 0x0020, 0x2071, 0x4780, 0x2031, 0x49c0, 0x704c,
- 0xa08c, 0x0200, 0x1128, 0xa608, 0x2d0a, 0x8000, 0x704e, 0xa006,
- 0x00ee, 0x0005, 0x00f6, 0xd7fc, 0x1118, 0x2079, 0x4740, 0x0010,
- 0x2079, 0x4780, 0x080c, 0x1b9a, 0x2091, 0x8000, 0x6804, 0x780a,
- 0xa065, 0x05f0, 0x0030, 0x2c00, 0x780a, 0x2060, 0x6000, 0xa065,
- 0x05b8, 0x6010, 0xa306, 0x1db8, 0x600c, 0xa206, 0x1da0, 0x2c28,
- 0x7848, 0xac06, 0x1108, 0x0448, 0x6804, 0xac06, 0x1140, 0x6000,
- 0x2060, 0x6806, 0xa005, 0x1118, 0x6803, 0x0000, 0x0048, 0x6400,
- 0x7808, 0x2060, 0x6402, 0xa486, 0x0000, 0x1110, 0x2c00, 0x6802,
- 0x2560, 0x080c, 0x1c02, 0x601b, 0x0005, 0x6023, 0x0020, 0x00fe,
- 0x080c, 0x1db2, 0x00f6, 0x7908, 0x8109, 0x790a, 0x6810, 0x8001,
- 0x6812, 0x1118, 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff, 0xa005,
- 0x00fe, 0x0005, 0x0076, 0x2700, 0x2039, 0x0000, 0xd0fc, 0x0108,
- 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x2091,
- 0x8000, 0x080c, 0x1bb2, 0x8738, 0xa784, 0x001f, 0x1dd0, 0xa7bc,
- 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d90, 0x2091,
- 0x8001, 0x007e, 0x0005, 0x786c, 0x2009, 0x8f74, 0x210c, 0xa10d,
- 0x0118, 0xa065, 0x0804, 0x20a1, 0x2061, 0x0000, 0x6018, 0xd084,
- 0x11b8, 0x7810, 0xd08c, 0x0130, 0xc08c, 0x7812, 0xc7fc, 0x2069,
- 0x4740, 0x0028, 0xc08d, 0x7812, 0x2069, 0x4780, 0xc7fd, 0x2091,
- 0x8000, 0x681c, 0x681f, 0x0000, 0x2091, 0x8001, 0xa005, 0x1108,
- 0x0005, 0xa08c, 0xfff0, 0x0110, 0x080c, 0x2575, 0x0002, 0x1cd7,
- 0x1cda, 0x1ce0, 0x1ce4, 0x1cd8, 0x1ce8, 0x1cd8, 0x1cd8, 0x1cd8,
- 0x1cee, 0x1d18, 0x1d1b, 0x1d20, 0x1d29, 0x1cd8, 0x1cd8, 0x0005,
- 0x080c, 0x2575, 0x080c, 0x1c7a, 0x2001, 0x8001, 0x0804, 0x1d32,
- 0x2001, 0x8003, 0x0804, 0x1d32, 0x2001, 0x8004, 0x0804, 0x1d32,
- 0x080c, 0x1c7a, 0x2001, 0x8006, 0x0804, 0x1d32, 0x2011, 0x800a,
- 0x2091, 0x8000, 0xd7fc, 0x1118, 0x2069, 0x4740, 0x0010, 0x2069,
- 0x4780, 0x2038, 0x6800, 0xa086, 0x0000, 0x0120, 0x6f1e, 0x2091,
- 0x8001, 0x0005, 0x0026, 0x6870, 0xa0bc, 0xff00, 0x2041, 0x0021,
- 0x2049, 0x0004, 0x2051, 0x0010, 0x080c, 0x1bb2, 0x8738, 0xa784,
- 0x001f, 0x1dd0, 0x2091, 0x8001, 0x000e, 0x6970, 0x71c6, 0x00d0,
- 0x2001, 0x800c, 0x00b8, 0x080c, 0x1c7a, 0x2001, 0x800d, 0x0090,
- 0xd7fc, 0x0110, 0x78e4, 0x0008, 0x78e0, 0x70c6, 0x2001, 0x800e,
- 0x0048, 0xd7fc, 0x0110, 0x78ec, 0x0008, 0x78e8, 0x70c6, 0x2001,
- 0x800f, 0x0000, 0x70c2, 0xd7fc, 0x1118, 0x70db, 0x0000, 0x0010,
- 0x70db, 0x0001, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080,
- 0x0005, 0xac80, 0x0001, 0x81ff, 0x0518, 0x2099, 0x0030, 0x20a0,
- 0x700c, 0xa084, 0x07ff, 0x0100, 0x7018, 0x0006, 0x701c, 0x0006,
- 0x7020, 0x0006, 0x7024, 0x0006, 0x7112, 0x81ac, 0x721a, 0x731e,
- 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001, 0x7008, 0x800b,
- 0x1ee8, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x1110, 0x53a5, 0xa006,
- 0x7003, 0x0000, 0x7007, 0x0004, 0x000e, 0x7026, 0x000e, 0x7022,
- 0x000e, 0x701e, 0x000e, 0x701a, 0x0005, 0x2011, 0x0020, 0x2009,
- 0x0010, 0x6b0a, 0x6c0e, 0x681f, 0x0201, 0x6803, 0xfd20, 0x6807,
- 0x0038, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004, 0x8109,
- 0x1d80, 0x0005, 0x70ec, 0xd0dc, 0x1520, 0x2029, 0x0001, 0x7814,
- 0xd0cc, 0x1160, 0x70ec, 0xd0e4, 0x2019, 0x0c0a, 0x2021, 0x000a,
- 0x1120, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x0070, 0x70ec, 0xd0e4,
- 0x1128, 0x2019, 0x180c, 0x2021, 0x000c, 0x0030, 0x2019, 0x1809,
- 0x2021, 0x0009, 0xa5ad, 0x0200, 0x6b0a, 0x6c0e, 0x6d1e, 0x6807,
- 0x0038, 0x0005, 0x6004, 0x6086, 0x2c08, 0x2063, 0x0000, 0x7868,
- 0xa005, 0x796a, 0x0110, 0x2c02, 0x0008, 0x796e, 0x0005, 0x00c6,
- 0x2061, 0x4700, 0x6887, 0x0103, 0x2d08, 0x206b, 0x0000, 0x6068,
- 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008, 0x616e, 0x00ce, 0x0005,
- 0x2091, 0x8000, 0x2c04, 0x786e, 0xa005, 0x1108, 0x786a, 0x2091,
- 0x8001, 0x609c, 0xa005, 0x0188, 0x00c6, 0x2060, 0x2008, 0x609c,
- 0xa005, 0x0138, 0x2062, 0x609f, 0x0000, 0xa065, 0x609c, 0xa005,
- 0x1dc8, 0x7848, 0x794a, 0x2062, 0x00ce, 0x7848, 0x2062, 0x609f,
- 0x0000, 0xac85, 0x0000, 0x1110, 0x080c, 0x2575, 0x784a, 0x0005,
- 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x1208, 0xa200,
- 0x1f04, 0x1dfc, 0x8086, 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010,
- 0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a,
- 0x1220, 0x1f04, 0x1e0c, 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04,
- 0x1e0c, 0x0006, 0x3200, 0xa084, 0xefff, 0x2080, 0x000e, 0x015e,
- 0x0005, 0x0006, 0x3200, 0xa085, 0x1000, 0x0cb8, 0x7d74, 0x70d0,
- 0xa506, 0x0904, 0x1eda, 0x7810, 0x2050, 0x080c, 0x1b77, 0x0904,
- 0x1eda, 0xa046, 0x7970, 0x2500, 0x8000, 0xa112, 0x2009, 0x0040,
- 0x1208, 0x0030, 0x72d0, 0xa206, 0x0118, 0x8840, 0x2009, 0x0080,
- 0x00c6, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, 0x0020,
- 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0110, 0x080c,
- 0x1b77, 0x7008, 0xd0fc, 0x0de8, 0x7007, 0x0002, 0x2091, 0x8001,
- 0xa08c, 0x01e0, 0x1538, 0x53a5, 0x8cff, 0x1120, 0x88ff, 0x0904,
- 0x1ec7, 0x0050, 0x2c00, 0x788e, 0x20a9, 0x0020, 0xac80, 0x0001,
- 0x20a0, 0x53a5, 0x0804, 0x1ec7, 0xa046, 0x7218, 0x731c, 0xdac4,
- 0x0110, 0x7420, 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3,
- 0x0000, 0xa5ab, 0x0000, 0x721a, 0x731e, 0xdac4, 0x0118, 0x7422,
- 0x7526, 0xa006, 0x7007, 0x0004, 0x0904, 0x1ec7, 0x8cff, 0x0110,
- 0x080c, 0x1b7f, 0x00ce, 0x080c, 0x1b7f, 0xa046, 0x7888, 0x8000,
- 0x788a, 0xa086, 0x0002, 0x01c0, 0x7a7c, 0x7b78, 0xdac4, 0x0110,
- 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399,
- 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a, 0x731e, 0xdac4,
- 0x0588, 0x7422, 0x7526, 0x0470, 0x6014, 0xd0fc, 0x1118, 0x2069,
- 0x4740, 0x0010, 0x2069, 0x4780, 0x2091, 0x8000, 0x681f, 0x0002,
- 0x88ff, 0x0120, 0xa046, 0x788c, 0x2060, 0x0c70, 0x788b, 0x0000,
- 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0098, 0x00ce,
- 0x788b, 0x0000, 0x080c, 0x205c, 0x6004, 0xa084, 0x000f, 0x0059,
- 0x88ff, 0x0130, 0x788c, 0x2060, 0x6004, 0xa084, 0x000f, 0x0019,
- 0x0804, 0x1e26, 0x0005, 0x0002, 0x1eec, 0x1f07, 0x1f20, 0x1eec,
- 0x1f2d, 0x1efd, 0x1eec, 0x1eec, 0x1eec, 0x1f05, 0x1f1e, 0x1eec,
- 0x1eec, 0x1eec, 0x1eec, 0x1eec, 0x2039, 0x0400, 0x78bc, 0xa705,
- 0x78be, 0x6008, 0xa705, 0x600a, 0x080c, 0x1f69, 0x609c, 0x78ba,
- 0x609f, 0x0000, 0x080c, 0x2048, 0x0005, 0x78bc, 0xd0c4, 0x0108,
- 0x0c58, 0x601c, 0xc0bd, 0x601e, 0x0030, 0x080c, 0x2086, 0x78bc,
- 0xd0c4, 0x0108, 0x0c08, 0x78bf, 0x0000, 0x6004, 0x8007, 0xa084,
- 0x00ff, 0x78b2, 0x8001, 0x0138, 0x080c, 0x1f69, 0x0120, 0x78bc,
- 0xc0c5, 0x78be, 0x0010, 0x0804, 0x1f84, 0x0005, 0x080c, 0x2083,
- 0x78bc, 0xa08c, 0x0e00, 0x1110, 0xd0c4, 0x1108, 0x0828, 0x080c,
- 0x1f69, 0x1110, 0x0804, 0x1f84, 0x0005, 0x78bc, 0xd0c4, 0x0110,
- 0x0804, 0x1eec, 0x78bf, 0x0000, 0x6714, 0x2011, 0x0001, 0x22a8,
- 0x6018, 0xa084, 0x00ff, 0xa005, 0x0188, 0xa7bc, 0xff00, 0x20a9,
- 0x0020, 0xa08e, 0x0001, 0x0150, 0xa7bc, 0x8000, 0x2011, 0x0002,
- 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0108, 0x00c0, 0x080c, 0x1b9a,
- 0x2d00, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808,
- 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x1f04,
- 0x1f51, 0x8211, 0x0118, 0x20a9, 0x0100, 0x0c58, 0x080c, 0x1b7f,
- 0x0005, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, 0x1110,
- 0x78ba, 0x0038, 0x689e, 0x2d00, 0x6002, 0x78b8, 0xad06, 0x1108,
- 0x6002, 0x78b0, 0x8001, 0x78b2, 0x1130, 0x78bc, 0xc0c4, 0x78be,
- 0x78b8, 0x2060, 0xa006, 0x0005, 0x00e6, 0xa02e, 0x2530, 0x7dba,
- 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2, 0x2048, 0xa984, 0xe1ff,
- 0x601e, 0xa984, 0x0060, 0x0160, 0x080c, 0x3fe9, 0x86ff, 0x1140,
- 0x85ff, 0x1130, 0x2039, 0x0800, 0x080c, 0x2048, 0x0804, 0x2046,
- 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, 0x4780, 0xd7fc,
- 0x1110, 0x2071, 0x4740, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f,
- 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x71c0, 0xa168,
- 0x2700, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x71c4,
- 0xa100, 0x60c2, 0x2091, 0x8000, 0x7814, 0xd0c4, 0x0138, 0xd7fc,
- 0x1118, 0xd0f4, 0x1140, 0x0010, 0xd0fc, 0x1128, 0x6e08, 0xd684,
- 0x01f0, 0xd9fc, 0x11e0, 0x2091, 0x8001, 0x080c, 0x1c02, 0x2091,
- 0x8000, 0x080c, 0x1db2, 0x2091, 0x8001, 0x7814, 0xd0c4, 0x0904,
- 0x2046, 0xd7fc, 0x1120, 0xd0f4, 0x1130, 0x0804, 0x2046, 0xd0fc,
- 0x1110, 0x0804, 0x2046, 0x601b, 0x0021, 0x0804, 0x2046, 0x6024,
- 0xa096, 0x0001, 0x1110, 0x8000, 0x6026, 0x6a10, 0x6814, 0xa202,
- 0x0268, 0x0160, 0x2091, 0x8001, 0x2039, 0x0200, 0x609c, 0x78ba,
- 0x609f, 0x0000, 0x080c, 0x2048, 0x0804, 0x2046, 0x2c08, 0xd9fc,
- 0x01f0, 0x6800, 0xa065, 0x01d8, 0x6a04, 0x7000, 0xa084, 0x0002,
- 0x0168, 0x7048, 0xa206, 0x1150, 0x6b04, 0x2160, 0x2304, 0x6002,
- 0xa005, 0x1108, 0x6902, 0x2260, 0x6102, 0x0098, 0x2d00, 0x2060,
- 0x080c, 0x26bf, 0x6e08, 0x2160, 0x6202, 0x6906, 0x0050, 0x6800,
- 0x6902, 0xa065, 0x0110, 0x6102, 0x0008, 0x6906, 0x2160, 0x6003,
- 0x0000, 0x2160, 0xd9fc, 0x0118, 0xa6b4, 0xfffc, 0x6e0a, 0x6810,
- 0x7d08, 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4,
- 0x0128, 0xa6b6, 0x0040, 0x6e0a, 0x080c, 0x1c13, 0x00ee, 0x0005,
- 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x080c, 0x1db2, 0x2091,
- 0x8001, 0x78b8, 0xa065, 0x0128, 0x609c, 0x78ba, 0x609f, 0x0000,
- 0x0c78, 0x78b6, 0x78ba, 0x0005, 0x7970, 0x7874, 0x2818, 0xd384,
- 0x0118, 0x8000, 0xa112, 0x0220, 0x8000, 0xa112, 0x1278, 0xc384,
- 0x7a7c, 0x721a, 0x7a78, 0x721e, 0xdac4, 0x0120, 0x7a84, 0x7222,
- 0x7a80, 0x7226, 0xa006, 0xd384, 0x0108, 0x8000, 0x7876, 0x70d2,
- 0x781c, 0xa005, 0x0138, 0x8001, 0x781e, 0x1120, 0x0e04, 0x2082,
- 0x2091, 0x4080, 0x0005, 0x2039, 0x2098, 0x0010, 0x2039, 0x209e,
- 0x2704, 0xa005, 0x0160, 0xac00, 0x2068, 0x6908, 0x6810, 0x6912,
- 0x680a, 0x690c, 0x6814, 0x6916, 0x680e, 0x8738, 0x0c88, 0x0005,
- 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015, 0x001b,
- 0x0000, 0x2041, 0x0000, 0x780c, 0x0002, 0x224a, 0x2225, 0x20a9,
- 0x2119, 0x2039, 0x8f74, 0x2734, 0x7d10, 0x00c0, 0x6084, 0xa086,
- 0x0103, 0x1904, 0x2103, 0x6114, 0x6018, 0xa105, 0x0120, 0x86ff,
- 0x11d8, 0x0804, 0x2103, 0x8603, 0xa080, 0x8f55, 0x620c, 0x2202,
- 0x8000, 0x6210, 0x2202, 0x080c, 0x1dd0, 0x8630, 0xa68e, 0x000f,
- 0x0904, 0x2184, 0x786c, 0xa065, 0x1d08, 0x7808, 0xa602, 0x1220,
- 0xd5ac, 0x1110, 0x263a, 0x0005, 0xa682, 0x0003, 0x1a04, 0x2184,
- 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x11f8, 0x2011,
- 0x8f55, 0x2204, 0x70c6, 0x8210, 0x2204, 0x70ca, 0xd684, 0x1130,
- 0x8210, 0x2204, 0x70da, 0x8210, 0x2204, 0x70de, 0xa685, 0x8020,
- 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf,
- 0x7812, 0x2091, 0x8001, 0x203b, 0x0000, 0x0005, 0x7810, 0xc0ad,
- 0x7812, 0x0804, 0x2184, 0x263a, 0x080c, 0x2250, 0x1904, 0x226c,
- 0x786c, 0xa065, 0x1904, 0x20ae, 0x2091, 0x8000, 0x7810, 0xa084,
- 0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0804,
- 0x226c, 0x2039, 0x8f74, 0x2734, 0x7d10, 0x00a0, 0x6084, 0xa086,
- 0x0103, 0x1904, 0x216e, 0x6114, 0x6018, 0xa105, 0x0120, 0x86ff,
- 0x11b8, 0x0804, 0x216e, 0xa680, 0x8f55, 0x620c, 0x2202, 0x080c,
- 0x1dd0, 0x8630, 0xa68e, 0x001e, 0x0904, 0x2184, 0x786c, 0xa065,
- 0x1d28, 0x7808, 0xa602, 0x1220, 0xd5ac, 0x1110, 0x263a, 0x0005,
- 0xa682, 0x0006, 0x1a04, 0x2184, 0x2091, 0x8000, 0x2069, 0x0000,
- 0x6818, 0xd084, 0x11f8, 0x2011, 0x8f55, 0x2009, 0x8f4e, 0x26a8,
- 0x211c, 0x2204, 0x201a, 0x8108, 0x8210, 0x1f04, 0x2150, 0xa685,
- 0x8030, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084,
- 0xffcf, 0x7812, 0x2091, 0x8001, 0xa006, 0x2009, 0x8f75, 0x200a,
- 0x203a, 0x0005, 0x7810, 0xc0ad, 0x7812, 0x00b0, 0x263a, 0x080c,
- 0x2250, 0x1904, 0x226c, 0x786c, 0xa065, 0x1904, 0x211e, 0x2091,
- 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812,
- 0x2091, 0x8001, 0x0804, 0x226c, 0x2091, 0x8000, 0x7007, 0x0004,
- 0x7994, 0x70d4, 0xa102, 0x0228, 0x0168, 0x7b90, 0xa302, 0x1150,
- 0x0010, 0x8002, 0x1138, 0x263a, 0x7810, 0xc0ad, 0x7812, 0x2091,
- 0x8001, 0x0005, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c, 0x810c,
- 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107, 0x8004, 0x8004,
- 0x7a9c, 0xa210, 0x721a, 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4,
- 0x0130, 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1,
- 0x0030, 0x7003, 0x0000, 0x2009, 0x8f54, 0x260a, 0x8109, 0x2198,
- 0x2104, 0xd084, 0x0108, 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6,
- 0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, 0xa10a,
- 0x1208, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0140, 0x810f,
- 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107,
- 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211, 0xd4c4,
- 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0de8,
- 0xa084, 0x01e0, 0x01d0, 0x7d10, 0x2031, 0x8f54, 0x2634, 0x78a8,
- 0x8000, 0x78aa, 0xd08c, 0x1138, 0x7007, 0x0006, 0x7004, 0xd094,
- 0x1de8, 0x0804, 0x2186, 0x2069, 0x4747, 0x206b, 0x0003, 0x78ac,
- 0xa085, 0x0300, 0x78ae, 0xa006, 0x0048, 0x2030, 0x75d6, 0x2091,
- 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091, 0x8001,
- 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a, 0x721e,
- 0xd5c4, 0x0110, 0x7322, 0x7426, 0x0005, 0x6084, 0xa086, 0x0103,
- 0x11d8, 0x6114, 0x6018, 0xa105, 0x11b8, 0x2069, 0x0000, 0x6818,
- 0xd084, 0x1190, 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020,
- 0x681b, 0x0001, 0x2091, 0x4080, 0x080c, 0x1dd0, 0x0e04, 0x2243,
- 0x786c, 0xa065, 0x1d10, 0x0005, 0x0059, 0x1530, 0x786c, 0xa065,
- 0x19e0, 0x0410, 0x0029, 0x1500, 0x786c, 0xa065, 0x1dd8, 0x00e0,
- 0x6084, 0xa086, 0x0103, 0x1168, 0x6018, 0xc0fc, 0x601a, 0xa086,
- 0x0004, 0x1138, 0x7804, 0xd0a4, 0x0120, 0x080c, 0x1dd0, 0xa006,
- 0x0005, 0x0079, 0x1118, 0xa085, 0x0001, 0x0005, 0x00b9, 0x1110,
- 0x2041, 0x0001, 0x7d10, 0x0005, 0x88ff, 0x0110, 0x2091, 0x4080,
- 0x0005, 0x7b90, 0x7994, 0x70d4, 0xa102, 0x1118, 0xa385, 0x0000,
- 0x0005, 0x0210, 0xa302, 0x0005, 0x8002, 0x0005, 0xa184, 0xff00,
- 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
- 0x0018, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0,
- 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018, 0x6028,
- 0xa005, 0x0110, 0x2009, 0x0040, 0x080c, 0x1b34, 0x01d0, 0x78a8,
- 0x8000, 0x78aa, 0xd08c, 0x1510, 0x6014, 0xd0fc, 0x1118, 0x2069,
- 0x4740, 0x0010, 0x2069, 0x4780, 0x2091, 0x8000, 0x681f, 0x0003,
- 0x78ab, 0x0000, 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001,
- 0x0068, 0x78ab, 0x0000, 0x080c, 0x1dd0, 0x7990, 0x7894, 0x8000,
- 0xa10a, 0x1208, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071, 0x0010,
- 0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118, 0x2009, 0x4758, 0x0010,
- 0x2009, 0x4798, 0x2091, 0x8000, 0x200a, 0x00f6, 0x2009, 0x4780,
- 0x2079, 0x0100, 0xd7fc, 0x1120, 0x2009, 0x4740, 0x2079, 0x0200,
- 0x2104, 0xa086, 0x0000, 0x1180, 0xd7fc, 0x1118, 0x2009, 0x4745,
- 0x0010, 0x2009, 0x4785, 0x2104, 0xa005, 0x1130, 0x7830, 0xa084,
- 0x00c0, 0x1110, 0x781b, 0x0052, 0x00fe, 0x0005, 0x2009, 0x0002,
- 0x2069, 0x4700, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x234b,
- 0x2071, 0x4780, 0x2079, 0x0100, 0x2021, 0x49bf, 0x784b, 0x000f,
- 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118, 0x2019, 0x3e37, 0x0030,
- 0x20a1, 0x012b, 0x2019, 0x3e37, 0xd184, 0x0110, 0x20a1, 0x022b,
- 0x2304, 0xa005, 0x0140, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398,
- 0x53a6, 0x3318, 0x0ca8, 0x789b, 0x0000, 0x789b, 0x0020, 0x20a9,
- 0x0010, 0x78af, 0x0000, 0x78af, 0x2020, 0x1f04, 0x2329, 0x7003,
- 0x0000, 0x0016, 0xd18c, 0x2009, 0x0000, 0x0108, 0xc1bd, 0x080c,
- 0x246c, 0x001e, 0x7020, 0xa084, 0x000f, 0xa085, 0x6300, 0x7806,
- 0x780f, 0x9000, 0x7843, 0x00d8, 0x7853, 0x0090, 0x780b, 0x2f08,
- 0x7452, 0x704f, 0x0000, 0x8109, 0x0140, 0x2071, 0x4740, 0x2079,
- 0x0200, 0x2021, 0x47bf, 0x0804, 0x2306, 0x080c, 0x2526, 0x0005,
- 0x0016, 0x2011, 0x0101, 0xd1bc, 0x1110, 0x2011, 0x0201, 0xa18c,
- 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012, 0x001e, 0x080c,
- 0x246c, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110, 0x2011, 0x0201,
- 0x20a9, 0x0009, 0x810b, 0x1f04, 0x2372, 0xa18c, 0x0e00, 0x2204,
- 0xa084, 0xf1ff, 0xa105, 0x2012, 0x0005, 0x2019, 0x0002, 0x2009,
- 0x0101, 0x20a9, 0x0005, 0x8213, 0x1f04, 0x2383, 0xa294, 0x00e0,
- 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x8319, 0x0118, 0x2009,
- 0x0201, 0x0c78, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110, 0x2011,
- 0x0201, 0x20a9, 0x000c, 0x810b, 0x1f04, 0x239b, 0xa18c, 0xf000,
- 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x0005, 0x2011, 0x0102,
- 0xd3fc, 0x1110, 0x2011, 0x0202, 0x2204, 0xa09c, 0x0f30, 0xa084,
- 0xf0cf, 0xa105, 0x2012, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc,
- 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020,
- 0x609a, 0x62ac, 0x63ac, 0x00ce, 0x0005, 0x00c6, 0x2061, 0x0100,
- 0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080,
- 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x00ce, 0x0005,
- 0x00c6, 0x2061, 0x0100, 0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc,
- 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, 0xa28c, 0x0020,
- 0x0118, 0xc2ac, 0xa39d, 0x4000, 0xc3ec, 0xd3b4, 0x1108, 0xc3ed,
- 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x00ce, 0x0005, 0x2091,
- 0x8000, 0x00c6, 0x00e6, 0x6818, 0xa005, 0x0904, 0x2450, 0xd1fc,
- 0x0118, 0x2061, 0x8ed0, 0x0010, 0x2061, 0x8dc0, 0x080c, 0x2458,
- 0x0560, 0x20a9, 0x0101, 0xd1fc, 0x0118, 0x2061, 0x8dd0, 0x0010,
- 0x2061, 0x8cc0, 0x00c6, 0x080c, 0x2458, 0x0128, 0x00ce, 0x8c60,
- 0x1f04, 0x2412, 0x04a8, 0x000e, 0xd1fc, 0x0128, 0xa082, 0x8dd0,
- 0x2071, 0x4780, 0x0020, 0xa082, 0x8cc0, 0x2071, 0x4740, 0x7076,
- 0x7172, 0x2138, 0x2001, 0x0004, 0x7062, 0x707f, 0x000f, 0x71d0,
- 0xc1c4, 0x71d2, 0x080c, 0x22cb, 0x00c0, 0xd1fc, 0x1118, 0x2071,
- 0x4740, 0x0010, 0x2071, 0x4780, 0x6020, 0xc0dd, 0x6022, 0x7172,
- 0x2138, 0x2c00, 0x707a, 0x2001, 0x0006, 0x7062, 0x707f, 0x000f,
- 0x71d0, 0xc1c4, 0x71d2, 0x080c, 0x22cb, 0x2001, 0x0000, 0x0010,
- 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x00ee, 0x00ce, 0x0005,
- 0x2c04, 0xa005, 0x0170, 0x2060, 0x6010, 0xa306, 0x1140, 0x600c,
- 0xa206, 0x1128, 0x6014, 0xa106, 0x1110, 0xa006, 0x0020, 0x6000,
- 0x0c80, 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x0016, 0x2079,
- 0x4780, 0x2071, 0x0100, 0xd1bc, 0x1120, 0x2079, 0x4740, 0x2071,
- 0x0200, 0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x1110, 0x001e,
- 0x0060, 0x810b, 0x810b, 0x810b, 0x810b, 0x000e, 0xa18d, 0x0800,
- 0xd0bc, 0x1110, 0xa18d, 0x0f00, 0x2104, 0x00ee, 0x00fe, 0x0005,
- 0x2001, 0x4701, 0x2004, 0xd0ac, 0x1138, 0x68e4, 0xd0ac, 0x0120,
- 0xa084, 0x0006, 0x1108, 0x0009, 0x0005, 0x6014, 0x00e6, 0x0036,
- 0x2018, 0x2071, 0x4c40, 0xd0fc, 0x1110, 0x2071, 0x4bc0, 0x8007,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, 0xa084,
- 0x000a, 0x1904, 0x2523, 0x7108, 0xa194, 0xff00, 0x0904, 0x2523,
- 0xa18c, 0x00ff, 0x701c, 0xa084, 0xff00, 0x01c0, 0x7004, 0xa085,
- 0x003a, 0x7006, 0x2001, 0x0009, 0xa102, 0x16d8, 0x2001, 0x000a,
- 0xa102, 0x16d0, 0x2001, 0x000c, 0xa102, 0x16c8, 0x701c, 0xa084,
- 0x00ff, 0x701e, 0x7004, 0xa084, 0xffdf, 0x7006, 0x2001, 0x000a,
- 0xa106, 0x01a8, 0x2001, 0x000c, 0xa106, 0x01a0, 0x2001, 0x0012,
- 0xa106, 0x0198, 0x2001, 0x0014, 0xa106, 0x0190, 0x2001, 0x0019,
- 0xa106, 0x0188, 0x2001, 0x0032, 0xa106, 0x0180, 0x00d8, 0x2009,
- 0x000c, 0x00d0, 0x2009, 0x0012, 0x00b8, 0x2009, 0x0014, 0x00a0,
- 0x2009, 0x0019, 0x0088, 0x2009, 0x0020, 0x0070, 0x2009, 0x003f,
- 0x0058, 0x2009, 0x000a, 0x0040, 0x2009, 0x000c, 0x0028, 0x2009,
- 0x0019, 0x0010, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, 0x7004,
- 0xa085, 0x000a, 0x7006, 0x2071, 0x4700, 0x7004, 0xd0bc, 0x0158,
- 0xd3fc, 0x1120, 0x73ea, 0x2071, 0x4740, 0x0018, 0x73ee, 0x2071,
- 0x4780, 0x701f, 0x000d, 0x003e, 0x00ee, 0x0005, 0x2001, 0x01ff,
- 0x2004, 0xd0fc, 0x11d0, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
- 0x12a0, 0x2071, 0x0200, 0x71ec, 0xa18c, 0x1c00, 0x810f, 0x810c,
- 0x810c, 0x2079, 0x0100, 0x78ec, 0xa084, 0x1c00, 0x8007, 0x8004,
- 0x8004, 0xa105, 0xa08a, 0x0007, 0x0208, 0x0005, 0x0002, 0x2574,
- 0x255b, 0x2574, 0x255b, 0x254e, 0x2568, 0x254e, 0x7008, 0xa084,
- 0xc3ff, 0xa085, 0x3000, 0x700a, 0x7808, 0xa084, 0xc3ff, 0xa085,
- 0x3000, 0x780a, 0x0005, 0x7008, 0xa084, 0xc3ff, 0xa085, 0x2000,
- 0x700a, 0x7808, 0xa084, 0xc3ff, 0xa085, 0x2000, 0x780a, 0x0005,
- 0x7008, 0xa084, 0xc3ff, 0xa085, 0x0c00, 0x700a, 0x7808, 0xa084,
- 0xc3ff, 0xa085, 0x0c00, 0x780a, 0x0005, 0x0e04, 0x2575, 0x2091,
- 0x8000, 0x2071, 0x0000, 0x0006, 0x7018, 0xd084, 0x1de8, 0x000e,
- 0x2071, 0x0010, 0x70ca, 0x000e, 0x70c6, 0x70c3, 0x8002, 0x70db,
- 0x0a04, 0x70df, 0x002a, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091,
- 0x4080, 0x0cf8, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708a,
- 0x758e, 0x7492, 0x7696, 0x779a, 0xa594, 0x003f, 0xd4f4, 0x0138,
- 0xd7bc, 0x1128, 0xa784, 0x007d, 0x1904, 0x3c9c, 0x0871, 0xa49c,
- 0x000f, 0xa382, 0x0004, 0x0320, 0xa3a6, 0x0007, 0x1930, 0x2418,
- 0x8507, 0xa084, 0x000f, 0x0002, 0x2b6c, 0x2c57, 0x2c95, 0x2efb,
- 0x3279, 0x32d0, 0x3376, 0x3405, 0x34d9, 0x35ab, 0x25c7, 0x25c4,
- 0x299e, 0x2a85, 0x324d, 0x25c4, 0x080c, 0x2575, 0x0005, 0xa006,
- 0x0038, 0x7808, 0xc08d, 0x780a, 0xa006, 0x7002, 0x704a, 0x7042,
- 0x70ce, 0x705c, 0xa005, 0x1904, 0x2718, 0x7060, 0xa084, 0x0007,
- 0x0002, 0x25e1, 0x2652, 0x265a, 0x2663, 0x266c, 0x26fe, 0x2675,
- 0x2652, 0x7830, 0xd0bc, 0x1d10, 0x71d0, 0xd1bc, 0x19f8, 0xd1b4,
- 0x1904, 0x262f, 0x70a0, 0xa086, 0x0001, 0x09c0, 0x7014, 0xa005,
- 0x19a8, 0x70b0, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0080,
- 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d,
- 0xa886, 0x0001, 0x0118, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d,
- 0x6e1c, 0x2001, 0x0010, 0x0804, 0x284b, 0x705c, 0xa005, 0x1904,
- 0x25c6, 0x00c6, 0x00d6, 0x70b0, 0xa06d, 0x6800, 0xa065, 0xa055,
- 0x789b, 0x0080, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804,
- 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0118, 0x69bc, 0x7daa, 0x79aa,
- 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0020, 0x0804, 0x284b, 0x080c,
- 0x3c5b, 0x1904, 0x25c6, 0x781b, 0x0068, 0x70b8, 0xa06d, 0x68b4,
- 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808,
- 0xc08d, 0x780a, 0x68bc, 0x703e, 0xc1b4, 0x71d2, 0x70b4, 0xa065,
- 0x68c0, 0x7056, 0x7003, 0x0002, 0x2d00, 0x704a, 0xad80, 0x0009,
- 0x7042, 0x0005, 0x080c, 0x3c5b, 0x1120, 0x781b, 0x0054, 0x7003,
- 0x0004, 0x0005, 0x080c, 0x3c5b, 0x1128, 0x2011, 0x000c, 0x0419,
- 0x7003, 0x0004, 0x0005, 0x080c, 0x3c5b, 0x1128, 0x2011, 0x0006,
- 0x00d1, 0x7003, 0x0004, 0x0005, 0x080c, 0x3c5b, 0x1128, 0x2011,
- 0x000d, 0x0089, 0x7003, 0x0004, 0x0005, 0x080c, 0x3c5b, 0x1150,
- 0x2011, 0x0006, 0x0041, 0x7078, 0x707b, 0x0000, 0x2068, 0x704a,
- 0x7003, 0x0004, 0x0005, 0x7170, 0xc1fc, 0x8107, 0x7882, 0x789b,
- 0x0080, 0xa286, 0x000c, 0x1120, 0x7aaa, 0x2001, 0x0001, 0x0098,
- 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d, 0x0120,
- 0x7aaa, 0x2001, 0x0002, 0x0038, 0x78ab, 0x0020, 0x7174, 0x79aa,
- 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060, 0x78aa, 0x785b, 0x0004,
- 0x781b, 0x0113, 0x080c, 0x3c6e, 0x707f, 0x000f, 0x70d0, 0xd0b4,
- 0x0168, 0xc0b4, 0x70d2, 0x00c6, 0x70b4, 0xa065, 0x6008, 0xa084,
- 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x0005, 0x7014,
- 0xa005, 0x1138, 0x70d0, 0xd0b4, 0x0128, 0x70b4, 0xac06, 0x1110,
- 0x0c29, 0x0005, 0x0016, 0x71a0, 0xa186, 0x0001, 0x0528, 0x00d6,
- 0x0026, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b0, 0x2068, 0x6800,
- 0xac06, 0x0120, 0x8211, 0x01b0, 0x00c9, 0x0cc8, 0x00c6, 0x2100,
- 0x2011, 0x0001, 0xa212, 0x70b0, 0x2068, 0x6800, 0x2060, 0x6008,
- 0xa084, 0xfbef, 0x600a, 0x8211, 0x0110, 0x0041, 0x0cb0, 0x70a3,
- 0x0001, 0x00ce, 0x002e, 0x00de, 0x001e, 0x0005, 0xade8, 0x0005,
- 0x70a8, 0xad06, 0x1110, 0x70a4, 0x2068, 0x0005, 0x080c, 0x3c5b,
- 0x1904, 0x25c6, 0x7078, 0x2068, 0x7770, 0x080c, 0x3b95, 0x2c50,
- 0x080c, 0x3cf6, 0x789b, 0x0080, 0x6814, 0xa084, 0x001f, 0xc0bd,
- 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004, 0x0804, 0x2850,
- 0x080c, 0x3c5b, 0x1904, 0x25c6, 0x789b, 0x0080, 0x705c, 0x2068,
- 0x6f14, 0x70d0, 0xd0b4, 0x0168, 0xc0b4, 0x70d2, 0x00c6, 0x70b4,
- 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a,
- 0x00ce, 0x080c, 0x3b95, 0x2c50, 0x080c, 0x3cf6, 0x6824, 0xa005,
- 0x0130, 0xa082, 0x0006, 0x0208, 0x0010, 0x6827, 0x0005, 0x6814,
- 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001,
- 0x2001, 0x0003, 0x0804, 0x2850, 0xc28d, 0x72d2, 0x72bc, 0xa200,
- 0xa015, 0x7150, 0x8108, 0xa12a, 0x0208, 0x71bc, 0x2164, 0x6504,
- 0x85ff, 0x1170, 0x7152, 0x8421, 0x1da8, 0x70d0, 0xd08c, 0x0128,
- 0x70cc, 0xa005, 0x1110, 0x70cf, 0x000a, 0x0005, 0x2200, 0x0c90,
- 0x70d0, 0xc08c, 0x70d2, 0x70cf, 0x0000, 0x6034, 0xa005, 0x1db0,
- 0x6708, 0xa784, 0x073f, 0x01d0, 0xd7d4, 0x1d80, 0xa784, 0x0021,
- 0x1d68, 0xa784, 0x0002, 0x0130, 0xa784, 0x0004, 0x0d38, 0xa7bc,
- 0xfffb, 0x670a, 0xa784, 0x0218, 0x1d08, 0xa784, 0x0100, 0x0130,
- 0x6018, 0xa005, 0x19d8, 0xa7bc, 0xfeff, 0x670a, 0x2568, 0x6823,
- 0x0000, 0x6e1c, 0xa684, 0x000e, 0x6318, 0x0128, 0x601c, 0xa302,
- 0x0220, 0x0118, 0x0858, 0x83ff, 0x1948, 0x2d58, 0x2c50, 0x7152,
- 0xd7bc, 0x1120, 0x7028, 0x6022, 0x603a, 0x0010, 0xc7bc, 0x670a,
- 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041, 0x0001, 0x6b14,
- 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0110, 0xd684, 0x0110,
- 0xa39c, 0xffbf, 0xd6a4, 0x0110, 0xa39d, 0x0020, 0xa684, 0x000e,
- 0x1904, 0x2802, 0xc7a5, 0x670a, 0x2c00, 0x68c6, 0x77a0, 0xa786,
- 0x0001, 0x1178, 0x70d0, 0xd0b4, 0x1160, 0x7000, 0xa082, 0x0002,
- 0x1240, 0x7830, 0xd0bc, 0x1128, 0x789b, 0x0080, 0x7baa, 0x0804,
- 0x2849, 0x8739, 0x77a2, 0x2750, 0x77ac, 0xa7b0, 0x0005, 0x70a8,
- 0xa606, 0x1108, 0x76a4, 0x76ae, 0x2c3a, 0x8738, 0x2d3a, 0x8738,
- 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830, 0xd0bc, 0x0150,
- 0x2091, 0x8000, 0x2091, 0x303d, 0x70d0, 0xa084, 0x303d, 0x2091,
- 0x8000, 0x2090, 0xaad5, 0x0000, 0x0120, 0x8421, 0x2200, 0x1904,
- 0x2751, 0x0005, 0xd1dc, 0x0904, 0x37f1, 0x2029, 0x0020, 0xd69c,
- 0x1120, 0x8528, 0xd68c, 0x1108, 0x8528, 0x8840, 0x6f14, 0x610c,
- 0x8108, 0xa18c, 0x00ff, 0x70c8, 0xa160, 0x2c64, 0x8cff, 0x0188,
- 0x6014, 0xa706, 0x1dd0, 0x60b8, 0x8001, 0x60ba, 0x1d88, 0x2a60,
- 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x1904, 0x2751,
- 0x0005, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840, 0x6008,
- 0xc0d5, 0x600a, 0x77a0, 0xa786, 0x0001, 0x1904, 0x27d9, 0x70d0,
- 0xd0b4, 0x1904, 0x27d9, 0x7000, 0xa082, 0x0002, 0x1a04, 0x27d9,
- 0x7830, 0xd0bc, 0x1904, 0x27d9, 0x789b, 0x0080, 0x7baa, 0x7daa,
- 0x79aa, 0x2001, 0x0002, 0x0006, 0x6018, 0x8000, 0x601a, 0x0008,
- 0x0006, 0x2960, 0x6104, 0x2a60, 0x080c, 0x3d09, 0x1590, 0xa184,
- 0x0018, 0x0180, 0xa184, 0x0010, 0x0118, 0x080c, 0x399a, 0x1548,
- 0xa184, 0x0008, 0x0138, 0x69a0, 0xa184, 0x0600, 0x1118, 0x080c,
- 0x38b8, 0x00f8, 0x69a0, 0xa184, 0x1e00, 0x0528, 0xa184, 0x0800,
- 0x0178, 0x00c6, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104,
- 0xa18d, 0x0010, 0x6106, 0x00ce, 0x080c, 0x399a, 0x1150, 0x69a0,
- 0xa184, 0x0200, 0x0118, 0x080c, 0x38fd, 0x0018, 0xa184, 0x0400,
- 0x19f0, 0x69a0, 0xa184, 0x1000, 0x0130, 0x6914, 0xa18c, 0xff00,
- 0x810f, 0x080c, 0x23c5, 0x002e, 0xa68c, 0x00e0, 0xa684, 0x0060,
- 0x0128, 0xa086, 0x0060, 0x1110, 0xa18d, 0x4000, 0xa18d, 0x0104,
- 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a,
- 0xd6bc, 0x0168, 0xc0fc, 0x7083, 0x0000, 0xa08a, 0x000d, 0x0328,
- 0xa08a, 0x000c, 0x7182, 0x2001, 0x000c, 0x800c, 0x7186, 0x78aa,
- 0x3518, 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0,
- 0x789b, 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898,
- 0x25a0, 0xa286, 0x0020, 0x1508, 0x70d0, 0xc0b5, 0x70d2, 0x2c00,
- 0x70b6, 0x2d00, 0x70ba, 0x6814, 0xc0fc, 0x8007, 0x7882, 0xa286,
- 0x0002, 0x0904, 0x2921, 0x70a0, 0x8000, 0x70a2, 0x74b0, 0xa498,
- 0x0005, 0x70a8, 0xa306, 0x1108, 0x73a4, 0x73b2, 0xa286, 0x0010,
- 0x0904, 0x25c6, 0x00de, 0x00ce, 0x0005, 0x7000, 0xa005, 0x19e0,
- 0xa286, 0x0002, 0x1904, 0x2938, 0x080c, 0x3c5b, 0x19a8, 0x6814,
- 0xc0fc, 0x8007, 0x7882, 0x2091, 0x8000, 0x781b, 0x0068, 0x68b4,
- 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x2091,
- 0x8001, 0x7808, 0xc08d, 0x780a, 0x0126, 0x00d6, 0x00c6, 0x70d0,
- 0xa084, 0x2e00, 0x2090, 0x00ce, 0x00de, 0x012e, 0x2900, 0x7056,
- 0x68bc, 0x703e, 0x7003, 0x0002, 0x2d00, 0x704a, 0xad80, 0x0009,
- 0x7042, 0x7830, 0xd0bc, 0x0140, 0x2091, 0x303d, 0x70d0, 0xa084,
- 0x303d, 0x2091, 0x8000, 0x2090, 0x70a0, 0xa005, 0x1108, 0x0005,
- 0x8421, 0x0de8, 0x724c, 0x70bc, 0xa200, 0xa015, 0x0804, 0x2751,
- 0xa286, 0x0010, 0x1560, 0x080c, 0x3c5b, 0x1904, 0x28cc, 0x6814,
- 0xc0fc, 0x8007, 0x7882, 0x781b, 0x0068, 0x68b4, 0x785a, 0x6894,
- 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a,
- 0x70a0, 0x8000, 0x70a2, 0x74b0, 0xa490, 0x0005, 0x70a8, 0xa206,
- 0x1108, 0x72a4, 0x72b2, 0x2900, 0x7056, 0x68bc, 0x703e, 0x7003,
- 0x0002, 0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x0005, 0x6bb4,
- 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x6b94,
- 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x0068, 0x2900,
- 0x7056, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605, 0x0170,
- 0x70d0, 0xa084, 0x2e00, 0xa086, 0x2600, 0x1118, 0x2009, 0x0000,
- 0x0010, 0x2009, 0x0001, 0xa284, 0x000f, 0x0033, 0xad80, 0x0009,
- 0x7042, 0x2d00, 0x704a, 0x0005, 0x299c, 0x4208, 0x4208, 0x41f6,
- 0x4208, 0x299c, 0x299c, 0x299c, 0x080c, 0x2575, 0x7808, 0xa084,
- 0xfffd, 0x780a, 0x00f6, 0x2079, 0x4700, 0x78ac, 0x00fe, 0xd084,
- 0x01c0, 0x7160, 0xa186, 0x0001, 0x0904, 0x2a61, 0xa186, 0x0007,
- 0x0170, 0xa186, 0x0005, 0x1158, 0x7078, 0x2068, 0x681b, 0x0004,
- 0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7063,
- 0x0000, 0x70a3, 0x0000, 0x70a4, 0x70ae, 0x70b2, 0x080c, 0x26ae,
- 0x0156, 0x2011, 0x0004, 0x7160, 0xa186, 0x0001, 0x0158, 0xa186,
- 0x0007, 0x1118, 0x701f, 0x0005, 0x0010, 0x701f, 0x0001, 0x70d0,
- 0xc0c5, 0x70d2, 0x2001, 0x470a, 0x2004, 0xa084, 0x00ff, 0xa086,
- 0x0018, 0x0130, 0x7018, 0x7016, 0xa005, 0x1110, 0x70a3, 0x0001,
- 0x0066, 0x080c, 0x3f4e, 0x20a9, 0x0010, 0x2039, 0x0000, 0x080c,
- 0x3a8b, 0xa7b8, 0x0100, 0x1f04, 0x29ef, 0x006e, 0x7000, 0x0002,
- 0x2a2c, 0x2a0a, 0x2a0a, 0x2a02, 0x2a2c, 0x2a2c, 0x2a2c, 0x2a00,
- 0x080c, 0x2575, 0x705c, 0xa005, 0x0538, 0xad06, 0x1118, 0x6800,
- 0x705e, 0x0080, 0x6820, 0xd084, 0x1148, 0x6f14, 0x080c, 0x3b95,
- 0x6008, 0xc0d4, 0x600a, 0x080c, 0x37c7, 0x0020, 0x7058, 0x2060,
- 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, 0xd0fc, 0x0108,
- 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff,
- 0xc09d, 0x6822, 0x080c, 0x1dbf, 0x2011, 0x0004, 0x74c8, 0xa4a0,
- 0x0100, 0x04b1, 0xaea0, 0x0017, 0x0499, 0x20a9, 0x0101, 0x74c8,
- 0x0479, 0x8420, 0x1f04, 0x2a38, 0x70c0, 0x2060, 0x2021, 0x0002,
- 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0198, 0x6018, 0x0016, 0x0006,
- 0x2011, 0x4702, 0x220c, 0xa102, 0x2012, 0x000e, 0x001e, 0xa102,
- 0x0338, 0x6012, 0x1128, 0x2011, 0x4704, 0x2204, 0xc0a5, 0x2012,
- 0x601b, 0x0000, 0xace0, 0x0010, 0x1f04, 0x2a42, 0x8421, 0x1d00,
- 0x015e, 0x7063, 0x0000, 0x7003, 0x0000, 0x704b, 0x0000, 0x0005,
- 0x0046, 0x2404, 0xa005, 0x01a8, 0x2068, 0x6800, 0x0006, 0x6a1a,
- 0x6817, 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e,
- 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1dbf, 0x000e,
- 0x0c48, 0x004e, 0x2023, 0x0000, 0x0005, 0xa282, 0x0003, 0x0310,
- 0x080c, 0x2575, 0x2300, 0x0002, 0x2a8f, 0x2b0c, 0x2b1a, 0xa282,
- 0x0002, 0x0110, 0x080c, 0x2575, 0x7060, 0x7063, 0x0000, 0x707f,
- 0x0000, 0x0022, 0x77d0, 0xc7c5, 0x77d2, 0x0002, 0x2aa6, 0x2aa6,
- 0x2aa8, 0x2ae0, 0x37fb, 0x2aa6, 0x2ae0, 0x2aa6, 0x080c, 0x2575,
- 0x7770, 0x080c, 0x3a8b, 0x7770, 0xa7bc, 0x8f00, 0x080c, 0x3b95,
- 0x6018, 0xa005, 0x0528, 0xd7fc, 0x1118, 0x2021, 0x8dc0, 0x0010,
- 0x2021, 0x8ed0, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c, 0x2b34,
- 0x01b8, 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, 0x2021, 0x8cc0,
- 0x0010, 0x2021, 0x8dd0, 0x0046, 0x2009, 0x0005, 0x2011, 0x0010,
- 0x080c, 0x2b34, 0x004e, 0x0118, 0x8420, 0x1f04, 0x2acb, 0x015e,
- 0x8738, 0xa784, 0x001f, 0x1990, 0x0804, 0x25c9, 0x0804, 0x25c9,
- 0x7770, 0x080c, 0x3b95, 0x6018, 0xa005, 0x0520, 0xd7fc, 0x1118,
- 0x2021, 0x8dc0, 0x0010, 0x2021, 0x8ed0, 0x2009, 0x0005, 0x2011,
- 0x0020, 0x080c, 0x2b34, 0x01b0, 0x0156, 0x20a9, 0x0101, 0xd7fc,
- 0x1118, 0x2021, 0x8cc0, 0x0010, 0x2021, 0x8dd0, 0x0046, 0x2009,
- 0x0005, 0x2011, 0x0020, 0x0481, 0x004e, 0x0118, 0x8420, 0x1f04,
- 0x2afe, 0x015e, 0x0804, 0x25c9, 0x2200, 0x0002, 0x2b11, 0x2b13,
- 0x2b13, 0x080c, 0x2575, 0x7063, 0x0000, 0x70d0, 0xc0c5, 0x70d2,
- 0x0804, 0x25c9, 0x2200, 0x0002, 0x2b21, 0x2b13, 0x2b1f, 0x080c,
- 0x2575, 0x080c, 0x3f4e, 0x7000, 0xa086, 0x0002, 0x1904, 0x3780,
- 0x080c, 0x37e1, 0x6008, 0xa084, 0xfbef, 0x600a, 0x080c, 0x3772,
- 0x0904, 0x3780, 0x0804, 0x25c9, 0x2404, 0xa005, 0x0590, 0x2068,
- 0x2d04, 0x0006, 0x6814, 0xa706, 0x0118, 0x2d20, 0x000e, 0x0ca8,
- 0x000e, 0x2022, 0x691a, 0x6817, 0x0000, 0x682b, 0x0000, 0x68b4,
- 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084, 0x00ff, 0xa205, 0x6822,
- 0x080c, 0x1dbf, 0x2021, 0x4702, 0x241c, 0x8319, 0x2322, 0x6010,
- 0x8001, 0x6012, 0x1128, 0x2021, 0x4704, 0x2404, 0xc0a5, 0x2022,
- 0x6008, 0xa084, 0xf9ef, 0x600a, 0x080c, 0x26ca, 0x080c, 0x37e1,
- 0x0005, 0xa085, 0x0001, 0x0ce0, 0x2300, 0x0002, 0x2b73, 0x2b71,
- 0x2bee, 0x080c, 0x2575, 0x78e4, 0xa005, 0x17b0, 0x3208, 0xa18c,
- 0x0800, 0x0118, 0x0104, 0x25c6, 0x0010, 0x0304, 0x25c6, 0x2008,
- 0xa084, 0x0030, 0x1110, 0x0804, 0x324d, 0x78ec, 0xa084, 0x0003,
- 0x0dd0, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090, 0xa184,
- 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050, 0xa184,
- 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010, 0x2001,
- 0x0001, 0x0002, 0x2bd1, 0x2bda, 0x2bc7, 0x2baa, 0x3c4f, 0x3c4f,
- 0x2baa, 0x2be4, 0x080c, 0x2575, 0x7000, 0xa086, 0x0004, 0x1190,
- 0x7060, 0xa086, 0x0002, 0x1130, 0x2011, 0x0002, 0x2019, 0x0000,
- 0x0804, 0x2a85, 0x7060, 0xa086, 0x0006, 0x0db0, 0x7060, 0xa086,
- 0x0004, 0x0d90, 0x79e4, 0x2001, 0x0003, 0x0804, 0x2f3b, 0x6818,
- 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a61, 0x781b, 0x006e,
- 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a61,
- 0x0804, 0x3c2d, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c,
- 0x3a61, 0x781b, 0x00fa, 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b,
- 0x001d, 0x080c, 0x3a61, 0x781b, 0x00cb, 0x0005, 0xa584, 0x000f,
- 0x11c0, 0x7000, 0x0002, 0x25c9, 0x2bfb, 0x2bfd, 0x3780, 0x3780,
- 0x3780, 0x2bfb, 0x2bfb, 0x080c, 0x2575, 0x080c, 0x37e1, 0x6008,
- 0xa084, 0xfbef, 0x600a, 0x080c, 0x3772, 0x0904, 0x3780, 0x0804,
- 0x25c9, 0x78e4, 0xa005, 0x1b04, 0x2bac, 0x3208, 0xa18c, 0x0800,
- 0x0118, 0x0104, 0x2bac, 0x0010, 0x0304, 0x2bac, 0x2008, 0xa084,
- 0x0030, 0x1118, 0x781b, 0x0068, 0x0005, 0x78ec, 0xa084, 0x0003,
- 0x0dc8, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090, 0xa184,
- 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050, 0xa184,
- 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010, 0x2001,
- 0x0001, 0x0002, 0x2c49, 0x2c4d, 0x2c44, 0x2c42, 0x3c4f, 0x3c4f,
- 0x2c42, 0x3c49, 0x080c, 0x2575, 0x080c, 0x3a67, 0x781b, 0x006e,
- 0x0005, 0x080c, 0x3a67, 0x0804, 0x3c2d, 0x080c, 0x3a67, 0x781b,
- 0x00fa, 0x0005, 0x080c, 0x3a67, 0x781b, 0x00cb, 0x0005, 0x2300,
- 0x0002, 0x2c5e, 0x2c5c, 0x2c60, 0x080c, 0x2575, 0x0804, 0x3405,
- 0x681b, 0x0016, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, 0x0904,
- 0x3405, 0x78ec, 0xa084, 0x0003, 0x0904, 0x3405, 0xa184, 0x0100,
- 0x0d98, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090, 0xa184,
- 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050, 0xa184,
- 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010, 0x2001,
- 0x0001, 0x0002, 0x2c92, 0x2c4d, 0x2bc7, 0x3c0b, 0x3c4f, 0x3c4f,
- 0x3c0b, 0x3c49, 0x080c, 0x3c17, 0x0005, 0xa282, 0x0005, 0x0310,
- 0x080c, 0x2575, 0x7898, 0x2040, 0x2300, 0x0002, 0x2ca1, 0x2ecb,
- 0x2ed5, 0x2200, 0x0002, 0x2cbd, 0x2caa, 0x2cbd, 0x2ca8, 0x2ead,
- 0x080c, 0x2575, 0x789b, 0x0018, 0x78a8, 0x2010, 0xa084, 0x00ff,
- 0xa082, 0x0020, 0x0a04, 0x3a30, 0xa08a, 0x0004, 0x1a04, 0x3a30,
- 0x0002, 0x3a30, 0x3a30, 0x3a30, 0x39e4, 0x789b, 0x0018, 0x79a8,
- 0xa184, 0x0080, 0x0148, 0x0804, 0x3a30, 0x7000, 0xa005, 0x1dd8,
- 0x2011, 0x0004, 0x0804, 0x35b7, 0xa184, 0x00ff, 0xa08a, 0x0010,
- 0x1a04, 0x3a30, 0x0002, 0x2ce5, 0x2ce3, 0x2cf7, 0x2cfb, 0x2da9,
- 0x3a30, 0x3a30, 0x2dab, 0x3a30, 0x3a30, 0x2ea9, 0x2ea9, 0x3a30,
- 0x3a30, 0x3a30, 0x2eab, 0x080c, 0x2575, 0xd6e4, 0x0140, 0x2001,
- 0x0300, 0x8000, 0x8000, 0x783a, 0x781b, 0x00c7, 0x0005, 0x6818,
- 0xd0fc, 0x0118, 0x681b, 0x001d, 0x0c90, 0x0804, 0x3c0b, 0x681b,
- 0x001d, 0x0804, 0x3a5b, 0x6920, 0x6922, 0xa684, 0x1800, 0x1904,
- 0x2d4c, 0x6820, 0xd084, 0x1904, 0x2d54, 0x6818, 0xa086, 0x0008,
- 0x1110, 0x681b, 0x0000, 0xd6d4, 0x0568, 0xd6bc, 0x0558, 0x7083,
- 0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d, 0x0718, 0xa08a,
- 0x000c, 0x7182, 0x2001, 0x000c, 0x800c, 0x7186, 0x789b, 0x0061,
- 0x78aa, 0x0156, 0x0136, 0x0146, 0x0016, 0x3208, 0xa18c, 0x0600,
- 0x0118, 0x20a1, 0x022b, 0x0010, 0x20a1, 0x012b, 0x001e, 0x789b,
- 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x014e,
- 0x013e, 0x015e, 0x6038, 0xa005, 0x1150, 0x681c, 0xa084, 0x000e,
- 0x0904, 0x3a5b, 0x080c, 0x3a6d, 0x782b, 0x3008, 0x0010, 0x8001,
- 0x603a, 0x781b, 0x0071, 0x0005, 0xd6e4, 0x0130, 0x781b, 0x0083,
- 0x0005, 0x781b, 0x0083, 0x0005, 0xa684, 0x0060, 0x0dd0, 0xd6dc,
- 0x0dc0, 0xd6fc, 0x01a0, 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8,
- 0x78d0, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x6b98,
- 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0xd6f4,
- 0x0118, 0xc6f4, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003, 0x1148,
- 0x0006, 0x080c, 0x3f4e, 0x080c, 0x4208, 0x000e, 0x781b, 0x0080,
- 0x0005, 0xa006, 0x080c, 0x42e8, 0x6ab0, 0x69ac, 0x6c98, 0x6b94,
- 0x2200, 0xa105, 0x0120, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa,
- 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x1130,
- 0xc6f5, 0x7e5a, 0x6eb6, 0x781b, 0x0080, 0x0005, 0x781b, 0x0080,
- 0x2200, 0xa115, 0x1118, 0x080c, 0x4208, 0x0005, 0x080c, 0x4235,
- 0x0005, 0x080c, 0x2575, 0x0804, 0x2e3f, 0x00c6, 0x7054, 0x2060,
- 0x6920, 0xa18c, 0xecff, 0x6922, 0x6000, 0xa084, 0xcfdf, 0x6002,
- 0x080c, 0x3917, 0xa006, 0x2040, 0x2038, 0x080c, 0x39bf, 0x0804,
- 0x2e33, 0x00c6, 0x7054, 0x2060, 0x2c48, 0x7aa8, 0xa294, 0x00ff,
- 0xa286, 0x0004, 0x11d8, 0x6920, 0xd1e4, 0x1170, 0x2039, 0x0000,
- 0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x391a,
- 0x080c, 0x39bf, 0x0804, 0x2e33, 0xa18c, 0xecff, 0x6922, 0x6104,
- 0xa18c, 0xffdd, 0x6106, 0x6000, 0xc0ac, 0x6002, 0xa286, 0x0003,
- 0x01d0, 0x6104, 0xa184, 0x0010, 0x0548, 0x080c, 0x3b91, 0x080c,
- 0x399a, 0x88ff, 0x0518, 0x00ce, 0x789b, 0x0060, 0x2800, 0x78aa,
- 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005,
- 0x781b, 0x0082, 0x0005, 0x6920, 0xd1cc, 0x0130, 0xa18c, 0xfdff,
- 0x6922, 0x6000, 0xc0ec, 0x6002, 0x2039, 0x0000, 0x2041, 0x0000,
- 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x39bf, 0xa286, 0x0001,
- 0x0158, 0x6104, 0xa184, 0x0008, 0x01b0, 0x080c, 0x3b91, 0x080c,
- 0x38b8, 0x88ff, 0x1980, 0x0078, 0x6920, 0xd1c4, 0x0130, 0xa18c,
- 0xfeff, 0x6922, 0x6000, 0xc0e4, 0x6002, 0x2031, 0x0000, 0xa006,
- 0x2010, 0x080c, 0x391a, 0x00ce, 0x7e58, 0xd6d4, 0x1118, 0x781b,
- 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0x0804, 0x3a57, 0x2808,
- 0x789b, 0x0080, 0x2019, 0x0080, 0x78a8, 0xa094, 0x00ff, 0xa286,
- 0x0001, 0x11b8, 0x2300, 0xa102, 0xa086, 0x0001, 0x0904, 0x2dad,
- 0x7ca8, 0xa4a4, 0x00ff, 0xa480, 0x0002, 0xa300, 0x2018, 0xa102,
- 0x0a04, 0x2dc1, 0x0904, 0x2dc1, 0x24a8, 0x7aa8, 0x1f04, 0x2e5d,
- 0x0c18, 0xa284, 0x00f0, 0xa082, 0x0020, 0x06b8, 0x2200, 0xa082,
- 0x0021, 0x1698, 0x7aa8, 0x8318, 0x8318, 0x2100, 0xa302, 0x0aa0,
- 0xa286, 0x0023, 0x0950, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58,
- 0xa684, 0xfff1, 0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a,
- 0x78a0, 0xa005, 0x0904, 0x2e34, 0x20a8, 0x7998, 0x789b, 0x0060,
- 0x78aa, 0x2011, 0x0080, 0x799a, 0x78a8, 0x7998, 0x7a9a, 0x78aa,
- 0x7a98, 0x1f04, 0x2e8b, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b,
- 0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x8318, 0x2100, 0xa302,
- 0x0a04, 0x2e44, 0xa284, 0x0080, 0x1904, 0x3a5b, 0x78a0, 0xa005,
- 0x08c8, 0x0804, 0x3a5b, 0x0804, 0x3a30, 0x7054, 0xa04d, 0x789b,
- 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0110, 0x080c,
- 0x2575, 0x7aa8, 0xa294, 0x00ff, 0x784b, 0x0008, 0x78a8, 0xa084,
- 0x00ff, 0xa08a, 0x0005, 0x1a04, 0x3a30, 0x0002, 0x3a30, 0x382f,
- 0x3a30, 0x394a, 0x3d59, 0xa282, 0x0000, 0x1110, 0x080c, 0x2575,
- 0x080c, 0x3a61, 0x781b, 0x0082, 0x0005, 0xa282, 0x0003, 0x1110,
- 0x080c, 0x2575, 0xd4fc, 0x11d0, 0x7060, 0xa005, 0x0110, 0x080c,
- 0x2575, 0x6f14, 0x7772, 0xa7bc, 0x8f00, 0x080c, 0x3b95, 0x6008,
- 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f, 0x1db0, 0x080c,
- 0x3a64, 0x7063, 0x0002, 0x701f, 0x0009, 0x0010, 0x080c, 0x3a70,
- 0x781b, 0x0082, 0x0005, 0xa282, 0x0004, 0x0310, 0x080c, 0x2575,
- 0x2300, 0x0002, 0x2f05, 0x309b, 0x30d7, 0xa286, 0x0003, 0x0598,
- 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x71d0, 0xd1b4, 0x0528, 0xd1bc,
- 0x1518, 0x2001, 0x4701, 0x2004, 0xd0c4, 0x11f0, 0x7868, 0xa084,
- 0x00ff, 0x11d0, 0xa282, 0x0002, 0x12b8, 0x00d6, 0x783b, 0x8300,
- 0x781b, 0x0059, 0x70b8, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6,
- 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030,
- 0x00de, 0x2001, 0x0000, 0x0058, 0x783b, 0x1300, 0x781b, 0x0057,
- 0x2001, 0x0000, 0x0020, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x7046,
- 0x68a0, 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a, 0xa284, 0x000f,
- 0x0002, 0x307c, 0x2f56, 0x2f53, 0x31a7, 0x3232, 0x25c9, 0x2f51,
- 0x2f51, 0x080c, 0x2575, 0x6008, 0xc0d4, 0x600a, 0xd6e4, 0x0120,
- 0x7044, 0xa086, 0x0014, 0x11e8, 0x080c, 0x3f4e, 0x2009, 0x0000,
- 0x6818, 0xd0fc, 0x0108, 0x7044, 0xa086, 0x0014, 0x0168, 0x6818,
- 0xa086, 0x0008, 0x1904, 0x303e, 0x7858, 0xd09c, 0x0904, 0x303e,
- 0x6820, 0xd0ac, 0x0904, 0x303e, 0x681b, 0x0014, 0x2009, 0x0002,
- 0x04a8, 0x7868, 0xa08c, 0x00ff, 0x0588, 0xa186, 0x0008, 0x1158,
- 0x6008, 0xc0a4, 0x600a, 0x080c, 0x3772, 0x0540, 0x080c, 0x37e1,
- 0x080c, 0x3f4e, 0x0060, 0xa186, 0x0028, 0x1500, 0x6018, 0xa005,
- 0x0d78, 0x8001, 0x0d68, 0x8001, 0x0d58, 0x601e, 0x0c48, 0x6820,
- 0xd084, 0x0904, 0x25c9, 0xc084, 0x6822, 0x080c, 0x26bf, 0x7058,
- 0x00c6, 0x2060, 0x6800, 0x6002, 0x00ce, 0x6004, 0x6802, 0xa005,
- 0x2d00, 0x1108, 0x6002, 0x6006, 0x0804, 0x25c9, 0x0016, 0x81ff,
- 0x15f0, 0x7000, 0xa086, 0x0030, 0x05d0, 0x71d0, 0xd1bc, 0x15b8,
- 0xd1b4, 0x11e8, 0x705c, 0xa005, 0x1590, 0x70a0, 0xa086, 0x0001,
- 0x0570, 0x7003, 0x0000, 0x0046, 0x0056, 0x0076, 0x0066, 0x00c6,
- 0x00d6, 0x080c, 0x25f1, 0x00de, 0x00ce, 0x006e, 0x007e, 0x005e,
- 0x004e, 0x71d0, 0xd1b4, 0x11d8, 0x7003, 0x0040, 0x00c0, 0x080c,
- 0x3c5b, 0x11a8, 0x781b, 0x0068, 0x00d6, 0x70b8, 0xa06d, 0x68b4,
- 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4,
- 0x71d2, 0x7003, 0x0030, 0x7808, 0xc08d, 0x780a, 0x00de, 0x080c,
- 0x30ff, 0x001e, 0x81ff, 0x0904, 0x303e, 0xa684, 0xdf00, 0x681e,
- 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x1904, 0x303f, 0x6818,
- 0xa086, 0x0014, 0x1130, 0x2008, 0xd6e4, 0x0118, 0x7868, 0xa08c,
- 0x00ff, 0x080c, 0x3a7a, 0x080c, 0x26ca, 0x6820, 0xd0dc, 0x1578,
- 0x8717, 0xa294, 0x000f, 0x8213, 0x8213, 0x8213, 0xb284, 0x0600,
- 0x0118, 0xa290, 0x4bc0, 0x0010, 0xa290, 0x4c40, 0xa290, 0x0000,
- 0x221c, 0xd3c4, 0x0170, 0x6820, 0xd0e4, 0x0128, 0xa084, 0xefff,
- 0x6822, 0xc3ac, 0x2312, 0x8210, 0x2204, 0xa085, 0x0038, 0x2012,
- 0x8211, 0xd3d4, 0x0138, 0x68a0, 0xd0c4, 0x1120, 0x080c, 0x3167,
- 0x0804, 0x25c9, 0x6008, 0xc08d, 0x600a, 0x0008, 0x692a, 0x6916,
- 0x6818, 0xd0fc, 0x0110, 0x7044, 0x681a, 0xa68c, 0xdf00, 0x691e,
- 0x6410, 0x84ff, 0x0168, 0x2009, 0x4702, 0x2104, 0x8001, 0x200a,
- 0x8421, 0x6412, 0x1128, 0x2021, 0x4704, 0x2404, 0xc0a5, 0x2022,
- 0x6018, 0xa005, 0x0118, 0x8001, 0x601a, 0x1118, 0x6008, 0xc0a4,
- 0x600a, 0x6820, 0xd084, 0x1130, 0x6800, 0xa005, 0x1108, 0x6002,
- 0x6006, 0x0020, 0x7058, 0x2060, 0x6800, 0x6002, 0x2061, 0x4700,
- 0x6887, 0x0103, 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a,
- 0x0110, 0x2d02, 0x0008, 0x616e, 0x7200, 0xa286, 0x0030, 0x0158,
- 0xa286, 0x0040, 0x1904, 0x25c9, 0x7003, 0x0002, 0x7048, 0x2068,
- 0x68c4, 0x2060, 0x0005, 0x7003, 0x0002, 0x70b8, 0xa06d, 0x68bc,
- 0x703e, 0x70b4, 0xa065, 0x68c0, 0x7056, 0x2d00, 0x704a, 0xad80,
- 0x0009, 0x7042, 0x0005, 0xa282, 0x0004, 0x0210, 0x080c, 0x2575,
- 0x2200, 0x0002, 0x30a6, 0x30b5, 0x30c1, 0x30b5, 0xa586, 0x1300,
- 0x0160, 0xa586, 0x8300, 0x1d90, 0x7003, 0x0000, 0x6018, 0x8001,
- 0x601a, 0x6008, 0xa084, 0xfbef, 0x600a, 0x7000, 0xa086, 0x0005,
- 0x0128, 0x080c, 0x3a61, 0x781b, 0x0082, 0x0005, 0x781b, 0x0083,
- 0x0005, 0x7890, 0x8007, 0x8001, 0xa084, 0x0007, 0xa080, 0x0018,
- 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186, 0x0003, 0x0128, 0xa186,
- 0x0000, 0x0110, 0x0804, 0x3a30, 0x781b, 0x0083, 0x0005, 0x6820,
- 0xc095, 0x6822, 0x82ff, 0x1118, 0x080c, 0x3a61, 0x0030, 0x8211,
- 0x0110, 0x080c, 0x2575, 0x080c, 0x3a70, 0x781b, 0x0082, 0x0005,
- 0x080c, 0x3c6e, 0x7830, 0xa084, 0x00c0, 0x1170, 0x0016, 0x3208,
- 0xa18c, 0x0800, 0x001e, 0x0118, 0x0104, 0x30fc, 0x0010, 0x0304,
- 0x30fc, 0x791a, 0xa006, 0x0005, 0xa085, 0x0001, 0x0005, 0xa684,
- 0x0060, 0x1130, 0x682f, 0x0000, 0x6833, 0x0000, 0x0804, 0x3166,
- 0xd6dc, 0x1198, 0x68b4, 0xd0dc, 0x1180, 0x6998, 0x6a94, 0x692e,
- 0x6a32, 0x7044, 0xa005, 0x1130, 0x2200, 0xa105, 0x0904, 0x3f4e,
- 0x7047, 0x0015, 0x0804, 0x3f4e, 0x0005, 0xd6ac, 0x01f0, 0xd6f4,
- 0x0130, 0x682f, 0x0000, 0x6833, 0x0000, 0x0804, 0x3f4e, 0x68b4,
- 0xa084, 0x4000, 0xa635, 0xd6f4, 0x1da0, 0x7044, 0xa005, 0x1110,
- 0x7047, 0x0015, 0xd6dc, 0x1128, 0x68b4, 0xd0dc, 0x0110, 0x6ca8,
- 0x6da4, 0x6c2e, 0x6d32, 0x0804, 0x3f4e, 0xd6f4, 0x0130, 0x682f,
- 0x0000, 0x6833, 0x0000, 0x0804, 0x3f4e, 0x68b4, 0xa084, 0x4800,
- 0xa635, 0xd6f4, 0x1da0, 0x7044, 0xa005, 0x1110, 0x7047, 0x0015,
- 0x2408, 0x2510, 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291,
- 0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x1110, 0x0804, 0x3f4e,
- 0x7000, 0xa086, 0x0006, 0x0110, 0x0804, 0x3f4e, 0x0005, 0x6946,
- 0x6008, 0xc0cd, 0xd3cc, 0x0108, 0xc08d, 0x600a, 0x6818, 0x683a,
- 0x681b, 0x0006, 0x688f, 0x0000, 0x6893, 0x0000, 0x6a30, 0x692c,
- 0x6a3e, 0x6942, 0x682f, 0x0003, 0x6833, 0x0000, 0x6837, 0x0020,
- 0x6897, 0x0000, 0x689b, 0x0020, 0x7000, 0x0002, 0x25c9, 0x3196,
- 0x3190, 0x318e, 0x318e, 0x318e, 0x318e, 0x318e, 0x080c, 0x2575,
- 0x6820, 0xd084, 0x1118, 0x080c, 0x37c7, 0x0030, 0x7058, 0x2c50,
- 0x2060, 0x6800, 0x6002, 0x2a60, 0xaea0, 0x0017, 0x2404, 0xa005,
- 0x0110, 0x2020, 0x0cd8, 0x2d22, 0x206b, 0x0000, 0x0005, 0x080c,
- 0x37cd, 0x080c, 0x37e1, 0x6008, 0xc0cc, 0x600a, 0x682b, 0x0000,
- 0x789b, 0x000e, 0x6f14, 0x6938, 0x691a, 0x6944, 0x6916, 0x2009,
- 0x0000, 0xae86, 0x4740, 0x0110, 0x2009, 0x0001, 0x080c, 0x431f,
- 0xd6dc, 0x01c8, 0x691c, 0xc1ed, 0x691e, 0x6828, 0xa082, 0x000e,
- 0x0290, 0x6848, 0xa084, 0x000f, 0xa086, 0x000b, 0x1160, 0x685c,
- 0xa086, 0x0047, 0x1140, 0x2001, 0x4701, 0x2004, 0xd0ac, 0x1118,
- 0x2700, 0x080c, 0x249e, 0x6818, 0xd0fc, 0x0140, 0x681b, 0x0000,
- 0x7868, 0xa08c, 0x00ff, 0x0110, 0x681b, 0x001e, 0xaea0, 0x0017,
- 0x6800, 0x2022, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060,
- 0x6000, 0xd0a4, 0x0580, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051,
- 0x0020, 0x00d6, 0x00f6, 0x0156, 0x0146, 0x2079, 0x4700, 0x080c,
- 0x1bb2, 0x014e, 0x015e, 0x00fe, 0x70c8, 0x2010, 0x2009, 0x0101,
- 0x0026, 0x2204, 0xa06d, 0x0140, 0x6814, 0xa706, 0x0110, 0x6800,
- 0x0cc8, 0x6820, 0xc0d5, 0x6822, 0x002e, 0x8210, 0x8109, 0x1d80,
- 0x00de, 0x7063, 0x0003, 0x707b, 0x0000, 0x7772, 0x707f, 0x000f,
- 0x71d0, 0xc1c4, 0x71d2, 0x6818, 0xa086, 0x0002, 0x1138, 0x6817,
- 0x0000, 0x682b, 0x0000, 0x681c, 0xc0ec, 0x681e, 0x080c, 0x1dbf,
- 0x0804, 0x25c9, 0x7cd8, 0x7ddc, 0x7fd0, 0x080c, 0x30ff, 0x682b,
- 0x0000, 0x789b, 0x000e, 0x6f14, 0x080c, 0x3c72, 0xa08c, 0x00ff,
- 0x6916, 0x6818, 0xd0fc, 0x0110, 0x7044, 0x681a, 0xa68c, 0xdf00,
- 0x691e, 0x7063, 0x0000, 0x0804, 0x25c9, 0x7000, 0xa005, 0x1110,
- 0x0804, 0x25c9, 0xa006, 0x080c, 0x3f4e, 0x6920, 0xd1ac, 0x1110,
- 0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820,
- 0xa084, 0x00ff, 0x6822, 0x7000, 0x0002, 0x25c9, 0x326f, 0x326f,
- 0x3272, 0x3272, 0x3272, 0x326d, 0x326d, 0x080c, 0x2575, 0x6818,
- 0x0804, 0x2f3b, 0x6008, 0xc0a4, 0x600a, 0x6817, 0x0000, 0x0804,
- 0x3795, 0x2300, 0x0002, 0x327e, 0x3280, 0x32ce, 0x080c, 0x2575,
- 0xd6fc, 0x1904, 0x2d5b, 0x7000, 0xa00d, 0x0002, 0x25c9, 0x3290,
- 0x3290, 0x32ba, 0x3290, 0x32cb, 0x328e, 0x328e, 0x080c, 0x2575,
- 0xa684, 0x0060, 0x0538, 0xa086, 0x0060, 0x1510, 0xc6ac, 0xc6f4,
- 0xc6ed, 0x7e5a, 0x6eb6, 0x681c, 0xc0ac, 0x681e, 0xa186, 0x0002,
- 0x0148, 0x080c, 0x3f4e, 0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c,
- 0x4235, 0x0010, 0x080c, 0x4208, 0x781b, 0x0083, 0x71d0, 0xd1b4,
- 0x1904, 0x25c6, 0x70a0, 0xa086, 0x0001, 0x1904, 0x260d, 0x0005,
- 0xd6ec, 0x09f0, 0x6818, 0xd0fc, 0x0170, 0xd6f4, 0x1130, 0x681b,
- 0x0015, 0x781b, 0x0083, 0x0804, 0x25c6, 0x681b, 0x0007, 0x682f,
- 0x0000, 0x6833, 0x0000, 0x080c, 0x3c17, 0x0005, 0x080c, 0x2575,
- 0x2300, 0x0002, 0x32d7, 0x32f9, 0x3351, 0x080c, 0x2575, 0x7000,
- 0x0002, 0x32e1, 0x32e3, 0x32ea, 0x32e1, 0x32e1, 0x32e1, 0x32e1,
- 0x32e1, 0x080c, 0x2575, 0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c,
- 0x4235, 0x0010, 0x080c, 0x4208, 0x681c, 0xc0b4, 0x681e, 0x70d0,
- 0xd0b4, 0x1904, 0x25c6, 0x70a0, 0xa086, 0x0001, 0x1904, 0x260d,
- 0x0005, 0xd6fc, 0x1904, 0x3341, 0x7000, 0xa00d, 0x0002, 0x25c9,
- 0x330f, 0x3309, 0x3339, 0x330f, 0x333e, 0x3307, 0x3307, 0x080c,
- 0x2575, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684,
- 0x0060, 0x0538, 0xa086, 0x0060, 0x1510, 0xa6b4, 0xbfbf, 0xc6ed,
- 0x7e5a, 0x6eb6, 0xa186, 0x0002, 0x0148, 0x080c, 0x3f4e, 0x69ac,
- 0x68b0, 0xa115, 0x0118, 0x080c, 0x4235, 0x0010, 0x080c, 0x4208,
- 0x781b, 0x0083, 0x681c, 0xc0b4, 0x681e, 0x71d0, 0xd1b4, 0x1904,
- 0x25c6, 0x70a0, 0xa086, 0x0001, 0x1904, 0x260d, 0x0005, 0xd6ec,
- 0x09f0, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x0007, 0x781b, 0x00fb,
- 0x0005, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302,
- 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b, 0x0083,
- 0x0005, 0xd6dc, 0x0130, 0x782b, 0x3009, 0x781b, 0x0083, 0x0804,
- 0x25c6, 0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, 0x1150,
- 0xa484, 0x0200, 0x0108, 0xc6f5, 0xc6dd, 0x7e5a, 0x781b, 0x0083,
- 0x0804, 0x25c6, 0x6820, 0xc095, 0x6822, 0x080c, 0x3c02, 0xc6dd,
- 0x080c, 0x3a61, 0x781b, 0x0082, 0x0804, 0x25c6, 0x2300, 0x0002,
- 0x337b, 0x337d, 0x337f, 0x080c, 0x2575, 0x0804, 0x3a5b, 0x7d98,
- 0xd6d4, 0x15a8, 0x79e4, 0xd1ac, 0x0130, 0x78ec, 0xa084, 0x0003,
- 0x0110, 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684,
- 0xfffb, 0x785a, 0x7d9a, 0x79e4, 0xd1ac, 0x0120, 0x78ec, 0xa084,
- 0x0003, 0x1120, 0x2001, 0x0014, 0x0804, 0x2f3b, 0x7884, 0xd0fc,
- 0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004,
- 0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005,
- 0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x04c2, 0x7a90,
- 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, 0x0568, 0x789b,
- 0x0080, 0x7ba8, 0xa384, 0x0001, 0x11d0, 0x7ba8, 0x7ba8, 0xa386,
- 0x0004, 0x1118, 0x2009, 0xffdf, 0x0058, 0xa386, 0x0001, 0x1118,
- 0x2009, 0xfff7, 0x0028, 0xa386, 0x0003, 0x1148, 0x2009, 0xffef,
- 0x00c6, 0x7054, 0x2060, 0x6004, 0xa104, 0x6006, 0x00ce, 0x789b,
- 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, 0x3009,
- 0x6920, 0xa18c, 0xecff, 0x6922, 0x7d9a, 0x0804, 0x3c0b, 0x2bd1,
- 0x2bda, 0x33f9, 0x33ff, 0x33f7, 0x33f7, 0x3c0b, 0x3c0b, 0x080c,
- 0x2575, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0804, 0x3c11, 0x6920,
- 0xa18c, 0xfcff, 0x6922, 0x0804, 0x3c0b, 0x79e4, 0xa184, 0x0030,
- 0x0120, 0x78ec, 0xa084, 0x0003, 0x1570, 0x7000, 0xa086, 0x0004,
- 0x1190, 0x7060, 0xa086, 0x0002, 0x1130, 0x2011, 0x0002, 0x2019,
- 0x0000, 0x0804, 0x2a85, 0x7060, 0xa086, 0x0006, 0x0db0, 0x7060,
- 0xa086, 0x0004, 0x0d90, 0x7000, 0xa086, 0x0000, 0x0904, 0x25c6,
- 0x6920, 0xa184, 0x0420, 0x0128, 0xc1d4, 0x6922, 0x6818, 0x0804,
- 0x2f3b, 0x6818, 0xa08e, 0x0002, 0x0120, 0xc0fd, 0x681a, 0x2001,
- 0x0014, 0x0804, 0x2f3b, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007,
- 0x0090, 0xa184, 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000,
- 0x0050, 0xa184, 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007,
- 0x0010, 0x2001, 0x0001, 0x0002, 0x3c0b, 0x3c0b, 0x345c, 0x3c0b,
- 0x3c4f, 0x3c4f, 0x3c0b, 0x3c0b, 0xd6bc, 0x0570, 0x7180, 0x81ff,
- 0x0558, 0xa182, 0x000d, 0x1318, 0x7083, 0x0000, 0x0028, 0xa182,
- 0x000c, 0x7082, 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa, 0x0156,
- 0x0136, 0x0146, 0x7084, 0x8114, 0xa210, 0x7286, 0xa080, 0x000b,
- 0xad00, 0x2098, 0xb284, 0x0600, 0x0118, 0x20a1, 0x022b, 0x0010,
- 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x014e,
- 0x013e, 0x015e, 0x0804, 0x3c11, 0xd6d4, 0x1904, 0x34cf, 0x6820,
- 0xd084, 0x0904, 0x3c11, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0120,
- 0xa086, 0x0060, 0x1108, 0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b,
- 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a,
- 0x78aa, 0x8008, 0x810c, 0x0904, 0x37f6, 0xa18c, 0x00f8, 0x1904,
- 0x37f6, 0x0156, 0x0136, 0x0146, 0x0016, 0x20a1, 0x012b, 0x3208,
- 0xa18c, 0x0600, 0x0110, 0x20a1, 0x022b, 0x001e, 0x789b, 0x0000,
- 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x014e, 0x013e,
- 0x015e, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0804, 0x3c11, 0x6818,
- 0xd0fc, 0x0110, 0x681b, 0x0008, 0x080c, 0x3a61, 0x781b, 0x00ed,
- 0x0005, 0x2300, 0x0002, 0x34e0, 0x359d, 0x34de, 0x080c, 0x2575,
- 0x7cd8, 0x7ddc, 0x7fd0, 0x82ff, 0x1528, 0x7200, 0xa286, 0x0003,
- 0x0904, 0x2f09, 0x71d0, 0xd1bc, 0x11f8, 0xd1b4, 0x01e8, 0x2001,
- 0x4701, 0x2004, 0xd0c4, 0x11c0, 0x00d6, 0x783b, 0x8800, 0x781b,
- 0x0059, 0x70b8, 0xa06d, 0x68b4, 0xc0a5, 0x785a, 0x6894, 0x78d6,
- 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030,
- 0x00de, 0x0030, 0x7200, 0x0020, 0x783b, 0x1800, 0x781b, 0x0057,
- 0xa284, 0x000f, 0x0002, 0x3588, 0x3545, 0x351d, 0x2f38, 0x351b,
- 0x3588, 0x351b, 0x351b, 0x080c, 0x2575, 0x681c, 0xd0ec, 0x0118,
- 0x6008, 0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, 0x6800, 0x6006,
- 0xa005, 0x1108, 0x6002, 0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084,
- 0x000e, 0x1120, 0x71c8, 0xa188, 0x0100, 0x0028, 0x7030, 0x68ba,
- 0x713c, 0x70c8, 0xa108, 0x2104, 0x6802, 0x2d0a, 0x715a, 0xd6dc,
- 0x1120, 0xc6fc, 0x6eb6, 0x0804, 0x3588, 0x6eb6, 0xa684, 0x0060,
- 0x1120, 0xa684, 0x7fff, 0x68b6, 0x04d8, 0xd6dc, 0x1150, 0xa684,
- 0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898, 0x68aa, 0x080c, 0x3f4e,
- 0x0478, 0xd6ac, 0x0140, 0xa006, 0x080c, 0x3f4e, 0x2408, 0x2510,
- 0x69aa, 0x6aa6, 0x0068, 0x2408, 0x2510, 0x2700, 0x8007, 0xa084,
- 0x007f, 0xa108, 0xa291, 0x0000, 0x69aa, 0x6aa6, 0x080c, 0x3f4e,
- 0xd6fc, 0x01b0, 0xa684, 0x7fff, 0x68b6, 0x2510, 0x2408, 0xd6ac,
- 0x1138, 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000,
- 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae,
- 0x7000, 0xa086, 0x0030, 0x1904, 0x25c9, 0x7003, 0x0002, 0x70b8,
- 0xa06d, 0x68bc, 0x703e, 0x70b4, 0xa065, 0x68c0, 0x7056, 0x2d00,
- 0x704a, 0xad80, 0x0009, 0x7042, 0x0005, 0xa586, 0x8800, 0x1148,
- 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef,
- 0x600a, 0x0804, 0x3a5b, 0x7043, 0x0000, 0xa282, 0x0006, 0x0310,
- 0x080c, 0x2575, 0x2300, 0x0002, 0x35b7, 0x35c8, 0x35d2, 0x2200,
- 0x0002, 0x35bf, 0x3a5b, 0x35c1, 0x35bf, 0x3603, 0x3651, 0x080c,
- 0x2575, 0x7a80, 0xa294, 0x0f00, 0x080c, 0x36a5, 0x0804, 0x3a30,
- 0x00c1, 0x0002, 0x3a5b, 0x35d0, 0x35d0, 0x3603, 0x35d0, 0x3a5b,
- 0x080c, 0x2575, 0x0071, 0x0002, 0x35dc, 0x35da, 0x35da, 0x35dc,
- 0x35da, 0x35dc, 0x080c, 0x2575, 0x080c, 0x3a70, 0x781b, 0x0082,
- 0x0005, 0x7000, 0xa086, 0x0002, 0x1150, 0x080c, 0x37e1, 0x0010,
- 0x080c, 0x3f4e, 0x6008, 0xa084, 0xfbef, 0x600a, 0x0020, 0x7000,
- 0xa086, 0x0003, 0x0da8, 0x7003, 0x0005, 0x2001, 0x8ee0, 0xae8e,
- 0x4740, 0x0110, 0x2001, 0x8f12, 0x2068, 0x704a, 0xad80, 0x0009,
- 0x7042, 0x2200, 0x0005, 0x7000, 0xa086, 0x0002, 0x1158, 0x70d0,
- 0xc0b5, 0x70d2, 0x2c00, 0x70b6, 0x2d00, 0x70ba, 0x0038, 0x080c,
- 0x3f4e, 0x0020, 0x7000, 0xa086, 0x0003, 0x0dc8, 0x7003, 0x0001,
- 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f,
- 0xa215, 0x2069, 0x8dc0, 0xb284, 0x0600, 0x1118, 0xc2fd, 0x2069,
- 0x8ed0, 0x2d04, 0x2d08, 0x715a, 0xa06d, 0x0128, 0x6814, 0xa206,
- 0x0120, 0x6800, 0x0cb8, 0x080c, 0x36a5, 0x6eb4, 0x7e5a, 0x6920,
- 0xa184, 0x0c00, 0x0904, 0x36cb, 0x7060, 0xa086, 0x0006, 0x1128,
- 0x7070, 0xa206, 0x1110, 0x7062, 0x707a, 0x681b, 0x0005, 0xc1ad,
- 0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x080c, 0x3a67, 0x0804,
- 0x36cb, 0x7200, 0xa286, 0x0002, 0x1158, 0x70d0, 0xc0b5, 0x70d2,
- 0x2c00, 0x70b6, 0x2d00, 0x70ba, 0x0030, 0x080c, 0x3f4e, 0x0018,
- 0xa286, 0x0003, 0x0dd0, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00,
- 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0xae86, 0x4740,
- 0x0108, 0xc2fd, 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0x2118, 0x70c8,
- 0xa168, 0x2d04, 0x2d08, 0x715a, 0xa06d, 0x0128, 0x6814, 0xa206,
- 0x0118, 0x6800, 0x0cb8, 0x0409, 0x6eb4, 0x6920, 0xa184, 0x0c00,
- 0x0904, 0x36cb, 0xd0dc, 0x0178, 0x7060, 0xa086, 0x0004, 0x1140,
- 0x7070, 0xa206, 0x1128, 0x7074, 0xa306, 0x1110, 0x7062, 0x707a,
- 0x080c, 0x3a6d, 0x0480, 0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922,
- 0x080c, 0x3a67, 0x707b, 0x0000, 0x0430, 0x7003, 0x0005, 0xb284,
- 0x0600, 0x0118, 0x2001, 0x8ee0, 0x0010, 0x2001, 0x8f12, 0x2068,
- 0x704a, 0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x1f04,
- 0x36b4, 0x015e, 0xb284, 0x0600, 0x0110, 0xc2fc, 0x0008, 0xc2fd,
- 0x6a16, 0xad80, 0x0009, 0x7042, 0x68b7, 0x0700, 0x6823, 0x0800,
- 0x6827, 0x0003, 0x0005, 0xc6ec, 0xa6ac, 0x0060, 0x0904, 0x3712,
- 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x11e0, 0x7bd2, 0x7bda,
- 0x7cd6, 0x7cde, 0xa586, 0x0060, 0x05c8, 0xd6f4, 0x1108, 0xc6ed,
- 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0083, 0xd69c, 0x0128, 0x2009,
- 0x0082, 0x2019, 0x0000, 0x2320, 0x791a, 0xd6ec, 0x0588, 0x080c,
- 0x4208, 0x0470, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305,
- 0x01f8, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x1108,
- 0xc6ed, 0xc6f4, 0x7e5a, 0x2011, 0x0083, 0xd69c, 0x0128, 0x2011,
- 0x0082, 0x2019, 0x0000, 0x2320, 0x7a1a, 0xd6ec, 0x0188, 0x080c,
- 0x4235, 0x0070, 0x2019, 0x0000, 0x2320, 0x0010, 0xa6b4, 0xb7ff,
- 0x7e5a, 0x2009, 0x0083, 0xd69c, 0x0110, 0x2009, 0x0082, 0x791a,
- 0x68c0, 0x7056, 0x2d00, 0x704a, 0x68c4, 0x2060, 0x71d0, 0x2001,
- 0x4701, 0x2004, 0xd0c4, 0x15c8, 0x70d4, 0xa02d, 0x01b8, 0xd1bc,
- 0x0548, 0x7a80, 0xa294, 0x0f00, 0x70d8, 0xa206, 0x0118, 0x78e0,
- 0xa504, 0x1558, 0x70d6, 0xc1bc, 0x71d2, 0x0438, 0x2031, 0x0001,
- 0x852c, 0x0218, 0x8633, 0x8210, 0x0cd8, 0x0005, 0x7de0, 0xa594,
- 0xff00, 0x0130, 0x2011, 0x0008, 0x852f, 0x0c81, 0x8637, 0x0008,
- 0x0c69, 0x8217, 0x7880, 0xa084, 0x0f00, 0xa206, 0x0170, 0x72da,
- 0x76d6, 0x0058, 0x7a80, 0xa294, 0x0f00, 0x70d8, 0xa236, 0x0dc0,
- 0x78e0, 0xa534, 0x0da8, 0xc1bd, 0x71d2, 0xd1b4, 0x1904, 0x25c6,
- 0x2300, 0xa405, 0x0904, 0x25c6, 0x70a0, 0xa086, 0x0001, 0x1904,
- 0x260d, 0x0005, 0x6020, 0xa005, 0x0150, 0x8001, 0x6022, 0x6008,
- 0xa085, 0x0008, 0x600a, 0x700f, 0x0100, 0x702c, 0x6026, 0x0005,
- 0xa006, 0x080c, 0x3f4e, 0x7000, 0xa086, 0x0002, 0x0120, 0x7060,
- 0xa086, 0x0005, 0x1150, 0x682b, 0x0000, 0x6817, 0x0000, 0x681b,
- 0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084, 0x000f,
- 0x0002, 0x25c9, 0x37a6, 0x37a3, 0x37c3, 0x37af, 0x25c9, 0x37a1,
- 0x37a1, 0x080c, 0x2575, 0x0449, 0x0411, 0x0028, 0x0431, 0x7058,
- 0x2060, 0x6800, 0x6002, 0x080c, 0x1dbf, 0x0804, 0x25c9, 0x7060,
- 0x7063, 0x0000, 0x707f, 0x0000, 0x0002, 0x37bf, 0x37bf, 0x37bd,
- 0x37bd, 0x37bd, 0x37bf, 0x37bd, 0x37bf, 0x0804, 0x2a9a, 0x7063,
- 0x0000, 0x0804, 0x25c9, 0x681b, 0x0000, 0x0804, 0x31a7, 0x6800,
- 0xa005, 0x1108, 0x6002, 0x6006, 0x0005, 0x6410, 0x84ff, 0x0168,
- 0x2009, 0x4702, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x1128,
- 0x2021, 0x4704, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xc0a4, 0x600a,
- 0x0005, 0x6018, 0xa005, 0x0110, 0x8001, 0x601a, 0x0005, 0x080c,
- 0x3c6e, 0x681b, 0x0018, 0x0490, 0x080c, 0x3c6e, 0x681b, 0x0019,
- 0x0468, 0x080c, 0x3c6e, 0x681b, 0x001a, 0x0440, 0x080c, 0x3c6e,
- 0x681b, 0x0003, 0x0418, 0x7770, 0x080c, 0x3b95, 0x7174, 0xa18c,
- 0x00ff, 0x3210, 0xa294, 0x0600, 0x0118, 0xa1e8, 0x8cc0, 0x0010,
- 0xa1e8, 0x8dd0, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x1118, 0x707a,
- 0x0804, 0x25c9, 0x6814, 0x7270, 0xa206, 0x0110, 0x6800, 0x0c98,
- 0x6800, 0x200a, 0x681b, 0x0005, 0x707b, 0x0000, 0x080c, 0x37cd,
- 0x6820, 0xd084, 0x1110, 0x080c, 0x37c7, 0x080c, 0x37e1, 0x681f,
- 0x0000, 0x6823, 0x0020, 0x080c, 0x1dbf, 0x0804, 0x25c9, 0xa282,
- 0x0003, 0x1904, 0x3a35, 0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4,
- 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1c4, 0x05b0, 0xc1c4, 0x6922,
- 0xa6b4, 0x00ff, 0x0530, 0xa682, 0x0018, 0x0218, 0x0110, 0x2031,
- 0x0018, 0xa686, 0x0010, 0x1108, 0x8630, 0x852b, 0x852b, 0x2041,
- 0x0000, 0x080c, 0x3aee, 0x0118, 0x080c, 0x391a, 0x00a0, 0x080c,
- 0x3aba, 0x080c, 0x3917, 0x6920, 0xc1c5, 0x6922, 0x7e58, 0xc695,
- 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, 0x0082,
- 0x0005, 0x080c, 0x3917, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071,
- 0x0005, 0x781b, 0x0083, 0x0005, 0x00c6, 0x7054, 0x2060, 0x6100,
- 0xd1e4, 0x0598, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x0018,
- 0x0218, 0x0110, 0x2011, 0x0018, 0x2600, 0xa202, 0x1208, 0x2230,
- 0xa686, 0x0010, 0x1108, 0x8630, 0x6208, 0xa294, 0x00ff, 0x78ec,
- 0xd0e4, 0x0130, 0xa282, 0x000a, 0x1240, 0x2011, 0x000a, 0x0028,
- 0xa282, 0x000c, 0x1210, 0x2011, 0x000c, 0x2200, 0xa502, 0x1208,
- 0x2228, 0x080c, 0x3abe, 0x852b, 0x852b, 0x2041, 0x0000, 0x080c,
- 0x3aee, 0x0118, 0x080c, 0x391a, 0x0020, 0x080c, 0x3aba, 0x080c,
- 0x3917, 0x7858, 0xc095, 0x785a, 0x00ce, 0x781b, 0x0082, 0x0005,
- 0x00c6, 0x2960, 0x6000, 0xd0e4, 0x1188, 0xd0b4, 0x1150, 0x6010,
- 0xa084, 0x000f, 0x1130, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x00ce,
- 0x0005, 0x2011, 0x0032, 0x2019, 0x0000, 0x00f0, 0x68a0, 0xd0cc,
- 0x1dc0, 0x6208, 0xa294, 0x00ff, 0x78ec, 0xd0e4, 0x0130, 0xa282,
- 0x000b, 0x1218, 0x2011, 0x000a, 0x0028, 0xa282, 0x000c, 0x1210,
- 0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x0018,
- 0x0218, 0x0110, 0x2019, 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0003,
- 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5,
- 0x6822, 0x080c, 0x3a7a, 0x00ce, 0x0005, 0x00c6, 0x2960, 0x6104,
- 0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0000,
- 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa,
- 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x00ce, 0x0005, 0xa006,
- 0x2030, 0x2010, 0x00c6, 0x7154, 0x2160, 0x2018, 0x2008, 0xa084,
- 0xffe0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4,
- 0xa084, 0x7770, 0xa18c, 0x000f, 0xa105, 0x2029, 0x4705, 0x252c,
- 0xd5cc, 0x0140, 0xd3a4, 0x0110, 0xa085, 0x0800, 0xd3fc, 0x0110,
- 0xa085, 0x8080, 0x78a6, 0x6016, 0x788a, 0xa6b4, 0x001f, 0x8637,
- 0x8204, 0x8004, 0xa605, 0x600e, 0x6004, 0xa084, 0xffd5, 0x6006,
- 0x00ce, 0x0005, 0xa282, 0x0002, 0x1904, 0x3a3f, 0x7aa8, 0x6920,
- 0xc1bd, 0x6922, 0xd1cc, 0x0568, 0xc1cc, 0x6922, 0xa294, 0x00ff,
- 0xa282, 0x0002, 0x1a04, 0x3a30, 0x080c, 0x39c1, 0x080c, 0x3917,
- 0xa980, 0x0001, 0x200c, 0x080c, 0x3b91, 0x080c, 0x38b8, 0x88ff,
- 0x0178, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a,
- 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, 0x0082, 0x0005,
- 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083,
- 0x0005, 0xa282, 0x0002, 0x1218, 0xa284, 0x0001, 0x0140, 0x7154,
- 0xa188, 0x0000, 0x210c, 0xd1ec, 0x1110, 0x2011, 0x0000, 0x080c,
- 0x3aac, 0x0479, 0x080c, 0x3917, 0x7858, 0xc095, 0x785a, 0x781b,
- 0x0082, 0x0005, 0x00c6, 0x0026, 0x2960, 0x6000, 0x2011, 0x0001,
- 0xd0ec, 0x1158, 0xd0bc, 0x1138, 0x6014, 0xd0b4, 0x1120, 0xc1a4,
- 0x6106, 0xa006, 0x0088, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
- 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x080c, 0x3a7a,
- 0x6820, 0xa085, 0x0200, 0x6822, 0x002e, 0x00ce, 0x0005, 0x8807,
- 0xa715, 0x00c6, 0x2009, 0x0000, 0x7054, 0x2060, 0x82ff, 0x0110,
- 0x2009, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084,
- 0xff9f, 0xa105, 0xc0ec, 0xd0b4, 0x1108, 0xc0ed, 0x6100, 0xd1f4,
- 0x0110, 0xa085, 0x0020, 0x78a6, 0x6016, 0x788a, 0x6004, 0xa084,
- 0xffef, 0x6006, 0x00ce, 0x0005, 0x0006, 0x7000, 0xa086, 0x0003,
- 0x0110, 0x000e, 0x0010, 0x000e, 0x0498, 0xd6ac, 0x0588, 0x7888,
- 0xa084, 0x0040, 0x0568, 0x7bb8, 0x8307, 0xa084, 0x007f, 0x1518,
- 0x8207, 0xa084, 0x00ff, 0x0904, 0x3a57, 0xa09a, 0x0004, 0x1a04,
- 0x3a57, 0xd6f4, 0x11d0, 0x79d8, 0x7adc, 0xa108, 0xa291, 0x0000,
- 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x080c, 0x42e8, 0x781b, 0x0080,
- 0xb284, 0x0600, 0x0118, 0x2001, 0x0000, 0x0010, 0x2001, 0x0001,
- 0x080c, 0x419a, 0x0005, 0x080c, 0x2575, 0x781b, 0x0080, 0x0005,
- 0x781b, 0x0083, 0x0005, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031,
- 0x0000, 0xa006, 0x2010, 0x080c, 0x391a, 0x080c, 0x39bf, 0x7e58,
- 0x080c, 0x3a73, 0x781b, 0x0082, 0x0005, 0x0cd1, 0x6820, 0xc0c4,
- 0x6822, 0x00c6, 0x7054, 0x2060, 0x080c, 0x3944, 0x00b0, 0x0c81,
- 0x6820, 0xc0cc, 0x6822, 0x00c6, 0x7054, 0x2060, 0x080c, 0x39de,
- 0x0060, 0x0c31, 0x6820, 0xa084, 0xecff, 0x6822, 0x00c6, 0x7054,
- 0x2060, 0x6004, 0xa084, 0xffc5, 0x6006, 0x00ce, 0x0005, 0x0049,
- 0x781b, 0x0082, 0x0005, 0x6827, 0x0002, 0x0049, 0x781b, 0x0082,
- 0x0005, 0x2001, 0x0005, 0x0088, 0x2001, 0x000c, 0x0070, 0x6820,
- 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0040, 0x2001, 0x000d, 0x0028,
- 0x2001, 0x0009, 0x0010, 0x2001, 0x0007, 0x789b, 0x007e, 0x78aa,
- 0xc69d, 0x7e5a, 0x70d0, 0xd0b4, 0x0168, 0xc0b4, 0x70d2, 0x00c6,
- 0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
- 0x601a, 0x00ce, 0x0005, 0x0076, 0x873f, 0xa7bc, 0x000f, 0x873b,
- 0x873b, 0x8703, 0xa0e0, 0x4bc0, 0xae8e, 0x4740, 0x0110, 0xa0e0,
- 0x4c40, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x7fe0, 0x78ae,
- 0x6012, 0x79a4, 0xa184, 0x773f, 0x78a6, 0x6016, 0x6004, 0xa085,
- 0x0038, 0x6006, 0x007e, 0x0005, 0x789b, 0x0080, 0x78ab, 0x0001,
- 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab,
- 0x0004, 0x0800, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b, 0x0080,
- 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7eaa,
- 0x789b, 0x0060, 0x78ab, 0x0005, 0x0804, 0x3a7a, 0x0156, 0x8007,
- 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4,
- 0xa18c, 0xffe0, 0x2021, 0x3b7a, 0x2019, 0x0011, 0x20a9, 0x000e,
- 0x2011, 0x0032, 0x2404, 0xa084, 0xffe0, 0xa106, 0x0128, 0x8420,
- 0x2300, 0xa210, 0x1f04, 0x3ae2, 0x015e, 0x0005, 0x0156, 0x0804,
- 0x3b30, 0x2021, 0x3b88, 0x20a9, 0x0009, 0x2011, 0x0029, 0xa582,
- 0x0028, 0x0550, 0x8420, 0x95a9, 0x2011, 0x0033, 0xa582, 0x0033,
- 0x0618, 0x8420, 0x95a9, 0x2019, 0x000a, 0x2011, 0x0065, 0x2200,
- 0xa502, 0x02d0, 0x8420, 0x2300, 0xa210, 0x1f04, 0x3b07, 0x015e,
- 0x0088, 0x2021, 0x3b7a, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011,
- 0x0033, 0x2200, 0xa502, 0x0240, 0x8420, 0x2300, 0xa210, 0x1f04,
- 0x3b19, 0x015e, 0xa006, 0x0005, 0x8211, 0x015e, 0xa582, 0x0064,
- 0x1220, 0x7808, 0xa085, 0x0070, 0x780a, 0x2404, 0xa005, 0x0005,
- 0xa886, 0x0002, 0x01e8, 0x2021, 0x3b66, 0x20a9, 0x000d, 0x2011,
- 0x0028, 0xa582, 0x0028, 0x0d48, 0x8420, 0x2019, 0x0019, 0x2011,
- 0x0033, 0x2200, 0xa502, 0x0e00, 0x8420, 0x2300, 0xa210, 0x1f04,
- 0x3b41, 0x015e, 0x2011, 0x0184, 0xa582, 0x0185, 0x0ab0, 0x0890,
- 0x2021, 0x3b75, 0x20a9, 0x0003, 0x2011, 0x0024, 0xa586, 0x0024,
- 0x0960, 0x8420, 0x2011, 0x0028, 0xa586, 0x0028, 0x0930, 0x8420,
- 0x2019, 0x0019, 0x2011, 0x0033, 0x0804, 0x3b19, 0x1021, 0x2202,
- 0x3403, 0x4604, 0x5805, 0x6a06, 0x7c07, 0x4610, 0x4612, 0x5812,
- 0x5a12, 0x6a14, 0x6c14, 0x6e14, 0x7e17, 0x9021, 0xb002, 0xe204,
- 0xe210, 0xe210, 0x1209, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404,
- 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, 0x0e07,
- 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, 0x7c07, 0x7e07,
- 0x0e00, 0x789b, 0x0080, 0xa046, 0x0005, 0xa784, 0x0f00, 0x800b,
- 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xd7fc,
- 0x0118, 0xa0e0, 0x6cc0, 0x0010, 0xa0e0, 0x4cc0, 0x0005, 0x00e6,
- 0x00f6, 0xd084, 0x0138, 0x2079, 0x0100, 0x2009, 0x4780, 0x2071,
- 0x4780, 0x0030, 0x2009, 0x4740, 0x2079, 0x0200, 0x2071, 0x4740,
- 0x2091, 0x8000, 0x2104, 0xa084, 0x000f, 0x0002, 0x3bc8, 0x3bc8,
- 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc6, 0x3bc6, 0x080c, 0x2575,
- 0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x0580, 0x7858,
- 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, 0xa086, 0x1814,
- 0x1530, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004, 0x1de0, 0x784b,
- 0x0008, 0x7848, 0xa084, 0x0008, 0x1de0, 0x7830, 0xd0bc, 0x11b8,
- 0xb284, 0x0800, 0x0118, 0x0104, 0x3bff, 0x0010, 0x0304, 0x3bff,
- 0x79e4, 0xa184, 0x0030, 0x0158, 0x78ec, 0xa084, 0x0003, 0x0138,
- 0x681c, 0xd0ac, 0x1110, 0x00d9, 0x0010, 0x781b, 0x00fb, 0x00fe,
- 0x00ee, 0x0005, 0x2001, 0x4701, 0x2004, 0xd0ac, 0x1118, 0x6814,
- 0x080c, 0x249e, 0x0005, 0x781b, 0x0083, 0x0005, 0x781b, 0x0082,
- 0x0005, 0x781b, 0x0071, 0x0005, 0x781b, 0x006e, 0x0005, 0x2009,
- 0x4719, 0x210c, 0xa186, 0x0000, 0x0150, 0xa186, 0x0001, 0x0150,
- 0x701f, 0x000b, 0x7063, 0x0001, 0x781b, 0x0054, 0x0005, 0x781b,
- 0x00f3, 0x0005, 0x701f, 0x000a, 0x0005, 0x2009, 0x4719, 0x210c,
- 0xa186, 0x0000, 0x0168, 0xa186, 0x0001, 0x0138, 0x701f, 0x000b,
- 0x7063, 0x0001, 0x781b, 0x0054, 0x0005, 0x701f, 0x000a, 0x0005,
- 0x781b, 0x00f2, 0x0005, 0x781b, 0x00fb, 0x0005, 0x781b, 0x00fa,
- 0x0005, 0x781b, 0x00cc, 0x0005, 0x781b, 0x00cb, 0x0005, 0x6818,
- 0xd0fc, 0x0110, 0x681b, 0x001d, 0x701f, 0x000b, 0x7063, 0x0001,
- 0x781b, 0x0054, 0x0005, 0x7830, 0xa084, 0x00c0, 0x1170, 0x7808,
- 0xc08c, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000, 0x78ec, 0xa084,
- 0x0021, 0x0118, 0x7808, 0xc08d, 0x780a, 0x0005, 0x7808, 0xc08d,
- 0x780a, 0x0005, 0x7830, 0xa084, 0x0040, 0x1de0, 0xb284, 0x0800,
- 0x0118, 0x1104, 0x3c80, 0x0010, 0x1304, 0x3c80, 0x78ac, 0x0005,
- 0x7808, 0xa084, 0xfffd, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000,
- 0x78ec, 0xa084, 0x0021, 0x0140, 0xb284, 0x0800, 0x0118, 0x1104,
- 0x3c8f, 0x0010, 0x1304, 0x3c92, 0x78ac, 0x0006, 0x7808, 0xa085,
- 0x0002, 0x780a, 0x000e, 0x0005, 0xa784, 0x0001, 0x1904, 0x324d,
- 0xa784, 0x0070, 0x0140, 0x00c6, 0x2d60, 0x2f68, 0x080c, 0x2490,
- 0x2d78, 0x2c68, 0x00ce, 0xa784, 0x0008, 0x0148, 0x784b, 0x0008,
- 0x78ec, 0xa084, 0x0003, 0x0904, 0x324d, 0x0804, 0x3c0b, 0xa784,
- 0x0004, 0x01c8, 0x78b8, 0xa084, 0x8000, 0x01a8, 0x784b, 0x0008,
- 0x78ec, 0xa084, 0x0003, 0x0904, 0x324d, 0x78e4, 0xa084, 0x0007,
- 0xa086, 0x0001, 0x1140, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a,
- 0x781b, 0x00fb, 0x0005, 0xa784, 0x0080, 0x0140, 0x7884, 0xd0fc,
- 0x0128, 0x080c, 0x3a57, 0x681b, 0x0022, 0x0005, 0x681b, 0x0003,
- 0x7858, 0xa084, 0x5f00, 0x681e, 0x682f, 0x0000, 0x6833, 0x0000,
- 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x2bac, 0xb284,
- 0x0800, 0x0110, 0x0104, 0x25c6, 0x0304, 0x25c6, 0x6b14, 0x8307,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc, 0x0118, 0xa080,
- 0x4c40, 0x0010, 0xa080, 0x4bc0, 0x2060, 0x2048, 0x7056, 0x2a60,
- 0x0005, 0x00c6, 0x2960, 0x6000, 0xd0ac, 0x0904, 0x3d57, 0x68a0,
- 0xd1ac, 0x1120, 0xa084, 0x0e00, 0x0904, 0x3d55, 0x6108, 0x8117,
- 0xa18c, 0x00ff, 0x631c, 0x832f, 0xd0dc, 0x0110, 0xa39d, 0x0001,
- 0xd0cc, 0x11c8, 0xa584, 0x00ff, 0x0138, 0x78ec, 0xd0e4, 0x0110,
- 0x8213, 0x00b8, 0x2029, 0x0000, 0xa182, 0x000c, 0x1290, 0x78ec,
- 0xd0e4, 0x1118, 0x2009, 0x000c, 0x0060, 0xa182, 0x000b, 0x1248,
- 0x2009, 0x000a, 0x0030, 0x2009, 0x0032, 0x2011, 0x0000, 0x2029,
- 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004, 0x79aa,
- 0x78ab, 0x0000, 0x7aaa, 0x7baa, 0x7daa, 0xa8c0, 0x0008, 0x6820,
- 0xa085, 0x1000, 0x6822, 0x080c, 0x3a7a, 0xa085, 0x0001, 0x00ce,
- 0x0005, 0xa282, 0x0006, 0x1904, 0x3a49, 0x7da8, 0x7eac, 0x8637,
- 0xa5ac, 0x00ff, 0xa6b4, 0x00ff, 0x7fac, 0x8747, 0xa7bc, 0x00ff,
- 0xa8c4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1e4, 0x0904, 0x3dcb,
- 0xa18c, 0xecff, 0x6922, 0xa782, 0x0002, 0x1a04, 0x3a23, 0xa6b4,
- 0x00ff, 0x0904, 0x3dc8, 0xa682, 0x0031, 0x1a04, 0x3a23, 0xa582,
- 0x0009, 0x0a04, 0x3a23, 0xa882, 0x0003, 0x1a04, 0x3a23, 0xa886,
- 0x0002, 0x01d0, 0xa886, 0x0000, 0x1904, 0x3a23, 0x2001, 0x000c,
- 0x79ec, 0xd1e4, 0x0110, 0x2001, 0x000a, 0xa502, 0x1290, 0x080c,
- 0x3a23, 0x00c6, 0x2960, 0x6004, 0xa085, 0x001a, 0x6006, 0x6000,
- 0xc0ac, 0x6002, 0x00ce, 0x0005, 0xa786, 0x0000, 0x0904, 0x3a23,
- 0x8634, 0xa682, 0x0018, 0x0228, 0x0120, 0x2031, 0x0018, 0x0804,
- 0x3e19, 0xa686, 0x0010, 0x1108, 0x8630, 0x852b, 0x852b, 0x080c,
- 0x3aee, 0x0904, 0x3a23, 0x080c, 0x391a, 0x080c, 0x39bf, 0x7e58,
- 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005,
- 0x080c, 0x3917, 0x0c90, 0xa886, 0x0002, 0x1108, 0x8634, 0x7154,
- 0xa188, 0x0000, 0x210c, 0xd1ac, 0x0904, 0x3a23, 0xd1ec, 0x1120,
- 0x2039, 0x0000, 0x2041, 0x0000, 0xd1e4, 0x1120, 0x2031, 0x0000,
- 0x2041, 0x0000, 0xa782, 0x0002, 0x12c8, 0x621c, 0xa284, 0x00ff,
- 0xa706, 0x0110, 0x2039, 0x0000, 0xa605, 0x0190, 0x6108, 0x811f,
- 0xa39c, 0x00ff, 0x0168, 0xa302, 0x1208, 0x2330, 0x8807, 0xa705,
- 0xa086, 0x0201, 0x0160, 0xa886, 0x0000, 0x0168, 0x2039, 0x0000,
- 0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x0070, 0xa284,
- 0xff00, 0x1108, 0x2040, 0xa184, 0x00ff, 0xa502, 0x0108, 0x2128,
- 0x852b, 0x852b, 0x080c, 0x3aee, 0x0d58, 0x080c, 0x391a, 0x080c,
- 0x39bf, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab,
- 0x0004, 0x7daa, 0x78ab, 0x0000, 0x7eaa, 0x7faa, 0x2800, 0x78aa,
- 0x789b, 0x0060, 0x78ab, 0x0008, 0x6820, 0xc0e5, 0x6822, 0x080c,
- 0x3a7a, 0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x0020,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0062, 0x0009, 0x0014, 0x0014, 0x9855, 0x984d, 0x0014,
- 0x9911, 0x98ff, 0x0014, 0x0014, 0x0090, 0x00e7, 0x0100, 0x0402,
- 0x2008, 0xf880, 0x0018, 0x0017, 0x840f, 0xd8c1, 0x0014, 0x0016,
- 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, 0x2500, 0x0013, 0x2500,
- 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
- 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0xa200, 0x3806,
- 0x8839, 0x20c4, 0x0864, 0xa850, 0x3008, 0x28c1, 0x9d18, 0xa201,
- 0x300c, 0x2847, 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a,
- 0xa808, 0x28e2, 0x9cce, 0xa8f3, 0x0864, 0xa83e, 0x300c, 0xa801,
- 0x3008, 0x28e1, 0x9cce, 0x28a2, 0x7163, 0xa831, 0x2021, 0xa818,
- 0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0, 0x6fc0, 0x67a4, 0x6c80,
- 0x0212, 0xa205, 0x883d, 0x882b, 0x1814, 0x883b, 0x7027, 0x85f2,
- 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa813, 0x883e, 0xa811,
- 0x2882, 0x7162, 0xa814, 0x280a, 0xa204, 0x64c0, 0x6de0, 0x67a0,
- 0x6fc0, 0x1814, 0x883b, 0x7023, 0x8576, 0x8677, 0xa802, 0x7861,
- 0x883e, 0x206a, 0x28c1, 0x9d18, 0x2042, 0x2101, 0xa8ca, 0x2902,
- 0xa20e, 0xa80b, 0xa207, 0x0014, 0xa203, 0x8000, 0x85a4, 0x1872,
- 0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208, 0x856e, 0x7121, 0x0014,
- 0x0704, 0x3008, 0x9cce, 0x0014, 0xa202, 0x8000, 0x85a4, 0x3009,
- 0x84a8, 0x19e2, 0xf844, 0x856e, 0x883f, 0x08e6, 0xa8f5, 0xf861,
- 0xa8eb, 0xf801, 0x0014, 0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532,
- 0xfaa2, 0x1de2, 0x0014, 0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8,
- 0xd6e0, 0x1fe6, 0x0014, 0x3008, 0x8000, 0x2849, 0x1011, 0xa8fc,
- 0x3008, 0x8000, 0xa000, 0x2081, 0x2802, 0x1011, 0xa8fc, 0xa889,
- 0x3008, 0x20a1, 0x283c, 0x1011, 0xa8fc, 0xa209, 0x0017, 0x300c,
- 0x8000, 0x85a4, 0x1de2, 0xdac1, 0x0014, 0x0210, 0xa801, 0x0014,
- 0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0, 0x18f2, 0x0014, 0xa20b,
- 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d22, 0x0704, 0xa206, 0x6865,
- 0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016, 0x6042, 0x8008, 0xa8fa,
- 0x8160, 0x842a, 0x8180, 0xf021, 0x3008, 0x84a8, 0x11d7, 0x7042,
- 0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, 0x0000, 0x0126, 0x70d0,
- 0xa084, 0x4c00, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205,
- 0x11a0, 0x720c, 0x82ff, 0x0128, 0x8aff, 0x1178, 0x7200, 0xd284,
- 0x1160, 0x7804, 0xd0cc, 0x0110, 0x080c, 0x435b, 0x7007, 0x0008,
- 0x7003, 0x0008, 0x012e, 0x2000, 0x0005, 0x7000, 0xa084, 0x0003,
- 0x7002, 0xc69c, 0xd084, 0x0588, 0x7108, 0xe000, 0x7008, 0xa106,
- 0x1dd8, 0xa184, 0x0003, 0x0904, 0x3fca, 0xa184, 0x01e0, 0x1904,
- 0x3fca, 0xd1f4, 0x1d88, 0xa184, 0x3000, 0xa086, 0x1000, 0x0d60,
- 0x2011, 0x0180, 0x710c, 0x8211, 0x0130, 0x7008, 0xd0f4, 0x1d20,
- 0x700c, 0xa106, 0x0dc0, 0x7007, 0x0012, 0x7108, 0xe000, 0x7008,
- 0xa106, 0x1dd8, 0xa184, 0x0003, 0x0568, 0xd194, 0x0db0, 0xd1f4,
- 0x0548, 0x7007, 0x0002, 0x0880, 0x0428, 0x7108, 0xd1fc, 0x0130,
- 0x080c, 0x40d6, 0x8aff, 0x0904, 0x3f54, 0x0cb8, 0x700c, 0xa08c,
- 0x07ff, 0x01e8, 0x7004, 0xd084, 0x0178, 0x7014, 0xa005, 0x1148,
- 0x7010, 0x7310, 0xa306, 0x1de0, 0x2300, 0xa005, 0x0128, 0xa102,
- 0x1e20, 0x7007, 0x0010, 0x0030, 0x8aff, 0x0148, 0x080c, 0x429a,
- 0x1de8, 0x09d8, 0x080c, 0x405c, 0x012e, 0x2000, 0x0005, 0x7204,
- 0x7108, 0xc19c, 0x8103, 0x1218, 0x7007, 0x0002, 0x0cc0, 0xa205,
- 0x1d88, 0x7007, 0x0008, 0x7003, 0x0008, 0x0006, 0x2001, 0x4701,
- 0x2004, 0xd0cc, 0x0110, 0x080c, 0x435b, 0x000e, 0x012e, 0x2000,
- 0x0005, 0x6428, 0x84ff, 0x0508, 0x2c70, 0x7004, 0xa0bc, 0x000f,
- 0xa7b8, 0x401d, 0x273c, 0x87fb, 0x1148, 0x0210, 0x080c, 0x2575,
- 0x609c, 0xa075, 0x0190, 0x0c88, 0x2039, 0x4012, 0x2704, 0xae68,
- 0x6808, 0xa630, 0x680c, 0xa529, 0x8421, 0x0138, 0x8738, 0x2704,
- 0xa005, 0x1da8, 0x709c, 0xa075, 0x1d00, 0x0005, 0x0000, 0x0005,
- 0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003,
- 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x4012, 0x400f,
- 0x0000, 0x0000, 0x8000, 0x0000, 0x4012, 0x0000, 0x401a, 0x4017,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x401a, 0x0000, 0x4015, 0x4015,
- 0x0000, 0x0000, 0x8000, 0x0000, 0x4015, 0x0000, 0x401b, 0x401b,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x401b, 0x2079, 0x4700, 0x2071,
- 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001, 0x2009,
- 0x0002, 0x2071, 0x0050, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003,
- 0x0000, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1128, 0x8109, 0x0118,
- 0x2071, 0x0020, 0x0c80, 0x0005, 0x7004, 0x8004, 0x1a04, 0x40b2,
- 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c,
- 0x410e, 0x0804, 0x40d2, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108,
- 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c, 0x410e,
- 0x0804, 0x40d2, 0xa19c, 0x300c, 0xa386, 0x2004, 0x0190, 0xa386,
- 0x0008, 0x01c0, 0x7004, 0xd084, 0x1148, 0x7108, 0x7008, 0xa106,
- 0x1de0, 0xa184, 0x0003, 0x0110, 0x0804, 0x410e, 0xa386, 0x200c,
- 0x19f0, 0x7200, 0x8204, 0x0230, 0x730c, 0xa384, 0x07ff, 0x0110,
- 0x080c, 0x2575, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0,
- 0x0118, 0x080c, 0x410e, 0x0470, 0x7007, 0x0012, 0x7000, 0xd084,
- 0x1148, 0x7310, 0x7014, 0xa305, 0x0128, 0x710c, 0xa184, 0x07ff,
- 0x1904, 0x405c, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0,
- 0x0118, 0x080c, 0x410e, 0x00b0, 0x7007, 0x0012, 0x7007, 0x0008,
- 0x7004, 0xd09c, 0x1de8, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184,
- 0x01e0, 0x0118, 0x080c, 0x410e, 0x0028, 0x7007, 0x0012, 0x7108,
- 0x8103, 0x0e88, 0x7003, 0x0008, 0x0005, 0x7108, 0xa184, 0x01e0,
- 0x15a8, 0x7108, 0xa184, 0x01e0, 0x1588, 0xa184, 0x0007, 0x0002,
- 0x40ea, 0x40f8, 0x40e8, 0x40f8, 0x40e8, 0x4148, 0x40e8, 0x4146,
- 0x080c, 0x2575, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff,
- 0x1118, 0x2049, 0x0000, 0x0005, 0x080c, 0x429a, 0x1de8, 0x0005,
- 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x7004, 0xd084, 0x1140,
- 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x0003, 0x0108, 0x0030,
- 0x8aff, 0x0118, 0x080c, 0x429a, 0x1de8, 0x0005, 0x7007, 0x0012,
- 0x7108, 0x1d04, 0x4111, 0x2091, 0x6000, 0x1d04, 0x4115, 0x2091,
- 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x1de8,
- 0x7007, 0x0012, 0x7108, 0xd1fc, 0x1dd8, 0x7003, 0x0000, 0x7000,
- 0xa005, 0x1130, 0x7004, 0xa005, 0x1118, 0x700c, 0xa005, 0x0108,
- 0x0c40, 0x2049, 0x0000, 0xb284, 0x0200, 0x0118, 0x2001, 0x0000,
- 0x0010, 0x2001, 0x0001, 0x080c, 0x3ba7, 0x681b, 0x0002, 0x2051,
- 0x0000, 0x0005, 0x080c, 0x2575, 0x080c, 0x2575, 0x080c, 0x4187,
- 0x7210, 0x7114, 0x700c, 0xa09c, 0x07ff, 0x2800, 0xa300, 0xa211,
- 0xa189, 0x0000, 0x04a1, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200,
- 0xa322, 0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0140, 0x1238,
- 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0c58, 0x2b60,
- 0x8a07, 0x0006, 0x6004, 0xd09c, 0x0118, 0xa7ba, 0x4017, 0x0010,
- 0xa7ba, 0x400f, 0x000e, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92,
- 0x6b8e, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0110,
- 0x080c, 0x410e, 0x7007, 0x0012, 0x080c, 0x405c, 0x0005, 0x8a50,
- 0x8739, 0x2704, 0xa004, 0x1168, 0x6000, 0xa064, 0x1108, 0x2d60,
- 0x6004, 0xa084, 0x000f, 0xa080, 0x402d, 0x203c, 0x87fb, 0x090c,
- 0x2575, 0x0005, 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004,
- 0x2090, 0x00de, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057,
- 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x0006, 0x6804, 0xa084, 0x0008,
- 0x000e, 0x0118, 0xa0b8, 0x4017, 0x0010, 0xa0b8, 0x400f, 0xb284,
- 0x0200, 0x0110, 0x7e20, 0x0008, 0x7e24, 0xa6b5, 0x000c, 0x681c,
- 0xd0b4, 0x0108, 0xc685, 0x2400, 0xa305, 0x0550, 0x2c58, 0x2704,
- 0x6104, 0xac60, 0x6000, 0xa400, 0x2048, 0xa9cc, 0x0004, 0x0118,
- 0x080c, 0x43a3, 0x0400, 0x701a, 0x6004, 0xa301, 0x701e, 0xd19c,
- 0x0140, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081, 0x0000,
- 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300, 0xa203,
- 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x080c, 0x42c5, 0x0010,
- 0x080c, 0x429a, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x00d6,
- 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x7007, 0x0004,
- 0x7004, 0xd094, 0x1de8, 0x7003, 0x0008, 0x012e, 0x2000, 0x0005,
- 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de,
- 0x7e20, 0xb284, 0x0200, 0x1108, 0x7e24, 0xa6b5, 0x000c, 0x681c,
- 0xd0ac, 0x1118, 0xc685, 0x7003, 0x0000, 0x6828, 0x2050, 0x2d60,
- 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x401d, 0x273c, 0x87fb, 0x1138,
- 0x0210, 0x080c, 0x2575, 0x689c, 0xa065, 0x0120, 0x0c88, 0x080c,
- 0x429a, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x0006, 0x0016,
- 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x7e20, 0xb284,
- 0x0200, 0x1108, 0x7e24, 0x00de, 0x003e, 0x004e, 0xa6b5, 0x000c,
- 0x681c, 0xd0b4, 0x0128, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004,
- 0x2049, 0x4235, 0x6828, 0xa055, 0x00d6, 0x0904, 0x4296, 0x2d70,
- 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x401d, 0x273c, 0x87fb,
- 0x1140, 0x0210, 0x080c, 0x2575, 0x709c, 0xa075, 0x2060, 0x0570,
- 0x0c80, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0268,
- 0x8a51, 0x1110, 0x080c, 0x2575, 0x8738, 0x2704, 0xa005, 0x1d90,
- 0x709c, 0xa075, 0x2060, 0x01d0, 0x08e0, 0x8422, 0x8420, 0x831a,
- 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b,
- 0x1210, 0x080c, 0x2575, 0xb284, 0x0200, 0x0118, 0x2071, 0x0050,
- 0x0010, 0x2071, 0x0020, 0x00de, 0x0804, 0x41c3, 0x00de, 0x012e,
- 0x2000, 0x0005, 0x7008, 0x0006, 0xa084, 0x01e0, 0x000e, 0x0110,
- 0xa006, 0x0005, 0xa084, 0x0003, 0xa086, 0x0003, 0x1108, 0x0005,
- 0x2704, 0xac78, 0x7800, 0x2f08, 0xd094, 0x1904, 0x43a6, 0x701a,
- 0x7804, 0x701e, 0x7808, 0x7012, 0x780c, 0x7016, 0x6004, 0xd09c,
- 0x0120, 0x7810, 0x7022, 0x7814, 0x7026, 0x7602, 0x7004, 0xa084,
- 0x0010, 0xc085, 0x7006, 0x2079, 0x4700, 0x8a51, 0x01e8, 0x8738,
- 0x2704, 0xa005, 0x1168, 0x609c, 0xa005, 0x01b8, 0x2060, 0x6004,
- 0xa084, 0x000f, 0xa080, 0x401d, 0x203c, 0x87fb, 0x090c, 0x2575,
- 0x7008, 0x0006, 0xa084, 0x01e0, 0x000e, 0x0110, 0xa006, 0x0028,
- 0xa084, 0x0003, 0xa086, 0x0003, 0x0005, 0x2051, 0x0000, 0x0005,
- 0x0126, 0x0006, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090,
- 0x00de, 0x008e, 0x7108, 0xa184, 0x0003, 0x1128, 0x6828, 0xa005,
- 0x0178, 0x0804, 0x3f6d, 0x7108, 0xd1fc, 0x0118, 0x080c, 0x40d6,
- 0x0c88, 0x7007, 0x0010, 0x7108, 0xd1fc, 0x0de8, 0x080c, 0x40d6,
- 0x7008, 0xa086, 0x0008, 0x1d30, 0x7000, 0xa005, 0x1d18, 0x7003,
- 0x0000, 0x2049, 0x0000, 0x0006, 0x2001, 0x4701, 0x2004, 0xd0cc,
- 0x0110, 0x080c, 0x435b, 0x000e, 0x012e, 0x2000, 0x0005, 0x0126,
- 0x0146, 0x0136, 0x0156, 0x00c6, 0x00d6, 0x70d0, 0xa084, 0x4c00,
- 0x8004, 0x2090, 0x00de, 0x2049, 0x431f, 0xad80, 0x0011, 0x20a0,
- 0xb284, 0x0200, 0x0118, 0x2099, 0x0032, 0x0010, 0x2099, 0x0031,
- 0x700c, 0xa084, 0x07ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002,
- 0x7003, 0x0001, 0x0118, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084,
- 0x07ff, 0x0130, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x1de0,
- 0x00ce, 0x2049, 0x0000, 0x7003, 0x0000, 0x015e, 0x013e, 0x014e,
- 0x012e, 0x2000, 0x0005, 0x6814, 0xd0fc, 0x0904, 0x439e, 0x7000,
- 0xd084, 0x05e0, 0x7e24, 0xa6b5, 0x0004, 0x7007, 0x0004, 0x7004,
- 0xa084, 0x0004, 0x1de0, 0x7118, 0x0016, 0x711c, 0x0016, 0x7120,
- 0x0016, 0x7124, 0x0016, 0x701b, 0x0000, 0x701f, 0x3fff, 0x7023,
- 0x0000, 0x7027, 0x0000, 0x7013, 0x0004, 0x7017, 0x0000, 0x7602,
- 0x7007, 0x0001, 0x2001, 0xffff, 0x2009, 0x0031, 0x200a, 0x200a,
- 0x7108, 0x7008, 0xa106, 0x1de0, 0xd1fc, 0x0dd0, 0x002e, 0x7226,
- 0x002e, 0x7222, 0x002e, 0x721e, 0x002e, 0x721a, 0x7007, 0x0002,
- 0x7008, 0xa086, 0x0008, 0x0110, 0x0804, 0x410e, 0x7007, 0x0004,
- 0x7003, 0x0000, 0x0005, 0x2049, 0x41c3, 0x0068, 0x7008, 0xa084,
- 0x0003, 0x0110, 0xa006, 0x0005, 0xa006, 0x2020, 0x2018, 0x2c58,
- 0x2160, 0x2049, 0x0000, 0x8b58, 0x6100, 0x2100, 0xa408, 0x711a,
- 0x6004, 0xa301, 0x701e, 0x0006, 0x2b04, 0xa084, 0x0008, 0x0150,
- 0x6010, 0xa081, 0x0000, 0x7022, 0x0006, 0x6014, 0xa081, 0x0000,
- 0x7026, 0x0006, 0xa184, 0x0007, 0x2011, 0x0008, 0xa22a, 0x6208,
- 0x2400, 0xa212, 0x0026, 0x620c, 0x2240, 0x2300, 0xa843, 0x002e,
- 0x88ff, 0x1170, 0x2500, 0xa202, 0x0108, 0x1250, 0x2220, 0x2041,
- 0x0000, 0x2b04, 0xd09c, 0x0110, 0x000e, 0x000e, 0x000e, 0x0450,
- 0x7512, 0x7017, 0x0000, 0x7602, 0xa986, 0x41c3, 0x1118, 0x7007,
- 0x0001, 0x0028, 0x7004, 0xa084, 0x0010, 0xc085, 0x7006, 0x2500,
- 0xa100, 0x701a, 0x2b04, 0xa084, 0x0008, 0x0110, 0x000e, 0x004e,
- 0x001e, 0xa189, 0x0000, 0x711e, 0x2b0c, 0xa18c, 0x0008, 0x0130,
- 0xa4a1, 0x0000, 0x7422, 0xa081, 0x0000, 0x7026, 0x2500, 0xa222,
- 0xa8c3, 0x0000, 0x7412, 0x2820, 0x7416, 0x7602, 0xa986, 0x41c3,
- 0x1118, 0x7007, 0x0001, 0x0028, 0x7004, 0xa084, 0x0010, 0xc085,
- 0x7006, 0x8b59, 0x2b60, 0x2079, 0x4700, 0x080c, 0x42c5, 0xa006,
- 0x0005, 0x2091, 0x8000, 0x2091, 0x6000, 0x78ac, 0xa005, 0x1168,
- 0x7974, 0x70d0, 0xa106, 0x1148, 0x781c, 0xa005, 0x0130, 0x781f,
- 0x0000, 0x0e04, 0x443d, 0x2091, 0x4080, 0x2069, 0x4780, 0xc7fd,
- 0x6800, 0xa084, 0x000f, 0x1198, 0x68d0, 0xd0b4, 0x0180, 0xd0bc,
- 0x1170, 0x00f6, 0x2079, 0x0100, 0xd7fc, 0x1110, 0x2079, 0x0200,
- 0x7830, 0xa084, 0x00c0, 0x1110, 0x080c, 0x22d5, 0x00fe, 0xd7fc,
- 0x0120, 0x2069, 0x4740, 0xc7fc, 0x0c18, 0x7830, 0x8001, 0x7832,
- 0x1904, 0x44c7, 0x7834, 0x7832, 0x2061, 0x6cc0, 0x2069, 0x4780,
- 0xc7fd, 0x68cc, 0xa005, 0x0128, 0x8001, 0x68ce, 0x1110, 0x080c,
- 0x4639, 0x6800, 0xa084, 0x000f, 0x0168, 0xa086, 0x0001, 0x0150,
- 0x6840, 0xa00d, 0x0138, 0x2104, 0xa005, 0x0120, 0x8001, 0x200a,
- 0x0904, 0x45d6, 0x6814, 0xa005, 0x01a8, 0x8001, 0x6816, 0x1190,
- 0x68a3, 0x0001, 0x00f6, 0xd7fc, 0x1118, 0x2079, 0x0200, 0x0010,
- 0x2079, 0x0100, 0x080c, 0x3c6e, 0x00fe, 0x6860, 0xa005, 0x0110,
- 0x080c, 0x22d5, 0x687c, 0xa005, 0x0140, 0x8001, 0x687e, 0x1128,
- 0x6863, 0x0000, 0x68d0, 0xc0c5, 0x68d2, 0x68d0, 0xd0fc, 0x01b0,
- 0xc0fc, 0x68d2, 0x20a9, 0x0200, 0x6034, 0xa005, 0x0158, 0x8001,
- 0x6036, 0x68d0, 0xc0fd, 0x68d2, 0x1128, 0x6010, 0xa005, 0x0110,
- 0x080c, 0x22d5, 0xace0, 0x0010, 0x1f04, 0x44ac, 0xd7fc, 0x0138,
- 0x2061, 0x4cc0, 0x2069, 0x4740, 0xc7fc, 0x0804, 0x4469, 0x0459,
- 0x7838, 0x8001, 0x783a, 0x11a0, 0x783c, 0x783a, 0x2061, 0x4cc0,
- 0x2069, 0x4740, 0xc7fc, 0x680c, 0xa005, 0x0110, 0x080c, 0x4543,
- 0xd7fc, 0x1130, 0x2061, 0x6cc0, 0x2069, 0x4780, 0xc7fd, 0x0c98,
- 0x7810, 0xd0cc, 0x0168, 0xd0ac, 0x1120, 0xd0a4, 0x0148, 0xc0ad,
- 0x7812, 0x2091, 0x8001, 0x0e04, 0x44ef, 0x080c, 0x20a1, 0x0005,
- 0x2091, 0x8001, 0x0005, 0x7840, 0x8001, 0x7842, 0x1904, 0x4542,
- 0x7844, 0x7842, 0x2069, 0x4740, 0xc7fc, 0x2079, 0x0200, 0x68d4,
- 0xa005, 0x0138, 0x7de0, 0xa504, 0x1120, 0x68d6, 0x68d0, 0xc0bc,
- 0x68d2, 0x2079, 0x4700, 0x6810, 0xa005, 0x1110, 0x2001, 0x0101,
- 0x8001, 0x6812, 0xd7fc, 0x0118, 0xa080, 0x8dd0, 0x0010, 0xa080,
- 0x8cc0, 0x2040, 0x2004, 0xa065, 0x01e0, 0x6024, 0xa005, 0x01b0,
- 0x8001, 0x6026, 0x1198, 0x6800, 0xa005, 0x0130, 0x6848, 0xac06,
- 0x1118, 0x080c, 0x45d6, 0x0068, 0x6860, 0xa005, 0x0118, 0x6027,
- 0x0001, 0x0020, 0x080c, 0x4584, 0x2804, 0x0c28, 0x6000, 0x2c40,
- 0x0c10, 0xd7fc, 0x1138, 0x2069, 0x4780, 0xc7fd, 0x2079, 0x0100,
- 0x0804, 0x44ff, 0x0005, 0x2009, 0x0000, 0x20a9, 0x0200, 0x6008,
- 0xd09c, 0x0558, 0x6024, 0xa005, 0x0118, 0x8001, 0x6026, 0x0418,
- 0x6008, 0xc09c, 0xd084, 0x1110, 0xd0ac, 0x01c0, 0x600a, 0x6004,
- 0xa005, 0x01d8, 0x00d6, 0x00c6, 0x0016, 0x2068, 0x6010, 0x8001,
- 0x6012, 0x080c, 0x37c7, 0x2d00, 0x2c68, 0x2060, 0x080c, 0x1c02,
- 0x080c, 0x1db2, 0x001e, 0x00ce, 0x00de, 0x0038, 0xc0bd, 0x600a,
- 0xa18d, 0x0001, 0x0010, 0xa18d, 0x0100, 0xace0, 0x0010, 0x1f04,
- 0x4547, 0xa184, 0x0001, 0x0130, 0xa18c, 0xfffe, 0x690e, 0x080c,
- 0x22d5, 0x0008, 0x690e, 0x0005, 0x2c00, 0x687a, 0x6714, 0x6f72,
- 0x6017, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x60b4, 0xa084,
- 0x5f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0060, 0x6022,
- 0x6000, 0x2042, 0x2069, 0x4780, 0xd7fc, 0x1110, 0x2069, 0x4740,
- 0x6858, 0xac06, 0x1110, 0x2800, 0x685a, 0x080c, 0x1b9a, 0x6818,
- 0xa005, 0x0110, 0x8001, 0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810,
- 0x7908, 0x8109, 0x790a, 0x8001, 0x1310, 0x080c, 0x2575, 0x6812,
- 0x1118, 0x7910, 0xc1a5, 0x7912, 0x602f, 0x0000, 0x6033, 0x0000,
- 0x2c68, 0x080c, 0x1dbf, 0xd7fc, 0x1118, 0x2069, 0x4740, 0x0010,
- 0x2069, 0x4780, 0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x1118,
- 0x6976, 0x2001, 0x0004, 0x080c, 0x22cb, 0x0005, 0x00d6, 0x6948,
- 0x2160, 0xd7fc, 0x1118, 0x2069, 0x0200, 0x0010, 0x2069, 0x0100,
- 0x080c, 0x2490, 0x601b, 0x0006, 0x6858, 0xa084, 0x5f00, 0x601e,
- 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, 0x0000,
- 0x6033, 0x0000, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4,
- 0x01b0, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110,
- 0x1f04, 0x45fd, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084,
- 0x0110, 0x1f04, 0x4606, 0x20a9, 0x00fa, 0x1f04, 0x460d, 0x681b,
- 0x0054, 0x00de, 0x6863, 0x0007, 0x0005, 0x2079, 0x4700, 0x00e1,
- 0x0089, 0x00a9, 0x2009, 0x0002, 0x2069, 0x4780, 0x680f, 0x0000,
- 0x6813, 0x0000, 0x6817, 0x0000, 0x8109, 0x0118, 0x2069, 0x4740,
- 0x0ca8, 0x0005, 0x2019, 0x00a3, 0x7b3a, 0x7b3e, 0x0005, 0x2019,
- 0x0033, 0x7b42, 0x7b46, 0x0005, 0x2019, 0x32dd, 0x7b32, 0x7b36,
- 0x0005, 0x6a4c, 0xa285, 0x0000, 0x01f0, 0x6950, 0x6bbc, 0xa300,
- 0x00c6, 0x2164, 0x6304, 0x83ff, 0x1138, 0x8211, 0x0148, 0x8108,
- 0xa11a, 0x0eb8, 0x69bc, 0x0ca8, 0x68cf, 0x000a, 0x00ce, 0x0005,
- 0x694c, 0x6abc, 0x2264, 0x6008, 0xc0b5, 0x600a, 0x8210, 0x8109,
- 0x1dc8, 0x694e, 0x00ce, 0x0005, 0x0016, 0x1d04, 0x465d, 0x2091,
- 0x6000, 0x1d04, 0x4661, 0x2091, 0x6000, 0x70ec, 0xd0dc, 0x1118,
- 0xd0d4, 0x0190, 0x00a0, 0xae8e, 0x0100, 0x0138, 0x7814, 0xc0f5,
- 0xc0c5, 0x7816, 0xd0d4, 0x1580, 0x0460, 0x7814, 0xc0fd, 0xc0c5,
- 0x7816, 0xd0d4, 0x1548, 0x0428, 0xd0e4, 0x0904, 0x46c4, 0x1d04,
- 0x467f, 0x2091, 0x6000, 0x2009, 0x000c, 0x1d04, 0x4685, 0x2091,
- 0x6000, 0x8109, 0x1dd0, 0x70e4, 0xa084, 0x01ff, 0xa086, 0x01ff,
- 0x1110, 0x70ec, 0x08c0, 0xae8e, 0x0100, 0x0128, 0x7814, 0xc0f4,
- 0xd0fc, 0x1130, 0x0020, 0x7814, 0xc0fc, 0xd0f4, 0x1108, 0xc0c4,
- 0x7816, 0x7804, 0xd08c, 0x0500, 0x00c6, 0x2061, 0x0000, 0x6018,
- 0xd084, 0x11b8, 0xae86, 0x0200, 0x00e6, 0x2071, 0x0010, 0x0120,
- 0x70db, 0x0001, 0x78e4, 0x0018, 0x70db, 0x0000, 0x78e0, 0x70c6,
- 0x70c3, 0x800e, 0x601b, 0x0001, 0x2091, 0x4080, 0x00ee, 0x00ce,
- 0x0018, 0x00ce, 0x681f, 0x000c, 0x001e, 0x70a0, 0x70a2, 0x0005,
- 0x0c26
-};
-#ifdef UNIQUE_FW_NAME
-static unsigned short fw12160i_length01 = 0x36c9;
-#else
-static unsigned short risc_code_length01 = 0x36c9;
-#endif
-
diff --git a/drivers/scsi/ql1280_fw.h b/drivers/scsi/ql1280_fw.h
deleted file mode 100644
index 784f2a04bf2..00000000000
--- a/drivers/scsi/ql1280_fw.h
+++ /dev/null
@@ -1,2048 +0,0 @@
-/*****************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP1280/ device driver for Linux 2.2.x and 2.4.x
- * Copyright (C) 2001 Qlogic Corporation (www.qlogic.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, 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.
- *
- *****************************************************************************/
-
-/************************************************************************
- * --- ISP1240/1080/1280 Initiator Firmware --- *
- * 32 LUN Support *
- ************************************************************************/
-
-
-/*
- * Firmware Version 8.15.11 (10:20 Jan 02, 2002)
- */
-
-#ifdef UNIQUE_FW_NAME
-static unsigned char fw1280ei_version_str[] = {8,15,11};
-#else
-static unsigned char firmware_version[] = {8,15,11};
-#endif
-
-#ifdef UNIQUE_FW_NAME
-#define fw1280ei_VERSION_STRING "8.15.11"
-#else
-#define FW_VERSION_STRING "8.15.11"
-#endif
-
-#ifdef UNIQUE_FW_NAME
-static unsigned short fw1280ei_addr01 = 0x1000 ;
-#else
-static unsigned short risc_code_addr01 = 0x1000 ;
-#endif
-
-#ifdef UNIQUE_FW_NAME
-static unsigned short fw1280ei_code01[] = {
-#else
-static unsigned short risc_code01[] = {
-#endif
- 0x0078, 0x1041, 0x0000, 0x3e2e, 0x0000, 0x2043, 0x4f50, 0x5952,
- 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
- 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320,
- 0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350,
- 0x3132, 0x3430, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056,
- 0x6572, 0x7369, 0x6f6e, 0x2030, 0x382e, 0x3135, 0x2020, 0x2043,
- 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050,
- 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020,
- 0x2400, 0x20c9, 0x98ff, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1080,
- 0x00c0, 0x1054, 0x2071, 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010,
- 0x2089, 0x1374, 0x0078, 0x106d, 0x2001, 0x04fc, 0x2004, 0xa086,
- 0x1280, 0x00c0, 0x1069, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2071,
- 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, 0x2089, 0x13f8, 0x0078,
- 0x106d, 0x20c1, 0x0020, 0x2089, 0x131c, 0x2071, 0x0010, 0x70c3,
- 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3,
- 0x0008, 0x2001, 0x04fe, 0x70d6, 0x20c1, 0x0021, 0x2019, 0x0000,
- 0x2009, 0xfeff, 0x2100, 0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64,
- 0x206b, 0x0a0a, 0xaddc, 0x3fff, 0x2b54, 0x205b, 0x5050, 0x2114,
- 0xa286, 0xa5a5, 0x0040, 0x10a4, 0xa386, 0x000f, 0x0040, 0x10a0,
- 0x2c6a, 0x2a5a, 0x20c1, 0x0020, 0x2019, 0x000f, 0x0078, 0x1080,
- 0x2c6a, 0x2a5a, 0x0078, 0x10a2, 0x2c6a, 0x2a5a, 0x2130, 0x2128,
- 0xa1a2, 0x4f00, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
- 0xa192, 0x9900, 0x2009, 0x0000, 0x2001, 0x0032, 0x1078, 0x20c1,
- 0x2218, 0x2079, 0x4f00, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
- 0x0040, 0x42a4, 0x8109, 0x00c0, 0x10bf, 0x2009, 0xff00, 0x3400,
- 0xa102, 0x0048, 0x10cf, 0x0040, 0x10cf, 0x20a8, 0x42a4, 0x2001,
- 0x04fc, 0x2004, 0xa086, 0x1080, 0x00c0, 0x10e5, 0x2071, 0x0100,
- 0x0d7e, 0x2069, 0x4f40, 0x1078, 0x4db0, 0x0d7f, 0x7810, 0xc0ed,
- 0x7812, 0x781b, 0x0064, 0x0078, 0x110a, 0x2001, 0x04fc, 0x2004,
- 0xa086, 0x1280, 0x00c0, 0x1105, 0x7814, 0xc0ed, 0xc0d5, 0x7816,
- 0x781b, 0x0064, 0x2071, 0x0200, 0x0d7e, 0x2069, 0x4f40, 0x1078,
- 0x4db0, 0x2069, 0x4f80, 0x2071, 0x0100, 0x1078, 0x4db0, 0x7814,
- 0xc0d4, 0x7816, 0x0d7f, 0x0078, 0x110a, 0x7814, 0xc0e5, 0x7816,
- 0x781b, 0x003c, 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800,
- 0xc08d, 0x7802, 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002,
- 0x7827, 0x0002, 0x2009, 0x0002, 0x2069, 0x4f40, 0x681b, 0x0003,
- 0x6823, 0x0007, 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028,
- 0x6837, 0x0000, 0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000,
- 0x8109, 0x0040, 0x115e, 0x68d3, 0x000a, 0x68c3, 0x4fc0, 0x2079,
- 0x4f00, 0x7814, 0xd0e4, 0x00c0, 0x1144, 0xd0ec, 0x00c0, 0x1148,
- 0x68d7, 0x7329, 0x0078, 0x114a, 0x68d7, 0x730d, 0x0078, 0x114a,
- 0x68d7, 0x732d, 0x68c7, 0x54c0, 0x68cb, 0x53c0, 0x68cf, 0x94c0,
- 0x68ab, 0x9744, 0x68af, 0x9749, 0x68b3, 0x9744, 0x68b7, 0x9744,
- 0x68a7, 0x0001, 0x2069, 0x4f80, 0x0078, 0x111e, 0x68d3, 0x000a,
- 0x68c3, 0x51c0, 0x7814, 0xd0e4, 0x00c0, 0x116a, 0x68d7, 0x7439,
- 0x0078, 0x116c, 0x68d7, 0x7419, 0x68c7, 0x74c0, 0x68cb, 0x5440,
- 0x68cf, 0x95d0, 0x68ab, 0x9749, 0x68af, 0x974e, 0x68b3, 0x9749,
- 0x68b7, 0x9749, 0x68a7, 0x0001, 0x7810, 0xd0ec, 0x00c0, 0x11c2,
- 0x7814, 0xd0e4, 0x00c0, 0x11b4, 0x0e7e, 0x2069, 0x53c0, 0x2071,
- 0x0200, 0x70ec, 0xd0e4, 0x00c0, 0x1195, 0x2019, 0x0c0c, 0x2021,
- 0x000c, 0x1078, 0x2050, 0x0078, 0x119b, 0x2019, 0x0c0a, 0x2021,
- 0x000a, 0x1078, 0x2050, 0x2069, 0x5440, 0x2071, 0x0100, 0x70ec,
- 0xd0e4, 0x00c0, 0x11ab, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078,
- 0x2050, 0x0078, 0x11b1, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078,
- 0x2050, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0c, 0x2021, 0x000c,
- 0x2069, 0x53c0, 0x1078, 0x2050, 0x2069, 0x5440, 0x1078, 0x2050,
- 0x0078, 0x11db, 0x2069, 0x53c0, 0x0e7e, 0x2071, 0x0100, 0x70ec,
- 0xd0e4, 0x00c0, 0x11d4, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078,
- 0x2050, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0a, 0x2021, 0x000a,
- 0x1078, 0x2050, 0x0e7f, 0x2011, 0x0002, 0x2069, 0x54c0, 0x2009,
- 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bc8,
- 0xa386, 0xfeff, 0x00c0, 0x11f2, 0x6817, 0x0100, 0x681f, 0x0064,
- 0x0078, 0x11f6, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010,
- 0x00f0, 0x11e3, 0x8109, 0x00c0, 0x11e1, 0x8211, 0x0040, 0x1204,
- 0x2069, 0x74c0, 0x0078, 0x11df, 0x1078, 0x26a2, 0x1078, 0x4712,
- 0x1078, 0x1e1b, 0x1078, 0x4d42, 0x2091, 0x2100, 0x2079, 0x4f00,
- 0x7810, 0xd0ec, 0x0040, 0x1218, 0x2071, 0x0020, 0x0078, 0x121a,
- 0x2071, 0x0050, 0x2091, 0x2200, 0x2079, 0x4f00, 0x2071, 0x0020,
- 0x2091, 0x2300, 0x2079, 0x4f00, 0x7810, 0xd0ec, 0x0040, 0x122c,
- 0x2079, 0x0100, 0x0078, 0x122e, 0x2079, 0x0200, 0x2071, 0x4f40,
- 0x2091, 0x2400, 0x2079, 0x0100, 0x2071, 0x4f80, 0x2091, 0x2000,
- 0x2079, 0x4f00, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090,
- 0x2071, 0x0010, 0x70c3, 0x0000, 0x0090, 0x124d, 0x70c0, 0xa086,
- 0x0002, 0x00c0, 0x124d, 0x1078, 0x15c1, 0x2039, 0x0000, 0x7810,
- 0xd0ec, 0x00c0, 0x12cf, 0x1078, 0x148e, 0x78ac, 0xa005, 0x00c0,
- 0x126b, 0x0068, 0x1261, 0x786c, 0xa065, 0x0040, 0x1261, 0x1078,
- 0x23dc, 0x1078, 0x20e8, 0x0068, 0x1278, 0x786c, 0xa065, 0x0040,
- 0x126b, 0x1078, 0x23dc, 0x0068, 0x1278, 0x2009, 0x4f47, 0x2011,
- 0x4f87, 0x2104, 0x220c, 0xa105, 0x0040, 0x1278, 0x1078, 0x1f51,
- 0x2071, 0x4f40, 0x70a4, 0xa005, 0x0040, 0x129d, 0x7450, 0xa485,
- 0x0000, 0x0040, 0x129d, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4,
- 0xa28c, 0x303d, 0x2190, 0x1078, 0x2bb1, 0x2091, 0x8000, 0x2091,
- 0x303d, 0x0068, 0x129d, 0x2079, 0x4f00, 0x786c, 0xa065, 0x0040,
- 0x129d, 0x2071, 0x0010, 0x1078, 0x23dc, 0x00e0, 0x12a5, 0x2079,
- 0x4f00, 0x2071, 0x0010, 0x1078, 0x4b16, 0x2071, 0x4f80, 0x70a4,
- 0xa005, 0x0040, 0x12bd, 0x7050, 0xa025, 0x0040, 0x12bd, 0x2079,
- 0x0100, 0x2091, 0x8000, 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078,
- 0x2bb1, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079, 0x4f00, 0x2071,
- 0x0010, 0x0068, 0x12c9, 0x786c, 0xa065, 0x0040, 0x12c9, 0x1078,
- 0x23dc, 0x00e0, 0x1253, 0x1078, 0x4b16, 0x0078, 0x1253, 0x1078,
- 0x148e, 0x78ac, 0xa005, 0x00c0, 0x12e7, 0x0068, 0x12dd, 0x786c,
- 0xa065, 0x0040, 0x12dd, 0x1078, 0x23dc, 0x1078, 0x20e8, 0x0068,
- 0x12f1, 0x786c, 0xa065, 0x0040, 0x12e7, 0x1078, 0x23dc, 0x0068,
- 0x12f1, 0x2009, 0x4f47, 0x2104, 0xa005, 0x0040, 0x12f1, 0x1078,
- 0x1f51, 0x2071, 0x4f40, 0x70a4, 0xa005, 0x0040, 0x130c, 0x7450,
- 0xa485, 0x0000, 0x0040, 0x130c, 0x2079, 0x0100, 0x2091, 0x8000,
- 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, 0x2bb1, 0x2091, 0x8000,
- 0x2091, 0x303d, 0x2079, 0x4f00, 0x2071, 0x0010, 0x0068, 0x1316,
- 0x786c, 0xa065, 0x0040, 0x1316, 0x1078, 0x23dc, 0x00e0, 0x12cf,
- 0x1078, 0x4b16, 0x0078, 0x12cf, 0x133c, 0x133c, 0x133e, 0x133e,
- 0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363,
- 0x134b, 0x134b, 0x134b, 0x134b, 0x133c, 0x133c, 0x133e, 0x133e,
- 0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363,
- 0x134b, 0x134b, 0x134b, 0x134b, 0x0078, 0x133c, 0x007e, 0x107e,
- 0x127e, 0x2091, 0x2400, 0x1078, 0x29d1, 0x127f, 0x107f, 0x007f,
- 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13c8,
- 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e,
- 0x127e, 0x2091, 0x2300, 0x1078, 0x29d1, 0x127f, 0x107f, 0x007f,
- 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300,
- 0x1078, 0x29d1, 0x2091, 0x2400, 0x1078, 0x29d1, 0x127f, 0x107f,
- 0x007f, 0x2091, 0x8001, 0x007c, 0x1394, 0x1394, 0x1396, 0x1396,
- 0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13ae, 0x13ae, 0x1396, 0x1396,
- 0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13af, 0x13af, 0x13af, 0x13af,
- 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af,
- 0x13af, 0x13af, 0x13af, 0x13af, 0x0078, 0x1394, 0x007e, 0x107e,
- 0x127e, 0x2091, 0x2300, 0x1078, 0x29d1, 0x127f, 0x107f, 0x007f,
- 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13d5,
- 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007c, 0x107e,
- 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x007e, 0x2071, 0x0100, 0x2069,
- 0x4f40, 0x2079, 0x4f00, 0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078,
- 0x4db0, 0x007f, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, 0x107f, 0x007c,
- 0x3c00, 0xa084, 0x0007, 0x0079, 0x13cd, 0x13de, 0x13de, 0x13e0,
- 0x13e0, 0x13e5, 0x13e5, 0x13ea, 0x13ea, 0x3c00, 0xa084, 0x0003,
- 0x0079, 0x13da, 0x13de, 0x13de, 0x13f3, 0x13f3, 0x1078, 0x29b2,
- 0x2091, 0x2200, 0x1078, 0x47ec, 0x007c, 0x2091, 0x2100, 0x1078,
- 0x47ec, 0x007c, 0x2091, 0x2100, 0x1078, 0x47ec, 0x2091, 0x2200,
- 0x1078, 0x47ec, 0x007c, 0x2091, 0x2100, 0x1078, 0x47ec, 0x007c,
- 0x1418, 0x1418, 0x141a, 0x141a, 0x1427, 0x1427, 0x1427, 0x1427,
- 0x1432, 0x1432, 0x143f, 0x143f, 0x1427, 0x1427, 0x1427, 0x1427,
- 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450,
- 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450,
- 0x0078, 0x1418, 0x007e, 0x107e, 0x127e, 0x2091, 0x2400, 0x1078,
- 0x29d1, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e,
- 0x107e, 0x127e, 0x1078, 0x13c8, 0x127f, 0x107f, 0x007f, 0x2091,
- 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078,
- 0x29d1, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e,
- 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x29d1, 0x2091, 0x2400,
- 0x1078, 0x29d1, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c,
- 0x007e, 0x107e, 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2079, 0x4f00,
- 0x2071, 0x0200, 0x2069, 0x4f40, 0x3d00, 0xd08c, 0x0040, 0x1466,
- 0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078, 0x4db0, 0x3d00, 0xd084,
- 0x0040, 0x1474, 0x2069, 0x4f80, 0x2071, 0x0100, 0x70ec, 0xa084,
- 0x1c00, 0x78e6, 0x1078, 0x4db0, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f,
- 0x107f, 0x007f, 0x007c, 0x7008, 0x800b, 0x00c8, 0x1489, 0x7007,
- 0x0002, 0xa08c, 0x01e0, 0x00c0, 0x148a, 0xd09c, 0x0040, 0x1489,
- 0x087a, 0x097a, 0x70c3, 0x4002, 0x0078, 0x15c4, 0x0068, 0x151a,
- 0x2061, 0x0000, 0x6018, 0xd084, 0x00c0, 0x151a, 0x7828, 0xa005,
- 0x00c0, 0x149e, 0x0010, 0x151b, 0x0078, 0x151a, 0x7910, 0xd1f4,
- 0x0040, 0x14a4, 0x0078, 0x14b9, 0x7914, 0xd1ec, 0x0040, 0x14bd,
- 0xd0fc, 0x0040, 0x14b3, 0x007e, 0x1078, 0x1dae, 0x007f, 0x0040,
- 0x14bd, 0x0078, 0x14b9, 0x007e, 0x1078, 0x1da1, 0x007f, 0x0040,
- 0x14bd, 0x2001, 0x4007, 0x0078, 0x15c3, 0x7910, 0xd0fc, 0x00c0,
- 0x14c7, 0x2061, 0x4f40, 0xc19c, 0xc7fc, 0x0078, 0x14cb, 0x2061,
- 0x4f80, 0xc19d, 0xc7fd, 0x6064, 0xa005, 0x00c0, 0x151a, 0x7912,
- 0x6082, 0x7828, 0xc0fc, 0xa086, 0x0018, 0x00c0, 0x14db, 0x0c7e,
- 0x1078, 0x1b85, 0x0c7f, 0x782b, 0x0000, 0x607c, 0xa065, 0x0040,
- 0x1500, 0x0c7e, 0x609c, 0x1078, 0x1e90, 0x0c7f, 0x609f, 0x0000,
- 0x1078, 0x1cd5, 0x2009, 0x0018, 0x6087, 0x0103, 0x7810, 0x007e,
- 0x84ff, 0x00c0, 0x14f6, 0x85ff, 0x0040, 0x14f8, 0xc0c5, 0x7812,
- 0x1078, 0x1dbb, 0x007f, 0x7812, 0x00c0, 0x1514, 0x1078, 0x1e0d,
- 0x7810, 0xd09c, 0x00c0, 0x1508, 0x2061, 0x4f40, 0x0078, 0x150c,
- 0x2061, 0x4f80, 0xc09c, 0x7812, 0x607f, 0x0000, 0x60d4, 0xd0dc,
- 0x0040, 0x1518, 0xc0dc, 0x60d6, 0x2001, 0x4005, 0x0078, 0x15c3,
- 0x0078, 0x15c1, 0x007c, 0x7810, 0xd0f4, 0x0040, 0x1523, 0x2001,
- 0x4007, 0x0078, 0x15c3, 0xa006, 0x70c2, 0x70c6, 0x70ca, 0x70ce,
- 0x70da, 0x70c0, 0xa03d, 0xa08a, 0x0040, 0x00c8, 0x1531, 0x0079,
- 0x1538, 0x2100, 0xa08a, 0x0040, 0x00c8, 0x15cf, 0x0079, 0x1578,
- 0x15c1, 0x1617, 0x15e0, 0x164f, 0x1687, 0x1687, 0x15d7, 0x1ced,
- 0x1692, 0x15cf, 0x15e4, 0x15e6, 0x15e8, 0x15ea, 0x1cf2, 0x15cf,
- 0x16a0, 0x16fd, 0x1ba5, 0x1ce7, 0x15ec, 0x19ea, 0x1a2c, 0x1a67,
- 0x1ab8, 0x19a5, 0x19b2, 0x19c6, 0x19d9, 0x17eb, 0x15cf, 0x1734,
- 0x1741, 0x174d, 0x1759, 0x176f, 0x177b, 0x177e, 0x178a, 0x1796,
- 0x179e, 0x17d3, 0x17df, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x17f8,
- 0x180a, 0x1826, 0x185c, 0x1884, 0x1894, 0x1897, 0x18c8, 0x18f9,
- 0x190b, 0x1974, 0x1984, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x1994,
- 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x1d17, 0x1d1d, 0x15cf,
- 0x15cf, 0x15cf, 0x1d21, 0x1d66, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
- 0x1611, 0x1681, 0x169a, 0x16f7, 0x1b9f, 0x15cf, 0x15cf, 0x1b68,
- 0x15cf, 0x1d6a, 0x1d09, 0x1d13, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
- 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
- 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
- 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
- 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
- 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078, 0x15c3, 0x73ce, 0x72ca,
- 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068, 0x15c4, 0x2061, 0x0000,
- 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x007c, 0x70c3,
- 0x4001, 0x0078, 0x15c4, 0x70c3, 0x4006, 0x0078, 0x15c4, 0x2099,
- 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078, 0x15c1,
- 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x15c1, 0x0078, 0x15c1,
- 0x0078, 0x15c1, 0x0078, 0x15c1, 0x2091, 0x8000, 0x70c3, 0x0004,
- 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x0008,
- 0x2001, 0x000f, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001, 0x2031,
- 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051, 0x0445, 0x2061,
- 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091, 0x4080, 0x0078,
- 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x161a, 0x2029,
- 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0, 0x2099,
- 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, 0x721e, 0x7422,
- 0x7526, 0x2021, 0x0040, 0x81ff, 0x0040, 0x15c1, 0xa182, 0x0040,
- 0x00c8, 0x1634, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x7007,
- 0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0040, 0x163b, 0x7007,
- 0x0002, 0xa084, 0x01e0, 0x0040, 0x1649, 0x70c3, 0x4002, 0x0078,
- 0x15c4, 0x24a8, 0x53a5, 0x0078, 0x162b, 0x0078, 0x15c1, 0x2029,
- 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x2098, 0x20a1,
- 0x0030, 0x7003, 0x0000, 0x7007, 0x0006, 0x731a, 0x721e, 0x7422,
- 0x7526, 0x2021, 0x0040, 0x7007, 0x0006, 0x81ff, 0x0040, 0x15c1,
- 0xa182, 0x0040, 0x00c8, 0x166e, 0x2120, 0xa006, 0x2008, 0x8403,
- 0x7012, 0x24a8, 0x53a6, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0040,
- 0x1675, 0xa084, 0x01e0, 0x0040, 0x1663, 0x70c3, 0x4002, 0x0078,
- 0x15c4, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1652, 0x71c4,
- 0x70c8, 0x2114, 0xa79e, 0x0004, 0x00c0, 0x168f, 0x200a, 0x72ca,
- 0x0078, 0x15c0, 0x70c7, 0x0008, 0x70cb, 0x000f, 0x70cf, 0x000b,
- 0x0078, 0x15c1, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x16a3,
- 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6,
- 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x16f2, 0xa40a, 0x0040,
- 0x16b3, 0x00c8, 0x16bc, 0x8001, 0x7872, 0xa084, 0xfc00, 0x0040,
- 0x16c0, 0x78ac, 0xc085, 0x78ae, 0x2001, 0x4005, 0x0078, 0x15c3,
- 0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76, 0xa48c, 0xff00, 0x0040,
- 0x16d8, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f, 0xa118,
- 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x0078, 0x16e2,
- 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1, 0x0000,
- 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605, 0x0040,
- 0x16ec, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, 0x78ae,
- 0x0078, 0x16f5, 0x78ac, 0xc085, 0x78ae, 0x0078, 0x15c1, 0x75d8,
- 0x76dc, 0x75da, 0x76de, 0x0078, 0x1700, 0x2029, 0x0000, 0x2530,
- 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6,
- 0xa005, 0x0040, 0x172f, 0xa40a, 0x0040, 0x1710, 0x00c8, 0x1719,
- 0x8001, 0x7892, 0xa084, 0xfc00, 0x0040, 0x171d, 0x78ac, 0xc0c5,
- 0x78ae, 0x2001, 0x4005, 0x0078, 0x15c3, 0x7a9a, 0x7b9e, 0x7da2,
- 0x7ea6, 0x2600, 0xa505, 0x0040, 0x1728, 0x7a10, 0xc2c5, 0x7a12,
- 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0078, 0x1732, 0x78ac,
- 0xc0c5, 0x78ae, 0x0078, 0x15c1, 0x2009, 0x0000, 0x786c, 0xa065,
- 0x0040, 0x173e, 0x8108, 0x6000, 0x0078, 0x1737, 0x7ac4, 0x0078,
- 0x15bf, 0x2009, 0x4f48, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15c0,
- 0x2011, 0x4f88, 0x2214, 0x0078, 0x15bf, 0x2009, 0x4f49, 0x210c,
- 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2011, 0x4f89, 0x2214, 0x0078,
- 0x15bf, 0x2061, 0x4f40, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214,
- 0x7810, 0xd0ec, 0x00c0, 0x176d, 0x2061, 0x4f80, 0x6328, 0x73da,
- 0x632c, 0x831c, 0x831c, 0x831c, 0x73de, 0x0078, 0x15bf, 0x2009,
- 0x4f4c, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2011, 0x4f8c,
- 0x2214, 0x0078, 0x15bf, 0x7918, 0x0078, 0x15c0, 0x2009, 0x4f4d,
- 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2011, 0x4f8d, 0x2214,
- 0x0078, 0x15bf, 0x2009, 0x4f4e, 0x210c, 0x7810, 0xd0ec, 0x00c0,
- 0x15c0, 0x2011, 0x4f8e, 0x2214, 0x0078, 0x15bf, 0x7920, 0x7810,
- 0xd0ec, 0x00c0, 0x15c0, 0x7a24, 0x0078, 0x15bf, 0x71c4, 0xd1fc,
- 0x00c0, 0x17a6, 0x2011, 0x53c0, 0x0078, 0x17a8, 0x2011, 0x5440,
- 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x6a00,
- 0x6804, 0xd09c, 0x0040, 0x17b7, 0x6b08, 0x0078, 0x17b8, 0x6b0c,
- 0xd1fc, 0x00c0, 0x17bf, 0x2021, 0x023b, 0x0078, 0x17c1, 0x2021,
- 0x013b, 0x2424, 0x7914, 0xd1e4, 0x0040, 0x17cd, 0xd4c4, 0x00c0,
- 0x17cc, 0xc4d5, 0x0078, 0x17cd, 0xc4dd, 0xa4a4, 0x1c00, 0x74de,
- 0x71c4, 0x0078, 0x15be, 0x77c4, 0x1078, 0x1e2b, 0x2091, 0x8000,
- 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x15be, 0x2061,
- 0x4f40, 0x6118, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2061, 0x4f80,
- 0x6218, 0x0078, 0x15bf, 0x77c4, 0x1078, 0x1e2b, 0x2091, 0x8000,
- 0x6908, 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0078, 0x15be,
- 0x71c4, 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x00c8, 0x15b9,
- 0x1078, 0x27c6, 0xa384, 0x4000, 0x0040, 0x1808, 0xa295, 0x0020,
- 0x0078, 0x15be, 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, 0x00c8,
- 0x15b9, 0xd1bc, 0x00c0, 0x1819, 0x2011, 0x4f48, 0x2204, 0x0078,
- 0x181d, 0x2011, 0x4f88, 0x2204, 0xc0bd, 0x007e, 0x2100, 0xc0bc,
- 0x2012, 0x1078, 0x2723, 0x017f, 0x0078, 0x15c0, 0x71c4, 0x2021,
- 0x4f49, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0078, 0x1835, 0x71c8,
- 0x2021, 0x4f89, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1854, 0x20a9,
- 0x0008, 0x2204, 0xa106, 0x0040, 0x1844, 0x8210, 0x00f0, 0x1839,
- 0x71c4, 0x72c8, 0x0078, 0x15b8, 0xa292, 0x1854, 0x027e, 0x2122,
- 0x017f, 0x1078, 0x2744, 0x7810, 0xd0ec, 0x00c0, 0x1852, 0xd3fc,
- 0x0040, 0x182f, 0x0078, 0x15c1, 0x03e8, 0x00fa, 0x01f4, 0x02ee,
- 0x0004, 0x0001, 0x0002, 0x0003, 0x2061, 0x4f40, 0x6128, 0x622c,
- 0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003,
- 0x8003, 0x602e, 0x7810, 0xd0ec, 0x00c0, 0x1882, 0x027e, 0x017e,
- 0x2061, 0x4f80, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70d8,
- 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, 0x72de,
- 0x017f, 0x027f, 0x0078, 0x15bf, 0x2061, 0x4f40, 0x6130, 0x70c4,
- 0x6032, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2061, 0x4f80, 0x6230,
- 0x70c8, 0x6032, 0x0078, 0x15bf, 0x7918, 0x0078, 0x15c0, 0x71c4,
- 0xa184, 0xffcf, 0x0040, 0x18a3, 0x7810, 0xd0ec, 0x00c0, 0x15b9,
- 0x72c8, 0x0078, 0x15b8, 0x2011, 0x4f4d, 0x2204, 0x2112, 0x007e,
- 0x2019, 0x0000, 0x1078, 0x27ab, 0x7810, 0xd0ec, 0x0040, 0x18b3,
- 0x017f, 0x0078, 0x15c0, 0x71c8, 0xa184, 0xffcf, 0x0040, 0x18bc,
- 0x2110, 0x71c4, 0x0078, 0x15b8, 0x2011, 0x4f8d, 0x2204, 0x2112,
- 0x007e, 0xc3fd, 0x1078, 0x27ab, 0x027f, 0x017f, 0x0078, 0x15bf,
- 0x71c4, 0xa182, 0x0010, 0x0048, 0x18d4, 0x7810, 0xd0ec, 0x00c0,
- 0x15b9, 0x72c8, 0x0078, 0x15b8, 0x2011, 0x4f4e, 0x2204, 0x007e,
- 0x2112, 0x2019, 0x0000, 0x1078, 0x2789, 0x7810, 0xd0ec, 0x0040,
- 0x18e4, 0x017f, 0x0078, 0x15c0, 0x71c8, 0xa182, 0x0010, 0x0048,
- 0x18ed, 0x2110, 0x71c4, 0x0078, 0x15b8, 0x2011, 0x4f8e, 0x2204,
- 0x007e, 0x2112, 0xc3fd, 0x1078, 0x2789, 0x027f, 0x017f, 0x0078,
- 0x15bf, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x15b8, 0xa284,
- 0xfffd, 0x00c0, 0x15b8, 0x2100, 0x7920, 0x7822, 0x2200, 0x7a24,
- 0x7826, 0x0078, 0x15bf, 0x71c4, 0xd1fc, 0x00c0, 0x1913, 0x2011,
- 0x53c0, 0x0078, 0x1915, 0x2011, 0x5440, 0x8107, 0xa084, 0x000f,
- 0x8003, 0x8003, 0x8003, 0xa268, 0x2019, 0x0000, 0x72c8, 0xd2bc,
- 0x0040, 0x1924, 0xa39d, 0x0010, 0xd2b4, 0x0040, 0x1929, 0xa39d,
- 0x0008, 0x2091, 0x8000, 0x6800, 0x007e, 0xa226, 0x0040, 0x1948,
- 0x6a02, 0xd4ec, 0x0040, 0x1935, 0xc3a5, 0xd4e4, 0x0040, 0x1939,
- 0xc39d, 0xd4f4, 0x0040, 0x1948, 0x810f, 0xd2f4, 0x0040, 0x1944,
- 0x1078, 0x2808, 0x0078, 0x1948, 0x1078, 0x27e6, 0x0078, 0x1948,
- 0x72cc, 0x6808, 0xa206, 0x0040, 0x196a, 0xa2a4, 0x00ff, 0x7814,
- 0xd0e4, 0x00c0, 0x195b, 0xa482, 0x0028, 0x0048, 0x1967, 0x0040,
- 0x1967, 0x0078, 0x195f, 0xa482, 0x0043, 0x0048, 0x1967, 0x71c4,
- 0x71c6, 0x027f, 0x72ca, 0x2091, 0x8001, 0x0078, 0x15ba, 0x6a0a,
- 0xa39d, 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4,
- 0x2091, 0x8001, 0x0078, 0x15be, 0x77c4, 0x1078, 0x1e2b, 0x2091,
- 0x8000, 0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc,
- 0x681e, 0x2708, 0x0078, 0x15be, 0x70c4, 0x2061, 0x4f40, 0x6118,
- 0x601a, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x70c8, 0x2061, 0x4f80,
- 0x6218, 0x601a, 0x0078, 0x15bf, 0x71c4, 0x72c8, 0x73cc, 0xa182,
- 0x0010, 0x00c8, 0x15b9, 0x1078, 0x282a, 0xa384, 0x4000, 0x0040,
- 0x19a3, 0xa295, 0x0020, 0x0078, 0x15be, 0x77c4, 0x1078, 0x1e2b,
- 0x2091, 0x8000, 0x6a08, 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708,
- 0x0078, 0x15bf, 0x77c4, 0x1078, 0x1e2b, 0x2091, 0x8000, 0x6a08,
- 0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x19c1, 0x1078,
- 0x266f, 0x2091, 0x8001, 0x2708, 0x0078, 0x15bf, 0x77c4, 0x1078,
- 0x1e2b, 0x2091, 0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005,
- 0x0040, 0x19d4, 0x1078, 0x266f, 0x2091, 0x8001, 0x2708, 0x0078,
- 0x15bf, 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020,
- 0x2091, 0x8000, 0x1078, 0x1e46, 0x2091, 0x8001, 0x2708, 0x6a08,
- 0x0078, 0x15bf, 0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x19fe, 0xd7fc,
- 0x0040, 0x19f8, 0x1078, 0x1dae, 0x0040, 0x19fe, 0x0078, 0x15c3,
- 0x1078, 0x1da1, 0x0040, 0x19fe, 0x0078, 0x15c3, 0x73c8, 0x72cc,
- 0x77c6, 0x73ca, 0x72ce, 0x1078, 0x1ecd, 0x00c0, 0x1a28, 0x6818,
- 0xa005, 0x0040, 0x1a22, 0x2708, 0x077e, 0x1078, 0x285a, 0x077f,
- 0x00c0, 0x1a22, 0x2001, 0x0015, 0xd7fc, 0x00c0, 0x1a1b, 0x2061,
- 0x4f40, 0x0078, 0x1a1e, 0xc0fd, 0x2061, 0x4f80, 0x782a, 0x2091,
- 0x8001, 0x007c, 0x2091, 0x8001, 0x2001, 0x4005, 0x0078, 0x15c3,
- 0x2091, 0x8001, 0x0078, 0x15c1, 0x77c4, 0x7814, 0xd0e4, 0x00c0,
- 0x1a40, 0xd7fc, 0x0040, 0x1a3a, 0x1078, 0x1dae, 0x0040, 0x1a40,
- 0x0078, 0x15c3, 0x1078, 0x1da1, 0x0040, 0x1a40, 0x0078, 0x15c3,
- 0x77c6, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091,
- 0x8000, 0x1078, 0x1e46, 0x2009, 0x0016, 0xd7fc, 0x00c0, 0x1a54,
- 0x2061, 0x4f40, 0x0078, 0x1a57, 0x2061, 0x4f80, 0xc1fd, 0x6067,
- 0x0003, 0x607f, 0x0000, 0x6776, 0x6083, 0x000f, 0x792a, 0x61d4,
- 0xc1dc, 0x61d6, 0x1078, 0x266f, 0x2091, 0x8001, 0x007c, 0x77c8,
- 0x77ca, 0x77c4, 0x77c6, 0x7814, 0xd0e4, 0x00c0, 0x1a7e, 0xd7fc,
- 0x0040, 0x1a78, 0x1078, 0x1dae, 0x0040, 0x1a7e, 0x0078, 0x15c3,
- 0x1078, 0x1da1, 0x0040, 0x1a7e, 0x0078, 0x15c3, 0xa7bc, 0xff00,
- 0x2091, 0x8000, 0x2009, 0x0017, 0xd7fc, 0x00c0, 0x1a8b, 0x2061,
- 0x4f40, 0x0078, 0x1a8e, 0x2061, 0x4f80, 0xc1fd, 0x607f, 0x0000,
- 0x6067, 0x0002, 0x6776, 0x6083, 0x000f, 0x792a, 0x61d4, 0xc1dc,
- 0x61d6, 0x1078, 0x266f, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049,
- 0x0005, 0x2051, 0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0040,
- 0x1aac, 0x60d4, 0xc0fd, 0x60d6, 0x1078, 0x1e46, 0x70c8, 0x6836,
- 0x8738, 0xa784, 0x001f, 0x00c0, 0x1aac, 0x2091, 0x8001, 0x007c,
- 0x2019, 0x0000, 0x7814, 0xd0e4, 0x00c0, 0x1ace, 0x72c8, 0xd284,
- 0x0040, 0x1ac8, 0x1078, 0x1dae, 0x0040, 0x1ace, 0x0078, 0x15c3,
- 0x1078, 0x1da1, 0x0040, 0x1ace, 0x0078, 0x15c3, 0x72c8, 0x72ca,
- 0x78ac, 0xa084, 0x0003, 0x00c0, 0x1af9, 0x2039, 0x0000, 0xd284,
- 0x0040, 0x1adb, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051,
- 0x0008, 0x1078, 0x1e2b, 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d,
- 0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1ae1,
- 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0,
- 0x1ae1, 0x2091, 0x8000, 0x72c8, 0xd284, 0x00c0, 0x1b0b, 0x7810,
- 0xd0ec, 0x0040, 0x1b07, 0x2069, 0x0100, 0x0078, 0x1b0d, 0x2069,
- 0x0200, 0x0078, 0x1b0d, 0x2069, 0x0100, 0x6808, 0xa084, 0xfffd,
- 0x680a, 0x6830, 0xd0b4, 0x0040, 0x1b2d, 0x684b, 0x0004, 0x20a9,
- 0x0014, 0x6848, 0xd094, 0x0040, 0x1b1f, 0x00f0, 0x1b19, 0x684b,
- 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0040, 0x1b29, 0x00f0,
- 0x1b23, 0x20a9, 0x00fa, 0x00f0, 0x1b2b, 0x2079, 0x4f00, 0x2009,
- 0x0018, 0x72c8, 0xd284, 0x00c0, 0x1b39, 0x2061, 0x4f40, 0x0078,
- 0x1b3c, 0x2061, 0x4f80, 0xc1fd, 0x607f, 0x0000, 0x792a, 0x6067,
- 0x0001, 0x6083, 0x000f, 0x60a7, 0x0000, 0x60a8, 0x60b2, 0x60b6,
- 0x60d4, 0xd0b4, 0x0040, 0x1b58, 0xc0b4, 0x60d6, 0x0c7e, 0x60b8,
- 0xa065, 0x6008, 0xc0d4, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f,
- 0x60d4, 0xa084, 0x77ff, 0x60d6, 0x78ac, 0xc08d, 0x78ae, 0x83ff,
- 0x0040, 0x1b63, 0x007c, 0x681b, 0x0047, 0x2091, 0x8001, 0x007c,
- 0x73cc, 0x1078, 0x1aba, 0x69ec, 0x6a48, 0xa185, 0x1800, 0x684a,
- 0xa185, 0x0040, 0x68ee, 0x73cc, 0x2021, 0x0004, 0x20a9, 0x09ff,
- 0x00f0, 0x1b78, 0x8421, 0x00c0, 0x1b76, 0x8319, 0x00c0, 0x1b74,
- 0x69ee, 0x6a4a, 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x1b8c,
- 0x2069, 0x4f40, 0x0078, 0x1b8e, 0x2069, 0x4f80, 0x71c4, 0x71c6,
- 0x6916, 0x81ff, 0x00c0, 0x1b96, 0x68a7, 0x0001, 0x78ac, 0xc08c,
- 0x78ae, 0xd084, 0x00c0, 0x1b9e, 0x1078, 0x1f2d, 0x007c, 0x75d8,
- 0x74dc, 0x75da, 0x74de, 0x0078, 0x1ba7, 0xa02e, 0x2520, 0x71c4,
- 0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4f00, 0x7dde,
- 0x7cda, 0x7bd6, 0x7ad2, 0x1078, 0x1e04, 0x0040, 0x1cd1, 0x20a9,
- 0x0005, 0x20a1, 0x4f14, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001,
- 0x2009, 0x0040, 0x1078, 0x2018, 0x0040, 0x1bca, 0x1078, 0x1e0d,
- 0x0078, 0x1cd1, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, 0x00c0,
- 0x1bd5, 0x007e, 0x1078, 0x23bf, 0x007f, 0xa084, 0xff00, 0x8007,
- 0x8009, 0x0040, 0x1c61, 0x0c7e, 0x2c68, 0x1078, 0x1e04, 0x0040,
- 0x1c1b, 0x2c00, 0x689e, 0x8109, 0x00c0, 0x1bdc, 0x609f, 0x0000,
- 0x0c7f, 0x0c7e, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040,
- 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda,
- 0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0040, 0x1c60, 0x2009,
- 0x0040, 0x1078, 0x2018, 0x00c0, 0x1c3e, 0x6004, 0xa084, 0x00ff,
- 0xa086, 0x0002, 0x00c0, 0x1c1b, 0x6004, 0xa084, 0x00ff, 0xa086,
- 0x000a, 0x00c0, 0x1c17, 0x017e, 0x1078, 0x23bb, 0x017f, 0x2d00,
- 0x6002, 0x0078, 0x1bea, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e90,
- 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1cd5, 0x2009, 0x0018, 0x6008,
- 0xc0cd, 0x600a, 0x6004, 0x6086, 0x7810, 0x007e, 0x84ff, 0x00c0,
- 0x1c34, 0x85ff, 0x0040, 0x1c36, 0xc0c5, 0x7812, 0x1078, 0x1dbb,
- 0x007f, 0x7812, 0x1078, 0x1e0d, 0x0078, 0x1cd1, 0x0c7f, 0x0c7e,
- 0x609c, 0x1078, 0x1e90, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1cd5,
- 0x2009, 0x0018, 0x6087, 0x0103, 0x601b, 0x0003, 0x7810, 0x007e,
- 0x84ff, 0x00c0, 0x1c56, 0x85ff, 0x0040, 0x1c58, 0xc0c5, 0x7812,
- 0x1078, 0x1dbb, 0x007f, 0x7812, 0x1078, 0x1e0d, 0x0078, 0x1cd1,
- 0x0c7f, 0x7814, 0xd0e4, 0x00c0, 0x1c8f, 0x6114, 0xd1fc, 0x0040,
- 0x1c6f, 0x1078, 0x1dae, 0x0040, 0x1c8f, 0x0078, 0x1c73, 0x1078,
- 0x1da1, 0x0040, 0x1c8f, 0x1078, 0x1cd5, 0x2009, 0x0018, 0x6087,
- 0x0103, 0x601b, 0x0021, 0x7810, 0x007e, 0x84ff, 0x00c0, 0x1c83,
- 0x85ff, 0x0040, 0x1c85, 0xc0c5, 0x7812, 0x1078, 0x1dbb, 0x007f,
- 0x7812, 0x1078, 0x1e0d, 0x2001, 0x4007, 0x0078, 0x15c3, 0x74c4,
- 0x73c8, 0x72cc, 0x6014, 0x2091, 0x8000, 0x0e7e, 0x2009, 0x0012,
- 0xd0fc, 0x00c0, 0x1c9f, 0x2071, 0x4f40, 0x0078, 0x1ca2, 0x2071,
- 0x4f80, 0xc1fd, 0x792a, 0x7067, 0x0005, 0x71d4, 0xc1dc, 0x71d6,
- 0x736a, 0x726e, 0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, 0x707e,
- 0xa02e, 0x2530, 0x611c, 0xa184, 0x0060, 0x0040, 0x1cb9, 0x1078,
- 0x46b6, 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000,
- 0x60b3, 0x0000, 0x6714, 0x6023, 0x0000, 0x6024, 0xa096, 0x0001,
- 0x00c0, 0x1ccc, 0x8000, 0x6026, 0x1078, 0x266f, 0x2091, 0x8001,
- 0x007c, 0x70c3, 0x4005, 0x0078, 0x15c4, 0x20a9, 0x0005, 0x2099,
- 0x4f14, 0x2091, 0x8000, 0x530a, 0x2091, 0x8001, 0x2100, 0xa210,
- 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c, 0x71c4,
- 0x70c7, 0x0000, 0x791e, 0x0078, 0x15c1, 0x71c4, 0x71c6, 0x2168,
- 0x0078, 0x1cf4, 0x2069, 0x1000, 0x690c, 0xa016, 0x2d04, 0xa210,
- 0x8d68, 0x8109, 0x00c0, 0x1cf6, 0xa285, 0x0000, 0x00c0, 0x1d04,
- 0x70c3, 0x4000, 0x0078, 0x1d06, 0x70c3, 0x4003, 0x70ca, 0x0078,
- 0x15c4, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x00c8, 0x15b9,
- 0x7966, 0x0078, 0x15c1, 0x7964, 0x71c6, 0x0078, 0x15c1, 0x7900,
- 0x71c6, 0x71c4, 0x7902, 0x0078, 0x15c1, 0x7900, 0x71c6, 0x0078,
- 0x15c1, 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0040, 0x1d36,
- 0x810c, 0x0048, 0x1d32, 0x8210, 0x810c, 0x810c, 0x0048, 0x1d32,
- 0x8210, 0x810c, 0x81ff, 0x00c0, 0x15ba, 0x8210, 0x7a0e, 0xd28c,
- 0x0040, 0x1d62, 0x7910, 0xc1cd, 0x7912, 0x2009, 0x0021, 0x2019,
- 0x0003, 0xd284, 0x0040, 0x1d5c, 0x8108, 0x2019, 0x0041, 0x2011,
- 0x974e, 0x2312, 0x2019, 0x0042, 0x8210, 0x2312, 0x2019, 0x0043,
- 0x8210, 0x2312, 0x2019, 0x0046, 0x8210, 0x2312, 0x2019, 0x0047,
- 0x8210, 0x2312, 0x2019, 0x0006, 0x2011, 0x9753, 0x2112, 0x2011,
- 0x9773, 0x2312, 0x7904, 0x7806, 0x0078, 0x15c0, 0x7804, 0x70c6,
- 0x0078, 0x15c1, 0x71c4, 0xd1fc, 0x00c0, 0x1d72, 0x2011, 0x53c0,
- 0x0078, 0x1d74, 0x2011, 0x5440, 0x8107, 0xa084, 0x000f, 0x8003,
- 0x8003, 0x8003, 0xa268, 0x6a14, 0xd2b4, 0x0040, 0x1d83, 0x2011,
- 0x0001, 0x0078, 0x1d85, 0x2011, 0x0000, 0x6b0c, 0x6800, 0x70da,
- 0x0078, 0x15be, 0x7814, 0xd0f4, 0x0040, 0x1d95, 0x2001, 0x4007,
- 0x70db, 0x0000, 0xa005, 0x0078, 0x1da0, 0xd0fc, 0x0040, 0x1d9f,
- 0x2001, 0x4007, 0x70db, 0x0001, 0xa005, 0x0078, 0x1da0, 0xa006,
- 0x007c, 0x7814, 0xd0f4, 0x0040, 0x1dac, 0x2001, 0x4007, 0x70db,
- 0x0000, 0xa005, 0x0078, 0x1dad, 0xa006, 0x007c, 0x7814, 0xd0fc,
- 0x0040, 0x1db9, 0x2001, 0x4007, 0x70db, 0x0001, 0xa005, 0x0078,
- 0x1dba, 0xa006, 0x007c, 0x7112, 0x721a, 0x731e, 0x7810, 0xd0c4,
- 0x0040, 0x1dc4, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, 0x810c,
- 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084, 0x20a2,
- 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0040, 0x1de1,
- 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078,
- 0x1de4, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006,
- 0xa211, 0x7d10, 0xd5c4, 0x0040, 0x1df1, 0x7b84, 0xa319, 0x7c80,
- 0xa421, 0x7008, 0xd0fc, 0x0040, 0x1df1, 0x7003, 0x0001, 0x7007,
- 0x0006, 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0040, 0x1e01, 0x7322,
- 0x7426, 0xa084, 0x01e0, 0x007c, 0x7848, 0xa065, 0x0040, 0x1e0c,
- 0x2c04, 0x784a, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x4f00,
- 0x7848, 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1e18, 0x1078, 0x29b2,
- 0x784a, 0x0f7f, 0x007c, 0x2011, 0x9900, 0x7a4a, 0x7bc4, 0x8319,
- 0x0040, 0x1e28, 0xa280, 0x0032, 0x2012, 0x2010, 0x0078, 0x1e1f,
- 0x2013, 0x0000, 0x007c, 0x017e, 0x027e, 0xd7fc, 0x00c0, 0x1e34,
- 0x2011, 0x54c0, 0x0078, 0x1e36, 0x2011, 0x74c0, 0xa784, 0x0f00,
- 0x800b, 0xa784, 0x001f, 0x0040, 0x1e41, 0x8003, 0x8003, 0x8003,
- 0x8003, 0xa105, 0xa268, 0x027f, 0x017f, 0x007c, 0x1078, 0x1e2b,
- 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef, 0xa80d,
- 0x690a, 0x0e7e, 0xd7fc, 0x00c0, 0x1e5b, 0x2009, 0x4f53, 0x2071,
- 0x4f40, 0x0078, 0x1e5f, 0x2009, 0x4f93, 0x2071, 0x4f80, 0x210c,
- 0x6804, 0xa005, 0x0040, 0x1e6f, 0xa116, 0x00c0, 0x1e6f, 0x2060,
- 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x1e72, 0x2009,
- 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1e87, 0x6000, 0x6806,
- 0x1078, 0x1ea2, 0x1078, 0x2064, 0x6810, 0x7908, 0x8109, 0x790a,
- 0x8001, 0x6812, 0x00c0, 0x1e72, 0x7910, 0xc1a5, 0x7912, 0x017f,
- 0x6902, 0x6906, 0x2d00, 0x2060, 0x1078, 0x2b13, 0x0e7f, 0x007c,
- 0xa065, 0x0040, 0x1ea1, 0x2008, 0x609c, 0xa005, 0x0040, 0x1e9e,
- 0x2062, 0x609f, 0x0000, 0xa065, 0x0078, 0x1e94, 0x7848, 0x794a,
- 0x2062, 0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c,
- 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a,
- 0x682c, 0x6022, 0x007c, 0x0e7e, 0xd7fc, 0x00c0, 0x1ebd, 0x2071,
- 0x4f40, 0x2031, 0x4fc0, 0x0078, 0x1ec1, 0x2071, 0x4f80, 0x2031,
- 0x51c0, 0x7050, 0xa08c, 0x0200, 0x00c0, 0x1ecb, 0xa608, 0x2d0a,
- 0x8000, 0x7052, 0xa006, 0x0e7f, 0x007c, 0x0f7e, 0xd7fc, 0x00c0,
- 0x1ed5, 0x2079, 0x4f40, 0x0078, 0x1ed7, 0x2079, 0x4f80, 0x1078,
- 0x1e2b, 0x2091, 0x8000, 0x6804, 0x780a, 0xa065, 0x0040, 0x1f2b,
- 0x0078, 0x1ee9, 0x2c00, 0x780a, 0x2060, 0x6000, 0xa065, 0x0040,
- 0x1f2b, 0x6010, 0xa306, 0x00c0, 0x1ee2, 0x600c, 0xa206, 0x00c0,
- 0x1ee2, 0x2c28, 0x784c, 0xac06, 0x00c0, 0x1ef8, 0x0078, 0x1f28,
- 0x6804, 0xac06, 0x00c0, 0x1f06, 0x6000, 0x2060, 0x6806, 0xa005,
- 0x00c0, 0x1f06, 0x6803, 0x0000, 0x0078, 0x1f10, 0x6400, 0x7808,
- 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1f10, 0x2c00, 0x6802,
- 0x2560, 0x0f7f, 0x1078, 0x1ea2, 0x0f7e, 0x601b, 0x0005, 0x6023,
- 0x0020, 0x0f7f, 0x1078, 0x2064, 0x0f7e, 0x7908, 0x8109, 0x790a,
- 0x6810, 0x8001, 0x6812, 0x00c0, 0x1f28, 0x7810, 0xc0a5, 0x7812,
- 0x2001, 0xffff, 0xa005, 0x0f7f, 0x007c, 0x077e, 0x2700, 0x2039,
- 0x0000, 0xd0fc, 0x0040, 0x1f35, 0xc7fd, 0x2041, 0x0021, 0x2049,
- 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x1e46, 0x8738,
- 0xa784, 0x001f, 0x00c0, 0x1f3d, 0xa7bc, 0xff00, 0x873f, 0x8738,
- 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1f3d, 0x2091, 0x8001, 0x077f,
- 0x007c, 0x786c, 0x2009, 0x9774, 0x210c, 0xa10d, 0x0040, 0x1f5b,
- 0xa065, 0x0078, 0x23dc, 0x2061, 0x0000, 0x6018, 0xd084, 0x00c0,
- 0x1f7b, 0x7810, 0xd08c, 0x0040, 0x1f6c, 0xc08c, 0x7812, 0xc7fc,
- 0x2069, 0x4f40, 0x0078, 0x1f71, 0xc08d, 0x7812, 0x2069, 0x4f80,
- 0xc7fd, 0x2091, 0x8000, 0x681c, 0x681f, 0x0000, 0x2091, 0x8001,
- 0xa005, 0x00c0, 0x1f7c, 0x007c, 0xa08c, 0xfff0, 0x0040, 0x1f82,
- 0x1078, 0x29b2, 0x0079, 0x1f84, 0x1f94, 0x1f97, 0x1f9d, 0x1fa1,
- 0x1f95, 0x1fa5, 0x1f95, 0x1f95, 0x1f95, 0x1fab, 0x1fdc, 0x1fe0,
- 0x1fe6, 0x1ffb, 0x1f95, 0x1f95, 0x007c, 0x1078, 0x29b2, 0x1078,
- 0x1f2d, 0x2001, 0x8001, 0x0078, 0x2007, 0x2001, 0x8003, 0x0078,
- 0x2007, 0x2001, 0x8004, 0x0078, 0x2007, 0x1078, 0x1f2d, 0x2001,
- 0x8006, 0x0078, 0x2007, 0x2091, 0x8000, 0x077e, 0xd7fc, 0x00c0,
- 0x1fb7, 0x2069, 0x4f40, 0x2039, 0x0009, 0x0078, 0x1fbb, 0x2069,
- 0x4f80, 0x2039, 0x0009, 0x6800, 0xa086, 0x0000, 0x0040, 0x1fc5,
- 0x007f, 0x6f1e, 0x2091, 0x8001, 0x007c, 0x6874, 0x077f, 0xa0bc,
- 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x1078,
- 0x1e46, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1fcf, 0x2091, 0x8001,
- 0x2001, 0x800a, 0x0078, 0x2007, 0x2001, 0x800c, 0x0078, 0x2007,
- 0x1078, 0x1f2d, 0x2001, 0x800d, 0x0078, 0x2007, 0x7814, 0xd0e4,
- 0x00c0, 0x1ff9, 0xd0ec, 0x0040, 0x1ff3, 0xd7fc, 0x0040, 0x1ff3,
- 0x78e4, 0x0078, 0x1ff4, 0x78e0, 0x70c6, 0x2001, 0x800e, 0x0078,
- 0x2007, 0x0078, 0x1f95, 0xd7fc, 0x0040, 0x2001, 0x78ec, 0x0078,
- 0x2002, 0x78e8, 0x70c6, 0x2001, 0x800f, 0x0078, 0x2007, 0x70c2,
- 0xd7fc, 0x00c0, 0x200f, 0x70db, 0x0000, 0x0078, 0x2011, 0x70db,
- 0x0001, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x007c,
- 0xac80, 0x0001, 0x81ff, 0x0040, 0x2043, 0x2099, 0x0030, 0x20a0,
- 0x700c, 0xa084, 0x03ff, 0x0040, 0x2025, 0x7018, 0x007e, 0x701c,
- 0x007e, 0x7020, 0x007e, 0x7024, 0x007e, 0x7112, 0x81ac, 0x721a,
- 0x731e, 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001, 0x7008,
- 0x800b, 0x00c8, 0x2037, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0,
- 0x2043, 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, 0x007f,
- 0x7026, 0x007f, 0x7022, 0x007f, 0x701e, 0x007f, 0x701a, 0x007c,
- 0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x6803, 0xfd00,
- 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004,
- 0x8109, 0x00c0, 0x2054, 0x007c, 0x6004, 0x6086, 0x2c08, 0x2063,
- 0x0000, 0x7868, 0xa005, 0x796a, 0x0040, 0x2071, 0x2c02, 0x0078,
- 0x2072, 0x796e, 0x007c, 0x0c7e, 0x2061, 0x4f00, 0x6887, 0x0103,
- 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x2083,
- 0x2d02, 0x0078, 0x2084, 0x616e, 0x0c7f, 0x007c, 0x2091, 0x8000,
- 0x2c04, 0x786e, 0xa005, 0x00c0, 0x208e, 0x786a, 0x2091, 0x8001,
- 0x609c, 0xa005, 0x0040, 0x20a7, 0x0c7e, 0x2060, 0x2008, 0x609c,
- 0xa005, 0x0040, 0x20a3, 0x2062, 0x609f, 0x0000, 0xa065, 0x609c,
- 0xa005, 0x00c0, 0x209b, 0x7848, 0x794a, 0x2062, 0x0c7f, 0x7848,
- 0x2062, 0x609f, 0x0000, 0xac85, 0x0000, 0x00c0, 0x20b1, 0x1078,
- 0x29b2, 0x784a, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086,
- 0x818e, 0x00c8, 0x20bc, 0xa200, 0x00f0, 0x20b7, 0x8086, 0x818e,
- 0x007c, 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x20e2, 0xa11a,
- 0x00c8, 0x20e2, 0x8213, 0x818d, 0x0048, 0x20d5, 0xa11a, 0x00c8,
- 0x20d6, 0x00f0, 0x20ca, 0x0078, 0x20da, 0xa11a, 0x2308, 0x8210,
- 0x00f0, 0x20ca, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f,
- 0x157f, 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x20de,
- 0x7d74, 0x70d0, 0xa506, 0x0040, 0x21ce, 0x7810, 0x2050, 0x7800,
- 0xd08c, 0x0040, 0x210a, 0xdaec, 0x0040, 0x210a, 0x0e7e, 0x2091,
- 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x2107, 0x7008,
- 0x0e7f, 0xa086, 0x0008, 0x0040, 0x210a, 0x0078, 0x21ce, 0x0e7f,
- 0x0078, 0x21ce, 0x1078, 0x1e04, 0x0040, 0x21ce, 0xa046, 0x7970,
- 0x2500, 0x8000, 0xa112, 0x2009, 0x0040, 0x00c8, 0x2119, 0x0078,
- 0x2120, 0x72d0, 0xa206, 0x0040, 0x2120, 0x8840, 0x2009, 0x0080,
- 0x0c7e, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, 0x0020,
- 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0040, 0x2132,
- 0x1078, 0x1e04, 0x7008, 0xd0fc, 0x0040, 0x2132, 0x7007, 0x0002,
- 0x2091, 0x8001, 0xa08c, 0x01e0, 0x00c0, 0x2169, 0x53a5, 0x8cff,
- 0x00c0, 0x2147, 0x88ff, 0x0040, 0x21b8, 0x0078, 0x2151, 0x2c00,
- 0x788e, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5, 0x0078,
- 0x21b8, 0xa046, 0x7218, 0x731c, 0xdac4, 0x0040, 0x2159, 0x7420,
- 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3, 0x0000, 0xa5ab,
- 0x0000, 0x721a, 0x731e, 0xdac4, 0x0040, 0x2169, 0x7422, 0x7526,
- 0xa006, 0x7007, 0x0004, 0x0040, 0x21b8, 0x8cff, 0x0040, 0x2172,
- 0x1078, 0x1e0d, 0x0c7f, 0x1078, 0x1e0d, 0xa046, 0x7888, 0x8000,
- 0x788a, 0xa086, 0x0002, 0x0040, 0x2198, 0x7a7c, 0x7b78, 0xdac4,
- 0x0040, 0x2184, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004,
- 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a,
- 0x731e, 0xdac4, 0x0040, 0x21ce, 0x7422, 0x7526, 0x0078, 0x21ce,
- 0x6014, 0xd0fc, 0x00c0, 0x21a0, 0x2069, 0x4f40, 0x0078, 0x21a2,
- 0x2069, 0x4f80, 0x2091, 0x8000, 0x681f, 0x0002, 0x88ff, 0x0040,
- 0x21ae, 0xa046, 0x788c, 0x2060, 0x0078, 0x2198, 0x788b, 0x0000,
- 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0078, 0x21ce,
- 0x0c7f, 0x788b, 0x0000, 0x1078, 0x238d, 0x6004, 0xa084, 0x000f,
- 0x1078, 0x21cf, 0x88ff, 0x0040, 0x21cc, 0x788c, 0x2060, 0x6004,
- 0xa084, 0x000f, 0x1078, 0x21cf, 0x0078, 0x20e8, 0x007c, 0x0079,
- 0x21d1, 0x21e1, 0x21ff, 0x221d, 0x21e1, 0x222e, 0x21f2, 0x21e1,
- 0x21e1, 0x21e1, 0x21fd, 0x221b, 0x21e1, 0x21e1, 0x21e1, 0x21e1,
- 0x21e1, 0x2039, 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705,
- 0x600a, 0x1078, 0x2271, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078,
- 0x2377, 0x007c, 0x78bc, 0xd0c4, 0x0040, 0x21f8, 0x0078, 0x21e1,
- 0x601c, 0xc0bd, 0x601e, 0x0078, 0x2205, 0x1078, 0x23bf, 0x78bc,
- 0xd0c4, 0x0040, 0x2205, 0x0078, 0x21e1, 0x78bf, 0x0000, 0x6004,
- 0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0040, 0x2218, 0x1078,
- 0x2271, 0x0040, 0x2218, 0x78bc, 0xc0c5, 0x78be, 0x0078, 0x221a,
- 0x0078, 0x2290, 0x007c, 0x1078, 0x23bb, 0x78bc, 0xa08c, 0x0e00,
- 0x00c0, 0x2225, 0xd0c4, 0x00c0, 0x2227, 0x0078, 0x21e1, 0x1078,
- 0x2271, 0x00c0, 0x222d, 0x0078, 0x2290, 0x007c, 0x78bc, 0xd0c4,
- 0x0040, 0x2234, 0x0078, 0x21e1, 0x78bf, 0x0000, 0x6714, 0x2011,
- 0x0001, 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040, 0x2254,
- 0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040, 0x2254,
- 0xa7bc, 0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002,
- 0x0040, 0x2254, 0x0078, 0x226e, 0x1078, 0x1e2b, 0x2d00, 0x2091,
- 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, 0xffde,
- 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x00f0, 0x2257, 0x8211,
- 0x0040, 0x226e, 0x20a9, 0x0100, 0x0078, 0x2257, 0x1078, 0x1e0d,
- 0x007c, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, 0x00c0,
- 0x227c, 0x78ba, 0x0078, 0x2284, 0x689e, 0x2d00, 0x6002, 0x78b8,
- 0xad06, 0x00c0, 0x2284, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x00c0,
- 0x228f, 0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, 0x007c,
- 0x0e7e, 0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c,
- 0x60a2, 0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0040,
- 0x22a3, 0x1078, 0x46b6, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714,
- 0x2071, 0x4f80, 0xd7fc, 0x00c0, 0x22af, 0x2071, 0x4f40, 0xa784,
- 0x0f00, 0x800b, 0xa784, 0x001f, 0x0040, 0x22ba, 0x8003, 0x8003,
- 0x8003, 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, 0x8007, 0xa084,
- 0x000f, 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, 0x60c2, 0x2091,
- 0x8000, 0x7814, 0xd0c4, 0x0040, 0x22df, 0xd0ec, 0x0040, 0x22db,
- 0xd7fc, 0x00c0, 0x22d8, 0xd0f4, 0x00c0, 0x22e6, 0x0078, 0x22df,
- 0xd0fc, 0x00c0, 0x22e6, 0x7810, 0xd0f4, 0x00c0, 0x22e6, 0x6e08,
- 0xd684, 0x0040, 0x2310, 0xd9fc, 0x00c0, 0x2310, 0x2091, 0x8001,
- 0x1078, 0x1ea2, 0x2091, 0x8000, 0x1078, 0x2064, 0x2091, 0x8001,
- 0x7814, 0xd0e4, 0x00c0, 0x2375, 0x7814, 0xd0c4, 0x0040, 0x2375,
- 0xd0ec, 0x0040, 0x2308, 0xd7fc, 0x00c0, 0x2303, 0xd0f4, 0x00c0,
- 0x230c, 0x0078, 0x2375, 0xd0fc, 0x00c0, 0x230c, 0x0078, 0x2375,
- 0x7810, 0xd0f4, 0x0040, 0x2375, 0x601b, 0x0021, 0x0078, 0x2375,
- 0x6024, 0xa096, 0x0001, 0x00c0, 0x2317, 0x8000, 0x6026, 0x6a10,
- 0x6814, 0xa202, 0x0048, 0x232a, 0x0040, 0x232a, 0x2091, 0x8001,
- 0x2039, 0x0200, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078, 0x2377,
- 0x0078, 0x2375, 0x2c08, 0xd9fc, 0x0040, 0x2352, 0x6800, 0xa065,
- 0x0040, 0x2352, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0040, 0x2348,
- 0x704c, 0xa206, 0x00c0, 0x2348, 0x6b04, 0x2160, 0x2304, 0x6002,
- 0xa005, 0x00c0, 0x2344, 0x6902, 0x2260, 0x6102, 0x0078, 0x235e,
- 0x2d00, 0x2060, 0x1078, 0x2b13, 0x6e08, 0x2160, 0x6202, 0x6906,
- 0x0078, 0x235e, 0x6800, 0x6902, 0xa065, 0x0040, 0x235a, 0x6102,
- 0x0078, 0x235b, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160, 0xd9fc,
- 0x0040, 0x2365, 0xa6b4, 0xfffc, 0x6e0a, 0x6810, 0x7d08, 0x8528,
- 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4, 0x0040, 0x2375,
- 0xa6b6, 0x0040, 0x6e0a, 0x1078, 0x1eb3, 0x0e7f, 0x007c, 0x6008,
- 0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x2064, 0x2091, 0x8001,
- 0x78b8, 0xa065, 0x0040, 0x238a, 0x609c, 0x78ba, 0x609f, 0x0000,
- 0x0078, 0x2377, 0x78b6, 0x78ba, 0x007c, 0x7970, 0x7874, 0x2818,
- 0xd384, 0x0040, 0x2397, 0x8000, 0xa112, 0x0048, 0x239c, 0x8000,
- 0xa112, 0x00c8, 0x23ac, 0xc384, 0x7a7c, 0x721a, 0x7a78, 0x721e,
- 0xdac4, 0x0040, 0x23a7, 0x7a84, 0x7222, 0x7a80, 0x7226, 0xa006,
- 0xd384, 0x0040, 0x23ac, 0x8000, 0x7876, 0x70d2, 0x781c, 0xa005,
- 0x0040, 0x23ba, 0x8001, 0x781e, 0x00c0, 0x23ba, 0x0068, 0x23ba,
- 0x2091, 0x4080, 0x007c, 0x2039, 0x23d3, 0x0078, 0x23c1, 0x2039,
- 0x23d9, 0x2704, 0xa005, 0x0040, 0x23d2, 0xac00, 0x2068, 0x6908,
- 0x6810, 0x6912, 0x680a, 0x690c, 0x6814, 0x6916, 0x680e, 0x8738,
- 0x0078, 0x23c1, 0x007c, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b,
- 0x0000, 0x0015, 0x001b, 0x0000, 0x2041, 0x0000, 0x780c, 0x0079,
- 0x23e1, 0x25b3, 0x2586, 0x23e5, 0x245e, 0x2039, 0x9774, 0x2734,
- 0x7d10, 0x0078, 0x2405, 0x6084, 0xa086, 0x0103, 0x00c0, 0x2447,
- 0x6114, 0x6018, 0xa105, 0x0040, 0x23fa, 0x86ff, 0x00c0, 0x2416,
- 0x0078, 0x2447, 0x8603, 0xa080, 0x9755, 0x620c, 0x2202, 0x8000,
- 0x6210, 0x2202, 0x1078, 0x2086, 0x8630, 0xa68e, 0x000f, 0x0040,
- 0x24d2, 0x786c, 0xa065, 0x00c0, 0x23eb, 0x7808, 0xa602, 0x00c8,
- 0x2416, 0xd5ac, 0x00c0, 0x2416, 0x263a, 0x007c, 0xa682, 0x0003,
- 0x00c8, 0x24d2, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084,
- 0x00c0, 0x2442, 0x2011, 0x9755, 0x2204, 0x70c6, 0x8210, 0x2204,
- 0x70ca, 0xd684, 0x00c0, 0x2432, 0x8210, 0x2204, 0x70da, 0x8210,
- 0x2204, 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001, 0x2091,
- 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, 0x203b,
- 0x0000, 0x007c, 0x7810, 0xc0ad, 0x7812, 0x0078, 0x24d2, 0x263a,
- 0x1078, 0x25bd, 0x00c0, 0x25e0, 0x786c, 0xa065, 0x00c0, 0x23eb,
- 0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040, 0x2459,
- 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0078, 0x25e0, 0x2039, 0x9774,
- 0x2734, 0x7d10, 0x0078, 0x247a, 0x6084, 0xa086, 0x0103, 0x00c0,
- 0x24bb, 0x6114, 0x6018, 0xa105, 0x0040, 0x2473, 0x86ff, 0x00c0,
- 0x248b, 0x0078, 0x24bb, 0xa680, 0x9755, 0x620c, 0x2202, 0x1078,
- 0x2086, 0x8630, 0xa68e, 0x001e, 0x0040, 0x24d2, 0x786c, 0xa065,
- 0x00c0, 0x2464, 0x7808, 0xa602, 0x00c8, 0x248b, 0xd5ac, 0x00c0,
- 0x248b, 0x263a, 0x007c, 0xa682, 0x0006, 0x00c8, 0x24d2, 0x2091,
- 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x24b6, 0x2011,
- 0x9755, 0x2009, 0x974e, 0x26a8, 0x211c, 0x2204, 0x201a, 0x8108,
- 0x8210, 0x00f0, 0x249c, 0xa685, 0x8030, 0x70c2, 0x681b, 0x0001,
- 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001,
- 0xa006, 0x2009, 0x9775, 0x200a, 0x203a, 0x007c, 0x7810, 0xc0ad,
- 0x7812, 0x0078, 0x24d2, 0x263a, 0x1078, 0x25bd, 0x00c0, 0x25e0,
- 0x786c, 0xa065, 0x00c0, 0x2464, 0x2091, 0x8000, 0x7810, 0xa084,
- 0xffcf, 0x86ff, 0x0040, 0x24cd, 0xc0ad, 0x7812, 0x2091, 0x8001,
- 0x0078, 0x25e0, 0x2091, 0x8000, 0x7007, 0x0004, 0x7994, 0x70d4,
- 0xa102, 0x0048, 0x24e3, 0x0040, 0x24ed, 0x7b90, 0xa302, 0x00c0,
- 0x24ed, 0x0078, 0x24e6, 0x8002, 0x00c0, 0x24ed, 0x263a, 0x7810,
- 0xc0ad, 0x7812, 0x2091, 0x8001, 0x007c, 0xa184, 0xff00, 0x0040,
- 0x24fa, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
- 0x0078, 0x24fd, 0x8107, 0x8004, 0x8004, 0x7a9c, 0xa210, 0x721a,
- 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0040, 0x250d, 0x7aa4,
- 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, 0x0030, 0x7003,
- 0x0000, 0x2009, 0x9754, 0x260a, 0x8109, 0x2198, 0x2104, 0xd084,
- 0x0040, 0x251b, 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6, 0x8603,
- 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8,
- 0x252a, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0040, 0x2539,
- 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078,
- 0x253c, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006,
- 0xa211, 0xd4c4, 0x0040, 0x2548, 0x7b84, 0xa319, 0x7c80, 0xa421,
- 0x7008, 0xd0fc, 0x0040, 0x2548, 0xa084, 0x01e0, 0x0040, 0x256d,
- 0x7d10, 0x2031, 0x9754, 0x2634, 0x78a8, 0x8000, 0x78aa, 0xd08c,
- 0x00c0, 0x2562, 0x7007, 0x0006, 0x7004, 0xd094, 0x00c0, 0x255c,
- 0x0078, 0x24d4, 0x2069, 0x4f47, 0x206b, 0x0003, 0x78ac, 0xa085,
- 0x0300, 0x78ae, 0xa006, 0x0078, 0x2576, 0x2030, 0x75d6, 0x2091,
- 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091, 0x8001,
- 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a, 0x721e,
- 0xd5c4, 0x0040, 0x2585, 0x7322, 0x7426, 0x007c, 0x6084, 0xa086,
- 0x0103, 0x00c0, 0x25a9, 0x6114, 0x6018, 0xa105, 0x00c0, 0x25a9,
- 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x25a9, 0x600c, 0x70c6,
- 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091, 0x4080,
- 0x1078, 0x2086, 0x0068, 0x25a8, 0x786c, 0xa065, 0x00c0, 0x2586,
- 0x007c, 0x1078, 0x25bd, 0x00c0, 0x25e0, 0x786c, 0xa065, 0x00c0,
- 0x2586, 0x0078, 0x25e0, 0x1078, 0x25bd, 0x00c0, 0x25e0, 0x786c,
- 0xa065, 0x00c0, 0x25b3, 0x0078, 0x25e0, 0x6084, 0xa086, 0x0103,
- 0x00c0, 0x25d1, 0x6018, 0xc0fc, 0x601a, 0xa086, 0x0004, 0x00c0,
- 0x25d1, 0x7804, 0xd0a4, 0x0040, 0x25d1, 0x1078, 0x2086, 0xa006,
- 0x007c, 0x1078, 0x25e6, 0x00c0, 0x25d8, 0xa085, 0x0001, 0x007c,
- 0x1078, 0x25f5, 0x00c0, 0x25de, 0x2041, 0x0001, 0x7d10, 0x007c,
- 0x88ff, 0x0040, 0x25e5, 0x2091, 0x4080, 0x007c, 0x7b90, 0x7994,
- 0x70d4, 0xa102, 0x00c0, 0x25ef, 0xa385, 0x0000, 0x007c, 0x0048,
- 0x25f3, 0xa302, 0x007c, 0x8002, 0x007c, 0x7810, 0xd0ec, 0x0040,
- 0x260d, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005,
- 0x00c0, 0x260a, 0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040, 0x260d,
- 0x0078, 0x265e, 0x0e7f, 0x0078, 0x265e, 0xa184, 0xff00, 0x0040,
- 0x261a, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
- 0x0078, 0x261d, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4,
- 0x7da0, 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018,
- 0x6028, 0xa005, 0x0040, 0x262e, 0x2009, 0x0040, 0x1078, 0x1dbb,
- 0x0040, 0x2650, 0x78a8, 0x8000, 0x78aa, 0xd08c, 0x00c0, 0x265e,
- 0x6014, 0xd0fc, 0x00c0, 0x2640, 0x2069, 0x4f40, 0x0078, 0x2642,
- 0x2069, 0x4f80, 0x2091, 0x8000, 0x681f, 0x0003, 0x78ab, 0x0000,
- 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001, 0x0078, 0x265e,
- 0x78ab, 0x0000, 0x1078, 0x2086, 0x7990, 0x7894, 0x8000, 0xa10a,
- 0x00c8, 0x265b, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071, 0x0010,
- 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x266a, 0x2009, 0x4f59,
- 0x0078, 0x266c, 0x2009, 0x4f99, 0x2091, 0x8000, 0x200a, 0x0f7e,
- 0xd7fc, 0x00c0, 0x2683, 0x2009, 0x4f40, 0x2001, 0x4f04, 0x2004,
- 0xd0ec, 0x0040, 0x267f, 0x2079, 0x0100, 0x0078, 0x2687, 0x2079,
- 0x0200, 0x0078, 0x2687, 0x2009, 0x4f80, 0x2079, 0x0100, 0x2104,
- 0xa086, 0x0000, 0x00c0, 0x26a0, 0xd7fc, 0x00c0, 0x2693, 0x2009,
- 0x4f45, 0x0078, 0x2695, 0x2009, 0x4f85, 0x2104, 0xa005, 0x00c0,
- 0x26a0, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x26a0, 0x781b, 0x0045,
- 0x0f7f, 0x007c, 0x2009, 0x0002, 0x2069, 0x4f00, 0x6810, 0xd0ec,
- 0x00c0, 0x270f, 0x2071, 0x4f80, 0x2079, 0x0100, 0x2021, 0x51bf,
- 0x784b, 0x000f, 0x2019, 0x44a7, 0xd184, 0x0040, 0x26c3, 0x6810,
- 0xd0ec, 0x0040, 0x26bf, 0x20a1, 0x012b, 0x0078, 0x26c5, 0x20a1,
- 0x022b, 0x0078, 0x26c5, 0x20a1, 0x012b, 0x2304, 0xa005, 0x0040,
- 0x26d2, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318,
- 0x0078, 0x26c5, 0x789b, 0x0020, 0x20a9, 0x0010, 0x6814, 0xd0e4,
- 0x0040, 0x26e2, 0x78af, 0x0000, 0x78af, 0x9020, 0x00f0, 0x26da,
- 0x0078, 0x26e8, 0x78af, 0x0000, 0x78af, 0x8020, 0x00f0, 0x26e2,
- 0x7003, 0x0000, 0x017e, 0xd18c, 0x2009, 0x0000, 0x0040, 0x26f1,
- 0xc1bd, 0x1078, 0x28e2, 0x017f, 0x7020, 0xa084, 0x000f, 0x007e,
- 0x6814, 0xd0e4, 0x007f, 0x00c0, 0x2701, 0xa085, 0x6340, 0x0078,
- 0x2703, 0xa085, 0x62c0, 0x7806, 0x780f, 0x9200, 0x7843, 0x00d8,
- 0x7853, 0x0080, 0x780b, 0x0008, 0x7456, 0x7053, 0x0000, 0x8109,
- 0x0040, 0x2722, 0x2071, 0x4f40, 0x6810, 0xd0ec, 0x0040, 0x271c,
- 0x2079, 0x0100, 0x0078, 0x271e, 0x2079, 0x0200, 0x2021, 0x4fbf,
- 0x0078, 0x26b0, 0x007c, 0x017e, 0xd1bc, 0x00c0, 0x2737, 0x007e,
- 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2733, 0x2011,
- 0x0101, 0x0078, 0x2739, 0x2011, 0x0201, 0x0078, 0x2739, 0x2011,
- 0x0101, 0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012,
- 0x017f, 0x1078, 0x28e2, 0x007c, 0xd3fc, 0x00c0, 0x2757, 0x007e,
- 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2753, 0x2011,
- 0x0101, 0x0078, 0x2759, 0x2011, 0x0201, 0x0078, 0x2759, 0x2011,
- 0x0101, 0x20a9, 0x0009, 0x810b, 0x00f0, 0x275b, 0xa18c, 0x0e00,
- 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2019, 0x0002,
- 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x0040, 0x2773, 0x8319, 0x2009,
- 0x0101, 0x0078, 0x2775, 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213,
- 0x00f0, 0x2777, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205,
- 0x200a, 0x8319, 0x0040, 0x2788, 0x2009, 0x0201, 0x0078, 0x2775,
- 0x007c, 0xd3fc, 0x00c0, 0x279c, 0x007e, 0x2001, 0x4f04, 0x2004,
- 0xd0ec, 0x007f, 0x0040, 0x2798, 0x2011, 0x0101, 0x0078, 0x279e,
- 0x2011, 0x0201, 0x0078, 0x279e, 0x2011, 0x0101, 0x20a9, 0x000c,
- 0x810b, 0x00f0, 0x27a0, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff,
- 0xa105, 0x2012, 0x007c, 0xd3fc, 0x00c0, 0x27be, 0x007e, 0x2001,
- 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x27ba, 0x2011, 0x0102,
- 0x0078, 0x27c0, 0x2011, 0x0202, 0x0078, 0x27c0, 0x2011, 0x0102,
- 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x007c, 0x0c7e, 0xd1bc,
- 0x00c0, 0x27da, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f,
- 0x0040, 0x27d6, 0x2061, 0x0100, 0x0078, 0x27dc, 0x2061, 0x0200,
- 0x0078, 0x27dc, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080,
- 0x0020, 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc,
- 0x00c0, 0x27fa, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f,
- 0x0040, 0x27f6, 0x2061, 0x0100, 0x0078, 0x27fc, 0x2061, 0x0200,
- 0x0078, 0x27fc, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080,
- 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f, 0x007c,
- 0x0c7e, 0xd1bc, 0x00c0, 0x281c, 0x007e, 0x2001, 0x4f04, 0x2004,
- 0xd0ec, 0x007f, 0x0040, 0x2818, 0x2061, 0x0100, 0x0078, 0x281e,
- 0x2061, 0x0200, 0x0078, 0x281e, 0x2061, 0x0100, 0xc1bc, 0x8103,
- 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae,
- 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x283e, 0x007e, 0x2001,
- 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x283a, 0x2061, 0x0100,
- 0x0078, 0x2840, 0x2061, 0x0200, 0x0078, 0x2840, 0x2061, 0x0100,
- 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, 0xa28c,
- 0x0020, 0x0040, 0x284e, 0xc2ac, 0xa39d, 0x4000, 0xc3fc, 0xd3b4,
- 0x00c0, 0x2853, 0xc3fd, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018,
- 0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005,
- 0x0040, 0x28c0, 0xd1fc, 0x0040, 0x2869, 0x2061, 0x96d0, 0x0078,
- 0x286b, 0x2061, 0x95c0, 0x1078, 0x28c8, 0x0040, 0x28a2, 0x20a9,
- 0x0101, 0xd1fc, 0x0040, 0x2878, 0x2061, 0x95d0, 0x0078, 0x287a,
- 0x2061, 0x94c0, 0x0c7e, 0x1078, 0x28c8, 0x0040, 0x2885, 0x0c7f,
- 0x8c60, 0x00f0, 0x287a, 0x0078, 0x28c0, 0x007f, 0xd1fc, 0x0040,
- 0x288f, 0xa082, 0x95d0, 0x2071, 0x4f80, 0x0078, 0x2893, 0xa082,
- 0x94c0, 0x2071, 0x4f40, 0x707a, 0x7176, 0x2138, 0x2001, 0x0004,
- 0x7066, 0x7083, 0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x1078, 0x2663,
- 0x0078, 0x28bc, 0xd1fc, 0x00c0, 0x28a9, 0x2071, 0x4f40, 0x0078,
- 0x28ab, 0x2071, 0x4f80, 0x6020, 0xc0dd, 0x6022, 0x7176, 0x2138,
- 0x2c00, 0x707e, 0x2001, 0x0006, 0x7066, 0x7083, 0x000f, 0x71d4,
- 0xc1dc, 0x71d6, 0x1078, 0x2663, 0x2001, 0x0000, 0x0078, 0x28c2,
- 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f, 0x007c,
- 0x2c04, 0xa005, 0x0040, 0x28df, 0x2060, 0x6010, 0xa306, 0x00c0,
- 0x28dc, 0x600c, 0xa206, 0x00c0, 0x28dc, 0x6014, 0xa106, 0x00c0,
- 0x28dc, 0xa006, 0x0078, 0x28e1, 0x6000, 0x0078, 0x28c9, 0xa085,
- 0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x017e, 0xd1bc, 0x00c0, 0x28fa,
- 0x2079, 0x4f40, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f,
- 0x0040, 0x28f6, 0x2071, 0x0100, 0x0078, 0x28fe, 0x2071, 0x0200,
- 0x0078, 0x28fe, 0x2079, 0x4f80, 0x2071, 0x0100, 0x7920, 0xa18c,
- 0x000f, 0x70ec, 0xd0c4, 0x00c0, 0x2908, 0x017f, 0x0078, 0x2923,
- 0x810b, 0x810b, 0x810b, 0x810b, 0x007f, 0xd0bc, 0x00c0, 0x2920,
- 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x291c,
- 0xa18d, 0x0f00, 0x0078, 0x2922, 0xa18d, 0x0f00, 0x0078, 0x2922,
- 0xa18d, 0x0800, 0x2104, 0x0e7f, 0x0f7f, 0x007c, 0x0e7e, 0x2001,
- 0x4f01, 0x2004, 0xd0ac, 0x00c0, 0x29a3, 0x68e4, 0xd0ac, 0x0040,
- 0x29a3, 0xa084, 0x0006, 0x00c0, 0x29a3, 0x6014, 0xd0fc, 0x00c0,
- 0x293d, 0x2071, 0x53c0, 0x0078, 0x293f, 0x2071, 0x5440, 0x8007,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, 0xa084,
- 0x000a, 0x00c0, 0x29a3, 0x7108, 0xa194, 0xff00, 0x0040, 0x29a3,
- 0xa18c, 0x00ff, 0x2001, 0x000a, 0xa106, 0x0040, 0x2972, 0x2001,
- 0x000c, 0xa106, 0x0040, 0x2976, 0x2001, 0x0012, 0xa106, 0x0040,
- 0x297a, 0x2001, 0x0014, 0xa106, 0x0040, 0x297e, 0x2001, 0x0019,
- 0xa106, 0x0040, 0x2982, 0x2001, 0x0032, 0xa106, 0x0040, 0x2986,
- 0x0078, 0x298a, 0x2009, 0x000c, 0x0078, 0x298c, 0x2009, 0x0012,
- 0x0078, 0x298c, 0x2009, 0x0014, 0x0078, 0x298c, 0x2009, 0x0019,
- 0x0078, 0x298c, 0x2009, 0x0020, 0x0078, 0x298c, 0x2009, 0x003f,
- 0x0078, 0x298c, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, 0x2071,
- 0x4f00, 0x7004, 0xd0bc, 0x0040, 0x29a3, 0x6014, 0xd0fc, 0x00c0,
- 0x299e, 0x70ea, 0x2071, 0x4f40, 0x0078, 0x29a1, 0x70ee, 0x2071,
- 0x4f80, 0x701f, 0x000d, 0x0e7f, 0x007c, 0x2001, 0x4f05, 0x2004,
- 0xd0e4, 0x00c0, 0x29b1, 0x7804, 0xa084, 0xff1f, 0xa085, 0x6340,
- 0x7806, 0x007c, 0x0068, 0x29b2, 0x2091, 0x8000, 0x2071, 0x0000,
- 0x007e, 0x7018, 0xd084, 0x00c0, 0x29b9, 0x007f, 0x2071, 0x0010,
- 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x080f, 0x70df,
- 0x000b, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078,
- 0x29cf, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708e, 0x7592,
- 0x7496, 0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4, 0x0040, 0x29e6,
- 0xa784, 0x007d, 0x00c0, 0x441d, 0x1078, 0x29b2, 0xa49c, 0x000f,
- 0xa382, 0x0004, 0x0050, 0x29f1, 0xa3a6, 0x0007, 0x00c0, 0x29b2,
- 0x2418, 0x8507, 0xa084, 0x000f, 0x0079, 0x29f6, 0x3071, 0x3162,
- 0x318d, 0x33ff, 0x37e8, 0x3862, 0x3917, 0x39a8, 0x3a96, 0x3b85,
- 0x2a09, 0x2a06, 0x2e42, 0x2f65, 0x37b9, 0x2a06, 0x1078, 0x29b2,
- 0x007c, 0xa006, 0x0078, 0x2a13, 0x7808, 0xc08d, 0x780a, 0xa006,
- 0x7002, 0x704e, 0x7046, 0x70d2, 0x7060, 0xa005, 0x00c0, 0x2b79,
- 0x7064, 0xa084, 0x0007, 0x0079, 0x2a1d, 0x2a25, 0x2a98, 0x2aa1,
- 0x2aac, 0x2ab7, 0x2b5f, 0x2ac2, 0x2a98, 0x7830, 0xd0bc, 0x00c0,
- 0x2a08, 0x71d4, 0xd1bc, 0x00c0, 0x2a08, 0xd1b4, 0x00c0, 0x2a75,
- 0x70a4, 0xa086, 0x0001, 0x0040, 0x2a08, 0x70b4, 0xa06d, 0x6800,
- 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, 0x6808, 0xa045,
- 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0040, 0x2a4b,
- 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0010,
- 0x0078, 0x2cd3, 0x7060, 0xa005, 0x00c0, 0x2a08, 0x0c7e, 0x0d7e,
- 0x70b4, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c,
- 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886,
- 0x0001, 0x0040, 0x2a6e, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d,
- 0x6e1c, 0x2001, 0x0020, 0x0078, 0x2cd3, 0x1078, 0x43b0, 0x00c0,
- 0x2a08, 0x781b, 0x005b, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894,
- 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a,
- 0x68bc, 0x7042, 0xc1b4, 0x71d6, 0x70b8, 0xa065, 0x68c0, 0x705a,
- 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c,
- 0x1078, 0x43b0, 0x00c0, 0x2aa0, 0x781b, 0x0047, 0x7003, 0x0004,
- 0x007c, 0x1078, 0x43b0, 0x00c0, 0x2aab, 0x2011, 0x000c, 0x1078,
- 0x2ad2, 0x7003, 0x0004, 0x007c, 0x1078, 0x43b0, 0x00c0, 0x2ab6,
- 0x2011, 0x0006, 0x1078, 0x2ad2, 0x7003, 0x0004, 0x007c, 0x1078,
- 0x43b0, 0x00c0, 0x2ac1, 0x2011, 0x000d, 0x1078, 0x2ad2, 0x7003,
- 0x0004, 0x007c, 0x1078, 0x43b0, 0x00c0, 0x2ad1, 0x2011, 0x0006,
- 0x1078, 0x2ad2, 0x707c, 0x707f, 0x0000, 0x2068, 0x704e, 0x7003,
- 0x0001, 0x007c, 0x7174, 0xc1fc, 0x8107, 0x7882, 0x789b, 0x0010,
- 0xa286, 0x000c, 0x00c0, 0x2ae1, 0x7aaa, 0x2001, 0x0001, 0x0078,
- 0x2af6, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d,
- 0x0040, 0x2aef, 0x7aaa, 0x2001, 0x0002, 0x0078, 0x2af6, 0x78ab,
- 0x0020, 0x7178, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060,
- 0x78aa, 0x785b, 0x0004, 0x781b, 0x0116, 0x1078, 0x43d3, 0x7083,
- 0x000f, 0x70d4, 0xd0b4, 0x0040, 0x2b12, 0xc0b4, 0x70d6, 0x0c7e,
- 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
- 0x601a, 0x0c7f, 0x007c, 0x7014, 0xa005, 0x00c0, 0x2b21, 0x70d4,
- 0xd0b4, 0x0040, 0x2b22, 0x70b8, 0xac06, 0x00c0, 0x2b22, 0x1078,
- 0x2b01, 0x007c, 0x017e, 0x71a4, 0xa186, 0x0001, 0x0040, 0x2b54,
- 0x0d7e, 0x027e, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b4, 0x2068,
- 0x6800, 0xac06, 0x0040, 0x2b3b, 0x8211, 0x0040, 0x2b52, 0x1078,
- 0x2b56, 0x0078, 0x2b30, 0x0c7e, 0x2100, 0x2011, 0x0001, 0xa212,
- 0x70b4, 0x2068, 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef, 0x600a,
- 0x8211, 0x0040, 0x2b4f, 0x1078, 0x2b56, 0x0078, 0x2b42, 0x70a7,
- 0x0001, 0x0c7f, 0x027f, 0x0d7f, 0x017f, 0x007c, 0xade8, 0x0005,
- 0x70ac, 0xad06, 0x00c0, 0x2b5e, 0x70a8, 0x2068, 0x007c, 0x1078,
- 0x43b0, 0x00c0, 0x2a08, 0x707c, 0x2068, 0x7774, 0x1078, 0x424e,
- 0x2c50, 0x1078, 0x4492, 0x789b, 0x0010, 0x6814, 0xa084, 0x001f,
- 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004, 0x0078,
- 0x2cd9, 0x1078, 0x43b0, 0x00c0, 0x2a08, 0x789b, 0x0010, 0x7060,
- 0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0040, 0x2b93, 0xc0b4, 0x70d6,
- 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018,
- 0x8001, 0x601a, 0x0c7f, 0x1078, 0x424e, 0x2c50, 0x1078, 0x4492,
- 0x6824, 0xa005, 0x0040, 0x2ba4, 0xa082, 0x0006, 0x0048, 0x2ba2,
- 0x0078, 0x2ba4, 0x6827, 0x0005, 0x6814, 0xa084, 0x001f, 0xc0bd,
- 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001, 0x2001, 0x0003, 0x0078,
- 0x2cd9, 0xc28d, 0x72d6, 0x72c0, 0xa200, 0xa015, 0x7154, 0x8108,
- 0xa12a, 0x0048, 0x2bbc, 0x71c0, 0x2164, 0x6504, 0x85ff, 0x00c0,
- 0x2bd3, 0x7156, 0x8421, 0x00c0, 0x2bb7, 0x70d4, 0xd08c, 0x0040,
- 0x2bcf, 0x70d0, 0xa005, 0x00c0, 0x2bcf, 0x70d3, 0x000a, 0x007c,
- 0x2200, 0x0078, 0x2bc1, 0x70d4, 0xc08c, 0x70d6, 0x70d3, 0x0000,
- 0x6034, 0xa005, 0x00c0, 0x2bd0, 0x6708, 0xa784, 0x073f, 0x0040,
- 0x2c02, 0xd7d4, 0x00c0, 0x2bd0, 0xa784, 0x0021, 0x00c0, 0x2bd0,
- 0xa784, 0x0002, 0x0040, 0x2bf3, 0xa784, 0x0004, 0x0040, 0x2bd0,
- 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, 0x00c0, 0x2bd0, 0xa784,
- 0x0100, 0x0040, 0x2c02, 0x6018, 0xa005, 0x00c0, 0x2bd0, 0xa7bc,
- 0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e,
- 0x6318, 0x0040, 0x2c13, 0x601c, 0xa302, 0x0048, 0x2c16, 0x0040,
- 0x2c16, 0x0078, 0x2bd0, 0x83ff, 0x00c0, 0x2bd0, 0x2d58, 0x2c50,
- 0x7156, 0xd7bc, 0x00c0, 0x2c1f, 0x7028, 0x6022, 0x603a, 0xc7bc,
- 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041, 0x0001,
- 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0040, 0x2c33,
- 0xd684, 0x0040, 0x2c35, 0xa39c, 0xffbf, 0xd6a4, 0x0040, 0x2c3a,
- 0xa39d, 0x0020, 0xa684, 0x000e, 0x00c0, 0x2c85, 0xc7a5, 0x670a,
- 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c59, 0x70d4,
- 0xd0b4, 0x00c0, 0x2c59, 0x7000, 0xa082, 0x0002, 0x00c8, 0x2c59,
- 0x7830, 0xd0bc, 0x00c0, 0x2c59, 0x789b, 0x0010, 0x7baa, 0x0078,
- 0x2cd1, 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, 0x0005, 0x70ac,
- 0xa606, 0x00c0, 0x2c64, 0x76a8, 0x76b2, 0x2c3a, 0x8738, 0x2d3a,
- 0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830, 0xd0bc,
- 0x0040, 0x2c7c, 0x2091, 0x8000, 0x2091, 0x303d, 0x70d4, 0xa084,
- 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000, 0x0040, 0x2c84,
- 0x8421, 0x2200, 0x00c0, 0x2bb6, 0x007c, 0xd1dc, 0x0040, 0x3e49,
- 0x2029, 0x0020, 0xd69c, 0x00c0, 0x2c92, 0x8528, 0xd68c, 0x00c0,
- 0x2c92, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, 0xa18c, 0x00ff,
- 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0040, 0x2cb1, 0x6014, 0xa706,
- 0x00c0, 0x2c9a, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2c95, 0x2a60,
- 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x00c0, 0x2bb6,
- 0x007c, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840, 0x6008,
- 0xc0d5, 0x600a, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c59, 0x70d4,
- 0xd0b4, 0x00c0, 0x2c59, 0x7000, 0xa082, 0x0002, 0x00c8, 0x2c59,
- 0x7830, 0xd0bc, 0x00c0, 0x2c59, 0x789b, 0x0010, 0x7baa, 0x7daa,
- 0x79aa, 0x2001, 0x0002, 0x007e, 0x6018, 0x8000, 0x601a, 0x0078,
- 0x2cda, 0x007e, 0x2960, 0x6104, 0x2a60, 0xa184, 0x0018, 0x0040,
- 0x2cf6, 0xa184, 0x0010, 0x0040, 0x2ce9, 0x1078, 0x405e, 0x00c0,
- 0x2d1b, 0xa184, 0x0008, 0x0040, 0x2cf6, 0x69a0, 0xa184, 0x0600,
- 0x00c0, 0x2cf6, 0x1078, 0x3f3e, 0x0078, 0x2d1b, 0x69a0, 0xa184,
- 0x1e00, 0x0040, 0x2d26, 0xa184, 0x0800, 0x0040, 0x2d0f, 0x0c7e,
- 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010,
- 0x6106, 0x0c7f, 0x1078, 0x405e, 0x00c0, 0x2d1b, 0x69a0, 0xa184,
- 0x0200, 0x0040, 0x2d17, 0x1078, 0x3fa1, 0x0078, 0x2d1b, 0xa184,
- 0x0400, 0x00c0, 0x2cf2, 0x69a0, 0xa184, 0x1000, 0x0040, 0x2d26,
- 0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x27e6, 0x027f, 0xa68c,
- 0x00e0, 0xa684, 0x0060, 0x0040, 0x2d33, 0xa086, 0x0060, 0x00c0,
- 0x2d33, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, 0x789b, 0x0060,
- 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, 0x0040, 0x2d4e,
- 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0050, 0x2d4c, 0xa08a,
- 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, 0x78aa, 0x3518,
- 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0, 0x789b,
- 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898, 0x25a0,
- 0xa286, 0x0020, 0x00c0, 0x2d86, 0x70d4, 0xc0b5, 0x70d6, 0x2c00,
- 0x70ba, 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, 0x7882, 0xa286,
- 0x0002, 0x0040, 0x2dbc, 0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa498,
- 0x0005, 0x70ac, 0xa306, 0x00c0, 0x2d7e, 0x73a8, 0x73b6, 0xa286,
- 0x0010, 0x0040, 0x2a08, 0x0d7f, 0x0c7f, 0x007c, 0x7000, 0xa005,
- 0x00c0, 0x2d64, 0xa286, 0x0002, 0x00c0, 0x2dd6, 0x1078, 0x43b0,
- 0x00c0, 0x2d64, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x2091, 0x8000,
- 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898,
- 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, 0x780a, 0x127e,
- 0x0d7e, 0x0c7e, 0x70d4, 0xa084, 0x2700, 0x2090, 0x0c7f, 0x0d7f,
- 0x127f, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, 0x0002, 0x2d00,
- 0x704e, 0xad80, 0x0009, 0x7046, 0x7830, 0xd0bc, 0x0040, 0x2dc8,
- 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090,
- 0x70a4, 0xa005, 0x00c0, 0x2dcd, 0x007c, 0x8421, 0x0040, 0x2dcc,
- 0x7250, 0x70c0, 0xa200, 0xa015, 0x0078, 0x2bb6, 0xa286, 0x0010,
- 0x00c0, 0x2e07, 0x1078, 0x43b0, 0x00c0, 0x2d64, 0x6814, 0xc0fc,
- 0x8007, 0x7882, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6,
- 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x70a4,
- 0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, 0xa206, 0x00c0,
- 0x2dfa, 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003,
- 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0x6bb4,
- 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x6b94,
- 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x005b, 0x2900,
- 0x705a, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605, 0x0040,
- 0x2e32, 0x70d4, 0xa084, 0x2700, 0xa086, 0x2300, 0x00c0, 0x2e2c,
- 0x2009, 0x0000, 0x0078, 0x2e2e, 0x2009, 0x0001, 0xa284, 0x000f,
- 0x1079, 0x2e38, 0xad80, 0x0009, 0x7046, 0x2d00, 0x704e, 0x007c,
- 0x2e40, 0x493f, 0x493f, 0x492c, 0x493f, 0x2e40, 0x2e40, 0x2e40,
- 0x1078, 0x29b2, 0x7808, 0xa084, 0xfffd, 0x780a, 0x1078, 0x29a5,
- 0x0f7e, 0x2079, 0x4f00, 0x78ac, 0x0f7f, 0xd084, 0x0040, 0x2e6a,
- 0x7064, 0xa086, 0x0001, 0x00c0, 0x2e58, 0x7066, 0x0078, 0x2f41,
- 0x7064, 0xa086, 0x0005, 0x00c0, 0x2e68, 0x707c, 0x2068, 0x681b,
- 0x0004, 0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822,
- 0x7067, 0x0000, 0x70a7, 0x0000, 0x70a8, 0x70b2, 0x70b6, 0x1078,
- 0x2b01, 0x157e, 0x2011, 0x0004, 0x7164, 0xa186, 0x0001, 0x0040,
- 0x2e8a, 0xa186, 0x0007, 0x00c0, 0x2e81, 0x701f, 0x0005, 0x0078,
- 0x2e8a, 0x701f, 0x0001, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6,
- 0x0078, 0x2e8c, 0x7067, 0x0000, 0x2001, 0x4f0a, 0x2004, 0xa084,
- 0x00ff, 0xa086, 0x0018, 0x0040, 0x2e9c, 0x7018, 0x7016, 0xa005,
- 0x00c0, 0x2e9c, 0x70a7, 0x0001, 0x067e, 0x1078, 0x45d6, 0x20a9,
- 0x0010, 0x2039, 0x0000, 0x1078, 0x4148, 0xa7b8, 0x0100, 0x00f0,
- 0x2ea3, 0x067f, 0x7000, 0x0079, 0x2ead, 0x2ee7, 0x2ec2, 0x2ec2,
- 0x2eb7, 0x2ee7, 0x2ee7, 0x2ee7, 0x2eb5, 0x1078, 0x29b2, 0x7060,
- 0xa005, 0x0040, 0x2ee7, 0xad06, 0x00c0, 0x2ec2, 0x6800, 0x7062,
- 0x0078, 0x2ed4, 0x6820, 0xd084, 0x00c0, 0x2ed0, 0x6f14, 0x1078,
- 0x424e, 0x6008, 0xc0d4, 0x600a, 0x1078, 0x3e19, 0x0078, 0x2ed4,
- 0x705c, 0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818,
- 0xd0fc, 0x0040, 0x2edc, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000,
- 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x1078, 0x2073, 0xb284,
- 0x0400, 0x0040, 0x2eef, 0x2021, 0x96d0, 0x0078, 0x2ef1, 0x2021,
- 0x95c0, 0x1078, 0x2f46, 0xb284, 0x0400, 0x0040, 0x2efb, 0x2021,
- 0x4f98, 0x0078, 0x2efd, 0x2021, 0x4f58, 0x1078, 0x2f46, 0x20a9,
- 0x0101, 0xb284, 0x0400, 0x0040, 0x2f09, 0x2021, 0x95d0, 0x0078,
- 0x2f0b, 0x2021, 0x94c0, 0x1078, 0x2f46, 0x8420, 0x00f0, 0x2f0b,
- 0xb284, 0x0300, 0x0040, 0x2f18, 0x2061, 0x54c0, 0x0078, 0x2f1a,
- 0x2061, 0x74c0, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff,
- 0x0040, 0x2f37, 0x6018, 0x017e, 0x007e, 0x2011, 0x4f02, 0x220c,
- 0xa102, 0x2012, 0x007f, 0x017f, 0xa102, 0x0050, 0x2f37, 0x6012,
- 0x00c0, 0x2f37, 0x2011, 0x4f04, 0x2204, 0xc0a5, 0x2012, 0x601b,
- 0x0000, 0xace0, 0x0010, 0x00f0, 0x2f1e, 0x8421, 0x00c0, 0x2f1c,
- 0x157f, 0x7003, 0x0000, 0x704f, 0x0000, 0x007c, 0x047e, 0x2404,
- 0xa005, 0x0040, 0x2f61, 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6817,
- 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820,
- 0xa084, 0x00ff, 0xc09d, 0x6822, 0x1078, 0x2073, 0x007f, 0x0078,
- 0x2f48, 0x047f, 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050,
- 0x2f6b, 0x1078, 0x29b2, 0x2300, 0x0079, 0x2f6e, 0x2f71, 0x2ffc,
- 0x3019, 0xa282, 0x0002, 0x0040, 0x2f77, 0x1078, 0x29b2, 0x7064,
- 0x7067, 0x0000, 0x7083, 0x0000, 0x0079, 0x2f7e, 0x2f86, 0x2f86,
- 0x2f88, 0x2fc8, 0x3e55, 0x2f86, 0x2fc8, 0x2f86, 0x1078, 0x29b2,
- 0x7774, 0x1078, 0x4148, 0x7774, 0xa7bc, 0x8f00, 0x1078, 0x424e,
- 0x6018, 0xa005, 0x0040, 0x2fbf, 0xd7fc, 0x00c0, 0x2f9b, 0x2021,
- 0x95c0, 0x0078, 0x2f9d, 0x2021, 0x96d0, 0x2009, 0x0005, 0x2011,
- 0x0010, 0x1078, 0x3034, 0x0040, 0x2fbf, 0x157e, 0x20a9, 0x0101,
- 0xd7fc, 0x00c0, 0x2faf, 0x2021, 0x94c0, 0x0078, 0x2fb1, 0x2021,
- 0x95d0, 0x047e, 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, 0x3034,
- 0x047f, 0x0040, 0x2fbe, 0x8420, 0x00f0, 0x2fb1, 0x157f, 0x8738,
- 0xa784, 0x001f, 0x00c0, 0x2f8e, 0x0078, 0x2a0c, 0x0078, 0x2a0c,
- 0x7774, 0x1078, 0x424e, 0x6018, 0xa005, 0x0040, 0x2ffa, 0xd7fc,
- 0x00c0, 0x2fd6, 0x2021, 0x95c0, 0x0078, 0x2fd8, 0x2021, 0x96d0,
- 0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x3034, 0x0040, 0x2ffa,
- 0x157e, 0x20a9, 0x0101, 0xd7fc, 0x00c0, 0x2fea, 0x2021, 0x94c0,
- 0x0078, 0x2fec, 0x2021, 0x95d0, 0x047e, 0x2009, 0x0005, 0x2011,
- 0x0020, 0x1078, 0x3034, 0x047f, 0x0040, 0x2ff9, 0x8420, 0x00f0,
- 0x2fec, 0x157f, 0x0078, 0x2a0c, 0x2200, 0x0079, 0x2fff, 0x3002,
- 0x3004, 0x3004, 0x1078, 0x29b2, 0x2009, 0x0012, 0x7064, 0xa086,
- 0x0002, 0x0040, 0x300d, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0040,
- 0x3012, 0x691a, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078,
- 0x435d, 0x2200, 0x0079, 0x301c, 0x3021, 0x3004, 0x301f, 0x1078,
- 0x29b2, 0x1078, 0x45d6, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3dc7,
- 0x1078, 0x3e36, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3db8,
- 0x0040, 0x3dc7, 0x0078, 0x2a0c, 0x2404, 0xa005, 0x0040, 0x306d,
- 0x2068, 0x2d04, 0x007e, 0x6814, 0xa706, 0x0040, 0x3043, 0x2d20,
- 0x007f, 0x0078, 0x3035, 0x007f, 0x2022, 0x691a, 0x6817, 0x0000,
- 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084,
- 0x00ff, 0xa205, 0x6822, 0x1078, 0x2073, 0x2021, 0x4f02, 0x241c,
- 0x8319, 0x2322, 0x6010, 0x8001, 0x6012, 0x00c0, 0x3064, 0x2021,
- 0x4f04, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a,
- 0x1078, 0x2b22, 0x1078, 0x3e36, 0x007c, 0xa085, 0x0001, 0x0078,
- 0x306c, 0x2300, 0x0079, 0x3074, 0x3079, 0x3077, 0x30f9, 0x1078,
- 0x29b2, 0x78e4, 0xa005, 0x00d0, 0x30af, 0x3208, 0x007e, 0x2001,
- 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x308a, 0xa18c, 0x0300,
- 0x0078, 0x308c, 0xa18c, 0x0400, 0x0040, 0x3092, 0x0018, 0x2a08,
- 0x0078, 0x3094, 0x0028, 0x2a08, 0x2008, 0xa084, 0x0030, 0x00c0,
- 0x309b, 0x0078, 0x37b9, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3099,
- 0x2100, 0xa084, 0x0007, 0x0079, 0x30a5, 0x30d9, 0x30e3, 0x30ce,
- 0x30ad, 0x43a5, 0x43a5, 0x30ad, 0x30ee, 0x1078, 0x29b2, 0x7000,
- 0xa086, 0x0004, 0x00c0, 0x30c9, 0x7064, 0xa086, 0x0002, 0x00c0,
- 0x30bf, 0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x2f65, 0x7064,
- 0xa086, 0x0006, 0x0040, 0x30b9, 0x7064, 0xa086, 0x0004, 0x0040,
- 0x30b9, 0x79e4, 0x2001, 0x0003, 0x0078, 0x3443, 0x6818, 0xd0fc,
- 0x0040, 0x30d4, 0x681b, 0x001d, 0x1078, 0x4118, 0x781b, 0x0064,
- 0x007c, 0x6818, 0xd0fc, 0x0040, 0x30df, 0x681b, 0x001d, 0x1078,
- 0x4118, 0x0078, 0x4381, 0x6818, 0xd0fc, 0x0040, 0x30e9, 0x681b,
- 0x001d, 0x1078, 0x4118, 0x781b, 0x00f8, 0x007c, 0x6818, 0xd0fc,
- 0x0040, 0x30f4, 0x681b, 0x001d, 0x1078, 0x4118, 0x781b, 0x00c8,
- 0x007c, 0xa584, 0x000f, 0x00c0, 0x3118, 0x1078, 0x29a5, 0x7000,
- 0x0079, 0x3102, 0x2a0c, 0x310a, 0x310c, 0x3dc7, 0x3dc7, 0x3dc7,
- 0x310a, 0x310a, 0x1078, 0x29b2, 0x1078, 0x3e36, 0x6008, 0xa084,
- 0xfbef, 0x600a, 0x1078, 0x3db8, 0x0040, 0x3dc7, 0x0078, 0x2a0c,
- 0x78e4, 0xa005, 0x00d0, 0x30af, 0x3208, 0x007e, 0x2001, 0x4f04,
- 0x2004, 0xd0ec, 0x007f, 0x0040, 0x3129, 0xa18c, 0x0300, 0x0078,
- 0x312b, 0xa18c, 0x0400, 0x0040, 0x3131, 0x0018, 0x30af, 0x0078,
- 0x3133, 0x0028, 0x30af, 0x2008, 0xa084, 0x0030, 0x00c0, 0x313b,
- 0x781b, 0x005b, 0x007c, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3138,
- 0x2100, 0xa184, 0x0007, 0x0079, 0x3145, 0x3154, 0x3158, 0x314f,
- 0x314d, 0x43a5, 0x43a5, 0x314d, 0x439f, 0x1078, 0x29b2, 0x1078,
- 0x4120, 0x781b, 0x0064, 0x007c, 0x1078, 0x4120, 0x0078, 0x4381,
- 0x1078, 0x4120, 0x781b, 0x00f8, 0x007c, 0x1078, 0x4120, 0x781b,
- 0x00c8, 0x007c, 0x2300, 0x0079, 0x3165, 0x316a, 0x3168, 0x316c,
- 0x1078, 0x29b2, 0x0078, 0x39a8, 0x681b, 0x0016, 0x78a3, 0x0000,
- 0x79e4, 0xa184, 0x0030, 0x0040, 0x39a8, 0x78ec, 0xa084, 0x0003,
- 0x0040, 0x39a8, 0xa184, 0x0100, 0x0040, 0x3170, 0xa184, 0x0007,
- 0x0079, 0x3182, 0x318a, 0x3158, 0x30ce, 0x435d, 0x43a5, 0x43a5,
- 0x435d, 0x439f, 0x1078, 0x4369, 0x007c, 0xa282, 0x0005, 0x0050,
- 0x3193, 0x1078, 0x29b2, 0x2300, 0x0079, 0x3196, 0x3199, 0x33c9,
- 0x33d4, 0x2200, 0x0079, 0x319c, 0x31b6, 0x31a3, 0x31b6, 0x31a1,
- 0x33ac, 0x1078, 0x29b2, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff,
- 0xa082, 0x0020, 0x0048, 0x4107, 0xa08a, 0x0004, 0x00c8, 0x4107,
- 0x0079, 0x31b2, 0x4107, 0x4107, 0x4107, 0x40b1, 0x789b, 0x0018,
- 0x79a8, 0xa184, 0x0080, 0x0040, 0x31c7, 0x0078, 0x4107, 0x7000,
- 0xa005, 0x00c0, 0x31bd, 0x2011, 0x0004, 0x0078, 0x3b93, 0xa184,
- 0x00ff, 0xa08a, 0x0010, 0x00c8, 0x4107, 0x0079, 0x31cf, 0x31e1,
- 0x31df, 0x31f6, 0x31fa, 0x32cd, 0x4107, 0x4107, 0x32cf, 0x4107,
- 0x4107, 0x33a8, 0x33a8, 0x4107, 0x4107, 0x4107, 0x33aa, 0x1078,
- 0x29b2, 0xd6e4, 0x0040, 0x31ec, 0x2001, 0x0300, 0x8000, 0x8000,
- 0x783a, 0x781b, 0x00c3, 0x007c, 0x6818, 0xd0fc, 0x0040, 0x31f4,
- 0x681b, 0x001d, 0x0078, 0x31e4, 0x0078, 0x435d, 0x681b, 0x001d,
- 0x0078, 0x4111, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0, 0x325f,
- 0x6820, 0xd084, 0x00c0, 0x3265, 0x6818, 0xa086, 0x0008, 0x00c0,
- 0x320b, 0x681b, 0x0000, 0xd6d4, 0x0040, 0x32ca, 0xd6bc, 0x0040,
- 0x324b, 0x7087, 0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d,
- 0x0050, 0x324b, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c,
- 0x718a, 0x789b, 0x0061, 0x78aa, 0x157e, 0x137e, 0x147e, 0x017e,
- 0x3208, 0xa18c, 0x0300, 0x0040, 0x323d, 0x007e, 0x2001, 0x4f04,
- 0x2004, 0xd0ec, 0x007f, 0x0040, 0x3239, 0x20a1, 0x012b, 0x0078,
- 0x323f, 0x20a1, 0x022b, 0x0078, 0x323f, 0x20a1, 0x012b, 0x017f,
- 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6,
- 0x147f, 0x137f, 0x157f, 0x6038, 0xa005, 0x00c0, 0x325a, 0x681c,
- 0xa084, 0x000e, 0x0040, 0x4111, 0x1078, 0x4127, 0x782b, 0x3008,
- 0x0078, 0x325c, 0x8001, 0x603a, 0x781b, 0x0067, 0x007c, 0xd6e4,
- 0x0040, 0x3265, 0x781b, 0x0079, 0x007c, 0xa684, 0x0060, 0x0040,
- 0x32c7, 0xd6dc, 0x0040, 0x32c7, 0xd6fc, 0x00c0, 0x3271, 0x0078,
- 0x3288, 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x801b,
- 0x00c8, 0x327b, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
- 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae,
- 0xd6f4, 0x0040, 0x328e, 0xc6f4, 0x7e5a, 0x6eb6, 0x7000, 0xa086,
- 0x0003, 0x00c0, 0x329c, 0x007e, 0x1078, 0x45d6, 0x1078, 0x493f,
- 0x007f, 0x781b, 0x0076, 0x007c, 0xa006, 0x1078, 0x4a44, 0x6ab0,
- 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040, 0x32ab, 0x2200,
- 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6,
- 0x7bde, 0x2300, 0xa405, 0x00c0, 0x32bb, 0xc6f5, 0x7e5a, 0x6eb6,
- 0x781b, 0x0076, 0x007c, 0x781b, 0x0076, 0x2200, 0xa115, 0x00c0,
- 0x32c4, 0x1078, 0x493f, 0x007c, 0x1078, 0x4977, 0x007c, 0x781b,
- 0x0079, 0x007c, 0x781b, 0x0067, 0x007c, 0x1078, 0x29b2, 0x0078,
- 0x331b, 0x6920, 0xd1c4, 0x0040, 0x32e4, 0xc1c4, 0x6922, 0x0c7e,
- 0x7058, 0x2060, 0x6000, 0xc0e4, 0x6002, 0x6004, 0xa084, 0xfff5,
- 0x6006, 0x0c7f, 0x0078, 0x330f, 0xd1cc, 0x0040, 0x330f, 0xc1cc,
- 0x6922, 0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x6004,
- 0xc0a4, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x330f,
- 0x1078, 0x424a, 0x1078, 0x3f3e, 0x88ff, 0x0040, 0x330f, 0x789b,
- 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0,
- 0x330c, 0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7e58,
- 0xd6d4, 0x00c0, 0x3316, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079,
- 0x007c, 0x0078, 0x410c, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007,
- 0x00c0, 0x3329, 0x6820, 0xa084, 0x0100, 0x0040, 0x3319, 0x2009,
- 0x0008, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001,
- 0x00c0, 0x3345, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040,
- 0x333d, 0x0048, 0x333d, 0x0078, 0x333f, 0x0078, 0x32d1, 0x24a8,
- 0x7aa8, 0x00f0, 0x333f, 0x0078, 0x332b, 0xa284, 0x00f0, 0xa086,
- 0x0020, 0x00c0, 0x3399, 0x8318, 0x8318, 0x2300, 0xa102, 0x0040,
- 0x3355, 0x0048, 0x3355, 0x0078, 0x3396, 0xa286, 0x0023, 0x0040,
- 0x3319, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1,
- 0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x0c7e, 0x7058,
- 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd1a4, 0x0040, 0x3376,
- 0x1078, 0x424a, 0x1078, 0x405e, 0x0078, 0x3384, 0x0c7e, 0x7058,
- 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x330f,
- 0x1078, 0x424a, 0x1078, 0x3f3e, 0x88ff, 0x0040, 0x330f, 0x789b,
- 0x0060, 0x2800, 0x78aa, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x3393,
- 0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7aa8, 0x0078,
- 0x332b, 0x8318, 0x2300, 0xa102, 0x0040, 0x33a2, 0x0048, 0x33a2,
- 0x0078, 0x332b, 0xa284, 0x0080, 0x00c0, 0x4111, 0x0078, 0x410c,
- 0x0078, 0x4111, 0x0078, 0x4107, 0x7058, 0xa04d, 0x789b, 0x0018,
- 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0040, 0x33b9, 0x1078,
- 0x29b2, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a,
- 0x0004, 0x00c8, 0x4107, 0x0079, 0x33c5, 0x4107, 0x3e8f, 0x4107,
- 0x4006, 0xa282, 0x0000, 0x00c0, 0x33cf, 0x1078, 0x29b2, 0x1078,
- 0x4118, 0x781b, 0x0078, 0x007c, 0xa282, 0x0003, 0x00c0, 0x33da,
- 0x1078, 0x29b2, 0xd4fc, 0x00c0, 0x33fa, 0x7064, 0xa005, 0x0040,
- 0x33e3, 0x1078, 0x29b2, 0x6f14, 0x7776, 0xa7bc, 0x8f00, 0x1078,
- 0x424e, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f,
- 0x00c0, 0x33e7, 0x1078, 0x411c, 0x7067, 0x0002, 0x701f, 0x0009,
- 0x0078, 0x33fc, 0x1078, 0x412b, 0x781b, 0x0078, 0x007c, 0xa282,
- 0x0004, 0x0050, 0x3405, 0x1078, 0x29b2, 0x2300, 0x0079, 0x3408,
- 0x340b, 0x35cb, 0x360e, 0xa286, 0x0003, 0x0040, 0x3443, 0x7200,
- 0x7cd8, 0x7ddc, 0x7fd0, 0x71d4, 0xd1bc, 0x00c0, 0x343b, 0xd1b4,
- 0x0040, 0x343b, 0x7868, 0xa084, 0x00ff, 0x00c0, 0x343b, 0xa282,
- 0x0002, 0x00c8, 0x343b, 0x0d7e, 0x783b, 0x8300, 0x781b, 0x004c,
- 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898,
- 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x2001,
- 0x0000, 0x0078, 0x3447, 0x783b, 0x1300, 0x781b, 0x004a, 0x2001,
- 0x0000, 0x0078, 0x3447, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x704a,
- 0x68a0, 0xd0ec, 0x0040, 0x344f, 0x6008, 0xc08d, 0x600a, 0xa284,
- 0x000f, 0x0079, 0x3453, 0x35ab, 0x3460, 0x345d, 0x3711, 0x379d,
- 0x2a0c, 0x345b, 0x345b, 0x1078, 0x29b2, 0x6008, 0xc0d4, 0x600a,
- 0xd6e4, 0x0040, 0x3468, 0x7048, 0xa086, 0x0014, 0x00c0, 0x3488,
- 0x1078, 0x45d6, 0x2009, 0x0000, 0x6818, 0xd0fc, 0x0040, 0x3471,
- 0x7048, 0xa086, 0x0014, 0x0040, 0x3482, 0x6818, 0xa086, 0x0008,
- 0x00c0, 0x3563, 0x7858, 0xd09c, 0x0040, 0x3563, 0x6820, 0xd0ac,
- 0x0040, 0x3563, 0x681b, 0x0014, 0x2009, 0x0002, 0x0078, 0x34c7,
- 0x7868, 0xa08c, 0x00ff, 0x0040, 0x34c7, 0xa186, 0x0008, 0x00c0,
- 0x349e, 0x6008, 0xc0a4, 0x600a, 0x1078, 0x3db8, 0x0040, 0x34c7,
- 0x1078, 0x3e36, 0x1078, 0x45d6, 0x0078, 0x34af, 0xa186, 0x0028,
- 0x00c0, 0x34c7, 0x6018, 0xa005, 0x0040, 0x3491, 0x8001, 0x0040,
- 0x3491, 0x8001, 0x0040, 0x3491, 0x601e, 0x0078, 0x3491, 0x6820,
- 0xd084, 0x0040, 0x2a0c, 0xc084, 0x6822, 0x1078, 0x2b13, 0x705c,
- 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, 0x6802, 0xa005,
- 0x2d00, 0x00c0, 0x34c4, 0x6002, 0x6006, 0x0078, 0x2a0c, 0x017e,
- 0x81ff, 0x00c0, 0x3511, 0x7000, 0xa086, 0x0030, 0x0040, 0x3511,
- 0x71d4, 0xd1bc, 0x00c0, 0x3511, 0xd1b4, 0x00c0, 0x34f8, 0x7060,
- 0xa005, 0x00c0, 0x3511, 0x70a4, 0xa086, 0x0001, 0x0040, 0x3511,
- 0x7003, 0x0000, 0x047e, 0x057e, 0x077e, 0x067e, 0x0c7e, 0x0d7e,
- 0x1078, 0x2a35, 0x0d7f, 0x0c7f, 0x067f, 0x077f, 0x057f, 0x047f,
- 0x71d4, 0xd1b4, 0x00c0, 0x3511, 0x7003, 0x0040, 0x0078, 0x3511,
- 0x1078, 0x43b0, 0x00c0, 0x3511, 0x781b, 0x005b, 0x0d7e, 0x70bc,
- 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
- 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x7808, 0xc08d, 0x780a,
- 0x0d7f, 0x1078, 0x3648, 0x017f, 0x81ff, 0x0040, 0x3563, 0xa684,
- 0xdf00, 0x681e, 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x00c0,
- 0x3564, 0x6818, 0xa086, 0x0014, 0x00c0, 0x352d, 0x2008, 0xd6e4,
- 0x0040, 0x352d, 0x7868, 0xa08c, 0x00ff, 0x1078, 0x2b01, 0x1078,
- 0x2b22, 0x6820, 0xd0dc, 0x00c0, 0x3564, 0x8717, 0xa294, 0x000f,
- 0x8213, 0x8213, 0x8213, 0xb284, 0x0300, 0x0040, 0x3543, 0xa290,
- 0x53c0, 0x0078, 0x3545, 0xa290, 0x5440, 0xa290, 0x0000, 0x221c,
- 0xd3c4, 0x00c0, 0x354d, 0x0078, 0x3553, 0x8210, 0x2204, 0xa085,
- 0x0018, 0x2012, 0x8211, 0xd3d4, 0x0040, 0x355e, 0x68a0, 0xd0c4,
- 0x00c0, 0x355e, 0x1078, 0x36c2, 0x0078, 0x2a0c, 0x6008, 0xc08d,
- 0x600a, 0x0078, 0x3564, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0040,
- 0x356b, 0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff,
- 0x0040, 0x3580, 0x2009, 0x4f02, 0x2104, 0x8001, 0x200a, 0x8421,
- 0x6412, 0x00c0, 0x3580, 0x2021, 0x4f04, 0x2404, 0xc0a5, 0x2022,
- 0x6018, 0xa005, 0x0040, 0x3588, 0x8001, 0x601a, 0x00c0, 0x358b,
- 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, 0x00c0, 0x3597, 0x6800,
- 0xa005, 0x00c0, 0x3594, 0x6002, 0x6006, 0x0078, 0x359b, 0x705c,
- 0x2060, 0x6800, 0x6002, 0x2061, 0x4f00, 0x6887, 0x0103, 0x2d08,
- 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x35aa, 0x2d02,
- 0x0078, 0x35ab, 0x616e, 0x7200, 0xa286, 0x0030, 0x0040, 0x35bb,
- 0xa286, 0x0040, 0x00c0, 0x2a0c, 0x7003, 0x0002, 0x704c, 0x2068,
- 0x68c4, 0x2060, 0x007c, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc,
- 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80,
- 0x0009, 0x7046, 0x007c, 0xa282, 0x0004, 0x0048, 0x35d1, 0x1078,
- 0x29b2, 0x2200, 0x0079, 0x35d4, 0x35d8, 0x35e9, 0x35f6, 0x35e9,
- 0xa586, 0x1300, 0x0040, 0x35e9, 0xa586, 0x8300, 0x00c0, 0x35cf,
- 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef,
- 0x600a, 0x7000, 0xa086, 0x0005, 0x0040, 0x35f3, 0x1078, 0x4118,
- 0x781b, 0x0078, 0x007c, 0x781b, 0x0079, 0x007c, 0x7890, 0x8007,
- 0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c,
- 0x00ff, 0xa186, 0x0003, 0x0040, 0x360b, 0xa186, 0x0000, 0x0040,
- 0x360b, 0x0078, 0x4107, 0x781b, 0x0079, 0x007c, 0x6820, 0xc095,
- 0x6822, 0x82ff, 0x00c0, 0x3618, 0x1078, 0x4118, 0x0078, 0x361f,
- 0x8211, 0x0040, 0x361d, 0x1078, 0x29b2, 0x1078, 0x412b, 0x781b,
- 0x0078, 0x007c, 0x1078, 0x43d3, 0x7830, 0xa084, 0x00c0, 0x00c0,
- 0x3645, 0x017e, 0x3208, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec,
- 0x007f, 0x0040, 0x3637, 0xa18c, 0x0300, 0x0078, 0x3639, 0xa18c,
- 0x0400, 0x017f, 0x0040, 0x3640, 0x0018, 0x3645, 0x0078, 0x3642,
- 0x0028, 0x3645, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c,
- 0xa684, 0x0060, 0x00c0, 0x3652, 0x682f, 0x0000, 0x6833, 0x0000,
- 0x0078, 0x36c1, 0xd6dc, 0x00c0, 0x366a, 0x68b4, 0xd0dc, 0x00c0,
- 0x366a, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x00c0,
- 0x3667, 0x2200, 0xa105, 0x0040, 0x45d6, 0x704b, 0x0015, 0x0078,
- 0x45d6, 0x007c, 0xd6ac, 0x0040, 0x3690, 0xd6f4, 0x0040, 0x3676,
- 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x45d6, 0x68b4, 0xa084,
- 0x4000, 0xa635, 0xd6f4, 0x00c0, 0x3670, 0x7048, 0xa005, 0x00c0,
- 0x3683, 0x704b, 0x0015, 0xd6dc, 0x00c0, 0x368c, 0x68b4, 0xd0dc,
- 0x0040, 0x368c, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0078, 0x45d6,
- 0xd6f4, 0x0040, 0x3699, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078,
- 0x45d6, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x00c0, 0x3693,
- 0x7048, 0xa005, 0x00c0, 0x36a6, 0x704b, 0x0015, 0x2408, 0x2510,
- 0x2700, 0x80fb, 0x00c8, 0x36ad, 0x8000, 0xa084, 0x003f, 0xa108,
- 0xa291, 0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x36ba,
- 0x0078, 0x45d6, 0x7000, 0xa086, 0x0006, 0x0040, 0x36c1, 0x0078,
- 0x45d6, 0x007c, 0x6946, 0x6008, 0xc0cd, 0xd3cc, 0x0040, 0x36c9,
- 0xc08d, 0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f, 0x0000,
- 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003,
- 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020,
- 0x7000, 0x0079, 0x36e3, 0x2a0c, 0x36f5, 0x36ed, 0x36eb, 0x36eb,
- 0x36eb, 0x36eb, 0x36eb, 0x1078, 0x29b2, 0x6820, 0xd084, 0x00c0,
- 0x36f5, 0x1078, 0x3e19, 0x0078, 0x36fb, 0x705c, 0x2c50, 0x2060,
- 0x6800, 0x6002, 0x2a60, 0x3208, 0xa18c, 0x0300, 0x0040, 0x3704,
- 0x2021, 0x4f58, 0x0078, 0x3706, 0x2021, 0x4f98, 0x2404, 0xa005,
- 0x0040, 0x370d, 0x2020, 0x0078, 0x3706, 0x2d22, 0x206b, 0x0000,
- 0x007c, 0x1078, 0x3e20, 0x1078, 0x3e36, 0x6008, 0xc0cc, 0x600a,
- 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x6938, 0x691a, 0x6944,
- 0x6916, 0x3208, 0xa18c, 0x0300, 0x0040, 0x372a, 0x2009, 0x0000,
- 0x0078, 0x372c, 0x2009, 0x0001, 0x1078, 0x4a81, 0xd6dc, 0x0040,
- 0x3734, 0x691c, 0xc1ed, 0x691e, 0x6818, 0xd0fc, 0x0040, 0x3743,
- 0x7868, 0xa08c, 0x00ff, 0x0040, 0x3741, 0x681b, 0x001e, 0x0078,
- 0x3743, 0x681b, 0x0000, 0xb284, 0x0300, 0x00c0, 0x374b, 0x2021,
- 0x4f98, 0x0078, 0x374d, 0x2021, 0x4f58, 0x6800, 0x2022, 0x6a3c,
- 0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4, 0x0040,
- 0x378d, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x0d7e,
- 0x0f7e, 0x157e, 0x147e, 0x2079, 0x4f00, 0x1078, 0x1e46, 0x147f,
- 0x157f, 0x0f7f, 0x70cc, 0x2010, 0x2009, 0x0101, 0x027e, 0x2204,
- 0xa06d, 0x0040, 0x377d, 0x6814, 0xa706, 0x0040, 0x377a, 0x6800,
- 0x0078, 0x3770, 0x6820, 0xc0d5, 0x6822, 0x027f, 0x8210, 0x8109,
- 0x00c0, 0x376e, 0x0d7f, 0x7067, 0x0003, 0x707f, 0x0000, 0x7776,
- 0x7083, 0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x6818, 0xa086, 0x0002,
- 0x00c0, 0x3799, 0x6817, 0x0000, 0x682b, 0x0000, 0x681c, 0xc0ec,
- 0x681e, 0x1078, 0x2073, 0x0078, 0x2a0c, 0x7cd8, 0x7ddc, 0x7fd0,
- 0x1078, 0x3648, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x1078,
- 0x43d7, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc, 0x0040, 0x37b2,
- 0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x7067, 0x0000, 0x0078,
- 0x2a0c, 0x7000, 0xa005, 0x00c0, 0x37bf, 0x0078, 0x2a0c, 0xa006,
- 0x1078, 0x45d6, 0x6920, 0xd1ac, 0x00c0, 0x37c8, 0x681b, 0x0014,
- 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff,
- 0x6822, 0x7000, 0x0079, 0x37d4, 0x2a0c, 0x37de, 0x37de, 0x37e1,
- 0x37e1, 0x37e1, 0x37dc, 0x37dc, 0x1078, 0x29b2, 0x6818, 0x0078,
- 0x3443, 0x6008, 0xc0a4, 0x600a, 0x6817, 0x0000, 0x0078, 0x3dde,
- 0x2300, 0x0079, 0x37eb, 0x37ee, 0x37f0, 0x3860, 0x1078, 0x29b2,
- 0xd6fc, 0x00c0, 0x3847, 0x7000, 0xa00d, 0x0079, 0x37f7, 0x2a0c,
- 0x3801, 0x3801, 0x3831, 0x3801, 0x3844, 0x37ff, 0x37ff, 0x1078,
- 0x29b2, 0xa684, 0x0060, 0x0040, 0x3831, 0xa086, 0x0060, 0x00c0,
- 0x382e, 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x6eb6, 0x681c, 0xc0ac,
- 0x681e, 0xa186, 0x0002, 0x0040, 0x3820, 0x1078, 0x45d6, 0x69ac,
- 0x68b0, 0xa115, 0x0040, 0x3820, 0x1078, 0x4977, 0x0078, 0x3822,
- 0x1078, 0x493f, 0x781b, 0x0079, 0x71d4, 0xd1b4, 0x00c0, 0x2a08,
- 0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a52, 0x007c, 0xd6ec, 0x0040,
- 0x380b, 0x6818, 0xd0fc, 0x0040, 0x3844, 0xd6f4, 0x00c0, 0x383e,
- 0x681b, 0x0015, 0x781b, 0x0079, 0x0078, 0x2a08, 0x681b, 0x0007,
- 0x682f, 0x0000, 0x6833, 0x0000, 0x1078, 0x4369, 0x007c, 0xc6fc,
- 0x7e5a, 0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8, 0x3850, 0x8000,
- 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302,
- 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0079, 0x007c,
- 0x1078, 0x29b2, 0x2300, 0x0079, 0x3865, 0x386a, 0x388f, 0x38ef,
- 0x1078, 0x29b2, 0x7000, 0x0079, 0x386d, 0x3875, 0x3877, 0x3880,
- 0x3875, 0x3875, 0x3875, 0x3875, 0x3875, 0x1078, 0x29b2, 0x69ac,
- 0x68b0, 0xa115, 0x0040, 0x3880, 0x1078, 0x4977, 0x0078, 0x3882,
- 0x1078, 0x493f, 0x681c, 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x00c0,
- 0x2a08, 0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a52, 0x007c, 0xd6fc,
- 0x00c0, 0x38df, 0x7000, 0xa00d, 0x0079, 0x3896, 0x2a0c, 0x38a6,
- 0x38a0, 0x38d6, 0x38a6, 0x38dc, 0x389e, 0x389e, 0x1078, 0x29b2,
- 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060,
- 0x0040, 0x38d6, 0xa086, 0x0060, 0x00c0, 0x38d3, 0xa6b4, 0xbfbf,
- 0xc6ed, 0x7e5a, 0x6eb6, 0xa186, 0x0002, 0x0040, 0x38c2, 0x1078,
- 0x45d6, 0x69ac, 0x68b0, 0xa115, 0x0040, 0x38c2, 0x1078, 0x4977,
- 0x0078, 0x38c4, 0x1078, 0x493f, 0x781b, 0x0079, 0x681c, 0xc0b4,
- 0x681e, 0x71d4, 0xd1b4, 0x00c0, 0x2a08, 0x70a4, 0xa086, 0x0001,
- 0x00c0, 0x2a52, 0x007c, 0xd6ec, 0x0040, 0x38b0, 0x6818, 0xd0fc,
- 0x0040, 0x38dc, 0x681b, 0x0007, 0x781b, 0x00f9, 0x007c, 0xc6fc,
- 0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94,
- 0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b, 0x0079, 0x007c, 0xd6dc,
- 0x0040, 0x38f8, 0x782b, 0x3009, 0x781b, 0x0079, 0x0078, 0x2a08,
- 0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, 0x00c0, 0x390b,
- 0xa484, 0x0200, 0x0040, 0x3905, 0xc6f5, 0xc6dd, 0x7e5a, 0x781b,
- 0x0079, 0x0078, 0x2a08, 0x6820, 0xc095, 0x6822, 0x1078, 0x42e2,
- 0xc6dd, 0x1078, 0x4118, 0x781b, 0x0078, 0x0078, 0x2a08, 0x2300,
- 0x0079, 0x391a, 0x391d, 0x391f, 0x3921, 0x1078, 0x29b2, 0x0078,
- 0x4111, 0xd6d4, 0x00c0, 0x395c, 0x79e4, 0xd1ac, 0x0040, 0x392f,
- 0x78ec, 0xa084, 0x0003, 0x0040, 0x392f, 0x782b, 0x3009, 0x789b,
- 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, 0xd1ac,
- 0x0040, 0x393f, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x3958, 0x2001,
- 0x4f04, 0x2004, 0xd0e4, 0x00c0, 0x3954, 0x6820, 0xd0c4, 0x0040,
- 0x3954, 0x0c7e, 0x7058, 0x2060, 0x6004, 0xc09d, 0x6006, 0x6008,
- 0xa084, 0x00ff, 0x600a, 0x0c7f, 0x2001, 0x0014, 0x0078, 0x3443,
- 0xa184, 0x0007, 0x0079, 0x3992, 0x7a90, 0xa294, 0x0007, 0x789b,
- 0x0060, 0x79a8, 0x81ff, 0x0040, 0x3990, 0x789b, 0x0010, 0x7ba8,
- 0xa384, 0x0001, 0x00c0, 0x3983, 0x7ba8, 0x7ba8, 0xa386, 0x0001,
- 0x00c0, 0x3976, 0x2009, 0xfff7, 0x0078, 0x397c, 0xa386, 0x0003,
- 0x00c0, 0x3983, 0x2009, 0xffef, 0x0c7e, 0x7058, 0x2060, 0x6004,
- 0xa104, 0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684,
- 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xfcff, 0x6922,
- 0x0078, 0x435d, 0x30d9, 0x30e3, 0x399c, 0x39a2, 0x399a, 0x399a,
- 0x435d, 0x435d, 0x1078, 0x29b2, 0x6920, 0xa18c, 0xfcff, 0x6922,
- 0x0078, 0x4363, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x435d,
- 0x79e4, 0xa184, 0x0030, 0x0040, 0x39b2, 0x78ec, 0xa084, 0x0003,
- 0x00c0, 0x39e6, 0x7000, 0xa086, 0x0004, 0x00c0, 0x39cc, 0x7064,
- 0xa086, 0x0002, 0x00c0, 0x39c2, 0x2011, 0x0002, 0x2019, 0x0000,
- 0x0078, 0x2f65, 0x7064, 0xa086, 0x0006, 0x0040, 0x39bc, 0x7064,
- 0xa086, 0x0004, 0x0040, 0x39bc, 0x7000, 0xa086, 0x0000, 0x0040,
- 0x2a08, 0x6920, 0xa184, 0x0420, 0x0040, 0x39db, 0xc1d4, 0x6922,
- 0x6818, 0x0078, 0x3443, 0x6818, 0xa08e, 0x0002, 0x0040, 0x39e4,
- 0xc0fd, 0x681a, 0x2001, 0x0014, 0x0078, 0x3443, 0xa184, 0x0007,
- 0x0079, 0x39ea, 0x435d, 0x435d, 0x39f2, 0x435d, 0x43a5, 0x43a5,
- 0x435d, 0x435d, 0xd6bc, 0x0040, 0x3a34, 0x7184, 0x81ff, 0x0040,
- 0x3a34, 0xa182, 0x000d, 0x00d0, 0x3a01, 0x7087, 0x0000, 0x0078,
- 0x3a06, 0xa182, 0x000c, 0x7086, 0x2009, 0x000c, 0x789b, 0x0061,
- 0x79aa, 0x157e, 0x137e, 0x147e, 0x7088, 0x8114, 0xa210, 0x728a,
- 0xa080, 0x000b, 0xad00, 0x2098, 0xb284, 0x0300, 0x0040, 0x3a28,
- 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x3a24,
- 0x20a1, 0x012b, 0x0078, 0x3a2a, 0x20a1, 0x022b, 0x0078, 0x3a2a,
- 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f,
- 0x137f, 0x157f, 0x0078, 0x4363, 0xd6d4, 0x00c0, 0x3a88, 0x6820,
- 0xd084, 0x0040, 0x4363, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0040,
- 0x3a46, 0xa086, 0x0060, 0x00c0, 0x3a46, 0xc1f5, 0xc194, 0x795a,
- 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818,
- 0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c, 0x0040, 0x3e4f, 0xa18c,
- 0x00f8, 0x00c0, 0x3e4f, 0x157e, 0x137e, 0x147e, 0x017e, 0x3208,
- 0xa18c, 0x0300, 0x0040, 0x3a74, 0x007e, 0x2001, 0x4f04, 0x2004,
- 0xd0ec, 0x007f, 0x0040, 0x3a70, 0x20a1, 0x012b, 0x0078, 0x3a76,
- 0x20a1, 0x022b, 0x0078, 0x3a76, 0x20a1, 0x012b, 0x017f, 0x789b,
- 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f,
- 0x137f, 0x157f, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0078, 0x4363,
- 0x6818, 0xd0fc, 0x0040, 0x3a8e, 0x681b, 0x0008, 0x6820, 0xc0ad,
- 0x6822, 0x1078, 0x4120, 0x781b, 0x00ea, 0x007c, 0x2300, 0x0079,
- 0x3a99, 0x3a9e, 0x3b76, 0x3a9c, 0x1078, 0x29b2, 0x7cd8, 0x7ddc,
- 0x7fd0, 0x82ff, 0x00c0, 0x3ac7, 0x7200, 0xa286, 0x0003, 0x0040,
- 0x3410, 0x71d4, 0xd1bc, 0x00c0, 0x3aca, 0xd1b4, 0x0040, 0x3aca,
- 0x0d7e, 0x783b, 0x8800, 0x781b, 0x004c, 0x70bc, 0xa06d, 0x68b4,
- 0xc0a5, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da,
- 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x0078, 0x3ace, 0x7200,
- 0x0078, 0x3ace, 0x783b, 0x1800, 0x781b, 0x004a, 0xa284, 0x000f,
- 0x0079, 0x3ad2, 0x3b61, 0x3b10, 0x3adc, 0x343f, 0x3ada, 0x3b61,
- 0x3ada, 0x3ada, 0x1078, 0x29b2, 0x681c, 0xd0ec, 0x0040, 0x3ae3,
- 0x6008, 0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, 0x6800, 0x6006,
- 0xa005, 0x00c0, 0x3aec, 0x6002, 0x6008, 0xc0d4, 0x600a, 0x681c,
- 0xa084, 0x000e, 0x00c0, 0x3b00, 0xb284, 0x0300, 0x0040, 0x3afc,
- 0x2009, 0x95c0, 0x0078, 0x3b05, 0x2009, 0x96d0, 0x0078, 0x3b05,
- 0x7030, 0x68ba, 0x7140, 0x70cc, 0xa108, 0x2104, 0x6802, 0x2d0a,
- 0x715e, 0xd6dc, 0x00c0, 0x3b10, 0xc6fc, 0x6eb6, 0x0078, 0x3b61,
- 0x6eb6, 0xa684, 0x0060, 0x00c0, 0x3b1a, 0xa684, 0x7fff, 0x68b6,
- 0x0078, 0x3b61, 0xd6dc, 0x00c0, 0x3b28, 0xa684, 0x7fff, 0x68b6,
- 0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078, 0x45d6, 0x0078, 0x3b61,
- 0xd6ac, 0x0040, 0x3b34, 0xa006, 0x1078, 0x45d6, 0x2408, 0x2510,
- 0x69aa, 0x6aa6, 0x0078, 0x3b44, 0x2408, 0x2510, 0x2700, 0x801b,
- 0x00c8, 0x3b3b, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
- 0x69aa, 0x6aa6, 0x1078, 0x45d6, 0xd6fc, 0x0040, 0x3b61, 0xa684,
- 0x7fff, 0x68b6, 0x2510, 0x2408, 0xd6ac, 0x00c0, 0x3b59, 0x2700,
- 0x801b, 0x00c8, 0x3b54, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291,
- 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303,
- 0x68ae, 0x7000, 0xa086, 0x0030, 0x00c0, 0x2a0c, 0x7003, 0x0002,
- 0x70bc, 0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a,
- 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0xa586, 0x8800,
- 0x00c0, 0x3b83, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008,
- 0xa084, 0xfbef, 0x600a, 0x0078, 0x4111, 0x7047, 0x0000, 0xa282,
- 0x0006, 0x0050, 0x3b8d, 0x1078, 0x29b2, 0x2300, 0x0079, 0x3b90,
- 0x3b93, 0x3ba5, 0x3bb1, 0x2200, 0x0079, 0x3b96, 0x3b9c, 0x4111,
- 0x3b9e, 0x3b9c, 0x3beb, 0x3c40, 0x1078, 0x29b2, 0x7a80, 0xa294,
- 0x0f00, 0x1078, 0x3cca, 0x0078, 0x4107, 0x1078, 0x3bc2, 0x0079,
- 0x3ba9, 0x4111, 0x3baf, 0x3baf, 0x3beb, 0x3baf, 0x4111, 0x1078,
- 0x29b2, 0x1078, 0x3bc2, 0x0079, 0x3bb5, 0x3bbd, 0x3bbb, 0x3bbb,
- 0x3bbd, 0x3bbb, 0x3bbd, 0x1078, 0x29b2, 0x1078, 0x412b, 0x781b,
- 0x0078, 0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3bd3, 0x1078,
- 0x3e36, 0x0078, 0x3bcd, 0x1078, 0x45d6, 0x6008, 0xa084, 0xfbef,
- 0x600a, 0x0078, 0x3bd8, 0x7000, 0xa086, 0x0003, 0x0040, 0x3bcb,
- 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3be2, 0x2001, 0x96e0,
- 0x0078, 0x3be4, 0x2001, 0x9712, 0x2068, 0x704e, 0xad80, 0x0009,
- 0x7046, 0x2200, 0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3bfd,
- 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078,
- 0x3c02, 0x1078, 0x45d6, 0x0078, 0x3c02, 0x7000, 0xa086, 0x0003,
- 0x0040, 0x3bf9, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b,
- 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x95c0, 0xb284,
- 0x0300, 0x00c0, 0x3c16, 0xc2fd, 0x2069, 0x96d0, 0x2d04, 0x2d08,
- 0x715e, 0xa06d, 0x0040, 0x3c23, 0x6814, 0xa206, 0x0040, 0x3c25,
- 0x6800, 0x0078, 0x3c17, 0x1078, 0x3cca, 0x6eb4, 0x7e5a, 0x6920,
- 0xa184, 0x0c00, 0x0040, 0x3cf4, 0x7064, 0xa086, 0x0006, 0x00c0,
- 0x3c37, 0x7074, 0xa206, 0x00c0, 0x3c37, 0x7066, 0x707e, 0x681b,
- 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x4120, 0x0078, 0x3cf4,
- 0x7200, 0xa286, 0x0002, 0x00c0, 0x3c52, 0x70d4, 0xc0b5, 0x70d6,
- 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3c56, 0x1078, 0x45d6,
- 0x0078, 0x3c56, 0xa286, 0x0003, 0x0040, 0x3c4e, 0x7003, 0x0001,
- 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f,
- 0xa215, 0xb284, 0x0300, 0x00c0, 0x3c66, 0xc2fd, 0x79a8, 0x79a8,
- 0xa18c, 0x00ff, 0x2118, 0x70cc, 0xa168, 0x2d04, 0x2d08, 0x715e,
- 0xa06d, 0x0040, 0x3c7a, 0x6814, 0xa206, 0x0040, 0x3ca3, 0x6800,
- 0x0078, 0x3c6e, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3c84,
- 0x2001, 0x96e0, 0x0078, 0x3c86, 0x2001, 0x9712, 0x2068, 0x704e,
- 0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3c8b,
- 0x157f, 0xb284, 0x0300, 0x0040, 0x3c98, 0xc2fc, 0x0078, 0x3c99,
- 0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823,
- 0x0800, 0x6827, 0x0003, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0040,
- 0x3cf4, 0xd0dc, 0x0040, 0x3cbf, 0x7064, 0xa086, 0x0004, 0x00c0,
- 0x3cbb, 0x7074, 0xa206, 0x00c0, 0x3cbb, 0x7078, 0xa306, 0x00c0,
- 0x3cbb, 0x7066, 0x707e, 0x1078, 0x4127, 0x0078, 0x3cf4, 0x681b,
- 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x4120, 0x707f, 0x0000,
- 0x0078, 0x3cf4, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3cd4,
- 0x2001, 0x96e0, 0x0078, 0x3cd6, 0x2001, 0x9712, 0x2068, 0x704e,
- 0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3cdb,
- 0x157f, 0xb284, 0x0300, 0x0040, 0x3ce8, 0xc2fc, 0x0078, 0x3ce9,
- 0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823,
- 0x0800, 0x6827, 0x0003, 0x007c, 0xc6ec, 0xa6ac, 0x0060, 0x0040,
- 0x3d46, 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x00c0, 0x3d21,
- 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa586, 0x0060, 0x0040, 0x3d4b,
- 0xd6f4, 0x00c0, 0x3d0c, 0xc6ed, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009,
- 0x0079, 0xd69c, 0x0040, 0x3d19, 0x2009, 0x0078, 0x2019, 0x0000,
- 0x2320, 0x791a, 0xd6ec, 0x0040, 0x3d56, 0x1078, 0x493f, 0x0078,
- 0x3d56, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x0040,
- 0x3d4d, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x00c0,
- 0x3d32, 0xc6ed, 0xc6f4, 0x7e5a, 0x2011, 0x0079, 0xd69c, 0x0040,
- 0x3d3e, 0x2011, 0x0078, 0x2019, 0x0000, 0x2320, 0x7a1a, 0xd6ec,
- 0x0040, 0x3d56, 0x1078, 0x4977, 0x0078, 0x3d56, 0x2019, 0x0000,
- 0x2320, 0x0078, 0x3d4d, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0079,
- 0xd69c, 0x0040, 0x3d55, 0x2009, 0x0078, 0x791a, 0x68c0, 0x705a,
- 0x2d00, 0x704e, 0x68c4, 0x2060, 0x71d4, 0x2001, 0x4f01, 0x2004,
- 0xd0c4, 0x00c0, 0x3dab, 0x70d8, 0xa02d, 0x0040, 0x3d84, 0xd1bc,
- 0x0040, 0x3d9e, 0x7a80, 0xa294, 0x0f00, 0x70dc, 0xa206, 0x0040,
- 0x3d75, 0x78e0, 0xa504, 0x00c0, 0x3dab, 0x70da, 0xc1bc, 0x71d6,
- 0x0078, 0x3dab, 0x2031, 0x0001, 0x852c, 0x0048, 0x3d83, 0x8633,
- 0x8210, 0x0078, 0x3d7c, 0x007c, 0x7de0, 0xa594, 0xff00, 0x0040,
- 0x3d91, 0x2011, 0x0008, 0x852f, 0x1078, 0x3d7a, 0x8637, 0x0078,
- 0x3d93, 0x1078, 0x3d7a, 0x8217, 0x7880, 0xa084, 0x0f00, 0xa206,
- 0x0040, 0x3dab, 0x72de, 0x76da, 0x0078, 0x3dab, 0x7a80, 0xa294,
- 0x0f00, 0x70dc, 0xa236, 0x0040, 0x3d9b, 0x78e0, 0xa534, 0x0040,
- 0x3d9b, 0xc1bd, 0x71d6, 0xd1b4, 0x00c0, 0x2a08, 0x2300, 0xa405,
- 0x0040, 0x2a08, 0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a52, 0x007c,
- 0x6020, 0xa005, 0x0040, 0x3dc6, 0x8001, 0x6022, 0x6008, 0xa085,
- 0x0008, 0x600a, 0x700f, 0x0100, 0x702c, 0x6026, 0x007c, 0xa006,
- 0x1078, 0x45d6, 0x7000, 0xa086, 0x0002, 0x0040, 0x3dd4, 0x7064,
- 0xa086, 0x0005, 0x00c0, 0x3dde, 0x682b, 0x0000, 0x6817, 0x0000,
- 0x681b, 0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084,
- 0x000f, 0x0079, 0x3de3, 0x2a0c, 0x3df3, 0x3ded, 0x3e15, 0x3dfd,
- 0x2a0c, 0x3deb, 0x3deb, 0x1078, 0x29b2, 0x1078, 0x3e20, 0x1078,
- 0x3e19, 0x0078, 0x3df9, 0x1078, 0x3e20, 0x705c, 0x2060, 0x6800,
- 0x6002, 0x1078, 0x2073, 0x0078, 0x2a0c, 0x7064, 0x7067, 0x0000,
- 0x7083, 0x0000, 0x0079, 0x3e04, 0x3e11, 0x3e11, 0x3e0c, 0x3e0c,
- 0x3e0c, 0x3e11, 0x3e0c, 0x3e11, 0x77d4, 0xc7dd, 0x77d6, 0x0079,
- 0x2f7e, 0x7067, 0x0000, 0x0078, 0x2a0c, 0x681b, 0x0000, 0x0078,
- 0x3711, 0x6800, 0xa005, 0x00c0, 0x3e1e, 0x6002, 0x6006, 0x007c,
- 0x6410, 0x84ff, 0x0040, 0x3e32, 0x2009, 0x4f02, 0x2104, 0x8001,
- 0x200a, 0x8421, 0x6412, 0x00c0, 0x3e32, 0x2021, 0x4f04, 0x2404,
- 0xc0a5, 0x2022, 0x6008, 0xc0a4, 0x600a, 0x007c, 0x6018, 0xa005,
- 0x0040, 0x3e3c, 0x8001, 0x601a, 0x007c, 0x1078, 0x43d3, 0x681b,
- 0x0018, 0x0078, 0x3e7d, 0x1078, 0x43d3, 0x681b, 0x0019, 0x0078,
- 0x3e7d, 0x1078, 0x43d3, 0x681b, 0x001a, 0x0078, 0x3e7d, 0x1078,
- 0x43d3, 0x681b, 0x0003, 0x0078, 0x3e7d, 0x7774, 0x1078, 0x424e,
- 0x7178, 0xa18c, 0x00ff, 0x3210, 0xa294, 0x0300, 0x0040, 0x3e64,
- 0xa1e8, 0x94c0, 0x0078, 0x3e66, 0xa1e8, 0x95d0, 0x2d04, 0x2d08,
- 0x2068, 0xa005, 0x00c0, 0x3e6f, 0x707e, 0x0078, 0x2a0c, 0x6814,
- 0x7274, 0xa206, 0x0040, 0x3e77, 0x6800, 0x0078, 0x3e67, 0x6800,
- 0x200a, 0x681b, 0x0005, 0x707f, 0x0000, 0x1078, 0x3e20, 0x6820,
- 0xd084, 0x00c0, 0x3e85, 0x1078, 0x3e19, 0x1078, 0x3e36, 0x681f,
- 0x0000, 0x6823, 0x0020, 0x1078, 0x2073, 0x0078, 0x2a0c, 0xa282,
- 0x0003, 0x00c0, 0x4107, 0x7da8, 0xa5ac, 0x00ff, 0x7e5a, 0x7ea8,
- 0xa6b4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1c4, 0x0040, 0x3eea,
- 0xc1c4, 0x6922, 0xa6b4, 0x00ff, 0x0040, 0x3ed7, 0xa682, 0x000c,
- 0x0048, 0x3eae, 0x0040, 0x3eae, 0x2031, 0x000c, 0x2500, 0xa086,
- 0x000a, 0x0040, 0x3eb5, 0x852b, 0x852b, 0x1078, 0x41e0, 0x0040,
- 0x3ebd, 0x1078, 0x3fbc, 0x0078, 0x3ee0, 0x1078, 0x419b, 0x0c7e,
- 0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3ff2, 0x0c7f,
- 0x6920, 0xc1c5, 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0,
- 0x3ed4, 0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x0c7e,
- 0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3ff2, 0x0c7f,
- 0x7e58, 0xd6d4, 0x00c0, 0x3ee7, 0x781b, 0x0067, 0x007c, 0x781b,
- 0x0079, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x6100, 0xd1e4, 0x0040,
- 0x3f33, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048,
- 0x3efd, 0x0040, 0x3efd, 0x2011, 0x000c, 0x2600, 0xa202, 0x00c8,
- 0x3f02, 0x2230, 0x6208, 0xa294, 0x00ff, 0x2001, 0x4f05, 0x2004,
- 0xd0e4, 0x00c0, 0x3f17, 0x78ec, 0xd0e4, 0x0040, 0x3f17, 0xa282,
- 0x000a, 0x00c8, 0x3f1d, 0x2011, 0x000a, 0x0078, 0x3f1d, 0xa282,
- 0x000c, 0x00c8, 0x3f1d, 0x2011, 0x000c, 0x2200, 0xa502, 0x00c8,
- 0x3f22, 0x2228, 0x1078, 0x419f, 0x2500, 0xa086, 0x000a, 0x0040,
- 0x3f2b, 0x852b, 0x852b, 0x1078, 0x41e0, 0x0040, 0x3f33, 0x1078,
- 0x3fbc, 0x0078, 0x3f37, 0x1078, 0x419b, 0x1078, 0x3ff2, 0x7858,
- 0xc095, 0x785a, 0x0c7f, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x2960,
- 0x6000, 0xd0e4, 0x00c0, 0x3f58, 0xd0b4, 0x00c0, 0x3f52, 0x6010,
- 0xa084, 0x000f, 0x00c0, 0x3f52, 0x6104, 0xa18c, 0xfff5, 0x6106,
- 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3f83,
- 0x68a0, 0xd0cc, 0x00c0, 0x3f52, 0x6208, 0xa294, 0x00ff, 0x2001,
- 0x4f05, 0x2004, 0xd0e4, 0x00c0, 0x3f71, 0x78ec, 0xd0e4, 0x0040,
- 0x3f71, 0xa282, 0x000b, 0x00c8, 0x3f71, 0x2011, 0x000a, 0x0078,
- 0x3f77, 0xa282, 0x000c, 0x00c8, 0x3f77, 0x2011, 0x000c, 0x6308,
- 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c, 0x0048, 0x3f83, 0x0040,
- 0x3f83, 0x2019, 0x000c, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
- 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822,
- 0x70d4, 0xd0b4, 0x0040, 0x3f9f, 0xc0b4, 0x70d6, 0x70b8, 0xa065,
- 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f,
- 0x007c, 0x0c7e, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x2011,
- 0x0032, 0x2019, 0x0000, 0x0078, 0x3fad, 0x78ab, 0x0001, 0x78ab,
- 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820,
- 0xc0c5, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x7158, 0x2160, 0x2018,
- 0xa08c, 0x0020, 0x0040, 0x3fc5, 0xc0ac, 0x2008, 0xa084, 0xfff0,
- 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4, 0xa084,
- 0xfff0, 0xa18c, 0x000f, 0xa105, 0xc0f4, 0xa39c, 0x0020, 0x0040,
- 0x3fdb, 0xa085, 0x4000, 0xc0fc, 0xd0b4, 0x00c0, 0x3fe0, 0xc0fd,
- 0x78a6, 0x6016, 0x788a, 0xa6b4, 0x000f, 0x8637, 0x8204, 0x8004,
- 0xa084, 0x00ff, 0xa605, 0x600e, 0x6004, 0xa084, 0xfff5, 0x6006,
- 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x6018, 0x789a, 0x78a4,
- 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886,
- 0x600c, 0xa084, 0x00ff, 0x600e, 0x0c7f, 0x007c, 0xa282, 0x0002,
- 0x00c0, 0x4107, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc, 0x0040,
- 0x4041, 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8,
- 0x4107, 0x1078, 0x4094, 0x1078, 0x3ff2, 0xa980, 0x0001, 0x200c,
- 0x1078, 0x424a, 0x1078, 0x3f3e, 0x88ff, 0x0040, 0x4037, 0x789b,
- 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0,
- 0x4034, 0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7e58,
- 0xd6d4, 0x00c0, 0x403e, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079,
- 0x007c, 0xa282, 0x0002, 0x00c8, 0x4049, 0xa284, 0x0001, 0x0040,
- 0x4052, 0x7158, 0xa188, 0x0000, 0x210c, 0xd1ec, 0x00c0, 0x4052,
- 0x2011, 0x0000, 0x1078, 0x417c, 0x1078, 0x4094, 0x1078, 0x3ff2,
- 0x7858, 0xc095, 0x785a, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x027e,
- 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x00c0, 0x4075, 0xd0bc,
- 0x00c0, 0x4073, 0x6014, 0xd0b4, 0x00c0, 0x4073, 0xc1a4, 0x6106,
- 0xa006, 0x0078, 0x4091, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
- 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x70d4, 0xd0b4,
- 0x0040, 0x408d, 0xc0b4, 0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084,
- 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x6820, 0xa085, 0x0200,
- 0x6822, 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x82ff,
- 0x0040, 0x409c, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a,
- 0x78a4, 0xa084, 0xffbf, 0xa205, 0xc0fc, 0xd0b4, 0x00c0, 0x40a9,
- 0xc0fd, 0x78a6, 0x6016, 0x788a, 0x6004, 0xc0a4, 0x6006, 0x0c7f,
- 0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x40ba, 0x007f,
- 0x0078, 0x40bd, 0x007f, 0x0078, 0x4104, 0xd6ac, 0x0040, 0x4104,
- 0x7888, 0xa084, 0x0040, 0x0040, 0x4104, 0x7bb8, 0xa384, 0x003f,
- 0x831b, 0x00c8, 0x40cc, 0x8000, 0xa005, 0x0040, 0x40e1, 0x831b,
- 0x00c8, 0x40d5, 0x8001, 0x0040, 0x4101, 0xd6f4, 0x0040, 0x40e1,
- 0x78b8, 0x801b, 0x00c8, 0x40dd, 0x8000, 0xa084, 0x003f, 0x00c0,
- 0x4101, 0xc6f4, 0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108,
- 0x00c8, 0x40ec, 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade,
- 0x1078, 0x4a44, 0x781b, 0x0076, 0xb284, 0x0300, 0x0040, 0x40fc,
- 0x2001, 0x0000, 0x0078, 0x40fe, 0x2001, 0x0001, 0x1078, 0x48ce,
- 0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0079, 0x007c, 0x1078,
- 0x412f, 0x781b, 0x0078, 0x007c, 0x1078, 0x4118, 0x781b, 0x0078,
- 0x007c, 0x6827, 0x0002, 0x1078, 0x4120, 0x781b, 0x0078, 0x007c,
- 0x2001, 0x0005, 0x0078, 0x4131, 0x2001, 0x000c, 0x0078, 0x4131,
- 0x6820, 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0078, 0x4131, 0x2001,
- 0x000d, 0x0078, 0x4131, 0x2001, 0x0009, 0x0078, 0x4131, 0x2001,
- 0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a, 0x70d4, 0xd0b4,
- 0x0040, 0x4147, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008,
- 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c,
- 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0x017e,
- 0xb28c, 0x0300, 0x0040, 0x4158, 0xa0e0, 0x53c0, 0x0078, 0x415a,
- 0xa0e0, 0x5440, 0x017f, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184,
- 0x000f, 0x0040, 0x416a, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004,
- 0xc09d, 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040,
- 0x0040, 0x417a, 0xa184, 0xffbf, 0xc0fd, 0x78a6, 0x6016, 0x6004,
- 0xc0a5, 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001,
- 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab,
- 0x0004, 0x70d4, 0xd0b4, 0x0040, 0x419a, 0xc0b4, 0x70d6, 0x0c7e,
- 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
- 0x601a, 0x0c7f, 0x007c, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b,
- 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa,
- 0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x70d4, 0xd0b4, 0x0040,
- 0x41be, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084,
- 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c, 0x157e,
- 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a,
- 0x79a4, 0xa18c, 0xfff0, 0x2021, 0x4233, 0x2019, 0x0011, 0x20a9,
- 0x000e, 0x2011, 0x0032, 0x2404, 0xa084, 0xfff0, 0xa106, 0x0040,
- 0x41de, 0x8420, 0x2300, 0xa210, 0x00f0, 0x41d3, 0x157f, 0x007c,
- 0x157e, 0x2001, 0x4f05, 0x2004, 0xd0e4, 0x00c0, 0x4211, 0x2021,
- 0x4241, 0x20a9, 0x0009, 0x2011, 0x0028, 0xa582, 0x0019, 0x0040,
- 0x4227, 0x0048, 0x4227, 0x8420, 0x95a9, 0x2011, 0x0032, 0xa582,
- 0x0032, 0x0040, 0x4227, 0x0048, 0x4227, 0x8420, 0x95a9, 0x2019,
- 0x000a, 0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x4227, 0x0048,
- 0x4227, 0x8420, 0x2300, 0xa210, 0x00f0, 0x4203, 0x157f, 0x0078,
- 0x4225, 0x2021, 0x4233, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011,
- 0x0032, 0x2200, 0xa502, 0x0040, 0x4227, 0x0048, 0x4227, 0x8420,
- 0x2300, 0xa210, 0x00f0, 0x4219, 0x157f, 0xa006, 0x007c, 0x157f,
- 0xa582, 0x0064, 0x00c8, 0x4230, 0x7808, 0xa085, 0x0070, 0x780a,
- 0x2404, 0xa005, 0x007c, 0x1209, 0x3002, 0x3202, 0x4203, 0x4403,
- 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07,
- 0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, 0x7c07,
- 0x7e07, 0x0e00, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784, 0x0f00,
- 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105,
- 0xd7fc, 0x0040, 0x425f, 0xa0e0, 0x74c0, 0x0078, 0x4261, 0xa0e0,
- 0x54c0, 0x007c, 0x0e7e, 0x0f7e, 0xd084, 0x0040, 0x426f, 0x2079,
- 0x0100, 0x2009, 0x4f80, 0x2071, 0x4f80, 0x0078, 0x427f, 0x2009,
- 0x4f40, 0x2071, 0x4f40, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x0040,
- 0x427d, 0x2079, 0x0100, 0x0078, 0x427f, 0x2079, 0x0200, 0x2091,
- 0x8000, 0x2104, 0xa084, 0x000f, 0x0079, 0x4286, 0x4290, 0x4290,
- 0x4290, 0x4290, 0x4290, 0x4290, 0x428e, 0x428e, 0x1078, 0x29b2,
- 0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x0040, 0x42df,
- 0x7858, 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, 0xa086,
- 0x1814, 0x00c0, 0x42df, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
- 0x00c0, 0x42a5, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0,
- 0x42ac, 0x7830, 0xd0bc, 0x00c0, 0x42df, 0x007e, 0x2001, 0x4f04,
- 0x2004, 0xd0ec, 0x007f, 0x0040, 0x42c1, 0xb284, 0x0300, 0x0078,
- 0x42c3, 0xb284, 0x0400, 0x0040, 0x42c9, 0x0018, 0x42df, 0x0078,
- 0x42cb, 0x0028, 0x42df, 0x79e4, 0xa184, 0x0030, 0x0040, 0x42df,
- 0x78ec, 0xa084, 0x0003, 0x0040, 0x42df, 0x681c, 0xd0ac, 0x00c0,
- 0x42dd, 0x1078, 0x4369, 0x0078, 0x42df, 0x781b, 0x00f9, 0x0f7f,
- 0x0e7f, 0x007c, 0x0c7e, 0x2001, 0x4f01, 0x2004, 0xd0ac, 0x00c0,
- 0x435b, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
- 0xb28c, 0x0300, 0x0040, 0x42f8, 0xa0e0, 0x53c0, 0x0078, 0x42fa,
- 0xa0e0, 0x5440, 0x6004, 0xa084, 0x000a, 0x00c0, 0x435b, 0x6108,
- 0xa194, 0xff00, 0x0040, 0x435b, 0xa18c, 0x00ff, 0x2001, 0x000a,
- 0xa106, 0x0040, 0x4326, 0x2001, 0x000c, 0xa106, 0x0040, 0x432a,
- 0x2001, 0x0012, 0xa106, 0x0040, 0x432e, 0x2001, 0x0014, 0xa106,
- 0x0040, 0x4332, 0x2001, 0x0019, 0xa106, 0x0040, 0x4336, 0x2001,
- 0x0032, 0xa106, 0x0040, 0x433a, 0x0078, 0x433e, 0x2009, 0x000c,
- 0x0078, 0x4340, 0x2009, 0x0012, 0x0078, 0x4340, 0x2009, 0x0014,
- 0x0078, 0x4340, 0x2009, 0x0019, 0x0078, 0x4340, 0x2009, 0x0020,
- 0x0078, 0x4340, 0x2009, 0x003f, 0x0078, 0x4340, 0x2011, 0x0000,
- 0x2100, 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x2061,
- 0x4f00, 0x6004, 0xd0bc, 0x0040, 0x435b, 0x6814, 0xd0fc, 0x00c0,
- 0x4356, 0x60ea, 0x2061, 0x4f40, 0x0078, 0x4359, 0x60ee, 0x2061,
- 0x4f80, 0x601f, 0x800f, 0x0c7f, 0x007c, 0x781b, 0x0079, 0x007c,
- 0x781b, 0x0078, 0x007c, 0x781b, 0x0067, 0x007c, 0x781b, 0x0064,
- 0x007c, 0x2009, 0x4f19, 0x210c, 0xa186, 0x0000, 0x0040, 0x437b,
- 0xa186, 0x0001, 0x0040, 0x437e, 0x701f, 0x000b, 0x7067, 0x0001,
- 0x781b, 0x0047, 0x007c, 0x781b, 0x00f0, 0x007c, 0x701f, 0x000a,
- 0x007c, 0x2009, 0x4f19, 0x210c, 0xa186, 0x0000, 0x0040, 0x4396,
- 0xa186, 0x0001, 0x0040, 0x4393, 0x701f, 0x000b, 0x7067, 0x0001,
- 0x781b, 0x0047, 0x007c, 0x701f, 0x000a, 0x007c, 0x781b, 0x00ef,
- 0x007c, 0x781b, 0x00f9, 0x007c, 0x781b, 0x00f8, 0x007c, 0x781b,
- 0x00c9, 0x007c, 0x781b, 0x00c8, 0x007c, 0x6818, 0xd0fc, 0x0040,
- 0x43ab, 0x681b, 0x001d, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c,
- 0x7830, 0xa084, 0x00c0, 0x00c0, 0x43d2, 0x7808, 0xc08c, 0x780a,
- 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x00c0,
- 0x43cf, 0x2001, 0x4f05, 0x2004, 0xd0e4, 0x00c0, 0x43cd, 0x7804,
- 0xa084, 0xff1f, 0xa085, 0x00e0, 0x7806, 0xa006, 0x007c, 0x7808,
- 0xc08d, 0x780a, 0x007c, 0x7808, 0xc08d, 0x780a, 0x007c, 0x7830,
- 0xa084, 0x0040, 0x00c0, 0x43d7, 0x2001, 0x4f04, 0x2004, 0xd0ec,
- 0x0040, 0x43e6, 0xb284, 0x0300, 0x0078, 0x43e8, 0xb284, 0x0400,
- 0x0040, 0x43ee, 0x0098, 0x43f2, 0x0078, 0x43f0, 0x00a8, 0x43f2,
- 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005,
- 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, 0x4415, 0x007e,
- 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x440b, 0xb284,
- 0x0300, 0x0078, 0x440d, 0xb284, 0x0400, 0x0040, 0x4413, 0x0098,
- 0x440f, 0x0078, 0x4415, 0x00a8, 0x4413, 0x78ac, 0x007e, 0x7808,
- 0xa085, 0x0002, 0x780a, 0x007f, 0x007c, 0xa784, 0x0001, 0x00c0,
- 0x37b9, 0xa784, 0x0070, 0x0040, 0x442d, 0x0c7e, 0x2d60, 0x2f68,
- 0x1078, 0x2926, 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040,
- 0x443a, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x37b9,
- 0x0078, 0x435d, 0xa784, 0x0004, 0x0040, 0x4469, 0x78b8, 0xa084,
- 0x4001, 0x0040, 0x4469, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
- 0x0040, 0x37b9, 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0,
- 0x4469, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00f9,
- 0x007c, 0x784b, 0x0008, 0x6818, 0xd0fc, 0x0040, 0x4466, 0x681b,
- 0x0015, 0xd6f4, 0x0040, 0x4466, 0x681b, 0x0007, 0x1078, 0x4369,
- 0x007c, 0x681b, 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f,
- 0x0000, 0x6833, 0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
- 0x0040, 0x30af, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f,
- 0x0040, 0x4486, 0xb284, 0x0300, 0x0078, 0x4488, 0xb284, 0x0400,
- 0x0040, 0x448e, 0x0018, 0x2a08, 0x0078, 0x4490, 0x0028, 0x2a08,
- 0x0078, 0x410c, 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003,
- 0x8003, 0xd3fc, 0x0040, 0x44a0, 0xa080, 0x5440, 0x0078, 0x44a2,
- 0xa080, 0x53c0, 0x2060, 0x2048, 0x705a, 0x2a60, 0x007c, 0x0020,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0062, 0x0009, 0x0014, 0x0014, 0x9848, 0x0014, 0x0014,
- 0x9914, 0x98fd, 0x0014, 0x0014, 0x0080, 0x00ff, 0x0100, 0x0402,
- 0x2008, 0xf880, 0x0018, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014,
- 0x2500, 0x0013, 0x2500, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
- 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
- 0x0010, 0xa200, 0x3806, 0x7102, 0x805f, 0x9481, 0x8839, 0x20c4,
- 0x0864, 0xa856, 0x3008, 0x28c1, 0x9d1b, 0xa201, 0x300c, 0x2847,
- 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a, 0xa808, 0x28e2,
- 0x9ccb, 0xa8f3, 0x0864, 0xa844, 0x300c, 0xa801, 0x3008, 0x28e1,
- 0x9ccb, 0x2021, 0xa81d, 0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0,
- 0x6fc0, 0x63a4, 0x6c80, 0x0212, 0xa205, 0x883d, 0x7942, 0x8020,
- 0xa4a1, 0x882b, 0x1814, 0x883b, 0x80df, 0x94a1, 0x7027, 0x85f2,
- 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa816, 0x883e, 0xa814,
- 0x2001, 0xa812, 0xa204, 0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x7942,
- 0x8020, 0xa4a1, 0x1814, 0x80df, 0x94a1, 0x883b, 0x7023, 0x8576,
- 0x8677, 0xa802, 0x7861, 0x883e, 0x206b, 0x28c1, 0x9d1b, 0x2044,
- 0x2103, 0x20a2, 0x2081, 0xa8c3, 0xa207, 0x0904, 0xa20e, 0xa809,
- 0xa203, 0x8000, 0x85a4, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601,
- 0xa208, 0x856e, 0x866f, 0x7161, 0x0014, 0x0704, 0x3008, 0x9ccb,
- 0x0014, 0xa202, 0x8000, 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844,
- 0x856e, 0x883f, 0x08e6, 0xa8f5, 0xf861, 0xa8ea, 0xf801, 0x0014,
- 0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014,
- 0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014,
- 0x3008, 0x8000, 0x284a, 0x1011, 0xa8fc, 0x3008, 0x9d33, 0x8000,
- 0xa000, 0x2802, 0x1011, 0xa8fd, 0x9d39, 0xa8bd, 0x3008, 0x9d33,
- 0x283b, 0x1011, 0xa8fd, 0xa209, 0x7102, 0x805f, 0x9481, 0x0017,
- 0x300c, 0xa209, 0x8000, 0x85a4, 0x1de2, 0xa209, 0xdac1, 0x0014,
- 0x0210, 0xa801, 0x0014, 0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0,
- 0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d25,
- 0x0704, 0xa206, 0x6865, 0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016,
- 0x6042, 0x8008, 0xa8fa, 0x8000, 0x84a4, 0x8160, 0x842a, 0xf021,
- 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d4, 0x8822,
- 0x0016, 0x7944, 0x8421, 0xa020, 0xa532, 0x84a1, 0x0016, 0x7944,
- 0x8421, 0xa0df, 0x9532, 0x84a1, 0x0016, 0x0000, 0x127e, 0x70d4,
- 0xa084, 0x4600, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205,
- 0x00c0, 0x4602, 0x720c, 0x82ff, 0x0040, 0x45ed, 0x8aff, 0x00c0,
- 0x4602, 0x7200, 0xd284, 0x00c0, 0x4602, 0x7804, 0xd0cc, 0x0040,
- 0x45f3, 0x1078, 0x4acc, 0x7023, 0x0000, 0x7027, 0x0000, 0x7000,
- 0xd084, 0x0040, 0x45fd, 0x7007, 0x0004, 0x7003, 0x0008, 0x127f,
- 0x2000, 0x007c, 0x7000, 0xa084, 0x0003, 0x7002, 0xc69c, 0xd084,
- 0x0040, 0x465b, 0x7108, 0x0005, 0x7008, 0xa106, 0x00c0, 0x460a,
- 0xa184, 0x0003, 0x0040, 0x468c, 0xa184, 0x01e0, 0x00c0, 0x468c,
- 0xd1f4, 0x00c0, 0x460a, 0xa184, 0x3000, 0xa086, 0x1000, 0x0040,
- 0x460a, 0x2001, 0x4f05, 0x2004, 0xd0e4, 0x0040, 0x4637, 0x2011,
- 0x0180, 0x710c, 0x8211, 0x0040, 0x4645, 0x7008, 0xd0f4, 0x00c0,
- 0x460a, 0x700c, 0xa106, 0x0040, 0x462a, 0x0078, 0x4627, 0x2011,
- 0x0180, 0x710c, 0x8211, 0x0040, 0x4645, 0x7008, 0xd0f4, 0x00c0,
- 0x460a, 0x700c, 0xa106, 0x0040, 0x463a, 0x7007, 0x0012, 0x7108,
- 0x0005, 0x7008, 0xa106, 0x00c0, 0x4647, 0xa184, 0x0003, 0x0040,
- 0x468c, 0xd194, 0x0040, 0x4647, 0xd1f4, 0x0040, 0x468c, 0x7007,
- 0x0002, 0x0078, 0x460a, 0x7108, 0xd1fc, 0x0040, 0x4666, 0x1078,
- 0x47ed, 0x8aff, 0x0040, 0x45dc, 0x0078, 0x465b, 0x700c, 0xa08c,
- 0x03ff, 0x0040, 0x4691, 0x7004, 0xd084, 0x0040, 0x4683, 0x7014,
- 0xa005, 0x00c0, 0x467f, 0x7010, 0x7310, 0xa306, 0x00c0, 0x4673,
- 0x2300, 0xa005, 0x0040, 0x4683, 0xa102, 0x00c8, 0x465b, 0x7007,
- 0x0010, 0x0078, 0x468c, 0x8aff, 0x0040, 0x4691, 0x1078, 0x49f2,
- 0x00c0, 0x4686, 0x0040, 0x465b, 0x1078, 0x4738, 0x127f, 0x2000,
- 0x007c, 0x7204, 0x7108, 0xc19c, 0x8103, 0x00c8, 0x46a0, 0x7007,
- 0x0002, 0x0078, 0x4691, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c,
- 0xa205, 0x00c0, 0x468c, 0x7023, 0x0000, 0x7027, 0x0000, 0x7003,
- 0x0008, 0x007e, 0x2001, 0x4f01, 0x2004, 0xd0cc, 0x0040, 0x46b2,
- 0x1078, 0x4acc, 0x007f, 0x127f, 0x2000, 0x007c, 0x6428, 0x84ff,
- 0x0040, 0x46e2, 0x2c70, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x46f2,
- 0x273c, 0x87fb, 0x00c0, 0x46d0, 0x0048, 0x46c8, 0x1078, 0x29b2,
- 0x609c, 0xa075, 0x0040, 0x46e2, 0x0078, 0x46bb, 0x2039, 0x46e7,
- 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, 0xa529, 0x8421, 0x0040,
- 0x46e2, 0x8738, 0x2704, 0xa005, 0x00c0, 0x46d1, 0x709c, 0xa075,
- 0x00c0, 0x46bb, 0x007c, 0x0000, 0x0005, 0x0009, 0x000d, 0x0011,
- 0x0015, 0x0019, 0x001d, 0x0000, 0x0003, 0x0009, 0x000f, 0x0015,
- 0x001b, 0x0000, 0x0000, 0x46e7, 0x46e4, 0x0000, 0x0000, 0x8000,
- 0x0000, 0x46e7, 0x0000, 0x46ef, 0x46ec, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x46ef, 0x0000, 0x46ea, 0x46ea, 0x0000, 0x0000, 0x8000,
- 0x0000, 0x46ea, 0x0000, 0x46f0, 0x46f0, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x46f0, 0x2079, 0x4f00, 0x2071, 0x0010, 0x7007, 0x000a,
- 0x7007, 0x0002, 0x7003, 0x0001, 0x7810, 0xd0ec, 0x0040, 0x4726,
- 0x2009, 0x0001, 0x2071, 0x0020, 0x0078, 0x472a, 0x2009, 0x0002,
- 0x2071, 0x0050, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000,
- 0x8109, 0x0040, 0x4737, 0x2071, 0x0020, 0x0078, 0x472a, 0x007c,
- 0x7004, 0x8004, 0x00c8, 0x47c1, 0x7108, 0x7008, 0xa106, 0x00c0,
- 0x473c, 0xa184, 0x01e0, 0x0040, 0x4749, 0x1078, 0x4830, 0x0078,
- 0x47e9, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108, 0x7008, 0xa106,
- 0x00c0, 0x474d, 0xa184, 0x01e0, 0x0040, 0x475a, 0x1078, 0x4830,
- 0x0078, 0x47e9, 0x7810, 0xd0ec, 0x0040, 0x4774, 0x2001, 0x04fd,
- 0x2004, 0xa086, 0x0003, 0x00c0, 0x4778, 0xa184, 0x4000, 0x0040,
- 0x477c, 0xa382, 0x0003, 0x00c8, 0x477c, 0xa184, 0x0004, 0x0040,
- 0x474d, 0x8318, 0x0078, 0x474d, 0x7814, 0xd0ec, 0x00c0, 0x477c,
- 0xa184, 0x4000, 0x00c0, 0x474d, 0xa19c, 0x300c, 0xa386, 0x2004,
- 0x0040, 0x4799, 0xa386, 0x0008, 0x0040, 0x47a4, 0x7004, 0xd084,
- 0x00c0, 0x4795, 0x7108, 0x7008, 0xa106, 0x00c0, 0x478a, 0xa184,
- 0x0003, 0x0040, 0x4795, 0x0078, 0x4830, 0xa386, 0x200c, 0x00c0,
- 0x474d, 0x7200, 0x8204, 0x0048, 0x47a4, 0x730c, 0xa384, 0x03ff,
- 0x0040, 0x47a4, 0x1078, 0x29b2, 0x7108, 0x7008, 0xa106, 0x00c0,
- 0x47a4, 0xa184, 0x01e0, 0x0040, 0x47b1, 0x1078, 0x4830, 0x0078,
- 0x47e9, 0x7007, 0x0012, 0x7000, 0xd084, 0x00c0, 0x47c1, 0x7310,
- 0x7014, 0xa305, 0x0040, 0x47c1, 0x710c, 0xa184, 0x03ff, 0x00c0,
- 0x4738, 0x7108, 0x7008, 0xa106, 0x00c0, 0x47c1, 0xa184, 0x01e0,
- 0x0040, 0x47ce, 0x1078, 0x4830, 0x0078, 0x47e9, 0x7007, 0x0012,
- 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x47d2, 0x7108, 0x7008,
- 0xa106, 0x00c0, 0x47d6, 0xa184, 0x01e0, 0x0040, 0x47e3, 0x1078,
- 0x4830, 0x0078, 0x47e9, 0x7007, 0x0012, 0x7108, 0x8103, 0x0048,
- 0x47d6, 0x7003, 0x0008, 0x007c, 0x7108, 0xa184, 0x01e0, 0x00c0,
- 0x4830, 0x7108, 0xa184, 0x01e0, 0x00c0, 0x4830, 0xa184, 0x0007,
- 0x0079, 0x47fa, 0x4804, 0x4814, 0x4802, 0x4814, 0x4802, 0x4872,
- 0x4802, 0x4870, 0x1078, 0x29b2, 0x7004, 0xa084, 0x0010, 0xc08d,
- 0x7006, 0x8aff, 0x00c0, 0x480f, 0x2049, 0x0000, 0x007c, 0x1078,
- 0x49f2, 0x00c0, 0x480f, 0x007c, 0x7004, 0xa084, 0x0010, 0xc08d,
- 0x7006, 0x7004, 0xd084, 0x00c0, 0x4828, 0x7108, 0x7008, 0xa106,
- 0x00c0, 0x481d, 0xa184, 0x0003, 0x0040, 0x4828, 0x0078, 0x4830,
- 0x8aff, 0x0040, 0x482f, 0x1078, 0x49f2, 0x00c0, 0x482b, 0x007c,
- 0x7007, 0x0012, 0x7108, 0x00e0, 0x4833, 0x2091, 0x6000, 0x00e0,
- 0x4837, 0x2091, 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004,
- 0xd09c, 0x00c0, 0x483f, 0x7007, 0x0012, 0x7108, 0xd1fc, 0x00c0,
- 0x4843, 0x7003, 0x0000, 0x7000, 0xa005, 0x00c0, 0x4857, 0x7004,
- 0xa005, 0x00c0, 0x4857, 0x700c, 0xa005, 0x0040, 0x4859, 0x0078,
- 0x483b, 0x2049, 0x0000, 0xb284, 0x0100, 0x0040, 0x4863, 0x2001,
- 0x0000, 0x0078, 0x4865, 0x2001, 0x0001, 0x1078, 0x4262, 0x681b,
- 0x0002, 0x2051, 0x0000, 0x007c, 0x1078, 0x29b2, 0x1078, 0x29b2,
- 0x1078, 0x48b9, 0x7210, 0x7114, 0x700c, 0xa09c, 0x03ff, 0x2800,
- 0xa300, 0xa211, 0xa189, 0x0000, 0x1078, 0x48b9, 0x2704, 0x2c58,
- 0xac60, 0x6308, 0x2200, 0xa322, 0x630c, 0x2100, 0xa31b, 0x2400,
- 0xa305, 0x0040, 0x4895, 0x00c8, 0x4895, 0x8412, 0x8210, 0x830a,
- 0xa189, 0x0000, 0x2b60, 0x0078, 0x487c, 0x2b60, 0x8a07, 0x007e,
- 0x6004, 0xd09c, 0x0040, 0x48a0, 0xa7ba, 0x46ec, 0x0078, 0x48a2,
- 0xa7ba, 0x46e4, 0x007f, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92,
- 0x6b8e, 0x7108, 0x7008, 0xa106, 0x00c0, 0x48a9, 0xa184, 0x01e0,
- 0x0040, 0x48b4, 0x1078, 0x4830, 0x7007, 0x0012, 0x1078, 0x4738,
- 0x007c, 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x48cd, 0x6000,
- 0xa064, 0x00c0, 0x48c4, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080,
- 0x4702, 0x203c, 0x87fb, 0x1040, 0x29b2, 0x007c, 0x127e, 0x0d7e,
- 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x6884, 0x2060,
- 0x6888, 0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff,
- 0x007e, 0x6804, 0xa084, 0x0008, 0x007f, 0x0040, 0x48eb, 0xa0b8,
- 0x46ec, 0x0078, 0x48ed, 0xa0b8, 0x46e4, 0xb284, 0x0100, 0x0040,
- 0x48f4, 0x7e20, 0x0078, 0x48f5, 0x7e24, 0xa6b5, 0x000c, 0x681c,
- 0xd0b4, 0x0040, 0x48fc, 0xc685, 0x2400, 0xa305, 0x0040, 0x4925,
- 0x2c58, 0x2704, 0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004,
- 0xa301, 0x701e, 0xd19c, 0x0040, 0x4915, 0x6010, 0xa081, 0x0000,
- 0x7022, 0x6014, 0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202,
- 0x7012, 0x620c, 0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001,
- 0x2b60, 0x1078, 0x4a1c, 0x0078, 0x4927, 0x1078, 0x49f2, 0x00c0,
- 0x4925, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084,
- 0x4600, 0x8004, 0x2090, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xd094,
- 0x00c0, 0x4936, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e,
- 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x007e, 0x2090, 0x007f,
- 0x0d7f, 0x7e20, 0xb284, 0x0100, 0x00c0, 0x494f, 0x7e24, 0xa6b5,
- 0x000c, 0x681c, 0xd0ac, 0x00c0, 0x495a, 0xc685, 0x7003, 0x0000,
- 0x7007, 0x0004, 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f,
- 0xa7b8, 0x46f2, 0x273c, 0x87fb, 0x00c0, 0x4970, 0x0048, 0x496a,
- 0x1078, 0x29b2, 0x689c, 0xa065, 0x0040, 0x4974, 0x0078, 0x495d,
- 0x1078, 0x49f2, 0x00c0, 0x4970, 0x127f, 0x2000, 0x007c, 0x127e,
- 0x007e, 0x017e, 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x007e,
- 0x2090, 0x007f, 0x7e20, 0xb284, 0x0100, 0x00c0, 0x4988, 0x7e24,
- 0x0d7f, 0x037f, 0x047f, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0040,
- 0x4996, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004, 0x2049, 0x4977,
- 0x6828, 0xa055, 0x0d7e, 0x0040, 0x49ee, 0x2d70, 0x2e60, 0x7004,
- 0xa0bc, 0x000f, 0xa7b8, 0x46f2, 0x273c, 0x87fb, 0x00c0, 0x49b3,
- 0x0048, 0x49ac, 0x1078, 0x29b2, 0x709c, 0xa075, 0x2060, 0x0040,
- 0x49ee, 0x0078, 0x499f, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c,
- 0xa31b, 0x0048, 0x49cc, 0x8a51, 0x00c0, 0x49c0, 0x1078, 0x29b2,
- 0x8738, 0x2704, 0xa005, 0x00c0, 0x49b4, 0x709c, 0xa075, 0x2060,
- 0x0040, 0x49ee, 0x0078, 0x499f, 0x8422, 0x8420, 0x831a, 0xa399,
- 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8,
- 0x49db, 0x1078, 0x29b2, 0xb284, 0x0100, 0x0040, 0x49e9, 0x2001,
- 0x4f04, 0x2004, 0xd0ec, 0x00c0, 0x49e9, 0x2071, 0x0050, 0x0078,
- 0x49eb, 0x2071, 0x0020, 0x0d7f, 0x0078, 0x48fc, 0x0d7f, 0x127f,
- 0x2000, 0x007c, 0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040,
- 0x49fb, 0xa006, 0x007c, 0xa084, 0x0003, 0xa086, 0x0003, 0x00c0,
- 0x4a02, 0x007c, 0x2704, 0xac78, 0x7800, 0x701a, 0x7804, 0x701e,
- 0x7808, 0x7012, 0x780c, 0x7016, 0x6004, 0xd09c, 0x0040, 0x4a14,
- 0x7810, 0x7022, 0x7814, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010,
- 0xc085, 0x7006, 0x2079, 0x4f00, 0x8738, 0x8a51, 0x0040, 0x4a40,
- 0x2704, 0xa005, 0x00c0, 0x4a32, 0x609c, 0xa005, 0x0040, 0x4a41,
- 0x2060, 0x6004, 0xa084, 0x000f, 0xa080, 0x46f2, 0x203c, 0x87fb,
- 0x1040, 0x29b2, 0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040,
- 0x4a3c, 0xa006, 0x0078, 0x4a41, 0xa084, 0x0003, 0xa086, 0x0003,
- 0x007c, 0x2051, 0x0000, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x70d4,
- 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x087f, 0x7108, 0xa184,
- 0x0003, 0x00c0, 0x4a59, 0x6828, 0xa005, 0x0040, 0x4a69, 0x0078,
- 0x4602, 0x7108, 0xd1fc, 0x0040, 0x4a61, 0x1078, 0x47ed, 0x0078,
- 0x4a4e, 0x7007, 0x0010, 0x7108, 0xd1fc, 0x0040, 0x4a63, 0x1078,
- 0x47ed, 0x7008, 0xa086, 0x0008, 0x00c0, 0x4a4e, 0x7000, 0xa005,
- 0x00c0, 0x4a4e, 0x7003, 0x0000, 0x2049, 0x0000, 0x007e, 0x7804,
- 0xd0cc, 0x0040, 0x4a7d, 0x1078, 0x4acc, 0x007f, 0x127f, 0x2000,
- 0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x70d4,
- 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x2049, 0x4a81, 0xad80,
- 0x0011, 0x20a0, 0xb284, 0x0100, 0x0040, 0x4aa4, 0x2001, 0x4f04,
- 0x2004, 0xd0ec, 0x0040, 0x4aa0, 0x2099, 0x0031, 0x0078, 0x4aa6,
- 0x2099, 0x0032, 0x0078, 0x4aa6, 0x2099, 0x0031, 0x700c, 0xa084,
- 0x03ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001,
- 0x0040, 0x4ab5, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, 0x03ff,
- 0x0040, 0x4ac1, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
- 0x4abc, 0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000, 0x157f, 0x137f,
- 0x147f, 0x127f, 0x2000, 0x007c, 0x6814, 0xd0fc, 0x0040, 0x4b11,
- 0x7000, 0xd084, 0x0040, 0x4b11, 0x7e24, 0xa6b5, 0x0004, 0x7007,
- 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4ad9, 0x7118, 0x017e,
- 0x711c, 0x017e, 0x7120, 0x017e, 0x7124, 0x017e, 0xa00e, 0x711a,
- 0x701f, 0x3fff, 0x7122, 0x7126, 0x7013, 0x0004, 0x7116, 0x7602,
- 0x7007, 0x0001, 0x2001, 0xffff, 0x2009, 0x0031, 0x200a, 0x200a,
- 0x7108, 0x7008, 0xa106, 0x00c0, 0x4af8, 0xd1fc, 0x0040, 0x4af8,
- 0x027f, 0x7226, 0x027f, 0x7222, 0x027f, 0x721e, 0x027f, 0x721a,
- 0x7007, 0x0002, 0x7008, 0xa086, 0x0008, 0x0040, 0x4b11, 0x0078,
- 0x4830, 0x7007, 0x0004, 0x7003, 0x0000, 0x007c, 0x2091, 0x8000,
- 0x2091, 0x6000, 0x78ac, 0xa005, 0x00c0, 0x4b2d, 0x7974, 0x70d0,
- 0xa106, 0x00c0, 0x4b2d, 0x781c, 0xa005, 0x0040, 0x4b2d, 0x781f,
- 0x0000, 0x0068, 0x4b2d, 0x2091, 0x4080, 0x7830, 0x8001, 0x7832,
- 0x00c0, 0x4bb5, 0x7834, 0x7832, 0x7810, 0xd0ec, 0x00c0, 0x4bae,
- 0x2061, 0x74c0, 0x2069, 0x4f80, 0xc7fd, 0x68d0, 0xa005, 0x0040,
- 0x4b47, 0x8001, 0x68d2, 0x00c0, 0x4b47, 0x1078, 0x4d83, 0x6800,
- 0xa084, 0x000f, 0x0040, 0x4b5c, 0xa086, 0x0001, 0x0040, 0x4b5c,
- 0x6844, 0xa00d, 0x0040, 0x4b5c, 0x2104, 0xa005, 0x0040, 0x4b5c,
- 0x8001, 0x200a, 0x0040, 0x4cf6, 0x6814, 0xa005, 0x0040, 0x4b81,
- 0x8001, 0x6816, 0x00c0, 0x4b81, 0x68a7, 0x0001, 0x0f7e, 0xd7fc,
- 0x00c0, 0x4b76, 0x7810, 0xd0ec, 0x0040, 0x4b72, 0x2079, 0x0100,
- 0x0078, 0x4b78, 0x2079, 0x0200, 0x0078, 0x4b78, 0x2079, 0x0100,
- 0x1078, 0x43d3, 0x0f7f, 0x6864, 0xa005, 0x0040, 0x4b81, 0x1078,
- 0x266f, 0x6880, 0xa005, 0x0040, 0x4b8e, 0x8001, 0x6882, 0x00c0,
- 0x4b8e, 0x6867, 0x0000, 0x68d4, 0xc0dd, 0x68d6, 0x68d4, 0xd0fc,
- 0x0040, 0x4bab, 0xc0fc, 0x68d6, 0x20a9, 0x0200, 0x6034, 0xa005,
- 0x0040, 0x4ba7, 0x8001, 0x6036, 0x68d4, 0xc0fd, 0x68d6, 0x00c0,
- 0x4ba7, 0x6010, 0xa005, 0x0040, 0x4ba7, 0x1078, 0x266f, 0xace0,
- 0x0010, 0x00f0, 0x4b96, 0xd7fc, 0x0040, 0x4bb5, 0x2061, 0x54c0,
- 0x2069, 0x4f40, 0xc7fc, 0x0078, 0x4b3d, 0x1078, 0x4bf1, 0x7838,
- 0x8001, 0x783a, 0x00c0, 0x4bd7, 0x783c, 0x783a, 0x2061, 0x54c0,
- 0x2069, 0x4f40, 0xc7fc, 0x680c, 0xa005, 0x0040, 0x4bc9, 0x1078,
- 0x4c5b, 0xd7fc, 0x00c0, 0x4bd7, 0x7810, 0xd0ec, 0x00c0, 0x4bd7,
- 0x2061, 0x74c0, 0x2069, 0x4f80, 0xc7fd, 0x0078, 0x4bc3, 0x7814,
- 0xd0e4, 0x00c0, 0x4bdb, 0x7810, 0xd0cc, 0x0040, 0x4bee, 0xd0ac,
- 0x00c0, 0x4be7, 0xd0a4, 0x0040, 0x4bee, 0xc0ad, 0x7812, 0x2091,
- 0x8001, 0x0068, 0x4bed, 0x1078, 0x23dc, 0x007c, 0x2091, 0x8001,
- 0x007c, 0x7840, 0x8001, 0x7842, 0x00c0, 0x4c5a, 0x7844, 0x7842,
- 0x2069, 0x4f40, 0xc7fc, 0x7810, 0x2079, 0x0200, 0xd0ec, 0x0040,
- 0x4c03, 0x2079, 0x0100, 0x68d8, 0xa005, 0x0040, 0x4c0f, 0x7de0,
- 0xa504, 0x00c0, 0x4c0f, 0x68da, 0x68d4, 0xc0bc, 0x68d6, 0x2079,
- 0x4f00, 0x6810, 0xa005, 0x00c0, 0x4c17, 0x2001, 0x0101, 0x8001,
- 0x6812, 0xd7fc, 0x0040, 0x4c20, 0xa080, 0x95d0, 0x0078, 0x4c22,
- 0xa080, 0x94c0, 0x2040, 0x2004, 0xa065, 0x0040, 0x4c4c, 0x6024,
- 0xa005, 0x0040, 0x4c48, 0x8001, 0x6026, 0x00c0, 0x4c48, 0x6800,
- 0xa005, 0x0040, 0x4c3b, 0x684c, 0xac06, 0x00c0, 0x4c3b, 0x1078,
- 0x4cf6, 0x0078, 0x4c4c, 0x6864, 0xa005, 0x0040, 0x4c43, 0x6027,
- 0x0001, 0x0078, 0x4c48, 0x1078, 0x4ca9, 0x2804, 0x0078, 0x4c24,
- 0x6000, 0x2c40, 0x0078, 0x4c24, 0xd7fc, 0x00c0, 0x4c5a, 0x7810,
- 0xd0ec, 0x00c0, 0x4c5a, 0x2069, 0x4f80, 0xc7fd, 0x2079, 0x0100,
- 0x0078, 0x4c03, 0x007c, 0x2009, 0x0000, 0x20a9, 0x0200, 0x6008,
- 0xd09c, 0x0040, 0x4c95, 0x6024, 0xa005, 0x0040, 0x4c6b, 0x8001,
- 0x6026, 0x0078, 0x4c93, 0x6008, 0xc09c, 0xd084, 0x00c0, 0x4c73,
- 0xd0ac, 0x0040, 0x4c8d, 0x600a, 0x6004, 0xa005, 0x0040, 0x4c95,
- 0x0d7e, 0x0c7e, 0x017e, 0x2068, 0x6010, 0x8001, 0x6012, 0x1078,
- 0x3e19, 0x2d00, 0x2c68, 0x2060, 0x1078, 0x1ea2, 0x1078, 0x2064,
- 0x017f, 0x0c7f, 0x0d7f, 0x0078, 0x4c95, 0xc0bd, 0x600a, 0xa18d,
- 0x0001, 0x0078, 0x4c95, 0xa18d, 0x0100, 0xace0, 0x0010, 0x00f0,
- 0x4c5f, 0xa184, 0x0001, 0x0040, 0x4ca4, 0xa18c, 0xfffe, 0x690e,
- 0x1078, 0x266f, 0x0078, 0x4ca5, 0x690e, 0x007c, 0x00c0, 0x4ca5,
- 0x786c, 0x2c00, 0x687e, 0x6714, 0x6f76, 0x6017, 0x0000, 0x602b,
- 0x0000, 0x601b, 0x0006, 0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020,
- 0xa084, 0x00ff, 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x1078,
- 0x1e2b, 0x6818, 0xa005, 0x0040, 0x4cc7, 0x8001, 0x681a, 0x6808,
- 0xc0a4, 0x680a, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x00d0,
- 0x4cd3, 0x1078, 0x29b2, 0x6812, 0x00c0, 0x4cd9, 0x7910, 0xc1a5,
- 0x7912, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078, 0x2073,
- 0xd7fc, 0x00c0, 0x4ce7, 0x2069, 0x4f40, 0x0078, 0x4ce9, 0x2069,
- 0x4f80, 0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x00c0, 0x4cf3,
- 0x697a, 0x2001, 0x0004, 0x1078, 0x2663, 0x007c, 0x0d7e, 0x694c,
- 0x2160, 0xd7fc, 0x00c0, 0x4d08, 0x7810, 0xd0ec, 0x0040, 0x4d04,
- 0x2069, 0x0100, 0x0078, 0x4d0a, 0x2069, 0x0200, 0x0078, 0x4d0a,
- 0x2069, 0x0100, 0x1078, 0x2926, 0x601b, 0x0006, 0x6858, 0xa084,
- 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022,
- 0x602f, 0x0000, 0x6033, 0x0000, 0x6808, 0xa084, 0xfffd, 0x680a,
- 0x6830, 0xd0b4, 0x0040, 0x4d3c, 0x684b, 0x0004, 0x20a9, 0x0014,
- 0x6848, 0xd094, 0x0040, 0x4d2e, 0x00f0, 0x4d28, 0x684b, 0x0009,
- 0x20a9, 0x0014, 0x6848, 0xd084, 0x0040, 0x4d38, 0x00f0, 0x4d32,
- 0x20a9, 0x00fa, 0x00f0, 0x4d3a, 0x681b, 0x0047, 0x0d7f, 0x6867,
- 0x0007, 0x007c, 0x2079, 0x4f00, 0x1078, 0x4d76, 0x1078, 0x4d5c,
- 0x1078, 0x4d69, 0x2009, 0x0002, 0x2069, 0x4f80, 0x680f, 0x0000,
- 0x6813, 0x0000, 0x6817, 0x0000, 0x8109, 0x0040, 0x4d5b, 0x2069,
- 0x4f40, 0x0078, 0x4d4e, 0x007c, 0x7810, 0xd0ec, 0x0040, 0x4d64,
- 0x2019, 0x00cc, 0x0078, 0x4d66, 0x2019, 0x007b, 0x7b3a, 0x7b3e,
- 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x4d71, 0x2019, 0x0040, 0x0078,
- 0x4d73, 0x2019, 0x0026, 0x7b42, 0x7b46, 0x007c, 0x7814, 0xd0e4,
- 0x00c0, 0x4d7e, 0x2019, 0x3f94, 0x0078, 0x4d80, 0x2019, 0x2624,
- 0x7b32, 0x7b36, 0x007c, 0x6a50, 0xa285, 0x0000, 0x0040, 0x4daf,
- 0x6954, 0x6bc0, 0xa300, 0x0c7e, 0x2164, 0x6304, 0x83ff, 0x00c0,
- 0x4d9b, 0x8211, 0x0040, 0x4d9f, 0x8108, 0xa11a, 0x0048, 0x4d8c,
- 0x69c0, 0x0078, 0x4d8c, 0x68d3, 0x000a, 0x0c7f, 0x007c, 0x6950,
- 0x6ac0, 0x2264, 0x602b, 0x0000, 0x602f, 0x0000, 0x6008, 0xc0b5,
- 0x600a, 0x8210, 0x8109, 0x00c0, 0x4da1, 0x6952, 0x0c7f, 0x007c,
- 0x00e0, 0x4db0, 0x2091, 0x6000, 0x00e0, 0x4db4, 0x2091, 0x6000,
- 0x70ec, 0xd0dc, 0x00c0, 0x4dc1, 0xd0d4, 0x0040, 0x4dea, 0x0078,
- 0x4ded, 0x2008, 0x7810, 0xd0ec, 0x0040, 0x4dd4, 0xd1c4, 0x00c0,
- 0x4e0e, 0x7814, 0xc0c5, 0x7816, 0x7810, 0xc0f5, 0x7812, 0xd0ec,
- 0x0040, 0x4e0a, 0x0078, 0x4e06, 0xae8e, 0x0100, 0x0040, 0x4de1,
- 0x7814, 0xc0f5, 0xc0c5, 0x7816, 0xd0d4, 0x00c0, 0x4e0a, 0x0078,
- 0x4e06, 0x7814, 0xc0fd, 0xc0c5, 0x7816, 0xd0d4, 0x00c0, 0x4e0a,
- 0x0078, 0x4e06, 0xd0e4, 0x0040, 0x4e0c, 0x00e0, 0x4ded, 0x2091,
- 0x6000, 0x2009, 0x000c, 0x00e0, 0x4df3, 0x2091, 0x6000, 0x8109,
- 0x00c0, 0x4df3, 0x70e4, 0xa084, 0x01ff, 0xa086, 0x01ff, 0x00c0,
- 0x4e04, 0x70ec, 0x0078, 0x4dc1, 0x1078, 0x4e0f, 0x7804, 0xd08c,
- 0x0040, 0x4e0c, 0x681f, 0x000c, 0x70a0, 0x70a2, 0x007c, 0x7910,
- 0xd1ec, 0x0040, 0x4e19, 0x7814, 0xc0c4, 0xc1f4, 0x7912, 0x0078,
- 0x4e2b, 0xae8e, 0x0100, 0x0040, 0x4e25, 0x7814, 0xc0f4, 0xd0fc,
- 0x00c0, 0x4e2b, 0xc0c4, 0x0078, 0x4e2b, 0x7814, 0xc0fc, 0xd0f4,
- 0x00c0, 0x4e2b, 0xc0c4, 0x7816, 0x007c, 0x14e3
-};
-#ifdef UNIQUE_FW_NAME
-static unsigned short fw1280ei_length01 = 0x3e2e;
-#else
-static unsigned short risc_code_length01 = 0x3e2e;
-#endif
-
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index df09820e891..5defe5ea5ed 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -348,6 +348,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -384,11 +385,7 @@
#define MEMORY_MAPPED_IO 1
#endif
-#define UNIQUE_FW_NAME
#include "qla1280.h"
-#include "ql12160_fw.h" /* ISP RISC codes */
-#include "ql1280_fw.h"
-#include "ql1040_fw.h"
#ifndef BITS_PER_LONG
#error "BITS_PER_LONG not defined!"
@@ -541,10 +538,7 @@ __setup("qla1280=", qla1280_setup);
struct qla_boards {
unsigned char name[9]; /* Board ID String */
int numPorts; /* Number of SCSI ports */
- unsigned short *fwcode; /* pointer to FW array */
- unsigned short *fwlen; /* number of words in array */
- unsigned short *fwstart; /* start address for F/W */
- unsigned char *fwver; /* Ptr to F/W version array */
+ char *fwname; /* firmware name */
};
/* NOTE: the last argument in each entry is used to index ql1280_board_tbl */
@@ -567,19 +561,13 @@ MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
static struct qla_boards ql1280_board_tbl[] = {
/* Name , Number of ports, FW details */
- {"QLA12160", 2, &fw12160i_code01[0], &fw12160i_length01,
- &fw12160i_addr01, &fw12160i_version_str[0]},
- {"QLA1040", 1, &risc_code01[0], &risc_code_length01,
- &risc_code_addr01, &firmware_version[0]},
- {"QLA1080", 1, &fw1280ei_code01[0], &fw1280ei_length01,
- &fw1280ei_addr01, &fw1280ei_version_str[0]},
- {"QLA1240", 2, &fw1280ei_code01[0], &fw1280ei_length01,
- &fw1280ei_addr01, &fw1280ei_version_str[0]},
- {"QLA1280", 2, &fw1280ei_code01[0], &fw1280ei_length01,
- &fw1280ei_addr01, &fw1280ei_version_str[0]},
- {"QLA10160", 1, &fw12160i_code01[0], &fw12160i_length01,
- &fw12160i_addr01, &fw12160i_version_str[0]},
- {" ", 0}
+ {"QLA12160", 2, "qlogic/12160.bin"},
+ {"QLA1040", 1, "qlogic/1040.bin"},
+ {"QLA1080", 1, "qlogic/1280.bin"},
+ {"QLA1240", 2, "qlogic/1280.bin"},
+ {"QLA1280", 2, "qlogic/1280.bin"},
+ {"QLA10160", 1, "qlogic/12160.bin"},
+ {" ", 0, " "},
};
static int qla1280_verbose = 1;
@@ -704,7 +692,7 @@ qla1280_info(struct Scsi_Host *host)
sprintf (bp,
"QLogic %s PCI to SCSI Host Adapter\n"
" Firmware version: %2d.%02d.%02d, Driver version %s",
- &bdp->name[0], bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],
+ &bdp->name[0], ha->fwver1, ha->fwver2, ha->fwver3,
QLA1280_VERSION);
return bp;
}
@@ -1648,36 +1636,60 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
static int
qla1280_load_firmware_pio(struct scsi_qla_host *ha)
{
- uint16_t risc_address, *risc_code_address, risc_code_size;
+ const struct firmware *fw;
+ const __le16 *fw_data;
+ uint16_t risc_address, risc_code_size;
uint16_t mb[MAILBOX_REGISTER_COUNT], i;
int err;
+ err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
+ &ha->pdev->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ ql1280_board_tbl[ha->devnum].fwname, err);
+ return err;
+ }
+ if ((fw->size % 2) || (fw->size < 6)) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, ql1280_board_tbl[ha->devnum].fwname);
+ err = -EINVAL;
+ goto out;
+ }
+ ha->fwver1 = fw->data[0];
+ ha->fwver2 = fw->data[1];
+ ha->fwver3 = fw->data[2];
+ fw_data = (const __le16 *)&fw->data[0];
+ ha->fwstart = __le16_to_cpu(fw_data[2]);
+
/* Load RISC code. */
- risc_address = *ql1280_board_tbl[ha->devnum].fwstart;
- risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;
- risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen;
+ risc_address = ha->fwstart;
+ fw_data = (const __le16 *)&fw->data[6];
+ risc_code_size = (fw->size - 6) / 2;
for (i = 0; i < risc_code_size; i++) {
mb[0] = MBC_WRITE_RAM_WORD;
mb[1] = risc_address + i;
- mb[2] = risc_code_address[i];
+ mb[2] = __le16_to_cpu(fw_data[i]);
err = qla1280_mailbox_command(ha, BIT_0 | BIT_1 | BIT_2, mb);
if (err) {
printk(KERN_ERR "scsi(%li): Failed to load firmware\n",
ha->host_no);
- return err;
+ goto out;
}
}
-
- return 0;
+out:
+ release_firmware(fw);
+ return err;
}
#define DUMP_IT_BACK 0 /* for debug of RISC loading */
static int
qla1280_load_firmware_dma(struct scsi_qla_host *ha)
{
- uint16_t risc_address, *risc_code_address, risc_code_size;
+ const struct firmware *fw;
+ const __le16 *fw_data;
+ uint16_t risc_address, risc_code_size;
uint16_t mb[MAILBOX_REGISTER_COUNT], cnt;
int err = 0, num, i;
#if DUMP_IT_BACK
@@ -1689,10 +1701,29 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
return -ENOMEM;
#endif
+ err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
+ &ha->pdev->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ ql1280_board_tbl[ha->devnum].fwname, err);
+ return err;
+ }
+ if ((fw->size % 2) || (fw->size < 6)) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, ql1280_board_tbl[ha->devnum].fwname);
+ err = -EINVAL;
+ goto out;
+ }
+ ha->fwver1 = fw->data[0];
+ ha->fwver2 = fw->data[1];
+ ha->fwver3 = fw->data[2];
+ fw_data = (const __le16 *)&fw->data[0];
+ ha->fwstart = __le16_to_cpu(fw_data[2]);
+
/* Load RISC code. */
- risc_address = *ql1280_board_tbl[ha->devnum].fwstart;
- risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;
- risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen;
+ risc_address = ha->fwstart;
+ fw_data = (const __le16 *)&fw->data[6];
+ risc_code_size = (fw->size - 6) / 2;
dprintk(1, "%s: DMA RISC code (%i) words\n",
__func__, risc_code_size);
@@ -1708,10 +1739,9 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
dprintk(2, "qla1280_setup_chip: loading risc @ =(0x%p),"
"%d,%d(0x%x)\n",
- risc_code_address, cnt, num, risc_address);
+ fw_data, cnt, num, risc_address);
for(i = 0; i < cnt; i++)
- ((__le16 *)ha->request_ring)[i] =
- cpu_to_le16(risc_code_address[i]);
+ ((__le16 *)ha->request_ring)[i] = fw_data[i];
mb[0] = MBC_LOAD_RAM;
mb[1] = risc_address;
@@ -1763,7 +1793,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
#endif
risc_address += cnt;
risc_code_size = risc_code_size - cnt;
- risc_code_address = risc_code_address + cnt;
+ fw_data = fw_data + cnt;
num++;
}
@@ -1771,6 +1801,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
#if DUMP_IT_BACK
pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf);
#endif
+ release_firmware(fw);
return err;
}
@@ -1786,7 +1817,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha)
/* Verify checksum of loaded RISC code. */
mb[0] = MBC_VERIFY_CHECKSUM;
/* mb[1] = ql12_risc_code_addr01; */
- mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
+ mb[1] = ha->fwstart;
err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, mb);
if (err) {
printk(KERN_ERR "scsi(%li): RISC checksum failed.\n", ha->host_no);
@@ -1796,7 +1827,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha)
/* Start firmware execution. */
dprintk(1, "%s: start firmware running.\n", __func__);
mb[0] = MBC_EXECUTE_FIRMWARE;
- mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
+ mb[1] = ha->fwstart;
err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
if (err) {
printk(KERN_ERR "scsi(%li): Failed to start firmware\n",
@@ -4244,8 +4275,8 @@ qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->devnum = devnum; /* specifies microcode load address */
#ifdef QLA_64BIT_PTR
- if (pci_set_dma_mask(ha->pdev, DMA_64BIT_MASK)) {
- if (pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(ha->pdev, DMA_BIT_MASK(64))) {
+ if (pci_set_dma_mask(ha->pdev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "scsi(%li): Unable to set a "
"suitable DMA mask - aborting\n", ha->host_no);
error = -ENODEV;
@@ -4255,7 +4286,7 @@ qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
dprintk(2, "scsi(%li): 64 Bit PCI Addressing Enabled\n",
ha->host_no);
#else
- if (pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(ha->pdev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "scsi(%li): Unable to set a "
"suitable DMA mask - aborting\n", ha->host_no);
error = -ENODEV;
@@ -4450,6 +4481,9 @@ module_exit(qla1280_exit);
MODULE_AUTHOR("Qlogic & Jes Sorensen");
MODULE_DESCRIPTION("Qlogic ISP SCSI (qla1x80/qla1x160) driver");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("qlogic/1040.bin");
+MODULE_FIRMWARE("qlogic/1280.bin");
+MODULE_FIRMWARE("qlogic/12160.bin");
MODULE_VERSION(QLA1280_VERSION);
/*
diff --git a/drivers/scsi/qla1280.h b/drivers/scsi/qla1280.h
index ff2c363ead2..d7c44b8d2b4 100644
--- a/drivers/scsi/qla1280.h
+++ b/drivers/scsi/qla1280.h
@@ -1069,6 +1069,12 @@ struct scsi_qla_host {
struct nvram nvram;
int nvram_valid;
+
+ /* Firmware Info */
+ unsigned short fwstart; /* start address for F/W */
+ unsigned char fwver1; /* F/W version first char */
+ unsigned char fwver2; /* F/W version second char */
+ unsigned char fwver3; /* F/W version third char */
};
#endif /* _QLA1280_H */
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index ee9d4015243..b09993a0657 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -96,7 +96,9 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj,
if (!capable(CAP_SYS_ADMIN))
return 0;
- /* Read NVRAM data from cache. */
+ if (IS_NOCACHE_VPD_TYPE(ha))
+ ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_nvram << 2,
+ ha->nvram_size);
return memory_read_from_buffer(buf, count, &off, ha->nvram,
ha->nvram_size);
}
@@ -111,7 +113,8 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
struct qla_hw_data *ha = vha->hw;
uint16_t cnt;
- if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size)
+ if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size ||
+ !ha->isp_ops->write_nvram)
return 0;
/* Checksum NVRAM. */
@@ -137,12 +140,21 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
*iter = chksum;
}
+ if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
+ qla_printk(KERN_WARNING, ha,
+ "HBA not online, failing NVRAM update.\n");
+ return -EAGAIN;
+ }
+
/* Write NVRAM. */
ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count);
ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base,
count);
+ /* NVRAM settings take effect immediately. */
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+ qla2xxx_wake_dpc(vha);
+ qla2x00_wait_for_chip_reset(vha);
return (count);
}
@@ -330,6 +342,12 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
if (ha->optrom_state != QLA_SWRITING)
break;
+ if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
+ qla_printk(KERN_WARNING, ha,
+ "HBA not online, failing flash update.\n");
+ return -EAGAIN;
+ }
+
DEBUG2(qla_printk(KERN_INFO, ha,
"Writing flash region -- 0x%x/0x%x.\n",
ha->optrom_region_start, ha->optrom_region_size));
@@ -364,7 +382,9 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj,
if (!capable(CAP_SYS_ADMIN))
return 0;
- /* Read NVRAM data from cache. */
+ if (IS_NOCACHE_VPD_TYPE(ha))
+ ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_vpd << 2,
+ ha->vpd_size);
return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size);
}
@@ -376,14 +396,35 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj,
struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
struct device, kobj)));
struct qla_hw_data *ha = vha->hw;
+ uint8_t *tmp_data;
- if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size)
+ if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size ||
+ !ha->isp_ops->write_nvram)
return 0;
+ if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
+ qla_printk(KERN_WARNING, ha,
+ "HBA not online, failing VPD update.\n");
+ return -EAGAIN;
+ }
+
/* Write NVRAM. */
ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count);
ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count);
+ /* Update flash version information for 4Gb & above. */
+ if (!IS_FWI2_CAPABLE(ha))
+ goto done;
+
+ tmp_data = vmalloc(256);
+ if (!tmp_data) {
+ qla_printk(KERN_WARNING, ha,
+ "Unable to allocate memory for VPD information update.\n");
+ goto done;
+ }
+ ha->isp_ops->get_flash_version(vha, tmp_data);
+ vfree(tmp_data);
+done:
return count;
}
@@ -458,6 +499,199 @@ static struct bin_attribute sysfs_sfp_attr = {
.read = qla2x00_sysfs_read_sfp,
};
+static ssize_t
+qla2x00_sysfs_write_reset(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
+ struct device, kobj)));
+ struct qla_hw_data *ha = vha->hw;
+ int type;
+
+ if (off != 0)
+ return 0;
+
+ type = simple_strtol(buf, NULL, 10);
+ switch (type) {
+ case 0x2025c:
+ qla_printk(KERN_INFO, ha,
+ "Issuing ISP reset on (%ld).\n", vha->host_no);
+
+ scsi_block_requests(vha->host);
+ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+ qla2xxx_wake_dpc(vha);
+ qla2x00_wait_for_chip_reset(vha);
+ scsi_unblock_requests(vha->host);
+ break;
+ case 0x2025d:
+ if (!IS_QLA81XX(ha))
+ break;
+
+ qla_printk(KERN_INFO, ha,
+ "Issuing MPI reset on (%ld).\n", vha->host_no);
+
+ /* Make sure FC side is not in reset */
+ qla2x00_wait_for_hba_online(vha);
+
+ /* Issue MPI reset */
+ scsi_block_requests(vha->host);
+ if (qla81xx_restart_mpi_firmware(vha) != QLA_SUCCESS)
+ qla_printk(KERN_WARNING, ha,
+ "MPI reset failed on (%ld).\n", vha->host_no);
+ scsi_unblock_requests(vha->host);
+ break;
+ }
+ return count;
+}
+
+static struct bin_attribute sysfs_reset_attr = {
+ .attr = {
+ .name = "reset",
+ .mode = S_IWUSR,
+ },
+ .size = 0,
+ .write = qla2x00_sysfs_write_reset,
+};
+
+static ssize_t
+qla2x00_sysfs_write_edc(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
+ struct device, kobj)));
+ struct qla_hw_data *ha = vha->hw;
+ uint16_t dev, adr, opt, len;
+ int rval;
+
+ ha->edc_data_len = 0;
+
+ if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8)
+ return 0;
+
+ if (!ha->edc_data) {
+ ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
+ &ha->edc_data_dma);
+ if (!ha->edc_data) {
+ DEBUG2(qla_printk(KERN_INFO, ha,
+ "Unable to allocate memory for EDC write.\n"));
+ return 0;
+ }
+ }
+
+ dev = le16_to_cpup((void *)&buf[0]);
+ adr = le16_to_cpup((void *)&buf[2]);
+ opt = le16_to_cpup((void *)&buf[4]);
+ len = le16_to_cpup((void *)&buf[6]);
+
+ if (!(opt & BIT_0))
+ if (len == 0 || len > DMA_POOL_SIZE || len > count - 8)
+ return -EINVAL;
+
+ memcpy(ha->edc_data, &buf[8], len);
+
+ rval = qla2x00_write_edc(vha, dev, adr, ha->edc_data_dma,
+ ha->edc_data, len, opt);
+ if (rval != QLA_SUCCESS) {
+ DEBUG2(qla_printk(KERN_INFO, ha,
+ "Unable to write EDC (%x) %02x:%02x:%04x:%02x:%02x.\n",
+ rval, dev, adr, opt, len, *buf));
+ return 0;
+ }
+
+ return count;
+}
+
+static struct bin_attribute sysfs_edc_attr = {
+ .attr = {
+ .name = "edc",
+ .mode = S_IWUSR,
+ },
+ .size = 0,
+ .write = qla2x00_sysfs_write_edc,
+};
+
+static ssize_t
+qla2x00_sysfs_write_edc_status(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
+ struct device, kobj)));
+ struct qla_hw_data *ha = vha->hw;
+ uint16_t dev, adr, opt, len;
+ int rval;
+
+ ha->edc_data_len = 0;
+
+ if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8)
+ return 0;
+
+ if (!ha->edc_data) {
+ ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
+ &ha->edc_data_dma);
+ if (!ha->edc_data) {
+ DEBUG2(qla_printk(KERN_INFO, ha,
+ "Unable to allocate memory for EDC status.\n"));
+ return 0;
+ }
+ }
+
+ dev = le16_to_cpup((void *)&buf[0]);
+ adr = le16_to_cpup((void *)&buf[2]);
+ opt = le16_to_cpup((void *)&buf[4]);
+ len = le16_to_cpup((void *)&buf[6]);
+
+ if (!(opt & BIT_0))
+ if (len == 0 || len > DMA_POOL_SIZE)
+ return -EINVAL;
+
+ memset(ha->edc_data, 0, len);
+ rval = qla2x00_read_edc(vha, dev, adr, ha->edc_data_dma,
+ ha->edc_data, len, opt);
+ if (rval != QLA_SUCCESS) {
+ DEBUG2(qla_printk(KERN_INFO, ha,
+ "Unable to write EDC status (%x) %02x:%02x:%04x:%02x.\n",
+ rval, dev, adr, opt, len));
+ return 0;
+ }
+
+ ha->edc_data_len = len;
+
+ return count;
+}
+
+static ssize_t
+qla2x00_sysfs_read_edc_status(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
+ struct device, kobj)));
+ struct qla_hw_data *ha = vha->hw;
+
+ if (!capable(CAP_SYS_ADMIN) || off != 0 || count == 0)
+ return 0;
+
+ if (!ha->edc_data || ha->edc_data_len == 0 || ha->edc_data_len > count)
+ return -EINVAL;
+
+ memcpy(buf, ha->edc_data, ha->edc_data_len);
+
+ return ha->edc_data_len;
+}
+
+static struct bin_attribute sysfs_edc_status_attr = {
+ .attr = {
+ .name = "edc_status",
+ .mode = S_IRUSR | S_IWUSR,
+ },
+ .size = 0,
+ .write = qla2x00_sysfs_write_edc_status,
+ .read = qla2x00_sysfs_read_edc_status,
+};
+
static struct sysfs_entry {
char *name;
struct bin_attribute *attr;
@@ -469,6 +703,9 @@ static struct sysfs_entry {
{ "optrom_ctl", &sysfs_optrom_ctl_attr, },
{ "vpd", &sysfs_vpd_attr, 1 },
{ "sfp", &sysfs_sfp_attr, 1 },
+ { "reset", &sysfs_reset_attr, },
+ { "edc", &sysfs_edc_attr, 2 },
+ { "edc_status", &sysfs_edc_status_attr, 2 },
{ NULL },
};
@@ -482,6 +719,8 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha)
for (iter = bin_file_entries; iter->name; iter++) {
if (iter->is4GBp_only && !IS_FWI2_CAPABLE(vha->hw))
continue;
+ if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw))
+ continue;
ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
iter->attr);
@@ -502,6 +741,8 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha)
for (iter = bin_file_entries; iter->name; iter++) {
if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha))
continue;
+ if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha))
+ continue;
sysfs_remove_bin_file(&host->shost_gendev.kobj,
iter->attr);
@@ -818,9 +1059,33 @@ qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr,
if (!IS_QLA81XX(ha))
return snprintf(buf, PAGE_SIZE, "\n");
- return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x (%x)\n",
+ return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n",
ha->mpi_version[0], ha->mpi_version[1], ha->mpi_version[2],
- ha->mpi_version[3], ha->mpi_capabilities);
+ ha->mpi_capabilities);
+}
+
+static ssize_t
+qla2x00_phy_version_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+ struct qla_hw_data *ha = vha->hw;
+
+ if (!IS_QLA81XX(ha))
+ return snprintf(buf, PAGE_SIZE, "\n");
+
+ return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n",
+ ha->phy_version[0], ha->phy_version[1], ha->phy_version[2]);
+}
+
+static ssize_t
+qla2x00_flash_block_size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+ struct qla_hw_data *ha = vha->hw;
+
+ return snprintf(buf, PAGE_SIZE, "0x%x\n", ha->fdt_block_size);
}
static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
@@ -848,6 +1113,9 @@ static DEVICE_ATTR(optrom_fw_version, S_IRUGO, qla2x00_optrom_fw_version_show,
static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show,
NULL);
static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL);
+static DEVICE_ATTR(phy_version, S_IRUGO, qla2x00_phy_version_show, NULL);
+static DEVICE_ATTR(flash_block_size, S_IRUGO, qla2x00_flash_block_size_show,
+ NULL);
struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_driver_version,
@@ -868,6 +1136,8 @@ struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_optrom_fw_version,
&dev_attr_total_isp_aborts,
&dev_attr_mpi_version,
+ &dev_attr_phy_version,
+ &dev_attr_flash_block_size,
NULL,
};
@@ -1012,7 +1282,10 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
if (!fcport)
return;
- qla2x00_abort_fcport_cmds(fcport);
+ if (unlikely(pci_channel_offline(fcport->vha->hw->pdev)))
+ qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
+ else
+ qla2x00_abort_fcport_cmds(fcport);
/*
* Transport has effectively 'deleted' the rport, clear
@@ -1032,16 +1305,18 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
if (!fcport)
return;
+ if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) {
+ qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
+ return;
+ }
/*
* At this point all fcport's software-states are cleared. Perform any
* final cleanup of firmware resources (PCBs and XCBs).
*/
- if (fcport->loop_id != FC_NO_LOOP_ID) {
+ if (fcport->loop_id != FC_NO_LOOP_ID)
fcport->vha->hw->isp_ops->fabric_logout(fcport->vha,
fcport->loop_id, fcport->d_id.b.domain,
fcport->d_id.b.area, fcport->d_id.b.al_pa);
- fcport->loop_id = FC_NO_LOOP_ID;
- }
qla2x00_abort_fcport_cmds(fcport);
}
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index e0c5bb54b25..714ee67567e 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -176,8 +176,7 @@
/* ISP request and response entry counts (37-65535) */
#define REQUEST_ENTRY_CNT_2100 128 /* Number of request entries. */
#define REQUEST_ENTRY_CNT_2200 2048 /* Number of request entries. */
-#define REQUEST_ENTRY_CNT_2XXX_EXT_MEM 4096 /* Number of request entries. */
-#define REQUEST_ENTRY_CNT_24XX 4096 /* Number of request entries. */
+#define REQUEST_ENTRY_CNT_24XX 2048 /* Number of request entries. */
#define RESPONSE_ENTRY_CNT_2100 64 /* Number of response entries.*/
#define RESPONSE_ENTRY_CNT_2300 512 /* Number of response entries.*/
@@ -201,20 +200,7 @@ typedef struct srb {
/*
* SRB flag definitions
*/
-#define SRB_TIMEOUT BIT_0 /* Command timed out */
-#define SRB_DMA_VALID BIT_1 /* Command sent to ISP */
-#define SRB_WATCHDOG BIT_2 /* Command on watchdog list */
-#define SRB_ABORT_PENDING BIT_3 /* Command abort sent to device */
-
-#define SRB_ABORTED BIT_4 /* Command aborted command already */
-#define SRB_RETRY BIT_5 /* Command needs retrying */
-#define SRB_GOT_SENSE BIT_6 /* Command has sense data */
-#define SRB_FAILOVER BIT_7 /* Command in failover state */
-
-#define SRB_BUSY BIT_8 /* Command is in busy retry state */
-#define SRB_FO_CANCEL BIT_9 /* Command don't need to do failover */
-#define SRB_IOCTL BIT_10 /* IOCTL command. */
-#define SRB_TAPE BIT_11 /* FCP2 (Tape) command. */
+#define SRB_DMA_VALID BIT_0 /* Command sent to ISP */
/*
* ISP I/O Register Set structure definitions.
@@ -372,10 +358,10 @@ struct device_reg_2xxx {
};
struct device_reg_25xxmq {
- volatile uint32_t req_q_in;
- volatile uint32_t req_q_out;
- volatile uint32_t rsp_q_in;
- volatile uint32_t rsp_q_out;
+ uint32_t req_q_in;
+ uint32_t req_q_out;
+ uint32_t rsp_q_in;
+ uint32_t rsp_q_out;
};
typedef union {
@@ -620,6 +606,7 @@ typedef struct {
#define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */
#define MBC_TRACE_CONTROL 0x27 /* Trace control command. */
#define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */
+#define MBC_WRITE_SFP 0x30 /* Write SFP Data. */
#define MBC_READ_SFP 0x31 /* Read SFP Data. */
#define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */
#define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */
@@ -1570,39 +1557,13 @@ typedef struct fc_port {
#define FCS_DEVICE_DEAD 2
#define FCS_DEVICE_LOST 3
#define FCS_ONLINE 4
-#define FCS_NOT_SUPPORTED 5
-#define FCS_FAILOVER 6
-#define FCS_FAILOVER_FAILED 7
/*
* FC port flags.
*/
#define FCF_FABRIC_DEVICE BIT_0
#define FCF_LOGIN_NEEDED BIT_1
-#define FCF_FO_MASKED BIT_2
-#define FCF_FAILOVER_NEEDED BIT_3
-#define FCF_RESET_NEEDED BIT_4
-#define FCF_PERSISTENT_BOUND BIT_5
-#define FCF_TAPE_PRESENT BIT_6
-#define FCF_FARP_DONE BIT_7
-#define FCF_FARP_FAILED BIT_8
-#define FCF_FARP_REPLY_NEEDED BIT_9
-#define FCF_AUTH_REQ BIT_10
-#define FCF_SEND_AUTH_REQ BIT_11
-#define FCF_RECEIVE_AUTH_REQ BIT_12
-#define FCF_AUTH_SUCCESS BIT_13
-#define FCF_RLC_SUPPORT BIT_14
-#define FCF_CONFIG BIT_15 /* Needed? */
-#define FCF_RESCAN_NEEDED BIT_16
-#define FCF_XP_DEVICE BIT_17
-#define FCF_MSA_DEVICE BIT_18
-#define FCF_EVA_DEVICE BIT_19
-#define FCF_MSA_PORT_ACTIVE BIT_20
-#define FCF_FAILBACK_DISABLE BIT_21
-#define FCF_FAILOVER_DISABLE BIT_22
-#define FCF_DSXXX_DEVICE BIT_23
-#define FCF_AA_EVA_DEVICE BIT_24
-#define FCF_AA_MSA_DEVICE BIT_25
+#define FCF_TAPE_PRESENT BIT_2
/* No loop ID flag. */
#define FC_NO_LOOP_ID 0x1000
@@ -2102,9 +2063,6 @@ struct isp_operations {
int (*get_flash_version) (struct scsi_qla_host *, void *);
int (*start_scsi) (srb_t *);
- void (*wrt_req_reg) (struct qla_hw_data *, uint16_t, uint16_t);
- void (*wrt_rsp_reg) (struct qla_hw_data *, uint16_t, uint16_t);
- uint16_t (*rd_req_reg) (struct qla_hw_data *, uint16_t);
};
/* MSI-X Support *************************************************************/
@@ -2200,6 +2158,8 @@ struct rsp_que {
dma_addr_t dma;
response_t *ring;
response_t *ring_ptr;
+ uint32_t __iomem *rsp_q_in; /* FWI2-capable only. */
+ uint32_t __iomem *rsp_q_out;
uint16_t ring_index;
uint16_t out_ptr;
uint16_t length;
@@ -2217,6 +2177,8 @@ struct req_que {
dma_addr_t dma;
request_t *ring;
request_t *ring_ptr;
+ uint32_t __iomem *req_q_in; /* FWI2-capable only. */
+ uint32_t __iomem *req_q_out;
uint16_t ring_index;
uint16_t in_ptr;
uint16_t cnt;
@@ -2256,10 +2218,10 @@ struct qla_hw_data {
uint32_t msix_enabled :1;
uint32_t disable_serdes :1;
uint32_t gpsc_supported :1;
- uint32_t vsan_enabled :1;
uint32_t npiv_supported :1;
uint32_t fce_enabled :1;
- uint32_t hw_event_marker_found:1;
+ uint32_t fac_supported :1;
+ uint32_t chip_reset_done :1;
} flags;
/* This spinlock is used to protect "io transactions", you must
@@ -2277,7 +2239,7 @@ struct qla_hw_data {
#define MIN_IOBASE_LEN 0x100
/* Multi queue data structs */
- device_reg_t *mqiobase;
+ device_reg_t __iomem *mqiobase;
uint16_t msix_count;
uint8_t mqenable;
struct req_que **req_q_map;
@@ -2300,7 +2262,6 @@ struct qla_hw_data {
uint16_t max_loop_id;
uint16_t fb_rev;
- uint16_t max_public_loop_ids;
uint16_t min_external_loopid; /* First external loop Id */
#define PORT_SPEED_UNKNOWN 0xFFFF
@@ -2381,6 +2342,8 @@ struct qla_hw_data {
IS_QLA25XX(ha) || IS_QLA81XX(ha))
#define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && \
(ha)->flags.msix_enabled)
+#define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha))
+#define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha))
#define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA)
#define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2)
@@ -2425,6 +2388,10 @@ struct qla_hw_data {
void *sfp_data;
dma_addr_t sfp_data_dma;
+ uint8_t *edc_data;
+ dma_addr_t edc_data_dma;
+ uint16_t edc_data_len;
+
struct task_struct *dpc_thread;
uint8_t dpc_active; /* DPC routine is active */
@@ -2439,6 +2406,8 @@ struct qla_hw_data {
dma_addr_t init_cb_dma;
init_cb_t *init_cb;
int init_cb_size;
+ dma_addr_t ex_init_cb_dma;
+ struct ex_init_cb_81xx *ex_init_cb;
/* These are used by mailbox operations. */
volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT];
@@ -2453,15 +2422,6 @@ struct qla_hw_data {
struct completion mbx_cmd_comp; /* Serialize mbx access */
struct completion mbx_intr_comp; /* Used for completion notification */
- uint32_t mbx_flags;
-#define MBX_IN_PROGRESS BIT_0
-#define MBX_BUSY BIT_1 /* Got the Access */
-#define MBX_SLEEPING_ON_SEM BIT_2
-#define MBX_POLLING_FOR_COMP BIT_3
-#define MBX_COMPLETED BIT_4
-#define MBX_TIMEDOUT BIT_5
-#define MBX_ACCESS_TIMEDOUT BIT_6
-
/* Basic firmware related information. */
uint16_t fw_major_version;
uint16_t fw_minor_version;
@@ -2473,13 +2433,15 @@ struct qla_hw_data {
#define RISC_START_ADDRESS_2100 0x1000
#define RISC_START_ADDRESS_2300 0x800
#define RISC_START_ADDRESS_2400 0x100000
+ uint16_t fw_xcb_count;
uint16_t fw_options[16]; /* slots: 1,2,3,10,11 */
uint8_t fw_seriallink_options[4];
uint16_t fw_seriallink_options24[4];
- uint8_t mpi_version[4];
+ uint8_t mpi_version[3];
uint32_t mpi_capabilities;
+ uint8_t phy_version[3];
/* Firmware dump information. */
struct qla2xxx_fw_dump *fw_dump;
@@ -2545,6 +2507,8 @@ struct qla_hw_data {
uint32_t flt_region_boot;
uint32_t flt_region_fw;
uint32_t flt_region_vpd_nvram;
+ uint32_t flt_region_vpd;
+ uint32_t flt_region_nvram;
uint32_t flt_region_npiv_conf;
/* Needed for BEACON */
@@ -2613,36 +2577,19 @@ typedef struct scsi_qla_host {
#define LOOP_RESYNC_ACTIVE 5
#define LOCAL_LOOP_UPDATE 6 /* Perform a local loop update. */
#define RSCN_UPDATE 7 /* Perform an RSCN update. */
-#define MAILBOX_RETRY 8
-#define ISP_RESET_NEEDED 9 /* Initiate a ISP reset. */
-#define FAILOVER_EVENT_NEEDED 10
-#define FAILOVER_EVENT 11
-#define FAILOVER_NEEDED 12
-#define SCSI_RESTART_NEEDED 13 /* Processes SCSI retry queue. */
-#define PORT_RESTART_NEEDED 14 /* Processes Retry queue. */
-#define RESTART_QUEUES_NEEDED 15 /* Restarts the Lun queue. */
-#define ABORT_QUEUES_NEEDED 16
-#define RELOGIN_NEEDED 17
-#define LOGIN_RETRY_NEEDED 18 /* Initiate required fabric logins. */
-#define REGISTER_FC4_NEEDED 19 /* SNS FC4 registration required. */
-#define ISP_ABORT_RETRY 20 /* ISP aborted. */
-#define FCPORT_RESCAN_NEEDED 21 /* IO descriptor processing needed */
-#define IODESC_PROCESS_NEEDED 22 /* IO descriptor processing needed */
-#define IOCTL_ERROR_RECOVERY 23
-#define LOOP_RESET_NEEDED 24
-#define BEACON_BLINK_NEEDED 25
-#define REGISTER_FDMI_NEEDED 26
-#define FCPORT_UPDATE_NEEDED 27
-#define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */
-#define UNLOADING 29
-#define NPIV_CONFIG_NEEDED 30
+#define RELOGIN_NEEDED 8
+#define REGISTER_FC4_NEEDED 9 /* SNS FC4 registration required. */
+#define ISP_ABORT_RETRY 10 /* ISP aborted. */
+#define BEACON_BLINK_NEEDED 11
+#define REGISTER_FDMI_NEEDED 12
+#define FCPORT_UPDATE_NEEDED 13
+#define VP_DPC_NEEDED 14 /* wake up for VP dpc handling */
+#define UNLOADING 15
+#define NPIV_CONFIG_NEEDED 16
uint32_t device_flags;
-#define DFLG_LOCAL_DEVICES BIT_0
-#define DFLG_RETRY_LOCAL_DEVICES BIT_1
-#define DFLG_FABRIC_DEVICES BIT_2
-#define SWITCH_FOUND BIT_3
-#define DFLG_NO_CABLE BIT_4
+#define SWITCH_FOUND BIT_0
+#define DFLG_NO_CABLE BIT_1
srb_t *status_srb; /* Status continuation entry. */
@@ -2755,10 +2702,5 @@ typedef struct scsi_qla_host {
#include "qla_inline.h"
#define CMD_SP(Cmnd) ((Cmnd)->SCp.ptr)
-#define CMD_COMPL_STATUS(Cmnd) ((Cmnd)->SCp.this_residual)
-#define CMD_RESID_LEN(Cmnd) ((Cmnd)->SCp.buffers_residual)
-#define CMD_SCSI_STATUS(Cmnd) ((Cmnd)->SCp.Status)
-#define CMD_ACTUAL_SNSLEN(Cmnd) ((Cmnd)->SCp.Message)
-#define CMD_ENTRY_STATUS(Cmnd) ((Cmnd)->SCp.have_data_in)
#endif
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index c66036da7d2..3a9a6ca4226 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -71,7 +71,7 @@ qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
mutex_unlock(&ha->fce_mutex);
out:
- return single_open(file, qla2x00_dfs_fce_show, ha);
+ return single_open(file, qla2x00_dfs_fce_show, vha);
}
static int
@@ -145,7 +145,7 @@ create_dir:
atomic_inc(&qla2x00_dfs_root_count);
create_nodes:
- ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, ha,
+ ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
&dfs_fce_ops);
if (!ha->dfs_fce) {
qla_printk(KERN_NOTICE, ha,
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index ffff4255408..96ccb9642ba 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1403,6 +1403,21 @@ struct access_chip_rsp_84xx {
#define MBA_IDC_TIME_EXT 0x8102
#define MBC_IDC_ACK 0x101
+#define MBC_RESTART_MPI_FW 0x3d
+#define MBC_FLASH_ACCESS_CTRL 0x3e /* Control flash access. */
+
+/* Flash access control option field bit definitions */
+#define FAC_OPT_FORCE_SEMAPHORE BIT_15
+#define FAC_OPT_REQUESTOR_ID BIT_14
+#define FAC_OPT_CMD_SUBCODE 0xff
+
+/* Flash access control command subcodes */
+#define FAC_OPT_CMD_WRITE_PROTECT 0x00
+#define FAC_OPT_CMD_WRITE_ENABLE 0x01
+#define FAC_OPT_CMD_ERASE_SECTOR 0x02
+#define FAC_OPT_CMD_LOCK_SEMAPHORE 0x03
+#define FAC_OPT_CMD_UNLOCK_SEMAPHORE 0x04
+#define FAC_OPT_CMD_GET_SECTOR_SIZE 0x05
struct nvram_81xx {
/* NVRAM header. */
@@ -1440,7 +1455,17 @@ struct nvram_81xx {
uint16_t reserved_6[24];
/* Offset 128. */
- uint16_t reserved_7[64];
+ uint16_t ex_version;
+ uint8_t prio_fcf_matching_flags;
+ uint8_t reserved_6_1[3];
+ uint16_t pri_fcf_vlan_id;
+ uint8_t pri_fcf_fabric_name[8];
+ uint16_t reserved_6_2[7];
+ uint8_t spma_mac_addr[6];
+ uint16_t reserved_6_3[14];
+
+ /* Offset 192. */
+ uint16_t reserved_7[32];
/*
* BIT 0 = Enable spinup delay
@@ -1664,6 +1689,17 @@ struct mid_init_cb_81xx {
struct mid_conf_entry_24xx entries[MAX_MULTI_ID_FABRIC];
};
+struct ex_init_cb_81xx {
+ uint16_t ex_version;
+ uint8_t prio_fcf_matching_flags;
+ uint8_t reserved_1[3];
+ uint16_t pri_fcf_vlan_id;
+ uint8_t pri_fcf_fabric_name[8];
+ uint16_t reserved_2[7];
+ uint8_t spma_mac_addr[6];
+ uint16_t reserved_3[14];
+};
+
#define FARX_ACCESS_FLASH_CONF_81XX 0x7FFD0000
#define FARX_ACCESS_FLASH_DATA_81XX 0x7F800000
@@ -1672,6 +1708,10 @@ struct mid_init_cb_81xx {
#define FA_RISC_CODE_ADDR_81 0xA0000
#define FA_FW_AREA_ADDR_81 0xC0000
#define FA_VPD_NVRAM_ADDR_81 0xD0000
+#define FA_VPD0_ADDR_81 0xD0000
+#define FA_VPD1_ADDR_81 0xD0400
+#define FA_NVRAM0_ADDR_81 0xD0080
+#define FA_NVRAM1_ADDR_81 0xD0480
#define FA_FEATURE_ADDR_81 0xD4000
#define FA_FLASH_DESCR_ADDR_81 0xD8000
#define FA_FLASH_LAYOUT_ADDR_81 0xD8400
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 6de283f8f11..528913f6bed 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -73,6 +73,7 @@ extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
fc_host_event_code, u32);
extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *);
+extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
extern void qla2x00_abort_fcport_cmds(fc_port_t *);
extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
@@ -82,7 +83,7 @@ extern void qla2x00_relogin(struct scsi_qla_host *);
/*
* Global Functions in qla_mid.c source file.
*/
-extern struct scsi_host_template qla24xx_driver_template;
+extern struct scsi_host_template qla2xxx_driver_template;
extern struct scsi_transport_template *qla2xxx_transport_vport_template;
extern void qla2x00_timer(scsi_qla_host_t *);
extern void qla2x00_start_timer(scsi_qla_host_t *, void *, unsigned long);
@@ -110,6 +111,7 @@ extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);
extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
+extern int qla2x00_wait_for_chip_reset(scsi_qla_host_t *);
extern void qla2xxx_wake_dpc(struct scsi_qla_host *);
extern void qla2x00_alert_all_vps(struct rsp_que *, uint16_t *);
@@ -144,8 +146,8 @@ extern int
qla2x00_execute_fw(scsi_qla_host_t *, uint32_t);
extern void
-qla2x00_get_fw_version(scsi_qla_host_t *, uint16_t *,
- uint16_t *, uint16_t *, uint16_t *, uint32_t *, uint8_t *, uint32_t *);
+qla2x00_get_fw_version(scsi_qla_host_t *, uint16_t *, uint16_t *, uint16_t *,
+ uint16_t *, uint32_t *, uint8_t *, uint32_t *, uint8_t *);
extern int
qla2x00_get_fw_options(scsi_qla_host_t *, uint16_t *);
@@ -263,12 +265,29 @@ extern int
qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
extern int
+qla2x00_read_edc(scsi_qla_host_t *, uint16_t, uint16_t, dma_addr_t,
+ uint8_t *, uint16_t, uint16_t);
+
+extern int
+qla2x00_write_edc(scsi_qla_host_t *, uint16_t, uint16_t, dma_addr_t,
+ uint8_t *, uint16_t, uint16_t);
+
+extern int
qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *);
extern int qla81xx_idc_ack(scsi_qla_host_t *, uint16_t *);
+extern int
+qla81xx_fac_get_sector_size(scsi_qla_host_t *, uint32_t *);
+
+extern int
+qla81xx_fac_do_write_enable(scsi_qla_host_t *, int);
+
+extern int
+qla81xx_fac_erase_sector(scsi_qla_host_t *, uint32_t, uint32_t);
+
/*
* Global Function Prototypes in qla_isr.c source file.
*/
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 87f9abc7146..bd7dd84c064 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -20,7 +20,6 @@
* QLogic ISP2x00 Hardware Support Function Prototypes.
*/
static int qla2x00_isp_firmware(scsi_qla_host_t *);
-static void qla2x00_resize_request_q(scsi_qla_host_t *);
static int qla2x00_setup_chip(scsi_qla_host_t *);
static int qla2x00_init_rings(scsi_qla_host_t *);
static int qla2x00_fw_ready(scsi_qla_host_t *);
@@ -61,8 +60,10 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
int rval;
struct qla_hw_data *ha = vha->hw;
struct req_que *req = ha->req_q_map[0];
+
/* Clear adapter flags. */
vha->flags.online = 0;
+ ha->flags.chip_reset_done = 0;
vha->flags.reset_active = 0;
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
atomic_set(&vha->loop_state, LOOP_DOWN);
@@ -70,7 +71,6 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
vha->dpc_flags = 0;
vha->flags.management_server_logged_in = 0;
vha->marker_needed = 0;
- ha->mbx_flags = 0;
ha->isp_abort_cnt = 0;
ha->beacon_blink_led = 0;
set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
@@ -131,6 +131,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
}
}
rval = qla2x00_init_rings(vha);
+ ha->flags.chip_reset_done = 1;
return (rval);
}
@@ -512,7 +513,6 @@ qla2x00_reset_chip(scsi_qla_host_t *vha)
static inline void
qla24xx_reset_risc(scsi_qla_host_t *vha)
{
- int hw_evt = 0;
unsigned long flags = 0;
struct qla_hw_data *ha = vha->hw;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
@@ -542,8 +542,6 @@ qla24xx_reset_risc(scsi_qla_host_t *vha)
d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
barrier();
}
- if (cnt == 0)
- hw_evt = 1;
/* Wait for soft-reset to complete. */
d2 = RD_REG_DWORD(&reg->ctrl_status);
@@ -816,7 +814,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n",
FCE_SIZE / 1024);
- fce_size = sizeof(struct qla2xxx_fce_chain) + EFT_SIZE;
+ fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
ha->flags.fce_enabled = 1;
ha->fce_dma = tc_dma;
ha->fce = tc;
@@ -894,62 +892,6 @@ cont_alloc:
}
/**
- * qla2x00_resize_request_q() - Resize request queue given available ISP memory.
- * @ha: HA context
- *
- * Returns 0 on success.
- */
-static void
-qla2x00_resize_request_q(scsi_qla_host_t *vha)
-{
- int rval;
- uint16_t fw_iocb_cnt = 0;
- uint16_t request_q_length = REQUEST_ENTRY_CNT_2XXX_EXT_MEM;
- dma_addr_t request_dma;
- request_t *request_ring;
- struct qla_hw_data *ha = vha->hw;
- struct req_que *req = ha->req_q_map[0];
-
- /* Valid only on recent ISPs. */
- if (IS_QLA2100(ha) || IS_QLA2200(ha))
- return;
-
- /* Retrieve IOCB counts available to the firmware. */
- rval = qla2x00_get_resource_cnts(vha, NULL, NULL, NULL, &fw_iocb_cnt,
- &ha->max_npiv_vports);
- if (rval)
- return;
- /* No point in continuing if current settings are sufficient. */
- if (fw_iocb_cnt < 1024)
- return;
- if (req->length >= request_q_length)
- return;
-
- /* Attempt to claim larger area for request queue. */
- request_ring = dma_alloc_coherent(&ha->pdev->dev,
- (request_q_length + 1) * sizeof(request_t), &request_dma,
- GFP_KERNEL);
- if (request_ring == NULL)
- return;
-
- /* Resize successful, report extensions. */
- qla_printk(KERN_INFO, ha, "Extended memory detected (%d KB)...\n",
- (ha->fw_memory_size + 1) / 1024);
- qla_printk(KERN_INFO, ha, "Resizing request queue depth "
- "(%d -> %d)...\n", req->length, request_q_length);
-
- /* Clear old allocations. */
- dma_free_coherent(&ha->pdev->dev,
- (req->length + 1) * sizeof(request_t), req->ring,
- req->dma);
-
- /* Begin using larger queue. */
- req->length = request_q_length;
- req->ring = request_ring;
- req->dma = request_dma;
-}
-
-/**
* qla2x00_setup_chip() - Load and start RISC firmware.
* @ha: HA context
*
@@ -963,6 +905,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
struct qla_hw_data *ha = vha->hw;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
unsigned long flags;
+ uint16_t fw_major_version;
if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) {
/* Disable SRAM, Instruction RAM and GP RAM parity. */
@@ -986,13 +929,15 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
rval = qla2x00_execute_fw(vha, srisc_address);
/* Retrieve firmware information. */
- if (rval == QLA_SUCCESS && ha->fw_major_version == 0) {
+ if (rval == QLA_SUCCESS) {
+ fw_major_version = ha->fw_major_version;
qla2x00_get_fw_version(vha,
&ha->fw_major_version,
&ha->fw_minor_version,
&ha->fw_subminor_version,
&ha->fw_attributes, &ha->fw_memory_size,
- ha->mpi_version, &ha->mpi_capabilities);
+ ha->mpi_version, &ha->mpi_capabilities,
+ ha->phy_version);
ha->flags.npiv_supported = 0;
if (IS_QLA2XXX_MIDTYPE(ha) &&
(ha->fw_attributes & BIT_2)) {
@@ -1003,9 +948,11 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
ha->max_npiv_vports =
MIN_MULTI_ID_FABRIC - 1;
}
- qla2x00_resize_request_q(vha);
+ qla2x00_get_resource_cnts(vha, NULL,
+ &ha->fw_xcb_count, NULL, NULL,
+ &ha->max_npiv_vports);
- if (ql2xallocfwdump)
+ if (!fw_major_version && ql2xallocfwdump)
qla2x00_alloc_fw_dump(vha);
}
} else {
@@ -1028,6 +975,21 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
+ if (rval == QLA_SUCCESS && IS_FAC_REQUIRED(ha)) {
+ uint32_t size;
+
+ rval = qla81xx_fac_get_sector_size(vha, &size);
+ if (rval == QLA_SUCCESS) {
+ ha->flags.fac_supported = 1;
+ ha->fdt_block_size = size << 2;
+ } else {
+ qla_printk(KERN_ERR, ha,
+ "Unsupported FAC firmware (%d.%02d.%02d).\n",
+ ha->fw_major_version, ha->fw_minor_version,
+ ha->fw_subminor_version);
+ }
+ }
+
if (rval) {
DEBUG2_3(printk("scsi(%ld): Setup chip **** FAILED ****.\n",
vha->host_no));
@@ -1314,8 +1276,11 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
mid_init_cb->count = cpu_to_le16(ha->max_npiv_vports);
}
-
- mid_init_cb->options = __constant_cpu_to_le16(BIT_1);
+ if (IS_FWI2_CAPABLE(ha)) {
+ mid_init_cb->options = __constant_cpu_to_le16(BIT_1);
+ mid_init_cb->init_cb.execution_throttle =
+ cpu_to_le16(ha->fw_xcb_count);
+ }
rval = qla2x00_init_firmware(vha, ha->init_cb_size);
if (rval) {
@@ -1989,7 +1954,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
fcport->port_type = FCT_UNKNOWN;
fcport->loop_id = FC_NO_LOOP_ID;
atomic_set(&fcport->state, FCS_UNCONFIGURED);
- fcport->flags = FCF_RLC_SUPPORT;
fcport->supported_classes = FC_COS_UNSPECIFIED;
return fcport;
@@ -2171,7 +2135,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
vha->host_no, fcport->loop_id));
atomic_set(&fcport->state, FCS_DEVICE_LOST);
- fcport->flags &= ~FCF_FARP_DONE;
}
}
@@ -2228,8 +2191,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
WWN_SIZE))
continue;
- fcport->flags &= ~(FCF_FABRIC_DEVICE |
- FCF_PERSISTENT_BOUND);
+ fcport->flags &= ~FCF_FABRIC_DEVICE;
fcport->loop_id = new_fcport->loop_id;
fcport->port_type = new_fcport->port_type;
fcport->d_id.b24 = new_fcport->d_id.b24;
@@ -2242,7 +2204,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
if (!found) {
/* New device, add to fcports list. */
- new_fcport->flags &= ~FCF_PERSISTENT_BOUND;
if (vha->vp_idx) {
new_fcport->vha = vha;
new_fcport->vp_idx = vha->vp_idx;
@@ -2275,11 +2236,6 @@ cleanup_allocation:
"rval=%x\n", vha->host_no, rval));
}
- if (found_devs) {
- vha->device_flags |= DFLG_LOCAL_DEVICES;
- vha->device_flags &= ~DFLG_RETRY_LOCAL_DEVICES;
- }
-
return (rval);
}
@@ -2765,7 +2721,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
fcport->loop_id = FC_NO_LOOP_ID;
fcport->flags |= (FCF_FABRIC_DEVICE |
FCF_LOGIN_NEEDED);
- fcport->flags &= ~FCF_PERSISTENT_BOUND;
break;
}
@@ -2808,9 +2763,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
kfree(swl);
kfree(new_fcport);
- if (!list_empty(new_fcports))
- vha->device_flags |= DFLG_FABRIC_DEVICES;
-
return (rval);
}
@@ -2993,7 +2945,6 @@ qla2x00_device_resync(scsi_qla_host_t *vha)
0, 0);
}
}
- fcport->flags &= ~FCF_FARP_DONE;
}
}
return (rval);
@@ -3302,6 +3253,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
if (vha->flags.online) {
vha->flags.online = 0;
+ ha->flags.chip_reset_done = 0;
clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
ha->qla_stats.total_isp_aborts++;
@@ -3451,6 +3403,7 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
if (!status && !(status = qla2x00_init_rings(vha))) {
clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
+ ha->flags.chip_reset_done = 1;
/* Initialize the queues in use */
qla25xx_init_queues(ha);
@@ -4338,23 +4291,17 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
/* Determine NVRAM starting address. */
ha->nvram_size = sizeof(struct nvram_81xx);
- ha->nvram_base = FA_NVRAM_FUNC0_ADDR;
ha->vpd_size = FA_NVRAM_VPD_SIZE;
- ha->vpd_base = FA_NVRAM_VPD0_ADDR;
- if (PCI_FUNC(ha->pdev->devfn) & 1) {
- ha->nvram_base = FA_NVRAM_FUNC1_ADDR;
- ha->vpd_base = FA_NVRAM_VPD1_ADDR;
- }
/* Get VPD data into cache */
ha->vpd = ha->nvram + VPD_OFFSET;
- ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd,
- ha->nvram_base - FA_NVRAM_FUNC0_ADDR, FA_NVRAM_VPD_SIZE * 4);
+ ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_vpd << 2,
+ ha->vpd_size);
/* Get NVRAM data into cache and calculate checksum. */
- dptr = (uint32_t *)nv;
- ha->isp_ops->read_nvram(vha, (uint8_t *)dptr, ha->nvram_base,
+ ha->isp_ops->read_optrom(vha, ha->nvram, ha->flt_region_nvram << 2,
ha->nvram_size);
+ dptr = (uint32_t *)nv;
for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++)
chksum += le32_to_cpu(*dptr++);
@@ -4452,6 +4399,9 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
icb->enode_mac[5] = 0x06 + PCI_FUNC(ha->pdev->devfn);
}
+ /* Use extended-initialization control block. */
+ memcpy(ha->ex_init_cb, &nv->ex_version, sizeof(*ha->ex_init_cb));
+
/*
* Setup driver NVRAM options.
*/
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 2258152b1f4..a8abbb95730 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -776,7 +776,7 @@ qla24xx_start_scsi(srb_t *sp)
req_cnt = qla24xx_calc_iocbs(tot_dsds);
if (req->cnt < (req_cnt + 2)) {
- cnt = ha->isp_ops->rd_req_reg(ha, req->id);
+ cnt = RD_REG_DWORD_RELAXED(req->req_q_out);
if (req->ring_index < cnt)
req->cnt = cnt - req->ring_index;
@@ -836,7 +836,8 @@ qla24xx_start_scsi(srb_t *sp)
sp->flags |= SRB_DMA_VALID;
/* Set chip new ring index. */
- ha->isp_ops->wrt_req_reg(ha, req->id, req->ring_index);
+ WRT_REG_DWORD(req->req_q_in, req->ring_index);
+ RD_REG_DWORD_RELAXED(&ha->iobase->isp24.hccr);
/* Manage unprocessed RIO/ZIO commands in response queue. */
if (vha->flags.process_response_queue &&
@@ -854,35 +855,3 @@ queuing_error:
return QLA_FUNCTION_FAILED;
}
-
-uint16_t
-qla24xx_rd_req_reg(struct qla_hw_data *ha, uint16_t id)
-{
- device_reg_t __iomem *reg = (void *) ha->iobase;
- return RD_REG_DWORD_RELAXED(&reg->isp24.req_q_out);
-}
-
-uint16_t
-qla25xx_rd_req_reg(struct qla_hw_data *ha, uint16_t id)
-{
- device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id;
- return RD_REG_DWORD_RELAXED(&reg->isp25mq.req_q_out);
-}
-
-void
-qla24xx_wrt_req_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
-{
- device_reg_t __iomem *reg = (void *) ha->iobase;
- WRT_REG_DWORD(&reg->isp24.req_q_in, index);
- RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
-}
-
-void
-qla25xx_wrt_req_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
-{
- device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id;
- struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp;
- WRT_REG_DWORD(&reg->isp25mq.req_q_in, index);
- RD_REG_DWORD(&ioreg->hccr); /* PCI posting */
-}
-
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index f250e5b7897..d04981848e5 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -852,9 +852,6 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
/* Free outstanding command slot. */
req->outstanding_cmds[index] = NULL;
- CMD_COMPL_STATUS(sp->cmd) = 0L;
- CMD_SCSI_STATUS(sp->cmd) = 0L;
-
/* Save ISP completion status */
sp->cmd->result = DID_OK << 16;
@@ -955,7 +952,6 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len)
if (sense_len >= SCSI_SENSE_BUFFERSIZE)
sense_len = SCSI_SENSE_BUFFERSIZE;
- CMD_ACTUAL_SNSLEN(cp) = sense_len;
sp->request_sense_length = sense_len;
sp->request_sense_ptr = cp->sense_buffer;
if (sp->request_sense_length > 32)
@@ -973,8 +969,7 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len)
cp->device->channel, cp->device->id, cp->device->lun, cp,
cp->serial_number));
if (sense_len)
- DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
- CMD_ACTUAL_SNSLEN(cp)));
+ DEBUG5(qla2x00_dump_buffer(cp->sense_buffer, sense_len));
}
/**
@@ -1043,9 +1038,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
}
lscsi_status = scsi_status & STATUS_MASK;
- CMD_ENTRY_STATUS(cp) = sts->entry_status;
- CMD_COMPL_STATUS(cp) = comp_status;
- CMD_SCSI_STATUS(cp) = scsi_status;
fcport = sp->fcport;
@@ -1104,7 +1096,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
resid = resid_len;
scsi_set_resid(cp, resid);
- CMD_RESID_LEN(cp) = resid;
if (!lscsi_status &&
((unsigned)(scsi_bufflen(cp) - resid) <
@@ -1160,7 +1151,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
if (scsi_status & SS_RESIDUAL_UNDER) {
scsi_set_resid(cp, resid);
- CMD_RESID_LEN(cp) = resid;
} else {
DEBUG2(printk(KERN_INFO
"scsi(%ld:%d:%d) UNDERRUN status detected "
@@ -1499,7 +1489,6 @@ qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
void
qla24xx_process_response_queue(struct rsp_que *rsp)
{
- struct qla_hw_data *ha = rsp->hw;
struct sts_entry_24xx *pkt;
struct scsi_qla_host *vha;
@@ -1553,7 +1542,7 @@ qla24xx_process_response_queue(struct rsp_que *rsp)
}
/* Adjust ring index */
- ha->isp_ops->wrt_rsp_reg(ha, rsp->id, rsp->ring_index);
+ WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index);
}
static void
@@ -2029,7 +2018,7 @@ skip_msix:
skip_msi:
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
- IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp);
+ IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp);
if (ret) {
qla_printk(KERN_WARNING, ha,
"Failed to reserve interrupt %d already in use.\n",
@@ -2117,18 +2106,3 @@ int qla25xx_request_irq(struct rsp_que *rsp)
msix->rsp = rsp;
return ret;
}
-
-void
-qla25xx_wrt_rsp_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
-{
- device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id;
- WRT_REG_DWORD(&reg->isp25mq.rsp_q_out, index);
-}
-
-void
-qla24xx_wrt_rsp_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
-{
- device_reg_t __iomem *reg = (void *) ha->iobase;
- WRT_REG_DWORD(&reg->isp24.rsp_q_out, index);
-}
-
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 4aab7acf752..e67c1660bf4 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -45,6 +45,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
struct qla_hw_data *ha = vha->hw;
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+ if (ha->pdev->error_state > pci_channel_io_frozen)
+ return QLA_FUNCTION_TIMEOUT;
+
reg = ha->iobase;
io_lock_on = base_vha->flags.init_done;
@@ -408,7 +411,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
void
qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
uint16_t *subminor, uint16_t *attributes, uint32_t *memory, uint8_t *mpi,
- uint32_t *mpi_caps)
+ uint32_t *mpi_caps, uint8_t *phy)
{
int rval;
mbx_cmd_t mc;
@@ -420,7 +423,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
mcp->out_mb = MBX_0;
mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
if (IS_QLA81XX(vha->hw))
- mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
+ mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
mcp->flags = 0;
mcp->tov = MBX_TOV_SECONDS;
rval = qla2x00_mailbox_command(vha, mcp);
@@ -435,11 +438,13 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
else
*memory = (mcp->mb[5] << 16) | mcp->mb[4];
if (IS_QLA81XX(vha->hw)) {
- mpi[0] = mcp->mb[10] >> 8;
- mpi[1] = mcp->mb[10] & 0xff;
- mpi[2] = mcp->mb[11] >> 8;
- mpi[3] = mcp->mb[11] & 0xff;
+ mpi[0] = mcp->mb[10] & 0xff;
+ mpi[1] = mcp->mb[11] >> 8;
+ mpi[2] = mcp->mb[11] & 0xff;
*mpi_caps = (mcp->mb[12] << 16) | mcp->mb[13];
+ phy[0] = mcp->mb[8] & 0xff;
+ phy[1] = mcp->mb[9] >> 8;
+ phy[2] = mcp->mb[9] & 0xff;
}
if (rval != QLA_SUCCESS) {
@@ -1043,14 +1048,22 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
else
mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
+ mcp->mb[1] = 0;
mcp->mb[2] = MSW(ha->init_cb_dma);
mcp->mb[3] = LSW(ha->init_cb_dma);
- mcp->mb[4] = 0;
- mcp->mb[5] = 0;
mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
- mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
- mcp->in_mb = MBX_5|MBX_4|MBX_0;
+ mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+ if (IS_QLA81XX(ha) && ha->ex_init_cb->ex_version) {
+ mcp->mb[1] = BIT_0;
+ mcp->mb[10] = MSW(ha->ex_init_cb_dma);
+ mcp->mb[11] = LSW(ha->ex_init_cb_dma);
+ mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
+ mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
+ mcp->mb[14] = sizeof(*ha->ex_init_cb);
+ mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
+ }
+ mcp->in_mb = MBX_0;
mcp->buf_size = size;
mcp->flags = MBX_DMA_OUT;
mcp->tov = MBX_TOV_SECONDS;
@@ -1187,10 +1200,6 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
fcport->d_id.b.al_pa = pd->port_id[2];
fcport->d_id.b.rsvd_1 = 0;
- /* Check for device require authentication. */
- pd->common_features & BIT_5 ? (fcport->flags |= FCF_AUTH_REQ) :
- (fcport->flags &= ~FCF_AUTH_REQ);
-
/* If not target must be initiator or unknown type. */
if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
fcport->port_type = FCT_INITIATOR;
@@ -3218,3 +3227,204 @@ qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
return rval;
}
+
+int
+qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ if (!IS_QLA81XX(vha->hw))
+ return QLA_FUNCTION_FAILED;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
+ mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
+ mcp->out_mb = MBX_1|MBX_0;
+ mcp->in_mb = MBX_1|MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
+ __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
+ *sector_size = mcp->mb[1];
+ }
+
+ return rval;
+}
+
+int
+qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ if (!IS_QLA81XX(vha->hw))
+ return QLA_FUNCTION_FAILED;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
+ mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
+ FAC_OPT_CMD_WRITE_PROTECT;
+ mcp->out_mb = MBX_1|MBX_0;
+ mcp->in_mb = MBX_1|MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
+ __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
+ }
+
+ return rval;
+}
+
+int
+qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ if (!IS_QLA81XX(vha->hw))
+ return QLA_FUNCTION_FAILED;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
+ mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
+ mcp->mb[2] = LSW(start);
+ mcp->mb[3] = MSW(start);
+ mcp->mb[4] = LSW(finish);
+ mcp->mb[5] = MSW(finish);
+ mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
+ mcp->in_mb = MBX_2|MBX_1|MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
+ "mb[2]=%x.\n", __func__, vha->host_no, rval, mcp->mb[0],
+ mcp->mb[1], mcp->mb[2]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
+ }
+
+ return rval;
+}
+
+int
+qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
+{
+ int rval = 0;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ mcp->mb[0] = MBC_RESTART_MPI_FW;
+ mcp->out_mb = MBX_0;
+ mcp->in_mb = MBX_0|MBX_1;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=0x%x mb[1]=0x%x.\n",
+ __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
+ }
+
+ return rval;
+}
+
+int
+qla2x00_read_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
+ dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ mcp->mb[0] = MBC_READ_SFP;
+ mcp->mb[1] = dev;
+ mcp->mb[2] = MSW(sfp_dma);
+ mcp->mb[3] = LSW(sfp_dma);
+ mcp->mb[6] = MSW(MSD(sfp_dma));
+ mcp->mb[7] = LSW(MSD(sfp_dma));
+ mcp->mb[8] = len;
+ mcp->mb[9] = adr;
+ mcp->mb[10] = opt;
+ mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+ mcp->in_mb = MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (opt & BIT_0)
+ if (sfp)
+ *sfp = mcp->mb[8];
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
+ vha->host_no, rval, mcp->mb[0]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
+ }
+
+ return rval;
+}
+
+int
+qla2x00_write_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
+ dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ if (opt & BIT_0)
+ if (sfp)
+ len = *sfp;
+
+ mcp->mb[0] = MBC_WRITE_SFP;
+ mcp->mb[1] = dev;
+ mcp->mb[2] = MSW(sfp_dma);
+ mcp->mb[3] = LSW(sfp_dma);
+ mcp->mb[6] = MSW(MSD(sfp_dma));
+ mcp->mb[7] = LSW(MSD(sfp_dma));
+ mcp->mb[8] = len;
+ mcp->mb[9] = adr;
+ mcp->mb[10] = opt;
+ mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+ mcp->in_mb = MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
+ vha->host_no, rval, mcp->mb[0]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
+ }
+
+ return rval;
+}
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 785c61279e6..51716c7e300 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -359,7 +359,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost);
struct qla_hw_data *ha = base_vha->hw;
scsi_qla_host_t *vha;
- struct scsi_host_template *sht = &qla24xx_driver_template;
+ struct scsi_host_template *sht = &qla2xxx_driver_template;
struct Scsi_Host *host;
vha = qla2x00_create_host(sht, ha);
@@ -584,6 +584,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
struct req_que *req = NULL;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
uint16_t que_id = 0;
+ device_reg_t __iomem *reg;
req = kzalloc(sizeof(struct req_que), GFP_KERNEL);
if (req == NULL) {
@@ -631,6 +632,9 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
req->ring_index = 0;
req->cnt = req->length;
req->id = que_id;
+ reg = ISP_QUE_REG(ha, que_id);
+ req->req_q_in = &reg->isp25mq.req_q_in;
+ req->req_q_out = &reg->isp25mq.req_q_out;
req->max_q_depth = ha->req_q_map[0]->max_q_depth;
mutex_unlock(&ha->vport_lock);
@@ -658,7 +662,8 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
int ret = 0;
struct rsp_que *rsp = NULL;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
- uint16_t que_id = 0;;
+ uint16_t que_id = 0;
+ device_reg_t __iomem *reg;
rsp = kzalloc(sizeof(struct rsp_que), GFP_KERNEL);
if (rsp == NULL) {
@@ -706,6 +711,9 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
rsp->ring_ptr = rsp->ring;
rsp->ring_index = 0;
rsp->id = que_id;
+ reg = ISP_QUE_REG(ha, que_id);
+ rsp->rsp_q_in = &reg->isp25mq.rsp_q_in;
+ rsp->rsp_q_out = &reg->isp25mq.rsp_q_out;
mutex_unlock(&ha->vport_lock);
ret = qla25xx_request_irq(rsp);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3ddfa889e94..e4fdcdad80d 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -104,9 +104,7 @@ static int qla2xxx_slave_alloc(struct scsi_device *);
static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time);
static void qla2xxx_scan_start(struct Scsi_Host *);
static void qla2xxx_slave_destroy(struct scsi_device *);
-static int qla2x00_queuecommand(struct scsi_cmnd *cmd,
- void (*fn)(struct scsi_cmnd *));
-static int qla24xx_queuecommand(struct scsi_cmnd *cmd,
+static int qla2xxx_queuecommand(struct scsi_cmnd *cmd,
void (*fn)(struct scsi_cmnd *));
static int qla2xxx_eh_abort(struct scsi_cmnd *);
static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
@@ -117,42 +115,10 @@ static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
static int qla2x00_change_queue_depth(struct scsi_device *, int);
static int qla2x00_change_queue_type(struct scsi_device *, int);
-static struct scsi_host_template qla2x00_driver_template = {
+struct scsi_host_template qla2xxx_driver_template = {
.module = THIS_MODULE,
.name = QLA2XXX_DRIVER_NAME,
- .queuecommand = qla2x00_queuecommand,
-
- .eh_abort_handler = qla2xxx_eh_abort,
- .eh_device_reset_handler = qla2xxx_eh_device_reset,
- .eh_target_reset_handler = qla2xxx_eh_target_reset,
- .eh_bus_reset_handler = qla2xxx_eh_bus_reset,
- .eh_host_reset_handler = qla2xxx_eh_host_reset,
-
- .slave_configure = qla2xxx_slave_configure,
-
- .slave_alloc = qla2xxx_slave_alloc,
- .slave_destroy = qla2xxx_slave_destroy,
- .scan_finished = qla2xxx_scan_finished,
- .scan_start = qla2xxx_scan_start,
- .change_queue_depth = qla2x00_change_queue_depth,
- .change_queue_type = qla2x00_change_queue_type,
- .this_id = -1,
- .cmd_per_lun = 3,
- .use_clustering = ENABLE_CLUSTERING,
- .sg_tablesize = SG_ALL,
-
- /*
- * The RISC allows for each command to transfer (2^32-1) bytes of data,
- * which equates to 0x800000 sectors.
- */
- .max_sectors = 0xFFFF,
- .shost_attrs = qla2x00_host_attrs,
-};
-
-struct scsi_host_template qla24xx_driver_template = {
- .module = THIS_MODULE,
- .name = QLA2XXX_DRIVER_NAME,
- .queuecommand = qla24xx_queuecommand,
+ .queuecommand = qla2xxx_queuecommand,
.eh_abort_handler = qla2xxx_eh_abort,
.eh_device_reset_handler = qla2xxx_eh_device_reset,
@@ -430,73 +396,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
}
static int
-qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
-{
- scsi_qla_host_t *vha = shost_priv(cmd->device->host);
- fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
- struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
- struct qla_hw_data *ha = vha->hw;
- srb_t *sp;
- int rval;
-
- if (unlikely(pci_channel_offline(ha->pdev))) {
- cmd->result = DID_REQUEUE << 16;
- goto qc_fail_command;
- }
-
- rval = fc_remote_port_chkready(rport);
- if (rval) {
- cmd->result = rval;
- goto qc_fail_command;
- }
-
- /* Close window on fcport/rport state-transitioning. */
- if (fcport->drport)
- goto qc_target_busy;
-
- if (atomic_read(&fcport->state) != FCS_ONLINE) {
- if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
- atomic_read(&vha->loop_state) == LOOP_DEAD) {
- cmd->result = DID_NO_CONNECT << 16;
- goto qc_fail_command;
- }
- goto qc_target_busy;
- }
-
- spin_unlock_irq(vha->host->host_lock);
-
- sp = qla2x00_get_new_sp(vha, fcport, cmd, done);
- if (!sp)
- goto qc_host_busy_lock;
-
- rval = ha->isp_ops->start_scsi(sp);
- if (rval != QLA_SUCCESS)
- goto qc_host_busy_free_sp;
-
- spin_lock_irq(vha->host->host_lock);
-
- return 0;
-
-qc_host_busy_free_sp:
- qla2x00_sp_free_dma(sp);
- mempool_free(sp, ha->srb_mempool);
-
-qc_host_busy_lock:
- spin_lock_irq(vha->host->host_lock);
- return SCSI_MLQUEUE_HOST_BUSY;
-
-qc_target_busy:
- return SCSI_MLQUEUE_TARGET_BUSY;
-
-qc_fail_command:
- done(cmd);
-
- return 0;
-}
-
-
-static int
-qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
@@ -507,7 +407,10 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
int rval;
if (unlikely(pci_channel_offline(ha->pdev))) {
- cmd->result = DID_REQUEUE << 16;
+ if (ha->pdev->error_state == pci_channel_io_frozen)
+ cmd->result = DID_REQUEUE << 16;
+ else
+ cmd->result = DID_NO_CONNECT << 16;
goto qc24_fail_command;
}
@@ -635,6 +538,34 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
return (return_status);
}
+int
+qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha)
+{
+ int return_status;
+ unsigned long wait_reset;
+ struct qla_hw_data *ha = vha->hw;
+ scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+
+ wait_reset = jiffies + (MAX_LOOP_TIMEOUT * HZ);
+ while (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) ||
+ test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
+ test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
+ ha->dpc_active) && time_before(jiffies, wait_reset)) {
+
+ msleep(1000);
+
+ if (!test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) &&
+ ha->flags.chip_reset_done)
+ break;
+ }
+ if (ha->flags.chip_reset_done)
+ return_status = QLA_SUCCESS;
+ else
+ return_status = QLA_FUNCTION_FAILED;
+
+ return return_status;
+}
+
/*
* qla2x00_wait_for_loop_ready
* Wait for MAX_LOOP_TIMEOUT(5 min) value for loop
@@ -1163,7 +1094,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
continue;
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
sp = req->outstanding_cmds[cnt];
- if (sp && sp->fcport->vha == vha) {
+ if (sp) {
req->outstanding_cmds[cnt] = NULL;
sp->cmd->result = res;
qla2x00_sp_compl(ha, sp);
@@ -1245,10 +1176,10 @@ qla2x00_config_dma_addressing(struct qla_hw_data *ha)
/* Assume a 32bit DMA mask. */
ha->flags.enable_64bit_addressing = 0;
- if (!dma_set_mask(&ha->pdev->dev, DMA_64BIT_MASK)) {
+ if (!dma_set_mask(&ha->pdev->dev, DMA_BIT_MASK(64))) {
/* Any upper-dword bits set? */
if (MSD(dma_get_required_mask(&ha->pdev->dev)) &&
- !pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) {
+ !pci_set_consistent_dma_mask(ha->pdev, DMA_BIT_MASK(64))) {
/* Ok, a 64bit DMA mask is applicable. */
ha->flags.enable_64bit_addressing = 1;
ha->isp_ops->calc_req_entries = qla2x00_calc_iocbs_64;
@@ -1257,8 +1188,8 @@ qla2x00_config_dma_addressing(struct qla_hw_data *ha)
}
}
- dma_set_mask(&ha->pdev->dev, DMA_32BIT_MASK);
- pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK);
+ dma_set_mask(&ha->pdev->dev, DMA_BIT_MASK(32));
+ pci_set_consistent_dma_mask(ha->pdev, DMA_BIT_MASK(32));
}
static void
@@ -1351,9 +1282,6 @@ static struct isp_operations qla2100_isp_ops = {
.write_optrom = qla2x00_write_optrom_data,
.get_flash_version = qla2x00_get_flash_version,
.start_scsi = qla2x00_start_scsi,
- .wrt_req_reg = NULL,
- .wrt_rsp_reg = NULL,
- .rd_req_reg = NULL,
};
static struct isp_operations qla2300_isp_ops = {
@@ -1389,9 +1317,6 @@ static struct isp_operations qla2300_isp_ops = {
.write_optrom = qla2x00_write_optrom_data,
.get_flash_version = qla2x00_get_flash_version,
.start_scsi = qla2x00_start_scsi,
- .wrt_req_reg = NULL,
- .wrt_rsp_reg = NULL,
- .rd_req_reg = NULL,
};
static struct isp_operations qla24xx_isp_ops = {
@@ -1427,9 +1352,6 @@ static struct isp_operations qla24xx_isp_ops = {
.write_optrom = qla24xx_write_optrom_data,
.get_flash_version = qla24xx_get_flash_version,
.start_scsi = qla24xx_start_scsi,
- .wrt_req_reg = qla24xx_wrt_req_reg,
- .wrt_rsp_reg = qla24xx_wrt_rsp_reg,
- .rd_req_reg = qla24xx_rd_req_reg,
};
static struct isp_operations qla25xx_isp_ops = {
@@ -1465,9 +1387,6 @@ static struct isp_operations qla25xx_isp_ops = {
.write_optrom = qla24xx_write_optrom_data,
.get_flash_version = qla24xx_get_flash_version,
.start_scsi = qla24xx_start_scsi,
- .wrt_req_reg = qla24xx_wrt_req_reg,
- .wrt_rsp_reg = qla24xx_wrt_rsp_reg,
- .rd_req_reg = qla24xx_rd_req_reg,
};
static struct isp_operations qla81xx_isp_ops = {
@@ -1493,8 +1412,8 @@ static struct isp_operations qla81xx_isp_ops = {
.build_iocbs = NULL,
.prep_ms_iocb = qla24xx_prep_ms_iocb,
.prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb,
- .read_nvram = qla25xx_read_nvram_data,
- .write_nvram = qla25xx_write_nvram_data,
+ .read_nvram = NULL,
+ .write_nvram = NULL,
.fw_dump = qla81xx_fw_dump,
.beacon_on = qla24xx_beacon_on,
.beacon_off = qla24xx_beacon_off,
@@ -1503,9 +1422,6 @@ static struct isp_operations qla81xx_isp_ops = {
.write_optrom = qla24xx_write_optrom_data,
.get_flash_version = qla24xx_get_flash_version,
.start_scsi = qla24xx_start_scsi,
- .wrt_req_reg = qla24xx_wrt_req_reg,
- .wrt_rsp_reg = qla24xx_wrt_rsp_reg,
- .rd_req_reg = qla24xx_rd_req_reg,
};
static inline void
@@ -1727,7 +1643,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
struct rsp_que *rsp = NULL;
bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
- sht = &qla2x00_driver_template;
+ sht = &qla2xxx_driver_template;
if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 ||
@@ -1736,7 +1652,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532 ||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8001) {
bars = pci_select_bars(pdev, IORESOURCE_MEM);
- sht = &qla24xx_driver_template;
mem_only = 1;
}
@@ -1927,10 +1842,16 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->rsp_q_map[0] = rsp;
ha->req_q_map[0] = req;
+ /* FWI2-capable only. */
+ req->req_q_in = &ha->iobase->isp24.req_q_in;
+ req->req_q_out = &ha->iobase->isp24.req_q_out;
+ rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in;
+ rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out;
if (ha->mqenable) {
- ha->isp_ops->wrt_req_reg = qla25xx_wrt_req_reg;
- ha->isp_ops->wrt_rsp_reg = qla25xx_wrt_rsp_reg;
- ha->isp_ops->rd_req_reg = qla25xx_rd_req_reg;
+ req->req_q_in = &ha->mqiobase->isp25mq.req_q_in;
+ req->req_q_out = &ha->mqiobase->isp25mq.req_q_out;
+ rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in;
+ rsp->rsp_q_out = &ha->mqiobase->isp25mq.rsp_q_out;
}
if (qla2x00_initialize_adapter(base_vha)) {
@@ -2000,6 +1921,16 @@ probe_init_failed:
ha->max_queues = 0;
probe_failed:
+ if (base_vha->timer_active)
+ qla2x00_stop_timer(base_vha);
+ base_vha->flags.online = 0;
+ if (ha->dpc_thread) {
+ struct task_struct *t = ha->dpc_thread;
+
+ ha->dpc_thread = NULL;
+ kthread_stop(t);
+ }
+
qla2x00_free_device(base_vha);
scsi_host_put(base_vha->host);
@@ -2033,10 +1964,30 @@ qla2x00_remove_one(struct pci_dev *pdev)
set_bit(UNLOADING, &base_vha->dpc_flags);
+ qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
+
qla2x00_dfs_remove(base_vha);
qla84xx_put_chip(base_vha);
+ /* Disable timer */
+ if (base_vha->timer_active)
+ qla2x00_stop_timer(base_vha);
+
+ base_vha->flags.online = 0;
+
+ /* Kill the kernel thread for this host */
+ if (ha->dpc_thread) {
+ struct task_struct *t = ha->dpc_thread;
+
+ /*
+ * qla2xxx_wake_dpc checks for ->dpc_thread
+ * so we need to zero it out.
+ */
+ ha->dpc_thread = NULL;
+ kthread_stop(t);
+ }
+
qla2x00_free_sysfs_attr(base_vha);
fc_remove_host(base_vha->host);
@@ -2065,25 +2016,6 @@ static void
qla2x00_free_device(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
- qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);
-
- /* Disable timer */
- if (vha->timer_active)
- qla2x00_stop_timer(vha);
-
- vha->flags.online = 0;
-
- /* Kill the kernel thread for this host */
- if (ha->dpc_thread) {
- struct task_struct *t = ha->dpc_thread;
-
- /*
- * qla2xxx_wake_dpc checks for ->dpc_thread
- * so we need to zero it out.
- */
- ha->dpc_thread = NULL;
- kthread_stop(t);
- }
if (ha->flags.fce_enabled)
qla2x00_disable_fce_trace(vha, NULL, NULL);
@@ -2313,9 +2245,19 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
} else
ha->npiv_info = NULL;
+ /* Get consistent memory allocated for EX-INIT-CB. */
+ if (IS_QLA81XX(ha)) {
+ ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
+ &ha->ex_init_cb_dma);
+ if (!ha->ex_init_cb)
+ goto fail_ex_init_cb;
+ }
+
INIT_LIST_HEAD(&ha->vp_list);
return 1;
+fail_ex_init_cb:
+ kfree(ha->npiv_info);
fail_npiv_info:
dma_free_coherent(&ha->pdev->dev, ((*rsp)->length + 1) *
sizeof(response_t), (*rsp)->ring, (*rsp)->dma);
@@ -2398,18 +2340,22 @@ qla2x00_mem_free(struct qla_hw_data *ha)
if (ha->sfp_data)
dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma);
+ if (ha->edc_data)
+ dma_pool_free(ha->s_dma_pool, ha->edc_data, ha->edc_data_dma);
+
if (ha->ms_iocb)
dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
+ if (ha->ex_init_cb)
+ dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma);
+
if (ha->s_dma_pool)
dma_pool_destroy(ha->s_dma_pool);
-
if (ha->gid_list)
dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,
ha->gid_list_dma);
-
if (ha->init_cb)
dma_free_coherent(&ha->pdev->dev, ha->init_cb_size,
ha->init_cb, ha->init_cb_dma);
@@ -2428,6 +2374,8 @@ qla2x00_mem_free(struct qla_hw_data *ha)
ha->ms_iocb_dma = 0;
ha->init_cb = NULL;
ha->init_cb_dma = 0;
+ ha->ex_init_cb = NULL;
+ ha->ex_init_cb_dma = 0;
ha->s_dma_pool = NULL;
@@ -2914,19 +2862,11 @@ qla2x00_timer(scsi_qla_host_t *vha)
spin_unlock_irqrestore(&ha->hardware_lock,
cpu_flags);
}
- set_bit(ABORT_QUEUES_NEEDED, &vha->dpc_flags);
start_dpc++;
}
/* if the loop has been down for 4 minutes, reinit adapter */
if (atomic_dec_and_test(&vha->loop_down_timer) != 0) {
- DEBUG(printk("scsi(%ld): Loop down exceed 4 mins - "
- "restarting queues.\n",
- vha->host_no));
-
- set_bit(RESTART_QUEUES_NEEDED, &vha->dpc_flags);
- start_dpc++;
-
if (!(vha->device_flags & DFLG_NO_CABLE) &&
!vha->vp_idx) {
DEBUG(printk("scsi(%ld): Loop down - "
@@ -3053,6 +2993,8 @@ qla2x00_release_firmware(void)
static pci_ers_result_t
qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
{
+ scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
+
switch (state) {
case pci_channel_io_normal:
return PCI_ERS_RESULT_CAN_RECOVER;
@@ -3060,7 +3002,7 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
pci_disable_device(pdev);
return PCI_ERS_RESULT_NEED_RESET;
case pci_channel_io_perm_failure:
- qla2x00_remove_one(pdev);
+ qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
return PCI_ERS_RESULT_DISCONNECT;
}
return PCI_ERS_RESULT_NEED_RESET;
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 284827926ef..152ecfc26cd 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -612,8 +612,8 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
/* Good data. Use specified location. */
loc = locations[1];
- *start = le16_to_cpu(fltl->start_hi) << 16 |
- le16_to_cpu(fltl->start_lo);
+ *start = (le16_to_cpu(fltl->start_hi) << 16 |
+ le16_to_cpu(fltl->start_lo)) >> 2;
end:
DEBUG2(qla_printk(KERN_DEBUG, ha, "FLTL[%s] = 0x%x.\n", loc, *start));
return QLA_SUCCESS;
@@ -629,6 +629,14 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
{ FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR_81 };
const uint32_t def_vpd_nvram[] =
{ FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR_81 };
+ const uint32_t def_vpd0[] =
+ { 0, 0, FA_VPD0_ADDR_81 };
+ const uint32_t def_vpd1[] =
+ { 0, 0, FA_VPD1_ADDR_81 };
+ const uint32_t def_nvram0[] =
+ { 0, 0, FA_NVRAM0_ADDR_81 };
+ const uint32_t def_nvram1[] =
+ { 0, 0, FA_NVRAM1_ADDR_81 };
const uint32_t def_fdt[] =
{ FA_FLASH_DESCR_ADDR_24, FA_FLASH_DESCR_ADDR,
FA_FLASH_DESCR_ADDR_81 };
@@ -693,6 +701,20 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
break;
case FLT_REG_VPD_0:
ha->flt_region_vpd_nvram = start;
+ if (!(PCI_FUNC(ha->pdev->devfn) & 1))
+ ha->flt_region_vpd = start;
+ break;
+ case FLT_REG_VPD_1:
+ if (PCI_FUNC(ha->pdev->devfn) & 1)
+ ha->flt_region_vpd = start;
+ break;
+ case FLT_REG_NVRAM_0:
+ if (!(PCI_FUNC(ha->pdev->devfn) & 1))
+ ha->flt_region_nvram = start;
+ break;
+ case FLT_REG_NVRAM_1:
+ if (PCI_FUNC(ha->pdev->devfn) & 1)
+ ha->flt_region_nvram = start;
break;
case FLT_REG_FDT:
ha->flt_region_fdt = start;
@@ -722,13 +744,18 @@ no_flash_data:
ha->flt_region_fw = def_fw[def];
ha->flt_region_boot = def_boot[def];
ha->flt_region_vpd_nvram = def_vpd_nvram[def];
+ ha->flt_region_vpd = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
+ def_vpd0[def]: def_vpd1[def];
+ ha->flt_region_nvram = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
+ def_nvram0[def]: def_nvram1[def];
ha->flt_region_fdt = def_fdt[def];
ha->flt_region_npiv_conf = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
def_npiv_conf0[def]: def_npiv_conf1[def];
done:
DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x "
- "vpd_nvram=0x%x fdt=0x%x flt=0x%x npiv=0x%x.\n", loc,
- ha->flt_region_boot, ha->flt_region_fw, ha->flt_region_vpd_nvram,
+ "vpd_nvram=0x%x vpd=0x%x nvram=0x%x fdt=0x%x flt=0x%x "
+ "npiv=0x%x.\n", loc, ha->flt_region_boot, ha->flt_region_fw,
+ ha->flt_region_vpd_nvram, ha->flt_region_vpd, ha->flt_region_nvram,
ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_npiv_conf));
}
@@ -931,31 +958,41 @@ done:
ha->npiv_info = NULL;
}
-static void
-qla24xx_unprotect_flash(struct qla_hw_data *ha)
+static int
+qla24xx_unprotect_flash(scsi_qla_host_t *vha)
{
+ struct qla_hw_data *ha = vha->hw;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+ if (ha->flags.fac_supported)
+ return qla81xx_fac_do_write_enable(vha, 1);
+
/* Enable flash write. */
WRT_REG_DWORD(&reg->ctrl_status,
RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */
if (!ha->fdt_wrt_disable)
- return;
+ goto done;
/* Disable flash write-protection, first clear SR protection bit */
qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
/* Then write zero again to clear remaining SR bits.*/
qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
+done:
+ return QLA_SUCCESS;
}
-static void
-qla24xx_protect_flash(struct qla_hw_data *ha)
+static int
+qla24xx_protect_flash(scsi_qla_host_t *vha)
{
uint32_t cnt;
+ struct qla_hw_data *ha = vha->hw;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+ if (ha->flags.fac_supported)
+ return qla81xx_fac_do_write_enable(vha, 0);
+
if (!ha->fdt_wrt_disable)
goto skip_wrt_protect;
@@ -973,6 +1010,26 @@ skip_wrt_protect:
WRT_REG_DWORD(&reg->ctrl_status,
RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */
+
+ return QLA_SUCCESS;
+}
+
+static int
+qla24xx_erase_sector(scsi_qla_host_t *vha, uint32_t fdata)
+{
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t start, finish;
+
+ if (ha->flags.fac_supported) {
+ start = fdata >> 2;
+ finish = start + (ha->fdt_block_size >> 2) - 1;
+ return qla81xx_fac_erase_sector(vha, flash_data_addr(ha,
+ start), flash_data_addr(ha, finish));
+ }
+
+ return qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd,
+ (fdata & 0xff00) | ((fdata << 16) & 0xff0000) |
+ ((fdata >> 16) & 0xff));
}
static int
@@ -987,8 +1044,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
void *optrom = NULL;
struct qla_hw_data *ha = vha->hw;
- ret = QLA_SUCCESS;
-
/* Prepare burst-capable write on supported ISPs. */
if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && !(faddr & 0xfff) &&
dwords > OPTROM_BURST_DWORDS) {
@@ -1004,7 +1059,12 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
rest_addr = (ha->fdt_block_size >> 2) - 1;
sec_mask = ~rest_addr;
- qla24xx_unprotect_flash(ha);
+ ret = qla24xx_unprotect_flash(vha);
+ if (ret != QLA_SUCCESS) {
+ qla_printk(KERN_WARNING, ha,
+ "Unable to unprotect flash for update.\n");
+ goto done;
+ }
for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) {
fdata = (faddr & sec_mask) << 2;
@@ -1017,9 +1077,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
ha->fdt_unprotect_sec_cmd,
(fdata & 0xff00) | ((fdata << 16) &
0xff0000) | ((fdata >> 16) & 0xff));
- ret = qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd,
- (fdata & 0xff00) |((fdata << 16) &
- 0xff0000) | ((fdata >> 16) & 0xff));
+ ret = qla24xx_erase_sector(vha, fdata);
if (ret != QLA_SUCCESS) {
DEBUG9(qla_printk("Unable to erase sector: "
"address=%x.\n", faddr));
@@ -1073,8 +1131,11 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
0xff0000) | ((fdata >> 16) & 0xff));
}
- qla24xx_protect_flash(ha);
-
+ ret = qla24xx_protect_flash(vha);
+ if (ret != QLA_SUCCESS)
+ qla_printk(KERN_WARNING, ha,
+ "Unable to protect flash after update.\n");
+done:
if (optrom)
dma_free_coherent(&ha->pdev->dev,
OPTROM_BURST_SIZE, optrom, optrom_dma);
@@ -1915,7 +1976,7 @@ qla2x00_resume_hba(struct scsi_qla_host *vha)
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
- qla2x00_wait_for_hba_online(vha);
+ qla2x00_wait_for_chip_reset(vha);
scsi_unblock_requests(vha->host);
}
@@ -2206,11 +2267,7 @@ qla24xx_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
rval = qla24xx_write_flash_data(vha, (uint32_t *)buf, offset >> 2,
length >> 2);
- /* Resume HBA -- RISC reset needed. */
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
- set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
- qla2xxx_wake_dpc(vha);
- qla2x00_wait_for_hba_online(vha);
scsi_unblock_requests(vha->host);
return rval;
@@ -2518,7 +2575,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
dcode = mbuf;
/* Begin with first PCI expansion ROM header. */
- pcihdr = ha->flt_region_boot;
+ pcihdr = ha->flt_region_boot << 2;
last_image = 1;
do {
/* Verify PCI expansion ROM header. */
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index a772eab2f0e..19d1afc3a34 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,9 +7,9 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.03.00-k4"
+#define QLA2XXX_VERSION "8.03.01-k1"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3
-#define QLA_DRIVER_PATCH_VER 0
+#define QLA_DRIVER_PATCH_VER 1
#define QLA_DRIVER_BETA_VER 0
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index eb3a414b189..ec9da6ce848 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -1369,16 +1369,16 @@ static void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha)
int retval;
/* Update our PCI device dma_mask for full 64 bit mask */
- if (pci_set_dma_mask(ha->pdev, DMA_64BIT_MASK) == 0) {
- if (pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) {
+ if (pci_set_dma_mask(ha->pdev, DMA_BIT_MASK(64)) == 0) {
+ if (pci_set_consistent_dma_mask(ha->pdev, DMA_BIT_MASK(64))) {
dev_dbg(&ha->pdev->dev,
"Failed to set 64 bit PCI consistent mask; "
"using 32 bit.\n");
retval = pci_set_consistent_dma_mask(ha->pdev,
- DMA_32BIT_MASK);
+ DMA_BIT_MASK(32));
}
} else
- retval = pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK);
+ retval = pci_set_dma_mask(ha->pdev, DMA_BIT_MASK(32));
}
static int qla4xxx_slave_alloc(struct scsi_device *sdev)
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index 69d6ad862b6..fa34b92850a 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -28,6 +28,7 @@
#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/firmware.h>
#include <asm/byteorder.h>
@@ -53,8 +54,6 @@
#define DEFAULT_LOOP_COUNT 10000
-#include "qlogicpti_asm.c"
-
static struct qlogicpti *qptichain = NULL;
static DEFINE_SPINLOCK(qptichain_lock);
@@ -465,16 +464,32 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host)
static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
{
+ const struct firmware *fw;
+ const char fwname[] = "qlogic/isp1000.bin";
+ const __le16 *fw_data;
struct Scsi_Host *host = qpti->qhost;
unsigned short csum = 0;
unsigned short param[6];
- unsigned short *risc_code, risc_code_addr, risc_code_length;
+ unsigned short risc_code_addr, risc_code_length;
+ int err;
unsigned long flags;
int i, timeout;
- risc_code = &sbus_risc_code01[0];
+ err = request_firmware(&fw, fwname, &qpti->op->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size % 2) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ err = -EINVAL;
+ goto outfirm;
+ }
+ fw_data = (const __le16 *)&fw->data[0];
risc_code_addr = 0x1000; /* all f/w modules load at 0x1000 */
- risc_code_length = sbus_risc_code_length01;
+ risc_code_length = fw->size / 2;
spin_lock_irqsave(host->host_lock, flags);
@@ -482,12 +497,12 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
* afterwards via the mailbox commands.
*/
for (i = 0; i < risc_code_length; i++)
- csum += risc_code[i];
+ csum += __le16_to_cpu(fw_data[i]);
if (csum) {
- spin_unlock_irqrestore(host->host_lock, flags);
printk(KERN_EMERG "qlogicpti%d: Aieee, firmware checksum failed!",
qpti->qpti_id);
- return 1;
+ err = 1;
+ goto out;
}
sbus_writew(SBUS_CTRL_RESET, qpti->qregs + SBUS_CTRL);
sbus_writew((DMA_CTRL_CCLEAR | DMA_CTRL_CIRQ), qpti->qregs + CMD_DMA_CTRL);
@@ -496,9 +511,9 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
while (--timeout && (sbus_readw(qpti->qregs + SBUS_CTRL) & SBUS_CTRL_RESET))
udelay(20);
if (!timeout) {
- spin_unlock_irqrestore(host->host_lock, flags);
printk(KERN_EMERG "qlogicpti%d: Cannot reset the ISP.", qpti->qpti_id);
- return 1;
+ err = 1;
+ goto out;
}
sbus_writew(HCCTRL_RESET, qpti->qregs + HCCTRL);
@@ -536,21 +551,21 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
if (qlogicpti_mbox_command(qpti, param, 1)) {
printk(KERN_EMERG "qlogicpti%d: Cannot stop firmware for reload.\n",
qpti->qpti_id);
- spin_unlock_irqrestore(host->host_lock, flags);
- return 1;
+ err = 1;
+ goto out;
}
/* Load it up.. */
for (i = 0; i < risc_code_length; i++) {
param[0] = MBOX_WRITE_RAM_WORD;
param[1] = risc_code_addr + i;
- param[2] = risc_code[i];
+ param[2] = __le16_to_cpu(fw_data[i]);
if (qlogicpti_mbox_command(qpti, param, 1) ||
param[0] != MBOX_COMMAND_COMPLETE) {
printk("qlogicpti%d: Firmware dload failed, I'm bolixed!\n",
qpti->qpti_id);
- spin_unlock_irqrestore(host->host_lock, flags);
- return 1;
+ err = 1;
+ goto out;
}
}
@@ -569,8 +584,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
(param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: New firmware csum failure!\n",
qpti->qpti_id);
- spin_unlock_irqrestore(host->host_lock, flags);
- return 1;
+ err = 1;
+ goto out;
}
/* Start using newly downloaded firmware. */
@@ -583,8 +598,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
(param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: AboutFirmware cmd fails.\n",
qpti->qpti_id);
- spin_unlock_irqrestore(host->host_lock, flags);
- return 1;
+ err = 1;
+ goto out;
}
/* Snag the major and minor revisions from the result. */
@@ -599,8 +614,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
(param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: could not set clock rate.\n",
qpti->qpti_id);
- spin_unlock_irqrestore(host->host_lock, flags);
- return 1;
+ err = 1;
+ goto out;
}
if (qpti->is_pti != 0) {
@@ -616,8 +631,11 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
qlogicpti_mbox_command(qpti, param, 1);
}
+out:
spin_unlock_irqrestore(host->host_lock, flags);
- return 0;
+outfirm:
+ release_firmware(fw);
+ return err;
}
static int qlogicpti_verify_tmon(struct qlogicpti *qpti)
@@ -1458,6 +1476,7 @@ MODULE_DESCRIPTION("QlogicISP SBUS driver");
MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
MODULE_LICENSE("GPL");
MODULE_VERSION("2.1");
+MODULE_FIRMWARE("qlogic/isp1000.bin");
module_init(qpti_init);
module_exit(qpti_exit);
diff --git a/drivers/scsi/qlogicpti_asm.c b/drivers/scsi/qlogicpti_asm.c
deleted file mode 100644
index 19aa84f4601..00000000000
--- a/drivers/scsi/qlogicpti_asm.c
+++ /dev/null
@@ -1,1160 +0,0 @@
-/* Version 1.31.00 ISP1000 Initiator RISC firmware */
-unsigned short sbus_risc_code01[] __devinitdata = {
- 0x0078, 0x1030, 0x0000, 0x2419, 0x0000, 0x12ff, 0x2043, 0x4f50,
- 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932,
- 0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749,
- 0x4320, 0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049,
- 0x5350, 0x3130, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520,
- 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, 0x312e, 0x3331, 0x2020,
- 0x20b9, 0x1212, 0x20c1, 0x0008, 0x2071, 0x0010, 0x70c3, 0x0004,
- 0x20c9, 0x3fff, 0x2089, 0x10c8, 0x70c7, 0x4953, 0x70cb, 0x5020,
- 0x70cf, 0x2020, 0x70d3, 0x0001, 0x3f00, 0x70d6, 0x2031, 0x0030,
- 0x2079, 0x3500, 0x7863, 0x0000, 0x2fa0, 0x2009, 0x0327, 0x2011,
- 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109, 0x00c0, 0x1051, 0x789b,
- 0x0101, 0x780b, 0x0002, 0x780f, 0x0002, 0x784f, 0x0bb8, 0x2069,
- 0x3540, 0x00a8, 0x106a, 0x681b, 0x003c, 0x2009, 0x1313, 0x21b8,
- 0x0078, 0x106c, 0x681b, 0x0028, 0x6807, 0x0007, 0x680b, 0x00fa,
- 0x680f, 0x0008, 0x6813, 0x0005, 0x681f, 0x0000, 0x6823, 0x0006,
- 0x6817, 0x0008, 0x6827, 0x0000, 0x2069, 0x3600, 0x2011, 0x0020,
- 0x2009, 0x0010, 0x680b, 0x0c19, 0x680f, 0x0019, 0x6803, 0xdd00,
- 0x6807, 0x001a, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004,
- 0x8109, 0x00c0, 0x1082, 0x2069, 0x3680, 0x20a9, 0x0080, 0x6837,
- 0x0000, 0x680b, 0x0040, 0x6817, 0x0100, 0x681f, 0x0064, 0xade8,
- 0x0010, 0x0070, 0x10a5, 0x0078, 0x1097, 0x1078, 0x1a38, 0x1078,
- 0x2f3a, 0x1078, 0x1681, 0x1078, 0x33ba, 0x3200, 0xa085, 0x000d,
- 0x2090, 0x70c3, 0x0000, 0x0090, 0x10bc, 0x70c0, 0xa086, 0x0002,
- 0x00c0, 0x10bc, 0x1078, 0x11ba, 0x1078, 0x10ec, 0x1078, 0x1817,
- 0x1078, 0x19a8, 0x1078, 0x327d, 0x1078, 0x177d, 0x0078, 0x10bc,
- 0x10d0, 0x10d2, 0x1bc3, 0x1bc3, 0x2f98, 0x2f98, 0x1bc3, 0x1bc3,
- 0x0078, 0x10d0, 0x0078, 0x10d2, 0x0078, 0x10d4, 0x0078, 0x10d6,
- 0x7008, 0x800c, 0x00c8, 0x10e7, 0x7007, 0x0002, 0xa08c, 0x000c,
- 0x00c0, 0x10e8, 0x8004, 0x8004, 0x00c8, 0x10e7, 0x087a, 0x097a,
- 0x70c3, 0x4002, 0x0078, 0x11bd, 0x7814, 0xa005, 0x00c0, 0x10f4,
- 0x0010, 0x1130, 0x0078, 0x112f, 0x2009, 0x3568, 0x2104, 0xa005,
- 0x00c0, 0x112f, 0x7814, 0xa086, 0x0001, 0x00c0, 0x1101, 0x1078,
- 0x1536, 0x7817, 0x0000, 0x2009, 0x356f, 0x2104, 0xa065, 0x0040,
- 0x111d, 0x2009, 0x356a, 0x211c, 0x8108, 0x2114, 0x8108, 0x2104,
- 0xa210, 0xa399, 0x0000, 0x2009, 0x001c, 0x6083, 0x0103, 0x1078,
- 0x1611, 0x00c0, 0x1129, 0x1078, 0x1678, 0x2009, 0x356f, 0x200b,
- 0x0000, 0x2009, 0x3569, 0x2104, 0x200b, 0x0000, 0xa005, 0x0040,
- 0x112d, 0x2001, 0x4005, 0x0078, 0x11bc, 0x0078, 0x11ba, 0x007c,
- 0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x0040, 0x1138, 0x007c,
- 0x70c3, 0x0000, 0x70c7, 0x0000, 0x70cb, 0x0000, 0x70cf, 0x0000,
- 0x70c0, 0xa0bc, 0xffc0, 0x00c0, 0x1188, 0x2038, 0x0079, 0x1148,
- 0x11ba, 0x1205, 0x11d3, 0x1205, 0x1256, 0x1256, 0x11ca, 0x1590,
- 0x1261, 0x11c6, 0x11d7, 0x11d9, 0x11db, 0x11dd, 0x1595, 0x11c6,
- 0x1267, 0x1283, 0x1544, 0x158a, 0x11df, 0x146b, 0x148d, 0x14a7,
- 0x14d0, 0x1424, 0x1432, 0x1446, 0x145a, 0x12ef, 0x11c6, 0x129f,
- 0x12a6, 0x12ab, 0x12b0, 0x12b6, 0x12bb, 0x12c0, 0x12c5, 0x12ca,
- 0x12ce, 0x12e3, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x12fb,
- 0x1304, 0x1313, 0x1339, 0x1343, 0x134a, 0x1370, 0x137f, 0x138e,
- 0x13a0, 0x1409, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x1419,
- 0xa0bc, 0xffa0, 0x00c0, 0x11c6, 0x2038, 0xa084, 0x001f, 0x0079,
- 0x1191, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6,
- 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6,
- 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6,
- 0x11c6, 0x11c6, 0x11c6, 0x15ed, 0x15f7, 0x15fb, 0x1609, 0x11c6,
- 0x11c6, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078, 0x11bc, 0x73ce,
- 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x2061, 0x0000, 0x601b,
- 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x007c, 0x70c3, 0x4001,
- 0x0078, 0x11bd, 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005,
- 0x53a3, 0x0078, 0x11ba, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078,
- 0x11ba, 0x0078, 0x11ba, 0x0078, 0x11ba, 0x0078, 0x11ba, 0x2091,
- 0x8000, 0x70c3, 0x0000, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf,
- 0x2020, 0x70d3, 0x0001, 0x3f00, 0x70d6, 0x2079, 0x0000, 0x781b,
- 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x0457, 0x2051,
- 0x0470, 0x2061, 0x0472, 0x20b9, 0xffff, 0x20c1, 0x0000, 0x2091,
- 0x5000, 0x2091, 0x4080, 0x0078, 0x0455, 0x71d0, 0x72c8, 0x73cc,
- 0x70c4, 0x20a0, 0x2098, 0x2031, 0x0030, 0x81ff, 0x0040, 0x11ba,
- 0x7007, 0x0004, 0x731a, 0x721e, 0x2051, 0x0012, 0x2049, 0x1234,
- 0x2041, 0x11ba, 0x7003, 0x0002, 0xa786, 0x0001, 0x00c0, 0x1226,
- 0x2049, 0x1242, 0x2041, 0x124e, 0x7003, 0x0003, 0x7017, 0x0000,
- 0x810b, 0x7112, 0x00c8, 0x122e, 0x7017, 0x0001, 0x7007, 0x0001,
- 0xa786, 0x0001, 0x0040, 0x1242, 0x700c, 0xa084, 0x007f, 0x8004,
- 0x2009, 0x0020, 0xa102, 0x0942, 0x094a, 0x20a8, 0x26a0, 0x53a6,
- 0x0078, 0x10d8, 0x700c, 0xa084, 0x007f, 0x0040, 0x1242, 0x80ac,
- 0x0048, 0x1242, 0x2698, 0x53a5, 0x0078, 0x10d8, 0x700c, 0xa084,
- 0x007f, 0x80ac, 0x2698, 0x53a5, 0x0078, 0x11ba, 0x71c4, 0x70c8,
- 0x2114, 0xa79e, 0x0004, 0x00c0, 0x125e, 0x200a, 0x72ca, 0x0078,
- 0x11b9, 0x70c7, 0x0001, 0x70cb, 0x001f, 0x0078, 0x11ba, 0x70c4,
- 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005,
- 0x0040, 0x127d, 0x8001, 0x7872, 0x7a7a, 0x7b7e, 0x7c76, 0x7898,
- 0xa084, 0xfffc, 0x789a, 0x0078, 0x1281, 0x7898, 0xa085, 0x0001,
- 0x789a, 0x0078, 0x11ba, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6,
- 0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0040, 0x1299, 0x8001, 0x7886,
- 0x7a8e, 0x7b92, 0x7c8a, 0x7898, 0xa084, 0xfcff, 0x789a, 0x0078,
- 0x129d, 0x7898, 0xa085, 0x0100, 0x789a, 0x0078, 0x11ba, 0x2009,
- 0x3559, 0x210c, 0x2011, 0x0410, 0x0078, 0x11b8, 0x2009, 0x3541,
- 0x210c, 0x0078, 0x11b9, 0x2009, 0x3542, 0x210c, 0x0078, 0x11b9,
- 0x2061, 0x3540, 0x610c, 0x6210, 0x0078, 0x11b8, 0x2009, 0x3545,
- 0x210c, 0x0078, 0x11b9, 0x2009, 0x3546, 0x210c, 0x0078, 0x11b9,
- 0x2009, 0x3547, 0x210c, 0x0078, 0x11b9, 0x2009, 0x3548, 0x210c,
- 0x0078, 0x11b9, 0x7908, 0x7a0c, 0x0078, 0x11b8, 0x71c4, 0x8107,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8, 0x3600, 0x6a00,
- 0x6804, 0xa084, 0x0008, 0x0040, 0x12e0, 0x6b08, 0x0078, 0x12e1,
- 0x6b0c, 0x0078, 0x11b7, 0x77c4, 0x1078, 0x1692, 0x2091, 0x8000,
- 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x11b7, 0x77c4,
- 0x1078, 0x1692, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x2091,
- 0x8001, 0x0078, 0x11b7, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x11b2,
- 0x1078, 0x1abc, 0x0078, 0x11b7, 0x71c4, 0xa182, 0x0010, 0x00c8,
- 0x11b2, 0x2011, 0x3541, 0x2204, 0x007e, 0x2112, 0x1078, 0x1a75,
- 0x017f, 0x0078, 0x11b9, 0x71c4, 0x2011, 0x1331, 0x20a9, 0x0008,
- 0x2204, 0xa106, 0x0040, 0x1323, 0x8210, 0x0070, 0x1321, 0x0078,
- 0x1318, 0x0078, 0x11b2, 0xa292, 0x1331, 0x027e, 0x2011, 0x3542,
- 0x2204, 0x2112, 0x017f, 0x007e, 0x1078, 0x1a81, 0x017f, 0x0078,
- 0x11b9, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032,
- 0x004b, 0x2061, 0x3540, 0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8,
- 0x6012, 0x0078, 0x11b8, 0x2061, 0x3540, 0x6114, 0x70c4, 0x6016,
- 0x0078, 0x11b9, 0x71c4, 0x2011, 0x0004, 0x2019, 0x1212, 0xa186,
- 0x0028, 0x0040, 0x1363, 0x2011, 0x0005, 0x2019, 0x1212, 0xa186,
- 0x0032, 0x0040, 0x1363, 0x2011, 0x0006, 0x2019, 0x1313, 0xa186,
- 0x003c, 0x00c0, 0x11b2, 0x2061, 0x3540, 0x6018, 0x007e, 0x611a,
- 0x23b8, 0x1078, 0x1a92, 0x1078, 0x33ba, 0x017f, 0x0078, 0x11b9,
- 0x71c4, 0xa184, 0xffcf, 0x00c0, 0x11b2, 0x2011, 0x3547, 0x2204,
- 0x2112, 0x007e, 0x1078, 0x1ab4, 0x017f, 0x0078, 0x11b9, 0x71c4,
- 0xa182, 0x0010, 0x00c8, 0x11b2, 0x2011, 0x3548, 0x2204, 0x007e,
- 0x2112, 0x1078, 0x1aa3, 0x017f, 0x0078, 0x11b9, 0x71c4, 0x72c8,
- 0xa184, 0xfffd, 0x00c0, 0x11b1, 0xa284, 0xfffd, 0x00c0, 0x11b1,
- 0x2100, 0x7908, 0x780a, 0x2200, 0x7a0c, 0x780e, 0x0078, 0x11b8,
- 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
- 0x3600, 0x2019, 0x0000, 0x72c8, 0x6800, 0x007e, 0xa226, 0x0040,
- 0x13cf, 0x6a02, 0xa484, 0x2000, 0x0040, 0x13b8, 0xa39d, 0x0010,
- 0xa484, 0x1000, 0x0040, 0x13be, 0xa39d, 0x0008, 0xa484, 0x4000,
- 0x0040, 0x13cf, 0x810f, 0xa284, 0x4000, 0x0040, 0x13cb, 0x1078,
- 0x1ad6, 0x0078, 0x13cf, 0x1078, 0x1ac8, 0x0078, 0x13cf, 0x72cc,
- 0x82ff, 0x0040, 0x1401, 0x6808, 0xa206, 0x0040, 0x1401, 0xa2a4,
- 0x00ff, 0x2061, 0x3540, 0x6118, 0xa186, 0x0028, 0x0040, 0x13e8,
- 0xa186, 0x0032, 0x0040, 0x13ee, 0xa186, 0x003c, 0x0040, 0x13f4,
- 0xa482, 0x0064, 0x0048, 0x13fe, 0x0078, 0x13f8, 0xa482, 0x0050,
- 0x0048, 0x13fe, 0x0078, 0x13f8, 0xa482, 0x0043, 0x0048, 0x13fe,
- 0x71c4, 0x71c6, 0x027f, 0x72ca, 0x0078, 0x11b3, 0x6a0a, 0xa39d,
- 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x0078,
- 0x11b7, 0x77c4, 0x1078, 0x1692, 0x2091, 0x8000, 0x6a14, 0x6b1c,
- 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0078,
- 0x11b7, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, 0x11b2,
- 0x1078, 0x1ae4, 0x0078, 0x11b7, 0x77c4, 0x1078, 0x1692, 0x2091,
- 0x8000, 0x6a08, 0xa295, 0x0002, 0x6a0a, 0x2091, 0x8001, 0x2708,
- 0x0078, 0x11b8, 0x77c4, 0x1078, 0x1692, 0x2091, 0x8000, 0x6a08,
- 0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1441, 0x1078,
- 0x1a19, 0x2091, 0x8001, 0x2708, 0x0078, 0x11b8, 0x77c4, 0x1078,
- 0x1692, 0x2091, 0x8000, 0x6a08, 0xa295, 0x0004, 0x6a0a, 0x6804,
- 0xa005, 0x0040, 0x1455, 0x1078, 0x1a19, 0x2091, 0x8001, 0x2708,
- 0x0078, 0x11b8, 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051,
- 0x0020, 0x2091, 0x8000, 0x1078, 0x169f, 0x2091, 0x8001, 0x2708,
- 0x6a08, 0x0078, 0x11b8, 0x77c4, 0x72c8, 0x73cc, 0x77c6, 0x72ca,
- 0x73ce, 0x1078, 0x1718, 0x00c0, 0x1489, 0x6818, 0xa005, 0x0040,
- 0x1483, 0x2708, 0x1078, 0x1af4, 0x00c0, 0x1483, 0x7817, 0xffff,
- 0x2091, 0x8001, 0x007c, 0x2091, 0x8001, 0x2001, 0x4005, 0x0078,
- 0x11bc, 0x2091, 0x8001, 0x0078, 0x11ba, 0x77c4, 0x77c6, 0x2041,
- 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
- 0x169f, 0x2061, 0x3540, 0x60a3, 0x0003, 0x67b6, 0x60a7, 0x0000,
- 0x7817, 0xffff, 0x2091, 0x8001, 0x1078, 0x1a19, 0x007c, 0x77c8,
- 0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2061,
- 0x3540, 0x60a3, 0x0002, 0x60a7, 0x0000, 0x67b6, 0x7817, 0xffff,
- 0x1078, 0x1a19, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049, 0x0004,
- 0x2051, 0x0010, 0x2091, 0x8000, 0x1078, 0x169f, 0x70c8, 0x6836,
- 0x8738, 0xa784, 0x0007, 0x00c0, 0x14c4, 0x2091, 0x8001, 0x007c,
- 0x7898, 0xa084, 0x0003, 0x00c0, 0x14f4, 0x2039, 0x0000, 0x2041,
- 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x1078, 0x1692, 0x2091,
- 0x8000, 0x6808, 0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784,
- 0x0007, 0x00c0, 0x14dd, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f,
- 0xa784, 0x0f00, 0x00c0, 0x14dd, 0x2091, 0x8000, 0x2069, 0x0100,
- 0x6830, 0xa084, 0x0040, 0x0040, 0x151d, 0x684b, 0x0004, 0x20a9,
- 0x0014, 0x6848, 0xa084, 0x0004, 0x0040, 0x150a, 0x0070, 0x150a,
- 0x0078, 0x1501, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084,
- 0x0001, 0x0040, 0x1517, 0x0070, 0x1517, 0x0078, 0x150e, 0x20a9,
- 0x00fa, 0x0070, 0x151d, 0x0078, 0x1519, 0x2079, 0x3500, 0x7817,
- 0x0001, 0x2061, 0x3540, 0x60a3, 0x0001, 0x60a7, 0x0000, 0x60c3,
- 0x000f, 0x7898, 0xa085, 0x0002, 0x789a, 0x6808, 0xa084, 0xfffd,
- 0x680a, 0x681b, 0x0046, 0x2091, 0x8001, 0x007c, 0x7898, 0xa084,
- 0xfffd, 0x789a, 0xa084, 0x0001, 0x00c0, 0x1540, 0x1078, 0x1760,
- 0x71c4, 0x71c6, 0x794a, 0x007c, 0x74c4, 0x73c8, 0x72cc, 0x74c6,
- 0x73ca, 0x72ce, 0x2079, 0x3500, 0x2009, 0x0040, 0x1078, 0x166f,
- 0x0040, 0x1586, 0x1078, 0x163f, 0x0040, 0x155a, 0x1078, 0x1678,
- 0x0078, 0x1586, 0x6010, 0x2091, 0x8001, 0x7817, 0xffff, 0x2009,
- 0x3568, 0x200b, 0x0005, 0x8108, 0x200b, 0x0000, 0x8108, 0x230a,
- 0x8108, 0x220a, 0x8108, 0x240a, 0x8108, 0x200a, 0x8108, 0x200b,
- 0x0000, 0x8108, 0x2c0a, 0xa02e, 0x2530, 0x0e7e, 0x1078, 0x2f13,
- 0x0e7f, 0x6592, 0x65a2, 0x6696, 0x66a6, 0x60ab, 0x0000, 0x60af,
- 0x0000, 0x2091, 0x8001, 0x1078, 0x1a19, 0x007c, 0x70c3, 0x4005,
- 0x0078, 0x11bd, 0x71c4, 0x70c7, 0x0000, 0x7906, 0x0078, 0x11ba,
- 0x71c4, 0x71c6, 0x2168, 0x0078, 0x1597, 0x2069, 0x1000, 0x690c,
- 0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0, 0x1599, 0xa285,
- 0x0000, 0x00c0, 0x15a7, 0x70c3, 0x4000, 0x0078, 0x15a9, 0x70c3,
- 0x4003, 0x70ca, 0x0078, 0x11bd, 0x71c4, 0x72c8, 0x73cc, 0x2100,
- 0xa184, 0xfffc, 0x00c0, 0x11c6, 0x2100, 0x0079, 0x15b7, 0x15ce,
- 0x15e3, 0x15e5, 0x15e7, 0x70c3, 0x4003, 0x71ce, 0x72d2, 0x73d6,
- 0x0078, 0x15ca, 0x70c3, 0x4000, 0x70cf, 0x0000, 0x70d3, 0x0000,
- 0x70d7, 0x0000, 0x77c6, 0x71ca, 0x0078, 0x11ba, 0x2031, 0x15e9,
- 0x2624, 0x8630, 0x2412, 0x2204, 0xa446, 0x00c0, 0x15bb, 0xa484,
- 0xffff, 0x00c0, 0x15d0, 0x2031, 0x15e9, 0x8210, 0x8319, 0xa384,
- 0xffff, 0x00c0, 0x15d0, 0x0078, 0x15c2, 0x0078, 0x15c2, 0x0078,
- 0x15c2, 0x5555, 0xaaaa, 0xffff, 0x0000, 0x7960, 0x71c6, 0x71c4,
- 0xa182, 0x0003, 0x00c8, 0x11b2, 0x7962, 0x0078, 0x11ba, 0x7960,
- 0x71c6, 0x0078, 0x11ba, 0x7954, 0x71c6, 0x71c4, 0x7956, 0x7958,
- 0x71ca, 0x71c8, 0x795a, 0x795c, 0x71ce, 0x71cc, 0x795e, 0x0078,
- 0x11ba, 0x7954, 0x71c6, 0x7958, 0x71ca, 0x795c, 0x71ce, 0x0078,
- 0x11ba, 0x700c, 0xa084, 0x007f, 0x0040, 0x161d, 0x7007, 0x0004,
- 0x7004, 0xa084, 0x0004, 0x00c0, 0x1618, 0x7017, 0x0000, 0x7112,
- 0x721a, 0x731e, 0x8108, 0x810c, 0x81a9, 0x8c98, 0x20a1, 0x0030,
- 0x6080, 0x20a2, 0x53a6, 0x780c, 0xa085, 0x0000, 0x7002, 0x7007,
- 0x0001, 0x7108, 0x8104, 0x00c8, 0x1631, 0x7007, 0x0002, 0xa184,
- 0x000c, 0x710c, 0xa184, 0x0300, 0x7003, 0x0000, 0x007c, 0x700c,
- 0xa084, 0x007f, 0x0040, 0x164b, 0x7007, 0x0004, 0x7004, 0xa084,
- 0x0004, 0x00c0, 0x1646, 0x7017, 0x0000, 0x7112, 0x721a, 0x731e,
- 0x2099, 0x0030, 0x8108, 0x81ac, 0x780c, 0xa085, 0x0001, 0x7002,
- 0x7007, 0x0001, 0x7008, 0x800c, 0x00c8, 0x165a, 0x7007, 0x0002,
- 0xa08c, 0x000c, 0x00c0, 0x166c, 0x710c, 0xa184, 0x0300, 0x00c0,
- 0x166c, 0x2ca0, 0x53a5, 0xa006, 0x7003, 0x0000, 0x007c, 0x7850,
- 0xa065, 0x0040, 0x1677, 0x2c04, 0x7852, 0x2063, 0x0000, 0x007c,
- 0x0f7e, 0x2079, 0x3500, 0x7850, 0x2062, 0x2c00, 0x7852, 0x0f7f,
- 0x007c, 0x2011, 0x4000, 0x7a52, 0x2019, 0x0410, 0x8319, 0x0040,
- 0x168f, 0xa280, 0x002f, 0x2012, 0x2010, 0x0078, 0x1686, 0x2013,
- 0x0000, 0x007c, 0xa784, 0x0f00, 0x800c, 0xa784, 0x0007, 0x8003,
- 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e8, 0x3680, 0x007c, 0x1078,
- 0x1692, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xffef,
- 0xa80d, 0x690a, 0x2009, 0x354f, 0x210c, 0x6804, 0xa005, 0x0040,
- 0x16bc, 0xa116, 0x00c0, 0x16bc, 0x2060, 0x6000, 0x6806, 0x017e,
- 0x200b, 0x0000, 0x0078, 0x16bf, 0x2009, 0x0000, 0x017e, 0x6804,
- 0xa065, 0x0040, 0x16ce, 0x6000, 0x6806, 0x1078, 0x16df, 0x1078,
- 0x17cb, 0x6810, 0x8001, 0x6812, 0x00c0, 0x16bf, 0x017f, 0x6902,
- 0x6906, 0x007c, 0xa065, 0x0040, 0x16de, 0x6098, 0x609b, 0x0000,
- 0x2008, 0x1078, 0x1678, 0x2100, 0x0078, 0x16d2, 0x007c, 0x6003,
- 0x0103, 0x20a9, 0x001c, 0xac80, 0x0004, 0x20a0, 0x2001, 0x0000,
- 0x40a4, 0x6828, 0x6016, 0x682c, 0x601e, 0x007c, 0x0e7e, 0x2071,
- 0x3540, 0x7040, 0xa08c, 0x0080, 0x00c0, 0x16fc, 0xa088, 0x3580,
- 0x2d0a, 0x8000, 0x7042, 0xa006, 0x0e7f, 0x007c, 0x0e7e, 0x2071,
- 0x3540, 0x2009, 0x3580, 0x7240, 0x8221, 0x8211, 0x0048, 0x1716,
- 0x2104, 0x8108, 0xad06, 0x00c0, 0x1705, 0x8119, 0x211e, 0x8108,
- 0x8318, 0x8211, 0x00c8, 0x170e, 0x7442, 0xa006, 0x0e7f, 0x007c,
- 0x1078, 0x1692, 0x2091, 0x8000, 0x6804, 0x781e, 0xa065, 0x0040,
- 0x175f, 0x0078, 0x1729, 0x2c00, 0x781e, 0x6000, 0xa065, 0x0040,
- 0x175f, 0x600c, 0xa306, 0x00c0, 0x1723, 0x6008, 0xa206, 0x00c0,
- 0x1723, 0x2c28, 0x2001, 0x354f, 0x2004, 0xac06, 0x0040, 0x175f,
- 0x6804, 0xac06, 0x00c0, 0x1746, 0x6000, 0x2060, 0x6806, 0xa005,
- 0x00c0, 0x1746, 0x6803, 0x0000, 0x0078, 0x1750, 0x6400, 0x781c,
- 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1750, 0x2c00, 0x6802,
- 0x2560, 0x1078, 0x16df, 0x6017, 0x0005, 0x601f, 0x0020, 0x1078,
- 0x17cb, 0x6810, 0x8001, 0x6812, 0x2001, 0xffff, 0xa005, 0x007c,
- 0x2039, 0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008,
- 0x2091, 0x8000, 0x1078, 0x169f, 0x8738, 0xa784, 0x0007, 0x00c0,
- 0x176a, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00,
- 0x00c0, 0x176a, 0x2091, 0x8001, 0x007c, 0x2061, 0x0000, 0x6018,
- 0xa084, 0x0001, 0x00c0, 0x178a, 0x78ac, 0x78af, 0x0000, 0xa005,
- 0x00c0, 0x178b, 0x007c, 0xa08c, 0xfff0, 0x0040, 0x1791, 0x1078,
- 0x1ba5, 0x0079, 0x1793, 0x17a3, 0x17a5, 0x17ab, 0x17af, 0x17a3,
- 0x17b3, 0x17a3, 0x17a3, 0x17a3, 0x17a3, 0x17b9, 0x17bd, 0x17a3,
- 0x17a3, 0x17a3, 0x17a3, 0x1078, 0x1ba5, 0x1078, 0x1760, 0x2001,
- 0x8001, 0x0078, 0x17c3, 0x2001, 0x8003, 0x0078, 0x17c3, 0x2001,
- 0x8004, 0x0078, 0x17c3, 0x1078, 0x1760, 0x2001, 0x8006, 0x0078,
- 0x17c3, 0x2001, 0x800c, 0x0078, 0x17c3, 0x1078, 0x1760, 0x2001,
- 0x800d, 0x0078, 0x17c3, 0x70c2, 0x2061, 0x0000, 0x601b, 0x0001,
- 0x2091, 0x4080, 0x007c, 0x2c04, 0x6082, 0x2c08, 0x2063, 0x0000,
- 0x7864, 0x8000, 0x7866, 0x7868, 0xa005, 0x796a, 0x0040, 0x17db,
- 0x2c02, 0x0078, 0x17dc, 0x796e, 0x007c, 0x0c7e, 0x2061, 0x3500,
- 0x6883, 0x0103, 0x2d08, 0x206b, 0x0000, 0x6064, 0x8000, 0x6066,
- 0x6068, 0xa005, 0x616a, 0x0040, 0x17f0, 0x2d02, 0x0078, 0x17f1,
- 0x616e, 0x0c7f, 0x007c, 0x1078, 0x1804, 0x0040, 0x1803, 0x0c7e,
- 0x6098, 0xa065, 0x0040, 0x17fe, 0x1078, 0x16d2, 0x0c7f, 0x609b,
- 0x0000, 0x1078, 0x1678, 0x007c, 0x786c, 0xa065, 0x0040, 0x1816,
- 0x2091, 0x8000, 0x7864, 0x8001, 0x7866, 0x2c04, 0x786e, 0xa005,
- 0x00c0, 0x1814, 0x786a, 0x8000, 0x2091, 0x8001, 0x007c, 0x7898,
- 0xa005, 0x00c0, 0x1865, 0x7974, 0x70d0, 0x0005, 0x0005, 0x72d0,
- 0xa206, 0x00c0, 0x181c, 0x2200, 0xa106, 0x00c0, 0x1833, 0x7804,
- 0xa005, 0x0040, 0x1865, 0x7807, 0x0000, 0x0068, 0x1865, 0x2091,
- 0x4080, 0x0078, 0x1865, 0x1078, 0x166f, 0x0040, 0x1865, 0x7a7c,
- 0x7b78, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399, 0x0000, 0x2009,
- 0x0040, 0x1078, 0x163f, 0x0040, 0x185c, 0x1078, 0x1678, 0x7880,
- 0x8000, 0x7882, 0xa086, 0x0002, 0x00c0, 0x1865, 0x2091, 0x8000,
- 0x78af, 0x0002, 0x7883, 0x0000, 0x7898, 0xa085, 0x0003, 0x789a,
- 0x2091, 0x8001, 0x0078, 0x1865, 0x7883, 0x0000, 0x1078, 0x1992,
- 0x6000, 0xa084, 0x0007, 0x0079, 0x1866, 0x007c, 0x186e, 0x187d,
- 0x189d, 0x186e, 0x18af, 0x186e, 0x186e, 0x186e, 0x2039, 0x0400,
- 0x78a8, 0xa705, 0x78aa, 0x6004, 0xa705, 0x6006, 0x1078, 0x18ed,
- 0x6018, 0x78a6, 0x1078, 0x197a, 0x007c, 0x78a8, 0xa084, 0x0100,
- 0x0040, 0x1884, 0x0078, 0x186e, 0x78ab, 0x0000, 0x6000, 0x8007,
- 0xa084, 0x00ff, 0x789e, 0x8001, 0x609b, 0x0000, 0x0040, 0x189a,
- 0x1078, 0x18ed, 0x0040, 0x189a, 0x78a8, 0xa085, 0x0100, 0x78aa,
- 0x0078, 0x189c, 0x1078, 0x1911, 0x007c, 0x78a8, 0xa08c, 0x0e00,
- 0x00c0, 0x18a6, 0xa084, 0x0100, 0x00c0, 0x18a8, 0x0078, 0x186e,
- 0x1078, 0x18ed, 0x00c0, 0x18ae, 0x1078, 0x1911, 0x007c, 0x78a8,
- 0xa084, 0x0100, 0x0040, 0x18b6, 0x0078, 0x186e, 0x78ab, 0x0000,
- 0x6710, 0x20a9, 0x0001, 0x6014, 0xa084, 0x00ff, 0xa005, 0x0040,
- 0x18d3, 0xa7bc, 0xff00, 0x20a9, 0x0008, 0xa08e, 0x0001, 0x0040,
- 0x18d3, 0x2039, 0x0000, 0x20a9, 0x0080, 0xa08e, 0x0002, 0x0040,
- 0x18d3, 0x0078, 0x18ea, 0x1078, 0x1692, 0x2d00, 0x2091, 0x8000,
- 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, 0xffde, 0x680a,
- 0x2d00, 0xa080, 0x0010, 0x2068, 0x2091, 0x8001, 0x0070, 0x18ea,
- 0x0078, 0x18d6, 0x1078, 0x1678, 0x007c, 0x78a0, 0xa06d, 0x00c0,
- 0x18f8, 0x2c00, 0x78a2, 0x78a6, 0x609b, 0x0000, 0x0078, 0x1904,
- 0x2c00, 0x689a, 0x609b, 0x0000, 0x78a2, 0x2d00, 0x6002, 0x78a4,
- 0xad06, 0x00c0, 0x1904, 0x6002, 0x789c, 0x8001, 0x789e, 0x00c0,
- 0x1910, 0x78a8, 0xa084, 0x0000, 0x78aa, 0x78a4, 0x2060, 0xa006,
- 0x007c, 0xa02e, 0x2530, 0x6118, 0xa184, 0x0060, 0x619e, 0x0040,
- 0x191d, 0x0e7e, 0x1078, 0x2f13, 0x0e7f, 0x6592, 0x65a2, 0x6696,
- 0x66a6, 0x60ab, 0x0000, 0x60af, 0x0000, 0x6710, 0x1078, 0x1692,
- 0x2091, 0x8000, 0x6808, 0xa084, 0x0001, 0x0040, 0x193f, 0x2091,
- 0x8001, 0x1078, 0x16df, 0x2091, 0x8000, 0x1078, 0x17cb, 0x2091,
- 0x8001, 0x78a3, 0x0000, 0x78a7, 0x0000, 0x0078, 0x1979, 0x6020,
- 0xa096, 0x0001, 0x00c0, 0x1946, 0x8000, 0x6022, 0x6a10, 0x6814,
- 0x2091, 0x8001, 0xa202, 0x0048, 0x1955, 0x0040, 0x1955, 0x2039,
- 0x0200, 0x1078, 0x197a, 0x0078, 0x1979, 0x2c08, 0x2091, 0x8000,
- 0x6800, 0xa065, 0x0040, 0x195d, 0x6102, 0x6902, 0x00c0, 0x1961,
- 0x6906, 0x2160, 0x6003, 0x0000, 0x6810, 0x8000, 0x6812, 0x2091,
- 0x8001, 0x6808, 0xa08c, 0x0040, 0x0040, 0x1973, 0xa086, 0x0040,
- 0x680a, 0x1078, 0x16ee, 0x1078, 0x1a19, 0x78a7, 0x0000, 0x78a3,
- 0x0000, 0x007c, 0x6004, 0xa705, 0x6006, 0x2091, 0x8000, 0x1078,
- 0x17cb, 0x2091, 0x8001, 0x78a4, 0xa065, 0x0040, 0x198d, 0x6098,
- 0x78a6, 0x609b, 0x0000, 0x0078, 0x197d, 0x78a3, 0x0000, 0x78a7,
- 0x0000, 0x007c, 0x7970, 0x7874, 0x8000, 0xa10a, 0x00c8, 0x1999,
- 0xa006, 0x7876, 0x70d2, 0x7804, 0xa005, 0x0040, 0x19a7, 0x8001,
- 0x7806, 0x00c0, 0x19a7, 0x0068, 0x19a7, 0x2091, 0x4080, 0x007c,
- 0x0068, 0x19c2, 0x2029, 0x0000, 0x786c, 0xa065, 0x0040, 0x19bd,
- 0x1078, 0x19c3, 0x0040, 0x19bd, 0x057e, 0x1078, 0x19d9, 0x057f,
- 0x00c0, 0x19bd, 0x8528, 0x0078, 0x19ac, 0x85ff, 0x0040, 0x19c2,
- 0x2091, 0x4080, 0x007c, 0x7b84, 0x7988, 0x72d4, 0x0005, 0x0005,
- 0x70d4, 0xa206, 0x00c0, 0x19c5, 0x2200, 0xa102, 0x00c0, 0x19d3,
- 0x2300, 0xa005, 0x007c, 0x0048, 0x19d7, 0xa302, 0x007c, 0x8002,
- 0x007c, 0x1078, 0x1a0b, 0x2009, 0x001c, 0x6024, 0xa005, 0x0040,
- 0x19e3, 0x2009, 0x0040, 0x1078, 0x1611, 0x0040, 0x19fc, 0x7894,
- 0x8000, 0x7896, 0xa086, 0x0002, 0x00c0, 0x1a0a, 0x2091, 0x8000,
- 0x78af, 0x0003, 0x7897, 0x0000, 0x7898, 0xa085, 0x0300, 0x789a,
- 0x2091, 0x8001, 0x0078, 0x1a0a, 0x7897, 0x0000, 0x1078, 0x17f3,
- 0x7984, 0x7888, 0x8000, 0xa10a, 0x00c8, 0x1a07, 0xa006, 0x788a,
- 0x70d6, 0xa006, 0x007c, 0x8107, 0x8004, 0x8004, 0x7a90, 0x7b8c,
- 0xa210, 0xa399, 0x0000, 0x007c, 0x2009, 0x3568, 0x2091, 0x8000,
- 0x200a, 0x0f7e, 0x2079, 0x0100, 0x2009, 0x3540, 0x2091, 0x8000,
- 0x2104, 0xa086, 0x0000, 0x00c0, 0x1a34, 0x2009, 0x3512, 0x2104,
- 0xa005, 0x00c0, 0x1a34, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x1a34,
- 0x0018, 0x1a34, 0x781b, 0x0044, 0x2091, 0x8001, 0x0f7f, 0x007c,
- 0x127e, 0x2091, 0x2300, 0x2071, 0x3540, 0x2079, 0x0100, 0x2019,
- 0x2dd8, 0x20a1, 0x012b, 0x2304, 0xa005, 0x0040, 0x1a50, 0x789a,
- 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318, 0x0078, 0x1a43,
- 0x789b, 0x0020, 0x20a9, 0x0010, 0x78af, 0x0000, 0x78af, 0x0220,
- 0x0070, 0x1a5c, 0x0078, 0x1a54, 0x7003, 0x0000, 0x1078, 0x1b5b,
- 0x7004, 0xa084, 0x000f, 0xa085, 0x6280, 0x7806, 0x780f, 0x9200,
- 0x7843, 0x00d8, 0x7853, 0x0080, 0x780b, 0x0038, 0x7047, 0x357f,
- 0x7043, 0x0000, 0x127f, 0x2000, 0x007c, 0xa18c, 0x000f, 0x2011,
- 0x0101, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012, 0x1078, 0x1b5b,
- 0x007c, 0x2011, 0x0101, 0x20a9, 0x0009, 0x810b, 0x0070, 0x1a8a,
- 0x0078, 0x1a85, 0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105,
- 0x2012, 0x007c, 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x0070,
- 0x1a9b, 0x0078, 0x1a96, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f,
- 0xa205, 0x200a, 0x007c, 0x2011, 0x0101, 0x20a9, 0x000c, 0x810b,
- 0x0070, 0x1aac, 0x0078, 0x1aa7, 0xa18c, 0xf000, 0x2204, 0xa084,
- 0x0fff, 0xa105, 0x2012, 0x007c, 0x2011, 0x0102, 0x2204, 0xa084,
- 0xffcf, 0xa105, 0x2012, 0x007c, 0x8103, 0x8003, 0xa080, 0x0020,
- 0x0c7e, 0x2061, 0x0100, 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c,
- 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e, 0x2061, 0x0100, 0x609a,
- 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f, 0x007c, 0x8103, 0x8003,
- 0xa080, 0x0022, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0xa085,
- 0x0020, 0x60ae, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0020,
- 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0x62ae, 0x2010, 0x60a4,
- 0x63ae, 0x2018, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e,
- 0x6818, 0xa005, 0x0040, 0x1b39, 0x2061, 0x3f80, 0x1078, 0x1b41,
- 0x0040, 0x1b27, 0x20a9, 0x0000, 0x2061, 0x3e80, 0x0c7e, 0x1078,
- 0x1b41, 0x0040, 0x1b13, 0x0c7f, 0x8c60, 0x0070, 0x1b11, 0x0078,
- 0x1b06, 0x0078, 0x1b39, 0x007f, 0xa082, 0x3e80, 0x2071, 0x3540,
- 0x70ba, 0x601c, 0xa085, 0x0800, 0x601e, 0x71b6, 0x60a7, 0x0000,
- 0x2001, 0x0004, 0x70a2, 0x1078, 0x1a14, 0x0078, 0x1b35, 0x2071,
- 0x3540, 0x601c, 0xa085, 0x0800, 0x601e, 0x71b6, 0x60a7, 0x0000,
- 0x2001, 0x0006, 0x70a2, 0x1078, 0x1a14, 0x2001, 0x0000, 0x0078,
- 0x1b3b, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f,
- 0x007c, 0x2c04, 0xa005, 0x0040, 0x1b58, 0x2060, 0x600c, 0xa306,
- 0x00c0, 0x1b55, 0x6008, 0xa206, 0x00c0, 0x1b55, 0x6010, 0xa106,
- 0x00c0, 0x1b55, 0xa006, 0x0078, 0x1b5a, 0x6000, 0x0078, 0x1b42,
- 0xa085, 0x0001, 0x007c, 0x2011, 0x3541, 0x220c, 0xa18c, 0x000f,
- 0x2011, 0x013b, 0x2204, 0xa084, 0x0100, 0x0040, 0x1b6a, 0x2021,
- 0xff80, 0x2122, 0x007c, 0x0e7e, 0x68e4, 0xa08c, 0x0020, 0x0040,
- 0x1ba3, 0xa084, 0x0006, 0x00c0, 0x1ba3, 0x6010, 0x8007, 0xa084,
- 0x000f, 0x8003, 0x8003, 0x8003, 0xa0f0, 0x3600, 0x7004, 0xa084,
- 0x000a, 0x00c0, 0x1ba3, 0x7108, 0xa194, 0xff00, 0x0040, 0x1ba3,
- 0xa18c, 0x00ff, 0x2001, 0x0019, 0xa106, 0x0040, 0x1b96, 0x2001,
- 0x0032, 0xa106, 0x0040, 0x1b9a, 0x0078, 0x1b9e, 0x2009, 0x0020,
- 0x0078, 0x1ba0, 0x2009, 0x003f, 0x0078, 0x1ba0, 0x2011, 0x0000,
- 0x2100, 0xa205, 0x700a, 0x0e7f, 0x007c, 0x0068, 0x1ba5, 0x007e,
- 0x2071, 0x0000, 0x7018, 0xa084, 0x0001, 0x00c0, 0x1baa, 0x007f,
- 0x2e08, 0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002,
- 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x007f, 0x2070,
- 0x007f, 0x0078, 0x1bc1, 0x107e, 0x007e, 0x127e, 0x2091, 0x2300,
- 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0xa594, 0x003f, 0xa484, 0x4000,
- 0x0040, 0x1bd8, 0xa784, 0x007c, 0x00c0, 0x2d9c, 0x1078, 0x1ba5,
- 0xa49c, 0x000f, 0xa382, 0x0004, 0x0050, 0x1be0, 0x1078, 0x1ba5,
- 0x8507, 0xa084, 0x000f, 0x0079, 0x1be5, 0x1fea, 0x209a, 0x20c0,
- 0x22e6, 0x256b, 0x25b3, 0x25ea, 0x2665, 0x26bf, 0x2744, 0x1c0b,
- 0x1bf5, 0x1e53, 0x1f1d, 0x254a, 0x1bf5, 0x1078, 0x1ba5, 0x0018,
- 0x1bc8, 0x127f, 0x2091, 0x8001, 0x007f, 0x107f, 0x007c, 0x7003,
- 0x0000, 0x703f, 0x0000, 0x7030, 0xa005, 0x0040, 0x1c09, 0x7033,
- 0x0000, 0x0018, 0x1bc8, 0x705c, 0xa005, 0x00c0, 0x1cb6, 0x70a0,
- 0xa084, 0x0007, 0x0079, 0x1c14, 0x1cd6, 0x1c1c, 0x1c2a, 0x1c4b,
- 0x1c71, 0x1c9d, 0x1c9b, 0x1c1c, 0x7808, 0xa084, 0xfffd, 0x780a,
- 0x2009, 0x0046, 0x1078, 0x2412, 0x00c0, 0x1c28, 0x7003, 0x0004,
- 0x0078, 0x1bf7, 0x1078, 0x2d5e, 0x00c0, 0x1c49, 0x70b4, 0x8007,
- 0x789b, 0x007e, 0x78aa, 0x789b, 0x0010, 0x78ab, 0x000c, 0x789b,
- 0x0060, 0x78ab, 0x0001, 0x785b, 0x0004, 0x2009, 0x00f7, 0x1078,
- 0x2410, 0x00c0, 0x1c49, 0x7003, 0x0004, 0x70c3, 0x000f, 0x7033,
- 0x3570, 0x0078, 0x1bf7, 0x1078, 0x2d5e, 0x00c0, 0x1c6f, 0x71b4,
- 0x8107, 0x789b, 0x007e, 0x78aa, 0x789b, 0x0010, 0xa18c, 0x0007,
- 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab,
- 0x0002, 0x785b, 0x0004, 0x2009, 0x00f7, 0x1078, 0x2410, 0x00c0,
- 0x1c6f, 0x7003, 0x0004, 0x70c3, 0x000f, 0x7033, 0x3570, 0x0078,
- 0x1bf7, 0x1078, 0x2d5e, 0x00c0, 0x1c99, 0x71b4, 0x8107, 0x789b,
- 0x007e, 0x78aa, 0x789b, 0x0010, 0xa18c, 0x0007, 0xa18d, 0x00c0,
- 0x79aa, 0x78ab, 0x0020, 0x71b8, 0x79aa, 0x78ab, 0x000d, 0x789b,
- 0x0060, 0x78ab, 0x0004, 0x785b, 0x0004, 0x2009, 0x00f7, 0x1078,
- 0x2410, 0x00c0, 0x1c99, 0x7003, 0x0004, 0x70c3, 0x000f, 0x7033,
- 0x3570, 0x0078, 0x1bf7, 0x0078, 0x1c4b, 0x1078, 0x2d5e, 0x00c0,
- 0x1bf7, 0x70bc, 0x2068, 0x789b, 0x0010, 0x6f10, 0x1078, 0x2ca1,
- 0x2c50, 0x6810, 0xa084, 0x0007, 0xa085, 0x0080, 0x78aa, 0x6e18,
- 0x2041, 0x0001, 0x2001, 0x0004, 0x0078, 0x1dde, 0x1078, 0x2d5e,
- 0x00c0, 0x1bf7, 0x789b, 0x0010, 0x705c, 0x2068, 0x6f10, 0x1078,
- 0x2ca1, 0x2c50, 0x6008, 0xa085, 0x0010, 0x600a, 0x6810, 0xa084,
- 0x0007, 0xa085, 0x0080, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001,
- 0x1078, 0x2dc5, 0x2001, 0x0003, 0x0078, 0x1dc9, 0x0018, 0x1bc8,
- 0x7440, 0xa485, 0x0000, 0x0040, 0x1cf0, 0xa080, 0x3580, 0x2030,
- 0x7144, 0x8108, 0xa12a, 0x0048, 0x1ce7, 0x2009, 0x3580, 0x2164,
- 0x6504, 0x85ff, 0x00c0, 0x1cfd, 0x8421, 0x00c0, 0x1ce1, 0x7146,
- 0x7003, 0x0000, 0x703f, 0x0000, 0x0078, 0x1bf7, 0x7640, 0xa6b0,
- 0x3580, 0x7144, 0x2600, 0x0078, 0x1cec, 0x7146, 0x2568, 0x2558,
- 0x753e, 0x2c50, 0x6034, 0xa085, 0x0000, 0x00c0, 0x1cfa, 0x6708,
- 0x7736, 0xa784, 0x013f, 0x0040, 0x1d2f, 0xa784, 0x0021, 0x00c0,
- 0x1cfa, 0xa784, 0x0002, 0x0040, 0x1d1c, 0xa784, 0x0004, 0x0040,
- 0x1cfa, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0008, 0x00c0, 0x1cfa,
- 0xa784, 0x0010, 0x00c0, 0x1cfa, 0xa784, 0x0100, 0x0040, 0x1d2f,
- 0x6018, 0xa005, 0x00c0, 0x1cfa, 0xa7bc, 0xfeff, 0x670a, 0x681f,
- 0x0000, 0x6e18, 0xa684, 0x000e, 0x6118, 0x0040, 0x1d3f, 0x601c,
- 0xa102, 0x0048, 0x1d42, 0x0040, 0x1d42, 0x0078, 0x1cf6, 0x81ff,
- 0x00c0, 0x1cf6, 0xa784, 0x0080, 0x00c0, 0x1d48, 0x700c, 0x6022,
- 0xa7bc, 0xff7f, 0x670a, 0x6b10, 0x8307, 0xa084, 0x000f, 0x8003,
- 0x8003, 0x8003, 0xa080, 0x3600, 0x2060, 0x2048, 0x704a, 0x6000,
- 0x704e, 0x6004, 0x7052, 0x2a60, 0x0018, 0x1bc8, 0x789b, 0x0010,
- 0xa046, 0x1078, 0x2d5e, 0x00c0, 0x1bf7, 0x6b10, 0xa39c, 0x0007,
- 0xa39d, 0x00c0, 0x704c, 0xa084, 0x8000, 0x0040, 0x1d73, 0xa684,
- 0x0001, 0x0040, 0x1d75, 0xa39c, 0xffbf, 0xa684, 0x0010, 0x0040,
- 0x1d7b, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684, 0x000e, 0x00c0,
- 0x1d86, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x1dc7, 0x714c, 0xa18c,
- 0x0800, 0x0040, 0x2902, 0x2011, 0x0021, 0x8004, 0x8004, 0x0048,
- 0x1d9d, 0x2011, 0x0022, 0x8004, 0x0048, 0x1d9d, 0x2011, 0x0020,
- 0x8004, 0x0048, 0x1d9d, 0x0040, 0x1dc7, 0x7aaa, 0x8840, 0x1078,
- 0x2d77, 0x6a10, 0x610c, 0x8108, 0xa18c, 0x00ff, 0xa1e0, 0x3e80,
- 0x2c64, 0x8cff, 0x0040, 0x1dbe, 0x6010, 0xa206, 0x00c0, 0x1da8,
- 0x60b4, 0x8001, 0x60b6, 0x00c0, 0x1da3, 0x0c7e, 0x2a60, 0x6008,
- 0xa085, 0x0100, 0x600a, 0x0c7f, 0x0078, 0x1cd6, 0x1078, 0x2d5e,
- 0x00c0, 0x1bf7, 0x2a60, 0x610e, 0x79aa, 0x8840, 0x712e, 0x2001,
- 0x0001, 0x007e, 0x7150, 0xa184, 0x0018, 0x0040, 0x1ddd, 0xa184,
- 0x0010, 0x0040, 0x1dd7, 0x1078, 0x2acc, 0x00c0, 0x1ddd, 0xa184,
- 0x0008, 0x0040, 0x1ddd, 0x1078, 0x29e6, 0x007f, 0x7002, 0xa68c,
- 0x0060, 0x88ff, 0x0040, 0x1de6, 0xa18d, 0x0004, 0x795a, 0x69b2,
- 0x789b, 0x0060, 0x2800, 0x78aa, 0x789b, 0x0061, 0x6814, 0xa085,
- 0x8000, 0x6816, 0x78aa, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012c,
- 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000a, 0x2098, 0x53a6,
- 0x147f, 0x137f, 0x157f, 0x6810, 0x8007, 0x789b, 0x007e, 0x78aa,
- 0x6d90, 0x7dd6, 0x7dde, 0x6e94, 0x7ed2, 0x7eda, 0x7830, 0xa084,
- 0x00c0, 0x00c0, 0x1e15, 0x0098, 0x1e1d, 0x6008, 0xa084, 0xffef,
- 0x600a, 0x1078, 0x2d77, 0x0078, 0x1bff, 0x7200, 0xa284, 0x0007,
- 0xa086, 0x0001, 0x00c0, 0x1e2a, 0x781b, 0x0049, 0x1078, 0x2d77,
- 0x0078, 0x1e3b, 0x6ab0, 0xa295, 0x2000, 0x7a5a, 0x781b, 0x0049,
- 0x1078, 0x2d77, 0x7200, 0x2500, 0xa605, 0x0040, 0x1e3b, 0xa284,
- 0x0007, 0x1079, 0x1e49, 0xad80, 0x0008, 0x7032, 0xa284, 0x0007,
- 0xa086, 0x0001, 0x00c0, 0x1e47, 0x6018, 0x8000, 0x601a, 0x0078,
- 0x1bf7, 0x1e51, 0x30f0, 0x30f0, 0x30df, 0x30f0, 0x1e51, 0x1e51,
- 0x1e51, 0x1078, 0x1ba5, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0f7e,
- 0x2079, 0x3500, 0x7898, 0x0f7f, 0xa084, 0x0001, 0x0040, 0x1e79,
- 0x70a0, 0xa086, 0x0001, 0x00c0, 0x1e68, 0x70a2, 0x0078, 0x1f01,
- 0x70a0, 0xa086, 0x0005, 0x00c0, 0x1e77, 0x70bc, 0x2068, 0x6817,
- 0x0004, 0x6813, 0x0000, 0x681c, 0xa085, 0x0008, 0x681e, 0x70a3,
- 0x0000, 0x157e, 0x2011, 0x0004, 0x71a0, 0xa186, 0x0001, 0x0040,
- 0x1e9b, 0xa186, 0x0007, 0x00c0, 0x1e8b, 0x2009, 0x352b, 0x200b,
- 0x0005, 0x0078, 0x1e9b, 0x2009, 0x3513, 0x2104, 0x2009, 0x3512,
- 0x200a, 0x2009, 0x352b, 0x200b, 0x0001, 0x70a3, 0x0000, 0x70a7,
- 0x0001, 0x0078, 0x1e9d, 0x70a3, 0x0000, 0x1078, 0x2ec7, 0x20a9,
- 0x0010, 0x2039, 0x0000, 0x1078, 0x2ba6, 0xa7b8, 0x0100, 0x0070,
- 0x1eab, 0x0078, 0x1ea3, 0x7000, 0x2020, 0x0079, 0x1eaf, 0x1edd,
- 0x1ec6, 0x1ec6, 0x1eb9, 0x1edd, 0x1edd, 0x1eb7, 0x1eb7, 0x1078,
- 0x1ba5, 0x2021, 0x3557, 0x2404, 0xa005, 0x0040, 0x1ec6, 0xad06,
- 0x00c0, 0x1ec6, 0x6800, 0x2022, 0x0078, 0x1ed6, 0x681c, 0xa084,
- 0x0001, 0x00c0, 0x1ed2, 0x6f10, 0x1078, 0x2ca1, 0x1078, 0x28d9,
- 0x0078, 0x1ed6, 0x7054, 0x2060, 0x6800, 0x6002, 0x6a16, 0x681c,
- 0xa085, 0x0008, 0x681e, 0x1078, 0x17dd, 0x2021, 0x3f80, 0x1078,
- 0x1f07, 0x2021, 0x3557, 0x1078, 0x1f07, 0x20a9, 0x0000, 0x2021,
- 0x3e80, 0x1078, 0x1f07, 0x8420, 0x0070, 0x1ef0, 0x0078, 0x1ee9,
- 0x20a9, 0x0080, 0x2061, 0x3680, 0x6018, 0x6110, 0xa102, 0x6012,
- 0x601b, 0x0000, 0xace0, 0x0010, 0x0070, 0x1f00, 0x0078, 0x1ef4,
- 0x157f, 0x7003, 0x0000, 0x703f, 0x0000, 0x0078, 0x1bf7, 0x047e,
- 0x2404, 0xa005, 0x0040, 0x1f19, 0x2068, 0x6800, 0x007e, 0x6a16,
- 0x681c, 0xa085, 0x0008, 0x681e, 0x1078, 0x17dd, 0x007f, 0x0078,
- 0x1f09, 0x047f, 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050,
- 0x1f23, 0x1078, 0x1ba5, 0x2300, 0x0079, 0x1f26, 0x1f29, 0x1f9c,
- 0x1faa, 0xa282, 0x0002, 0x0040, 0x1f2f, 0x1078, 0x1ba5, 0x70a0,
- 0x70a3, 0x0000, 0x70c3, 0x0000, 0x0079, 0x1f36, 0x1f3e, 0x1f3e,
- 0x1f40, 0x1f74, 0x2908, 0x1f3e, 0x1f74, 0x1f3e, 0x1078, 0x1ba5,
- 0x77b4, 0x1078, 0x2ba6, 0x77b4, 0xa7bc, 0x0f00, 0x1078, 0x2ca1,
- 0x6018, 0xa005, 0x0040, 0x1f6b, 0x2021, 0x3f80, 0x2009, 0x0004,
- 0x2011, 0x0010, 0x1078, 0x1fc5, 0x0040, 0x1f6b, 0x157e, 0x20a9,
- 0x0000, 0x2021, 0x3e80, 0x047e, 0x2009, 0x0004, 0x2011, 0x0010,
- 0x1078, 0x1fc5, 0x047f, 0x0040, 0x1f6a, 0x8420, 0x0070, 0x1f6a,
- 0x0078, 0x1f5b, 0x157f, 0x8738, 0xa784, 0x0007, 0x00c0, 0x1f46,
- 0x0078, 0x1bff, 0x0078, 0x1bff, 0x77b4, 0x1078, 0x2ca1, 0x6018,
- 0xa005, 0x0040, 0x1f9a, 0x2021, 0x3f80, 0x2009, 0x0005, 0x2011,
- 0x0020, 0x1078, 0x1fc5, 0x0040, 0x1f9a, 0x157e, 0x20a9, 0x0000,
- 0x2021, 0x3e80, 0x047e, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078,
- 0x1fc5, 0x047f, 0x0040, 0x1f99, 0x8420, 0x0070, 0x1f99, 0x0078,
- 0x1f8a, 0x157f, 0x0078, 0x1bff, 0x2200, 0x0079, 0x1f9f, 0x1fa2,
- 0x1fa4, 0x1fa4, 0x1078, 0x1ba5, 0x70a3, 0x0000, 0x70a7, 0x0001,
- 0x0078, 0x1bf7, 0x2200, 0x0079, 0x1fad, 0x1fb2, 0x1fa4, 0x1fb0,
- 0x1078, 0x1ba5, 0x1078, 0x241f, 0x7000, 0xa086, 0x0001, 0x00c0,
- 0x28af, 0x1078, 0x28ef, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078,
- 0x28a2, 0x0040, 0x28af, 0x0078, 0x1cd6, 0x2404, 0xa005, 0x0040,
- 0x1fe6, 0x2068, 0x2d04, 0x007e, 0x6810, 0xa706, 0x0040, 0x1fd4,
- 0x2d20, 0x007f, 0x0078, 0x1fc6, 0x007f, 0x2022, 0x6916, 0x681c,
- 0xa205, 0x681e, 0x1078, 0x17dd, 0x6010, 0x8001, 0x6012, 0x6008,
- 0xa084, 0xffef, 0x600a, 0x1078, 0x28ef, 0x007c, 0xa085, 0x0001,
- 0x0078, 0x1fe5, 0x2300, 0x0079, 0x1fed, 0x1ff2, 0x1ff0, 0x2035,
- 0x1078, 0x1ba5, 0x78e4, 0xa005, 0x00d0, 0x2015, 0x0018, 0x2015,
- 0x2008, 0xa084, 0x0030, 0x00c0, 0x2001, 0x781b, 0x0049, 0x0078,
- 0x1bf7, 0x78ec, 0xa084, 0x0003, 0x0040, 0x1ffd, 0x2100, 0xa084,
- 0x0007, 0x0079, 0x200b, 0x2023, 0x2029, 0x201d, 0x2013, 0x2d58,
- 0x2d58, 0x2013, 0x202f, 0x1078, 0x1ba5, 0x7000, 0xa005, 0x0040,
- 0x1bff, 0x2001, 0x0003, 0x0078, 0x22fa, 0x1078, 0x2b89, 0x781b,
- 0x0055, 0x0078, 0x1bf7, 0x1078, 0x2b89, 0x781b, 0x00dc, 0x0078,
- 0x1bf7, 0x1078, 0x2b89, 0x781b, 0x00e3, 0x0078, 0x1bf7, 0x1078,
- 0x2b89, 0x781b, 0x009d, 0x0078, 0x1bf7, 0xa584, 0x000f, 0x00c0,
- 0x205f, 0x1078, 0x241f, 0x7000, 0x0079, 0x203e, 0x2046, 0x2053,
- 0x2046, 0x28af, 0x2048, 0x28af, 0x2046, 0x2046, 0x1078, 0x1ba5,
- 0x71a0, 0x70a3, 0x0000, 0xa186, 0x0004, 0x00c0, 0x2051, 0x0078,
- 0x2908, 0x0078, 0x28af, 0x1078, 0x28ef, 0x6008, 0xa084, 0xffef,
- 0x600a, 0x1078, 0x28a2, 0x0040, 0x28af, 0x0078, 0x1cd6, 0x78e4,
- 0xa005, 0x00d0, 0x2015, 0x0018, 0x2015, 0x2008, 0xa084, 0x0030,
- 0x00c0, 0x206e, 0x781b, 0x0049, 0x0078, 0x1bf7, 0x78ec, 0xa084,
- 0x0003, 0x0040, 0x206a, 0x2100, 0xa184, 0x0007, 0x0079, 0x2078,
- 0x2088, 0x208e, 0x2082, 0x2080, 0x2d58, 0x2d58, 0x2080, 0x2d50,
- 0x1078, 0x1ba5, 0x1078, 0x2b91, 0x781b, 0x0055, 0x0078, 0x1bf7,
- 0x1078, 0x2b91, 0x781b, 0x00dc, 0x0078, 0x1bf7, 0x1078, 0x2b91,
- 0x781b, 0x00e3, 0x0078, 0x1bf7, 0x1078, 0x2b91, 0x781b, 0x009d,
- 0x0078, 0x1bf7, 0x2300, 0x0079, 0x209d, 0x20a2, 0x20a0, 0x20a4,
- 0x1078, 0x1ba5, 0x0078, 0x2665, 0x6817, 0x0008, 0x78a3, 0x0000,
- 0x79e4, 0xa184, 0x0030, 0x0040, 0x2665, 0x78ec, 0xa084, 0x0003,
- 0x0040, 0x2665, 0xa184, 0x0007, 0x0079, 0x20b6, 0x2023, 0x2029,
- 0x201d, 0x2d30, 0x2d58, 0x2d58, 0x20be, 0x2d50, 0x1078, 0x1ba5,
- 0xa282, 0x0005, 0x0050, 0x20c6, 0x1078, 0x1ba5, 0x2300, 0x0079,
- 0x20c9, 0x20cc, 0x22ce, 0x22da, 0x2200, 0x0079, 0x20cf, 0x20d4,
- 0x20d6, 0x20e9, 0x20d4, 0x22b3, 0x1078, 0x1ba5, 0x789b, 0x0018,
- 0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0048, 0x2b6a, 0xa08a,
- 0x0004, 0x00c8, 0x2b6a, 0x0079, 0x20e5, 0x2b6a, 0x2b6a, 0x2b6a,
- 0x2b0c, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0040, 0x20fe,
- 0xa184, 0x0018, 0x0040, 0x20fa, 0x0078, 0x2b6a, 0x7000, 0xa005,
- 0x00c0, 0x20f4, 0x2011, 0x0003, 0x0078, 0x2752, 0xa184, 0x00ff,
- 0xa08a, 0x0010, 0x00c8, 0x2b6a, 0x0079, 0x2106, 0x2118, 0x2116,
- 0x212e, 0x2130, 0x21c2, 0x2b6a, 0x2b6a, 0x21c4, 0x2b6a, 0x2b6a,
- 0x22af, 0x22af, 0x2b6a, 0x2b6a, 0x2b6a, 0x22b1, 0x1078, 0x1ba5,
- 0xa684, 0x1000, 0x0040, 0x2125, 0x2001, 0x0300, 0x8000, 0x8000,
- 0x783a, 0x781b, 0x009a, 0x0078, 0x1bf7, 0x6814, 0xa084, 0x8000,
- 0x0040, 0x212c, 0x6817, 0x0003, 0x0078, 0x2d30, 0x1078, 0x1ba5,
- 0x691c, 0x691e, 0xa684, 0x1800, 0x00c0, 0x214a, 0x681c, 0xa084,
- 0x0001, 0x00c0, 0x2152, 0x6814, 0xa086, 0x0008, 0x00c0, 0x2142,
- 0x6817, 0x0000, 0xa684, 0x0400, 0x0040, 0x21be, 0x781b, 0x0058,
- 0x0078, 0x1bf7, 0xa684, 0x1000, 0x0040, 0x2152, 0x781b, 0x0058,
- 0x0078, 0x1bf7, 0xa684, 0x0060, 0x0040, 0x21ba, 0xa684, 0x0800,
- 0x0040, 0x21ba, 0xa684, 0x8000, 0x00c0, 0x2160, 0x0078, 0x217a,
- 0xa6b4, 0x7fff, 0x7e5a, 0x6eb2, 0x789b, 0x0074, 0x7aac, 0x79ac,
- 0x78ac, 0x801b, 0x00c8, 0x216d, 0x8000, 0xa084, 0x003f, 0xa108,
- 0xa291, 0x0000, 0x6b94, 0x2100, 0xa302, 0x68ae, 0x6b90, 0x2200,
- 0xa303, 0x68aa, 0xa684, 0x4000, 0x0040, 0x2182, 0xa6b4, 0xbfff,
- 0x7e5a, 0x6eb2, 0x7000, 0xa086, 0x0003, 0x00c0, 0x218f, 0x1078,
- 0x2f3a, 0x1078, 0x30df, 0x781b, 0x0067, 0x0078, 0x1bf7, 0xa006,
- 0x1078, 0x3194, 0x6aac, 0x69a8, 0x6c94, 0x6b90, 0x2200, 0xa105,
- 0x0040, 0x219e, 0x2200, 0xa422, 0x2100, 0xa31b, 0x7cd2, 0x7bd6,
- 0x2300, 0xa405, 0x00c0, 0x21ac, 0xa6b5, 0x4000, 0x7e5a, 0x6eb2,
- 0x781b, 0x0067, 0x0078, 0x1bf7, 0x781b, 0x0067, 0x2200, 0xa115,
- 0x00c0, 0x21b6, 0x1078, 0x30f0, 0x0078, 0x1bf7, 0x1078, 0x311d,
- 0x0078, 0x1bf7, 0x781b, 0x006a, 0x0078, 0x1bf7, 0x781b, 0x0058,
- 0x0078, 0x1bf7, 0x1078, 0x1ba5, 0x0078, 0x2221, 0x691c, 0xa184,
- 0x0100, 0x0040, 0x21dc, 0xa18c, 0xfeff, 0x691e, 0x0c7e, 0x7048,
- 0x2060, 0x6000, 0xa084, 0xefff, 0x6002, 0x6004, 0xa084, 0xfff5,
- 0x6006, 0x0c7f, 0x0078, 0x2210, 0xa184, 0x0200, 0x0040, 0x2210,
- 0xa18c, 0xfdff, 0x691e, 0x0c7e, 0x7048, 0x2060, 0x6000, 0xa084,
- 0xdfff, 0x6002, 0x6004, 0xa084, 0xffef, 0x6006, 0x2008, 0x2c48,
- 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2210, 0x1078, 0x2c9d, 0x1078,
- 0x29e6, 0x88ff, 0x0040, 0x2210, 0x789b, 0x0060, 0x2800, 0x78aa,
- 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x220c,
- 0x781b, 0x0055, 0x0078, 0x1bf7, 0x781b, 0x0069, 0x0078, 0x1bf7,
- 0x7e58, 0xa684, 0x0400, 0x00c0, 0x2219, 0x781b, 0x0058, 0x0078,
- 0x1bf7, 0x781b, 0x006a, 0x0078, 0x1bf7, 0x0078, 0x2b70, 0x0078,
- 0x2b70, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x0040, 0x221f,
- 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0,
- 0x2244, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x223c,
- 0x0048, 0x223c, 0x0078, 0x223e, 0x0078, 0x21c6, 0x24a8, 0x7aa8,
- 0x00f0, 0x223e, 0x0078, 0x222a, 0xa284, 0x00f0, 0xa086, 0x0020,
- 0x00c0, 0x22a0, 0x8318, 0x8318, 0x2300, 0xa102, 0x0040, 0x2254,
- 0x0048, 0x2254, 0x0078, 0x229d, 0xa286, 0x0023, 0x0040, 0x221f,
- 0x6818, 0xa084, 0xfff1, 0x681a, 0x7e58, 0xa684, 0xfff1, 0xa085,
- 0x0010, 0x2030, 0x7e5a, 0x6008, 0xa085, 0x0010, 0x600a, 0x0c7e,
- 0x7048, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0010,
- 0x0040, 0x2278, 0x1078, 0x2c9d, 0x1078, 0x2acc, 0x0078, 0x2287,
- 0x0c7e, 0x7048, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xa184,
- 0x0008, 0x0040, 0x2210, 0x1078, 0x2c9d, 0x1078, 0x29e6, 0x88ff,
- 0x0040, 0x2210, 0x789b, 0x0060, 0x2800, 0x78aa, 0xa6b5, 0x0004,
- 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2299, 0x781b, 0x0055, 0x0078,
- 0x1bf7, 0x781b, 0x0069, 0x0078, 0x1bf7, 0x7aa8, 0x0078, 0x222a,
- 0x8318, 0x2300, 0xa102, 0x0040, 0x22a9, 0x0048, 0x22a9, 0x0078,
- 0x222a, 0xa284, 0x0080, 0x00c0, 0x2b76, 0x0078, 0x2b70, 0x0078,
- 0x2b76, 0x0078, 0x2b6a, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff,
- 0xa08e, 0x0001, 0x0040, 0x22be, 0x1078, 0x1ba5, 0x7aa8, 0xa294,
- 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x2b6a,
- 0x0079, 0x22ca, 0x2b6a, 0x2939, 0x2b6a, 0x2a67, 0xa282, 0x0000,
- 0x00c0, 0x22d4, 0x1078, 0x1ba5, 0x1078, 0x2b89, 0x781b, 0x0069,
- 0x0078, 0x1bf7, 0xa282, 0x0003, 0x00c0, 0x22e0, 0x1078, 0x1ba5,
- 0x1078, 0x2b99, 0x781b, 0x0069, 0x0078, 0x1bf7, 0xa282, 0x0004,
- 0x0050, 0x22ec, 0x1078, 0x1ba5, 0x2300, 0x0079, 0x22ef, 0x22f2,
- 0x23c9, 0x23fa, 0xa286, 0x0003, 0x0040, 0x22f8, 0x1078, 0x1ba5,
- 0x2001, 0x0000, 0x703a, 0x7000, 0xa084, 0x0007, 0x0079, 0x2300,
- 0x2308, 0x230a, 0x230a, 0x2508, 0x2530, 0x24d2, 0x2308, 0x2308,
- 0x1078, 0x1ba5, 0xa684, 0x1000, 0x00c0, 0x2312, 0x1078, 0x2ec7,
- 0x0040, 0x23a3, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x235a, 0xa186,
- 0x0008, 0x00c0, 0x2329, 0x1078, 0x28ef, 0x6008, 0xa084, 0xffef,
- 0x600a, 0x1078, 0x28a2, 0x0040, 0x235a, 0x1078, 0x2ec7, 0x0078,
- 0x2341, 0xa186, 0x0028, 0x00c0, 0x235a, 0x1078, 0x2ec7, 0x6008,
- 0xa084, 0xffef, 0x600a, 0x6018, 0xa005, 0x0040, 0x2341, 0x8001,
- 0x601a, 0xa005, 0x0040, 0x2341, 0x8001, 0xa005, 0x0040, 0x2341,
- 0x601e, 0x681c, 0xa084, 0x0001, 0x0040, 0x1bff, 0x681c, 0xa084,
- 0xfffe, 0x681e, 0x7054, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f,
- 0x6004, 0x6802, 0xa005, 0x2d00, 0x00c0, 0x2357, 0x6002, 0x6006,
- 0x0078, 0x1bff, 0x017e, 0x1078, 0x241f, 0x017f, 0xa684, 0xdf00,
- 0x681a, 0x6827, 0x0000, 0x6f10, 0x81ff, 0x0040, 0x23a3, 0xa186,
- 0x0002, 0x00c0, 0x239b, 0xa684, 0x0800, 0x00c0, 0x2377, 0xa684,
- 0x0060, 0x0040, 0x2377, 0x78d8, 0x7adc, 0x682e, 0x6a2a, 0x8717,
- 0xa294, 0x000f, 0x8213, 0x8213, 0x8213, 0xa290, 0x3600, 0xa290,
- 0x0000, 0x221c, 0xa384, 0x0100, 0x00c0, 0x2388, 0x0078, 0x238e,
- 0x8210, 0x2204, 0xa085, 0x0018, 0x2012, 0x8211, 0xa384, 0x0400,
- 0x0040, 0x239b, 0x689c, 0xa084, 0x0100, 0x00c0, 0x239b, 0x1078,
- 0x2491, 0x0078, 0x1bff, 0xa186, 0x0018, 0x0040, 0x23a3, 0xa186,
- 0x0014, 0x0040, 0x1bff, 0x6912, 0x6814, 0xa084, 0x8000, 0x0040,
- 0x23ab, 0x7038, 0x6816, 0xa68c, 0xdf00, 0x691a, 0x1078, 0x28e0,
- 0x1078, 0x28ef, 0x00c0, 0x23b8, 0x6008, 0xa084, 0xffef, 0x600a,
- 0x681c, 0xa084, 0x0001, 0x00c0, 0x23c1, 0x1078, 0x28d9, 0x0078,
- 0x23c5, 0x7054, 0x2060, 0x6800, 0x6002, 0x1078, 0x17dd, 0x0078,
- 0x1bff, 0xa282, 0x0004, 0x0048, 0x23cf, 0x1078, 0x1ba5, 0x2200,
- 0x0079, 0x23d2, 0x23d6, 0x23d8, 0x23e5, 0x23d8, 0x1078, 0x1ba5,
- 0x7000, 0xa086, 0x0005, 0x0040, 0x23e1, 0x1078, 0x2b89, 0x781b,
- 0x0069, 0x781b, 0x006a, 0x0078, 0x1bf7, 0x7890, 0x8007, 0x8001,
- 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff,
- 0xa186, 0x0003, 0x0040, 0x23f6, 0x0078, 0x2b6a, 0x781b, 0x006a,
- 0x0078, 0x1bf7, 0x681c, 0xa085, 0x0004, 0x681e, 0x82ff, 0x00c0,
- 0x2405, 0x1078, 0x2b89, 0x0078, 0x240c, 0x8211, 0x0040, 0x240a,
- 0x1078, 0x1ba5, 0x1078, 0x2b99, 0x781b, 0x0069, 0x0078, 0x1bf7,
- 0x1078, 0x2d77, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x241c, 0x0018,
- 0x241c, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684,
- 0x0060, 0x00c0, 0x2429, 0x682f, 0x0000, 0x682b, 0x0000, 0x0078,
- 0x2490, 0xa684, 0x0800, 0x00c0, 0x2438, 0x68b0, 0xa084, 0x4800,
- 0xa635, 0xa684, 0x0800, 0x00c0, 0x2438, 0x1078, 0x2ec7, 0x007c,
- 0xa684, 0x0020, 0x0040, 0x2462, 0x78d0, 0x8003, 0x00c8, 0x2446,
- 0xa006, 0x1078, 0x3194, 0x78d4, 0x1078, 0x31f9, 0xa684, 0x4000,
- 0x0040, 0x2450, 0x682f, 0x0000, 0x682b, 0x0000, 0x0078, 0x2435,
- 0x68b0, 0xa084, 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x244a,
- 0x7038, 0xa005, 0x00c0, 0x245c, 0x79d8, 0x7adc, 0x692e, 0x6a2a,
- 0x0078, 0x2435, 0xa684, 0x4000, 0x0040, 0x246c, 0x682f, 0x0000,
- 0x682b, 0x0000, 0x0078, 0x2435, 0x68b0, 0xa084, 0x4800, 0xa635,
- 0xa684, 0x4000, 0x00c0, 0x2466, 0x7038, 0xa005, 0x00c0, 0x247a,
- 0x703b, 0x0007, 0x79d8, 0x7adc, 0x78d0, 0x80f3, 0x00c8, 0x2481,
- 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a2a,
- 0x2100, 0xa205, 0x00c0, 0x248e, 0x0078, 0x2435, 0x1078, 0x3194,
- 0x007c, 0xa384, 0x0200, 0x0040, 0x2499, 0x6008, 0xa085, 0x0002,
- 0x600a, 0x6817, 0x0006, 0x6a28, 0x692c, 0x6a3a, 0x693e, 0x682b,
- 0x0300, 0x682f, 0x0000, 0x6833, 0x2000, 0x6893, 0x0000, 0x6897,
- 0x0020, 0x7000, 0x0079, 0x24ac, 0x24b4, 0x24b6, 0x24bf, 0x24b4,
- 0x24b4, 0x24b4, 0x24b4, 0x24b4, 0x1078, 0x1ba5, 0x681c, 0xa084,
- 0x0001, 0x00c0, 0x24bf, 0x1078, 0x28d9, 0x0078, 0x24c5, 0x7054,
- 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60, 0x2021, 0x3557, 0x2404,
- 0xa005, 0x0040, 0x24ce, 0x2020, 0x0078, 0x24c7, 0x2d22, 0x206b,
- 0x0000, 0x007c, 0x77b4, 0x1078, 0x2ba6, 0xa7bc, 0x0f00, 0x1078,
- 0x2ca1, 0x6018, 0xa005, 0x0040, 0x2501, 0x0d7e, 0x2001, 0x3f90,
- 0x2068, 0x0d7f, 0x2021, 0x3f80, 0x2009, 0x0004, 0x2011, 0x0010,
- 0x1078, 0x1fc5, 0x0040, 0x2501, 0x157e, 0x20a9, 0x0000, 0x2021,
- 0x3e80, 0x047e, 0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x1fc5,
- 0x047f, 0x0040, 0x2500, 0x8420, 0x0070, 0x2500, 0x0078, 0x24f1,
- 0x157f, 0x8738, 0xa784, 0x0007, 0x00c0, 0x24d7, 0x0078, 0x1bff,
- 0x1078, 0x28e0, 0x1078, 0x28ef, 0x6827, 0x0000, 0x789b, 0x000e,
- 0x6f10, 0x6813, 0x0002, 0x1078, 0x31ca, 0xa684, 0x0800, 0x0040,
- 0x251d, 0x6918, 0xa18d, 0x2000, 0x691a, 0x6814, 0xa084, 0x8000,
- 0x0040, 0x2524, 0x6817, 0x0000, 0x2021, 0x3557, 0x6800, 0x2022,
- 0x6a38, 0x693c, 0x6a2a, 0x692e, 0x1078, 0x17dd, 0x0078, 0x1bff,
- 0x1078, 0x241f, 0x6827, 0x0000, 0x789b, 0x000e, 0x6f10, 0x1078,
- 0x2d7c, 0xa08c, 0x00ff, 0x6912, 0x6814, 0xa084, 0x8000, 0x0040,
- 0x2543, 0x7038, 0x6816, 0xa68c, 0xdf00, 0x691a, 0x70a3, 0x0000,
- 0x0078, 0x1bff, 0xa006, 0x1078, 0x2ec7, 0x6813, 0x0000, 0x6817,
- 0x0001, 0xa68c, 0xdf00, 0x691a, 0x6827, 0x0000, 0x7000, 0x0079,
- 0x2559, 0x2561, 0x2563, 0x2563, 0x2565, 0x2565, 0x2565, 0x2561,
- 0x2561, 0x1078, 0x1ba5, 0x1078, 0x28ef, 0x6008, 0xa084, 0xffef,
- 0x600a, 0x0078, 0x28ba, 0x2300, 0x0079, 0x256e, 0x2571, 0x2573,
- 0x25b1, 0x1078, 0x1ba5, 0x7000, 0x0079, 0x2576, 0x257e, 0x2580,
- 0x2580, 0x258b, 0x2580, 0x2592, 0x257e, 0x257e, 0x1078, 0x1ba5,
- 0xa684, 0x2000, 0x00c0, 0x258b, 0xa6b5, 0x2000, 0x7e5a, 0x1078,
- 0x30f0, 0x0078, 0x2d30, 0x6814, 0xa084, 0x8000, 0x0040, 0x2592,
- 0x6817, 0x0007, 0x2009, 0x3518, 0x210c, 0xa186, 0x0000, 0x0040,
- 0x25a7, 0xa186, 0x0001, 0x0040, 0x25ab, 0x2009, 0x352b, 0x200b,
- 0x000b, 0x70a3, 0x0001, 0x781b, 0x0046, 0x0078, 0x1bf7, 0x781b,
- 0x00dd, 0x0078, 0x1bf7, 0x2009, 0x352b, 0x200b, 0x000a, 0x0078,
- 0x1bf7, 0x1078, 0x1ba5, 0x2300, 0x0079, 0x25b6, 0x25b9, 0x25bb,
- 0x25de, 0x1078, 0x1ba5, 0x7000, 0x0079, 0x25be, 0x25c6, 0x25c8,
- 0x25c8, 0x25d3, 0x25c8, 0x25da, 0x25c6, 0x25c6, 0x1078, 0x1ba5,
- 0xa684, 0x2000, 0x00c0, 0x25d3, 0xa6b5, 0x2000, 0x7e5a, 0x1078,
- 0x30f0, 0x0078, 0x2d30, 0x6814, 0xa084, 0x8000, 0x0040, 0x25da,
- 0x6817, 0x0007, 0x781b, 0x00e4, 0x0078, 0x1bf7, 0x681c, 0xa085,
- 0x0004, 0x681e, 0xa6b5, 0x0800, 0x1078, 0x2b89, 0x781b, 0x0069,
- 0x0078, 0x1bf7, 0x2300, 0x0079, 0x25ed, 0x25f0, 0x25f2, 0x25f4,
- 0x1078, 0x1ba5, 0x1078, 0x1ba5, 0xa684, 0x0400, 0x00c0, 0x2613,
- 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb,
- 0x785a, 0x79e4, 0xa184, 0x0020, 0x0040, 0x260b, 0x78ec, 0xa084,
- 0x0003, 0x00c0, 0x260f, 0x2001, 0x0014, 0x0078, 0x22fa, 0xa184,
- 0x0007, 0x0079, 0x264b, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060,
- 0x79a8, 0x81ff, 0x0040, 0x2649, 0x789b, 0x0010, 0x7ba8, 0xa384,
- 0x0001, 0x00c0, 0x263a, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0,
- 0x262d, 0x2009, 0xfff7, 0x0078, 0x2633, 0xa386, 0x0003, 0x00c0,
- 0x263a, 0x2009, 0xffef, 0x0c7e, 0x7048, 0x2060, 0x6004, 0xa104,
- 0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb,
- 0x785a, 0x782b, 0x3009, 0x691c, 0xa18c, 0xfdff, 0xa18c, 0xfeff,
- 0x691e, 0x0078, 0x2d30, 0x2023, 0x2029, 0x2655, 0x265d, 0x2653,
- 0x2653, 0x2653, 0x2d30, 0x1078, 0x1ba5, 0x691c, 0xa18c, 0xfdff,
- 0xa18c, 0xfeff, 0x691e, 0x0078, 0x2d38, 0x691c, 0xa18c, 0xfdff,
- 0xa18c, 0xfeff, 0x691e, 0x0078, 0x2d30, 0x79e4, 0xa184, 0x0030,
- 0x0040, 0x266f, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x2677, 0x6814,
- 0xa085, 0x8000, 0x6816, 0x2001, 0x0014, 0x0078, 0x22fa, 0xa184,
- 0x0007, 0x0079, 0x267b, 0x2d30, 0x2d30, 0x2683, 0x2d30, 0x2d58,
- 0x2d58, 0x2d30, 0x2d30, 0xa684, 0x0400, 0x00c0, 0x26b4, 0x681c,
- 0xa084, 0x0001, 0x0040, 0x2d38, 0xa68c, 0x2060, 0xa18c, 0xfffb,
- 0x795a, 0x69b2, 0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061,
- 0x6814, 0xa085, 0x8000, 0x6816, 0x78aa, 0x157e, 0x137e, 0x147e,
- 0x20a1, 0x012c, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000a,
- 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6810, 0x8007, 0x789b,
- 0x007e, 0x78aa, 0x0078, 0x2d38, 0x6814, 0xa084, 0x8000, 0x0040,
- 0x26bb, 0x6817, 0x0008, 0x781b, 0x00d8, 0x0078, 0x1bf7, 0x2300,
- 0x0079, 0x26c2, 0x26c7, 0x2742, 0x26c5, 0x1078, 0x1ba5, 0x7000,
- 0xa084, 0x0007, 0x0079, 0x26cc, 0x26d4, 0x26d6, 0x26f2, 0x26d4,
- 0x26d4, 0x24d2, 0x26d4, 0x26d4, 0x1078, 0x1ba5, 0x691c, 0xa18d,
- 0x0001, 0x691e, 0x6800, 0x6006, 0xa005, 0x00c0, 0x26e0, 0x6002,
- 0x6818, 0xa084, 0x000e, 0x0040, 0x26ec, 0x7014, 0x68b6, 0x712c,
- 0xa188, 0x3e80, 0x0078, 0x26ee, 0x2009, 0x3f80, 0x2104, 0x6802,
- 0x2d0a, 0x7156, 0x6eb2, 0xa684, 0x0060, 0x0040, 0x2740, 0xa684,
- 0x0800, 0x00c0, 0x2704, 0xa684, 0x7fff, 0x68b2, 0x6890, 0x6894,
- 0x1078, 0x2ec7, 0x0078, 0x2740, 0xa684, 0x0020, 0x0040, 0x2716,
- 0xa006, 0x1078, 0x3194, 0x78d0, 0x8003, 0x00c8, 0x2712, 0x78d4,
- 0x1078, 0x31f9, 0x79d8, 0x7adc, 0x0078, 0x271a, 0x1078, 0x2cae,
- 0x1078, 0x3194, 0xa684, 0x8000, 0x0040, 0x2740, 0xa684, 0x7fff,
- 0x68b2, 0x789b, 0x0074, 0x1078, 0x2d7c, 0x2010, 0x1078, 0x2d7c,
- 0x2008, 0xa684, 0x0020, 0x00c0, 0x2738, 0x1078, 0x2d7c, 0x801b,
- 0x00c8, 0x2733, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
- 0x6b94, 0x2100, 0xa302, 0x68ae, 0x6b90, 0x2200, 0xa303, 0x68aa,
- 0x0078, 0x1bff, 0x0078, 0x2b76, 0x7033, 0x0000, 0xa282, 0x0005,
- 0x0050, 0x274c, 0x1078, 0x1ba5, 0x2300, 0x0079, 0x274f, 0x2752,
- 0x275c, 0x277f, 0x2200, 0x0079, 0x2755, 0x275a, 0x2b76, 0x275a,
- 0x27a8, 0x27f9, 0x1078, 0x1ba5, 0x7000, 0xa086, 0x0001, 0x00c0,
- 0x2769, 0x1078, 0x28ef, 0x1078, 0x2ec7, 0x7034, 0x600a, 0x0078,
- 0x276e, 0x7000, 0xa086, 0x0003, 0x0040, 0x2763, 0x7003, 0x0005,
- 0x2001, 0x3f90, 0x2068, 0x703e, 0x7032, 0x2200, 0x0079, 0x2778,
- 0x2b76, 0x277d, 0x27a8, 0x277d, 0x2b76, 0x1078, 0x1ba5, 0x7000,
- 0xa086, 0x0001, 0x00c0, 0x278c, 0x1078, 0x28ef, 0x1078, 0x2ec7,
- 0x7034, 0x600a, 0x0078, 0x2791, 0x7000, 0xa086, 0x0003, 0x0040,
- 0x2786, 0x7003, 0x0005, 0x2001, 0x3f90, 0x2068, 0x703e, 0x7032,
- 0x2200, 0x0079, 0x279b, 0x27a2, 0x27a0, 0x27a2, 0x27a0, 0x27a2,
- 0x1078, 0x1ba5, 0x1078, 0x2b99, 0x781b, 0x0069, 0x0078, 0x1bf7,
- 0x7000, 0xa086, 0x0001, 0x00c0, 0x27b5, 0x1078, 0x28ef, 0x1078,
- 0x2ec7, 0x7034, 0x600a, 0x0078, 0x27ba, 0x7000, 0xa086, 0x0003,
- 0x0040, 0x27af, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b,
- 0x0018, 0x7ca8, 0xa484, 0x0007, 0xa215, 0x2069, 0x3f80, 0x2d04,
- 0x2d08, 0x7156, 0x2068, 0xa005, 0x0040, 0x27d5, 0x6810, 0xa206,
- 0x0040, 0x27ee, 0x6800, 0x0078, 0x27c8, 0x7003, 0x0005, 0x2001,
- 0x3f90, 0x2068, 0x703e, 0x7032, 0x157e, 0x20a9, 0x002f, 0x2003,
- 0x0000, 0x8000, 0x0070, 0x27e6, 0x0078, 0x27df, 0x157f, 0x6a12,
- 0x68b3, 0x0700, 0x681f, 0x0800, 0x6823, 0x0003, 0x6eb0, 0x7e5a,
- 0x681c, 0xa084, 0x0c00, 0x0040, 0x284f, 0x1078, 0x2b91, 0x0078,
- 0x284f, 0x7000, 0xa086, 0x0001, 0x00c0, 0x2806, 0x1078, 0x28ef,
- 0x1078, 0x2ec7, 0x7034, 0x600a, 0x0078, 0x280b, 0x7000, 0xa086,
- 0x0003, 0x0040, 0x2800, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00,
- 0x789b, 0x0018, 0x7ca8, 0xa484, 0x0007, 0xa215, 0x79a8, 0x79a8,
- 0xa18c, 0x00ff, 0xa1e8, 0x3e80, 0x2d04, 0x2d08, 0x7156, 0x2068,
- 0xa005, 0x0040, 0x282a, 0x6810, 0xa206, 0x0040, 0x2843, 0x6800,
- 0x0078, 0x281d, 0x7003, 0x0005, 0x2001, 0x3f90, 0x2068, 0x703e,
- 0x7032, 0x157e, 0x20a9, 0x002f, 0x2003, 0x0000, 0x8000, 0x0070,
- 0x283b, 0x0078, 0x2834, 0x157f, 0x6a12, 0x68b3, 0x0700, 0x681f,
- 0x0800, 0x6823, 0x0003, 0x6eb0, 0x7e5a, 0x681c, 0xa084, 0x0c00,
- 0x0040, 0x284f, 0x1078, 0x2b8d, 0x7e58, 0x0078, 0x284f, 0x027e,
- 0x8207, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x3600,
- 0x2060, 0x704a, 0x6000, 0x704e, 0x6004, 0x7052, 0xa684, 0x0060,
- 0x0040, 0x2886, 0x6b94, 0x6c90, 0x69a8, 0x68ac, 0xa105, 0x00c0,
- 0x2874, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, 0xb7ff, 0x7e5a,
- 0x1078, 0x30f0, 0x0078, 0x2886, 0x68ac, 0xa31a, 0x2100, 0xa423,
- 0x2400, 0xa305, 0x0040, 0x2886, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde,
- 0x68ac, 0xa6b4, 0xbfff, 0x7e5a, 0x1078, 0x311d, 0x077f, 0x1078,
- 0x2ca1, 0x2009, 0x006a, 0xa684, 0x0008, 0x0040, 0x2891, 0x2009,
- 0x0069, 0xa6b5, 0x2000, 0x7e5a, 0x791a, 0x2d00, 0x703e, 0x8207,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x3600, 0x2048,
- 0x0078, 0x1bf7, 0x6020, 0xa005, 0x0040, 0x28ae, 0x8001, 0x6022,
- 0x6008, 0xa085, 0x0008, 0x600a, 0x7010, 0x6026, 0x007c, 0xa006,
- 0x1078, 0x2ec7, 0x6813, 0x0000, 0x6817, 0x0001, 0x681f, 0x0040,
- 0x681b, 0x0100, 0x7000, 0xa084, 0x0007, 0x0079, 0x28bf, 0x28c7,
- 0x28c9, 0x28c9, 0x28d5, 0x28d1, 0x28c7, 0x28c7, 0x28c7, 0x1078,
- 0x1ba5, 0x1078, 0x28e0, 0x1078, 0x28d9, 0x1078, 0x17dd, 0x0078,
- 0x1bff, 0x70a3, 0x0000, 0x0078, 0x1bff, 0x6817, 0x0000, 0x0078,
- 0x2508, 0x6800, 0xa005, 0x00c0, 0x28de, 0x6002, 0x6006, 0x007c,
- 0x6010, 0xa005, 0x0040, 0x28e9, 0x8001, 0x00d0, 0x28e9, 0x1078,
- 0x1ba5, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x007c, 0x6018,
- 0xa005, 0x0040, 0x28f5, 0x8001, 0x601a, 0x007c, 0x1078, 0x2d77,
- 0x6817, 0x0018, 0x0078, 0x2926, 0x1078, 0x2d77, 0x6817, 0x0019,
- 0x0078, 0x2926, 0x1078, 0x2d77, 0x6817, 0x001a, 0x0078, 0x2926,
- 0x77b4, 0x1078, 0x2ca1, 0x71b8, 0xa18c, 0x00ff, 0xa1e8, 0x3e80,
- 0x2d04, 0x2d08, 0x2068, 0xa005, 0x00c0, 0x2918, 0x0078, 0x1bff,
- 0x6810, 0x72b4, 0xa206, 0x0040, 0x2920, 0x6800, 0x0078, 0x2911,
- 0x6800, 0x200a, 0x6817, 0x0005, 0x70bf, 0x0000, 0x1078, 0x28e0,
- 0x681c, 0xa084, 0x0001, 0x00c0, 0x292f, 0x1078, 0x28d9, 0x1078,
- 0x28ef, 0x681b, 0x0000, 0x681f, 0x0020, 0x1078, 0x17dd, 0x0078,
- 0x1bff, 0xa282, 0x0003, 0x00c0, 0x2b6a, 0x7da8, 0xa5ac, 0x00ff,
- 0x7ea8, 0xa6b4, 0x00ff, 0x691c, 0xa18d, 0x0080, 0x691e, 0xa184,
- 0x0100, 0x0040, 0x2999, 0xa18c, 0xfeff, 0x691e, 0xa6b4, 0x00ff,
- 0x0040, 0x2983, 0xa682, 0x000f, 0x0048, 0x295a, 0x0040, 0x295a,
- 0x2031, 0x000f, 0x852b, 0x852b, 0x1078, 0x2c24, 0x0040, 0x2964,
- 0x1078, 0x2a33, 0x0078, 0x298c, 0x1078, 0x2bdf, 0x0c7e, 0x2960,
- 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x2a57, 0x0c7f, 0x691c,
- 0xa18d, 0x0100, 0x691e, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684,
- 0x0400, 0x00c0, 0x297f, 0x781b, 0x0055, 0x0078, 0x1bf7, 0x781b,
- 0x0069, 0x0078, 0x1bf7, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5,
- 0x6006, 0x1078, 0x2a57, 0x0c7f, 0x7e58, 0xa684, 0x0400, 0x00c0,
- 0x2995, 0x781b, 0x0058, 0x0078, 0x1bf7, 0x781b, 0x006a, 0x0078,
- 0x1bf7, 0x0c7e, 0x7048, 0x2060, 0x6100, 0xa18c, 0x1000, 0x0040,
- 0x29d9, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000f, 0x0048,
- 0x29ad, 0x0040, 0x29ad, 0x2011, 0x000f, 0x2600, 0xa202, 0x00c8,
- 0x29b2, 0x2230, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086, 0x0028,
- 0x00c0, 0x29c2, 0xa282, 0x0019, 0x00c8, 0x29c8, 0x2011, 0x0019,
- 0x0078, 0x29c8, 0xa282, 0x000c, 0x00c8, 0x29c8, 0x2011, 0x000c,
- 0x2200, 0xa502, 0x00c8, 0x29cd, 0x2228, 0x1078, 0x2be3, 0x852b,
- 0x852b, 0x1078, 0x2c24, 0x0040, 0x29d9, 0x1078, 0x2a33, 0x0078,
- 0x29dd, 0x1078, 0x2bdf, 0x1078, 0x2a57, 0x7858, 0xa085, 0x0004,
- 0x785a, 0x0c7f, 0x781b, 0x0069, 0x0078, 0x1bf7, 0x0c7e, 0x2960,
- 0x6000, 0xa084, 0x1000, 0x00c0, 0x2a01, 0x6010, 0xa084, 0x000f,
- 0x00c0, 0x29fb, 0xa18c, 0x0002, 0x00c0, 0x29fb, 0xa18c, 0xfff5,
- 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078,
- 0x2a23, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086, 0x0028, 0x00c0,
- 0x2a11, 0xa282, 0x0019, 0x00c8, 0x2a17, 0x2011, 0x0019, 0x0078,
- 0x2a17, 0xa282, 0x000c, 0x00c8, 0x2a17, 0x2011, 0x000c, 0x6308,
- 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000f, 0x0048, 0x2a23, 0x0040,
- 0x2a23, 0x2019, 0x000f, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
- 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x681c, 0xa085, 0x0100,
- 0x681e, 0x0c7f, 0x007c, 0x0c7e, 0x7148, 0x2160, 0x2008, 0xa084,
- 0xfff0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4,
- 0xa084, 0xfff8, 0xa18c, 0x0007, 0xa105, 0x78a6, 0x6016, 0x788a,
- 0xa6b4, 0x000f, 0x8637, 0x8204, 0x8004, 0xa084, 0x00ff, 0xa605,
- 0x600e, 0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x007c, 0x0c7e,
- 0x7048, 0x2060, 0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6,
- 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886, 0x0c7f, 0x007c, 0xa282,
- 0x0002, 0x00c0, 0x2b6a, 0x7aa8, 0x691c, 0xa18d, 0x0080, 0x691e,
- 0xa184, 0x0200, 0x0040, 0x2aac, 0xa18c, 0xfdff, 0x691e, 0xa294,
- 0x00ff, 0xa282, 0x0002, 0x00c8, 0x2b6a, 0x1078, 0x2af3, 0x1078,
- 0x2a57, 0xa980, 0x0001, 0x200c, 0x1078, 0x2c9d, 0x1078, 0x29e6,
- 0x88ff, 0x0040, 0x2a9f, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58,
- 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2a9b, 0x781b,
- 0x0055, 0x0078, 0x1bf7, 0x781b, 0x0069, 0x0078, 0x1bf7, 0x7e58,
- 0xa684, 0x0400, 0x00c0, 0x2aa8, 0x781b, 0x0058, 0x0078, 0x1bf7,
- 0x781b, 0x006a, 0x0078, 0x1bf7, 0xa282, 0x0002, 0x00c8, 0x2ab4,
- 0xa284, 0x0001, 0x0040, 0x2abe, 0x7148, 0xa188, 0x0000, 0x210c,
- 0xa18c, 0x2000, 0x00c0, 0x2abe, 0x2011, 0x0000, 0x1078, 0x2bd1,
- 0x1078, 0x2af3, 0x1078, 0x2a57, 0x7858, 0xa085, 0x0004, 0x785a,
- 0x781b, 0x0069, 0x0078, 0x1bf7, 0x0c7e, 0x027e, 0x2960, 0x6000,
- 0x2011, 0x0001, 0xa084, 0x2000, 0x00c0, 0x2ae3, 0x6014, 0xa084,
- 0x0040, 0x00c0, 0x2ae1, 0xa18c, 0xffef, 0x6106, 0xa006, 0x0078,
- 0x2af0, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab,
- 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x681c, 0xa085, 0x0200, 0x681e,
- 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7048, 0x2060, 0x82ff, 0x0040,
- 0x2afb, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4,
- 0xa084, 0xffbf, 0xa205, 0x78a6, 0x6016, 0x788a, 0x6004, 0xa084,
- 0xffef, 0x6006, 0x0c7f, 0x007c, 0x007e, 0x7000, 0xa086, 0x0003,
- 0x0040, 0x2b15, 0x007f, 0x0078, 0x2b18, 0x007f, 0x0078, 0x2b66,
- 0xa684, 0x0020, 0x0040, 0x2b66, 0x7888, 0xa084, 0x0040, 0x0040,
- 0x2b66, 0x78a8, 0x8001, 0x0040, 0x2b25, 0x7bb8, 0xa384, 0x003f,
- 0x831b, 0x00c8, 0x2b2c, 0x8000, 0xa005, 0x0040, 0x2b4d, 0x831b,
- 0x00c8, 0x2b35, 0x8001, 0x0040, 0x2b62, 0xa006, 0x1078, 0x3194,
- 0x78b4, 0x1078, 0x31f9, 0x0078, 0x2b66, 0xa684, 0x4000, 0x0040,
- 0x2b4d, 0x78b8, 0x801b, 0x00c8, 0x2b46, 0x8000, 0xa084, 0x003f,
- 0x00c0, 0x2b62, 0xa6b4, 0xbfff, 0x7e5a, 0x79d8, 0x7adc, 0x2001,
- 0x0001, 0xa108, 0x00c8, 0x2b56, 0xa291, 0x0000, 0x79d2, 0x79da,
- 0x7ad6, 0x7ade, 0x1078, 0x3194, 0x781b, 0x0067, 0x1078, 0x305e,
- 0x0078, 0x1bf7, 0x781b, 0x0067, 0x0078, 0x1bf7, 0x781b, 0x006a,
- 0x0078, 0x1bf7, 0x1078, 0x2b9d, 0x781b, 0x0069, 0x0078, 0x1bf7,
- 0x1078, 0x2b89, 0x781b, 0x0069, 0x0078, 0x1bf7, 0x6823, 0x0002,
- 0x1078, 0x2b91, 0x691c, 0xa18d, 0x0020, 0x691e, 0x6814, 0xa084,
- 0x8000, 0x0040, 0x2b85, 0x6817, 0x0005, 0x781b, 0x0069, 0x0078,
- 0x1bf7, 0x2001, 0x0005, 0x0078, 0x2b9f, 0x2001, 0x000c, 0x0078,
- 0x2b9f, 0x2001, 0x0006, 0x0078, 0x2b9f, 0x2001, 0x000d, 0x0078,
- 0x2b9f, 0x2001, 0x0009, 0x0078, 0x2b9f, 0x2001, 0x0007, 0x789b,
- 0x007f, 0x78aa, 0xa6b5, 0x0008, 0x7e5a, 0x007c, 0x077e, 0x873f,
- 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0, 0x3600, 0xa7b8,
- 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040, 0x2bbf, 0xa184,
- 0xfff0, 0x78a6, 0x6012, 0x6004, 0xa085, 0x0008, 0x6006, 0x8738,
- 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040, 0x0040, 0x2bcf, 0xa184,
- 0xffbf, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0010, 0x6006, 0x077f,
- 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab,
- 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004, 0x007c, 0x2031,
- 0x0000, 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab,
- 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7eaa, 0x789b, 0x0060, 0x78ab,
- 0x0005, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003,
- 0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0, 0x2001, 0x3546,
- 0x2004, 0xa082, 0x0028, 0x0040, 0x2c0d, 0x2021, 0x2c84, 0x2019,
- 0x0014, 0x20a9, 0x000c, 0x0078, 0x2c13, 0x2021, 0x2c90, 0x2019,
- 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064, 0x2404, 0xa084, 0xfff0,
- 0xa106, 0x0040, 0x2c22, 0x8420, 0x2300, 0xa210, 0x0070, 0x2c22,
- 0x0078, 0x2c15, 0x157f, 0x007c, 0x157e, 0x2011, 0x3546, 0x2214,
- 0xa282, 0x0032, 0x0048, 0x2c38, 0x0040, 0x2c3c, 0x2021, 0x2c76,
- 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, 0x0078, 0x2c4c,
- 0xa282, 0x0028, 0x0040, 0x2c44, 0x2021, 0x2c84, 0x2019, 0x0014,
- 0x20a9, 0x000c, 0x0078, 0x2c4a, 0x2021, 0x2c90, 0x2019, 0x0019,
- 0x20a9, 0x000d, 0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x2c5c,
- 0x0048, 0x2c5c, 0x8420, 0x2300, 0xa210, 0x0070, 0x2c59, 0x0078,
- 0x2c4c, 0x157f, 0xa006, 0x007c, 0x157f, 0xa582, 0x0064, 0x00c8,
- 0x2c65, 0x7808, 0xa085, 0x0070, 0x780a, 0x78ec, 0xa084, 0x0300,
- 0x0040, 0x2c73, 0x2404, 0xa09e, 0x1201, 0x00c0, 0x2c73, 0x2001,
- 0x2101, 0x0078, 0x2c74, 0x2404, 0xa005, 0x007c, 0x1201, 0x3002,
- 0x3202, 0x4203, 0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806,
- 0x7a06, 0x0a07, 0x0c07, 0x0e07, 0x3202, 0x4202, 0x5202, 0x6202,
- 0x7202, 0x6605, 0x7605, 0x7805, 0x7a05, 0x7c05, 0x7e05, 0x7f05,
- 0x2202, 0x3202, 0x4202, 0x5202, 0x5404, 0x6404, 0x7404, 0x7604,
- 0x7804, 0x7a04, 0x7c04, 0x7e04, 0x7f04, 0x789b, 0x0010, 0xa046,
- 0x007c, 0xa784, 0x0f00, 0x800c, 0xa784, 0x0007, 0x8003, 0x8003,
- 0x8003, 0x8003, 0xa105, 0xa0e0, 0x3680, 0x007c, 0x79d8, 0x7adc,
- 0x78d0, 0x801b, 0x00c8, 0x2cb5, 0x8000, 0xa084, 0x003f, 0xa108,
- 0xa291, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x0100, 0x2009, 0x3540,
- 0x2091, 0x8000, 0x2104, 0x0079, 0x2cc5, 0x2cf7, 0x2ccf, 0x2ccf,
- 0x2ccf, 0x2ccf, 0x2ccf, 0x2ccd, 0x2ccd, 0x1078, 0x1ba5, 0x784b,
- 0x0004, 0x7848, 0xa084, 0x0004, 0x00c0, 0x2cd1, 0x784b, 0x0008,
- 0x7848, 0xa084, 0x0008, 0x00c0, 0x2cd8, 0x68b0, 0xa085, 0x4000,
- 0x68b2, 0x7858, 0xa085, 0x4000, 0x785a, 0x7830, 0xa084, 0x0080,
- 0x00c0, 0x2cf7, 0x0018, 0x2cf7, 0x6818, 0xa084, 0x0020, 0x00c0,
- 0x2cf5, 0x781b, 0x00dd, 0x0078, 0x2cf7, 0x781b, 0x00e4, 0x2091,
- 0x8001, 0x0f7f, 0x007c, 0x0c7e, 0x6810, 0x8007, 0xa084, 0x000f,
- 0x8003, 0x8003, 0x8003, 0xa0e0, 0x3600, 0x6004, 0xa084, 0x000a,
- 0x00c0, 0x2d2e, 0x6108, 0xa194, 0xff00, 0x0040, 0x2d2e, 0xa18c,
- 0x00ff, 0x2001, 0x0019, 0xa106, 0x0040, 0x2d1d, 0x2001, 0x0032,
- 0xa106, 0x0040, 0x2d21, 0x0078, 0x2d25, 0x2009, 0x0020, 0x0078,
- 0x2d27, 0x2009, 0x003f, 0x0078, 0x2d27, 0x2011, 0x0000, 0x2100,
- 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x0c7f, 0x007c,
- 0x781b, 0x006a, 0x0078, 0x1bf7, 0x781b, 0x0069, 0x0078, 0x1bf7,
- 0x781b, 0x0058, 0x0078, 0x1bf7, 0x781b, 0x0055, 0x0078, 0x1bf7,
- 0x781b, 0x00dd, 0x0078, 0x1bf7, 0x781b, 0x00dc, 0x0078, 0x1bf7,
- 0x781b, 0x00e4, 0x0078, 0x1bf7, 0x781b, 0x00e3, 0x0078, 0x1bf7,
- 0x781b, 0x009e, 0x0078, 0x1bf7, 0x781b, 0x009d, 0x0078, 0x1bf7,
- 0x70a3, 0x0001, 0x781b, 0x0046, 0x0078, 0x1bf7, 0x007e, 0x7830,
- 0xa084, 0x00c0, 0x00c0, 0x2d75, 0x7808, 0xa084, 0xfffd, 0x780a,
- 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040,
- 0x2d75, 0x7808, 0xa085, 0x0002, 0x780a, 0x007f, 0x007c, 0x7808,
- 0xa085, 0x0002, 0x780a, 0x007c, 0x7830, 0xa084, 0x0040, 0x00c0,
- 0x2d7c, 0x0098, 0x2d85, 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd,
- 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021,
- 0x0040, 0x2d94, 0x0098, 0x2d92, 0x78ac, 0x007e, 0x7808, 0xa085,
- 0x0002, 0x780a, 0x007f, 0x007c, 0xa784, 0x0070, 0x0040, 0x2da8,
- 0x0c7e, 0x2d60, 0x2f68, 0x1078, 0x1b6b, 0x2d78, 0x2c68, 0x0c7f,
- 0x6817, 0x0003, 0x7858, 0xa084, 0x3f00, 0x681a, 0x682f, 0x0000,
- 0x682b, 0x0000, 0x784b, 0x0008, 0x78e4, 0xa005, 0x00d0, 0x2015,
- 0xa084, 0x0020, 0x0040, 0x2015, 0x78ec, 0xa084, 0x0003, 0x0040,
- 0x2015, 0x0018, 0x2015, 0x0078, 0x2b70, 0x0c7e, 0x6810, 0x8007,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x3600, 0x2060,
- 0x2048, 0x704a, 0x6000, 0x704e, 0x6004, 0x7052, 0x0c7f, 0x007c,
- 0x0020, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0062, 0x0009, 0x0014, 0x0014, 0x9847, 0x0014,
- 0x0014, 0x98f5, 0x98e7, 0x0014, 0x0014, 0x0080, 0x00bf, 0x0100,
- 0x0402, 0x2008, 0xf880, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014,
- 0xa200, 0x8838, 0x817e, 0x842a, 0x84a0, 0x3806, 0x8839, 0x28c2,
- 0x9cc3, 0xa805, 0x0864, 0xa83b, 0x3008, 0x28c1, 0x9cc3, 0xa201,
- 0x300c, 0x2847, 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a,
- 0xa808, 0x28e2, 0x9ca0, 0xa8f3, 0x0864, 0xa829, 0x300c, 0xa801,
- 0x3008, 0x28e1, 0x9ca0, 0x280d, 0xa204, 0x64c0, 0x67a0, 0x6fc0,
- 0x1814, 0x883b, 0x7023, 0x8576, 0x8677, 0xa80f, 0x786e, 0x883e,
- 0xa80c, 0x282b, 0xa205, 0x64a0, 0x67a0, 0x6fc0, 0x1814, 0x883b,
- 0x7023, 0x8576, 0x8677, 0xa801, 0x883e, 0x2069, 0x28c1, 0x9cc3,
- 0x2044, 0x2103, 0x20a2, 0x2081, 0xa8dc, 0xa207, 0x0014, 0xa203,
- 0x8000, 0x84a8, 0x85a4, 0x1872, 0x849a, 0x883c, 0x1fe2, 0xf601,
- 0xa208, 0x856e, 0x866f, 0x0704, 0x3008, 0x9ca0, 0x0014, 0xa202,
- 0x8000, 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf848, 0x8174, 0x86eb,
- 0x85eb, 0x872e, 0x87a9, 0x883f, 0x08e6, 0xa8f1, 0xf861, 0xa8e8,
- 0xf801, 0x0014, 0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfaa2,
- 0x1de2, 0x0014, 0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8, 0xd6e0,
- 0x1fe6, 0x0014, 0xa206, 0x6865, 0x817f, 0x842a, 0x1dc1, 0x8823,
- 0x0016, 0x6042, 0x8008, 0xa8fa, 0x8000, 0x84a4, 0x8160, 0x842a,
- 0xf021, 0x3008, 0x84a8, 0x1dc6, 0x20d7, 0x8822, 0x0016, 0x8000,
- 0x2848, 0x1011, 0xa8fc, 0x3008, 0x8000, 0xa000, 0x2802, 0x1011,
- 0xa8fd, 0xa887, 0x3008, 0x283d, 0x1011, 0xa8fd, 0xa209, 0x0017,
- 0x300c, 0x8000, 0x85a4, 0x1de2, 0xdac1, 0x0014, 0x26e0, 0x873a,
- 0xfaa2, 0x19f2, 0x1fe2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x817e,
- 0x842a, 0x84a0, 0x3806, 0x0210, 0x9ccd, 0x0704, 0x0000, 0x127e,
- 0x2091, 0x2200, 0x2049, 0x2ec7, 0x7000, 0x7204, 0xa205, 0x720c,
- 0xa215, 0x7008, 0xa084, 0xfffd, 0xa205, 0x0040, 0x2ed9, 0x0078,
- 0x2ede, 0x7003, 0x0000, 0x127f, 0x2000, 0x007c, 0x7000, 0xa084,
- 0x0001, 0x00c0, 0x2f0c, 0x7108, 0x8104, 0x00c8, 0x2eeb, 0x1078,
- 0x2fa8, 0x0078, 0x2ee3, 0x700c, 0xa08c, 0x007f, 0x0040, 0x2f0c,
- 0x7004, 0x8004, 0x00c8, 0x2f03, 0x7014, 0xa005, 0x00c0, 0x2eff,
- 0x7010, 0xa005, 0x0040, 0x2f03, 0xa102, 0x00c8, 0x2ee3, 0x7007,
- 0x0010, 0x0078, 0x2f0c, 0x8aff, 0x0040, 0x2f0c, 0x1078, 0x316b,
- 0x00c0, 0x2f06, 0x0040, 0x2ee3, 0x1078, 0x2f56, 0x7003, 0x0000,
- 0x127f, 0x2000, 0x007c, 0x6424, 0x84ff, 0x0040, 0x2f30, 0x2c70,
- 0x2039, 0x2f35, 0x2704, 0xae68, 0x680c, 0xa630, 0x6808, 0xa529,
- 0x8421, 0x0040, 0x2f30, 0x8738, 0x2704, 0xa005, 0x00c0, 0x2f1b,
- 0x7098, 0xa075, 0x0040, 0x2f30, 0x2039, 0x2f32, 0x0078, 0x2f1a,
- 0x007c, 0x0000, 0x0004, 0x0008, 0x000c, 0x0010, 0x0014, 0x0018,
- 0x001c, 0x0000, 0x127e, 0x2091, 0x2200, 0x2079, 0x3500, 0x2071,
- 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2071,
- 0x0020, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2049,
- 0x0000, 0x78b3, 0x0000, 0x127f, 0x2000, 0x007c, 0x2049, 0x2f56,
- 0x7004, 0x8004, 0x00c8, 0x2f82, 0x7007, 0x0012, 0x7108, 0x7008,
- 0xa106, 0x00c0, 0x2f5e, 0xa184, 0x0030, 0x0040, 0x2f6b, 0xa086,
- 0x0030, 0x00c0, 0x2f5e, 0x7000, 0xa084, 0x0001, 0x00c0, 0x2f82,
- 0x7008, 0xa084, 0x000c, 0x00c0, 0x2f80, 0x710c, 0xa184, 0x0300,
- 0x00c0, 0x2f80, 0xa184, 0x007f, 0x00c0, 0x2f56, 0x0078, 0x2f82,
- 0x6817, 0x0003, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xa084,
- 0x0008, 0x00c0, 0x2f86, 0x7007, 0x0012, 0x7108, 0x8104, 0x0048,
- 0x2f8b, 0x78b3, 0x0000, 0x7003, 0x0000, 0x2049, 0x0000, 0x007c,
- 0x107e, 0x007e, 0x127e, 0x157e, 0x2091, 0x2200, 0x7108, 0x1078,
- 0x2fa8, 0x157f, 0x127f, 0x2091, 0x8001, 0x007f, 0x107f, 0x007c,
- 0x7204, 0x2118, 0x7108, 0x700c, 0xa084, 0x0300, 0x00c0, 0x2fea,
- 0xa184, 0x000c, 0x00c0, 0x2fea, 0x8213, 0x8213, 0x8213, 0x8213,
- 0xa284, 0x0100, 0xa10d, 0x810b, 0x810b, 0x810f, 0xa184, 0x0007,
- 0x0079, 0x2fc2, 0x2fcc, 0x2fdc, 0x2fea, 0x2fdc, 0x2ffe, 0x2ffe,
- 0x2fea, 0x2ffc, 0x1078, 0x1ba5, 0x7007, 0x0002, 0x8aff, 0x00c0,
- 0x2fd5, 0x2049, 0x0000, 0x0078, 0x2fd9, 0x1078, 0x316b, 0x00c0,
- 0x2fd5, 0x78b3, 0x0000, 0x007c, 0x7007, 0x0002, 0x8aff, 0x00c0,
- 0x2fe3, 0x0078, 0x2fe7, 0x1078, 0x316b, 0x00c0, 0x2fe3, 0x78b3,
- 0x0000, 0x007c, 0x7007, 0x0002, 0x1078, 0x2f56, 0x1078, 0x2cbb,
- 0x6814, 0xa084, 0x8000, 0x0040, 0x2ff7, 0x6817, 0x0002, 0x007c,
- 0x1078, 0x1ba5, 0x1078, 0x1ba5, 0x1078, 0x3050, 0x7210, 0x7114,
- 0x700c, 0xa09c, 0x007f, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000,
- 0x78b0, 0xa005, 0x0040, 0x3010, 0x78b3, 0x0000, 0x0078, 0x3033,
- 0x1078, 0x3050, 0x2704, 0x2c58, 0xac60, 0x630c, 0x2200, 0xa322,
- 0x6308, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x3029, 0x00c8,
- 0x3029, 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078,
- 0x3010, 0x2b60, 0x8a07, 0xa7ba, 0x2f32, 0xa73d, 0x2c00, 0x6882,
- 0x6f86, 0x6c8e, 0x6b8a, 0x7007, 0x0012, 0x1078, 0x2f56, 0x007c,
- 0x8738, 0x2704, 0xa005, 0x00c0, 0x3044, 0x6098, 0xa005, 0x0040,
- 0x304d, 0x2060, 0x2039, 0x2f32, 0x8a51, 0x0040, 0x304c, 0x7008,
- 0xa084, 0x00c0, 0xa086, 0x00c0, 0x007c, 0x2051, 0x0000, 0x007c,
- 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x305d, 0x2039, 0x2f38,
- 0x6000, 0xa064, 0x00c0, 0x305d, 0x2d60, 0x007c, 0x127e, 0x0d7e,
- 0x2091, 0x2200, 0x0d7f, 0x6880, 0x2060, 0x6884, 0x6b88, 0x6c8c,
- 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0xa0b8, 0x2f32, 0x7e08,
- 0xa6b5, 0x000c, 0x6818, 0xa084, 0x0040, 0x0040, 0x3079, 0xa6b5,
- 0x0001, 0x0f7e, 0x2079, 0x0100, 0x7858, 0x0f7f, 0xa084, 0x0040,
- 0x0040, 0x3088, 0xa684, 0x0001, 0x00c0, 0x3088, 0xa6b5, 0x0001,
- 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x308a, 0x7000,
- 0xa005, 0x0040, 0x3095, 0x1078, 0x1ba5, 0x2400, 0xa305, 0x00c0,
- 0x309b, 0x0078, 0x30d8, 0x2c58, 0x2704, 0xac60, 0x6004, 0xa400,
- 0x007e, 0x701a, 0x6000, 0xa301, 0x701e, 0x2009, 0x04fd, 0x2104,
- 0xa086, 0x04fd, 0x007f, 0x00c0, 0x30c8, 0xa084, 0x0001, 0x0040,
- 0x30c8, 0xa684, 0x0001, 0x00c0, 0x30c8, 0x7013, 0x0001, 0x7017,
- 0x0000, 0x7602, 0x7007, 0x0001, 0x78b3, 0x0001, 0xa4a0, 0x0001,
- 0xa399, 0x0000, 0x6004, 0xa400, 0x701a, 0x6000, 0xa301, 0x701e,
- 0x620c, 0x2400, 0xa202, 0x7012, 0x6208, 0x2300, 0xa203, 0x7016,
- 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078, 0x3038, 0x0078, 0x30da,
- 0x1078, 0x316b, 0x00c0, 0x30d8, 0x127f, 0x2000, 0x007c, 0x127e,
- 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xa084,
- 0x0004, 0x00c0, 0x30e6, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c,
- 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049, 0x30f0, 0x7007,
- 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x30f9, 0x7000, 0xa005,
- 0x0040, 0x3104, 0x1078, 0x1ba5, 0x7e08, 0xa6b5, 0x000c, 0x6818,
- 0xa084, 0x0040, 0x0040, 0x310e, 0xa6b5, 0x0001, 0x6824, 0xa005,
- 0x0040, 0x311a, 0x2050, 0x2039, 0x2f35, 0x2d60, 0x1078, 0x316b,
- 0x00c0, 0x3116, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e,
- 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x037f, 0x047f, 0x7e08, 0xa6b5,
- 0x000c, 0x6818, 0xa084, 0x0040, 0x0040, 0x3130, 0xa6b5, 0x0001,
- 0x2049, 0x311d, 0x6824, 0xa055, 0x0040, 0x3168, 0x2d70, 0x2e60,
- 0x2039, 0x2f35, 0x2704, 0xae68, 0x680c, 0xa422, 0x6808, 0xa31b,
- 0x0048, 0x3155, 0x8a51, 0x00c0, 0x3147, 0x1078, 0x1ba5, 0x8738,
- 0x2704, 0xa005, 0x00c0, 0x313b, 0x7098, 0xa075, 0x2060, 0x0040,
- 0x3168, 0x2039, 0x2f32, 0x0078, 0x313a, 0x8422, 0x8420, 0x831a,
- 0xa399, 0x0000, 0x690c, 0x2400, 0xa122, 0x6908, 0x2300, 0xa11b,
- 0x00c8, 0x3164, 0x1078, 0x1ba5, 0x2071, 0x0020, 0x0078, 0x3088,
- 0x127f, 0x2000, 0x007c, 0x7008, 0xa084, 0x00c0, 0xa086, 0x00c0,
- 0x0040, 0x3193, 0x2704, 0xac08, 0x2104, 0x701e, 0x8108, 0x2104,
- 0x701a, 0x8108, 0x2104, 0x7016, 0x8108, 0x2104, 0x7012, 0x0f7e,
- 0x2079, 0x0100, 0x7858, 0x0f7f, 0xa084, 0x0040, 0x0040, 0x318e,
- 0xa684, 0x0001, 0x00c0, 0x318e, 0xa6b5, 0x0001, 0x7602, 0x7007,
- 0x0001, 0x1078, 0x3038, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091,
- 0x2200, 0x2049, 0x3194, 0x0d7f, 0x087f, 0x7108, 0xa184, 0x00c0,
- 0x00c0, 0x31aa, 0x6824, 0xa005, 0x0040, 0x31ba, 0x0078, 0x2ede,
- 0x0078, 0x31ba, 0x7108, 0x8104, 0x00c8, 0x31b2, 0x1078, 0x2fa8,
- 0x0078, 0x319d, 0x7007, 0x0010, 0x7108, 0x8104, 0x00c8, 0x31b4,
- 0x1078, 0x2fa8, 0x7008, 0xa086, 0x0002, 0x00c0, 0x319d, 0x7000,
- 0xa005, 0x00c0, 0x319d, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f,
- 0x2000, 0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0d7e, 0x2091,
- 0x2200, 0x0d7f, 0x2049, 0x31ca, 0xad80, 0x0010, 0x20a0, 0x2099,
- 0x0031, 0x700c, 0xa084, 0x007f, 0x6826, 0x7007, 0x0008, 0x7007,
- 0x0002, 0x7003, 0x0001, 0x0040, 0x31e8, 0x8000, 0x80ac, 0x53a5,
- 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x31ea, 0x2049,
- 0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f, 0x2000,
- 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049,
- 0x31f9, 0x6880, 0x2060, 0x6884, 0x6b88, 0x6c8c, 0x8057, 0xaad4,
- 0x00ff, 0xa084, 0x00ff, 0xa0b8, 0x2f32, 0x7e08, 0xa6b5, 0x0004,
- 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x3212, 0x2c58,
- 0x2704, 0xac60, 0x6004, 0xa400, 0x701a, 0x6000, 0xa301, 0x701e,
- 0x7013, 0x0001, 0x7017, 0x0000, 0x7602, 0x7007, 0x0001, 0x007f,
- 0x8007, 0x2009, 0x0031, 0x200a, 0x00a0, 0x322c, 0x7108, 0x7007,
- 0x0002, 0x810c, 0x00c8, 0x322c, 0x810c, 0x0048, 0x3239, 0x0078,
- 0x2fea, 0xa4a0, 0x0001, 0xa399, 0x0000, 0x6b8a, 0x6c8e, 0x7007,
- 0x0004, 0x2049, 0x0000, 0x7003, 0x0000, 0x127f, 0x2000, 0x007c,
- 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x00c8, 0x3251,
- 0xa200, 0x00f0, 0x324c, 0x8086, 0x818e, 0x007c, 0x157e, 0x20a9,
- 0x0010, 0xa005, 0x0040, 0x3277, 0xa11a, 0x00c8, 0x3277, 0x8213,
- 0x818d, 0x0048, 0x326a, 0xa11a, 0x00c8, 0x326b, 0x00f0, 0x325f,
- 0x0078, 0x326f, 0xa11a, 0x2308, 0x8210, 0x00f0, 0x325f, 0x007e,
- 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f, 0x007c, 0x007e,
- 0x3200, 0xa085, 0x0800, 0x0078, 0x3273, 0x00e0, 0x32bf, 0x2091,
- 0x6000, 0x7820, 0x8001, 0x7822, 0x00c0, 0x32b9, 0x7824, 0x7822,
- 0x2091, 0x8000, 0x2069, 0x3540, 0x6800, 0xa084, 0x0007, 0x0040,
- 0x32a1, 0xa086, 0x0002, 0x0040, 0x32a1, 0x6830, 0xa00d, 0x0040,
- 0x32a1, 0x2104, 0xa005, 0x0040, 0x32a1, 0x8001, 0x200a, 0x0040,
- 0x336f, 0x2061, 0x3680, 0x20a9, 0x0080, 0x6034, 0xa005, 0x0040,
- 0x32b3, 0x8001, 0x6036, 0x00c0, 0x32b3, 0x6010, 0xa005, 0x0040,
- 0x32b3, 0x1078, 0x1a19, 0xace0, 0x0010, 0x0070, 0x32b9, 0x0078,
- 0x32a5, 0x1078, 0x32d4, 0x1078, 0x32c2, 0x1078, 0x32f9, 0x2091,
- 0x8001, 0x007c, 0x783c, 0x8001, 0x783e, 0x00c0, 0x32d3, 0x7840,
- 0x783e, 0x7848, 0xa005, 0x0040, 0x32d3, 0x8001, 0x784a, 0x00c0,
- 0x32d3, 0x1078, 0x1a19, 0x007c, 0x7834, 0x8001, 0x7836, 0x00c0,
- 0x32f8, 0x7838, 0x7836, 0x2091, 0x8000, 0x7844, 0xa005, 0x00c0,
- 0x32e3, 0x2001, 0x0101, 0x8001, 0x7846, 0xa080, 0x3e80, 0x2040,
- 0x2004, 0xa065, 0x0040, 0x32f8, 0x6020, 0xa005, 0x0040, 0x32f4,
- 0x8001, 0x6022, 0x0040, 0x3328, 0x6000, 0x2c40, 0x0078, 0x32e9,
- 0x007c, 0x7828, 0x8001, 0x782a, 0x00c0, 0x3327, 0x782c, 0x782a,
- 0x7830, 0xa005, 0x00c0, 0x3306, 0x2001, 0x0080, 0x8001, 0x7832,
- 0x8003, 0x8003, 0x8003, 0x8003, 0xa090, 0x3680, 0xa298, 0x0002,
- 0x2304, 0xa084, 0x0008, 0x0040, 0x3327, 0xa290, 0x0009, 0x2204,
- 0xa005, 0x0040, 0x331f, 0x8001, 0x2012, 0x00c0, 0x3327, 0x2304,
- 0xa084, 0xfff7, 0xa085, 0x0080, 0x201a, 0x1078, 0x1a19, 0x007c,
- 0x2069, 0x3540, 0x6800, 0xa005, 0x0040, 0x3332, 0x683c, 0xac06,
- 0x0040, 0x336f, 0x6017, 0x0006, 0x60b0, 0xa084, 0x3f00, 0x601a,
- 0x601c, 0xa084, 0x00ff, 0xa085, 0x0060, 0x601e, 0x6000, 0x2042,
- 0x6710, 0x6fb6, 0x1078, 0x1692, 0x6818, 0xa005, 0x0040, 0x334a,
- 0x8001, 0x681a, 0x6808, 0xa084, 0xffef, 0x680a, 0x6810, 0x8001,
- 0x00d0, 0x3354, 0x1078, 0x1ba5, 0x6812, 0x602f, 0x0000, 0x602b,
- 0x0000, 0x2c68, 0x1078, 0x17dd, 0x2069, 0x3540, 0x2001, 0x0006,
- 0x68a2, 0x7944, 0xa184, 0x0100, 0x00c0, 0x336a, 0x69ba, 0x2001,
- 0x0004, 0x68a2, 0x1078, 0x1a14, 0x2091, 0x8001, 0x007c, 0x2009,
- 0x354f, 0x2164, 0x2069, 0x0100, 0x1078, 0x1b6b, 0x6017, 0x0006,
- 0x6858, 0xa084, 0x3f00, 0x601a, 0x601c, 0xa084, 0x00ff, 0xa085,
- 0x0048, 0x601e, 0x602f, 0x0000, 0x602b, 0x0000, 0x6830, 0xa084,
- 0x0040, 0x0040, 0x33ab, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848,
- 0xa084, 0x0004, 0x0040, 0x3398, 0x0070, 0x3398, 0x0078, 0x338f,
- 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0040,
- 0x33a5, 0x0070, 0x33a5, 0x0078, 0x339c, 0x20a9, 0x00fa, 0x0070,
- 0x33ab, 0x0078, 0x33a7, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b,
- 0x0046, 0x2009, 0x3568, 0x200b, 0x0007, 0x784c, 0x784a, 0x2091,
- 0x8001, 0x007c, 0x2079, 0x3500, 0x1078, 0x3403, 0x1078, 0x33cb,
- 0x1078, 0x33e0, 0x1078, 0x33f5, 0x7833, 0x0000, 0x7847, 0x0000,
- 0x784b, 0x0000, 0x007c, 0x2019, 0x000a, 0x2011, 0x3546, 0x2204,
- 0xa086, 0x0032, 0x0040, 0x33dd, 0x2019, 0x000c, 0x2204, 0xa086,
- 0x003c, 0x0040, 0x33dd, 0x2019, 0x0008, 0x7b2a, 0x7b2e, 0x007c,
- 0x2019, 0x0030, 0x2011, 0x3546, 0x2204, 0xa086, 0x0032, 0x0040,
- 0x33f2, 0x2019, 0x0039, 0x2204, 0xa086, 0x003c, 0x0040, 0x33f2,
- 0x2019, 0x0027, 0x7b36, 0x7b3a, 0x007c, 0x2019, 0x000d, 0x2011,
- 0x3546, 0x2204, 0xa086, 0x003c, 0x0040, 0x3400, 0x2019, 0x000a,
- 0x7b3e, 0x7b42, 0x007c, 0x2019, 0x2faf, 0x2011, 0x3546, 0x2204,
- 0xa086, 0x0032, 0x0040, 0x3415, 0x2019, 0x3971, 0x2204, 0xa086,
- 0x003c, 0x0040, 0x3415, 0x2019, 0x2626, 0x7b22, 0x7b26, 0x007c,
- 0x92a7
-};
-unsigned short __devinitdata sbus_risc_code_length01 = 0x2419;
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index a2ef03243a2..166417a6afb 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -169,12 +169,10 @@ scsi_pool_alloc_command(struct scsi_host_cmd_pool *pool, gfp_t gfp_mask)
{
struct scsi_cmnd *cmd;
- cmd = kmem_cache_alloc(pool->cmd_slab, gfp_mask | pool->gfp_mask);
+ cmd = kmem_cache_zalloc(pool->cmd_slab, gfp_mask | pool->gfp_mask);
if (!cmd)
return NULL;
- memset(cmd, 0, sizeof(*cmd));
-
cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab,
gfp_mask | pool->gfp_mask);
if (!cmd->sense_buffer) {
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 4b13e36d3aa..d1cb64ad1a3 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -791,7 +791,22 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
"%d bytes done.\n",
req->nr_sectors, good_bytes));
- /* A number of bytes were successfully read. If there
+ /*
+ * Recovered errors need reporting, but they're always treated
+ * as success, so fiddle the result code here. For BLOCK_PC
+ * we already took a copy of the original into rq->errors which
+ * is what gets returned to the user
+ */
+ if (sense_valid && sshdr.sense_key == RECOVERED_ERROR) {
+ if (!(req->cmd_flags & REQ_QUIET))
+ scsi_print_sense("", cmd);
+ result = 0;
+ /* BLOCK_PC may have set error */
+ error = 0;
+ }
+
+ /*
+ * A number of bytes were successfully read. If there
* are leftovers and there is some kind of error
* (result != 0), retry the rest.
*/
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index e1850904ff7..fbc83bebdd8 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -38,9 +38,6 @@ static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
{ };
#endif
-/* scsi_scan.c */
-int scsi_complete_async_scans(void);
-
/* scsi_devinfo.c */
extern int scsi_get_device_flags(struct scsi_device *sdev,
const unsigned char *vendor,
diff --git a/drivers/scsi/scsi_wait_scan.c b/drivers/scsi/scsi_wait_scan.c
index 8a636103083..2f21af21269 100644
--- a/drivers/scsi/scsi_wait_scan.c
+++ b/drivers/scsi/scsi_wait_scan.c
@@ -11,7 +11,7 @@
*/
#include <linux/module.h>
-#include "scsi_priv.h"
+#include <scsi/scsi_scan.h>
static int __init wait_scan_init(void)
{
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index aeab5d9dff2..3fcb64b91c4 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1051,12 +1051,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
good_bytes = sd_completed_bytes(SCpnt);
break;
case RECOVERED_ERROR:
- /* Inform the user, but make sure that it's not treated
- * as a hard error.
- */
- scsi_print_sense("sd", SCpnt);
- SCpnt->result = 0;
- memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
good_bytes = scsi_bufflen(SCpnt);
break;
case NO_SENSE:
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index c9146d751cb..4f618f48735 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -264,6 +264,7 @@ struct ses_host_edev {
struct enclosure_device *edev;
};
+#if 0
int ses_match_host(struct enclosure_device *edev, void *data)
{
struct ses_host_edev *sed = data;
@@ -280,6 +281,7 @@ int ses_match_host(struct enclosure_device *edev, void *data)
sed->edev = edev;
return 1;
}
+#endif /* 0 */
static void ses_process_descriptor(struct enclosure_component *ecomp,
unsigned char *desc)
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index ffc87851f2e..82312df9b0b 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1312,8 +1312,10 @@ static void sg_rq_end_io(struct request *rq, int uptodate)
wake_up_interruptible(&sfp->read_wait);
kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN);
kref_put(&sfp->f_ref, sg_remove_sfp);
- } else
- execute_in_process_context(sg_rq_end_io_usercontext, &srp->ew);
+ } else {
+ INIT_WORK(&srp->ew.work, sg_rq_end_io_usercontext);
+ schedule_work(&srp->ew.work);
+ }
}
static struct file_operations sg_fops = {
@@ -1656,10 +1658,30 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd)
md->null_mapped = hp->dxferp ? 0 : 1;
}
- if (iov_count)
- res = blk_rq_map_user_iov(q, rq, md, hp->dxferp, iov_count,
- hp->dxfer_len, GFP_ATOMIC);
- else
+ if (iov_count) {
+ int len, size = sizeof(struct sg_iovec) * iov_count;
+ struct iovec *iov;
+
+ iov = kmalloc(size, GFP_ATOMIC);
+ if (!iov)
+ return -ENOMEM;
+
+ if (copy_from_user(iov, hp->dxferp, size)) {
+ kfree(iov);
+ return -EFAULT;
+ }
+
+ len = iov_length(iov, iov_count);
+ if (hp->dxfer_len < len) {
+ iov_count = iov_shorten(iov, iov_count, hp->dxfer_len);
+ len = hp->dxfer_len;
+ }
+
+ res = blk_rq_map_user_iov(q, rq, md, (struct sg_iovec *)iov,
+ iov_count,
+ len, GFP_ATOMIC);
+ kfree(iov);
+ } else
res = blk_rq_map_user(q, rq, md, hp->dxferp,
hp->dxfer_len, GFP_ATOMIC);
@@ -2079,7 +2101,8 @@ static void sg_remove_sfp(struct kref *kref)
write_unlock_irqrestore(&sg_index_lock, iflags);
wake_up_interruptible(&sdp->o_excl_wait);
- execute_in_process_context(sg_remove_sfp_usercontext, &sfp->ew);
+ INIT_WORK(&sfp->ew.work, sg_remove_sfp_usercontext);
+ schedule_work(&sfp->ew.work);
}
static int
diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c
index 77f0b2cdaa9..37b3359e863 100644
--- a/drivers/scsi/sni_53c710.c
+++ b/drivers/scsi/sni_53c710.c
@@ -83,7 +83,7 @@ static int __init snirm710_probe(struct platform_device *dev)
}
hostdata->dev = &dev->dev;
- dma_set_mask(&dev->dev, DMA_32BIT_MASK);
+ dma_set_mask(&dev->dev, DMA_BIT_MASK(32));
hostdata->base = ioremap_nocache(base, 0x100);
hostdata->differential = 0;
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index e7fa3caead7..0e1a0f2d2ad 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -309,15 +309,6 @@ static int sr_done(struct scsi_cmnd *SCpnt)
break;
case RECOVERED_ERROR:
-
- /*
- * An error occured, but it recovered. Inform the
- * user, but make sure that it's not treated as a
- * hard error.
- */
- scsi_print_sense("sr", SCpnt);
- SCpnt->result = 0;
- SCpnt->sense_buffer[0] = 0x0;
good_bytes = this_count;
break;
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 47b614e8580..8d2a95c4e5b 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -36,11 +36,11 @@
#include <scsi/scsi_eh.h>
#define DRV_NAME "stex"
-#define ST_DRIVER_VERSION "4.6.0000.1"
-#define ST_VER_MAJOR 4
-#define ST_VER_MINOR 6
-#define ST_OEM 0
-#define ST_BUILD_VER 1
+#define ST_DRIVER_VERSION "4.6.0000.3"
+#define ST_VER_MAJOR 4
+#define ST_VER_MINOR 6
+#define ST_OEM 0
+#define ST_BUILD_VER 3
enum {
/* MU register offset */
@@ -55,6 +55,13 @@ enum {
OIS = 0x30, /* MU_OUTBOUND_INTERRUPT_STATUS */
OIM = 0x3c, /* MU_OUTBOUND_INTERRUPT_MASK */
+ YH2I_INT = 0x20,
+ YINT_EN = 0x34,
+ YI2H_INT = 0x9c,
+ YI2H_INT_C = 0xa0,
+ YH2I_REQ = 0xc0,
+ YH2I_REQ_HI = 0xc4,
+
/* MU register value */
MU_INBOUND_DOORBELL_HANDSHAKE = 1,
MU_INBOUND_DOORBELL_REQHEADCHANGED = 2,
@@ -95,20 +102,14 @@ enum {
TASK_ATTRIBUTE_ORDERED = 0x2,
TASK_ATTRIBUTE_ACA = 0x4,
- /* request count, etc. */
- MU_MAX_REQUEST = 32,
+ SS_STS_NORMAL = 0x80000000,
+ SS_STS_DONE = 0x40000000,
+ SS_STS_HANDSHAKE = 0x20000000,
- /* one message wasted, use MU_MAX_REQUEST+1
- to handle MU_MAX_REQUEST messages */
- MU_REQ_COUNT = (MU_MAX_REQUEST + 1),
- MU_STATUS_COUNT = (MU_MAX_REQUEST + 1),
+ SS_HEAD_HANDSHAKE = 0x80,
STEX_CDB_LENGTH = 16,
- REQ_VARIABLE_LEN = 1024,
STATUS_VAR_LEN = 128,
- ST_CAN_QUEUE = MU_MAX_REQUEST,
- ST_CMD_PER_LUN = MU_MAX_REQUEST,
- ST_MAX_SG = 32,
/* sg flags */
SG_CF_EOT = 0x80, /* end of table */
@@ -120,9 +121,9 @@ enum {
st_shasta = 0,
st_vsc = 1,
- st_vsc1 = 2,
- st_yosemite = 3,
- st_seq = 4,
+ st_yosemite = 2,
+ st_seq = 3,
+ st_yel = 4,
PASSTHRU_REQ_TYPE = 0x00000001,
PASSTHRU_REQ_NO_WAKEUP = 0x00000100,
@@ -160,26 +161,36 @@ struct st_sgitem {
u8 ctrl; /* SG_CF_xxx */
u8 reserved[3];
__le32 count;
+ __le64 addr;
+};
+
+struct st_ss_sgitem {
__le32 addr;
__le32 addr_hi;
+ __le32 count;
};
struct st_sgtable {
__le16 sg_count;
__le16 max_sg_count;
__le32 sz_in_byte;
- struct st_sgitem table[ST_MAX_SG];
+};
+
+struct st_msg_header {
+ __le64 handle;
+ u8 flag;
+ u8 channel;
+ __le16 timeout;
+ u32 reserved;
};
struct handshake_frame {
- __le32 rb_phy; /* request payload queue physical address */
- __le32 rb_phy_hi;
+ __le64 rb_phy; /* request payload queue physical address */
__le16 req_sz; /* size of each request payload */
__le16 req_cnt; /* count of reqs the buffer can hold */
__le16 status_sz; /* size of each status payload */
__le16 status_cnt; /* count of status the buffer can hold */
- __le32 hosttime; /* seconds from Jan 1, 1970 (GMT) */
- __le32 hosttime_hi;
+ __le64 hosttime; /* seconds from Jan 1, 1970 (GMT) */
u8 partner_type; /* who sends this frame */
u8 reserved0[7];
__le32 partner_ver_major;
@@ -188,7 +199,8 @@ struct handshake_frame {
__le32 partner_ver_build;
__le32 extra_offset; /* NEW */
__le32 extra_size; /* NEW */
- u32 reserved1[2];
+ __le32 scratch_size;
+ u32 reserved1;
};
struct req_msg {
@@ -200,7 +212,7 @@ struct req_msg {
u8 data_dir;
u8 payload_sz; /* payload size in 4-byte, not used */
u8 cdb[STEX_CDB_LENGTH];
- u8 variable[REQ_VARIABLE_LEN];
+ u32 variable[0];
};
struct status_msg {
@@ -256,12 +268,6 @@ struct st_drvver {
u32 reserved[3];
};
-#define MU_REQ_BUFFER_SIZE (MU_REQ_COUNT * sizeof(struct req_msg))
-#define MU_STATUS_BUFFER_SIZE (MU_STATUS_COUNT * sizeof(struct status_msg))
-#define MU_BUFFER_SIZE (MU_REQ_BUFFER_SIZE + MU_STATUS_BUFFER_SIZE)
-#define STEX_EXTRA_SIZE sizeof(struct st_frame)
-#define STEX_BUFFER_SIZE (MU_BUFFER_SIZE + STEX_EXTRA_SIZE)
-
struct st_ccb {
struct req_msg *req;
struct scsi_cmnd *cmd;
@@ -273,6 +279,7 @@ struct st_ccb {
u32 req_type;
u8 srb_status;
u8 scsi_status;
+ u8 reserved[2];
};
struct st_hba {
@@ -284,6 +291,10 @@ struct st_hba {
struct Scsi_Host *host;
struct pci_dev *pdev;
+ struct req_msg * (*alloc_rq) (struct st_hba *);
+ int (*map_sg)(struct st_hba *, struct req_msg *, struct st_ccb *);
+ void (*send) (struct st_hba *, struct req_msg *, u16);
+
u32 req_head;
u32 req_tail;
u32 status_head;
@@ -291,16 +302,36 @@ struct st_hba {
struct status_msg *status_buffer;
void *copy_buffer; /* temp buffer for driver-handled commands */
- struct st_ccb ccb[MU_MAX_REQUEST];
+ struct st_ccb *ccb;
struct st_ccb *wait_ccb;
- wait_queue_head_t waitq;
+ __le32 *scratch;
unsigned int mu_status;
+ unsigned int cardtype;
+ int msi_enabled;
int out_req_cnt;
+ u32 extra_offset;
+ u16 rq_count;
+ u16 rq_size;
+ u16 sts_count;
+};
- unsigned int cardtype;
+struct st_card_info {
+ struct req_msg * (*alloc_rq) (struct st_hba *);
+ int (*map_sg)(struct st_hba *, struct req_msg *, struct st_ccb *);
+ void (*send) (struct st_hba *, struct req_msg *, u16);
+ unsigned int max_id;
+ unsigned int max_lun;
+ unsigned int max_channel;
+ u16 rq_count;
+ u16 rq_size;
+ u16 sts_count;
};
+static int msi;
+module_param(msi, int, 0);
+MODULE_PARM_DESC(msi, "Enable Message Signaled Interrupts(0=off, 1=on)");
+
static const char console_inq_page[] =
{
0x03,0x00,0x03,0x03,0xFA,0x00,0x00,0x30,
@@ -318,22 +349,20 @@ MODULE_DESCRIPTION("Promise Technology SuperTrak EX Controllers");
MODULE_LICENSE("GPL");
MODULE_VERSION(ST_DRIVER_VERSION);
-static void stex_gettime(__le32 *time)
+static void stex_gettime(__le64 *time)
{
struct timeval tv;
do_gettimeofday(&tv);
- *time = cpu_to_le32(tv.tv_sec & 0xffffffff);
- *(time + 1) = cpu_to_le32((tv.tv_sec >> 16) >> 16);
+ *time = cpu_to_le64(tv.tv_sec);
}
static struct status_msg *stex_get_status(struct st_hba *hba)
{
- struct status_msg *status =
- hba->status_buffer + hba->status_tail;
+ struct status_msg *status = hba->status_buffer + hba->status_tail;
++hba->status_tail;
- hba->status_tail %= MU_STATUS_COUNT;
+ hba->status_tail %= hba->sts_count+1;
return status;
}
@@ -351,47 +380,83 @@ static void stex_invalid_field(struct scsi_cmnd *cmd,
static struct req_msg *stex_alloc_req(struct st_hba *hba)
{
- struct req_msg *req = ((struct req_msg *)hba->dma_mem) +
- hba->req_head;
+ struct req_msg *req = hba->dma_mem + hba->req_head * hba->rq_size;
++hba->req_head;
- hba->req_head %= MU_REQ_COUNT;
+ hba->req_head %= hba->rq_count+1;
return req;
}
+static struct req_msg *stex_ss_alloc_req(struct st_hba *hba)
+{
+ return (struct req_msg *)(hba->dma_mem +
+ hba->req_head * hba->rq_size + sizeof(struct st_msg_header));
+}
+
static int stex_map_sg(struct st_hba *hba,
struct req_msg *req, struct st_ccb *ccb)
{
struct scsi_cmnd *cmd;
struct scatterlist *sg;
struct st_sgtable *dst;
+ struct st_sgitem *table;
int i, nseg;
cmd = ccb->cmd;
- dst = (struct st_sgtable *)req->variable;
- dst->max_sg_count = cpu_to_le16(ST_MAX_SG);
- dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd));
+ nseg = scsi_dma_map(cmd);
+ BUG_ON(nseg < 0);
+ if (nseg) {
+ dst = (struct st_sgtable *)req->variable;
+
+ ccb->sg_count = nseg;
+ dst->sg_count = cpu_to_le16((u16)nseg);
+ dst->max_sg_count = cpu_to_le16(hba->host->sg_tablesize);
+ dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd));
+
+ table = (struct st_sgitem *)(dst + 1);
+ scsi_for_each_sg(cmd, sg, nseg, i) {
+ table[i].count = cpu_to_le32((u32)sg_dma_len(sg));
+ table[i].addr = cpu_to_le64(sg_dma_address(sg));
+ table[i].ctrl = SG_CF_64B | SG_CF_HOST;
+ }
+ table[--i].ctrl |= SG_CF_EOT;
+ }
+
+ return nseg;
+}
+
+static int stex_ss_map_sg(struct st_hba *hba,
+ struct req_msg *req, struct st_ccb *ccb)
+{
+ struct scsi_cmnd *cmd;
+ struct scatterlist *sg;
+ struct st_sgtable *dst;
+ struct st_ss_sgitem *table;
+ int i, nseg;
+ cmd = ccb->cmd;
nseg = scsi_dma_map(cmd);
- if (nseg < 0)
- return -EIO;
+ BUG_ON(nseg < 0);
if (nseg) {
+ dst = (struct st_sgtable *)req->variable;
+
ccb->sg_count = nseg;
dst->sg_count = cpu_to_le16((u16)nseg);
+ dst->max_sg_count = cpu_to_le16(hba->host->sg_tablesize);
+ dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd));
+ table = (struct st_ss_sgitem *)(dst + 1);
scsi_for_each_sg(cmd, sg, nseg, i) {
- dst->table[i].count = cpu_to_le32((u32)sg_dma_len(sg));
- dst->table[i].addr =
+ table[i].count = cpu_to_le32((u32)sg_dma_len(sg));
+ table[i].addr =
cpu_to_le32(sg_dma_address(sg) & 0xffffffff);
- dst->table[i].addr_hi =
+ table[i].addr_hi =
cpu_to_le32((sg_dma_address(sg) >> 16) >> 16);
- dst->table[i].ctrl = SG_CF_64B | SG_CF_HOST;
}
- dst->table[--i].ctrl |= SG_CF_EOT;
}
- return 0;
+ return nseg;
}
static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
@@ -400,7 +465,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
size_t count = sizeof(struct st_frame);
p = hba->copy_buffer;
- count = scsi_sg_copy_to_buffer(ccb->cmd, p, count);
+ scsi_sg_copy_to_buffer(ccb->cmd, p, count);
memset(p->base, 0, sizeof(u32)*6);
*(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0);
p->rom_addr = 0;
@@ -418,15 +483,13 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
p->subid =
hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device;
- count = scsi_sg_copy_from_buffer(ccb->cmd, p, count);
+ scsi_sg_copy_from_buffer(ccb->cmd, p, count);
}
static void
stex_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag)
{
req->tag = cpu_to_le16(tag);
- req->task_attr = TASK_ATTRIBUTE_SIMPLE;
- req->task_manage = 0; /* not supported yet */
hba->ccb[tag].req = req;
hba->out_req_cnt++;
@@ -436,13 +499,44 @@ stex_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag)
readl(hba->mmio_base + IDBL); /* flush */
}
+static void
+stex_ss_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag)
+{
+ struct scsi_cmnd *cmd;
+ struct st_msg_header *msg_h;
+ dma_addr_t addr;
+
+ req->tag = cpu_to_le16(tag);
+
+ hba->ccb[tag].req = req;
+ hba->out_req_cnt++;
+
+ cmd = hba->ccb[tag].cmd;
+ msg_h = (struct st_msg_header *)req - 1;
+ if (likely(cmd)) {
+ msg_h->channel = (u8)cmd->device->channel;
+ msg_h->timeout = cpu_to_le16(cmd->request->timeout/HZ);
+ }
+ addr = hba->dma_handle + hba->req_head * hba->rq_size;
+ addr += (hba->ccb[tag].sg_count+4)/11;
+ msg_h->handle = cpu_to_le64(addr);
+
+ ++hba->req_head;
+ hba->req_head %= hba->rq_count+1;
+
+ writel((addr >> 16) >> 16, hba->mmio_base + YH2I_REQ_HI);
+ readl(hba->mmio_base + YH2I_REQ_HI); /* flush */
+ writel(addr, hba->mmio_base + YH2I_REQ);
+ readl(hba->mmio_base + YH2I_REQ); /* flush */
+}
+
static int
stex_slave_alloc(struct scsi_device *sdev)
{
/* Cheat: usually extracted from Inquiry data */
sdev->tagged_supported = 1;
- scsi_activate_tcq(sdev, ST_CMD_PER_LUN);
+ scsi_activate_tcq(sdev, sdev->host->can_queue);
return 0;
}
@@ -469,7 +563,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
{
struct st_hba *hba;
struct Scsi_Host *host;
- unsigned int id,lun;
+ unsigned int id, lun;
struct req_msg *req;
u16 tag;
@@ -516,7 +610,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
case INQUIRY:
if (id != host->max_id - 1)
break;
- if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
+ if (!lun && !cmd->device->channel &&
+ (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
scsi_sg_copy_from_buffer(cmd, (void *)console_inq_page,
sizeof(console_inq_page));
cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
@@ -554,7 +649,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
if (unlikely(tag >= host->can_queue))
return SCSI_MLQUEUE_HOST_BUSY;
- req = stex_alloc_req(hba);
+ req = hba->alloc_rq(hba);
req->lun = lun;
req->target = id;
@@ -572,12 +667,13 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
hba->ccb[tag].cmd = cmd;
hba->ccb[tag].sense_bufflen = SCSI_SENSE_BUFFERSIZE;
hba->ccb[tag].sense_buffer = cmd->sense_buffer;
- hba->ccb[tag].req_type = 0;
- if (cmd->sc_data_direction != DMA_NONE)
- stex_map_sg(hba, req, &hba->ccb[tag]);
+ if (!hba->map_sg(hba, req, &hba->ccb[tag])) {
+ hba->ccb[tag].sg_count = 0;
+ memset(&req->variable[0], 0, 8);
+ }
- stex_send_cmd(hba, req, tag);
+ hba->send(hba, req, tag);
return 0;
}
@@ -586,7 +682,7 @@ static void stex_scsi_done(struct st_ccb *ccb)
struct scsi_cmnd *cmd = ccb->cmd;
int result;
- if (ccb->srb_status == SRB_STATUS_SUCCESS || ccb->srb_status == 0) {
+ if (ccb->srb_status == SRB_STATUS_SUCCESS || ccb->srb_status == 0) {
result = ccb->scsi_status;
switch (ccb->scsi_status) {
case SAM_STAT_GOOD:
@@ -626,8 +722,6 @@ static void stex_scsi_done(struct st_ccb *ccb)
static void stex_copy_data(struct st_ccb *ccb,
struct status_msg *resp, unsigned int variable)
{
- size_t count = variable;
-
if (resp->scsi_status != SAM_STAT_GOOD) {
if (ccb->sense_buffer != NULL)
memcpy(ccb->sense_buffer, resp->variable,
@@ -637,17 +731,16 @@ static void stex_copy_data(struct st_ccb *ccb,
if (ccb->cmd == NULL)
return;
- count = scsi_sg_copy_from_buffer(ccb->cmd, resp->variable, count);
+ scsi_sg_copy_from_buffer(ccb->cmd, resp->variable, variable);
}
-static void stex_ys_commands(struct st_hba *hba,
+static void stex_check_cmd(struct st_hba *hba,
struct st_ccb *ccb, struct status_msg *resp)
{
if (ccb->cmd->cmnd[0] == MGT_CMD &&
- resp->scsi_status != SAM_STAT_CHECK_CONDITION) {
+ resp->scsi_status != SAM_STAT_CHECK_CONDITION)
scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) -
le32_to_cpu(*(__le32 *)&resp->variable[0]));
- }
}
static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
@@ -658,12 +751,12 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
unsigned int size;
u16 tag;
- if (!(doorbell & MU_OUTBOUND_DOORBELL_STATUSHEADCHANGED))
+ if (unlikely(!(doorbell & MU_OUTBOUND_DOORBELL_STATUSHEADCHANGED)))
return;
/* status payloads */
hba->status_head = readl(base + OMR1);
- if (unlikely(hba->status_head >= MU_STATUS_COUNT)) {
+ if (unlikely(hba->status_head > hba->sts_count)) {
printk(KERN_WARNING DRV_NAME "(%s): invalid status head\n",
pci_name(hba->pdev));
return;
@@ -693,13 +786,13 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
continue;
}
+ hba->out_req_cnt--;
ccb = &hba->ccb[tag];
- if (hba->wait_ccb == ccb)
+ if (unlikely(hba->wait_ccb == ccb))
hba->wait_ccb = NULL;
if (unlikely(ccb->req == NULL)) {
printk(KERN_WARNING DRV_NAME
"(%s): lagging req\n", pci_name(hba->pdev));
- hba->out_req_cnt--;
continue;
}
@@ -720,7 +813,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
if (likely(ccb->cmd != NULL)) {
if (hba->cardtype == st_yosemite)
- stex_ys_commands(hba, ccb, resp);
+ stex_check_cmd(hba, ccb, resp);
if (unlikely(ccb->cmd->cmnd[0] == PASSTHRU_CMD &&
ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER))
@@ -728,17 +821,8 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
scsi_dma_unmap(ccb->cmd);
stex_scsi_done(ccb);
- hba->out_req_cnt--;
- } else if (ccb->req_type & PASSTHRU_REQ_TYPE) {
- hba->out_req_cnt--;
- if (ccb->req_type & PASSTHRU_REQ_NO_WAKEUP) {
- ccb->req_type = 0;
- continue;
- }
+ } else
ccb->req_type = 0;
- if (waitqueue_active(&hba->waitq))
- wake_up(&hba->waitq);
- }
}
update_status:
@@ -771,7 +855,103 @@ static irqreturn_t stex_intr(int irq, void *__hba)
return IRQ_RETVAL(handled);
}
-static int stex_handshake(struct st_hba *hba)
+static void stex_ss_mu_intr(struct st_hba *hba)
+{
+ struct status_msg *resp;
+ struct st_ccb *ccb;
+ __le32 *scratch;
+ unsigned int size;
+ int count = 0;
+ u32 value;
+ u16 tag;
+
+ if (unlikely(hba->out_req_cnt <= 0 ||
+ hba->mu_status == MU_STATE_RESETTING))
+ return;
+
+ while (count < hba->sts_count) {
+ scratch = hba->scratch + hba->status_tail;
+ value = le32_to_cpu(*scratch);
+ if (unlikely(!(value & SS_STS_NORMAL)))
+ return;
+
+ resp = hba->status_buffer + hba->status_tail;
+ *scratch = 0;
+ ++count;
+ ++hba->status_tail;
+ hba->status_tail %= hba->sts_count+1;
+
+ tag = (u16)value;
+ if (unlikely(tag >= hba->host->can_queue)) {
+ printk(KERN_WARNING DRV_NAME
+ "(%s): invalid tag\n", pci_name(hba->pdev));
+ continue;
+ }
+
+ hba->out_req_cnt--;
+ ccb = &hba->ccb[tag];
+ if (unlikely(hba->wait_ccb == ccb))
+ hba->wait_ccb = NULL;
+ if (unlikely(ccb->req == NULL)) {
+ printk(KERN_WARNING DRV_NAME
+ "(%s): lagging req\n", pci_name(hba->pdev));
+ continue;
+ }
+
+ ccb->req = NULL;
+ if (likely(value & SS_STS_DONE)) { /* normal case */
+ ccb->srb_status = SRB_STATUS_SUCCESS;
+ ccb->scsi_status = SAM_STAT_GOOD;
+ } else {
+ ccb->srb_status = resp->srb_status;
+ ccb->scsi_status = resp->scsi_status;
+ size = resp->payload_sz * sizeof(u32);
+ if (unlikely(size < sizeof(*resp) - STATUS_VAR_LEN ||
+ size > sizeof(*resp))) {
+ printk(KERN_WARNING DRV_NAME
+ "(%s): bad status size\n",
+ pci_name(hba->pdev));
+ } else {
+ size -= sizeof(*resp) - STATUS_VAR_LEN;
+ if (size)
+ stex_copy_data(ccb, resp, size);
+ }
+ if (likely(ccb->cmd != NULL))
+ stex_check_cmd(hba, ccb, resp);
+ }
+
+ if (likely(ccb->cmd != NULL)) {
+ scsi_dma_unmap(ccb->cmd);
+ stex_scsi_done(ccb);
+ } else
+ ccb->req_type = 0;
+ }
+}
+
+static irqreturn_t stex_ss_intr(int irq, void *__hba)
+{
+ struct st_hba *hba = __hba;
+ void __iomem *base = hba->mmio_base;
+ u32 data;
+ unsigned long flags;
+ int handled = 0;
+
+ spin_lock_irqsave(hba->host->host_lock, flags);
+
+ data = readl(base + YI2H_INT);
+ if (data && data != 0xffffffff) {
+ /* clear the interrupt */
+ writel(data, base + YI2H_INT_C);
+ stex_ss_mu_intr(hba);
+ handled = 1;
+ }
+
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+ return IRQ_RETVAL(handled);
+}
+
+static int stex_common_handshake(struct st_hba *hba)
{
void __iomem *base = hba->mmio_base;
struct handshake_frame *h;
@@ -800,26 +980,27 @@ static int stex_handshake(struct st_hba *hba)
data = readl(base + OMR1);
if ((data & 0xffff0000) == MU_HANDSHAKE_SIGNATURE_HALF) {
data &= 0x0000ffff;
- if (hba->host->can_queue > data)
+ if (hba->host->can_queue > data) {
hba->host->can_queue = data;
+ hba->host->cmd_per_lun = data;
+ }
}
- h = (struct handshake_frame *)(hba->dma_mem + MU_REQ_BUFFER_SIZE);
- h->rb_phy = cpu_to_le32(hba->dma_handle);
- h->rb_phy_hi = cpu_to_le32((hba->dma_handle >> 16) >> 16);
- h->req_sz = cpu_to_le16(sizeof(struct req_msg));
- h->req_cnt = cpu_to_le16(MU_REQ_COUNT);
+ h = (struct handshake_frame *)hba->status_buffer;
+ h->rb_phy = cpu_to_le64(hba->dma_handle);
+ h->req_sz = cpu_to_le16(hba->rq_size);
+ h->req_cnt = cpu_to_le16(hba->rq_count+1);
h->status_sz = cpu_to_le16(sizeof(struct status_msg));
- h->status_cnt = cpu_to_le16(MU_STATUS_COUNT);
+ h->status_cnt = cpu_to_le16(hba->sts_count+1);
stex_gettime(&h->hosttime);
h->partner_type = HMU_PARTNER_TYPE;
- if (hba->dma_size > STEX_BUFFER_SIZE) {
- h->extra_offset = cpu_to_le32(STEX_BUFFER_SIZE);
+ if (hba->extra_offset) {
+ h->extra_offset = cpu_to_le32(hba->extra_offset);
h->extra_size = cpu_to_le32(ST_ADDITIONAL_MEM);
} else
h->extra_offset = h->extra_size = 0;
- status_phys = hba->dma_handle + MU_REQ_BUFFER_SIZE;
+ status_phys = hba->dma_handle + (hba->rq_count+1) * hba->rq_size;
writel(status_phys, base + IMR0);
readl(base + IMR0);
writel((status_phys >> 16) >> 16, base + IMR1);
@@ -851,10 +1032,79 @@ static int stex_handshake(struct st_hba *hba)
readl(base + IMR1);
writel(0, base + OMR1);
readl(base + OMR1); /* flush */
- hba->mu_status = MU_STATE_STARTED;
return 0;
}
+static int stex_ss_handshake(struct st_hba *hba)
+{
+ void __iomem *base = hba->mmio_base;
+ struct st_msg_header *msg_h;
+ struct handshake_frame *h;
+ __le32 *scratch = hba->scratch;
+ u32 data;
+ unsigned long before;
+ int ret = 0;
+
+ h = (struct handshake_frame *)(hba->alloc_rq(hba));
+ msg_h = (struct st_msg_header *)h - 1;
+ msg_h->handle = cpu_to_le64(hba->dma_handle);
+ msg_h->flag = SS_HEAD_HANDSHAKE;
+
+ h->rb_phy = cpu_to_le64(hba->dma_handle);
+ h->req_sz = cpu_to_le16(hba->rq_size);
+ h->req_cnt = cpu_to_le16(hba->rq_count+1);
+ h->status_sz = cpu_to_le16(sizeof(struct status_msg));
+ h->status_cnt = cpu_to_le16(hba->sts_count+1);
+ stex_gettime(&h->hosttime);
+ h->partner_type = HMU_PARTNER_TYPE;
+ h->extra_offset = h->extra_size = 0;
+ h->scratch_size = cpu_to_le32((hba->sts_count+1)*sizeof(u32));
+
+ data = readl(base + YINT_EN);
+ data &= ~4;
+ writel(data, base + YINT_EN);
+ writel((hba->dma_handle >> 16) >> 16, base + YH2I_REQ_HI);
+ writel(hba->dma_handle, base + YH2I_REQ);
+
+ scratch = hba->scratch;
+ before = jiffies;
+ while (!(le32_to_cpu(*scratch) & SS_STS_HANDSHAKE)) {
+ if (time_after(jiffies, before + MU_MAX_DELAY * HZ)) {
+ printk(KERN_ERR DRV_NAME
+ "(%s): no signature after handshake frame\n",
+ pci_name(hba->pdev));
+ ret = -1;
+ break;
+ }
+ rmb();
+ msleep(1);
+ }
+
+ *scratch = 0;
+ msg_h->flag = 0;
+ return ret;
+}
+
+static int stex_handshake(struct st_hba *hba)
+{
+ int err;
+ unsigned long flags;
+
+ err = (hba->cardtype == st_yel) ?
+ stex_ss_handshake(hba) : stex_common_handshake(hba);
+ if (err == 0) {
+ spin_lock_irqsave(hba->host->host_lock, flags);
+ hba->req_head = 0;
+ hba->req_tail = 0;
+ hba->status_head = 0;
+ hba->status_tail = 0;
+ hba->out_req_cnt = 0;
+ hba->mu_status = MU_STATE_STARTED;
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
+ }
+ return err;
+}
+
static int stex_abort(struct scsi_cmnd *cmd)
{
struct Scsi_Host *host = cmd->device->host;
@@ -883,15 +1133,23 @@ static int stex_abort(struct scsi_cmnd *cmd)
goto out;
}
- data = readl(base + ODBL);
- if (data == 0 || data == 0xffffffff)
- goto fail_out;
+ if (hba->cardtype == st_yel) {
+ data = readl(base + YI2H_INT);
+ if (data == 0 || data == 0xffffffff)
+ goto fail_out;
- writel(data, base + ODBL);
- readl(base + ODBL); /* flush */
+ writel(data, base + YI2H_INT_C);
+ stex_ss_mu_intr(hba);
+ } else {
+ data = readl(base + ODBL);
+ if (data == 0 || data == 0xffffffff)
+ goto fail_out;
- stex_mu_intr(hba, data);
+ writel(data, base + ODBL);
+ readl(base + ODBL); /* flush */
+ stex_mu_intr(hba, data);
+ }
if (hba->wait_ccb == NULL) {
printk(KERN_WARNING DRV_NAME
"(%s): lost interrupt\n", pci_name(hba->pdev));
@@ -950,8 +1208,8 @@ static void stex_hard_reset(struct st_hba *hba)
static int stex_reset(struct scsi_cmnd *cmd)
{
struct st_hba *hba;
- unsigned long flags;
- unsigned long before;
+ void __iomem *base;
+ unsigned long flags, before;
hba = (struct st_hba *) &cmd->device->host->hostdata[0];
@@ -971,13 +1229,6 @@ static int stex_reset(struct scsi_cmnd *cmd)
pci_name(hba->pdev));
return FAILED;
}
- spin_lock_irqsave(hba->host->host_lock, flags);
- hba->req_head = 0;
- hba->req_tail = 0;
- hba->status_head = 0;
- hba->status_tail = 0;
- hba->out_req_cnt = 0;
- spin_unlock_irqrestore(hba->host->host_lock, flags);
return SUCCESS;
}
@@ -994,7 +1245,23 @@ static int stex_reset(struct scsi_cmnd *cmd)
msleep(1);
}
+ base = hba->mmio_base;
+ writel(0, base + IMR0);
+ readl(base + IMR0);
+ writel(0, base + OMR0);
+ readl(base + OMR0);
+ writel(0, base + IMR1);
+ readl(base + IMR1);
+ writel(0, base + OMR1);
+ readl(base + OMR1); /* flush */
+ spin_lock_irqsave(hba->host->host_lock, flags);
+ hba->req_head = 0;
+ hba->req_tail = 0;
+ hba->status_head = 0;
+ hba->status_tail = 0;
+ hba->out_req_cnt = 0;
hba->mu_status = MU_STATE_STARTED;
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
return SUCCESS;
}
@@ -1028,30 +1295,157 @@ static struct scsi_host_template driver_template = {
.slave_destroy = stex_slave_destroy,
.eh_abort_handler = stex_abort,
.eh_host_reset_handler = stex_reset,
- .can_queue = ST_CAN_QUEUE,
.this_id = -1,
- .sg_tablesize = ST_MAX_SG,
- .cmd_per_lun = ST_CMD_PER_LUN,
+};
+
+static struct pci_device_id stex_pci_tbl[] = {
+ /* st_shasta */
+ { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ st_shasta }, /* SuperTrak EX8350/8300/16350/16300 */
+ { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ st_shasta }, /* SuperTrak EX12350 */
+ { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ st_shasta }, /* SuperTrak EX4350 */
+ { 0x105a, 0xe350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ st_shasta }, /* SuperTrak EX24350 */
+
+ /* st_vsc */
+ { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc },
+
+ /* st_yosemite */
+ { 0x105a, 0x8650, 0x105a, PCI_ANY_ID, 0, 0, st_yosemite },
+
+ /* st_seq */
+ { 0x105a, 0x3360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_seq },
+
+ /* st_yel */
+ { 0x105a, 0x8650, 0x1033, PCI_ANY_ID, 0, 0, st_yel },
+ { 0x105a, 0x8760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yel },
+ { } /* terminate list */
+};
+
+static struct st_card_info stex_card_info[] = {
+ /* st_shasta */
+ {
+ .max_id = 17,
+ .max_lun = 8,
+ .max_channel = 0,
+ .rq_count = 32,
+ .rq_size = 1048,
+ .sts_count = 32,
+ .alloc_rq = stex_alloc_req,
+ .map_sg = stex_map_sg,
+ .send = stex_send_cmd,
+ },
+
+ /* st_vsc */
+ {
+ .max_id = 129,
+ .max_lun = 1,
+ .max_channel = 0,
+ .rq_count = 32,
+ .rq_size = 1048,
+ .sts_count = 32,
+ .alloc_rq = stex_alloc_req,
+ .map_sg = stex_map_sg,
+ .send = stex_send_cmd,
+ },
+
+ /* st_yosemite */
+ {
+ .max_id = 2,
+ .max_lun = 256,
+ .max_channel = 0,
+ .rq_count = 256,
+ .rq_size = 1048,
+ .sts_count = 256,
+ .alloc_rq = stex_alloc_req,
+ .map_sg = stex_map_sg,
+ .send = stex_send_cmd,
+ },
+
+ /* st_seq */
+ {
+ .max_id = 129,
+ .max_lun = 1,
+ .max_channel = 0,
+ .rq_count = 32,
+ .rq_size = 1048,
+ .sts_count = 32,
+ .alloc_rq = stex_alloc_req,
+ .map_sg = stex_map_sg,
+ .send = stex_send_cmd,
+ },
+
+ /* st_yel */
+ {
+ .max_id = 129,
+ .max_lun = 256,
+ .max_channel = 3,
+ .rq_count = 801,
+ .rq_size = 512,
+ .sts_count = 801,
+ .alloc_rq = stex_ss_alloc_req,
+ .map_sg = stex_ss_map_sg,
+ .send = stex_ss_send_cmd,
+ },
};
static int stex_set_dma_mask(struct pci_dev * pdev)
{
int ret;
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)
- && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+ && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
return 0;
- ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (!ret)
- ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
return ret;
}
+static int stex_request_irq(struct st_hba *hba)
+{
+ struct pci_dev *pdev = hba->pdev;
+ int status;
+
+ if (msi) {
+ status = pci_enable_msi(pdev);
+ if (status != 0)
+ printk(KERN_ERR DRV_NAME
+ "(%s): error %d setting up MSI\n",
+ pci_name(pdev), status);
+ else
+ hba->msi_enabled = 1;
+ } else
+ hba->msi_enabled = 0;
+
+ status = request_irq(pdev->irq, hba->cardtype == st_yel ?
+ stex_ss_intr : stex_intr, IRQF_SHARED, DRV_NAME, hba);
+
+ if (status != 0) {
+ if (hba->msi_enabled)
+ pci_disable_msi(pdev);
+ }
+ return status;
+}
+
+static void stex_free_irq(struct st_hba *hba)
+{
+ struct pci_dev *pdev = hba->pdev;
+
+ free_irq(pdev->irq, hba);
+ if (hba->msi_enabled)
+ pci_disable_msi(pdev);
+}
+
static int __devinit
stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct st_hba *hba;
struct Scsi_Host *host;
+ const struct st_card_info *ci = NULL;
+ u32 sts_offset, cp_offset, scratch_offset;
int err;
err = pci_enable_device(pdev);
@@ -1095,10 +1489,17 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
hba->cardtype = (unsigned int) id->driver_data;
- if (hba->cardtype == st_vsc && (pdev->subsystem_device & 1))
- hba->cardtype = st_vsc1;
- hba->dma_size = (hba->cardtype == st_vsc1 || hba->cardtype == st_seq) ?
- (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE);
+ ci = &stex_card_info[hba->cardtype];
+ sts_offset = scratch_offset = (ci->rq_count+1) * ci->rq_size;
+ if (hba->cardtype == st_yel)
+ sts_offset += (ci->sts_count+1) * sizeof(u32);
+ cp_offset = sts_offset + (ci->sts_count+1) * sizeof(struct status_msg);
+ hba->dma_size = cp_offset + sizeof(struct st_frame);
+ if (hba->cardtype == st_seq ||
+ (hba->cardtype == st_vsc && (pdev->subsystem_device & 1))) {
+ hba->extra_offset = hba->dma_size;
+ hba->dma_size += ST_ADDITIONAL_MEM;
+ }
hba->dma_mem = dma_alloc_coherent(&pdev->dev,
hba->dma_size, &hba->dma_handle, GFP_KERNEL);
if (!hba->dma_mem) {
@@ -1108,35 +1509,46 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto out_iounmap;
}
- hba->status_buffer =
- (struct status_msg *)(hba->dma_mem + MU_REQ_BUFFER_SIZE);
- hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE;
+ hba->ccb = kcalloc(ci->rq_count, sizeof(struct st_ccb), GFP_KERNEL);
+ if (!hba->ccb) {
+ err = -ENOMEM;
+ printk(KERN_ERR DRV_NAME "(%s): ccb alloc failed\n",
+ pci_name(pdev));
+ goto out_pci_free;
+ }
+
+ if (hba->cardtype == st_yel)
+ hba->scratch = (__le32 *)(hba->dma_mem + scratch_offset);
+ hba->status_buffer = (struct status_msg *)(hba->dma_mem + sts_offset);
+ hba->copy_buffer = hba->dma_mem + cp_offset;
+ hba->rq_count = ci->rq_count;
+ hba->rq_size = ci->rq_size;
+ hba->sts_count = ci->sts_count;
+ hba->alloc_rq = ci->alloc_rq;
+ hba->map_sg = ci->map_sg;
+ hba->send = ci->send;
hba->mu_status = MU_STATE_STARTING;
- if (hba->cardtype == st_shasta) {
- host->max_lun = 8;
- host->max_id = 16 + 1;
- } else if (hba->cardtype == st_yosemite) {
- host->max_lun = 256;
- host->max_id = 1 + 1;
- } else {
- /* st_vsc , st_vsc1 and st_seq */
- host->max_lun = 1;
- host->max_id = 128 + 1;
- }
- host->max_channel = 0;
+ if (hba->cardtype == st_yel)
+ host->sg_tablesize = 38;
+ else
+ host->sg_tablesize = 32;
+ host->can_queue = ci->rq_count;
+ host->cmd_per_lun = ci->rq_count;
+ host->max_id = ci->max_id;
+ host->max_lun = ci->max_lun;
+ host->max_channel = ci->max_channel;
host->unique_id = host->host_no;
host->max_cmd_len = STEX_CDB_LENGTH;
hba->host = host;
hba->pdev = pdev;
- init_waitqueue_head(&hba->waitq);
- err = request_irq(pdev->irq, stex_intr, IRQF_SHARED, DRV_NAME, hba);
+ err = stex_request_irq(hba);
if (err) {
printk(KERN_ERR DRV_NAME "(%s): request irq failed\n",
pci_name(pdev));
- goto out_pci_free;
+ goto out_ccb_free;
}
err = stex_handshake(hba);
@@ -1164,7 +1576,9 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
out_free_irq:
- free_irq(pdev->irq, hba);
+ stex_free_irq(hba);
+out_ccb_free:
+ kfree(hba->ccb);
out_pci_free:
dma_free_coherent(&pdev->dev, hba->dma_size,
hba->dma_mem, hba->dma_handle);
@@ -1183,15 +1597,20 @@ out_disable:
static void stex_hba_stop(struct st_hba *hba)
{
struct req_msg *req;
+ struct st_msg_header *msg_h;
unsigned long flags;
unsigned long before;
u16 tag = 0;
spin_lock_irqsave(hba->host->host_lock, flags);
- req = stex_alloc_req(hba);
- memset(req->cdb, 0, STEX_CDB_LENGTH);
+ req = hba->alloc_rq(hba);
+ if (hba->cardtype == st_yel) {
+ msg_h = (struct st_msg_header *)req - 1;
+ memset(msg_h, 0, hba->rq_size);
+ } else
+ memset(req, 0, hba->rq_size);
- if (hba->cardtype == st_yosemite) {
+ if (hba->cardtype == st_yosemite || hba->cardtype == st_yel) {
req->cdb[0] = MGT_CMD;
req->cdb[1] = MGT_CMD_SIGNATURE;
req->cdb[2] = CTLR_CONFIG_CMD;
@@ -1206,27 +1625,31 @@ static void stex_hba_stop(struct st_hba *hba)
hba->ccb[tag].sg_count = 0;
hba->ccb[tag].sense_bufflen = 0;
hba->ccb[tag].sense_buffer = NULL;
- hba->ccb[tag].req_type |= PASSTHRU_REQ_TYPE;
+ hba->ccb[tag].req_type = PASSTHRU_REQ_TYPE;
- stex_send_cmd(hba, req, tag);
+ hba->send(hba, req, tag);
spin_unlock_irqrestore(hba->host->host_lock, flags);
before = jiffies;
while (hba->ccb[tag].req_type & PASSTHRU_REQ_TYPE) {
- if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ))
+ if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ)) {
+ hba->ccb[tag].req_type = 0;
return;
- msleep(10);
+ }
+ msleep(1);
}
}
static void stex_hba_free(struct st_hba *hba)
{
- free_irq(hba->pdev->irq, hba);
+ stex_free_irq(hba);
iounmap(hba->mmio_base);
pci_release_regions(hba->pdev);
+ kfree(hba->ccb);
+
dma_free_coherent(&hba->pdev->dev, hba->dma_size,
hba->dma_mem, hba->dma_handle);
}
@@ -1255,27 +1678,6 @@ static void stex_shutdown(struct pci_dev *pdev)
stex_hba_stop(hba);
}
-static struct pci_device_id stex_pci_tbl[] = {
- /* st_shasta */
- { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- st_shasta }, /* SuperTrak EX8350/8300/16350/16300 */
- { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- st_shasta }, /* SuperTrak EX12350 */
- { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- st_shasta }, /* SuperTrak EX4350 */
- { 0x105a, 0xe350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- st_shasta }, /* SuperTrak EX24350 */
-
- /* st_vsc */
- { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc },
-
- /* st_yosemite */
- { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite },
-
- /* st_seq */
- { 0x105a, 0x3360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_seq },
- { } /* terminate list */
-};
MODULE_DEVICE_TABLE(pci, stex_pci_tbl);
static struct pci_driver stex_pci_driver = {
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 23e78201588..583966ec826 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -1349,7 +1349,7 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
if ((SYM_CONF_DMA_ADDRESSING_MODE > 0) && (np->features & FE_DAC) &&
!pci_set_dma_mask(pdev, DMA_DAC_MASK)) {
set_dac(np);
- } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ } else if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printf_warning("%s: No suitable DMA available\n", sym_name(np));
goto attach_failed;
}
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h
index 567fbe0b4f0..b80bf709f10 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.h
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.h
@@ -234,7 +234,7 @@ static inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host)
/*
* Set the status field of a CAM CCB.
*/
-static __inline void
+static inline void
sym_set_cam_status(struct scsi_cmnd *cmd, int status)
{
cmd->result &= ~(0xff << 16);
@@ -244,7 +244,7 @@ sym_set_cam_status(struct scsi_cmnd *cmd, int status)
/*
* Get the status field of a CAM CCB.
*/
-static __inline int
+static inline int
sym_get_cam_status(struct scsi_cmnd *cmd)
{
return host_byte(cmd->result);
@@ -253,7 +253,7 @@ sym_get_cam_status(struct scsi_cmnd *cmd)
/*
* Build CAM result for a successful IO and for a failed IO.
*/
-static __inline void sym_set_cam_result_ok(struct sym_ccb *cp, struct scsi_cmnd *cmd, int resid)
+static inline void sym_set_cam_result_ok(struct sym_ccb *cp, struct scsi_cmnd *cmd, int resid)
{
scsi_set_resid(cmd, resid);
cmd->result = (((DID_OK) << 16) + ((cp->ssss_status) & 0x7f));
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index ccea7db59f4..ffa70d1ed18 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -602,7 +602,7 @@ sym_getsync(struct sym_hcb *np, u_char dt, u_char sfac, u_char *divp, u_char *fa
/*
* Set initial io register bits from burst code.
*/
-static __inline void sym_init_burst(struct sym_hcb *np, u_char bc)
+static inline void sym_init_burst(struct sym_hcb *np, u_char bc)
{
np->rv_ctest4 &= ~0x80;
np->rv_dmode &= ~(0x3 << 6);
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
index 61d28fcfffb..9ebc8706b6b 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h
@@ -1080,23 +1080,23 @@ int sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram
*/
#if SYM_CONF_DMA_ADDRESSING_MODE == 0
-#define DMA_DAC_MASK DMA_32BIT_MASK
+#define DMA_DAC_MASK DMA_BIT_MASK(32)
#define sym_build_sge(np, data, badd, len) \
do { \
(data)->addr = cpu_to_scr(badd); \
(data)->size = cpu_to_scr(len); \
} while (0)
#elif SYM_CONF_DMA_ADDRESSING_MODE == 1
-#define DMA_DAC_MASK DMA_40BIT_MASK
+#define DMA_DAC_MASK DMA_BIT_MASK(40)
#define sym_build_sge(np, data, badd, len) \
do { \
(data)->addr = cpu_to_scr(badd); \
(data)->size = cpu_to_scr((((badd) >> 8) & 0xff000000) + len); \
} while (0)
#elif SYM_CONF_DMA_ADDRESSING_MODE == 2
-#define DMA_DAC_MASK DMA_64BIT_MASK
+#define DMA_DAC_MASK DMA_BIT_MASK(64)
int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s);
-static __inline void
+static inline void
sym_build_sge(struct sym_hcb *np, struct sym_tblmove *data, u64 badd, int len)
{
u32 h = (badd>>32);
@@ -1201,7 +1201,7 @@ dma_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m);
#define sym_m_pool_match(mp_id1, mp_id2) (mp_id1 == mp_id2)
-static __inline void *sym_m_get_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
+static inline void *sym_m_get_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
{
void *vaddr = NULL;
dma_addr_t baddr = 0;
@@ -1215,7 +1215,7 @@ static __inline void *sym_m_get_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
return vaddr;
}
-static __inline void sym_m_free_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
+static inline void sym_m_free_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
{
dma_free_coherent(mp->dev_dmat, SYM_MEM_CLUSTER_SIZE, vbp->vaddr,
vbp->baddr);
diff --git a/drivers/scsi/sym53c8xx_2/sym_malloc.c b/drivers/scsi/sym53c8xx_2/sym_malloc.c
index 92bf9b14a7a..883cac10daf 100644
--- a/drivers/scsi/sym53c8xx_2/sym_malloc.c
+++ b/drivers/scsi/sym53c8xx_2/sym_malloc.c
@@ -262,7 +262,7 @@ static void ___free_dma_mem_cluster(m_pool_p mp, void *m)
#endif
/* Fetch the memory pool for a given pool id (i.e. DMA constraints) */
-static __inline m_pool_p ___get_dma_pool(m_pool_ident_t dev_dmat)
+static inline m_pool_p ___get_dma_pool(m_pool_ident_t dev_dmat)
{
m_pool_p mp;
for (mp = mp0.next;
diff --git a/drivers/scsi/sym53c8xx_2/sym_misc.h b/drivers/scsi/sym53c8xx_2/sym_misc.h
index 430537183c1..96c15145902 100644
--- a/drivers/scsi/sym53c8xx_2/sym_misc.h
+++ b/drivers/scsi/sym53c8xx_2/sym_misc.h
@@ -52,17 +52,17 @@ typedef struct sym_quehead {
(ptr)->flink = (ptr); (ptr)->blink = (ptr); \
} while (0)
-static __inline struct sym_quehead *sym_que_first(struct sym_quehead *head)
+static inline struct sym_quehead *sym_que_first(struct sym_quehead *head)
{
return (head->flink == head) ? 0 : head->flink;
}
-static __inline struct sym_quehead *sym_que_last(struct sym_quehead *head)
+static inline struct sym_quehead *sym_que_last(struct sym_quehead *head)
{
return (head->blink == head) ? 0 : head->blink;
}
-static __inline void __sym_que_add(struct sym_quehead * new,
+static inline void __sym_que_add(struct sym_quehead * new,
struct sym_quehead * blink,
struct sym_quehead * flink)
{
@@ -72,19 +72,19 @@ static __inline void __sym_que_add(struct sym_quehead * new,
blink->flink = new;
}
-static __inline void __sym_que_del(struct sym_quehead * blink,
+static inline void __sym_que_del(struct sym_quehead * blink,
struct sym_quehead * flink)
{
flink->blink = blink;
blink->flink = flink;
}
-static __inline int sym_que_empty(struct sym_quehead *head)
+static inline int sym_que_empty(struct sym_quehead *head)
{
return head->flink == head;
}
-static __inline void sym_que_splice(struct sym_quehead *list,
+static inline void sym_que_splice(struct sym_quehead *list,
struct sym_quehead *head)
{
struct sym_quehead *first = list->flink;
@@ -101,7 +101,7 @@ static __inline void sym_que_splice(struct sym_quehead *list,
}
}
-static __inline void sym_que_move(struct sym_quehead *orig,
+static inline void sym_que_move(struct sym_quehead *orig,
struct sym_quehead *dest)
{
struct sym_quehead *first, *last;
@@ -129,7 +129,7 @@ static __inline void sym_que_move(struct sym_quehead *orig,
#define sym_insque_head(new, head) __sym_que_add(new, head, (head)->flink)
-static __inline struct sym_quehead *sym_remque_head(struct sym_quehead *head)
+static inline struct sym_quehead *sym_remque_head(struct sym_quehead *head)
{
struct sym_quehead *elem = head->flink;
@@ -142,7 +142,7 @@ static __inline struct sym_quehead *sym_remque_head(struct sym_quehead *head)
#define sym_insque_tail(new, head) __sym_que_add(new, (head)->blink, head)
-static __inline struct sym_quehead *sym_remque_tail(struct sym_quehead *head)
+static inline struct sym_quehead *sym_remque_tail(struct sym_quehead *head)
{
struct sym_quehead *elem = head->blink;
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 533f82025ad..7ddff3f5508 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -306,6 +306,63 @@ static void __devexit pci_plx9050_exit(struct pci_dev *dev)
}
}
+#define NI8420_INT_ENABLE_REG 0x38
+#define NI8420_INT_ENABLE_BIT 0x2000
+
+static void __devexit pci_ni8420_exit(struct pci_dev *dev)
+{
+ void __iomem *p;
+ unsigned long base, len;
+ unsigned int bar = 0;
+
+ if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
+ moan_device("no memory in bar", dev);
+ return;
+ }
+
+ base = pci_resource_start(dev, bar);
+ len = pci_resource_len(dev, bar);
+ p = ioremap_nocache(base, len);
+ if (p == NULL)
+ return;
+
+ /* Disable the CPU Interrupt */
+ writel(readl(p + NI8420_INT_ENABLE_REG) & ~(NI8420_INT_ENABLE_BIT),
+ p + NI8420_INT_ENABLE_REG);
+ iounmap(p);
+}
+
+
+/* MITE registers */
+#define MITE_IOWBSR1 0xc4
+#define MITE_IOWCR1 0xf4
+#define MITE_LCIMR1 0x08
+#define MITE_LCIMR2 0x10
+
+#define MITE_LCIMR2_CLR_CPU_IE (1 << 30)
+
+static void __devexit pci_ni8430_exit(struct pci_dev *dev)
+{
+ void __iomem *p;
+ unsigned long base, len;
+ unsigned int bar = 0;
+
+ if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
+ moan_device("no memory in bar", dev);
+ return;
+ }
+
+ base = pci_resource_start(dev, bar);
+ len = pci_resource_len(dev, bar);
+ p = ioremap_nocache(base, len);
+ if (p == NULL)
+ return;
+
+ /* Disable the CPU Interrupt */
+ writel(MITE_LCIMR2_CLR_CPU_IE, p + MITE_LCIMR2);
+ iounmap(p);
+}
+
/* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */
static int
sbs_setup(struct serial_private *priv, const struct pciserial_board *board,
@@ -597,6 +654,108 @@ static int pci_xircom_init(struct pci_dev *dev)
return 0;
}
+static int pci_ni8420_init(struct pci_dev *dev)
+{
+ void __iomem *p;
+ unsigned long base, len;
+ unsigned int bar = 0;
+
+ if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
+ moan_device("no memory in bar", dev);
+ return 0;
+ }
+
+ base = pci_resource_start(dev, bar);
+ len = pci_resource_len(dev, bar);
+ p = ioremap_nocache(base, len);
+ if (p == NULL)
+ return -ENOMEM;
+
+ /* Enable CPU Interrupt */
+ writel(readl(p + NI8420_INT_ENABLE_REG) | NI8420_INT_ENABLE_BIT,
+ p + NI8420_INT_ENABLE_REG);
+
+ iounmap(p);
+ return 0;
+}
+
+#define MITE_IOWBSR1_WSIZE 0xa
+#define MITE_IOWBSR1_WIN_OFFSET 0x800
+#define MITE_IOWBSR1_WENAB (1 << 7)
+#define MITE_LCIMR1_IO_IE_0 (1 << 24)
+#define MITE_LCIMR2_SET_CPU_IE (1 << 31)
+#define MITE_IOWCR1_RAMSEL_MASK 0xfffffffe
+
+static int pci_ni8430_init(struct pci_dev *dev)
+{
+ void __iomem *p;
+ unsigned long base, len;
+ u32 device_window;
+ unsigned int bar = 0;
+
+ if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
+ moan_device("no memory in bar", dev);
+ return 0;
+ }
+
+ base = pci_resource_start(dev, bar);
+ len = pci_resource_len(dev, bar);
+ p = ioremap_nocache(base, len);
+ if (p == NULL)
+ return -ENOMEM;
+
+ /* Set device window address and size in BAR0 */
+ device_window = ((base + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00)
+ | MITE_IOWBSR1_WENAB | MITE_IOWBSR1_WSIZE;
+ writel(device_window, p + MITE_IOWBSR1);
+
+ /* Set window access to go to RAMSEL IO address space */
+ writel((readl(p + MITE_IOWCR1) & MITE_IOWCR1_RAMSEL_MASK),
+ p + MITE_IOWCR1);
+
+ /* Enable IO Bus Interrupt 0 */
+ writel(MITE_LCIMR1_IO_IE_0, p + MITE_LCIMR1);
+
+ /* Enable CPU Interrupt */
+ writel(MITE_LCIMR2_SET_CPU_IE, p + MITE_LCIMR2);
+
+ iounmap(p);
+ return 0;
+}
+
+/* UART Port Control Register */
+#define NI8430_PORTCON 0x0f
+#define NI8430_PORTCON_TXVR_ENABLE (1 << 3)
+
+static int
+pci_ni8430_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_port *port, int idx)
+{
+ void __iomem *p;
+ unsigned long base, len;
+ unsigned int bar, offset = board->first_offset;
+
+ if (idx >= board->num_ports)
+ return 1;
+
+ bar = FL_GET_BASE(board->flags);
+ offset += idx * board->uart_offset;
+
+ base = pci_resource_start(priv->dev, bar);
+ len = pci_resource_len(priv->dev, bar);
+ p = ioremap_nocache(base, len);
+
+ /* enable the transciever */
+ writeb(readb(p + offset + NI8430_PORTCON) | NI8430_PORTCON_TXVR_ENABLE,
+ p + offset + NI8430_PORTCON);
+
+ iounmap(p);
+
+ return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+
static int pci_netmos_init(struct pci_dev *dev)
{
/* subdevice 0x00PS means <P> parallel, <S> serial */
@@ -913,6 +1072,126 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.exit = __devexit_p(pci_ite887x_exit),
},
/*
+ * National Instruments
+ */
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI23216,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2328,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2324,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2322,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2324I,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2322I,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8420_23216,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8420_2328,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8420_2324,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8420_2322,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8422_2324,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8422_2322,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8430_init,
+ .setup = pci_ni8430_setup,
+ .exit = __devexit_p(pci_ni8430_exit),
+ },
+ /*
* Panacom
*/
{
@@ -1216,6 +1495,7 @@ enum pci_board_num_t {
pbn_b1_2_115200,
pbn_b1_4_115200,
pbn_b1_8_115200,
+ pbn_b1_16_115200,
pbn_b1_1_921600,
pbn_b1_2_921600,
@@ -1225,6 +1505,9 @@ enum pci_board_num_t {
pbn_b1_2_1250000,
pbn_b1_bt_1_115200,
+ pbn_b1_bt_2_115200,
+ pbn_b1_bt_4_115200,
+
pbn_b1_bt_2_921600,
pbn_b1_1_1382400,
@@ -1280,6 +1563,10 @@ enum pci_board_num_t {
pbn_exar_XR17C154,
pbn_exar_XR17C158,
pbn_pasemi_1682M,
+ pbn_ni8430_2,
+ pbn_ni8430_4,
+ pbn_ni8430_8,
+ pbn_ni8430_16,
};
/*
@@ -1487,6 +1774,12 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.base_baud = 115200,
.uart_offset = 8,
},
+ [pbn_b1_16_115200] = {
+ .flags = FL_BASE1,
+ .num_ports = 16,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
[pbn_b1_1_921600] = {
.flags = FL_BASE1,
@@ -1525,6 +1818,18 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.base_baud = 115200,
.uart_offset = 8,
},
+ [pbn_b1_bt_2_115200] = {
+ .flags = FL_BASE1|FL_BASE_BARS,
+ .num_ports = 2,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b1_bt_4_115200] = {
+ .flags = FL_BASE1|FL_BASE_BARS,
+ .num_ports = 4,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
[pbn_b1_bt_2_921600] = {
.flags = FL_BASE1|FL_BASE_BARS,
@@ -1850,6 +2155,37 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.num_ports = 1,
.base_baud = 8333333,
},
+ /*
+ * National Instruments 843x
+ */
+ [pbn_ni8430_16] = {
+ .flags = FL_BASE0,
+ .num_ports = 16,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8430_8] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8430_4] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8430_2] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
};
static const struct pci_device_id softmodem_blacklist[] = {
@@ -3052,6 +3388,82 @@ static struct pci_device_id serial_pci_tbl[] = {
pbn_pasemi_1682M },
/*
+ * National Instruments
+ */
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI23216,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_16_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2328,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_8_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_4_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_2_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324I,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_4_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322I,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_2_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_23216,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_16_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2328,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_8_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_4_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_2_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_4_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_2_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_4 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_4 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2328,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_8 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2328,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_8 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_23216,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_16 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_23216,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_16 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_4 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_4 },
+
+ /*
* ADDI-DATA GmbH communication cards <info@addi-data.com>
*/
{ PCI_VENDOR_ID_ADDIDATA,
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index bbcfc26a3b6..d71dfe39894 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -333,6 +333,10 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "WACF006", 0 },
{ "WACF007", 0 },
{ "WACF008", 0 },
+ { "WACF009", 0 },
+ { "WACF00A", 0 },
+ { "WACF00B", 0 },
+ { "WACF00C", 0 },
/* Compaq touchscreen */
{ "FPI2002", 0 },
/* Fujitsu Stylistic touchscreens */
@@ -346,8 +350,9 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "FUJ02B8", 0 },
{ "FUJ02B9", 0 },
{ "FUJ02BC", 0 },
- /* Fujitsu Wacom Tablet PC devices */
+ /* Fujitsu Wacom Tablet PC device */
{ "FUJ02E5", 0 },
+ /* Fujitsu P-series tablet PC device */
{ "FUJ02E6", 0 },
/*
* LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 9be11b0963f..343e3a35b6a 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -533,6 +533,13 @@ config SERIAL_S3C6400
Serial port support for the Samsung S3C6400 and S3C6410
SoCs
+config SERIAL_MAX3100
+ tristate "MAX3100 support"
+ depends on SPI
+ select SERIAL_CORE
+ help
+ MAX3100 chip support
+
config SERIAL_DZ
bool "DECstation DZ serial driver"
depends on MACH_DECSTATION && 32BIT
@@ -700,7 +707,7 @@ choice
config SERIAL_BFIN_DMA
bool "DMA mode"
- depends on !DMA_UNCACHED_NONE && !KGDB_UART
+ depends on !DMA_UNCACHED_NONE && KGDB_SERIAL_CONSOLE=n
help
This driver works under DMA mode. If this option is selected, the
blackfin simple dma driver is also enabled.
@@ -727,19 +734,19 @@ config BFIN_UART0_CTSRTS
config UART0_CTS_PIN
int "UART0 CTS pin"
- depends on BFIN_UART0_CTSRTS
+ depends on BFIN_UART0_CTSRTS && !BF548
default 23
help
The default pin is GPIO_GP7.
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
config UART0_RTS_PIN
int "UART0 RTS pin"
- depends on BFIN_UART0_CTSRTS
+ depends on BFIN_UART0_CTSRTS && !BF548
default 22
help
The default pin is GPIO_GP6.
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
config SERIAL_BFIN_UART1
bool "Enable UART1"
@@ -756,21 +763,21 @@ config BFIN_UART1_CTSRTS
config UART1_CTS_PIN
int "UART1 CTS pin"
- depends on BFIN_UART1_CTSRTS && !BF54x
+ depends on BFIN_UART1_CTSRTS && !BF548
default -1
help
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
config UART1_RTS_PIN
int "UART1 RTS pin"
- depends on BFIN_UART1_CTSRTS && !BF54x
+ depends on BFIN_UART1_CTSRTS && !BF548
default -1
help
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
config SERIAL_BFIN_UART2
bool "Enable UART2"
- depends on SERIAL_BFIN && (BF54x)
+ depends on SERIAL_BFIN && (BF54x || BF538 || BF539)
help
Enable UART2
@@ -783,17 +790,17 @@ config BFIN_UART2_CTSRTS
config UART2_CTS_PIN
int "UART2 CTS pin"
- depends on BFIN_UART2_CTSRTS
+ depends on BFIN_UART2_CTSRTS && !BF548
default -1
help
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
config UART2_RTS_PIN
int "UART2 RTS pin"
- depends on BFIN_UART2_CTSRTS
+ depends on BFIN_UART2_CTSRTS && !BF548
default -1
help
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
config SERIAL_BFIN_UART3
bool "Enable UART3"
@@ -808,6 +815,20 @@ config BFIN_UART3_CTSRTS
Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
signal.
+config UART3_CTS_PIN
+ int "UART3 CTS pin"
+ depends on BFIN_UART3_CTSRTS && !BF548
+ default -1
+ help
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
+
+config UART3_RTS_PIN
+ int "UART3 RTS pin"
+ depends on BFIN_UART3_CTSRTS && !BF548
+ default -1
+ help
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
+
config SERIAL_IMX
bool "IMX serial port support"
depends on ARM && (ARCH_IMX || ARCH_MXC)
@@ -833,7 +854,7 @@ config SERIAL_IMX_CONSOLE
config SERIAL_UARTLITE
tristate "Xilinx uartlite serial port support"
- depends on PPC32
+ depends on PPC32 || MICROBLAZE
select SERIAL_CORE
help
Say Y here if you want to use the Xilinx uartlite serial controller.
@@ -1319,7 +1340,7 @@ config SERIAL_NETX_CONSOLE
config SERIAL_OF_PLATFORM
tristate "Serial port on Open Firmware platform bus"
- depends on PPC_OF
+ depends on PPC_OF || MICROBLAZE
depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL
help
If you have a PowerPC based system that has serial ports
@@ -1374,7 +1395,7 @@ config SERIAL_BFIN_SPORT
depends on BLACKFIN && EXPERIMENTAL
select SERIAL_CORE
help
- Enble support SPORT emulate UART on Blackfin series.
+ Enable SPORT emulate UART on Blackfin series.
To compile this driver as a module, choose M here: the
module will be called bfin_sport_uart.
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 8844c0a0392..d438eb2a73d 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o
obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o
obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
+obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
obj-$(CONFIG_SERIAL_MUX) += mux.o
obj-$(CONFIG_SERIAL_68328) += 68328serial.o
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 8f58f7ff0dd..b3497d7e535 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -1020,7 +1020,8 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
/* Get current mode register */
mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL
- | ATMEL_US_NBSTOP | ATMEL_US_PAR);
+ | ATMEL_US_NBSTOP | ATMEL_US_PAR
+ | ATMEL_US_USMODE);
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
quot = uart_get_divisor(port, baud);
@@ -1065,6 +1066,12 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
} else
mode |= ATMEL_US_PAR_NONE;
+ /* hardware handshake (RTS/CTS) */
+ if (termios->c_cflag & CRTSCTS)
+ mode |= ATMEL_US_USMODE_HWHS;
+ else
+ mode |= ATMEL_US_USMODE_NORMAL;
+
spin_lock_irqsave(&port->lock, flags);
port->read_status_mask = ATMEL_US_OVRE;
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 318d69dce8e..18ba812a4f8 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -63,7 +63,6 @@ static int kgdboc_break_enabled;
#define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT)
#define DMA_RX_FLUSH_JIFFIES (HZ / 50)
-#define CTS_CHECK_JIFFIES (HZ / 50)
#ifdef CONFIG_SERIAL_BFIN_DMA
static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart);
@@ -71,10 +70,65 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart);
static void bfin_serial_tx_chars(struct bfin_serial_port *uart);
#endif
-static void bfin_serial_mctrl_check(struct bfin_serial_port *uart);
-
static void bfin_serial_reset_irda(struct uart_port *port);
+#if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \
+ defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS)
+static unsigned int bfin_serial_get_mctrl(struct uart_port *port)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+ if (uart->cts_pin < 0)
+ return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+
+ /* CTS PIN is negative assertive. */
+ if (UART_GET_CTS(uart))
+ return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+ else
+ return TIOCM_DSR | TIOCM_CAR;
+}
+
+static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+ if (uart->rts_pin < 0)
+ return;
+
+ /* RTS PIN is negative assertive. */
+ if (mctrl & TIOCM_RTS)
+ UART_ENABLE_RTS(uart);
+ else
+ UART_DISABLE_RTS(uart);
+}
+
+/*
+ * Handle any change of modem status signal.
+ */
+static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id)
+{
+ struct bfin_serial_port *uart = dev_id;
+ unsigned int status;
+
+ status = bfin_serial_get_mctrl(&uart->port);
+ uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ uart->scts = 1;
+ UART_CLEAR_SCTS(uart);
+ UART_CLEAR_IER(uart, EDSSI);
+#endif
+
+ return IRQ_HANDLED;
+}
+#else
+static unsigned int bfin_serial_get_mctrl(struct uart_port *port)
+{
+ return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+}
+
+static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+}
+#endif
+
/*
* interrupts are disabled on entry
*/
@@ -111,6 +165,13 @@ static void bfin_serial_start_tx(struct uart_port *port)
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
struct tty_struct *tty = uart->port.info->port.tty;
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) {
+ uart->scts = 0;
+ uart_handle_cts_change(&uart->port, uart->scts);
+ }
+#endif
+
/*
* To avoid losting RX interrupt, we reset IR function
* before sending data.
@@ -174,10 +235,10 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
return;
}
- if (!uart->port.info || !uart->port.info->tty)
+ if (!uart->port.info || !uart->port.info->port.tty)
return;
#endif
- tty = uart->port.info->tty;
+ tty = uart->port.info->port.tty;
if (ANOMALY_05000363) {
/* The BF533 (and BF561) family of processors have a nice anomaly
@@ -264,12 +325,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
{
struct circ_buf *xmit = &uart->port.info->xmit;
- /*
- * Check the modem control lines before
- * transmitting anything.
- */
- bfin_serial_mctrl_check(uart);
-
if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
#ifdef CONFIG_BF54x
/* Clear TFI bit */
@@ -312,6 +367,12 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id)
{
struct bfin_serial_port *uart = dev_id;
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) {
+ uart->scts = 0;
+ uart_handle_cts_change(&uart->port, uart->scts);
+ }
+#endif
spin_lock(&uart->port.lock);
if (UART_GET_LSR(uart) & THRE)
bfin_serial_tx_chars(uart);
@@ -328,12 +389,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
uart->tx_done = 0;
- /*
- * Check the modem control lines before
- * transmitting anything.
- */
- bfin_serial_mctrl_check(uart);
-
if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
uart->tx_count = 0;
uart->tx_done = 1;
@@ -401,9 +456,11 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
else
flg = TTY_NORMAL;
- for (i = uart->rx_dma_buf.tail; i != uart->rx_dma_buf.head; i++) {
+ for (i = uart->rx_dma_buf.tail; ; i++) {
if (i >= UART_XMIT_SIZE)
i = 0;
+ if (i == uart->rx_dma_buf.head)
+ break;
if (!uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i]))
uart_insert_char(&uart->port, status, OE,
uart->rx_dma_buf.buf[i], flg);
@@ -415,7 +472,8 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
{
- int x_pos, pos, flags;
+ int x_pos, pos;
+ unsigned long flags;
spin_lock_irqsave(&uart->port.lock, flags);
@@ -445,6 +503,13 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
struct bfin_serial_port *uart = dev_id;
struct circ_buf *xmit = &uart->port.info->xmit;
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) {
+ uart->scts = 0;
+ uart_handle_cts_change(&uart->port, uart->scts);
+ }
+#endif
+
spin_lock(&uart->port.lock);
if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) {
disable_dma(uart->tx_dma_channel);
@@ -493,61 +558,6 @@ static unsigned int bfin_serial_tx_empty(struct uart_port *port)
return 0;
}
-static unsigned int bfin_serial_get_mctrl(struct uart_port *port)
-{
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
- if (uart->cts_pin < 0)
- return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
-
- if (UART_GET_CTS(uart))
- return TIOCM_DSR | TIOCM_CAR;
- else
-#endif
- return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
-}
-
-static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
-{
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
- if (uart->rts_pin < 0)
- return;
-
- if (mctrl & TIOCM_RTS)
- UART_CLEAR_RTS(uart);
- else
- UART_SET_RTS(uart);
-#endif
-}
-
-/*
- * Handle any change of modem status signal since we were last called.
- */
-static void bfin_serial_mctrl_check(struct bfin_serial_port *uart)
-{
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- unsigned int status;
- struct uart_info *info = uart->port.info;
- struct tty_struct *tty = info->port.tty;
-
- status = bfin_serial_get_mctrl(&uart->port);
- uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
- if (!(status & TIOCM_CTS)) {
- tty->hw_stopped = 1;
- uart->cts_timer.data = (unsigned long)(uart);
- uart->cts_timer.function = (void *)bfin_serial_mctrl_check;
- uart->cts_timer.expires = jiffies + CTS_CHECK_JIFFIES;
- add_timer(&(uart->cts_timer));
- } else {
- tty->hw_stopped = 0;
- }
-#endif
-}
-
-/*
- * Interrupts are always disabled.
- */
static void bfin_serial_break_ctl(struct uart_port *port, int break_state)
{
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
@@ -603,7 +613,7 @@ static int bfin_serial_startup(struct uart_port *port)
uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES;
add_timer(&(uart->rx_dma_timer));
#else
-#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
+# if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
if (kgdboc_port_line == uart->port.line && kgdboc_break_enabled)
kgdboc_break_enabled = 0;
@@ -658,11 +668,50 @@ static int bfin_serial_startup(struct uart_port *port)
}
}
# endif
-#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
+# if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
}
# endif
#endif
+
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ if (uart->cts_pin >= 0) {
+ if (request_irq(gpio_to_irq(uart->cts_pin),
+ bfin_serial_mctrl_cts_int,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
+ IRQF_DISABLED, "BFIN_UART_CTS", uart)) {
+ uart->cts_pin = -1;
+ pr_info("Unable to attach BlackFin UART CTS interrupt.\
+ So, disable it.\n");
+ }
+ }
+ if (uart->rts_pin >= 0) {
+ gpio_request(uart->rts_pin, DRIVER_NAME);
+ gpio_direction_output(uart->rts_pin, 0);
+ }
+#endif
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ if (request_irq(uart->status_irq,
+ bfin_serial_mctrl_cts_int,
+ IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) {
+ pr_info("Unable to attach BlackFin UART Modem \
+ Status interrupt.\n");
+ }
+
+ if (uart->cts_pin >= 0) {
+ gpio_request(uart->cts_pin, DRIVER_NAME);
+ gpio_direction_output(uart->cts_pin, 1);
+ }
+ if (uart->rts_pin >= 0) {
+ gpio_request(uart->rts_pin, DRIVER_NAME);
+ gpio_direction_output(uart->rts_pin, 0);
+ }
+
+ /* CTS RTS PINs are negative assertive. */
+ UART_PUT_MCR(uart, ACTS);
+ UART_SET_IER(uart, EDSSI);
+#endif
+
UART_SET_IER(uart, ERBFI);
return 0;
}
@@ -696,6 +745,21 @@ static void bfin_serial_shutdown(struct uart_port *port)
free_irq(uart->port.irq, uart);
free_irq(uart->port.irq+1, uart);
#endif
+
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ if (uart->cts_pin >= 0)
+ free_irq(gpio_to_irq(uart->cts_pin), uart);
+ if (uart->rts_pin >= 0)
+ gpio_free(uart->rts_pin);
+#endif
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ if (uart->cts_pin >= 0)
+ gpio_free(uart->cts_pin);
+ if (uart->rts_pin >= 0)
+ gpio_free(uart->rts_pin);
+ if (UART_GET_IER(uart) && EDSSI)
+ free_irq(uart->status_irq, uart);
+#endif
}
static void
@@ -757,7 +821,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
}
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
- quot = uart_get_divisor(port, baud);
+ quot = uart_get_divisor(port, baud) - ANOMALY_05000230;
spin_lock_irqsave(&uart->port.lock, flags);
UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15);
@@ -861,6 +925,20 @@ static void bfin_serial_set_ldisc(struct uart_port *port)
}
}
+static void bfin_serial_reset_irda(struct uart_port *port)
+{
+ int line = port->line;
+ unsigned short val;
+
+ val = UART_GET_GCTL(&bfin_serial_ports[line]);
+ val &= ~(IREN | RPOLC);
+ UART_PUT_GCTL(&bfin_serial_ports[line], val);
+ SSYNC();
+ val |= (IREN | RPOLC);
+ UART_PUT_GCTL(&bfin_serial_ports[line], val);
+ SSYNC();
+}
+
#ifdef CONFIG_CONSOLE_POLL
static void bfin_serial_poll_put_char(struct uart_port *port, unsigned char chr)
{
@@ -906,20 +984,6 @@ static int bfin_kgdboc_port_startup(struct uart_port *port)
}
#endif
-static void bfin_serial_reset_irda(struct uart_port *port)
-{
- int line = port->line;
- unsigned short val;
-
- val = UART_GET_GCTL(&bfin_serial_ports[line]);
- val &= ~(IREN | RPOLC);
- UART_PUT_GCTL(&bfin_serial_ports[line], val);
- SSYNC();
- val |= (IREN | RPOLC);
- UART_PUT_GCTL(&bfin_serial_ports[line], val);
- SSYNC();
-}
-
static struct uart_ops bfin_serial_pops = {
.tx_empty = bfin_serial_tx_empty,
.set_mctrl = bfin_serial_set_mctrl,
@@ -949,6 +1013,39 @@ static struct uart_ops bfin_serial_pops = {
#endif
};
+static void __init bfin_serial_hw_init(void)
+{
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ peripheral_request(P_UART0_TX, DRIVER_NAME);
+ peripheral_request(P_UART0_RX, DRIVER_NAME);
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ peripheral_request(P_UART1_TX, DRIVER_NAME);
+ peripheral_request(P_UART1_RX, DRIVER_NAME);
+
+# if defined(CONFIG_BFIN_UART1_CTSRTS) && defined(CONFIG_BF54x)
+ peripheral_request(P_UART1_RTS, DRIVER_NAME);
+ peripheral_request(P_UART1_CTS, DRIVER_NAME);
+# endif
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART2
+ peripheral_request(P_UART2_TX, DRIVER_NAME);
+ peripheral_request(P_UART2_RX, DRIVER_NAME);
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART3
+ peripheral_request(P_UART3_TX, DRIVER_NAME);
+ peripheral_request(P_UART3_RX, DRIVER_NAME);
+
+# if defined(CONFIG_BFIN_UART3_CTSRTS) && defined(CONFIG_BF54x)
+ peripheral_request(P_UART3_RTS, DRIVER_NAME);
+ peripheral_request(P_UART3_CTS, DRIVER_NAME);
+# endif
+#endif
+}
+
static void __init bfin_serial_init_ports(void)
{
static int first = 1;
@@ -958,6 +1055,8 @@ static void __init bfin_serial_init_ports(void)
return;
first = 0;
+ bfin_serial_hw_init();
+
for (i = 0; i < nr_active_ports; i++) {
bfin_serial_ports[i].port.uartclk = get_sclk();
bfin_serial_ports[i].port.fifosize = BFIN_UART_TX_FIFO_SIZE;
@@ -970,6 +1069,8 @@ static void __init bfin_serial_init_ports(void)
bfin_serial_resource[i].uart_base_addr;
bfin_serial_ports[i].port.irq =
bfin_serial_resource[i].uart_irq;
+ bfin_serial_ports[i].status_irq =
+ bfin_serial_resource[i].uart_status_irq;
bfin_serial_ports[i].port.flags = UPF_BOOT_AUTOCONF;
#ifdef CONFIG_SERIAL_BFIN_DMA
bfin_serial_ports[i].tx_done = 1;
@@ -980,16 +1081,14 @@ static void __init bfin_serial_init_ports(void)
bfin_serial_resource[i].uart_rx_dma_channel;
init_timer(&(bfin_serial_ports[i].rx_dma_timer));
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- init_timer(&(bfin_serial_ports[i].cts_timer));
+#if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \
+ defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS)
bfin_serial_ports[i].cts_pin =
bfin_serial_resource[i].uart_cts_pin;
bfin_serial_ports[i].rts_pin =
bfin_serial_resource[i].uart_rts_pin;
#endif
- bfin_serial_hw_init(&bfin_serial_ports[i]);
}
-
}
#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
@@ -1046,7 +1145,8 @@ bfin_serial_console_setup(struct console *co, char *options)
int baud = 57600;
int bits = 8;
int parity = 'n';
-# ifdef CONFIG_SERIAL_BFIN_CTSRTS
+# if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \
+ defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS)
int flow = 'r';
# else
int flow = 'n';
@@ -1088,7 +1188,7 @@ static void
bfin_serial_console_write(struct console *co, const char *s, unsigned int count)
{
struct bfin_serial_port *uart = &bfin_serial_ports[co->index];
- int flags = 0;
+ unsigned long flags;
spin_lock_irqsave(&uart->port.lock, flags);
uart_console_write(&uart->port, s, count, bfin_serial_console_putchar);
@@ -1243,7 +1343,8 @@ static int bfin_serial_remove(struct platform_device *dev)
continue;
uart_remove_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port);
bfin_serial_ports[i].port.dev = NULL;
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+#if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \
+ defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS)
gpio_free(bfin_serial_ports[i].cts_pin);
gpio_free(bfin_serial_ports[i].rts_pin);
#endif
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 5c6ef51da27..f8df0681e16 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -1106,6 +1106,10 @@ static int cpm_uart_init_port(struct device_node *np,
for (i = 0; i < NUM_GPIOS; i++)
pinfo->gpios[i] = of_get_gpio(np, i);
+#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
+ udbg_putc = NULL;
+#endif
+
return cpm_uart_request_port(&pinfo->port);
out_pram:
@@ -1255,10 +1259,6 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
baud = 9600;
}
-#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
- udbg_putc = NULL;
-#endif
-
if (IS_SMC(pinfo)) {
out_be16(&pinfo->smcup->smc_brkcr, 0);
cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
@@ -1339,13 +1339,13 @@ static int __devinit cpm_uart_probe(struct of_device *ofdev,
dev_set_drvdata(&ofdev->dev, pinfo);
+ /* initialize the device pointer for the port */
+ pinfo->port.dev = &ofdev->dev;
+
ret = cpm_uart_init_port(ofdev->node, pinfo);
if (ret)
return ret;
- /* initialize the device pointer for the port */
- pinfo->port.dev = &ofdev->dev;
-
return uart_add_one_port(&cpm_reg, &pinfo->port);
}
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index e642c22c80e..7ba7d70f04d 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -1391,7 +1391,7 @@ static inline void e100_disable_rx_irq(struct e100_serial *info)
#if defined(CONFIG_ETRAX_RS485)
/* Enable RS-485 mode on selected port. This is UGLY. */
static int
-e100_enable_rs485(struct tty_struct *tty,struct rs485_control *r)
+e100_enable_rs485(struct tty_struct *tty, struct serial_rs485 *r)
{
struct e100_serial * info = (struct e100_serial *)tty->driver_data;
@@ -1409,13 +1409,11 @@ e100_enable_rs485(struct tty_struct *tty,struct rs485_control *r)
CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 1);
#endif
- info->rs485.rts_on_send = 0x01 & r->rts_on_send;
- info->rs485.rts_after_sent = 0x01 & r->rts_after_sent;
+ info->rs485.flags = r->flags;
if (r->delay_rts_before_send >= 1000)
info->rs485.delay_rts_before_send = 1000;
else
info->rs485.delay_rts_before_send = r->delay_rts_before_send;
- info->rs485.enabled = r->enabled;
/* printk("rts: on send = %i, after = %i, enabled = %i",
info->rs485.rts_on_send,
info->rs485.rts_after_sent,
@@ -1430,17 +1428,18 @@ e100_write_rs485(struct tty_struct *tty,
const unsigned char *buf, int count)
{
struct e100_serial * info = (struct e100_serial *)tty->driver_data;
- int old_enabled = info->rs485.enabled;
+ int old_value = (info->rs485.flags) & SER_RS485_ENABLED;
/* rs485 is always implicitly enabled if we're using the ioctl()
- * but it doesn't have to be set in the rs485_control
+ * but it doesn't have to be set in the serial_rs485
* (to be backward compatible with old apps)
* So we store, set and restore it.
*/
- info->rs485.enabled = 1;
+ info->rs485.flags |= SER_RS485_ENABLED;
/* rs_write now deals with RS485 if enabled */
count = rs_write(tty, buf, count);
- info->rs485.enabled = old_enabled;
+ if (!old_value)
+ info->rs485.flags &= ~(SER_RS485_ENABLED);
return count;
}
@@ -1451,7 +1450,7 @@ static void rs485_toggle_rts_timer_function(unsigned long data)
struct e100_serial *info = (struct e100_serial *)data;
fast_timers_rs485[info->line].function = NULL;
- e100_rts(info, info->rs485.rts_after_sent);
+ e100_rts(info, (info->rs485.flags & SER_RS485_RTS_AFTER_SEND));
#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
e100_enable_rx(info);
e100_enable_rx_irq(info);
@@ -1647,7 +1646,7 @@ transmit_chars_dma(struct e100_serial *info)
info->tr_running = 0;
#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER)
- if (info->rs485.enabled) {
+ if (info->rs485.flags & SER_RS485_ENABLED) {
/* Set a short timer to toggle RTS */
start_one_shot_timer(&fast_timers_rs485[info->line],
rs485_toggle_rts_timer_function,
@@ -2577,7 +2576,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
info->icount.tx++;
if (info->xmit.head == info->xmit.tail) {
#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER)
- if (info->rs485.enabled) {
+ if (info->rs485.flags & SER_RS485_ENABLED) {
/* Set a short timer to toggle RTS */
start_one_shot_timer(&fast_timers_rs485[info->line],
rs485_toggle_rts_timer_function,
@@ -3218,7 +3217,7 @@ rs_write(struct tty_struct *tty,
#if defined(CONFIG_ETRAX_RS485)
struct e100_serial *info = (struct e100_serial *)tty->driver_data;
- if (info->rs485.enabled)
+ if (info->rs485.flags & SER_RS485_ENABLED)
{
/* If we are in RS-485 mode, we need to toggle RTS and disable
* the receiver before initiating a DMA transfer
@@ -3228,7 +3227,7 @@ rs_write(struct tty_struct *tty,
fast_timers_rs485[info->line].function = NULL;
del_fast_timer(&fast_timers_rs485[info->line]);
#endif
- e100_rts(info, info->rs485.rts_on_send);
+ e100_rts(info, (info->rs485.flags & SER_RS485_RTS_ON_SEND));
#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
e100_disable_rx(info);
e100_enable_rx_irq(info);
@@ -3242,7 +3241,7 @@ rs_write(struct tty_struct *tty,
count = rs_raw_write(tty, buf, count);
#if defined(CONFIG_ETRAX_RS485)
- if (info->rs485.enabled)
+ if (info->rs485.flags & SER_RS485_ENABLED)
{
unsigned int val;
/* If we are in RS-485 mode the following has to be done:
@@ -3263,7 +3262,7 @@ rs_write(struct tty_struct *tty,
get_lsr_info(info, &val);
}while (!(val & TIOCSER_TEMT));
- e100_rts(info, info->rs485.rts_after_sent);
+ e100_rts(info, (info->rs485.flags & SER_RS485_RTS_AFTER_SEND));
#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
e100_enable_rx(info);
@@ -3678,14 +3677,52 @@ rs_ioctl(struct tty_struct *tty, struct file * file,
#if defined(CONFIG_ETRAX_RS485)
case TIOCSERSETRS485:
{
+ /* In this ioctl we still use the old structure
+ * rs485_control for backward compatibility
+ * (if we use serial_rs485, then old user-level code
+ * wouldn't work anymore...).
+ * The use of this ioctl is deprecated: use TIOCSRS485
+ * instead.*/
struct rs485_control rs485ctrl;
+ struct serial_rs485 rs485data;
+ printk(KERN_DEBUG "The use of this ioctl is deprecated. Use TIOCSRS485 instead\n");
if (copy_from_user(&rs485ctrl, (struct rs485_control *)arg,
sizeof(rs485ctrl)))
return -EFAULT;
- return e100_enable_rs485(tty, &rs485ctrl);
+ rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send;
+ rs485data.flags = 0;
+ if (rs485ctrl.enabled)
+ rs485data.flags |= SER_RS485_ENABLED;
+ else
+ rs485data.flags &= ~(SER_RS485_ENABLED);
+
+ if (rs485ctrl.rts_on_send)
+ rs485data.flags |= SER_RS485_RTS_ON_SEND;
+ else
+ rs485data.flags &= ~(SER_RS485_RTS_ON_SEND);
+
+ if (rs485ctrl.rts_after_sent)
+ rs485data.flags |= SER_RS485_RTS_AFTER_SEND;
+ else
+ rs485data.flags &= ~(SER_RS485_RTS_AFTER_SEND);
+
+ return e100_enable_rs485(tty, &rs485data);
}
+ case TIOCSRS485:
+ {
+ /* This is the new version of TIOCSRS485, with new
+ * data structure serial_rs485 */
+ struct serial_rs485 rs485data;
+ if (copy_from_user(&rs485data, (struct rs485_control *)arg,
+ sizeof(rs485data)))
+ return -EFAULT;
+
+ return e100_enable_rs485(tty, &rs485data);
+ }
+
+
case TIOCSERWRRS485:
{
struct rs485_write rs485wr;
@@ -3827,8 +3864,8 @@ rs_close(struct tty_struct *tty, struct file * filp)
/* port closed */
#if defined(CONFIG_ETRAX_RS485)
- if (info->rs485.enabled) {
- info->rs485.enabled = 0;
+ if (info->rs485.flags & SER_RS485_ENABLED) {
+ info->rs485.flags &= ~(SER_RS485_ENABLED);
#if defined(CONFIG_ETRAX_RS485_ON_PA)
*R_PORT_PA_DATA = port_pa_data_shadow &= ~(1 << rs485_pa_bit);
#endif
@@ -4493,10 +4530,10 @@ rs_init(void)
#if defined(CONFIG_ETRAX_RS485)
/* Set sane defaults */
- info->rs485.rts_on_send = 0;
- info->rs485.rts_after_sent = 1;
+ info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND);
+ info->rs485.flags |= SER_RS485_RTS_AFTER_SEND;
info->rs485.delay_rts_before_send = 0;
- info->rs485.enabled = 0;
+ info->rs485.flags &= ~(SER_RS485_ENABLED);
#endif
INIT_WORK(&info->work, do_softint);
diff --git a/drivers/serial/crisv10.h b/drivers/serial/crisv10.h
index f36a729280b..ea0beb46a10 100644
--- a/drivers/serial/crisv10.h
+++ b/drivers/serial/crisv10.h
@@ -125,7 +125,7 @@ struct e100_serial {
int errorcode;
#ifdef CONFIG_ETRAX_RS485
- struct rs485_control rs485; /* RS-485 support */
+ struct serial_rs485 rs485; /* RS-485 support */
#endif
};
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 2b7531d9f6a..6579e2be1dd 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -1098,7 +1098,6 @@ static void icom_set_termios(struct uart_port *port,
{
int baud;
unsigned cflag, iflag;
- int bits;
char new_config2;
char new_config3 = 0;
char tmp_byte;
@@ -1119,34 +1118,27 @@ static void icom_set_termios(struct uart_port *port,
switch (cflag & CSIZE) {
case CS5: /* 5 bits/char */
new_config2 |= ICOM_ACFG_5BPC;
- bits = 7;
break;
case CS6: /* 6 bits/char */
new_config2 |= ICOM_ACFG_6BPC;
- bits = 8;
break;
case CS7: /* 7 bits/char */
new_config2 |= ICOM_ACFG_7BPC;
- bits = 9;
break;
case CS8: /* 8 bits/char */
new_config2 |= ICOM_ACFG_8BPC;
- bits = 10;
break;
default:
- bits = 10;
break;
}
if (cflag & CSTOPB) {
/* 2 stop bits */
new_config2 |= ICOM_ACFG_2STOP_BIT;
- bits++;
}
if (cflag & PARENB) {
/* parity bit enabled */
new_config2 |= ICOM_ACFG_PARITY_ENAB;
trace(ICOM_PORT, "PARENB", 0);
- bits++;
}
if (cflag & PARODD) {
/* odd parity */
@@ -1322,7 +1314,6 @@ static struct uart_driver icom_uart_driver = {
static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
{
u32 subsystem_id = icom_adapter->subsystem_id;
- int retval = 0;
int i;
struct icom_port *icom_port;
@@ -1368,7 +1359,7 @@ static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
}
}
- return retval;
+ return 0;
}
static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
@@ -1391,7 +1382,6 @@ static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
{
struct icom_port *icom_port;
int port_num;
- int retval;
for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
@@ -1405,7 +1395,7 @@ static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
icom_port->adapter = icom_adapter;
/* get port memory */
- if ((retval = get_port_memory(icom_port)) != 0) {
+ if (get_port_memory(icom_port) != 0) {
dev_err(&icom_port->adapter->pci_dev->dev,
"Memory allocation for port FAILED\n");
}
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
index ac79cbe4c2c..d2d32a19862 100644
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -52,12 +52,11 @@ int jsm_debug;
module_param(jsm_debug, int, 0);
MODULE_PARM_DESC(jsm_debug, "Driver debugging level");
-static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int rc = 0;
struct jsm_board *brd;
static int adapter_count = 0;
- int retval;
rc = pci_enable_device(pdev);
if (rc) {
@@ -134,7 +133,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = jsm_tty_init(brd);
if (rc < 0) {
dev_err(&pdev->dev, "Can't init tty devices (%d)\n", rc);
- retval = -ENXIO;
+ rc = -ENXIO;
goto out_free_irq;
}
@@ -142,7 +141,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc < 0) {
/* XXX: leaking all resources from jsm_tty_init here! */
dev_err(&pdev->dev, "Can't init uart port (%d)\n", rc);
- retval = -ENXIO;
+ rc = -ENXIO;
goto out_free_irq;
}
@@ -161,7 +160,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* XXX: leaking all resources from jsm_tty_init and
jsm_uart_port_init here! */
dev_err(&pdev->dev, "memory allocation for flipbuf failed\n");
- retval = -ENOMEM;
+ rc = -ENOMEM;
goto out_free_irq;
}
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index e6390d02363..9dadaa11d26 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -533,7 +533,6 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch)
if (!(ch->ch_flags & (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM)))
return;
- len_written = 0;
n = UART_17158_TX_FIFOSIZE - ch->ch_t_tlevel;
/* cache head and tail of queue */
@@ -619,14 +618,10 @@ static void neo_parse_modem(struct jsm_channel *ch, u8 signals)
/* Make the UART raise any of the output signals we want up */
static void neo_assert_modem_signals(struct jsm_channel *ch)
{
- u8 out;
-
if (!ch)
return;
- out = ch->ch_mostat;
-
- writeb(out, &ch->ch_neo_uart->mcr);
+ writeb(ch->ch_mostat, &ch->ch_neo_uart->mcr);
/* flush write operation */
neo_pci_posting_flush(ch->ch_bd);
@@ -936,10 +931,9 @@ static inline void neo_parse_lsr(struct jsm_board *brd, u32 port)
static void neo_param(struct jsm_channel *ch)
{
u8 lcr = 0;
- u8 uart_lcr = 0;
- u8 ier = 0;
- u32 baud = 9600;
- int quot = 0;
+ u8 uart_lcr, ier;
+ u32 baud;
+ int quot;
struct jsm_board *bd;
bd = ch->ch_bd;
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 324c74d2f66..31496dc0a0d 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -183,7 +183,6 @@ static void jsm_tty_break(struct uart_port *port, int break_state)
static int jsm_tty_open(struct uart_port *port)
{
struct jsm_board *brd;
- int rc = 0;
struct jsm_channel *channel = (struct jsm_channel *)port;
struct ktermios *termios;
@@ -265,7 +264,7 @@ static int jsm_tty_open(struct uart_port *port)
channel->ch_open_count++;
jsm_printk(OPEN, INFO, &channel->ch_bd->pci_dev, "finish\n");
- return rc;
+ return 0;
}
static void jsm_tty_close(struct uart_port *port)
@@ -367,7 +366,7 @@ static struct uart_ops jsm_ops = {
* Init the tty subsystem. Called once per board after board has been
* downloaded and init'ed.
*/
-int jsm_tty_init(struct jsm_board *brd)
+int __devinit jsm_tty_init(struct jsm_board *brd)
{
int i;
void __iomem *vaddr;
@@ -431,7 +430,7 @@ int jsm_tty_init(struct jsm_board *brd)
return 0;
}
-int jsm_uart_port_init(struct jsm_board *brd)
+int __devinit jsm_uart_port_init(struct jsm_board *brd)
{
int i;
struct jsm_channel *ch;
@@ -748,7 +747,7 @@ static void jsm_carrier(struct jsm_channel *ch)
void jsm_check_queue_flow_control(struct jsm_channel *ch)
{
struct board_ops *bd_ops = ch->ch_bd->bd_ops;
- int qleft = 0;
+ int qleft;
/* Store how much space we have left in the queue */
if ((qleft = ch->ch_r_tail - ch->ch_r_head - 1) < 0)
@@ -834,7 +833,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
*/
int jsm_tty_write(struct uart_port *port)
{
- int bufcount = 0, n = 0;
+ int bufcount;
int data_count = 0,data_count1 =0;
u16 head;
u16 tail;
@@ -850,14 +849,12 @@ int jsm_tty_write(struct uart_port *port)
if ((bufcount = tail - head - 1) < 0)
bufcount += WQUEUESIZE;
- n = bufcount;
-
- n = min(n, 56);
+ bufcount = min(bufcount, 56);
remain = WQUEUESIZE - head;
data_count = 0;
- if (n >= remain) {
- n -= remain;
+ if (bufcount >= remain) {
+ bufcount -= remain;
while ((port->info->xmit.head != temp_tail) &&
(data_count < remain)) {
channel->ch_wqueue[head++] =
@@ -871,8 +868,8 @@ int jsm_tty_write(struct uart_port *port)
}
data_count1 = 0;
- if (n > 0) {
- remain = n;
+ if (bufcount > 0) {
+ remain = bufcount;
while ((port->info->xmit.head != temp_tail) &&
(data_count1 < remain)) {
channel->ch_wqueue[head++] =
diff --git a/drivers/serial/max3100.c b/drivers/serial/max3100.c
new file mode 100644
index 00000000000..9fd33e5622b
--- /dev/null
+++ b/drivers/serial/max3100.c
@@ -0,0 +1,927 @@
+/*
+ *
+ * Copyright (C) 2008 Christian Pellegrin <chripell@evolware.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.
+ *
+ *
+ * Notes: the MAX3100 doesn't provide an interrupt on CTS so we have
+ * to use polling for flow control. TX empty IRQ is unusable, since
+ * writing conf clears FIFO buffer and we cannot have this interrupt
+ * always asking us for attention.
+ *
+ * Example platform data:
+
+ static struct plat_max3100 max3100_plat_data = {
+ .loopback = 0,
+ .crystal = 0,
+ .poll_time = 100,
+ };
+
+ static struct spi_board_info spi_board_info[] = {
+ {
+ .modalias = "max3100",
+ .platform_data = &max3100_plat_data,
+ .irq = IRQ_EINT12,
+ .max_speed_hz = 5*1000*1000,
+ .chip_select = 0,
+ },
+ };
+
+ * The initial minor number is 209 in the low-density serial port:
+ * mknod /dev/ttyMAX0 c 204 209
+ */
+
+#define MAX3100_MAJOR 204
+#define MAX3100_MINOR 209
+/* 4 MAX3100s should be enough for everyone */
+#define MAX_MAX3100 4
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/spi/spi.h>
+#include <linux/freezer.h>
+
+#include <linux/serial_max3100.h>
+
+#define MAX3100_C (1<<14)
+#define MAX3100_D (0<<14)
+#define MAX3100_W (1<<15)
+#define MAX3100_RX (0<<15)
+
+#define MAX3100_WC (MAX3100_W | MAX3100_C)
+#define MAX3100_RC (MAX3100_RX | MAX3100_C)
+#define MAX3100_WD (MAX3100_W | MAX3100_D)
+#define MAX3100_RD (MAX3100_RX | MAX3100_D)
+#define MAX3100_CMD (3 << 14)
+
+#define MAX3100_T (1<<14)
+#define MAX3100_R (1<<15)
+
+#define MAX3100_FEN (1<<13)
+#define MAX3100_SHDN (1<<12)
+#define MAX3100_TM (1<<11)
+#define MAX3100_RM (1<<10)
+#define MAX3100_PM (1<<9)
+#define MAX3100_RAM (1<<8)
+#define MAX3100_IR (1<<7)
+#define MAX3100_ST (1<<6)
+#define MAX3100_PE (1<<5)
+#define MAX3100_L (1<<4)
+#define MAX3100_BAUD (0xf)
+
+#define MAX3100_TE (1<<10)
+#define MAX3100_RAFE (1<<10)
+#define MAX3100_RTS (1<<9)
+#define MAX3100_CTS (1<<9)
+#define MAX3100_PT (1<<8)
+#define MAX3100_DATA (0xff)
+
+#define MAX3100_RT (MAX3100_R | MAX3100_T)
+#define MAX3100_RTC (MAX3100_RT | MAX3100_CTS | MAX3100_RAFE)
+
+/* the following simulate a status reg for ignore_status_mask */
+#define MAX3100_STATUS_PE 1
+#define MAX3100_STATUS_FE 2
+#define MAX3100_STATUS_OE 4
+
+struct max3100_port {
+ struct uart_port port;
+ struct spi_device *spi;
+
+ int cts; /* last CTS received for flow ctrl */
+ int tx_empty; /* last TX empty bit */
+
+ spinlock_t conf_lock; /* shared data */
+ int conf_commit; /* need to make changes */
+ int conf; /* configuration for the MAX31000
+ * (bits 0-7, bits 8-11 are irqs) */
+ int rts_commit; /* need to change rts */
+ int rts; /* rts status */
+ int baud; /* current baud rate */
+
+ int parity; /* keeps track if we should send parity */
+#define MAX3100_PARITY_ON 1
+#define MAX3100_PARITY_ODD 2
+#define MAX3100_7BIT 4
+ int rx_enabled; /* if we should rx chars */
+
+ int irq; /* irq assigned to the max3100 */
+
+ int minor; /* minor number */
+ int crystal; /* 1 if 3.6864Mhz crystal 0 for 1.8432 */
+ int loopback; /* 1 if we are in loopback mode */
+
+ /* for handling irqs: need workqueue since we do spi_sync */
+ struct workqueue_struct *workqueue;
+ struct work_struct work;
+ /* set to 1 to make the workhandler exit as soon as possible */
+ int force_end_work;
+ /* need to know we are suspending to avoid deadlock on workqueue */
+ int suspending;
+
+ /* hook for suspending MAX3100 via dedicated pin */
+ void (*max3100_hw_suspend) (int suspend);
+
+ /* poll time (in ms) for ctrl lines */
+ int poll_time;
+ /* and its timer */
+ struct timer_list timer;
+};
+
+static struct max3100_port *max3100s[MAX_MAX3100]; /* the chips */
+static DEFINE_MUTEX(max3100s_lock); /* race on probe */
+
+static int max3100_do_parity(struct max3100_port *s, u16 c)
+{
+ int parity;
+
+ if (s->parity & MAX3100_PARITY_ODD)
+ parity = 1;
+ else
+ parity = 0;
+
+ if (s->parity & MAX3100_7BIT)
+ c &= 0x7f;
+ else
+ c &= 0xff;
+
+ parity = parity ^ (hweight8(c) & 1);
+ return parity;
+}
+
+static int max3100_check_parity(struct max3100_port *s, u16 c)
+{
+ return max3100_do_parity(s, c) == ((c >> 8) & 1);
+}
+
+static void max3100_calc_parity(struct max3100_port *s, u16 *c)
+{
+ if (s->parity & MAX3100_7BIT)
+ *c &= 0x7f;
+ else
+ *c &= 0xff;
+
+ if (s->parity & MAX3100_PARITY_ON)
+ *c |= max3100_do_parity(s, *c) << 8;
+}
+
+static void max3100_work(struct work_struct *w);
+
+static void max3100_dowork(struct max3100_port *s)
+{
+ if (!s->force_end_work && !work_pending(&s->work) &&
+ !freezing(current) && !s->suspending)
+ queue_work(s->workqueue, &s->work);
+}
+
+static void max3100_timeout(unsigned long data)
+{
+ struct max3100_port *s = (struct max3100_port *)data;
+
+ if (s->port.info) {
+ max3100_dowork(s);
+ mod_timer(&s->timer, jiffies + s->poll_time);
+ }
+}
+
+static int max3100_sr(struct max3100_port *s, u16 tx, u16 *rx)
+{
+ struct spi_message message;
+ u16 etx, erx;
+ int status;
+ struct spi_transfer tran = {
+ .tx_buf = &etx,
+ .rx_buf = &erx,
+ .len = 2,
+ };
+
+ etx = cpu_to_be16(tx);
+ spi_message_init(&message);
+ spi_message_add_tail(&tran, &message);
+ status = spi_sync(s->spi, &message);
+ if (status) {
+ dev_warn(&s->spi->dev, "error while calling spi_sync\n");
+ return -EIO;
+ }
+ *rx = be16_to_cpu(erx);
+ s->tx_empty = (*rx & MAX3100_T) > 0;
+ dev_dbg(&s->spi->dev, "%04x - %04x\n", tx, *rx);
+ return 0;
+}
+
+static int max3100_handlerx(struct max3100_port *s, u16 rx)
+{
+ unsigned int ch, flg, status = 0;
+ int ret = 0, cts;
+
+ if (rx & MAX3100_R && s->rx_enabled) {
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+ ch = rx & (s->parity & MAX3100_7BIT ? 0x7f : 0xff);
+ if (rx & MAX3100_RAFE) {
+ s->port.icount.frame++;
+ flg = TTY_FRAME;
+ status |= MAX3100_STATUS_FE;
+ } else {
+ if (s->parity & MAX3100_PARITY_ON) {
+ if (max3100_check_parity(s, rx)) {
+ s->port.icount.rx++;
+ flg = TTY_NORMAL;
+ } else {
+ s->port.icount.parity++;
+ flg = TTY_PARITY;
+ status |= MAX3100_STATUS_PE;
+ }
+ } else {
+ s->port.icount.rx++;
+ flg = TTY_NORMAL;
+ }
+ }
+ uart_insert_char(&s->port, status, MAX3100_STATUS_OE, ch, flg);
+ ret = 1;
+ }
+
+ cts = (rx & MAX3100_CTS) > 0;
+ if (s->cts != cts) {
+ s->cts = cts;
+ uart_handle_cts_change(&s->port, cts ? TIOCM_CTS : 0);
+ }
+
+ return ret;
+}
+
+static void max3100_work(struct work_struct *w)
+{
+ struct max3100_port *s = container_of(w, struct max3100_port, work);
+ int rxchars;
+ u16 tx, rx;
+ int conf, cconf, rts, crts;
+ struct circ_buf *xmit = &s->port.info->xmit;
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ rxchars = 0;
+ do {
+ spin_lock(&s->conf_lock);
+ conf = s->conf;
+ cconf = s->conf_commit;
+ s->conf_commit = 0;
+ rts = s->rts;
+ crts = s->rts_commit;
+ s->rts_commit = 0;
+ spin_unlock(&s->conf_lock);
+ if (cconf)
+ max3100_sr(s, MAX3100_WC | conf, &rx);
+ if (crts) {
+ max3100_sr(s, MAX3100_WD | MAX3100_TE |
+ (s->rts ? MAX3100_RTS : 0), &rx);
+ rxchars += max3100_handlerx(s, rx);
+ }
+
+ max3100_sr(s, MAX3100_RD, &rx);
+ rxchars += max3100_handlerx(s, rx);
+
+ if (rx & MAX3100_T) {
+ tx = 0xffff;
+ if (s->port.x_char) {
+ tx = s->port.x_char;
+ s->port.icount.tx++;
+ s->port.x_char = 0;
+ } else if (!uart_circ_empty(xmit) &&
+ !uart_tx_stopped(&s->port)) {
+ tx = xmit->buf[xmit->tail];
+ xmit->tail = (xmit->tail + 1) &
+ (UART_XMIT_SIZE - 1);
+ s->port.icount.tx++;
+ }
+ if (tx != 0xffff) {
+ max3100_calc_parity(s, &tx);
+ tx |= MAX3100_WD | (s->rts ? MAX3100_RTS : 0);
+ max3100_sr(s, tx, &rx);
+ rxchars += max3100_handlerx(s, rx);
+ }
+ }
+
+ if (rxchars > 16 && s->port.info->port.tty != NULL) {
+ tty_flip_buffer_push(s->port.info->port.tty);
+ rxchars = 0;
+ }
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&s->port);
+
+ } while (!s->force_end_work &&
+ !freezing(current) &&
+ ((rx & MAX3100_R) ||
+ (!uart_circ_empty(xmit) &&
+ !uart_tx_stopped(&s->port))));
+
+ if (rxchars > 0 && s->port.info->port.tty != NULL)
+ tty_flip_buffer_push(s->port.info->port.tty);
+}
+
+static irqreturn_t max3100_irq(int irqno, void *dev_id)
+{
+ struct max3100_port *s = dev_id;
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ max3100_dowork(s);
+ return IRQ_HANDLED;
+}
+
+static void max3100_enable_ms(struct uart_port *port)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+
+ if (s->poll_time > 0)
+ mod_timer(&s->timer, jiffies);
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+}
+
+static void max3100_start_tx(struct uart_port *port)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ max3100_dowork(s);
+}
+
+static void max3100_stop_rx(struct uart_port *port)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ s->rx_enabled = 0;
+ spin_lock(&s->conf_lock);
+ s->conf &= ~MAX3100_RM;
+ s->conf_commit = 1;
+ spin_unlock(&s->conf_lock);
+ max3100_dowork(s);
+}
+
+static unsigned int max3100_tx_empty(struct uart_port *port)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ /* may not be truly up-to-date */
+ max3100_dowork(s);
+ return s->tx_empty;
+}
+
+static unsigned int max3100_get_mctrl(struct uart_port *port)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ /* may not be truly up-to-date */
+ max3100_dowork(s);
+ /* always assert DCD and DSR since these lines are not wired */
+ return (s->cts ? TIOCM_CTS : 0) | TIOCM_DSR | TIOCM_CAR;
+}
+
+static void max3100_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+ int rts;
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ rts = (mctrl & TIOCM_RTS) > 0;
+
+ spin_lock(&s->conf_lock);
+ if (s->rts != rts) {
+ s->rts = rts;
+ s->rts_commit = 1;
+ max3100_dowork(s);
+ }
+ spin_unlock(&s->conf_lock);
+}
+
+static void
+max3100_set_termios(struct uart_port *port, struct ktermios *termios,
+ struct ktermios *old)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+ int baud = 0;
+ unsigned cflag;
+ u32 param_new, param_mask, parity = 0;
+ struct tty_struct *tty = s->port.info->port.tty;
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+ if (!tty)
+ return;
+
+ cflag = termios->c_cflag;
+ param_new = 0;
+ param_mask = 0;
+
+ baud = tty_get_baud_rate(tty);
+ param_new = s->conf & MAX3100_BAUD;
+ switch (baud) {
+ case 300:
+ if (s->crystal)
+ baud = s->baud;
+ else
+ param_new = 15;
+ break;
+ case 600:
+ param_new = 14 + s->crystal;
+ break;
+ case 1200:
+ param_new = 13 + s->crystal;
+ break;
+ case 2400:
+ param_new = 12 + s->crystal;
+ break;
+ case 4800:
+ param_new = 11 + s->crystal;
+ break;
+ case 9600:
+ param_new = 10 + s->crystal;
+ break;
+ case 19200:
+ param_new = 9 + s->crystal;
+ break;
+ case 38400:
+ param_new = 8 + s->crystal;
+ break;
+ case 57600:
+ param_new = 1 + s->crystal;
+ break;
+ case 115200:
+ param_new = 0 + s->crystal;
+ break;
+ case 230400:
+ if (s->crystal)
+ param_new = 0;
+ else
+ baud = s->baud;
+ break;
+ default:
+ baud = s->baud;
+ }
+ tty_encode_baud_rate(tty, baud, baud);
+ s->baud = baud;
+ param_mask |= MAX3100_BAUD;
+
+ if ((cflag & CSIZE) == CS8) {
+ param_new &= ~MAX3100_L;
+ parity &= ~MAX3100_7BIT;
+ } else {
+ param_new |= MAX3100_L;
+ parity |= MAX3100_7BIT;
+ cflag = (cflag & ~CSIZE) | CS7;
+ }
+ param_mask |= MAX3100_L;
+
+ if (cflag & CSTOPB)
+ param_new |= MAX3100_ST;
+ else
+ param_new &= ~MAX3100_ST;
+ param_mask |= MAX3100_ST;
+
+ if (cflag & PARENB) {
+ param_new |= MAX3100_PE;
+ parity |= MAX3100_PARITY_ON;
+ } else {
+ param_new &= ~MAX3100_PE;
+ parity &= ~MAX3100_PARITY_ON;
+ }
+ param_mask |= MAX3100_PE;
+
+ if (cflag & PARODD)
+ parity |= MAX3100_PARITY_ODD;
+ else
+ parity &= ~MAX3100_PARITY_ODD;
+
+ /* mask termios capabilities we don't support */
+ cflag &= ~CMSPAR;
+ termios->c_cflag = cflag;
+
+ s->port.ignore_status_mask = 0;
+ if (termios->c_iflag & IGNPAR)
+ s->port.ignore_status_mask |=
+ MAX3100_STATUS_PE | MAX3100_STATUS_FE |
+ MAX3100_STATUS_OE;
+
+ /* we are sending char from a workqueue so enable */
+ s->port.info->port.tty->low_latency = 1;
+
+ if (s->poll_time > 0)
+ del_timer_sync(&s->timer);
+
+ uart_update_timeout(port, termios->c_cflag, baud);
+
+ spin_lock(&s->conf_lock);
+ s->conf = (s->conf & ~param_mask) | (param_new & param_mask);
+ s->conf_commit = 1;
+ s->parity = parity;
+ spin_unlock(&s->conf_lock);
+ max3100_dowork(s);
+
+ if (UART_ENABLE_MS(&s->port, termios->c_cflag))
+ max3100_enable_ms(&s->port);
+}
+
+static void max3100_shutdown(struct uart_port *port)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ if (s->suspending)
+ return;
+
+ s->force_end_work = 1;
+
+ if (s->poll_time > 0)
+ del_timer_sync(&s->timer);
+
+ if (s->workqueue) {
+ flush_workqueue(s->workqueue);
+ destroy_workqueue(s->workqueue);
+ s->workqueue = NULL;
+ }
+ if (s->irq)
+ free_irq(s->irq, s);
+
+ /* set shutdown mode to save power */
+ if (s->max3100_hw_suspend)
+ s->max3100_hw_suspend(1);
+ else {
+ u16 tx, rx;
+
+ tx = MAX3100_WC | MAX3100_SHDN;
+ max3100_sr(s, tx, &rx);
+ }
+}
+
+static int max3100_startup(struct uart_port *port)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+ char b[12];
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ s->conf = MAX3100_RM;
+ s->baud = s->crystal ? 230400 : 115200;
+ s->rx_enabled = 1;
+
+ if (s->suspending)
+ return 0;
+
+ s->force_end_work = 0;
+ s->parity = 0;
+ s->rts = 0;
+
+ sprintf(b, "max3100-%d", s->minor);
+ s->workqueue = create_freezeable_workqueue(b);
+ if (!s->workqueue) {
+ dev_warn(&s->spi->dev, "cannot create workqueue\n");
+ return -EBUSY;
+ }
+ INIT_WORK(&s->work, max3100_work);
+
+ if (request_irq(s->irq, max3100_irq,
+ IRQF_TRIGGER_FALLING, "max3100", s) < 0) {
+ dev_warn(&s->spi->dev, "cannot allocate irq %d\n", s->irq);
+ s->irq = 0;
+ destroy_workqueue(s->workqueue);
+ s->workqueue = NULL;
+ return -EBUSY;
+ }
+
+ if (s->loopback) {
+ u16 tx, rx;
+ tx = 0x4001;
+ max3100_sr(s, tx, &rx);
+ }
+
+ if (s->max3100_hw_suspend)
+ s->max3100_hw_suspend(0);
+ s->conf_commit = 1;
+ max3100_dowork(s);
+ /* wait for clock to settle */
+ msleep(50);
+
+ max3100_enable_ms(&s->port);
+
+ return 0;
+}
+
+static const char *max3100_type(struct uart_port *port)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ return s->port.type == PORT_MAX3100 ? "MAX3100" : NULL;
+}
+
+static void max3100_release_port(struct uart_port *port)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+}
+
+static void max3100_config_port(struct uart_port *port, int flags)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ if (flags & UART_CONFIG_TYPE)
+ s->port.type = PORT_MAX3100;
+}
+
+static int max3100_verify_port(struct uart_port *port,
+ struct serial_struct *ser)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+ int ret = -EINVAL;
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ if (ser->type == PORT_UNKNOWN || ser->type == PORT_MAX3100)
+ ret = 0;
+ return ret;
+}
+
+static void max3100_stop_tx(struct uart_port *port)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+}
+
+static int max3100_request_port(struct uart_port *port)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+ return 0;
+}
+
+static void max3100_break_ctl(struct uart_port *port, int break_state)
+{
+ struct max3100_port *s = container_of(port,
+ struct max3100_port,
+ port);
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+}
+
+static struct uart_ops max3100_ops = {
+ .tx_empty = max3100_tx_empty,
+ .set_mctrl = max3100_set_mctrl,
+ .get_mctrl = max3100_get_mctrl,
+ .stop_tx = max3100_stop_tx,
+ .start_tx = max3100_start_tx,
+ .stop_rx = max3100_stop_rx,
+ .enable_ms = max3100_enable_ms,
+ .break_ctl = max3100_break_ctl,
+ .startup = max3100_startup,
+ .shutdown = max3100_shutdown,
+ .set_termios = max3100_set_termios,
+ .type = max3100_type,
+ .release_port = max3100_release_port,
+ .request_port = max3100_request_port,
+ .config_port = max3100_config_port,
+ .verify_port = max3100_verify_port,
+};
+
+static struct uart_driver max3100_uart_driver = {
+ .owner = THIS_MODULE,
+ .driver_name = "ttyMAX",
+ .dev_name = "ttyMAX",
+ .major = MAX3100_MAJOR,
+ .minor = MAX3100_MINOR,
+ .nr = MAX_MAX3100,
+};
+static int uart_driver_registered;
+
+static int __devinit max3100_probe(struct spi_device *spi)
+{
+ int i, retval;
+ struct plat_max3100 *pdata;
+ u16 tx, rx;
+
+ mutex_lock(&max3100s_lock);
+
+ if (!uart_driver_registered) {
+ uart_driver_registered = 1;
+ retval = uart_register_driver(&max3100_uart_driver);
+ if (retval) {
+ printk(KERN_ERR "Couldn't register max3100 uart driver\n");
+ mutex_unlock(&max3100s_lock);
+ return retval;
+ }
+ }
+
+ for (i = 0; i < MAX_MAX3100; i++)
+ if (!max3100s[i])
+ break;
+ if (i == MAX_MAX3100) {
+ dev_warn(&spi->dev, "too many MAX3100 chips\n");
+ mutex_unlock(&max3100s_lock);
+ return -ENOMEM;
+ }
+
+ max3100s[i] = kzalloc(sizeof(struct max3100_port), GFP_KERNEL);
+ if (!max3100s[i]) {
+ dev_warn(&spi->dev,
+ "kmalloc for max3100 structure %d failed!\n", i);
+ mutex_unlock(&max3100s_lock);
+ return -ENOMEM;
+ }
+ max3100s[i]->spi = spi;
+ max3100s[i]->irq = spi->irq;
+ spin_lock_init(&max3100s[i]->conf_lock);
+ dev_set_drvdata(&spi->dev, max3100s[i]);
+ pdata = spi->dev.platform_data;
+ max3100s[i]->crystal = pdata->crystal;
+ max3100s[i]->loopback = pdata->loopback;
+ max3100s[i]->poll_time = pdata->poll_time * HZ / 1000;
+ if (pdata->poll_time > 0 && max3100s[i]->poll_time == 0)
+ max3100s[i]->poll_time = 1;
+ max3100s[i]->max3100_hw_suspend = pdata->max3100_hw_suspend;
+ max3100s[i]->minor = i;
+ init_timer(&max3100s[i]->timer);
+ max3100s[i]->timer.function = max3100_timeout;
+ max3100s[i]->timer.data = (unsigned long) max3100s[i];
+
+ dev_dbg(&spi->dev, "%s: adding port %d\n", __func__, i);
+ max3100s[i]->port.irq = max3100s[i]->irq;
+ max3100s[i]->port.uartclk = max3100s[i]->crystal ? 3686400 : 1843200;
+ max3100s[i]->port.fifosize = 16;
+ max3100s[i]->port.ops = &max3100_ops;
+ max3100s[i]->port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
+ max3100s[i]->port.line = i;
+ max3100s[i]->port.type = PORT_MAX3100;
+ max3100s[i]->port.dev = &spi->dev;
+ retval = uart_add_one_port(&max3100_uart_driver, &max3100s[i]->port);
+ if (retval < 0)
+ dev_warn(&spi->dev,
+ "uart_add_one_port failed for line %d with error %d\n",
+ i, retval);
+
+ /* set shutdown mode to save power. Will be woken-up on open */
+ if (max3100s[i]->max3100_hw_suspend)
+ max3100s[i]->max3100_hw_suspend(1);
+ else {
+ tx = MAX3100_WC | MAX3100_SHDN;
+ max3100_sr(max3100s[i], tx, &rx);
+ }
+ mutex_unlock(&max3100s_lock);
+ return 0;
+}
+
+static int __devexit max3100_remove(struct spi_device *spi)
+{
+ struct max3100_port *s = dev_get_drvdata(&spi->dev);
+ int i;
+
+ mutex_lock(&max3100s_lock);
+
+ /* find out the index for the chip we are removing */
+ for (i = 0; i < MAX_MAX3100; i++)
+ if (max3100s[i] == s)
+ break;
+
+ dev_dbg(&spi->dev, "%s: removing port %d\n", __func__, i);
+ uart_remove_one_port(&max3100_uart_driver, &max3100s[i]->port);
+ kfree(max3100s[i]);
+ max3100s[i] = NULL;
+
+ /* check if this is the last chip we have */
+ for (i = 0; i < MAX_MAX3100; i++)
+ if (max3100s[i]) {
+ mutex_unlock(&max3100s_lock);
+ return 0;
+ }
+ pr_debug("removing max3100 driver\n");
+ uart_unregister_driver(&max3100_uart_driver);
+
+ mutex_unlock(&max3100s_lock);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int max3100_suspend(struct spi_device *spi, pm_message_t state)
+{
+ struct max3100_port *s = dev_get_drvdata(&spi->dev);
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ disable_irq(s->irq);
+
+ s->suspending = 1;
+ uart_suspend_port(&max3100_uart_driver, &s->port);
+
+ if (s->max3100_hw_suspend)
+ s->max3100_hw_suspend(1);
+ else {
+ /* no HW suspend, so do SW one */
+ u16 tx, rx;
+
+ tx = MAX3100_WC | MAX3100_SHDN;
+ max3100_sr(s, tx, &rx);
+ }
+ return 0;
+}
+
+static int max3100_resume(struct spi_device *spi)
+{
+ struct max3100_port *s = dev_get_drvdata(&spi->dev);
+
+ dev_dbg(&s->spi->dev, "%s\n", __func__);
+
+ if (s->max3100_hw_suspend)
+ s->max3100_hw_suspend(0);
+ uart_resume_port(&max3100_uart_driver, &s->port);
+ s->suspending = 0;
+
+ enable_irq(s->irq);
+
+ s->conf_commit = 1;
+ if (s->workqueue)
+ max3100_dowork(s);
+
+ return 0;
+}
+
+#else
+#define max3100_suspend NULL
+#define max3100_resume NULL
+#endif
+
+static struct spi_driver max3100_driver = {
+ .driver = {
+ .name = "max3100",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = max3100_probe,
+ .remove = __devexit_p(max3100_remove),
+ .suspend = max3100_suspend,
+ .resume = max3100_resume,
+};
+
+static int __init max3100_init(void)
+{
+ return spi_register_driver(&max3100_driver);
+}
+module_init(max3100_init);
+
+static void __exit max3100_exit(void)
+{
+ spi_unregister_driver(&max3100_driver);
+}
+module_exit(max3100_exit);
+
+MODULE_DESCRIPTION("MAX3100 driver");
+MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c
index 56841fe5f48..0eefb07beba 100644
--- a/drivers/serial/mcf.c
+++ b/drivers/serial/mcf.c
@@ -513,7 +513,7 @@ static int __init mcf_console_setup(struct console *co, char *options)
int parity = 'n';
int flow = 'n';
- if ((co->index >= 0) && (co->index <= MCF_MAXPORTS))
+ if ((co->index < 0) || (co->index >= MCF_MAXPORTS))
co->index = 0;
port = &mcf_ports[co->index].port;
if (port->membase == 0)
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index ad348850401..9c1243fbd51 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -1538,6 +1538,21 @@ no_dma:
uap->port.type = PORT_PMAC_ZILOG;
uap->port.flags = 0;
+ /*
+ * Fixup for the port on Gatwick for which the device-tree has
+ * missing interrupts. Normally, the macio_dev would contain
+ * fixed up interrupt info, but we use the device-tree directly
+ * here due to early probing so we need the fixup too.
+ */
+ if (uap->port.irq == NO_IRQ &&
+ np->parent && np->parent->parent &&
+ of_device_is_compatible(np->parent->parent, "gatwick")) {
+ /* IRQs on gatwick are offset by 64 */
+ uap->port.irq = irq_create_mapping(NULL, 64 + 15);
+ uap->tx_dma_irq = irq_create_mapping(NULL, 64 + 4);
+ uap->rx_dma_irq = irq_create_mapping(NULL, 64 + 5);
+ }
+
/* Setup some valid baud rate information in the register
* shadows so we don't write crap there before baud rate is
* first initialized.
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index a4dc79b1d7a..47c6837850b 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1178,7 +1178,7 @@ static struct uart_driver sunsu_reg = {
.major = TTY_MAJOR,
};
-static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up)
+static int __devinit sunsu_kbd_ms_init(struct uart_sunsu_port *up)
{
int quot, baud;
#ifdef CONFIG_SERIO
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c
index 315a9333ca3..7de66c06b05 100644
--- a/drivers/serial/ucc_uart.c
+++ b/drivers/serial/ucc_uart.c
@@ -1274,6 +1274,7 @@ static int ucc_uart_probe(struct of_device *ofdev,
if (!iprop) {
iprop = of_get_property(np, "device-id", NULL);
if (!iprop) {
+ kfree(qe_port);
dev_err(&ofdev->dev, "UCC is unspecified in "
"device tree\n");
return -EINVAL;
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index 2269fbcaa18..12d13d99b6f 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -22,6 +22,8 @@
#include <linux/interrupt.h>
#include <linux/bootmem.h>
#include <linux/sh_intc.h>
+#include <linux/sysdev.h>
+#include <linux/list.h>
#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
@@ -40,6 +42,9 @@ struct intc_handle_int {
};
struct intc_desc_int {
+ struct list_head list;
+ struct sys_device sysdev;
+ pm_message_t state;
unsigned long *reg;
#ifdef CONFIG_SMP
unsigned long *smp;
@@ -52,6 +57,8 @@ struct intc_desc_int {
struct irq_chip chip;
};
+static LIST_HEAD(intc_list);
+
#ifdef CONFIG_SMP
#define IS_SMP(x) x.smp
#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c))
@@ -232,6 +239,11 @@ static void intc_disable(unsigned int irq)
}
}
+static int intc_set_wake(unsigned int irq, unsigned int on)
+{
+ return 0; /* allow wakeup, but setup hardware in intc_suspend() */
+}
+
#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
static void intc_mask_ack(unsigned int irq)
{
@@ -664,6 +676,9 @@ void __init register_intc_controller(struct intc_desc *desc)
d = alloc_bootmem(sizeof(*d));
+ INIT_LIST_HEAD(&d->list);
+ list_add(&d->list, &intc_list);
+
d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0;
d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
@@ -707,7 +722,11 @@ void __init register_intc_controller(struct intc_desc *desc)
d->chip.mask = intc_disable;
d->chip.unmask = intc_enable;
d->chip.mask_ack = intc_disable;
+ d->chip.enable = intc_enable;
+ d->chip.disable = intc_disable;
+ d->chip.shutdown = intc_disable;
d->chip.set_type = intc_set_sense;
+ d->chip.set_wake = intc_set_wake;
#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
if (desc->ack_regs) {
@@ -758,3 +777,79 @@ void __init register_intc_controller(struct intc_desc *desc)
intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect));
}
}
+
+static int intc_suspend(struct sys_device *dev, pm_message_t state)
+{
+ struct intc_desc_int *d;
+ struct irq_desc *desc;
+ int irq;
+
+ /* get intc controller associated with this sysdev */
+ d = container_of(dev, struct intc_desc_int, sysdev);
+
+ switch (state.event) {
+ case PM_EVENT_ON:
+ if (d->state.event != PM_EVENT_FREEZE)
+ break;
+ for_each_irq_desc(irq, desc) {
+ if (desc->chip != &d->chip)
+ continue;
+ if (desc->status & IRQ_DISABLED)
+ intc_disable(irq);
+ else
+ intc_enable(irq);
+ }
+ break;
+ case PM_EVENT_FREEZE:
+ /* nothing has to be done */
+ break;
+ case PM_EVENT_SUSPEND:
+ /* enable wakeup irqs belonging to this intc controller */
+ for_each_irq_desc(irq, desc) {
+ if ((desc->status & IRQ_WAKEUP) && (desc->chip == &d->chip))
+ intc_enable(irq);
+ }
+ break;
+ }
+ d->state = state;
+
+ return 0;
+}
+
+static int intc_resume(struct sys_device *dev)
+{
+ return intc_suspend(dev, PMSG_ON);
+}
+
+static struct sysdev_class intc_sysdev_class = {
+ .name = "intc",
+ .suspend = intc_suspend,
+ .resume = intc_resume,
+};
+
+/* register this intc as sysdev to allow suspend/resume */
+static int __init register_intc_sysdevs(void)
+{
+ struct intc_desc_int *d;
+ int error;
+ int id = 0;
+
+ error = sysdev_class_register(&intc_sysdev_class);
+ if (!error) {
+ list_for_each_entry(d, &intc_list, list) {
+ d->sysdev.id = id;
+ d->sysdev.cls = &intc_sysdev_class;
+ error = sysdev_register(&d->sysdev);
+ if (error)
+ break;
+ id++;
+ }
+ }
+
+ if (error)
+ pr_warning("intc: sysdev registration error\n");
+
+ return error;
+}
+
+device_initcall(register_intc_sysdevs);
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c
index a0aa33dde0a..816d4c592a3 100644
--- a/drivers/sn/ioc3.c
+++ b/drivers/sn/ioc3.c
@@ -617,9 +617,9 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
pci_set_master(pdev);
#ifdef USE_64BIT_DMA
- ret = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (!ret) {
- ret = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (ret < 0) {
printk(KERN_WARNING "%s: Unable to obtain 64 bit DMA "
"for consistent allocations\n",
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 33fcef3150d..c1688c71f05 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -28,6 +28,7 @@
#include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/clk.h>
+#include <linux/gpio.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -53,6 +54,7 @@ MODULE_ALIAS("platform:pxa2xx-spi");
#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
#define IS_DMA_ALIGNED(x) ((((u32)(x)) & 0x07) == 0)
#define MAX_DMA_LEN 8191
+#define DMA_ALIGNMENT 8
/*
* for testing SSCR1 changes that require SSP restart, basically
@@ -166,6 +168,8 @@ struct chip_data {
u8 enable_dma;
u8 bits_per_word;
u32 speed_hz;
+ int gpio_cs;
+ int gpio_cs_inverted;
int (*write)(struct driver_data *drv_data);
int (*read)(struct driver_data *drv_data);
void (*cs_control)(u32 command);
@@ -173,6 +177,32 @@ struct chip_data {
static void pump_messages(struct work_struct *work);
+static void cs_assert(struct driver_data *drv_data)
+{
+ struct chip_data *chip = drv_data->cur_chip;
+
+ if (chip->cs_control) {
+ chip->cs_control(PXA2XX_CS_ASSERT);
+ return;
+ }
+
+ if (gpio_is_valid(chip->gpio_cs))
+ gpio_set_value(chip->gpio_cs, chip->gpio_cs_inverted);
+}
+
+static void cs_deassert(struct driver_data *drv_data)
+{
+ struct chip_data *chip = drv_data->cur_chip;
+
+ if (chip->cs_control) {
+ chip->cs_control(PXA2XX_CS_ASSERT);
+ return;
+ }
+
+ if (gpio_is_valid(chip->gpio_cs))
+ gpio_set_value(chip->gpio_cs, !chip->gpio_cs_inverted);
+}
+
static int flush(struct driver_data *drv_data)
{
unsigned long limit = loops_per_jiffy << 1;
@@ -189,10 +219,6 @@ static int flush(struct driver_data *drv_data)
return limit;
}
-static void null_cs_control(u32 command)
-{
-}
-
static int null_writer(struct driver_data *drv_data)
{
void __iomem *reg = drv_data->ioaddr;
@@ -400,7 +426,6 @@ static void giveback(struct driver_data *drv_data)
msg = drv_data->cur_msg;
drv_data->cur_msg = NULL;
drv_data->cur_transfer = NULL;
- drv_data->cur_chip = NULL;
queue_work(drv_data->workqueue, &drv_data->pump_messages);
spin_unlock_irqrestore(&drv_data->lock, flags);
@@ -416,7 +441,7 @@ static void giveback(struct driver_data *drv_data)
* a message with an error, or next message is for another chip
*/
if (!last_transfer->cs_change)
- drv_data->cs_control(PXA2XX_CS_DEASSERT);
+ cs_deassert(drv_data);
else {
struct spi_message *next_msg;
@@ -445,12 +470,14 @@ static void giveback(struct driver_data *drv_data)
if (next_msg && next_msg->spi != msg->spi)
next_msg = NULL;
if (!next_msg || msg->state == ERROR_STATE)
- drv_data->cs_control(PXA2XX_CS_DEASSERT);
+ cs_deassert(drv_data);
}
msg->state = NULL;
if (msg->complete)
msg->complete(msg->context);
+
+ drv_data->cur_chip = NULL;
}
static int wait_ssp_rx_stall(void const __iomem *ioaddr)
@@ -887,7 +914,7 @@ static void pump_transfers(unsigned long data)
/* Drop chip select only if cs_change is requested */
if (previous->cs_change)
- drv_data->cs_control(PXA2XX_CS_DEASSERT);
+ cs_deassert(drv_data);
}
/* Check for transfers that need multiple DMA segments */
@@ -922,7 +949,6 @@ static void pump_transfers(unsigned long data)
}
drv_data->n_bytes = chip->n_bytes;
drv_data->dma_width = chip->dma_width;
- drv_data->cs_control = chip->cs_control;
drv_data->tx = (void *)transfer->tx_buf;
drv_data->tx_end = drv_data->tx + transfer->len;
drv_data->rx = transfer->rx_buf;
@@ -1084,11 +1110,7 @@ static void pump_transfers(unsigned long data)
write_SSTO(chip->timeout, reg);
}
- /* FIXME, need to handle cs polarity,
- * this driver uses struct pxa2xx_spi_chip.cs_control to
- * specify a CS handling function, and it ignores most
- * struct spi_device.mode[s], including SPI_CS_HIGH */
- drv_data->cs_control(PXA2XX_CS_ASSERT);
+ cs_assert(drv_data);
/* after chip select, release the data by enabling service
* requests and interrupts, without changing any mode bits */
@@ -1166,6 +1188,44 @@ static int transfer(struct spi_device *spi, struct spi_message *msg)
/* the spi->mode bits understood by this driver: */
#define MODEBITS (SPI_CPOL | SPI_CPHA)
+static int setup_cs(struct spi_device *spi, struct chip_data *chip,
+ struct pxa2xx_spi_chip *chip_info)
+{
+ int err = 0;
+
+ if (chip == NULL || chip_info == NULL)
+ return 0;
+
+ /* NOTE: setup() can be called multiple times, possibly with
+ * different chip_info, release previously requested GPIO
+ */
+ if (gpio_is_valid(chip->gpio_cs))
+ gpio_free(chip->gpio_cs);
+
+ /* If (*cs_control) is provided, ignore GPIO chip select */
+ if (chip_info->cs_control) {
+ chip->cs_control = chip_info->cs_control;
+ return 0;
+ }
+
+ if (gpio_is_valid(chip_info->gpio_cs)) {
+ err = gpio_request(chip_info->gpio_cs, "SPI_CS");
+ if (err) {
+ dev_err(&spi->dev, "failed to request chip select "
+ "GPIO%d\n", chip_info->gpio_cs);
+ return err;
+ }
+
+ chip->gpio_cs = chip_info->gpio_cs;
+ chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH;
+
+ err = gpio_direction_output(chip->gpio_cs,
+ !chip->gpio_cs_inverted);
+ }
+
+ return err;
+}
+
static int setup(struct spi_device *spi)
{
struct pxa2xx_spi_chip *chip_info = NULL;
@@ -1211,7 +1271,7 @@ static int setup(struct spi_device *spi)
return -ENOMEM;
}
- chip->cs_control = null_cs_control;
+ chip->gpio_cs = -1;
chip->enable_dma = 0;
chip->timeout = TIMOUT_DFLT;
chip->dma_burst_size = drv_data->master_info->enable_dma ?
@@ -1225,8 +1285,6 @@ static int setup(struct spi_device *spi)
/* chip_info isn't always needed */
chip->cr1 = 0;
if (chip_info) {
- if (chip_info->cs_control)
- chip->cs_control = chip_info->cs_control;
if (chip_info->timeout)
chip->timeout = chip_info->timeout;
if (chip_info->tx_threshold)
@@ -1308,13 +1366,16 @@ static int setup(struct spi_device *spi)
spi_set_ctldata(spi, chip);
- return 0;
+ return setup_cs(spi, chip, chip_info);
}
static void cleanup(struct spi_device *spi)
{
struct chip_data *chip = spi_get_ctldata(spi);
+ if (gpio_is_valid(chip->gpio_cs))
+ gpio_free(chip->gpio_cs);
+
kfree(chip);
}
@@ -1438,6 +1499,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
master->bus_num = pdev->id;
master->num_chipselect = platform_info->num_chipselect;
+ master->dma_alignment = DMA_ALIGNMENT;
master->cleanup = cleanup;
master->setup = setup;
master->transfer = transfer;
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 643908b74bc..8eba98c8ed1 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -658,7 +658,7 @@ int spi_write_then_read(struct spi_device *spi,
int status;
struct spi_message message;
- struct spi_transfer x;
+ struct spi_transfer x[2];
u8 *local_buf;
/* Use preallocated DMA-safe buffer. We can't avoid copying here,
@@ -669,9 +669,15 @@ int spi_write_then_read(struct spi_device *spi,
return -EINVAL;
spi_message_init(&message);
- memset(&x, 0, sizeof x);
- x.len = n_tx + n_rx;
- spi_message_add_tail(&x, &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);
+ }
/* ... unless someone else is using the pre-allocated buffer */
if (!mutex_trylock(&lock)) {
@@ -682,15 +688,15 @@ int spi_write_then_read(struct spi_device *spi,
local_buf = buf;
memcpy(local_buf, txbuf, n_tx);
- x.tx_buf = local_buf;
- x.rx_buf = local_buf;
+ x[0].tx_buf = local_buf;
+ x[1].rx_buf = local_buf + n_tx;
/* do the i/o */
status = spi_sync(spi, &message);
if (status == 0)
- memcpy(rxbuf, x.rx_buf + n_tx, n_rx);
+ memcpy(rxbuf, x[1].rx_buf, n_rx);
- if (x.tx_buf == buf)
+ if (x[0].tx_buf == buf)
mutex_unlock(&lock);
else
kfree(local_buf);
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 3410b0c55ed..f014cc21e81 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -25,18 +25,17 @@
#include <asm/dma.h>
#include <asm/portmux.h>
#include <asm/bfin5xx_spi.h>
+#include <asm/cacheflush.h>
#define DRV_NAME "bfin-spi"
#define DRV_AUTHOR "Bryan Wu, Luke Yang"
-#define DRV_DESC "Blackfin BF5xx on-chip SPI Controller Driver"
+#define DRV_DESC "Blackfin on-chip SPI Controller Driver"
#define DRV_VERSION "1.0"
MODULE_AUTHOR(DRV_AUTHOR);
MODULE_DESCRIPTION(DRV_DESC);
MODULE_LICENSE("GPL");
-#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07) == 0)
-
#define START_STATE ((void *)0)
#define RUNNING_STATE ((void *)1)
#define DONE_STATE ((void *)2)
@@ -44,6 +43,9 @@ MODULE_LICENSE("GPL");
#define QUEUE_RUNNING 0
#define QUEUE_STOPPED 1
+/* Value to send if no TX value is supplied */
+#define SPI_IDLE_TXVAL 0x0000
+
struct driver_data {
/* Driver model hookup */
struct platform_device *pdev;
@@ -110,6 +112,8 @@ struct chip_data {
u8 bits_per_word; /* 8 or 16 */
u8 cs_change_per_word;
u16 cs_chg_udelay; /* Some devices require > 255usec delay */
+ u32 cs_gpio;
+ u16 idle_tx_val;
void (*write) (struct driver_data *);
void (*read) (struct driver_data *);
void (*duplex) (struct driver_data *);
@@ -154,10 +158,13 @@ static u16 hz_to_spi_baud(u32 speed_hz)
if ((sclk % (2 * speed_hz)) > 0)
spi_baud++;
+ if (spi_baud < MIN_SPI_BAUD_VAL)
+ spi_baud = MIN_SPI_BAUD_VAL;
+
return spi_baud;
}
-static int flush(struct driver_data *drv_data)
+static int bfin_spi_flush(struct driver_data *drv_data)
{
unsigned long limit = loops_per_jiffy << 1;
@@ -171,33 +178,40 @@ static int flush(struct driver_data *drv_data)
}
/* Chip select operation functions for cs_change flag */
-static void cs_active(struct driver_data *drv_data, struct chip_data *chip)
+static void bfin_spi_cs_active(struct driver_data *drv_data, struct chip_data *chip)
{
- u16 flag = read_FLAG(drv_data);
+ if (likely(chip->chip_select_num)) {
+ u16 flag = read_FLAG(drv_data);
- flag |= chip->flag;
- flag &= ~(chip->flag << 8);
+ flag |= chip->flag;
+ flag &= ~(chip->flag << 8);
- write_FLAG(drv_data, flag);
+ write_FLAG(drv_data, flag);
+ } else {
+ gpio_set_value(chip->cs_gpio, 0);
+ }
}
-static void cs_deactive(struct driver_data *drv_data, struct chip_data *chip)
+static void bfin_spi_cs_deactive(struct driver_data *drv_data, struct chip_data *chip)
{
- u16 flag = read_FLAG(drv_data);
+ if (likely(chip->chip_select_num)) {
+ u16 flag = read_FLAG(drv_data);
- flag |= (chip->flag << 8);
+ flag &= ~chip->flag;
+ flag |= (chip->flag << 8);
- write_FLAG(drv_data, flag);
+ write_FLAG(drv_data, flag);
+ } else {
+ gpio_set_value(chip->cs_gpio, 1);
+ }
/* Move delay here for consistency */
if (chip->cs_chg_udelay)
udelay(chip->cs_chg_udelay);
}
-#define MAX_SPI_SSEL 7
-
/* stop controller and re-config current chip*/
-static void restore_state(struct driver_data *drv_data)
+static void bfin_spi_restore_state(struct driver_data *drv_data)
{
struct chip_data *chip = drv_data->cur_chip;
@@ -211,294 +225,256 @@ static void restore_state(struct driver_data *drv_data)
write_BAUD(drv_data, chip->baud);
bfin_spi_enable(drv_data);
- cs_active(drv_data, chip);
+ bfin_spi_cs_active(drv_data, chip);
}
-/* used to kick off transfer in rx mode */
-static unsigned short dummy_read(struct driver_data *drv_data)
+/* used to kick off transfer in rx mode and read unwanted RX data */
+static inline void bfin_spi_dummy_read(struct driver_data *drv_data)
{
- unsigned short tmp;
- tmp = read_RDBR(drv_data);
- return tmp;
+ (void) read_RDBR(drv_data);
}
-static void null_writer(struct driver_data *drv_data)
+static void bfin_spi_null_writer(struct driver_data *drv_data)
{
u8 n_bytes = drv_data->n_bytes;
+ u16 tx_val = drv_data->cur_chip->idle_tx_val;
+
+ /* clear RXS (we check for RXS inside the loop) */
+ bfin_spi_dummy_read(drv_data);
while (drv_data->tx < drv_data->tx_end) {
- write_TDBR(drv_data, 0);
- while ((read_STAT(drv_data) & BIT_STAT_TXS))
- cpu_relax();
+ write_TDBR(drv_data, tx_val);
drv_data->tx += n_bytes;
+ /* wait until transfer finished.
+ checking SPIF or TXS may not guarantee transfer completion */
+ while (!(read_STAT(drv_data) & BIT_STAT_RXS))
+ cpu_relax();
+ /* discard RX data and clear RXS */
+ bfin_spi_dummy_read(drv_data);
}
}
-static void null_reader(struct driver_data *drv_data)
+static void bfin_spi_null_reader(struct driver_data *drv_data)
{
u8 n_bytes = drv_data->n_bytes;
- dummy_read(drv_data);
+ u16 tx_val = drv_data->cur_chip->idle_tx_val;
+
+ /* discard old RX data and clear RXS */
+ bfin_spi_dummy_read(drv_data);
while (drv_data->rx < drv_data->rx_end) {
+ write_TDBR(drv_data, tx_val);
+ drv_data->rx += n_bytes;
while (!(read_STAT(drv_data) & BIT_STAT_RXS))
cpu_relax();
- dummy_read(drv_data);
- drv_data->rx += n_bytes;
+ bfin_spi_dummy_read(drv_data);
}
}
-static void u8_writer(struct driver_data *drv_data)
+static void bfin_spi_u8_writer(struct driver_data *drv_data)
{
- dev_dbg(&drv_data->pdev->dev,
- "cr8-s is 0x%x\n", read_STAT(drv_data));
+ /* clear RXS (we check for RXS inside the loop) */
+ bfin_spi_dummy_read(drv_data);
while (drv_data->tx < drv_data->tx_end) {
- write_TDBR(drv_data, (*(u8 *) (drv_data->tx)));
- while (read_STAT(drv_data) & BIT_STAT_TXS)
+ write_TDBR(drv_data, (*(u8 *) (drv_data->tx++)));
+ /* wait until transfer finished.
+ checking SPIF or TXS may not guarantee transfer completion */
+ while (!(read_STAT(drv_data) & BIT_STAT_RXS))
cpu_relax();
- ++drv_data->tx;
+ /* discard RX data and clear RXS */
+ bfin_spi_dummy_read(drv_data);
}
-
- /* poll for SPI completion before return */
- while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
- cpu_relax();
}
-static void u8_cs_chg_writer(struct driver_data *drv_data)
+static void bfin_spi_u8_cs_chg_writer(struct driver_data *drv_data)
{
struct chip_data *chip = drv_data->cur_chip;
- while (drv_data->tx < drv_data->tx_end) {
- cs_active(drv_data, chip);
+ /* clear RXS (we check for RXS inside the loop) */
+ bfin_spi_dummy_read(drv_data);
- write_TDBR(drv_data, (*(u8 *) (drv_data->tx)));
- while (read_STAT(drv_data) & BIT_STAT_TXS)
- cpu_relax();
- while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
+ while (drv_data->tx < drv_data->tx_end) {
+ bfin_spi_cs_active(drv_data, chip);
+ write_TDBR(drv_data, (*(u8 *) (drv_data->tx++)));
+ /* make sure transfer finished before deactiving CS */
+ while (!(read_STAT(drv_data) & BIT_STAT_RXS))
cpu_relax();
-
- cs_deactive(drv_data, chip);
-
- ++drv_data->tx;
+ bfin_spi_dummy_read(drv_data);
+ bfin_spi_cs_deactive(drv_data, chip);
}
}
-static void u8_reader(struct driver_data *drv_data)
+static void bfin_spi_u8_reader(struct driver_data *drv_data)
{
- dev_dbg(&drv_data->pdev->dev,
- "cr-8 is 0x%x\n", read_STAT(drv_data));
-
- /* poll for SPI completion before start */
- while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
- cpu_relax();
+ u16 tx_val = drv_data->cur_chip->idle_tx_val;
- /* clear TDBR buffer before read(else it will be shifted out) */
- write_TDBR(drv_data, 0xFFFF);
+ /* discard old RX data and clear RXS */
+ bfin_spi_dummy_read(drv_data);
- dummy_read(drv_data);
-
- while (drv_data->rx < drv_data->rx_end - 1) {
+ while (drv_data->rx < drv_data->rx_end) {
+ write_TDBR(drv_data, tx_val);
while (!(read_STAT(drv_data) & BIT_STAT_RXS))
cpu_relax();
- *(u8 *) (drv_data->rx) = read_RDBR(drv_data);
- ++drv_data->rx;
+ *(u8 *) (drv_data->rx++) = read_RDBR(drv_data);
}
-
- while (!(read_STAT(drv_data) & BIT_STAT_RXS))
- cpu_relax();
- *(u8 *) (drv_data->rx) = read_SHAW(drv_data);
- ++drv_data->rx;
}
-static void u8_cs_chg_reader(struct driver_data *drv_data)
+static void bfin_spi_u8_cs_chg_reader(struct driver_data *drv_data)
{
struct chip_data *chip = drv_data->cur_chip;
+ u16 tx_val = chip->idle_tx_val;
- while (drv_data->rx < drv_data->rx_end) {
- cs_active(drv_data, chip);
- read_RDBR(drv_data); /* kick off */
+ /* discard old RX data and clear RXS */
+ bfin_spi_dummy_read(drv_data);
+ while (drv_data->rx < drv_data->rx_end) {
+ bfin_spi_cs_active(drv_data, chip);
+ write_TDBR(drv_data, tx_val);
while (!(read_STAT(drv_data) & BIT_STAT_RXS))
cpu_relax();
- while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
- cpu_relax();
-
- *(u8 *) (drv_data->rx) = read_SHAW(drv_data);
- cs_deactive(drv_data, chip);
-
- ++drv_data->rx;
+ *(u8 *) (drv_data->rx++) = read_RDBR(drv_data);
+ bfin_spi_cs_deactive(drv_data, chip);
}
}
-static void u8_duplex(struct driver_data *drv_data)
+static void bfin_spi_u8_duplex(struct driver_data *drv_data)
{
- /* in duplex mode, clk is triggered by writing of TDBR */
+ /* discard old RX data and clear RXS */
+ bfin_spi_dummy_read(drv_data);
+
while (drv_data->rx < drv_data->rx_end) {
- write_TDBR(drv_data, (*(u8 *) (drv_data->tx)));
- while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
- cpu_relax();
+ write_TDBR(drv_data, (*(u8 *) (drv_data->tx++)));
while (!(read_STAT(drv_data) & BIT_STAT_RXS))
cpu_relax();
- *(u8 *) (drv_data->rx) = read_RDBR(drv_data);
- ++drv_data->rx;
- ++drv_data->tx;
+ *(u8 *) (drv_data->rx++) = read_RDBR(drv_data);
}
}
-static void u8_cs_chg_duplex(struct driver_data *drv_data)
+static void bfin_spi_u8_cs_chg_duplex(struct driver_data *drv_data)
{
struct chip_data *chip = drv_data->cur_chip;
- while (drv_data->rx < drv_data->rx_end) {
- cs_active(drv_data, chip);
-
- write_TDBR(drv_data, (*(u8 *) (drv_data->tx)));
+ /* discard old RX data and clear RXS */
+ bfin_spi_dummy_read(drv_data);
- while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
- cpu_relax();
+ while (drv_data->rx < drv_data->rx_end) {
+ bfin_spi_cs_active(drv_data, chip);
+ write_TDBR(drv_data, (*(u8 *) (drv_data->tx++)));
while (!(read_STAT(drv_data) & BIT_STAT_RXS))
cpu_relax();
- *(u8 *) (drv_data->rx) = read_RDBR(drv_data);
-
- cs_deactive(drv_data, chip);
-
- ++drv_data->rx;
- ++drv_data->tx;
+ *(u8 *) (drv_data->rx++) = read_RDBR(drv_data);
+ bfin_spi_cs_deactive(drv_data, chip);
}
}
-static void u16_writer(struct driver_data *drv_data)
+static void bfin_spi_u16_writer(struct driver_data *drv_data)
{
- dev_dbg(&drv_data->pdev->dev,
- "cr16 is 0x%x\n", read_STAT(drv_data));
+ /* clear RXS (we check for RXS inside the loop) */
+ bfin_spi_dummy_read(drv_data);
while (drv_data->tx < drv_data->tx_end) {
write_TDBR(drv_data, (*(u16 *) (drv_data->tx)));
- while ((read_STAT(drv_data) & BIT_STAT_TXS))
- cpu_relax();
drv_data->tx += 2;
+ /* wait until transfer finished.
+ checking SPIF or TXS may not guarantee transfer completion */
+ while (!(read_STAT(drv_data) & BIT_STAT_RXS))
+ cpu_relax();
+ /* discard RX data and clear RXS */
+ bfin_spi_dummy_read(drv_data);
}
-
- /* poll for SPI completion before return */
- while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
- cpu_relax();
}
-static void u16_cs_chg_writer(struct driver_data *drv_data)
+static void bfin_spi_u16_cs_chg_writer(struct driver_data *drv_data)
{
struct chip_data *chip = drv_data->cur_chip;
- while (drv_data->tx < drv_data->tx_end) {
- cs_active(drv_data, chip);
+ /* clear RXS (we check for RXS inside the loop) */
+ bfin_spi_dummy_read(drv_data);
+ while (drv_data->tx < drv_data->tx_end) {
+ bfin_spi_cs_active(drv_data, chip);
write_TDBR(drv_data, (*(u16 *) (drv_data->tx)));
- while ((read_STAT(drv_data) & BIT_STAT_TXS))
- cpu_relax();
- while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
- cpu_relax();
-
- cs_deactive(drv_data, chip);
-
drv_data->tx += 2;
+ /* make sure transfer finished before deactiving CS */
+ while (!(read_STAT(drv_data) & BIT_STAT_RXS))
+ cpu_relax();
+ bfin_spi_dummy_read(drv_data);
+ bfin_spi_cs_deactive(drv_data, chip);
}
}
-static void u16_reader(struct driver_data *drv_data)
+static void bfin_spi_u16_reader(struct driver_data *drv_data)
{
- dev_dbg(&drv_data->pdev->dev,
- "cr-16 is 0x%x\n", read_STAT(drv_data));
-
- /* poll for SPI completion before start */
- while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
- cpu_relax();
-
- /* clear TDBR buffer before read(else it will be shifted out) */
- write_TDBR(drv_data, 0xFFFF);
+ u16 tx_val = drv_data->cur_chip->idle_tx_val;
- dummy_read(drv_data);
+ /* discard old RX data and clear RXS */
+ bfin_spi_dummy_read(drv_data);
- while (drv_data->rx < (drv_data->rx_end - 2)) {
+ while (drv_data->rx < drv_data->rx_end) {
+ write_TDBR(drv_data, tx_val);
while (!(read_STAT(drv_data) & BIT_STAT_RXS))
cpu_relax();
*(u16 *) (drv_data->rx) = read_RDBR(drv_data);
drv_data->rx += 2;
}
-
- while (!(read_STAT(drv_data) & BIT_STAT_RXS))
- cpu_relax();
- *(u16 *) (drv_data->rx) = read_SHAW(drv_data);
- drv_data->rx += 2;
}
-static void u16_cs_chg_reader(struct driver_data *drv_data)
+static void bfin_spi_u16_cs_chg_reader(struct driver_data *drv_data)
{
struct chip_data *chip = drv_data->cur_chip;
+ u16 tx_val = chip->idle_tx_val;
- /* poll for SPI completion before start */
- while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
- cpu_relax();
-
- /* clear TDBR buffer before read(else it will be shifted out) */
- write_TDBR(drv_data, 0xFFFF);
-
- cs_active(drv_data, chip);
- dummy_read(drv_data);
-
- while (drv_data->rx < drv_data->rx_end - 2) {
- cs_deactive(drv_data, chip);
+ /* discard old RX data and clear RXS */
+ bfin_spi_dummy_read(drv_data);
+ while (drv_data->rx < drv_data->rx_end) {
+ bfin_spi_cs_active(drv_data, chip);
+ write_TDBR(drv_data, tx_val);
while (!(read_STAT(drv_data) & BIT_STAT_RXS))
cpu_relax();
- cs_active(drv_data, chip);
*(u16 *) (drv_data->rx) = read_RDBR(drv_data);
drv_data->rx += 2;
+ bfin_spi_cs_deactive(drv_data, chip);
}
- cs_deactive(drv_data, chip);
-
- while (!(read_STAT(drv_data) & BIT_STAT_RXS))
- cpu_relax();
- *(u16 *) (drv_data->rx) = read_SHAW(drv_data);
- drv_data->rx += 2;
}
-static void u16_duplex(struct driver_data *drv_data)
+static void bfin_spi_u16_duplex(struct driver_data *drv_data)
{
- /* in duplex mode, clk is triggered by writing of TDBR */
- while (drv_data->tx < drv_data->tx_end) {
+ /* discard old RX data and clear RXS */
+ bfin_spi_dummy_read(drv_data);
+
+ while (drv_data->rx < drv_data->rx_end) {
write_TDBR(drv_data, (*(u16 *) (drv_data->tx)));
- while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
- cpu_relax();
+ drv_data->tx += 2;
while (!(read_STAT(drv_data) & BIT_STAT_RXS))
cpu_relax();
*(u16 *) (drv_data->rx) = read_RDBR(drv_data);
drv_data->rx += 2;
- drv_data->tx += 2;
}
}
-static void u16_cs_chg_duplex(struct driver_data *drv_data)
+static void bfin_spi_u16_cs_chg_duplex(struct driver_data *drv_data)
{
struct chip_data *chip = drv_data->cur_chip;
- while (drv_data->tx < drv_data->tx_end) {
- cs_active(drv_data, chip);
+ /* discard old RX data and clear RXS */
+ bfin_spi_dummy_read(drv_data);
+ while (drv_data->rx < drv_data->rx_end) {
+ bfin_spi_cs_active(drv_data, chip);
write_TDBR(drv_data, (*(u16 *) (drv_data->tx)));
- while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
- cpu_relax();
+ drv_data->tx += 2;
while (!(read_STAT(drv_data) & BIT_STAT_RXS))
cpu_relax();
*(u16 *) (drv_data->rx) = read_RDBR(drv_data);
-
- cs_deactive(drv_data, chip);
-
drv_data->rx += 2;
- drv_data->tx += 2;
+ bfin_spi_cs_deactive(drv_data, chip);
}
}
/* test if ther is more transfer to be done */
-static void *next_transfer(struct driver_data *drv_data)
+static void *bfin_spi_next_transfer(struct driver_data *drv_data)
{
struct spi_message *msg = drv_data->cur_msg;
struct spi_transfer *trans = drv_data->cur_transfer;
@@ -517,7 +493,7 @@ static void *next_transfer(struct driver_data *drv_data)
* caller already set message->status;
* dma and pio irqs are blocked give finished message back
*/
-static void giveback(struct driver_data *drv_data)
+static void bfin_spi_giveback(struct driver_data *drv_data)
{
struct chip_data *chip = drv_data->cur_chip;
struct spi_transfer *last_transfer;
@@ -537,26 +513,30 @@ static void giveback(struct driver_data *drv_data)
msg->state = NULL;
- /* disable chip select signal. And not stop spi in autobuffer mode */
- if (drv_data->tx_dma != 0xFFFF) {
- cs_deactive(drv_data, chip);
- bfin_spi_disable(drv_data);
- }
-
if (!drv_data->cs_change)
- cs_deactive(drv_data, chip);
+ bfin_spi_cs_deactive(drv_data, chip);
+
+ /* Not stop spi in autobuffer mode */
+ if (drv_data->tx_dma != 0xFFFF)
+ bfin_spi_disable(drv_data);
if (msg->complete)
msg->complete(msg->context);
}
-static irqreturn_t dma_irq_handler(int irq, void *dev_id)
+static irqreturn_t bfin_spi_dma_irq_handler(int irq, void *dev_id)
{
struct driver_data *drv_data = dev_id;
struct chip_data *chip = drv_data->cur_chip;
struct spi_message *msg = drv_data->cur_msg;
+ unsigned long timeout;
+ unsigned short dmastat = get_dma_curr_irqstat(drv_data->dma_channel);
+ u16 spistat = read_STAT(drv_data);
+
+ dev_dbg(&drv_data->pdev->dev,
+ "in dma_irq_handler dmastat:0x%x spistat:0x%x\n",
+ dmastat, spistat);
- dev_dbg(&drv_data->pdev->dev, "in dma_irq_handler\n");
clear_dma_irqstat(drv_data->dma_channel);
/* Wait for DMA to complete */
@@ -575,16 +555,30 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
cpu_relax();
}
+ dev_dbg(&drv_data->pdev->dev,
+ "in dma_irq_handler dmastat:0x%x spistat:0x%x\n",
+ dmastat, read_STAT(drv_data));
+
+ timeout = jiffies + HZ;
while (!(read_STAT(drv_data) & SPIF))
- cpu_relax();
+ if (!time_before(jiffies, timeout)) {
+ dev_warn(&drv_data->pdev->dev, "timeout waiting for SPIF");
+ break;
+ } else
+ cpu_relax();
- msg->actual_length += drv_data->len_in_bytes;
+ if ((dmastat & DMA_ERR) && (spistat & RBSY)) {
+ msg->state = ERROR_STATE;
+ dev_err(&drv_data->pdev->dev, "dma receive: fifo/buffer overflow\n");
+ } else {
+ msg->actual_length += drv_data->len_in_bytes;
- if (drv_data->cs_change)
- cs_deactive(drv_data, chip);
+ if (drv_data->cs_change)
+ bfin_spi_cs_deactive(drv_data, chip);
- /* Move to next transfer */
- msg->state = next_transfer(drv_data);
+ /* Move to next transfer */
+ msg->state = bfin_spi_next_transfer(drv_data);
+ }
/* Schedule transfer tasklet */
tasklet_schedule(&drv_data->pump_transfers);
@@ -598,7 +592,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void pump_transfers(unsigned long data)
+static void bfin_spi_pump_transfers(unsigned long data)
{
struct driver_data *drv_data = (struct driver_data *)data;
struct spi_message *message = NULL;
@@ -621,20 +615,23 @@ static void pump_transfers(unsigned long data)
/* Handle for abort */
if (message->state == ERROR_STATE) {
+ dev_dbg(&drv_data->pdev->dev, "transfer: we've hit an error\n");
message->status = -EIO;
- giveback(drv_data);
+ bfin_spi_giveback(drv_data);
return;
}
/* Handle end of message */
if (message->state == DONE_STATE) {
+ dev_dbg(&drv_data->pdev->dev, "transfer: all done!\n");
message->status = 0;
- giveback(drv_data);
+ bfin_spi_giveback(drv_data);
return;
}
/* Delay if requested at end of transfer */
if (message->state == RUNNING_STATE) {
+ dev_dbg(&drv_data->pdev->dev, "transfer: still running ...\n");
previous = list_entry(transfer->transfer_list.prev,
struct spi_transfer, transfer_list);
if (previous->delay_usecs)
@@ -642,13 +639,20 @@ static void pump_transfers(unsigned long data)
}
/* Setup the transfer state based on the type of transfer */
- if (flush(drv_data) == 0) {
+ if (bfin_spi_flush(drv_data) == 0) {
dev_err(&drv_data->pdev->dev, "pump_transfers: flush failed\n");
message->status = -EIO;
- giveback(drv_data);
+ bfin_spi_giveback(drv_data);
return;
}
+ if (transfer->len == 0) {
+ /* Move to next transfer of this msg */
+ message->state = bfin_spi_next_transfer(drv_data);
+ /* Schedule next transfer tasklet */
+ tasklet_schedule(&drv_data->pump_transfers);
+ }
+
if (transfer->tx_buf != NULL) {
drv_data->tx = (void *)transfer->tx_buf;
drv_data->tx_end = drv_data->tx + transfer->len;
@@ -679,31 +683,31 @@ static void pump_transfers(unsigned long data)
drv_data->n_bytes = 1;
width = CFG_SPI_WORDSIZE8;
drv_data->read = chip->cs_change_per_word ?
- u8_cs_chg_reader : u8_reader;
+ bfin_spi_u8_cs_chg_reader : bfin_spi_u8_reader;
drv_data->write = chip->cs_change_per_word ?
- u8_cs_chg_writer : u8_writer;
+ bfin_spi_u8_cs_chg_writer : bfin_spi_u8_writer;
drv_data->duplex = chip->cs_change_per_word ?
- u8_cs_chg_duplex : u8_duplex;
+ bfin_spi_u8_cs_chg_duplex : bfin_spi_u8_duplex;
break;
case 16:
drv_data->n_bytes = 2;
width = CFG_SPI_WORDSIZE16;
drv_data->read = chip->cs_change_per_word ?
- u16_cs_chg_reader : u16_reader;
+ bfin_spi_u16_cs_chg_reader : bfin_spi_u16_reader;
drv_data->write = chip->cs_change_per_word ?
- u16_cs_chg_writer : u16_writer;
+ bfin_spi_u16_cs_chg_writer : bfin_spi_u16_writer;
drv_data->duplex = chip->cs_change_per_word ?
- u16_cs_chg_duplex : u16_duplex;
+ bfin_spi_u16_cs_chg_duplex : bfin_spi_u16_duplex;
break;
default:
/* No change, the same as default setting */
drv_data->n_bytes = chip->n_bytes;
width = chip->width;
- drv_data->write = drv_data->tx ? chip->write : null_writer;
- drv_data->read = drv_data->rx ? chip->read : null_reader;
- drv_data->duplex = chip->duplex ? chip->duplex : null_writer;
+ drv_data->write = drv_data->tx ? chip->write : bfin_spi_null_writer;
+ drv_data->read = drv_data->rx ? chip->read : bfin_spi_null_reader;
+ drv_data->duplex = chip->duplex ? chip->duplex : bfin_spi_null_writer;
break;
}
cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD));
@@ -717,7 +721,7 @@ static void pump_transfers(unsigned long data)
}
dev_dbg(&drv_data->pdev->dev,
"transfer: drv_data->write is %p, chip->write is %p, null_wr is %p\n",
- drv_data->write, chip->write, null_writer);
+ drv_data->write, chip->write, bfin_spi_null_writer);
/* speed and width has been set on per message */
message->state = RUNNING_STATE;
@@ -731,32 +735,34 @@ static void pump_transfers(unsigned long data)
write_STAT(drv_data, BIT_STAT_CLR);
cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD));
- cs_active(drv_data, chip);
+ if (drv_data->cs_change)
+ bfin_spi_cs_active(drv_data, chip);
dev_dbg(&drv_data->pdev->dev,
"now pumping a transfer: width is %d, len is %d\n",
width, transfer->len);
/*
- * Try to map dma buffer and do a dma transfer if
- * successful use different way to r/w according to
- * drv_data->cur_chip->enable_dma
+ * Try to map dma buffer and do a dma transfer. If successful use,
+ * different way to r/w according to the enable_dma settings and if
+ * we are not doing a full duplex transfer (since the hardware does
+ * not support full duplex DMA transfers).
*/
if (!full_duplex && drv_data->cur_chip->enable_dma
&& drv_data->len > 6) {
+ unsigned long dma_start_addr, flags;
+
disable_dma(drv_data->dma_channel);
clear_dma_irqstat(drv_data->dma_channel);
- bfin_spi_disable(drv_data);
/* config dma channel */
dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n");
+ set_dma_x_count(drv_data->dma_channel, drv_data->len);
if (width == CFG_SPI_WORDSIZE16) {
- set_dma_x_count(drv_data->dma_channel, drv_data->len);
set_dma_x_modify(drv_data->dma_channel, 2);
dma_width = WDSIZE_16;
} else {
- set_dma_x_count(drv_data->dma_channel, drv_data->len);
set_dma_x_modify(drv_data->dma_channel, 1);
dma_width = WDSIZE_8;
}
@@ -779,58 +785,75 @@ static void pump_transfers(unsigned long data)
enable_dma(drv_data->dma_channel);
/* start SPI transfer */
- write_CTRL(drv_data,
- (cr | CFG_SPI_DMAWRITE | BIT_CTL_ENABLE));
+ write_CTRL(drv_data, cr | BIT_CTL_TIMOD_DMA_TX);
/* just return here, there can only be one transfer
* in this mode
*/
message->status = 0;
- giveback(drv_data);
+ bfin_spi_giveback(drv_data);
return;
}
/* In dma mode, rx or tx must be NULL in one transfer */
+ dma_config = (RESTART | dma_width | DI_EN);
if (drv_data->rx != NULL) {
/* set transfer mode, and enable SPI */
- dev_dbg(&drv_data->pdev->dev, "doing DMA in.\n");
+ dev_dbg(&drv_data->pdev->dev, "doing DMA in to %p (size %zx)\n",
+ drv_data->rx, drv_data->len_in_bytes);
- /* clear tx reg soformer data is not shifted out */
- write_TDBR(drv_data, 0xFFFF);
+ /* invalidate caches, if needed */
+ if (bfin_addr_dcachable((unsigned long) drv_data->rx))
+ invalidate_dcache_range((unsigned long) drv_data->rx,
+ (unsigned long) (drv_data->rx +
+ drv_data->len_in_bytes));
- set_dma_x_count(drv_data->dma_channel, drv_data->len);
-
- /* start dma */
- dma_enable_irq(drv_data->dma_channel);
- dma_config = (WNR | RESTART | dma_width | DI_EN);
- set_dma_config(drv_data->dma_channel, dma_config);
- set_dma_start_addr(drv_data->dma_channel,
- (unsigned long)drv_data->rx);
- enable_dma(drv_data->dma_channel);
-
- /* start SPI transfer */
- write_CTRL(drv_data,
- (cr | CFG_SPI_DMAREAD | BIT_CTL_ENABLE));
+ dma_config |= WNR;
+ dma_start_addr = (unsigned long)drv_data->rx;
+ cr |= BIT_CTL_TIMOD_DMA_RX | BIT_CTL_SENDOPT;
} else if (drv_data->tx != NULL) {
dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n");
- /* start dma */
- dma_enable_irq(drv_data->dma_channel);
- dma_config = (RESTART | dma_width | DI_EN);
- set_dma_config(drv_data->dma_channel, dma_config);
- set_dma_start_addr(drv_data->dma_channel,
- (unsigned long)drv_data->tx);
- enable_dma(drv_data->dma_channel);
+ /* flush caches, if needed */
+ if (bfin_addr_dcachable((unsigned long) drv_data->tx))
+ flush_dcache_range((unsigned long) drv_data->tx,
+ (unsigned long) (drv_data->tx +
+ drv_data->len_in_bytes));
+
+ dma_start_addr = (unsigned long)drv_data->tx;
+ cr |= BIT_CTL_TIMOD_DMA_TX;
+
+ } else
+ BUG();
+
+ /* oh man, here there be monsters ... and i dont mean the
+ * fluffy cute ones from pixar, i mean the kind that'll eat
+ * your data, kick your dog, and love it all. do *not* try
+ * and change these lines unless you (1) heavily test DMA
+ * with SPI flashes on a loaded system (e.g. ping floods),
+ * (2) know just how broken the DMA engine interaction with
+ * the SPI peripheral is, and (3) have someone else to blame
+ * when you screw it all up anyways.
+ */
+ set_dma_start_addr(drv_data->dma_channel, dma_start_addr);
+ set_dma_config(drv_data->dma_channel, dma_config);
+ local_irq_save(flags);
+ SSYNC();
+ write_CTRL(drv_data, cr);
+ enable_dma(drv_data->dma_channel);
+ dma_enable_irq(drv_data->dma_channel);
+ local_irq_restore(flags);
- /* start SPI transfer */
- write_CTRL(drv_data,
- (cr | CFG_SPI_DMAWRITE | BIT_CTL_ENABLE));
- }
} else {
/* IO mode write then read */
dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n");
+ /* we always use SPI_WRITE mode. SPI_READ mode
+ seems to have problems with setting up the
+ output value in TDBR prior to the transfer. */
+ write_CTRL(drv_data, (cr | CFG_SPI_WRITE));
+
if (full_duplex) {
/* full duplex mode */
BUG_ON((drv_data->tx_end - drv_data->tx) !=
@@ -838,9 +861,6 @@ static void pump_transfers(unsigned long data)
dev_dbg(&drv_data->pdev->dev,
"IO duplex: cr is 0x%x\n", cr);
- /* set SPI transfer mode */
- write_CTRL(drv_data, (cr | CFG_SPI_WRITE));
-
drv_data->duplex(drv_data);
if (drv_data->tx != drv_data->tx_end)
@@ -850,9 +870,6 @@ static void pump_transfers(unsigned long data)
dev_dbg(&drv_data->pdev->dev,
"IO write: cr is 0x%x\n", cr);
- /* set SPI transfer mode */
- write_CTRL(drv_data, (cr | CFG_SPI_WRITE));
-
drv_data->write(drv_data);
if (drv_data->tx != drv_data->tx_end)
@@ -862,9 +879,6 @@ static void pump_transfers(unsigned long data)
dev_dbg(&drv_data->pdev->dev,
"IO read: cr is 0x%x\n", cr);
- /* set SPI transfer mode */
- write_CTRL(drv_data, (cr | CFG_SPI_READ));
-
drv_data->read(drv_data);
if (drv_data->rx != drv_data->rx_end)
tranf_success = 0;
@@ -876,20 +890,19 @@ static void pump_transfers(unsigned long data)
message->state = ERROR_STATE;
} else {
/* Update total byte transfered */
- message->actual_length += drv_data->len;
-
+ message->actual_length += drv_data->len_in_bytes;
/* Move to next transfer of this msg */
- message->state = next_transfer(drv_data);
+ message->state = bfin_spi_next_transfer(drv_data);
+ if (drv_data->cs_change)
+ bfin_spi_cs_deactive(drv_data, chip);
}
-
/* Schedule next transfer tasklet */
tasklet_schedule(&drv_data->pump_transfers);
-
}
}
/* pop a msg from queue and kick off real transfer */
-static void pump_messages(struct work_struct *work)
+static void bfin_spi_pump_messages(struct work_struct *work)
{
struct driver_data *drv_data;
unsigned long flags;
@@ -917,7 +930,7 @@ static void pump_messages(struct work_struct *work)
/* Setup the SSP using the per chip configuration */
drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
- restore_state(drv_data);
+ bfin_spi_restore_state(drv_data);
list_del_init(&drv_data->cur_msg->queue);
@@ -946,7 +959,7 @@ static void pump_messages(struct work_struct *work)
* got a msg to transfer, queue it in drv_data->queue.
* And kick off message pumper
*/
-static int transfer(struct spi_device *spi, struct spi_message *msg)
+static int bfin_spi_transfer(struct spi_device *spi, struct spi_message *msg)
{
struct driver_data *drv_data = spi_master_get_devdata(spi->master);
unsigned long flags;
@@ -975,7 +988,7 @@ static int transfer(struct spi_device *spi, struct spi_message *msg)
#define MAX_SPI_SSEL 7
-static u16 ssel[3][MAX_SPI_SSEL] = {
+static u16 ssel[][MAX_SPI_SSEL] = {
{P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3,
P_SPI0_SSEL4, P_SPI0_SSEL5,
P_SPI0_SSEL6, P_SPI0_SSEL7},
@@ -990,12 +1003,12 @@ static u16 ssel[3][MAX_SPI_SSEL] = {
};
/* first setup for new devices */
-static int setup(struct spi_device *spi)
+static int bfin_spi_setup(struct spi_device *spi)
{
struct bfin5xx_spi_chip *chip_info = NULL;
struct chip_data *chip;
struct driver_data *drv_data = spi_master_get_devdata(spi->master);
- u8 spi_flg;
+ int ret;
/* Abort device setup if requested features are not supported */
if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) {
@@ -1041,6 +1054,8 @@ static int setup(struct spi_device *spi)
chip->bits_per_word = chip_info->bits_per_word;
chip->cs_change_per_word = chip_info->cs_change_per_word;
chip->cs_chg_udelay = chip_info->cs_chg_udelay;
+ chip->cs_gpio = chip_info->cs_gpio;
+ chip->idle_tx_val = chip_info->idle_tx_val;
}
/* translate common spi framework into our register */
@@ -1059,13 +1074,13 @@ static int setup(struct spi_device *spi)
*/
if (chip->enable_dma && !drv_data->dma_requested) {
/* register dma irq handler */
- if (request_dma(drv_data->dma_channel, "BF53x_SPI_DMA") < 0) {
+ if (request_dma(drv_data->dma_channel, "BFIN_SPI_DMA") < 0) {
dev_dbg(&spi->dev,
"Unable to request BlackFin SPI DMA channel\n");
return -ENODEV;
}
if (set_dma_callback(drv_data->dma_channel,
- (void *)dma_irq_handler, drv_data) < 0) {
+ bfin_spi_dma_irq_handler, drv_data) < 0) {
dev_dbg(&spi->dev, "Unable to set dma callback\n");
return -EPERM;
}
@@ -1078,37 +1093,47 @@ static int setup(struct spi_device *spi)
* SPI_BAUD, not the real baudrate
*/
chip->baud = hz_to_spi_baud(spi->max_speed_hz);
- spi_flg = ~(1 << (spi->chip_select));
- chip->flag = ((u16) spi_flg << 8) | (1 << (spi->chip_select));
+ chip->flag = 1 << (spi->chip_select);
chip->chip_select_num = spi->chip_select;
+ if (chip->chip_select_num == 0) {
+ ret = gpio_request(chip->cs_gpio, spi->modalias);
+ if (ret) {
+ if (drv_data->dma_requested)
+ free_dma(drv_data->dma_channel);
+ return ret;
+ }
+ gpio_direction_output(chip->cs_gpio, 1);
+ }
+
switch (chip->bits_per_word) {
case 8:
chip->n_bytes = 1;
chip->width = CFG_SPI_WORDSIZE8;
chip->read = chip->cs_change_per_word ?
- u8_cs_chg_reader : u8_reader;
+ bfin_spi_u8_cs_chg_reader : bfin_spi_u8_reader;
chip->write = chip->cs_change_per_word ?
- u8_cs_chg_writer : u8_writer;
+ bfin_spi_u8_cs_chg_writer : bfin_spi_u8_writer;
chip->duplex = chip->cs_change_per_word ?
- u8_cs_chg_duplex : u8_duplex;
+ bfin_spi_u8_cs_chg_duplex : bfin_spi_u8_duplex;
break;
case 16:
chip->n_bytes = 2;
chip->width = CFG_SPI_WORDSIZE16;
chip->read = chip->cs_change_per_word ?
- u16_cs_chg_reader : u16_reader;
+ bfin_spi_u16_cs_chg_reader : bfin_spi_u16_reader;
chip->write = chip->cs_change_per_word ?
- u16_cs_chg_writer : u16_writer;
+ bfin_spi_u16_cs_chg_writer : bfin_spi_u16_writer;
chip->duplex = chip->cs_change_per_word ?
- u16_cs_chg_duplex : u16_duplex;
+ bfin_spi_u16_cs_chg_duplex : bfin_spi_u16_duplex;
break;
default:
dev_err(&spi->dev, "%d bits_per_word is not supported\n",
chip->bits_per_word);
- kfree(chip);
+ if (chip_info)
+ kfree(chip);
return -ENODEV;
}
@@ -1125,7 +1150,7 @@ static int setup(struct spi_device *spi)
peripheral_request(ssel[spi->master->bus_num]
[chip->chip_select_num-1], spi->modalias);
- cs_deactive(drv_data, chip);
+ bfin_spi_cs_deactive(drv_data, chip);
return 0;
}
@@ -1134,19 +1159,25 @@ static int setup(struct spi_device *spi)
* callback for spi framework.
* clean driver specific data
*/
-static void cleanup(struct spi_device *spi)
+static void bfin_spi_cleanup(struct spi_device *spi)
{
struct chip_data *chip = spi_get_ctldata(spi);
+ if (!chip)
+ return;
+
if ((chip->chip_select_num > 0)
&& (chip->chip_select_num <= spi->master->num_chipselect))
peripheral_free(ssel[spi->master->bus_num]
[chip->chip_select_num-1]);
+ if (chip->chip_select_num == 0)
+ gpio_free(chip->cs_gpio);
+
kfree(chip);
}
-static inline int init_queue(struct driver_data *drv_data)
+static inline int bfin_spi_init_queue(struct driver_data *drv_data)
{
INIT_LIST_HEAD(&drv_data->queue);
spin_lock_init(&drv_data->lock);
@@ -1156,10 +1187,10 @@ static inline int init_queue(struct driver_data *drv_data)
/* init transfer tasklet */
tasklet_init(&drv_data->pump_transfers,
- pump_transfers, (unsigned long)drv_data);
+ bfin_spi_pump_transfers, (unsigned long)drv_data);
/* init messages workqueue */
- INIT_WORK(&drv_data->pump_messages, pump_messages);
+ INIT_WORK(&drv_data->pump_messages, bfin_spi_pump_messages);
drv_data->workqueue = create_singlethread_workqueue(
dev_name(drv_data->master->dev.parent));
if (drv_data->workqueue == NULL)
@@ -1168,7 +1199,7 @@ static inline int init_queue(struct driver_data *drv_data)
return 0;
}
-static inline int start_queue(struct driver_data *drv_data)
+static inline int bfin_spi_start_queue(struct driver_data *drv_data)
{
unsigned long flags;
@@ -1190,7 +1221,7 @@ static inline int start_queue(struct driver_data *drv_data)
return 0;
}
-static inline int stop_queue(struct driver_data *drv_data)
+static inline int bfin_spi_stop_queue(struct driver_data *drv_data)
{
unsigned long flags;
unsigned limit = 500;
@@ -1219,11 +1250,11 @@ static inline int stop_queue(struct driver_data *drv_data)
return status;
}
-static inline int destroy_queue(struct driver_data *drv_data)
+static inline int bfin_spi_destroy_queue(struct driver_data *drv_data)
{
int status;
- status = stop_queue(drv_data);
+ status = bfin_spi_stop_queue(drv_data);
if (status != 0)
return status;
@@ -1232,7 +1263,7 @@ static inline int destroy_queue(struct driver_data *drv_data)
return 0;
}
-static int __init bfin5xx_spi_probe(struct platform_device *pdev)
+static int __init bfin_spi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct bfin5xx_spi_master *platform_info;
@@ -1258,9 +1289,9 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
master->bus_num = pdev->id;
master->num_chipselect = platform_info->num_chipselect;
- master->cleanup = cleanup;
- master->setup = setup;
- master->transfer = transfer;
+ master->cleanup = bfin_spi_cleanup;
+ master->setup = bfin_spi_setup;
+ master->transfer = bfin_spi_transfer;
/* Find and map our resources */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1285,13 +1316,13 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
}
/* Initial and start queue */
- status = init_queue(drv_data);
+ status = bfin_spi_init_queue(drv_data);
if (status != 0) {
dev_err(dev, "problem initializing queue\n");
goto out_error_queue_alloc;
}
- status = start_queue(drv_data);
+ status = bfin_spi_start_queue(drv_data);
if (status != 0) {
dev_err(dev, "problem starting queue\n");
goto out_error_queue_alloc;
@@ -1317,7 +1348,7 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
return status;
out_error_queue_alloc:
- destroy_queue(drv_data);
+ bfin_spi_destroy_queue(drv_data);
out_error_no_dma_ch:
iounmap((void *) drv_data->regs_base);
out_error_ioremap:
@@ -1328,7 +1359,7 @@ out_error_get_res:
}
/* stop hardware and remove the driver */
-static int __devexit bfin5xx_spi_remove(struct platform_device *pdev)
+static int __devexit bfin_spi_remove(struct platform_device *pdev)
{
struct driver_data *drv_data = platform_get_drvdata(pdev);
int status = 0;
@@ -1337,7 +1368,7 @@ static int __devexit bfin5xx_spi_remove(struct platform_device *pdev)
return 0;
/* Remove the queue */
- status = destroy_queue(drv_data);
+ status = bfin_spi_destroy_queue(drv_data);
if (status != 0)
return status;
@@ -1362,12 +1393,12 @@ static int __devexit bfin5xx_spi_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
-static int bfin5xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
+static int bfin_spi_suspend(struct platform_device *pdev, pm_message_t state)
{
struct driver_data *drv_data = platform_get_drvdata(pdev);
int status = 0;
- status = stop_queue(drv_data);
+ status = bfin_spi_stop_queue(drv_data);
if (status != 0)
return status;
@@ -1377,7 +1408,7 @@ static int bfin5xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
return 0;
}
-static int bfin5xx_spi_resume(struct platform_device *pdev)
+static int bfin_spi_resume(struct platform_device *pdev)
{
struct driver_data *drv_data = platform_get_drvdata(pdev);
int status = 0;
@@ -1386,7 +1417,7 @@ static int bfin5xx_spi_resume(struct platform_device *pdev)
bfin_spi_enable(drv_data);
/* Start the queue running */
- status = start_queue(drv_data);
+ status = bfin_spi_start_queue(drv_data);
if (status != 0) {
dev_err(&pdev->dev, "problem starting queue (%d)\n", status);
return status;
@@ -1395,29 +1426,29 @@ static int bfin5xx_spi_resume(struct platform_device *pdev)
return 0;
}
#else
-#define bfin5xx_spi_suspend NULL
-#define bfin5xx_spi_resume NULL
+#define bfin_spi_suspend NULL
+#define bfin_spi_resume NULL
#endif /* CONFIG_PM */
MODULE_ALIAS("platform:bfin-spi");
-static struct platform_driver bfin5xx_spi_driver = {
+static struct platform_driver bfin_spi_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
},
- .suspend = bfin5xx_spi_suspend,
- .resume = bfin5xx_spi_resume,
- .remove = __devexit_p(bfin5xx_spi_remove),
+ .suspend = bfin_spi_suspend,
+ .resume = bfin_spi_resume,
+ .remove = __devexit_p(bfin_spi_remove),
};
-static int __init bfin5xx_spi_init(void)
+static int __init bfin_spi_init(void)
{
- return platform_driver_probe(&bfin5xx_spi_driver, bfin5xx_spi_probe);
+ return platform_driver_probe(&bfin_spi_driver, bfin_spi_probe);
}
-module_init(bfin5xx_spi_init);
+module_init(bfin_spi_init);
-static void __exit bfin5xx_spi_exit(void)
+static void __exit bfin_spi_exit(void)
{
- platform_driver_unregister(&bfin5xx_spi_driver);
+ platform_driver_unregister(&bfin_spi_driver);
}
-module_exit(bfin5xx_spi_exit);
+module_exit(bfin_spi_exit);
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index 0480d8bb19d..0671aeef579 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -186,6 +186,7 @@
#define QUEUE_STOPPED (1)
#define IS_DMA_ALIGNED(x) (((u32)(x) & 0x03) == 0)
+#define DMA_ALIGNMENT 4
/*-------------------------------------------------------------------------*/
@@ -779,7 +780,8 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
/* Read trailing bytes */
limit = loops_per_jiffy << 1;
- while ((read(drv_data) == 0) && limit--);
+ while ((read(drv_data) == 0) && --limit)
+ cpu_relax();
if (limit == 0)
dev_err(&drv_data->pdev->dev,
@@ -1481,6 +1483,7 @@ static int __init spi_imx_probe(struct platform_device *pdev)
master->bus_num = pdev->id;
master->num_chipselect = platform_info->num_chipselect;
+ master->dma_alignment = DMA_ALIGNMENT;
master->cleanup = cleanup;
master->setup = setup;
master->transfer = transfer;
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 211af86a6c5..0dcf9ca0b0a 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -4,7 +4,7 @@ menuconfig STAGING
---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
+ are placed here in order to get a wider audience to make 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
@@ -12,7 +12,7 @@ menuconfig STAGING
Using any of these drivers will taint your kernel which might
affect support options from both the community, and various
- commercial support orginizations.
+ commercial support organizations.
If you wish to work on these drivers, to help improve them, or
to report problems you have with them, please see the
@@ -73,6 +73,8 @@ source "drivers/staging/rt2860/Kconfig"
source "drivers/staging/rt2870/Kconfig"
+source "drivers/staging/rt3070/Kconfig"
+
source "drivers/staging/comedi/Kconfig"
source "drivers/staging/asus_oled/Kconfig"
@@ -93,5 +95,25 @@ source "drivers/staging/epl/Kconfig"
source "drivers/staging/android/Kconfig"
+source "drivers/staging/dst/Kconfig"
+
+source "drivers/staging/pohmelfs/Kconfig"
+
+source "drivers/staging/stlc45xx/Kconfig"
+
+source "drivers/staging/uc2322/Kconfig"
+
+source "drivers/staging/b3dfg/Kconfig"
+
+source "drivers/staging/phison/Kconfig"
+
+source "drivers/staging/p9auth/Kconfig"
+
+source "drivers/staging/heci/Kconfig"
+
+source "drivers/staging/line6/Kconfig"
+
+source "drivers/staging/serqt_usb/Kconfig"
+
endif # !STAGING_EXCLUDE_BUILD
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 47a56f5ffab..47dfd5b4288 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_AGNX) += agnx/
obj-$(CONFIG_OTUS) += otus/
obj-$(CONFIG_RT2860) += rt2860/
obj-$(CONFIG_RT2870) += rt2870/
+obj-$(CONFIG_RT3070) += rt3070/
obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_ASUS_OLED) += asus_oled/
obj-$(CONFIG_PANEL) += panel/
@@ -29,3 +30,13 @@ obj-$(CONFIG_INPUT_MIMIO) += mimio/
obj-$(CONFIG_TRANZPORT) += frontier/
obj-$(CONFIG_EPL) += epl/
obj-$(CONFIG_ANDROID) += android/
+obj-$(CONFIG_DST) += dst/
+obj-$(CONFIG_POHMELFS) += pohmelfs/
+obj-$(CONFIG_STLC45XX) += stlc45xx/
+obj-$(CONFIG_USB_SERIAL_ATEN2011) += uc2322/
+obj-$(CONFIG_B3DFG) += b3dfg/
+obj-$(CONFIG_IDE_PHISON) += phison/
+obj-$(CONFIG_PLAN9AUTH) += p9auth/
+obj-$(CONFIG_HECI) += heci/
+obj-$(CONFIG_LINE6_USB) += line6/
+obj-$(CONFIG_USB_SERIAL_QUATECH_ESU100) += serqt_usb/
diff --git a/drivers/staging/agnx/agnx.h b/drivers/staging/agnx/agnx.h
index 20f36da6247..3963d2597a1 100644
--- a/drivers/staging/agnx/agnx.h
+++ b/drivers/staging/agnx/agnx.h
@@ -41,16 +41,16 @@ static const struct ieee80211_rate agnx_rates_80211g[] = {
/* { .bitrate = 20, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
/* { .bitrate = 55, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
/* { .bitrate = 110, .hw_value = 4, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
- { .bitrate = 10, .hw_value = 1, },
- { .bitrate = 20, .hw_value = 2, },
- { .bitrate = 55, .hw_value = 3, },
- { .bitrate = 110, .hw_value = 4,},
+ { .bitrate = 10, .hw_value = 1, },
+ { .bitrate = 20, .hw_value = 2, },
+ { .bitrate = 55, .hw_value = 3, },
+ { .bitrate = 110, .hw_value = 4,},
{ .bitrate = 60, .hw_value = 0xB, },
{ .bitrate = 90, .hw_value = 0xF, },
{ .bitrate = 120, .hw_value = 0xA },
{ .bitrate = 180, .hw_value = 0xE, },
-// { .bitrate = 240, .hw_value = 0xd, },
+/* { .bitrate = 240, .hw_value = 0xd, }, */
{ .bitrate = 360, .hw_value = 0xD, },
{ .bitrate = 480, .hw_value = 0x8, },
{ .bitrate = 540, .hw_value = 0xC, },
@@ -110,10 +110,10 @@ struct agnx_priv {
/* Need volatile? */
u32 irq_status;
- struct delayed_work periodic_work; /* Periodic tasks like recalibrate*/
+ struct delayed_work periodic_work; /* Periodic tasks like recalibrate */
struct ieee80211_low_level_stats stats;
-// unsigned int phymode;
+ /* unsigned int phymode; */
int mode;
int channel;
u8 bssid[ETH_ALEN];
diff --git a/drivers/staging/agnx/debug.h b/drivers/staging/agnx/debug.h
index e3e25dda0ba..761d99c2d3f 100644
--- a/drivers/staging/agnx/debug.h
+++ b/drivers/staging/agnx/debug.h
@@ -23,7 +23,7 @@ static inline void agnx_bug(char *reason)
static inline void agnx_print_desc(struct agnx_desc *desc)
{
- u32 reg = be32_to_cpu(desc->frag);
+ u32 reg = be32_to_cpu(desc->frag);
PRINTK_BITS(DESC, PACKET_LEN);
@@ -291,7 +291,7 @@ static inline void agnx_print_sta(struct agnx_priv *priv, unsigned int sta_idx)
PRINTK_LE32(STA, sta->phy_stats_high);
PRINTK_LE32(STA, sta->phy_stats_low);
-// for (i = 0; i < 8; i++)
+ /* for (i = 0; i < 8; i++) */
agnx_print_sta_traffic(sta->traffic + 0);
PRINTK_LE16(STA, sta->traffic_class0_frag_success);
@@ -311,10 +311,10 @@ static inline void agnx_print_sta(struct agnx_priv *priv, unsigned int sta_idx)
static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
{
u16 fctl;
- int hdrlen;
+ int hdrlen;
DECLARE_MAC_BUF(mac);
- fctl = le16_to_cpu(hdr->frame_control);
+ fctl = le16_to_cpu(hdr->frame_control);
switch (fctl & IEEE80211_FCTL_FTYPE) {
case IEEE80211_FTYPE_DATA:
printk(PFX "%s DATA ", tag);
@@ -324,7 +324,7 @@ static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
break;
case IEEE80211_FTYPE_MGMT:
printk(PFX "%s MGMT ", tag);
- switch(fctl & IEEE80211_FCTL_STYPE) {
+ switch (fctl & IEEE80211_FCTL_STYPE) {
case IEEE80211_STYPE_ASSOC_REQ:
printk("SubType: ASSOC_REQ ");
break;
@@ -369,7 +369,7 @@ static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
printk(PFX "%s Packet type: Unknow\n", tag);
}
- hdrlen = ieee80211_hdrlen(fctl);
+ hdrlen = ieee80211_hdrlen(fctl);
if (hdrlen >= 4)
printk("FC=0x%04x DUR=0x%04x",
@@ -389,29 +389,28 @@ static inline void dump_txm_registers(struct agnx_priv *priv)
{
void __iomem *ctl = priv->ctl;
int i;
- for (i = 0; i <=0x1e8; i += 4) {
+ for (i = 0; i <= 0x1e8; i += 4)
printk(KERN_DEBUG PFX "TXM: %x---> 0x%.8x\n", i, ioread32(ctl + i));
- }
}
static inline void dump_rxm_registers(struct agnx_priv *priv)
{
void __iomem *ctl = priv->ctl;
int i;
- for (i = 0; i <=0x108; i += 4)
+ for (i = 0; i <= 0x108; i += 4)
printk(KERN_DEBUG PFX "RXM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2000 + i));
}
static inline void dump_bm_registers(struct agnx_priv *priv)
{
void __iomem *ctl = priv->ctl;
int i;
- for (i = 0; i <=0x90; i += 4)
+ for (i = 0; i <= 0x90; i += 4)
printk(KERN_DEBUG PFX "BM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2c00 + i));
}
static inline void dump_cir_registers(struct agnx_priv *priv)
{
void __iomem *ctl = priv->ctl;
int i;
- for (i = 0; i <=0xb8; i += 4)
+ for (i = 0; i <= 0xb8; i += 4)
printk(KERN_DEBUG PFX "CIR: %x---> 0x%.8x\n", i, ioread32(ctl + 0x3000 + i));
}
diff --git a/drivers/staging/agnx/pci.c b/drivers/staging/agnx/pci.c
index 854630cb527..25c0ffd2faa 100644
--- a/drivers/staging/agnx/pci.c
+++ b/drivers/staging/agnx/pci.c
@@ -39,34 +39,34 @@ static inline void agnx_interrupt_ack(struct agnx_priv *priv, u32 *reason)
void __iomem *ctl = priv->ctl;
u32 reg;
- if ( *reason & AGNX_STAT_RX ) {
+ if (*reason & AGNX_STAT_RX) {
/* Mark complete RX */
reg = ioread32(ctl + AGNX_CIR_RXCTL);
reg |= 0x4;
iowrite32(reg, ctl + AGNX_CIR_RXCTL);
/* disable Rx interrupt */
}
- if ( *reason & AGNX_STAT_TX ) {
+ if (*reason & AGNX_STAT_TX) {
reg = ioread32(ctl + AGNX_CIR_TXDCTL);
if (reg & 0x4) {
iowrite32(reg, ctl + AGNX_CIR_TXDCTL);
*reason |= AGNX_STAT_TXD;
}
- reg = ioread32(ctl + AGNX_CIR_TXMCTL);
+ reg = ioread32(ctl + AGNX_CIR_TXMCTL);
if (reg & 0x4) {
iowrite32(reg, ctl + AGNX_CIR_TXMCTL);
*reason |= AGNX_STAT_TXM;
}
}
- if ( *reason & AGNX_STAT_X ) {
-/* reg = ioread32(ctl + AGNX_INT_STAT); */
-/* iowrite32(reg, ctl + AGNX_INT_STAT); */
-/* /\* FIXME reinit interrupt mask *\/ */
-/* reg = 0xc390bf9 & ~IRQ_TX_BEACON; */
-/* reg &= ~IRQ_TX_DISABLE; */
-/* iowrite32(reg, ctl + AGNX_INT_MASK); */
-/* iowrite32(0x800, ctl + AGNX_CIR_BLKCTL); */
- }
+/* if (*reason & AGNX_STAT_X) {
+ reg = ioread32(ctl + AGNX_INT_STAT);
+ iowrite32(reg, ctl + AGNX_INT_STAT);
+ /* FIXME reinit interrupt mask *\/
+ reg = 0xc390bf9 & ~IRQ_TX_BEACON;
+ reg &= ~IRQ_TX_DISABLE;
+ iowrite32(reg, ctl + AGNX_INT_MASK);
+ iowrite32(0x800, ctl + AGNX_CIR_BLKCTL);
+ } */
} /* agnx_interrupt_ack */
static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
@@ -79,7 +79,7 @@ static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
spin_lock(&priv->lock);
-// printk(KERN_ERR PFX "Get a interrupt %s\n", __func__);
+/* printk(KERN_ERR PFX "Get a interrupt %s\n", __func__); */
if (priv->init_status != AGNX_START)
goto out;
@@ -92,7 +92,7 @@ static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
ret = IRQ_HANDLED;
priv->irq_status = ioread32(ctl + AGNX_INT_STAT);
-// printk(PFX "Interrupt reason is 0x%x\n", irq_reason);
+/* printk(PFX "Interrupt reason is 0x%x\n", irq_reason); */
/* Make sure the txm and txd flags don't conflict with other unknown
interrupt flag, maybe is not necessary */
irq_reason &= 0xF;
@@ -101,13 +101,13 @@ static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
/* TODO Make sure the card finished initialized */
agnx_interrupt_ack(priv, &irq_reason);
- if ( irq_reason & AGNX_STAT_RX )
+ if (irq_reason & AGNX_STAT_RX)
handle_rx_irq(priv);
- if ( irq_reason & AGNX_STAT_TXD )
+ if (irq_reason & AGNX_STAT_TXD)
handle_txd_irq(priv);
- if ( irq_reason & AGNX_STAT_TXM )
+ if (irq_reason & AGNX_STAT_TXM)
handle_txm_irq(priv);
- if ( irq_reason & AGNX_STAT_X )
+ if (irq_reason & AGNX_STAT_X)
handle_other_irq(priv);
enable_rx_interrupt(priv);
@@ -171,7 +171,7 @@ static int agnx_alloc_rings(struct agnx_priv *priv)
len = priv->rx.size + priv->txm.size + priv->txd.size;
-// priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_KERNEL);
+/* priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_KERNEL); */
priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_ATOMIC);
if (!priv->rx.info)
return -ENOMEM;
@@ -210,28 +210,27 @@ static void rings_free(struct agnx_priv *priv)
#if 0
static void agnx_periodic_work_handler(struct work_struct *work)
{
- struct agnx_priv *priv = container_of(work, struct agnx_priv,
- periodic_work.work);
-// unsigned long flags;
+ struct agnx_priv *priv = container_of(work, struct agnx_priv, periodic_work.work);
+/* unsigned long flags; */
unsigned long delay;
/* fixme: using mutex?? */
-// spin_lock_irqsave(&priv->lock, flags);
+/* spin_lock_irqsave(&priv->lock, flags); */
/* TODO Recalibrate*/
-// calibrate_oscillator(priv);
-// antenna_calibrate(priv);
-// agnx_send_packet(priv, 997);
+/* calibrate_oscillator(priv); */
+/* antenna_calibrate(priv); */
+/* agnx_send_packet(priv, 997); /
/* FIXME */
/* if (debug == 3) */
/* delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); */
/* else */
delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY);
-// delay = round_jiffies(HZ * 15);
+/* delay = round_jiffies(HZ * 15); */
queue_delayed_work(priv->hw->workqueue, &priv->periodic_work, delay);
-// spin_unlock_irqrestore(&priv->lock, flags);
+/* spin_unlock_irqrestore(&priv->lock, flags); */
}
#endif
@@ -255,12 +254,12 @@ static int agnx_start(struct ieee80211_hw *dev)
goto out;
}
-// mdelay(500);
+/* mdelay(500); */
might_sleep();
agnx_hw_init(priv);
-// mdelay(500);
+/* mdelay(500); */
might_sleep();
priv->init_status = AGNX_START;
@@ -280,16 +279,16 @@ static void agnx_stop(struct ieee80211_hw *dev)
/* make sure hardware will not generate irq */
agnx_hw_reset(priv);
free_irq(priv->pdev->irq, dev);
- flush_workqueue(priv->hw->workqueue);
-// cancel_delayed_work_sync(&priv->periodic_work);
+ flush_workqueue(priv->hw->workqueue);
+/* cancel_delayed_work_sync(&priv->periodic_work); */
unfill_rings(priv);
rings_free(priv);
}
-static int agnx_config(struct ieee80211_hw *dev,
- struct ieee80211_conf *conf)
+static int agnx_config(struct ieee80211_hw *dev, u32 changed)
{
struct agnx_priv *priv = dev->priv;
+ struct ieee80211_conf *conf = &dev->conf;
int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
AGNX_TRACE;
@@ -315,7 +314,6 @@ static int agnx_config_interface(struct ieee80211_hw *dev,
spin_lock(&priv->lock);
if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
-// u32 reghi, reglo;
agnx_set_bssid(priv, conf->bssid);
memcpy(priv->bssid, conf->bssid, ETH_ALEN);
hash_write(priv, conf->bssid, BSSID_STAID);
@@ -425,7 +423,7 @@ static struct ieee80211_ops agnx_ops = {
.remove_interface = agnx_remove_interface,
.config = agnx_config,
.config_interface = agnx_config_interface,
- .configure_filter = agnx_configure_filter,
+ .configure_filter = agnx_configure_filter,
.get_stats = agnx_get_stats,
.get_tx_stats = agnx_get_tx_stats,
.get_tsf = agnx_get_tsft
@@ -434,11 +432,12 @@ static struct ieee80211_ops agnx_ops = {
static void __devexit agnx_pci_remove(struct pci_dev *pdev)
{
struct ieee80211_hw *dev = pci_get_drvdata(pdev);
- struct agnx_priv *priv = dev->priv;
+ struct agnx_priv *priv;
AGNX_TRACE;
if (!dev)
return;
+ priv = dev->priv;
ieee80211_unregister_hw(dev);
pci_iounmap(pdev, priv->ctl);
pci_iounmap(pdev, priv->data);
@@ -478,8 +477,8 @@ static int __devinit agnx_pci_probe(struct pci_dev *pdev,
return err;
}
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
- pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
+ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_ERR PFX "No suitable DMA available\n");
goto err_free_reg;
}
@@ -504,7 +503,7 @@ static int __devinit agnx_pci_probe(struct pci_dev *pdev,
/* Map mem #1 and #2 */
priv->ctl = pci_iomap(pdev, 0, mem_len0);
-// printk(KERN_DEBUG PFX"MEM1 mapped address is 0x%p\n", priv->ctl);
+/* printk(KERN_DEBUG PFX"MEM1 mapped address is 0x%p\n", priv->ctl); */
if (!priv->ctl) {
printk(KERN_ERR PFX "Can't map device memory\n");
goto err_free_dev;
diff --git a/drivers/staging/agnx/phy.c b/drivers/staging/agnx/phy.c
index da8f10c0838..2be63312b72 100644
--- a/drivers/staging/agnx/phy.c
+++ b/drivers/staging/agnx/phy.c
@@ -114,7 +114,7 @@ static void mac_address_set(struct agnx_priv *priv)
/* FIXME */
reg = (mac_addr[0] << 24) | (mac_addr[1] << 16) | mac_addr[2] << 8 | mac_addr[3];
iowrite32(reg, ctl + AGNX_RXM_MACHI);
- reg = (mac_addr[4] << 8) | mac_addr[5];
+ reg = (mac_addr[4] << 8) | mac_addr[5];
iowrite32(reg, ctl + AGNX_RXM_MACLO);
}
@@ -127,7 +127,7 @@ static void receiver_bssid_set(struct agnx_priv *priv, u8 *bssid)
/* FIXME */
reg = bssid[0] << 24 | (bssid[1] << 16) | (bssid[2] << 8) | bssid[3];
iowrite32(reg, ctl + AGNX_RXM_BSSIDHI);
- reg = (bssid[4] << 8) | bssid[5];
+ reg = (bssid[4] << 8) | bssid[5];
iowrite32(reg, ctl + AGNX_RXM_BSSIDLO);
/* Enable the receiver */
@@ -401,9 +401,9 @@ static void rx_management_init(struct agnx_priv *priv)
agnx_write32(ctl, 0x2074, 0x1f171710);
agnx_write32(ctl, 0x2078, 0x10100d0d);
agnx_write32(ctl, 0x207c, 0x11111010);
- }
- else
+ } else {
agnx_write32(ctl, AGNX_RXM_DELAY11, 0x0);
+ }
agnx_write32(ctl, AGNX_RXM_REQRATE, 0x8195e00);
}
@@ -476,7 +476,7 @@ static void gain_ctlcnt_init(struct agnx_priv *priv)
/* It seemed if we set other bit to 1 the bit 0 will
be auto change to 0 */
agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x2 | 0x1);
-// agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x1);
+/* agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x1); */
} /* gain_ctlcnt_init */
@@ -490,7 +490,7 @@ static void phy_init(struct agnx_priv *priv)
/* Load InitialGainTable */
gain_table_init(priv);
- agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x2000000);
+ agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x2000000);
/* Clear the following offsets in Memory Range #2: */
memset_io(data + 0x5040, 0, 0xa * 4);
@@ -586,7 +586,7 @@ static void phy_init(struct agnx_priv *priv)
agnx_write32(ctl, AGNX_GCR_SIFST11B, 0x28);
agnx_write32(ctl, AGNX_GCR_CWDETEC, 0x0);
agnx_write32(ctl, AGNX_GCR_0X38, 0x1e);
-// agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);
+/* agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);*/
agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
agnx_write32(ctl, AGNX_GCR_THCAP11A, 0x32);
@@ -810,10 +810,10 @@ static void card_interface_init(struct agnx_priv *priv)
}
print_hex_dump_bytes(PFX "EEPROM: ", DUMP_PREFIX_NONE, eeprom,
ARRAY_SIZE(eeprom));
- } while(0);
+ } while (0);
spi_rc_write(ctl, RF_CHIP0, 0x26);
- reg = agnx_read32(ctl, AGNX_SPI_RLSW);
+ reg = agnx_read32(ctl, AGNX_SPI_RLSW);
/* Initialize the system interface */
system_itf_init(priv);
@@ -874,19 +874,19 @@ static void card_interface_init(struct agnx_priv *priv)
/* FIXME Enable the request */
/* Check packet length */
/* Set maximum packet length */
-/* agnx_write32(ctl, AGNX_RXM_REQRATE, 0x88195e00); */
-/* enable_receiver(priv); */
+/* agnx_write32(ctl, AGNX_RXM_REQRATE, 0x88195e00); */
+/* enable_receiver(priv); */
/* Set the Receiver BSSID */
receiver_bssid_set(priv, bssid);
/* FIXME Set to managed mode */
set_managed_mode(priv);
-// set_promiscuous_mode(priv);
-/* set_scan_mode(priv); */
-/* set_learn_mode(priv); */
-// set_promis_and_managed(priv);
-// set_adhoc_mode(priv);
+/* set_promiscuous_mode(priv); */
+/* set_scan_mode(priv); */
+/* set_learn_mode(priv); */
+/* set_promis_and_managed(priv); */
+/* set_adhoc_mode(priv); */
/* Set the recieve request rate */
/* Check packet length */
diff --git a/drivers/staging/agnx/rf.c b/drivers/staging/agnx/rf.c
index 8294b6e2eb9..42e457a1844 100644
--- a/drivers/staging/agnx/rf.c
+++ b/drivers/staging/agnx/rf.c
@@ -109,12 +109,12 @@ void rf_chips_init(struct agnx_priv *priv)
}
/* Set SPI clock speed to 200NS */
- reg = agnx_read32(ctl, AGNX_SPI_CFG);
- reg &= ~0xF;
- reg |= 0x3;
- agnx_write32(ctl, AGNX_SPI_CFG, reg);
+ reg = agnx_read32(ctl, AGNX_SPI_CFG);
+ reg &= ~0xF;
+ reg |= 0x3;
+ agnx_write32(ctl, AGNX_SPI_CFG, reg);
- /* Set SPI clock speed to 50NS */
+ /* Set SPI clock speed to 50NS */
reg = agnx_read32(ctl, AGNX_SPI_CFG);
reg &= ~0xF;
reg |= 0x1;
@@ -256,7 +256,7 @@ static void antenna_init(struct agnx_priv *priv, int num_antenna)
agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 70);
agnx_write32(ctl, AGNX_GCR_SIGHTH, 100);
agnx_write32(ctl, AGNX_GCR_SIGLTH, 48);
-// agnx_write32(ctl, AGNX_GCR_SIGLTH, 16);
+/* agnx_write32(ctl, AGNX_GCR_SIGLTH, 16); */
break;
default:
printk(KERN_WARNING PFX "Unknow antenna number\n");
@@ -275,8 +275,8 @@ static void chain_update(struct agnx_priv *priv, u32 chain)
if (reg == 0x4)
spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, reg|0x1000);
else if (reg != 0x0)
- spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
- else {
+ spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
+ else {
if (chain == 3 || chain == 6) {
spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
@@ -634,8 +634,7 @@ static void chain_calibrate(struct agnx_priv *priv, struct chains *chains,
}
} /* chain_calibrate */
-
-static void inline get_calibrete_value(struct agnx_priv *priv, struct chains *chains,
+static inline void get_calibrete_value(struct agnx_priv *priv, struct chains *chains,
unsigned int num)
{
void __iomem *ctl = priv->ctl;
@@ -652,7 +651,7 @@ static void inline get_calibrete_value(struct agnx_priv *priv, struct chains *ch
}
if (num == 0 || num == 1 || num == 2) {
- if ( 0 == chains[num].cali)
+ if (0 == chains[num].cali)
chains[num].cali = 0xff;
else
chains[num].cali--;
@@ -669,7 +668,7 @@ static inline void calibra_delay(struct agnx_priv *priv)
unsigned int i = 100;
wmb();
- while (i--) {
+ while (--i) {
reg = (ioread32(ctl + AGNX_ACI_STATUS));
if (reg == 0x4000)
break;
diff --git a/drivers/staging/agnx/sta.c b/drivers/staging/agnx/sta.c
index d3ac675e45b..5b2d54a587c 100644
--- a/drivers/staging/agnx/sta.c
+++ b/drivers/staging/agnx/sta.c
@@ -18,7 +18,7 @@ void hash_read(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id)
iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
- reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
+ reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
}
@@ -40,7 +40,7 @@ void hash_write(struct agnx_priv *priv, u8 *mac_addr, u8 sta_id)
iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH);
iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
- reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
+ reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
if (!(reglo & 0x80000000))
printk(KERN_WARNING PFX "Update hash table failed\n");
}
@@ -59,7 +59,7 @@ void hash_delete(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id)
iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
- reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
+ reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
}
@@ -69,15 +69,14 @@ void hash_dump(struct agnx_priv *priv, u8 sta_id)
void __iomem *ctl = priv->ctl;
u32 reghi, reglo;
- reglo = 0x0; /* dump command */
- reglo|= 0x40000000; /* status bit */
+ reglo = 0x40000000; /* status bit */
iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
iowrite32(sta_id << 16, ctl + AGNX_RXM_HASH_DUMP_DATA);
udelay(80);
reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
- reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
+ reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
printk(PFX "hash cmd are : %.8x%.8x\n", reghi, reglo);
reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_FLAG);
printk(PFX "hash flag is : %.8x\n", reghi);
@@ -91,7 +90,7 @@ void hash_dump(struct agnx_priv *priv, u8 sta_id)
void get_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx)
{
void __iomem *ctl = priv->ctl;
- memcpy_fromio(power, ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
+ memcpy_fromio(power, ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
sizeof(*power));
}
@@ -100,7 +99,7 @@ set_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int
{
void __iomem *ctl = priv->ctl;
/* FIXME 2. Write Template to offset + station number */
- memcpy_toio(ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
+ memcpy_toio(ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
power, sizeof(*power));
}
@@ -135,7 +134,7 @@ inline void set_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int s
{
void __iomem *data = priv->data;
- memcpy_toio(data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
+ memcpy_toio(data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
sta, sizeof(*sta));
}
@@ -165,7 +164,7 @@ static void sta_tx_workqueue_init(struct agnx_priv *priv, unsigned int sta_idx)
reg = agnx_set_bits(WORK_QUEUE_VALID, WORK_QUEUE_VALID_SHIFT, 1);
reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 1);
-// reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 0);
+/* reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 0); */
tx_wq.reg2 |= cpu_to_le32(reg);
/* Suppose all 8 traffic class are used */
@@ -181,7 +180,7 @@ static void sta_traffic_init(struct agnx_sta_traffic *traffic)
reg = agnx_set_bits(NEW_PACKET, NEW_PACKET_SHIFT, 1);
reg |= agnx_set_bits(TRAFFIC_VALID, TRAFFIC_VALID_SHIFT, 1);
-// reg |= agnx_set_bits(TRAFFIC_ACK_TYPE, TRAFFIC_ACK_TYPE_SHIFT, 1);
+/* reg |= agnx_set_bits(TRAFFIC_ACK_TYPE, TRAFFIC_ACK_TYPE_SHIFT, 1); */
traffic->reg0 = cpu_to_le32(reg);
/* 3. setting RX Sequence Number to 4095 */
diff --git a/drivers/staging/agnx/sta.h b/drivers/staging/agnx/sta.h
index 58d0b12900d..94e2cf1f973 100644
--- a/drivers/staging/agnx/sta.h
+++ b/drivers/staging/agnx/sta.h
@@ -16,7 +16,7 @@ struct agnx_hash_cmd {
#define PASS 0x00000001
#define PASS_SHIFT 1
__be32 cmdlo;
-}__attribute__((__packed__));
+} __attribute__((__packed__));
/*
diff --git a/drivers/staging/agnx/table.c b/drivers/staging/agnx/table.c
index c60048487b5..b52fef9db0e 100644
--- a/drivers/staging/agnx/table.c
+++ b/drivers/staging/agnx/table.c
@@ -80,7 +80,7 @@ void routing_table_init(struct agnx_priv *priv)
disable_receiver(priv);
- for ( type = 0; type < 0x3; type++ ) {
+ for (type = 0; type < 0x3; type++) {
for (subtype = 0; subtype < 0x10; subtype++) {
/* 1. Set Routing table to R/W and to Return status on Read */
reg = (type << ROUTAB_TYPE_SHIFT) |
@@ -89,7 +89,7 @@ void routing_table_init(struct agnx_priv *priv)
if (type == ROUTAB_TYPE_DATA) {
/* NULL goes to RFP */
if (subtype == ROUTAB_SUBTYPE_NULL)
-// reg |= ROUTAB_ROUTE_RFP;
+/* reg |= ROUTAB_ROUTE_RFP; */
reg |= ROUTAB_ROUTE_CPU;
/* QOS NULL goes to CPU */
else if (subtype == ROUTAB_SUBTYPE_QOSNULL)
@@ -104,7 +104,7 @@ void routing_table_init(struct agnx_priv *priv)
(subtype == ROUTAB_SUBTYPE_QOSDATAPOLL) ||
(subtype == ROUTAB_SUBTYPE_QOSDATAACKPOLL))
reg |= ROUTAB_ROUTE_ENCRY;
-// reg |= ROUTAB_ROUTE_CPU;
+/* reg |= ROUTAB_ROUTE_CPU; */
/*Drop NULL and QOS NULL ack, poll and poll ack*/
else if ((subtype == ROUTAB_SUBTYPE_NULLACK) ||
(subtype == ROUTAB_SUBTYPE_QOSNULLACK) ||
@@ -112,11 +112,11 @@ void routing_table_init(struct agnx_priv *priv)
(subtype == ROUTAB_SUBTYPE_QOSNULLPOLL) ||
(subtype == ROUTAB_SUBTYPE_NULLPOLLACK) ||
(subtype == ROUTAB_SUBTYPE_QOSNULLPOLLACK))
-// reg |= ROUTAB_ROUTE_DROP;
+/* reg |= ROUTAB_ROUTE_DROP; */
reg |= ROUTAB_ROUTE_CPU;
- }
- else
+ } else {
reg |= (ROUTAB_ROUTE_CPU);
+ }
iowrite32(reg, ctl + AGNX_RXM_ROUTAB);
/* Check to verify that the status bit cleared */
routing_table_delay();
diff --git a/drivers/staging/agnx/xmit.c b/drivers/staging/agnx/xmit.c
index 7f01528b8a4..0e034081f3a 100644
--- a/drivers/staging/agnx/xmit.c
+++ b/drivers/staging/agnx/xmit.c
@@ -17,8 +17,8 @@
#include "debug.h"
#include "phy.h"
-unsigned int rx_frame_cnt = 0;
-//unsigned int local_tx_sent_cnt = 0;
+unsigned int rx_frame_cnt;
+/* unsigned int local_tx_sent_cnt = 0; */
static inline void disable_rx_engine(struct agnx_priv *priv)
{
@@ -242,15 +242,15 @@ static void get_rx_stats(struct agnx_priv *priv, struct agnx_hdr *hdr,
memset(stat, 0, sizeof(*stat));
/* RSSI */
rssi = (u8 *)&hdr->phy_stats_lo;
-// stat->ssi = (rssi[0] + rssi[1] + rssi[2]) / 3;
+/* stat->ssi = (rssi[0] + rssi[1] + rssi[2]) / 3; */
/* Noise */
noise = ioread32(ctl + AGNX_GCR_NOISE0);
noise += ioread32(ctl + AGNX_GCR_NOISE1);
noise += ioread32(ctl + AGNX_GCR_NOISE2);
stat->noise = noise / 3;
/* Signal quality */
- //snr = stat->ssi - stat->noise;
- if (snr >=0 && snr < 40)
+/* snr = stat->ssi - stat->noise; */
+ if (snr >= 0 && snr < 40)
stat->signal = 5 * snr / 2;
else if (snr >= 40)
stat->signal = 100;
@@ -269,10 +269,9 @@ static void get_rx_stats(struct agnx_priv *priv, struct agnx_hdr *hdr,
stat->band = IEEE80211_BAND_2GHZ;
stat->freq = agnx_channels[priv->channel - 1].center_freq;
-// stat->antenna = 3;
-// stat->mactime = be32_to_cpu(hdr->time_stamp);
-// stat->channel = priv->channel;
-
+/* stat->antenna = 3;
+ stat->mactime = be32_to_cpu(hdr->time_stamp);
+ stat->channel = priv->channel; */
}
static inline void combine_hdr_frag(struct ieee80211_hdr *ieeehdr,
@@ -296,7 +295,7 @@ static inline void combine_hdr_frag(struct ieee80211_hdr *ieeehdr,
static inline int agnx_packet_check(struct agnx_priv *priv, struct agnx_hdr *agnxhdr,
unsigned packet_len)
{
- if (agnx_get_bits(CRC_FAIL, CRC_FAIL_SHIFT, be32_to_cpu(agnxhdr->reg1)) == 1){
+ if (agnx_get_bits(CRC_FAIL, CRC_FAIL_SHIFT, be32_to_cpu(agnxhdr->reg1)) == 1) {
printk(PFX "RX: CRC check fail\n");
goto drop;
}
@@ -320,7 +319,7 @@ void handle_rx_irq(struct agnx_priv *priv)
{
struct ieee80211_rx_status status;
unsigned int len;
-// AGNX_TRACE;
+/* AGNX_TRACE; */
do {
struct agnx_desc *desc;
@@ -341,54 +340,54 @@ void handle_rx_irq(struct agnx_priv *priv)
len = (frag & PACKET_LEN) >> PACKET_LEN_SHIFT;
if (agnx_packet_check(priv, hdr, len) == -1) {
- rx_desc_reusing(priv, i);
+ rx_desc_reusing(priv, i);
continue;
}
skb_put(skb, len);
do {
- u16 fctl;
+ u16 fctl;
fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)->frame_control);
- if ((fctl & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_BEACON)// && !(fctl & IEEE80211_STYPE_BEACON))
+ if ((fctl & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_BEACON)/* && !(fctl & IEEE80211_STYPE_BEACON)) */
dump_ieee80211_hdr((struct ieee80211_hdr *)hdr->mac_hdr, "RX");
} while (0);
if (hdr->_11b0 && !hdr->_11g0) {
-/* int j; */
-/* u16 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr) */
-/* ->frame_control); */
-/* if ( (fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { */
-/* agnx_print_rx_hdr(hdr); */
-// agnx_print_sta(priv, BSSID_STAID);
-/* for (j = 0; j < 8; j++) */
-/* agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
-/* } */
+/* int j;
+ u16 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)
+ ->frame_control);
+ if ( (fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
+ agnx_print_rx_hdr(hdr);
+ agnx_print_sta(priv, BSSID_STAID);
+ for (j = 0; j < 8; j++)
+ agnx_print_sta_tx_wq(priv, BSSID_STAID, j);
+ } */
get_rx_stats(priv, hdr, &status);
skb_pull(skb, sizeof(*hdr));
combine_hdr_frag((struct ieee80211_hdr *)hdr->mac_hdr, skb);
} else if (!hdr->_11b0 && hdr->_11g0) {
-// int j;
+/* int j; */
agnx_print_rx_hdr(hdr);
agnx_print_sta(priv, BSSID_STAID);
-// for (j = 0; j < 8; j++)
+/* for (j = 0; j < 8; j++) */
agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);
print_hex_dump_bytes("agnx: RX_PACKET: ", DUMP_PREFIX_NONE,
skb->data, skb->len + 8);
-// if (agnx_plcp_get_bitrate_ofdm(&hdr->_11g0) == 0)
+/* if (agnx_plcp_get_bitrate_ofdm(&hdr->_11g0) == 0) */
get_rx_stats(priv, hdr, &status);
skb_pull(skb, sizeof(*hdr));
combine_hdr_frag((struct ieee80211_hdr *)
((void *)&hdr->mac_hdr), skb);
-// dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G");
+/* dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G"); */
} else
agnx_bug("Unknown packets type");
ieee80211_rx_irqsafe(priv->hw, skb, &status);
rx_desc_reinit(priv, i);
- } while ( priv->rx.idx++ );
+ } while (priv->rx.idx++);
} /* handle_rx_irq */
static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
@@ -415,40 +414,40 @@ static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_TODEVICE);
do {
-// int j;
+/* int j; */
size_t len;
len = info->skb->len - sizeof(struct agnx_hdr) + info->hdr_len;
- // if (len == 614) {
-// agnx_print_desc(desc);
+/* if (len == 614) { */
+/* agnx_print_desc(desc); */
if (info->type == PACKET) {
-// agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data);
-/* agnx_print_sta_power(priv, LOCAL_STAID); */
-/* agnx_print_sta(priv, LOCAL_STAID); */
-/* // for (j = 0; j < 8; j++) */
-/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); */
-// agnx_print_sta_power(priv, BSSID_STAID);
-// agnx_print_sta(priv, BSSID_STAID);
-// for (j = 0; j < 8; j++)
-// agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);
+/* agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data); */
+/* agnx_print_sta_power(priv, LOCAL_STAID); */
+/* agnx_print_sta(priv, LOCAL_STAID); */
+/* for (j = 0; j < 8; j++) */
+/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); */
+/* agnx_print_sta_power(priv, BSSID_STAID); */
+/* agnx_print_sta(priv, BSSID_STAID); */
+/* for (j = 0; j < 8; j++) */
+/* agnx_print_sta_tx_wq(priv, BSSID_STAID, 0); */
}
-// }
+/* } */
} while (0);
if (info->type == PACKET) {
-// dump_txm_registers(priv);
-// dump_rxm_registers(priv);
-// dump_bm_registers(priv);
-// dump_cir_registers(priv);
+/* dump_txm_registers(priv);
+ dump_rxm_registers(priv);
+ dump_bm_registers(priv);
+ dump_cir_registers(priv); */
}
if (info->type == PACKET) {
-// struct ieee80211_hdr *hdr;
+/* struct ieee80211_hdr *hdr; */
struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(info->skb);
skb_pull(info->skb, sizeof(struct agnx_hdr));
memcpy(skb_push(info->skb, info->hdr_len), &info->hdr, info->hdr_len);
-// dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE");
+/* dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE"); */
/* print_hex_dump_bytes("agnx: TX_HANDLE: ", DUMP_PREFIX_NONE, */
/* info->skb->data, info->skb->len); */
@@ -462,7 +461,7 @@ static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
/* ieee80211_tx_status_irqsafe(priv->hw, info->skb, &(info->tx_status)); */
/* } else */
/* dev_kfree_skb_irq(info->skb); */
- }
+ }
memset(desc, 0, sizeof(*desc));
memset(info, 0, sizeof(*info));
}
@@ -485,7 +484,7 @@ void handle_txd_irq(struct agnx_priv *priv)
void handle_other_irq(struct agnx_priv *priv)
{
-// void __iomem *ctl = priv->ctl;
+/* void __iomem *ctl = priv->ctl; */
u32 status = priv->irq_status;
void __iomem *ctl = priv->ctl;
u32 reg;
@@ -526,11 +525,11 @@ void handle_other_irq(struct agnx_priv *priv)
iowrite32(reg, ctl + AGNX_INT_MASK);
iowrite32(IRQ_RX_FRAME, ctl + AGNX_INT_STAT);
printk(PFX "IRQ: RX Frame\n");
- rx_frame_cnt++;
+ rx_frame_cnt++;
}
if (status & IRQ_ERR_INT) {
iowrite32(IRQ_ERR_INT, ctl + AGNX_INT_STAT);
-// agnx_hw_reset(priv);
+/* agnx_hw_reset(priv); */
printk(PFX "IRQ: Error Interrupt\n");
}
if (status & IRQ_TX_QUE_FULL)
@@ -558,14 +557,14 @@ void handle_other_irq(struct agnx_priv *priv)
static inline void route_flag_set(struct agnx_hdr *txhdr)
{
-// u32 reg = 0;
+/* u32 reg = 0; */
/* FIXME */
-/* reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; */
-/* txhdr->reg5 = cpu_to_be32(reg); */
- txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18);
-// txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18));
-// txhdr->reg5 = cpu_to_be32(0x7 << 0x0);
+/* reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; */
+/* txhdr->reg5 = cpu_to_be32(reg); */
+ txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18);
+/* txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18)); */
+/* txhdr->reg5 = cpu_to_be32(0x7 << 0x0); */
}
/* Return 0 if no match */
@@ -579,12 +578,29 @@ static inline unsigned int get_power_level(unsigned int rate, unsigned int anten
case 55:
case 60:
case 90:
- case 120: power_level = 22; break;
- case 180: power_level = 19; break;
- case 240: power_level = 18; break;
- case 360: power_level = 16; break;
- case 480: power_level = 15; break;
- case 540: power_level = 14; break;
+ case 120:
+ power_level = 22;
+ break;
+
+ case 180:
+ power_level = 19;
+ break;
+
+ case 240:
+ power_level = 18;
+ break;
+
+ case 360:
+ power_level = 16;
+ break;
+
+ case 480:
+ power_level = 15;
+ break;
+
+ case 540:
+ power_level = 14;
+ break;
default:
agnx_bug("Error rate setting\n");
}
@@ -604,30 +620,30 @@ static inline void fill_agnx_hdr(struct agnx_priv *priv, struct agnx_info *tx_in
memset(txhdr, 0, sizeof(*txhdr));
-// reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID);
+/* reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID); */
reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, BSSID_STAID);
reg |= agnx_set_bits(WORKQUEUE_ID, WORKQUEUE_ID_SHIFT, 0);
txhdr->reg4 = cpu_to_be32(reg);
/* Set the Hardware Sequence Number to 1? */
reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 0);
-// reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1);
+/* reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1); */
reg |= agnx_set_bits(MAC_HDR_LEN, MAC_HDR_LEN_SHIFT, tx_info->hdr_len);
txhdr->reg1 = cpu_to_be32(reg);
/* Set the agnx_hdr's MAC header */
memcpy(txhdr->mac_hdr, &tx_info->hdr, tx_info->hdr_len);
reg = agnx_set_bits(ACK, ACK_SHIFT, 1);
-// reg = agnx_set_bits(ACK, ACK_SHIFT, 0);
+/* reg = agnx_set_bits(ACK, ACK_SHIFT, 0); */
reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 0);
-// reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1);
+/* reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1); */
reg |= agnx_set_bits(RELAY, RELAY_SHIFT, 0);
reg |= agnx_set_bits(TM, TM_SHIFT, 0);
txhdr->reg0 = cpu_to_be32(reg);
/* Set the long and short retry limits */
- txhdr->tx.short_retry_limit = tx_info->txi->control.rates[0].count;
- txhdr->tx.long_retry_limit = tx_info->txi->control.rates[0].count;
+ txhdr->tx.short_retry_limit = tx_info->txi->control.rates[0].count;
+ txhdr->tx.long_retry_limit = tx_info->txi->control.rates[0].count;
/* FIXME */
len = tx_info->skb->len - sizeof(*txhdr) + tx_info->hdr_len + FCS_LEN;
@@ -652,23 +668,23 @@ static void txm_power_set(struct agnx_priv *priv,
if (txi->control.rates[0].idx < 0) {
/* For B mode Short Preamble */
reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_SHORT);
-// control->tx_rate = -control->tx_rate;
+/* control->tx_rate = -control->tx_rate; */
} else
reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211G);
-// reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG);
+/* reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG); */
reg |= agnx_set_bits(SIGNAL, SIGNAL_SHIFT, 0xB);
reg |= agnx_set_bits(RATE, RATE_SHIFT, 0xB);
-// reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15);
+/* reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15); */
reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 20);
/* if rate < 11M set it to 0 */
reg |= agnx_set_bits(NUM_TRANSMITTERS, NUM_TRANSMITTERS_SHIFT, 1);
-// reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1);
-// reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1);
+/* reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1); */
+/* reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1); */
power.reg = reg;
-// power.reg = cpu_to_le32(reg);
+/* power.reg = cpu_to_le32(reg); */
-// set_sta_power(priv, &power, LOCAL_STAID);
+/* set_sta_power(priv, &power, LOCAL_STAID); */
set_sta_power(priv, &power, BSSID_STAID);
}
@@ -759,24 +775,24 @@ static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,
txm_power_set(priv, txi);
-/* do { */
-/* int j; */
-/* size_t len; */
-/* len = skb->len - hdr_info->dma_len + hdr_info->hdr_len; */
-/* // if (len == 614) { */
-/* agnx_print_desc(hdr_desc); */
-/* agnx_print_desc(frag_desc); */
-/* agnx_print_tx_hdr((struct agnx_hdr *)skb->data); */
-/* agnx_print_sta_power(priv, LOCAL_STAID); */
-/* agnx_print_sta(priv, LOCAL_STAID); */
-/* for (j = 0; j < 8; j++) */
-/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); */
-/* agnx_print_sta_power(priv, BSSID_STAID); */
-/* agnx_print_sta(priv, BSSID_STAID); */
-/* for (j = 0; j < 8; j++) */
-/* agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
-/* // } */
-/* } while (0); */
+/* do { */
+/* int j; */
+/* size_t len; */
+/* len = skb->len - hdr_info->dma_len + hdr_info->hdr_len; */
+/* if (len == 614) { */
+/* agnx_print_desc(hdr_desc); */
+/* agnx_print_desc(frag_desc); */
+/* agnx_print_tx_hdr((struct agnx_hdr *)skb->data); */
+/* agnx_print_sta_power(priv, LOCAL_STAID); */
+/* agnx_print_sta(priv, LOCAL_STAID); */
+/* for (j = 0; j < 8; j++) */
+/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); */
+/* agnx_print_sta_power(priv, BSSID_STAID); */
+/* agnx_print_sta(priv, BSSID_STAID); */
+/* for (j = 0; j < 8; j++) */
+/* agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
+/* } */
+/* } while (0); */
spin_unlock_irqrestore(&priv->lock, flags);
@@ -787,7 +803,7 @@ static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,
reg = (ioread32(priv->ctl + AGNX_CIR_TXMCTL));
reg |= 0x8;
iowrite32((reg), priv->ctl + AGNX_CIR_TXMCTL);
- }while (0);
+ } while (0);
/* Trigger TXD */
do {
@@ -795,7 +811,7 @@ static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,
reg = (ioread32(priv->ctl + AGNX_CIR_TXDCTL));
reg |= 0x8;
iowrite32((reg), priv->ctl + AGNX_CIR_TXDCTL);
- }while (0);
+ } while (0);
return 0;
}
@@ -807,12 +823,12 @@ int _agnx_tx(struct agnx_priv *priv, struct sk_buff *skb)
if (tx_packet_check(skb))
return 0;
-/* print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, */
-/* skb->data, skb->len); */
+/* print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, */
+/* skb->data, skb->len); */
- fctl = le16_to_cpu(*((__le16 *)skb->data));
+ fctl = le16_to_cpu(*((__le16 *)skb->data));
- if ( (fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA )
+ if ((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
return __agnx_tx(priv, skb, &priv->txd);
else
return __agnx_tx(priv, skb, &priv->txm);
diff --git a/drivers/staging/altpciechdma/altpciechdma.c b/drivers/staging/altpciechdma/altpciechdma.c
index f516140ca97..5869e1484a9 100644
--- a/drivers/staging/altpciechdma/altpciechdma.c
+++ b/drivers/staging/altpciechdma/altpciechdma.c
@@ -46,7 +46,6 @@
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
-#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -313,15 +312,16 @@ static int __devinit map_bars(struct ape_dev *ape, struct pci_dev *dev)
continue;
/* do not map BARs with address 0 */
if (!bar_start || !bar_end) {
- printk(KERN_DEBUG "BAR #%d is not present?!\n", i);
+ printk(KERN_DEBUG "BAR #%d is not present?!\n", i);
rc = -1;
goto fail;
}
bar_length = bar_end - bar_start + 1;
/* BAR length is less than driver requires? */
if (bar_length < bar_min_len[i]) {
- printk(KERN_DEBUG "BAR #%d length = %lu bytes but driver "
- "requires at least %lu bytes\n", i, bar_length, bar_min_len[i]);
+ printk(KERN_DEBUG "BAR #%d length = %lu bytes but driver "
+ "requires at least %lu bytes\n",
+ i, bar_length, bar_min_len[i]);
rc = -1;
goto fail;
}
@@ -333,8 +333,8 @@ static int __devinit map_bars(struct ape_dev *ape, struct pci_dev *dev)
rc = -1;
goto fail;
}
- printk(KERN_DEBUG "BAR[%d] mapped at 0x%p with length %lu(/%lu).\n", i,
- ape->bar[i], bar_min_len[i], bar_length);
+ printk(KERN_DEBUG "BAR[%d] mapped at 0x%p with length %lu(/%lu).\n", i,
+ ape->bar[i], bar_min_len[i], bar_length);
}
/* succesfully mapped all required BAR regions */
rc = 0;
@@ -427,11 +427,13 @@ static int ape_sg_to_chdma_table(struct scatterlist *sgl, int nents, int first,
dma_addr_t next = sg_dma_address(&sgl[i + 1]);
/* length of this entry i */
len = sg_dma_len(&sgl[i]);
- printk(KERN_DEBUG "%04d: addr=0x%08x length=0x%08x\n", i, addr, len);
+ printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
+ (unsigned long long)addr, len);
/* entry i + 1 is non-contiguous with entry i? */
if (next != addr + len) {
/* TODO create entry here (we could overwrite i) */
- printk(KERN_DEBUG "%4d: cont_addr=0x%08x cont_len=0x%08x\n", j, cont_addr, cont_len);
+ printk(KERN_DEBUG "%4d: cont_addr=0x%Lx cont_len=0x%08x\n", j,
+ (unsigned long long)cont_addr, cont_len);
/* set descriptor for contiguous transfer */
ape_chdma_desc_set(&desc[j], cont_addr, ep_addr, cont_len);
/* next end point memory address */
@@ -447,8 +449,10 @@ static int ape_sg_to_chdma_table(struct scatterlist *sgl, int nents, int first,
addr = next;
}
/* TODO create entry here (we could overwrite i) */
- printk(KERN_DEBUG "%04d: addr=0x%08x length=0x%08x\n", i, addr, len);
- printk(KERN_DEBUG "%4d: cont_addr=0x%08x length=0x%08x\n", j, cont_addr, cont_len);
+ printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
+ (unsigned long long)addr, len);
+ printk(KERN_DEBUG "%4d: cont_addr=0x%Lx length=0x%08x\n", j,
+ (unsigned long long)cont_addr, cont_len);
j++;
return j;
}
@@ -467,15 +471,14 @@ static inline int compare(u32 *p, u32 *q, int len)
} else {
fail++;
/* show the first few miscompares */
- if (fail < 10) {
- printk(KERN_DEBUG "[%p] = 0x%08x != [%p] = 0x%08x ?!\n", p, *p, q, *q);
- /* but stop after a while */
- } else if (fail == 10) {
- printk(KERN_DEBUG "---more errors follow! not printed---\n");
- } else {
+ if (fail < 10)
+ printk(KERN_DEBUG "[%p] = 0x%08x != [%p] = 0x%08x ?!\n", p, *p, q, *q);
+ /* but stop after a while */
+ else if (fail == 10)
+ printk(KERN_DEBUG "---more errors follow! not printed---\n");
+ else
/* stop compare after this many errors */
- break;
- }
+ break;
}
p++;
q++;
@@ -528,7 +531,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
printk(KERN_DEBUG "ape->table_virt = 0x%p.\n", ape->table_virt);
if (!write_header || !read_header || !ape->table_virt)
- goto fail;
+ goto fail;
/* allocate and map coherently-cached memory for a DMA-able buffer */
/* @see Documentation/PCI/PCI-DMA-mapping.txt, near line 318 */
@@ -565,9 +568,8 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
/* read 8192 bytes from RC buffer to EP address 4096 */
ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus, 4096, 2 * PAGE_SIZE);
#if 1
- for (i = 0; i < 255; i++) {
+ for (i = 0; i < 255; i++)
ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus, 4096, 2 * PAGE_SIZE);
- }
/* index of last descriptor */
n = i - 1;
#endif
@@ -647,7 +649,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
printk(KERN_DEBUG "EPLAST = %u, n = %d\n", eplast, n);
if (eplast == n) {
printk(KERN_DEBUG "DONE\n");
- /* print IRQ count before the transfer */
+ /* print IRQ count before the transfer */
printk(KERN_DEBUG "#IRQs during transfer: %d\n", ape->irq_count - irq_count);
break;
}
@@ -661,9 +663,9 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
n = 0;
ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
#if 1
- for (i = 0; i < 255; i++) {
+ for (i = 0; i < 255; i++)
ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
- }
+
/* index of last descriptor */
n = i - 1;
#endif
@@ -691,7 +693,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
w = (u32)(n + 1);
/* enable updates of eplast for each descriptor completion */
w |= (u32)(1UL << 18)/*global EPLAST_EN*/;
-#if 0 // test variable, make a module option later
+#if 0 /* test variable, make a module option later */
/* enable MSI for each descriptor completion */
if (ape->msi_enabled)
w |= (1UL << 17)/*global MSI*/;
@@ -715,7 +717,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
/** memory write barrier */
wmb();
/** dummy read to flush posted writes */
- //(void)ioread32();
+ /* (void) ioread32(); */
printk(KERN_DEBUG "POLL FOR WRITE:\n");
/* poll for completion, 1000 times 1 millisecond */
@@ -844,18 +846,18 @@ static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id)
}
ape->got_regions = 1;
-#if 1 // @todo For now, disable 64-bit, because I do not understand the implications (DAC!)
+#if 1 /* @todo For now, disable 64-bit, because I do not understand the implications (DAC!) */
/* query for DMA transfer */
/* @see Documentation/PCI/PCI-DMA-mapping.txt */
- if (!pci_set_dma_mask(dev, DMA_64BIT_MASK)) {
- pci_set_consistent_dma_mask(dev, DMA_64BIT_MASK);
+ if (!pci_set_dma_mask(dev, DMA_BIT_MASK(64))) {
+ pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(64));
/* use 64-bit DMA */
printk(KERN_DEBUG "Using a 64-bit DMA mask.\n");
} else
#endif
- if (!pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
+ if (!pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
printk(KERN_DEBUG "Could not set 64-bit DMA mask.\n");
- pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK);
+ pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(32));
/* use 32-bit DMA */
printk(KERN_DEBUG "Using a 32-bit DMA mask.\n");
} else {
@@ -947,7 +949,8 @@ static void __devexit remove(struct pci_dev *dev)
struct ape_dev *ape;
printk(KERN_DEBUG "remove(0x%p)\n", dev);
if ((dev == 0) || (dev->dev.driver_data == 0)) {
- printk(KERN_DEBUG "remove(dev = 0x%p) dev->dev.driver_data = 0x%p\n", dev, dev->dev.driver_data);
+ printk(KERN_DEBUG "remove(dev = 0x%p) dev->dev.driver_data = 0x%p\n",
+ dev, (dev? dev->dev.driver_data: NULL));
return;
}
ape = (struct ape_dev *)dev->dev.driver_data;
@@ -1048,10 +1051,9 @@ static ssize_t sg_write(struct file *file, const char __user *buf, size_t count,
printk(KERN_DEBUG DRV_NAME "_write(buf=0x%p, count=%lld, pos=%llu)\n",
buf, (s64)count, (u64)*pos);
/* TODO transfer boundaries at PAGE_SIZE granularity */
- while (remaining > 0)
- {
+ while (remaining > 0) {
/* limit DMA transfer size */
- transfer_len = (remaining < APE_CHDMA_MAX_TRANSFER_LEN)? remaining:
+ transfer_len = (remaining < APE_CHDMA_MAX_TRANSFER_LEN) ? remaining :
APE_CHDMA_MAX_TRANSFER_LEN;
/* get all user space buffer pages and create a scattergather list */
sgm_map_user_pages(ape->sgm, transfer_addr, transfer_len, 0/*read from userspace*/);
@@ -1085,12 +1087,12 @@ static ssize_t sg_write(struct file *file, const char __user *buf, size_t count,
/*
* character device file operations
*/
-static struct file_operations sg_fops = {
- .owner = THIS_MODULE,
- .open = sg_open,
- .release = sg_close,
- .read = sg_read,
- .write = sg_write,
+static const struct file_operations sg_fops = {
+ .owner = THIS_MODULE,
+ .open = sg_open,
+ .release = sg_close,
+ .read = sg_read,
+ .write = sg_write,
};
/* sg_init() - Initialize character device
@@ -1158,12 +1160,12 @@ static struct pci_driver pci_driver = {
*/
static int __init alterapciechdma_init(void)
{
- int rc = 0;
+ int rc = 0;
printk(KERN_DEBUG DRV_NAME " init(), built at " __DATE__ " " __TIME__ "\n");
/* register this driver with the PCI bus driver */
rc = pci_register_driver(&pci_driver);
if (rc < 0)
- return rc;
+ return rc;
return 0;
}
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 758131cad08..79e90fed27d 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -2649,14 +2649,22 @@ static void binder_vma_open(struct vm_area_struct *vma)
{
struct binder_proc *proc = vma->vm_private_data;
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
- printk(KERN_INFO "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
+ printk(KERN_INFO
+ "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
+ proc->pid, vma->vm_start, vma->vm_end,
+ (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
+ (unsigned long)pgprot_val(vma->vm_page_prot));
dump_stack();
}
static void binder_vma_close(struct vm_area_struct *vma)
{
struct binder_proc *proc = vma->vm_private_data;
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
- printk(KERN_INFO "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
+ printk(KERN_INFO
+ "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
+ proc->pid, vma->vm_start, vma->vm_end,
+ (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
+ (unsigned long)pgprot_val(vma->vm_page_prot));
proc->vma = NULL;
}
@@ -2677,7 +2685,11 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_end = vma->vm_start + SZ_4M;
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
- printk(KERN_INFO "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
+ printk(KERN_INFO
+ "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n",
+ proc->pid, vma->vm_start, vma->vm_end,
+ (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
+ (unsigned long)pgprot_val(vma->vm_page_prot));
if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) {
ret = -EPERM;
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index 643ac5ce381..3375c1cce2b 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -225,7 +225,7 @@ static int __init ram_console_init(struct ram_console_buffer *buffer,
buffer_size - sizeof(struct ram_console_buffer);
if (ram_console_buffer_size > buffer_size) {
- pr_err("ram_console: buffer %p, invalid size %d, datasize %d\n",
+ pr_err("ram_console: buffer %p, invalid size %zu, datasize %zu\n",
buffer, buffer_size, ram_console_buffer_size);
return 0;
}
@@ -235,8 +235,8 @@ static int __init ram_console_init(struct ram_console_buffer *buffer,
ECC_BLOCK_SIZE) + 1) * ECC_SIZE;
if (ram_console_buffer_size > buffer_size) {
- pr_err("ram_console: buffer %p, invalid size %d, "
- "non-ecc datasize %d\n",
+ pr_err("ram_console: buffer %p, invalid size %zu, "
+ "non-ecc datasize %zu\n",
buffer, buffer_size, ram_console_buffer_size);
return 0;
}
@@ -322,7 +322,7 @@ static int ram_console_driver_probe(struct platform_device *pdev)
}
buffer_size = res->end - res->start + 1;
start = res->start;
- printk(KERN_INFO "ram_console: got buffer at %x, size %x\n",
+ printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n",
start, buffer_size);
buffer = ioremap(res->start, buffer_size);
if (buffer == NULL) {
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index 666a186e212..04dde4b8281 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -56,10 +56,10 @@ MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com");
MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION);
MODULE_LICENSE("GPL");
-static struct class *oled_class = 0;
-static int oled_num = 0;
+static struct class *oled_class;
+static int oled_num;
-static uint start_off = 0;
+static uint start_off;
module_param(start_off, uint, 0644);
@@ -80,20 +80,20 @@ struct oled_dev_desc_str {
};
/* table of devices that work with this driver */
-static struct usb_device_id id_table [] = {
+static struct usb_device_id id_table[] = {
{ USB_DEVICE(0x0b05, 0x1726) }, // Asus G1/G2 (and variants)
{ USB_DEVICE(0x0b05, 0x175b) }, // Asus G50V (and possibly others - G70? G71?)
{ },
};
/* parameters of specific devices */
-static struct oled_dev_desc_str oled_dev_desc_table [] = {
+static struct oled_dev_desc_str oled_dev_desc_table[] = {
{ 0x0b05, 0x1726, 128, PACK_MODE_G1, "G1/G2" },
{ 0x0b05, 0x175b, 256, PACK_MODE_G50, "G50" },
{ },
};
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
#define SETUP_PACKET_HEADER(packet, val1, val2, val3, val4, val5, val6, val7) \
do { \
@@ -107,7 +107,7 @@ MODULE_DEVICE_TABLE (usb, id_table);
packet->header.value6 = val5; \
packet->header.value7 = val6; \
packet->header.value8 = val7; \
- } while(0);
+ } while (0);
struct asus_oled_header {
uint8_t magic1;
@@ -160,10 +160,12 @@ static void enable_oled(struct asus_oled_dev *odev, uint8_t enabl)
SETUP_PACKET_HEADER(packet, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00);
- if (enabl) packet->bitmap[0] = 0xaf;
- else packet->bitmap[0] = 0xae;
+ if (enabl)
+ packet->bitmap[0] = 0xaf;
+ else
+ packet->bitmap[0] = 0xae;
- for (a=0; a<1; a++) {
+ for (a = 0; a < 1; a++) {
retval = usb_bulk_msg(odev->udev,
usb_sndbulkpipe(odev->udev, 2),
packet,
@@ -252,7 +254,7 @@ static void send_packets(struct usb_device *udev, struct asus_oled_packet *packe
}
}
-static void send_packet(struct usb_device *udev, struct asus_oled_packet *packet, size_t offset, size_t len, char *buf, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6){
+static void send_packet(struct usb_device *udev, struct asus_oled_packet *packet, size_t offset, size_t len, char *buf, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6) {
int retval;
int act_len;
@@ -294,7 +296,7 @@ static void send_data(struct asus_oled_dev *odev)
return;
}
- if (odev->pack_mode==PACK_MODE_G1){
+ if (odev->pack_mode == PACK_MODE_G1) {
// When sending roll-mode data the display updated only first packet.
// I have no idea why, but when static picture is send just before
// rolling picture - everything works fine.
@@ -308,7 +310,7 @@ static void send_data(struct asus_oled_dev *odev)
send_packets(odev->udev, packet, odev->buf, odev->pic_mode, packet_num);
}
else
- if (odev->pack_mode==PACK_MODE_G50){
+ if (odev->pack_mode == PACK_MODE_G50) {
send_packets_g50(odev->udev, packet, odev->buf);
}
@@ -326,7 +328,7 @@ static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count)
x += odev->x_shift;
y += odev->y_shift;
- switch(odev->pack_mode)
+ switch (odev->pack_mode)
{
case PACK_MODE_G1:
// i = (x/128)*640 + 127 - x + (y/8)*128;
@@ -377,30 +379,32 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
{
size_t offs = 0, max_offs;
- if (count < 1) return 0;
+ if (count < 1)
+ return 0;
- if (tolower(buf[0]) == 'b'){
+ if (tolower(buf[0]) == 'b') {
// binary mode, set the entire memory
size_t i;
odev->buf_size = (odev->dev_width * ASUS_OLED_DISP_HEIGHT) / 8;
- if (odev->buf) kfree(odev->buf);
+ if (odev->buf)
+ kfree(odev->buf);
odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
memset(odev->buf, 0xff, odev->buf_size);
- for (i=1; i < count && i<=32*32; i++){
+ for (i = 1; i < count && i <= 32 * 32; i++) {
odev->buf[i-1] = buf[i];
odev->buf_offs = i-1;
}
- odev->width=odev->dev_width / 8;
- odev->height=ASUS_OLED_DISP_HEIGHT;
- odev->x_shift=0;
- odev->y_shift=0;
- odev->last_val=0;
+ odev->width = odev->dev_width / 8;
+ odev->height = ASUS_OLED_DISP_HEIGHT;
+ odev->x_shift = 0;
+ odev->y_shift = 0;
+ odev->last_val = 0;
send_data(odev);
@@ -416,7 +420,7 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
goto error_header;
}
- switch(tolower(buf[1])) {
+ switch (tolower(buf[1])) {
case ASUS_OLED_STATIC:
case ASUS_OLED_ROLL:
case ASUS_OLED_FLASH:
@@ -432,27 +436,36 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
if (buf[i] >= '0' && buf[i] <= '9') {
w = 10*w + (buf[i] - '0');
- if (w > ASUS_OLED_MAX_WIDTH) goto error_width;
+ if (w > ASUS_OLED_MAX_WIDTH)
+ goto error_width;
}
- else if (tolower(buf[i]) == 'x') break;
- else goto error_width;
+ else if (tolower(buf[i]) == 'x')
+ break;
+ else
+ goto error_width;
}
for (++i; i < count; ++i) {
if (buf[i] >= '0' && buf[i] <= '9') {
h = 10*h + (buf[i] - '0');
- if (h > ASUS_OLED_DISP_HEIGHT) goto error_height;
+ if (h > ASUS_OLED_DISP_HEIGHT)
+ goto error_height;
}
- else if (tolower(buf[i]) == '>') break;
- else goto error_height;
+ else if (tolower(buf[i]) == '>')
+ break;
+ else
+ goto error_height;
}
- if (w < 1 || w > ASUS_OLED_MAX_WIDTH) goto error_width;
+ if (w < 1 || w > ASUS_OLED_MAX_WIDTH)
+ goto error_width;
- if (h < 1 || h > ASUS_OLED_DISP_HEIGHT) goto error_height;
+ if (h < 1 || h > ASUS_OLED_DISP_HEIGHT)
+ goto error_height;
- if (i >= count || buf[i] != '>') goto error_header;
+ if (i >= count || buf[i] != '>')
+ goto error_header;
offs = i+1;
@@ -468,7 +481,8 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
odev->buf_size = w_mem * h_mem / 8;
- if (odev->buf) kfree(odev->buf);
+ if (odev->buf)
+ kfree(odev->buf);
odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
if (odev->buf == NULL) {
@@ -505,23 +519,30 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
int ret;
if (buf[offs] == '1' || buf[offs] == '#') {
- if ( (ret = append_values(odev, 1, 1)) < 0) return ret;
+ ret = append_values(odev, 1, 1);
+ if (ret < 0)
+ return ret;
}
else if (buf[offs] == '0' || buf[offs] == ' ') {
- if ( (ret = append_values(odev, 0, 1)) < 0) return ret;
+ ret = append_values(odev, 0, 1);
+ if (ret < 0)
+ return ret;
}
else if (buf[offs] == '\n') {
// New line detected. Lets assume, that all characters till the end of the
// line were equal to the last character in this line.
if (odev->buf_offs % odev->width != 0)
- if ( (ret = append_values(odev, odev->last_val,
- odev->width - (odev->buf_offs % odev->width))) < 0) return ret;
+ ret = append_values(odev, odev->last_val,
+ odev->width - (odev->buf_offs % odev->width));
+ if (ret < 0)
+ return ret;
}
offs++;
}
- if (odev->buf_offs >= max_offs) send_data(odev);
+ if (odev->buf_offs >= max_offs)
+ send_data(odev);
return count;
@@ -566,9 +587,9 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
uint16_t dev_width = 0;
oled_pack_mode_t pack_mode = PACK_MODE_LAST;
const struct oled_dev_desc_str * dev_desc = oled_dev_desc_table;
- const char *desc = 0;
+ const char *desc = NULL;
- if (id == 0) {
+ if (!id) {
// Even possible? Just to make sure...
dev_err(&interface->dev, "No usb_device_id provided!\n");
return -ENODEV;
@@ -586,7 +607,7 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
}
}
- if ( !desc || dev_width < 1 || pack_mode == PACK_MODE_LAST) {
+ if (!desc || dev_width < 1 || pack_mode == PACK_MODE_LAST) {
dev_err(&interface->dev, "Missing or incomplete device description!\n");
return -ENODEV;
}
@@ -611,20 +632,20 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
odev->last_val = 0;
odev->buf = NULL;
odev->enabled = 1;
- odev->dev = 0;
+ odev->dev = NULL;
- usb_set_intfdata (interface, odev);
+ usb_set_intfdata(interface, odev);
- if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled)))) {
+ retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));
+ if (retval)
goto err_files;
- }
- if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture)))) {
+ retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
+ if (retval)
goto err_files;
- }
- odev->dev = device_create(oled_class, &interface->dev, MKDEV(0,0),
- NULL,"oled_%d", ++oled_num);
+ odev->dev = device_create(oled_class, &interface->dev, MKDEV(0, 0),
+ NULL, "oled_%d", ++oled_num);
if (IS_ERR(odev->dev)) {
retval = PTR_ERR(odev->dev);
@@ -633,13 +654,13 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
dev_set_drvdata(odev->dev, odev);
- if ( (retval = device_create_file(odev->dev, &dev_attr_enabled))) {
+ retval = device_create_file(odev->dev, &dev_attr_enabled);
+ if (retval)
goto err_class_enabled;
- }
- if ( (retval = device_create_file(odev->dev, &dev_attr_picture))) {
+ retval = device_create_file(odev->dev, &dev_attr_picture);
+ if (retval)
goto err_class_picture;
- }
dev_info(&interface->dev, "Attached Asus OLED device: %s [width %u, pack_mode %d]\n", desc, odev->dev_width, odev->pack_mode);
@@ -659,7 +680,7 @@ err_files:
device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));
device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
- usb_set_intfdata (interface, NULL);
+ usb_set_intfdata(interface, NULL);
usb_put_dev(odev->udev);
kfree(odev);
@@ -670,19 +691,20 @@ static void asus_oled_disconnect(struct usb_interface *interface)
{
struct asus_oled_dev *odev;
- odev = usb_get_intfdata (interface);
- usb_set_intfdata (interface, NULL);
+ odev = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
device_remove_file(odev->dev, &dev_attr_picture);
device_remove_file(odev->dev, &dev_attr_enabled);
device_unregister(odev->dev);
- device_remove_file(&interface->dev, & ASUS_OLED_DEVICE_ATTR(picture));
- device_remove_file(&interface->dev, & ASUS_OLED_DEVICE_ATTR(enabled));
+ device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
+ device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));
usb_put_dev(odev->udev);
- if (odev->buf) kfree(odev->buf);
+ if (odev->buf)
+ kfree(odev->buf);
kfree(odev);
@@ -713,7 +735,8 @@ static int __init asus_oled_init(void)
return PTR_ERR(oled_class);
}
- if ((retval = class_create_file(oled_class, &class_attr_version))) {
+ retval = class_create_file(oled_class, &class_attr_version);
+ if (retval) {
err("Error creating class version file");
goto error;
}
@@ -740,6 +763,6 @@ static void __exit asus_oled_exit(void)
usb_deregister(&oled_driver);
}
-module_init (asus_oled_init);
-module_exit (asus_oled_exit);
+module_init(asus_oled_init);
+module_exit(asus_oled_exit);
diff --git a/drivers/staging/at76_usb/TODO b/drivers/staging/at76_usb/TODO
index 6911ca71a41..0c7ed21c3b9 100644
--- a/drivers/staging/at76_usb/TODO
+++ b/drivers/staging/at76_usb/TODO
@@ -1,2 +1,7 @@
-rewrite the driver to use the proper in-kernel wireless stack
-instead of using its own.
+Fix the mac80211 port of at76_usb (the proper in-kernel wireless
+stack) and get it included to the mainline. Patches available here:
+
+http://git.kernel.org/?p=linux/kernel/git/linville/wireless-legacy.git;a=shortlog;h=at76
+
+Contact Kalle Valo <kalle.valo@iki.fi> and linux-wireless list
+<linux-wireless@vger.kernel.org> for more information.
diff --git a/drivers/staging/at76_usb/at76_usb.c b/drivers/staging/at76_usb/at76_usb.c
index c8e4d31c7df..6f6e36a3bd9 100644
--- a/drivers/staging/at76_usb/at76_usb.c
+++ b/drivers/staging/at76_usb/at76_usb.c
@@ -36,7 +36,7 @@
#include <net/ieee80211_radiotap.h>
#include <linux/firmware.h>
#include <linux/leds.h>
-#include <net/ieee80211.h>
+#include <linux/ieee80211.h>
#include "at76_usb.h"
@@ -1727,12 +1727,12 @@ static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss)
/* write TLV data elements */
- ie->id = MFIE_TYPE_SSID;
+ ie->id = WLAN_EID_SSID;
ie->len = bss->ssid_len;
memcpy(ie->data, bss->ssid, bss->ssid_len);
next_ie(&ie);
- ie->id = MFIE_TYPE_RATES;
+ ie->id = WLAN_EID_SUPP_RATES;
ie->len = sizeof(hw_rates);
memcpy(ie->data, hw_rates, sizeof(hw_rates));
next_ie(&ie); /* ie points behind the supp_rates field */
@@ -4397,7 +4397,7 @@ static void at76_rx_mgmt_beacon(struct at76_priv *priv,
switch (ie->id) {
- case MFIE_TYPE_SSID:
+ case WLAN_EID_SSID:
if (have_ssid)
break;
@@ -4420,7 +4420,7 @@ static void at76_rx_mgmt_beacon(struct at76_priv *priv,
have_ssid = 1;
break;
- case MFIE_TYPE_RATES:
+ case WLAN_EID_SUPP_RATES:
if (have_rates)
break;
@@ -4433,7 +4433,7 @@ static void at76_rx_mgmt_beacon(struct at76_priv *priv,
hex2str(ie->data, ie->len));
break;
- case MFIE_TYPE_DS_SET:
+ case WLAN_EID_DS_PARAMS:
if (have_channel)
break;
@@ -4443,9 +4443,9 @@ static void at76_rx_mgmt_beacon(struct at76_priv *priv,
priv->netdev->name, match->channel);
break;
- case MFIE_TYPE_CF_SET:
- case MFIE_TYPE_TIM:
- case MFIE_TYPE_IBSS_SET:
+ case WLAN_EID_CF_PARAMS:
+ case WLAN_EID_TIM:
+ case WLAN_EID_IBSS_PARAMS:
default:
at76_dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s",
priv->netdev->name, ie->id, ie->len,
@@ -5370,8 +5370,7 @@ static void at76_delete_device(struct at76_priv *priv)
at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__);
- if (priv->rx_skb)
- kfree_skb(priv->rx_skb);
+ kfree_skb(priv->rx_skb);
at76_free_bss_list(priv);
del_timer_sync(&priv->bss_list_timer);
diff --git a/drivers/staging/at76_usb/at76_usb.h b/drivers/staging/at76_usb/at76_usb.h
index b20be9da1fa..6d60c6e23a0 100644
--- a/drivers/staging/at76_usb/at76_usb.h
+++ b/drivers/staging/at76_usb/at76_usb.h
@@ -22,6 +22,93 @@
#ifndef _AT76_USB_H
#define _AT76_USB_H
+/*
+ * ieee80211 definitions copied from net/ieee80211.h
+ */
+
+#define WEP_KEY_LEN 13
+#define WEP_KEYS 4
+
+#define IEEE80211_DATA_LEN 2304
+/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
+ 6.2.1.1.2.
+
+ The figure in section 7.1.2 suggests a body size of up to 2312
+ bytes is allowed, which is a bit confusing, I suspect this
+ represents the 2304 bytes of real data, plus a possible 8 bytes of
+ WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
+
+#define IEEE80211_1ADDR_LEN 10
+#define IEEE80211_2ADDR_LEN 16
+#define IEEE80211_3ADDR_LEN 24
+#define IEEE80211_4ADDR_LEN 30
+#define IEEE80211_FCS_LEN 4
+#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
+#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
+
+#define MIN_FRAG_THRESHOLD 256U
+#define MAX_FRAG_THRESHOLD 2346U
+
+struct ieee80211_info_element {
+ u8 id;
+ u8 len;
+ u8 data[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_auth {
+ struct ieee80211_hdr_3addr header;
+ __le16 algorithm;
+ __le16 transaction;
+ __le16 status;
+ /* challenge */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_request {
+ struct ieee80211_hdr_3addr header;
+ __le16 capability;
+ __le16 listen_interval;
+ /* SSID, supported rates, RSN */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_probe_response {
+ struct ieee80211_hdr_3addr header;
+ __le32 time_stamp[2];
+ __le16 beacon_interval;
+ __le16 capability;
+ /* SSID, supported rates, FH params, DS params,
+ * CF params, IBSS params, TIM (if beacon), RSN */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+/* Alias beacon for probe_response */
+#define ieee80211_beacon ieee80211_probe_response
+
+struct ieee80211_assoc_response {
+ struct ieee80211_hdr_3addr header;
+ __le16 capability;
+ __le16 status;
+ __le16 aid;
+ /* supported rates */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_disassoc {
+ struct ieee80211_hdr_3addr header;
+ __le16 reason;
+} __attribute__ ((packed));
+
/* Board types */
enum board_type {
BOARD_503_ISL3861 = 1,
diff --git a/drivers/staging/b3dfg/Kconfig b/drivers/staging/b3dfg/Kconfig
new file mode 100644
index 00000000000..524231047de
--- /dev/null
+++ b/drivers/staging/b3dfg/Kconfig
@@ -0,0 +1,9 @@
+config B3DFG
+ tristate "Brontes 3d Frame Framegrabber"
+ default n
+ ---help---
+ This driver provides support for the Brontes 3d Framegrabber
+ PCI card.
+
+ To compile this driver as a module, choose M here. The module
+ will be called b3dfg.
diff --git a/drivers/staging/b3dfg/Makefile b/drivers/staging/b3dfg/Makefile
new file mode 100644
index 00000000000..91f439ffc17
--- /dev/null
+++ b/drivers/staging/b3dfg/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_B3DFG) += b3dfg.o
diff --git a/drivers/staging/b3dfg/TODO b/drivers/staging/b3dfg/TODO
new file mode 100644
index 00000000000..f5a9298b9ac
--- /dev/null
+++ b/drivers/staging/b3dfg/TODO
@@ -0,0 +1,4 @@
+
+ - queue/wait buffer presents filltime results for each frame?
+ - counting of dropped frames
+ - review endianness
diff --git a/drivers/staging/b3dfg/b3dfg.c b/drivers/staging/b3dfg/b3dfg.c
new file mode 100644
index 00000000000..75ebe338c6f
--- /dev/null
+++ b/drivers/staging/b3dfg/b3dfg.c
@@ -0,0 +1,1119 @@
+ /*
+ * Brontes PCI frame grabber driver
+ *
+ * Copyright (C) 2008 3M Company
+ * Contact: Justin Bronder <jsbronder@brontes3d.com>
+ * Original Authors: Daniel Drake <ddrake@brontes3d.com>
+ * Duane Griffin <duaneg@dghda.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/device.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/ioctl.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/cdev.h>
+#include <linux/list.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/mm.h>
+#include <linux/version.h>
+#include <linux/uaccess.h>
+
+static unsigned int b3dfg_nbuf = 2;
+
+module_param_named(buffer_count, b3dfg_nbuf, uint, 0444);
+
+MODULE_PARM_DESC(buffer_count, "Number of buffers (min 2, default 2)\n");
+
+MODULE_AUTHOR("Daniel Drake <ddrake@brontes3d.com>");
+MODULE_DESCRIPTION("Brontes frame grabber driver");
+MODULE_LICENSE("GPL");
+
+#define DRIVER_NAME "b3dfg"
+#define B3DFG_MAX_DEVS 4
+#define B3DFG_FRAMES_PER_BUFFER 3
+
+#define B3DFG_BAR_REGS 0
+#define B3DFG_REGS_LENGTH 0x10000
+
+#define B3DFG_IOC_MAGIC 0xb3 /* dfg :-) */
+#define B3DFG_IOCGFRMSZ _IOR(B3DFG_IOC_MAGIC, 1, int)
+#define B3DFG_IOCTNUMBUFS _IO(B3DFG_IOC_MAGIC, 2)
+#define B3DFG_IOCTTRANS _IO(B3DFG_IOC_MAGIC, 3)
+#define B3DFG_IOCTQUEUEBUF _IO(B3DFG_IOC_MAGIC, 4)
+#define B3DFG_IOCTPOLLBUF _IOWR(B3DFG_IOC_MAGIC, 5, struct b3dfg_poll)
+#define B3DFG_IOCTWAITBUF _IOWR(B3DFG_IOC_MAGIC, 6, struct b3dfg_wait)
+#define B3DFG_IOCGWANDSTAT _IOR(B3DFG_IOC_MAGIC, 7, int)
+
+enum {
+ /* number of 4kb pages per frame */
+ B3D_REG_FRM_SIZE = 0x0,
+
+ /* bit 0: set to enable interrupts
+ * bit 1: set to enable cable status change interrupts */
+ B3D_REG_HW_CTRL = 0x4,
+
+ /* bit 0-1 - 1-based ID of next pending frame transfer (0 = none)
+ * bit 2 indicates the previous DMA transfer has completed
+ * bit 3 indicates wand cable status change
+ * bit 8:15 - counter of number of discarded triplets */
+ B3D_REG_DMA_STS = 0x8,
+
+ /* bit 0: wand status (1 = present, 0 = disconnected) */
+ B3D_REG_WAND_STS = 0xc,
+
+ /* bus address for DMA transfers. lower 2 bits must be zero because DMA
+ * works with 32 bit word size. */
+ B3D_REG_EC220_DMA_ADDR = 0x8000,
+
+ /* bit 20:0 - number of 32 bit words to be transferred
+ * bit 21:31 - reserved */
+ B3D_REG_EC220_TRF_SIZE = 0x8004,
+
+ /* bit 0 - error bit
+ * bit 1 - interrupt bit (set to generate interrupt at end of transfer)
+ * bit 2 - start bit (set to start transfer)
+ * bit 3 - direction (0 = DMA_TO_DEVICE, 1 = DMA_FROM_DEVICE
+ * bit 4:31 - reserved */
+ B3D_REG_EC220_DMA_STS = 0x8008,
+};
+
+enum b3dfg_buffer_state {
+ B3DFG_BUFFER_POLLED = 0,
+ B3DFG_BUFFER_PENDING,
+ B3DFG_BUFFER_POPULATED,
+};
+
+struct b3dfg_buffer {
+ unsigned char *frame[B3DFG_FRAMES_PER_BUFFER];
+ struct list_head list;
+ u8 state;
+};
+
+struct b3dfg_dev {
+
+ /* no protection needed: all finalized at initialization time */
+ struct pci_dev *pdev;
+ struct cdev chardev;
+ struct device *dev;
+ void __iomem *regs;
+ unsigned int frame_size;
+
+ /*
+ * Protects buffer state, including buffer_queue, triplet_ready,
+ * cur_dma_frame_idx & cur_dma_frame_addr.
+ */
+ spinlock_t buffer_lock;
+ struct b3dfg_buffer *buffers;
+ struct list_head buffer_queue;
+
+ /* Last frame in triplet transferred (-1 if none). */
+ int cur_dma_frame_idx;
+
+ /* Current frame's address for DMA. */
+ dma_addr_t cur_dma_frame_addr;
+
+ /*
+ * Protects cstate_tstamp.
+ * Nests inside buffer_lock.
+ */
+ spinlock_t cstate_lock;
+ unsigned long cstate_tstamp;
+
+ /*
+ * Protects triplets_dropped.
+ * Nests inside buffers_lock.
+ */
+ spinlock_t triplets_dropped_lock;
+ unsigned int triplets_dropped;
+
+ wait_queue_head_t buffer_waitqueue;
+
+ unsigned int transmission_enabled:1;
+ unsigned int triplet_ready:1;
+};
+
+static u8 b3dfg_devices[B3DFG_MAX_DEVS];
+
+static struct class *b3dfg_class;
+static dev_t b3dfg_devt;
+
+static const struct pci_device_id b3dfg_ids[] __devinitdata = {
+ { PCI_DEVICE(0x0b3d, 0x0001) },
+ { },
+};
+
+MODULE_DEVICE_TABLE(pci, b3dfg_ids);
+
+/***** user-visible types *****/
+
+struct b3dfg_poll {
+ int buffer_idx;
+ unsigned int triplets_dropped;
+};
+
+struct b3dfg_wait {
+ int buffer_idx;
+ unsigned int timeout;
+ unsigned int triplets_dropped;
+};
+
+/**** register I/O ****/
+
+static u32 b3dfg_read32(struct b3dfg_dev *fgdev, u16 reg)
+{
+ return ioread32(fgdev->regs + reg);
+}
+
+static void b3dfg_write32(struct b3dfg_dev *fgdev, u16 reg, u32 value)
+{
+ iowrite32(value, fgdev->regs + reg);
+}
+
+/**** buffer management ****/
+
+/*
+ * Program EC220 for transfer of a specific frame.
+ * Called with buffer_lock held.
+ */
+static int setup_frame_transfer(struct b3dfg_dev *fgdev,
+ struct b3dfg_buffer *buf, int frame)
+{
+ unsigned char *frm_addr;
+ dma_addr_t frm_addr_dma;
+ unsigned int frm_size = fgdev->frame_size;
+
+ frm_addr = buf->frame[frame];
+ frm_addr_dma = pci_map_single(fgdev->pdev, frm_addr,
+ frm_size, PCI_DMA_FROMDEVICE);
+ if (pci_dma_mapping_error(fgdev->pdev, frm_addr_dma))
+ return -ENOMEM;
+
+ fgdev->cur_dma_frame_addr = frm_addr_dma;
+ fgdev->cur_dma_frame_idx = frame;
+
+ b3dfg_write32(fgdev, B3D_REG_EC220_DMA_ADDR,
+ cpu_to_le32(frm_addr_dma));
+ b3dfg_write32(fgdev, B3D_REG_EC220_TRF_SIZE,
+ cpu_to_le32(frm_size >> 2));
+ b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0xf);
+
+ return 0;
+}
+
+/* Caller should hold buffer lock */
+static void dequeue_all_buffers(struct b3dfg_dev *fgdev)
+{
+ int i;
+ for (i = 0; i < b3dfg_nbuf; i++) {
+ struct b3dfg_buffer *buf = &fgdev->buffers[i];
+ buf->state = B3DFG_BUFFER_POLLED;
+ list_del_init(&buf->list);
+ }
+}
+
+/* queue a buffer to receive data */
+static int queue_buffer(struct b3dfg_dev *fgdev, int bufidx)
+{
+ struct device *dev = &fgdev->pdev->dev;
+ struct b3dfg_buffer *buf;
+ unsigned long flags;
+ int r = 0;
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+ if (bufidx < 0 || bufidx >= b3dfg_nbuf) {
+ dev_dbg(dev, "Invalid buffer index, %d\n", bufidx);
+ r = -ENOENT;
+ goto out;
+ }
+ buf = &fgdev->buffers[bufidx];
+
+ if (unlikely(buf->state == B3DFG_BUFFER_PENDING)) {
+ dev_dbg(dev, "buffer %d is already queued\n", bufidx);
+ r = -EINVAL;
+ goto out;
+ }
+
+ buf->state = B3DFG_BUFFER_PENDING;
+ list_add_tail(&buf->list, &fgdev->buffer_queue);
+
+ if (fgdev->transmission_enabled && fgdev->triplet_ready) {
+ dev_dbg(dev, "triplet is ready, pushing immediately\n");
+ fgdev->triplet_ready = 0;
+ r = setup_frame_transfer(fgdev, buf, 0);
+ if (r)
+ dev_err(dev, "unable to map DMA buffer\n");
+ }
+
+out:
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+ return r;
+}
+
+/* non-blocking buffer poll. returns 1 if data is present in the buffer,
+ * 0 otherwise */
+static int poll_buffer(struct b3dfg_dev *fgdev, void __user *arg)
+{
+ struct device *dev = &fgdev->pdev->dev;
+ struct b3dfg_poll p;
+ struct b3dfg_buffer *buf;
+ unsigned long flags;
+ int r = 1;
+ int arg_out = 0;
+
+ if (copy_from_user(&p, arg, sizeof(p)))
+ return -EFAULT;
+
+ if (unlikely(!fgdev->transmission_enabled)) {
+ dev_dbg(dev, "cannot poll, transmission disabled\n");
+ return -EINVAL;
+ }
+
+ if (p.buffer_idx < 0 || p.buffer_idx >= b3dfg_nbuf)
+ return -ENOENT;
+
+ buf = &fgdev->buffers[p.buffer_idx];
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+
+ if (likely(buf->state == B3DFG_BUFFER_POPULATED)) {
+ arg_out = 1;
+ buf->state = B3DFG_BUFFER_POLLED;
+
+ /* IRQs already disabled by spin_lock_irqsave above. */
+ spin_lock(&fgdev->triplets_dropped_lock);
+ p.triplets_dropped = fgdev->triplets_dropped;
+ fgdev->triplets_dropped = 0;
+ spin_unlock(&fgdev->triplets_dropped_lock);
+ } else {
+ r = 0;
+ }
+
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+ if (arg_out && copy_to_user(arg, &p, sizeof(p)))
+ r = -EFAULT;
+
+ return r;
+}
+
+static unsigned long get_cstate_change(struct b3dfg_dev *fgdev)
+{
+ unsigned long flags, when;
+
+ spin_lock_irqsave(&fgdev->cstate_lock, flags);
+ when = fgdev->cstate_tstamp;
+ spin_unlock_irqrestore(&fgdev->cstate_lock, flags);
+ return when;
+}
+
+static int is_event_ready(struct b3dfg_dev *fgdev, struct b3dfg_buffer *buf,
+ unsigned long when)
+{
+ int result;
+ unsigned long flags;
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+ spin_lock(&fgdev->cstate_lock);
+ result = (!fgdev->transmission_enabled ||
+ buf->state == B3DFG_BUFFER_POPULATED ||
+ when != fgdev->cstate_tstamp);
+ spin_unlock(&fgdev->cstate_lock);
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+ return result;
+}
+
+/* sleep until a specific buffer becomes populated */
+static int wait_buffer(struct b3dfg_dev *fgdev, void __user *arg)
+{
+ struct device *dev = &fgdev->pdev->dev;
+ struct b3dfg_wait w;
+ struct b3dfg_buffer *buf;
+ unsigned long flags, when;
+ int r;
+
+ if (copy_from_user(&w, arg, sizeof(w)))
+ return -EFAULT;
+
+ if (!fgdev->transmission_enabled) {
+ dev_dbg(dev, "cannot wait, transmission disabled\n");
+ return -EINVAL;
+ }
+
+ if (w.buffer_idx < 0 || w.buffer_idx >= b3dfg_nbuf)
+ return -ENOENT;
+
+ buf = &fgdev->buffers[w.buffer_idx];
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+
+ if (buf->state == B3DFG_BUFFER_POPULATED) {
+ r = w.timeout;
+ goto out_triplets_dropped;
+ }
+
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+ when = get_cstate_change(fgdev);
+ if (w.timeout > 0) {
+ r = wait_event_interruptible_timeout(fgdev->buffer_waitqueue,
+ is_event_ready(fgdev, buf, when),
+ (w.timeout * HZ) / 1000);
+
+ if (unlikely(r < 0))
+ goto out;
+
+ w.timeout = r * 1000 / HZ;
+ } else {
+ r = wait_event_interruptible(fgdev->buffer_waitqueue,
+ is_event_ready(fgdev, buf, when));
+
+ if (unlikely(r)) {
+ r = -ERESTARTSYS;
+ goto out;
+ }
+ }
+
+ /* TODO: Inform the user via field(s) in w? */
+ if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev)) {
+ r = -EINVAL;
+ goto out;
+ }
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+
+ if (buf->state != B3DFG_BUFFER_POPULATED) {
+ r = -ETIMEDOUT;
+ goto out_unlock;
+ }
+
+ buf->state = B3DFG_BUFFER_POLLED;
+
+out_triplets_dropped:
+
+ /* IRQs already disabled by spin_lock_irqsave above. */
+ spin_lock(&fgdev->triplets_dropped_lock);
+ w.triplets_dropped = fgdev->triplets_dropped;
+ fgdev->triplets_dropped = 0;
+ spin_unlock(&fgdev->triplets_dropped_lock);
+
+out_unlock:
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+ if (copy_to_user(arg, &w, sizeof(w)))
+ r = -EFAULT;
+out:
+ return r;
+}
+
+/* mmap page fault handler */
+static int b3dfg_vma_fault(struct vm_area_struct *vma,
+ struct vm_fault *vmf)
+{
+ struct b3dfg_dev *fgdev = vma->vm_file->private_data;
+ unsigned long off = vmf->pgoff << PAGE_SHIFT;
+ unsigned int frame_size = fgdev->frame_size;
+ unsigned int buf_size = frame_size * B3DFG_FRAMES_PER_BUFFER;
+ unsigned char *addr;
+
+ /* determine which buffer the offset lies within */
+ unsigned int buf_idx = off / buf_size;
+ /* and the offset into the buffer */
+ unsigned int buf_off = off % buf_size;
+
+ /* determine which frame inside the buffer the offset lies in */
+ unsigned int frm_idx = buf_off / frame_size;
+ /* and the offset into the frame */
+ unsigned int frm_off = buf_off % frame_size;
+
+ if (unlikely(buf_idx >= b3dfg_nbuf))
+ return VM_FAULT_SIGBUS;
+
+ addr = fgdev->buffers[buf_idx].frame[frm_idx] + frm_off;
+ vm_insert_pfn(vma, (unsigned long)vmf->virtual_address,
+ virt_to_phys(addr) >> PAGE_SHIFT);
+
+ return VM_FAULT_NOPAGE;
+}
+
+static struct vm_operations_struct b3dfg_vm_ops = {
+ .fault = b3dfg_vma_fault,
+};
+
+static int get_wand_status(struct b3dfg_dev *fgdev, int __user *arg)
+{
+ u32 wndstat = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
+ dev_dbg(&fgdev->pdev->dev, "wand status %x\n", wndstat);
+ return __put_user(wndstat & 0x1, arg);
+}
+
+static int enable_transmission(struct b3dfg_dev *fgdev)
+{
+ u16 command;
+ unsigned long flags;
+ struct device *dev = &fgdev->pdev->dev;
+
+ dev_dbg(dev, "enable transmission\n");
+
+ /* check the cable is plugged in. */
+ if (!b3dfg_read32(fgdev, B3D_REG_WAND_STS)) {
+ dev_dbg(dev, "cannot start transmission without wand\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Check we're a bus master.
+ * TODO: I think we can remove this having added the pci_set_master call
+ */
+ pci_read_config_word(fgdev->pdev, PCI_COMMAND, &command);
+ if (!(command & PCI_COMMAND_MASTER)) {
+ dev_err(dev, "not a bus master, force-enabling\n");
+ pci_write_config_word(fgdev->pdev, PCI_COMMAND,
+ command | PCI_COMMAND_MASTER);
+ }
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+
+ /* Handle racing enable_transmission calls. */
+ if (fgdev->transmission_enabled) {
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+ goto out;
+ }
+
+ spin_lock(&fgdev->triplets_dropped_lock);
+ fgdev->triplets_dropped = 0;
+ spin_unlock(&fgdev->triplets_dropped_lock);
+
+ fgdev->triplet_ready = 0;
+ fgdev->cur_dma_frame_idx = -1;
+ fgdev->transmission_enabled = 1;
+
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+ /* Enable DMA and cable status interrupts. */
+ b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0x03);
+
+out:
+ return 0;
+}
+
+static void disable_transmission(struct b3dfg_dev *fgdev)
+{
+ struct device *dev = &fgdev->pdev->dev;
+ unsigned long flags;
+ u32 tmp;
+
+ dev_dbg(dev, "disable transmission\n");
+
+ /* guarantee that no more interrupts will be serviced */
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+ fgdev->transmission_enabled = 0;
+
+ b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
+
+ /* FIXME: temporary debugging only. if the board stops transmitting,
+ * hitting ctrl+c and seeing this message is useful for determining
+ * the state of the board. */
+ tmp = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
+ dev_dbg(dev, "DMA_STS reads %x after TX stopped\n", tmp);
+
+ dequeue_all_buffers(fgdev);
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+ wake_up_interruptible(&fgdev->buffer_waitqueue);
+}
+
+static int set_transmission(struct b3dfg_dev *fgdev, int enabled)
+{
+ int res = 0;
+
+ if (enabled && !fgdev->transmission_enabled)
+ res = enable_transmission(fgdev);
+ else if (!enabled && fgdev->transmission_enabled)
+ disable_transmission(fgdev);
+
+ return res;
+}
+
+/* Called in interrupt context. */
+static void handle_cstate_unplug(struct b3dfg_dev *fgdev)
+{
+ /* Disable all interrupts. */
+ b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
+
+ /* Stop transmission. */
+ spin_lock(&fgdev->buffer_lock);
+ fgdev->transmission_enabled = 0;
+
+ fgdev->cur_dma_frame_idx = -1;
+ fgdev->triplet_ready = 0;
+ if (fgdev->cur_dma_frame_addr) {
+ pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
+ fgdev->frame_size, PCI_DMA_FROMDEVICE);
+ fgdev->cur_dma_frame_addr = 0;
+ }
+ dequeue_all_buffers(fgdev);
+ spin_unlock(&fgdev->buffer_lock);
+}
+
+/* Called in interrupt context. */
+static void handle_cstate_change(struct b3dfg_dev *fgdev)
+{
+ u32 cstate = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
+ unsigned long when;
+ struct device *dev = &fgdev->pdev->dev;
+
+ dev_dbg(dev, "cable state change: %u\n", cstate);
+
+ /*
+ * When the wand is unplugged we reset our state. The hardware will
+ * have done the same internally.
+ *
+ * Note we should never see a cable *plugged* event, as interrupts
+ * should only be enabled when transmitting, which requires the cable
+ * to be plugged. If we do see one it probably means the cable has been
+ * unplugged and re-plugged very rapidly. Possibly because it has a
+ * broken wire and is momentarily losing contact.
+ *
+ * TODO: At the moment if you plug in the cable then enable transmission
+ * the hardware will raise a couple of spurious interrupts, so
+ * just ignore them for now.
+ *
+ * Once the hardware is fixed we should complain and treat it as an
+ * unplug. Or at least track how frequently it is happening and do
+ * so if too many come in.
+ */
+ if (cstate) {
+ dev_warn(dev, "ignoring unexpected plug event\n");
+ return;
+ }
+ handle_cstate_unplug(fgdev);
+
+ /*
+ * Record cable state change timestamp & wake anyone waiting
+ * on a cable state change. Be paranoid about ensuring events
+ * are not missed if we somehow get two interrupts in a jiffy.
+ */
+ spin_lock(&fgdev->cstate_lock);
+ when = jiffies_64;
+ if (when <= fgdev->cstate_tstamp)
+ when = fgdev->cstate_tstamp + 1;
+ fgdev->cstate_tstamp = when;
+ wake_up_interruptible(&fgdev->buffer_waitqueue);
+ spin_unlock(&fgdev->cstate_lock);
+}
+
+/* Called with buffer_lock held. */
+static void transfer_complete(struct b3dfg_dev *fgdev)
+{
+ struct b3dfg_buffer *buf;
+ struct device *dev = &fgdev->pdev->dev;
+
+ pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
+ fgdev->frame_size, PCI_DMA_FROMDEVICE);
+ fgdev->cur_dma_frame_addr = 0;
+
+ buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
+ if (buf) {
+ dev_dbg(dev, "handle frame completion\n");
+ if (fgdev->cur_dma_frame_idx == B3DFG_FRAMES_PER_BUFFER - 1) {
+
+ /* last frame of that triplet completed */
+ dev_dbg(dev, "triplet completed\n");
+ buf->state = B3DFG_BUFFER_POPULATED;
+ list_del_init(&buf->list);
+ wake_up_interruptible(&fgdev->buffer_waitqueue);
+ }
+ } else {
+ dev_err(dev, "got frame but no buffer!\n");
+ }
+}
+
+/*
+ * Called with buffer_lock held.
+ *
+ * Note that idx is the (1-based) *next* frame to be transferred, while
+ * cur_dma_frame_idx is the (0-based) *last* frame to have been transferred (or
+ * -1 if none). Thus there should be a difference of 2 between them.
+ */
+static bool setup_next_frame_transfer(struct b3dfg_dev *fgdev, int idx)
+{
+ struct b3dfg_buffer *buf;
+ struct device *dev = &fgdev->pdev->dev;
+ bool need_ack = 1;
+
+ dev_dbg(dev, "program DMA transfer for next frame: %d\n", idx);
+
+ buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
+ if (buf) {
+ if (idx == fgdev->cur_dma_frame_idx + 2) {
+ if (setup_frame_transfer(fgdev, buf, idx - 1))
+ dev_err(dev, "unable to map DMA buffer\n");
+ need_ack = 0;
+ } else {
+ dev_err(dev, "frame mismatch, got %d, expected %d\n",
+ idx, fgdev->cur_dma_frame_idx + 2);
+
+ /* FIXME: handle dropped triplets here */
+ }
+ } else {
+ dev_err(dev, "cannot setup DMA, no buffer\n");
+ }
+
+ return need_ack;
+}
+
+static irqreturn_t b3dfg_intr(int irq, void *dev_id)
+{
+ struct b3dfg_dev *fgdev = dev_id;
+ struct device *dev = &fgdev->pdev->dev;
+ u32 sts;
+ u8 dropped;
+ bool need_ack = 1;
+ irqreturn_t res = IRQ_HANDLED;
+
+ sts = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
+ if (unlikely(sts == 0)) {
+ dev_warn(dev, "ignore interrupt, DMA status is 0\n");
+ res = IRQ_NONE;
+ goto out;
+ }
+
+ if (unlikely(!fgdev->transmission_enabled)) {
+ dev_warn(dev, "ignore interrupt, TX disabled\n");
+ res = IRQ_HANDLED;
+ goto out;
+ }
+
+ /* Handle dropped frames, as reported by the hardware. */
+ dropped = (sts >> 8) & 0xff;
+ dev_dbg(dev, "intr: DMA_STS=%08x (drop=%d comp=%d next=%d)\n",
+ sts, dropped, !!(sts & 0x4), sts & 0x3);
+ if (unlikely(dropped > 0)) {
+ spin_lock(&fgdev->triplets_dropped_lock);
+ fgdev->triplets_dropped += dropped;
+ spin_unlock(&fgdev->triplets_dropped_lock);
+ }
+
+ /* Handle a cable state change (i.e. the wand being unplugged). */
+ if (sts & 0x08) {
+ handle_cstate_change(fgdev);
+ goto out;
+ }
+
+ spin_lock(&fgdev->buffer_lock);
+ if (unlikely(list_empty(&fgdev->buffer_queue))) {
+
+ /* FIXME need more sanity checking here */
+ dev_info(dev, "buffer not ready for next transfer\n");
+ fgdev->triplet_ready = 1;
+ goto out_unlock;
+ }
+
+ /* Has a frame transfer been completed? */
+ if (sts & 0x4) {
+ u32 dma_status = b3dfg_read32(fgdev, B3D_REG_EC220_DMA_STS);
+
+ /* Check for DMA errors reported by the hardware. */
+ if (unlikely(dma_status & 0x1)) {
+ dev_err(dev, "EC220 error: %08x\n", dma_status);
+
+ /* FIXME flesh out error handling */
+ goto out_unlock;
+ }
+
+ /* Sanity check, we should have a frame index at this point. */
+ if (unlikely(fgdev->cur_dma_frame_idx == -1)) {
+ dev_err(dev, "completed but no last idx?\n");
+
+ /* FIXME flesh out error handling */
+ goto out_unlock;
+ }
+
+ transfer_complete(fgdev);
+ }
+
+ /* Is there another frame transfer pending? */
+ if (sts & 0x3)
+ need_ack = setup_next_frame_transfer(fgdev, sts & 0x3);
+ else
+ fgdev->cur_dma_frame_idx = -1;
+
+out_unlock:
+ spin_unlock(&fgdev->buffer_lock);
+out:
+ if (need_ack) {
+ dev_dbg(dev, "acknowledging interrupt\n");
+ b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0x0b);
+ }
+ return res;
+}
+
+static int b3dfg_open(struct inode *inode, struct file *filp)
+{
+ struct b3dfg_dev *fgdev =
+ container_of(inode->i_cdev, struct b3dfg_dev, chardev);
+
+ dev_dbg(&fgdev->pdev->dev, "open\n");
+ filp->private_data = fgdev;
+ return 0;
+}
+
+static int b3dfg_release(struct inode *inode, struct file *filp)
+{
+ struct b3dfg_dev *fgdev = filp->private_data;
+ dev_dbg(&fgdev->pdev->dev, "release\n");
+ disable_transmission(fgdev);
+ return 0;
+}
+
+static long b3dfg_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ struct b3dfg_dev *fgdev = filp->private_data;
+
+ switch (cmd) {
+ case B3DFG_IOCGFRMSZ:
+ return __put_user(fgdev->frame_size, (int __user *) arg);
+ case B3DFG_IOCGWANDSTAT:
+ return get_wand_status(fgdev, (int __user *) arg);
+ case B3DFG_IOCTTRANS:
+ return set_transmission(fgdev, (int) arg);
+ case B3DFG_IOCTQUEUEBUF:
+ return queue_buffer(fgdev, (int) arg);
+ case B3DFG_IOCTPOLLBUF:
+ return poll_buffer(fgdev, (void __user *) arg);
+ case B3DFG_IOCTWAITBUF:
+ return wait_buffer(fgdev, (void __user *) arg);
+ default:
+ dev_dbg(&fgdev->pdev->dev, "unrecognised ioctl %x\n", cmd);
+ return -EINVAL;
+ }
+}
+
+static unsigned int b3dfg_poll(struct file *filp, poll_table *poll_table)
+{
+ struct b3dfg_dev *fgdev = filp->private_data;
+ unsigned long flags, when;
+ int i;
+ int r = 0;
+
+ when = get_cstate_change(fgdev);
+ poll_wait(filp, &fgdev->buffer_waitqueue, poll_table);
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+ for (i = 0; i < b3dfg_nbuf; i++) {
+ if (fgdev->buffers[i].state == B3DFG_BUFFER_POPULATED) {
+ r = POLLIN | POLLRDNORM;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+ /* TODO: Confirm this is how we want to communicate the change. */
+ if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev))
+ r = POLLERR;
+
+ return r;
+}
+
+static int b3dfg_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct b3dfg_dev *fgdev = filp->private_data;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ unsigned long vsize = vma->vm_end - vma->vm_start;
+ unsigned long bufdatalen = b3dfg_nbuf * fgdev->frame_size * 3;
+ unsigned long psize = bufdatalen - offset;
+ int r = 0;
+
+ if (vsize <= psize) {
+ vma->vm_flags |= VM_IO | VM_RESERVED | VM_CAN_NONLINEAR |
+ VM_PFNMAP;
+ vma->vm_ops = &b3dfg_vm_ops;
+ } else {
+ r = -EINVAL;
+ }
+
+ return r;
+}
+
+static struct file_operations b3dfg_fops = {
+ .owner = THIS_MODULE,
+ .open = b3dfg_open,
+ .release = b3dfg_release,
+ .unlocked_ioctl = b3dfg_ioctl,
+ .poll = b3dfg_poll,
+ .mmap = b3dfg_mmap,
+};
+
+static void free_all_frame_buffers(struct b3dfg_dev *fgdev)
+{
+ int i, j;
+ for (i = 0; i < b3dfg_nbuf; i++)
+ for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++)
+ kfree(fgdev->buffers[i].frame[j]);
+ kfree(fgdev->buffers);
+}
+
+/* initialize device and any data structures. called before any interrupts
+ * are enabled. */
+static int b3dfg_init_dev(struct b3dfg_dev *fgdev)
+{
+ int i, j;
+ u32 frm_size = b3dfg_read32(fgdev, B3D_REG_FRM_SIZE);
+
+ /* Disable interrupts. In abnormal circumstances (e.g. after a crash)
+ * the board may still be transmitting from the previous session. If we
+ * ensure that interrupts are disabled before we later enable them, we
+ * are sure to capture a triplet from the start, rather than starting
+ * from frame 2 or 3. Disabling interrupts causes the FG to throw away
+ * all buffered data and stop buffering more until interrupts are
+ * enabled again.
+ */
+ b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
+
+ fgdev->frame_size = frm_size * 4096;
+ fgdev->buffers = kzalloc(sizeof(struct b3dfg_buffer) * b3dfg_nbuf,
+ GFP_KERNEL);
+ if (!fgdev->buffers)
+ goto err_no_buf;
+ for (i = 0; i < b3dfg_nbuf; i++) {
+ struct b3dfg_buffer *buf = &fgdev->buffers[i];
+ for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++) {
+ buf->frame[j] = kmalloc(fgdev->frame_size, GFP_KERNEL);
+ if (!buf->frame[j])
+ goto err_no_mem;
+ }
+ INIT_LIST_HEAD(&buf->list);
+ }
+
+ INIT_LIST_HEAD(&fgdev->buffer_queue);
+ init_waitqueue_head(&fgdev->buffer_waitqueue);
+ spin_lock_init(&fgdev->buffer_lock);
+ spin_lock_init(&fgdev->cstate_lock);
+ spin_lock_init(&fgdev->triplets_dropped_lock);
+ return 0;
+
+err_no_mem:
+ free_all_frame_buffers(fgdev);
+err_no_buf:
+ return -ENOMEM;
+}
+
+/* find next free minor number, returns -1 if none are availabile */
+static int get_free_minor(void)
+{
+ int i;
+ for (i = 0; i < B3DFG_MAX_DEVS; i++) {
+ if (b3dfg_devices[i] == 0)
+ return i;
+ }
+ return -1;
+}
+
+static int __devinit b3dfg_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct b3dfg_dev *fgdev = kzalloc(sizeof(*fgdev), GFP_KERNEL);
+ int r = 0;
+ int minor = get_free_minor();
+ dev_t devno = MKDEV(MAJOR(b3dfg_devt), minor);
+ unsigned long res_len;
+ resource_size_t res_base;
+
+ if (fgdev == NULL)
+ return -ENOMEM;
+
+ if (minor < 0) {
+ dev_err(&pdev->dev, "too many devices found!\n");
+ r = -EIO;
+ goto err_free;
+ }
+
+ b3dfg_devices[minor] = 1;
+ dev_info(&pdev->dev, "probe device with IRQ %d\n", pdev->irq);
+
+ cdev_init(&fgdev->chardev, &b3dfg_fops);
+ fgdev->chardev.owner = THIS_MODULE;
+
+ r = cdev_add(&fgdev->chardev, devno, 1);
+ if (r) {
+ dev_err(&pdev->dev, "cannot add char device\n");
+ goto err_release_minor;
+ }
+
+ fgdev->dev = device_create(
+ b3dfg_class,
+ &pdev->dev,
+ devno,
+ dev_get_drvdata(&pdev->dev),
+ DRIVER_NAME "%d", minor);
+
+ if (IS_ERR(fgdev->dev)) {
+ dev_err(&pdev->dev, "cannot create device\n");
+ r = PTR_ERR(fgdev->dev);
+ goto err_del_cdev;
+ }
+
+ r = pci_enable_device(pdev);
+ if (r) {
+ dev_err(&pdev->dev, "cannot enable PCI device\n");
+ goto err_dev_unreg;
+ }
+
+ res_len = pci_resource_len(pdev, B3DFG_BAR_REGS);
+ if (res_len != B3DFG_REGS_LENGTH) {
+ dev_err(&pdev->dev, "invalid register resource size\n");
+ r = -EIO;
+ goto err_disable;
+ }
+
+ if (pci_resource_flags(pdev, B3DFG_BAR_REGS)
+ != (IORESOURCE_MEM | IORESOURCE_SIZEALIGN)) {
+ dev_err(&pdev->dev, "invalid resource flags\n");
+ r = -EIO;
+ goto err_disable;
+ }
+ r = pci_request_regions(pdev, DRIVER_NAME);
+ if (r) {
+ dev_err(&pdev->dev, "cannot obtain PCI resources\n");
+ goto err_disable;
+ }
+
+ pci_set_master(pdev);
+
+ r = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (r) {
+ dev_err(&pdev->dev, "no usable DMA configuration\n");
+ goto err_free_res;
+ }
+
+ res_base = pci_resource_start(pdev, B3DFG_BAR_REGS);
+ fgdev->regs = ioremap_nocache(res_base, res_len);
+ if (!fgdev->regs) {
+ dev_err(&pdev->dev, "regs ioremap failed\n");
+ r = -EIO;
+ goto err_free_res;
+ }
+
+ fgdev->pdev = pdev;
+ pci_set_drvdata(pdev, fgdev);
+ r = b3dfg_init_dev(fgdev);
+ if (r < 0) {
+ dev_err(&pdev->dev, "failed to initalize device\n");
+ goto err_unmap;
+ }
+
+ r = request_irq(pdev->irq, b3dfg_intr, IRQF_SHARED, DRIVER_NAME, fgdev);
+ if (r) {
+ dev_err(&pdev->dev, "couldn't request irq %d\n", pdev->irq);
+ goto err_free_bufs;
+ }
+
+ return 0;
+
+err_free_bufs:
+ free_all_frame_buffers(fgdev);
+err_unmap:
+ iounmap(fgdev->regs);
+err_free_res:
+ pci_release_regions(pdev);
+err_disable:
+ pci_disable_device(pdev);
+err_dev_unreg:
+ device_destroy(b3dfg_class, devno);
+err_del_cdev:
+ cdev_del(&fgdev->chardev);
+err_release_minor:
+ b3dfg_devices[minor] = 0;
+err_free:
+ kfree(fgdev);
+ return r;
+}
+
+static void __devexit b3dfg_remove(struct pci_dev *pdev)
+{
+ struct b3dfg_dev *fgdev = pci_get_drvdata(pdev);
+ unsigned int minor = MINOR(fgdev->chardev.dev);
+
+ dev_dbg(&pdev->dev, "remove\n");
+
+ free_irq(pdev->irq, fgdev);
+ iounmap(fgdev->regs);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ device_destroy(b3dfg_class, MKDEV(MAJOR(b3dfg_devt), minor));
+ cdev_del(&fgdev->chardev);
+ free_all_frame_buffers(fgdev);
+ kfree(fgdev);
+ b3dfg_devices[minor] = 0;
+}
+
+static struct pci_driver b3dfg_driver = {
+ .name = DRIVER_NAME,
+ .id_table = b3dfg_ids,
+ .probe = b3dfg_probe,
+ .remove = __devexit_p(b3dfg_remove),
+};
+
+static int __init b3dfg_module_init(void)
+{
+ int r;
+
+ if (b3dfg_nbuf < 2) {
+ printk(KERN_ERR DRIVER_NAME
+ ": buffer_count is out of range (must be >= 2)");
+ return -EINVAL;
+ }
+
+ printk(KERN_INFO DRIVER_NAME ": loaded\n");
+
+ b3dfg_class = class_create(THIS_MODULE, DRIVER_NAME);
+ if (IS_ERR(b3dfg_class))
+ return PTR_ERR(b3dfg_class);
+
+ r = alloc_chrdev_region(&b3dfg_devt, 0, B3DFG_MAX_DEVS, DRIVER_NAME);
+ if (r)
+ goto err1;
+
+ r = pci_register_driver(&b3dfg_driver);
+ if (r)
+ goto err2;
+
+ return r;
+
+err2:
+ unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
+err1:
+ class_destroy(b3dfg_class);
+ return r;
+}
+
+static void __exit b3dfg_module_exit(void)
+{
+ printk(KERN_INFO DRIVER_NAME ": unloaded\n");
+ pci_unregister_driver(&b3dfg_driver);
+ unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
+ class_destroy(b3dfg_class);
+}
+
+module_init(b3dfg_module_init);
+module_exit(b3dfg_module_exit);
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index b47ca1e7e38..2d819d278b0 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -1,11 +1,18 @@
config COMEDI
- tristate "Data Acquision support (comedi)"
+ tristate "Data acquisition support (comedi)"
default N
depends on m
---help---
- Enable support a wide range of data acquision devices
+ Enable support a wide range of data acquisition devices
for Linux.
+config COMEDI_DEBUG
+ bool "Comedi debugging"
+ depends on COMEDI != n
+ help
+ This is an option for use by developers; most people should
+ say N here. This enables comedi core and driver debugging.
+
config COMEDI_RT
tristate "Comedi Real-time support"
depends on COMEDI && RT
@@ -20,6 +27,13 @@ config COMEDI_PCI_DRIVERS
---help---
Enable lots of comedi PCI drivers to be built
+config COMEDI_PCMCIA_DRIVERS
+ tristate "Comedi PCMCIA drivers"
+ depends on COMEDI && PCMCIAI
+ default N
+ ---help---
+ Enable lots of comedi PCMCIA drivers to be built
+
config COMEDI_USB_DRIVERS
tristate "Comedi USB drivers"
depends on COMEDI && USB
diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h
index 36d2e1b01e7..e6b5f16edb0 100644
--- a/drivers/staging/comedi/comedi.h
+++ b/drivers/staging/comedi/comedi.h
@@ -57,9 +57,6 @@ extern "C" {
/* max length of device and driver names */
#define COMEDI_NAMELEN 20
- typedef unsigned int lsampl_t;
- typedef unsigned short sampl_t;
-
/* packs and unpacks a channel/range number */
#define CR_PACK(chan, rng, aref) ((((aref)&0x3)<<24) | (((rng)&0xff)<<16) | (chan))
@@ -261,10 +258,11 @@ enum configuration_ids {
INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */
INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */
/* INSN_CONFIG_GET_OTHER_SRC = 2006,*/ /* Get other source */
- INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE, /* Get size in bytes of
- subdevice's on-board fifos
- used during streaming
- input/output */
+ INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006, /* Get size in bytes of
+ subdevice's on-board
+ fifos used during
+ streaming
+ input/output */
INSN_CONFIG_SET_COUNTER_MODE = 4097,
INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE, /* deprecated */
INSN_CONFIG_8254_READ_STATUS = 4098,
@@ -293,45 +291,32 @@ enum comedi_support_level {
/* ioctls */
#define CIO 'd'
-#define COMEDI_DEVCONFIG _IOW(CIO, 0, comedi_devconfig)
-#define COMEDI_DEVINFO _IOR(CIO, 1, comedi_devinfo)
-#define COMEDI_SUBDINFO _IOR(CIO, 2, comedi_subdinfo)
-#define COMEDI_CHANINFO _IOR(CIO, 3, comedi_chaninfo)
+#define COMEDI_DEVCONFIG _IOW(CIO, 0, struct comedi_devconfig)
+#define COMEDI_DEVINFO _IOR(CIO, 1, struct comedi_devinfo)
+#define COMEDI_SUBDINFO _IOR(CIO, 2, struct comedi_subdinfo)
+#define COMEDI_CHANINFO _IOR(CIO, 3, struct comedi_chaninfo)
#define COMEDI_TRIG _IOWR(CIO, 4, comedi_trig)
#define COMEDI_LOCK _IO(CIO, 5)
#define COMEDI_UNLOCK _IO(CIO, 6)
#define COMEDI_CANCEL _IO(CIO, 7)
-#define COMEDI_RANGEINFO _IOR(CIO, 8, comedi_rangeinfo)
-#define COMEDI_CMD _IOR(CIO, 9, comedi_cmd)
-#define COMEDI_CMDTEST _IOR(CIO, 10, comedi_cmd)
-#define COMEDI_INSNLIST _IOR(CIO, 11, comedi_insnlist)
-#define COMEDI_INSN _IOR(CIO, 12, comedi_insn)
-#define COMEDI_BUFCONFIG _IOR(CIO, 13, comedi_bufconfig)
-#define COMEDI_BUFINFO _IOWR(CIO, 14, comedi_bufinfo)
+#define COMEDI_RANGEINFO _IOR(CIO, 8, struct comedi_rangeinfo)
+#define COMEDI_CMD _IOR(CIO, 9, struct comedi_cmd)
+#define COMEDI_CMDTEST _IOR(CIO, 10, struct comedi_cmd)
+#define COMEDI_INSNLIST _IOR(CIO, 11, struct comedi_insnlist)
+#define COMEDI_INSN _IOR(CIO, 12, struct comedi_insn)
+#define COMEDI_BUFCONFIG _IOR(CIO, 13, struct comedi_bufconfig)
+#define COMEDI_BUFINFO _IOWR(CIO, 14, struct comedi_bufinfo)
#define COMEDI_POLL _IO(CIO, 15)
/* structures */
-typedef struct comedi_trig_struct comedi_trig;
-typedef struct comedi_cmd_struct comedi_cmd;
-typedef struct comedi_insn_struct comedi_insn;
-typedef struct comedi_insnlist_struct comedi_insnlist;
-typedef struct comedi_chaninfo_struct comedi_chaninfo;
-typedef struct comedi_subdinfo_struct comedi_subdinfo;
-typedef struct comedi_devinfo_struct comedi_devinfo;
-typedef struct comedi_devconfig_struct comedi_devconfig;
-typedef struct comedi_rangeinfo_struct comedi_rangeinfo;
-typedef struct comedi_krange_struct comedi_krange;
-typedef struct comedi_bufconfig_struct comedi_bufconfig;
-typedef struct comedi_bufinfo_struct comedi_bufinfo;
-
-struct comedi_trig_struct {
+struct comedi_trig {
unsigned int subdev; /* subdevice */
unsigned int mode; /* mode */
unsigned int flags;
unsigned int n_chan; /* number of channels */
unsigned int *chanlist; /* channel/range list */
- sampl_t *data; /* data list, size depends on subd flags */
+ short *data; /* data list, size depends on subd flags */
unsigned int n; /* number of scans */
unsigned int trigsrc;
unsigned int trigvar;
@@ -340,21 +325,21 @@ struct comedi_trig_struct {
unsigned int unused[3];
};
-struct comedi_insn_struct {
+struct comedi_insn {
unsigned int insn;
unsigned int n;
- lsampl_t *data;
+ unsigned int *data;
unsigned int subdev;
unsigned int chanspec;
unsigned int unused[3];
};
-struct comedi_insnlist_struct {
+struct comedi_insnlist {
unsigned int n_insns;
- comedi_insn *insns;
+ struct comedi_insn *insns;
};
-struct comedi_cmd_struct {
+struct comedi_cmd {
unsigned int subdev;
unsigned int flags;
@@ -376,37 +361,37 @@ struct comedi_cmd_struct {
unsigned int *chanlist; /* channel/range list */
unsigned int chanlist_len;
- sampl_t *data; /* data list, size depends on subd flags */
+ short *data; /* data list, size depends on subd flags */
unsigned int data_len;
};
-struct comedi_chaninfo_struct {
+struct comedi_chaninfo {
unsigned int subdev;
- lsampl_t *maxdata_list;
+ unsigned int *maxdata_list;
unsigned int *flaglist;
unsigned int *rangelist;
unsigned int unused[4];
};
-struct comedi_rangeinfo_struct {
+struct comedi_rangeinfo {
unsigned int range_type;
void *range_ptr;
};
-struct comedi_krange_struct {
+struct comedi_krange {
int min; /* fixed point, multiply by 1e-6 */
int max; /* fixed point, multiply by 1e-6 */
unsigned int flags;
};
-struct comedi_subdinfo_struct {
+struct comedi_subdinfo {
unsigned int type;
unsigned int n_chan;
unsigned int subd_flags;
unsigned int timer_type;
unsigned int len_chanlist;
- lsampl_t maxdata;
+ unsigned int maxdata;
unsigned int flags; /* channel flags */
unsigned int range_type; /* lookup in kernel */
unsigned int settling_time_0;
@@ -414,7 +399,7 @@ struct comedi_subdinfo_struct {
unsigned int unused[8];
};
-struct comedi_devinfo_struct {
+struct comedi_devinfo {
unsigned int version_code;
unsigned int n_subdevs;
char driver_name[COMEDI_NAMELEN];
@@ -424,12 +409,12 @@ struct comedi_devinfo_struct {
int unused[30];
};
-struct comedi_devconfig_struct {
+struct comedi_devconfig {
char board_name[COMEDI_NAMELEN];
int options[COMEDI_NDEVCONFOPTS];
};
-struct comedi_bufconfig_struct {
+struct comedi_bufconfig {
unsigned int subdevice;
unsigned int flags;
@@ -439,7 +424,7 @@ struct comedi_bufconfig_struct {
unsigned int unused[4];
};
-struct comedi_bufinfo_struct {
+struct comedi_bufinfo {
unsigned int subdevice;
unsigned int bytes_read;
diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c
index 7d0116bcb9f..1b9c2a7c824 100644
--- a/drivers/staging/comedi/comedi_compat32.c
+++ b/drivers/staging/comedi/comedi_compat32.c
@@ -37,31 +37,31 @@
#include <linux/ioctl32.h> /* for (un)register_ioctl32_conversion */
#endif
-#define COMEDI32_CHANINFO _IOR(CIO,3,comedi32_chaninfo)
-#define COMEDI32_RANGEINFO _IOR(CIO,8,comedi32_rangeinfo)
+#define COMEDI32_CHANINFO _IOR(CIO, 3, struct comedi32_chaninfo_struct)
+#define COMEDI32_RANGEINFO _IOR(CIO, 8, struct comedi32_rangeinfo_struct)
/* N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR.
* It's too late to change it now, but it only affects the command number. */
-#define COMEDI32_CMD _IOR(CIO,9,comedi32_cmd)
+#define COMEDI32_CMD _IOR(CIO, 9, struct comedi32_cmd_struct)
/* N.B. COMEDI32_CMDTEST and COMEDI_CMDTEST ought to use _IOWR, not _IOR.
* It's too late to change it now, but it only affects the command number. */
-#define COMEDI32_CMDTEST _IOR(CIO,10,comedi32_cmd)
-#define COMEDI32_INSNLIST _IOR(CIO,11,comedi32_insnlist)
-#define COMEDI32_INSN _IOR(CIO,12,comedi32_insn)
+#define COMEDI32_CMDTEST _IOR(CIO, 10, struct comedi32_cmd_struct)
+#define COMEDI32_INSNLIST _IOR(CIO, 11, struct comedi32_insnlist_struct)
+#define COMEDI32_INSN _IOR(CIO, 12, struct comedi32_insn_struct)
-typedef struct comedi32_chaninfo_struct {
+struct comedi32_chaninfo_struct {
unsigned int subdev;
- compat_uptr_t maxdata_list; /* 32-bit 'lsampl_t *' */
+ compat_uptr_t maxdata_list; /* 32-bit 'unsigned int *' */
compat_uptr_t flaglist; /* 32-bit 'unsigned int *' */
compat_uptr_t rangelist; /* 32-bit 'unsigned int *' */
unsigned int unused[4];
-} comedi32_chaninfo;
+};
-typedef struct comedi32_rangeinfo_struct {
+struct comedi32_rangeinfo_struct {
unsigned int range_type;
compat_uptr_t range_ptr; /* 32-bit 'void *' */
-} comedi32_rangeinfo;
+};
-typedef struct comedi32_cmd_struct {
+struct comedi32_cmd_struct {
unsigned int subdev;
unsigned int flags;
unsigned int start_src;
@@ -76,37 +76,36 @@ typedef struct comedi32_cmd_struct {
unsigned int stop_arg;
compat_uptr_t chanlist; /* 32-bit 'unsigned int *' */
unsigned int chanlist_len;
- compat_uptr_t data; /* 32-bit 'sampl_t *' */
+ compat_uptr_t data; /* 32-bit 'short *' */
unsigned int data_len;
-} comedi32_cmd;
+};
-typedef struct comedi32_insn_struct {
+struct comedi32_insn_struct {
unsigned int insn;
unsigned int n;
- compat_uptr_t data; /* 32-bit 'lsampl_t *' */
+ compat_uptr_t data; /* 32-bit 'unsigned int *' */
unsigned int subdev;
unsigned int chanspec;
unsigned int unused[3];
-} comedi32_insn;
+};
-typedef struct comedi32_insnlist_struct {
+struct comedi32_insnlist_struct {
unsigned int n_insns;
- compat_uptr_t insns; /* 32-bit 'comedi_insn *' */
-} comedi32_insnlist;
+ compat_uptr_t insns; /* 32-bit 'struct comedi_insn *' */
+};
/* Handle translated ioctl. */
static int translated_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
- if (!file->f_op) {
+ if (!file->f_op)
return -ENOTTY;
- }
+
#ifdef HAVE_UNLOCKED_IOCTL
if (file->f_op->unlocked_ioctl) {
int rc = (int)(*file->f_op->unlocked_ioctl)(file, cmd, arg);
- if (rc == -ENOIOCTLCMD) {
+ if (rc == -ENOIOCTLCMD)
rc = -ENOTTY;
- }
return rc;
}
#endif
@@ -124,8 +123,8 @@ static int translated_ioctl(struct file *file, unsigned int cmd,
/* Handle 32-bit COMEDI_CHANINFO ioctl. */
static int compat_chaninfo(struct file *file, unsigned long arg)
{
- comedi_chaninfo __user *chaninfo;
- comedi32_chaninfo __user *chaninfo32;
+ struct comedi_chaninfo __user *chaninfo;
+ struct comedi32_chaninfo_struct __user *chaninfo32;
int err;
union {
unsigned int uint;
@@ -150,9 +149,8 @@ static int compat_chaninfo(struct file *file, unsigned long arg)
err |= __put_user(compat_ptr(temp.uptr), &chaninfo->flaglist);
err |= __get_user(temp.uptr, &chaninfo32->rangelist);
err |= __put_user(compat_ptr(temp.uptr), &chaninfo->rangelist);
- if (err) {
+ if (err)
return -EFAULT;
- }
return translated_ioctl(file, COMEDI_CHANINFO, (unsigned long)chaninfo);
}
@@ -160,8 +158,8 @@ static int compat_chaninfo(struct file *file, unsigned long arg)
/* Handle 32-bit COMEDI_RANGEINFO ioctl. */
static int compat_rangeinfo(struct file *file, unsigned long arg)
{
- comedi_rangeinfo __user *rangeinfo;
- comedi32_rangeinfo __user *rangeinfo32;
+ struct comedi_rangeinfo __user *rangeinfo;
+ struct comedi32_rangeinfo_struct __user *rangeinfo32;
int err;
union {
unsigned int uint;
@@ -182,17 +180,16 @@ static int compat_rangeinfo(struct file *file, unsigned long arg)
err |= __put_user(temp.uint, &rangeinfo->range_type);
err |= __get_user(temp.uptr, &rangeinfo32->range_ptr);
err |= __put_user(compat_ptr(temp.uptr), &rangeinfo->range_ptr);
- if (err) {
+ if (err)
return -EFAULT;
- }
return translated_ioctl(file, COMEDI_RANGEINFO,
(unsigned long)rangeinfo);
}
/* Copy 32-bit cmd structure to native cmd structure. */
-static int get_compat_cmd(comedi_cmd __user *cmd,
- comedi32_cmd __user *cmd32)
+static int get_compat_cmd(struct comedi_cmd __user *cmd,
+ struct comedi32_cmd_struct __user *cmd32)
{
int err;
union {
@@ -242,7 +239,7 @@ static int get_compat_cmd(comedi_cmd __user *cmd,
}
/* Copy native cmd structure to 32-bit cmd structure. */
-static int put_compat_cmd(comedi32_cmd __user *cmd32, comedi_cmd __user *cmd)
+static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32, struct comedi_cmd __user *cmd)
{
int err;
unsigned int temp;
@@ -292,17 +289,16 @@ static int put_compat_cmd(comedi32_cmd __user *cmd32, comedi_cmd __user *cmd)
/* Handle 32-bit COMEDI_CMD ioctl. */
static int compat_cmd(struct file *file, unsigned long arg)
{
- comedi_cmd __user *cmd;
- comedi32_cmd __user *cmd32;
+ struct comedi_cmd __user *cmd;
+ struct comedi32_cmd_struct __user *cmd32;
int rc;
cmd32 = compat_ptr(arg);
cmd = compat_alloc_user_space(sizeof(*cmd));
rc = get_compat_cmd(cmd, cmd32);
- if (rc) {
+ if (rc)
return rc;
- }
return translated_ioctl(file, COMEDI_CMD, (unsigned long)cmd);
}
@@ -310,33 +306,31 @@ static int compat_cmd(struct file *file, unsigned long arg)
/* Handle 32-bit COMEDI_CMDTEST ioctl. */
static int compat_cmdtest(struct file *file, unsigned long arg)
{
- comedi_cmd __user *cmd;
- comedi32_cmd __user *cmd32;
+ struct comedi_cmd __user *cmd;
+ struct comedi32_cmd_struct __user *cmd32;
int rc, err;
cmd32 = compat_ptr(arg);
cmd = compat_alloc_user_space(sizeof(*cmd));
rc = get_compat_cmd(cmd, cmd32);
- if (rc) {
+ if (rc)
return rc;
- }
rc = translated_ioctl(file, COMEDI_CMDTEST, (unsigned long)cmd);
- if (rc < 0) {
+ if (rc < 0)
return rc;
- }
err = put_compat_cmd(cmd32, cmd);
- if (err) {
+ if (err)
rc = err;
- }
+
return rc;
}
/* Copy 32-bit insn structure to native insn structure. */
-static int get_compat_insn(comedi_insn __user *insn,
- comedi32_insn __user *insn32)
+static int get_compat_insn(struct comedi_insn __user *insn,
+ struct comedi32_insn_struct __user *insn32)
{
int err;
union {
@@ -347,9 +341,9 @@ static int get_compat_insn(comedi_insn __user *insn,
/* Copy insn structure. Ignore the unused members. */
err = 0;
if (!access_ok(VERIFY_READ, insn32, sizeof(*insn32))
- || !access_ok(VERIFY_WRITE, insn, sizeof(*insn))) {
+ || !access_ok(VERIFY_WRITE, insn, sizeof(*insn)))
return -EFAULT;
- }
+
err |= __get_user(temp.uint, &insn32->insn);
err |= __put_user(temp.uint, &insn->insn);
err |= __get_user(temp.uint, &insn32->n);
@@ -367,11 +361,11 @@ static int get_compat_insn(comedi_insn __user *insn,
static int compat_insnlist(struct file *file, unsigned long arg)
{
struct combined_insnlist {
- comedi_insnlist insnlist;
- comedi_insn insn[1];
+ struct comedi_insnlist insnlist;
+ struct comedi_insn insn[1];
} __user *s;
- comedi32_insnlist __user *insnlist32;
- comedi32_insn __user *insn32;
+ struct comedi32_insnlist_struct __user *insnlist32;
+ struct comedi32_insn_struct __user *insn32;
compat_uptr_t uptr;
unsigned int n_insns, n;
int err, rc;
@@ -386,9 +380,8 @@ static int compat_insnlist(struct file *file, unsigned long arg)
err |= __get_user(n_insns, &insnlist32->n_insns);
err |= __get_user(uptr, &insnlist32->insns);
insn32 = compat_ptr(uptr);
- if (err) {
+ if (err)
return -EFAULT;
- }
/* Allocate user memory to copy insnlist and insns into. */
s = compat_alloc_user_space(offsetof(struct combined_insnlist,
@@ -400,16 +393,14 @@ static int compat_insnlist(struct file *file, unsigned long arg)
}
err |= __put_user(n_insns, &s->insnlist.n_insns);
err |= __put_user(&s->insn[0], &s->insnlist.insns);
- if (err) {
+ if (err)
return -EFAULT;
- }
/* Copy insn structures. */
for (n = 0; n < n_insns; n++) {
rc = get_compat_insn(&s->insn[n], &insn32[n]);
- if (rc) {
+ if (rc)
return rc;
- }
}
return translated_ioctl(file, COMEDI_INSNLIST,
@@ -419,17 +410,16 @@ static int compat_insnlist(struct file *file, unsigned long arg)
/* Handle 32-bit COMEDI_INSN ioctl. */
static int compat_insn(struct file *file, unsigned long arg)
{
- comedi_insn __user *insn;
- comedi32_insn __user *insn32;
+ struct comedi_insn __user *insn;
+ struct comedi32_insn_struct __user *insn32;
int rc;
insn32 = compat_ptr(arg);
insn = compat_alloc_user_space(sizeof(*insn));
rc = get_compat_insn(insn, insn32);
- if (rc) {
+ if (rc)
return rc;
- }
return translated_ioctl(file, COMEDI_INSN, (unsigned long)insn);
}
@@ -512,14 +502,14 @@ static int mapped_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
int rc;
/* Make sure we are dealing with a Comedi device. */
- if (imajor(file->f_dentry->d_inode) != COMEDI_MAJOR) {
+ if (imajor(file->f_dentry->d_inode) != COMEDI_MAJOR)
return -ENOTTY;
- }
+
rc = raw_ioctl(file, cmd, arg);
/* Do not return -ENOIOCTLCMD. */
- if (rc == -ENOIOCTLCMD) {
+ if (rc == -ENOIOCTLCMD)
rc = -ENOTTY;
- }
+
return rc;
}
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 018c964396d..19dce2ebfc1 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -59,33 +59,39 @@ int comedi_debug;
module_param(comedi_debug, int, 0644);
#endif
+int comedi_autoconfig = 1;
+module_param(comedi_autoconfig, bool, 0444);
+
+int comedi_num_legacy_minors = 0;
+module_param(comedi_num_legacy_minors, int, 0444);
+
static DEFINE_SPINLOCK(comedi_file_info_table_lock);
static struct comedi_device_file_info
*comedi_file_info_table[COMEDI_NUM_MINORS];
-static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg);
-static int do_bufconfig_ioctl(comedi_device *dev, void *arg);
-static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
+static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *arg);
+static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg);
+static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *arg,
struct file *file);
-static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
+static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *arg,
void *file);
-static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg);
-static int do_bufinfo_ioctl(comedi_device *dev, void *arg);
-static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file);
-static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file);
-static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file);
-static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_insn_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_poll_ioctl(comedi_device *dev, unsigned int subd, void *file);
-
-extern void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s);
-static int do_cancel(comedi_device *dev, comedi_subdevice *s);
+static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *arg);
+static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg);
+static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file);
+static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, void *file);
+static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *file);
+static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file);
+static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file);
+static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file);
+static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file);
+static int do_poll_ioctl(struct comedi_device *dev, unsigned int subd, void *file);
+
+extern void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s);
+static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
static int comedi_fasync(int fd, struct file *file, int on);
-static int is_device_busy(comedi_device *dev);
+static int is_device_busy(struct comedi_device *dev);
#ifdef HAVE_UNLOCKED_IOCTL
static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
@@ -98,9 +104,13 @@ static int comedi_ioctl(struct inode *inode, struct file *file,
const unsigned minor = iminor(file->f_dentry->d_inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
+ struct comedi_device *dev;
int rc;
+ if (dev_file_info == NULL || dev_file_info->device == NULL)
+ return -ENODEV;
+ dev = dev_file_info->device;
+
mutex_lock(&dev->mutex);
/* Device config is special, because it must work on
@@ -182,9 +192,9 @@ done:
writes:
none
*/
-static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
+static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *arg)
{
- comedi_devconfig it;
+ struct comedi_devconfig it;
int ret;
unsigned char *aux_data = NULL;
int aux_len;
@@ -203,7 +213,7 @@ static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
return 0;
}
- if (copy_from_user(&it, arg, sizeof(comedi_devconfig)))
+ if (copy_from_user(&it, arg, sizeof(struct comedi_devconfig)))
return -EFAULT;
it.board_name[COMEDI_NAMELEN - 1] = 0;
@@ -262,14 +272,14 @@ static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
modified bufconfig at arg
*/
-static int do_bufconfig_ioctl(comedi_device *dev, void *arg)
+static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg)
{
- comedi_bufconfig bc;
- comedi_async *async;
- comedi_subdevice *s;
+ struct comedi_bufconfig bc;
+ struct comedi_async *async;
+ struct comedi_subdevice *s;
int ret = 0;
- if (copy_from_user(&bc, arg, sizeof(comedi_bufconfig)))
+ if (copy_from_user(&bc, arg, sizeof(struct comedi_bufconfig)))
return -EFAULT;
if (bc.subdevice >= dev->n_subdevices || bc.subdevice < 0)
@@ -330,7 +340,7 @@ static int do_bufconfig_ioctl(comedi_device *dev, void *arg)
bc.maximum_size = async->max_bufsize;
copyback:
- if (copy_to_user(arg, &bc, sizeof(comedi_bufconfig)))
+ if (copy_to_user(arg, &bc, sizeof(struct comedi_bufconfig)))
return -EFAULT;
return 0;
@@ -350,16 +360,16 @@ copyback:
devinfo structure
*/
-static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
+static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *arg,
struct file *file)
{
- comedi_devinfo devinfo;
+ struct comedi_devinfo devinfo;
const unsigned minor = iminor(file->f_dentry->d_inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_subdevice *read_subdev =
+ struct comedi_subdevice *read_subdev =
comedi_get_read_subdevice(dev_file_info);
- comedi_subdevice *write_subdev =
+ struct comedi_subdevice *write_subdev =
comedi_get_write_subdevice(dev_file_info);
memset(&devinfo, 0, sizeof(devinfo));
@@ -380,7 +390,7 @@ static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
else
devinfo.write_subdevice = -1;
- if (copy_to_user(arg, &devinfo, sizeof(comedi_devinfo)))
+ if (copy_to_user(arg, &devinfo, sizeof(struct comedi_devinfo)))
return -EFAULT;
return 0;
@@ -400,14 +410,14 @@ static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
array of subdevice info structures at arg
*/
-static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
+static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *arg,
void *file)
{
int ret, i;
- comedi_subdinfo *tmp, *us;
- comedi_subdevice *s;
+ struct comedi_subdinfo *tmp, *us;
+ struct comedi_subdevice *s;
- tmp = kcalloc(dev->n_subdevices, sizeof(comedi_subdinfo), GFP_KERNEL);
+ tmp = kcalloc(dev->n_subdevices, sizeof(struct comedi_subdinfo), GFP_KERNEL);
if (!tmp)
return -ENOMEM;
@@ -459,7 +469,7 @@ static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
}
ret = copy_to_user(arg, tmp,
- dev->n_subdevices * sizeof(comedi_subdinfo));
+ dev->n_subdevices * sizeof(struct comedi_subdinfo));
kfree(tmp);
@@ -480,12 +490,12 @@ static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
arrays at elements of chaninfo structure
*/
-static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
+static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *arg)
{
- comedi_subdevice *s;
- comedi_chaninfo it;
+ struct comedi_subdevice *s;
+ struct comedi_chaninfo it;
- if (copy_from_user(&it, arg, sizeof(comedi_chaninfo)))
+ if (copy_from_user(&it, arg, sizeof(struct comedi_chaninfo)))
return -EFAULT;
if (it.subdev >= dev->n_subdevices)
@@ -496,7 +506,7 @@ static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
if (s->maxdata || !s->maxdata_list)
return -EINVAL;
if (copy_to_user(it.maxdata_list, s->maxdata_list,
- s->n_chan * sizeof(lsampl_t)))
+ s->n_chan * sizeof(unsigned int)))
return -EFAULT;
}
@@ -544,13 +554,13 @@ static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
modified bufinfo at arg
*/
-static int do_bufinfo_ioctl(comedi_device *dev, void *arg)
+static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg)
{
- comedi_bufinfo bi;
- comedi_subdevice *s;
- comedi_async *async;
+ struct comedi_bufinfo bi;
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
- if (copy_from_user(&bi, arg, sizeof(comedi_bufinfo)))
+ if (copy_from_user(&bi, arg, sizeof(struct comedi_bufinfo)))
return -EFAULT;
if (bi.subdevice >= dev->n_subdevices || bi.subdevice < 0)
@@ -591,13 +601,13 @@ static int do_bufinfo_ioctl(comedi_device *dev, void *arg)
bi.buf_read_ptr = async->buf_read_ptr;
copyback:
- if (copy_to_user(arg, &bi, sizeof(comedi_bufinfo)))
+ if (copy_to_user(arg, &bi, sizeof(struct comedi_bufinfo)))
return -EFAULT;
return 0;
}
-static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
+static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
void *file);
/*
* COMEDI_INSNLIST
@@ -616,25 +626,25 @@ static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
*/
/* arbitrary limits */
#define MAX_SAMPLES 256
-static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file)
{
- comedi_insnlist insnlist;
- comedi_insn *insns = NULL;
- lsampl_t *data = NULL;
+ struct comedi_insnlist insnlist;
+ struct comedi_insn *insns = NULL;
+ unsigned int *data = NULL;
int i = 0;
int ret = 0;
- if (copy_from_user(&insnlist, arg, sizeof(comedi_insnlist)))
+ if (copy_from_user(&insnlist, arg, sizeof(struct comedi_insnlist)))
return -EFAULT;
- data = kmalloc(sizeof(lsampl_t) * MAX_SAMPLES, GFP_KERNEL);
+ data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
if (!data) {
DPRINTK("kmalloc failed\n");
ret = -ENOMEM;
goto error;
}
- insns = kmalloc(sizeof(comedi_insn) * insnlist.n_insns, GFP_KERNEL);
+ insns = kmalloc(sizeof(struct comedi_insn) * insnlist.n_insns, GFP_KERNEL);
if (!insns) {
DPRINTK("kmalloc failed\n");
ret = -ENOMEM;
@@ -642,7 +652,7 @@ static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
}
if (copy_from_user(insns, insnlist.insns,
- sizeof(comedi_insn) * insnlist.n_insns)) {
+ sizeof(struct comedi_insn) * insnlist.n_insns)) {
DPRINTK("copy_from_user failed\n");
ret = -EFAULT;
goto error;
@@ -656,7 +666,7 @@ static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
}
if (insns[i].insn & INSN_MASK_WRITE) {
if (copy_from_user(data, insns[i].data,
- insns[i].n * sizeof(lsampl_t))) {
+ insns[i].n * sizeof(unsigned int))) {
DPRINTK("copy_from_user failed\n");
ret = -EFAULT;
goto error;
@@ -667,7 +677,7 @@ static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
goto error;
if (insns[i].insn & INSN_MASK_READ) {
if (copy_to_user(insns[i].data, data,
- insns[i].n * sizeof(lsampl_t))) {
+ insns[i].n * sizeof(unsigned int))) {
DPRINTK("copy_to_user failed\n");
ret = -EFAULT;
goto error;
@@ -686,7 +696,7 @@ error:
return i;
}
-static int check_insn_config_length(comedi_insn *insn, lsampl_t *data)
+static int check_insn_config_length(struct comedi_insn *insn, unsigned int *data)
{
if (insn->n < 1)
return -EINVAL;
@@ -747,10 +757,10 @@ static int check_insn_config_length(comedi_insn *insn, lsampl_t *data)
return -EINVAL;
}
-static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
+static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
void *file)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
int ret = 0;
int i;
@@ -815,7 +825,7 @@ static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
}
} else {
/* a subdevice instruction */
- lsampl_t maxdata;
+ unsigned int maxdata;
if (insn->subdev >= dev->n_subdevices) {
DPRINTK("subdevice %d out of range\n", insn->subdev);
@@ -901,25 +911,25 @@ out:
* pointer to insn
*
* reads:
- * comedi_insn struct at arg
+ * struct comedi_insn struct at arg
* data (for writes)
*
* writes:
* data (for reads)
*/
-static int do_insn_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file)
{
- comedi_insn insn;
- lsampl_t *data = NULL;
+ struct comedi_insn insn;
+ unsigned int *data = NULL;
int ret = 0;
- data = kmalloc(sizeof(lsampl_t) * MAX_SAMPLES, GFP_KERNEL);
+ data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto error;
}
- if (copy_from_user(&insn, arg, sizeof(comedi_insn))) {
+ if (copy_from_user(&insn, arg, sizeof(struct comedi_insn))) {
ret = -EFAULT;
goto error;
}
@@ -928,7 +938,7 @@ static int do_insn_ioctl(comedi_device *dev, void *arg, void *file)
if (insn.n > MAX_SAMPLES)
insn.n = MAX_SAMPLES;
if (insn.insn & INSN_MASK_WRITE) {
- if (copy_from_user(data, insn.data, insn.n * sizeof(lsampl_t))) {
+ if (copy_from_user(data, insn.data, insn.n * sizeof(unsigned int))) {
ret = -EFAULT;
goto error;
}
@@ -937,7 +947,7 @@ static int do_insn_ioctl(comedi_device *dev, void *arg, void *file)
if (ret < 0)
goto error;
if (insn.insn & INSN_MASK_READ) {
- if (copy_to_user(insn.data, data, insn.n * sizeof(lsampl_t))) {
+ if (copy_to_user(insn.data, data, insn.n * sizeof(unsigned int))) {
ret = -EFAULT;
goto error;
}
@@ -965,15 +975,15 @@ error:
modified cmd structure at arg
*/
-static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file)
{
- comedi_cmd user_cmd;
- comedi_subdevice *s;
- comedi_async *async;
+ struct comedi_cmd user_cmd;
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
int ret = 0;
unsigned int *chanlist_saver = NULL;
- if (copy_from_user(&user_cmd, arg, sizeof(comedi_cmd))) {
+ if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) {
DPRINTK("bad cmd address\n");
return -EFAULT;
}
@@ -1062,7 +1072,7 @@ static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file)
/* restore chanlist pointer before copying back */
user_cmd.chanlist = chanlist_saver;
user_cmd.data = NULL;
- if (copy_to_user(arg, &user_cmd, sizeof(comedi_cmd))) {
+ if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) {
DPRINTK("fault writing cmd\n");
ret = -EFAULT;
goto cleanup;
@@ -1119,15 +1129,15 @@ cleanup:
modified cmd structure at arg
*/
-static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file)
{
- comedi_cmd user_cmd;
- comedi_subdevice *s;
+ struct comedi_cmd user_cmd;
+ struct comedi_subdevice *s;
int ret = 0;
unsigned int *chanlist = NULL;
unsigned int *chanlist_saver = NULL;
- if (copy_from_user(&user_cmd, arg, sizeof(comedi_cmd))) {
+ if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) {
DPRINTK("bad cmd address\n");
return -EFAULT;
}
@@ -1191,7 +1201,7 @@ static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file)
/* restore chanlist pointer before copying back */
user_cmd.chanlist = chanlist_saver;
- if (copy_to_user(arg, &user_cmd, sizeof(comedi_cmd))) {
+ if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) {
DPRINTK("bad cmd address\n");
ret = -EFAULT;
goto cleanup;
@@ -1217,11 +1227,11 @@ cleanup:
*/
-static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
{
int ret = 0;
unsigned long flags;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
if (arg >= dev->n_subdevices)
return -EINVAL;
@@ -1261,9 +1271,9 @@ static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file)
This function isn't protected by the semaphore, since
we already own the lock.
*/
-static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
if (arg >= dev->n_subdevices)
return -EINVAL;
@@ -1301,9 +1311,9 @@ static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file)
nothing
*/
-static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
if (arg >= dev->n_subdevices)
return -EINVAL;
@@ -1337,9 +1347,9 @@ static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file)
nothing
*/
-static int do_poll_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
if (arg >= dev->n_subdevices)
return -EINVAL;
@@ -1360,7 +1370,7 @@ static int do_poll_ioctl(comedi_device *dev, unsigned int arg, void *file)
return -EINVAL;
}
-static int do_cancel(comedi_device *dev, comedi_subdevice *s)
+static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
int ret = 0;
@@ -1374,8 +1384,8 @@ static int do_cancel(comedi_device *dev, comedi_subdevice *s)
void comedi_unmap(struct vm_area_struct *area)
{
- comedi_async *async;
- comedi_device *dev;
+ struct comedi_async *async;
+ struct comedi_device *dev;
async = area->vm_private_data;
dev = async->subdevice->device;
@@ -1394,14 +1404,14 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
const unsigned minor = iminor(file->f_dentry->d_inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
- comedi_async *async = NULL;
+ struct comedi_device *dev = dev_file_info->device;
+ struct comedi_async *async = NULL;
unsigned long start = vma->vm_start;
unsigned long size;
int n_pages;
int i;
int retval;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
mutex_lock(&dev->mutex);
if (!dev->attached) {
@@ -1470,9 +1480,9 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
const unsigned minor = iminor(file->f_dentry->d_inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
- comedi_subdevice *read_subdev;
- comedi_subdevice *write_subdev;
+ struct comedi_device *dev = dev_file_info->device;
+ struct comedi_subdevice *read_subdev;
+ struct comedi_subdevice *write_subdev;
mutex_lock(&dev->mutex);
if (!dev->attached) {
@@ -1513,14 +1523,14 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
loff_t *offset)
{
- comedi_subdevice *s;
- comedi_async *async;
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
int n, m, count = 0, retval = 0;
DECLARE_WAITQUEUE(wait, current);
const unsigned minor = iminor(file->f_dentry->d_inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
+ struct comedi_device *dev = dev_file_info->device;
if (!dev->attached) {
DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1615,14 +1625,14 @@ done:
static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
loff_t *offset)
{
- comedi_subdevice *s;
- comedi_async *async;
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
int n, m, count = 0, retval = 0;
DECLARE_WAITQUEUE(wait, current);
const unsigned minor = iminor(file->f_dentry->d_inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
+ struct comedi_device *dev = dev_file_info->device;
if (!dev->attached) {
DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1723,9 +1733,9 @@ done:
/*
This function restores a subdevice to an idle state.
*/
-void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s)
+void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_async *async = s->async;
+ struct comedi_async *async = s->async;
comedi_set_subdevice_runflags(s, SRF_RUNNING, 0);
#ifdef CONFIG_COMEDI_RT
@@ -1747,11 +1757,11 @@ void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s)
static int comedi_open(struct inode *inode, struct file *file)
{
- char mod[32];
const unsigned minor = iminor(inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
+ struct comedi_device *dev = dev_file_info ? dev_file_info->device : NULL;
+
if (dev == NULL) {
DPRINTK("invalid minor number\n");
return -ENODEV;
@@ -1783,10 +1793,9 @@ static int comedi_open(struct inode *inode, struct file *file)
dev->in_request_module = 1;
- sprintf(mod, "char-major-%i-%i", COMEDI_MAJOR, dev->minor);
#ifdef CONFIG_KMOD
mutex_unlock(&dev->mutex);
- request_module(mod);
+ request_module("char-major-%i-%i", COMEDI_MAJOR, dev->minor);
mutex_lock(&dev->mutex);
#endif
@@ -1823,8 +1832,8 @@ static int comedi_close(struct inode *inode, struct file *file)
const unsigned minor = iminor(inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
- comedi_subdevice *s = NULL;
+ struct comedi_device *dev = dev_file_info->device;
+ struct comedi_subdevice *s = NULL;
int i;
mutex_lock(&dev->mutex);
@@ -1862,7 +1871,7 @@ static int comedi_fasync(int fd, struct file *file, int on)
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
+ struct comedi_device *dev = dev_file_info->device;
return fasync_helper(fd, file, on, &dev->async_queue);
}
@@ -1893,7 +1902,7 @@ static void comedi_cleanup_legacy_minors(void)
{
unsigned i;
- for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++)
+ for (i = 0; i < comedi_num_legacy_minors; i++)
comedi_free_board_minor(i);
}
@@ -1905,6 +1914,22 @@ static int __init comedi_init(void)
printk(KERN_INFO "comedi: version " COMEDI_RELEASE
" - http://www.comedi.org\n");
+ if (comedi_num_legacy_minors < 0 ||
+ comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) {
+ printk(KERN_ERR "comedi: error: invalid value for module "
+ "parameter \"comedi_num_legacy_minors\". Valid values "
+ "are 0 through %i.\n", COMEDI_NUM_BOARD_MINORS);
+ return -EINVAL;
+ }
+
+ /*
+ * comedi is unusable if both comedi_autoconfig and
+ * comedi_num_legacy_minors are zero, so we might as well adjust the
+ * defaults in that case
+ */
+ if (comedi_autoconfig == 0 && comedi_num_legacy_minors == 0)
+ comedi_num_legacy_minors = 16;
+
memset(comedi_file_info_table, 0,
sizeof(struct comedi_device_file_info *) * COMEDI_NUM_MINORS);
@@ -1933,7 +1958,7 @@ static int __init comedi_init(void)
comedi_proc_init();
/* create devices files for legacy/manual use */
- for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++) {
+ for (i = 0; i < comedi_num_legacy_minors; i++) {
int minor;
minor = comedi_alloc_board_minor(NULL);
if (minor < 0) {
@@ -1975,15 +2000,15 @@ static void __exit comedi_cleanup(void)
module_init(comedi_init);
module_exit(comedi_cleanup);
-void comedi_error(const comedi_device *dev, const char *s)
+void comedi_error(const struct comedi_device *dev, const char *s)
{
rt_printk("comedi%d: %s: %s\n", dev->minor, dev->driver->driver_name,
s);
}
-void comedi_event(comedi_device *dev, comedi_subdevice *s)
+void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_async *async = s->async;
+ struct comedi_async *async = s->async;
unsigned runflags = 0;
unsigned runflags_mask = 0;
@@ -2042,7 +2067,7 @@ void comedi_event(comedi_device *dev, comedi_subdevice *s)
s->async->events = 0;
}
-void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
+void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask,
unsigned bits)
{
unsigned long flags;
@@ -2053,7 +2078,7 @@ void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
comedi_spin_unlock_irqrestore(&s->spin_lock, flags);
}
-unsigned comedi_get_subdevice_runflags(comedi_subdevice *s)
+unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s)
{
unsigned long flags;
unsigned runflags;
@@ -2064,9 +2089,9 @@ unsigned comedi_get_subdevice_runflags(comedi_subdevice *s)
return runflags;
}
-static int is_device_busy(comedi_device *dev)
+static int is_device_busy(struct comedi_device *dev)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
int i;
if (!dev->attached)
@@ -2083,15 +2108,15 @@ static int is_device_busy(comedi_device *dev)
return 0;
}
-void comedi_device_init(comedi_device *dev)
+void comedi_device_init(struct comedi_device *dev)
{
- memset(dev, 0, sizeof(comedi_device));
+ memset(dev, 0, sizeof(struct comedi_device));
spin_lock_init(&dev->spinlock);
mutex_init(&dev->mutex);
dev->minor = -1;
}
-void comedi_device_cleanup(comedi_device *dev)
+void comedi_device_cleanup(struct comedi_device *dev)
{
if (dev == NULL)
return;
@@ -2105,13 +2130,13 @@ int comedi_alloc_board_minor(struct device *hardware_device)
{
unsigned long flags;
struct comedi_device_file_info *info;
- device_create_result_type *csdev;
+ struct device *csdev;
unsigned i;
info = kzalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL);
if (info == NULL)
return -ENOMEM;
- info->device = kzalloc(sizeof(comedi_device), GFP_KERNEL);
+ info->device = kzalloc(sizeof(struct comedi_device), GFP_KERNEL);
if (info->device == NULL) {
kfree(info);
return -ENOMEM;
@@ -2155,7 +2180,7 @@ void comedi_free_board_minor(unsigned minor)
comedi_spin_unlock_irqrestore(&comedi_file_info_table_lock, flags);
if (info) {
- comedi_device *dev = info->device;
+ struct comedi_device *dev = info->device;
if (dev) {
if (dev->class_dev) {
device_destroy(comedi_class,
@@ -2168,11 +2193,11 @@ void comedi_free_board_minor(unsigned minor)
}
}
-int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
+int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s)
{
unsigned long flags;
struct comedi_device_file_info *info;
- device_create_result_type *csdev;
+ struct device *csdev;
unsigned i;
info = kmalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL);
@@ -2182,7 +2207,7 @@ int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
info->read_subdevice = s;
info->write_subdevice = s;
comedi_spin_lock_irqsave(&comedi_file_info_table_lock, flags);
- for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_BOARD_MINORS; ++i) {
+ for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_MINORS; ++i) {
if (comedi_file_info_table[i] == NULL) {
comedi_file_info_table[i] = info;
break;
@@ -2206,7 +2231,7 @@ int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
return i;
}
-void comedi_free_subdevice_minor(comedi_subdevice *s)
+void comedi_free_subdevice_minor(struct comedi_subdevice *s)
{
unsigned long flags;
struct comedi_device_file_info *info;
diff --git a/drivers/staging/comedi/comedi_fops.h b/drivers/staging/comedi/comedi_fops.h
index 63f8df558e8..cb503c88c7f 100644
--- a/drivers/staging/comedi/comedi_fops.h
+++ b/drivers/staging/comedi/comedi_fops.h
@@ -4,5 +4,6 @@
extern struct class *comedi_class;
extern const struct file_operations comedi_fops;
+extern int comedi_autoconfig;
#endif /* _COMEDI_FOPS_H */
diff --git a/drivers/staging/comedi/comedi_ksyms.c b/drivers/staging/comedi/comedi_ksyms.c
index 90d57282efb..6e6fb979ef5 100644
--- a/drivers/staging/comedi/comedi_ksyms.c
+++ b/drivers/staging/comedi/comedi_ksyms.c
@@ -31,12 +31,12 @@
/* for drivers */
EXPORT_SYMBOL(comedi_driver_register);
EXPORT_SYMBOL(comedi_driver_unregister);
-//EXPORT_SYMBOL(comedi_bufcheck);
-//EXPORT_SYMBOL(comedi_done);
-//EXPORT_SYMBOL(comedi_error_done);
+/* EXPORT_SYMBOL(comedi_bufcheck); */
+/* EXPORT_SYMBOL(comedi_done); */
+/* EXPORT_SYMBOL(comedi_error_done); */
EXPORT_SYMBOL(comedi_error);
-//EXPORT_SYMBOL(comedi_eobuf);
-//EXPORT_SYMBOL(comedi_eos);
+/* EXPORT_SYMBOL(comedi_eobuf); */
+/* EXPORT_SYMBOL(comedi_eos); */
EXPORT_SYMBOL(comedi_event);
EXPORT_SYMBOL(comedi_get_subdevice_runflags);
EXPORT_SYMBOL(comedi_set_subdevice_runflags);
@@ -60,6 +60,8 @@ EXPORT_SYMBOL_GPL(comedi_alloc_board_minor);
EXPORT_SYMBOL_GPL(comedi_free_board_minor);
EXPORT_SYMBOL_GPL(comedi_pci_auto_config);
EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig);
+EXPORT_SYMBOL_GPL(comedi_usb_auto_config);
+EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig);
/* for kcomedilib */
EXPORT_SYMBOL(check_chanlist);
diff --git a/drivers/staging/comedi/comedi_rt.h b/drivers/staging/comedi/comedi_rt.h
index 61852bf5adc..169ca963312 100644
--- a/drivers/staging/comedi/comedi_rt.h
+++ b/drivers/staging/comedi/comedi_rt.h
@@ -28,7 +28,6 @@
#error comedi_rt.h should only be included by comedidev.h
#endif
-#include <linux/version.h>
#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <linux/errno.h>
@@ -59,12 +58,12 @@
int comedi_request_irq(unsigned int irq, irqreturn_t(*handler) (int,
void *PT_REGS_ARG), unsigned long flags, const char *device,
- comedi_device *dev_id);
-void comedi_free_irq(unsigned int irq, comedi_device *dev_id);
+ struct comedi_device *dev_id);
+void comedi_free_irq(unsigned int irq, struct comedi_device *dev_id);
void comedi_rt_init(void);
void comedi_rt_cleanup(void);
-int comedi_switch_to_rt(comedi_device *dev);
-void comedi_switch_to_non_rt(comedi_device *dev);
+int comedi_switch_to_rt(struct comedi_device *dev);
+void comedi_switch_to_non_rt(struct comedi_device *dev);
void comedi_rt_pend_wakeup(wait_queue_head_t *q);
extern int rt_pend_call(void (*func) (int arg1, void *arg2), int arg1,
void *arg2);
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
index 3735355d3c5..ea319360ae6 100644
--- a/drivers/staging/comedi/comedidev.h
+++ b/drivers/staging/comedi/comedidev.h
@@ -26,7 +26,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <linux/errno.h>
@@ -36,7 +35,6 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
-#include <linux/mm.h>
#include "interrupt.h"
#include <linux/dma-mapping.h>
#include <linux/uaccess.h>
@@ -55,9 +53,9 @@
#define COMEDI_INITCLEANUP_NOMODULE(x) \
static int __init x ## _init_module(void) \
- {return comedi_driver_register(&(x));} \
+ {return comedi_driver_register(&(x)); } \
static void __exit x ## _cleanup_module(void) \
- {comedi_driver_unregister(&(x));} \
+ {comedi_driver_unregister(&(x)); } \
module_init(x ## _init_module); \
module_exit(x ## _cleanup_module); \
@@ -120,23 +118,14 @@
#define PCI_VENDOR_ID_MEILHAUS 0x1402
#define COMEDI_NUM_MINORS 0x100
-#define COMEDI_NUM_LEGACY_MINORS 0x10
#define COMEDI_NUM_BOARD_MINORS 0x30
#define COMEDI_FIRST_SUBDEVICE_MINOR COMEDI_NUM_BOARD_MINORS
-typedef struct comedi_device_struct comedi_device;
-typedef struct comedi_subdevice_struct comedi_subdevice;
-typedef struct comedi_async_struct comedi_async;
-typedef struct comedi_driver_struct comedi_driver;
-typedef struct comedi_lrange_struct comedi_lrange;
-
-typedef struct device device_create_result_type;
-
#define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \
device_create(cs, ((parent) ? (parent) : (device)), devt, drvdata, fmt)
-struct comedi_subdevice_struct {
- comedi_device *device;
+struct comedi_subdevice {
+ struct comedi_device *device;
int type;
int n_chan;
volatile int subdev_flags;
@@ -144,7 +133,7 @@ struct comedi_subdevice_struct {
void *private;
- comedi_async *async;
+ struct comedi_async *async;
void *lock;
void *busy;
@@ -153,46 +142,46 @@ struct comedi_subdevice_struct {
int io_bits;
- lsampl_t maxdata; /* if maxdata==0, use list */
- const lsampl_t *maxdata_list; /* list is channel specific */
+ unsigned int maxdata; /* if maxdata==0, use list */
+ const unsigned int *maxdata_list; /* list is channel specific */
unsigned int flags;
const unsigned int *flaglist;
unsigned int settling_time_0;
- const comedi_lrange *range_table;
- const comedi_lrange *const *range_table_list;
+ const struct comedi_lrange *range_table;
+ const struct comedi_lrange *const *range_table_list;
unsigned int *chanlist; /* driver-owned chanlist (not used) */
- int (*insn_read) (comedi_device *, comedi_subdevice *, comedi_insn *,
- lsampl_t *);
- int (*insn_write) (comedi_device *, comedi_subdevice *, comedi_insn *,
- lsampl_t *);
- int (*insn_bits) (comedi_device *, comedi_subdevice *, comedi_insn *,
- lsampl_t *);
- int (*insn_config) (comedi_device *, comedi_subdevice *, comedi_insn *,
- lsampl_t *);
-
- int (*do_cmd) (comedi_device *, comedi_subdevice *);
- int (*do_cmdtest) (comedi_device *, comedi_subdevice *, comedi_cmd *);
- int (*poll) (comedi_device *, comedi_subdevice *);
- int (*cancel) (comedi_device *, comedi_subdevice *);
- /* int (*do_lock)(comedi_device *,comedi_subdevice *); */
- /* int (*do_unlock)(comedi_device *,comedi_subdevice *); */
+ int (*insn_read) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+ int (*insn_write) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+ int (*insn_bits) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+ int (*insn_config) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+
+ int (*do_cmd) (struct comedi_device *, struct comedi_subdevice *);
+ int (*do_cmdtest) (struct comedi_device *, struct comedi_subdevice *, struct comedi_cmd *);
+ int (*poll) (struct comedi_device *, struct comedi_subdevice *);
+ int (*cancel) (struct comedi_device *, struct comedi_subdevice *);
+ /* int (*do_lock)(struct comedi_device *,struct comedi_subdevice *); */
+ /* int (*do_unlock)(struct comedi_device *,struct comedi_subdevice *); */
/* called when the buffer changes */
- int (*buf_change) (comedi_device *dev, comedi_subdevice *s,
+ int (*buf_change) (struct comedi_device *dev, struct comedi_subdevice *s,
unsigned long new_size);
- void (*munge) (comedi_device *dev, comedi_subdevice *s, void *data,
+ void (*munge) (struct comedi_device *dev, struct comedi_subdevice *s, void *data,
unsigned int num_bytes, unsigned int start_chan_index);
enum dma_data_direction async_dma_dir;
unsigned int state;
- device_create_result_type *class_dev;
+ struct device *class_dev;
int minor;
};
@@ -201,8 +190,8 @@ struct comedi_buf_page {
dma_addr_t dma_addr;
};
-struct comedi_async_struct {
- comedi_subdevice *subdevice;
+struct comedi_async {
+ struct comedi_subdevice *subdevice;
void *prealloc_buf; /* pre-allocated buffer */
unsigned int prealloc_bufsz; /* buffer size, in bytes */
@@ -232,7 +221,7 @@ struct comedi_async_struct {
unsigned int events; /* events that have occurred */
- comedi_cmd cmd;
+ struct comedi_cmd cmd;
wait_queue_head_t wait_head;
@@ -241,17 +230,17 @@ struct comedi_async_struct {
int (*cb_func) (unsigned int flags, void *);
void *cb_arg;
- int (*inttrig) (comedi_device *dev, comedi_subdevice *s,
+ int (*inttrig) (struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int x);
};
-struct comedi_driver_struct {
- struct comedi_driver_struct *next;
+struct comedi_driver {
+ struct comedi_driver *next;
const char *driver_name;
struct module *module;
- int (*attach) (comedi_device *, comedi_devconfig *);
- int (*detach) (comedi_device *);
+ int (*attach) (struct comedi_device *, struct comedi_devconfig *);
+ int (*detach) (struct comedi_device *);
/* number of elements in board_name and board_id arrays */
unsigned int num_names;
@@ -260,12 +249,12 @@ struct comedi_driver_struct {
int offset;
};
-struct comedi_device_struct {
+struct comedi_device {
int use_count;
- comedi_driver *driver;
+ struct comedi_driver *driver;
void *private;
- device_create_result_type *class_dev;
+ struct device *class_dev;
int minor;
/* hw_dev is passed to dma_alloc_coherent when allocating async buffers
* for subdevices that have async_dma_dir set to something other than
@@ -281,25 +270,25 @@ struct comedi_device_struct {
int in_request_module;
int n_subdevices;
- comedi_subdevice *subdevices;
+ struct comedi_subdevice *subdevices;
/* dumb */
unsigned long iobase;
unsigned int irq;
- comedi_subdevice *read_subdev;
- comedi_subdevice *write_subdev;
+ struct comedi_subdevice *read_subdev;
+ struct comedi_subdevice *write_subdev;
struct fasync_struct *async_queue;
- void (*open) (comedi_device *dev);
- void (*close) (comedi_device *dev);
+ void (*open) (struct comedi_device *dev);
+ void (*close) (struct comedi_device *dev);
};
struct comedi_device_file_info {
- comedi_device *device;
- comedi_subdevice *read_subdevice;
- comedi_subdevice *write_subdevice;
+ struct comedi_device *device;
+ struct comedi_subdevice *read_subdevice;
+ struct comedi_subdevice *write_subdevice;
};
#ifdef CONFIG_COMEDI_DEBUG
@@ -312,8 +301,8 @@ static const int comedi_debug;
* function prototypes
*/
-void comedi_event(comedi_device *dev, comedi_subdevice *s);
-void comedi_error(const comedi_device *dev, const char *s);
+void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s);
+void comedi_error(const struct comedi_device *dev, const char *s);
/* we can expand the number of bits used to encode devices/subdevices into
the minor number soon, after more distros support > 8 bit minor numbers
@@ -327,7 +316,7 @@ static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1;
struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor);
-static inline comedi_subdevice *comedi_get_read_subdevice(
+static inline struct comedi_subdevice *comedi_get_read_subdevice(
const struct comedi_device_file_info *info)
{
if (info->read_subdevice)
@@ -337,7 +326,7 @@ static inline comedi_subdevice *comedi_get_read_subdevice(
return info->device->read_subdev;
}
-static inline comedi_subdevice *comedi_get_write_subdevice(
+static inline struct comedi_subdevice *comedi_get_write_subdevice(
const struct comedi_device_file_info *info)
{
if (info->write_subdevice)
@@ -347,17 +336,17 @@ static inline comedi_subdevice *comedi_get_write_subdevice(
return info->device->write_subdev;
}
-void comedi_device_detach(comedi_device *dev);
-int comedi_device_attach(comedi_device *dev, comedi_devconfig *it);
-int comedi_driver_register(comedi_driver *);
-int comedi_driver_unregister(comedi_driver *);
+void comedi_device_detach(struct comedi_device *dev);
+int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+int comedi_driver_register(struct comedi_driver *);
+int comedi_driver_unregister(struct comedi_driver *);
void init_polling(void);
void cleanup_polling(void);
-void start_polling(comedi_device *);
-void stop_polling(comedi_device *);
+void start_polling(struct comedi_device *);
+void stop_polling(struct comedi_device *);
-int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s, unsigned long
+int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long
new_size);
#ifdef CONFIG_PROC_FS
@@ -386,13 +375,13 @@ enum subdevice_runflags {
various internal comedi functions
*/
-int do_rangeinfo_ioctl(comedi_device *dev, comedi_rangeinfo *arg);
-int check_chanlist(comedi_subdevice *s, int n, unsigned int *chanlist);
-void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
+int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg);
+int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist);
+void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask,
unsigned bits);
-unsigned comedi_get_subdevice_runflags(comedi_subdevice *s);
-int insn_inval(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data);
+unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s);
+int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
/* range stuff */
@@ -403,12 +392,12 @@ int insn_inval(comedi_device *dev, comedi_subdevice *s,
#define BIP_RANGE(a) {-(a)*1e6, (a)*1e6, 0}
#define UNI_RANGE(a) {0, (a)*1e6, 0}
-extern const comedi_lrange range_bipolar10;
-extern const comedi_lrange range_bipolar5;
-extern const comedi_lrange range_bipolar2_5;
-extern const comedi_lrange range_unipolar10;
-extern const comedi_lrange range_unipolar5;
-extern const comedi_lrange range_unknown;
+extern const struct comedi_lrange range_bipolar10;
+extern const struct comedi_lrange range_bipolar5;
+extern const struct comedi_lrange range_bipolar2_5;
+extern const struct comedi_lrange range_unipolar10;
+extern const struct comedi_lrange range_unipolar5;
+extern const struct comedi_lrange range_unknown;
#define range_digital range_unipolar5
@@ -418,21 +407,21 @@ extern const comedi_lrange range_unknown;
#define GCC_ZERO_LENGTH_ARRAY 0
#endif
-struct comedi_lrange_struct {
+struct comedi_lrange {
int length;
- comedi_krange range[GCC_ZERO_LENGTH_ARRAY];
+ struct comedi_krange range[GCC_ZERO_LENGTH_ARRAY];
};
/* some silly little inline functions */
-static inline int alloc_subdevices(comedi_device *dev,
+static inline int alloc_subdevices(struct comedi_device *dev,
unsigned int num_subdevices)
{
unsigned i;
dev->n_subdevices = num_subdevices;
dev->subdevices =
- kcalloc(num_subdevices, sizeof(comedi_subdevice), GFP_KERNEL);
+ kcalloc(num_subdevices, sizeof(struct comedi_subdevice), GFP_KERNEL);
if (!dev->subdevices)
return -ENOMEM;
for (i = 0; i < num_subdevices; ++i) {
@@ -444,7 +433,7 @@ static inline int alloc_subdevices(comedi_device *dev,
return 0;
}
-static inline int alloc_private(comedi_device *dev, int size)
+static inline int alloc_private(struct comedi_device *dev, int size)
{
dev->private = kzalloc(size, GFP_KERNEL);
if (!dev->private)
@@ -452,17 +441,17 @@ static inline int alloc_private(comedi_device *dev, int size)
return 0;
}
-static inline unsigned int bytes_per_sample(const comedi_subdevice *subd)
+static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)
{
if (subd->subdev_flags & SDF_LSAMPL)
- return sizeof(lsampl_t);
+ return sizeof(unsigned int);
else
- return sizeof(sampl_t);
+ return sizeof(short);
}
/* must be used in attach to set dev->hw_dev if you wish to dma directly
into comedi's buffer */
-static inline void comedi_set_hw_dev(comedi_device *dev, struct device *hw_dev)
+static inline void comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev)
{
if (dev->hw_dev)
put_device(dev->hw_dev);
@@ -474,31 +463,31 @@ static inline void comedi_set_hw_dev(comedi_device *dev, struct device *hw_dev)
}
}
-int comedi_buf_put(comedi_async *async, sampl_t x);
-int comedi_buf_get(comedi_async *async, sampl_t *x);
+int comedi_buf_put(struct comedi_async *async, short x);
+int comedi_buf_get(struct comedi_async *async, short *x);
-unsigned int comedi_buf_write_n_available(comedi_async *async);
-unsigned int comedi_buf_write_alloc(comedi_async *async, unsigned int nbytes);
-unsigned int comedi_buf_write_alloc_strict(comedi_async *async,
+unsigned int comedi_buf_write_n_available(struct comedi_async *async);
+unsigned int comedi_buf_write_alloc(struct comedi_async *async, unsigned int nbytes);
+unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
unsigned int nbytes);
-unsigned comedi_buf_write_free(comedi_async *async, unsigned int nbytes);
-unsigned comedi_buf_read_alloc(comedi_async *async, unsigned nbytes);
-unsigned comedi_buf_read_free(comedi_async *async, unsigned int nbytes);
-unsigned int comedi_buf_read_n_available(comedi_async *async);
-void comedi_buf_memcpy_to(comedi_async *async, unsigned int offset,
+unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes);
+unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes);
+unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes);
+unsigned int comedi_buf_read_n_available(struct comedi_async *async);
+void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
const void *source, unsigned int num_bytes);
-void comedi_buf_memcpy_from(comedi_async *async, unsigned int offset,
+void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
void *destination, unsigned int num_bytes);
-static inline unsigned comedi_buf_write_n_allocated(comedi_async *async)
+static inline unsigned comedi_buf_write_n_allocated(struct comedi_async *async)
{
return async->buf_write_alloc_count - async->buf_write_count;
}
-static inline unsigned comedi_buf_read_n_allocated(comedi_async *async)
+static inline unsigned comedi_buf_read_n_allocated(struct comedi_async *async)
{
return async->buf_read_alloc_count - async->buf_read_count;
}
-void comedi_reset_async_buf(comedi_async *async);
+void comedi_reset_async_buf(struct comedi_async *async);
static inline void *comedi_aux_data(int options[], int n)
{
@@ -527,10 +516,13 @@ static inline void *comedi_aux_data(int options[], int n)
int comedi_alloc_board_minor(struct device *hardware_device);
void comedi_free_board_minor(unsigned minor);
-int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s);
-void comedi_free_subdevice_minor(comedi_subdevice *s);
+int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s);
+void comedi_free_subdevice_minor(struct comedi_subdevice *s);
int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name);
void comedi_pci_auto_unconfig(struct pci_dev *pcidev);
+struct usb_device; /* forward declaration */
+int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name);
+void comedi_usb_auto_unconfig(struct usb_device *usbdev);
#include "comedi_rt.h"
diff --git a/drivers/staging/comedi/comedilib.h b/drivers/staging/comedi/comedilib.h
index fc5fc015726..c2729312d57 100644
--- a/drivers/staging/comedi/comedilib.h
+++ b/drivers/staging/comedi/comedilib.h
@@ -36,18 +36,16 @@
#ifndef KCOMEDILIB_DEPRECATED
-typedef void comedi_t;
-
/* these functions may not be called at real-time priority */
-comedi_t *comedi_open(const char *path);
-int comedi_close(comedi_t *dev);
+void *comedi_open(const char *path);
+int comedi_close(void *dev);
/* these functions may be called at any priority, but may fail at
real-time priority */
-int comedi_lock(comedi_t *dev, unsigned int subdev);
-int comedi_unlock(comedi_t *dev, unsigned int subdev);
+int comedi_lock(void *dev, unsigned int subdev);
+int comedi_unlock(void *dev, unsigned int subdev);
/* these functions may be called at any priority, but you must hold
the lock for the subdevice */
@@ -56,68 +54,68 @@ int comedi_loglevel(int loglevel);
void comedi_perror(const char *s);
char *comedi_strerror(int errnum);
int comedi_errno(void);
-int comedi_fileno(comedi_t *dev);
+int comedi_fileno(void *dev);
-int comedi_cancel(comedi_t *dev, unsigned int subdev);
-int comedi_register_callback(comedi_t *dev, unsigned int subdev,
+int comedi_cancel(void *dev, unsigned int subdev);
+int comedi_register_callback(void *dev, unsigned int subdev,
unsigned int mask, int (*cb) (unsigned int, void *), void *arg);
-int comedi_command(comedi_t *dev, comedi_cmd *cmd);
-int comedi_command_test(comedi_t *dev, comedi_cmd *cmd);
-int comedi_trigger(comedi_t *dev, unsigned int subdev, comedi_trig *it);
-int __comedi_trigger(comedi_t *dev, unsigned int subdev, comedi_trig *it);
-int comedi_data_write(comedi_t *dev, unsigned int subdev, unsigned int chan,
- unsigned int range, unsigned int aref, lsampl_t data);
-int comedi_data_read(comedi_t *dev, unsigned int subdev, unsigned int chan,
- unsigned int range, unsigned int aref, lsampl_t *data);
-int comedi_data_read_hint(comedi_t *dev, unsigned int subdev,
+int comedi_command(void *dev, struct comedi_cmd *cmd);
+int comedi_command_test(void *dev, struct comedi_cmd *cmd);
+int comedi_trigger(void *dev, unsigned int subdev, struct comedi_trig *it);
+int __comedi_trigger(void *dev, unsigned int subdev, struct comedi_trig *it);
+int comedi_data_write(void *dev, unsigned int subdev, unsigned int chan,
+ unsigned int range, unsigned int aref, unsigned int data);
+int comedi_data_read(void *dev, unsigned int subdev, unsigned int chan,
+ unsigned int range, unsigned int aref, unsigned int *data);
+int comedi_data_read_hint(void *dev, unsigned int subdev,
unsigned int chan, unsigned int range, unsigned int aref);
-int comedi_data_read_delayed(comedi_t *dev, unsigned int subdev,
+int comedi_data_read_delayed(void *dev, unsigned int subdev,
unsigned int chan, unsigned int range, unsigned int aref,
- lsampl_t *data, unsigned int nano_sec);
-int comedi_dio_config(comedi_t *dev, unsigned int subdev, unsigned int chan,
+ unsigned int *data, unsigned int nano_sec);
+int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan,
unsigned int io);
-int comedi_dio_read(comedi_t *dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan,
unsigned int *val);
-int comedi_dio_write(comedi_t *dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_write(void *dev, unsigned int subdev, unsigned int chan,
unsigned int val);
-int comedi_dio_bitfield(comedi_t *dev, unsigned int subdev, unsigned int mask,
+int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask,
unsigned int *bits);
-int comedi_get_n_subdevices(comedi_t *dev);
-int comedi_get_version_code(comedi_t *dev);
-const char *comedi_get_driver_name(comedi_t *dev);
-const char *comedi_get_board_name(comedi_t *dev);
-int comedi_get_subdevice_type(comedi_t *dev, unsigned int subdevice);
-int comedi_find_subdevice_by_type(comedi_t *dev, int type, unsigned int subd);
-int comedi_get_n_channels(comedi_t *dev, unsigned int subdevice);
-lsampl_t comedi_get_maxdata(comedi_t *dev, unsigned int subdevice, unsigned
+int comedi_get_n_subdevices(void *dev);
+int comedi_get_version_code(void *dev);
+const char *comedi_get_driver_name(void *dev);
+const char *comedi_get_board_name(void *dev);
+int comedi_get_subdevice_type(void *dev, unsigned int subdevice);
+int comedi_find_subdevice_by_type(void *dev, int type, unsigned int subd);
+int comedi_get_n_channels(void *dev, unsigned int subdevice);
+unsigned int comedi_get_maxdata(void *dev, unsigned int subdevice, unsigned
int chan);
-int comedi_get_n_ranges(comedi_t *dev, unsigned int subdevice, unsigned int
+int comedi_get_n_ranges(void *dev, unsigned int subdevice, unsigned int
chan);
-int comedi_do_insn(comedi_t *dev, comedi_insn *insn);
-int comedi_poll(comedi_t *dev, unsigned int subdev);
+int comedi_do_insn(void *dev, struct comedi_insn *insn);
+int comedi_poll(void *dev, unsigned int subdev);
/* DEPRECATED functions */
-int comedi_get_rangetype(comedi_t *dev, unsigned int subdevice,
+int comedi_get_rangetype(void *dev, unsigned int subdevice,
unsigned int chan);
/* ALPHA functions */
-unsigned int comedi_get_subdevice_flags(comedi_t *dev, unsigned int subdevice);
-int comedi_get_len_chanlist(comedi_t *dev, unsigned int subdevice);
-int comedi_get_krange(comedi_t *dev, unsigned int subdevice, unsigned int
- chan, unsigned int range, comedi_krange *krange);
-unsigned int comedi_get_buf_head_pos(comedi_t *dev, unsigned int subdevice);
-int comedi_set_user_int_count(comedi_t *dev, unsigned int subdevice,
+unsigned int comedi_get_subdevice_flags(void *dev, unsigned int subdevice);
+int comedi_get_len_chanlist(void *dev, unsigned int subdevice);
+int comedi_get_krange(void *dev, unsigned int subdevice, unsigned int
+ chan, unsigned int range, struct comedi_krange *krange);
+unsigned int comedi_get_buf_head_pos(void *dev, unsigned int subdevice);
+int comedi_set_user_int_count(void *dev, unsigned int subdevice,
unsigned int buf_user_count);
-int comedi_map(comedi_t *dev, unsigned int subdev, void *ptr);
-int comedi_unmap(comedi_t *dev, unsigned int subdev);
-int comedi_get_buffer_size(comedi_t *dev, unsigned int subdev);
-int comedi_mark_buffer_read(comedi_t *dev, unsigned int subdevice,
+int comedi_map(void *dev, unsigned int subdev, void *ptr);
+int comedi_unmap(void *dev, unsigned int subdev);
+int comedi_get_buffer_size(void *dev, unsigned int subdev);
+int comedi_mark_buffer_read(void *dev, unsigned int subdevice,
unsigned int num_bytes);
-int comedi_mark_buffer_written(comedi_t *d, unsigned int subdevice,
+int comedi_mark_buffer_written(void *d, unsigned int subdevice,
unsigned int num_bytes);
-int comedi_get_buffer_contents(comedi_t *dev, unsigned int subdevice);
-int comedi_get_buffer_offset(comedi_t *dev, unsigned int subdevice);
+int comedi_get_buffer_contents(void *dev, unsigned int subdevice);
+int comedi_get_buffer_offset(void *dev, unsigned int subdevice);
#else
@@ -139,14 +137,14 @@ int comedi_cancel(unsigned int minor, unsigned int subdev);
int comedi_register_callback(unsigned int minor, unsigned int subdev,
unsigned int mask, int (*cb) (unsigned int, void *), void *arg);
-int comedi_command(unsigned int minor, comedi_cmd *cmd);
-int comedi_command_test(unsigned int minor, comedi_cmd *cmd);
-int comedi_trigger(unsigned int minor, unsigned int subdev, comedi_trig *it);
-int __comedi_trigger(unsigned int minor, unsigned int subdev, comedi_trig *it);
+int comedi_command(unsigned int minor, struct comedi_cmd *cmd);
+int comedi_command_test(unsigned int minor, struct comedi_cmd *cmd);
+int comedi_trigger(unsigned int minor, unsigned int subdev, struct comedi_trig *it);
+int __comedi_trigger(unsigned int minor, unsigned int subdev, struct comedi_trig *it);
int comedi_data_write(unsigned int dev, unsigned int subdev, unsigned int chan,
- unsigned int range, unsigned int aref, lsampl_t data);
+ unsigned int range, unsigned int aref, unsigned int data);
int comedi_data_read(unsigned int dev, unsigned int subdev, unsigned int chan,
- unsigned int range, unsigned int aref, lsampl_t *data);
+ unsigned int range, unsigned int aref, unsigned int *data);
int comedi_dio_config(unsigned int dev, unsigned int subdev, unsigned int chan,
unsigned int io);
int comedi_dio_read(unsigned int dev, unsigned int subdev, unsigned int chan,
@@ -163,11 +161,11 @@ int comedi_get_subdevice_type(unsigned int minor, unsigned int subdevice);
int comedi_find_subdevice_by_type(unsigned int minor, int type,
unsigned int subd);
int comedi_get_n_channels(unsigned int minor, unsigned int subdevice);
-lsampl_t comedi_get_maxdata(unsigned int minor, unsigned int subdevice, unsigned
+unsigned int comedi_get_maxdata(unsigned int minor, unsigned int subdevice, unsigned
int chan);
int comedi_get_n_ranges(unsigned int minor, unsigned int subdevice, unsigned int
chan);
-int comedi_do_insn(unsigned int minor, comedi_insn *insn);
+int comedi_do_insn(unsigned int minor, struct comedi_insn *insn);
int comedi_poll(unsigned int minor, unsigned int subdev);
/* DEPRECATED functions */
@@ -179,7 +177,7 @@ unsigned int comedi_get_subdevice_flags(unsigned int minor, unsigned int
subdevice);
int comedi_get_len_chanlist(unsigned int minor, unsigned int subdevice);
int comedi_get_krange(unsigned int minor, unsigned int subdevice, unsigned int
- chan, unsigned int range, comedi_krange *krange);
+ chan, unsigned int range, struct comedi_krange *krange);
unsigned int comedi_get_buf_head_pos(unsigned int minor, unsigned int
subdevice);
int comedi_set_user_int_count(unsigned int minor, unsigned int subdevice,
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 36a93b95e3f..6e13e450dc7 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -28,6 +28,7 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/usb.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -46,26 +47,26 @@
#include <asm/io.h>
#include <asm/system.h>
-static int postconfig(comedi_device * dev);
-static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static void *comedi_recognize(comedi_driver * driv, const char *name);
-static void comedi_report_boards(comedi_driver * driv);
-static int poll_invalid(comedi_device * dev, comedi_subdevice * s);
-int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
+static int postconfig(struct comedi_device *dev);
+static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static void *comedi_recognize(struct comedi_driver * driv, const char *name);
+static void comedi_report_boards(struct comedi_driver *driv);
+static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s);
+int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned long new_size);
-comedi_driver *comedi_drivers;
+struct comedi_driver *comedi_drivers;
int comedi_modprobe(int minor)
{
return -EINVAL;
}
-static void cleanup_device(comedi_device * dev)
+static void cleanup_device(struct comedi_device *dev)
{
int i;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
if (dev->subdevices) {
for (i = 0; i < dev->n_subdevices; i++) {
@@ -80,10 +81,8 @@ static void cleanup_device(comedi_device * dev)
dev->subdevices = NULL;
dev->n_subdevices = 0;
}
- if (dev->private) {
- kfree(dev->private);
- dev->private = NULL;
- }
+ kfree(dev->private);
+ dev->private = NULL;
dev->driver = 0;
dev->board_name = NULL;
dev->board_ptr = NULL;
@@ -96,7 +95,7 @@ static void cleanup_device(comedi_device * dev)
comedi_set_hw_dev(dev, NULL);
}
-static void __comedi_device_detach(comedi_device * dev)
+static void __comedi_device_detach(struct comedi_device *dev)
{
dev->attached = 0;
if (dev->driver) {
@@ -107,16 +106,16 @@ static void __comedi_device_detach(comedi_device * dev)
cleanup_device(dev);
}
-void comedi_device_detach(comedi_device * dev)
+void comedi_device_detach(struct comedi_device *dev)
{
if (!dev->attached)
return;
__comedi_device_detach(dev);
}
-int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
+int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- comedi_driver *driv;
+ struct comedi_driver *driv;
int ret;
if (dev->attached)
@@ -139,7 +138,7 @@ int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
continue;
}
}
- //initialize dev->driver here so comedi_error() can be called from attach
+ /* initialize dev->driver here so comedi_error() can be called from attach */
dev->driver = driv;
ret = driv->attach(dev, it);
if (ret < 0) {
@@ -150,8 +149,8 @@ int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
goto attached;
}
- // recognize has failed if we get here
- // report valid board names before returning error
+ /* recognize has failed if we get here */
+ /* report valid board names before returning error */
for (driv = comedi_drivers; driv; driv = driv->next) {
if (!try_module_get(driv->module)) {
printk("comedi: failed to increment module count\n");
@@ -181,7 +180,7 @@ attached:
return 0;
}
-int comedi_driver_register(comedi_driver * driver)
+int comedi_driver_register(struct comedi_driver *driver)
{
driver->next = comedi_drivers;
comedi_drivers = driver;
@@ -189,15 +188,15 @@ int comedi_driver_register(comedi_driver * driver)
return 0;
}
-int comedi_driver_unregister(comedi_driver * driver)
+int comedi_driver_unregister(struct comedi_driver *driver)
{
- comedi_driver *prev;
+ struct comedi_driver *prev;
int i;
/* check for devices using this driver */
for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(i);
- comedi_device *dev;
+ struct comedi_device *dev;
if(dev_file_info == NULL) continue;
dev = dev_file_info->device;
@@ -225,11 +224,11 @@ int comedi_driver_unregister(comedi_driver * driver)
return -EINVAL;
}
-static int postconfig(comedi_device * dev)
+static int postconfig(struct comedi_device *dev)
{
int i;
- comedi_subdevice *s;
- comedi_async *async = NULL;
+ struct comedi_subdevice *s;
+ struct comedi_async *async = NULL;
int ret;
for (i = 0; i < dev->n_subdevices; i++) {
@@ -246,7 +245,7 @@ static int postconfig(comedi_device * dev)
SDF_CMD_WRITE)) == 0);
BUG_ON(!s->do_cmdtest);
- async = kzalloc(sizeof(comedi_async), GFP_KERNEL);
+ async = kzalloc(sizeof(struct comedi_async), GFP_KERNEL);
if (async == NULL) {
printk("failed to allocate async struct\n");
return -ENOMEM;
@@ -298,8 +297,8 @@ static int postconfig(comedi_device * dev)
return 0;
}
-// generic recognize function for drivers that register their supported board names
-void *comedi_recognize(comedi_driver * driv, const char *name)
+/* generic recognize function for drivers that register their supported board names */
+void *comedi_recognize(struct comedi_driver * driv, const char *name)
{
unsigned i;
const char *const *name_ptr = driv->board_name;
@@ -314,7 +313,7 @@ void *comedi_recognize(comedi_driver * driv, const char *name)
return NULL;
}
-void comedi_report_boards(comedi_driver * driv)
+void comedi_report_boards(struct comedi_driver *driv)
{
unsigned int i;
const char *const *name_ptr;
@@ -332,28 +331,28 @@ void comedi_report_boards(comedi_driver * driv)
printk(" %s\n", driv->driver_name);
}
-static int poll_invalid(comedi_device * dev, comedi_subdevice * s)
+static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
{
return -EINVAL;
}
-int insn_inval(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
return -EINVAL;
}
-static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
- comedi_insn new_insn;
+ struct comedi_insn new_insn;
int ret;
static const unsigned channels_per_bitfield = 32;
unsigned chan = CR_CHAN(insn->chanspec);
const unsigned base_bitfield_channel =
(chan < channels_per_bitfield) ? 0 : chan;
- lsampl_t new_data[2];
+ unsigned int new_data[2];
memset(new_data, 0, sizeof(new_data));
memset(&new_insn, 0, sizeof(new_insn));
new_insn.insn = INSN_BITS;
@@ -380,7 +379,7 @@ static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
return 1;
}
-static inline unsigned long uvirt_to_kva(pgd_t * pgd, unsigned long adr)
+static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
{
unsigned long ret = 0UL;
pmd_t *pmd;
@@ -413,10 +412,10 @@ static inline unsigned long kvirt_to_kva(unsigned long adr)
return kva;
}
-int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
+int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned long new_size)
{
- comedi_async *async = s->async;
+ struct comedi_async *async = s->async;
/* Round up new_size to multiple of PAGE_SIZE */
new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
@@ -425,7 +424,7 @@ int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
if (async->prealloc_buf && async->prealloc_bufsz == new_size) {
return 0;
}
- // deallocate old buffer
+ /* deallocate old buffer */
if (async->prealloc_buf) {
vunmap(async->prealloc_buf);
async->prealloc_buf = NULL;
@@ -454,7 +453,7 @@ int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
async->buf_page_list = NULL;
async->n_buf_pages = 0;
}
- // allocate new buffer
+ /* allocate new buffer */
if (new_size) {
unsigned i = 0;
unsigned n_pages = new_size >> PAGE_SHIFT;
@@ -537,16 +536,15 @@ int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
/* munging is applied to data by core as it passes between user
* and kernel space */
-unsigned int comedi_buf_munge(comedi_async * async, unsigned int num_bytes)
+unsigned int comedi_buf_munge(struct comedi_async *async, unsigned int num_bytes)
{
- comedi_subdevice *s = async->subdevice;
+ struct comedi_subdevice *s = async->subdevice;
unsigned int count = 0;
const unsigned num_sample_bytes = bytes_per_sample(s);
if (s->munge == NULL || (async->cmd.flags & CMDF_RAWDATA)) {
async->munge_count += num_bytes;
- if ((int)(async->munge_count - async->buf_write_count) > 0)
- BUG();
+ BUG_ON((int)(async->munge_count - async->buf_write_count) > 0);
return num_bytes;
}
/* don't munge partial samples */
@@ -567,7 +565,7 @@ unsigned int comedi_buf_munge(comedi_async * async, unsigned int num_bytes)
s->munge(s->device, s, async->prealloc_buf + async->munge_ptr,
block_size, async->munge_chan);
- smp_wmb(); //barrier insures data is munged in buffer before munge_count is incremented
+ smp_wmb(); /* barrier insures data is munged in buffer before munge_count is incremented */
async->munge_chan += block_size / num_sample_bytes;
async->munge_chan %= async->cmd.chanlist_len;
@@ -576,12 +574,11 @@ unsigned int comedi_buf_munge(comedi_async * async, unsigned int num_bytes)
async->munge_ptr %= async->prealloc_bufsz;
count += block_size;
}
- if ((int)(async->munge_count - async->buf_write_count) > 0)
- BUG();
+ BUG_ON((int)(async->munge_count - async->buf_write_count) > 0);
return count;
}
-unsigned int comedi_buf_write_n_available(comedi_async * async)
+unsigned int comedi_buf_write_n_available(struct comedi_async *async)
{
unsigned int free_end;
unsigned int nbytes;
@@ -601,7 +598,7 @@ unsigned int comedi_buf_write_n_available(comedi_async * async)
}
/* allocates chunk for the writer from free buffer space */
-unsigned int comedi_buf_write_alloc(comedi_async * async, unsigned int nbytes)
+unsigned int comedi_buf_write_alloc(struct comedi_async *async, unsigned int nbytes)
{
unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
@@ -616,7 +613,7 @@ unsigned int comedi_buf_write_alloc(comedi_async * async, unsigned int nbytes)
}
/* allocates nothing unless it can completely fulfill the request */
-unsigned int comedi_buf_write_alloc_strict(comedi_async * async,
+unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
unsigned int nbytes)
{
unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
@@ -632,7 +629,7 @@ unsigned int comedi_buf_write_alloc_strict(comedi_async * async,
}
/* transfers a chunk from writer to filled buffer space */
-unsigned comedi_buf_write_free(comedi_async * async, unsigned int nbytes)
+unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes)
{
if ((int)(async->buf_write_count + nbytes -
async->buf_write_alloc_count) > 0) {
@@ -650,7 +647,7 @@ unsigned comedi_buf_write_free(comedi_async * async, unsigned int nbytes)
}
/* allocates a chunk for the reader from filled (and munged) buffer space */
-unsigned comedi_buf_read_alloc(comedi_async * async, unsigned nbytes)
+unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes)
{
if ((int)(async->buf_read_alloc_count + nbytes - async->munge_count) >
0) {
@@ -664,9 +661,9 @@ unsigned comedi_buf_read_alloc(comedi_async * async, unsigned nbytes)
}
/* transfers control of a chunk from reader to free buffer space */
-unsigned comedi_buf_read_free(comedi_async * async, unsigned int nbytes)
+unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes)
{
- // barrier insures data has been read out of buffer before read count is incremented
+ /* barrier insures data has been read out of buffer before read count is incremented */
smp_mb();
if ((int)(async->buf_read_count + nbytes -
async->buf_read_alloc_count) > 0) {
@@ -680,7 +677,7 @@ unsigned comedi_buf_read_free(comedi_async * async, unsigned int nbytes)
return nbytes;
}
-void comedi_buf_memcpy_to(comedi_async * async, unsigned int offset,
+void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
const void *data, unsigned int num_bytes)
{
unsigned int write_ptr = async->buf_write_ptr + offset;
@@ -705,7 +702,7 @@ void comedi_buf_memcpy_to(comedi_async * async, unsigned int offset,
}
}
-void comedi_buf_memcpy_from(comedi_async * async, unsigned int offset,
+void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
void *dest, unsigned int nbytes)
{
void *src;
@@ -731,7 +728,7 @@ void comedi_buf_memcpy_from(comedi_async * async, unsigned int offset,
}
}
-unsigned int comedi_buf_read_n_available(comedi_async * async)
+unsigned int comedi_buf_read_n_available(struct comedi_async *async)
{
unsigned num_bytes;
@@ -746,32 +743,32 @@ unsigned int comedi_buf_read_n_available(comedi_async * async)
return num_bytes;
}
-int comedi_buf_get(comedi_async * async, sampl_t * x)
+int comedi_buf_get(struct comedi_async *async, short *x)
{
unsigned int n = comedi_buf_read_n_available(async);
- if (n < sizeof(sampl_t))
+ if (n < sizeof(short))
return 0;
- comedi_buf_read_alloc(async, sizeof(sampl_t));
- *x = *(sampl_t *) (async->prealloc_buf + async->buf_read_ptr);
- comedi_buf_read_free(async, sizeof(sampl_t));
+ comedi_buf_read_alloc(async, sizeof(short));
+ *x = *(short *) (async->prealloc_buf + async->buf_read_ptr);
+ comedi_buf_read_free(async, sizeof(short));
return 1;
}
-int comedi_buf_put(comedi_async * async, sampl_t x)
+int comedi_buf_put(struct comedi_async *async, short x)
{
- unsigned int n = comedi_buf_write_alloc_strict(async, sizeof(sampl_t));
+ unsigned int n = comedi_buf_write_alloc_strict(async, sizeof(short));
- if (n < sizeof(sampl_t)) {
+ if (n < sizeof(short)) {
async->events |= COMEDI_CB_ERROR;
return 0;
}
- *(sampl_t *) (async->prealloc_buf + async->buf_write_ptr) = x;
- comedi_buf_write_free(async, sizeof(sampl_t));
+ *(short *) (async->prealloc_buf + async->buf_write_ptr) = x;
+ comedi_buf_write_free(async, sizeof(short));
return 1;
}
-void comedi_reset_async_buf(comedi_async * async)
+void comedi_reset_async_buf(struct comedi_async *async)
{
async->buf_write_alloc_count = 0;
async->buf_write_count = 0;
@@ -792,14 +789,27 @@ void comedi_reset_async_buf(comedi_async * async)
int comedi_auto_config(struct device *hardware_device, const char *board_name, const int *options, unsigned num_options)
{
- comedi_devconfig it;
+ struct comedi_devconfig it;
int minor;
struct comedi_device_file_info *dev_file_info;
int retval;
+ unsigned *private_data = NULL;
+
+ if (!comedi_autoconfig) {
+ dev_set_drvdata(hardware_device, NULL);
+ return 0;
+ }
minor = comedi_alloc_board_minor(hardware_device);
if(minor < 0) return minor;
- dev_set_drvdata(hardware_device, (void*)(unsigned long)minor);
+
+ private_data = kmalloc(sizeof(unsigned), GFP_KERNEL);
+ if (private_data == NULL) {
+ retval = -ENOMEM;
+ goto cleanup;
+ }
+ *private_data = minor;
+ dev_set_drvdata(hardware_device, private_data);
dev_file_info = comedi_get_device_file_info(minor);
@@ -812,8 +822,11 @@ int comedi_auto_config(struct device *hardware_device, const char *board_name, c
mutex_lock(&dev_file_info->device->mutex);
retval = comedi_device_attach(dev_file_info->device, &it);
mutex_unlock(&dev_file_info->device->mutex);
+
+cleanup:
if(retval < 0)
{
+ kfree(private_data);
comedi_free_board_minor(minor);
}
return retval;
@@ -821,20 +834,23 @@ int comedi_auto_config(struct device *hardware_device, const char *board_name, c
void comedi_auto_unconfig(struct device *hardware_device)
{
- unsigned long minor = (unsigned long)dev_get_drvdata(hardware_device);
+ unsigned *minor = (unsigned *)dev_get_drvdata(hardware_device);
+ if(minor == NULL) return;
- BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS);
+ BUG_ON(*minor >= COMEDI_NUM_BOARD_MINORS);
- comedi_free_board_minor(minor);
+ comedi_free_board_minor(*minor);
+ dev_set_drvdata(hardware_device, NULL);
+ kfree(minor);
}
int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name)
{
int options[2];
- // pci bus
+ /* pci bus */
options[0] = pcidev->bus->number;
- // pci slot
+ /* pci slot */
options[1] = PCI_SLOT(pcidev->devfn);
return comedi_auto_config(&pcidev->dev, board_name, options, sizeof(options) / sizeof(options[0]));
@@ -844,3 +860,16 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev)
{
comedi_auto_unconfig(&pcidev->dev);
}
+
+int comedi_usb_auto_config(struct usb_device *usbdev,
+ const char *board_name)
+{
+ BUG_ON(usbdev == NULL);
+ return comedi_auto_config(&usbdev->dev, board_name, NULL, 0);
+}
+
+void comedi_usb_auto_unconfig(struct usb_device *usbdev)
+{
+ BUG_ON(usbdev == NULL);
+ comedi_auto_unconfig(&usbdev->dev);
+}
diff --git a/drivers/staging/comedi/drivers/8253.h b/drivers/staging/comedi/drivers/8253.h
new file mode 100644
index 00000000000..08a11a5a16e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/8253.h
@@ -0,0 +1,420 @@
+/*
+ comedi/drivers/8253.h
+ Header file for 8253
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _8253_H
+#define _8253_H
+
+#ifndef CMDTEST
+#include "../comedi.h"
+#else
+#include "../comedi.h"
+#endif
+
+#define i8253_cascade_ns_to_timer i8253_cascade_ns_to_timer_2div
+
+static inline void i8253_cascade_ns_to_timer_2div_old(int i8253_osc_base,
+ unsigned int *d1, unsigned int *d2, unsigned int *nanosec,
+ int round_mode)
+{
+ int divider;
+ int div1, div2;
+ int div1_glb, div2_glb, ns_glb;
+ int div1_lub, div2_lub, ns_lub;
+ int ns;
+
+ divider = (*nanosec + i8253_osc_base / 2) / i8253_osc_base;
+
+ /* find 2 integers 1<={x,y}<=65536 such that x*y is
+ close to divider */
+
+ div1_lub = div2_lub = 0;
+ div1_glb = div2_glb = 0;
+
+ ns_glb = 0;
+ ns_lub = 0xffffffff;
+
+ div2 = 0x10000;
+ for (div1 = divider / 65536 + 1; div1 < div2; div1++) {
+ div2 = divider / div1;
+
+ ns = i8253_osc_base * div1 * div2;
+ if (ns <= *nanosec && ns > ns_glb) {
+ ns_glb = ns;
+ div1_glb = div1;
+ div2_glb = div2;
+ }
+
+ div2++;
+ if (div2 <= 65536) {
+ ns = i8253_osc_base * div1 * div2;
+ if (ns > *nanosec && ns < ns_lub) {
+ ns_lub = ns;
+ div1_lub = div1;
+ div2_lub = div2;
+ }
+ }
+ }
+
+ *nanosec = div1_lub * div2_lub * i8253_osc_base;
+ *d1 = div1_lub & 0xffff;
+ *d2 = div2_lub & 0xffff;
+ return;
+}
+
+static inline void i8253_cascade_ns_to_timer_power(int i8253_osc_base,
+ unsigned int *d1, unsigned int *d2, unsigned int *nanosec,
+ int round_mode)
+{
+ int div1, div2;
+ int base;
+
+ for (div1 = 2; div1 <= (1 << 16); div1 <<= 1) {
+ base = i8253_osc_base * div1;
+ round_mode &= TRIG_ROUND_MASK;
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ div2 = (*nanosec + base / 2) / base;
+ break;
+ case TRIG_ROUND_DOWN:
+ div2 = (*nanosec) / base;
+ break;
+ case TRIG_ROUND_UP:
+ div2 = (*nanosec + base - 1) / base;
+ break;
+ }
+ if (div2 < 2)
+ div2 = 2;
+ if (div2 <= 65536) {
+ *nanosec = div2 * base;
+ *d1 = div1 & 0xffff;
+ *d2 = div2 & 0xffff;
+ return;
+ }
+ }
+
+ /* shouldn't get here */
+ div1 = 0x10000;
+ div2 = 0x10000;
+ *nanosec = div1 * div2 * i8253_osc_base;
+ *d1 = div1 & 0xffff;
+ *d2 = div2 & 0xffff;
+}
+
+static inline void i8253_cascade_ns_to_timer_2div(int i8253_osc_base,
+ unsigned int *d1, unsigned int *d2, unsigned int *nanosec,
+ int round_mode)
+{
+ unsigned int divider;
+ unsigned int div1, div2;
+ unsigned int div1_glb, div2_glb, ns_glb;
+ unsigned int div1_lub, div2_lub, ns_lub;
+ unsigned int ns;
+ unsigned int start;
+ unsigned int ns_low, ns_high;
+ static const unsigned int max_count = 0x10000;
+ /* exit early if everything is already correct (this can save time
+ * since this function may be called repeatedly during command tests
+ * and execution) */
+ div1 = *d1 ? *d1 : max_count;
+ div2 = *d2 ? *d2 : max_count;
+ divider = div1 * div2;
+ if (div1 * div2 * i8253_osc_base == *nanosec &&
+ div1 > 1 && div1 <= max_count &&
+ div2 > 1 && div2 <= max_count &&
+ /* check for overflow */
+ divider > div1 && divider > div2 &&
+ divider * i8253_osc_base > divider &&
+ divider * i8253_osc_base > i8253_osc_base) {
+ return;
+ }
+
+ divider = *nanosec / i8253_osc_base;
+
+ div1_lub = div2_lub = 0;
+ div1_glb = div2_glb = 0;
+
+ ns_glb = 0;
+ ns_lub = 0xffffffff;
+
+ div2 = max_count;
+ start = divider / div2;
+ if (start < 2)
+ start = 2;
+ for (div1 = start; div1 <= divider / div1 + 1 && div1 <= max_count;
+ div1++) {
+ for (div2 = divider / div1;
+ div1 * div2 <= divider + div1 + 1 && div2 <= max_count;
+ div2++) {
+ ns = i8253_osc_base * div1 * div2;
+ if (ns <= *nanosec && ns > ns_glb) {
+ ns_glb = ns;
+ div1_glb = div1;
+ div2_glb = div2;
+ }
+ if (ns >= *nanosec && ns < ns_lub) {
+ ns_lub = ns;
+ div1_lub = div1;
+ div2_lub = div2;
+ }
+ }
+ }
+
+ round_mode &= TRIG_ROUND_MASK;
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ ns_high = div1_lub * div2_lub * i8253_osc_base;
+ ns_low = div1_glb * div2_glb * i8253_osc_base;
+ if (ns_high - *nanosec < *nanosec - ns_low) {
+ div1 = div1_lub;
+ div2 = div2_lub;
+ } else {
+ div1 = div1_glb;
+ div2 = div2_glb;
+ }
+ break;
+ case TRIG_ROUND_UP:
+ div1 = div1_lub;
+ div2 = div2_lub;
+ break;
+ case TRIG_ROUND_DOWN:
+ div1 = div1_glb;
+ div2 = div2_glb;
+ break;
+ }
+
+ *nanosec = div1 * div2 * i8253_osc_base;
+ *d1 = div1 & 0xffff; // masking is done since counter maps zero to 0x10000
+ *d2 = div2 & 0xffff;
+ return;
+}
+
+#ifndef CMDTEST
+/* i8254_load programs 8254 counter chip. It should also work for the 8253.
+ * base_address is the lowest io address for the chip (the address of counter 0).
+ * counter_number is the counter you want to load (0,1 or 2)
+ * count is the number to load into the counter.
+ *
+ * You probably want to use mode 2.
+ *
+ * Use i8254_mm_load() if you board uses memory-mapped io, it is
+ * the same as i8254_load() except it uses writeb() instead of outb().
+ *
+ * Neither i8254_load() or i8254_read() do their loading/reading
+ * atomically. The 16 bit read/writes are performed with two successive
+ * 8 bit read/writes. So if two parts of your driver do a load/read on
+ * the same counter, it may be necessary to protect these functions
+ * with a spinlock.
+ *
+ * FMH
+ */
+
+#define i8254_control_reg 3
+
+static inline int i8254_load(unsigned long base_address, unsigned int regshift,
+ unsigned int counter_number, unsigned int count, unsigned int mode)
+{
+ unsigned int byte;
+
+ if (counter_number > 2)
+ return -1;
+ if (count > 0xffff)
+ return -1;
+ if (mode > 5)
+ return -1;
+ if ((mode == 2 || mode == 3) && count == 1)
+ return -1;
+
+ byte = counter_number << 6;
+ byte |= 0x30; // load low then high byte
+ byte |= (mode << 1); // set counter mode
+ outb(byte, base_address + (i8254_control_reg << regshift));
+ byte = count & 0xff; // lsb of counter value
+ outb(byte, base_address + (counter_number << regshift));
+ byte = (count >> 8) & 0xff; // msb of counter value
+ outb(byte, base_address + (counter_number << regshift));
+
+ return 0;
+}
+
+static inline int i8254_mm_load(void *base_address, unsigned int regshift,
+ unsigned int counter_number, unsigned int count, unsigned int mode)
+{
+ unsigned int byte;
+
+ if (counter_number > 2)
+ return -1;
+ if (count > 0xffff)
+ return -1;
+ if (mode > 5)
+ return -1;
+ if ((mode == 2 || mode == 3) && count == 1)
+ return -1;
+
+ byte = counter_number << 6;
+ byte |= 0x30; // load low then high byte
+ byte |= (mode << 1); // set counter mode
+ writeb(byte, base_address + (i8254_control_reg << regshift));
+ byte = count & 0xff; // lsb of counter value
+ writeb(byte, base_address + (counter_number << regshift));
+ byte = (count >> 8) & 0xff; // msb of counter value
+ writeb(byte, base_address + (counter_number << regshift));
+
+ return 0;
+}
+
+/* Returns 16 bit counter value, should work for 8253 also.*/
+static inline int i8254_read(unsigned long base_address, unsigned int regshift,
+ unsigned int counter_number)
+{
+ unsigned int byte;
+ int ret;
+
+ if (counter_number > 2)
+ return -1;
+
+ // latch counter
+ byte = counter_number << 6;
+ outb(byte, base_address + (i8254_control_reg << regshift));
+
+ // read lsb
+ ret = inb(base_address + (counter_number << regshift));
+ // read msb
+ ret += inb(base_address + (counter_number << regshift)) << 8;
+
+ return ret;
+}
+
+static inline int i8254_mm_read(void *base_address, unsigned int regshift,
+ unsigned int counter_number)
+{
+ unsigned int byte;
+ int ret;
+
+ if (counter_number > 2)
+ return -1;
+
+ // latch counter
+ byte = counter_number << 6;
+ writeb(byte, base_address + (i8254_control_reg << regshift));
+
+ // read lsb
+ ret = readb(base_address + (counter_number << regshift));
+ // read msb
+ ret += readb(base_address + (counter_number << regshift)) << 8;
+
+ return ret;
+}
+
+/* Loads 16 bit initial counter value, should work for 8253 also. */
+static inline void i8254_write(unsigned long base_address,
+ unsigned int regshift, unsigned int counter_number, unsigned int count)
+{
+ unsigned int byte;
+
+ if (counter_number > 2)
+ return;
+
+ byte = count & 0xff; // lsb of counter value
+ outb(byte, base_address + (counter_number << regshift));
+ byte = (count >> 8) & 0xff; // msb of counter value
+ outb(byte, base_address + (counter_number << regshift));
+}
+
+static inline void i8254_mm_write(void *base_address,
+ unsigned int regshift, unsigned int counter_number, unsigned int count)
+{
+ unsigned int byte;
+
+ if (counter_number > 2)
+ return;
+
+ byte = count & 0xff; // lsb of counter value
+ writeb(byte, base_address + (counter_number << regshift));
+ byte = (count >> 8) & 0xff; // msb of counter value
+ writeb(byte, base_address + (counter_number << regshift));
+}
+
+/* Set counter mode, should work for 8253 also.
+ * Note: the 'mode' value is different to that for i8254_load() and comes
+ * from the INSN_CONFIG_8254_SET_MODE command:
+ * I8254_MODE0, I8254_MODE1, ..., I8254_MODE5
+ * OR'ed with:
+ * I8254_BCD, I8254_BINARY
+ */
+static inline int i8254_set_mode(unsigned long base_address,
+ unsigned int regshift, unsigned int counter_number, unsigned int mode)
+{
+ unsigned int byte;
+
+ if (counter_number > 2)
+ return -1;
+ if (mode > (I8254_MODE5 | I8254_BINARY))
+ return -1;
+
+ byte = counter_number << 6;
+ byte |= 0x30; // load low then high byte
+ byte |= mode; // set counter mode and BCD|binary
+ outb(byte, base_address + (i8254_control_reg << regshift));
+
+ return 0;
+}
+
+static inline int i8254_mm_set_mode(void *base_address,
+ unsigned int regshift, unsigned int counter_number, unsigned int mode)
+{
+ unsigned int byte;
+
+ if (counter_number > 2)
+ return -1;
+ if (mode > (I8254_MODE5 | I8254_BINARY))
+ return -1;
+
+ byte = counter_number << 6;
+ byte |= 0x30; // load low then high byte
+ byte |= mode; // set counter mode and BCD|binary
+ writeb(byte, base_address + (i8254_control_reg << regshift));
+
+ return 0;
+}
+
+static inline int i8254_status(unsigned long base_address,
+ unsigned int regshift, unsigned int counter_number)
+{
+ outb(0xE0 | (2 << counter_number),
+ base_address + (i8254_control_reg << regshift));
+ return inb(base_address + (counter_number << regshift));
+}
+
+static inline int i8254_mm_status(void *base_address,
+ unsigned int regshift, unsigned int counter_number)
+{
+ writeb(0xE0 | (2 << counter_number),
+ base_address + (i8254_control_reg << regshift));
+ return readb(base_address + (counter_number << regshift));
+}
+
+#endif
+
+#endif
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c
new file mode 100644
index 00000000000..0369c7c84ac
--- /dev/null
+++ b/drivers/staging/comedi/drivers/8255.c
@@ -0,0 +1,442 @@
+/*
+ comedi/drivers/8255.c
+ Driver for 8255
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: 8255
+Description: generic 8255 support
+Devices: [standard] 8255 (8255)
+Author: ds
+Status: works
+Updated: Fri, 7 Jun 2002 12:56:45 -0700
+
+The classic in digital I/O. The 8255 appears in Comedi as a single
+digital I/O subdevice with 24 channels. The channel 0 corresponds
+to the 8255's port A, bit 0; channel 23 corresponds to port C, bit
+7. Direction configuration is done in blocks, with channels 0-7,
+8-15, 16-19, and 20-23 making up the 4 blocks. The only 8255 mode
+supported is mode 0.
+
+You should enable compilation this driver if you plan to use a board
+that has an 8255 chip. For multifunction boards, the main driver will
+configure the 8255 subdevice automatically.
+
+This driver also works independently with ISA and PCI cards that
+directly map the 8255 registers to I/O ports, including cards with
+multiple 8255 chips. To configure the driver for such a card, the
+option list should be a list of the I/O port bases for each of the
+8255 chips. For example,
+
+ comedi_config /dev/comedi0 8255 0x200,0x204,0x208,0x20c
+
+Note that most PCI 8255 boards do NOT work with this driver, and
+need a separate driver as a wrapper. For those that do work, the
+I/O port base address can be found in the output of 'lspci -v'.
+
+*/
+
+/*
+ This file contains an exported subdevice for driving an 8255.
+
+ To use this subdevice as part of another driver, you need to
+ set up the subdevice in the attach function of the driver by
+ calling:
+
+ subdev_8255_init(device, subdevice, callback_function, arg)
+
+ device and subdevice are pointers to the device and subdevice
+ structures. callback_function will be called to provide the
+ low-level input/output to the device, i.e., actual register
+ access. callback_function will be called with the value of arg
+ as the last parameter. If the 8255 device is mapped as 4
+ consecutive I/O ports, you can use NULL for callback_function
+ and the I/O port base for arg, and an internal function will
+ handle the register access.
+
+ In addition, if the main driver handles interrupts, you can
+ enable commands on the subdevice by calling subdev_8255_init_irq()
+ instead. Then, when you get an interrupt that is likely to be
+ from the 8255, you should call subdev_8255_interrupt(), which
+ will copy the latched value to a Comedi buffer.
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define _8255_SIZE 4
+
+#define _8255_DATA 0
+#define _8255_CR 3
+
+#define CR_C_LO_IO 0x01
+#define CR_B_IO 0x02
+#define CR_B_MODE 0x04
+#define CR_C_HI_IO 0x08
+#define CR_A_IO 0x10
+#define CR_A_MODE(a) ((a)<<5)
+#define CR_CW 0x80
+
+struct subdev_8255_struct {
+ unsigned long cb_arg;
+ int (*cb_func) (int, int, int, unsigned long);
+ int have_irq;
+};
+
+#define CALLBACK_ARG (((struct subdev_8255_struct *)s->private)->cb_arg)
+#define CALLBACK_FUNC (((struct subdev_8255_struct *)s->private)->cb_func)
+#define subdevpriv ((struct subdev_8255_struct *)s->private)
+
+static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig * it);
+static int dev_8255_detach(struct comedi_device *dev);
+static struct comedi_driver driver_8255 = {
+ driver_name:"8255",
+ module:THIS_MODULE,
+ attach:dev_8255_attach,
+ detach:dev_8255_detach,
+};
+
+COMEDI_INITCLEANUP(driver_8255);
+
+static void do_config(struct comedi_device *dev, struct comedi_subdevice * s);
+
+void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+ short d;
+
+ d = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG);
+ d |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 8);
+
+ comedi_buf_put(s->async, d);
+ s->async->events |= COMEDI_CB_EOS;
+
+ comedi_event(dev, s);
+}
+
+static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
+{
+ unsigned long iobase = arg;
+
+ if (dir) {
+ outb(data, iobase + port);
+ return 0;
+ } else {
+ return inb(iobase + port);
+ }
+}
+
+static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+
+ if (data[0] & 0xff)
+ CALLBACK_FUNC(1, _8255_DATA, s->state & 0xff,
+ CALLBACK_ARG);
+ if (data[0] & 0xff00)
+ CALLBACK_FUNC(1, _8255_DATA + 1, (s->state >> 8) & 0xff,
+ CALLBACK_ARG);
+ if (data[0] & 0xff0000)
+ CALLBACK_FUNC(1, _8255_DATA + 2,
+ (s->state >> 16) & 0xff, CALLBACK_ARG);
+ }
+
+ data[1] = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG);
+ data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 8);
+ data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 2, 0, CALLBACK_ARG) << 16);
+
+ return 2;
+}
+
+static int subdev_8255_insn_config(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int mask;
+ unsigned int bits;
+
+ mask = 1 << CR_CHAN(insn->chanspec);
+ if (mask & 0x0000ff) {
+ bits = 0x0000ff;
+ } else if (mask & 0x00ff00) {
+ bits = 0x00ff00;
+ } else if (mask & 0x0f0000) {
+ bits = 0x0f0000;
+ } else {
+ bits = 0xf00000;
+ }
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~bits;
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= bits;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ do_config(dev, s);
+
+ return 1;
+}
+
+static void do_config(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+ int config;
+
+ config = CR_CW;
+ /* 1 in io_bits indicates output, 1 in config indicates input */
+ if (!(s->io_bits & 0x0000ff))
+ config |= CR_A_IO;
+ if (!(s->io_bits & 0x00ff00))
+ config |= CR_B_IO;
+ if (!(s->io_bits & 0x0f0000))
+ config |= CR_C_LO_IO;
+ if (!(s->io_bits & 0xf00000))
+ config |= CR_C_HI_IO;
+ CALLBACK_FUNC(1, _8255_CR, config, CALLBACK_ARG);
+}
+
+static int subdev_8255_cmdtest(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* step 1 */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_FOLLOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2 */
+
+ if (err)
+ return 2;
+
+ /* step 3 */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ if (cmd->scan_end_arg != 1) {
+ cmd->scan_end_arg = 1;
+ err++;
+ }
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4 */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int subdev_8255_cmd(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+ /* FIXME */
+
+ return 0;
+}
+
+static int subdev_8255_cancel(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+ /* FIXME */
+
+ return 0;
+}
+
+int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice * s, int (*cb) (int,
+ int, int, unsigned long), unsigned long arg)
+{
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 24;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+
+ s->private = kmalloc(sizeof(struct subdev_8255_struct), GFP_KERNEL);
+ if (!s->private)
+ return -ENOMEM;
+
+ CALLBACK_ARG = arg;
+ if (cb == NULL) {
+ CALLBACK_FUNC = subdev_8255_cb;
+ } else {
+ CALLBACK_FUNC = cb;
+ }
+ s->insn_bits = subdev_8255_insn;
+ s->insn_config = subdev_8255_insn_config;
+
+ s->state = 0;
+ s->io_bits = 0;
+ do_config(dev, s);
+
+ return 0;
+}
+
+int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice * s,
+ int (*cb) (int, int, int, unsigned long), unsigned long arg)
+{
+ int ret;
+
+ ret = subdev_8255_init(dev, s, cb, arg);
+ if (ret < 0)
+ return ret;
+
+ s->do_cmdtest = subdev_8255_cmdtest;
+ s->do_cmd = subdev_8255_cmd;
+ s->cancel = subdev_8255_cancel;
+
+ subdevpriv->have_irq = 1;
+
+ return 0;
+}
+
+void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+ if (s->private) {
+ if (subdevpriv->have_irq) {
+ }
+
+ kfree(s->private);
+ }
+}
+
+/*
+
+ Start of the 8255 standalone device
+
+ */
+
+static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig * it)
+{
+ int ret;
+ unsigned long iobase;
+ int i;
+
+ printk("comedi%d: 8255:", dev->minor);
+
+ dev->board_name = "8255";
+
+ for (i = 0; i < COMEDI_NDEVCONFOPTS; i++) {
+ iobase = it->options[i];
+ if (!iobase)
+ break;
+ }
+ if (i == 0) {
+ printk(" no devices specified\n");
+ return -EINVAL;
+ }
+
+ if ((ret = alloc_subdevices(dev, i)) < 0)
+ return ret;
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ iobase = it->options[i];
+
+ printk(" 0x%04lx", iobase);
+ if (!request_region(iobase, _8255_SIZE, "8255")) {
+ printk(" (I/O port conflict)");
+
+ dev->subdevices[i].type = COMEDI_SUBD_UNUSED;
+ } else {
+ subdev_8255_init(dev, dev->subdevices + i, NULL,
+ iobase);
+ }
+ }
+
+ printk("\n");
+
+ return 0;
+}
+
+static int dev_8255_detach(struct comedi_device *dev)
+{
+ int i;
+ unsigned long iobase;
+ struct comedi_subdevice *s;
+
+ printk("comedi%d: 8255: remove\n", dev->minor);
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ s = dev->subdevices + i;
+ if (s->type != COMEDI_SUBD_UNUSED) {
+ iobase = CALLBACK_ARG;
+ release_region(iobase, _8255_SIZE);
+ }
+ subdev_8255_cleanup(dev, s);
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL(subdev_8255_init);
+EXPORT_SYMBOL(subdev_8255_init_irq);
+EXPORT_SYMBOL(subdev_8255_cleanup);
+EXPORT_SYMBOL(subdev_8255_interrupt);
diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h
new file mode 100644
index 00000000000..979311b9927
--- /dev/null
+++ b/drivers/staging/comedi/drivers/8255.h
@@ -0,0 +1,57 @@
+/*
+ module/8255.h
+ Header file for 8255
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _8255_H
+#define _8255_H
+
+#include "../comedidev.h"
+
+#if defined(CONFIG_COMEDI_8255) || defined(CONFIG_COMEDI_8255_MODULE)
+
+int subdev_8255_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ int (*cb) (int, int, int, unsigned long), unsigned long arg);
+int subdev_8255_init_irq(struct comedi_device * dev, struct comedi_subdevice * s,
+ int (*cb) (int, int, int, unsigned long), unsigned long arg);
+void subdev_8255_cleanup(struct comedi_device * dev, struct comedi_subdevice * s);
+void subdev_8255_interrupt(struct comedi_device * dev, struct comedi_subdevice * s);
+
+#else
+
+static inline int subdev_8255_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *x, unsigned long y)
+{
+ printk("8255 support not configured -- disabling subdevice\n");
+
+ s->type = COMEDI_SUBD_UNUSED;
+
+ return 0;
+}
+
+static inline void subdev_8255_cleanup(struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+}
+
+#endif
+
+#endif
diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile
index eb7a615e085..12d6e4312f3 100644
--- a/drivers/staging/comedi/drivers/Makefile
+++ b/drivers/staging/comedi/drivers/Makefile
@@ -8,12 +8,121 @@ obj-$(CONFIG_COMEDI) += comedi_test.o
obj-$(CONFIG_COMEDI) += comedi_parport.o
# Comedi PCI drivers
-obj-$(CONFIG_COMEDI_PCI_DRIVERS) += mite.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += 8255.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += acl7225b.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_035.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1032.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1500.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1516.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1564.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_16xx.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_2016.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_2032.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_2200.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3001.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3120.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3501.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3xxx.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci6208.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci7296.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci7432.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci8164.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci9111.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci9118.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adq12b.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adv_pci1710.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adv_pci1723.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adv_pci_dio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += aio_aio12_8.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += aio_iiro_16.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_dio200.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pc236.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pc263.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pci224.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pci230.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += c6xdigio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidas64.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidas.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidda.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcimdas.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcimdda.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_bond.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_parport.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_test.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += contec_pci_dio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += daqboard2000.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das08.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das16m1.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das16.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das1800.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das6402.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das800.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dmm32at.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2801.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2811.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2814.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2815.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2817.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt282x.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt3000.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += fl512.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += gsc_hpdi.o
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += icp_multi.o
-obj-$(CONFIG_COMEDI_PCI_DRIVERS) += me_daq.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ii_pci20kc.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += jr3_pci.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ke_counter.o
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += me4000.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += me_daq.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += mite.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += mpc624.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += multiq3.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_6527.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_65xx.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_660x.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_670x.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_at_a2150.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_at_ao.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_atmio16d.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_atmio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_labpc.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_pcidio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_pcimio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_tiocmd.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_tio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl711.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl724.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl725.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl726.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl730.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl812.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl816.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl818.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcm3724.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcm3730.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmad.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmda12.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmmio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmuio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += poc.o
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += rtd520.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += rti800.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += rti802.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += s526.o
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += s626.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += serial2002.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += skel.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ssv_dnp.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += unioxx5.o
+
+# Comedi PCMCIA drivers
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += cb_das16_cs.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += das08_cs.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_daq_700.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_daq_dio24.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_labpc_cs.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_mio_cs.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += quatech_daqp_cs.o
# Comedi USB drivers
obj-$(CONFIG_COMEDI_USB_DRIVERS) += usbdux.o
diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c
new file mode 100644
index 00000000000..b21320f0959
--- /dev/null
+++ b/drivers/staging/comedi/drivers/acl7225b.c
@@ -0,0 +1,149 @@
+/*
+ * comedi/drivers/acl7225b.c
+ * Driver for Adlink NuDAQ ACL-7225b and clones
+ * José Luis Sánchez
+ */
+/*
+Driver: acl7225b
+Description: Adlink NuDAQ ACL-7225b & compatibles
+Author: José Luis Sánchez (jsanchezv@teleline.es)
+Status: testing
+Devices: [Adlink] ACL-7225b (acl7225b), [ICP] P16R16DIO (p16r16dio)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define ACL7225_SIZE 8 /* Requires 8 ioports, but only 4 are used */
+#define P16R16DIO_SIZE 4
+#define ACL7225_RIO_LO 0 /* Relays input/output low byte (R0-R7) */
+#define ACL7225_RIO_HI 1 /* Relays input/output high byte (R8-R15) */
+#define ACL7225_DI_LO 2 /* Digital input low byte (DI0-DI7) */
+#define ACL7225_DI_HI 3 /* Digital input high byte (DI8-DI15) */
+
+static int acl7225b_attach(struct comedi_device *dev, struct comedi_devconfig * it);
+static int acl7225b_detach(struct comedi_device *dev);
+
+struct boardtype {
+ const char *name; // driver name
+ int io_range; // len of I/O space
+};
+
+static const struct boardtype boardtypes[] = {
+ {"acl7225b", ACL7225_SIZE,},
+ {"p16r16dio", P16R16DIO_SIZE,},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
+#define this_board ((const struct boardtype *)dev->board_ptr)
+
+static struct comedi_driver driver_acl7225b = {
+ driver_name:"acl7225b",
+ module:THIS_MODULE,
+ attach:acl7225b_attach,
+ detach:acl7225b_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct boardtype),
+};
+
+COMEDI_INITCLEANUP(driver_acl7225b);
+
+static int acl7225b_do_insn(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ }
+ if (data[0] & 0x00ff)
+ outb(s->state & 0xff, dev->iobase + (unsigned long)s->private);
+ if (data[0] & 0xff00)
+ outb((s->state >> 8),
+ dev->iobase + (unsigned long)s->private + 1);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int acl7225b_di_insn(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + (unsigned long)s->private) |
+ (inb(dev->iobase + (unsigned long)s->private + 1) << 8);
+
+ return 2;
+}
+
+static int acl7225b_attach(struct comedi_device *dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int iobase, iorange;
+
+ iobase = it->options[0];
+ iorange = this_board->io_range;
+ printk("comedi%d: acl7225b: board=%s 0x%04x ", dev->minor,
+ this_board->name, iobase);
+ if (!request_region(iobase, iorange, "acl7225b")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->board_name = this_board->name;
+ dev->iobase = iobase;
+ dev->irq = 0;
+
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* Relays outputs */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = acl7225b_do_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)ACL7225_RIO_LO;
+
+ s = dev->subdevices + 1;
+ /* Relays status */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = acl7225b_di_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)ACL7225_RIO_LO;
+
+ s = dev->subdevices + 2;
+ /* Isolated digital inputs */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = acl7225b_di_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)ACL7225_DI_LO;
+
+ printk("\n");
+
+ return 0;
+}
+
+static int acl7225b_detach(struct comedi_device *dev)
+{
+ printk("comedi%d: acl7225b: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, this_board->io_range);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c
new file mode 100644
index 00000000000..c96aee09e1b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c
@@ -0,0 +1,1047 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+/*
+ | Description : APCI-1710 82X54 timer module |
+*/
+
+#include "APCI1710_82x54.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitTimer |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| BYTE_ b_TimerMode, |
+| ULONG_ ul_ReloadValue, |
+| BYTE_ b_InputClockSelection, |
+| BYTE_ b_InputClockLevel, |
+| BYTE_ b_OutputLevel, |
+| BYTE_ b_HardwareGateLevel)
+INT i_InsnConfig_InitTimer(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data)
+|
++----------------------------------------------------------------------------+
+| Task : Configure the Timer (b_TimerNbr) operating mode |
+| (b_TimerMode) from selected module (b_ModulNbr). |
+| You must calling this function be for you call any |
+| other function witch access of the timer. |
+| |
+| |
+| Timer mode description table |
+| |
+|+--------+-----------------------------+--------------+--------------------+|
+||Selected+ Mode description +u_ReloadValue | Hardware gate input||
+|| mode | | description | action ||
+|+--------+-----------------------------+--------------+--------------------+|
+|| |Mode 0 is typically used | | ||
+|| |for event counting. After | | ||
+|| |the initialisation, OUT | | ||
+|| |is initially low, and | | ||
+|| 0 |will remain low until the |Start counting| Hardware gate ||
+|| |counter reaches zero. | value | ||
+|| |OUT then goes high and | | ||
+|| |remains high until a new | | ||
+|| |count is written. See | | ||
+|| |"i_APCI1710_WriteTimerValue" | | ||
+|| |function. | | ||
+|+--------+-----------------------------+--------------+--------------------+|
+|| |Mode 1 is similar to mode 0 | | ||
+|| |except for the gate input | | ||
+|| 1 |action. The gate input is not|Start counting| Hardware trigger ||
+|| |used for enabled or disabled | value | ||
+|| |the timer. | | ||
+|| |The gate input is used for | | ||
+|| |triggered the timer. | | ||
+|+--------+-----------------------------+--------------+--------------------+|
+|| |This mode functions like a | | ||
+|| |divide-by-ul_ReloadValue | | ||
+|| |counter. It is typically used| | ||
+|| |to generate a real time clock| | ||
+|| |interrupt. OUT will initially| | ||
+|| 2 |be high after the | Division | Hardware gate ||
+|| |initialisation. When the | factor | ||
+|| |initial count has decremented| | ||
+|| |to 1, OUT goes low for one | | ||
+|| |CLK pule. OUT then goes high | | ||
+|| |again, the counter reloads | | ||
+|| |the initial count | | ||
+|| |(ul_ReloadValue) and the | | ||
+|| |process is repeated. | | ||
+|| |This action can generated a | | ||
+|| |interrupt. See function | | ||
+|| |"i_APCI1710_SetBoardInt- | | ||
+|| |RoutineX" | | ||
+|| |and "i_APCI1710_EnableTimer" | | ||
+|+--------+-----------------------------+--------------+--------------------+|
+|| |Mode 3 is typically used for | | ||
+|| |baud rate generation. This | | ||
+|| |mode is similar to mode 2 | | ||
+|| |except for the duty cycle of | | ||
+|| 3 |OUT. OUT will initially be | Division | Hardware gate ||
+|| |high after the initialisation| factor | ||
+|| |When half the initial count | | ||
+|| |(ul_ReloadValue) has expired,| | ||
+|| |OUT goes low for the | | ||
+|| |remainder of the count. The | | ||
+|| |mode is periodic; the | | ||
+|| |sequence above is repeated | | ||
+|| |indefinitely. | | ||
+|+--------+-----------------------------+--------------+--------------------+|
+|| |OUT will be initially high | | ||
+|| |after the initialisation. | | ||
+|| |When the initial count | | ||
+|| 4 |expires OUT will go low for |Start counting| Hardware gate ||
+|| |one CLK pulse and then go | value | ||
+|| |high again. | | ||
+|| |The counting sequences is | | ||
+|| |triggered by writing a new | | ||
+|| |value. See | | ||
+|| |"i_APCI1710_WriteTimerValue" | | ||
+|| |function. If a new count is | | ||
+|| |written during counting, | | ||
+|| |it will be loaded on the | | ||
+|| |next CLK pulse | | ||
+|+--------+-----------------------------+--------------+--------------------+|
+|| |Mode 5 is similar to mode 4 | | ||
+|| |except for the gate input | | ||
+|| |action. The gate input is not| | ||
+|| 5 |used for enabled or disabled |Start counting| Hardware trigger ||
+|| |the timer. The gate input is | value | ||
+|| |used for triggered the timer.| | ||
+|+--------+-----------------------------+--------------+--------------------+|
+| |
+| |
+| |
+| Input clock selection table |
+| |
+| +--------------------------------+------------------------------------+ |
+| | b_InputClockSelection | Description | |
+| | parameter | | |
+| +--------------------------------+------------------------------------+ |
+| | APCI1710_PCI_BUS_CLOCK | For the timer input clock, the PCI | |
+| | | bus clock / 4 is used. This PCI bus| |
+| | | clock can be 30MHz or 33MHz. For | |
+| | | Timer 0 only this selection are | |
+| | | available. | |
+| +--------------------------------+------------------------------------+ |
+| | APCI1710_ FRONT_CONNECTOR_INPUT| Of the front connector you have the| |
+| | | possibility to inject a input clock| |
+| | | for Timer 1 or Timer 2. The source | |
+| | | from this clock can eat the output | |
+| | | clock from Timer 0 or any other | |
+| | | clock source. | |
+| +--------------------------------+------------------------------------+ |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to |
+| configure (0 to 2) |
+| BYTE_ b_TimerMode : Timer mode selection |
+| (0 to 5) |
+| 0: Interrupt on terminal|
+| count |
+| 1: Hardware |
+| retriggerable one- |
+| shot |
+| 2: Rate generator |
+| 3: Square wave mode |
+| 4: Software triggered |
+| strobe |
+| 5: Hardware triggered |
+| strobe |
+| See timer mode |
+| description table. |
+| ULONG_ ul_ReloadValue : Start counting value |
+| or division factor |
+| See timer mode |
+| description table. |
+| BYTE_ b_InputClockSelection : Selection from input |
+| timer clock. |
+| See input clock |
+| selection table. |
+| BYTE_ b_InputClockLevel : Selection from input |
+| clock level. |
+| 0 : Low active |
+| (Input inverted) |
+| 1 : High active |
+| BYTE_ b_OutputLevel, : Selection from output |
+| clock level. |
+| 0 : Low active |
+| 1 : High active |
+| (Output inverted) |
+| BYTE_ b_HardwareGateLevel : Selection from |
+| hardware gate level. |
+| 0 : Low active |
+| (Input inverted) |
+| 1 : High active |
+| If you will not used |
+| the hardware gate set |
+| this value to 0.
+|b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
+ b_TimerMode = (BYTE) data[0];
+ ul_ReloadValue = (ULONG) data[1];
+ b_InputClockSelection =(BYTE) data[2];
+ b_InputClockLevel =(BYTE) data[3];
+ b_OutputLevel =(BYTE) data[4];
+ b_HardwareGateLevel =(BYTE) data[5];
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer mode selection is wrong |
+| -6: Input timer clock selection is wrong |
+| -7: Selection from input clock level is wrong |
+| -8: Selection from output clock level is wrong |
+| -9: Selection from hardware gate level is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ INT i_ReturnValue = 0;
+ BYTE b_ModulNbr;
+ BYTE b_TimerNbr;
+ BYTE b_TimerMode;
+ ULONG ul_ReloadValue;
+ BYTE b_InputClockSelection;
+ BYTE b_InputClockLevel;
+ BYTE b_OutputLevel;
+ BYTE b_HardwareGateLevel;
+
+ //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+ DWORD dw_Test = 0;
+ //END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
+ b_TimerMode = (BYTE) data[0];
+ ul_ReloadValue = (ULONG) data[1];
+ b_InputClockSelection = (BYTE) data[2];
+ b_InputClockLevel = (BYTE) data[3];
+ b_OutputLevel = (BYTE) data[4];
+ b_HardwareGateLevel = (BYTE) data[5];
+
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test the timer number */
+
+ if (b_TimerNbr <= 2) {
+ /* Test the timer mode */
+ if (b_TimerMode <= 5) {
+ //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+ /* Test te imput clock selection */
+ /*
+ if (((b_TimerNbr == 0) && (b_InputClockSelection == 0)) ||
+ ((b_TimerNbr != 0) && ((b_InputClockSelection == 0) || (b_InputClockSelection == 1))))
+ */
+
+ if (((b_TimerNbr == 0) &&
+ (b_InputClockSelection == APCI1710_PCI_BUS_CLOCK)) ||
+ ((b_TimerNbr == 0) &&
+ (b_InputClockSelection == APCI1710_10MHZ)) ||
+ ((b_TimerNbr != 0) &&
+ ((b_InputClockSelection == APCI1710_PCI_BUS_CLOCK) ||
+ (b_InputClockSelection == APCI1710_FRONT_CONNECTOR_INPUT) ||
+ (b_InputClockSelection == APCI1710_10MHZ)))) {
+ //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+ if (((b_InputClockSelection == APCI1710_10MHZ) &&
+ ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) >= 0x3131)) ||
+ (b_InputClockSelection != APCI1710_10MHZ)) {
+ //END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+ /* Test the input clock level selection */
+
+ if ((b_InputClockLevel == 0) ||
+ (b_InputClockLevel == 1)) {
+ /* Test the output clock level selection */
+ if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) {
+ /* Test the hardware gate level selection */
+ if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) {
+ //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+ /* Test if version > 1.1 and clock selection = 10MHz */
+ if ((b_InputClockSelection == APCI1710_10MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) > 0x3131)) {
+ /* Test if 40MHz quartz on board */
+ dw_Test = inl(devpriv->s_BoardInfos.ui_Address + (16 + (b_TimerNbr * 4) + (64 * b_ModulNbr)));
+
+ dw_Test = (dw_Test >> 16) & 1;
+ } else {
+ dw_Test = 1;
+ }
+
+ /* Test if detection OK */
+ if (dw_Test == 1) {
+ //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+ /* Initialisation OK */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init = 1;
+
+ /* Save the input clock selection */
+ devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockSelection = b_InputClockSelection;
+
+ /* Save the input clock level */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockLevel = ~b_InputClockLevel & 1;
+
+ /* Save the output level */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel = ~b_OutputLevel & 1;
+
+ /* Save the gate level */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_HardwareGateLevel = b_HardwareGateLevel;
+
+ /* Set the configuration word and disable the timer */
+ //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+ /*
+ devpriv->s_ModuleInfo [b_ModulNbr].
+ s_82X54ModuleInfo.
+ s_82X54TimerInfo [b_TimerNbr].
+ dw_ConfigurationWord = (DWORD) (((b_HardwareGateLevel << 0) & 0x1) |
+ ((b_InputClockLevel << 1) & 0x2) |
+ (((~b_OutputLevel & 1) << 2) & 0x4) |
+ ((b_InputClockSelection << 4) & 0x10));
+ */
+ /* Test if 10MHz selected */
+ if (b_InputClockSelection == APCI1710_10MHZ) {
+ b_InputClockSelection = 2;
+ }
+
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = (DWORD)(((b_HardwareGateLevel << 0) & 0x1) | ((b_InputClockLevel << 1) & 0x2) | (((~b_OutputLevel & 1) << 2) & 0x4) | ((b_InputClockSelection << 4) & 0x30));
+ //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ /* Initialise the 82X54 Timer */
+ outl((DWORD) b_TimerMode, devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ /* Write the reload value */
+ outl(ul_ReloadValue, devpriv->s_BoardInfos.ui_Address + 0 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+ //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+ } // if (dw_Test == 1)
+ else {
+ /* Input timer clock selection is wrong */
+ i_ReturnValue = -6;
+ } // if (dw_Test == 1)
+ //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+ } // if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1))
+ else {
+ /* Selection from hardware gate level is wrong */
+ DPRINTK("Selection from hardware gate level is wrong\n");
+ i_ReturnValue = -9;
+ } // if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1))
+ } // if ((b_OutputLevel == 0) || (b_OutputLevel == 1))
+ else {
+ /* Selection from output clock level is wrong */
+ DPRINTK("Selection from output clock level is wrong\n");
+ i_ReturnValue = -8;
+ } // if ((b_OutputLevel == 0) || (b_OutputLevel == 1))
+ } // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1))
+ else {
+ /* Selection from input clock level is wrong */
+ DPRINTK("Selection from input clock level is wrong\n");
+ i_ReturnValue = -7;
+ } // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1))
+ } else {
+ /* Input timer clock selection is wrong */
+ DPRINTK("Input timer clock selection is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /* Input timer clock selection is wrong */
+ DPRINTK("Input timer clock selection is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } // if ((b_TimerMode >= 0) && (b_TimerMode <= 5))
+ else {
+ /* Timer mode selection is wrong */
+ DPRINTK("Timer mode selection is wrong\n");
+ i_ReturnValue = -5;
+ } // if ((b_TimerMode >= 0) && (b_TimerMode <= 5))
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ else {
+ /* Timer selection wrong */
+ DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ } else {
+ /* The module is not a TIMER module */
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* Module number error */
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnableTimer |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| BYTE_ b_InterruptEnable)
+INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Enable OR Disable the Timer (b_TimerNbr) from selected module |
+| (b_ModulNbr). You must calling the |
+| "i_APCI1710_InitTimer" function be for you call this |
+| function. If you enable the timer interrupt, the timer |
+| generate a interrupt after the timer value reach |
+| the zero. See function "i_APCI1710_SetBoardIntRoutineX"|
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to enable |
+| (0 to 2) |
+| BYTE_ b_InterruptEnable : Enable or disable the |
+| timer interrupt. |
+| APCI1710_ENABLE : |
+| Enable the timer interrupt |
+| APCI1710_DISABLE : |
+| Disable the timer interrupt|
+i_ReturnValue=insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
+ b_ActionType = (BYTE) data[0]; // enable disable
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer not initialised see function |
+| "i_APCI1710_InitTimer" |
+| -6: Interrupt parameter is wrong |
+| -7: Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device * dev,
+ struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_DummyRead;
+ BYTE b_ModulNbr;
+ BYTE b_TimerNbr;
+ BYTE b_ActionType;
+ BYTE b_InterruptEnable;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
+ b_ActionType = (BYTE) data[0]; // enable disable
+
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test the timer number */
+ if (b_TimerNbr <= 2) {
+ /* Test if timer initialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
+
+ switch (b_ActionType) {
+ case APCI1710_ENABLE:
+ b_InterruptEnable = (BYTE) data[1];
+ /* Test the interrupt selection */
+ if ((b_InterruptEnable == APCI1710_ENABLE) ||
+ (b_InterruptEnable == APCI1710_DISABLE)) {
+ if (b_InterruptEnable == APCI1710_ENABLE) {
+
+ dw_DummyRead = inl(devpriv->s_BoardInfos.ui_Address + 12 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ /* Enable the interrupt */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord | 0x8;
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+ devpriv->tsk_Current = current; // Save the current process task structure
+
+ } // if (b_InterruptEnable == APCI1710_ENABLE)
+ else {
+ /* Disable the interrupt */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7;
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ /* Save the interrupt flag */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr));
+ } // if (b_InterruptEnable == APCI1710_ENABLE)
+
+ /* Test if error occur */
+ if (i_ReturnValue >= 0) {
+ /* Save the interrupt flag */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask | ((1 & b_InterruptEnable) << b_TimerNbr);
+
+ /* Enable the timer */
+ outl(1, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+ }
+ } else {
+ /* Interrupt parameter is wrong */
+ DPRINTK("\n");
+ i_ReturnValue = -6;
+ }
+ break;
+ case APCI1710_DISABLE:
+ /* Test the interrupt flag */
+ if (((devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask >> b_TimerNbr) & 1) == 1) {
+ /* Disable the interrupt */
+
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr]. dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7;
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ /* Save the interrupt flag */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr));
+ }
+
+ /* Disable the timer */
+ outl(0, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+ break;
+ } // Switch end
+ } else {
+ /* Timer not initialised see function */
+ DPRINTK ("Timer not initialised see function\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /* Timer selection wrong */
+ DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ } else {
+ /* The module is not a TIMER module */
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* Module number error */
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadAllTimerValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PULONG_ pul_TimerValueArray)
+INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the all timer values from selected timer |
+| module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_TimerValueArray : Timer value array. |
+| Element 0 contain the timer 0 value. |
+| Element 1 contain the timer 1 value. |
+| Element 2 contain the timer 2 value. |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a TIMER module |
+| -4: Timer 0 not initialised see function |
+| "i_APCI1710_InitTimer" |
+| -5: Timer 1 not initialised see function |
+| "i_APCI1710_InitTimer" |
+| -6: Timer 2 not initialised see function |
+| "i_APCI1710_InitTimer" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+{
+ INT i_ReturnValue = 0;
+ BYTE b_ModulNbr, b_ReadType;
+ PULONG pul_TimerValueArray;
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_ReadType = CR_CHAN(insn->chanspec);
+ pul_TimerValueArray = (PULONG) data;
+ i_ReturnValue = insn->n;
+
+ switch (b_ReadType) {
+ case APCI1710_TIMER_READINTERRUPT:
+
+ data[0] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /* Increment the read FIFO */
+ devpriv->s_InterruptParameters.ui_Read = (devpriv->s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ break;
+
+ case APCI1710_TIMER_READALLTIMER:
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test if timer 0 iniutialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[0].b_82X54Init == 1) {
+ /* Test if timer 1 iniutialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[1].b_82X54Init == 1) {
+ /* Test if timer 2 iniutialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[2].b_82X54Init == 1) {
+ /* Latch all counter */
+ outl(0x17, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
+
+ /* Read the timer 0 value */
+ pul_TimerValueArray[0] = inl(devpriv->s_BoardInfos.ui_Address + 0 + (64 * b_ModulNbr));
+
+ /* Read the timer 1 value */
+ pul_TimerValueArray[1] = inl(devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
+
+ /* Read the timer 2 value */
+ pul_TimerValueArray[2] = inl(devpriv->s_BoardInfos.ui_Address + 8 + (64 * b_ModulNbr));
+ } else {
+ /* Timer 2 not initialised see function */
+ DPRINTK("Timer 2 not initialised see function\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /* Timer 1 not initialised see function */
+ DPRINTK("Timer 1 not initialised see function\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /* Timer 0 not initialised see function */
+ DPRINTK("Timer 0 not initialised see function\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* The module is not a TIMER module */
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /* Module number error */
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ } // End of Switch
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev,
+struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read write functions for Timer |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_BitsType;
+ INT i_ReturnValue = 0;
+ b_BitsType = data[0];
+
+ printk("\n82X54");
+
+ switch (b_BitsType) {
+ case APCI1710_TIMER_READVALUE:
+ i_ReturnValue = i_APCI1710_ReadTimerValue(dev,
+ (BYTE)CR_AREF(insn->chanspec),
+ (BYTE)CR_CHAN(insn->chanspec),
+ (PULONG) & data[0]);
+ break;
+
+ case APCI1710_TIMER_GETOUTPUTLEVEL:
+ i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev,
+ (BYTE)CR_AREF(insn->chanspec),
+ (BYTE)CR_CHAN(insn->chanspec),
+ (PBYTE) &data[0]);
+ break;
+
+ case APCI1710_TIMER_GETPROGRESSSTATUS:
+ i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev,
+ (BYTE)CR_AREF(insn->chanspec),
+ (BYTE)CR_CHAN(insn->chanspec),
+ (PBYTE)&data[0]);
+ break;
+
+ case APCI1710_TIMER_WRITEVALUE:
+ i_ReturnValue = i_APCI1710_WriteTimerValue(dev,
+ (BYTE)CR_AREF(insn->chanspec),
+ (BYTE)CR_CHAN(insn->chanspec),
+ (ULONG)data[1]);
+
+ break;
+
+ default:
+ printk("Bits Config Parameter Wrong\n");
+ i_ReturnValue = -1;
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadTimerValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| PULONG_ pul_TimerValue) |
++----------------------------------------------------------------------------+
+| Task : Return the timer value from selected digital timer |
+| (b_TimerNbr) from selected timer module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to read |
+| (0 to 2) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_TimerValue : Timer value |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer not initialised see function |
+| "i_APCI1710_InitTimer" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadTimerValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ PULONG pul_TimerValue)
+{
+ INT i_ReturnValue = 0;
+
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test the timer number */
+ if (b_TimerNbr <= 2) {
+ /* Test if timer initialised */
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_82X54ModuleInfo.
+ s_82X54TimerInfo[b_TimerNbr].
+ b_82X54Init == 1) {
+ /* Latch the timer value */
+ outl((2 << b_TimerNbr) | 0xD0,
+ devpriv->s_BoardInfos.
+ ui_Address + 12 +
+ (64 * b_ModulNbr));
+
+ /* Read the counter value */
+ *pul_TimerValue =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + (b_TimerNbr * 4) +
+ (64 * b_ModulNbr));
+ } else {
+ /* Timer not initialised see function */
+ DPRINTK("Timer not initialised see function\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /* Timer selection wrong */
+ DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ } else {
+ /* The module is not a TIMER module */
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* Module number error */
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : _INT_ i_APCI1710_GetTimerOutputLevel |
+ | (BYTE_ b_BoardHandle, |
+ | BYTE_ b_ModulNbr, |
+ | BYTE_ b_TimerNbr, |
+ | PBYTE_ pb_OutputLevel) |
+ +----------------------------------------------------------------------------+
+ | Task : Return the output signal level (pb_OutputLevel) from |
+ | selected digital timer (b_TimerNbr) from selected timer|
+ | module (b_ModulNbr). |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+ | APCI-1710 |
+ | BYTE_ b_ModulNbr : Selected module number |
+ | (0 to 3) |
+ | BYTE_ b_TimerNbr : Timer number to test |
+ | (0 to 2) |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : PBYTE_ pb_OutputLevel : Output signal level |
+ | 0 : The output is low |
+ | 1 : The output is high |
+ +----------------------------------------------------------------------------+
+ | Return Value : 0: No error |
+ | -1: The handle parameter of the board is wrong |
+ | -2: Module selection wrong |
+ | -3: Timer selection wrong |
+ | -4: The module is not a TIMER module |
+ | -5: Timer not initialised see function |
+ | "i_APCI1710_InitTimer" |
+ +----------------------------------------------------------------------------+
+ */
+
+INT i_APCI1710_GetTimerOutputLevel(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ PBYTE pb_OutputLevel)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_TimerStatus;
+
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test the timer number */
+ if (b_TimerNbr <= 2) {
+ /* Test if timer initialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
+ /* Latch the timer value */
+ outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
+
+ /* Read the timer status */
+ dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ *pb_OutputLevel = (BYTE) (((dw_TimerStatus >> 7) & 1) ^ devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel);
+ } else {
+ /* Timer not initialised see function */
+ DPRINTK("Timer not initialised see function\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /* Timer selection wrong */
+ DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ } else {
+ /* The module is not a TIMER module */
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* Module number error */
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetTimerProgressStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| PBYTE_ pb_TimerStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the progress status (pb_TimerStatus) from |
+| selected digital timer (b_TimerNbr) from selected timer|
+| module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to test |
+| (0 to 2) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TimerStatus : Output signal level |
+| 0 : Timer not in progress |
+| 1 : Timer in progress |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer not initialised see function |
+| "i_APCI1710_InitTimer" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ PBYTE pb_TimerStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_TimerStatus;
+
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test the timer number */
+ if (b_TimerNbr <= 2) {
+ /* Test if timer initialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
+ /* Latch the timer value */
+ outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
+
+ /* Read the timer status */
+ dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ *pb_TimerStatus = (BYTE) ((dw_TimerStatus) >> 8) & 1;
+ printk("ProgressStatus : %d", *pb_TimerStatus);
+ } else {
+ /* Timer not initialised see function */
+ i_ReturnValue = -5;
+ }
+ } else {
+ /* Timer selection wrong */
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ } else {
+ /* The module is not a TIMER module */
+
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* Module number error */
+
+ i_ReturnValue = -2;
+ }
+
+ return i_ReturnValue;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_WriteTimerValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| ULONG_ ul_WriteValue) |
++----------------------------------------------------------------------------+
+| Task : Write the value (ul_WriteValue) into the selected timer|
+| (b_TimerNbr) from selected timer module (b_ModulNbr). |
+| The action in depend of the time mode selection. |
+| See timer mode description table. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to write |
+| (0 to 2) |
+| ULONG_ ul_WriteValue : Value to write |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer not initialised see function |
+| "i_APCI1710_InitTimer" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_WriteTimerValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ ULONG ul_WriteValue)
+{
+ INT i_ReturnValue = 0;
+
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test the timer number */
+ if (b_TimerNbr <= 2) {
+ /* Test if timer initialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
+ /* Write the value */
+ outl(ul_WriteValue, devpriv->s_BoardInfos.ui_Address + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+ } else {
+ /* Timer not initialised see function */
+ DPRINTK("Timer not initialised see function\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /* Timer selection wrong */
+ DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ } else {
+ /* The module is not a TIMER module */
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* Module number error */
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return i_ReturnValue;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h
new file mode 100644
index 00000000000..4797c0b77a4
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+#define APCI1710_PCI_BUS_CLOCK 0
+#define APCI1710_FRONT_CONNECTOR_INPUT 1
+#define APCI1710_TIMER_READVALUE 0
+#define APCI1710_TIMER_GETOUTPUTLEVEL 1
+#define APCI1710_TIMER_GETPROGRESSSTATUS 2
+#define APCI1710_TIMER_WRITEVALUE 3
+
+#define APCI1710_TIMER_READINTERRUPT 1
+#define APCI1710_TIMER_READALLTIMER 2
+
+/* BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
+#ifndef APCI1710_10MHZ
+#define APCI1710_10MHZ 10
+#endif
+/* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
+
+/*
+ * 82X54 TIMER INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * 82X54 READ FUNCTION
+ */
+INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * 82X54 READ & WRITE FUNCTION
+ */
+INT i_APCI1710_ReadTimerValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ PULONG pul_TimerValue);
+
+INT i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ PBYTE pb_OutputLevel);
+
+INT i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ PBYTE pb_TimerStatus);
+
+/*
+ * 82X54 WRITE FUNCTION
+ */
+INT i_APCI1710_WriteTimerValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ ULONG ul_WriteValue);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
new file mode 100644
index 00000000000..1a54d3b2c69
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
@@ -0,0 +1,2032 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : CHRONO.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 chronometer module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 29/06/98 | S. Weber | Digital input / output implementation |
+ |----------|-----------|------------------------------------------------|
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+ | | | |
+ | | | |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "APCI1710_Chrono.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitChrono |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_ChronoMode, |
+| BYTE_ b_PCIInputClock, |
+| BYTE_ b_TimingUnit, |
+| ULONG_ ul_TimingInterval, |
+| PULONG_ pul_RealTimingInterval)
+
++----------------------------------------------------------------------------+
+| Task : Configure the chronometer operating mode (b_ChronoMode)|
+| from selected module (b_ModulNbr). |
+| The ul_TimingInterval and ul_TimingUnit determine the |
+| timing base for the measurement. |
+| The pul_RealTimingInterval return the real timing |
+| value. You must calling this function be for you call |
+| any other function witch access of the chronometer. |
+| |
+| Witch this functionality from the APCI-1710 you have |
+| the possibility to measure the timing witch two event. |
+| |
+| The mode 0 and 1 is appropriate for period measurement.|
+| The mode 2 and 3 is appropriate for frequent |
+| measurement. |
+| The mode 4 to 7 is appropriate for measuring the timing|
+| between two event. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr CR_AREF(insn->chanspec) : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_ChronoMode data[0] : Chronometer action mode |
+| (0 to 7). |
+| BYTE_ b_PCIInputClock data[1] : Selection from PCI bus clock|
+| - APCI1710_30MHZ : |
+| The PC have a PCI bus |
+| clock from 30 MHz |
+| - APCI1710_33MHZ : |
+| The PC have a PCI bus |
+| clock from 33 MHz |
+| - APCI1710_40MHZ |
+| The APCI-1710 have a |
+| integrated 40Mhz |
+| quartz. |
+| BYTE_ b_TimingUnit data[2] : Base timing unity (0 to 4) |
+| 0 : ns |
+| 1 : µs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| ULONG_ ul_TimingInterval : data[3] Base timing value. |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_RealTimingInterval : Real base timing |
+| value.
+| data[0]
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer mode selection is wrong |
+| -5: The selected PCI input clock is wrong |
+| -6: Timing unity selection is wrong |
+| -7: Base timing selection is wrong |
+| -8: You can not used the 40MHz clock selection wich |
+| this board |
+| -9: You can not used the 40MHz clock selection wich |
+| this CHRONOS version |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitChrono(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ ULONG ul_TimerValue = 0;
+ ULONG ul_TimingInterval = 0;
+ ULONG ul_RealTimingInterval = 0;
+ double d_RealTimingInterval = 0;
+ DWORD dw_ModeArray[8] =
+ { 0x01, 0x05, 0x00, 0x04, 0x02, 0x0E, 0x0A, 0x06 };
+ BYTE b_ModulNbr, b_ChronoMode, b_PCIInputClock, b_TimingUnit;
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_ChronoMode = (BYTE) data[0];
+ b_PCIInputClock = (BYTE) data[1];
+ b_TimingUnit = (BYTE) data[2];
+ ul_TimingInterval = (ULONG) data[3];
+ i_ReturnValue = insn->n;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+ /*****************************/
+ /* Test the chronometer mode */
+ /*****************************/
+
+ if (b_ChronoMode <= 7) {
+ /**************************/
+ /* Test the PCI bus clock */
+ /**************************/
+
+ if ((b_PCIInputClock == APCI1710_30MHZ) ||
+ (b_PCIInputClock == APCI1710_33MHZ) ||
+ (b_PCIInputClock == APCI1710_40MHZ)) {
+ /*************************/
+ /* Test the timing unity */
+ /*************************/
+
+ if (b_TimingUnit <= 4) {
+ /**********************************/
+ /* Test the base timing selection */
+ /**********************************/
+
+ if (((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 66) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165576UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 60) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150240UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 50) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374182UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 1UL))) {
+ /**************************/
+ /* Test the board version */
+ /**************************/
+
+ if (((b_PCIInputClock == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_PCIInputClock != APCI1710_40MHZ)) {
+ /************************/
+ /* Test the TOR version */
+ /************************/
+
+ if (((b_PCIInputClock == APCI1710_40MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131)) || (b_PCIInputClock != APCI1710_40MHZ)) {
+ fpu_begin
+ ();
+
+ /****************************************/
+ /* Calculate the timer 0 division fator */
+ /****************************************/
+
+ switch (b_TimingUnit) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (0.001 * b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (0.001 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (0.001 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (0.001
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (0.001 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 0.99392);
+ }
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (1.0 * b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (1.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (1.0 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (
+ (double)
+ 1.0
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (1.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 0.99392);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ ul_TimingInterval
+ *
+ (1000
+ *
+ b_PCIInputClock);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (1000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (1000.0 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (1000.0
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (1000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 0.99392);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (1000000.0
+ *
+ b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (1000000.0
+ *
+ (double)
+ b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (1000000.0
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 0.99392);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (ul_TimingInterval
+ *
+ 60)
+ *
+ (1000000.0
+ *
+ b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)(ul_TimingInterval * 60.0) * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (1000000.0
+ *
+ (double)
+ b_PCIInputClock))
+ /
+ 60;
+ d_RealTimingInterval
+ =
+ (
+ (double)
+ ul_TimerValue
+ /
+ (0.001 * (double)b_PCIInputClock)) / 60.0;
+
+ if ((double)(((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) / 60.0) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 0.99392);
+ }
+
+ break;
+ }
+
+ fpu_end();
+
+ /****************************/
+ /* Save the PCI input clock */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_PCIInputClock
+ =
+ b_PCIInputClock;
+
+ /*************************/
+ /* Save the timing unity */
+ /*************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_TimingUnit
+ =
+ b_TimingUnit;
+
+ /************************/
+ /* Save the base timing */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ d_TimingInterval
+ =
+ d_RealTimingInterval;
+
+ /****************************/
+ /* Set the chronometer mode */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg
+ =
+ dw_ModeArray
+ [b_ChronoMode];
+
+ /***********************/
+ /* Test if 40 MHz used */
+ /***********************/
+
+ if (b_PCIInputClock == APCI1710_40MHZ) {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg
+ |
+ 0x80;
+ }
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].s_ChronoModuleInfo.dw_ConfigReg, devpriv->s_BoardInfos.ui_Address + 16 + (64 * b_ModulNbr));
+
+ /***********************/
+ /* Write timer 0 value */
+ /***********************/
+
+ outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
+
+ /*********************/
+ /* Chronometer init. */
+ /*********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_ChronoInit
+ =
+ 1;
+ } else {
+ /***********************************************/
+ /* TOR version error for 40MHz clock selection */
+ /***********************************************/
+
+ DPRINTK("TOR version error for 40MHz clock selection\n");
+ i_ReturnValue
+ =
+ -9;
+ }
+ } else {
+ /**************************************************************/
+ /* You can not used the 40MHz clock selection wich this board */
+ /**************************************************************/
+
+ DPRINTK("You can not used the 40MHz clock selection wich this board\n");
+ i_ReturnValue =
+ -8;
+ }
+ } else {
+ /**********************************/
+ /* Base timing selection is wrong */
+ /**********************************/
+
+ DPRINTK("Base timing selection is wrong\n");
+ i_ReturnValue = -7;
+ }
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ else {
+ /***********************************/
+ /* Timing unity selection is wrong */
+ /***********************************/
+
+ DPRINTK("Timing unity selection is wrong\n");
+ i_ReturnValue = -6;
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))
+ else {
+ /*****************************************/
+ /* The selected PCI input clock is wrong */
+ /*****************************************/
+
+ DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue = -5;
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))
+ } // if (b_ChronoMode >= 0 && b_ChronoMode <= 7)
+ else {
+ /***************************************/
+ /* Chronometer mode selection is wrong */
+ /***************************************/
+
+ DPRINTK("Chronometer mode selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_ChronoMode >= 0 && b_ChronoMode <= 7)
+ } else {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+ data[0] = ul_RealTimingInterval;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnableChrono |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_CycleMode, |
+| BYTE_ b_InterruptEnable)
+INT i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
+struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Enable the chronometer from selected module |
+| (b_ModulNbr). You must calling the |
+| "i_APCI1710_InitChrono" function be for you call this |
+| function. |
+| If you enable the chronometer interrupt, the |
+| chronometer generate a interrupt after the stop signal.|
+| See function "i_APCI1710_SetBoardIntRoutineX" and the |
+| Interrupt mask description chapter from this manual. |
+| The b_CycleMode parameter determine if you will |
+| measured a single or more cycle.
+
+| Disable the chronometer from selected module |
+| (b_ModulNbr). If you disable the chronometer after a |
+| start signal occur and you restart the chronometer |
+| witch the " i_APCI1710_EnableChrono" function, if no |
+| stop signal occur this start signal is ignored.
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr CR_AREF(chanspec) : Selected module number (0 to 3) |
+ data[0] ENABle/Disable chrono
+| BYTE_ b_CycleMode : Selected the chronometer |
+| data[1] acquisition mode |
+| BYTE_ b_InterruptEnable : Enable or disable the |
+| data[2] chronometer interrupt. |
+| APCI1710_ENABLE: |
+| Enable the chronometer |
+| interrupt |
+| APCI1710_DISABLE: |
+| Disable the chronometer |
+| interrupt |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
+| -5: Chronometer acquisition mode cycle is wrong |
+| -6: Interrupt parameter is wrong |
+| -7: Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX"
+ -8: data[0] wrong input |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ BYTE b_ModulNbr, b_CycleMode, b_InterruptEnable, b_Action;
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_Action = (BYTE) data[0];
+ b_CycleMode = (BYTE) data[1];
+ b_InterruptEnable = (BYTE) data[2];
+ i_ReturnValue = insn->n;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+ /***********************************/
+ /* Test if chronometer initialised */
+ /***********************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.b_ChronoInit == 1) {
+
+ switch (b_Action) {
+
+ case APCI1710_ENABLE:
+
+ /*********************************/
+ /* Test the cycle mode parameter */
+ /*********************************/
+
+ if ((b_CycleMode == APCI1710_SINGLE)
+ || (b_CycleMode ==
+ APCI1710_CONTINUOUS)) {
+ /***************************/
+ /* Test the interrupt flag */
+ /***************************/
+
+ if ((b_InterruptEnable ==
+ APCI1710_ENABLE)
+ || (b_InterruptEnable ==
+ APCI1710_DISABLE))
+ {
+
+ /***************************/
+ /* Save the interrupt flag */
+ /***************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_InterruptMask
+ =
+ b_InterruptEnable;
+
+ /***********************/
+ /* Save the cycle mode */
+ /***********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_CycleMode =
+ b_CycleMode;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg &
+ 0x8F) | ((1 &
+ b_InterruptEnable)
+ << 5) | ((1 &
+ b_CycleMode)
+ << 6) | 0x10;
+
+ /*****************************/
+ /* Test if interrupt enabled */
+ /*****************************/
+
+ if (b_InterruptEnable ==
+ APCI1710_ENABLE)
+ {
+ /****************************/
+ /* Clear the interrupt flag */
+ /****************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg,
+ devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 32 +
+ (64 * b_ModulNbr));
+ devpriv->tsk_Current = current; // Save the current process task structure
+ }
+
+ /***********************************/
+ /* Enable or disable the interrupt */
+ /* Enable the chronometer */
+ /***********************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 16 +
+ (64 * b_ModulNbr));
+
+ /*************************/
+ /* Clear status register */
+ /*************************/
+
+ outl(0, devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 36 +
+ (64 * b_ModulNbr));
+
+ } // if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))
+ else {
+ /********************************/
+ /* Interrupt parameter is wrong */
+ /********************************/
+
+ DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue = -6;
+ } // if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))
+ } // if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))
+ else {
+ /***********************************************/
+ /* Chronometer acquisition mode cycle is wrong */
+ /***********************************************/
+
+ DPRINTK("Chronometer acquisition mode cycle is wrong\n");
+ i_ReturnValue = -5;
+ } // if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))
+ break;
+
+ case APCI1710_DISABLE:
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_InterruptMask = 0;
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg =
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg & 0x2F;
+
+ /***************************/
+ /* Disable the interrupt */
+ /* Disable the chronometer */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.dw_ConfigReg,
+ devpriv->s_BoardInfos.
+ ui_Address + 16 +
+ (64 * b_ModulNbr));
+
+ /***************************/
+ /* Test if continuous mode */
+ /***************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_CycleMode ==
+ APCI1710_CONTINUOUS) {
+ /*************************/
+ /* Clear status register */
+ /*************************/
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 36 +
+ (64 * b_ModulNbr));
+ }
+ break;
+
+ default:
+ DPRINTK("Inputs wrong! Enable or Disable chrono\n");
+ i_ReturnValue = -8;
+ } // switch ENABLE/DISABLE
+ } else {
+ /*******************************/
+ /* Chronometer not initialised */
+ /*******************************/
+
+ DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnReadChrono(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read functions for Timer |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadChrono(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_ReadType;
+ INT i_ReturnValue = insn->n;
+
+ b_ReadType = CR_CHAN(insn->chanspec);
+
+ switch (b_ReadType) {
+ case APCI1710_CHRONO_PROGRESS_STATUS:
+ i_ReturnValue = i_APCI1710_GetChronoProgressStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_CHRONO_READVALUE:
+ i_ReturnValue = i_APCI1710_ReadChronoValue(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (UINT) insn->unused[0],
+ (PBYTE) & data[0], (PULONG) & data[1]);
+ break;
+
+ case APCI1710_CHRONO_CONVERTVALUE:
+ i_ReturnValue = i_APCI1710_ConvertChronoValue(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (ULONG) insn->unused[0],
+ (PULONG) & data[0],
+ (PBYTE) & data[1],
+ (PBYTE) & data[2],
+ (PUINT) & data[3],
+ (PUINT) & data[4], (PUINT) & data[5]);
+ break;
+
+ case APCI1710_CHRONO_READINTERRUPT:
+ printk("In Chrono Read Interrupt\n");
+
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.
+ ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+ break;
+
+ default:
+ printk("ReadType Parameter wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetChronoProgressStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_ChronoStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the chronometer status (pb_ChronoStatus) from |
+| selected chronometer module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pb_ChronoStatus : Return the chronometer |
+| status. |
+| 0 : Measurement not started.|
+| No start signal occur. |
+| 1 : Measurement started. |
+| A start signal occur. |
+| 2 : Measurement stopped. |
+| A stop signal occur. |
+| The measurement is |
+| terminate. |
+| 3: A overflow occur. You |
+| must change the base |
+| timing witch the |
+| function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetChronoProgressStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_ChronoStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+ /***********************************/
+ /* Test if chronometer initialised */
+ /***********************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.b_ChronoInit == 1) {
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (64 * b_ModulNbr));
+
+ /********************/
+ /* Test if overflow */
+ /********************/
+
+ if ((dw_Status & 8) == 8) {
+ /******************/
+ /* Overflow occur */
+ /******************/
+
+ *pb_ChronoStatus = 3;
+ } // if ((dw_Status & 8) == 8)
+ else {
+ /*******************************/
+ /* Test if measurement stopped */
+ /*******************************/
+
+ if ((dw_Status & 2) == 2) {
+ /***********************/
+ /* A stop signal occur */
+ /***********************/
+
+ *pb_ChronoStatus = 2;
+ } // if ((dw_Status & 2) == 2)
+ else {
+ /*******************************/
+ /* Test if measurement started */
+ /*******************************/
+
+ if ((dw_Status & 1) == 1) {
+ /************************/
+ /* A start signal occur */
+ /************************/
+
+ *pb_ChronoStatus = 1;
+ } // if ((dw_Status & 1) == 1)
+ else {
+ /***************************/
+ /* Measurement not started */
+ /***************************/
+
+ *pb_ChronoStatus = 0;
+ } // if ((dw_Status & 1) == 1)
+ } // if ((dw_Status & 2) == 2)
+ } // if ((dw_Status & 8) == 8)
+ } else {
+ /*******************************/
+ /* Chronometer not initialised */
+ /*******************************/
+ DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadChronoValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| UINT_ ui_TimeOut, |
+| PBYTE_ pb_ChronoStatus, |
+| PULONG_ pul_ChronoValue) |
++----------------------------------------------------------------------------+
+| Task : Return the chronometer status (pb_ChronoStatus) and the|
+| timing value (pul_ChronoValue) after a stop signal |
+| occur from selected chronometer module (b_ModulNbr). |
+| This function are only avaible if you have disabled |
+| the interrupt functionality. See function |
+| "i_APCI1710_EnableChrono" and the Interrupt mask |
+| description chapter. |
+| You can test the chronometer status witch the |
+| "i_APCI1710_GetChronoProgressStatus" function. |
+| |
+| The returned value from pul_ChronoValue parameter is |
+| not real measured timing. |
+| You must used the "i_APCI1710_ConvertChronoValue" |
+| function or make this operation for calculate the |
+| timing: |
+| |
+| Timing = pul_ChronoValue * pul_RealTimingInterval. |
+| |
+| pul_RealTimingInterval is the returned parameter from |
+| "i_APCI1710_InitChrono" function and the time unity is |
+| the b_TimingUnit from "i_APCI1710_InitChrono" function|
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pb_ChronoStatus : Return the chronometer |
+| status. |
+| 0 : Measurement not started.|
+| No start signal occur. |
+| 1 : Measurement started. |
+| A start signal occur. |
+| 2 : Measurement stopped. |
+| A stop signal occur. |
+| The measurement is |
+| terminate. |
+| 3: A overflow occur. You |
+| must change the base |
+| timing witch the |
+| function |
+| "i_APCI1710_InitChrono" |
+| PULONG pul_ChronoValue : Chronometer timing value. |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
+| -5: Timeout parameter is wrong (0 to 65535) |
+| -6: Interrupt routine installed. You can not read |
+| directly the chronometer measured timing. |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadChronoValue(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ UINT ui_TimeOut, PBYTE pb_ChronoStatus, PULONG pul_ChronoValue)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ DWORD dw_TimeOut = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+ /***********************************/
+ /* Test if chronometer initialised */
+ /***********************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.b_ChronoInit == 1) {
+ /*****************************/
+ /* Test the timout parameter */
+ /*****************************/
+
+ if ((ui_TimeOut >= 0)
+ && (ui_TimeOut <= 65535UL)) {
+
+ for (;;) {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ dw_Status =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 8 +
+ (64 * b_ModulNbr));
+
+ /********************/
+ /* Test if overflow */
+ /********************/
+
+ if ((dw_Status & 8) == 8) {
+ /******************/
+ /* Overflow occur */
+ /******************/
+
+ *pb_ChronoStatus = 3;
+
+ /***************************/
+ /* Test if continuous mode */
+ /***************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_CycleMode ==
+ APCI1710_CONTINUOUS)
+ {
+ /*************************/
+ /* Clear status register */
+ /*************************/
+
+ outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));
+ }
+
+ break;
+ } // if ((dw_Status & 8) == 8)
+ else {
+ /*******************************/
+ /* Test if measurement stopped */
+ /*******************************/
+
+ if ((dw_Status & 2) ==
+ 2) {
+ /***********************/
+ /* A stop signal occur */
+ /***********************/
+
+ *pb_ChronoStatus
+ = 2;
+
+ /***************************/
+ /* Test if continnous mode */
+ /***************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_CycleMode
+ ==
+ APCI1710_CONTINUOUS)
+ {
+ /*************************/
+ /* Clear status register */
+ /*************************/
+
+ outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));
+ }
+ break;
+ } // if ((dw_Status & 2) == 2)
+ else {
+ /*******************************/
+ /* Test if measurement started */
+ /*******************************/
+
+ if ((dw_Status & 1) == 1) {
+ /************************/
+ /* A start signal occur */
+ /************************/
+
+ *pb_ChronoStatus
+ =
+ 1;
+ } // if ((dw_Status & 1) == 1)
+ else {
+ /***************************/
+ /* Measurement not started */
+ /***************************/
+
+ *pb_ChronoStatus
+ =
+ 0;
+ } // if ((dw_Status & 1) == 1)
+ } // if ((dw_Status & 2) == 2)
+ } // if ((dw_Status & 8) == 8)
+
+ if (dw_TimeOut == ui_TimeOut) {
+ /*****************/
+ /* Timeout occur */
+ /*****************/
+
+ break;
+ } else {
+ /*************************/
+ /* Increment the timeout */
+ /*************************/
+
+ dw_TimeOut =
+ dw_TimeOut + 1;
+ mdelay(1000);
+
+ }
+ } // for (;;)
+
+ /*****************************/
+ /* Test if stop signal occur */
+ /*****************************/
+
+ if (*pb_ChronoStatus == 2) {
+ /**********************************/
+ /* Read the measured timing value */
+ /**********************************/
+
+ *pul_ChronoValue =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 4 +
+ (64 * b_ModulNbr));
+
+ if (*pul_ChronoValue != 0) {
+ *pul_ChronoValue =
+ *pul_ChronoValue
+ - 1;
+ }
+ } else {
+ /*************************/
+ /* Test if timeout occur */
+ /*************************/
+
+ if ((*pb_ChronoStatus != 3)
+ && (dw_TimeOut ==
+ ui_TimeOut)
+ && (ui_TimeOut != 0)) {
+ /*****************/
+ /* Timeout occur */
+ /*****************/
+
+ *pb_ChronoStatus = 4;
+ }
+ }
+
+ } else {
+ /******************************/
+ /* Timeout parameter is wrong */
+ /******************************/
+ DPRINTK("Timeout parameter is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /*******************************/
+ /* Chronometer not initialised */
+ /*******************************/
+ DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ConvertChronoValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| ULONG_ ul_ChronoValue, |
+| PULONG_ pul_Hour, |
+| PBYTE_ pb_Minute, |
+| PBYTE_ pb_Second, |
+| PUINT_ pui_MilliSecond, |
+| PUINT_ pui_MicroSecond, |
+| PUINT_ pui_NanoSecond) |
++----------------------------------------------------------------------------+
+| Task : Convert the chronometer measured timing |
+| (ul_ChronoValue) in to h, mn, s, ms, µs, ns. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
+| ULONG_ ul_ChronoValue : Measured chronometer timing |
+| value. |
+| See"i_APCI1710_ReadChronoValue"|
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_Hour : Chronometer timing hour |
+| PBYTE_ pb_Minute : Chronometer timing minute |
+| PBYTE_ pb_Second : Chronometer timing second |
+| PUINT_ pui_MilliSecond : Chronometer timing mini |
+| second |
+| PUINT_ pui_MicroSecond : Chronometer timing micro |
+| second |
+| PUINT_ pui_NanoSecond : Chronometer timing nano |
+| second |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ConvertChronoValue(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ ULONG ul_ChronoValue,
+ PULONG pul_Hour,
+ PBYTE pb_Minute,
+ PBYTE pb_Second,
+ PUINT pui_MilliSecond, PUINT pui_MicroSecond, PUINT pui_NanoSecond)
+{
+ INT i_ReturnValue = 0;
+ double d_Hour;
+ double d_Minute;
+ double d_Second;
+ double d_MilliSecond;
+ double d_MicroSecond;
+ double d_NanoSecond;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+ /***********************************/
+ /* Test if chronometer initialised */
+ /***********************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.b_ChronoInit == 1) {
+ fpu_begin();
+
+ d_Hour = (double)ul_ChronoValue *(double)
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.d_TimingInterval;
+
+ switch (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.b_TimingUnit) {
+ case 0:
+ d_Hour = d_Hour / (double)1000.0;
+
+ case 1:
+ d_Hour = d_Hour / (double)1000.0;
+
+ case 2:
+ d_Hour = d_Hour / (double)1000.0;
+
+ case 3:
+ d_Hour = d_Hour / (double)60.0;
+
+ case 4:
+ /**********************/
+ /* Calculate the hour */
+ /**********************/
+
+ d_Hour = d_Hour / (double)60.0;
+ *pul_Hour = (ULONG) d_Hour;
+
+ /************************/
+ /* Calculate the minute */
+ /************************/
+
+ d_Minute = d_Hour - *pul_Hour;
+ d_Minute = d_Minute * 60;
+ *pb_Minute = (BYTE) d_Minute;
+
+ /************************/
+ /* Calculate the second */
+ /************************/
+
+ d_Second = d_Minute - *pb_Minute;
+ d_Second = d_Second * 60;
+ *pb_Second = (BYTE) d_Second;
+
+ /*****************************/
+ /* Calculate the mini second */
+ /*****************************/
+
+ d_MilliSecond = d_Second - *pb_Second;
+ d_MilliSecond = d_MilliSecond * 1000;
+ *pui_MilliSecond = (UINT) d_MilliSecond;
+
+ /******************************/
+ /* Calculate the micro second */
+ /******************************/
+
+ d_MicroSecond =
+ d_MilliSecond -
+ *pui_MilliSecond;
+ d_MicroSecond = d_MicroSecond * 1000;
+ *pui_MicroSecond = (UINT) d_MicroSecond;
+
+ /******************************/
+ /* Calculate the micro second */
+ /******************************/
+
+ d_NanoSecond =
+ d_MicroSecond -
+ *pui_MicroSecond;
+ d_NanoSecond = d_NanoSecond * 1000;
+ *pui_NanoSecond = (UINT) d_NanoSecond;
+ break;
+ }
+
+ fpu_end();
+ } else {
+ /*******************************/
+ /* Chronometer not initialised */
+ /*******************************/
+ DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Sets the output witch has been passed with the |
+| parameter b_Channel. Setting an output means setting an|
+| output high. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
+| BYTE_ b_OutputChannel : Selection from digital output |
+| CR_CHAN() channel (0 to 2) |
+| 0 : Channel H |
+| 1 : Channel A |
+| 2 : Channel B |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: The selected digital output is wrong |
+| -5: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetChronoChlOff |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_OutputChannel) |
++----------------------------------------------------------------------------+
+| Task : Resets the output witch has been passed with the |
+| parameter b_Channel. Resetting an output means setting |
+| an output low. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710
+ data[0] : Chl ON, Chl OFF , Chl Read , Port Read
+
+| BYTE_ b_ModulNbr CR_AREF : Selected module number (0 to 3)|
+| BYTE_ b_OutputChannel CR_CHAN : Selection from digital output |
+| channel (0 to 2) |
+| 0 : Channel H |
+| 1 : Channel A |
+| 2 : Channel B |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: The selected digital output is wrong |
+| -5: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadChronoChlValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_InputChannel, |
+| PBYTE_ pb_ChannelStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the status from selected digital input |
+| (b_InputChannel) from selected chronometer |
+| module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
+| BYTE_ b_InputChannel : Selection from digital input |
+| channel (0 to 2) |
+| CR_CHAN() 0 : Channel E |
+| 1 : Channel F |
+| 2 : Channel G |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_ChannelStatus : Digital input channel status.|
+| data[0] 0 : Channel is not active |
+| 1 : Channel is active |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: The selected digital input is wrong |
+| -5: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadChronoPortValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_PortValue) |
++----------------------------------------------------------------------------+
+| Task : Return the status from digital inputs port from |
+| selected (b_ModulNbr) chronometer module. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_PortValue : Digital inputs port status.
+| data[0]
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ BYTE b_ModulNbr, b_OutputChannel, b_InputChannel, b_IOType;
+ DWORD dw_Status;
+ PBYTE pb_ChannelStatus;
+ PBYTE pb_PortValue;
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ i_ReturnValue = insn->n;
+ b_IOType = (BYTE) data[0];
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+ /***********************************/
+ /* Test if chronometer initialised */
+ /***********************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.b_ChronoInit == 1) {
+ /***********************************/
+ /* Test the digital output channel */
+ /***********************************/
+ switch (b_IOType) {
+
+ case APCI1710_CHRONO_SET_CHANNELOFF:
+
+ b_OutputChannel =
+ (BYTE) CR_CHAN(insn->chanspec);
+ if (b_OutputChannel <= 2) {
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 20 +
+ (b_OutputChannel * 4) +
+ (64 * b_ModulNbr));
+ } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
+ else {
+ /****************************************/
+ /* The selected digital output is wrong */
+ /****************************************/
+
+ DPRINTK("The selected digital output is wrong\n");
+ i_ReturnValue = -4;
+
+ } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
+
+ break;
+
+ case APCI1710_CHRONO_SET_CHANNELON:
+
+ b_OutputChannel =
+ (BYTE) CR_CHAN(insn->chanspec);
+ if (b_OutputChannel <= 2) {
+
+ outl(1, devpriv->s_BoardInfos.
+ ui_Address + 20 +
+ (b_OutputChannel * 4) +
+ (64 * b_ModulNbr));
+ } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
+ else {
+ /****************************************/
+ /* The selected digital output is wrong */
+ /****************************************/
+
+ DPRINTK("The selected digital output is wrong\n");
+ i_ReturnValue = -4;
+
+ } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
+
+ break;
+
+ case APCI1710_CHRONO_READ_CHANNEL:
+ /**********************************/
+ /* Test the digital input channel */
+ /**********************************/
+ pb_ChannelStatus = (PBYTE) & data[0];
+ b_InputChannel =
+ (BYTE) CR_CHAN(insn->chanspec);
+
+ if (b_InputChannel <= 2) {
+
+ dw_Status =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 12 +
+ (64 * b_ModulNbr));
+
+ *pb_ChannelStatus =
+ (BYTE) (((dw_Status >>
+ b_InputChannel)
+ & 1) ^ 1);
+ } // if ((b_InputChannel >= 0) && (b_InputChannel <= 2))
+ else {
+ /***************************************/
+ /* The selected digital input is wrong */
+ /***************************************/
+
+ DPRINTK("The selected digital input is wrong\n");
+ i_ReturnValue = -4;
+ } // if ((b_InputChannel >= 0) && (b_InputChannel <= 2))
+
+ break;
+
+ case APCI1710_CHRONO_READ_PORT:
+
+ pb_PortValue = (PBYTE) & data[0];
+
+ dw_Status =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 12 +
+ (64 * b_ModulNbr));
+
+ *pb_PortValue =
+ (BYTE) ((dw_Status & 0x7) ^ 7);
+ break;
+ }
+ } else {
+ /*******************************/
+ /* Chronometer not initialised */
+ /*******************************/
+
+ DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h
new file mode 100644
index 00000000000..26b50cefee5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
+
+#define APCI1710_SINGLE 0
+#define APCI1710_CONTINUOUS 1
+
+#define APCI1710_CHRONO_PROGRESS_STATUS 0
+#define APCI1710_CHRONO_READVALUE 1
+#define APCI1710_CHRONO_CONVERTVALUE 2
+#define APCI1710_CHRONO_READINTERRUPT 3
+
+#define APCI1710_CHRONO_SET_CHANNELON 0
+#define APCI1710_CHRONO_SET_CHANNELOFF 1
+#define APCI1710_CHRONO_READ_CHANNEL 2
+#define APCI1710_CHRONO_READ_PORT 3
+
+/*
+ * CHRONOMETER INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+/*
+ * CHRONOMETER READ FUNCTION
+ */
+INT i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_ChronoStatus);
+
+INT i_APCI1710_ReadChronoValue(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ UINT ui_TimeOut, PBYTE pb_ChronoStatus,
+ PULONG pul_ChronoValue);
+
+INT i_APCI1710_ConvertChronoValue(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ ULONG ul_ChronoValue,
+ PULONG pul_Hour,
+ PBYTE pb_Minute,
+ PBYTE pb_Second,
+ PUINT pui_MilliSecond, PUINT pui_MicroSecond,
+ PUINT pui_NanoSecond);
+
+/*
+ * CHRONOMETER DIGITAL INPUT OUTPUT FUNCTION
+ */
+INT i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
new file mode 100644
index 00000000000..8be27aedaaf
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
@@ -0,0 +1,1020 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : DIG_IO.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 digital I/O module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 16/06/98 | S. Weber | Digital input / output implementation |
+ |----------|-----------|------------------------------------------------|
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+ | | | |
+ | | | |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "APCI1710_Dig_io.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, |
+| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
++----------------------------------------------------------------------------+
+| Task : Configure the digital I/O operating mode from selected |
+| module (b_ModulNbr). You must calling this function be|
+| for you call any other function witch access of digital|
+| I/O. |
++----------------------------------------------------------------------------+
+| Input Parameters : |
+| BYTE_ b_ModulNbr data[0]: Module number to |
+| configure (0 to 3) |
+| BYTE_ b_ChannelAMode data[1] : Channel A mode selection |
+| 0 : Channel used for digital |
+| input |
+| 1 : Channel used for digital |
+| output |
+| BYTE_ b_ChannelBMode data[2] : Channel B mode selection |
+| 0 : Channel used for digital |
+| input |
+| 1 : Channel used for digital |
+| output |
+ data[0] memory on/off
+Activates and deactivates the digital output memory.
+ After having |
+| called up this function with memory on,the output you have previously|
+| activated with the function are not reset
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a digital I/O module |
+| -4: Bi-directional channel A configuration error |
+| -5: Bi-directional channel B configuration error |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigDigitalIO(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_ModulNbr, b_ChannelAMode, b_ChannelBMode;
+ BYTE b_MemoryOnOff, b_ConfigType;
+ INT i_ReturnValue = 0;
+ DWORD dw_WriteConfig = 0;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_ConfigType = (BYTE) data[0]; // Memory or Init
+ b_ChannelAMode = (BYTE) data[1];
+ b_ChannelBMode = (BYTE) data[2];
+ b_MemoryOnOff = (BYTE) data[1]; // if memory operation
+ i_ReturnValue = insn->n;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr >= 4) {
+ DPRINTK("Module Number invalid\n");
+ i_ReturnValue = -2;
+ return i_ReturnValue;
+ }
+ switch (b_ConfigType) {
+ case APCI1710_DIGIO_MEMORYONOFF:
+
+ if (b_MemoryOnOff) // If Memory ON
+ {
+ /****************************/
+ /* Set the output memory on */
+ /****************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_OutputMemoryEnabled = 1;
+
+ /***************************/
+ /* Clear the output memory */
+ /***************************/
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.dw_OutputMemory = 0;
+ } else // If memory off
+ {
+ /*****************************/
+ /* Set the output memory off */
+ /*****************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_OutputMemoryEnabled = 0;
+ }
+ break;
+
+ case APCI1710_DIGIO_INIT:
+
+ /*******************************/
+ /* Test if digital I/O counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+
+ /***************************************************/
+ /* Test the bi-directional channel A configuration */
+ /***************************************************/
+
+ if ((b_ChannelAMode == 0) || (b_ChannelAMode == 1)) {
+ /***************************************************/
+ /* Test the bi-directional channel B configuration */
+ /***************************************************/
+
+ if ((b_ChannelBMode == 0)
+ || (b_ChannelBMode == 1)) {
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_DigitalInit =
+ 1;
+
+ /********************************/
+ /* Save channel A configuration */
+ /********************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelAMode = b_ChannelAMode;
+
+ /********************************/
+ /* Save channel B configuration */
+ /********************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelBMode = b_ChannelBMode;
+
+ /*****************************************/
+ /* Set the channel A and B configuration */
+ /*****************************************/
+
+ dw_WriteConfig =
+ (DWORD) (b_ChannelAMode |
+ (b_ChannelBMode * 2));
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(dw_WriteConfig,
+ devpriv->s_BoardInfos.
+ ui_Address + 4 +
+ (64 * b_ModulNbr));
+
+ } else {
+ /************************************************/
+ /* Bi-directional channel B configuration error */
+ /************************************************/
+ DPRINTK("Bi-directional channel B configuration error\n");
+ i_ReturnValue = -5;
+ }
+
+ } else {
+ /************************************************/
+ /* Bi-directional channel A configuration error */
+ /************************************************/
+ DPRINTK("Bi-directional channel A configuration error\n");
+ i_ReturnValue = -4;
+
+ }
+
+ } else {
+ /******************************************/
+ /* The module is not a digital I/O module */
+ /******************************************/
+ DPRINTK("The module is not a digital I/O module\n");
+ i_ReturnValue = -3;
+ }
+ } // end of Switch
+ printk("Return Value %d\n", i_ReturnValue);
+ return i_ReturnValue;
+}
+
+/*
++----------------------------------------------------------------------------+
+| INPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+
+|INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,comedi_subdevice
+*s, struct comedi_insn *insn,unsigned int *data)
+
++----------------------------------------------------------------------------+
+| Task : Read the status from selected digital I/O digital input|
+| (b_InputChannel) |
++----------------------------------------------------------------------------|
+
+
+|
+| BYTE_ b_ModulNbr CR_AREF(chanspec) : Selected module number |
+| (0 to 3) |
+| BYTE_ b_InputChannel CR_CHAN(chanspec) : Selection from digital |
+| input ( 0 to 6) |
+| 0 : Channel C |
+| 1 : Channel D |
+| 2 : Channel E |
+| 3 : Channel F |
+| 4 : Channel G |
+| 5 : Channel A |
+| 6 : Channel B
+
+
+ |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Digital input channel |
+| status |
+| 0 : Channle is not active|
+| 1 : Channle is active |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a digital I/O module |
+| -4: The selected digital I/O digital input is wrong |
+| -5: Digital I/O not initialised |
+| -6: The digital channel A is used for output |
+| -7: The digital channel B is used for output |
++----------------------------------------------------------------------------+
+*/
+
+//_INT_ i_APCI1710_ReadDigitalIOChlValue (BYTE_ b_BoardHandle,
+// BYTE_ b_ModulNbr,
+// BYTE_ b_InputChannel,
+//
+// PBYTE_ pb_ChannelStatus)
+INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg;
+ BYTE b_ModulNbr, b_InputChannel;
+ PBYTE pb_ChannelStatus;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_InputChannel = (BYTE) CR_CHAN(insn->chanspec);
+ data[0] = 0;
+ pb_ChannelStatus = (PBYTE) & data[0];
+ i_ReturnValue = insn->n;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if digital I/O counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+ /******************************************/
+ /* Test the digital imnput channel number */
+ /******************************************/
+
+ if (b_InputChannel <= 6) {
+ /**********************************************/
+ /* Test if the digital I/O module initialised */
+ /**********************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_DigitalInit == 1) {
+ /**********************************/
+ /* Test if channel A or channel B */
+ /**********************************/
+
+ if (b_InputChannel > 4) {
+ /*********************/
+ /* Test if channel A */
+ /*********************/
+
+ if (b_InputChannel == 5) {
+ /***************************/
+ /* Test the channel A mode */
+ /***************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelAMode
+ != 0) {
+ /********************************************/
+ /* The digital channel A is used for output */
+ /********************************************/
+
+ i_ReturnValue =
+ -6;
+ }
+ } // if (b_InputChannel == 5)
+ else {
+ /***************************/
+ /* Test the channel B mode */
+ /***************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelBMode
+ != 0) {
+ /********************************************/
+ /* The digital channel B is used for output */
+ /********************************************/
+
+ i_ReturnValue =
+ -7;
+ }
+ } // if (b_InputChannel == 5)
+ } // if (b_InputChannel > 4)
+
+ /***********************/
+ /* Test if error occur */
+ /***********************/
+
+ if (i_ReturnValue >= 0) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ //INPDW (ps_APCI1710Variable->
+ // s_Board [b_BoardHandle].
+ // s_BoardInfos.
+ // ui_Address + (64 * b_ModulNbr),
+ // &dw_StatusReg);
+
+ dw_StatusReg =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (64 * b_ModulNbr));
+
+ *pb_ChannelStatus =
+ (BYTE) ((dw_StatusReg ^
+ 0x1C) >>
+ b_InputChannel) & 1;
+
+ } // if (i_ReturnValue == 0)
+ } else {
+ /*******************************/
+ /* Digital I/O not initialised */
+ /*******************************/
+ DPRINTK("Digital I/O not initialised\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /********************************/
+ /* Selected digital input error */
+ /********************************/
+ DPRINTK("Selected digital input error\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a digital I/O module */
+ /******************************************/
+ DPRINTK("The module is not a digital I/O module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| OUTPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device
+|*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)
+
++----------------------------------------------------------------------------+
+| Task : Sets or resets the output witch has been passed with the |
+| parameter b_Channel. Setting an output means setting |
+| an ouput high. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr (aref ) : Selected module number (0 to 3)|
+| BYTE_ b_OutputChannel (CR_CHAN) : Selection from digital output |
+| channel (0 to 2) |
+| 0 : Channel H |
+| 1 : Channel A |
+| 2 : Channel B |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a digital I/O module |
+| -4: The selected digital output is wrong |
+| -5: digital I/O not initialised see function |
+| " i_APCI1710_InitDigitalIO" |
+| -6: The digital channel A is used for input |
+| -7: The digital channel B is used for input
+ -8: Digital Output Memory OFF. |
+| Use previously the function |
+| "i_APCI1710_SetDigitalIOMemoryOn". |
++----------------------------------------------------------------------------+
+*/
+
+//_INT_ i_APCI1710_SetDigitalIOChlOn (BYTE_ b_BoardHandle,
+// BYTE_ b_ModulNbr,
+// BYTE_ b_OutputChannel)
+INT i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_WriteValue = 0;
+ BYTE b_ModulNbr, b_OutputChannel;
+ i_ReturnValue = insn->n;
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_OutputChannel = CR_CHAN(insn->chanspec);
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if digital I/O counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+ /**********************************************/
+ /* Test if the digital I/O module initialised */
+ /**********************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_DigitalInit == 1) {
+ /******************************************/
+ /* Test the digital output channel number */
+ /******************************************/
+
+ switch (b_OutputChannel) {
+ /*************/
+ /* Channel H */
+ /*************/
+
+ case 0:
+ break;
+
+ /*************/
+ /* Channel A */
+ /*************/
+
+ case 1:
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelAMode != 1) {
+ /*******************************************/
+ /* The digital channel A is used for input */
+ /*******************************************/
+
+ i_ReturnValue = -6;
+ }
+ break;
+
+ /*************/
+ /* Channel B */
+ /*************/
+
+ case 2:
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelBMode != 1) {
+ /*******************************************/
+ /* The digital channel B is used for input */
+ /*******************************************/
+
+ i_ReturnValue = -7;
+ }
+ break;
+
+ default:
+ /****************************************/
+ /* The selected digital output is wrong */
+ /****************************************/
+
+ i_ReturnValue = -4;
+ break;
+ }
+
+ /***********************/
+ /* Test if error occur */
+ /***********************/
+
+ if (i_ReturnValue >= 0) {
+
+ /*********************************/
+ /* Test if set channel ON */
+ /*********************************/
+ if (data[0]) {
+ /*********************************/
+ /* Test if output memory enabled */
+ /*********************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_OutputMemoryEnabled ==
+ 1) {
+ dw_WriteValue =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ | (1 <<
+ b_OutputChannel);
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ = dw_WriteValue;
+ } else {
+ dw_WriteValue =
+ 1 <<
+ b_OutputChannel;
+ }
+ } // set channel off
+ else {
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_OutputMemoryEnabled ==
+ 1) {
+ dw_WriteValue =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ & (0xFFFFFFFFUL
+ -
+ (1 << b_OutputChannel));
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ = dw_WriteValue;
+ } else {
+ /*****************************/
+ /* Digital Output Memory OFF */
+ /*****************************/
+ // +Use previously the function "i_APCI1710_SetDigitalIOMemoryOn"
+ i_ReturnValue = -8;
+ }
+
+ }
+ /*******************/
+ /* Write the value */
+ /*******************/
+
+ //OUTPDW (ps_APCI1710Variable->
+ // s_Board [b_BoardHandle].
+ // s_BoardInfos.
+ // ui_Address + (64 * b_ModulNbr),
+ // dw_WriteValue);
+ outl(dw_WriteValue,
+ devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+ }
+ } else {
+ /*******************************/
+ /* Digital I/O not initialised */
+ /*******************************/
+
+ i_ReturnValue = -5;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a digital I/O module */
+ /******************************************/
+
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+
+|INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,comedi_subdevice
+ *s, struct comedi_insn *insn,unsigned int *data)
++----------------------------------------------------------------------------+
+| Task : write:
+ Sets or resets one or several outputs from port. |
+| Setting an output means setting an output high. |
+| If you have switched OFF the digital output memory |
+| (OFF), all the other output are set to "0".
+
+| read:
+ Read the status from digital input port |
+| from selected digital I/O module (b_ModulNbr)
++----------------------------------------------------------------------------+
+| Input Parameters :
+ BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr CR_AREF(aref) : Selected module number (0 to 3)|
+| BYTE_ b_PortValue CR_CHAN(chanspec) : Output Value ( 0 To 7 )
+| data[0] read or write port
+ data[1] if write then indicate ON or OFF
+
+ if read : data[1] will return port status.
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
+
+ INPUT :
+
+ 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a digital I/O module |
+| -4: Digital I/O not initialised
+
+ OUTPUT: 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a digital I/O module |
+| -4: Output value wrong |
+| -5: digital I/O not initialised see function |
+| " i_APCI1710_InitDigitalIO" |
+| -6: The digital channel A is used for input |
+| -7: The digital channel B is used for input
+ -8: Digital Output Memory OFF. |
+| Use previously the function |
+| "i_APCI1710_SetDigitalIOMemoryOn". |
++----------------------------------------------------------------------------+
+*/
+
+//_INT_ i_APCI1710_SetDigitalIOPortOn (BYTE_ b_BoardHandle,
+// BYTE_ b_ModulNbr,
+// BYTE_ b_PortValue)
+INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_WriteValue = 0;
+ DWORD dw_StatusReg;
+ BYTE b_ModulNbr, b_PortValue;
+ BYTE b_PortOperation, b_PortOnOFF;
+
+ PBYTE pb_PortValue;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_PortOperation = (BYTE) data[0]; // Input or output
+ b_PortOnOFF = (BYTE) data[1]; // if output then On or Off
+ b_PortValue = (BYTE) data[2]; // if out put then Value
+ i_ReturnValue = insn->n;
+ pb_PortValue = (PBYTE) & data[0];
+// if input then read value
+
+ switch (b_PortOperation) {
+ case APCI1710_INPUT:
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if digital I/O counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+ /**********************************************/
+ /* Test if the digital I/O module initialised */
+ /**********************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_DigitalInit == 1) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ //INPDW (ps_APCI1710Variable->
+ // s_Board [b_BoardHandle].
+ // s_BoardInfos.
+ // ui_Address + (64 * b_ModulNbr),
+ // &dw_StatusReg);
+
+ dw_StatusReg =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+ *pb_PortValue =
+ (BYTE) (dw_StatusReg ^ 0x1C);
+
+ } else {
+ /*******************************/
+ /* Digital I/O not initialised */
+ /*******************************/
+
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a digital I/O module */
+ /******************************************/
+
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ i_ReturnValue = -2;
+ }
+
+ break;
+
+ case APCI1710_OUTPUT:
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if digital I/O counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+ /**********************************************/
+ /* Test if the digital I/O module initialised */
+ /**********************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_DigitalInit == 1) {
+ /***********************/
+ /* Test the port value */
+ /***********************/
+
+ if (b_PortValue <= 7) {
+ /***********************************/
+ /* Test the digital output channel */
+ /***********************************/
+
+ /**************************/
+ /* Test if channel A used */
+ /**************************/
+
+ if ((b_PortValue & 2) == 2) {
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelAMode
+ != 1) {
+ /*******************************************/
+ /* The digital channel A is used for input */
+ /*******************************************/
+
+ i_ReturnValue =
+ -6;
+ }
+ } // if ((b_PortValue & 2) == 2)
+
+ /**************************/
+ /* Test if channel B used */
+ /**************************/
+
+ if ((b_PortValue & 4) == 4) {
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelBMode
+ != 1) {
+ /*******************************************/
+ /* The digital channel B is used for input */
+ /*******************************************/
+
+ i_ReturnValue =
+ -7;
+ }
+ } // if ((b_PortValue & 4) == 4)
+
+ /***********************/
+ /* Test if error occur */
+ /***********************/
+
+ if (i_ReturnValue >= 0) {
+
+ //if(data[1])
+ //{
+ switch (b_PortOnOFF) {
+ /*********************************/
+ /* Test if set Port ON */
+ /*********************************/
+
+ case APCI1710_ON:
+
+ /*********************************/
+ /* Test if output memory enabled */
+ /*********************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_OutputMemoryEnabled
+ == 1) {
+ dw_WriteValue
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ |
+ b_PortValue;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ =
+ dw_WriteValue;
+ } else {
+ dw_WriteValue
+ =
+ b_PortValue;
+ }
+ break;
+
+ // If Set PORT OFF
+ case APCI1710_OFF:
+
+ /*********************************/
+ /* Test if output memory enabled */
+ /*********************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_OutputMemoryEnabled
+ == 1) {
+ dw_WriteValue
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ &
+ (0xFFFFFFFFUL
+ -
+ b_PortValue);
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ =
+ dw_WriteValue;
+ } else {
+ /*****************************/
+ /* Digital Output Memory OFF */
+ /*****************************/
+
+ i_ReturnValue
+ =
+ -8;
+ }
+ } // switch
+
+ /*******************/
+ /* Write the value */
+ /*******************/
+
+ // OUTPDW (ps_APCI1710Variable->
+ // s_Board [b_BoardHandle].
+ // s_BoardInfos.
+ // ui_Address + (64 * b_ModulNbr),
+ // dw_WriteValue);
+ outl(dw_WriteValue,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (64 * b_ModulNbr));
+ }
+ } else {
+ /**********************/
+ /* Output value wrong */
+ /**********************/
+
+ i_ReturnValue = -4;
+ }
+ } else {
+ /*******************************/
+ /* Digital I/O not initialised */
+ /*******************************/
+
+ i_ReturnValue = -5;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a digital I/O module */
+ /******************************************/
+
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ i_ReturnValue = -2;
+ }
+ break;
+
+ default:
+ i_ReturnValue = -9;
+ DPRINTK("NO INPUT/OUTPUT specified\n");
+ } //switch INPUT / OUTPUT
+ return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h
new file mode 100644
index 00000000000..5ef157a55ca
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+#define APCI1710_ON 1 /* Digital Output ON or OFF */
+#define APCI1710_OFF 0
+
+#define APCI1710_INPUT 0 /* Digital I/O */
+#define APCI1710_OUTPUT 1
+
+#define APCI1710_DIGIO_MEMORYONOFF 0x10
+#define APCI1710_DIGIO_INIT 0x11
+
+/*
+ * DIGITAL I/O INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * INPUT OUTPUT FUNCTIONS
+ */
+INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
new file mode 100644
index 00000000000..1062f2fdec3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
@@ -0,0 +1,5363 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : INC_CPT.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 incremental counter module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ |----------|-----------|------------------------------------------------|
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+ | 29/06/01 | Guinot C. | - 1100/0231 -> 0701/0232 |
+ | | | See i_APCI1710_DisableFrequencyMeasurement |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_INCCPT.h"
+
+/*
++----------------------------------------------------------------------------+
+| INT i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data)
+
++----------------------------------------------------------------------------+
+| Task : Configuration function for INC_CPT |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : *data
++----------------------------------------------------------------------------+
+| Return Value : |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigINCCPT(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_ConfigType;
+ INT i_ReturnValue = 0;
+ ui_ConfigType = CR_CHAN(insn->chanspec);
+
+ printk("\nINC_CPT");
+
+ devpriv->tsk_Current = current; // Save the current process task structure
+ switch (ui_ConfigType) {
+ case APCI1710_INCCPT_INITCOUNTER:
+ i_ReturnValue = i_APCI1710_InitCounter(dev,
+ CR_AREF(insn->chanspec),
+ (BYTE) data[0],
+ (BYTE) data[1],
+ (BYTE) data[2], (BYTE) data[3], (BYTE) data[4]);
+ break;
+
+ case APCI1710_INCCPT_COUNTERAUTOTEST:
+ i_ReturnValue = i_APCI1710_CounterAutoTest(dev,
+ (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_INITINDEX:
+ i_ReturnValue = i_APCI1710_InitIndex(dev,
+ CR_AREF(insn->chanspec),
+ (BYTE) data[0],
+ (BYTE) data[1], (BYTE) data[2], (BYTE) data[3]);
+ break;
+
+ case APCI1710_INCCPT_INITREFERENCE:
+ i_ReturnValue = i_APCI1710_InitReference(dev,
+ CR_AREF(insn->chanspec), (BYTE) data[0]);
+ break;
+
+ case APCI1710_INCCPT_INITEXTERNALSTROBE:
+ i_ReturnValue = i_APCI1710_InitExternalStrobe(dev,
+ CR_AREF(insn->chanspec),
+ (BYTE) data[0], (BYTE) data[1]);
+ break;
+
+ case APCI1710_INCCPT_INITCOMPARELOGIC:
+ i_ReturnValue = i_APCI1710_InitCompareLogic(dev,
+ CR_AREF(insn->chanspec), (UINT) data[0]);
+ break;
+
+ case APCI1710_INCCPT_INITFREQUENCYMEASUREMENT:
+ i_ReturnValue = i_APCI1710_InitFrequencyMeasurement(dev,
+ CR_AREF(insn->chanspec),
+ (BYTE) data[0],
+ (BYTE) data[1], (ULONG) data[2], (PULONG) & data[0]);
+ break;
+
+ default:
+ printk("Insn Config : Config Parameter Wrong\n");
+
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitCounter |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_CounterRange, |
+| BYTE_ b_FirstCounterModus, |
+| BYTE_ b_FirstCounterOption, |
+| BYTE_ b_SecondCounterModus, |
+| BYTE_ b_SecondCounterOption) |
++----------------------------------------------------------------------------+
+| Task : Configure the counter operating mode from selected |
+| module (b_ModulNbr). You must calling this function be |
+| for you call any other function witch access of |
+| counters. |
+| |
+| Counter range |
+| ------------- |
+| +------------------------------------+-----------------------------------+ |
+| | Parameter Passed value | Description | |
+| |------------------------------------+-----------------------------------| |
+| |b_ModulNbr APCI1710_16BIT_COUNTER | The module is configured for | |
+| | | two 16-bit counter. | |
+| | | - b_FirstCounterModus and | |
+| | | b_FirstCounterOption | |
+| | | configure the first 16 bit | |
+| | | counter. | |
+| | | - b_SecondCounterModus and | |
+| | | b_SecondCounterOption | |
+| | | configure the second 16 bit | |
+| | | counter. | |
+| |------------------------------------+-----------------------------------| |
+| |b_ModulNbr APCI1710_32BIT_COUNTER | The module is configured for one | |
+| | | 32-bit counter. | |
+| | | - b_FirstCounterModus and | |
+| | | b_FirstCounterOption | |
+| | | configure the 32 bit counter. | |
+| | | - b_SecondCounterModus and | |
+| | | b_SecondCounterOption | |
+| | | are not used and have no | |
+| | | importance. | |
+| +------------------------------------+-----------------------------------+ |
+| |
+| Counter operating mode |
+| ---------------------- |
+| |
+| +--------------------+-------------------------+-------------------------+ |
+| | Parameter | Passed value | Description | |
+| |--------------------+-------------------------+-------------------------| |
+| |b_FirstCounterModus | APCI1710_QUADRUPLE_MODE | In the quadruple mode, | |
+| | or | | the edge analysis | |
+| |b_SecondCounterModus| | circuit generates a | |
+| | | | counting pulse from | |
+| | | | each edge of 2 signals | |
+| | | | which are phase shifted | |
+| | | | in relation to each | |
+| | | | other. | |
+| |--------------------+-------------------------+-------------------------| |
+| |b_FirstCounterModus | APCI1710_DOUBLE_MODE | Functions in the same | |
+| | or | | way as the quadruple | |
+| |b_SecondCounterModus| | mode, except that only | |
+| | | | two of the four edges | |
+| | | | are analysed per | |
+| | | | period | |
+| |--------------------+-------------------------+-------------------------| |
+| |b_FirstCounterModus | APCI1710_SIMPLE_MODE | Functions in the same | |
+| | or | | way as the quadruple | |
+| |b_SecondCounterModus| | mode, except that only | |
+| | | | one of the four edges | |
+| | | | is analysed per | |
+| | | | period. | |
+| |--------------------+-------------------------+-------------------------| |
+| |b_FirstCounterModus | APCI1710_DIRECT_MODE | In the direct mode the | |
+| | or | | both edge analysis | |
+| |b_SecondCounterModus| | circuits are inactive. | |
+| | | | The inputs A, B in the | |
+| | | | 32-bit mode or A, B and | |
+| | | | C, D in the 16-bit mode | |
+| | | | represent, each, one | |
+| | | | clock pulse gate circuit| |
+| | | | There by frequency and | |
+| | | | pulse duration | |
+| | | | measurements can be | |
+| | | | performed. | |
+| +--------------------+-------------------------+-------------------------+ |
+| |
+| |
+| IMPORTANT! |
+| If you have configured the module for two 16-bit counter, a mixed |
+| mode with a counter in quadruple/double/single mode |
+| and the other counter in direct mode is not possible! |
+| |
+| |
+| Counter operating option for quadruple/double/simple mode |
+| --------------------------------------------------------- |
+| |
+| +----------------------+-------------------------+------------------------+|
+| | Parameter | Passed value | Description ||
+| |----------------------+-------------------------+------------------------||
+| |b_FirstCounterOption | APCI1710_HYSTERESIS_ON | In both edge analysis ||
+| | or | | circuits is available ||
+| |b_SecondCounterOption | | one hysteresis circuit.||
+| | | | It suppresses each ||
+| | | | time the first counting||
+| | | | pulse after a change ||
+| | | | of rotation. ||
+| |----------------------+-------------------------+------------------------||
+| |b_FirstCounterOption | APCI1710_HYSTERESIS_OFF | The first counting ||
+| | or | | pulse is not suppress ||
+| |b_SecondCounterOption | | after a change of ||
+| | | | rotation. ||
+| +----------------------+-------------------------+------------------------+|
+| |
+| |
+| IMPORTANT! |
+| This option are only avaible if you have selected the direct mode. |
+| |
+| |
+| Counter operating option for direct mode |
+| ---------------------------------------- |
+| |
+| +----------------------+--------------------+----------------------------+ |
+| | Parameter | Passed value | Description | |
+| |----------------------+--------------------+----------------------------| |
+| |b_FirstCounterOption | APCI1710_INCREMENT | The counter increment for | |
+| | or | | each counting pulse | |
+| |b_SecondCounterOption | | | |
+| |----------------------+--------------------+----------------------------| |
+| |b_FirstCounterOption | APCI1710_DECREMENT | The counter decrement for | |
+| | or | | each counting pulse | |
+| |b_SecondCounterOption | | | |
+| +----------------------+--------------------+----------------------------+ |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_CounterRange : Selection form counter |
+| range. |
+| BYTE_ b_FirstCounterModus : First counter operating |
+| mode. |
+| BYTE_ b_FirstCounterOption : First counter option. |
+| BYTE_ b_SecondCounterModus : Second counter operating |
+| mode. |
+| BYTE_ b_SecondCounterOption : Second counter option. |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module is not a counter module |
+| -3: The selected counter range is wrong. |
+| -4: The selected first counter operating mode is wrong. |
+| -5: The selected first counter operating option is wrong|
+| -6: The selected second counter operating mode is wrong.|
+| -7: The selected second counter operating option is |
+| wrong. |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitCounter(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_CounterRange,
+ BYTE b_FirstCounterModus,
+ BYTE b_FirstCounterOption,
+ BYTE b_SecondCounterModus, BYTE b_SecondCounterOption)
+{
+ INT i_ReturnValue = 0;
+
+ /*******************************/
+ /* Test if incremental counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER) {
+ /**************************/
+ /* Test the counter range */
+ /**************************/
+
+ if (b_CounterRange == APCI1710_16BIT_COUNTER
+ || b_CounterRange == APCI1710_32BIT_COUNTER) {
+ /********************************/
+ /* Test the first counter modus */
+ /********************************/
+
+ if (b_FirstCounterModus == APCI1710_QUADRUPLE_MODE ||
+ b_FirstCounterModus == APCI1710_DOUBLE_MODE ||
+ b_FirstCounterModus == APCI1710_SIMPLE_MODE ||
+ b_FirstCounterModus == APCI1710_DIRECT_MODE) {
+ /*********************************/
+ /* Test the first counter option */
+ /*********************************/
+
+ if ((b_FirstCounterModus == APCI1710_DIRECT_MODE
+ && (b_FirstCounterOption ==
+ APCI1710_INCREMENT
+ || b_FirstCounterOption
+ == APCI1710_DECREMENT))
+ || (b_FirstCounterModus !=
+ APCI1710_DIRECT_MODE
+ && (b_FirstCounterOption ==
+ APCI1710_HYSTERESIS_ON
+ || b_FirstCounterOption
+ ==
+ APCI1710_HYSTERESIS_OFF)))
+ {
+ /**************************/
+ /* Test if 16-bit counter */
+ /**************************/
+
+ if (b_CounterRange ==
+ APCI1710_16BIT_COUNTER) {
+ /*********************************/
+ /* Test the second counter modus */
+ /*********************************/
+
+ if ((b_FirstCounterModus !=
+ APCI1710_DIRECT_MODE
+ &&
+ (b_SecondCounterModus
+ ==
+ APCI1710_QUADRUPLE_MODE
+ ||
+ b_SecondCounterModus
+ ==
+ APCI1710_DOUBLE_MODE
+ ||
+ b_SecondCounterModus
+ ==
+ APCI1710_SIMPLE_MODE))
+ || (b_FirstCounterModus
+ ==
+ APCI1710_DIRECT_MODE
+ &&
+ b_SecondCounterModus
+ ==
+ APCI1710_DIRECT_MODE))
+ {
+ /**********************************/
+ /* Test the second counter option */
+ /**********************************/
+
+ if ((b_SecondCounterModus == APCI1710_DIRECT_MODE && (b_SecondCounterOption == APCI1710_INCREMENT || b_SecondCounterOption == APCI1710_DECREMENT)) || (b_SecondCounterModus != APCI1710_DIRECT_MODE && (b_SecondCounterOption == APCI1710_HYSTERESIS_ON || b_SecondCounterOption == APCI1710_HYSTERESIS_OFF))) {
+ i_ReturnValue =
+ 0;
+ } else {
+ /*********************************************************/
+ /* The selected second counter operating option is wrong */
+ /*********************************************************/
+
+ DPRINTK("The selected second counter operating option is wrong\n");
+ i_ReturnValue =
+ -7;
+ }
+ } else {
+ /*******************************************************/
+ /* The selected second counter operating mode is wrong */
+ /*******************************************************/
+
+ DPRINTK("The selected second counter operating mode is wrong\n");
+ i_ReturnValue = -6;
+ }
+ }
+ } else {
+ /********************************************************/
+ /* The selected first counter operating option is wrong */
+ /********************************************************/
+
+ DPRINTK("The selected first counter operating option is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /******************************************************/
+ /* The selected first counter operating mode is wrong */
+ /******************************************************/
+ DPRINTK("The selected first counter operating mode is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /***************************************/
+ /* The selected counter range is wrong */
+ /***************************************/
+
+ DPRINTK("The selected counter range is wrong\n");
+ i_ReturnValue = -3;
+ }
+
+ /*************************/
+ /* Test if a error occur */
+ /*************************/
+
+ if (i_ReturnValue == 0) {
+ /**************************/
+ /* Test if 16-Bit counter */
+ /**************************/
+
+ if (b_CounterRange == APCI1710_32BIT_COUNTER) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister1 = b_CounterRange |
+ b_FirstCounterModus |
+ b_FirstCounterOption;
+ } else {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister1 = b_CounterRange |
+ (b_FirstCounterModus & 0x5) |
+ (b_FirstCounterOption & 0x20) |
+ (b_SecondCounterModus & 0xA) |
+ (b_SecondCounterOption & 0x40);
+
+ /***********************/
+ /* Test if direct mode */
+ /***********************/
+
+ if (b_FirstCounterModus == APCI1710_DIRECT_MODE) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister1 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister1 |
+ APCI1710_DIRECT_MODE;
+ }
+ }
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.
+ ui_Address + 20 + (64 * b_ModulNbr));
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_CounterInit = 1;
+ }
+ } else {
+ /**************************************/
+ /* The module is not a counter module */
+ /**************************************/
+
+ DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_CounterAutoTest |
+| (BYTE_ b_BoardHandle, |
+| PBYTE_ pb_TestStatus) |
++----------------------------------------------------------------------------+
+| Task : A test mode is intended for testing the component and |
+| the connected periphery. All the 8-bit counter chains |
+| are operated internally as down counters. |
+| Independently from the external signals, |
+| all the four 8-bit counter chains are decremented in |
+| parallel by each negative clock pulse edge of CLKX. |
+| |
+| Counter auto test conclusion |
+| ---------------------------- |
+| +-----------------+-----------------------------+ |
+| | pb_TestStatus | Error description | |
+| | mask | | |
+| |-----------------+-----------------------------| |
+| | 0000 | No error detected | |
+| |-----------------|-----------------------------| |
+| | 0001 | Error detected of counter 0 | |
+| |-----------------|-----------------------------| |
+| | 0010 | Error detected of counter 1 | |
+| |-----------------|-----------------------------| |
+| | 0100 | Error detected of counter 2 | |
+| |-----------------|-----------------------------| |
+| | 1000 | Error detected of counter 3 | |
+| +-----------------+-----------------------------+ |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 | |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TestStatus : Auto test conclusion. See table|
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_CounterAutoTest(struct comedi_device * dev, PBYTE pb_TestStatus)
+{
+ BYTE b_ModulCpt = 0;
+ INT i_ReturnValue = 0;
+ DWORD dw_LathchValue;
+
+ *pb_TestStatus = 0;
+
+ /********************************/
+ /* Test if counter module found */
+ /********************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[0] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER
+ || (devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[1] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER
+ || (devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[2] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER
+ || (devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[3] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER) {
+ for (b_ModulCpt = 0; b_ModulCpt < 4; b_ModulCpt++) {
+ /*******************************/
+ /* Test if incremental counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulCpt] &
+ 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER) {
+ /******************/
+ /* Start the test */
+ /******************/
+
+ outl(3, devpriv->s_BoardInfos.
+ ui_Address + 16 + (64 * b_ModulCpt));
+
+ /*********************/
+ /* Tatch the counter */
+ /*********************/
+
+ outl(1, devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulCpt));
+
+ /************************/
+ /* Read the latch value */
+ /************************/
+
+ dw_LathchValue = inl(devpriv->s_BoardInfos.
+ ui_Address + 4 + (64 * b_ModulCpt));
+
+ if ((dw_LathchValue & 0xFF) !=
+ ((dw_LathchValue >> 8) & 0xFF)
+ && (dw_LathchValue & 0xFF) !=
+ ((dw_LathchValue >> 16) & 0xFF)
+ && (dw_LathchValue & 0xFF) !=
+ ((dw_LathchValue >> 24) & 0xFF)) {
+ *pb_TestStatus =
+ *pb_TestStatus | (1 <<
+ b_ModulCpt);
+ }
+
+ /*****************/
+ /* Stop the test */
+ /*****************/
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 16 + (64 * b_ModulCpt));
+ }
+ }
+ } else {
+ /***************************/
+ /* No counter module found */
+ /***************************/
+
+ DPRINTK("No counter module found\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitIndex (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_ReferenceAction, |
+| BYTE_ b_IndexOperation, |
+| BYTE_ b_AutoMode, |
+| BYTE_ b_InterruptEnable) |
++----------------------------------------------------------------------------+
+| Task : Initialise the index corresponding to the selected |
+| module (b_ModulNbr). If a INDEX flag occur, you have |
+| the possibility to clear the 32-Bit counter or to latch|
+| the current 32-Bit value in to the first latch |
+| register. The b_IndexOperation parameter give the |
+| possibility to choice the INDEX action. |
+| If you have enabled the automatic mode, each INDEX |
+| action is cleared automatically, else you must read |
+| the index status ("i_APCI1710_ReadIndexStatus") |
+| after each INDEX action. |
+| |
+| |
+| Index action |
+| ------------ |
+| |
+| +------------------------+------------------------------------+ |
+| | b_IndexOperation | Operation | |
+| |------------------------+------------------------------------| |
+| |APCI1710_LATCH_COUNTER | After a index signal, the counter | |
+| | | value (32-Bit) is latched in to | |
+| | | the first latch register | |
+| |------------------------|------------------------------------| |
+| |APCI1710_CLEAR_COUNTER | After a index signal, the counter | |
+| | | value is cleared (32-Bit) | |
+| +------------------------+------------------------------------+ |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_ReferenceAction : Determine if the reference |
+| must set or no for the |
+| acceptance from index |
+| APCI1710_ENABLE : |
+| Reference must be set for |
+| accepted the index |
+| APCI1710_DISABLE : |
+| Reference have not |
+| importance |
+| BYTE_ b_IndexOperation : Index operating mode. |
+| See table. |
+| BYTE_ b_AutoMode : Enable or disable the |
+| automatic index reset. |
+| APCI1710_ENABLE : |
+| Enable the automatic mode |
+| APCI1710_DISABLE : |
+| Disable the automatic mode |
+| BYTE_ b_InterruptEnable : Enable or disable the |
+| interrupt. |
+| APCI1710_ENABLE : |
+| Enable the interrupt |
+| APCI1710_DISABLE : |
+| Disable the interrupt |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4 The reference action parameter is wrong |
+| -5: The index operating mode parameter is wrong |
+| -6: The auto mode parameter is wrong |
+| -7: Interrupt parameter is wrong |
+| -8: Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitIndex(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_ReferenceAction,
+ BYTE b_IndexOperation, BYTE b_AutoMode, BYTE b_InterruptEnable)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /********************************/
+ /* Test the reference parameter */
+ /********************************/
+
+ if (b_ReferenceAction == APCI1710_ENABLE ||
+ b_ReferenceAction == APCI1710_DISABLE) {
+ /****************************/
+ /* Test the index parameter */
+ /****************************/
+
+ if (b_IndexOperation ==
+ APCI1710_HIGH_EDGE_LATCH_COUNTER
+ || b_IndexOperation ==
+ APCI1710_LOW_EDGE_LATCH_COUNTER
+ || b_IndexOperation ==
+ APCI1710_HIGH_EDGE_CLEAR_COUNTER
+ || b_IndexOperation ==
+ APCI1710_LOW_EDGE_CLEAR_COUNTER
+ || b_IndexOperation ==
+ APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER
+ || b_IndexOperation ==
+ APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+ {
+ /********************************/
+ /* Test the auto mode parameter */
+ /********************************/
+
+ if (b_AutoMode == APCI1710_ENABLE ||
+ b_AutoMode == APCI1710_DISABLE)
+ {
+ /***************************/
+ /* Test the interrupt mode */
+ /***************************/
+
+ if (b_InterruptEnable ==
+ APCI1710_ENABLE
+ || b_InterruptEnable ==
+ APCI1710_DISABLE) {
+
+ /************************************/
+ /* Makte the configuration commando */
+ /************************************/
+
+ if (b_ReferenceAction ==
+ APCI1710_ENABLE)
+ {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ |
+ APCI1710_ENABLE_INDEX_ACTION;
+ } else {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ &
+ APCI1710_DISABLE_INDEX_ACTION;
+ }
+
+ /****************************************/
+ /* Test if low level latch or/and clear */
+ /****************************************/
+
+ if (b_IndexOperation ==
+ APCI1710_LOW_EDGE_LATCH_COUNTER
+ ||
+ b_IndexOperation
+ ==
+ APCI1710_LOW_EDGE_CLEAR_COUNTER
+ ||
+ b_IndexOperation
+ ==
+ APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+ {
+ /*************************************/
+ /* Set the index level to low (DQ26) */
+ /*************************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ |
+ APCI1710_SET_LOW_INDEX_LEVEL;
+ } else {
+ /**************************************/
+ /* Set the index level to high (DQ26) */
+ /**************************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ &
+ APCI1710_SET_HIGH_INDEX_LEVEL;
+ }
+
+ /***********************************/
+ /* Test if latch and clear counter */
+ /***********************************/
+
+ if (b_IndexOperation ==
+ APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER
+ ||
+ b_IndexOperation
+ ==
+ APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+ {
+ /***************************************/
+ /* Set the latch and clear flag (DQ27) */
+ /***************************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ |
+ APCI1710_ENABLE_LATCH_AND_CLEAR;
+ } // if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER || b_IndexOperation == APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+ else {
+ /*****************************************/
+ /* Clear the latch and clear flag (DQ27) */
+ /*****************************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ &
+ APCI1710_DISABLE_LATCH_AND_CLEAR;
+
+ /*************************/
+ /* Test if latch counter */
+ /*************************/
+
+ if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_COUNTER || b_IndexOperation == APCI1710_LOW_EDGE_LATCH_COUNTER) {
+ /*********************************/
+ /* Enable the latch from counter */
+ /*********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ |
+ APCI1710_INDEX_LATCH_COUNTER;
+ } else {
+ /*********************************/
+ /* Enable the clear from counter */
+ /*********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ &
+ (~APCI1710_INDEX_LATCH_COUNTER);
+ }
+ } // // if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER || b_IndexOperation == APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+
+ if (b_AutoMode ==
+ APCI1710_DISABLE)
+ {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ |
+ APCI1710_INDEX_AUTO_MODE;
+ } else {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ &
+ (~APCI1710_INDEX_AUTO_MODE);
+ }
+
+ if (b_InterruptEnable ==
+ APCI1710_ENABLE)
+ {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3
+ |
+ APCI1710_ENABLE_INDEX_INT;
+ } else {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3
+ &
+ APCI1710_DISABLE_INDEX_INT;
+ }
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.
+ b_IndexInit = 1;
+
+ } else {
+ /********************************/
+ /* Interrupt parameter is wrong */
+ /********************************/
+ DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue = -7;
+ }
+ } else {
+ /************************************/
+ /* The auto mode parameter is wrong */
+ /************************************/
+
+ DPRINTK("The auto mode parameter is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /***********************************************/
+ /* The index operating mode parameter is wrong */
+ /***********************************************/
+
+ DPRINTK("The index operating mode parameter is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /*******************************************/
+ /* The reference action parameter is wrong */
+ /*******************************************/
+
+ DPRINTK("The reference action parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitReference |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_ReferenceLevel) |
++----------------------------------------------------------------------------+
+| Task : Initialise the reference corresponding to the selected |
+| module (b_ModulNbr). |
+| |
+| Reference level |
+| --------------- |
+| +--------------------+-------------------------+ |
+| | b_ReferenceLevel | Operation | |
+| +--------------------+-------------------------+ |
+| | APCI1710_LOW | Reference occur if "0" | |
+| |--------------------|-------------------------| |
+| | APCI1710_HIGH | Reference occur if "1" | |
+| +--------------------+-------------------------+ |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_ReferenceLevel : Reference level. |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number parameter is wrong |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Reference level parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitReference(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_ReferenceLevel)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /**************************************/
+ /* Test the reference level parameter */
+ /**************************************/
+
+ if (b_ReferenceLevel == 0 || b_ReferenceLevel == 1) {
+ if (b_ReferenceLevel == 1) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 |
+ APCI1710_REFERENCE_HIGH;
+ } else {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 &
+ APCI1710_REFERENCE_LOW;
+ }
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_ReferenceInit = 1;
+ } else {
+ /**************************************/
+ /* Reference level parameter is wrong */
+ /**************************************/
+
+ DPRINTK("Reference level parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitExternalStrobe |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_ExternalStrobe, |
+| BYTE_ b_ExternalStrobeLevel) |
++----------------------------------------------------------------------------+
+| Task : Initialises the external strobe level corresponding to |
+| the selected module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_ExternalStrobe : External strobe selection |
+| 0 : External strobe A |
+| 1 : External strobe B |
+| BYTE_ b_ExternalStrobeLevel : External strobe level |
+| APCI1710_LOW : |
+| External latch occurs if "0" |
+| APCI1710_HIGH : |
+| External latch occurs if "1" |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number is wrong |
+| -3: Counter not initialised. |
+| See function "i_APCI1710_InitCounter" |
+| -4: External strobe selection is wrong |
+| -5: External strobe level parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitExternalStrobe(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_ExternalStrobe, BYTE b_ExternalStrobeLevel)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /**************************************/
+ /* Test the external strobe selection */
+ /**************************************/
+
+ if (b_ExternalStrobe == 0 || b_ExternalStrobe == 1) {
+ /******************/
+ /* Test the level */
+ /******************/
+
+ if ((b_ExternalStrobeLevel == APCI1710_HIGH) ||
+ ((b_ExternalStrobeLevel == APCI1710_LOW
+ && (devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) >=
+ 0x3135))) {
+ /*****************/
+ /* Set the level */
+ /*****************/
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4 = (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4 & (0xFF -
+ (0x10 << b_ExternalStrobe))) | ((b_ExternalStrobeLevel ^ 1) << (4 + b_ExternalStrobe));
+ } else {
+ /********************************************/
+ /* External strobe level parameter is wrong */
+ /********************************************/
+
+ DPRINTK("External strobe level parameter is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } // if (b_ExternalStrobe == 0 || b_ExternalStrobe == 1)
+ else {
+ /**************************************/
+ /* External strobe selection is wrong */
+ /**************************************/
+
+ DPRINTK("External strobe selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_ExternalStrobe == 0 || b_ExternalStrobe == 1)
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : _INT_ i_APCI1710_InitCompareLogic |
+ | (BYTE_ b_BoardHandle, |
+ | BYTE_ b_ModulNbr, |
+ | UINT_ ui_CompareValue) |
+ +----------------------------------------------------------------------------+
+ | Task : Set the 32-Bit compare value. At that moment that the |
+ | incremental counter arrive to the compare value |
+ | (ui_CompareValue) a interrupt is generated. |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+ | BYTE_ b_ModulNbr : Module number to configure |
+ | (0 to 3) |
+ | UINT_ ui_CompareValue : 32-Bit compare value |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -
+ +----------------------------------------------------------------------------+
+ | Return Value : 0: No error |
+ | -1: The handle parameter of the board is wrong |
+ | -2: No counter module found |
+ | -3: Counter not initialised see function |
+ | "i_APCI1710_InitCounter" |
+ +----------------------------------------------------------------------------+
+ */
+
+INT i_APCI1710_InitCompareLogic(struct comedi_device * dev,
+ BYTE b_ModulNbr, UINT ui_CompareValue)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+
+ outl(ui_CompareValue, devpriv->s_BoardInfos.
+ ui_Address + 28 + (64 * b_ModulNbr));
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_CompareLogicInit = 1;
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitFrequencyMeasurement |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PCIInputClock, |
+| BYTE_ b_TimingUnity, |
+| ULONG_ ul_TimingInterval, |
+| PULONG_ pul_RealTimingInterval) |
++----------------------------------------------------------------------------+
+| Task : Sets the time for the frequency measurement. |
+| Configures the selected TOR incremental counter of the |
+| selected module (b_ModulNbr). The ul_TimingInterval and|
+| ul_TimingUnity determine the time base for the |
+| measurement. The pul_RealTimingInterval returns the |
+| real time value. You must call up this function before |
+| you call up any other function which gives access to |
+| the frequency measurement. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Number of the module to be |
+| configured (0 to 3) |
+| BYTE_ b_PCIInputClock : Selection of the PCI bus |
+| clock |
+| - APCI1710_30MHZ : |
+| The PC has a PCI bus clock |
+| of 30 MHz |
+| - APCI1710_33MHZ : |
+| The PC has a PCI bus clock |
+| of 33 MHz |
+| BYTE_ b_TimingUnity : Base time unit (0 to 2) |
+| 0 : ns |
+| 1 : æs |
+| 2 : ms |
+| ULONG_ ul_TimingInterval: Base time value. |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_RealTimingInterval : Real base time value. |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number is wrong |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: The selected PCI input clock is wrong |
+| -5: Timing unity selection is wrong |
+| -6: Base timing selection is wrong |
+| -7: 40MHz quartz not on board |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitFrequencyMeasurement(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_PCIInputClock,
+ BYTE b_TimingUnity,
+ ULONG ul_TimingInterval, PULONG pul_RealTimingInterval)
+{
+ INT i_ReturnValue = 0;
+ ULONG ul_TimerValue = 0;
+ double d_RealTimingInterval;
+ DWORD dw_Status = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /**************************/
+ /* Test the PCI bus clock */
+ /**************************/
+
+ if ((b_PCIInputClock == APCI1710_30MHZ) ||
+ (b_PCIInputClock == APCI1710_33MHZ) ||
+ (b_PCIInputClock == APCI1710_40MHZ)) {
+ /************************/
+ /* Test the timing unit */
+ /************************/
+
+ if (b_TimingUnity <= 2) {
+ /**********************************/
+ /* Test the base timing selection */
+ /**********************************/
+
+ if (((b_PCIInputClock == APCI1710_30MHZ)
+ && (b_TimingUnity == 0)
+ && (ul_TimingInterval >=
+ 266)
+ && (ul_TimingInterval <=
+ 8738133UL))
+ || ((b_PCIInputClock ==
+ APCI1710_30MHZ)
+ && (b_TimingUnity == 1)
+ && (ul_TimingInterval >=
+ 1)
+ && (ul_TimingInterval <=
+ 8738UL))
+ || ((b_PCIInputClock ==
+ APCI1710_30MHZ)
+ && (b_TimingUnity == 2)
+ && (ul_TimingInterval >=
+ 1)
+ && (ul_TimingInterval <=
+ 8UL))
+ || ((b_PCIInputClock ==
+ APCI1710_33MHZ)
+ && (b_TimingUnity == 0)
+ && (ul_TimingInterval >=
+ 242)
+ && (ul_TimingInterval <=
+ 7943757UL))
+ || ((b_PCIInputClock ==
+ APCI1710_33MHZ)
+ && (b_TimingUnity == 1)
+ && (ul_TimingInterval >=
+ 1)
+ && (ul_TimingInterval <=
+ 7943UL))
+ || ((b_PCIInputClock ==
+ APCI1710_33MHZ)
+ && (b_TimingUnity == 2)
+ && (ul_TimingInterval >=
+ 1)
+ && (ul_TimingInterval <=
+ 7UL))
+ || ((b_PCIInputClock ==
+ APCI1710_40MHZ)
+ && (b_TimingUnity == 0)
+ && (ul_TimingInterval >=
+ 200)
+ && (ul_TimingInterval <=
+ 6553500UL))
+ || ((b_PCIInputClock ==
+ APCI1710_40MHZ)
+ && (b_TimingUnity == 1)
+ && (ul_TimingInterval >=
+ 1)
+ && (ul_TimingInterval <=
+ 6553UL))
+ || ((b_PCIInputClock ==
+ APCI1710_40MHZ)
+ && (b_TimingUnity == 2)
+ && (ul_TimingInterval >=
+ 1)
+ && (ul_TimingInterval <=
+ 6UL))) {
+ /**********************/
+ /* Test if 40MHz used */
+ /**********************/
+
+ if (b_PCIInputClock ==
+ APCI1710_40MHZ) {
+ /******************************/
+ /* Test if firmware >= Rev1.5 */
+ /******************************/
+
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3135) {
+ /*********************************/
+ /* Test if 40MHz quartz on board */
+ /*********************************/
+
+ /*INPDW (ps_APCI1710Variable->
+ s_Board [b_BoardHandle].
+ s_BoardInfos.
+ ui_Address + 36 + (64 * b_ModulNbr), &dw_Status); */
+ dw_Status =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 36 +
+ (64 * b_ModulNbr));
+
+ /******************************/
+ /* Test the quartz flag (DQ0) */
+ /******************************/
+
+ if ((dw_Status & 1) != 1) {
+ /*****************************/
+ /* 40MHz quartz not on board */
+ /*****************************/
+
+ DPRINTK("40MHz quartz not on board\n");
+ i_ReturnValue
+ =
+ -7;
+ }
+ } else {
+ /*****************************/
+ /* 40MHz quartz not on board */
+ /*****************************/
+ DPRINTK("40MHz quartz not on board\n");
+ i_ReturnValue =
+ -7;
+ }
+ } // if (b_PCIInputClock == APCI1710_40MHZ)
+
+ /***************************/
+ /* Test if not error occur */
+ /***************************/
+
+ if (i_ReturnValue == 0) {
+ /****************************/
+ /* Test the INC_CPT version */
+ /****************************/
+
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131) {
+
+ /**********************/
+ /* Test if 40MHz used */
+ /**********************/
+
+ if (b_PCIInputClock == APCI1710_40MHZ) {
+ /*********************************/
+ /* Enable the 40MHz quarz (DQ30) */
+ /*********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ |
+ APCI1710_ENABLE_40MHZ_FREQUENCY;
+ } // if (b_PCIInputClock == APCI1710_40MHZ)
+ else {
+ /**********************************/
+ /* Disable the 40MHz quarz (DQ30) */
+ /**********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ &
+ APCI1710_DISABLE_40MHZ_FREQUENCY;
+
+ } // if (b_PCIInputClock == APCI1710_40MHZ)
+
+ /********************************/
+ /* Calculate the division fator */
+ /********************************/
+
+ fpu_begin();
+ switch (b_TimingUnity) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (0.00025 * b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (0.00025 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (0.00025 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (0.00025
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (0.00025 * (double)b_PCIInputClock)) >= (double)((double)*pul_RealTimingInterval + 0.5)) {
+ *pul_RealTimingInterval
+ =
+ *pul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (0.25 * b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (0.25 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (0.25 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (
+ (double)
+ 0.25
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (0.25 * (double)b_PCIInputClock)) >= (double)((double)*pul_RealTimingInterval + 0.5)) {
+ *pul_RealTimingInterval
+ =
+ *pul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ ul_TimingInterval
+ *
+ (250.0
+ *
+ b_PCIInputClock);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (250.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (250.0 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (250.0
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (250.0 * (double)b_PCIInputClock)) >= (double)((double)*pul_RealTimingInterval + 0.5)) {
+ *pul_RealTimingInterval
+ =
+ *pul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ break;
+ }
+
+ fpu_end();
+ /*************************/
+ /* Write the timer value */
+ /*************************/
+
+ outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + 32 + (64 * b_ModulNbr));
+
+ /*******************************/
+ /* Set the initialisation flag */
+ /*******************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.
+ b_FrequencyMeasurementInit
+ = 1;
+ } else {
+ /***************************/
+ /* Counter not initialised */
+ /***************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue =
+ -3;
+ }
+ } // if (i_ReturnValue == 0)
+ } else {
+ /**********************************/
+ /* Base timing selection is wrong */
+ /**********************************/
+
+ DPRINTK("Base timing selection is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /***********************************/
+ /* Timing unity selection is wrong */
+ /***********************************/
+
+ DPRINTK("Timing unity selection is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /*****************************************/
+ /* The selected PCI input clock is wrong */
+ /*****************************************/
+
+ DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*########################################################################### */
+
+ //INSN BITS
+/*########################################################################### */
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Set & Clear Functions for INC_CPT |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsINCCPT(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_BitsType;
+ INT i_ReturnValue = 0;
+ ui_BitsType = CR_CHAN(insn->chanspec);
+ devpriv->tsk_Current = current; // Save the current process task structure
+
+ switch (ui_BitsType) {
+ case APCI1710_INCCPT_CLEARCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_ClearCounterValue(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_CLEARALLCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_ClearAllCounterValue(dev);
+ break;
+
+ case APCI1710_INCCPT_SETINPUTFILTER:
+ i_ReturnValue = i_APCI1710_SetInputFilter(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) data[0], (BYTE) data[1]);
+ break;
+
+ case APCI1710_INCCPT_LATCHCOUNTER:
+ i_ReturnValue = i_APCI1710_LatchCounter(dev,
+ (BYTE) CR_AREF(insn->chanspec), (BYTE) data[0]);
+ break;
+
+ case APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE:
+ i_ReturnValue = i_APCI1710_SetIndexAndReferenceSource(dev,
+ (BYTE) CR_AREF(insn->chanspec), (BYTE) data[0]);
+ break;
+
+ case APCI1710_INCCPT_SETDIGITALCHLON:
+ i_ReturnValue = i_APCI1710_SetDigitalChlOn(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_SETDIGITALCHLOFF:
+ i_ReturnValue = i_APCI1710_SetDigitalChlOff(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ default:
+ printk("Bits Config Parameter Wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ClearCounterValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Clear the counter value from selected module |
+| (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number parameter is wrong |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ClearCounterValue(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*********************/
+ /* Clear the counter */
+ /*********************/
+
+ outl(1, devpriv->s_BoardInfos.
+ ui_Address + 16 + (64 * b_ModulNbr));
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ClearAllCounterValue |
+| (BYTE_ b_BoardHandle) |
++----------------------------------------------------------------------------+
+| Task : Clear all counter value. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ClearAllCounterValue(struct comedi_device * dev)
+{
+ BYTE b_ModulCpt = 0;
+ INT i_ReturnValue = 0;
+
+ /********************************/
+ /* Test if counter module found */
+ /********************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[0] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER
+ || (devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[1] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER
+ || (devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[2] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER
+ || (devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[3] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER) {
+ for (b_ModulCpt = 0; b_ModulCpt < 4; b_ModulCpt++) {
+ /*******************************/
+ /* Test if incremental counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulCpt] &
+ 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER) {
+ /*********************/
+ /* Clear the counter */
+ /*********************/
+
+ outl(1, devpriv->s_BoardInfos.
+ ui_Address + 16 + (64 * b_ModulCpt));
+ }
+ }
+ } else {
+ /***************************/
+ /* No counter module found */
+ /***************************/
+
+ DPRINTK("No counter module found\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetInputFilter |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_Module, |
+| BYTE_ b_PCIInputClock, |
+| BYTE_ b_Filter) |
++----------------------------------------------------------------------------+
+| Task : Disable or enable the software filter from selected |
+| module (b_ModulNbr). b_Filter determine the filter time|
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Number of the module to be |
+| configured (0 to 3) |
+| BYTE_ b_PCIInputClock : Selection of the PCI bus |
+| clock |
+| - APCI1710_30MHZ : |
+| The PC has a PCI bus clock |
+| of 30 MHz |
+| - APCI1710_33MHZ : |
+| The PC has a PCI bus clock |
+| of 33 MHz |
+| - APCI1710_40MHZ : |
+| The APCI1710 has a 40MHz |
+| quartz |
+| BYTE_ b_Filter : Filter selection |
+| |
+| 30 MHz |
+| ------ |
+| 0: Software filter not used |
+| 1: Filter from 266ns (3.750000MHz) |
+| 2: Filter from 400ns (2.500000MHz) |
+| 3: Filter from 533ns (1.876170MHz) |
+| 4: Filter from 666ns (1.501501MHz) |
+| 5: Filter from 800ns (1.250000MHz) |
+| 6: Filter from 933ns (1.071800MHz) |
+| 7: Filter from 1066ns (0.938080MHz) |
+| 8: Filter from 1200ns (0.833333MHz) |
+| 9: Filter from 1333ns (0.750000MHz) |
+| 10: Filter from 1466ns (0.682100MHz) |
+| 11: Filter from 1600ns (0.625000MHz) |
+| 12: Filter from 1733ns (0.577777MHz) |
+| 13: Filter from 1866ns (0.535900MHz) |
+| 14: Filter from 2000ns (0.500000MHz) |
+| 15: Filter from 2133ns (0.468800MHz) |
+| |
+| 33 MHz |
+| ------ |
+| 0: Software filter not used |
+| 1: Filter from 242ns (4.125000MHz) |
+| 2: Filter from 363ns (2.754820MHz) |
+| 3: Filter from 484ns (2.066115MHz) |
+| 4: Filter from 605ns (1.652892MHz) |
+| 5: Filter from 726ns (1.357741MHz) |
+| 6: Filter from 847ns (1.180637MHz) |
+| 7: Filter from 968ns (1.033055MHz) |
+| 8: Filter from 1089ns (0.918273MHz) |
+| 9: Filter from 1210ns (0.826446MHz) |
+| 10: Filter from 1331ns (0.751314MHz) |
+| 11: Filter from 1452ns (0.688705MHz) |
+| 12: Filter from 1573ns (0.635727MHz) |
+| 13: Filter from 1694ns (0.590318MHz) |
+| 14: Filter from 1815ns (0.550964MHz) |
+| 15: Filter from 1936ns (0.516528MHz) |
+| |
+| 40 MHz |
+| ------ |
+| 0: Software filter not used |
+| 1: Filter from 200ns (5.000000MHz) |
+| 2: Filter from 300ns (3.333333MHz) |
+| 3: Filter from 400ns (2.500000MHz) |
+| 4: Filter from 500ns (2.000000MHz) |
+| 5: Filter from 600ns (1.666666MHz) |
+| 6: Filter from 700ns (1.428500MHz) |
+| 7: Filter from 800ns (1.250000MHz) |
+| 8: Filter from 900ns (1.111111MHz) |
+| 9: Filter from 1000ns (1.000000MHz) |
+| 10: Filter from 1100ns (0.909090MHz) |
+| 11: Filter from 1200ns (0.833333MHz) |
+| 12: Filter from 1300ns (0.769200MHz) |
+| 13: Filter from 1400ns (0.714200MHz) |
+| 14: Filter from 1500ns (0.666666MHz) |
+| 15: Filter from 1600ns (0.625000MHz) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number is wrong |
+| -3: The module is not a counter module |
+| -4: The selected PCI input clock is wrong |
+| -5: The selected filter value is wrong |
+| -6: 40MHz quartz not on board |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetInputFilter(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_PCIInputClock, BYTE b_Filter)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if incremental counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER) {
+ /******************************/
+ /* Test if firmware >= Rev1.5 */
+ /******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF) >= 0x3135) {
+ /**************************/
+ /* Test the PCI bus clock */
+ /**************************/
+
+ if ((b_PCIInputClock == APCI1710_30MHZ) ||
+ (b_PCIInputClock == APCI1710_33MHZ) ||
+ (b_PCIInputClock == APCI1710_40MHZ)) {
+ /*************************/
+ /* Test the filter value */
+ /*************************/
+
+ if (b_Filter < 16) {
+ /**********************/
+ /* Test if 40MHz used */
+ /**********************/
+
+ if (b_PCIInputClock ==
+ APCI1710_40MHZ) {
+ /*********************************/
+ /* Test if 40MHz quartz on board */
+ /*********************************/
+
+ dw_Status =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 36 +
+ (64 * b_ModulNbr));
+
+ /******************************/
+ /* Test the quartz flag (DQ0) */
+ /******************************/
+
+ if ((dw_Status & 1) !=
+ 1) {
+ /*****************************/
+ /* 40MHz quartz not on board */
+ /*****************************/
+
+ DPRINTK("40MHz quartz not on board\n");
+ i_ReturnValue =
+ -6;
+ }
+ } // if (b_PCIInputClock == APCI1710_40MHZ)
+
+ /***************************/
+ /* Test if error not occur */
+ /***************************/
+
+ if (i_ReturnValue == 0) {
+ /**********************/
+ /* Test if 40MHz used */
+ /**********************/
+
+ if (b_PCIInputClock ==
+ APCI1710_40MHZ)
+ {
+ /*********************************/
+ /* Enable the 40MHz quarz (DQ31) */
+ /*********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ |
+ APCI1710_ENABLE_40MHZ_FILTER;
+
+ } // if (b_PCIInputClock == APCI1710_40MHZ)
+ else {
+ /**********************************/
+ /* Disable the 40MHz quarz (DQ31) */
+ /**********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ &
+ APCI1710_DISABLE_40MHZ_FILTER;
+
+ } // if (b_PCIInputClock == APCI1710_40MHZ)
+
+ /************************/
+ /* Set the filter value */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3
+ =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3
+ & 0x1F) |
+ ((b_Filter &
+ 0x7) <<
+ 5);
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ & 0xFE) |
+ ((b_Filter &
+ 0x8) >>
+ 3);
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 20 +
+ (64 * b_ModulNbr));
+ } // if (i_ReturnValue == 0)
+ } // if (b_Filter < 16)
+ else {
+ /**************************************/
+ /* The selected filter value is wrong */
+ /**************************************/
+
+ DPRINTK("The selected filter value is wrong\n");
+ i_ReturnValue = -5;
+ } // if (b_Filter < 16)
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ) || (b_PCIInputClock == APCI1710_40MHZ))
+ else {
+ /*****************************************/
+ /* The selected PCI input clock is wrong */
+ /*****************************************/
+
+ DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue = 4;
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ) || (b_PCIInputClock == APCI1710_40MHZ))
+ } else {
+ /**************************************/
+ /* The module is not a counter module */
+ /**************************************/
+
+ DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /**************************************/
+ /* The module is not a counter module */
+ /**************************************/
+
+ DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_LatchCounter (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_LatchReg) |
++----------------------------------------------------------------------------+
+| Task : Latch the courant value from selected module |
+| (b_ModulNbr) in to the selected latch register |
+| (b_LatchReg). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_LatchReg : Selected latch register |
+| 0 : for the first latch register |
+| 1 : for the second latch register |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: The selected latch register parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_LatchCounter(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_LatchReg)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*************************************/
+ /* Test the latch register parameter */
+ /*************************************/
+
+ if (b_LatchReg < 2) {
+ /*********************/
+ /* Tatch the counter */
+ /*********************/
+
+ outl(1 << (b_LatchReg * 4),
+ devpriv->s_BoardInfos.ui_Address +
+ (64 * b_ModulNbr));
+ } else {
+ /**************************************************/
+ /* The selected latch register parameter is wrong */
+ /**************************************************/
+
+ DPRINTK("The selected latch register parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetIndexAndReferenceSource |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_SourceSelection) |
++----------------------------------------------------------------------------+
+| Task : Determine the hardware source for the index and the |
+| reference logic. Per default the index logic is |
+| connected to the difference input C and the reference |
+| logic is connected to the 24V input E |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_SourceSelection : APCI1710_SOURCE_0 : |
+| The index logic is connected |
+| to the difference input C and|
+| the reference logic is |
+| connected to the 24V input E.|
+| This is the default |
+| configuration. |
+| APCI1710_SOURCE_1 : |
+| The reference logic is |
+| connected to the difference |
+| input C and the index logic |
+| is connected to the 24V |
+| input E |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number is wrong |
+| -3: The module is not a counter module. |
+| -4: The source selection is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetIndexAndReferenceSource(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_SourceSelection)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if incremental counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER) {
+ /******************************/
+ /* Test if firmware >= Rev1.5 */
+ /******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF) >= 0x3135) {
+ /*****************************/
+ /* Test the source selection */
+ /*****************************/
+
+ if (b_SourceSelection == APCI1710_SOURCE_0 ||
+ b_SourceSelection == APCI1710_SOURCE_1)
+ {
+ /******************************************/
+ /* Test if invert the index and reference */
+ /******************************************/
+
+ if (b_SourceSelection ==
+ APCI1710_SOURCE_1) {
+ /********************************************/
+ /* Invert index and reference source (DQ25) */
+ /********************************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4 =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4 |
+ APCI1710_INVERT_INDEX_RFERENCE;
+ } else {
+ /****************************************/
+ /* Set the default configuration (DQ25) */
+ /****************************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4 =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4 &
+ APCI1710_DEFAULT_INDEX_RFERENCE;
+ }
+ } // if (b_SourceSelection == APCI1710_SOURCE_0 ||b_SourceSelection == APCI1710_SOURCE_1)
+ else {
+ /*********************************/
+ /* The source selection is wrong */
+ /*********************************/
+
+ DPRINTK("The source selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_SourceSelection == APCI1710_SOURCE_0 ||b_SourceSelection == APCI1710_SOURCE_1)
+ } else {
+ /**************************************/
+ /* The module is not a counter module */
+ /**************************************/
+
+ DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /**************************************/
+ /* The module is not a counter module */
+ /**************************************/
+
+ DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***************************************/
+ /* The selected module number is wrong */
+ /***************************************/
+
+ DPRINTK("The selected module number is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetDigitalChlOn |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Sets the digital output H Setting an output means |
+| setting an ouput high. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Number of the module to be |
+| configured (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number is wrong |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetDigitalChlOn(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.b_ModeRegister3 | 0x10;
+
+ /*********************/
+ /* Set the output On */
+ /*********************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4, devpriv->s_BoardInfos.
+ ui_Address + 20 + (64 * b_ModulNbr));
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetDigitalChlOff |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Resets the digital output H. Resetting an output means |
+| setting an ouput low. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Number of the module to be |
+| configured (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number is wrong |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetDigitalChlOff(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.b_ModeRegister3 & 0xEF;
+
+ /**********************/
+ /* Set the output Off */
+ /**********************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4, devpriv->s_BoardInfos.
+ ui_Address + 20 + (64 * b_ModulNbr));
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*########################################################################### */
+
+ // INSN WRITE
+/*########################################################################### */
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Enable Disable functions for INC_CPT |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1710_InsnWriteINCCPT(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_WriteType;
+ INT i_ReturnValue = 0;
+
+ ui_WriteType = CR_CHAN(insn->chanspec);
+ devpriv->tsk_Current = current; // Save the current process task structure
+
+ switch (ui_WriteType) {
+ case APCI1710_INCCPT_ENABLELATCHINTERRUPT:
+ i_ReturnValue = i_APCI1710_EnableLatchInterrupt(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_DISABLELATCHINTERRUPT:
+ i_ReturnValue = i_APCI1710_DisableLatchInterrupt(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_WRITE16BITCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_Write16BitCounterValue(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) data[0], (UINT) data[1]);
+ break;
+
+ case APCI1710_INCCPT_WRITE32BITCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_Write32BitCounterValue(dev,
+ (BYTE) CR_AREF(insn->chanspec), (ULONG) data[0]);
+
+ break;
+
+ case APCI1710_INCCPT_ENABLEINDEX:
+ i_APCI1710_EnableIndex(dev, (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_DISABLEINDEX:
+ i_ReturnValue = i_APCI1710_DisableIndex(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_ENABLECOMPARELOGIC:
+ i_ReturnValue = i_APCI1710_EnableCompareLogic(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_DISABLECOMPARELOGIC:
+ i_ReturnValue = i_APCI1710_DisableCompareLogic(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT:
+ i_ReturnValue = i_APCI1710_EnableFrequencyMeasurement(dev,
+ (BYTE) CR_AREF(insn->chanspec), (BYTE) data[0]);
+ break;
+
+ case APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT:
+ i_ReturnValue = i_APCI1710_DisableFrequencyMeasurement(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ default:
+ printk("Write Config Parameter Wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnableLatchInterrupt |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Enable the latch interrupt from selected module |
+| (b_ModulNbr). Each software or hardware latch occur a |
+| interrupt. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Interrupt routine not installed see function |
+| "i_APCI1710_SetBoardIntRoutine" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_EnableLatchInterrupt(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+
+ /********************/
+ /* Enable interrupt */
+ /********************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 | APCI1710_ENABLE_LATCH_INT;
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4, devpriv->s_BoardInfos.
+ ui_Address + 20 + (64 * b_ModulNbr));
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_DisableLatchInterrupt |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Disable the latch interrupt from selected module |
+| (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Interrupt routine not installed see function |
+| "i_APCI1710_SetBoardIntRoutine" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_DisableLatchInterrupt(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4 &
+ ((APCI1710_DISABLE_LATCH_INT << 8) | 0xFF),
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+
+ mdelay(1000);
+
+ /*********************/
+ /* Disable interrupt */
+ /*********************/
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 & APCI1710_DISABLE_LATCH_INT;
+
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_Write16BitCounterValue |
+| (BYTE_ b_BoardHandle |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_SelectedCounter, |
+| UINT_ ui_WriteValue) |
++----------------------------------------------------------------------------+
+| Task : Write a 16-Bit value (ui_WriteValue) in to the selected|
+| 16-Bit counter (b_SelectedCounter) from selected module|
+| (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_SelectedCounter : Selected 16-Bit counter |
+| (0 or 1) |
+| UINT_ ui_WriteValue : 16-Bit write value |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: The selected 16-Bit counter parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Write16BitCounterValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_SelectedCounter, UINT ui_WriteValue)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /******************************/
+ /* Test the counter selection */
+ /******************************/
+
+ if (b_SelectedCounter < 2) {
+ /*******************/
+ /* Write the value */
+ /*******************/
+
+ outl((ULONG) ((ULONG) (ui_WriteValue) << (16 *
+ b_SelectedCounter)),
+ devpriv->s_BoardInfos.ui_Address + 8 +
+ (b_SelectedCounter * 4) +
+ (64 * b_ModulNbr));
+ } else {
+ /**************************************************/
+ /* The selected 16-Bit counter parameter is wrong */
+ /**************************************************/
+
+ DPRINTK("The selected 16-Bit counter parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_Write32BitCounterValue |
+| (BYTE_ b_BoardHandle |
+| BYTE_ b_ModulNbr, |
+| ULONG_ ul_WriteValue) |
++----------------------------------------------------------------------------+
+| Task : Write a 32-Bit value (ui_WriteValue) in to the selected|
+| module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| ULONG_ ul_WriteValue : 32-Bit write value |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Write32BitCounterValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, ULONG ul_WriteValue)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*******************/
+ /* Write the value */
+ /*******************/
+
+ outl(ul_WriteValue, devpriv->s_BoardInfos.
+ ui_Address + 4 + (64 * b_ModulNbr));
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnableIndex (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Enable the INDEX actions |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Index not initialised see function |
+| "i_APCI1710_InitIndex" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_EnableIndex(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+ ULONG ul_InterruptLatchReg;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*****************************/
+ /* Test if index initialised */
+ /*****************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_IndexInit) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 | APCI1710_ENABLE_INDEX;
+
+ ul_InterruptLatchReg =
+ inl(devpriv->s_BoardInfos.ui_Address +
+ 24 + (64 * b_ModulNbr));
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+ } else {
+ /*************************************************************/
+ /* Index not initialised see function "i_APCI1710_InitIndex" */
+ /*************************************************************/
+
+ DPRINTK("Index not initialised \n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_DisableIndex (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Disable the INDEX actions |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Index not initialised see function |
+| "i_APCI1710_InitIndex" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_DisableIndex(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*****************************/
+ /* Test if index initialised */
+ /*****************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_IndexInit) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 &
+ APCI1710_DISABLE_INDEX;
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+ } else {
+ /*************************************************************/
+ /* Index not initialised see function "i_APCI1710_InitIndex" */
+ /*************************************************************/
+
+ DPRINTK("Index not initialised \n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnableCompareLogic |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Enable the 32-Bit compare logic. At that moment that |
+| the incremental counter arrive to the compare value a |
+| interrupt is generated. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : -
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Compare logic not initialised. |
+| See function "i_APCI1710_InitCompareLogic" |
+| -5: Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_EnableCompareLogic(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*************************************/
+ /* Test if compare logic initialised */
+ /*************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_CompareLogicInit == 1) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 |
+ APCI1710_ENABLE_COMPARE_INT;
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+ } else {
+ /*********************************/
+ /* Compare logic not initialised */
+ /*********************************/
+
+ DPRINTK("Compare logic not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_DisableCompareLogic |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Disable the 32-Bit compare logic.
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : -
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Compare logic not initialised. |
+| See function "i_APCI1710_InitCompareLogic" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_DisableCompareLogic(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*************************************/
+ /* Test if compare logic initialised */
+ /*************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_CompareLogicInit == 1) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 &
+ APCI1710_DISABLE_COMPARE_INT;
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+ } else {
+ /*********************************/
+ /* Compare logic not initialised */
+ /*********************************/
+
+ DPRINTK("Compare logic not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : _INT_ i_APCI1710_EnableFrequencyMeasurement |
+ | (BYTE_ b_BoardHandle, |
+ | BYTE_ b_ModulNbr, |
+ | BYTE_ b_InterruptEnable) |
+ +----------------------------------------------------------------------------+
+ | Task : Enables the frequency measurement function |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+ | BYTE_ b_ModulNbr : Number of the module to be |
+ | configured (0 to 3) |
+ | BYTE_ b_InterruptEnable: Enable or disable the |
+ | interrupt. |
+ | APCI1710_ENABLE: |
+ | Enable the interrupt |
+ | APCI1710_DISABLE: |
+ | Disable the interrupt |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : - |
+ +----------------------------------------------------------------------------+
+ | Return Value : 0: No error |
+ | -1: The handle parameter of the board is wrong |
+ | -2: The selected module number is wrong |
+ | -3: Counter not initialised see function |
+ | "i_APCI1710_InitCounter" |
+ | -4: Frequency measurement logic not initialised. |
+ | See function "i_APCI1710_InitFrequencyMeasurement" |
+ | -5: Interrupt parameter is wrong |
+ | -6: Interrupt function not initialised. |
+ +----------------------------------------------------------------------------+
+ */
+
+INT i_APCI1710_EnableFrequencyMeasurement(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_InterruptEnable)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /********************************************/
+ /* Test if frequency mesurement initialised */
+ /********************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_FrequencyMeasurementInit == 1) {
+ /***************************/
+ /* Test the interrupt mode */
+ /***************************/
+
+ if ((b_InterruptEnable == APCI1710_DISABLE) ||
+ (b_InterruptEnable == APCI1710_ENABLE))
+ {
+
+ /************************************/
+ /* Enable the frequency measurement */
+ /************************************/
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 |
+ APCI1710_ENABLE_FREQUENCY;
+
+ /*********************************************/
+ /* Disable or enable the frequency interrupt */
+ /*********************************************/
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 &
+ APCI1710_DISABLE_FREQUENCY_INT)
+ | (b_InterruptEnable << 3);
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.
+ ui_Address + 20 +
+ (64 * b_ModulNbr));
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.
+ b_FrequencyMeasurementEnable =
+ 1;
+ } else {
+ /********************************/
+ /* Interrupt parameter is wrong */
+ /********************************/
+
+ DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /***********************************************/
+ /* Frequency measurement logic not initialised */
+ /***********************************************/
+
+ DPRINTK("Frequency measurement logic not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : _INT_ i_APCI1710_DisableFrequencyMeasurement |
+ | (BYTE_ b_BoardHandle, |
+ | BYTE_ b_ModulNbr) |
+ +----------------------------------------------------------------------------+
+ | Task : Disables the frequency measurement function |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+ | BYTE_ b_ModulNbr : Number of the module to be |
+ | configured (0 to 3) |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : - |
+ +----------------------------------------------------------------------------+
+ | Return Value : 0: No error |
+ | -1: The handle parameter of the board is wrong |
+ | -2: The selected module number is wrong |
+ | -3: Counter not initialised see function |
+ | "i_APCI1710_InitCounter" |
+ | -4: Frequency measurement logic not initialised. |
+ | See function "i_APCI1710_InitFrequencyMeasurement" |
+ +----------------------------------------------------------------------------+
+ */
+
+INT i_APCI1710_DisableFrequencyMeasurement(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /********************************************/
+ /* Test if frequency mesurement initialised */
+ /********************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_FrequencyMeasurementInit == 1) {
+ /*************************************/
+ /* Disable the frequency measurement */
+ /*************************************/
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 &
+ APCI1710_DISABLE_FREQUENCY
+ // Begin CG 29/06/01 CG 1100/0231 -> 0701/0232 Frequence measure IRQ must be cleared
+ & APCI1710_DISABLE_FREQUENCY_INT;
+ // End CG 29/06/01 CG 1100/0231 -> 0701/0232 Frequence measure IRQ must be cleared
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+
+ /*************************************/
+ /* Disable the frequency measurement */
+ /*************************************/
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.
+ b_FrequencyMeasurementEnable = 0;
+ } else {
+ /***********************************************/
+ /* Frequency measurement logic not initialised */
+ /***********************************************/
+
+ DPRINTK("Frequency measurement logic not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*########################################################################### */
+
+ // INSN READ
+
+/*########################################################################### */
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read and Get functions for INC_CPT |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1710_InsnReadINCCPT(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_ReadType;
+ INT i_ReturnValue = 0;
+
+ ui_ReadType = CR_CHAN(insn->chanspec);
+
+ devpriv->tsk_Current = current; // Save the current process task structure
+ switch (ui_ReadType) {
+ case APCI1710_INCCPT_READLATCHREGISTERSTATUS:
+ i_ReturnValue = i_APCI1710_ReadLatchRegisterStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) CR_RANGE(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_READLATCHREGISTERVALUE:
+ i_ReturnValue = i_APCI1710_ReadLatchRegisterValue(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) CR_RANGE(insn->chanspec), (PULONG) & data[0]);
+ printk("Latch Register Value %d\n", data[0]);
+ break;
+
+ case APCI1710_INCCPT_READ16BITCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_Read16BitCounterValue(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) CR_RANGE(insn->chanspec), (PUINT) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_READ32BITCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_Read32BitCounterValue(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PULONG) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_GETINDEXSTATUS:
+ i_ReturnValue = i_APCI1710_GetIndexStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_GETREFERENCESTATUS:
+ i_ReturnValue = i_APCI1710_GetReferenceStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_GETUASSTATUS:
+ i_ReturnValue = i_APCI1710_GetUASStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_GETCBSTATUS:
+ i_ReturnValue = i_APCI1710_GetCBStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_GET16BITCBSTATUS:
+ i_ReturnValue = i_APCI1710_Get16BitCBStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (PBYTE) & data[0], (PBYTE) & data[1]);
+ break;
+
+ case APCI1710_INCCPT_GETUDSTATUS:
+ i_ReturnValue = i_APCI1710_GetUDStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+
+ break;
+
+ case APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS:
+ i_ReturnValue = i_APCI1710_GetInterruptUDLatchedStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_READFREQUENCYMEASUREMENT:
+ i_ReturnValue = i_APCI1710_ReadFrequencyMeasurement(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (PBYTE) & data[0],
+ (PBYTE) & data[1], (PULONG) & data[2]);
+ break;
+
+ case APCI1710_INCCPT_READINTERRUPT:
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->s_InterruptParameters.
+ ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ break;
+
+ default:
+ printk("ReadType Parameter wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadLatchRegisterStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_LatchReg, |
+| PBYTE_ pb_LatchStatus) |
++----------------------------------------------------------------------------+
+| Task : Read the latch register status from selected module |
+| (b_ModulNbr) and selected latch register (b_LatchReg). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_LatchReg : Selected latch register |
+| 0 : for the first latch register |
+| 1 : for the second latch register |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_LatchStatus : Latch register status. |
+| 0 : No latch occur |
+| 1 : A software latch occur |
+| 2 : A hardware latch occur |
+| 3 : A software and hardware |
+| latch occur |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: The selected latch register parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadLatchRegisterStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_LatchReg, PBYTE pb_LatchStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_LatchReg;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*************************************/
+ /* Test the latch register parameter */
+ /*************************************/
+
+ if (b_LatchReg < 2) {
+ dw_LatchReg = inl(devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+
+ *pb_LatchStatus =
+ (BYTE) ((dw_LatchReg >> (b_LatchReg *
+ 4)) & 0x3);
+ } else {
+ /**************************************************/
+ /* The selected latch register parameter is wrong */
+ /**************************************************/
+
+ DPRINTK("The selected latch register parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadLatchRegisterValue |
+| (BYTE_ b_BoardHandle,|
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_LatchReg, |
+| PULONG_ pul_LatchValue) |
++----------------------------------------------------------------------------+
+| Task : Read the latch register value from selected module |
+| (b_ModulNbr) and selected latch register (b_LatchReg). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_LatchReg : Selected latch register |
+| 0 : for the first latch register |
+| 1 : for the second latch register |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_LatchValue : Latch register value |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: The selected latch register parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadLatchRegisterValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_LatchReg, PULONG pul_LatchValue)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*************************************/
+ /* Test the latch register parameter */
+ /*************************************/
+
+ if (b_LatchReg < 2) {
+ *pul_LatchValue = inl(devpriv->s_BoardInfos.
+ ui_Address + ((b_LatchReg + 1) * 4) +
+ (64 * b_ModulNbr));
+
+ } else {
+ /**************************************************/
+ /* The selected latch register parameter is wrong */
+ /**************************************************/
+
+ DPRINTK("The selected latch register parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_Read16BitCounterValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_SelectedCounter, |
+| PUINT_ pui_CounterValue) |
++----------------------------------------------------------------------------+
+| Task : Latch the selected 16-Bit counter (b_SelectedCounter) |
+| from selected module (b_ModulNbr) in to the first |
+| latch register and return the latched value. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_SelectedCounter : Selected 16-Bit counter |
+| (0 or 1) |
++----------------------------------------------------------------------------+
+| Output Parameters : PUINT_ pui_CounterValue : 16-Bit counter value |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: The selected 16-Bit counter parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Read16BitCounterValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_SelectedCounter, PUINT pui_CounterValue)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_LathchValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /******************************/
+ /* Test the counter selection */
+ /******************************/
+
+ if (b_SelectedCounter < 2) {
+ /*********************/
+ /* Latch the counter */
+ /*********************/
+
+ outl(1, devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+
+ /************************/
+ /* Read the latch value */
+ /************************/
+
+ dw_LathchValue = inl(devpriv->s_BoardInfos.
+ ui_Address + 4 + (64 * b_ModulNbr));
+
+ *pui_CounterValue =
+ (UINT) ((dw_LathchValue >> (16 *
+ b_SelectedCounter)) &
+ 0xFFFFU);
+ } else {
+ /**************************************************/
+ /* The selected 16-Bit counter parameter is wrong */
+ /**************************************************/
+
+ DPRINTK("The selected 16-Bit counter parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_Read32BitCounterValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PULONG_ pul_CounterValue) |
++----------------------------------------------------------------------------+
+| Task : Latch the 32-Bit counter from selected module |
+| (b_ModulNbr) in to the first latch register and return |
+| the latched value. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_CounterValue : 32-Bit counter value |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Read32BitCounterValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, PULONG pul_CounterValue)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*********************/
+ /* Tatch the counter */
+ /*********************/
+
+ outl(1, devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+
+ /************************/
+ /* Read the latch value */
+ /************************/
+
+ *pul_CounterValue = inl(devpriv->s_BoardInfos.
+ ui_Address + 4 + (64 * b_ModulNbr));
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetIndexStatus (BYTE_ b_BoardHandle,|
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_IndexStatus)|
++----------------------------------------------------------------------------+
+| Task : Return the index status |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_IndexStatus : 0 : No INDEX occur |
+| 1 : A INDEX occur |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Index not initialised see function |
+| "i_APCI1710_InitIndex" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetIndexStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_IndexStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*****************************/
+ /* Test if index initialised */
+ /*****************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_IndexInit) {
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (64 * b_ModulNbr));
+
+ *pb_IndexStatus = (BYTE) (dw_StatusReg & 1);
+ } else {
+ /*************************************************************/
+ /* Index not initialised see function "i_APCI1710_InitIndex" */
+ /*************************************************************/
+
+ DPRINTK("Index not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetReferenceStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_ReferenceStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the reference status |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_ReferenceStatus : 0 : No REFERENCE occur |
+| 1 : A REFERENCE occur |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Reference not initialised see function |
+| "i_APCI1710_InitReference" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetReferenceStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_ReferenceStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*********************************/
+ /* Test if reference initialised */
+ /*********************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_ReferenceInit) {
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 24 + (64 * b_ModulNbr));
+
+ *pb_ReferenceStatus =
+ (BYTE) (~dw_StatusReg & 1);
+ } else {
+ /*********************************************************************/
+ /* Reference not initialised see function "i_APCI1710_InitReference" */
+ /*********************************************************************/
+
+ DPRINTK("Reference not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetUASStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_UASStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the error signal (UAS) status |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_UASStatus : 0 : UAS is low "0" |
+| 1 : UAS is high "1" |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetUASStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_UASStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 24 + (64 * b_ModulNbr));
+
+ *pb_UASStatus = (BYTE) ((dw_StatusReg >> 1) & 1);
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetCBStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_CBStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the counter overflow status |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_CBStatus : 0 : Counter no overflow |
+| 1 : Counter overflow |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetCBStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_CBStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 16 + (64 * b_ModulNbr));
+
+ *pb_CBStatus = (BYTE) (dw_StatusReg & 1);
+
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_Get16BitCBStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_CBStatusCounter0, |
+| PBYTE_ pb_CBStatusCounter1) |
++----------------------------------------------------------------------------+
+| Task : Returns the counter overflow (counter initialised to |
+| 2*16-bit) status from selected incremental counter |
+| module |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_CBStatusCounter0 : 0 : No overflow occur for |
+| the first 16-bit |
+| counter |
+| 1 : Overflow occur for the|
+| first 16-bit counter |
+| PBYTE_ pb_CBStatusCounter1 : 0 : No overflow occur for |
+| the second 16-bit |
+| counter |
+| 1 : Overflow occur for the|
+| second 16-bit counter |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Counter not initialised to 2*16-bit mode. |
+| See function "i_APCI1710_InitCounter" |
+| -5: Firmware revision error |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Get16BitCBStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_CBStatusCounter0, PBYTE pb_CBStatusCounter1)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*************************/
+ /* Test if 2*16-Bit mode */
+ /*************************/
+
+ if ((devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister1 & 0x10) == 0x10) {
+ /*****************************/
+ /* Test the Firmware version */
+ /*****************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] & 0xFFFF) >=
+ 0x3136) {
+ dw_StatusReg =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 16 +
+ (64 * b_ModulNbr));
+
+ *pb_CBStatusCounter1 =
+ (BYTE) ((dw_StatusReg >> 0) &
+ 1);
+ *pb_CBStatusCounter0 =
+ (BYTE) ((dw_StatusReg >> 1) &
+ 1);
+ } // if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_BoardInfos.dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3136)
+ else {
+ /****************************/
+ /* Firmware revision error */
+ /****************************/
+
+ i_ReturnValue = -5;
+ } // if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_BoardInfos.dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3136)
+ } // if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_ModeRegister.s_ByteModeRegister.b_ModeRegister1 & 0x10) == 0x10)
+ else {
+ /********************************************/
+ /* Counter not initialised to 2*16-bit mode */
+ /* "i_APCI1710_InitCounter" */
+ /********************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -4;
+ } // if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_ModeRegister.s_ByteModeRegister.b_ModeRegister1 & 0x10) == 0x10)
+ } // if (ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1)
+ else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ } // if (ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1)
+ } // if (b_ModulNbr < 4)
+ else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ } // if (b_ModulNbr < 4)
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetUDStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_UDStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the counter progress status |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_UDStatus : 0 : Counter progress in the |
+| selected mode down |
+| 1 : Counter progress in the |
+| selected mode up |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetUDStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_UDStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 24 + (64 * b_ModulNbr));
+
+ *pb_UDStatus = (BYTE) ((dw_StatusReg >> 2) & 1);
+
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetInterruptUDLatchedStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_UDStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the counter progress latched status after a |
+| index interrupt occur. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_UDStatus : 0 : Counter progress in the |
+| selected mode down |
+| 1 : Counter progress in the |
+| selected mode up |
+| 2 : No index interrupt occur |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_UDStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*********************************/
+ /* Test if index interrupt occur */
+ /*********************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_IndexInterruptOccur == 1) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_IndexInterruptOccur = 0;
+
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (64 * b_ModulNbr));
+
+ *pb_UDStatus = (BYTE) ((dw_StatusReg >> 1) & 1);
+ } else {
+ /****************************/
+ /* No index interrupt occur */
+ /****************************/
+
+ *pb_UDStatus = 2;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : _INT_ i_APCI1710_ReadFrequencyMeasurement |
+ | (BYTE_ b_BoardHandle, |
+ | BYTE_ b_ModulNbr, |
+ | PBYTE_ pb_Status, |
+ | PULONG_ pul_ReadValue) |
+ +----------------------------------------------------------------------------+
+ | Task : Returns the status (pb_Status) and the number of |
+ | increments in the set time. |
+ | See function " i_APCI1710_InitFrequencyMeasurement " |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+ | BYTE_ b_ModulNbr : Number of the module to be |
+ | configured (0 to 3) |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : PBYTE_ pb_Status : Returns the frequency |
+ | measurement status |
+ | 0 : Counting cycle not |
+ | started. |
+ | 1 : Counting cycle started. |
+ | 2 : Counting cycle stopped. |
+ | The measurement cycle is |
+ | completed. |
+ | PBYTE_ pb_UDStatus : 0 : Counter progress in the |
+ | selected mode down |
+ | 1 : Counter progress in the |
+ | selected mode up |
+ | PULONG_ pul_ReadValue : Return the number of |
+ | increments in the defined |
+ | time base. |
+ +----------------------------------------------------------------------------+
+ | Return Value : 0: No error |
+ | -1: The handle parameter of the board is wrong |
+ | -2: The selected module number is wrong |
+ | -3: Counter not initialised see function |
+ | "i_APCI1710_InitCounter" |
+ | -4: Frequency measurement logic not initialised. |
+ | See function "i_APCI1710_InitFrequencyMeasurement" |
+ +----------------------------------------------------------------------------+
+ */
+
+INT i_APCI1710_ReadFrequencyMeasurement(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ PBYTE pb_Status, PBYTE pb_UDStatus, PULONG pul_ReadValue)
+{
+ INT i_ReturnValue = 0;
+ UINT ui_16BitValue;
+ DWORD dw_StatusReg;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /********************************************/
+ /* Test if frequency mesurement initialised */
+ /********************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_FrequencyMeasurementInit == 1) {
+ /******************/
+ /* Test if enable */
+ /******************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.
+ b_FrequencyMeasurementEnable == 1) {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ dw_StatusReg =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 32 +
+ (64 * b_ModulNbr));
+
+ /**************************/
+ /* Test if frequency stop */
+ /**************************/
+
+ if (dw_StatusReg & 1) {
+ *pb_Status = 2;
+ *pb_UDStatus =
+ (BYTE) ((dw_StatusReg >>
+ 1) & 3);
+
+ /******************/
+ /* Read the value */
+ /******************/
+
+ *pul_ReadValue =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 28 +
+ (64 * b_ModulNbr));
+
+ if (*pb_UDStatus == 0) {
+ /*************************/
+ /* Test the counter mode */
+ /*************************/
+
+ if ((devpriv->s_ModuleInfo[b_ModulNbr].s_SiemensCounterInfo.s_ModeRegister.s_ByteModeRegister.b_ModeRegister1 & APCI1710_16BIT_COUNTER) == APCI1710_16BIT_COUNTER) {
+ /****************************************/
+ /* Test if 16-bit counter 1 pulse occur */
+ /****************************************/
+
+ if ((*pul_ReadValue & 0xFFFFU) != 0) {
+ ui_16BitValue
+ =
+ (UINT)
+ *
+ pul_ReadValue
+ &
+ 0xFFFFU;
+ *pul_ReadValue
+ =
+ (*pul_ReadValue
+ &
+ 0xFFFF0000UL)
+ |
+ (0xFFFFU
+ -
+ ui_16BitValue);
+ }
+
+ /****************************************/
+ /* Test if 16-bit counter 2 pulse occur */
+ /****************************************/
+
+ if ((*pul_ReadValue & 0xFFFF0000UL) != 0) {
+ ui_16BitValue
+ =
+ (UINT)
+ (
+ (*pul_ReadValue
+ >>
+ 16)
+ &
+ 0xFFFFU);
+ *pul_ReadValue
+ =
+ (*pul_ReadValue
+ &
+ 0xFFFFUL)
+ |
+ (
+ (0xFFFFU - ui_16BitValue) << 16);
+ }
+ } else {
+ if (*pul_ReadValue != 0) {
+ *pul_ReadValue
+ =
+ 0xFFFFFFFFUL
+ -
+ *pul_ReadValue;
+ }
+ }
+ } else {
+ if (*pb_UDStatus == 1) {
+ /****************************************/
+ /* Test if 16-bit counter 2 pulse occur */
+ /****************************************/
+
+ if ((*pul_ReadValue & 0xFFFF0000UL) != 0) {
+ ui_16BitValue
+ =
+ (UINT)
+ (
+ (*pul_ReadValue
+ >>
+ 16)
+ &
+ 0xFFFFU);
+ *pul_ReadValue
+ =
+ (*pul_ReadValue
+ &
+ 0xFFFFUL)
+ |
+ (
+ (0xFFFFU - ui_16BitValue) << 16);
+ }
+ } else {
+ if (*pb_UDStatus
+ == 2) {
+ /****************************************/
+ /* Test if 16-bit counter 1 pulse occur */
+ /****************************************/
+
+ if ((*pul_ReadValue & 0xFFFFU) != 0) {
+ ui_16BitValue
+ =
+ (UINT)
+ *
+ pul_ReadValue
+ &
+ 0xFFFFU;
+ *pul_ReadValue
+ =
+ (*pul_ReadValue
+ &
+ 0xFFFF0000UL)
+ |
+ (0xFFFFU
+ -
+ ui_16BitValue);
+ }
+ }
+ }
+ }
+ } else {
+ *pb_Status = 1;
+ *pb_UDStatus = 0;
+ }
+ } else {
+ *pb_Status = 0;
+ *pb_UDStatus = 0;
+ }
+ } else {
+ /***********************************************/
+ /* Frequency measurement logic not initialised */
+ /***********************************************/
+
+ DPRINTK("Frequency measurement logic not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h
new file mode 100644
index 00000000000..5153cf68665
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+#define APCI1710_16BIT_COUNTER 0x10
+#define APCI1710_32BIT_COUNTER 0x0
+#define APCI1710_QUADRUPLE_MODE 0x0
+#define APCI1710_DOUBLE_MODE 0x3
+#define APCI1710_SIMPLE_MODE 0xF
+#define APCI1710_DIRECT_MODE 0x80
+#define APCI1710_HYSTERESIS_ON 0x60
+#define APCI1710_HYSTERESIS_OFF 0x0
+#define APCI1710_INCREMENT 0x60
+#define APCI1710_DECREMENT 0x0
+#define APCI1710_LATCH_COUNTER 0x1
+#define APCI1710_CLEAR_COUNTER 0x0
+#define APCI1710_LOW 0x0
+#define APCI1710_HIGH 0x1
+
+/*********************/
+/* Version 0600-0229 */
+/*********************/
+#define APCI1710_HIGH_EDGE_CLEAR_COUNTER 0x0
+#define APCI1710_HIGH_EDGE_LATCH_COUNTER 0x1
+#define APCI1710_LOW_EDGE_CLEAR_COUNTER 0x2
+#define APCI1710_LOW_EDGE_LATCH_COUNTER 0x3
+#define APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER 0x4
+#define APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER 0x5
+#define APCI1710_SOURCE_0 0x0
+#define APCI1710_SOURCE_1 0x1
+
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
+
+#define APCI1710_ENABLE_LATCH_INT 0x80
+#define APCI1710_DISABLE_LATCH_INT (~APCI1710_ENABLE_LATCH_INT)
+
+#define APCI1710_INDEX_LATCH_COUNTER 0x10
+#define APCI1710_INDEX_AUTO_MODE 0x8
+#define APCI1710_ENABLE_INDEX 0x4
+#define APCI1710_DISABLE_INDEX (~APCI1710_ENABLE_INDEX)
+#define APCI1710_ENABLE_LATCH_AND_CLEAR 0x8
+#define APCI1710_DISABLE_LATCH_AND_CLEAR (~APCI1710_ENABLE_LATCH_AND_CLEAR)
+#define APCI1710_SET_LOW_INDEX_LEVEL 0x4
+#define APCI1710_SET_HIGH_INDEX_LEVEL (~APCI1710_SET_LOW_INDEX_LEVEL)
+#define APCI1710_INVERT_INDEX_RFERENCE 0x2
+#define APCI1710_DEFAULT_INDEX_RFERENCE (~APCI1710_INVERT_INDEX_RFERENCE)
+
+#define APCI1710_ENABLE_INDEX_INT 0x1
+#define APCI1710_DISABLE_INDEX_INT (~APCI1710_ENABLE_INDEX_INT)
+
+#define APCI1710_ENABLE_FREQUENCY 0x4
+#define APCI1710_DISABLE_FREQUENCY (~APCI1710_ENABLE_FREQUENCY)
+
+#define APCI1710_ENABLE_FREQUENCY_INT 0x8
+#define APCI1710_DISABLE_FREQUENCY_INT (~APCI1710_ENABLE_FREQUENCY_INT)
+
+#define APCI1710_ENABLE_40MHZ_FREQUENCY 0x40
+#define APCI1710_DISABLE_40MHZ_FREQUENCY (~APCI1710_ENABLE_40MHZ_FREQUENCY)
+
+#define APCI1710_ENABLE_40MHZ_FILTER 0x80
+#define APCI1710_DISABLE_40MHZ_FILTER (~APCI1710_ENABLE_40MHZ_FILTER)
+
+#define APCI1710_ENABLE_COMPARE_INT 0x2
+#define APCI1710_DISABLE_COMPARE_INT (~APCI1710_ENABLE_COMPARE_INT)
+
+#define APCI1710_ENABLE_INDEX_ACTION 0x20
+#define APCI1710_DISABLE_INDEX_ACTION (~APCI1710_ENABLE_INDEX_ACTION)
+#define APCI1710_REFERENCE_HIGH 0x40
+#define APCI1710_REFERENCE_LOW (~APCI1710_REFERENCE_HIGH)
+
+#define APCI1710_TOR_GATE_LOW 0x40
+#define APCI1710_TOR_GATE_HIGH (~APCI1710_TOR_GATE_LOW)
+
+/* INSN CONFIG */
+#define APCI1710_INCCPT_INITCOUNTER 100
+#define APCI1710_INCCPT_COUNTERAUTOTEST 101
+#define APCI1710_INCCPT_INITINDEX 102
+#define APCI1710_INCCPT_INITREFERENCE 103
+#define APCI1710_INCCPT_INITEXTERNALSTROBE 104
+#define APCI1710_INCCPT_INITCOMPARELOGIC 105
+#define APCI1710_INCCPT_INITFREQUENCYMEASUREMENT 106
+
+/* INSN READ */
+#define APCI1710_INCCPT_READLATCHREGISTERSTATUS 200
+#define APCI1710_INCCPT_READLATCHREGISTERVALUE 201
+#define APCI1710_INCCPT_READ16BITCOUNTERVALUE 202
+#define APCI1710_INCCPT_READ32BITCOUNTERVALUE 203
+#define APCI1710_INCCPT_GETINDEXSTATUS 204
+#define APCI1710_INCCPT_GETREFERENCESTATUS 205
+#define APCI1710_INCCPT_GETUASSTATUS 206
+#define APCI1710_INCCPT_GETCBSTATUS 207
+#define APCI1710_INCCPT_GET16BITCBSTATUS 208
+#define APCI1710_INCCPT_GETUDSTATUS 209
+#define APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS 210
+#define APCI1710_INCCPT_READFREQUENCYMEASUREMENT 211
+#define APCI1710_INCCPT_READINTERRUPT 212
+
+/* INSN BITS */
+#define APCI1710_INCCPT_CLEARCOUNTERVALUE 300
+#define APCI1710_INCCPT_CLEARALLCOUNTERVALUE 301
+#define APCI1710_INCCPT_SETINPUTFILTER 302
+#define APCI1710_INCCPT_LATCHCOUNTER 303
+#define APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE 304
+#define APCI1710_INCCPT_SETDIGITALCHLON 305
+#define APCI1710_INCCPT_SETDIGITALCHLOFF 306
+
+/* INSN WRITE */
+#define APCI1710_INCCPT_ENABLELATCHINTERRUPT 400
+#define APCI1710_INCCPT_DISABLELATCHINTERRUPT 401
+#define APCI1710_INCCPT_WRITE16BITCOUNTERVALUE 402
+#define APCI1710_INCCPT_WRITE32BITCOUNTERVALUE 403
+#define APCI1710_INCCPT_ENABLEINDEX 404
+#define APCI1710_INCCPT_DISABLEINDEX 405
+#define APCI1710_INCCPT_ENABLECOMPARELOGIC 406
+#define APCI1710_INCCPT_DISABLECOMPARELOGIC 407
+#define APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT 408
+#define APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT 409
+
+/************ Main Functions *************/
+INT i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int * data);
+
+INT i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn *insn, unsigned int * data);
+
+INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn *insn, unsigned int * data);
+
+INT i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn *insn, unsigned int * data);
+
+/*********** Supplementary Functions********/
+
+/* INSN CONFIG */
+INT i_APCI1710_InitCounter(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_CounterRange,
+ BYTE b_FirstCounterModus,
+ BYTE b_FirstCounterOption,
+ BYTE b_SecondCounterModus,
+ BYTE b_SecondCounterOption);
+
+INT i_APCI1710_CounterAutoTest(struct comedi_device *dev, PBYTE pb_TestStatus);
+
+INT i_APCI1710_InitIndex(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_ReferenceAction,
+ BYTE b_IndexOperation, BYTE b_AutoMode,
+ BYTE b_InterruptEnable);
+
+INT i_APCI1710_InitReference(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_ReferenceLevel);
+
+INT i_APCI1710_InitExternalStrobe(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_ExternalStrobe,
+ BYTE b_ExternalStrobeLevel);
+
+INT i_APCI1710_InitCompareLogic(struct comedi_device *dev,
+ BYTE b_ModulNbr, UINT ui_CompareValue);
+
+INT i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PCIInputClock,
+ BYTE b_TimingUnity,
+ ULONG ul_TimingInterval,
+ PULONG pul_RealTimingInterval);
+
+/* INSN BITS */
+INT i_APCI1710_ClearCounterValue(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_ClearAllCounterValue(struct comedi_device *dev);
+
+INT i_APCI1710_SetInputFilter(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_PCIInputClock,
+ BYTE b_Filter);
+
+INT i_APCI1710_LatchCounter(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_LatchReg);
+
+INT i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_SourceSelection);
+
+INT i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, BYTE b_ModulNbr);
+
+/* INSN WRITE */
+INT i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_Write16BitCounterValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_SelectedCounter,
+ UINT ui_WriteValue);
+
+INT i_APCI1710_Write32BitCounterValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, ULONG ul_WriteValue);
+
+INT i_APCI1710_EnableIndex(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_DisableIndex(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_EnableCompareLogic(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_DisableCompareLogic(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_InterruptEnable);
+
+INT i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev,
+ BYTE b_ModulNbr);
+
+/* INSN READ */
+INT i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_LatchReg,
+ PBYTE pb_LatchStatus);
+
+INT i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_LatchReg,
+ PULONG pul_LatchValue);
+
+INT i_APCI1710_Read16BitCounterValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_SelectedCounter,
+ PUINT pui_CounterValue);
+
+INT i_APCI1710_Read32BitCounterValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, PULONG pul_CounterValue);
+
+INT i_APCI1710_GetIndexStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_IndexStatus);
+
+INT i_APCI1710_GetReferenceStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_ReferenceStatus);
+
+INT i_APCI1710_GetUASStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_UASStatus);
+
+INT i_APCI1710_GetCBStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_CBStatus);
+
+INT i_APCI1710_Get16BitCBStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_CBStatusCounter0,
+ PBYTE pb_CBStatusCounter1);
+
+INT i_APCI1710_GetUDStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_UDStatus);
+
+INT i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_UDStatus);
+
+INT i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ PBYTE pb_Status, PBYTE pb_UDStatus,
+ PULONG pul_ReadValue);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
new file mode 100644
index 00000000000..3ac6a264ef5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
@@ -0,0 +1,861 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : Inp_CPT.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 pulse encoder module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ |----------|-----------|------------------------------------------------|
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Inp_cpt.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitPulseEncoder |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PulseEncoderNbr, |
+| BYTE_ b_InputLevelSelection, |
+| BYTE_ b_TriggerOutputAction, |
+| ULONG_ ul_StartValue) |
++----------------------------------------------------------------------------+
+| Task : Configure the pulse encoder operating mode selected via|
+| b_ModulNbr and b_PulseEncoderNbr. The pulse encoder |
+| after each pulse decrement the counter value from 1. |
+| |
+| You must calling this function be for you call any |
+| other function witch access of pulse encoders. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
+| (0 to 3) |
+| BYTE_ b_InputLevelSelection : Input level selection |
+| (0 or 1) |
+| 0 : Set pulse encoder|
+| count the the low|
+| level pulse. |
+| 1 : Set pulse encoder|
+| count the the |
+| high level pulse.|
+| BYTE_ b_TriggerOutputAction : Digital TRIGGER output |
+| action |
+| 0 : No action |
+| 1 : Set the trigger |
+| output to "1" |
+| (high) after the |
+| passage from 1 to|
+| 0 from pulse |
+| encoder. |
+| 2 : Set the trigger |
+| output to "0" |
+| (low) after the |
+| passage from 1 to|
+| 0 from pulse |
+| encoder |
+| ULONG_ ul_StartValue : Pulse encoder start value|
+| (1 to 4294967295)
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);
+ b_PulseEncoderNbr =(BYTE) data[0];
+ b_InputLevelSelection =(BYTE) data[1];
+ b_TriggerOutputAction =(BYTE) data[2];
+ ul_StartValue =(ULONG) data[3];
+ |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module is not a pulse encoder module |
+| -3: Pulse encoder selection is wrong |
+| -4: Input level selection is wrong |
+| -5: Digital TRIGGER output action selection is wrong |
+| -6: Pulse encoder start value is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_IntRegister;
+
+ BYTE b_ModulNbr;
+ BYTE b_PulseEncoderNbr;
+ BYTE b_InputLevelSelection;
+ BYTE b_TriggerOutputAction;
+ ULONG ul_StartValue;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_PulseEncoderNbr = (BYTE) data[0];
+ b_InputLevelSelection = (BYTE) data[1];
+ b_TriggerOutputAction = (BYTE) data[2];
+ ul_StartValue = (ULONG) data[3];
+
+ i_ReturnValue = insn->n;
+
+ /***********************************/
+ /* Test the selected module number */
+ /***********************************/
+
+ if (b_ModulNbr <= 3) {
+ /*************************/
+ /* Test if pulse encoder */
+ /*************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ APCI1710_PULSE_ENCODER) ==
+ APCI1710_PULSE_ENCODER) {
+ /******************************************/
+ /* Test the selected pulse encoder number */
+ /******************************************/
+
+ if (b_PulseEncoderNbr <= 3) {
+ /************************/
+ /* Test the input level */
+ /************************/
+
+ if ((b_InputLevelSelection == 0)
+ || (b_InputLevelSelection == 1)) {
+ /*******************************************/
+ /* Test the ouput TRIGGER action selection */
+ /*******************************************/
+
+ if ((b_TriggerOutputAction <= 2)
+ || (b_PulseEncoderNbr > 0)) {
+ if (ul_StartValue > 1) {
+
+ dw_IntRegister =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 20 +
+ (64 * b_ModulNbr));
+
+ /***********************/
+ /* Set the start value */
+ /***********************/
+
+ outl(ul_StartValue,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (b_PulseEncoderNbr
+ * 4) +
+ (64 * b_ModulNbr));
+
+ /***********************/
+ /* Set the input level */
+ /***********************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister &
+ (0xFFFFFFFFUL -
+ (1UL << (8 + b_PulseEncoderNbr)))) | ((1UL & (~b_InputLevelSelection)) << (8 + b_PulseEncoderNbr));
+
+ /*******************************/
+ /* Test if output trigger used */
+ /*******************************/
+
+ if ((b_TriggerOutputAction > 0) && (b_PulseEncoderNbr > 1)) {
+ /****************************/
+ /* Enable the output action */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ | (1UL
+ << (4 + b_PulseEncoderNbr));
+
+ /*********************************/
+ /* Set the output TRIGGER action */
+ /*********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ &
+ (0xFFFFFFFFUL
+ -
+ (1UL << (12 + b_PulseEncoderNbr)))) | ((1UL & (b_TriggerOutputAction - 1)) << (12 + b_PulseEncoderNbr));
+ } else {
+ /*****************************/
+ /* Disable the output action */
+ /*****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ &
+ (0xFFFFFFFFUL
+ -
+ (1UL << (4 + b_PulseEncoderNbr)));
+ }
+
+ /*************************/
+ /* Set the configuration */
+ /*************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 20 +
+ (64 * b_ModulNbr));
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ s_PulseEncoderInfo
+ [b_PulseEncoderNbr].
+ b_PulseEncoderInit
+ = 1;
+ } else {
+ /**************************************/
+ /* Pulse encoder start value is wrong */
+ /**************************************/
+
+ DPRINTK("Pulse encoder start value is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /****************************************************/
+ /* Digital TRIGGER output action selection is wrong */
+ /****************************************************/
+
+ DPRINTK("Digital TRIGGER output action selection is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /**********************************/
+ /* Input level selection is wrong */
+ /**********************************/
+
+ DPRINTK("Input level selection is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /************************************/
+ /* Pulse encoder selection is wrong */
+ /************************************/
+
+ DPRINTK("Pulse encoder selection is wrong\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /********************************************/
+ /* The module is not a pulse encoder module */
+ /********************************************/
+
+ DPRINTK("The module is not a pulse encoder module\n");
+ i_ReturnValue = -2;
+ }
+ } else {
+ /********************************************/
+ /* The module is not a pulse encoder module */
+ /********************************************/
+
+ DPRINTK("The module is not a pulse encoder module\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnablePulseEncoder |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PulseEncoderNbr, |
+| BYTE_ b_CycleSelection, |
+| BYTE_ b_InterruptHandling) |
++----------------------------------------------------------------------------+
+| Task : Enableor disable the selected pulse encoder (b_PulseEncoderNbr) |
+| from selected module (b_ModulNbr). Each input pulse |
+| decrement the pulse encoder counter value from 1. |
+| If you enabled the interrupt (b_InterruptHandling), a |
+| interrupt is generated when the pulse encoder has run |
+| down. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
+| (0 to 3) |
+| BYTE_ b_CycleSelection : APCI1710_CONTINUOUS: |
+| Each time the |
+| counting value is set|
+| on "0", the pulse |
+| encoder load the |
+| start value after |
+| the next pulse. |
+| APCI1710_SINGLE: |
+| If the counter is set|
+| on "0", the pulse |
+| encoder is stopped. |
+| BYTE_ b_InterruptHandling : Interrupts can be |
+| generated, when the pulse|
+| encoder has run down. |
+| With this parameter the |
+| user decides if |
+| interrupts are used or |
+| not. |
+| APCI1710_ENABLE: |
+| Interrupts are enabled |
+| APCI1710_DISABLE: |
+| Interrupts are disabled
+
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);
+ b_Action =(BYTE) data[0];
+ b_PulseEncoderNbr =(BYTE) data[1];
+ b_CycleSelection =(BYTE) data[2];
+ b_InterruptHandling =(BYTE) data[3];|
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection is wrong |
+| -3: Pulse encoder selection is wrong |
+| -4: Pulse encoder not initialised. |
+| See function "i_APCI1710_InitPulseEncoder" |
+| -5: Cycle selection mode is wrong |
+| -6: Interrupt handling mode is wrong |
+| -7: Interrupt routine not installed. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ BYTE b_ModulNbr;
+ BYTE b_PulseEncoderNbr;
+ BYTE b_CycleSelection;
+ BYTE b_InterruptHandling;
+ BYTE b_Action;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_Action = (BYTE) data[0];
+ b_PulseEncoderNbr = (BYTE) data[1];
+ b_CycleSelection = (BYTE) data[2];
+ b_InterruptHandling = (BYTE) data[3];
+
+ /***********************************/
+ /* Test the selected module number */
+ /***********************************/
+
+ if (b_ModulNbr <= 3) {
+ /******************************************/
+ /* Test the selected pulse encoder number */
+ /******************************************/
+
+ if (b_PulseEncoderNbr <= 3) {
+ /*************************************/
+ /* Test if pulse encoder initialised */
+ /*************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ s_PulseEncoderInfo[b_PulseEncoderNbr].
+ b_PulseEncoderInit == 1) {
+ switch (b_Action) {
+
+ case APCI1710_ENABLE:
+ /****************************/
+ /* Test the cycle selection */
+ /****************************/
+
+ if (b_CycleSelection ==
+ APCI1710_CONTINUOUS
+ || b_CycleSelection ==
+ APCI1710_SINGLE) {
+ /*******************************/
+ /* Test the interrupt handling */
+ /*******************************/
+
+ if (b_InterruptHandling ==
+ APCI1710_ENABLE
+ || b_InterruptHandling
+ == APCI1710_DISABLE) {
+ /******************************/
+ /* Test if interrupt not used */
+ /******************************/
+
+ if (b_InterruptHandling
+ ==
+ APCI1710_DISABLE)
+ {
+ /*************************/
+ /* Disable the interrupt */
+ /*************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ &
+ (0xFFFFFFFFUL
+ -
+ (1UL << b_PulseEncoderNbr));
+ } else {
+
+ /************************/
+ /* Enable the interrupt */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ | (1UL
+ <<
+ b_PulseEncoderNbr);
+ devpriv->tsk_Current = current; // Save the current process task structure
+
+ }
+
+ if (i_ReturnValue >= 0) {
+ /***********************************/
+ /* Enable or disable the interrupt */
+ /***********************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister,
+ devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 20 +
+ (64 * b_ModulNbr));
+
+ /****************************/
+ /* Enable the pulse encoder */
+ /****************************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister
+ | (1UL
+ <<
+ b_PulseEncoderNbr);
+
+ /**********************/
+ /* Set the cycle mode */
+ /**********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister
+ =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister
+ &
+ (0xFFFFFFFFUL
+ -
+ (1 << (b_PulseEncoderNbr + 4)))) | ((b_CycleSelection & 1UL) << (4 + b_PulseEncoderNbr));
+
+ /****************************/
+ /* Enable the pulse encoder */
+ /****************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister,
+ devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 16 +
+ (64 * b_ModulNbr));
+ }
+ } else {
+ /************************************/
+ /* Interrupt handling mode is wrong */
+ /************************************/
+
+ DPRINTK("Interrupt handling mode is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /*********************************/
+ /* Cycle selection mode is wrong */
+ /*********************************/
+
+ DPRINTK("Cycle selection mode is wrong\n");
+ i_ReturnValue = -5;
+ }
+ break;
+
+ case APCI1710_DISABLE:
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister =
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister &
+ (0xFFFFFFFFUL -
+ (1UL << b_PulseEncoderNbr));
+
+ /*****************************/
+ /* Disable the pulse encoder */
+ /*****************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister,
+ devpriv->s_BoardInfos.
+ ui_Address + 16 +
+ (64 * b_ModulNbr));
+
+ break;
+ } // switch End
+
+ } else {
+ /*********************************/
+ /* Pulse encoder not initialised */
+ /*********************************/
+
+ DPRINTK("Pulse encoder not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /************************************/
+ /* Pulse encoder selection is wrong */
+ /************************************/
+
+ DPRINTK("Pulse encoder selection is wrong\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*****************************/
+ /* Module selection is wrong */
+ /*****************************/
+
+ DPRINTK("Module selection is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadPulseEncoderStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PulseEncoderNbr, |
+| PBYTE_ pb_Status) |
++----------------------------------------------------------------------------+
+| Task APCI1710_PULSEENCODER_READ : Reads the pulse encoder status
+ and valuefrom selected pulse |
+| encoder (b_PulseEncoderNbr) from selected module |
+| (b_ModulNbr). |
++----------------------------------------------------------------------------+
+ BYTE b_Type; data[0]
+ APCI1710_PULSEENCODER_WRITE
+ Writes a 32-bit value (ul_WriteValue) into the selected|
+| pulse encoder (b_PulseEncoderNbr) from selected module |
+| (b_ModulNbr). This operation set the new start pulse |
+| encoder value.
+ APCI1710_PULSEENCODER_READ
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| CRAREF() BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| data[1] BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
+| (0 to 3)
+ APCI1710_PULSEENCODER_WRITE
+ data[2] ULONG_ ul_WriteValue : 32-bit value to be |
+| written |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_Status : Pulse encoder status. |
+| 0 : No overflow occur|
+| 1 : Overflow occur
+ PULONG_ pul_ReadValue : Pulse encoder value | |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection is wrong |
+| -3: Pulse encoder selection is wrong |
+| -4: Pulse encoder not initialised. |
+| See function "i_APCI1710_InitPulseEncoder" |
++----------------------------------------------------------------------------+
+*/
+
+/*_INT_ i_APCI1710_ReadPulseEncoderStatus (BYTE_ b_BoardHandle,
+ BYTE_ b_ModulNbr,
+ BYTE_ b_PulseEncoderNbr,
+
+ PBYTE_ pb_Status)
+ */
+INT i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusRegister;
+ BYTE b_ModulNbr;
+ BYTE b_PulseEncoderNbr;
+ PBYTE pb_Status;
+ BYTE b_Type;
+ PULONG pul_ReadValue;
+ ULONG ul_WriteValue;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_Type = (BYTE) data[0];
+ b_PulseEncoderNbr = (BYTE) data[1];
+ pb_Status = (PBYTE) & data[0];
+ pul_ReadValue = (PULONG) & data[1];
+
+ /***********************************/
+ /* Test the selected module number */
+ /***********************************/
+
+ if (b_ModulNbr <= 3) {
+ /******************************************/
+ /* Test the selected pulse encoder number */
+ /******************************************/
+
+ if (b_PulseEncoderNbr <= 3) {
+ /*************************************/
+ /* Test if pulse encoder initialised */
+ /*************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ s_PulseEncoderInfo[b_PulseEncoderNbr].
+ b_PulseEncoderInit == 1) {
+
+ switch (b_Type) {
+ case APCI1710_PULSEENCODER_READ:
+ /****************************/
+ /* Read the status register */
+ /****************************/
+
+ dw_StatusRegister =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 16 +
+ (64 * b_ModulNbr));
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister |
+ dw_StatusRegister;
+
+ *pb_Status =
+ (BYTE) (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister >> (1 +
+ b_PulseEncoderNbr)) & 1;
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister =
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister &
+ (0xFFFFFFFFUL - (1 << (1 +
+ b_PulseEncoderNbr)));
+
+ /******************/
+ /* Read the value */
+ /******************/
+
+ *pul_ReadValue =
+ inl(devpriv->s_BoardInfos.
+ ui_Address +
+ (4 * b_PulseEncoderNbr) +
+ (64 * b_ModulNbr));
+ break;
+
+ case APCI1710_PULSEENCODER_WRITE:
+ ul_WriteValue = (ULONG) data[2];
+ /*******************/
+ /* Write the value */
+ /*******************/
+
+ outl(ul_WriteValue,
+ devpriv->s_BoardInfos.
+ ui_Address +
+ (4 * b_PulseEncoderNbr) +
+ (64 * b_ModulNbr));
+
+ } //end of switch
+ } else {
+ /*********************************/
+ /* Pulse encoder not initialised */
+ /*********************************/
+
+ DPRINTK("Pulse encoder not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /************************************/
+ /* Pulse encoder selection is wrong */
+ /************************************/
+
+ DPRINTK("Pulse encoder selection is wrong\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*****************************/
+ /* Module selection is wrong */
+ /*****************************/
+
+ DPRINTK("Module selection is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+INT i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /***************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ return insn->n;
+
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h
new file mode 100644
index 00000000000..28252873e86
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+#define APCI1710_SINGLE 0
+#define APCI1710_CONTINUOUS 1
+
+#define APCI1710_PULSEENCODER_READ 0
+#define APCI1710_PULSEENCODER_WRITE 1
+
+INT i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+/*
+ * READ PULSE ENCODER FUNCTIONS
+ */
+INT i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+/*
+ * WRITE PULSE ENCODER FUNCTIONS
+ */
+INT i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
new file mode 100644
index 00000000000..5ddd092a656
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
@@ -0,0 +1,3588 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : PWM.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 Wulse wide modulation module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +-----------------------------------------------------------------------+
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Pwm.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnConfigPWM(struct comedi_device *dev,
+struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Pwm Init and Get Pwm Initialisation |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigPWM(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_ConfigType;
+ INT i_ReturnValue = 0;
+ b_ConfigType = CR_CHAN(insn->chanspec);
+
+ switch (b_ConfigType) {
+ case APCI1710_PWM_INIT:
+ i_ReturnValue = i_APCI1710_InitPWM(dev, (BYTE) CR_AREF(insn->chanspec), // b_ModulNbr
+ (BYTE) data[0], //b_PWM
+ (BYTE) data[1], // b_ClockSelection
+ (BYTE) data[2], // b_TimingUnit
+ (ULONG) data[3], //ul_LowTiming
+ (ULONG) data[4], //ul_HighTiming
+ (PULONG) & data[0], //pul_RealLowTiming
+ (PULONG) & data[1] //pul_RealHighTiming
+ );
+ break;
+
+ case APCI1710_PWM_GETINITDATA:
+ i_ReturnValue = i_APCI1710_GetPWMInitialisation(dev, (BYTE) CR_AREF(insn->chanspec), // b_ModulNbr
+ (BYTE) data[0], //b_PWM
+ (PBYTE) & data[0], //pb_TimingUnit
+ (PULONG) & data[1], //pul_LowTiming
+ (PULONG) & data[2], //pul_HighTiming
+ (PBYTE) & data[3], // pb_StartLevel
+ (PBYTE) & data[4], // pb_StopMode
+ (PBYTE) & data[5], // pb_StopLevel
+ (PBYTE) & data[6], // pb_ExternGate
+ (PBYTE) & data[7], // pb_InterruptEnable
+ (PBYTE) & data[8] // pb_Enable
+ );
+ break;
+
+ default:
+ printk(" Config Parameter Wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitPWM |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| BYTE_ b_ClockSelection, |
+| BYTE_ b_TimingUnit, |
+| ULONG_ ul_LowTiming, |
+| ULONG_ ul_HighTiming, |
+| PULONG_ pul_RealLowTiming, |
+| PULONG_ pul_RealHighTiming) |
++----------------------------------------------------------------------------+
+| Task : Configure the selected PWM (b_PWM) from selected module|
+| (b_ModulNbr). The ul_LowTiming, ul_HighTiming and |
+| ul_TimingUnit determine the low/high timing base for |
+| the period. pul_RealLowTiming, pul_RealHighTiming |
+| return the real timing value. |
+| You must calling this function be for you call any |
+| other function witch access of the PWM. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure|
+| (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1). |
+| BYTE_ b_ClockSelection : Selection from PCI bus |
+| clock |
+| - APCI1710_30MHZ : |
+| The PC have a 30 MHz |
+| PCI bus clock |
+| - APCI1710_33MHZ : |
+| The PC have a 33 MHz |
+| PCI bus clock |
+| - APCI1710_40MHZ |
+| The APCI-1710 have a |
+| integrated 40Mhz |
+| quartz. |
+| BYTE_ b_TimingUnit : Base timing Unit (0 to 4) |
+| 0 : ns |
+| 1 : æs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| ULONG_ ul_LowTiming : Low base timing value. |
+| ULONG_ ul_HighTiming : High base timing value. |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_RealLowTiming : Real low base timing |
+| value. |
+| PULONG_ pul_RealHighTiming : Real high base timing |
+| value. |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: The selected input clock is wrong |
+| -6: Timing Unit selection is wrong |
+| -7: Low base timing selection is wrong |
+| -8: High base timing selection is wrong |
+| -9: You can not used the 40MHz clock selection with |
+| this board |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitPWM(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_ClockSelection,
+ BYTE b_TimingUnit,
+ ULONG ul_LowTiming,
+ ULONG ul_HighTiming,
+ PULONG pul_RealLowTiming, PULONG pul_RealHighTiming)
+{
+ INT i_ReturnValue = 0;
+ ULONG ul_LowTimerValue = 0;
+ ULONG ul_HighTimerValue = 0;
+ DWORD dw_Command;
+ double d_RealLowTiming = 0;
+ double d_RealHighTiming = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM <= 1) {
+ /******************/
+ /* Test the clock */
+ /******************/
+
+ if ((b_ClockSelection == APCI1710_30MHZ) ||
+ (b_ClockSelection == APCI1710_33MHZ) ||
+ (b_ClockSelection == APCI1710_40MHZ)) {
+ /************************/
+ /* Test the timing unit */
+ /************************/
+
+ if (b_TimingUnit <= 4) {
+ /*********************************/
+ /* Test the low timing selection */
+ /*********************************/
+
+ if (((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 0)
+ && (ul_LowTiming
+ >= 266)
+ && (ul_LowTiming
+ <=
+ 0xFFFFFFFFUL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 1)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 571230650UL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 2)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 571230UL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 3)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 571UL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 4)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <= 9UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 0)
+ && (ul_LowTiming
+ >= 242)
+ && (ul_LowTiming
+ <=
+ 0xFFFFFFFFUL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 1)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 519691043UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 2)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 519691UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 3)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 520UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 4)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <= 8UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 0)
+ && (ul_LowTiming
+ >= 200)
+ && (ul_LowTiming
+ <=
+ 0xFFFFFFFFUL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 1)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 429496729UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 2)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 429496UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 3)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 429UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 4)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 7UL))) {
+ /**********************************/
+ /* Test the High timing selection */
+ /**********************************/
+
+ if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 266) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230650UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 9UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 242) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691043UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 520UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 8UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 200) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496729UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 7UL))) {
+ /**************************/
+ /* Test the board version */
+ /**************************/
+
+ if (((b_ClockSelection == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_ClockSelection != APCI1710_40MHZ)) {
+
+ /************************************/
+ /* Calculate the low division fator */
+ /************************************/
+
+ fpu_begin
+ ();
+
+ switch (b_TimingUnit) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (ul_LowTiming
+ *
+ (0.00025 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (0.00025 * (double)b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (0.00025
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+ *pul_RealLowTiming
+ =
+ *pul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (ul_LowTiming
+ *
+ (0.25 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (0.25 * (double)b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (
+ (double)
+ 0.25
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+ *pul_RealLowTiming
+ =
+ *pul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ ul_LowTiming
+ *
+ (250.0
+ *
+ b_ClockSelection);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (250.0 * (double)b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (250.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+ *pul_RealLowTiming
+ =
+ *pul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (ul_LowTiming
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+ *pul_RealLowTiming
+ =
+ *pul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (ul_LowTiming
+ *
+ 60)
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)(ul_LowTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60;
+ d_RealLowTiming
+ =
+ (
+ (double)
+ ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60.0;
+
+ if ((double)(((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+ *pul_RealLowTiming
+ =
+ *pul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+ }
+
+ /*************************************/
+ /* Calculate the high division fator */
+ /*************************************/
+
+ switch (b_TimingUnit) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (ul_HighTiming
+ *
+ (0.00025 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (0.00025 * (double)b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (0.00025
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+ *pul_RealHighTiming
+ =
+ *pul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (ul_HighTiming
+ *
+ (0.25 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (0.25 * (double)b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (
+ (double)
+ 0.25
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+ *pul_RealHighTiming
+ =
+ *pul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ ul_HighTiming
+ *
+ (250.0
+ *
+ b_ClockSelection);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (250.0 * (double)b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (250.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+ *pul_RealHighTiming
+ =
+ *pul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (ul_HighTiming
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+ *pul_RealHighTiming
+ =
+ *pul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (ul_HighTiming
+ *
+ 60)
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)(ul_HighTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60;
+ d_RealHighTiming
+ =
+ (
+ (double)
+ ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60.0;
+
+ if ((double)(((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+ *pul_RealHighTiming
+ =
+ *pul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+ }
+
+ fpu_end();
+ /****************************/
+ /* Save the clock selection */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ b_ClockSelection
+ =
+ b_ClockSelection;
+
+ /************************/
+ /* Save the timing unit */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ b_TimingUnit
+ =
+ b_TimingUnit;
+
+ /****************************/
+ /* Save the low base timing */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ d_LowTiming
+ =
+ d_RealLowTiming;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ ul_RealLowTiming
+ =
+ *pul_RealLowTiming;
+
+ /****************************/
+ /* Save the high base timing */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ d_HighTiming
+ =
+ d_RealHighTiming;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ ul_RealHighTiming
+ =
+ *pul_RealHighTiming;
+
+ /************************/
+ /* Write the low timing */
+ /************************/
+
+ outl(ul_LowTimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /*************************/
+ /* Write the high timing */
+ /*************************/
+
+ outl(ul_HighTimerValue, devpriv->s_BoardInfos.ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /***************************/
+ /* Set the clock selection */
+ /***************************/
+
+ dw_Command
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 8
+ +
+ (20 * b_PWM) + (64 * b_ModulNbr));
+
+ dw_Command
+ =
+ dw_Command
+ &
+ 0x7F;
+
+ if (b_ClockSelection == APCI1710_40MHZ) {
+ dw_Command
+ =
+ dw_Command
+ |
+ 0x80;
+ }
+
+ /***************************/
+ /* Set the clock selection */
+ /***************************/
+
+ outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /*************/
+ /* PWM init. */
+ /*************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ b_PWMInit
+ =
+ 1;
+ } else {
+ /***************************************************/
+ /* You can not used the 40MHz clock selection with */
+ /* this board */
+ /***************************************************/
+ DPRINTK("You can not used the 40MHz clock selection with this board\n");
+ i_ReturnValue
+ =
+ -9;
+ }
+ } else {
+ /***************************************/
+ /* High base timing selection is wrong */
+ /***************************************/
+ DPRINTK("High base timing selection is wrong\n");
+ i_ReturnValue =
+ -8;
+ }
+ } else {
+ /**************************************/
+ /* Low base timing selection is wrong */
+ /**************************************/
+ DPRINTK("Low base timing selection is wrong\n");
+ i_ReturnValue = -7;
+ }
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ else {
+ /**********************************/
+ /* Timing unit selection is wrong */
+ /**********************************/
+ DPRINTK("Timing unit selection is wrong\n");
+ i_ReturnValue = -6;
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ } // if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ))
+ else {
+ /*******************************/
+ /* The selected clock is wrong */
+ /*******************************/
+ DPRINTK("The selected clock is wrong\n");
+ i_ReturnValue = -5;
+ } // if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ))
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ } else {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetPWMInitialisation |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| PBYTE_ pb_TimingUnit, |
+| PULONG_ pul_LowTiming, |
+| PULONG_ pul_HighTiming, |
+| PBYTE_ pb_StartLevel, |
+| PBYTE_ pb_StopMode, |
+| PBYTE_ pb_StopLevel, |
+| PBYTE_ pb_ExternGate, |
+| PBYTE_ pb_InterruptEnable, |
+| PBYTE_ pb_Enable) |
++----------------------------------------------------------------------------+
+| Task : Return the PWM (b_PWM) initialisation from selected |
+| module (b_ModulNbr). You must calling the |
+| "i_APCI1710_InitPWM" function be for you call this |
+| function. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TimingUnit : Base timing Unit (0 to 4) |
+| 0 : ns |
+| 1 : æs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| PULONG_ pul_LowTiming : Low base timing value. |
+| PULONG_ pul_HighTiming : High base timing value. |
+| PBYTE_ pb_StartLevel : Start period level |
+| selection |
+| 0 : The period start |
+| with a low level |
+| 1 : The period start |
+| with a high level|
+| PBYTE_ pb_StopMode : Stop mode selection |
+| 0 : The PWM is stopped |
+| directly after the |
+| "i_APCI1710_DisablePWM"|
+| function and break the|
+| last period |
+| 1 : After the |
+| "i_APCI1710_DisablePWM"|
+| function the PWM is |
+| stopped at the end |
+| from last period cycle|
+| PBYTE_ pb_StopLevel : Stop PWM level selection |
+| 0 : The output signal |
+| keep the level after|
+| the |
+| "i_APCI1710_DisablePWM"|
+| function |
+| 1 : The output signal is|
+| set to low after the|
+| "i_APCI1710_DisablePWM"|
+| function |
+| 2 : The output signal is|
+| set to high after |
+| the |
+| "i_APCI1710_DisablePWM"|
+| function |
+| PBYTE_ pb_ExternGate : Extern gate action |
+| selection |
+| 0 : Extern gate signal |
+| not used. |
+| 1 : Extern gate signal |
+| used. |
+| PBYTE_ pb_InterruptEnable : Enable or disable the PWM |
+| interrupt. |
+| - APCI1710_ENABLE : |
+| Enable the PWM interrupt|
+| A interrupt occur after |
+| each period |
+| - APCI1710_DISABLE : |
+| Disable the PWM |
+| interrupt |
+| PBYTE_ pb_Enable : Indicate if the PWM is |
+| enabled or no |
+| 0 : PWM not enabled |
+| 1 : PWM enabled |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised see function |
+| "i_APCI1710_InitPWM" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetPWMInitialisation(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ PBYTE pb_TimingUnit,
+ PULONG pul_LowTiming,
+ PULONG pul_HighTiming,
+ PBYTE pb_StartLevel,
+ PBYTE pb_StopMode,
+ PBYTE pb_StopLevel,
+ PBYTE pb_ExternGate, PBYTE pb_InterruptEnable, PBYTE pb_Enable)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ DWORD dw_Command;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM <= 1) {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ /***********************/
+ /* Read the low timing */
+ /***********************/
+
+ *pul_LowTiming =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 0 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ /************************/
+ /* Read the high timing */
+ /************************/
+
+ *pul_HighTiming =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 4 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ /********************/
+ /* Read the command */
+ /********************/
+
+ dw_Command = inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ *pb_StartLevel =
+ (BYTE) ((dw_Command >> 5) & 1);
+ *pb_StopMode =
+ (BYTE) ((dw_Command >> 0) & 1);
+ *pb_StopLevel =
+ (BYTE) ((dw_Command >> 1) & 1);
+ *pb_ExternGate =
+ (BYTE) ((dw_Command >> 4) & 1);
+ *pb_InterruptEnable =
+ (BYTE) ((dw_Command >> 3) & 1);
+
+ if (*pb_StopLevel) {
+ *pb_StopLevel =
+ *pb_StopLevel +
+ (BYTE) ((dw_Command >>
+ 2) & 1);
+ }
+
+ /********************/
+ /* Read the command */
+ /********************/
+
+ dw_Command = inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ *pb_Enable =
+ (BYTE) ((dw_Command >> 0) & 1);
+
+ *pb_TimingUnit = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo[b_PWM].b_TimingUnit;
+ } // if (dw_Status & 0x10)
+ else {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+ DPRINTK("PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ } else {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnWritePWM(struct comedi_device *dev,
+struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Pwm Enable Disable and Set New Timing |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWritePWM(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_WriteType;
+ INT i_ReturnValue = 0;
+ b_WriteType = CR_CHAN(insn->chanspec);
+
+ switch (b_WriteType) {
+ case APCI1710_PWM_ENABLE:
+ i_ReturnValue = i_APCI1710_EnablePWM(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) data[0],
+ (BYTE) data[1],
+ (BYTE) data[2],
+ (BYTE) data[3], (BYTE) data[4], (BYTE) data[5]);
+ break;
+
+ case APCI1710_PWM_DISABLE:
+ i_ReturnValue = i_APCI1710_DisablePWM(dev,
+ (BYTE) CR_AREF(insn->chanspec), (BYTE) data[0]);
+ break;
+
+ case APCI1710_PWM_NEWTIMING:
+ i_ReturnValue = i_APCI1710_SetNewPWMTiming(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) data[0],
+ (BYTE) data[1], (ULONG) data[2], (ULONG) data[3]);
+ break;
+
+ default:
+ printk("Write Config Parameter Wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnablePWM |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| BYTE_ b_StartLevel, |
+| BYTE_ b_StopMode, |
+| BYTE_ b_StopLevel, |
+| BYTE_ b_ExternGate, |
+| BYTE_ b_InterruptEnable) |
++----------------------------------------------------------------------------+
+| Task : Enable the selected PWM (b_PWM) from selected module |
+| (b_ModulNbr). You must calling the "i_APCI1710_InitPWM"|
+| function be for you call this function. |
+| If you enable the PWM interrupt, the PWM generate a |
+| interrupt after each period. |
+| See function "i_APCI1710_SetBoardIntRoutineX" and the |
+| Interrupt mask description chapter. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1) |
+| BYTE_ b_StartLevel : Start period level selection |
+| 0 : The period start with a |
+| low level |
+| 1 : The period start with a |
+| high level |
+| BYTE_ b_StopMode : Stop mode selection |
+| 0 : The PWM is stopped |
+| directly after the |
+| "i_APCI1710_DisablePWM" |
+| function and break the |
+| last period |
+| 1 : After the |
+| "i_APCI1710_DisablePWM" |
+| function the PWM is |
+| stopped at the end from|
+| last period cycle. |
+| BYTE_ b_StopLevel : Stop PWM level selection |
+| 0 : The output signal keep |
+| the level after the |
+| "i_APCI1710_DisablePWM" |
+| function |
+| 1 : The output signal is set|
+| to low after the |
+| "i_APCI1710_DisablePWM" |
+| function |
+| 2 : The output signal is set|
+| to high after the |
+| "i_APCI1710_DisablePWM" |
+| function |
+| BYTE_ b_ExternGate : Extern gate action selection |
+| 0 : Extern gate signal not |
+| used. |
+| 1 : Extern gate signal used.|
+| BYTE_ b_InterruptEnable : Enable or disable the PWM |
+| interrupt. |
+| - APCI1710_ENABLE : |
+| Enable the PWM interrupt |
+| A interrupt occur after |
+| each period |
+| - APCI1710_DISABLE : |
+| Disable the PWM interrupt |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised see function |
+| "i_APCI1710_InitPWM" |
+| -6: PWM start level selection is wrong |
+| -7: PWM stop mode selection is wrong |
+| -8: PWM stop level selection is wrong |
+| -9: Extern gate signal selection is wrong |
+| -10: Interrupt parameter is wrong |
+| -11: Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_EnablePWM(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_StartLevel,
+ BYTE b_StopMode,
+ BYTE b_StopLevel, BYTE b_ExternGate, BYTE b_InterruptEnable)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ DWORD dw_Command;
+
+ devpriv->tsk_Current = current; // Save the current process task structure
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM <= 1) {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ /**********************************/
+ /* Test the start level selection */
+ /**********************************/
+
+ if (b_StartLevel <= 1) {
+ /**********************/
+ /* Test the stop mode */
+ /**********************/
+
+ if (b_StopMode <= 1) {
+ /***********************/
+ /* Test the stop level */
+ /***********************/
+
+ if (b_StopLevel <= 2) {
+ /*****************************/
+ /* Test the extern gate mode */
+ /*****************************/
+
+ if (b_ExternGate
+ <= 1) {
+ /*****************************/
+ /* Test the interrupt action */
+ /*****************************/
+
+ if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE) {
+ /******************************************/
+ /* Test if interrupt function initialised */
+ /******************************************/
+
+ /********************/
+ /* Read the command */
+ /********************/
+
+ dw_Command
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 8
+ +
+ (20 * b_PWM) + (64 * b_ModulNbr));
+
+ dw_Command
+ =
+ dw_Command
+ &
+ 0x80;
+
+ /********************/
+ /* Make the command */
+ /********************/
+
+ dw_Command
+ =
+ dw_Command
+ |
+ b_StopMode
+ |
+ (b_InterruptEnable
+ <<
+ 3)
+ |
+ (b_ExternGate
+ <<
+ 4)
+ |
+ (b_StartLevel
+ <<
+ 5);
+
+ if (b_StopLevel & 3) {
+ dw_Command
+ =
+ dw_Command
+ |
+ 2;
+
+ if (b_StopLevel & 2) {
+ dw_Command
+ =
+ dw_Command
+ |
+ 4;
+ }
+ }
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ b_InterruptEnable
+ =
+ b_InterruptEnable;
+
+ /*******************/
+ /* Set the command */
+ /*******************/
+
+ outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /******************/
+ /* Enable the PWM */
+ /******************/
+ outl(1, devpriv->s_BoardInfos.ui_Address + 12 + (20 * b_PWM) + (64 * b_ModulNbr));
+ } // if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE)
+ else {
+ /********************************/
+ /* Interrupt parameter is wrong */
+ /********************************/
+ DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue
+ =
+ -10;
+ } // if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE)
+ } // if (b_ExternGate >= 0 && b_ExternGate <= 1)
+ else {
+ /*****************************************/
+ /* Extern gate signal selection is wrong */
+ /*****************************************/
+ DPRINTK("Extern gate signal selection is wrong\n");
+ i_ReturnValue
+ =
+ -9;
+ } // if (b_ExternGate >= 0 && b_ExternGate <= 1)
+ } // if (b_StopLevel >= 0 && b_StopLevel <= 2)
+ else {
+ /*************************************/
+ /* PWM stop level selection is wrong */
+ /*************************************/
+ DPRINTK("PWM stop level selection is wrong\n");
+ i_ReturnValue =
+ -8;
+ } // if (b_StopLevel >= 0 && b_StopLevel <= 2)
+ } // if (b_StopMode >= 0 && b_StopMode <= 1)
+ else {
+ /************************************/
+ /* PWM stop mode selection is wrong */
+ /************************************/
+ DPRINTK("PWM stop mode selection is wrong\n");
+ i_ReturnValue = -7;
+ } // if (b_StopMode >= 0 && b_StopMode <= 1)
+ } // if (b_StartLevel >= 0 && b_StartLevel <= 1)
+ else {
+ /**************************************/
+ /* PWM start level selection is wrong */
+ /**************************************/
+ DPRINTK("PWM start level selection is wrong\n");
+ i_ReturnValue = -6;
+ } // if (b_StartLevel >= 0 && b_StartLevel <= 1)
+ } // if (dw_Status & 0x10)
+ else {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+ DPRINTK("PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ } else {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_DisablePWM (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM) |
++----------------------------------------------------------------------------+
+| Task : Disable the selected PWM (b_PWM) from selected module |
+| (b_ModulNbr). The output signal level depend of the |
+| initialisation by the "i_APCI1710_EnablePWM". |
+| See the b_StartLevel, b_StopMode and b_StopLevel |
+| parameters from this function. |
++----------------------------------------------------------------------------+
+| Input Parameters :BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised see function |
+| "i_APCI1710_InitPWM" |
+| -6: PWM not enabled see function |
+| "i_APCI1710_EnablePWM" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_DisablePWM(struct comedi_device * dev, BYTE b_ModulNbr, BYTE b_PWM)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM <= 1) {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ /***********************/
+ /* Test if PWM enabled */
+ /***********************/
+
+ if (dw_Status & 0x1) {
+ /*******************/
+ /* Disable the PWM */
+ /*******************/
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 12 +
+ (20 * b_PWM) +
+ (64 * b_ModulNbr));
+ } // if (dw_Status & 0x1)
+ else {
+ /*******************/
+ /* PWM not enabled */
+ /*******************/
+ DPRINTK("PWM not enabled\n");
+ i_ReturnValue = -6;
+ } // if (dw_Status & 0x1)
+ } // if (dw_Status & 0x10)
+ else {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+ DPRINTK(" PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ } else {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetNewPWMTiming |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| BYTE_ b_ClockSelection, |
+| BYTE_ b_TimingUnit, |
+| ULONG_ ul_LowTiming, |
+| ULONG_ ul_HighTiming) |
++----------------------------------------------------------------------------+
+| Task : Set a new timing. The ul_LowTiming, ul_HighTiming and |
+| ul_TimingUnit determine the low/high timing base for |
+| the period. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure|
+| (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1). |
+| BYTE_ b_TimingUnit : Base timing Unit (0 to 4) |
+| 0 : ns |
+| 1 : æs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| ULONG_ ul_LowTiming : Low base timing value. |
+| ULONG_ ul_HighTiming : High base timing value. |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised |
+| -6: Timing Unit selection is wrong |
+| -7: Low base timing selection is wrong |
+| -8: High base timing selection is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetNewPWMTiming(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM, BYTE b_TimingUnit, ULONG ul_LowTiming, ULONG ul_HighTiming)
+{
+ BYTE b_ClockSelection;
+ INT i_ReturnValue = 0;
+ ULONG ul_LowTimerValue = 0;
+ ULONG ul_HighTimerValue = 0;
+ ULONG ul_RealLowTiming = 0;
+ ULONG ul_RealHighTiming = 0;
+ DWORD dw_Status;
+ DWORD dw_Command;
+ double d_RealLowTiming = 0;
+ double d_RealHighTiming = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM <= 1) {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ b_ClockSelection = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PWMModuleInfo.
+ b_ClockSelection;
+
+ /************************/
+ /* Test the timing unit */
+ /************************/
+
+ if (b_TimingUnit <= 4) {
+ /*********************************/
+ /* Test the low timing selection */
+ /*********************************/
+
+ if (((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 0)
+ && (ul_LowTiming
+ >= 266)
+ && (ul_LowTiming
+ <=
+ 0xFFFFFFFFUL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 1)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 571230650UL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 2)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 571230UL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 3)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 571UL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 4)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <= 9UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 0)
+ && (ul_LowTiming
+ >= 242)
+ && (ul_LowTiming
+ <=
+ 0xFFFFFFFFUL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 1)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 519691043UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 2)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 519691UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 3)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 520UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 4)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <= 8UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 0)
+ && (ul_LowTiming
+ >= 200)
+ && (ul_LowTiming
+ <=
+ 0xFFFFFFFFUL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 1)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 429496729UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 2)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 429496UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 3)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 429UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 4)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 7UL))) {
+ /**********************************/
+ /* Test the High timing selection */
+ /**********************************/
+
+ if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 266) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230650UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 9UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 242) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691043UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 520UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 8UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 200) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496729UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 7UL))) {
+ /************************************/
+ /* Calculate the low division fator */
+ /************************************/
+
+ fpu_begin();
+ switch (b_TimingUnit) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (ul_LowTiming
+ *
+ (0.00025 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (0.00025 * (double)b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (0.00025
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
+ ul_RealLowTiming
+ =
+ ul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (ul_LowTiming
+ *
+ (0.25 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (0.25 * (double)b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (
+ (double)
+ 0.25
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
+ ul_RealLowTiming
+ =
+ ul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ ul_LowTiming
+ *
+ (250.0
+ *
+ b_ClockSelection);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (250.0 * (double)b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (250.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
+ ul_RealLowTiming
+ =
+ ul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (ul_LowTiming
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
+ ul_RealLowTiming
+ =
+ ul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (ul_LowTiming
+ *
+ 60)
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)(ul_LowTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60;
+ d_RealLowTiming
+ =
+ (
+ (double)
+ ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60.0;
+
+ if ((double)(((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)ul_RealLowTiming + 0.5)) {
+ ul_RealLowTiming
+ =
+ ul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+ }
+
+ /*************************************/
+ /* Calculate the high division fator */
+ /*************************************/
+
+ switch (b_TimingUnit) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (ul_HighTiming
+ *
+ (0.00025 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (0.00025 * (double)b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (0.00025
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
+ ul_RealHighTiming
+ =
+ ul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (ul_HighTiming
+ *
+ (0.25 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (0.25 * (double)b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (
+ (double)
+ 0.25
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
+ ul_RealHighTiming
+ =
+ ul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ ul_HighTiming
+ *
+ (250.0
+ *
+ b_ClockSelection);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (250.0 * (double)b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (250.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
+ ul_RealHighTiming
+ =
+ ul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (ul_HighTiming
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
+ ul_RealHighTiming
+ =
+ ul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (ul_HighTiming
+ *
+ 60)
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)(ul_HighTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60;
+ d_RealHighTiming
+ =
+ (
+ (double)
+ ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60.0;
+
+ if ((double)(((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)ul_RealHighTiming + 0.5)) {
+ ul_RealHighTiming
+ =
+ ul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+ }
+
+ fpu_end();
+
+ /************************/
+ /* Save the timing unit */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ b_TimingUnit
+ =
+ b_TimingUnit;
+
+ /****************************/
+ /* Save the low base timing */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ d_LowTiming
+ =
+ d_RealLowTiming;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ ul_RealLowTiming
+ =
+ ul_RealLowTiming;
+
+ /****************************/
+ /* Save the high base timing */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ d_HighTiming
+ =
+ d_RealHighTiming;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ ul_RealHighTiming
+ =
+ ul_RealHighTiming;
+
+ /************************/
+ /* Write the low timing */
+ /************************/
+
+ outl(ul_LowTimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /*************************/
+ /* Write the high timing */
+ /*************************/
+
+ outl(ul_HighTimerValue, devpriv->s_BoardInfos.ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /***************************/
+ /* Set the clock selection */
+ /***************************/
+
+ dw_Command =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 8 +
+ (20 * b_PWM) + (64 * b_ModulNbr));
+
+ dw_Command =
+ dw_Command
+ & 0x7F;
+
+ if (b_ClockSelection == APCI1710_40MHZ) {
+ dw_Command
+ =
+ dw_Command
+ |
+ 0x80;
+ }
+
+ /***************************/
+ /* Set the clock selection */
+ /***************************/
+
+ outl(dw_Command,
+ devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 8 +
+ (20 * b_PWM) + (64 * b_ModulNbr));
+ } else {
+ /***************************************/
+ /* High base timing selection is wrong */
+ /***************************************/
+ DPRINTK("High base timing selection is wrong\n");
+ i_ReturnValue =
+ -8;
+ }
+ } else {
+ /**************************************/
+ /* Low base timing selection is wrong */
+ /**************************************/
+ DPRINTK("Low base timing selection is wrong\n");
+ i_ReturnValue = -7;
+ }
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ else {
+ /**********************************/
+ /* Timing unit selection is wrong */
+ /**********************************/
+ DPRINTK("Timing unit selection is wrong\n");
+ i_ReturnValue = -6;
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ } // if (dw_Status & 0x10)
+ else {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+ DPRINTK("PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ } else {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetPWMStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| PBYTE_ pb_PWMOutputStatus, |
+| PBYTE_ pb_ExternGateStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the status from selected PWM (b_PWM) from |
+| selected module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_PWM : Selected PWM (0 or 1) |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);
+ b_PWM =(BYTE) data[0];
+
+ |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_PWMOutputStatus : Return the PWM output |
+| level status. |
+| 0 : The PWM output level|
+| is low. |
+| 1 : The PWM output level|
+| is high. |
+| PBYTE_ pb_ExternGateStatus : Return the extern gate |
+| level status. |
+| 0 : The extern gate is |
+| low. |
+| 1 : The extern gate is |
+| high.
+ pb_PWMOutputStatus =(PBYTE) data[0];
+ pb_ExternGateStatus =(PBYTE) data[1]; |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised see function |
+| "i_APCI1710_InitPWM" |
+| -6: PWM not enabled see function "i_APCI1710_EnablePWM"|
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadGetPWMStatus(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+
+ BYTE b_ModulNbr;
+ BYTE b_PWM;
+ PBYTE pb_PWMOutputStatus;
+ PBYTE pb_ExternGateStatus;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_PWM = (BYTE) CR_CHAN(insn->chanspec);
+ pb_PWMOutputStatus = (PBYTE) & data[0];
+ pb_ExternGateStatus = (PBYTE) & data[1];
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM <= 1) {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ /***********************/
+ /* Test if PWM enabled */
+ /***********************/
+
+ if (dw_Status & 0x1) {
+ *pb_PWMOutputStatus =
+ (BYTE) ((dw_Status >> 7)
+ & 1);
+ *pb_ExternGateStatus =
+ (BYTE) ((dw_Status >> 6)
+ & 1);
+ } // if (dw_Status & 0x1)
+ else {
+ /*******************/
+ /* PWM not enabled */
+ /*******************/
+
+ DPRINTK("PWM not enabled \n");
+ i_ReturnValue = -6;
+ } // if (dw_Status & 0x1)
+ } // if (dw_Status & 0x10)
+ else {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+
+ DPRINTK("PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ } else {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+INT i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ return insn->n;
+
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h
new file mode 100644
index 00000000000..c1b7f4ca47c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
+
+#define APCI1710_PWM_INIT 0
+#define APCI1710_PWM_GETINITDATA 1
+
+#define APCI1710_PWM_DISABLE 0
+#define APCI1710_PWM_ENABLE 1
+#define APCI1710_PWM_NEWTIMING 2
+
+INT i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InitPWM(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_ClockSelection,
+ BYTE b_TimingUnit,
+ ULONG ul_LowTiming,
+ ULONG ul_HighTiming,
+ PULONG pul_RealLowTiming, PULONG pul_RealHighTiming);
+
+INT i_APCI1710_GetPWMInitialisation(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ PBYTE pb_TimingUnit,
+ PULONG pul_LowTiming,
+ PULONG pul_HighTiming,
+ PBYTE pb_StartLevel,
+ PBYTE pb_StopMode,
+ PBYTE pb_StopLevel,
+ PBYTE pb_ExternGate,
+ PBYTE pb_InterruptEnable, PBYTE pb_Enable);
+
+INT i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_EnablePWM(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_StartLevel,
+ BYTE b_StopMode,
+ BYTE b_StopLevel, BYTE b_ExternGate,
+ BYTE b_InterruptEnable);
+
+INT i_APCI1710_SetNewPWMTiming(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM, BYTE b_TimingUnit,
+ ULONG ul_LowTiming, ULONG ul_HighTiming);
+
+INT i_APCI1710_DisablePWM(struct comedi_device *dev, BYTE b_ModulNbr, BYTE b_PWM);
+
+INT i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
new file mode 100644
index 00000000000..bb6e1622e37
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
@@ -0,0 +1,848 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : SSI.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 SSI counter module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 13/05/98 | S. Weber | SSI digital input / output implementation |
+ |----------|-----------|------------------------------------------------|
+ | 22/03/00 | C.Guinot | 0100/0226 -> 0200/0227 |
+ | | | Änderung in InitSSI Funktion |
+ | | | b_SSIProfile >= 2 anstatt b_SSIProfile > 2 |
+ | | | |
+ +-----------------------------------------------------------------------+
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Ssi.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitSSI |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_SSIProfile, |
+| BYTE_ b_PositionTurnLength, |
+| BYTE_ b_TurnCptLength, |
+| BYTE_ b_PCIInputClock, |
+| ULONG_ ul_SSIOutputClock, |
+| BYTE_ b_SSICountingMode) |
++----------------------------------------------------------------------------+
+| Task : Configure the SSI operating mode from selected module |
+| (b_ModulNbr). You must calling this function be for you|
+| call any other function witch access of SSI. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_SSIProfile : Selection from SSI |
+| profile length (2 to 32).|
+| BYTE_ b_PositionTurnLength : Selection from SSI |
+| position data length |
+| (1 to 31). |
+| BYTE_ b_TurnCptLength : Selection from SSI turn |
+| counter data length |
+| (1 to 31). |
+| BYTE b_PCIInputClock : Selection from PCI bus |
+| clock |
+| - APCI1710_30MHZ : |
+| The PC have a PCI bus |
+| clock from 30 MHz |
+| - APCI1710_33MHZ : |
+| The PC have a PCI bus |
+| clock from 33 MHz |
+| ULONG_ ul_SSIOutputClock : Selection from SSI output|
+| clock. |
+| From 229 to 5 000 000 Hz|
+| for 30 MHz selection. |
+| From 252 to 5 000 000 Hz|
+| for 33 MHz selection. |
+| BYTE b_SSICountingMode : SSI counting mode |
+| selection |
+| - APCI1710_BINARY_MODE : |
+| Binary counting mode. |
+| - APCI1710_GRAY_MODE : |
+| Gray counting mode.
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_SSIProfile = (BYTE) data[0];
+ b_PositionTurnLength= (BYTE) data[1];
+ b_TurnCptLength = (BYTE) data[2];
+ b_PCIInputClock = (BYTE) data[3];
+ ul_SSIOutputClock = (ULONG) data[4];
+ b_SSICountingMode = (BYTE) data[5]; |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a SSI module |
+| -4: The selected SSI profile length is wrong |
+| -5: The selected SSI position data length is wrong |
+| -6: The selected SSI turn counter data length is wrong |
+| -7: The selected PCI input clock is wrong |
+| -8: The selected SSI output clock is wrong |
+| -9: The selected SSI counting mode parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitSSI(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ UINT ui_TimerValue;
+ BYTE b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength,
+ b_PCIInputClock, b_SSICountingMode;
+ ULONG ul_SSIOutputClock;
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_SSIProfile = (BYTE) data[0];
+ b_PositionTurnLength = (BYTE) data[1];
+ b_TurnCptLength = (BYTE) data[2];
+ b_PCIInputClock = (BYTE) data[3];
+ ul_SSIOutputClock = (ULONG) data[4];
+ b_SSICountingMode = (BYTE) data[5];
+
+ i_ReturnValue = insn->n;
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if SSI counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
+ /*******************************/
+ /* Test the SSI profile length */
+ /*******************************/
+
+ // CG 22/03/00 b_SSIProfile >= 2 anstatt b_SSIProfile > 2
+ if (b_SSIProfile >= 2 && b_SSIProfile < 33) {
+ /*************************************/
+ /* Test the SSI position data length */
+ /*************************************/
+
+ if (b_PositionTurnLength > 0
+ && b_PositionTurnLength < 32) {
+ /*****************************************/
+ /* Test the SSI turn counter data length */
+ /*****************************************/
+
+ if (b_TurnCptLength > 0
+ && b_TurnCptLength < 32) {
+ /***************************/
+ /* Test the profile length */
+ /***************************/
+
+ if ((b_TurnCptLength +
+ b_PositionTurnLength)
+ <= b_SSIProfile) {
+ /****************************/
+ /* Test the PCI input clock */
+ /****************************/
+
+ if (b_PCIInputClock ==
+ APCI1710_30MHZ
+ ||
+ b_PCIInputClock
+ ==
+ APCI1710_33MHZ)
+ {
+ /*************************/
+ /* Test the output clock */
+ /*************************/
+
+ if ((b_PCIInputClock == APCI1710_30MHZ && (ul_SSIOutputClock > 228 && ul_SSIOutputClock <= 5000000UL)) || (b_PCIInputClock == APCI1710_33MHZ && (ul_SSIOutputClock > 251 && ul_SSIOutputClock <= 5000000UL))) {
+ if (b_SSICountingMode == APCI1710_BINARY_MODE || b_SSICountingMode == APCI1710_GRAY_MODE) {
+ /**********************/
+ /* Save configuration */
+ /**********************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_SSIProfile
+ =
+ b_SSIProfile;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_PositionTurnLength
+ =
+ b_PositionTurnLength;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_TurnCptLength
+ =
+ b_TurnCptLength;
+
+ /*********************************/
+ /* Initialise the profile length */
+ /*********************************/
+
+ if (b_SSICountingMode == APCI1710_BINARY_MODE) {
+
+ outl(b_SSIProfile + 1, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
+ } else {
+
+ outl(b_SSIProfile, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
+ }
+
+ /******************************/
+ /* Calculate the output clock */
+ /******************************/
+
+ ui_TimerValue
+ =
+ (UINT)
+ (
+ ((ULONG) (b_PCIInputClock) * 500000UL) / ul_SSIOutputClock);
+
+ /************************/
+ /* Initialise the timer */
+ /************************/
+
+ outl(ui_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
+
+ /********************************/
+ /* Initialise the counting mode */
+ /********************************/
+
+ outl(7 * b_SSICountingMode, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_SSIInit
+ =
+ 1;
+ } else {
+ /*****************************************************/
+ /* The selected SSI counting mode parameter is wrong */
+ /*****************************************************/
+
+ DPRINTK("The selected SSI counting mode parameter is wrong\n");
+ i_ReturnValue
+ =
+ -9;
+ }
+ } else {
+ /******************************************/
+ /* The selected SSI output clock is wrong */
+ /******************************************/
+
+ DPRINTK("The selected SSI output clock is wrong\n");
+ i_ReturnValue
+ =
+ -8;
+ }
+ } else {
+ /*****************************************/
+ /* The selected PCI input clock is wrong */
+ /*****************************************/
+
+ DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue =
+ -7;
+ }
+ } else {
+ /********************************************/
+ /* The selected SSI profile length is wrong */
+ /********************************************/
+
+ DPRINTK("The selected SSI profile length is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************************/
+ /* The selected SSI turn counter data length is wrong */
+ /******************************************************/
+
+ DPRINTK("The selected SSI turn counter data length is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /**************************************************/
+ /* The selected SSI position data length is wrong */
+ /**************************************************/
+
+ DPRINTK("The selected SSI position data length is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /********************************************/
+ /* The selected SSI profile length is wrong */
+ /********************************************/
+
+ DPRINTK("The selected SSI profile length is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /**********************************/
+ /* The module is not a SSI module */
+ /**********************************/
+
+ DPRINTK("The module is not a SSI module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_Read1SSIValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_SelectedSSI, |
+| PULONG_ pul_Position, |
+| PULONG_ pul_TurnCpt)
+ INT i_APCI1710_ReadSSIValue(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task :
+
+
+ Read the selected SSI counter (b_SelectedSSI) from |
+| selected module (b_ModulNbr).
+ or Read all SSI counter (b_SelectedSSI) from |
+| selected module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_SelectedSSI : Selection from SSI |
+| counter (0 to 2)
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_SelectedSSI = (BYTE) CR_CHAN(insn->chanspec); (in case of single ssi)
+ b_ReadType = (BYTE) CR_RANGE(insn->chanspec);
+|
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_Position : SSI position in the turn |
+| PULONG_ pul_TurnCpt : Number of turns
+
+pul_Position = (PULONG) &data[0];
+ pul_TurnCpt = (PULONG) &data[1]; |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a SSI module |
+| -4: SSI not initialised see function |
+| "i_APCI1710_InitSSI" |
+| -5: The selected SSI is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadSSIValue(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ BYTE b_Cpt;
+ BYTE b_Length;
+ BYTE b_Schift;
+ BYTE b_SSICpt;
+ DWORD dw_And;
+ DWORD dw_And1;
+ DWORD dw_And2;
+ DWORD dw_StatusReg;
+ DWORD dw_CounterValue;
+ BYTE b_ModulNbr;
+ BYTE b_SelectedSSI;
+ BYTE b_ReadType;
+ PULONG pul_Position;
+ PULONG pul_TurnCpt;
+ PULONG pul_Position1;
+ PULONG pul_TurnCpt1;
+
+ i_ReturnValue = insn->n;
+ pul_Position1 = (PULONG) & data[0];
+// For Read1
+ pul_TurnCpt1 = (PULONG) & data[1];
+// For Read all
+ pul_Position = (PULONG) & data[0]; //0-2
+ pul_TurnCpt = (PULONG) & data[3]; //3-5
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_SelectedSSI = (BYTE) CR_CHAN(insn->chanspec);
+ b_ReadType = (BYTE) CR_RANGE(insn->chanspec);
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if SSI counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
+ /***************************/
+ /* Test if SSI initialised */
+ /***************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SSICounterInfo.b_SSIInit == 1) {
+
+ switch (b_ReadType) {
+
+ case APCI1710_SSI_READ1VALUE:
+ /****************************************/
+ /* Test the selected SSI counter number */
+ /****************************************/
+
+ if (b_SelectedSSI < 3) {
+ /************************/
+ /* Start the conversion */
+ /************************/
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 8 +
+ (64 * b_ModulNbr));
+
+ do {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ dw_StatusReg =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (64 * b_ModulNbr));
+ }
+ while ((dw_StatusReg & 0x1) !=
+ 0);
+
+ /******************************/
+ /* Read the SSI counter value */
+ /******************************/
+
+ dw_CounterValue =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 4 +
+ (b_SelectedSSI * 4) +
+ (64 * b_ModulNbr));
+
+ b_Length =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_SSIProfile / 2;
+
+ if ((b_Length * 2) !=
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_SSIProfile) {
+ b_Length++;
+ }
+
+ b_Schift =
+ b_Length -
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_PositionTurnLength;
+
+ *pul_Position1 =
+ dw_CounterValue >>
+ b_Schift;
+
+ dw_And = 1;
+
+ for (b_Cpt = 0;
+ b_Cpt <
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_PositionTurnLength;
+ b_Cpt++) {
+ dw_And = dw_And * 2;
+ }
+
+ *pul_Position1 =
+ *pul_Position1 &
+ ((dw_And) - 1);
+
+ *pul_TurnCpt1 =
+ dw_CounterValue >>
+ b_Length;
+
+ dw_And = 1;
+
+ for (b_Cpt = 0;
+ b_Cpt <
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_TurnCptLength;
+ b_Cpt++) {
+ dw_And = dw_And * 2;
+ }
+
+ *pul_TurnCpt1 =
+ *pul_TurnCpt1 &
+ ((dw_And) - 1);
+ } else {
+ /*****************************/
+ /* The selected SSI is wrong */
+ /*****************************/
+
+ DPRINTK("The selected SSI is wrong\n");
+ i_ReturnValue = -5;
+ }
+ break;
+
+ case APCI1710_SSI_READALLVALUE:
+ dw_And1 = 1;
+
+ for (b_Cpt = 0;
+ b_Cpt <
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SSICounterInfo.
+ b_PositionTurnLength; b_Cpt++) {
+ dw_And1 = dw_And1 * 2;
+ }
+
+ dw_And2 = 1;
+
+ for (b_Cpt = 0;
+ b_Cpt <
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SSICounterInfo.
+ b_TurnCptLength; b_Cpt++) {
+ dw_And2 = dw_And2 * 2;
+ }
+
+ /************************/
+ /* Start the conversion */
+ /************************/
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 8 +
+ (64 * b_ModulNbr));
+
+ do {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ dw_StatusReg =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (64 * b_ModulNbr));
+ }
+ while ((dw_StatusReg & 0x1) != 0);
+
+ for (b_SSICpt = 0; b_SSICpt < 3;
+ b_SSICpt++) {
+ /******************************/
+ /* Read the SSI counter value */
+ /******************************/
+
+ dw_CounterValue =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 4 +
+ (b_SSICpt * 4) +
+ (64 * b_ModulNbr));
+
+ b_Length =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_SSIProfile / 2;
+
+ if ((b_Length * 2) !=
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_SSIProfile) {
+ b_Length++;
+ }
+
+ b_Schift =
+ b_Length -
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_PositionTurnLength;
+
+ pul_Position[b_SSICpt] =
+ dw_CounterValue >>
+ b_Schift;
+ pul_Position[b_SSICpt] =
+ pul_Position[b_SSICpt] &
+ ((dw_And1) - 1);
+
+ pul_TurnCpt[b_SSICpt] =
+ dw_CounterValue >>
+ b_Length;
+ pul_TurnCpt[b_SSICpt] =
+ pul_TurnCpt[b_SSICpt] &
+ ((dw_And2) - 1);
+ }
+ break;
+
+ default:
+ printk("Read Type Inputs Wrong\n");
+
+ } // switch ending
+
+ } else {
+ /***********************/
+ /* SSI not initialised */
+ /***********************/
+
+ DPRINTK("SSI not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /**********************************/
+ /* The module is not a SSI module */
+ /**********************************/
+
+ DPRINTK("The module is not a SSI module\n");
+ i_ReturnValue = -3;
+
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadSSI1DigitalInput |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_InputChannel, |
+| PBYTE_ pb_ChannelStatus) |
++----------------------------------------------------------------------------+
+| Task :
+ (0) Set the digital output from selected SSI moule |
+| (b_ModuleNbr) ON
+ (1) Set the digital output from selected SSI moule |
+| (b_ModuleNbr) OFF
+ (2)Read the status from selected SSI digital input |
+| (b_InputChannel)
+ (3)Read the status from all SSI digital inputs from |
+| selected SSI module (b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr CR_AREF : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_InputChannel CR_CHAN : Selection from digital |
+| data[0] which IOTYPE input ( 0 to 2) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_ChannelStatus : Digital input channel |
+| data[0] status |
+| 0 : Channle is not active|
+| 1 : Channle is active |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a SSI module |
+| -4: The selected SSI digital input is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg;
+ BYTE b_ModulNbr;
+ BYTE b_InputChannel;
+ PBYTE pb_ChannelStatus;
+ PBYTE pb_InputStatus;
+ BYTE b_IOType;
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_IOType = (BYTE) data[0];
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if SSI counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
+ switch (b_IOType) {
+ case APCI1710_SSI_SET_CHANNELON:
+ /*****************************/
+ /* Set the digital output ON */
+ /*****************************/
+
+ outl(1, devpriv->s_BoardInfos.ui_Address + 16 +
+ (64 * b_ModulNbr));
+ break;
+
+ case APCI1710_SSI_SET_CHANNELOFF:
+ /******************************/
+ /* Set the digital output OFF */
+ /******************************/
+
+ outl(0, devpriv->s_BoardInfos.ui_Address + 16 +
+ (64 * b_ModulNbr));
+ break;
+
+ case APCI1710_SSI_READ_1CHANNEL:
+ /******************************************/
+ /* Test the digital imnput channel number */
+ /******************************************/
+
+ b_InputChannel = (BYTE) CR_CHAN(insn->chanspec);
+ pb_ChannelStatus = (PBYTE) & data[0];
+
+ if (b_InputChannel <= 2) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ dw_StatusReg =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+ *pb_ChannelStatus =
+ (BYTE) (((~dw_StatusReg) >> (4 +
+ b_InputChannel))
+ & 1);
+ } else {
+ /********************************/
+ /* Selected digital input error */
+ /********************************/
+
+ DPRINTK("Selected digital input error\n");
+ i_ReturnValue = -4;
+ }
+ break;
+
+ case APCI1710_SSI_READ_ALLCHANNEL:
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+ pb_InputStatus = (PBYTE) & data[0];
+
+ dw_StatusReg =
+ inl(devpriv->s_BoardInfos.ui_Address +
+ (64 * b_ModulNbr));
+ *pb_InputStatus =
+ (BYTE) (((~dw_StatusReg) >> 4) & 7);
+ break;
+
+ default:
+ printk("IO type wrong\n");
+
+ } //switch end
+ } else {
+ /**********************************/
+ /* The module is not a SSI module */
+ /**********************************/
+
+ DPRINTK("The module is not a SSI module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h
new file mode 100644
index 00000000000..88daad1a391
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
+
+#define APCI1710_BINARY_MODE 0x1
+#define APCI1710_GRAY_MODE 0x0
+
+#define APCI1710_SSI_READ1VALUE 1
+#define APCI1710_SSI_READALLVALUE 2
+
+#define APCI1710_SSI_SET_CHANNELON 0
+#define APCI1710_SSI_SET_CHANNELOFF 1
+#define APCI1710_SSI_READ_1CHANNEL 2
+#define APCI1710_SSI_READ_ALLCHANNEL 3
+
+/*
+ * SSI INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
new file mode 100644
index 00000000000..90316e10a3b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
@@ -0,0 +1,2049 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : TOR.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 tor counter module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 27/01/99 | S. Weber | 40 MHz implementation |
+ +-----------------------------------------------------------------------+
+ | 28/04/00 | S. Weber | Simple,double and quadruple mode implementation|
+ | | | Extern clock implementation |
+ +-----------------------------------------------------------------------+
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Tor.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitTorCounter |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TorCounter, |
+| BYTE_ b_PCIInputClock, |
+| BYTE_ b_TimingUnit, |
+| ULONG_ ul_TimingInterval, |
+| PULONG_ pul_RealTimingInterval) |
++----------------------------------------------------------------------------+
+| Task : Configure the selected tor counter (b_TorCounter) |
+| from selected module (b_ModulNbr). |
+| The ul_TimingInterval and ul_TimingUnit determine the |
+| timing base for the measurement. |
+| The pul_RealTimingInterval return the real timing |
+| value. You must calling this function be for you call |
+| any other function witch access of the tor counter. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : |
+|
+ CR_AREF BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| data[0] BYTE_ b_TorCounter : Tor counter selection |
+| (0 or 1). |
+| data[1] BYTE_ b_PCIInputClock : Selection from PCI bus clock|
+| - APCI1710_30MHZ : |
+| The PC have a PCI bus |
+| clock from 30 MHz |
+| - APCI1710_33MHZ : |
+| The PC have a PCI bus |
+| clock from 33 MHz |
+| - APCI1710_40MHZ |
+| The APCI-1710 have a |
+| integrated 40Mhz |
+| quartz. |
+| - APCI1710_GATE_INPUT |
+| Used the gate input for |
+| the base clock. If you |
+| have selected this option,|
+| than it is not possibl to |
+| used the gate input for |
+| enabled the acquisition |
+| data[2] BYTE_ b_TimingUnit : Base timing unit (0 to 4) |
+| 0 : ns |
+| 1 : µs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| data[3] ULONG_ ul_TimingInterval : Base timing value. |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_RealTimingInterval : Real base timing |
+| data[0] value. |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a tor counter module |
+| -4: Tor counter selection is wrong |
+| -5: The selected PCI input clock is wrong |
+| -6: Timing unit selection is wrong |
+| -7: Base timing selection is wrong |
+| -8: You can not used the 40MHz clock selection wich |
+| this board |
+| -9: You can not used the 40MHz clock selection wich |
+| this TOR version |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitTorCounter(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ ULONG ul_TimerValue = 0;
+ DWORD dw_Command;
+ double d_RealTimingInterval = 0;
+ BYTE b_ModulNbr;
+ BYTE b_TorCounter;
+ BYTE b_PCIInputClock;
+ BYTE b_TimingUnit;
+ ULONG ul_TimingInterval;
+ ULONG ul_RealTimingInterval = 0;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+
+ b_TorCounter = (BYTE) data[0];
+ b_PCIInputClock = (BYTE) data[1];
+ b_TimingUnit = (BYTE) data[2];
+ ul_TimingInterval = (ULONG) data[3];
+ printk("INPUT clock %d\n", b_PCIInputClock);
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if tor counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+ /**********************************/
+ /* Test the tor counter selection */
+ /**********************************/
+
+ if (b_TorCounter <= 1) {
+ /**************************/
+ /* Test the PCI bus clock */
+ /**************************/
+
+ if ((b_PCIInputClock == APCI1710_30MHZ) ||
+ (b_PCIInputClock == APCI1710_33MHZ) ||
+ (b_PCIInputClock == APCI1710_40MHZ) ||
+ (b_PCIInputClock ==
+ APCI1710_GATE_INPUT)) {
+ /************************/
+ /* Test the timing unit */
+ /************************/
+
+ if ((b_TimingUnit <= 4)
+ || (b_PCIInputClock ==
+ APCI1710_GATE_INPUT)) {
+ /**********************************/
+ /* Test the base timing selection */
+ /**********************************/
+
+ if (((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 133) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571230650UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571230UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 9UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 121) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 519691043UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 519691UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 520UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 8UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 100) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429496729UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429496UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 7UL)) || ((b_PCIInputClock == APCI1710_GATE_INPUT) && (ul_TimingInterval >= 2))) {
+ /**************************/
+ /* Test the board version */
+ /**************************/
+
+ if (((b_PCIInputClock == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_PCIInputClock != APCI1710_40MHZ)) {
+ /************************/
+ /* Test the TOR version */
+ /************************/
+
+ if (((b_PCIInputClock == APCI1710_40MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131)) || ((b_PCIInputClock == APCI1710_GATE_INPUT) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3132)) || (b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) {
+ /*********************************/
+ /* Test if not extern clock used */
+ /*********************************/
+
+ if (b_PCIInputClock != APCI1710_GATE_INPUT) {
+ fpu_begin
+ ();
+ /****************************************/
+ /* Calculate the timer 0 division fator */
+ /****************************************/
+
+ switch (b_TimingUnit) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (0.00025 * b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (0.00025 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (0.00025 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (0.00025
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (0.00025 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (0.25 * b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (0.25 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (0.25 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (
+ (double)
+ 0.25
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (0.25 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ ul_TimingInterval
+ *
+ (250.0
+ *
+ b_PCIInputClock);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (250.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (250.0 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (250.0
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (250.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (250000.0
+ *
+ b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (250000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (250000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (ul_TimingInterval
+ *
+ 60)
+ *
+ (250000.0
+ *
+ b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)(ul_TimingInterval * 60.0) * (250000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_PCIInputClock))
+ /
+ 60;
+ d_RealTimingInterval
+ =
+ (
+ (double)
+ ul_TimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_PCIInputClock))
+ /
+ 60.0;
+
+ if ((double)(((double)ul_TimerValue / (250000.0 * (double)b_PCIInputClock)) / 60.0) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+ }
+
+ fpu_end();
+ } // if (b_PCIInputClock != APCI1710_GATE_INPUT)
+ else {
+ /*************************************************************/
+ /* 2 Clock used for the overflow and the reload from counter */
+ /*************************************************************/
+
+ ul_TimerValue
+ =
+ ul_TimingInterval
+ -
+ 2;
+ } // if (b_PCIInputClock != APCI1710_GATE_INPUT)
+
+ /****************************/
+ /* Save the PCI input clock */
+ /****************************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ b_PCIInputClock
+ =
+ b_PCIInputClock;
+
+ /************************/
+ /* Save the timing unit */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo
+ [b_TorCounter].
+ b_TimingUnit
+ =
+ b_TimingUnit;
+
+ /************************/
+ /* Save the base timing */
+ /************************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo
+ [b_TorCounter].
+ d_TimingInterval
+ =
+ d_RealTimingInterval;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo
+ [b_TorCounter].
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval;
+
+ /*******************/
+ /* Get the command */
+ /*******************/
+
+ dw_Command
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 4
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ dw_Command
+ =
+ (dw_Command
+ >>
+ 4)
+ &
+ 0xF;
+
+ /******************/
+ /* Test if 40 MHz */
+ /******************/
+
+ if (b_PCIInputClock == APCI1710_40MHZ) {
+ /****************************/
+ /* Set the 40 MHz selection */
+ /****************************/
+
+ dw_Command
+ =
+ dw_Command
+ |
+ 0x10;
+ }
+
+ /*****************************/
+ /* Test if extern clock used */
+ /*****************************/
+
+ if (b_PCIInputClock == APCI1710_GATE_INPUT) {
+ /****************************/
+ /* Set the 40 MHz selection */
+ /****************************/
+
+ dw_Command
+ =
+ dw_Command
+ |
+ 0x20;
+ }
+
+ /*************************/
+ /* Write the new command */
+ /*************************/
+
+ outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ /*******************/
+ /* Disable the tor */
+ /*******************/
+
+ outl(0, devpriv->s_BoardInfos.ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+ /*************************/
+ /* Set the timer 1 value */
+ /*************************/
+
+ outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ /*********************/
+ /* Tor counter init. */
+ /*********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo
+ [b_TorCounter].
+ b_TorCounterInit
+ =
+ 1;
+ } else {
+ /***********************************************/
+ /* TOR version error for 40MHz clock selection */
+ /***********************************************/
+
+ DPRINTK("TOR version error for 40MHz clock selection\n");
+ i_ReturnValue
+ =
+ -9;
+ }
+ } else {
+ /**************************************************************/
+ /* You can not used the 40MHz clock selection wich this board */
+ /**************************************************************/
+
+ DPRINTK("You can not used the 40MHz clock selection wich this board\n");
+ i_ReturnValue =
+ -8;
+ }
+ } else {
+ /**********************************/
+ /* Base timing selection is wrong */
+ /**********************************/
+
+ DPRINTK("Base timing selection is wrong\n");
+ i_ReturnValue = -7;
+ }
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ else {
+ /**********************************/
+ /* Timing unit selection is wrong */
+ /**********************************/
+
+ DPRINTK("Timing unit selection is wrong\n");
+ i_ReturnValue = -6;
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))
+ else {
+ /*****************************************/
+ /* The selected PCI input clock is wrong */
+ /*****************************************/
+
+ DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue = -5;
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))
+ } // if (b_TorCounterMode >= 0 && b_TorCounterMode <= 7)
+ else {
+ /**********************************/
+ /* Tor Counter selection is wrong */
+ /**********************************/
+
+ DPRINTK("Tor Counter selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_TorCounterMode >= 0 && b_TorCounterMode <= 7)
+ } else {
+ /******************************************/
+ /* The module is not a tor counter module */
+ /******************************************/
+
+ DPRINTK("The module is not a tor counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+ data[0] = (UINT) ul_RealTimingInterval;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnableTorCounter |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TorCounter, |
+| BYTE_ b_InputMode, |
+| BYTE_ b_ExternGate, |
+| BYTE_ b_CycleMode, |
+| BYTE_ b_InterruptEnable) |
++----------------------------------------------------------------------------+
+| Task : Enable the tor counter (b_TorCounter) from selected |
+| module (b_ModulNbr). You must calling the |
+| "i_APCI1710_InitTorCounter" function be for you call |
+| this function. |
+| If you enable the tor counter interrupt, the |
+| tor counter generate a interrupt after the timing cycle|
+| See function "i_APCI1710_SetBoardIntRoutineX" and the |
+| Interrupt mask description chapter from this manual. |
+| The b_CycleMode parameter determine if you will |
+| measured a single or more cycle. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_TorCounter : Tor counter selection (0 or 1). |
+| BYTE_ b_InputMode : Input signal level selection |
+| 0 : Tor count each low level |
+| 1 : Tor count each high level|
+| BYTE_ b_ExternGate : Extern gate action selection |
+| 0 : Extern gate signal not |
+| used |
+| 1 : Extern gate signal used. |
+| If you selected the |
+| single mode, each high |
+| level signal start the |
+| counter. |
+| If you selected the |
+| continuous mode, the |
+| first high level signal |
+| start the tor counter |
+| |
+| APCI1710_TOR_QUADRUPLE _MODE : |
+| In the quadruple mode, the edge|
+| analysis circuit generates a |
+| counting pulse from each edge |
+| of 2 signals which are phase |
+| shifted in relation to each |
+| other. |
+| The gate input is used for the |
+| signal B |
+| |
+| APCI1710_TOR_DOUBLE_MODE: |
+| Functions in the same way as |
+| the quadruple mode, except that|
+| only two of the four edges are |
+| analysed per period. |
+| The gate input is used for the |
+| signal B |
+| |
+| APCI1710_TOR_SIMPLE_MODE: |
+| Functions in the same way as |
+| the quadruple mode, except that|
+| only one of the four edges is |
+| analysed per period. |
+| The gate input is used for the |
+| signal B |
+| |
+| BYTE_ b_CycleMode : Selected the tor counter |
+| acquisition mode |
+| BYTE_ b_InterruptEnable : Enable or disable the |
+| tor counter interrupt. |
+| APCI1710_ENABLE: |
+| Enable the tor counter |
+| interrupt |
+| APCI1710_DISABLE: |
+| Disable the tor counter |
+| interrupt |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a tor counter module |
+| -4: Tor counter selection is wrong |
+| -5: Tor counter not initialised see function |
+| "i_APCI1710_InitTorCounter" |
+| -6: Tor input signal selection is wrong |
+| -7: Extern gate signal mode is wrong |
+| -8: Tor counter acquisition mode cycle is wrong |
+| -9: Interrupt parameter is wrong |
+| -10:Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_DisableTorCounter |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TorCounter) |
++----------------------------------------------------------------------------+
+| Task : Disable the tor counter (b_TorCounter) from selected |
+| module (b_ModulNbr). If you disable the tor counter |
+| after a start cycle occur and you restart the tor |
+| counter witch the " i_APCI1710_EnableTorCounter" |
+| function, the status register is cleared |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_TorCounter : Tor counter selection (0 or 1). |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a tor counter module |
+| -4: Tor counter selection is wrong |
+| -5: Tor counter not initialised see function |
+| "i_APCI1710_InitTorCounter" |
+| -6: Tor counter not enabled see function |
+| "i_APCI1710_EnableTorCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ DWORD dw_DummyRead;
+ DWORD dw_ConfigReg;
+ BYTE b_ModulNbr, b_Action;
+ BYTE b_TorCounter;
+ BYTE b_InputMode;
+ BYTE b_ExternGate;
+ BYTE b_CycleMode;
+ BYTE b_InterruptEnable;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_Action = (BYTE) data[0]; // enable or disable
+ b_TorCounter = (BYTE) data[1];
+ b_InputMode = (BYTE) data[2];
+ b_ExternGate = (BYTE) data[3];
+ b_CycleMode = (BYTE) data[4];
+ b_InterruptEnable = (BYTE) data[5];
+ i_ReturnValue = insn->n;;
+ devpriv->tsk_Current = current; // Save the current process task structure
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if tor counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+ /**********************************/
+ /* Test the tor counter selection */
+ /**********************************/
+
+ if (b_TorCounter <= 1) {
+ switch (b_Action) // Enable or Disable
+ {
+ case APCI1710_ENABLE:
+ /***********************************/
+ /* Test if tor counter initialised */
+ /***********************************/
+
+ dw_Status =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 8 +
+ (16 * b_TorCounter) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ /******************************/
+ /* Test the input signal mode */
+ /******************************/
+
+ if (b_InputMode == 0 ||
+ b_InputMode == 1 ||
+ b_InputMode ==
+ APCI1710_TOR_SIMPLE_MODE
+ || b_InputMode ==
+ APCI1710_TOR_DOUBLE_MODE
+ || b_InputMode ==
+ APCI1710_TOR_QUADRUPLE_MODE)
+ {
+ /************************************/
+ /* Test the extern gate signal mode */
+ /************************************/
+
+ if (b_ExternGate == 0
+ || b_ExternGate
+ == 1
+ || b_InputMode >
+ 1) {
+ /*********************************/
+ /* Test the cycle mode parameter */
+ /*********************************/
+
+ if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) {
+ /***************************/
+ /* Test the interrupt flag */
+ /***************************/
+
+ if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE)) {
+
+ /***************************/
+ /* Save the interrupt mode */
+ /***************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo
+ [b_TorCounter].
+ b_InterruptEnable
+ =
+ b_InterruptEnable;
+
+ /*******************/
+ /* Get the command */
+ /*******************/
+
+ dw_ConfigReg
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 4
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ dw_ConfigReg
+ =
+ (dw_ConfigReg
+ >>
+ 4)
+ &
+ 0x30;
+
+ /********************************/
+ /* Test if not direct mode used */
+ /********************************/
+
+ if (b_InputMode > 1) {
+ /*******************************/
+ /* Extern gate can not be used */
+ /*******************************/
+
+ b_ExternGate
+ =
+ 0;
+
+ /*******************************************/
+ /* Enable the extern gate for the Signal B */
+ /*******************************************/
+
+ dw_ConfigReg
+ =
+ dw_ConfigReg
+ |
+ 0x40;
+
+ /***********************/
+ /* Test if simple mode */
+ /***********************/
+
+ if (b_InputMode == APCI1710_TOR_SIMPLE_MODE) {
+ /**************************/
+ /* Enable the sinple mode */
+ /**************************/
+
+ dw_ConfigReg
+ =
+ dw_ConfigReg
+ |
+ 0x780;
+
+ } // if (b_InputMode == APCI1710_TOR_SIMPLE_MODE)
+
+ /***********************/
+ /* Test if double mode */
+ /***********************/
+
+ if (b_InputMode == APCI1710_TOR_DOUBLE_MODE) {
+ /**************************/
+ /* Enable the double mode */
+ /**************************/
+
+ dw_ConfigReg
+ =
+ dw_ConfigReg
+ |
+ 0x180;
+
+ } // if (b_InputMode == APCI1710_TOR_DOUBLE_MODE)
+
+ b_InputMode
+ =
+ 0;
+ } // if (b_InputMode > 1)
+
+ /*******************/
+ /* Set the command */
+ /*******************/
+
+ dw_ConfigReg
+ =
+ dw_ConfigReg
+ |
+ b_CycleMode
+ |
+ (b_InterruptEnable
+ *
+ 2)
+ |
+ (b_InputMode
+ *
+ 4)
+ |
+ (b_ExternGate
+ *
+ 8);
+
+ /*****************************/
+ /* Clear the status register */
+ /*****************************/
+
+ dw_DummyRead
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 0
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ /***************************************/
+ /* Clear the interrupt status register */
+ /***************************************/
+
+ dw_DummyRead
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 12
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ /********************/
+ /* Set the commando */
+ /********************/
+
+ outl(dw_ConfigReg, devpriv->s_BoardInfos.ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ /****************/
+ /* Set the gate */
+ /****************/
+
+ outl(1, devpriv->s_BoardInfos.ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ } // if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))
+ else {
+ /********************************/
+ /* Interrupt parameter is wrong */
+ /********************************/
+
+ DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue
+ =
+ -9;
+ } // if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))
+ } // if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))
+ else {
+ /***********************************************/
+ /* Tor counter acquisition mode cycle is wrong */
+ /***********************************************/
+
+ DPRINTK("Tor counter acquisition mode cycle is wrong\n");
+ i_ReturnValue
+ =
+ -8;
+ } // if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))
+ } // if (b_ExternGate >= 0 && b_ExternGate <= 1)
+ else {
+ /***********************************/
+ /* Extern gate input mode is wrong */
+ /***********************************/
+
+ DPRINTK("Extern gate input mode is wrong\n");
+ i_ReturnValue =
+ -7;
+ } // if (b_ExternGate >= 0 && b_ExternGate <= 1)
+ } // if (b_InputMode >= 0 && b_InputMode <= 1)
+ else {
+ /***************************************/
+ /* Tor input signal selection is wrong */
+ /***************************************/
+
+ DPRINTK("Tor input signal selection is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /*******************************/
+ /* Tor counter not initialised */
+ /*******************************/
+
+ DPRINTK("Tor counter not initialised\n");
+ i_ReturnValue = -5;
+ }
+ break;
+
+ case APCI1710_DISABLE:
+ /***********************************/
+ /* Test if tor counter initialised */
+ /***********************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 8 +
+ (16 * b_TorCounter) +
+ (64 * b_ModulNbr));
+
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (dw_Status & 0x10) {
+ /***************************/
+ /* Test if counter enabled */
+ /***************************/
+
+ if (dw_Status & 0x1) {
+ /****************************/
+ /* Clear the interrupt mode */
+ /****************************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo
+ [b_TorCounter].
+ b_InterruptEnable
+ =
+ APCI1710_DISABLE;
+
+ /******************/
+ /* Clear the gate */
+ /******************/
+
+ outl(0, devpriv->
+ s_BoardInfos.
+ ui_Address + 8 +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+ } // if (dw_Status & 0x1)
+ else {
+ /***************************/
+ /* Tor counter not enabled */
+ /***************************/
+
+ DPRINTK("Tor counter not enabled \n");
+ i_ReturnValue = -6;
+ } // if (dw_Status & 0x1)
+ } // if (dw_Status & 0x10)
+ else {
+ /*******************************/
+ /* Tor counter not initialised */
+ /*******************************/
+
+ DPRINTK("Tor counter not initialised\n");
+ i_ReturnValue = -5;
+ } // // if (dw_Status & 0x10)
+
+ } // switch
+ } // if (b_TorCounter <= 1)
+ else {
+ /**********************************/
+ /* Tor counter selection is wrong */
+ /**********************************/
+
+ DPRINTK("Tor counter selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_TorCounter <= 1)
+ } else {
+ /******************************************/
+ /* The module is not a tor counter module */
+ /******************************************/
+
+ DPRINTK("The module is not a tor counter module \n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error \n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetTorCounterInitialisation |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TorCounter, |
+| PBYTE_ pb_TimingUnit, |
+| PULONG_ pul_TimingInterval, |
+| PBYTE_ pb_InputMode, |
+| PBYTE_ pb_ExternGate, |
+| PBYTE_ pb_CycleMode, |
+| PBYTE_ pb_Enable, |
+| PBYTE_ pb_InterruptEnable)|
++----------------------------------------------------------------------------+
+| Task : Enable the tor counter (b_TorCounter) from selected |
+| module (b_ModulNbr). You must calling the |
+| "i_APCI1710_InitTorCounter" function be for you call |
+| this function. |
+| If you enable the tor counter interrupt, the |
+| tor counter generate a interrupt after the timing cycle|
+| See function "i_APCI1710_SetBoardIntRoutineX" and the |
+| Interrupt mask description chapter from this manual. |
+| The b_CycleMode parameter determine if you will |
+| measured a single or more cycle. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_TorCounter : Tor counter selection (0 or 1)
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_TorCounter = CR_CHAN(insn->chanspec);
+. |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TimingUnit : Base timing unit (0 to 4) |
+| 0 : ns |
+| 1 : µs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| PULONG_ pul_TimingInterval : Base timing value. |
+| PBYTE_ pb_InputMode : Input signal level |
+| selection |
+| 0 : Tor count each low level |
+| 1 : Tor count each high level|
+| PBYTE_ pb_ExternGate : Extern gate action |
+| selection |
+| 0 : Extern gate signal not |
+| used |
+| 1 : Extern gate signal used|
+| PBYTE_ pb_CycleMode : Tor counter acquisition |
+| mode |
+| PBYTE_ pb_Enable : Indicate if the tor counter|
+| is enabled or no |
+| 0 : Tor counter disabled |
+| 1 : Tor counter enabled |
+| PBYTE_ pb_InterruptEnable : Enable or disable the |
+| tor counter interrupt. |
+| APCI1710_ENABLE: |
+| Enable the tor counter |
+| interrupt |
+| APCI1710_DISABLE: |
+| Disable the tor counter |
+| interrupt
+ pb_TimingUnit = (PBYTE) &data[0];
+ pul_TimingInterval = (PULONG) &data[1];
+ pb_InputMode = (PBYTE) &data[2];
+ pb_ExternGate = (PBYTE) &data[3];
+ pb_CycleMode = (PBYTE) &data[4];
+ pb_Enable = (PBYTE) &data[5];
+ pb_InterruptEnable = (PBYTE) &data[6];
+ |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a tor counter module |
+| -4: Tor counter selection is wrong |
+| -5: Tor counter not initialised see function |
+| "i_APCI1710_InitTorCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ BYTE b_ModulNbr;
+ BYTE b_TorCounter;
+ PBYTE pb_TimingUnit;
+ PULONG pul_TimingInterval;
+ PBYTE pb_InputMode;
+ PBYTE pb_ExternGate;
+ PBYTE pb_CycleMode;
+ PBYTE pb_Enable;
+ PBYTE pb_InterruptEnable;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_TorCounter = CR_CHAN(insn->chanspec);
+
+ pb_TimingUnit = (PBYTE) & data[0];
+ pul_TimingInterval = (PULONG) & data[1];
+ pb_InputMode = (PBYTE) & data[2];
+ pb_ExternGate = (PBYTE) & data[3];
+ pb_CycleMode = (PBYTE) & data[4];
+ pb_Enable = (PBYTE) & data[5];
+ pb_InterruptEnable = (PBYTE) & data[6];
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if tor counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+ /**********************************/
+ /* Test the tor counter selection */
+ /**********************************/
+
+ if (b_TorCounter <= 1) {
+
+ /***********************************/
+ /* Test if tor counter initialised */
+ /***********************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (16 * b_TorCounter) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ *pb_Enable = dw_Status & 1;
+
+ /********************/
+ /* Get the commando */
+ /********************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 4 +
+ (16 * b_TorCounter) +
+ (64 * b_ModulNbr));
+
+ *pb_CycleMode =
+ (BYTE) ((dw_Status >> 4) & 1);
+ *pb_InterruptEnable =
+ (BYTE) ((dw_Status >> 5) & 1);
+
+ /******************************************************/
+ /* Test if extern gate used for clock or for signal B */
+ /******************************************************/
+
+ if (dw_Status & 0x600) {
+ /*****************************************/
+ /* Test if extern gate used for signal B */
+ /*****************************************/
+
+ if (dw_Status & 0x400) {
+ /***********************/
+ /* Test if simple mode */
+ /***********************/
+
+ if ((dw_Status & 0x7800)
+ == 0x7800) {
+ *pb_InputMode =
+ APCI1710_TOR_SIMPLE_MODE;
+ }
+
+ /***********************/
+ /* Test if double mode */
+ /***********************/
+
+ if ((dw_Status & 0x7800)
+ == 0x1800) {
+ *pb_InputMode =
+ APCI1710_TOR_DOUBLE_MODE;
+ }
+
+ /**************************/
+ /* Test if quadruple mode */
+ /**************************/
+
+ if ((dw_Status & 0x7800)
+ == 0x0000) {
+ *pb_InputMode =
+ APCI1710_TOR_QUADRUPLE_MODE;
+ }
+ } // if (dw_Status & 0x400)
+ else {
+ *pb_InputMode = 1;
+ } // // if (dw_Status & 0x400)
+
+ /************************/
+ /* Extern gate not used */
+ /************************/
+
+ *pb_ExternGate = 0;
+ } // if (dw_Status & 0x600)
+ else {
+ *pb_InputMode =
+ (BYTE) ((dw_Status >> 6)
+ & 1);
+ *pb_ExternGate =
+ (BYTE) ((dw_Status >> 7)
+ & 1);
+ } // if (dw_Status & 0x600)
+
+ *pb_TimingUnit =
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo[b_TorCounter].
+ b_TimingUnit;
+
+ *pul_TimingInterval =
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo[b_TorCounter].
+ ul_RealTimingInterval;
+ } else {
+ /*******************************/
+ /* Tor counter not initialised */
+ /*******************************/
+
+ DPRINTK("Tor counter not initialised\n");
+ i_ReturnValue = -5;
+ }
+
+ } // if (b_TorCounter <= 1)
+ else {
+ /**********************************/
+ /* Tor counter selection is wrong */
+ /**********************************/
+
+ DPRINTK("Tor counter selection is wrong \n");
+ i_ReturnValue = -4;
+ } // if (b_TorCounter <= 1)
+ } else {
+ /******************************************/
+ /* The module is not a tor counter module */
+ /******************************************/
+
+ DPRINTK("The module is not a tor counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadTorCounterValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TorCounter, |
+| UINT_ ui_TimeOut, |
+| PBYTE_ pb_TorCounterStatus, |
+| PULONG_ pul_TorCounterValue) |
++----------------------------------------------------------------------------+
+| Task case APCI1710_TOR_GETPROGRESSSTATUS: Return the tor counter
+(b_TorCounter) status (pb_TorCounterStatus) from selected tor counter |
+| module (b_ModulNbr).
+
+ case APCI1710_TOR_GETCOUNTERVALUE :
+ Return the tor counter (b_TorCounter) status |
+| (pb_TorCounterStatus) and the timing value |
+| (pul_TorCounterValue) after a conting cycle stop |
+| from selected tor counter module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_TorCounter : Tor counter selection (0 or 1).
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_ReadType = (BYTE) data[0];
+ b_TorCounter = (BYTE) data[1];
+ ui_TimeOut = (UINT) data[2]; |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TorCounterStatus : Return the tor counter |
+| status. |
+| 0 : Conting cycle not started|
+| Software gate not set. |
+| 1 : Conting cycle started. |
+| Software gate set. |
+| 2 : Conting cycle stopped. |
+| The conting cycle is |
+| terminate. |
+| 3 : A overflow occur. You |
+| must change the base |
+| timing witch the |
+| function |
+| "i_APCI1710_InitTorCounter"|
+| 4 : Timeeout occur |
+| PULONG pul_TorCounterValue : Tor counter value.
+ pb_TorCounterStatus=(PBYTE) &data[0];
+ pul_TorCounterValue=(PULONG) &data[1]; |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a tor counter module |
+| -4: Tor counter selection is wrong |
+| -5: Tor counter not initialised see function |
+| "i_APCI1710_InitTorCounter" |
+| -6: Tor counter not enabled see function |
+| "i_APCI1710_EnableTorCounter" |
+| -7: Timeout parameter is wrong (0 to 65535) |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ DWORD dw_TimeOut = 0;
+
+ BYTE b_ModulNbr;
+ BYTE b_TorCounter;
+ BYTE b_ReadType;
+ UINT ui_TimeOut;
+ PBYTE pb_TorCounterStatus;
+ PULONG pul_TorCounterValue;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_ReadType = (BYTE) data[0];
+ b_TorCounter = (BYTE) data[1];
+ ui_TimeOut = (UINT) data[2];
+ pb_TorCounterStatus = (PBYTE) & data[0];
+ pul_TorCounterValue = (PULONG) & data[1];
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ReadType == APCI1710_TOR_READINTERRUPT) {
+
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.
+ ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ return insn->n;
+ }
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if tor counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+ /**********************************/
+ /* Test the tor counter selection */
+ /**********************************/
+
+ if (b_TorCounter <= 1) {
+ /***********************************/
+ /* Test if tor counter initialised */
+ /***********************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (16 * b_TorCounter) +
+ (64 * b_ModulNbr));
+
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (dw_Status & 0x10) {
+ /***************************/
+ /* Test if counter enabled */
+ /***************************/
+
+ if (dw_Status & 0x1) {
+
+ switch (b_ReadType) {
+
+ case APCI1710_TOR_GETPROGRESSSTATUS:
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ dw_Status =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 4 +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ dw_Status =
+ dw_Status & 0xF;
+
+ /*****************/
+ /* Test if start */
+ /*****************/
+
+ if (dw_Status & 1) {
+ if (dw_Status &
+ 2) {
+ if (dw_Status & 4) {
+ /************************/
+ /* Tor counter owerflow */
+ /************************/
+
+ *pb_TorCounterStatus
+ =
+ 3;
+ } else {
+ /***********************/
+ /* Tor counter started */
+ /***********************/
+
+ *pb_TorCounterStatus
+ =
+ 2;
+ }
+ } else {
+ /***********************/
+ /* Tor counter started */
+ /***********************/
+
+ *pb_TorCounterStatus
+ =
+ 1;
+ }
+ } else {
+ /***************************/
+ /* Tor counter not started */
+ /***************************/
+
+ *pb_TorCounterStatus
+ = 0;
+ }
+ break;
+
+ case APCI1710_TOR_GETCOUNTERVALUE:
+
+ /*****************************/
+ /* Test the timout parameter */
+ /*****************************/
+
+ if ((ui_TimeOut >= 0)
+ && (ui_TimeOut
+ <=
+ 65535UL))
+ {
+ for (;;) {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ dw_Status
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 4
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+ /********************/
+ /* Test if overflow */
+ /********************/
+
+ if ((dw_Status & 4) == 4) {
+ /******************/
+ /* Overflow occur */
+ /******************/
+
+ *pb_TorCounterStatus
+ =
+ 3;
+
+ /******************/
+ /* Read the value */
+ /******************/
+
+ *pul_TorCounterValue
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 0
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+ break;
+ } // if ((dw_Status & 4) == 4)
+ else {
+ /*******************************/
+ /* Test if measurement stopped */
+ /*******************************/
+
+ if ((dw_Status & 2) == 2) {
+ /***********************/
+ /* A stop signal occur */
+ /***********************/
+
+ *pb_TorCounterStatus
+ =
+ 2;
+
+ /******************/
+ /* Read the value */
+ /******************/
+
+ *pul_TorCounterValue
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 0
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ break;
+ } // if ((dw_Status & 2) == 2)
+ else {
+ /*******************************/
+ /* Test if measurement started */
+ /*******************************/
+
+ if ((dw_Status & 1) == 1) {
+ /************************/
+ /* A start signal occur */
+ /************************/
+
+ *pb_TorCounterStatus
+ =
+ 1;
+ } // if ((dw_Status & 1) == 1)
+ else {
+ /***************************/
+ /* Measurement not started */
+ /***************************/
+
+ *pb_TorCounterStatus
+ =
+ 0;
+ } // if ((dw_Status & 1) == 1)
+ } // if ((dw_Status & 2) == 2)
+ } // if ((dw_Status & 8) == 8)
+
+ if (dw_TimeOut == ui_TimeOut) {
+ /*****************/
+ /* Timeout occur */
+ /*****************/
+
+ break;
+ } else {
+ /*************************/
+ /* Increment the timeout */
+ /*************************/
+
+ dw_TimeOut
+ =
+ dw_TimeOut
+ +
+ 1;
+
+ mdelay(1000);
+ }
+ } // for (;;)
+
+ /*************************/
+ /* Test if timeout occur */
+ /*************************/
+
+ if ((*pb_TorCounterStatus != 3) && (dw_TimeOut == ui_TimeOut) && (ui_TimeOut != 0)) {
+ /*****************/
+ /* Timeout occur */
+ /*****************/
+
+ *pb_TorCounterStatus
+ =
+ 4;
+ }
+ } else {
+ /******************************/
+ /* Timeout parameter is wrong */
+ /******************************/
+
+ DPRINTK("Timeout parameter is wrong\n");
+ i_ReturnValue =
+ -7;
+ }
+ break;
+
+ default:
+ printk("Inputs wrong\n");
+ } // switch end
+ } // if (dw_Status & 0x1)
+ else {
+ /***************************/
+ /* Tor counter not enabled */
+ /***************************/
+
+ DPRINTK("Tor counter not enabled\n");
+ i_ReturnValue = -6;
+ } // if (dw_Status & 0x1)
+ } else {
+ /*******************************/
+ /* Tor counter not initialised */
+ /*******************************/
+
+ DPRINTK("Tor counter not initialised\n");
+ i_ReturnValue = -5;
+ }
+ } // if (b_TorCounter <= 1)
+ else {
+ /**********************************/
+ /* Tor counter selection is wrong */
+ /**********************************/
+
+ DPRINTK("Tor counter selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_TorCounter <= 1)
+ } else {
+ /******************************************/
+ /* The module is not a tor counter module */
+ /******************************************/
+
+ DPRINTK("The module is not a tor counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h
new file mode 100644
index 00000000000..c245d16207b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
+
+#define APCI1710_GATE_INPUT 10
+
+#define APCI1710_TOR_SIMPLE_MODE 2
+#define APCI1710_TOR_DOUBLE_MODE 3
+#define APCI1710_TOR_QUADRUPLE_MODE 4
+
+#define APCI1710_SINGLE 0
+#define APCI1710_CONTINUOUS 1
+
+#define APCI1710_TOR_GETPROGRESSSTATUS 0
+#define APCI1710_TOR_GETCOUNTERVALUE 1
+#define APCI1710_TOR_READINTERRUPT 2
+
+/*
+ * TOR_COUNTER INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+INT i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+/*
+ * TOR_COUNTER READ FUNCTION
+ */
+INT i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
new file mode 100644
index 00000000000..68b1d26bae1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
@@ -0,0 +1,1038 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : TTL.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 TTL I/O module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 13/05/98 | S. Weber | TTL digital input / output implementation |
+ |----------|-----------|------------------------------------------------|
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+ | | | |
+ | | | |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Ttl.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitTTLIODirection |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PortAMode, |
+| BYTE_ b_PortBMode, |
+| BYTE_ b_PortCMode, |
+| BYTE_ b_PortDMode) |
++----------------------------------------------------------------------------+
+| Task APCI1710_TTL_INIT (using defaults) : Configure the TTL I/O operating mode from selected |
+| module (b_ModulNbr). You must calling this function be|
+| for you call any other function witch access of TTL. |
+ APCI1710_TTL_INITDIRECTION(user inputs for direction)
+
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3)
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_InitType = (BYTE) data[0];
+ b_PortAMode = (BYTE) data[1];
+ b_PortBMode = (BYTE) data[2];
+ b_PortCMode = (BYTE) data[3];
+ b_PortDMode = (BYTE) data[4];|
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a TTL module |
+| -4: Function not available for this version |
+| -5: Port A mode selection is wrong |
+| -6: Port B mode selection is wrong |
+| -7: Port C mode selection is wrong |
+| -8: Port D mode selection is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitTTLIO(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ BYTE b_ModulNbr;
+ BYTE b_InitType;
+ BYTE b_PortAMode;
+ BYTE b_PortBMode;
+ BYTE b_PortCMode;
+ BYTE b_PortDMode;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_InitType = (BYTE) data[0];
+ i_ReturnValue = insn->n;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /**************************/
+ /* Test if TTL I/O module */
+ /**************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TTL_IO) {
+ switch (b_InitType) {
+ case APCI1710_TTL_INIT:
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_TTLInit = 1;
+
+ /***************************/
+ /* Set TTL port A to input */
+ /***************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_PortConfiguration[0] = 0;
+
+ /***************************/
+ /* Set TTL port B to input */
+ /***************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_PortConfiguration[1] = 0;
+
+ /***************************/
+ /* Set TTL port C to input */
+ /***************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_PortConfiguration[2] = 0;
+
+ /****************************/
+ /* Set TTL port D to output */
+ /****************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_PortConfiguration[3] = 1;
+
+ /*************************/
+ /* Set the configuration */
+ /*************************/
+
+ outl(0x8,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+ break;
+
+ case APCI1710_TTL_INITDIRECTION:
+
+ b_PortAMode = (BYTE) data[1];
+ b_PortBMode = (BYTE) data[2];
+ b_PortCMode = (BYTE) data[3];
+ b_PortDMode = (BYTE) data[4];
+
+ /********************/
+ /* Test the version */
+ /********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] & 0xFFFF) >=
+ 0x3230) {
+ /************************/
+ /* Test the port A mode */
+ /************************/
+
+ if ((b_PortAMode == 0)
+ || (b_PortAMode == 1)) {
+ /************************/
+ /* Test the port B mode */
+ /************************/
+
+ if ((b_PortBMode == 0)
+ || (b_PortBMode == 1)) {
+ /************************/
+ /* Test the port C mode */
+ /************************/
+
+ if ((b_PortCMode == 0)
+ || (b_PortCMode
+ == 1)) {
+ /************************/
+ /* Test the port D mode */
+ /************************/
+
+ if ((b_PortDMode == 0) || (b_PortDMode == 1)) {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_TTLInit
+ =
+ 1;
+
+ /***********************/
+ /* Set TTL port A mode */
+ /***********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [0]
+ =
+ b_PortAMode;
+
+ /***********************/
+ /* Set TTL port B mode */
+ /***********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [1]
+ =
+ b_PortBMode;
+
+ /***********************/
+ /* Set TTL port C mode */
+ /***********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [2]
+ =
+ b_PortCMode;
+
+ /***********************/
+ /* Set TTL port D mode */
+ /***********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [3]
+ =
+ b_PortDMode;
+
+ /*************************/
+ /* Set the configuration */
+ /*************************/
+
+ outl((b_PortAMode << 0) | (b_PortBMode << 1) | (b_PortCMode << 2) | (b_PortDMode << 3), devpriv->s_BoardInfos.ui_Address + 20 + (64 * b_ModulNbr));
+ } else {
+ /**********************************/
+ /* Port D mode selection is wrong */
+ /**********************************/
+
+ DPRINTK("Port D mode selection is wrong\n");
+ i_ReturnValue
+ =
+ -8;
+ }
+ } else {
+ /**********************************/
+ /* Port C mode selection is wrong */
+ /**********************************/
+
+ DPRINTK("Port C mode selection is wrong\n");
+ i_ReturnValue =
+ -7;
+ }
+ } else {
+ /**********************************/
+ /* Port B mode selection is wrong */
+ /**********************************/
+
+ DPRINTK("Port B mode selection is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /**********************************/
+ /* Port A mode selection is wrong */
+ /**********************************/
+
+ DPRINTK("Port A mode selection is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /*******************************************/
+ /* Function not available for this version */
+ /*******************************************/
+
+ DPRINTK("Function not available for this version\n");
+ i_ReturnValue = -4;
+ }
+ break;
+
+ DPRINTK("\n");
+ default:
+ printk("Bad Config Type\n");
+ } // switch end
+ } else {
+ /**********************************/
+ /* The module is not a TTL module */
+ /**********************************/
+
+ DPRINTK("The module is not a TTL module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| INPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadTTLIOChannelValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_SelectedPort, |
+| BYTE_ b_InputChannel, |
+| PBYTE_ pb_ChannelStatus) |
++----------------------------------------------------------------------------+
+| Task : Read the status from selected TTL digital input |
+| (b_InputChannel)
++----------------------------------------------------------------------------+
+| Task : Read the status from digital input port |
+| (b_SelectedPort) from selected TTL module (b_ModulNbr) |
++----------------------------------------------------------------------------+
+
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 7) |
+| BYTE_ b_SelectedPort, : Selection from TTL I/O |
+| port (0 to 2) |
+| 0 : Port A selection |
+| 1 : Port B selection |
+| 2 : Port C selection |
+| 3 : Port D selection |
+| BYTE_ b_InputChannel : Selection from digital |
+| input ( 0 to 2)
+APCI1710_TTL_READCHANNEL
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_SelectedPort= CR_RANGE(insn->chanspec);
+ b_InputChannel= CR_CHAN(insn->chanspec);
+ b_ReadType = (BYTE) data[0];
+
+ APCI1710_TTL_READPORT|
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_SelectedPort= CR_RANGE(insn->chanspec);
+ b_ReadType = (BYTE) data[0];
+
++----------------------------------------------------------------------------+
+| Output Parameters : data[0]
+
+ PBYTE_ pb_ChannelStatus : Digital input channel |
+| status |
+| 0 : Channle is not active|
+| 1 : Channle is active |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a TTL module |
+| -4: The selected TTL input port is wrong |
+| -5: The selected TTL digital input is wrong |
+| -6: TTL I/O not initialised |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsReadTTLIO(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg;
+ BYTE b_ModulNbr;
+ BYTE b_SelectedPort;
+ BYTE b_InputChannel;
+ BYTE b_ReadType;
+ PBYTE pb_ChannelStatus;
+ PBYTE pb_PortValue;
+
+ i_ReturnValue = insn->n;
+ b_ReadType = (BYTE) data[0];
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_SelectedPort = CR_RANGE(insn->chanspec);
+ b_InputChannel = CR_CHAN(insn->chanspec);
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /**************************/
+ /* Test if TTL I/O module */
+ /**************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TTL_IO) {
+ switch (b_ReadType) {
+
+ case APCI1710_TTL_READCHANNEL:
+ pb_ChannelStatus = (PBYTE) & data[0];
+ /********************************/
+ /* Test the TTL I/O port number */
+ /********************************/
+
+ if (((b_SelectedPort <= 2)
+ && ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) ==
+ 0x3130))
+ || ((b_SelectedPort <= 3)
+ && ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) >=
+ 0x3230))) {
+ /******************************************/
+ /* Test the digital imnput channel number */
+ /******************************************/
+
+ if (((b_InputChannel <= 7)
+ && (b_SelectedPort < 3))
+ || ((b_InputChannel <= 1)
+ && (b_SelectedPort ==
+ 3))) {
+ /******************************************/
+ /* Test if the TTL I/O module initialised */
+ /******************************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.b_TTLInit ==
+ 1) {
+ /***********************************/
+ /* Test if TTL port used for input */
+ /***********************************/
+
+ if (((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) == 0x3130) || (((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3230) && (devpriv->s_ModuleInfo[b_ModulNbr].s_TTLIOInfo.b_PortConfiguration[b_SelectedPort] == 0))) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ dw_StatusReg =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ (64 * b_ModulNbr));
+
+ *pb_ChannelStatus
+ =
+ (BYTE) (
+ (dw_StatusReg
+ >>
+ (8 * b_SelectedPort)) >> b_InputChannel) & 1;
+ } else {
+ /*******************************/
+ /* Selected TTL I/O port error */
+ /*******************************/
+
+ DPRINTK("Selected TTL I/O port error\n");
+ i_ReturnValue =
+ -4;
+ }
+ } else {
+ /***************************/
+ /* TTL I/O not initialised */
+ /***************************/
+
+ DPRINTK("TTL I/O not initialised\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /********************************/
+ /* Selected digital input error */
+ /********************************/
+
+ DPRINTK("Selected digital input error\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /*******************************/
+ /* Selected TTL I/O port error */
+ /*******************************/
+
+ DPRINTK("Selected TTL I/O port error\n");
+ i_ReturnValue = -4;
+ }
+ break;
+
+ case APCI1710_TTL_READPORT:
+ pb_PortValue = (PBYTE) & data[0];
+ /********************************/
+ /* Test the TTL I/O port number */
+ /********************************/
+
+ if (((b_SelectedPort <= 2)
+ && ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) ==
+ 0x3130))
+ || ((b_SelectedPort <= 3)
+ && ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) >=
+ 0x3230))) {
+ /******************************************/
+ /* Test if the TTL I/O module initialised */
+ /******************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_TTLInit == 1) {
+ /***********************************/
+ /* Test if TTL port used for input */
+ /***********************************/
+
+ if (((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr]
+ &
+ 0xFFFF)
+ == 0x3130)
+ || (((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3230) && (devpriv->s_ModuleInfo[b_ModulNbr].s_TTLIOInfo.b_PortConfiguration[b_SelectedPort] == 0))) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ dw_StatusReg =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (64 * b_ModulNbr));
+
+ *pb_PortValue =
+ (BYTE) (
+ (dw_StatusReg >>
+ (8 * b_SelectedPort)) & 0xFF);
+ } else {
+ /*******************************/
+ /* Selected TTL I/O port error */
+ /*******************************/
+
+ DPRINTK("Selected TTL I/O port error\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /***************************/
+ /* TTL I/O not initialised */
+ /***************************/
+
+ DPRINTK("TTL I/O not initialised\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /*******************************/
+ /* Selected TTL I/O port error */
+ /*******************************/
+
+ DPRINTK("Selected TTL I/O port error\n");
+ i_ReturnValue = -4;
+ }
+ break;
+
+ default:
+ printk("Bad ReadType\n");
+
+ } //End Switch
+ } else {
+ /**********************************/
+ /* The module is not a TTL module */
+ /**********************************/
+
+ DPRINTK("The module is not a TTL module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI1710_InsnReadTTLIOAllPortValue(comedi_device
+*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read the status from all digital input ports |
+| (port A, port B and port C) from selected TTL |
+| module (b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_PortValue : Digital TTL inputs port |
+| status |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a TTL module |
+| -4: TTL I/O not initialised |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg;
+ BYTE b_ModulNbr;
+ PULONG pul_PortValue;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ i_ReturnValue = insn->n;
+ pul_PortValue = (PULONG) & data[0];
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /**************************/
+ /* Test if TTL I/O module */
+ /**************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TTL_IO) {
+ /******************************************/
+ /* Test if the TTL I/O module initialised */
+ /******************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_TTLInit == 1) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+
+ /**********************/
+ /* Test if TTL Rev1.0 */
+ /**********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] & 0xFFFF) ==
+ 0x3130) {
+ *pul_PortValue =
+ dw_StatusReg & 0xFFFFFFUL;
+ } else {
+ /**************************************/
+ /* Test if port A not used for output */
+ /**************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration[0] == 1) {
+ *pul_PortValue =
+ dw_StatusReg &
+ 0x3FFFF00UL;
+ }
+
+ /**************************************/
+ /* Test if port B not used for output */
+ /**************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration[1] == 1) {
+ *pul_PortValue =
+ dw_StatusReg &
+ 0x3FF00FFUL;
+ }
+
+ /**************************************/
+ /* Test if port C not used for output */
+ /**************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration[2] == 1) {
+ *pul_PortValue =
+ dw_StatusReg &
+ 0x300FFFFUL;
+ }
+
+ /**************************************/
+ /* Test if port D not used for output */
+ /**************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration[3] == 1) {
+ *pul_PortValue =
+ dw_StatusReg &
+ 0xFFFFFFUL;
+ }
+ }
+ } else {
+ /***************************/
+ /* TTL I/O not initialised */
+ /***************************/
+ DPRINTK("TTL I/O not initialised\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /**********************************/
+ /* The module is not a TTL module */
+ /**********************************/
+ DPRINTK("The module is not a TTL module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| OUTPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetTTLIOChlOn |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_OutputChannel)
+INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Sets or resets the output witch has been passed with the |
+| parameter b_Channel. Setting an output means setting |
+| an ouput high. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
+| BYTE_ b_OutputChannel : Selection from digital output |
+| channel (0 or 1) |
+| 0 : PD0 |
+| 1 : PD1 |
+| 2 to 9 : PA |
+| 10 to 17: PB |
+| 18 to 25: PC |
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_OutputChannel= CR_CHAN(insn->chanspec);
+ ui_State = data[0]; // ON or OFF
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a TTL I/O module |
+| -4: The selected digital output is wrong |
+| -5: TTL I/O not initialised see function |
+| " i_APCI1710_InitTTLIO"
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+ BYTE b_ModulNbr;
+ BYTE b_OutputChannel;
+ UINT ui_State;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_OutputChannel = CR_CHAN(insn->chanspec);
+ ui_State = data[0]; // ON or OFF
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /**************************/
+ /* Test if TTL I/O module */
+ /**************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TTL_IO) {
+ /******************************************/
+ /* Test if the TTL I/O module initialised */
+ /******************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_TTLInit == 1) {
+ /***********************************/
+ /* Test the TTL I/O channel number */
+ /***********************************/
+
+ if (((b_OutputChannel <= 1)
+ && ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) ==
+ 0x3130))
+ || ((b_OutputChannel <= 25)
+ && ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) >=
+ 0x3230))) {
+ /****************************************************/
+ /* Test if the selected channel is a output channel */
+ /****************************************************/
+
+ if (((b_OutputChannel <= 1)
+ && (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [3] == 1))
+ || ((b_OutputChannel >= 2)
+ && (b_OutputChannel <=
+ 9)
+ && (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [0] == 1))
+ || ((b_OutputChannel >= 10)
+ && (b_OutputChannel <=
+ 17)
+ && (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [1] == 1))
+ || ((b_OutputChannel >= 18)
+ && (b_OutputChannel <=
+ 25)
+ && (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [2] == 1))) {
+ /************************/
+ /* Test if PD0 selected */
+ /************************/
+
+ if (b_OutputChannel == 0) {
+
+ outl(ui_State,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (64 * b_ModulNbr));
+ } else {
+ /************************/
+ /* Test if PD1 selected */
+ /************************/
+
+ if (b_OutputChannel ==
+ 1) {
+
+ outl(ui_State,
+ devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 4 +
+ (64 * b_ModulNbr));
+ } else {
+ b_OutputChannel
+ =
+ b_OutputChannel
+ - 2;
+
+ /********************/
+ /* Read all channel */
+ /********************/
+
+ dw_StatusReg =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ (64 * b_ModulNbr));
+ if (ui_State) // ON
+ {
+ dw_StatusReg
+ =
+ (dw_StatusReg
+ >>
+ ((b_OutputChannel / 8) * 8)) & 0xFF;
+ dw_StatusReg
+ =
+ dw_StatusReg
+ |
+ (1
+ <<
+ (b_OutputChannel
+ %
+ 8));
+ } else // Off
+ {
+ dw_StatusReg
+ =
+ (dw_StatusReg
+ >>
+ ((b_OutputChannel / 8) * 8)) & 0xFF;
+ dw_StatusReg
+ =
+ dw_StatusReg
+ &
+ (0xFF
+ -
+ (1 << (b_OutputChannel % 8)));
+
+ }
+
+ /****************************/
+ /* Set the new output value */
+ /****************************/
+
+ outl(dw_StatusReg, devpriv->s_BoardInfos.ui_Address + 8 + ((b_OutputChannel / 8) * 4) + (64 * b_ModulNbr));
+ }
+ }
+ } else {
+ /************************************/
+ /* The selected TTL output is wrong */
+ /************************************/
+
+ DPRINTK(" The selected TTL output is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /************************************/
+ /* The selected TTL output is wrong */
+ /************************************/
+
+ DPRINTK("The selected TTL output is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /***************************/
+ /* TTL I/O not initialised */
+ /***************************/
+
+ DPRINTK("TTL I/O not initialised\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /**************************************/
+ /* The module is not a TTL I/O module */
+ /**************************************/
+
+ DPRINTK("The module is not a TTL I/O module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h
new file mode 100644
index 00000000000..00915ddf921
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+#define APCI1710_TTL_INIT 0
+#define APCI1710_TTL_INITDIRECTION 1
+
+#define APCI1710_TTL_READCHANNEL 0
+#define APCI1710_TTL_READPORT 1
+
+/*
+ * TTL INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * TTL INPUT FUNCTION
+ */
+INT i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * TTL OUTPUT FUNCTIONS
+ */
+INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
new file mode 100644
index 00000000000..b0907ec1466
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
@@ -0,0 +1,203 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : ADDI HEADER READ WRITER | Compiler : Visual C++ |
+ | Module name : S5920.cpp | Version : 6.0 |
+ +-------------------------------+---------------------------------------+
+ | Author : E. LIBS Date : 02/05/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : DLL with the S5920 PCI Controller functions |
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 28/08/02 | LIBS Eric | Add return codes each time a function of the |
+ | | | Addi Library is called |
+ +-----------------------------------------------------------------------+
+ | 31/07/03 | KRAUTH J. | Changes for the MSX-Box |
+ +-----------------------------------------------------------------------+
+*/
+
+#include "addi_amcc_S5920.h"
+
+/*+----------------------------------------------------------------------------+*/
+/*| Function Name : INT i_AddiHeaderRW_ReadEeprom |*/
+/*| (INT i_NbOfWordsToRead, |*/
+/*| DWORD dw_PCIBoardEepromAddress, |*/
+/*| WORD w_EepromStartAddress, |*/
+/*| PWORD pw_DataRead) |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Task : Read word from the 5920 eeprom. |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Input Parameters : INT i_NbOfWordsToRead : Nbr. of word to read |*/
+/*| DWORD dw_PCIBoardEepromAddress : Address of the eeprom |*/
+/*| WORD w_EepromStartAddress : Eeprom strat address |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Output Parameters : PWORD pw_DataRead : Read data |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Return Value : - |*/
+/*+----------------------------------------------------------------------------+*/
+
+INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
+ DWORD dw_PCIBoardEepromAddress,
+ WORD w_EepromStartAddress, PWORD pw_DataRead)
+{
+ DWORD dw_eeprom_busy = 0;
+ INT i_Counter = 0;
+ INT i_WordCounter;
+ INT i;
+ BYTE pb_ReadByte[1];
+ BYTE b_ReadLowByte = 0;
+ BYTE b_ReadHighByte = 0;
+ BYTE b_SelectedAddressLow = 0;
+ BYTE b_SelectedAddressHigh = 0;
+ WORD w_ReadWord = 0;
+
+ for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
+ i_WordCounter++) {
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ for (i_Counter = 0; i_Counter < 2; i_Counter++) {
+ b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256; //Read the low 8 bit part
+ b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256; //Read the high 8 bit part
+
+ //Select the load low address mode
+ outb(NVCMD_LOAD_LOW,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Load the low address
+ outb(b_SelectedAddressLow,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the load high address mode
+ outb(NVCMD_LOAD_HIGH,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Load the high address
+ outb(b_SelectedAddressHigh,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the READ mode
+ outb(NVCMD_BEGIN_READ,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Read data into the EEPROM
+ *pb_ReadByte =
+ inb(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR + 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the upper address part
+ if (i_Counter == 0) {
+ b_ReadLowByte = pb_ReadByte[0];
+ } else {
+ b_ReadHighByte = pb_ReadByte[0];
+ }
+
+ //Sleep
+ for (i = 0; i < 10000; i++) ;
+
+ }
+ w_ReadWord =
+ (b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
+ 256));
+
+ pw_DataRead[i_WordCounter] = w_ReadWord;
+
+ w_EepromStartAddress += 2; // to read the next word
+
+ } // for (...) i_NbOfWordsToRead
+ return (0);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h
new file mode 100644
index 00000000000..9ae56bc3ada
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+#define AMCC_OP_REG_MCSR 0x3c
+#define EEPROM_BUSY 0x80000000
+#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */
+#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */
+#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */
+#define NVCMD_BEGIN_WRITE (0x6 << 5) /* EEPROM begin write command */
+
+INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
+ DWORD dw_PCIBoardEepromAddress,
+ WORD w_EepromStartAddress, PWORD pw_DataRead);
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
new file mode 100644
index 00000000000..b50774cdcf7
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+/* Header file for AMCC s 5933 */
+
+#ifndef _AMCC_S5933_H_
+#define _AMCC_S5933_H_
+
+#include "../../comedidev.h"
+
+#include "../comedi_pci.h"
+
+#ifdef PCI_SUPPORT_VER1
+#error No support for 2.1.55 and older
+#endif
+
+/* written on base0 */
+#define FIFO_ADVANCE_ON_BYTE_2 0x20000000
+
+/* added for step 6 dma written on base2 */
+#define AMWEN_ENABLE 0x02
+
+#define A2P_FIFO_WRITE_ENABLE 0x01
+
+/* for transfer count enable bit */
+#define AGCSTS_TC_ENABLE 0x10000000
+
+/*
+ * ADDON RELATED ADDITIONS
+ */
+/* Constant */
+#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00
+#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200
+#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L
+#define APCI3120_AMWEN_ENABLE 0x02
+#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01
+#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L
+#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L
+#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L
+#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
+#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0
+#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0
+
+/* ADD_ON ::: this needed since apci supports 16 bit interface to add on */
+#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C
+#define APCI3120_ADD_ON_AGCSTS_HIGH (APCI3120_ADD_ON_AGCSTS_LOW + 2)
+#define APCI3120_ADD_ON_MWAR_LOW 0x24
+#define APCI3120_ADD_ON_MWAR_HIGH (APCI3120_ADD_ON_MWAR_LOW + 2)
+#define APCI3120_ADD_ON_MWTC_LOW 0x058
+#define APCI3120_ADD_ON_MWTC_HIGH (APCI3120_ADD_ON_MWTC_LOW + 2)
+
+/* AMCC */
+#define APCI3120_AMCC_OP_MCSR 0x3C
+#define APCI3120_AMCC_OP_REG_INTCSR 0x38
+
+/*
+ * AMCC Operation Register Offsets - PCI
+ */
+#define AMCC_OP_REG_OMB1 0x00
+#define AMCC_OP_REG_OMB2 0x04
+#define AMCC_OP_REG_OMB3 0x08
+#define AMCC_OP_REG_OMB4 0x0c
+#define AMCC_OP_REG_IMB1 0x10
+#define AMCC_OP_REG_IMB2 0x14
+#define AMCC_OP_REG_IMB3 0x18
+#define AMCC_OP_REG_IMB4 0x1c
+#define AMCC_OP_REG_FIFO 0x20
+#define AMCC_OP_REG_MWAR 0x24
+#define AMCC_OP_REG_MWTC 0x28
+#define AMCC_OP_REG_MRAR 0x2c
+#define AMCC_OP_REG_MRTC 0x30
+#define AMCC_OP_REG_MBEF 0x34
+#define AMCC_OP_REG_INTCSR 0x38
+/* INT source */
+#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2)
+/* FIFO ctrl */
+#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3)
+#define AMCC_OP_REG_MCSR 0x3c
+/* Data in byte 2 */
+#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2)
+/* Command in byte 3 */
+#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3)
+
+#define AMCC_FIFO_DEPTH_DWORD 8
+#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof(u32))
+
+/*
+ * AMCC Operation Registers Size - PCI
+ */
+#define AMCC_OP_REG_SIZE 64 /* in bytes */
+
+/*
+ * AMCC Operation Register Offsets - Add-on
+ */
+#define AMCC_OP_REG_AIMB1 0x00
+#define AMCC_OP_REG_AIMB2 0x04
+#define AMCC_OP_REG_AIMB3 0x08
+#define AMCC_OP_REG_AIMB4 0x0c
+#define AMCC_OP_REG_AOMB1 0x10
+#define AMCC_OP_REG_AOMB2 0x14
+#define AMCC_OP_REG_AOMB3 0x18
+#define AMCC_OP_REG_AOMB4 0x1c
+#define AMCC_OP_REG_AFIFO 0x20
+#define AMCC_OP_REG_AMWAR 0x24
+#define AMCC_OP_REG_APTA 0x28
+#define AMCC_OP_REG_APTD 0x2c
+#define AMCC_OP_REG_AMRAR 0x30
+#define AMCC_OP_REG_AMBEF 0x34
+#define AMCC_OP_REG_AINT 0x38
+#define AMCC_OP_REG_AGCSTS 0x3c
+#define AMCC_OP_REG_AMWTC 0x58
+#define AMCC_OP_REG_AMRTC 0x5c
+
+/*
+ * AMCC - Add-on General Control/Status Register
+ */
+#define AGCSTS_CONTROL_MASK 0xfffff000
+#define AGCSTS_NV_ACC_MASK 0xe0000000
+#define AGCSTS_RESET_MASK 0x0e000000
+#define AGCSTS_NV_DA_MASK 0x00ff0000
+#define AGCSTS_BIST_MASK 0x0000f000
+#define AGCSTS_STATUS_MASK 0x000000ff
+#define AGCSTS_TCZERO_MASK 0x000000c0
+#define AGCSTS_FIFO_ST_MASK 0x0000003f
+
+#define AGCSTS_RESET_MBFLAGS 0x08000000
+#define AGCSTS_RESET_P2A_FIFO 0x04000000
+#define AGCSTS_RESET_A2P_FIFO 0x02000000
+#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
+
+#define AGCSTS_A2P_TCOUNT 0x00000080
+#define AGCSTS_P2A_TCOUNT 0x00000040
+
+#define AGCSTS_FS_P2A_EMPTY 0x00000020
+#define AGCSTS_FS_P2A_HALF 0x00000010
+#define AGCSTS_FS_P2A_FULL 0x00000008
+
+#define AGCSTS_FS_A2P_EMPTY 0x00000004
+#define AGCSTS_FS_A2P_HALF 0x00000002
+#define AGCSTS_FS_A2P_FULL 0x00000001
+
+/*
+ * AMCC - Add-on Interrupt Control/Status Register
+ */
+#define AINT_INT_MASK 0x00ff0000
+#define AINT_SEL_MASK 0x0000ffff
+#define AINT_IS_ENSEL_MASK 0x00001f1f
+
+#define AINT_INT_ASSERTED 0x00800000
+#define AINT_BM_ERROR 0x00200000
+#define AINT_BIST_INT 0x00100000
+
+#define AINT_RT_COMPLETE 0x00080000
+#define AINT_WT_COMPLETE 0x00040000
+
+#define AINT_OUT_MB_INT 0x00020000
+#define AINT_IN_MB_INT 0x00010000
+
+#define AINT_READ_COMPL 0x00008000
+#define AINT_WRITE_COMPL 0x00004000
+
+#define AINT_OMB_ENABLE 0x00001000
+#define AINT_OMB_SELECT 0x00000c00
+#define AINT_OMB_BYTE 0x00000300
+
+#define AINT_IMB_ENABLE 0x00000010
+#define AINT_IMB_SELECT 0x0000000c
+#define AINT_IMB_BYTE 0x00000003
+
+/* Enable Bus Mastering */
+#define EN_A2P_TRANSFERS 0x00000400
+/* FIFO Flag Reset */
+#define RESET_A2P_FLAGS 0x04000000L
+/* FIFO Relative Priority */
+#define A2P_HI_PRIORITY 0x00000100L
+/* Identify Interrupt Sources */
+#define ANY_S593X_INT 0x00800000L
+#define READ_TC_INT 0x00080000L
+#define WRITE_TC_INT 0x00040000L
+#define IN_MB_INT 0x00020000L
+#define MASTER_ABORT_INT 0x00100000L
+#define TARGET_ABORT_INT 0x00200000L
+#define BUS_MASTER_INT 0x00200000L
+
+/****************************************************************************/
+
+struct pcilst_struct {
+ struct pcilst_struct *next;
+ int used;
+ struct pci_dev *pcidev;
+ unsigned short vendor;
+ unsigned short device;
+ unsigned char pci_bus;
+ unsigned char pci_slot;
+ unsigned char pci_func;
+ resource_size_t io_addr[5];
+ unsigned int irq;
+};
+
+/* ptr to root list of all amcc devices */
+struct pcilst_struct *amcc_devices;
+
+static const int i_ADDIDATADeviceID[] = { 0x15B8, 0x10E8 };
+
+/****************************************************************************/
+
+void v_pci_card_list_init(unsigned short pci_vendor, char display);
+void v_pci_card_list_cleanup(unsigned short pci_vendor);
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
+ unsigned short
+ device_id);
+int i_find_free_pci_card_by_position(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot,
+ struct pcilst_struct **card);
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot,
+ int i_Master);
+
+int pci_card_alloc(struct pcilst_struct *amcc, int master);
+int i_pci_card_free(struct pcilst_struct *amcc);
+void v_pci_card_list_display(void);
+int i_pci_card_data(struct pcilst_struct *amcc,
+ unsigned char *pci_bus, unsigned char *pci_slot,
+ unsigned char *pci_func, resource_size_t * io_addr,
+ unsigned int *irq);
+
+/****************************************************************************/
+
+/* build list of amcc cards in this system */
+void v_pci_card_list_init(unsigned short pci_vendor, char display)
+{
+ struct pci_dev *pcidev;
+ struct pcilst_struct *amcc, *last;
+ int i;
+ int i_Count = 0;
+ amcc_devices = NULL;
+ last = NULL;
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ for (i_Count = 0; i_Count < 2; i_Count++) {
+ pci_vendor = i_ADDIDATADeviceID[i_Count];
+ if (pcidev->vendor == pci_vendor) {
+ amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
+ memset(amcc, 0, sizeof(*amcc));
+
+ amcc->pcidev = pcidev;
+ if (last)
+ last->next = amcc;
+ else
+ amcc_devices = amcc;
+ last = amcc;
+
+ amcc->vendor = pcidev->vendor;
+ amcc->device = pcidev->device;
+ amcc->pci_bus = pcidev->bus->number;
+ amcc->pci_slot = PCI_SLOT(pcidev->devfn);
+ amcc->pci_func = PCI_FUNC(pcidev->devfn);
+ /* Note: resources may be invalid if PCI device
+ * not enabled, but they are corrected in
+ * pci_card_alloc. */
+ for (i = 0; i < 5; i++)
+ amcc->io_addr[i] =
+ pci_resource_start(pcidev, i);
+ amcc->irq = pcidev->irq;
+
+ }
+ }
+ }
+
+ if (display)
+ v_pci_card_list_display();
+}
+
+/****************************************************************************/
+/* free up list of amcc cards in this system */
+void v_pci_card_list_cleanup(unsigned short pci_vendor)
+{
+ struct pcilst_struct *amcc, *next;
+
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ kfree(amcc);
+ }
+
+ amcc_devices = NULL;
+}
+
+/****************************************************************************/
+/* find first unused card with this device_id */
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
+ unsigned short device_id)
+{
+ struct pcilst_struct *amcc, *next;
+
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ if ((!amcc->used) && (amcc->device == device_id)
+ && (amcc->vendor == vendor_id))
+ return amcc;
+
+ }
+
+ return NULL;
+}
+
+/****************************************************************************/
+/* find card on requested position */
+int i_find_free_pci_card_by_position(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot,
+ struct pcilst_struct **card)
+{
+ struct pcilst_struct *amcc, *next;
+
+ *card = NULL;
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
+ && (amcc->pci_bus == pci_bus)
+ && (amcc->pci_slot == pci_slot)) {
+ if (!(amcc->used)) {
+ *card = amcc;
+ return 0; /* ok, card is found */
+ } else {
+ rt_printk(" - \nCard on requested position is used b:s %d:%d!\n",
+ pci_bus, pci_slot);
+ return 2; /* card exist but is used */
+ }
+ }
+ }
+
+ /* no card found */
+ return 1;
+}
+
+/****************************************************************************/
+/* mark card as used */
+int pci_card_alloc(struct pcilst_struct *amcc, int master)
+{
+ int i;
+
+ if (!amcc)
+ return -1;
+
+ if (amcc->used)
+ return 1;
+ if (comedi_pci_enable(amcc->pcidev, "addi_amcc_s5933"))
+ return -1;
+ /* Resources will be accurate now. */
+ for (i = 0; i < 5; i++)
+ amcc->io_addr[i] = pci_resource_start(amcc->pcidev, i);
+ if (master)
+ pci_set_master(amcc->pcidev);
+ amcc->used = 1;
+
+ return 0;
+}
+
+/****************************************************************************/
+/* mark card as free */
+int i_pci_card_free(struct pcilst_struct *amcc)
+{
+ if (!amcc)
+ return -1;
+
+ if (!amcc->used)
+ return 1;
+ amcc->used = 0;
+ comedi_pci_disable(amcc->pcidev);
+ return 0;
+}
+
+/****************************************************************************/
+/* display list of found cards */
+void v_pci_card_list_display(void)
+{
+ struct pcilst_struct *amcc, *next;
+
+ printk(KERN_DEBUG "List of pci cards\n");
+ printk(KERN_DEBUG "bus:slot:func vendor device io_amcc io_daq irq used\n");
+
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ printk
+ ("%2d %2d %2d 0x%4x 0x%4x 0x%8llx 0x%8llx %2u %2d\n",
+ amcc->pci_bus, amcc->pci_slot, amcc->pci_func,
+ amcc->vendor, amcc->device,
+ (unsigned long long)amcc->io_addr[0],
+ (unsigned long long)amcc->io_addr[2], amcc->irq,
+ amcc->used);
+
+ }
+}
+
+/****************************************************************************/
+/* return all card information for driver */
+int i_pci_card_data(struct pcilst_struct *amcc,
+ unsigned char *pci_bus, unsigned char *pci_slot,
+ unsigned char *pci_func, resource_size_t * io_addr,
+ unsigned int *irq)
+{
+ int i;
+
+ if (!amcc)
+ return -1;
+ *pci_bus = amcc->pci_bus;
+ *pci_slot = amcc->pci_slot;
+ *pci_func = amcc->pci_func;
+ for (i = 0; i < 5; i++)
+ io_addr[i] = amcc->io_addr[i];
+ *irq = amcc->irq;
+ return 0;
+}
+
+/****************************************************************************/
+/* select and alloc card */
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot,
+ int i_Master)
+{
+ struct pcilst_struct *card;
+
+ if ((pci_bus < 1) & (pci_slot < 1)) {
+ /* use autodetection */
+ card = ptr_find_free_pci_card_by_device(vendor_id, device_id);
+ if (card == NULL) {
+ rt_printk(" - Unused card not found in system!\n");
+ return NULL;
+ }
+ } else {
+ switch (i_find_free_pci_card_by_position(vendor_id, device_id,
+ pci_bus, pci_slot,
+ &card)) {
+ case 1:
+ rt_printk(" - Card not found on requested position b:s %d:%d!\n",
+ pci_bus, pci_slot);
+ return NULL;
+ case 2:
+ rt_printk(" - Card on requested position is used b:s %d:%d!\n",
+ pci_bus, pci_slot);
+ return NULL;
+ }
+ }
+
+ if (pci_card_alloc(card, i_Master) != 0) {
+ rt_printk(" - Can't allocate card!\n");
+ return NULL;
+
+ }
+
+ return card;
+}
+#endif
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c
new file mode 100644
index 00000000000..618c69b6838
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c
@@ -0,0 +1,3062 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : ADDI DATA | Compiler : GCC |
+ | Modulname : addi_common.c | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Author : | Date : |
+ +-----------------------------------------------------------------------+
+ | Description : ADDI COMMON Main Module |
+ +-----------------------------------------------------------------------+
+ | CONFIG OPTIONS |
+ | option[0] - PCI bus number - if bus number and slot number are 0, |
+ | then driver search for first unused card |
+ | option[1] - PCI slot number |
+ | |
+ | option[2] = 0 - DMA ENABLE |
+ | = 1 - DMA DISABLE |
+ +----------+-----------+------------------------------------------------+
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include "../../comedidev.h"
+#include <asm/io.h>
+#if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
+#include <asm/i387.h>
+#endif
+#include "../comedi_fc.h"
+
+#include "addi_common.h"
+#include "addi_amcc_s5933.h"
+
+//Update-0.7.57->0.7.68MODULE_AUTHOR("ADDI-DATA GmbH <info@addi-data.com>");
+//Update-0.7.57->0.7.68MODULE_DESCRIPTION("Comedi ADDI-DATA module");
+//Update-0.7.57->0.7.68MODULE_LICENSE("GPL");
+
+#define devpriv ((addi_private *)dev->private)
+#define this_board ((boardtype *)dev->board_ptr)
+
+#if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
+//BYTE b_SaveFPUReg [94];
+
+void fpu_begin(void)
+{
+ //asm ("fstenv b_SaveFPUReg");
+ kernel_fpu_begin();
+}
+
+void fpu_end(void)
+{
+ // asm ("frstor b_SaveFPUReg");
+ kernel_fpu_end();
+}
+#endif
+
+#include "addi_eeprom.c"
+#if (defined (CONFIG_APCI_3120) || defined (CONFIG_APCI_3001))
+#include "hwdrv_apci3120.c"
+#endif
+#ifdef CONFIG_APCI_1032
+#include "hwdrv_apci1032.c"
+#endif
+#ifdef CONFIG_APCI_1516
+#include "hwdrv_apci1516.c"
+#endif
+#ifdef CONFIG_APCI_2016
+#include "hwdrv_apci2016.c"
+#endif
+#ifdef CONFIG_APCI_2032
+#include "hwdrv_apci2032.c"
+#endif
+#ifdef CONFIG_APCI_2200
+#include "hwdrv_apci2200.c"
+#endif
+#ifdef CONFIG_APCI_1564
+#include "hwdrv_apci1564.c"
+#endif
+#ifdef CONFIG_APCI_1500
+#include "hwdrv_apci1500.c"
+#endif
+#ifdef CONFIG_APCI_3501
+#include "hwdrv_apci3501.c"
+#endif
+#ifdef CONFIG_APCI_035
+#include "hwdrv_apci035.c"
+#endif
+#if (defined (CONFIG_APCI_3200) || defined (CONFIG_APCI_3300))
+#include "hwdrv_apci3200.c"
+#endif
+#ifdef CONFIG_APCI_1710
+#include "hwdrv_APCI1710.c"
+#endif
+#ifdef CONFIG_APCI_16XX
+#include "hwdrv_apci16xx.c"
+#endif
+#ifdef CONFIG_APCI_3XXX
+#include "hwdrv_apci3xxx.c"
+#endif
+
+#ifndef COMEDI_SUBD_TTLIO
+#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
+#endif
+
+static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = {
+#ifdef CONFIG_APCI_3120
+ {APCI3120_BOARD_VENDOR_ID, 0x818D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1032
+ {APCI1032_BOARD_VENDOR_ID, 0x1003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1516
+ {APCI1516_BOARD_VENDOR_ID, 0x1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_2016
+ {APCI2016_BOARD_VENDOR_ID, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_2032
+ {APCI2032_BOARD_VENDOR_ID, 0x1004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_2200
+ {APCI2200_BOARD_VENDOR_ID, 0x1005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1564
+ {APCI1564_BOARD_VENDOR_ID, 0x1006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1500
+ {APCI1500_BOARD_VENDOR_ID, 0x80fc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3001
+ {APCI3120_BOARD_VENDOR_ID, 0x828D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3501
+ {APCI3501_BOARD_VENDOR_ID, 0x3001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_035
+ {APCI035_BOARD_VENDOR_ID, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3200
+ {APCI3200_BOARD_VENDOR_ID, 0x3000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3300
+ {APCI3200_BOARD_VENDOR_ID, 0x3007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1710
+ {APCI1710_BOARD_VENDOR_ID, APCI1710_BOARD_DEVICE_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_16XX
+ {0x15B8, 0x1009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x100A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3XXX
+ {0x15B8, 0x3010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x300F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x300E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3015, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3016, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3017, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x301A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x301B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x301C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x301D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x301E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x301F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x300B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, addi_apci_tbl);
+
+static const boardtype boardtypes[] = {
+#ifdef CONFIG_APCI_3120
+ {"apci3120",
+ APCI3120_BOARD_VENDOR_ID,
+ 0x818D,
+ AMCC_OP_REG_SIZE,
+ APCI3120_ADDRESS_RANGE,
+ 8,
+ 0,
+ ADDIDATA_NO_EEPROM,
+ NULL,
+ 16,
+ 8,
+ 16,
+ 8,
+ 0xffff,
+ 0x3fff,
+ &range_apci3120_ai,
+ &range_apci3120_ao,
+ 4,
+ 4,
+ 0x0f,
+ 0,
+ NULL,
+ 1,
+ 1,
+ 1,
+ 10000,
+ 100000,
+ v_APCI3120_Interrupt,
+ i_APCI3120_Reset,
+ i_APCI3120_InsnConfigAnalogInput,
+ i_APCI3120_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ i_APCI3120_CommandTestAnalogInput,
+ i_APCI3120_CommandAnalogInput,
+ i_APCI3120_StopCyclicAcquisition,
+ NULL,
+ i_APCI3120_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ i_APCI3120_InsnReadDigitalInput,
+ NULL,
+ i_APCI3120_InsnBitsDigitalInput,
+ i_APCI3120_InsnConfigDigitalOutput,
+ i_APCI3120_InsnWriteDigitalOutput,
+ i_APCI3120_InsnBitsDigitalOutput,
+ NULL,
+ i_APCI3120_InsnConfigTimer,
+ i_APCI3120_InsnWriteTimer,
+ i_APCI3120_InsnReadTimer,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_1032
+ {"apci1032",
+ APCI1032_BOARD_VENDOR_ID,
+ 0x1003,
+ 4,
+ APCI1032_ADDRESS_RANGE,
+ 0,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_93C76,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 32,
+ 0,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ v_APCI1032_Interrupt,
+ i_APCI1032_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI1032_ConfigDigitalInput,
+ i_APCI1032_Read1DigitalInput,
+ NULL,
+ i_APCI1032_ReadMoreDigitalInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_1516
+ {"apci1516",
+ APCI1516_BOARD_VENDOR_ID,
+ 0x1001,
+ 128,
+ APCI1516_ADDRESS_RANGE,
+ 32,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_S5920,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 8,
+ 8,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ NULL,
+ i_APCI1516_Reset,
+ NULL, NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI1516_Read1DigitalInput,
+ NULL,
+ i_APCI1516_ReadMoreDigitalInput,
+ i_APCI1516_ConfigDigitalOutput,
+ i_APCI1516_WriteDigitalOutput,
+ i_APCI1516_ReadDigitalOutput,
+ NULL,
+ i_APCI1516_ConfigWatchdog,
+ i_APCI1516_StartStopWriteWatchdog,
+ i_APCI1516_ReadWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_2016
+ {"apci2016",
+ APCI2016_BOARD_VENDOR_ID,
+ 0x1002,
+ 128,
+ APCI2016_ADDRESS_RANGE,
+ 32,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_S5920,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 0,
+ 16,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ NULL,
+ i_APCI2016_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI2016_ConfigDigitalOutput,
+ i_APCI2016_WriteDigitalOutput,
+ i_APCI2016_BitsDigitalOutput,
+ NULL,
+ i_APCI2016_ConfigWatchdog,
+ i_APCI2016_StartStopWriteWatchdog,
+ i_APCI2016_ReadWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_2032
+ {"apci2032",
+ APCI2032_BOARD_VENDOR_ID,
+ 0x1004,
+ 4,
+ APCI2032_ADDRESS_RANGE,
+ 0,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_93C76,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 0,
+ 32,
+ 0xffffffff,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ v_APCI2032_Interrupt,
+ i_APCI2032_Reset,
+ NULL, NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI2032_ConfigDigitalOutput,
+ i_APCI2032_WriteDigitalOutput,
+ i_APCI2032_ReadDigitalOutput,
+ i_APCI2032_ReadInterruptStatus,
+ i_APCI2032_ConfigWatchdog,
+ i_APCI2032_StartStopWriteWatchdog,
+ i_APCI2032_ReadWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_2200
+ {"apci2200",
+ APCI2200_BOARD_VENDOR_ID,
+ 0x1005,
+ 4,
+ APCI2200_ADDRESS_RANGE,
+ 0,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_93C76,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 8,
+ 16,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ NULL,
+ i_APCI2200_Reset,
+ NULL, NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI2200_Read1DigitalInput,
+ NULL,
+ i_APCI2200_ReadMoreDigitalInput,
+ i_APCI2200_ConfigDigitalOutput,
+ i_APCI2200_WriteDigitalOutput,
+ i_APCI2200_ReadDigitalOutput,
+ NULL,
+ i_APCI2200_ConfigWatchdog,
+ i_APCI2200_StartStopWriteWatchdog,
+ i_APCI2200_ReadWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_1564
+ {"apci1564",
+ APCI1564_BOARD_VENDOR_ID,
+ 0x1006,
+ 128,
+ APCI1564_ADDRESS_RANGE,
+ 0,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_93C76,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 32,
+ 32,
+ 0xffffffff,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ v_APCI1564_Interrupt,
+ i_APCI1564_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI1564_ConfigDigitalInput,
+ i_APCI1564_Read1DigitalInput,
+ NULL,
+ i_APCI1564_ReadMoreDigitalInput,
+ i_APCI1564_ConfigDigitalOutput,
+ i_APCI1564_WriteDigitalOutput,
+ i_APCI1564_ReadDigitalOutput,
+ i_APCI1564_ReadInterruptStatus,
+ i_APCI1564_ConfigTimerCounterWatchdog,
+ i_APCI1564_StartStopWriteTimerCounterWatchdog,
+ i_APCI1564_ReadTimerCounterWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_1500
+ {"apci1500",
+ APCI1500_BOARD_VENDOR_ID,
+ 0x80fc,
+ 128,
+ APCI1500_ADDRESS_RANGE,
+ 4,
+ 0,
+ ADDIDATA_NO_EEPROM,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 16,
+ 16,
+ 0xffff,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ v_APCI1500_Interrupt,
+ i_APCI1500_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI1500_ConfigDigitalInputEvent,
+ i_APCI1500_Initialisation,
+ i_APCI1500_StartStopInputEvent,
+ i_APCI1500_ReadMoreDigitalInput,
+ i_APCI1500_ConfigDigitalOutputErrorInterrupt,
+ i_APCI1500_WriteDigitalOutput,
+ i_APCI1500_ConfigureInterrupt,
+ NULL,
+ i_APCI1500_ConfigCounterTimerWatchdog,
+ i_APCI1500_StartStopTriggerTimerCounterWatchdog,
+ i_APCI1500_ReadInterruptMask,
+ i_APCI1500_ReadCounterTimerWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_3001
+ {"apci3001",
+ APCI3120_BOARD_VENDOR_ID,
+ 0x828D,
+ AMCC_OP_REG_SIZE,
+ APCI3120_ADDRESS_RANGE,
+ 8,
+ 0,
+ ADDIDATA_NO_EEPROM,
+ NULL,
+ 16,
+ 8,
+ 16,
+ 0,
+ 0xfff,
+ 0,
+ &range_apci3120_ai,
+ NULL,
+ 4,
+ 4,
+ 0x0f,
+ 0,
+ NULL,
+ 1,
+ 1,
+ 1,
+ 10000,
+ 100000,
+ v_APCI3120_Interrupt,
+ i_APCI3120_Reset,
+ i_APCI3120_InsnConfigAnalogInput,
+ i_APCI3120_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ i_APCI3120_CommandTestAnalogInput,
+ i_APCI3120_CommandAnalogInput,
+ i_APCI3120_StopCyclicAcquisition,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3120_InsnReadDigitalInput,
+ NULL,
+ i_APCI3120_InsnBitsDigitalInput,
+ i_APCI3120_InsnConfigDigitalOutput,
+ i_APCI3120_InsnWriteDigitalOutput,
+ i_APCI3120_InsnBitsDigitalOutput,
+ NULL,
+ i_APCI3120_InsnConfigTimer,
+ i_APCI3120_InsnWriteTimer,
+ i_APCI3120_InsnReadTimer,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_3501
+ {"apci3501",
+ APCI3501_BOARD_VENDOR_ID,
+ 0x3001,
+ 64,
+ APCI3501_ADDRESS_RANGE,
+ 0,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_S5933,
+ 0,
+ 0,
+ 0,
+ 8,
+ 0,
+ 16383,
+ NULL,
+ &range_apci3501_ao,
+ 2,
+ 2,
+ 0x3,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ v_APCI3501_Interrupt,
+ i_APCI3501_Reset,
+ NULL, NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3501_ConfigAnalogOutput,
+ i_APCI3501_WriteAnalogOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3501_ReadDigitalInput,
+ i_APCI3501_ConfigDigitalOutput,
+ i_APCI3501_WriteDigitalOutput,
+ i_APCI3501_ReadDigitalOutput,
+ NULL,
+ i_APCI3501_ConfigTimerCounterWatchdog,
+ i_APCI3501_StartStopWriteTimerCounterWatchdog,
+ i_APCI3501_ReadTimerCounterWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_035
+ {"apci035",
+ APCI035_BOARD_VENDOR_ID,
+ 0x0300,
+ 127,
+ APCI035_ADDRESS_RANGE,
+ 0,
+ 0,
+ 1,
+ ADDIDATA_S5920,
+ 16,
+ 8,
+ 16,
+ 0,
+ 0xff,
+ 0,
+ &range_apci035_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 10000,
+ 100000,
+ v_APCI035_Interrupt,
+ i_APCI035_Reset,
+ i_APCI035_ConfigAnalogInput,
+ i_APCI035_ReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI035_ConfigTimerWatchdog,
+ i_APCI035_StartStopWriteTimerWatchdog,
+ i_APCI035_ReadTimerWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_3200
+ {"apci3200",
+ APCI3200_BOARD_VENDOR_ID,
+ 0x3000,
+ 128,
+ 256,
+ 4,
+ 4,
+ ADDIDATA_EEPROM,
+ ADDIDATA_S5920,
+ 16,
+ 8,
+ 16,
+ 0,
+ 0x3ffff,
+ 0,
+ &range_apci3200_ai,
+ NULL,
+ 4,
+ 4,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 10000,
+ 100000,
+ v_APCI3200_Interrupt,
+ i_APCI3200_Reset,
+ i_APCI3200_ConfigAnalogInput,
+ i_APCI3200_ReadAnalogInput,
+ i_APCI3200_InsnWriteReleaseAnalogInput,
+ i_APCI3200_InsnBits_AnalogInput_Test,
+ i_APCI3200_CommandTestAnalogInput,
+ i_APCI3200_CommandAnalogInput,
+ i_APCI3200_StopCyclicAcquisition,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3200_ReadDigitalInput,
+ i_APCI3200_ConfigDigitalOutput,
+ i_APCI3200_WriteDigitalOutput,
+ i_APCI3200_ReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_3300
+ //Begin JK 20.10.2004: APCI-3300 integration
+ {"apci3300",
+ APCI3200_BOARD_VENDOR_ID,
+ 0x3007,
+ 128,
+ 256,
+ 4,
+ 4,
+ ADDIDATA_EEPROM,
+ ADDIDATA_S5920,
+ 0,
+ 8,
+ 8,
+ 0,
+ 0x3ffff,
+ 0,
+ &range_apci3300_ai,
+ NULL,
+ 4,
+ 4,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 10000,
+ 100000,
+ v_APCI3200_Interrupt,
+ i_APCI3200_Reset,
+ i_APCI3200_ConfigAnalogInput,
+ i_APCI3200_ReadAnalogInput,
+ i_APCI3200_InsnWriteReleaseAnalogInput,
+ i_APCI3200_InsnBits_AnalogInput_Test,
+ i_APCI3200_CommandTestAnalogInput,
+ i_APCI3200_CommandAnalogInput,
+ i_APCI3200_StopCyclicAcquisition,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3200_ReadDigitalInput,
+ i_APCI3200_ConfigDigitalOutput,
+ i_APCI3200_WriteDigitalOutput,
+ i_APCI3200_ReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_1710
+ {"apci1710", APCI1710_BOARD_VENDOR_ID, APCI1710_BOARD_DEVICE_ID,
+ 128,
+ 8,
+ 256,
+ 0,
+ ADDIDATA_NO_EEPROM,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ v_APCI1710_Interrupt,
+ i_APCI1710_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_16XX
+ {"apci1648",
+ 0x15B8,
+ 0x1009,
+ 128,
+ 0,
+ 0,
+ 0,
+ ADDIDATA_NO_EEPROM,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 48,
+ &range_apci16xx_ttl,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ i_APCI16XX_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI16XX_InsnConfigInitTTLIO,
+ i_APCI16XX_InsnBitsReadTTLIO,
+ i_APCI16XX_InsnReadTTLIOAllPortValue,
+ i_APCI16XX_InsnBitsWriteTTLIO},
+
+ {"apci1696",
+ 0x15B8,
+ 0x100A,
+ 128,
+ 0,
+ 0,
+ 0,
+ ADDIDATA_NO_EEPROM,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 96,
+ &range_apci16xx_ttl,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ i_APCI16XX_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI16XX_InsnConfigInitTTLIO,
+ i_APCI16XX_InsnBitsReadTTLIO,
+ i_APCI16XX_InsnReadTTLIOAllPortValue,
+ i_APCI16XX_InsnBitsWriteTTLIO},
+#endif
+#ifdef CONFIG_APCI_3XXX
+ {"apci3000-16",
+ 0x15B8,
+ 0x3010,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 0,
+ 4095,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3000-8",
+ 0x15B8,
+ 0x300F,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 0,
+ 4095,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3000-4",
+ 0x15B8,
+ 0x300E,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 4,
+ 2,
+ 4,
+ 0,
+ 4095,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3006-16",
+ 0x15B8,
+ 0x3013,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3006-8",
+ 0x15B8,
+ 0x3014,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3006-4",
+ 0x15B8,
+ 0x3015,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 4,
+ 2,
+ 4,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3010-16",
+ 0x15B8,
+ 0x3016,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 0,
+ 4095,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3010-8",
+ 0x15B8,
+ 0x3017,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 0,
+ 4095,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3010-4",
+ 0x15B8,
+ 0x3018,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 4,
+ 2,
+ 4,
+ 0,
+ 4095,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3016-16",
+ 0x15B8,
+ 0x3019,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3016-8",
+ 0x15B8,
+ 0x301A,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3016-4",
+ 0x15B8,
+ 0x301B,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 4,
+ 2,
+ 4,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3100-16-4",
+ 0x15B8,
+ 0x301C,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 4,
+ 4095,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3100-8-4",
+ 0x15B8,
+ 0x301D,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 4,
+ 4095,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3106-16-4",
+ 0x15B8,
+ 0x301E,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 4,
+ 65535,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3106-8-4",
+ 0x15B8,
+ 0x301F,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 4,
+ 65535,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3110-16-4",
+ 0x15B8,
+ 0x3020,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 4,
+ 4095,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3110-8-4",
+ 0x15B8,
+ 0x3021,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 4,
+ 4095,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3116-16-4",
+ 0x15B8,
+ 0x3022,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 4,
+ 65535,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3116-8-4",
+ 0x15B8,
+ 0x3023,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 4,
+ 65535,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3003",
+ 0x15B8,
+ 0x300B,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 0,
+ 4,
+ 4,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 7,
+ 2500,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+
+ {"apci3002-16",
+ 0x15B8,
+ 0x3002,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 0,
+ 16,
+ 16,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+
+ {"apci3002-8",
+ 0x15B8,
+ 0x3003,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 0,
+ 8,
+ 8,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+
+ {"apci3002-4",
+ 0x15B8,
+ 0x3004,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 0,
+ 4,
+ 4,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+
+ {"apci3500",
+ 0x15B8,
+ 0x3024,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 0,
+ 0,
+ 0,
+ 4,
+ 0,
+ 4095,
+ NULL,
+ &range_apci3XXX_ao,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+#endif
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(boardtype))
+
+struct comedi_driver driver_addi = {
+ driver_name:"addi_common",
+ module:THIS_MODULE,
+ attach:i_ADDI_Attach,
+ detach:i_ADDI_Detach,
+ num_names:n_boardtypes,
+ board_name:&boardtypes[0].pc_DriverName,
+ offset:sizeof(boardtype),
+};
+
+COMEDI_PCI_INITCLEANUP(driver_addi, addi_apci_tbl);
+
+/*
++----------------------------------------------------------------------------+
+| Function name :static int i_ADDI_Attach(struct comedi_device *dev, |
+| struct comedi_devconfig *it) |
+| |
++----------------------------------------------------------------------------+
+| Task :Detects the card. |
+| Configure the driver for a particular board. |
+| This function does all the initializations and memory |
+| allocation of data structures for the driver. |
++----------------------------------------------------------------------------+
+| Input Parameters :struct comedi_device *dev |
+| struct comedi_devconfig *it |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+static int i_ADDI_Attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret, pages, i, n_subdevices;
+ DWORD dw_Dummy;
+ resource_size_t io_addr[5];
+ unsigned int irq;
+ resource_size_t iobase_a, iobase_main, iobase_addon, iobase_reserved;
+ struct pcilst_struct *card = NULL;
+ unsigned char pci_bus, pci_slot, pci_func;
+ int i_Dma = 0;
+ static char c_Identifier[150];
+
+ sprintf(c_Identifier, "Addi-Data GmbH Comedi %s",
+ this_board->pc_DriverName);
+
+ if ((ret = alloc_private(dev, sizeof(addi_private))) < 0) {
+ return -ENOMEM;
+ }
+
+ if (!pci_list_builded) {
+ v_pci_card_list_init(this_board->i_VendorId, 1); //1 for displaying the list..
+ pci_list_builded = 1;
+ }
+ //rt_printk("comedi%d: addi_common: board=%s",dev->minor,this_board->pc_DriverName);
+
+ if ((this_board->i_Dma) && (it->options[2] == 0)) {
+ i_Dma = 1;
+ }
+
+ if ((card = ptr_select_and_alloc_pci_card(this_board->i_VendorId,
+ this_board->i_DeviceId,
+ it->options[0],
+ it->options[1], i_Dma)) == NULL) {
+ return -EIO;
+ }
+ devpriv->allocated = 1;
+
+ if ((i_pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0],
+ &irq)) < 0) {
+ i_pci_card_free(card);
+ printk(" - Can't get AMCC data!\n");
+ return -EIO;
+ }
+
+ iobase_a = io_addr[0];
+ iobase_main = io_addr[1];
+ iobase_addon = io_addr[2];
+ iobase_reserved = io_addr[3];
+ printk("\nBus %d: Slot %d: Funct%d\nBase0: 0x%8llx\nBase1: 0x%8llx\nBase2: 0x%8llx\nBase3: 0x%8llx\n", pci_bus, pci_slot, pci_func, (unsigned long long)io_addr[0], (unsigned long long)io_addr[1], (unsigned long long)io_addr[2], (unsigned long long)io_addr[3]);
+
+ if ((this_board->pc_EepromChip == NULL)
+ || (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) {
+ /************************************/
+ /* Test if more that 1 address used */
+ /************************************/
+
+ if (this_board->i_IorangeBase1 != 0) {
+ dev->iobase = (unsigned long)iobase_main; // DAQ base address...
+ } else {
+ dev->iobase = (unsigned long)iobase_a; // DAQ base address...
+ }
+
+ dev->board_name = this_board->pc_DriverName;
+ devpriv->amcc = card;
+ devpriv->iobase = (INT) dev->iobase;
+ devpriv->i_IobaseAmcc = (INT) iobase_a; //AMCC base address...
+ devpriv->i_IobaseAddon = (INT) iobase_addon; //ADD ON base address....
+ devpriv->i_IobaseReserved = (INT) iobase_reserved;
+ devpriv->ps_BoardInfo = this_board;
+ } else {
+ dev->board_name = this_board->pc_DriverName;
+ dev->iobase = (unsigned long)io_addr[2];
+ devpriv->amcc = card;
+ devpriv->iobase = (INT) io_addr[2];
+ devpriv->ps_BoardInfo = this_board;
+ devpriv->i_IobaseReserved = (INT) io_addr[3];
+ printk("\nioremap begin");
+ devpriv->dw_AiBase =
+ (ULONG_PTR) ioremap(io_addr[3],
+ this_board->i_IorangeBase3);
+ printk("\nioremap end");
+ }
+
+ //##
+
+ if (irq > 0) {
+ if (comedi_request_irq(irq, v_ADDI_Interrupt, IRQF_SHARED,
+ c_Identifier, dev) < 0) {
+ printk(", unable to allocate IRQ %u, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk("\nirq=%u", irq);
+ }
+ } else {
+ rt_printk(", IRQ disabled");
+ }
+
+ printk("\nOption %d %d %d\n", it->options[0], it->options[1],
+ it->options[2]);
+ dev->irq = irq;
+
+ // Read eepeom and fill boardtype Structure
+
+ if (this_board->i_PCIEeprom) {
+ printk("\nPCI Eeprom used");
+ if (!(strcmp(this_board->pc_EepromChip, "S5920"))) {
+ // Set 3 wait stait
+ if (!(strcmp(this_board->pc_DriverName, "apci035"))) {
+ outl(0x80808082, devpriv->i_IobaseAmcc + 0x60);
+ } else {
+ outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
+ }
+ // Enable the interrupt for the controler
+ dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
+ outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
+ printk("\nEnable the interrupt for the controler");
+ }
+ printk("\nRead Eeprom");
+ i_EepromReadMainHeader(io_addr[0], this_board->pc_EepromChip,
+ dev);
+ } else {
+ printk("\nPCI Eeprom unused");
+ }
+
+ if (it->options[2] > 0) {
+ devpriv->us_UseDma = ADDI_DISABLE;
+ } else {
+ devpriv->us_UseDma = ADDI_ENABLE;
+ }
+
+ if (this_board->i_Dma) {
+ printk("\nDMA used");
+ if (devpriv->us_UseDma == ADDI_ENABLE) {
+ // alloc DMA buffers
+ devpriv->b_DmaDoubleBuffer = 0;
+ for (i = 0; i < 2; i++) {
+ for (pages = 4; pages >= 0; pages--) {
+ if ((devpriv->ul_DmaBufferVirtual[i] =
+ (void *)
+ __get_free_pages
+ (GFP_KERNEL, pages))) {
+ break;
+ }
+ }
+ if (devpriv->ul_DmaBufferVirtual[i]) {
+ devpriv->ui_DmaBufferPages[i] = pages;
+ devpriv->ui_DmaBufferSize[i] =
+ PAGE_SIZE * pages;
+ devpriv->ui_DmaBufferSamples[i] =
+ devpriv->
+ ui_DmaBufferSize[i] >> 1;
+ devpriv->ul_DmaBufferHw[i] =
+ virt_to_bus((void *)devpriv->
+ ul_DmaBufferVirtual[i]);
+ }
+ }
+ if (!devpriv->ul_DmaBufferVirtual[0]) {
+ rt_printk
+ (", Can't allocate DMA buffer, DMA disabled!");
+ devpriv->us_UseDma = ADDI_DISABLE;
+ }
+
+ if (devpriv->ul_DmaBufferVirtual[1]) {
+ devpriv->b_DmaDoubleBuffer = 1;
+ }
+ }
+
+ if ((devpriv->us_UseDma == ADDI_ENABLE)) {
+ rt_printk("\nDMA ENABLED\n");
+ } else {
+ printk("\nDMA DISABLED\n");
+ }
+ }
+
+ if (!strcmp(this_board->pc_DriverName, "apci1710")) {
+#ifdef CONFIG_APCI_1710
+ i_ADDI_AttachPCI1710(dev);
+
+ // save base address
+ devpriv->s_BoardInfos.ui_Address = io_addr[2];
+#endif
+ } else {
+ //Update-0.7.57->0.7.68dev->n_subdevices = 7;
+ n_subdevices = 7;
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+ return ret;
+
+ // Allocate and Initialise AI Subdevice Structures
+ s = dev->subdevices + 0;
+ if ((this_board->i_NbrAiChannel)
+ || (this_board->i_NbrAiChannelDiff)) {
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags =
+ SDF_READABLE | SDF_RT | SDF_COMMON | SDF_GROUND
+ | SDF_DIFF;
+ if (this_board->i_NbrAiChannel) {
+ s->n_chan = this_board->i_NbrAiChannel;
+ devpriv->b_SingelDiff = 0;
+ } else {
+ s->n_chan = this_board->i_NbrAiChannelDiff;
+ devpriv->b_SingelDiff = 1;
+ }
+ s->maxdata = this_board->i_AiMaxdata;
+ s->len_chanlist = this_board->i_AiChannelList;
+ s->range_table = this_board->pr_AiRangelist;
+
+ /* Set the initialisation flag */
+ devpriv->b_AiInitialisation = 1;
+
+ s->insn_config =
+ this_board->i_hwdrv_InsnConfigAnalogInput;
+ s->insn_read = this_board->i_hwdrv_InsnReadAnalogInput;
+ s->insn_write =
+ this_board->i_hwdrv_InsnWriteAnalogInput;
+ s->insn_bits = this_board->i_hwdrv_InsnBitsAnalogInput;
+ s->do_cmdtest =
+ this_board->i_hwdrv_CommandTestAnalogInput;
+ s->do_cmd = this_board->i_hwdrv_CommandAnalogInput;
+ s->cancel = this_board->i_hwdrv_CancelAnalogInput;
+
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ // Allocate and Initialise AO Subdevice Structures
+ s = dev->subdevices + 1;
+ if (this_board->i_NbrAoChannel) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_GROUND | SDF_COMMON |
+ SDF_RT;
+ s->n_chan = this_board->i_NbrAoChannel;
+ s->maxdata = this_board->i_AoMaxdata;
+ s->len_chanlist = this_board->i_NbrAoChannel;
+ s->range_table = this_board->pr_AoRangelist;
+ s->insn_config =
+ this_board->i_hwdrv_InsnConfigAnalogOutput;
+ s->insn_write =
+ this_board->i_hwdrv_InsnWriteAnalogOutput;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ // Allocate and Initialise DI Subdevice Structures
+ s = dev->subdevices + 2;
+ if (this_board->i_NbrDiChannel) {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags =
+ SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->i_NbrDiChannel;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->i_NbrDiChannel;
+ s->range_table = &range_digital;
+ s->io_bits = 0; /* all bits input */
+ s->insn_config =
+ this_board->i_hwdrv_InsnConfigDigitalInput;
+ s->insn_read = this_board->i_hwdrv_InsnReadDigitalInput;
+ s->insn_write =
+ this_board->i_hwdrv_InsnWriteDigitalInput;
+ s->insn_bits = this_board->i_hwdrv_InsnBitsDigitalInput;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ // Allocate and Initialise DO Subdevice Structures
+ s = dev->subdevices + 3;
+ if (this_board->i_NbrDoChannel) {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITEABLE | SDF_RT |
+ SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->i_NbrDoChannel;
+ s->maxdata = this_board->i_DoMaxdata;
+ s->len_chanlist = this_board->i_NbrDoChannel;
+ s->range_table = &range_digital;
+ s->io_bits = 0xf; /* all bits output */
+
+ s->insn_config = this_board->i_hwdrv_InsnConfigDigitalOutput; //for digital output memory..
+ s->insn_write =
+ this_board->i_hwdrv_InsnWriteDigitalOutput;
+ s->insn_bits =
+ this_board->i_hwdrv_InsnBitsDigitalOutput;
+ s->insn_read =
+ this_board->i_hwdrv_InsnReadDigitalOutput;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ // Allocate and Initialise Timer Subdevice Structures
+ s = dev->subdevices + 4;
+ if (this_board->i_Timer) {
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_RT | SDF_GROUND |
+ SDF_COMMON;
+ s->n_chan = 1;
+ s->maxdata = 0;
+ s->len_chanlist = 1;
+ s->range_table = &range_digital;
+
+ s->insn_write = this_board->i_hwdrv_InsnWriteTimer;
+ s->insn_read = this_board->i_hwdrv_InsnReadTimer;
+ s->insn_config = this_board->i_hwdrv_InsnConfigTimer;
+ s->insn_bits = this_board->i_hwdrv_InsnBitsTimer;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ // Allocate and Initialise TTL
+ s = dev->subdevices + 5;
+ if (this_board->i_NbrTTLChannel) {
+ s->type = COMEDI_SUBD_TTLIO;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT |
+ SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->i_NbrTTLChannel;
+ s->maxdata = 1;
+ s->io_bits = 0; /* all bits input */
+ s->len_chanlist = this_board->i_NbrTTLChannel;
+ s->range_table = &range_digital;
+ s->insn_config = this_board->i_hwdr_ConfigInitTTLIO;
+ s->insn_bits = this_board->i_hwdr_ReadTTLIOBits;
+ s->insn_read = this_board->i_hwdr_ReadTTLIOAllPortValue;
+ s->insn_write = this_board->i_hwdr_WriteTTLIOChlOnOff;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* EEPROM */
+ s = dev->subdevices + 6;
+ if (this_board->i_PCIEeprom) {
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+ s->n_chan = 256;
+ s->maxdata = 0xffff;
+ s->insn_read = i_ADDIDATA_InsnReadEeprom;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ }
+
+ printk("\ni_ADDI_Attach end\n");
+ i_ADDI_Reset(dev);
+ devpriv->b_ValidDriver = 1;
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : static int i_ADDI_Detach(struct comedi_device *dev) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : Deallocates resources of the addi_common driver |
+| Free the DMA buffers, unregister irq. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+static int i_ADDI_Detach(struct comedi_device * dev)
+{
+
+ if (dev->private) {
+ if (devpriv->b_ValidDriver) {
+ i_ADDI_Reset(dev);
+ }
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+
+ if ((devpriv->ps_BoardInfo->pc_EepromChip == NULL)
+ || (strcmp(devpriv->ps_BoardInfo->pc_EepromChip,
+ ADDIDATA_9054) != 0)) {
+ if (devpriv->allocated) {
+ i_pci_card_free(devpriv->amcc);
+ }
+
+ if (devpriv->ul_DmaBufferVirtual[0]) {
+ free_pages((unsigned long)devpriv->
+ ul_DmaBufferVirtual[0],
+ devpriv->ui_DmaBufferPages[0]);
+ }
+
+ if (devpriv->ul_DmaBufferVirtual[1]) {
+ free_pages((unsigned long)devpriv->
+ ul_DmaBufferVirtual[1],
+ devpriv->ui_DmaBufferPages[1]);
+ }
+ } else {
+ iounmap((void *)devpriv->dw_AiBase);
+
+ if (devpriv->allocated) {
+ i_pci_card_free(devpriv->amcc);
+ }
+ }
+
+ if (pci_list_builded) {
+ //v_pci_card_list_cleanup(PCI_VENDOR_ID_AMCC);
+ v_pci_card_list_cleanup(this_board->i_VendorId);
+ pci_list_builded = 0;
+ }
+ }
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : static int i_ADDI_Reset(struct comedi_device *dev) |
+| |
++----------------------------------------------------------------------------+
+| Task : Disables all interrupts, Resets digital output to low, |
+| Set all analog output to low |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+static int i_ADDI_Reset(struct comedi_device * dev)
+{
+
+ this_board->i_hwdrv_Reset(dev);
+ return 0;
+}
+
+// Interrupt function
+/*
++----------------------------------------------------------------------------+
+| Function name : |
+|static void v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG) |
+| |
++----------------------------------------------------------------------------+
+| Task : Registerd interrupt routine |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+static irqreturn_t v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ this_board->v_hwdrv_Interrupt(irq, d);
+ return IRQ_RETVAL(1);
+}
+
+// EEPROM Read Function
+/*
++----------------------------------------------------------------------------+
+| Function name : |
+|INT i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data)
+| |
++----------------------------------------------------------------------------+
+| Task : Read 256 words from EEPROM |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters :(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+static int i_ADDIDATA_InsnReadEeprom(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ WORD w_Data;
+ WORD w_Address;
+ w_Address = CR_CHAN(insn->chanspec); // address to be read as 0,1,2,3...255
+
+ w_Data = w_EepromReadWord(devpriv->i_IobaseAmcc,
+ this_board->pc_EepromChip, 0x100 + (2 * w_Address));
+ data[0] = w_Data;
+ //multiplied by 2 bcozinput will be like 0,1,2...255
+ return insn->n;
+
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h
new file mode 100644
index 00000000000..19df5c1444a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/kmod.h>
+#include <linux/uaccess.h>
+#include "../../comedidev.h"
+#include "addi_amcc_s5933.h"
+
+#define ERROR -1
+#define SUCCESS 1
+
+/* variable type definition */
+typedef unsigned char BYTE, *PBYTE;
+typedef short SHORT, *PSHORT;
+typedef unsigned short USHORT, *PUSHORT;
+typedef unsigned short WORD, *PWORD;
+typedef int INT, *PINT;;
+typedef unsigned int UINT, *PUINT;
+typedef int LONG, *PLONG; /* 32-bit */
+typedef unsigned int ULONG, *PULONG; /* 32-bit */
+typedef unsigned int DWORD, *PDWORD; /* 32-bit */
+typedef unsigned long ULONG_PTR;
+
+typedef const struct comedi_lrange *PCRANGE;
+
+#define LOBYTE(W) (BYTE)((W) & 0xFF)
+#define HIBYTE(W) (BYTE)(((W) >> 8) & 0xFF)
+#define MAKEWORD(H, L) (USHORT)((L) | ((H) << 8))
+#define LOWORD(W) (USHORT)((W) & 0xFFFF)
+#define HIWORD(W) (USHORT)(((W) >> 16) & 0xFFFF)
+#define MAKEDWORD(H, L) (UINT)((L) | ((H) << 16))
+
+#define ADDI_ENABLE 1
+#define ADDI_DISABLE 0
+#define APCI1710_SAVE_INTERRUPT 1
+
+#define ADDIDATA_EEPROM 1
+#define ADDIDATA_NO_EEPROM 0
+#define ADDIDATA_93C76 "93C76"
+#define ADDIDATA_S5920 "S5920"
+#define ADDIDATA_S5933 "S5933"
+#define ADDIDATA_9054 "9054"
+
+/* ADDIDATA Enable Disable */
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+
+/* Structures */
+
+/* structure for the boardtype */
+typedef struct {
+ const char *pc_DriverName; // driver name
+ INT i_VendorId; //PCI vendor a device ID of card
+ INT i_DeviceId;
+ INT i_IorangeBase0;
+ INT i_IorangeBase1;
+ INT i_IorangeBase2; // base 2 range
+ INT i_IorangeBase3; // base 3 range
+ INT i_PCIEeprom; // eeprom present or not
+ char *pc_EepromChip; // type of chip
+ INT i_NbrAiChannel; // num of A/D chans
+ INT i_NbrAiChannelDiff; // num of A/D chans in diff mode
+ INT i_AiChannelList; // len of chanlist
+ INT i_NbrAoChannel; // num of D/A chans
+ INT i_AiMaxdata; // resolution of A/D
+ INT i_AoMaxdata; // resolution of D/A
+ PCRANGE pr_AiRangelist; // rangelist for A/D
+ PCRANGE pr_AoRangelist; // rangelist for D/A
+
+ INT i_NbrDiChannel; // Number of DI channels
+ INT i_NbrDoChannel; // Number of DO channels
+ INT i_DoMaxdata; // data to set all chanels high
+
+ INT i_NbrTTLChannel; // Number of TTL channels
+ PCRANGE pr_TTLRangelist; // rangelist for TTL
+
+ INT i_Dma; // dma present or not
+ INT i_Timer; // timer subdevice present or not
+ BYTE b_AvailableConvertUnit;
+ UINT ui_MinAcquisitiontimeNs; // Minimum Acquisition in Nano secs
+ UINT ui_MinDelaytimeNs; // Minimum Delay in Nano secs
+
+ /* interrupt and reset */
+ void (*v_hwdrv_Interrupt)(int irq, void *d);
+ int (*i_hwdrv_Reset)(struct comedi_device *dev);
+
+ /* Subdevice functions */
+
+ /* ANALOG INPUT */
+ int (*i_hwdrv_InsnConfigAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnReadAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnWriteAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnBitsAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_CommandTestAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd);
+ int (*i_hwdrv_CommandAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s);
+ int (*i_hwdrv_CancelAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s);
+
+ /* Analog Output */
+ int (*i_hwdrv_InsnConfigAnalogOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnWriteAnalogOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnBitsAnalogOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+ /* Digital Input */
+ int (*i_hwdrv_InsnConfigDigitalInput) (struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnReadDigitalInput) (struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnWriteDigitalInput) (struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnBitsDigitalInput) (struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+ /* Digital Output */
+ int (*i_hwdrv_InsnConfigDigitalOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnWriteDigitalOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnBitsDigitalOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnReadDigitalOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+ /* TIMER */
+ int (*i_hwdrv_InsnConfigTimer)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+ int (*i_hwdrv_InsnWriteTimer)(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnReadTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+ int (*i_hwdrv_InsnBitsTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+ /* TTL IO */
+ int (*i_hwdr_ConfigInitTTLIO)(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdr_ReadTTLIOBits)(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+ int (*i_hwdr_ReadTTLIOAllPortValue)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdr_WriteTTLIOChlOnOff)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+} boardtype;
+
+//MODULE INFO STRUCTURE
+
+typedef union {
+ /* Incremental counter infos */
+ struct {
+ union {
+ struct {
+ BYTE b_ModeRegister1;
+ BYTE b_ModeRegister2;
+ BYTE b_ModeRegister3;
+ BYTE b_ModeRegister4;
+ } s_ByteModeRegister;
+ DWORD dw_ModeRegister1_2_3_4;
+ } s_ModeRegister;
+
+ struct {
+ unsigned int b_IndexInit:1;
+ unsigned int b_CounterInit:1;
+ unsigned int b_ReferenceInit:1;
+ unsigned int b_IndexInterruptOccur:1;
+ unsigned int b_CompareLogicInit:1;
+ unsigned int b_FrequencyMeasurementInit:1;
+ unsigned int b_FrequencyMeasurementEnable:1;
+ } s_InitFlag;
+
+ } s_SiemensCounterInfo;
+
+ /* SSI infos */
+ struct {
+ BYTE b_SSIProfile;
+ BYTE b_PositionTurnLength;
+ BYTE b_TurnCptLength;
+ BYTE b_SSIInit;
+ } s_SSICounterInfo;
+
+ /* TTL I/O infos */
+ struct {
+ BYTE b_TTLInit;
+ BYTE b_PortConfiguration[4];
+ } s_TTLIOInfo;
+
+ /* Digital I/O infos */
+ struct {
+ BYTE b_DigitalInit;
+ BYTE b_ChannelAMode;
+ BYTE b_ChannelBMode;
+ BYTE b_OutputMemoryEnabled;
+ DWORD dw_OutputMemory;
+ } s_DigitalIOInfo;
+
+ /*********************/
+ /* 82X54 timer infos */
+ /*********************/
+
+ struct {
+ struct {
+ BYTE b_82X54Init;
+ BYTE b_InputClockSelection;
+ BYTE b_InputClockLevel;
+ BYTE b_OutputLevel;
+ BYTE b_HardwareGateLevel;
+ DWORD dw_ConfigurationWord;
+ } s_82X54TimerInfo[3];
+ BYTE b_InterruptMask;
+ } s_82X54ModuleInfo;
+
+ /*********************/
+ /* Chronometer infos */
+ /*********************/
+
+ struct {
+ BYTE b_ChronoInit;
+ BYTE b_InterruptMask;
+ BYTE b_PCIInputClock;
+ BYTE b_TimingUnit;
+ BYTE b_CycleMode;
+ double d_TimingInterval;
+ DWORD dw_ConfigReg;
+ } s_ChronoModuleInfo;
+
+ /***********************/
+ /* Pulse encoder infos */
+ /***********************/
+
+ struct {
+ struct {
+ BYTE b_PulseEncoderInit;
+ } s_PulseEncoderInfo[4];
+ DWORD dw_SetRegister;
+ DWORD dw_ControlRegister;
+ DWORD dw_StatusRegister;
+ } s_PulseEncoderModuleInfo;
+
+ /* Tor conter infos */
+ struct {
+ struct {
+ BYTE b_TorCounterInit;
+ BYTE b_TimingUnit;
+ BYTE b_InterruptEnable;
+ double d_TimingInterval;
+ ULONG ul_RealTimingInterval;
+ } s_TorCounterInfo[2];
+ BYTE b_PCIInputClock;
+ } s_TorCounterModuleInfo;
+
+ /* PWM infos */
+ struct {
+ struct {
+ BYTE b_PWMInit;
+ BYTE b_TimingUnit;
+ BYTE b_InterruptEnable;
+ double d_LowTiming;
+ double d_HighTiming;
+ ULONG ul_RealLowTiming;
+ ULONG ul_RealHighTiming;
+ } s_PWMInfo[2];
+ BYTE b_ClockSelection;
+ } s_PWMModuleInfo;
+
+ /* ETM infos */
+ struct {
+ struct {
+ BYTE b_ETMEnable;
+ BYTE b_ETMInterrupt;
+ } s_ETMInfo[2];
+ BYTE b_ETMInit;
+ BYTE b_TimingUnit;
+ BYTE b_ClockSelection;
+ double d_TimingInterval;
+ ULONG ul_Timing;
+ } s_ETMModuleInfo;
+
+ /* CDA infos */
+ struct {
+ BYTE b_CDAEnable;
+ BYTE b_CDAInterrupt;
+ BYTE b_CDAInit;
+ BYTE b_FctSelection;
+ BYTE b_CDAReadFIFOOverflow;
+ } s_CDAModuleInfo;
+
+} str_ModuleInfo;
+
+/* Private structure for the addi_apci3120 driver */
+typedef struct {
+
+ INT iobase;
+ INT i_IobaseAmcc; // base+size for AMCC chip
+ INT i_IobaseAddon; //addon base address
+ INT i_IobaseReserved;
+ ULONG_PTR dw_AiBase;
+ struct pcilst_struct *amcc; // ptr too AMCC data
+ BYTE allocated; // we have blocked card
+ BYTE b_ValidDriver; // driver is ok
+ BYTE b_AiContinuous; // we do unlimited AI
+ BYTE b_AiInitialisation;
+ UINT ui_AiActualScan; //how many scans we finished
+ UINT ui_AiBufferPtr; // data buffer ptr in samples
+ UINT ui_AiNbrofChannels; // how many channels is measured
+ UINT ui_AiScanLength; // Length of actual scanlist
+ UINT ui_AiActualScanPosition; // position in actual scan
+ PUINT pui_AiChannelList; // actual chanlist
+ UINT ui_AiChannelList[32]; // actual chanlist
+ BYTE b_AiChannelConfiguration[32]; // actual chanlist
+ UINT ui_AiReadData[32];
+ DWORD dw_AiInitialised;
+ UINT ui_AiTimer0; //Timer Constant for Timer0
+ UINT ui_AiTimer1; //Timer constant for Timer1
+ UINT ui_AiFlags;
+ UINT ui_AiDataLength;
+ short *AiData; // Pointer to sample data
+ UINT ui_AiNbrofScans; // number of scans to do
+ USHORT us_UseDma; // To use Dma or not
+ BYTE b_DmaDoubleBuffer; // we can use double buffering
+ UINT ui_DmaActualBuffer; // which buffer is used now
+ //*UPDATE-0.7.57->0.7.68
+ //ULONG ul_DmaBufferVirtual[2];// pointers to begin of DMA buffer
+ short *ul_DmaBufferVirtual[2]; // pointers to begin of DMA buffer
+ ULONG ul_DmaBufferHw[2]; // hw address of DMA buff
+ UINT ui_DmaBufferSize[2]; // size of dma buffer in bytes
+ UINT ui_DmaBufferUsesize[2]; // which size we may now used for transfer
+ UINT ui_DmaBufferSamples[2]; // size in samples
+ UINT ui_DmaBufferPages[2]; // number of pages in buffer
+ BYTE b_DigitalOutputRegister; // Digital Output Register
+ BYTE b_OutputMemoryStatus;
+ BYTE b_AnalogInputChannelNbr; // Analog input channel Nbr
+ BYTE b_AnalogOutputChannelNbr; // Analog input Output Nbr
+ BYTE b_TimerSelectMode; // Contain data written at iobase + 0C
+ BYTE b_ModeSelectRegister; // Contain data written at iobase + 0E
+ USHORT us_OutputRegister; // Contain data written at iobase + 0
+ BYTE b_InterruptState;
+ BYTE b_TimerInit; // Specify if InitTimerWatchdog was load
+ BYTE b_TimerStarted; // Specify if timer 2 is running or not
+ BYTE b_Timer2Mode; // Specify the timer 2 mode
+ BYTE b_Timer2Interrupt; //Timer2 interrupt enable or disable
+ BYTE b_AiCyclicAcquisition; // indicate cyclic acquisition
+ BYTE b_InterruptMode; // eoc eos or dma
+ BYTE b_EocEosInterrupt; // Enable disable eoc eos interrupt
+ UINT ui_EocEosConversionTime;
+ BYTE b_EocEosConversionTimeBase;
+ BYTE b_SingelDiff;
+ BYTE b_ExttrigEnable; /* To enable or disable external trigger */
+
+ /* Pointer to the current process */
+ struct task_struct *tsk_Current;
+ boardtype *ps_BoardInfo;
+
+ /* Hardware board infos for 1710 */
+ struct {
+ UINT ui_Address; /* Board address */
+ UINT ui_FlashAddress;
+ BYTE b_InterruptNbr; /* Board interrupt number */
+ BYTE b_SlotNumber; /* PCI slot number */
+ BYTE b_BoardVersion;
+ DWORD dw_MolduleConfiguration[4]; /* Module config */
+ } s_BoardInfos;
+
+ /* Interrupt infos */
+ struct {
+ ULONG ul_InterruptOccur; /* 0 : No interrupt occur */
+ /* > 0 : Interrupt occur */
+ UINT ui_Read; /* Read FIFO */
+ UINT ui_Write; /* Write FIFO */
+ struct {
+ BYTE b_OldModuleMask;
+ ULONG ul_OldInterruptMask; /* Interrupt mask */
+ ULONG ul_OldCounterLatchValue; /* Interrupt counter value */
+ } s_FIFOInterruptParameters[APCI1710_SAVE_INTERRUPT];
+ } s_InterruptParameters;
+
+ str_ModuleInfo s_ModuleInfo[4];
+ ULONG ul_TTLPortConfiguration[10];
+
+} addi_private;
+
+static unsigned short pci_list_builded; /* set to 1 when list of card is known */
+
+/* Function declarations */
+static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int i_ADDI_Detach(struct comedi_device *dev);
+static int i_ADDI_Reset(struct comedi_device *dev);
+
+static irqreturn_t v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG);
+static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
new file mode 100644
index 00000000000..a8a1bb2e8fa
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
@@ -0,0 +1,1158 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : ADDI DATA | Compiler : GCC |
+ | Modulname : addi_eeprom.c | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : ADDI EEPROM Module |
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+#define NVCMD_BEGIN_READ (0x7 << 5 ) // nvRam begin read command
+#define NVCMD_LOAD_LOW (0x4 << 5 ) // nvRam load low command
+#define NVCMD_LOAD_HIGH (0x5 << 5 ) // nvRam load high command
+#define EE76_CMD_LEN 13 // bits in instructions
+#define EE_READ 0x0180 // 01 1000 0000 read instruction
+
+#define WORD unsigned short
+#define PWORD unsigned short *
+#define PDWORD unsigned int *
+
+#ifndef DWORD
+#define DWORD unsigned int
+#endif
+
+#define EEPROM_DIGITALINPUT 0
+#define EEPROM_DIGITALOUTPUT 1
+#define EEPROM_ANALOGINPUT 2
+#define EEPROM_ANALOGOUTPUT 3
+#define EEPROM_TIMER 4
+#define EEPROM_WATCHDOG 5
+#define EEPROM_TIMER_WATCHDOG_COUNTER 10
+
+struct str_Functionality {
+ BYTE b_Type;
+ WORD w_Address;
+};
+
+typedef struct {
+ WORD w_HeaderSize;
+ BYTE b_Nfunctions;
+ struct str_Functionality s_Functions[7];
+} str_MainHeader;
+
+typedef struct {
+ WORD w_Nchannel;
+ BYTE b_Interruptible;
+ WORD w_NinterruptLogic;
+} str_DigitalInputHeader;
+
+typedef struct {
+ WORD w_Nchannel;
+} str_DigitalOutputHeader;
+
+// used for timer as well as watchdog
+
+typedef struct {
+ WORD w_HeaderSize;
+ BYTE b_Resolution;
+ BYTE b_Mode; // in case of Watchdog it is functionality
+ WORD w_MinTiming;
+ BYTE b_TimeBase;
+} str_TimerDetails;
+typedef struct {
+
+ WORD w_Ntimer;
+ str_TimerDetails s_TimerDetails[4]; // supports 4 timers
+} str_TimerMainHeader;
+
+typedef struct {
+ WORD w_Nchannel;
+ BYTE b_Resolution;
+} str_AnalogOutputHeader;
+
+typedef struct {
+ WORD w_Nchannel;
+ WORD w_MinConvertTiming;
+ WORD w_MinDelayTiming;
+ BYTE b_HasDma;
+ BYTE b_Resolution;
+} str_AnalogInputHeader;
+
+ /*****************************************/
+ /* Read Header Functions */
+ /*****************************************/
+
+INT i_EepromReadMainHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, struct comedi_device *dev);
+
+INT i_EepromReadDigitalInputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_DigitalInputHeader * s_Header);
+
+INT i_EepromReadDigitalOutputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_DigitalOutputHeader * s_Header);
+
+INT i_EepromReadTimerHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_TimerMainHeader * s_Header);
+
+INT i_EepromReadAnlogOutputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_AnalogOutputHeader * s_Header);
+
+INT i_EepromReadAnlogInputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_AnalogInputHeader * s_Header);
+
+ /******************************************/
+ /* Eeprom Specific Functions */
+ /******************************************/
+WORD w_EepromReadWord(WORD w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
+ WORD w_EepromStartAddress);
+void v_EepromWaitBusy(WORD w_PCIBoardEepromAddress);
+void v_EepromClock76(DWORD dw_Address, DWORD dw_RegisterValue);
+void v_EepromWaitBusy(WORD w_PCIBoardEepromAddress);
+void v_EepromSendCommand76(DWORD dw_Address, DWORD dw_EepromCommand,
+ BYTE b_DataLengthInBits);
+void v_EepromCs76Read(DWORD dw_Address, WORD w_offset, PWORD pw_Value);
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : WORD w_EepromReadWord |
+| (WORD w_PCIBoardEepromAddress, |
+| char * pc_PCIChipInformation, |
+| WORD w_EepromStartAddress) |
++----------------------------------------------------------------------------+
+| Task : Read from eepromn a word |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| WORD w_EepromStartAddress : Selected eeprom address |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : Read word value from eeprom |
++----------------------------------------------------------------------------+
+*/
+
+WORD w_EepromReadWord(WORD w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
+ WORD w_EepromStartAddress)
+{
+
+ BYTE b_Counter = 0;
+
+ BYTE b_ReadByte = 0;
+
+ BYTE b_ReadLowByte = 0;
+
+ BYTE b_ReadHighByte = 0;
+
+ BYTE b_SelectedAddressLow = 0;
+
+ BYTE b_SelectedAddressHigh = 0;
+
+ WORD w_ReadWord = 0;
+
+ /**************************/
+
+ /* Test the PCI chip type */
+
+ /**************************/
+
+ if ((!strcmp(pc_PCIChipInformation, "S5920")) ||
+ (!strcmp(pc_PCIChipInformation, "S5933")))
+ {
+
+ for (b_Counter = 0; b_Counter < 2; b_Counter++)
+ {
+
+ b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256; //Read the low 8 bit part
+
+ b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256; //Read the high 8 bit part
+
+ /************************************/
+
+ /* Select the load low address mode */
+
+ /************************************/
+
+ outb(NVCMD_LOAD_LOW, w_PCIBoardEepromAddress + 0x3F);
+
+ /****************/
+
+ /* Wait on busy */
+
+ /****************/
+
+ v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+ /************************/
+
+ /* Load the low address */
+
+ /************************/
+
+ outb(b_SelectedAddressLow,
+ w_PCIBoardEepromAddress + 0x3E);
+
+ /****************/
+
+ /* Wait on busy */
+
+ /****************/
+
+ v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+ /*************************************/
+
+ /* Select the load high address mode */
+
+ /*************************************/
+
+ outb(NVCMD_LOAD_HIGH, w_PCIBoardEepromAddress + 0x3F);
+
+ /****************/
+
+ /* Wait on busy */
+
+ /****************/
+
+ v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+ /*************************/
+
+ /* Load the high address */
+
+ /*************************/
+
+ outb(b_SelectedAddressHigh,
+ w_PCIBoardEepromAddress + 0x3E);
+
+ /****************/
+
+ /* Wait on busy */
+
+ /****************/
+
+ v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+ /************************/
+
+ /* Select the READ mode */
+
+ /************************/
+
+ outb(NVCMD_BEGIN_READ, w_PCIBoardEepromAddress + 0x3F);
+
+ /****************/
+
+ /* Wait on busy */
+
+ /****************/
+
+ v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+ /*****************************/
+
+ /* Read data into the EEPROM */
+
+ /*****************************/
+
+ b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E);
+
+ /****************/
+
+ /* Wait on busy */
+
+ /****************/
+
+ v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+ /*********************************/
+
+ /* Select the upper address part */
+
+ /*********************************/
+
+ if (b_Counter == 0)
+ {
+
+ b_ReadLowByte = b_ReadByte;
+
+ } // if(b_Counter==0)
+
+ else
+ {
+
+ b_ReadHighByte = b_ReadByte;
+
+ } // if(b_Counter==0)
+
+ } // for (b_Counter=0; b_Counter<2; b_Counter++)
+
+ w_ReadWord = (b_ReadLowByte | (((WORD) b_ReadHighByte) * 256));
+
+ } // end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933")))
+
+ if (!strcmp(pc_PCIChipInformation, "93C76"))
+ {
+
+ /*************************************/
+
+ /* Read 16 bit from the EEPROM 93C76 */
+
+ /*************************************/
+
+ v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress,
+ &w_ReadWord);
+
+ }
+
+ return (w_ReadWord);
+
+}
+
+/*
+
++----------------------------------------------------------------------------+
+
+| Function Name : void v_EepromWaitBusy |
+
+| (WORD w_PCIBoardEepromAddress) |
+
++----------------------------------------------------------------------------+
+
+| Task : Wait the busy flag from PCI controller |
+
++----------------------------------------------------------------------------+
+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom base address |
+
++----------------------------------------------------------------------------+
+
+| Output Parameters : - |
+
++----------------------------------------------------------------------------+
+
+| Return Value : - |
+
++----------------------------------------------------------------------------+
+
+*/
+
+void v_EepromWaitBusy(WORD w_PCIBoardEepromAddress)
+{
+
+ BYTE b_EepromBusy = 0;
+
+ do
+ {
+
+ /*************/
+
+ /* IMPORTANT */
+
+ /*************/
+
+ /************************************************************************/
+
+ /* An error has been written in the AMCC 5933 book at the page B-13 */
+
+ /* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and */
+
+ /* the operator register is AMCC_OP_REG_MCSR+3 */
+
+ /* WORD read EEPROM=0x8000 andAMCC_OP_REG_MCSR+2 */
+
+ /* DWORD read EEPROM=0x80000000 and AMCC_OP_REG_MCSR */
+
+ /************************************************************************/
+
+ b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F);
+ b_EepromBusy = b_EepromBusy & 0x80;
+
+ }
+ while (b_EepromBusy == 0x80);
+
+}
+
+/*
+
++---------------------------------------------------------------------------------+
+
+| Function Name : void v_EepromClock76(DWORD dw_Address, |
+
+| DWORD dw_RegisterValue) |
+
++---------------------------------------------------------------------------------+
+
+| Task : This function sends the clocking sequence to the EEPROM. |
+
++---------------------------------------------------------------------------------+
+
+| Input Parameters : DWORD dw_Address : PCI eeprom base address |
+
+| DWORD dw_RegisterValue : PCI eeprom register value to write.|
+
++---------------------------------------------------------------------------------+
+
+| Output Parameters : - |
+
++---------------------------------------------------------------------------------+
+
+| Return Value : - |
+
++---------------------------------------------------------------------------------+
+
+*/
+
+void v_EepromClock76(DWORD dw_Address, DWORD dw_RegisterValue)
+{
+
+ /************************/
+
+ /* Set EEPROM clock Low */
+
+ /************************/
+
+ outl(dw_RegisterValue & 0x6, dw_Address);
+
+ /***************/
+
+ /* Wait 0.1 ms */
+
+ /***************/
+
+ udelay(100);
+
+ /*************************/
+
+ /* Set EEPROM clock High */
+
+ /*************************/
+
+ outl(dw_RegisterValue | 0x1, dw_Address);
+
+ /***************/
+
+ /* Wait 0.1 ms */
+
+ /***************/
+
+ udelay(100);
+
+}
+
+/*
+
++---------------------------------------------------------------------------------+
+
+| Function Name : void v_EepromSendCommand76(DWORD dw_Address, |
+
+| DWORD dw_EepromCommand, |
+
+| BYTE b_DataLengthInBits) |
+
++---------------------------------------------------------------------------------+
+
+| Task : This function sends a Command to the EEPROM 93C76. |
+
++---------------------------------------------------------------------------------+
+
+| Input Parameters : DWORD dw_Address : PCI eeprom base address |
+
+| DWORD dw_EepromCommand : PCI eeprom command to write. |
+
+| BYTE b_DataLengthInBits : PCI eeprom command data length. |
+
++---------------------------------------------------------------------------------+
+
+| Output Parameters : - |
+
++---------------------------------------------------------------------------------+
+
+| Return Value : - |
+
++---------------------------------------------------------------------------------+
+
+*/
+
+void v_EepromSendCommand76(DWORD dw_Address, DWORD dw_EepromCommand,
+ BYTE b_DataLengthInBits)
+{
+
+ char c_BitPos = 0;
+
+ DWORD dw_RegisterValue = 0;
+
+ /*****************************/
+
+ /* Enable EEPROM Chip Select */
+
+ /*****************************/
+
+ dw_RegisterValue = 0x2;
+
+ /********************************************************************/
+
+ /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
+
+ /********************************************************************/
+
+ outl(dw_RegisterValue, dw_Address);
+
+ /***************/
+
+ /* Wait 0.1 ms */
+
+ /***************/
+
+ udelay(100);
+
+ /*******************************************/
+
+ /* Send EEPROM command - one bit at a time */
+
+ /*******************************************/
+
+ for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--)
+ {
+
+ /**********************************/
+
+ /* Check if current bit is 0 or 1 */
+
+ /**********************************/
+
+ if (dw_EepromCommand & (1 << c_BitPos))
+ {
+
+ /***********/
+
+ /* Write 1 */
+
+ /***********/
+
+ dw_RegisterValue = dw_RegisterValue | 0x4;
+
+ }
+
+ else
+ {
+
+ /***********/
+
+ /* Write 0 */
+
+ /***********/
+
+ dw_RegisterValue = dw_RegisterValue & 0x3;
+
+ }
+
+ /*********************/
+
+ /* Write the command */
+
+ /*********************/
+
+ outl(dw_RegisterValue, dw_Address);
+
+ /***************/
+
+ /* Wait 0.1 ms */
+
+ /***************/
+
+ udelay(100);
+
+ /****************************/
+
+ /* Trigger the EEPROM clock */
+
+ /****************************/
+
+ v_EepromClock76(dw_Address, dw_RegisterValue);
+
+ }
+
+}
+
+/*
+
++---------------------------------------------------------------------------------+
+
+| Function Name : void v_EepromCs76Read(DWORD dw_Address, |
+
+| WORD w_offset, |
+
+| PWORD pw_Value) |
+
++---------------------------------------------------------------------------------+
+
+| Task : This function read a value from the EEPROM 93C76. |
+
++---------------------------------------------------------------------------------+
+
+| Input Parameters : DWORD dw_Address : PCI eeprom base address |
+
+| WORD w_offset : Offset of the adress to read |
+
+| PWORD pw_Value : PCI eeprom 16 bit read value. |
+
++---------------------------------------------------------------------------------+
+
+| Output Parameters : - |
+
++---------------------------------------------------------------------------------+
+
+| Return Value : - |
+
++---------------------------------------------------------------------------------+
+
+*/
+
+void v_EepromCs76Read(DWORD dw_Address, WORD w_offset, PWORD pw_Value)
+{
+
+ char c_BitPos = 0;
+
+ DWORD dw_RegisterValue = 0;
+
+ DWORD dw_RegisterValueRead = 0;
+
+ /*************************************************/
+
+ /* Send EEPROM read command and offset to EEPROM */
+
+ /*************************************************/
+
+ v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2),
+ EE76_CMD_LEN);
+
+ /*******************************/
+
+ /* Get the last register value */
+
+ /*******************************/
+
+ dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2;
+
+ /*****************************/
+
+ /* Set the 16-bit value of 0 */
+
+ /*****************************/
+
+ *pw_Value = 0;
+
+ /************************/
+
+ /* Get the 16-bit value */
+
+ /************************/
+
+ for (c_BitPos = 0; c_BitPos < 16; c_BitPos++)
+ {
+
+ /****************************/
+
+ /* Trigger the EEPROM clock */
+
+ /****************************/
+
+ v_EepromClock76(dw_Address, dw_RegisterValue);
+
+ /**********************/
+
+ /* Get the result bit */
+
+ /**********************/
+
+ dw_RegisterValueRead = inl(dw_Address);
+
+ /***************/
+
+ /* Wait 0.1 ms */
+
+ /***************/
+
+ udelay(100);
+
+ /***************************************/
+
+ /* Get bit value and shift into result */
+
+ /***************************************/
+
+ if (dw_RegisterValueRead & 0x8)
+ {
+
+ /**********/
+
+ /* Read 1 */
+
+ /**********/
+
+ *pw_Value = (*pw_Value << 1) | 0x1;
+
+ }
+
+ else
+ {
+
+ /**********/
+
+ /* Read 0 */
+
+ /**********/
+
+ *pw_Value = (*pw_Value << 1);
+
+ }
+
+ }
+
+ /*************************/
+
+ /* Clear all EEPROM bits */
+
+ /*************************/
+
+ dw_RegisterValue = 0x0;
+
+ /********************************************************************/
+
+ /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
+
+ /********************************************************************/
+
+ outl(dw_RegisterValue, dw_Address);
+
+ /***************/
+
+ /* Wait 0.1 ms */
+
+ /***************/
+
+ udelay(100);
+
+}
+
+ /******************************************/
+ /* EEPROM HEADER READ FUNCTIONS */
+ /******************************************/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadMainHeader(WORD w_PCIBoardEepromAddress, |
+| char * pc_PCIChipInformation,struct comedi_device *dev) |
++----------------------------------------------------------------------------+
+| Task : Read from eeprom Main Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| struct comedi_device *dev : comedi device structure |
+| pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+
+INT i_EepromReadMainHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, struct comedi_device *dev)
+{
+ WORD w_Temp, i, w_Count = 0;
+ UINT ui_Temp;
+ str_MainHeader s_MainHeader;
+ str_DigitalInputHeader s_DigitalInputHeader;
+ str_DigitalOutputHeader s_DigitalOutputHeader;
+ //str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader;
+ str_AnalogOutputHeader s_AnalogOutputHeader;
+ str_AnalogInputHeader s_AnalogInputHeader;
+
+ // Read size
+ s_MainHeader.w_HeaderSize =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + 8);
+
+ // Read nbr of functionality
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + 10);
+ s_MainHeader.b_Nfunctions = (BYTE) w_Temp & 0x00FF;
+
+ // Read functionality details
+ for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
+ // Read Type
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + 12 + w_Count);
+ s_MainHeader.s_Functions[i].b_Type = (BYTE) w_Temp & 0x3F;
+ w_Count = w_Count + 2;
+ //Read Address
+ s_MainHeader.s_Functions[i].w_Address =
+ w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + 12 + w_Count);
+ w_Count = w_Count + 2;
+ }
+
+ // Display main header info
+ for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
+
+ switch (s_MainHeader.s_Functions[i].b_Type) {
+ case EEPROM_DIGITALINPUT:
+ i_EepromReadDigitalInputHeader(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ s_MainHeader.s_Functions[i].w_Address,
+ &s_DigitalInputHeader);
+ this_board->i_NbrDiChannel =
+ s_DigitalInputHeader.w_Nchannel;
+ break;
+
+ case EEPROM_DIGITALOUTPUT:
+ i_EepromReadDigitalOutputHeader(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ s_MainHeader.s_Functions[i].w_Address,
+ &s_DigitalOutputHeader);
+ this_board->i_NbrDoChannel =
+ s_DigitalOutputHeader.w_Nchannel;
+ ui_Temp = 0xffffffff;
+ this_board->i_DoMaxdata =
+ ui_Temp >> (32 - this_board->i_NbrDoChannel);
+ break;
+
+ case EEPROM_ANALOGINPUT:
+ i_EepromReadAnlogInputHeader(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ s_MainHeader.s_Functions[i].w_Address,
+ &s_AnalogInputHeader);
+ if (!(strcmp(this_board->pc_DriverName, "apci3200")))
+ this_board->i_NbrAiChannel =
+ s_AnalogInputHeader.w_Nchannel * 4;
+ else
+ this_board->i_NbrAiChannel =
+ s_AnalogInputHeader.w_Nchannel;
+ this_board->i_Dma = s_AnalogInputHeader.b_HasDma;
+ this_board->ui_MinAcquisitiontimeNs =
+ (UINT) s_AnalogInputHeader.w_MinConvertTiming *
+ 1000;
+ this_board->ui_MinDelaytimeNs =
+ (UINT) s_AnalogInputHeader.w_MinDelayTiming *
+ 1000;
+ ui_Temp = 0xffff;
+ this_board->i_AiMaxdata =
+ ui_Temp >> (16 -
+ s_AnalogInputHeader.b_Resolution);
+ break;
+
+ case EEPROM_ANALOGOUTPUT:
+ i_EepromReadAnlogOutputHeader(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ s_MainHeader.s_Functions[i].w_Address,
+ &s_AnalogOutputHeader);
+ this_board->i_NbrAoChannel =
+ s_AnalogOutputHeader.w_Nchannel;
+ ui_Temp = 0xffff;
+ this_board->i_AoMaxdata =
+ ui_Temp >> (16 -
+ s_AnalogOutputHeader.b_Resolution);
+ break;
+
+ case EEPROM_TIMER:
+ this_board->i_Timer = 1; //Timer subdevice present
+ break;
+
+ case EEPROM_WATCHDOG:
+ this_board->i_Timer = 1; //Timer subdevice present
+ break;
+
+ case EEPROM_TIMER_WATCHDOG_COUNTER:
+ this_board->i_Timer = 1; //Timer subdevice present
+ }
+ }
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadDigitalInputHeader(WORD |
+| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
+| WORD w_Address,str_DigitalInputHeader *s_Header) |
+| |
++----------------------------------------------------------------------------+
+| Task : Read Digital Input Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_DigitalInputHeader *s_Header: Digita Input Header |
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+INT i_EepromReadDigitalInputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_DigitalInputHeader * s_Header)
+{
+ WORD w_Temp;
+
+ // read nbr of channels
+ s_Header->w_Nchannel =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + w_Address + 6);
+
+ // interruptible or not
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + w_Address + 8);
+ s_Header->b_Interruptible = (BYTE) (w_Temp >> 7) & 0x01;
+
+// How many interruptible logic
+ s_Header->w_NinterruptLogic =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + w_Address + 10);
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadDigitalOutputHeader(WORD |
+| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
+| WORD w_Address,str_DigitalOutputHeader *s_Header) |
+| |
++----------------------------------------------------------------------------+
+| Task : Read Digital Output Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_DigitalOutputHeader *s_Header: Digital Output Header|
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+INT i_EepromReadDigitalOutputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_DigitalOutputHeader * s_Header)
+{
+// Read Nbr channels
+ s_Header->w_Nchannel =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + w_Address + 6);
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadTimerHeader(WORD w_PCIBoardEepromAddress, |
+| char *pc_PCIChipInformation,WORD w_Address, |
+| str_TimerMainHeader *s_Header) |
++----------------------------------------------------------------------------+
+| Task : Read Timer or Watchdog Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_TimerMainHeader *s_Header: Timer Header |
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+INT i_EepromReadTimerHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_TimerMainHeader * s_Header)
+{
+
+ WORD i, w_Size = 0, w_Temp;
+
+//Read No of Timer
+ s_Header->w_Ntimer =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + w_Address + 6);
+//Read header size
+
+ for (i = 0; i < s_Header->w_Ntimer; i++) {
+ s_Header->s_TimerDetails[i].w_HeaderSize =
+ w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ 0x100 + w_Address + 8 + w_Size + 0);
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ 0x100 + w_Address + 8 + w_Size + 2);
+
+ //Read Resolution
+ s_Header->s_TimerDetails[i].b_Resolution =
+ (BYTE) (w_Temp >> 10) & 0x3F;
+
+ //Read Mode
+ s_Header->s_TimerDetails[i].b_Mode =
+ (BYTE) (w_Temp >> 4) & 0x3F;
+
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ 0x100 + w_Address + 8 + w_Size + 4);
+
+ //Read MinTiming
+ s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF;
+
+ //Read Timebase
+ s_Header->s_TimerDetails[i].b_TimeBase = (BYTE) (w_Temp) & 0x3F;
+ w_Size += s_Header->s_TimerDetails[i].w_HeaderSize;
+ }
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadAnlogOutputHeader(WORD |
+| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
+| WORD w_Address,str_AnalogOutputHeader *s_Header) |
++----------------------------------------------------------------------------+
+| Task : Read Nalog Output Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_AnalogOutputHeader *s_Header:Anlog Output Header |
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+
+INT i_EepromReadAnlogOutputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_AnalogOutputHeader * s_Header)
+{
+ WORD w_Temp;
+ // No of channels for 1st hard component
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + w_Address + 10);
+ s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
+ // Resolution for 1st hard component
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + w_Address + 16);
+ s_Header->b_Resolution = (BYTE) (w_Temp >> 8) & 0xFF;
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadAnlogInputHeader(WORD |
+| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
+| WORD w_Address,str_AnalogInputHeader *s_Header) |
++----------------------------------------------------------------------------+
+| Task : Read Nalog Output Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_AnalogInputHeader *s_Header:Anlog Input Header |
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+
+// Reads only for ONE hardware component
+INT i_EepromReadAnlogInputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_AnalogInputHeader * s_Header)
+{
+ WORD w_Temp, w_Offset;
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + w_Address + 10);
+ s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
+ s_Header->w_MinConvertTiming =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + w_Address + 16);
+ s_Header->w_MinDelayTiming =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + w_Address + 30);
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + w_Address + 20);
+ s_Header->b_HasDma = (w_Temp >> 13) & 0x01; // whether dma present or not
+
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72); // reading Y
+ w_Temp = w_Temp & 0x00FF;
+ if (w_Temp) //Y>0
+ {
+ w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16))); // offset of first analog input single header
+ w_Offset = w_Offset + 2; // resolution
+ } else //Y=0
+ {
+ w_Offset = 74;
+ w_Offset = w_Offset + 2; // resolution
+ }
+
+// read Resolution
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + w_Address + w_Offset);
+ s_Header->b_Resolution = w_Temp & 0x001F; // last 5 bits
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h b/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h
new file mode 100644
index 00000000000..617dc087dcb
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h
@@ -0,0 +1,457 @@
+/*
+ Modified by umesh on 16th may 2001
+ Modified by sarath on 22nd may 2001
+*/
+
+/*
+ comedi/drivers/amcc_s5933_v_58.h
+
+ Stuff for AMCC S5933 PCI Controller
+
+ Author: Michal Dobes <majkl@tesnet.cz>
+
+ Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver
+ made by Andrea Cisternino <acister@pcape1.pi.infn.it>
+ and as result of espionage from MITE code made by David A. Schleef.
+ Thanks to AMCC for their on-line documentation and bus master DMA
+ example.
+*/
+
+#ifndef _AMCC_S5933_H_
+#define _AMCC_S5933_H_
+
+#include <linux/pci.h>
+#include "../../comedidev.h"
+
+#ifdef PCI_SUPPORT_VER1
+#error Sorry, no support for 2.1.55 and older! :-((((
+#endif
+
+/***********Added by sarath for compatibility with APCI3120
+
+*************************/
+
+#define FIFO_ADVANCE_ON_BYTE_2 0x20000000 // written on base0
+
+#define AMWEN_ENABLE 0x02 // added for step 6 dma written on base2
+#define A2P_FIFO_WRITE_ENABLE 0x01
+
+#define AGCSTS_TC_ENABLE 0x10000000 // Added for transfer count enable bit
+
+// ADDON RELATED ADDITIONS
+// Constant
+#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00
+#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200
+#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L
+#define APCI3120_AMWEN_ENABLE 0x02
+#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01
+#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L
+#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L
+#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L
+#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
+#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0
+#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0
+
+ // ADD_ON ::: this needed since apci supports 16 bit interface to add on
+#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C
+#define APCI3120_ADD_ON_AGCSTS_HIGH APCI3120_ADD_ON_AGCSTS_LOW + 2
+#define APCI3120_ADD_ON_MWAR_LOW 0x24
+#define APCI3120_ADD_ON_MWAR_HIGH APCI3120_ADD_ON_MWAR_LOW + 2
+#define APCI3120_ADD_ON_MWTC_LOW 0x058
+#define APCI3120_ADD_ON_MWTC_HIGH APCI3120_ADD_ON_MWTC_LOW + 2
+
+// AMCC
+#define APCI3120_AMCC_OP_MCSR 0x3C
+#define APCI3120_AMCC_OP_REG_INTCSR 0x38
+
+/*******from here all upward definitions are added by sarath */
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - PCI */
+/****************************************************************************/
+
+#define AMCC_OP_REG_OMB1 0x00
+#define AMCC_OP_REG_OMB2 0x04
+#define AMCC_OP_REG_OMB3 0x08
+#define AMCC_OP_REG_OMB4 0x0c
+#define AMCC_OP_REG_IMB1 0x10
+#define AMCC_OP_REG_IMB2 0x14
+#define AMCC_OP_REG_IMB3 0x18
+#define AMCC_OP_REG_IMB4 0x1c
+#define AMCC_OP_REG_FIFO 0x20
+#define AMCC_OP_REG_MWAR 0x24
+#define AMCC_OP_REG_MWTC 0x28
+#define AMCC_OP_REG_MRAR 0x2c
+#define AMCC_OP_REG_MRTC 0x30
+#define AMCC_OP_REG_MBEF 0x34
+#define AMCC_OP_REG_INTCSR 0x38
+#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) /* INT source */
+#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) /* FIFO ctrl */
+#define AMCC_OP_REG_MCSR 0x3c
+#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) /* Data in byte 2 */
+#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */
+
+#define AMCC_FIFO_DEPTH_DWORD 8
+#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof (u32))
+
+/****************************************************************************/
+/* AMCC Operation Registers Size - PCI */
+/****************************************************************************/
+
+#define AMCC_OP_REG_SIZE 64 /* in bytes */
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - Add-on */
+/****************************************************************************/
+
+#define AMCC_OP_REG_AIMB1 0x00
+#define AMCC_OP_REG_AIMB2 0x04
+#define AMCC_OP_REG_AIMB3 0x08
+#define AMCC_OP_REG_AIMB4 0x0c
+#define AMCC_OP_REG_AOMB1 0x10
+#define AMCC_OP_REG_AOMB2 0x14
+#define AMCC_OP_REG_AOMB3 0x18
+#define AMCC_OP_REG_AOMB4 0x1c
+#define AMCC_OP_REG_AFIFO 0x20
+#define AMCC_OP_REG_AMWAR 0x24
+#define AMCC_OP_REG_APTA 0x28
+#define AMCC_OP_REG_APTD 0x2c
+#define AMCC_OP_REG_AMRAR 0x30
+#define AMCC_OP_REG_AMBEF 0x34
+#define AMCC_OP_REG_AINT 0x38
+#define AMCC_OP_REG_AGCSTS 0x3c
+#define AMCC_OP_REG_AMWTC 0x58
+#define AMCC_OP_REG_AMRTC 0x5c
+
+/****************************************************************************/
+/* AMCC - Add-on General Control/Status Register */
+/****************************************************************************/
+
+#define AGCSTS_CONTROL_MASK 0xfffff000
+#define AGCSTS_NV_ACC_MASK 0xe0000000
+#define AGCSTS_RESET_MASK 0x0e000000
+#define AGCSTS_NV_DA_MASK 0x00ff0000
+#define AGCSTS_BIST_MASK 0x0000f000
+#define AGCSTS_STATUS_MASK 0x000000ff
+#define AGCSTS_TCZERO_MASK 0x000000c0
+#define AGCSTS_FIFO_ST_MASK 0x0000003f
+
+#define AGCSTS_RESET_MBFLAGS 0x08000000
+#define AGCSTS_RESET_P2A_FIFO 0x04000000
+#define AGCSTS_RESET_A2P_FIFO 0x02000000
+#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
+
+#define AGCSTS_A2P_TCOUNT 0x00000080
+#define AGCSTS_P2A_TCOUNT 0x00000040
+
+#define AGCSTS_FS_P2A_EMPTY 0x00000020
+#define AGCSTS_FS_P2A_HALF 0x00000010
+#define AGCSTS_FS_P2A_FULL 0x00000008
+
+#define AGCSTS_FS_A2P_EMPTY 0x00000004
+#define AGCSTS_FS_A2P_HALF 0x00000002
+#define AGCSTS_FS_A2P_FULL 0x00000001
+
+/****************************************************************************/
+/* AMCC - Add-on Interrupt Control/Status Register */
+/****************************************************************************/
+
+#define AINT_INT_MASK 0x00ff0000
+#define AINT_SEL_MASK 0x0000ffff
+#define AINT_IS_ENSEL_MASK 0x00001f1f
+
+#define AINT_INT_ASSERTED 0x00800000
+#define AINT_BM_ERROR 0x00200000
+#define AINT_BIST_INT 0x00100000
+
+#define AINT_RT_COMPLETE 0x00080000
+#define AINT_WT_COMPLETE 0x00040000
+
+#define AINT_OUT_MB_INT 0x00020000
+#define AINT_IN_MB_INT 0x00010000
+
+#define AINT_READ_COMPL 0x00008000
+#define AINT_WRITE_COMPL 0x00004000
+
+#define AINT_OMB_ENABLE 0x00001000
+#define AINT_OMB_SELECT 0x00000c00
+#define AINT_OMB_BYTE 0x00000300
+
+#define AINT_IMB_ENABLE 0x00000010
+#define AINT_IMB_SELECT 0x0000000c
+#define AINT_IMB_BYTE 0x00000003
+
+/* Enable Bus Mastering */
+#define EN_A2P_TRANSFERS 0x00000400
+/* FIFO Flag Reset */
+#define RESET_A2P_FLAGS 0x04000000L
+/* FIFO Relative Priority */
+#define A2P_HI_PRIORITY 0x00000100L
+/* Identify Interrupt Sources */
+#define ANY_S593X_INT 0x00800000L
+#define READ_TC_INT 0x00080000L
+#define WRITE_TC_INT 0x00040000L
+#define IN_MB_INT 0x00020000L
+#define MASTER_ABORT_INT 0x00100000L
+#define TARGET_ABORT_INT 0x00200000L
+#define BUS_MASTER_INT 0x00200000L
+
+/****************************************************************************/
+
+struct pcilst_struct {
+ struct pcilst_struct *next;
+ int used;
+ struct pci_dev *pcidev;
+ unsigned short vendor;
+ unsigned short device;
+ unsigned int master;
+ unsigned char pci_bus;
+ unsigned char pci_slot;
+ unsigned char pci_func;
+ unsigned int io_addr[5];
+ unsigned int irq;
+};
+
+struct pcilst_struct *amcc_devices; // ptr to root list of all amcc devices
+
+/****************************************************************************/
+
+void v_pci_card_list_init(unsigned short pci_vendor, char display);
+void v_pci_card_list_cleanup(unsigned short pci_vendor);
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
+ unsigned short
+ device_id);
+int i_find_free_pci_card_by_position(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot,
+ struct pcilst_struct **card);
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot);
+
+int i_pci_card_alloc(struct pcilst_struct *amcc);
+int i_pci_card_free(struct pcilst_struct *amcc);
+void v_pci_card_list_display(void);
+int i_pci_card_data(struct pcilst_struct *amcc,
+ unsigned char *pci_bus, unsigned char *pci_slot,
+ unsigned char *pci_func, unsigned short *io_addr,
+ unsigned short *irq, unsigned short *master);
+
+/****************************************************************************/
+
+/* build list of amcc cards in this system */
+void v_pci_card_list_init(unsigned short pci_vendor, char display)
+{
+ struct pci_dev *pcidev;
+ struct pcilst_struct *amcc, *last;
+ int i;
+
+ amcc_devices = NULL;
+ last = NULL;
+
+ pci_for_each_dev(pcidev) {
+ if (pcidev->vendor == pci_vendor) {
+ amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
+ memset(amcc, 0, sizeof(*amcc));
+
+ amcc->pcidev = pcidev;
+ if (last) {
+ last->next = amcc;
+ } else {
+ amcc_devices = amcc;
+ }
+ last = amcc;
+
+ amcc->vendor = pcidev->vendor;
+ amcc->device = pcidev->device;
+#if 0
+ amcc->master = pcidev->master; // how get this information under 2.4 kernels?
+#endif
+ amcc->pci_bus = pcidev->bus->number;
+ amcc->pci_slot = PCI_SLOT(pcidev->devfn);
+ amcc->pci_func = PCI_FUNC(pcidev->devfn);
+ for (i = 0; i < 5; i++)
+ amcc->io_addr[i] =
+ pcidev->resource[i].start & ~3UL;
+ amcc->irq = pcidev->irq;
+ }
+ }
+
+ if (display)
+ v_pci_card_list_display();
+}
+
+/****************************************************************************/
+/* free up list of amcc cards in this system */
+void v_pci_card_list_cleanup(unsigned short pci_vendor)
+{
+ struct pcilst_struct *amcc, *next;
+
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ kfree(amcc);
+ }
+
+ amcc_devices = NULL;
+}
+
+/****************************************************************************/
+/* find first unused card with this device_id */
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
+ unsigned short device_id)
+{
+ struct pcilst_struct *amcc, *next;
+
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ if ((!amcc->used) && (amcc->device == device_id)
+ && (amcc->vendor == vendor_id))
+ return amcc;
+
+ }
+
+ return NULL;
+}
+
+/****************************************************************************/
+/* find card on requested position */
+int i_find_free_pci_card_by_position(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot,
+ struct pcilst_struct **card)
+{
+ struct pcilst_struct *amcc, *next;
+
+ *card = NULL;
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
+ && (amcc->pci_bus == pci_bus)
+ && (amcc->pci_slot == pci_slot)) {
+ if (!(amcc->used)) {
+ *card = amcc;
+ return 0; // ok, card is found
+ } else {
+ rt_printk
+ (" - \nCard on requested position is used b:s %d:%d!\n",
+ pci_bus, pci_slot);
+ return 2; // card exist but is used
+ }
+ }
+ }
+
+ return 1; // no card found
+}
+
+/****************************************************************************/
+/* mark card as used */
+int i_pci_card_alloc(struct pcilst_struct *amcc)
+{
+ if (!amcc)
+ return -1;
+
+ if (amcc->used)
+ return 1;
+ amcc->used = 1;
+ return 0;
+}
+
+/****************************************************************************/
+/* mark card as free */
+int i_pci_card_free(struct pcilst_struct *amcc)
+{
+ if (!amcc)
+ return -1;
+
+ if (!amcc->used)
+ return 1;
+ amcc->used = 0;
+ return 0;
+}
+
+/****************************************************************************/
+/* display list of found cards */
+void v_pci_card_list_display(void)
+{
+ struct pcilst_struct *amcc, *next;
+
+ printk("List of pci cards\n");
+ printk("bus:slot:func vendor device master io_amcc io_daq irq used\n");
+
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ printk
+ ("%2d %2d %2d 0x%4x 0x%4x %3s 0x%4x 0x%4x %2d %2d\n",
+ amcc->pci_bus, amcc->pci_slot, amcc->pci_func,
+ amcc->vendor, amcc->device, amcc->master ? "yes" : "no",
+ amcc->io_addr[0], amcc->io_addr[2], amcc->irq, amcc->used);
+
+ }
+}
+
+/****************************************************************************/
+/* return all card information for driver */
+int i_pci_card_data(struct pcilst_struct *amcc,
+ unsigned char *pci_bus, unsigned char *pci_slot,
+ unsigned char *pci_func, unsigned short *io_addr,
+ unsigned short *irq, unsigned short *master)
+{
+ int i;
+
+ if (!amcc)
+ return -1;
+ *pci_bus = amcc->pci_bus;
+ *pci_slot = amcc->pci_slot;
+ *pci_func = amcc->pci_func;
+ for (i = 0; i < 5; i++)
+ io_addr[i] = amcc->io_addr[i];
+ *irq = amcc->irq;
+ *master = amcc->master;
+ return 0;
+}
+
+/****************************************************************************/
+/* select and alloc card */
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot)
+{
+ struct pcilst_struct *card;
+
+ if ((pci_bus < 1) & (pci_slot < 1)) { // use autodetection
+ if ((card = ptr_find_free_pci_card_by_device(vendor_id,
+ device_id)) ==
+ NULL) {
+ rt_printk(" - Unused card not found in system!\n");
+ return NULL;
+ }
+ } else {
+ switch (i_find_free_pci_card_by_position(vendor_id, device_id,
+ pci_bus, pci_slot,
+ &card)) {
+ case 1:
+ rt_printk
+ (" - Card not found on requested position b:s %d:%d!\n",
+ pci_bus, pci_slot);
+ return NULL;
+ case 2:
+ rt_printk
+ (" - Card on requested position is used b:s %d:%d!\n",
+ pci_bus, pci_slot);
+ return NULL;
+ }
+ }
+
+ if (i_pci_card_alloc(card) != 0) {
+ rt_printk(" - Can't allocate card!\n");
+ return NULL;
+ }
+
+ return card;
+}
+
+#endif
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
new file mode 100644
index 00000000000..3f8929c0907
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
@@ -0,0 +1,1265 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-1710 | Compiler : GCC |
+ | Module name : hwdrv_apci1710.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-1710 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+#include "hwdrv_APCI1710.h"
+#include "APCI1710_Inp_cpt.c"
+
+#include "APCI1710_Ssi.c"
+#include "APCI1710_Tor.c"
+#include "APCI1710_Ttl.c"
+#include "APCI1710_Dig_io.c"
+#include "APCI1710_82x54.c"
+#include "APCI1710_Chrono.c"
+#include "APCI1710_Pwm.c"
+#include "APCI1710_INCCPT.c"
+
+void i_ADDI_AttachPCI1710(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s;
+ int ret = 0;
+ int n_subdevices = 9;
+
+ //Update-0.7.57->0.7.68dev->n_subdevices = 9;
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+ return;
+
+ // Allocate and Initialise Timer Subdevice Structures
+ s = dev->subdevices + 0;
+
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_WRITEABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 3;
+ s->maxdata = 0;
+ s->len_chanlist = 3;
+ s->range_table = &range_digital;
+ s->insn_write = i_APCI1710_InsnWriteEnableDisableTimer;
+ s->insn_read = i_APCI1710_InsnReadAllTimerValue;
+ s->insn_config = i_APCI1710_InsnConfigInitTimer;
+ s->insn_bits = i_APCI1710_InsnBitsTimer;
+
+ // Allocate and Initialise DIO Subdevice Structures
+ s = dev->subdevices + 1;
+
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 7;
+ s->maxdata = 1;
+ s->len_chanlist = 7;
+ s->range_table = &range_digital;
+ s->insn_config = i_APCI1710_InsnConfigDigitalIO;
+ s->insn_read = i_APCI1710_InsnReadDigitalIOChlValue;
+ s->insn_bits = i_APCI1710_InsnBitsDigitalIOPortOnOff;
+ s->insn_write = i_APCI1710_InsnWriteDigitalIOChlOnOff;
+
+ // Allocate and Initialise Chrono Subdevice Structures
+ s = dev->subdevices + 2;
+
+ s->type = COMEDI_SUBD_CHRONO;
+ s->subdev_flags = SDF_WRITEABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 4;
+ s->maxdata = 0;
+ s->len_chanlist = 4;
+ s->range_table = &range_digital;
+ s->insn_write = i_APCI1710_InsnWriteEnableDisableChrono;
+ s->insn_read = i_APCI1710_InsnReadChrono;
+ s->insn_config = i_APCI1710_InsnConfigInitChrono;
+ s->insn_bits = i_APCI1710_InsnBitsChronoDigitalIO;
+
+ // Allocate and Initialise PWM Subdevice Structures
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_PWM;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 3;
+ s->maxdata = 1;
+ s->len_chanlist = 3;
+ s->range_table = &range_digital;
+ s->io_bits = 0; //all bits input
+ s->insn_config = i_APCI1710_InsnConfigPWM;
+ s->insn_read = i_APCI1710_InsnReadGetPWMStatus;
+ s->insn_write = i_APCI1710_InsnWritePWM;
+ s->insn_bits = i_APCI1710_InsnBitsReadPWMInterrupt;
+
+ // Allocate and Initialise TTLIO Subdevice Structures
+ s = dev->subdevices + 4;
+ s->type = COMEDI_SUBD_TTLIO;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->len_chanlist = 8;
+ s->range_table = &range_apci1710_ttl; // to pass arguments in range
+ s->insn_config = i_APCI1710_InsnConfigInitTTLIO;
+ s->insn_bits = i_APCI1710_InsnBitsReadTTLIO;
+ s->insn_write = i_APCI1710_InsnWriteSetTTLIOChlOnOff;
+ s->insn_read = i_APCI1710_InsnReadTTLIOAllPortValue;
+
+ // Allocate and Initialise TOR Subdevice Structures
+ s = dev->subdevices + 5;
+ s->type = COMEDI_SUBD_TOR;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->len_chanlist = 8;
+ s->range_table = &range_digital;
+ s->io_bits = 0; //all bits input
+ s->insn_config = i_APCI1710_InsnConfigInitTorCounter;
+ s->insn_read = i_APCI1710_InsnReadGetTorCounterInitialisation;
+ s->insn_write = i_APCI1710_InsnWriteEnableDisableTorCounter;
+ s->insn_bits = i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue;
+
+ // Allocate and Initialise SSI Subdevice Structures
+ s = dev->subdevices + 6;
+ s->type = COMEDI_SUBD_SSI;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->len_chanlist = 4;
+ s->range_table = &range_apci1710_ssi;
+ s->insn_config = i_APCI1710_InsnConfigInitSSI;
+ s->insn_read = i_APCI1710_InsnReadSSIValue;
+ s->insn_bits = i_APCI1710_InsnBitsSSIDigitalIO;
+
+ // Allocate and Initialise PULSEENCODER Subdevice Structures
+ s = dev->subdevices + 7;
+ s->type = COMEDI_SUBD_PULSEENCODER;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->len_chanlist = 4;
+ s->range_table = &range_digital;
+ s->insn_config = i_APCI1710_InsnConfigInitPulseEncoder;
+ s->insn_write = i_APCI1710_InsnWriteEnableDisablePulseEncoder;
+ s->insn_bits = i_APCI1710_InsnBitsReadWritePulseEncoder;
+ s->insn_read = i_APCI1710_InsnReadInterruptPulseEncoder;
+
+ // Allocate and Initialise INCREMENTALCOUNTER Subdevice Structures
+ s = dev->subdevices + 8;
+ s->type = COMEDI_SUBD_INCREMENTALCOUNTER;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 500;
+ s->maxdata = 1;
+ s->len_chanlist = 500;
+ s->range_table = &range_apci1710_inccpt;
+ s->insn_config = i_APCI1710_InsnConfigINCCPT;
+ s->insn_write = i_APCI1710_InsnWriteINCCPT;
+ s->insn_read = i_APCI1710_InsnReadINCCPT;
+ s->insn_bits = i_APCI1710_InsnBitsINCCPT;
+}
+
+int i_APCI1710_Reset(struct comedi_device * dev);
+void v_APCI1710_Interrupt(int irq, void *d);
+//for 1710
+
+int i_APCI1710_Reset(struct comedi_device * dev)
+{
+ int ret;
+ DWORD dw_Dummy;
+
+ /*********************************/
+ /* Read all module configuration */
+ /*********************************/
+ ret = inl(devpriv->s_BoardInfos.ui_Address + 60);
+ devpriv->s_BoardInfos.dw_MolduleConfiguration[0] = ret;
+
+ ret = inl(devpriv->s_BoardInfos.ui_Address + 124);
+ devpriv->s_BoardInfos.dw_MolduleConfiguration[1] = ret;
+
+ ret = inl(devpriv->s_BoardInfos.ui_Address + 188);
+ devpriv->s_BoardInfos.dw_MolduleConfiguration[2] = ret;
+
+ ret = inl(devpriv->s_BoardInfos.ui_Address + 252);
+ devpriv->s_BoardInfos.dw_MolduleConfiguration[3] = ret;
+
+ // outl(0x80808082,devpriv->s_BoardInfos.ui_Address+0x60);
+ outl(0x83838383, devpriv->s_BoardInfos.ui_Address + 0x60);
+
+ devpriv->s_BoardInfos.b_BoardVersion = 1;
+
+ // Enable the interrupt for the controler
+ dw_Dummy = inl(devpriv->s_BoardInfos.ui_Address + 0x38);
+ outl(dw_Dummy | 0x2000, devpriv->s_BoardInfos.ui_Address + 0x38);
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function's Name : __void__ v_APCI1710_InterruptFunction |
+| (BYTE b_Interrupt, __CPPARGS) |
++----------------------------------------------------------------------------+
+| Task : APCI-1710 interrupt function |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE b_Interrupt : Interrupt number |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 : OK |
+| -1 : Error |
++----------------------------------------------------------------------------+
+*/
+
+void v_APCI1710_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ BYTE b_ModuleCpt = 0;
+ BYTE b_InterruptFlag = 0;
+ BYTE b_PWMCpt = 0;
+ BYTE b_TorCounterCpt = 0;
+ BYTE b_PulseIncoderCpt = 0;
+ UINT ui_16BitValue;
+ ULONG ul_InterruptLatchReg = 0;
+ ULONG ul_LatchRegisterValue = 0;
+ ULONG ul_82X54InterruptStatus;
+ ULONG ul_StatusRegister;
+
+ str_ModuleInfo *ps_ModuleInfo;
+
+ printk("APCI1710 Interrupt\n");
+ for (b_ModuleCpt = 0; b_ModuleCpt < 4; b_ModuleCpt++, ps_ModuleInfo++) {
+
+ /**************************/
+ /* 1199/0225 to 0100/0226 */
+ /**************************/
+ ps_ModuleInfo = &devpriv->s_ModuleInfo[b_ModuleCpt];
+
+ /***********************/
+ /* Test if 82X54 timer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+
+ //printk("TIMER Interrupt Occurred\n");
+ ul_82X54InterruptStatus = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if ((ul_82X54InterruptStatus & ps_ModuleInfo->
+ s_82X54ModuleInfo.
+ b_InterruptMask) != 0) {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask =
+ (ul_82X54InterruptStatus &
+ ps_ModuleInfo->s_82X54ModuleInfo.
+ b_InterruptMask) << 4;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.
+ ui_Write].ul_OldCounterLatchValue = 0;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ } // if ((ul_82X54InterruptStatus & 0x7) != 0)
+ } // 82X54 timer
+
+ /***************************/
+ /* Test if increm. counter */
+ /***************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER) {
+
+ ul_InterruptLatchReg = inl(devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModuleCpt));
+
+ /*********************/
+ /* Test if interrupt */
+ /*********************/
+
+ if ((ul_InterruptLatchReg & 0x22) && (ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 & 0x80)) {
+ /************************************/
+ /* Test if strobe latch I interrupt */
+ /************************************/
+
+ if (ul_InterruptLatchReg & 2) {
+ ul_LatchRegisterValue =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 4 +
+ (64 * b_ModuleCpt));
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].ul_OldInterruptMask =
+ 1UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue =
+ ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current,
+ 0);
+
+ }
+
+ /*************************************/
+ /* Test if strobe latch II interrupt */
+ /*************************************/
+
+ if (ul_InterruptLatchReg & 0x20) {
+
+ ul_LatchRegisterValue =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 8 +
+ (64 * b_ModuleCpt));
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].ul_OldInterruptMask =
+ 2UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue =
+ ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current,
+ 0);
+
+ }
+ }
+
+ ul_InterruptLatchReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 24 + (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if index interrupt */
+ /***************************/
+
+ if (ul_InterruptLatchReg & 0x8) {
+ ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_InitFlag.b_IndexInterruptOccur = 1;
+
+ if (ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 &
+ APCI1710_INDEX_AUTO_MODE) {
+
+ outl(ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.
+ ui_Address + 20 +
+ (64 * b_ModuleCpt));
+ }
+
+ /*****************************/
+ /* Test if interrupt enabled */
+ /*****************************/
+
+ if ((ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 &
+ APCI1710_ENABLE_INDEX_INT) ==
+ APCI1710_ENABLE_INDEX_INT) {
+ devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].ul_OldInterruptMask =
+ 4UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue =
+ ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current,
+ 0);
+
+ }
+ }
+
+ /*****************************/
+ /* Test if compare interrupt */
+ /*****************************/
+
+ if (ul_InterruptLatchReg & 0x10) {
+ /*****************************/
+ /* Test if interrupt enabled */
+ /*****************************/
+
+ if ((ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 &
+ APCI1710_ENABLE_COMPARE_INT) ==
+ APCI1710_ENABLE_COMPARE_INT) {
+ devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].ul_OldInterruptMask =
+ 8UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue =
+ ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current,
+ 0);
+
+ }
+ }
+
+ /*******************************************/
+ /* Test if frequency measurement interrupt */
+ /*******************************************/
+
+ if (ul_InterruptLatchReg & 0x20) {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ ul_StatusRegister = inl(devpriv->s_BoardInfos.
+ ui_Address + 32 + (64 * b_ModuleCpt));
+
+ /******************/
+ /* Read the value */
+ /******************/
+
+ ul_LatchRegisterValue =
+ inl(devpriv->s_BoardInfos.ui_Address +
+ 28 + (64 * b_ModuleCpt));
+
+ switch ((ul_StatusRegister >> 1) & 3) {
+ case 0:
+ /*************************/
+ /* Test the counter mode */
+ /*************************/
+
+ if ((devpriv->s_ModuleInfo[b_ModuleCpt].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister1 &
+ APCI1710_16BIT_COUNTER)
+ == APCI1710_16BIT_COUNTER) {
+ /****************************************/
+ /* Test if 16-bit counter 1 pulse occur */
+ /****************************************/
+
+ if ((ul_LatchRegisterValue &
+ 0xFFFFU) != 0) {
+ ui_16BitValue =
+ (UINT)
+ ul_LatchRegisterValue
+ & 0xFFFFU;
+ ul_LatchRegisterValue =
+ (ul_LatchRegisterValue
+ & 0xFFFF0000UL)
+ | (0xFFFFU -
+ ui_16BitValue);
+ }
+
+ /****************************************/
+ /* Test if 16-bit counter 2 pulse occur */
+ /****************************************/
+
+ if ((ul_LatchRegisterValue &
+ 0xFFFF0000UL) !=
+ 0) {
+ ui_16BitValue =
+ (UINT) (
+ (ul_LatchRegisterValue
+ >> 16) &
+ 0xFFFFU);
+ ul_LatchRegisterValue =
+ (ul_LatchRegisterValue
+ & 0xFFFFUL) |
+ ((0xFFFFU -
+ ui_16BitValue)
+ << 16);
+ }
+ } else {
+ if (ul_LatchRegisterValue != 0) {
+ ul_LatchRegisterValue =
+ 0xFFFFFFFFUL -
+ ul_LatchRegisterValue;
+ }
+ }
+ break;
+
+ case 1:
+ /****************************************/
+ /* Test if 16-bit counter 2 pulse occur */
+ /****************************************/
+
+ if ((ul_LatchRegisterValue &
+ 0xFFFF0000UL) != 0) {
+ ui_16BitValue =
+ (UINT) (
+ (ul_LatchRegisterValue
+ >> 16) &
+ 0xFFFFU);
+ ul_LatchRegisterValue =
+ (ul_LatchRegisterValue &
+ 0xFFFFUL) | ((0xFFFFU -
+ ui_16BitValue)
+ << 16);
+ }
+ break;
+
+ case 2:
+ /****************************************/
+ /* Test if 16-bit counter 1 pulse occur */
+ /****************************************/
+
+ if ((ul_LatchRegisterValue & 0xFFFFU) !=
+ 0) {
+ ui_16BitValue =
+ (UINT)
+ ul_LatchRegisterValue &
+ 0xFFFFU;
+ ul_LatchRegisterValue =
+ (ul_LatchRegisterValue &
+ 0xFFFF0000UL) | (0xFFFFU
+ - ui_16BitValue);
+ }
+ break;
+ }
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask = 0x10000UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue =
+ ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ }
+ } // Incremental counter
+
+ /***************/
+ /* Test if CDA */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_CDA) {
+ /******************************************/
+ /* Test if CDA enable and functionality 0 */
+ /******************************************/
+
+ if ((devpriv->s_ModuleInfo[b_ModuleCpt].
+ s_CDAModuleInfo.
+ b_CDAEnable == APCI1710_ENABLE)
+ && (devpriv->s_ModuleInfo[b_ModuleCpt].
+ s_CDAModuleInfo.b_FctSelection == 0)) {
+ /****************************/
+ /* Get the interrupt status */
+ /****************************/
+
+ ul_StatusRegister = inl(devpriv->s_BoardInfos.
+ ui_Address + 16 + (64 * b_ModuleCpt));
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if (ul_StatusRegister & 1) {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].ul_OldInterruptMask =
+ 0x80000UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue = 0;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current,
+ 0);
+
+ } // if (ul_StatusRegister & 1)
+
+ }
+ } // CDA
+
+ /***********************/
+ /* Test if PWM counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ for (b_PWMCpt = 0; b_PWMCpt < 2; b_PWMCpt++) {
+ /*************************************/
+ /* Test if PWM interrupt initialised */
+ /*************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModuleCpt].
+ s_PWMModuleInfo.
+ s_PWMInfo[b_PWMCpt].
+ b_InterruptEnable == APCI1710_ENABLE) {
+ /*****************************/
+ /* Read the interrupt status */
+ /*****************************/
+
+ ul_StatusRegister =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 16 +
+ (20 * b_PWMCpt) +
+ (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if (ul_StatusRegister & 0x1) {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask =
+ 0x4000UL << b_PWMCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) %
+ APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,
+ devpriv->tsk_Current,
+ 0);
+
+ } // if (ul_StatusRegister & 0x1)
+ } // if (APCI1710_ENABLE)
+ } // for (b_PWMCpt == 0; b_PWMCpt < 0; b_PWMCpt ++)
+ } // PWM counter
+
+ /***********************/
+ /* Test if tor counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+ for (b_TorCounterCpt = 0; b_TorCounterCpt < 2;
+ b_TorCounterCpt++) {
+ /*************************************/
+ /* Test if tor interrupt initialised */
+ /*************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModuleCpt].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo[b_TorCounterCpt].
+ b_InterruptEnable == APCI1710_ENABLE) {
+ /*****************************/
+ /* Read the interrupt status */
+ /*****************************/
+
+ ul_StatusRegister =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 12 +
+ (16 * b_TorCounterCpt) +
+ (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if (ul_StatusRegister & 0x1) {
+ /******************************/
+ /* Read the tor counter value */
+ /******************************/
+
+ ul_LatchRegisterValue =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 0 +
+ (16 * b_TorCounterCpt) +
+ (64 * b_ModuleCpt));
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask =
+ 0x1000UL <<
+ b_TorCounterCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue
+ = ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) %
+ APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,
+ devpriv->tsk_Current,
+ 0);
+ } // if (ul_StatusRegister & 0x1)
+ } // if (APCI1710_ENABLE)
+ } // for (b_TorCounterCpt == 0; b_TorCounterCpt < 0; b_TorCounterCpt ++)
+ } // Tor counter
+
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+
+ //printk("APCI1710 Chrono Interrupt\n");
+ /*****************************/
+ /* Read the interrupt status */
+ /*****************************/
+
+ ul_InterruptLatchReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if ((ul_InterruptLatchReg & 0x8) == 0x8) {
+ /****************************/
+ /* Clear the interrupt flag */
+ /****************************/
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 32 + (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if continuous mode */
+ /***************************/
+
+ if (ps_ModuleInfo->
+ s_ChronoModuleInfo.
+ b_CycleMode == APCI1710_ENABLE) {
+ /********************/
+ /* Clear the status */
+ /********************/
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 36 +
+ (64 * b_ModuleCpt));
+ }
+
+ /*************************/
+ /* Read the timing value */
+ /*************************/
+
+ ul_LatchRegisterValue =
+ inl(devpriv->s_BoardInfos.ui_Address +
+ 4 + (64 * b_ModuleCpt));
+
+ /*****************************/
+ /* Test if interrupt enabled */
+ /*****************************/
+
+ if (ps_ModuleInfo->
+ s_ChronoModuleInfo.b_InterruptMask) {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].ul_OldInterruptMask =
+ 0x80;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue =
+ ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current,
+ 0);
+
+ }
+ }
+ } // Chronometer
+
+ /*************************/
+ /* Test if pulse encoder */
+ /*************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_PULSE_ENCODER) {
+ /****************************/
+ /* Read the status register */
+ /****************************/
+
+ ul_StatusRegister = inl(devpriv->s_BoardInfos.
+ ui_Address + 20 + (64 * b_ModuleCpt));
+
+ if (ul_StatusRegister & 0xF) {
+ for (b_PulseIncoderCpt = 0;
+ b_PulseIncoderCpt < 4;
+ b_PulseIncoderCpt++) {
+ /*************************************/
+ /* Test if pulse encoder initialised */
+ /*************************************/
+
+ if ((ps_ModuleInfo->
+ s_PulseEncoderModuleInfo.
+ s_PulseEncoderInfo
+ [b_PulseIncoderCpt].
+ b_PulseEncoderInit == 1)
+ && (((ps_ModuleInfo->s_PulseEncoderModuleInfo.dw_SetRegister >> b_PulseIncoderCpt) & 1) == 1) && (((ul_StatusRegister >> (b_PulseIncoderCpt)) & 1) == 1)) {
+ devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask =
+ 0x100UL <<
+ b_PulseIncoderCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue
+ = ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) %
+ APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,
+ devpriv->tsk_Current,
+ 0);
+
+ }
+ }
+ }
+ } //pulse encoder
+
+ }
+ return;
+
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h
new file mode 100644
index 00000000000..998cbba8afe
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
+#define COMEDI_SUBD_PWM 12 /* Pulse width Measurement */
+#define COMEDI_SUBD_SSI 13 /* Synchronous serial interface */
+#define COMEDI_SUBD_TOR 14 /* Tor counter */
+#define COMEDI_SUBD_CHRONO 15 /* Chrono meter */
+#define COMEDI_SUBD_PULSEENCODER 16 /* Pulse Encoder INP CPT */
+#define COMEDI_SUBD_INCREMENTALCOUNTER 17 /* Incremental Counter */
+
+#define APCI1710_BOARD_NAME "apci1710"
+#define APCI1710_BOARD_VENDOR_ID 0x10E8
+#define APCI1710_BOARD_DEVICE_ID 0x818F
+#define APCI1710_ADDRESS_RANGE 256
+#define APCI1710_CONFIG_ADDRESS_RANGE 8
+#define APCI1710_INCREMENTAL_COUNTER 0x53430000UL
+#define APCI1710_SSI_COUNTER 0x53490000UL
+#define APCI1710_TTL_IO 0x544C0000UL
+#define APCI1710_DIGITAL_IO 0x44490000UL
+#define APCI1710_82X54_TIMER 0x49430000UL
+#define APCI1710_CHRONOMETER 0x43480000UL
+#define APCI1710_PULSE_ENCODER 0x495A0000UL
+#define APCI1710_TOR_COUNTER 0x544F0000UL
+#define APCI1710_PWM 0x50570000UL
+#define APCI1710_ETM 0x45540000UL
+#define APCI1710_CDA 0x43440000UL
+#define APCI1710_DISABLE 0
+#define APCI1710_ENABLE 1
+#define APCI1710_SYNCHRONOUS_MODE 1
+#define APCI1710_ASYNCHRONOUS_MODE 0
+
+//MODULE INFO STRUCTURE
+
+static const struct comedi_lrange range_apci1710_ttl = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1)
+ }
+};
+
+static const struct comedi_lrange range_apci1710_ssi = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1)
+ }
+};
+
+static const struct comedi_lrange range_apci1710_inccpt = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1)
+ }
+};
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
new file mode 100644
index 00000000000..e4527926c2d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
@@ -0,0 +1,600 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-035 | Compiler : GCC |
+ | Module name : hwdrv_apci035.c | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-035 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci035.h"
+INT i_WatchdogNbr = 0;
+INT i_Temp = 0;
+INT i_Flag = 1;
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI035_ConfigTimerWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Configure As Timer |
+| 1 Configure As Watchdog |
+ data[1] : Watchdog number
+| data[2] : Time base Unit |
+| data[3] : Reload Value |
+ data[4] : External Trigger |
+ 1:Enable
+ 0:Disable
+ data[5] :External Trigger Level
+ 00 Trigger Disabled
+ 01 Trigger Enabled (Low level)
+ 10 Trigger Enabled (High Level)
+ 11 Trigger Enabled (High/Low level)
+ data[6] : External Gate |
+ 1:Enable
+ 0:Disable
+ data[7] : External Gate level
+ 00 Gate Disabled
+ 01 Gate Enabled (Low level)
+ 10 Gate Enabled (High Level)
+ data[8] :Warning Relay
+ 1: ENABLE
+ 0: DISABLE
+ data[9] :Warning Delay available
+ data[10] :Warning Relay Time unit
+ data[11] :Warning Relay Time Reload value
+ data[12] :Reset Relay
+ 1 : ENABLE
+ 0 : DISABLE
+ data[13] :Interrupt
+ 1 : ENABLE
+ 0 : DISABLE
+
+|
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_ConfigTimerWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Status = 0;
+ UINT ui_Command = 0;
+ UINT ui_Mode = 0;
+ i_Temp = 0;
+ devpriv->tsk_Current = current;
+ devpriv->b_TimerSelectMode = data[0];
+ i_WatchdogNbr = data[1];
+ if (data[0] == 0) {
+ ui_Mode = 2;
+ } else {
+ ui_Mode = 0;
+ }
+//ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ ui_Command = 0;
+//ui_Command = ui_Command & 0xFFFFF9FEUL;
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ ui_Command = 0;
+ ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/************************/
+/* Set the reload value */
+/************************/
+ outl(data[3], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 4);
+/*********************/
+/* Set the time unit */
+/*********************/
+ outl(data[2], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 8);
+ if (data[0] == ADDIDATA_TIMER) {
+
+ /******************************/
+ /* Set the mode : */
+ /* - Disable the hardware */
+ /* - Disable the counter mode */
+ /* - Disable the warning */
+ /* - Disable the reset */
+ /* - Enable the timer mode */
+ /* - Set the timer mode */
+ /******************************/
+
+ ui_Command =
+ (ui_Command & 0xFFF719E2UL) | ui_Mode << 13UL | 0x10UL;
+
+ } //if (data[0] == ADDIDATA_TIMER)
+ else {
+ if (data[0] == ADDIDATA_WATCHDOG) {
+
+ /******************************/
+ /* Set the mode : */
+ /* - Disable the hardware */
+ /* - Disable the counter mode */
+ /* - Disable the warning */
+ /* - Disable the reset */
+ /* - Disable the timer mode */
+ /******************************/
+
+ ui_Command = ui_Command & 0xFFF819E2UL;
+
+ } else {
+ printk("\n The parameter for Timer/watchdog selection is in error\n");
+ return -EINVAL;
+ }
+ }
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ ui_Command = 0;
+ ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/********************************/
+/* Disable the hardware trigger */
+/********************************/
+ ui_Command = ui_Command & 0xFFFFF89FUL;
+ if (data[4] == ADDIDATA_ENABLE) {
+ /**********************************/
+ /* Set the hardware trigger level */
+ /**********************************/
+ ui_Command = ui_Command | (data[5] << 5);
+ }
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ ui_Command = 0;
+ ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/*****************************/
+/* Disable the hardware gate */
+/*****************************/
+ ui_Command = ui_Command & 0xFFFFF87FUL;
+ if (data[6] == ADDIDATA_ENABLE) {
+/*******************************/
+/* Set the hardware gate level */
+/*******************************/
+ ui_Command = ui_Command | (data[7] << 7);
+ }
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ ui_Command = 0;
+ ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/*******************************/
+/* Disable the hardware output */
+/*******************************/
+ ui_Command = ui_Command & 0xFFFFF9FBUL;
+/*********************************/
+/* Set the hardware output level */
+/*********************************/
+ ui_Command = ui_Command | (data[8] << 2);
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ if (data[9] == ADDIDATA_ENABLE) {
+ /************************/
+ /* Set the reload value */
+ /************************/
+ outl(data[11],
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 24);
+ /**********************/
+ /* Set the time unite */
+ /**********************/
+ outl(data[10],
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 28);
+ }
+
+ ui_Command = 0;
+ ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ /*******************************/
+ /* Disable the hardware output */
+ /*******************************/
+ ui_Command = ui_Command & 0xFFFFF9F7UL;
+ /*********************************/
+ /* Set the hardware output level */
+ /*********************************/
+ ui_Command = ui_Command | (data[12] << 3);
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ /*************************************/
+ /** Enable the watchdog interrupt **/
+ /*************************************/
+ ui_Command = 0;
+ ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/*******************************/
+/* Set the interrupt selection */
+/*******************************/
+ ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16);
+
+ ui_Command = (ui_Command & 0xFFFFF9FDUL) | (data[13] << 1);
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI035_StartStopWriteTimerWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Start / Stop The Selected Timer , or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 - Stop Selected Timer/Watchdog |
+| 1 - Start Selected Timer/Watchdog |
+| 2 - Trigger Selected Timer/Watchdog |
+| 3 - Stop All Timer/Watchdog |
+| 4 - Start All Timer/Watchdog |
+| 5 - Trigger All Timer/Watchdog |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Command = 0;
+ INT i_Count = 0;
+ if (data[0] == 1) {
+ ui_Command =
+ inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ /**********************/
+ /* Start the hardware */
+ /**********************/
+ ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x1UL;
+ outl(ui_Command,
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ } // if (data[0]==1)
+ if (data[0] == 2) {
+ ui_Command =
+ inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ /***************************/
+ /* Set the trigger command */
+ /***************************/
+ ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x200UL;
+ outl(ui_Command,
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ }
+
+ if (data[0] == 0) //Stop The Watchdog
+ {
+ //Stop The Watchdog
+ ui_Command = 0;
+ //ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ //ui_Command = ui_Command & 0xFFFFF9FEUL;
+ outl(ui_Command,
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ } // if (data[1]==0)
+ if (data[0] == 3) //stop all Watchdogs
+ {
+ ui_Command = 0;
+ for (i_Count = 1; i_Count <= 4; i_Count++) {
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ ui_Command = 0x2UL;
+ } else {
+ ui_Command = 0x10UL;
+ }
+ i_WatchdogNbr = i_Count;
+ outl(ui_Command,
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
+ 0);
+ }
+
+ }
+ if (data[0] == 4) //start all Watchdogs
+ {
+ ui_Command = 0;
+ for (i_Count = 1; i_Count <= 4; i_Count++) {
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ ui_Command = 0x1UL;
+ } else {
+ ui_Command = 0x8UL;
+ }
+ i_WatchdogNbr = i_Count;
+ outl(ui_Command,
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
+ 0);
+ }
+ }
+ if (data[0] == 5) //trigger all Watchdogs
+ {
+ ui_Command = 0;
+ for (i_Count = 1; i_Count <= 4; i_Count++) {
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ ui_Command = 0x4UL;
+ } else {
+ ui_Command = 0x20UL;
+ }
+
+ i_WatchdogNbr = i_Count;
+ outl(ui_Command,
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
+ 0);
+ }
+ i_Temp = 1;
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI035_ReadTimerWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : software trigger status
+ data[1] : hardware trigger status
+| data[2] : Software clear status
+ data[3] : Overflow status
+ data[4] : Timer actual value
+
+
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_ReadTimerWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Status = 0; // Status register
+ i_WatchdogNbr = insn->unused[0];
+ /******************/
+ /* Get the status */
+ /******************/
+ ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16);
+ /***********************************/
+ /* Get the software trigger status */
+ /***********************************/
+ data[0] = ((ui_Status >> 1) & 1);
+ /***********************************/
+ /* Get the hardware trigger status */
+ /***********************************/
+ data[1] = ((ui_Status >> 2) & 1);
+ /*********************************/
+ /* Get the software clear status */
+ /*********************************/
+ data[2] = ((ui_Status >> 3) & 1);
+ /***************************/
+ /* Get the overflow status */
+ /***************************/
+ data[3] = ((ui_Status >> 0) & 1);
+ if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ data[4] = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0);
+
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI035_ConfigAnalogInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Analog Input Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s : Subdevice Pointer |
+| struct comedi_insn *insn : Insn Structure Pointer |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| data[0] : Warning delay value
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_ConfigAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ devpriv->tsk_Current = current;
+ outl(0x200 | 0, devpriv->iobase + 128 + 0x4);
+ outl(0, devpriv->iobase + 128 + 0);
+/********************************/
+/* Initialise the warning value */
+/********************************/
+ outl(0x300 | 0, devpriv->iobase + 128 + 0x4);
+ outl((data[0] << 8), devpriv->iobase + 128 + 0);
+ outl(0x200000UL, devpriv->iobase + 128 + 12);
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI035_ReadAnalogInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
+| data[0] : Digital Value Of Input |
+| |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_ReadAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_CommandRegister = 0;
+/******************/
+/* Set the start */
+/******************/
+ ui_CommandRegister = 0x80000;
+ /******************************/
+ /* Write the command register */
+ /******************************/
+ outl(ui_CommandRegister, devpriv->iobase + 128 + 8);
+
+/***************************************/
+/* Read the digital value of the input */
+/***************************************/
+ data[0] = inl(devpriv->iobase + 128 + 28);
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI035_Reset(struct comedi_device *dev) |
+| |
++----------------------------------------------------------------------------+
+| Task :Resets the registers of the card |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_Reset(struct comedi_device * dev)
+{
+ INT i_Count = 0;
+ for (i_Count = 1; i_Count <= 4; i_Count++) {
+ i_WatchdogNbr = i_Count;
+ outl(0x0, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0); //stop all timers
+ }
+ outl(0x0, devpriv->iobase + 128 + 12); //Disable the warning delay
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI035_Interrupt |
+| (int irq , void *d) |
++----------------------------------------------------------------------------+
+| Task : Interrupt processing Routine |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+static void v_APCI035_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ UINT ui_StatusRegister1 = 0;
+ UINT ui_StatusRegister2 = 0;
+ UINT ui_ReadCommand = 0;
+ UINT ui_ChannelNumber = 0;
+ UINT ui_DigitalTemperature = 0;
+ if (i_Temp == 1) {
+ i_WatchdogNbr = i_Flag;
+ i_Flag = i_Flag + 1;
+ }
+ /**************************************/
+ /* Read the interrupt status register of temperature Warning */
+ /**************************************/
+ ui_StatusRegister1 = inl(devpriv->iobase + 128 + 16);
+ /**************************************/
+ /* Read the interrupt status register for Watchdog/timer */
+ /**************************************/
+
+ ui_StatusRegister2 =
+ inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 20);
+
+ if ((((ui_StatusRegister1) & 0x8) == 0x8)) //Test if warning relay interrupt
+ {
+ /**********************************/
+ /* Disable the temperature warning */
+ /**********************************/
+ ui_ReadCommand = inl(devpriv->iobase + 128 + 12);
+ ui_ReadCommand = ui_ReadCommand & 0xFFDF0000UL;
+ outl(ui_ReadCommand, devpriv->iobase + 128 + 12);
+ /***************************/
+ /* Read the channel number */
+ /***************************/
+ ui_ChannelNumber = inl(devpriv->iobase + 128 + 60);
+ /**************************************/
+ /* Read the digital temperature value */
+ /**************************************/
+ ui_DigitalTemperature = inl(devpriv->iobase + 128 + 60);
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ } //if (((ui_StatusRegister1 & 0x8) == 0x8))
+
+ else {
+ if ((ui_StatusRegister2 & 0x1) == 0x1) {
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ }
+ } //else if (((ui_StatusRegister1 & 0x8) == 0x8))
+
+ return;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h
new file mode 100644
index 00000000000..80d7c0d39aa
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+/* Card Specific information */
+#define APCI035_BOARD_VENDOR_ID 0x15B8
+#define APCI035_ADDRESS_RANGE 255
+
+INT i_TW_Number;
+struct {
+ INT i_Gain;
+ INT i_Polarity;
+ INT i_OffsetRange;
+ INT i_Coupling;
+ INT i_SingleDiff;
+ INT i_AutoCalibration;
+ UINT ui_ReloadValue;
+ UINT ui_TimeUnitReloadVal;
+ INT i_Interrupt;
+ INT i_ModuleSelection;
+} Config_Parameters_Main;
+
+/* ANALOG INPUT RANGE */
+struct comedi_lrange range_apci035_ai = { 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+/* Timer / Watchdog Related Defines */
+#define APCI035_TCW_SYNC_ENABLEDISABLE 0
+#define APCI035_TCW_RELOAD_VALUE 4
+#define APCI035_TCW_TIMEBASE 8
+#define APCI035_TCW_PROG 12
+#define APCI035_TCW_TRIG_STATUS 16
+#define APCI035_TCW_IRQ 20
+#define APCI035_TCW_WARN_TIMEVAL 24
+#define APCI035_TCW_WARN_TIMEBASE 28
+
+#define ADDIDATA_TIMER 0
+/* #define ADDIDATA_WATCHDOG 1 */
+
+#define APCI035_TW1 0
+#define APCI035_TW2 32
+#define APCI035_TW3 64
+#define APCI035_TW4 96
+
+#define APCI035_AI_OFFSET 0
+#define APCI035_TEMP 128
+#define APCI035_ALR_SEQ 4
+#define APCI035_START_STOP_INDEX 8
+#define APCI035_ALR_START_STOP 12
+#define APCI035_ALR_IRQ 16
+#define APCI035_EOS 20
+#define APCI035_CHAN_NO 24
+#define APCI035_CHAN_VAL 28
+#define APCI035_CONV_TIME_TIME_BASE 36
+#define APCI035_RELOAD_CONV_TIME_VAL 32
+#define APCI035_DELAY_TIME_TIME_BASE 44
+#define APCI035_RELOAD_DELAY_TIME_VAL 40
+#define ENABLE_EXT_TRIG 1
+#define ENABLE_EXT_GATE 2
+#define ENABLE_EXT_TRIG_GATE 3
+
+#define ANALOG_INPUT 0
+#define TEMPERATURE 1
+#define RESISTANCE 2
+
+#define ADDIDATA_GREATER_THAN_TEST 0
+#define ADDIDATA_LESS_THAN_TEST 1
+
+#define APCI035_MAXVOLT 2.5
+
+#define ADDIDATA_UNIPOLAR 1
+#define ADDIDATA_BIPOLAR 2
+
+/* ADDIDATA Enable Disable */
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+
+/* Hardware Layer functions for Apci035 */
+
+/* TIMER */
+/* timer value is passed as u seconds */
+INT i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/* Temperature Related Defines (Analog Input Subdevice) */
+
+INT i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/* Interrupt */
+static void v_APCI035_Interrupt(int irq, void *d);
+
+/* Reset functions */
+INT i_APCI035_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
new file mode 100644
index 00000000000..32796ceb946
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
@@ -0,0 +1,285 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-1032 | Compiler : GCC |
+ | Module name : hwdrv_apci1032.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-1032 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci1032.h"
+#include <linux/delay.h>
+//Global variables
+UINT ui_InterruptStatus = 0;
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1032_ConfigDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures the digital input Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 1 Enable Digital Input Interrupt |
+| 0 Disable Digital Input Interrupt |
+| data[1] : 0 ADDIDATA Interrupt OR LOGIC |
+| : 1 ADDIDATA Interrupt AND LOGIC |
+| data[2] : Interrupt mask for the mode 1 |
+| data[3] : Interrupt mask for the mode 2 |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1032_ConfigDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_TmpValue;
+
+ ULONG ul_Command1 = 0;
+ ULONG ul_Command2 = 0;
+ devpriv->tsk_Current = current;
+
+ /*******************************/
+ /* Set the digital input logic */
+ /*******************************/
+ if (data[0] == ADDIDATA_ENABLE) {
+ ul_Command1 = ul_Command1 | data[2];
+ ul_Command2 = ul_Command2 | data[3];
+ outl(ul_Command1,
+ devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
+ outl(ul_Command2,
+ devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
+ if (data[1] == ADDIDATA_OR) {
+ outl(0x4, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+ ui_TmpValue =
+ inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+ } //if (data[1] == ADDIDATA_OR)
+ else {
+ outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+ } //else if(data[1] == ADDIDATA_OR)
+ } // if( data[0] == ADDIDATA_ENABLE)
+ else {
+ ul_Command1 = ul_Command1 & 0xFFFF0000;
+ ul_Command2 = ul_Command2 & 0xFFFF0000;
+ outl(ul_Command1,
+ devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
+ outl(ul_Command2,
+ devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
+ outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+ } //else if ( data[0] == ADDIDATA_ENABLE)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1032_Read1DigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_Channel : Channel number to read |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1032_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_TmpValue = 0;
+ UINT ui_Channel;
+ ui_Channel = CR_CHAN(insn->chanspec);
+ if (ui_Channel >= 0 && ui_Channel <= 31) {
+ ui_TmpValue = (UINT) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
+ // since only 1 channel reqd to bring it to last bit it is rotated
+ // 8 +(chan - 1) times then ANDed with 1 for last bit.
+ *data = (ui_TmpValue >> ui_Channel) & 0x1;
+ } //if(ui_Channel >= 0 && ui_Channel <=31)
+ else {
+ //comedi_error(dev," \n chan spec wrong\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //else if(ui_Channel >= 0 && ui_Channel <=31)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1032_ReadMoreDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To be Read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1032_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_PortValue = data[0];
+ UINT ui_Mask = 0;
+ UINT ui_NoOfChannels;
+
+ ui_NoOfChannels = CR_CHAN(insn->chanspec);
+ if (data[1] == 0) {
+ *data = (UINT) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
+ switch (ui_NoOfChannels) {
+ case 2:
+ ui_Mask = 3;
+ *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+ break;
+ case 4:
+ ui_Mask = 15;
+ *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+ break;
+ case 8:
+ ui_Mask = 255;
+ *data = (*data >> (8 * ui_PortValue)) & ui_Mask;
+ break;
+ case 16:
+ ui_Mask = 65535;
+ *data = (*data >> (16 * ui_PortValue)) & ui_Mask;
+ break;
+ case 31:
+ break;
+ default:
+ //comedi_error(dev," \nchan spec wrong\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } //switch(ui_NoOfChannels)
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ *data = ui_InterruptStatus;
+ } //if(data[1]==1)
+ } //else if(data[1]==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI1032_Interrupt |
+| (int irq , void *d) |
++----------------------------------------------------------------------------+
+| Task : Interrupt handler for the interruptible digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+static void v_APCI1032_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+
+ UINT ui_Temp;
+ //disable the interrupt
+ ui_Temp = inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+ outl(ui_Temp & APCI1032_DIGITAL_IP_INTERRUPT_DISABLE,
+ devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+ ui_InterruptStatus =
+ inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS);
+ ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF;
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ outl(ui_Temp, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); //enable the interrupt
+ return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1032_Reset(struct comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1032_Reset(struct comedi_device * dev)
+{
+ outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); //disable the interrupts
+ inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); //Reset the interrupt status register
+ outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); //Disable the and/or interrupt
+ outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h
new file mode 100644
index 00000000000..659ef85088c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+/********* Definitions for APCI-1032 card *****/
+
+#define APCI1032_BOARD_VENDOR_ID 0x15B8
+#define APCI1032_ADDRESS_RANGE 20
+//DIGITAL INPUT DEFINE
+
+#define APCI1032_DIGITAL_IP 0
+#define APCI1032_DIGITAL_IP_INTERRUPT_MODE1 4
+#define APCI1032_DIGITAL_IP_INTERRUPT_MODE2 8
+#define APCI1032_DIGITAL_IP_IRQ 16
+
+//Digital Input IRQ Function Selection
+#define ADDIDATA_OR 0
+#define ADDIDATA_AND 1
+
+//Digital Input Interrupt Status
+#define APCI1032_DIGITAL_IP_INTERRUPT_STATUS 12
+
+//Digital Input Interrupt Enable Disable.
+#define APCI1032_DIGITAL_IP_INTERRUPT_ENABLE 0x4
+#define APCI1032_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB
+
+//ADDIDATA Enable Disable
+
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+
+// Hardware Layer functions for Apci1032
+
+//DI
+// for di read
+
+INT i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// Interrupt functions.....
+
+static void v_APCI1032_Interrupt(int irq, void *d);
+//Reset
+INT i_APCI1032_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
new file mode 100644
index 00000000000..2d6adcff41e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
@@ -0,0 +1,3045 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-1500 | Compiler : GCC |
+ | Module name : hwdrv_apci1500.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-1500 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+#include "hwdrv_apci1500.h"
+
+int i_TimerCounter1Init = 0;
+int i_TimerCounter2Init = 0;
+int i_WatchdogCounter3Init = 0;
+int i_Event1Status = 0, i_Event2Status = 0;
+int i_TimerCounterWatchdogInterrupt = 0;
+int i_Logic = 0, i_CounterLogic = 0;
+int i_InterruptMask = 0;
+int i_InputChannel = 0;
+int i_TimerCounter1Enabled = 0, i_TimerCounter2Enabled =
+ 0, i_WatchdogCounter3Enabled = 0;
+
+/*
+ +----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ConfigDigitalInputEvent |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : An event can be generated for each port. |
+| The first event is related to the first 8 channels |
+| (port 1) and the second to the following 6 channels |
+| (port 2). An interrupt is generated when one or both |
+| events have occurred |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] :Number of the input port on |
+| which the event will take place |
+| (1 or 2)
+ data[1] : The event logic for port 1 has |
+| three possibilities |
+| :0 APCI1500_AND :This logic |
+| links |
+| the inputs |
+| with an AND |
+| logic. |
+| 1 APCI1500_OR :This logic |
+| links |
+| the inputs |
+| with a |
+| OR logic. |
+| 2 APCI1500_OR_PRIORITY |
+| :This logic |
+| links |
+| the inputs |
+| with a |
+| priority |
+| OR logic. |
+| Input 1 |
+| has the |
+| highest |
+| priority |
+| level and |
+| input 8 |
+| the smallest|
+| For the second port the user has|
+| 1 possibility: |
+| APCI1500_OR :This logic |
+| links |
+| the inputs |
+| with a |
+| polarity |
+| OR logic |
+| data[2] : These 8-character word for port1|
+| and 6-character word for port 2 |
+| give the mask of the event. |
+| Each place gives the state |
+| of the input channels and can |
+| have one of these six characters|
+| |
+| 0 : This input must be on 0 |
+| 1 : This input must be on 1 |
+| 2 : This input reacts to |
+| a falling edge |
+| 3 : This input reacts to a |
+| rising edge |
+| 4 : This input reacts to both edges |
+|
+| 5 : This input is not |
+| used for event |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_ConfigDigitalInputEvent(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0;
+ int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0;
+ int i_PatternTransitionCount = 0, i_RegValue;
+ int i;
+
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Disables the main interrupt on the board */
+ /**********************************************/
+ outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ if (data[0] == 1) {
+ i_MaxChannel = 8;
+ } // if (data[0] == 1)
+ else {
+ if (data[0] == 2) {
+ i_MaxChannel = 6;
+ } // if(data[0]==2)
+ else {
+ printk("\nThe specified port event does not exist\n");
+ return -EINVAL;
+ } //else if(data[0]==2)
+ } //else if (data[0] == 1)
+ switch (data[1]) {
+ case 0:
+ data[1] = APCI1500_AND;
+ break;
+ case 1:
+ data[1] = APCI1500_OR;
+ break;
+ case 2:
+ data[1] = APCI1500_OR_PRIORITY;
+ break;
+ default:
+ printk("\nThe specified interrupt logic does not exist\n");
+ return -EINVAL;
+ } //switch(data[1]);
+
+ i_Logic = data[1];
+ for (i_Count = i_MaxChannel, i = 0; i_Count > 0; i_Count--, i++) {
+ i_EventMask = data[2 + i];
+ switch (i_EventMask) {
+ case 0:
+ i_PatternMask =
+ i_PatternMask | (1 << (i_MaxChannel - i_Count));
+ break;
+ case 1:
+ i_PatternMask =
+ i_PatternMask | (1 << (i_MaxChannel - i_Count));
+ i_PatternPolarity =
+ i_PatternPolarity | (1 << (i_MaxChannel -
+ i_Count));
+ break;
+ case 2:
+ i_PatternMask =
+ i_PatternMask | (1 << (i_MaxChannel - i_Count));
+ i_PatternTransition =
+ i_PatternTransition | (1 << (i_MaxChannel -
+ i_Count));
+ break;
+ case 3:
+ i_PatternMask =
+ i_PatternMask | (1 << (i_MaxChannel - i_Count));
+ i_PatternPolarity =
+ i_PatternPolarity | (1 << (i_MaxChannel -
+ i_Count));
+ i_PatternTransition =
+ i_PatternTransition | (1 << (i_MaxChannel -
+ i_Count));
+ break;
+ case 4:
+ i_PatternTransition =
+ i_PatternTransition | (1 << (i_MaxChannel -
+ i_Count));
+ break;
+ case 5:
+ break;
+ default:
+ printk("\nThe option indicated in the event mask does not exist\n");
+ return -EINVAL;
+ } // switch(i_EventMask)
+ } //for (i_Count = i_MaxChannel; i_Count >0;i_Count --)
+
+ if (data[0] == 1) {
+ /****************************/
+ /* Test the interrupt logic */
+ /****************************/
+
+ if (data[1] == APCI1500_AND ||
+ data[1] == APCI1500_OR ||
+ data[1] == APCI1500_OR_PRIORITY) {
+ /**************************************/
+ /* Tests if a transition was declared */
+ /* for a OR PRIORITY logic */
+ /**************************************/
+
+ if (data[1] == APCI1500_OR_PRIORITY
+ && i_PatternTransition != 0) {
+ /********************************************/
+ /* Transition error on an OR PRIORITY logic */
+ /********************************************/
+ printk("\nTransition error on an OR PRIORITY logic\n");
+ return -EINVAL;
+ } // if (data[1]== APCI1500_OR_PRIORITY && i_PatternTransition != 0)
+
+ /*************************************/
+ /* Tests if more than one transition */
+ /* was declared for an AND logic */
+ /*************************************/
+
+ if (data[1] == APCI1500_AND) {
+ for (i_Count = 0; i_Count < 8; i_Count++) {
+ i_PatternTransitionCount =
+ i_PatternTransitionCount +
+ ((i_PatternTransition >>
+ i_Count) & 0x1);
+
+ } //for (i_Count = 0; i_Count < 8; i_Count++)
+
+ if (i_PatternTransitionCount > 1) {
+ /****************************************/
+ /* Transition error on an AND logic */
+ /****************************************/
+ printk("\n Transition error on an AND logic\n");
+ return -EINVAL;
+ } // if (i_PatternTransitionCount > 1)
+ } // if (data[1]== APCI1500_AND)
+
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port A */
+ /******************/
+ outb(0xF0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Selects the polarity register of port 1 */
+ /**********************************************/
+ outb(APCI1500_RW_PORT_A_PATTERN_POLARITY,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternPolarity,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*********************************************/
+ /* Selects the pattern mask register of */
+ /* port 1 */
+ /*********************************************/
+ outb(APCI1500_RW_PORT_A_PATTERN_MASK,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternMask,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /********************************************/
+ /* Selects the pattern transition register */
+ /* of port 1 */
+ /********************************************/
+ outb(APCI1500_RW_PORT_A_PATTERN_TRANSITION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternTransition,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port 1 */
+ /******************************************/
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port 1 */
+ /******************************************/
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************/
+ /* Port A new mode */
+ /**********************/
+
+ i_RegValue = (i_RegValue & 0xF9) | data[1] | 0x9;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ i_Event1Status = 1;
+
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port A */
+ /*****************/
+ outb(0xF4,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ } // if(data[1]==APCI1500_AND||data[1]==APCI1500_OR||data[1]==APCI1500_OR_PRIORITY)
+ else {
+ printk("\nThe choice for interrupt logic does not exist\n");
+ return -EINVAL;
+ } // else }// if(data[1]==APCI1500_AND||data[1]==APCI1500_OR||data[1]==APCI1500_OR_PRIORITY)
+ } // if (data[0]== 1)
+
+ /************************************/
+ /* Test if event setting for port 2 */
+ /************************************/
+
+ if (data[0] == 2) {
+ /************************/
+ /* Test the event logic */
+ /************************/
+
+ if (data[1] == APCI1500_OR) {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port B */
+ /******************/
+ outb(0x74,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the mode specification mask */
+ /* register of port B */
+ /****************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port B */
+ /******************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = i_RegValue & 0xF9;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************************/
+ /* Selects error channels 1 and 2 */
+ /**********************************/
+
+ i_PatternMask = (i_PatternMask | 0xC0);
+ i_PatternPolarity = (i_PatternPolarity | 0xC0);
+ i_PatternTransition = (i_PatternTransition | 0xC0);
+
+ /**********************************************/
+ /* Selects the polarity register of port 2 */
+ /**********************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternPolarity,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Selects the pattern transition register */
+ /* of port 2 */
+ /**********************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternTransition,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Selects the pattern Mask register */
+ /* of port 2 */
+ /**********************************************/
+
+ outb(APCI1500_RW_PORT_B_PATTERN_MASK,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternMask,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port 2 */
+ /******************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port 2 */
+ /******************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = (i_RegValue & 0xF9) | 4;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ i_Event2Status = 1;
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port B */
+ /*****************/
+
+ outb(0xF4,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } // if (data[1] == APCI1500_OR)
+ else {
+ printk("\nThe choice for interrupt logic does not exist\n");
+ return -EINVAL;
+ } //elseif (data[1] == APCI1500_OR)
+ } //if(data[0]==2)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_StartStopInputEvent |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Allows or disallows a port event |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_Channel : Channel number to read |
+| unsigned int *data : Data Pointer to read status |
+ data[0] :0 Start input event
+ 1 Stop input event
+ data[1] :No of port (1 or 2)
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_StartStopInputEvent(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i_Event1InterruptStatus = 0, i_Event2InterruptStatus =
+ 0, i_RegValue;
+ switch (data[0]) {
+ case START:
+ /*************************/
+ /* Tests the port number */
+ /*************************/
+
+ if (data[1] == 1 || data[1] == 2) {
+ /***************************/
+ /* Test if port 1 selected */
+ /***************************/
+
+ if (data[1] == 1) {
+ /*****************************/
+ /* Test if event initialised */
+ /*****************************/
+ if (i_Event1Status == 1) {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port A */
+ /******************/
+ outb(0xF0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the command and status register of */
+ /* port 1 */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************/
+ /* Allows the pattern interrupt */
+ /*************************************/
+ outb(0xC0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port A */
+ /*****************/
+ outb(0xF4,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_Event1InterruptStatus = 1;
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Authorizes the main interrupt on the board */
+ /**********************************************/
+ outb(0xD0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ } // if(i_Event1Status==1)
+ else {
+ printk("\nEvent 1 not initialised\n");
+ return -EINVAL;
+ } //else if(i_Event1Status==1)
+ } //if (data[1]==1)
+ if (data[1] == 2) {
+
+ if (i_Event2Status == 1) {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port B */
+ /******************/
+ outb(0x74,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the command and status register of */
+ /* port 2 */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************/
+ /* Allows the pattern interrupt */
+ /*************************************/
+ outb(0xC0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port B */
+ /*****************/
+ outb(0xF4,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Authorizes the main interrupt on the board */
+ /**********************************************/
+ outb(0xD0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_Event2InterruptStatus = 1;
+ } // if(i_Event2Status==1)
+ else {
+ printk("\nEvent 2 not initialised\n");
+ return -EINVAL;
+ } //else if(i_Event2Status==1)
+ } // if(data[1]==2)
+ } // if (data[1] == 1 || data[0] == 2)
+ else {
+ printk("\nThe port parameter is in error\n");
+ return -EINVAL;
+ } //else if (data[1] == 1 || data[0] == 2)
+
+ break;
+
+ case STOP:
+ /*************************/
+ /* Tests the port number */
+ /*************************/
+
+ if (data[1] == 1 || data[1] == 2) {
+ /***************************/
+ /* Test if port 1 selected */
+ /***************************/
+
+ if (data[1] == 1) {
+ /*****************************/
+ /* Test if event initialised */
+ /*****************************/
+ if (i_Event1Status == 1) {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port A */
+ /******************/
+ outb(0xF0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the command and status register of */
+ /* port 1 */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************/
+ /* Inhibits the pattern interrupt */
+ /*************************************/
+ outb(0xE0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port A */
+ /*****************/
+ outb(0xF4,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_Event1InterruptStatus = 0;
+ } // if(i_Event1Status==1)
+ else {
+ printk("\nEvent 1 not initialised\n");
+ return -EINVAL;
+ } //else if(i_Event1Status==1)
+ } //if (data[1]==1)
+ if (data[1] == 2) {
+ /*****************************/
+ /* Test if event initialised */
+ /*****************************/
+ if (i_Event2Status == 1) {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port B */
+ /******************/
+ outb(0x74,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the command and status register of */
+ /* port 2 */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************/
+ /* Inhibits the pattern interrupt */
+ /*************************************/
+ outb(0xE0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port B */
+ /*****************/
+ outb(0xF4,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_Event2InterruptStatus = 0;
+ } // if(i_Event2Status==1)
+ else {
+ printk("\nEvent 2 not initialised\n");
+ return -EINVAL;
+ } //else if(i_Event2Status==1)
+ } //if(data[1]==2)
+
+ } // if (data[1] == 1 || data[1] == 2)
+ else {
+ printk("\nThe port parameter is in error\n");
+ return -EINVAL;
+ } //else if (data[1] == 1 || data[1] == 2)
+ break;
+ default:
+ printk("\nThe option of START/STOP logic does not exist\n");
+ return -EINVAL;
+ } //switch(data[0])
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_Initialisation |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_Channel : Channel number to read |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1500_Initialisation(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i_DummyRead = 0;
+ /******************/
+ /* Software reset */
+ /******************/
+ i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the master configuration control register */
+ /*****************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the mode specification register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the data path polarity register of port A */
+ outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* High level of port A means 1 */
+ outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the data direction register of port A */
+ outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs */
+ outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port A */
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port A */
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of port A: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the handshake specification register of port A */
+ outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes the register */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the mode specification register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data path polarity register of port B */
+ outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* A high level of port B means 1 */
+ outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data direction register of port B */
+ outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs */
+ outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port B */
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port B */
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of port B: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the handshake specification register of port B */
+ outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes the register */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the data path polarity register of port C */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* High level of port C means 1 */
+ outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data direction register of port C */
+ outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs except channel 1 */
+ outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the special IO register of port C */
+ outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes it */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 1 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of timer 1 */
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of timer 1 */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 2 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of timer 2 */
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates Timer 2 interrupt management: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 3 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of Timer 3 */
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates interrupt management of timer 3: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes all interrupts */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ReadMoreDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To be Read |
+| UINT *data : Data Pointer
+ data[0] : 0 Read a single channel
+ 1 read a port value
+ data[1] : port value
++----------------------------------------------------------------------------+
+| Output Parameters : -- data[0] :The read status value
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_PortValue = data[1];
+ UINT ui_Mask = 0;
+ UINT ui_Channel;
+ UINT ui_TmpValue = 0;
+ ui_Channel = CR_CHAN(insn->chanspec);
+
+ switch (data[0]) {
+ case 0:
+ if (ui_Channel >= 0 && ui_Channel <= 15) {
+ ui_TmpValue =
+ (UINT) inw(devpriv->i_IobaseAddon +
+ APCI1500_DIGITAL_IP);
+ *data = (ui_TmpValue >> ui_Channel) & 0x1;
+ } //if(ui_Channel >= 0 && ui_Channel <=15)
+ else {
+ printk("\nThe channel specification are in error\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //else if(ui_Channel >= 0 && ui_Channel <=15)
+ break;
+ case 1:
+
+ *data = (UINT) inw(devpriv->i_IobaseAddon +
+ APCI1500_DIGITAL_IP);
+ switch (ui_Channel) {
+ case 2:
+ ui_Mask = 3;
+ *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+ break;
+ case 4:
+ ui_Mask = 15;
+ *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+ break;
+ case 8:
+ ui_Mask = 255;
+ *data = (*data >> (8 * ui_PortValue)) & ui_Mask;
+ break;
+ case 15:
+ break;
+
+ default:
+ printk("\nSpecified channel cannot be read \n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } //switch(ui_Channel)
+ break;
+ default:
+ printk("\nThe specified functionality does not exist\n");
+ return -EINVAL;
+ } //switch(data[0])
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ConfigDigitalOutputErrorInterrupt
+ (struct comedi_device *dev,struct comedi_subdevice *s struct comedi_insn
+ *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures the digital output memory and the digital
+ output error interrupt |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| data[0] :1:Memory on |
+| 0:Memory off |
+ data[1] :1 Enable the voltage error interrupt
+| :0 Disable the voltage error interrupt |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ devpriv->b_OutputMemoryStatus = data[0];
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To Write |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ static UINT ui_Temp = 0;
+ UINT ui_Temp1;
+
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+
+ if (!devpriv->b_OutputMemoryStatus) {
+ ui_Temp = 0;
+
+ } //if(!devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outw(data[0],
+ devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 4:
+ data[0] =
+ (data[0] << (4 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 8:
+ data[0] =
+ (data[0] << (8 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 15:
+ data[0] = data[0] | ui_Temp;
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outw(data[0],
+ devpriv->i_IobaseAddon +
+ APCI1500_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ (data[0] << ui_NoOfChannel) ^
+ 0xffffffff;
+ data[0] = data[0] & ui_Temp;
+ outw(data[0],
+ devpriv->i_IobaseAddon +
+ APCI1500_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 4:
+ data[0] = ~data[0] & 0xf;
+ ui_Temp1 = 15;
+ ui_Temp1 =
+ ui_Temp1 << 4 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (4 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 8:
+ data[0] = ~data[0] & 0xff;
+ ui_Temp1 = 255;
+ ui_Temp1 =
+ ui_Temp1 << 8 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (8 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 15:
+ break;
+
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outw(data[0],
+ devpriv->i_IobaseAddon +
+ APCI1500_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ ui_Temp = data[0];
+ return (insn->n);;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ConfigCounterTimerWatchdog(comedi_device
+ *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status data[0] : 2 APCI1500_1_8_KHZ
+| 1 APCI1500_3_6_KHZ |
+| 0 APCI1500_115_KHZ
+ data[1] : 0 Counter1/Timer1
+ 1 Counter2/Timer2
+ 2 Counter3/Watchdog
+ data[2] : 0 Counter
+ 1 Timer/Watchdog
+ data[3] : This parameter has |
+| two meanings. |
+| - If the counter/timer |
+| is used as a counter |
+| the limit value of |
+| the counter is given |
+| |
+| - If the counter/timer |
+| is used as a timer, |
+| the divider factor |
+| for the output is |
+| given.
+ data[4] : 0 APCI1500_CONTINUOUS
+ 1 APCI1500_SINGLE
+ data[5] : 0 Software Trigger
+ 1 Hardware Trigger
+
+ data[6] :0 Software gate
+ 1 Hardware gate
+ data[7] :0 Interrupt Disable
+ 1 Interrupt Enable
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i_TimerCounterMode, i_MasterConfiguration;
+
+ devpriv->tsk_Current = current;
+
+//Selection of the input clock
+ if (data[0] == 0 || data[0] == 1 || data[0] == 2) {
+ outw(data[0], devpriv->i_IobaseAddon + APCI1500_CLK_SELECT);
+ } // if(data[0]==0||data[0]==1||data[0]==2)
+ else {
+ if (data[0] != 3) {
+ printk("\nThe option for input clock selection does not exist\n");
+ return -EINVAL;
+ } // if(data[0]!=3)
+ } //elseif(data[0]==0||data[0]==1||data[0]==2)
+ //Select the counter/timer
+ switch (data[1]) {
+ case COUNTER1:
+ //selecting counter or timer
+ switch (data[2]) {
+ case 0:
+ data[2] = APCI1500_COUNTER;
+ break;
+ case 1:
+ data[2] = APCI1500_TIMER;
+ break;
+ default:
+ printk("\nThis choice is not a timer nor a counter\n");
+ return -EINVAL;
+ } // switch(data[2])
+
+ //Selecting single or continuous mode
+ switch (data[4]) {
+ case 0:
+ data[4] = APCI1500_CONTINUOUS;
+ break;
+ case 1:
+ data[4] = APCI1500_SINGLE;
+ break;
+ default:
+ printk("\nThis option for single/continuous mode does not exist\n");
+ return -EINVAL;
+ } // switch(data[4])
+
+ i_TimerCounterMode = data[2] | data[4] | 7;
+ /*************************/
+ /* Test the reload value */
+ /*************************/
+
+ if ((data[3] >= 0) && (data[3] <= 65535)) {
+ if (data[7] == APCI1500_ENABLE
+ || data[7] == APCI1500_DISABLE) {
+
+ /************************************************/
+ /* Selects the mode register of timer/counter 1 */
+ /************************************************/
+ outb(APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************/
+ /* Writes the new mode */
+ /***********************/
+ outb(i_TimerCounterMode,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of timer/counter 1 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************/
+ /* Writes the low value */
+ /*************************/
+
+ outb(data[3],
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of timer/counter 1 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**************************/
+ /* Writes the high value */
+ /**************************/
+
+ data[3] = data[3] >> 8;
+ outb(data[3],
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************/
+ /* Reads the register */
+ /**********************/
+
+ i_MasterConfiguration =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************************************/
+ /* Enables timer/counter 1 and triggers timer/counter 1 */
+ /********************************************************/
+
+ i_MasterConfiguration =
+ i_MasterConfiguration | 0x40;
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************/
+ /* Writes the new configuration */
+ /********************************/
+ outb(i_MasterConfiguration,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the commands register of */
+ /* timer/counter 1 */
+ /****************************************/
+
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Disable timer/counter 1 */
+ /***************************/
+
+ outb(0x0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the commands register of */
+ /* timer/counter 1 */
+ /****************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Trigger timer/counter 1 */
+ /***************************/
+ outb(0x2,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ else {
+ printk("\nError in selection of interrupt enable or disable\n");
+ return -EINVAL;
+ } //elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ } // if ((data[3]>= 0) && (data[3] <= 65535))
+ else {
+ printk("\nError in selection of reload value\n");
+ return -EINVAL;
+ } //else if ((data[3]>= 0) && (data[3] <= 65535))
+ i_TimerCounterWatchdogInterrupt = data[7];
+ i_TimerCounter1Init = 1;
+ break;
+
+ case COUNTER2: //selecting counter or timer
+ switch (data[2]) {
+ case 0:
+ data[2] = APCI1500_COUNTER;
+ break;
+ case 1:
+ data[2] = APCI1500_TIMER;
+ break;
+ default:
+ printk("\nThis choice is not a timer nor a counter\n");
+ return -EINVAL;
+ } // switch(data[2])
+
+ //Selecting single or continuous mode
+ switch (data[4]) {
+ case 0:
+ data[4] = APCI1500_CONTINUOUS;
+ break;
+ case 1:
+ data[4] = APCI1500_SINGLE;
+ break;
+ default:
+ printk("\nThis option for single/continuous mode does not exist\n");
+ return -EINVAL;
+ } // switch(data[4])
+
+ //Selecting software or hardware trigger
+ switch (data[5]) {
+ case 0:
+ data[5] = APCI1500_SOFTWARE_TRIGGER;
+ break;
+ case 1:
+ data[5] = APCI1500_HARDWARE_TRIGGER;
+ break;
+ default:
+ printk("\nThis choice for software or hardware trigger does not exist\n");
+ return -EINVAL;
+ } // switch(data[5])
+
+ //Selecting software or hardware gate
+ switch (data[6]) {
+ case 0:
+ data[6] = APCI1500_SOFTWARE_GATE;
+ break;
+ case 1:
+ data[6] = APCI1500_HARDWARE_GATE;
+ break;
+ default:
+ printk("\nThis choice for software or hardware gate does not exist\n");
+ return -EINVAL;
+ } // switch(data[6])
+
+ i_TimerCounterMode = data[2] | data[4] | data[5] | data[6] | 7;
+
+ /*************************/
+ /* Test the reload value */
+ /*************************/
+
+ if ((data[3] >= 0) && (data[3] <= 65535)) {
+ if (data[7] == APCI1500_ENABLE
+ || data[7] == APCI1500_DISABLE) {
+
+ /************************************************/
+ /* Selects the mode register of timer/counter 2 */
+ /************************************************/
+ outb(APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************/
+ /* Writes the new mode */
+ /***********************/
+ outb(i_TimerCounterMode,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of timer/counter 2 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************/
+ /* Writes the low value */
+ /*************************/
+
+ outb(data[3],
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of timer/counter 2 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**************************/
+ /* Writes the high value */
+ /**************************/
+
+ data[3] = data[3] >> 8;
+ outb(data[3],
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************/
+ /* Reads the register */
+ /**********************/
+
+ i_MasterConfiguration =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************************************/
+ /* Enables timer/counter 2 and triggers timer/counter 2 */
+ /********************************************************/
+
+ i_MasterConfiguration =
+ i_MasterConfiguration | 0x20;
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************/
+ /* Writes the new configuration */
+ /********************************/
+ outb(i_MasterConfiguration,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the commands register of */
+ /* timer/counter 2 */
+ /****************************************/
+
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Disable timer/counter 2 */
+ /***************************/
+
+ outb(0x0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the commands register of */
+ /* timer/counter 2 */
+ /****************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Trigger timer/counter 1 */
+ /***************************/
+ outb(0x2,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ else {
+ printk("\nError in selection of interrupt enable or disable\n");
+ return -EINVAL;
+ } //elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ } // if ((data[3]>= 0) && (data[3] <= 65535))
+ else {
+ printk("\nError in selection of reload value\n");
+ return -EINVAL;
+ } //else if ((data[3]>= 0) && (data[3] <= 65535))
+ i_TimerCounterWatchdogInterrupt = data[7];
+ i_TimerCounter2Init = 1;
+ break;
+
+ case COUNTER3: //selecting counter or watchdog
+ switch (data[2]) {
+ case 0:
+ data[2] = APCI1500_COUNTER;
+ break;
+ case 1:
+ data[2] = APCI1500_WATCHDOG;
+ break;
+ default:
+ printk("\nThis choice is not a watchdog nor a counter\n");
+ return -EINVAL;
+ } // switch(data[2])
+
+ //Selecting single or continuous mode
+ switch (data[4]) {
+ case 0:
+ data[4] = APCI1500_CONTINUOUS;
+ break;
+ case 1:
+ data[4] = APCI1500_SINGLE;
+ break;
+ default:
+ printk("\nThis option for single/continuous mode does not exist\n");
+ return -EINVAL;
+ } // switch(data[4])
+
+ //Selecting software or hardware gate
+ switch (data[6]) {
+ case 0:
+ data[6] = APCI1500_SOFTWARE_GATE;
+ break;
+ case 1:
+ data[6] = APCI1500_HARDWARE_GATE;
+ break;
+ default:
+ printk("\nThis choice for software or hardware gate does not exist\n");
+ return -EINVAL;
+ } // switch(data[6])
+
+ /*****************************/
+ /* Test if used for watchdog */
+ /*****************************/
+
+ if (data[2] == APCI1500_WATCHDOG) {
+ /*****************************/
+ /* - Enables the output line */
+ /* - Enables retrigger */
+ /* - Pulses output */
+ /*****************************/
+ i_TimerCounterMode = data[2] | data[4] | 0x54;
+ } //if (data[2] == APCI1500_WATCHDOG)
+ else {
+ i_TimerCounterMode = data[2] | data[4] | data[6] | 7;
+ } //elseif (data[2] == APCI1500_WATCHDOG)
+ /*************************/
+ /* Test the reload value */
+ /*************************/
+
+ if ((data[3] >= 0) && (data[3] <= 65535)) {
+ if (data[7] == APCI1500_ENABLE
+ || data[7] == APCI1500_DISABLE) {
+
+ /************************************************/
+ /* Selects the mode register of watchdog/counter 3 */
+ /************************************************/
+ outb(APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************/
+ /* Writes the new mode */
+ /***********************/
+ outb(i_TimerCounterMode,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of watchdog/counter 3 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************/
+ /* Writes the low value */
+ /*************************/
+
+ outb(data[3],
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of watchdog/counter 3 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**************************/
+ /* Writes the high value */
+ /**************************/
+
+ data[3] = data[3] >> 8;
+ outb(data[3],
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************/
+ /* Reads the register */
+ /**********************/
+
+ i_MasterConfiguration =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************************************/
+ /* Enables watchdog/counter 3 and triggers watchdog/counter 3 */
+ /********************************************************/
+
+ i_MasterConfiguration =
+ i_MasterConfiguration | 0x10;
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************/
+ /* Writes the new configuration */
+ /********************************/
+ outb(i_MasterConfiguration,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************/
+ /* Test if COUNTER */
+ /********************/
+ if (data[2] == APCI1500_COUNTER) {
+
+ /*************************************/
+ /* Selects the command register of */
+ /* watchdog/counter 3 */
+ /*************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************************/
+ /* Disable the watchdog/counter 3 and starts it */
+ /*************************************************/
+ outb(0x0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************************/
+ /* Selects the command register of */
+ /* watchdog/counter 3 */
+ /*************************************/
+
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************************/
+ /* Trigger the watchdog/counter 3 and starts it */
+ /*************************************************/
+ outb(0x2,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ } //elseif(data[2]==APCI1500_COUNTER)
+
+ } //if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ else {
+ printk("\nError in selection of interrupt enable or disable\n");
+ return -EINVAL;
+ } //elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ } // if ((data[3]>= 0) && (data[3] <= 65535))
+ else {
+ printk("\nError in selection of reload value\n");
+ return -EINVAL;
+ } //else if ((data[3]>= 0) && (data[3] <= 65535))
+ i_TimerCounterWatchdogInterrupt = data[7];
+ i_WatchdogCounter3Init = 1;
+ break;
+
+ default:
+ printk("\nThe specified counter\timer option does not exist\n");
+ } //switch(data[1])
+ i_CounterLogic = data[2];
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_StartStopTriggerTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Start / Stop or trigger the timer counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
+ data[0] : 0 Counter1/Timer1
+ 1 Counter2/Timer2
+ 2 Counter3/Watchdog
+ data[1] : 0 start
+ 1 stop
+ 2 Trigger
+ data[2] : 0 Counter
+ 1 Timer/Watchdog
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i_CommandAndStatusValue;
+
+ switch (data[0]) {
+ case COUNTER1:
+ switch (data[1]) {
+ case START:
+ if (i_TimerCounter1Init == 1) {
+ if (i_TimerCounterWatchdogInterrupt == 1) {
+ i_CommandAndStatusValue = 0xC4; //Enable the interrupt
+ } // if(i_TimerCounterWatchdogInterrupt==1)
+ else {
+ i_CommandAndStatusValue = 0xE4; //disable the interrupt
+ } //elseif(i_TimerCounterWatchdogInterrupt==1)
+ /**************************/
+ /* Starts timer/counter 1 */
+ /**************************/
+ i_TimerCounter1Enabled = 1;
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_TimerCounter1Init==1)
+ else {
+ printk("\nCounter/Timer1 not configured\n");
+ return -EINVAL;
+ }
+ break;
+
+ case STOP:
+
+ /**************************/
+ /* Stop timer/counter 1 */
+ /**************************/
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x00,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_TimerCounter1Enabled = 0;
+ break;
+
+ case TRIGGER:
+ if (i_TimerCounter1Init == 1) {
+ if (i_TimerCounter1Enabled == 1) {
+ /************************/
+ /* Set Trigger and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0x6;
+ } //if( i_TimerCounter1Enabled==1)
+ else {
+ /***************/
+ /* Set Trigger */
+ /***************/
+
+ i_CommandAndStatusValue = 0x2;
+ } //elseif(i_TimerCounter1Enabled==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_TimerCounter1Init==1)
+ else {
+ printk("\nCounter/Timer1 not configured\n");
+ return -EINVAL;
+ }
+ break;
+
+ default:
+ printk("\nThe specified option for start/stop/trigger does not exist\n");
+ return -EINVAL;
+ } //switch(data[1])
+ break;
+
+ case COUNTER2:
+ switch (data[1]) {
+ case START:
+ if (i_TimerCounter2Init == 1) {
+ if (i_TimerCounterWatchdogInterrupt == 1) {
+ i_CommandAndStatusValue = 0xC4; //Enable the interrupt
+ } // if(i_TimerCounterWatchdogInterrupt==1)
+ else {
+ i_CommandAndStatusValue = 0xE4; //disable the interrupt
+ } //elseif(i_TimerCounterWatchdogInterrupt==1)
+ /**************************/
+ /* Starts timer/counter 2 */
+ /**************************/
+ i_TimerCounter2Enabled = 1;
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_TimerCounter2Init==1)
+ else {
+ printk("\nCounter/Timer2 not configured\n");
+ return -EINVAL;
+ }
+ break;
+
+ case STOP:
+
+ /**************************/
+ /* Stop timer/counter 2 */
+ /**************************/
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x00,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_TimerCounter2Enabled = 0;
+ break;
+ case TRIGGER:
+ if (i_TimerCounter2Init == 1) {
+ if (i_TimerCounter2Enabled == 1) {
+ /************************/
+ /* Set Trigger and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0x6;
+ } //if( i_TimerCounter2Enabled==1)
+ else {
+ /***************/
+ /* Set Trigger */
+ /***************/
+
+ i_CommandAndStatusValue = 0x2;
+ } //elseif(i_TimerCounter2Enabled==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_TimerCounter2Init==1)
+ else {
+ printk("\nCounter/Timer2 not configured\n");
+ return -EINVAL;
+ }
+ break;
+ default:
+ printk("\nThe specified option for start/stop/trigger does not exist\n");
+ return -EINVAL;
+ } //switch(data[1])
+ break;
+ case COUNTER3:
+ switch (data[1]) {
+ case START:
+ if (i_WatchdogCounter3Init == 1) {
+
+ if (i_TimerCounterWatchdogInterrupt == 1) {
+ i_CommandAndStatusValue = 0xC4; //Enable the interrupt
+ } // if(i_TimerCounterWatchdogInterrupt==1)
+ else {
+ i_CommandAndStatusValue = 0xE4; //disable the interrupt
+ } //elseif(i_TimerCounterWatchdogInterrupt==1)
+ /**************************/
+ /* Starts Watchdog/counter 3 */
+ /**************************/
+ i_WatchdogCounter3Enabled = 1;
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ } // if( i_WatchdogCounter3init==1)
+ else {
+ printk("\nWatchdog/Counter3 not configured\n");
+ return -EINVAL;
+ }
+ break;
+
+ case STOP:
+
+ /**************************/
+ /* Stop Watchdog/counter 3 */
+ /**************************/
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x00,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_WatchdogCounter3Enabled = 0;
+ break;
+
+ case TRIGGER:
+ switch (data[2]) {
+ case 0: //triggering counter 3
+ if (i_WatchdogCounter3Init == 1) {
+ if (i_WatchdogCounter3Enabled == 1) {
+ /************************/
+ /* Set Trigger and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0x6;
+ } //if( i_WatchdogCounter3Enabled==1)
+ else {
+ /***************/
+ /* Set Trigger */
+ /***************/
+
+ i_CommandAndStatusValue = 0x2;
+ } //elseif(i_WatchdogCounter3Enabled==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_WatchdogCounter3Init==1)
+ else {
+ printk("\nCounter3 not configured\n");
+ return -EINVAL;
+ }
+ break;
+ case 1:
+ //triggering Watchdog 3
+ if (i_WatchdogCounter3Init == 1) {
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x6,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_WatchdogCounter3Init==1)
+ else {
+ printk("\nWatchdog 3 not configured\n");
+ return -EINVAL;
+ }
+ break;
+ default:
+ printk("\nWrong choice of watchdog/counter3\n");
+ return -EINVAL;
+ } //switch(data[2])
+ break;
+ default:
+ printk("\nThe specified option for start/stop/trigger does not exist\n");
+ return -EINVAL;
+ } //switch(data[1])
+ break;
+ default:
+ printk("\nThe specified choice for counter/watchdog/timer does not exist\n");
+ return -EINVAL;
+ } //switch(data[0])
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ReadCounterTimerWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
+ data[0] : 0 Counter1/Timer1
+ 1 Counter2/Timer2
+ 2 Counter3/Watchdog
+
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i_CommandAndStatusValue;
+ switch (data[0]) {
+ case COUNTER1:
+ //Read counter/timer1
+ if (i_TimerCounter1Init == 1) {
+ if (i_TimerCounter1Enabled == 1) {
+ /************************/
+ /* Set RCC and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0xC;
+ } //if( i_TimerCounter1Init==1)
+ else {
+ /***************/
+ /* Set RCC */
+ /***************/
+
+ i_CommandAndStatusValue = 0x8;
+ } //elseif(i_TimerCounter1Init==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************************/
+ /* Selects the counter register (high) */
+ /***************************************/
+ outb(APCI1500_R_CPT_TMR1_VALUE_HIGH,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] = data[0] << 8;
+ data[0] = data[0] & 0xff00;
+ outb(APCI1500_R_CPT_TMR1_VALUE_LOW,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] =
+ data[0] | inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_TimerCounter1Init==1)
+ else {
+ printk("\nTimer/Counter1 not configured\n");
+ return -EINVAL;
+ } //elseif( i_TimerCounter1Init==1)
+ break;
+ case COUNTER2:
+ //Read counter/timer2
+ if (i_TimerCounter2Init == 1) {
+ if (i_TimerCounter2Enabled == 1) {
+ /************************/
+ /* Set RCC and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0xC;
+ } //if( i_TimerCounter2Init==1)
+ else {
+ /***************/
+ /* Set RCC */
+ /***************/
+
+ i_CommandAndStatusValue = 0x8;
+ } //elseif(i_TimerCounter2Init==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************************/
+ /* Selects the counter register (high) */
+ /***************************************/
+ outb(APCI1500_R_CPT_TMR2_VALUE_HIGH,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] = data[0] << 8;
+ data[0] = data[0] & 0xff00;
+ outb(APCI1500_R_CPT_TMR2_VALUE_LOW,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] =
+ data[0] | inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_TimerCounter2Init==1)
+ else {
+ printk("\nTimer/Counter2 not configured\n");
+ return -EINVAL;
+ } //elseif( i_TimerCounter2Init==1)
+ break;
+ case COUNTER3:
+ //Read counter/watchdog2
+ if (i_WatchdogCounter3Init == 1) {
+ if (i_WatchdogCounter3Enabled == 1) {
+ /************************/
+ /* Set RCC and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0xC;
+ } //if( i_TimerCounter2Init==1)
+ else {
+ /***************/
+ /* Set RCC */
+ /***************/
+
+ i_CommandAndStatusValue = 0x8;
+ } //elseif(i_WatchdogCounter3Init==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************************/
+ /* Selects the counter register (high) */
+ /***************************************/
+ outb(APCI1500_R_CPT_TMR3_VALUE_HIGH,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] = data[0] << 8;
+ data[0] = data[0] & 0xff00;
+ outb(APCI1500_R_CPT_TMR3_VALUE_LOW,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] =
+ data[0] | inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_WatchdogCounter3Init==1)
+ else {
+ printk("\nWatchdogCounter3 not configured\n");
+ return -EINVAL;
+ } //elseif( i_WatchdogCounter3Init==1)
+ break;
+ default:
+ printk("\nThe choice of timer/counter/watchdog does not exist\n");
+ return -EINVAL;
+ } //switch(data[0])
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ReadInterruptMask |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Read the interrupt mask |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
+
+
++----------------------------------------------------------------------------+
+| Output Parameters : -- data[0]:The interrupt mask value data[1]:Channel no
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_ReadInterruptMask(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = i_InterruptMask;
+ data[1] = i_InputChannel;
+ i_InterruptMask = 0;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ConfigureInterrupt |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Configures the interrupt registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer |
+
+
++----------------------------------------------------------------------------+
+| Output Parameters : --
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_ConfigureInterrupt(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Status;
+ int i_RegValue;
+ int i_Constant;
+ devpriv->tsk_Current = current;
+ outl(0x0, devpriv->i_IobaseAmcc + 0x38);
+ if (data[0] == 1) {
+ i_Constant = 0xC0;
+ } //if(data[0]==1)
+ else {
+ if (data[0] == 0) {
+ i_Constant = 0x00;
+ } //if{data[0]==0)
+ else {
+ printk("\nThe parameter passed to driver is in error for enabling the voltage interrupt\n");
+ return -EINVAL;
+ } //else if(data[0]==0)
+ } //elseif(data[0]==1)
+
+ /*****************************************************/
+ /* Selects the mode specification register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*********************************************/
+ /* Writes the new configuration (APCI1500_OR) */
+ /*********************************************/
+ i_RegValue = (i_RegValue & 0xF9) | APCI1500_OR;
+
+ outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************/
+ /* Authorises the interrupt on the board */
+ /*****************************************/
+ outb(0xC0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the pattern polarity register of port B */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************/
+ /* Selects the pattern transition register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************************/
+ /* Selects the pattern mask register of port B */
+ /***********************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_MASK,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of port A */
+ /***********************************/
+
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of port B */
+ /***********************************/
+
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 1 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 1 */
+ /***********************************/
+
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 2 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 2 */
+ /***********************************/
+
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 3 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 3 */
+ /***********************************/
+
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Authorizes the main interrupt on the board */
+ /**********************************************/
+ outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Enables the PCI interrupt */
+ /*****************************/
+ outl(0x3000, devpriv->i_IobaseAmcc + 0x38);
+ ui_Status = inl(devpriv->i_IobaseAmcc + 0x10);
+ ui_Status = inl(devpriv->i_IobaseAmcc + 0x38);
+ outl(0x23000, devpriv->i_IobaseAmcc + 0x38);
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI1500_Interrupt |
+| (int irq , void *d) |
++----------------------------------------------------------------------------+
+| Task : Interrupt handler |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+static void v_APCI1500_Interrupt(int irq, void *d)
+{
+
+ struct comedi_device *dev = d;
+ UINT ui_InterruptStatus = 0;
+ int i_RegValue = 0;
+ i_InterruptMask = 0;
+
+ /***********************************/
+ /* Read the board interrupt status */
+ /***********************************/
+ ui_InterruptStatus = inl(devpriv->i_IobaseAmcc + 0x38);
+
+ /***************************************/
+ /* Test if board generated a interrupt */
+ /***************************************/
+ if ((ui_InterruptStatus & 0x800000) == 0x800000) {
+ /************************/
+ /* Disable all Interrupt */
+ /************************/
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ //outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Disables the main interrupt on the board */
+ /**********************************************/
+ //outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60) {
+ /*****************************************************/
+ /* Selects the command and status register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of port A */
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_InterruptMask = i_InterruptMask | 1;
+ if (i_Logic == APCI1500_OR_PRIORITY) {
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************************************/
+ /* Selects the interrupt vector register of port A */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ i_InputChannel = 1 + (i_RegValue >> 1);
+
+ } // if(i_Logic==APCI1500_OR_PRIORITY)
+ else {
+ i_InputChannel = 0;
+ } //elseif(i_Logic==APCI1500_OR_PRIORITY)
+ } // if ((i_RegValue & 0x60) == 0x60)
+
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60) {
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of port B */
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ printk("\n\n\n");
+ /****************/
+ /* Reads port B */
+ /****************/
+ i_RegValue =
+ inb((UINT) devpriv->iobase +
+ APCI1500_Z8536_PORT_B);
+
+ i_RegValue = i_RegValue & 0xC0;
+ /**************************************/
+ /* Tests if this is an external error */
+ /**************************************/
+
+ if (i_RegValue) {
+ //Disable the interrupt
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outl(0x0, devpriv->i_IobaseAmcc + 0x38);
+
+ if (i_RegValue & 0x80) {
+ i_InterruptMask =
+ i_InterruptMask | 0x40;
+ } //if (i_RegValue & 0x80)
+
+ if (i_RegValue & 0x40) {
+ i_InterruptMask =
+ i_InterruptMask | 0x80;
+ } //if (i_RegValue & 0x40)
+ } // if (i_RegValue)
+ else {
+ i_InterruptMask = i_InterruptMask | 2;
+ } // if (i_RegValue)
+ } //if ((i_RegValue & 0x60) == 0x60)
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 1 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60) {
+ /*****************************************************/
+ /* Selects the command and status register of timer 1 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 1 */
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_InterruptMask = i_InterruptMask | 4;
+ } // if ((i_RegValue & 0x60) == 0x60)
+ /*****************************************************/
+ /* Selects the command and status register of timer 2 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60) {
+ /*****************************************************/
+ /* Selects the command and status register of timer 2 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 2 */
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_InterruptMask = i_InterruptMask | 8;
+ } // if ((i_RegValue & 0x60) == 0x60)
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 3 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60) {
+ /*****************************************************/
+ /* Selects the command and status register of timer 3 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 3 */
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ if (i_CounterLogic == APCI1500_COUNTER) {
+ i_InterruptMask = i_InterruptMask | 0x10;
+ } //if(i_CounterLogic==APCI1500_COUNTER)
+ else {
+ i_InterruptMask = i_InterruptMask | 0x20;
+ }
+ } // if ((i_RegValue & 0x60) == 0x60)
+
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ /***********************/
+ /* Enable all Interrupts */
+ /***********************/
+
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Authorizes the main interrupt on the board */
+ /**********************************************/
+ outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ } // if ((ui_InterruptStatus & 0x800000) == 0x800000)
+ else {
+ printk("\nInterrupt from unknown source\n");
+
+ } //else if ((ui_InterruptStatus & 0x800000) == 0x800000)
+ return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_Reset(struct comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_Reset(struct comedi_device * dev)
+{
+ int i_DummyRead = 0;
+ i_TimerCounter1Init = 0;
+ i_TimerCounter2Init = 0;
+ i_WatchdogCounter3Init = 0;
+ i_Event1Status = 0;
+ i_Event2Status = 0;
+ i_TimerCounterWatchdogInterrupt = 0;
+ i_Logic = 0;
+ i_CounterLogic = 0;
+ i_InterruptMask = 0;
+ i_InputChannel = 0;;
+ i_TimerCounter1Enabled = 0;
+ i_TimerCounter2Enabled = 0;
+ i_WatchdogCounter3Enabled = 0;
+
+ /******************/
+ /* Software reset */
+ /******************/
+ i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the master configuration control register */
+ /*****************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the mode specification register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the data path polarity register of port A */
+ outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* High level of port A means 1 */
+ outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the data direction register of port A */
+ outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs */
+ outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port A */
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port A */
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of port A: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the handshake specification register of port A */
+ outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes the register */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the mode specification register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data path polarity register of port B */
+ outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* A high level of port B means 1 */
+ outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data direction register of port B */
+ outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs */
+ outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port B */
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port B */
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of port B: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the handshake specification register of port B */
+ outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes the register */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the data path polarity register of port C */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* High level of port C means 1 */
+ outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data direction register of port C */
+ outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs except channel 1 */
+ outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the special IO register of port C */
+ outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes it */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 1 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of timer 1 */
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of timer 1 */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 2 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of timer 2 */
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates Timer 2 interrupt management: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 3 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of Timer 3 */
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates interrupt management of timer 3: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes all interrupts */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ //reset all the digital outputs
+ outw(0x0, devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
+/*******************************/
+/* Disable the board interrupt */
+/*******************************/
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************/
+ /* Selects the command and status register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+ outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+ outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+ /* Selects the command and status register of timer 1 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+ outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+ /* Selects the command and status register of timer 2 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+ outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+/* Selects the command and status register of timer 3*/
+/*****************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+ outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h
new file mode 100644
index 00000000000..5d960b40a6a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+/********* Definitions for APCI-1500 card *****/
+
+// Card Specific information
+#define APCI1500_BOARD_VENDOR_ID 0x10e8
+#define APCI1500_ADDRESS_RANGE 4
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI1500_DIGITAL_OP 2
+#define APCI1500_DIGITAL_IP 0
+#define APCI1500_AND 2
+#define APCI1500_OR 4
+#define APCI1500_OR_PRIORITY 6
+#define APCI1500_CLK_SELECT 0
+#define COUNTER1 0
+#define COUNTER2 1
+#define COUNTER3 2
+#define APCI1500_COUNTER 0x20
+#define APCI1500_TIMER 0
+#define APCI1500_WATCHDOG 0
+#define APCI1500_SINGLE 0
+#define APCI1500_CONTINUOUS 0x80
+#define APCI1500_DISABLE 0
+#define APCI1500_ENABLE 1
+#define APCI1500_SOFTWARE_TRIGGER 0x4
+#define APCI1500_HARDWARE_TRIGGER 0x10
+#define APCI1500_SOFTWARE_GATE 0
+#define APCI1500_HARDWARE_GATE 0x8
+#define START 0
+#define STOP 1
+#define TRIGGER 2
+
+/*
+ * Zillog I/O enumeration
+ */
+enum {
+ APCI1500_Z8536_PORT_C,
+ APCI1500_Z8536_PORT_B,
+ APCI1500_Z8536_PORT_A,
+ APCI1500_Z8536_CONTROL_REGISTER
+};
+
+/*
+ * Z8536 CIO Internal Address
+ */
+enum {
+ APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
+ APCI1500_RW_PORT_B_INTERRUPT_CONTROL,
+ APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR,
+ APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
+ APCI1500_RW_PORT_C_DATA_DIRECTION,
+ APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
+
+ APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ APCI1500_RW_PORT_A_DATA,
+ APCI1500_RW_PORT_B_DATA,
+ APCI1500_RW_PORT_C_DATA,
+
+ APCI1500_R_CPT_TMR1_VALUE_HIGH,
+ APCI1500_R_CPT_TMR1_VALUE_LOW,
+ APCI1500_R_CPT_TMR2_VALUE_HIGH,
+ APCI1500_R_CPT_TMR2_VALUE_LOW,
+ APCI1500_R_CPT_TMR3_VALUE_HIGH,
+ APCI1500_R_CPT_TMR3_VALUE_LOW,
+ APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
+ APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
+ APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
+ APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
+ APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
+ APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
+ APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
+ APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
+ APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
+ APCI1500_R_CURRENT_VECTOR,
+
+ APCI1500_RW_PORT_A_SPECIFICATION,
+ APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
+ APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
+ APCI1500_RW_PORT_A_DATA_DIRECTION,
+ APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL,
+ APCI1500_RW_PORT_A_PATTERN_POLARITY,
+ APCI1500_RW_PORT_A_PATTERN_TRANSITION,
+ APCI1500_RW_PORT_A_PATTERN_MASK,
+
+ APCI1500_RW_PORT_B_SPECIFICATION,
+ APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
+ APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
+ APCI1500_RW_PORT_B_DATA_DIRECTION,
+ APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL,
+ APCI1500_RW_PORT_B_PATTERN_POLARITY,
+ APCI1500_RW_PORT_B_PATTERN_TRANSITION,
+ APCI1500_RW_PORT_B_PATTERN_MASK
+};
+
+ /*----------DIGITAL INPUT----------------*/
+static int i_APCI1500_Initialisation(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+static int i_APCI1500_StartStopInputEvent(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*---------- DIGITAL OUTPUT------------*/
+static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+static int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*----------TIMER----------------*/
+static int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+static int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+static int i_APCI1500_ReadInterruptMask(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*----------INTERRUPT HANDLER------*/
+static void v_APCI1500_Interrupt(int irq, void *d);
+static int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+/*----------RESET---------------*/
+static int i_APCI1500_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
new file mode 100644
index 00000000000..5ae9a93844e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
@@ -0,0 +1,542 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-1516 | Compiler : GCC |
+ | Module name : hwdrv_apci1516.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-1516 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci1516.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_Read1DigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1516_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_TmpValue = 0;
+ UINT ui_Channel;
+ ui_Channel = CR_CHAN(insn->chanspec);
+ if (ui_Channel >= 0 && ui_Channel <= 7) {
+ ui_TmpValue = (UINT) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
+ // since only 1 channel reqd to bring it to last bit it is rotated
+ // 8 +(chan - 1) times then ANDed with 1 for last bit.
+ *data = (ui_TmpValue >> ui_Channel) & 0x1;
+ } //if(ui_Channel >= 0 && ui_Channel <=7)
+ else {
+ //comedi_error(dev," \n chan spec wrong\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //else if(ui_Channel >= 0 && ui_Channel <=7)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ReadMoreDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ui_PortValue = data[0];
+ UINT ui_Mask = 0;
+ UINT ui_NoOfChannels;
+
+ ui_NoOfChannels = CR_CHAN(insn->chanspec);
+
+ *data = (UINT) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
+ switch (ui_NoOfChannels) {
+ case 2:
+ ui_Mask = 3;
+ *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+ break;
+ case 4:
+ ui_Mask = 15;
+ *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+ break;
+ case 7:
+ break;
+
+ default:
+ printk("\nWrong parameters\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } //switch(ui_NoOfChannels)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ConfigDigitalOutput (struct comedi_device *dev,
+ struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| data[0] :1:Memory on |
+| 0:Memory off |
+| |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1516_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ devpriv->b_OutputMemoryStatus = data[0];
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp, ui_Temp1;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+
+ printk("EL311003 : @=%x\n", devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp = inw(devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ } //if(devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } //if(devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outw(data[0], devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ printk("EL311003 : d=%d @=%x\n", data[0],
+ devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 4:
+ data[0] =
+ (data[0] << (4 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 7:
+ data[0] = data[0] | ui_Temp;
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outw(data[0],
+ devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ printk("EL311003 : d=%d @=%x\n", data[0],
+ devpriv->iobase + APCI1516_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] = (data[0] << ui_NoOfChannel) ^ 0xff;
+ data[0] = data[0] & ui_Temp;
+ outw(data[0],
+ devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ printk("EL311003 : d=%d @=%x\n", data[0],
+ devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xff) & ui_Temp;
+ break;
+
+ case 4:
+ data[0] = ~data[0] & 0xf;
+ ui_Temp1 = 15;
+ ui_Temp1 =
+ ui_Temp1 << 4 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (4 *
+ data
+ [2])) ^
+ 0xff) & ui_Temp;
+ break;
+
+ case 7:
+ break;
+
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outw(data[0],
+ devpriv->iobase +
+ APCI1516_DIGITAL_OP);
+
+ printk("EL311003 : d=%d @=%x\n",
+ data[0],
+ devpriv->iobase +
+ APCI1516_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ return (insn->n);;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ReadDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ui_Temp;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ ui_Temp = data[0];
+ *data = inw(devpriv->iobase + APCI1516_DIGITAL_OP_RW);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } //if(ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ *data = (*data >> (2 * data[1])) & 3;
+ break;
+
+ case 4:
+ *data = (*data >> (4 * data[1])) & 15;
+ break;
+
+ case 7:
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+ } //if(ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } //elseif(ui_Temp==1)
+ } //elseif(ui_Temp==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ConfigWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1516_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0] == 0) {
+ //Disable the watchdog
+ outw(0x0,
+ devpriv->i_IobaseAddon +
+ APCI1516_WATCHDOG_ENABLEDISABLE);
+ //Loading the Reload value
+ outw(data[1],
+ devpriv->i_IobaseAddon +
+ APCI1516_WATCHDOG_RELOAD_VALUE);
+ data[1] = data[1] >> 16;
+ outw(data[1],
+ devpriv->i_IobaseAddon +
+ APCI1516_WATCHDOG_RELOAD_VALUE + 2);
+ } //if(data[0]==0)
+ else {
+ printk("\nThe input parameters are wrong\n");
+ return -EINVAL;
+ } //elseif(data[0]==0)
+
+ return insn->n;
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI1516_StartStopWriteWatchdog |
+ | (struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data); |
+ +----------------------------------------------------------------------------+
+ | Task : Start / Stop The Watchdog |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+ | unsigned int *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+ */
+
+int i_APCI1516_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case 0: //stop the watchdog
+ outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE); //disable the watchdog
+ break;
+ case 1: //start the watchdog
+ outw(0x0001,
+ devpriv->i_IobaseAddon +
+ APCI1516_WATCHDOG_ENABLEDISABLE);
+ break;
+ case 2: //Software trigger
+ outw(0x0201,
+ devpriv->i_IobaseAddon +
+ APCI1516_WATCHDOG_ENABLEDISABLE);
+ break;
+ default:
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } // switch(data[0])
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ReadWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1516_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = inw(devpriv->i_IobaseAddon + APCI1516_WATCHDOG_STATUS) & 0x1;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_Reset(struct comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_Reset(struct comedi_device * dev)
+{
+ outw(0x0, devpriv->iobase + APCI1516_DIGITAL_OP); //RESETS THE DIGITAL OUTPUTS
+ outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE);
+ outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE);
+ outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE + 2);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h
new file mode 100644
index 00000000000..398baa04a16
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+/********* Definitions for APCI-1516 card *****/
+
+// Card Specific information
+#define APCI1516_BOARD_VENDOR_ID 0x15B8
+#define APCI1516_ADDRESS_RANGE 8
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI1516_DIGITAL_OP 4
+#define APCI1516_DIGITAL_OP_RW 4
+#define APCI1516_DIGITAL_IP 0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define ADDIDATA_WATCHDOG 2
+#define APCI1516_DIGITAL_OP_WATCHDOG 0
+#define APCI1516_WATCHDOG_ENABLEDISABLE 12
+#define APCI1516_WATCHDOG_RELOAD_VALUE 4
+#define APCI1516_WATCHDOG_STATUS 16
+
+// Hardware Layer functions for Apci1516
+
+//Digital Input
+INT i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1516_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//Digital Output
+int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//reset
+INT i_APCI1516_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
new file mode 100644
index 00000000000..a6b504c3d39
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
@@ -0,0 +1,1105 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-1564 | Compiler : GCC |
+ | Module name : hwdrv_apci1564.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-1564 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include <linux/delay.h>
+#include "hwdrv_apci1564.h"
+
+//Global variables
+UINT ui_InterruptStatus_1564 = 0;
+UINT ui_InterruptData, ui_Type;
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ConfigDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures the digital input Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 1 Enable Digital Input Interrupt |
+| 0 Disable Digital Input Interrupt |
+| data[1] : 0 ADDIDATA Interrupt OR LOGIC |
+| : 1 ADDIDATA Interrupt AND LOGIC |
+| data[2] : Interrupt mask for the mode 1 |
+| data[3] : Interrupt mask for the mode 2 |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ConfigDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ devpriv->tsk_Current = current;
+ /*******************************/
+ /* Set the digital input logic */
+ /*******************************/
+ if (data[0] == ADDIDATA_ENABLE) {
+ data[2] = data[2] << 4;
+ data[3] = data[3] << 4;
+ outl(data[2],
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
+ outl(data[3],
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
+ if (data[1] == ADDIDATA_OR) {
+ outl(0x4,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ);
+ } // if (data[1] == ADDIDATA_OR)
+ else {
+ outl(0x6,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ);
+ } // else if (data[1] == ADDIDATA_OR)
+ } // if (data[0] == ADDIDATA_ENABLE)
+ else {
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ);
+ } // else if (data[0] == ADDIDATA_ENABLE)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_Read1DigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_Channel : Channel number to read |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_TmpValue = 0;
+ UINT ui_Channel;
+
+ ui_Channel = CR_CHAN(insn->chanspec);
+ if (ui_Channel >= 0 && ui_Channel <= 31) {
+ ui_TmpValue =
+ (UINT) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
+ // since only 1 channel reqd to bring it to last bit it is rotated
+ // 8 +(chan - 1) times then ANDed with 1 for last bit.
+ *data = (ui_TmpValue >> ui_Channel) & 0x1;
+ } // if (ui_Channel >= 0 && ui_Channel <=31)
+ else {
+ comedi_error(dev, "Not a valid channel number !!! \n");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //else if (ui_Channel >= 0 && ui_Channel <=31)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ReadMoreDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To be Read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_PortValue = data[0];
+ UINT ui_Mask = 0;
+ UINT ui_NoOfChannels;
+
+ ui_NoOfChannels = CR_CHAN(insn->chanspec);
+ if (data[1] == 0) {
+ *data = (UINT) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
+ switch (ui_NoOfChannels) {
+ case 2:
+ ui_Mask = 3;
+ *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+ break;
+ case 4:
+ ui_Mask = 15;
+ *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+ break;
+ case 8:
+ ui_Mask = 255;
+ *data = (*data >> (8 * ui_PortValue)) & ui_Mask;
+ break;
+ case 16:
+ ui_Mask = 65535;
+ *data = (*data >> (16 * ui_PortValue)) & ui_Mask;
+ break;
+ case 31:
+ break;
+ default:
+ comedi_error(dev, "Not a valid Channel number !!!\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } // switch (ui_NoOfChannels)
+ } // if (data[1]==0)
+ else {
+ if (data[1] == 1) {
+ *data = ui_InterruptStatus_1564;
+ } // if (data[1]==1)
+ } // else if (data[1]==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ConfigDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[1] : 1 Enable VCC Interrupt |
+| 0 Disable VCC Interrupt |
+| data[2] : 1 Enable CC Interrupt |
+| 0 Disable CC Interrupt |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command = 0;
+
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ } // if ((data[0]!=0) && (data[0]!=1))
+ if (data[0]) {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+ } // if (data[0])
+ else {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+ } // else if (data[0])
+ if (data[1] == ADDIDATA_ENABLE) {
+ ul_Command = ul_Command | 0x1;
+ } // if (data[1] == ADDIDATA_ENABLE)
+ else {
+ ul_Command = ul_Command & 0xFFFFFFFE;
+ } // else if (data[1] == ADDIDATA_ENABLE)
+ if (data[2] == ADDIDATA_ENABLE) {
+ ul_Command = ul_Command | 0x2;
+ } // if (data[2] == ADDIDATA_ENABLE)
+ else {
+ ul_Command = ul_Command & 0xFFFFFFFD;
+ } // else if (data[2] == ADDIDATA_ENABLE)
+ outl(ul_Command,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_INTERRUPT);
+ ui_InterruptData =
+ inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_INTERRUPT);
+ devpriv->tsk_Current = current;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To Write |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp, ui_Temp1;
+ UINT ui_NoOfChannel;
+
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp =
+ inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_RW);
+ } // if (devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } // else if (devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outl(data[0],
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_RW);
+ } // if (data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+ case 4:
+ data[0] =
+ (data[0] << (4 *
+ data[2])) | ui_Temp;
+ break;
+ case 8:
+ data[0] =
+ (data[0] << (8 *
+ data[2])) | ui_Temp;
+ break;
+ case 16:
+ data[0] =
+ (data[0] << (16 *
+ data[2])) | ui_Temp;
+ break;
+ case 31:
+ data[0] = data[0] | ui_Temp;
+ break;
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } // switch (ui_NoOfChannels)
+ outl(data[0],
+ devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_RW);
+ } // if (data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } // else if (data[1]==1)
+ } // else if (data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ (data[0] << ui_NoOfChannel) ^
+ 0xffffffff;
+ data[0] = data[0] & ui_Temp;
+ outl(data[0],
+ devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_RW);
+ } // if (data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+ case 4:
+ data[0] = ~data[0] & 0xf;
+ ui_Temp1 = 15;
+ ui_Temp1 =
+ ui_Temp1 << 4 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (4 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+ case 8:
+ data[0] = ~data[0] & 0xff;
+ ui_Temp1 = 255;
+ ui_Temp1 =
+ ui_Temp1 << 8 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (8 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+ case 16:
+ data[0] = ~data[0] & 0xffff;
+ ui_Temp1 = 65535;
+ ui_Temp1 =
+ ui_Temp1 << 16 *
+ data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (16 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+ case 31:
+ break;
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //switch(ui_NoOfChannels)
+ outl(data[0],
+ devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_RW);
+ } // if (data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } // else if (data[1]==1)
+ } // else if (data[1]==0)
+ } // if (data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } // else if (data[3]==1)
+ } // else if (data[3]==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ReadDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_RW);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } // if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ switch (ui_NoOfChannel) {
+ case 2:
+ *data = (*data >> (2 * data[1])) & 3;
+ break;
+
+ case 4:
+ *data = (*data >> (4 * data[1])) & 15;
+ break;
+
+ case 8:
+ *data = (*data >> (8 * data[1])) & 255;
+ break;
+
+ case 16:
+ *data = (*data >> (16 * data[1])) & 65535;
+ break;
+
+ case 31:
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } // switch(ui_NoOfChannels)
+ } // if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } // else if (ui_Temp==1)
+ } // else if (ui_Temp==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ConfigTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Configure As Timer |
+| 1 Configure As Counter |
+| 2 Configure As Watchdog |
+| data[1] : 1 Enable Interrupt |
+| 0 Disable Interrupt |
+| data[2] : Time Unit |
+| data[3] : Reload Value |
+| data[4] : Timer Mode |
+| data[5] : Timer Counter Watchdog Number|
+ data[6] : Counter Direction
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command1 = 0;
+ devpriv->tsk_Current = current;
+ if (data[0] == ADDIDATA_WATCHDOG) {
+ devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
+
+ //Disable the watchdog
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_PROG);
+ //Loading the Reload value
+ outl(data[3],
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_RELOAD_VALUE);
+ } // if (data[0]==ADDIDATA_WATCHDOG)
+ else if (data[0] == ADDIDATA_TIMER) {
+ //First Stop The Timer
+ ul_Command1 =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); //Stop The Timer
+
+ devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
+ if (data[1] == 1) {
+ outl(0x02, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); //Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ);
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_IRQ);
+ outl(0x0,
+ devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_IRQ);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER1 +
+ APCI1564_TCW_IRQ);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER2 +
+ APCI1564_TCW_IRQ);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER3 +
+ APCI1564_TCW_IRQ);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER4 +
+ APCI1564_TCW_IRQ);
+ } // if (data[1]==1)
+ else {
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); //disable Timer interrupt
+ } // else if (data[1]==1)
+
+ // Loading Timebase
+
+ outl(data[2],
+ devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_TIMEBASE);
+
+ //Loading the Reload value
+ outl(data[3],
+ devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_RELOAD_VALUE);
+
+ ul_Command1 =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ ul_Command1 =
+ (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
+ outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); //mode 2
+ } // else if (data[0]==ADDIDATA_TIMER)
+ else if (data[0] == ADDIDATA_COUNTER) {
+ devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
+ devpriv->b_ModeSelectRegister = data[5];
+
+ //First Stop The Counter
+ ul_Command1 =
+ inl(devpriv->iobase + ((data[5] - 1) * 0x20) +
+ APCI1564_TCW_PROG);
+ ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1, devpriv->iobase + ((data[5] - 1) * 0x20) + APCI1564_TCW_PROG); //Stop The Timer
+
+ /************************/
+ /* Set the reload value */
+ /************************/
+ outl(data[3],
+ devpriv->iobase + ((data[5] - 1) * 0x20) +
+ APCI1564_TCW_RELOAD_VALUE);
+
+ /******************************/
+ /* Set the mode : */
+ /* - Disable the hardware */
+ /* - Disable the counter mode */
+ /* - Disable the warning */
+ /* - Disable the reset */
+ /* - Disable the timer mode */
+ /* - Enable the counter mode */
+ /******************************/
+ ul_Command1 =
+ (ul_Command1 & 0xFFFC19E2UL) | 0x80000UL |
+ (ULONG) ((ULONG) data[4] << 16UL);
+ outl(ul_Command1,
+ devpriv->iobase + ((data[5] - 1) * 0x20) +
+ APCI1564_TCW_PROG);
+
+ // Enable or Disable Interrupt
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1);
+ outl(ul_Command1,
+ devpriv->iobase + ((data[5] - 1) * 0x20) +
+ APCI1564_TCW_PROG);
+
+ /*****************************/
+ /* Set the Up/Down selection */
+ /*****************************/
+ ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18);
+ outl(ul_Command1,
+ devpriv->iobase + ((data[5] - 1) * 0x20) +
+ APCI1564_TCW_PROG);
+ } // else if (data[0]==ADDIDATA_COUNTER)
+ else {
+ printk(" Invalid subdevice.");
+ } // else if (data[0]==ADDIDATA_WATCHDOG)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_StartStopWriteTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Start / Stop The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Timer |
+| 1 Counter |
+| 2 Watchdog | | data[1] : 1 Start |
+| 0 Stop |
+| 2 Trigger |
+| Clear (Only Counter) |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command1 = 0;
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ switch (data[1]) {
+ case 0: //stop the watchdog
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + APCI1564_TCW_PROG); //disable the watchdog
+ break;
+ case 1: //start the watchdog
+ outl(0x0001,
+ devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_PROG);
+ break;
+ case 2: //Software trigger
+ outl(0x0201,
+ devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_PROG);
+ break;
+ default:
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } // switch (data[1])
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+ if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ if (data[1] == 1) {
+ ul_Command1 =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
+
+ //Enable the Timer
+ outl(ul_Command1,
+ devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ } // if (data[1]==1)
+ else if (data[1] == 0) {
+ //Stop The Timer
+
+ ul_Command1 =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1,
+ devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ } // else if(data[1]==0)
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+ if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
+ ul_Command1 =
+ inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
+ 1) * 0x20) + APCI1564_TCW_PROG);
+ if (data[1] == 1) {
+ //Start the Counter subdevice
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
+ } // if (data[1] == 1)
+ else if (data[1] == 0) {
+ // Stops the Counter subdevice
+ ul_Command1 = 0;
+
+ } // else if (data[1] == 0)
+ else if (data[1] == 2) {
+ // Clears the Counter subdevice
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400;
+ } // else if (data[1] == 3)
+ outl(ul_Command1,
+ devpriv->iobase + ((devpriv->b_ModeSelectRegister -
+ 1) * 0x20) + APCI1564_TCW_PROG);
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ReadTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command1 = 0;
+
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ // Stores the status of the Watchdog
+ data[0] =
+ inl(devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_TRIG_STATUS) & 0x1;
+ data[1] =
+ inl(devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP_WATCHDOG);
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+ else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ // Stores the status of the Timer
+ data[0] =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_TRIG_STATUS) & 0x1;
+
+ // Stores the Actual value of the Timer
+ data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER);
+ } // else if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+ else if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
+ // Read the Counter Actual Value.
+ data[0] =
+ inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
+ 1) * 0x20) +
+ APCI1564_TCW_SYNC_ENABLEDISABLE);
+ ul_Command1 =
+ inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
+ 1) * 0x20) + APCI1564_TCW_TRIG_STATUS);
+
+ /***********************************/
+ /* Get the software trigger status */
+ /***********************************/
+ data[1] = (BYTE) ((ul_Command1 >> 1) & 1);
+
+ /***********************************/
+ /* Get the hardware trigger status */
+ /***********************************/
+ data[2] = (BYTE) ((ul_Command1 >> 2) & 1);
+
+ /*********************************/
+ /* Get the software clear status */
+ /*********************************/
+ data[3] = (BYTE) ((ul_Command1 >> 3) & 1);
+
+ /***************************/
+ /* Get the overflow status */
+ /***************************/
+ data[4] = (BYTE) ((ul_Command1 >> 0) & 1);
+ } // else if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER)
+ else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
+ && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)
+ && (devpriv->b_TimerSelectMode != ADDIDATA_COUNTER)) {
+ printk("\n Invalid Subdevice !!!\n");
+ } // else if ((devpriv->b_TimerSelectMode!=ADDIDATA_TIMER) && (devpriv->b_TimerSelectMode!=ADDIDATA_WATCHDOG)&& (devpriv->b_TimerSelectMode!=ADDIDATA_COUNTER))
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ReadInterruptStatus |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task :Reads the interrupt status register |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1564_ReadInterruptStatus(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ *data = ui_Type;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI1564_Interrupt |
+| (int irq , void *d) |
++----------------------------------------------------------------------------+
+| Task : Interrupt handler for the interruptible digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+static void v_APCI1564_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ UINT ui_DO, ui_DI;
+ UINT ui_Timer;
+ UINT ui_C1, ui_C2, ui_C3, ui_C4;
+ ULONG ul_Command2 = 0;
+ ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ) & 0x01;
+ ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_IRQ) & 0x01;
+ ui_Timer =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_IRQ) & 0x01;
+ ui_C1 = inl(devpriv->iobase + APCI1564_COUNTER1 +
+ APCI1564_TCW_IRQ) & 0x1;
+ ui_C2 = inl(devpriv->iobase + APCI1564_COUNTER2 +
+ APCI1564_TCW_IRQ) & 0x1;
+ ui_C3 = inl(devpriv->iobase + APCI1564_COUNTER3 +
+ APCI1564_TCW_IRQ) & 0x1;
+ ui_C4 = inl(devpriv->iobase + APCI1564_COUNTER4 +
+ APCI1564_TCW_IRQ) & 0x1;
+ if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0
+ && ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) {
+ printk("\nInterrupt from unknown source\n");
+ } // if(ui_DI==0 && ui_DO==0 && ui_Timer==0 && ui_C1==0 && ui_C2==0 && ui_C3==0 && ui_C4==0)
+
+ if (ui_DI == 1) {
+ ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ);
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ);
+ ui_InterruptStatus_1564 =
+ inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_INTERRUPT_STATUS);
+ ui_InterruptStatus_1564 = ui_InterruptStatus_1564 & 0X000FFFF0;
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ outl(ui_DI, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ); //enable the interrupt
+ return;
+ }
+
+ if (ui_DO == 1) {
+ // Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt.
+ ui_Type =
+ inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
+ //Disable the Interrupt
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_INTERRUPT);
+
+ //Sends signal to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ } // if (ui_DO)
+
+ if ((ui_Timer == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_TIMER)) {
+ // Disable Timer Interrupt
+ ul_Command2 =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ // Enable Timer Interrupt
+
+ outl(ul_Command2,
+ devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ } // if ((ui_Timer == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_TIMER))
+
+ if ((ui_C1 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
+ // Disable Counter Interrupt
+ ul_Command2 =
+ inl(devpriv->iobase + APCI1564_COUNTER1 +
+ APCI1564_TCW_PROG);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER1 +
+ APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ // Enable Counter Interrupt
+ outl(ul_Command2,
+ devpriv->iobase + APCI1564_COUNTER1 +
+ APCI1564_TCW_PROG);
+ } // if ((ui_C1 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER))
+
+ if ((ui_C2 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
+ // Disable Counter Interrupt
+ ul_Command2 =
+ inl(devpriv->iobase + APCI1564_COUNTER2 +
+ APCI1564_TCW_PROG);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER2 +
+ APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ // Enable Counter Interrupt
+ outl(ul_Command2,
+ devpriv->iobase + APCI1564_COUNTER2 +
+ APCI1564_TCW_PROG);
+ } // if ((ui_C2 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+
+ if ((ui_C3 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
+ // Disable Counter Interrupt
+ ul_Command2 =
+ inl(devpriv->iobase + APCI1564_COUNTER3 +
+ APCI1564_TCW_PROG);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER3 +
+ APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ // Enable Counter Interrupt
+ outl(ul_Command2,
+ devpriv->iobase + APCI1564_COUNTER3 +
+ APCI1564_TCW_PROG);
+ } // if ((ui_C3 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+
+ if ((ui_C4 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
+ // Disable Counter Interrupt
+ ul_Command2 =
+ inl(devpriv->iobase + APCI1564_COUNTER4 +
+ APCI1564_TCW_PROG);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER4 +
+ APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ // Enable Counter Interrupt
+ outl(ul_Command2,
+ devpriv->iobase + APCI1564_COUNTER4 +
+ APCI1564_TCW_PROG);
+ } // if ((ui_C4 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+ return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_Reset(struct comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1564_Reset(struct comedi_device * dev)
+{
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_IRQ); //disable the interrupts
+ inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_STATUS); //Reset the interrupt status register
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE1); //Disable the and/or interrupt
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
+ devpriv->b_DigitalOutputRegister = 0;
+ ui_Type = 0;
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP); //Resets the output channels
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_INTERRUPT); //Disables the interrupt.
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_RELOAD_VALUE);
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER);
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);
+
+ outl(0x0, devpriv->iobase + APCI1564_COUNTER1 + APCI1564_TCW_PROG);
+ outl(0x0, devpriv->iobase + APCI1564_COUNTER2 + APCI1564_TCW_PROG);
+ outl(0x0, devpriv->iobase + APCI1564_COUNTER3 + APCI1564_TCW_PROG);
+ outl(0x0, devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_PROG);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h
new file mode 100644
index 00000000000..f0c461ca539
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+/********* Definitions for APCI-1564 card *****/
+
+#define APCI1564_BOARD_VENDOR_ID 0x15B8
+#define APCI1564_ADDRESS_RANGE 128
+
+//DIGITAL INPUT-OUTPUT DEFINE
+// Input defines
+#define APCI1564_DIGITAL_IP 0x04
+#define APCI1564_DIGITAL_IP_INTERRUPT_MODE1 4
+#define APCI1564_DIGITAL_IP_INTERRUPT_MODE2 8
+#define APCI1564_DIGITAL_IP_IRQ 16
+
+// Output defines
+#define APCI1564_DIGITAL_OP 0x18
+#define APCI1564_DIGITAL_OP_RW 0
+#define APCI1564_DIGITAL_OP_INTERRUPT 4
+#define APCI1564_DIGITAL_OP_IRQ 12
+
+//Digital Input IRQ Function Selection
+#define ADDIDATA_OR 0
+#define ADDIDATA_AND 1
+
+//Digital Input Interrupt Status
+#define APCI1564_DIGITAL_IP_INTERRUPT_STATUS 12
+
+//Digital Output Interrupt Status
+#define APCI1564_DIGITAL_OP_INTERRUPT_STATUS 8
+
+//Digital Input Interrupt Enable Disable.
+#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4
+#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB
+
+//Digital Output Interrupt Enable Disable.
+#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
+#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE
+#define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2
+#define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD
+
+//ADDIDATA Enable Disable
+
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define ADDIDATA_TIMER 0
+#define ADDIDATA_COUNTER 1
+#define ADDIDATA_WATCHDOG 2
+#define APCI1564_DIGITAL_OP_WATCHDOG 0x28
+#define APCI1564_TIMER 0x48
+#define APCI1564_COUNTER1 0x0
+#define APCI1564_COUNTER2 0x20
+#define APCI1564_COUNTER3 0x40
+#define APCI1564_COUNTER4 0x60
+#define APCI1564_TCW_SYNC_ENABLEDISABLE 0
+#define APCI1564_TCW_RELOAD_VALUE 4
+#define APCI1564_TCW_TIMEBASE 8
+#define APCI1564_TCW_PROG 12
+#define APCI1564_TCW_TRIG_STATUS 16
+#define APCI1564_TCW_IRQ 20
+#define APCI1564_TCW_WARN_TIMEVAL 24
+#define APCI1564_TCW_WARN_TIMEBASE 28
+
+// Hardware Layer functions for Apci1564
+
+//DI
+// for di read
+INT i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//DO
+int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+INT i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// INTERRUPT
+static void v_APCI1564_Interrupt(int irq, void *d);
+
+// RESET
+INT i_APCI1564_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
new file mode 100644
index 00000000000..906d635da6b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
@@ -0,0 +1,780 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1648 | Compiler : gcc |
+ | Module name : TTL.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: S. Weber | Date : 25/05/2005 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-16XX TTL I/O module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ |25.05.2005| S.Weber | Creation |
+ | | | |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "hwdrv_apci16xx.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI16XX_InsnConfigInitTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task APCI16XX_TTL_INIT (using defaults) : |
+| Configure the TTL I/O operating mode from all ports |
+| You must calling this function be |
+| for you call any other function witch access of TTL. |
+| APCI16XX_TTL_INITDIRECTION(user inputs for direction) |
++----------------------------------------------------------------------------+
+| Input Parameters : b_InitType = (BYTE) data[0]; |
+| b_Port0Mode = (BYTE) data[1]; |
+| b_Port1Mode = (BYTE) data[2]; |
+| b_Port2Mode = (BYTE) data[3]; |
+| b_Port3Mode = (BYTE) data[4]; |
+| ........ |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :>0: No error |
+| -1: Port 0 mode selection is wrong |
+| -2: Port 1 mode selection is wrong |
+| -3: Port 2 mode selection is wrong |
+| -4: Port 3 mode selection is wrong |
+| -X: Port X-1 mode selection is wrong |
+| .... |
+| -100 : Config command error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Command = 0;
+ BYTE b_Cpt = 0;
+ BYTE b_NumberOfPort =
+ (BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /*******************/
+ /* Get the command */
+ /* **************** */
+
+ b_Command = (BYTE) data[0];
+
+ /********************/
+ /* Test the command */
+ /********************/
+
+ if ((b_Command == APCI16XX_TTL_INIT) ||
+ (b_Command == APCI16XX_TTL_INITDIRECTION) ||
+ (b_Command == APCI16XX_TTL_OUTPUTMEMORY)) {
+ /***************************************/
+ /* Test the initialisation buffer size */
+ /***************************************/
+
+ if ((b_Command == APCI16XX_TTL_INITDIRECTION)
+ && ((BYTE) (insn->n - 1) != b_NumberOfPort)) {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+
+ if ((b_Command == APCI16XX_TTL_OUTPUTMEMORY)
+ && ((BYTE) (insn->n) != 2)) {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+ } else {
+ /************************/
+ /* Config command error */
+ /************************/
+
+ printk("\nCommand selection error");
+ i_ReturnValue = -100;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+
+ /**************************************************************************/
+ /* Test if no error occur and APCI16XX_TTL_INITDIRECTION command selected */
+ /**************************************************************************/
+
+ if ((i_ReturnValue >= 0) && (b_Command == APCI16XX_TTL_INITDIRECTION)) {
+ memset(devpriv->ul_TTLPortConfiguration, 0,
+ sizeof(devpriv->ul_TTLPortConfiguration));
+
+ /*************************************/
+ /* Test the port direction selection */
+ /*************************************/
+
+ for (b_Cpt = 1;
+ (b_Cpt <= b_NumberOfPort) && (i_ReturnValue >= 0);
+ b_Cpt++) {
+ /**********************/
+ /* Test the direction */
+ /**********************/
+
+ if ((data[b_Cpt] != 0) && (data[b_Cpt] != 0xFF)) {
+ /************************/
+ /* Port direction error */
+ /************************/
+
+ printk("\nPort %d direction selection error",
+ (INT) b_Cpt);
+ i_ReturnValue = -(INT) b_Cpt;
+ }
+
+ /**************************/
+ /* Save the configuration */
+ /**************************/
+
+ devpriv->ul_TTLPortConfiguration[(b_Cpt - 1) / 4] =
+ devpriv->ul_TTLPortConfiguration[(b_Cpt -
+ 1) / 4] | (data[b_Cpt] << (8 * ((b_Cpt -
+ 1) % 4)));
+ }
+ }
+
+ /**************************/
+ /* Test if no error occur */
+ /**************************/
+
+ if (i_ReturnValue >= 0) {
+ /***********************************/
+ /* Test if TTL port initilaisation */
+ /***********************************/
+
+ if ((b_Command == APCI16XX_TTL_INIT)
+ || (b_Command == APCI16XX_TTL_INITDIRECTION)) {
+ /******************************/
+ /* Set all port configuration */
+ /******************************/
+
+ for (b_Cpt = 0; b_Cpt <= b_NumberOfPort; b_Cpt++) {
+ if ((b_Cpt % 4) == 0) {
+ /*************************/
+ /* Set the configuration */
+ /*************************/
+
+ outl(devpriv->
+ ul_TTLPortConfiguration[b_Cpt /
+ 4],
+ devpriv->iobase + 32 + b_Cpt);
+ }
+ }
+ }
+ }
+
+ /************************************************/
+ /* Test if output memory initialisation command */
+ /************************************************/
+
+ if (b_Command == APCI16XX_TTL_OUTPUTMEMORY) {
+ if (data[1]) {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+ } else {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+ }
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| INPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI16XX_InsnBitsReadTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read the status from selected TTL digital input |
+| (b_InputChannel) |
++----------------------------------------------------------------------------+
+| Task : Read the status from digital input port |
+| (b_SelectedPort) |
++----------------------------------------------------------------------------+
+| Input Parameters : |
+| APCI16XX_TTL_READCHANNEL |
+| b_SelectedPort= CR_RANGE(insn->chanspec); |
+| b_InputChannel= CR_CHAN(insn->chanspec); |
+| b_ReadType = (BYTE) data[0]; |
+| |
+| APCI16XX_TTL_READPORT |
+| b_SelectedPort= CR_RANGE(insn->chanspec); |
+| b_ReadType = (BYTE) data[0]; |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] 0 : Channle is not active |
+| 1 : Channle is active |
++----------------------------------------------------------------------------+
+| Return Value : >0 : No error |
+| -100 : Config command error |
+| -101 : Data size error |
+| -102 : The selected TTL input port is wrong |
+| -103 : The selected TTL digital input is wrong |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Command = 0;
+ BYTE b_NumberOfPort =
+ (BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
+ BYTE b_SelectedPort = CR_RANGE(insn->chanspec);
+ BYTE b_InputChannel = CR_CHAN(insn->chanspec);
+ BYTE *pb_Status;
+ DWORD dw_Status;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /*******************/
+ /* Get the command */
+ /* **************** */
+
+ b_Command = (BYTE) data[0];
+
+ /********************/
+ /* Test the command */
+ /********************/
+
+ if ((b_Command == APCI16XX_TTL_READCHANNEL)
+ || (b_Command == APCI16XX_TTL_READPORT)) {
+ /**************************/
+ /* Test the selected port */
+ /**************************/
+
+ if (b_SelectedPort < b_NumberOfPort) {
+ /**********************/
+ /* Test if input port */
+ /**********************/
+
+ if (((devpriv->ul_TTLPortConfiguration
+ [b_SelectedPort /
+ 4] >> (8 *
+ (b_SelectedPort
+ %
+ 4))) &
+ 0xFF) == 0) {
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if ((b_Command ==
+ APCI16XX_TTL_READCHANNEL)
+ && (b_InputChannel > 7)) {
+ /*******************************************/
+ /* The selected TTL digital input is wrong */
+ /*******************************************/
+
+ printk("\nChannel selection error");
+ i_ReturnValue = -103;
+ }
+ } else {
+ /****************************************/
+ /* The selected TTL input port is wrong */
+ /****************************************/
+
+ printk("\nPort selection error");
+ i_ReturnValue = -102;
+ }
+ } else {
+ /****************************************/
+ /* The selected TTL input port is wrong */
+ /****************************************/
+
+ printk("\nPort selection error");
+ i_ReturnValue = -102;
+ }
+ } else {
+ /************************/
+ /* Config command error */
+ /************************/
+
+ printk("\nCommand selection error");
+ i_ReturnValue = -100;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+
+ /**************************/
+ /* Test if no error occur */
+ /**************************/
+
+ if (i_ReturnValue >= 0) {
+ pb_Status = (PBYTE) & data[0];
+
+ /*******************************/
+ /* Get the digital inpu status */
+ /*******************************/
+
+ dw_Status =
+ inl(devpriv->iobase + 8 + ((b_SelectedPort / 4) * 4));
+ dw_Status = (dw_Status >> (8 * (b_SelectedPort % 4))) & 0xFF;
+
+ /***********************/
+ /* Save the port value */
+ /***********************/
+
+ *pb_Status = (BYTE) dw_Status;
+
+ /***************************************/
+ /* Test if read channel status command */
+ /***************************************/
+
+ if (b_Command == APCI16XX_TTL_READCHANNEL) {
+ *pb_Status = (*pb_Status >> b_InputChannel) & 1;
+ }
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI16XX_InsnReadTTLIOAllPortValue |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read the status from all digital input ports |
++----------------------------------------------------------------------------+
+| Input Parameters : - |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Port 0 to 3 data |
+| data[1] : Port 4 to 7 data |
+| .... |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -100 : Read command error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_Command = (BYTE) CR_AREF(insn->chanspec);
+ INT i_ReturnValue = insn->n;
+ BYTE b_Cpt = 0;
+ BYTE b_NumberOfPort = 0;
+ unsigned int *pls_ReadData = data;
+
+ /********************/
+ /* Test the command */
+ /********************/
+
+ if ((b_Command == APCI16XX_TTL_READ_ALL_INPUTS)
+ || (b_Command == APCI16XX_TTL_READ_ALL_OUTPUTS)) {
+ /**********************************/
+ /* Get the number of 32-Bit ports */
+ /**********************************/
+
+ b_NumberOfPort =
+ (BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 32);
+ if ((b_NumberOfPort * 32) <
+ devpriv->ps_BoardInfo->i_NbrTTLChannel) {
+ b_NumberOfPort = b_NumberOfPort + 1;
+ }
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= b_NumberOfPort) {
+ if (b_Command == APCI16XX_TTL_READ_ALL_INPUTS) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ for (b_Cpt = 0; b_Cpt < b_NumberOfPort; b_Cpt++) {
+ /************************/
+ /* Read the 32-Bit port */
+ /************************/
+
+ pls_ReadData[b_Cpt] =
+ inl(devpriv->iobase + 8 +
+ (b_Cpt * 4));
+
+ /**************************************/
+ /* Mask all channels used als outputs */
+ /**************************************/
+
+ pls_ReadData[b_Cpt] =
+ pls_ReadData[b_Cpt] &
+ (~devpriv->
+ ul_TTLPortConfiguration[b_Cpt]);
+ }
+ } else {
+ /****************************/
+ /* Read all digital outputs */
+ /****************************/
+
+ for (b_Cpt = 0; b_Cpt < b_NumberOfPort; b_Cpt++) {
+ /************************/
+ /* Read the 32-Bit port */
+ /************************/
+
+ pls_ReadData[b_Cpt] =
+ inl(devpriv->iobase + 20 +
+ (b_Cpt * 4));
+
+ /**************************************/
+ /* Mask all channels used als outputs */
+ /**************************************/
+
+ pls_ReadData[b_Cpt] =
+ pls_ReadData[b_Cpt] & devpriv->
+ ul_TTLPortConfiguration[b_Cpt];
+ }
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+ } else {
+ /*****************/
+ /* Command error */
+ /*****************/
+
+ printk("\nCommand selection error");
+ i_ReturnValue = -100;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| OUTPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI16XX_InsnBitsWriteTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Set the state from selected TTL digital output |
+| (b_OutputChannel) |
++----------------------------------------------------------------------------+
+| Task : Set the state from digital output port |
+| (b_SelectedPort) |
++----------------------------------------------------------------------------+
+| Input Parameters : |
+| APCI16XX_TTL_WRITECHANNEL_ON | APCI16XX_TTL_WRITECHANNEL_OFF |
+| b_SelectedPort = CR_RANGE(insn->chanspec); |
+| b_OutputChannel= CR_CHAN(insn->chanspec); |
+| b_Command = (BYTE) data[0]; |
+| |
+| APCI16XX_TTL_WRITEPORT_ON | APCI16XX_TTL_WRITEPORT_OFF |
+| b_SelectedPort = CR_RANGE(insn->chanspec); |
+| b_Command = (BYTE) data[0]; |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : TTL output port 0 to 3 data |
+| data[1] : TTL output port 4 to 7 data |
+| .... |
++----------------------------------------------------------------------------+
+| Return Value : >0 : No error |
+| -100 : Command error |
+| -101 : Data size error |
+| -102 : The selected TTL output port is wrong |
+| -103 : The selected TTL digital output is wrong |
+| -104 : Output memory disabled |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Command = 0;
+ BYTE b_NumberOfPort =
+ (BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
+ BYTE b_SelectedPort = CR_RANGE(insn->chanspec);
+ BYTE b_OutputChannel = CR_CHAN(insn->chanspec);
+ DWORD dw_Status = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /*******************/
+ /* Get the command */
+ /* **************** */
+
+ b_Command = (BYTE) data[0];
+
+ /********************/
+ /* Test the command */
+ /********************/
+
+ if ((b_Command == APCI16XX_TTL_WRITECHANNEL_ON) ||
+ (b_Command == APCI16XX_TTL_WRITEPORT_ON) ||
+ (b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) ||
+ (b_Command == APCI16XX_TTL_WRITEPORT_OFF)) {
+ /**************************/
+ /* Test the selected port */
+ /**************************/
+
+ if (b_SelectedPort < b_NumberOfPort) {
+ /***********************/
+ /* Test if output port */
+ /***********************/
+
+ if (((devpriv->ul_TTLPortConfiguration
+ [b_SelectedPort /
+ 4] >> (8 *
+ (b_SelectedPort
+ %
+ 4))) &
+ 0xFF) == 0xFF) {
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if (((b_Command == APCI16XX_TTL_WRITECHANNEL_ON) || (b_Command == APCI16XX_TTL_WRITECHANNEL_OFF)) && (b_OutputChannel > 7)) {
+ /********************************************/
+ /* The selected TTL digital output is wrong */
+ /********************************************/
+
+ printk("\nChannel selection error");
+ i_ReturnValue = -103;
+ }
+
+ if (((b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) || (b_Command == APCI16XX_TTL_WRITEPORT_OFF)) && (devpriv->b_OutputMemoryStatus == ADDIDATA_DISABLE)) {
+ /********************************************/
+ /* The selected TTL digital output is wrong */
+ /********************************************/
+
+ printk("\nOutput memory disabled");
+ i_ReturnValue = -104;
+ }
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (((b_Command == APCI16XX_TTL_WRITEPORT_ON) || (b_Command == APCI16XX_TTL_WRITEPORT_OFF)) && (insn->n < 2)) {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+ } else {
+ /*****************************************/
+ /* The selected TTL output port is wrong */
+ /*****************************************/
+
+ printk("\nPort selection error %lX",
+ (unsigned long)devpriv->
+ ul_TTLPortConfiguration[0]);
+ i_ReturnValue = -102;
+ }
+ } else {
+ /****************************************/
+ /* The selected TTL output port is wrong */
+ /****************************************/
+
+ printk("\nPort selection error %d %d",
+ b_SelectedPort, b_NumberOfPort);
+ i_ReturnValue = -102;
+ }
+ } else {
+ /************************/
+ /* Config command error */
+ /************************/
+
+ printk("\nCommand selection error");
+ i_ReturnValue = -100;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+
+ /**************************/
+ /* Test if no error occur */
+ /**************************/
+
+ if (i_ReturnValue >= 0) {
+ /********************************/
+ /* Get the digital output state */
+ /********************************/
+
+ dw_Status =
+ inl(devpriv->iobase + 20 + ((b_SelectedPort / 4) * 4));
+
+ /**********************************/
+ /* Test if output memory not used */
+ /**********************************/
+
+ if (devpriv->b_OutputMemoryStatus == ADDIDATA_DISABLE) {
+ /*********************************/
+ /* Clear the selected port value */
+ /*********************************/
+
+ dw_Status =
+ dw_Status & (0xFFFFFFFFUL -
+ (0xFFUL << (8 * (b_SelectedPort % 4))));
+ }
+
+ /******************************/
+ /* Test if setting channel ON */
+ /******************************/
+
+ if (b_Command == APCI16XX_TTL_WRITECHANNEL_ON) {
+ dw_Status =
+ dw_Status | (1UL << ((8 * (b_SelectedPort %
+ 4)) + b_OutputChannel));
+ }
+
+ /***************************/
+ /* Test if setting port ON */
+ /***************************/
+
+ if (b_Command == APCI16XX_TTL_WRITEPORT_ON) {
+ dw_Status =
+ dw_Status | ((data[1] & 0xFF) << (8 *
+ (b_SelectedPort % 4)));
+ }
+
+ /*******************************/
+ /* Test if setting channel OFF */
+ /*******************************/
+
+ if (b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) {
+ dw_Status =
+ dw_Status & (0xFFFFFFFFUL -
+ (1UL << ((8 * (b_SelectedPort % 4)) +
+ b_OutputChannel)));
+ }
+
+ /****************************/
+ /* Test if setting port OFF */
+ /****************************/
+
+ if (b_Command == APCI16XX_TTL_WRITEPORT_OFF) {
+ dw_Status =
+ dw_Status & (0xFFFFFFFFUL -
+ ((data[1] & 0xFF) << (8 * (b_SelectedPort %
+ 4))));
+ }
+
+ outl(dw_Status,
+ devpriv->iobase + 20 + ((b_SelectedPort / 4) * 4));
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : - |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_Reset(struct comedi_device * dev)
+{
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h
new file mode 100644
index 00000000000..5bf91e13a03
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+#ifndef COMEDI_SUBD_TTLIO
+#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
+#endif
+
+#ifndef ADDIDATA_ENABLE
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+#endif
+
+#define APCI16XX_TTL_INIT 0
+#define APCI16XX_TTL_INITDIRECTION 1
+#define APCI16XX_TTL_OUTPUTMEMORY 2
+
+#define APCI16XX_TTL_READCHANNEL 0
+#define APCI16XX_TTL_READPORT 1
+
+#define APCI16XX_TTL_WRITECHANNEL_ON 0
+#define APCI16XX_TTL_WRITECHANNEL_OFF 1
+#define APCI16XX_TTL_WRITEPORT_ON 2
+#define APCI16XX_TTL_WRITEPORT_OFF 3
+
+#define APCI16XX_TTL_READ_ALL_INPUTS 0
+#define APCI16XX_TTL_READ_ALL_OUTPUTS 1
+
+#ifdef __KERNEL__
+
+static const struct comedi_lrange range_apci16xx_ttl = { 12,
+ {BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1)}
+};
+
+/*
++----------------------------------------------------------------------------+
+| TTL INISIALISATION FUNCTION |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+
+/*
++----------------------------------------------------------------------------+
+| TTL INPUT FUNCTION |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+
+int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*
++----------------------------------------------------------------------------+
+| TTL OUTPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+
+int i_APCI16XX_Reset(struct comedi_device *dev);
+#endif
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
new file mode 100644
index 00000000000..31f55da39ea
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
@@ -0,0 +1,460 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-2016 | Compiler : GCC |
+ | Module name : hwdrv_apci2016.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-2016 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci2016.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_ConfigDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 1 Digital Memory On |
+| 0 Digital Memory Off |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ } // if ((data[0]!=0) && (data[0]!=1))
+ if (data[0]) {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+ } // if (data[0]
+ else {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+ } // else if (data[0]
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To Write |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_NoOfChannel;
+ UINT ui_Temp, ui_Temp1;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) {
+ comedi_error(dev,
+ "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
+ return -EINVAL;
+ } // if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp = inw(devpriv->iobase + APCI2016_DIGITAL_OP);
+ } // if (devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } // else if (devpriv->b_OutputMemoryStatus )
+ if ((data[1] != 0) && (data[1] != 1)) {
+ comedi_error(dev,
+ "Invalid Data[1] value !!!, Data[1] should be 0 or 1\n");
+ return -EINVAL;
+ } // if ((data[1]!=0) && (data[1]!=1))
+
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP);
+ } // if (data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+ case 4:
+ data[0] =
+ (data[0] << (4 *
+ data[2])) | ui_Temp;
+ break;
+ case 8:
+ data[0] =
+ (data[0] << (8 *
+ data[2])) | ui_Temp;
+ break;
+ case 15:
+ data[0] = data[0] | ui_Temp;
+ break;
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //switch(ui_NoOfChannels)
+ outw(data[0],
+ devpriv->iobase + APCI2016_DIGITAL_OP);
+ } // if (data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } // else if (data[1]==1)
+ } // else if (data[1]==0)
+ } // if (data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
+ data[0] = data[0] & ui_Temp;
+ outw(data[0],
+ devpriv->iobase + APCI2016_DIGITAL_OP);
+ } // if (data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xffff) & ui_Temp;
+ break;
+ case 4:
+ data[0] = ~data[0] & 0xf;
+ ui_Temp1 = 15;
+ ui_Temp1 =
+ ui_Temp1 << 4 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (4 *
+ data
+ [2])) ^
+ 0xffff) & ui_Temp;
+ break;
+ case 8:
+ data[0] = ~data[0] & 0xff;
+ ui_Temp1 = 255;
+ ui_Temp1 =
+ ui_Temp1 << 8 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (8 *
+ data
+ [2])) ^
+ 0xffff) & ui_Temp;
+ break;
+ case 15:
+ break;
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //switch(ui_NoOfChannels)
+ outw(data[0],
+ devpriv->iobase +
+ APCI2016_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_BitsDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_BitsDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) {
+ comedi_error(dev,
+ "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
+ return -EINVAL;
+ } // if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Invalid Data[0] value !!!, Data[0] should be 0 or 1\n");
+ return -EINVAL;
+ } // if ((data[0]!=0) && (data[0]!=1))
+ ui_Temp = data[0];
+ *data = inw(devpriv->iobase + APCI2016_DIGITAL_OP_RW);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } // if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ switch (ui_NoOfChannel) {
+ case 2:
+ *data = (*data >> (2 * data[1])) & 3;
+ break;
+
+ case 4:
+ *data = (*data >> (4 * data[1])) & 15;
+ break;
+
+ case 8:
+ *data = (*data >> (8 * data[1])) & 255;
+ break;
+
+ case 15:
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //switch(ui_NoOfChannel)
+ } // if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } // else if (ui_Temp==1)
+ } // if (ui_Temp==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_ConfigWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure |
+| struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ if (data[0] == 0) {
+ //Disable the watchdog
+ outw(0x0,
+ devpriv->i_IobaseAddon +
+ APCI2016_WATCHDOG_ENABLEDISABLE);
+ //Loading the Reload value
+ outw(data[1],
+ devpriv->i_IobaseAddon +
+ APCI2016_WATCHDOG_RELOAD_VALUE);
+ data[1] = data[1] >> 16;
+ outw(data[1],
+ devpriv->i_IobaseAddon +
+ APCI2016_WATCHDOG_RELOAD_VALUE + 2);
+ } else {
+ printk("\nThe input parameters are wrong\n");
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_StartStopWriteWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Start / Stop The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure |
+| struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ switch (data[0]) {
+ case 0: //stop the watchdog
+ outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE); //disable the watchdog
+ break;
+ case 1: //start the watchdog
+ outw(0x0001,
+ devpriv->i_IobaseAddon +
+ APCI2016_WATCHDOG_ENABLEDISABLE);
+ break;
+ case 2: //Software trigger
+ outw(0x0201,
+ devpriv->i_IobaseAddon +
+ APCI2016_WATCHDOG_ENABLEDISABLE);
+ break;
+ default:
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } // switch(data[0])
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_ReadWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure |
+| struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2016_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ udelay(5);
+ data[0] = inw(devpriv->i_IobaseAddon + APCI2016_WATCHDOG_STATUS) & 0x1;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_Reset(struct comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2016_Reset(struct comedi_device * dev)
+{
+ outw(0x0, devpriv->iobase + APCI2016_DIGITAL_OP); // Resets the digital output channels
+ outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE);
+ outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE);
+ outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE + 2);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h
new file mode 100644
index 00000000000..9261aacd25f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+/********* Definitions for APCI-2016 card *****/
+
+#define APCI2016_BOARD_VENDOR_ID 0x15B8
+#define APCI2016_ADDRESS_RANGE 8
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI2016_DIGITAL_OP 0x04
+#define APCI2016_DIGITAL_OP_RW 4
+
+//ADDIDATA Enable Disable
+
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define ADDIDATA_WATCHDOG 2
+#define APCI2016_DIGITAL_OP_WATCHDOG 0
+#define APCI2016_WATCHDOG_ENABLEDISABLE 12
+#define APCI2016_WATCHDOG_RELOAD_VALUE 4
+#define APCI2016_WATCHDOG_STATUS 16
+
+// Hardware Layer functions for Apci2016
+
+//DO
+int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+
+int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+int i_APCI2016_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// Interrupt functions.....
+
+// void v_APCI2016_Interrupt(int irq, void *d) ;
+
+ //void v_APCI2016_Interrupt(int irq, void *d);
+// RESET
+INT i_APCI2016_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
new file mode 100644
index 00000000000..1347bc388f3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
@@ -0,0 +1,579 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-2032 | Compiler : GCC |
+ | Module name : hwdrv_apci2032.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-2032 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "hwdrv_apci2032.h"
+UINT ui_InterruptData, ui_Type;
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_ConfigDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[1] : 1 Enable VCC Interrupt |
+| 0 Disable VCC Interrupt |
+| data[2] : 1 Enable CC Interrupt |
+| 0 Disable CC Interrupt |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2032_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command = 0;
+ devpriv->tsk_Current = current;
+
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ } //if ( (data[0]!=0) && (data[0]!=1) )
+ if (data[0]) {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+ } // if (data[0])
+ else {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+ } //else if (data[0])
+
+ if (data[1] == ADDIDATA_ENABLE) {
+ ul_Command = ul_Command | 0x1;
+ } //if (data[1] == ADDIDATA_ENABLE)
+ else {
+ ul_Command = ul_Command & 0xFFFFFFFE;
+ } //elseif (data[1] == ADDIDATA_ENABLE)
+ if (data[2] == ADDIDATA_ENABLE) {
+ ul_Command = ul_Command | 0x2;
+ } //if (data[2] == ADDIDATA_ENABLE)
+ else {
+ ul_Command = ul_Command & 0xFFFFFFFD;
+ } //elseif (data[2] == ADDIDATA_ENABLE)
+ outl(ul_Command, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
+ ui_InterruptData = inl(devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To Write |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2032_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp, ui_Temp1;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp = inl(devpriv->iobase + APCI2032_DIGITAL_OP);
+
+ } //if(devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } //if(devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 4:
+ data[0] =
+ (data[0] << (4 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 8:
+ data[0] =
+ (data[0] << (8 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 16:
+ data[0] =
+ (data[0] << (16 *
+ data[2])) | ui_Temp;
+ break;
+ case 31:
+ data[0] = data[0] | ui_Temp;
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outl(data[0],
+ devpriv->iobase + APCI2032_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ (data[0] << ui_NoOfChannel) ^
+ 0xffffffff;
+ data[0] = data[0] & ui_Temp;
+ outl(data[0],
+ devpriv->iobase + APCI2032_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 4:
+ data[0] = ~data[0] & 0xf;
+ ui_Temp1 = 15;
+ ui_Temp1 =
+ ui_Temp1 << 4 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (4 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 8:
+ data[0] = ~data[0] & 0xff;
+ ui_Temp1 = 255;
+ ui_Temp1 =
+ ui_Temp1 << 8 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (8 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 16:
+ data[0] = ~data[0] & 0xffff;
+ ui_Temp1 = 65535;
+ ui_Temp1 =
+ ui_Temp1 << 16 *
+ data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (16 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 31:
+ break;
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outl(data[0],
+ devpriv->iobase +
+ APCI2032_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ return (insn->n);;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_ReadDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2032_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->iobase + APCI2032_DIGITAL_OP_RW);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } //if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ *data = (*data >> (2 * data[1])) & 3;
+ break;
+
+ case 4:
+ *data = (*data >> (4 * data[1])) & 15;
+ break;
+
+ case 8:
+ *data = (*data >> (8 * data[1])) & 255;
+ break;
+
+ case 16:
+ *data = (*data >> (16 * data[1])) & 65535;
+ break;
+
+ case 31:
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+ } //if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } //elseif (ui_Temp==1)
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI2032_ConfigWatchdog(comedi_device
+ *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI2032_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0] == 0) {
+ //Disable the watchdog
+ outl(0x0,
+ devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+ APCI2032_TCW_PROG);
+ //Loading the Reload value
+ outl(data[1],
+ devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+ APCI2032_TCW_RELOAD_VALUE);
+ } else {
+ printk("\nThe input parameters are wrong\n");
+ return -EINVAL;
+ }
+
+ return insn->n;
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI2032_StartStopWriteWatchdog |
+ | (struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data); |
+ +----------------------------------------------------------------------------+
+ | Task : Start / Stop The Watchdog |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+ | unsigned int *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+ */
+
+int i_APCI2032_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case 0: //stop the watchdog
+ outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); //disable the watchdog
+ break;
+ case 1: //start the watchdog
+ outl(0x0001,
+ devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+ APCI2032_TCW_PROG);
+ break;
+ case 2: //Software trigger
+ outl(0x0201,
+ devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+ APCI2032_TCW_PROG);
+ break;
+ default:
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_ReadWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2032_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ data[0] =
+ inl(devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+ APCI2032_TCW_TRIG_STATUS) & 0x1;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : void v_APCI2032_Interrupt |
+| (int irq , void *d) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+void v_APCI2032_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ unsigned int ui_DO;
+
+ ui_DO = inl(devpriv->iobase + APCI2032_DIGITAL_OP_IRQ) & 0x1; //Check if VCC OR CC interrupt has occured.
+
+ if (ui_DO == 0) {
+ printk("\nInterrupt from unKnown source\n");
+ } // if(ui_DO==0)
+ if (ui_DO) {
+ // Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt.
+ ui_Type =
+ inl(devpriv->iobase +
+ APCI2032_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
+ outl(0x0,
+ devpriv->iobase + APCI2032_DIGITAL_OP +
+ APCI2032_DIGITAL_OP_INTERRUPT);
+ if (ui_Type == 1) {
+ //Sends signal to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+ } // if (ui_Type==1)
+ else {
+ if (ui_Type == 2) {
+ // Sends signal to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+ } //if (ui_Type==2)
+ } //else if (ui_Type==1)
+ } //if(ui_DO)
+
+ return;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_ReadInterruptStatus |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task :Reads the interrupt status register |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2032_ReadInterruptStatus(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ *data = ui_Type;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_Reset(struct comedi_device *dev) |
+| |
++----------------------------------------------------------------------------+
+| Task :Resets the registers of the card |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2032_Reset(struct comedi_device * dev)
+{
+ devpriv->b_DigitalOutputRegister = 0;
+ ui_Type = 0;
+ outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP); //Resets the output channels
+ outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT); //Disables the interrupt.
+ outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); //disable the watchdog
+ outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_RELOAD_VALUE); //reload=0
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h
new file mode 100644
index 00000000000..55002e0288b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+/********* Definitions for APCI-2032 card *****/
+
+// Card Specific information
+#define APCI2032_BOARD_VENDOR_ID 0x15B8
+#define APCI2032_ADDRESS_RANGE 63
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI2032_DIGITAL_OP 0
+#define APCI2032_DIGITAL_OP_RW 0
+#define APCI2032_DIGITAL_OP_INTERRUPT 4
+#define APCI2032_DIGITAL_OP_IRQ 12
+
+//Digital Output Interrupt Status
+#define APCI2032_DIGITAL_OP_INTERRUPT_STATUS 8
+
+//Digital Output Interrupt Enable Disable.
+#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
+#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE
+#define APCI2032_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2
+#define APCI2032_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD
+
+//ADDIDATA Enable Disable
+
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define ADDIDATA_WATCHDOG 2
+#define APCI2032_DIGITAL_OP_WATCHDOG 16
+#define APCI2032_TCW_RELOAD_VALUE 4
+#define APCI2032_TCW_TIMEBASE 8
+#define APCI2032_TCW_PROG 12
+#define APCI2032_TCW_TRIG_STATUS 16
+#define APCI2032_TCW_IRQ 20
+
+// Hardware Layer functions for Apci2032
+
+//DO
+int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+INT i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// Interrupt functions.....
+
+void v_APCI2032_Interrupt(int irq, void *d);
+
+//Reset functions
+int i_APCI2032_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
new file mode 100644
index 00000000000..947e18ef3ab
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
@@ -0,0 +1,549 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-2200 | Compiler : GCC |
+ | Module name : hwdrv_apci2200.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-2200 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci2200.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_Read1DigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI2200_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_TmpValue = 0;
+ UINT ui_Channel;
+ ui_Channel = CR_CHAN(insn->chanspec);
+ if (ui_Channel >= 0 && ui_Channel <= 7) {
+ ui_TmpValue = (UINT) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
+ *data = (ui_TmpValue >> ui_Channel) & 0x1;
+ } //if(ui_Channel >= 0 && ui_Channel <=7)
+ else {
+ printk("\nThe specified channel does not exist\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //else if(ui_Channel >= 0 && ui_Channel <=7)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ReadMoreDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ui_PortValue = data[0];
+ UINT ui_Mask = 0;
+ UINT ui_NoOfChannels;
+
+ ui_NoOfChannels = CR_CHAN(insn->chanspec);
+
+ *data = (UINT) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
+ switch (ui_NoOfChannels) {
+ case 2:
+ ui_Mask = 3;
+ *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+ break;
+ case 4:
+ ui_Mask = 15;
+ *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+ break;
+ case 7:
+ break;
+
+ default:
+ printk("\nWrong parameters\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } //switch(ui_NoOfChannels)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ConfigDigitalOutput (struct comedi_device *dev,
+ struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| data[0] :1:Memory on |
+| 0:Memory off |
+| |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2200_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ devpriv->b_OutputMemoryStatus = data[0];
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp, ui_Temp1;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
+
+ } //if(devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } //if(devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outw(data[0], devpriv->iobase + APCI2200_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 4:
+ data[0] =
+ (data[0] << (4 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 8:
+ data[0] =
+ (data[0] << (8 *
+ data[2])) | ui_Temp;
+ break;
+ case 15:
+ data[0] = data[0] | ui_Temp;
+ break;
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outw(data[0],
+ devpriv->iobase + APCI2200_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
+ data[0] = data[0] & ui_Temp;
+ outw(data[0],
+ devpriv->iobase + APCI2200_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xffff) & ui_Temp;
+ break;
+
+ case 4:
+ data[0] = ~data[0] & 0xf;
+ ui_Temp1 = 15;
+ ui_Temp1 =
+ ui_Temp1 << 4 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (4 *
+ data
+ [2])) ^
+ 0xffff) & ui_Temp;
+ break;
+
+ case 8:
+ data[0] = ~data[0] & 0xff;
+ ui_Temp1 = 255;
+ ui_Temp1 =
+ ui_Temp1 << 8 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (8 *
+ data
+ [2])) ^
+ 0xffff) & ui_Temp;
+ break;
+ case 15:
+ break;
+
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outw(data[0],
+ devpriv->iobase +
+ APCI2200_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ return (insn->n);;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ReadDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ui_Temp;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ ui_Temp = data[0];
+ *data = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } //if(ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ *data = (*data >> (2 * data[1])) & 3;
+ break;
+
+ case 4:
+ *data = (*data >> (4 * data[1])) & 15;
+ break;
+
+ case 8:
+ *data = (*data >> (8 * data[1])) & 255;
+ break;
+
+ case 15:
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+ } //if(ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } //elseif(ui_Temp==1)
+ } //elseif(ui_Temp==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ConfigWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2200_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0] == 0) {
+ //Disable the watchdog
+ outw(0x0,
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_ENABLEDISABLE);
+ //Loading the Reload value
+ outw(data[1],
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_RELOAD_VALUE);
+ data[1] = data[1] >> 16;
+ outw(data[1],
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_RELOAD_VALUE + 2);
+ } //if(data[0]==0)
+ else {
+ printk("\nThe input parameters are wrong\n");
+ return -EINVAL;
+ } //elseif(data[0]==0)
+
+ return insn->n;
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI2200_StartStopWriteWatchdog |
+ | (struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data); |
+ +----------------------------------------------------------------------------+
+ | Task : Start / Stop The Watchdog |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+ | unsigned int *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+ */
+
+int i_APCI2200_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case 0: //stop the watchdog
+ outw(0x0, devpriv->iobase + APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE); //disable the watchdog
+ break;
+ case 1: //start the watchdog
+ outw(0x0001,
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_ENABLEDISABLE);
+ break;
+ case 2: //Software trigger
+ outw(0x0201,
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_ENABLEDISABLE);
+ break;
+ default:
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } // switch(data[0])
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ReadWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2200_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] =
+ inw(devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_STATUS) & 0x1;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_Reset(struct comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_Reset(struct comedi_device * dev)
+{
+ outw(0x0, devpriv->iobase + APCI2200_DIGITAL_OP); //RESETS THE DIGITAL OUTPUTS
+ outw(0x0,
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_ENABLEDISABLE);
+ outw(0x0,
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_RELOAD_VALUE);
+ outw(0x0,
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_RELOAD_VALUE + 2);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h
new file mode 100644
index 00000000000..0a115b4c44c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+/********* Definitions for APCI-2200 card *****/
+
+// Card Specific information
+#define APCI2200_BOARD_VENDOR_ID 0x15b8
+#define APCI2200_ADDRESS_RANGE 64
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI2200_DIGITAL_OP 4
+#define APCI2200_DIGITAL_IP 0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define APCI2200_WATCHDOG 0x08
+#define APCI2200_WATCHDOG_ENABLEDISABLE 12
+#define APCI2200_WATCHDOG_RELOAD_VALUE 4
+#define APCI2200_WATCHDOG_STATUS 16
+
+// Hardware Layer functions for Apci2200
+
+//Digital Input
+INT i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//Digital Output
+int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//reset
+INT i_APCI2200_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
new file mode 100644
index 00000000000..68eb8dfd513
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
@@ -0,0 +1,2697 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : APCI-3120 | Compiler : GCC |
+ | Module name : hwdrv_apci3120.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description :APCI3120 Module. Hardware abstraction Layer for APCI3120|
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+#include "hwdrv_apci3120.h"
+static UINT ui_Temp = 0;
+
+// FUNCTION DEFINITIONS
+
+/*
++----------------------------------------------------------------------------+
+| ANALOG INPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev,|
+| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Calls card specific function |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnConfigAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT i;
+
+ if ((data[0] != APCI3120_EOC_MODE) && (data[0] != APCI3120_EOS_MODE))
+ return -1;
+
+ // Check for Conversion time to be added ??
+ devpriv->ui_EocEosConversionTime = data[2];
+
+ if (data[0] == APCI3120_EOS_MODE) {
+
+ //Test the number of the channel
+ for (i = 0; i < data[3]; i++) {
+
+ if (CR_CHAN(data[4 + i]) >= this_board->i_NbrAiChannel) {
+ printk("bad channel list\n");
+ return -2;
+ }
+ }
+
+ devpriv->b_InterruptMode = APCI3120_EOS_MODE;
+
+ if (data[1]) {
+ devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
+ } else
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ // Copy channel list and Range List to devpriv
+
+ devpriv->ui_AiNbrofChannels = data[3];
+ for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) {
+ devpriv->ui_AiChannelList[i] = data[4 + i];
+ }
+
+ } else // EOC
+ {
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+ if (data[1]) {
+ devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
+ } else {
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ }
+ }
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, |
+| struct comedi_subdevice *s,struct comedi_insn *insn, unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : card specific function |
+| Reads analog input in synchronous mode |
+| EOC and EOS is selected as per configured |
+| if no conversion time is set uses default conversion |
+| time 10 microsec. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnReadAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ USHORT us_ConvertTiming, us_TmpValue, i;
+ BYTE b_Tmp;
+
+ // fix convertion time to 10 us
+ if (!devpriv->ui_EocEosConversionTime) {
+ printk("No timer0 Value using 10 us\n");
+ us_ConvertTiming = 10;
+ } else
+ us_ConvertTiming = (USHORT) (devpriv->ui_EocEosConversionTime / 1000); // nano to useconds
+
+ // this_board->i_hwdrv_InsnReadAnalogInput(dev,us_ConvertTiming,insn->n,&insn->chanspec,data,insn->unused[0]);
+
+ // Clear software registers
+ devpriv->b_TimerSelectMode = 0;
+ devpriv->b_ModeSelectRegister = 0;
+ devpriv->us_OutputRegister = 0;
+// devpriv->b_DigitalOutputRegister=0;
+
+ if (insn->unused[0] == 222) // second insn read
+ {
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ui_AiReadData[i];
+ }
+
+ } else {
+ devpriv->tsk_Current = current; // Save the current process task structure
+ //Testing if board have the new Quartz and calculate the time value
+ //to set in the timer
+
+ us_TmpValue =
+ (USHORT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+ //EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001
+ if ((us_TmpValue & 0x00B0) == 0x00B0
+ || !strcmp(this_board->pc_DriverName, "apci3001")) {
+ us_ConvertTiming = (us_ConvertTiming * 2) - 2;
+ } else {
+ us_ConvertTiming =
+ ((us_ConvertTiming * 12926) / 10000) - 1;
+ }
+
+ us_TmpValue = (USHORT) devpriv->b_InterruptMode;
+
+ switch (us_TmpValue) {
+
+ case APCI3120_EOC_MODE:
+
+ // Testing the interrupt flag and set the EOC bit
+ // Clears the FIFO
+ inw(devpriv->iobase + APCI3120_RESET_FIFO);
+
+ // Initialize the sequence array
+
+ //if (!i_APCI3120_SetupChannelList(dev,s,1,chanlist,0)) return -EINVAL;
+
+ if (!i_APCI3120_SetupChannelList(dev, s, 1,
+ &insn->chanspec, 0))
+ return -EINVAL;
+
+ //Initialize Timer 0 mode 4
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0xFC) |
+ APCI3120_TIMER_0_MODE_4;
+ outb(devpriv->b_TimerSelectMode,
+ devpriv->iobase + APCI3120_TIMER_CRT1);
+
+ // Reset the scan bit and Disables the EOS, DMA, EOC interrupt
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_SCAN;
+
+ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) {
+
+ //Disables the EOS,DMA and enables the EOC interrupt
+ devpriv->b_ModeSelectRegister =
+ (devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_EOS_INT) |
+ APCI3120_ENABLE_EOC_INT;
+ inw(devpriv->iobase);
+
+ } else {
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER;
+ }
+
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ // Sets gate 0
+ devpriv->us_OutputRegister =
+ (devpriv->
+ us_OutputRegister & APCI3120_CLEAR_PA_PR) |
+ APCI3120_ENABLE_TIMER0;
+ outw(devpriv->us_OutputRegister,
+ devpriv->iobase + APCI3120_WR_ADDRESS);
+
+ // Select Timer 0
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_0_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ //Set the convertion time
+ outw(us_ConvertTiming,
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ us_TmpValue =
+ (USHORT) inw(dev->iobase + APCI3120_RD_STATUS);
+
+ if (devpriv->b_EocEosInterrupt == APCI3120_DISABLE) {
+
+ do {
+ // Waiting for the end of conversion
+ us_TmpValue =
+ inw(devpriv->iobase +
+ APCI3120_RD_STATUS);
+ } while ((us_TmpValue & APCI3120_EOC) ==
+ APCI3120_EOC);
+
+ //Read the result in FIFO and put it in insn data pointer
+ us_TmpValue = inw(devpriv->iobase + 0);
+ *data = us_TmpValue;
+
+ inw(devpriv->iobase + APCI3120_RESET_FIFO);
+ }
+
+ break;
+
+ case APCI3120_EOS_MODE:
+
+ inw(devpriv->iobase);
+ // Clears the FIFO
+ inw(devpriv->iobase + APCI3120_RESET_FIFO);
+ // clear PA PR and disable timer 0
+
+ devpriv->us_OutputRegister =
+ (devpriv->
+ us_OutputRegister & APCI3120_CLEAR_PA_PR) |
+ APCI3120_DISABLE_TIMER0;
+
+ outw(devpriv->us_OutputRegister,
+ devpriv->iobase + APCI3120_WR_ADDRESS);
+
+ if (!i_APCI3120_SetupChannelList(dev, s,
+ devpriv->ui_AiNbrofChannels,
+ devpriv->ui_AiChannelList, 0))
+ return -EINVAL;
+
+ //Initialize Timer 0 mode 2
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0xFC) |
+ APCI3120_TIMER_0_MODE_2;
+ outb(devpriv->b_TimerSelectMode,
+ devpriv->iobase + APCI3120_TIMER_CRT1);
+
+ //Select Timer 0
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_0_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ //Set the convertion time
+ outw(us_ConvertTiming,
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ //Set the scan bit
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister | APCI3120_ENABLE_SCAN;
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ //If Interrupt function is loaded
+ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) {
+ //Disables the EOC,DMA and enables the EOS interrupt
+ devpriv->b_ModeSelectRegister =
+ (devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_EOC_INT) |
+ APCI3120_ENABLE_EOS_INT;
+ inw(devpriv->iobase);
+
+ } else
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER;
+
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+ //Sets gate 0
+
+ devpriv->us_OutputRegister =
+ devpriv->
+ us_OutputRegister | APCI3120_ENABLE_TIMER0;
+ outw(devpriv->us_OutputRegister,
+ devpriv->iobase + APCI3120_WR_ADDRESS);
+
+ //Start conversion
+ outw(0, devpriv->iobase + APCI3120_START_CONVERSION);
+
+ //Waiting of end of convertion if interrupt is not installed
+ if (devpriv->b_EocEosInterrupt == APCI3120_DISABLE) {
+ //Waiting the end of convertion
+ do {
+ us_TmpValue =
+ inw(devpriv->iobase +
+ APCI3120_RD_STATUS);
+ }
+ while ((us_TmpValue & APCI3120_EOS) !=
+ APCI3120_EOS);
+
+ for (i = 0; i < devpriv->ui_AiNbrofChannels;
+ i++) {
+ //Read the result in FIFO and write them in shared memory
+ us_TmpValue = inw(devpriv->iobase);
+ data[i] = (UINT) us_TmpValue;
+ }
+
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE; // Restore defaults.
+ }
+ break;
+
+ default:
+ printk("inputs wrong\n");
+
+ }
+ devpriv->ui_EocEosConversionTime = 0; // re initializing the variable;
+ }
+
+ return insn->n;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev,|
+| struct comedi_subdevice *s)|
+| |
++----------------------------------------------------------------------------+
+| Task : Stops Cyclic acquisition |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| |
++----------------------------------------------------------------------------+
+| Return Value :0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_StopCyclicAcquisition(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ // Disable A2P Fifo write and AMWEN signal
+ outw(0, devpriv->i_IobaseAddon + 4);
+
+ //Disable Bus Master ADD ON
+ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+ outw(0, devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(0, devpriv->i_IobaseAddon + 2);
+
+ //Disable BUS Master PCI
+ outl(0, devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR);
+
+ //outl(inl(devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR)&(~AINT_WRITE_COMPL), devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR); // stop amcc irqs
+ //outl(inl(devpriv->i_IobaseAmcc+AMCC_OP_REG_MCSR)&(~EN_A2P_TRANSFERS), devpriv->i_IobaseAmcc+AMCC_OP_REG_MCSR); // stop DMA
+
+ //Disable ext trigger
+ i_APCI3120_ExttrigDisable(dev);
+
+ devpriv->us_OutputRegister = 0;
+ //stop counters
+ outw(devpriv->
+ us_OutputRegister & APCI3120_DISABLE_TIMER0 &
+ APCI3120_DISABLE_TIMER1, dev->iobase + APCI3120_WR_ADDRESS);
+
+ outw(APCI3120_DISABLE_ALL_TIMER, dev->iobase + APCI3120_WR_ADDRESS);
+
+ //DISABLE_ALL_INTERRUPT
+ outb(APCI3120_DISABLE_ALL_INTERRUPT,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+ //Flush FIFO
+ inb(dev->iobase + APCI3120_RESET_FIFO);
+ inw(dev->iobase + APCI3120_RD_STATUS);
+ devpriv->ui_AiActualScan = 0;
+ devpriv->ui_AiActualScanPosition = 0;
+ s->async->cur_chan = 0;
+ devpriv->ui_AiBufferPtr = 0;
+ devpriv->b_AiContinuous = 0;
+ devpriv->ui_DmaActualBuffer = 0;
+
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ i_APCI3120_Reset(dev);
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev|
+| ,struct comedi_subdevice *s,struct comedi_cmd *cmd) |
+| |
++----------------------------------------------------------------------------+
+| Task : Test validity for a command for cyclic anlog input |
+| acquisition |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_cmd *cmd |
++----------------------------------------------------------------------------+
+| Return Value :0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_CommandTestAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp; // divisor1,divisor2;
+
+ // step 1: make sure trigger sources are trivially valid
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ //step 2: make sure trigger sources are unique and mutually compatible
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
+ err++;
+ }
+
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+
+ if (cmd->convert_src != TRIG_TIMER)
+ err++;
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ if (err)
+ return 2;
+
+ // step 3: make sure arguments are trivially compatible
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER) // Test Delay timing
+ {
+ if (cmd->scan_begin_arg < this_board->ui_MinDelaytimeNs) {
+ cmd->scan_begin_arg = this_board->ui_MinDelaytimeNs;
+ err++;
+ }
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) // Test Acquisition timing
+ {
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if ((cmd->convert_arg)
+ && (cmd->convert_arg <
+ this_board->ui_MinAcquisitiontimeNs)) {
+ cmd->convert_arg =
+ this_board->ui_MinAcquisitiontimeNs;
+ err++;
+ }
+ } else {
+ if (cmd->convert_arg <
+ this_board->ui_MinAcquisitiontimeNs) {
+ cmd->convert_arg =
+ this_board->ui_MinAcquisitiontimeNs;
+ err++;
+
+ }
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->chanlist_len > this_board->i_AiChannelList) {
+ cmd->chanlist_len = this_board->i_AiChannelList;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { // TRIG_NONE
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ // step 4: fix up any arguments
+
+ if (cmd->convert_src == TRIG_TIMER) {
+
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, |
+| struct comedi_subdevice *s) |
+| |
++----------------------------------------------------------------------------+
+| Task : Does asynchronous acquisition |
+| Determines the mode 1 or 2. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_CommandAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ //loading private structure with cmd structure inputs
+ devpriv->ui_AiFlags = cmd->flags;
+ devpriv->ui_AiNbrofChannels = cmd->chanlist_len;
+ devpriv->ui_AiScanLength = cmd->scan_end_arg;
+ devpriv->pui_AiChannelList = cmd->chanlist;
+
+ //UPDATE-0.7.57->0.7.68devpriv->AiData=s->async->data;
+ devpriv->AiData = s->async->prealloc_buf;
+ //UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len;
+ devpriv->ui_AiDataLength = s->async->prealloc_bufsz;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ui_AiNbrofScans = cmd->stop_arg;
+ } else {
+ devpriv->ui_AiNbrofScans = 0;
+ }
+
+ devpriv->ui_AiTimer0 = 0; // variables changed to timer0,timer1
+ devpriv->ui_AiTimer1 = 0;
+ if ((devpriv->ui_AiNbrofScans == 0) || (devpriv->ui_AiNbrofScans == -1))
+ devpriv->b_AiContinuous = 1; // user want neverending analog acquisition
+ // stopped using cancel
+
+ if (cmd->start_src == TRIG_EXT)
+ devpriv->b_ExttrigEnable = APCI3120_ENABLE;
+ else
+ devpriv->b_ExttrigEnable = APCI3120_DISABLE;
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ // mode 1 or 3
+ if (cmd->convert_src == TRIG_TIMER) {
+ // mode 1
+
+ devpriv->ui_AiTimer0 = cmd->convert_arg; // timer constant in nano seconds
+ //return this_board->i_hwdrv_CommandAnalogInput(1,dev,s);
+ return i_APCI3120_CyclicAnalogInput(1, dev, s);
+ }
+
+ }
+ if ((cmd->scan_begin_src == TRIG_TIMER)
+ && (cmd->convert_src == TRIG_TIMER)) {
+ // mode 2
+ devpriv->ui_AiTimer1 = cmd->scan_begin_arg;
+ devpriv->ui_AiTimer0 = cmd->convert_arg; // variable changed timer2 to timer0
+ //return this_board->i_hwdrv_CommandAnalogInput(2,dev,s);
+ return i_APCI3120_CyclicAnalogInput(2, dev, s);
+ }
+ return -1;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_CyclicAnalogInput(int mode, |
+| struct comedi_device * dev,struct comedi_subdevice * s) |
++----------------------------------------------------------------------------+
+| Task : This is used for analog input cyclic acquisition |
+| Performs the command operations. |
+| If DMA is configured does DMA initialization |
+| otherwise does the acquisition with EOS interrupt. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ BYTE b_Tmp;
+ UINT ui_Tmp, ui_DelayTiming = 0, ui_TimerValue1 = 0, dmalen0 =
+ 0, dmalen1 = 0, ui_TimerValue2 =
+ 0, ui_TimerValue0, ui_ConvertTiming;
+ USHORT us_TmpValue;
+
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ //devpriv->b_AiCyclicAcquisition=APCI3120_ENABLE;
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ /*******************/
+ /* Resets the FIFO */
+ /*******************/
+ inb(dev->iobase + APCI3120_RESET_FIFO);
+
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ //inw(dev->iobase+APCI3120_RD_STATUS);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ /***************************/
+ /* Acquisition initialized */
+ /***************************/
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ devpriv->b_AiCyclicAcquisition = APCI3120_ENABLE;
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ // clear software registers
+ devpriv->b_TimerSelectMode = 0;
+ devpriv->us_OutputRegister = 0;
+ devpriv->b_ModeSelectRegister = 0;
+ //devpriv->b_DigitalOutputRegister=0;
+
+ //COMMENT JK 07.05.04: Followings calls are in i_APCI3120_StartAnalogInputAcquisition
+
+ /****************************/
+ /* Clear Timer Write TC INT */
+ /****************************/
+ outl(APCI3120_CLEAR_WRITE_TC_INT,
+ devpriv->i_IobaseAmcc + APCI3120_AMCC_OP_REG_INTCSR);
+
+ /************************************/
+ /* Clears the timer status register */
+ /************************************/
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ //inw(dev->iobase+APCI3120_TIMER_STATUS_REGISTER);
+ inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ /**************************/
+ /* Disables All Timer */
+ /* Sets PR and PA to 0 */
+ /**************************/
+ devpriv->us_OutputRegister = devpriv->us_OutputRegister &
+ APCI3120_DISABLE_TIMER0 &
+ APCI3120_DISABLE_TIMER1 & APCI3120_CLEAR_PA_PR;
+
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+
+ /*******************/
+ /* Resets the FIFO */
+ /*******************/
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ inb(devpriv->iobase + APCI3120_RESET_FIFO);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ devpriv->ui_AiActualScan = 0;
+ devpriv->ui_AiActualScanPosition = 0;
+ s->async->cur_chan = 0;
+ devpriv->ui_AiBufferPtr = 0;
+ devpriv->ui_DmaActualBuffer = 0;
+
+ // value for timer2 minus -2 has to be done .....dunno y??
+ ui_TimerValue2 = devpriv->ui_AiNbrofScans - 2;
+ ui_ConvertTiming = devpriv->ui_AiTimer0;
+
+ if (mode == 2)
+ ui_DelayTiming = devpriv->ui_AiTimer1;
+
+ /**********************************/
+ /* Initializes the sequence array */
+ /**********************************/
+ if (!i_APCI3120_SetupChannelList(dev, s, devpriv->ui_AiNbrofChannels,
+ devpriv->pui_AiChannelList, 0))
+ return -EINVAL;
+
+ us_TmpValue = (USHORT) inw(dev->iobase + APCI3120_RD_STATUS);
+/*** EL241003 : add this section in comment because floats must not be used
+ if((us_TmpValue & 0x00B0)==0x00B0)
+ {
+ f_ConvertValue=(((float)ui_ConvertTiming * 0.002) - 2);
+ ui_TimerValue0=(UINT)f_ConvertValue;
+ if (mode==2)
+ {
+ f_DelayValue = (((float)ui_DelayTiming * 0.00002) - 2);
+ ui_TimerValue1 = (UINT) f_DelayValue;
+ }
+ }
+ else
+ {
+ f_ConvertValue=(((float)ui_ConvertTiming * 0.0012926) - 1);
+ ui_TimerValue0=(UINT)f_ConvertValue;
+ if (mode == 2)
+ {
+ f_DelayValue = (((float)ui_DelayTiming * 0.000012926) - 1);
+ ui_TimerValue1 = (UINT) f_DelayValue;
+ }
+ }
+***********************************************************************************************/
+/*** EL241003 Begin : add this section to replace floats calculation by integer calculations **/
+ //EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001
+ if ((us_TmpValue & 0x00B0) == 0x00B0
+ || !strcmp(this_board->pc_DriverName, "apci3001")) {
+ ui_TimerValue0 = ui_ConvertTiming * 2 - 2000;
+ ui_TimerValue0 = ui_TimerValue0 / 1000;
+
+ if (mode == 2) {
+ ui_DelayTiming = ui_DelayTiming / 1000;
+ ui_TimerValue1 = ui_DelayTiming * 2 - 200;
+ ui_TimerValue1 = ui_TimerValue1 / 100;
+ }
+ } else {
+ ui_ConvertTiming = ui_ConvertTiming / 1000;
+ ui_TimerValue0 = ui_ConvertTiming * 12926 - 10000;
+ ui_TimerValue0 = ui_TimerValue0 / 10000;
+
+ if (mode == 2) {
+ ui_DelayTiming = ui_DelayTiming / 1000;
+ ui_TimerValue1 = ui_DelayTiming * 12926 - 1;
+ ui_TimerValue1 = ui_TimerValue1 / 1000000;
+ }
+ }
+/*** EL241003 End ******************************************************************************/
+
+ if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) {
+ i_APCI3120_ExttrigEnable(dev); // activate EXT trigger
+ }
+ switch (mode) {
+ case 1:
+ // init timer0 in mode 2
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_2;
+ outb(devpriv->b_TimerSelectMode,
+ dev->iobase + APCI3120_TIMER_CRT1);
+
+ //Select Timer 0
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_0_WORD;
+ outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+ //Set the convertion time
+ outw(((USHORT) ui_TimerValue0),
+ dev->iobase + APCI3120_TIMER_VALUE);
+ break;
+
+ case 2:
+ // init timer1 in mode 2
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0xF3) | APCI3120_TIMER_1_MODE_2;
+ outb(devpriv->b_TimerSelectMode,
+ dev->iobase + APCI3120_TIMER_CRT1);
+
+ //Select Timer 1
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_1_WORD;
+ outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+ //Set the convertion time
+ outw(((USHORT) ui_TimerValue1),
+ dev->iobase + APCI3120_TIMER_VALUE);
+
+ // init timer0 in mode 2
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_2;
+ outb(devpriv->b_TimerSelectMode,
+ dev->iobase + APCI3120_TIMER_CRT1);
+
+ //Select Timer 0
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_0_WORD;
+ outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+
+ //Set the convertion time
+ outw(((USHORT) ui_TimerValue0),
+ dev->iobase + APCI3120_TIMER_VALUE);
+ break;
+
+ }
+ // ##########common for all modes#################
+
+ /***********************/
+ /* Clears the SCAN bit */
+ /***********************/
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ //devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister | APCI3120_DISABLE_SCAN;
+ devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister &
+ APCI3120_DISABLE_SCAN;
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ // If DMA is disabled
+ if (devpriv->us_UseDma == APCI3120_DISABLE) {
+ // disable EOC and enable EOS
+ devpriv->b_InterruptMode = APCI3120_EOS_MODE;
+ devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
+
+ devpriv->b_ModeSelectRegister =
+ (devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT) |
+ APCI3120_ENABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ if (!devpriv->b_AiContinuous) {
+ // configure Timer2 For counting EOS
+ //Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0)
+ devpriv->us_OutputRegister =
+ devpriv->
+ us_OutputRegister & APCI3120_DISABLE_TIMER2;
+ outw(devpriv->us_OutputRegister,
+ dev->iobase + APCI3120_WR_ADDRESS);
+
+ // DISABLE TIMER INTERRUPT
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_TIMER_INT & 0xEF;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ //(1) Init timer 2 in mode 0 and write timer value
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0x0F) |
+ APCI3120_TIMER_2_MODE_0;
+ outb(devpriv->b_TimerSelectMode,
+ dev->iobase + APCI3120_TIMER_CRT1);
+
+ //Writing LOW WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+ outw(LOWORD(ui_TimerValue2),
+ dev->iobase + APCI3120_TIMER_VALUE);
+
+ //Writing HIGH WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+ outw(HIWORD(ui_TimerValue2),
+ dev->iobase + APCI3120_TIMER_VALUE);
+
+ //(2) Reset FC_TIMER BIT Clearing timer status register
+ inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER);
+ // enable timer counter and disable watch dog
+ devpriv->b_ModeSelectRegister =
+ (devpriv->
+ b_ModeSelectRegister |
+ APCI3120_ENABLE_TIMER_COUNTER) &
+ APCI3120_DISABLE_WATCHDOG;
+ // select EOS clock input for timer 2
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister |
+ APCI3120_TIMER2_SELECT_EOS;
+ // Enable timer2 interrupt
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister |
+ APCI3120_ENABLE_TIMER_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+ devpriv->b_Timer2Mode = APCI3120_COUNTER;
+ devpriv->b_Timer2Interrupt = APCI3120_ENABLE;
+ }
+ } else {
+ // If DMA Enabled
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ //inw(dev->iobase+0);// reset EOC bit
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+ devpriv->b_InterruptMode = APCI3120_DMA_MODE;
+
+ /************************************/
+ /* Disables the EOC, EOS interrupt */
+ /************************************/
+ devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister &
+ APCI3120_DISABLE_EOC_INT & APCI3120_DISABLE_EOS_INT;
+
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ dmalen0 = devpriv->ui_DmaBufferSize[0];
+ dmalen1 = devpriv->ui_DmaBufferSize[1];
+
+ if (!devpriv->b_AiContinuous) {
+
+ if (dmalen0 > (devpriv->ui_AiNbrofScans * devpriv->ui_AiScanLength * 2)) { // must we fill full first buffer?
+ dmalen0 =
+ devpriv->ui_AiNbrofScans *
+ devpriv->ui_AiScanLength * 2;
+ } else if (dmalen1 > (devpriv->ui_AiNbrofScans * devpriv->ui_AiScanLength * 2 - dmalen0)) // and must we fill full second buffer when first is once filled?
+ dmalen1 =
+ devpriv->ui_AiNbrofScans *
+ devpriv->ui_AiScanLength * 2 - dmalen0;
+ }
+
+ if (devpriv->ui_AiFlags & TRIG_WAKE_EOS) {
+ // don't we want wake up every scan?
+ if (dmalen0 > (devpriv->ui_AiScanLength * 2)) {
+ dmalen0 = devpriv->ui_AiScanLength * 2;
+ if (devpriv->ui_AiScanLength & 1)
+ dmalen0 += 2;
+ }
+ if (dmalen1 > (devpriv->ui_AiScanLength * 2)) {
+ dmalen1 = devpriv->ui_AiScanLength * 2;
+ if (devpriv->ui_AiScanLength & 1)
+ dmalen1 -= 2;
+ if (dmalen1 < 4)
+ dmalen1 = 4;
+ }
+ } else { // isn't output buff smaller that our DMA buff?
+ if (dmalen0 > (devpriv->ui_AiDataLength)) {
+ dmalen0 = devpriv->ui_AiDataLength;
+ }
+ if (dmalen1 > (devpriv->ui_AiDataLength)) {
+ dmalen1 = devpriv->ui_AiDataLength;
+ }
+ }
+ devpriv->ui_DmaBufferUsesize[0] = dmalen0;
+ devpriv->ui_DmaBufferUsesize[1] = dmalen1;
+
+ //Initialize DMA
+
+ // Set Transfer count enable bit and A2P_fifo reset bit in AGCSTS register
+ //1
+ ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
+ outl(ui_Tmp, devpriv->i_IobaseAmcc + AMCC_OP_REG_AGCSTS);
+
+ // changed since 16 bit interface for add on
+ /*********************/
+ /* ENABLE BUS MASTER */
+ /*********************/
+ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,
+ devpriv->i_IobaseAddon + 2);
+
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH,
+ devpriv->i_IobaseAddon + 2);
+
+ // TO VERIFIED
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ outw(0x1000, devpriv->i_IobaseAddon + 2);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ //2 No change
+ // A2P FIFO MANAGEMENT
+ // A2P fifo reset & transfer control enable
+ /***********************/
+ /* A2P FIFO MANAGEMENT */
+ /***********************/
+ outl(APCI3120_A2P_FIFO_MANAGEMENT, devpriv->i_IobaseAmcc +
+ APCI3120_AMCC_OP_MCSR);
+
+ //3
+ //beginning address of dma buf
+ //The 32 bit address of dma buffer is converted into two 16 bit addresses
+ // Can done by using _attach and put into into an array
+ // array used may be for differnet pages
+
+ // DMA Start Adress Low
+ outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
+ outw((devpriv->ul_DmaBufferHw[0] & 0xFFFF),
+ devpriv->i_IobaseAddon + 2);
+
+ /*************************/
+ /* DMA Start Adress High */
+ /*************************/
+ outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
+ outw((devpriv->ul_DmaBufferHw[0] / 65536),
+ devpriv->i_IobaseAddon + 2);
+
+ //4
+ // amount of bytes to be transfered set transfer count
+ // used ADDON MWTC register
+ //commented testing outl(devpriv->ui_DmaBufferUsesize[0], devpriv->i_IobaseAddon+AMCC_OP_REG_AMWTC);
+
+ /**************************/
+ /* Nbr of acquisition LOW */
+ /**************************/
+ outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
+ outw((devpriv->ui_DmaBufferUsesize[0] & 0xFFFF),
+ devpriv->i_IobaseAddon + 2);
+
+ /***************************/
+ /* Nbr of acquisition HIGH */
+ /***************************/
+ outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
+ outw((devpriv->ui_DmaBufferUsesize[0] / 65536),
+ devpriv->i_IobaseAddon + 2);
+
+ //5
+ // To configure A2P FIFO
+ // testing outl( FIFO_ADVANCE_ON_BYTE_2,devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR);
+
+ /******************/
+ /* A2P FIFO RESET */
+ /******************/
+ // TO VERIFY
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ outl(0x04000000UL, devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ //6
+ //ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+ // AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ //outw(3,devpriv->i_IobaseAddon + 4);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ //7
+ //initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI)
+ /***************************************************/
+ /* A2P FIFO CONFIGURATE, END OF DMA INTERRUPT INIT */
+ /***************************************************/
+ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
+ APCI3120_ENABLE_WRITE_TC_INT),
+ devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);
+
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ /******************************************/
+ /* ENABLE A2P FIFO WRITE AND ENABLE AMWEN */
+ /******************************************/
+ outw(3, devpriv->i_IobaseAddon + 4);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ /******************/
+ /* A2P FIFO RESET */
+ /******************/
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ outl(0x04000000UL,
+ devpriv->i_IobaseAmcc + APCI3120_AMCC_OP_MCSR);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+ }
+
+ if ((devpriv->us_UseDma == APCI3120_DISABLE)
+ && !devpriv->b_AiContinuous) {
+ // set gate 2 to start conversion
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER2;
+ outw(devpriv->us_OutputRegister,
+ dev->iobase + APCI3120_WR_ADDRESS);
+ }
+
+ switch (mode) {
+ case 1:
+ // set gate 0 to start conversion
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0;
+ outw(devpriv->us_OutputRegister,
+ dev->iobase + APCI3120_WR_ADDRESS);
+ break;
+ case 2:
+ // set gate 0 and gate 1
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER1;
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0;
+ outw(devpriv->us_OutputRegister,
+ dev->iobase + APCI3120_WR_ADDRESS);
+ break;
+
+ }
+
+ return 0;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| INTERNAL FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_Reset(struct comedi_device *dev) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : Hardware reset function |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_Reset(struct comedi_device * dev)
+{
+ unsigned int i;
+ unsigned short us_TmpValue;
+
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+ devpriv->ui_EocEosConversionTime = 0; // set eoc eos conv time to 0
+ devpriv->b_OutputMemoryStatus = 0;
+
+ // variables used in timer subdevice
+ devpriv->b_Timer2Mode = 0;
+ devpriv->b_Timer2Interrupt = 0;
+ devpriv->b_ExttrigEnable = 0; // Disable ext trigger
+
+ /* Disable all interrupts, watchdog for the anolog output */
+ devpriv->b_ModeSelectRegister = 0;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ // Disables all counters, ext trigger and clears PA, PR
+ devpriv->us_OutputRegister = 0;
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+
+ //Code to set the all anolog o/p channel to 0v
+ //8191 is decimal value for zero(0 v)volt in bipolar mode(default)
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_1, dev->iobase + APCI3120_ANALOG_OUTPUT_1); //channel 1
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_2, dev->iobase + APCI3120_ANALOG_OUTPUT_1); //channel 2
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_3, dev->iobase + APCI3120_ANALOG_OUTPUT_1); //channel 3
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_4, dev->iobase + APCI3120_ANALOG_OUTPUT_1); //channel 4
+
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_5, dev->iobase + APCI3120_ANALOG_OUTPUT_2); //channel 5
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_6, dev->iobase + APCI3120_ANALOG_OUTPUT_2); //channel 6
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_7, dev->iobase + APCI3120_ANALOG_OUTPUT_2); //channel 7
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_8, dev->iobase + APCI3120_ANALOG_OUTPUT_2); //channel 8
+
+ // Reset digital output to L0W
+
+//ES05 outb(0x0,dev->iobase+APCI3120_DIGITAL_OUTPUT);
+ udelay(10);
+
+ inw(dev->iobase + 0); //make a dummy read
+ inb(dev->iobase + APCI3120_RESET_FIFO); // flush FIFO
+ inw(dev->iobase + APCI3120_RD_STATUS); // flush A/D status register
+
+ //code to reset the RAM sequence
+ for (i = 0; i < 16; i++) {
+ us_TmpValue = i << 8; //select the location
+ outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS);
+ }
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_SetupChannelList(struct comedi_device * dev, |
+| struct comedi_subdevice * s, int n_chan,unsigned int *chanlist|
+| ,char check) |
+| |
++----------------------------------------------------------------------------+
+| Task :This function will first check channel list is ok or not|
+|and then initialize the sequence RAM with the polarity, Gain,Channel number |
+|If the last argument of function "check"is 1 then it only checks the channel|
+|list is ok or not. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device * dev |
+| struct comedi_subdevice * s |
+| int n_chan |
+ unsigned int *chanlist
+ char check
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_SetupChannelList(struct comedi_device * dev, struct comedi_subdevice * s,
+ int n_chan, unsigned int *chanlist, char check)
+{
+ unsigned int i; //, differencial=0, bipolar=0;
+ unsigned int gain;
+ unsigned short us_TmpValue;
+
+ /* correct channel and range number check itself comedi/range.c */
+ if (n_chan < 1) {
+ if (!check)
+ comedi_error(dev, "range/channel list is empty!");
+ return 0;
+ }
+ // All is ok, so we can setup channel/range list
+ if (check)
+ return 1;
+
+ //Code to set the PA and PR...Here it set PA to 0..
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR;
+ devpriv->us_OutputRegister = ((n_chan - 1) & 0xf) << 8;
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+
+ for (i = 0; i < n_chan; i++) {
+ // store range list to card
+ us_TmpValue = CR_CHAN(chanlist[i]); // get channel number;
+
+ if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) {
+ us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); // set bipolar
+ } else {
+ us_TmpValue |= APCI3120_UNIPOLAR; // enable unipolar......
+ }
+
+ gain = CR_RANGE(chanlist[i]); // get gain number
+ us_TmpValue |= ((gain & 0x03) << 4); //<<4 for G0 and G1 bit in RAM
+ us_TmpValue |= i << 8; //To select the RAM LOCATION....
+ outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS);
+
+ printk("\n Gain = %i",
+ (((unsigned char)CR_RANGE(chanlist[i]) & 0x03) << 2));
+ printk("\n Channel = %i", CR_CHAN(chanlist[i]));
+ printk("\n Polarity = %i", us_TmpValue & APCI3120_UNIPOLAR);
+ }
+ return 1; // we can serve this with scan logic
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_ExttrigEnable(struct comedi_device * dev) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : Enable the external trigger |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device * dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_ExttrigEnable(struct comedi_device * dev)
+{
+
+ devpriv->us_OutputRegister |= APCI3120_ENABLE_EXT_TRIGGER;
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_ExttrigDisable(struct comedi_device * dev) |
+| |
++----------------------------------------------------------------------------+
+| Task : Disables the external trigger |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device * dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_ExttrigDisable(struct comedi_device * dev)
+{
+ devpriv->us_OutputRegister &= ~APCI3120_ENABLE_EXT_TRIGGER;
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| INTERRUPT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name : void v_APCI3120_Interrupt(int irq, void *d) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task :Interrupt handler for APCI3120 |
+| When interrupt occurs this gets called. |
+| First it finds which interrupt has been generated and |
+| handles corresponding interrupt |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq |
+| void *d |
+| |
++----------------------------------------------------------------------------+
+| Return Value : void |
+| |
++----------------------------------------------------------------------------+
+*/
+
+void v_APCI3120_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ USHORT int_daq;
+
+ unsigned int int_amcc, ui_Check, i;
+ USHORT us_TmpValue;
+ BYTE b_DummyRead;
+
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ ui_Check = 1;
+
+ int_daq = inw(dev->iobase + APCI3120_RD_STATUS) & 0xf000; // get IRQ reasons
+ int_amcc = inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); // get AMCC INT register
+
+ if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) {
+ comedi_error(dev, "IRQ from unknow source");
+ return;
+ }
+
+ outl(int_amcc | 0x00ff0000, devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); // shutdown IRQ reasons in AMCC
+
+ int_daq = (int_daq >> 12) & 0xF;
+
+ if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) {
+ //Disable ext trigger
+ i_APCI3120_ExttrigDisable(dev);
+ devpriv->b_ExttrigEnable = APCI3120_DISABLE;
+ }
+ //clear the timer 2 interrupt
+ inb(devpriv->i_IobaseAmcc + APCI3120_TIMER_STATUS_REGISTER);
+
+ if (int_amcc & MASTER_ABORT_INT)
+ comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
+ if (int_amcc & TARGET_ABORT_INT)
+ comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
+
+ // Ckeck if EOC interrupt
+ if (((int_daq & 0x8) == 0)
+ && (devpriv->b_InterruptMode == APCI3120_EOC_MODE)) {
+ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) {
+
+ // Read the AI Value
+
+ devpriv->ui_AiReadData[0] =
+ (UINT) inw(devpriv->iobase + 0);
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ } else {
+ //Disable EOC Interrupt
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ }
+ }
+
+ // Check If EOS interrupt
+ if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) {
+
+ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) // enable this in without DMA ???
+ {
+
+ if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) {
+ ui_Check = 0;
+ i_APCI3120_InterruptHandleEos(dev);
+ devpriv->ui_AiActualScan++;
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister |
+ APCI3120_ENABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase +
+ APCI3120_WRITE_MODE_SELECT);
+ } else {
+ ui_Check = 0;
+ for (i = 0; i < devpriv->ui_AiNbrofChannels;
+ i++) {
+ us_TmpValue = inw(devpriv->iobase + 0);
+ devpriv->ui_AiReadData[i] =
+ (UINT) us_TmpValue;
+ }
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+
+ }
+
+ } else {
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE; //Default settings
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+ }
+
+ }
+ //Timer2 interrupt
+ if (int_daq & 0x1) {
+
+ switch (devpriv->b_Timer2Mode) {
+ case APCI3120_COUNTER:
+
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ // stop timer 2
+ devpriv->us_OutputRegister =
+ devpriv->
+ us_OutputRegister & APCI3120_DISABLE_ALL_TIMER;
+ outw(devpriv->us_OutputRegister,
+ dev->iobase + APCI3120_WR_ADDRESS);
+
+ //stop timer 0 and timer 1
+ i_APCI3120_StopCyclicAcquisition(dev, s);
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+
+ //UPDATE-0.7.57->0.7.68comedi_done(dev,s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+
+ break;
+
+ case APCI3120_TIMER:
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+ break;
+
+ case APCI3120_WATCHDOG:
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+ break;
+
+ default:
+
+ // disable Timer Interrupt
+
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_TIMER_INT;
+
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ }
+
+ b_DummyRead = inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER);
+
+ }
+
+ if ((int_daq & 0x4) && (devpriv->b_InterruptMode == APCI3120_DMA_MODE)) {
+ if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) {
+
+ /****************************/
+ /* Clear Timer Write TC INT */
+ /****************************/
+
+ outl(APCI3120_CLEAR_WRITE_TC_INT,
+ devpriv->i_IobaseAmcc +
+ APCI3120_AMCC_OP_REG_INTCSR);
+
+ /************************************/
+ /* Clears the timer status register */
+ /************************************/
+ inw(dev->iobase + APCI3120_TIMER_STATUS_REGISTER);
+ v_APCI3120_InterruptDma(irq, d); // do some data transfer
+ } else {
+ /* Stops the Timer */
+ outw(devpriv->
+ us_OutputRegister & APCI3120_DISABLE_TIMER0 &
+ APCI3120_DISABLE_TIMER1,
+ dev->iobase + APCI3120_WR_ADDRESS);
+ }
+
+ }
+
+ return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : This function handles EOS interrupt. |
+| This function copies the acquired data(from FIFO) |
+| to Comedi buffer. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+/*
+ * int i_APCI3120_InterruptHandleEos(struct comedi_device *dev)
+{
+ int n_chan,i;
+ short *data;
+ struct comedi_subdevice *s=dev->subdevices+0;
+ struct comedi_async *async = s->async;
+ data=async->data+async->buf_int_ptr;
+ n_chan=devpriv->ui_AiNbrofChannels;
+
+ for(i=0;i<n_chan;i++)
+ {
+ data[i]=inw(dev->iobase+0);
+ }
+ async->buf_int_count+=n_chan*sizeof(short);
+ async->buf_int_ptr+=n_chan*sizeof(short);
+ comedi_eos(dev,s);
+ if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over
+ {
+*//* buffer rollover */
+/* s->async->buf_int_ptr=0;
+ comedi_eobuf(dev,s);
+ }
+ return 0;
+}*/
+int i_APCI3120_InterruptHandleEos(struct comedi_device * dev)
+{
+ int n_chan, i;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int err = 1;
+
+ n_chan = devpriv->ui_AiNbrofChannels;
+
+ s->async->events = 0;
+
+ for (i = 0; i < n_chan; i++)
+ err &= comedi_buf_put(s->async, inw(dev->iobase + 0));
+
+ s->async->events |= COMEDI_CB_EOS;
+
+ if (err == 0)
+ s->async->events |= COMEDI_CB_OVERFLOW;
+
+ comedi_event(dev, s);
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : void v_APCI3120_InterruptDma(int irq, void *d) |
+| |
++----------------------------------------------------------------------------+
+| Task : This is a handler for the DMA interrupt |
+| This function copies the data to Comedi Buffer. |
+| For continuous DMA it reinitializes the DMA operation. |
+| For single mode DMA it stop the acquisition. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq, void *d |
+| |
++----------------------------------------------------------------------------+
+| Return Value : void |
+| |
++----------------------------------------------------------------------------+
+*/
+
+void v_APCI3120_InterruptDma(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ unsigned int next_dma_buf, samplesinbuf;
+ unsigned long low_word, high_word, var;
+
+ UINT ui_Tmp;
+ samplesinbuf =
+ devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer] -
+ inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC);
+
+ if (samplesinbuf <
+ devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) {
+ comedi_error(dev, "Interrupted DMA transfer!");
+ }
+ if (samplesinbuf & 1) {
+ comedi_error(dev, "Odd count of bytes in DMA ring!");
+ i_APCI3120_StopCyclicAcquisition(dev, s);
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+
+ return;
+ }
+ samplesinbuf = samplesinbuf >> 1; // number of received samples
+ if (devpriv->b_DmaDoubleBuffer) {
+ // switch DMA buffers if is used double buffering
+ next_dma_buf = 1 - devpriv->ui_DmaActualBuffer;
+
+ ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
+ outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS);
+
+ // changed since 16 bit interface for add on
+ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,
+ devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); // 0x1000 is out putted in windows driver
+
+ var = devpriv->ul_DmaBufferHw[next_dma_buf];
+ low_word = var & 0xffff;
+ var = devpriv->ul_DmaBufferHw[next_dma_buf];
+ high_word = var / 65536;
+
+ /* DMA Start Adress Low */
+ outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
+ outw(low_word, devpriv->i_IobaseAddon + 2);
+
+ /* DMA Start Adress High */
+ outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(high_word, devpriv->i_IobaseAddon + 2);
+
+ var = devpriv->ui_DmaBufferUsesize[next_dma_buf];
+ low_word = var & 0xffff;
+ var = devpriv->ui_DmaBufferUsesize[next_dma_buf];
+ high_word = var / 65536;
+
+ /* Nbr of acquisition LOW */
+ outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
+ outw(low_word, devpriv->i_IobaseAddon + 2);
+
+ /* Nbr of acquisition HIGH */
+ outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(high_word, devpriv->i_IobaseAddon + 2);
+
+ // To configure A2P FIFO
+ // ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+ // AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+ outw(3, devpriv->i_IobaseAddon + 4);
+ //initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI)
+ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
+ APCI3120_ENABLE_WRITE_TC_INT),
+ devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);
+
+ }
+/*UPDATE-0.7.57->0.7.68
+ ptr=(short *)devpriv->ul_DmaBufferVirtual[devpriv->ui_DmaActualBuffer];
+
+
+ // if there is not enough space left in the buffer to copy all data contained in the DMABufferVirtual
+ if(s->async->buf_int_ptr+samplesinbuf*sizeof(short)>=devpriv->ui_AiDataLength)
+ {
+ m=(devpriv->ui_AiDataLength-s->async->buf_int_ptr)/sizeof(short);
+ v_APCI3120_InterruptDmaMoveBlock16bit(dev,s,(void *)ptr,((void *)(devpriv->AiData))+s->async->buf_int_ptr,m);
+ s->async->buf_int_count+=m*sizeof(short);
+ ptr+=m*sizeof(short);
+ samplesinbuf-=m;
+ s->async->buf_int_ptr=0;
+ comedi_eobuf(dev,s);
+ }
+
+ if (samplesinbuf)
+ {
+ v_APCI3120_InterruptDmaMoveBlock16bit(dev,s,(void *)ptr,((void *)(devpriv->AiData))+s->async->buf_int_ptr,samplesinbuf);
+
+ s->async->buf_int_count+=samplesinbuf*sizeof(short);
+ s->async->buf_int_ptr+=samplesinbuf*sizeof(short);
+ if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS))
+ {
+ comedi_bufcheck(dev,s);
+ }
+ }
+ if (!devpriv->b_AiContinuous)
+ if ( devpriv->ui_AiActualScan>=devpriv->ui_AiNbrofScans )
+ {
+ // all data sampled
+ i_APCI3120_StopCyclicAcquisition(dev,s);
+ devpriv->b_AiCyclicAcquisition=APCI3120_DISABLE;
+ //DPRINTK("\n Single DMA completed..\n");
+ comedi_done(dev,s);
+ return;
+ }
+*/
+ if (samplesinbuf) {
+ v_APCI3120_InterruptDmaMoveBlock16bit(dev, s,
+ devpriv->ul_DmaBufferVirtual[devpriv->
+ ui_DmaActualBuffer], samplesinbuf);
+
+ if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS)) {
+ s->async->events |= COMEDI_CB_EOS;
+ comedi_event(dev, s);
+ }
+ }
+ if (!devpriv->b_AiContinuous)
+ if (devpriv->ui_AiActualScan >= devpriv->ui_AiNbrofScans) {
+ // all data sampled
+ i_APCI3120_StopCyclicAcquisition(dev, s);
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return;
+ }
+
+ if (devpriv->b_DmaDoubleBuffer) { // switch dma buffers
+ devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer;
+ } else {
+ // restart DMA if is not used double buffering
+ //ADDED REINITIALISE THE DMA
+ ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
+ outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS);
+
+ // changed since 16 bit interface for add on
+ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,
+ devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); //
+ // A2P FIFO MANAGEMENT
+ // A2P fifo reset & transfer control enable
+ outl(APCI3120_A2P_FIFO_MANAGEMENT,
+ devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR);
+
+ var = devpriv->ul_DmaBufferHw[0];
+ low_word = var & 0xffff;
+ var = devpriv->ul_DmaBufferHw[0];
+ high_word = var / 65536;
+ outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
+ outw(low_word, devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(high_word, devpriv->i_IobaseAddon + 2);
+
+ var = devpriv->ui_DmaBufferUsesize[0];
+ low_word = var & 0xffff; //changed
+ var = devpriv->ui_DmaBufferUsesize[0];
+ high_word = var / 65536;
+ outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
+ outw(low_word, devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(high_word, devpriv->i_IobaseAddon + 2);
+
+ // To configure A2P FIFO
+ //ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+ // AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+ outw(3, devpriv->i_IobaseAddon + 4);
+ //initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI)
+ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
+ APCI3120_ENABLE_WRITE_TC_INT),
+ devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);
+ }
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :void v_APCI3120_InterruptDmaMoveBlock16bit(comedi_device|
+|*dev,struct comedi_subdevice *s,short *dma,short *data,int n) |
+| |
++----------------------------------------------------------------------------+
+| Task : This function copies the data from DMA buffer to the |
+| Comedi buffer |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| short *dma |
+| short *data,int n |
++----------------------------------------------------------------------------+
+| Return Value : void |
+| |
++----------------------------------------------------------------------------+
+*/
+
+/*void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,struct comedi_subdevice *s,short *dma,short *data,int n)
+{
+ int i,j,m;
+
+ j=s->async->cur_chan;
+ m=devpriv->ui_AiActualScanPosition;
+ for(i=0;i<n;i++)
+ {
+ *data=*dma;
+ data++; dma++;
+ j++;
+ if(j>=devpriv->ui_AiNbrofChannels)
+ {
+ m+=j;
+ j=0;
+ if(m>=devpriv->ui_AiScanLength)
+ {
+ m=0;
+ devpriv->ui_AiActualScan++;
+ if (devpriv->ui_AiFlags & TRIG_WAKE_EOS)
+;//UPDATE-0.7.57->0.7.68 comedi_eos(dev,s);
+ }
+ }
+ }
+ devpriv->ui_AiActualScanPosition=m;
+ s->async->cur_chan=j;
+
+}
+*/
+void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device * dev,
+ struct comedi_subdevice * s, short * dma_buffer, unsigned int num_samples)
+{
+ devpriv->ui_AiActualScan +=
+ (s->async->cur_chan + num_samples) / devpriv->ui_AiScanLength;
+ s->async->cur_chan += num_samples;
+ s->async->cur_chan %= devpriv->ui_AiScanLength;
+
+ cfc_write_array_to_buffer(s, dma_buffer, num_samples * sizeof(short));
+}
+
+/*
++----------------------------------------------------------------------------+
+| TIMER SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, |
+| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task :Configure Timer 2 |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
+| |
+| data[0]= TIMER configure as timer |
+| = WATCHDOG configure as watchdog |
+| data[1] = Timer constant |
+| data[2] = Timer2 interrupt (1)enable or(0) disable |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnConfigTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ui_Timervalue2;
+ USHORT us_TmpValue;
+ BYTE b_Tmp;
+
+ if (!data[1])
+ comedi_error(dev, "config:No timer constant !");
+
+ devpriv->b_Timer2Interrupt = (BYTE) data[2]; // save info whether to enable or disable interrupt
+
+ ui_Timervalue2 = data[1] / 1000; // convert nano seconds to u seconds
+
+ //this_board->i_hwdrv_InsnConfigTimer(dev, ui_Timervalue2,(BYTE)data[0]);
+ us_TmpValue = (USHORT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+ //EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001
+ // and calculate the time value to set in the timer
+ if ((us_TmpValue & 0x00B0) == 0x00B0
+ || !strcmp(this_board->pc_DriverName, "apci3001")) {
+ //Calculate the time value to set in the timer
+ ui_Timervalue2 = ui_Timervalue2 / 50;
+ } else {
+ //Calculate the time value to set in the timer
+ ui_Timervalue2 = ui_Timervalue2 / 70;
+ }
+
+ //Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0)
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER2;
+ outw(devpriv->us_OutputRegister, devpriv->iobase + APCI3120_WR_ADDRESS);
+
+ // Disable TIMER Interrupt
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT & 0xEF;
+
+ // Disable Eoc and Eos Interrupts
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT &
+ APCI3120_DISABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+ if (data[0] == APCI3120_TIMER) //initialize timer
+ {
+
+ //devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister| APCI3120_ENABLE_TIMER_INT ;
+ //outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);
+
+ //Set the Timer 2 in mode 2(Timer)
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_2;
+ outb(devpriv->b_TimerSelectMode,
+ devpriv->iobase + APCI3120_TIMER_CRT1);
+
+ //Configure the timer 2 for writing the LOW WORD of timer is Delay value
+ //You must make a b_tmp variable with DigitalOutPutRegister because at Address_1+APCI3120_TIMER_CRT0
+ //you can set the digital output and configure the timer 2,and if you don't make this, digital output
+ //are erase (Set to 0)
+
+ //Writing LOW WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+ outw(LOWORD(ui_Timervalue2),
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ //Writing HIGH WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+ outw(HIWORD(ui_Timervalue2),
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+ // timer2 in Timer mode enabled
+ devpriv->b_Timer2Mode = APCI3120_TIMER;
+
+ } else // Initialize Watch dog
+ {
+
+ //Set the Timer 2 in mode 5(Watchdog)
+
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_5;
+ outb(devpriv->b_TimerSelectMode,
+ devpriv->iobase + APCI3120_TIMER_CRT1);
+
+ //Configure the timer 2 for writing the LOW WORD of timer is Delay value
+ //You must make a b_tmp variable with DigitalOutPutRegister because at Address_1+APCI3120_TIMER_CRT0
+ //you can set the digital output and configure the timer 2,and if you don't make this, digital output
+ //are erase (Set to 0)
+
+ //Writing LOW WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+ outw(LOWORD(ui_Timervalue2),
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ //Writing HIGH WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ outw(HIWORD(ui_Timervalue2),
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+ //watchdog enabled
+ devpriv->b_Timer2Mode = APCI3120_WATCHDOG;
+
+ }
+
+ return insn->n;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, |
+| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : To start and stop the timer |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
+| |
+| data[0] = 1 (start) |
+| data[0] = 0 (stop ) |
+| data[0] = 2 (write new value) |
+| data[1]= new value |
+| |
+| devpriv->b_Timer2Mode = 0 DISABLE |
+| 1 Timer |
+| 2 Watch dog |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnWriteTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ui_Timervalue2 = 0;
+ USHORT us_TmpValue;
+ BYTE b_Tmp;
+
+ if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG)
+ && (devpriv->b_Timer2Mode != APCI3120_TIMER)) {
+ comedi_error(dev, "\nwrite:timer2 not configured ");
+ return -EINVAL;
+ }
+
+ if (data[0] == 2) // write new value
+ {
+ if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
+ comedi_error(dev,
+ "write :timer2 not configured in TIMER MODE");
+ return -EINVAL;
+ }
+
+ if (data[1])
+ ui_Timervalue2 = data[1];
+ else
+ ui_Timervalue2 = 0;
+ }
+
+ //this_board->i_hwdrv_InsnWriteTimer(dev,data[0],ui_Timervalue2);
+
+ switch (data[0]) {
+ case APCI3120_START:
+
+ // Reset FC_TIMER BIT
+ inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER);
+ if (devpriv->b_Timer2Mode == APCI3120_TIMER) //start timer
+ {
+ //Enable Timer
+ devpriv->b_ModeSelectRegister =
+ devpriv->b_ModeSelectRegister & 0x0B;
+ } else //start watch dog
+ {
+ //Enable WatchDog
+ devpriv->b_ModeSelectRegister =
+ (devpriv->
+ b_ModeSelectRegister & 0x0B) |
+ APCI3120_ENABLE_WATCHDOG;
+ }
+
+ //enable disable interrupt
+ if ((devpriv->b_Timer2Interrupt) == APCI3120_ENABLE) {
+
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister |
+ APCI3120_ENABLE_TIMER_INT;
+ // save the task structure to pass info to user
+ devpriv->tsk_Current = current;
+ } else {
+
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_TIMER_INT;
+ }
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ if (devpriv->b_Timer2Mode == APCI3120_TIMER) //start timer
+ {
+ //For Timer mode is Gate2 must be activated **timer started
+ devpriv->us_OutputRegister =
+ devpriv->
+ us_OutputRegister | APCI3120_ENABLE_TIMER2;
+ outw(devpriv->us_OutputRegister,
+ devpriv->iobase + APCI3120_WR_ADDRESS);
+ }
+
+ break;
+
+ case APCI3120_STOP:
+ if (devpriv->b_Timer2Mode == APCI3120_TIMER) {
+ //Disable timer
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_TIMER_COUNTER;
+ } else {
+ //Disable WatchDog
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_WATCHDOG;
+ }
+ // Disable timer interrupt
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT;
+
+ // Write above states to register
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ // Reset Gate 2
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER_INT;
+ outw(devpriv->us_OutputRegister,
+ devpriv->iobase + APCI3120_WR_ADDRESS);
+
+ // Reset FC_TIMER BIT
+ inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER);
+
+ // Disable timer
+ //devpriv->b_Timer2Mode=APCI3120_DISABLE;
+
+ break;
+
+ case 2: //write new value to Timer
+ if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
+ comedi_error(dev,
+ "write :timer2 not configured in TIMER MODE");
+ return -EINVAL;
+ }
+ // ui_Timervalue2=data[1]; // passed as argument
+ us_TmpValue =
+ (USHORT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+ //EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001
+ // and calculate the time value to set in the timer
+ if ((us_TmpValue & 0x00B0) == 0x00B0
+ || !strcmp(this_board->pc_DriverName, "apci3001")) {
+ //Calculate the time value to set in the timer
+ ui_Timervalue2 = ui_Timervalue2 / 50;
+ } else {
+ //Calculate the time value to set in the timer
+ ui_Timervalue2 = ui_Timervalue2 / 70;
+ }
+ //Writing LOW WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ outw(LOWORD(ui_Timervalue2),
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ //Writing HIGH WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ outw(HIWORD(ui_Timervalue2),
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ break;
+ default:
+ return -EINVAL; // Not a valid input
+ }
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_InsnReadTimer(struct comedi_device *dev, |
+| struct comedi_subdevice *s,struct comedi_insn *insn, unsigned int *data) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : read the Timer value |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| for Timer: data[0]= Timer constant |
+| |
+| for watchdog: data[0]=0 (still running) |
+| data[0]=1 (run down) |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3120_InsnReadTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_Tmp;
+ USHORT us_TmpValue, us_TmpValue_2, us_StatusValue;
+
+ if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG)
+ && (devpriv->b_Timer2Mode != APCI3120_TIMER)) {
+ comedi_error(dev, "\nread:timer2 not configured ");
+ }
+
+ //this_board->i_hwdrv_InsnReadTimer(dev,data);
+ if (devpriv->b_Timer2Mode == APCI3120_TIMER) {
+
+ //Read the LOW WORD of Timer 2 register
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ us_TmpValue = inw(devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ //Read the HIGH WORD of Timer 2 register
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ us_TmpValue_2 = inw(devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ // combining both words
+ data[0] = (UINT) ((us_TmpValue) | ((us_TmpValue_2) << 16));
+
+ } else // Read watch dog status
+ {
+
+ us_StatusValue = inw(devpriv->iobase + APCI3120_RD_STATUS);
+ us_StatusValue =
+ ((us_StatusValue & APCI3120_FC_TIMER) >> 12) & 1;
+ if (us_StatusValue == 1) {
+ // RESET FC_TIMER BIT
+ inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER);
+ }
+ data[0] = us_StatusValue; // when data[0] = 1 then the watch dog has rundown
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| DIGITAL INPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, |
+| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : Reads the value of the specified Digital input channel|
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ UINT ui_Chan, ui_TmpValue;
+
+ ui_Chan = CR_CHAN(insn->chanspec); // channel specified
+
+ //this_board->i_hwdrv_InsnReadDigitalInput(dev,ui_Chan,data);
+ if (ui_Chan >= 0 && ui_Chan <= 3) {
+ ui_TmpValue = (UINT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+ // since only 1 channel reqd to bring it to last bit it is rotated
+ // 8 +(chan - 1) times then ANDed with 1 for last bit.
+ *data = (ui_TmpValue >> (ui_Chan + 8)) & 1;
+ //return 0;
+ } else {
+ // comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ }
+ return insn->n;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, |
+|struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Reads the value of the Digital input Port i.e.4channels|
+| value is returned in data[0] |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3120_InsnBitsDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_TmpValue;
+ ui_TmpValue = (UINT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+ /***** state of 4 channels in the 11, 10, 9, 8 bits of status reg
+ rotated right 8 times to bring them to last four bits
+ ANDed with oxf for value.
+ *****/
+
+ *data = (ui_TmpValue >> 8) & 0xf;
+ //this_board->i_hwdrv_InsnBitsDigitalInput(dev,data);
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| DIGITAL OUTPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device |
+| *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task :Configure the output memory ON or OFF |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters :struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ }
+ if (data[0]) {
+ devpriv->b_OutputMemoryStatus = APCI3120_ENABLE;
+
+ } else {
+ devpriv->b_OutputMemoryStatus = APCI3120_DISABLE;
+ devpriv->b_DigitalOutputRegister = 0;
+ }
+ if (!devpriv->b_OutputMemoryStatus) {
+ ui_Temp = 0;
+
+ } //if(!devpriv->b_OutputMemoryStatus )
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, |
+| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : write diatal output port |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
+ data[0] Value to be written
+ data[1] :1 Set digital o/p ON
+ data[1] 2 Set digital o/p OFF with memory ON
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device * dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ if ((data[0] > this_board->i_DoMaxdata) || (data[0] < 0)) {
+
+ comedi_error(dev, "Data is not valid !!! \n");
+ return -EINVAL;
+ }
+
+ switch (data[1]) {
+ case 1:
+ data[0] = (data[0] << 4) | devpriv->b_DigitalOutputRegister;
+ break;
+
+ case 2:
+ data[0] = data[0];
+ break;
+ default:
+ printk("\nThe parameter passed is in error \n");
+ return -EINVAL;
+ } // switch(data[1])
+ outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
+
+ devpriv->b_DigitalOutputRegister = data[0] & 0xF0;
+
+ return insn->n;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,|
+|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Write digiatl output |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
+ data[0] Value to be written
+ data[1] :1 Set digital o/p ON
+ data[1] 2 Set digital o/p OFF with memory ON
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+
+ UINT ui_Temp1;
+
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ }
+ if ((ui_NoOfChannel > (this_board->i_NbrDoChannel - 1))
+ || (ui_NoOfChannel < 0)) {
+ comedi_error(dev,
+ "This board doesn't have specified channel !!! \n");
+ return -EINVAL;
+ }
+
+ switch (data[1]) {
+ case 1:
+ data[0] = (data[0] << ui_NoOfChannel);
+//ES05 data[0]=(data[0]<<4)|ui_Temp;
+ data[0] = (data[0] << 4) | devpriv->b_DigitalOutputRegister;
+ break;
+
+ case 2:
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp1 = ui_Temp1 << 4;
+//ES05 ui_Temp=ui_Temp|ui_Temp1;
+ devpriv->b_DigitalOutputRegister =
+ devpriv->b_DigitalOutputRegister | ui_Temp1;
+
+ data[0] = (data[0] << ui_NoOfChannel) ^ 0xf;
+ data[0] = data[0] << 4;
+//ES05 data[0]=data[0]& ui_Temp;
+ data[0] = data[0] & devpriv->b_DigitalOutputRegister;
+ break;
+ default:
+ printk("\nThe parameter passed is in error \n");
+ return -EINVAL;
+ } // switch(data[1])
+ outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
+
+//ES05 ui_Temp=data[0] & 0xf0;
+ devpriv->b_DigitalOutputRegister = data[0] & 0xf0;
+ return (insn->n);
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| ANALOG OUTPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,|
+|struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Write analog output |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ UINT ui_Range, ui_Channel;
+ USHORT us_TmpValue;
+
+ ui_Range = CR_RANGE(insn->chanspec);
+ ui_Channel = CR_CHAN(insn->chanspec);
+
+ //this_board->i_hwdrv_InsnWriteAnalogOutput(dev, ui_Range, ui_Channel,data[0]);
+ if (ui_Range) // if 1 then unipolar
+ {
+
+ if (data[0] != 0)
+ data[0] =
+ ((((ui_Channel & 0x03) << 14) & 0xC000) | (1 <<
+ 13) | (data[0] + 8191));
+ else
+ data[0] =
+ ((((ui_Channel & 0x03) << 14) & 0xC000) | (1 <<
+ 13) | 8192);
+
+ } else // if 0 then bipolar
+ {
+ data[0] =
+ ((((ui_Channel & 0x03) << 14) & 0xC000) | (0 << 13) |
+ data[0]);
+
+ }
+
+ //out put n values at the given channel.
+ // rt_printk("\nwaiting for DA_READY BIT");
+ do //Waiting of DA_READY BIT
+ {
+ us_TmpValue =
+ ((USHORT) inw(devpriv->iobase +
+ APCI3120_RD_STATUS)) & 0x0001;
+ } while (us_TmpValue != 0x0001);
+
+ if (ui_Channel <= 3)
+ // for channel 0-3 out at the register 1 (wrDac1-8)
+ // data[i] typecasted to ushort since word write is to be done
+ outw((USHORT) data[0],
+ devpriv->iobase + APCI3120_ANALOG_OUTPUT_1);
+ else
+ // for channel 4-7 out at the register 2 (wrDac5-8)
+ //data[i] typecasted to ushort since word write is to be done
+ outw((USHORT) data[0],
+ devpriv->iobase + APCI3120_ANALOG_OUTPUT_2);
+
+ return insn->n;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h
new file mode 100644
index 00000000000..59d5d87a845
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h
@@ -0,0 +1,241 @@
+
+// hwdrv_apci3120.h
+
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+// comedi related defines
+
+//ANALOG INPUT RANGE
+static const struct comedi_lrange range_apci3120_ai = { 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+// ANALOG OUTPUT RANGE
+static const struct comedi_lrange range_apci3120_ao = { 2, {
+ BIP_RANGE(10),
+ UNI_RANGE(10)
+ }
+};
+
+#define APCI3120_BIPOLAR_RANGES 4 // used for test on mixture of BIP/UNI ranges
+
+#define APCI3120_BOARD_VENDOR_ID 0x10E8
+#define APCI3120_ADDRESS_RANGE 16
+
+#define APCI3120_DISABLE 0
+#define APCI3120_ENABLE 1
+
+#define APCI3120_START 1
+#define APCI3120_STOP 0
+
+#define APCI3120_EOC_MODE 1
+#define APCI3120_EOS_MODE 2
+#define APCI3120_DMA_MODE 3
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI3120_DIGITAL_OUTPUT 0x0D
+#define APCI3120_RD_STATUS 0x02
+#define APCI3120_RD_FIFO 0x00
+
+// digital output insn_write ON /OFF selection
+#define APCI3120_SET4DIGITALOUTPUTON 1
+#define APCI3120_SET4DIGITALOUTPUTOFF 0
+
+// analog output SELECT BIT
+#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000
+#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000
+#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000
+#define APCI3120_ANALOG_OP_CHANNEL_4 0xC000
+#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000
+#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000
+#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000
+#define APCI3120_ANALOG_OP_CHANNEL_8 0xC000
+
+// Enable external trigger bit in nWrAddress
+#define APCI3120_ENABLE_EXT_TRIGGER 0x8000
+
+//ANALOG OUTPUT AND INPUT DEFINE
+#define APCI3120_UNIPOLAR 0x80 //$$ RAM sequence polarity BIT
+#define APCI3120_BIPOLAR 0x00 //$$ RAM sequence polarity BIT
+#define APCI3120_ANALOG_OUTPUT_1 0x08 // (ADDRESS )
+#define APCI3120_ANALOG_OUTPUT_2 0x0A // (ADDRESS )
+#define APCI3120_1_GAIN 0x00 //$$ RAM sequence Gain Bits for gain 1
+#define APCI3120_2_GAIN 0x10 //$$ RAM sequence Gain Bits for gain 2
+#define APCI3120_5_GAIN 0x20 //$$ RAM sequence Gain Bits for gain 5
+#define APCI3120_10_GAIN 0x30 //$$ RAM sequence Gain Bits for gain 10
+#define APCI3120_SEQ_RAM_ADDRESS 0x06 //$$ EARLIER NAMED APCI3120_FIFO_ADDRESS
+#define APCI3120_RESET_FIFO 0x0C //(ADDRESS)
+#define APCI3120_TIMER_0_MODE_2 0x01 //$$ Bits for timer mode
+#define APCI3120_TIMER_0_MODE_4 0x2
+#define APCI3120_SELECT_TIMER_0_WORD 0x00
+#define APCI3120_ENABLE_TIMER0 0x1000 //$$Gatebit 0 in nWrAddress
+#define APCI3120_CLEAR_PR 0xF0FF
+#define APCI3120_CLEAR_PA 0xFFF0
+#define APCI3120_CLEAR_PA_PR (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA)
+
+// nWrMode_Select
+#define APCI3120_ENABLE_SCAN 0x8 //$$ bit in nWrMode_Select
+#define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN)
+#define APCI3120_ENABLE_EOS_INT 0x2 //$$ bit in nWrMode_Select
+
+#define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT)
+#define APCI3120_ENABLE_EOC_INT 0x1
+#define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT)
+#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
+#define APCI3120_DISABLE_ALL_INTERRUPT (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
+
+//status register bits
+#define APCI3120_EOC 0x8000
+#define APCI3120_EOS 0x2000
+
+// software trigger dummy register
+#define APCI3120_START_CONVERSION 0x02 //(ADDRESS)
+
+//TIMER DEFINE
+#define APCI3120_QUARTZ_A 70
+#define APCI3120_QUARTZ_B 50
+#define APCI3120_TIMER 1
+#define APCI3120_WATCHDOG 2
+#define APCI3120_TIMER_DISABLE 0
+#define APCI3120_TIMER_ENABLE 1
+#define APCI3120_ENABLE_TIMER2 0x4000 //$$ gatebit 2 in nWrAddress
+#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
+#define APCI3120_ENABLE_TIMER_INT 0x04 //$$ ENAIRQ_FC_Bit in nWrModeSelect
+#define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT)
+#define APCI3120_WRITE_MODE_SELECT 0x0E // (ADDRESS)
+#define APCI3120_SELECT_TIMER_0_WORD 0x00
+#define APCI3120_SELECT_TIMER_1_WORD 0x01
+#define APCI3120_TIMER_1_MODE_2 0x4
+
+//$$ BIT FOR MODE IN nCsTimerCtr1
+#define APCI3120_TIMER_2_MODE_0 0x0
+#define APCI3120_TIMER_2_MODE_2 0x10
+#define APCI3120_TIMER_2_MODE_5 0x30
+
+//$$ BIT FOR MODE IN nCsTimerCtr0
+#define APCI3120_SELECT_TIMER_2_LOW_WORD 0x02
+#define APCI3120_SELECT_TIMER_2_HIGH_WORD 0x03
+
+#define APCI3120_TIMER_CRT0 0x0D //(ADDRESS for cCsTimerCtr0)
+#define APCI3120_TIMER_CRT1 0x0C //(ADDRESS for cCsTimerCtr1)
+
+#define APCI3120_TIMER_VALUE 0x04 //ADDRESS for nCsTimerWert
+#define APCI3120_TIMER_STATUS_REGISTER 0x0D //ADDRESS for delete timer 2 interrupt
+#define APCI3120_RD_STATUS 0x02 //ADDRESS
+#define APCI3120_WR_ADDRESS 0x00 //ADDRESS
+#define APCI3120_ENABLE_WATCHDOG 0x20 //$$BIT in nWrMode_Select
+#define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG)
+#define APCI3120_ENABLE_TIMER_COUNTER 0x10 //$$BIT in nWrMode_Select
+#define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER)
+#define APCI3120_FC_TIMER 0x1000 //bit in status register
+#define APCI3120_ENABLE_TIMER0 0x1000
+#define APCI3120_ENABLE_TIMER1 0x2000
+#define APCI3120_ENABLE_TIMER2 0x4000
+#define APCI3120_DISABLE_TIMER0 (~APCI3120_ENABLE_TIMER0)
+#define APCI3120_DISABLE_TIMER1 (~APCI3120_ENABLE_TIMER1)
+#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
+
+#define APCI3120_TIMER2_SELECT_EOS 0xC0 // ADDED on 20-6
+#define APCI3120_COUNTER 3 // on 20-6
+#define APCI3120_DISABLE_ALL_TIMER ( APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1 & APCI3120_DISABLE_TIMER2 ) // on 20-6
+
+#define MAX_ANALOGINPUT_CHANNELS 32
+
+typedef struct {
+ BYTE b_Type; /* EOC or EOS */
+ BYTE b_InterruptFlag; /* Interrupt use or not */
+ UINT ui_ConvertTiming; /* Selection of the convertion time */
+ BYTE b_NbrOfChannel; /* Number of channel to read */
+ UINT ui_ChannelList[MAX_ANALOGINPUT_CHANNELS]; /* Number of the channel to be read */
+ UINT ui_RangeList[MAX_ANALOGINPUT_CHANNELS]; /* Gain of each channel */
+
+} str_AnalogReadInformation;
+
+// Function Declaration For APCI-3120
+
+// Internal functions
+int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevice *s,
+ int n_chan, unsigned int *chanlist, char check);
+int i_APCI3120_ExttrigEnable(struct comedi_device *dev);
+int i_APCI3120_ExttrigDisable(struct comedi_device *dev);
+int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
+int i_APCI3120_Reset(struct comedi_device *dev);
+int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
+ struct comedi_subdevice *s);
+// Interrupt functions
+void v_APCI3120_Interrupt(int irq, void *d);
+//UPDATE-0.7.57->0.7.68 void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,struct comedi_subdevice *s,short *dma,short *data,int n);
+void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ short *dma_buffer,
+ unsigned int num_samples);
+int i_APCI3120_InterruptHandleEos(struct comedi_device *dev);
+void v_APCI3120_InterruptDma(int irq, void *d);
+
+// TIMER
+
+int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//DI
+// for di read
+
+int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//DO
+//int i_APCI3120_WriteDigitalOutput(struct comedi_device *dev, BYTE data);
+int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//AO
+//int i_APCI3120_Write1AnalogValue(struct comedi_device *dev,UINT ui_Range,UINT ui_Channel,UINT data );
+int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//AI HArdware layer
+
+int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd);
+int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
+//int i_APCI3120_CancelAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
+int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
new file mode 100644
index 00000000000..1ff66bee548
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -0,0 +1,3642 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-3200 | Compiler : GCC |
+ | Module name : hwdrv_apci3200.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-3200 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 02.07.04 | J. Krauth | Modification from the driver in order to |
+ | | | correct some errors when using several boards. |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+ | 26.10.04 | J. Krauth | - Update for COMEDI 0.7.68 |
+ | | | - Read eeprom value |
+ | | | - Append APCI-3300 |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
+ +----------------------------------------------------------------------------+
+ | Included files |
+ +----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci3200.h"
+//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+#include "addi_amcc_S5920.h"
+//#define PRINT_INFO
+
+//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+//BEGIN JK 06.07.04: Management of sevrals boards
+/*
+ INT i_CJCAvailable=1;
+ INT i_CJCPolarity=0;
+ INT i_CJCGain=2;//changed from 0 to 2
+ INT i_InterruptFlag=0;
+ INT i_ADDIDATAPolarity;
+ INT i_ADDIDATAGain;
+ INT i_AutoCalibration=0; //: auto calibration
+ INT i_ADDIDATAConversionTime;
+ INT i_ADDIDATAConversionTimeUnit;
+ INT i_ADDIDATAType;
+ INT i_ChannelNo;
+ INT i_ChannelCount=0;
+ INT i_ScanType;
+ INT i_FirstChannel;
+ INT i_LastChannel;
+ INT i_Sum=0;
+ INT i_Offset;
+ UINT ui_Channel_num=0;
+ static int i_Count=0;
+ INT i_Initialised=0;
+ UINT ui_InterruptChannelValue[96]; //Buffer
+*/
+str_BoardInfos s_BoardInfos[100]; // 100 will be the max number of boards to be used
+//END JK 06.07.04: Management of sevrals boards
+
+//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+/*+----------------------------------------------------------------------------+*/
+/*| Function Name : INT i_AddiHeaderRW_ReadEeprom |*/
+/*| (INT i_NbOfWordsToRead, |*/
+/*| DWORD dw_PCIBoardEepromAddress, |*/
+/*| WORD w_EepromStartAddress, |*/
+/*| PWORD pw_DataRead) |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Task : Read word from the 5920 eeprom. |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Input Parameters : INT i_NbOfWordsToRead : Nbr. of word to read |*/
+/*| DWORD dw_PCIBoardEepromAddress : Address of the eeprom |*/
+/*| WORD w_EepromStartAddress : Eeprom strat address |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Output Parameters : PWORD pw_DataRead : Read data |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Return Value : - |*/
+/*+----------------------------------------------------------------------------+*/
+
+INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
+ DWORD dw_PCIBoardEepromAddress,
+ WORD w_EepromStartAddress, PWORD pw_DataRead)
+{
+ DWORD dw_eeprom_busy = 0;
+ INT i_Counter = 0;
+ INT i_WordCounter;
+ INT i;
+ BYTE pb_ReadByte[1];
+ BYTE b_ReadLowByte = 0;
+ BYTE b_ReadHighByte = 0;
+ BYTE b_SelectedAddressLow = 0;
+ BYTE b_SelectedAddressHigh = 0;
+ WORD w_ReadWord = 0;
+
+ for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
+ i_WordCounter++) {
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ for (i_Counter = 0; i_Counter < 2; i_Counter++) {
+ b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256; //Read the low 8 bit part
+ b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256; //Read the high 8 bit part
+
+ //Select the load low address mode
+ outb(NVCMD_LOAD_LOW,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Load the low address
+ outb(b_SelectedAddressLow,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the load high address mode
+ outb(NVCMD_LOAD_HIGH,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Load the high address
+ outb(b_SelectedAddressHigh,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the READ mode
+ outb(NVCMD_BEGIN_READ,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Read data into the EEPROM
+ *pb_ReadByte =
+ inb(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR + 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the upper address part
+ if (i_Counter == 0) {
+ b_ReadLowByte = pb_ReadByte[0];
+ } else {
+ b_ReadHighByte = pb_ReadByte[0];
+ }
+
+ //Sleep
+ for (i = 0; i < 10000; i++) ;
+
+ }
+ w_ReadWord =
+ (b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
+ 256));
+
+ pw_DataRead[i_WordCounter] = w_ReadWord;
+
+ w_EepromStartAddress += 2; // to read the next word
+
+ } // for (...) i_NbOfWordsToRead
+ return (0);
+}
+
+/*+----------------------------------------------------------------------------+*/
+/*| Function Name : void v_GetAPCI3200EepromCalibrationValue (void) |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Task : Read calibration value from the APCI-3200 eeprom. |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Input Parameters : - |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Output Parameters : - |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Return Value : - |*/
+/*+----------------------------------------------------------------------------+*/
+
+void v_GetAPCI3200EepromCalibrationValue(DWORD dw_PCIBoardEepromAddress,
+ str_BoardInfos * BoardInformations)
+{
+ WORD w_AnalogInputMainHeaderAddress;
+ WORD w_AnalogInputComponentAddress;
+ WORD w_NumberOfModuls = 0;
+ WORD w_CurrentSources[2];
+ WORD w_ModulCounter = 0;
+ WORD w_FirstHeaderSize = 0;
+ WORD w_NumberOfInputs = 0;
+ WORD w_CJCFlag = 0;
+ WORD w_NumberOfGainValue = 0;
+ WORD w_SingleHeaderAddress = 0;
+ WORD w_SingleHeaderSize = 0;
+ WORD w_Input = 0;
+ WORD w_GainFactorAddress = 0;
+ WORD w_GainFactorValue[2];
+ WORD w_GainIndex = 0;
+ WORD w_GainValue = 0;
+
+ /*****************************************/
+ /** Get the Analog input header address **/
+ /*****************************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, 0x116, //w_EepromStartAddress: Analog input header address
+ &w_AnalogInputMainHeaderAddress);
+
+ /*******************************************/
+ /** Compute the real analog input address **/
+ /*******************************************/
+ w_AnalogInputMainHeaderAddress = w_AnalogInputMainHeaderAddress + 0x100;
+
+ /******************************/
+ /** Get the number of moduls **/
+ /******************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputMainHeaderAddress + 0x02, //w_EepromStartAddress: Number of conponment
+ &w_NumberOfModuls);
+
+ for (w_ModulCounter = 0; w_ModulCounter < w_NumberOfModuls;
+ w_ModulCounter++) {
+ /***********************************/
+ /** Compute the component address **/
+ /***********************************/
+ w_AnalogInputComponentAddress =
+ w_AnalogInputMainHeaderAddress +
+ (w_FirstHeaderSize * w_ModulCounter) + 0x04;
+
+ /****************************/
+ /** Read first header size **/
+ /****************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress, // Address of the first header
+ &w_FirstHeaderSize);
+
+ w_FirstHeaderSize = w_FirstHeaderSize >> 4;
+
+ /***************************/
+ /** Read number of inputs **/
+ /***************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x06, // Number of inputs for the first modul
+ &w_NumberOfInputs);
+
+ w_NumberOfInputs = w_NumberOfInputs >> 4;
+
+ /***********************/
+ /** Read the CJC flag **/
+ /***********************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x08, // CJC flag
+ &w_CJCFlag);
+
+ w_CJCFlag = (w_CJCFlag >> 3) & 0x1; // Get only the CJC flag
+
+ /*******************************/
+ /** Read number of gain value **/
+ /*******************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x44, // Number of gain value
+ &w_NumberOfGainValue);
+
+ w_NumberOfGainValue = w_NumberOfGainValue & 0xFF;
+
+ /***********************************/
+ /** Compute single header address **/
+ /***********************************/
+ w_SingleHeaderAddress =
+ w_AnalogInputComponentAddress + 0x46 +
+ (((w_NumberOfGainValue / 16) + 1) * 2) +
+ (6 * w_NumberOfGainValue) +
+ (4 * (((w_NumberOfGainValue / 16) + 1) * 2));
+
+ /********************************************/
+ /** Read current sources value for input 1 **/
+ /********************************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_SingleHeaderAddress, //w_EepromStartAddress: Single header address
+ &w_SingleHeaderSize);
+
+ w_SingleHeaderSize = w_SingleHeaderSize >> 4;
+
+ /*************************************/
+ /** Read gain factor for the module **/
+ /*************************************/
+ w_GainFactorAddress = w_AnalogInputComponentAddress;
+
+ for (w_GainIndex = 0; w_GainIndex < w_NumberOfGainValue;
+ w_GainIndex++) {
+ /************************************/
+ /** Read gain value for the module **/
+ /************************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + (2 * (1 + (w_NumberOfGainValue / 16))) + (0x02 * w_GainIndex), // Gain value
+ &w_GainValue);
+
+ BoardInformations->s_Module[w_ModulCounter].
+ w_GainValue[w_GainIndex] = w_GainValue;
+
+# ifdef PRINT_INFO
+ printk("\n Gain value = %d",
+ BoardInformations->s_Module[w_ModulCounter].
+ w_GainValue[w_GainIndex]);
+# endif
+
+ /*************************************/
+ /** Read gain factor for the module **/
+ /*************************************/
+ i_AddiHeaderRW_ReadEeprom(2, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + ((2 * w_NumberOfGainValue) + (2 * (1 + (w_NumberOfGainValue / 16)))) + (0x04 * w_GainIndex), // Gain factor
+ w_GainFactorValue);
+
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_GainFactor[w_GainIndex] =
+ (w_GainFactorValue[1] << 16) +
+ w_GainFactorValue[0];
+
+# ifdef PRINT_INFO
+ printk("\n w_GainFactorValue [%d] = %lu", w_GainIndex,
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_GainFactor[w_GainIndex]);
+# endif
+ }
+
+ /***************************************************************/
+ /** Read current source value for each channels of the module **/
+ /***************************************************************/
+ for (w_Input = 0; w_Input < w_NumberOfInputs; w_Input++) {
+ /********************************************/
+ /** Read current sources value for input 1 **/
+ /********************************************/
+ i_AddiHeaderRW_ReadEeprom(2, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress,
+ (w_Input * w_SingleHeaderSize) +
+ w_SingleHeaderAddress + 0x0C, w_CurrentSources);
+
+ /************************************/
+ /** Save the current sources value **/
+ /************************************/
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_CurrentSource[w_Input] =
+ (w_CurrentSources[0] +
+ ((w_CurrentSources[1] & 0xFFF) << 16));
+
+# ifdef PRINT_INFO
+ printk("\n Current sources [%d] = %lu", w_Input,
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_CurrentSource[w_Input]);
+# endif
+ }
+
+ /***************************************/
+ /** Read the CJC current source value **/
+ /***************************************/
+ i_AddiHeaderRW_ReadEeprom(2, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress,
+ (w_Input * w_SingleHeaderSize) + w_SingleHeaderAddress +
+ 0x0C, w_CurrentSources);
+
+ /************************************/
+ /** Save the current sources value **/
+ /************************************/
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_CurrentSourceCJC =
+ (w_CurrentSources[0] +
+ ((w_CurrentSources[1] & 0xFFF) << 16));
+
+# ifdef PRINT_INFO
+ printk("\n Current sources CJC = %lu",
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_CurrentSourceCJC);
+# endif
+ }
+}
+
+INT i_APCI3200_GetChannelCalibrationValue(struct comedi_device * dev,
+ unsigned int ui_Channel_num, unsigned int * CJCCurrentSource,
+ unsigned int * ChannelCurrentSource, unsigned int * ChannelGainFactor)
+{
+ int i_DiffChannel = 0;
+ int i_Module = 0;
+
+#ifdef PRINT_INFO
+ printk("\n Channel = %u", ui_Channel_num);
+#endif
+
+ //Test if single or differential mode
+ if (s_BoardInfos[dev->minor].i_ConnectionType == 1) {
+ //if diff
+
+ if ((ui_Channel_num >= 0) && (ui_Channel_num <= 1))
+ i_DiffChannel = ui_Channel_num, i_Module = 0;
+ else if ((ui_Channel_num >= 2) && (ui_Channel_num <= 3))
+ i_DiffChannel = ui_Channel_num - 2, i_Module = 1;
+ else if ((ui_Channel_num >= 4) && (ui_Channel_num <= 5))
+ i_DiffChannel = ui_Channel_num - 4, i_Module = 2;
+ else if ((ui_Channel_num >= 6) && (ui_Channel_num <= 7))
+ i_DiffChannel = ui_Channel_num - 6, i_Module = 3;
+
+ } else {
+ // if single
+ if ((ui_Channel_num == 0) || (ui_Channel_num == 1))
+ i_DiffChannel = 0, i_Module = 0;
+ else if ((ui_Channel_num == 2) || (ui_Channel_num == 3))
+ i_DiffChannel = 1, i_Module = 0;
+ else if ((ui_Channel_num == 4) || (ui_Channel_num == 5))
+ i_DiffChannel = 0, i_Module = 1;
+ else if ((ui_Channel_num == 6) || (ui_Channel_num == 7))
+ i_DiffChannel = 1, i_Module = 1;
+ else if ((ui_Channel_num == 8) || (ui_Channel_num == 9))
+ i_DiffChannel = 0, i_Module = 2;
+ else if ((ui_Channel_num == 10) || (ui_Channel_num == 11))
+ i_DiffChannel = 1, i_Module = 2;
+ else if ((ui_Channel_num == 12) || (ui_Channel_num == 13))
+ i_DiffChannel = 0, i_Module = 3;
+ else if ((ui_Channel_num == 14) || (ui_Channel_num == 15))
+ i_DiffChannel = 1, i_Module = 3;
+ }
+
+ //Test if thermocouple or RTD mode
+ *CJCCurrentSource =
+ s_BoardInfos[dev->minor].s_Module[i_Module].ul_CurrentSourceCJC;
+#ifdef PRINT_INFO
+ printk("\n CJCCurrentSource = %lu", *CJCCurrentSource);
+#endif
+
+ *ChannelCurrentSource =
+ s_BoardInfos[dev->minor].s_Module[i_Module].
+ ul_CurrentSource[i_DiffChannel];
+#ifdef PRINT_INFO
+ printk("\n ChannelCurrentSource = %lu", *ChannelCurrentSource);
+#endif
+ // }
+ // }
+
+ //Channle gain factor
+ *ChannelGainFactor =
+ s_BoardInfos[dev->minor].s_Module[i_Module].
+ ul_GainFactor[s_BoardInfos[dev->minor].i_ADDIDATAGain];
+#ifdef PRINT_INFO
+ printk("\n ChannelGainFactor = %lu", *ChannelGainFactor);
+#endif
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ return (0);
+}
+
+//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadDigitalInput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read value of the selected channel or port |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannels : No Of Channels To read for Port
+ Channel Numberfor single channel
+ | UINT data[0] : 0: Read single channel
+ 1: Read port value
+ data[1] Port number
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- data[0] :Read status value
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3200_ReadDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp = 0;
+ UINT ui_NoOfChannel = 0;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->i_IobaseReserved);
+
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } //if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ if (data[1] < 0 || data[1] > 1) {
+ printk("\nThe port number is in error\n");
+ return -EINVAL;
+ } //if(data[1] < 0 || data[1] >1)
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ *data = (*data >> (2 * data[1])) & 0x3;
+ break;
+ case 3:
+ *data = (*data & 15);
+ break;
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+ } //if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } //elseif (ui_Temp==1)
+ }
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ConfigDigitalOutput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Configures The Digital Output Subdevice. |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | data[0] :1 Memory enable
+ 0 Memory Disable
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ } //if ( (data[0]!=0) && (data[0]!=1) )
+ if (data[0]) {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+ } // if (data[0])
+ else {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+ } //else if (data[0])
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_WriteDigitalOutput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : writes To the digital Output Subdevice |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s : Subdevice Pointer |
+ | struct comedi_insn *insn : Insn Structure Pointer |
+ | unsigned int *data : Data Pointer contains |
+ | configuration parameters as below |
+ | data[0] :Value to output
+ data[1] : 0 o/p single channel
+ 1 o/p port
+ data[2] : port no
+ data[3] :0 set the digital o/p on
+ 1 set the digital o/p off
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp = 0, ui_Temp1 = 0;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp = inl(devpriv->i_IobaseAddon);
+
+ } //if(devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } //if(devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outl(data[0], devpriv->i_IobaseAddon);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+ case 3:
+ data[0] = (data[0] | ui_Temp);
+ break;
+ } //switch(ui_NoOfChannels)
+
+ outl(data[0], devpriv->i_IobaseAddon);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] = (data[0] << ui_NoOfChannel) ^ 0xf;
+ data[0] = data[0] & ui_Temp;
+ outl(data[0], devpriv->i_IobaseAddon);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xf) & ui_Temp;
+
+ break;
+ case 3:
+ break;
+
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //switch(ui_NoOfChannels)
+
+ outl(data[0], devpriv->i_IobaseAddon);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadDigitalOutput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read value of the selected channel or port |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannels : No Of Channels To read |
+ | UINT *data : Data Pointer to read status |
+ data[0] :0 read single channel
+ 1 read port value
+ data[1] port no
+
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->i_IobaseAddon);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } // if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ if (data[1] < 0 || data[1] > 1) {
+ printk("\nThe port selection is in error\n");
+ return -EINVAL;
+ } //if(data[1] <0 ||data[1] >1)
+ switch (ui_NoOfChannel) {
+ case 2:
+ *data = (*data >> (2 * data[1])) & 3;
+ break;
+
+ case 3:
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } // switch(ui_NoOfChannels)
+ } // if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } // else if (ui_Temp==1)
+ } // else if (ui_Temp==0)
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : INT i_APCI3200_ConfigAnalogInput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Configures The Analog Input Subdevice |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s : Subdevice Pointer |
+ | struct comedi_insn *insn : Insn Structure Pointer |
+ | unsigned int *data : Data Pointer contains |
+ | configuration parameters as below |
+ | |
+ | data[0]
+ | 0:Normal AI |
+ | 1:RTD |
+ | 2:THERMOCOUPLE |
+ | data[1] : Gain To Use |
+ | |
+ | data[2] : Polarity
+ | 0:Bipolar |
+ | 1:Unipolar |
+ | |
+ | data[3] : Offset Range
+ | |
+ | data[4] : Coupling
+ | 0:DC Coupling |
+ | 1:AC Coupling |
+ | |
+ | data[5] :Differential/Single
+ | 0:Single |
+ | 1:Differential |
+ | |
+ | data[6] :TimerReloadValue
+ | |
+ | data[7] :ConvertingTimeUnit
+ | |
+ | data[8] :0 Analog voltage measurement
+ 1 Resistance measurement
+ 2 Temperature measurement
+ | data[9] :Interrupt
+ | 0:Disable
+ | 1:Enable
+ data[10] :Type of Thermocouple
+ | data[11] : 0: single channel
+ Module Number
+ |
+ | data[12]
+ | 0:Single Read
+ | 1:Read more channel
+ 2:Single scan
+ | 3:Continous Scan
+ data[13] :Number of channels to read
+ | data[14] :RTD connection type
+ :0:RTD not used
+ 1:RTD 2 wire connection
+ 2:RTD 3 wire connection
+ 3:RTD 4 wire connection
+ | |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_ConfigAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ul_Config = 0, ul_Temp = 0;
+ UINT ui_ChannelNo = 0;
+ UINT ui_Dummy = 0;
+ INT i_err = 0;
+
+ //Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+#ifdef PRINT_INFO
+ INT i = 0, i2 = 0;
+#endif
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ // Initialize the structure
+ if (s_BoardInfos[dev->minor].b_StructInitialized != 1) {
+ s_BoardInfos[dev->minor].i_CJCAvailable = 1;
+ s_BoardInfos[dev->minor].i_CJCPolarity = 0;
+ s_BoardInfos[dev->minor].i_CJCGain = 2; //changed from 0 to 2
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ s_BoardInfos[dev->minor].i_AutoCalibration = 0; //: auto calibration
+ s_BoardInfos[dev->minor].i_ChannelCount = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ s_BoardInfos[dev->minor].ui_Channel_num = 0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].b_StructInitialized = 1;
+
+ //Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ s_BoardInfos[dev->minor].i_ConnectionType = 0;
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ //Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ memset(s_BoardInfos[dev->minor].s_Module, 0,
+ sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE]));
+
+ v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc,
+ &s_BoardInfos[dev->minor]);
+
+#ifdef PRINT_INFO
+ for (i = 0; i < MAX_MODULE; i++) {
+ printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i,
+ s_BoardInfos[dev->minor].s_Module[i].
+ ul_CurrentSourceCJC);
+
+ for (i2 = 0; i2 < 5; i2++) {
+ printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]);
+ }
+
+ for (i2 = 0; i2 < 8; i2++) {
+ printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]);
+ }
+
+ for (i2 = 0; i2 < 8; i2++) {
+ printk("\n s_Module[%i].w_GainValue [%i] = %u",
+ i, i2,
+ s_BoardInfos[dev->minor].s_Module[i].
+ w_GainValue[i2]);
+ }
+ }
+#endif
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ }
+
+ if (data[0] != 0 && data[0] != 1 && data[0] != 2) {
+ printk("\nThe selection of acquisition type is in error\n");
+ i_err++;
+ } //if(data[0]!=0 && data[0]!=1 && data[0]!=2)
+ if (data[0] == 1) {
+ if (data[14] != 0 && data[14] != 1 && data[14] != 2
+ && data[14] != 4) {
+ printk("\n Error in selection of RTD connection type\n");
+ i_err++;
+ } //if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4)
+ } //if(data[0]==1 )
+ if (data[1] < 0 || data[1] > 7) {
+ printk("\nThe selection of gain is in error\n");
+ i_err++;
+ } // if(data[1]<0 || data[1]>7)
+ if (data[2] != 0 && data[2] != 1) {
+ printk("\nThe selection of polarity is in error\n");
+ i_err++;
+ } //if(data[2]!=0 && data[2]!=1)
+ if (data[3] != 0) {
+ printk("\nThe selection of offset range is in error\n");
+ i_err++;
+ } // if(data[3]!=0)
+ if (data[4] != 0 && data[4] != 1) {
+ printk("\nThe selection of coupling is in error\n");
+ i_err++;
+ } //if(data[4]!=0 && data[4]!=1)
+ if (data[5] != 0 && data[5] != 1) {
+ printk("\nThe selection of single/differential mode is in error\n");
+ i_err++;
+ } //if(data[5]!=0 && data[5]!=1)
+ if (data[8] != 0 && data[8] != 1 && data[2] != 2) {
+ printk("\nError in selection of functionality\n");
+ } //if(data[8]!=0 && data[8]!=1 && data[2]!=2)
+ if (data[12] == 0 || data[12] == 1) {
+ if (data[6] != 20 && data[6] != 40 && data[6] != 80
+ && data[6] != 160) {
+ printk("\nThe selection of conversion time reload value is in error\n");
+ i_err++;
+ } // if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 )
+ if (data[7] != 2) {
+ printk("\nThe selection of conversion time unit is in error\n");
+ i_err++;
+ } // if(data[7]!=2)
+ }
+ if (data[9] != 0 && data[9] != 1) {
+ printk("\nThe selection of interrupt enable is in error\n");
+ i_err++;
+ } //if(data[9]!=0 && data[9]!=1)
+ if (data[11] < 0 || data[11] > 4) {
+ printk("\nThe selection of module is in error\n");
+ i_err++;
+ } //if(data[11] <0 || data[11]>1)
+ if (data[12] < 0 || data[12] > 3) {
+ printk("\nThe selection of singlechannel/scan selection is in error\n");
+ i_err++;
+ } //if(data[12] < 0 || data[12]> 3)
+ if (data[13] < 0 || data[13] > 16) {
+ printk("\nThe selection of number of channels is in error\n");
+ i_err++;
+ } // if(data[13] <0 ||data[13] >15)
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ /*
+ i_ChannelCount=data[13];
+ i_ScanType=data[12];
+ i_ADDIDATAPolarity = data[2];
+ i_ADDIDATAGain=data[1];
+ i_ADDIDATAConversionTime=data[6];
+ i_ADDIDATAConversionTimeUnit=data[7];
+ i_ADDIDATAType=data[0];
+ */
+
+ // Save acquisition configuration for the actual board
+ s_BoardInfos[dev->minor].i_ChannelCount = data[13];
+ s_BoardInfos[dev->minor].i_ScanType = data[12];
+ s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2];
+ s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1];
+ s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6];
+ s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7];
+ s_BoardInfos[dev->minor].i_ADDIDATAType = data[0];
+ //Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ s_BoardInfos[dev->minor].i_ConnectionType = data[5];
+ //End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //END JK 06.07.04: Management of sevrals boards
+
+ //Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int)); // 7 is the maximal number of channels
+ //End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ //BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards
+ //while(i_InterruptFlag==1)
+ while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
+#ifndef MSXBOX
+ udelay(1);
+#else
+ // In the case where the driver is compiled for the MSX-Box
+ // we used a printk to have a little delay because udelay
+ // seems to be broken under the MSX-Box.
+ // This solution hat to be studied.
+ printk("");
+#endif
+ }
+ //END JK 02.07.04 : This while can't be do, it block the process when using severals boards
+
+ ui_ChannelNo = CR_CHAN(insn->chanspec); // get the channel
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=ui_ChannelNo;
+ //ui_Channel_num =ui_ChannelNo;
+
+ s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo;
+ s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo;
+
+ //END JK 06.07.04: Management of sevrals boards
+
+ if (data[5] == 0) {
+ if (ui_ChannelNo < 0 || ui_ChannelNo > 15) {
+ printk("\nThe Selection of the channel is in error\n");
+ i_err++;
+ } // if(ui_ChannelNo<0 || ui_ChannelNo>15)
+ } //if(data[5]==0)
+ else {
+ if (data[14] == 2) {
+ if (ui_ChannelNo < 0 || ui_ChannelNo > 3) {
+ printk("\nThe Selection of the channel is in error\n");
+ i_err++;
+ } // if(ui_ChannelNo<0 || ui_ChannelNo>3)
+ } //if(data[14]==2)
+ else {
+ if (ui_ChannelNo < 0 || ui_ChannelNo > 7) {
+ printk("\nThe Selection of the channel is in error\n");
+ i_err++;
+ } // if(ui_ChannelNo<0 || ui_ChannelNo>7)
+ } //elseif(data[14]==2)
+ } //elseif(data[5]==0)
+ if (data[12] == 0 || data[12] == 1) {
+ switch (data[5]) {
+ case 0:
+ if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=0 && ui_ChannelNo <=3)
+ if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=64;
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=4 && ui_ChannelNo <=7)
+ if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=128;
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=8 && ui_ChannelNo <=11)
+ if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=192;
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=12 && ui_ChannelNo <=15)
+ break;
+ case 1:
+ if (data[14] == 2) {
+ if (ui_ChannelNo == 0) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo ==0 )
+ if (ui_ChannelNo == 1) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ //END JK 06.07.04: Management of sevrals boards
+ } // if(ui_ChannelNo ==1)
+ if (ui_ChannelNo == 2) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=128;
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo ==2 )
+ if (ui_ChannelNo == 3) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=192;
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo ==3)
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=0;
+ s_BoardInfos[dev->minor].i_ChannelNo = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ ui_ChannelNo = 0;
+ break;
+ } //if(data[14]==2)
+ if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=0 && ui_ChannelNo <=1)
+ if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=i_ChannelNo-2;
+ //i_Offset=64;
+ s_BoardInfos[dev->minor].i_ChannelNo =
+ s_BoardInfos[dev->minor].i_ChannelNo -
+ 2;
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ //END JK 06.07.04: Management of sevrals boards
+ ui_ChannelNo = ui_ChannelNo - 2;
+ } //if(ui_ChannelNo >=2 && ui_ChannelNo <=3)
+ if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=i_ChannelNo-4;
+ //i_Offset=128;
+ s_BoardInfos[dev->minor].i_ChannelNo =
+ s_BoardInfos[dev->minor].i_ChannelNo -
+ 4;
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ //END JK 06.07.04: Management of sevrals boards
+ ui_ChannelNo = ui_ChannelNo - 4;
+ } //if(ui_ChannelNo >=4 && ui_ChannelNo <=5)
+ if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=i_ChannelNo-6;
+ //i_Offset=192;
+ s_BoardInfos[dev->minor].i_ChannelNo =
+ s_BoardInfos[dev->minor].i_ChannelNo -
+ 6;
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ //END JK 06.07.04: Management of sevrals boards
+ ui_ChannelNo = ui_ChannelNo - 6;
+ } //if(ui_ChannelNo >=6 && ui_ChannelNo <=7)
+ break;
+
+ default:
+ printk("\n This selection of polarity does not exist\n");
+ i_err++;
+ } //switch(data[2])
+ } //if(data[12]==0 || data[12]==1)
+ else {
+ switch (data[11]) {
+ case 1:
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ break;
+ case 2:
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=64;
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ //END JK 06.07.04: Management of sevrals boards
+ break;
+ case 3:
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=128;
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ //END JK 06.07.04: Management of sevrals boards
+ break;
+ case 4:
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=192;
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ //END JK 06.07.04: Management of sevrals boards
+ break;
+ default:
+ printk("\nError in module selection\n");
+ i_err++;
+ } // switch(data[11])
+ } // elseif(data[12]==0 || data[12]==1)
+ if (i_err) {
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ }
+ //if(i_ScanType!=1)
+ if (s_BoardInfos[dev->minor].i_ScanType != 1) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Count=0;
+ //i_Sum=0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(i_ScanType!=1)
+
+ ul_Config =
+ data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) |
+ (data[4] << 9);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //END JK 06.07.04: Management of sevrals boards
+ /*********************************/
+ /* Write the channel to configure */
+ /*********************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4);
+ outl(0 | ui_ChannelNo,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //END JK 06.07.04: Management of sevrals boards
+ /**************************/
+ /* Reset the configuration */
+ /**************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //outl(0 , devpriv->iobase+i_Offset + 0x0);
+ outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //END JK 06.07.04: Management of sevrals boards
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //outl(ul_Config , devpriv->iobase+i_Offset + 0x0);
+ outl(ul_Config,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
+ //END JK 06.07.04: Management of sevrals boards
+
+ /***************************/
+ /*Reset the calibration bit */
+ /***************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ul_Temp = inl(devpriv->iobase+i_Offset + 12);
+ ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12);
+ outl((ul_Temp & 0xFFF9FFFF),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ //END JK 06.07.04: Management of sevrals boards
+
+ if (data[9] == 1) {
+ devpriv->tsk_Current = current;
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_InterruptFlag=1;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 1;
+ //END JK 06.07.04: Management of sevrals boards
+ } // if(data[9]==1)
+ else {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //else if(data[9]==1)
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Initialised=1;
+ s_BoardInfos[dev->minor].i_Initialised = 1;
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_ScanType==1)
+ if (s_BoardInfos[dev->minor].i_ScanType == 1)
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Sum=i_Sum+1;
+ s_BoardInfos[dev->minor].i_Sum =
+ s_BoardInfos[dev->minor].i_Sum + 1;
+ //END JK 06.07.04: Management of sevrals boards
+
+ insn->unused[0] = 0;
+ i_APCI3200_ReadAnalogInput(dev, s, insn, &ui_Dummy);
+ }
+
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadAnalogInput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read value of the selected channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannels : No Of Channels To read |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Digital Value Of Input |
+ | data[1] : Calibration Offset Value |
+ | data[2] : Calibration Gain Value
+ | data[3] : CJC value
+ | data[4] : CJC offset value
+ | data[5] : CJC gain value
+ | Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ | data[6] : CJC current source from eeprom
+ | data[7] : Channel current source from eeprom
+ | data[8] : Channle gain factor from eeprom
+ | End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_ReadAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_DummyValue = 0;
+ int i_ConvertCJCCalibration;
+ int i = 0;
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_Initialised==0)
+ if (s_BoardInfos[dev->minor].i_Initialised == 0)
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } //if(i_Initialised==0);
+
+#ifdef PRINT_INFO
+ printk("\n insn->unused[0] = %i", insn->unused[0]);
+#endif
+
+ switch (insn->unused[0]) {
+ case 0:
+
+ i_APCI3200_Read1AnalogInputChannel(dev, s, insn,
+ &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count+0]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 0] = ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+
+ //Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ i_APCI3200_GetChannelCalibrationValue(dev,
+ s_BoardInfos[dev->minor].ui_Channel_num,
+ &s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 6],
+ &s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 7],
+ &s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 8]);
+
+#ifdef PRINT_INFO
+ printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]);
+
+ printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]);
+
+ printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]);
+#endif
+
+ //End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1))
+ if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
+ && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_APCI3200_ReadCJCValue(dev, &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 3] = ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE))
+ else {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count + 3]=0;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 3] = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1))
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE))
+ if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE))
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_APCI3200_ReadCalibrationOffsetValue(dev,
+ &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 1] = ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+ i_APCI3200_ReadCalibrationGainValue(dev,
+ &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 2] = ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE))
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1))
+ if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
+ && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ /**********************************************************/
+ /*Test if the Calibration channel must be read for the CJC */
+ /**********************************************************/
+ /**********************************/
+ /*Test if the polarity is the same */
+ /**********************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ if (s_BoardInfos[dev->minor].i_CJCPolarity !=
+ s_BoardInfos[dev->minor].i_ADDIDATAPolarity)
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_ConvertCJCCalibration = 1;
+ } //if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ else {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_CJCGain==i_ADDIDATAGain)
+ if (s_BoardInfos[dev->minor].i_CJCGain ==
+ s_BoardInfos[dev->minor].i_ADDIDATAGain)
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_ConvertCJCCalibration = 0;
+ } //if(i_CJCGain==i_ADDIDATAGain)
+ else {
+ i_ConvertCJCCalibration = 1;
+ } //elseif(i_CJCGain==i_ADDIDATAGain)
+ } //elseif(i_CJCPolarity!=i_ADDIDATAPolarity)
+ if (i_ConvertCJCCalibration == 1) {
+ i_APCI3200_ReadCJCCalOffset(dev,
+ &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count+4]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 4] =
+ ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+
+ i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue);
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count+5]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 5] =
+ ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(i_ConvertCJCCalibration==1)
+ else {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count+4]=0;
+ //ui_InterruptChannelValue[i_Count+5]=0;
+
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 4] = 0;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 5] = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //elseif(i_ConvertCJCCalibration==1)
+ } //if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE))
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_ScanType!=1)
+ if (s_BoardInfos[dev->minor].i_ScanType != 1) {
+ //i_Count=0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ } //if(i_ScanType!=1)
+ else {
+ //i_Count=i_Count +6;
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6;
+ s_BoardInfos[dev->minor].i_Count =
+ s_BoardInfos[dev->minor].i_Count + 9;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ } //else if(i_ScanType!=1)
+
+ //if((i_ScanType==1) &&(i_InterruptFlag==1))
+ if ((s_BoardInfos[dev->minor].i_ScanType == 1)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) {
+ //i_Count=i_Count-6;
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6;
+ s_BoardInfos[dev->minor].i_Count =
+ s_BoardInfos[dev->minor].i_Count - 9;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ }
+ //if(i_ScanType==0)
+ if (s_BoardInfos[dev->minor].i_ScanType == 0) {
+ /*
+ data[0]= ui_InterruptChannelValue[0];
+ data[1]= ui_InterruptChannelValue[1];
+ data[2]= ui_InterruptChannelValue[2];
+ data[3]= ui_InterruptChannelValue[3];
+ data[4]= ui_InterruptChannelValue[4];
+ data[5]= ui_InterruptChannelValue[5];
+ */
+#ifdef PRINT_INFO
+ printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];");
+#endif
+ data[0] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[0];
+ data[1] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[1];
+ data[2] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[2];
+ data[3] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[3];
+ data[4] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[4];
+ data[5] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[5];
+
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]);
+ i_APCI3200_GetChannelCalibrationValue(dev,
+ s_BoardInfos[dev->minor].ui_Channel_num,
+ &data[6], &data[7], &data[8]);
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ }
+ break;
+ case 1:
+
+ for (i = 0; i < insn->n; i++) {
+ //data[i]=ui_InterruptChannelValue[i];
+ data[i] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[i];
+ }
+
+ //i_Count=0;
+ //i_Sum=0;
+ //if(i_ScanType==1)
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ if (s_BoardInfos[dev->minor].i_ScanType == 1) {
+ //i_Initialised=0;
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ }
+ break;
+ default:
+ printk("\nThe parameters passed are in error\n");
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } //switch(insn->unused[0])
+
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_Read1AnalogInputChannel |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read value of the selected channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannel : Channel No to read |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Digital Value read |
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_Read1AnalogInputChannel(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_EOC = 0;
+ UINT ui_ChannelNo = 0;
+ UINT ui_CommandRegister = 0;
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_ChannelNo=i_ChannelNo;
+ ui_ChannelNo = s_BoardInfos[dev->minor].i_ChannelNo;
+
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ /*********************************/
+ /* Write the channel to configure */
+ /*********************************/
+ //Begin JK 20.10.2004: Bad channel value is used when using differential mode
+ //outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+ //outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4);
+ outl(0 | s_BoardInfos[dev->minor].i_ChannelNo,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
+ //End JK 20.10.2004: Bad channel value is used when using differential mode
+
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+
+ /**************************************************************************/
+ /* Set the start end stop index to the selected channel and set the start */
+ /**************************************************************************/
+
+ ui_CommandRegister = ui_ChannelNo | (ui_ChannelNo << 8) | 0x80000;
+
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+ /************************/
+ /* Enable the interrupt */
+ /************************/
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+ } //if (i_InterruptFlag == ADDIDATA_ENABLE)
+
+ /******************************/
+ /* Write the command register */
+ /******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable */
+ /*****************************/
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ do {
+ /*************************/
+ /*Read the EOC Status bit */
+ /*************************/
+
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /***************************************/
+ /* Read the digital value of the input */
+ /***************************************/
+
+ //data[0] = inl (devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ //END JK 06.07.04: Management of sevrals boards
+
+ } // if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCalibrationOffsetValue |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read calibration offset value of the selected channel|
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Calibration offset Value |
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device * dev, UINT * data)
+{
+ UINT ui_Temp = 0, ui_EOC = 0;
+ UINT ui_CommandRegister = 0;
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ /*********************************/
+ /* Write the channel to configure */
+ /*********************************/
+ //Begin JK 20.10.2004: This seems not necessary !
+ //outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+ //outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4);
+ //End JK 20.10.2004: This seems not necessary !
+
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+ /*****************************/
+ /*Read the calibration offset */
+ /*****************************/
+ //ui_Temp = inl(devpriv->iobase+i_Offset + 12);
+ ui_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+
+ /*********************************/
+ /*Configure the Offset Conversion */
+ /*********************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((ui_Temp | 0x00020000), devpriv->iobase+i_Offset + 12);
+ outl((ui_Temp | 0x00020000),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ /*******************************/
+ /*Initialise ui_CommandRegister */
+ /*******************************/
+
+ ui_CommandRegister = 0;
+
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+
+ } //if (i_InterruptFlag == ADDIDATA_ENABLE)
+
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable */
+ /*****************************/
+
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+
+ do {
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+
+ //ui_EOC = inl (devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /**************************************************/
+ /*Read the digital value of the calibration Offset */
+ /**************************************************/
+
+ //data[0] = inl(devpriv->iobase+i_Offset+ 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCalibrationGainValue |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read calibration gain value of the selected channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Calibration gain Value Of Input |
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCalibrationGainValue(struct comedi_device * dev, UINT * data)
+{
+ UINT ui_EOC = 0;
+ INT ui_CommandRegister = 0;
+
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ /*********************************/
+ /* Write the channel to configure */
+ /*********************************/
+ //Begin JK 20.10.2004: This seems not necessary !
+ //outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+ //outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4);
+ //End JK 20.10.2004: This seems not necessary !
+
+ /***************************/
+ /*Read the calibration gain */
+ /***************************/
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+ /*******************************/
+ /*Configure the Gain Conversion */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00040000 , devpriv->iobase+i_Offset + 12);
+ outl(0x00040000,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+
+ /*******************************/
+ /*Initialise ui_CommandRegister */
+ /*******************************/
+
+ ui_CommandRegister = 0;
+
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+
+ } //if (i_InterruptFlag == ADDIDATA_ENABLE)
+
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable */
+ /*****************************/
+
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+
+ do {
+
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /************************************************/
+ /*Read the digital value of the calibration Gain */
+ /************************************************/
+
+ //data[0] = inl(devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCJCValue |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read CJC value of the selected channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : CJC Value |
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_ReadCJCValue(struct comedi_device * dev, unsigned int * data)
+{
+ UINT ui_EOC = 0;
+ INT ui_CommandRegister = 0;
+
+ /******************************/
+ /*Set the converting time unit */
+ /******************************/
+
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+
+ /******************************/
+ /*Configure the CJC Conversion */
+ /******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl( 0x00000400 , devpriv->iobase+i_Offset + 4);
+ outl(0x00000400,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /*******************************/
+ /*Initialise dw_CommandRegister */
+ /*******************************/
+ ui_CommandRegister = 0;
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+ }
+
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable */
+ /*****************************/
+
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ do {
+
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /***********************************/
+ /*Read the digital value of the CJC */
+ /***********************************/
+
+ //data[0] = inl(devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCJCCalOffset |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read CJC calibration offset value of the selected channel
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : CJC calibration offset Value
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCJCCalOffset(struct comedi_device * dev, unsigned int * data)
+{
+ UINT ui_EOC = 0;
+ INT ui_CommandRegister = 0;
+ /*******************************************/
+ /*Read calibration offset value for the CJC */
+ /*******************************************/
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+ /******************************/
+ /*Configure the CJC Conversion */
+ /******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00000400 , devpriv->iobase+i_Offset + 4);
+ outl(0x00000400,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /*********************************/
+ /*Configure the Offset Conversion */
+ /*********************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00020000, devpriv->iobase+i_Offset + 12);
+ outl(0x00020000,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ /*******************************/
+ /*Initialise ui_CommandRegister */
+ /*******************************/
+ ui_CommandRegister = 0;
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+
+ }
+
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister,devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ do {
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+ } while (ui_EOC != 1);
+
+ /**************************************************/
+ /*Read the digital value of the calibration Offset */
+ /**************************************************/
+ //data[0] = inl(devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCJCGainValue |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read CJC calibration gain value
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannels : No Of Channels To read |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : CJC calibration gain value
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCJCCalGain(struct comedi_device * dev, unsigned int * data)
+{
+ UINT ui_EOC = 0;
+ INT ui_CommandRegister = 0;
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+ /******************************/
+ /*Configure the CJC Conversion */
+ /******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00000400,devpriv->iobase+i_Offset + 4);
+ outl(0x00000400,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /*******************************/
+ /*Configure the Gain Conversion */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00040000,devpriv->iobase+i_Offset + 12);
+ outl(0x00040000,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+
+ /*******************************/
+ /*Initialise dw_CommandRegister */
+ /*******************************/
+ ui_CommandRegister = 0;
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+ }
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister ,devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ do {
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+ } while (ui_EOC != 1);
+ /************************************************/
+ /*Read the digital value of the calibration Gain */
+ /************************************************/
+ //data[0] = inl (devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_InsnBits_AnalogInput_Test |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Tests the Selected Anlog Input Channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s : Subdevice Pointer |
+ | struct comedi_insn *insn : Insn Structure Pointer |
+ | unsigned int *data : Data Pointer contains |
+ | configuration parameters as below |
+ |
+ |
+ | data[0] : 0 TestAnalogInputShortCircuit
+ | 1 TestAnalogInputConnection |
+
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Digital value obtained |
+ | data[1] : calibration offset |
+ | data[2] : calibration gain |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Configuration = 0;
+ INT i_Temp; //,i_TimeUnit;
+ //if(i_Initialised==0)
+
+ if (s_BoardInfos[dev->minor].i_Initialised == 0) {
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } //if(i_Initialised==0);
+ if (data[0] != 0 && data[0] != 1) {
+ printk("\nError in selection of functionality\n");
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } //if(data[0]!=0 && data[0]!=1)
+
+ if (data[0] == 1) //Perform Short Circuit TEST
+ {
+ /**************************/
+ /*Set the short-cicuit bit */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+ i_Offset + 12) >> 19) & 1) !=
+ 1) ;
+ //outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ outl((0x00001000 | s_BoardInfos[dev->minor].i_ChannelNo),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 4);
+ /*************************/
+ /*Set the time unit to ns */
+ /*************************/
+ /* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
+ i_ADDIDATAConversionTimeUnit= 1; */
+ //i_Temp= i_InterruptFlag ;
+ i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
+ //i_InterruptFlag = ADDIDATA_DISABLE;
+ s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
+ i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
+ //if(i_AutoCalibration == FALSE)
+ if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+ i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ outl((0x00001000 | s_BoardInfos[dev->minor].
+ i_ChannelNo),
+ devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 4);
+ data++;
+ i_APCI3200_ReadCalibrationOffsetValue(dev, data);
+ data++;
+ i_APCI3200_ReadCalibrationGainValue(dev, data);
+ }
+ } else {
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+ i_Offset + 12) >> 19) & 1) !=
+ 1) ;
+ //outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ outl((0x00000800 | s_BoardInfos[dev->minor].i_ChannelNo),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 4);
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 0);
+ ui_Configuration =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 0);
+ /*************************/
+ /*Set the time unit to ns */
+ /*************************/
+ /* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
+ i_ADDIDATAConversionTimeUnit= 1; */
+ //i_Temp= i_InterruptFlag ;
+ i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
+ //i_InterruptFlag = ADDIDATA_DISABLE;
+ s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
+ i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
+ //if(i_AutoCalibration == FALSE)
+ if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+ i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ outl((0x00000800 | s_BoardInfos[dev->minor].
+ i_ChannelNo),
+ devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 4);
+ data++;
+ i_APCI3200_ReadCalibrationOffsetValue(dev, data);
+ data++;
+ i_APCI3200_ReadCalibrationGainValue(dev, data);
+ }
+ }
+ //i_InterruptFlag=i_Temp ;
+ s_BoardInfos[dev->minor].i_InterruptFlag = i_Temp;
+ //printk("\ni_InterruptFlag=%d\n",i_InterruptFlag);
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_InsnWriteReleaseAnalogInput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Resets the channels |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s : Subdevice Pointer |
+ | struct comedi_insn *insn : Insn Structure Pointer |
+ | unsigned int *data : Data Pointer
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ i_APCI3200_Reset(dev);
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function name :int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev|
+ | ,struct comedi_subdevice *s,struct comedi_cmd *cmd) |
+ | |
+ +----------------------------------------------------------------------------+
+ | Task : Test validity for a command for cyclic anlog input |
+ | acquisition |
+ | |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev |
+ | struct comedi_subdevice *s |
+ | struct comedi_cmd *cmd |
+ | |
+ |
+ | |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value :0 |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_CommandTestAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+
+ int err = 0;
+ int tmp; // divisor1,divisor2;
+ UINT ui_ConvertTime = 0;
+ UINT ui_ConvertTimeBase = 0;
+ UINT ui_DelayTime = 0;
+ UINT ui_DelayTimeBase = 0;
+ INT i_Triggermode = 0;
+ INT i_TriggerEdge = 0;
+ INT i_NbrOfChannel = 0;
+ INT i_Cpt = 0;
+ double d_ConversionTimeForAllChannels = 0.0;
+ double d_SCANTimeNewUnit = 0.0;
+ // step 1: make sure trigger sources are trivially valid
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+ //if(i_InterruptFlag==0)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
+ err++;
+ // printk("\nThe interrupt should be enabled\n");
+ }
+ if (err) {
+ i_APCI3200_Reset(dev);
+ return 1;
+ }
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
+ err++;
+ }
+ if (cmd->start_src == TRIG_EXT) {
+ i_TriggerEdge = cmd->start_arg & 0xFFFF;
+ i_Triggermode = cmd->start_arg >> 16;
+ if (i_TriggerEdge < 1 || i_TriggerEdge > 3) {
+ err++;
+ printk("\nThe trigger edge selection is in error\n");
+ }
+ if (i_Triggermode != 2) {
+ err++;
+ printk("\nThe trigger mode selection is in error\n");
+ }
+ }
+
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+
+ if (cmd->convert_src != TRIG_TIMER)
+ err++;
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ if (err) {
+ i_APCI3200_Reset(dev);
+ return 2;
+ }
+ //i_FirstChannel=cmd->chanlist[0];
+ s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
+ //i_LastChannel=cmd->chanlist[1];
+ s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1];
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ ui_ConvertTime = cmd->convert_arg & 0xFFFF;
+ ui_ConvertTimeBase = cmd->convert_arg >> 16;
+ if (ui_ConvertTime != 20 && ui_ConvertTime != 40
+ && ui_ConvertTime != 80 && ui_ConvertTime != 160)
+ {
+ printk("\nThe selection of conversion time reload value is in error\n");
+ err++;
+ } // if (ui_ConvertTime!=20 && ui_ConvertTime!=40 && ui_ConvertTime!=80 && ui_ConvertTime!=160 )
+ if (ui_ConvertTimeBase != 2) {
+ printk("\nThe selection of conversion time unit is in error\n");
+ err++;
+ } //if(ui_ConvertTimeBase!=2)
+ } else {
+ ui_ConvertTime = 0;
+ ui_ConvertTimeBase = 0;
+ }
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ ui_DelayTime = 0;
+ ui_DelayTimeBase = 0;
+ } //if(cmd->scan_begin_src==TRIG_FOLLOW)
+ else {
+ ui_DelayTime = cmd->scan_begin_arg & 0xFFFF;
+ ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
+ if (ui_DelayTimeBase != 2 && ui_DelayTimeBase != 3) {
+ err++;
+ printk("\nThe Delay time base selection is in error\n");
+ }
+ if (ui_DelayTime < 1 && ui_DelayTime > 1023) {
+ err++;
+ printk("\nThe Delay time value is in error\n");
+ }
+ if (err) {
+ i_APCI3200_Reset(dev);
+ return 3;
+ }
+ fpu_begin();
+ d_SCANTimeNewUnit = (double)ui_DelayTime;
+ //i_NbrOfChannel= i_LastChannel-i_FirstChannel + 4;
+ i_NbrOfChannel =
+ s_BoardInfos[dev->minor].i_LastChannel -
+ s_BoardInfos[dev->minor].i_FirstChannel + 4;
+ /**********************************************************/
+ /*calculate the total conversion time for all the channels */
+ /**********************************************************/
+ d_ConversionTimeForAllChannels =
+ (double)((double)ui_ConvertTime /
+ (double)i_NbrOfChannel);
+
+ /*******************************/
+ /*Convert the frequence in time */
+ /*******************************/
+ d_ConversionTimeForAllChannels =
+ (double)1.0 / d_ConversionTimeForAllChannels;
+ ui_ConvertTimeBase = 3;
+ /***********************************/
+ /*Test if the time unit is the same */
+ /***********************************/
+
+ if (ui_DelayTimeBase <= ui_ConvertTimeBase) {
+
+ for (i_Cpt = 0;
+ i_Cpt < (ui_ConvertTimeBase - ui_DelayTimeBase);
+ i_Cpt++) {
+
+ d_ConversionTimeForAllChannels =
+ d_ConversionTimeForAllChannels * 1000;
+ d_ConversionTimeForAllChannels =
+ d_ConversionTimeForAllChannels + 1;
+ }
+ } else {
+ for (i_Cpt = 0;
+ i_Cpt < (ui_DelayTimeBase - ui_ConvertTimeBase);
+ i_Cpt++) {
+ d_SCANTimeNewUnit = d_SCANTimeNewUnit * 1000;
+
+ }
+ }
+
+ if (d_ConversionTimeForAllChannels >= d_SCANTimeNewUnit) {
+
+ printk("\nSCAN Delay value cannot be used\n");
+ /*********************************/
+ /*SCAN Delay value cannot be used */
+ /*********************************/
+ err++;
+ }
+ fpu_end();
+ } //else if(cmd->scan_begin_src==TRIG_FOLLOW)
+
+ if (err) {
+ i_APCI3200_Reset(dev);
+ return 4;
+ }
+
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function name :int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev,|
+ | struct comedi_subdevice *s)|
+ | |
+ +----------------------------------------------------------------------------+
+ | Task : Stop the acquisition |
+ | |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev |
+ | struct comedi_subdevice *s |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value :0 |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_StopCyclicAcquisition(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ UINT ui_Configuration = 0;
+ //i_InterruptFlag=0;
+ //i_Initialised=0;
+ //i_Count=0;
+ //i_Sum=0;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+
+ /*******************/
+ /*Read the register */
+ /*******************/
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 8);
+ ui_Configuration =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ /*****************************/
+ /*Reset the START and IRQ bit */
+ /*****************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((ui_Configuration & 0xFFE7FFFF),devpriv->iobase+i_Offset + 8);
+ outl((ui_Configuration & 0xFFE7FFFF),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function name : int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, |
+ | struct comedi_subdevice *s) |
+ | |
+ +----------------------------------------------------------------------------+
+ | Task : Does asynchronous acquisition |
+ | Determines the mode 1 or 2. |
+ | |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev |
+ | struct comedi_subdevice *s |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value : |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_CommandAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ UINT ui_Configuration = 0;
+ //INT i_CurrentSource = 0;
+ UINT ui_Trigger = 0;
+ UINT ui_TriggerEdge = 0;
+ UINT ui_Triggermode = 0;
+ UINT ui_ScanMode = 0;
+ UINT ui_ConvertTime = 0;
+ UINT ui_ConvertTimeBase = 0;
+ UINT ui_DelayTime = 0;
+ UINT ui_DelayTimeBase = 0;
+ UINT ui_DelayMode = 0;
+ //i_FirstChannel=cmd->chanlist[0];
+ //i_LastChannel=cmd->chanlist[1];
+ s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
+ s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1];
+ if (cmd->start_src == TRIG_EXT) {
+ ui_Trigger = 1;
+ ui_TriggerEdge = cmd->start_arg & 0xFFFF;
+ ui_Triggermode = cmd->start_arg >> 16;
+ } //if(cmd->start_src==TRIG_EXT)
+ else {
+ ui_Trigger = 0;
+ } //elseif(cmd->start_src==TRIG_EXT)
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ ui_ScanMode = 0;
+ } // if (cmd->stop_src==TRIG_COUNT)
+ else {
+ ui_ScanMode = 2;
+ } //else if (cmd->stop_src==TRIG_COUNT)
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ ui_DelayTime = 0;
+ ui_DelayTimeBase = 0;
+ ui_DelayMode = 0;
+ } //if(cmd->scan_begin_src==TRIG_FOLLOW)
+ else {
+ ui_DelayTime = cmd->scan_begin_arg & 0xFFFF;
+ ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
+ ui_DelayMode = 1;
+ } //else if(cmd->scan_begin_src==TRIG_FOLLOW)
+ // printk("\nui_DelayTime=%u\n",ui_DelayTime);
+ // printk("\nui_DelayTimeBase=%u\n",ui_DelayTimeBase);
+ if (cmd->convert_src == TRIG_TIMER) {
+ ui_ConvertTime = cmd->convert_arg & 0xFFFF;
+ ui_ConvertTimeBase = cmd->convert_arg >> 16;
+ } else {
+ ui_ConvertTime = 0;
+ ui_ConvertTimeBase = 0;
+ }
+
+ // if(i_ADDIDATAType ==1 || ((i_ADDIDATAType==2)))
+ // {
+ /**************************************************/
+ /*Read the old configuration of the current source */
+ /**************************************************/
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 12);
+ ui_Configuration =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ /***********************************************/
+ /*Write the configuration of the current source */
+ /***********************************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((ui_Configuration & 0xFFC00000 ), devpriv->iobase+i_Offset +12);
+ outl((ui_Configuration & 0xFFC00000),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ // }
+ ui_Configuration = 0;
+ // printk("\nfirstchannel=%u\n",i_FirstChannel);
+ // printk("\nlastchannel=%u\n",i_LastChannel);
+ // printk("\nui_Trigger=%u\n",ui_Trigger);
+ // printk("\nui_TriggerEdge=%u\n",ui_TriggerEdge);
+ // printk("\nui_Triggermode=%u\n",ui_Triggermode);
+ // printk("\nui_DelayMode=%u\n",ui_DelayMode);
+ // printk("\nui_ScanMode=%u\n",ui_ScanMode);
+
+ //ui_Configuration = i_FirstChannel |(i_LastChannel << 8)| 0x00100000 |
+ ui_Configuration =
+ s_BoardInfos[dev->minor].i_FirstChannel | (s_BoardInfos[dev->
+ minor].
+ i_LastChannel << 8) | 0x00100000 | (ui_Trigger << 24) |
+ (ui_TriggerEdge << 25) | (ui_Triggermode << 27) | (ui_DelayMode
+ << 18) | (ui_ScanMode << 16);
+
+ /*************************/
+ /*Write the Configuration */
+ /*************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl( ui_Configuration, devpriv->iobase+i_Offset + 0x8);
+ outl(ui_Configuration,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x8);
+ /***********************/
+ /*Write the Delay Value */
+ /***********************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_DelayTime,devpriv->iobase+i_Offset + 40);
+ outl(ui_DelayTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 40);
+ /***************************/
+ /*Write the Delay time base */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_DelayTimeBase,devpriv->iobase+i_Offset + 44);
+ outl(ui_DelayTimeBase,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 44);
+ /*********************************/
+ /*Write the conversion time value */
+ /*********************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_ConvertTime,devpriv->iobase+i_Offset + 32);
+ outl(ui_ConvertTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+
+ /********************************/
+ /*Write the conversion time base */
+ /********************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_ConvertTimeBase,devpriv->iobase+i_Offset + 36);
+ outl(ui_ConvertTimeBase,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /*******************/
+ /*Read the register */
+ /*******************/
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 4);
+ ui_Configuration =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /******************/
+ /*Set the SCAN bit */
+ /******************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(((ui_Configuration & 0x1E0FF) | 0x00002000),devpriv->iobase+i_Offset + 4);
+ outl(((ui_Configuration & 0x1E0FF) | 0x00002000),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /*******************/
+ /*Read the register */
+ /*******************/
+ ui_Configuration = 0;
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 8);
+ ui_Configuration =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*******************/
+ /*Set the START bit */
+ /*******************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((ui_Configuration | 0x00080000),devpriv->iobase+i_Offset + 8);
+ outl((ui_Configuration | 0x00080000),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_Reset(struct comedi_device *dev) |
+ | |
+ +----------------------------------------------------------------------------+
+ | Task :Resets the registers of the card |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_Reset(struct comedi_device * dev)
+{
+ INT i_Temp;
+ DWORD dw_Dummy;
+ //i_InterruptFlag=0;
+ //i_Initialised==0;
+ //i_Count=0;
+ //i_Sum=0;
+
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ s_BoardInfos[dev->minor].b_StructInitialized = 0;
+
+ outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
+
+ // Enable the interrupt for the controler
+ dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
+ outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
+ outl(0, devpriv->i_IobaseAddon); //Resets the output
+ /***************/
+ /*Empty the buffer */
+ /**************/
+ for (i_Temp = 0; i_Temp <= 95; i_Temp++) {
+ //ui_InterruptChannelValue[i_Temp]=0;
+ s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0;
+ } //for(i_Temp=0;i_Temp<=95;i_Temp++)
+ /*****************************/
+ /*Reset the START and IRQ bit */
+ /*****************************/
+ for (i_Temp = 0; i_Temp <= 192;) {
+ while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ;
+ outl(0, devpriv->iobase + i_Temp + 8);
+ i_Temp = i_Temp + 64;
+ } //for(i_Temp=0;i_Temp<=192;i_Temp+64)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : static void v_APCI3200_Interrupt |
+ | (int irq , void *d) |
+ +----------------------------------------------------------------------------+
+ | Task : Interrupt processing Routine |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : int irq : irq number |
+ | void *d : void pointer |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+void v_APCI3200_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ UINT ui_StatusRegister = 0;
+ UINT ui_ChannelNumber = 0;
+ INT i_CalibrationFlag = 0;
+ INT i_CJCFlag = 0;
+ UINT ui_DummyValue = 0;
+ UINT ui_DigitalTemperature = 0;
+ UINT ui_DigitalInput = 0;
+ int i_ConvertCJCCalibration;
+
+ //BEGIN JK TEST
+ int i_ReturnValue = 0;
+ //END JK TEST
+
+ //printk ("\n i_ScanType = %i i_ADDIDATAType = %i", s_BoardInfos [dev->minor].i_ScanType, s_BoardInfos [dev->minor].i_ADDIDATAType);
+
+ //switch(i_ScanType)
+ switch (s_BoardInfos[dev->minor].i_ScanType) {
+ case 0:
+ case 1:
+ //switch(i_ADDIDATAType)
+ switch (s_BoardInfos[dev->minor].i_ADDIDATAType) {
+ case 0:
+ case 1:
+
+ /************************************/
+ /*Read the interrupt status register */
+ /************************************/
+ //ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+ ui_StatusRegister =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 16);
+ if ((ui_StatusRegister & 0x2) == 0x2) {
+ //i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17);
+ i_CalibrationFlag =
+ ((inl(devpriv->iobase +
+ s_BoardInfos[dev->
+ minor].
+ i_Offset +
+ 12) & 0x00060000) >>
+ 17);
+ /*************************/
+ /*Read the channel number */
+ /*************************/
+ //ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+
+ /*************************************/
+ /*Read the digital analog input value */
+ /*************************************/
+ //ui_DigitalInput = inl(devpriv->iobase+i_Offset + 28);
+ ui_DigitalInput =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+
+ /***********************************************/
+ /* Test if the value read is the channel value */
+ /***********************************************/
+ if (i_CalibrationFlag == 0) {
+ //ui_InterruptChannelValue[i_Count + 0] = ui_DigitalInput;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 0] = ui_DigitalInput;
+
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ /*
+ printk("\n 1 - i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos %i", ui_ChannelNumber);
+ i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos [dev->minor].ui_Channel_num,
+ &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 6],
+ &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 7],
+ &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 8]);
+ */
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ /******************************************************/
+ /*Start the conversion of the calibration offset value */
+ /******************************************************/
+ i_APCI3200_ReadCalibrationOffsetValue
+ (dev, &ui_DummyValue);
+ } //if (i_CalibrationFlag == 0)
+ /**********************************************************/
+ /* Test if the value read is the calibration offset value */
+ /**********************************************************/
+
+ if (i_CalibrationFlag == 1) {
+
+ /******************/
+ /* Save the value */
+ /******************/
+
+ //ui_InterruptChannelValue[i_Count + 1] = ui_DigitalInput;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 1] = ui_DigitalInput;
+
+ /******************************************************/
+ /* Start the conversion of the calibration gain value */
+ /******************************************************/
+ i_APCI3200_ReadCalibrationGainValue(dev,
+ &ui_DummyValue);
+ } //if (i_CalibrationFlag == 1)
+ /******************************************************/
+ /*Test if the value read is the calibration gain value */
+ /******************************************************/
+
+ if (i_CalibrationFlag == 2) {
+
+ /****************/
+ /*Save the value */
+ /****************/
+ //ui_InterruptChannelValue[i_Count + 2] = ui_DigitalInput;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 2] = ui_DigitalInput;
+ //if(i_ScanType==1)
+ if (s_BoardInfos[dev->minor].
+ i_ScanType == 1) {
+
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].
+ i_InterruptFlag = 0;
+ //i_Count=i_Count + 6;
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6;
+ s_BoardInfos[dev->minor].
+ i_Count =
+ s_BoardInfos[dev->
+ minor].i_Count + 9;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ } //if(i_ScanType==1)
+ else {
+ //i_Count=0;
+ s_BoardInfos[dev->minor].
+ i_Count = 0;
+ } //elseif(i_ScanType==1)
+ //if(i_ScanType!=1)
+ if (s_BoardInfos[dev->minor].
+ i_ScanType != 1) {
+ i_ReturnValue = send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ } //if(i_ScanType!=1)
+ else {
+ //if(i_ChannelCount==i_Sum)
+ if (s_BoardInfos[dev->minor].
+ i_ChannelCount ==
+ s_BoardInfos[dev->
+ minor].i_Sum) {
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ }
+ } //if(i_ScanType!=1)
+ } //if (i_CalibrationFlag == 2)
+ } // if ((ui_StatusRegister & 0x2) == 0x2)
+
+ break;
+
+ case 2:
+ /************************************/
+ /*Read the interrupt status register */
+ /************************************/
+
+ //ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+ ui_StatusRegister =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 16);
+ /*************************/
+ /*Test if interrupt occur */
+ /*************************/
+
+ if ((ui_StatusRegister & 0x2) == 0x2) {
+
+ //i_CJCFlag = ((inl(devpriv->iobase+i_Offset + 4) & 0x00000400) >> 10);
+ i_CJCFlag =
+ ((inl(devpriv->iobase +
+ s_BoardInfos[dev->
+ minor].
+ i_Offset +
+ 4) & 0x00000400) >> 10);
+
+ //i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17);
+ i_CalibrationFlag =
+ ((inl(devpriv->iobase +
+ s_BoardInfos[dev->
+ minor].
+ i_Offset +
+ 12) & 0x00060000) >>
+ 17);
+
+ /*************************/
+ /*Read the channel number */
+ /*************************/
+
+ //ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+ ui_ChannelNumber =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 24);
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ s_BoardInfos[dev->minor].ui_Channel_num =
+ ui_ChannelNumber;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ /************************************/
+ /*Read the digital temperature value */
+ /************************************/
+ //ui_DigitalTemperature = inl(devpriv->iobase+i_Offset + 28);
+ ui_DigitalTemperature =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+
+ /*********************************************/
+ /*Test if the value read is the channel value */
+ /*********************************************/
+
+ if ((i_CalibrationFlag == 0)
+ && (i_CJCFlag == 0)) {
+ //ui_InterruptChannelValue[i_Count + 0]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 0] =
+ ui_DigitalTemperature;
+
+ /*********************************/
+ /*Start the conversion of the CJC */
+ /*********************************/
+ i_APCI3200_ReadCJCValue(dev,
+ &ui_DummyValue);
+
+ } //if ((i_CalibrationFlag == 0) && (i_CJCFlag == 0))
+
+ /*****************************************/
+ /*Test if the value read is the CJC value */
+ /*****************************************/
+
+ if ((i_CJCFlag == 1)
+ && (i_CalibrationFlag == 0)) {
+ //ui_InterruptChannelValue[i_Count + 3]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 3] =
+ ui_DigitalTemperature;
+
+ /******************************************************/
+ /*Start the conversion of the calibration offset value */
+ /******************************************************/
+ i_APCI3200_ReadCalibrationOffsetValue
+ (dev, &ui_DummyValue);
+ } // if ((i_CJCFlag == 1) && (i_CalibrationFlag == 0))
+
+ /********************************************************/
+ /*Test if the value read is the calibration offset value */
+ /********************************************************/
+
+ if ((i_CalibrationFlag == 1)
+ && (i_CJCFlag == 0)) {
+ //ui_InterruptChannelValue[i_Count + 1]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 1] =
+ ui_DigitalTemperature;
+
+ /****************************************************/
+ /*Start the conversion of the calibration gain value */
+ /****************************************************/
+ i_APCI3200_ReadCalibrationGainValue(dev,
+ &ui_DummyValue);
+
+ } //if ((i_CalibrationFlag == 1) && (i_CJCFlag == 0))
+
+ /******************************************************/
+ /*Test if the value read is the calibration gain value */
+ /******************************************************/
+
+ if ((i_CalibrationFlag == 2)
+ && (i_CJCFlag == 0)) {
+ //ui_InterruptChannelValue[i_Count + 2]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 2] =
+ ui_DigitalTemperature;
+
+ /**********************************************************/
+ /*Test if the Calibration channel must be read for the CJC */
+ /**********************************************************/
+
+ /*Test if the polarity is the same */
+ /**********************************/
+ //if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ if (s_BoardInfos[dev->minor].
+ i_CJCPolarity !=
+ s_BoardInfos[dev->minor].
+ i_ADDIDATAPolarity) {
+ i_ConvertCJCCalibration = 1;
+ } //if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ else {
+ //if(i_CJCGain==i_ADDIDATAGain)
+ if (s_BoardInfos[dev->minor].
+ i_CJCGain ==
+ s_BoardInfos[dev->
+ minor].
+ i_ADDIDATAGain) {
+ i_ConvertCJCCalibration
+ = 0;
+ } //if(i_CJCGain==i_ADDIDATAGain)
+ else {
+ i_ConvertCJCCalibration
+ = 1;
+ } //elseif(i_CJCGain==i_ADDIDATAGain)
+ } //elseif(i_CJCPolarity!=i_ADDIDATAPolarity)
+ if (i_ConvertCJCCalibration == 1) {
+ /****************************************************************/
+ /*Start the conversion of the calibration gain value for the CJC */
+ /****************************************************************/
+ i_APCI3200_ReadCJCCalOffset(dev,
+ &ui_DummyValue);
+
+ } //if(i_ConvertCJCCalibration==1)
+ else {
+ //ui_InterruptChannelValue[i_Count + 4]=0;
+ //ui_InterruptChannelValue[i_Count + 5]=0;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->
+ minor].i_Count +
+ 4] = 0;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->
+ minor].i_Count +
+ 5] = 0;
+ } //elseif(i_ConvertCJCCalibration==1)
+ } //else if ((i_CalibrationFlag == 2) && (i_CJCFlag == 0))
+
+ /********************************************************************/
+ /*Test if the value read is the calibration offset value for the CJC */
+ /********************************************************************/
+
+ if ((i_CalibrationFlag == 1)
+ && (i_CJCFlag == 1)) {
+ //ui_InterruptChannelValue[i_Count + 4]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 4] =
+ ui_DigitalTemperature;
+
+ /****************************************************************/
+ /*Start the conversion of the calibration gain value for the CJC */
+ /****************************************************************/
+ i_APCI3200_ReadCJCCalGain(dev,
+ &ui_DummyValue);
+
+ } //if ((i_CalibrationFlag == 1) && (i_CJCFlag == 1))
+
+ /******************************************************************/
+ /*Test if the value read is the calibration gain value for the CJC */
+ /******************************************************************/
+
+ if ((i_CalibrationFlag == 2)
+ && (i_CJCFlag == 1)) {
+ //ui_InterruptChannelValue[i_Count + 5]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 5] =
+ ui_DigitalTemperature;
+
+ //if(i_ScanType==1)
+ if (s_BoardInfos[dev->minor].
+ i_ScanType == 1) {
+
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].
+ i_InterruptFlag = 0;
+ //i_Count=i_Count + 6;
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6;
+ s_BoardInfos[dev->minor].
+ i_Count =
+ s_BoardInfos[dev->
+ minor].i_Count + 9;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ } //if(i_ScanType==1)
+ else {
+ //i_Count=0;
+ s_BoardInfos[dev->minor].
+ i_Count = 0;
+ } //elseif(i_ScanType==1)
+
+ //if(i_ScanType!=1)
+ if (s_BoardInfos[dev->minor].
+ i_ScanType != 1) {
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ } //if(i_ScanType!=1)
+ else {
+ //if(i_ChannelCount==i_Sum)
+ if (s_BoardInfos[dev->minor].
+ i_ChannelCount ==
+ s_BoardInfos[dev->
+ minor].i_Sum) {
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+
+ } //if(i_ChannelCount==i_Sum)
+ } //else if(i_ScanType!=1)
+ } //if ((i_CalibrationFlag == 2) && (i_CJCFlag == 1))
+
+ } //else if ((ui_StatusRegister & 0x2) == 0x2)
+ break;
+ } //switch(i_ADDIDATAType)
+ break;
+ case 2:
+ case 3:
+ i_APCI3200_InterruptHandleEos(dev);
+ break;
+ } //switch(i_ScanType)
+ return;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function name :int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Task : . |
+ | This function copies the acquired data(from FIFO) |
+ | to Comedi buffer. |
+ | |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value : 0 |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_InterruptHandleEos(struct comedi_device * dev)
+{
+ UINT ui_StatusRegister = 0;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+
+ //BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //comedi_async *async = s->async;
+ //UINT *data;
+ //data=async->data+async->buf_int_ptr;//new samples added from here onwards
+ int n = 0, i = 0;
+ //END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ /************************************/
+ /*Read the interrupt status register */
+ /************************************/
+ //ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+ ui_StatusRegister =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16);
+
+ /*************************/
+ /*Test if interrupt occur */
+ /*************************/
+
+ if ((ui_StatusRegister & 0x2) == 0x2) {
+ /*************************/
+ /*Read the channel number */
+ /*************************/
+ //ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+ //BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //This value is not used
+ //ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24);
+ s->async->events = 0;
+ //END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ /*************************************/
+ /*Read the digital Analog Input value */
+ /*************************************/
+
+ //data[i_Count] = inl(devpriv->iobase+i_Offset + 28);
+ //Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28);
+ s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ //End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ //if((i_Count == (i_LastChannel-i_FirstChannel+3)))
+ if ((s_BoardInfos[dev->minor].i_Count ==
+ (s_BoardInfos[dev->minor].i_LastChannel -
+ s_BoardInfos[dev->minor].
+ i_FirstChannel + 3))) {
+
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ s_BoardInfos[dev->minor].i_Count++;
+
+ for (i = s_BoardInfos[dev->minor].i_FirstChannel;
+ i <= s_BoardInfos[dev->minor].i_LastChannel;
+ i++) {
+ i_APCI3200_GetChannelCalibrationValue(dev, i,
+ &s_BoardInfos[dev->minor].
+ ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count + ((i -
+ s_BoardInfos
+ [dev->minor].
+ i_FirstChannel)
+ * 3)],
+ &s_BoardInfos[dev->minor].
+ ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count + ((i -
+ s_BoardInfos
+ [dev->minor].
+ i_FirstChannel)
+ * 3) + 1],
+ &s_BoardInfos[dev->minor].
+ ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count + ((i -
+ s_BoardInfos
+ [dev->minor].
+ i_FirstChannel)
+ * 3) + 2]);
+ }
+
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ //i_Count=-1;
+
+ s_BoardInfos[dev->minor].i_Count = -1;
+
+ //async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(UINT);
+ //Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(UINT);
+ //End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(UINT);
+ //Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(UINT);
+ //comedi_eos(dev,s);
+
+ // Set the event type (Comedi Buffer End Of Scan)
+ s->async->events |= COMEDI_CB_EOS;
+
+ // Test if enougth memory is available and allocate it for 7 values
+ //n = comedi_buf_write_alloc(s->async, 7*sizeof(unsigned int));
+ n = comedi_buf_write_alloc(s->async,
+ (7 + 12) * sizeof(unsigned int));
+
+ // If not enougth memory available, event is set to Comedi Buffer Errror
+ if (n > ((7 + 12) * sizeof(unsigned int))) {
+ printk("\ncomedi_buf_write_alloc n = %i", n);
+ s->async->events |= COMEDI_CB_ERROR;
+ }
+ // Write all 7 scan values in the comedi buffer
+ comedi_buf_memcpy_to(s->async, 0,
+ (unsigned int *) s_BoardInfos[dev->minor].
+ ui_ScanValueArray, (7 + 12) * sizeof(unsigned int));
+
+ // Update comedi buffer pinters indexes
+ comedi_buf_write_free(s->async,
+ (7 + 12) * sizeof(unsigned int));
+
+ // Send events
+ comedi_event(dev, s);
+ //End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ //BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //
+ //if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over
+ // {
+ // /* buffer rollover */
+ // s->async->buf_int_ptr=0;
+ // comedi_eobuf(dev,s);
+ // }
+ //End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ }
+ //i_Count++;
+ s_BoardInfos[dev->minor].i_Count++;
+ }
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h
new file mode 100644
index 00000000000..a6f57f55e79
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+// Card Specific information
+#define APCI3200_BOARD_VENDOR_ID 0x15B8
+//#define APCI3200_ADDRESS_RANGE 264
+
+int MODULE_NO;
+struct {
+ INT i_Gain;
+ INT i_Polarity;
+ INT i_OffsetRange;
+ INT i_Coupling;
+ INT i_SingleDiff;
+ INT i_AutoCalibration;
+ UINT ui_ReloadValue;
+ UINT ui_TimeUnitReloadVal;
+ INT i_Interrupt;
+ INT i_ModuleSelection;
+} Config_Parameters_Module1, Config_Parameters_Module2,
+ Config_Parameters_Module3, Config_Parameters_Module4;
+
+//ANALOG INPUT RANGE
+static const struct comedi_lrange range_apci3200_ai = { 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+static const struct comedi_lrange range_apci3300_ai = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+//Analog Input related Defines
+#define APCI3200_AI_OFFSET_GAIN 0
+#define APCI3200_AI_SC_TEST 4
+#define APCI3200_AI_IRQ 8
+#define APCI3200_AI_AUTOCAL 12
+#define APCI3200_RELOAD_CONV_TIME_VAL 32
+#define APCI3200_CONV_TIME_TIME_BASE 36
+#define APCI3200_RELOAD_DELAY_TIME_VAL 40
+#define APCI3200_DELAY_TIME_TIME_BASE 44
+#define APCI3200_AI_MODULE1 0
+#define APCI3200_AI_MODULE2 64
+#define APCI3200_AI_MODULE3 128
+#define APCI3200_AI_MODULE4 192
+#define TRUE 1
+#define FALSE 0
+#define APCI3200_AI_EOSIRQ 16
+#define APCI3200_AI_EOS 20
+#define APCI3200_AI_CHAN_ID 24
+#define APCI3200_AI_CHAN_VAL 28
+#define ANALOG_INPUT 0
+#define TEMPERATURE 1
+#define RESISTANCE 2
+
+#define ENABLE_EXT_TRIG 1
+#define ENABLE_EXT_GATE 2
+#define ENABLE_EXT_TRIG_GATE 3
+
+#define APCI3200_MAXVOLT 2.5
+#define ADDIDATA_GREATER_THAN_TEST 0
+#define ADDIDATA_LESS_THAN_TEST 1
+
+#define ADDIDATA_UNIPOLAR 1
+#define ADDIDATA_BIPOLAR 2
+
+//BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+#define MAX_MODULE 4
+//END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+typedef struct {
+ ULONG ul_NumberOfValue;
+ ULONG *pul_ResistanceValue;
+ ULONG *pul_TemperatureValue;
+} str_ADDIDATA_RTDStruct, *pstr_ADDIDATA_RTDStruct;
+
+//BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+typedef struct {
+ // Begin JK 05/08/2003 change for Linux
+ unsigned long ul_CurrentSourceCJC;
+ unsigned long ul_CurrentSource[5];
+ // End JK 05/08/2003 change for Linux
+
+ // Begin CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1
+ unsigned long ul_GainFactor[8]; // Gain Factor
+ unsigned int w_GainValue[10];
+ // End CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1
+} str_Module;
+//END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+//BEGIN JK 06.07.04: Management of sevrals boards
+typedef struct {
+ INT i_CJCAvailable;
+ INT i_CJCPolarity;
+ INT i_CJCGain;
+ INT i_InterruptFlag;
+ INT i_ADDIDATAPolarity;
+ INT i_ADDIDATAGain;
+ INT i_AutoCalibration;
+ INT i_ADDIDATAConversionTime;
+ INT i_ADDIDATAConversionTimeUnit;
+ INT i_ADDIDATAType;
+ INT i_ChannelNo;
+ INT i_ChannelCount;
+ INT i_ScanType;
+ INT i_FirstChannel;
+ INT i_LastChannel;
+ INT i_Sum;
+ INT i_Offset;
+ UINT ui_Channel_num;
+ INT i_Count;
+ INT i_Initialised;
+ //UINT ui_InterruptChannelValue[96]; //Buffer
+ UINT ui_InterruptChannelValue[144]; //Buffer
+ BYTE b_StructInitialized;
+ //Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ unsigned int ui_ScanValueArray[7 + 12]; // 7 is the maximal number of channels
+ //End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ //Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ INT i_ConnectionType;
+ INT i_NbrOfModule;
+ str_Module s_Module[MAX_MODULE];
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+} str_BoardInfos;
+//END JK 06.07.04: Management of sevrals boards
+
+// Hardware Layer functions for Apci3200
+
+//AI
+
+INT i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3200_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
+INT i_APCI3200_InterruptHandleEos(struct comedi_device *dev);
+INT i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd);
+INT i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
+INT i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+//Interrupt
+void v_APCI3200_Interrupt(int irq, void *d);
+int i_APCI3200_InterruptHandleEos(struct comedi_device *dev);
+//Reset functions
+INT i_APCI3200_Reset(struct comedi_device *dev);
+
+int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data);
+int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data);
+int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, UINT *data);
+int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, UINT *data);
+int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
new file mode 100644
index 00000000000..20391a91da0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
@@ -0,0 +1,742 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*.
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-3501 | Compiler : GCC |
+ | Module name : hwdrv_apci3501.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-3501 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci3501.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ReadDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3501_ReadDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->iobase + APCI3501_DIGITAL_IP);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } //if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+
+ *data = *data & 0x3;
+ } //if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } //elseif (ui_Temp==1)
+ } //elseif (ui_Temp==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ConfigDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[1] : 1 Enable VCC Interrupt |
+| 0 Disable VCC Interrupt |
+| data[2] : 1 Enable CC Interrupt |
+| 0 Disable CC Interrupt |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3501_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ } //if ( (data[0]!=0) && (data[0]!=1) )
+ if (data[0]) {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+ } // if (data[0])
+ else {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+ } //else if (data[0])
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : writes To the digital Output Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s : Subdevice Pointer |
+| struct comedi_insn *insn : Insn Structure Pointer |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp, ui_Temp1;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
+ } //if(devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } //if(devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outl(data[0], devpriv->iobase + APCI3501_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ data[0] = (data[0] << (2 * data[2])) | ui_Temp;
+ outl(data[0],
+ devpriv->iobase + APCI3501_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ (data[0] << ui_NoOfChannel) ^
+ 0xffffffff;
+ data[0] = data[0] & ui_Temp;
+ outl(data[0],
+ devpriv->iobase + APCI3501_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 = ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data[2])) ^
+ 0xffffffff) & ui_Temp;
+ outl(data[0],
+ devpriv->iobase +
+ APCI3501_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ReadDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } // if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ *data = *data & 0x3;
+
+ } // if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } // else if (ui_Temp==1)
+ } // else if (ui_Temp==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ConfigAnalogOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Analog Output Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s : Subdevice Pointer |
+| struct comedi_insn *insn : Insn Structure Pointer |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : Voltage Mode |
+| 0:Mode 0 |
+| 1:Mode 1 |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_ConfigAnalogOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ outl(data[0],
+ devpriv->iobase + APCI3501_ANALOG_OUTPUT +
+ APCI3501_AO_VOLT_MODE);
+
+ if (data[0]) {
+ devpriv->b_InterruptMode = MODE1;
+ } else {
+ devpriv->b_InterruptMode = MODE0;
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_WriteAnalogOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes To the Selected Anlog Output Channel |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s : Subdevice Pointer |
+| struct comedi_insn *insn : Insn Structure Pointer |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_WriteAnalogOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command1 = 0, ul_Channel_no, ul_Polarity, ul_DAC_Ready = 0;;
+
+ ul_Channel_no = CR_CHAN(insn->chanspec);
+
+ if (devpriv->b_InterruptMode == MODE1) {
+ ul_Polarity = 0x80000000;
+ if ((*data < 0) || (*data > 16384)) {
+ printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
+ }
+
+ } // end if(devpriv->b_InterruptMode==MODE1)
+ else {
+ ul_Polarity = 0;
+ if ((*data < 0) || (*data > 8192)) {
+ printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
+ }
+
+ } // end else
+
+ if ((ul_Channel_no < 0) || (ul_Channel_no > 7)) {
+ printk("\nIn WriteAnalogOutput :: Not Valid Channel\n");
+ } // end if((ul_Channel_no<0)||(ul_Channel_no>7))
+
+ ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
+
+ while (ul_DAC_Ready == 0) {
+ ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
+ ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1;
+ }
+
+ if (ul_DAC_Ready) {
+// Output the Value on the output channels.
+ ul_Command1 =
+ (ULONG) ((ULONG) (ul_Channel_no & 0xFF) |
+ (ULONG) ((*data << 0x8) & 0x7FFFFF00L) |
+ (ULONG) (ul_Polarity));
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_ANALOG_OUTPUT +
+ APCI3501_AO_PROG);
+ }
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ConfigTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Configure As Timer |
+| 1 Configure As Counter |
+| 2 Configure As Watchdog |
+| data[1] : 1 Enable Interrupt |
+| 0 Disable Interrupt |
+| data[2] : Time Unit |
+| data[3] : Reload Value |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command1 = 0;
+ devpriv->tsk_Current = current;
+ if (data[0] == ADDIDATA_WATCHDOG) {
+
+ devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
+ //Disable the watchdog
+ outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Wa
+
+ if (data[1] == 1) {
+ //Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
+ outl(0x02,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ } else {
+ outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Timer interrupt
+ }
+
+ //Loading the Timebase value
+ outl(data[2],
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_TIMEBASE);
+
+ //Loading the Reload value
+ outl(data[3],
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_RELOAD_VALUE);
+ //Set the mode
+ ul_Command1 = inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG) | 0xFFF819E0UL; //e2->e0
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ } //end if(data[0]==ADDIDATA_WATCHDOG)
+
+ else if (data[0] == ADDIDATA_TIMER) {
+ //First Stop The Timer
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //Stop The Timer
+ devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
+ if (data[1] == 1) {
+ //Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
+ outl(0x02,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ } else {
+ outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Timer interrupt
+ }
+
+ // Loading Timebase
+ outl(data[2],
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_TIMEBASE);
+
+ //Loading the Reload value
+ outl(data[3],
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_RELOAD_VALUE);
+
+ // printk ("\nTimer Address :: %x\n", (devpriv->iobase+APCI3501_WATCHDOG));
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 =
+ (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
+ outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //mode 2
+
+ } //end if(data[0]==ADDIDATA_TIMER)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_StartStopWriteTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Start / Stop The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Timer |
+| 1 Counter |
+| 2 Watchdog | | data[1] : 1 Start |
+| 0 Stop | 2 Trigger |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command1 = 0;
+ int i_Temp;
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+
+ if (data[1] == 1) {
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
+ //Enable the Watchdog
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ }
+
+ else if (data[1] == 0) //Stop The Watchdog
+ {
+ //Stop The Watchdog
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+ outl(0x0,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ } else if (data[1] == 2) {
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ } //if(data[1]==2)
+ } // end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+
+ if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ if (data[1] == 1) {
+
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
+ //Enable the Timer
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ } else if (data[1] == 0) {
+ //Stop The Timer
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ }
+
+ else if (data[1] == 2) {
+ //Trigger the Timer
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ }
+
+ } // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+ i_Temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_TRIG_STATUS) & 0x1;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ReadTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Timer |
+| 1 Counter |
+| 2 Watchdog | | data[1] : Timer Counter Watchdog Number |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ data[0] =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_TRIG_STATUS) & 0x1;
+ data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG);
+ } // end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+
+ else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ data[0] =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_TRIG_STATUS) & 0x1;
+ data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG);
+ } // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+
+ else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
+ && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)) {
+ printk("\nIn ReadTimerCounterWatchdog :: Invalid Subdevice \n");
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_Reset(struct comedi_device *dev) |
+| |
++----------------------------------------------------------------------------+
+| Task :Resets the registers of the card |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3501_Reset(struct comedi_device * dev)
+{
+ int i_Count = 0, i_temp = 0;
+ ULONG ul_Command1 = 0, ul_Polarity, ul_DAC_Ready = 0;
+ outl(0x0, devpriv->iobase + APCI3501_DIGITAL_OP);
+ outl(1, devpriv->iobase + APCI3501_ANALOG_OUTPUT +
+ APCI3501_AO_VOLT_MODE);
+
+ ul_Polarity = 0x80000000;
+
+ for (i_Count = 0; i_Count <= 7; i_Count++) {
+ ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
+
+ while (ul_DAC_Ready == 0) {
+ ul_DAC_Ready =
+ inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
+ ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1;
+ }
+
+ if (ul_DAC_Ready) {
+ // Output the Value on the output channels.
+ ul_Command1 =
+ (ULONG) ((ULONG) (i_Count & 0xFF) |
+ (ULONG) ((i_temp << 0x8) & 0x7FFFFF00L) |
+ (ULONG) (ul_Polarity));
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_ANALOG_OUTPUT +
+ APCI3501_AO_PROG);
+ }
+ }
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI3501_Interrupt |
+| (int irq , void *d) |
++----------------------------------------------------------------------------+
+| Task : Interrupt processing Routine |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+void v_APCI3501_Interrupt(int irq, void *d)
+{
+ int i_temp;
+ struct comedi_device *dev = d;
+ unsigned int ui_Timer_AOWatchdog;
+ unsigned long ul_Command1;
+ // Disable Interrupt
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
+
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FDul);
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
+
+ ui_Timer_AOWatchdog =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_IRQ) & 0x1;
+
+ if ((!ui_Timer_AOWatchdog)) {
+ comedi_error(dev, "IRQ from unknow source");
+ return;
+ }
+
+ // Enable Interrupt
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
+ ul_Command1 = ((ul_Command1 & 0xFFFFF9FDul) | 1 << 1);
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
+ i_temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_TRIG_STATUS) & 0x1;
+ return;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h
new file mode 100644
index 00000000000..51e7b66544a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+// Card Specific information
+#define APCI3501_BOARD_VENDOR_ID 0x15B8
+#define APCI3501_ADDRESS_RANGE 255
+
+#define APCI3501_DIGITAL_IP 0x50
+#define APCI3501_DIGITAL_OP 0x40
+#define APCI3501_ANALOG_OUTPUT 0x00
+
+//Analog Output related Defines
+#define APCI3501_AO_VOLT_MODE 0
+#define APCI3501_AO_PROG 4
+#define APCI3501_AO_TRIG_SCS 8
+#define UNIPOLAR 0
+#define BIPOLAR 1
+#define MODE0 0
+#define MODE1 1
+// ANALOG OUTPUT RANGE
+struct comedi_lrange range_apci3501_ao = { 2, {
+ BIP_RANGE(10),
+ UNI_RANGE(10)
+ }
+};
+
+//Watchdog Related Defines
+
+#define APCI3501_WATCHDOG 0x20
+#define APCI3501_TCW_SYNC_ENABLEDISABLE 0
+#define APCI3501_TCW_RELOAD_VALUE 4
+#define APCI3501_TCW_TIMEBASE 8
+#define APCI3501_TCW_PROG 12
+#define APCI3501_TCW_TRIG_STATUS 16
+#define APCI3501_TCW_IRQ 20
+#define APCI3501_TCW_WARN_TIMEVAL 24
+#define APCI3501_TCW_WARN_TIMEBASE 28
+#define ADDIDATA_TIMER 0
+#define ADDIDATA_WATCHDOG 2
+
+// Hardware Layer functions for Apci3501
+
+//AO
+INT i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//DI
+// for di read
+//INT i_APCI3501_ReadDigitalInput(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data);
+
+INT i_APCI3501_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//DO
+int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+INT i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+//Interrupt
+void v_APCI3501_Interrupt(int irq, void *d);
+
+//Reset functions
+int i_APCI3501_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
new file mode 100644
index 00000000000..b7268e4da64
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
@@ -0,0 +1,1691 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.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
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : APCI-3XXX | Compiler : GCC |
+ | Module name : hwdrv_apci3xxx.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: S. Weber | Date : 15/09/2005 |
+ +-----------------------------------------------------------------------+
+ | Description :APCI3XXX Module. Hardware abstraction Layer for APCI3XXX|
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+#include "hwdrv_apci3xxx.h"
+
+/*
++----------------------------------------------------------------------------+
+| ANALOG INPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_TestConversionStarted |
+| (struct comedi_device *dev) |
++----------------------------------------------------------------------------+
+| Task Test if any conversion started |
++----------------------------------------------------------------------------+
+| Input Parameters : - |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 : Conversion not started |
+| 1 : Conversion started |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_TestConversionStarted(struct comedi_device * dev)
+{
+ if ((readl((void *)(devpriv->dw_AiBase + 8)) & 0x80000UL) == 0x80000UL) {
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_AnalogInputConfigOperatingMode |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task Converting mode and convert time selection |
++----------------------------------------------------------------------------+
+| Input Parameters : b_SingleDiff = (BYTE) data[1]; |
+| b_TimeBase = (BYTE) data[2]; (0: ns, 1:micros 2:ms)|
+| dw_ReloadValue = (DWORD) data[3]; |
+| ........ |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :>0 : No error |
+| -1 : Single/Diff selection error |
+| -2 : Convert time base unity selection error |
+| -3 : Convert time value selection error |
+| -10: Any conversion started |
+| .... |
+| -100 : Config command error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_TimeBase = 0;
+ BYTE b_SingleDiff = 0;
+ DWORD dw_ReloadValue = 0;
+ DWORD dw_TestReloadValue = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n == 4) {
+ /****************************/
+ /* Get the Singel/Diff flag */
+ /****************************/
+
+ b_SingleDiff = (BYTE) data[1];
+
+ /****************************/
+ /* Get the time base unitiy */
+ /****************************/
+
+ b_TimeBase = (BYTE) data[2];
+
+ /*************************************/
+ /* Get the convert time reload value */
+ /*************************************/
+
+ dw_ReloadValue = (DWORD) data[3];
+
+ /**********************/
+ /* Test the time base */
+ /**********************/
+
+ if ((devpriv->ps_BoardInfo->
+ b_AvailableConvertUnit & (1 << b_TimeBase)) !=
+ 0) {
+ /*******************************/
+ /* Test the convert time value */
+ /*******************************/
+
+ if ((dw_ReloadValue >= 0) && (dw_ReloadValue <= 65535)) {
+ dw_TestReloadValue = dw_ReloadValue;
+
+ if (b_TimeBase == 1) {
+ dw_TestReloadValue =
+ dw_TestReloadValue * 1000UL;
+ }
+ if (b_TimeBase == 2) {
+ dw_TestReloadValue =
+ dw_TestReloadValue * 1000000UL;
+ }
+
+ /*******************************/
+ /* Test the convert time value */
+ /*******************************/
+
+ if (dw_TestReloadValue >=
+ devpriv->ps_BoardInfo->
+ ui_MinAcquisitiontimeNs) {
+ if ((b_SingleDiff == APCI3XXX_SINGLE)
+ || (b_SingleDiff ==
+ APCI3XXX_DIFF)) {
+ if (((b_SingleDiff == APCI3XXX_SINGLE) && (devpriv->ps_BoardInfo->i_NbrAiChannel == 0)) || ((b_SingleDiff == APCI3XXX_DIFF) && (devpriv->ps_BoardInfo->i_NbrAiChannelDiff == 0))) {
+ /*******************************/
+ /* Single/Diff selection error */
+ /*******************************/
+
+ printk("Single/Diff selection error\n");
+ i_ReturnValue = -1;
+ } else {
+ /**********************************/
+ /* Test if conversion not started */
+ /**********************************/
+
+ if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
+ devpriv->
+ ui_EocEosConversionTime
+ =
+ (UINT)
+ dw_ReloadValue;
+ devpriv->
+ b_EocEosConversionTimeBase
+ =
+ b_TimeBase;
+ devpriv->
+ b_SingelDiff
+ =
+ b_SingleDiff;
+ devpriv->
+ b_AiInitialisation
+ = 1;
+
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+
+ writel((DWORD)
+ b_TimeBase,
+ (void *)
+ (devpriv->
+ dw_AiBase
+ +
+ 36));
+
+ /**************************/
+ /* Set the convert timing */
+ /*************************/
+
+ writel(dw_ReloadValue, (void *)(devpriv->dw_AiBase + 32));
+ } else {
+ /**************************/
+ /* Any conversion started */
+ /**************************/
+
+ printk("Any conversion started\n");
+ i_ReturnValue =
+ -10;
+ }
+ }
+ } else {
+ /*******************************/
+ /* Single/Diff selection error */
+ /*******************************/
+
+ printk("Single/Diff selection error\n");
+ i_ReturnValue = -1;
+ }
+ } else {
+ /************************/
+ /* Time selection error */
+ /************************/
+
+ printk("Convert time value selection error\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /************************/
+ /* Time selection error */
+ /************************/
+
+ printk("Convert time value selection error\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*****************************/
+ /* Time base selection error */
+ /*****************************/
+
+ printk("Convert time base unity selection error\n");
+ i_ReturnValue = -2;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnConfigAnalogInput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task Converting mode and convert time selection |
++----------------------------------------------------------------------------+
+| Input Parameters : b_ConvertMode = (BYTE) data[0]; |
+| b_TimeBase = (BYTE) data[1]; (0: ns, 1:micros 2:ms)|
+| dw_ReloadValue = (DWORD) data[2]; |
+| ........ |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :>0: No error |
+| .... |
+| -100 : Config command error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ switch ((BYTE) data[0]) {
+ case APCI3XXX_CONFIGURATION:
+ i_ReturnValue =
+ i_APCI3XXX_AnalogInputConfigOperatingMode(dev,
+ s, insn, data);
+ break;
+
+ default:
+ i_ReturnValue = -100;
+ printk("Config command error %d\n", data[0]);
+ break;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnReadAnalogInput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task Read 1 analog input |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
+| b_Channel = CR_CHAN(insn->chanspec); |
+| dw_NbrOfAcquisition = insn->n; |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :>0: No error |
+| -3 : Channel selection error |
+| -4 : Configuration selelection error |
+| -10: Any conversion started |
+| .... |
+| -100 : Config command error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Configuration = (BYTE) CR_RANGE(insn->chanspec);
+ BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+ DWORD dw_Temp = 0;
+ DWORD dw_Configuration = 0;
+ DWORD dw_AcquisitionCpt = 0;
+ BYTE b_Interrupt = 0;
+
+ /*************************************/
+ /* Test if operating mode configured */
+ /*************************************/
+
+ if (devpriv->b_AiInitialisation) {
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if (((b_Channel < devpriv->ps_BoardInfo->i_NbrAiChannel)
+ && (devpriv->b_SingelDiff == APCI3XXX_SINGLE))
+ || ((b_Channel < devpriv->ps_BoardInfo->
+ i_NbrAiChannelDiff)
+ && (devpriv->b_SingelDiff == APCI3XXX_DIFF))) {
+ /**********************************/
+ /* Test the channel configuration */
+ /**********************************/
+
+ if (b_Configuration > 7) {
+ /***************************/
+ /* Channel not initialised */
+ /***************************/
+
+ i_ReturnValue = -4;
+ printk("Channel %d range %d selection error\n",
+ b_Channel, b_Configuration);
+ }
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ i_ReturnValue = -3;
+ printk("Channel %d selection error\n", b_Channel);
+ }
+
+ /**************************/
+ /* Test if no error occur */
+ /**************************/
+
+ if (i_ReturnValue >= 0) {
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if ((b_Interrupt != 0) || ((b_Interrupt == 0)
+ && (insn->n >= 1))) {
+ /**********************************/
+ /* Test if conversion not started */
+ /**********************************/
+
+ if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
+ /******************/
+ /* Clear the FIFO */
+ /******************/
+
+ writel(0x10000UL,
+ (void *)(devpriv->dw_AiBase +
+ 12));
+
+ /*******************************/
+ /* Get and save the delay mode */
+ /*******************************/
+
+ dw_Temp =
+ readl((void *)(devpriv->
+ dw_AiBase + 4));
+ dw_Temp = dw_Temp & 0xFFFFFEF0UL;
+
+ /***********************************/
+ /* Channel configuration selection */
+ /***********************************/
+
+ writel(dw_Temp,
+ (void *)(devpriv->dw_AiBase +
+ 4));
+
+ /**************************/
+ /* Make the configuration */
+ /**************************/
+
+ dw_Configuration =
+ (b_Configuration & 3) |
+ ((DWORD) (b_Configuration >> 2)
+ << 6) | ((DWORD) devpriv->
+ b_SingelDiff << 7);
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ writel(dw_Configuration,
+ (void *)(devpriv->dw_AiBase +
+ 0));
+
+ /*********************/
+ /* Channel selection */
+ /*********************/
+
+ writel(dw_Temp | 0x100UL,
+ (void *)(devpriv->dw_AiBase +
+ 4));
+ writel((DWORD) b_Channel,
+ (void *)(devpriv->dw_AiBase +
+ 0));
+
+ /***********************/
+ /* Restaure delay mode */
+ /***********************/
+
+ writel(dw_Temp,
+ (void *)(devpriv->dw_AiBase +
+ 4));
+
+ /***********************************/
+ /* Set the number of sequence to 1 */
+ /***********************************/
+
+ writel(1,
+ (void *)(devpriv->dw_AiBase +
+ 48));
+
+ /***************************/
+ /* Save the interrupt flag */
+ /***************************/
+
+ devpriv->b_EocEosInterrupt =
+ b_Interrupt;
+
+ /*******************************/
+ /* Save the number of channels */
+ /*******************************/
+
+ devpriv->ui_AiNbrofChannels = 1;
+
+ /******************************/
+ /* Test if interrupt not used */
+ /******************************/
+
+ if (b_Interrupt == 0) {
+ for (dw_AcquisitionCpt = 0;
+ dw_AcquisitionCpt <
+ insn->n;
+ dw_AcquisitionCpt++) {
+ /************************/
+ /* Start the conversion */
+ /************************/
+
+ writel(0x80000UL,
+ (void *)
+ (devpriv->
+ dw_AiBase
+ + 8));
+
+ /****************/
+ /* Wait the EOS */
+ /****************/
+
+ do {
+ dw_Temp =
+ readl(
+ (void *)
+ (devpriv->
+ dw_AiBase
+ +
+ 20));
+ dw_Temp =
+ dw_Temp
+ & 1;
+ }
+ while (dw_Temp != 1);
+
+ /*************************/
+ /* Read the analog value */
+ /*************************/
+
+ data[dw_AcquisitionCpt]
+ =
+ (unsigned int)
+ readl((void
+ *)
+ (devpriv->
+ dw_AiBase
+ + 28));
+ }
+ } else {
+ /************************/
+ /* Start the conversion */
+ /************************/
+
+ writel(0x180000UL,
+ (void *)(devpriv->
+ dw_AiBase + 8));
+ }
+ } else {
+ /**************************/
+ /* Any conversion started */
+ /**************************/
+
+ printk("Any conversion started\n");
+ i_ReturnValue = -10;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+ }
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ printk("Operating mode not configured\n");
+ i_ReturnValue = -1;
+ }
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : void v_APCI3XXX_Interrupt (int irq, |
+| void *d) |
++----------------------------------------------------------------------------+
+| Task :Interrupt handler for APCI3XXX |
+| When interrupt occurs this gets called. |
+| First it finds which interrupt has been generated and |
+| handles corresponding interrupt |
++----------------------------------------------------------------------------+
+| Input Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : - |
++----------------------------------------------------------------------------+
+*/
+
+void v_APCI3XXX_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ BYTE b_CopyCpt = 0;
+ DWORD dw_Status = 0;
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if (((dw_Status = readl((void *)(devpriv->dw_AiBase + 16))) & 0x2UL) ==
+ 0x2UL) {
+ /***********************/
+ /* Reset the interrupt */
+ /***********************/
+
+ writel(dw_Status, (void *)(devpriv->dw_AiBase + 16));
+
+ /*****************************/
+ /* Test if interrupt enabled */
+ /*****************************/
+
+ if (devpriv->b_EocEosInterrupt == 1) {
+ /********************************/
+ /* Read all analog inputs value */
+ /********************************/
+
+ for (b_CopyCpt = 0;
+ b_CopyCpt < devpriv->ui_AiNbrofChannels;
+ b_CopyCpt++) {
+ devpriv->ui_AiReadData[b_CopyCpt] =
+ (UINT) readl((void *)(devpriv->
+ dw_AiBase + 28));
+ }
+
+ /**************************/
+ /* Set the interrupt flag */
+ /**************************/
+
+ devpriv->b_EocEosInterrupt = 2;
+
+ /**********************************************/
+ /* Send a signal to from kernel to user space */
+ /**********************************************/
+
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+ }
+ }
+}
+
+/*
++----------------------------------------------------------------------------+
+| ANALOG OUTPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnWriteAnalogOutput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task Read 1 analog input |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
+| b_Channel = CR_CHAN(insn->chanspec); |
+| data[0] = analog value; |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :>0: No error |
+| -3 : Channel selection error |
+| -4 : Configuration selelection error |
+| .... |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_Range = (BYTE) CR_RANGE(insn->chanspec);
+ BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+ DWORD dw_Status = 0;
+ INT i_ReturnValue = insn->n;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if (b_Channel < devpriv->ps_BoardInfo->i_NbrAoChannel) {
+ /**********************************/
+ /* Test the channel configuration */
+ /**********************************/
+
+ if (b_Range < 2) {
+ /***************************/
+ /* Set the range selection */
+ /***************************/
+
+ writel(b_Range,
+ (void *)(devpriv->dw_AiBase + 96));
+
+ /**************************************************/
+ /* Write the analog value to the selected channel */
+ /**************************************************/
+
+ writel((data[0] << 8) | b_Channel,
+ (void *)(devpriv->dw_AiBase + 100));
+
+ /****************************/
+ /* Wait the end of transfer */
+ /****************************/
+
+ do {
+ dw_Status =
+ readl((void *)(devpriv->
+ dw_AiBase + 96));
+ }
+ while ((dw_Status & 0x100) != 0x100);
+ } else {
+ /***************************/
+ /* Channel not initialised */
+ /***************************/
+
+ i_ReturnValue = -4;
+ printk("Channel %d range %d selection error\n",
+ b_Channel, b_Range);
+ }
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ i_ReturnValue = -3;
+ printk("Channel %d selection error\n", b_Channel);
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| TTL FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnConfigInitTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task You must calling this function be |
+| for you call any other function witch access of TTL. |
+| APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)|
++----------------------------------------------------------------------------+
+| Input Parameters : b_InitType = (BYTE) data[0]; |
+| b_Port2Mode = (BYTE) data[1]; |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :>0: No error |
+| -1: Port 2 mode selection is wrong |
+| .... |
+| -100 : Config command error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Command = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /*******************/
+ /* Get the command */
+ /* **************** */
+
+ b_Command = (BYTE) data[0];
+
+ /********************/
+ /* Test the command */
+ /********************/
+
+ if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
+ /***************************************/
+ /* Test the initialisation buffer size */
+ /***************************************/
+
+ if ((b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)
+ && (insn->n != 2)) {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+ } else {
+ /************************/
+ /* Config command error */
+ /************************/
+
+ printk("Command selection error\n");
+ i_ReturnValue = -100;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ /*********************************************************************************/
+ /* Test if no error occur and APCI3XXX_TTL_INIT_DIRECTION_PORT2 command selected */
+ /*********************************************************************************/
+
+ if ((i_ReturnValue >= 0)
+ && (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)) {
+ /**********************/
+ /* Test the direction */
+ /**********************/
+
+ if ((data[1] == 0) || (data[1] == 0xFF)) {
+ /**************************/
+ /* Save the configuration */
+ /**************************/
+
+ devpriv->ul_TTLPortConfiguration[0] =
+ devpriv->ul_TTLPortConfiguration[0] | data[1];
+ } else {
+ /************************/
+ /* Port direction error */
+ /************************/
+
+ printk("Port 2 direction selection error\n");
+ i_ReturnValue = -1;
+ }
+ }
+
+ /**************************/
+ /* Test if no error occur */
+ /**************************/
+
+ if (i_ReturnValue >= 0) {
+ /***********************************/
+ /* Test if TTL port initilaisation */
+ /***********************************/
+
+ if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
+ /*************************/
+ /* Set the configuration */
+ /*************************/
+
+ outl(data[1], devpriv->iobase + 224);
+ }
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| TTL INPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnBitsTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Write the selected output mask and read the status from|
+| all TTL channles |
++----------------------------------------------------------------------------+
+| Input Parameters : dw_ChannelMask = data [0]; |
+| dw_BitMask = data [1]; |
++----------------------------------------------------------------------------+
+| Output Parameters : data[1] : All TTL channles states |
++----------------------------------------------------------------------------+
+| Return Value : >0 : No error |
+| -4 : Channel mask error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_ChannelCpt = 0;
+ DWORD dw_ChannelMask = 0;
+ DWORD dw_BitMask = 0;
+ DWORD dw_Status = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 2) {
+ /*******************************/
+ /* Get the channe and bit mask */
+ /*******************************/
+
+ dw_ChannelMask = data[0];
+ dw_BitMask = data[1];
+
+ /*************************/
+ /* Test the channel mask */
+ /*************************/
+
+ if (((dw_ChannelMask & 0XFF00FF00) == 0) &&
+ (((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF)
+ || (((devpriv->ul_TTLPortConfiguration[0] &
+ 0xFF) == 0)
+ && ((dw_ChannelMask & 0XFF0000) ==
+ 0)))) {
+ /*********************************/
+ /* Test if set/reset any channel */
+ /*********************************/
+
+ if (dw_ChannelMask) {
+ /****************************************/
+ /* Test if set/rest any port 0 channels */
+ /****************************************/
+
+ if (dw_ChannelMask & 0xFF) {
+ /*******************************************/
+ /* Read port 0 (first digital output port) */
+ /*******************************************/
+
+ dw_Status = inl(devpriv->iobase + 80);
+
+ for (b_ChannelCpt = 0; b_ChannelCpt < 8;
+ b_ChannelCpt++) {
+ if ((dw_ChannelMask >>
+ b_ChannelCpt) &
+ 1) {
+ dw_Status =
+ (dw_Status &
+ (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
+ }
+ }
+
+ outl(dw_Status, devpriv->iobase + 80);
+ }
+
+ /****************************************/
+ /* Test if set/rest any port 2 channels */
+ /****************************************/
+
+ if (dw_ChannelMask & 0xFF0000) {
+ dw_BitMask = dw_BitMask >> 16;
+ dw_ChannelMask = dw_ChannelMask >> 16;
+
+ /********************************************/
+ /* Read port 2 (second digital output port) */
+ /********************************************/
+
+ dw_Status = inl(devpriv->iobase + 112);
+
+ for (b_ChannelCpt = 0; b_ChannelCpt < 8;
+ b_ChannelCpt++) {
+ if ((dw_ChannelMask >>
+ b_ChannelCpt) &
+ 1) {
+ dw_Status =
+ (dw_Status &
+ (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
+ }
+ }
+
+ outl(dw_Status, devpriv->iobase + 112);
+ }
+ }
+
+ /*******************************************/
+ /* Read port 0 (first digital output port) */
+ /*******************************************/
+
+ data[1] = inl(devpriv->iobase + 80);
+
+ /******************************************/
+ /* Read port 1 (first digital input port) */
+ /******************************************/
+
+ data[1] = data[1] | (inl(devpriv->iobase + 64) << 8);
+
+ /************************/
+ /* Test if port 2 input */
+ /************************/
+
+ if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) {
+ data[1] =
+ data[1] | (inl(devpriv->iobase +
+ 96) << 16);
+ } else {
+ data[1] =
+ data[1] | (inl(devpriv->iobase +
+ 112) << 16);
+ }
+ } else {
+ /************************/
+ /* Config command error */
+ /************************/
+
+ printk("Channel mask error\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnReadTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read the status from selected channel |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Selected TTL channel state |
++----------------------------------------------------------------------------+
+| Return Value : 0 : No error |
+| -3 : Channel selection error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnReadTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+ INT i_ReturnValue = insn->n;
+ unsigned int *pls_ReadData = data;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /***********************/
+ /* Test if read port 0 */
+ /***********************/
+
+ if (b_Channel < 8) {
+ /*******************************************/
+ /* Read port 0 (first digital output port) */
+ /*******************************************/
+
+ pls_ReadData[0] = inl(devpriv->iobase + 80);
+ pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1;
+ } else {
+ /***********************/
+ /* Test if read port 1 */
+ /***********************/
+
+ if ((b_Channel > 7) && (b_Channel < 16)) {
+ /******************************************/
+ /* Read port 1 (first digital input port) */
+ /******************************************/
+
+ pls_ReadData[0] = inl(devpriv->iobase + 64);
+ pls_ReadData[0] =
+ (pls_ReadData[0] >> (b_Channel -
+ 8)) & 1;
+ } else {
+ /***********************/
+ /* Test if read port 2 */
+ /***********************/
+
+ if ((b_Channel > 15) && (b_Channel < 24)) {
+ /************************/
+ /* Test if port 2 input */
+ /************************/
+
+ if ((devpriv->ul_TTLPortConfiguration[0]
+ & 0xFF) == 0) {
+ pls_ReadData[0] =
+ inl(devpriv->iobase +
+ 96);
+ pls_ReadData[0] =
+ (pls_ReadData[0] >>
+ (b_Channel - 16)) & 1;
+ } else {
+ pls_ReadData[0] =
+ inl(devpriv->iobase +
+ 112);
+ pls_ReadData[0] =
+ (pls_ReadData[0] >>
+ (b_Channel - 16)) & 1;
+ }
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ i_ReturnValue = -3;
+ printk("Channel %d selection error\n",
+ b_Channel);
+ }
+ }
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| TTL OUTPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnWriteTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Set the state from TTL output channel |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
+| b_State = data [0] |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 : No error |
+| -3 : Channel selection error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+ BYTE b_State = 0;
+ DWORD dw_Status = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ b_State = (BYTE) data[0];
+
+ /***********************/
+ /* Test if read port 0 */
+ /***********************/
+
+ if (b_Channel < 8) {
+ /*****************************************************************************/
+ /* Read port 0 (first digital output port) and set/reset the selcted channel */
+ /*****************************************************************************/
+
+ dw_Status = inl(devpriv->iobase + 80);
+ dw_Status =
+ (dw_Status & (0xFF -
+ (1 << b_Channel))) | ((b_State & 1) <<
+ b_Channel);
+ outl(dw_Status, devpriv->iobase + 80);
+ } else {
+ /***********************/
+ /* Test if read port 2 */
+ /***********************/
+
+ if ((b_Channel > 15) && (b_Channel < 24)) {
+ /*************************/
+ /* Test if port 2 output */
+ /*************************/
+
+ if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
+ == 0xFF) {
+ /*****************************************************************************/
+ /* Read port 2 (first digital output port) and set/reset the selcted channel */
+ /*****************************************************************************/
+
+ dw_Status = inl(devpriv->iobase + 112);
+ dw_Status =
+ (dw_Status & (0xFF -
+ (1 << (b_Channel -
+ 16)))) |
+ ((b_State & 1) << (b_Channel -
+ 16));
+ outl(dw_Status, devpriv->iobase + 112);
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ i_ReturnValue = -3;
+ printk("Channel %d selection error\n",
+ b_Channel);
+ }
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ i_ReturnValue = -3;
+ printk("Channel %d selection error\n",
+ b_Channel);
+ }
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| DIGITAL INPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3XXX_InsnReadDigitalInput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Reads the value of the specified Digital input channel |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Channel value |
++----------------------------------------------------------------------------+
+| Return Value : 0 : No error |
+| -3 : Channel selection error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+ DWORD dw_Temp = 0;
+
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if (b_Channel <= devpriv->ps_BoardInfo->i_NbrDiChannel) {
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ dw_Temp = inl(devpriv->iobase + 32);
+ *data = (dw_Temp >> b_Channel) & 1;
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ printk("Channel selection error\n");
+ i_ReturnValue = -3;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3XXX_InsnBitsDigitalInput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Reads the value of the Digital input Port i.e.4channels|
++----------------------------------------------------------------------------+
+| Input Parameters : - |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Port value |
++----------------------------------------------------------------------------+
+| Return Value :>0: No error |
+| .... |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ DWORD dw_Temp = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ dw_Temp = inl(devpriv->iobase + 32);
+ *data = dw_Temp & 0xf;
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| DIGITAL OUTPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3XXX_InsnBitsDigitalOutput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Write the selected output mask and read the status from|
+| all digital output channles |
++----------------------------------------------------------------------------+
+| Input Parameters : dw_ChannelMask = data [0]; |
+| dw_BitMask = data [1]; |
++----------------------------------------------------------------------------+
+| Output Parameters : data[1] : All digital output channles states |
++----------------------------------------------------------------------------+
+| Return Value : >0 : No error |
+| -4 : Channel mask error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_ChannelCpt = 0;
+ DWORD dw_ChannelMask = 0;
+ DWORD dw_BitMask = 0;
+ DWORD dw_Status = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 2) {
+ /*******************************/
+ /* Get the channe and bit mask */
+ /*******************************/
+
+ dw_ChannelMask = data[0];
+ dw_BitMask = data[1];
+
+ /*************************/
+ /* Test the channel mask */
+ /*************************/
+
+ if ((dw_ChannelMask & 0XFFFFFFF0) == 0) {
+ /*********************************/
+ /* Test if set/reset any channel */
+ /*********************************/
+
+ if (dw_ChannelMask & 0xF) {
+ /********************************/
+ /* Read the digital output port */
+ /********************************/
+
+ dw_Status = inl(devpriv->iobase + 48);
+
+ for (b_ChannelCpt = 0; b_ChannelCpt < 4;
+ b_ChannelCpt++) {
+ if ((dw_ChannelMask >> b_ChannelCpt) &
+ 1) {
+ dw_Status =
+ (dw_Status & (0xF -
+ (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
+ }
+ }
+
+ outl(dw_Status, devpriv->iobase + 48);
+ }
+
+ /********************************/
+ /* Read the digital output port */
+ /********************************/
+
+ data[1] = inl(devpriv->iobase + 48);
+ } else {
+ /************************/
+ /* Config command error */
+ /************************/
+
+ printk("Channel mask error\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3XXX_InsnWriteDigitalOutput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Set the state from digital output channel |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
+| b_State = data [0] |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : >0 : No error |
+| -3 : Channel selection error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Channel = CR_CHAN(insn->chanspec);
+ BYTE b_State = 0;
+ DWORD dw_Status = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
+ /*******************/
+ /* Get the command */
+ /*******************/
+
+ b_State = (BYTE) data[0];
+
+ /********************************/
+ /* Read the digital output port */
+ /********************************/
+
+ dw_Status = inl(devpriv->iobase + 48);
+
+ dw_Status =
+ (dw_Status & (0xF -
+ (1 << b_Channel))) | ((b_State & 1) <<
+ b_Channel);
+ outl(dw_Status, devpriv->iobase + 48);
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ printk("Channel selection error\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3XXX_InsnReadDigitalOutput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read the state from digital output channel |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
++----------------------------------------------------------------------------+
+| Output Parameters : b_State = data [0] |
++----------------------------------------------------------------------------+
+| Return Value : >0 : No error |
+| -3 : Channel selection error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Channel = CR_CHAN(insn->chanspec);
+ DWORD dw_Status = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
+ /********************************/
+ /* Read the digital output port */
+ /********************************/
+
+ dw_Status = inl(devpriv->iobase + 48);
+
+ dw_Status = (dw_Status >> b_Channel) & 1;
+ *data = dw_Status;
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ printk("Channel selection error\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3XXX_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : - |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_Reset(struct comedi_device * dev)
+{
+ unsigned char b_Cpt = 0;
+
+ /*************************/
+ /* Disable the interrupt */
+ /*************************/
+
+ disable_irq(dev->irq);
+
+ /****************************/
+ /* Reset the interrupt flag */
+ /****************************/
+
+ devpriv->b_EocEosInterrupt = 0;
+
+ /***************************/
+ /* Clear the start command */
+ /***************************/
+
+ writel(0, (void *)(devpriv->dw_AiBase + 8));
+
+ /*****************************/
+ /* Reset the interrupt flags */
+ /*****************************/
+
+ writel(readl((void *)(devpriv->dw_AiBase + 16)),
+ (void *)(devpriv->dw_AiBase + 16));
+
+ /*****************/
+ /* clear the EOS */
+ /*****************/
+
+ readl((void *)(devpriv->dw_AiBase + 20));
+
+ /******************/
+ /* Clear the FIFO */
+ /******************/
+
+ for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) {
+ readl((void *)(devpriv->dw_AiBase + 28));
+ }
+
+ /************************/
+ /* Enable the interrupt */
+ /************************/
+
+ enable_irq(dev->irq);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h
new file mode 100644
index 00000000000..788d7c1cf5c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.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.
+ */
+
+#ifndef COMEDI_SUBD_TTLIO
+#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
+#endif
+
+#ifndef ADDIDATA_ENABLE
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+#endif
+
+#define APCI3XXX_SINGLE 0
+#define APCI3XXX_DIFF 1
+#define APCI3XXX_CONFIGURATION 0
+
+#define APCI3XXX_TTL_INIT_DIRECTION_PORT2 0
+
+#ifdef __KERNEL__
+
+static const struct comedi_lrange range_apci3XXX_ai = { 8, {BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)}
+};
+
+static const struct comedi_lrange range_apci3XXX_ttl = { 12, {BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1)}
+};
+
+static const struct comedi_lrange range_apci3XXX_ao = { 2, {BIP_RANGE(10),
+ UNI_RANGE(10)}
+};
+#endif
diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c
new file mode 100644
index 00000000000..bac018202fe
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_035.c
@@ -0,0 +1,5 @@
+#define CONFIG_APCI_035 1
+
+#define ADDIDATA_WATCHDOG 2 // Or shold it be something else
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c
new file mode 100644
index 00000000000..fa2056e8aa0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1032.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1032 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c
new file mode 100644
index 00000000000..7a5cae599ef
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1500.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1500 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c
new file mode 100644
index 00000000000..8d414844009
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1516.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1516 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c
new file mode 100644
index 00000000000..0351cdde102
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1564.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1564 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c
new file mode 100644
index 00000000000..50679904129
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_16XX 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c
new file mode 100644
index 00000000000..c433445913d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1710.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1710 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c
new file mode 100644
index 00000000000..271c47c8cad
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_2016.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_2016 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c
new file mode 100644
index 00000000000..5108ea2a392
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_2032.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_2032 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c
new file mode 100644
index 00000000000..e439f835cf4
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_2200.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_2200 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c
new file mode 100644
index 00000000000..df97c305828
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3001.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3001 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c
new file mode 100644
index 00000000000..9183125ddde
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3120.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3120 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c
new file mode 100644
index 00000000000..f25a70b3290
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3200.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3200 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c
new file mode 100644
index 00000000000..1ee4778ad45
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3300.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3300 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c
new file mode 100644
index 00000000000..1049e20237e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3501.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3501 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
new file mode 100644
index 00000000000..fb9deb7083b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3XXX 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_all.c b/drivers/staging/comedi/drivers/addi_apci_all.c
new file mode 100644
index 00000000000..aeb1b2688f3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_all.c
@@ -0,0 +1,18 @@
+#define CONFIG_APCI_035 1
+#define CONFIG_APCI_1032 1
+#define CONFIG_APCI_1500 1
+#define CONFIG_APCI_1516 1
+#define CONFIG_APCI_1564 1
+#define CONFIG_APCI_16XX 1
+#define CONFIG_APCI_1710 1
+#define CONFIG_APCI_2016 1
+#define CONFIG_APCI_2032 1
+#define CONFIG_APCI_2200 1
+#define CONFIG_APCI_3001 1
+#define CONFIG_APCI_3120 1
+#define CONFIG_APCI_3200 1
+#define CONFIG_APCI_3300 1
+#define CONFIG_APCI_3501 1
+#define CONFIG_APCI_3XXX 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c
new file mode 100644
index 00000000000..f710f551820
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci6208.c
@@ -0,0 +1,391 @@
+/*
+ comedi/drivers/adl_pci6208.c
+
+ Hardware driver for ADLink 6208 series cards:
+ card | voltage output | current output
+ -------------+-------------------+---------------
+ PCI-6208V | 8 channels | -
+ PCI-6216V | 16 channels | -
+ PCI-6208A | 8 channels | 8 channels
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: adl_pci6208
+Description: ADLink PCI-6208A
+Devices: [ADLink] PCI-6208A (adl_pci6208)
+Author: nsyeow <nsyeow@pd.jaring.my>
+Updated: Fri, 30 Jan 2004 14:44:27 +0800
+Status: untested
+
+Configuration Options:
+ none
+
+References:
+ - ni_660x.c
+ - adl_pci9111.c copied the entire pci setup section
+ - adl_pci9118.c
+*/
+/*
+ * These headers should be followed by a blank line, and any comments
+ * you wish to say about the driver. The comment area is the place
+ * to put any known bugs, limitations, unsupported features, supported
+ * command triggers, whether or not commands are supported on particular
+ * subdevices, etc.
+ *
+ * Somewhere in the comment should be information about configuration
+ * options that are used with comedi_config.
+ */
+#include "../comedidev.h"
+#include "comedi_pci.h"
+
+#define PCI6208_DRIVER_NAME "adl_pci6208"
+
+/* Board descriptions */
+struct pci6208_board {
+ const char *name;
+ unsigned short dev_id; /* `lspci` will show you this */
+ int ao_chans;
+ //int ao_bits;
+};
+
+static const struct pci6208_board pci6208_boards[] = {
+ /*{
+ name : "pci6208v",
+ dev_id : 0x6208, //not sure
+ ao_chans: 8
+ //, ao_bits : 16
+ },
+ {
+ name : "pci6216v",
+ dev_id : 0x6208, //not sure
+ ao_chans: 16
+ //, ao_bits : 16
+ }, */
+ {
+ name: "pci6208a",
+ dev_id: 0x6208,
+ ao_chans:8
+ //, ao_bits : 16
+ }
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers. Should
+ * only be used for PCI and ISA-PnP devices */
+static DEFINE_PCI_DEVICE_TABLE(pci6208_pci_table) = {
+ //{ PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ //{ PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ {PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci6208_pci_table);
+
+/* Will be initialized in pci6208_find device(). */
+#define thisboard ((const struct pci6208_board *)dev->board_ptr)
+
+struct pci6208_private {
+ int data;
+ struct pci_dev *pci_dev; /* for a PCI device */
+ unsigned int ao_readback[2]; /* Used for AO readback */
+};
+
+#define devpriv ((struct pci6208_private *)dev->private)
+
+static int pci6208_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci6208_detach(struct comedi_device * dev);
+
+#define pci6208_board_nbr \
+ (sizeof(pci6208_boards) / sizeof(struct pci6208_board))
+
+static struct comedi_driver driver_pci6208 = {
+ driver_name:PCI6208_DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:pci6208_attach,
+ detach:pci6208_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_pci6208, pci6208_pci_table);
+
+static int pci6208_find_device(struct comedi_device * dev, int bus, int slot);
+static int
+pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr,
+ int dev_minor);
+
+/*read/write functions*/
+static int pci6208_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pci6208_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+//static int pci6208_dio_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s,
+// struct comedi_insn *insn,unsigned int *data);
+//static int pci6208_dio_insn_config(struct comedi_device *dev,struct comedi_subdevice *s,
+// struct comedi_insn *insn,unsigned int *data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pci6208_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int retval;
+ unsigned long io_base;
+
+ printk("comedi%d: pci6208: ", dev->minor);
+
+ retval = alloc_private(dev, sizeof(struct pci6208_private));
+ if (retval < 0)
+ return retval;
+
+ retval = pci6208_find_device(dev, it->options[0], it->options[1]);
+ if (retval < 0)
+ return retval;
+
+ retval = pci6208_pci_setup(devpriv->pci_dev, &io_base, dev->minor);
+ if (retval < 0)
+ return retval;
+
+ dev->iobase = io_base;
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE; //anything else to add here??
+ s->n_chan = thisboard->ao_chans;
+ s->maxdata = 0xffff; //16-bit DAC
+ s->range_table = &range_bipolar10; //this needs to be checked.
+ s->insn_write = pci6208_ao_winsn;
+ s->insn_read = pci6208_ao_rinsn;
+
+ //s=dev->subdevices+1;
+ /* digital i/o subdevice */
+ //s->type=COMEDI_SUBD_DIO;
+ //s->subdev_flags=SDF_READABLE|SDF_WRITABLE;
+ //s->n_chan=16;
+ //s->maxdata=1;
+ //s->range_table=&range_digital;
+ //s->insn_bits = pci6208_dio_insn_bits;
+ //s->insn_config = pci6208_dio_insn_config;
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pci6208_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pci6208: remove\n", dev->minor);
+
+ if (devpriv && devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
+ return 0;
+}
+
+static int pci6208_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i = 0, Data_Read;
+ unsigned short chan = CR_CHAN(insn->chanspec);
+ unsigned long invert = 1 << (16 - 1);
+ unsigned long out_value;
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ out_value = data[i] ^ invert;
+ /* a typical programming sequence */
+ do {
+ Data_Read = (inw(dev->iobase) & 1);
+ } while (Data_Read);
+ outw(out_value, dev->iobase + (0x02 * chan));
+ devpriv->ao_readback[chan] = out_value;
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int pci6208_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+//static int pci6208_dio_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s,
+// struct comedi_insn *insn,unsigned int *data)
+//{
+// if(insn->n!=2)return -EINVAL;
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+// if(data[0]){
+// s->state &= ~data[0];
+// s->state |= data[0]&data[1];
+ /* Write out the new digital output lines */
+ //outw(s->state,dev->iobase + SKEL_DIO);
+// }
+
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ //data[1]=inw(dev->iobase + SKEL_DIO);
+ /* or we could just return the software copy of the output values if
+ * it was a purely digital output subdevice */
+ //data[1]=s->state;
+
+// return 2;
+//}
+
+//static int pci6208_dio_insn_config(struct comedi_device *dev,struct comedi_subdevice *s,
+// struct comedi_insn *insn,unsigned int *data)
+//{
+// int chan=CR_CHAN(insn->chanspec);
+
+ /* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+// if(data[0]==COMEDI_OUTPUT){
+// s->io_bits |= 1<<chan;
+// }else{
+// s->io_bits &= ~(1<<chan);
+// }
+ //outw(s->io_bits,dev->iobase + SKEL_DIO_CONFIG);
+
+// return 1;
+//}
+
+static int pci6208_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct pci_dev *pci_dev;
+ int i;
+
+ for (pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pci_dev != NULL;
+ pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
+ if (pci_dev->vendor == PCI_VENDOR_ID_ADLINK) {
+ for (i = 0; i < pci6208_board_nbr; i++) {
+ if (pci6208_boards[i].dev_id == pci_dev->device) {
+ // was a particular bus/slot requested?
+ if ((bus != 0) || (slot != 0)) {
+ // are we on the wrong bus/slot?
+ if (pci_dev->bus->number
+ != bus ||
+ PCI_SLOT(pci_dev->devfn)
+ != slot) {
+ continue;
+ }
+ }
+ dev->board_ptr = pci6208_boards + i;
+ goto found;
+ }
+ }
+ }
+ }
+
+ printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+ dev->minor, bus, slot);
+ return -EIO;
+
+ found:
+ printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n",
+ dev->minor,
+ pci6208_boards[i].name,
+ pci_dev->bus->number,
+ PCI_SLOT(pci_dev->devfn),
+ PCI_FUNC(pci_dev->devfn), pci_dev->irq);
+
+ // TODO: Warn about non-tested boards.
+ //switch(board->device_id)
+ //{
+ //};
+
+ devpriv->pci_dev = pci_dev;
+
+ return 0;
+}
+
+static int
+pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr,
+ int dev_minor)
+{
+ unsigned long io_base, io_range, lcr_io_base, lcr_io_range;
+
+ // Enable PCI device and request regions
+ if (comedi_pci_enable(pci_dev, PCI6208_DRIVER_NAME) < 0) {
+ printk("comedi%d: Failed to enable PCI device and request regions\n", dev_minor);
+ return -EIO;
+ }
+ // Read local configuration register base address [PCI_BASE_ADDRESS #1].
+ lcr_io_base = pci_resource_start(pci_dev, 1);
+ lcr_io_range = pci_resource_len(pci_dev, 1);
+
+ printk("comedi%d: local config registers at address 0x%4lx [0x%4lx]\n",
+ dev_minor, lcr_io_base, lcr_io_range);
+
+ // Read PCI6208 register base address [PCI_BASE_ADDRESS #2].
+ io_base = pci_resource_start(pci_dev, 2);
+ io_range = pci_resource_end(pci_dev, 2) - io_base + 1;
+
+ printk("comedi%d: 6208 registers at address 0x%4lx [0x%4lx]\n",
+ dev_minor, io_base, io_range);
+
+ *io_base_ptr = io_base;
+ //devpriv->io_range = io_range;
+ //devpriv->is_valid=0;
+ //devpriv->lcr_io_base=lcr_io_base;
+ //devpriv->lcr_io_range=lcr_io_range;
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c
new file mode 100644
index 00000000000..bd0f9ab226e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci7296.c
@@ -0,0 +1,174 @@
+/*
+ comedi/drivers/adl_pci7296.c
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: adl_pci7296
+Description: Driver for the Adlink PCI-7296 96 ch. digital io board
+Devices: [ADLink] PCI-7296 (adl_pci7296)
+Author: Jon Grierson <jd@renko.co.uk>
+Updated: Mon, 14 Apr 2008 15:05:56 +0100
+Status: testing
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+*/
+
+#include "../comedidev.h"
+#include <linux/kernel.h>
+
+#include "comedi_pci.h"
+#include "8255.h"
+// #include "8253.h"
+
+#define PORT1A 0
+#define PORT2A 4
+#define PORT3A 8
+#define PORT4A 12
+
+#define PCI_DEVICE_ID_PCI7296 0x7296
+
+static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = {
+ {PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296, PCI_ANY_ID, PCI_ANY_ID, 0,
+ 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, adl_pci7296_pci_table);
+
+struct adl_pci7296_private {
+ int data;
+ struct pci_dev *pci_dev;
+};
+
+
+#define devpriv ((struct adl_pci7296_private *)dev->private)
+
+static int adl_pci7296_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int adl_pci7296_detach(struct comedi_device * dev);
+static struct comedi_driver driver_adl_pci7296 = {
+ driver_name:"adl_pci7296",
+ module:THIS_MODULE,
+ attach:adl_pci7296_attach,
+ detach:adl_pci7296_detach,
+};
+
+static int adl_pci7296_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev;
+ struct comedi_subdevice *s;
+ int bus, slot;
+ int ret;
+
+ printk("comedi: attempt to attach...\n");
+ printk("comedi%d: adl_pci7432\n", dev->minor);
+
+ dev->board_name = "pci7432";
+ bus = it->options[0];
+ slot = it->options[1];
+
+ if (alloc_private(dev, sizeof(struct adl_pci7296_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+
+ if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
+ pcidev->device == PCI_DEVICE_ID_PCI7296) {
+ if (bus || slot) {
+ /* requested particular bus/slot */
+ if (pcidev->bus->number != bus
+ || PCI_SLOT(pcidev->devfn) != slot) {
+ continue;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+ if (comedi_pci_enable(pcidev, "adl_pci7296") < 0) {
+ printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
+ return -EIO;
+ }
+
+ dev->iobase = pci_resource_start(pcidev, 2);
+ printk("comedi: base addr %4lx\n", dev->iobase);
+
+ // four 8255 digital io subdevices
+ s = dev->subdevices + 0;
+ subdev_8255_init(dev, s, NULL,
+ (unsigned long)(dev->iobase));
+
+ s = dev->subdevices + 1;
+ ret = subdev_8255_init(dev, s, NULL,
+ (unsigned long)(dev->iobase + PORT2A));
+ if (ret < 0)
+ return ret;
+
+ s = dev->subdevices + 2;
+ ret = subdev_8255_init(dev, s, NULL,
+ (unsigned long)(dev->iobase + PORT3A));
+ if (ret < 0)
+ return ret;
+
+ s = dev->subdevices + 3;
+ ret = subdev_8255_init(dev, s, NULL,
+ (unsigned long)(dev->iobase + PORT4A));
+ if (ret < 0)
+ return ret;
+
+ printk("attached\n");
+
+ return 1;
+ }
+ }
+
+ printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+ dev->minor, bus, slot);
+ return -EIO;
+}
+
+static int adl_pci7296_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pci7432: remove\n", dev->minor);
+
+ if (devpriv && devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ // detach four 8255 digital io subdevices
+ if (dev->subdevices) {
+ subdev_8255_cleanup(dev, dev->subdevices + 0);
+ subdev_8255_cleanup(dev, dev->subdevices + 1);
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+ subdev_8255_cleanup(dev, dev->subdevices + 3);
+
+ }
+
+ return 0;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_adl_pci7296, adl_pci7296_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c
new file mode 100644
index 00000000000..a8f1715608d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci7432.c
@@ -0,0 +1,202 @@
+/*
+ comedi/drivers/adl_pci7432.c
+
+ Hardware comedi driver fot PCI7432 Adlink card
+ Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca>
+
+ 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.
+
+*/
+/*
+Driver: adl_pci7432
+Description: Driver for the Adlink PCI-7432 64 ch. isolated digital io board
+Devices: [ADLink] PCI-7432 (adl_pci7432)
+Author: Michel Lachaine <mike@mikelachaine.ca>
+Status: experimental
+Updated: Mon, 14 Apr 2008 15:08:14 +0100
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+*/
+
+#include "../comedidev.h"
+#include <linux/kernel.h>
+#include "comedi_pci.h"
+
+#define PCI7432_DI 0x00
+#define PCI7432_DO 0x00
+
+#define PCI_DEVICE_ID_PCI7432 0x7432
+
+static DEFINE_PCI_DEVICE_TABLE(adl_pci7432_pci_table) = {
+ {PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432, PCI_ANY_ID, PCI_ANY_ID, 0,
+ 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, adl_pci7432_pci_table);
+
+struct adl_pci7432_private {
+ int data;
+ struct pci_dev *pci_dev;
+};
+
+#define devpriv ((struct adl_pci7432_private *)dev->private)
+
+static int adl_pci7432_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int adl_pci7432_detach(struct comedi_device * dev);
+static struct comedi_driver driver_adl_pci7432 = {
+ driver_name:"adl_pci7432",
+ module:THIS_MODULE,
+ attach:adl_pci7432_attach,
+ detach:adl_pci7432_detach,
+};
+
+/* Digital IO */
+
+static int adl_pci7432_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci7432_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/* */
+
+static int adl_pci7432_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev;
+ struct comedi_subdevice *s;
+ int bus, slot;
+
+ printk("comedi: attempt to attach...\n");
+ printk("comedi%d: adl_pci7432\n", dev->minor);
+
+ dev->board_name = "pci7432";
+ bus = it->options[0];
+ slot = it->options[1];
+
+ if (alloc_private(dev, sizeof(struct adl_pci7432_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+
+ if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
+ pcidev->device == PCI_DEVICE_ID_PCI7432) {
+ if (bus || slot) {
+ /* requested particular bus/slot */
+ if (pcidev->bus->number != bus
+ || PCI_SLOT(pcidev->devfn) != slot) {
+ continue;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+ if (comedi_pci_enable(pcidev, "adl_pci7432") < 0) {
+ printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
+ return -EIO;
+ }
+ dev->iobase = pci_resource_start(pcidev, 2);
+ printk("comedi: base addr %4lx\n", dev->iobase);
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags =
+ SDF_READABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 32;
+ s->maxdata = 1;
+ s->len_chanlist = 32;
+ s->io_bits = 0x00000000;
+ s->range_table = &range_digital;
+ s->insn_bits = adl_pci7432_di_insn_bits;
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags =
+ SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 32;
+ s->maxdata = 1;
+ s->len_chanlist = 32;
+ s->io_bits = 0xffffffff;
+ s->range_table = &range_digital;
+ s->insn_bits = adl_pci7432_do_insn_bits;
+
+ printk("comedi: attached\n");
+
+ return 1;
+ }
+ }
+
+ printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+ dev->minor, bus, slot);
+ return -EIO;
+}
+
+static int adl_pci7432_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pci7432: remove\n", dev->minor);
+
+ if (devpriv && devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
+ return 0;
+}
+
+static int adl_pci7432_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ printk("comedi: pci7432_do_insn_bits called\n");
+ printk("comedi: data0: %8x data1: %8x\n", data[0], data[1]);
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+
+ printk("comedi: out: %8x on iobase %4lx\n", s->state,
+ dev->iobase + PCI7432_DO);
+ outl(s->state & 0xffffffff, dev->iobase + PCI7432_DO);
+ }
+ return 2;
+}
+
+static int adl_pci7432_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ printk("comedi: pci7432_di_insn_bits called\n");
+ printk("comedi: data0: %8x data1: %8x\n", data[0], data[1]);
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inl(dev->iobase + PCI7432_DI) & 0xffffffff;
+ printk("comedi: data1 %8x\n", data[1]);
+
+ return 2;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_adl_pci7432, adl_pci7432_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c
new file mode 100644
index 00000000000..adf90be7998
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci8164.c
@@ -0,0 +1,512 @@
+/*
+ comedi/drivers/adl_pci8164.c
+
+ Hardware comedi driver fot PCI-8164 Adlink card
+ Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca>
+
+ 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.
+
+*/
+/*
+Driver: adl_pci8164
+Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board
+Devices: [ADLink] PCI-8164 (adl_pci8164)
+Author: Michel Lachaine <mike@mikelachaine.ca>
+Status: experimental
+Updated: Mon, 14 Apr 2008 15:10:32 +0100
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+#include "comedi_fc.h"
+#include "comedi_pci.h"
+#include "8253.h"
+
+#define PCI8164_AXIS_X 0x00
+#define PCI8164_AXIS_Y 0x08
+#define PCI8164_AXIS_Z 0x10
+#define PCI8164_AXIS_U 0x18
+
+#define PCI8164_MSTS 0x00
+#define PCI8164_SSTS 0x02
+#define PCI8164_BUF0 0x04
+#define PCI8164_BUF1 0x06
+
+#define PCI8164_CMD 0x00
+#define PCI8164_OTP 0x02
+
+#define PCI_DEVICE_ID_PCI8164 0x8164
+
+static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = {
+ {PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164, PCI_ANY_ID, PCI_ANY_ID, 0,
+ 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table);
+
+struct adl_pci8164_private {
+ int data;
+ struct pci_dev *pci_dev;
+};
+
+#define devpriv ((struct adl_pci8164_private *)dev->private)
+
+static int adl_pci8164_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int adl_pci8164_detach(struct comedi_device * dev);
+static struct comedi_driver driver_adl_pci8164 = {
+ driver_name:"adl_pci8164",
+ module:THIS_MODULE,
+ attach:adl_pci8164_attach,
+ detach:adl_pci8164_detach,
+};
+
+static int adl_pci8164_insn_read_msts(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_read_ssts(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_read_buf0(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_read_buf1(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_write_cmd(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_write_otp(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_write_buf0(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_write_buf1(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev;
+ struct comedi_subdevice *s;
+ int bus, slot;
+
+ printk("comedi: attempt to attach...\n");
+ printk("comedi%d: adl_pci8164\n", dev->minor);
+
+ dev->board_name = "pci8164";
+ bus = it->options[0];
+ slot = it->options[1];
+
+ if (alloc_private(dev, sizeof(struct adl_pci8164_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+
+ if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
+ pcidev->device == PCI_DEVICE_ID_PCI8164) {
+ if (bus || slot) {
+ /* requested particular bus/slot */
+ if (pcidev->bus->number != bus
+ || PCI_SLOT(pcidev->devfn) != slot) {
+ continue;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+ if (comedi_pci_enable(pcidev, "adl_pci8164") < 0) {
+ printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
+ return -EIO;
+ }
+ dev->iobase = pci_resource_start(pcidev, 2);
+ printk("comedi: base addr %4lx\n", dev->iobase);
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_PROC;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 4;
+ //s->range_table = &range_axis;
+ s->insn_read = adl_pci8164_insn_read_msts;
+ s->insn_write = adl_pci8164_insn_write_cmd;
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_PROC;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 4;
+ //s->range_table = &range_axis;
+ s->insn_read = adl_pci8164_insn_read_ssts;
+ s->insn_write = adl_pci8164_insn_write_otp;
+
+ s = dev->subdevices + 2;
+ s->type = COMEDI_SUBD_PROC;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 4;
+ //s->range_table = &range_axis;
+ s->insn_read = adl_pci8164_insn_read_buf0;
+ s->insn_write = adl_pci8164_insn_write_buf0;
+
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_PROC;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 4;
+ //s->range_table = &range_axis;
+ s->insn_read = adl_pci8164_insn_read_buf1;
+ s->insn_write = adl_pci8164_insn_write_buf1;
+
+ printk("comedi: attached\n");
+
+ return 1;
+ }
+ }
+
+ printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+ dev->minor, bus, slot);
+ return -EIO;
+}
+
+static int adl_pci8164_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pci8164: remove\n", dev->minor);
+
+ if (devpriv && devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
+ return 0;
+}
+
+static int adl_pci8164_insn_read_msts(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ data[0] = inw(dev->iobase + axis_reg + PCI8164_MSTS);
+ printk("comedi: pci8164 MSTS read -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_read_ssts(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ data[0] = inw(dev->iobase + axis_reg + PCI8164_SSTS);
+ printk("comedi: pci8164 SSTS read -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_read_buf0(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ data[0] = inw(dev->iobase + axis_reg + PCI8164_BUF0);
+ printk("comedi: pci8164 BUF0 read -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_read_buf1(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ data[0] = inw(dev->iobase + axis_reg + PCI8164_BUF1);
+ printk("comedi: pci8164 BUF1 read -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_write_cmd(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int axis, axis_reg;
+
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ outw(data[0], dev->iobase + axis_reg + PCI8164_CMD);
+ printk("comedi: pci8164 CMD write -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_write_otp(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ outw(data[0], dev->iobase + axis_reg + PCI8164_OTP);
+ printk("comedi: pci8164 OTP write -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_write_buf0(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ outw(data[0], dev->iobase + axis_reg + PCI8164_BUF0);
+ printk("comedi: pci8164 BUF0 write -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_write_buf1(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ outw(data[0], dev->iobase + axis_reg + PCI8164_BUF1);
+ printk("comedi: pci8164 BUF1 write -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_adl_pci8164, adl_pci8164_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
new file mode 100644
index 00000000000..b4a61c560c5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -0,0 +1,1391 @@
+/*
+
+ comedi/drivers/adl_pci9111.c
+
+ Hardware driver for PCI9111 ADLink cards:
+
+ PCI-9111HR
+
+ Copyright (C) 2002-2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
+
+ 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.
+*/
+
+/*
+Driver: adl_pci9111
+Description: Adlink PCI-9111HR
+Author: Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
+Devices: [ADLink] PCI-9111HR (adl_pci9111)
+Status: experimental
+
+Supports:
+
+ - ai_insn read
+ - ao_insn read/write
+ - di_insn read
+ - do_insn read/write
+ - ai_do_cmd mode with the following sources:
+
+ - start_src TRIG_NOW
+ - scan_begin_src TRIG_FOLLOW TRIG_TIMER TRIG_EXT
+ - convert_src TRIG_TIMER TRIG_EXT
+ - scan_end_src TRIG_COUNT
+ - stop_src TRIG_COUNT TRIG_NONE
+
+ The scanned channels must be consecutive and start from 0. They must
+ all have the same range and aref.
+
+Configuration options:
+
+ [0] - PCI bus number (optional)
+ [1] - PCI slot number (optional)
+
+ If bus/slot is not specified, the first available PCI
+ device will be used.
+
+*/
+
+/*
+CHANGELOG:
+
+ 2005/02/17 Extend AI streaming capabilities. Now, scan_begin_arg can be
+ a multiple of chanlist_len*convert_arg.
+ 2002/02/19 Fixed the two's complement conversion in pci9111_(hr_)ai_get_data.
+ 2002/02/18 Added external trigger support for analog input.
+
+TODO:
+
+ - Really test implemented functionality.
+ - Add support for the PCI-9111DG with a probe routine to identify the card type
+ (perhaps with the help of the channel number readback of the A/D Data register).
+ - Add external multiplexer support.
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "8253.h"
+#include "comedi_pci.h"
+#include "comedi_fc.h"
+
+#define PCI9111_DRIVER_NAME "adl_pci9111"
+#define PCI9111_HR_DEVICE_ID 0x9111
+
+/* TODO: Add other pci9111 board id */
+
+#define PCI9111_IO_RANGE 0x0100
+
+#define PCI9111_FIFO_HALF_SIZE 512
+
+#define PCI9111_AI_CHANNEL_NBR 16
+
+#define PCI9111_AI_RESOLUTION 12
+#define PCI9111_AI_RESOLUTION_MASK 0x0FFF
+#define PCI9111_AI_RESOLUTION_2_CMP_BIT 0x0800
+
+#define PCI9111_HR_AI_RESOLUTION 16
+#define PCI9111_HR_AI_RESOLUTION_MASK 0xFFFF
+#define PCI9111_HR_AI_RESOLUTION_2_CMP_BIT 0x8000
+
+#define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS 10000
+#define PCI9111_AO_CHANNEL_NBR 1
+#define PCI9111_AO_RESOLUTION 12
+#define PCI9111_AO_RESOLUTION_MASK 0x0FFF
+#define PCI9111_DI_CHANNEL_NBR 16
+#define PCI9111_DO_CHANNEL_NBR 16
+#define PCI9111_DO_MASK 0xFFFF
+
+#define PCI9111_RANGE_SETTING_DELAY 10
+#define PCI9111_AI_INSTANT_READ_UDELAY_US 2
+#define PCI9111_AI_INSTANT_READ_TIMEOUT 100
+
+#define PCI9111_8254_CLOCK_PERIOD_NS 500
+
+#define PCI9111_8254_COUNTER_0 0x00
+#define PCI9111_8254_COUNTER_1 0x40
+#define PCI9111_8254_COUNTER_2 0x80
+#define PCI9111_8254_COUNTER_LATCH 0x00
+#define PCI9111_8254_READ_LOAD_LSB_ONLY 0x10
+#define PCI9111_8254_READ_LOAD_MSB_ONLY 0x20
+#define PCI9111_8254_READ_LOAD_LSB_MSB 0x30
+#define PCI9111_8254_MODE_0 0x00
+#define PCI9111_8254_MODE_1 0x02
+#define PCI9111_8254_MODE_2 0x04
+#define PCI9111_8254_MODE_3 0x06
+#define PCI9111_8254_MODE_4 0x08
+#define PCI9111_8254_MODE_5 0x0A
+#define PCI9111_8254_BINARY_COUNTER 0x00
+#define PCI9111_8254_BCD_COUNTER 0x01
+
+/* IO address map */
+
+#define PCI9111_REGISTER_AD_FIFO_VALUE 0x00 /* AD Data stored in FIFO */
+#define PCI9111_REGISTER_DA_OUTPUT 0x00
+#define PCI9111_REGISTER_DIGITAL_IO 0x02
+#define PCI9111_REGISTER_EXTENDED_IO_PORTS 0x04
+#define PCI9111_REGISTER_AD_CHANNEL_CONTROL 0x06 /* Channel selection */
+#define PCI9111_REGISTER_AD_CHANNEL_READBACK 0x06
+#define PCI9111_REGISTER_INPUT_SIGNAL_RANGE 0x08
+#define PCI9111_REGISTER_RANGE_STATUS_READBACK 0x08
+#define PCI9111_REGISTER_TRIGGER_MODE_CONTROL 0x0A
+#define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK 0x0A
+#define PCI9111_REGISTER_SOFTWARE_TRIGGER 0x0E
+#define PCI9111_REGISTER_INTERRUPT_CONTROL 0x0C
+#define PCI9111_REGISTER_8254_COUNTER_0 0x40
+#define PCI9111_REGISTER_8254_COUNTER_1 0x42
+#define PCI9111_REGISTER_8254_COUNTER_2 0X44
+#define PCI9111_REGISTER_8254_CONTROL 0x46
+#define PCI9111_REGISTER_INTERRUPT_CLEAR 0x48
+
+#define PCI9111_TRIGGER_MASK 0x0F
+#define PCI9111_PTRG_OFF (0 << 3)
+#define PCI9111_PTRG_ON (1 << 3)
+#define PCI9111_EITS_EXTERNAL (1 << 2)
+#define PCI9111_EITS_INTERNAL (0 << 2)
+#define PCI9111_TPST_SOFTWARE_TRIGGER (0 << 1)
+#define PCI9111_TPST_TIMER_PACER (1 << 1)
+#define PCI9111_ASCAN_ON (1 << 0)
+#define PCI9111_ASCAN_OFF (0 << 0)
+
+#define PCI9111_ISC0_SET_IRQ_ON_ENDING_OF_AD_CONVERSION (0 << 0)
+#define PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL (1 << 0)
+#define PCI9111_ISC1_SET_IRQ_ON_TIMER_TICK (0 << 1)
+#define PCI9111_ISC1_SET_IRQ_ON_EXT_TRG (1 << 1)
+#define PCI9111_FFEN_SET_FIFO_ENABLE (0 << 2)
+#define PCI9111_FFEN_SET_FIFO_DISABLE (1 << 2)
+
+#define PCI9111_CHANNEL_MASK 0x0F
+
+#define PCI9111_RANGE_MASK 0x07
+#define PCI9111_FIFO_EMPTY_MASK 0x10
+#define PCI9111_FIFO_HALF_FULL_MASK 0x20
+#define PCI9111_FIFO_FULL_MASK 0x40
+#define PCI9111_AD_BUSY_MASK 0x80
+
+#define PCI9111_IO_BASE dev->iobase
+
+/*
+ * Define inlined function
+ */
+
+#define pci9111_trigger_and_autoscan_get() \
+ (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK)&0x0F)
+
+#define pci9111_trigger_and_autoscan_set(flags) \
+ outb(flags,PCI9111_IO_BASE+PCI9111_REGISTER_TRIGGER_MODE_CONTROL)
+
+#define pci9111_interrupt_and_fifo_get() \
+ ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) >> 4) &0x03)
+
+#define pci9111_interrupt_and_fifo_set(flags) \
+ outb(flags,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
+
+#define pci9111_interrupt_clear() \
+ outb(0,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CLEAR)
+
+#define pci9111_software_trigger() \
+ outb(0,PCI9111_IO_BASE+PCI9111_REGISTER_SOFTWARE_TRIGGER)
+
+#define pci9111_fifo_reset() \
+ outb(PCI9111_FFEN_SET_FIFO_ENABLE,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
+ outb(PCI9111_FFEN_SET_FIFO_DISABLE,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
+ outb(PCI9111_FFEN_SET_FIFO_ENABLE,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
+
+#define pci9111_is_fifo_full() \
+ ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
+ PCI9111_FIFO_FULL_MASK)==0)
+
+#define pci9111_is_fifo_half_full() \
+ ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
+ PCI9111_FIFO_HALF_FULL_MASK)==0)
+
+#define pci9111_is_fifo_empty() \
+ ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
+ PCI9111_FIFO_EMPTY_MASK)==0)
+
+#define pci9111_ai_channel_set(channel) \
+ outb((channel)&PCI9111_CHANNEL_MASK,PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_CONTROL)
+
+#define pci9111_ai_channel_get() \
+ inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_READBACK)&PCI9111_CHANNEL_MASK
+
+#define pci9111_ai_range_set(range) \
+ outb((range)&PCI9111_RANGE_MASK,PCI9111_IO_BASE+PCI9111_REGISTER_INPUT_SIGNAL_RANGE)
+
+#define pci9111_ai_range_get() \
+ inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)&PCI9111_RANGE_MASK
+
+#define pci9111_ai_get_data() \
+ ((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)>>4)&PCI9111_AI_RESOLUTION_MASK) \
+ ^ PCI9111_AI_RESOLUTION_2_CMP_BIT
+
+#define pci9111_hr_ai_get_data() \
+ (inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE) & PCI9111_HR_AI_RESOLUTION_MASK) \
+ ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT
+
+#define pci9111_ao_set_data(data) \
+ outw(data&PCI9111_AO_RESOLUTION_MASK,PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT)
+
+#define pci9111_di_get_bits() \
+ inw(PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
+
+#define pci9111_do_set_bits(bits) \
+ outw(bits,PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
+
+#define pci9111_8254_control_set(flags) \
+ outb(flags,PCI9111_IO_BASE+PCI9111_REGISTER_8254_CONTROL)
+
+#define pci9111_8254_counter_0_set(data) \
+ outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \
+ outb( (data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0)
+
+#define pci9111_8254_counter_1_set(data) \
+ outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \
+ outb( (data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1)
+
+#define pci9111_8254_counter_2_set(data) \
+ outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \
+ outb( (data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2)
+
+/* Function prototypes */
+
+static int pci9111_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci9111_detach(struct comedi_device * dev);
+static void pci9111_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *data, unsigned int num_bytes, unsigned int start_chan_index);
+
+static const struct comedi_lrange pci9111_hr_ai_range = {
+ 5,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625)
+ }
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = {
+ {PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0,
+ 0, 0},
+ /* { PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci9111_pci_table);
+
+/* */
+/* Board specification structure */
+/* */
+
+struct pci9111_board {
+ const char *name; /* driver name */
+ int device_id;
+ int ai_channel_nbr; /* num of A/D chans */
+ int ao_channel_nbr; /* num of D/A chans */
+ int ai_resolution; /* resolution of A/D */
+ int ai_resolution_mask;
+ int ao_resolution; /* resolution of D/A */
+ int ao_resolution_mask;
+ const struct comedi_lrange *ai_range_list; /* rangelist for A/D */
+ const struct comedi_lrange *ao_range_list; /* rangelist for D/A */
+ unsigned int ai_acquisition_period_min_ns;
+};
+
+static const struct pci9111_board pci9111_boards[] = {
+ {
+ name: "pci9111_hr",
+ device_id:PCI9111_HR_DEVICE_ID,
+ ai_channel_nbr:PCI9111_AI_CHANNEL_NBR,
+ ao_channel_nbr:PCI9111_AO_CHANNEL_NBR,
+ ai_resolution:PCI9111_HR_AI_RESOLUTION,
+ ai_resolution_mask:PCI9111_HR_AI_RESOLUTION_MASK,
+ ao_resolution:PCI9111_AO_RESOLUTION,
+ ao_resolution_mask:PCI9111_AO_RESOLUTION_MASK,
+ ai_range_list:&pci9111_hr_ai_range,
+ ao_range_list:&range_bipolar10,
+ ai_acquisition_period_min_ns:PCI9111_AI_ACQUISITION_PERIOD_MIN_NS}
+};
+
+#define pci9111_board_nbr \
+ (sizeof(pci9111_boards)/sizeof(struct pci9111_board))
+
+static struct comedi_driver pci9111_driver = {
+ driver_name:PCI9111_DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:pci9111_attach,
+ detach:pci9111_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(pci9111_driver, pci9111_pci_table);
+
+/* Private data structure */
+
+struct pci9111_private_data {
+ struct pci_dev *pci_device;
+ unsigned long io_range; /* PCI6503 io range */
+
+ unsigned long lcr_io_base; /* Local configuration register base address */
+ unsigned long lcr_io_range;
+
+ int stop_counter;
+ int stop_is_none;
+
+ unsigned int scan_delay;
+ unsigned int chanlist_len;
+ unsigned int chunk_counter;
+ unsigned int chunk_num_samples;
+
+ int ao_readback; /* Last written analog output data */
+
+ int timer_divisor_1; /* Divisor values for the 8254 timer pacer */
+ int timer_divisor_2;
+
+ int is_valid; /* Is device valid */
+
+ short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
+};
+
+#define dev_private ((struct pci9111_private_data *)dev->private)
+
+/* ------------------------------------------------------------------ */
+/* PLX9050 SECTION */
+/* ------------------------------------------------------------------ */
+
+#define PLX9050_REGISTER_INTERRUPT_CONTROL 0x4c
+
+#define PLX9050_LINTI1_ENABLE (1 << 0)
+#define PLX9050_LINTI1_ACTIVE_HIGH (1 << 1)
+#define PLX9050_LINTI1_STATUS (1 << 2)
+#define PLX9050_LINTI2_ENABLE (1 << 3)
+#define PLX9050_LINTI2_ACTIVE_HIGH (1 << 4)
+#define PLX9050_LINTI2_STATUS (1 << 5)
+#define PLX9050_PCI_INTERRUPT_ENABLE (1 << 6)
+#define PLX9050_SOFTWARE_INTERRUPT (1 << 7)
+
+static void plx9050_interrupt_control(unsigned long io_base,
+ bool LINTi1_enable,
+ bool LINTi1_active_high,
+ bool LINTi2_enable, bool LINTi2_active_high, bool interrupt_enable)
+{
+ int flags = 0;
+
+ if (LINTi1_enable)
+ flags |= PLX9050_LINTI1_ENABLE;
+ if (LINTi1_active_high)
+ flags |= PLX9050_LINTI1_ACTIVE_HIGH;
+ if (LINTi2_enable)
+ flags |= PLX9050_LINTI2_ENABLE;
+ if (LINTi2_active_high)
+ flags |= PLX9050_LINTI2_ACTIVE_HIGH;
+
+ if (interrupt_enable)
+ flags |= PLX9050_PCI_INTERRUPT_ENABLE;
+
+ outb(flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL);
+}
+
+/* ------------------------------------------------------------------ */
+/* MISCELLANEOUS SECTION */
+/* ------------------------------------------------------------------ */
+
+/* 8254 timer */
+
+static void pci9111_timer_set(struct comedi_device * dev)
+{
+ pci9111_8254_control_set(PCI9111_8254_COUNTER_0 |
+ PCI9111_8254_READ_LOAD_LSB_MSB |
+ PCI9111_8254_MODE_0 | PCI9111_8254_BINARY_COUNTER);
+
+ pci9111_8254_control_set(PCI9111_8254_COUNTER_1 |
+ PCI9111_8254_READ_LOAD_LSB_MSB |
+ PCI9111_8254_MODE_2 | PCI9111_8254_BINARY_COUNTER);
+
+ pci9111_8254_control_set(PCI9111_8254_COUNTER_2 |
+ PCI9111_8254_READ_LOAD_LSB_MSB |
+ PCI9111_8254_MODE_2 | PCI9111_8254_BINARY_COUNTER);
+
+ comedi_udelay(1);
+
+ pci9111_8254_counter_2_set(dev_private->timer_divisor_2);
+ pci9111_8254_counter_1_set(dev_private->timer_divisor_1);
+}
+
+enum pci9111_trigger_sources {
+ software,
+ timer_pacer,
+ external
+};
+
+static void pci9111_trigger_source_set(struct comedi_device * dev,
+ enum pci9111_trigger_sources source)
+{
+ int flags;
+
+ flags = pci9111_trigger_and_autoscan_get() & 0x09;
+
+ switch (source) {
+ case software:
+ flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_SOFTWARE_TRIGGER;
+ break;
+
+ case timer_pacer:
+ flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_TIMER_PACER;
+ break;
+
+ case external:
+ flags |= PCI9111_EITS_EXTERNAL;
+ break;
+ }
+
+ pci9111_trigger_and_autoscan_set(flags);
+}
+
+static void pci9111_pretrigger_set(struct comedi_device * dev, bool pretrigger)
+{
+ int flags;
+
+ flags = pci9111_trigger_and_autoscan_get() & 0x07;
+
+ if (pretrigger)
+ flags |= PCI9111_PTRG_ON;
+
+ pci9111_trigger_and_autoscan_set(flags);
+}
+
+static void pci9111_autoscan_set(struct comedi_device * dev, bool autoscan)
+{
+ int flags;
+
+ flags = pci9111_trigger_and_autoscan_get() & 0x0e;
+
+ if (autoscan)
+ flags |= PCI9111_ASCAN_ON;
+
+ pci9111_trigger_and_autoscan_set(flags);
+}
+
+enum pci9111_ISC0_sources {
+ irq_on_eoc,
+ irq_on_fifo_half_full
+};
+
+enum pci9111_ISC1_sources {
+ irq_on_timer_tick,
+ irq_on_external_trigger
+};
+
+static void pci9111_interrupt_source_set(struct comedi_device * dev,
+ enum pci9111_ISC0_sources irq_0_source, enum pci9111_ISC1_sources irq_1_source)
+{
+ int flags;
+
+ flags = pci9111_interrupt_and_fifo_get() & 0x04;
+
+ if (irq_0_source == irq_on_fifo_half_full)
+ flags |= PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL;
+
+ if (irq_1_source == irq_on_external_trigger)
+ flags |= PCI9111_ISC1_SET_IRQ_ON_EXT_TRG;
+
+ pci9111_interrupt_and_fifo_set(flags);
+}
+
+/* ------------------------------------------------------------------ */
+/* HARDWARE TRIGGERED ANALOG INPUT SECTION */
+/* ------------------------------------------------------------------ */
+
+/* Cancel analog input autoscan */
+
+#undef AI_DO_CMD_DEBUG
+
+static int pci9111_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ /* Disable interrupts */
+
+ plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
+ true, false);
+
+ pci9111_trigger_source_set(dev, software);
+
+ pci9111_autoscan_set(dev, false);
+
+ pci9111_fifo_reset();
+
+#ifdef AI_DO_CMD_DEBUG
+ printk(PCI9111_DRIVER_NAME ": ai_cancel\n");
+#endif
+
+ return 0;
+}
+
+/* Test analog input command */
+
+#define pci9111_check_trigger_src(src,flags) \
+ tmp = src; \
+ src &= flags; \
+ if (!src || tmp != src) error++
+
+static int
+pci9111_ai_do_cmd_test(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_cmd * cmd)
+{
+ int tmp;
+ int error = 0;
+ int range, reference;
+ int i;
+ struct pci9111_board *board = (struct pci9111_board *) dev->board_ptr;
+
+ /* Step 1 : check if trigger are trivialy valid */
+
+ pci9111_check_trigger_src(cmd->start_src, TRIG_NOW);
+ pci9111_check_trigger_src(cmd->scan_begin_src,
+ TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
+ pci9111_check_trigger_src(cmd->convert_src, TRIG_TIMER | TRIG_EXT);
+ pci9111_check_trigger_src(cmd->scan_end_src, TRIG_COUNT);
+ pci9111_check_trigger_src(cmd->stop_src, TRIG_COUNT | TRIG_NONE);
+
+ if (error)
+ return 1;
+
+ /* step 2 : make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW)
+ error++;
+
+ if ((cmd->scan_begin_src != TRIG_TIMER) &&
+ (cmd->scan_begin_src != TRIG_FOLLOW) &&
+ (cmd->scan_begin_src != TRIG_EXT))
+ error++;
+
+ if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT)) {
+ error++;
+ }
+ if ((cmd->convert_src == TRIG_TIMER) &&
+ !((cmd->scan_begin_src == TRIG_TIMER) ||
+ (cmd->scan_begin_src == TRIG_FOLLOW))) {
+ error++;
+ }
+ if ((cmd->convert_src == TRIG_EXT) &&
+ !((cmd->scan_begin_src == TRIG_EXT) ||
+ (cmd->scan_begin_src == TRIG_FOLLOW))) {
+ error++;
+ }
+
+ if (cmd->scan_end_src != TRIG_COUNT)
+ error++;
+ if ((cmd->stop_src != TRIG_COUNT) && (cmd->stop_src != TRIG_NONE))
+ error++;
+
+ if (error)
+ return 2;
+
+ /* Step 3 : make sure arguments are trivialy compatible */
+
+ if (cmd->chanlist_len < 1) {
+ cmd->chanlist_len = 1;
+ error++;
+ }
+
+ if (cmd->chanlist_len > board->ai_channel_nbr) {
+ cmd->chanlist_len = board->ai_channel_nbr;
+ error++;
+ }
+
+ if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) {
+ cmd->start_arg = 0;
+ error++;
+ }
+
+ if ((cmd->convert_src == TRIG_TIMER) &&
+ (cmd->convert_arg < board->ai_acquisition_period_min_ns)) {
+ cmd->convert_arg = board->ai_acquisition_period_min_ns;
+ error++;
+ }
+ if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) {
+ cmd->convert_arg = 0;
+ error++;
+ }
+
+ if ((cmd->scan_begin_src == TRIG_TIMER) &&
+ (cmd->scan_begin_arg < board->ai_acquisition_period_min_ns)) {
+ cmd->scan_begin_arg = board->ai_acquisition_period_min_ns;
+ error++;
+ }
+ if ((cmd->scan_begin_src == TRIG_FOLLOW) && (cmd->scan_begin_arg != 0)) {
+ cmd->scan_begin_arg = 0;
+ error++;
+ }
+ if ((cmd->scan_begin_src == TRIG_EXT) && (cmd->scan_begin_arg != 0)) {
+ cmd->scan_begin_arg = 0;
+ error++;
+ }
+
+ if ((cmd->scan_end_src == TRIG_COUNT) &&
+ (cmd->scan_end_arg != cmd->chanlist_len)) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ error++;
+ }
+
+ if ((cmd->stop_src == TRIG_COUNT) && (cmd->stop_arg < 1)) {
+ cmd->stop_arg = 1;
+ error++;
+ }
+ if ((cmd->stop_src == TRIG_NONE) && (cmd->stop_arg != 0)) {
+ cmd->stop_arg = 0;
+ error++;
+ }
+
+ if (error)
+ return 3;
+
+ /* Step 4 : fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
+ &(dev_private->timer_divisor_1),
+ &(dev_private->timer_divisor_2),
+ &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ error++;
+ }
+ /* There's only one timer on this card, so the scan_begin timer must */
+ /* be a multiple of chanlist_len*convert_arg */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+
+ unsigned int scan_begin_min;
+ unsigned int scan_begin_arg;
+ unsigned int scan_factor;
+
+ scan_begin_min = cmd->chanlist_len * cmd->convert_arg;
+
+ if (cmd->scan_begin_arg != scan_begin_min) {
+ if (scan_begin_min < cmd->scan_begin_arg) {
+ scan_factor =
+ cmd->scan_begin_arg / scan_begin_min;
+ scan_begin_arg = scan_factor * scan_begin_min;
+ if (cmd->scan_begin_arg != scan_begin_arg) {
+ cmd->scan_begin_arg = scan_begin_arg;
+ error++;
+ }
+ } else {
+ cmd->scan_begin_arg = scan_begin_min;
+ error++;
+ }
+ }
+ }
+
+ if (error)
+ return 4;
+
+ /* Step 5 : check channel list */
+
+ if (cmd->chanlist) {
+
+ range = CR_RANGE(cmd->chanlist[0]);
+ reference = CR_AREF(cmd->chanlist[0]);
+
+ if (cmd->chanlist_len > 1) {
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) != i) {
+ comedi_error(dev,
+ "entries in chanlist must be consecutive "
+ "channels,counting upwards from 0\n");
+ error++;
+ }
+ if (CR_RANGE(cmd->chanlist[i]) != range) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same gain\n");
+ error++;
+ }
+ if (CR_AREF(cmd->chanlist[i]) != reference) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same reference\n");
+ error++;
+ }
+ }
+ } else {
+ if ((CR_CHAN(cmd->chanlist[0]) >
+ (board->ai_channel_nbr - 1))
+ || (CR_CHAN(cmd->chanlist[0]) < 0)) {
+ comedi_error(dev,
+ "channel number is out of limits\n");
+ error++;
+ }
+ }
+ }
+
+ if (error)
+ return 5;
+
+ return 0;
+
+}
+
+/* Analog input command */
+
+static int pci9111_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * subdevice)
+{
+ struct comedi_cmd *async_cmd = &subdevice->async->cmd;
+
+ if (!dev->irq) {
+ comedi_error(dev,
+ "no irq assigned for PCI9111, cannot do hardware conversion");
+ return -1;
+ }
+ /* Set channel scan limit */
+ /* PCI9111 allows only scanning from channel 0 to channel n */
+ /* TODO: handle the case of an external multiplexer */
+
+ if (async_cmd->chanlist_len > 1) {
+ pci9111_ai_channel_set((async_cmd->chanlist_len) - 1);
+ pci9111_autoscan_set(dev, true);
+ } else {
+ pci9111_ai_channel_set(CR_CHAN(async_cmd->chanlist[0]));
+ pci9111_autoscan_set(dev, false);
+ }
+
+ /* Set gain */
+ /* This is the same gain on every channel */
+
+ pci9111_ai_range_set(CR_RANGE(async_cmd->chanlist[0]));
+
+ /* Set counter */
+
+ switch (async_cmd->stop_src) {
+ case TRIG_COUNT:
+ dev_private->stop_counter =
+ async_cmd->stop_arg * async_cmd->chanlist_len;
+ dev_private->stop_is_none = 0;
+ break;
+
+ case TRIG_NONE:
+ dev_private->stop_counter = 0;
+ dev_private->stop_is_none = 1;
+ break;
+
+ default:
+ comedi_error(dev, "Invalid stop trigger");
+ return -1;
+ }
+
+ /* Set timer pacer */
+
+ dev_private->scan_delay = 0;
+ switch (async_cmd->convert_src) {
+ case TRIG_TIMER:
+ i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
+ &(dev_private->timer_divisor_1),
+ &(dev_private->timer_divisor_2),
+ &(async_cmd->convert_arg),
+ async_cmd->flags & TRIG_ROUND_MASK);
+#ifdef AI_DO_CMD_DEBUG
+ printk(PCI9111_DRIVER_NAME ": divisors = %d, %d\n",
+ dev_private->timer_divisor_1,
+ dev_private->timer_divisor_2);
+#endif
+
+ pci9111_trigger_source_set(dev, software);
+ pci9111_timer_set(dev);
+ pci9111_fifo_reset();
+ pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
+ irq_on_timer_tick);
+ pci9111_trigger_source_set(dev, timer_pacer);
+ plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
+ false, true, true);
+
+ dev_private->scan_delay =
+ (async_cmd->scan_begin_arg / (async_cmd->convert_arg *
+ async_cmd->chanlist_len)) - 1;
+
+ break;
+
+ case TRIG_EXT:
+
+ pci9111_trigger_source_set(dev, external);
+ pci9111_fifo_reset();
+ pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
+ irq_on_timer_tick);
+ plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
+ false, true, true);
+
+ break;
+
+ default:
+ comedi_error(dev, "Invalid convert trigger");
+ return -1;
+ }
+
+ dev_private->stop_counter *= (1 + dev_private->scan_delay);
+ dev_private->chanlist_len = async_cmd->chanlist_len;
+ dev_private->chunk_counter = 0;
+ dev_private->chunk_num_samples =
+ dev_private->chanlist_len * (1 + dev_private->scan_delay);
+
+#ifdef AI_DO_CMD_DEBUG
+ printk(PCI9111_DRIVER_NAME ": start interruptions!\n");
+ printk(PCI9111_DRIVER_NAME ": trigger source = %2x\n",
+ pci9111_trigger_and_autoscan_get());
+ printk(PCI9111_DRIVER_NAME ": irq source = %2x\n",
+ pci9111_interrupt_and_fifo_get());
+ printk(PCI9111_DRIVER_NAME ": ai_do_cmd\n");
+ printk(PCI9111_DRIVER_NAME ": stop counter = %d\n",
+ dev_private->stop_counter);
+ printk(PCI9111_DRIVER_NAME ": scan delay = %d\n",
+ dev_private->scan_delay);
+ printk(PCI9111_DRIVER_NAME ": chanlist_len = %d\n",
+ dev_private->chanlist_len);
+ printk(PCI9111_DRIVER_NAME ": chunk num samples = %d\n",
+ dev_private->chunk_num_samples);
+#endif
+
+ return 0;
+}
+
+static void pci9111_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *data, unsigned int num_bytes, unsigned int start_chan_index)
+{
+ unsigned int i, num_samples = num_bytes / sizeof(short);
+ short *array = data;
+ int resolution =
+ ((struct pci9111_board *) dev->board_ptr)->ai_resolution;
+
+ for (i = 0; i < num_samples; i++) {
+ if (resolution == PCI9111_HR_AI_RESOLUTION)
+ array[i] =
+ (array[i] & PCI9111_HR_AI_RESOLUTION_MASK) ^
+ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT;
+ else
+ array[i] =
+ ((array[i] >> 4) & PCI9111_AI_RESOLUTION_MASK) ^
+ PCI9111_AI_RESOLUTION_2_CMP_BIT;
+ }
+}
+
+/* ------------------------------------------------------------------ */
+/* INTERRUPT SECTION */
+/* ------------------------------------------------------------------ */
+
+#undef INTERRUPT_DEBUG
+
+static irqreturn_t pci9111_interrupt(int irq, void *p_device PT_REGS_ARG)
+{
+ struct comedi_device *dev = p_device;
+ struct comedi_subdevice *subdevice = dev->read_subdev;
+ struct comedi_async *async;
+ unsigned long irq_flags;
+ unsigned char intcsr;
+
+ if (!dev->attached) {
+ /* Ignore interrupt before device fully attached. */
+ /* Might not even have allocated subdevices yet! */
+ return IRQ_NONE;
+ }
+
+ async = subdevice->async;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+
+ /* Check if we are source of interrupt */
+ intcsr = inb(dev_private->lcr_io_base +
+ PLX9050_REGISTER_INTERRUPT_CONTROL);
+ if (!(((intcsr & PLX9050_PCI_INTERRUPT_ENABLE) != 0)
+ && (((intcsr & (PLX9050_LINTI1_ENABLE |
+ PLX9050_LINTI1_STATUS))
+ ==
+ (PLX9050_LINTI1_ENABLE |
+ PLX9050_LINTI1_STATUS))
+ || ((intcsr & (PLX9050_LINTI2_ENABLE |
+ PLX9050_LINTI2_STATUS))
+ ==
+ (PLX9050_LINTI2_ENABLE |
+ PLX9050_LINTI2_STATUS))))) {
+ /* Not the source of the interrupt. */
+ /* (N.B. not using PLX9050_SOFTWARE_INTERRUPT) */
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ return IRQ_NONE;
+ }
+
+ if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) ==
+ (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) {
+ /* Interrupt comes from fifo_half-full signal */
+
+ if (pci9111_is_fifo_full()) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock,
+ irq_flags);
+ comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow");
+ pci9111_interrupt_clear();
+ pci9111_ai_cancel(dev, subdevice);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, subdevice);
+
+ return IRQ_HANDLED;
+ }
+
+ if (pci9111_is_fifo_half_full()) {
+ unsigned int num_samples;
+ unsigned int bytes_written = 0;
+
+#ifdef INTERRUPT_DEBUG
+ printk(PCI9111_DRIVER_NAME ": fifo is half full\n");
+#endif
+
+ num_samples =
+ PCI9111_FIFO_HALF_SIZE >
+ dev_private->stop_counter
+ && !dev_private->stop_is_none ? dev_private->
+ stop_counter : PCI9111_FIFO_HALF_SIZE;
+ insw(PCI9111_IO_BASE + PCI9111_REGISTER_AD_FIFO_VALUE,
+ dev_private->ai_bounce_buffer, num_samples);
+
+ if (dev_private->scan_delay < 1) {
+ bytes_written =
+ cfc_write_array_to_buffer(subdevice,
+ dev_private->ai_bounce_buffer,
+ num_samples * sizeof(short));
+ } else {
+ int position = 0;
+ int to_read;
+
+ while (position < num_samples) {
+ if (dev_private->chunk_counter <
+ dev_private->chanlist_len) {
+ to_read =
+ dev_private->
+ chanlist_len -
+ dev_private->
+ chunk_counter;
+
+ if (to_read >
+ num_samples - position)
+ to_read =
+ num_samples -
+ position;
+
+ bytes_written +=
+ cfc_write_array_to_buffer
+ (subdevice,
+ dev_private->
+ ai_bounce_buffer +
+ position,
+ to_read *
+ sizeof(short));
+ } else {
+ to_read =
+ dev_private->
+ chunk_num_samples -
+ dev_private->
+ chunk_counter;
+ if (to_read >
+ num_samples - position)
+ to_read =
+ num_samples -
+ position;
+
+ bytes_written +=
+ sizeof(short) *
+ to_read;
+ }
+
+ position += to_read;
+ dev_private->chunk_counter += to_read;
+
+ if (dev_private->chunk_counter >=
+ dev_private->chunk_num_samples)
+ dev_private->chunk_counter = 0;
+ }
+ }
+
+ dev_private->stop_counter -=
+ bytes_written / sizeof(short);
+ }
+ }
+
+ if ((dev_private->stop_counter == 0) && (!dev_private->stop_is_none)) {
+ async->events |= COMEDI_CB_EOA;
+ pci9111_ai_cancel(dev, subdevice);
+ }
+
+ /* Very important, otherwise another interrupt request will be inserted
+ * and will cause driver hangs on processing interrupt event. */
+
+ pci9111_interrupt_clear();
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ comedi_event(dev, subdevice);
+
+ return IRQ_HANDLED;
+}
+
+/* ------------------------------------------------------------------ */
+/* INSTANT ANALOG INPUT OUTPUT SECTION */
+/* ------------------------------------------------------------------ */
+
+/* analog instant input */
+
+#undef AI_INSN_DEBUG
+
+static int pci9111_ai_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * subdevice, struct comedi_insn * insn, unsigned int * data)
+{
+ int resolution =
+ ((struct pci9111_board *) dev->board_ptr)->ai_resolution;
+
+ int timeout, i;
+
+#ifdef AI_INSN_DEBUG
+ printk(PCI9111_DRIVER_NAME ": ai_insn set c/r/n = %2x/%2x/%2x\n",
+ CR_CHAN((&insn->chanspec)[0]),
+ CR_RANGE((&insn->chanspec)[0]), insn->n);
+#endif
+
+ pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0]));
+
+ if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0])) {
+ pci9111_ai_range_set(CR_RANGE((&insn->chanspec)[0]));
+ }
+
+ pci9111_fifo_reset();
+
+ for (i = 0; i < insn->n; i++) {
+ pci9111_software_trigger();
+
+ timeout = PCI9111_AI_INSTANT_READ_TIMEOUT;
+
+ while (timeout--) {
+ if (!pci9111_is_fifo_empty())
+ goto conversion_done;
+ }
+
+ comedi_error(dev, "A/D read timeout");
+ data[i] = 0;
+ pci9111_fifo_reset();
+ return -ETIME;
+
+ conversion_done:
+
+ if (resolution == PCI9111_HR_AI_RESOLUTION) {
+ data[i] = pci9111_hr_ai_get_data();
+ } else {
+ data[i] = pci9111_ai_get_data();
+ }
+ }
+
+#ifdef AI_INSN_DEBUG
+ printk(PCI9111_DRIVER_NAME ": ai_insn get c/r/t = %2x/%2x/%2x\n",
+ pci9111_ai_channel_get(),
+ pci9111_ai_range_get(), pci9111_trigger_and_autoscan_get());
+#endif
+
+ return i;
+}
+
+/* Analog instant output */
+
+static int
+pci9111_ao_insn_write(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ pci9111_ao_set_data(data[i]);
+ dev_private->ao_readback = data[i];
+ }
+
+ return i;
+}
+
+/* Analog output readback */
+
+static int pci9111_ao_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = dev_private->ao_readback & PCI9111_AO_RESOLUTION_MASK;
+ }
+
+ return i;
+}
+
+/* ------------------------------------------------------------------ */
+/* DIGITAL INPUT OUTPUT SECTION */
+/* ------------------------------------------------------------------ */
+
+/* Digital inputs */
+
+static int pci9111_di_insn_bits(struct comedi_device * dev,
+ struct comedi_subdevice * subdevice, struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits;
+
+ bits = pci9111_di_get_bits();
+ data[1] = bits;
+
+ return 2;
+}
+
+/* Digital outputs */
+
+static int pci9111_do_insn_bits(struct comedi_device * dev,
+ struct comedi_subdevice * subdevice, struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits;
+
+ /* Only set bits that have been masked */
+ /* data[0] = mask */
+ /* data[1] = bit state */
+
+ data[0] &= PCI9111_DO_MASK;
+
+ bits = subdevice->state;
+ bits &= ~data[0];
+ bits |= data[0] & data[1];
+ subdevice->state = bits;
+
+ pci9111_do_set_bits(bits);
+
+ data[1] = bits;
+
+ return 2;
+}
+
+/* ------------------------------------------------------------------ */
+/* INITIALISATION SECTION */
+/* ------------------------------------------------------------------ */
+
+/* Reset device */
+
+static int pci9111_reset(struct comedi_device * dev)
+{
+ /* Set trigger source to software */
+
+ plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
+ true, false);
+
+ pci9111_trigger_source_set(dev, software);
+ pci9111_pretrigger_set(dev, false);
+ pci9111_autoscan_set(dev, false);
+
+ /* Reset 8254 chip */
+
+ dev_private->timer_divisor_1 = 0;
+ dev_private->timer_divisor_2 = 0;
+
+ pci9111_timer_set(dev);
+
+ return 0;
+}
+
+/* Attach */
+/* - Register PCI device */
+/* - Declare device driver capability */
+
+static int pci9111_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *subdevice;
+ unsigned long io_base, io_range, lcr_io_base, lcr_io_range;
+ struct pci_dev *pci_device;
+ int error, i;
+ const struct pci9111_board *board;
+
+ if (alloc_private(dev, sizeof(struct pci9111_private_data)) < 0) {
+ return -ENOMEM;
+ }
+ /* Probe the device to determine what device in the series it is. */
+
+ printk("comedi%d: " PCI9111_DRIVER_NAME " driver\n", dev->minor);
+
+ for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pci_device != NULL;
+ pci_device =
+ pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
+ if (pci_device->vendor == PCI_VENDOR_ID_ADLINK) {
+ for (i = 0; i < pci9111_board_nbr; i++) {
+ if (pci9111_boards[i].device_id ==
+ pci_device->device) {
+ /* was a particular bus/slot requested? */
+ if ((it->options[0] != 0)
+ || (it->options[1] != 0)) {
+ /* are we on the wrong bus/slot? */
+ if (pci_device->bus->number !=
+ it->options[0]
+ || PCI_SLOT(pci_device->
+ devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+
+ dev->board_ptr = pci9111_boards + i;
+ board = (struct pci9111_board *) dev->
+ board_ptr;
+ dev_private->pci_device = pci_device;
+ goto found;
+ }
+ }
+ }
+ }
+
+ printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+ dev->minor, it->options[0], it->options[1]);
+ return -EIO;
+
+ found:
+
+ printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n",
+ dev->minor,
+ pci9111_boards[i].name,
+ pci_device->bus->number,
+ PCI_SLOT(pci_device->devfn),
+ PCI_FUNC(pci_device->devfn), pci_device->irq);
+
+ /* TODO: Warn about non-tested boards. */
+
+ switch (board->device_id) {
+ };
+
+ /* Read local configuration register base address [PCI_BASE_ADDRESS #1]. */
+
+ lcr_io_base = pci_resource_start(pci_device, 1);
+ lcr_io_range = pci_resource_len(pci_device, 1);
+
+ printk("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n", dev->minor, lcr_io_base, lcr_io_range);
+
+ /* Enable PCI device and request regions */
+ if (comedi_pci_enable(pci_device, PCI9111_DRIVER_NAME) < 0) {
+ printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
+ return -EIO;
+ }
+ /* Read PCI6308 register base address [PCI_BASE_ADDRESS #2]. */
+
+ io_base = pci_resource_start(pci_device, 2);
+ io_range = pci_resource_len(pci_device, 2);
+
+ printk("comedi%d: 6503 registers at address 0x%4lx [0x%4lx]\n",
+ dev->minor, io_base, io_range);
+
+ dev->iobase = io_base;
+ dev->board_name = board->name;
+ dev_private->io_range = io_range;
+ dev_private->is_valid = 0;
+ dev_private->lcr_io_base = lcr_io_base;
+ dev_private->lcr_io_range = lcr_io_range;
+
+ pci9111_reset(dev);
+
+ /* Irq setup */
+
+ dev->irq = 0;
+ if (pci_device->irq > 0) {
+ if (comedi_request_irq(pci_device->irq,
+ pci9111_interrupt,
+ IRQF_SHARED, PCI9111_DRIVER_NAME, dev) != 0) {
+ printk("comedi%d: unable to allocate irq %u\n",
+ dev->minor, pci_device->irq);
+ return -EINVAL;
+ }
+ }
+ dev->irq = pci_device->irq;
+
+ /* TODO: Add external multiplexer setup (according to option[2]). */
+
+ if ((error = alloc_subdevices(dev, 4)) < 0)
+ return error;
+
+ subdevice = dev->subdevices + 0;
+ dev->read_subdev = subdevice;
+
+ subdevice->type = COMEDI_SUBD_AI;
+ subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ;
+
+ /* TODO: Add external multiplexer data */
+ /* if (devpriv->usemux) { subdevice->n_chan = devpriv->usemux; } */
+ /* else { subdevice->n_chan = this_board->n_aichan; } */
+
+ subdevice->n_chan = board->ai_channel_nbr;
+ subdevice->maxdata = board->ai_resolution_mask;
+ subdevice->len_chanlist = board->ai_channel_nbr;
+ subdevice->range_table = board->ai_range_list;
+ subdevice->cancel = pci9111_ai_cancel;
+ subdevice->insn_read = pci9111_ai_insn_read;
+ subdevice->do_cmdtest = pci9111_ai_do_cmd_test;
+ subdevice->do_cmd = pci9111_ai_do_cmd;
+ subdevice->munge = pci9111_ai_munge;
+
+ subdevice = dev->subdevices + 1;
+ subdevice->type = COMEDI_SUBD_AO;
+ subdevice->subdev_flags = SDF_WRITABLE | SDF_COMMON;
+ subdevice->n_chan = board->ao_channel_nbr;
+ subdevice->maxdata = board->ao_resolution_mask;
+ subdevice->len_chanlist = board->ao_channel_nbr;
+ subdevice->range_table = board->ao_range_list;
+ subdevice->insn_write = pci9111_ao_insn_write;
+ subdevice->insn_read = pci9111_ao_insn_read;
+
+ subdevice = dev->subdevices + 2;
+ subdevice->type = COMEDI_SUBD_DI;
+ subdevice->subdev_flags = SDF_READABLE;
+ subdevice->n_chan = PCI9111_DI_CHANNEL_NBR;
+ subdevice->maxdata = 1;
+ subdevice->range_table = &range_digital;
+ subdevice->insn_bits = pci9111_di_insn_bits;
+
+ subdevice = dev->subdevices + 3;
+ subdevice->type = COMEDI_SUBD_DO;
+ subdevice->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ subdevice->n_chan = PCI9111_DO_CHANNEL_NBR;
+ subdevice->maxdata = 1;
+ subdevice->range_table = &range_digital;
+ subdevice->insn_bits = pci9111_do_insn_bits;
+
+ dev_private->is_valid = 1;
+
+ return 0;
+}
+
+/* Detach */
+
+static int pci9111_detach(struct comedi_device * dev)
+{
+ /* Reset device */
+
+ if (dev->private != 0) {
+ if (dev_private->is_valid)
+ pci9111_reset(dev);
+
+ }
+ /* Release previously allocated irq */
+
+ if (dev->irq != 0) {
+ comedi_free_irq(dev->irq, dev);
+ }
+
+ if (dev_private != 0 && dev_private->pci_device != 0) {
+ if (dev->iobase) {
+ comedi_pci_disable(dev_private->pci_device);
+ }
+ pci_dev_put(dev_private->pci_device);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
new file mode 100644
index 00000000000..278cf30cc4a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -0,0 +1,2100 @@
+/*
+ * comedi/drivers/adl_pci9118.c
+ *
+ * hardware driver for ADLink cards:
+ * card: PCI-9118DG, PCI-9118HG, PCI-9118HR
+ * driver: pci9118dg, pci9118hg, pci9118hr
+ *
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ *
+*/
+/*
+Driver: adl_pci9118
+Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
+ PCI-9118HR (pci9118hr)
+Status: works
+
+This driver supports AI, AO, DI and DO subdevices.
+AI subdevice supports cmd and insn interface,
+other subdevices support only insn interface.
+For AI:
+- If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
+- If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
+- If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
+- It is not neccessary to have cmd.scan_end_arg=cmd.chanlist_len but
+ cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
+- If return value of cmdtest is 5 then you've bad channel list
+ (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
+ ranges).
+
+There are some hardware limitations:
+a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
+ ended inputs.
+b) DMA transfers must have the length aligned to two samples (32 bit),
+ so there is some problems if cmd->chanlist_len is odd. This driver tries
+ bypass this with adding one sample to the end of the every scan and discard
+ it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW
+ and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode
+ with interrupt after every sample.
+c) If isn't used DMA then you can use only mode where
+ cmd->scan_begin_src=TRIG_FOLLOW.
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, then first available PCI
+ card will be used.
+ [2] - 0= standard 8 DIFF/16 SE channels configuration
+ n= external multiplexer connected, 1<=n<=256
+ [3] - 0=autoselect DMA or EOC interrupts operation
+ 1=disable DMA mode
+ 3=disable DMA and INT, only insn interface will work
+ [4] - sample&hold signal - card can generate signal for external S&H board
+ 0=use SSHO (pin 45) signal is generated in onboard hardware S&H logic
+ 0!=use ADCHN7 (pin 23) signal is generated from driver, number
+ say how long delay is requested in ns and sign polarity of the hold
+ (in this case external multiplexor can serve only 128 channels)
+ [5] - 0=stop measure on all hardware errors
+ 2|=ignore ADOR - A/D Overrun status
+ 8|=ignore Bover - A/D Burst Mode Overrun status
+ 256|=ignore nFull - A/D FIFO Full status
+
+*/
+#include "../comedidev.h"
+#include "../pci_ids.h"
+
+#include <linux/delay.h>
+
+#include "amcc_s5933.h"
+#include "8253.h"
+#include "comedi_pci.h"
+#include "comedi_fc.h"
+
+/* paranoid checks are broken */
+#undef PCI9118_PARANOIDCHECK /* if defined, then is used code which control correct channel number on every 12 bit sample */
+
+#undef PCI9118_EXTDEBUG /* if defined then driver prints a lot of messages */
+
+#undef DPRINTK
+#ifdef PCI9118_EXTDEBUG
+#define DPRINTK(fmt, args...) rt_printk(fmt, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define IORANGE_9118 64 /* I hope */
+#define PCI9118_CHANLEN 255 /* len of chanlist, some source say 256, but reality looks like 255 :-( */
+
+#define PCI9118_CNT0 0x00 /* R/W: 8254 couter 0 */
+#define PCI9118_CNT1 0x04 /* R/W: 8254 couter 0 */
+#define PCI9118_CNT2 0x08 /* R/W: 8254 couter 0 */
+#define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */
+#define PCI9118_AD_DATA 0x10 /* R: A/D data */
+#define PCI9118_DA1 0x10 /* W: D/A registers */
+#define PCI9118_DA2 0x14
+#define PCI9118_ADSTAT 0x18 /* R: A/D status register */
+#define PCI9118_ADCNTRL 0x18 /* W: A/D control register */
+#define PCI9118_DI 0x1c /* R: digi input register */
+#define PCI9118_DO 0x1c /* W: digi output register */
+#define PCI9118_SOFTTRG 0x20 /* W: soft trigger for A/D */
+#define PCI9118_GAIN 0x24 /* W: A/D gain/channel register */
+#define PCI9118_BURST 0x28 /* W: A/D burst number register */
+#define PCI9118_SCANMOD 0x2c /* W: A/D auto scan mode */
+#define PCI9118_ADFUNC 0x30 /* W: A/D function register */
+#define PCI9118_DELFIFO 0x34 /* W: A/D data FIFO reset */
+#define PCI9118_INTSRC 0x38 /* R: interrupt reason register */
+#define PCI9118_INTCTRL 0x38 /* W: interrupt control register */
+
+// bits from A/D control register (PCI9118_ADCNTRL)
+#define AdControl_UniP 0x80 /* 1=bipolar, 0=unipolar */
+#define AdControl_Diff 0x40 /* 1=differential, 0= single end inputs */
+#define AdControl_SoftG 0x20 /* 1=8254 counter works, 0=counter stops */
+#define AdControl_ExtG 0x10 /* 1=8254 countrol controlled by TGIN(pin 46), 0=controled by SoftG */
+#define AdControl_ExtM 0x08 /* 1=external hardware trigger (pin 44), 0=internal trigger */
+#define AdControl_TmrTr 0x04 /* 1=8254 is iternal trigger source, 0=software trigger is source (register PCI9118_SOFTTRG) */
+#define AdControl_Int 0x02 /* 1=enable INT, 0=disable */
+#define AdControl_Dma 0x01 /* 1=enable DMA, 0=disable */
+
+// bits from A/D function register (PCI9118_ADFUNC)
+#define AdFunction_PDTrg 0x80 /* 1=positive, 0=negative digital trigger (only positive is correct) */
+#define AdFunction_PETrg 0x40 /* 1=positive, 0=negative external trigger (only positive is correct) */
+#define AdFunction_BSSH 0x20 /* 1=with sample&hold, 0=without */
+#define AdFunction_BM 0x10 /* 1=burst mode, 0=normal mode */
+#define AdFunction_BS 0x08 /* 1=burst mode start, 0=burst mode stop */
+#define AdFunction_PM 0x04 /* 1=post trigger mode, 0=not post trigger */
+#define AdFunction_AM 0x02 /* 1=about trigger mode, 0=not about trigger */
+#define AdFunction_Start 0x01 /* 1=trigger start, 0=trigger stop */
+
+// bits from A/D status register (PCI9118_ADSTAT)
+#define AdStatus_nFull 0x100 /* 0=FIFO full (fatal), 1=not full */
+#define AdStatus_nHfull 0x080 /* 0=FIFO half full, 1=FIFO not half full */
+#define AdStatus_nEpty 0x040 /* 0=FIFO empty, 1=FIFO not empty */
+#define AdStatus_Acmp 0x020 /* */
+#define AdStatus_DTH 0x010 /* 1=external digital trigger */
+#define AdStatus_Bover 0x008 /* 1=burst mode overrun (fatal) */
+#define AdStatus_ADOS 0x004 /* 1=A/D over speed (warning) */
+#define AdStatus_ADOR 0x002 /* 1=A/D overrun (fatal) */
+#define AdStatus_ADrdy 0x001 /* 1=A/D already ready, 0=not ready */
+
+// bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL)
+// 1=interrupt occur, enable source, 0=interrupt not occur, disable source
+#define Int_Timer 0x08 /* timer interrupt */
+#define Int_About 0x04 /* about trigger complete */
+#define Int_Hfull 0x02 /* A/D FIFO hlaf full */
+#define Int_DTrg 0x01 /* external digital trigger */
+
+#define START_AI_EXT 0x01 /* start measure on external trigger */
+#define STOP_AI_EXT 0x02 /* stop measure on external trigger */
+#define START_AI_INT 0x04 /* start measure on internal trigger */
+#define STOP_AI_INT 0x08 /* stop measure on internal trigger */
+
+#define EXTTRG_AI 0 /* ext trg is used by AI */
+
+static const struct comedi_lrange range_pci9118dg_hr = { 8, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25)
+ }
+};
+
+static const struct comedi_lrange range_pci9118hg = { 8, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.005),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01)
+ }
+};
+
+#define PCI9118_BIPOLAR_RANGES 4 /* used for test on mixture of BIP/UNI ranges */
+
+static int pci9118_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci9118_detach(struct comedi_device * dev);
+
+struct boardtype {
+ const char *name; // board name
+ int vendor_id; // PCI vendor a device ID of card
+ int device_id;
+ int iorange_amcc; // iorange for own S5933 region
+ int iorange_9118; // pass thru card region size
+ int n_aichan; // num of A/D chans
+ int n_aichand; // num of A/D chans in diff mode
+ int mux_aichan; // num of A/D chans with external multiplexor
+ int n_aichanlist; // len of chanlist
+ int n_aochan; // num of D/A chans
+ int ai_maxdata; // resolution of A/D
+ int ao_maxdata; // resolution of D/A
+ const struct comedi_lrange *rangelist_ai; // rangelist for A/D
+ const struct comedi_lrange *rangelist_ao; // rangelist for D/A
+ unsigned int ai_ns_min; // max sample speed of card v ns
+ unsigned int ai_pacer_min; // minimal pacer value (c1*c2 or c1 in burst)
+ int half_fifo_size; // size of FIFO/2
+
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = {
+ {PCI_VENDOR_ID_AMCC, 0x80d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci9118_pci_table);
+
+static const struct boardtype boardtypes[] = {
+ {"pci9118dg", PCI_VENDOR_ID_AMCC, 0x80d9,
+ AMCC_OP_REG_SIZE, IORANGE_9118,
+ 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
+ &range_pci9118dg_hr, &range_bipolar10,
+ 3000, 12, 512},
+ {"pci9118hg", PCI_VENDOR_ID_AMCC, 0x80d9,
+ AMCC_OP_REG_SIZE, IORANGE_9118,
+ 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
+ &range_pci9118hg, &range_bipolar10,
+ 3000, 12, 512},
+ {"pci9118hr", PCI_VENDOR_ID_AMCC, 0x80d9,
+ AMCC_OP_REG_SIZE, IORANGE_9118,
+ 16, 8, 256, PCI9118_CHANLEN, 2, 0xffff, 0x0fff,
+ &range_pci9118dg_hr, &range_bipolar10,
+ 10000, 40, 512},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
+
+static struct comedi_driver driver_pci9118 = {
+ driver_name:"adl_pci9118",
+ module:THIS_MODULE,
+ attach:pci9118_attach,
+ detach:pci9118_detach,
+ num_names:n_boardtypes,
+ board_name:&boardtypes[0].name,
+ offset:sizeof(struct boardtype),
+};
+
+COMEDI_PCI_INITCLEANUP(driver_pci9118, pci9118_pci_table);
+
+struct pci9118_private {
+ unsigned long iobase_a; // base+size for AMCC chip
+ unsigned int master; // master capable
+ struct pci_dev *pcidev; // ptr to actual pcidev
+ unsigned int usemux; // we want to use external multiplexor!
+#ifdef PCI9118_PARANOIDCHECK
+ unsigned short chanlist[PCI9118_CHANLEN + 1]; // list of scaned channel
+ unsigned char chanlistlen; // number of scanlist
+#endif
+ unsigned char AdControlReg; // A/D control register
+ unsigned char IntControlReg; // Interrupt control register
+ unsigned char AdFunctionReg; // A/D function register
+ char valid; // driver is ok
+ char ai_neverending; // we do unlimited AI
+ unsigned int i8254_osc_base; // frequence of onboard oscilator
+ unsigned int ai_do; // what do AI? 0=nothing, 1 to 4 mode
+ unsigned int ai_act_scan; // how many scans we finished
+ unsigned int ai_buf_ptr; // data buffer ptr in samples
+ unsigned int ai_n_chan; // how many channels is measured
+ unsigned int ai_n_scanlen; // len of actual scanlist
+ unsigned int ai_n_realscanlen; // what we must transfer for one outgoing scan include front/back adds
+ unsigned int ai_act_dmapos; // position in actual real stream
+ unsigned int ai_add_front; // how many channels we must add before scan to satisfy S&H?
+ unsigned int ai_add_back; // how many channels we must add before scan to satisfy DMA?
+ unsigned int *ai_chanlist; // actaul chanlist
+ unsigned int ai_timer1;
+ unsigned int ai_timer2;
+ unsigned int ai_flags;
+ char ai12_startstop; // measure can start/stop on external trigger
+ unsigned int ai_divisor1, ai_divisor2; // divisors for start of measure on external start
+ unsigned int ai_data_len;
+ short *ai_data;
+ short ao_data[2]; // data output buffer
+ unsigned int ai_scans; // number of scans to do
+ char dma_doublebuf; // we can use double buffring
+ unsigned int dma_actbuf; // which buffer is used now
+ short *dmabuf_virt[2]; // pointers to begin of DMA buffer
+ unsigned long dmabuf_hw[2]; // hw address of DMA buff
+ unsigned int dmabuf_size[2]; // size of dma buffer in bytes
+ unsigned int dmabuf_use_size[2]; // which size we may now used for transfer
+ unsigned int dmabuf_used_size[2]; // which size was trully used
+ unsigned int dmabuf_panic_size[2];
+ unsigned int dmabuf_samples[2]; // size in samples
+ int dmabuf_pages[2]; // number of pages in buffer
+ unsigned char cnt0_users; // bit field of 8254 CNT0 users (0-unused, 1-AO, 2-DI, 3-DO)
+ unsigned char exttrg_users; // bit field of external trigger users (0-AI, 1-AO, 2-DI, 3-DO)
+ unsigned int cnt0_divisor; // actual CNT0 divisor
+ void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *, unsigned short, unsigned int, unsigned short); // ptr to actual interrupt AI function
+ unsigned char ai16bits; // =1 16 bit card
+ unsigned char usedma; // =1 use DMA transfer and not INT
+ unsigned char useeoshandle; // =1 change WAKE_EOS DMA transfer to fit on every second
+ unsigned char usessh; // =1 turn on S&H support
+ int softsshdelay; // >0 use software S&H, numer is requested delay in ns
+ unsigned char softsshsample; // polarity of S&H signal in sample state
+ unsigned char softsshhold; // polarity of S&H signal in hold state
+ unsigned int ai_maskerr; // which warning was printed
+ unsigned int ai_maskharderr; // on which error bits stops
+ unsigned int ai_inttrig_start; // TRIG_INT for start
+};
+
+#define devpriv ((struct pci9118_private *)dev->private)
+#define this_board ((struct boardtype *)dev->board_ptr)
+
+/*
+==============================================================================
+*/
+
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ int n_chan, unsigned int *chanlist, int frontadd, int backadd);
+static int setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ int n_chan, unsigned int *chanlist, int rot, int frontadd, int backadd,
+ int usedma, char eoshandle);
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2);
+static int pci9118_reset(struct comedi_device * dev);
+static int pci9118_exttrg_add(struct comedi_device * dev, unsigned char source);
+static int pci9118_exttrg_del(struct comedi_device * dev, unsigned char source);
+static int pci9118_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci9118_calc_divisors(char mode, struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned int *tim1, unsigned int *tim2,
+ unsigned int flags, int chans, unsigned int *div1, unsigned int *div2,
+ char usessh, unsigned int chnsshfront);
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_read_ai(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ int n, timeout;
+
+ devpriv->AdControlReg = AdControl_Int & 0xff;
+ devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); // positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
+
+ if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0))
+ return -EINVAL;
+
+ outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
+
+ for (n = 0; n < insn->n; n++) {
+ outw(0, dev->iobase + PCI9118_SOFTTRG); /* start conversion */
+ comedi_udelay(2);
+ timeout = 100;
+ while (timeout--) {
+ if (inl(dev->iobase + PCI9118_ADSTAT) & AdStatus_ADrdy)
+ goto conv_finish;
+ comedi_udelay(1);
+ }
+
+ comedi_error(dev, "A/D insn timeout");
+ data[n] = 0;
+ outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
+ return -ETIME;
+
+ conv_finish:
+ if (devpriv->ai16bits) {
+ data[n] =
+ (inl(dev->iobase +
+ PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
+ } else {
+ data[n] =
+ (inw(dev->iobase +
+ PCI9118_AD_DATA) >> 4) & 0xfff;
+ }
+ }
+
+ outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
+ return n;
+
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_write_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, chanreg, ch;
+
+ ch = CR_CHAN(insn->chanspec);
+ if (ch) {
+ chanreg = PCI9118_DA2;
+ } else {
+ chanreg = PCI9118_DA1;
+ }
+
+ for (n = 0; n < insn->n; n++) {
+ outl(data[n], dev->iobase + chanreg);
+ devpriv->ao_data[ch] = data[n];
+ }
+
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_read_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ for (n = 0; n < insn->n; n++)
+ data[n] = devpriv->ao_data[chan];
+
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_bits_di(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[1] = inl(dev->iobase + PCI9118_DI) & 0xf;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_bits_do(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci9118_ai_mode4_switch(struct comedi_device * dev)
+{
+ devpriv->AdFunctionReg =
+ AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+ outl(0x30, dev->iobase + PCI9118_CNTCTRL);
+ outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 1) & 0xff,
+ dev->iobase + PCI9118_CNT0);
+ outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff,
+ dev->iobase + PCI9118_CNT0);
+ devpriv->AdFunctionReg |= AdFunction_Start;
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+}
+
+static unsigned int defragment_dma_buffer(struct comedi_device * dev,
+ struct comedi_subdevice * s, short * dma_buffer, unsigned int num_samples)
+{
+ unsigned int i = 0, j = 0;
+ unsigned int start_pos = devpriv->ai_add_front,
+ stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan;
+ unsigned int raw_scanlen = devpriv->ai_add_front + devpriv->ai_n_chan +
+ devpriv->ai_add_back;
+
+ for (i = 0; i < num_samples; i++) {
+ if (devpriv->ai_act_dmapos >= start_pos &&
+ devpriv->ai_act_dmapos < stop_pos) {
+ dma_buffer[j++] = dma_buffer[i];
+ }
+ devpriv->ai_act_dmapos++;
+ devpriv->ai_act_dmapos %= raw_scanlen;
+ }
+
+ return j;
+}
+
+/*
+==============================================================================
+*/
+static unsigned int move_block_from_dma(struct comedi_device * dev,
+ struct comedi_subdevice * s, short * dma_buffer, unsigned int num_samples)
+{
+ unsigned int num_bytes;
+
+ num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
+ devpriv->ai_act_scan +=
+ (s->async->cur_chan + num_samples) / devpriv->ai_n_scanlen;
+ s->async->cur_chan += num_samples;
+ s->async->cur_chan %= devpriv->ai_n_scanlen;
+ num_bytes =
+ cfc_write_array_to_buffer(s, dma_buffer,
+ num_samples * sizeof(short));
+ if (num_bytes < num_samples * sizeof(short))
+ return -1;
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static char pci9118_decode_error_status(struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned char m)
+{
+ if (m & 0x100) {
+ comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
+ devpriv->ai_maskerr &= ~0x100L;
+ }
+ if (m & 0x008) {
+ comedi_error(dev,
+ "A/D Burst Mode Overrun Status (Fatal Error!)");
+ devpriv->ai_maskerr &= ~0x008L;
+ }
+ if (m & 0x004) {
+ comedi_error(dev, "A/D Over Speed Status (Warning!)");
+ devpriv->ai_maskerr &= ~0x004L;
+ }
+ if (m & 0x002) {
+ comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
+ devpriv->ai_maskerr &= ~0x002L;
+ }
+ if (m & devpriv->ai_maskharderr) {
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ pci9118_ai_cancel(dev, s);
+ comedi_event(dev, s);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void pci9118_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *data, unsigned int num_bytes, unsigned int start_chan_index)
+{
+ unsigned int i, num_samples = num_bytes / sizeof(short);
+ short *array = data;
+
+ for (i = 0; i < num_samples; i++) {
+ if (devpriv->usedma)
+ array[i] = be16_to_cpu(array[i]);
+ if (devpriv->ai16bits) {
+ array[i] ^= 0x8000;
+ } else {
+ array[i] = (array[i] >> 4) & 0x0fff;
+ }
+ }
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci9118_ai_onesample(struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned short int_adstat, unsigned int int_amcc,
+ unsigned short int_daq)
+{
+ register short sampl;
+
+ s->async->events = 0;
+
+ if (int_adstat & devpriv->ai_maskerr)
+ if (pci9118_decode_error_status(dev, s, int_adstat))
+ return;
+
+ sampl = inw(dev->iobase + PCI9118_AD_DATA);
+
+#ifdef PCI9118_PARANOIDCHECK
+ if (devpriv->ai16bits == 0) {
+ if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) { // data dropout!
+ rt_printk
+ ("comedi: A/D SAMPL - data dropout: received channel %d, expected %d!\n",
+ sampl & 0x000f,
+ devpriv->chanlist[s->async->cur_chan]);
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ pci9118_ai_cancel(dev, s);
+ comedi_event(dev, s);
+ return;
+ }
+ }
+#endif
+ cfc_write_to_buffer(s, sampl);
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= devpriv->ai_n_scanlen) { /* one scan done */
+ s->async->cur_chan %= devpriv->ai_n_scanlen;
+ devpriv->ai_act_scan++;
+ if (!(devpriv->ai_neverending))
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
+ pci9118_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ }
+ }
+
+ if (s->async->events)
+ comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci9118_ai_dma(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned short int_adstat, unsigned int int_amcc,
+ unsigned short int_daq)
+{
+ unsigned int next_dma_buf, samplesinbuf, sampls, m;
+
+ if (int_amcc & MASTER_ABORT_INT) {
+ comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ pci9118_ai_cancel(dev, s);
+ comedi_event(dev, s);
+ return;
+ }
+
+ if (int_amcc & TARGET_ABORT_INT) {
+ comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ pci9118_ai_cancel(dev, s);
+ comedi_event(dev, s);
+ return;
+ }
+
+ if (int_adstat & devpriv->ai_maskerr)
+// if (int_adstat & 0x106)
+ if (pci9118_decode_error_status(dev, s, int_adstat))
+ return;
+
+ samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1; // number of received real samples
+// DPRINTK("dma_actbuf=%d\n",devpriv->dma_actbuf);
+
+ if (devpriv->dma_doublebuf) { // switch DMA buffers if is used double buffering
+ next_dma_buf = 1 - devpriv->dma_actbuf;
+ outl(devpriv->dmabuf_hw[next_dma_buf],
+ devpriv->iobase_a + AMCC_OP_REG_MWAR);
+ outl(devpriv->dmabuf_use_size[next_dma_buf],
+ devpriv->iobase_a + AMCC_OP_REG_MWTC);
+ devpriv->dmabuf_used_size[next_dma_buf] =
+ devpriv->dmabuf_use_size[next_dma_buf];
+ if (devpriv->ai_do == 4)
+ interrupt_pci9118_ai_mode4_switch(dev);
+ }
+
+ if (samplesinbuf) {
+ m = devpriv->ai_data_len >> 1; // how many samples is to end of buffer
+// DPRINTK("samps=%d m=%d %d %d\n",samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr);
+ sampls = m;
+ move_block_from_dma(dev, s,
+ devpriv->dmabuf_virt[devpriv->dma_actbuf],
+ samplesinbuf);
+ m = m - sampls; // m= how many samples was transfered
+ }
+// DPRINTK("YYY\n");
+
+ if (!devpriv->ai_neverending)
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
+ pci9118_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ }
+
+ if (devpriv->dma_doublebuf) { // switch dma buffers
+ devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
+ } else { // restart DMA if is not used double buffering
+ outl(devpriv->dmabuf_hw[0],
+ devpriv->iobase_a + AMCC_OP_REG_MWAR);
+ outl(devpriv->dmabuf_use_size[0],
+ devpriv->iobase_a + AMCC_OP_REG_MWTC);
+ if (devpriv->ai_do == 4)
+ interrupt_pci9118_ai_mode4_switch(dev);
+ }
+
+ comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_pci9118(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ unsigned int int_daq = 0, int_amcc, int_adstat;
+
+ if (!dev->attached)
+ return IRQ_NONE; // not fully initialized
+
+ int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf; // get IRQ reasons from card
+ int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR); // get INT register from AMCC chip
+
+// DPRINTK("INT daq=0x%01x amcc=0x%08x MWAR=0x%08x MWTC=0x%08x ADSTAT=0x%02x ai_do=%d\n", int_daq, int_amcc, inl(devpriv->iobase_a+AMCC_OP_REG_MWAR), inl(devpriv->iobase_a+AMCC_OP_REG_MWTC), inw(dev->iobase+PCI9118_ADSTAT)&0x1ff,devpriv->ai_do);
+
+ if ((!int_daq) && (!(int_amcc & ANY_S593X_INT)))
+ return IRQ_NONE; // interrupt from other source
+
+ outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR); // shutdown IRQ reasons in AMCC
+
+ int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff; // get STATUS register
+
+ if (devpriv->ai_do) {
+ if (devpriv->ai12_startstop)
+ if ((int_adstat & AdStatus_DTH) && (int_daq & Int_DTrg)) { // start stop of measure
+ if (devpriv->ai12_startstop & START_AI_EXT) {
+ devpriv->ai12_startstop &=
+ ~START_AI_EXT;
+ if (!(devpriv->ai12_startstop &
+ STOP_AI_EXT))
+ pci9118_exttrg_del(dev, EXTTRG_AI); // deactivate EXT trigger
+ start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, devpriv->ai_divisor2); // start pacer
+ outl(devpriv->AdControlReg,
+ dev->iobase + PCI9118_ADCNTRL);
+ } else {
+ if (devpriv->
+ ai12_startstop & STOP_AI_EXT) {
+ devpriv->ai12_startstop &=
+ ~STOP_AI_EXT;
+ pci9118_exttrg_del(dev, EXTTRG_AI); // deactivate EXT trigger
+ devpriv->ai_neverending = 0; //well, on next interrupt from DMA/EOC measure will stop
+ }
+ }
+ }
+
+ (devpriv->int_ai_func) (dev, dev->subdevices + 0, int_adstat,
+ int_amcc, int_daq);
+
+ }
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ if (trignum != devpriv->ai_inttrig_start)
+ return -EINVAL;
+
+ devpriv->ai12_startstop &= ~START_AI_INT;
+ s->async->inttrig = NULL;
+
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+ if (devpriv->ai_do != 3) {
+ start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
+ devpriv->ai_divisor2);
+ devpriv->AdControlReg |= AdControl_SoftG;
+ }
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
+
+ return 1;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp, divisor1, divisor2;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ if (devpriv->master) {
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW;
+ } else {
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ }
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ if (devpriv->master) {
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW;
+ } else {
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ }
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE | TRIG_EXT;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW &&
+ cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT &&
+ cmd->scan_begin_src != TRIG_INT &&
+ cmd->scan_begin_src != TRIG_FOLLOW) {
+ cmd->scan_begin_src = TRIG_FOLLOW;
+ err++;
+ }
+
+ if (cmd->convert_src != TRIG_TIMER &&
+ cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) {
+ cmd->convert_src = TRIG_TIMER;
+ err++;
+ }
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE &&
+ cmd->stop_src != TRIG_COUNT &&
+ cmd->stop_src != TRIG_INT && cmd->stop_src != TRIG_EXT) {
+ cmd->stop_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+
+ if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+
+ if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
+ (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) {
+ cmd->convert_src = TRIG_TIMER;
+ err++;
+ }
+
+ if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
+ (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT)))) {
+ cmd->convert_src = TRIG_TIMER;
+ err++;
+ }
+
+ if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
+ cmd->stop_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ if ((cmd->scan_begin_src == TRIG_TIMER) &&
+ (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
+ cmd->scan_begin_src = TRIG_FOLLOW;
+ cmd->convert_arg = cmd->scan_begin_arg;
+ cmd->scan_begin_arg = 0;
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER)
+ if (cmd->scan_begin_arg < this_board->ai_ns_min) {
+ cmd->scan_begin_arg = this_board->ai_ns_min;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_EXT)
+ if (cmd->scan_begin_arg) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ if (cmd->scan_end_arg > 65535) {
+ cmd->scan_end_arg = 65535;
+ err++;
+ }
+ }
+
+ if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
+ if (cmd->convert_arg < this_board->ai_ns_min) {
+ cmd->convert_arg = this_board->ai_ns_min;
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_EXT)
+ if (cmd->convert_arg) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+
+ if (cmd->chanlist_len > this_board->n_aichanlist) {
+ cmd->chanlist_len = this_board->n_aichanlist;
+ err++;
+ }
+
+ if (cmd->scan_end_arg < cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if ((cmd->scan_end_arg % cmd->chanlist_len)) {
+ cmd->scan_end_arg =
+ cmd->chanlist_len * (cmd->scan_end_arg /
+ cmd->chanlist_len);
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+// rt_printk("S1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+ i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
+ &divisor2, &cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+// rt_printk("S2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+ if (cmd->scan_begin_arg < this_board->ai_ns_min)
+ cmd->scan_begin_arg = this_board->ai_ns_min;
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
+ &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+// rt_printk("s1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER
+ && cmd->convert_src == TRIG_NOW) {
+ if (cmd->convert_arg == 0) {
+ if (cmd->scan_begin_arg <
+ this_board->ai_ns_min *
+ (cmd->scan_end_arg + 2)) {
+ cmd->scan_begin_arg =
+ this_board->ai_ns_min *
+ (cmd->scan_end_arg + 2);
+// rt_printk("s2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+ err++;
+ }
+ } else {
+ if (cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->chanlist_len) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg *
+ cmd->chanlist_len;
+// rt_printk("s3 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+ err++;
+ }
+ }
+ }
+ }
+
+ if (err)
+ return 4;
+
+ if (cmd->chanlist)
+ if (!check_channel_list(dev, s, cmd->chanlist_len,
+ cmd->chanlist, 0, 0))
+ return 5; // incorrect channels list
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int Compute_and_setup_dma(struct comedi_device * dev)
+{
+ unsigned int dmalen0, dmalen1, i;
+
+ DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n");
+ dmalen0 = devpriv->dmabuf_size[0];
+ dmalen1 = devpriv->dmabuf_size[1];
+ DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1,
+ devpriv->ai_data_len);
+ // isn't output buff smaller that our DMA buff?
+ if (dmalen0 > (devpriv->ai_data_len)) {
+ dmalen0 = devpriv->ai_data_len & ~3L; // allign to 32bit down
+ }
+ if (dmalen1 > (devpriv->ai_data_len)) {
+ dmalen1 = devpriv->ai_data_len & ~3L; // allign to 32bit down
+ }
+ DPRINTK("2 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
+
+ // we want wake up every scan?
+ if (devpriv->ai_flags & TRIG_WAKE_EOS) {
+ if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
+ // uff, too short DMA buffer, disable EOS support!
+ devpriv->ai_flags &= (~TRIG_WAKE_EOS);
+ rt_printk
+ ("comedi%d: WAR: DMA0 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",
+ dev->minor, dmalen0,
+ devpriv->ai_n_realscanlen << 1);
+ } else {
+ // short first DMA buffer to one scan
+ dmalen0 = devpriv->ai_n_realscanlen << 1;
+ DPRINTK("21 dmalen0=%d ai_n_realscanlen=%d useeoshandle=%d\n", dmalen0, devpriv->ai_n_realscanlen, devpriv->useeoshandle);
+ if (devpriv->useeoshandle)
+ dmalen0 += 2;
+ if (dmalen0 < 4) {
+ rt_printk
+ ("comedi%d: ERR: DMA0 buf len bug? (%d<4)\n",
+ dev->minor, dmalen0);
+ dmalen0 = 4;
+ }
+ }
+ }
+ if (devpriv->ai_flags & TRIG_WAKE_EOS) {
+ if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
+ // uff, too short DMA buffer, disable EOS support!
+ devpriv->ai_flags &= (~TRIG_WAKE_EOS);
+ rt_printk
+ ("comedi%d: WAR: DMA1 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",
+ dev->minor, dmalen1,
+ devpriv->ai_n_realscanlen << 1);
+ } else {
+ // short second DMA buffer to one scan
+ dmalen1 = devpriv->ai_n_realscanlen << 1;
+ DPRINTK("22 dmalen1=%d ai_n_realscanlen=%d useeoshandle=%d\n", dmalen1, devpriv->ai_n_realscanlen, devpriv->useeoshandle);
+ if (devpriv->useeoshandle)
+ dmalen1 -= 2;
+ if (dmalen1 < 4) {
+ rt_printk
+ ("comedi%d: ERR: DMA1 buf len bug? (%d<4)\n",
+ dev->minor, dmalen1);
+ dmalen1 = 4;
+ }
+ }
+ }
+
+ DPRINTK("3 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
+ // transfer without TRIG_WAKE_EOS
+ if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) {
+ // if it's possible then allign DMA buffers to length of scan
+ i = dmalen0;
+ dmalen0 =
+ (dmalen0 / (devpriv->ai_n_realscanlen << 1)) *
+ (devpriv->ai_n_realscanlen << 1);
+ dmalen0 &= ~3L;
+ if (!dmalen0)
+ dmalen0 = i; // uff. very long scan?
+ i = dmalen1;
+ dmalen1 =
+ (dmalen1 / (devpriv->ai_n_realscanlen << 1)) *
+ (devpriv->ai_n_realscanlen << 1);
+ dmalen1 &= ~3L;
+ if (!dmalen1)
+ dmalen1 = i; // uff. very long scan?
+ // if measure isn't neverending then test, if it whole fits into one or two DMA buffers
+ if (!devpriv->ai_neverending) {
+ // fits whole measure into one DMA buffer?
+ if (dmalen0 >
+ ((devpriv->ai_n_realscanlen << 1) *
+ devpriv->ai_scans)) {
+ DPRINTK("3.0 ai_n_realscanlen=%d ai_scans=%d \n", devpriv->ai_n_realscanlen, devpriv->ai_scans);
+ dmalen0 =
+ (devpriv->ai_n_realscanlen << 1) *
+ devpriv->ai_scans;
+ DPRINTK("3.1 dmalen0=%d dmalen1=%d \n", dmalen0,
+ dmalen1);
+ dmalen0 &= ~3L;
+ } else { // fits whole measure into two DMA buffer?
+ if (dmalen1 >
+ ((devpriv->ai_n_realscanlen << 1) *
+ devpriv->ai_scans - dmalen0))
+ dmalen1 =
+ (devpriv->
+ ai_n_realscanlen << 1) *
+ devpriv->ai_scans - dmalen0;
+ DPRINTK("3.2 dmalen0=%d dmalen1=%d \n", dmalen0,
+ dmalen1);
+ dmalen1 &= ~3L;
+ }
+ }
+ }
+
+ DPRINTK("4 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
+
+ // these DMA buffer size we'll be used
+ devpriv->dma_actbuf = 0;
+ devpriv->dmabuf_use_size[0] = dmalen0;
+ devpriv->dmabuf_use_size[1] = dmalen1;
+
+ DPRINTK("5 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
+#if 0
+ if (devpriv->ai_n_scanlen < this_board->half_fifo_size) {
+ devpriv->dmabuf_panic_size[0] =
+ (this_board->half_fifo_size / devpriv->ai_n_scanlen +
+ 1) * devpriv->ai_n_scanlen * sizeof(short);
+ devpriv->dmabuf_panic_size[1] =
+ (this_board->half_fifo_size / devpriv->ai_n_scanlen +
+ 1) * devpriv->ai_n_scanlen * sizeof(short);
+ } else {
+ devpriv->dmabuf_panic_size[0] =
+ (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0];
+ devpriv->dmabuf_panic_size[1] =
+ (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
+ }
+#endif
+
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), devpriv->iobase_a + AMCC_OP_REG_MCSR); // stop DMA
+ outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR);
+ outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC);
+ // init DMA transfer
+ outl(0x00000000 | AINT_WRITE_COMPL,
+ devpriv->iobase_a + AMCC_OP_REG_INTCSR);
+// outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR);
+
+ outl(inl(devpriv->iobase_a +
+ AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY |
+ EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR);
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_INTCSR); // allow bus mastering
+
+ DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_docmd_sampl(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n",
+ dev->minor, devpriv->ai_do);
+ switch (devpriv->ai_do) {
+ case 1:
+ devpriv->AdControlReg |= AdControl_TmrTr;
+ break;
+ case 2:
+ comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
+ return -EIO;
+ case 3:
+ devpriv->AdControlReg |= AdControl_ExtM;
+ break;
+ case 4:
+ comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
+ return -EIO;
+ default:
+ comedi_error(dev,
+ "pci9118_ai_docmd_sampl() mode number bug!\n");
+ return -EIO;
+ };
+
+ devpriv->int_ai_func = interrupt_pci9118_ai_onesample; //transfer function
+
+ if (devpriv->ai12_startstop)
+ pci9118_exttrg_add(dev, EXTTRG_AI); // activate EXT trigger
+
+ if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2))
+ devpriv->IntControlReg |= Int_Timer;
+
+ devpriv->AdControlReg |= AdControl_Int;
+
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR); // allow INT in AMCC
+
+ if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+ if (devpriv->ai_do != 3) {
+ start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
+ devpriv->ai_divisor2);
+ devpriv->AdControlReg |= AdControl_SoftG;
+ }
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+ }
+
+ DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_docmd_sampl()\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_docmd_dma(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n",
+ dev->minor, devpriv->ai_do, devpriv->usedma);
+ Compute_and_setup_dma(dev);
+
+ switch (devpriv->ai_do) {
+ case 1:
+ devpriv->AdControlReg |=
+ ((AdControl_TmrTr | AdControl_Dma) & 0xff);
+ break;
+ case 2:
+ devpriv->AdControlReg |=
+ ((AdControl_TmrTr | AdControl_Dma) & 0xff);
+ devpriv->AdFunctionReg =
+ AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM |
+ AdFunction_BS;
+ if (devpriv->usessh && (!devpriv->softsshdelay))
+ devpriv->AdFunctionReg |= AdFunction_BSSH;
+ outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST);
+ break;
+ case 3:
+ devpriv->AdControlReg |=
+ ((AdControl_ExtM | AdControl_Dma) & 0xff);
+ devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
+ break;
+ case 4:
+ devpriv->AdControlReg |=
+ ((AdControl_TmrTr | AdControl_Dma) & 0xff);
+ devpriv->AdFunctionReg =
+ AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+ outl(0x30, dev->iobase + PCI9118_CNTCTRL);
+ outl((devpriv->dmabuf_hw[0] >> 1) & 0xff,
+ dev->iobase + PCI9118_CNT0);
+ outl((devpriv->dmabuf_hw[0] >> 9) & 0xff,
+ dev->iobase + PCI9118_CNT0);
+ devpriv->AdFunctionReg |= AdFunction_Start;
+ break;
+ default:
+ comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
+ return -EIO;
+ };
+
+ if (devpriv->ai12_startstop) {
+ pci9118_exttrg_add(dev, EXTTRG_AI); // activate EXT trigger
+ }
+
+ devpriv->int_ai_func = interrupt_pci9118_ai_dma; //transfer function
+
+ outl(0x02000000 | AINT_WRITE_COMPL,
+ devpriv->iobase_a + AMCC_OP_REG_INTCSR);
+
+ if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+ if (devpriv->ai_do != 3) {
+ start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
+ devpriv->ai_divisor2);
+ devpriv->AdControlReg |= AdControl_SoftG;
+ }
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
+ }
+
+ DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma()\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int addchans = 0;
+ int ret = 0;
+
+ DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n", dev->minor);
+ devpriv->ai12_startstop = 0;
+ devpriv->ai_flags = cmd->flags;
+ devpriv->ai_n_chan = cmd->chanlist_len;
+ devpriv->ai_n_scanlen = cmd->scan_end_arg;
+ devpriv->ai_chanlist = cmd->chanlist;
+ devpriv->ai_data = s->async->prealloc_buf;
+ devpriv->ai_data_len = s->async->prealloc_bufsz;
+ devpriv->ai_timer1 = 0;
+ devpriv->ai_timer2 = 0;
+ devpriv->ai_add_front = 0;
+ devpriv->ai_add_back = 0;
+ devpriv->ai_maskerr = 0x10e;
+
+ // prepare for start/stop conditions
+ if (cmd->start_src == TRIG_EXT)
+ devpriv->ai12_startstop |= START_AI_EXT;
+ if (cmd->stop_src == TRIG_EXT) {
+ devpriv->ai_neverending = 1;
+ devpriv->ai12_startstop |= STOP_AI_EXT;
+ }
+ if (cmd->start_src == TRIG_INT) {
+ devpriv->ai12_startstop |= START_AI_INT;
+ devpriv->ai_inttrig_start = cmd->start_arg;
+ s->async->inttrig = pci9118_ai_inttrig;
+ }
+#if 0
+ if (cmd->stop_src == TRIG_INT) {
+ devpriv->ai_neverending = 1;
+ devpriv->ai12_startstop |= STOP_AI_INT;
+ }
+#endif
+ if (cmd->stop_src == TRIG_NONE)
+ devpriv->ai_neverending = 1;
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ai_scans = cmd->stop_arg;
+ devpriv->ai_neverending = 0;
+ } else {
+ devpriv->ai_scans = 0;
+ }
+
+ // use sample&hold signal?
+ if (cmd->convert_src == TRIG_NOW) {
+ devpriv->usessh = 1;
+ } // yes
+ else {
+ devpriv->usessh = 0;
+ } // no
+
+ DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n",
+ devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh,
+ devpriv->ai12_startstop);
+
+ // use additional sample at end of every scan to satisty DMA 32 bit transfer?
+ devpriv->ai_add_front = 0;
+ devpriv->ai_add_back = 0;
+ devpriv->useeoshandle = 0;
+ if (devpriv->master) {
+ devpriv->usedma = 1;
+ if ((cmd->flags & TRIG_WAKE_EOS) &&
+ (devpriv->ai_n_scanlen == 1)) {
+ if (cmd->convert_src == TRIG_NOW) {
+ devpriv->ai_add_back = 1;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ devpriv->usedma = 0; // use INT transfer if scanlist have only one channel
+ }
+ }
+ if ((cmd->flags & TRIG_WAKE_EOS) &&
+ (devpriv->ai_n_scanlen & 1) &&
+ (devpriv->ai_n_scanlen > 1)) {
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ //vpriv->useeoshandle=1; // change DMA transfer block to fit EOS on every second call
+ devpriv->usedma = 0; // XXX maybe can be corrected to use 16 bit DMA
+ } else { // well, we must insert one sample to end of EOS to meet 32 bit transfer
+ devpriv->ai_add_back = 1;
+ }
+ }
+ } else { // interrupt transfer don't need any correction
+ devpriv->usedma = 0;
+ }
+
+ // we need software S&H signal? It add two samples before every scan as minimum
+ if (devpriv->usessh && devpriv->softsshdelay) {
+ devpriv->ai_add_front = 2;
+ if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) { // move it to front
+ devpriv->ai_add_front++;
+ devpriv->ai_add_back = 0;
+ }
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+ addchans = devpriv->softsshdelay / cmd->convert_arg;
+ if (devpriv->softsshdelay % cmd->convert_arg)
+ addchans++;
+ if (addchans > (devpriv->ai_add_front - 1)) { // uff, still short :-(
+ devpriv->ai_add_front = addchans + 1;
+ if (devpriv->usedma == 1)
+ if ((devpriv->ai_add_front +
+ devpriv->ai_n_chan +
+ devpriv->ai_add_back) & 1)
+ devpriv->ai_add_front++; // round up to 32 bit
+ }
+ } // well, we now know what must be all added
+
+ devpriv->ai_n_realscanlen = // what we must take from card in real to have ai_n_scanlen on output?
+ (devpriv->ai_add_front + devpriv->ai_n_chan +
+ devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
+ devpriv->ai_n_chan);
+
+ DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n",
+ devpriv->usedma,
+ devpriv->ai_n_realscanlen, devpriv->ai_add_front,
+ devpriv->ai_n_chan, devpriv->ai_add_back,
+ devpriv->ai_n_scanlen);
+
+ // check and setup channel list
+ if (!check_channel_list(dev, s, devpriv->ai_n_chan,
+ devpriv->ai_chanlist, devpriv->ai_add_front,
+ devpriv->ai_add_back))
+ return -EINVAL;
+ if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
+ devpriv->ai_chanlist, 0, devpriv->ai_add_front,
+ devpriv->ai_add_back, devpriv->usedma,
+ devpriv->useeoshandle))
+ return -EINVAL;
+
+ // compute timers settings
+ // simplest way, fr=4Mhz/(tim1*tim2), channel manipulation without timers effect
+ if (((cmd->scan_begin_src == TRIG_FOLLOW) || (cmd->scan_begin_src == TRIG_EXT) || (cmd->scan_begin_src == TRIG_INT)) && (cmd->convert_src == TRIG_TIMER)) { // both timer is used for one time
+ if (cmd->scan_begin_src == TRIG_EXT) {
+ devpriv->ai_do = 4;
+ } else {
+ devpriv->ai_do = 1;
+ }
+ pci9118_calc_divisors(devpriv->ai_do, dev, s,
+ &cmd->scan_begin_arg, &cmd->convert_arg,
+ devpriv->ai_flags, devpriv->ai_n_realscanlen,
+ &devpriv->ai_divisor1, &devpriv->ai_divisor2,
+ devpriv->usessh, devpriv->ai_add_front);
+ devpriv->ai_timer2 = cmd->convert_arg;
+ }
+
+ if ((cmd->scan_begin_src == TRIG_TIMER) && ((cmd->convert_src == TRIG_TIMER) || (cmd->convert_src == TRIG_NOW))) { // double timed action
+ if (!devpriv->usedma) {
+ comedi_error(dev,
+ "cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!");
+ return -EIO;
+ }
+
+ devpriv->ai_do = 2;
+ pci9118_calc_divisors(devpriv->ai_do, dev, s,
+ &cmd->scan_begin_arg, &cmd->convert_arg,
+ devpriv->ai_flags, devpriv->ai_n_realscanlen,
+ &devpriv->ai_divisor1, &devpriv->ai_divisor2,
+ devpriv->usessh, devpriv->ai_add_front);
+ devpriv->ai_timer1 = cmd->scan_begin_arg;
+ devpriv->ai_timer2 = cmd->convert_arg;
+ }
+
+ if ((cmd->scan_begin_src == TRIG_FOLLOW)
+ && (cmd->convert_src == TRIG_EXT)) {
+ devpriv->ai_do = 3;
+ }
+
+ start_pacer(dev, -1, 0, 0); // stop pacer
+
+ devpriv->AdControlReg = 0; // bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable DMA
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
+ devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; // positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+ comedi_udelay(1);
+ outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
+ inl(dev->iobase + PCI9118_ADSTAT); // flush A/D and INT status register
+ inl(dev->iobase + PCI9118_INTSRC);
+
+ devpriv->ai_act_scan = 0;
+ devpriv->ai_act_dmapos = 0;
+ s->async->cur_chan = 0;
+ devpriv->ai_buf_ptr = 0;
+
+ if (devpriv->usedma) {
+ ret = pci9118_ai_docmd_dma(dev, s);
+ } else {
+ ret = pci9118_ai_docmd_sampl(dev, s);
+ }
+
+ DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n");
+ return ret;
+}
+
+/*
+==============================================================================
+*/
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ int n_chan, unsigned int *chanlist, int frontadd, int backadd)
+{
+ unsigned int i, differencial = 0, bipolar = 0;
+
+ /* correct channel and range number check itself comedi/range.c */
+ if (n_chan < 1) {
+ comedi_error(dev, "range/channel list is empty!");
+ return 0;
+ }
+ if ((frontadd + n_chan + backadd) > s->len_chanlist) {
+ rt_printk
+ ("comedi%d: range/channel list is too long for actual configuration (%d>%d)!",
+ dev->minor, n_chan,
+ s->len_chanlist - frontadd - backadd);
+ return 0;
+ }
+
+ if (CR_AREF(chanlist[0]) == AREF_DIFF)
+ differencial = 1; // all input must be diff
+ if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
+ bipolar = 1; // all input must be bipolar
+ if (n_chan > 1)
+ for (i = 1; i < n_chan; i++) { // check S.E/diff
+ if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
+ (differencial)) {
+ comedi_error(dev,
+ "Differencial and single ended inputs cann't be mixtured!");
+ return 0;
+ }
+ if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
+ (bipolar)) {
+ comedi_error(dev,
+ "Bipolar and unipolar ranges cann't be mixtured!");
+ return 0;
+ }
+ if ((!devpriv->usemux) & (differencial) &
+ (CR_CHAN(chanlist[i]) >=
+ this_board->n_aichand)) {
+ comedi_error(dev,
+ "If AREF_DIFF is used then is available only first 8 channels!");
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*
+==============================================================================
+*/
+static int setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ int n_chan, unsigned int *chanlist, int rot, int frontadd, int backadd,
+ int usedma, char useeos)
+{
+ unsigned int i, differencial = 0, bipolar = 0;
+ unsigned int scanquad, gain, ssh = 0x00;
+
+ DPRINTK("adl_pci9118 EDBG: BGN: setup_channel_list(%d,.,%d,.,%d,%d,%d,%d)\n", dev->minor, n_chan, rot, frontadd, backadd, usedma);
+
+ if (usedma == 1) {
+ rot = 8;
+ usedma = 0;
+ }
+
+ if (CR_AREF(chanlist[0]) == AREF_DIFF)
+ differencial = 1; // all input must be diff
+ if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
+ bipolar = 1; // all input must be bipolar
+
+ // All is ok, so we can setup channel/range list
+
+ if (!bipolar) {
+ devpriv->AdControlReg |= AdControl_UniP; // set unibipolar
+ } else {
+ devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff); // enable bipolar
+ }
+
+ if (differencial) {
+ devpriv->AdControlReg |= AdControl_Diff; // enable diff inputs
+ } else {
+ devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff); // set single ended inputs
+ }
+
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); // setup mode
+
+ outl(2, dev->iobase + PCI9118_SCANMOD); // gods know why this sequence!
+ outl(0, dev->iobase + PCI9118_SCANMOD);
+ outl(1, dev->iobase + PCI9118_SCANMOD);
+
+#ifdef PCI9118_PARANOIDCHECK
+ devpriv->chanlistlen = n_chan;
+ for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
+ devpriv->chanlist[i] = 0x55aa;
+#endif
+
+ if (frontadd) { // insert channels for S&H
+ ssh = devpriv->softsshsample;
+ DPRINTK("FA: %04x: ", ssh);
+ for (i = 0; i < frontadd; i++) { // store range list to card
+ scanquad = CR_CHAN(chanlist[0]); // get channel number;
+ gain = CR_RANGE(chanlist[0]); // get gain number
+ scanquad |= ((gain & 0x03) << 8);
+ outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
+ DPRINTK("%02x ", scanquad | ssh);
+ ssh = devpriv->softsshhold;
+ }
+ DPRINTK("\n ");
+ }
+
+ DPRINTK("SL: ", ssh);
+ for (i = 0; i < n_chan; i++) { // store range list to card
+ scanquad = CR_CHAN(chanlist[i]); // get channel number;
+#ifdef PCI9118_PARANOIDCHECK
+ devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
+#endif
+ gain = CR_RANGE(chanlist[i]); // get gain number
+ scanquad |= ((gain & 0x03) << 8);
+ outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
+ DPRINTK("%02x ", scanquad | ssh);
+ }
+ DPRINTK("\n ");
+
+ if (backadd) { // insert channels for fit onto 32bit DMA
+ DPRINTK("BA: %04x: ", ssh);
+ for (i = 0; i < backadd; i++) { // store range list to card
+ scanquad = CR_CHAN(chanlist[0]); // get channel number;
+ gain = CR_RANGE(chanlist[0]); // get gain number
+ scanquad |= ((gain & 0x03) << 8);
+ outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
+ DPRINTK("%02x ", scanquad | ssh);
+ }
+ DPRINTK("\n ");
+ }
+#ifdef PCI9118_PARANOIDCHECK
+ devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma]; // for 32bit oerations
+ if (useeos) {
+ for (i = 1; i < n_chan; i++) { // store range list to card
+ devpriv->chanlist[(n_chan + i) ^ usedma] =
+ (CR_CHAN(chanlist[i]) & 0xf) << rot;
+ }
+ devpriv->chanlist[(2 * n_chan) ^ usedma] = devpriv->chanlist[0 ^ usedma]; // for 32bit oerations
+ useeos = 2;
+ } else {
+ useeos = 1;
+ }
+#ifdef PCI9118_EXTDEBUG
+ DPRINTK("CHL: ");
+ for (i = 0; i <= (useeos * n_chan); i++) {
+ DPRINTK("%04x ", devpriv->chanlist[i]);
+ }
+ DPRINTK("\n ");
+#endif
+#endif
+ outl(0, dev->iobase + PCI9118_SCANMOD); // close scan queue
+// comedi_udelay(100); // important delay, or first sample will be cripled
+
+ DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n");
+ return 1; // we can serve this with scan logic
+}
+
+/*
+==============================================================================
+ calculate 8254 divisors if they are used for dual timing
+*/
+static void pci9118_calc_divisors(char mode, struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned int *tim1, unsigned int *tim2,
+ unsigned int flags, int chans, unsigned int *div1, unsigned int *div2,
+ char usessh, unsigned int chnsshfront)
+{
+ DPRINTK("adl_pci9118 EDBG: BGN: pci9118_calc_divisors(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n", mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront);
+ switch (mode) {
+ case 1:
+ case 4:
+ if (*tim2 < this_board->ai_ns_min)
+ *tim2 = this_board->ai_ns_min;
+ i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
+ tim2, flags & TRIG_ROUND_NEAREST);
+ DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n",
+ devpriv->i8254_osc_base, *div1, *div2, *tim1);
+ break;
+ case 2:
+ if (*tim2 < this_board->ai_ns_min)
+ *tim2 = this_board->ai_ns_min;
+ DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+ *div1 = *tim2 / devpriv->i8254_osc_base; // convert timer (burst)
+ DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+ if (*div1 < this_board->ai_pacer_min)
+ *div1 = this_board->ai_pacer_min;
+ DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+ *div2 = *tim1 / devpriv->i8254_osc_base; // scan timer
+ DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+ *div2 = *div2 / *div1; // major timer is c1*c2
+ DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+ if (*div2 < chans)
+ *div2 = chans;
+ DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+
+ *tim2 = *div1 * devpriv->i8254_osc_base; // real convert timer
+
+ if (usessh & (chnsshfront == 0)) // use BSSH signal
+ if (*div2 < (chans + 2))
+ *div2 = chans + 2;
+
+ DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+ *tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
+ DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n",
+ devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2);
+ break;
+ }
+ DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n",
+ *div1, *div2);
+}
+
+/*
+==============================================================================
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2)
+{
+ outl(0x74, dev->iobase + PCI9118_CNTCTRL);
+ outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
+// outl(0x30, dev->iobase + PCI9118_CNTCTRL);
+ comedi_udelay(1);
+
+ if ((mode == 1) || (mode == 2) || (mode == 4)) {
+ outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
+ outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
+ outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
+ outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
+ }
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_exttrg_add(struct comedi_device * dev, unsigned char source)
+{
+ if (source > 3)
+ return -1; // incorrect source
+ devpriv->exttrg_users |= (1 << source);
+ devpriv->IntControlReg |= Int_DTrg;
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR); // allow INT in AMCC
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_exttrg_del(struct comedi_device * dev, unsigned char source)
+{
+ if (source > 3)
+ return -1; // incorrect source
+ devpriv->exttrg_users &= ~(1 << source);
+ if (!devpriv->exttrg_users) { // shutdown ext trg intterrupts
+ devpriv->IntControlReg &= ~Int_DTrg;
+ if (!devpriv->IntControlReg) // all IRQ disabled
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) & (~0x00001f00), devpriv->iobase_a + AMCC_OP_REG_INTCSR); // disable int in AMCC
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+ }
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (devpriv->usedma)
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), devpriv->iobase_a + AMCC_OP_REG_MCSR); // stop DMA
+ pci9118_exttrg_del(dev, EXTTRG_AI);
+ start_pacer(dev, 0, 0, 0); // stop 8254 counters
+ devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); // positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
+ devpriv->AdControlReg = 0x00;
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); // bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA
+ outl(0, dev->iobase + PCI9118_BURST);
+ outl(1, dev->iobase + PCI9118_SCANMOD);
+ outl(2, dev->iobase + PCI9118_SCANMOD); // reset scan queue
+ outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
+
+ devpriv->ai_do = 0;
+ devpriv->usedma = 0;
+
+ devpriv->ai_act_scan = 0;
+ devpriv->ai_act_dmapos = 0;
+ s->async->cur_chan = 0;
+ s->async->inttrig = NULL;
+ devpriv->ai_buf_ptr = 0;
+ devpriv->ai_neverending = 0;
+ devpriv->dma_actbuf = 0;
+
+ if (!devpriv->IntControlReg)
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR); // allow INT in AMCC
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_reset(struct comedi_device * dev)
+{
+ devpriv->IntControlReg = 0;
+ devpriv->exttrg_users = 0;
+ inl(dev->iobase + PCI9118_INTCTRL);
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); // disable interrupts source
+ outl(0x30, dev->iobase + PCI9118_CNTCTRL);
+// outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
+ start_pacer(dev, 0, 0, 0); // stop 8254 counters
+ devpriv->AdControlReg = 0;
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); // bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA
+ outl(0, dev->iobase + PCI9118_BURST);
+ outl(1, dev->iobase + PCI9118_SCANMOD);
+ outl(2, dev->iobase + PCI9118_SCANMOD); // reset scan queue
+ devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); // positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
+
+ devpriv->ao_data[0] = 2047;
+ devpriv->ao_data[1] = 2047;
+ outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1); // reset A/D outs to 0V
+ outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
+ outl(0, dev->iobase + PCI9118_DO); // reset digi outs to L
+ comedi_udelay(10);
+ inl(dev->iobase + PCI9118_AD_DATA);
+ outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
+ outl(0, dev->iobase + PCI9118_INTSRC); // remove INT requests
+ inl(dev->iobase + PCI9118_ADSTAT); // flush A/D status register
+ inl(dev->iobase + PCI9118_INTSRC); // flush INT requests
+ devpriv->AdControlReg = 0;
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); // bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA
+
+ devpriv->cnt0_users = 0;
+ devpriv->exttrg_users = 0;
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret, pages, i;
+ unsigned short master;
+ unsigned int irq;
+ unsigned long iobase_a, iobase_9;
+ struct pci_dev *pcidev;
+ int opt_bus, opt_slot;
+ const char *errstr;
+ unsigned char pci_bus, pci_slot, pci_func;
+ u16 u16w;
+
+ rt_printk("comedi%d: adl_pci9118: board=%s", dev->minor,
+ this_board->name);
+
+ opt_bus = it->options[0];
+ opt_slot = it->options[1];
+ if (it->options[3] & 1) {
+ master = 0; // user don't want use bus master
+ } else {
+ master = 1;
+ }
+
+ if ((ret = alloc_private(dev, sizeof(struct pci9118_private))) < 0) {
+ rt_printk(" - Allocation failed!\n");
+ return -ENOMEM;
+ }
+
+ /* Look for matching PCI device */
+ errstr = "not found!";
+ pcidev = NULL;
+ while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC,
+ this_board->device_id, pcidev))) {
+ /* Found matching vendor/device. */
+ if (opt_bus || opt_slot) {
+ /* Check bus/slot. */
+ if (opt_bus != pcidev->bus->number
+ || opt_slot != PCI_SLOT(pcidev->devfn))
+ continue; /* no match */
+ }
+ /*
+ * Look for device that isn't in use.
+ * Enable PCI device and request regions.
+ */
+ if (comedi_pci_enable(pcidev, "adl_pci9118")) {
+ errstr = "failed to enable PCI device and request regions!";
+ continue;
+ }
+ break;
+ }
+
+ if (!pcidev) {
+ if (opt_bus || opt_slot) {
+ rt_printk(" - Card at b:s %d:%d %s\n",
+ opt_bus, opt_slot, errstr);
+ } else {
+ rt_printk(" - Card %s\n", errstr);
+ }
+ return -EIO;
+ }
+
+ if (master) {
+ pci_set_master(pcidev);
+ }
+
+ pci_bus = pcidev->bus->number;
+ pci_slot = PCI_SLOT(pcidev->devfn);
+ pci_func = PCI_FUNC(pcidev->devfn);
+ irq = pcidev->irq;
+ iobase_a = pci_resource_start(pcidev, 0);
+ iobase_9 = pci_resource_start(pcidev, 2);
+
+ rt_printk(", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus, pci_slot,
+ pci_func, iobase_9, iobase_a);
+
+ dev->iobase = iobase_9;
+ dev->board_name = this_board->name;
+
+ devpriv->pcidev = pcidev;
+ devpriv->iobase_a = iobase_a;
+
+ pci9118_reset(dev);
+
+ if (it->options[3] & 2)
+ irq = 0; // user don't want use IRQ
+ if (irq > 0) {
+ if (comedi_request_irq(irq, interrupt_pci9118, IRQF_SHARED,
+ "ADLink PCI-9118", dev)) {
+ rt_printk(", unable to allocate IRQ %d, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk(", irq=%u", irq);
+ }
+ } else {
+ rt_printk(", IRQ disabled");
+ }
+
+ dev->irq = irq;
+
+ if (master) { // alloc DMA buffers
+ devpriv->dma_doublebuf = 0;
+ for (i = 0; i < 2; i++) {
+ for (pages = 4; pages >= 0; pages--)
+ if ((devpriv->dmabuf_virt[i] = (short *)
+ __get_free_pages(GFP_KERNEL,
+ pages)))
+ break;
+ if (devpriv->dmabuf_virt[i]) {
+ devpriv->dmabuf_pages[i] = pages;
+ devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
+ devpriv->dmabuf_samples[i] =
+ devpriv->dmabuf_size[i] >> 1;
+ devpriv->dmabuf_hw[i] =
+ virt_to_bus((void *)devpriv->
+ dmabuf_virt[i]);
+ }
+ }
+ if (!devpriv->dmabuf_virt[0]) {
+ rt_printk(", Can't allocate DMA buffer, DMA disabled!");
+ master = 0;
+ }
+
+ if (devpriv->dmabuf_virt[1])
+ devpriv->dma_doublebuf = 1;
+
+ }
+
+ if ((devpriv->master = master)) {
+ rt_printk(", bus master");
+ } else {
+ rt_printk(", no bus master");
+ }
+
+ devpriv->usemux = 0;
+ if (it->options[2] > 0) {
+ devpriv->usemux = it->options[2];
+ if (devpriv->usemux > 256)
+ devpriv->usemux = 256; // max 256 channels!
+ if (it->options[4] > 0)
+ if (devpriv->usemux > 128) {
+ devpriv->usemux = 128; // max 128 channels with softare S&H!
+ }
+ rt_printk(", ext. mux %d channels", devpriv->usemux);
+ }
+
+ devpriv->softsshdelay = it->options[4];
+ if (devpriv->softsshdelay < 0) { // select sample&hold signal polarity
+ devpriv->softsshdelay = -devpriv->softsshdelay;
+ devpriv->softsshsample = 0x80;
+ devpriv->softsshhold = 0x00;
+ } else {
+ devpriv->softsshsample = 0x00;
+ devpriv->softsshhold = 0x80;
+ }
+
+ rt_printk(".\n");
+
+ pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w);
+ pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64); // Enable parity check for parity error
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
+ if (devpriv->usemux) {
+ s->n_chan = devpriv->usemux;
+ } else {
+ s->n_chan = this_board->n_aichan;
+ }
+ s->maxdata = this_board->ai_maxdata;
+ s->len_chanlist = this_board->n_aichanlist;
+ s->range_table = this_board->rangelist_ai;
+ s->cancel = pci9118_ai_cancel;
+ s->insn_read = pci9118_insn_read_ai;
+ if (dev->irq) {
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmdtest = pci9118_ai_cmdtest;
+ s->do_cmd = pci9118_ai_cmd;
+ s->munge = pci9118_ai_munge;
+ }
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = this_board->ao_maxdata;
+ s->len_chanlist = this_board->n_aochan;
+ s->range_table = this_board->rangelist_ao;
+ s->insn_write = pci9118_insn_write_ao;
+ s->insn_read = pci9118_insn_read_ao;
+
+ s = dev->subdevices + 2;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->len_chanlist = 4;
+ s->range_table = &range_digital;
+ s->io_bits = 0; /* all bits input */
+ s->insn_bits = pci9118_insn_bits_di;
+
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->len_chanlist = 4;
+ s->range_table = &range_digital;
+ s->io_bits = 0xf; /* all bits output */
+ s->insn_bits = pci9118_insn_bits_do;
+
+ devpriv->valid = 1;
+ devpriv->i8254_osc_base = 250; // 250ns=4MHz
+ devpriv->ai_maskharderr = 0x10a; // default measure crash condition
+ if (it->options[5]) // disable some requested
+ devpriv->ai_maskharderr &= ~it->options[5];
+
+ switch (this_board->ai_maxdata) {
+ case 0xffff:
+ devpriv->ai16bits = 1;
+ break;
+ default:
+ devpriv->ai16bits = 0;
+ break;
+ }
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_detach(struct comedi_device * dev)
+{
+ if (dev->private) {
+ if (devpriv->valid)
+ pci9118_reset(dev);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (devpriv->pcidev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pcidev);
+ }
+ pci_dev_put(devpriv->pcidev);
+ }
+ if (devpriv->dmabuf_virt[0])
+ free_pages((unsigned long)devpriv->dmabuf_virt[0],
+ devpriv->dmabuf_pages[0]);
+ if (devpriv->dmabuf_virt[1])
+ free_pages((unsigned long)devpriv->dmabuf_virt[1],
+ devpriv->dmabuf_pages[1]);
+ }
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c
new file mode 100644
index 00000000000..92f62854d6d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adq12b.c
@@ -0,0 +1,394 @@
+/*
+ comedi/drivers/adq12b.c
+ driver for MicroAxial ADQ12-B data acquisition and control card
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: adq12b
+Description: driver for MicroAxial ADQ12-B data acquisition and control card
+Devices: [MicroAxial] ADQ12-B (adq12b)
+Author: jeremy theler <thelerg@ib.cnea.gov.ar>
+Updated: Thu, 21 Feb 2008 02:56:27 -0300
+Status: works
+
+Driver for the acquisition card ADQ12-B (without any add-on).
+
+ - Analog input is subdevice 0 (16 channels single-ended or 8 differential)
+ - Digital input is subdevice 1 (5 channels)
+ - Digital output is subdevice 1 (8 channels)
+ - The PACER is not supported in this version
+
+If you do not specify any options, they will default to
+
+ # comedi_config /dev/comedi0 adq12b 0x300,0,0
+
+ option 1: I/O base address. The following table is provided as a help
+ of the hardware jumpers.
+
+ address jumper JADR
+ 0x300 1 (factory default)
+ 0x320 2
+ 0x340 3
+ 0x360 4
+ 0x380 5
+ 0x3A0 6
+
+ option 2: unipolar/bipolar ADC selection: 0 -> bipolar, 1 -> unipolar
+
+ selection comedi_config option JUB
+ bipolar 0 2-3 (factory default)
+ unipolar 1 1-2
+
+ option 3: single-ended/differential AI selection: 0 -> SE, 1 -> differential
+
+ selection comedi_config option JCHA JCHB
+ single-ended 0 1-2 1-2 (factory default)
+ differential 1 2-3 2-3
+
+
+ written by jeremy theler <thelerg@ib.cnea.gov.ar>
+
+ instituto balseiro
+ comision nacional de energia atomica
+ universidad nacional de cuyo
+ argentina
+
+ 21-feb-2008
+ + changed supported devices string (missused the [] and ())
+
+ 13-oct-2007
+ + first try
+
+
+*/
+
+#include "../comedidev.h"
+
+// address scheme (page 2.17 of the manual)
+#define ADQ12B_SIZE 16
+
+#define ADQ12B_CTREG 0x00
+#define ADQ12B_STINR 0x00
+#define ADQ12B_OUTBR 0x04
+#define ADQ12B_ADLOW 0x08
+#define ADQ12B_ADHIG 0x09
+#define ADQ12B_CONT0 0x0c
+#define ADQ12B_CONT1 0x0d
+#define ADQ12B_CONT2 0x0e
+#define ADQ12B_COWORD 0x0f
+
+// mask of the bit at STINR to check end of conversion
+#define ADQ12B_EOC 0x20
+
+#define TIMEOUT 20
+
+// available ranges through the PGA gains
+static const struct comedi_lrange range_adq12b_ai_bipolar = { 4, {
+ BIP_RANGE( 5 ),
+ BIP_RANGE( 2 ),
+ BIP_RANGE( 1 ),
+ BIP_RANGE( 0.5 )
+}};
+
+static const struct comedi_lrange range_adq12b_ai_unipolar = { 4, {
+ UNI_RANGE( 5 ),
+ UNI_RANGE( 2 ),
+ UNI_RANGE( 1 ),
+ UNI_RANGE( 0.5 )
+}};
+
+
+
+struct adq12b_board {
+ const char *name;
+ int ai_se_chans;
+ int ai_diff_chans;
+ int ai_bits;
+ int di_chans;
+ int do_chans;
+};
+
+static const struct adq12b_board adq12b_boards[] = {
+ {
+ name: "adq12b",
+ ai_se_chans: 16,
+ ai_diff_chans: 8,
+ ai_bits: 12,
+ di_chans: 5,
+ do_chans: 8
+ }
+// potentially, more adq-based deviced will be added
+/*,
+ name: "adq12b",
+ ai_chans: 16, // this is just for reference, hardcoded again later
+ ai_bits: 12,
+ di_chans: 8,
+ do_chans: 5
+ }*/
+};
+
+#define thisboard ((const struct adq12b_board *)dev->board_ptr)
+
+struct adq12b_private {
+ int unipolar; /* option 2 of comedi_config (1 is iobase) */
+ int differential; /* option 3 of comedi_config */
+ int last_channel;
+ int last_range;
+ unsigned int digital_state;
+};
+
+#define devpriv ((struct adq12b_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int adq12b_attach(struct comedi_device *dev,struct comedi_devconfig *it);
+static int adq12b_detach(struct comedi_device *dev);
+static struct comedi_driver driver_adq12b={
+ driver_name: "adq12b",
+ module: THIS_MODULE,
+ attach: adq12b_attach,
+ detach: adq12b_detach,
+ board_name: &adq12b_boards[0].name,
+ offset: sizeof(struct adq12b_board),
+ num_names: sizeof(adq12b_boards) / sizeof(struct adq12b_board),
+};
+
+static int adq12b_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data);
+static int adq12b_di_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data);
+static int adq12b_do_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int adq12b_attach(struct comedi_device *dev,struct comedi_devconfig *it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+ int unipolar, differential;
+
+ iobase = it->options[0];
+ unipolar = it->options[1];
+ differential = it->options[2];
+
+ printk("comedi%d: adq12b called with options base=0x%03lx, %s and %s\n",dev->minor, iobase, (unipolar==1)?"unipolar":"bipolar", (differential==1)?"differential":"single-ended");
+
+ /* if no address was specified, try the default 0x300 */
+ if (iobase == 0) {
+ printk("comedi%d: adq12b warning: I/O base address not specified. Trying the default 0x300.\n", dev->minor);
+ iobase = 0x300;
+ }
+
+ printk("comedi%d: adq12b: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, ADQ12B_SIZE, "adq12b")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if(alloc_private(dev, sizeof(struct adq12b_private)) < 0)
+ return -ENOMEM;
+
+/* fill in devpriv structure */
+ devpriv->unipolar = unipolar;
+ devpriv->differential = differential;
+ devpriv->digital_state = 0;
+/* initialize channel and range to -1 so we make sure we always write
+ at least once to the CTREG in the instruction */
+ devpriv->last_channel = -1;
+ devpriv->last_range = -1;
+
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if(alloc_subdevices(dev, 3)<0)
+ return -ENOMEM;
+
+ s = dev->subdevices+0;
+ /* analog input subdevice */
+ s->type = COMEDI_SUBD_AI;
+ if (differential) {
+ s->subdev_flags = SDF_READABLE|SDF_GROUND|SDF_DIFF;
+ s->n_chan = thisboard->ai_diff_chans;
+ } else {
+ s->subdev_flags = SDF_READABLE|SDF_GROUND;
+ s->n_chan = thisboard->ai_se_chans;
+ }
+
+ if (unipolar) {
+ s->range_table = &range_adq12b_ai_unipolar;
+ } else {
+ s->range_table = &range_adq12b_ai_bipolar;
+ }
+
+ s->maxdata = (1 << thisboard->ai_bits)-1;
+
+
+ s->len_chanlist = 4; /* This is the maximum chanlist length that
+ the board can handle */
+ s->insn_read = adq12b_ai_rinsn;
+
+
+ s = dev->subdevices+1;
+ /* digital input subdevice */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan=thisboard->di_chans;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = adq12b_di_insn_bits;
+
+ s = dev->subdevices+2;
+ /* digital output subdevice */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->do_chans;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = adq12b_do_insn_bits;
+
+
+ printk("attached\n");
+
+ return 0;
+}
+
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int adq12b_detach(struct comedi_device *dev)
+{
+ if (dev->iobase)
+ release_region(dev->iobase, ADQ12B_SIZE);
+
+ kfree(devpriv);
+
+ printk("comedi%d: adq12b: removed\n",dev->minor);
+
+ return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+
+static int adq12b_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)
+{
+ int n, i;
+ int range, channel;
+ unsigned char hi, lo, status;
+
+ /* change channel and range only if it is different from the previous */
+ range = CR_RANGE(insn->chanspec);
+ channel = CR_CHAN(insn->chanspec);
+ if (channel != devpriv->last_channel || range != devpriv->last_range) {
+ outb((range << 4) | channel, dev->iobase + ADQ12B_CTREG);
+ comedi_udelay(50); /* wait for the mux to settle */
+ }
+
+ /* trigger conversion */
+ status = inb(dev->iobase + ADQ12B_ADLOW);
+
+ /* convert n samples */
+ for(n=0; n < insn->n; n++){
+
+ /* wait for end of convertion */
+ i = 0;
+ do {
+// comedi_udelay(1);
+ status = inb(dev->iobase + ADQ12B_STINR);
+ status = status & ADQ12B_EOC;
+ } while (status == 0 && ++i < TIMEOUT);
+// } while (++i < 10);
+
+ /* read data */
+ hi = inb(dev->iobase + ADQ12B_ADHIG);
+ lo = inb(dev->iobase + ADQ12B_ADLOW);
+
+ //rt_printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", channel, range, status, hi, lo);
+ data[n] = (hi << 8) | lo;
+
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+
+static int adq12b_di_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data)
+{
+
+ /* only bits 0-4 have information about digital inputs */
+ data[1] = (inb(dev->iobase+ADQ12B_STINR) & (0x1f));
+
+ return 2;
+}
+
+
+static int adq12b_do_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data)
+{
+ int channel;
+
+ for (channel = 0; channel < 8; channel++)
+ if (((data[0]>>channel) & 0x01) != 0)
+ outb((((data[1]>>channel)&0x01)<<3) | channel, dev->iobase + ADQ12B_OUTBR);
+
+ /* store information to retrieve when asked for reading */
+ if (data[0]) {
+ devpriv->digital_state &= ~data[0];
+ devpriv->digital_state |= (data[0]&data[1]);
+ }
+
+ data[1] = devpriv->digital_state;
+
+ return 2;
+}
+
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_adq12b);
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
new file mode 100644
index 00000000000..29eac743c8e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -0,0 +1,1568 @@
+/*
+ * comedi/drivers/adv_pci1710.c
+ *
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ *
+ * Thanks to ZhenGang Shang <ZhenGang.Shang@Advantech.com.cn>
+ * for testing and informations.
+ *
+ * hardware driver for Advantech cards:
+ * card: PCI-1710, PCI-1710HG, PCI-1711, PCI-1713, PCI-1720, PCI-1731
+ * driver: pci1710, pci1710hg, pci1711, pci1713, pci1720, pci1731
+ *
+ * Options:
+ * [0] - PCI bus number - if bus number and slot number are 0,
+ * then driver search for first unused card
+ * [1] - PCI slot number
+ *
+*/
+/*
+Driver: adv_pci1710
+Description: Advantech PCI-1710, PCI-1710HG, PCI-1711, PCI-1713,
+ Advantech PCI-1720, PCI-1731
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCI-1710 (adv_pci1710), PCI-1710HG (pci1710hg),
+ PCI-1711 (adv_pci1710), PCI-1713, PCI-1720,
+ PCI-1731
+Status: works
+
+This driver supports AI, AO, DI and DO subdevices.
+AI subdevice supports cmd and insn interface,
+other subdevices support only insn interface.
+
+The PCI-1710 and PCI-1710HG have the same PCI device ID, so the
+driver cannot distinguish between them, as would be normal for a
+PCI driver.
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI
+ device will be used.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "8253.h"
+#include "amcc_s5933.h"
+
+#define PCI171x_PARANOIDCHECK /* if defined, then is used code which control correct channel number on every 12 bit sample */
+
+#undef PCI171X_EXTDEBUG
+
+#define DRV_NAME "adv_pci1710"
+
+#undef DPRINTK
+#ifdef PCI171X_EXTDEBUG
+#define DPRINTK(fmt, args...) rt_printk(fmt, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+// hardware types of the cards
+#define TYPE_PCI171X 0
+#define TYPE_PCI1713 2
+#define TYPE_PCI1720 3
+
+#define IORANGE_171x 32
+#define IORANGE_1720 16
+
+#define PCI171x_AD_DATA 0 /* R: A/D data */
+#define PCI171x_SOFTTRG 0 /* W: soft trigger for A/D */
+#define PCI171x_RANGE 2 /* W: A/D gain/range register */
+#define PCI171x_MUX 4 /* W: A/D multiplexor control */
+#define PCI171x_STATUS 6 /* R: status register */
+#define PCI171x_CONTROL 6 /* W: control register */
+#define PCI171x_CLRINT 8 /* W: clear interrupts request */
+#define PCI171x_CLRFIFO 9 /* W: clear FIFO */
+#define PCI171x_DA1 10 /* W: D/A register */
+#define PCI171x_DA2 12 /* W: D/A register */
+#define PCI171x_DAREF 14 /* W: D/A reference control */
+#define PCI171x_DI 16 /* R: digi inputs */
+#define PCI171x_DO 16 /* R: digi inputs */
+#define PCI171x_CNT0 24 /* R/W: 8254 couter 0 */
+#define PCI171x_CNT1 26 /* R/W: 8254 couter 1 */
+#define PCI171x_CNT2 28 /* R/W: 8254 couter 2 */
+#define PCI171x_CNTCTRL 30 /* W: 8254 counter control */
+
+// upper bits from status register (PCI171x_STATUS) (lower is same woth control reg)
+#define Status_FE 0x0100 /* 1=FIFO is empty */
+#define Status_FH 0x0200 /* 1=FIFO is half full */
+#define Status_FF 0x0400 /* 1=FIFO is full, fatal error */
+#define Status_IRQ 0x0800 /* 1=IRQ occured */
+// bits from control register (PCI171x_CONTROL)
+#define Control_CNT0 0x0040 /* 1=CNT0 have external source, 0=have internal 100kHz source */
+#define Control_ONEFH 0x0020 /* 1=IRQ on FIFO is half full, 0=every sample */
+#define Control_IRQEN 0x0010 /* 1=enable IRQ */
+#define Control_GATE 0x0008 /* 1=enable external trigger GATE (8254?) */
+#define Control_EXT 0x0004 /* 1=external trigger source */
+#define Control_PACER 0x0002 /* 1=enable internal 8254 trigger source */
+#define Control_SW 0x0001 /* 1=enable software trigger source */
+// bits from counter control register (PCI171x_CNTCTRL)
+#define Counter_BCD 0x0001 /* 0 = binary counter, 1 = BCD counter */
+#define Counter_M0 0x0002 /* M0-M2 select modes 0-5 */
+#define Counter_M1 0x0004 /* 000 = mode 0, 010 = mode 2 ... */
+#define Counter_M2 0x0008
+#define Counter_RW0 0x0010 /* RW0/RW1 select read/write mode */
+#define Counter_RW1 0x0020
+#define Counter_SC0 0x0040 /* Select Counter. Only 00 or 11 may */
+#define Counter_SC1 0x0080 /* be used, 00 for CNT0, 11 for read-back command */
+
+#define PCI1720_DA0 0 /* W: D/A register 0 */
+#define PCI1720_DA1 2 /* W: D/A register 1 */
+#define PCI1720_DA2 4 /* W: D/A register 2 */
+#define PCI1720_DA3 6 /* W: D/A register 3 */
+#define PCI1720_RANGE 8 /* R/W: D/A range register */
+#define PCI1720_SYNCOUT 9 /* W: D/A synchronized output register */
+#define PCI1720_SYNCONT 15 /* R/W: D/A synchronized control */
+
+// D/A synchronized control (PCI1720_SYNCONT)
+#define Syncont_SC0 1 /* set synchronous output mode */
+
+static const struct comedi_lrange range_pci1710_3 = { 9, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ BIP_RANGE(10),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25)
+ }
+};
+
+static const char range_codes_pci1710_3[] =
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x10, 0x11, 0x12, 0x13 };
+
+static const struct comedi_lrange range_pci1710hg = { 12, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.005),
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.01),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01)
+ }
+};
+
+static const char range_codes_pci1710hg[] =
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12,
+ 0x13 };
+
+static const struct comedi_lrange range_pci17x1 = { 5, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625)
+ }
+};
+
+static const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
+
+static const struct comedi_lrange range_pci1720 = { 4, {
+ UNI_RANGE(5),
+ UNI_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(10)
+ }
+};
+
+static const struct comedi_lrange range_pci171x_da = { 2, {
+ UNI_RANGE(5),
+ UNI_RANGE(10),
+ }
+};
+
+static int pci1710_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci1710_detach(struct comedi_device * dev);
+
+struct boardtype {
+ const char *name; // board name
+ int device_id;
+ int iorange; // I/O range len
+ char have_irq; // 1=card support IRQ
+ char cardtype; // 0=1710& co. 2=1713, ...
+ int n_aichan; // num of A/D chans
+ int n_aichand; // num of A/D chans in diff mode
+ int n_aochan; // num of D/A chans
+ int n_dichan; // num of DI chans
+ int n_dochan; // num of DO chans
+ int n_counter; // num of counters
+ int ai_maxdata; // resolution of A/D
+ int ao_maxdata; // resolution of D/A
+ const struct comedi_lrange *rangelist_ai; // rangelist for A/D
+ const char *rangecode_ai; // range codes for programming
+ const struct comedi_lrange *rangelist_ao; // rangelist for D/A
+ unsigned int ai_ns_min; // max sample speed of card v ns
+ unsigned int fifo_half_size; // size of FIFO/2
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci1710_pci_table) = {
+ {PCI_VENDOR_ID_ADVANTECH, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1711, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1731, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci1710_pci_table);
+
+static const struct boardtype boardtypes[] = {
+ {"pci1710", 0x1710,
+ IORANGE_171x, 1, TYPE_PCI171X,
+ 16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
+ &range_pci1710_3, range_codes_pci1710_3,
+ &range_pci171x_da,
+ 10000, 2048},
+ {"pci1710hg", 0x1710,
+ IORANGE_171x, 1, TYPE_PCI171X,
+ 16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
+ &range_pci1710hg, range_codes_pci1710hg,
+ &range_pci171x_da,
+ 10000, 2048},
+ {"pci1711", 0x1711,
+ IORANGE_171x, 1, TYPE_PCI171X,
+ 16, 0, 2, 16, 16, 1, 0x0fff, 0x0fff,
+ &range_pci17x1, range_codes_pci17x1, &range_pci171x_da,
+ 10000, 512},
+ {"pci1713", 0x1713,
+ IORANGE_171x, 1, TYPE_PCI1713,
+ 32, 16, 0, 0, 0, 0, 0x0fff, 0x0000,
+ &range_pci1710_3, range_codes_pci1710_3, NULL,
+ 10000, 2048},
+ {"pci1720", 0x1720,
+ IORANGE_1720, 0, TYPE_PCI1720,
+ 0, 0, 4, 0, 0, 0, 0x0000, 0x0fff,
+ NULL, NULL, &range_pci1720,
+ 0, 0},
+ {"pci1731", 0x1731,
+ IORANGE_171x, 1, TYPE_PCI171X,
+ 16, 0, 0, 16, 16, 0, 0x0fff, 0x0000,
+ &range_pci17x1, range_codes_pci17x1, NULL,
+ 10000, 512},
+ // dummy entry corresponding to driver name
+ {.name = DRV_NAME},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
+
+static struct comedi_driver driver_pci1710 = {
+ .driver_name = DRV_NAME,
+ .module = THIS_MODULE,
+ .attach = pci1710_attach,
+ .detach = pci1710_detach,
+ .num_names = n_boardtypes,
+ .board_name = &boardtypes[0].name,
+ .offset = sizeof(struct boardtype),
+};
+
+struct pci1710_private {
+ struct pci_dev *pcidev; // ptr to PCI device
+ char valid; // card is usable
+ char neverending_ai; // we do unlimited AI
+ unsigned int CntrlReg; // Control register
+ unsigned int i8254_osc_base; // frequence of onboard oscilator
+ unsigned int ai_do; // what do AI? 0=nothing, 1 to 4 mode
+ unsigned int ai_act_scan; // how many scans we finished
+ unsigned int ai_act_chan; // actual position in actual scan
+ unsigned int ai_buf_ptr; // data buffer ptr in samples
+ unsigned char ai_eos; // 1=EOS wake up
+ unsigned char ai_et;
+ unsigned int ai_et_CntrlReg;
+ unsigned int ai_et_MuxVal;
+ unsigned int ai_et_div1, ai_et_div2;
+ unsigned int act_chanlist[32]; // list of scaned channel
+ unsigned char act_chanlist_len; // len of scanlist
+ unsigned char act_chanlist_pos; // actual position in MUX list
+ unsigned char da_ranges; // copy of D/A outpit range register
+ unsigned int ai_scans; // len of scanlist
+ unsigned int ai_n_chan; // how many channels is measured
+ unsigned int *ai_chanlist; // actaul chanlist
+ unsigned int ai_flags; // flaglist
+ unsigned int ai_data_len; // len of data buffer
+ short *ai_data; // data buffer
+ unsigned int ai_timer1; // timers
+ unsigned int ai_timer2;
+ short ao_data[4]; // data output buffer
+ unsigned int cnt0_write_wait; // after a write, wait for update of the internal state
+};
+
+#define devpriv ((struct pci1710_private *)dev->private)
+#define this_board ((const struct boardtype *)dev->board_ptr)
+
+/*
+==============================================================================
+*/
+
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan);
+static void setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan, unsigned int seglen);
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2);
+static int pci1710_reset(struct comedi_device * dev);
+static int pci171x_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static const unsigned int muxonechan[] = { 0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707, // used for gain list programming
+ 0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f,
+ 0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717,
+ 0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f
+};
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_read_ai(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, timeout;
+#ifdef PCI171x_PARANOIDCHECK
+ unsigned int idata;
+#endif
+
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_insn_read_ai(...)\n");
+ devpriv->CntrlReg &= Control_CNT0;
+ devpriv->CntrlReg |= Control_SW; // set software trigger
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+ outb(0, dev->iobase + PCI171x_CLRFIFO);
+ outb(0, dev->iobase + PCI171x_CLRINT);
+
+ setup_channel_list(dev, s, &insn->chanspec, 1, 1);
+
+ DPRINTK("adv_pci1710 A ST=%4x IO=%x\n",
+ inw(dev->iobase + PCI171x_STATUS),
+ dev->iobase + PCI171x_STATUS);
+ for (n = 0; n < insn->n; n++) {
+ outw(0, dev->iobase + PCI171x_SOFTTRG); /* start conversion */
+ DPRINTK("adv_pci1710 B n=%d ST=%4x\n", n,
+ inw(dev->iobase + PCI171x_STATUS));
+ //comedi_udelay(1);
+ DPRINTK("adv_pci1710 C n=%d ST=%4x\n", n,
+ inw(dev->iobase + PCI171x_STATUS));
+ timeout = 100;
+ while (timeout--) {
+ if (!(inw(dev->iobase + PCI171x_STATUS) & Status_FE))
+ goto conv_finish;
+ if (!(timeout % 10))
+ DPRINTK("adv_pci1710 D n=%d tm=%d ST=%4x\n", n,
+ timeout,
+ inw(dev->iobase + PCI171x_STATUS));
+ }
+ comedi_error(dev, "A/D insn timeout");
+ outb(0, dev->iobase + PCI171x_CLRFIFO);
+ outb(0, dev->iobase + PCI171x_CLRINT);
+ data[n] = 0;
+ DPRINTK("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n", n);
+ return -ETIME;
+
+ conv_finish:
+#ifdef PCI171x_PARANOIDCHECK
+ idata = inw(dev->iobase + PCI171x_AD_DATA);
+ if (this_board->cardtype != TYPE_PCI1713)
+ if ((idata & 0xf000) != devpriv->act_chanlist[0]) {
+ comedi_error(dev, "A/D insn data droput!");
+ return -ETIME;
+ }
+ data[n] = idata & 0x0fff;
+#else
+ data[n] = inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff;
+#endif
+
+ }
+
+ outb(0, dev->iobase + PCI171x_CLRFIFO);
+ outb(0, dev->iobase + PCI171x_CLRINT);
+
+ DPRINTK("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n", n);
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_write_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, chan, range, ofs;
+
+ chan = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+ if (chan) {
+ devpriv->da_ranges &= 0xfb;
+ devpriv->da_ranges |= (range << 2);
+ outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
+ ofs = PCI171x_DA2;
+ } else {
+ devpriv->da_ranges &= 0xfe;
+ devpriv->da_ranges |= range;
+ outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
+ ofs = PCI171x_DA1;
+ }
+
+ for (n = 0; n < insn->n; n++)
+ outw(data[n], dev->iobase + ofs);
+
+ devpriv->ao_data[chan] = data[n];
+
+ return n;
+
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_read_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ for (n = 0; n < insn->n; n++)
+ data[n] = devpriv->ao_data[chan];
+
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_bits_di(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[1] = inw(dev->iobase + PCI171x_DI);
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_bits_do(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ outw(s->state, dev->iobase + PCI171x_DO);
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_counter_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int msb, lsb, ccntrl;
+ int i;
+
+ ccntrl = 0xD2; /* count only */
+ for (i = 0; i < insn->n; i++) {
+ outw(ccntrl, dev->iobase + PCI171x_CNTCTRL);
+
+ lsb = inw(dev->iobase + PCI171x_CNT0) & 0xFF;
+ msb = inw(dev->iobase + PCI171x_CNT0) & 0xFF;
+
+ data[0] = lsb | (msb << 8);
+ }
+
+ return insn->n;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_counter_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ uint msb, lsb, ccntrl, status;
+
+ lsb = data[0] & 0x00FF;
+ msb = (data[0] & 0xFF00) >> 8;
+
+ /* write lsb, then msb */
+ outw(lsb, dev->iobase + PCI171x_CNT0);
+ outw(msb, dev->iobase + PCI171x_CNT0);
+
+ if (devpriv->cnt0_write_wait) {
+ /* wait for the new count to be loaded */
+ ccntrl = 0xE2;
+ do {
+ outw(ccntrl, dev->iobase + PCI171x_CNTCTRL);
+ status = inw(dev->iobase + PCI171x_CNT0) & 0xFF;
+ } while (status & 0x40);
+ }
+
+ return insn->n;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_counter_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef unused
+ /* This doesn't work like a normal Comedi counter config */
+ uint ccntrl = 0;
+
+ devpriv->cnt0_write_wait = data[0] & 0x20;
+
+ /* internal or external clock? */
+ if (!(data[0] & 0x10)) { /* internal */
+ devpriv->CntrlReg &= ~Control_CNT0;
+ } else {
+ devpriv->CntrlReg |= Control_CNT0;
+ }
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+
+ if (data[0] & 0x01)
+ ccntrl |= Counter_M0;
+ if (data[0] & 0x02)
+ ccntrl |= Counter_M1;
+ if (data[0] & 0x04)
+ ccntrl |= Counter_M2;
+ if (data[0] & 0x08)
+ ccntrl |= Counter_BCD;
+ ccntrl |= Counter_RW0; /* set read/write mode */
+ ccntrl |= Counter_RW1;
+ outw(ccntrl, dev->iobase + PCI171x_CNTCTRL);
+#endif
+
+ return 1;
+}
+
+/*
+==============================================================================
+*/
+static int pci1720_insn_write_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, rangereg, chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ rangereg = devpriv->da_ranges & (~(0x03 << (chan << 1)));
+ rangereg |= (CR_RANGE(insn->chanspec) << (chan << 1));
+ if (rangereg != devpriv->da_ranges) {
+ outb(rangereg, dev->iobase + PCI1720_RANGE);
+ devpriv->da_ranges = rangereg;
+ }
+
+ for (n = 0; n < insn->n; n++) {
+ outw(data[n], dev->iobase + PCI1720_DA0 + (chan << 1));
+ outb(0, dev->iobase + PCI1720_SYNCOUT); // update outputs
+ }
+
+ devpriv->ao_data[chan] = data[n];
+
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci1710_every_sample(void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int m;
+#ifdef PCI171x_PARANOIDCHECK
+ short sampl;
+#endif
+
+ DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_every_sample(...)\n");
+ m = inw(dev->iobase + PCI171x_STATUS);
+ if (m & Status_FE) {
+ rt_printk("comedi%d: A/D FIFO empty (%4x)\n", dev->minor, m);
+ pci171x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return;
+ }
+ if (m & Status_FF) {
+ rt_printk
+ ("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
+ dev->minor, m);
+ pci171x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return;
+ }
+
+ outb(0, dev->iobase + PCI171x_CLRINT); // clear our INT request
+
+ DPRINTK("FOR ");
+ for (; !(inw(dev->iobase + PCI171x_STATUS) & Status_FE);) {
+#ifdef PCI171x_PARANOIDCHECK
+ sampl = inw(dev->iobase + PCI171x_AD_DATA);
+ DPRINTK("%04x:", sampl);
+ if (this_board->cardtype != TYPE_PCI1713)
+ if ((sampl & 0xf000) !=
+ devpriv->act_chanlist[s->async->cur_chan]) {
+ rt_printk
+ ("comedi: A/D data dropout: received data from channel %d, expected %d!\n",
+ (sampl & 0xf000) >> 12,
+ (devpriv->act_chanlist[s->async->
+ cur_chan] & 0xf000) >>
+ 12);
+ pci171x_ai_cancel(dev, s);
+ s->async->events |=
+ COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return;
+ }
+ DPRINTK("%8d %2d %8d~", s->async->buf_int_ptr,
+ s->async->cur_chan, s->async->buf_int_count);
+ comedi_buf_put(s->async, sampl & 0x0fff);
+#else
+ comedi_buf_put(s->async,
+ inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
+#endif
+ ++s->async->cur_chan;
+
+ if (s->async->cur_chan >= devpriv->ai_n_chan) {
+ s->async->cur_chan = 0;
+ }
+
+ if (s->async->cur_chan == 0) { // one scan done
+ devpriv->ai_act_scan++;
+ DPRINTK("adv_pci1710 EDBG: EOS1 bic %d bip %d buc %d bup %d\n", s->async->buf_int_count, s->async->buf_int_ptr, s->async->buf_user_count, s->async->buf_user_ptr);
+ DPRINTK("adv_pci1710 EDBG: EOS2\n");
+ if ((!devpriv->neverending_ai) && (devpriv->ai_act_scan >= devpriv->ai_scans)) { // all data sampled
+ pci171x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return;
+ }
+ }
+ }
+
+ outb(0, dev->iobase + PCI171x_CLRINT); // clear our INT request
+ DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_every_sample(...)\n");
+
+ comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static int move_block_from_fifo(struct comedi_device * dev, struct comedi_subdevice * s,
+ int n, int turn)
+{
+ int i, j;
+#ifdef PCI171x_PARANOIDCHECK
+ int sampl;
+#endif
+ DPRINTK("adv_pci1710 EDBG: BGN: move_block_from_fifo(...,%d,%d)\n", n,
+ turn);
+ j = s->async->cur_chan;
+ for (i = 0; i < n; i++) {
+#ifdef PCI171x_PARANOIDCHECK
+ sampl = inw(dev->iobase + PCI171x_AD_DATA);
+ if (this_board->cardtype != TYPE_PCI1713)
+ if ((sampl & 0xf000) != devpriv->act_chanlist[j]) {
+ rt_printk
+ ("comedi%d: A/D FIFO data dropout: received data from channel %d, expected %d! (%d/%d/%d/%d/%d/%4x)\n",
+ dev->minor, (sampl & 0xf000) >> 12,
+ (devpriv->
+ act_chanlist[j] & 0xf000) >> 12,
+ i, j, devpriv->ai_act_scan, n, turn,
+ sampl);
+ pci171x_ai_cancel(dev, s);
+ s->async->events |=
+ COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return 1;
+ }
+ comedi_buf_put(s->async, sampl & 0x0fff);
+#else
+ comedi_buf_put(s->async,
+ inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
+#endif
+ j++;
+ if (j >= devpriv->ai_n_chan) {
+ j = 0;
+ devpriv->ai_act_scan++;
+ }
+ }
+ DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci1710_half_fifo(void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int m, samplesinbuf;
+
+ DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_half_fifo(...)\n");
+ m = inw(dev->iobase + PCI171x_STATUS);
+ if (!(m & Status_FH)) {
+ rt_printk("comedi%d: A/D FIFO not half full! (%4x)\n",
+ dev->minor, m);
+ pci171x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return;
+ }
+ if (m & Status_FF) {
+ rt_printk
+ ("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
+ dev->minor, m);
+ pci171x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return;
+ }
+
+ samplesinbuf = this_board->fifo_half_size;
+ if (samplesinbuf * sizeof(short) >= devpriv->ai_data_len) {
+ m = devpriv->ai_data_len / sizeof(short);
+ if (move_block_from_fifo(dev, s, m, 0))
+ return;
+ samplesinbuf -= m;
+ }
+
+ if (samplesinbuf) {
+ if (move_block_from_fifo(dev, s, samplesinbuf, 1))
+ return;
+ }
+
+ if (!devpriv->neverending_ai)
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
+ pci171x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return;
+ }
+ outb(0, dev->iobase + PCI171x_CLRINT); // clear our INT request
+ DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_half_fifo(...)\n");
+
+ comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_service_pci1710(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+
+ DPRINTK("adv_pci1710 EDBG: BGN: interrupt_service_pci1710(%d,...)\n",
+ irq);
+ if (!dev->attached) // is device attached?
+ return IRQ_NONE; // no, exit
+
+ if (!(inw(dev->iobase + PCI171x_STATUS) & Status_IRQ)) // is this interrupt from our board?
+ return IRQ_NONE; // no, exit
+
+ DPRINTK("adv_pci1710 EDBG: interrupt_service_pci1710() ST: %4x\n",
+ inw(dev->iobase + PCI171x_STATUS));
+
+ if (devpriv->ai_et) { // Switch from initial TRIG_EXT to TRIG_xxx.
+ devpriv->ai_et = 0;
+ devpriv->CntrlReg &= Control_CNT0;
+ devpriv->CntrlReg |= Control_SW; // set software trigger
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+ devpriv->CntrlReg = devpriv->ai_et_CntrlReg;
+ outb(0, dev->iobase + PCI171x_CLRFIFO);
+ outb(0, dev->iobase + PCI171x_CLRINT);
+ outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX);
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+ // start pacer
+ start_pacer(dev, 1, devpriv->ai_et_div1, devpriv->ai_et_div2);
+ return IRQ_HANDLED;
+ }
+ if (devpriv->ai_eos) { // We use FIFO half full INT or not?
+ interrupt_pci1710_every_sample(d);
+ } else {
+ interrupt_pci1710_half_fifo(d);
+ }
+ DPRINTK("adv_pci1710 EDBG: END: interrupt_service_pci1710(...)\n");
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ unsigned int divisor1, divisor2;
+ unsigned int seglen;
+
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_docmd_and_mode(%d,...)\n",
+ mode);
+ start_pacer(dev, -1, 0, 0); // stop pacer
+
+ seglen = check_channel_list(dev, s, devpriv->ai_chanlist,
+ devpriv->ai_n_chan);
+ if (seglen < 1)
+ return -EINVAL;
+ setup_channel_list(dev, s, devpriv->ai_chanlist,
+ devpriv->ai_n_chan, seglen);
+
+ outb(0, dev->iobase + PCI171x_CLRFIFO);
+ outb(0, dev->iobase + PCI171x_CLRINT);
+
+ devpriv->ai_do = mode;
+
+ devpriv->ai_act_scan = 0;
+ s->async->cur_chan = 0;
+ devpriv->ai_buf_ptr = 0;
+ devpriv->neverending_ai = 0;
+
+ devpriv->CntrlReg &= Control_CNT0;
+ if ((devpriv->ai_flags & TRIG_WAKE_EOS)) { // don't we want wake up every scan? devpriv->ai_eos=1;
+ devpriv->ai_eos = 1;
+ } else {
+ devpriv->CntrlReg |= Control_ONEFH;
+ devpriv->ai_eos = 0;
+ }
+
+ if ((devpriv->ai_scans == 0) || (devpriv->ai_scans == -1)) {
+ devpriv->neverending_ai = 1;
+ } //well, user want neverending
+ else {
+ devpriv->neverending_ai = 0;
+ }
+ switch (mode) {
+ case 1:
+ case 2:
+ if (devpriv->ai_timer1 < this_board->ai_ns_min)
+ devpriv->ai_timer1 = this_board->ai_ns_min;
+ devpriv->CntrlReg |= Control_PACER | Control_IRQEN;
+ if (mode == 2) {
+ devpriv->ai_et_CntrlReg = devpriv->CntrlReg;
+ devpriv->CntrlReg &=
+ ~(Control_PACER | Control_ONEFH | Control_GATE);
+ devpriv->CntrlReg |= Control_EXT;
+ devpriv->ai_et = 1;
+ } else {
+ devpriv->ai_et = 0;
+ }
+ i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
+ &divisor2, &devpriv->ai_timer1,
+ devpriv->ai_flags & TRIG_ROUND_MASK);
+ DPRINTK("adv_pci1710 EDBG: OSC base=%u div1=%u div2=%u timer=%u\n", devpriv->i8254_osc_base, divisor1, divisor2, devpriv->ai_timer1);
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+ if (mode != 2) {
+ // start pacer
+ start_pacer(dev, mode, divisor1, divisor2);
+ } else {
+ devpriv->ai_et_div1 = divisor1;
+ devpriv->ai_et_div2 = divisor2;
+ }
+ break;
+ case 3:
+ devpriv->CntrlReg |= Control_EXT | Control_IRQEN;
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+ break;
+ }
+
+ DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_docmd_and_mode(...)\n");
+ return 0;
+}
+
+#ifdef PCI171X_EXTDEBUG
+/*
+==============================================================================
+*/
+static void pci171x_cmdtest_out(int e, struct comedi_cmd * cmd)
+{
+ rt_printk("adv_pci1710 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
+ cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
+ rt_printk("adv_pci1710 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
+ cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
+ rt_printk("adv_pci1710 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
+ cmd->scan_end_src);
+ rt_printk("adv_pci1710 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n",
+ e, cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+}
+#endif
+
+/*
+==============================================================================
+*/
+static int pci171x_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp, divisor1, divisor2;
+
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...)\n");
+#ifdef PCI171X_EXTDEBUG
+ pci171x_cmdtest_out(-1, cmd);
+#endif
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err) {
+#ifdef PCI171X_EXTDEBUG
+ pci171x_cmdtest_out(1, cmd);
+#endif
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n", err);
+ return 1;
+ }
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ cmd->scan_begin_src = TRIG_FOLLOW;
+ err++;
+ }
+
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ if (err) {
+#ifdef PCI171X_EXTDEBUG
+ pci171x_cmdtest_out(2, cmd);
+#endif
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n", err);
+ return 2;
+ }
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ai_ns_min) {
+ cmd->convert_arg = this_board->ai_ns_min;
+ err++;
+ }
+ } else { /* TRIG_FOLLOW */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->chanlist_len > this_board->n_aichan) {
+ cmd->chanlist_len = this_board->n_aichan;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err) {
+#ifdef PCI171X_EXTDEBUG
+ pci171x_cmdtest_out(3, cmd);
+#endif
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n", err);
+ return 3;
+ }
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
+ &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err) {
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=4\n", err);
+ return 4;
+ }
+
+ /* step 5: complain about special chanlist considerations */
+
+ if (cmd->chanlist) {
+ if (!check_channel_list(dev, s, cmd->chanlist,
+ cmd->chanlist_len))
+ return 5; // incorrect channels list
+ }
+
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) ret=0\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmd(...)\n");
+ devpriv->ai_n_chan = cmd->chanlist_len;
+ devpriv->ai_chanlist = cmd->chanlist;
+ devpriv->ai_flags = cmd->flags;
+ devpriv->ai_data_len = s->async->prealloc_bufsz;
+ devpriv->ai_data = s->async->prealloc_buf;
+ devpriv->ai_timer1 = 0;
+ devpriv->ai_timer2 = 0;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ai_scans = cmd->stop_arg;
+ } else {
+ devpriv->ai_scans = 0;
+ }
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) { // mode 1, 2, 3
+ if (cmd->convert_src == TRIG_TIMER) { // mode 1 and 2
+ devpriv->ai_timer1 = cmd->convert_arg;
+ return pci171x_ai_docmd_and_mode(cmd->start_src ==
+ TRIG_EXT ? 2 : 1, dev, s);
+ }
+ if (cmd->convert_src == TRIG_EXT) { // mode 3
+ return pci171x_ai_docmd_and_mode(3, dev, s);
+ }
+ }
+
+ return -1;
+}
+
+/*
+==============================================================================
+ Check if channel list from user is builded correctly
+ If it's ok, then program scan/gain logic.
+ This works for all cards.
+*/
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan)
+{
+ unsigned int chansegment[32];
+ unsigned int i, nowmustbechan, seglen, segpos;
+
+ DPRINTK("adv_pci1710 EDBG: check_channel_list(...,%d)\n", n_chan);
+ /* correct channel and range number check itself comedi/range.c */
+ if (n_chan < 1) {
+ comedi_error(dev, "range/channel list is empty!");
+ return 0;
+ }
+
+ if (n_chan > 1) {
+ chansegment[0] = chanlist[0]; // first channel is everytime ok
+ for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { // build part of chanlist
+ // rt_printk("%d. %d %d\n",i,CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i]));
+ if (chanlist[0] == chanlist[i])
+ break; // we detect loop, this must by finish
+ if (CR_CHAN(chanlist[i]) & 1) // odd channel cann't by differencial
+ if (CR_AREF(chanlist[i]) == AREF_DIFF) {
+ comedi_error(dev,
+ "Odd channel can't be differential input!\n");
+ return 0;
+ }
+ nowmustbechan =
+ (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
+ if (CR_AREF(chansegment[i - 1]) == AREF_DIFF)
+ nowmustbechan = (nowmustbechan + 1) % s->n_chan;
+ if (nowmustbechan != CR_CHAN(chanlist[i])) { // channel list isn't continous :-(
+ rt_printk
+ ("channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
+ i, CR_CHAN(chanlist[i]), nowmustbechan,
+ CR_CHAN(chanlist[0]));
+ return 0;
+ }
+ chansegment[i] = chanlist[i]; // well, this is next correct channel in list
+ }
+
+ for (i = 0, segpos = 0; i < n_chan; i++) { // check whole chanlist
+ //rt_printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i]));
+ if (chanlist[i] != chansegment[i % seglen]) {
+ rt_printk
+ ("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
+ i, CR_CHAN(chansegment[i]),
+ CR_RANGE(chansegment[i]),
+ CR_AREF(chansegment[i]),
+ CR_CHAN(chanlist[i % seglen]),
+ CR_RANGE(chanlist[i % seglen]),
+ CR_AREF(chansegment[i % seglen]));
+ return 0; // chan/gain list is strange
+ }
+ }
+ } else {
+ seglen = 1;
+ }
+ return seglen;
+}
+
+static void setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan, unsigned int seglen)
+{
+ unsigned int i, range, chanprog;
+
+ DPRINTK("adv_pci1710 EDBG: setup_channel_list(...,%d,%d)\n", n_chan,
+ seglen);
+ devpriv->act_chanlist_len = seglen;
+ devpriv->act_chanlist_pos = 0;
+
+ DPRINTK("SegLen: %d\n", seglen);
+ for (i = 0; i < seglen; i++) { // store range list to card
+ chanprog = muxonechan[CR_CHAN(chanlist[i])];
+ outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */
+ range = this_board->rangecode_ai[CR_RANGE(chanlist[i])];
+ if (CR_AREF(chanlist[i]) == AREF_DIFF)
+ range |= 0x0020;
+ outw(range, dev->iobase + PCI171x_RANGE); /* select gain */
+#ifdef PCI171x_PARANOIDCHECK
+ devpriv->act_chanlist[i] =
+ (CR_CHAN(chanlist[i]) << 12) & 0xf000;
+#endif
+ DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
+ devpriv->act_chanlist[i]);
+ }
+
+ devpriv->ai_et_MuxVal =
+ CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
+ outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX); /* select channel interval to scan */
+ DPRINTK("MUX: %4x L%4x.H%4x\n",
+ CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8),
+ CR_CHAN(chanlist[0]), CR_CHAN(chanlist[seglen - 1]));
+}
+
+/*
+==============================================================================
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2)
+{
+ DPRINTK("adv_pci1710 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode,
+ divisor1, divisor2);
+ outw(0xb4, dev->iobase + PCI171x_CNTCTRL);
+ outw(0x74, dev->iobase + PCI171x_CNTCTRL);
+
+ if (mode == 1) {
+ outw(divisor2 & 0xff, dev->iobase + PCI171x_CNT2);
+ outw((divisor2 >> 8) & 0xff, dev->iobase + PCI171x_CNT2);
+ outw(divisor1 & 0xff, dev->iobase + PCI171x_CNT1);
+ outw((divisor1 >> 8) & 0xff, dev->iobase + PCI171x_CNT1);
+ }
+ DPRINTK("adv_pci1710 EDBG: END: start_pacer(...)\n");
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cancel(...)\n");
+
+ switch (this_board->cardtype) {
+ default:
+ devpriv->CntrlReg &= Control_CNT0;
+ devpriv->CntrlReg |= Control_SW;
+
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); // reset any operations
+ start_pacer(dev, -1, 0, 0);
+ outb(0, dev->iobase + PCI171x_CLRFIFO);
+ outb(0, dev->iobase + PCI171x_CLRINT);
+ break;
+ }
+
+ devpriv->ai_do = 0;
+ devpriv->ai_act_scan = 0;
+ s->async->cur_chan = 0;
+ devpriv->ai_buf_ptr = 0;
+ devpriv->neverending_ai = 0;
+
+ DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_cancel(...)\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_reset(struct comedi_device * dev)
+{
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_reset(...)\n");
+ outw(0x30, dev->iobase + PCI171x_CNTCTRL);
+ devpriv->CntrlReg = Control_SW | Control_CNT0; // Software trigger, CNT0=external
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); // reset any operations
+ outb(0, dev->iobase + PCI171x_CLRFIFO); // clear FIFO
+ outb(0, dev->iobase + PCI171x_CLRINT); // clear INT request
+ start_pacer(dev, -1, 0, 0); // stop 8254
+ devpriv->da_ranges = 0;
+ if (this_board->n_aochan) {
+ outb(devpriv->da_ranges, dev->iobase + PCI171x_DAREF); // set DACs to 0..5V
+ outw(0, dev->iobase + PCI171x_DA1); // set DA outputs to 0V
+ devpriv->ao_data[0] = 0x0000;
+ if (this_board->n_aochan > 1) {
+ outw(0, dev->iobase + PCI171x_DA2);
+ devpriv->ao_data[1] = 0x0000;
+ }
+ }
+ outw(0, dev->iobase + PCI171x_DO); // digital outputs to 0
+ outb(0, dev->iobase + PCI171x_CLRFIFO); // clear FIFO
+ outb(0, dev->iobase + PCI171x_CLRINT); // clear INT request
+
+ DPRINTK("adv_pci1710 EDBG: END: pci171x_reset(...)\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci1720_reset(struct comedi_device * dev)
+{
+ DPRINTK("adv_pci1710 EDBG: BGN: pci1720_reset(...)\n");
+ outb(Syncont_SC0, dev->iobase + PCI1720_SYNCONT); // set synchronous output mode
+ devpriv->da_ranges = 0xAA;
+ outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE); // set all ranges to +/-5V
+ outw(0x0800, dev->iobase + PCI1720_DA0); // set outputs to 0V
+ outw(0x0800, dev->iobase + PCI1720_DA1);
+ outw(0x0800, dev->iobase + PCI1720_DA2);
+ outw(0x0800, dev->iobase + PCI1720_DA3);
+ outb(0, dev->iobase + PCI1720_SYNCOUT); // update outputs
+ devpriv->ao_data[0] = 0x0800;
+ devpriv->ao_data[1] = 0x0800;
+ devpriv->ao_data[2] = 0x0800;
+ devpriv->ao_data[3] = 0x0800;
+ DPRINTK("adv_pci1710 EDBG: END: pci1720_reset(...)\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci1710_reset(struct comedi_device * dev)
+{
+ DPRINTK("adv_pci1710 EDBG: BGN: pci1710_reset(...)\n");
+ switch (this_board->cardtype) {
+ case TYPE_PCI1720:
+ return pci1720_reset(dev);
+ default:
+ return pci171x_reset(dev);
+ }
+ DPRINTK("adv_pci1710 EDBG: END: pci1710_reset(...)\n");
+}
+
+/*
+==============================================================================
+*/
+static int pci1710_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret, subdev, n_subdevices;
+ unsigned int irq;
+ unsigned long iobase;
+ struct pci_dev *pcidev;
+ int opt_bus, opt_slot;
+ const char *errstr;
+ unsigned char pci_bus, pci_slot, pci_func;
+ int i;
+ int board_index;
+
+ rt_printk("comedi%d: adv_pci1710: ", dev->minor);
+
+ opt_bus = it->options[0];
+ opt_slot = it->options[1];
+
+ if ((ret = alloc_private(dev, sizeof(struct pci1710_private))) < 0) {
+ rt_printk(" - Allocation failed!\n");
+ return -ENOMEM;
+ }
+
+ /* Look for matching PCI device */
+ errstr = "not found!";
+ pcidev = NULL;
+ board_index = this_board - boardtypes;
+ while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_ADVANTECH,
+ PCI_ANY_ID, pcidev))) {
+ if(strcmp(this_board->name, DRV_NAME) == 0)
+ {
+ for(i = 0; i < n_boardtypes; ++i)
+ {
+ if(pcidev->device == boardtypes[i].device_id)
+ {
+ board_index = i;
+ break;
+ }
+ }
+ if(i == n_boardtypes) continue;
+ }else
+ {
+ if(pcidev->device != boardtypes[board_index].device_id) continue;
+ }
+
+ /* Found matching vendor/device. */
+ if (opt_bus || opt_slot) {
+ /* Check bus/slot. */
+ if (opt_bus != pcidev->bus->number
+ || opt_slot != PCI_SLOT(pcidev->devfn))
+ continue; /* no match */
+ }
+ /*
+ * Look for device that isn't in use.
+ * Enable PCI device and request regions.
+ */
+ if (comedi_pci_enable(pcidev, DRV_NAME)) {
+ errstr = "failed to enable PCI device and request regions!";
+ continue;
+ }
+ // fixup board_ptr in case we were using the dummy entry with the driver name
+ dev->board_ptr = &boardtypes[board_index];
+ break;
+ }
+
+ if (!pcidev) {
+ if (opt_bus || opt_slot) {
+ rt_printk(" - Card at b:s %d:%d %s\n",
+ opt_bus, opt_slot, errstr);
+ } else {
+ rt_printk(" - Card %s\n", errstr);
+ }
+ return -EIO;
+ }
+
+ pci_bus = pcidev->bus->number;
+ pci_slot = PCI_SLOT(pcidev->devfn);
+ pci_func = PCI_FUNC(pcidev->devfn);
+ irq = pcidev->irq;
+ iobase = pci_resource_start(pcidev, 2);
+
+ rt_printk(", b:s:f=%d:%d:%d, io=0x%4lx", pci_bus, pci_slot, pci_func,
+ iobase);
+
+ dev->iobase = iobase;
+
+ dev->board_name = this_board->name;
+ devpriv->pcidev = pcidev;
+
+ n_subdevices = 0;
+ if (this_board->n_aichan)
+ n_subdevices++;
+ if (this_board->n_aochan)
+ n_subdevices++;
+ if (this_board->n_dichan)
+ n_subdevices++;
+ if (this_board->n_dochan)
+ n_subdevices++;
+ if (this_board->n_counter)
+ n_subdevices++;
+
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+ rt_printk(" - Allocation failed!\n");
+ return ret;
+ }
+
+ pci1710_reset(dev);
+
+ if (this_board->have_irq) {
+ if (irq) {
+ if (comedi_request_irq(irq, interrupt_service_pci1710,
+ IRQF_SHARED, "Advantech PCI-1710",
+ dev)) {
+ rt_printk
+ (", unable to allocate IRQ %d, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk(", irq=%u", irq);
+ }
+ } else {
+ rt_printk(", IRQ disabled");
+ }
+ } else {
+ irq = 0;
+ }
+
+ dev->irq = irq;
+
+ printk(".\n");
+
+ subdev = 0;
+
+ if (this_board->n_aichan) {
+ s = dev->subdevices + subdev;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
+ if (this_board->n_aichand)
+ s->subdev_flags |= SDF_DIFF;
+ s->n_chan = this_board->n_aichan;
+ s->maxdata = this_board->ai_maxdata;
+ s->len_chanlist = this_board->n_aichan;
+ s->range_table = this_board->rangelist_ai;
+ s->cancel = pci171x_ai_cancel;
+ s->insn_read = pci171x_insn_read_ai;
+ if (irq) {
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmdtest = pci171x_ai_cmdtest;
+ s->do_cmd = pci171x_ai_cmd;
+ }
+ devpriv->i8254_osc_base = 100; // 100ns=10MHz
+ subdev++;
+ }
+
+ if (this_board->n_aochan) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = this_board->ao_maxdata;
+ s->len_chanlist = this_board->n_aochan;
+ s->range_table = this_board->rangelist_ao;
+ switch (this_board->cardtype) {
+ case TYPE_PCI1720:
+ s->insn_write = pci1720_insn_write_ao;
+ break;
+ default:
+ s->insn_write = pci171x_insn_write_ao;
+ break;
+ }
+ s->insn_read = pci171x_insn_read_ao;
+ subdev++;
+ }
+
+ if (this_board->n_dichan) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->n_dichan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dichan;
+ s->range_table = &range_digital;
+ s->io_bits = 0; /* all bits input */
+ s->insn_bits = pci171x_insn_bits_di;
+ subdev++;
+ }
+
+ if (this_board->n_dochan) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->n_dochan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dochan;
+ s->range_table = &range_digital;
+ s->io_bits = (1 << this_board->n_dochan) - 1; /* all bits output */
+ s->state = 0;
+ s->insn_bits = pci171x_insn_bits_do;
+ subdev++;
+ }
+
+ if (this_board->n_counter) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = this_board->n_counter;
+ s->len_chanlist = this_board->n_counter;
+ s->maxdata = 0xffff;
+ s->range_table = &range_unknown;
+ s->insn_read = pci171x_insn_counter_read;
+ s->insn_write = pci171x_insn_counter_write;
+ s->insn_config = pci171x_insn_counter_config;
+ subdev++;
+ }
+
+ devpriv->valid = 1;
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci1710_detach(struct comedi_device * dev)
+{
+
+ if (dev->private) {
+ if (devpriv->valid)
+ pci1710_reset(dev);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (devpriv->pcidev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pcidev);
+ }
+ pci_dev_put(devpriv->pcidev);
+ }
+ }
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+COMEDI_PCI_INITCLEANUP(driver_pci1710, pci1710_pci_table);
+/*
+==============================================================================
+*/
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c
new file mode 100644
index 00000000000..81f7ee18c15
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adv_pci1723.c
@@ -0,0 +1,465 @@
+/*******************************************************************************
+ comedi/drivers/pci1723.c
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*******************************************************************************/
+/*
+Driver: adv_pci1723
+Description: Advantech PCI-1723
+Author: yonggang <rsmgnu@gmail.com>, Ian Abbott <abbotti@mev.co.uk>
+Devices: [Advantech] PCI-1723 (adv_pci1723)
+Updated: Mon, 14 Apr 2008 15:12:56 +0100
+Status: works
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+
+Subdevice 0 is 8-channel AO, 16-bit, range +/- 10 V.
+
+Subdevice 1 is 16-channel DIO. The channels are configurable as input or
+output in 2 groups (0 to 7, 8 to 15). Configuring any channel implicitly
+configures all channels in the same group.
+
+TODO:
+
+1. Add the two milliamp ranges to the AO subdevice (0 to 20 mA, 4 to 20 mA).
+2. Read the initial ranges and values of the AO subdevice at start-up instead
+ of reinitializing them.
+3. Implement calibration.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#define ADVANTECH_VENDOR 0x13fe /* Advantech PCI vendor ID */
+
+// hardware types of the cards
+#define TYPE_PCI1723 0
+
+#define IORANGE_1723 0x2A
+
+/* all the registers for the pci1723 board */
+#define PCI1723_DA(N) ((N)<<1) /* W: D/A register N (0 to 7) */
+
+#define PCI1723_SYN_SET 0x12 /*synchronized set register */
+#define PCI1723_ALL_CHNNELE_SYN_STROBE 0x12 /*synchronized status register */
+
+#define PCI1723_RANGE_CALIBRATION_MODE 0x14 /* range and calibration mode */
+#define PCI1723_RANGE_CALIBRATION_STATUS 0x14 /* range and calibration status */
+
+#define PCI1723_CONTROL_CMD_CALIBRATION_FUN 0x16 /* SADC control command for calibration function */
+#define PCI1723_STATUS_CMD_CALIBRATION_FUN 0x16 /* SADC control status for calibration function */
+
+#define PCI1723_CALIBRATION_PARA_STROBE 0x18 /* Calibration parameter strobe */
+
+#define PCI1723_DIGITAL_IO_PORT_SET 0x1A /* Digital I/O port setting */
+#define PCI1723_DIGITAL_IO_PORT_MODE 0x1A /* Digital I/O port mode */
+
+#define PCI1723_WRITE_DIGITAL_OUTPUT_CMD 0x1C /* Write digital output command */
+#define PCI1723_READ_DIGITAL_INPUT_DATA 0x1C /* Read digital input data */
+
+#define PCI1723_WRITE_CAL_CMD 0x1E /* Write calibration command */
+#define PCI1723_READ_CAL_STATUS 0x1E /* Read calibration status */
+
+#define PCI1723_SYN_STROBE 0x20 /* Synchronized strobe */
+
+#define PCI1723_RESET_ALL_CHN_STROBE 0x22 /* Reset all D/A channels strobe */
+
+#define PCI1723_RESET_CAL_CONTROL_STROBE 0x24 /* Reset the calibration controller strobe */
+
+#define PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE 0x26 /* Change D/A channels output type strobe */
+
+#define PCI1723_SELECT_CALIBRATION 0x28 /* Select the calibration Ref_V */
+
+//static unsigned short pci_list_builded=0; /*=1 list of card is know */
+
+static const struct comedi_lrange range_pci1723 = { 1, {
+ BIP_RANGE(10)
+ }
+};
+
+/*
+ * Board descriptions for pci1723 boards.
+ */
+struct pci1723_board {
+ const char *name;
+ int vendor_id; // PCI vendor a device ID of card
+ int device_id;
+ int iorange;
+ char cardtype;
+ int n_aochan; // num of D/A chans
+ int n_diochan; // num of DIO chans
+ int ao_maxdata; // resolution of D/A
+ const struct comedi_lrange *rangelist_ao; // rangelist for D/A
+};
+
+static const struct pci1723_board boardtypes[] = {
+ {
+ name: "pci1723",
+ vendor_id:ADVANTECH_VENDOR,
+ device_id:0x1723,
+ iorange: IORANGE_1723,
+ cardtype:TYPE_PCI1723,
+ n_aochan:8,
+ n_diochan:16,
+ ao_maxdata:0xffff,
+ rangelist_ao:&range_pci1723,
+ },
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers. Should
+ * only be used for PCI and ISA-PnP devices */
+static DEFINE_PCI_DEVICE_TABLE(pci1723_pci_table) = {
+ {PCI_VENDOR_ID_ADVANTECH, 0x1723, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci1723_pci_table);
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pci1723_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci1723_detach(struct comedi_device * dev);
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pci1723_board))
+
+static struct comedi_driver driver_pci1723 = {
+ driver_name:"adv_pci1723",
+ module:THIS_MODULE,
+ attach:pci1723_attach,
+ detach:pci1723_detach,
+};
+
+/* this structure is for data unique to this hardware driver. */
+struct pci1723_private {
+ int valid; //card is usable;
+
+ struct pci_dev *pcidev;
+ unsigned char da_range[8]; // D/A output range for each channel
+
+ short ao_data[8]; // data output buffer
+};
+
+/*the following macro to make it easy to
+* access the private structure.
+*/
+#define devpriv ((struct pci1723_private *)dev->private)
+
+#define this_board boardtypes
+
+/*
+ * the pci1723 card reset;
+ */
+static int pci1723_reset(struct comedi_device * dev)
+{
+ int i;
+ DPRINTK("adv_pci1723 EDBG: BGN: pci1723_reset(...)\n");
+
+ outw(0x01, dev->iobase + PCI1723_SYN_SET); // set synchronous output mode
+
+ for (i = 0; i < 8; i++) {
+ // set all outputs to 0V
+ devpriv->ao_data[i] = 0x8000;
+ outw(devpriv->ao_data[i], dev->iobase + PCI1723_DA(i));
+ // set all ranges to +/- 10V
+ devpriv->da_range[i] = 0;
+ outw(((devpriv->da_range[i] << 4) | i),
+ PCI1723_RANGE_CALIBRATION_MODE);
+ }
+
+ outw(0, dev->iobase + PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE); // update ranges
+ outw(0, dev->iobase + PCI1723_SYN_STROBE); // update outputs
+
+ // set asynchronous output mode
+ outw(0, dev->iobase + PCI1723_SYN_SET);
+
+ DPRINTK("adv_pci1723 EDBG: END: pci1723_reset(...)\n");
+ return 0;
+}
+
+static int pci1723_insn_read_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ DPRINTK(" adv_PCI1723 DEBUG: pci1723_insn_read_ao() ----- \n");
+ for (n = 0; n < insn->n; n++)
+ data[n] = devpriv->ao_data[chan];
+
+ return n;
+}
+
+/*
+ analog data output;
+*/
+static int pci1723_ao_write_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, chan;
+ chan = CR_CHAN(insn->chanspec);
+
+ DPRINTK("PCI1723: the pci1723_ao_write_winsn() ------\n");
+
+ for (n = 0; n < insn->n; n++) {
+
+ devpriv->ao_data[chan] = data[n];
+ outw(data[n], dev->iobase + PCI1723_DA(chan));
+ }
+
+ return n;
+}
+
+/*
+ digital i/o config/query
+*/
+static int pci1723_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int mask;
+ unsigned int bits;
+ unsigned short dio_mode;
+
+ mask = 1 << CR_CHAN(insn->chanspec);
+ if (mask & 0x00FF) {
+ bits = 0x00FF;
+ } else {
+ bits = 0xFF00;
+ }
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~bits;
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= bits;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ default:
+ return -EINVAL;
+ }
+
+ // update hardware DIO mode
+ dio_mode = 0x0000; // low byte output, high byte output
+ if ((s->io_bits & 0x00FF) == 0)
+ dio_mode |= 0x0001; // low byte input
+ if ((s->io_bits & 0xFF00) == 0)
+ dio_mode |= 0x0002; // high byte input
+ outw(dio_mode, dev->iobase + PCI1723_DIGITAL_IO_PORT_SET);
+ return 1;
+}
+
+/*
+ digital i/o bits read/write
+*/
+static int pci1723_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ outw(s->state, dev->iobase + PCI1723_WRITE_DIGITAL_OUTPUT_CMD);
+ }
+ data[1] = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA);
+ return 2;
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a pci1723 board.
+ */
+static int pci1723_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret, subdev, n_subdevices;
+ struct pci_dev *pcidev;
+ unsigned int iobase;
+ unsigned char pci_bus, pci_slot, pci_func;
+ int opt_bus, opt_slot;
+ const char *errstr;
+
+ rt_printk("comedi%d: adv_pci1723: board=%s", dev->minor,
+ this_board->name);
+
+ opt_bus = it->options[0];
+ opt_slot = it->options[1];
+
+ if ((ret = alloc_private(dev, sizeof(struct pci1723_private))) < 0) {
+ rt_printk(" - Allocation failed!\n");
+ return -ENOMEM;
+ }
+
+ /* Look for matching PCI device */
+ errstr = "not found!";
+ pcidev = NULL;
+ while (NULL != (pcidev =
+ pci_get_device(PCI_VENDOR_ID_ADVANTECH,
+ this_board->device_id, pcidev))) {
+ /* Found matching vendor/device. */
+ if (opt_bus || opt_slot) {
+ /* Check bus/slot. */
+ if (opt_bus != pcidev->bus->number
+ || opt_slot != PCI_SLOT(pcidev->devfn))
+ continue; /* no match */
+ }
+ /*
+ * Look for device that isn't in use.
+ * Enable PCI device and request regions.
+ */
+ if (comedi_pci_enable(pcidev, "adv_pci1723")) {
+ errstr = "failed to enable PCI device and request regions!";
+ continue;
+ }
+ break;
+ }
+
+ if (!pcidev) {
+ if (opt_bus || opt_slot) {
+ rt_printk(" - Card at b:s %d:%d %s\n",
+ opt_bus, opt_slot, errstr);
+ } else {
+ rt_printk(" - Card %s\n", errstr);
+ }
+ return -EIO;
+ }
+
+ pci_bus = pcidev->bus->number;
+ pci_slot = PCI_SLOT(pcidev->devfn);
+ pci_func = PCI_FUNC(pcidev->devfn);
+ iobase = pci_resource_start(pcidev, 2);
+
+ rt_printk(", b:s:f=%d:%d:%d, io=0x%4x", pci_bus, pci_slot, pci_func,
+ iobase);
+
+ dev->iobase = iobase;
+
+ dev->board_name = this_board->name;
+ devpriv->pcidev = pcidev;
+
+ n_subdevices = 0;
+
+ if (this_board->n_aochan)
+ n_subdevices++;
+ if (this_board->n_diochan)
+ n_subdevices++;
+
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+ rt_printk(" - Allocation failed!\n");
+ return ret;
+ }
+
+ pci1723_reset(dev);
+ subdev = 0;
+ if (this_board->n_aochan) {
+ s = dev->subdevices + subdev;
+ dev->write_subdev = s;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = this_board->ao_maxdata;
+ s->len_chanlist = this_board->n_aochan;
+ s->range_table = this_board->rangelist_ao;
+
+ s->insn_write = pci1723_ao_write_winsn;
+ s->insn_read = pci1723_insn_read_ao;
+
+ // read DIO config
+ switch (inw(dev->iobase + PCI1723_DIGITAL_IO_PORT_MODE) & 0x03) {
+ case 0x00: // low byte output, high byte output
+ s->io_bits = 0xFFFF;
+ break;
+ case 0x01: // low byte input, high byte output
+ s->io_bits = 0xFF00;
+ break;
+ case 0x02: // low byte output, high byte input
+ s->io_bits = 0x00FF;
+ break;
+ case 0x03: // low byte input, high byte input
+ s->io_bits = 0x0000;
+ break;
+ }
+ // read DIO port state
+ s->state = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA);
+
+ subdev++;
+ }
+
+ if (this_board->n_diochan) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->n_diochan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_diochan;
+ s->range_table = &range_digital;
+ s->insn_config = pci1723_dio_insn_config;
+ s->insn_bits = pci1723_dio_insn_bits;
+ subdev++;
+ }
+
+ devpriv->valid = 1;
+
+ pci1723_reset(dev);
+
+ return 0;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pci1723_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pci1723: remove\n", dev->minor);
+
+ if (dev->private) {
+ if (devpriv->valid)
+ pci1723_reset(dev);
+
+ if (devpriv->pcidev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pcidev);
+ }
+ pci_dev_put(devpriv->pcidev);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_pci1723, pci1723_pci_table);
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
new file mode 100644
index 00000000000..2604425c3a0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -0,0 +1,1077 @@
+/*
+ * comedi/drivers/adv_pci_dio.c
+ *
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ *
+ * Hardware driver for Advantech PCI DIO cards.
+*/
+/*
+Driver: adv_pci_dio
+Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1736UP,
+ PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754,
+ PCI-1756, PCI-1762
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
+ PCI-1734, PCI-1736UP, PCI-1750,
+ PCI-1751, PCI-1752, PCI-1753,
+ PCI-1753+PCI-1753E, PCI-1754, PCI-1756,
+ PCI-1760, PCI-1762
+Status: untested
+Updated: Mon, 14 Apr 2008 10:43:08 +0100
+
+This driver supports now only insn interface for DI/DO/DIO.
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI
+ device will be used.
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "8255.h"
+
+#undef PCI_DIO_EXTDEBUG /* if defined, enable extensive debug logging */
+
+#undef DPRINTK
+#ifdef PCI_DIO_EXTDEBUG
+#define DPRINTK(fmt, args...) rt_printk(fmt, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+/* hardware types of the cards */
+enum hw_cards_id {
+ TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1736,
+ TYPE_PCI1750,
+ TYPE_PCI1751,
+ TYPE_PCI1752,
+ TYPE_PCI1753, TYPE_PCI1753E,
+ TYPE_PCI1754, TYPE_PCI1756,
+ TYPE_PCI1760,
+ TYPE_PCI1762
+};
+
+/* which I/O instructions to use */
+enum hw_io_access {
+ IO_8b, IO_16b
+};
+
+#define MAX_DI_SUBDEVS 2 /* max number of DI subdevices per card */
+#define MAX_DO_SUBDEVS 2 /* max number of DO subdevices per card */
+#define MAX_DIO_SUBDEVG 2 /* max number of DIO subdevices group per card */
+
+#define SIZE_8255 4 /* 8255 IO space length */
+
+#define PCIDIO_MAINREG 2 /* main I/O region for all Advantech cards? */
+
+/* Register offset definitions */
+/* Advantech PCI-1730/3/4 */
+#define PCI1730_IDI 0 /* R: Isolated digital input 0-15 */
+#define PCI1730_IDO 0 /* W: Isolated digital output 0-15 */
+#define PCI1730_DI 2 /* R: Digital input 0-15 */
+#define PCI1730_DO 2 /* W: Digital output 0-15 */
+#define PCI1733_IDI 0 /* R: Isolated digital input 0-31 */
+#define PCI1730_3_INT_EN 0x08 /* R/W: enable/disable interrupts */
+#define PCI1730_3_INT_RF 0x0c /* R/W: set falling/raising edge for interrupts */
+#define PCI1730_3_INT_CLR 0x10 /* R/W: clear interrupts */
+#define PCI1734_IDO 0 /* W: Isolated digital output 0-31 */
+#define PCI173x_BOARDID 4 /* R: Board I/D switch for 1730/3/4 */
+
+/* Advantech PCI-1736UP */
+#define PCI1736_IDI 0 /* R: Isolated digital input 0-15 */
+#define PCI1736_IDO 0 /* W: Isolated digital output 0-15 */
+#define PCI1736_3_INT_EN 0x08 /* R/W: enable/disable interrupts */
+#define PCI1736_3_INT_RF 0x0c /* R/W: set falling/raising edge for interrupts */
+#define PCI1736_3_INT_CLR 0x10 /* R/W: clear interrupts */
+#define PCI1736_BOARDID 4 /* R: Board I/D switch for 1736UP */
+#define PCI1736_MAINREG 0 /* Normal register (2) doesn't work */
+
+/* Advantech PCI-1750 */
+#define PCI1750_IDI 0 /* R: Isolated digital input 0-15 */
+#define PCI1750_IDO 0 /* W: Isolated digital output 0-15 */
+#define PCI1750_ICR 32 /* W: Interrupt control register */
+#define PCI1750_ISR 32 /* R: Interrupt status register */
+
+/* Advantech PCI-1751/3/3E */
+#define PCI1751_DIO 0 /* R/W: begin of 8255 registers block */
+#define PCI1751_ICR 32 /* W: Interrupt control register */
+#define PCI1751_ISR 32 /* R: Interrupt status register */
+#define PCI1753_DIO 0 /* R/W: begin of 8255 registers block */
+#define PCI1753_ICR0 16 /* R/W: Interrupt control register group 0 */
+#define PCI1753_ICR1 17 /* R/W: Interrupt control register group 1 */
+#define PCI1753_ICR2 18 /* R/W: Interrupt control register group 2 */
+#define PCI1753_ICR3 19 /* R/W: Interrupt control register group 3 */
+#define PCI1753E_DIO 32 /* R/W: begin of 8255 registers block */
+#define PCI1753E_ICR0 48 /* R/W: Interrupt control register group 0 */
+#define PCI1753E_ICR1 49 /* R/W: Interrupt control register group 1 */
+#define PCI1753E_ICR2 50 /* R/W: Interrupt control register group 2 */
+#define PCI1753E_ICR3 51 /* R/W: Interrupt control register group 3 */
+
+/* Advantech PCI-1752/4/6 */
+#define PCI1752_IDO 0 /* R/W: Digital output 0-31 */
+#define PCI1752_IDO2 4 /* R/W: Digital output 32-63 */
+#define PCI1754_IDI 0 /* R: Digital input 0-31 */
+#define PCI1754_IDI2 4 /* R: Digital input 32-64 */
+#define PCI1756_IDI 0 /* R: Digital input 0-31 */
+#define PCI1756_IDO 4 /* R/W: Digital output 0-31 */
+#define PCI1754_6_ICR0 0x08 /* R/W: Interrupt control register group 0 */
+#define PCI1754_6_ICR1 0x0a /* R/W: Interrupt control register group 1 */
+#define PCI1754_ICR2 0x0c /* R/W: Interrupt control register group 2 */
+#define PCI1754_ICR3 0x0e /* R/W: Interrupt control register group 3 */
+#define PCI1752_6_CFC 0x12 /* R/W: set/read channel freeze function */
+#define PCI175x_BOARDID 0x10 /* R: Board I/D switch for 1752/4/6 */
+
+/* Advantech PCI-1762 registers */
+#define PCI1762_RO 0 /* R/W: Relays status/output */
+#define PCI1762_IDI 2 /* R: Isolated input status */
+#define PCI1762_BOARDID 4 /* R: Board I/D switch */
+#define PCI1762_ICR 6 /* W: Interrupt control register */
+#define PCI1762_ISR 6 /* R: Interrupt status register */
+
+/* Advantech PCI-1760 registers */
+#define OMB0 0x0c /* W: Mailbox outgoing registers */
+#define OMB1 0x0d
+#define OMB2 0x0e
+#define OMB3 0x0f
+#define IMB0 0x1c /* R: Mailbox incoming registers */
+#define IMB1 0x1d
+#define IMB2 0x1e
+#define IMB3 0x1f
+#define INTCSR0 0x38 /* R/W: Interrupt control registers */
+#define INTCSR1 0x39
+#define INTCSR2 0x3a
+#define INTCSR3 0x3b
+
+/* PCI-1760 mailbox commands */
+#define CMD_ClearIMB2 0x00 /* Clear IMB2 status and return actaul DI status in IMB3 */
+#define CMD_SetRelaysOutput 0x01 /* Set relay output from OMB0 */
+#define CMD_GetRelaysStatus 0x02 /* Get relay status to IMB0 */
+#define CMD_ReadCurrentStatus 0x07 /* Read the current status of the register in OMB0, result in IMB0 */
+#define CMD_ReadFirmwareVersion 0x0e /* Read the firmware ver., result in IMB1.IMB0 */
+#define CMD_ReadHardwareVersion 0x0f /* Read the hardware ver., result in IMB1.IMB0 */
+#define CMD_EnableIDIFilters 0x20 /* Enable IDI filters based on bits in OMB0 */
+#define CMD_EnableIDIPatternMatch 0x21 /* Enable IDI pattern match based on bits in OMB0 */
+#define CMD_SetIDIPatternMatch 0x22 /* Enable IDI pattern match based on bits in OMB0 */
+#define CMD_EnableIDICounters 0x28 /* Enable IDI counters based on bits in OMB0 */
+#define CMD_ResetIDICounters 0x29 /* Reset IDI counters based on bits in OMB0 to its reset values */
+#define CMD_OverflowIDICounters 0x2a /* Enable IDI counters overflow interrupts based on bits in OMB0 */
+#define CMD_MatchIntIDICounters 0x2b /* Enable IDI counters match value interrupts based on bits in OMB0 */
+#define CMD_EdgeIDICounters 0x2c /* Set IDI up counters count edge (bit=0 - rising, =1 - falling) */
+#define CMD_GetIDICntCurValue 0x2f /* Read IDI{OMB0} up counter current value */
+#define CMD_SetIDI0CntResetValue 0x40 /* Set IDI0 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI1CntResetValue 0x41 /* Set IDI1 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI2CntResetValue 0x42 /* Set IDI2 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI3CntResetValue 0x43 /* Set IDI3 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI4CntResetValue 0x44 /* Set IDI4 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI5CntResetValue 0x45 /* Set IDI5 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI6CntResetValue 0x46 /* Set IDI6 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI7CntResetValue 0x47 /* Set IDI7 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI0CntMatchValue 0x48 /* Set IDI0 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI1CntMatchValue 0x49 /* Set IDI1 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI2CntMatchValue 0x4a /* Set IDI2 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI3CntMatchValue 0x4b /* Set IDI3 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI4CntMatchValue 0x4c /* Set IDI4 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI5CntMatchValue 0x4d /* Set IDI5 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI6CntMatchValue 0x4e /* Set IDI6 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI7CntMatchValue 0x4f /* Set IDI7 Counter Match Value 256*OMB1+OMB0 */
+
+#define OMBCMD_RETRY 0x03 /* 3 times try request before error */
+
+static int pci_dio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci_dio_detach(struct comedi_device * dev);
+
+struct diosubd_data {
+ int chans; /* num of chans */
+ int addr; /* PCI address ofset */
+ int regs; /* number of registers to read or 8255 subdevices */
+ unsigned int specflags; /* addon subdevice flags */
+};
+
+struct dio_boardtype {
+ const char *name; /* board name */
+ int vendor_id; /* vendor/device PCI ID */
+ int device_id;
+ int main_pci_region; /* main I/O PCI region */
+ enum hw_cards_id cardtype;
+ struct diosubd_data sdi[MAX_DI_SUBDEVS]; /* DI chans */
+ struct diosubd_data sdo[MAX_DO_SUBDEVS]; /* DO chans */
+ struct diosubd_data sdio[MAX_DIO_SUBDEVG]; /* DIO 8255 chans */
+ struct diosubd_data boardid; /* card supports board ID switch */
+ enum hw_io_access io_access;
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci_dio_pci_table) = {
+ {PCI_VENDOR_ID_ADVANTECH, 0x1730, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1733, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1734, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1752, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1753, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1754, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1756, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1762, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci_dio_pci_table);
+
+static const struct dio_boardtype boardtypes[] = {
+ {"pci1730", PCI_VENDOR_ID_ADVANTECH, 0x1730, PCIDIO_MAINREG,
+ TYPE_PCI1730,
+ {{16, PCI1730_DI, 2, 0}, {16, PCI1730_IDI, 2, 0}},
+ {{16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
+ IO_8b,
+ },
+ {"pci1733", PCI_VENDOR_ID_ADVANTECH, 0x1733, PCIDIO_MAINREG,
+ TYPE_PCI1733,
+ {{0, 0, 0, 0}, {32, PCI1733_IDI, 4, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
+ IO_8b},
+ {"pci1734", PCI_VENDOR_ID_ADVANTECH, 0x1734, PCIDIO_MAINREG,
+ TYPE_PCI1734,
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {32, PCI1734_IDO, 4, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
+ IO_8b},
+ {"pci1736", PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI1736_MAINREG,
+ TYPE_PCI1736,
+ {{0, 0, 0, 0}, {16, PCI1736_IDI, 2, 0}},
+ {{0, 0, 0, 0}, {16, PCI1736_IDO, 2, 0}},
+ {{ 0, 0, 0, 0}, { 0, 0, 0, 0}},
+ { 4, PCI1736_BOARDID, 1, SDF_INTERNAL},
+ IO_8b,
+ },
+ {"pci1750", PCI_VENDOR_ID_ADVANTECH, 0x1750, PCIDIO_MAINREG,
+ TYPE_PCI1750,
+ {{0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0}},
+ {{0, 0, 0, 0}, {16, PCI1750_IDO, 2, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {0, 0, 0, 0},
+ IO_8b},
+ {"pci1751", PCI_VENDOR_ID_ADVANTECH, 0x1751, PCIDIO_MAINREG,
+ TYPE_PCI1751,
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0}},
+ {0, 0, 0, 0},
+ IO_8b},
+ {"pci1752", PCI_VENDOR_ID_ADVANTECH, 0x1752, PCIDIO_MAINREG,
+ TYPE_PCI1752,
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{32, PCI1752_IDO, 2, 0}, {32, PCI1752_IDO2, 2, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
+ IO_16b},
+ {"pci1753", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
+ TYPE_PCI1753,
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{96, PCI1753_DIO, 4, 0}, {0, 0, 0, 0}},
+ {0, 0, 0, 0},
+ IO_8b},
+ {"pci1753e", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
+ TYPE_PCI1753E,
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{96, PCI1753_DIO, 4, 0}, {96, PCI1753E_DIO, 4, 0}},
+ {0, 0, 0, 0},
+ IO_8b},
+ {"pci1754", PCI_VENDOR_ID_ADVANTECH, 0x1754, PCIDIO_MAINREG,
+ TYPE_PCI1754,
+ {{32, PCI1754_IDI, 2, 0}, {32, PCI1754_IDI2, 2, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
+ IO_16b},
+ {"pci1756", PCI_VENDOR_ID_ADVANTECH, 0x1756, PCIDIO_MAINREG,
+ TYPE_PCI1756,
+ {{0, 0, 0, 0}, {32, PCI1756_IDI, 2, 0}},
+ {{0, 0, 0, 0}, {32, PCI1756_IDO, 2, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
+ IO_16b},
+ {"pci1760", PCI_VENDOR_ID_ADVANTECH, 0x1760, 0,
+ TYPE_PCI1760,
+ {{0, 0, 0, 0}, {0, 0, 0, 0}}, /* This card have own setup work */
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {0, 0, 0, 0},
+ IO_8b},
+ {"pci1762", PCI_VENDOR_ID_ADVANTECH, 0x1762, PCIDIO_MAINREG,
+ TYPE_PCI1762,
+ {{0, 0, 0, 0}, {16, PCI1762_IDI, 1, 0}},
+ {{0, 0, 0, 0}, {16, PCI1762_RO, 1, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI1762_BOARDID, 1, SDF_INTERNAL},
+ IO_16b}
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct dio_boardtype))
+
+static struct comedi_driver driver_pci_dio = {
+ driver_name:"adv_pci_dio",
+ module:THIS_MODULE,
+ attach:pci_dio_attach,
+ detach:pci_dio_detach
+};
+
+struct pci_dio_private {
+ struct pci_dio_private *prev; /* previous private struct */
+ struct pci_dio_private *next; /* next private struct */
+ struct pci_dev *pcidev; /* pointer to board's pci_dev */
+ char valid; /* card is usable */
+ char GlobalIrqEnabled; /* 1= any IRQ source is enabled */
+ /* PCI-1760 specific data */
+ unsigned char IDICntEnable; /* counter's counting enable status */
+ unsigned char IDICntOverEnable; /* counter's overflow interrupts enable status */
+ unsigned char IDICntMatchEnable; /* counter's match interrupts enable status */
+ unsigned char IDICntEdge; /* counter's count edge value (bit=0 - rising, =1 - falling) */
+ unsigned short CntResValue[8]; /* counters' reset value */
+ unsigned short CntMatchValue[8]; /* counters' match interrupt value */
+ unsigned char IDIFiltersEn; /* IDI's digital filters enable status */
+ unsigned char IDIPatMatchEn; /* IDI's pattern match enable status */
+ unsigned char IDIPatMatchValue; /* IDI's pattern match value */
+ unsigned short IDIFiltrLow[8]; /* IDI's filter value low signal */
+ unsigned short IDIFiltrHigh[8]; /* IDI's filter value high signal */
+};
+
+static struct pci_dio_private *pci_priv = NULL; /* list of allocated cards */
+
+#define devpriv ((struct pci_dio_private *)dev->private)
+#define this_board ((const struct dio_boardtype *)dev->board_ptr)
+
+/*
+==============================================================================
+*/
+static int pci_dio_insn_bits_di_b(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ const struct diosubd_data *d = (const struct diosubd_data *)s->private;
+ int i;
+
+ data[1] = 0;
+ for (i = 0; i < d->regs; i++) {
+ data[1] |= inb(dev->iobase + d->addr + i) << (8 * i);
+ }
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_insn_bits_di_w(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ const struct diosubd_data *d = (const struct diosubd_data *)s->private;
+ int i;
+
+ data[1] = 0;
+ for (i = 0; i < d->regs; i++)
+ data[1] |= inw(dev->iobase + d->addr + 2 * i) << (16 * i);
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_insn_bits_do_b(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ const struct diosubd_data *d = (const struct diosubd_data *)s->private;
+ int i;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ for (i = 0; i < d->regs; i++)
+ outb((s->state >> (8 * i)) & 0xff,
+ dev->iobase + d->addr + i);
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_insn_bits_do_w(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ const struct diosubd_data *d = (const struct diosubd_data *)s->private;
+ int i;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ for (i = 0; i < d->regs; i++)
+ outw((s->state >> (16 * i)) & 0xffff,
+ dev->iobase + d->addr + 2 * i);
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_unchecked_mbxrequest(struct comedi_device * dev,
+ unsigned char *omb, unsigned char *imb, int repeats)
+{
+ int cnt, tout, ok = 0;
+
+ for (cnt = 0; cnt < repeats; cnt++) {
+ outb(omb[0], dev->iobase + OMB0);
+ outb(omb[1], dev->iobase + OMB1);
+ outb(omb[2], dev->iobase + OMB2);
+ outb(omb[3], dev->iobase + OMB3);
+ for (tout = 0; tout < 251; tout++) {
+ if ((imb[2] = inb(dev->iobase + IMB2)) == omb[2]) {
+ imb[0] = inb(dev->iobase + IMB0);
+ imb[1] = inb(dev->iobase + IMB1);
+ imb[3] = inb(dev->iobase + IMB3);
+ ok = 1;
+ break;
+ }
+ comedi_udelay(1);
+ }
+ if (ok)
+ return 0;
+ }
+
+ comedi_error(dev, "PCI-1760 mailbox request timeout!");
+ return -ETIME;
+}
+
+static int pci1760_clear_imb2(struct comedi_device * dev)
+{
+ unsigned char omb[4] = { 0x0, 0x0, CMD_ClearIMB2, 0x0 };
+ unsigned char imb[4];
+ /* check if imb2 is already clear */
+ if (inb(dev->iobase + IMB2) == CMD_ClearIMB2)
+ return 0;
+ return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY);
+}
+
+static int pci1760_mbxrequest(struct comedi_device * dev,
+ unsigned char *omb, unsigned char *imb)
+{
+ if (omb[2] == CMD_ClearIMB2) {
+ comedi_error(dev,
+ "bug! this function should not be used for CMD_ClearIMB2 command");
+ return -EINVAL;
+ }
+ if (inb(dev->iobase + IMB2) == omb[2]) {
+ int retval;
+ retval = pci1760_clear_imb2(dev);
+ if (retval < 0)
+ return retval;
+ }
+ return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY);
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_insn_bits_di(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[1] = inb(dev->iobase + IMB3);
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_insn_bits_do(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int ret;
+ unsigned char omb[4] = {
+ 0x00,
+ 0x00,
+ CMD_SetRelaysOutput,
+ 0x00
+ };
+ unsigned char imb[4];
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ omb[0] = s->state;
+ if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+ return ret;
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_insn_cnt_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int ret, n;
+ unsigned char omb[4] = {
+ CR_CHAN(insn->chanspec) & 0x07,
+ 0x00,
+ CMD_GetIDICntCurValue,
+ 0x00
+ };
+ unsigned char imb[4];
+
+ for (n = 0; n < insn->n; n++) {
+ if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+ return ret;
+ data[n] = (imb[1] << 8) + imb[0];
+ }
+
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_insn_cnt_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int ret;
+ unsigned char chan = CR_CHAN(insn->chanspec) & 0x07;
+ unsigned char bitmask = 1 << chan;
+ unsigned char omb[4] = {
+ data[0] & 0xff,
+ (data[0] >> 8) & 0xff,
+ CMD_SetIDI0CntResetValue + chan,
+ 0x00
+ };
+ unsigned char imb[4];
+
+ if (devpriv->CntResValue[chan] != (data[0] & 0xffff)) { /* Set reset value if different */
+ if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+ return ret;
+ devpriv->CntResValue[chan] = data[0] & 0xffff;
+ }
+
+ omb[0] = bitmask; /* reset counter to it reset value */
+ omb[2] = CMD_ResetIDICounters;
+ if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+ return ret;
+
+ if (!(bitmask & devpriv->IDICntEnable)) { /* start counter if it don't run */
+ omb[0] = bitmask;
+ omb[2] = CMD_EnableIDICounters;
+ if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+ return ret;
+ devpriv->IDICntEnable |= bitmask;
+ }
+ return 1;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_reset(struct comedi_device * dev)
+{
+ int i;
+ unsigned char omb[4] = { 0x00, 0x00, 0x00, 0x00 };
+ unsigned char imb[4];
+
+ outb(0, dev->iobase + INTCSR0); /* disable IRQ */
+ outb(0, dev->iobase + INTCSR1);
+ outb(0, dev->iobase + INTCSR2);
+ outb(0, dev->iobase + INTCSR3);
+ devpriv->GlobalIrqEnabled = 0;
+
+ omb[0] = 0x00;
+ omb[2] = CMD_SetRelaysOutput; /* reset relay outputs */
+ pci1760_mbxrequest(dev, omb, imb);
+
+ omb[0] = 0x00;
+ omb[2] = CMD_EnableIDICounters; /* disable IDI up counters */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDICntEnable = 0;
+
+ omb[0] = 0x00;
+ omb[2] = CMD_OverflowIDICounters; /* disable counters overflow interrupts */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDICntOverEnable = 0;
+
+ omb[0] = 0x00;
+ omb[2] = CMD_MatchIntIDICounters; /* disable counters match value interrupts */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDICntMatchEnable = 0;
+
+ omb[0] = 0x00;
+ omb[1] = 0x80;
+ for (i = 0; i < 8; i++) { /* set IDI up counters match value */
+ omb[2] = CMD_SetIDI0CntMatchValue + i;
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->CntMatchValue[i] = 0x8000;
+ }
+
+ omb[0] = 0x00;
+ omb[1] = 0x00;
+ for (i = 0; i < 8; i++) { /* set IDI up counters reset value */
+ omb[2] = CMD_SetIDI0CntResetValue + i;
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->CntResValue[i] = 0x0000;
+ }
+
+ omb[0] = 0xff;
+ omb[2] = CMD_ResetIDICounters; /* reset IDI up counters to reset values */
+ pci1760_mbxrequest(dev, omb, imb);
+
+ omb[0] = 0x00;
+ omb[2] = CMD_EdgeIDICounters; /* set IDI up counters count edge */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDICntEdge = 0x00;
+
+ omb[0] = 0x00;
+ omb[2] = CMD_EnableIDIFilters; /* disable all digital in filters */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDIFiltersEn = 0x00;
+
+ omb[0] = 0x00;
+ omb[2] = CMD_EnableIDIPatternMatch; /* disable pattern matching */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDIPatMatchEn = 0x00;
+
+ omb[0] = 0x00;
+ omb[2] = CMD_SetIDIPatternMatch; /* set pattern match value */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDIPatMatchValue = 0x00;
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_reset(struct comedi_device * dev)
+{
+ DPRINTK("adv_pci_dio EDBG: BGN: pci171x_reset(...)\n");
+
+ switch (this_board->cardtype) {
+ case TYPE_PCI1730:
+ outb(0, dev->iobase + PCI1730_DO); /* clear outputs */
+ outb(0, dev->iobase + PCI1730_DO + 1);
+ outb(0, dev->iobase + PCI1730_IDO);
+ outb(0, dev->iobase + PCI1730_IDO + 1);
+ /* NO break there! */
+ case TYPE_PCI1733:
+ outb(0, dev->iobase + PCI1730_3_INT_EN); /* disable interrupts */
+ outb(0x0f, dev->iobase + PCI1730_3_INT_CLR); /* clear interrupts */
+ outb(0, dev->iobase + PCI1730_3_INT_RF); /* set rising edge trigger */
+ break;
+ case TYPE_PCI1734:
+ outb(0, dev->iobase + PCI1734_IDO); /* clear outputs */
+ outb(0, dev->iobase + PCI1734_IDO + 1);
+ outb(0, dev->iobase + PCI1734_IDO + 2);
+ outb(0, dev->iobase + PCI1734_IDO + 3);
+ break;
+
+ case TYPE_PCI1736:
+ outb(0, dev->iobase+PCI1736_IDO);
+ outb(0, dev->iobase+PCI1736_IDO+1);
+ outb(0, dev->iobase+PCI1736_3_INT_EN); /* disable interrupts */
+ outb(0x0f, dev->iobase+PCI1736_3_INT_CLR);/* clear interrupts */
+ outb(0, dev->iobase+PCI1736_3_INT_RF); /* set rising edge trigger */
+ break;
+
+ case TYPE_PCI1750:
+ case TYPE_PCI1751:
+ outb(0x88, dev->iobase + PCI1750_ICR); /* disable & clear interrupts */
+ break;
+ case TYPE_PCI1752:
+ outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze function */
+ outw(0, dev->iobase + PCI1752_IDO); /* clear outputs */
+ outw(0, dev->iobase + PCI1752_IDO + 2);
+ outw(0, dev->iobase + PCI1752_IDO2);
+ outw(0, dev->iobase + PCI1752_IDO2 + 2);
+ break;
+ case TYPE_PCI1753E:
+ outb(0x88, dev->iobase + PCI1753E_ICR0); /* disable & clear interrupts */
+ outb(0x80, dev->iobase + PCI1753E_ICR1);
+ outb(0x80, dev->iobase + PCI1753E_ICR2);
+ outb(0x80, dev->iobase + PCI1753E_ICR3);
+ /* NO break there! */
+ case TYPE_PCI1753:
+ outb(0x88, dev->iobase + PCI1753_ICR0); /* disable & clear interrupts */
+ outb(0x80, dev->iobase + PCI1753_ICR1);
+ outb(0x80, dev->iobase + PCI1753_ICR2);
+ outb(0x80, dev->iobase + PCI1753_ICR3);
+ break;
+ case TYPE_PCI1754:
+ outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear interrupts */
+ outw(0x08, dev->iobase + PCI1754_6_ICR1);
+ outw(0x08, dev->iobase + PCI1754_ICR2);
+ outw(0x08, dev->iobase + PCI1754_ICR3);
+ break;
+ case TYPE_PCI1756:
+ outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze function */
+ outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear interrupts */
+ outw(0x08, dev->iobase + PCI1754_6_ICR1);
+ outw(0, dev->iobase + PCI1756_IDO); /* clear outputs */
+ outw(0, dev->iobase + PCI1756_IDO + 2);
+ break;
+ case TYPE_PCI1760:
+ pci1760_reset(dev);
+ break;
+ case TYPE_PCI1762:
+ outw(0x0101, dev->iobase + PCI1762_ICR); /* disable & clear interrupts */
+ break;
+ }
+
+ DPRINTK("adv_pci_dio EDBG: END: pci171x_reset(...)\n");
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int subdev = 0;
+
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->len_chanlist = 8;
+ s->range_table = &range_digital;
+ s->insn_bits = pci1760_insn_bits_di;
+ subdev++;
+
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->len_chanlist = 8;
+ s->range_table = &range_digital;
+ s->state = 0;
+ s->insn_bits = pci1760_insn_bits_do;
+ subdev++;
+
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_WRITABLE | SDF_LSAMPL;
+ s->n_chan = 2;
+ s->maxdata = 0xffffffff;
+ s->len_chanlist = 2;
+/* s->insn_config=pci1760_insn_pwm_cfg; */
+ subdev++;
+
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 8;
+ s->insn_read = pci1760_insn_cnt_read;
+ s->insn_write = pci1760_insn_cnt_write;
+/* s->insn_config=pci1760_insn_cnt_cfg; */
+ subdev++;
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_add_di(struct comedi_device * dev, struct comedi_subdevice * s,
+ const struct diosubd_data * d, int subdev)
+{
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | d->specflags;
+ if (d->chans > 16)
+ s->subdev_flags |= SDF_LSAMPL;
+ s->n_chan = d->chans;
+ s->maxdata = 1;
+ s->len_chanlist = d->chans;
+ s->range_table = &range_digital;
+ switch (this_board->io_access) {
+ case IO_8b:
+ s->insn_bits = pci_dio_insn_bits_di_b;
+ break;
+ case IO_16b:
+ s->insn_bits = pci_dio_insn_bits_di_w;
+ break;
+ }
+ s->private = (void *)d;
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_add_do(struct comedi_device * dev, struct comedi_subdevice * s,
+ const struct diosubd_data * d, int subdev)
+{
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ if (d->chans > 16)
+ s->subdev_flags |= SDF_LSAMPL;
+ s->n_chan = d->chans;
+ s->maxdata = 1;
+ s->len_chanlist = d->chans;
+ s->range_table = &range_digital;
+ s->state = 0;
+ switch (this_board->io_access) {
+ case IO_8b:
+ s->insn_bits = pci_dio_insn_bits_do_b;
+ break;
+ case IO_16b:
+ s->insn_bits = pci_dio_insn_bits_do_w;
+ break;
+ }
+ s->private = (void *)d;
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int CheckAndAllocCard(struct comedi_device * dev, struct comedi_devconfig * it,
+ struct pci_dev *pcidev)
+{
+ struct pci_dio_private *pr, *prev;
+
+ for (pr = pci_priv, prev = NULL; pr != NULL; prev = pr, pr = pr->next) {
+ if (pr->pcidev == pcidev) {
+ return 0; /* this card is used, look for another */
+ }
+ }
+
+ if (prev) {
+ devpriv->prev = prev;
+ prev->next = devpriv;
+ } else {
+ pci_priv = devpriv;
+ }
+
+ devpriv->pcidev = pcidev;
+
+ return 1;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret, subdev, n_subdevices, i, j;
+ unsigned long iobase;
+ struct pci_dev *pcidev;
+
+ rt_printk("comedi%d: adv_pci_dio: ", dev->minor);
+
+ if ((ret = alloc_private(dev, sizeof(struct pci_dio_private))) < 0) {
+ rt_printk(", Error: Cann't allocate private memory!\n");
+ return -ENOMEM;
+ }
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ /* loop through cards supported by this driver */
+ for (i = 0; i < n_boardtypes; ++i) {
+ if (boardtypes[i].vendor_id != pcidev->vendor)
+ continue;
+ if (boardtypes[i].device_id != pcidev->device)
+ continue;
+ /* was a particular bus/slot requested? */
+ if (it->options[0] || it->options[1]) {
+ /* are we on the wrong bus/slot? */
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ ret = CheckAndAllocCard(dev, it, pcidev);
+ if (ret != 1) continue;
+ dev->board_ptr = boardtypes + i;
+ break;
+ }
+ if (dev->board_ptr)
+ break;
+ }
+
+ if (!dev->board_ptr) {
+ rt_printk
+ (", Error: Requested type of the card was not found!\n");
+ return -EIO;
+ }
+
+ if (comedi_pci_enable(pcidev, driver_pci_dio.driver_name)) {
+ rt_printk
+ (", Error: Can't enable PCI device and request regions!\n");
+ return -EIO;
+ }
+ iobase = pci_resource_start(pcidev, this_board->main_pci_region);
+ rt_printk(", b:s:f=%d:%d:%d, io=0x%4lx",
+ pcidev->bus->number, PCI_SLOT(pcidev->devfn),
+ PCI_FUNC(pcidev->devfn), iobase);
+
+ dev->iobase = iobase;
+ dev->board_name = this_board->name;
+
+ if (this_board->cardtype == TYPE_PCI1760) {
+ n_subdevices = 4; /* 8 IDI, 8 IDO, 2 PWM, 8 CNT */
+ } else {
+ n_subdevices = 0;
+ for (i = 0; i < MAX_DI_SUBDEVS; i++)
+ if (this_board->sdi[i].chans)
+ n_subdevices++;
+ for (i = 0; i < MAX_DO_SUBDEVS; i++)
+ if (this_board->sdo[i].chans)
+ n_subdevices++;
+ for (i = 0; i < MAX_DIO_SUBDEVG; i++)
+ n_subdevices += this_board->sdio[i].regs;
+ if (this_board->boardid.chans)
+ n_subdevices++;
+ }
+
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+ rt_printk(", Error: Cann't allocate subdevice memory!\n");
+ return ret;
+ }
+
+ rt_printk(".\n");
+
+ subdev = 0;
+
+ for (i = 0; i < MAX_DI_SUBDEVS; i++)
+ if (this_board->sdi[i].chans) {
+ s = dev->subdevices + subdev;
+ pci_dio_add_di(dev, s, &this_board->sdi[i], subdev);
+ subdev++;
+ }
+
+ for (i = 0; i < MAX_DO_SUBDEVS; i++)
+ if (this_board->sdo[i].chans) {
+ s = dev->subdevices + subdev;
+ pci_dio_add_do(dev, s, &this_board->sdo[i], subdev);
+ subdev++;
+ }
+
+ for (i = 0; i < MAX_DIO_SUBDEVG; i++)
+ for (j = 0; j < this_board->sdio[i].regs; j++) {
+ s = dev->subdevices + subdev;
+ subdev_8255_init(dev, s, NULL,
+ dev->iobase + this_board->sdio[i].addr +
+ SIZE_8255 * j);
+ subdev++;
+ }
+
+ if (this_board->boardid.chans) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DI;
+ pci_dio_add_di(dev, s, &this_board->boardid, subdev);
+ subdev++;
+ }
+
+ if (this_board->cardtype == TYPE_PCI1760)
+ pci1760_attach(dev, it);
+
+ devpriv->valid = 1;
+
+ pci_dio_reset(dev);
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_detach(struct comedi_device * dev)
+{
+ int i, j;
+ struct comedi_subdevice *s;
+ int subdev;
+
+ if (dev->private) {
+ if (devpriv->valid) {
+ pci_dio_reset(dev);
+ }
+
+ /* This shows the silliness of using this kind of
+ * scheme for numbering subdevices. Don't do it. --ds */
+ subdev = 0;
+ for (i = 0; i < MAX_DI_SUBDEVS; i++) {
+ if (this_board->sdi[i].chans) {
+ subdev++;
+ }
+ }
+ for (i = 0; i < MAX_DO_SUBDEVS; i++) {
+ if (this_board->sdo[i].chans) {
+ subdev++;
+ }
+ }
+ for (i = 0; i < MAX_DIO_SUBDEVG; i++) {
+ for (j = 0; j < this_board->sdio[i].regs; j++) {
+ s = dev->subdevices + subdev;
+ subdev_8255_cleanup(dev, s);
+ subdev++;
+ }
+ }
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ s = dev->subdevices + i;
+ s->private = NULL;
+ }
+
+ if (devpriv->pcidev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pcidev);
+ }
+ pci_dev_put(devpriv->pcidev);
+ }
+
+ if (devpriv->prev) {
+ devpriv->prev->next = devpriv->next;
+ } else {
+ pci_priv = devpriv->next;
+ }
+ if (devpriv->next) {
+ devpriv->next->prev = devpriv->prev;
+ }
+ }
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+COMEDI_PCI_INITCLEANUP(driver_pci_dio, pci_dio_pci_table);
+/*
+==============================================================================
+*/
diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c
new file mode 100644
index 00000000000..b97b4d82611
--- /dev/null
+++ b/drivers/staging/comedi/drivers/aio_aio12_8.c
@@ -0,0 +1,226 @@
+/*
+
+ comedi/drivers/aio_aio12_8.c
+
+ Driver for Acces I/O Products PC-104 AIO12-8 Analog I/O Board
+ Copyright (C) 2006 C&C Technologies, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+
+Driver: aio_aio12_8
+Description: Acces I/O Products PC-104 AIO12-8 Analog I/O Board
+Author: Pablo Mejia <pablo.mejia@cctechnol.com>
+Devices:
+ [Acces I/O] PC-104 AIO12-8
+Status: experimental
+
+Configuration Options:
+ [0] - I/O port base address
+
+Notes:
+
+ Only synchronous operations are supported.
+
+*/
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+#include "8255.h"
+
+#define AIO12_8_STATUS 0x00
+#define AIO12_8_INTERRUPT 0x01
+#define AIO12_8_ADC 0x02
+#define AIO12_8_DAC_0 0x04
+#define AIO12_8_DAC_1 0x06
+#define AIO12_8_DAC_2 0x08
+#define AIO12_8_DAC_3 0x0A
+#define AIO12_8_COUNTER_0 0x0C
+#define AIO12_8_COUNTER_1 0x0D
+#define AIO12_8_COUNTER_2 0x0E
+#define AIO12_8_COUNTER_CONTROL 0x0F
+#define AIO12_8_DIO_0 0x10
+#define AIO12_8_DIO_1 0x11
+#define AIO12_8_DIO_2 0x12
+#define AIO12_8_DIO_STATUS 0x13
+#define AIO12_8_DIO_CONTROL 0x14
+#define AIO12_8_ADC_TRIGGER_CONTROL 0x15
+#define AIO12_8_TRIGGER 0x16
+#define AIO12_8_POWER 0x17
+
+#define STATUS_ADC_EOC 0x80
+
+#define ADC_MODE_NORMAL 0x00
+#define ADC_MODE_INTERNAL_CLOCK 0x40
+#define ADC_MODE_STANDBY 0x80
+#define ADC_MODE_POWERDOWN 0xC0
+
+#define DAC_ENABLE 0x18
+
+struct aio12_8_boardtype {
+ const char *name;
+};
+
+static const struct aio12_8_boardtype board_types[] = {
+ {
+ name: "aio_aio12_8"},
+};
+
+#define thisboard ((const struct aio12_8_boardtype *) dev->board_ptr)
+
+struct aio12_8_private {
+ unsigned int ao_readback[4];
+};
+
+#define devpriv ((struct aio12_8_private *) dev->private)
+
+static int aio_aio12_8_ai_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ unsigned char control =
+ ADC_MODE_NORMAL |
+ (CR_RANGE(insn->chanspec) << 3) | CR_CHAN(insn->chanspec);
+
+ //read status to clear EOC latch
+ inb(dev->iobase + AIO12_8_STATUS);
+
+ for (n = 0; n < insn->n; n++) {
+ int timeout = 5;
+
+ // Setup and start conversion
+ outb(control, dev->iobase + AIO12_8_ADC);
+
+ // Wait for conversion to complete
+ while (timeout &&
+ !(inb(dev->iobase + AIO12_8_STATUS) & STATUS_ADC_EOC)) {
+ timeout--;
+ printk("timeout %d\n", timeout);
+ comedi_udelay(1);
+ }
+ if (timeout == 0) {
+ comedi_error(dev, "ADC timeout");
+ return -EIO;
+ }
+
+ data[n] = inw(dev->iobase + AIO12_8_ADC) & 0x0FFF;
+ }
+ return n;
+}
+
+static int aio_aio12_8_ao_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int val = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = val;
+ return insn->n;
+}
+
+static int aio_aio12_8_ao_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned long port = dev->iobase + AIO12_8_DAC_0 + (2 * chan);
+
+ //enable DACs
+ outb(0x01, dev->iobase + DAC_ENABLE);
+
+ for (i = 0; i < insn->n; i++) {
+ outb(data[i] & 0xFF, port); // LSB
+ outb((data[i] >> 8) & 0x0F, port + 1); // MSB
+ devpriv->ao_readback[chan] = data[i];
+ }
+ return insn->n;
+}
+
+static const struct comedi_lrange range_aio_aio12_8 = {
+ 4,
+ {
+ UNI_RANGE(5),
+ BIP_RANGE(5),
+ UNI_RANGE(10),
+ BIP_RANGE(10),
+ }
+};
+
+static int aio_aio12_8_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int iobase;
+ struct comedi_subdevice *s;
+
+ iobase = it->options[0];
+ if (!request_region(iobase, 24, "aio_aio12_8")) {
+ printk("I/O port conflict");
+ return -EIO;
+ }
+
+ dev->board_name = thisboard->name;
+
+ dev->iobase = iobase;
+
+ if (alloc_private(dev, sizeof(struct aio12_8_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = &dev->subdevices[0];
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
+ s->n_chan = 8;
+ s->maxdata = (1 << 12) - 1;
+ s->range_table = &range_aio_aio12_8;
+ s->insn_read = aio_aio12_8_ai_read;
+
+ s = &dev->subdevices[1];
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_DIFF;
+ s->n_chan = 4;
+ s->maxdata = (1 << 12) - 1;
+ s->range_table = &range_aio_aio12_8;
+ s->insn_read = aio_aio12_8_ao_read;
+ s->insn_write = aio_aio12_8_ao_write;
+
+ s = &dev->subdevices[2];
+ subdev_8255_init(dev, s, NULL, dev->iobase + AIO12_8_DIO_0);
+
+ return 0;
+}
+
+static int aio_aio12_8_detach(struct comedi_device * dev)
+{
+ subdev_8255_cleanup(dev, &dev->subdevices[2]);
+ if (dev->iobase)
+ release_region(dev->iobase, 24);
+ return 0;
+}
+
+static struct comedi_driver driver_aio_aio12_8 = {
+ driver_name:"aio_aio12_8",
+ module:THIS_MODULE,
+ attach:aio_aio12_8_attach,
+ detach:aio_aio12_8_detach,
+ board_name:&board_types[0].name,
+ num_names:1,
+ offset:sizeof(struct aio12_8_boardtype),
+};
+
+COMEDI_INITCLEANUP(driver_aio_aio12_8);
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
new file mode 100644
index 00000000000..9160fdf0ca3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -0,0 +1,177 @@
+/*
+
+ comedi/drivers/aio_iiro_16.c
+
+ Driver for Acces I/O Products PC-104 AIO-IIRO-16 Digital I/O board
+ Copyright (C) 2006 C&C Technologies, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+
+Driver: aio_iiro_16
+Description: Acces I/O Products PC-104 IIRO16 Relay And Isolated Input Board
+Author: Zachary Ware <zach.ware@cctechnol.com>
+Devices:
+ [Acces I/O] PC-104 AIO12-8
+Status: experimental
+
+Configuration Options:
+ [0] - I/O port base address
+
+*/
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+
+#define AIO_IIRO_16_SIZE 0x08
+#define AIO_IIRO_16_RELAY_0_7 0x00
+#define AIO_IIRO_16_INPUT_0_7 0x01
+#define AIO_IIRO_16_IRQ 0x02
+#define AIO_IIRO_16_RELAY_8_15 0x04
+#define AIO_IIRO_16_INPUT_8_15 0x05
+
+struct aio_iiro_16_board {
+ const char *name;
+ int do_;
+ int di;
+};
+
+static const struct aio_iiro_16_board aio_iiro_16_boards[] = {
+ {
+ name: "aio_iiro_16",
+ di: 16,
+ do_: 16},
+};
+
+#define thisboard ((const struct aio_iiro_16_board *) dev->board_ptr)
+
+struct aio_iiro_16_private {
+ int data;
+ struct pci_dev *pci_dev;
+ unsigned int ao_readback[2];
+};
+
+#define devpriv ((struct aio_iiro_16_private *) dev->private)
+
+static int aio_iiro_16_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+
+static int aio_iiro_16_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_aio_iiro_16 = {
+ driver_name:"aio_iiro_16",
+ module:THIS_MODULE,
+ attach:aio_iiro_16_attach,
+ detach:aio_iiro_16_detach,
+ board_name:&aio_iiro_16_boards[0].name,
+ offset:sizeof(struct aio_iiro_16_board),
+ num_names:sizeof(aio_iiro_16_boards) / sizeof(struct aio_iiro_16_board),
+};
+
+static int aio_iiro_16_dio_insn_bits_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int aio_iiro_16_dio_insn_bits_write(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int aio_iiro_16_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int iobase;
+ struct comedi_subdevice *s;
+
+ printk("comedi%d: aio_iiro_16: ", dev->minor);
+
+ dev->board_name = thisboard->name;
+
+ iobase = it->options[0];
+
+ if (!request_region(iobase, AIO_IIRO_16_SIZE, dev->board_name)) {
+ printk("I/O port conflict");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+ if (alloc_private(dev, sizeof(struct aio_iiro_16_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = aio_iiro_16_dio_insn_bits_write;
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = aio_iiro_16_dio_insn_bits_read;
+
+ printk("attached\n");
+
+ return 1;
+}
+
+static int aio_iiro_16_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: aio_iiro_16: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, AIO_IIRO_16_SIZE);
+
+ return 0;
+}
+
+static int aio_iiro_16_dio_insn_bits_write(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7);
+ outb((s->state >> 8) & 0xff,
+ dev->iobase + AIO_IIRO_16_RELAY_8_15);
+ }
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int aio_iiro_16_dio_insn_bits_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = 0;
+ data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_0_7);
+ data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8;
+
+ return 2;
+}
+
+COMEDI_INITCLEANUP(driver_aio_iiro_16);
diff --git a/drivers/staging/comedi/drivers/am9513.h b/drivers/staging/comedi/drivers/am9513.h
new file mode 100644
index 00000000000..f533cf1658c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/am9513.h
@@ -0,0 +1,79 @@
+/*
+ module/am9513.h
+ value added preprocessor definitions for Am9513 timer chip
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _AM9513_H_
+#define _AM9513_H_
+
+#if 0
+
+/*
+ * Before including this file, the following need to be defined:
+ */
+#define Am9513_8BITBUS xxx
+/* or */
+#define Am9513_16BITBUS xxx
+
+#define Am9513_output_control(a) xxx
+#define Am9513_input_status() xxx
+#define Am9513_output_data(a) xxx
+#define Am9513_input_data() xxx
+
+#endif
+
+/*
+ *
+ */
+
+#ifdef Am9513_8BITBUS
+
+#define Am9513_write_register(reg,val) \
+ do{ \
+ Am9513_output_control(reg); \
+ Am9513_output_data(val>>8); \
+ Am9513_output_data(val&0xff); \
+ }while(0)
+
+#define Am9513_read_register(reg,val) \
+ do{ \
+ Am9513_output_control(reg); \
+ val=Am9513_input_data()<<8; \
+ val|=Am9513_input_data(); \
+ }while(0)
+
+#else /* Am9513_16BITBUS */
+
+#define Am9513_write_register(reg,val) \
+ do{ \
+ Am9513_output_control(reg); \
+ Am9513_output_data(val); \
+ }while(0)
+
+#define Am9513_read_register(reg,val) \
+ do{ \
+ Am9513_output_control(reg); \
+ val=Am9513_input_data(); \
+ }while(0)
+
+#endif
+
+#endif
diff --git a/drivers/staging/comedi/drivers/amcc_s5933.h b/drivers/staging/comedi/drivers/amcc_s5933.h
new file mode 100644
index 00000000000..aceffce7ef3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amcc_s5933.h
@@ -0,0 +1,172 @@
+/*
+ comedi/drivers/amcc_s5933.h
+
+ Stuff for AMCC S5933 PCI Controller
+
+ Author: Michal Dobes <dobes@tesnet.cz>
+
+ Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver
+ made by Andrea Cisternino <acister@pcape1.pi.infn.it>
+ and as result of espionage from MITE code made by David A. Schleef.
+ Thanks to AMCC for their on-line documentation and bus master DMA
+ example.
+*/
+
+#ifndef _AMCC_S5933_H_
+#define _AMCC_S5933_H_
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - PCI */
+/****************************************************************************/
+
+#define AMCC_OP_REG_OMB1 0x00
+#define AMCC_OP_REG_OMB2 0x04
+#define AMCC_OP_REG_OMB3 0x08
+#define AMCC_OP_REG_OMB4 0x0c
+#define AMCC_OP_REG_IMB1 0x10
+#define AMCC_OP_REG_IMB2 0x14
+#define AMCC_OP_REG_IMB3 0x18
+#define AMCC_OP_REG_IMB4 0x1c
+#define AMCC_OP_REG_FIFO 0x20
+#define AMCC_OP_REG_MWAR 0x24
+#define AMCC_OP_REG_MWTC 0x28
+#define AMCC_OP_REG_MRAR 0x2c
+#define AMCC_OP_REG_MRTC 0x30
+#define AMCC_OP_REG_MBEF 0x34
+#define AMCC_OP_REG_INTCSR 0x38
+#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) /* INT source */
+#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) /* FIFO ctrl */
+#define AMCC_OP_REG_MCSR 0x3c
+#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) /* Data in byte 2 */
+#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */
+
+#define AMCC_FIFO_DEPTH_DWORD 8
+#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof (u32))
+
+/****************************************************************************/
+/* AMCC - PCI Interrupt Control/Status Register */
+/****************************************************************************/
+#define INTCSR_OUTBOX_BYTE(x) ((x) & 0x3)
+#define INTCSR_OUTBOX_SELECT(x) (((x) & 0x3) << 2)
+#define INTCSR_OUTBOX_EMPTY_INT 0x10 // enable outbox empty interrupt
+#define INTCSR_INBOX_BYTE(x) (((x) & 0x3) << 8)
+#define INTCSR_INBOX_SELECT(x) (((x) & 0x3) << 10)
+#define INTCSR_INBOX_FULL_INT 0x1000 // enable inbox full interrupt
+#define INTCSR_INBOX_INTR_STATUS 0x20000 // read, or write clear inbox full interrupt
+#define INTCSR_INTR_ASSERTED 0x800000 // read only, interrupt asserted
+
+/****************************************************************************/
+/* AMCC - PCI non-volatile ram command register (byte 3 of master control/status register) */
+/****************************************************************************/
+#define MCSR_NV_LOAD_LOW_ADDR 0x0
+#define MCSR_NV_LOAD_HIGH_ADDR 0x20
+#define MCSR_NV_WRITE 0x40
+#define MCSR_NV_READ 0x60
+#define MCSR_NV_MASK 0x60
+#define MCSR_NV_ENABLE 0x80
+#define MCSR_NV_BUSY MCSR_NV_ENABLE
+
+/****************************************************************************/
+/* AMCC Operation Registers Size - PCI */
+/****************************************************************************/
+
+#define AMCC_OP_REG_SIZE 64 /* in bytes */
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - Add-on */
+/****************************************************************************/
+
+#define AMCC_OP_REG_AIMB1 0x00
+#define AMCC_OP_REG_AIMB2 0x04
+#define AMCC_OP_REG_AIMB3 0x08
+#define AMCC_OP_REG_AIMB4 0x0c
+#define AMCC_OP_REG_AOMB1 0x10
+#define AMCC_OP_REG_AOMB2 0x14
+#define AMCC_OP_REG_AOMB3 0x18
+#define AMCC_OP_REG_AOMB4 0x1c
+#define AMCC_OP_REG_AFIFO 0x20
+#define AMCC_OP_REG_AMWAR 0x24
+#define AMCC_OP_REG_APTA 0x28
+#define AMCC_OP_REG_APTD 0x2c
+#define AMCC_OP_REG_AMRAR 0x30
+#define AMCC_OP_REG_AMBEF 0x34
+#define AMCC_OP_REG_AINT 0x38
+#define AMCC_OP_REG_AGCSTS 0x3c
+#define AMCC_OP_REG_AMWTC 0x58
+#define AMCC_OP_REG_AMRTC 0x5c
+
+/****************************************************************************/
+/* AMCC - Add-on General Control/Status Register */
+/****************************************************************************/
+
+#define AGCSTS_CONTROL_MASK 0xfffff000
+#define AGCSTS_NV_ACC_MASK 0xe0000000
+#define AGCSTS_RESET_MASK 0x0e000000
+#define AGCSTS_NV_DA_MASK 0x00ff0000
+#define AGCSTS_BIST_MASK 0x0000f000
+#define AGCSTS_STATUS_MASK 0x000000ff
+#define AGCSTS_TCZERO_MASK 0x000000c0
+#define AGCSTS_FIFO_ST_MASK 0x0000003f
+
+#define AGCSTS_RESET_MBFLAGS 0x08000000
+#define AGCSTS_RESET_P2A_FIFO 0x04000000
+#define AGCSTS_RESET_A2P_FIFO 0x02000000
+#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
+
+#define AGCSTS_A2P_TCOUNT 0x00000080
+#define AGCSTS_P2A_TCOUNT 0x00000040
+
+#define AGCSTS_FS_P2A_EMPTY 0x00000020
+#define AGCSTS_FS_P2A_HALF 0x00000010
+#define AGCSTS_FS_P2A_FULL 0x00000008
+
+#define AGCSTS_FS_A2P_EMPTY 0x00000004
+#define AGCSTS_FS_A2P_HALF 0x00000002
+#define AGCSTS_FS_A2P_FULL 0x00000001
+
+/****************************************************************************/
+/* AMCC - Add-on Interrupt Control/Status Register */
+/****************************************************************************/
+
+#define AINT_INT_MASK 0x00ff0000
+#define AINT_SEL_MASK 0x0000ffff
+#define AINT_IS_ENSEL_MASK 0x00001f1f
+
+#define AINT_INT_ASSERTED 0x00800000
+#define AINT_BM_ERROR 0x00200000
+#define AINT_BIST_INT 0x00100000
+
+#define AINT_RT_COMPLETE 0x00080000
+#define AINT_WT_COMPLETE 0x00040000
+
+#define AINT_OUT_MB_INT 0x00020000
+#define AINT_IN_MB_INT 0x00010000
+
+#define AINT_READ_COMPL 0x00008000
+#define AINT_WRITE_COMPL 0x00004000
+
+#define AINT_OMB_ENABLE 0x00001000
+#define AINT_OMB_SELECT 0x00000c00
+#define AINT_OMB_BYTE 0x00000300
+
+#define AINT_IMB_ENABLE 0x00000010
+#define AINT_IMB_SELECT 0x0000000c
+#define AINT_IMB_BYTE 0x00000003
+
+// these are bits from various different registers, needs cleanup XXX
+/* Enable Bus Mastering */
+#define EN_A2P_TRANSFERS 0x00000400
+/* FIFO Flag Reset */
+#define RESET_A2P_FLAGS 0x04000000L
+/* FIFO Relative Priority */
+#define A2P_HI_PRIORITY 0x00000100L
+/* Identify Interrupt Sources */
+#define ANY_S593X_INT 0x00800000L
+#define READ_TC_INT 0x00080000L
+#define WRITE_TC_INT 0x00040000L
+#define IN_MB_INT 0x00020000L
+#define MASTER_ABORT_INT 0x00100000L
+#define TARGET_ABORT_INT 0x00200000L
+#define BUS_MASTER_INT 0x00200000L
+
+#endif
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
new file mode 100644
index 00000000000..8555e272a86
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -0,0 +1,1483 @@
+/*
+ comedi/drivers/amplc_dio200.c
+ Driver for Amplicon PC272E and PCI272 DIO boards.
+ (Support for other boards in Amplicon 200 series may be added at
+ a later date, e.g. PCI215.)
+
+ Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: amplc_dio200
+Description: Amplicon 200 Series Digital I/O
+Author: Ian Abbott <abbotti@mev.co.uk>
+Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e),
+ PCI215 (pci215 or amplc_dio200), PC218E (pc218e), PC272E (pc272e),
+ PCI272 (pci272 or amplc_dio200)
+Updated: Wed, 22 Oct 2008 13:36:02 +0100
+Status: works
+
+Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
+ [0] - I/O port base address
+ [1] - IRQ (optional, but commands won't work without it)
+
+Configuration options - PCI215, PCI272:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI device will
+ be used.
+
+Passing a zero for an option is the same as leaving it unspecified.
+
+SUBDEVICES
+
+ PC218E PC212E PC215E/PCI215
+ ------------- ------------- -------------
+ Subdevices 7 6 5
+ 0 CTR-X1 PPI-X PPI-X
+ 1 CTR-X2 CTR-Y1 PPI-Y
+ 2 CTR-Y1 CTR-Y2 CTR-Z1
+ 3 CTR-Y2 CTR-Z1 CTR-Z2
+ 4 CTR-Z1 CTR-Z2 INTERRUPT
+ 5 CTR-Z2 INTERRUPT
+ 6 INTERRUPT
+
+ PC214E PC272E/PCI272
+ ------------- -------------
+ Subdevices 4 4
+ 0 PPI-X PPI-X
+ 1 PPI-Y PPI-Y
+ 2 CTR-Z1* PPI-Z
+ 3 INTERRUPT* INTERRUPT
+
+Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels
+are configurable as inputs or outputs in four groups:
+
+ Port A - channels 0 to 7
+ Port B - channels 8 to 15
+ Port CL - channels 16 to 19
+ Port CH - channels 20 to 23
+
+Only mode 0 of the 8255 chips is supported.
+
+Each CTR is a 8254 chip providing 3 16-bit counter channels. Each
+channel is configured individually with INSN_CONFIG instructions. The
+specific type of configuration instruction is specified in data[0].
+Some configuration instructions expect an additional parameter in
+data[1]; others return a value in data[1]. The following configuration
+instructions are supported:
+
+ INSN_CONFIG_SET_COUNTER_MODE. Sets the counter channel's mode and
+ BCD/binary setting specified in data[1].
+
+ INSN_CONFIG_8254_READ_STATUS. Reads the status register value for the
+ counter channel into data[1].
+
+ INSN_CONFIG_SET_CLOCK_SRC. Sets the counter channel's clock source as
+ specified in data[1] (this is a hardware-specific value). Not
+ supported on PC214E. For the other boards, valid clock sources are
+ 0 to 7 as follows:
+
+ 0. CLK n, the counter channel's dedicated CLK input from the SK1
+ connector. (N.B. for other values, the counter channel's CLKn
+ pin on the SK1 connector is an output!)
+ 1. Internal 10 MHz clock.
+ 2. Internal 1 MHz clock.
+ 3. Internal 100 kHz clock.
+ 4. Internal 10 kHz clock.
+ 5. Internal 1 kHz clock.
+ 6. OUT n-1, the output of counter channel n-1 (see note 1 below).
+ 7. Ext Clock, the counter chip's dedicated Ext Clock input from
+ the SK1 connector. This pin is shared by all three counter
+ channels on the chip.
+
+ INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
+ clock source in data[1]. For internal clock sources, data[2] is set
+ to the period in ns.
+
+ INSN_CONFIG_SET_GATE_SRC. Sets the counter channel's gate source as
+ specified in data[2] (this is a hardware-specific value). Not
+ supported on PC214E. For the other boards, valid gate sources are 0
+ to 7 as follows:
+
+ 0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
+ 1. GND (internal 0V d.c.), i.e. gate permanently disabled.
+ 2. GAT n, the counter channel's dedicated GAT input from the SK1
+ connector. (N.B. for other values, the counter channel's GATn
+ pin on the SK1 connector is an output!)
+ 3. /OUT n-2, the inverted output of counter channel n-2 (see note
+ 2 below).
+ 4. Reserved.
+ 5. Reserved.
+ 6. Reserved.
+ 7. Reserved.
+
+ INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate
+ source in data[2].
+
+Clock and gate interconnection notes:
+
+ 1. Clock source OUT n-1 is the output of the preceding channel on the
+ same counter subdevice if n > 0, or the output of channel 2 on the
+ preceding counter subdevice (see note 3) if n = 0.
+
+ 2. Gate source /OUT n-2 is the inverted output of channel 0 on the
+ same counter subdevice if n = 2, or the inverted output of channel n+1
+ on the preceding counter subdevice (see note 3) if n < 2.
+
+ 3. The counter subdevices are connected in a ring, so the highest
+ counter subdevice precedes the lowest.
+
+The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The
+digital inputs come from the interrupt status register. The number of
+channels matches the number of interrupt sources. The PC214E does not
+have an interrupt status register; see notes on 'INTERRUPT SOURCES'
+below.
+
+INTERRUPT SOURCES
+
+ PC218E PC212E PC215E/PCI215
+ ------------- ------------- -------------
+ Sources 6 6 6
+ 0 CTR-X1-OUT PPI-X-C0 PPI-X-C0
+ 1 CTR-X2-OUT PPI-X-C3 PPI-X-C3
+ 2 CTR-Y1-OUT CTR-Y1-OUT PPI-Y-C0
+ 3 CTR-Y2-OUT CTR-Y2-OUT PPI-Y-C3
+ 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT
+ 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT
+
+ PC214E PC272E/PCI272
+ ------------- -------------
+ Sources 1 6
+ 0 JUMPER-J5 PPI-X-C0
+ 1 PPI-X-C3
+ 2 PPI-Y-C0
+ 3 PPI-Y-C3
+ 4 PPI-Z-C0
+ 5 PPI-Z-C3
+
+When an interrupt source is enabled in the interrupt source enable
+register, a rising edge on the source signal latches the corresponding
+bit to 1 in the interrupt status register.
+
+When the interrupt status register value as a whole (actually, just the
+6 least significant bits) goes from zero to non-zero, the board will
+generate an interrupt. For level-triggered hardware interrupts (PCI
+card), the interrupt will remain asserted until the interrupt status
+register is cleared to zero. For edge-triggered hardware interrupts
+(ISA card), no further interrupts will occur until the interrupt status
+register is cleared to zero. To clear a bit to zero in the interrupt
+status register, the corresponding interrupt source must be disabled
+in the interrupt source enable register (there is no separate interrupt
+clear register).
+
+The PC214E does not have an interrupt source enable register or an
+interrupt status register; its 'INTERRUPT' subdevice has a single
+channel and its interrupt source is selected by the position of jumper
+J5.
+
+COMMANDS
+
+The driver supports a read streaming acquisition command on the
+'INTERRUPT' subdevice. The channel list selects the interrupt sources
+to be enabled. All channels will be sampled together (convert_src ==
+TRIG_NOW). The scan begins a short time after the hardware interrupt
+occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
+scan_begin_arg == 0). The value read from the interrupt status register
+is packed into a short value, one bit per requested channel, in the
+order they appear in the channel list.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "8255.h"
+#include "8253.h"
+
+#define DIO200_DRIVER_NAME "amplc_dio200"
+
+/* PCI IDs */
+/* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
+#define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
+#define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+/* 200 series registers */
+#define DIO200_IO_SIZE 0x20
+#define DIO200_XCLK_SCE 0x18 /* Group X clock selection register */
+#define DIO200_YCLK_SCE 0x19 /* Group Y clock selection register */
+#define DIO200_ZCLK_SCE 0x1a /* Group Z clock selection register */
+#define DIO200_XGAT_SCE 0x1b /* Group X gate selection register */
+#define DIO200_YGAT_SCE 0x1c /* Group Y gate selection register */
+#define DIO200_ZGAT_SCE 0x1d /* Group Z gate selection register */
+#define DIO200_INT_SCE 0x1e /* Interrupt enable/status register */
+
+/*
+ * Macros for constructing value for DIO_200_?CLK_SCE and
+ * DIO_200_?GAT_SCE registers:
+ *
+ * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
+ * 'chan' is the channel: 0, 1 or 2.
+ * 'source' is the signal source: 0 to 7.
+ */
+#define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
+#define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
+
+/*
+ * Periods of the internal clock sources in nanoseconds.
+ */
+static const unsigned clock_period[8] = {
+ 0, /* dedicated clock input/output pin */
+ 100, /* 10 MHz */
+ 1000, /* 1 MHz */
+ 10000, /* 100 kHz */
+ 100000, /* 10 kHz */
+ 1000000, /* 1 kHz */
+ 0, /* OUT N-1 */
+ 0 /* group clock input pin */
+};
+
+/*
+ * Board descriptions.
+ */
+
+enum dio200_bustype { isa_bustype, pci_bustype };
+
+enum dio200_model {
+ pc212e_model,
+ pc214e_model,
+ pc215e_model, pci215_model,
+ pc218e_model,
+ pc272e_model, pci272_model,
+ anypci_model
+};
+
+enum dio200_layout {
+ pc212_layout,
+ pc214_layout,
+ pc215_layout,
+ pc218_layout,
+ pc272_layout
+};
+
+struct dio200_board {
+ const char *name;
+ unsigned short devid;
+ enum dio200_bustype bustype;
+ enum dio200_model model;
+ enum dio200_layout layout;
+};
+
+static const struct dio200_board dio200_boards[] = {
+ {
+ name: "pc212e",
+ bustype: isa_bustype,
+ model: pc212e_model,
+ layout: pc212_layout,
+ },
+ {
+ name: "pc214e",
+ bustype: isa_bustype,
+ model: pc214e_model,
+ layout: pc214_layout,
+ },
+ {
+ name: "pc215e",
+ bustype: isa_bustype,
+ model: pc215e_model,
+ layout: pc215_layout,
+ },
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: "pci215",
+ devid: PCI_DEVICE_ID_AMPLICON_PCI215,
+ bustype: pci_bustype,
+ model: pci215_model,
+ layout: pc215_layout,
+ },
+#endif
+ {
+ name: "pc218e",
+ bustype: isa_bustype,
+ model: pc218e_model,
+ layout: pc218_layout,
+ },
+ {
+ name: "pc272e",
+ bustype: isa_bustype,
+ model: pc272e_model,
+ layout: pc272_layout,
+ },
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: "pci272",
+ devid: PCI_DEVICE_ID_AMPLICON_PCI272,
+ bustype: pci_bustype,
+ model: pci272_model,
+ layout: pc272_layout,
+ },
+#endif
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: DIO200_DRIVER_NAME,
+ devid: PCI_DEVICE_ID_INVALID,
+ bustype: pci_bustype,
+ model: anypci_model, /* wildcard */
+ },
+#endif
+};
+
+/*
+ * Layout descriptions - some ISA and PCI board descriptions share the same
+ * layout.
+ */
+
+enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254 };
+
+#define DIO200_MAX_SUBDEVS 7
+#define DIO200_MAX_ISNS 6
+
+struct dio200_layout_struct {
+ unsigned short n_subdevs; /* number of subdevices */
+ unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */
+ unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */
+ char has_int_sce; /* has interrupt enable/status register */
+ char has_clk_gat_sce; /* has clock/gate selection registers */
+};
+
+static const struct dio200_layout_struct dio200_layouts[] = {
+ [pc212_layout] = {
+ n_subdevs:6,
+ sdtype: {sd_8255, sd_8254, sd_8254, sd_8254,
+ sd_8254,
+ sd_intr},
+ sdinfo: {0x00, 0x08, 0x0C, 0x10, 0x14,
+ 0x3F},
+ has_int_sce:1,
+ has_clk_gat_sce:1,
+ },
+ [pc214_layout] = {
+ n_subdevs:4,
+ sdtype: {sd_8255, sd_8255, sd_8254,
+ sd_intr},
+ sdinfo: {0x00, 0x08, 0x10, 0x01},
+ has_int_sce:0,
+ has_clk_gat_sce:0,
+ },
+ [pc215_layout] = {
+ n_subdevs:5,
+ sdtype: {sd_8255, sd_8255, sd_8254,
+ sd_8254,
+ sd_intr},
+ sdinfo: {0x00, 0x08, 0x10, 0x14, 0x3F},
+ has_int_sce:1,
+ has_clk_gat_sce:1,
+ },
+ [pc218_layout] = {
+ n_subdevs:7,
+ sdtype: {sd_8254, sd_8254, sd_8255, sd_8254,
+ sd_8254,
+ sd_intr},
+ sdinfo: {0x00, 0x04, 0x08, 0x0C, 0x10,
+ 0x14,
+ 0x3F},
+ has_int_sce:1,
+ has_clk_gat_sce:1,
+ },
+ [pc272_layout] = {
+ n_subdevs:4,
+ sdtype: {sd_8255, sd_8255, sd_8255,
+ sd_intr},
+ sdinfo: {0x00, 0x08, 0x10, 0x3F},
+ has_int_sce:1,
+ has_clk_gat_sce:0,
+ },
+};
+
+/*
+ * PCI driver table.
+ */
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, dio200_pci_table);
+#endif /* CONFIG_COMEDI_PCI */
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct dio200_board *)dev->board_ptr)
+#define thislayout (&dio200_layouts[((struct dio200_board *)dev->board_ptr)->layout])
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct dio200_private {
+#ifdef CONFIG_COMEDI_PCI
+ struct pci_dev *pci_dev; /* PCI device */
+#endif
+ int intr_sd;
+};
+
+#define devpriv ((struct dio200_private *)dev->private)
+
+struct dio200_subdev_8254 {
+ unsigned long iobase; /* Counter base address */
+ unsigned long clk_sce_iobase; /* CLK_SCE base address */
+ unsigned long gat_sce_iobase; /* GAT_SCE base address */
+ int which; /* Bit 5 of CLK_SCE or GAT_SCE */
+ int has_clk_gat_sce;
+ unsigned clock_src[3]; /* Current clock sources */
+ unsigned gate_src[3]; /* Current gate sources */
+};
+
+struct dio200_subdev_intr {
+ unsigned long iobase;
+ spinlock_t spinlock;
+ int active;
+ int has_int_sce;
+ unsigned int valid_isns;
+ unsigned int enabled_isns;
+ unsigned int stopcount;
+ int continuous;
+};
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int dio200_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dio200_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_dio200 = {
+ driver_name:DIO200_DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:dio200_attach,
+ detach:dio200_detach,
+ board_name:&dio200_boards[0].name,
+ offset:sizeof(struct dio200_board),
+ num_names:sizeof(dio200_boards) / sizeof(struct dio200_board),
+};
+
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_amplc_dio200, dio200_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_amplc_dio200);
+#endif
+
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+#ifdef CONFIG_COMEDI_PCI
+static int
+dio200_find_pci(struct comedi_device * dev, int bus, int slot,
+ struct pci_dev **pci_dev_p)
+{
+ struct pci_dev *pci_dev = NULL;
+
+ *pci_dev_p = NULL;
+
+ /* Look for matching PCI device. */
+ for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+ pci_dev != NULL;
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
+ PCI_ANY_ID, pci_dev)) {
+ /* If bus/slot specified, check them. */
+ if (bus || slot) {
+ if (bus != pci_dev->bus->number
+ || slot != PCI_SLOT(pci_dev->devfn))
+ continue;
+ }
+ if (thisboard->model == anypci_model) {
+ /* Match any supported model. */
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) {
+ if (dio200_boards[i].bustype != pci_bustype)
+ continue;
+ if (pci_dev->device == dio200_boards[i].devid) {
+ /* Change board_ptr to matched board. */
+ dev->board_ptr = &dio200_boards[i];
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(dio200_boards))
+ continue;
+ } else {
+ /* Match specific model name. */
+ if (pci_dev->device != thisboard->devid)
+ continue;
+ }
+
+ /* Found a match. */
+ *pci_dev_p = pci_dev;
+ return 0;
+ }
+ /* No match found. */
+ if (bus || slot) {
+ printk(KERN_ERR
+ "comedi%d: error! no %s found at pci %02x:%02x!\n",
+ dev->minor, thisboard->name, bus, slot);
+ } else {
+ printk(KERN_ERR "comedi%d: error! no %s found!\n",
+ dev->minor, thisboard->name);
+ }
+ return -EIO;
+}
+#endif
+
+/*
+ * This function checks and requests an I/O region, reporting an error
+ * if there is a conflict.
+ */
+static int
+dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
+{
+ if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
+ printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
+ minor, from, extent);
+ return -EIO;
+ }
+ return 0;
+}
+
+/*
+ * 'insn_bits' function for an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_subdev_intr_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+
+ if (subpriv->has_int_sce) {
+ /* Just read the interrupt status register. */
+ data[1] = inb(subpriv->iobase) & subpriv->valid_isns;
+ } else {
+ /* No interrupt status register. */
+ data[0] = 0;
+ }
+
+ return 2;
+}
+
+/*
+ * Called to stop acquisition for an 'INTERRUPT' subdevice.
+ */
+static void dio200_stop_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+
+ subpriv->active = 0;
+ subpriv->enabled_isns = 0;
+ if (subpriv->has_int_sce) {
+ outb(0, subpriv->iobase);
+ }
+}
+
+/*
+ * Called to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int dio200_start_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned int n;
+ unsigned isn_bits;
+ struct dio200_subdev_intr *subpriv = s->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int retval = 0;
+
+ if (!subpriv->continuous && subpriv->stopcount == 0) {
+ /* An empty acquisition! */
+ s->async->events |= COMEDI_CB_EOA;
+ subpriv->active = 0;
+ retval = 1;
+ } else {
+ /* Determine interrupt sources to enable. */
+ isn_bits = 0;
+ if (cmd->chanlist) {
+ for (n = 0; n < cmd->chanlist_len; n++) {
+ isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
+ }
+ }
+ isn_bits &= subpriv->valid_isns;
+ /* Enable interrupt sources. */
+ subpriv->enabled_isns = isn_bits;
+ if (subpriv->has_int_sce) {
+ outb(isn_bits, subpriv->iobase);
+ }
+ }
+
+ return retval;
+}
+
+/*
+ * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_inttrig_start_intr(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ struct dio200_subdev_intr *subpriv;
+ unsigned long flags;
+ int event = 0;
+
+ if (trignum != 0)
+ return -EINVAL;
+
+ subpriv = s->private;
+
+ comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
+ s->async->inttrig = 0;
+ if (subpriv->active) {
+ event = dio200_start_intr(dev, s);
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+ if (event) {
+ comedi_event(dev, s);
+ }
+
+ return 1;
+}
+
+/*
+ * This is called from the interrupt service routine to handle a read
+ * scan on an 'INTERRUPT' subdevice.
+ */
+static int dio200_handle_read_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+ unsigned triggered;
+ unsigned intstat;
+ unsigned cur_enabled;
+ unsigned int oldevents;
+ unsigned long flags;
+
+ triggered = 0;
+
+ comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
+ oldevents = s->async->events;
+ if (subpriv->has_int_sce) {
+ /*
+ * Collect interrupt sources that have triggered and disable
+ * them temporarily. Loop around until no extra interrupt
+ * sources have triggered, at which point, the valid part of
+ * the interrupt status register will read zero, clearing the
+ * cause of the interrupt.
+ *
+ * Mask off interrupt sources already seen to avoid infinite
+ * loop in case of misconfiguration.
+ */
+ cur_enabled = subpriv->enabled_isns;
+ while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns
+ & ~triggered)) != 0) {
+ triggered |= intstat;
+ cur_enabled &= ~triggered;
+ outb(cur_enabled, subpriv->iobase);
+ }
+ } else {
+ /*
+ * No interrupt status register. Assume the single interrupt
+ * source has triggered.
+ */
+ triggered = subpriv->enabled_isns;
+ }
+
+ if (triggered) {
+ /*
+ * Some interrupt sources have triggered and have been
+ * temporarily disabled to clear the cause of the interrupt.
+ *
+ * Reenable them NOW to minimize the time they are disabled.
+ */
+ cur_enabled = subpriv->enabled_isns;
+ if (subpriv->has_int_sce) {
+ outb(cur_enabled, subpriv->iobase);
+ }
+
+ if (subpriv->active) {
+ /*
+ * The command is still active.
+ *
+ * Ignore interrupt sources that the command isn't
+ * interested in (just in case there's a race
+ * condition).
+ */
+ if (triggered & subpriv->enabled_isns) {
+ /* Collect scan data. */
+ short val;
+ unsigned int n, ch, len;
+
+ val = 0;
+ len = s->async->cmd.chanlist_len;
+ for (n = 0; n < len; n++) {
+ ch = CR_CHAN(s->async->cmd.chanlist[n]);
+ if (triggered & (1U << ch)) {
+ val |= (1U << n);
+ }
+ }
+ /* Write the scan to the buffer. */
+ if (comedi_buf_put(s->async, val)) {
+ s->async->events |= (COMEDI_CB_BLOCK |
+ COMEDI_CB_EOS);
+ } else {
+ /* Error! Stop acquisition. */
+ dio200_stop_intr(dev, s);
+ s->async->events |= COMEDI_CB_ERROR
+ | COMEDI_CB_OVERFLOW;
+ comedi_error(dev, "buffer overflow");
+ }
+
+ /* Check for end of acquisition. */
+ if (!subpriv->continuous) {
+ /* stop_src == TRIG_COUNT */
+ if (subpriv->stopcount > 0) {
+ subpriv->stopcount--;
+ if (subpriv->stopcount == 0) {
+ s->async->events |=
+ COMEDI_CB_EOA;
+ dio200_stop_intr(dev,
+ s);
+ }
+ }
+ }
+ }
+ }
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+ if (oldevents != s->async->events) {
+ comedi_event(dev, s);
+ }
+
+ return (triggered != 0);
+}
+
+/*
+ * 'cancel' function for an 'INTERRUPT' subdevice.
+ */
+static int dio200_subdev_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
+ if (subpriv->active) {
+ dio200_stop_intr(dev, s);
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+ return 0;
+}
+
+/*
+ * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_subdev_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= (TRIG_NOW | TRIG_INT);
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* these tests are true if more than one _src bit is set */
+ if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+ err++;
+ if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+ err++;
+ if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_begin_src == TRIG_EXT */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ /* cmd->convert_src == TRIG_NOW */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_end_src == TRIG_COUNT */
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ /* any count allowed */
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ /* if (err) return 4; */
+
+ return 0;
+}
+
+/*
+ * 'do_cmd' function for an 'INTERRUPT' subdevice.
+ */
+static int dio200_subdev_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ struct dio200_subdev_intr *subpriv = s->private;
+ unsigned long flags;
+ int event = 0;
+
+ comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
+ subpriv->active = 1;
+
+ /* Set up end of acquisition. */
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ subpriv->continuous = 0;
+ subpriv->stopcount = cmd->stop_arg;
+ break;
+ default:
+ /* TRIG_NONE */
+ subpriv->continuous = 1;
+ subpriv->stopcount = 0;
+ break;
+ }
+
+ /* Set up start of acquisition. */
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ s->async->inttrig = dio200_inttrig_start_intr;
+ break;
+ default:
+ /* TRIG_NOW */
+ event = dio200_start_intr(dev, s);
+ break;
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+ if (event) {
+ comedi_event(dev, s);
+ }
+
+ return 0;
+}
+
+/*
+ * This function initializes an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_subdev_intr_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long iobase, unsigned valid_isns, int has_int_sce)
+{
+ struct dio200_subdev_intr *subpriv;
+
+ subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
+ if (!subpriv) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return -ENOMEM;
+ }
+ subpriv->iobase = iobase;
+ subpriv->has_int_sce = has_int_sce;
+ subpriv->valid_isns = valid_isns;
+ spin_lock_init(&subpriv->spinlock);
+
+ if (has_int_sce) {
+ outb(0, subpriv->iobase); /* Disable interrupt sources. */
+ }
+
+ s->private = subpriv;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ if (has_int_sce) {
+ s->n_chan = DIO200_MAX_ISNS;
+ s->len_chanlist = DIO200_MAX_ISNS;
+ } else {
+ /* No interrupt source register. Support single channel. */
+ s->n_chan = 1;
+ s->len_chanlist = 1;
+ }
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_bits = dio200_subdev_intr_insn_bits;
+ s->do_cmdtest = dio200_subdev_intr_cmdtest;
+ s->do_cmd = dio200_subdev_intr_cmd;
+ s->cancel = dio200_subdev_intr_cancel;
+
+ return 0;
+}
+
+/*
+ * This function cleans up an 'INTERRUPT' subdevice.
+ */
+static void
+dio200_subdev_intr_cleanup(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+
+ if (subpriv) {
+ kfree(subpriv);
+ }
+}
+
+/*
+ * Interrupt service routine.
+ */
+static irqreturn_t dio200_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ int handled;
+
+ if (!dev->attached) {
+ return IRQ_NONE;
+ }
+
+ if (devpriv->intr_sd >= 0) {
+ handled = dio200_handle_read_intr(dev,
+ dev->subdevices + devpriv->intr_sd);
+ } else {
+ handled = 0;
+ }
+
+ return IRQ_RETVAL(handled);
+}
+
+/*
+ * Handle 'insn_read' for an '8254' counter subdevice.
+ */
+static int
+dio200_subdev_8254_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+ int chan = CR_CHAN(insn->chanspec);
+
+ data[0] = i8254_read(subpriv->iobase, 0, chan);
+
+ return 1;
+}
+
+/*
+ * Handle 'insn_write' for an '8254' counter subdevice.
+ */
+static int
+dio200_subdev_8254_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+ int chan = CR_CHAN(insn->chanspec);
+
+ i8254_write(subpriv->iobase, 0, chan, data[0]);
+
+ return 1;
+}
+
+/*
+ * Set gate source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_set_gate_src(struct dio200_subdev_8254 * subpriv, unsigned int counter_number,
+ unsigned int gate_src)
+{
+ unsigned char byte;
+
+ if (!subpriv->has_clk_gat_sce)
+ return -1;
+ if (counter_number > 2)
+ return -1;
+ if (gate_src > 7)
+ return -1;
+
+ subpriv->gate_src[counter_number] = gate_src;
+ byte = GAT_SCE(subpriv->which, counter_number, gate_src);
+ outb(byte, subpriv->gat_sce_iobase);
+
+ return 0;
+}
+
+/*
+ * Get gate source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_get_gate_src(struct dio200_subdev_8254 * subpriv, unsigned int counter_number)
+{
+ if (!subpriv->has_clk_gat_sce)
+ return -1;
+ if (counter_number > 2)
+ return -1;
+
+ return subpriv->gate_src[counter_number];
+}
+
+/*
+ * Set clock source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_set_clock_src(struct dio200_subdev_8254 * subpriv, unsigned int counter_number,
+ unsigned int clock_src)
+{
+ unsigned char byte;
+
+ if (!subpriv->has_clk_gat_sce)
+ return -1;
+ if (counter_number > 2)
+ return -1;
+ if (clock_src > 7)
+ return -1;
+
+ subpriv->clock_src[counter_number] = clock_src;
+ byte = CLK_SCE(subpriv->which, counter_number, clock_src);
+ outb(byte, subpriv->clk_sce_iobase);
+
+ return 0;
+}
+
+/*
+ * Get clock source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_get_clock_src(struct dio200_subdev_8254 * subpriv, unsigned int counter_number,
+ unsigned int * period_ns)
+{
+ unsigned clock_src;
+
+ if (!subpriv->has_clk_gat_sce)
+ return -1;
+ if (counter_number > 2)
+ return -1;
+
+ clock_src = subpriv->clock_src[counter_number];
+ *period_ns = clock_period[clock_src];
+ return clock_src;
+}
+
+/*
+ * Handle 'insn_config' for an '8254' counter subdevice.
+ */
+static int
+dio200_subdev_8254_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+ int ret;
+ int chan = CR_CHAN(insn->chanspec);
+
+ switch (data[0]) {
+ case INSN_CONFIG_SET_COUNTER_MODE:
+ ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]);
+ if (ret < 0)
+ return -EINVAL;
+ break;
+ case INSN_CONFIG_8254_READ_STATUS:
+ data[1] = i8254_status(subpriv->iobase, 0, chan);
+ break;
+ case INSN_CONFIG_SET_GATE_SRC:
+ ret = dio200_set_gate_src(subpriv, chan, data[2]);
+ if (ret < 0)
+ return -EINVAL;
+ break;
+ case INSN_CONFIG_GET_GATE_SRC:
+ ret = dio200_get_gate_src(subpriv, chan);
+ if (ret < 0)
+ return -EINVAL;
+ data[2] = ret;
+ break;
+ case INSN_CONFIG_SET_CLOCK_SRC:
+ ret = dio200_set_clock_src(subpriv, chan, data[1]);
+ if (ret < 0)
+ return -EINVAL;
+ break;
+ case INSN_CONFIG_GET_CLOCK_SRC:
+ ret = dio200_get_clock_src(subpriv, chan, &data[2]);
+ if (ret < 0)
+ return -EINVAL;
+ data[1] = ret;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return insn->n;
+}
+
+/*
+ * This function initializes an '8254' counter subdevice.
+ *
+ * Note: iobase is the base address of the board, not the subdevice;
+ * offset is the offset to the 8254 chip.
+ */
+static int
+dio200_subdev_8254_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long iobase, unsigned offset, int has_clk_gat_sce)
+{
+ struct dio200_subdev_8254 *subpriv;
+ unsigned int chan;
+
+ subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
+ if (!subpriv) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return -ENOMEM;
+ }
+
+ s->private = subpriv;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 3;
+ s->maxdata = 0xFFFF;
+ s->insn_read = dio200_subdev_8254_read;
+ s->insn_write = dio200_subdev_8254_write;
+ s->insn_config = dio200_subdev_8254_config;
+
+ subpriv->iobase = offset + iobase;
+ subpriv->has_clk_gat_sce = has_clk_gat_sce;
+ if (has_clk_gat_sce) {
+ /* Derive CLK_SCE and GAT_SCE register offsets from
+ * 8254 offset. */
+ subpriv->clk_sce_iobase =
+ DIO200_XCLK_SCE + (offset >> 3) + iobase;
+ subpriv->gat_sce_iobase =
+ DIO200_XGAT_SCE + (offset >> 3) + iobase;
+ subpriv->which = (offset >> 2) & 1;
+ }
+
+ /* Initialize channels. */
+ for (chan = 0; chan < 3; chan++) {
+ i8254_set_mode(subpriv->iobase, 0, chan,
+ I8254_MODE0 | I8254_BINARY);
+ if (subpriv->has_clk_gat_sce) {
+ /* Gate source 0 is VCC (logic 1). */
+ dio200_set_gate_src(subpriv, chan, 0);
+ /* Clock source 0 is the dedicated clock input. */
+ dio200_set_clock_src(subpriv, chan, 0);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * This function cleans up an '8254' counter subdevice.
+ */
+static void
+dio200_subdev_8254_cleanup(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+
+ if (subpriv) {
+ kfree(subpriv);
+ }
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int dio200_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = 0;
+ unsigned int irq = 0;
+#ifdef CONFIG_COMEDI_PCI
+ struct pci_dev *pci_dev = NULL;
+ int bus = 0, slot = 0;
+#endif
+ const struct dio200_layout_struct *layout;
+ int share_irq = 0;
+ int sdx;
+ unsigned n;
+ int ret;
+
+ printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
+ DIO200_DRIVER_NAME);
+
+ if ((ret = alloc_private(dev, sizeof(struct dio200_private))) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+
+ /* Process options. */
+ switch (thisboard->bustype) {
+ case isa_bustype:
+ iobase = it->options[0];
+ irq = it->options[1];
+ share_irq = 0;
+ break;
+#ifdef CONFIG_COMEDI_PCI
+ case pci_bustype:
+ bus = it->options[0];
+ slot = it->options[1];
+ share_irq = 1;
+
+ if ((ret = dio200_find_pci(dev, bus, slot, &pci_dev)) < 0)
+ return ret;
+ devpriv->pci_dev = pci_dev;
+ break;
+#endif
+ default:
+ printk(KERN_ERR
+ "comedi%d: %s: BUG! cannot determine board type!\n",
+ dev->minor, DIO200_DRIVER_NAME);
+ return -EINVAL;
+ break;
+ }
+
+ devpriv->intr_sd = -1;
+
+ /* Enable device and reserve I/O spaces. */
+#ifdef CONFIG_COMEDI_PCI
+ if (pci_dev) {
+ ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "comedi%d: error! cannot enable PCI device and request regions!\n",
+ dev->minor);
+ return ret;
+ }
+ iobase = pci_resource_start(pci_dev, 2);
+ irq = pci_dev->irq;
+ } else
+#endif
+ {
+ ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+ dev->iobase = iobase;
+
+ layout = thislayout;
+ if ((ret = alloc_subdevices(dev, layout->n_subdevs)) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+
+ for (n = 0; n < dev->n_subdevices; n++) {
+ s = &dev->subdevices[n];
+ switch (layout->sdtype[n]) {
+ case sd_8254:
+ /* counter subdevice (8254) */
+ ret = dio200_subdev_8254_init(dev, s, iobase,
+ layout->sdinfo[n], layout->has_clk_gat_sce);
+ if (ret < 0) {
+ return ret;
+ }
+ break;
+ case sd_8255:
+ /* digital i/o subdevice (8255) */
+ ret = subdev_8255_init(dev, s, 0,
+ iobase + layout->sdinfo[n]);
+ if (ret < 0) {
+ return ret;
+ }
+ break;
+ case sd_intr:
+ /* 'INTERRUPT' subdevice */
+ if (irq) {
+ ret = dio200_subdev_intr_init(dev, s,
+ iobase + DIO200_INT_SCE,
+ layout->sdinfo[n], layout->has_int_sce);
+ if (ret < 0) {
+ return ret;
+ }
+ devpriv->intr_sd = n;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ break;
+ default:
+ s->type = COMEDI_SUBD_UNUSED;
+ break;
+ }
+ }
+
+ sdx = devpriv->intr_sd;
+ if (sdx >= 0 && sdx < dev->n_subdevices) {
+ dev->read_subdev = &dev->subdevices[sdx];
+ }
+
+ dev->board_name = thisboard->name;
+
+ if (irq) {
+ unsigned long flags = share_irq ? IRQF_SHARED : 0;
+
+ if (comedi_request_irq(irq, dio200_interrupt, flags,
+ DIO200_DRIVER_NAME, dev) >= 0) {
+ dev->irq = irq;
+ } else {
+ printk(KERN_WARNING
+ "comedi%d: warning! irq %u unavailable!\n",
+ dev->minor, irq);
+ }
+ }
+
+ printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
+ if (thisboard->bustype == isa_bustype) {
+ printk("(base %#lx) ", iobase);
+ } else {
+#ifdef CONFIG_COMEDI_PCI
+ printk("(pci %s) ", pci_name(pci_dev));
+#endif
+ }
+ if (irq) {
+ printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
+ } else {
+ printk("(no irq) ");
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int dio200_detach(struct comedi_device * dev)
+{
+ const struct dio200_layout_struct *layout;
+ unsigned n;
+
+ printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
+ DIO200_DRIVER_NAME);
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (dev->subdevices) {
+ layout = thislayout;
+ for (n = 0; n < dev->n_subdevices; n++) {
+ struct comedi_subdevice *s = &dev->subdevices[n];
+ switch (layout->sdtype[n]) {
+ case sd_8254:
+ dio200_subdev_8254_cleanup(dev, s);
+ break;
+ case sd_8255:
+ subdev_8255_cleanup(dev, s);
+ break;
+ case sd_intr:
+ dio200_subdev_intr_cleanup(dev, s);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if (devpriv) {
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ } else
+#endif
+ {
+ if (dev->iobase) {
+ release_region(dev->iobase, DIO200_IO_SIZE);
+ }
+ }
+ }
+ if (dev->board_name) {
+ printk(KERN_INFO "comedi%d: %s removed\n",
+ dev->minor, dev->board_name);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c
new file mode 100644
index 00000000000..2027c75feac
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pc236.c
@@ -0,0 +1,654 @@
+/*
+ comedi/drivers/amplc_pc236.c
+ Driver for Amplicon PC36AT and PCI236 DIO boards.
+
+ Copyright (C) 2002 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: amplc_pc236
+Description: Amplicon PC36AT, PCI236
+Author: Ian Abbott <abbotti@mev.co.uk>
+Devices: [Amplicon] PC36AT (pc36at), PCI236 (pci236 or amplc_pc236)
+Updated: Wed, 22 Oct 2008 13:40:03 +0100
+Status: works
+
+Configuration options - PC36AT:
+ [0] - I/O port base address
+ [1] - IRQ (optional)
+
+Configuration options - PCI236:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI device will be
+ used.
+
+The PC36AT ISA board and PCI236 PCI board have a single 8255 appearing
+as subdevice 0.
+
+Subdevice 1 pretends to be a digital input device, but it always returns
+0 when read. However, if you run a command with scan_begin_src=TRIG_EXT,
+a rising edge on port C bit 7 acts as an external trigger, which can be
+used to wake up tasks. This is like the comedi_parport device, but the
+only way to physically disable the interrupt on the PC36AT is to remove
+the IRQ jumper. If no interrupt is connected, then subdevice 1 is
+unused.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "8255.h"
+#include "plx9052.h"
+
+#define PC236_DRIVER_NAME "amplc_pc236"
+
+/* PCI236 PCI configuration register information */
+#define PCI_VENDOR_ID_AMPLICON 0x14dc
+#define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+/* PC36AT / PCI236 registers */
+
+#define PC236_IO_SIZE 4
+#define PC236_LCR_IO_SIZE 128
+
+/*
+ * INTCSR values for PCI236.
+ */
+/* Disable interrupt, also clear any interrupt there */
+#define PCI236_INTR_DISABLE ( PLX9052_INTCSR_LI1ENAB_DISABLED \
+ | PLX9052_INTCSR_LI1POL_HIGH \
+ | PLX9052_INTCSR_LI2POL_HIGH \
+ | PLX9052_INTCSR_PCIENAB_DISABLED \
+ | PLX9052_INTCSR_LI1SEL_EDGE \
+ | PLX9052_INTCSR_LI1CLRINT_ASSERTED )
+/* Enable interrupt, also clear any interrupt there. */
+#define PCI236_INTR_ENABLE ( PLX9052_INTCSR_LI1ENAB_ENABLED \
+ | PLX9052_INTCSR_LI1POL_HIGH \
+ | PLX9052_INTCSR_LI2POL_HIGH \
+ | PLX9052_INTCSR_PCIENAB_ENABLED \
+ | PLX9052_INTCSR_LI1SEL_EDGE \
+ | PLX9052_INTCSR_LI1CLRINT_ASSERTED )
+
+/*
+ * Board descriptions for Amplicon PC36AT and PCI236.
+ */
+
+enum pc236_bustype { isa_bustype, pci_bustype };
+enum pc236_model { pc36at_model, pci236_model, anypci_model };
+
+struct pc236_board {
+ const char *name;
+ const char *fancy_name;
+ unsigned short devid;
+ enum pc236_bustype bustype;
+ enum pc236_model model;
+};
+static const struct pc236_board pc236_boards[] = {
+ {
+ name: "pc36at",
+ fancy_name:"PC36AT",
+ bustype: isa_bustype,
+ model: pc36at_model,
+ },
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: "pci236",
+ fancy_name:"PCI236",
+ devid: PCI_DEVICE_ID_AMPLICON_PCI236,
+ bustype: pci_bustype,
+ model: pci236_model,
+ },
+#endif
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: PC236_DRIVER_NAME,
+ fancy_name:PC236_DRIVER_NAME,
+ devid: PCI_DEVICE_ID_INVALID,
+ bustype: pci_bustype,
+ model: anypci_model, /* wildcard */
+ },
+#endif
+};
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = {
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236, PCI_ANY_ID,
+ PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pc236_pci_table);
+#endif /* CONFIG_COMEDI_PCI */
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pc236_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct pc236_private {
+#ifdef CONFIG_COMEDI_PCI
+ /* PCI device */
+ struct pci_dev *pci_dev;
+ unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
+#endif
+ int enable_irq;
+};
+
+#define devpriv ((struct pc236_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pc236_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pc236_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_pc236 = {
+ driver_name:PC236_DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:pc236_attach,
+ detach:pc236_detach,
+ board_name:&pc236_boards[0].name,
+ offset:sizeof(struct pc236_board),
+ num_names:sizeof(pc236_boards) / sizeof(struct pc236_board),
+};
+
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_amplc_pc236, pc236_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_amplc_pc236);
+#endif
+
+static int pc236_request_region(unsigned minor, unsigned long from,
+ unsigned long extent);
+static void pc236_intr_disable(struct comedi_device * dev);
+static void pc236_intr_enable(struct comedi_device * dev);
+static int pc236_intr_check(struct comedi_device * dev);
+static int pc236_intr_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pc236_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int pc236_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pc236_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t pc236_interrupt(int irq, void *d PT_REGS_ARG);
+
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+#ifdef CONFIG_COMEDI_PCI
+static int
+pc236_find_pci(struct comedi_device * dev, int bus, int slot,
+ struct pci_dev **pci_dev_p)
+{
+ struct pci_dev *pci_dev = NULL;
+
+ *pci_dev_p = NULL;
+
+ /* Look for matching PCI device. */
+ for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+ pci_dev != NULL;
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
+ PCI_ANY_ID, pci_dev)) {
+ /* If bus/slot specified, check them. */
+ if (bus || slot) {
+ if (bus != pci_dev->bus->number
+ || slot != PCI_SLOT(pci_dev->devfn))
+ continue;
+ }
+ if (thisboard->model == anypci_model) {
+ /* Match any supported model. */
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pc236_boards); i++) {
+ if (pc236_boards[i].bustype != pci_bustype)
+ continue;
+ if (pci_dev->device == pc236_boards[i].devid) {
+ /* Change board_ptr to matched board. */
+ dev->board_ptr = &pc236_boards[i];
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(pc236_boards))
+ continue;
+ } else {
+ /* Match specific model name. */
+ if (pci_dev->device != thisboard->devid)
+ continue;
+ }
+
+ /* Found a match. */
+ *pci_dev_p = pci_dev;
+ return 0;
+ }
+ /* No match found. */
+ if (bus || slot) {
+ printk(KERN_ERR
+ "comedi%d: error! no %s found at pci %02x:%02x!\n",
+ dev->minor, thisboard->name, bus, slot);
+ } else {
+ printk(KERN_ERR "comedi%d: error! no %s found!\n",
+ dev->minor, thisboard->name);
+ }
+ return -EIO;
+}
+#endif
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pc236_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = 0;
+ unsigned int irq = 0;
+#ifdef CONFIG_COMEDI_PCI
+ struct pci_dev *pci_dev = NULL;
+ int bus = 0, slot = 0;
+#endif
+ int share_irq = 0;
+ int ret;
+
+ printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
+ PC236_DRIVER_NAME);
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if ((ret = alloc_private(dev, sizeof(struct pc236_private))) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+ /* Process options. */
+ switch (thisboard->bustype) {
+ case isa_bustype:
+ iobase = it->options[0];
+ irq = it->options[1];
+ share_irq = 0;
+ break;
+#ifdef CONFIG_COMEDI_PCI
+ case pci_bustype:
+ bus = it->options[0];
+ slot = it->options[1];
+ share_irq = 1;
+
+ if ((ret = pc236_find_pci(dev, bus, slot, &pci_dev)) < 0)
+ return ret;
+ devpriv->pci_dev = pci_dev;
+ break;
+#endif /* CONFIG_COMEDI_PCI */
+ default:
+ printk(KERN_ERR
+ "comedi%d: %s: BUG! cannot determine board type!\n",
+ dev->minor, PC236_DRIVER_NAME);
+ return -EINVAL;
+ break;
+ }
+
+/*
+ * Initialize dev->board_name.
+ */
+ dev->board_name = thisboard->name;
+
+ /* Enable device and reserve I/O spaces. */
+#ifdef CONFIG_COMEDI_PCI
+ if (pci_dev) {
+ if ((ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME)) < 0) {
+ printk(KERN_ERR
+ "comedi%d: error! cannot enable PCI device and request regions!\n",
+ dev->minor);
+ return ret;
+ }
+ devpriv->lcr_iobase = pci_resource_start(pci_dev, 1);
+ iobase = pci_resource_start(pci_dev, 2);
+ irq = pci_dev->irq;
+ } else
+#endif
+ {
+ ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+ dev->iobase = iobase;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if ((ret = alloc_subdevices(dev, 2)) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+
+ s = dev->subdevices + 0;
+ /* digital i/o subdevice (8255) */
+ if ((ret = subdev_8255_init(dev, s, NULL, iobase)) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+ s = dev->subdevices + 1;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_UNUSED;
+ pc236_intr_disable(dev);
+ if (irq) {
+ unsigned long flags = share_irq ? IRQF_SHARED : 0;
+
+ if (comedi_request_irq(irq, pc236_interrupt, flags,
+ PC236_DRIVER_NAME, dev) >= 0) {
+ dev->irq = irq;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = 1;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = pc236_intr_insn;
+ s->do_cmdtest = pc236_intr_cmdtest;
+ s->do_cmd = pc236_intr_cmd;
+ s->cancel = pc236_intr_cancel;
+ }
+ }
+ printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
+ if (thisboard->bustype == isa_bustype) {
+ printk("(base %#lx) ", iobase);
+ } else {
+#ifdef CONFIG_COMEDI_PCI
+ printk("(pci %s) ", pci_name(pci_dev));
+#endif
+ }
+ if (irq) {
+ printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
+ } else {
+ printk("(no irq) ");
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pc236_detach(struct comedi_device * dev)
+{
+ printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
+ PC236_DRIVER_NAME);
+ if (devpriv) {
+ pc236_intr_disable(dev);
+ }
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (dev->subdevices) {
+ subdev_8255_cleanup(dev, dev->subdevices + 0);
+ }
+ if (devpriv) {
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ } else
+#endif
+ {
+ if (dev->iobase) {
+ release_region(dev->iobase, PC236_IO_SIZE);
+ }
+ }
+ }
+ if (dev->board_name) {
+ printk(KERN_INFO "comedi%d: %s removed\n",
+ dev->minor, dev->board_name);
+ }
+ return 0;
+}
+
+/*
+ * This function checks and requests an I/O region, reporting an error
+ * if there is a conflict.
+ */
+static int pc236_request_region(unsigned minor, unsigned long from,
+ unsigned long extent)
+{
+ if (!from || !request_region(from, extent, PC236_DRIVER_NAME)) {
+ printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
+ minor, from, extent);
+ return -EIO;
+ }
+ return 0;
+}
+
+/*
+ * This function is called to mark the interrupt as disabled (no command
+ * configured on subdevice 1) and to physically disable the interrupt
+ * (not possible on the PC36AT, except by removing the IRQ jumper!).
+ */
+static void pc236_intr_disable(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->enable_irq = 0;
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->lcr_iobase)
+ outl(PCI236_INTR_DISABLE, devpriv->lcr_iobase + PLX9052_INTCSR);
+#endif
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+/*
+ * This function is called to mark the interrupt as enabled (a command
+ * configured on subdevice 1) and to physically enable the interrupt
+ * (not possible on the PC36AT, except by (re)connecting the IRQ jumper!).
+ */
+static void pc236_intr_enable(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->enable_irq = 1;
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->lcr_iobase)
+ outl(PCI236_INTR_ENABLE, devpriv->lcr_iobase + PLX9052_INTCSR);
+#endif
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+/*
+ * This function is called when an interrupt occurs to check whether
+ * the interrupt has been marked as enabled and was generated by the
+ * board. If so, the function prepares the hardware for the next
+ * interrupt.
+ * Returns 0 if the interrupt should be ignored.
+ */
+static int pc236_intr_check(struct comedi_device * dev)
+{
+ int retval = 0;
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ if (devpriv->enable_irq) {
+ retval = 1;
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->lcr_iobase) {
+ if ((inl(devpriv->lcr_iobase + PLX9052_INTCSR)
+ & PLX9052_INTCSR_LI1STAT_MASK)
+ == PLX9052_INTCSR_LI1STAT_INACTIVE) {
+ retval = 0;
+ } else {
+ /* Clear interrupt and keep it enabled. */
+ outl(PCI236_INTR_ENABLE,
+ devpriv->lcr_iobase + PLX9052_INTCSR);
+ }
+ }
+#endif
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return retval;
+}
+
+/*
+ * Input from subdevice 1.
+ * Copied from the comedi_parport driver.
+ */
+static int pc236_intr_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[1] = 0;
+ return 2;
+}
+
+/*
+ * Subdevice 1 command test.
+ * Copied from the comedi_parport driver.
+ */
+static int pc236_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1 */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_FOLLOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: ignored */
+
+ if (err)
+ return 2;
+
+ /* step 3: */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ if (cmd->scan_end_arg != 1) {
+ cmd->scan_end_arg = 1;
+ err++;
+ }
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: ignored */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+/*
+ * Subdevice 1 command.
+ */
+static int pc236_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ pc236_intr_enable(dev);
+
+ return 0;
+}
+
+/*
+ * Subdevice 1 cancel command.
+ */
+static int pc236_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ pc236_intr_disable(dev);
+
+ return 0;
+}
+
+/*
+ * Interrupt service routine.
+ * Based on the comedi_parport driver.
+ */
+static irqreturn_t pc236_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 1;
+ int handled;
+
+ handled = pc236_intr_check(dev);
+ if (dev->attached && handled) {
+ comedi_buf_put(s->async, 0);
+ s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+ comedi_event(dev, s);
+ }
+ return IRQ_RETVAL(handled);
+}
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c
new file mode 100644
index 00000000000..97ac4157ada
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pc263.c
@@ -0,0 +1,431 @@
+/*
+ comedi/drivers/amplc_pc263.c
+ Driver for Amplicon PC263 and PCI263 relay boards.
+
+ Copyright (C) 2002 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: amplc_pc263
+Description: Amplicon PC263, PCI263
+Author: Ian Abbott <abbotti@mev.co.uk>
+Devices: [Amplicon] PC263 (pc263), PCI263 (pci263 or amplc_pc263)
+Updated: Wed, 22 Oct 2008 14:10:53 +0100
+Status: works
+
+Configuration options - PC263:
+ [0] - I/O port base address
+
+Configuration options - PCI263:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI device will be
+ used.
+
+Each board appears as one subdevice, with 16 digital outputs, each
+connected to a reed-relay. Relay contacts are closed when output is 1.
+The state of the outputs can be read.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#define PC263_DRIVER_NAME "amplc_pc263"
+
+/* PCI263 PCI configuration register information */
+#define PCI_VENDOR_ID_AMPLICON 0x14dc
+#define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+/* PC263 / PCI263 registers */
+#define PC263_IO_SIZE 2
+
+/*
+ * Board descriptions for Amplicon PC263 / PCI263.
+ */
+
+enum pc263_bustype { isa_bustype, pci_bustype };
+enum pc263_model { pc263_model, pci263_model, anypci_model };
+
+struct pc263_board {
+ const char *name;
+ const char *fancy_name;
+ unsigned short devid;
+ enum pc263_bustype bustype;
+ enum pc263_model model;
+};
+static const struct pc263_board pc263_boards[] = {
+ {
+ name: "pc263",
+ fancy_name:"PC263",
+ bustype: isa_bustype,
+ model: pc263_model,
+ },
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: "pci263",
+ fancy_name:"PCI263",
+ devid: PCI_DEVICE_ID_AMPLICON_PCI263,
+ bustype: pci_bustype,
+ model: pci263_model,
+ },
+#endif
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: PC263_DRIVER_NAME,
+ fancy_name:PC263_DRIVER_NAME,
+ devid: PCI_DEVICE_ID_INVALID,
+ bustype: pci_bustype,
+ model: anypci_model, /* wildcard */
+ },
+#endif
+};
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = {
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263, PCI_ANY_ID,
+ PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pc263_pci_table);
+#endif /* CONFIG_COMEDI_PCI */
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pc263_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+#ifdef CONFIG_COMEDI_PCI
+struct pc263_private {
+ /* PCI device. */
+ struct pci_dev *pci_dev;
+};
+
+#define devpriv ((struct pc263_private *)dev->private)
+#endif /* CONFIG_COMEDI_PCI */
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pc263_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pc263_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_pc263 = {
+ driver_name:PC263_DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:pc263_attach,
+ detach:pc263_detach,
+ board_name:&pc263_boards[0].name,
+ offset:sizeof(struct pc263_board),
+ num_names:sizeof(pc263_boards) / sizeof(struct pc263_board),
+};
+
+static int pc263_request_region(unsigned minor, unsigned long from,
+ unsigned long extent);
+static int pc263_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pc263_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+#ifdef CONFIG_COMEDI_PCI
+static int
+pc263_find_pci(struct comedi_device * dev, int bus, int slot,
+ struct pci_dev **pci_dev_p)
+{
+ struct pci_dev *pci_dev = NULL;
+
+ *pci_dev_p = NULL;
+
+ /* Look for matching PCI device. */
+ for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+ pci_dev != NULL;
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
+ PCI_ANY_ID, pci_dev)) {
+ /* If bus/slot specified, check them. */
+ if (bus || slot) {
+ if (bus != pci_dev->bus->number
+ || slot != PCI_SLOT(pci_dev->devfn))
+ continue;
+ }
+ if (thisboard->model == anypci_model) {
+ /* Match any supported model. */
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pc263_boards); i++) {
+ if (pc263_boards[i].bustype != pci_bustype)
+ continue;
+ if (pci_dev->device == pc263_boards[i].devid) {
+ /* Change board_ptr to matched board. */
+ dev->board_ptr = &pc263_boards[i];
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(pc263_boards))
+ continue;
+ } else {
+ /* Match specific model name. */
+ if (pci_dev->device != thisboard->devid)
+ continue;
+ }
+
+ /* Found a match. */
+ *pci_dev_p = pci_dev;
+ return 0;
+ }
+ /* No match found. */
+ if (bus || slot) {
+ printk(KERN_ERR
+ "comedi%d: error! no %s found at pci %02x:%02x!\n",
+ dev->minor, thisboard->name, bus, slot);
+ } else {
+ printk(KERN_ERR "comedi%d: error! no %s found!\n",
+ dev->minor, thisboard->name);
+ }
+ return -EIO;
+}
+#endif
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pc263_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = 0;
+#ifdef CONFIG_COMEDI_PCI
+ struct pci_dev *pci_dev = NULL;
+ int bus = 0, slot = 0;
+#endif
+ int ret;
+
+ printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
+ PC263_DRIVER_NAME);
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+#ifdef CONFIG_COMEDI_PCI
+ if ((ret = alloc_private(dev, sizeof(struct pc263_private))) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+#endif
+ /* Process options. */
+ switch (thisboard->bustype) {
+ case isa_bustype:
+ iobase = it->options[0];
+ break;
+#ifdef CONFIG_COMEDI_PCI
+ case pci_bustype:
+ bus = it->options[0];
+ slot = it->options[1];
+
+ if ((ret = pc263_find_pci(dev, bus, slot, &pci_dev)) < 0)
+ return ret;
+ devpriv->pci_dev = pci_dev;
+ break;
+#endif /* CONFIG_COMEDI_PCI */
+ default:
+ printk(KERN_ERR
+ "comedi%d: %s: BUG! cannot determine board type!\n",
+ dev->minor, PC263_DRIVER_NAME);
+ return -EINVAL;
+ break;
+ }
+
+/*
+ * Initialize dev->board_name.
+ */
+ dev->board_name = thisboard->name;
+
+ /* Enable device and reserve I/O spaces. */
+#ifdef CONFIG_COMEDI_PCI
+ if (pci_dev) {
+ if ((ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME)) < 0) {
+ printk(KERN_ERR
+ "comedi%d: error! cannot enable PCI device and request regions!\n",
+ dev->minor);
+ return ret;
+ }
+ iobase = pci_resource_start(pci_dev, 2);
+ } else
+#endif
+ {
+ ret = pc263_request_region(dev->minor, iobase, PC263_IO_SIZE);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+ dev->iobase = iobase;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if ((ret = alloc_subdevices(dev, 1)) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+
+ s = dev->subdevices + 0;
+ /* digital i/o subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_RT;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = pc263_dio_insn_bits;
+ s->insn_config = pc263_dio_insn_config;
+ /* all outputs */
+ s->io_bits = 0xffff;
+ /* read initial relay state */
+ s->state = inb(dev->iobase);
+ s->state = s->state | (inb(dev->iobase) << 8);
+
+ printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
+ if (thisboard->bustype == isa_bustype) {
+ printk("(base %#lx) ", iobase);
+ } else {
+#ifdef CONFIG_COMEDI_PCI
+ printk("(pci %s) ", pci_name(pci_dev));
+#endif
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pc263_detach(struct comedi_device * dev)
+{
+ printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
+ PC263_DRIVER_NAME);
+
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv)
+#endif
+ {
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ } else
+#endif
+ {
+ if (dev->iobase) {
+ release_region(dev->iobase, PC263_IO_SIZE);
+ }
+ }
+ }
+ if (dev->board_name) {
+ printk(KERN_INFO "comedi%d: %s removed\n",
+ dev->minor, dev->board_name);
+ }
+ return 0;
+}
+
+/*
+ * This function checks and requests an I/O region, reporting an error
+ * if there is a conflict.
+ */
+static int pc263_request_region(unsigned minor, unsigned long from,
+ unsigned long extent)
+{
+ if (!from || !request_region(from, extent, PC263_DRIVER_NAME)) {
+ printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
+ minor, from, extent);
+ return -EIO;
+ }
+ return 0;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int pc263_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ /* Write out the new digital output lines */
+ outb(s->state & 0xFF, dev->iobase);
+ outb(s->state >> 8, dev->iobase + 1);
+ }
+
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ /* or we could just return the software copy of the output values if
+ * it was a purely digital output subdevice */
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int pc263_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 1)
+ return -EINVAL;
+ return 1;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_amplc_pc263, pc263_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_amplc_pc263);
+#endif
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c
new file mode 100644
index 00000000000..770b9664893
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pci224.c
@@ -0,0 +1,1545 @@
+/*
+ comedi/drivers/amplc_pci224.c
+ Driver for Amplicon PCI224 and PCI234 AO boards.
+
+ Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: amplc_pci224
+Description: Amplicon PCI224, PCI234
+Author: Ian Abbott <abbotti@mev.co.uk>
+Devices: [Amplicon] PCI224 (amplc_pci224 or pci224),
+ PCI234 (amplc_pci224 or pci234)
+Updated: Wed, 22 Oct 2008 12:25:08 +0100
+Status: works, but see caveats
+
+Supports:
+
+ - ao_insn read/write
+ - ao_do_cmd mode with the following sources:
+
+ - start_src TRIG_INT TRIG_EXT
+ - scan_begin_src TRIG_TIMER TRIG_EXT
+ - convert_src TRIG_NOW
+ - scan_end_src TRIG_COUNT
+ - stop_src TRIG_COUNT TRIG_EXT TRIG_NONE
+
+ The channel list must contain at least one channel with no repeated
+ channels. The scan end count must equal the number of channels in
+ the channel list.
+
+ There is only one external trigger source so only one of start_src,
+ scan_begin_src or stop_src may use TRIG_EXT.
+
+Configuration options - PCI224:
+ [0] - PCI bus of device (optional).
+ [1] - PCI slot of device (optional).
+ If bus/slot is not specified, the first available PCI device
+ will be used.
+ [2] - Select available ranges according to jumper LK1. All channels
+ are set to the same range:
+ 0=Jumper position 1-2 (factory default), 4 software-selectable
+ internal voltage references, giving 4 bipolar and 4 unipolar
+ ranges:
+ [-10V,+10V], [-5V,+5V], [-2.5V,+2.5V], [-1.25V,+1.25V],
+ [0,+10V], [0,+5V], [0,+2.5V], [0,1.25V].
+ 1=Jumper position 2-3, 1 external voltage reference, giving
+ 1 bipolar and 1 unipolar range:
+ [-Vext,+Vext], [0,+Vext].
+
+Configuration options - PCI234:
+ [0] - PCI bus of device (optional).
+ [1] - PCI slot of device (optional).
+ If bus/slot is not specified, the first available PCI device
+ will be used.
+ [2] - Select internal or external voltage reference according to
+ jumper LK1. This affects all channels:
+ 0=Jumper position 1-2 (factory default), Vref=5V internal.
+ 1=Jumper position 2-3, Vref=Vext external.
+ [3] - Select channel 0 range according to jumper LK2:
+ 0=Jumper position 2-3 (factory default), range [-2*Vref,+2*Vref]
+ (10V bipolar when options[2]=0).
+ 1=Jumper position 1-2, range [-Vref,+Vref]
+ (5V bipolar when options[2]=0).
+ [4] - Select channel 1 range according to jumper LK3: cf. options[3].
+ [5] - Select channel 2 range according to jumper LK4: cf. options[3].
+ [6] - Select channel 3 range according to jumper LK5: cf. options[3].
+
+Passing a zero for an option is the same as leaving it unspecified.
+
+Caveats:
+
+ 1) All channels on the PCI224 share the same range. Any change to the
+ range as a result of insn_write or a streaming command will affect
+ the output voltages of all channels, including those not specified
+ by the instruction or command.
+
+ 2) For the analog output command, the first scan may be triggered
+ falsely at the start of acquisition. This occurs when the DAC scan
+ trigger source is switched from 'none' to 'timer' (scan_begin_src =
+ TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start
+ of acquisition and the trigger source is at logic level 1 at the
+ time of the switch. This is very likely for TRIG_TIMER. For
+ TRIG_EXT, it depends on the state of the external line and whether
+ the CR_INVERT flag has been set. The remaining scans are triggered
+ correctly.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "comedi_fc.h"
+#include "8253.h"
+
+#define DRIVER_NAME "amplc_pci224"
+
+/*
+ * PCI IDs.
+ */
+/* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
+#define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
+#define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+/*
+ * PCI224/234 i/o space 1 (PCIBAR2) registers.
+ */
+#define PCI224_IO1_SIZE 0x20 /* Size of i/o space 1 (8-bit registers) */
+#define PCI224_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
+#define PCI224_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
+#define PCI224_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
+#define PCI224_Z2_CTC 0x17 /* 82C54 counter/timer control word */
+#define PCI224_ZCLK_SCE 0x1A /* Group Z Clock Configuration Register */
+#define PCI224_ZGAT_SCE 0x1D /* Group Z Gate Configuration Register */
+#define PCI224_INT_SCE 0x1E /* ISR Interrupt source mask register */
+ /* /Interrupt status */
+
+/*
+ * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
+ */
+#define PCI224_IO2_SIZE 0x10 /* Size of i/o space 2 (16-bit registers). */
+#define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
+#define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
+#define PCI224_DACCON 0x02 /* (r/w) DAC status/configuration. */
+#define PCI224_FIFOSIZ 0x04 /* (w-o) FIFO size for wraparound mode. */
+#define PCI224_DACCEN 0x06 /* (w-o) DAC channel enable register. */
+
+/*
+ * DACCON values.
+ */
+/* (r/w) Scan trigger. */
+#define PCI224_DACCON_TRIG_MASK (7 << 0)
+#define PCI224_DACCON_TRIG_NONE (0 << 0) /* none */
+#define PCI224_DACCON_TRIG_SW (1 << 0) /* software trig */
+#define PCI224_DACCON_TRIG_EXTP (2 << 0) /* ext +ve edge */
+#define PCI224_DACCON_TRIG_EXTN (3 << 0) /* ext -ve edge */
+#define PCI224_DACCON_TRIG_Z2CT0 (4 << 0) /* Z2 CT0 out */
+#define PCI224_DACCON_TRIG_Z2CT1 (5 << 0) /* Z2 CT1 out */
+#define PCI224_DACCON_TRIG_Z2CT2 (6 << 0) /* Z2 CT2 out */
+/* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
+#define PCI224_DACCON_POLAR_MASK (1 << 3)
+#define PCI224_DACCON_POLAR_UNI (0 << 3) /* range [0,Vref] */
+#define PCI224_DACCON_POLAR_BI (1 << 3) /* range [-Vref,Vref] */
+/* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
+#define PCI224_DACCON_VREF_MASK (3 << 4)
+#define PCI224_DACCON_VREF_1_25 (0 << 4) /* Vref = 1.25V */
+#define PCI224_DACCON_VREF_2_5 (1 << 4) /* Vref = 2.5V */
+#define PCI224_DACCON_VREF_5 (2 << 4) /* Vref = 5V */
+#define PCI224_DACCON_VREF_10 (3 << 4) /* Vref = 10V */
+/* (r/w) Wraparound mode enable (to play back stored waveform). */
+#define PCI224_DACCON_FIFOWRAP (1 << 7)
+/* (r/w) FIFO enable. It MUST be set! */
+#define PCI224_DACCON_FIFOENAB (1 << 8)
+/* (r/w) FIFO interrupt trigger level (most values are not very useful). */
+#define PCI224_DACCON_FIFOINTR_MASK (7 << 9)
+#define PCI224_DACCON_FIFOINTR_EMPTY (0 << 9) /* when empty */
+#define PCI224_DACCON_FIFOINTR_NEMPTY (1 << 9) /* when not empty */
+#define PCI224_DACCON_FIFOINTR_NHALF (2 << 9) /* when not half full */
+#define PCI224_DACCON_FIFOINTR_HALF (3 << 9) /* when half full */
+#define PCI224_DACCON_FIFOINTR_NFULL (4 << 9) /* when not full */
+#define PCI224_DACCON_FIFOINTR_FULL (5 << 9) /* when full */
+/* (r-o) FIFO fill level. */
+#define PCI224_DACCON_FIFOFL_MASK (7 << 12)
+#define PCI224_DACCON_FIFOFL_EMPTY (1 << 12) /* 0 */
+#define PCI224_DACCON_FIFOFL_ONETOHALF (0 << 12) /* [1,2048] */
+#define PCI224_DACCON_FIFOFL_HALFTOFULL (4 << 12) /* [2049,4095] */
+#define PCI224_DACCON_FIFOFL_FULL (6 << 12) /* 4096 */
+/* (r-o) DAC busy flag. */
+#define PCI224_DACCON_BUSY (1 << 15)
+/* (w-o) FIFO reset. */
+#define PCI224_DACCON_FIFORESET (1 << 12)
+/* (w-o) Global reset (not sure what it does). */
+#define PCI224_DACCON_GLOBALRESET (1 << 13)
+
+/*
+ * DAC FIFO size.
+ */
+#define PCI224_FIFO_SIZE 4096
+
+/*
+ * DAC FIFO guaranteed minimum room available, depending on reported fill level.
+ * The maximum room available depends on the reported fill level and how much
+ * has been written!
+ */
+#define PCI224_FIFO_ROOM_EMPTY PCI224_FIFO_SIZE
+#define PCI224_FIFO_ROOM_ONETOHALF (PCI224_FIFO_SIZE / 2)
+#define PCI224_FIFO_ROOM_HALFTOFULL 1
+#define PCI224_FIFO_ROOM_FULL 0
+
+/*
+ * Counter/timer clock input configuration sources.
+ */
+#define CLK_CLK 0 /* reserved (channel-specific clock) */
+#define CLK_10MHZ 1 /* internal 10 MHz clock */
+#define CLK_1MHZ 2 /* internal 1 MHz clock */
+#define CLK_100KHZ 3 /* internal 100 kHz clock */
+#define CLK_10KHZ 4 /* internal 10 kHz clock */
+#define CLK_1KHZ 5 /* internal 1 kHz clock */
+#define CLK_OUTNM1 6 /* output of channel-1 modulo total */
+#define CLK_EXT 7 /* external clock */
+/* Macro to construct clock input configuration register value. */
+#define CLK_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
+/* Timebases in ns. */
+#define TIMEBASE_10MHZ 100
+#define TIMEBASE_1MHZ 1000
+#define TIMEBASE_100KHZ 10000
+#define TIMEBASE_10KHZ 100000
+#define TIMEBASE_1KHZ 1000000
+
+/*
+ * Counter/timer gate input configuration sources.
+ */
+#define GAT_VCC 0 /* VCC (i.e. enabled) */
+#define GAT_GND 1 /* GND (i.e. disabled) */
+#define GAT_EXT 2 /* reserved (external gate input) */
+#define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
+/* Macro to construct gate input configuration register value. */
+#define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
+
+/*
+ * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
+ *
+ * Channel's Channel's
+ * clock input gate input
+ * Channel CLK_OUTNM1 GAT_NOUTNM2
+ * ------- ---------- -----------
+ * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
+ * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
+ * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
+ */
+
+/*
+ * Interrupt enable/status bits
+ */
+#define PCI224_INTR_EXT 0x01 /* rising edge on external input */
+#define PCI224_INTR_DAC 0x04 /* DAC (FIFO) interrupt */
+#define PCI224_INTR_Z2CT1 0x20 /* rising edge on Z2-CT1 output */
+
+#define PCI224_INTR_EDGE_BITS (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
+#define PCI224_INTR_LEVEL_BITS PCI224_INTR_DACFIFO
+
+/*
+ * Handy macros.
+ */
+
+/* Combine old and new bits. */
+#define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
+
+/* A generic null function pointer value. */
+#define NULLFUNC 0
+
+/* Current CPU. XXX should this be hard_smp_processor_id()? */
+#define THISCPU smp_processor_id()
+
+/* State bits for use with atomic bit operations. */
+#define AO_CMD_STARTED 0
+
+/*
+ * Range tables.
+ */
+
+/* The software selectable internal ranges for PCI224 (option[2] == 0). */
+static const struct comedi_lrange range_pci224_internal = {
+ 8,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+
+static const unsigned short hwrange_pci224_internal[8] = {
+ PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
+ PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
+ PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
+ PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
+ PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
+ PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
+ PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
+ PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
+};
+
+/* The software selectable external ranges for PCI224 (option[2] == 1). */
+static const struct comedi_lrange range_pci224_external = {
+ 2,
+ {
+ RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
+ RANGE_ext(0, 1), /* unipolar [0,+Vref] */
+ }
+};
+
+static const unsigned short hwrange_pci224_external[2] = {
+ PCI224_DACCON_POLAR_BI,
+ PCI224_DACCON_POLAR_UNI,
+};
+
+/* The hardware selectable Vref*2 external range for PCI234
+ * (option[2] == 1, option[3+n] == 0). */
+static const struct comedi_lrange range_pci234_ext2 = {
+ 1,
+ {
+ RANGE_ext(-2, 2),
+ }
+};
+
+/* The hardware selectable Vref external range for PCI234
+ * (option[2] == 1, option[3+n] == 1). */
+static const struct comedi_lrange range_pci234_ext = {
+ 1,
+ {
+ RANGE_ext(-1, 1),
+ }
+};
+
+/* This serves for all the PCI234 ranges. */
+static const unsigned short hwrange_pci234[1] = {
+ PCI224_DACCON_POLAR_BI, /* bipolar - hardware ignores it! */
+};
+
+/*
+ * Board descriptions.
+ */
+
+enum pci224_model { any_model, pci224_model, pci234_model };
+
+struct pci224_board {
+ const char *name;
+ unsigned short devid;
+ enum pci224_model model;
+ unsigned int ao_chans;
+ unsigned int ao_bits;
+};
+
+static const struct pci224_board pci224_boards[] = {
+ {
+ name: "pci224",
+ devid: PCI_DEVICE_ID_AMPLICON_PCI224,
+ model: pci224_model,
+ ao_chans:16,
+ ao_bits: 12,
+ },
+ {
+ name: "pci234",
+ devid: PCI_DEVICE_ID_AMPLICON_PCI234,
+ model: pci234_model,
+ ao_chans:4,
+ ao_bits: 16,
+ },
+ {
+ name: DRIVER_NAME,
+ devid: PCI_DEVICE_ID_INVALID,
+ model: any_model, /* wildcard */
+ },
+};
+
+/*
+ * PCI driver table.
+ */
+
+static DEFINE_PCI_DEVICE_TABLE(pci224_pci_table) = {
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci224_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((struct pci224_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct pci224_private {
+ struct pci_dev *pci_dev; /* PCI device */
+ const unsigned short *hwrange;
+ unsigned long iobase1;
+ unsigned long state;
+ spinlock_t ao_spinlock;
+ unsigned int *ao_readback;
+ short *ao_scan_vals;
+ unsigned char *ao_scan_order;
+ int intr_cpuid;
+ short intr_running;
+ unsigned short daccon;
+ unsigned int cached_div1;
+ unsigned int cached_div2;
+ unsigned int ao_stop_count;
+ short ao_stop_continuous;
+ unsigned short ao_enab; /* max 16 channels so 'short' will do */
+ unsigned char intsce;
+};
+
+#define devpriv ((struct pci224_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pci224_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci224_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_pci224 = {
+ driver_name:DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:pci224_attach,
+ detach:pci224_detach,
+ board_name:&pci224_boards[0].name,
+ offset:sizeof(struct pci224_board),
+ num_names:sizeof(pci224_boards) / sizeof(struct pci224_board),
+};
+
+COMEDI_PCI_INITCLEANUP(driver_amplc_pci224, pci224_pci_table);
+
+/*
+ * Called from the 'insn_write' function to perform a single write.
+ */
+static void
+pci224_ao_set_data(struct comedi_device * dev, int chan, int range, unsigned int data)
+{
+ unsigned short mangled;
+
+ /* Store unmangled data for readback. */
+ devpriv->ao_readback[chan] = data;
+ /* Enable the channel. */
+ outw(1 << chan, dev->iobase + PCI224_DACCEN);
+ /* Set range and reset FIFO. */
+ devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
+ (PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK));
+ outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
+ dev->iobase + PCI224_DACCON);
+ /*
+ * Mangle the data. The hardware expects:
+ * - bipolar: 16-bit 2's complement
+ * - unipolar: 16-bit unsigned
+ */
+ mangled = (unsigned short)data << (16 - thisboard->ao_bits);
+ if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
+ PCI224_DACCON_POLAR_BI) {
+ mangled ^= 0x8000;
+ }
+ /* Write mangled data to the FIFO. */
+ outw(mangled, dev->iobase + PCI224_DACDATA);
+ /* Trigger the conversion. */
+ inw(dev->iobase + PCI224_SOFTTRIG);
+}
+
+/*
+ * 'insn_write' function for AO subdevice.
+ */
+static int
+pci224_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan, range;
+
+ /* Unpack channel and range. */
+ chan = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ pci224_ao_set_data(dev, chan, range, data[i]);
+ }
+ return i;
+}
+
+/*
+ * 'insn_read' function for AO subdevice.
+ *
+ * N.B. The value read will not be valid if the DAC channel has
+ * never been written successfully since the device was attached
+ * or since the channel has been used by an AO streaming write
+ * command.
+ */
+static int
+pci224_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+/*
+ * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
+ */
+static void
+pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
+ unsigned int *nanosec, int round_mode)
+{
+ i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
+}
+
+/*
+ * Kills a command running on the AO subdevice.
+ */
+static void pci224_ao_stop(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state)) {
+ return;
+ }
+
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ /* Kill the interrupts. */
+ devpriv->intsce = 0;
+ outb(0, devpriv->iobase1 + PCI224_INT_SCE);
+ /*
+ * Interrupt routine may or may not be running. We may or may not
+ * have been called from the interrupt routine (directly or
+ * indirectly via a comedi_events() callback routine). It's highly
+ * unlikely that we've been called from some other interrupt routine
+ * but who knows what strange things coders get up to!
+ *
+ * If the interrupt routine is currently running, wait for it to
+ * finish, unless we appear to have been called via the interrupt
+ * routine.
+ */
+ while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ /* Reconfigure DAC for insn_write usage. */
+ outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */
+ devpriv->daccon = COMBINE(devpriv->daccon,
+ PCI224_DACCON_TRIG_SW | PCI224_DACCON_FIFOINTR_EMPTY,
+ PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK);
+ outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
+ dev->iobase + PCI224_DACCON);
+}
+
+/*
+ * Handles start of acquisition for the AO subdevice.
+ */
+static void pci224_ao_start(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned long flags;
+
+ set_bit(AO_CMD_STARTED, &devpriv->state);
+ if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
+ /* An empty acquisition! */
+ pci224_ao_stop(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ } else {
+ /* Enable interrupts. */
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ if (cmd->stop_src == TRIG_EXT) {
+ devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
+ } else {
+ devpriv->intsce = PCI224_INTR_DAC;
+ }
+ outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ }
+}
+
+/*
+ * Handles interrupts from the DAC FIFO.
+ */
+static void pci224_ao_handle_fifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int num_scans;
+ unsigned int room;
+ unsigned short dacstat;
+ unsigned int i, n;
+ unsigned int bytes_per_scan;
+
+ if (cmd->chanlist_len) {
+ bytes_per_scan = cmd->chanlist_len * sizeof(short);
+ } else {
+ /* Shouldn't get here! */
+ bytes_per_scan = sizeof(short);
+ }
+ /* Determine number of scans available in buffer. */
+ num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
+ if (!devpriv->ao_stop_continuous) {
+ /* Fixed number of scans. */
+ if (num_scans > devpriv->ao_stop_count) {
+ num_scans = devpriv->ao_stop_count;
+ }
+ }
+
+ /* Determine how much room is in the FIFO (in samples). */
+ dacstat = inw(dev->iobase + PCI224_DACCON);
+ switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
+ case PCI224_DACCON_FIFOFL_EMPTY:
+ room = PCI224_FIFO_ROOM_EMPTY;
+ if (!devpriv->ao_stop_continuous
+ && devpriv->ao_stop_count == 0) {
+ /* FIFO empty at end of counted acquisition. */
+ pci224_ao_stop(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return;
+ }
+ break;
+ case PCI224_DACCON_FIFOFL_ONETOHALF:
+ room = PCI224_FIFO_ROOM_ONETOHALF;
+ break;
+ case PCI224_DACCON_FIFOFL_HALFTOFULL:
+ room = PCI224_FIFO_ROOM_HALFTOFULL;
+ break;
+ default:
+ room = PCI224_FIFO_ROOM_FULL;
+ break;
+ }
+ if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
+ /* FIFO is less than half-full. */
+ if (num_scans == 0) {
+ /* Nothing left to put in the FIFO. */
+ pci224_ao_stop(dev, s);
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ rt_printk(KERN_ERR "comedi%d: "
+ "AO buffer underrun\n", dev->minor);
+ }
+ }
+ /* Determine how many new scans can be put in the FIFO. */
+ if (cmd->chanlist_len) {
+ room /= cmd->chanlist_len;
+ }
+ /* Determine how many scans to process. */
+ if (num_scans > room) {
+ num_scans = room;
+ }
+ /* Process scans. */
+ for (n = 0; n < num_scans; n++) {
+ cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
+ bytes_per_scan);
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ outw(devpriv->ao_scan_vals[devpriv->
+ ao_scan_order[i]],
+ dev->iobase + PCI224_DACDATA);
+ }
+ }
+ if (!devpriv->ao_stop_continuous) {
+ devpriv->ao_stop_count -= num_scans;
+ if (devpriv->ao_stop_count == 0) {
+ /*
+ * Change FIFO interrupt trigger level to wait
+ * until FIFO is empty.
+ */
+ devpriv->daccon = COMBINE(devpriv->daccon,
+ PCI224_DACCON_FIFOINTR_EMPTY,
+ PCI224_DACCON_FIFOINTR_MASK);
+ outw(devpriv->daccon,
+ dev->iobase + PCI224_DACCON);
+ }
+ }
+ if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
+ PCI224_DACCON_TRIG_NONE) {
+ unsigned short trig;
+
+ /*
+ * This is the initial DAC FIFO interrupt at the
+ * start of the acquisition. The DAC's scan trigger
+ * has been set to 'none' up until now.
+ *
+ * Now that data has been written to the FIFO, the
+ * DAC's scan trigger source can be set to the
+ * correct value.
+ *
+ * BUG: The first scan will be triggered immediately
+ * if the scan trigger source is at logic level 1.
+ */
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ trig = PCI224_DACCON_TRIG_Z2CT0;
+ } else {
+ /* cmd->scan_begin_src == TRIG_EXT */
+ if (cmd->scan_begin_arg & CR_INVERT) {
+ trig = PCI224_DACCON_TRIG_EXTN;
+ } else {
+ trig = PCI224_DACCON_TRIG_EXTP;
+ }
+ }
+ devpriv->daccon = COMBINE(devpriv->daccon, trig,
+ PCI224_DACCON_TRIG_MASK);
+ outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
+ }
+ if (s->async->events) {
+ comedi_event(dev, s);
+ }
+}
+
+/*
+ * Internal trigger function to start acquisition on AO subdevice.
+ */
+static int
+pci224_ao_inttrig_start(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ if (trignum != 0)
+ return -EINVAL;
+
+ s->async->inttrig = NULLFUNC;
+ pci224_ao_start(dev, s);
+
+ return 1;
+}
+
+#define MAX_SCAN_PERIOD 0xFFFFFFFFU
+#define MIN_SCAN_PERIOD 2500
+#define CONVERT_PERIOD 625
+
+/*
+ * 'do_cmdtest' function for AO subdevice.
+ */
+static int
+pci224_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* Step 1: make sure trigger sources are trivially valid. */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_INT | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT | TRIG_TIMER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* Step 2: make sure trigger sources are unique and mutually
+ * compatible. */
+
+ /* these tests are true if more than one _src bit is set */
+ if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+ err++;
+ if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+ err++;
+ if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+ err++;
+
+ /* There's only one external trigger signal (which makes these
+ * tests easier). Only one thing can use it. */
+ tmp = 0;
+ if (cmd->start_src & TRIG_EXT)
+ tmp++;
+ if (cmd->scan_begin_src & TRIG_EXT)
+ tmp++;
+ if (cmd->stop_src & TRIG_EXT)
+ tmp++;
+ if (tmp > 1)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* Step 3: make sure arguments are trivially compatible. */
+
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ break;
+ case TRIG_EXT:
+ /* Force to external trigger 0. */
+ if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
+ cmd->start_arg = COMBINE(cmd->start_arg, 0,
+ ~CR_FLAGS_MASK);
+ err++;
+ }
+ /* The only flag allowed is CR_EDGE, which is ignored. */
+ if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
+ cmd->start_arg = COMBINE(cmd->start_arg, 0,
+ CR_FLAGS_MASK & ~CR_EDGE);
+ err++;
+ }
+ break;
+ }
+
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) {
+ cmd->scan_begin_arg = MAX_SCAN_PERIOD;
+ err++;
+ }
+ tmp = cmd->chanlist_len * CONVERT_PERIOD;
+ if (tmp < MIN_SCAN_PERIOD) {
+ tmp = MIN_SCAN_PERIOD;
+ }
+ if (cmd->scan_begin_arg < tmp) {
+ cmd->scan_begin_arg = tmp;
+ err++;
+ }
+ break;
+ case TRIG_EXT:
+ /* Force to external trigger 0. */
+ if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
+ cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+ ~CR_FLAGS_MASK);
+ err++;
+ }
+ /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
+ if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
+ ~(CR_EDGE | CR_INVERT)) != 0) {
+ cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+ CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
+ err++;
+ }
+ break;
+ }
+
+ /* cmd->convert_src == TRIG_NOW */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_end_arg == TRIG_COUNT */
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ /* Any count allowed. */
+ break;
+ case TRIG_EXT:
+ /* Force to external trigger 0. */
+ if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
+ cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
+ ~CR_FLAGS_MASK);
+ err++;
+ }
+ /* The only flag allowed is CR_EDGE, which is ignored. */
+ if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
+ cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
+ CR_FLAGS_MASK & ~CR_EDGE);
+ }
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* Step 4: fix up any arguments. */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ unsigned int div1, div2, round;
+ int round_mode = cmd->flags & TRIG_ROUND_MASK;
+
+ tmp = cmd->scan_begin_arg;
+ /* Check whether to use a single timer. */
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ round = TIMEBASE_10MHZ / 2;
+ break;
+ case TRIG_ROUND_DOWN:
+ round = 0;
+ break;
+ case TRIG_ROUND_UP:
+ round = TIMEBASE_10MHZ - 1;
+ break;
+ }
+ /* Be careful to avoid overflow! */
+ div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
+ div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
+ TIMEBASE_10MHZ;
+ if (div2 <= 0x10000) {
+ /* A single timer will suffice. */
+ if (div2 < 2)
+ div2 = 2;
+ cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
+ if (cmd->scan_begin_arg < div2 ||
+ cmd->scan_begin_arg < TIMEBASE_10MHZ) {
+ /* Overflow! */
+ cmd->scan_begin_arg = MAX_SCAN_PERIOD;
+ }
+ } else {
+ /* Use two timers. */
+ div1 = devpriv->cached_div1;
+ div2 = devpriv->cached_div2;
+ pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
+ &cmd->scan_begin_arg, round_mode);
+ devpriv->cached_div1 = div1;
+ devpriv->cached_div2 = div2;
+ }
+ if (tmp != cmd->scan_begin_arg) {
+ err++;
+ }
+ }
+
+ if (err)
+ return 4;
+
+ /* Step 5: check channel list. */
+
+ if (cmd->chanlist && (cmd->chanlist_len > 0)) {
+ unsigned int range;
+ enum { range_err = 1, dupchan_err = 2, };
+ unsigned errors;
+ unsigned int n;
+ unsigned int ch;
+
+ /*
+ * Check all channels have the same range index. Don't care
+ * about analogue reference, as we can't configure it.
+ *
+ * Check the list has no duplicate channels.
+ */
+ range = CR_RANGE(cmd->chanlist[0]);
+ errors = 0;
+ tmp = 0;
+ for (n = 0; n < cmd->chanlist_len; n++) {
+ ch = CR_CHAN(cmd->chanlist[n]);
+ if (tmp & (1U << ch)) {
+ errors |= dupchan_err;
+ }
+ tmp |= (1U << ch);
+ if (CR_RANGE(cmd->chanlist[n]) != range) {
+ errors |= range_err;
+ }
+ }
+ if (errors) {
+ if (errors & dupchan_err) {
+ DPRINTK("comedi%d: " DRIVER_NAME
+ ": ao_cmdtest: "
+ "entries in chanlist must contain no "
+ "duplicate channels\n", dev->minor);
+ }
+ if (errors & range_err) {
+ DPRINTK("comedi%d: " DRIVER_NAME
+ ": ao_cmdtest: "
+ "entries in chanlist must all have "
+ "the same range index\n", dev->minor);
+ }
+ err++;
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+/*
+ * 'do_cmd' function for AO subdevice.
+ */
+static int pci224_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int range;
+ unsigned int i, j;
+ unsigned int ch;
+ unsigned int rank;
+ unsigned long flags;
+
+ /* Cannot handle null/empty chanlist. */
+ if (cmd->chanlist == NULL || cmd->chanlist_len == 0) {
+ return -EINVAL;
+ }
+
+ /* Determine which channels are enabled and their load order. */
+ devpriv->ao_enab = 0;
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ ch = CR_CHAN(cmd->chanlist[i]);
+ devpriv->ao_enab |= 1U << ch;
+ rank = 0;
+ for (j = 0; j < cmd->chanlist_len; j++) {
+ if (CR_CHAN(cmd->chanlist[j]) < ch) {
+ rank++;
+ }
+ }
+ devpriv->ao_scan_order[rank] = i;
+ }
+
+ /* Set enabled channels. */
+ outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
+
+ /* Determine range and polarity. All channels the same. */
+ range = CR_RANGE(cmd->chanlist[0]);
+
+ /*
+ * Set DAC range and polarity.
+ * Set DAC scan trigger source to 'none'.
+ * Set DAC FIFO interrupt trigger level to 'not half full'.
+ * Reset DAC FIFO.
+ *
+ * N.B. DAC FIFO interrupts are currently disabled.
+ */
+ devpriv->daccon = COMBINE(devpriv->daccon,
+ (devpriv->hwrange[range] | PCI224_DACCON_TRIG_NONE |
+ PCI224_DACCON_FIFOINTR_NHALF),
+ (PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK |
+ PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK));
+ outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
+ dev->iobase + PCI224_DACCON);
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ unsigned int div1, div2, round;
+ unsigned int ns = cmd->scan_begin_arg;
+ int round_mode = cmd->flags & TRIG_ROUND_MASK;
+
+ /* Check whether to use a single timer. */
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ round = TIMEBASE_10MHZ / 2;
+ break;
+ case TRIG_ROUND_DOWN:
+ round = 0;
+ break;
+ case TRIG_ROUND_UP:
+ round = TIMEBASE_10MHZ - 1;
+ break;
+ }
+ /* Be careful to avoid overflow! */
+ div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
+ div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
+ TIMEBASE_10MHZ;
+ if (div2 <= 0x10000) {
+ /* A single timer will suffice. */
+ if (div2 < 2)
+ div2 = 2;
+ div2 &= 0xffff;
+ div1 = 1; /* Flag that single timer to be used. */
+ } else {
+ /* Use two timers. */
+ div1 = devpriv->cached_div1;
+ div2 = devpriv->cached_div2;
+ pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
+ &ns, round_mode);
+ }
+
+ /*
+ * The output of timer Z2-0 will be used as the scan trigger
+ * source.
+ */
+ /* Make sure Z2-0 is gated on. */
+ outb(GAT_CONFIG(0, GAT_VCC),
+ devpriv->iobase1 + PCI224_ZGAT_SCE);
+ if (div1 == 1) {
+ /* Not cascading. Z2-0 needs 10 MHz clock. */
+ outb(CLK_CONFIG(0, CLK_10MHZ),
+ devpriv->iobase1 + PCI224_ZCLK_SCE);
+ } else {
+ /* Cascading with Z2-2. */
+ /* Make sure Z2-2 is gated on. */
+ outb(GAT_CONFIG(2, GAT_VCC),
+ devpriv->iobase1 + PCI224_ZGAT_SCE);
+ /* Z2-2 needs 10 MHz clock. */
+ outb(CLK_CONFIG(2, CLK_10MHZ),
+ devpriv->iobase1 + PCI224_ZCLK_SCE);
+ /* Load Z2-2 mode (2) and counter (div1). */
+ i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
+ 2, div1, 2);
+ /* Z2-0 is clocked from Z2-2's output. */
+ outb(CLK_CONFIG(0, CLK_OUTNM1),
+ devpriv->iobase1 + PCI224_ZCLK_SCE);
+ }
+ /* Load Z2-0 mode (2) and counter (div2). */
+ i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
+ }
+
+ /*
+ * Sort out end of acquisition.
+ */
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ /* Fixed number of scans. */
+ devpriv->ao_stop_continuous = 0;
+ devpriv->ao_stop_count = cmd->stop_arg;
+ break;
+ default:
+ /* Continuous scans. */
+ devpriv->ao_stop_continuous = 1;
+ devpriv->ao_stop_count = 0;
+ break;
+ }
+
+ /*
+ * Sort out start of acquisition.
+ */
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ s->async->inttrig = &pci224_ao_inttrig_start;
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ break;
+ case TRIG_EXT:
+ /* Enable external interrupt trigger to start acquisition. */
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ devpriv->intsce |= PCI224_INTR_EXT;
+ outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * 'cancel' function for AO subdevice.
+ */
+static int pci224_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ pci224_ao_stop(dev, s);
+ return 0;
+}
+
+/*
+ * 'munge' data for AO command.
+ */
+static void
+pci224_ao_munge(struct comedi_device * dev, struct comedi_subdevice * s, void *data,
+ unsigned int num_bytes, unsigned int chan_index)
+{
+ struct comedi_async *async = s->async;
+ short *array = data;
+ unsigned int length = num_bytes / sizeof(*array);
+ unsigned int offset;
+ unsigned int shift;
+ unsigned int i;
+
+ /* The hardware expects 16-bit numbers. */
+ shift = 16 - thisboard->ao_bits;
+ /* Channels will be all bipolar or all unipolar. */
+ if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
+ PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
+ /* Unipolar */
+ offset = 0;
+ } else {
+ /* Bipolar */
+ offset = 32768;
+ }
+ /* Munge the data. */
+ for (i = 0; i < length; i++) {
+ array[i] = (array[i] << shift) - offset;
+ }
+}
+
+/*
+ * Interrupt handler.
+ */
+static irqreturn_t pci224_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = &dev->subdevices[0];
+ struct comedi_cmd *cmd;
+ unsigned char intstat, valid_intstat;
+ unsigned char curenab;
+ int retval = 0;
+ unsigned long flags;
+
+ intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
+ if (intstat) {
+ retval = 1;
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ valid_intstat = devpriv->intsce & intstat;
+ /* Temporarily disable interrupt sources. */
+ curenab = devpriv->intsce & ~intstat;
+ outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
+ devpriv->intr_running = 1;
+ devpriv->intr_cpuid = THISCPU;
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ if (valid_intstat != 0) {
+ cmd = &s->async->cmd;
+ if (valid_intstat & PCI224_INTR_EXT) {
+ devpriv->intsce &= ~PCI224_INTR_EXT;
+ if (cmd->start_src == TRIG_EXT) {
+ pci224_ao_start(dev, s);
+ } else if (cmd->stop_src == TRIG_EXT) {
+ pci224_ao_stop(dev, s);
+ }
+ }
+ if (valid_intstat & PCI224_INTR_DAC) {
+ pci224_ao_handle_fifo(dev, s);
+ }
+ }
+ /* Reenable interrupt sources. */
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ if (curenab != devpriv->intsce) {
+ outb(devpriv->intsce,
+ devpriv->iobase1 + PCI224_INT_SCE);
+ }
+ devpriv->intr_running = 0;
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ }
+ return IRQ_RETVAL(retval);
+}
+
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+static int
+pci224_find_pci(struct comedi_device * dev, int bus, int slot,
+ struct pci_dev **pci_dev_p)
+{
+ struct pci_dev *pci_dev = NULL;
+
+ *pci_dev_p = NULL;
+
+ /* Look for matching PCI device. */
+ for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+ pci_dev != NULL;
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID,
+ pci_dev)) {
+ /* If bus/slot specified, check them. */
+ if (bus || slot) {
+ if (bus != pci_dev->bus->number
+ || slot != PCI_SLOT(pci_dev->devfn))
+ continue;
+ }
+ if (thisboard->model == any_model) {
+ /* Match any supported model. */
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pci224_boards); i++) {
+ if (pci_dev->device == pci224_boards[i].devid) {
+ /* Change board_ptr to matched board. */
+ dev->board_ptr = &pci224_boards[i];
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(pci224_boards))
+ continue;
+ } else {
+ /* Match specific model name. */
+ if (thisboard->devid != pci_dev->device)
+ continue;
+ }
+
+ /* Found a match. */
+ *pci_dev_p = pci_dev;
+ return 0;
+ }
+ /* No match found. */
+ if (bus || slot) {
+ printk(KERN_ERR "comedi%d: error! "
+ "no %s found at pci %02x:%02x!\n",
+ dev->minor, thisboard->name, bus, slot);
+ } else {
+ printk(KERN_ERR "comedi%d: error! no %s found!\n",
+ dev->minor, thisboard->name);
+ }
+ return -EIO;
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pci224_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ struct pci_dev *pci_dev;
+ unsigned int irq;
+ int bus = 0, slot = 0;
+ unsigned n;
+ int ret;
+
+ printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME);
+
+ bus = it->options[0];
+ slot = it->options[1];
+ if ((ret = alloc_private(dev, sizeof(struct pci224_private))) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+ if ((ret = pci224_find_pci(dev, bus, slot, &pci_dev)) < 0)
+ return ret;
+ devpriv->pci_dev = pci_dev;
+
+ if ((ret = comedi_pci_enable(pci_dev, DRIVER_NAME)) < 0) {
+ printk(KERN_ERR
+ "comedi%d: error! cannot enable PCI device "
+ "and request regions!\n", dev->minor);
+ return ret;
+ }
+ spin_lock_init(&devpriv->ao_spinlock);
+
+ devpriv->iobase1 = pci_resource_start(pci_dev, 2);
+ dev->iobase = pci_resource_start(pci_dev, 3);
+ irq = pci_dev->irq;
+
+ /* Allocate readback buffer for AO channels. */
+ devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
+ thisboard->ao_chans, GFP_KERNEL);
+ if (!devpriv->ao_readback) {
+ return -ENOMEM;
+ }
+
+ /* Allocate buffer to hold values for AO channel scan. */
+ devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
+ thisboard->ao_chans, GFP_KERNEL);
+ if (!devpriv->ao_scan_vals) {
+ return -ENOMEM;
+ }
+
+ /* Allocate buffer to hold AO channel scan order. */
+ devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
+ thisboard->ao_chans, GFP_KERNEL);
+ if (!devpriv->ao_scan_order) {
+ return -ENOMEM;
+ }
+
+ /* Disable interrupt sources. */
+ devpriv->intsce = 0;
+ outb(0, devpriv->iobase1 + PCI224_INT_SCE);
+
+ /* Initialize the DAC hardware. */
+ outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
+ outw(0, dev->iobase + PCI224_DACCEN);
+ outw(0, dev->iobase + PCI224_FIFOSIZ);
+ devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
+ PCI224_DACCON_FIFOENAB | PCI224_DACCON_FIFOINTR_EMPTY);
+ outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
+ dev->iobase + PCI224_DACCON);
+
+ /* Allocate subdevices. There is only one! */
+ if ((ret = alloc_subdevices(dev, 1)) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+
+ s = dev->subdevices + 0;
+ /* Analog output subdevice. */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
+ s->n_chan = thisboard->ao_chans;
+ s->maxdata = (1 << thisboard->ao_bits) - 1;
+ s->insn_write = &pci224_ao_insn_write;
+ s->insn_read = &pci224_ao_insn_read;
+ s->len_chanlist = s->n_chan;
+
+ dev->write_subdev = s;
+ s->do_cmd = &pci224_ao_cmd;
+ s->do_cmdtest = &pci224_ao_cmdtest;
+ s->cancel = &pci224_ao_cancel;
+ s->munge = &pci224_ao_munge;
+
+ /* Sort out channel range options. */
+ if (thisboard->model == pci234_model) {
+ /* PCI234 range options. */
+ const struct comedi_lrange **range_table_list;
+
+ s->range_table_list = range_table_list =
+ kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
+ GFP_KERNEL);
+ if (!s->range_table_list) {
+ return -ENOMEM;
+ }
+ for (n = 2; n < 3 + s->n_chan; n++) {
+ if (it->options[n] < 0 || it->options[n] > 1) {
+ printk(KERN_WARNING "comedi%d: %s: warning! "
+ "bad options[%u]=%d\n",
+ dev->minor, DRIVER_NAME, n,
+ it->options[n]);
+ }
+ }
+ for (n = 0; n < s->n_chan; n++) {
+ if (n < COMEDI_NDEVCONFOPTS - 3 &&
+ it->options[3 + n] == 1) {
+ if (it->options[2] == 1) {
+ range_table_list[n] = &range_pci234_ext;
+ } else {
+ range_table_list[n] = &range_bipolar5;
+ }
+ } else {
+ if (it->options[2] == 1) {
+ range_table_list[n] =
+ &range_pci234_ext2;
+ } else {
+ range_table_list[n] = &range_bipolar10;
+ }
+ }
+ }
+ devpriv->hwrange = hwrange_pci234;
+ } else {
+ /* PCI224 range options. */
+ if (it->options[2] == 1) {
+ s->range_table = &range_pci224_external;
+ devpriv->hwrange = hwrange_pci224_external;
+ } else {
+ if (it->options[2] != 0) {
+ printk(KERN_WARNING "comedi%d: %s: warning! "
+ "bad options[2]=%d\n",
+ dev->minor, DRIVER_NAME,
+ it->options[2]);
+ }
+ s->range_table = &range_pci224_internal;
+ devpriv->hwrange = hwrange_pci224_internal;
+ }
+ }
+
+ dev->board_name = thisboard->name;
+
+ if (irq) {
+ ret = comedi_request_irq(irq, pci224_interrupt, IRQF_SHARED,
+ DRIVER_NAME, dev);
+ if (ret < 0) {
+ printk(KERN_ERR "comedi%d: error! "
+ "unable to allocate irq %u\n", dev->minor, irq);
+ return ret;
+ } else {
+ dev->irq = irq;
+ }
+ }
+
+ printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
+ printk("(pci %s) ", pci_name(pci_dev));
+ if (irq) {
+ printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
+ } else {
+ printk("(no irq) ");
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pci224_detach(struct comedi_device * dev)
+{
+ printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, DRIVER_NAME);
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (dev->subdevices) {
+ struct comedi_subdevice *s;
+
+ s = dev->subdevices + 0;
+ /* AO subdevice */
+ if (s->range_table_list) {
+ kfree(s->range_table_list);
+ }
+ }
+ if (devpriv) {
+ if (devpriv->ao_readback) {
+ kfree(devpriv->ao_readback);
+ }
+ if (devpriv->ao_scan_vals) {
+ kfree(devpriv->ao_scan_vals);
+ }
+ if (devpriv->ao_scan_order) {
+ kfree(devpriv->ao_scan_order);
+ }
+ if (devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+ if (dev->board_name) {
+ printk(KERN_INFO "comedi%d: %s removed\n",
+ dev->minor, dev->board_name);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c
new file mode 100644
index 00000000000..0c9e5737e10
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pci230.c
@@ -0,0 +1,2977 @@
+ /*
+ comedi/drivers/amplc_pci230.c
+ Driver for Amplicon PCI230 and PCI260 Multifunction I/O boards.
+
+ Copyright (C) 2001 Allan Willcox <allanwillcox@ozemail.com.au>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+Driver: amplc_pci230
+Description: Amplicon PCI230, PCI260 Multifunction I/O boards
+Author: Allan Willcox <allanwillcox@ozemail.com.au>,
+ Steve D Sharples <steve.sharples@nottingham.ac.uk>,
+ Ian Abbott <abbotti@mev.co.uk>
+Updated: Wed, 22 Oct 2008 12:34:49 +0100
+Devices: [Amplicon] PCI230 (pci230 or amplc_pci230),
+ PCI230+ (pci230+ or amplc_pci230),
+ PCI260 (pci260 or amplc_pci230), PCI260+ (pci260+ or amplc_pci230)
+Status: works
+
+Configuration options:
+ [0] - PCI bus of device (optional).
+ [1] - PCI slot of device (optional).
+ If bus/slot is not specified, the first available PCI device
+ will be used.
+
+Configuring a "amplc_pci230" will match any supported card and it will
+choose the best match, picking the "+" models if possible. Configuring
+a "pci230" will match a PCI230 or PCI230+ card and it will be treated as
+a PCI230. Configuring a "pci260" will match a PCI260 or PCI260+ card
+and it will be treated as a PCI260. Configuring a "pci230+" will match
+a PCI230+ card. Configuring a "pci260+" will match a PCI260+ card.
+
+Subdevices:
+
+ PCI230(+) PCI260(+)
+ --------- ---------
+ Subdevices 3 1
+ 0 AI AI
+ 1 AO
+ 2 DIO
+
+AI Subdevice:
+
+ The AI subdevice has 16 single-ended channels or 8 differential
+ channels.
+
+ The PCI230 and PCI260 cards have 12-bit resolution. The PCI230+ and
+ PCI260+ cards have 16-bit resolution.
+
+ For differential mode, use inputs 2N and 2N+1 for channel N (e.g. use
+ inputs 14 and 15 for channel 7). If the card is physically a PCI230
+ or PCI260 then it actually uses a "pseudo-differential" mode where the
+ inputs are sampled a few microseconds apart. The PCI230+ and PCI260+
+ use true differential sampling. Another difference is that if the
+ card is physically a PCI230 or PCI260, the inverting input is 2N,
+ whereas for a PCI230+ or PCI260+ the inverting input is 2N+1. So if a
+ PCI230 is physically replaced by a PCI230+ (or a PCI260 with a
+ PCI260+) and differential mode is used, the differential inputs need
+ to be physically swapped on the connector.
+
+ The following input ranges are supported:
+
+ 0 => [-10, +10] V
+ 1 => [-5, +5] V
+ 2 => [-2.5, +2.5] V
+ 3 => [-1.25, +1.25] V
+ 4 => [0, 10] V
+ 5 => [0, 5] V
+ 6 => [0, 2.5] V
+
+AI Commands:
+
+ +=========+==============+===========+============+==========+
+ |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
+ +=========+==============+===========+============+==========+
+ |TRIG_NOW | TRIG_FOLLOW |TRIG_TIMER | TRIG_COUNT |TRIG_NONE |
+ |TRIG_INT | |TRIG_EXT(3)| |TRIG_COUNT|
+ | | |TRIG_INT | | |
+ | |--------------|-----------| | |
+ | | TRIG_TIMER(1)|TRIG_TIMER | | |
+ | | TRIG_EXT(2) | | | |
+ | | TRIG_INT | | | |
+ +---------+--------------+-----------+------------+----------+
+
+ Note 1: If AI command and AO command are used simultaneously, only
+ one may have scan_begin_src == TRIG_TIMER.
+
+ Note 2: For PCI230 and PCI230+, scan_begin_src == TRIG_EXT uses
+ DIO channel 16 (pin 49) which will need to be configured as
+ a digital input. For PCI260+, the EXTTRIG/EXTCONVCLK input
+ (pin 17) is used instead. For PCI230, scan_begin_src ==
+ TRIG_EXT is not supported. The trigger is a rising edge
+ on the input.
+
+ Note 3: For convert_src == TRIG_EXT, the EXTTRIG/EXTCONVCLK input
+ (pin 25 on PCI230(+), pin 17 on PCI260(+)) is used. The
+ convert_arg value is interpreted as follows:
+
+ convert_arg == (CR_EDGE | 0) => rising edge
+ convert_arg == (CR_EDGE | CR_INVERT | 0) => falling edge
+ convert_arg == 0 => falling edge (backwards compatibility)
+ convert_arg == 1 => rising edge (backwards compatibility)
+
+ All entries in the channel list must use the same analogue reference.
+ If the analogue reference is not AREF_DIFF (not differential) each
+ pair of channel numbers (0 and 1, 2 and 3, etc.) must use the same
+ input range. The input ranges used in the sequence must be all
+ bipolar (ranges 0 to 3) or all unipolar (ranges 4 to 6). The channel
+ sequence must consist of 1 or more identical subsequences. Within the
+ subsequence, channels must be in ascending order with no repeated
+ channels. For example, the following sequences are valid: 0 1 2 3
+ (single valid subsequence), 0 2 3 5 0 2 3 5 (repeated valid
+ subsequence), 1 1 1 1 (repeated valid subsequence). The following
+ sequences are invalid: 0 3 2 1 (invalid subsequence), 0 2 3 5 0 2 3
+ (incompletely repeated subsequence). Some versions of the PCI230+ and
+ PCI260+ have a bug that requires a subsequence longer than one entry
+ long to include channel 0.
+
+AO Subdevice:
+
+ The AO subdevice has 2 channels with 12-bit resolution.
+
+ The following output ranges are supported:
+
+ 0 => [0, 10] V
+ 1 => [-10, +10] V
+
+AO Commands:
+
+ +=========+==============+===========+============+==========+
+ |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
+ +=========+==============+===========+============+==========+
+ |TRIG_INT | TRIG_TIMER(1)| TRIG_NOW | TRIG_COUNT |TRIG_NONE |
+ | | TRIG_EXT(2) | | |TRIG_COUNT|
+ | | TRIG_INT | | | |
+ +---------+--------------+-----------+------------+----------+
+
+ Note 1: If AI command and AO command are used simultaneously, only
+ one may have scan_begin_src == TRIG_TIMER.
+
+ Note 2: scan_begin_src == TRIG_EXT is only supported if the card is
+ configured as a PCI230+ and is only supported on later
+ versions of the card. As a card configured as a PCI230+ is
+ not guaranteed to support external triggering, please consider
+ this support to be a bonus. It uses the EXTTRIG/ EXTCONVCLK
+ input (PCI230+ pin 25). Triggering will be on the rising edge
+ unless the CR_INVERT flag is set in scan_begin_arg.
+
+ The channels in the channel sequence must be in ascending order with
+ no repeats. All entries in the channel sequence must use the same
+ output range.
+
+DIO Subdevice:
+
+ The DIO subdevice is a 8255 chip providing 24 DIO channels. The DIO
+ channels are configurable as inputs or outputs in four groups:
+
+ Port A - channels 0 to 7
+ Port B - channels 8 to 15
+ Port CL - channels 16 to 19
+ Port CH - channels 20 to 23
+
+ Only mode 0 of the 8255 chip is supported.
+
+ Bit 0 of port C (DIO channel 16) is also used as an external scan
+ trigger input for AI commands on PCI230 and PCI230+, so would need to
+ be configured as an input to use it for that purpose.
+*/
+/*
+Extra triggered scan functionality, interrupt bug-fix added by Steve Sharples.
+Support for PCI230+/260+, more triggered scan functionality, and workarounds
+for (or detection of) various hardware problems added by Ian Abbott.
+*/
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "8253.h"
+#include "8255.h"
+
+/* PCI230 PCI configuration register information */
+#define PCI_VENDOR_ID_AMPLICON 0x14dc
+#define PCI_DEVICE_ID_PCI230 0x0000
+#define PCI_DEVICE_ID_PCI260 0x0006
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+#define PCI230_IO1_SIZE 32 /* Size of I/O space 1 */
+#define PCI230_IO2_SIZE 16 /* Size of I/O space 2 */
+
+/* PCI230 i/o space 1 registers. */
+#define PCI230_PPI_X_BASE 0x00 /* User PPI (82C55) base */
+#define PCI230_PPI_X_A 0x00 /* User PPI (82C55) port A */
+#define PCI230_PPI_X_B 0x01 /* User PPI (82C55) port B */
+#define PCI230_PPI_X_C 0x02 /* User PPI (82C55) port C */
+#define PCI230_PPI_X_CMD 0x03 /* User PPI (82C55) control word */
+#define PCI230_Z2_CT_BASE 0x14 /* 82C54 counter/timer base */
+#define PCI230_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
+#define PCI230_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
+#define PCI230_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
+#define PCI230_Z2_CTC 0x17 /* 82C54 counter/timer control word */
+#define PCI230_ZCLK_SCE 0x1A /* Group Z Clock Configuration */
+#define PCI230_ZGAT_SCE 0x1D /* Group Z Gate Configuration */
+#define PCI230_INT_SCE 0x1E /* Interrupt source mask (w) */
+#define PCI230_INT_STAT 0x1E /* Interrupt status (r) */
+
+/* PCI230 i/o space 2 registers. */
+#define PCI230_DACCON 0x00 /* DAC control */
+#define PCI230_DACOUT1 0x02 /* DAC channel 0 (w) */
+#define PCI230_DACOUT2 0x04 /* DAC channel 1 (w) (not FIFO mode) */
+#define PCI230_ADCDATA 0x08 /* ADC data (r) */
+#define PCI230_ADCSWTRIG 0x08 /* ADC software trigger (w) */
+#define PCI230_ADCCON 0x0A /* ADC control */
+#define PCI230_ADCEN 0x0C /* ADC channel enable bits */
+#define PCI230_ADCG 0x0E /* ADC gain control bits */
+/* PCI230+ i/o space 2 additional registers. */
+#define PCI230P_ADCTRIG 0x10 /* ADC start acquisition trigger */
+#define PCI230P_ADCTH 0x12 /* ADC analog trigger threshold */
+#define PCI230P_ADCFFTH 0x14 /* ADC FIFO interrupt threshold */
+#define PCI230P_ADCFFLEV 0x16 /* ADC FIFO level (r) */
+#define PCI230P_ADCPTSC 0x18 /* ADC pre-trigger sample count (r) */
+#define PCI230P_ADCHYST 0x1A /* ADC analog trigger hysteresys */
+#define PCI230P_EXTFUNC 0x1C /* Extended functions */
+#define PCI230P_HWVER 0x1E /* Hardware version (r) */
+/* PCI230+ hardware version 2 onwards. */
+#define PCI230P2_DACDATA 0x02 /* DAC data (FIFO mode) (w) */
+#define PCI230P2_DACSWTRIG 0x02 /* DAC soft trigger (FIFO mode) (r) */
+#define PCI230P2_DACEN 0x06 /* DAC channel enable (FIFO mode) */
+
+/* Convertor related constants. */
+#define PCI230_DAC_SETTLE 5 /* Analogue output settling time in µs */
+ /* (DAC itself is 1µs nominally). */
+#define PCI230_ADC_SETTLE 1 /* Analogue input settling time in µs */
+ /* (ADC itself is 1.6µs nominally but we poll
+ * anyway). */
+#define PCI230_MUX_SETTLE 10 /* ADC MUX settling time in µS */
+ /* - 10µs for se, 20µs de. */
+
+/* DACCON read-write values. */
+#define PCI230_DAC_OR_UNI (0<<0) /* Output range unipolar */
+#define PCI230_DAC_OR_BIP (1<<0) /* Output range bipolar */
+#define PCI230_DAC_OR_MASK (1<<0)
+/* The following applies only if DAC FIFO support is enabled in the EXTFUNC
+ * register (and only for PCI230+ hardware version 2 onwards). */
+#define PCI230P2_DAC_FIFO_EN (1<<8) /* FIFO enable */
+/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards). */
+#define PCI230P2_DAC_TRIG_NONE (0<<2) /* No trigger */
+#define PCI230P2_DAC_TRIG_SW (1<<2) /* Software trigger trigger */
+#define PCI230P2_DAC_TRIG_EXTP (2<<2) /* EXTTRIG +ve edge trigger */
+#define PCI230P2_DAC_TRIG_EXTN (3<<2) /* EXTTRIG -ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT0 (4<<2) /* CT0-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT1 (5<<2) /* CT1-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT2 (6<<2) /* CT2-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_MASK (7<<2)
+#define PCI230P2_DAC_FIFO_WRAP (1<<7) /* FIFO wraparound mode */
+#define PCI230P2_DAC_INT_FIFO_EMPTY (0<<9) /* FIFO interrupt empty */
+#define PCI230P2_DAC_INT_FIFO_NEMPTY (1<<9)
+#define PCI230P2_DAC_INT_FIFO_NHALF (2<<9) /* FIFO intr not half full */
+#define PCI230P2_DAC_INT_FIFO_HALF (3<<9)
+#define PCI230P2_DAC_INT_FIFO_NFULL (4<<9) /* FIFO interrupt not full */
+#define PCI230P2_DAC_INT_FIFO_FULL (5<<9)
+#define PCI230P2_DAC_INT_FIFO_MASK (7<<9)
+
+/* DACCON read-only values. */
+#define PCI230_DAC_BUSY (1<<1) /* DAC busy. */
+/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards). */
+#define PCI230P2_DAC_FIFO_UNDERRUN_LATCHED (1<<5) /* Underrun error */
+#define PCI230P2_DAC_FIFO_EMPTY (1<<13) /* FIFO empty */
+#define PCI230P2_DAC_FIFO_FULL (1<<14) /* FIFO full */
+#define PCI230P2_DAC_FIFO_HALF (1<<15) /* FIFO half full */
+
+/* DACCON write-only, transient values. */
+/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards). */
+#define PCI230P2_DAC_FIFO_UNDERRUN_CLEAR (1<<5) /* Clear underrun */
+#define PCI230P2_DAC_FIFO_RESET (1<<12) /* FIFO reset */
+
+/* PCI230+ hardware version 2 DAC FIFO levels. */
+#define PCI230P2_DAC_FIFOLEVEL_HALF 512
+#define PCI230P2_DAC_FIFOLEVEL_FULL 1024
+/* Free space in DAC FIFO. */
+#define PCI230P2_DAC_FIFOROOM_EMPTY PCI230P2_DAC_FIFOLEVEL_FULL
+#define PCI230P2_DAC_FIFOROOM_ONETOHALF \
+ (PCI230P2_DAC_FIFOLEVEL_FULL - PCI230P2_DAC_FIFOLEVEL_HALF)
+#define PCI230P2_DAC_FIFOROOM_HALFTOFULL 1
+#define PCI230P2_DAC_FIFOROOM_FULL 0
+
+/* ADCCON read/write values. */
+#define PCI230_ADC_TRIG_NONE (0<<0) /* No trigger */
+#define PCI230_ADC_TRIG_SW (1<<0) /* Software trigger trigger */
+#define PCI230_ADC_TRIG_EXTP (2<<0) /* EXTTRIG +ve edge trigger */
+#define PCI230_ADC_TRIG_EXTN (3<<0) /* EXTTRIG -ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT0 (4<<0) /* CT0-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT1 (5<<0) /* CT1-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT2 (6<<0) /* CT2-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_MASK (7<<0)
+#define PCI230_ADC_IR_UNI (0<<3) /* Input range unipolar */
+#define PCI230_ADC_IR_BIP (1<<3) /* Input range bipolar */
+#define PCI230_ADC_IR_MASK (1<<3)
+#define PCI230_ADC_IM_SE (0<<4) /* Input mode single ended */
+#define PCI230_ADC_IM_DIF (1<<4) /* Input mode differential */
+#define PCI230_ADC_IM_MASK (1<<4)
+#define PCI230_ADC_FIFO_EN (1<<8) /* FIFO enable */
+#define PCI230_ADC_INT_FIFO_EMPTY (0<<9)
+#define PCI230_ADC_INT_FIFO_NEMPTY (1<<9) /* FIFO interrupt not empty */
+#define PCI230_ADC_INT_FIFO_NHALF (2<<9)
+#define PCI230_ADC_INT_FIFO_HALF (3<<9) /* FIFO interrupt half full */
+#define PCI230_ADC_INT_FIFO_NFULL (4<<9)
+#define PCI230_ADC_INT_FIFO_FULL (5<<9) /* FIFO interrupt full */
+#define PCI230P_ADC_INT_FIFO_THRESH (7<<9) /* FIFO interrupt threshold */
+#define PCI230_ADC_INT_FIFO_MASK (7<<9)
+
+/* ADCCON write-only, transient values. */
+#define PCI230_ADC_FIFO_RESET (1<<12) /* FIFO reset */
+#define PCI230_ADC_GLOB_RESET (1<<13) /* Global reset */
+
+/* ADCCON read-only values. */
+#define PCI230_ADC_BUSY (1<<15) /* ADC busy */
+#define PCI230_ADC_FIFO_EMPTY (1<<12) /* FIFO empty */
+#define PCI230_ADC_FIFO_FULL (1<<13) /* FIFO full */
+#define PCI230_ADC_FIFO_HALF (1<<14) /* FIFO half full */
+#define PCI230_ADC_FIFO_FULL_LATCHED (1<<5) /* Indicates overrun occurred */
+
+/* PCI230 ADC FIFO levels. */
+#define PCI230_ADC_FIFOLEVEL_HALFFULL 2049 /* Value for FIFO half full */
+#define PCI230_ADC_FIFOLEVEL_FULL 4096 /* FIFO size */
+
+/* Value to write to ADCSWTRIG to trigger ADC conversion in software trigger
+ * mode. Can be anything. */
+#define PCI230_ADC_CONV 0xffff
+
+/* PCI230+ EXTFUNC values. */
+#define PCI230P_EXTFUNC_GAT_EXTTRIG (1<<0)
+ /* Route EXTTRIG pin to external gate inputs. */
+/* PCI230+ hardware version 2 values. */
+#define PCI230P2_EXTFUNC_DACFIFO (1<<1)
+ /* Allow DAC FIFO to be enabled. */
+
+/*
+ * Counter/timer clock input configuration sources.
+ */
+#define CLK_CLK 0 /* reserved (channel-specific clock) */
+#define CLK_10MHZ 1 /* internal 10 MHz clock */
+#define CLK_1MHZ 2 /* internal 1 MHz clock */
+#define CLK_100KHZ 3 /* internal 100 kHz clock */
+#define CLK_10KHZ 4 /* internal 10 kHz clock */
+#define CLK_1KHZ 5 /* internal 1 kHz clock */
+#define CLK_OUTNM1 6 /* output of channel-1 modulo total */
+#define CLK_EXT 7 /* external clock */
+/* Macro to construct clock input configuration register value. */
+#define CLK_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
+/* Timebases in ns. */
+#define TIMEBASE_10MHZ 100
+#define TIMEBASE_1MHZ 1000
+#define TIMEBASE_100KHZ 10000
+#define TIMEBASE_10KHZ 100000
+#define TIMEBASE_1KHZ 1000000
+
+/*
+ * Counter/timer gate input configuration sources.
+ */
+#define GAT_VCC 0 /* VCC (i.e. enabled) */
+#define GAT_GND 1 /* GND (i.e. disabled) */
+#define GAT_EXT 2 /* external gate input (PPCn on PCI230) */
+#define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
+/* Macro to construct gate input configuration register value. */
+#define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
+
+/*
+ * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI230 and PCI260:
+ *
+ * Channel's Channel's
+ * clock input gate input
+ * Channel CLK_OUTNM1 GAT_NOUTNM2
+ * ------- ---------- -----------
+ * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
+ * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
+ * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
+ */
+
+/* Interrupt enables/status register values. */
+#define PCI230_INT_DISABLE 0
+#define PCI230_INT_PPI_C0 (1<<0)
+#define PCI230_INT_PPI_C3 (1<<1)
+#define PCI230_INT_ADC (1<<2)
+#define PCI230_INT_ZCLK_CT1 (1<<5)
+/* For PCI230+ hardware version 2 when DAC FIFO enabled. */
+#define PCI230P2_INT_DAC (1<<4)
+
+#define PCI230_TEST_BIT(val, n) ((val>>n)&1)
+ /* Assumes bits numbered with zero offset, ie. 0-15 */
+
+/* (Potentially) shared resources and their owners */
+enum {
+ RES_Z2CT0, /* Z2-CT0 */
+ RES_Z2CT1, /* Z2-CT1 */
+ RES_Z2CT2, /* Z2-CT2 */
+ NUM_RESOURCES /* Number of (potentially) shared resources. */
+};
+
+enum {
+ OWNER_NONE, /* Not owned */
+ OWNER_AICMD, /* Owned by AI command */
+ OWNER_AOCMD /* Owned by AO command */
+};
+
+/*
+ * Handy macros.
+ */
+
+/* Combine old and new bits. */
+#define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
+
+/* A generic null function pointer value. */
+#define NULLFUNC 0
+
+/* Current CPU. XXX should this be hard_smp_processor_id()? */
+#define THISCPU smp_processor_id()
+
+/* State flags for atomic bit operations */
+#define AI_CMD_STARTED 0
+#define AO_CMD_STARTED 1
+
+/*
+ * Board descriptions for the two boards supported.
+ */
+
+struct pci230_board {
+ const char *name;
+ unsigned short id;
+ int ai_chans;
+ int ai_bits;
+ int ao_chans;
+ int ao_bits;
+ int have_dio;
+ unsigned int min_hwver; /* Minimum hardware version supported. */
+};
+static const struct pci230_board pci230_boards[] = {
+ {
+ name: "pci230+",
+ id: PCI_DEVICE_ID_PCI230,
+ ai_chans:16,
+ ai_bits: 16,
+ ao_chans:2,
+ ao_bits: 12,
+ have_dio:1,
+ min_hwver:1,
+ },
+ {
+ name: "pci260+",
+ id: PCI_DEVICE_ID_PCI260,
+ ai_chans:16,
+ ai_bits: 16,
+ ao_chans:0,
+ ao_bits: 0,
+ have_dio:0,
+ min_hwver:1,
+ },
+ {
+ name: "pci230",
+ id: PCI_DEVICE_ID_PCI230,
+ ai_chans:16,
+ ai_bits: 12,
+ ao_chans:2,
+ ao_bits: 12,
+ have_dio:1,
+ },
+ {
+ name: "pci260",
+ id: PCI_DEVICE_ID_PCI260,
+ ai_chans:16,
+ ai_bits: 12,
+ ao_chans:0,
+ ao_bits: 0,
+ have_dio:0,
+ },
+ {
+ name: "amplc_pci230", /* Wildcard matches any above */
+ id: PCI_DEVICE_ID_INVALID,
+ },
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci230_pci_table) = {
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230, PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0, 0},
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260, PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci230_pci_table);
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define n_pci230_boards (sizeof(pci230_boards)/sizeof(pci230_boards[0]))
+#define thisboard ((const struct pci230_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct pci230_private {
+ struct pci_dev *pci_dev;
+ spinlock_t isr_spinlock; /* Interrupt spin lock */
+ spinlock_t res_spinlock; /* Shared resources spin lock */
+ spinlock_t ai_stop_spinlock; /* Spin lock for stopping AI command */
+ spinlock_t ao_stop_spinlock; /* Spin lock for stopping AO command */
+ unsigned long state; /* State flags */
+ unsigned long iobase1; /* PCI230's I/O space 1 */
+ unsigned int ao_readback[2]; /* Used for AO readback */
+ unsigned int ai_scan_count; /* Number of analogue input scans
+ * remaining. */
+ unsigned int ai_scan_pos; /* Current position within analogue
+ * input scan */
+ unsigned int ao_scan_count; /* Number of analogue output scans
+ * remaining. */
+ int intr_cpuid; /* ID of CPU running interrupt routine. */
+ unsigned short hwver; /* Hardware version (for '+' models). */
+ unsigned short adccon; /* ADCCON register value. */
+ unsigned short daccon; /* DACCON register value. */
+ unsigned short adcfifothresh; /* ADC FIFO programmable interrupt
+ * level threshold (PCI230+/260+). */
+ unsigned short adcg; /* ADCG register value. */
+ unsigned char int_en; /* Interrupt enables bits. */
+ unsigned char ai_continuous; /* Flag set when cmd->stop_src ==
+ * TRIG_NONE - user chooses to stop
+ * continuous conversion by
+ * cancelation. */
+ unsigned char ao_continuous; /* Flag set when cmd->stop_src ==
+ * TRIG_NONE - user chooses to stop
+ * continuous conversion by
+ * cancelation. */
+ unsigned char ai_bipolar; /* Set if bipolar input range so we
+ * know to mangle it. */
+ unsigned char ao_bipolar; /* Set if bipolar output range so we
+ * know to mangle it. */
+ unsigned char ier; /* Copy of interrupt enables/status register. */
+ unsigned char intr_running; /* Flag set in interrupt routine. */
+ unsigned char res_owner[NUM_RESOURCES]; /* Shared resource owners. */
+};
+
+#define devpriv ((struct pci230_private *)dev->private)
+
+/* PCI230 clock source periods in ns */
+static const unsigned int pci230_timebase[8] = {
+ [CLK_10MHZ] = TIMEBASE_10MHZ,
+ [CLK_1MHZ] = TIMEBASE_1MHZ,
+ [CLK_100KHZ] = TIMEBASE_100KHZ,
+ [CLK_10KHZ] = TIMEBASE_10KHZ,
+ [CLK_1KHZ] = TIMEBASE_1KHZ,
+};
+
+/* PCI230 analogue input range table */
+static const struct comedi_lrange pci230_ai_range = { 7, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5)
+ }
+};
+
+/* PCI230 analogue gain bits for each input range. */
+static const unsigned char pci230_ai_gain[7] = { 0, 1, 2, 3, 1, 2, 3 };
+
+/* PCI230 adccon bipolar flag for each analogue input range. */
+static const unsigned char pci230_ai_bipolar[7] = { 1, 1, 1, 1, 0, 0, 0 };
+
+/* PCI230 analogue output range table */
+static const struct comedi_lrange pci230_ao_range = { 2, {
+ UNI_RANGE(10),
+ BIP_RANGE(10)
+ }
+};
+
+/* PCI230 daccon bipolar flag for each analogue output range. */
+static const unsigned char pci230_ao_bipolar[2] = { 0, 1 };
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pci230_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci230_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_pci230 = {
+ driver_name:"amplc_pci230",
+ module:THIS_MODULE,
+ attach:pci230_attach,
+ detach:pci230_detach,
+ board_name:&pci230_boards[0].name,
+ offset:sizeof(pci230_boards[0]),
+ num_names:sizeof(pci230_boards) / sizeof(pci230_boards[0]),
+};
+
+COMEDI_PCI_INITCLEANUP(driver_amplc_pci230, pci230_pci_table);
+
+static int pci230_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pci230_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pci230_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static void pci230_ct_setup_ns_mode(struct comedi_device * dev, unsigned int ct,
+ unsigned int mode, uint64_t ns, unsigned int round);
+static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round);
+static void pci230_cancel_ct(struct comedi_device * dev, unsigned int ct);
+static irqreturn_t pci230_interrupt(int irq, void *d PT_REGS_ARG);
+static int pci230_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int pci230_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci230_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci230_ao_stop(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci230_handle_ao_nofifo(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci230_handle_ao_fifo(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci230_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int pci230_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci230_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci230_ai_stop(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci230_handle_ai(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static short pci230_ai_read(struct comedi_device * dev)
+{
+ /* Read sample. */
+ short data = (short) inw(dev->iobase + PCI230_ADCDATA);
+
+ /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
+ * four bits reserved for expansion). */
+ /* PCI230+ is 16 bit AI. */
+ data = data >> (16 - thisboard->ai_bits);
+
+ /* If a bipolar range was specified, mangle it (twos
+ * complement->straight binary). */
+ if (devpriv->ai_bipolar) {
+ data ^= 1 << (thisboard->ai_bits - 1);
+ }
+ return data;
+}
+
+static inline unsigned short pci230_ao_mangle_datum(struct comedi_device * dev,
+ short datum)
+{
+ /* If a bipolar range was specified, mangle it (straight binary->twos
+ * complement). */
+ if (devpriv->ao_bipolar) {
+ datum ^= 1 << (thisboard->ao_bits - 1);
+ }
+
+ /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
+ * four bits reserved for expansion). */
+ /* PCI230+ is also 12 bit AO. */
+ datum <<= (16 - thisboard->ao_bits);
+ return (unsigned short)datum;
+}
+
+static inline void pci230_ao_write_nofifo(struct comedi_device * dev, short datum,
+ unsigned int chan)
+{
+ /* Store unmangled datum to be read back later. */
+ devpriv->ao_readback[chan] = datum;
+
+ /* Write mangled datum to appropriate DACOUT register. */
+ outw(pci230_ao_mangle_datum(dev, datum), dev->iobase + (((chan) == 0)
+ ? PCI230_DACOUT1 : PCI230_DACOUT2));
+}
+
+static inline void pci230_ao_write_fifo(struct comedi_device * dev, short datum,
+ unsigned int chan)
+{
+ /* Store unmangled datum to be read back later. */
+ devpriv->ao_readback[chan] = datum;
+
+ /* Write mangled datum to appropriate DACDATA register. */
+ outw(pci230_ao_mangle_datum(dev, datum),
+ dev->iobase + PCI230P2_DACDATA);
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pci230_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase1, iobase2;
+ /* PCI230's I/O spaces 1 and 2 respectively. */
+ struct pci_dev *pci_dev;
+ int i = 0, irq_hdl, rc;
+
+ printk("comedi%d: amplc_pci230: attach %s %d,%d\n", dev->minor,
+ thisboard->name, it->options[0], it->options[1]);
+
+ /* Allocate the private structure area using alloc_private().
+ * Macro defined in comedidev.h - memsets struct fields to 0. */
+ if ((alloc_private(dev, sizeof(struct pci230_private))) < 0) {
+ return -ENOMEM;
+ }
+ spin_lock_init(&devpriv->isr_spinlock);
+ spin_lock_init(&devpriv->res_spinlock);
+ spin_lock_init(&devpriv->ai_stop_spinlock);
+ spin_lock_init(&devpriv->ao_stop_spinlock);
+ /* Find card */
+ for (pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pci_dev != NULL;
+ pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
+ if (it->options[0] || it->options[1]) {
+ /* Match against bus/slot options. */
+ if (it->options[0] != pci_dev->bus->number ||
+ it->options[1] != PCI_SLOT(pci_dev->devfn))
+ continue;
+ }
+ if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
+ continue;
+ if (thisboard->id == PCI_DEVICE_ID_INVALID) {
+ /* The name was specified as "amplc_pci230" which is
+ * used to match any supported device. Replace the
+ * current dev->board_ptr with one that matches the
+ * PCI device ID. */
+ for (i = 0; i < n_pci230_boards; i++) {
+ if (pci_dev->device == pci230_boards[i].id) {
+ if (pci230_boards[i].min_hwver > 0) {
+ /* Check for a '+' model.
+ * First check length of
+ * registers. */
+ if (pci_resource_len(pci_dev, 3)
+ < 32) {
+ /* Not a '+' model. */
+ continue;
+ }
+ /* TODO: temporarily enable the
+ * PCI device and read the
+ * hardware version register.
+ * For now assume it's okay. */
+ }
+ /* Change board_ptr to matched board */
+ dev->board_ptr = &pci230_boards[i];
+ break;
+ }
+ }
+ if (i < n_pci230_boards)
+ break;
+ } else {
+ /* The name was specified as a specific device name.
+ * The current dev->board_ptr is correct. Check
+ * whether it matches the PCI device ID. */
+ if (thisboard->id == pci_dev->device) {
+ /* Check minimum hardware version. */
+ if (thisboard->min_hwver > 0) {
+ /* Looking for a '+' model. First
+ * check length of registers. */
+ if (pci_resource_len(pci_dev, 3) < 32) {
+ /* Not a '+' model. */
+ continue;
+ }
+ /* TODO: temporarily enable the PCI
+ * device and read the hardware version
+ * register. For now, assume it's
+ * okay. */
+ break;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ if (!pci_dev) {
+ printk("comedi%d: No %s card found\n", dev->minor,
+ thisboard->name);
+ return -EIO;
+ }
+ devpriv->pci_dev = pci_dev;
+
+ /*
+ * Initialize dev->board_name.
+ */
+ dev->board_name = thisboard->name;
+
+ /* Enable PCI device and reserve I/O spaces. */
+ if (comedi_pci_enable(pci_dev, "amplc_pci230") < 0) {
+ printk("comedi%d: failed to enable PCI device "
+ "and request regions\n", dev->minor);
+ return -EIO;
+ }
+
+ /* Read base addresses of the PCI230's two I/O regions from PCI
+ * configuration register. */
+ iobase1 = pci_resource_start(pci_dev, 2);
+ iobase2 = pci_resource_start(pci_dev, 3);
+
+ printk("comedi%d: %s I/O region 1 0x%04lx I/O region 2 0x%04lx\n",
+ dev->minor, dev->board_name, iobase1, iobase2);
+
+ devpriv->iobase1 = iobase1;
+ dev->iobase = iobase2;
+
+ /* Read bits of DACCON register - only the output range. */
+ devpriv->daccon = inw(dev->iobase + PCI230_DACCON) & PCI230_DAC_OR_MASK;
+
+ /* Read hardware version register and set extended function register
+ * if they exist. */
+ if (pci_resource_len(pci_dev, 3) >= 32) {
+ unsigned short extfunc = 0;
+
+ devpriv->hwver = inw(dev->iobase + PCI230P_HWVER);
+ if (devpriv->hwver < thisboard->min_hwver) {
+ printk("comedi%d: %s - bad hardware version "
+ "- got %u, need %u\n", dev->minor,
+ dev->board_name, devpriv->hwver,
+ thisboard->min_hwver);
+ return -EIO;
+ }
+ if (devpriv->hwver > 0) {
+ if (!thisboard->have_dio) {
+ /* No DIO ports. Route counters' external gates
+ * to the EXTTRIG signal (PCI260+ pin 17).
+ * (Otherwise, they would be routed to DIO
+ * inputs PC0, PC1 and PC2 which don't exist
+ * on PCI260[+].) */
+ extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG;
+ }
+ if ((thisboard->ao_chans > 0)
+ && (devpriv->hwver >= 2)) {
+ /* Enable DAC FIFO functionality. */
+ extfunc |= PCI230P2_EXTFUNC_DACFIFO;
+ }
+ }
+ outw(extfunc, dev->iobase + PCI230P_EXTFUNC);
+ if ((extfunc & PCI230P2_EXTFUNC_DACFIFO) != 0) {
+ /* Temporarily enable DAC FIFO, reset it and disable
+ * FIFO wraparound. */
+ outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN
+ | PCI230P2_DAC_FIFO_RESET,
+ dev->iobase + PCI230_DACCON);
+ /* Clear DAC FIFO channel enable register. */
+ outw(0, dev->iobase + PCI230P2_DACEN);
+ /* Disable DAC FIFO. */
+ outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
+ }
+ }
+
+ /* Disable board's interrupts. */
+ outb(0, devpriv->iobase1 + PCI230_INT_SCE);
+
+ /* Set ADC to a reasonable state. */
+ devpriv->adcg = 0;
+ devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE
+ | PCI230_ADC_IR_BIP;
+ outw(1 << 0, dev->iobase + PCI230_ADCEN);
+ outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
+ outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
+ dev->iobase + PCI230_ADCCON);
+
+ /* Register the interrupt handler. */
+ irq_hdl = comedi_request_irq(devpriv->pci_dev->irq, pci230_interrupt,
+ IRQF_SHARED, "amplc_pci230", dev);
+ if (irq_hdl < 0) {
+ printk("comedi%d: unable to register irq, "
+ "commands will not be available %d\n", dev->minor,
+ devpriv->pci_dev->irq);
+ } else {
+ dev->irq = devpriv->pci_dev->irq;
+ printk("comedi%d: registered irq %u\n", dev->minor,
+ devpriv->pci_dev->irq);
+ }
+
+ /*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog input subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
+ s->n_chan = thisboard->ai_chans;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = &pci230_ai_range;
+ s->insn_read = &pci230_ai_rinsn;
+ s->len_chanlist = 256; /* but there are restrictions. */
+ /* Only register commands if the interrupt handler is installed. */
+ if (irq_hdl == 0) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmd = &pci230_ai_cmd;
+ s->do_cmdtest = &pci230_ai_cmdtest;
+ s->cancel = pci230_ai_cancel;
+ }
+
+ s = dev->subdevices + 1;
+ /* analog output subdevice */
+ if (thisboard->ao_chans > 0) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = thisboard->ao_chans;;
+ s->maxdata = (1 << thisboard->ao_bits) - 1;
+ s->range_table = &pci230_ao_range;
+ s->insn_write = &pci230_ao_winsn;
+ s->insn_read = &pci230_ao_rinsn;
+ s->len_chanlist = thisboard->ao_chans;
+ /* Only register commands if the interrupt handler is
+ * installed. */
+ if (irq_hdl == 0) {
+ dev->write_subdev = s;
+ s->subdev_flags |= SDF_CMD_WRITE;
+ s->do_cmd = &pci230_ao_cmd;
+ s->do_cmdtest = &pci230_ao_cmdtest;
+ s->cancel = pci230_ao_cancel;
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 2;
+ /* digital i/o subdevice */
+ if (thisboard->have_dio) {
+ rc = subdev_8255_init(dev, s, NULL,
+ (devpriv->iobase1 + PCI230_PPI_X_BASE));
+ if (rc < 0)
+ return rc;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ printk("comedi%d: attached\n", dev->minor);
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pci230_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: amplc_pci230: remove\n", dev->minor);
+
+ if (dev->subdevices && thisboard->have_dio)
+ /* Clean up dio subdevice. */
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (devpriv) {
+ if (devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+
+ return 0;
+}
+
+static int get_resources(struct comedi_device * dev, unsigned int res_mask,
+ unsigned char owner)
+{
+ int ok;
+ unsigned int i;
+ unsigned int b;
+ unsigned int claimed;
+ unsigned long irqflags;
+
+ ok = 1;
+ claimed = 0;
+ comedi_spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
+ for (b = 1, i = 0; (i < NUM_RESOURCES)
+ && (res_mask != 0); b <<= 1, i++) {
+ if ((res_mask & b) != 0) {
+ res_mask &= ~b;
+ if (devpriv->res_owner[i] == OWNER_NONE) {
+ devpriv->res_owner[i] = owner;
+ claimed |= b;
+ } else if (devpriv->res_owner[i] != owner) {
+ for (b = 1, i = 0; claimed != 0; b <<= 1, i++) {
+ if ((claimed & b) != 0) {
+ devpriv->res_owner[i]
+ = OWNER_NONE;
+ claimed &= ~b;
+ }
+ }
+ ok = 0;
+ break;
+ }
+ }
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
+ return ok;
+}
+
+static inline int get_one_resource(struct comedi_device * dev, unsigned int resource,
+ unsigned char owner)
+{
+ return get_resources(dev, (1U << resource), owner);
+}
+
+static void put_resources(struct comedi_device * dev, unsigned int res_mask,
+ unsigned char owner)
+{
+ unsigned int i;
+ unsigned int b;
+ unsigned long irqflags;
+
+ comedi_spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
+ for (b = 1, i = 0; (i < NUM_RESOURCES)
+ && (res_mask != 0); b <<= 1, i++) {
+ if ((res_mask & b) != 0) {
+ res_mask &= ~b;
+ if (devpriv->res_owner[i] == owner) {
+ devpriv->res_owner[i] = OWNER_NONE;
+ }
+ }
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
+}
+
+static inline void put_one_resource(struct comedi_device * dev, unsigned int resource,
+ unsigned char owner)
+{
+ put_resources(dev, (1U << resource), owner);
+}
+
+static inline void put_all_resources(struct comedi_device * dev, unsigned char owner)
+{
+ put_resources(dev, (1U << NUM_RESOURCES) - 1, owner);
+}
+
+/*
+ * COMEDI_SUBD_AI instruction;
+ */
+static int pci230_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int n, i;
+ unsigned int chan, range, aref;
+ unsigned int gainshift;
+ unsigned int status;
+ unsigned short adccon, adcen;
+
+ /* Unpack channel and range. */
+ chan = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+ aref = CR_AREF(insn->chanspec);
+ if (aref == AREF_DIFF) {
+ /* Differential. */
+ if (chan >= s->n_chan / 2) {
+ DPRINTK("comedi%d: amplc_pci230: ai_rinsn: "
+ "differential channel number out of range "
+ "0 to %u\n", dev->minor, (s->n_chan / 2) - 1);
+ return -EINVAL;
+ }
+ }
+
+ /* Use Z2-CT2 as a conversion trigger instead of the built-in
+ * software trigger, as otherwise triggering of differential channels
+ * doesn't work properly for some versions of PCI230/260. Also set
+ * FIFO mode because the ADC busy bit only works for software triggers.
+ */
+ adccon = PCI230_ADC_TRIG_Z2CT2 | PCI230_ADC_FIFO_EN;
+ /* Set Z2-CT2 output low to avoid any false triggers. */
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE0);
+ devpriv->ai_bipolar = pci230_ai_bipolar[range];
+ if (aref == AREF_DIFF) {
+ /* Differential. */
+ gainshift = chan * 2;
+ if (devpriv->hwver == 0) {
+ /* Original PCI230/260 expects both inputs of the
+ * differential channel to be enabled. */
+ adcen = 3 << gainshift;
+ } else {
+ /* PCI230+/260+ expects only one input of the
+ * differential channel to be enabled. */
+ adcen = 1 << gainshift;
+ }
+ adccon |= PCI230_ADC_IM_DIF;
+ } else {
+ /* Single ended. */
+ adcen = 1 << chan;
+ gainshift = chan & ~1;
+ adccon |= PCI230_ADC_IM_SE;
+ }
+ devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
+ | (pci230_ai_gain[range] << gainshift);
+ if (devpriv->ai_bipolar) {
+ adccon |= PCI230_ADC_IR_BIP;
+ } else {
+ adccon |= PCI230_ADC_IR_UNI;
+ }
+
+ /* Enable only this channel in the scan list - otherwise by default
+ * we'll get one sample from each channel. */
+ outw(adcen, dev->iobase + PCI230_ADCEN);
+
+ /* Set gain for channel. */
+ outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
+
+ /* Specify uni/bip, se/diff, conversion source, and reset FIFO. */
+ devpriv->adccon = adccon;
+ outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
+
+ /* Convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ /* Trigger conversion by toggling Z2-CT2 output (finish with
+ * output high). */
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
+ I8254_MODE0);
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
+ I8254_MODE1);
+
+#define TIMEOUT 100
+ /* wait for conversion to end */
+ for (i = 0; i < TIMEOUT; i++) {
+ status = inw(dev->iobase + PCI230_ADCCON);
+ if (!(status & PCI230_ADC_FIFO_EMPTY))
+ break;
+ comedi_udelay(1);
+ }
+ if (i == TIMEOUT) {
+ /* rt_printk() should be used instead of printk()
+ * whenever the code can be called from real-time. */
+ rt_printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ /* read data */
+ data[n] = pci230_ai_read(dev);
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+/*
+ * COMEDI_SUBD_AO instructions;
+ */
+static int pci230_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan, range;
+
+ /* Unpack channel and range. */
+ chan = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+
+ /* Set range - see analogue output range table; 0 => unipolar 10V,
+ * 1 => bipolar +/-10V range scale */
+ devpriv->ao_bipolar = pci230_ao_bipolar[range];
+ outw(range, dev->iobase + PCI230_DACCON);
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ /* Write value to DAC and store it. */
+ pci230_ao_write_nofifo(dev, data[i], chan);
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int pci230_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+static int pci230_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* Step 1: make sure trigger sources are trivially valid.
+ * "invalid source" returned by comedilib to user mode process
+ * if this fails. */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_INT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ if ((thisboard->min_hwver > 0) && (devpriv->hwver >= 2)) {
+ /*
+ * For PCI230+ hardware version 2 onwards, allow external
+ * trigger from EXTTRIG/EXTCONVCLK input (PCI230+ pin 25).
+ *
+ * FIXME: The permitted scan_begin_src values shouldn't depend
+ * on devpriv->hwver (the detected card's actual hardware
+ * version). They should only depend on thisboard->min_hwver
+ * (the static capabilities of the configured card). To fix
+ * it, a new card model, e.g. "pci230+2" would have to be
+ * defined with min_hwver set to 2. It doesn't seem worth it
+ * for this alone. At the moment, please consider
+ * scan_begin_src==TRIG_EXT support to be a bonus rather than a
+ * guarantee!
+ */
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_INT | TRIG_EXT;
+ } else {
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_INT;
+ }
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* Step 2: make sure trigger sources are unique and mutually compatible
+ * "source conflict" returned by comedilib to user mode process
+ * if this fails. */
+
+ /* these tests are true if more than one _src bit is set */
+ if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+ err++;
+ if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+ err++;
+ if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* Step 3: make sure arguments are trivially compatible.
+ * "invalid argument" returned by comedilib to user mode process
+ * if this fails. */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED_AO 8000 /* 8000 ns => 125 kHz */
+#define MIN_SPEED_AO 4294967295u /* 4294967295ns = 4.29s */
+ /*- Comedi limit due to unsigned int cmd. Driver limit
+ * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
+ * clock) = 65.536s */
+
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ if (cmd->scan_begin_arg < MAX_SPEED_AO) {
+ cmd->scan_begin_arg = MAX_SPEED_AO;
+ err++;
+ }
+ if (cmd->scan_begin_arg > MIN_SPEED_AO) {
+ cmd->scan_begin_arg = MIN_SPEED_AO;
+ err++;
+ }
+ break;
+ case TRIG_EXT:
+ /* External trigger - for PCI230+ hardware version 2 onwards. */
+ /* Trigger number must be 0. */
+ if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
+ cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+ ~CR_FLAGS_MASK);
+ err++;
+ }
+ /* The only flags allowed are CR_EDGE and CR_INVERT. The
+ * CR_EDGE flag is ignored. */
+ if ((cmd->scan_begin_arg
+ & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) !=
+ 0) {
+ cmd->scan_begin_arg =
+ COMBINE(cmd->scan_begin_arg, 0,
+ CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
+ err++;
+ }
+ break;
+ default:
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ break;
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_NONE) {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* Step 4: fix up any arguments.
+ * "argument conflict" returned by comedilib to user mode process
+ * if this fails. */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ pci230_ns_to_single_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ /* Step 5: check channel list if it exists. */
+
+ if (cmd->chanlist && cmd->chanlist_len > 0) {
+ enum {
+ seq_err = (1 << 0),
+ range_err = (1 << 1)
+ };
+ unsigned int errors;
+ unsigned int n;
+ unsigned int chan, prev_chan;
+ unsigned int range, first_range;
+
+ prev_chan = CR_CHAN(cmd->chanlist[0]);
+ first_range = CR_RANGE(cmd->chanlist[0]);
+ errors = 0;
+ for (n = 1; n < cmd->chanlist_len; n++) {
+ chan = CR_CHAN(cmd->chanlist[n]);
+ range = CR_RANGE(cmd->chanlist[n]);
+ /* Channel numbers must strictly increase. */
+ if (chan < prev_chan) {
+ errors |= seq_err;
+ }
+ /* Ranges must be the same. */
+ if (range != first_range) {
+ errors |= range_err;
+ }
+ prev_chan = chan;
+ }
+ if (errors != 0) {
+ err++;
+ if ((errors & seq_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
+ "channel numbers must increase\n",
+ dev->minor);
+ }
+ if ((errors & range_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
+ "channels must have the same range\n",
+ dev->minor);
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int pci230_ao_inttrig_scan_begin(struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned int trig_num)
+{
+ unsigned long irqflags;
+
+ if (trig_num != 0)
+ return -EINVAL;
+
+ comedi_spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
+ if (test_bit(AO_CMD_STARTED, &devpriv->state)) {
+ /* Perform scan. */
+ if (devpriv->hwver < 2) {
+ /* Not using DAC FIFO. */
+ comedi_spin_unlock_irqrestore(&devpriv->
+ ao_stop_spinlock, irqflags);
+ pci230_handle_ao_nofifo(dev, s);
+ comedi_event(dev, s);
+ } else {
+ /* Using DAC FIFO. */
+ /* Read DACSWTRIG register to trigger conversion. */
+ inw(dev->iobase + PCI230P2_DACSWTRIG);
+ comedi_spin_unlock_irqrestore(&devpriv->
+ ao_stop_spinlock, irqflags);
+ }
+ /* Delay. Should driver be responsible for this? */
+ /* XXX TODO: See if DAC busy bit can be used. */
+ comedi_udelay(8);
+ }
+
+ return 1;
+}
+
+static void pci230_ao_start(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned long irqflags;
+
+ set_bit(AO_CMD_STARTED, &devpriv->state);
+ if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) {
+ /* An empty acquisition! */
+ async->events |= COMEDI_CB_EOA;
+ pci230_ao_stop(dev, s);
+ comedi_event(dev, s);
+ } else {
+ if (devpriv->hwver >= 2) {
+ /* Using DAC FIFO. */
+ unsigned short scantrig;
+ int run;
+
+ /* Preload FIFO data. */
+ run = pci230_handle_ao_fifo(dev, s);
+ comedi_event(dev, s);
+ if (!run) {
+ /* Stopped. */
+ return;
+ }
+ /* Set scan trigger source. */
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ scantrig = PCI230P2_DAC_TRIG_Z2CT1;
+ break;
+ case TRIG_EXT:
+ /* Trigger on EXTTRIG/EXTCONVCLK pin. */
+ if ((cmd->scan_begin_arg & CR_INVERT) == 0) {
+ /* +ve edge */
+ scantrig = PCI230P2_DAC_TRIG_EXTP;
+ } else {
+ /* -ve edge */
+ scantrig = PCI230P2_DAC_TRIG_EXTN;
+ }
+ break;
+ case TRIG_INT:
+ scantrig = PCI230P2_DAC_TRIG_SW;
+ break;
+ default:
+ /* Shouldn't get here. */
+ scantrig = PCI230P2_DAC_TRIG_NONE;
+ break;
+ }
+ devpriv->daccon = (devpriv->daccon
+ & ~PCI230P2_DAC_TRIG_MASK) | scantrig;
+ outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
+
+ }
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ if (devpriv->hwver < 2) {
+ /* Not using DAC FIFO. */
+ /* Enable CT1 timer interrupt. */
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock,
+ irqflags);
+ devpriv->int_en |= PCI230_INT_ZCLK_CT1;
+ devpriv->ier |= PCI230_INT_ZCLK_CT1;
+ outb(devpriv->ier,
+ devpriv->iobase1 + PCI230_INT_SCE);
+ comedi_spin_unlock_irqrestore(&devpriv->
+ isr_spinlock, irqflags);
+ }
+ /* Set CT1 gate high to start counting. */
+ outb(GAT_CONFIG(1, GAT_VCC),
+ devpriv->iobase1 + PCI230_ZGAT_SCE);
+ break;
+ case TRIG_INT:
+ async->inttrig = pci230_ao_inttrig_scan_begin;
+ break;
+ }
+ if (devpriv->hwver >= 2) {
+ /* Using DAC FIFO. Enable DAC FIFO interrupt. */
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock,
+ irqflags);
+ devpriv->int_en |= PCI230P2_INT_DAC;
+ devpriv->ier |= PCI230P2_INT_DAC;
+ outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock,
+ irqflags);
+ }
+ }
+}
+
+static int pci230_ao_inttrig_start(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trig_num)
+{
+ if (trig_num != 0)
+ return -EINVAL;
+
+ s->async->inttrig = NULLFUNC;
+ pci230_ao_start(dev, s);
+
+ return 1;
+}
+
+static int pci230_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned short daccon;
+ unsigned int range;
+
+ /* Get the command. */
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* Claim Z2-CT1. */
+ if (!get_one_resource(dev, RES_Z2CT1, OWNER_AOCMD)) {
+ return -EBUSY;
+ }
+ }
+
+ /* Get number of scans required. */
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ao_scan_count = cmd->stop_arg;
+ devpriv->ao_continuous = 0;
+ } else {
+ /* TRIG_NONE, user calls cancel. */
+ devpriv->ao_scan_count = 0;
+ devpriv->ao_continuous = 1;
+ }
+
+ /* Set range - see analogue output range table; 0 => unipolar 10V,
+ * 1 => bipolar +/-10V range scale */
+ range = CR_RANGE(cmd->chanlist[0]);
+ devpriv->ao_bipolar = pci230_ao_bipolar[range];
+ daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI;
+ /* Use DAC FIFO for hardware version 2 onwards. */
+ if (devpriv->hwver >= 2) {
+ unsigned short dacen;
+ unsigned int i;
+
+ dacen = 0;
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ dacen |= 1 << CR_CHAN(cmd->chanlist[i]);
+ }
+ /* Set channel scan list. */
+ outw(dacen, dev->iobase + PCI230P2_DACEN);
+ /*
+ * Enable DAC FIFO.
+ * Set DAC scan source to 'none'.
+ * Set DAC FIFO interrupt trigger level to 'not half full'.
+ * Reset DAC FIFO and clear underrun.
+ *
+ * N.B. DAC FIFO interrupts are currently disabled.
+ */
+ daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET
+ | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR
+ | PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
+ }
+
+ /* Set DACCON. */
+ outw(daccon, dev->iobase + PCI230_DACCON);
+ /* Preserve most of DACCON apart from write-only, transient bits. */
+ devpriv->daccon = daccon
+ & ~(PCI230P2_DAC_FIFO_RESET | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* Set the counter timer 1 to the specified scan frequency. */
+ /* cmd->scan_begin_arg is sampling period in ns */
+ /* gate it off for now. */
+ outb(GAT_CONFIG(1, GAT_GND),
+ devpriv->iobase1 + PCI230_ZGAT_SCE);
+ pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
+ cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+ }
+
+ /* N.B. cmd->start_src == TRIG_INT */
+ s->async->inttrig = pci230_ao_inttrig_start;
+
+ return 0;
+}
+
+static int pci230_ai_check_scan_period(struct comedi_cmd * cmd)
+{
+ unsigned int min_scan_period, chanlist_len;
+ int err = 0;
+
+ chanlist_len = cmd->chanlist_len;
+ if (cmd->chanlist_len == 0) {
+ chanlist_len = 1;
+ }
+ min_scan_period = chanlist_len * cmd->convert_arg;
+ if ((min_scan_period < chanlist_len)
+ || (min_scan_period < cmd->convert_arg)) {
+ /* Arithmetic overflow. */
+ min_scan_period = UINT_MAX;
+ err++;
+ }
+ if (cmd->scan_begin_arg < min_scan_period) {
+ cmd->scan_begin_arg = min_scan_period;
+ err++;
+ }
+
+ return !err;
+}
+
+static int pci230_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4,5 or 0, depending on which tests
+ * the command passes. */
+
+ /* Step 1: make sure trigger sources are trivially valid.
+ * "invalid source" returned by comedilib to user mode process
+ * if this fails. */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_INT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ /* Unfortunately, we cannot trigger a scan off an external source
+ * on the PCI260 board, since it uses the PPIC0 (DIO) input, which
+ * isn't present on the PCI260. For PCI260+ we can use the
+ * EXTTRIG/EXTCONVCLK input on pin 17 instead. */
+ if ((thisboard->have_dio) || (thisboard->min_hwver > 0)) {
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_INT
+ | TRIG_EXT;
+ } else {
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_INT;
+ }
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_INT | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* Step 2: make sure trigger sources are unique and mutually compatible
+ * "source conflict" returned by comedilib to user mode process
+ * if this fails. */
+
+ /* these tests are true if more than one _src bit is set */
+ if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+ err++;
+ if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+ err++;
+ if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+ err++;
+
+ /* If scan_begin_src is not TRIG_FOLLOW, then a monostable will be
+ * set up to generate a fixed number of timed conversion pulses. */
+ if ((cmd->scan_begin_src != TRIG_FOLLOW)
+ && (cmd->convert_src != TRIG_TIMER))
+ err++;
+
+ if (err)
+ return 2;
+
+ /* Step 3: make sure arguments are trivially compatible.
+ * "invalid argument" returned by comedilib to user mode process
+ * if this fails. */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED_AI_SE 3200 /* PCI230 SE: 3200 ns => 312.5 kHz */
+#define MAX_SPEED_AI_DIFF 8000 /* PCI230 DIFF: 8000 ns => 125 kHz */
+#define MAX_SPEED_AI_PLUS 4000 /* PCI230+: 4000 ns => 250 kHz */
+#define MIN_SPEED_AI 4294967295u /* 4294967295ns = 4.29s */
+ /*- Comedi limit due to unsigned int cmd. Driver limit
+ * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
+ * clock) = 65.536s */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ unsigned int max_speed_ai;
+
+ if (devpriv->hwver == 0) {
+ /* PCI230 or PCI260. Max speed depends whether
+ * single-ended or pseudo-differential. */
+ if (cmd->chanlist && (cmd->chanlist_len > 0)) {
+ /* Peek analogue reference of first channel. */
+ if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
+ max_speed_ai = MAX_SPEED_AI_DIFF;
+ } else {
+ max_speed_ai = MAX_SPEED_AI_SE;
+ }
+ } else {
+ /* No channel list. Assume single-ended. */
+ max_speed_ai = MAX_SPEED_AI_SE;
+ }
+ } else {
+ /* PCI230+ or PCI260+. */
+ max_speed_ai = MAX_SPEED_AI_PLUS;
+ }
+
+ if (cmd->convert_arg < max_speed_ai) {
+ cmd->convert_arg = max_speed_ai;
+ err++;
+ }
+ if (cmd->convert_arg > MIN_SPEED_AI) {
+ cmd->convert_arg = MIN_SPEED_AI;
+ err++;
+ }
+ } else if (cmd->convert_src == TRIG_EXT) {
+ /*
+ * external trigger
+ *
+ * convert_arg == (CR_EDGE | 0)
+ * => trigger on +ve edge.
+ * convert_arg == (CR_EDGE | CR_INVERT | 0)
+ * => trigger on -ve edge.
+ */
+ if ((cmd->convert_arg & CR_FLAGS_MASK) != 0) {
+ /* Trigger number must be 0. */
+ if ((cmd->convert_arg & ~CR_FLAGS_MASK) != 0) {
+ cmd->convert_arg = COMBINE(cmd->convert_arg, 0,
+ ~CR_FLAGS_MASK);
+ err++;
+ }
+ /* The only flags allowed are CR_INVERT and CR_EDGE.
+ * CR_EDGE is required. */
+ if ((cmd->convert_arg & (CR_FLAGS_MASK & ~CR_INVERT))
+ != CR_EDGE) {
+ /* Set CR_EDGE, preserve CR_INVERT. */
+ cmd->convert_arg =
+ COMBINE(cmd->start_arg, (CR_EDGE | 0),
+ CR_FLAGS_MASK & ~CR_INVERT);
+ err++;
+ }
+ } else {
+ /* Backwards compatibility with previous versions. */
+ /* convert_arg == 0 => trigger on -ve edge. */
+ /* convert_arg == 1 => trigger on +ve edge. */
+ if (cmd->convert_arg > 1) {
+ /* Default to trigger on +ve edge. */
+ cmd->convert_arg = 1;
+ err++;
+ }
+ }
+ } else {
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if (cmd->stop_src == TRIG_NONE) {
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->scan_begin_src == TRIG_EXT) {
+ /* external "trigger" to begin each scan
+ * scan_begin_arg==0 => use PPC0 input -> gate of CT0 -> gate
+ * of CT2 (sample convert trigger is CT2) */
+ if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
+ cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+ ~CR_FLAGS_MASK);
+ err++;
+ }
+ /* The only flag allowed is CR_EDGE, which is ignored. */
+ if ((cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
+ cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+ CR_FLAGS_MASK & ~CR_EDGE);
+ err++;
+ }
+ } else if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* N.B. cmd->convert_arg is also TRIG_TIMER */
+ if (!pci230_ai_check_scan_period(cmd)) {
+ err++;
+ }
+ } else {
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* Step 4: fix up any arguments.
+ * "argument conflict" returned by comedilib to user mode process
+ * if this fails. */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ pci230_ns_to_single_timer(&cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* N.B. cmd->convert_arg is also TRIG_TIMER */
+ tmp = cmd->scan_begin_arg;
+ pci230_ns_to_single_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (!pci230_ai_check_scan_period(cmd)) {
+ /* Was below minimum required. Round up. */
+ pci230_ns_to_single_timer(&cmd->scan_begin_arg,
+ TRIG_ROUND_UP);
+ pci230_ai_check_scan_period(cmd);
+ }
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ /* Step 5: check channel list if it exists. */
+
+ if (cmd->chanlist && cmd->chanlist_len > 0) {
+ enum {
+ seq_err = 1 << 0,
+ rangepair_err = 1 << 1,
+ polarity_err = 1 << 2,
+ aref_err = 1 << 3,
+ diffchan_err = 1 << 4,
+ buggy_chan0_err = 1 << 5
+ };
+ unsigned int errors;
+ unsigned int chan, prev_chan;
+ unsigned int range, prev_range;
+ unsigned int polarity, prev_polarity;
+ unsigned int aref, prev_aref;
+ unsigned int subseq_len;
+ unsigned int n;
+
+ subseq_len = 0;
+ errors = 0;
+ prev_chan = prev_aref = prev_range = prev_polarity = 0;
+ for (n = 0; n < cmd->chanlist_len; n++) {
+ chan = CR_CHAN(cmd->chanlist[n]);
+ range = CR_RANGE(cmd->chanlist[n]);
+ aref = CR_AREF(cmd->chanlist[n]);
+ polarity = pci230_ai_bipolar[range];
+ /* Only the first half of the channels are available if
+ * differential. (These are remapped in software. In
+ * hardware, only the even channels are available.) */
+ if ((aref == AREF_DIFF)
+ && (chan >= (s->n_chan / 2))) {
+ errors |= diffchan_err;
+ }
+ if (n > 0) {
+ /* Channel numbers must strictly increase or
+ * subsequence must repeat exactly. */
+ if ((chan <= prev_chan)
+ && (subseq_len == 0)) {
+ subseq_len = n;
+ }
+ if ((subseq_len > 0)
+ && (cmd->chanlist[n] !=
+ cmd->chanlist[n %
+ subseq_len])) {
+ errors |= seq_err;
+ }
+ /* Channels must have same AREF. */
+ if (aref != prev_aref) {
+ errors |= aref_err;
+ }
+ /* Channel ranges must have same polarity. */
+ if (polarity != prev_polarity) {
+ errors |= polarity_err;
+ }
+ /* Single-ended channel pairs must have same
+ * range. */
+ if ((aref != AREF_DIFF)
+ && (((chan ^ prev_chan) & ~1) == 0)
+ && (range != prev_range)) {
+ errors |= rangepair_err;
+ }
+ }
+ prev_chan = chan;
+ prev_range = range;
+ prev_aref = aref;
+ prev_polarity = polarity;
+ }
+ if (subseq_len == 0) {
+ /* Subsequence is whole sequence. */
+ subseq_len = n;
+ }
+ /* If channel list is a repeating subsequence, need a whole
+ * number of repeats. */
+ if ((n % subseq_len) != 0) {
+ errors |= seq_err;
+ }
+ if ((devpriv->hwver > 0) && (devpriv->hwver < 4)) {
+ /*
+ * Buggy PCI230+ or PCI260+ requires channel 0 to be
+ * (first) in the sequence if the sequence contains
+ * more than one channel. Hardware versions 1 and 2
+ * have the bug. There is no hardware version 3.
+ *
+ * Actually, there are two firmwares that report
+ * themselves as hardware version 1 (the boards
+ * have different ADC chips with slightly different
+ * timing requirements, which was supposed to be
+ * invisible to software). The first one doesn't
+ * seem to have the bug, but the second one
+ * does, and we can't tell them apart!
+ */
+ if ((subseq_len > 1)
+ && (CR_CHAN(cmd->chanlist[0]) != 0)) {
+ errors |= buggy_chan0_err;
+ }
+ }
+ if (errors != 0) {
+ err++;
+ if ((errors & seq_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+ "channel numbers must increase or "
+ "sequence must repeat exactly\n",
+ dev->minor);
+ }
+ if ((errors & rangepair_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+ "single-ended channel pairs must "
+ "have the same range\n", dev->minor);
+ }
+ if ((errors & polarity_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+ "channel sequence ranges must be all "
+ "bipolar or all unipolar\n",
+ dev->minor);
+ }
+ if ((errors & aref_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+ "channel sequence analogue references "
+ "must be all the same (single-ended "
+ "or differential)\n", dev->minor);
+ }
+ if ((errors & diffchan_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+ "differential channel number out of "
+ "range 0 to %u\n", dev->minor,
+ (s->n_chan / 2) - 1);
+ }
+ if ((errors & buggy_chan0_err) != 0) {
+ /* Use printk instead of DPRINTK here. */
+ printk("comedi: comedi%d: amplc_pci230: "
+ "ai_cmdtest: Buggy PCI230+/260+ "
+ "h/w version %u requires first channel "
+ "of multi-channel sequence to be 0 "
+ "(corrected in h/w version 4)\n",
+ dev->minor, devpriv->hwver);
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static void pci230_ai_update_fifo_trigger_level(struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int scanlen = cmd->scan_end_arg;
+ unsigned int wake;
+ unsigned short triglev;
+ unsigned short adccon;
+
+ if ((cmd->flags & TRIG_WAKE_EOS) != 0) {
+ /* Wake at end of scan. */
+ wake = scanlen - devpriv->ai_scan_pos;
+ } else {
+ if (devpriv->ai_continuous
+ || (devpriv->ai_scan_count
+ >= PCI230_ADC_FIFOLEVEL_HALFFULL)
+ || (scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL)) {
+ wake = PCI230_ADC_FIFOLEVEL_HALFFULL;
+ } else {
+ wake = (devpriv->ai_scan_count * scanlen)
+ - devpriv->ai_scan_pos;
+ }
+ }
+ if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
+ triglev = PCI230_ADC_INT_FIFO_HALF;
+ } else {
+ if ((wake > 1) && (devpriv->hwver > 0)) {
+ /* PCI230+/260+ programmable FIFO interrupt level. */
+ if (devpriv->adcfifothresh != wake) {
+ devpriv->adcfifothresh = wake;
+ outw(wake, dev->iobase + PCI230P_ADCFFTH);
+ }
+ triglev = PCI230P_ADC_INT_FIFO_THRESH;
+ } else {
+ triglev = PCI230_ADC_INT_FIFO_NEMPTY;
+ }
+ }
+ adccon = (devpriv->adccon & ~PCI230_ADC_INT_FIFO_MASK) | triglev;
+ if (adccon != devpriv->adccon) {
+ devpriv->adccon = adccon;
+ outw(adccon, dev->iobase + PCI230_ADCCON);
+ }
+}
+
+static int pci230_ai_inttrig_convert(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trig_num)
+{
+ unsigned long irqflags;
+
+ if (trig_num != 0)
+ return -EINVAL;
+
+ comedi_spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
+ if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
+ unsigned int delayus;
+
+ /* Trigger conversion by toggling Z2-CT2 output. Finish
+ * with output high. */
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
+ I8254_MODE0);
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
+ I8254_MODE1);
+ /* Delay. Should driver be responsible for this? An
+ * alternative would be to wait until conversion is complete,
+ * but we can't tell when it's complete because the ADC busy
+ * bit has a different meaning when FIFO enabled (and when
+ * FIFO not enabled, it only works for software triggers). */
+ if (((devpriv->adccon & PCI230_ADC_IM_MASK)
+ == PCI230_ADC_IM_DIF)
+ && (devpriv->hwver == 0)) {
+ /* PCI230/260 in differential mode */
+ delayus = 8;
+ } else {
+ /* single-ended or PCI230+/260+ */
+ delayus = 4;
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->ai_stop_spinlock,
+ irqflags);
+ comedi_udelay(delayus);
+ } else {
+ comedi_spin_unlock_irqrestore(&devpriv->ai_stop_spinlock,
+ irqflags);
+ }
+
+ return 1;
+}
+
+static int pci230_ai_inttrig_scan_begin(struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned int trig_num)
+{
+ unsigned long irqflags;
+ unsigned char zgat;
+
+ if (trig_num != 0)
+ return -EINVAL;
+
+ comedi_spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
+ if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
+ /* Trigger scan by waggling CT0 gate source. */
+ zgat = GAT_CONFIG(0, GAT_GND);
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ zgat = GAT_CONFIG(0, GAT_VCC);
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
+
+ return 1;
+}
+
+static void pci230_ai_start(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long irqflags;
+ unsigned short conv;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+
+ set_bit(AI_CMD_STARTED, &devpriv->state);
+ if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
+ /* An empty acquisition! */
+ async->events |= COMEDI_CB_EOA;
+ pci230_ai_stop(dev, s);
+ comedi_event(dev, s);
+ } else {
+ /* Enable ADC FIFO trigger level interrupt. */
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ devpriv->int_en |= PCI230_INT_ADC;
+ devpriv->ier |= PCI230_INT_ADC;
+ outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+ /* Update conversion trigger source which is currently set
+ * to CT2 output, which is currently stuck high. */
+ switch (cmd->convert_src) {
+ default:
+ conv = PCI230_ADC_TRIG_NONE;
+ break;
+ case TRIG_TIMER:
+ /* Using CT2 output. */
+ conv = PCI230_ADC_TRIG_Z2CT2;
+ break;
+ case TRIG_EXT:
+ if ((cmd->convert_arg & CR_EDGE) != 0) {
+ if ((cmd->convert_arg & CR_INVERT) == 0) {
+ /* Trigger on +ve edge. */
+ conv = PCI230_ADC_TRIG_EXTP;
+ } else {
+ /* Trigger on -ve edge. */
+ conv = PCI230_ADC_TRIG_EXTN;
+ }
+ } else {
+ /* Backwards compatibility. */
+ if (cmd->convert_arg != 0) {
+ /* Trigger on +ve edge. */
+ conv = PCI230_ADC_TRIG_EXTP;
+ } else {
+ /* Trigger on -ve edge. */
+ conv = PCI230_ADC_TRIG_EXTN;
+ }
+ }
+ break;
+ case TRIG_INT:
+ /* Use CT2 output for software trigger due to problems
+ * in differential mode on PCI230/260. */
+ conv = PCI230_ADC_TRIG_Z2CT2;
+ break;
+ }
+ devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK)
+ | conv;
+ outw(devpriv->adccon, dev->iobase + PCI230_ADCCON);
+ if (cmd->convert_src == TRIG_INT) {
+ async->inttrig = pci230_ai_inttrig_convert;
+ }
+ /* Update FIFO interrupt trigger level, which is currently
+ * set to "full". */
+ pci230_ai_update_fifo_trigger_level(dev, s);
+ if (cmd->convert_src == TRIG_TIMER) {
+ /* Update timer gates. */
+ unsigned char zgat;
+
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ /* Conversion timer CT2 needs to be gated by
+ * inverted output of monostable CT2. */
+ zgat = GAT_CONFIG(2, GAT_NOUTNM2);
+ } else {
+ /* Conversion timer CT2 needs to be gated on
+ * continuously. */
+ zgat = GAT_CONFIG(2, GAT_VCC);
+ }
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ /* Set monostable CT0 trigger source. */
+ switch (cmd->scan_begin_src) {
+ default:
+ zgat = GAT_CONFIG(0, GAT_VCC);
+ break;
+ case TRIG_EXT:
+ /*
+ * For CT0 on PCI230, the external
+ * trigger (gate) signal comes from
+ * PPC0, which is channel 16 of the DIO
+ * subdevice. The application needs to
+ * configure this as an input in order
+ * to use it as an external scan
+ * trigger.
+ */
+ zgat = GAT_CONFIG(0, GAT_EXT);
+ break;
+ case TRIG_TIMER:
+ /*
+ * Monostable CT0 triggered by rising
+ * edge on inverted output of CT1
+ * (falling edge on CT1).
+ */
+ zgat = GAT_CONFIG(0, GAT_NOUTNM2);
+ break;
+ case TRIG_INT:
+ /*
+ * Monostable CT0 is triggered by
+ * inttrig function waggling the CT0
+ * gate source.
+ */
+ zgat = GAT_CONFIG(0, GAT_VCC);
+ break;
+ }
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ /* Scan period timer CT1 needs to be
+ * gated on to start counting. */
+ zgat = GAT_CONFIG(1, GAT_VCC);
+ outb(zgat, devpriv->iobase1
+ + PCI230_ZGAT_SCE);
+ break;
+ case TRIG_INT:
+ async->inttrig =
+ pci230_ai_inttrig_scan_begin;
+ break;
+ }
+ }
+ } else if (cmd->convert_src != TRIG_INT) {
+ /* No longer need Z2-CT2. */
+ put_one_resource(dev, RES_Z2CT2, OWNER_AICMD);
+ }
+ }
+}
+
+static int pci230_ai_inttrig_start(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trig_num)
+{
+ if (trig_num != 0)
+ return -EINVAL;
+
+ s->async->inttrig = NULLFUNC;
+ pci230_ai_start(dev, s);
+
+ return 1;
+}
+
+static int pci230_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned int i, chan, range, diff;
+ unsigned int res_mask;
+ unsigned short adccon, adcen;
+ unsigned char zgat;
+
+ /* Get the command. */
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+
+ /*
+ * Determine which shared resources are needed.
+ */
+ res_mask = 0;
+ /* Need Z2-CT2 to supply a conversion trigger source at a high
+ * logic level, even if not doing timed conversions. */
+ res_mask |= (1U << RES_Z2CT2);
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ /* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */
+ res_mask |= (1U << RES_Z2CT0);
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* Using Z2-CT1 for scan frequency */
+ res_mask |= (1U << RES_Z2CT1);
+ }
+ }
+ /* Claim resources. */
+ if (!get_resources(dev, res_mask, OWNER_AICMD)) {
+ return -EBUSY;
+ }
+
+ /* Get number of scans required. */
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ai_scan_count = cmd->stop_arg;
+ devpriv->ai_continuous = 0;
+ } else {
+ /* TRIG_NONE, user calls cancel. */
+ devpriv->ai_scan_count = 0;
+ devpriv->ai_continuous = 1;
+ }
+ devpriv->ai_scan_pos = 0; /* Position within scan. */
+
+ /* Steps;
+ * - Set channel scan list.
+ * - Set channel gains.
+ * - Enable and reset FIFO, specify uni/bip, se/diff, and set
+ * start conversion source to point to something at a high logic
+ * level (we use the output of counter/timer 2 for this purpose.
+ * - PAUSE to allow things to settle down.
+ * - Reset the FIFO again because it needs resetting twice and there
+ * may have been a false conversion trigger on some versions of
+ * PCI230/260 due to the start conversion source being set to a
+ * high logic level.
+ * - Enable ADC FIFO level interrupt.
+ * - Set actual conversion trigger source and FIFO interrupt trigger
+ * level.
+ * - If convert_src is TRIG_TIMER, set up the timers.
+ */
+
+ adccon = PCI230_ADC_FIFO_EN;
+ adcen = 0;
+
+ if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
+ /* Differential - all channels must be differential. */
+ diff = 1;
+ adccon |= PCI230_ADC_IM_DIF;
+ } else {
+ /* Single ended - all channels must be single-ended. */
+ diff = 0;
+ adccon |= PCI230_ADC_IM_SE;
+ }
+
+ range = CR_RANGE(cmd->chanlist[0]);
+ devpriv->ai_bipolar = pci230_ai_bipolar[range];
+ if (devpriv->ai_bipolar) {
+ adccon |= PCI230_ADC_IR_BIP;
+ } else {
+ adccon |= PCI230_ADC_IR_UNI;
+ }
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ unsigned int gainshift;
+
+ chan = CR_CHAN(cmd->chanlist[i]);
+ range = CR_RANGE(cmd->chanlist[i]);
+ if (diff) {
+ gainshift = 2 * chan;
+ if (devpriv->hwver == 0) {
+ /* Original PCI230/260 expects both inputs of
+ * the differential channel to be enabled. */
+ adcen |= 3 << gainshift;
+ } else {
+ /* PCI230+/260+ expects only one input of the
+ * differential channel to be enabled. */
+ adcen |= 1 << gainshift;
+ }
+ } else {
+ gainshift = (chan & ~1);
+ adcen |= 1 << chan;
+ }
+ devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
+ | (pci230_ai_gain[range] << gainshift);
+ }
+
+ /* Set channel scan list. */
+ outw(adcen, dev->iobase + PCI230_ADCEN);
+
+ /* Set channel gains. */
+ outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
+
+ /* Set counter/timer 2 output high for use as the initial start
+ * conversion source. */
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE1);
+
+ /* Temporarily use CT2 output as conversion trigger source and
+ * temporarily set FIFO interrupt trigger level to 'full'. */
+ adccon |= PCI230_ADC_INT_FIFO_FULL | PCI230_ADC_TRIG_Z2CT2;
+
+ /* Enable and reset FIFO, specify FIFO trigger level full, specify
+ * uni/bip, se/diff, and temporarily set the start conversion source
+ * to CT2 output. Note that CT2 output is currently high, and this
+ * will produce a false conversion trigger on some versions of the
+ * PCI230/260, but that will be dealt with later. */
+ devpriv->adccon = adccon;
+ outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
+
+ /* Delay */
+ /* Failure to include this will result in the first few channels'-worth
+ * of data being corrupt, normally manifesting itself by large negative
+ * voltages. It seems the board needs time to settle between the first
+ * FIFO reset (above) and the second FIFO reset (below). Setting the
+ * channel gains and scan list _before_ the first FIFO reset also
+ * helps, though only slightly. */
+ comedi_udelay(25);
+
+ /* Reset FIFO again. */
+ outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ /* Set up CT2 as conversion timer, but gate it off for now.
+ * Note, counter/timer output 2 can be monitored on the
+ * connector: PCI230 pin 21, PCI260 pin 18. */
+ zgat = GAT_CONFIG(2, GAT_GND);
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ /* Set counter/timer 2 to the specified conversion period. */
+ pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ /*
+ * Set up monostable on CT0 output for scan timing. A
+ * rising edge on the trigger (gate) input of CT0 will
+ * trigger the monostable, causing its output to go low
+ * for the configured period. The period depends on
+ * the conversion period and the number of conversions
+ * in the scan.
+ *
+ * Set the trigger high before setting up the
+ * monostable to stop it triggering. The trigger
+ * source will be changed later.
+ */
+ zgat = GAT_CONFIG(0, GAT_VCC);
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1,
+ ((uint64_t) cmd->convert_arg
+ * cmd->scan_end_arg), TRIG_ROUND_UP);
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /*
+ * Monostable on CT0 will be triggered by
+ * output of CT1 at configured scan frequency.
+ *
+ * Set up CT1 but gate it off for now.
+ */
+ zgat = GAT_CONFIG(1, GAT_GND);
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
+ cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ }
+ }
+ }
+
+ if (cmd->start_src == TRIG_INT) {
+ s->async->inttrig = pci230_ai_inttrig_start;
+ } else {
+ /* TRIG_NOW */
+ pci230_ai_start(dev, s);
+ }
+
+ return 0;
+}
+
+static unsigned int divide_ns(uint64_t ns, unsigned int timebase,
+ unsigned int round_mode)
+{
+ uint64_t div;
+ unsigned int rem;
+
+ div = ns;
+ rem = do_div(div, timebase);
+ round_mode &= TRIG_ROUND_MASK;
+ switch (round_mode) {
+ default:
+ case TRIG_ROUND_NEAREST:
+ div += (rem + (timebase / 2)) / timebase;
+ break;
+ case TRIG_ROUND_DOWN:
+ break;
+ case TRIG_ROUND_UP:
+ div += (rem + timebase - 1) / timebase;
+ break;
+ }
+ return div > UINT_MAX ? UINT_MAX : (unsigned int)div;
+}
+
+/* Given desired period in ns, returns the required internal clock source
+ * and gets the initial count. */
+static unsigned int pci230_choose_clk_count(uint64_t ns, unsigned int *count,
+ unsigned int round_mode)
+{
+ unsigned int clk_src, cnt;
+
+ for (clk_src = CLK_10MHZ;; clk_src++) {
+ cnt = divide_ns(ns, pci230_timebase[clk_src], round_mode);
+ if ((cnt <= 65536) || (clk_src == CLK_1KHZ)) {
+ break;
+ }
+ }
+ *count = cnt;
+ return clk_src;
+}
+
+static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round)
+{
+ unsigned int count;
+ unsigned int clk_src;
+
+ clk_src = pci230_choose_clk_count(*ns, &count, round);
+ *ns = count * pci230_timebase[clk_src];
+ return;
+}
+
+static void pci230_ct_setup_ns_mode(struct comedi_device * dev, unsigned int ct,
+ unsigned int mode, uint64_t ns, unsigned int round)
+{
+ unsigned int clk_src;
+ unsigned int count;
+
+ /* Set mode. */
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, mode);
+ /* Determine clock source and count. */
+ clk_src = pci230_choose_clk_count(ns, &count, round);
+ /* Program clock source. */
+ outb(CLK_CONFIG(ct, clk_src), devpriv->iobase1 + PCI230_ZCLK_SCE);
+ /* Set initial count. */
+ if (count >= 65536) {
+ count = 0;
+ }
+ i8254_write(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, count);
+}
+
+static void pci230_cancel_ct(struct comedi_device * dev, unsigned int ct)
+{
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct,
+ I8254_MODE1);
+ /* Counter ct, 8254 mode 1, initial count not written. */
+}
+
+/* Interrupt handler */
+static irqreturn_t pci230_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ unsigned char status_int, valid_status_int;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
+ unsigned long irqflags;
+
+ /* Read interrupt status/enable register. */
+ status_int = inb(devpriv->iobase1 + PCI230_INT_STAT);
+
+ if (status_int == PCI230_INT_DISABLE) {
+ return IRQ_NONE;
+ }
+
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ valid_status_int = devpriv->int_en & status_int;
+ /* Disable triggered interrupts.
+ * (Only those interrupts that need re-enabling, are, later in the
+ * handler). */
+ devpriv->ier = devpriv->int_en & ~status_int;
+ outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+ devpriv->intr_running = 1;
+ devpriv->intr_cpuid = THISCPU;
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+ /*
+ * Check the source of interrupt and handle it.
+ * The PCI230 can cope with concurrent ADC, DAC, PPI C0 and C3
+ * interrupts. However, at present (Comedi-0.7.60) does not allow
+ * concurrent execution of commands, instructions or a mixture of the
+ * two.
+ */
+
+ if ((valid_status_int & PCI230_INT_ZCLK_CT1) != 0) {
+ s = dev->write_subdev;
+ pci230_handle_ao_nofifo(dev, s);
+ comedi_event(dev, s);
+ }
+
+ if ((valid_status_int & PCI230P2_INT_DAC) != 0) {
+ s = dev->write_subdev;
+ pci230_handle_ao_fifo(dev, s);
+ comedi_event(dev, s);
+ }
+
+ if ((valid_status_int & PCI230_INT_ADC) != 0) {
+ s = dev->read_subdev;
+ pci230_handle_ai(dev, s);
+ comedi_event(dev, s);
+ }
+
+ /* Reenable interrupts. */
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ if (devpriv->ier != devpriv->int_en) {
+ devpriv->ier = devpriv->int_en;
+ outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+ }
+ devpriv->intr_running = 0;
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+ return IRQ_HANDLED;
+}
+
+static void pci230_handle_ao_nofifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ short data;
+ int i, ret;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+
+ if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) {
+ return;
+ }
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ /* Read sample from Comedi's circular buffer. */
+ ret = comedi_buf_get(s->async, &data);
+ if (ret == 0) {
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ pci230_ao_stop(dev, s);
+ comedi_error(dev, "AO buffer underrun");
+ return;
+ }
+ /* Write value to DAC. */
+ pci230_ao_write_nofifo(dev, data, CR_CHAN(cmd->chanlist[i]));
+ }
+
+ async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+ if (!devpriv->ao_continuous) {
+ devpriv->ao_scan_count--;
+ if (devpriv->ao_scan_count == 0) {
+ /* End of acquisition. */
+ async->events |= COMEDI_CB_EOA;
+ pci230_ao_stop(dev, s);
+ }
+ }
+}
+
+/* Loads DAC FIFO (if using it) from buffer. */
+/* Returns 0 if AO finished due to completion or error, 1 if still going. */
+static int pci230_handle_ao_fifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int num_scans;
+ unsigned int room;
+ unsigned short dacstat;
+ unsigned int i, n;
+ unsigned int bytes_per_scan;
+ unsigned int events = 0;
+ int running;
+
+ /* Get DAC FIFO status. */
+ dacstat = inw(dev->iobase + PCI230_DACCON);
+
+ /* Determine number of scans available in buffer. */
+ bytes_per_scan = cmd->chanlist_len * sizeof(short);
+ num_scans = comedi_buf_read_n_available(async) / bytes_per_scan;
+ if (!devpriv->ao_continuous) {
+ /* Fixed number of scans. */
+ if (num_scans > devpriv->ao_scan_count) {
+ num_scans = devpriv->ao_scan_count;
+ }
+ if (devpriv->ao_scan_count == 0) {
+ /* End of acquisition. */
+ events |= COMEDI_CB_EOA;
+ }
+ }
+ if (events == 0) {
+ /* Check for FIFO underrun. */
+ if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
+ comedi_error(dev, "AO FIFO underrun");
+ events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+ }
+ /* Check for buffer underrun if FIFO less than half full
+ * (otherwise there will be loads of "DAC FIFO not half full"
+ * interrupts). */
+ if ((num_scans == 0)
+ && ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) {
+ comedi_error(dev, "AO buffer underrun");
+ events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+ }
+ }
+ if (events == 0) {
+ /* Determine how much room is in the FIFO (in samples). */
+ if ((dacstat & PCI230P2_DAC_FIFO_FULL) != 0) {
+ room = PCI230P2_DAC_FIFOROOM_FULL;
+ } else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0) {
+ room = PCI230P2_DAC_FIFOROOM_HALFTOFULL;
+ } else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0) {
+ room = PCI230P2_DAC_FIFOROOM_EMPTY;
+ } else {
+ room = PCI230P2_DAC_FIFOROOM_ONETOHALF;
+ }
+ /* Convert room to number of scans that can be added. */
+ room /= cmd->chanlist_len;
+ /* Determine number of scans to process. */
+ if (num_scans > room) {
+ num_scans = room;
+ }
+ /* Process scans. */
+ for (n = 0; n < num_scans; n++) {
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ short datum;
+
+ comedi_buf_get(async, &datum);
+ pci230_ao_write_fifo(dev, datum,
+ CR_CHAN(cmd->chanlist[i]));
+ }
+ }
+ events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK;
+ if (!devpriv->ao_continuous) {
+ devpriv->ao_scan_count -= num_scans;
+ if (devpriv->ao_scan_count == 0) {
+ /* All data for the command has been written
+ * to FIFO. Set FIFO interrupt trigger level
+ * to 'empty'. */
+ devpriv->daccon = (devpriv->daccon
+ & ~PCI230P2_DAC_INT_FIFO_MASK)
+ | PCI230P2_DAC_INT_FIFO_EMPTY;
+ outw(devpriv->daccon,
+ dev->iobase + PCI230_DACCON);
+ }
+ }
+ /* Check if FIFO underrun occurred while writing to FIFO. */
+ dacstat = inw(dev->iobase + PCI230_DACCON);
+ if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
+ comedi_error(dev, "AO FIFO underrun");
+ events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+ }
+ }
+ if ((events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
+ != 0) {
+ /* Stopping AO due to completion or error. */
+ pci230_ao_stop(dev, s);
+ running = 0;
+ } else {
+ running = 1;
+ }
+ async->events |= events;
+ return running;
+}
+
+static void pci230_handle_ai(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned int events = 0;
+ unsigned int status_fifo;
+ unsigned int i;
+ unsigned int todo;
+ unsigned int fifoamount;
+ struct comedi_async *async = s->async;
+ unsigned int scanlen = async->cmd.scan_end_arg;
+
+ /* Determine number of samples to read. */
+ if (devpriv->ai_continuous) {
+ todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
+ } else if (devpriv->ai_scan_count == 0) {
+ todo = 0;
+ } else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL)
+ || (scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL)) {
+ todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
+ } else {
+ todo = (devpriv->ai_scan_count * scanlen)
+ - devpriv->ai_scan_pos;
+ if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL) {
+ todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
+ }
+ }
+
+ if (todo == 0) {
+ return;
+ }
+
+ fifoamount = 0;
+ for (i = 0; i < todo; i++) {
+ if (fifoamount == 0) {
+ /* Read FIFO state. */
+ status_fifo = inw(dev->iobase + PCI230_ADCCON);
+
+ if ((status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) != 0) {
+ /* Report error otherwise FIFO overruns will go
+ * unnoticed by the caller. */
+ comedi_error(dev, "AI FIFO overrun");
+ events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+ break;
+ } else if ((status_fifo & PCI230_ADC_FIFO_EMPTY) != 0) {
+ /* FIFO empty. */
+ break;
+ } else if ((status_fifo & PCI230_ADC_FIFO_HALF) != 0) {
+ /* FIFO half full. */
+ fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL;
+ } else {
+ /* FIFO not empty. */
+ if (devpriv->hwver > 0) {
+ /* Read PCI230+/260+ ADC FIFO level. */
+ fifoamount = inw(dev->iobase
+ + PCI230P_ADCFFLEV);
+ if (fifoamount == 0) {
+ /* Shouldn't happen. */
+ break;
+ }
+ } else {
+ fifoamount = 1;
+ }
+ }
+ }
+
+ /* Read sample and store in Comedi's circular buffer. */
+ if (comedi_buf_put(async, pci230_ai_read(dev)) == 0) {
+ events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
+ comedi_error(dev, "AI buffer overflow");
+ break;
+ }
+ fifoamount--;
+ devpriv->ai_scan_pos++;
+ if (devpriv->ai_scan_pos == scanlen) {
+ /* End of scan. */
+ devpriv->ai_scan_pos = 0;
+ devpriv->ai_scan_count--;
+ async->events |= COMEDI_CB_EOS;
+ }
+ }
+
+ if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
+ /* End of acquisition. */
+ events |= COMEDI_CB_EOA;
+ } else {
+ /* More samples required, tell Comedi to block. */
+ events |= COMEDI_CB_BLOCK;
+ }
+ async->events |= events;
+
+ if ((async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
+ COMEDI_CB_OVERFLOW)) != 0) {
+ /* disable hardware conversions */
+ pci230_ai_stop(dev, s);
+ } else {
+ /* update FIFO interrupt trigger level */
+ pci230_ai_update_fifo_trigger_level(dev, s);
+ }
+}
+
+static void pci230_ao_stop(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long irqflags;
+ unsigned char intsrc;
+ int started;
+ struct comedi_cmd *cmd;
+
+ comedi_spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
+ started = test_and_clear_bit(AO_CMD_STARTED, &devpriv->state);
+ comedi_spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
+ if (!started) {
+ return;
+ }
+
+ cmd = &s->async->cmd;
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* Stop scan rate generator. */
+ pci230_cancel_ct(dev, 1);
+ }
+
+ /* Determine interrupt source. */
+ if (devpriv->hwver < 2) {
+ /* Not using DAC FIFO. Using CT1 interrupt. */
+ intsrc = PCI230_INT_ZCLK_CT1;
+ } else {
+ /* Using DAC FIFO interrupt. */
+ intsrc = PCI230P2_INT_DAC;
+ }
+ /* Disable interrupt and wait for interrupt routine to finish running
+ * unless we are called from the interrupt routine. */
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ devpriv->int_en &= ~intsrc;
+ while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ }
+ if (devpriv->ier != devpriv->int_en) {
+ devpriv->ier = devpriv->int_en;
+ outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+ if (devpriv->hwver >= 2) {
+ /* Using DAC FIFO. Reset FIFO, clear underrun error,
+ * disable FIFO. */
+ devpriv->daccon &= PCI230_DAC_OR_MASK;
+ outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET
+ | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
+ dev->iobase + PCI230_DACCON);
+ }
+
+ /* Release resources. */
+ put_all_resources(dev, OWNER_AOCMD);
+}
+
+static int pci230_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ pci230_ao_stop(dev, s);
+ return 0;
+}
+
+static void pci230_ai_stop(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long irqflags;
+ struct comedi_cmd *cmd;
+ int started;
+
+ comedi_spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
+ started = test_and_clear_bit(AI_CMD_STARTED, &devpriv->state);
+ comedi_spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
+ if (!started) {
+ return;
+ }
+
+ cmd = &s->async->cmd;
+ if (cmd->convert_src == TRIG_TIMER) {
+ /* Stop conversion rate generator. */
+ pci230_cancel_ct(dev, 2);
+ }
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ /* Stop scan period monostable. */
+ pci230_cancel_ct(dev, 0);
+ }
+
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ /* Disable ADC interrupt and wait for interrupt routine to finish
+ * running unless we are called from the interrupt routine. */
+ devpriv->int_en &= ~PCI230_INT_ADC;
+ while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ }
+ if (devpriv->ier != devpriv->int_en) {
+ devpriv->ier = devpriv->int_en;
+ outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+ /* Reset FIFO, disable FIFO and set start conversion source to none.
+ * Keep se/diff and bip/uni settings */
+ devpriv->adccon = (devpriv->adccon & (PCI230_ADC_IR_MASK
+ | PCI230_ADC_IM_MASK)) | PCI230_ADC_TRIG_NONE;
+ outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
+ dev->iobase + PCI230_ADCCON);
+
+ /* Release resources. */
+ put_all_resources(dev, OWNER_AICMD);
+}
+
+static int pci230_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ pci230_ai_stop(dev, s);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c
new file mode 100644
index 00000000000..2efffb14610
--- /dev/null
+++ b/drivers/staging/comedi/drivers/c6xdigio.c
@@ -0,0 +1,517 @@
+/*
+ comedi/drivers/c6xdigio.c
+
+ Hardware driver for Mechatronic Systems Inc. C6x_DIGIO DSP daughter card.
+ (http://robot0.ge.uiuc.edu/~spong/mecha/)
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999 Dan Block
+
+ 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.
+
+ */
+/*
+Driver: c6xdigio
+Description: Mechatronic Systems Inc. C6x_DIGIO DSP daughter card
+Author: Dan Block
+Status: unknown
+Devices: [Mechatronic Systems Inc.] C6x_DIGIO DSP daughter card (c6xdigio)
+Updated: Sun Nov 20 20:18:34 EST 2005
+
+This driver will not work with a 2.4 kernel.
+http://robot0.ge.uiuc.edu/~spong/mecha/
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <linux/pnp.h>
+
+#include "../comedidev.h"
+
+static u8 ReadByteFromHwPort(unsigned long addr)
+{
+ u8 result = inb(addr);
+ return result;
+}
+
+static void WriteByteToHwPort(unsigned long addr, u8 val)
+{
+ outb_p(val, addr);
+}
+
+#define C6XDIGIO_SIZE 3
+
+/*
+ * port offsets
+ */
+#define C6XDIGIO_PARALLEL_DATA 0
+#define C6XDIGIO_PARALLEL_STATUS 1
+#define C6XDIGIO_PARALLEL_CONTROL 2
+struct pwmbitstype {
+ unsigned sb0:2;
+ unsigned sb1:2;
+ unsigned sb2:2;
+ unsigned sb3:2;
+ unsigned sb4:2;
+};
+union pwmcmdtype {
+ unsigned cmd; // assuming here that int is 32bit
+ struct pwmbitstype bits;
+};
+struct encbitstype {
+ unsigned sb0:3;
+ unsigned sb1:3;
+ unsigned sb2:3;
+ unsigned sb3:3;
+ unsigned sb4:3;
+ unsigned sb5:3;
+ unsigned sb6:3;
+ unsigned sb7:3;
+};
+union encvaluetype {
+ unsigned value;
+ struct encbitstype bits;
+};
+
+#define C6XDIGIO_TIME_OUT 20
+
+static int c6xdigio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int c6xdigio_detach(struct comedi_device * dev);
+struct comedi_driver driver_c6xdigio = {
+ driver_name:"c6xdigio",
+ module:THIS_MODULE,
+ attach:c6xdigio_attach,
+ detach:c6xdigio_detach,
+};
+
+static void C6X_pwmInit(unsigned long baseAddr)
+{
+ int timeout = 0;
+
+//printk("Inside C6X_pwmInit\n");
+
+ WriteByteToHwPort(baseAddr, 0x70);
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, 0x74);
+ timeout = 0;
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, 0x70);
+ timeout = 0;
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x0)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, 0x0);
+ timeout = 0;
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+
+}
+
+static void C6X_pwmOutput(unsigned long baseAddr, unsigned channel, int value)
+{
+ unsigned ppcmd;
+ union pwmcmdtype pwm;
+ int timeout = 0;
+ unsigned tmp;
+
+ //printk("Inside C6X_pwmOutput\n");
+
+ pwm.cmd = value;
+ if (pwm.cmd > 498)
+ pwm.cmd = 498;
+ if (pwm.cmd < 2)
+ pwm.cmd = 2;
+
+ if (channel == 0) {
+ ppcmd = 0x28;
+ } else { // if channel == 1
+ ppcmd = 0x30;
+ } /* endif */
+
+ WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb0);
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb1 + 0x4);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb2);
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb3 + 0x4);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb4);
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, 0x0);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+}
+
+static int C6X_encInput(unsigned long baseAddr, unsigned channel)
+{
+ unsigned ppcmd;
+ union encvaluetype enc;
+ int timeout = 0;
+ int tmp;
+
+ //printk("Inside C6X_encInput\n");
+
+ enc.value = 0;
+ if (channel == 0) {
+ ppcmd = 0x48;
+ } else {
+ ppcmd = 0x50;
+ }
+ WriteByteToHwPort(baseAddr, ppcmd);
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ enc.bits.sb0 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd + 0x4);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb1 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb2 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd + 0x4);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb3 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb4 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd + 0x4);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb5 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb6 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd + 0x4);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb7 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, 0x0);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ return (enc.value ^ 0x800000);
+}
+
+static void C6X_encResetAll(unsigned long baseAddr)
+{
+ unsigned timeout = 0;
+
+//printk("Inside C6X_encResetAll\n");
+
+ WriteByteToHwPort(baseAddr, 0x68);
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+ WriteByteToHwPort(baseAddr, 0x6C);
+ timeout = 0;
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+ WriteByteToHwPort(baseAddr, 0x68);
+ timeout = 0;
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x0)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+ WriteByteToHwPort(baseAddr, 0x0);
+ timeout = 0;
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+}
+
+static int c6xdigio_pwmo_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ printk("c6xdigio_pwmo_insn_read %x\n", insn->n);
+ return insn->n;
+}
+
+static int c6xdigio_pwmo_insn_write(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ // printk("c6xdigio_pwmo_insn_write %x\n", insn->n);
+ for (i = 0; i < insn->n; i++) {
+ C6X_pwmOutput(dev->iobase, chan, data[i]);
+ /* devpriv->ao_readback[chan] = data[i]; */
+ }
+ return i;
+}
+
+//static int c6xdigio_ei_init_insn_read(struct comedi_device *dev,
+// struct comedi_subdevice *s,
+// struct comedi_insn *insn,
+// unsigned int *data)
+//{
+// printk("c6xdigio_ei_init_insn_read %x\n", insn->n);
+// return insn->n;
+//}
+
+//static int c6xdigio_ei_init_insn_write(struct comedi_device *dev,
+// struct comedi_subdevice *s,
+// struct comedi_insn *insn,
+// unsigned int *data)
+//{
+// int i;
+// int chan = CR_CHAN(insn->chanspec);
+//
+// C6X_encResetAll( dev->iobase );
+//
+// return insn->n;
+//}
+
+static int c6xdigio_ei_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ // printk("c6xdigio_ei__insn_read %x\n", insn->n);
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ data[n] = (C6X_encInput(dev->iobase, chan) & 0xffffff);
+ }
+
+ return n;
+}
+
+static void board_init(struct comedi_device * dev)
+{
+
+ //printk("Inside board_init\n");
+
+ C6X_pwmInit(dev->iobase);
+ C6X_encResetAll(dev->iobase);
+
+}
+
+//static void board_halt(struct comedi_device *dev) {
+// C6X_pwmInit(dev->iobase);
+//}
+
+/*
+ options[0] - I/O port
+ options[1] - irq
+ options[2] - number of encoder chips installed
+ */
+
+static const struct pnp_device_id c6xdigio_pnp_tbl[] = {
+ /* Standard LPT Printer Port */
+ {.id = "PNP0400",.driver_data = 0},
+ /* ECP Printer Port */
+ {.id = "PNP0401",.driver_data = 0},
+ {}
+};
+
+static struct pnp_driver c6xdigio_pnp_driver = {
+ .name = "c6xdigio",
+ .id_table = c6xdigio_pnp_tbl,
+};
+
+static int c6xdigio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int result = 0;
+ unsigned long iobase;
+ unsigned int irq;
+ struct comedi_subdevice *s;
+
+ iobase = it->options[0];
+ printk("comedi%d: c6xdigio: 0x%04lx\n", dev->minor, iobase);
+ if (!request_region(iobase, C6XDIGIO_SIZE, "c6xdigio")) {
+ printk("comedi%d: I/O port conflict\n", dev->minor);
+ return -EIO;
+ }
+ dev->iobase = iobase;
+ dev->board_name = "c6xdigio";
+
+ result = alloc_subdevices(dev, 2); // 3 with encoder_init write
+ if (result < 0)
+ return result;
+
+ // Make sure that PnP ports gets activated
+ pnp_register_driver(&c6xdigio_pnp_driver);
+
+ irq = it->options[1];
+ if (irq > 0) {
+ printk("comedi%d: irq = %u ignored\n", dev->minor, irq);
+ } else if (irq == 0) {
+ printk("comedi%d: no irq\n", dev->minor);
+ }
+
+ s = dev->subdevices + 0;
+ /* pwm output subdevice */
+ s->type = COMEDI_SUBD_AO; // Not sure what to put here
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 2;
+ /* s->trig[0] = c6xdigio_pwmo; */
+ s->insn_read = c6xdigio_pwmo_insn_read;
+ s->insn_write = c6xdigio_pwmo_insn_write;
+ s->maxdata = 500;
+ s->range_table = &range_bipolar10; // A suitable lie
+
+ s = dev->subdevices + 1;
+ /* encoder (counter) subdevice */
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
+ s->n_chan = 2;
+ /* s->trig[0] = c6xdigio_ei; */
+ s->insn_read = c6xdigio_ei_insn_read;
+ s->maxdata = 0xffffff;
+ s->range_table = &range_unknown;
+
+ // s = dev->subdevices + 2;
+ // /* pwm output subdevice */
+ // s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here
+ // s->subdev_flags = SDF_WRITEABLE;
+ // s->n_chan = 1;
+ // /* s->trig[0] = c6xdigio_ei_init; */
+ // s->insn_read = c6xdigio_ei_init_insn_read;
+ // s->insn_write = c6xdigio_ei_init_insn_write;
+ // s->maxdata = 0xFFFF; // Really just a don't care
+ // s->range_table = &range_unknown; // Not sure what to put here
+
+ // I will call this init anyway but more than likely the DSP board will not be connect
+ // when device driver is loaded.
+ board_init(dev);
+
+ return 0;
+}
+
+static int c6xdigio_detach(struct comedi_device * dev)
+{
+// board_halt(dev); // may not need this
+
+ printk("comedi%d: c6xdigio: remove\n", dev->minor);
+
+ if (dev->iobase) {
+ release_region(dev->iobase, C6XDIGIO_SIZE);
+ }
+ if (dev->irq) {
+ free_irq(dev->irq, dev);
+ } // Not using IRQ so I am not sure if I need this
+ pnp_unregister_driver(&c6xdigio_pnp_driver);
+
+ return 0;
+}
+
+COMEDI_INITCLEANUP(driver_c6xdigio);
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
new file mode 100644
index 00000000000..0bfe4c954eb
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -0,0 +1,976 @@
+/*
+ comedi/drivers/das16cs.c
+ Driver for Computer Boards PC-CARD DAS16/16.
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000, 2001, 2002 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: cb_das16_cs
+Description: Computer Boards PC-CARD DAS16/16
+Devices: [ComputerBoards] PC-CARD DAS16/16 (cb_das16_cs), PC-CARD DAS16/16-AO
+Author: ds
+Updated: Mon, 04 Nov 2002 20:04:21 -0800
+Status: experimental
+
+
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+#include "8253.h"
+
+#define DAS16CS_SIZE 18
+
+#define DAS16CS_ADC_DATA 0
+#define DAS16CS_DIO_MUX 2
+#define DAS16CS_MISC1 4
+#define DAS16CS_MISC2 6
+#define DAS16CS_CTR0 8
+#define DAS16CS_CTR1 10
+#define DAS16CS_CTR2 12
+#define DAS16CS_CTR_CONTROL 14
+#define DAS16CS_DIO 16
+
+struct das16cs_board {
+ const char *name;
+ int device_id;
+ int n_ao_chans;
+};
+static const struct das16cs_board das16cs_boards[] = {
+ {
+ device_id:0x0000,/* unknown */
+ name: "PC-CARD DAS16/16",
+ n_ao_chans:0,
+ },
+ {
+ device_id:0x0039,
+ name: "PC-CARD DAS16/16-AO",
+ n_ao_chans:2,
+ },
+ {
+ device_id:0x4009,
+ name: "PCM-DAS16s/16",
+ n_ao_chans:0,
+ },
+};
+
+#define n_boards (sizeof(das16cs_boards)/sizeof(das16cs_boards[0]))
+#define thisboard ((const struct das16cs_board *)dev->board_ptr)
+
+struct das16cs_private {
+ struct pcmcia_device *link;
+
+ unsigned int ao_readback[2];
+ unsigned short status1;
+ unsigned short status2;
+};
+#define devpriv ((struct das16cs_private *)dev->private)
+
+static int das16cs_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das16cs_detach(struct comedi_device * dev);
+static struct comedi_driver driver_das16cs = {
+ driver_name:"cb_das16_cs",
+ module:THIS_MODULE,
+ attach:das16cs_attach,
+ detach:das16cs_detach,
+};
+
+static struct pcmcia_device *cur_dev = NULL;
+
+static const struct comedi_lrange das16cs_ai_range = { 4, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ }
+};
+
+static irqreturn_t das16cs_interrupt(int irq, void *d PT_REGS_ARG);
+static int das16cs_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16cs_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das16cs_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int das16cs_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16cs_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16cs_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16cs_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16cs_timer_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16cs_timer_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int get_prodid(struct comedi_device * dev, struct pcmcia_device *link)
+{
+ tuple_t tuple;
+ u_short buf[128];
+ int prodid = 0;
+
+ tuple.TupleData = (cisdata_t *) buf;
+ tuple.TupleOffset = 0;
+ tuple.TupleDataMax = 255;
+ tuple.DesiredTuple = CISTPL_MANFID;
+ tuple.Attributes = TUPLE_RETURN_COMMON;
+ if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
+ (pcmcia_get_tuple_data(link, &tuple) == 0)) {
+ prodid = le16_to_cpu(buf[1]);
+ }
+
+ return prodid;
+}
+
+static const struct das16cs_board *das16cs_probe(struct comedi_device * dev,
+ struct pcmcia_device *link)
+{
+ int id;
+ int i;
+
+ id = get_prodid(dev, link);
+
+ for (i = 0; i < n_boards; i++) {
+ if (das16cs_boards[i].device_id == id) {
+ return das16cs_boards + i;
+ }
+ }
+
+ printk("unknown board!\n");
+
+ return NULL;
+}
+
+static int das16cs_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pcmcia_device *link;
+ struct comedi_subdevice *s;
+ int ret;
+ int i;
+
+ printk("comedi%d: cb_das16_cs: ", dev->minor);
+
+ link = cur_dev; /* XXX hack */
+ if (!link)
+ return -EIO;
+
+ dev->iobase = link->io.BasePort1;
+ printk("I/O base=0x%04lx ", dev->iobase);
+
+ printk("fingerprint:\n");
+ for (i = 0; i < 48; i += 2) {
+ printk("%04x ", inw(dev->iobase + i));
+ }
+ printk("\n");
+
+ ret = comedi_request_irq(link->irq.AssignedIRQ, das16cs_interrupt,
+ IRQF_SHARED, "cb_das16_cs", dev);
+ if (ret < 0) {
+ return ret;
+ }
+ dev->irq = link->irq.AssignedIRQ;
+ printk("irq=%u ", dev->irq);
+
+ dev->board_ptr = das16cs_probe(dev, link);
+ if (!dev->board_ptr)
+ return -EIO;
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_private(dev, sizeof(struct das16cs_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ /* analog input subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+ s->n_chan = 16;
+ s->maxdata = 0xffff;
+ s->range_table = &das16cs_ai_range;
+ s->len_chanlist = 16;
+ s->insn_read = das16cs_ai_rinsn;
+ s->do_cmd = das16cs_ai_cmd;
+ s->do_cmdtest = das16cs_ai_cmdtest;
+
+ s = dev->subdevices + 1;
+ /* analog output subdevice */
+ if (thisboard->n_ao_chans) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->n_ao_chans;
+ s->maxdata = 0xffff;
+ s->range_table = &range_bipolar10;
+ s->insn_write = &das16cs_ao_winsn;
+ s->insn_read = &das16cs_ao_rinsn;
+ }
+
+ s = dev->subdevices + 2;
+ /* digital i/o subdevice */
+ if (1) {
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das16cs_dio_insn_bits;
+ s->insn_config = das16cs_dio_insn_config;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 3;
+ /* timer subdevice */
+ if (0) {
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 1;
+ s->maxdata = 0xff;
+ s->range_table = &range_unknown;
+ s->insn_read = das16cs_timer_insn_read;
+ s->insn_config = das16cs_timer_insn_config;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+static int das16cs_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: das16cs: remove\n", dev->minor);
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+
+ return 0;
+}
+
+static irqreturn_t das16cs_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ //struct comedi_device *dev = d;
+ return IRQ_HANDLED;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int das16cs_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int to;
+ int aref;
+ int range;
+ int chan;
+ static int range_bits[] = { 0x800, 0x000, 0x100, 0x200 };
+
+ chan = CR_CHAN(insn->chanspec);
+ aref = CR_AREF(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+
+ outw(chan, dev->iobase + 2);
+
+ devpriv->status1 &= ~0xf320;
+ devpriv->status1 |= (aref == AREF_DIFF) ? 0 : 0x0020;
+ outw(devpriv->status1, dev->iobase + 4);
+
+ devpriv->status2 &= ~0xff00;
+ devpriv->status2 |= range_bits[range];
+ outw(devpriv->status2, dev->iobase + 6);
+
+ for (i = 0; i < insn->n; i++) {
+ outw(0, dev->iobase);
+
+#define TIMEOUT 1000
+ for (to = 0; to < TIMEOUT; to++) {
+ if (inw(dev->iobase + 4) & 0x0080)
+ break;
+ }
+ if (to == TIMEOUT) {
+ printk("cb_das16_cs: ai timeout\n");
+ return -ETIME;
+ }
+ data[i] = (unsigned short)inw(dev->iobase + 0);
+ }
+
+ return i;
+}
+
+static int das16cs_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ return -EINVAL;
+}
+
+static int das16cs_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED 10000 /* in nanoseconds */
+#define MIN_SPEED 1000000000 /* in nanoseconds */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < MAX_SPEED) {
+ cmd->scan_begin_arg = MAX_SPEED;
+ err++;
+ }
+ if (cmd->scan_begin_arg > MIN_SPEED) {
+ cmd->scan_begin_arg = MIN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* should be level/edge, hi/lo specification here */
+ /* should specify multiple external triggers */
+ if (cmd->scan_begin_arg > 9) {
+ cmd->scan_begin_arg = 9;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < MAX_SPEED) {
+ cmd->convert_arg = MAX_SPEED;
+ err++;
+ }
+ if (cmd->convert_arg > MIN_SPEED) {
+ cmd->convert_arg = MIN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* see above */
+ if (cmd->convert_arg > 9) {
+ cmd->convert_arg = 9;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg > 0x00ffffff) {
+ cmd->stop_arg = 0x00ffffff;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ unsigned int div1, div2;
+
+ tmp = cmd->scan_begin_arg;
+ i8253_cascade_ns_to_timer(100, &div1, &div2,
+ &cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ unsigned int div1, div2;
+
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer(100, &div1, &div2,
+ &cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int das16cs_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned short status1;
+ unsigned short d;
+ int bit;
+
+ for (i = 0; i < insn->n; i++) {
+ devpriv->ao_readback[chan] = data[i];
+ d = data[i];
+
+ outw(devpriv->status1, dev->iobase + 4);
+ comedi_udelay(1);
+
+ status1 = devpriv->status1 & ~0xf;
+ if (chan)
+ status1 |= 0x0001;
+ else
+ status1 |= 0x0008;
+
+/* printk("0x%04x\n",status1);*/
+ outw(status1, dev->iobase + 4);
+ comedi_udelay(1);
+
+ for (bit = 15; bit >= 0; bit--) {
+ int b = (d >> bit) & 0x1;
+ b <<= 1;
+/* printk("0x%04x\n",status1 | b | 0x0000);*/
+ outw(status1 | b | 0x0000, dev->iobase + 4);
+ comedi_udelay(1);
+/* printk("0x%04x\n",status1 | b | 0x0004);*/
+ outw(status1 | b | 0x0004, dev->iobase + 4);
+ comedi_udelay(1);
+ }
+/* make high both DAC0CS and DAC1CS to load
+ new data and update analog output*/
+ outw(status1 | 0x9, dev->iobase + 4);
+ }
+
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int das16cs_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int das16cs_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+
+ outw(s->state, dev->iobase + 16);
+ }
+
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ data[1] = inw(dev->iobase + 16);
+
+ return 2;
+}
+
+static int das16cs_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int bits;
+
+ if (chan < 4)
+ bits = 0x0f;
+ else
+ bits = 0xf0;
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= bits;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= bits;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->
+ io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ devpriv->status2 &= ~0x00c0;
+ devpriv->status2 |= (s->io_bits & 0xf0) ? 0x0080 : 0;
+ devpriv->status2 |= (s->io_bits & 0x0f) ? 0x0040 : 0;
+
+ outw(devpriv->status2, dev->iobase + 6);
+
+ return insn->n;
+}
+
+static int das16cs_timer_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ return -EINVAL;
+}
+
+static int das16cs_timer_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ return -EINVAL;
+}
+
+/* PCMCIA stuff */
+
+/*======================================================================
+
+ The following pcmcia code for the pcm-das08 is adapted from the
+ dummy_cs.c driver of the Linux PCMCIA Card Services package.
+
+ The initial developer of the original code is David A. Hinds
+ <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
+ are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+
+======================================================================*/
+
+/*
+ All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
+ you do not define PCMCIA_DEBUG at all, all the debug code will be
+ left out. If you compile with PCMCIA_DEBUG=0, the debug code will
+ be present but disabled -- but it can then be enabled for specific
+ modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version =
+ "cb_das16_cs.c pcmcia code (David Schleef), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+static void das16cs_pcmcia_config(struct pcmcia_device *link);
+static void das16cs_pcmcia_release(struct pcmcia_device *link);
+static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev);
+static int das16cs_pcmcia_resume(struct pcmcia_device *p_dev);
+
+/*
+ The attach() and detach() entry points are used to create and destroy
+ "instances" of the driver, where each instance represents everything
+ needed to manage one actual PCMCIA card.
+*/
+
+static int das16cs_pcmcia_attach(struct pcmcia_device *);
+static void das16cs_pcmcia_detach(struct pcmcia_device *);
+
+/*
+ You'll also need to prototype all the functions that will actually
+ be used to talk to your device. See 'memory_cs' for a good example
+ of a fully self-sufficient driver; the other drivers rely more or
+ less on other parts of the kernel.
+*/
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static dev_info_t dev_info = "cb_das16_cs";
+
+struct local_info_t {
+ struct pcmcia_device *link;
+ dev_node_t node;
+ int stop;
+ struct bus_operations *bus;
+};
+
+/*======================================================================
+
+ das16cs_pcmcia_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+
+ The dev_link structure is initialized, but we don't actually
+ configure the card at this point -- we wait until we receive a
+ card insertion event.
+
+======================================================================*/
+
+static int das16cs_pcmcia_attach(struct pcmcia_device *link)
+{
+ struct local_info_t *local;
+
+ DEBUG(0, "das16cs_pcmcia_attach()\n");
+
+ /* Allocate space for private device-specific data */
+ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
+ if (!local)
+ return -ENOMEM;
+ local->link = link;
+ link->priv = local;
+
+ /* Initialize the pcmcia_device structure */
+ /* Interrupt setup */
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = NULL;
+
+ link->conf.Attributes = 0;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ cur_dev = link;
+
+ das16cs_pcmcia_config(link);
+
+ return 0;
+} /* das16cs_pcmcia_attach */
+
+static void das16cs_pcmcia_detach(struct pcmcia_device *link)
+{
+ DEBUG(0, "das16cs_pcmcia_detach(0x%p)\n", link);
+
+ if (link->dev_node) {
+ ((struct local_info_t *) link->priv)->stop = 1;
+ das16cs_pcmcia_release(link);
+ }
+ /* This points to the parent struct local_info_t struct */
+ if (link->priv)
+ kfree(link->priv);
+} /* das16cs_pcmcia_detach */
+
+static void das16cs_pcmcia_config(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+ tuple_t tuple;
+ cisparse_t parse;
+ int last_fn, last_ret;
+ u_char buf[64];
+ cistpl_cftable_entry_t dflt = { 0 };
+
+ DEBUG(0, "das16cs_pcmcia_config(0x%p)\n", link);
+
+ /*
+ This reads the card's CONFIG tuple to find its configuration
+ registers.
+ */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ last_fn = GetFirstTuple;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0)
+ goto cs_failed;
+ last_fn = GetTupleData;
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0)
+ goto cs_failed;
+ last_fn = ParseTuple;
+ if ((last_ret = pcmcia_parse_tuple(link, &tuple, &parse)) != 0)
+ goto cs_failed;
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+ /*
+ In this loop, we scan the CIS for configuration table entries,
+ each of which describes a valid card configuration, including
+ voltage, IO window, memory window, and interrupt settings.
+
+ We make no assumptions about the card to be configured: we use
+ just the information available in the CIS. In an ideal world,
+ this would work for any PCMCIA card, but it requires a complete
+ and accurate CIS. In practice, a driver usually "knows" most of
+ these things without consulting the CIS, and most client drivers
+ will only use the CIS to fill in implementation-defined details.
+ */
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ last_fn = GetFirstTuple;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0)
+ goto cs_failed;
+ while (1) {
+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ if (pcmcia_get_tuple_data(link, &tuple))
+ goto next_entry;
+ if (pcmcia_parse_tuple(link, &tuple, &parse))
+ goto next_entry;
+
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ if (cfg->index == 0)
+ goto next_entry;
+ link->conf.ConfigIndex = cfg->index;
+
+ /* Does this card need audio output? */
+/* if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ link->conf.Attributes |= CONF_ENABLE_SPKR;
+ link->conf.Status = CCSR_AUDIO_ENA;
+ }
+*/
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(link, &link->io))
+ goto next_entry;
+ }
+
+ /* If we got this far, we're cool! */
+ break;
+
+ next_entry:
+ last_fn = GetNextTuple;
+ if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0)
+ goto cs_failed;
+ }
+
+ /*
+ 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) {
+ last_fn = RequestIRQ;
+ if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0)
+ goto cs_failed;
+ }
+ /*
+ This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping, and putting the
+ card and host interface into "Memory and IO" mode.
+ */
+ last_fn = RequestConfiguration;
+ if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0)
+ goto cs_failed;
+
+ /*
+ At this point, the dev_node_t structure(s) need to be
+ initialized and arranged in a linked list at link->dev.
+ */
+ sprintf(dev->node.dev_name, "cb_das16_cs");
+ dev->node.major = dev->node.minor = 0;
+ link->dev_node = &dev->node;
+
+ /* Finally, report what we've done */
+ printk(KERN_INFO "%s: index 0x%02x",
+ dev->node.dev_name, link->conf.ConfigIndex);
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ printk(", irq %u", 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");
+
+ return;
+
+ cs_failed:
+ cs_error(link, last_fn, last_ret);
+ das16cs_pcmcia_release(link);
+} /* das16cs_pcmcia_config */
+
+static void das16cs_pcmcia_release(struct pcmcia_device *link)
+{
+ DEBUG(0, "das16cs_pcmcia_release(0x%p)\n", link);
+ pcmcia_disable_device(link);
+} /* das16cs_pcmcia_release */
+
+static int das16cs_pcmcia_suspend(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ /* Mark the device as stopped, to block IO until later */
+ local->stop = 1;
+
+ return 0;
+} /* das16cs_pcmcia_suspend */
+
+static int das16cs_pcmcia_resume(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ local->stop = 0;
+ return 0;
+} /* das16cs_pcmcia_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id das16cs_id_table[] = {
+ PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039),
+ PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4009),
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, das16cs_id_table);
+
+struct pcmcia_driver das16cs_driver = {
+ .probe = das16cs_pcmcia_attach,
+ .remove = das16cs_pcmcia_detach,
+ .suspend = das16cs_pcmcia_suspend,
+ .resume = das16cs_pcmcia_resume,
+ .id_table = das16cs_id_table,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+static int __init init_das16cs_pcmcia_cs(void)
+{
+ DEBUG(0, "%s\n", version);
+ pcmcia_register_driver(&das16cs_driver);
+ return 0;
+}
+
+static void __exit exit_das16cs_pcmcia_cs(void)
+{
+ DEBUG(0, "das16cs_pcmcia_cs: unloading\n");
+ pcmcia_unregister_driver(&das16cs_driver);
+}
+
+int __init init_module(void)
+{
+ int ret;
+
+ ret = init_das16cs_pcmcia_cs();
+ if (ret < 0)
+ return ret;
+
+ return comedi_driver_register(&driver_das16cs);
+}
+
+void __exit cleanup_module(void)
+{
+ exit_das16cs_pcmcia_cs();
+ comedi_driver_unregister(&driver_das16cs);
+}
+
+#else
+COMEDI_INITCLEANUP(driver_das16cs);
+#endif //CONFIG_PCMCIA
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
new file mode 100644
index 00000000000..fcc55165136
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -0,0 +1,1831 @@
+/*
+ comedi/drivers/cb_pcidas.c
+
+ Developed by Ivan Martinez and Frank Mori Hess, with valuable help from
+ David Schleef and the rest of the Comedi developers comunity.
+
+ Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk>
+ Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: cb_pcidas
+Description: MeasurementComputing PCI-DAS series with the AMCC S5933 PCI controller
+Author: Ivan Martinez <imr@oersted.dtu.dk>,
+ Frank Mori Hess <fmhess@users.sourceforge.net>
+Updated: 2003-3-11
+Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
+ PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
+ PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
+
+Status:
+ There are many reports of the driver being used with most of the
+ supported cards. Despite no detailed log is maintained, it can
+ be said that the driver is quite tested and stable.
+
+ The boards may be autocalibrated using the comedi_calibrate
+ utility.
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+
+For commands, the scanned channels must be consecutive
+(i.e. 4-5-6-7, 2-3-4,...), and must all have the same
+range and aref.
+*/
+/*
+
+TODO:
+
+analog triggering on 1602 series
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+
+#include "8253.h"
+#include "8255.h"
+#include "amcc_s5933.h"
+#include "comedi_pci.h"
+#include "comedi_fc.h"
+
+#undef CB_PCIDAS_DEBUG // disable debugging code
+//#define CB_PCIDAS_DEBUG // enable debugging code
+
+// PCI vendor number of ComputerBoards/MeasurementComputing
+#define PCI_VENDOR_ID_CB 0x1307
+#define TIMER_BASE 100 // 10MHz master clock
+#define AI_BUFFER_SIZE 1024 // maximum fifo size of any supported board
+#define AO_BUFFER_SIZE 1024 // maximum fifo size of any supported board
+#define NUM_CHANNELS_8800 8
+#define NUM_CHANNELS_7376 1
+#define NUM_CHANNELS_8402 2
+#define NUM_CHANNELS_DAC08 1
+
+/* PCI-DAS base addresses */
+
+// indices of base address regions
+#define S5933_BADRINDEX 0
+#define CONT_STAT_BADRINDEX 1
+#define ADC_FIFO_BADRINDEX 2
+#define PACER_BADRINDEX 3
+#define AO_BADRINDEX 4
+// sizes of io regions
+#define CONT_STAT_SIZE 10
+#define ADC_FIFO_SIZE 4
+#define PACER_SIZE 12
+#define AO_SIZE 4
+
+/* Control/Status registers */
+#define INT_ADCFIFO 0 // INTERRUPT / ADC FIFO register
+#define INT_EOS 0x1 // interrupt end of scan
+#define INT_FHF 0x2 // interrupt fifo half full
+#define INT_FNE 0x3 // interrupt fifo not empty
+#define INT_MASK 0x3 // mask of interrupt select bits
+#define INTE 0x4 // interrupt enable
+#define DAHFIE 0x8 // dac half full interrupt enable
+#define EOAIE 0x10 // end of aquisition interrupt enable
+#define DAHFI 0x20 // dac half full read status / write interrupt clear
+#define EOAI 0x40 // read end of acq. interrupt status / write clear
+#define INT 0x80 // read interrupt status / write clear
+#define EOBI 0x200 // read end of burst interrupt status
+#define ADHFI 0x400 // read half-full interrupt status
+#define ADNEI 0x800 // read fifo not empty interrupt latch status
+#define ADNE 0x1000 // read, fifo not empty (realtime, not latched) status
+#define DAEMIE 0x1000 // write, dac empty interrupt enable
+#define LADFUL 0x2000 // read fifo overflow / write clear
+#define DAEMI 0x4000 // dac fifo empty interrupt status / write clear
+
+#define ADCMUX_CONT 2 // ADC CHANNEL MUX AND CONTROL register
+#define BEGIN_SCAN(x) ((x) & 0xf)
+#define END_SCAN(x) (((x) & 0xf) << 4)
+#define GAIN_BITS(x) (((x) & 0x3) << 8)
+#define UNIP 0x800 // Analog front-end unipolar for range
+#define SE 0x400 // Inputs in single-ended mode
+#define PACER_MASK 0x3000 // pacer source bits
+#define PACER_INT 0x1000 // internal pacer
+#define PACER_EXT_FALL 0x2000 // external falling edge
+#define PACER_EXT_RISE 0x3000 // external rising edge
+#define EOC 0x4000 // adc not busy
+
+#define TRIG_CONTSTAT 4 // TRIGGER CONTROL/STATUS register
+#define SW_TRIGGER 0x1 // software start trigger
+#define EXT_TRIGGER 0x2 // external start trigger
+#define ANALOG_TRIGGER 0x3 // external analog trigger
+#define TRIGGER_MASK 0x3 // mask of bits that determine start trigger
+#define TGEN 0x10 // enable external start trigger
+#define BURSTE 0x20 // burst mode enable
+#define XTRCL 0x80 // clear external trigger
+
+#define CALIBRATION_REG 6 // CALIBRATION register
+#define SELECT_8800_BIT 0x100 // select 8800 caldac
+#define SELECT_TRIMPOT_BIT 0x200 // select ad7376 trim pot
+#define SELECT_DAC08_BIT 0x400 // select dac08 caldac
+#define CAL_SRC_BITS(x) (((x) & 0x7) << 11)
+#define CAL_EN_BIT 0x4000 // read calibration source instead of analog input channel 0
+#define SERIAL_DATA_IN_BIT 0x8000 // serial data stream going to 8800 and 7376
+
+#define DAC_CSR 0x8 // dac control and status register
+enum dac_csr_bits {
+ DACEN = 0x2, // dac enable
+ DAC_MODE_UPDATE_BOTH = 0x80, // update both dacs when dac0 is written
+};
+static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
+{
+ return (range & 0x3) << (8 + 2 * (channel & 0x1));
+}
+static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
+{
+ return 0x3 << (8 + 2 * (channel & 0x1));
+};
+
+// bits for 1602 series only
+enum dac_csr_bits_1602 {
+ DAC_EMPTY = 0x1, // dac fifo empty, read, write clear
+ DAC_START = 0x4, // start/arm dac fifo operations
+ DAC_PACER_MASK = 0x18, // bits that set dac pacer source
+ DAC_PACER_INT = 0x8, // dac internal pacing
+ DAC_PACER_EXT_FALL = 0x10, // dac external pacing, falling edge
+ DAC_PACER_EXT_RISE = 0x18, // dac external pacing, rising edge
+};
+static inline unsigned int DAC_CHAN_EN(unsigned int channel)
+{
+ return 1 << (5 + (channel & 0x1)); // enable channel 0 or 1
+};
+
+/* analog input fifo */
+#define ADCDATA 0 // ADC DATA register
+#define ADCFIFOCLR 2 // ADC FIFO CLEAR
+
+// pacer, counter, dio registers
+#define ADC8254 0
+#define DIO_8255 4
+#define DAC8254 8
+
+// analog output registers for 100x, 1200 series
+static inline unsigned int DAC_DATA_REG(unsigned int channel)
+{
+ return 2 * (channel & 0x1);
+}
+
+/* analog output registers for 1602 series*/
+#define DACDATA 0 // DAC DATA register
+#define DACFIFOCLR 2 // DAC FIFO CLEAR
+
+// bit in hexadecimal representation of range index that indicates unipolar input range
+#define IS_UNIPOLAR 0x4
+// analog input ranges for most boards
+static const struct comedi_lrange cb_pcidas_ranges = {
+ 8,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25)
+ }
+};
+
+// pci-das1001 input ranges
+static const struct comedi_lrange cb_pcidas_alt_ranges = {
+ 8,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.01),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01)
+ }
+};
+
+// analog output ranges
+static const struct comedi_lrange cb_pcidas_ao_ranges = {
+ 4,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(10),
+ }
+};
+
+enum trimpot_model {
+ AD7376,
+ AD8402,
+};
+
+struct cb_pcidas_board {
+ const char *name;
+ unsigned short device_id;
+ int ai_se_chans; // Inputs in single-ended mode
+ int ai_diff_chans; // Inputs in differential mode
+ int ai_bits; // analog input resolution
+ int ai_speed; // fastest conversion period in ns
+ int ao_nchan; // number of analog out channels
+ int has_ao_fifo; // analog output has fifo
+ int ao_scan_speed; // analog output speed for 1602 series (for a scan, not conversion)
+ int fifo_size; // number of samples fifo can hold
+ const struct comedi_lrange *ranges;
+ enum trimpot_model trimpot;
+ unsigned has_dac08:1;
+};
+
+static const struct cb_pcidas_board cb_pcidas_boards[] = {
+ {
+ name: "pci-das1602/16",
+ device_id:0x1,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:2,
+ has_ao_fifo:1,
+ ao_scan_speed:10000,
+ fifo_size:512,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD8402,
+ has_dac08:1,
+ },
+ {
+ name: "pci-das1200",
+ device_id:0xF,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 12,
+ ai_speed:3200,
+ ao_nchan:2,
+ has_ao_fifo:0,
+ fifo_size:1024,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD7376,
+ has_dac08:0,
+ },
+ {
+ name: "pci-das1602/12",
+ device_id:0x10,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 12,
+ ai_speed:3200,
+ ao_nchan:2,
+ has_ao_fifo:1,
+ ao_scan_speed:4000,
+ fifo_size:1024,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD7376,
+ has_dac08:0,
+ },
+ {
+ name: "pci-das1200/jr",
+ device_id:0x19,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 12,
+ ai_speed:3200,
+ ao_nchan:0,
+ has_ao_fifo:0,
+ fifo_size:1024,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD7376,
+ has_dac08:0,
+ },
+ {
+ name: "pci-das1602/16/jr",
+ device_id:0x1C,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:0,
+ has_ao_fifo:0,
+ fifo_size:512,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD8402,
+ has_dac08:1,
+ },
+ {
+ name: "pci-das1000",
+ device_id:0x4C,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 12,
+ ai_speed:4000,
+ ao_nchan:0,
+ has_ao_fifo:0,
+ fifo_size:1024,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD7376,
+ has_dac08:0,
+ },
+ {
+ name: "pci-das1001",
+ device_id:0x1a,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 12,
+ ai_speed:6800,
+ ao_nchan:2,
+ has_ao_fifo:0,
+ fifo_size:1024,
+ ranges: &cb_pcidas_alt_ranges,
+ trimpot: AD7376,
+ has_dac08:0,
+ },
+ {
+ name: "pci-das1002",
+ device_id:0x1b,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 12,
+ ai_speed:6800,
+ ao_nchan:2,
+ has_ao_fifo:0,
+ fifo_size:1024,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD7376,
+ has_dac08:0,
+ },
+};
+
+// Number of boards in cb_pcidas_boards
+#define N_BOARDS (sizeof(cb_pcidas_boards) / sizeof(struct cb_pcidas_board))
+
+static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
+ {PCI_VENDOR_ID_CB, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x000f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x001c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x004c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x001a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x001b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct cb_pcidas_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct cb_pcidas_private {
+ /* would be useful for a PCI device */
+ struct pci_dev *pci_dev;
+ // base addresses
+ unsigned long s5933_config;
+ unsigned long control_status;
+ unsigned long adc_fifo;
+ unsigned long pacer_counter_dio;
+ unsigned long ao_registers;
+ // divisors of master clock for analog input pacing
+ unsigned int divisor1;
+ unsigned int divisor2;
+ volatile unsigned int count; // number of analog input samples remaining
+ volatile unsigned int adc_fifo_bits; // bits to write to interupt/adcfifo register
+ volatile unsigned int s5933_intcsr_bits; // bits to write to amcc s5933 interrupt control/status register
+ volatile unsigned int ao_control_bits; // bits to write to ao control and status register
+ short ai_buffer[AI_BUFFER_SIZE];
+ short ao_buffer[AO_BUFFER_SIZE];
+ // divisors of master clock for analog output pacing
+ unsigned int ao_divisor1;
+ unsigned int ao_divisor2;
+ volatile unsigned int ao_count; // number of analog output samples remaining
+ int ao_value[2]; // remember what the analog outputs are set to, to allow readback
+ unsigned int caldac_value[NUM_CHANNELS_8800]; // for readback of caldac
+ unsigned int trimpot_value[NUM_CHANNELS_8402]; // for readback of trimpot
+ unsigned int dac08_value;
+ unsigned int calibration_source;
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct cb_pcidas_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int cb_pcidas_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int cb_pcidas_detach(struct comedi_device * dev);
+static struct comedi_driver driver_cb_pcidas = {
+ driver_name:"cb_pcidas",
+ module:THIS_MODULE,
+ attach:cb_pcidas_attach,
+ detach:cb_pcidas_detach,
+};
+
+static int cb_pcidas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_ao_nofifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_ao_fifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int cb_pcidas_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int cb_pcidas_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
+ struct comedi_subdevice *subdev,
+ unsigned int trig_num);
+static int cb_pcidas_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static irqreturn_t cb_pcidas_interrupt(int irq, void *d PT_REGS_ARG);
+static void handle_ao_interrupt(struct comedi_device * dev, unsigned int status);
+static int cb_pcidas_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int cb_pcidas_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void cb_pcidas_load_counters(struct comedi_device * dev, unsigned int *ns,
+ int round_flags);
+static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int caldac_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int caldac_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int trimpot_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_trimpot_write(struct comedi_device * dev, unsigned int channel,
+ unsigned int value);
+static int trimpot_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dac08_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dac08_write(struct comedi_device * dev, unsigned int value);
+static int dac08_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
+ uint8_t value);
+static int trimpot_7376_write(struct comedi_device * dev, uint8_t value);
+static int trimpot_8402_write(struct comedi_device * dev, unsigned int channel,
+ uint8_t value);
+static int nvram_read(struct comedi_device * dev, unsigned int address,
+ uint8_t * data);
+
+static inline unsigned int cal_enable_bits(struct comedi_device * dev)
+{
+ return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.
+ */
+static int cb_pcidas_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ struct pci_dev *pcidev;
+ int index;
+ int i;
+
+ printk("comedi%d: cb_pcidas: ", dev->minor);
+
+/*
+ * Allocate the private structure area.
+ */
+ if (alloc_private(dev, sizeof(struct cb_pcidas_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+ printk("\n");
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ // is it not a computer boards card?
+ if (pcidev->vendor != PCI_VENDOR_ID_CB)
+ continue;
+ // loop through cards supported by this driver
+ for (index = 0; index < N_BOARDS; index++) {
+ if (cb_pcidas_boards[index].device_id != pcidev->device)
+ continue;
+ // was a particular bus/slot requested?
+ if (it->options[0] || it->options[1]) {
+ // are we on the wrong bus/slot?
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+ dev->board_ptr = cb_pcidas_boards + index;
+ goto found;
+ }
+ }
+
+ printk("No supported ComputerBoards/MeasurementComputing card found on "
+ "requested position\n");
+ return -EIO;
+
+ found:
+
+ printk("Found %s on bus %i, slot %i\n", cb_pcidas_boards[index].name,
+ pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+
+ /*
+ * Enable PCI device and reserve I/O ports.
+ */
+ if (comedi_pci_enable(pcidev, "cb_pcidas")) {
+ printk(" Failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+ /*
+ * Initialize devpriv->control_status and devpriv->adc_fifo to point to
+ * their base address.
+ */
+ devpriv->s5933_config =
+ pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX);
+ devpriv->control_status =
+ pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX);
+ devpriv->adc_fifo =
+ pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX);
+ devpriv->pacer_counter_dio =
+ pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX);
+ if (thisboard->ao_nchan) {
+ devpriv->ao_registers =
+ pci_resource_start(devpriv->pci_dev, AO_BADRINDEX);
+ }
+ // disable and clear interrupts on amcc s5933
+ outl(INTCSR_INBOX_INTR_STATUS,
+ devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+
+ // get irq
+ if (comedi_request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt,
+ IRQF_SHARED, "cb_pcidas", dev)) {
+ printk(" unable to allocate irq %d\n", devpriv->pci_dev->irq);
+ return -EINVAL;
+ }
+ dev->irq = devpriv->pci_dev->irq;
+
+ //Initialize dev->board_name
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures.
+ */
+ if (alloc_subdevices(dev, 7) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog input subdevice */
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+ /* WARNING: Number of inputs in differential mode is ignored */
+ s->n_chan = thisboard->ai_se_chans;
+ s->len_chanlist = thisboard->ai_se_chans;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = thisboard->ranges;
+ s->insn_read = cb_pcidas_ai_rinsn;
+ s->insn_config = ai_config_insn;
+ s->do_cmd = cb_pcidas_ai_cmd;
+ s->do_cmdtest = cb_pcidas_ai_cmdtest;
+ s->cancel = cb_pcidas_cancel;
+
+ /* analog output subdevice */
+ s = dev->subdevices + 1;
+ if (thisboard->ao_nchan) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = thisboard->ao_nchan;
+ // analog out resolution is the same as analog input resolution, so use ai_bits
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = &cb_pcidas_ao_ranges;
+ s->insn_read = cb_pcidas_ao_readback_insn;
+ if (thisboard->has_ao_fifo) {
+ dev->write_subdev = s;
+ s->subdev_flags |= SDF_CMD_WRITE;
+ s->insn_write = cb_pcidas_ao_fifo_winsn;
+ s->do_cmdtest = cb_pcidas_ao_cmdtest;
+ s->do_cmd = cb_pcidas_ao_cmd;
+ s->cancel = cb_pcidas_ao_cancel;
+ } else {
+ s->insn_write = cb_pcidas_ao_nofifo_winsn;
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* 8255 */
+ s = dev->subdevices + 2;
+ subdev_8255_init(dev, s, NULL, devpriv->pacer_counter_dio + DIO_8255);
+
+ // serial EEPROM,
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+ s->n_chan = 256;
+ s->maxdata = 0xff;
+ s->insn_read = eeprom_read_insn;
+
+ // 8800 caldac
+ s = dev->subdevices + 4;
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = NUM_CHANNELS_8800;
+ s->maxdata = 0xff;
+ s->insn_read = caldac_read_insn;
+ s->insn_write = caldac_write_insn;
+ for (i = 0; i < s->n_chan; i++)
+ caldac_8800_write(dev, i, s->maxdata / 2);
+
+ // trim potentiometer
+ s = dev->subdevices + 5;
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ if (thisboard->trimpot == AD7376) {
+ s->n_chan = NUM_CHANNELS_7376;
+ s->maxdata = 0x7f;
+ } else {
+ s->n_chan = NUM_CHANNELS_8402;
+ s->maxdata = 0xff;
+ }
+ s->insn_read = trimpot_read_insn;
+ s->insn_write = trimpot_write_insn;
+ for (i = 0; i < s->n_chan; i++)
+ cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
+
+ // dac08 caldac
+ s = dev->subdevices + 6;
+ if (thisboard->has_dac08) {
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = NUM_CHANNELS_DAC08;
+ s->insn_read = dac08_read_insn;
+ s->insn_write = dac08_write_insn;
+ s->maxdata = 0xff;
+ dac08_write(dev, s->maxdata / 2);
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ // make sure mailbox 4 is empty
+ inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
+ /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
+ devpriv->s5933_intcsr_bits =
+ INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
+ INTCSR_INBOX_FULL_INT;
+ // clear and enable interrupt on amcc s5933
+ outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
+ devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+
+ return 1;
+}
+
+/*
+ * cb_pcidas_detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int cb_pcidas_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: cb_pcidas: remove\n", dev->minor);
+
+ if (devpriv) {
+ if (devpriv->s5933_config) {
+ // disable and clear interrupts on amcc s5933
+ outl(INTCSR_INBOX_INTR_STATUS,
+ devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("detaching, incsr is 0x%x\n",
+ inl(devpriv->s5933_config +
+ AMCC_OP_REG_INTCSR));
+#endif
+ }
+ }
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+ if (devpriv && devpriv->pci_dev) {
+ if (devpriv->s5933_config) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
+ return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int cb_pcidas_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i;
+ unsigned int bits;
+ static const int timeout = 10000;
+ int channel;
+ // enable calibration input if appropriate
+ if (insn->chanspec & CR_ALT_SOURCE) {
+ outw(cal_enable_bits(dev),
+ devpriv->control_status + CALIBRATION_REG);
+ channel = 0;
+ } else {
+ outw(0, devpriv->control_status + CALIBRATION_REG);
+ channel = CR_CHAN(insn->chanspec);
+ }
+ // set mux limits and gain
+ bits = BEGIN_SCAN(channel) |
+ END_SCAN(channel) | GAIN_BITS(CR_RANGE(insn->chanspec));
+ // set unipolar/bipolar
+ if (CR_RANGE(insn->chanspec) & IS_UNIPOLAR)
+ bits |= UNIP;
+ // set singleended/differential
+ if (CR_AREF(insn->chanspec) != AREF_DIFF)
+ bits |= SE;
+ outw(bits, devpriv->control_status + ADCMUX_CONT);
+
+ /* clear fifo */
+ outw(0, devpriv->adc_fifo + ADCFIFOCLR);
+
+ /* convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ outw(0, devpriv->adc_fifo + ADCDATA);
+
+ /* wait for conversion to end */
+ /* return -ETIMEDOUT if there is a timeout */
+ for (i = 0; i < timeout; i++) {
+ if (inw(devpriv->control_status + ADCMUX_CONT) & EOC)
+ break;
+ }
+ if (i == timeout)
+ return -ETIMEDOUT;
+
+ /* read data */
+ data[n] = inw(devpriv->adc_fifo + ADCDATA);
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+static int ai_config_calibration_source(struct comedi_device * dev, unsigned int * data)
+{
+ static const int num_calibration_sources = 8;
+ unsigned int source = data[1];
+
+ if (source >= num_calibration_sources) {
+ printk("invalid calibration source: %i\n", source);
+ return -EINVAL;
+ }
+
+ devpriv->calibration_source = source;
+
+ return 2;
+}
+
+static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int id = data[0];
+
+ switch (id) {
+ case INSN_CONFIG_ALT_SOURCE:
+ return ai_config_calibration_source(dev, data);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return -EINVAL;
+}
+
+// analog output insn for pcidas-1000 and 1200 series
+static int cb_pcidas_ao_nofifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel;
+ unsigned long flags;
+
+ // set channel and range
+ channel = CR_CHAN(insn->chanspec);
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->ao_control_bits &=
+ ~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel);
+ devpriv->ao_control_bits |=
+ DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec));
+ outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // remember value for readback
+ devpriv->ao_value[channel] = data[0];
+ // send data
+ outw(data[0], devpriv->ao_registers + DAC_DATA_REG(channel));
+
+ return 1;
+}
+
+// analog output insn for pcidas-1602 series
+static int cb_pcidas_ao_fifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel;
+ unsigned long flags;
+
+ // clear dac fifo
+ outw(0, devpriv->ao_registers + DACFIFOCLR);
+
+ // set channel and range
+ channel = CR_CHAN(insn->chanspec);
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->ao_control_bits &=
+ ~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) & ~DAC_RANGE_MASK(channel) &
+ ~DAC_PACER_MASK;
+ devpriv->ao_control_bits |=
+ DACEN | DAC_RANGE(channel,
+ CR_RANGE(insn->chanspec)) | DAC_CHAN_EN(channel) | DAC_START;
+ outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // remember value for readback
+ devpriv->ao_value[channel] = data[0];
+ // send data
+ outw(data[0], devpriv->ao_registers + DACDATA);
+
+ return 1;
+}
+
+// analog output readback insn
+// XXX loses track of analog output value back after an analog ouput command is executed
+static int cb_pcidas_ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ uint8_t nvram_data;
+ int retval;
+
+ retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
+ if (retval < 0)
+ return retval;
+
+ data[0] = nvram_data;
+
+ return 1;
+}
+
+static int caldac_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ const unsigned int channel = CR_CHAN(insn->chanspec);
+
+ return caldac_8800_write(dev, channel, data[0]);
+}
+
+static int caldac_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+/* 1602/16 pregain offset */
+static int dac08_write(struct comedi_device * dev, unsigned int value)
+{
+ if (devpriv->dac08_value == value)
+ return 1;
+
+ devpriv->dac08_value = value;
+
+ outw(cal_enable_bits(dev) | (value & 0xff),
+ devpriv->control_status + CALIBRATION_REG);
+ comedi_udelay(1);
+ outw(cal_enable_bits(dev) | SELECT_DAC08_BIT | (value & 0xff),
+ devpriv->control_status + CALIBRATION_REG);
+ comedi_udelay(1);
+ outw(cal_enable_bits(dev) | (value & 0xff),
+ devpriv->control_status + CALIBRATION_REG);
+ comedi_udelay(1);
+
+ return 1;
+}
+
+static int dac08_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ return dac08_write(dev, data[0]);
+}
+
+static int dac08_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->dac08_value;
+
+ return 1;
+}
+
+static int cb_pcidas_trimpot_write(struct comedi_device * dev,
+ unsigned int channel, unsigned int value)
+{
+ if (devpriv->trimpot_value[channel] == value)
+ return 1;
+
+ devpriv->trimpot_value[channel] = value;
+ switch (thisboard->trimpot) {
+ case AD7376:
+ trimpot_7376_write(dev, value);
+ break;
+ case AD8402:
+ trimpot_8402_write(dev, channel, value);
+ break;
+ default:
+ comedi_error(dev, "driver bug?");
+ return -1;
+ break;
+ }
+
+ return 1;
+}
+
+static int trimpot_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int channel = CR_CHAN(insn->chanspec);
+
+ return cb_pcidas_trimpot_write(dev, channel, data[0]);
+}
+
+static int trimpot_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int channel = CR_CHAN(insn->chanspec);
+
+ data[0] = devpriv->trimpot_value[channel];
+
+ return 1;
+}
+
+static int cb_pcidas_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int i, gain, start_chan;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER &&
+ cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ // make sure trigger sources are compatible with each other
+ if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
+ err++;
+ if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->start_src == TRIG_EXT &&
+ (cmd->convert_src == TRIG_EXT
+ || cmd->scan_begin_src == TRIG_EXT))
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg <
+ thisboard->ai_speed * cmd->chanlist_len) {
+ cmd->scan_begin_arg =
+ thisboard->ai_speed * cmd->chanlist_len;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_NONE) {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ // check channel/gain list against card's limitations
+ if (cmd->chanlist) {
+ gain = CR_RANGE(cmd->chanlist[0]);
+ start_chan = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) !=
+ (start_chan + i) % s->n_chan) {
+ comedi_error(dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ err++;
+ }
+ if (CR_RANGE(cmd->chanlist[i]) != gain) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same gain\n");
+ err++;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int cb_pcidas_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int bits;
+ unsigned long flags;
+
+ // make sure CAL_EN_BIT is disabled
+ outw(0, devpriv->control_status + CALIBRATION_REG);
+ // initialize before settings pacer source and count values
+ outw(0, devpriv->control_status + TRIG_CONTSTAT);
+ // clear fifo
+ outw(0, devpriv->adc_fifo + ADCFIFOCLR);
+
+ // set mux limits, gain and pacer source
+ bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
+ END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
+ GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
+ // set unipolar/bipolar
+ if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
+ bits |= UNIP;
+ // set singleended/differential
+ if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
+ bits |= SE;
+ // set pacer source
+ if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
+ bits |= PACER_EXT_RISE;
+ else
+ bits |= PACER_INT;
+ outw(bits, devpriv->control_status + ADCMUX_CONT);
+
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("comedi: sent 0x%x to adcmux control\n", bits);
+#endif
+
+ // load counters
+ if (cmd->convert_src == TRIG_TIMER)
+ cb_pcidas_load_counters(dev, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ else if (cmd->scan_begin_src == TRIG_TIMER)
+ cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+
+ // set number of conversions
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->count = cmd->chanlist_len * cmd->stop_arg;
+ }
+ // enable interrupts
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->adc_fifo_bits |= INTE;
+ devpriv->adc_fifo_bits &= ~INT_MASK;
+ if (cmd->flags & TRIG_WAKE_EOS) {
+ if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
+ devpriv->adc_fifo_bits |= INT_EOS; // interrupt end of burst
+ else
+ devpriv->adc_fifo_bits |= INT_FNE; // interrupt fifo not empty
+ } else {
+ devpriv->adc_fifo_bits |= INT_FHF; //interrupt fifo half full
+ }
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits);
+#endif
+ // enable (and clear) interrupts
+ outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // set start trigger and burst mode
+ bits = 0;
+ if (cmd->start_src == TRIG_NOW)
+ bits |= SW_TRIGGER;
+ else if (cmd->start_src == TRIG_EXT)
+ bits |= EXT_TRIGGER | TGEN | XTRCL;
+ else {
+ comedi_error(dev, "bug!");
+ return -1;
+ }
+ if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
+ bits |= BURSTE;
+ outw(bits, devpriv->control_status + TRIG_CONTSTAT);
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("comedi: sent 0x%x to trig control\n", bits);
+#endif
+
+ return 0;
+}
+
+static int cb_pcidas_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_INT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < thisboard->ao_scan_speed) {
+ cmd->scan_begin_arg = thisboard->ao_scan_speed;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_NONE) {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->ao_divisor1), &(devpriv->ao_divisor2),
+ &(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ // check channel/gain list against card's limitations
+ if (cmd->chanlist && cmd->chanlist_len > 1) {
+ if (CR_CHAN(cmd->chanlist[0]) != 0 ||
+ CR_CHAN(cmd->chanlist[1]) != 1) {
+ comedi_error(dev,
+ "channels must be ordered channel 0, channel 1 in chanlist\n");
+ err++;
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int cb_pcidas_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int i;
+ unsigned long flags;
+
+ // set channel limits, gain
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ // enable channel
+ devpriv->ao_control_bits |=
+ DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
+ // set range
+ devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
+ CR_RANGE(cmd->chanlist[i]));
+ }
+
+ // disable analog out before settings pacer source and count values
+ outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // clear fifo
+ outw(0, devpriv->ao_registers + DACFIFOCLR);
+
+ // load counters
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->ao_divisor1), &(devpriv->ao_divisor2),
+ &(cmd->scan_begin_arg), cmd->flags);
+
+ /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
+ i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
+ devpriv->ao_divisor1, 2);
+ i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
+ devpriv->ao_divisor2, 2);
+ }
+ // set number of conversions
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
+ }
+ // set pacer source
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ devpriv->ao_control_bits |= DAC_PACER_INT;
+ break;
+ case TRIG_EXT:
+ devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
+ break;
+ default:
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ comedi_error(dev, "error setting dac pacer source");
+ return -1;
+ break;
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ async->inttrig = cb_pcidas_ao_inttrig;
+
+ return 0;
+}
+
+static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
+{
+ unsigned int num_bytes, num_points = thisboard->fifo_size;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned long flags;
+
+ if (trig_num != 0)
+ return -EINVAL;
+
+ // load up fifo
+ if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
+ num_points = devpriv->ao_count;
+
+ num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
+ num_points * sizeof(short));
+ num_points = num_bytes / sizeof(short);
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ao_count -= num_points;
+ }
+ // write data to board's fifo
+ outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
+
+ // enable dac half-full and empty interrupts
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits);
+#endif
+ // enable and clear interrupts
+ outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
+ devpriv->control_status + INT_ADCFIFO);
+
+ // start dac
+ devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
+ outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("comedi: sent 0x%x to dac control\n",
+ devpriv->ao_control_bits);
+#endif
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ async->inttrig = NULL;
+
+ return 0;
+}
+
+static irqreturn_t cb_pcidas_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async;
+ int status, s5933_status;
+ int half_fifo = thisboard->fifo_size / 2;
+ unsigned int num_samples, i;
+ static const int timeout = 10000;
+ unsigned long flags;
+
+ if (dev->attached == 0) {
+ return IRQ_NONE;
+ }
+
+ async = s->async;
+ async->events = 0;
+
+ s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("intcsr 0x%x\n", s5933_status);
+ rt_printk("mbef 0x%x\n", inl(devpriv->s5933_config + AMCC_OP_REG_MBEF));
+#endif
+
+ if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
+ return IRQ_NONE;
+
+ // make sure mailbox 4 is empty
+ inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
+ // clear interrupt on amcc s5933
+ outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
+ devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+
+ status = inw(devpriv->control_status + INT_ADCFIFO);
+#ifdef CB_PCIDAS_DEBUG
+ if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) {
+ comedi_error(dev, "spurious interrupt");
+ }
+#endif
+
+ // check for analog output interrupt
+ if (status & (DAHFI | DAEMI)) {
+ handle_ao_interrupt(dev, status);
+ }
+ // check for analog input interrupts
+ // if fifo half-full
+ if (status & ADHFI) {
+ // read data
+ num_samples = half_fifo;
+ if (async->cmd.stop_src == TRIG_COUNT &&
+ num_samples > devpriv->count) {
+ num_samples = devpriv->count;
+ }
+ insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
+ num_samples);
+ cfc_write_array_to_buffer(s, devpriv->ai_buffer,
+ num_samples * sizeof(short));
+ devpriv->count -= num_samples;
+ if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
+ async->events |= COMEDI_CB_EOA;
+ cb_pcidas_cancel(dev, s);
+ }
+ // clear half-full interrupt latch
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ outw(devpriv->adc_fifo_bits | INT,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ // else if fifo not empty
+ } else if (status & (ADNEI | EOBI)) {
+ for (i = 0; i < timeout; i++) {
+ // break if fifo is empty
+ if ((ADNE & inw(devpriv->control_status +
+ INT_ADCFIFO)) == 0)
+ break;
+ cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
+ if (async->cmd.stop_src == TRIG_COUNT && --devpriv->count == 0) { /* end of acquisition */
+ cb_pcidas_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA;
+ break;
+ }
+ }
+ // clear not-empty interrupt latch
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ outw(devpriv->adc_fifo_bits | INT,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ } else if (status & EOAI) {
+ comedi_error(dev,
+ "bug! encountered end of aquisition interrupt?");
+ // clear EOA interrupt latch
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ outw(devpriv->adc_fifo_bits | EOAI,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ }
+ //check for fifo overflow
+ if (status & LADFUL) {
+ comedi_error(dev, "fifo overflow");
+ // clear overflow interrupt latch
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ outw(devpriv->adc_fifo_bits | LADFUL,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ cb_pcidas_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ }
+
+ comedi_event(dev, s);
+
+ return IRQ_HANDLED;
+}
+
+static void handle_ao_interrupt(struct comedi_device * dev, unsigned int status)
+{
+ struct comedi_subdevice *s = dev->write_subdev;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int half_fifo = thisboard->fifo_size / 2;
+ unsigned int num_points;
+ unsigned int flags;
+
+ async->events = 0;
+
+ if (status & DAEMI) {
+ // clear dac empty interrupt latch
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ outw(devpriv->adc_fifo_bits | DAEMI,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
+ if (cmd->stop_src == TRIG_NONE ||
+ (cmd->stop_src == TRIG_COUNT
+ && devpriv->ao_count)) {
+ comedi_error(dev, "dac fifo underflow");
+ cb_pcidas_ao_cancel(dev, s);
+ async->events |= COMEDI_CB_ERROR;
+ }
+ async->events |= COMEDI_CB_EOA;
+ }
+ } else if (status & DAHFI) {
+ unsigned int num_bytes;
+
+ // figure out how many points we are writing to fifo
+ num_points = half_fifo;
+ if (cmd->stop_src == TRIG_COUNT &&
+ devpriv->ao_count < num_points)
+ num_points = devpriv->ao_count;
+ num_bytes =
+ cfc_read_array_from_buffer(s, devpriv->ao_buffer,
+ num_points * sizeof(short));
+ num_points = num_bytes / sizeof(short);
+
+ if (async->cmd.stop_src == TRIG_COUNT) {
+ devpriv->ao_count -= num_points;
+ }
+ // write data to board's fifo
+ outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
+ num_points);
+ // clear half-full interrupt latch
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ outw(devpriv->adc_fifo_bits | DAHFI,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ }
+
+ comedi_event(dev, s);
+}
+
+/* cancel analog input command */
+static int cb_pcidas_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ // disable interrupts
+ devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
+ outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // disable start trigger source and burst mode
+ outw(0, devpriv->control_status + TRIG_CONTSTAT);
+ // software pacer source
+ outw(0, devpriv->control_status + ADCMUX_CONT);
+
+ return 0;
+}
+
+/* cancel analog output command */
+static int cb_pcidas_ao_cancel(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ // disable interrupts
+ devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
+ outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
+
+ // disable output
+ devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
+ outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return 0;
+}
+
+static void cb_pcidas_load_counters(struct comedi_device * dev, unsigned int *ns,
+ int rounding_flags)
+{
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
+ &(devpriv->divisor2), ns, rounding_flags & TRIG_ROUND_MASK);
+
+ /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
+ i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
+ devpriv->divisor1, 2);
+ i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
+ devpriv->divisor2, 2);
+}
+
+static void write_calibration_bitstream(struct comedi_device * dev,
+ unsigned int register_bits, unsigned int bitstream,
+ unsigned int bitstream_length)
+{
+ static const int write_delay = 1;
+ unsigned int bit;
+
+ for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
+ if (bitstream & bit)
+ register_bits |= SERIAL_DATA_IN_BIT;
+ else
+ register_bits &= ~SERIAL_DATA_IN_BIT;
+ comedi_udelay(write_delay);
+ outw(register_bits, devpriv->control_status + CALIBRATION_REG);
+ }
+}
+
+static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
+ uint8_t value)
+{
+ static const int num_caldac_channels = 8;
+ static const int bitstream_length = 11;
+ unsigned int bitstream = ((address & 0x7) << 8) | value;
+ static const int caldac_8800_comedi_udelay = 1;
+
+ if (address >= num_caldac_channels) {
+ comedi_error(dev, "illegal caldac channel");
+ return -1;
+ }
+
+ if (value == devpriv->caldac_value[address])
+ return 1;
+
+ devpriv->caldac_value[address] = value;
+
+ write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
+ bitstream_length);
+
+ comedi_udelay(caldac_8800_comedi_udelay);
+ outw(cal_enable_bits(dev) | SELECT_8800_BIT,
+ devpriv->control_status + CALIBRATION_REG);
+ comedi_udelay(caldac_8800_comedi_udelay);
+ outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
+
+ return 1;
+}
+
+static int trimpot_7376_write(struct comedi_device * dev, uint8_t value)
+{
+ static const int bitstream_length = 7;
+ unsigned int bitstream = value & 0x7f;
+ unsigned int register_bits;
+ static const int ad7376_comedi_udelay = 1;
+
+ register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
+ comedi_udelay(ad7376_comedi_udelay);
+ outw(register_bits, devpriv->control_status + CALIBRATION_REG);
+
+ write_calibration_bitstream(dev, register_bits, bitstream,
+ bitstream_length);
+
+ comedi_udelay(ad7376_comedi_udelay);
+ outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
+
+ return 0;
+}
+
+/* For 1602/16 only
+ * ch 0 : adc gain
+ * ch 1 : adc postgain offset */
+static int trimpot_8402_write(struct comedi_device * dev, unsigned int channel,
+ uint8_t value)
+{
+ static const int bitstream_length = 10;
+ unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
+ unsigned int register_bits;
+ static const int ad8402_comedi_udelay = 1;
+
+ register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
+ comedi_udelay(ad8402_comedi_udelay);
+ outw(register_bits, devpriv->control_status + CALIBRATION_REG);
+
+ write_calibration_bitstream(dev, register_bits, bitstream,
+ bitstream_length);
+
+ comedi_udelay(ad8402_comedi_udelay);
+ outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
+
+ return 0;
+}
+
+static int wait_for_nvram_ready(unsigned long s5933_base_addr)
+{
+ static const int timeout = 1000;
+ unsigned int i;
+
+ for (i = 0; i < timeout; i++) {
+ if ((inb(s5933_base_addr +
+ AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
+ == 0)
+ return 0;
+ comedi_udelay(1);
+ }
+ return -1;
+}
+
+static int nvram_read(struct comedi_device * dev, unsigned int address, uint8_t * data)
+{
+ unsigned long iobase = devpriv->s5933_config;
+
+ if (wait_for_nvram_ready(iobase) < 0)
+ return -ETIMEDOUT;
+
+ outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
+ iobase + AMCC_OP_REG_MCSR_NVCMD);
+ outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
+ outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
+ iobase + AMCC_OP_REG_MCSR_NVCMD);
+ outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
+ outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
+
+ if (wait_for_nvram_ready(iobase) < 0)
+ return -ETIMEDOUT;
+
+ *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
+
+ return 0;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_cb_pcidas, cb_pcidas_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
new file mode 100644
index 00000000000..1a580bd2247
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -0,0 +1,4222 @@
+/*
+ comedi/drivers/cb_pcidas64.c
+ This is a driver for the ComputerBoards/MeasurementComputing PCI-DAS
+ 64xx, 60xx, and 4020 cards.
+
+ Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+ Copyright (C) 2001, 2002 Frank Mori Hess
+
+ Thanks also go to the following people:
+
+ Steve Rosenbluth, for providing the source code for
+ his pci-das6402 driver, and source code for working QNX pci-6402
+ drivers by Greg Laird and Mariusz Bogacz. None of the code was
+ used directly here, but it was useful as an additional source of
+ documentation on how to program the boards.
+
+ John Sims, for much testing and feedback on pcidas-4020 support.
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************/
+
+/*
+
+Driver: cb_pcidas64
+Description: MeasurementComputing PCI-DAS64xx, 60XX, and 4020 series with the PLX 9080 PCI controller
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Status: works
+Updated: 2002-10-09
+Devices: [Measurement Computing] PCI-DAS6402/16 (cb_pcidas64),
+ PCI-DAS6402/12, PCI-DAS64/M1/16, PCI-DAS64/M2/16,
+ PCI-DAS64/M3/16, PCI-DAS6402/16/JR, PCI-DAS64/M1/16/JR,
+ PCI-DAS64/M2/16/JR, PCI-DAS64/M3/16/JR, PCI-DAS64/M1/14,
+ PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6013, PCI-DAS6014,
+ PCI-DAS6023, PCI-DAS6025, PCI-DAS6030,
+ PCI-DAS6031, PCI-DAS6032, PCI-DAS6033, PCI-DAS6034,
+ PCI-DAS6035, PCI-DAS6036, PCI-DAS6040, PCI-DAS6052,
+ PCI-DAS6070, PCI-DAS6071, PCI-DAS4020/12
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+
+These boards may be autocalibrated with the comedi_calibrate utility.
+
+To select the bnc trigger input on the 4020 (instead of the dio input),
+specify a nonzero channel in the chanspec. If you wish to use an external
+master clock on the 4020, you may do so by setting the scan_begin_src
+to TRIG_OTHER, and using an INSN_CONFIG_TIMER_1 configuration insn
+to configure the divisor to use for the external clock.
+
+Some devices are not identified because the PCI device IDs are not yet
+known. If you have such a board, please file a bug report at
+https://bugs.comedi.org.
+
+*/
+
+/*
+
+TODO:
+ make it return error if user attempts an ai command that uses the
+ external queue, and an ao command simultaneously
+ user counter subdevice
+ there are a number of boards this driver will support when they are
+ fully released, but does not yet since the pci device id numbers
+ are not yet available.
+ support prescaled 100khz clock for slow pacing (not available on 6000 series?)
+ make ao fifo size adjustable like ai fifo
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+#include <asm/system.h>
+
+#include "comedi_pci.h"
+#include "8253.h"
+#include "8255.h"
+#include "plx9080.h"
+#include "comedi_fc.h"
+
+#undef PCIDAS64_DEBUG // disable debugging code
+//#define PCIDAS64_DEBUG // enable debugging code
+
+#ifdef PCIDAS64_DEBUG
+#define DEBUG_PRINT(format, args...) rt_printk(format , ## args )
+#else
+#define DEBUG_PRINT(format, args...)
+#endif
+
+#define TIMER_BASE 25 // 40MHz master clock
+#define PRESCALED_TIMER_BASE 10000 // 100kHz 'prescaled' clock for slow aquisition, maybe I'll support this someday
+#define DMA_BUFFER_SIZE 0x1000
+
+/* maximum value that can be loaded into board's 24-bit counters*/
+static const int max_counter_value = 0xffffff;
+
+/* PCI-DAS64xxx base addresses */
+
+// indices of base address regions
+enum base_address_regions {
+ PLX9080_BADDRINDEX = 0,
+ MAIN_BADDRINDEX = 2,
+ DIO_COUNTER_BADDRINDEX = 3,
+};
+
+// priv(dev)->main_iobase registers
+enum write_only_registers {
+ INTR_ENABLE_REG = 0x0, // interrupt enable register
+ HW_CONFIG_REG = 0x2, // hardware config register
+ DAQ_SYNC_REG = 0xc,
+ DAQ_ATRIG_LOW_4020_REG = 0xc,
+ ADC_CONTROL0_REG = 0x10, // adc control register 0
+ ADC_CONTROL1_REG = 0x12, // adc control register 1
+ CALIBRATION_REG = 0x14,
+ ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16, // lower 16 bits of adc sample interval counter
+ ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18, // upper 8 bits of adc sample interval counter
+ ADC_DELAY_INTERVAL_LOWER_REG = 0x1a, // lower 16 bits of delay interval counter
+ ADC_DELAY_INTERVAL_UPPER_REG = 0x1c, // upper 8 bits of delay interval counter
+ ADC_COUNT_LOWER_REG = 0x1e, // lower 16 bits of hardware conversion/scan counter
+ ADC_COUNT_UPPER_REG = 0x20, // upper 8 bits of hardware conversion/scan counter
+ ADC_START_REG = 0x22, // software trigger to start aquisition
+ ADC_CONVERT_REG = 0x24, // initiates single conversion
+ ADC_QUEUE_CLEAR_REG = 0x26, // clears adc queue
+ ADC_QUEUE_LOAD_REG = 0x28, // loads adc queue
+ ADC_BUFFER_CLEAR_REG = 0x2a,
+ ADC_QUEUE_HIGH_REG = 0x2c, // high channel for internal queue, use adc_chan_bits() inline above
+ DAC_CONTROL0_REG = 0x50, // dac control register 0
+ DAC_CONTROL1_REG = 0x52, // dac control register 0
+ DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54, // lower 16 bits of dac sample interval counter
+ DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56, // upper 8 bits of dac sample interval counter
+ DAC_SELECT_REG = 0x60,
+ DAC_START_REG = 0x64,
+ DAC_BUFFER_CLEAR_REG = 0x66, // clear dac buffer
+};
+static inline unsigned int dac_convert_reg(unsigned int channel)
+{
+ return 0x70 + (2 * (channel & 0x1));
+}
+static inline unsigned int dac_lsb_4020_reg(unsigned int channel)
+{
+ return 0x70 + (4 * (channel & 0x1));
+}
+static inline unsigned int dac_msb_4020_reg(unsigned int channel)
+{
+ return 0x72 + (4 * (channel & 0x1));
+}
+
+enum read_only_registers {
+ HW_STATUS_REG = 0x0, // hardware status register, reading this apparently clears pending interrupts as well
+ PIPE1_READ_REG = 0x4,
+ ADC_READ_PNTR_REG = 0x8,
+ LOWER_XFER_REG = 0x10,
+ ADC_WRITE_PNTR_REG = 0xc,
+ PREPOST_REG = 0x14,
+};
+
+enum read_write_registers {
+ I8255_4020_REG = 0x48, // 8255 offset, for 4020 only
+ ADC_QUEUE_FIFO_REG = 0x100, // external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG
+ ADC_FIFO_REG = 0x200, /* adc data fifo */
+ DAC_FIFO_REG = 0x300, /* dac data fifo, has weird interactions with external channel queue */
+};
+
+// priv(dev)->dio_counter_iobase registers
+enum dio_counter_registers {
+ DIO_8255_OFFSET = 0x0,
+ DO_REG = 0x20,
+ DI_REG = 0x28,
+ DIO_DIRECTION_60XX_REG = 0x40,
+ DIO_DATA_60XX_REG = 0x48,
+};
+
+// bit definitions for write-only registers
+
+enum intr_enable_contents {
+ ADC_INTR_SRC_MASK = 0x3, // bits that set adc interrupt source
+ ADC_INTR_QFULL_BITS = 0x0, // interrupt fifo quater full
+ ADC_INTR_EOC_BITS = 0x1, // interrupt end of conversion
+ ADC_INTR_EOSCAN_BITS = 0x2, // interrupt end of scan
+ ADC_INTR_EOSEQ_BITS = 0x3, // interrupt end of sequence (probably wont use this it's pretty fancy)
+ EN_ADC_INTR_SRC_BIT = 0x4, // enable adc interrupt source
+ EN_ADC_DONE_INTR_BIT = 0x8, // enable adc aquisition done interrupt
+ DAC_INTR_SRC_MASK = 0x30,
+ DAC_INTR_QEMPTY_BITS = 0x0,
+ DAC_INTR_HIGH_CHAN_BITS = 0x10,
+ EN_DAC_INTR_SRC_BIT = 0x40, // enable dac interrupt source
+ EN_DAC_DONE_INTR_BIT = 0x80,
+ EN_ADC_ACTIVE_INTR_BIT = 0x200, // enable adc active interrupt
+ EN_ADC_STOP_INTR_BIT = 0x400, // enable adc stop trigger interrupt
+ EN_DAC_ACTIVE_INTR_BIT = 0x800, // enable dac active interrupt
+ EN_DAC_UNDERRUN_BIT = 0x4000, // enable dac underrun status bit
+ EN_ADC_OVERRUN_BIT = 0x8000, // enable adc overrun status bit
+};
+
+enum hw_config_contents {
+ MASTER_CLOCK_4020_MASK = 0x3, // bits that specify master clock source for 4020
+ INTERNAL_CLOCK_4020_BITS = 0x1, // use 40 MHz internal master clock for 4020
+ BNC_CLOCK_4020_BITS = 0x2, // use BNC input for master clock
+ EXT_CLOCK_4020_BITS = 0x3, // use dio input for master clock
+ EXT_QUEUE_BIT = 0x200, // use external channel/gain queue (more versatile than internal queue)
+ SLOW_DAC_BIT = 0x400, // use 225 nanosec strobe when loading dac instead of 50 nanosec
+ HW_CONFIG_DUMMY_BITS = 0x2000, // bit with unknown function yet given as default value in pci-das64 manual
+ DMA_CH_SELECT_BIT = 0x8000, // bit selects channels 1/0 for analog input/output, otherwise 0/1
+ FIFO_SIZE_REG = 0x4, // allows adjustment of fifo sizes
+ DAC_FIFO_SIZE_MASK = 0xff00, // bits that set dac fifo size
+ DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */
+};
+#define DAC_FIFO_SIZE 0x2000
+
+enum daq_atrig_low_4020_contents {
+ EXT_AGATE_BNC_BIT = 0x8000, // use trig/ext clk bnc input for analog gate signal
+ EXT_STOP_TRIG_BNC_BIT = 0x4000, // use trig/ext clk bnc input for external stop trigger signal
+ EXT_START_TRIG_BNC_BIT = 0x2000, // use trig/ext clk bnc input for external start trigger signal
+};
+static inline uint16_t analog_trig_low_threshold_bits(uint16_t threshold)
+{
+ return threshold & 0xfff;
+}
+
+enum adc_control0_contents {
+ ADC_GATE_SRC_MASK = 0x3, // bits that select gate
+ ADC_SOFT_GATE_BITS = 0x1, // software gate
+ ADC_EXT_GATE_BITS = 0x2, // external digital gate
+ ADC_ANALOG_GATE_BITS = 0x3, // analog level gate
+ ADC_GATE_LEVEL_BIT = 0x4, // level-sensitive gate (for digital)
+ ADC_GATE_POLARITY_BIT = 0x8, // gate active low
+ ADC_START_TRIG_SOFT_BITS = 0x10,
+ ADC_START_TRIG_EXT_BITS = 0x20,
+ ADC_START_TRIG_ANALOG_BITS = 0x30,
+ ADC_START_TRIG_MASK = 0x30,
+ ADC_START_TRIG_FALLING_BIT = 0x40, // trig 1 uses falling edge
+ ADC_EXT_CONV_FALLING_BIT = 0x800, // external pacing uses falling edge
+ ADC_SAMPLE_COUNTER_EN_BIT = 0x1000, // enable hardware scan counter
+ ADC_DMA_DISABLE_BIT = 0x4000, // disables dma
+ ADC_ENABLE_BIT = 0x8000, // master adc enable
+};
+
+enum adc_control1_contents {
+ ADC_QUEUE_CONFIG_BIT = 0x1, // should be set for boards with > 16 channels
+ CONVERT_POLARITY_BIT = 0x10,
+ EOC_POLARITY_BIT = 0x20,
+ ADC_SW_GATE_BIT = 0x40, // software gate of adc
+ ADC_DITHER_BIT = 0x200, // turn on extra noise for dithering
+ RETRIGGER_BIT = 0x800,
+ ADC_LO_CHANNEL_4020_MASK = 0x300,
+ ADC_HI_CHANNEL_4020_MASK = 0xc00,
+ TWO_CHANNEL_4020_BITS = 0x1000, // two channel mode for 4020
+ FOUR_CHANNEL_4020_BITS = 0x2000, // four channel mode for 4020
+ CHANNEL_MODE_4020_MASK = 0x3000,
+ ADC_MODE_MASK = 0xf000,
+};
+static inline uint16_t adc_lo_chan_4020_bits(unsigned int channel)
+{
+ return (channel & 0x3) << 8;
+};
+static inline uint16_t adc_hi_chan_4020_bits(unsigned int channel)
+{
+ return (channel & 0x3) << 10;
+};
+static inline uint16_t adc_mode_bits(unsigned int mode)
+{
+ return (mode & 0xf) << 12;
+};
+
+enum calibration_contents {
+ SELECT_8800_BIT = 0x1,
+ SELECT_8402_64XX_BIT = 0x2,
+ SELECT_1590_60XX_BIT = 0x2,
+ CAL_EN_64XX_BIT = 0x40, // calibration enable for 64xx series
+ SERIAL_DATA_IN_BIT = 0x80,
+ SERIAL_CLOCK_BIT = 0x100,
+ CAL_EN_60XX_BIT = 0x200, // calibration enable for 60xx series
+ CAL_GAIN_BIT = 0x800,
+};
+/* calibration sources for 6025 are:
+ * 0 : ground
+ * 1 : 10V
+ * 2 : 5V
+ * 3 : 0.5V
+ * 4 : 0.05V
+ * 5 : ground
+ * 6 : dac channel 0
+ * 7 : dac channel 1
+ */
+static inline uint16_t adc_src_bits(unsigned int source)
+{
+ return (source & 0xf) << 3;
+};
+
+static inline uint16_t adc_convert_chan_4020_bits(unsigned int channel)
+{
+ return (channel & 0x3) << 8;
+};
+
+enum adc_queue_load_contents {
+ UNIP_BIT = 0x800, // unipolar/bipolar bit
+ ADC_SE_DIFF_BIT = 0x1000, // single-ended/ differential bit
+ ADC_COMMON_BIT = 0x2000, // non-referenced single-ended (common-mode input)
+ QUEUE_EOSEQ_BIT = 0x4000, // queue end of sequence
+ QUEUE_EOSCAN_BIT = 0x8000, // queue end of scan
+};
+static inline uint16_t adc_chan_bits(unsigned int channel)
+{
+ return channel & 0x3f;
+};
+
+enum dac_control0_contents {
+ DAC_ENABLE_BIT = 0x8000, // dac controller enable bit
+ DAC_CYCLIC_STOP_BIT = 0x4000,
+ DAC_WAVEFORM_MODE_BIT = 0x100,
+ DAC_EXT_UPDATE_FALLING_BIT = 0x80,
+ DAC_EXT_UPDATE_ENABLE_BIT = 0x40,
+ WAVEFORM_TRIG_MASK = 0x30,
+ WAVEFORM_TRIG_DISABLED_BITS = 0x0,
+ WAVEFORM_TRIG_SOFT_BITS = 0x10,
+ WAVEFORM_TRIG_EXT_BITS = 0x20,
+ WAVEFORM_TRIG_ADC1_BITS = 0x30,
+ WAVEFORM_TRIG_FALLING_BIT = 0x8,
+ WAVEFORM_GATE_LEVEL_BIT = 0x4,
+ WAVEFORM_GATE_ENABLE_BIT = 0x2,
+ WAVEFORM_GATE_SELECT_BIT = 0x1,
+};
+
+enum dac_control1_contents {
+ DAC_WRITE_POLARITY_BIT = 0x800, /* board-dependent setting */
+ DAC1_EXT_REF_BIT = 0x200,
+ DAC0_EXT_REF_BIT = 0x100,
+ DAC_OUTPUT_ENABLE_BIT = 0x80, // dac output enable bit
+ DAC_UPDATE_POLARITY_BIT = 0x40, /* board-dependent setting */
+ DAC_SW_GATE_BIT = 0x20,
+ DAC1_UNIPOLAR_BIT = 0x8,
+ DAC0_UNIPOLAR_BIT = 0x2,
+};
+
+// bit definitions for read-only registers
+enum hw_status_contents {
+ DAC_UNDERRUN_BIT = 0x1,
+ ADC_OVERRUN_BIT = 0x2,
+ DAC_ACTIVE_BIT = 0x4,
+ ADC_ACTIVE_BIT = 0x8,
+ DAC_INTR_PENDING_BIT = 0x10,
+ ADC_INTR_PENDING_BIT = 0x20,
+ DAC_DONE_BIT = 0x40,
+ ADC_DONE_BIT = 0x80,
+ EXT_INTR_PENDING_BIT = 0x100,
+ ADC_STOP_BIT = 0x200,
+};
+static inline uint16_t pipe_full_bits(uint16_t hw_status_bits)
+{
+ return (hw_status_bits >> 10) & 0x3;
+};
+
+static inline unsigned int dma_chain_flag_bits(uint16_t prepost_bits)
+{
+ return (prepost_bits >> 6) & 0x3;
+}
+static inline unsigned int adc_upper_read_ptr_code(uint16_t prepost_bits)
+{
+ return (prepost_bits >> 12) & 0x3;
+}
+static inline unsigned int adc_upper_write_ptr_code(uint16_t prepost_bits)
+{
+ return (prepost_bits >> 14) & 0x3;
+}
+
+// I2C addresses for 4020
+enum i2c_addresses {
+ RANGE_CAL_I2C_ADDR = 0x20,
+ CALDAC0_I2C_ADDR = 0xc,
+ CALDAC1_I2C_ADDR = 0xd,
+};
+
+enum range_cal_i2c_contents {
+ ADC_SRC_4020_MASK = 0x70, // bits that set what source the adc converter measures
+ BNC_TRIG_THRESHOLD_0V_BIT = 0x80, // make bnc trig/ext clock threshold 0V instead of 2.5V
+};
+static inline uint8_t adc_src_4020_bits(unsigned int source)
+{
+ return (source << 4) & ADC_SRC_4020_MASK;
+};
+static inline uint8_t attenuate_bit(unsigned int channel)
+{
+ // attenuate channel (+-5V input range)
+ return 1 << (channel & 0x3);
+};
+
+// analog input ranges for 64xx boards
+static const struct comedi_lrange ai_ranges_64xx = {
+ 8,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25)
+ }
+};
+
+/* analog input ranges for 60xx boards */
+static const struct comedi_lrange ai_ranges_60xx = {
+ 4,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ }
+};
+
+/* analog input ranges for 6030, etc boards */
+static const struct comedi_lrange ai_ranges_6030 = {
+ 14,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.2),
+ BIP_RANGE(0.1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1),
+ UNI_RANGE(0.5),
+ UNI_RANGE(0.2),
+ UNI_RANGE(0.1),
+ }
+};
+
+/* analog input ranges for 6052, etc boards */
+static const struct comedi_lrange ai_ranges_6052 = {
+ 15,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.25),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.05),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1),
+ UNI_RANGE(0.5),
+ UNI_RANGE(0.2),
+ UNI_RANGE(0.1),
+ }
+};
+
+// analog input ranges for 4020 board
+static const struct comedi_lrange ai_ranges_4020 = {
+ 2,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(1),
+ }
+};
+
+// analog output ranges
+static const struct comedi_lrange ao_ranges_64xx = {
+ 4,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(10),
+ }
+};
+static const int ao_range_code_64xx[] = {
+ 0x0,
+ 0x1,
+ 0x2,
+ 0x3,
+};
+
+static const struct comedi_lrange ao_ranges_60xx = {
+ 1,
+ {
+ BIP_RANGE(10),
+ }
+};
+static const int ao_range_code_60xx[] = {
+ 0x0,
+};
+
+static const struct comedi_lrange ao_ranges_6030 = {
+ 2,
+ {
+ BIP_RANGE(10),
+ UNI_RANGE(10),
+ }
+};
+static const int ao_range_code_6030[] = {
+ 0x0,
+ 0x2,
+};
+
+static const struct comedi_lrange ao_ranges_4020 = {
+ 2,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(10),
+ }
+};
+static const int ao_range_code_4020[] = {
+ 0x1,
+ 0x0,
+};
+
+enum register_layout {
+ LAYOUT_60XX,
+ LAYOUT_64XX,
+ LAYOUT_4020,
+};
+
+struct hw_fifo_info {
+ unsigned int num_segments;
+ unsigned int max_segment_length;
+ unsigned int sample_packing_ratio;
+ uint16_t fifo_size_reg_mask;
+};
+
+struct pcidas64_board {
+ const char *name;
+ int device_id; // pci device id
+ int ai_se_chans; // number of ai inputs in single-ended mode
+ int ai_bits; // analog input resolution
+ int ai_speed; // fastest conversion period in ns
+ const struct comedi_lrange *ai_range_table;
+ int ao_nchan; // number of analog out channels
+ int ao_bits; // analog output resolution
+ int ao_scan_speed; // analog output speed (for a scan, not conversion)
+ const struct comedi_lrange *ao_range_table;
+ const int *ao_range_code;
+ const struct hw_fifo_info *const ai_fifo;
+ enum register_layout layout; // different board families have slightly different registers
+ unsigned has_8255:1;
+};
+
+static const struct hw_fifo_info ai_fifo_4020 = {
+ num_segments:2,
+ max_segment_length:0x8000,
+ sample_packing_ratio:2,
+ fifo_size_reg_mask:0x7f,
+};
+
+static const struct hw_fifo_info ai_fifo_64xx = {
+ num_segments:4,
+ max_segment_length:0x800,
+ sample_packing_ratio:1,
+ fifo_size_reg_mask:0x3f,
+};
+
+static const struct hw_fifo_info ai_fifo_60xx = {
+ num_segments:4,
+ max_segment_length:0x800,
+ sample_packing_ratio:1,
+ fifo_size_reg_mask:0x7f,
+};
+
+/* maximum number of dma transfers we will chain together into a ring
+ * (and the maximum number of dma buffers we maintain) */
+#define MAX_AI_DMA_RING_COUNT (0x80000 / DMA_BUFFER_SIZE)
+#define MIN_AI_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
+#define AO_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
+static inline unsigned int ai_dma_ring_count(struct pcidas64_board * board)
+{
+ if (board->layout == LAYOUT_4020)
+ return MAX_AI_DMA_RING_COUNT;
+ else
+ return MIN_AI_DMA_RING_COUNT;
+}
+
+static const int bytes_in_sample = 2;
+
+static const struct pcidas64_board pcidas64_boards[] = {
+ {
+ name: "pci-das6402/16",
+ device_id:0x1d,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ao_range_table:&ao_ranges_64xx,
+ ao_range_code:ao_range_code_64xx,
+ ai_fifo: &ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das6402/12", // XXX check
+ device_id:0x1e,
+ ai_se_chans:64,
+ ai_bits: 12,
+ ai_speed:5000,
+ ao_nchan:2,
+ ao_bits: 12,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ao_range_table:&ao_ranges_64xx,
+ ao_range_code:ao_range_code_64xx,
+ ai_fifo: &ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m1/16",
+ device_id:0x35,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:1000,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ao_range_table:&ao_ranges_64xx,
+ ao_range_code:ao_range_code_64xx,
+ ai_fifo: &ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m2/16",
+ device_id:0x36,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:500,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ao_range_table:&ao_ranges_64xx,
+ ao_range_code:ao_range_code_64xx,
+ ai_fifo: &ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m3/16",
+ device_id:0x37,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:333,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ao_range_table:&ao_ranges_64xx,
+ ao_range_code:ao_range_code_64xx,
+ ai_fifo: &ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ .name = "pci-das6013",
+ .device_id = 0x78,
+ .ai_se_chans = 16,
+ .ai_bits = 16,
+ .ai_speed = 5000,
+ .ao_nchan = 0,
+ .ao_bits = 16,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_60xx,
+ .ao_range_table = &ao_ranges_60xx,
+ .ao_range_code = ao_range_code_60xx,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ {
+ name: "pci-das6014",
+ device_id:0x79,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:100000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_60xx,
+ ao_range_table:&ao_ranges_60xx,
+ ao_range_code:ao_range_code_60xx,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6023",
+ device_id:0x5d,
+ ai_se_chans:16,
+ ai_bits: 12,
+ ai_speed:5000,
+ ao_nchan:0,
+ ao_scan_speed:100000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_60xx,
+ ao_range_table:&ao_ranges_60xx,
+ ao_range_code:ao_range_code_60xx,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das6025",
+ device_id:0x5e,
+ ai_se_chans:16,
+ ai_bits: 12,
+ ai_speed:5000,
+ ao_nchan:2,
+ ao_bits: 12,
+ ao_scan_speed:100000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_60xx,
+ ao_range_table:&ao_ranges_60xx,
+ ao_range_code:ao_range_code_60xx,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das6030",
+ device_id:0x5f,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:10000,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:10000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6030,
+ ao_range_table:&ao_ranges_6030,
+ ao_range_code:ao_range_code_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6031",
+ device_id:0x60,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:10000,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:10000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6030,
+ ao_range_table:&ao_ranges_6030,
+ ao_range_code:ao_range_code_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6032",
+ device_id:0x61,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:10000,
+ ao_nchan:0,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6033",
+ device_id:0x62,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:10000,
+ ao_nchan:0,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6034",
+ device_id:0x63,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:0,
+ ao_scan_speed:0,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_60xx,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6035",
+ device_id:0x64,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:2,
+ ao_bits: 12,
+ ao_scan_speed:100000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_60xx,
+ ao_range_table:&ao_ranges_60xx,
+ ao_range_code:ao_range_code_60xx,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6036",
+ device_id:0x6f,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:100000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_60xx,
+ ao_range_table:&ao_ranges_60xx,
+ ao_range_code:ao_range_code_60xx,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6040",
+ device_id:0x65,
+ ai_se_chans:16,
+ ai_bits: 12,
+ ai_speed:2000,
+ ao_nchan:2,
+ ao_bits: 12,
+ ao_scan_speed:1000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6052,
+ ao_range_table:&ao_ranges_6030,
+ ao_range_code:ao_range_code_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6052",
+ device_id:0x66,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:3333,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:3333,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6052,
+ ao_range_table:&ao_ranges_6030,
+ ao_range_code:ao_range_code_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6070",
+ device_id:0x67,
+ ai_se_chans:16,
+ ai_bits: 12,
+ ai_speed:800,
+ ao_nchan:2,
+ ao_bits: 12,
+ ao_scan_speed:1000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6052,
+ ao_range_table:&ao_ranges_6030,
+ ao_range_code:ao_range_code_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6071",
+ device_id:0x68,
+ ai_se_chans:64,
+ ai_bits: 12,
+ ai_speed:800,
+ ao_nchan:2,
+ ao_bits: 12,
+ ao_scan_speed:1000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6052,
+ ao_range_table:&ao_ranges_6030,
+ ao_range_code:ao_range_code_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das4020/12",
+ device_id:0x52,
+ ai_se_chans:4,
+ ai_bits: 12,
+ ai_speed:50,
+ ao_bits: 12,
+ ao_nchan:2,
+ ao_scan_speed:0, // no hardware pacing on ao
+ layout: LAYOUT_4020,
+ ai_range_table:&ai_ranges_4020,
+ ao_range_table:&ao_ranges_4020,
+ ao_range_code:ao_range_code_4020,
+ ai_fifo: &ai_fifo_4020,
+ has_8255:1,
+ },
+#if 0
+ {
+ name: "pci-das6402/16/jr",
+ device_id:0 // XXX,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:0,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m1/16/jr",
+ device_id:0 // XXX,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:1000,
+ ao_nchan:0,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m2/16/jr",
+ device_id:0 // XXX,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:500,
+ ao_nchan:0,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m3/16/jr",
+ device_id:0 // XXX,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:333,
+ ao_nchan:0,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m1/14",
+ device_id:0, // XXX
+ ai_se_chans:64,
+ ai_bits: 14,
+ ai_speed:1000,
+ ao_nchan:2,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m2/14",
+ device_id:0, // XXX
+ ai_se_chans:64,
+ ai_bits: 14,
+ ai_speed:500,
+ ao_nchan:2,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m3/14",
+ device_id:0, // XXX
+ ai_se_chans:64,
+ ai_bits: 14,
+ ai_speed:333,
+ ao_nchan:2,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+#endif
+};
+
+// Number of boards in cb_pcidas_boards
+static inline unsigned int num_boards(void)
+{
+ return sizeof(pcidas64_boards) / sizeof(struct pcidas64_board);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(pcidas64_pci_table) = {
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x001d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x001e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x005d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x005e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x005f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0061, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0062, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0063, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0066, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0067, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x006f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0078, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0079, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pcidas64_pci_table);
+
+static inline struct pcidas64_board *board(const struct comedi_device * dev)
+{
+ return (struct pcidas64_board *) dev->board_ptr;
+}
+
+static inline unsigned short se_diff_bit_6xxx(struct comedi_device * dev,
+ int use_differential)
+{
+ if ((board(dev)->layout == LAYOUT_64XX && !use_differential) ||
+ (board(dev)->layout == LAYOUT_60XX && use_differential))
+ return ADC_SE_DIFF_BIT;
+ else
+ return 0;
+};
+
+struct ext_clock_info {
+ unsigned int divisor; // master clock divisor to use for scans with external master clock
+ unsigned int chanspec; // chanspec for master clock input when used as scan begin src
+};
+
+/* this structure is for data unique to this hardware driver. */
+struct pcidas64_private {
+
+ struct pci_dev *hw_dev; // pointer to board's pci_dev struct
+ // base addresses (physical)
+ resource_size_t plx9080_phys_iobase;
+ resource_size_t main_phys_iobase;
+ resource_size_t dio_counter_phys_iobase;
+ // base addresses (ioremapped)
+ void *plx9080_iobase;
+ void *main_iobase;
+ void *dio_counter_iobase;
+ // local address (used by dma controller)
+ uint32_t local0_iobase;
+ uint32_t local1_iobase;
+ volatile unsigned int ai_count; // number of analog input samples remaining
+ uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT]; // dma buffers for analog input
+ dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT]; // physical addresses of ai dma buffers
+ struct plx_dma_desc *ai_dma_desc; // array of ai dma descriptors read by plx9080, allocated to get proper alignment
+ dma_addr_t ai_dma_desc_bus_addr; // physical address of ai dma descriptor array
+ volatile unsigned int ai_dma_index; // index of the ai dma descriptor/buffer that is currently being used
+ uint16_t *ao_buffer[AO_DMA_RING_COUNT]; // dma buffers for analog output
+ dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT]; // physical addresses of ao dma buffers
+ struct plx_dma_desc *ao_dma_desc;
+ dma_addr_t ao_dma_desc_bus_addr;
+ volatile unsigned int ao_dma_index; // keeps track of buffer where the next ao sample should go
+ volatile unsigned long ao_count; // number of analog output samples remaining
+ volatile unsigned int ao_value[2]; // remember what the analog outputs are set to, to allow readback
+ unsigned int hw_revision; // stc chip hardware revision number
+ volatile unsigned int intr_enable_bits; // last bits sent to INTR_ENABLE_REG register
+ volatile uint16_t adc_control1_bits; // last bits sent to ADC_CONTROL1_REG register
+ volatile uint16_t fifo_size_bits; // last bits sent to FIFO_SIZE_REG register
+ volatile uint16_t hw_config_bits; // last bits sent to HW_CONFIG_REG register
+ volatile uint16_t dac_control1_bits;
+ volatile uint32_t plx_control_bits; // last bits written to plx9080 control register
+ volatile uint32_t plx_intcsr_bits; // last bits written to plx interrupt control and status register
+ volatile int calibration_source; // index of calibration source readable through ai ch0
+ volatile uint8_t i2c_cal_range_bits; // bits written to i2c calibration/range register
+ volatile unsigned int ext_trig_falling; // configure digital triggers to trigger on falling edge
+ // states of various devices stored to enable read-back
+ unsigned int ad8402_state[2];
+ unsigned int caldac_state[8];
+ volatile short ai_cmd_running;
+ unsigned int ai_fifo_segment_length;
+ struct ext_clock_info ext_clock;
+ short ao_bounce_buffer[DAC_FIFO_SIZE];
+};
+
+
+/* inline function that makes it easier to
+ * access the private structure.
+ */
+static inline struct pcidas64_private *priv(struct comedi_device * dev)
+{
+ return dev->private;
+}
+
+/*
+ * The comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int detach(struct comedi_device * dev);
+static struct comedi_driver driver_cb_pcidas = {
+ driver_name:"cb_pcidas64",
+ module:THIS_MODULE,
+ attach:attach,
+ detach:detach,
+};
+
+static int ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ unsigned int trig_num);
+static int ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG);
+static int ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dio_callback(int dir, int port, int data, unsigned long arg);
+static int dio_callback_4020(int dir, int port, int data, unsigned long arg);
+static int di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dio_60xx_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dio_60xx_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int calib_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int calib_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ad8402_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static void ad8402_write(struct comedi_device * dev, unsigned int channel,
+ unsigned int value);
+static int ad8402_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static void check_adc_timing(struct comedi_device * dev, struct comedi_cmd * cmd);
+static unsigned int get_divisor(unsigned int ns, unsigned int flags);
+static void i2c_write(struct comedi_device * dev, unsigned int address,
+ const uint8_t * data, unsigned int length);
+static void caldac_write(struct comedi_device * dev, unsigned int channel,
+ unsigned int value);
+static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
+ uint8_t value);
+//static int dac_1590_write(struct comedi_device *dev, unsigned int dac_a, unsigned int dac_b);
+static int caldac_i2c_write(struct comedi_device * dev, unsigned int caldac_channel,
+ unsigned int value);
+static void abort_dma(struct comedi_device * dev, unsigned int channel);
+static void disable_plx_interrupts(struct comedi_device * dev);
+static int set_ai_fifo_size(struct comedi_device * dev, unsigned int num_samples);
+static unsigned int ai_fifo_size(struct comedi_device * dev);
+static int set_ai_fifo_segment_length(struct comedi_device * dev,
+ unsigned int num_entries);
+static void disable_ai_pacing(struct comedi_device * dev);
+static void disable_ai_interrupts(struct comedi_device * dev);
+static void enable_ai_interrupts(struct comedi_device * dev, const struct comedi_cmd * cmd);
+static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags);
+static void load_ao_dma(struct comedi_device * dev, const struct comedi_cmd * cmd);
+
+COMEDI_PCI_INITCLEANUP(driver_cb_pcidas, pcidas64_pci_table);
+
+static unsigned int ai_range_bits_6xxx(const struct comedi_device * dev,
+ unsigned int range_index)
+{
+ const struct comedi_krange *range =
+ &board(dev)->ai_range_table->range[range_index];
+ unsigned int bits = 0;
+
+ switch (range->max) {
+ case 10000000:
+ bits = 0x000;
+ break;
+ case 5000000:
+ bits = 0x100;
+ break;
+ case 2000000:
+ case 2500000:
+ bits = 0x200;
+ break;
+ case 1000000:
+ case 1250000:
+ bits = 0x300;
+ break;
+ case 500000:
+ bits = 0x400;
+ break;
+ case 200000:
+ case 250000:
+ bits = 0x500;
+ break;
+ case 100000:
+ bits = 0x600;
+ break;
+ case 50000:
+ bits = 0x700;
+ break;
+ default:
+ comedi_error(dev, "bug! in ai_range_bits_6xxx");
+ break;
+ }
+ if (range->min == 0)
+ bits += 0x900;
+ return bits;
+}
+
+static unsigned int hw_revision(const struct comedi_device * dev,
+ uint16_t hw_status_bits)
+{
+ if (board(dev)->layout == LAYOUT_4020)
+ return (hw_status_bits >> 13) & 0x7;
+
+ return (hw_status_bits >> 12) & 0xf;
+}
+
+static void set_dac_range_bits(struct comedi_device * dev, volatile uint16_t * bits,
+ unsigned int channel, unsigned int range)
+{
+ unsigned int code = board(dev)->ao_range_code[range];
+
+ if (channel > 1)
+ comedi_error(dev, "bug! bad channel?");
+ if (code & ~0x3)
+ comedi_error(dev, "bug! bad range code?");
+
+ *bits &= ~(0x3 << (2 * channel));
+ *bits |= code << (2 * channel);
+};
+
+static inline int ao_cmd_is_supported(const struct pcidas64_board * board)
+{
+ return board->ao_nchan && board->layout != LAYOUT_4020;
+}
+
+// initialize plx9080 chip
+static void init_plx9080(struct comedi_device * dev)
+{
+ uint32_t bits;
+ void *plx_iobase = priv(dev)->plx9080_iobase;
+
+ priv(dev)->plx_control_bits =
+ readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG);
+
+ // plx9080 dump
+ DEBUG_PRINT(" plx interrupt status 0x%x\n",
+ readl(plx_iobase + PLX_INTRCS_REG));
+ DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
+ DEBUG_PRINT(" plx control reg 0x%x\n", priv(dev)->plx_control_bits);
+ DEBUG_PRINT(" plx mode/arbitration reg 0x%x\n",
+ readl(plx_iobase + PLX_MARB_REG));
+ DEBUG_PRINT(" plx region0 reg 0x%x\n",
+ readl(plx_iobase + PLX_REGION0_REG));
+ DEBUG_PRINT(" plx region1 reg 0x%x\n",
+ readl(plx_iobase + PLX_REGION1_REG));
+
+ DEBUG_PRINT(" plx revision 0x%x\n",
+ readl(plx_iobase + PLX_REVISION_REG));
+ DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_MODE_REG));
+ DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
+ readl(plx_iobase + PLX_DMA1_MODE_REG));
+ DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG));
+ DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG));
+ DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG));
+ DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG));
+ DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n",
+ readb(plx_iobase + PLX_DMA0_CS_REG));
+ DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
+ DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG));
+
+#ifdef __BIG_ENDIAN
+ bits = BIGEND_DMA0 | BIGEND_DMA1;
+#else
+ bits = 0;
+#endif
+ writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG);
+
+ disable_plx_interrupts(dev);
+
+ abort_dma(dev, 0);
+ abort_dma(dev, 1);
+
+ // configure dma0 mode
+ bits = 0;
+ // enable ready input, not sure if this is necessary
+ bits |= PLX_DMA_EN_READYIN_BIT;
+ // enable bterm, not sure if this is necessary
+ bits |= PLX_EN_BTERM_BIT;
+ // enable dma chaining
+ bits |= PLX_EN_CHAIN_BIT;
+ // enable interrupt on dma done (probably don't need this, since chain never finishes)
+ bits |= PLX_EN_DMA_DONE_INTR_BIT;
+ // don't increment local address during transfers (we are transferring from a fixed fifo register)
+ bits |= PLX_LOCAL_ADDR_CONST_BIT;
+ // route dma interrupt to pci bus
+ bits |= PLX_DMA_INTR_PCI_BIT;
+ // enable demand mode
+ bits |= PLX_DEMAND_MODE_BIT;
+ // enable local burst mode
+ bits |= PLX_DMA_LOCAL_BURST_EN_BIT;
+ // 4020 uses 32 bit dma
+ if (board(dev)->layout == LAYOUT_4020) {
+ bits |= PLX_LOCAL_BUS_32_WIDE_BITS;
+ } else { // localspace0 bus is 16 bits wide
+ bits |= PLX_LOCAL_BUS_16_WIDE_BITS;
+ }
+ writel(bits, plx_iobase + PLX_DMA1_MODE_REG);
+ if (ao_cmd_is_supported(board(dev)))
+ writel(bits, plx_iobase + PLX_DMA0_MODE_REG);
+
+ // enable interrupts on plx 9080
+ priv(dev)->plx_intcsr_bits |=
+ ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
+ ICS_DMA0_E | ICS_DMA1_E;
+ writel(priv(dev)->plx_intcsr_bits,
+ priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+}
+
+/* Allocate and initialize the subdevice structures.
+ */
+static int setup_subdevices(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s;
+ void *dio_8255_iobase;
+ int i;
+
+ if (alloc_subdevices(dev, 10) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog input subdevice */
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ;
+ if (board(dev)->layout == LAYOUT_60XX)
+ s->subdev_flags |= SDF_COMMON | SDF_DIFF;
+ else if (board(dev)->layout == LAYOUT_64XX)
+ s->subdev_flags |= SDF_DIFF;
+ /* XXX Number of inputs in differential mode is ignored */
+ s->n_chan = board(dev)->ai_se_chans;
+ s->len_chanlist = 0x2000;
+ s->maxdata = (1 << board(dev)->ai_bits) - 1;
+ s->range_table = board(dev)->ai_range_table;
+ s->insn_read = ai_rinsn;
+ s->insn_config = ai_config_insn;
+ s->do_cmd = ai_cmd;
+ s->do_cmdtest = ai_cmdtest;
+ s->cancel = ai_cancel;
+ if (board(dev)->layout == LAYOUT_4020) {
+ unsigned int i;
+ uint8_t data;
+ // set adc to read from inputs (not internal calibration sources)
+ priv(dev)->i2c_cal_range_bits = adc_src_4020_bits(4);
+ // set channels to +-5 volt input ranges
+ for (i = 0; i < s->n_chan; i++)
+ priv(dev)->i2c_cal_range_bits |= attenuate_bit(i);
+ data = priv(dev)->i2c_cal_range_bits;
+ i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data));
+ }
+
+ /* analog output subdevice */
+ s = dev->subdevices + 1;
+ if (board(dev)->ao_nchan) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITABLE | SDF_GROUND |
+ SDF_CMD_WRITE;
+ s->n_chan = board(dev)->ao_nchan;
+ s->maxdata = (1 << board(dev)->ao_bits) - 1;
+ s->range_table = board(dev)->ao_range_table;
+ s->insn_read = ao_readback_insn;
+ s->insn_write = ao_winsn;
+ if (ao_cmd_is_supported(board(dev))) {
+ dev->write_subdev = s;
+ s->do_cmdtest = ao_cmdtest;
+ s->do_cmd = ao_cmd;
+ s->len_chanlist = board(dev)->ao_nchan;
+ s->cancel = ao_cancel;
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ // digital input
+ s = dev->subdevices + 2;
+ if (board(dev)->layout == LAYOUT_64XX) {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = di_rbits;
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ // digital output
+ if (board(dev)->layout == LAYOUT_64XX) {
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = do_wbits;
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ /* 8255 */
+ s = dev->subdevices + 4;
+ if (board(dev)->has_8255) {
+ if (board(dev)->layout == LAYOUT_4020) {
+ dio_8255_iobase =
+ priv(dev)->main_iobase + I8255_4020_REG;
+ subdev_8255_init(dev, s, dio_callback_4020,
+ (unsigned long)dio_8255_iobase);
+ } else {
+ dio_8255_iobase =
+ priv(dev)->dio_counter_iobase + DIO_8255_OFFSET;
+ subdev_8255_init(dev, s, dio_callback,
+ (unsigned long)dio_8255_iobase);
+ }
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ // 8 channel dio for 60xx
+ s = dev->subdevices + 5;
+ if (board(dev)->layout == LAYOUT_60XX) {
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_config = dio_60xx_config_insn;
+ s->insn_bits = dio_60xx_wbits;
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ // caldac
+ s = dev->subdevices + 6;
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 8;
+ if (board(dev)->layout == LAYOUT_4020)
+ s->maxdata = 0xfff;
+ else
+ s->maxdata = 0xff;
+ s->insn_read = calib_read_insn;
+ s->insn_write = calib_write_insn;
+ for (i = 0; i < s->n_chan; i++)
+ caldac_write(dev, i, s->maxdata / 2);
+
+ // 2 channel ad8402 potentiometer
+ s = dev->subdevices + 7;
+ if (board(dev)->layout == LAYOUT_64XX) {
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 2;
+ s->insn_read = ad8402_read_insn;
+ s->insn_write = ad8402_write_insn;
+ s->maxdata = 0xff;
+ for (i = 0; i < s->n_chan; i++)
+ ad8402_write(dev, i, s->maxdata / 2);
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ //serial EEPROM, if present
+ s = dev->subdevices + 8;
+ if (readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) {
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+ s->n_chan = 128;
+ s->maxdata = 0xffff;
+ s->insn_read = eeprom_read_insn;
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ // user counter subd XXX
+ s = dev->subdevices + 9;
+ s->type = COMEDI_SUBD_UNUSED;
+
+ return 0;
+}
+
+static void disable_plx_interrupts(struct comedi_device * dev)
+{
+ priv(dev)->plx_intcsr_bits = 0;
+ writel(priv(dev)->plx_intcsr_bits,
+ priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+}
+
+static void init_stc_registers(struct comedi_device * dev)
+{
+ uint16_t bits;
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+ // bit should be set for 6025, although docs say boards with <= 16 chans should be cleared XXX
+ if (1)
+ priv(dev)->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT;
+ writew(priv(dev)->adc_control1_bits,
+ priv(dev)->main_iobase + ADC_CONTROL1_REG);
+
+ // 6402/16 manual says this register must be initialized to 0xff?
+ writew(0xff, priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
+
+ bits = SLOW_DAC_BIT | DMA_CH_SELECT_BIT;
+ if (board(dev)->layout == LAYOUT_4020)
+ bits |= INTERNAL_CLOCK_4020_BITS;
+ priv(dev)->hw_config_bits |= bits;
+ writew(priv(dev)->hw_config_bits,
+ priv(dev)->main_iobase + HW_CONFIG_REG);
+
+ writew(0, priv(dev)->main_iobase + DAQ_SYNC_REG);
+ writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // set fifos to maximum size
+ priv(dev)->fifo_size_bits |= DAC_FIFO_BITS;
+ set_ai_fifo_segment_length(dev,
+ board(dev)->ai_fifo->max_segment_length);
+
+ priv(dev)->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT;
+ priv(dev)->intr_enable_bits = /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */
+ EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT;
+ writew(priv(dev)->intr_enable_bits,
+ priv(dev)->main_iobase + INTR_ENABLE_REG);
+
+ disable_ai_pacing(dev);
+};
+
+int alloc_and_init_dma_members(struct comedi_device * dev)
+{
+ int i;
+
+ // alocate pci dma buffers
+ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
+ priv(dev)->ai_buffer[i] =
+ pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE,
+ &priv(dev)->ai_buffer_bus_addr[i]);
+ if (priv(dev)->ai_buffer[i] == NULL) {
+ return -ENOMEM;
+ }
+ }
+ for (i = 0; i < AO_DMA_RING_COUNT; i++) {
+ if (ao_cmd_is_supported(board(dev))) {
+ priv(dev)->ao_buffer[i] =
+ pci_alloc_consistent(priv(dev)->hw_dev,
+ DMA_BUFFER_SIZE,
+ &priv(dev)->ao_buffer_bus_addr[i]);
+ if (priv(dev)->ao_buffer[i] == NULL) {
+ return -ENOMEM;
+ }
+ }
+ }
+ // allocate dma descriptors
+ priv(dev)->ai_dma_desc =
+ pci_alloc_consistent(priv(dev)->hw_dev,
+ sizeof(struct plx_dma_desc) * ai_dma_ring_count(board(dev)),
+ &priv(dev)->ai_dma_desc_bus_addr);
+ if (priv(dev)->ai_dma_desc == NULL) {
+ return -ENOMEM;
+ }
+ DEBUG_PRINT("ai dma descriptors start at bus addr 0x%x\n",
+ priv(dev)->ai_dma_desc_bus_addr);
+ if (ao_cmd_is_supported(board(dev))) {
+ priv(dev)->ao_dma_desc =
+ pci_alloc_consistent(priv(dev)->hw_dev,
+ sizeof(struct plx_dma_desc) * AO_DMA_RING_COUNT,
+ &priv(dev)->ao_dma_desc_bus_addr);
+ if (priv(dev)->ao_dma_desc == NULL) {
+ return -ENOMEM;
+ }
+ DEBUG_PRINT("ao dma descriptors start at bus addr 0x%x\n",
+ priv(dev)->ao_dma_desc_bus_addr);
+ }
+ // initialize dma descriptors
+ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
+ priv(dev)->ai_dma_desc[i].pci_start_addr =
+ cpu_to_le32(priv(dev)->ai_buffer_bus_addr[i]);
+ if (board(dev)->layout == LAYOUT_4020)
+ priv(dev)->ai_dma_desc[i].local_start_addr =
+ cpu_to_le32(priv(dev)->local1_iobase +
+ ADC_FIFO_REG);
+ else
+ priv(dev)->ai_dma_desc[i].local_start_addr =
+ cpu_to_le32(priv(dev)->local0_iobase +
+ ADC_FIFO_REG);
+ priv(dev)->ai_dma_desc[i].transfer_size = cpu_to_le32(0);
+ priv(dev)->ai_dma_desc[i].next =
+ cpu_to_le32((priv(dev)->ai_dma_desc_bus_addr + ((i +
+ 1) %
+ ai_dma_ring_count(board(dev))) *
+ sizeof(priv(dev)->
+ ai_dma_desc[0])) | PLX_DESC_IN_PCI_BIT |
+ PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI);
+ }
+ if (ao_cmd_is_supported(board(dev))) {
+ for (i = 0; i < AO_DMA_RING_COUNT; i++) {
+ priv(dev)->ao_dma_desc[i].pci_start_addr =
+ cpu_to_le32(priv(dev)->ao_buffer_bus_addr[i]);
+ priv(dev)->ao_dma_desc[i].local_start_addr =
+ cpu_to_le32(priv(dev)->local0_iobase +
+ DAC_FIFO_REG);
+ priv(dev)->ao_dma_desc[i].transfer_size =
+ cpu_to_le32(0);
+ priv(dev)->ao_dma_desc[i].next =
+ cpu_to_le32((priv(dev)->ao_dma_desc_bus_addr +
+ ((i + 1) % (AO_DMA_RING_COUNT)) *
+ sizeof(priv(dev)->
+ ao_dma_desc[0])) |
+ PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT);
+ }
+ }
+ return 0;
+}
+
+static inline void warn_external_queue(struct comedi_device * dev)
+{
+ comedi_error(dev,
+ "AO command and AI external channel queue cannot be used simultaneously.");
+ comedi_error(dev,
+ "Use internal AI channel queue (channels must be consecutive and use same range/aref)");
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.
+ */
+static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
+{
+ struct pci_dev *pcidev;
+ int index;
+ uint32_t local_range, local_decode;
+ int retval;
+
+ printk("comedi%d: cb_pcidas64\n", dev->minor);
+
+/*
+ * Allocate the private structure area.
+ */
+ if (alloc_private(dev, sizeof(struct pcidas64_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ // is it not a computer boards card?
+ if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
+ continue;
+ // loop through cards supported by this driver
+ for (index = 0; index < num_boards(); index++) {
+ if (pcidas64_boards[index].device_id != pcidev->device)
+ continue;
+ // was a particular bus/slot requested?
+ if (it->options[0] || it->options[1]) {
+ // are we on the wrong bus/slot?
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ priv(dev)->hw_dev = pcidev;
+ dev->board_ptr = pcidas64_boards + index;
+ break;
+ }
+ if (dev->board_ptr)
+ break;
+ }
+
+ if (dev->board_ptr == NULL) {
+ printk("No supported ComputerBoards/MeasurementComputing card found\n");
+ return -EIO;
+ }
+
+ printk("Found %s on bus %i, slot %i\n", board(dev)->name,
+ pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+
+ if (comedi_pci_enable(pcidev, driver_cb_pcidas.driver_name)) {
+ printk(KERN_WARNING
+ " failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+ pci_set_master(pcidev);
+
+ //Initialize dev->board_name
+ dev->board_name = board(dev)->name;
+
+ priv(dev)->plx9080_phys_iobase =
+ pci_resource_start(pcidev, PLX9080_BADDRINDEX);
+ priv(dev)->main_phys_iobase =
+ pci_resource_start(pcidev, MAIN_BADDRINDEX);
+ priv(dev)->dio_counter_phys_iobase =
+ pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX);
+
+ // remap, won't work with 2.0 kernels but who cares
+ priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase,
+ pci_resource_len(pcidev, PLX9080_BADDRINDEX));
+ priv(dev)->main_iobase = ioremap(priv(dev)->main_phys_iobase,
+ pci_resource_len(pcidev, MAIN_BADDRINDEX));
+ priv(dev)->dio_counter_iobase =
+ ioremap(priv(dev)->dio_counter_phys_iobase,
+ pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX));
+
+ if (!priv(dev)->plx9080_iobase || !priv(dev)->main_iobase
+ || !priv(dev)->dio_counter_iobase) {
+ printk(" failed to remap io memory\n");
+ return -ENOMEM;
+ }
+
+ DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase);
+ DEBUG_PRINT(" main remapped to 0x%p\n", priv(dev)->main_iobase);
+ DEBUG_PRINT(" diocounter remapped to 0x%p\n",
+ priv(dev)->dio_counter_iobase);
+
+ // figure out what local addresses are
+ local_range =
+ readl(priv(dev)->plx9080_iobase +
+ PLX_LAS0RNG_REG) & LRNG_MEM_MASK;
+ local_decode =
+ readl(priv(dev)->plx9080_iobase +
+ PLX_LAS0MAP_REG) & local_range & LMAP_MEM_MASK;
+ priv(dev)->local0_iobase =
+ ((uint32_t) priv(dev)->
+ main_phys_iobase & ~local_range) | local_decode;
+ local_range =
+ readl(priv(dev)->plx9080_iobase +
+ PLX_LAS1RNG_REG) & LRNG_MEM_MASK;
+ local_decode =
+ readl(priv(dev)->plx9080_iobase +
+ PLX_LAS1MAP_REG) & local_range & LMAP_MEM_MASK;
+ priv(dev)->local1_iobase =
+ ((uint32_t) priv(dev)->
+ dio_counter_phys_iobase & ~local_range) | local_decode;
+
+ DEBUG_PRINT(" local 0 io addr 0x%x\n", priv(dev)->local0_iobase);
+ DEBUG_PRINT(" local 1 io addr 0x%x\n", priv(dev)->local1_iobase);
+
+ retval = alloc_and_init_dma_members(dev);
+ if (retval < 0)
+ return retval;
+
+ priv(dev)->hw_revision =
+ hw_revision(dev, readw(priv(dev)->main_iobase + HW_STATUS_REG));
+ printk(" stc hardware revision %i\n", priv(dev)->hw_revision);
+ init_plx9080(dev);
+ init_stc_registers(dev);
+ // get irq
+ if (comedi_request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
+ "cb_pcidas64", dev)) {
+ printk(" unable to allocate irq %u\n", pcidev->irq);
+ return -EINVAL;
+ }
+ dev->irq = pcidev->irq;
+ printk(" irq %u\n", dev->irq);
+
+ retval = setup_subdevices(dev);
+ if (retval < 0) {
+ return retval;
+ }
+
+ return 0;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int detach(struct comedi_device * dev)
+{
+ unsigned int i;
+
+ printk("comedi%d: cb_pcidas: remove\n", dev->minor);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (priv(dev)) {
+ if (priv(dev)->hw_dev) {
+ if (priv(dev)->plx9080_iobase) {
+ disable_plx_interrupts(dev);
+ iounmap((void *)priv(dev)->plx9080_iobase);
+ }
+ if (priv(dev)->main_iobase)
+ iounmap((void *)priv(dev)->main_iobase);
+ if (priv(dev)->dio_counter_iobase)
+ iounmap((void *)priv(dev)->dio_counter_iobase);
+ // free pci dma buffers
+ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
+ if (priv(dev)->ai_buffer[i])
+ pci_free_consistent(priv(dev)->hw_dev,
+ DMA_BUFFER_SIZE,
+ priv(dev)->ai_buffer[i],
+ priv(dev)->
+ ai_buffer_bus_addr[i]);
+ }
+ for (i = 0; i < AO_DMA_RING_COUNT; i++) {
+ if (priv(dev)->ao_buffer[i])
+ pci_free_consistent(priv(dev)->hw_dev,
+ DMA_BUFFER_SIZE,
+ priv(dev)->ao_buffer[i],
+ priv(dev)->
+ ao_buffer_bus_addr[i]);
+ }
+ // free dma descriptors
+ if (priv(dev)->ai_dma_desc)
+ pci_free_consistent(priv(dev)->hw_dev,
+ sizeof(struct plx_dma_desc) *
+ ai_dma_ring_count(board(dev)),
+ priv(dev)->ai_dma_desc,
+ priv(dev)->ai_dma_desc_bus_addr);
+ if (priv(dev)->ao_dma_desc)
+ pci_free_consistent(priv(dev)->hw_dev,
+ sizeof(struct plx_dma_desc) *
+ AO_DMA_RING_COUNT,
+ priv(dev)->ao_dma_desc,
+ priv(dev)->ao_dma_desc_bus_addr);
+ if (priv(dev)->main_phys_iobase) {
+ comedi_pci_disable(priv(dev)->hw_dev);
+ }
+ pci_dev_put(priv(dev)->hw_dev);
+ }
+ }
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 4);
+
+ return 0;
+}
+
+static int ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits = 0, n, i;
+ unsigned int channel, range, aref;
+ unsigned long flags;
+ static const int timeout = 100;
+
+ DEBUG_PRINT("chanspec 0x%x\n", insn->chanspec);
+ channel = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+ aref = CR_AREF(insn->chanspec);
+
+ // disable card's analog input interrupt sources and pacing
+ // 4020 generates dac done interrupts even though they are disabled
+ disable_ai_pacing(dev);
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ if (insn->chanspec & CR_ALT_FILTER)
+ priv(dev)->adc_control1_bits |= ADC_DITHER_BIT;
+ else
+ priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT;
+ writew(priv(dev)->adc_control1_bits,
+ priv(dev)->main_iobase + ADC_CONTROL1_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ if (board(dev)->layout != LAYOUT_4020) {
+ // use internal queue
+ priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT;
+ writew(priv(dev)->hw_config_bits,
+ priv(dev)->main_iobase + HW_CONFIG_REG);
+
+ // ALT_SOURCE is internal calibration reference
+ if (insn->chanspec & CR_ALT_SOURCE) {
+ unsigned int cal_en_bit;
+
+ DEBUG_PRINT("reading calibration source\n");
+ if (board(dev)->layout == LAYOUT_60XX)
+ cal_en_bit = CAL_EN_60XX_BIT;
+ else
+ cal_en_bit = CAL_EN_64XX_BIT;
+ // select internal reference source to connect to channel 0
+ writew(cal_en_bit | adc_src_bits(priv(dev)->
+ calibration_source),
+ priv(dev)->main_iobase + CALIBRATION_REG);
+ } else {
+ // make sure internal calibration source is turned off
+ writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+ }
+ // load internal queue
+ bits = 0;
+ // set gain
+ bits |= ai_range_bits_6xxx(dev, CR_RANGE(insn->chanspec));
+ // set single-ended / differential
+ bits |= se_diff_bit_6xxx(dev, aref == AREF_DIFF);
+ if (aref == AREF_COMMON)
+ bits |= ADC_COMMON_BIT;
+ bits |= adc_chan_bits(channel);
+ // set stop channel
+ writew(adc_chan_bits(channel),
+ priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG);
+ // set start channel, and rest of settings
+ writew(bits, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
+ } else {
+ uint8_t old_cal_range_bits = priv(dev)->i2c_cal_range_bits;
+
+ priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
+ if (insn->chanspec & CR_ALT_SOURCE) {
+ DEBUG_PRINT("reading calibration source\n");
+ priv(dev)->i2c_cal_range_bits |=
+ adc_src_4020_bits(priv(dev)->
+ calibration_source);
+ } else { //select BNC inputs
+ priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4);
+ }
+ // select range
+ if (range == 0)
+ priv(dev)->i2c_cal_range_bits |= attenuate_bit(channel);
+ else
+ priv(dev)->i2c_cal_range_bits &=
+ ~attenuate_bit(channel);
+ // update calibration/range i2c register only if necessary, as it is very slow
+ if (old_cal_range_bits != priv(dev)->i2c_cal_range_bits) {
+ uint8_t i2c_data = priv(dev)->i2c_cal_range_bits;
+ i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
+ sizeof(i2c_data));
+ }
+
+ /* 4020 manual asks that sample interval register to be set before writing to convert register.
+ * Using somewhat arbitrary setting of 4 master clock ticks = 0.1 usec */
+ writew(0,
+ priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
+ writew(2,
+ priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
+ }
+
+ for (n = 0; n < insn->n; n++) {
+
+ // clear adc buffer (inside loop for 4020 sake)
+ writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG);
+
+ /* trigger conversion, bits sent only matter for 4020 */
+ writew(adc_convert_chan_4020_bits(CR_CHAN(insn->chanspec)),
+ priv(dev)->main_iobase + ADC_CONVERT_REG);
+
+ // wait for data
+ for (i = 0; i < timeout; i++) {
+ bits = readw(priv(dev)->main_iobase + HW_STATUS_REG);
+ DEBUG_PRINT(" pipe bits 0x%x\n", pipe_full_bits(bits));
+ if (board(dev)->layout == LAYOUT_4020) {
+ if (readw(priv(dev)->main_iobase +
+ ADC_WRITE_PNTR_REG))
+ break;
+ } else {
+ if (pipe_full_bits(bits))
+ break;
+ }
+ comedi_udelay(1);
+ }
+ DEBUG_PRINT(" looped %i times waiting for data\n", i);
+ if (i == timeout) {
+ comedi_error(dev, " analog input read insn timed out");
+ rt_printk(" status 0x%x\n", bits);
+ return -ETIME;
+ }
+ if (board(dev)->layout == LAYOUT_4020)
+ data[n] =
+ readl(priv(dev)->dio_counter_iobase +
+ ADC_FIFO_REG) & 0xffff;
+ else
+ data[n] =
+ readw(priv(dev)->main_iobase + PIPE1_READ_REG);
+ }
+
+ return n;
+}
+
+static int ai_config_calibration_source(struct comedi_device * dev, unsigned int * data)
+{
+ unsigned int source = data[1];
+ int num_calibration_sources;
+
+ if (board(dev)->layout == LAYOUT_60XX)
+ num_calibration_sources = 16;
+ else
+ num_calibration_sources = 8;
+ if (source >= num_calibration_sources) {
+ printk("invalid calibration source: %i\n", source);
+ return -EINVAL;
+ }
+
+ DEBUG_PRINT("setting calibration source to %i\n", source);
+ priv(dev)->calibration_source = source;
+
+ return 2;
+}
+
+static int ai_config_block_size(struct comedi_device * dev, unsigned int * data)
+{
+ int fifo_size;
+ const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
+ unsigned int block_size, requested_block_size;
+ int retval;
+
+ requested_block_size = data[1];
+
+ if (requested_block_size) {
+ fifo_size =
+ requested_block_size * fifo->num_segments /
+ bytes_in_sample;
+
+ retval = set_ai_fifo_size(dev, fifo_size);
+ if (retval < 0)
+ return retval;
+
+ }
+
+ block_size = ai_fifo_size(dev) / fifo->num_segments * bytes_in_sample;
+
+ data[1] = block_size;
+
+ return 2;
+}
+
+static int ai_config_master_clock_4020(struct comedi_device * dev, unsigned int * data)
+{
+ unsigned int divisor = data[4];
+ int retval = 0;
+
+ if (divisor < 2) {
+ divisor = 2;
+ retval = -EAGAIN;
+ }
+
+ switch (data[1]) {
+ case COMEDI_EV_SCAN_BEGIN:
+ priv(dev)->ext_clock.divisor = divisor;
+ priv(dev)->ext_clock.chanspec = data[2];
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ data[4] = divisor;
+
+ return retval ? retval : 5;
+}
+
+// XXX could add support for 60xx series
+static int ai_config_master_clock(struct comedi_device * dev, unsigned int * data)
+{
+
+ switch (board(dev)->layout) {
+ case LAYOUT_4020:
+ return ai_config_master_clock_4020(dev, data);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int id = data[0];
+
+ switch (id) {
+ case INSN_CONFIG_ALT_SOURCE:
+ return ai_config_calibration_source(dev, data);
+ break;
+ case INSN_CONFIG_BLOCK_SIZE:
+ return ai_config_block_size(dev, data);
+ break;
+ case INSN_CONFIG_TIMER_1:
+ return ai_config_master_clock(dev, data);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return -EINVAL;
+}
+
+static int ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ unsigned int tmp_arg, tmp_arg2;
+ int i;
+ int aref;
+ unsigned int triggers;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ triggers = TRIG_TIMER;
+ if (board(dev)->layout == LAYOUT_4020)
+ triggers |= TRIG_OTHER;
+ else
+ triggers |= TRIG_FOLLOW;
+ cmd->scan_begin_src &= triggers;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ triggers = TRIG_TIMER;
+ if (board(dev)->layout == LAYOUT_4020)
+ triggers |= TRIG_NOW;
+ else
+ triggers |= TRIG_EXT;
+ cmd->convert_src &= triggers;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ // uniqueness check
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_OTHER &&
+ cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER &&
+ cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT &&
+ cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
+ err++;
+
+ // compatibility check
+ if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT &&
+ cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (board(dev)->layout == LAYOUT_4020) {
+ if (cmd->convert_arg) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ } else {
+ if (cmd->convert_arg < board(dev)->ai_speed) {
+ cmd->convert_arg = board(dev)->ai_speed;
+ err++;
+ }
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ // if scans are timed faster than conversion rate allows
+ if (cmd->convert_arg * cmd->chanlist_len >
+ cmd->scan_begin_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg *
+ cmd->chanlist_len;
+ err++;
+ }
+ }
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_EXT:
+ break;
+ case TRIG_COUNT:
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp_arg = cmd->convert_arg;
+ tmp_arg2 = cmd->scan_begin_arg;
+ check_adc_timing(dev, cmd);
+ if (tmp_arg != cmd->convert_arg)
+ err++;
+ if (tmp_arg2 != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ // make sure user is doesn't change analog reference mid chanlist
+ if (cmd->chanlist) {
+ aref = CR_AREF(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (aref != CR_AREF(cmd->chanlist[i])) {
+ comedi_error(dev,
+ "all elements in chanlist must use the same analog reference");
+ err++;
+ break;
+ }
+ }
+ // check 4020 chanlist
+ if (board(dev)->layout == LAYOUT_4020) {
+ unsigned int first_channel = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) !=
+ first_channel + i) {
+ comedi_error(dev,
+ "chanlist must use consecutive channels");
+ err++;
+ break;
+ }
+ }
+ if (cmd->chanlist_len == 3) {
+ comedi_error(dev,
+ "chanlist cannot be 3 channels long, use 1, 2, or 4 channels");
+ err++;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int use_hw_sample_counter(struct comedi_cmd * cmd)
+{
+// disable for now until I work out a race
+ return 0;
+
+ if (cmd->stop_src == TRIG_COUNT && cmd->stop_arg <= max_counter_value)
+ return 1;
+ else
+ return 0;
+}
+
+static void setup_sample_counters(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+ if (cmd->stop_src == TRIG_COUNT) {
+ // set software count
+ priv(dev)->ai_count = cmd->stop_arg * cmd->chanlist_len;
+ }
+ // load hardware conversion counter
+ if (use_hw_sample_counter(cmd)) {
+ writew(cmd->stop_arg & 0xffff,
+ priv(dev)->main_iobase + ADC_COUNT_LOWER_REG);
+ writew((cmd->stop_arg >> 16) & 0xff,
+ priv(dev)->main_iobase + ADC_COUNT_UPPER_REG);
+ } else {
+ writew(1, priv(dev)->main_iobase + ADC_COUNT_LOWER_REG);
+ }
+}
+
+static inline unsigned int dma_transfer_size(struct comedi_device * dev)
+{
+ unsigned int num_samples;
+
+ num_samples =
+ priv(dev)->ai_fifo_segment_length *
+ board(dev)->ai_fifo->sample_packing_ratio;
+ if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t))
+ num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t);
+
+ return num_samples;
+}
+
+static void disable_ai_pacing(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ disable_ai_interrupts(dev);
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ priv(dev)->adc_control1_bits &= ~ADC_SW_GATE_BIT;
+ writew(priv(dev)->adc_control1_bits,
+ priv(dev)->main_iobase + ADC_CONTROL1_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ /* disable pacing, triggering, etc */
+ writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT,
+ priv(dev)->main_iobase + ADC_CONTROL0_REG);
+}
+
+static void disable_ai_interrupts(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ priv(dev)->intr_enable_bits &=
+ ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT &
+ ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT &
+ ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK;
+ writew(priv(dev)->intr_enable_bits,
+ priv(dev)->main_iobase + INTR_ENABLE_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits);
+}
+
+static void enable_ai_interrupts(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ uint32_t bits;
+ unsigned long flags;
+
+ bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT |
+ EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT;
+ // Use pio transfer and interrupt on end of conversion if TRIG_WAKE_EOS flag is set.
+ if (cmd->flags & TRIG_WAKE_EOS) {
+ // 4020 doesn't support pio transfers except for fifo dregs
+ if (board(dev)->layout != LAYOUT_4020)
+ bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT;
+ }
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ priv(dev)->intr_enable_bits |= bits;
+ writew(priv(dev)->intr_enable_bits,
+ priv(dev)->main_iobase + INTR_ENABLE_REG);
+ DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static uint32_t ai_convert_counter_6xxx(const struct comedi_device * dev,
+ const struct comedi_cmd * cmd)
+{
+ // supposed to load counter with desired divisor minus 3
+ return cmd->convert_arg / TIMER_BASE - 3;
+}
+
+static uint32_t ai_scan_counter_6xxx(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+ uint32_t count;
+ // figure out how long we need to delay at end of scan
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ count = (cmd->scan_begin_arg -
+ (cmd->convert_arg * (cmd->chanlist_len - 1)))
+ / TIMER_BASE;
+ break;
+ case TRIG_FOLLOW:
+ count = cmd->convert_arg / TIMER_BASE;
+ break;
+ default:
+ return 0;
+ break;
+ }
+ return count - 3;
+}
+
+static uint32_t ai_convert_counter_4020(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+ unsigned int divisor;
+
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ divisor = cmd->scan_begin_arg / TIMER_BASE;
+ break;
+ case TRIG_OTHER:
+ divisor = priv(dev)->ext_clock.divisor;
+ break;
+ default: // should never happen
+ comedi_error(dev, "bug! failed to set ai pacing!");
+ divisor = 1000;
+ break;
+ }
+
+ // supposed to load counter with desired divisor minus 2 for 4020
+ return divisor - 2;
+}
+
+static void select_master_clock_4020(struct comedi_device * dev,
+ const struct comedi_cmd * cmd)
+{
+ // select internal/external master clock
+ priv(dev)->hw_config_bits &= ~MASTER_CLOCK_4020_MASK;
+ if (cmd->scan_begin_src == TRIG_OTHER) {
+ int chanspec = priv(dev)->ext_clock.chanspec;
+
+ if (CR_CHAN(chanspec))
+ priv(dev)->hw_config_bits |= BNC_CLOCK_4020_BITS;
+ else
+ priv(dev)->hw_config_bits |= EXT_CLOCK_4020_BITS;
+ } else {
+ priv(dev)->hw_config_bits |= INTERNAL_CLOCK_4020_BITS;
+ }
+ writew(priv(dev)->hw_config_bits,
+ priv(dev)->main_iobase + HW_CONFIG_REG);
+}
+
+static void select_master_clock(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ switch (board(dev)->layout) {
+ case LAYOUT_4020:
+ select_master_clock_4020(dev, cmd);
+ break;
+ default:
+ break;
+ }
+}
+
+static inline void dma_start_sync(struct comedi_device * dev, unsigned int channel)
+{
+ unsigned long flags;
+
+ // spinlock for plx dma control/status reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ if (channel)
+ writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT |
+ PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ else
+ writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT |
+ PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static void set_ai_pacing(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+ uint32_t convert_counter = 0, scan_counter = 0;
+
+ check_adc_timing(dev, cmd);
+
+ select_master_clock(dev, cmd);
+
+ if (board(dev)->layout == LAYOUT_4020) {
+ convert_counter = ai_convert_counter_4020(dev, cmd);
+ } else {
+ convert_counter = ai_convert_counter_6xxx(dev, cmd);
+ scan_counter = ai_scan_counter_6xxx(dev, cmd);
+ }
+
+ // load lower 16 bits of convert interval
+ writew(convert_counter & 0xffff,
+ priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
+ DEBUG_PRINT("convert counter 0x%x\n", convert_counter);
+ // load upper 8 bits of convert interval
+ writew((convert_counter >> 16) & 0xff,
+ priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
+ // load lower 16 bits of scan delay
+ writew(scan_counter & 0xffff,
+ priv(dev)->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG);
+ // load upper 8 bits of scan delay
+ writew((scan_counter >> 16) & 0xff,
+ priv(dev)->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG);
+ DEBUG_PRINT("scan counter 0x%x\n", scan_counter);
+}
+
+static int use_internal_queue_6xxx(const struct comedi_cmd * cmd)
+{
+ int i;
+ for (i = 0; i + 1 < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i + 1]) !=
+ CR_CHAN(cmd->chanlist[i]) + 1)
+ return 0;
+ if (CR_RANGE(cmd->chanlist[i + 1]) !=
+ CR_RANGE(cmd->chanlist[i]))
+ return 0;
+ if (CR_AREF(cmd->chanlist[i + 1]) != CR_AREF(cmd->chanlist[i]))
+ return 0;
+ }
+ return 1;
+}
+
+static int setup_channel_queue(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ unsigned short bits;
+ int i;
+
+ if (board(dev)->layout != LAYOUT_4020) {
+ if (use_internal_queue_6xxx(cmd)) {
+ priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT;
+ writew(priv(dev)->hw_config_bits,
+ priv(dev)->main_iobase + HW_CONFIG_REG);
+ bits = 0;
+ // set channel
+ bits |= adc_chan_bits(CR_CHAN(cmd->chanlist[0]));
+ // set gain
+ bits |= ai_range_bits_6xxx(dev,
+ CR_RANGE(cmd->chanlist[0]));
+ // set single-ended / differential
+ bits |= se_diff_bit_6xxx(dev,
+ CR_AREF(cmd->chanlist[0]) == AREF_DIFF);
+ if (CR_AREF(cmd->chanlist[0]) == AREF_COMMON)
+ bits |= ADC_COMMON_BIT;
+ // set stop channel
+ writew(adc_chan_bits(CR_CHAN(cmd->chanlist[cmd->
+ chanlist_len - 1])),
+ priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG);
+ // set start channel, and rest of settings
+ writew(bits,
+ priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
+ } else {
+ // use external queue
+ if (dev->write_subdev && dev->write_subdev->busy) {
+ warn_external_queue(dev);
+ return -EBUSY;
+ }
+ priv(dev)->hw_config_bits |= EXT_QUEUE_BIT;
+ writew(priv(dev)->hw_config_bits,
+ priv(dev)->main_iobase + HW_CONFIG_REG);
+ // clear DAC buffer to prevent weird interactions
+ writew(0,
+ priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG);
+ // clear queue pointer
+ writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
+ // load external queue
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ bits = 0;
+ // set channel
+ bits |= adc_chan_bits(CR_CHAN(cmd->
+ chanlist[i]));
+ // set gain
+ bits |= ai_range_bits_6xxx(dev,
+ CR_RANGE(cmd->chanlist[i]));
+ // set single-ended / differential
+ bits |= se_diff_bit_6xxx(dev,
+ CR_AREF(cmd->chanlist[i]) == AREF_DIFF);
+ if (CR_AREF(cmd->chanlist[i]) == AREF_COMMON)
+ bits |= ADC_COMMON_BIT;
+ // mark end of queue
+ if (i == cmd->chanlist_len - 1)
+ bits |= QUEUE_EOSCAN_BIT |
+ QUEUE_EOSEQ_BIT;
+ writew(bits,
+ priv(dev)->main_iobase +
+ ADC_QUEUE_FIFO_REG);
+ DEBUG_PRINT
+ ("wrote 0x%x to external channel queue\n",
+ bits);
+ }
+ /* doing a queue clear is not specified in board docs,
+ * but required for reliable operation */
+ writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
+ // prime queue holding register
+ writew(0, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
+ }
+ } else {
+ unsigned short old_cal_range_bits =
+ priv(dev)->i2c_cal_range_bits;
+
+ priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
+ //select BNC inputs
+ priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4);
+ // select ranges
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ unsigned int channel = CR_CHAN(cmd->chanlist[i]);
+ unsigned int range = CR_RANGE(cmd->chanlist[i]);
+
+ if (range == 0)
+ priv(dev)->i2c_cal_range_bits |=
+ attenuate_bit(channel);
+ else
+ priv(dev)->i2c_cal_range_bits &=
+ ~attenuate_bit(channel);
+ }
+ // update calibration/range i2c register only if necessary, as it is very slow
+ if (old_cal_range_bits != priv(dev)->i2c_cal_range_bits) {
+ uint8_t i2c_data = priv(dev)->i2c_cal_range_bits;
+ i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
+ sizeof(i2c_data));
+ }
+ }
+ return 0;
+}
+
+static inline void load_first_dma_descriptor(struct comedi_device * dev,
+ unsigned int dma_channel, unsigned int descriptor_bits)
+{
+ /* The transfer size, pci address, and local address registers
+ * are supposedly unused during chained dma,
+ * but I have found that left over values from last operation
+ * occasionally cause problems with transfer of first dma
+ * block. Initializing them to zero seems to fix the problem. */
+ if (dma_channel) {
+ writel(0,
+ priv(dev)->plx9080_iobase + PLX_DMA1_TRANSFER_SIZE_REG);
+ writel(0, priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG);
+ writel(0,
+ priv(dev)->plx9080_iobase + PLX_DMA1_LOCAL_ADDRESS_REG);
+ writel(descriptor_bits,
+ priv(dev)->plx9080_iobase + PLX_DMA1_DESCRIPTOR_REG);
+ } else {
+ writel(0,
+ priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
+ writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
+ writel(0,
+ priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
+ writel(descriptor_bits,
+ priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
+ }
+}
+
+static int ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ uint32_t bits;
+ unsigned int i;
+ unsigned long flags;
+ int retval;
+
+ disable_ai_pacing(dev);
+ abort_dma(dev, 1);
+
+ retval = setup_channel_queue(dev, cmd);
+ if (retval < 0)
+ return retval;
+
+ // make sure internal calibration source is turned off
+ writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+
+ set_ai_pacing(dev, cmd);
+
+ setup_sample_counters(dev, cmd);
+
+ enable_ai_interrupts(dev, cmd);
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ /* set mode, allow conversions through software gate */
+ priv(dev)->adc_control1_bits |= ADC_SW_GATE_BIT;
+ priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT;
+ if (board(dev)->layout != LAYOUT_4020) {
+ priv(dev)->adc_control1_bits &= ~ADC_MODE_MASK;
+ if (cmd->convert_src == TRIG_EXT)
+ priv(dev)->adc_control1_bits |= adc_mode_bits(13); // good old mode 13
+ else
+ priv(dev)->adc_control1_bits |= adc_mode_bits(8); // mode 8. What else could you need?
+ } else {
+ priv(dev)->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK;
+ if (cmd->chanlist_len == 4)
+ priv(dev)->adc_control1_bits |= FOUR_CHANNEL_4020_BITS;
+ else if (cmd->chanlist_len == 2)
+ priv(dev)->adc_control1_bits |= TWO_CHANNEL_4020_BITS;
+ priv(dev)->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK;
+ priv(dev)->adc_control1_bits |=
+ adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0]));
+ priv(dev)->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK;
+ priv(dev)->adc_control1_bits |=
+ adc_hi_chan_4020_bits(CR_CHAN(cmd->chanlist[cmd->
+ chanlist_len - 1]));
+ }
+ writew(priv(dev)->adc_control1_bits,
+ priv(dev)->main_iobase + ADC_CONTROL1_REG);
+ DEBUG_PRINT("control1 bits 0x%x\n", priv(dev)->adc_control1_bits);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // clear adc buffer
+ writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG);
+
+ if ((cmd->flags & TRIG_WAKE_EOS) == 0 ||
+ board(dev)->layout == LAYOUT_4020) {
+ priv(dev)->ai_dma_index = 0;
+
+ // set dma transfer size
+ for (i = 0; i < ai_dma_ring_count(board(dev)); i++)
+ priv(dev)->ai_dma_desc[i].transfer_size =
+ cpu_to_le32(dma_transfer_size(dev) *
+ sizeof(uint16_t));
+
+ // give location of first dma descriptor
+ load_first_dma_descriptor(dev, 1,
+ priv(dev)->
+ ai_dma_desc_bus_addr | PLX_DESC_IN_PCI_BIT |
+ PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI);
+
+ dma_start_sync(dev, 1);
+ }
+
+ if (board(dev)->layout == LAYOUT_4020) {
+ /* set source for external triggers */
+ bits = 0;
+ if (cmd->start_src == TRIG_EXT && CR_CHAN(cmd->start_arg))
+ bits |= EXT_START_TRIG_BNC_BIT;
+ if (cmd->stop_src == TRIG_EXT && CR_CHAN(cmd->stop_arg))
+ bits |= EXT_STOP_TRIG_BNC_BIT;
+ writew(bits, priv(dev)->main_iobase + DAQ_ATRIG_LOW_4020_REG);
+ }
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+ /* enable pacing, triggering, etc */
+ bits = ADC_ENABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT;
+ if (cmd->flags & TRIG_WAKE_EOS)
+ bits |= ADC_DMA_DISABLE_BIT;
+ // set start trigger
+ if (cmd->start_src == TRIG_EXT) {
+ bits |= ADC_START_TRIG_EXT_BITS;
+ if (cmd->start_arg & CR_INVERT)
+ bits |= ADC_START_TRIG_FALLING_BIT;
+ } else if (cmd->start_src == TRIG_NOW)
+ bits |= ADC_START_TRIG_SOFT_BITS;
+ if (use_hw_sample_counter(cmd))
+ bits |= ADC_SAMPLE_COUNTER_EN_BIT;
+ writew(bits, priv(dev)->main_iobase + ADC_CONTROL0_REG);
+ DEBUG_PRINT("control0 bits 0x%x\n", bits);
+
+ priv(dev)->ai_cmd_running = 1;
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // start aquisition
+ if (cmd->start_src == TRIG_NOW) {
+ writew(0, priv(dev)->main_iobase + ADC_START_REG);
+ DEBUG_PRINT("soft trig\n");
+ }
+
+ return 0;
+}
+
+// read num_samples from 16 bit wide ai fifo
+static void pio_drain_ai_fifo_16(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int i;
+ uint16_t prepost_bits;
+ int read_segment, read_index, write_segment, write_index;
+ int num_samples;
+
+ do {
+ // get least significant 15 bits
+ read_index =
+ readw(priv(dev)->main_iobase +
+ ADC_READ_PNTR_REG) & 0x7fff;
+ write_index =
+ readw(priv(dev)->main_iobase +
+ ADC_WRITE_PNTR_REG) & 0x7fff;
+ /* Get most significant bits (grey code). Different boards use different code
+ * so use a scheme that doesn't depend on encoding. This read must
+ * occur after reading least significant 15 bits to avoid race
+ * with fifo switching to next segment. */
+ prepost_bits = readw(priv(dev)->main_iobase + PREPOST_REG);
+
+ /* if read and write pointers are not on the same fifo segment, read to the
+ * end of the read segment */
+ read_segment = adc_upper_read_ptr_code(prepost_bits);
+ write_segment = adc_upper_write_ptr_code(prepost_bits);
+
+ DEBUG_PRINT(" rd seg %i, wrt seg %i, rd idx %i, wrt idx %i\n",
+ read_segment, write_segment, read_index, write_index);
+
+ if (read_segment != write_segment)
+ num_samples =
+ priv(dev)->ai_fifo_segment_length - read_index;
+ else
+ num_samples = write_index - read_index;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (priv(dev)->ai_count == 0)
+ break;
+ if (num_samples > priv(dev)->ai_count) {
+ num_samples = priv(dev)->ai_count;
+ }
+ priv(dev)->ai_count -= num_samples;
+ }
+
+ if (num_samples < 0) {
+ rt_printk(" cb_pcidas64: bug! num_samples < 0\n");
+ break;
+ }
+
+ DEBUG_PRINT(" read %i samples from fifo\n", num_samples);
+
+ for (i = 0; i < num_samples; i++) {
+ cfc_write_to_buffer(s,
+ readw(priv(dev)->main_iobase + ADC_FIFO_REG));
+ }
+
+ } while (read_segment != write_segment);
+}
+
+/* Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of pointers.
+ * The pci-4020 hardware only supports
+ * dma transfers (it only supports the use of pio for draining the last remaining
+ * points from the fifo when a data aquisition operation has completed).
+ */
+static void pio_drain_ai_fifo_32(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int i;
+ unsigned int max_transfer = 100000;
+ uint32_t fifo_data;
+ int write_code =
+ readw(priv(dev)->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
+ int read_code =
+ readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (max_transfer > priv(dev)->ai_count) {
+ max_transfer = priv(dev)->ai_count;
+ }
+ }
+ for (i = 0; read_code != write_code && i < max_transfer;) {
+ fifo_data = readl(priv(dev)->dio_counter_iobase + ADC_FIFO_REG);
+ cfc_write_to_buffer(s, fifo_data & 0xffff);
+ i++;
+ if (i < max_transfer) {
+ cfc_write_to_buffer(s, (fifo_data >> 16) & 0xffff);
+ i++;
+ }
+ read_code =
+ readw(priv(dev)->main_iobase +
+ ADC_READ_PNTR_REG) & 0x7fff;
+ }
+ priv(dev)->ai_count -= i;
+}
+
+// empty fifo
+static void pio_drain_ai_fifo(struct comedi_device * dev)
+{
+ if (board(dev)->layout == LAYOUT_4020) {
+ pio_drain_ai_fifo_32(dev);
+ } else
+ pio_drain_ai_fifo_16(dev);
+}
+
+static void drain_dma_buffers(struct comedi_device * dev, unsigned int channel)
+{
+ struct comedi_async *async = dev->read_subdev->async;
+ uint32_t next_transfer_addr;
+ int j;
+ int num_samples = 0;
+ void *pci_addr_reg;
+
+ if (channel)
+ pci_addr_reg =
+ priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
+ else
+ pci_addr_reg =
+ priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
+
+ // loop until we have read all the full buffers
+ for (j = 0, next_transfer_addr = readl(pci_addr_reg);
+ (next_transfer_addr <
+ priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index]
+ || next_transfer_addr >=
+ priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index] +
+ DMA_BUFFER_SIZE) && j < ai_dma_ring_count(board(dev));
+ j++) {
+ // transfer data from dma buffer to comedi buffer
+ num_samples = dma_transfer_size(dev);
+ if (async->cmd.stop_src == TRIG_COUNT) {
+ if (num_samples > priv(dev)->ai_count)
+ num_samples = priv(dev)->ai_count;
+ priv(dev)->ai_count -= num_samples;
+ }
+ cfc_write_array_to_buffer(dev->read_subdev,
+ priv(dev)->ai_buffer[priv(dev)->ai_dma_index],
+ num_samples * sizeof(uint16_t));
+ priv(dev)->ai_dma_index =
+ (priv(dev)->ai_dma_index +
+ 1) % ai_dma_ring_count(board(dev));
+
+ DEBUG_PRINT("next buffer addr 0x%lx\n",
+ (unsigned long)priv(dev)->ai_buffer_bus_addr[priv(dev)->
+ ai_dma_index]);
+ DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
+ }
+ /* XXX check for dma ring buffer overrun (use end-of-chain bit to mark last
+ * unused buffer) */
+}
+
+void handle_ai_interrupt(struct comedi_device * dev, unsigned short status,
+ unsigned int plx_status)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ uint8_t dma1_status;
+ unsigned long flags;
+
+ // check for fifo overrun
+ if (status & ADC_OVERRUN_BIT) {
+ comedi_error(dev, "fifo overrun");
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ }
+ // spin lock makes sure noone else changes plx dma control reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ if (plx_status & ICS_DMA1_A) { // dma chan 1 interrupt
+ writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
+
+ if (dma1_status & PLX_DMA_EN_BIT) {
+ drain_dma_buffers(dev, 1);
+ }
+ DEBUG_PRINT(" cleared dma ch1 interrupt\n");
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ if (status & ADC_DONE_BIT)
+ DEBUG_PRINT("adc done interrupt\n");
+
+ // drain fifo with pio
+ if ((status & ADC_DONE_BIT) ||
+ ((cmd->flags & TRIG_WAKE_EOS) &&
+ (status & ADC_INTR_PENDING_BIT) &&
+ (board(dev)->layout != LAYOUT_4020))) {
+ DEBUG_PRINT("pio fifo drain\n");
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ if (priv(dev)->ai_cmd_running) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ pio_drain_ai_fifo(dev);
+ } else
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ }
+ // if we are have all the data, then quit
+ if ((cmd->stop_src == TRIG_COUNT && priv(dev)->ai_count <= 0) ||
+ (cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) {
+ async->events |= COMEDI_CB_EOA;
+ }
+
+ cfc_handle_events(dev, s);
+}
+
+static inline unsigned int prev_ao_dma_index(struct comedi_device * dev)
+{
+ unsigned int buffer_index;
+
+ if (priv(dev)->ao_dma_index == 0)
+ buffer_index = AO_DMA_RING_COUNT - 1;
+ else
+ buffer_index = priv(dev)->ao_dma_index - 1;
+ return buffer_index;
+}
+
+static int last_ao_dma_load_completed(struct comedi_device * dev)
+{
+ unsigned int buffer_index;
+ unsigned int transfer_address;
+ unsigned short dma_status;
+
+ buffer_index = prev_ao_dma_index(dev);
+ dma_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ if ((dma_status & PLX_DMA_DONE_BIT) == 0)
+ return 0;
+
+ transfer_address =
+ readl(priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
+ if (transfer_address != priv(dev)->ao_buffer_bus_addr[buffer_index])
+ return 0;
+
+ return 1;
+}
+
+static int ao_stopped_by_error(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ if (cmd->stop_src == TRIG_NONE)
+ return 1;
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (priv(dev)->ao_count)
+ return 1;
+ if (last_ao_dma_load_completed(dev) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+static inline int ao_dma_needs_restart(struct comedi_device * dev,
+ unsigned short dma_status)
+{
+ if ((dma_status & PLX_DMA_DONE_BIT) == 0 ||
+ (dma_status & PLX_DMA_EN_BIT) == 0)
+ return 0;
+ if (last_ao_dma_load_completed(dev))
+ return 0;
+
+ return 1;
+}
+
+static void restart_ao_dma(struct comedi_device * dev)
+{
+ unsigned int dma_desc_bits;
+
+ dma_desc_bits =
+ readl(priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
+ dma_desc_bits &= ~PLX_END_OF_CHAIN_BIT;
+ DEBUG_PRINT("restarting ao dma, descriptor reg 0x%x\n", dma_desc_bits);
+ load_first_dma_descriptor(dev, 0, dma_desc_bits);
+
+ dma_start_sync(dev, 0);
+}
+
+static void handle_ao_interrupt(struct comedi_device * dev, unsigned short status,
+ unsigned int plx_status)
+{
+ struct comedi_subdevice *s = dev->write_subdev;
+ struct comedi_async *async;
+ struct comedi_cmd *cmd;
+ uint8_t dma0_status;
+ unsigned long flags;
+
+ /* board might not support ao, in which case write_subdev is NULL */
+ if (s == NULL)
+ return;
+ async = s->async;
+ cmd = &async->cmd;
+
+ // spin lock makes sure noone else changes plx dma control reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ if (plx_status & ICS_DMA0_A) { // dma chan 0 interrupt
+ if ((dma0_status & PLX_DMA_EN_BIT)
+ && !(dma0_status & PLX_DMA_DONE_BIT))
+ writeb(PLX_DMA_EN_BIT | PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ else
+ writeb(PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
+ if (dma0_status & PLX_DMA_EN_BIT) {
+ load_ao_dma(dev, cmd);
+ /* try to recover from dma end-of-chain event */
+ if (ao_dma_needs_restart(dev, dma0_status))
+ restart_ao_dma(dev);
+ }
+ DEBUG_PRINT(" cleared dma ch0 interrupt\n");
+ } else
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ if ((status & DAC_DONE_BIT)) {
+ async->events |= COMEDI_CB_EOA;
+ if (ao_stopped_by_error(dev, cmd))
+ async->events |= COMEDI_CB_ERROR;
+ DEBUG_PRINT("plx dma0 desc reg 0x%x\n",
+ readl(priv(dev)->plx9080_iobase +
+ PLX_DMA0_DESCRIPTOR_REG));
+ DEBUG_PRINT("plx dma0 address reg 0x%x\n",
+ readl(priv(dev)->plx9080_iobase +
+ PLX_DMA0_PCI_ADDRESS_REG));
+ }
+ cfc_handle_events(dev, s);
+}
+
+static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ unsigned short status;
+ uint32_t plx_status;
+ uint32_t plx_bits;
+
+ plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+ status = readw(priv(dev)->main_iobase + HW_STATUS_REG);
+
+ DEBUG_PRINT("cb_pcidas64: hw status 0x%x ", status);
+ DEBUG_PRINT("plx status 0x%x\n", plx_status);
+
+ /* an interrupt before all the postconfig stuff gets done could
+ * cause a NULL dereference if we continue through the
+ * interrupt handler */
+ if (dev->attached == 0) {
+ DEBUG_PRINT("cb_pcidas64: premature interrupt, ignoring",
+ status);
+ return IRQ_HANDLED;
+ }
+ handle_ai_interrupt(dev, status, plx_status);
+ handle_ao_interrupt(dev, status, plx_status);
+
+ // clear possible plx9080 interrupt sources
+ if (plx_status & ICS_LDIA) { // clear local doorbell interrupt
+ plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+ writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+ DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits);
+ }
+
+ DEBUG_PRINT("exiting handler\n");
+
+ return IRQ_HANDLED;
+}
+
+void abort_dma(struct comedi_device * dev, unsigned int channel)
+{
+ unsigned long flags;
+
+ // spinlock for plx dma control/status reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+ plx9080_abort_dma(priv(dev)->plx9080_iobase, channel);
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static int ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ if (priv(dev)->ai_cmd_running == 0) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ return 0;
+ }
+ priv(dev)->ai_cmd_running = 0;
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ disable_ai_pacing(dev);
+
+ abort_dma(dev, 1);
+
+ DEBUG_PRINT("ai canceled\n");
+ return 0;
+}
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int range = CR_RANGE(insn->chanspec);
+
+ // do some initializing
+ writew(0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+
+ // set range
+ set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, chan, range);
+ writew(priv(dev)->dac_control1_bits,
+ priv(dev)->main_iobase + DAC_CONTROL1_REG);
+
+ // write to channel
+ if (board(dev)->layout == LAYOUT_4020) {
+ writew(data[0] & 0xff,
+ priv(dev)->main_iobase + dac_lsb_4020_reg(chan));
+ writew((data[0] >> 8) & 0xf,
+ priv(dev)->main_iobase + dac_msb_4020_reg(chan));
+ } else {
+ writew(data[0], priv(dev)->main_iobase + dac_convert_reg(chan));
+ }
+
+ // remember output value
+ priv(dev)->ao_value[chan] = data[0];
+
+ return 1;
+}
+
+static int ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = priv(dev)->ao_value[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static void set_dac_control0_reg(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ unsigned int bits = DAC_ENABLE_BIT | WAVEFORM_GATE_LEVEL_BIT |
+ WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT;
+
+ if (cmd->start_src == TRIG_EXT) {
+ bits |= WAVEFORM_TRIG_EXT_BITS;
+ if (cmd->start_arg & CR_INVERT)
+ bits |= WAVEFORM_TRIG_FALLING_BIT;
+ } else {
+ bits |= WAVEFORM_TRIG_SOFT_BITS;
+ }
+ if (cmd->scan_begin_src == TRIG_EXT) {
+ bits |= DAC_EXT_UPDATE_ENABLE_BIT;
+ if (cmd->scan_begin_arg & CR_INVERT)
+ bits |= DAC_EXT_UPDATE_FALLING_BIT;
+ }
+ writew(bits, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+}
+
+static void set_dac_control1_reg(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ int i;
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ int channel, range;
+
+ channel = CR_CHAN(cmd->chanlist[i]);
+ range = CR_RANGE(cmd->chanlist[i]);
+ set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, channel,
+ range);
+ }
+ priv(dev)->dac_control1_bits |= DAC_SW_GATE_BIT;
+ writew(priv(dev)->dac_control1_bits,
+ priv(dev)->main_iobase + DAC_CONTROL1_REG);
+}
+
+static void set_dac_select_reg(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ uint16_t bits;
+ unsigned int first_channel, last_channel;
+
+ first_channel = CR_CHAN(cmd->chanlist[0]);
+ last_channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
+ if (last_channel < first_channel)
+ comedi_error(dev, "bug! last ao channel < first ao channel");
+
+ bits = (first_channel & 0x7) | (last_channel & 0x7) << 3;
+
+ writew(bits, priv(dev)->main_iobase + DAC_SELECT_REG);
+}
+
+static void set_dac_interval_regs(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ unsigned int divisor;
+
+ if (cmd->scan_begin_src != TRIG_TIMER)
+ return;
+
+ divisor = get_ao_divisor(cmd->scan_begin_arg, cmd->flags);
+ if (divisor > max_counter_value) {
+ comedi_error(dev, "bug! ao divisor too big");
+ divisor = max_counter_value;
+ }
+ writew(divisor & 0xffff,
+ priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG);
+ writew((divisor >> 16) & 0xff,
+ priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG);
+}
+
+static unsigned int load_ao_dma_buffer(struct comedi_device * dev,
+ const struct comedi_cmd * cmd)
+{
+ unsigned int num_bytes, buffer_index, prev_buffer_index;
+ unsigned int next_bits;
+
+ buffer_index = priv(dev)->ao_dma_index;
+ prev_buffer_index = prev_ao_dma_index(dev);
+
+ DEBUG_PRINT("attempting to load ao buffer %i (0x%x)\n", buffer_index,
+ priv(dev)->ao_buffer_bus_addr[buffer_index]);
+
+ num_bytes = comedi_buf_read_n_available(dev->write_subdev->async);
+ if (num_bytes > DMA_BUFFER_SIZE)
+ num_bytes = DMA_BUFFER_SIZE;
+ if (cmd->stop_src == TRIG_COUNT && num_bytes > priv(dev)->ao_count)
+ num_bytes = priv(dev)->ao_count;
+ num_bytes -= num_bytes % bytes_in_sample;
+
+ if (num_bytes == 0)
+ return 0;
+
+ DEBUG_PRINT("loading %i bytes\n", num_bytes);
+
+ num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
+ priv(dev)->ao_buffer[buffer_index], num_bytes);
+ priv(dev)->ao_dma_desc[buffer_index].transfer_size =
+ cpu_to_le32(num_bytes);
+ /* set end of chain bit so we catch underruns */
+ next_bits = le32_to_cpu(priv(dev)->ao_dma_desc[buffer_index].next);
+ next_bits |= PLX_END_OF_CHAIN_BIT;
+ priv(dev)->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits);
+ /* clear end of chain bit on previous buffer now that we have set it
+ * for the last buffer */
+ next_bits = le32_to_cpu(priv(dev)->ao_dma_desc[prev_buffer_index].next);
+ next_bits &= ~PLX_END_OF_CHAIN_BIT;
+ priv(dev)->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits);
+
+ priv(dev)->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT;
+ priv(dev)->ao_count -= num_bytes;
+
+ return num_bytes;
+}
+
+static void load_ao_dma(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ unsigned int num_bytes;
+ unsigned int next_transfer_addr;
+ void *pci_addr_reg =
+ priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
+ unsigned int buffer_index;
+
+ do {
+ buffer_index = priv(dev)->ao_dma_index;
+ /* don't overwrite data that hasn't been transferred yet */
+ next_transfer_addr = readl(pci_addr_reg);
+ if (next_transfer_addr >=
+ priv(dev)->ao_buffer_bus_addr[buffer_index]
+ && next_transfer_addr <
+ priv(dev)->ao_buffer_bus_addr[buffer_index] +
+ DMA_BUFFER_SIZE)
+ return;
+ num_bytes = load_ao_dma_buffer(dev, cmd);
+ } while (num_bytes >= DMA_BUFFER_SIZE);
+}
+
+static int prep_ao_dma(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ unsigned int num_bytes;
+ int i;
+
+ /* clear queue pointer too, since external queue has
+ * weird interactions with ao fifo */
+ writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
+ writew(0, priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG);
+
+ num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample;
+ if (cmd->stop_src == TRIG_COUNT &&
+ num_bytes / bytes_in_sample > priv(dev)->ao_count)
+ num_bytes = priv(dev)->ao_count * bytes_in_sample;
+ num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
+ priv(dev)->ao_bounce_buffer, num_bytes);
+ for (i = 0; i < num_bytes / bytes_in_sample; i++) {
+ writew(priv(dev)->ao_bounce_buffer[i],
+ priv(dev)->main_iobase + DAC_FIFO_REG);
+ }
+ priv(dev)->ao_count -= num_bytes / bytes_in_sample;
+ if (cmd->stop_src == TRIG_COUNT && priv(dev)->ao_count == 0)
+ return 0;
+ num_bytes = load_ao_dma_buffer(dev, cmd);
+ if (num_bytes == 0)
+ return -1;
+ if (num_bytes >= DMA_BUFFER_SIZE) ;
+ load_ao_dma(dev, cmd);
+
+ dma_start_sync(dev, 0);
+
+ return 0;
+}
+
+static inline int external_ai_queue_in_use(struct comedi_device * dev)
+{
+ if (dev->read_subdev->busy)
+ return 0;
+ if (board(dev)->layout == LAYOUT_4020)
+ return 0;
+ else if (use_internal_queue_6xxx(&dev->read_subdev->async->cmd))
+ return 0;
+ return 1;
+}
+
+static int ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (external_ai_queue_in_use(dev)) {
+ warn_external_queue(dev);
+ return -EBUSY;
+ }
+ /* disable analog output system during setup */
+ writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+
+ priv(dev)->ao_dma_index = 0;
+ priv(dev)->ao_count = cmd->stop_arg * cmd->chanlist_len;
+
+ set_dac_select_reg(dev, cmd);
+ set_dac_interval_regs(dev, cmd);
+ load_first_dma_descriptor(dev, 0, priv(dev)->ao_dma_desc_bus_addr |
+ PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT);
+
+ set_dac_control1_reg(dev, cmd);
+ s->async->inttrig = ao_inttrig;
+
+ return 0;
+}
+
+static int ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trig_num)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int retval;
+
+ if (trig_num != 0)
+ return -EINVAL;
+
+ retval = prep_ao_dma(dev, cmd);
+ if (retval < 0)
+ return -EPIPE;
+
+ set_dac_control0_reg(dev, cmd);
+
+ if (cmd->start_src == TRIG_INT)
+ writew(0, priv(dev)->main_iobase + DAC_START_REG);
+
+ s->async->inttrig = NULL;
+
+ return 0;
+}
+
+static int ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ unsigned int tmp_arg;
+ int i;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_INT | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ // uniqueness check
+ if (cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+
+ // compatibility check
+ if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT &&
+ cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < board(dev)->ao_scan_speed) {
+ cmd->scan_begin_arg = board(dev)->ao_scan_speed;
+ err++;
+ }
+ if (get_ao_divisor(cmd->scan_begin_arg,
+ cmd->flags) > max_counter_value) {
+ cmd->scan_begin_arg =
+ (max_counter_value + 2) * TIMER_BASE;
+ err++;
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp_arg = cmd->scan_begin_arg;
+ cmd->scan_begin_arg =
+ get_divisor(cmd->scan_begin_arg,
+ cmd->flags) * TIMER_BASE;
+ if (tmp_arg != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ if (cmd->chanlist) {
+ unsigned int first_channel = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) != first_channel + i) {
+ comedi_error(dev,
+ "chanlist must use consecutive channels");
+ err++;
+ break;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+ abort_dma(dev, 0);
+ return 0;
+}
+
+static int dio_callback(int dir, int port, int data, unsigned long iobase)
+{
+ if (dir) {
+ writeb(data, (void *)(iobase + port));
+ DEBUG_PRINT("wrote 0x%x to port %i\n", data, port);
+ return 0;
+ } else {
+ return readb((void *)(iobase + port));
+ }
+}
+
+static int dio_callback_4020(int dir, int port, int data, unsigned long iobase)
+{
+ if (dir) {
+ writew(data, (void *)(iobase + 2 * port));
+ return 0;
+ } else {
+ return readw((void *)(iobase + 2 * port));
+ }
+}
+
+static int di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits;
+
+ bits = readb(priv(dev)->dio_counter_iobase + DI_REG);
+ bits &= 0xf;
+ data[1] = bits;
+ data[0] = 0;
+
+ return 2;
+}
+
+static int do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] &= 0xf;
+ // zero bits we are going to change
+ s->state &= ~data[0];
+ // set new bits
+ s->state |= data[0] & data[1];
+
+ writeb(s->state, priv(dev)->dio_counter_iobase + DO_REG);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int dio_60xx_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int mask;
+
+ mask = 1 << CR_CHAN(insn->chanspec);
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~mask;
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= mask;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return 2;
+ default:
+ return -EINVAL;
+ }
+
+ writeb(s->io_bits,
+ priv(dev)->dio_counter_iobase + DIO_DIRECTION_60XX_REG);
+
+ return 1;
+}
+
+static int dio_60xx_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ writeb(s->state,
+ priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG);
+ }
+
+ data[1] = readb(priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG);
+
+ return 2;
+}
+
+static void caldac_write(struct comedi_device * dev, unsigned int channel,
+ unsigned int value)
+{
+ priv(dev)->caldac_state[channel] = value;
+
+ switch (board(dev)->layout) {
+ case LAYOUT_60XX:
+ case LAYOUT_64XX:
+ caldac_8800_write(dev, channel, value);
+ break;
+ case LAYOUT_4020:
+ caldac_i2c_write(dev, channel, value);
+ break;
+ default:
+ break;
+ }
+}
+
+static int calib_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel = CR_CHAN(insn->chanspec);
+
+ /* return immediately if setting hasn't changed, since
+ * programming these things is slow */
+ if (priv(dev)->caldac_state[channel] == data[0])
+ return 1;
+
+ caldac_write(dev, channel, data[0]);
+
+ return 1;
+}
+
+static int calib_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int channel = CR_CHAN(insn->chanspec);
+
+ data[0] = priv(dev)->caldac_state[channel];
+
+ return 1;
+}
+
+static void ad8402_write(struct comedi_device * dev, unsigned int channel,
+ unsigned int value)
+{
+ static const int bitstream_length = 10;
+ unsigned int bit, register_bits;
+ unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
+ static const int ad8402_comedi_udelay = 1;
+
+ priv(dev)->ad8402_state[channel] = value;
+
+ register_bits = SELECT_8402_64XX_BIT;
+ comedi_udelay(ad8402_comedi_udelay);
+ writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+
+ for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
+ if (bitstream & bit)
+ register_bits |= SERIAL_DATA_IN_BIT;
+ else
+ register_bits &= ~SERIAL_DATA_IN_BIT;
+ comedi_udelay(ad8402_comedi_udelay);
+ writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+ comedi_udelay(ad8402_comedi_udelay);
+ writew(register_bits | SERIAL_CLOCK_BIT,
+ priv(dev)->main_iobase + CALIBRATION_REG);
+ }
+
+ comedi_udelay(ad8402_comedi_udelay);
+ writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+}
+
+/* for pci-das6402/16, channel 0 is analog input gain and channel 1 is offset */
+static int ad8402_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel = CR_CHAN(insn->chanspec);
+
+ /* return immediately if setting hasn't changed, since
+ * programming these things is slow */
+ if (priv(dev)->ad8402_state[channel] == data[0])
+ return 1;
+
+ priv(dev)->ad8402_state[channel] = data[0];
+
+ ad8402_write(dev, channel, data[0]);
+
+ return 1;
+}
+
+static int ad8402_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int channel = CR_CHAN(insn->chanspec);
+
+ data[0] = priv(dev)->ad8402_state[channel];
+
+ return 1;
+}
+
+static uint16_t read_eeprom(struct comedi_device * dev, uint8_t address)
+{
+ static const int bitstream_length = 11;
+ static const int read_command = 0x6;
+ unsigned int bitstream = (read_command << 8) | address;
+ unsigned int bit;
+ void *const plx_control_addr =
+ priv(dev)->plx9080_iobase + PLX_CONTROL_REG;
+ uint16_t value;
+ static const int value_length = 16;
+ static const int eeprom_comedi_udelay = 1;
+
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits &= ~CTL_EE_CLK & ~CTL_EE_CS;
+ // make sure we don't send anything to the i2c bus on 4020
+ priv(dev)->plx_control_bits |= CTL_USERO;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ // activate serial eeprom
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits |= CTL_EE_CS;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+
+ // write read command and desired memory address
+ for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
+ // set bit to be written
+ comedi_udelay(eeprom_comedi_udelay);
+ if (bitstream & bit)
+ priv(dev)->plx_control_bits |= CTL_EE_W;
+ else
+ priv(dev)->plx_control_bits &= ~CTL_EE_W;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ // clock in bit
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits |= CTL_EE_CLK;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits &= ~CTL_EE_CLK;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ }
+ // read back value from eeprom memory location
+ value = 0;
+ for (bit = 1 << (value_length - 1); bit; bit >>= 1) {
+ // clock out bit
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits |= CTL_EE_CLK;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits &= ~CTL_EE_CLK;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(eeprom_comedi_udelay);
+ if (readl(plx_control_addr) & CTL_EE_R)
+ value |= bit;
+ }
+
+ // deactivate eeprom serial input
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits &= ~CTL_EE_CS;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+
+ return value;
+}
+
+static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = read_eeprom(dev, CR_CHAN(insn->chanspec));
+
+ return 1;
+}
+
+/* utility function that rounds desired timing to an achievable time, and
+ * sets cmd members appropriately.
+ * adc paces conversions from master clock by dividing by (x + 3) where x is 24 bit number
+ */
+static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
+{
+ unsigned int convert_divisor = 0, scan_divisor;
+ static const int min_convert_divisor = 3;
+ static const int max_convert_divisor =
+ max_counter_value + min_convert_divisor;
+ static const int min_scan_divisor_4020 = 2;
+ unsigned long long max_scan_divisor, min_scan_divisor;
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (board(dev)->layout == LAYOUT_4020) {
+ cmd->convert_arg = 0;
+ } else {
+ convert_divisor =
+ get_divisor(cmd->convert_arg, cmd->flags);
+ if (convert_divisor > max_convert_divisor)
+ convert_divisor = max_convert_divisor;
+ if (convert_divisor < min_convert_divisor)
+ convert_divisor = min_convert_divisor;
+ cmd->convert_arg = convert_divisor * TIMER_BASE;
+ }
+ } else if (cmd->convert_src == TRIG_NOW)
+ cmd->convert_arg = 0;
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags);
+ if (cmd->convert_src == TRIG_TIMER) {
+ // XXX check for integer overflows
+ min_scan_divisor = convert_divisor * cmd->chanlist_len;
+ max_scan_divisor =
+ (convert_divisor * cmd->chanlist_len - 1) +
+ max_counter_value;
+ } else {
+ min_scan_divisor = min_scan_divisor_4020;
+ max_scan_divisor = max_counter_value + min_scan_divisor;
+ }
+ if (scan_divisor > max_scan_divisor)
+ scan_divisor = max_scan_divisor;
+ if (scan_divisor < min_scan_divisor)
+ scan_divisor = min_scan_divisor;
+ cmd->scan_begin_arg = scan_divisor * TIMER_BASE;
+ }
+
+ return;
+}
+
+/* Gets nearest achievable timing given master clock speed, does not
+ * take into account possible minimum/maximum divisor values. Used
+ * by other timing checking functions. */
+static unsigned int get_divisor(unsigned int ns, unsigned int flags)
+{
+ unsigned int divisor;
+
+ switch (flags & TRIG_ROUND_MASK) {
+ case TRIG_ROUND_UP:
+ divisor = (ns + TIMER_BASE - 1) / TIMER_BASE;
+ break;
+ case TRIG_ROUND_DOWN:
+ divisor = ns / TIMER_BASE;
+ break;
+ case TRIG_ROUND_NEAREST:
+ default:
+ divisor = (ns + TIMER_BASE / 2) / TIMER_BASE;
+ break;
+ }
+ return divisor;
+}
+
+static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags)
+{
+ return get_divisor(ns, flags) - 2;
+}
+
+// adjusts the size of hardware fifo (which determines block size for dma xfers)
+static int set_ai_fifo_size(struct comedi_device * dev, unsigned int num_samples)
+{
+ unsigned int num_fifo_entries;
+ int retval;
+ const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
+
+ num_fifo_entries = num_samples / fifo->sample_packing_ratio;
+
+ retval = set_ai_fifo_segment_length(dev,
+ num_fifo_entries / fifo->num_segments);
+ if (retval < 0)
+ return retval;
+
+ num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio;
+
+ DEBUG_PRINT("set hardware fifo size to %i\n", num_samples);
+
+ return num_samples;
+}
+
+// query length of fifo
+static unsigned int ai_fifo_size(struct comedi_device * dev)
+{
+ return priv(dev)->ai_fifo_segment_length *
+ board(dev)->ai_fifo->num_segments *
+ board(dev)->ai_fifo->sample_packing_ratio;
+}
+
+static int set_ai_fifo_segment_length(struct comedi_device * dev,
+ unsigned int num_entries)
+{
+ static const int increment_size = 0x100;
+ const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
+ unsigned int num_increments;
+ uint16_t bits;
+
+ if (num_entries < increment_size)
+ num_entries = increment_size;
+ if (num_entries > fifo->max_segment_length)
+ num_entries = fifo->max_segment_length;
+
+ // 1 == 256 entries, 2 == 512 entries, etc
+ num_increments = (num_entries + increment_size / 2) / increment_size;
+
+ bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask;
+ priv(dev)->fifo_size_bits &= ~fifo->fifo_size_reg_mask;
+ priv(dev)->fifo_size_bits |= bits;
+ writew(priv(dev)->fifo_size_bits,
+ priv(dev)->main_iobase + FIFO_SIZE_REG);
+
+ priv(dev)->ai_fifo_segment_length = num_increments * increment_size;
+
+ DEBUG_PRINT("set hardware fifo segment length to %i\n",
+ priv(dev)->ai_fifo_segment_length);
+
+ return priv(dev)->ai_fifo_segment_length;
+}
+
+/* pci-6025 8800 caldac:
+ * address 0 == dac channel 0 offset
+ * address 1 == dac channel 0 gain
+ * address 2 == dac channel 1 offset
+ * address 3 == dac channel 1 gain
+ * address 4 == fine adc offset
+ * address 5 == coarse adc offset
+ * address 6 == coarse adc gain
+ * address 7 == fine adc gain
+ */
+/* pci-6402/16 uses all 8 channels for dac:
+ * address 0 == dac channel 0 fine gain
+ * address 1 == dac channel 0 coarse gain
+ * address 2 == dac channel 0 coarse offset
+ * address 3 == dac channel 1 coarse offset
+ * address 4 == dac channel 1 fine gain
+ * address 5 == dac channel 1 coarse gain
+ * address 6 == dac channel 0 fine offset
+ * address 7 == dac channel 1 fine offset
+*/
+
+static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
+ uint8_t value)
+{
+ static const int num_caldac_channels = 8;
+ static const int bitstream_length = 11;
+ unsigned int bitstream = ((address & 0x7) << 8) | value;
+ unsigned int bit, register_bits;
+ static const int caldac_8800_udelay = 1;
+
+ if (address >= num_caldac_channels) {
+ comedi_error(dev, "illegal caldac channel");
+ return -1;
+ }
+ for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
+ register_bits = 0;
+ if (bitstream & bit)
+ register_bits |= SERIAL_DATA_IN_BIT;
+ comedi_udelay(caldac_8800_udelay);
+ writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+ register_bits |= SERIAL_CLOCK_BIT;
+ comedi_udelay(caldac_8800_udelay);
+ writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+ }
+ comedi_udelay(caldac_8800_udelay);
+ writew(SELECT_8800_BIT, priv(dev)->main_iobase + CALIBRATION_REG);
+ comedi_udelay(caldac_8800_udelay);
+ writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+ comedi_udelay(caldac_8800_udelay);
+ return 0;
+}
+
+// 4020 caldacs
+static int caldac_i2c_write(struct comedi_device * dev, unsigned int caldac_channel,
+ unsigned int value)
+{
+ uint8_t serial_bytes[3];
+ uint8_t i2c_addr;
+ enum pointer_bits {
+ // manual has gain and offset bits switched
+ OFFSET_0_2 = 0x1,
+ GAIN_0_2 = 0x2,
+ OFFSET_1_3 = 0x4,
+ GAIN_1_3 = 0x8,
+ };
+ enum data_bits {
+ NOT_CLEAR_REGISTERS = 0x20,
+ };
+
+ switch (caldac_channel) {
+ case 0: // chan 0 offset
+ i2c_addr = CALDAC0_I2C_ADDR;
+ serial_bytes[0] = OFFSET_0_2;
+ break;
+ case 1: // chan 1 offset
+ i2c_addr = CALDAC0_I2C_ADDR;
+ serial_bytes[0] = OFFSET_1_3;
+ break;
+ case 2: // chan 2 offset
+ i2c_addr = CALDAC1_I2C_ADDR;
+ serial_bytes[0] = OFFSET_0_2;
+ break;
+ case 3: // chan 3 offset
+ i2c_addr = CALDAC1_I2C_ADDR;
+ serial_bytes[0] = OFFSET_1_3;
+ break;
+ case 4: // chan 0 gain
+ i2c_addr = CALDAC0_I2C_ADDR;
+ serial_bytes[0] = GAIN_0_2;
+ break;
+ case 5: // chan 1 gain
+ i2c_addr = CALDAC0_I2C_ADDR;
+ serial_bytes[0] = GAIN_1_3;
+ break;
+ case 6: // chan 2 gain
+ i2c_addr = CALDAC1_I2C_ADDR;
+ serial_bytes[0] = GAIN_0_2;
+ break;
+ case 7: // chan 3 gain
+ i2c_addr = CALDAC1_I2C_ADDR;
+ serial_bytes[0] = GAIN_1_3;
+ break;
+ default:
+ comedi_error(dev, "invalid caldac channel\n");
+ return -1;
+ break;
+ }
+ serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf);
+ serial_bytes[2] = value & 0xff;
+ i2c_write(dev, i2c_addr, serial_bytes, 3);
+ return 0;
+}
+
+// Their i2c requires a huge delay on setting clock or data high for some reason
+static const int i2c_high_comedi_udelay = 1000;
+static const int i2c_low_comedi_udelay = 10;
+
+// set i2c data line high or low
+static void i2c_set_sda(struct comedi_device * dev, int state)
+{
+ static const int data_bit = CTL_EE_W;
+ void *plx_control_addr = priv(dev)->plx9080_iobase + PLX_CONTROL_REG;
+
+ if (state) {
+ // set data line high
+ priv(dev)->plx_control_bits &= ~data_bit;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(i2c_high_comedi_udelay);
+ } else // set data line low
+ {
+ priv(dev)->plx_control_bits |= data_bit;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(i2c_low_comedi_udelay);
+ }
+}
+
+// set i2c clock line high or low
+static void i2c_set_scl(struct comedi_device * dev, int state)
+{
+ static const int clock_bit = CTL_USERO;
+ void *plx_control_addr = priv(dev)->plx9080_iobase + PLX_CONTROL_REG;
+
+ if (state) {
+ // set clock line high
+ priv(dev)->plx_control_bits &= ~clock_bit;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(i2c_high_comedi_udelay);
+ } else // set clock line low
+ {
+ priv(dev)->plx_control_bits |= clock_bit;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(i2c_low_comedi_udelay);
+ }
+}
+
+static void i2c_write_byte(struct comedi_device * dev, uint8_t byte)
+{
+ uint8_t bit;
+ unsigned int num_bits = 8;
+
+ DEBUG_PRINT("writing to i2c byte 0x%x\n", byte);
+
+ for (bit = 1 << (num_bits - 1); bit; bit >>= 1) {
+ i2c_set_scl(dev, 0);
+ if ((byte & bit))
+ i2c_set_sda(dev, 1);
+ else
+ i2c_set_sda(dev, 0);
+ i2c_set_scl(dev, 1);
+ }
+}
+
+// we can't really read the lines, so fake it
+static int i2c_read_ack(struct comedi_device * dev)
+{
+ i2c_set_scl(dev, 0);
+ i2c_set_sda(dev, 1);
+ i2c_set_scl(dev, 1);
+
+ return 0; // return fake acknowledge bit
+}
+
+// send start bit
+static void i2c_start(struct comedi_device * dev)
+{
+ i2c_set_scl(dev, 1);
+ i2c_set_sda(dev, 1);
+ i2c_set_sda(dev, 0);
+}
+
+// send stop bit
+static void i2c_stop(struct comedi_device * dev)
+{
+ i2c_set_scl(dev, 0);
+ i2c_set_sda(dev, 0);
+ i2c_set_scl(dev, 1);
+ i2c_set_sda(dev, 1);
+}
+
+static void i2c_write(struct comedi_device * dev, unsigned int address,
+ const uint8_t * data, unsigned int length)
+{
+ unsigned int i;
+ uint8_t bitstream;
+ static const int read_bit = 0x1;
+
+//XXX need mutex to prevent simultaneous attempts to access eeprom and i2c bus
+
+ // make sure we dont send anything to eeprom
+ priv(dev)->plx_control_bits &= ~CTL_EE_CS;
+
+ i2c_stop(dev);
+ i2c_start(dev);
+
+ // send address and write bit
+ bitstream = (address << 1) & ~read_bit;
+ i2c_write_byte(dev, bitstream);
+
+ // get acknowledge
+ if (i2c_read_ack(dev) != 0) {
+ comedi_error(dev, "i2c write failed: no acknowledge");
+ i2c_stop(dev);
+ return;
+ }
+ // write data bytes
+ for (i = 0; i < length; i++) {
+ i2c_write_byte(dev, data[i]);
+ if (i2c_read_ack(dev) != 0) {
+ comedi_error(dev, "i2c write failed: no acknowledge");
+ i2c_stop(dev);
+ return;
+ }
+ }
+ i2c_stop(dev);
+}
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
new file mode 100644
index 00000000000..ed0a5eb3dd9
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -0,0 +1,841 @@
+/*
+ comedi/drivers/cb_pcidda.c
+ This intends to be a driver for the ComputerBoards / MeasurementComputing
+ PCI-DDA series.
+
+ Copyright (C) 2001 Ivan Martinez <ivanmr@altavista.com>
+ Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: cb_pcidda
+Description: MeasurementComputing PCI-DDA series
+Author: Ivan Martinez <ivanmr@altavista.com>, Frank Mori Hess <fmhess@users.sourceforge.net>
+Status: Supports 08/16, 04/16, 02/16, 08/12, 04/12, and 02/12
+Devices: [Measurement Computing] PCI-DDA08/12 (cb_pcidda), PCI-DDA04/12,
+ PCI-DDA02/12, PCI-DDA08/16, PCI-DDA04/16, PCI-DDA02/16
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI
+ device will be used.
+
+Only simple analog output writing is supported.
+
+So far it has only been tested with:
+ - PCI-DDA08/12
+Please report success/failure with other different cards to
+<comedi@comedi.org>.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+#include "8255.h"
+
+#define PCI_VENDOR_ID_CB 0x1307 // PCI vendor number of ComputerBoards
+#define N_BOARDS 10 // Number of boards in cb_pcidda_boards
+#define EEPROM_SIZE 128 // number of entries in eeprom
+#define MAX_AO_CHANNELS 8 // maximum number of ao channels for supported boards
+
+/* PCI-DDA base addresses */
+#define DIGITALIO_BADRINDEX 2
+ // DIGITAL I/O is pci_dev->resource[2]
+#define DIGITALIO_SIZE 8
+ // DIGITAL I/O uses 8 I/O port addresses
+#define DAC_BADRINDEX 3
+ // DAC is pci_dev->resource[3]
+
+/* Digital I/O registers */
+#define PORT1A 0 // PORT 1A DATA
+
+#define PORT1B 1 // PORT 1B DATA
+
+#define PORT1C 2 // PORT 1C DATA
+
+#define CONTROL1 3 // CONTROL REGISTER 1
+
+#define PORT2A 4 // PORT 2A DATA
+
+#define PORT2B 5 // PORT 2B DATA
+
+#define PORT2C 6 // PORT 2C DATA
+
+#define CONTROL2 7 // CONTROL REGISTER 2
+
+/* DAC registers */
+#define DACONTROL 0 // D/A CONTROL REGISTER
+#define SU 0000001 // Simultaneous update enabled
+#define NOSU 0000000 // Simultaneous update disabled
+#define ENABLEDAC 0000002 // Enable specified DAC
+#define DISABLEDAC 0000000 // Disable specified DAC
+#define RANGE2V5 0000000 // 2.5V
+#define RANGE5V 0000200 // 5V
+#define RANGE10V 0000300 // 10V
+#define UNIP 0000400 // Unipolar outputs
+#define BIP 0000000 // Bipolar outputs
+
+#define DACALIBRATION1 4 // D/A CALIBRATION REGISTER 1
+//write bits
+#define SERIAL_IN_BIT 0x1 // serial data input for eeprom, caldacs, reference dac
+#define CAL_CHANNEL_MASK (0x7 << 1)
+#define CAL_CHANNEL_BITS(channel) (((channel) << 1) & CAL_CHANNEL_MASK)
+//read bits
+#define CAL_COUNTER_MASK 0x1f
+#define CAL_COUNTER_OVERFLOW_BIT 0x20 // calibration counter overflow status bit
+#define AO_BELOW_REF_BIT 0x40 // analog output is less than reference dac voltage
+#define SERIAL_OUT_BIT 0x80 // serial data out, for reading from eeprom
+
+#define DACALIBRATION2 6 // D/A CALIBRATION REGISTER 2
+#define SELECT_EEPROM_BIT 0x1 // send serial data in to eeprom
+#define DESELECT_REF_DAC_BIT 0x2 // don't send serial data to MAX542 reference dac
+#define DESELECT_CALDAC_BIT(n) (0x4 << (n)) // don't send serial data to caldac n
+#define DUMMY_BIT 0x40 // manual says to set this bit with no explanation
+
+#define DADATA 8 // FIRST D/A DATA REGISTER (0)
+
+static const struct comedi_lrange cb_pcidda_ranges = {
+ 6,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ }
+};
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct cb_pcidda_board {
+ const char *name;
+ char status; // Driver status:
+ // 0 - tested
+ // 1 - manual read, not tested
+ // 2 - manual not read
+ unsigned short device_id;
+ int ao_chans;
+ int ao_bits;
+ const struct comedi_lrange *ranges;
+};
+static const struct cb_pcidda_board cb_pcidda_boards[] = {
+ {
+ name: "pci-dda02/12",
+ status: 1,
+ device_id:0x20,
+ ao_chans:2,
+ ao_bits: 12,
+ ranges: &cb_pcidda_ranges,
+ },
+ {
+ name: "pci-dda04/12",
+ status: 1,
+ device_id:0x21,
+ ao_chans:4,
+ ao_bits: 12,
+ ranges: &cb_pcidda_ranges,
+ },
+ {
+ name: "pci-dda08/12",
+ status: 0,
+ device_id:0x22,
+ ao_chans:8,
+ ao_bits: 12,
+ ranges: &cb_pcidda_ranges,
+ },
+ {
+ name: "pci-dda02/16",
+ status: 2,
+ device_id:0x23,
+ ao_chans:2,
+ ao_bits: 16,
+ ranges: &cb_pcidda_ranges,
+ },
+ {
+ name: "pci-dda04/16",
+ status: 2,
+ device_id:0x24,
+ ao_chans:4,
+ ao_bits: 16,
+ ranges: &cb_pcidda_ranges,
+ },
+ {
+ name: "pci-dda08/16",
+ status: 0,
+ device_id:0x25,
+ ao_chans:8,
+ ao_bits: 16,
+ ranges: &cb_pcidda_ranges,
+ },
+};
+
+static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = {
+ {PCI_VENDOR_ID_CB, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0025, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct cb_pcidda_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct cb_pcidda_private {
+ int data;
+
+ /* would be useful for a PCI device */
+ struct pci_dev *pci_dev;
+
+ unsigned long digitalio;
+ unsigned long dac;
+ //unsigned long control_status;
+ //unsigned long adc_fifo;
+ unsigned int dac_cal1_bits; // bits last written to da calibration register 1
+ unsigned int ao_range[MAX_AO_CHANNELS]; // current range settings for output channels
+ u16 eeprom_data[EEPROM_SIZE]; // software copy of board's eeprom
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct cb_pcidda_private *)dev->private)
+
+static int cb_pcidda_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int cb_pcidda_detach(struct comedi_device * dev);
+//static int cb_pcidda_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data);
+static int cb_pcidda_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+//static int cb_pcidda_ai_cmd(struct comedi_device *dev,struct comedi_subdevice *s);
+//static int cb_pcidda_ai_cmdtest(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_cmd *cmd);
+//static int cb_pcidda_ns_to_timer(unsigned int *ns,int round);
+static unsigned int cb_pcidda_serial_in(struct comedi_device * dev);
+static void cb_pcidda_serial_out(struct comedi_device * dev, unsigned int value,
+ unsigned int num_bits);
+static unsigned int cb_pcidda_read_eeprom(struct comedi_device * dev,
+ unsigned int address);
+static void cb_pcidda_calibrate(struct comedi_device * dev, unsigned int channel,
+ unsigned int range);
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static struct comedi_driver driver_cb_pcidda = {
+ driver_name:"cb_pcidda",
+ module:THIS_MODULE,
+ attach:cb_pcidda_attach,
+ detach:cb_pcidda_detach,
+};
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.
+ */
+static int cb_pcidda_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ struct pci_dev *pcidev;
+ int index;
+
+ printk("comedi%d: cb_pcidda: ", dev->minor);
+
+/*
+ * Allocate the private structure area.
+ */
+ if (alloc_private(dev, sizeof(struct cb_pcidda_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+ printk("\n");
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ if (pcidev->vendor == PCI_VENDOR_ID_CB) {
+ if (it->options[0] || it->options[1]) {
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ for (index = 0; index < N_BOARDS; index++) {
+ if (cb_pcidda_boards[index].device_id ==
+ pcidev->device) {
+ goto found;
+ }
+ }
+ }
+ }
+ if (!pcidev) {
+ printk("Not a ComputerBoards/MeasurementComputing card on requested position\n");
+ return -EIO;
+ }
+ found:
+ devpriv->pci_dev = pcidev;
+ dev->board_ptr = cb_pcidda_boards + index;
+ // "thisboard" macro can be used from here.
+ printk("Found %s at requested position\n", thisboard->name);
+
+ /*
+ * Enable PCI device and request regions.
+ */
+ if (comedi_pci_enable(pcidev, thisboard->name)) {
+ printk("cb_pcidda: failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+
+/*
+ * Allocate the I/O ports.
+ */
+ devpriv->digitalio =
+ pci_resource_start(devpriv->pci_dev, DIGITALIO_BADRINDEX);
+ devpriv->dac = pci_resource_start(devpriv->pci_dev, DAC_BADRINDEX);
+
+/*
+ * Warn about the status of the driver.
+ */
+ if (thisboard->status == 2)
+ printk("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. " "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. " "PLEASE REPORT USAGE TO <ivanmr@altavista.com>.\n");
+
+/*
+ * Initialize dev->board_name.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures.
+ */
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->ao_chans;
+ s->maxdata = (1 << thisboard->ao_bits) - 1;
+ s->range_table = thisboard->ranges;
+ s->insn_write = cb_pcidda_ao_winsn;
+// s->subdev_flags |= SDF_CMD_READ;
+// s->do_cmd = cb_pcidda_ai_cmd;
+// s->do_cmdtest = cb_pcidda_ai_cmdtest;
+
+ // two 8255 digital io subdevices
+ s = dev->subdevices + 1;
+ subdev_8255_init(dev, s, NULL, devpriv->digitalio);
+ s = dev->subdevices + 2;
+ subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A);
+
+ printk(" eeprom:");
+ for (index = 0; index < EEPROM_SIZE; index++) {
+ devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index);
+ printk(" %i:0x%x ", index, devpriv->eeprom_data[index]);
+ }
+ printk("\n");
+
+ // set calibrations dacs
+ for (index = 0; index < thisboard->ao_chans; index++)
+ cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]);
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int cb_pcidda_detach(struct comedi_device * dev)
+{
+/*
+ * Deallocate the I/O ports.
+ */
+ if (devpriv) {
+ if (devpriv->pci_dev) {
+ if (devpriv->dac) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+ // cleanup 8255
+ if (dev->subdevices) {
+ subdev_8255_cleanup(dev, dev->subdevices + 1);
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+ }
+
+ printk("comedi%d: cb_pcidda: remove\n", dev->minor);
+
+ return 0;
+}
+
+/*
+ * I will program this later... ;-)
+ */
+#if 0
+static int cb_pcidda_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ printk("cb_pcidda_ai_cmd\n");
+ printk("subdev: %d\n", cmd->subdev);
+ printk("flags: %d\n", cmd->flags);
+ printk("start_src: %d\n", cmd->start_src);
+ printk("start_arg: %d\n", cmd->start_arg);
+ printk("scan_begin_src: %d\n", cmd->scan_begin_src);
+ printk("convert_src: %d\n", cmd->convert_src);
+ printk("convert_arg: %d\n", cmd->convert_arg);
+ printk("scan_end_src: %d\n", cmd->scan_end_src);
+ printk("scan_end_arg: %d\n", cmd->scan_end_arg);
+ printk("stop_src: %d\n", cmd->stop_src);
+ printk("stop_arg: %d\n", cmd->stop_arg);
+ printk("chanlist_len: %d\n", cmd->chanlist_len);
+}
+#endif
+
+#if 0
+static int cb_pcidda_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_TIMER
+ && cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED 10000 /* in nanoseconds */
+#define MIN_SPEED 1000000000 /* in nanoseconds */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < MAX_SPEED) {
+ cmd->scan_begin_arg = MAX_SPEED;
+ err++;
+ }
+ if (cmd->scan_begin_arg > MIN_SPEED) {
+ cmd->scan_begin_arg = MIN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* should be level/edge, hi/lo specification here */
+ /* should specify multiple external triggers */
+ if (cmd->scan_begin_arg > 9) {
+ cmd->scan_begin_arg = 9;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < MAX_SPEED) {
+ cmd->convert_arg = MAX_SPEED;
+ err++;
+ }
+ if (cmd->convert_arg > MIN_SPEED) {
+ cmd->convert_arg = MIN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* see above */
+ if (cmd->convert_arg > 9) {
+ cmd->convert_arg = 9;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg > 0x00ffffff) {
+ cmd->stop_arg = 0x00ffffff;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ cb_pcidda_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ cb_pcidda_ns_to_timer(&cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+#endif
+
+/* This function doesn't require a particular form, this is just
+ * what happens to be used in some of the drivers. It should
+ * convert ns nanoseconds to a counter value suitable for programming
+ * the device. Also, it should adjust ns so that it cooresponds to
+ * the actual time that the device will use. */
+#if 0
+static int cb_pcidda_ns_to_timer(unsigned int *ns, int round)
+{
+ /* trivial timer */
+ return *ns;
+}
+#endif
+
+static int cb_pcidda_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int command;
+ unsigned int channel, range;
+
+ channel = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+
+ // adjust calibration dacs if range has changed
+ if (range != devpriv->ao_range[channel])
+ cb_pcidda_calibrate(dev, channel, range);
+
+ /* output channel configuration */
+ command = NOSU | ENABLEDAC;
+
+ /* output channel range */
+ switch (range) {
+ case 0:
+ command |= BIP | RANGE10V;
+ break;
+ case 1:
+ command |= BIP | RANGE5V;
+ break;
+ case 2:
+ command |= BIP | RANGE2V5;
+ break;
+ case 3:
+ command |= UNIP | RANGE10V;
+ break;
+ case 4:
+ command |= UNIP | RANGE5V;
+ break;
+ case 5:
+ command |= UNIP | RANGE2V5;
+ break;
+ };
+
+ /* output channel specification */
+ command |= channel << 2;
+ outw(command, devpriv->dac + DACONTROL);
+
+ /* write data */
+ outw(data[0], devpriv->dac + DADATA + channel * 2);
+
+ /* return the number of samples read/written */
+ return 1;
+}
+
+// lowlevel read from eeprom
+static unsigned int cb_pcidda_serial_in(struct comedi_device * dev)
+{
+ unsigned int value = 0;
+ int i;
+ const int value_width = 16; // number of bits wide values are
+
+ for (i = 1; i <= value_width; i++) {
+ // read bits most significant bit first
+ if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT) {
+ value |= 1 << (value_width - i);
+ }
+ }
+
+ return value;
+}
+
+// lowlevel write to eeprom/dac
+static void cb_pcidda_serial_out(struct comedi_device * dev, unsigned int value,
+ unsigned int num_bits)
+{
+ int i;
+
+ for (i = 1; i <= num_bits; i++) {
+ // send bits most significant bit first
+ if (value & (1 << (num_bits - i)))
+ devpriv->dac_cal1_bits |= SERIAL_IN_BIT;
+ else
+ devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT;
+ outw_p(devpriv->dac_cal1_bits, devpriv->dac + DACALIBRATION1);
+ }
+}
+
+// reads a 16 bit value from board's eeprom
+static unsigned int cb_pcidda_read_eeprom(struct comedi_device * dev,
+ unsigned int address)
+{
+ unsigned int i;
+ unsigned int cal2_bits;
+ unsigned int value;
+ const int max_num_caldacs = 4; // one caldac for every two dac channels
+ const int read_instruction = 0x6; // bits to send to tell eeprom we want to read
+ const int instruction_length = 3;
+ const int address_length = 8;
+
+ // send serial output stream to eeprom
+ cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
+ // deactivate caldacs (one caldac for every two channels)
+ for (i = 0; i < max_num_caldacs; i++) {
+ cal2_bits |= DESELECT_CALDAC_BIT(i);
+ }
+ outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+
+ // tell eeprom we want to read
+ cb_pcidda_serial_out(dev, read_instruction, instruction_length);
+ // send address we want to read from
+ cb_pcidda_serial_out(dev, address, address_length);
+
+ value = cb_pcidda_serial_in(dev);
+
+ // deactivate eeprom
+ cal2_bits &= ~SELECT_EEPROM_BIT;
+ outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+
+ return value;
+}
+
+// writes to 8 bit calibration dacs
+static void cb_pcidda_write_caldac(struct comedi_device * dev, unsigned int caldac,
+ unsigned int channel, unsigned int value)
+{
+ unsigned int cal2_bits;
+ unsigned int i;
+ const int num_channel_bits = 3; // caldacs use 3 bit channel specification
+ const int num_caldac_bits = 8; // 8 bit calibration dacs
+ const int max_num_caldacs = 4; // one caldac for every two dac channels
+
+ /* write 3 bit channel */
+ cb_pcidda_serial_out(dev, channel, num_channel_bits);
+ // write 8 bit caldac value
+ cb_pcidda_serial_out(dev, value, num_caldac_bits);
+
+ // latch stream into appropriate caldac
+ // deselect reference dac
+ cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
+ // deactivate caldacs (one caldac for every two channels)
+ for (i = 0; i < max_num_caldacs; i++) {
+ cal2_bits |= DESELECT_CALDAC_BIT(i);
+ }
+ // activate the caldac we want
+ cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
+ outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+ // deactivate caldac
+ cal2_bits |= DESELECT_CALDAC_BIT(caldac);
+ outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+}
+
+// returns caldac that calibrates given analog out channel
+static unsigned int caldac_number(unsigned int channel)
+{
+ return channel / 2;
+}
+
+// returns caldac channel that provides fine gain for given ao channel
+static unsigned int fine_gain_channel(unsigned int ao_channel)
+{
+ return 4 * (ao_channel % 2);
+}
+
+// returns caldac channel that provides coarse gain for given ao channel
+static unsigned int coarse_gain_channel(unsigned int ao_channel)
+{
+ return 1 + 4 * (ao_channel % 2);
+}
+
+// returns caldac channel that provides coarse offset for given ao channel
+static unsigned int coarse_offset_channel(unsigned int ao_channel)
+{
+ return 2 + 4 * (ao_channel % 2);
+}
+
+// returns caldac channel that provides fine offset for given ao channel
+static unsigned int fine_offset_channel(unsigned int ao_channel)
+{
+ return 3 + 4 * (ao_channel % 2);
+}
+
+// returns eeprom address that provides offset for given ao channel and range
+static unsigned int offset_eeprom_address(unsigned int ao_channel,
+ unsigned int range)
+{
+ return 0x7 + 2 * range + 12 * ao_channel;
+}
+
+// returns eeprom address that provides gain calibration for given ao channel and range
+static unsigned int gain_eeprom_address(unsigned int ao_channel,
+ unsigned int range)
+{
+ return 0x8 + 2 * range + 12 * ao_channel;
+}
+
+// returns upper byte of eeprom entry, which gives the coarse adjustment values
+static unsigned int eeprom_coarse_byte(unsigned int word)
+{
+ return (word >> 8) & 0xff;
+}
+
+// returns lower byte of eeprom entry, which gives the fine adjustment values
+static unsigned int eeprom_fine_byte(unsigned int word)
+{
+ return word & 0xff;
+}
+
+// set caldacs to eeprom values for given channel and range
+static void cb_pcidda_calibrate(struct comedi_device * dev, unsigned int channel,
+ unsigned int range)
+{
+ unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain;
+
+ // remember range so we can tell when we need to readjust calibration
+ devpriv->ao_range[channel] = range;
+
+ // get values from eeprom data
+ coarse_offset =
+ eeprom_coarse_byte(devpriv->
+ eeprom_data[offset_eeprom_address(channel, range)]);
+ fine_offset =
+ eeprom_fine_byte(devpriv->
+ eeprom_data[offset_eeprom_address(channel, range)]);
+ coarse_gain =
+ eeprom_coarse_byte(devpriv->
+ eeprom_data[gain_eeprom_address(channel, range)]);
+ fine_gain =
+ eeprom_fine_byte(devpriv->
+ eeprom_data[gain_eeprom_address(channel, range)]);
+
+ // set caldacs
+ cb_pcidda_write_caldac(dev, caldac_number(channel),
+ coarse_offset_channel(channel), coarse_offset);
+ cb_pcidda_write_caldac(dev, caldac_number(channel),
+ fine_offset_channel(channel), fine_offset);
+ cb_pcidda_write_caldac(dev, caldac_number(channel),
+ coarse_gain_channel(channel), coarse_gain);
+ cb_pcidda_write_caldac(dev, caldac_number(channel),
+ fine_gain_channel(channel), fine_gain);
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_cb_pcidda, cb_pcidda_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c
new file mode 100644
index 00000000000..71a4b1482e3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcidio.c
@@ -0,0 +1,294 @@
+/*
+ comedi/drivers/cb_pcidio.c
+ A Comedi driver for PCI-DIO24H & PCI-DIO48H of ComputerBoards (currently MeasurementComputing)
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: cb_pcidio
+Description: ComputerBoards' DIO boards with PCI interface
+Devices: [Measurement Computing] PCI-DIO24 (cb_pcidio), PCI-DIO24H, PCI-DIO48H
+Author: Yoshiya Matsuzaka
+Updated: Mon, 29 Oct 2007 15:40:47 +0000
+Status: experimental
+
+This driver has been modified from skel.c of comedi-0.7.70.
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI device will
+ be used.
+
+Passing a zero for an option is the same as leaving it unspecified.
+*/
+
+/*------------------------------ HEADER FILES ---------------------------------*/
+#include "../comedidev.h"
+#include "comedi_pci.h"
+#include "8255.h"
+
+/*-------------------------- MACROS and DATATYPES -----------------------------*/
+#define PCI_VENDOR_ID_CB 0x1307
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct pcidio_board {
+ const char *name; // anme of the board
+ int n_8255; // number of 8255 chips on board
+
+ // indices of base address regions
+ int pcicontroler_badrindex;
+ int dioregs_badrindex;
+};
+
+static const struct pcidio_board pcidio_boards[] = {
+ {
+ name: "pci-dio24",
+ n_8255: 1,
+ pcicontroler_badrindex:1,
+ dioregs_badrindex:2,
+ },
+ {
+ name: "pci-dio24h",
+ n_8255: 1,
+ pcicontroler_badrindex:1,
+ dioregs_badrindex:2,
+ },
+ {
+ name: "pci-dio48h",
+ n_8255: 2,
+ pcicontroler_badrindex:0,
+ dioregs_badrindex:1,
+ },
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers. Should
+ * only be used for PCI and ISA-PnP devices */
+/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
+ * upstream. */
+static DEFINE_PCI_DEVICE_TABLE(pcidio_pci_table) = {
+ {PCI_VENDOR_ID_CB, 0x0028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pcidio_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pcidio_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct pcidio_private {
+ int data; // curently unused
+
+ /* would be useful for a PCI device */
+ struct pci_dev *pci_dev;
+
+ /* used for DO readback, curently unused */
+ unsigned int do_readback[4]; /* up to 4 unsigned int suffice to hold 96 bits for PCI-DIO96 */
+
+ unsigned long dio_reg_base; // address of port A of the first 8255 chip on board
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct pcidio_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pcidio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcidio_detach(struct comedi_device * dev);
+static struct comedi_driver driver_cb_pcidio = {
+ driver_name:"cb_pcidio",
+ module:THIS_MODULE,
+ attach:pcidio_attach,
+ detach:pcidio_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+ /* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in pcidio_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+// The following fields should NOT be initialized if you are dealing with PCI devices
+// board_name: pcidio_boards,
+// offset: sizeof(struct pcidio_board),
+// num_names: sizeof(pcidio_boards) / sizeof(struct pcidio_board),
+};
+
+/*------------------------------- FUNCTIONS -----------------------------------*/
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pcidio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev = NULL;
+ int index;
+ int i;
+
+ printk("comedi%d: cb_pcidio: \n", dev->minor);
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct pcidio_private)) < 0)
+ return -ENOMEM;
+/*
+ * If you can probe the device to determine what device in a series
+ * it is, this is the place to do it. Otherwise, dev->board_ptr
+ * should already be initialized.
+ */
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ // is it not a computer boards card?
+ if (pcidev->vendor != PCI_VENDOR_ID_CB)
+ continue;
+ // loop through cards supported by this driver
+ for (index = 0;
+ index < sizeof pcidio_boards / sizeof(struct pcidio_board);
+ index++) {
+ if (pcidio_pci_table[index].device != pcidev->device)
+ continue;
+
+ // was a particular bus/slot requested?
+ if (it->options[0] || it->options[1]) {
+ // are we on the wrong bus/slot?
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ dev->board_ptr = pcidio_boards + index;
+ goto found;
+ }
+ }
+
+ printk("No supported ComputerBoards/MeasurementComputing card found on "
+ "requested position\n");
+ return -EIO;
+
+ found:
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+ devpriv->pci_dev = pcidev;
+ printk("Found %s on bus %i, slot %i\n", thisboard->name,
+ devpriv->pci_dev->bus->number,
+ PCI_SLOT(devpriv->pci_dev->devfn));
+ if (comedi_pci_enable(pcidev, thisboard->name)) {
+ printk("cb_pcidio: failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+ devpriv->dio_reg_base
+ =
+ pci_resource_start(devpriv->pci_dev,
+ pcidio_boards[index].dioregs_badrindex);
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, thisboard->n_8255) < 0)
+ return -ENOMEM;
+
+ for (i = 0; i < thisboard->n_8255; i++) {
+ subdev_8255_init(dev, dev->subdevices + i,
+ NULL, devpriv->dio_reg_base + i * 4);
+ printk(" subdev %d: base = 0x%lx\n", i,
+ devpriv->dio_reg_base + i * 4);
+ }
+
+ printk("attached\n");
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pcidio_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: cb_pcidio: remove\n", dev->minor);
+ if (devpriv) {
+ if (devpriv->pci_dev) {
+ if (devpriv->dio_reg_base) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+ if (dev->subdevices) {
+ int i;
+ for (i = 0; i < thisboard->n_8255; i++) {
+ subdev_8255_cleanup(dev, dev->subdevices + i);
+ }
+ }
+ return 0;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_cb_pcidio, pcidio_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
new file mode 100644
index 00000000000..af705fa092c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -0,0 +1,484 @@
+/*
+ comedi/drivers/cb_pcimdas.c
+ Comedi driver for Computer Boards PCIM-DAS1602/16
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: cb_pcimdas
+Description: Measurement Computing PCI Migration series boards
+Devices: [ComputerBoards] PCIM-DAS1602/16 (cb_pcimdas)
+Author: Richard Bytheway
+Updated: Wed, 13 Nov 2002 12:34:56 +0000
+Status: experimental
+
+Written to support the PCIM-DAS1602/16 on a 2.4 series kernel.
+
+Configuration Options:
+ [0] - PCI bus number
+ [1] - PCI slot number
+
+Developed from cb_pcidas and skel by Richard Bytheway (mocelet@sucs.org).
+Only supports DIO, AO and simple AI in it's present form.
+No interrupts, multi channel or FIFO AI, although the card looks like it could support this.
+See http://www.measurementcomputing.com/PDFManuals/pcim-das1602_16.pdf for more details.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "plx9052.h"
+#include "8255.h"
+
+//#define CBPCIMDAS_DEBUG
+#undef CBPCIMDAS_DEBUG
+
+/* Registers for the PCIM-DAS1602/16 */
+
+// sizes of io regions (bytes)
+#define BADR0_SIZE 2 //??
+#define BADR1_SIZE 4
+#define BADR2_SIZE 6
+#define BADR3_SIZE 16
+#define BADR4_SIZE 4
+
+//DAC Offsets
+#define ADC_TRIG 0
+#define DAC0_OFFSET 2
+#define DAC1_OFFSET 4
+
+//AI and Counter Constants
+#define MUX_LIMITS 0
+#define MAIN_CONN_DIO 1
+#define ADC_STAT 2
+#define ADC_CONV_STAT 3
+#define ADC_INT 4
+#define ADC_PACER 5
+#define BURST_MODE 6
+#define PROG_GAIN 7
+#define CLK8254_1_DATA 8
+#define CLK8254_2_DATA 9
+#define CLK8254_3_DATA 10
+#define CLK8254_CONTROL 11
+#define USER_COUNTER 12
+#define RESID_COUNT_H 13
+#define RESID_COUNT_L 14
+
+/* Board description */
+struct cb_pcimdas_board {
+ const char *name;
+ unsigned short device_id;
+ int ai_se_chans; // Inputs in single-ended mode
+ int ai_diff_chans; // Inputs in differential mode
+ int ai_bits; // analog input resolution
+ int ai_speed; // fastest conversion period in ns
+ int ao_nchan; // number of analog out channels
+ int ao_bits; // analogue output resolution
+ int has_ao_fifo; // analog output has fifo
+ int ao_scan_speed; // analog output speed for 1602 series (for a scan, not conversion)
+ int fifo_size; // number of samples fifo can hold
+ int dio_bits; // number of dio bits
+ int has_dio; // has DIO
+ const struct comedi_lrange *ranges;
+};
+
+static const struct cb_pcimdas_board cb_pcimdas_boards[] = {
+ {
+ name: "PCIM-DAS1602/16",
+ device_id:0x56,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 16,
+ ai_speed:10000, //??
+ ao_nchan:2,
+ ao_bits: 12,
+ has_ao_fifo:0, //??
+ ao_scan_speed:10000,
+ //??
+ fifo_size:1024,
+ dio_bits:24,
+ has_dio: 1,
+// ranges: &cb_pcimdas_ranges,
+ },
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers. Should
+ * only be used for PCI and ISA-PnP devices */
+static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = {
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table);
+
+#define N_BOARDS 1 // Max number of boards supported
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct cb_pcimdas_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct cb_pcimdas_private {
+ int data;
+
+ // would be useful for a PCI device
+ struct pci_dev *pci_dev;
+
+ //base addresses
+ unsigned long BADR0;
+ unsigned long BADR1;
+ unsigned long BADR2;
+ unsigned long BADR3;
+ unsigned long BADR4;
+
+ /* Used for AO readback */
+ unsigned int ao_readback[2];
+
+ // Used for DIO
+ unsigned short int port_a; // copy of BADR4+0
+ unsigned short int port_b; // copy of BADR4+1
+ unsigned short int port_c; // copy of BADR4+2
+ unsigned short int dio_mode; // copy of BADR4+3
+
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct cb_pcimdas_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int cb_pcimdas_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int cb_pcimdas_detach(struct comedi_device * dev);
+static struct comedi_driver driver_cb_pcimdas = {
+ driver_name:"cb_pcimdas",
+ module:THIS_MODULE,
+ attach:cb_pcimdas_attach,
+ detach:cb_pcimdas_detach,
+};
+
+static int cb_pcimdas_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcimdas_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcimdas_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int cb_pcimdas_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ struct pci_dev *pcidev;
+ int index;
+ //int i;
+
+ printk("comedi%d: cb_pcimdas: ", dev->minor);
+
+/*
+ * Allocate the private structure area.
+ */
+ if (alloc_private(dev, sizeof(struct cb_pcimdas_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+ printk("\n");
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ // is it not a computer boards card?
+ if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
+ continue;
+ // loop through cards supported by this driver
+ for (index = 0; index < N_BOARDS; index++) {
+ if (cb_pcimdas_boards[index].device_id !=
+ pcidev->device)
+ continue;
+ // was a particular bus/slot requested?
+ if (it->options[0] || it->options[1]) {
+ // are we on the wrong bus/slot?
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+ dev->board_ptr = cb_pcimdas_boards + index;
+ goto found;
+ }
+ }
+
+ printk("No supported ComputerBoards/MeasurementComputing card found on "
+ "requested position\n");
+ return -EIO;
+
+ found:
+
+ printk("Found %s on bus %i, slot %i\n", cb_pcimdas_boards[index].name,
+ pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+
+ // Warn about non-tested features
+ switch (thisboard->device_id) {
+ case 0x56:
+ break;
+ default:
+ printk("THIS CARD IS UNSUPPORTED.\n"
+ "PLEASE REPORT USAGE TO <mocelet@sucs.org>\n");
+ };
+
+ if (comedi_pci_enable(pcidev, "cb_pcimdas")) {
+ printk(" Failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+
+ devpriv->BADR0 = pci_resource_start(devpriv->pci_dev, 0);
+ devpriv->BADR1 = pci_resource_start(devpriv->pci_dev, 1);
+ devpriv->BADR2 = pci_resource_start(devpriv->pci_dev, 2);
+ devpriv->BADR3 = pci_resource_start(devpriv->pci_dev, 3);
+ devpriv->BADR4 = pci_resource_start(devpriv->pci_dev, 4);
+
+#ifdef CBPCIMDAS_DEBUG
+ printk("devpriv->BADR0 = 0x%lx\n", devpriv->BADR0);
+ printk("devpriv->BADR1 = 0x%lx\n", devpriv->BADR1);
+ printk("devpriv->BADR2 = 0x%lx\n", devpriv->BADR2);
+ printk("devpriv->BADR3 = 0x%lx\n", devpriv->BADR3);
+ printk("devpriv->BADR4 = 0x%lx\n", devpriv->BADR4);
+#endif
+
+// Dont support IRQ yet
+// // get irq
+// if(comedi_request_irq(devpriv->pci_dev->irq, cb_pcimdas_interrupt, IRQF_SHARED, "cb_pcimdas", dev ))
+// {
+// printk(" unable to allocate irq %u\n", devpriv->pci_dev->irq);
+// return -EINVAL;
+// }
+// dev->irq = devpriv->pci_dev->irq;
+
+ //Initialize dev->board_name
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ //dev->read_subdev=s;
+ // analog input subdevice
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = thisboard->ai_se_chans;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = &range_unknown;
+ s->len_chanlist = 1; // This is the maximum chanlist length that
+ // the board can handle
+ s->insn_read = cb_pcimdas_ai_rinsn;
+
+ s = dev->subdevices + 1;
+ // analog output subdevice
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->ao_nchan;
+ s->maxdata = 1 << thisboard->ao_bits;
+ s->range_table = &range_unknown; //ranges are hardware settable, but not software readable.
+ s->insn_write = &cb_pcimdas_ao_winsn;
+ s->insn_read = &cb_pcimdas_ao_rinsn;
+
+ s = dev->subdevices + 2;
+ /* digital i/o subdevice */
+ if (thisboard->has_dio) {
+ subdev_8255_init(dev, s, NULL, devpriv->BADR4);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int cb_pcimdas_detach(struct comedi_device * dev)
+{
+#ifdef CBPCIMDAS_DEBUG
+ if (devpriv) {
+ printk("devpriv->BADR0 = 0x%lx\n", devpriv->BADR0);
+ printk("devpriv->BADR1 = 0x%lx\n", devpriv->BADR1);
+ printk("devpriv->BADR2 = 0x%lx\n", devpriv->BADR2);
+ printk("devpriv->BADR3 = 0x%lx\n", devpriv->BADR3);
+ printk("devpriv->BADR4 = 0x%lx\n", devpriv->BADR4);
+ }
+#endif
+ printk("comedi%d: cb_pcimdas: remove\n", dev->minor);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (devpriv) {
+ if (devpriv->pci_dev) {
+ if (devpriv->BADR0) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int cb_pcimdas_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i;
+ unsigned int d;
+ unsigned int busy;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned short chanlims;
+ int maxchans;
+
+ // only support sw initiated reads from a single channel
+
+ //check channel number
+ if ((inb(devpriv->BADR3 + 2) & 0x20) == 0) //differential mode
+ maxchans = thisboard->ai_diff_chans;
+ else
+ maxchans = thisboard->ai_se_chans;
+
+ if (chan > (maxchans - 1))
+ return -ETIMEDOUT; //*** Wrong error code. Fixme.
+
+ //configure for sw initiated read
+ d = inb(devpriv->BADR3 + 5);
+ if ((d & 0x03) > 0) { //only reset if needed.
+ d = d & 0xfd;
+ outb(d, devpriv->BADR3 + 5);
+ }
+ outb(0x01, devpriv->BADR3 + 6); //set bursting off, conversions on
+ outb(0x00, devpriv->BADR3 + 7); //set range to 10V. UP/BP is controlled by a switch on the board
+
+ // write channel limits to multiplexer, set Low (bits 0-3) and High (bits 4-7) channels to chan.
+ chanlims = chan | (chan << 4);
+ outb(chanlims, devpriv->BADR3 + 0);
+
+ /* convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ outw(0, devpriv->BADR2 + 0);
+
+#define TIMEOUT 1000 //typically takes 5 loops on a lightly loaded Pentium 100MHz,
+ //this is likely to be 100 loops on a 2GHz machine, so set 1000 as the limit.
+
+ /* wait for conversion to end */
+ for (i = 0; i < TIMEOUT; i++) {
+ busy = inb(devpriv->BADR3 + 2) & 0x80;
+ if (!busy)
+ break;
+ }
+ if (i == TIMEOUT) {
+ printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+ /* read data */
+ d = inw(devpriv->BADR2 + 0);
+
+ /* mangle the data as necessary */
+ //d ^= 1<<(thisboard->ai_bits-1); // 16 bit data from ADC, so no mangle needed.
+
+ data[n] = d;
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+static int cb_pcimdas_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ switch (chan) {
+ case 0:
+ outw(data[i] & 0x0FFF, devpriv->BADR2 + DAC0_OFFSET);
+ break;
+ case 1:
+ outw(data[i] & 0x0FFF, devpriv->BADR2 + DAC1_OFFSET);
+ break;
+ default:
+ return -1;
+ }
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int cb_pcimdas_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_cb_pcimdas, cb_pcimdas_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c
new file mode 100644
index 00000000000..e4c5b460fbd
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcimdda.c
@@ -0,0 +1,474 @@
+/*
+ comedi/drivers/cb_pcimdda.c
+ Computer Boards PCIM-DDA06-16 Comedi driver
+ Author: Calin Culianu <calin@ajvar.org>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: cb_pcimdda
+Description: Measurement Computing PCIM-DDA06-16
+Devices: [Measurement Computing] PCIM-DDA06-16 (cb_pcimdda)
+Author: Calin Culianu <calin@ajvar.org>
+Updated: Mon, 14 Apr 2008 15:15:51 +0100
+Status: works
+
+All features of the PCIM-DDA06-16 board are supported. This board
+has 6 16-bit AO channels, and the usual 8255 DIO setup. (24 channels,
+configurable in banks of 8 and 4, etc.). This board does not support commands.
+
+The board has a peculiar way of specifying AO gain/range settings -- You have
+1 jumper bank on the card, which either makes all 6 AO channels either
+5 Volt unipolar, 5V bipolar, 10 Volt unipolar or 10V bipolar.
+
+Since there is absolutely _no_ way to tell in software how this jumper is set
+(well, at least according to the rather thin spec. from Measurement Computing
+ that comes with the board), the driver assumes the jumper is at its factory
+default setting of +/-5V.
+
+Also of note is the fact that this board features another jumper, whose
+state is also completely invisible to software. It toggles two possible AO
+output modes on the board:
+
+ - Update Mode: Writing to an AO channel instantaneously updates the actual
+ signal output by the DAC on the board (this is the factory default).
+ - Simultaneous XFER Mode: Writing to an AO channel has no effect until
+ you read from any one of the AO channels. This is useful for loading
+ all 6 AO values, and then reading from any one of the AO channels on the
+ device to instantly update all 6 AO values in unison. Useful for some
+ control apps, I would assume? If your jumper is in this setting, then you
+ need to issue your comedi_data_write()s to load all the values you want,
+ then issue one comedi_data_read() on any channel on the AO subdevice
+ to initiate the simultaneous XFER.
+
+Configuration Options:
+ [0] PCI bus (optional)
+ [1] PCI slot (optional)
+ [2] analog output range jumper setting
+ 0 == +/- 5 V
+ 1 == +/- 10 V
+*/
+
+/*
+ This is a driver for the Computer Boards PCIM-DDA06-16 Analog Output
+ card. This board has a unique register layout and as such probably
+ deserves its own driver file.
+
+ It is theoretically possible to integrate this board into the cb_pcidda
+ file, but since that isn't my code, I didn't want to significantly
+ modify that file to support this board (I thought it impolite to do so).
+
+ At any rate, if you feel ambitious, please feel free to take
+ the code out of this file and combine it with a more unified driver
+ file.
+
+ I would like to thank Timothy Curry <Timothy.Curry@rdec.redstone.army.mil>
+ for lending me a board so that I could write this driver.
+
+ -Calin Culianu <calin@ajvar.org>
+ */
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "8255.h"
+
+/* device ids of the cards we support -- currently only 1 card supported */
+#define PCI_ID_PCIM_DDA06_16 0x0053
+
+/*
+ * This is straight from skel.c -- I did this in case this source file
+ * will someday support more than 1 board...
+ */
+struct board_struct {
+ const char *name;
+ unsigned short device_id;
+ int ao_chans;
+ int ao_bits;
+ int dio_chans;
+ int dio_method;
+ int dio_offset; /* how many bytes into the BADR are the DIO ports */
+ int regs_badrindex; /* IO Region for the control, analog output,
+ and DIO registers */
+ int reg_sz; /* number of bytes of registers in io region */
+};
+
+enum DIO_METHODS {
+ DIO_NONE = 0,
+ DIO_8255,
+ DIO_INTERNAL /* unimplemented */
+};
+
+static const struct board_struct boards[] = {
+ {
+ name: "cb_pcimdda06-16",
+ device_id:PCI_ID_PCIM_DDA06_16,
+ ao_chans:6,
+ ao_bits: 16,
+ dio_chans:24,
+ dio_method:DIO_8255,
+ dio_offset:12,
+ regs_badrindex:3,
+ reg_sz: 16,
+ }
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct board_struct *)dev->board_ptr)
+
+/* Number of boards in boards[] */
+#define N_BOARDS (sizeof(boards) / sizeof(struct board_struct))
+#define REG_SZ (thisboard->reg_sz)
+#define REGS_BADRINDEX (thisboard->regs_badrindex)
+
+/* This is used by modprobe to translate PCI IDs to drivers. Should
+ * only be used for PCI and ISA-PnP devices */
+/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
+ * upstream. */
+static DEFINE_PCI_DEVICE_TABLE(pci_table) = {
+ {PCI_VENDOR_ID_COMPUTERBOARDS, PCI_ID_PCIM_DDA06_16, PCI_ANY_ID,
+ PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci_table);
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct board_private_struct {
+ unsigned long registers; /* set by probe */
+ unsigned long dio_registers;
+ char attached_to_8255; /* boolean */
+ char attached_successfully; /* boolean */
+ /* would be useful for a PCI device */
+ struct pci_dev *pci_dev;
+
+#define MAX_AO_READBACK_CHANNELS 6
+ /* Used for AO readback */
+ unsigned int ao_readback[MAX_AO_READBACK_CHANNELS];
+
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct board_private_struct *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int detach(struct comedi_device * dev);
+static struct comedi_driver cb_pcimdda_driver = {
+ driver_name:"cb_pcimdda",
+ module:THIS_MODULE,
+ attach:attach,
+ detach:detach,
+};
+
+MODULE_AUTHOR("Calin A. Culianu <calin@rtlab.org>");
+MODULE_DESCRIPTION("Comedi low-level driver for the Computerboards PCIM-DDA "
+ "series. Currently only supports PCIM-DDA06-16 (which "
+ "also happens to be the only board in this series. :) ) ");
+MODULE_LICENSE("GPL");
+COMEDI_PCI_INITCLEANUP_NOMODULE(cb_pcimdda_driver, pci_table);
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/*---------------------------------------------------------------------------
+ HELPER FUNCTION DECLARATIONS
+-----------------------------------------------------------------------------*/
+
+/* returns a maxdata value for a given n_bits */
+static inline unsigned int figure_out_maxdata(int bits)
+{
+ return (((unsigned int) 1 << bits) - 1);
+}
+
+/*
+ * Probes for a supported device.
+ *
+ * Prerequisite: private be allocated already inside dev
+ *
+ * If the device is found, it returns 0 and has the following side effects:
+ *
+ * o assigns a struct pci_dev * to dev->private->pci_dev
+ * o assigns a struct board * to dev->board_ptr
+ * o sets dev->private->registers
+ * o sets dev->private->dio_registers
+ *
+ * Otherwise, returns a -errno on error
+ */
+static int probe(struct comedi_device * dev, const struct comedi_devconfig * it);
+
+/*---------------------------------------------------------------------------
+ FUNCTION DEFINITIONS
+-----------------------------------------------------------------------------*/
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int err;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ * if this function fails (returns negative) then the private area is
+ * kfree'd by comedi
+ */
+ if (alloc_private(dev, sizeof(struct board_private_struct)) < 0)
+ return -ENOMEM;
+
+/*
+ * If you can probe the device to determine what device in a series
+ * it is, this is the place to do it. Otherwise, dev->board_ptr
+ * should already be initialized.
+ */
+ if ((err = probe(dev, it)))
+ return err;
+
+/* Output some info */
+ printk("comedi%d: %s: ", dev->minor, thisboard->name);
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = thisboard->ao_chans;
+ s->maxdata = figure_out_maxdata(thisboard->ao_bits);
+ /* this is hard-coded here */
+ if (it->options[2]) {
+ s->range_table = &range_bipolar10;
+ } else {
+ s->range_table = &range_bipolar5;
+ }
+ s->insn_write = &ao_winsn;
+ s->insn_read = &ao_rinsn;
+
+ s = dev->subdevices + 1;
+ /* digital i/o subdevice */
+ if (thisboard->dio_chans) {
+ switch (thisboard->dio_method) {
+ case DIO_8255:
+ /* this is a straight 8255, so register us with the 8255 driver */
+ subdev_8255_init(dev, s, NULL, devpriv->dio_registers);
+ devpriv->attached_to_8255 = 1;
+ break;
+ case DIO_INTERNAL:
+ default:
+ printk("DIO_INTERNAL not implemented yet!\n");
+ return -ENXIO;
+ break;
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ devpriv->attached_successfully = 1;
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int detach(struct comedi_device * dev)
+{
+ if (devpriv) {
+
+ if (dev->subdevices && devpriv->attached_to_8255) {
+ /* de-register us from the 8255 driver */
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+ devpriv->attached_to_8255 = 0;
+ }
+
+ if (devpriv->pci_dev) {
+ if (devpriv->registers) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
+ if (devpriv->attached_successfully && thisboard)
+ printk("comedi%d: %s: detached\n", dev->minor,
+ thisboard->name);
+
+ }
+
+ return 0;
+}
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned long offset = devpriv->registers + chan * 2;
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ /* first, load the low byte */
+ outb((char)(data[i] & 0x00ff), offset);
+ /* next, write the high byte -- only after this is written is
+ the channel voltage updated in the DAC, unless
+ we're in simultaneous xfer mode (jumper on card)
+ then a rinsn is necessary to actually update the DAC --
+ see ao_rinsn() below... */
+ outb((char)(data[i] >> 8 & 0x00ff), offset + 1);
+
+ /* for testing only.. the actual rinsn SHOULD do an inw!
+ (see the stuff about simultaneous XFER mode on this board) */
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+
+ Usually this means copying a value stored in devpriv->ao_readback.
+ However, since this board has this jumper setting called "Simultaneous
+ Xfer mode" (off by default), we will support it. Simultaneaous xfer
+ mode is accomplished by loading ALL the values you want for AO in all the
+ channels, then READing off one of the AO registers to initiate the
+ instantaneous simultaneous update of all DAC outputs, which makes
+ all AO channels update simultaneously. This is useful for some control
+ applications, I would imagine.
+*/
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ inw(devpriv->registers + chan * 2);
+ /* should I set data[i] to the result of the actual read on the register
+ or the cached unsigned int in devpriv->ao_readback[]? */
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+/*---------------------------------------------------------------------------
+ HELPER FUNCTION DEFINITIONS
+-----------------------------------------------------------------------------*/
+
+/*
+ * Probes for a supported device.
+ *
+ * Prerequisite: private be allocated already inside dev
+ *
+ * If the device is found, it returns 0 and has the following side effects:
+ *
+ * o assigns a struct pci_dev * to dev->private->pci_dev
+ * o assigns a struct board * to dev->board_ptr
+ * o sets dev->private->registers
+ * o sets dev->private->dio_registers
+ *
+ * Otherwise, returns a -errno on error
+ */
+static int probe(struct comedi_device * dev, const struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev;
+ int index;
+ unsigned long registers;
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ // is it not a computer boards card?
+ if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
+ continue;
+ // loop through cards supported by this driver
+ for (index = 0; index < N_BOARDS; index++) {
+ if (boards[index].device_id != pcidev->device)
+ continue;
+ // was a particular bus/slot requested?
+ if (it->options[0] || it->options[1]) {
+ // are we on the wrong bus/slot?
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ /* found ! */
+
+ devpriv->pci_dev = pcidev;
+ dev->board_ptr = boards + index;
+ if (comedi_pci_enable(pcidev, thisboard->name)) {
+ printk("cb_pcimdda: Failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+ registers =
+ pci_resource_start(devpriv->pci_dev,
+ REGS_BADRINDEX);
+ devpriv->registers = registers;
+ devpriv->dio_registers
+ = devpriv->registers + thisboard->dio_offset;
+ return 0;
+ }
+ }
+
+ printk("cb_pcimdda: No supported ComputerBoards/MeasurementComputing "
+ "card found at the requested position\n");
+ return -ENODEV;
+}
diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c
index 9e5496f4f1a..1ee489864d3 100644
--- a/drivers/staging/comedi/drivers/comedi_bond.c
+++ b/drivers/staging/comedi/drivers/comedi_bond.c
@@ -59,7 +59,7 @@ Configuration Options:
* Devices: a full list of the boards that attempt to be supported by
* the driver. Format is "(manufacturer) board name [comedi name]",
* where comedi_name is the name that is used to configure the board.
- * See the comment near board_name: in the comedi_driver structure
+ * See the comment near board_name: in the struct comedi_driver structure
* below. If (manufacturer) or [comedi name] is missing, the previous
* value is used.
* Author: you
@@ -142,7 +142,7 @@ static const struct BondingBoard bondingBoards[] = {
#define thisboard ((const struct BondingBoard *)dev->board_ptr)
struct BondedDevice {
- comedi_t *dev;
+ void *dev;
unsigned minor;
unsigned subdev;
unsigned subdev_type;
@@ -154,7 +154,7 @@ struct BondedDevice {
/* this structure is for data unique to this hardware driver. If
several hardware drivers keep similar information in this structure,
- feel free to suggest moving the variable to the comedi_device struct. */
+ feel free to suggest moving the variable to the struct comedi_device struct. */
struct Private {
# define MAX_BOARD_NAME 256
char name[MAX_BOARD_NAME];
@@ -171,21 +171,21 @@ struct Private {
#define devpriv ((struct Private *)dev->private)
/*
- * The comedi_driver structure tells the Comedi core module
+ * The struct comedi_driver structure tells the Comedi core module
* which functions to call to configure/deconfigure (attach/detach)
* the board, and also about the kernel module that contains
* the device code.
*/
-static int bonding_attach(comedi_device *dev, comedi_devconfig *it);
-static int bonding_detach(comedi_device *dev);
+static int bonding_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int bonding_detach(struct comedi_device *dev);
/** Build Private array of all devices.. */
-static int doDevConfig(comedi_device *dev, comedi_devconfig *it);
-static void doDevUnconfig(comedi_device *dev);
+static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it);
+static void doDevUnconfig(struct comedi_device *dev);
/* Ugly implementation of realloc that always copies memory around -- I'm lazy,
* what can I say? I like to do wasteful memcopies.. :) */
static void *Realloc(const void *ptr, size_t len, size_t old_len);
-static comedi_driver driver_bonding = {
+static struct comedi_driver driver_bonding = {
.driver_name = MODULE_NAME,
.module = THIS_MODULE,
.attach = bonding_attach,
@@ -213,10 +213,10 @@ static comedi_driver driver_bonding = {
.num_names = sizeof(bondingBoards) / sizeof(struct BondingBoard),
};
-static int bonding_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data);
-static int bonding_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data);
+static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
/*
* Attach is called by the Comedi core to configure the driver
@@ -224,9 +224,9 @@ static int bonding_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
* in the driver structure, dev->board_ptr contains that
* address.
*/
-static int bonding_attach(comedi_device *dev, comedi_devconfig *it)
+static int bonding_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
LOG_MSG("comedi%d\n", dev->minor);
@@ -281,7 +281,7 @@ static int bonding_attach(comedi_device *dev, comedi_devconfig *it)
* allocated by _attach(). dev->private and dev->subdevices are
* deallocated automatically by the core.
*/
-static int bonding_detach(comedi_device *dev)
+static int bonding_detach(struct comedi_device *dev)
{
LOG_MSG("comedi%d: remove\n", dev->minor);
doDevUnconfig(dev);
@@ -293,10 +293,10 @@ static int bonding_detach(comedi_device *dev)
* useful to applications if you implement the insn_bits interface.
* This allows packed reading/writing of the DIO channels. The
* comedi core can convert between insn_bits and insn_read/write */
-static int bonding_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
-#define LSAMPL_BITS (sizeof(lsampl_t)*8)
+#define LSAMPL_BITS (sizeof(unsigned int)*8)
unsigned nchans = LSAMPL_BITS, num_done = 0, i;
if (insn->n != 2)
return -EINVAL;
@@ -312,12 +312,12 @@ static int bonding_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
to this subdevice.. need to shift them to zero position of
course. */
/* Bits corresponding to this subdev. */
- lsampl_t subdevMask = ((1 << bdev->nchans) - 1);
- lsampl_t writeMask, dataBits;
+ unsigned int subdevMask = ((1 << bdev->nchans) - 1);
+ unsigned int writeMask, dataBits;
/* Argh, we have >= LSAMPL_BITS chans.. take all bits */
if (bdev->nchans >= LSAMPL_BITS)
- subdevMask = (lsampl_t) (-1);
+ subdevMask = (unsigned int) (-1);
writeMask = (data[0] >> num_done) & subdevMask;
dataBits = (data[1] >> num_done) & subdevMask;
@@ -340,8 +340,8 @@ static int bonding_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
return insn->n;
}
-static int bonding_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int chan = CR_CHAN(insn->chanspec), ret, io_bits = s->io_bits;
unsigned int io;
@@ -394,10 +394,10 @@ static void *Realloc(const void *oldmem, size_t newlen, size_t oldlen)
return newmem;
}
-static int doDevConfig(comedi_device *dev, comedi_devconfig *it)
+static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
{
int i;
- comedi_t *devs_opened[COMEDI_NUM_BOARD_MINORS];
+ void *devs_opened[COMEDI_NUM_BOARD_MINORS];
memset(devs_opened, 0, sizeof(devs_opened));
devpriv->name[0] = 0;;
@@ -406,7 +406,7 @@ static int doDevConfig(comedi_device *dev, comedi_devconfig *it)
for (i = 0; i < COMEDI_NDEVCONFOPTS && (!i || it->options[i]); ++i) {
char file[] = "/dev/comediXXXXXX";
int minor = it->options[i];
- comedi_t *d;
+ void *d;
int sdev = -1, nchans, tmp;
struct BondedDevice *bdev = NULL;
@@ -497,7 +497,7 @@ static int doDevConfig(comedi_device *dev, comedi_devconfig *it)
return 1;
}
-static void doDevUnconfig(comedi_device *dev)
+static void doDevUnconfig(struct comedi_device *dev)
{
unsigned long devs_closed = 0;
diff --git a/drivers/staging/comedi/drivers/comedi_fc.c b/drivers/staging/comedi/drivers/comedi_fc.c
index cd74dbe5417..9fa4cdc84d4 100644
--- a/drivers/staging/comedi/drivers/comedi_fc.c
+++ b/drivers/staging/comedi/drivers/comedi_fc.c
@@ -28,10 +28,10 @@
#include "comedi_fc.h"
-static void increment_scan_progress(comedi_subdevice *subd,
+static void increment_scan_progress(struct comedi_subdevice *subd,
unsigned int num_bytes)
{
- comedi_async *async = subd->async;
+ struct comedi_async *async = subd->async;
unsigned int scan_length = cfc_bytes_per_scan(subd);
async->scan_progress += num_bytes;
@@ -42,10 +42,10 @@ static void increment_scan_progress(comedi_subdevice *subd,
}
/* Writes an array of data points to comedi's buffer */
-unsigned int cfc_write_array_to_buffer(comedi_subdevice *subd, void *data,
+unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd, void *data,
unsigned int num_bytes)
{
- comedi_async *async = subd->async;
+ struct comedi_async *async = subd->async;
unsigned int retval;
if (num_bytes == 0)
@@ -67,10 +67,10 @@ unsigned int cfc_write_array_to_buffer(comedi_subdevice *subd, void *data,
}
EXPORT_SYMBOL(cfc_write_array_to_buffer);
-unsigned int cfc_read_array_from_buffer(comedi_subdevice *subd, void *data,
+unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd, void *data,
unsigned int num_bytes)
{
- comedi_async *async = subd->async;
+ struct comedi_async *async = subd->async;
if (num_bytes == 0)
return 0;
@@ -85,7 +85,7 @@ unsigned int cfc_read_array_from_buffer(comedi_subdevice *subd, void *data,
}
EXPORT_SYMBOL(cfc_read_array_from_buffer);
-unsigned int cfc_handle_events(comedi_device *dev, comedi_subdevice *subd)
+unsigned int cfc_handle_events(struct comedi_device *dev, struct comedi_subdevice *subd)
{
unsigned int events = subd->async->events;
diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h
index 6952fe20f27..494ae3f2aff 100644
--- a/drivers/staging/comedi/drivers/comedi_fc.h
+++ b/drivers/staging/comedi/drivers/comedi_fc.h
@@ -30,30 +30,30 @@
#include "../comedidev.h"
/* Writes an array of data points to comedi's buffer */
-extern unsigned int cfc_write_array_to_buffer(comedi_subdevice *subd,
+extern unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd,
void *data,
unsigned int num_bytes);
-static inline unsigned int cfc_write_to_buffer(comedi_subdevice *subd,
- sampl_t data)
+static inline unsigned int cfc_write_to_buffer(struct comedi_subdevice *subd,
+ short data)
{
return cfc_write_array_to_buffer(subd, &data, sizeof(data));
};
-static inline unsigned int cfc_write_long_to_buffer(comedi_subdevice *subd,
- lsampl_t data)
+static inline unsigned int cfc_write_long_to_buffer(struct comedi_subdevice *subd,
+ unsigned int data)
{
return cfc_write_array_to_buffer(subd, &data, sizeof(data));
};
-extern unsigned int cfc_read_array_from_buffer(comedi_subdevice *subd,
+extern unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd,
void *data,
unsigned int num_bytes);
-extern unsigned int cfc_handle_events(comedi_device *dev,
- comedi_subdevice *subd);
+extern unsigned int cfc_handle_events(struct comedi_device *dev,
+ struct comedi_subdevice *subd);
-static inline unsigned int cfc_bytes_per_scan(comedi_subdevice *subd)
+static inline unsigned int cfc_bytes_per_scan(struct comedi_subdevice *subd)
{
int num_samples;
int bits_per_sample;
diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c
index ba838fffa29..a23339155ff 100644
--- a/drivers/staging/comedi/drivers/comedi_parport.c
+++ b/drivers/staging/comedi/drivers/comedi_parport.c
@@ -90,9 +90,9 @@ pin, which can be used to wake up tasks.
#define PARPORT_B 1
#define PARPORT_C 2
-static int parport_attach(comedi_device *dev, comedi_devconfig *it);
-static int parport_detach(comedi_device *dev);
-static comedi_driver driver_parport = {
+static int parport_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int parport_detach(struct comedi_device *dev);
+static struct comedi_driver driver_parport = {
.driver_name = "comedi_parport",
.module = THIS_MODULE,
.attach = parport_attach,
@@ -108,8 +108,8 @@ struct parport_private {
};
#define devpriv ((struct parport_private *)(dev->private))
-static int parport_insn_a(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int parport_insn_a(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
if (data[0]) {
devpriv->a_data &= ~data[0];
@@ -123,8 +123,8 @@ static int parport_insn_a(comedi_device *dev, comedi_subdevice *s,
return 2;
}
-static int parport_insn_config_a(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int parport_insn_config_a(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
if (data[0]) {
s->io_bits = 0xff;
@@ -138,8 +138,8 @@ static int parport_insn_config_a(comedi_device *dev, comedi_subdevice *s,
return 1;
}
-static int parport_insn_b(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int parport_insn_b(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
if (data[0]) {
/* should writes be ignored? */
@@ -151,8 +151,8 @@ static int parport_insn_b(comedi_device *dev, comedi_subdevice *s,
return 2;
}
-static int parport_insn_c(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int parport_insn_c(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
data[0] &= 0x0f;
if (data[0]) {
@@ -167,8 +167,8 @@ static int parport_insn_c(comedi_device *dev, comedi_subdevice *s,
return 2;
}
-static int parport_intr_insn(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int parport_intr_insn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
if (insn->n < 1)
return -EINVAL;
@@ -177,8 +177,8 @@ static int parport_intr_insn(comedi_device *dev, comedi_subdevice *s,
return 2;
}
-static int parport_intr_cmdtest(comedi_device *dev, comedi_subdevice *s,
- comedi_cmd *cmd)
+static int parport_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
int err = 0;
int tmp;
@@ -252,7 +252,7 @@ static int parport_intr_cmdtest(comedi_device *dev, comedi_subdevice *s,
return 0;
}
-static int parport_intr_cmd(comedi_device *dev, comedi_subdevice *s)
+static int parport_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
devpriv->c_data |= 0x10;
outb(devpriv->c_data, dev->iobase + PARPORT_C);
@@ -262,7 +262,7 @@ static int parport_intr_cmd(comedi_device *dev, comedi_subdevice *s)
return 0;
}
-static int parport_intr_cancel(comedi_device *dev, comedi_subdevice *s)
+static int parport_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
printk(KERN_DEBUG "parport_intr_cancel()\n");
@@ -276,8 +276,8 @@ static int parport_intr_cancel(comedi_device *dev, comedi_subdevice *s)
static irqreturn_t parport_interrupt(int irq, void *d PT_REGS_ARG)
{
- comedi_device *dev = d;
- comedi_subdevice *s = dev->subdevices + 3;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 3;
if (!devpriv->enable_irq) {
printk(KERN_ERR "comedi_parport: bogus irq, ignored\n");
@@ -291,12 +291,12 @@ static irqreturn_t parport_interrupt(int irq, void *d PT_REGS_ARG)
return IRQ_HANDLED;
}
-static int parport_attach(comedi_device *dev, comedi_devconfig *it)
+static int parport_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
int ret;
unsigned int irq;
unsigned long iobase;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
iobase = it->options[0];
printk(KERN_INFO "comedi%d: parport: 0x%04lx ", dev->minor, iobase);
@@ -376,7 +376,7 @@ static int parport_attach(comedi_device *dev, comedi_devconfig *it)
return 1;
}
-static int parport_detach(comedi_device *dev)
+static int parport_detach(struct comedi_device *dev)
{
printk("comedi%d: parport: remove\n", dev->minor);
diff --git a/drivers/staging/comedi/drivers/comedi_rt_timer.c b/drivers/staging/comedi/drivers/comedi_rt_timer.c
new file mode 100644
index 00000000000..f40c8cffd4b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/comedi_rt_timer.c
@@ -0,0 +1,728 @@
+/*
+ comedi/drivers/comedi_rt_timer.c
+ virtual driver for using RTL timing sources
+
+ Authors: David A. Schleef, Frank M. Hess
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999,2001 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+**************************************************************************
+*/
+/*
+Driver: comedi_rt_timer
+Description: Command emulator using real-time tasks
+Author: ds, fmhess
+Devices:
+Status: works
+
+This driver requires RTAI or RTLinux to work correctly. It doesn't
+actually drive hardware directly, but calls other drivers and uses
+a real-time task to emulate commands for drivers and devices that
+are incapable of native commands. Thus, you can get accurately
+timed I/O on any device.
+
+Since the timing is all done in software, sampling jitter is much
+higher than with a device that has an on-board timer, and maximum
+sample rate is much lower.
+
+Configuration options:
+ [0] - minor number of device you wish to emulate commands for
+ [1] - subdevice number you wish to emulate commands for
+*/
+/*
+TODO:
+ Support for digital io commands could be added, except I can't see why
+ anyone would want to use them
+ What happens if device we are emulating for is de-configured?
+*/
+
+#include "../comedidev.h"
+#include "../comedilib.h"
+
+#include "comedi_fc.h"
+
+#ifdef CONFIG_COMEDI_RTL_V1
+#include <rtl_sched.h>
+#include <asm/rt_irq.h>
+#endif
+#ifdef CONFIG_COMEDI_RTL
+#include <rtl.h>
+#include <rtl_sched.h>
+#include <rtl_compat.h>
+#include <asm/div64.h>
+
+#ifndef RTLINUX_VERSION_CODE
+#define RTLINUX_VERSION_CODE 0
+#endif
+#ifndef RTLINUX_VERSION
+#define RTLINUX_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#endif
+
+// begin hack to workaround broken HRT_TO_8254() function on rtlinux
+#if RTLINUX_VERSION_CODE <= RTLINUX_VERSION(3,0,100)
+// this function sole purpose is to divide a long long by 838
+static inline RTIME nano2count(long long ns)
+{
+ do_div(ns, 838);
+ return ns;
+}
+
+#ifdef rt_get_time()
+#undef rt_get_time()
+#endif
+#define rt_get_time() nano2count(gethrtime())
+
+#else
+
+#define nano2count(x) HRT_TO_8254(x)
+#endif
+// end hack
+
+// rtl-rtai compatibility
+#define rt_task_wait_period() rt_task_wait()
+#define rt_pend_linux_srq(irq) rtl_global_pend_irq(irq)
+#define rt_free_srq(irq) rtl_free_soft_irq(irq)
+#define rt_request_srq(x,y,z) rtl_get_soft_irq(y,"timer")
+#define rt_task_init(a,b,c,d,e,f,g) rt_task_init(a,b,c,d,(e)+1)
+#define rt_task_resume(x) rt_task_wakeup(x)
+#define rt_set_oneshot_mode()
+#define start_rt_timer(x)
+#define stop_rt_timer()
+
+#endif
+#ifdef CONFIG_COMEDI_RTAI
+#include <rtai.h>
+#include <rtai_sched.h>
+
+#if RTAI_VERSION_CODE < RTAI_MANGLE_VERSION(3,3,0)
+#define comedi_rt_task_context_t int
+#else
+#define comedi_rt_task_context_t long
+#endif
+
+#endif
+
+/* This defines the fastest speed we will emulate. Note that
+ * without a watchdog (like in RTAI), we could easily overrun our
+ * task period because analog input tends to be slow. */
+#define SPEED_LIMIT 100000 /* in nanoseconds */
+
+static int timer_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int timer_detach(struct comedi_device * dev);
+static int timer_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trig_num);
+static int timer_start_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static struct comedi_driver driver_timer = {
+ module:THIS_MODULE,
+ driver_name:"comedi_rt_timer",
+ attach:timer_attach,
+ detach:timer_detach,
+// open: timer_open,
+};
+
+COMEDI_INITCLEANUP(driver_timer);
+
+struct timer_private {
+ comedi_t *device; // device we are emulating commands for
+ int subd; // subdevice we are emulating commands for
+ RT_TASK *rt_task; // rt task that starts scans
+ RT_TASK *scan_task; // rt task that controls conversion timing in a scan
+ /* io_function can point to either an input or output function
+ * depending on what kind of subdevice we are emulating for */
+ int (*io_function) (struct comedi_device * dev, struct comedi_cmd * cmd,
+ unsigned int index);
+ // RTIME has units of 1 = 838 nanoseconds
+ // time at which first scan started, used to check scan timing
+ RTIME start;
+ // time between scans
+ RTIME scan_period;
+ // time between conversions in a scan
+ RTIME convert_period;
+ // flags
+ volatile int stop; // indicates we should stop
+ volatile int rt_task_active; // indicates rt_task is servicing a struct comedi_cmd
+ volatile int scan_task_active; // indicates scan_task is servicing a struct comedi_cmd
+ unsigned timer_running:1;
+};
+#define devpriv ((struct timer_private *)dev->private)
+
+static int timer_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ devpriv->stop = 1;
+
+ return 0;
+}
+
+// checks for scan timing error
+inline static int check_scan_timing(struct comedi_device * dev,
+ unsigned long long scan)
+{
+ RTIME now, timing_error;
+
+ now = rt_get_time();
+ timing_error = now - (devpriv->start + scan * devpriv->scan_period);
+ if (timing_error > devpriv->scan_period) {
+ comedi_error(dev, "timing error");
+ rt_printk("scan started %i ns late\n", timing_error * 838);
+ return -1;
+ }
+
+ return 0;
+}
+
+// checks for conversion timing error
+inline static int check_conversion_timing(struct comedi_device * dev,
+ RTIME scan_start, unsigned int conversion)
+{
+ RTIME now, timing_error;
+
+ now = rt_get_time();
+ timing_error =
+ now - (scan_start + conversion * devpriv->convert_period);
+ if (timing_error > devpriv->convert_period) {
+ comedi_error(dev, "timing error");
+ rt_printk("conversion started %i ns late\n",
+ timing_error * 838);
+ return -1;
+ }
+
+ return 0;
+}
+
+// devpriv->io_function for an input subdevice
+static int timer_data_read(struct comedi_device * dev, struct comedi_cmd * cmd,
+ unsigned int index)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ int ret;
+ unsigned int data;
+
+ ret = comedi_data_read(devpriv->device, devpriv->subd,
+ CR_CHAN(cmd->chanlist[index]),
+ CR_RANGE(cmd->chanlist[index]),
+ CR_AREF(cmd->chanlist[index]), &data);
+ if (ret < 0) {
+ comedi_error(dev, "read error");
+ return -EIO;
+ }
+ if (s->flags & SDF_LSAMPL) {
+ cfc_write_long_to_buffer(s, data);
+ } else {
+ comedi_buf_put(s->async, data);
+ }
+
+ return 0;
+}
+
+// devpriv->io_function for an output subdevice
+static int timer_data_write(struct comedi_device * dev, struct comedi_cmd * cmd,
+ unsigned int index)
+{
+ struct comedi_subdevice *s = dev->write_subdev;
+ unsigned int num_bytes;
+ short data;
+ unsigned int long_data;
+ int ret;
+
+ if (s->flags & SDF_LSAMPL) {
+ num_bytes =
+ cfc_read_array_from_buffer(s, &long_data,
+ sizeof(long_data));
+ } else {
+ num_bytes = cfc_read_array_from_buffer(s, &data, sizeof(data));
+ long_data = data;
+ }
+
+ if (num_bytes == 0) {
+ comedi_error(dev, "buffer underrun");
+ return -EAGAIN;
+ }
+ ret = comedi_data_write(devpriv->device, devpriv->subd,
+ CR_CHAN(cmd->chanlist[index]),
+ CR_RANGE(cmd->chanlist[index]),
+ CR_AREF(cmd->chanlist[index]), long_data);
+ if (ret < 0) {
+ comedi_error(dev, "write error");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+// devpriv->io_function for DIO subdevices
+static int timer_dio_read(struct comedi_device * dev, struct comedi_cmd * cmd,
+ unsigned int index)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ int ret;
+ unsigned int data;
+
+ ret = comedi_dio_bitfield(devpriv->device, devpriv->subd, 0, &data);
+ if (ret < 0) {
+ comedi_error(dev, "read error");
+ return -EIO;
+ }
+
+ if (s->flags & SDF_LSAMPL)
+ cfc_write_long_to_buffer(s, data);
+ else
+ cfc_write_to_buffer(s, data);
+
+ return 0;
+}
+
+// performs scans
+static void scan_task_func(comedi_rt_task_context_t d)
+{
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ int i, ret;
+ unsigned long long n;
+ RTIME scan_start;
+
+ // every struct comedi_cmd causes one execution of while loop
+ while (1) {
+ devpriv->scan_task_active = 1;
+ // each for loop completes one scan
+ for (n = 0; n < cmd->stop_arg || cmd->stop_src == TRIG_NONE;
+ n++) {
+ if (n) {
+ // suspend task until next scan
+ ret = rt_task_suspend(devpriv->scan_task);
+ if (ret < 0) {
+ comedi_error(dev,
+ "error suspending scan task");
+ async->events |= COMEDI_CB_ERROR;
+ goto cleanup;
+ }
+ }
+ // check if stop flag was set (by timer_cancel())
+ if (devpriv->stop)
+ goto cleanup;
+ ret = check_scan_timing(dev, n);
+ if (ret < 0) {
+ async->events |= COMEDI_CB_ERROR;
+ goto cleanup;
+ }
+ scan_start = rt_get_time();
+ for (i = 0; i < cmd->scan_end_arg; i++) {
+ // conversion timing
+ if (cmd->convert_src == TRIG_TIMER && i) {
+ rt_task_wait_period();
+ ret = check_conversion_timing(dev,
+ scan_start, i);
+ if (ret < 0) {
+ async->events |=
+ COMEDI_CB_ERROR;
+ goto cleanup;
+ }
+ }
+ ret = devpriv->io_function(dev, cmd, i);
+ if (ret < 0) {
+ async->events |= COMEDI_CB_ERROR;
+ goto cleanup;
+ }
+ }
+ s->async->events |= COMEDI_CB_BLOCK;
+ comedi_event(dev, s);
+ s->async->events = 0;
+ }
+
+ cleanup:
+
+ comedi_unlock(devpriv->device, devpriv->subd);
+ async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ async->events = 0;
+ devpriv->scan_task_active = 0;
+ // suspend task until next struct comedi_cmd
+ rt_task_suspend(devpriv->scan_task);
+ }
+}
+
+static void timer_task_func(comedi_rt_task_context_t d)
+{
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int ret;
+ unsigned long long n;
+
+ // every struct comedi_cmd causes one execution of while loop
+ while (1) {
+ devpriv->rt_task_active = 1;
+ devpriv->scan_task_active = 1;
+ devpriv->start = rt_get_time();
+
+ for (n = 0; n < cmd->stop_arg || cmd->stop_src == TRIG_NONE;
+ n++) {
+ // scan timing
+ if (n)
+ rt_task_wait_period();
+ if (devpriv->scan_task_active == 0) {
+ goto cleanup;
+ }
+ ret = rt_task_make_periodic(devpriv->scan_task,
+ devpriv->start + devpriv->scan_period * n,
+ devpriv->convert_period);
+ if (ret < 0) {
+ comedi_error(dev, "bug!");
+ }
+ }
+
+ cleanup:
+
+ devpriv->rt_task_active = 0;
+ // suspend until next struct comedi_cmd
+ rt_task_suspend(devpriv->rt_task);
+ }
+}
+
+static int timer_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct comedi_insn xinsn = *insn;
+
+ xinsn.data = data;
+ xinsn.subdev = devpriv->subd;
+
+ return comedi_do_insn(devpriv->device, &xinsn);
+}
+
+static int cmdtest_helper(struct comedi_cmd * cmd,
+ unsigned int start_src,
+ unsigned int scan_begin_src,
+ unsigned int convert_src,
+ unsigned int scan_end_src, unsigned int stop_src)
+{
+ int err = 0;
+ int tmp;
+
+ tmp = cmd->start_src;
+ cmd->start_src &= start_src;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= scan_begin_src;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= convert_src;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= scan_end_src;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= stop_src;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ return err;
+}
+
+static int timer_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int start_src = 0;
+
+ if (s->type == COMEDI_SUBD_AO)
+ start_src = TRIG_INT;
+ else
+ start_src = TRIG_NOW;
+
+ err = cmdtest_helper(cmd, start_src, /* start_src */
+ TRIG_TIMER | TRIG_FOLLOW, /* scan_begin_src */
+ TRIG_NOW | TRIG_TIMER, /* convert_src */
+ TRIG_COUNT, /* scan_end_src */
+ TRIG_COUNT | TRIG_NONE); /* stop_src */
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually
+ * compatible */
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+ if (cmd->scan_begin_src == TRIG_FOLLOW
+ && cmd->convert_src != TRIG_TIMER)
+ err++;
+ if (cmd->convert_src == TRIG_NOW && cmd->scan_begin_src != TRIG_TIMER)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+ // limit frequency, this is fairly arbitrary
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < SPEED_LIMIT) {
+ cmd->scan_begin_arg = SPEED_LIMIT;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < SPEED_LIMIT) {
+ cmd->convert_arg = SPEED_LIMIT;
+ err++;
+ }
+ }
+ // make sure conversion and scan frequencies are compatible
+ if (cmd->convert_src == TRIG_TIMER && cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->convert_arg * cmd->scan_end_arg > cmd->scan_begin_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+ if (err)
+ return 3;
+
+ /* step 4: fix up and arguments */
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int timer_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int ret;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ /* hack attack: drivers are not supposed to do this: */
+ dev->rt = 1;
+
+ // make sure tasks have finished cleanup of last struct comedi_cmd
+ if (devpriv->rt_task_active || devpriv->scan_task_active)
+ return -EBUSY;
+
+ ret = comedi_lock(devpriv->device, devpriv->subd);
+ if (ret < 0) {
+ comedi_error(dev, "failed to obtain lock");
+ return ret;
+ }
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ devpriv->scan_period = nano2count(cmd->scan_begin_arg);
+ break;
+ case TRIG_FOLLOW:
+ devpriv->scan_period =
+ nano2count(cmd->convert_arg * cmd->scan_end_arg);
+ break;
+ default:
+ comedi_error(dev, "bug setting scan period!");
+ return -1;
+ break;
+ }
+ switch (cmd->convert_src) {
+ case TRIG_TIMER:
+ devpriv->convert_period = nano2count(cmd->convert_arg);
+ break;
+ case TRIG_NOW:
+ devpriv->convert_period = 1;
+ break;
+ default:
+ comedi_error(dev, "bug setting conversion period!");
+ return -1;
+ break;
+ }
+
+ if (cmd->start_src == TRIG_NOW)
+ return timer_start_cmd(dev, s);
+
+ s->async->inttrig = timer_inttrig;
+
+ return 0;
+}
+
+static int timer_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trig_num)
+{
+ if (trig_num != 0)
+ return -EINVAL;
+
+ s->async->inttrig = NULL;
+
+ return timer_start_cmd(dev, s);
+}
+
+static int timer_start_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ RTIME now, delay, period;
+ int ret;
+
+ devpriv->stop = 0;
+ s->async->events = 0;
+
+ if (cmd->start_src == TRIG_NOW)
+ delay = nano2count(cmd->start_arg);
+ else
+ delay = 0;
+
+ now = rt_get_time();
+ /* Using 'period' this way gets around some weird bug in gcc-2.95.2
+ * that generates the compile error 'internal error--unrecognizable insn'
+ * when rt_task_make_period() is called (observed with rtlinux-3.1, linux-2.2.19).
+ * - fmhess */
+ period = devpriv->scan_period;
+ ret = rt_task_make_periodic(devpriv->rt_task, now + delay, period);
+ if (ret < 0) {
+ comedi_error(dev, "error starting rt_task");
+ return ret;
+ }
+ return 0;
+}
+
+static int timer_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ struct comedi_subdevice *s, *emul_s;
+ struct comedi_device *emul_dev;
+ /* These should probably be devconfig options[] */
+ const int timer_priority = 4;
+ const int scan_priority = timer_priority + 1;
+ char path[20];
+
+ printk("comedi%d: timer: ", dev->minor);
+
+ dev->board_name = "timer";
+
+ if ((ret = alloc_subdevices(dev, 1)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct timer_private))) < 0)
+ return ret;
+
+ sprintf(path, "/dev/comedi%d", it->options[0]);
+ devpriv->device = comedi_open(path);
+ devpriv->subd = it->options[1];
+
+ printk("emulating commands for minor %i, subdevice %d\n",
+ it->options[0], devpriv->subd);
+
+ emul_dev = devpriv->device;
+ emul_s = emul_dev->subdevices + devpriv->subd;
+
+ // input or output subdevice
+ s = dev->subdevices + 0;
+ s->type = emul_s->type;
+ s->subdev_flags = emul_s->subdev_flags; /* SDF_GROUND (to fool check_driver) */
+ s->n_chan = emul_s->n_chan;
+ s->len_chanlist = 1024;
+ s->do_cmd = timer_cmd;
+ s->do_cmdtest = timer_cmdtest;
+ s->cancel = timer_cancel;
+ s->maxdata = emul_s->maxdata;
+ s->range_table = emul_s->range_table;
+ s->range_table_list = emul_s->range_table_list;
+ switch (emul_s->type) {
+ case COMEDI_SUBD_AI:
+ s->insn_read = timer_insn;
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ devpriv->io_function = timer_data_read;
+ break;
+ case COMEDI_SUBD_AO:
+ s->insn_write = timer_insn;
+ s->insn_read = timer_insn;
+ dev->write_subdev = s;
+ s->subdev_flags |= SDF_CMD_WRITE;
+ devpriv->io_function = timer_data_write;
+ break;
+ case COMEDI_SUBD_DIO:
+ s->insn_write = timer_insn;
+ s->insn_read = timer_insn;
+ s->insn_bits = timer_insn;
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ devpriv->io_function = timer_dio_read;
+ break;
+ default:
+ comedi_error(dev, "failed to determine subdevice type!");
+ return -EINVAL;
+ }
+
+ rt_set_oneshot_mode();
+ start_rt_timer(1);
+ devpriv->timer_running = 1;
+
+ devpriv->rt_task = kzalloc(sizeof(RT_TASK), GFP_KERNEL);
+
+ // initialize real-time tasks
+ ret = rt_task_init(devpriv->rt_task, timer_task_func,
+ (comedi_rt_task_context_t) dev, 3000, timer_priority, 0, 0);
+ if (ret < 0) {
+ comedi_error(dev, "error initalizing rt_task");
+ kfree(devpriv->rt_task);
+ devpriv->rt_task = 0;
+ return ret;
+ }
+
+ devpriv->scan_task = kzalloc(sizeof(RT_TASK), GFP_KERNEL);
+
+ ret = rt_task_init(devpriv->scan_task, scan_task_func,
+ (comedi_rt_task_context_t) dev, 3000, scan_priority, 0, 0);
+ if (ret < 0) {
+ comedi_error(dev, "error initalizing scan_task");
+ kfree(devpriv->scan_task);
+ devpriv->scan_task = 0;
+ return ret;
+ }
+
+ return 1;
+}
+
+// free allocated resources
+static int timer_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: timer: remove\n", dev->minor);
+
+ if (devpriv) {
+ if (devpriv->rt_task) {
+ rt_task_delete(devpriv->rt_task);
+ kfree(devpriv->rt_task);
+ }
+ if (devpriv->scan_task) {
+ rt_task_delete(devpriv->scan_task);
+ kfree(devpriv->scan_task);
+ }
+ if (devpriv->timer_running)
+ stop_rt_timer();
+ if (devpriv->device)
+ comedi_close(devpriv->device);
+ }
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c
index 4b4c37d0748..e679328a4f8 100644
--- a/drivers/staging/comedi/drivers/comedi_test.c
+++ b/drivers/staging/comedi/drivers/comedi_test.c
@@ -89,13 +89,13 @@ struct waveform_private {
unsigned int scan_period; /* scan period in usec */
unsigned int convert_period; /* conversion period in usec */
unsigned timer_running:1;
- lsampl_t ao_loopbacks[N_CHANS];
+ unsigned int ao_loopbacks[N_CHANS];
};
#define devpriv ((struct waveform_private *)dev->private)
-static int waveform_attach(comedi_device *dev, comedi_devconfig *it);
-static int waveform_detach(comedi_device *dev);
-static comedi_driver driver_waveform = {
+static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int waveform_detach(struct comedi_device *dev);
+static struct comedi_driver driver_waveform = {
.driver_name = "comedi_test",
.module = THIS_MODULE,
.attach = waveform_attach,
@@ -107,28 +107,28 @@ static comedi_driver driver_waveform = {
COMEDI_INITCLEANUP(driver_waveform);
-static int waveform_ai_cmdtest(comedi_device *dev, comedi_subdevice *s,
- comedi_cmd *cmd);
-static int waveform_ai_cmd(comedi_device *dev, comedi_subdevice *s);
-static int waveform_ai_cancel(comedi_device *dev, comedi_subdevice *s);
-static int waveform_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data);
-static int waveform_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data);
-static sampl_t fake_sawtooth(comedi_device *dev, unsigned int range,
+static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd);
+static int waveform_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
+static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
+static int waveform_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int waveform_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static short fake_sawtooth(struct comedi_device *dev, unsigned int range,
unsigned long current_time);
-static sampl_t fake_squarewave(comedi_device *dev, unsigned int range,
+static short fake_squarewave(struct comedi_device *dev, unsigned int range,
unsigned long current_time);
-static sampl_t fake_flatline(comedi_device *dev, unsigned int range,
+static short fake_flatline(struct comedi_device *dev, unsigned int range,
unsigned long current_time);
-static sampl_t fake_waveform(comedi_device *dev, unsigned int channel,
+static short fake_waveform(struct comedi_device *dev, unsigned int channel,
unsigned int range, unsigned long current_time);
/* 1000 nanosec in a microsec */
static const int nano_per_micro = 1000;
/* fake analog input ranges */
-static const comedi_lrange waveform_ai_ranges = {
+static const struct comedi_lrange waveform_ai_ranges = {
2,
{
BIP_RANGE(10),
@@ -143,9 +143,9 @@ static const comedi_lrange waveform_ai_ranges = {
*/
static void waveform_ai_interrupt(unsigned long arg)
{
- comedi_device *dev = (comedi_device *) arg;
- comedi_async *async = dev->read_subdev->async;
- comedi_cmd *cmd = &async->cmd;
+ struct comedi_device *dev = (struct comedi_device *) arg;
+ struct comedi_async *async = dev->read_subdev->async;
+ struct comedi_cmd *cmd = &async->cmd;
unsigned int i, j;
/* all times in microsec */
unsigned long elapsed_time;
@@ -192,9 +192,9 @@ static void waveform_ai_interrupt(unsigned long arg)
comedi_event(dev, dev->read_subdev);
}
-static int waveform_attach(comedi_device *dev, comedi_devconfig *it)
+static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
int amplitude = it->options[0];
int period = it->options[1];
int i;
@@ -259,7 +259,7 @@ static int waveform_attach(comedi_device *dev, comedi_devconfig *it)
return 1;
}
-static int waveform_detach(comedi_device *dev)
+static int waveform_detach(struct comedi_device *dev)
{
printk("comedi%d: comedi_test: remove\n", dev->minor);
@@ -269,8 +269,8 @@ static int waveform_detach(comedi_device *dev)
return 0;
}
-static int waveform_ai_cmdtest(comedi_device *dev, comedi_subdevice *s,
- comedi_cmd *cmd)
+static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
int err = 0;
int tmp;
@@ -397,9 +397,9 @@ static int waveform_ai_cmdtest(comedi_device *dev, comedi_subdevice *s,
return 0;
}
-static int waveform_ai_cmd(comedi_device *dev, comedi_subdevice *s)
+static int waveform_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->async->cmd;
+ struct comedi_cmd *cmd = &s->async->cmd;
if (cmd->flags & TRIG_RT) {
comedi_error(dev,
@@ -429,20 +429,20 @@ static int waveform_ai_cmd(comedi_device *dev, comedi_subdevice *s)
return 0;
}
-static int waveform_ai_cancel(comedi_device *dev, comedi_subdevice *s)
+static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
devpriv->timer_running = 0;
del_timer(&devpriv->timer);
return 0;
}
-static sampl_t fake_sawtooth(comedi_device *dev, unsigned int range_index,
+static short fake_sawtooth(struct comedi_device *dev, unsigned int range_index,
unsigned long current_time)
{
- comedi_subdevice *s = dev->read_subdev;
+ struct comedi_subdevice *s = dev->read_subdev;
unsigned int offset = s->maxdata / 2;
u64 value;
- const comedi_krange *krange = &s->range_table->range[range_index];
+ const struct comedi_krange *krange = &s->range_table->range[range_index];
u64 binary_amplitude;
binary_amplitude = s->maxdata;
@@ -457,13 +457,13 @@ static sampl_t fake_sawtooth(comedi_device *dev, unsigned int range_index,
return offset + value;
}
-static sampl_t fake_squarewave(comedi_device *dev, unsigned int range_index,
+static short fake_squarewave(struct comedi_device *dev, unsigned int range_index,
unsigned long current_time)
{
- comedi_subdevice *s = dev->read_subdev;
+ struct comedi_subdevice *s = dev->read_subdev;
unsigned int offset = s->maxdata / 2;
u64 value;
- const comedi_krange *krange = &s->range_table->range[range_index];
+ const struct comedi_krange *krange = &s->range_table->range[range_index];
current_time %= devpriv->usec_period;
value = s->maxdata;
@@ -476,14 +476,14 @@ static sampl_t fake_squarewave(comedi_device *dev, unsigned int range_index,
return offset + value;
}
-static sampl_t fake_flatline(comedi_device *dev, unsigned int range_index,
+static short fake_flatline(struct comedi_device *dev, unsigned int range_index,
unsigned long current_time)
{
return dev->read_subdev->maxdata / 2;
}
/* generates a different waveform depending on what channel is read */
-static sampl_t fake_waveform(comedi_device *dev, unsigned int channel,
+static short fake_waveform(struct comedi_device *dev, unsigned int channel,
unsigned int range, unsigned long current_time)
{
enum {
@@ -504,8 +504,8 @@ static sampl_t fake_waveform(comedi_device *dev, unsigned int channel,
return fake_flatline(dev, range, current_time);
}
-static int waveform_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int waveform_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i, chan = CR_CHAN(insn->chanspec);
@@ -515,8 +515,8 @@ static int waveform_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
return insn->n;
}
-static int waveform_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int waveform_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i, chan = CR_CHAN(insn->chanspec);
diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c
new file mode 100644
index 00000000000..1f194a0a45d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/contec_pci_dio.c
@@ -0,0 +1,230 @@
+/*
+ comedi/drivers/contec_pci_dio.c
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: contec_pci_dio
+Description: Contec PIO1616L digital I/O board
+Devices: [Contec] PIO1616L (contec_pci_dio)
+Author: Stefano Rivoir <s.rivoir@gts.it>
+Updated: Wed, 27 Jun 2007 13:00:06 +0100
+Status: works
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+enum contec_model {
+ PIO1616L = 0,
+};
+
+struct contec_board {
+ const char *name;
+ int model;
+ int in_ports;
+ int out_ports;
+ int in_offs;
+ int out_offs;
+ int out_boffs;
+};
+static const struct contec_board contec_boards[] = {
+ {"PIO1616L", PIO1616L, 16, 16, 0, 2, 10},
+};
+
+#define PCI_DEVICE_ID_PIO1616L 0x8172
+static DEFINE_PCI_DEVICE_TABLE(contec_pci_table) = {
+ {PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L, PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0, PIO1616L},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, contec_pci_table);
+
+#define thisboard ((const struct contec_board *)dev->board_ptr)
+
+struct contec_private {
+ int data;
+
+ struct pci_dev *pci_dev;
+
+};
+
+#define devpriv ((struct contec_private *)dev->private)
+
+static int contec_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int contec_detach(struct comedi_device * dev);
+static struct comedi_driver driver_contec = {
+ driver_name:"contec_pci_dio",
+ module:THIS_MODULE,
+ attach:contec_attach,
+ detach:contec_detach,
+};
+
+/* Classic digital IO */
+static int contec_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int contec_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+#if 0
+static int contec_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+
+static int contec_ns_to_timer(unsigned int *ns, int round);
+#endif
+
+static int contec_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev;
+ struct comedi_subdevice *s;
+
+ printk("comedi%d: contec: ", dev->minor);
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_private(dev, sizeof(struct contec_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+
+ if (pcidev->vendor == PCI_VENDOR_ID_CONTEC &&
+ pcidev->device == PCI_DEVICE_ID_PIO1616L) {
+ if (it->options[0] || it->options[1]) {
+ /* Check bus and slot. */
+ if (it->options[0] != pcidev->bus->number ||
+ it->options[1] !=
+ PCI_SLOT(pcidev->devfn)) {
+ continue;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+ if (comedi_pci_enable(pcidev, "contec_pci_dio")) {
+ printk("error enabling PCI device and request regions!\n");
+ return -EIO;
+ }
+ dev->iobase = pci_resource_start(pcidev, 0);
+ printk(" base addr %lx ", dev->iobase);
+
+ dev->board_ptr = contec_boards + 0;
+
+ s = dev->subdevices + 0;
+
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = contec_di_insn_bits;
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = contec_do_insn_bits;
+
+ printk("attached\n");
+
+ return 1;
+ }
+ }
+
+ printk("card not present!\n");
+
+ return -EIO;
+}
+
+static int contec_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: contec: remove\n", dev->minor);
+
+ if (devpriv && devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
+ return 0;
+}
+
+#if 0
+static int contec_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ printk("contec_cmdtest called\n");
+ return 0;
+}
+
+static int contec_ns_to_timer(unsigned int *ns, int round)
+{
+ return *ns;
+}
+#endif
+
+static int contec_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ printk("contec_do_insn_bits called\n");
+ printk(" data: %d %d\n", data[0], data[1]);
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ rt_printk(" out: %d on %lx\n", s->state,
+ dev->iobase + thisboard->out_offs);
+ outw(s->state, dev->iobase + thisboard->out_offs);
+ }
+ return 2;
+}
+
+static int contec_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ rt_printk("contec_di_insn_bits called\n");
+ rt_printk(" data: %d %d\n", data[0], data[1]);
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inw(dev->iobase + thisboard->in_offs);
+
+ return 2;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_contec, contec_pci_table);
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c
new file mode 100644
index 00000000000..3b8444f09f2
--- /dev/null
+++ b/drivers/staging/comedi/drivers/daqboard2000.c
@@ -0,0 +1,877 @@
+/*
+ comedi/drivers/daqboard2000.c
+ hardware driver for IOtech DAQboard/2000
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ 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.
+
+ */
+/*
+Driver: daqboard2000
+Description: IOTech DAQBoard/2000
+Author: Anders Blomdell <anders.blomdell@control.lth.se>
+Status: works
+Updated: Mon, 14 Apr 2008 15:28:52 +0100
+Devices: [IOTech] DAQBoard/2000 (daqboard2000)
+
+Much of the functionality of this driver was determined from reading
+the source code for the Windows driver.
+
+The FPGA on the board requires initialization code, which can
+be loaded by comedi_config using the -i
+option. The initialization code is available from http://www.comedi.org
+in the comedi_nonfree_firmware tarball.
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+*/
+/*
+ This card was obviously never intended to leave the Windows world,
+ since it lacked all kind of hardware documentation (except for cable
+ pinouts, plug and pray has something to catch up with yet).
+
+ With some help from our swedish distributor, we got the Windows sourcecode
+ for the card, and here are the findings so far.
+
+ 1. A good document that describes the PCI interface chip is found at:
+ http://plx.plxtech.com/download/9080/databook/9080db-106.pdf
+
+ 2. The initialization done so far is:
+ a. program the FPGA (windows code sans a lot of error messages)
+ b.
+
+ 3. Analog out seems to work OK with DAC's disabled, if DAC's are enabled,
+ you have to output values to all enabled DAC's until result appears, I
+ guess that it has something to do with pacer clocks, but the source
+ gives me no clues. I'll keep it simple so far.
+
+ 4. Analog in.
+ Each channel in the scanlist seems to be controlled by four
+ control words:
+
+ Word0:
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! | | | ! | | | ! | | | ! | | | !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Word1:
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! | | | ! | | | ! | | | ! | | | !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | | | | | | |
+ +------+------+ | | | | +-- Digital input (??)
+ | | | | +---- 10 us settling time
+ | | | +------ Suspend acquisition (last to scan)
+ | | +-------- Simultaneous sample and hold
+ | +---------- Signed data format
+ +------------------------- Correction offset low
+
+ Word2:
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! | | | ! | | | ! | | | ! | | | !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | | | | | | | | | |
+ +-----+ +--+--+ +++ +++ +--+--+
+ | | | | +----- Expansion channel
+ | | | +----------- Expansion gain
+ | | +--------------- Channel (low)
+ | +--------------------- Correction offset high
+ +----------------------------- Correction gain low
+ Word3:
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! | | | ! | | | ! | | | ! | | | !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | | | | | | | | |
+ +------+------+ | | +-+-+ | | +-- Low bank enable
+ | | | | | +---- High bank enable
+ | | | | +------ Hi/low select
+ | | | +---------- Gain (1,?,2,4,8,16,32,64)
+ | | +-------------- differential/single ended
+ | +---------------- Unipolar
+ +------------------------- Correction gain high
+
+
+
+ 999. The card seems to have an incredible amount of capabilities, but
+ trying to reverse engineer them from the Windows source is beyond my
+ patience.
+
+
+ */
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "8255.h"
+
+#define DAQBOARD2000_SUBSYSTEM_IDS2 0x00021616 /* Daqboard/2000 - 2 Dacs */
+#define DAQBOARD2000_SUBSYSTEM_IDS4 0x00041616 /* Daqboard/2000 - 4 Dacs */
+
+#define DAQBOARD2000_DAQ_SIZE 0x1002
+#define DAQBOARD2000_PLX_SIZE 0x100
+
+// Initialization bits for the Serial EEPROM Control Register
+#define DAQBOARD2000_SECRProgPinHi 0x8001767e
+#define DAQBOARD2000_SECRProgPinLo 0x8000767e
+#define DAQBOARD2000_SECRLocalBusHi 0xc000767e
+#define DAQBOARD2000_SECRLocalBusLo 0x8000767e
+#define DAQBOARD2000_SECRReloadHi 0xa000767e
+#define DAQBOARD2000_SECRReloadLo 0x8000767e
+
+// SECR status bits
+#define DAQBOARD2000_EEPROM_PRESENT 0x10000000
+
+// CPLD status bits
+#define DAQBOARD2000_CPLD_INIT 0x0002
+#define DAQBOARD2000_CPLD_DONE 0x0004
+
+// Available ranges
+static const struct comedi_lrange range_daqboard2000_ai = { 13, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ RANGE(-0.625, 0.625),
+ RANGE(-0.3125, 0.3125),
+ RANGE(-0.156, 0.156),
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 2.5),
+ RANGE(0, 1.25),
+ RANGE(0, 0.625),
+ RANGE(0, 0.3125)
+ }
+};
+
+static const struct comedi_lrange range_daqboard2000_ao = { 1, {
+ RANGE(-10, 10)
+ }
+};
+
+struct daqboard2000_hw {
+ volatile u16 acqControl; // 0x00
+ volatile u16 acqScanListFIFO; // 0x02
+ volatile u32 acqPacerClockDivLow; // 0x04
+
+ volatile u16 acqScanCounter; // 0x08
+ volatile u16 acqPacerClockDivHigh; // 0x0a
+ volatile u16 acqTriggerCount; // 0x0c
+ volatile u16 fill2; // 0x0e
+ volatile u16 acqResultsFIFO; // 0x10
+ volatile u16 fill3; // 0x12
+ volatile u16 acqResultsShadow; // 0x14
+ volatile u16 fill4; // 0x16
+ volatile u16 acqAdcResult; // 0x18
+ volatile u16 fill5; // 0x1a
+ volatile u16 dacScanCounter; // 0x1c
+ volatile u16 fill6; // 0x1e
+
+ volatile u16 dacControl; // 0x20
+ volatile u16 fill7; // 0x22
+ volatile s16 dacFIFO; // 0x24
+ volatile u16 fill8[2]; // 0x26
+ volatile u16 dacPacerClockDiv; // 0x2a
+ volatile u16 refDacs; // 0x2c
+ volatile u16 fill9; // 0x2e
+
+ volatile u16 dioControl; // 0x30
+ volatile s16 dioP3hsioData; // 0x32
+ volatile u16 dioP3Control; // 0x34
+ volatile u16 calEepromControl; // 0x36
+ volatile s16 dacSetting[4]; // 0x38
+ volatile s16 dioP2ExpansionIO8Bit[32]; // 0x40
+
+ volatile u16 ctrTmrControl; // 0x80
+ volatile u16 fill10[3]; // 0x82
+ volatile s16 ctrInput[4]; // 0x88
+ volatile u16 fill11[8]; // 0x90
+ volatile u16 timerDivisor[2]; // 0xa0
+ volatile u16 fill12[6]; // 0xa4
+
+ volatile u16 dmaControl; // 0xb0
+ volatile u16 trigControl; // 0xb2
+ volatile u16 fill13[2]; // 0xb4
+ volatile u16 calEeprom; // 0xb8
+ volatile u16 acqDigitalMark; // 0xba
+ volatile u16 trigDacs; // 0xbc
+ volatile u16 fill14; // 0xbe
+ volatile s16 dioP2ExpansionIO16Bit[32]; // 0xc0
+};
+
+/* Scan Sequencer programming */
+#define DAQBOARD2000_SeqStartScanList 0x0011
+#define DAQBOARD2000_SeqStopScanList 0x0010
+
+// Prepare for acquisition
+#define DAQBOARD2000_AcqResetScanListFifo 0x0004
+#define DAQBOARD2000_AcqResetResultsFifo 0x0002
+#define DAQBOARD2000_AcqResetConfigPipe 0x0001
+
+// Acqusition status bits
+#define DAQBOARD2000_AcqResultsFIFOMore1Sample 0x0001
+#define DAQBOARD2000_AcqResultsFIFOHasValidData 0x0002
+#define DAQBOARD2000_AcqResultsFIFOOverrun 0x0004
+#define DAQBOARD2000_AcqLogicScanning 0x0008
+#define DAQBOARD2000_AcqConfigPipeFull 0x0010
+#define DAQBOARD2000_AcqScanListFIFOEmpty 0x0020
+#define DAQBOARD2000_AcqAdcNotReady 0x0040
+#define DAQBOARD2000_ArbitrationFailure 0x0080
+#define DAQBOARD2000_AcqPacerOverrun 0x0100
+#define DAQBOARD2000_DacPacerOverrun 0x0200
+#define DAQBOARD2000_AcqHardwareError 0x01c0
+
+// Scan Sequencer programming
+#define DAQBOARD2000_SeqStartScanList 0x0011
+#define DAQBOARD2000_SeqStopScanList 0x0010
+
+/* Pacer Clock Control */
+#define DAQBOARD2000_AdcPacerInternal 0x0030
+#define DAQBOARD2000_AdcPacerExternal 0x0032
+#define DAQBOARD2000_AdcPacerEnable 0x0031
+#define DAQBOARD2000_AdcPacerEnableDacPacer 0x0034
+#define DAQBOARD2000_AdcPacerDisable 0x0030
+#define DAQBOARD2000_AdcPacerNormalMode 0x0060
+#define DAQBOARD2000_AdcPacerCompatibilityMode 0x0061
+#define DAQBOARD2000_AdcPacerInternalOutEnable 0x0008
+#define DAQBOARD2000_AdcPacerExternalRising 0x0100
+
+// DAC status
+#define DAQBOARD2000_DacFull 0x0001
+#define DAQBOARD2000_RefBusy 0x0002
+#define DAQBOARD2000_TrgBusy 0x0004
+#define DAQBOARD2000_CalBusy 0x0008
+#define DAQBOARD2000_Dac0Busy 0x0010
+#define DAQBOARD2000_Dac1Busy 0x0020
+#define DAQBOARD2000_Dac2Busy 0x0040
+#define DAQBOARD2000_Dac3Busy 0x0080
+
+// DAC control
+#define DAQBOARD2000_Dac0Enable 0x0021
+#define DAQBOARD2000_Dac1Enable 0x0031
+#define DAQBOARD2000_Dac2Enable 0x0041
+#define DAQBOARD2000_Dac3Enable 0x0051
+#define DAQBOARD2000_DacEnableBit 0x0001
+#define DAQBOARD2000_Dac0Disable 0x0020
+#define DAQBOARD2000_Dac1Disable 0x0030
+#define DAQBOARD2000_Dac2Disable 0x0040
+#define DAQBOARD2000_Dac3Disable 0x0050
+#define DAQBOARD2000_DacResetFifo 0x0004
+#define DAQBOARD2000_DacPatternDisable 0x0060
+#define DAQBOARD2000_DacPatternEnable 0x0061
+#define DAQBOARD2000_DacSelectSignedData 0x0002
+#define DAQBOARD2000_DacSelectUnsignedData 0x0000
+
+/* Trigger Control */
+#define DAQBOARD2000_TrigAnalog 0x0000
+#define DAQBOARD2000_TrigTTL 0x0010
+#define DAQBOARD2000_TrigTransHiLo 0x0004
+#define DAQBOARD2000_TrigTransLoHi 0x0000
+#define DAQBOARD2000_TrigAbove 0x0000
+#define DAQBOARD2000_TrigBelow 0x0004
+#define DAQBOARD2000_TrigLevelSense 0x0002
+#define DAQBOARD2000_TrigEdgeSense 0x0000
+#define DAQBOARD2000_TrigEnable 0x0001
+#define DAQBOARD2000_TrigDisable 0x0000
+
+// Reference Dac Selection
+#define DAQBOARD2000_PosRefDacSelect 0x0100
+#define DAQBOARD2000_NegRefDacSelect 0x0000
+
+static int daqboard2000_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int daqboard2000_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_daqboard2000 = {
+ driver_name:"daqboard2000",
+ module:THIS_MODULE,
+ attach:daqboard2000_attach,
+ detach:daqboard2000_detach,
+};
+
+struct daq200_boardtype {
+ const char *name;
+ int id;
+};
+static const struct daq200_boardtype boardtypes[] = {
+ {"ids2", DAQBOARD2000_SUBSYSTEM_IDS2},
+ {"ids4", DAQBOARD2000_SUBSYSTEM_IDS4},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct daq200_boardtype))
+#define this_board ((const struct daq200_boardtype *)dev->board_ptr)
+
+static DEFINE_PCI_DEVICE_TABLE(daqboard2000_pci_table) = {
+ {0x1616, 0x0409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, daqboard2000_pci_table);
+
+struct daqboard2000_private {
+ enum {
+ card_daqboard_2000
+ } card;
+ struct pci_dev *pci_dev;
+ void *daq;
+ void *plx;
+ int got_regions;
+ unsigned int ao_readback[2];
+};
+
+#define devpriv ((struct daqboard2000_private *)dev->private)
+
+static void writeAcqScanListEntry(struct comedi_device * dev, u16 entry)
+{
+ struct daqboard2000_hw *fpga = devpriv->daq;
+
+// comedi_udelay(4);
+ fpga->acqScanListFIFO = entry & 0x00ff;
+// comedi_udelay(4);
+ fpga->acqScanListFIFO = (entry >> 8) & 0x00ff;
+}
+
+static void setup_sampling(struct comedi_device * dev, int chan, int gain)
+{
+ u16 word0, word1, word2, word3;
+
+ /* Channel 0-7 diff, channel 8-23 single ended */
+ word0 = 0;
+ word1 = 0x0004; /* Last scan */
+ word2 = (chan << 6) & 0x00c0;
+ switch (chan / 4) {
+ case 0:
+ word3 = 0x0001;
+ break;
+ case 1:
+ word3 = 0x0002;
+ break;
+ case 2:
+ word3 = 0x0005;
+ break;
+ case 3:
+ word3 = 0x0006;
+ break;
+ case 4:
+ word3 = 0x0041;
+ break;
+ case 5:
+ word3 = 0x0042;
+ break;
+ default:
+ word3 = 0;
+ break;
+ }
+/*
+ dev->eeprom.correctionDACSE[i][j][k].offset = 0x800;
+ dev->eeprom.correctionDACSE[i][j][k].gain = 0xc00;
+*/
+ /* These should be read from EEPROM */
+ word2 |= 0x0800;
+ word3 |= 0xc000;
+/* printk("%d %4.4x %4.4x %4.4x %4.4x\n", chan, word0, word1, word2, word3);*/
+ writeAcqScanListEntry(dev, word0);
+ writeAcqScanListEntry(dev, word1);
+ writeAcqScanListEntry(dev, word2);
+ writeAcqScanListEntry(dev, word3);
+}
+
+static int daqboard2000_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ struct daqboard2000_hw *fpga = devpriv->daq;
+ int gain, chan, timeout;
+
+ fpga->acqControl =
+ DAQBOARD2000_AcqResetScanListFifo |
+ DAQBOARD2000_AcqResetResultsFifo |
+ DAQBOARD2000_AcqResetConfigPipe;
+
+ /* If pacer clock is not set to some high value (> 10 us), we
+ risk multiple samples to be put into the result FIFO. */
+ fpga->acqPacerClockDivLow = 1000000; /* 1 second, should be long enough */
+ fpga->acqPacerClockDivHigh = 0;
+
+ gain = CR_RANGE(insn->chanspec);
+ chan = CR_CHAN(insn->chanspec);
+
+ /* This doesn't look efficient. I decided to take the conservative
+ * approach when I did the insn conversion. Perhaps it would be
+ * better to have broken it completely, then someone would have been
+ * forced to fix it. --ds */
+ for (i = 0; i < insn->n; i++) {
+ setup_sampling(dev, chan, gain);
+ /* Enable reading from the scanlist FIFO */
+ fpga->acqControl = DAQBOARD2000_SeqStartScanList;
+ for (timeout = 0; timeout < 20; timeout++) {
+ if (fpga->acqControl & DAQBOARD2000_AcqConfigPipeFull) {
+ break;
+ }
+ //comedi_udelay(2);
+ }
+ fpga->acqControl = DAQBOARD2000_AdcPacerEnable;
+ for (timeout = 0; timeout < 20; timeout++) {
+ if (fpga->acqControl & DAQBOARD2000_AcqLogicScanning) {
+ break;
+ }
+ //comedi_udelay(2);
+ }
+ for (timeout = 0; timeout < 20; timeout++) {
+ if (fpga->
+ acqControl &
+ DAQBOARD2000_AcqResultsFIFOHasValidData) {
+ break;
+ }
+ //comedi_udelay(2);
+ }
+ data[i] = fpga->acqResultsFIFO;
+ fpga->acqControl = DAQBOARD2000_AdcPacerDisable;
+ fpga->acqControl = DAQBOARD2000_SeqStopScanList;
+ }
+
+ return i;
+}
+
+static int daqboard2000_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+static int daqboard2000_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ struct daqboard2000_hw *fpga = devpriv->daq;
+ int timeout;
+
+ for (i = 0; i < insn->n; i++) {
+ /*
+ * OK, since it works OK without enabling the DAC's, let's keep
+ * it as simple as possible...
+ */
+ //fpga->dacControl = (chan + 2) * 0x0010 | 0x0001; comedi_udelay(1000);
+ fpga->dacSetting[chan] = data[i];
+ for (timeout = 0; timeout < 20; timeout++) {
+ if ((fpga->dacControl & ((chan + 1) * 0x0010)) == 0) {
+ break;
+ }
+ //comedi_udelay(2);
+ }
+ devpriv->ao_readback[chan] = data[i];
+ /*
+ * Since we never enabled the DAC's, we don't need to disable it...
+ * fpga->dacControl = (chan + 2) * 0x0010 | 0x0000; comedi_udelay(1000);
+ */
+ }
+
+ return i;
+}
+
+static void daqboard2000_resetLocalBus(struct comedi_device * dev)
+{
+ printk("daqboard2000_resetLocalBus\n");
+ writel(DAQBOARD2000_SECRLocalBusHi, devpriv->plx + 0x6c);
+ comedi_udelay(10000);
+ writel(DAQBOARD2000_SECRLocalBusLo, devpriv->plx + 0x6c);
+ comedi_udelay(10000);
+}
+
+static void daqboard2000_reloadPLX(struct comedi_device * dev)
+{
+ printk("daqboard2000_reloadPLX\n");
+ writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c);
+ comedi_udelay(10000);
+ writel(DAQBOARD2000_SECRReloadHi, devpriv->plx + 0x6c);
+ comedi_udelay(10000);
+ writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c);
+ comedi_udelay(10000);
+}
+
+static void daqboard2000_pulseProgPin(struct comedi_device * dev)
+{
+ printk("daqboard2000_pulseProgPin 1\n");
+ writel(DAQBOARD2000_SECRProgPinHi, devpriv->plx + 0x6c);
+ comedi_udelay(10000);
+ writel(DAQBOARD2000_SECRProgPinLo, devpriv->plx + 0x6c);
+ comedi_udelay(10000); /* Not in the original code, but I like symmetry... */
+}
+
+static int daqboard2000_pollCPLD(struct comedi_device * dev, int mask)
+{
+ int result = 0;
+ int i;
+ int cpld;
+
+ /* timeout after 50 tries -> 5ms */
+ for (i = 0; i < 50; i++) {
+ cpld = readw(devpriv->daq + 0x1000);
+ if ((cpld & mask) == mask) {
+ result = 1;
+ break;
+ }
+ comedi_udelay(100);
+ }
+ comedi_udelay(5);
+ return result;
+}
+
+static int daqboard2000_writeCPLD(struct comedi_device * dev, int data)
+{
+ int result = 0;
+
+ comedi_udelay(10);
+ writew(data, devpriv->daq + 0x1000);
+ if ((readw(devpriv->daq + 0x1000) & DAQBOARD2000_CPLD_INIT) ==
+ DAQBOARD2000_CPLD_INIT) {
+ result = 1;
+ }
+ return result;
+}
+
+static int initialize_daqboard2000(struct comedi_device * dev,
+ unsigned char *cpld_array, int len)
+{
+ int result = -EIO;
+ /* Read the serial EEPROM control register */
+ int secr;
+ int retry;
+ int i;
+
+ /* Check to make sure the serial eeprom is present on the board */
+ secr = readl(devpriv->plx + 0x6c);
+ if (!(secr & DAQBOARD2000_EEPROM_PRESENT)) {
+#ifdef DEBUG_EEPROM
+ printk("no serial eeprom\n");
+#endif
+ return -EIO;
+ }
+
+ for (retry = 0; retry < 3; retry++) {
+#ifdef DEBUG_EEPROM
+ printk("Programming EEPROM try %x\n", retry);
+#endif
+
+ daqboard2000_resetLocalBus(dev);
+ daqboard2000_reloadPLX(dev);
+ daqboard2000_pulseProgPin(dev);
+ if (daqboard2000_pollCPLD(dev, DAQBOARD2000_CPLD_INIT)) {
+ for (i = 0; i < len; i++) {
+ if (cpld_array[i] == 0xff
+ && cpld_array[i + 1] == 0x20) {
+#ifdef DEBUG_EEPROM
+ printk("Preamble found at %d\n", i);
+#endif
+ break;
+ }
+ }
+ for (; i < len; i += 2) {
+ int data =
+ (cpld_array[i] << 8) + cpld_array[i +
+ 1];
+ if (!daqboard2000_writeCPLD(dev, data)) {
+ break;
+ }
+ }
+ if (i >= len) {
+#ifdef DEBUG_EEPROM
+ printk("Programmed\n");
+#endif
+ daqboard2000_resetLocalBus(dev);
+ daqboard2000_reloadPLX(dev);
+ result = 0;
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+static void daqboard2000_adcStopDmaTransfer(struct comedi_device * dev)
+{
+/* printk("Implement: daqboard2000_adcStopDmaTransfer\n");*/
+}
+
+static void daqboard2000_adcDisarm(struct comedi_device * dev)
+{
+ struct daqboard2000_hw *fpga = devpriv->daq;
+
+ /* Disable hardware triggers */
+ comedi_udelay(2);
+ fpga->trigControl = DAQBOARD2000_TrigAnalog | DAQBOARD2000_TrigDisable;
+ comedi_udelay(2);
+ fpga->trigControl = DAQBOARD2000_TrigTTL | DAQBOARD2000_TrigDisable;
+
+ /* Stop the scan list FIFO from loading the configuration pipe */
+ comedi_udelay(2);
+ fpga->acqControl = DAQBOARD2000_SeqStopScanList;
+
+ /* Stop the pacer clock */
+ comedi_udelay(2);
+ fpga->acqControl = DAQBOARD2000_AdcPacerDisable;
+
+ /* Stop the input dma (abort channel 1) */
+ daqboard2000_adcStopDmaTransfer(dev);
+}
+
+static void daqboard2000_activateReferenceDacs(struct comedi_device * dev)
+{
+ struct daqboard2000_hw *fpga = devpriv->daq;
+ int timeout;
+
+ // Set the + reference dac value in the FPGA
+ fpga->refDacs = 0x80 | DAQBOARD2000_PosRefDacSelect;
+ for (timeout = 0; timeout < 20; timeout++) {
+ if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0) {
+ break;
+ }
+ comedi_udelay(2);
+ }
+/* printk("DAQBOARD2000_PosRefDacSelect %d\n", timeout);*/
+
+ // Set the - reference dac value in the FPGA
+ fpga->refDacs = 0x80 | DAQBOARD2000_NegRefDacSelect;
+ for (timeout = 0; timeout < 20; timeout++) {
+ if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0) {
+ break;
+ }
+ comedi_udelay(2);
+ }
+/* printk("DAQBOARD2000_NegRefDacSelect %d\n", timeout);*/
+}
+
+static void daqboard2000_initializeCtrs(struct comedi_device * dev)
+{
+/* printk("Implement: daqboard2000_initializeCtrs\n");*/
+}
+
+static void daqboard2000_initializeTmrs(struct comedi_device * dev)
+{
+/* printk("Implement: daqboard2000_initializeTmrs\n");*/
+}
+
+static void daqboard2000_dacDisarm(struct comedi_device * dev)
+{
+/* printk("Implement: daqboard2000_dacDisarm\n");*/
+}
+
+static void daqboard2000_initializeAdc(struct comedi_device * dev)
+{
+ daqboard2000_adcDisarm(dev);
+ daqboard2000_activateReferenceDacs(dev);
+ daqboard2000_initializeCtrs(dev);
+ daqboard2000_initializeTmrs(dev);
+}
+
+static void daqboard2000_initializeDac(struct comedi_device * dev)
+{
+ daqboard2000_dacDisarm(dev);
+}
+
+/*
+The test command, REMOVE!!:
+
+rmmod daqboard2000 ; rmmod comedi; make install ; modprobe daqboard2000; /usr/sbin/comedi_config /dev/comedi0 daqboard/2000 ; tail -40 /var/log/messages
+*/
+
+static int daqboard2000_8255_cb(int dir, int port, int data,
+ unsigned long ioaddr)
+{
+ int result = 0;
+ if (dir) {
+ writew(data, ((void *)ioaddr) + port * 2);
+ result = 0;
+ } else {
+ result = readw(((void *)ioaddr) + port * 2);
+ }
+/*
+ printk("daqboard2000_8255_cb %x %d %d %2.2x -> %2.2x\n",
+ arg, dir, port, data, result);
+*/
+ return result;
+}
+
+static int daqboard2000_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int result = 0;
+ struct comedi_subdevice *s;
+ struct pci_dev *card = NULL;
+ void *aux_data;
+ unsigned int aux_len;
+ int bus, slot;
+
+ printk("comedi%d: daqboard2000:", dev->minor);
+
+ bus = it->options[0];
+ slot = it->options[1];
+
+ result = alloc_private(dev, sizeof(struct daqboard2000_private));
+ if (result < 0) {
+ return -ENOMEM;
+ }
+ for (card = pci_get_device(0x1616, 0x0409, NULL);
+ card != NULL;
+ card = pci_get_device(0x1616, 0x0409, card)) {
+ if (bus || slot) {
+ /* requested particular bus/slot */
+ if (card->bus->number != bus ||
+ PCI_SLOT(card->devfn) != slot) {
+ continue;
+ }
+ }
+ break; /* found one */
+ }
+ if (!card) {
+ if (bus || slot)
+ printk(" no daqboard2000 found at bus/slot: %d/%d\n",
+ bus, slot);
+ else
+ printk(" no daqboard2000 found\n");
+ return -EIO;
+ } else {
+ u32 id;
+ int i;
+ devpriv->pci_dev = card;
+ id = ((u32) card->subsystem_device << 16) | card->
+ subsystem_vendor;
+ for (i = 0; i < n_boardtypes; i++) {
+ if (boardtypes[i].id == id) {
+ printk(" %s", boardtypes[i].name);
+ dev->board_ptr = boardtypes + i;
+ }
+ }
+ if (!dev->board_ptr) {
+ printk(" unknown subsystem id %08x (pretend it is an ids2)", id);
+ dev->board_ptr = boardtypes;
+ }
+ }
+
+ if ((result = comedi_pci_enable(card, "daqboard2000")) < 0) {
+ printk(" failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+ devpriv->got_regions = 1;
+ devpriv->plx =
+ ioremap(pci_resource_start(card, 0), DAQBOARD2000_PLX_SIZE);
+ devpriv->daq =
+ ioremap(pci_resource_start(card, 2), DAQBOARD2000_DAQ_SIZE);
+ if (!devpriv->plx || !devpriv->daq) {
+ return -ENOMEM;
+ }
+
+ result = alloc_subdevices(dev, 3);
+ if (result < 0)
+ goto out;
+
+ readl(devpriv->plx + 0x6c);
+
+ /*
+ u8 interrupt;
+ Windows code does restore interrupts, but since we don't use them...
+ pci_read_config_byte(card, PCI_INTERRUPT_LINE, &interrupt);
+ printk("Interrupt before is: %x\n", interrupt);
+ */
+
+ aux_data = comedi_aux_data(it->options, 0);
+ aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];
+
+ if (aux_data && aux_len) {
+ result = initialize_daqboard2000(dev, aux_data, aux_len);
+ } else {
+ printk("no FPGA initialization code, aborting\n");
+ result = -EIO;
+ }
+ if (result < 0)
+ goto out;
+ daqboard2000_initializeAdc(dev);
+ daqboard2000_initializeDac(dev);
+ /*
+ Windows code does restore interrupts, but since we don't use them...
+ pci_read_config_byte(card, PCI_INTERRUPT_LINE, &interrupt);
+ printk("Interrupt after is: %x\n", interrupt);
+ */
+
+ dev->iobase = (unsigned long)devpriv->daq;
+
+ dev->board_name = this_board->name;
+
+ s = dev->subdevices + 0;
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 24;
+ s->maxdata = 0xffff;
+ s->insn_read = daqboard2000_ai_insn_read;
+ s->range_table = &range_daqboard2000_ai;
+
+ s = dev->subdevices + 1;
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->maxdata = 0xffff;
+ s->insn_read = daqboard2000_ao_insn_read;
+ s->insn_write = daqboard2000_ao_insn_write;
+ s->range_table = &range_daqboard2000_ao;
+
+ s = dev->subdevices + 2;
+ result = subdev_8255_init(dev, s, daqboard2000_8255_cb,
+ (unsigned long)(dev->iobase + 0x40));
+
+ printk("\n");
+ out:
+ return result;
+}
+
+static int daqboard2000_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: daqboard2000: remove\n", dev->minor);
+
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+
+ if (dev->irq) {
+ free_irq(dev->irq, dev);
+ }
+ if (devpriv) {
+ if (devpriv->daq)
+ iounmap(devpriv->daq);
+ if (devpriv->plx)
+ iounmap(devpriv->plx);
+ if (devpriv->pci_dev) {
+ if (devpriv->got_regions) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+ return 0;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_daqboard2000, daqboard2000_pci_table);
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
new file mode 100644
index 00000000000..e4563331e96
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das08.c
@@ -0,0 +1,1068 @@
+/*
+ comedi/drivers/das08.c
+ DAS08 driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+ Copyright (C) 2004 Salvador E. Tropea <set@users.sf.net> <set@ieee.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*****************************************************************
+
+*/
+/*
+Driver: das08
+Description: DAS-08 compatible boards
+Author: Warren Jasper, ds, Frank Hess
+Devices: [Keithley Metrabyte] DAS08 (isa-das08), [ComputerBoards] DAS08 (isa-das08),
+ DAS08-PGM (das08-pgm),
+ DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh),
+ DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao),
+ DAS08/JR-16-AO (das08jr-16-ao), PCI-DAS08 (das08),
+ PC104-DAS08 (pc104-das08), DAS08/JR/16 (das08jr/16)
+Status: works
+
+This is a rewrite of the das08 and das08jr drivers.
+
+Options (for ISA cards):
+ [0] - base io address
+
+Options (for pci-das08):
+ [0] - bus (optional)
+ [1] = slot (optional)
+
+The das08 driver doesn't support asynchronous commands, since
+the cheap das08 hardware doesn't really support them. The
+comedi_rt_timer driver can be used to emulate commands for this
+driver.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "8255.h"
+#include "das08.h"
+
+#define DRV_NAME "das08"
+
+#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307
+#define PCI_DEVICE_ID_PCIDAS08 0x29
+#define PCIDAS08_SIZE 0x54
+
+// pci configuration registers
+#define INTCSR 0x4c
+#define INTR1_ENABLE 0x1
+#define INTR1_HIGH_POLARITY 0x2
+#define PCI_INTR_ENABLE 0x40
+#define INTR1_EDGE_TRIG 0x100 // requires high polarity
+#define CNTRL 0x50
+#define CNTRL_DIR 0x2
+#define CNTRL_INTR 0x4
+
+/*
+ cio-das08.pdf
+
+ "isa-das08"
+
+ 0 a/d bits 0-3 start 8 bit
+ 1 a/d bits 4-11 start 12 bit
+ 2 eoc, ip1-3, irq, mux op1-4, inte, mux
+ 3 unused unused
+ 4567 8254
+ 89ab 8255
+
+ requires hard-wiring for async ai
+
+*/
+
+#define DAS08_LSB 0
+#define DAS08_MSB 1
+#define DAS08_TRIG_12BIT 1
+#define DAS08_STATUS 2
+#define DAS08_EOC (1<<7)
+#define DAS08_IRQ (1<<3)
+#define DAS08_IP(x) (((x)>>4)&0x7)
+#define DAS08_CONTROL 2
+#define DAS08_MUX_MASK 0x7
+#define DAS08_MUX(x) ((x) & DAS08_MUX_MASK)
+#define DAS08_INTE (1<<3)
+#define DAS08_DO_MASK 0xf0
+#define DAS08_OP(x) (((x) << 4) & DAS08_DO_MASK)
+
+/*
+ cio-das08jr.pdf
+
+ "das08/jr-ao"
+
+ 0 a/d bits 0-3 unused
+ 1 a/d bits 4-11 start 12 bit
+ 2 eoc, mux mux
+ 3 di do
+ 4 unused ao0_lsb
+ 5 unused ao0_msb
+ 6 unused ao1_lsb
+ 7 unused ao1_msb
+
+*/
+
+#define DAS08JR_DIO 3
+#define DAS08JR_AO_LSB(x) ((x)?6:4)
+#define DAS08JR_AO_MSB(x) ((x)?7:5)
+
+/*
+ cio-das08_aox.pdf
+
+ "das08-aoh"
+ "das08-aol"
+ "das08-aom"
+
+ 0 a/d bits 0-3 start 8 bit
+ 1 a/d bits 4-11 start 12 bit
+ 2 eoc, ip1-3, irq, mux op1-4, inte, mux
+ 3 mux, gain status gain control
+ 4567 8254
+ 8 unused ao0_lsb
+ 9 unused ao0_msb
+ a unused ao1_lsb
+ b unused ao1_msb
+ 89ab
+ cdef 8255
+*/
+
+#define DAS08AO_GAIN_CONTROL 3
+#define DAS08AO_GAIN_STATUS 3
+
+#define DAS08AO_AO_LSB(x) ((x)?0xa:8)
+#define DAS08AO_AO_MSB(x) ((x)?0xb:9)
+#define DAS08AO_AO_UPDATE 8
+
+/* gainlist same as _pgx_ below */
+
+static int das08_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das08_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das08_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das08jr_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das08jr_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das08jr_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das08ao_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static void i8254_set_mode_low(unsigned int base, int channel,
+ unsigned int mode);
+
+static const struct comedi_lrange range_das08_pgl = { 9, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25)
+ }
+};
+static const struct comedi_lrange range_das08_pgh = { 12, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(1),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.01),
+ BIP_RANGE(0.005),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01),
+ }
+};
+static const struct comedi_lrange range_das08_pgm = { 9, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.01),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01)
+ }
+}; /*
+ cio-das08jr.pdf
+
+ "das08/jr-ao"
+
+ 0 a/d bits 0-3 unused
+ 1 a/d bits 4-11 start 12 bit
+ 2 eoc, mux mux
+ 3 di do
+ 4 unused ao0_lsb
+ 5 unused ao0_msb
+ 6 unused ao1_lsb
+ 7 unused ao1_msb
+
+ */
+
+static const struct comedi_lrange *const das08_ai_lranges[] = {
+ &range_unknown,
+ &range_bipolar5,
+ &range_das08_pgh,
+ &range_das08_pgl,
+ &range_das08_pgm,
+};
+
+static const int das08_pgh_gainlist[] =
+ { 8, 0, 10, 2, 12, 4, 14, 6, 1, 3, 5, 7 };
+static const int das08_pgl_gainlist[] = { 8, 0, 2, 4, 6, 1, 3, 5, 7 };
+static const int das08_pgm_gainlist[] = { 8, 0, 10, 12, 14, 9, 11, 13, 15 };
+
+static const int *const das08_gainlists[] = {
+ NULL,
+ NULL,
+ das08_pgh_gainlist,
+ das08_pgl_gainlist,
+ das08_pgm_gainlist,
+};
+
+static const struct das08_board_struct das08_boards[] = {
+ {
+ name: "isa-das08", // cio-das08.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pg_none,
+ ai_encoding:das08_encode12,
+ ao: NULL,
+ ao_nbits:12,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:8,
+ i8254_offset:4,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08-pgm", // cio-das08pgx.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pgm,
+ ai_encoding:das08_encode12,
+ ao: NULL,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08-pgh", // cio-das08pgx.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pgh,
+ ai_encoding:das08_encode12,
+ ao: NULL,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08-pgl", // cio-das08pgx.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pgl,
+ ai_encoding:das08_encode12,
+ ao: NULL,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08-aoh", // cio-das08_aox.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pgh,
+ ai_encoding:das08_encode12,
+ ao: das08ao_ao_winsn, // 8
+ ao_nbits:12,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0x0c,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08-aol", // cio-das08_aox.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pgl,
+ ai_encoding:das08_encode12,
+ ao: das08ao_ao_winsn, // 8
+ ao_nbits:12,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0x0c,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08-aom", // cio-das08_aox.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pgm,
+ ai_encoding:das08_encode12,
+ ao: das08ao_ao_winsn, // 8
+ ao_nbits:12,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0x0c,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08/jr-ao", // cio-das08-jr-ao.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pg_none,
+ ai_encoding:das08_encode12,
+ ao: das08jr_ao_winsn,
+ ao_nbits:12,
+ di: das08jr_di_rbits,
+ do_: das08jr_do_wbits,
+ do_nchan:8,
+ i8255_offset:0,
+ i8254_offset:0,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08jr-16-ao", // cio-das08jr-16-ao.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:16,
+ ai_pg: das08_pg_none,
+ ai_encoding:das08_encode12,
+ ao: das08jr_ao_winsn,
+ ao_nbits:16,
+ di: das08jr_di_rbits,
+ do_: das08jr_do_wbits,
+ do_nchan:8,
+ i8255_offset:0,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: "das08", // pci-das08
+ id: PCI_DEVICE_ID_PCIDAS08,
+ bustype: pci,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_bipolar5,
+ ai_encoding:das08_encode12,
+ ao: NULL,
+ ao_nbits:0,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0,
+ i8254_offset:4,
+ iosize: 8,
+ },
+#endif
+ {
+ name: "pc104-das08",
+ bustype: pc104,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pg_none,
+ ai_encoding:das08_encode12,
+ ao: NULL,
+ ao_nbits:0,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0,
+ i8254_offset:4,
+ iosize: 16, // unchecked
+ },
+#if 0
+ {
+ name: "das08/f",
+ },
+ {
+ name: "das08jr",
+ },
+#endif
+ {
+ name: "das08jr/16",
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:16,
+ ai_pg: das08_pg_none,
+ ai_encoding:das08_encode16,
+ ao: NULL,
+ ao_nbits:0,
+ di: das08jr_di_rbits,
+ do_: das08jr_do_wbits,
+ do_nchan:8,
+ i8255_offset:0,
+ i8254_offset:0,
+ iosize: 16, // unchecked
+ },
+#if 0
+ {
+ name: "das48-pga", // cio-das48-pga.pdf
+ },
+ {
+ name: "das08-pga-g2", // a KM board
+ },
+#endif
+};
+
+#ifdef CONFIG_COMEDI_PCMCIA
+struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = {
+ {
+ name: "pcm-das08",
+ id: 0x0, // XXX
+ bustype: pcmcia,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_bipolar5,
+ ai_encoding:das08_pcm_encode12,
+ ao: NULL,
+ ao_nbits:0,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:3,
+ i8255_offset:0,
+ i8254_offset:0,
+ iosize: 16,
+ },
+ // duplicate so driver name can be used also
+ {
+ name: "das08_cs",
+ id: 0x0, // XXX
+ bustype: pcmcia,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_bipolar5,
+ ai_encoding:das08_pcm_encode12,
+ ao: NULL,
+ ao_nbits:0,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:3,
+ i8255_offset:0,
+ i8254_offset:0,
+ iosize: 16,
+ },
+};
+#endif
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = {
+ {PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08, PCI_ANY_ID,
+ PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, das08_pci_table);
+#endif
+
+#define devpriv ((struct das08_private_struct *)dev->private)
+#define thisboard ((const struct das08_board_struct *)dev->board_ptr)
+
+#define TIMEOUT 100000
+
+static int das08_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int chan;
+ int range;
+ int lsb, msb;
+
+ chan = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+
+ /* clear crap */
+ inb(dev->iobase + DAS08_LSB);
+ inb(dev->iobase + DAS08_MSB);
+
+ /* set multiplexer */
+ spin_lock(&dev->spinlock); // lock to prevent race with digital output
+ devpriv->do_mux_bits &= ~DAS08_MUX_MASK;
+ devpriv->do_mux_bits |= DAS08_MUX(chan);
+ outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL);
+ spin_unlock(&dev->spinlock);
+
+ if (s->range_table->length > 1) {
+ /* set gain/range */
+ range = CR_RANGE(insn->chanspec);
+ outb(devpriv->pg_gainlist[range],
+ dev->iobase + DAS08AO_GAIN_CONTROL);
+ }
+
+ for (n = 0; n < insn->n; n++) {
+ /* clear over-range bits for 16-bit boards */
+ if (thisboard->ai_nbits == 16)
+ if (inb(dev->iobase + DAS08_MSB) & 0x80)
+ rt_printk("das08: over-range\n");
+
+ /* trigger conversion */
+ outb_p(0, dev->iobase + DAS08_TRIG_12BIT);
+
+ for (i = 0; i < TIMEOUT; i++) {
+ if (!(inb(dev->iobase + DAS08_STATUS) & DAS08_EOC))
+ break;
+ }
+ if (i == TIMEOUT) {
+ rt_printk("das08: timeout\n");
+ return -ETIME;
+ }
+ msb = inb(dev->iobase + DAS08_MSB);
+ lsb = inb(dev->iobase + DAS08_LSB);
+ if (thisboard->ai_encoding == das08_encode12) {
+ data[n] = (lsb >> 4) | (msb << 4);
+ } else if (thisboard->ai_encoding == das08_pcm_encode12) {
+ data[n] = (msb << 8) + lsb;
+ } else if (thisboard->ai_encoding == das08_encode16) {
+ /* FPOS 16-bit boards are sign-magnitude */
+ if (msb & 0x80)
+ data[n] = (1 << 15) | lsb | ((msb & 0x7f) << 8);
+ else
+ data[n] = (1 << 15) - (lsb | (msb & 0x7f) << 8);
+ } else {
+ comedi_error(dev, "bug! unknown ai encoding");
+ return -1;
+ }
+ }
+
+ return n;
+}
+
+static int das08_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = 0;
+ data[1] = DAS08_IP(inb(dev->iobase + DAS08_STATUS));
+
+ return 2;
+}
+
+static int das08_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int wbits;
+
+ // get current settings of digital output lines
+ wbits = (devpriv->do_mux_bits >> 4) & 0xf;
+ // null bits we are going to set
+ wbits &= ~data[0];
+ // set new bit values
+ wbits |= data[0] & data[1];
+ // remember digital output bits
+ spin_lock(&dev->spinlock); // prevent race with setting of analog input mux
+ devpriv->do_mux_bits &= ~DAS08_DO_MASK;
+ devpriv->do_mux_bits |= DAS08_OP(wbits);
+ outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL);
+ spin_unlock(&dev->spinlock);
+
+ data[1] = wbits;
+
+ return 2;
+}
+
+static int das08jr_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = 0;
+ data[1] = inb(dev->iobase + DAS08JR_DIO);
+
+ return 2;
+}
+
+static int das08jr_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ // null bits we are going to set
+ devpriv->do_bits &= ~data[0];
+ // set new bit values
+ devpriv->do_bits |= data[0] & data[1];
+ outb(devpriv->do_bits, dev->iobase + DAS08JR_DIO);
+
+ data[1] = devpriv->do_bits;
+
+ return 2;
+}
+
+static int das08jr_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int lsb, msb;
+ int chan;
+
+ lsb = data[0] & 0xff;
+ msb = (data[0] >> 8) & 0xf;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+#if 0
+ outb(lsb, dev->iobase + devpriv->ao_offset_lsb[chan]);
+ outb(msb, dev->iobase + devpriv->ao_offset_msb[chan]);
+#else
+ outb(lsb, dev->iobase + DAS08JR_AO_LSB(chan));
+ outb(msb, dev->iobase + DAS08JR_AO_MSB(chan));
+#endif
+
+ /* load DACs */
+ inb(dev->iobase + DAS08JR_DIO);
+ }
+
+ return n;
+}
+
+/*
+ *
+ * The -aox boards have the DACs at a different offset and use
+ * a different method to force an update.
+ *
+ */
+static int das08ao_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int lsb, msb;
+ int chan;
+
+ lsb = data[0] & 0xff;
+ msb = (data[0] >> 8) & 0xf;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+#if 0
+ outb(lsb, dev->iobase + devpriv->ao_offset_lsb[chan]);
+ outb(msb, dev->iobase + devpriv->ao_offset_msb[chan]);
+#else
+ outb(lsb, dev->iobase + DAS08AO_AO_LSB(chan));
+ outb(msb, dev->iobase + DAS08AO_AO_MSB(chan));
+#endif
+
+ /* load DACs */
+ inb(dev->iobase + DAS08AO_AO_UPDATE);
+ }
+
+ return n;
+}
+
+static unsigned int i8254_read_channel_low(unsigned int base, int chan)
+{
+ unsigned int msb, lsb;
+
+ /* The following instructions must be in order.
+ We must avoid other process reading the counter's value in the
+ middle.
+ The spin_lock isn't needed since ioctl calls grab the big kernel
+ lock automatically */
+ /*spin_lock(sp); */
+ outb(chan << 6, base + I8254_CTRL);
+ base += chan;
+ lsb = inb(base);
+ msb = inb(base);
+ /*spin_unlock(sp); */
+
+ return lsb | (msb << 8);
+}
+
+static void i8254_write_channel_low(unsigned int base, int chan,
+ unsigned int value)
+{
+ unsigned int msb, lsb;
+
+ lsb = value & 0xFF;
+ msb = value >> 8;
+
+ /* write lsb, then msb */
+ base += chan;
+ /* See comments in i8254_read_channel_low */
+ /*spin_lock(sp); */
+ outb(lsb, base);
+ outb(msb, base);
+ /*spin_unlock(sp); */
+}
+
+static unsigned int i8254_read_channel(struct i8254_struct *st, int channel)
+{
+ int chan = st->logic2phys[channel];
+
+ return i8254_read_channel_low(st->iobase, chan);
+}
+
+static void i8254_write_channel(struct i8254_struct *st, int channel,
+ unsigned int value)
+{
+ int chan = st->logic2phys[channel];
+
+ i8254_write_channel_low(st->iobase, chan, value);
+}
+
+static void i8254_initialize(struct i8254_struct *st)
+{
+ int i;
+ for (i = 0; i < 3; ++i)
+ i8254_set_mode_low(st->iobase, i, st->mode[i]);
+}
+
+static void i8254_set_mode_low(unsigned int base, int channel,
+ unsigned int mode)
+{
+ outb((channel << 6) | 0x30 | (mode & 0x0F), base + I8254_CTRL);
+}
+
+static void i8254_set_mode(struct i8254_struct *st, int channel,
+ unsigned int mode)
+{
+ int chan = st->logic2phys[channel];
+
+ st->mode[chan] = mode;
+ return i8254_set_mode_low(st->iobase, chan, mode);
+}
+
+static unsigned int i8254_read_status_low(unsigned int base, int channel)
+{
+ outb(0xE0 | (2 << channel), base + I8254_CTRL);
+ return inb(base + channel);
+}
+
+static unsigned int i8254_read_status(struct i8254_struct *st, int channel)
+{
+ int chan = st->logic2phys[channel];
+
+ return i8254_read_status_low(st->iobase, chan);
+}
+
+static int das08_counter_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = insn->chanspec;
+
+ //printk("Reading counter channel %d ",chan);
+ data[0] = i8254_read_channel(&devpriv->i8254, chan);
+ //printk("=> 0x%08X\n",data[0]);
+
+ return 1;
+}
+
+static int das08_counter_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = insn->chanspec;
+
+ //printk("Writing counter channel %d with 0x%04X\n",chan,data[0]);
+ i8254_write_channel(&devpriv->i8254, chan, data[0]);
+
+ return 1;
+}
+
+static int das08_counter_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = insn->chanspec;
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ switch (data[0]) {
+ case INSN_CONFIG_SET_COUNTER_MODE:
+ i8254_set_mode(&devpriv->i8254, chan, data[1]);
+ break;
+ case INSN_CONFIG_8254_READ_STATUS:
+ data[1] = i8254_read_status(&devpriv->i8254, chan);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 2;
+}
+
+static int das08_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+
+static struct comedi_driver driver_das08 = {
+ driver_name: DRV_NAME,
+ module:THIS_MODULE,
+ attach:das08_attach,
+ detach:das08_common_detach,
+ board_name:&das08_boards[0].name,
+ num_names:sizeof(das08_boards) /
+ sizeof(struct das08_board_struct),
+ offset:sizeof(struct das08_board_struct),
+};
+
+int das08_common_attach(struct comedi_device * dev, unsigned long iobase)
+{
+ struct comedi_subdevice *s;
+ int ret;
+
+ // allocate ioports for non-pcmcia, non-pci boards
+ if ((thisboard->bustype != pcmcia) && (thisboard->bustype != pci)) {
+ printk(" iobase 0x%lx\n", iobase);
+ if (!request_region(iobase, thisboard->iosize, DRV_NAME)) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ }
+ dev->iobase = iobase;
+
+ dev->board_name = thisboard->name;
+
+ if ((ret = alloc_subdevices(dev, 6)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ /* ai */
+ if (thisboard->ai) {
+ s->type = COMEDI_SUBD_AI;
+ /* XXX some boards actually have differential inputs instead of single ended.
+ * The driver does nothing with arefs though, so it's no big deal. */
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 8;
+ s->maxdata = (1 << thisboard->ai_nbits) - 1;
+ s->range_table = das08_ai_lranges[thisboard->ai_pg];
+ s->insn_read = thisboard->ai;
+ devpriv->pg_gainlist = das08_gainlists[thisboard->ai_pg];
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 1;
+ /* ao */
+ if (thisboard->ao) {
+ s->type = COMEDI_SUBD_AO;
+// XXX lacks read-back insn
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->maxdata = (1 << thisboard->ao_nbits) - 1;
+ s->range_table = &range_bipolar5;
+ s->insn_write = thisboard->ao;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 2;
+ /* di */
+ if (thisboard->di) {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = (thisboard->di == das08_di_rbits) ? 3 : 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = thisboard->di;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 3;
+ /* do */
+ if (thisboard->do_) {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = thisboard->do_nchan;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = thisboard->do_;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 4;
+ /* 8255 */
+ if (thisboard->i8255_offset != 0) {
+ subdev_8255_init(dev, s, NULL, (unsigned long)(dev->iobase +
+ thisboard->i8255_offset));
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 5;
+ /* 8254 */
+ if (thisboard->i8254_offset != 0) {
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 3;
+ s->maxdata = 0xFFFF;
+ s->insn_read = das08_counter_read;
+ s->insn_write = das08_counter_write;
+ s->insn_config = das08_counter_config;
+ /* Set-up the 8254 structure */
+ devpriv->i8254.channels = 3;
+ devpriv->i8254.logic2phys[0] = 0;
+ devpriv->i8254.logic2phys[1] = 1;
+ devpriv->i8254.logic2phys[2] = 2;
+ devpriv->i8254.iobase = iobase + thisboard->i8254_offset;
+ devpriv->i8254.mode[0] =
+ devpriv->i8254.mode[1] =
+ devpriv->i8254.mode[2] = I8254_MODE0 | I8254_BINARY;
+ i8254_initialize(&devpriv->i8254);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ return 0;
+}
+
+static int das08_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ unsigned long iobase;
+#ifdef CONFIG_COMEDI_PCI
+ unsigned long pci_iobase = 0;
+ struct pci_dev *pdev;
+#endif
+
+ if ((ret = alloc_private(dev, sizeof(struct das08_private_struct))) < 0)
+ return ret;
+
+ printk("comedi%d: das08: ", dev->minor);
+ // deal with a pci board
+ if (thisboard->bustype == pci) {
+#ifdef CONFIG_COMEDI_PCI
+ if (it->options[0] || it->options[1]) {
+ printk("bus %i slot %i ",
+ it->options[0], it->options[1]);
+ }
+ printk("\n");
+ // find card
+ for (pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pdev != NULL;
+ pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) {
+ if (pdev->vendor == PCI_VENDOR_ID_COMPUTERBOARDS
+ && pdev->device == PCI_DEVICE_ID_PCIDAS08) {
+ if (it->options[0] || it->options[1]) {
+ if (pdev->bus->number == it->options[0]
+ && PCI_SLOT(pdev->devfn) ==
+ it->options[1]) {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ if (!pdev) {
+ printk("No pci das08 cards found\n");
+ return -EIO;
+ }
+ devpriv->pdev = pdev;
+ // enable PCI device and reserve I/O spaces
+ if (comedi_pci_enable(pdev, DRV_NAME)) {
+ printk(" Error enabling PCI device and requesting regions\n");
+ return -EIO;
+ }
+ // read base addresses
+ pci_iobase = pci_resource_start(pdev, 1);
+ iobase = pci_resource_start(pdev, 2);
+ printk("pcibase 0x%lx iobase 0x%lx\n", pci_iobase, iobase);
+ devpriv->pci_iobase = pci_iobase;
+#if 0
+/* We could enable to pci-das08's interrupt here to make it possible
+ * to do timed input in this driver, but there is little point since
+ * conversions would have to be started by the interrupt handler
+ * so you might as well use comedi_rt_timer to emulate commands
+ */
+ /* set source of interrupt trigger to counter2 output */
+ outb(CNTRL_INTR | CNTRL_DIR, pci_iobase + CNTRL);
+ /* Enable local interrupt 1 and pci interrupt */
+ outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR);
+#endif
+#else /* CONFIG_COMEDI_PCI */
+ printk("this driver has not been built with PCI support.\n");
+ return -EINVAL;
+#endif /* CONFIG_COMEDI_PCI */
+ } else {
+ iobase = it->options[0];
+ }
+ printk("\n");
+
+ return das08_common_attach(dev, iobase);
+}
+
+int das08_common_detach(struct comedi_device * dev)
+{
+ printk(KERN_INFO "comedi%d: das08: remove\n", dev->minor);
+
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 4);
+
+ // deallocate ioports for non-pcmcia, non-pci boards
+ if ((thisboard->bustype != pcmcia) && (thisboard->bustype != pci)) {
+ if (dev->iobase)
+ release_region(dev->iobase, thisboard->iosize);
+ }
+
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv) {
+ if (devpriv->pdev) {
+ if (devpriv->pci_iobase) {
+ comedi_pci_disable(devpriv->pdev);
+ }
+ pci_dev_put(devpriv->pdev);
+ }
+ }
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_das08, das08_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_das08);
+#endif
+
+EXPORT_SYMBOL_GPL(das08_common_attach);
+EXPORT_SYMBOL_GPL(das08_common_detach);
+#ifdef CONFIG_COMEDI_PCMCIA
+EXPORT_SYMBOL_GPL(das08_cs_boards);
+#endif
diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h
new file mode 100644
index 00000000000..69089ce690f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das08.h
@@ -0,0 +1,78 @@
+/*
+ das08.h
+
+ Header for das08.c and das08_cs.c
+
+ Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _DAS08_H
+#define _DAS08_H
+
+enum das08_bustype { isa, pci, pcmcia, pc104 };
+// different ways ai data is encoded in first two registers
+enum das08_ai_encoding { das08_encode12, das08_encode16, das08_pcm_encode12 };
+enum das08_lrange { das08_pg_none, das08_bipolar5, das08_pgh, das08_pgl,
+ das08_pgm };
+
+struct das08_board_struct {
+ const char *name;
+ unsigned int id; // id for pci/pcmcia boards
+ enum das08_bustype bustype;
+ void *ai;
+ unsigned int ai_nbits;
+ enum das08_lrange ai_pg;
+ enum das08_ai_encoding ai_encoding;
+ void *ao;
+ unsigned int ao_nbits;
+ void *di;
+ void *do_;
+ unsigned int do_nchan;
+ unsigned int i8255_offset;
+ unsigned int i8254_offset;
+ unsigned int iosize; // number of ioports used
+};
+
+struct i8254_struct {
+ int channels; // available channels. Some could be used internally.
+ int logic2phys[3]; // to know which physical channel is.
+ int mode[3]; // the index is the real counter.
+ unsigned int iobase;
+};
+
+#define I8254_CNT0 0
+#define I8254_CNT1 1
+#define I8254_CNT2 2
+#define I8254_CTRL 3
+
+struct das08_private_struct {
+ unsigned int do_mux_bits; // bits for do/mux register on boards without seperate do register
+ unsigned int do_bits; // bits for do register on boards with register dedicated to digital out only
+ const unsigned int *pg_gainlist;
+ struct pci_dev *pdev; // struct for pci-das08
+ unsigned int pci_iobase; // additional base address for pci-das08
+ struct i8254_struct i8254;
+};
+
+#define NUM_DAS08_CS_BOARDS 2
+extern struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS];
+
+int das08_common_attach(struct comedi_device * dev, unsigned long iobase);
+int das08_common_detach(struct comedi_device * dev);
+
+#endif /* _DAS08_H */
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
new file mode 100644
index 00000000000..be6c88788c4
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -0,0 +1,488 @@
+/*
+ comedi/drivers/das08_cs.c
+ DAS08 driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*****************************************************************
+
+*/
+/*
+Driver: das08_cs
+Description: DAS-08 PCMCIA boards
+Author: Warren Jasper, ds, Frank Hess
+Devices: [ComputerBoards] PCM-DAS08 (pcm-das08)
+Status: works
+
+This is the PCMCIA-specific support split off from the
+das08 driver.
+
+Options (for pcm-das08):
+ NONE
+
+Command support does not exist, but could be added for this board.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include "das08.h"
+
+// pcmcia includes
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+static struct pcmcia_device *cur_dev = NULL;
+
+#define thisboard ((const struct das08_board_struct *)dev->board_ptr)
+
+static int das08_cs_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+
+static struct comedi_driver driver_das08_cs = {
+ driver_name:"das08_cs",
+ module:THIS_MODULE,
+ attach:das08_cs_attach,
+ detach:das08_common_detach,
+ board_name:&das08_cs_boards[0].name,
+ num_names:sizeof(das08_cs_boards) /
+ sizeof(struct das08_board_struct),
+ offset:sizeof(struct das08_board_struct),
+};
+
+static int das08_cs_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ unsigned long iobase;
+ struct pcmcia_device *link = cur_dev; // XXX hack
+
+ if ((ret = alloc_private(dev, sizeof(struct das08_private_struct))) < 0)
+ return ret;
+
+ printk("comedi%d: das08_cs: ", dev->minor);
+ // deal with a pci board
+
+ if (thisboard->bustype == pcmcia) {
+ if (link == NULL) {
+ printk(" no pcmcia cards found\n");
+ return -EIO;
+ }
+ iobase = link->io.BasePort1;
+ } else {
+ printk(" bug! board does not have PCMCIA bustype\n");
+ return -EINVAL;
+ }
+
+ printk("\n");
+
+ return das08_common_attach(dev, iobase);
+}
+
+/*======================================================================
+
+ The following pcmcia code for the pcm-das08 is adapted from the
+ dummy_cs.c driver of the Linux PCMCIA Card Services package.
+
+ The initial developer of the original code is David A. Hinds
+ <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
+ are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+
+======================================================================*/
+
+/*
+ All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
+ you do not define PCMCIA_DEBUG at all, all the debug code will be
+ left out. If you compile with PCMCIA_DEBUG=0, the debug code will
+ be present but disabled -- but it can then be enabled for specific
+ modules at load time with a 'pc_debug=#' option to insmod.
+*/
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static const char *version =
+ "das08.c pcmcia code (Frank Hess), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+static void das08_pcmcia_config(struct pcmcia_device *link);
+static void das08_pcmcia_release(struct pcmcia_device *link);
+static int das08_pcmcia_suspend(struct pcmcia_device *p_dev);
+static int das08_pcmcia_resume(struct pcmcia_device *p_dev);
+
+/*
+ The attach() and detach() entry points are used to create and destroy
+ "instances" of the driver, where each instance represents everything
+ needed to manage one actual PCMCIA card.
+*/
+
+static int das08_pcmcia_attach(struct pcmcia_device *);
+static void das08_pcmcia_detach(struct pcmcia_device *);
+
+/*
+ You'll also need to prototype all the functions that will actually
+ be used to talk to your device. See 'memory_cs' for a good example
+ of a fully self-sufficient driver; the other drivers rely more or
+ less on other parts of the kernel.
+*/
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static const dev_info_t dev_info = "pcm-das08";
+
+struct local_info_t {
+ struct pcmcia_device *link;
+ dev_node_t node;
+ int stop;
+ struct bus_operations *bus;
+};
+
+/*======================================================================
+
+ das08_pcmcia_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+
+ The dev_link structure is initialized, but we don't actually
+ configure the card at this point -- we wait until we receive a
+ card insertion event.
+
+======================================================================*/
+
+static int das08_pcmcia_attach(struct pcmcia_device *link)
+{
+ struct local_info_t *local;
+
+ DEBUG(0, "das08_pcmcia_attach()\n");
+
+ /* Allocate space for private device-specific data */
+ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
+ if (!local)
+ return -ENOMEM;
+ local->link = link;
+ link->priv = local;
+
+ /* Interrupt setup */
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = NULL;
+
+ /*
+ General socket configuration defaults can go here. In this
+ client, we assume very little, and rely on the CIS for almost
+ everything. In most clients, many details (i.e., number, sizes,
+ and attributes of IO windows) are fixed by the nature of the
+ device, and can be hard-wired here.
+ */
+ link->conf.Attributes = 0;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ cur_dev = link;
+
+ das08_pcmcia_config(link);
+
+ return 0;
+} /* das08_pcmcia_attach */
+
+/*======================================================================
+
+ This deletes a driver "instance". The device is de-registered
+ with Card Services. If it has been released, all local data
+ structures are freed. Otherwise, the structures will be freed
+ when the device is released.
+
+======================================================================*/
+
+static void das08_pcmcia_detach(struct pcmcia_device *link)
+{
+
+ DEBUG(0, "das08_pcmcia_detach(0x%p)\n", link);
+
+ if (link->dev_node) {
+ ((struct local_info_t *) link->priv)->stop = 1;
+ das08_pcmcia_release(link);
+ }
+
+ /* This points to the parent struct local_info_t struct */
+ if (link->priv)
+ kfree(link->priv);
+
+} /* das08_pcmcia_detach */
+
+/*======================================================================
+
+ das08_pcmcia_config() is scheduled to run after a CARD_INSERTION event
+ is received, to configure the PCMCIA socket, and to make the
+ device available to the system.
+
+======================================================================*/
+
+static void das08_pcmcia_config(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+ tuple_t tuple;
+ cisparse_t parse;
+ int last_fn, last_ret;
+ u_char buf[64];
+ cistpl_cftable_entry_t dflt = { 0 };
+
+ DEBUG(0, "das08_pcmcia_config(0x%p)\n", link);
+
+ /*
+ This reads the card's CONFIG tuple to find its configuration
+ registers.
+ */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ last_fn = GetFirstTuple;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0)
+ goto cs_failed;
+ last_fn = GetTupleData;
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0)
+ goto cs_failed;
+ last_fn = ParseTuple;
+ if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
+ goto cs_failed;
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+ /*
+ In this loop, we scan the CIS for configuration table entries,
+ each of which describes a valid card configuration, including
+ voltage, IO window, memory window, and interrupt settings.
+
+ We make no assumptions about the card to be configured: we use
+ just the information available in the CIS. In an ideal world,
+ this would work for any PCMCIA card, but it requires a complete
+ and accurate CIS. In practice, a driver usually "knows" most of
+ these things without consulting the CIS, and most client drivers
+ will only use the CIS to fill in implementation-defined details.
+ */
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ last_fn = GetFirstTuple;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0)
+ goto cs_failed;
+ while (1) {
+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0)
+ goto next_entry;
+ if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
+ goto next_entry;
+
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ if (cfg->index == 0)
+ goto next_entry;
+ link->conf.ConfigIndex = cfg->index;
+
+ /* Does this card need audio output? */
+/* if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ link->conf.Attributes |= CONF_ENABLE_SPKR;
+ link->conf.Status = CCSR_AUDIO_ENA;
+ }
+*/
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(link, &link->io) != 0)
+ goto next_entry;
+ }
+
+ /* If we got this far, we're cool! */
+ break;
+
+ next_entry:
+ last_fn = GetNextTuple;
+ if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0)
+ goto cs_failed;
+ }
+
+ if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+ last_fn = RequestIRQ;
+ if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0)
+ goto cs_failed;
+ }
+
+ /*
+ This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping, and putting the
+ card and host interface into "Memory and IO" mode.
+ */
+ last_fn = RequestConfiguration;
+ if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0)
+ goto cs_failed;
+
+ /*
+ At this point, the dev_node_t structure(s) need to be
+ initialized and arranged in a linked list at link->dev.
+ */
+ sprintf(dev->node.dev_name, "pcm-das08");
+ dev->node.major = dev->node.minor = 0;
+ link->dev_node = &dev->node;
+
+ /* Finally, report what we've done */
+ printk(KERN_INFO "%s: index 0x%02x",
+ dev->node.dev_name, link->conf.ConfigIndex);
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ printk(", irq %u", 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");
+
+ return;
+
+ cs_failed:
+ cs_error(link, last_fn, last_ret);
+ das08_pcmcia_release(link);
+
+} /* das08_pcmcia_config */
+
+/*======================================================================
+
+ After a card is removed, das08_pcmcia_release() will unregister the
+ device, and release the PCMCIA configuration. If the device is
+ still open, this will be postponed until it is closed.
+
+======================================================================*/
+
+static void das08_pcmcia_release(struct pcmcia_device *link)
+{
+ DEBUG(0, "das08_pcmcia_release(0x%p)\n", link);
+ pcmcia_disable_device(link);
+} /* das08_pcmcia_release */
+
+/*======================================================================
+
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received.
+
+ When a CARD_REMOVAL event is received, we immediately set a
+ private flag to block future accesses to this device. All the
+ functions that actually access the device should check this flag
+ to make sure the card is still present.
+
+======================================================================*/
+
+static int das08_pcmcia_suspend(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+ /* Mark the device as stopped, to block IO until later */
+ local->stop = 1;
+
+ return 0;
+} /* das08_pcmcia_suspend */
+
+static int das08_pcmcia_resume(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ local->stop = 0;
+ return 0;
+} /* das08_pcmcia_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id das08_cs_id_table[] = {
+ PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4001),
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, das08_cs_id_table);
+
+struct pcmcia_driver das08_cs_driver = {
+ .probe = das08_pcmcia_attach,
+ .remove = das08_pcmcia_detach,
+ .suspend = das08_pcmcia_suspend,
+ .resume = das08_pcmcia_resume,
+ .id_table = das08_cs_id_table,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+static int __init init_das08_pcmcia_cs(void)
+{
+ DEBUG(0, "%s\n", version);
+ pcmcia_register_driver(&das08_cs_driver);
+ return 0;
+}
+
+static void __exit exit_das08_pcmcia_cs(void)
+{
+ DEBUG(0, "das08_pcmcia_cs: unloading\n");
+ pcmcia_unregister_driver(&das08_cs_driver);
+}
+
+static int __init das08_cs_init_module(void)
+{
+ int ret;
+
+ ret = init_das08_pcmcia_cs();
+ if (ret < 0)
+ return ret;
+
+ return comedi_driver_register(&driver_das08_cs);
+}
+
+static void __exit das08_cs_exit_module(void)
+{
+ exit_das08_pcmcia_cs();
+ comedi_driver_unregister(&driver_das08_cs);
+}
+
+MODULE_LICENSE("GPL");
+module_init(das08_cs_init_module);
+module_exit(das08_cs_exit_module);
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c
new file mode 100644
index 00000000000..6b6b042099d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das16.c
@@ -0,0 +1,1730 @@
+/*
+ comedi/drivers/das16.c
+ DAS16 driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
+ Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: das16
+Description: DAS16 compatible boards
+Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
+Devices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g),
+ DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202),
+ DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601),
+ DAS-1602 (das-1602),
+ [ComputerBoards] PC104-DAS16/JR (pc104-das16jr),
+ PC104-DAS16JR/16 (pc104-das16jr/16),
+ CIO-DAS16JR/16 (cio-das16jr/16),
+ CIO-DAS16/JR (cio-das16/jr), CIO-DAS1401/12 (cio-das1401/12),
+ CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16),
+ CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12),
+ CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330)
+Status: works
+Updated: 2003-10-12
+
+A rewrite of the das16 and das1600 drivers.
+Options:
+ [0] - base io address
+ [1] - irq (does nothing, irq is not used anymore)
+ [2] - dma (optional, required for comedi_command support)
+ [3] - master clock speed in MHz (optional, 1 or 10, ignored if
+ board can probe clock, defaults to 1)
+ [4] - analog input range lowest voltage in microvolts (optional,
+ only useful if your board does not have software
+ programmable gain)
+ [5] - analog input range highest voltage in microvolts (optional,
+ only useful if board does not have software programmable
+ gain)
+ [6] - analog output range lowest voltage in microvolts (optional)
+ [7] - analog output range highest voltage in microvolts (optional)
+ [8] - use timer mode for DMA. Timer mode is needed e.g. for
+ buggy DMA controllers in NS CS5530A (Geode Companion), and for
+ 'jr' cards that lack a hardware fifo. This option is no
+ longer needed, since timer mode is _always_ used.
+
+Passing a zero for an option is the same as leaving it unspecified.
+
+*/
+/*
+
+Testing and debugging help provided by Daniel Koch.
+
+Keithley Manuals:
+ 2309.PDF (das16)
+ 4919.PDF (das1400, 1600)
+ 4922.PDF (das-1400)
+ 4923.PDF (das1200, 1400, 1600)
+
+Computer boards manuals also available from their website www.measurementcomputing.com
+
+*/
+
+#include <linux/pci.h>
+#include <asm/dma.h>
+#include "../comedidev.h"
+
+#include "8253.h"
+#include "8255.h"
+#include "comedi_fc.h"
+
+#undef DEBUG
+//#define DEBUG
+
+#ifdef DEBUG
+#define DEBUG_PRINT(format, args...) rt_printk("das16: " format, ## args)
+#else
+#define DEBUG_PRINT(format, args...)
+#endif
+
+#define DAS16_SIZE 20 // number of ioports
+#define DAS16_DMA_SIZE 0xff00 // size in bytes of allocated dma buffer
+
+/*
+ cio-das16.pdf
+
+ "das16"
+ "das16/f"
+
+ 0 a/d bits 0-3 start 12 bit
+ 1 a/d bits 4-11 unused
+ 2 mux read mux set
+ 3 di 4 bit do 4 bit
+ 4 unused ao0_lsb
+ 5 unused ao0_msb
+ 6 unused ao1_lsb
+ 7 unused ao1_msb
+ 8 status eoc uni/bip interrupt reset
+ 9 dma, int, trig ctrl set dma, int
+ a pacer control unused
+ b reserved reserved
+ cdef 8254
+ 0123 8255
+
+*/
+
+/*
+ cio-das16jr.pdf
+
+ "das16jr"
+
+ 0 a/d bits 0-3 start 12 bit
+ 1 a/d bits 4-11 unused
+ 2 mux read mux set
+ 3 di 4 bit do 4 bit
+ 4567 unused unused
+ 8 status eoc uni/bip interrupt reset
+ 9 dma, int, trig ctrl set dma, int
+ a pacer control unused
+ b gain status gain control
+ cdef 8254
+
+*/
+
+/*
+ cio-das16jr_16.pdf
+
+ "das16jr_16"
+
+ 0 a/d bits 0-7 start 16 bit
+ 1 a/d bits 8-15 unused
+ 2 mux read mux set
+ 3 di 4 bit do 4 bit
+ 4567 unused unused
+ 8 status eoc uni/bip interrupt reset
+ 9 dma, int, trig ctrl set dma, int
+ a pacer control unused
+ b gain status gain control
+ cdef 8254
+
+*/
+/*
+ cio-das160x-1x.pdf
+
+ "das1601/12"
+ "das1602/12"
+ "das1602/16"
+
+ 0 a/d bits 0-3 start 12 bit
+ 1 a/d bits 4-11 unused
+ 2 mux read mux set
+ 3 di 4 bit do 4 bit
+ 4 unused ao0_lsb
+ 5 unused ao0_msb
+ 6 unused ao1_lsb
+ 7 unused ao1_msb
+ 8 status eoc uni/bip interrupt reset
+ 9 dma, int, trig ctrl set dma, int
+ a pacer control unused
+ b gain status gain control
+ cdef 8254
+ 400 8255
+ 404 unused conversion enable
+ 405 unused burst enable
+ 406 unused das1600 enable
+ 407 status
+
+*/
+
+static const int sample_size = 2; // size in bytes of a sample from board
+
+#define DAS16_TRIG 0
+#define DAS16_AI_LSB 0
+#define DAS16_AI_MSB 1
+#define DAS16_MUX 2
+#define DAS16_DIO 3
+#define DAS16_AO_LSB(x) ((x)?6:4)
+#define DAS16_AO_MSB(x) ((x)?7:5)
+#define DAS16_STATUS 8
+#define BUSY (1<<7)
+#define UNIPOLAR (1<<6)
+#define DAS16_MUXBIT (1<<5)
+#define DAS16_INT (1<<4)
+#define DAS16_CONTROL 9
+#define DAS16_INTE (1<<7)
+#define DAS16_IRQ(x) (((x) & 0x7) << 4)
+#define DMA_ENABLE (1<<2)
+#define PACING_MASK 0x3
+#define INT_PACER 0x03
+#define EXT_PACER 0x02
+#define DAS16_SOFT 0x00
+#define DAS16_PACER 0x0A
+#define DAS16_CTR0 (1<<1)
+#define DAS16_TRIG0 (1<<0)
+#define BURST_LEN_BITS(x) (((x) & 0xf) << 4)
+#define DAS16_GAIN 0x0B
+#define DAS16_CNTR0_DATA 0x0C
+#define DAS16_CNTR1_DATA 0x0D
+#define DAS16_CNTR2_DATA 0x0E
+#define DAS16_CNTR_CONTROL 0x0F
+#define DAS16_TERM_CNT 0x00
+#define DAS16_ONE_SHOT 0x02
+#define DAS16_RATE_GEN 0x04
+#define DAS16_CNTR_LSB_MSB 0x30
+#define DAS16_CNTR0 0x00
+#define DAS16_CNTR1 0x40
+#define DAS16_CNTR2 0x80
+
+#define DAS1600_CONV 0x404
+#define DAS1600_CONV_DISABLE 0x40
+#define DAS1600_BURST 0x405
+#define DAS1600_BURST_VAL 0x40
+#define DAS1600_ENABLE 0x406
+#define DAS1600_ENABLE_VAL 0x40
+#define DAS1600_STATUS_B 0x407
+#define DAS1600_BME 0x40
+#define DAS1600_ME 0x20
+#define DAS1600_CD 0x10
+#define DAS1600_WS 0x02
+#define DAS1600_CLK_10MHZ 0x01
+
+static const struct comedi_lrange range_das1x01_bip = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.01),
+ }
+};
+static const struct comedi_lrange range_das1x01_unip = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01),
+ }
+};
+static const struct comedi_lrange range_das1x02_bip = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_das1x02_unip = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_das16jr = { 9, {
+ // also used by 16/330
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_das16jr_16 = { 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+
+static const int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 };
+static const int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+static const int das1600_gainlist[] = { 0, 1, 2, 3 };
+enum {
+ das16_pg_none = 0,
+ das16_pg_16jr,
+ das16_pg_16jr_16,
+ das16_pg_1601,
+ das16_pg_1602,
+};
+static const int *const das16_gainlists[] = {
+ NULL,
+ das16jr_gainlist,
+ das16jr_16_gainlist,
+ das1600_gainlist,
+ das1600_gainlist,
+};
+static const struct comedi_lrange *const das16_ai_uni_lranges[] = {
+ &range_unknown,
+ &range_das16jr,
+ &range_das16jr_16,
+ &range_das1x01_unip,
+ &range_das1x02_unip,
+};
+static const struct comedi_lrange *const das16_ai_bip_lranges[] = {
+ &range_unknown,
+ &range_das16jr,
+ &range_das16jr_16,
+ &range_das1x01_bip,
+ &range_das1x02_bip,
+};
+
+struct munge_info {
+ uint8_t byte;
+ unsigned have_byte:1;
+};
+
+static int das16_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int das16_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int das16_cmd_exec(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das16_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void das16_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *array, unsigned int num_bytes, unsigned int start_chan_index);
+
+static void das16_reset(struct comedi_device * dev);
+static irqreturn_t das16_dma_interrupt(int irq, void *d PT_REGS_ARG);
+static void das16_timer_interrupt(unsigned long arg);
+static void das16_interrupt(struct comedi_device * dev);
+
+static unsigned int das16_set_pacer(struct comedi_device * dev, unsigned int ns,
+ int flags);
+static int das1600_mode_detect(struct comedi_device * dev);
+static unsigned int das16_suggest_transfer_size(struct comedi_device * dev,
+ struct comedi_cmd cmd);
+
+static void reg_dump(struct comedi_device * dev);
+
+struct das16_board {
+ const char *name;
+ void *ai;
+ unsigned int ai_nbits;
+ unsigned int ai_speed; // max conversion speed in nanosec
+ unsigned int ai_pg;
+ void *ao;
+ unsigned int ao_nbits;
+ void *di;
+ void *do_;
+
+ unsigned int i8255_offset;
+ unsigned int i8254_offset;
+
+ unsigned int size;
+ unsigned int id;
+};
+
+static const struct das16_board das16_boards[] = {
+ {
+ name: "das-16",
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:15000,
+ ai_pg: das16_pg_none,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x10,
+ i8254_offset:0x0c,
+ size: 0x14,
+ id: 0x00,
+ },
+ {
+ name: "das-16g",
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:15000,
+ ai_pg: das16_pg_none,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x10,
+ i8254_offset:0x0c,
+ size: 0x14,
+ id: 0x00,
+ },
+ {
+ name: "das-16f",
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:8500,
+ ai_pg: das16_pg_none,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x10,
+ i8254_offset:0x0c,
+ size: 0x14,
+ id: 0x00,
+ },
+ {
+ name: "cio-das16", // cio-das16.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:20000,
+ ai_pg: das16_pg_none,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x10,
+ i8254_offset:0x0c,
+ size: 0x14,
+ id: 0x80,
+ },
+ {
+ name: "cio-das16/f", // das16.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_none,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x10,
+ i8254_offset:0x0c,
+ size: 0x14,
+ id: 0x80,
+ },
+ {
+ name: "cio-das16/jr", // cio-das16jr.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:7692,
+ ai_pg: das16_pg_16jr,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x10,
+ id: 0x00,
+ },
+ {
+ name: "pc104-das16jr", // pc104-das16jr_xx.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:3300,
+ ai_pg: das16_pg_16jr,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x10,
+ id: 0x00,
+ },
+ {
+ name: "cio-das16jr/16", // cio-das16jr_16.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:16,
+ ai_speed:10000,
+ ai_pg: das16_pg_16jr_16,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x10,
+ id: 0x00,
+ },
+ {
+ name: "pc104-das16jr/16", // pc104-das16jr_xx.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:16,
+ ai_speed:10000,
+ ai_pg: das16_pg_16jr_16,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x10,
+ id: 0x00,
+ },
+ {
+ name: "das-1201", // 4924.pdf (keithley user's manual)
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:20000,
+ ai_pg: das16_pg_none,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0x20,
+ },
+ {
+ name: "das-1202", // 4924.pdf (keithley user's manual)
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_none,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0x20,
+ },
+ {
+ name: "das-1401", // 4919.pdf and 4922.pdf (keithley user's manual)
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_1601,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x0,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0 // 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0
+ },
+ {
+ name: "das-1402", // 4919.pdf and 4922.pdf (keithley user's manual)
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_1602,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x0,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0 // 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0
+ },
+ {
+ name: "das-1601", // 4919.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_1601,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "das-1602", // 4919.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_1602,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das1401/12", // cio-das1400_series.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:6250,
+ ai_pg: das16_pg_1601,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das1402/12", // cio-das1400_series.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:6250,
+ ai_pg: das16_pg_1602,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das1402/16", // cio-das1400_series.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:16,
+ ai_speed:10000,
+ ai_pg: das16_pg_1602,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das1601/12", // cio-das160x-1x.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:6250,
+ ai_pg: das16_pg_1601,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das1602/12", // cio-das160x-1x.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_1602,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das1602/16", // cio-das160x-1x.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:16,
+ ai_speed:10000,
+ ai_pg: das16_pg_1602,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das16/330", // ?
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:3030,
+ ai_pg: das16_pg_16jr,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x14,
+ id: 0xf0},
+#if 0
+ {
+ name: "das16/330i", // ?
+ },
+ {
+ name: "das16/jr/ctr5", // ?
+ },
+ {
+ name: "cio-das16/m1/16", // cio-das16_m1_16.pdf, this board is a bit quirky, no dma
+ },
+#endif
+};
+
+#define n_das16_boards ((sizeof(das16_boards))/(sizeof(struct das16_board)))
+
+static int das16_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das16_detach(struct comedi_device * dev);
+static struct comedi_driver driver_das16 = {
+ driver_name:"das16",
+ module:THIS_MODULE,
+ attach:das16_attach,
+ detach:das16_detach,
+ board_name:&das16_boards[0].name,
+ num_names:n_das16_boards,
+ offset:sizeof(das16_boards[0]),
+};
+
+#define DAS16_TIMEOUT 1000
+
+/* Period for timer interrupt in jiffies. It's a function
+ * to deal with possibility of dynamic HZ patches */
+static inline int timer_period(void)
+{
+ return HZ / 20;
+}
+struct das16_private_struct {
+ unsigned int ai_unipolar; // unipolar flag
+ unsigned int ai_singleended; // single ended flag
+ unsigned int clockbase; // master clock speed in ns
+ volatile unsigned int control_state; // dma, interrupt and trigger control bits
+ volatile unsigned long adc_byte_count; // number of bytes remaining
+ unsigned int divisor1; // divisor dividing master clock to get conversion frequency
+ unsigned int divisor2; // divisor dividing master clock to get conversion frequency
+ unsigned int dma_chan; // dma channel
+ uint16_t *dma_buffer[2];
+ dma_addr_t dma_buffer_addr[2];
+ unsigned int current_buffer;
+ volatile unsigned int dma_transfer_size; // target number of bytes to transfer per dma shot
+ // user-defined analog input and output ranges defined from config options
+ struct comedi_lrange *user_ai_range_table;
+ struct comedi_lrange *user_ao_range_table;
+
+ struct timer_list timer; // for timed interrupt
+ volatile short timer_running;
+ volatile short timer_mode; // true if using timer mode
+};
+#define devpriv ((struct das16_private_struct *)(dev->private))
+#define thisboard ((struct das16_board *)(dev->board_ptr))
+
+static int das16_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0, tmp;
+ int gain, start_chan, i;
+ int mask;
+
+ /* make sure triggers are valid */
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ mask = TRIG_FOLLOW;
+ // if board supports burst mode
+ if (thisboard->size > 0x400)
+ mask |= TRIG_TIMER | TRIG_EXT;
+ cmd->scan_begin_src &= mask;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ mask = TRIG_TIMER | TRIG_EXT;
+ // if board supports burst mode
+ if (thisboard->size > 0x400)
+ mask |= TRIG_NOW;
+ cmd->convert_src &= mask;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT &&
+ cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER &&
+ cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ // make sure scan_begin_src and convert_src dont conflict
+ if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
+ err++;
+ if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ /* internal trigger */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ // check against maximum frequency
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg <
+ thisboard->ai_speed * cmd->chanlist_len) {
+ cmd->scan_begin_arg =
+ thisboard->ai_speed * cmd->chanlist_len;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+
+ if (cmd->stop_src == TRIG_NONE) {
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+ if (err)
+ return 3;
+
+ // step 4: fix up arguments
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ unsigned int tmp = cmd->scan_begin_arg;
+ // set divisors, correct timing arguments
+ i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
+ err += (tmp != cmd->scan_begin_arg);
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ unsigned int tmp = cmd->convert_arg;
+ // set divisors, correct timing arguments
+ i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
+ err += (tmp != cmd->convert_arg);
+ }
+ if (err)
+ return 4;
+
+ // check channel/gain list against card's limitations
+ if (cmd->chanlist) {
+ gain = CR_RANGE(cmd->chanlist[0]);
+ start_chan = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) !=
+ (start_chan + i) % s->n_chan) {
+ comedi_error(dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ err++;
+ }
+ if (CR_RANGE(cmd->chanlist[i]) != gain) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same gain\n");
+ err++;
+ }
+ }
+ }
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int das16_cmd_exec(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int byte;
+ unsigned long flags;
+ int range;
+
+ if (devpriv->dma_chan == 0 || (dev->irq == 0
+ && devpriv->timer_mode == 0)) {
+ comedi_error(dev,
+ "irq (or use of 'timer mode') dma required to execute comedi_cmd");
+ return -1;
+ }
+ if (cmd->flags & TRIG_RT) {
+ comedi_error(dev,
+ "isa dma transfers cannot be performed with TRIG_RT, aborting");
+ return -1;
+ }
+
+ devpriv->adc_byte_count =
+ cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t);
+
+ // disable conversions for das1600 mode
+ if (thisboard->size > 0x400) {
+ outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV);
+ }
+ // set scan limits
+ byte = CR_CHAN(cmd->chanlist[0]);
+ byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4;
+ outb(byte, dev->iobase + DAS16_MUX);
+
+ /* set gain (this is also burst rate register but according to
+ * computer boards manual, burst rate does nothing, even on keithley cards) */
+ if (thisboard->ai_pg != das16_pg_none) {
+ range = CR_RANGE(cmd->chanlist[0]);
+ outb((das16_gainlists[thisboard->ai_pg])[range],
+ dev->iobase + DAS16_GAIN);
+ }
+
+ /* set counter mode and counts */
+ cmd->convert_arg =
+ das16_set_pacer(dev, cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ DEBUG_PRINT("pacer period: %d ns\n", cmd->convert_arg);
+
+ /* enable counters */
+ byte = 0;
+ /* Enable burst mode if appropriate. */
+ if (thisboard->size > 0x400) {
+ if (cmd->convert_src == TRIG_NOW) {
+ outb(DAS1600_BURST_VAL, dev->iobase + DAS1600_BURST);
+ // set burst length
+ byte |= BURST_LEN_BITS(cmd->chanlist_len - 1);
+ } else {
+ outb(0, dev->iobase + DAS1600_BURST);
+ }
+ }
+ outb(byte, dev->iobase + DAS16_PACER);
+
+ // set up dma transfer
+ flags = claim_dma_lock();
+ disable_dma(devpriv->dma_chan);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma_chan);
+ devpriv->current_buffer = 0;
+ set_dma_addr(devpriv->dma_chan,
+ devpriv->dma_buffer_addr[devpriv->current_buffer]);
+ // set appropriate size of transfer
+ devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, *cmd);
+ set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
+ enable_dma(devpriv->dma_chan);
+ release_dma_lock(flags);
+
+ // set up interrupt
+ if (devpriv->timer_mode) {
+ devpriv->timer_running = 1;
+ devpriv->timer.expires = jiffies + timer_period();
+ add_timer(&devpriv->timer);
+ devpriv->control_state &= ~DAS16_INTE;
+ } else {
+ /* clear interrupt bit */
+ outb(0x00, dev->iobase + DAS16_STATUS);
+ /* enable interrupts */
+ devpriv->control_state |= DAS16_INTE;
+ }
+ devpriv->control_state |= DMA_ENABLE;
+ devpriv->control_state &= ~PACING_MASK;
+ if (cmd->convert_src == TRIG_EXT)
+ devpriv->control_state |= EXT_PACER;
+ else
+ devpriv->control_state |= INT_PACER;
+ outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
+
+ /* Enable conversions if using das1600 mode */
+ if (thisboard->size > 0x400) {
+ outb(0, dev->iobase + DAS1600_CONV);
+ }
+
+ return 0;
+}
+
+static int das16_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ /* disable interrupts, dma and pacer clocked conversions */
+ devpriv->control_state &= ~DAS16_INTE & ~PACING_MASK & ~DMA_ENABLE;
+ outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
+ if (devpriv->dma_chan)
+ disable_dma(devpriv->dma_chan);
+
+ // disable SW timer
+ if (devpriv->timer_mode && devpriv->timer_running) {
+ devpriv->timer_running = 0;
+ del_timer(&devpriv->timer);
+ }
+
+ /* disable burst mode */
+ if (thisboard->size > 0x400) {
+ outb(0, dev->iobase + DAS1600_BURST);
+ }
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return 0;
+}
+
+static void das16_reset(struct comedi_device * dev)
+{
+ outb(0, dev->iobase + DAS16_STATUS);
+ outb(0, dev->iobase + DAS16_CONTROL);
+ outb(0, dev->iobase + DAS16_PACER);
+ outb(0, dev->iobase + DAS16_CNTR_CONTROL);
+}
+
+static int das16_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int range;
+ int chan;
+ int msb, lsb;
+
+ // disable interrupts and pacing
+ devpriv->control_state &= ~DAS16_INTE & ~DMA_ENABLE & ~PACING_MASK;
+ outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
+
+ /* set multiplexer */
+ chan = CR_CHAN(insn->chanspec);
+ chan |= CR_CHAN(insn->chanspec) << 4;
+ outb(chan, dev->iobase + DAS16_MUX);
+
+ /* set gain */
+ if (thisboard->ai_pg != das16_pg_none) {
+ range = CR_RANGE(insn->chanspec);
+ outb((das16_gainlists[thisboard->ai_pg])[range],
+ dev->iobase + DAS16_GAIN);
+ }
+
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ outb_p(0, dev->iobase + DAS16_TRIG);
+
+ for (i = 0; i < DAS16_TIMEOUT; i++) {
+ if (!(inb(dev->iobase + DAS16_STATUS) & BUSY))
+ break;
+ }
+ if (i == DAS16_TIMEOUT) {
+ rt_printk("das16: timeout\n");
+ return -ETIME;
+ }
+ msb = inb(dev->iobase + DAS16_AI_MSB);
+ lsb = inb(dev->iobase + DAS16_AI_LSB);
+ if (thisboard->ai_nbits == 12) {
+ data[n] = ((lsb >> 4) & 0xf) | (msb << 4);
+ } else {
+ data[n] = lsb | (msb << 8);
+ }
+ }
+
+ return n;
+}
+
+static int das16_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits;
+
+ bits = inb(dev->iobase + DAS16_DIO) & 0xf;
+ data[1] = bits;
+ data[0] = 0;
+
+ return 2;
+}
+
+static int das16_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int wbits;
+
+ // only set bits that have been masked
+ data[0] &= 0xf;
+ wbits = s->state;
+ // zero bits that have been masked
+ wbits &= ~data[0];
+ // set masked bits
+ wbits |= data[0] & data[1];
+ s->state = wbits;
+ data[1] = wbits;
+
+ outb(s->state, dev->iobase + DAS16_DIO);
+
+ return 2;
+}
+
+static int das16_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int lsb, msb;
+ int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ if (thisboard->ao_nbits == 12) {
+ lsb = (data[i] << 4) & 0xff;
+ msb = (data[i] >> 4) & 0xff;
+ } else {
+ lsb = data[i] & 0xff;
+ msb = (data[i] >> 8) & 0xff;
+ }
+ outb(lsb, dev->iobase + DAS16_AO_LSB(chan));
+ outb(msb, dev->iobase + DAS16_AO_MSB(chan));
+ }
+
+ return i;
+}
+
+static irqreturn_t das16_dma_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ int status;
+ struct comedi_device *dev = d;
+
+ status = inb(dev->iobase + DAS16_STATUS);
+
+ if ((status & DAS16_INT) == 0) {
+ DEBUG_PRINT("spurious interrupt\n");
+ return IRQ_NONE;
+ }
+
+ /* clear interrupt */
+ outb(0x00, dev->iobase + DAS16_STATUS);
+ das16_interrupt(dev);
+ return IRQ_HANDLED;
+}
+
+static void das16_timer_interrupt(unsigned long arg)
+{
+ struct comedi_device *dev = (struct comedi_device *) arg;
+
+ das16_interrupt(dev);
+
+ if (devpriv->timer_running)
+ mod_timer(&devpriv->timer, jiffies + timer_period());
+}
+
+/* the pc104-das16jr (at least) has problems if the dma
+ transfer is interrupted in the middle of transferring
+ a 16 bit sample, so this function takes care to get
+ an even transfer count after disabling dma
+ channel.
+*/
+static int disable_dma_on_even(struct comedi_device * dev)
+{
+ int residue;
+ int i;
+ static const int disable_limit = 100;
+ static const int enable_timeout = 100;
+ disable_dma(devpriv->dma_chan);
+ residue = get_dma_residue(devpriv->dma_chan);
+ for (i = 0; i < disable_limit && (residue % 2); ++i) {
+ int j;
+ enable_dma(devpriv->dma_chan);
+ for (j = 0; j < enable_timeout; ++j) {
+ int new_residue;
+ comedi_udelay(2);
+ new_residue = get_dma_residue(devpriv->dma_chan);
+ if (new_residue != residue)
+ break;
+ }
+ disable_dma(devpriv->dma_chan);
+ residue = get_dma_residue(devpriv->dma_chan);
+ }
+ if (i == disable_limit) {
+ comedi_error(dev,
+ "failed to get an even dma transfer, could be trouble.");
+ }
+ return residue;
+}
+
+static void das16_interrupt(struct comedi_device * dev)
+{
+ unsigned long dma_flags, spin_flags;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async;
+ struct comedi_cmd *cmd;
+ int num_bytes, residue;
+ int buffer_index;
+
+ if (dev->attached == 0) {
+ comedi_error(dev, "premature interrupt");
+ return;
+ }
+ // initialize async here to make sure it is not NULL
+ async = s->async;
+ cmd = &async->cmd;
+
+ if (devpriv->dma_chan == 0) {
+ comedi_error(dev, "interrupt with no dma channel?");
+ return;
+ }
+
+ comedi_spin_lock_irqsave(&dev->spinlock, spin_flags);
+ if ((devpriv->control_state & DMA_ENABLE) == 0) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, spin_flags);
+ DEBUG_PRINT("interrupt while dma disabled?\n");
+ return;
+ }
+
+ dma_flags = claim_dma_lock();
+ clear_dma_ff(devpriv->dma_chan);
+ residue = disable_dma_on_even(dev);
+
+ // figure out how many points to read
+ if (residue > devpriv->dma_transfer_size) {
+ comedi_error(dev, "residue > transfer size!\n");
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ num_bytes = 0;
+ } else
+ num_bytes = devpriv->dma_transfer_size - residue;
+
+ if (cmd->stop_src == TRIG_COUNT && num_bytes >= devpriv->adc_byte_count) {
+ num_bytes = devpriv->adc_byte_count;
+ async->events |= COMEDI_CB_EOA;
+ }
+
+ buffer_index = devpriv->current_buffer;
+ devpriv->current_buffer = (devpriv->current_buffer + 1) % 2;
+ devpriv->adc_byte_count -= num_bytes;
+
+ // figure out how many bytes for next transfer
+ if (cmd->stop_src == TRIG_COUNT && devpriv->timer_mode == 0 &&
+ devpriv->dma_transfer_size > devpriv->adc_byte_count)
+ devpriv->dma_transfer_size = devpriv->adc_byte_count;
+
+ // re-enable dma
+ if ((async->events & COMEDI_CB_EOA) == 0) {
+ set_dma_addr(devpriv->dma_chan,
+ devpriv->dma_buffer_addr[devpriv->current_buffer]);
+ set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
+ enable_dma(devpriv->dma_chan);
+ /* reenable conversions for das1600 mode, (stupid hardware) */
+ if (thisboard->size > 0x400 && devpriv->timer_mode == 0) {
+ outb(0x00, dev->iobase + DAS1600_CONV);
+ }
+ }
+ release_dma_lock(dma_flags);
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, spin_flags);
+
+ cfc_write_array_to_buffer(s,
+ devpriv->dma_buffer[buffer_index], num_bytes);
+
+ cfc_handle_events(dev, s);
+}
+
+static unsigned int das16_set_pacer(struct comedi_device * dev, unsigned int ns,
+ int rounding_flags)
+{
+ i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1),
+ &(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK);
+
+ /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
+ i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 1, devpriv->divisor1, 2);
+ i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 2, devpriv->divisor2, 2);
+
+ return ns;
+}
+
+static void reg_dump(struct comedi_device * dev)
+{
+ DEBUG_PRINT("********DAS1600 REGISTER DUMP********\n");
+ DEBUG_PRINT("DAS16_MUX: %x\n", inb(dev->iobase + DAS16_MUX));
+ DEBUG_PRINT("DAS16_DIO: %x\n", inb(dev->iobase + DAS16_DIO));
+ DEBUG_PRINT("DAS16_STATUS: %x\n", inb(dev->iobase + DAS16_STATUS));
+ DEBUG_PRINT("DAS16_CONTROL: %x\n", inb(dev->iobase + DAS16_CONTROL));
+ DEBUG_PRINT("DAS16_PACER: %x\n", inb(dev->iobase + DAS16_PACER));
+ DEBUG_PRINT("DAS16_GAIN: %x\n", inb(dev->iobase + DAS16_GAIN));
+ DEBUG_PRINT("DAS16_CNTR_CONTROL: %x\n",
+ inb(dev->iobase + DAS16_CNTR_CONTROL));
+ DEBUG_PRINT("DAS1600_CONV: %x\n", inb(dev->iobase + DAS1600_CONV));
+ DEBUG_PRINT("DAS1600_BURST: %x\n", inb(dev->iobase + DAS1600_BURST));
+ DEBUG_PRINT("DAS1600_ENABLE: %x\n", inb(dev->iobase + DAS1600_ENABLE));
+ DEBUG_PRINT("DAS1600_STATUS_B: %x\n",
+ inb(dev->iobase + DAS1600_STATUS_B));
+}
+
+static int das16_probe(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int status;
+ int diobits;
+
+ /* status is available on all boards */
+
+ status = inb(dev->iobase + DAS16_STATUS);
+
+ if ((status & UNIPOLAR)) {
+ devpriv->ai_unipolar = 1;
+ } else {
+ devpriv->ai_unipolar = 0;
+ }
+
+ if ((status & DAS16_MUXBIT)) {
+ devpriv->ai_singleended = 1;
+ } else {
+ devpriv->ai_singleended = 0;
+ }
+
+ /* diobits indicates boards */
+
+ diobits = inb(dev->iobase + DAS16_DIO) & 0xf0;
+
+ printk(" id bits are 0x%02x\n", diobits);
+ if (thisboard->id != diobits) {
+ printk(" requested board's id bits are 0x%x (ignore)\n",
+ thisboard->id);
+ }
+
+ return 0;
+}
+
+static int das1600_mode_detect(struct comedi_device * dev)
+{
+ int status = 0;
+
+ status = inb(dev->iobase + DAS1600_STATUS_B);
+
+ if (status & DAS1600_CLK_10MHZ) {
+ devpriv->clockbase = 100;
+ printk(" 10MHz pacer clock\n");
+ } else {
+ devpriv->clockbase = 1000;
+ printk(" 1MHz pacer clock\n");
+ }
+
+ reg_dump(dev);
+
+ return 0;
+}
+
+/*
+ *
+ * Options list:
+ * 0 I/O base
+ * 1 IRQ
+ * 2 DMA
+ * 3 Clock speed (in MHz)
+ */
+
+static int das16_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret;
+ unsigned int irq;
+ unsigned long iobase;
+ unsigned int dma_chan;
+ int timer_mode;
+ unsigned long flags;
+ struct comedi_krange *user_ai_range, *user_ao_range;
+
+ iobase = it->options[0];
+#if 0
+ irq = it->options[1];
+ timer_mode = it->options[8];
+#endif
+ /* always use time_mode since using irq can drop samples while
+ * waiting for dma done interrupt (due to hardware limitations) */
+ irq = 0;
+ timer_mode = 1;
+ if (timer_mode)
+ irq = 0;
+
+ printk("comedi%d: das16:", dev->minor);
+
+ // check that clock setting is valid
+ if (it->options[3]) {
+ if (it->options[3] != 0 &&
+ it->options[3] != 1 && it->options[3] != 10) {
+ printk("\n Invalid option. Master clock must be set to 1 or 10 (MHz)\n");
+ return -EINVAL;
+ }
+ }
+
+ if ((ret = alloc_private(dev, sizeof(struct das16_private_struct))) < 0)
+ return ret;
+
+ if (thisboard->size < 0x400) {
+ printk(" 0x%04lx-0x%04lx\n", iobase, iobase + thisboard->size);
+ if (!request_region(iobase, thisboard->size, "das16")) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ } else {
+ printk(" 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n",
+ iobase, iobase + 0x0f,
+ iobase + 0x400,
+ iobase + 0x400 + (thisboard->size & 0x3ff));
+ if (!request_region(iobase, 0x10, "das16")) {
+ printk(" I/O port conflict: 0x%04lx-0x%04lx\n",
+ iobase, iobase + 0x0f);
+ return -EIO;
+ }
+ if (!request_region(iobase + 0x400, thisboard->size & 0x3ff,
+ "das16")) {
+ release_region(iobase, 0x10);
+ printk(" I/O port conflict: 0x%04lx-0x%04lx\n",
+ iobase + 0x400,
+ iobase + 0x400 + (thisboard->size & 0x3ff));
+ return -EIO;
+ }
+ }
+
+ dev->iobase = iobase;
+
+ // probe id bits to make sure they are consistent
+ if (das16_probe(dev, it)) {
+ printk(" id bits do not match selected board, aborting\n");
+ return -EINVAL;
+ }
+ dev->board_name = thisboard->name;
+
+ // get master clock speed
+ if (thisboard->size < 0x400) {
+ if (it->options[3])
+ devpriv->clockbase = 1000 / it->options[3];
+ else
+ devpriv->clockbase = 1000; // 1 MHz default
+ } else {
+ das1600_mode_detect(dev);
+ }
+
+ /* now for the irq */
+ if (irq > 1 && irq < 8) {
+ if ((ret = comedi_request_irq(irq, das16_dma_interrupt, 0,
+ "das16", dev)) < 0)
+ return ret;
+ dev->irq = irq;
+ printk(" ( irq = %u )", irq);
+ } else if (irq == 0) {
+ printk(" ( no irq )");
+ } else {
+ printk(" invalid irq\n");
+ return -EINVAL;
+ }
+
+ // initialize dma
+ dma_chan = it->options[2];
+ if (dma_chan == 1 || dma_chan == 3) {
+ // allocate dma buffers
+ int i;
+ for (i = 0; i < 2; i++) {
+ devpriv->dma_buffer[i] = pci_alloc_consistent(NULL,
+ DAS16_DMA_SIZE, &devpriv->dma_buffer_addr[i]);
+ if (devpriv->dma_buffer[i] == NULL)
+ return -ENOMEM;
+ }
+ if (request_dma(dma_chan, "das16")) {
+ printk(" failed to allocate dma channel %i\n",
+ dma_chan);
+ return -EINVAL;
+ }
+ devpriv->dma_chan = dma_chan;
+ flags = claim_dma_lock();
+ disable_dma(devpriv->dma_chan);
+ set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
+ release_dma_lock(flags);
+ printk(" ( dma = %u)\n", dma_chan);
+ } else if (dma_chan == 0) {
+ printk(" ( no dma )\n");
+ } else {
+ printk(" invalid dma channel\n");
+ return -EINVAL;
+ }
+
+ // get any user-defined input range
+ if (thisboard->ai_pg == das16_pg_none &&
+ (it->options[4] || it->options[5])) {
+ // allocate single-range range table
+ devpriv->user_ai_range_table =
+ kmalloc(sizeof(struct comedi_lrange) + sizeof(struct comedi_krange),
+ GFP_KERNEL);
+ // initialize ai range
+ devpriv->user_ai_range_table->length = 1;
+ user_ai_range = devpriv->user_ai_range_table->range;
+ user_ai_range->min = it->options[4];
+ user_ai_range->max = it->options[5];
+ user_ai_range->flags = UNIT_volt;
+ }
+ // get any user-defined output range
+ if (it->options[6] || it->options[7]) {
+ // allocate single-range range table
+ devpriv->user_ao_range_table =
+ kmalloc(sizeof(struct comedi_lrange) + sizeof(struct comedi_krange),
+ GFP_KERNEL);
+ // initialize ao range
+ devpriv->user_ao_range_table->length = 1;
+ user_ao_range = devpriv->user_ao_range_table->range;
+ user_ao_range->min = it->options[6];
+ user_ao_range->max = it->options[7];
+ user_ao_range->flags = UNIT_volt;
+ }
+
+ if (timer_mode) {
+ init_timer(&(devpriv->timer));
+ devpriv->timer.function = das16_timer_interrupt;
+ devpriv->timer.data = (unsigned long)dev;
+ }
+ devpriv->timer_mode = timer_mode ? 1 : 0;
+
+ if ((ret = alloc_subdevices(dev, 5)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ /* ai */
+ if (thisboard->ai) {
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ if (devpriv->ai_singleended) {
+ s->n_chan = 16;
+ s->len_chanlist = 16;
+ s->subdev_flags |= SDF_GROUND;
+ } else {
+ s->n_chan = 8;
+ s->len_chanlist = 8;
+ s->subdev_flags |= SDF_DIFF;
+ }
+ s->maxdata = (1 << thisboard->ai_nbits) - 1;
+ if (devpriv->user_ai_range_table) { // user defined ai range
+ s->range_table = devpriv->user_ai_range_table;
+ } else if (devpriv->ai_unipolar) {
+ s->range_table = das16_ai_uni_lranges[thisboard->ai_pg];
+ } else {
+ s->range_table = das16_ai_bip_lranges[thisboard->ai_pg];
+ }
+ s->insn_read = thisboard->ai;
+ s->do_cmdtest = das16_cmd_test;
+ s->do_cmd = das16_cmd_exec;
+ s->cancel = das16_cancel;
+ s->munge = das16_ai_munge;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 1;
+ /* ao */
+ if (thisboard->ao) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->maxdata = (1 << thisboard->ao_nbits) - 1;
+ if (devpriv->user_ao_range_table) { // user defined ao range
+ s->range_table = devpriv->user_ao_range_table;
+ } else {
+ s->range_table = &range_unknown;
+ }
+ s->insn_write = thisboard->ao;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 2;
+ /* di */
+ if (thisboard->di) {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = thisboard->di;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 3;
+ /* do */
+ if (thisboard->do_) {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = thisboard->do_;
+ // initialize digital output lines
+ outb(s->state, dev->iobase + DAS16_DIO);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 4;
+ /* 8255 */
+ if (thisboard->i8255_offset != 0) {
+ subdev_8255_init(dev, s, NULL, (dev->iobase +
+ thisboard->i8255_offset));
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ das16_reset(dev);
+ /* set the interrupt level */
+ devpriv->control_state = DAS16_IRQ(dev->irq);
+ outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
+
+ // turn on das1600 mode if available
+ if (thisboard->size > 0x400) {
+ outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE);
+ outb(0, dev->iobase + DAS1600_CONV);
+ outb(0, dev->iobase + DAS1600_BURST);
+ }
+
+ return 0;
+}
+
+static int das16_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: das16: remove\n", dev->minor);
+
+ das16_reset(dev);
+
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 4);
+
+ if (devpriv) {
+ int i;
+ for (i = 0; i < 2; i++) {
+ if (devpriv->dma_buffer[i])
+ pci_free_consistent(NULL, DAS16_DMA_SIZE,
+ devpriv->dma_buffer[i],
+ devpriv->dma_buffer_addr[i]);
+ }
+ if (devpriv->dma_chan)
+ free_dma(devpriv->dma_chan);
+ if (devpriv->user_ai_range_table)
+ kfree(devpriv->user_ai_range_table);
+ if (devpriv->user_ao_range_table)
+ kfree(devpriv->user_ao_range_table);
+ }
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (dev->iobase) {
+ if (thisboard->size < 0x400) {
+ release_region(dev->iobase, thisboard->size);
+ } else {
+ release_region(dev->iobase, 0x10);
+ release_region(dev->iobase + 0x400,
+ thisboard->size & 0x3ff);
+ }
+ }
+
+ return 0;
+}
+
+COMEDI_INITCLEANUP(driver_das16);
+
+// utility function that suggests a dma transfer size in bytes
+static unsigned int das16_suggest_transfer_size(struct comedi_device * dev,
+ struct comedi_cmd cmd)
+{
+ unsigned int size;
+ unsigned int freq;
+
+ /* if we are using timer interrupt, we don't care how long it
+ * will take to complete transfer since it will be interrupted
+ * by timer interrupt */
+ if (devpriv->timer_mode)
+ return DAS16_DMA_SIZE;
+
+ /* otherwise, we are relying on dma terminal count interrupt,
+ * so pick a reasonable size */
+ if (cmd.convert_src == TRIG_TIMER)
+ freq = 1000000000 / cmd.convert_arg;
+ else if (cmd.scan_begin_src == TRIG_TIMER)
+ freq = (1000000000 / cmd.scan_begin_arg) * cmd.chanlist_len;
+ // return some default value
+ else
+ freq = 0xffffffff;
+
+ if (cmd.flags & TRIG_WAKE_EOS) {
+ size = sample_size * cmd.chanlist_len;
+ } else {
+ // make buffer fill in no more than 1/3 second
+ size = (freq / 3) * sample_size;
+ }
+
+ // set a minimum and maximum size allowed
+ if (size > DAS16_DMA_SIZE)
+ size = DAS16_DMA_SIZE - DAS16_DMA_SIZE % sample_size;
+ else if (size < sample_size)
+ size = sample_size;
+
+ if (cmd.stop_src == TRIG_COUNT && size > devpriv->adc_byte_count)
+ size = devpriv->adc_byte_count;
+
+ return size;
+}
+
+static void das16_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *array, unsigned int num_bytes, unsigned int start_chan_index)
+{
+ unsigned int i, num_samples = num_bytes / sizeof(short);
+ short *data = array;
+
+ for (i = 0; i < num_samples; i++) {
+ data[i] = le16_to_cpu(data[i]);
+ if (thisboard->ai_nbits == 12) {
+ data[i] = (data[i] >> 4) & 0xfff;
+ }
+ }
+}
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
new file mode 100644
index 00000000000..0e423e199ed
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das16m1.c
@@ -0,0 +1,765 @@
+/*
+ comedi/drivers/das16m1.c
+ CIO-DAS16/M1 driver
+ Author: Frank Mori Hess, based on code from the das16
+ driver.
+ Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: das16m1
+Description: CIO-DAS16/M1
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [Measurement Computing] CIO-DAS16/M1 (cio-das16/m1)
+Status: works
+
+This driver supports a single board - the CIO-DAS16/M1.
+As far as I know, there are no other boards that have
+the same register layout. Even the CIO-DAS16/M1/16 is
+significantly different.
+
+I was _barely_ able to reach the full 1 MHz capability
+of this board, using a hard real-time interrupt
+(set the TRIG_RT flag in your struct comedi_cmd and use
+rtlinux or RTAI). The board can't do dma, so the bottleneck is
+pulling the data across the ISA bus. I timed the interrupt
+handler, and it took my computer ~470 microseconds to pull 512
+samples from the board. So at 1 Mhz sampling rate,
+expect your CPU to be spending almost all of its
+time in the interrupt handler.
+
+This board has some unusual restrictions for its channel/gain list. If the
+list has 2 or more channels in it, then two conditions must be satisfied:
+(1) - even/odd channels must appear at even/odd indices in the list
+(2) - the list must have an even number of entries.
+
+Options:
+ [0] - base io address
+ [1] - irq (optional, but you probably want it)
+
+irq can be omitted, although the cmd interface will not work without it.
+*/
+
+#include <linux/ioport.h>
+#include "../comedidev.h"
+
+#include "8255.h"
+#include "8253.h"
+#include "comedi_fc.h"
+
+#define DAS16M1_SIZE 16
+#define DAS16M1_SIZE2 8
+
+#define DAS16M1_XTAL 100 //10 MHz master clock
+
+#define FIFO_SIZE 1024 // 1024 sample fifo
+
+/*
+ CIO-DAS16_M1.pdf
+
+ "cio-das16/m1"
+
+ 0 a/d bits 0-3, mux start 12 bit
+ 1 a/d bits 4-11 unused
+ 2 status control
+ 3 di 4 bit do 4 bit
+ 4 unused clear interrupt
+ 5 interrupt, pacer
+ 6 channel/gain queue address
+ 7 channel/gain queue data
+ 89ab 8254
+ cdef 8254
+ 400 8255
+ 404-407 8254
+
+*/
+
+#define DAS16M1_AI 0 // 16-bit wide register
+#define AI_CHAN(x) ((x) & 0xf)
+#define DAS16M1_CS 2
+#define EXT_TRIG_BIT 0x1
+#define OVRUN 0x20
+#define IRQDATA 0x80
+#define DAS16M1_DIO 3
+#define DAS16M1_CLEAR_INTR 4
+#define DAS16M1_INTR_CONTROL 5
+#define EXT_PACER 0x2
+#define INT_PACER 0x3
+#define PACER_MASK 0x3
+#define INTE 0x80
+#define DAS16M1_QUEUE_ADDR 6
+#define DAS16M1_QUEUE_DATA 7
+#define Q_CHAN(x) ((x) & 0x7)
+#define Q_RANGE(x) (((x) & 0xf) << 4)
+#define UNIPOLAR 0x40
+#define DAS16M1_8254_FIRST 0x8
+#define DAS16M1_8254_FIRST_CNTRL 0xb
+#define TOTAL_CLEAR 0x30
+#define DAS16M1_8254_SECOND 0xc
+#define DAS16M1_82C55 0x400
+#define DAS16M1_8254_THIRD 0x404
+
+static const struct comedi_lrange range_das16m1 = { 9,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ BIP_RANGE(10),
+ }
+};
+
+static int das16m1_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16m1_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16m1_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int das16m1_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int das16m1_cmd_exec(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das16m1_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static int das16m1_poll(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t das16m1_interrupt(int irq, void *d PT_REGS_ARG);
+static void das16m1_handler(struct comedi_device * dev, unsigned int status);
+
+static unsigned int das16m1_set_pacer(struct comedi_device * dev, unsigned int ns,
+ int round_flag);
+
+static int das16m1_irq_bits(unsigned int irq);
+
+struct das16m1_board {
+ const char *name;
+ unsigned int ai_speed;
+};
+
+static const struct das16m1_board das16m1_boards[] = {
+ {
+ name: "cio-das16/m1", // CIO-DAS16_M1.pdf
+ ai_speed:1000, // 1MHz max speed
+ },
+};
+
+#define das16m1_num_boards ((sizeof(das16m1_boards)) / (sizeof(das16m1_boards[0])))
+
+static int das16m1_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das16m1_detach(struct comedi_device * dev);
+static struct comedi_driver driver_das16m1 = {
+ driver_name:"das16m1",
+ module:THIS_MODULE,
+ attach:das16m1_attach,
+ detach:das16m1_detach,
+ board_name:&das16m1_boards[0].name,
+ num_names:das16m1_num_boards,
+ offset:sizeof(das16m1_boards[0]),
+};
+
+struct das16m1_private_struct {
+ unsigned int control_state;
+ volatile unsigned int adc_count; // number of samples completed
+ /* initial value in lower half of hardware conversion counter,
+ * needed to keep track of whether new count has been loaded into
+ * counter yet (loaded by first sample conversion) */
+ u16 initial_hw_count;
+ short ai_buffer[FIFO_SIZE];
+ unsigned int do_bits; // saves status of digital output bits
+ unsigned int divisor1; // divides master clock to obtain conversion speed
+ unsigned int divisor2; // divides master clock to obtain conversion speed
+};
+#define devpriv ((struct das16m1_private_struct *)(dev->private))
+#define thisboard ((const struct das16m1_board *)(dev->board_ptr))
+
+COMEDI_INITCLEANUP(driver_das16m1);
+
+static inline short munge_sample(short data)
+{
+ return (data >> 4) & 0xfff;
+}
+
+static int das16m1_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ unsigned int err = 0, tmp, i;
+
+ /* make sure triggers are valid */
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ /* internal trigger */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ /* any count is allowed */
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ /* calculate counter values that give desired timing */
+ i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ // check chanlist against board's peculiarities
+ if (cmd->chanlist && cmd->chanlist_len > 1) {
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ // even/odd channels must go into even/odd queue addresses
+ if ((i % 2) != (CR_CHAN(cmd->chanlist[i]) % 2)) {
+ comedi_error(dev, "bad chanlist:\n"
+ " even/odd channels must go have even/odd chanlist indices");
+ err++;
+ }
+ }
+ if ((cmd->chanlist_len % 2) != 0) {
+ comedi_error(dev,
+ "chanlist must be of even length or length 1");
+ err++;
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int das16m1_cmd_exec(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int byte, i;
+
+ if (dev->irq == 0) {
+ comedi_error(dev, "irq required to execute comedi_cmd");
+ return -1;
+ }
+
+ /* disable interrupts and internal pacer */
+ devpriv->control_state &= ~INTE & ~PACER_MASK;
+ outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+ // set software count
+ devpriv->adc_count = 0;
+ /* Initialize lower half of hardware counter, used to determine how
+ * many samples are in fifo. Value doesn't actually load into counter
+ * until counter's next clock (the next a/d conversion) */
+ i8254_load(dev->iobase + DAS16M1_8254_FIRST, 0, 1, 0, 2);
+ /* remember current reading of counter so we know when counter has
+ * actually been loaded */
+ devpriv->initial_hw_count =
+ i8254_read(dev->iobase + DAS16M1_8254_FIRST, 0, 1);
+ /* setup channel/gain queue */
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ outb(i, dev->iobase + DAS16M1_QUEUE_ADDR);
+ byte = Q_CHAN(CR_CHAN(cmd->
+ chanlist[i])) | Q_RANGE(CR_RANGE(cmd->
+ chanlist[i]));
+ outb(byte, dev->iobase + DAS16M1_QUEUE_DATA);
+ }
+
+ /* set counter mode and counts */
+ cmd->convert_arg =
+ das16m1_set_pacer(dev, cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+
+ // set control & status register
+ byte = 0;
+ /* if we are using external start trigger (also board dislikes having
+ * both start and conversion triggers external simultaneously) */
+ if (cmd->start_src == TRIG_EXT && cmd->convert_src != TRIG_EXT) {
+ byte |= EXT_TRIG_BIT;
+ }
+ outb(byte, dev->iobase + DAS16M1_CS);
+ /* clear interrupt bit */
+ outb(0, dev->iobase + DAS16M1_CLEAR_INTR);
+
+ /* enable interrupts and internal pacer */
+ devpriv->control_state &= ~PACER_MASK;
+ if (cmd->convert_src == TRIG_TIMER) {
+ devpriv->control_state |= INT_PACER;
+ } else {
+ devpriv->control_state |= EXT_PACER;
+ }
+ devpriv->control_state |= INTE;
+ outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+ return 0;
+}
+
+static int das16m1_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ devpriv->control_state &= ~INTE & ~PACER_MASK;
+ outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+ return 0;
+}
+
+static int das16m1_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int byte;
+ const int timeout = 1000;
+
+ /* disable interrupts and internal pacer */
+ devpriv->control_state &= ~INTE & ~PACER_MASK;
+ outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+ /* setup channel/gain queue */
+ outb(0, dev->iobase + DAS16M1_QUEUE_ADDR);
+ byte = Q_CHAN(CR_CHAN(insn->chanspec)) | Q_RANGE(CR_RANGE(insn->
+ chanspec));
+ outb(byte, dev->iobase + DAS16M1_QUEUE_DATA);
+
+ for (n = 0; n < insn->n; n++) {
+ /* clear IRQDATA bit */
+ outb(0, dev->iobase + DAS16M1_CLEAR_INTR);
+ /* trigger conversion */
+ outb(0, dev->iobase);
+
+ for (i = 0; i < timeout; i++) {
+ if (inb(dev->iobase + DAS16M1_CS) & IRQDATA)
+ break;
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timeout");
+ return -ETIME;
+ }
+ data[n] = munge_sample(inw(dev->iobase));
+ }
+
+ return n;
+}
+
+static int das16m1_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits;
+
+ bits = inb(dev->iobase + DAS16M1_DIO) & 0xf;
+ data[1] = bits;
+ data[0] = 0;
+
+ return 2;
+}
+
+static int das16m1_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int wbits;
+
+ // only set bits that have been masked
+ data[0] &= 0xf;
+ wbits = devpriv->do_bits;
+ // zero bits that have been masked
+ wbits &= ~data[0];
+ // set masked bits
+ wbits |= data[0] & data[1];
+ devpriv->do_bits = wbits;
+ data[1] = wbits;
+
+ outb(devpriv->do_bits, dev->iobase + DAS16M1_DIO);
+
+ return 2;
+}
+
+static int das16m1_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+ unsigned int status;
+
+ // prevent race with interrupt handler
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ status = inb(dev->iobase + DAS16M1_CS);
+ das16m1_handler(dev, status);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return s->async->buf_write_count - s->async->buf_read_count;
+}
+
+static irqreturn_t das16m1_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ int status;
+ struct comedi_device *dev = d;
+
+ if (dev->attached == 0) {
+ comedi_error(dev, "premature interrupt");
+ return IRQ_HANDLED;
+ }
+ // prevent race with comedi_poll()
+ spin_lock(&dev->spinlock);
+
+ status = inb(dev->iobase + DAS16M1_CS);
+
+ if ((status & (IRQDATA | OVRUN)) == 0) {
+ comedi_error(dev, "spurious interrupt");
+ spin_unlock(&dev->spinlock);
+ return IRQ_NONE;
+ }
+
+ das16m1_handler(dev, status);
+
+ /* clear interrupt */
+ outb(0, dev->iobase + DAS16M1_CLEAR_INTR);
+
+ spin_unlock(&dev->spinlock);
+ return IRQ_HANDLED;
+}
+
+static void munge_sample_array(short * array, unsigned int num_elements)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_elements; i++) {
+ array[i] = munge_sample(array[i]);
+ }
+}
+
+static void das16m1_handler(struct comedi_device * dev, unsigned int status)
+{
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
+ struct comedi_cmd *cmd;
+ u16 num_samples;
+ u16 hw_counter;
+
+ s = dev->read_subdev;
+ async = s->async;
+ async->events = 0;
+ cmd = &async->cmd;
+
+ // figure out how many samples are in fifo
+ hw_counter = i8254_read(dev->iobase + DAS16M1_8254_FIRST, 0, 1);
+ /* make sure hardware counter reading is not bogus due to initial value
+ * not having been loaded yet */
+ if (devpriv->adc_count == 0 && hw_counter == devpriv->initial_hw_count) {
+ num_samples = 0;
+ } else {
+ /* The calculation of num_samples looks odd, but it uses the following facts.
+ * 16 bit hardware counter is initialized with value of zero (which really
+ * means 0x1000). The counter decrements by one on each conversion
+ * (when the counter decrements from zero it goes to 0xffff). num_samples
+ * is a 16 bit variable, so it will roll over in a similar fashion to the
+ * hardware counter. Work it out, and this is what you get. */
+ num_samples = -hw_counter - devpriv->adc_count;
+ }
+ // check if we only need some of the points
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (num_samples > cmd->stop_arg * cmd->chanlist_len)
+ num_samples = cmd->stop_arg * cmd->chanlist_len;
+ }
+ // make sure we dont try to get too many points if fifo has overrun
+ if (num_samples > FIFO_SIZE)
+ num_samples = FIFO_SIZE;
+ insw(dev->iobase, devpriv->ai_buffer, num_samples);
+ munge_sample_array(devpriv->ai_buffer, num_samples);
+ cfc_write_array_to_buffer(s, devpriv->ai_buffer,
+ num_samples * sizeof(short));
+ devpriv->adc_count += num_samples;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (devpriv->adc_count >= cmd->stop_arg * cmd->chanlist_len) { /* end of acquisition */
+ das16m1_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA;
+ }
+ }
+
+ /* this probably won't catch overruns since the card doesn't generate
+ * overrun interrupts, but we might as well try */
+ if (status & OVRUN) {
+ das16m1_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_error(dev, "fifo overflow");
+ }
+
+ comedi_event(dev, s);
+
+}
+
+/* This function takes a time in nanoseconds and sets the *
+ * 2 pacer clocks to the closest frequency possible. It also *
+ * returns the actual sampling period. */
+static unsigned int das16m1_set_pacer(struct comedi_device * dev, unsigned int ns,
+ int rounding_flags)
+{
+ i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL, &(devpriv->divisor1),
+ &(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK);
+
+ /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
+ i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 1, devpriv->divisor1,
+ 2);
+ i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 2, devpriv->divisor2,
+ 2);
+
+ return ns;
+}
+
+static int das16m1_irq_bits(unsigned int irq)
+{
+ int ret;
+
+ switch (irq) {
+ case 10:
+ ret = 0x0;
+ break;
+ case 11:
+ ret = 0x1;
+ break;
+ case 12:
+ ret = 0x2;
+ break;
+ case 15:
+ ret = 0x3;
+ break;
+ case 2:
+ ret = 0x4;
+ break;
+ case 3:
+ ret = 0x5;
+ break;
+ case 5:
+ ret = 0x6;
+ break;
+ case 7:
+ ret = 0x7;
+ break;
+ default:
+ return -1;
+ break;
+ }
+ return (ret << 4);
+}
+
+/*
+ * Options list:
+ * 0 I/O base
+ * 1 IRQ
+ */
+
+static int das16m1_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret;
+ unsigned int irq;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+
+ printk("comedi%d: das16m1:", dev->minor);
+
+ if ((ret = alloc_private(dev,
+ sizeof(struct das16m1_private_struct))) < 0)
+ return ret;
+
+ dev->board_name = thisboard->name;
+
+ printk(" io 0x%lx-0x%lx 0x%lx-0x%lx",
+ iobase, iobase + DAS16M1_SIZE,
+ iobase + DAS16M1_82C55, iobase + DAS16M1_82C55 + DAS16M1_SIZE2);
+ if (!request_region(iobase, DAS16M1_SIZE, driver_das16m1.driver_name)) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ if (!request_region(iobase + DAS16M1_82C55, DAS16M1_SIZE2,
+ driver_das16m1.driver_name)) {
+ release_region(iobase, DAS16M1_SIZE);
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* now for the irq */
+ irq = it->options[1];
+ // make sure it is valid
+ if (das16m1_irq_bits(irq) >= 0) {
+ ret = comedi_request_irq(irq, das16m1_interrupt, 0,
+ driver_das16m1.driver_name, dev);
+ if (ret < 0) {
+ printk(", irq unavailable\n");
+ return ret;
+ }
+ dev->irq = irq;
+ printk(", irq %u\n", irq);
+ } else if (irq == 0) {
+ printk(", no irq\n");
+ } else {
+ printk(", invalid irq\n"
+ " valid irqs are 2, 3, 5, 7, 10, 11, 12, or 15\n");
+ return -EINVAL;
+ }
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ /* ai */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = 8;
+ s->subdev_flags = SDF_DIFF;
+ s->len_chanlist = 256;
+ s->maxdata = (1 << 12) - 1;
+ s->range_table = &range_das16m1;
+ s->insn_read = das16m1_ai_rinsn;
+ s->do_cmdtest = das16m1_cmd_test;
+ s->do_cmd = das16m1_cmd_exec;
+ s->cancel = das16m1_cancel;
+ s->poll = das16m1_poll;
+
+ s = dev->subdevices + 1;
+ /* di */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das16m1_di_rbits;
+
+ s = dev->subdevices + 2;
+ /* do */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das16m1_do_wbits;
+
+ s = dev->subdevices + 3;
+ /* 8255 */
+ subdev_8255_init(dev, s, NULL, dev->iobase + DAS16M1_82C55);
+
+ // disable upper half of hardware conversion counter so it doesn't mess with us
+ outb(TOTAL_CLEAR, dev->iobase + DAS16M1_8254_FIRST_CNTRL);
+
+ // initialize digital output lines
+ outb(devpriv->do_bits, dev->iobase + DAS16M1_DIO);
+
+ /* set the interrupt level */
+ if (dev->irq)
+ devpriv->control_state = das16m1_irq_bits(dev->irq);
+ else
+ devpriv->control_state = 0;
+ outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+ return 0;
+}
+
+static int das16m1_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: das16m1: remove\n", dev->minor);
+
+// das16m1_reset(dev);
+
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 3);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (dev->iobase) {
+ release_region(dev->iobase, DAS16M1_SIZE);
+ release_region(dev->iobase + DAS16M1_82C55, DAS16M1_SIZE2);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
new file mode 100644
index 00000000000..cd4cd4e6a79
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -0,0 +1,1758 @@
+/*
+ comedi/drivers/das1800.c
+ Driver for Keitley das1700/das1800 series boards
+ Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: das1800
+Description: Keithley Metrabyte DAS1800 (& compatibles)
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
+ DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
+ DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
+ DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
+ DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
+ DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
+ DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
+ DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
+ DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
+ DAS-1802AO (das-1802ao)
+Status: works
+
+The waveform analog output on the 'ao' cards is not supported.
+If you need it, send me (Frank Hess) an email.
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ (optional, required for timed or externally triggered conversions)
+ [2] - DMA0 (optional, requires irq)
+ [3] - DMA1 (optional, requires irq and dma0)
+*/
+/*
+
+This driver supports the following Keithley boards:
+
+das-1701st
+das-1701st-da
+das-1701ao
+das-1702st
+das-1702st-da
+das-1702hr
+das-1702hr-da
+das-1702ao
+das-1801st
+das-1801st-da
+das-1801hc
+das-1801ao
+das-1802st
+das-1802st-da
+das-1802hr
+das-1802hr-da
+das-1802hc
+das-1802ao
+
+Options:
+ [0] - base io address
+ [1] - irq (optional, required for timed or externally triggered conversions)
+ [2] - dma0 (optional, requires irq)
+ [3] - dma1 (optional, requires irq and dma0)
+
+irq can be omitted, although the cmd interface will not work without it.
+
+analog input cmd triggers supported:
+ start_src: TRIG_NOW | TRIG_EXT
+ scan_begin_src: TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT
+ scan_end_src: TRIG_COUNT
+ convert_src: TRIG_TIMER | TRIG_EXT (TRIG_EXT requires scan_begin_src == TRIG_FOLLOW)
+ stop_src: TRIG_COUNT | TRIG_EXT | TRIG_NONE
+
+scan_begin_src triggers TRIG_TIMER and TRIG_EXT use the card's
+'burst mode' which limits the valid conversion time to 64 microseconds
+(convert_arg <= 64000). This limitation does not apply if scan_begin_src
+is TRIG_FOLLOW.
+
+NOTES:
+Only the DAS-1801ST has been tested by me.
+Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
+
+TODO:
+ Make it automatically allocate irq and dma channels if they are not specified
+ Add support for analog out on 'ao' cards
+ read insn for analog out
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+#include "comedi_fc.h"
+
+// misc. defines
+#define DAS1800_SIZE 16 //uses 16 io addresses
+#define FIFO_SIZE 1024 // 1024 sample fifo
+#define TIMER_BASE 200 // 5 Mhz master clock
+#define UNIPOLAR 0x4 // bit that determines whether input range is uni/bipolar
+#define DMA_BUF_SIZE 0x1ff00 // size in bytes of dma buffers
+
+/* Registers for the das1800 */
+#define DAS1800_FIFO 0x0
+#define DAS1800_QRAM 0x0
+#define DAS1800_DAC 0x0
+#define DAS1800_SELECT 0x2
+#define ADC 0x0
+#define QRAM 0x1
+#define DAC(a) (0x2 + a)
+#define DAS1800_DIGITAL 0x3
+#define DAS1800_CONTROL_A 0x4
+#define FFEN 0x1
+#define CGEN 0x4
+#define CGSL 0x8
+#define TGEN 0x10
+#define TGSL 0x20
+#define ATEN 0x80
+#define DAS1800_CONTROL_B 0x5
+#define DMA_CH5 0x1
+#define DMA_CH6 0x2
+#define DMA_CH7 0x3
+#define DMA_CH5_CH6 0x5
+#define DMA_CH6_CH7 0x6
+#define DMA_CH7_CH5 0x7
+#define DMA_ENABLED 0x3 //mask used to determine if dma is enabled
+#define DMA_DUAL 0x4
+#define IRQ3 0x8
+#define IRQ5 0x10
+#define IRQ7 0x18
+#define IRQ10 0x28
+#define IRQ11 0x30
+#define IRQ15 0x38
+#define FIMD 0x40
+#define DAS1800_CONTROL_C 0X6
+#define IPCLK 0x1
+#define XPCLK 0x3
+#define BMDE 0x4
+#define CMEN 0x8
+#define UQEN 0x10
+#define SD 0x40
+#define UB 0x80
+#define DAS1800_STATUS 0x7
+// bits that prevent interrupt status bits (and CVEN) from being cleared on write
+#define CLEAR_INTR_MASK (CVEN_MASK | 0x1f)
+#define INT 0x1
+#define DMATC 0x2
+#define CT0TC 0x8
+#define OVF 0x10
+#define FHF 0x20
+#define FNE 0x40
+#define CVEN_MASK 0x40 // masks CVEN on write
+#define CVEN 0x80
+#define DAS1800_BURST_LENGTH 0x8
+#define DAS1800_BURST_RATE 0x9
+#define DAS1800_QRAM_ADDRESS 0xa
+#define DAS1800_COUNTER 0xc
+
+#define IOBASE2 0x400 //offset of additional ioports used on 'ao' cards
+
+enum {
+ das1701st, das1701st_da, das1702st, das1702st_da, das1702hr,
+ das1702hr_da,
+ das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da,
+ das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
+};
+
+static int das1800_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das1800_detach(struct comedi_device * dev);
+static int das1800_probe(struct comedi_device * dev);
+static int das1800_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t das1800_interrupt(int irq, void *d PT_REGS_ARG);
+static int das1800_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s);
+static void das1800_ai_handler(struct comedi_device * dev);
+static void das1800_handle_dma(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int status);
+static void das1800_flush_dma(struct comedi_device * dev, struct comedi_subdevice * s);
+static void das1800_flush_dma_channel(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int channel, uint16_t * buffer);
+static void das1800_handle_fifo_half_full(struct comedi_device * dev,
+ struct comedi_subdevice * s);
+static void das1800_handle_fifo_not_empty(struct comedi_device * dev,
+ struct comedi_subdevice * s);
+static int das1800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int das1800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das1800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das1800_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das1800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das1800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int das1800_set_frequency(struct comedi_device * dev);
+static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode);
+static unsigned int suggest_transfer_size(struct comedi_cmd * cmd);
+
+// analog input ranges
+static const struct comedi_lrange range_ai_das1801 = {
+ 8,
+ {
+ RANGE(-5, 5),
+ RANGE(-1, 1),
+ RANGE(-0.1, 0.1),
+ RANGE(-0.02, 0.02),
+ RANGE(0, 5),
+ RANGE(0, 1),
+ RANGE(0, 0.1),
+ RANGE(0, 0.02),
+ }
+};
+
+static const struct comedi_lrange range_ai_das1802 = {
+ 8,
+ {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 2.5),
+ RANGE(0, 1.25),
+ }
+};
+
+struct das1800_board {
+ const char *name;
+ int ai_speed; /* max conversion period in nanoseconds */
+ int resolution; /* bits of ai resolution */
+ int qram_len; /* length of card's channel / gain queue */
+ int common; /* supports AREF_COMMON flag */
+ int do_n_chan; /* number of digital output channels */
+ int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
+ int ao_n_chan; /* number of analog out channels */
+ const struct comedi_lrange *range_ai; /* available input ranges */
+};
+
+/* Warning: the maximum conversion speeds listed below are
+ * not always achievable depending on board setup (see
+ * user manual.)
+ */
+static const struct das1800_board das1800_boards[] = {
+ {
+ name: "das-1701st",
+ ai_speed:6250,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:0,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1701st-da",
+ ai_speed:6250,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:1,
+ ao_n_chan:4,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1702st",
+ ai_speed:6250,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:0,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1702st-da",
+ ai_speed:6250,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:1,
+ ao_n_chan:4,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1702hr",
+ ai_speed:20000,
+ resolution:16,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:0,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1702hr-da",
+ ai_speed:20000,
+ resolution:16,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:1,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1701ao",
+ ai_speed:6250,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:2,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1702ao",
+ ai_speed:6250,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:2,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1801st",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:0,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1801st-da",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:4,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1802st",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:0,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1802st-da",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:1,
+ ao_n_chan:4,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1802hr",
+ ai_speed:10000,
+ resolution:16,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:0,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1802hr-da",
+ ai_speed:10000,
+ resolution:16,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:1,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1801hc",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:64,
+ common: 0,
+ do_n_chan:8,
+ ao_ability:1,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1802hc",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:64,
+ common: 0,
+ do_n_chan:8,
+ ao_ability:1,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1801ao",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:2,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1802ao",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:2,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1802,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct das1800_board *)dev->board_ptr)
+
+struct das1800_private {
+ volatile unsigned int count; /* number of data points left to be taken */
+ unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
+ unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
+ int do_bits; /* digital output bits */
+ int irq_dma_bits; /* bits for control register b */
+ /* dma bits for control register b, stored so that dma can be
+ * turned on and off */
+ int dma_bits;
+ unsigned int dma0; /* dma channels used */
+ unsigned int dma1;
+ volatile unsigned int dma_current; /* dma channel currently in use */
+ uint16_t *ai_buf0; /* pointers to dma buffers */
+ uint16_t *ai_buf1;
+ uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */
+ unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
+ unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */
+ short ao_update_bits; /* remembers the last write to the 'update' dac */
+};
+
+#define devpriv ((struct das1800_private *)dev->private)
+
+// analog out range for boards with basic analog out
+static const struct comedi_lrange range_ao_1 = {
+ 1,
+ {
+ RANGE(-10, 10),
+ }
+};
+
+// analog out range for 'ao' boards
+/*
+static const struct comedi_lrange range_ao_2 = {
+ 2,
+ {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ }
+};
+*/
+
+static struct comedi_driver driver_das1800 = {
+ driver_name:"das1800",
+ module:THIS_MODULE,
+ attach:das1800_attach,
+ detach:das1800_detach,
+ num_names:sizeof(das1800_boards) / sizeof(struct das1800_board),
+ board_name:&das1800_boards[0].name,
+ offset:sizeof(struct das1800_board),
+};
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_das1800);
+
+static int das1800_init_dma(struct comedi_device * dev, unsigned int dma0,
+ unsigned int dma1)
+{
+ unsigned long flags;
+
+ // need an irq to do dma
+ if (dev->irq && dma0) {
+ //encode dma0 and dma1 into 2 digit hexadecimal for switch
+ switch ((dma0 & 0x7) | (dma1 << 4)) {
+ case 0x5: // dma0 == 5
+ devpriv->dma_bits |= DMA_CH5;
+ break;
+ case 0x6: // dma0 == 6
+ devpriv->dma_bits |= DMA_CH6;
+ break;
+ case 0x7: // dma0 == 7
+ devpriv->dma_bits |= DMA_CH7;
+ break;
+ case 0x65: // dma0 == 5, dma1 == 6
+ devpriv->dma_bits |= DMA_CH5_CH6;
+ break;
+ case 0x76: // dma0 == 6, dma1 == 7
+ devpriv->dma_bits |= DMA_CH6_CH7;
+ break;
+ case 0x57: // dma0 == 7, dma1 == 5
+ devpriv->dma_bits |= DMA_CH7_CH5;
+ break;
+ default:
+ printk(" only supports dma channels 5 through 7\n"
+ " Dual dma only allows the following combinations:\n"
+ " dma 5,6 / 6,7 / or 7,5\n");
+ return -EINVAL;
+ break;
+ }
+ if (request_dma(dma0, driver_das1800.driver_name)) {
+ printk(" failed to allocate dma channel %i\n", dma0);
+ return -EINVAL;
+ }
+ devpriv->dma0 = dma0;
+ devpriv->dma_current = dma0;
+ if (dma1) {
+ if (request_dma(dma1, driver_das1800.driver_name)) {
+ printk(" failed to allocate dma channel %i\n",
+ dma1);
+ return -EINVAL;
+ }
+ devpriv->dma1 = dma1;
+ }
+ devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
+ if (devpriv->ai_buf0 == NULL)
+ return -ENOMEM;
+ devpriv->dma_current_buf = devpriv->ai_buf0;
+ if (dma1) {
+ devpriv->ai_buf1 =
+ kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
+ if (devpriv->ai_buf1 == NULL)
+ return -ENOMEM;
+ }
+ flags = claim_dma_lock();
+ disable_dma(devpriv->dma0);
+ set_dma_mode(devpriv->dma0, DMA_MODE_READ);
+ if (dma1) {
+ disable_dma(devpriv->dma1);
+ set_dma_mode(devpriv->dma1, DMA_MODE_READ);
+ }
+ release_dma_lock(flags);
+ }
+ return 0;
+}
+
+static int das1800_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = it->options[0];
+ unsigned int irq = it->options[1];
+ unsigned int dma0 = it->options[2];
+ unsigned int dma1 = it->options[3];
+ unsigned long iobase2;
+ int board;
+ int retval;
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(struct das1800_private)) < 0)
+ return -ENOMEM;
+
+ printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name,
+ iobase);
+ if (irq) {
+ printk(", irq %u", irq);
+ if (dma0) {
+ printk(", dma %u", dma0);
+ if (dma1)
+ printk(" and %u", dma1);
+ }
+ }
+ printk("\n");
+
+ if (iobase == 0) {
+ printk(" io base address required\n");
+ return -EINVAL;
+ }
+
+ /* check if io addresses are available */
+ if (!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name)) {
+ printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase, iobase + DAS1800_SIZE - 1);
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ board = das1800_probe(dev);
+ if (board < 0) {
+ printk(" unable to determine board type\n");
+ return -ENODEV;
+ }
+
+ dev->board_ptr = das1800_boards + board;
+ dev->board_name = thisboard->name;
+
+ // if it is an 'ao' board with fancy analog out then we need extra io ports
+ if (thisboard->ao_ability == 2) {
+ iobase2 = iobase + IOBASE2;
+ if (!request_region(iobase2, DAS1800_SIZE,
+ driver_das1800.driver_name)) {
+ printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase2, iobase2 + DAS1800_SIZE - 1);
+ return -EIO;
+ }
+ devpriv->iobase2 = iobase2;
+ }
+
+ /* grab our IRQ */
+ if (irq) {
+ if (comedi_request_irq(irq, das1800_interrupt, 0,
+ driver_das1800.driver_name, dev)) {
+ printk(" unable to allocate irq %u\n", irq);
+ return -EINVAL;
+ }
+ }
+ dev->irq = irq;
+
+ // set bits that tell card which irq to use
+ switch (irq) {
+ case 0:
+ break;
+ case 3:
+ devpriv->irq_dma_bits |= 0x8;
+ break;
+ case 5:
+ devpriv->irq_dma_bits |= 0x10;
+ break;
+ case 7:
+ devpriv->irq_dma_bits |= 0x18;
+ break;
+ case 10:
+ devpriv->irq_dma_bits |= 0x28;
+ break;
+ case 11:
+ devpriv->irq_dma_bits |= 0x30;
+ break;
+ case 15:
+ devpriv->irq_dma_bits |= 0x38;
+ break;
+ default:
+ printk(" irq out of range\n");
+ return -EINVAL;
+ break;
+ }
+
+ retval = das1800_init_dma(dev, dma0, dma1);
+ if (retval < 0)
+ return retval;
+
+ if (devpriv->ai_buf0 == NULL) {
+ devpriv->ai_buf0 =
+ kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
+ if (devpriv->ai_buf0 == NULL)
+ return -ENOMEM;
+ }
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ /* analog input subdevice */
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ;
+ if (thisboard->common)
+ s->subdev_flags |= SDF_COMMON;
+ s->n_chan = thisboard->qram_len;
+ s->len_chanlist = thisboard->qram_len;
+ s->maxdata = (1 << thisboard->resolution) - 1;
+ s->range_table = thisboard->range_ai;
+ s->do_cmd = das1800_ai_do_cmd;
+ s->do_cmdtest = das1800_ai_do_cmdtest;
+ s->insn_read = das1800_ai_rinsn;
+ s->poll = das1800_ai_poll;
+ s->cancel = das1800_cancel;
+
+ /* analog out */
+ s = dev->subdevices + 1;
+ if (thisboard->ao_ability == 1) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->ao_n_chan;
+ s->maxdata = (1 << thisboard->resolution) - 1;
+ s->range_table = &range_ao_1;
+ s->insn_write = das1800_ao_winsn;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* di */
+ s = dev->subdevices + 2;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das1800_di_rbits;
+
+ /* do */
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = thisboard->do_n_chan;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das1800_do_wbits;
+
+ das1800_cancel(dev, dev->read_subdev);
+
+ // initialize digital out channels
+ outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
+
+ // initialize analog out channels
+ if (thisboard->ao_ability == 1) {
+ // select 'update' dac channel for baseAddress + 0x0
+ outb(DAC(thisboard->ao_n_chan - 1),
+ dev->iobase + DAS1800_SELECT);
+ outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
+ }
+
+ return 0;
+};
+
+static int das1800_detach(struct comedi_device * dev)
+{
+ /* only free stuff if it has been allocated by _attach */
+ if (dev->iobase)
+ release_region(dev->iobase, DAS1800_SIZE);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (dev->private) {
+ if (devpriv->iobase2)
+ release_region(devpriv->iobase2, DAS1800_SIZE);
+ if (devpriv->dma0)
+ free_dma(devpriv->dma0);
+ if (devpriv->dma1)
+ free_dma(devpriv->dma1);
+ if (devpriv->ai_buf0)
+ kfree(devpriv->ai_buf0);
+ if (devpriv->ai_buf1)
+ kfree(devpriv->ai_buf1);
+ }
+
+ printk("comedi%d: %s: remove\n", dev->minor,
+ driver_das1800.driver_name);
+
+ return 0;
+};
+
+/* probes and checks das-1800 series board type
+ */
+static int das1800_probe(struct comedi_device * dev)
+{
+ int id;
+ int board;
+
+ id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
+ board = ((struct das1800_board *) dev->board_ptr) - das1800_boards;
+
+ switch (id) {
+ case 0x3:
+ if (board == das1801st_da || board == das1802st_da ||
+ board == das1701st_da || board == das1702st_da) {
+ printk(" Board model: %s\n",
+ das1800_boards[board].name);
+ return board;
+ }
+ printk(" Board model (probed, not recommended): das-1800st-da series\n");
+ return das1801st;
+ break;
+ case 0x4:
+ if (board == das1802hr_da || board == das1702hr_da) {
+ printk(" Board model: %s\n",
+ das1800_boards[board].name);
+ return board;
+ }
+ printk(" Board model (probed, not recommended): das-1802hr-da\n");
+ return das1802hr;
+ break;
+ case 0x5:
+ if (board == das1801ao || board == das1802ao ||
+ board == das1701ao || board == das1702ao) {
+ printk(" Board model: %s\n",
+ das1800_boards[board].name);
+ return board;
+ }
+ printk(" Board model (probed, not recommended): das-1800ao series\n");
+ return das1801ao;
+ break;
+ case 0x6:
+ if (board == das1802hr || board == das1702hr) {
+ printk(" Board model: %s\n",
+ das1800_boards[board].name);
+ return board;
+ }
+ printk(" Board model (probed, not recommended): das-1802hr\n");
+ return das1802hr;
+ break;
+ case 0x7:
+ if (board == das1801st || board == das1802st ||
+ board == das1701st || board == das1702st) {
+ printk(" Board model: %s\n",
+ das1800_boards[board].name);
+ return board;
+ }
+ printk(" Board model (probed, not recommended): das-1800st series\n");
+ return das1801st;
+ break;
+ case 0x8:
+ if (board == das1801hc || board == das1802hc) {
+ printk(" Board model: %s\n",
+ das1800_boards[board].name);
+ return board;
+ }
+ printk(" Board model (probed, not recommended): das-1800hc series\n");
+ return das1801hc;
+ break;
+ default:
+ printk(" Board model: probe returned 0x%x (unknown, please report)\n", id);
+ return board;
+ break;
+ }
+ return -1;
+}
+
+static int das1800_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ // prevent race with interrupt handler
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ das1800_ai_handler(dev);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return s->async->buf_write_count - s->async->buf_read_count;
+}
+
+static irqreturn_t das1800_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ unsigned int status;
+
+ if (dev->attached == 0) {
+ comedi_error(dev, "premature interrupt");
+ return IRQ_HANDLED;
+ }
+
+ /* Prevent race with das1800_ai_poll() on multi processor systems.
+ * Also protects indirect addressing in das1800_ai_handler */
+ spin_lock(&dev->spinlock);
+ status = inb(dev->iobase + DAS1800_STATUS);
+
+ /* if interrupt was not caused by das-1800 */
+ if (!(status & INT)) {
+ spin_unlock(&dev->spinlock);
+ return IRQ_NONE;
+ }
+ /* clear the interrupt status bit INT */
+ outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
+ // handle interrupt
+ das1800_ai_handler(dev);
+
+ spin_unlock(&dev->spinlock);
+ return IRQ_HANDLED;
+}
+
+// the guts of the interrupt handler, that is shared with das1800_ai_poll
+static void das1800_ai_handler(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int status = inb(dev->iobase + DAS1800_STATUS);
+
+ async->events = 0;
+ // select adc for base address + 0
+ outb(ADC, dev->iobase + DAS1800_SELECT);
+ // dma buffer full
+ if (devpriv->irq_dma_bits & DMA_ENABLED) {
+ // look for data from dma transfer even if dma terminal count hasn't happened yet
+ das1800_handle_dma(dev, s, status);
+ } else if (status & FHF) { // if fifo half full
+ das1800_handle_fifo_half_full(dev, s);
+ } else if (status & FNE) { // if fifo not empty
+ das1800_handle_fifo_not_empty(dev, s);
+ }
+
+ async->events |= COMEDI_CB_BLOCK;
+ /* if the card's fifo has overflowed */
+ if (status & OVF) {
+ // clear OVF interrupt bit
+ outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
+ comedi_error(dev, "DAS1800 FIFO overflow");
+ das1800_cancel(dev, s);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return;
+ }
+ // stop taking data if appropriate
+ /* stop_src TRIG_EXT */
+ if (status & CT0TC) {
+ // clear CT0TC interrupt bit
+ outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
+ // make sure we get all remaining data from board before quitting
+ if (devpriv->irq_dma_bits & DMA_ENABLED)
+ das1800_flush_dma(dev, s);
+ else
+ das1800_handle_fifo_not_empty(dev, s);
+ das1800_cancel(dev, s); /* disable hardware conversions */
+ async->events |= COMEDI_CB_EOA;
+ } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { // stop_src TRIG_COUNT
+ das1800_cancel(dev, s); /* disable hardware conversions */
+ async->events |= COMEDI_CB_EOA;
+ }
+
+ comedi_event(dev, s);
+
+ return;
+}
+
+static void das1800_handle_dma(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int status)
+{
+ unsigned long flags;
+ const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
+
+ flags = claim_dma_lock();
+ das1800_flush_dma_channel(dev, s, devpriv->dma_current,
+ devpriv->dma_current_buf);
+ // re-enable dma channel
+ set_dma_addr(devpriv->dma_current,
+ virt_to_bus(devpriv->dma_current_buf));
+ set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
+ enable_dma(devpriv->dma_current);
+ release_dma_lock(flags);
+
+ if (status & DMATC) {
+ // clear DMATC interrupt bit
+ outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
+ // switch dma channels for next time, if appropriate
+ if (dual_dma) {
+ // read data from the other channel next time
+ if (devpriv->dma_current == devpriv->dma0) {
+ devpriv->dma_current = devpriv->dma1;
+ devpriv->dma_current_buf = devpriv->ai_buf1;
+ } else {
+ devpriv->dma_current = devpriv->dma0;
+ devpriv->dma_current_buf = devpriv->ai_buf0;
+ }
+ }
+ }
+
+ return;
+}
+
+static inline uint16_t munge_bipolar_sample(const struct comedi_device * dev,
+ uint16_t sample)
+{
+ sample += 1 << (thisboard->resolution - 1);
+ return sample;
+}
+
+static void munge_data(struct comedi_device * dev, uint16_t * array,
+ unsigned int num_elements)
+{
+ unsigned int i;
+ int unipolar;
+
+ /* see if card is using a unipolar or bipolar range so we can munge data correctly */
+ unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
+
+ /* convert to unsigned type if we are in a bipolar mode */
+ if (!unipolar) {
+ for (i = 0; i < num_elements; i++) {
+ array[i] = munge_bipolar_sample(dev, array[i]);
+ }
+ }
+}
+
+/* Utility function used by das1800_flush_dma() and das1800_handle_dma().
+ * Assumes dma lock is held */
+static void das1800_flush_dma_channel(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int channel, uint16_t * buffer)
+{
+ unsigned int num_bytes, num_samples;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ disable_dma(channel);
+
+ /* clear flip-flop to make sure 2-byte registers
+ * get set correctly */
+ clear_dma_ff(channel);
+
+ // figure out how many points to read
+ num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
+ num_samples = num_bytes / sizeof(short);
+
+ /* if we only need some of the points */
+ if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
+ num_samples = devpriv->count;
+
+ munge_data(dev, buffer, num_samples);
+ cfc_write_array_to_buffer(s, buffer, num_bytes);
+ if (s->async->cmd.stop_src == TRIG_COUNT)
+ devpriv->count -= num_samples;
+
+ return;
+}
+
+/* flushes remaining data from board when external trigger has stopped aquisition
+ * and we are using dma transfers */
+static void das1800_flush_dma(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+ const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
+
+ flags = claim_dma_lock();
+ das1800_flush_dma_channel(dev, s, devpriv->dma_current,
+ devpriv->dma_current_buf);
+
+ if (dual_dma) {
+ // switch to other channel and flush it
+ if (devpriv->dma_current == devpriv->dma0) {
+ devpriv->dma_current = devpriv->dma1;
+ devpriv->dma_current_buf = devpriv->ai_buf1;
+ } else {
+ devpriv->dma_current = devpriv->dma0;
+ devpriv->dma_current_buf = devpriv->ai_buf0;
+ }
+ das1800_flush_dma_channel(dev, s, devpriv->dma_current,
+ devpriv->dma_current_buf);
+ }
+
+ release_dma_lock(flags);
+
+ // get any remaining samples in fifo
+ das1800_handle_fifo_not_empty(dev, s);
+
+ return;
+}
+
+static void das1800_handle_fifo_half_full(struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ int numPoints = 0; /* number of points to read */
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ numPoints = FIFO_SIZE / 2;
+ /* if we only need some of the points */
+ if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
+ numPoints = devpriv->count;
+ insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
+ munge_data(dev, devpriv->ai_buf0, numPoints);
+ cfc_write_array_to_buffer(s, devpriv->ai_buf0,
+ numPoints * sizeof(devpriv->ai_buf0[0]));
+ if (cmd->stop_src == TRIG_COUNT)
+ devpriv->count -= numPoints;
+ return;
+}
+
+static void das1800_handle_fifo_not_empty(struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ short dpnt;
+ int unipolar;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
+
+ while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
+ if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
+ break;
+ dpnt = inw(dev->iobase + DAS1800_FIFO);
+ /* convert to unsigned type if we are in a bipolar mode */
+ if (!unipolar) ;
+ dpnt = munge_bipolar_sample(dev, dpnt);
+ cfc_write_to_buffer(s, dpnt);
+ if (cmd->stop_src == TRIG_COUNT)
+ devpriv->count--;
+ }
+
+ return;
+}
+
+static int das1800_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
+ outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
+ outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
+ if (devpriv->dma0)
+ disable_dma(devpriv->dma0);
+ if (devpriv->dma1)
+ disable_dma(devpriv->dma1);
+ return 0;
+}
+
+/* test analog input cmd */
+static int das1800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ unsigned int tmp_arg;
+ int i;
+ int unipolar;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ // uniqueness check
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT &&
+ cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
+ err++;
+ //compatibility check
+ if (cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->convert_src != TRIG_TIMER)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ // if we are not in burst mode
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ tmp_arg = cmd->convert_arg;
+ /* calculate counter values that give desired timing */
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd->convert_arg),
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp_arg != cmd->convert_arg)
+ err++;
+ }
+ // if we are in burst mode
+ else {
+ // check that convert_arg is compatible
+ tmp_arg = cmd->convert_arg;
+ cmd->convert_arg =
+ burst_convert_arg(cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp_arg != cmd->convert_arg)
+ err++;
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ // if scans are timed faster than conversion rate allows
+ if (cmd->convert_arg * cmd->chanlist_len >
+ cmd->scan_begin_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg *
+ cmd->chanlist_len;
+ err++;
+ }
+ tmp_arg = cmd->scan_begin_arg;
+ /* calculate counter values that give desired timing */
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->divisor1),
+ &(devpriv->divisor2),
+ &(cmd->scan_begin_arg),
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp_arg != cmd->scan_begin_arg)
+ err++;
+ }
+ }
+ }
+
+ if (err)
+ return 4;
+
+ // make sure user is not trying to mix unipolar and bipolar ranges
+ if (cmd->chanlist) {
+ unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
+ comedi_error(dev,
+ "unipolar and bipolar ranges cannot be mixed in the chanlist");
+ err++;
+ break;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+/* analog input cmd interface */
+
+// first, some utility functions used in the main ai_do_cmd()
+
+// returns appropriate bits for control register a, depending on command
+static int control_a_bits(struct comedi_cmd cmd)
+{
+ int control_a;
+
+ control_a = FFEN; //enable fifo
+ if (cmd.stop_src == TRIG_EXT) {
+ control_a |= ATEN;
+ }
+ switch (cmd.start_src) {
+ case TRIG_EXT:
+ control_a |= TGEN | CGSL;
+ break;
+ case TRIG_NOW:
+ control_a |= CGEN;
+ break;
+ default:
+ break;
+ }
+
+ return control_a;
+}
+
+// returns appropriate bits for control register c, depending on command
+static int control_c_bits(struct comedi_cmd cmd)
+{
+ int control_c;
+ int aref;
+
+ /* set clock source to internal or external, select analog reference,
+ * select unipolar / bipolar
+ */
+ aref = CR_AREF(cmd.chanlist[0]);
+ control_c = UQEN; //enable upper qram addresses
+ if (aref != AREF_DIFF)
+ control_c |= SD;
+ if (aref == AREF_COMMON)
+ control_c |= CMEN;
+ /* if a unipolar range was selected */
+ if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR)
+ control_c |= UB;
+ switch (cmd.scan_begin_src) {
+ case TRIG_FOLLOW: // not in burst mode
+ switch (cmd.convert_src) {
+ case TRIG_TIMER:
+ /* trig on cascaded counters */
+ control_c |= IPCLK;
+ break;
+ case TRIG_EXT:
+ /* trig on falling edge of external trigger */
+ control_c |= XPCLK;
+ break;
+ default:
+ break;
+ }
+ break;
+ case TRIG_TIMER:
+ // burst mode with internal pacer clock
+ control_c |= BMDE | IPCLK;
+ break;
+ case TRIG_EXT:
+ // burst mode with external trigger
+ control_c |= BMDE | XPCLK;
+ break;
+ default:
+ break;
+ }
+
+ return control_c;
+}
+
+// sets up counters
+static int setup_counters(struct comedi_device * dev, struct comedi_cmd cmd)
+{
+ // setup cascaded counters for conversion/scan frequency
+ switch (cmd.scan_begin_src) {
+ case TRIG_FOLLOW: // not in burst mode
+ if (cmd.convert_src == TRIG_TIMER) {
+ /* set conversion frequency */
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd.convert_arg),
+ cmd.flags & TRIG_ROUND_MASK);
+ if (das1800_set_frequency(dev) < 0) {
+ return -1;
+ }
+ }
+ break;
+ case TRIG_TIMER: // in burst mode
+ /* set scan frequency */
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
+ &(devpriv->divisor2), &(cmd.scan_begin_arg),
+ cmd.flags & TRIG_ROUND_MASK);
+ if (das1800_set_frequency(dev) < 0) {
+ return -1;
+ }
+ break;
+ default:
+ break;
+ }
+
+ // setup counter 0 for 'about triggering'
+ if (cmd.stop_src == TRIG_EXT) {
+ // load counter 0 in mode 0
+ i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
+ }
+
+ return 0;
+}
+
+// sets up dma
+static void setup_dma(struct comedi_device * dev, struct comedi_cmd cmd)
+{
+ unsigned long lock_flags;
+ const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
+
+ if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
+ return;
+
+ /* determine a reasonable dma transfer size */
+ devpriv->dma_transfer_size = suggest_transfer_size(&cmd);
+ lock_flags = claim_dma_lock();
+ disable_dma(devpriv->dma0);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma0);
+ set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
+ // set appropriate size of transfer
+ set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
+ devpriv->dma_current = devpriv->dma0;
+ devpriv->dma_current_buf = devpriv->ai_buf0;
+ enable_dma(devpriv->dma0);
+ // set up dual dma if appropriate
+ if (dual_dma) {
+ disable_dma(devpriv->dma1);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma1);
+ set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
+ // set appropriate size of transfer
+ set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
+ enable_dma(devpriv->dma1);
+ }
+ release_dma_lock(lock_flags);
+
+ return;
+}
+
+// programs channel/gain list into card
+static void program_chanlist(struct comedi_device * dev, struct comedi_cmd cmd)
+{
+ int i, n, chan_range;
+ unsigned long irq_flags;
+ const int range_mask = 0x3; //masks unipolar/bipolar bit off range
+ const int range_bitshift = 8;
+
+ n = cmd.chanlist_len;
+ // spinlock protects indirect addressing
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
+ outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */
+ /* make channel / gain list */
+ for (i = 0; i < n; i++) {
+ chan_range =
+ CR_CHAN(cmd.chanlist[i]) | ((CR_RANGE(cmd.
+ chanlist[i]) & range_mask) <<
+ range_bitshift);
+ outw(chan_range, dev->iobase + DAS1800_QRAM);
+ }
+ outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ return;
+}
+
+// analog input do_cmd
+static int das1800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int ret;
+ int control_a, control_c;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd cmd = async->cmd;
+
+ if (!dev->irq) {
+ comedi_error(dev,
+ "no irq assigned for das-1800, cannot do hardware conversions");
+ return -1;
+ }
+
+ /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
+ * (because dma in handler is unsafe at hard real-time priority) */
+ if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) {
+ devpriv->irq_dma_bits &= ~DMA_ENABLED;
+ } else {
+ devpriv->irq_dma_bits |= devpriv->dma_bits;
+ }
+ // interrupt on end of conversion for TRIG_WAKE_EOS
+ if (cmd.flags & TRIG_WAKE_EOS) {
+ // interrupt fifo not empty
+ devpriv->irq_dma_bits &= ~FIMD;
+ } else {
+ // interrupt fifo half full
+ devpriv->irq_dma_bits |= FIMD;
+ }
+ // determine how many conversions we need
+ if (cmd.stop_src == TRIG_COUNT) {
+ devpriv->count = cmd.stop_arg * cmd.chanlist_len;
+ }
+
+ das1800_cancel(dev, s);
+
+ // determine proper bits for control registers
+ control_a = control_a_bits(cmd);
+ control_c = control_c_bits(cmd);
+
+ /* setup card and start */
+ program_chanlist(dev, cmd);
+ ret = setup_counters(dev, cmd);
+ if (ret < 0) {
+ comedi_error(dev, "Error setting up counters");
+ return ret;
+ }
+ setup_dma(dev, cmd);
+ outb(control_c, dev->iobase + DAS1800_CONTROL_C);
+ // set conversion rate and length for burst mode
+ if (control_c & BMDE) {
+ // program conversion period with number of microseconds minus 1
+ outb(cmd.convert_arg / 1000 - 1,
+ dev->iobase + DAS1800_BURST_RATE);
+ outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
+ }
+ outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); // enable irq/dma
+ outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */
+ outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
+
+ return 0;
+}
+
+/* read analog input */
+static int das1800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int chan, range, aref, chan_range;
+ int timeout = 1000;
+ short dpnt;
+ int conv_flags = 0;
+ unsigned long irq_flags;
+
+ /* set up analog reference and unipolar / bipolar mode */
+ aref = CR_AREF(insn->chanspec);
+ conv_flags |= UQEN;
+ if (aref != AREF_DIFF)
+ conv_flags |= SD;
+ if (aref == AREF_COMMON)
+ conv_flags |= CMEN;
+ /* if a unipolar range was selected */
+ if (CR_RANGE(insn->chanspec) & UNIPOLAR)
+ conv_flags |= UB;
+
+ outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */
+ outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
+ outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
+ outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
+
+ chan = CR_CHAN(insn->chanspec);
+ /* mask of unipolar/bipolar bit from range */
+ range = CR_RANGE(insn->chanspec) & 0x3;
+ chan_range = chan | (range << 8);
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
+ outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */
+ outw(chan_range, dev->iobase + DAS1800_QRAM);
+ outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
+ outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */
+
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ outb(0, dev->iobase + DAS1800_FIFO);
+ for (i = 0; i < timeout; i++) {
+ if (inb(dev->iobase + DAS1800_STATUS) & FNE)
+ break;
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timeout");
+ return -ETIME;
+ }
+ dpnt = inw(dev->iobase + DAS1800_FIFO);
+ /* shift data to offset binary for bipolar ranges */
+ if ((conv_flags & UB) == 0)
+ dpnt += 1 << (thisboard->resolution - 1);
+ data[n] = dpnt;
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ return n;
+}
+
+/* writes to an analog output channel */
+static int das1800_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+// int range = CR_RANGE(insn->chanspec);
+ int update_chan = thisboard->ao_n_chan - 1;
+ short output;
+ unsigned long irq_flags;
+
+ // card expects two's complement data
+ output = data[0] - (1 << (thisboard->resolution - 1));
+ // if the write is to the 'update' channel, we need to remember its value
+ if (chan == update_chan)
+ devpriv->ao_update_bits = output;
+ // write to channel
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */
+ outw(output, dev->iobase + DAS1800_DAC);
+ // now we need to write to 'update' channel to update all dac channels
+ if (chan != update_chan) {
+ outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */
+ outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ return 1;
+}
+
+/* reads from digital input channels */
+static int das1800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
+ data[0] = 0;
+
+ return 2;
+}
+
+/* writes to digital output channels */
+static int das1800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int wbits;
+
+ // only set bits that have been masked
+ data[0] &= (1 << s->n_chan) - 1;
+ wbits = devpriv->do_bits;
+ wbits &= ~data[0];
+ wbits |= data[0] & data[1];
+ devpriv->do_bits = wbits;
+
+ outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
+
+ data[1] = devpriv->do_bits;
+
+ return 2;
+}
+
+/* loads counters with divisor1, divisor2 from private structure */
+static int das1800_set_frequency(struct comedi_device * dev)
+{
+ int err = 0;
+
+ // counter 1, mode 2
+ if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
+ 2))
+ err++;
+ // counter 2, mode 2
+ if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
+ 2))
+ err++;
+ if (err)
+ return -1;
+
+ return 0;
+}
+
+/* converts requested conversion timing to timing compatible with
+ * hardware, used only when card is in 'burst mode'
+ */
+static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
+{
+ unsigned int micro_sec;
+
+ // in burst mode, the maximum conversion time is 64 microseconds
+ if (convert_arg > 64000)
+ convert_arg = 64000;
+
+ // the conversion time must be an integral number of microseconds
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ micro_sec = (convert_arg + 500) / 1000;
+ break;
+ case TRIG_ROUND_DOWN:
+ micro_sec = convert_arg / 1000;
+ break;
+ case TRIG_ROUND_UP:
+ micro_sec = (convert_arg - 1) / 1000 + 1;
+ break;
+ }
+
+ // return number of nanoseconds
+ return micro_sec * 1000;
+}
+
+// utility function that suggests a dma transfer size based on the conversion period 'ns'
+static unsigned int suggest_transfer_size(struct comedi_cmd * cmd)
+{
+ unsigned int size = DMA_BUF_SIZE;
+ static const int sample_size = 2; // size in bytes of one sample from board
+ unsigned int fill_time = 300000000; // target time in nanoseconds for filling dma buffer
+ unsigned int max_size; // maximum size we will allow for a transfer
+
+ // make dma buffer fill in 0.3 seconds for timed modes
+ switch (cmd->scan_begin_src) {
+ case TRIG_FOLLOW: // not in burst mode
+ if (cmd->convert_src == TRIG_TIMER)
+ size = (fill_time / cmd->convert_arg) * sample_size;
+ break;
+ case TRIG_TIMER:
+ size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
+ sample_size;
+ break;
+ default:
+ size = DMA_BUF_SIZE;
+ break;
+ }
+
+ // set a minimum and maximum size allowed
+ max_size = DMA_BUF_SIZE;
+ // if we are taking limited number of conversions, limit transfer size to that
+ if (cmd->stop_src == TRIG_COUNT &&
+ cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
+ max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
+
+ if (size > max_size)
+ size = max_size;
+ if (size < sample_size)
+ size = sample_size;
+
+ return size;
+}
diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c
new file mode 100644
index 00000000000..2a8ca052510
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das6402.c
@@ -0,0 +1,354 @@
+/*
+ Some comments on the code..
+
+ - it shouldn't be necessary to use outb_p().
+
+ - ignoreirq creates a race condition. It needs to be fixed.
+
+ */
+
+/*
+ comedi/drivers/das6402.c
+ An experimental driver for Computerboards' DAS6402 I/O card
+
+ Copyright (C) 1999 Oystein Svendsen <svendsen@pvv.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: das6402
+Description: Keithley Metrabyte DAS6402 (& compatibles)
+Author: Oystein Svendsen <svendsen@pvv.org>
+Status: bitrotten
+Devices: [Keithley Metrabyte] DAS6402 (das6402)
+
+This driver has suffered bitrot.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define DAS6402_SIZE 16
+
+#define N_WORDS 3000*64
+
+#define STOP 0
+#define START 1
+
+#define SCANL 0x3f00
+#define BYTE unsigned char
+#define WORD unsigned short
+
+/*----- register 8 ----*/
+#define CLRINT 0x01
+#define CLRXTR 0x02
+#define CLRXIN 0x04
+#define EXTEND 0x10
+#define ARMED 0x20 /* enable conting of post sample conv */
+#define POSTMODE 0x40
+#define MHZ 0x80 /* 10 MHz clock */
+/*---------------------*/
+
+/*----- register 9 ----*/
+#define IRQ (0x04 << 4) /* these two are */
+#define IRQV 10 /* dependent on each other */
+
+#define CONVSRC 0x03 /* trig src is Intarnal pacer */
+#define BURSTEN 0x04 /* enable burst */
+#define XINTE 0x08 /* use external int. trig */
+#define INTE 0x80 /* enable analog interrupts */
+/*---------------------*/
+
+/*----- register 10 ---*/
+#define TGEN 0x01 /* Use pin DI1 for externl trigging? */
+#define TGSEL 0x02 /* Use edge triggering */
+#define TGPOL 0x04 /* active edge is falling */
+#define PRETRIG 0x08 /* pretrig */
+/*---------------------*/
+
+/*----- register 11 ---*/
+#define EOB 0x0c
+#define FIFOHFULL 0x08
+#define GAIN 0x01
+#define FIFONEPTY 0x04
+#define MODE 0x10
+#define SEM 0x20
+#define BIP 0x40
+/*---------------------*/
+
+#define M0 0x00
+#define M2 0x04
+
+#define C0 0x00
+#define C1 0x40
+#define C2 0x80
+#define RWLH 0x30
+
+static int das6402_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das6402_detach(struct comedi_device * dev);
+static struct comedi_driver driver_das6402 = {
+ driver_name:"das6402",
+ module:THIS_MODULE,
+ attach:das6402_attach,
+ detach:das6402_detach,
+};
+
+COMEDI_INITCLEANUP(driver_das6402);
+
+struct das6402_private {
+ int ai_bytes_to_read;
+
+ int das6402_ignoreirq;
+};
+#define devpriv ((struct das6402_private *)dev->private)
+
+static void das6402_ai_fifo_dregs(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static void das6402_setcounter(struct comedi_device * dev)
+{
+ BYTE p;
+ unsigned short ctrlwrd;
+
+ /* set up counter0 first, mode 0 */
+ p = M0 | C0 | RWLH;
+ outb_p(p, dev->iobase + 15);
+ ctrlwrd = 2000;
+ p = (BYTE) (0xff & ctrlwrd);
+ outb_p(p, dev->iobase + 12);
+ p = (BYTE) (0xff & (ctrlwrd >> 8));
+ outb_p(p, dev->iobase + 12);
+
+ /* set up counter1, mode 2 */
+ p = M2 | C1 | RWLH;
+ outb_p(p, dev->iobase + 15);
+ ctrlwrd = 10;
+ p = (BYTE) (0xff & ctrlwrd);
+ outb_p(p, dev->iobase + 13);
+ p = (BYTE) (0xff & (ctrlwrd >> 8));
+ outb_p(p, dev->iobase + 13);
+
+ /* set up counter1, mode 2 */
+ p = M2 | C2 | RWLH;
+ outb_p(p, dev->iobase + 15);
+ ctrlwrd = 1000;
+ p = (BYTE) (0xff & ctrlwrd);
+ outb_p(p, dev->iobase + 14);
+ p = (BYTE) (0xff & (ctrlwrd >> 8));
+ outb_p(p, dev->iobase + 14);
+}
+
+static irqreturn_t intr_handler(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices;
+
+ if (!dev->attached || devpriv->das6402_ignoreirq) {
+ printk("das6402: BUG: spurious interrupt\n");
+ return IRQ_HANDLED;
+ }
+#ifdef DEBUG
+ printk("das6402: interrupt! das6402_irqcount=%i\n",
+ devpriv->das6402_irqcount);
+ printk("das6402: iobase+2=%i\n", inw_p(dev->iobase + 2));
+#endif
+
+ das6402_ai_fifo_dregs(dev, s);
+
+ if (s->async->buf_write_count >= devpriv->ai_bytes_to_read) {
+ outw_p(SCANL, dev->iobase + 2); /* clears the fifo */
+ outb(0x07, dev->iobase + 8); /* clears all flip-flops */
+#ifdef DEBUG
+ printk("das6402: Got %i samples\n\n",
+ devpriv->das6402_wordsread - diff);
+#endif
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ }
+
+ outb(0x01, dev->iobase + 8); /* clear only the interrupt flip-flop */
+
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+#if 0
+static void das6402_ai_fifo_read(struct comedi_device * dev, short * data, int n)
+{
+ int i;
+
+ for (i = 0; i < n; i++)
+ data[i] = inw(dev->iobase);
+}
+#endif
+
+static void das6402_ai_fifo_dregs(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ while (1) {
+ if (!(inb(dev->iobase + 8) & 0x01))
+ return;
+ comedi_buf_put(s->async, inw(dev->iobase));
+ }
+}
+
+static int das6402_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ /*
+ * This function should reset the board from whatever condition it
+ * is in (i.e., acquiring data), to a non-active state.
+ */
+
+ devpriv->das6402_ignoreirq = 1;
+#ifdef DEBUG
+ printk("das6402: Stopping acquisition\n");
+#endif
+ devpriv->das6402_ignoreirq = 1;
+ outb_p(0x02, dev->iobase + 10); /* disable external trigging */
+ outw_p(SCANL, dev->iobase + 2); /* resets the card fifo */
+ outb_p(0, dev->iobase + 9); /* disables interrupts */
+
+ outw_p(SCANL, dev->iobase + 2);
+
+ return 0;
+}
+
+#ifdef unused
+static int das6402_ai_mode2(struct comedi_device * dev, struct comedi_subdevice * s,
+ comedi_trig * it)
+{
+ devpriv->das6402_ignoreirq = 1;
+
+#ifdef DEBUG
+ printk("das6402: Starting acquisition\n");
+#endif
+ outb_p(0x03, dev->iobase + 10); /* enable external trigging */
+ outw_p(SCANL, dev->iobase + 2); /* resets the card fifo */
+ outb_p(IRQ | CONVSRC | BURSTEN | INTE, dev->iobase + 9);
+
+ devpriv->ai_bytes_to_read = it->n * sizeof(short);
+
+ /* um... ignoreirq is a nasty race condition */
+ devpriv->das6402_ignoreirq = 0;
+
+ outw_p(SCANL, dev->iobase + 2);
+
+ return 0;
+}
+#endif
+
+static int board_init(struct comedi_device * dev)
+{
+ BYTE b;
+
+ devpriv->das6402_ignoreirq = 1;
+
+ outb(0x07, dev->iobase + 8);
+
+ /* register 11 */
+ outb_p(MODE, dev->iobase + 11);
+ b = BIP | SEM | MODE | GAIN | FIFOHFULL;
+ outb_p(b, dev->iobase + 11);
+
+ /* register 8 */
+ outb_p(EXTEND, dev->iobase + 8);
+ b = EXTEND | MHZ;
+ outb_p(b, dev->iobase + 8);
+ b = MHZ | CLRINT | CLRXTR | CLRXIN;
+ outb_p(b, dev->iobase + 8);
+
+ /* register 9 */
+ b = IRQ | CONVSRC | BURSTEN | INTE;
+ outb_p(b, dev->iobase + 9);
+
+ /* register 10 */
+ b = TGSEL | TGEN;
+ outb_p(b, dev->iobase + 10);
+
+ b = 0x07;
+ outb_p(b, dev->iobase + 8);
+
+ das6402_setcounter(dev);
+
+ outw_p(SCANL, dev->iobase + 2); /* reset card fifo */
+
+ devpriv->das6402_ignoreirq = 0;
+
+ return 0;
+}
+
+static int das6402_detach(struct comedi_device * dev)
+{
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (dev->iobase)
+ release_region(dev->iobase, DAS6402_SIZE);
+
+ return 0;
+}
+
+static int das6402_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned int irq;
+ unsigned long iobase;
+ int ret;
+ struct comedi_subdevice *s;
+
+ dev->board_name = "das6402";
+
+ iobase = it->options[0];
+ if (iobase == 0)
+ iobase = 0x300;
+
+ printk("comedi%d: das6402: 0x%04lx", dev->minor, iobase);
+
+ if (!request_region(iobase, DAS6402_SIZE, "das6402")) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* should do a probe here */
+
+ irq = it->options[0];
+ printk(" ( irq = %u )", irq);
+ ret = comedi_request_irq(irq, intr_handler, 0, "das6402", dev);
+ if (ret < 0) {
+ printk("irq conflict\n");
+ return ret;
+ }
+ dev->irq = irq;
+
+ if ((ret = alloc_private(dev, sizeof(struct das6402_private))) < 0)
+ return ret;
+
+ if ((ret = alloc_subdevices(dev, 1)) < 0)
+ return ret;
+
+ /* ai subdevice */
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 8;
+ //s->trig[2]=das6402_ai_mode2;
+ s->cancel = das6402_ai_cancel;
+ s->maxdata = (1 << 12) - 1;
+ s->len_chanlist = 16; /* ? */
+ s->range_table = &range_unknown;
+
+ board_init(dev);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
new file mode 100644
index 00000000000..7a6656bf809
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -0,0 +1,894 @@
+/*
+ comedi/drivers/das800.c
+ Driver for Keitley das800 series boards and compatibles
+ Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: das800
+Description: Keithley Metrabyte DAS800 (& compatibles)
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [Keithley Metrabyte] DAS-800 (das-800), DAS-801 (das-801),
+ DAS-802 (das-802),
+ [Measurement Computing] CIO-DAS800 (cio-das800),
+ CIO-DAS801 (cio-das801), CIO-DAS802 (cio-das802),
+ CIO-DAS802/16 (cio-das802/16)
+Status: works, cio-das802/16 untested - email me if you have tested it
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ (optional, required for timed or externally triggered conversions)
+
+Notes:
+ IRQ can be omitted, although the cmd interface will not work without it.
+
+ All entries in the channel/gain list must use the same gain and be
+ consecutive channels counting upwards in channel number (these are
+ hardware limitations.)
+
+ I've never tested the gain setting stuff since I only have a
+ DAS-800 board with fixed gain.
+
+ The cio-das802/16 does not have a fifo-empty status bit! Therefore
+ only fifo-half-full transfers are possible with this card.
+*/
+/*
+
+cmd triggers supported:
+ start_src: TRIG_NOW | TRIG_EXT
+ scan_begin_src: TRIG_FOLLOW
+ scan_end_src: TRIG_COUNT
+ convert_src: TRIG_TIMER | TRIG_EXT
+ stop_src: TRIG_NONE | TRIG_COUNT
+
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include "8253.h"
+#include "comedi_fc.h"
+
+#define DAS800_SIZE 8
+#define TIMER_BASE 1000
+#define N_CHAN_AI 8 // number of analog input channels
+
+/* Registers for the das800 */
+
+#define DAS800_LSB 0
+#define FIFO_EMPTY 0x1
+#define FIFO_OVF 0x2
+#define DAS800_MSB 1
+#define DAS800_CONTROL1 2
+#define CONTROL1_INTE 0x8
+#define DAS800_CONV_CONTROL 2
+#define ITE 0x1
+#define CASC 0x2
+#define DTEN 0x4
+#define IEOC 0x8
+#define EACS 0x10
+#define CONV_HCEN 0x80
+#define DAS800_SCAN_LIMITS 2
+#define DAS800_STATUS 2
+#define IRQ 0x8
+#define BUSY 0x80
+#define DAS800_GAIN 3
+#define CIO_FFOV 0x8 // fifo overflow for cio-das802/16
+#define CIO_ENHF 0x90 // interrupt fifo half full for cio-das802/16
+#define CONTROL1 0x80
+#define CONV_CONTROL 0xa0
+#define SCAN_LIMITS 0xc0
+#define ID 0xe0
+#define DAS800_8254 4
+#define DAS800_STATUS2 7
+#define STATUS2_HCEN 0x80
+#define STATUS2_INTE 0X20
+#define DAS800_ID 7
+
+struct das800_board {
+ const char *name;
+ int ai_speed;
+ const struct comedi_lrange *ai_range;
+ int resolution;
+};
+
+//analog input ranges
+static const struct comedi_lrange range_das800_ai = {
+ 1,
+ {
+ RANGE(-5, 5),
+ }
+};
+
+static const struct comedi_lrange range_das801_ai = {
+ 9,
+ {
+ RANGE(-5, 5),
+ RANGE(-10, 10),
+ RANGE(0, 10),
+ RANGE(-0.5, 0.5),
+ RANGE(0, 1),
+ RANGE(-0.05, 0.05),
+ RANGE(0, 0.1),
+ RANGE(-0.01, 0.01),
+ RANGE(0, 0.02),
+ }
+};
+
+static const struct comedi_lrange range_cio_das801_ai = {
+ 9,
+ {
+ RANGE(-5, 5),
+ RANGE(-10, 10),
+ RANGE(0, 10),
+ RANGE(-0.5, 0.5),
+ RANGE(0, 1),
+ RANGE(-0.05, 0.05),
+ RANGE(0, 0.1),
+ RANGE(-0.005, 0.005),
+ RANGE(0, 0.01),
+ }
+};
+
+static const struct comedi_lrange range_das802_ai = {
+ 9,
+ {
+ RANGE(-5, 5),
+ RANGE(-10, 10),
+ RANGE(0, 10),
+ RANGE(-2.5, 2.5),
+ RANGE(0, 5),
+ RANGE(-1.25, 1.25),
+ RANGE(0, 2.5),
+ RANGE(-0.625, 0.625),
+ RANGE(0, 1.25),
+ }
+};
+
+static const struct comedi_lrange range_das80216_ai = {
+ 8,
+ {
+ RANGE(-10, 10),
+ RANGE(0, 10),
+ RANGE(-5, 5),
+ RANGE(0, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(0, 2.5),
+ RANGE(-1.25, 1.25),
+ RANGE(0, 1.25),
+ }
+};
+
+enum { das800, ciodas800, das801, ciodas801, das802, ciodas802, ciodas80216 };
+
+static const struct das800_board das800_boards[] = {
+ {
+ name: "das-800",
+ ai_speed:25000,
+ ai_range:&range_das800_ai,
+ resolution:12,
+ },
+ {
+ name: "cio-das800",
+ ai_speed:20000,
+ ai_range:&range_das800_ai,
+ resolution:12,
+ },
+ {
+ name: "das-801",
+ ai_speed:25000,
+ ai_range:&range_das801_ai,
+ resolution:12,
+ },
+ {
+ name: "cio-das801",
+ ai_speed:20000,
+ ai_range:&range_cio_das801_ai,
+ resolution:12,
+ },
+ {
+ name: "das-802",
+ ai_speed:25000,
+ ai_range:&range_das802_ai,
+ resolution:12,
+ },
+ {
+ name: "cio-das802",
+ ai_speed:20000,
+ ai_range:&range_das802_ai,
+ resolution:12,
+ },
+ {
+ name: "cio-das802/16",
+ ai_speed:10000,
+ ai_range:&range_das80216_ai,
+ resolution:16,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct das800_board *)dev->board_ptr)
+
+struct das800_private {
+ volatile unsigned int count; /* number of data points left to be taken */
+ volatile int forever; /* flag indicating whether we should take data forever */
+ unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
+ unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
+ volatile int do_bits; /* digital output bits */
+};
+
+#define devpriv ((struct das800_private *)dev->private)
+
+static int das800_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das800_detach(struct comedi_device * dev);
+static int das800_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static struct comedi_driver driver_das800 = {
+ driver_name:"das800",
+ module:THIS_MODULE,
+ attach:das800_attach,
+ detach:das800_detach,
+ num_names:sizeof(das800_boards) / sizeof(struct das800_board),
+ board_name:&das800_boards[0].name,
+ offset:sizeof(struct das800_board),
+};
+
+static irqreturn_t das800_interrupt(int irq, void *d PT_REGS_ARG);
+static void enable_das800(struct comedi_device * dev);
+static void disable_das800(struct comedi_device * dev);
+static int das800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int das800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das800_probe(struct comedi_device * dev);
+static int das800_set_frequency(struct comedi_device * dev);
+
+/* checks and probes das-800 series board type */
+static int das800_probe(struct comedi_device * dev)
+{
+ int id_bits;
+ unsigned long irq_flags;
+ int board;
+
+ // 'comedi spin lock irqsave' disables even rt interrupts, we use them to protect indirect addressing
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(ID, dev->iobase + DAS800_GAIN); /* select base address + 7 to be ID register */
+ id_bits = inb(dev->iobase + DAS800_ID) & 0x3; /* get id bits */
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ board = thisboard - das800_boards;
+
+ switch (id_bits) {
+ case 0x0:
+ if (board == das800) {
+ printk(" Board model: DAS-800\n");
+ return board;
+ }
+ if (board == ciodas800) {
+ printk(" Board model: CIO-DAS800\n");
+ return board;
+ }
+ printk(" Board model (probed): DAS-800\n");
+ return das800;
+ break;
+ case 0x2:
+ if (board == das801) {
+ printk(" Board model: DAS-801\n");
+ return board;
+ }
+ if (board == ciodas801) {
+ printk(" Board model: CIO-DAS801\n");
+ return board;
+ }
+ printk(" Board model (probed): DAS-801\n");
+ return das801;
+ break;
+ case 0x3:
+ if (board == das802) {
+ printk(" Board model: DAS-802\n");
+ return board;
+ }
+ if (board == ciodas802) {
+ printk(" Board model: CIO-DAS802\n");
+ return board;
+ }
+ if (board == ciodas80216) {
+ printk(" Board model: CIO-DAS802/16\n");
+ return board;
+ }
+ printk(" Board model (probed): DAS-802\n");
+ return das802;
+ break;
+ default:
+ printk(" Board model: probe returned 0x%x (unknown)\n",
+ id_bits);
+ return board;
+ break;
+ }
+ return -1;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_das800);
+
+/* interrupt service routine */
+static irqreturn_t das800_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ short i; /* loop index */
+ short dataPoint = 0;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->read_subdev; /* analog input subdevice */
+ struct comedi_async *async;
+ int status;
+ unsigned long irq_flags;
+ static const int max_loops = 128; // half-fifo size for cio-das802/16
+ // flags
+ int fifo_empty = 0;
+ int fifo_overflow = 0;
+
+ status = inb(dev->iobase + DAS800_STATUS);
+ /* if interrupt was not generated by board or driver not attached, quit */
+ if (!(status & IRQ))
+ return IRQ_NONE;
+ if (!(dev->attached))
+ return IRQ_HANDLED;
+
+ /* wait until here to initialize async, since we will get null dereference
+ * if interrupt occurs before driver is fully attached!
+ */
+ async = s->async;
+
+ // if hardware conversions are not enabled, then quit
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select base address + 7 to be STATUS2 register */
+ status = inb(dev->iobase + DAS800_STATUS2) & STATUS2_HCEN;
+ /* don't release spinlock yet since we want to make sure noone else disables hardware conversions */
+ if (status == 0) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ return IRQ_HANDLED;
+ }
+
+ /* loop while card's fifo is not empty (and limit to half fifo for cio-das802/16) */
+ for (i = 0; i < max_loops; i++) {
+ /* read 16 bits from dev->iobase and dev->iobase + 1 */
+ dataPoint = inb(dev->iobase + DAS800_LSB);
+ dataPoint += inb(dev->iobase + DAS800_MSB) << 8;
+ if (thisboard->resolution == 12) {
+ fifo_empty = dataPoint & FIFO_EMPTY;
+ fifo_overflow = dataPoint & FIFO_OVF;
+ if (fifo_overflow)
+ break;
+ } else {
+ fifo_empty = 0; // cio-das802/16 has no fifo empty status bit
+ }
+ if (fifo_empty) {
+ break;
+ }
+ /* strip off extraneous bits for 12 bit cards */
+ if (thisboard->resolution == 12)
+ dataPoint = (dataPoint >> 4) & 0xfff;
+ /* if there are more data points to collect */
+ if (devpriv->count > 0 || devpriv->forever == 1) {
+ /* write data point to buffer */
+ cfc_write_to_buffer(s, dataPoint);
+ if (devpriv->count > 0)
+ devpriv->count--;
+ }
+ }
+ async->events |= COMEDI_CB_BLOCK;
+ /* check for fifo overflow */
+ if (thisboard->resolution == 12) {
+ fifo_overflow = dataPoint & FIFO_OVF;
+ // else cio-das802/16
+ } else {
+ fifo_overflow = inb(dev->iobase + DAS800_GAIN) & CIO_FFOV;
+ }
+ if (fifo_overflow) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ comedi_error(dev, "DAS800 FIFO overflow");
+ das800_cancel(dev, dev->subdevices + 0);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ async->events = 0;
+ return IRQ_HANDLED;
+ }
+ if (devpriv->count > 0 || devpriv->forever == 1) {
+ /* Re-enable card's interrupt.
+ * We already have spinlock, so indirect addressing is safe */
+ outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
+ outb(CONTROL1_INTE | devpriv->do_bits,
+ dev->iobase + DAS800_CONTROL1);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ /* otherwise, stop taking data */
+ } else {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ disable_das800(dev); /* diable hardware triggered conversions */
+ async->events |= COMEDI_CB_EOA;
+ }
+ comedi_event(dev, s);
+ async->events = 0;
+ return IRQ_HANDLED;
+}
+
+static int das800_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = it->options[0];
+ unsigned int irq = it->options[1];
+ unsigned long irq_flags;
+ int board;
+
+ printk("comedi%d: das800: io 0x%lx", dev->minor, iobase);
+ if (irq) {
+ printk(", irq %u", irq);
+ }
+ printk("\n");
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(struct das800_private)) < 0)
+ return -ENOMEM;
+
+ if (iobase == 0) {
+ printk("io base address required for das800\n");
+ return -EINVAL;
+ }
+
+ /* check if io addresses are available */
+ if (!request_region(iobase, DAS800_SIZE, "das800")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ board = das800_probe(dev);
+ if (board < 0) {
+ printk("unable to determine board type\n");
+ return -ENODEV;
+ }
+ dev->board_ptr = das800_boards + board;
+
+ /* grab our IRQ */
+ if (irq == 1 || irq > 7) {
+ printk("irq out of range\n");
+ return -EINVAL;
+ }
+ if (irq) {
+ if (comedi_request_irq(irq, das800_interrupt, 0, "das800", dev)) {
+ printk("unable to allocate irq %u\n", irq);
+ return -EINVAL;
+ }
+ }
+ dev->irq = irq;
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ /* analog input subdevice */
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
+ s->n_chan = 8;
+ s->len_chanlist = 8;
+ s->maxdata = (1 << thisboard->resolution) - 1;
+ s->range_table = thisboard->ai_range;
+ s->do_cmd = das800_ai_do_cmd;
+ s->do_cmdtest = das800_ai_do_cmdtest;
+ s->insn_read = das800_ai_rinsn;
+ s->cancel = das800_cancel;
+
+ /* di */
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 3;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das800_di_rbits;
+
+ /* do */
+ s = dev->subdevices + 2;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das800_do_wbits;
+
+ disable_das800(dev);
+
+ /* initialize digital out channels */
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
+ outb(CONTROL1_INTE | devpriv->do_bits, dev->iobase + DAS800_CONTROL1);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ return 0;
+};
+
+static int das800_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: das800: remove\n", dev->minor);
+
+ /* only free stuff if it has been allocated by _attach */
+ if (dev->iobase)
+ release_region(dev->iobase, DAS800_SIZE);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ return 0;
+};
+
+static int das800_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ devpriv->forever = 0;
+ devpriv->count = 0;
+ disable_das800(dev);
+ return 0;
+}
+
+/* enable_das800 makes the card start taking hardware triggered conversions */
+static void enable_das800(struct comedi_device * dev)
+{
+ unsigned long irq_flags;
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ // enable fifo-half full interrupts for cio-das802/16
+ if (thisboard->resolution == 16)
+ outb(CIO_ENHF, dev->iobase + DAS800_GAIN);
+ outb(CONV_CONTROL, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be conversion control register */
+ outb(CONV_HCEN, dev->iobase + DAS800_CONV_CONTROL); /* enable hardware triggering */
+ outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
+ outb(CONTROL1_INTE | devpriv->do_bits, dev->iobase + DAS800_CONTROL1); /* enable card's interrupt */
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+}
+
+/* disable_das800 stops hardware triggered conversions */
+static void disable_das800(struct comedi_device * dev)
+{
+ unsigned long irq_flags;
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(CONV_CONTROL, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be conversion control register */
+ outb(0x0, dev->iobase + DAS800_CONV_CONTROL); /* disable hardware triggering of conversions */
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+}
+
+static int das800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int gain, startChan;
+ int i;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ /* calculate counter values that give desired timing */
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
+ &(devpriv->divisor2), &(cmd->convert_arg),
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ // check channel/gain list against card's limitations
+ if (cmd->chanlist) {
+ gain = CR_RANGE(cmd->chanlist[0]);
+ startChan = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) !=
+ (startChan + i) % N_CHAN_AI) {
+ comedi_error(dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ err++;
+ }
+ if (CR_RANGE(cmd->chanlist[i]) != gain) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same gain\n");
+ err++;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int das800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int startChan, endChan, scan, gain;
+ int conv_bits;
+ unsigned long irq_flags;
+ struct comedi_async *async = s->async;
+
+ if (!dev->irq) {
+ comedi_error(dev,
+ "no irq assigned for das-800, cannot do hardware conversions");
+ return -1;
+ }
+
+ disable_das800(dev);
+
+ /* set channel scan limits */
+ startChan = CR_CHAN(async->cmd.chanlist[0]);
+ endChan = (startChan + async->cmd.chanlist_len - 1) % 8;
+ scan = (endChan << 3) | startChan;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(SCAN_LIMITS, dev->iobase + DAS800_GAIN); /* select base address + 2 to be scan limits register */
+ outb(scan, dev->iobase + DAS800_SCAN_LIMITS); /* set scan limits */
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ /* set gain */
+ gain = CR_RANGE(async->cmd.chanlist[0]);
+ if (thisboard->resolution == 12 && gain > 0)
+ gain += 0x7;
+ gain &= 0xf;
+ outb(gain, dev->iobase + DAS800_GAIN);
+
+ switch (async->cmd.stop_src) {
+ case TRIG_COUNT:
+ devpriv->count = async->cmd.stop_arg * async->cmd.chanlist_len;
+ devpriv->forever = 0;
+ break;
+ case TRIG_NONE:
+ devpriv->forever = 1;
+ devpriv->count = 0;
+ break;
+ default:
+ break;
+ }
+
+ /* enable auto channel scan, send interrupts on end of conversion
+ * and set clock source to internal or external
+ */
+ conv_bits = 0;
+ conv_bits |= EACS | IEOC;
+ if (async->cmd.start_src == TRIG_EXT)
+ conv_bits |= DTEN;
+ switch (async->cmd.convert_src) {
+ case TRIG_TIMER:
+ conv_bits |= CASC | ITE;
+ /* set conversion frequency */
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
+ &(devpriv->divisor2), &(async->cmd.convert_arg),
+ async->cmd.flags & TRIG_ROUND_MASK);
+ if (das800_set_frequency(dev) < 0) {
+ comedi_error(dev, "Error setting up counters");
+ return -1;
+ }
+ break;
+ case TRIG_EXT:
+ break;
+ default:
+ break;
+ }
+
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(CONV_CONTROL, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be conversion control register */
+ outb(conv_bits, dev->iobase + DAS800_CONV_CONTROL);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ async->events = 0;
+ enable_das800(dev);
+ return 0;
+}
+
+static int das800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int chan;
+ int range;
+ int lsb, msb;
+ int timeout = 1000;
+ unsigned long irq_flags;
+
+ disable_das800(dev); /* disable hardware conversions (enables software conversions) */
+
+ /* set multiplexer */
+ chan = CR_CHAN(insn->chanspec);
+
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
+ outb(chan | devpriv->do_bits, dev->iobase + DAS800_CONTROL1);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ /* set gain / range */
+ range = CR_RANGE(insn->chanspec);
+ if (thisboard->resolution == 12 && range)
+ range += 0x7;
+ range &= 0xf;
+ outb(range, dev->iobase + DAS800_GAIN);
+
+ comedi_udelay(5);
+
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ outb_p(0, dev->iobase + DAS800_MSB);
+
+ for (i = 0; i < timeout; i++) {
+ if (!(inb(dev->iobase + DAS800_STATUS) & BUSY))
+ break;
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timeout");
+ return -ETIME;
+ }
+ lsb = inb(dev->iobase + DAS800_LSB);
+ msb = inb(dev->iobase + DAS800_MSB);
+ if (thisboard->resolution == 12) {
+ data[n] = (lsb >> 4) & 0xff;
+ data[n] |= (msb << 4);
+ } else {
+ data[n] = (msb << 8) | lsb;
+ }
+ }
+
+ return n;
+}
+
+static int das800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits;
+
+ bits = inb(dev->iobase + DAS800_STATUS) >> 4;
+ bits &= 0x7;
+ data[1] = bits;
+ data[0] = 0;
+
+ return 2;
+}
+
+static int das800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int wbits;
+ unsigned long irq_flags;
+
+ // only set bits that have been masked
+ data[0] &= 0xf;
+ wbits = devpriv->do_bits >> 4;
+ wbits &= ~data[0];
+ wbits |= data[0] & data[1];
+ devpriv->do_bits = wbits << 4;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
+ outb(devpriv->do_bits | CONTROL1_INTE, dev->iobase + DAS800_CONTROL1);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ data[1] = wbits;
+
+ return 2;
+}
+
+/* loads counters with divisor1, divisor2 from private structure */
+static int das800_set_frequency(struct comedi_device * dev)
+{
+ int err = 0;
+
+ if (i8254_load(dev->iobase + DAS800_8254, 0, 1, devpriv->divisor1, 2))
+ err++;
+ if (i8254_load(dev->iobase + DAS800_8254, 0, 2, devpriv->divisor2, 2))
+ err++;
+ if (err)
+ return -1;
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
new file mode 100644
index 00000000000..829083651ed
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -0,0 +1,1081 @@
+/*
+ comedi/drivers/dmm32at.c
+ Diamond Systems mm32at code for a Comedi driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: dmm32at
+Description: Diamond Systems mm32at driver.
+Devices:
+Author: Perry J. Piplani <perry.j.piplani@nasa.gov>
+Updated: Fri Jun 4 09:13:24 CDT 2004
+Status: experimental
+
+This driver is for the Diamond Systems MM-32-AT board
+http://www.diamondsystems.com/products/diamondmm32at It is being used
+on serveral projects inside NASA, without problems so far. For analog
+input commands, TRIG_EXT is not yet supported at all..
+
+Configuration Options:
+ comedi_config /dev/comedi0 dmm32at baseaddr,irq
+*/
+
+/*
+ * The previous block comment is used to automatically generate
+ * documentation in Comedi and Comedilib. The fields:
+ *
+ * Driver: the name of the driver
+ * Description: a short phrase describing the driver. Don't list boards.
+ * Devices: a full list of the boards that attempt to be supported by
+ * the driver. Format is "(manufacturer) board name [comedi name]",
+ * where comedi_name is the name that is used to configure the board.
+ * See the comment near board_name: in the struct comedi_driver structure
+ * below. If (manufacturer) or [comedi name] is missing, the previous
+ * value is used.
+ * Author: you
+ * Updated: date when the _documentation_ was last updated. Use 'date -R'
+ * to get a value for this.
+ * Status: a one-word description of the status. Valid values are:
+ * works - driver works correctly on most boards supported, and
+ * passes comedi_test.
+ * unknown - unknown. Usually put there by ds.
+ * experimental - may not work in any particular release. Author
+ * probably wants assistance testing it.
+ * bitrotten - driver has not been update in a long time, probably
+ * doesn't work, and probably is missing support for significant
+ * Comedi interface features.
+ * untested - author probably wrote it "blind", and is believed to
+ * work, but no confirmation.
+ *
+ * These headers should be followed by a blank line, and any comments
+ * you wish to say about the driver. The comment area is the place
+ * to put any known bugs, limitations, unsupported features, supported
+ * command triggers, whether or not commands are supported on particular
+ * subdevices, etc.
+ *
+ * Somewhere in the comment should be information about configuration
+ * options that are used with comedi_config.
+ */
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+
+/* Board register addresses */
+
+#define DMM32AT_MEMSIZE 0x10
+
+#define DMM32AT_CONV 0x00
+#define DMM32AT_AILSB 0x00
+#define DMM32AT_AUXDOUT 0x01
+#define DMM32AT_AIMSB 0x01
+#define DMM32AT_AILOW 0x02
+#define DMM32AT_AIHIGH 0x03
+
+#define DMM32AT_DACLSB 0x04
+#define DMM32AT_DACSTAT 0x04
+#define DMM32AT_DACMSB 0x05
+
+#define DMM32AT_FIFOCNTRL 0x07
+#define DMM32AT_FIFOSTAT 0x07
+
+#define DMM32AT_CNTRL 0x08
+#define DMM32AT_AISTAT 0x08
+
+#define DMM32AT_INTCLOCK 0x09
+
+#define DMM32AT_CNTRDIO 0x0a
+
+#define DMM32AT_AICONF 0x0b
+#define DMM32AT_AIRBACK 0x0b
+
+#define DMM32AT_CLK1 0x0d
+#define DMM32AT_CLK2 0x0e
+#define DMM32AT_CLKCT 0x0f
+
+#define DMM32AT_DIOA 0x0c
+#define DMM32AT_DIOB 0x0d
+#define DMM32AT_DIOC 0x0e
+#define DMM32AT_DIOCONF 0x0f
+
+#define dmm_inb(cdev,reg) inb((cdev->iobase)+reg)
+#define dmm_outb(cdev,reg,valu) outb(valu,(cdev->iobase)+reg)
+
+/* Board register values. */
+
+/* DMM32AT_DACSTAT 0x04 */
+#define DMM32AT_DACBUSY 0x80
+
+/* DMM32AT_FIFOCNTRL 0x07 */
+#define DMM32AT_FIFORESET 0x02
+#define DMM32AT_SCANENABLE 0x04
+
+/* DMM32AT_CNTRL 0x08 */
+#define DMM32AT_RESET 0x20
+#define DMM32AT_INTRESET 0x08
+#define DMM32AT_CLKACC 0x00
+#define DMM32AT_DIOACC 0x01
+
+/* DMM32AT_AISTAT 0x08 */
+#define DMM32AT_STATUS 0x80
+
+/* DMM32AT_INTCLOCK 0x09 */
+#define DMM32AT_ADINT 0x80
+#define DMM32AT_CLKSEL 0x03
+
+/* DMM32AT_CNTRDIO 0x0a */
+#define DMM32AT_FREQ12 0x80
+
+/* DMM32AT_AICONF 0x0b */
+#define DMM32AT_RANGE_U10 0x0c
+#define DMM32AT_RANGE_U5 0x0d
+#define DMM32AT_RANGE_B10 0x08
+#define DMM32AT_RANGE_B5 0x00
+#define DMM32AT_SCINT_20 0x00
+#define DMM32AT_SCINT_15 0x10
+#define DMM32AT_SCINT_10 0x20
+#define DMM32AT_SCINT_5 0x30
+
+/* DMM32AT_CLKCT 0x0f */
+#define DMM32AT_CLKCT1 0x56 /* mode3 counter 1 - write low byte only */
+#define DMM32AT_CLKCT2 0xb6 /* mode3 counter 2 - write high and low byte */
+
+/* DMM32AT_DIOCONF 0x0f */
+#define DMM32AT_DIENABLE 0x80
+#define DMM32AT_DIRA 0x10
+#define DMM32AT_DIRB 0x02
+#define DMM32AT_DIRCL 0x01
+#define DMM32AT_DIRCH 0x08
+
+/* board AI ranges in comedi structure */
+static const struct comedi_lrange dmm32at_airanges = {
+ 4,
+ {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ }
+};
+
+/* register values for above ranges */
+static const unsigned char dmm32at_rangebits[] = {
+ DMM32AT_RANGE_U10,
+ DMM32AT_RANGE_U5,
+ DMM32AT_RANGE_B10,
+ DMM32AT_RANGE_B5,
+};
+
+/* only one of these ranges is valid, as set by a jumper on the
+ * board. The application should only use the range set by the jumper
+ */
+static const struct comedi_lrange dmm32at_aoranges = {
+ 4,
+ {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ }
+};
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct dmm32at_board {
+ const char *name;
+ int ai_chans;
+ int ai_bits;
+ const struct comedi_lrange *ai_ranges;
+ int ao_chans;
+ int ao_bits;
+ const struct comedi_lrange *ao_ranges;
+ int have_dio;
+ int dio_chans;
+};
+static const struct dmm32at_board dmm32at_boards[] = {
+ {
+ name: "dmm32at",
+ ai_chans:32,
+ ai_bits: 16,
+ ai_ranges:&dmm32at_airanges,
+ ao_chans:4,
+ ao_bits: 12,
+ ao_ranges:&dmm32at_aoranges,
+ have_dio:1,
+ dio_chans:24,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct dmm32at_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ * several hardware drivers keep similar information in this structure,
+ * feel free to suggest moving the variable to the struct comedi_device struct.
+ */
+struct dmm32at_private {
+
+ int data;
+ int ai_inuse;
+ unsigned int ai_scans_left;
+
+ /* Used for AO readback */
+ unsigned int ao_readback[4];
+ unsigned char dio_config;
+
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct dmm32at_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int dmm32at_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dmm32at_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dmm32at = {
+ driver_name:"dmm32at",
+ module:THIS_MODULE,
+ attach:dmm32at_attach,
+ detach:dmm32at_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+/* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in dmm32at_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+ board_name:&dmm32at_boards[0].name,
+ offset:sizeof(struct dmm32at_board),
+ num_names:sizeof(dmm32at_boards) / sizeof(struct dmm32at_board),
+};
+
+/* prototypes for driver functions below */
+static int dmm32at_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int dmm32at_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dmm32at_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dmm32at_ns_to_timer(unsigned int *ns, int round);
+static irqreturn_t dmm32at_isr(int irq, void *d PT_REGS_ARG);
+void dmm32at_setaitimer(struct comedi_device * dev, unsigned int nansec);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int dmm32at_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ struct comedi_subdevice *s;
+ unsigned char aihi, ailo, fifostat, aistat, intstat, airback;
+ unsigned long iobase;
+ unsigned int irq;
+
+ iobase = it->options[0];
+ irq = it->options[1];
+
+ printk("comedi%d: dmm32at: attaching\n", dev->minor);
+ printk("dmm32at: probing at address 0x%04lx, irq %u\n", iobase, irq);
+
+ /* register address space */
+ if (!request_region(iobase, DMM32AT_MEMSIZE, thisboard->name)) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* the following just makes sure the board is there and gets
+ it to a known state */
+
+ /* reset the board */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_RESET);
+
+ /* allow a millisecond to reset */
+ udelay(1000);
+
+ /* zero scan and fifo control */
+ dmm_outb(dev, DMM32AT_FIFOCNTRL, 0x0);
+
+ /* zero interrupt and clock control */
+ dmm_outb(dev, DMM32AT_INTCLOCK, 0x0);
+
+ /* write a test channel range, the high 3 bits should drop */
+ dmm_outb(dev, DMM32AT_AILOW, 0x80);
+ dmm_outb(dev, DMM32AT_AIHIGH, 0xff);
+
+ /* set the range at 10v unipolar */
+ dmm_outb(dev, DMM32AT_AICONF, DMM32AT_RANGE_U10);
+
+ /* should take 10 us to settle, here's a hundred */
+ udelay(100);
+
+ /* read back the values */
+ ailo = dmm_inb(dev, DMM32AT_AILOW);
+ aihi = dmm_inb(dev, DMM32AT_AIHIGH);
+ fifostat = dmm_inb(dev, DMM32AT_FIFOSTAT);
+ aistat = dmm_inb(dev, DMM32AT_AISTAT);
+ intstat = dmm_inb(dev, DMM32AT_INTCLOCK);
+ airback = dmm_inb(dev, DMM32AT_AIRBACK);
+
+ printk("dmm32at: lo=0x%02x hi=0x%02x fifostat=0x%02x\n",
+ ailo, aihi, fifostat);
+ printk("dmm32at: aistat=0x%02x intstat=0x%02x airback=0x%02x\n",
+ aistat, intstat, airback);
+
+ if ((ailo != 0x00) || (aihi != 0x1f) || (fifostat != 0x80) ||
+ (aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) {
+ printk("dmmat32: board detection failed\n");
+ return -EIO;
+ }
+
+ /* board is there, register interrupt */
+ if (irq) {
+ ret = comedi_request_irq(irq, dmm32at_isr, 0, thisboard->name,
+ dev);
+ if (ret < 0) {
+ printk("irq conflict\n");
+ return ret;
+ }
+ dev->irq = irq;
+ }
+
+/*
+ * If you can probe the device to determine what device in a series
+ * it is, this is the place to do it. Otherwise, dev->board_ptr
+ * should already be initialized.
+ */
+ //dev->board_ptr = dmm32at_probe(dev);
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct dmm32at_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ /* analog input subdevice */
+ s->type = COMEDI_SUBD_AI;
+ /* we support single-ended (ground) and differential */
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+ s->n_chan = thisboard->ai_chans;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = thisboard->ai_ranges;
+ s->len_chanlist = 32; /* This is the maximum chanlist length that
+ the board can handle */
+ s->insn_read = dmm32at_ai_rinsn;
+ s->do_cmd = dmm32at_ai_cmd;
+ s->do_cmdtest = dmm32at_ai_cmdtest;
+ s->cancel = dmm32at_ai_cancel;
+
+ s = dev->subdevices + 1;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->ao_chans;
+ s->maxdata = (1 << thisboard->ao_bits) - 1;
+ s->range_table = thisboard->ao_ranges;
+ s->insn_write = dmm32at_ao_winsn;
+ s->insn_read = dmm32at_ao_rinsn;
+
+ s = dev->subdevices + 2;
+ /* digital i/o subdevice */
+ if (thisboard->have_dio) {
+
+ /* get access to the DIO regs */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
+ /* set the DIO's to the defualt input setting */
+ devpriv->dio_config = DMM32AT_DIRA | DMM32AT_DIRB |
+ DMM32AT_DIRCL | DMM32AT_DIRCH | DMM32AT_DIENABLE;
+ dmm_outb(dev, DMM32AT_DIOCONF, devpriv->dio_config);
+
+ /* set up the subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = thisboard->dio_chans;
+ s->maxdata = 1;
+ s->state = 0;
+ s->range_table = &range_digital;
+ s->insn_bits = dmm32at_dio_insn_bits;
+ s->insn_config = dmm32at_dio_insn_config;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* success */
+ printk("comedi%d: dmm32at: attached\n", dev->minor);
+
+ return 1;
+
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int dmm32at_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: dmm32at: remove\n", dev->minor);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (dev->iobase)
+ release_region(dev->iobase, DMM32AT_MEMSIZE);
+
+ return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+
+static int dmm32at_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i;
+ unsigned int d;
+ unsigned char status;
+ unsigned short msb, lsb;
+ unsigned char chan;
+ int range;
+
+ /* get the channel and range number */
+
+ chan = CR_CHAN(insn->chanspec) & (s->n_chan - 1);
+ range = CR_RANGE(insn->chanspec);
+
+ //printk("channel=0x%02x, range=%d\n",chan,range);
+
+ /* zero scan and fifo control and reset fifo */
+ dmm_outb(dev, DMM32AT_FIFOCNTRL, DMM32AT_FIFORESET);
+
+ /* write the ai channel range regs */
+ dmm_outb(dev, DMM32AT_AILOW, chan);
+ dmm_outb(dev, DMM32AT_AIHIGH, chan);
+ /* set the range bits */
+ dmm_outb(dev, DMM32AT_AICONF, dmm32at_rangebits[range]);
+
+ /* wait for circuit to settle */
+ for (i = 0; i < 40000; i++) {
+ status = dmm_inb(dev, DMM32AT_AIRBACK);
+ if ((status & DMM32AT_STATUS) == 0)
+ break;
+ }
+ if (i == 40000) {
+ printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ /* convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ dmm_outb(dev, DMM32AT_CONV, 0xff);
+ /* wait for conversion to end */
+ for (i = 0; i < 40000; i++) {
+ status = dmm_inb(dev, DMM32AT_AISTAT);
+ if ((status & DMM32AT_STATUS) == 0)
+ break;
+ }
+ if (i == 40000) {
+ printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ /* read data */
+ lsb = dmm_inb(dev, DMM32AT_AILSB);
+ msb = dmm_inb(dev, DMM32AT_AIMSB);
+
+ /* invert sign bit to make range unsigned, this is an
+ idiosyncracy of the diamond board, it return
+ conversions as a signed value, i.e. -32768 to
+ 32767, flipping the bit and interpreting it as
+ signed gives you a range of 0 to 65535 which is
+ used by comedi */
+ d = ((msb ^ 0x0080) << 8) + lsb;
+
+ data[n] = d;
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+static int dmm32at_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int start_chan, gain, i;
+
+ //printk("dmmat32 in command test\n");
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER /*| TRIG_EXT */ ;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER /*| TRIG_EXT */ ;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SCAN_SPEED 1000000 /* in nanoseconds */
+#define MIN_SCAN_SPEED 1000000000 /* in nanoseconds */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < MAX_SCAN_SPEED) {
+ cmd->scan_begin_arg = MAX_SCAN_SPEED;
+ err++;
+ }
+ if (cmd->scan_begin_arg > MIN_SCAN_SPEED) {
+ cmd->scan_begin_arg = MIN_SCAN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* should be level/edge, hi/lo specification here */
+ /* should specify multiple external triggers */
+ if (cmd->scan_begin_arg > 9) {
+ cmd->scan_begin_arg = 9;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg >= 17500)
+ cmd->convert_arg = 20000;
+ else if (cmd->convert_arg >= 12500)
+ cmd->convert_arg = 15000;
+ else if (cmd->convert_arg >= 7500)
+ cmd->convert_arg = 10000;
+ else
+ cmd->convert_arg = 5000;
+
+ } else {
+ /* external trigger */
+ /* see above */
+ if (cmd->convert_arg > 9) {
+ cmd->convert_arg = 9;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg > 0xfffffff0) {
+ cmd->stop_arg = 0xfffffff0;
+ err++;
+ }
+ if (cmd->stop_arg == 0) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ dmm32at_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ dmm32at_ns_to_timer(&cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+
+ if (err)
+ return 4;
+
+ /* step 5 check the channel list, the channel list for this
+ board must be consecutive and gains must be the same */
+
+ if (cmd->chanlist) {
+ gain = CR_RANGE(cmd->chanlist[0]);
+ start_chan = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) !=
+ (start_chan + i) % s->n_chan) {
+ comedi_error(dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ err++;
+ }
+ if (CR_RANGE(cmd->chanlist[i]) != gain) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same gain\n");
+ err++;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int dmm32at_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int i, range;
+ unsigned char chanlo, chanhi, status;
+
+ if (!cmd->chanlist)
+ return -EINVAL;
+
+ /* get the channel list and range */
+ chanlo = CR_CHAN(cmd->chanlist[0]) & (s->n_chan - 1);
+ chanhi = chanlo + cmd->chanlist_len - 1;
+ if (chanhi >= s->n_chan)
+ return -EINVAL;
+ range = CR_RANGE(cmd->chanlist[0]);
+
+ /* reset fifo */
+ dmm_outb(dev, DMM32AT_FIFOCNTRL, DMM32AT_FIFORESET);
+
+ /* set scan enable */
+ dmm_outb(dev, DMM32AT_FIFOCNTRL, DMM32AT_SCANENABLE);
+
+ /* write the ai channel range regs */
+ dmm_outb(dev, DMM32AT_AILOW, chanlo);
+ dmm_outb(dev, DMM32AT_AIHIGH, chanhi);
+
+ /* set the range bits */
+ dmm_outb(dev, DMM32AT_AICONF, dmm32at_rangebits[range]);
+
+ /* reset the interrupt just in case */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_INTRESET);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ devpriv->ai_scans_left = cmd->stop_arg;
+ else { /* TRIG_NONE */
+ devpriv->ai_scans_left = 0xffffffff; /* indicates TRIG_NONE to isr */
+ }
+
+ /* wait for circuit to settle */
+ for (i = 0; i < 40000; i++) {
+ status = dmm_inb(dev, DMM32AT_AIRBACK);
+ if ((status & DMM32AT_STATUS) == 0)
+ break;
+ }
+ if (i == 40000) {
+ printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ if (devpriv->ai_scans_left > 1) {
+ /* start the clock and enable the interrupts */
+ dmm32at_setaitimer(dev, cmd->scan_begin_arg);
+ } else {
+ /* start the interrups and initiate a single scan */
+ dmm_outb(dev, DMM32AT_INTCLOCK, DMM32AT_ADINT);
+ dmm_outb(dev, DMM32AT_CONV, 0xff);
+ }
+
+/* printk("dmmat32 in command\n"); */
+
+/* for(i=0;i<cmd->chanlist_len;i++) */
+/* comedi_buf_put(s->async,i*100); */
+
+/* s->async->events |= COMEDI_CB_EOA; */
+/* comedi_event(dev, s); */
+
+ return 0;
+
+}
+
+static int dmm32at_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ devpriv->ai_scans_left = 1;
+ return 0;
+}
+
+static irqreturn_t dmm32at_isr(int irq, void *d PT_REGS_ARG)
+{
+ unsigned char intstat;
+ unsigned int samp;
+ unsigned short msb, lsb;
+ int i;
+ struct comedi_device *dev = d;
+
+ if (!dev->attached) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_HANDLED;
+ }
+
+ intstat = dmm_inb(dev, DMM32AT_INTCLOCK);
+
+ if (intstat & DMM32AT_ADINT) {
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ /* read data */
+ lsb = dmm_inb(dev, DMM32AT_AILSB);
+ msb = dmm_inb(dev, DMM32AT_AIMSB);
+
+ /* invert sign bit to make range unsigned */
+ samp = ((msb ^ 0x0080) << 8) + lsb;
+ comedi_buf_put(s->async, samp);
+ }
+
+ if (devpriv->ai_scans_left != 0xffffffff) { /* TRIG_COUNT */
+ devpriv->ai_scans_left--;
+ if (devpriv->ai_scans_left == 0) {
+ /* disable further interrupts and clocks */
+ dmm_outb(dev, DMM32AT_INTCLOCK, 0x0);
+ /* set the buffer to be flushed with an EOF */
+ s->async->events |= COMEDI_CB_EOA;
+ }
+
+ }
+ /* flush the buffer */
+ comedi_event(dev, s);
+ }
+
+ /* reset the interrupt */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_INTRESET);
+ return IRQ_HANDLED;
+}
+
+/* This function doesn't require a particular form, this is just
+ * what happens to be used in some of the drivers. It should
+ * convert ns nanoseconds to a counter value suitable for programming
+ * the device. Also, it should adjust ns so that it cooresponds to
+ * the actual time that the device will use. */
+static int dmm32at_ns_to_timer(unsigned int *ns, int round)
+{
+ /* trivial timer */
+ /* if your timing is done through two cascaded timers, the
+ * i8253_cascade_ns_to_timer() function in 8253.h can be
+ * very helpful. There are also i8254_load() and i8254_mm_load()
+ * which can be used to load values into the ubiquitous 8254 counters
+ */
+
+ return *ns;
+}
+
+static int dmm32at_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned char hi, lo, status;
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+
+ devpriv->ao_readback[chan] = data[i];
+
+ /* get the low byte */
+ lo = data[i] & 0x00ff;
+ /* high byte also contains channel number */
+ hi = (data[i] >> 8) + chan * (1 << 6);
+ //printk("writing 0x%02x 0x%02x\n",hi,lo);
+ /* write the low and high values to the board */
+ dmm_outb(dev, DMM32AT_DACLSB, lo);
+ dmm_outb(dev, DMM32AT_DACMSB, hi);
+
+ /* wait for circuit to settle */
+ for (i = 0; i < 40000; i++) {
+ status = dmm_inb(dev, DMM32AT_DACSTAT);
+ if ((status & DMM32AT_DACBUSY) == 0)
+ break;
+ }
+ if (i == 40000) {
+ printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+ /* dummy read to update trigger the output */
+ status = dmm_inb(dev, DMM32AT_DACMSB);
+
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int dmm32at_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int dmm32at_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned char diobits;
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ /* Write out the new digital output lines */
+ //outw(s->state,dev->iobase + DMM32AT_DIO);
+ }
+
+ /* get access to the DIO regs */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
+
+ /* if either part of dio is set for output */
+ if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) ||
+ ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
+ diobits = (s->state & 0x00ff0000) >> 16;
+ dmm_outb(dev, DMM32AT_DIOC, diobits);
+ }
+ if ((devpriv->dio_config & DMM32AT_DIRB) == 0) {
+ diobits = (s->state & 0x0000ff00) >> 8;
+ dmm_outb(dev, DMM32AT_DIOB, diobits);
+ }
+ if ((devpriv->dio_config & DMM32AT_DIRA) == 0) {
+ diobits = (s->state & 0x000000ff);
+ dmm_outb(dev, DMM32AT_DIOA, diobits);
+ }
+
+ /* now read the state back in */
+ s->state = dmm_inb(dev, DMM32AT_DIOC);
+ s->state <<= 8;
+ s->state |= dmm_inb(dev, DMM32AT_DIOB);
+ s->state <<= 8;
+ s->state |= dmm_inb(dev, DMM32AT_DIOA);
+ data[1] = s->state;
+
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ //data[1]=inw(dev->iobase + DMM32AT_DIO);
+ /* or we could just return the software copy of the output values if
+ * it was a purely digital output subdevice */
+ //data[1]=s->state;
+
+ return 2;
+}
+
+static int dmm32at_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned char chanbit;
+ int chan = CR_CHAN(insn->chanspec);
+
+ if (insn->n != 1)
+ return -EINVAL;
+
+ if (chan < 8)
+ chanbit = DMM32AT_DIRA;
+ else if (chan < 16)
+ chanbit = DMM32AT_DIRB;
+ else if (chan < 20)
+ chanbit = DMM32AT_DIRCL;
+ else
+ chanbit = DMM32AT_DIRCH;
+
+ /* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+ /* if output clear the bit, otherwise set it */
+ if (data[0] == COMEDI_OUTPUT) {
+ devpriv->dio_config &= ~chanbit;
+ } else {
+ devpriv->dio_config |= chanbit;
+ }
+ /* get access to the DIO regs */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
+ /* set the DIO's to the new configuration setting */
+ dmm_outb(dev, DMM32AT_DIOCONF, devpriv->dio_config);
+
+ return 1;
+}
+
+void dmm32at_setaitimer(struct comedi_device * dev, unsigned int nansec)
+{
+ unsigned char lo1, lo2, hi2;
+ unsigned short both2;
+
+ /* based on 10mhz clock */
+ lo1 = 200;
+ both2 = nansec / 20000;
+ hi2 = (both2 & 0xff00) >> 8;
+ lo2 = both2 & 0x00ff;
+
+ /* set the counter frequency to 10mhz */
+ dmm_outb(dev, DMM32AT_CNTRDIO, 0);
+
+ /* get access to the clock regs */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_CLKACC);
+
+ /* write the counter 1 control word and low byte to counter */
+ dmm_outb(dev, DMM32AT_CLKCT, DMM32AT_CLKCT1);
+ dmm_outb(dev, DMM32AT_CLK1, lo1);
+
+ /* write the counter 2 control word and low byte then to counter */
+ dmm_outb(dev, DMM32AT_CLKCT, DMM32AT_CLKCT2);
+ dmm_outb(dev, DMM32AT_CLK2, lo2);
+ dmm_outb(dev, DMM32AT_CLK2, hi2);
+
+ /* enable the ai conversion interrupt and the clock to start scans */
+ dmm_outb(dev, DMM32AT_INTCLOCK, DMM32AT_ADINT | DMM32AT_CLKSEL);
+
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_dmm32at);
diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c
new file mode 100644
index 00000000000..5e0eed835d1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2801.c
@@ -0,0 +1,697 @@
+/*
+ * comedi/drivers/dt2801.c
+ * Device Driver for DataTranslation DT2801
+ *
+ */
+/*
+Driver: dt2801
+Description: Data Translation DT2801 series and DT01-EZ
+Author: ds
+Status: works
+Devices: [Data Translation] DT2801 (dt2801), DT2801-A, DT2801/5716A,
+ DT2805, DT2805/5716A, DT2808, DT2818, DT2809, DT01-EZ
+
+This driver can autoprobe the type of board.
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - unused
+ [2] - A/D reference 0=differential, 1=single-ended
+ [3] - A/D range
+ 0 = [-10,10]
+ 1 = [0,10]
+ [4] - D/A 0 range
+ 0 = [-10,10]
+ 1 = [-5,5]
+ 2 = [-2.5,2.5]
+ 3 = [0,10]
+ 4 = [0,5]
+ [5] - D/A 1 range (same choices)
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+#include <linux/ioport.h>
+
+#define DT2801_TIMEOUT 1000
+
+/* Hardware Configuration */
+/* ====================== */
+
+#define DT2801_MAX_DMA_SIZE (64 * 1024)
+
+/* Ports */
+#define DT2801_IOSIZE 2
+
+/* define's */
+/* ====================== */
+
+/* Commands */
+#define DT_C_RESET 0x0
+#define DT_C_CLEAR_ERR 0x1
+#define DT_C_READ_ERRREG 0x2
+#define DT_C_SET_CLOCK 0x3
+
+#define DT_C_TEST 0xb
+#define DT_C_STOP 0xf
+
+#define DT_C_SET_DIGIN 0x4
+#define DT_C_SET_DIGOUT 0x5
+#define DT_C_READ_DIG 0x6
+#define DT_C_WRITE_DIG 0x7
+
+#define DT_C_WRITE_DAIM 0x8
+#define DT_C_SET_DA 0x9
+#define DT_C_WRITE_DA 0xa
+
+#define DT_C_READ_ADIM 0xc
+#define DT_C_SET_AD 0xd
+#define DT_C_READ_AD 0xe
+
+/* Command modifiers (only used with read/write), EXTTRIG can be
+ used with some other commands.
+*/
+#define DT_MOD_DMA (1<<4)
+#define DT_MOD_CONT (1<<5)
+#define DT_MOD_EXTCLK (1<<6)
+#define DT_MOD_EXTTRIG (1<<7)
+
+/* Bits in status register */
+#define DT_S_DATA_OUT_READY (1<<0)
+#define DT_S_DATA_IN_FULL (1<<1)
+#define DT_S_READY (1<<2)
+#define DT_S_COMMAND (1<<3)
+#define DT_S_COMPOSITE_ERROR (1<<7)
+
+/* registers */
+#define DT2801_DATA 0
+#define DT2801_STATUS 1
+#define DT2801_CMD 1
+
+static int dt2801_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2801_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2801 = {
+ driver_name:"dt2801",
+ module:THIS_MODULE,
+ attach:dt2801_attach,
+ detach:dt2801_detach,
+};
+
+COMEDI_INITCLEANUP(driver_dt2801);
+
+#if 0
+// ignore 'defined but not used' warning
+static const struct comedi_lrange range_dt2801_ai_pgh_bipolar = { 4, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ }
+};
+#endif
+static const struct comedi_lrange range_dt2801_ai_pgl_bipolar = { 4, {
+ RANGE(-10, 10),
+ RANGE(-1, 1),
+ RANGE(-0.1, 0.1),
+ RANGE(-0.02, 0.02),
+ }
+};
+
+#if 0
+// ignore 'defined but not used' warning
+static const struct comedi_lrange range_dt2801_ai_pgh_unipolar = { 4, {
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 2.5),
+ RANGE(0, 1.25),
+ }
+};
+#endif
+static const struct comedi_lrange range_dt2801_ai_pgl_unipolar = { 4, {
+ RANGE(0, 10),
+ RANGE(0, 1),
+ RANGE(0, 0.1),
+ RANGE(0, 0.02),
+ }
+};
+
+struct dt2801_board {
+
+ const char *name;
+ int boardcode;
+ int ad_diff;
+ int ad_chan;
+ int adbits;
+ int adrangetype;
+ int dabits;
+};
+
+
+/* Typeid's for the different boards of the DT2801-series
+ (taken from the test-software, that comes with the board)
+ */
+static const struct dt2801_board boardtypes[] = {
+ {
+ name: "dt2801",
+ boardcode:0x09,
+ ad_diff: 2,
+ ad_chan: 16,
+ adbits: 12,
+ adrangetype:0,
+ dabits: 12},
+ {
+ name: "dt2801-a",
+ boardcode:0x52,
+ ad_diff: 2,
+ ad_chan: 16,
+ adbits: 12,
+ adrangetype:0,
+ dabits: 12},
+ {
+ name: "dt2801/5716a",
+ boardcode:0x82,
+ ad_diff: 1,
+ ad_chan: 16,
+ adbits: 16,
+ adrangetype:1,
+ dabits: 12},
+ {
+ name: "dt2805",
+ boardcode:0x12,
+ ad_diff: 1,
+ ad_chan: 16,
+ adbits: 12,
+ adrangetype:0,
+ dabits: 12},
+ {
+ name: "dt2805/5716a",
+ boardcode:0x92,
+ ad_diff: 1,
+ ad_chan: 16,
+ adbits: 16,
+ adrangetype:1,
+ dabits: 12},
+ {
+ name: "dt2808",
+ boardcode:0x20,
+ ad_diff: 0,
+ ad_chan: 16,
+ adbits: 12,
+ adrangetype:2,
+ dabits: 8},
+ {
+ name: "dt2818",
+ boardcode:0xa2,
+ ad_diff: 0,
+ ad_chan: 4,
+ adbits: 12,
+ adrangetype:0,
+ dabits: 12},
+ {
+ name: "dt2809",
+ boardcode:0xb0,
+ ad_diff: 0,
+ ad_chan: 8,
+ adbits: 12,
+ adrangetype:1,
+ dabits: 12},
+};
+
+#define n_boardtypes ((sizeof(boardtypes))/(sizeof(boardtypes[0])))
+#define boardtype (*(const struct dt2801_board *)dev->board_ptr)
+
+struct dt2801_private {
+
+ const struct comedi_lrange *dac_range_types[2];
+ unsigned int ao_readback[2];
+};
+
+#define devpriv ((struct dt2801_private *)dev->private)
+
+static int dt2801_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2801_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2801_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2801_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2801_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/* These are the low-level routines:
+ writecommand: write a command to the board
+ writedata: write data byte
+ readdata: read data byte
+ */
+
+/* Only checks DataOutReady-flag, not the Ready-flag as it is done
+ in the examples of the manual. I don't see why this should be
+ necessary. */
+static int dt2801_readdata(struct comedi_device * dev, int *data)
+{
+ int stat = 0;
+ int timeout = DT2801_TIMEOUT;
+
+ do {
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+ if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY)) {
+ return stat;
+ }
+ if (stat & DT_S_DATA_OUT_READY) {
+ *data = inb_p(dev->iobase + DT2801_DATA);
+ return 0;
+ }
+ } while (--timeout > 0);
+
+ return -ETIME;
+}
+
+static int dt2801_readdata2(struct comedi_device * dev, int *data)
+{
+ int lb, hb;
+ int ret;
+
+ ret = dt2801_readdata(dev, &lb);
+ if (ret)
+ return ret;
+ ret = dt2801_readdata(dev, &hb);
+ if (ret)
+ return ret;
+
+ *data = (hb << 8) + lb;
+ return 0;
+}
+
+static int dt2801_writedata(struct comedi_device * dev, unsigned int data)
+{
+ int stat = 0;
+ int timeout = DT2801_TIMEOUT;
+
+ do {
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+
+ if (stat & DT_S_COMPOSITE_ERROR) {
+ return stat;
+ }
+ if (!(stat & DT_S_DATA_IN_FULL)) {
+ outb_p(data & 0xff, dev->iobase + DT2801_DATA);
+ return 0;
+ }
+#if 0
+ if (stat & DT_S_READY) {
+ printk("dt2801: ready flag set (bad!) in dt2801_writedata()\n");
+ return -EIO;
+ }
+#endif
+ } while (--timeout > 0);
+
+ return -ETIME;
+}
+
+static int dt2801_writedata2(struct comedi_device * dev, unsigned int data)
+{
+ int ret;
+
+ ret = dt2801_writedata(dev, data & 0xff);
+ if (ret < 0)
+ return ret;
+ ret = dt2801_writedata(dev, (data >> 8));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int dt2801_wait_for_ready(struct comedi_device * dev)
+{
+ int timeout = DT2801_TIMEOUT;
+ int stat;
+
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+ if (stat & DT_S_READY) {
+ return 0;
+ }
+ do {
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+
+ if (stat & DT_S_COMPOSITE_ERROR) {
+ return stat;
+ }
+ if (stat & DT_S_READY) {
+ return 0;
+ }
+ } while (--timeout > 0);
+
+ return -ETIME;
+}
+
+static int dt2801_writecmd(struct comedi_device * dev, int command)
+{
+ int stat;
+
+ dt2801_wait_for_ready(dev);
+
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+ if (stat & DT_S_COMPOSITE_ERROR) {
+ printk("dt2801: composite-error in dt2801_writecmd(), ignoring\n");
+ }
+ if (!(stat & DT_S_READY)) {
+ printk("dt2801: !ready in dt2801_writecmd(), ignoring\n");
+ }
+ outb_p(command, dev->iobase + DT2801_CMD);
+
+ return 0;
+}
+
+static int dt2801_reset(struct comedi_device * dev)
+{
+ int board_code = 0;
+ unsigned int stat;
+ int timeout;
+
+ DPRINTK("dt2801: resetting board...\n");
+ DPRINTK("fingerprint: 0x%02x 0x%02x\n", inb_p(dev->iobase),
+ inb_p(dev->iobase + 1));
+
+ /* pull random data from data port */
+ inb_p(dev->iobase + DT2801_DATA);
+ inb_p(dev->iobase + DT2801_DATA);
+ inb_p(dev->iobase + DT2801_DATA);
+ inb_p(dev->iobase + DT2801_DATA);
+
+ DPRINTK("dt2801: stop\n");
+ //dt2801_writecmd(dev,DT_C_STOP);
+ outb_p(DT_C_STOP, dev->iobase + DT2801_CMD);
+
+ //dt2801_wait_for_ready(dev);
+ comedi_udelay(100);
+ timeout = 10000;
+ do {
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+ if (stat & DT_S_READY)
+ break;
+ } while (timeout--);
+ if (!timeout) {
+ printk("dt2801: timeout 1 status=0x%02x\n", stat);
+ }
+ //printk("dt2801: reading dummy\n");
+ //dt2801_readdata(dev,&board_code);
+
+ DPRINTK("dt2801: reset\n");
+ outb_p(DT_C_RESET, dev->iobase + DT2801_CMD);
+ //dt2801_writecmd(dev,DT_C_RESET);
+
+ comedi_udelay(100);
+ timeout = 10000;
+ do {
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+ if (stat & DT_S_READY)
+ break;
+ } while (timeout--);
+ if (!timeout) {
+ printk("dt2801: timeout 2 status=0x%02x\n", stat);
+ }
+
+ DPRINTK("dt2801: reading code\n");
+ dt2801_readdata(dev, &board_code);
+
+ DPRINTK("dt2801: ok. code=0x%02x\n", board_code);
+
+ return board_code;
+}
+
+static int probe_number_of_ai_chans(struct comedi_device * dev)
+{
+ int n_chans;
+ int stat;
+ int data;
+
+ for (n_chans = 0; n_chans < 16; n_chans++) {
+ stat = dt2801_writecmd(dev, DT_C_READ_ADIM);
+ dt2801_writedata(dev, 0);
+ dt2801_writedata(dev, n_chans);
+ stat = dt2801_readdata2(dev, &data);
+
+ if (stat)
+ break;
+ }
+
+ dt2801_reset(dev);
+ dt2801_reset(dev);
+
+ return n_chans;
+}
+
+static const struct comedi_lrange *dac_range_table[] = {
+ &range_bipolar10,
+ &range_bipolar5,
+ &range_bipolar2_5,
+ &range_unipolar10,
+ &range_unipolar5
+};
+
+static const struct comedi_lrange *dac_range_lkup(int opt)
+{
+ if (opt < 0 || opt > 5)
+ return &range_unknown;
+ return dac_range_table[opt];
+}
+
+static const struct comedi_lrange *ai_range_lkup(int type, int opt)
+{
+ switch (type) {
+ case 0:
+ return (opt) ?
+ &range_dt2801_ai_pgl_unipolar :
+ &range_dt2801_ai_pgl_bipolar;
+ case 1:
+ return (opt) ? &range_unipolar10 : &range_bipolar10;
+ case 2:
+ return &range_unipolar5;
+ }
+ return &range_unknown;
+}
+
+/*
+ options:
+ [0] - i/o base
+ [1] - unused
+ [2] - a/d 0=differential, 1=single-ended
+ [3] - a/d range 0=[-10,10], 1=[0,10]
+ [4] - dac0 range 0=[-10,10], 1=[-5,5], 2=[-2.5,2.5] 3=[0,10], 4=[0,5]
+ [5] - dac1 range 0=[-10,10], 1=[-5,5], 2=[-2.5,2.5] 3=[0,10], 4=[0,5]
+*/
+static int dt2801_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+ int board_code, type;
+ int ret = 0;
+ int n_ai_chans;
+
+ iobase = it->options[0];
+ if (!request_region(iobase, DT2801_IOSIZE, "dt2801")) {
+ comedi_error(dev, "I/O port conflict");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* do some checking */
+
+ board_code = dt2801_reset(dev);
+
+ /* heh. if it didn't work, try it again. */
+ if (!board_code)
+ board_code = dt2801_reset(dev);
+
+ for (type = 0; type < n_boardtypes; type++) {
+ if (boardtypes[type].boardcode == board_code)
+ goto havetype;
+ }
+ printk("dt2801: unrecognized board code=0x%02x, contact author\n",
+ board_code);
+ type = 0;
+
+ havetype:
+ dev->board_ptr = boardtypes + type;
+ printk("dt2801: %s at port 0x%lx", boardtype.name, iobase);
+
+ n_ai_chans = probe_number_of_ai_chans(dev);
+ printk(" (ai channels = %d)", n_ai_chans);
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ goto out;
+
+ if ((ret = alloc_private(dev, sizeof(struct dt2801_private))) < 0)
+ goto out;
+
+ dev->board_name = boardtype.name;
+
+ s = dev->subdevices + 0;
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+#if 1
+ s->n_chan = n_ai_chans;
+#else
+ if (it->options[2])
+ s->n_chan = boardtype.ad_chan;
+ else
+ s->n_chan = boardtype.ad_chan / 2;
+#endif
+ s->maxdata = (1 << boardtype.adbits) - 1;
+ s->range_table = ai_range_lkup(boardtype.adrangetype, it->options[3]);
+ s->insn_read = dt2801_ai_insn_read;
+
+ s++;
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->maxdata = (1 << boardtype.dabits) - 1;
+ s->range_table_list = devpriv->dac_range_types;
+ devpriv->dac_range_types[0] = dac_range_lkup(it->options[4]);
+ devpriv->dac_range_types[1] = dac_range_lkup(it->options[5]);
+ s->insn_read = dt2801_ao_insn_read;
+ s->insn_write = dt2801_ao_insn_write;
+
+ s++;
+ /* 1st digital subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = dt2801_dio_insn_bits;
+ s->insn_config = dt2801_dio_insn_config;
+
+ s++;
+ /* 2nd digital subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = dt2801_dio_insn_bits;
+ s->insn_config = dt2801_dio_insn_config;
+
+ ret = 0;
+ out:
+ printk("\n");
+
+ return ret;
+}
+
+static int dt2801_detach(struct comedi_device * dev)
+{
+ if (dev->iobase)
+ release_region(dev->iobase, DT2801_IOSIZE);
+
+ return 0;
+}
+
+static int dt2801_error(struct comedi_device * dev, int stat)
+{
+ if (stat < 0) {
+ if (stat == -ETIME) {
+ printk("dt2801: timeout\n");
+ } else {
+ printk("dt2801: error %d\n", stat);
+ }
+ return stat;
+ }
+ printk("dt2801: error status 0x%02x, resetting...\n", stat);
+
+ dt2801_reset(dev);
+ dt2801_reset(dev);
+
+ return -EIO;
+}
+
+static int dt2801_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int d;
+ int stat;
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ stat = dt2801_writecmd(dev, DT_C_READ_ADIM);
+ dt2801_writedata(dev, CR_RANGE(insn->chanspec));
+ dt2801_writedata(dev, CR_CHAN(insn->chanspec));
+ stat = dt2801_readdata2(dev, &d);
+
+ if (stat != 0)
+ return dt2801_error(dev, stat);
+
+ data[i] = d;
+ }
+
+ return i;
+}
+
+static int dt2801_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int dt2801_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ dt2801_writecmd(dev, DT_C_WRITE_DAIM);
+ dt2801_writedata(dev, CR_CHAN(insn->chanspec));
+ dt2801_writedata2(dev, data[0]);
+
+ devpriv->ao_readback[CR_CHAN(insn->chanspec)] = data[0];
+
+ return 1;
+}
+
+static int dt2801_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int which = 0;
+
+ if (s == dev->subdevices + 4)
+ which = 1;
+
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ dt2801_writecmd(dev, DT_C_WRITE_DIG);
+ dt2801_writedata(dev, which);
+ dt2801_writedata(dev, s->state);
+ }
+ dt2801_writecmd(dev, DT_C_READ_DIG);
+ dt2801_writedata(dev, which);
+ dt2801_readdata(dev, data + 1);
+
+ return 2;
+}
+
+static int dt2801_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int which = 0;
+
+ if (s == dev->subdevices + 4)
+ which = 1;
+
+ /* configure */
+ if (data[0]) {
+ s->io_bits = 0xff;
+ dt2801_writecmd(dev, DT_C_SET_DIGOUT);
+ } else {
+ s->io_bits = 0;
+ dt2801_writecmd(dev, DT_C_SET_DIGIN);
+ }
+ dt2801_writedata(dev, which);
+
+ return 1;
+}
diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c
new file mode 100644
index 00000000000..795932ec67d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2811.c
@@ -0,0 +1,604 @@
+/*
+ comedi/drivers/dt2811.c
+ Hardware driver for Data Translation DT2811
+
+ COMEDI - Linux Control and Measurement Device Interface
+ History:
+ Base Version - David A. Schleef <ds@schleef.org>
+ December 1998 - Updated to work. David does not have a DT2811
+ board any longer so this was suffering from bitrot.
+ Updated performed by ...
+
+ 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.
+ */
+/*
+Driver: dt2811
+Description: Data Translation DT2811
+Author: ds
+Devices: [Data Translation] DT2811-PGL (dt2811-pgl), DT2811-PGH (dt2811-pgh)
+Status: works
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ, although this is currently unused
+ [2] - A/D reference
+ 0 = signle-ended
+ 1 = differential
+ 2 = pseudo-differential (common reference)
+ [3] - A/D range
+ 0 = [-5,5]
+ 1 = [-2.5,2.5]
+ 2 = [0,5]
+ [4] - D/A 0 range (same choices)
+ [4] - D/A 1 range (same choices)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+static const char *driver_name = "dt2811";
+
+static const struct comedi_lrange range_dt2811_pgh_ai_5_unipolar = { 4, {
+ RANGE(0, 5),
+ RANGE(0, 2.5),
+ RANGE(0, 1.25),
+ RANGE(0, 0.625)
+ }
+};
+static const struct comedi_lrange range_dt2811_pgh_ai_2_5_bipolar = { 4, {
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ RANGE(-0.625, 0.625),
+ RANGE(-0.3125, 0.3125)
+ }
+};
+static const struct comedi_lrange range_dt2811_pgh_ai_5_bipolar = { 4, {
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ RANGE(-0.625, 0.625)
+ }
+};
+static const struct comedi_lrange range_dt2811_pgl_ai_5_unipolar = { 4, {
+ RANGE(0, 5),
+ RANGE(0, 0.5),
+ RANGE(0, 0.05),
+ RANGE(0, 0.01)
+ }
+};
+static const struct comedi_lrange range_dt2811_pgl_ai_2_5_bipolar = { 4, {
+ RANGE(-2.5, 2.5),
+ RANGE(-0.25, 0.25),
+ RANGE(-0.025, 0.025),
+ RANGE(-0.005, 0.005)
+ }
+};
+static const struct comedi_lrange range_dt2811_pgl_ai_5_bipolar = { 4, {
+ RANGE(-5, 5),
+ RANGE(-0.5, 0.5),
+ RANGE(-0.05, 0.05),
+ RANGE(-0.01, 0.01)
+ }
+};
+
+/*
+
+ 0x00 ADCSR R/W A/D Control/Status Register
+ bit 7 - (R) 1 indicates A/D conversion done
+ reading ADDAT clears bit
+ (W) ignored
+ bit 6 - (R) 1 indicates A/D error
+ (W) ignored
+ bit 5 - (R) 1 indicates A/D busy, cleared at end
+ of conversion
+ (W) ignored
+ bit 4 - (R) 0
+ (W)
+ bit 3 - (R) 0
+ bit 2 - (R/W) 1 indicates interrupts enabled
+ bits 1,0 - (R/W) mode bits
+ 00 single conversion on ADGCR load
+ 01 continuous conversion, internal clock,
+ (clock enabled on ADGCR load)
+ 10 continuous conversion, internal clock,
+ external trigger
+ 11 continuous conversion, external clock,
+ external trigger
+
+ 0x01 ADGCR R/W A/D Gain/Channel Register
+ bit 6,7 - (R/W) gain select
+ 00 gain=1, both PGH, PGL models
+ 01 gain=2 PGH, 10 PGL
+ 10 gain=4 PGH, 100 PGL
+ 11 gain=8 PGH, 500 PGL
+ bit 4,5 - reserved
+ bit 3-0 - (R/W) channel select
+ channel number from 0-15
+
+ 0x02,0x03 (R) ADDAT A/D Data Register
+ (W) DADAT0 D/A Data Register 0
+ 0x02 low byte
+ 0x03 high byte
+
+ 0x04,0x05 (W) DADAT0 D/A Data Register 1
+
+ 0x06 (R) DIO0 Digital Input Port 0
+ (W) DIO1 Digital Output Port 1
+
+ 0x07 TMRCTR (R/W) Timer/Counter Register
+ bits 6,7 - reserved
+ bits 5-3 - Timer frequency control (mantissa)
+ 543 divisor freqency (kHz)
+ 000 1 600
+ 001 10 60
+ 010 2 300
+ 011 3 200
+ 100 4 150
+ 101 5 120
+ 110 6 100
+ 111 12 50
+ bits 2-0 - Timer frequency control (exponent)
+ 210 multiply divisor/divide frequency by
+ 000 1
+ 001 10
+ 010 100
+ 011 1000
+ 100 10000
+ 101 100000
+ 110 1000000
+ 111 10000000
+
+ */
+
+#define TIMEOUT 10000
+
+#define DT2811_SIZE 8
+
+#define DT2811_ADCSR 0
+#define DT2811_ADGCR 1
+#define DT2811_ADDATLO 2
+#define DT2811_ADDATHI 3
+#define DT2811_DADAT0LO 2
+#define DT2811_DADAT0HI 3
+#define DT2811_DADAT1LO 4
+#define DT2811_DADAT1HI 5
+#define DT2811_DIO 6
+#define DT2811_TMRCTR 7
+
+/*
+ * flags
+ */
+
+/* ADCSR */
+
+#define DT2811_ADDONE 0x80
+#define DT2811_ADERROR 0x40
+#define DT2811_ADBUSY 0x20
+#define DT2811_CLRERROR 0x10
+#define DT2811_INTENB 0x04
+#define DT2811_ADMODE 0x03
+
+struct dt2811_board {
+
+ const char *name;
+ const struct comedi_lrange *bip_5;
+ const struct comedi_lrange *bip_2_5;
+ const struct comedi_lrange *unip_5;
+};
+
+static const struct dt2811_board boardtypes[] = {
+ {"dt2811-pgh",
+ &range_dt2811_pgh_ai_5_bipolar,
+ &range_dt2811_pgh_ai_2_5_bipolar,
+ &range_dt2811_pgh_ai_5_unipolar,
+ },
+ {"dt2811-pgl",
+ &range_dt2811_pgl_ai_5_bipolar,
+ &range_dt2811_pgl_ai_2_5_bipolar,
+ &range_dt2811_pgl_ai_5_unipolar,
+ },
+};
+
+#define this_board ((const struct dt2811_board *)dev->board_ptr)
+
+static int dt2811_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2811_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2811 = {
+ driver_name:"dt2811",
+ module:THIS_MODULE,
+ attach:dt2811_attach,
+ detach:dt2811_detach,
+ board_name:&boardtypes[0].name,
+ num_names:sizeof(boardtypes) / sizeof(struct dt2811_board),
+ offset:sizeof(struct dt2811_board),
+};
+
+COMEDI_INITCLEANUP(driver_dt2811);
+
+static int dt2811_ai_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2811_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2811_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2811_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2811_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+enum { card_2811_pgh, card_2811_pgl };
+
+struct dt2811_private {
+ int ntrig;
+ int curadchan;
+ enum {
+ adc_singleended, adc_diff, adc_pseudo_diff
+ } adc_mux;
+ enum {
+ dac_bipolar_5, dac_bipolar_2_5, dac_unipolar_5
+ } dac_range[2];
+ const struct comedi_lrange *range_type_list[2];
+ unsigned int ao_readback[2];
+};
+
+#define devpriv ((struct dt2811_private *)dev->private)
+
+static const struct comedi_lrange *dac_range_types[] = {
+ &range_bipolar5,
+ &range_bipolar2_5,
+ &range_unipolar5
+};
+
+#define DT2811_TIMEOUT 5
+
+#if 0
+static irqreturn_t dt2811_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ int lo, hi;
+ int data;
+ struct comedi_device *dev = d;
+
+ if (!dev->attached) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_HANDLED;
+ }
+
+ lo = inb(dev->iobase + DT2811_ADDATLO);
+ hi = inb(dev->iobase + DT2811_ADDATHI);
+
+ data = lo + (hi << 8);
+
+ if (!(--devpriv->ntrig)) {
+ /* how to turn off acquisition */
+ s->async->events |= COMEDI_SB_EOA;
+ }
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+#endif
+
+/*
+ options[0] Board base address
+ options[1] IRQ
+ options[2] Input configuration
+ 0 == single-ended
+ 1 == differential
+ 2 == pseudo-differential
+ options[3] Analog input range configuration
+ 0 == bipolar 5 (-5V -- +5V)
+ 1 == bipolar 2.5V (-2.5V -- +2.5V)
+ 2 == unipolar 5V (0V -- +5V)
+ options[4] Analog output 0 range configuration
+ 0 == bipolar 5 (-5V -- +5V)
+ 1 == bipolar 2.5V (-2.5V -- +2.5V)
+ 2 == unipolar 5V (0V -- +5V)
+ options[5] Analog output 1 range configuration
+ 0 == bipolar 5 (-5V -- +5V)
+ 1 == bipolar 2.5V (-2.5V -- +2.5V)
+ 2 == unipolar 5V (0V -- +5V)
+*/
+
+static int dt2811_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ //int i, irq;
+ //unsigned long irqs;
+ //long flags;
+ int ret;
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+
+ printk("comedi%d: dt2811: base=0x%04lx\n", dev->minor, iobase);
+
+ if (!request_region(iobase, DT2811_SIZE, driver_name)) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+ dev->board_name = this_board->name;
+
+#if 0
+ outb(0, dev->iobase + DT2811_ADCSR);
+ comedi_udelay(100);
+ i = inb(dev->iobase + DT2811_ADDATLO);
+ i = inb(dev->iobase + DT2811_ADDATHI);
+#endif
+
+#if 0
+ irq = it->options[1];
+ if (irq < 0) {
+ save_flags(flags);
+ sti();
+ irqs = probe_irq_on();
+
+ outb(DT2811_CLRERROR | DT2811_INTENB,
+ dev->iobase + DT2811_ADCSR);
+ outb(0, dev->iobase + DT2811_ADGCR);
+
+ comedi_udelay(100);
+
+ irq = probe_irq_off(irqs);
+ restore_flags(flags);
+
+ /*outb(DT2811_CLRERROR|DT2811_INTENB,dev->iobase+DT2811_ADCSR); */
+
+ if (inb(dev->iobase + DT2811_ADCSR) & DT2811_ADERROR) {
+ printk("error probing irq (bad) \n");
+ }
+ dev->irq = 0;
+ if (irq > 0) {
+ i = inb(dev->iobase + DT2811_ADDATLO);
+ i = inb(dev->iobase + DT2811_ADDATHI);
+ printk("(irq = %d)\n", irq);
+ ret = comedi_request_irq(irq, dt2811_interrupt, 0,
+ driver_name, dev);
+ if (ret < 0)
+ return -EIO;
+ dev->irq = irq;
+ } else if (irq == 0) {
+ printk("(no irq)\n");
+ } else {
+ printk("( multiple irq's -- this is bad! )\n");
+ }
+ }
+#endif
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct dt2811_private))) < 0)
+ return ret;
+ switch (it->options[2]) {
+ case 0:
+ devpriv->adc_mux = adc_singleended;
+ break;
+ case 1:
+ devpriv->adc_mux = adc_diff;
+ break;
+ case 2:
+ devpriv->adc_mux = adc_pseudo_diff;
+ break;
+ default:
+ devpriv->adc_mux = adc_singleended;
+ break;
+ }
+ switch (it->options[4]) {
+ case 0:
+ devpriv->dac_range[0] = dac_bipolar_5;
+ break;
+ case 1:
+ devpriv->dac_range[0] = dac_bipolar_2_5;
+ break;
+ case 2:
+ devpriv->dac_range[0] = dac_unipolar_5;
+ break;
+ default:
+ devpriv->dac_range[0] = dac_bipolar_5;
+ break;
+ }
+ switch (it->options[5]) {
+ case 0:
+ devpriv->dac_range[1] = dac_bipolar_5;
+ break;
+ case 1:
+ devpriv->dac_range[1] = dac_bipolar_2_5;
+ break;
+ case 2:
+ devpriv->dac_range[1] = dac_unipolar_5;
+ break;
+ default:
+ devpriv->dac_range[1] = dac_bipolar_5;
+ break;
+ }
+
+ s = dev->subdevices + 0;
+ /* initialize the ADC subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = devpriv->adc_mux == adc_diff ? 8 : 16;
+ s->insn_read = dt2811_ai_insn;
+ s->maxdata = 0xfff;
+ switch (it->options[3]) {
+ case 0:
+ default:
+ s->range_table = this_board->bip_5;
+ break;
+ case 1:
+ s->range_table = this_board->bip_2_5;
+ break;
+ case 2:
+ s->range_table = this_board->unip_5;
+ break;
+ }
+
+ s = dev->subdevices + 1;
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->insn_write = dt2811_ao_insn;
+ s->insn_read = dt2811_ao_insn_read;
+ s->maxdata = 0xfff;
+ s->range_table_list = devpriv->range_type_list;
+ devpriv->range_type_list[0] = dac_range_types[devpriv->dac_range[0]];
+ devpriv->range_type_list[1] = dac_range_types[devpriv->dac_range[1]];
+
+ s = dev->subdevices + 2;
+ /* di subdevice */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 8;
+ s->insn_bits = dt2811_di_insn_bits;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+
+ s = dev->subdevices + 3;
+ /* do subdevice */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 8;
+ s->insn_bits = dt2811_do_insn_bits;
+ s->maxdata = 1;
+ s->state = 0;
+ s->range_table = &range_digital;
+
+ return 0;
+}
+
+static int dt2811_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: dt2811: remove\n", dev->minor);
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (dev->iobase) {
+ release_region(dev->iobase, DT2811_SIZE);
+ }
+
+ return 0;
+}
+
+static int dt2811_ai_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int timeout = DT2811_TIMEOUT;
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ outb(chan, dev->iobase + DT2811_ADGCR);
+
+ while (timeout
+ && inb(dev->iobase + DT2811_ADCSR) & DT2811_ADBUSY)
+ timeout--;
+ if (!timeout)
+ return -ETIME;
+
+ data[i] = inb(dev->iobase + DT2811_ADDATLO);
+ data[i] |= inb(dev->iobase + DT2811_ADDATHI) << 8;
+ data[i] &= 0xfff;
+ }
+
+ return i;
+}
+
+#if 0
+/* Wow. This is code from the Comedi stone age. But it hasn't been
+ * replaced, so I'll let it stay. */
+int dt2811_adtrig(kdev_t minor, comedi_adtrig * adtrig)
+{
+ struct comedi_device *dev = comedi_devices + minor;
+
+ if (adtrig->n < 1)
+ return 0;
+ dev->curadchan = adtrig->chan;
+ switch (dev->i_admode) {
+ case COMEDI_MDEMAND:
+ dev->ntrig = adtrig->n - 1;
+ /*printk("dt2811: AD soft trigger\n"); */
+ /*outb(DT2811_CLRERROR|DT2811_INTENB,dev->iobase+DT2811_ADCSR); *//* not neccessary */
+ outb(dev->curadchan, dev->iobase + DT2811_ADGCR);
+ do_gettimeofday(&trigtime);
+ break;
+ case COMEDI_MCONTS:
+ dev->ntrig = adtrig->n;
+ break;
+ }
+
+ return 0;
+}
+#endif
+
+static int dt2811_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ outb(data[i] & 0xff, dev->iobase + DT2811_DADAT0LO + 2 * chan);
+ outb((data[i] >> 8) & 0xff,
+ dev->iobase + DT2811_DADAT0HI + 2 * chan);
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ return i;
+}
+
+static int dt2811_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+static int dt2811_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + DT2811_DIO);
+
+ return 2;
+}
+
+static int dt2811_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ outb(s->state, dev->iobase + DT2811_DIO);
+
+ data[1] = s->state;
+
+ return 2;
+}
diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c
new file mode 100644
index 00000000000..8320139160a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2814.c
@@ -0,0 +1,383 @@
+/*
+ comedi/drivers/dt2814.c
+ Hardware driver for Data Translation DT2814
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: dt2814
+Description: Data Translation DT2814
+Author: ds
+Status: complete
+Devices: [Data Translation] DT2814 (dt2814)
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ
+
+This card has 16 analog inputs multiplexed onto a 12 bit ADC. There
+is a minimally useful onboard clock. The base frequency for the
+clock is selected by jumpers, and the clock divider can be selected
+via programmed I/O. Unfortunately, the clock divider can only be
+a power of 10, from 1 to 10^7, of which only 3 or 4 are useful. In
+addition, the clock does not seem to be very accurate.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#define DT2814_SIZE 2
+
+#define DT2814_CSR 0
+#define DT2814_DATA 1
+
+/*
+ * flags
+ */
+
+#define DT2814_FINISH 0x80
+#define DT2814_ERR 0x40
+#define DT2814_BUSY 0x20
+#define DT2814_ENB 0x10
+#define DT2814_CHANMASK 0x0f
+
+static int dt2814_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2814_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2814 = {
+ driver_name:"dt2814",
+ module:THIS_MODULE,
+ attach:dt2814_attach,
+ detach:dt2814_detach,
+};
+
+COMEDI_INITCLEANUP(driver_dt2814);
+
+static irqreturn_t dt2814_interrupt(int irq, void *dev PT_REGS_ARG);
+
+struct dt2814_private {
+
+ int ntrig;
+ int curadchan;
+};
+
+#define devpriv ((struct dt2814_private *)dev->private)
+
+#define DT2814_TIMEOUT 10
+#define DT2814_MAX_SPEED 100000 /* Arbitrary 10 khz limit */
+
+static int dt2814_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i, hi, lo;
+ int chan;
+ int status = 0;
+
+ for (n = 0; n < insn->n; n++) {
+ chan = CR_CHAN(insn->chanspec);
+
+ outb(chan, dev->iobase + DT2814_CSR);
+ for (i = 0; i < DT2814_TIMEOUT; i++) {
+ status = inb(dev->iobase + DT2814_CSR);
+ printk("dt2814: status: %02x\n", status);
+ comedi_udelay(10);
+ if (status & DT2814_FINISH)
+ break;
+ }
+ if (i >= DT2814_TIMEOUT) {
+ printk("dt2814: status: %02x\n", status);
+ return -ETIMEDOUT;
+ }
+
+ hi = inb(dev->iobase + DT2814_DATA);
+ lo = inb(dev->iobase + DT2814_DATA);
+
+ data[n] = (hi << 4) | (lo >> 4);
+ }
+
+ return n;
+}
+
+static int dt2814_ns_to_timer(unsigned int *ns, unsigned int flags)
+{
+ int i;
+ unsigned int f;
+
+ /* XXX ignores flags */
+
+ f = 10000; /* ns */
+ for (i = 0; i < 8; i++) {
+ if ((2 * (*ns)) < (f * 11))
+ break;
+ f *= 10;
+ }
+
+ *ns = f;
+
+ return i;
+}
+
+static int dt2814_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg > 1000000000) {
+ cmd->scan_begin_arg = 1000000000;
+ err++;
+ }
+ if (cmd->scan_begin_arg < DT2814_MAX_SPEED) {
+ cmd->scan_begin_arg = DT2814_MAX_SPEED;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg < 2) {
+ cmd->stop_arg = 2;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ tmp = cmd->scan_begin_arg;
+ dt2814_ns_to_timer(&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int dt2814_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int chan;
+ int trigvar;
+
+ trigvar =
+ dt2814_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+
+ chan = CR_CHAN(cmd->chanlist[0]);
+
+ devpriv->ntrig = cmd->stop_arg;
+ outb(chan | DT2814_ENB | (trigvar << 5), dev->iobase + DT2814_CSR);
+
+ return 0;
+
+}
+
+static int dt2814_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int i, irq;
+ int ret;
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: dt2814: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, DT2814_SIZE, "dt2814")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+ dev->board_name = "dt2814";
+
+ outb(0, dev->iobase + DT2814_CSR);
+ comedi_udelay(100);
+ if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) {
+ printk("reset error (fatal)\n");
+ return -EIO;
+ }
+ i = inb(dev->iobase + DT2814_DATA);
+ i = inb(dev->iobase + DT2814_DATA);
+
+ irq = it->options[1];
+#if 0
+ if (irq < 0) {
+ save_flags(flags);
+ sti();
+ irqs = probe_irq_on();
+
+ outb(0, dev->iobase + DT2814_CSR);
+
+ comedi_udelay(100);
+
+ irq = probe_irq_off(irqs);
+ restore_flags(flags);
+ if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) {
+ printk("error probing irq (bad) \n");
+ }
+
+ i = inb(dev->iobase + DT2814_DATA);
+ i = inb(dev->iobase + DT2814_DATA);
+ }
+#endif
+ dev->irq = 0;
+ if (irq > 0) {
+ if (comedi_request_irq(irq, dt2814_interrupt, 0, "dt2814", dev)) {
+ printk("(irq %d unavailable)\n", irq);
+ } else {
+ printk("( irq = %d )\n", irq);
+ dev->irq = irq;
+ }
+ } else if (irq == 0) {
+ printk("(no irq)\n");
+ } else {
+#if 0
+ printk("(probe returned multiple irqs--bad)\n");
+#else
+ printk("(irq probe not implemented)\n");
+#endif
+ }
+
+ if ((ret = alloc_subdevices(dev, 1)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct dt2814_private))) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
+ s->n_chan = 16; /* XXX */
+ s->len_chanlist = 1;
+ s->insn_read = dt2814_ai_insn_read;
+ s->do_cmd = dt2814_ai_cmd;
+ s->do_cmdtest = dt2814_ai_cmdtest;
+ s->maxdata = 0xfff;
+ s->range_table = &range_unknown; /* XXX */
+
+ return 0;
+}
+
+static int dt2814_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: dt2814: remove\n", dev->minor);
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (dev->iobase) {
+ release_region(dev->iobase, DT2814_SIZE);
+ }
+
+ return 0;
+}
+
+static irqreturn_t dt2814_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ int lo, hi;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s;
+ int data;
+
+ if (!dev->attached) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_HANDLED;
+ }
+
+ s = dev->subdevices + 0;
+
+ hi = inb(dev->iobase + DT2814_DATA);
+ lo = inb(dev->iobase + DT2814_DATA);
+
+ data = (hi << 4) | (lo >> 4);
+
+ if (!(--devpriv->ntrig)) {
+ int i;
+
+ outb(0, dev->iobase + DT2814_CSR);
+ /* note: turning off timed mode triggers another
+ sample. */
+
+ for (i = 0; i < DT2814_TIMEOUT; i++) {
+ if (inb(dev->iobase + DT2814_CSR) & DT2814_FINISH)
+ break;
+ }
+ inb(dev->iobase + DT2814_DATA);
+ inb(dev->iobase + DT2814_DATA);
+
+ s->async->events |= COMEDI_CB_EOA;
+ }
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c
new file mode 100644
index 00000000000..fccec8a77d5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2815.c
@@ -0,0 +1,264 @@
+/*
+ comedi/drivers/dt2815.c
+ Hardware driver for Data Translation DT2815
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ 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.
+
+ */
+/*
+Driver: dt2815
+Description: Data Translation DT2815
+Author: ds
+Status: mostly complete, untested
+Devices: [Data Translation] DT2815 (dt2815)
+
+I'm not sure anyone has ever tested this board. If you have information
+contrary, please update.
+
+Configuration options:
+ [0] - I/O port base base address
+ [1] - IRQ (unused)
+ [2] - Voltage unipolar/bipolar configuration
+ 0 == unipolar 5V (0V -- +5V)
+ 1 == bipolar 5V (-5V -- +5V)
+ [3] - Current offset configuration
+ 0 == disabled (0mA -- +32mAV)
+ 1 == enabled (+4mA -- +20mAV)
+ [4] - Firmware program configuration
+ 0 == program 1 (see manual table 5-4)
+ 1 == program 2 (see manual table 5-4)
+ 2 == program 3 (see manual table 5-4)
+ 3 == program 4 (see manual table 5-4)
+ [5] - Analog output 0 range configuration
+ 0 == voltage
+ 1 == current
+ [6] - Analog output 1 range configuration (same options)
+ [7] - Analog output 2 range configuration (same options)
+ [8] - Analog output 3 range configuration (same options)
+ [9] - Analog output 4 range configuration (same options)
+ [10] - Analog output 5 range configuration (same options)
+ [11] - Analog output 6 range configuration (same options)
+ [12] - Analog output 7 range configuration (same options)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+static const struct comedi_lrange range_dt2815_ao_32_current = { 1, {
+ RANGE_mA(0, 32)
+ }
+};
+static const struct comedi_lrange range_dt2815_ao_20_current = { 1, {
+ RANGE_mA(4, 20)
+ }
+};
+
+#define DT2815_SIZE 2
+
+#define DT2815_DATA 0
+#define DT2815_STATUS 1
+
+static int dt2815_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2815_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2815 = {
+ driver_name:"dt2815",
+ module:THIS_MODULE,
+ attach:dt2815_attach,
+ detach:dt2815_detach,
+};
+
+COMEDI_INITCLEANUP(driver_dt2815);
+
+static void dt2815_free_resources(struct comedi_device * dev);
+
+struct dt2815_private {
+
+ const struct comedi_lrange *range_type_list[8];
+ unsigned int ao_readback[8];
+};
+
+
+#define devpriv ((struct dt2815_private *)dev->private)
+
+static int dt2815_wait_for_status(struct comedi_device * dev, int status)
+{
+ int i;
+
+ for (i = 0; i < 100; i++) {
+ if (inb(dev->iobase + DT2815_STATUS) == status)
+ break;
+ }
+ return status;
+}
+
+static int dt2815_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+static int dt2815_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned int status;
+ unsigned int lo, hi;
+
+ for (i = 0; i < insn->n; i++) {
+ lo = ((data[i] & 0x0f) << 4) | (chan << 1) | 0x01;
+ hi = (data[i] & 0xff0) >> 4;
+
+ status = dt2815_wait_for_status(dev, 0x00);
+ if (status != 0) {
+ rt_printk
+ ("dt2815: failed to write low byte on %d reason %x\n",
+ chan, status);
+ return -EBUSY;
+ }
+
+ outb(lo, dev->iobase + DT2815_DATA);
+
+ status = dt2815_wait_for_status(dev, 0x10);
+ if (status != 0x10) {
+ rt_printk
+ ("dt2815: failed to write high byte on %d reason %x\n",
+ chan, status);
+ return -EBUSY;
+ }
+ devpriv->ao_readback[chan] = data[i];
+ }
+ return i;
+}
+
+/*
+ options[0] Board base address
+ options[1] IRQ (not applicable)
+ options[2] Voltage unipolar/bipolar configuration
+ 0 == unipolar 5V (0V -- +5V)
+ 1 == bipolar 5V (-5V -- +5V)
+ options[3] Current offset configuration
+ 0 == disabled (0mA -- +32mAV)
+ 1 == enabled (+4mA -- +20mAV)
+ options[4] Firmware program configuration
+ 0 == program 1 (see manual table 5-4)
+ 1 == program 2 (see manual table 5-4)
+ 2 == program 3 (see manual table 5-4)
+ 3 == program 4 (see manual table 5-4)
+ options[5] Analog output 0 range configuration
+ 0 == voltage
+ 1 == current
+ options[6] Analog output 1 range configuration
+ ...
+ options[12] Analog output 7 range configuration
+ 0 == voltage
+ 1 == current
+ */
+
+static int dt2815_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int i;
+ const struct comedi_lrange *current_range_type, *voltage_range_type;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: dt2815: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, DT2815_SIZE, "dt2815")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+ dev->board_name = "dt2815";
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+ if (alloc_private(dev, sizeof(struct dt2815_private)) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices;
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 0xfff;
+ s->n_chan = 8;
+ s->insn_write = dt2815_ao_insn;
+ s->insn_read = dt2815_ao_insn_read;
+ s->range_table_list = devpriv->range_type_list;
+
+ current_range_type = (it->options[3])
+ ? &range_dt2815_ao_20_current : &range_dt2815_ao_32_current;
+ voltage_range_type = (it->options[2])
+ ? &range_bipolar5 : &range_unipolar5;
+ for (i = 0; i < 8; i++) {
+ devpriv->range_type_list[i] = (it->options[5 + i])
+ ? current_range_type : voltage_range_type;
+ }
+
+ /* Init the 2815 */
+ outb(0x00, dev->iobase + DT2815_STATUS);
+ for (i = 0; i < 100; i++) {
+ /* This is incredibly slow (approx 20 ms) */
+ unsigned int status;
+
+ comedi_udelay(1000);
+ status = inb(dev->iobase + DT2815_STATUS);
+ if (status == 4) {
+ unsigned int program;
+ program = (it->options[4] & 0x3) << 3 | 0x7;
+ outb(program, dev->iobase + DT2815_DATA);
+ printk(", program: 0x%x (@t=%d)\n", program, i);
+ break;
+ } else if (status != 0x00) {
+ printk("dt2815: unexpected status 0x%x (@t=%d)\n",
+ status, i);
+ if (status & 0x60) {
+ outb(0x00, dev->iobase + DT2815_STATUS);
+ }
+ }
+ }
+
+ printk("\n");
+
+ return 0;
+}
+
+static void dt2815_free_resources(struct comedi_device * dev)
+{
+ if (dev->iobase)
+ release_region(dev->iobase, DT2815_SIZE);
+}
+
+static int dt2815_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: dt2815: remove\n", dev->minor);
+
+ dt2815_free_resources(dev);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c
new file mode 100644
index 00000000000..2dc396a44e6
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2817.c
@@ -0,0 +1,178 @@
+/*
+ comedi/drivers/dt2817.c
+ Hardware driver for Data Translation DT2817
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: dt2817
+Description: Data Translation DT2817
+Author: ds
+Status: complete
+Devices: [Data Translation] DT2817 (dt2817)
+
+A very simple digital I/O card. Four banks of 8 lines, each bank
+is configurable for input or output. One wonders why it takes a
+50 page manual to describe this thing.
+
+The driver (which, btw, is much less than 50 pages) has 1 subdevice
+with 32 channels, configurable in groups of 8.
+
+Configuration options:
+ [0] - I/O port base base address
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define DT2817_SIZE 5
+
+#define DT2817_CR 0
+#define DT2817_DATA 1
+
+static int dt2817_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2817_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2817 = {
+ driver_name:"dt2817",
+ module:THIS_MODULE,
+ attach:dt2817_attach,
+ detach:dt2817_detach,
+};
+
+COMEDI_INITCLEANUP(driver_dt2817);
+
+static int dt2817_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int mask;
+ int chan;
+ int oe = 0;
+
+ if (insn->n != 1)
+ return -EINVAL;
+
+ chan = CR_CHAN(insn->chanspec);
+ if (chan < 8) {
+ mask = 0xff;
+ } else if (chan < 16) {
+ mask = 0xff00;
+ } else if (chan < 24) {
+ mask = 0xff0000;
+ } else
+ mask = 0xff000000;
+ if (data[0])
+ s->io_bits |= mask;
+ else
+ s->io_bits &= ~mask;
+
+ if (s->io_bits & 0x000000ff)
+ oe |= 0x1;
+ if (s->io_bits & 0x0000ff00)
+ oe |= 0x2;
+ if (s->io_bits & 0x00ff0000)
+ oe |= 0x4;
+ if (s->io_bits & 0xff000000)
+ oe |= 0x8;
+
+ outb(oe, dev->iobase + DT2817_CR);
+
+ return 1;
+}
+
+static int dt2817_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int changed;
+
+ /* It's questionable whether it is more important in
+ * a driver like this to be deterministic or fast.
+ * We choose fast. */
+
+ if (data[0]) {
+ changed = s->state;
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ changed ^= s->state;
+ changed &= s->io_bits;
+ if (changed & 0x000000ff)
+ outb(s->state & 0xff, dev->iobase + DT2817_DATA + 0);
+ if (changed & 0x0000ff00)
+ outb((s->state >> 8) & 0xff,
+ dev->iobase + DT2817_DATA + 1);
+ if (changed & 0x00ff0000)
+ outb((s->state >> 16) & 0xff,
+ dev->iobase + DT2817_DATA + 2);
+ if (changed & 0xff000000)
+ outb((s->state >> 24) & 0xff,
+ dev->iobase + DT2817_DATA + 3);
+ }
+ data[1] = inb(dev->iobase + DT2817_DATA + 0);
+ data[1] |= (inb(dev->iobase + DT2817_DATA + 1) << 8);
+ data[1] |= (inb(dev->iobase + DT2817_DATA + 2) << 16);
+ data[1] |= (inb(dev->iobase + DT2817_DATA + 3) << 24);
+
+ return 2;
+}
+
+static int dt2817_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: dt2817: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, DT2817_SIZE, "dt2817")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+ dev->board_name = "dt2817";
+
+ if ((ret = alloc_subdevices(dev, 1)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+
+ s->n_chan = 32;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_bits = dt2817_dio_insn_bits;
+ s->insn_config = dt2817_dio_insn_config;
+
+ s->state = 0;
+ outb(0, dev->iobase + DT2817_CR);
+
+ printk("\n");
+
+ return 0;
+}
+
+static int dt2817_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: dt2817: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, DT2817_SIZE);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
new file mode 100644
index 00000000000..4882c3e679c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -0,0 +1,1471 @@
+/*
+ comedi/drivers/dt282x.c
+ Hardware driver for Data Translation DT2821 series
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: dt282x
+Description: Data Translation DT2821 series (including DT-EZ)
+Author: ds
+Devices: [Data Translation] DT2821 (dt2821),
+ DT2821-F-16SE (dt2821-f), DT2821-F-8DI (dt2821-f),
+ DT2821-G-16SE (dt2821-f), DT2821-G-8DI (dt2821-g),
+ DT2823 (dt2823),
+ DT2824-PGH (dt2824-pgh), DT2824-PGL (dt2824-pgl), DT2825 (dt2825),
+ DT2827 (dt2827), DT2828 (dt2828), DT21-EZ (dt21-ez), DT23-EZ (dt23-ez),
+ DT24-EZ (dt24-ez), DT24-EZ-PGL (dt24-ez-pgl)
+Status: complete
+Updated: Wed, 22 Aug 2001 17:11:34 -0700
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ
+ [2] - DMA 1
+ [3] - DMA 2
+ [4] - AI jumpered for 0=single ended, 1=differential
+ [5] - AI jumpered for 0=straight binary, 1=2's complement
+ [6] - AO 0 jumpered for 0=straight binary, 1=2's complement
+ [7] - AO 1 jumpered for 0=straight binary, 1=2's complement
+ [8] - AI jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5]
+ [9] - AO 0 jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5],
+ 4=[-2.5,2.5]
+ [10]- A0 1 jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5],
+ 4=[-2.5,2.5]
+
+Notes:
+ - AO commands might be broken.
+ - If you try to run a command on both the AI and AO subdevices
+ simultaneously, bad things will happen. The driver needs to
+ be fixed to check for this situation and return an error.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <asm/dma.h>
+#include "comedi_fc.h"
+
+#define DEBUG
+
+#define DT2821_TIMEOUT 100 /* 500 us */
+#define DT2821_SIZE 0x10
+
+/*
+ * Registers in the DT282x
+ */
+
+#define DT2821_ADCSR 0x00 /* A/D Control/Status */
+#define DT2821_CHANCSR 0x02 /* Channel Control/Status */
+#define DT2821_ADDAT 0x04 /* A/D data */
+#define DT2821_DACSR 0x06 /* D/A Control/Status */
+#define DT2821_DADAT 0x08 /* D/A data */
+#define DT2821_DIODAT 0x0a /* digital data */
+#define DT2821_SUPCSR 0x0c /* Supervisor Control/Status */
+#define DT2821_TMRCTR 0x0e /* Timer/Counter */
+
+/*
+ * At power up, some registers are in a well-known state. The
+ * masks and values are as follows:
+ */
+
+#define DT2821_ADCSR_MASK 0xfff0
+#define DT2821_ADCSR_VAL 0x7c00
+
+#define DT2821_CHANCSR_MASK 0xf0f0
+#define DT2821_CHANCSR_VAL 0x70f0
+
+#define DT2821_DACSR_MASK 0x7c93
+#define DT2821_DACSR_VAL 0x7c90
+
+#define DT2821_SUPCSR_MASK 0xf8ff
+#define DT2821_SUPCSR_VAL 0x0000
+
+#define DT2821_TMRCTR_MASK 0xff00
+#define DT2821_TMRCTR_VAL 0xf000
+
+/*
+ * Bit fields of each register
+ */
+
+/* ADCSR */
+
+#define DT2821_ADERR 0x8000 /* (R) 1 for A/D error */
+#define DT2821_ADCLK 0x0200 /* (R/W) A/D clock enable */
+ /* 0x7c00 read as 1's */
+#define DT2821_MUXBUSY 0x0100 /* (R) multiplexer busy */
+#define DT2821_ADDONE 0x0080 /* (R) A/D done */
+#define DT2821_IADDONE 0x0040 /* (R/W) interrupt on A/D done */
+ /* 0x0030 gain select */
+ /* 0x000f channel select */
+
+/* CHANCSR */
+
+#define DT2821_LLE 0x8000 /* (R/W) Load List Enable */
+ /* 0x7000 read as 1's */
+ /* 0x0f00 (R) present address */
+ /* 0x00f0 read as 1's */
+ /* 0x000f (R) number of entries - 1 */
+
+/* DACSR */
+
+#define DT2821_DAERR 0x8000 /* (R) D/A error */
+#define DT2821_YSEL 0x0200 /* (R/W) DAC 1 select */
+#define DT2821_SSEL 0x0100 /* (R/W) single channel select */
+#define DT2821_DACRDY 0x0080 /* (R) DAC ready */
+#define DT2821_IDARDY 0x0040 /* (R/W) interrupt on DAC ready */
+#define DT2821_DACLK 0x0020 /* (R/W) D/A clock enable */
+#define DT2821_HBOE 0x0002 /* (R/W) DIO high byte output enable */
+#define DT2821_LBOE 0x0001 /* (R/W) DIO low byte output enable */
+
+/* SUPCSR */
+
+#define DT2821_DMAD 0x8000 /* (R) DMA done */
+#define DT2821_ERRINTEN 0x4000 /* (R/W) interrupt on error */
+#define DT2821_CLRDMADNE 0x2000 /* (W) clear DMA done */
+#define DT2821_DDMA 0x1000 /* (R/W) dual DMA */
+#define DT2821_DS1 0x0800 /* (R/W) DMA select 1 */
+#define DT2821_DS0 0x0400 /* (R/W) DMA select 0 */
+#define DT2821_BUFFB 0x0200 /* (R/W) buffer B selected */
+#define DT2821_SCDN 0x0100 /* (R) scan done */
+#define DT2821_DACON 0x0080 /* (W) DAC single conversion */
+#define DT2821_ADCINIT 0x0040 /* (W) A/D initialize */
+#define DT2821_DACINIT 0x0020 /* (W) D/A initialize */
+#define DT2821_PRLD 0x0010 /* (W) preload multiplexer */
+#define DT2821_STRIG 0x0008 /* (W) software trigger */
+#define DT2821_XTRIG 0x0004 /* (R/W) external trigger enable */
+#define DT2821_XCLK 0x0002 /* (R/W) external clock enable */
+#define DT2821_BDINIT 0x0001 /* (W) initialize board */
+
+static const struct comedi_lrange range_dt282x_ai_lo_bipolar = { 4, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25)
+ }
+};
+static const struct comedi_lrange range_dt282x_ai_lo_unipolar = { 4, {
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 2.5),
+ RANGE(0, 1.25)
+ }
+};
+static const struct comedi_lrange range_dt282x_ai_5_bipolar = { 4, {
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ RANGE(-0.625, 0.625),
+ }
+};
+static const struct comedi_lrange range_dt282x_ai_5_unipolar = { 4, {
+ RANGE(0, 5),
+ RANGE(0, 2.5),
+ RANGE(0, 1.25),
+ RANGE(0, 0.625),
+ }
+};
+static const struct comedi_lrange range_dt282x_ai_hi_bipolar = { 4, {
+ RANGE(-10, 10),
+ RANGE(-1, 1),
+ RANGE(-0.1, 0.1),
+ RANGE(-0.02, 0.02)
+ }
+};
+static const struct comedi_lrange range_dt282x_ai_hi_unipolar = { 4, {
+ RANGE(0, 10),
+ RANGE(0, 1),
+ RANGE(0, 0.1),
+ RANGE(0, 0.02)
+ }
+};
+
+struct dt282x_board {
+ const char *name;
+ int adbits;
+ int adchan_se;
+ int adchan_di;
+ int ai_speed;
+ int ispgl;
+ int dachan;
+ int dabits;
+};
+
+static const struct dt282x_board boardtypes[] = {
+ {name:"dt2821",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:20000,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt2821-f",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:6500,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt2821-g",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:4000,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt2823",
+ adbits: 16,
+ adchan_se:0,
+ adchan_di:4,
+ ai_speed:10000,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 16,
+ },
+ {name:"dt2824-pgh",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:20000,
+ ispgl: 0,
+ dachan: 0,
+ dabits: 0,
+ },
+ {name:"dt2824-pgl",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:20000,
+ ispgl: 1,
+ dachan: 0,
+ dabits: 0,
+ },
+ {name:"dt2825",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:20000,
+ ispgl: 1,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt2827",
+ adbits: 16,
+ adchan_se:0,
+ adchan_di:4,
+ ai_speed:10000,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt2828",
+ adbits: 12,
+ adchan_se:4,
+ adchan_di:0,
+ ai_speed:10000,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt2829",
+ adbits: 16,
+ adchan_se:8,
+ adchan_di:0,
+ ai_speed:33250,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 16,
+ },
+ {name:"dt21-ez",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:10000,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt23-ez",
+ adbits: 16,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:10000,
+ ispgl: 0,
+ dachan: 0,
+ dabits: 0,
+ },
+ {name:"dt24-ez",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:10000,
+ ispgl: 0,
+ dachan: 0,
+ dabits: 0,
+ },
+ {name:"dt24-ez-pgl",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:10000,
+ ispgl: 1,
+ dachan: 0,
+ dabits: 0,
+ },
+};
+
+#define n_boardtypes sizeof(boardtypes)/sizeof(struct dt282x_board)
+#define this_board ((const struct dt282x_board *)dev->board_ptr)
+
+struct dt282x_private {
+ int ad_2scomp; /* we have 2's comp jumper set */
+ int da0_2scomp; /* same, for DAC0 */
+ int da1_2scomp; /* same, for DAC1 */
+
+ const struct comedi_lrange *darangelist[2];
+
+ short ao[2];
+
+ volatile int dacsr; /* software copies of registers */
+ volatile int adcsr;
+ volatile int supcsr;
+
+ volatile int ntrig;
+ volatile int nread;
+
+ struct {
+ int chan;
+ short *buf; /* DMA buffer */
+ volatile int size; /* size of current transfer */
+ } dma[2];
+ int dma_maxsize; /* max size of DMA transfer (in bytes) */
+ int usedma; /* driver uses DMA */
+ volatile int current_dma_index;
+ int dma_dir;
+};
+
+#define devpriv ((struct dt282x_private *)dev->private)
+#define boardtype (*(const struct dt282x_board *)dev->board_ptr)
+
+/*
+ * Some useless abstractions
+ */
+#define chan_to_DAC(a) ((a)&1)
+#define update_dacsr(a) outw(devpriv->dacsr|(a),dev->iobase+DT2821_DACSR)
+#define update_adcsr(a) outw(devpriv->adcsr|(a),dev->iobase+DT2821_ADCSR)
+#define mux_busy() (inw(dev->iobase+DT2821_ADCSR)&DT2821_MUXBUSY)
+#define ad_done() (inw(dev->iobase+DT2821_ADCSR)&DT2821_ADDONE)
+#define update_supcsr(a) outw(devpriv->supcsr|(a),dev->iobase+DT2821_SUPCSR)
+
+/*
+ * danger! macro abuse... a is the expression to wait on, and b is
+ * the statement(s) to execute if it doesn't happen.
+ */
+#define wait_for(a,b) \
+ do{ \
+ int _i; \
+ for(_i=0;_i<DT2821_TIMEOUT;_i++){ \
+ if(a){_i=0;break;} \
+ comedi_udelay(5); \
+ } \
+ if(_i){b} \
+ }while(0)
+
+static int dt282x_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt282x_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt282x = {
+ driver_name:"dt282x",
+ module:THIS_MODULE,
+ attach:dt282x_attach,
+ detach:dt282x_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct dt282x_board),
+};
+
+COMEDI_INITCLEANUP(driver_dt282x);
+
+static void free_resources(struct comedi_device * dev);
+static int prep_ai_dma(struct comedi_device * dev, int chan, int size);
+static int prep_ao_dma(struct comedi_device * dev, int chan, int size);
+static int dt282x_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dt282x_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dt282x_ns_to_timer(int *nanosec, int round_mode);
+static void dt282x_disable_dma(struct comedi_device * dev);
+
+static int dt282x_grab_dma(struct comedi_device * dev, int dma1, int dma2);
+
+static void dt282x_munge(struct comedi_device * dev, short * buf,
+ unsigned int nbytes)
+{
+ unsigned int i;
+ unsigned short mask = (1 << boardtype.adbits) - 1;
+ unsigned short sign = 1 << (boardtype.adbits - 1);
+ int n;
+
+ if (devpriv->ad_2scomp) {
+ sign = 1 << (boardtype.adbits - 1);
+ } else {
+ sign = 0;
+ }
+
+ if (nbytes % 2)
+ comedi_error(dev, "bug! odd number of bytes from dma xfer");
+ n = nbytes / 2;
+ for (i = 0; i < n; i++) {
+ buf[i] = (buf[i] & mask) ^ sign;
+ }
+}
+
+static void dt282x_ao_dma_interrupt(struct comedi_device * dev)
+{
+ void *ptr;
+ int size;
+ int i;
+ struct comedi_subdevice *s = dev->subdevices + 1;
+
+ update_supcsr(DT2821_CLRDMADNE);
+
+ if (!s->async->prealloc_buf) {
+ printk("async->data disappeared. dang!\n");
+ return;
+ }
+
+ i = devpriv->current_dma_index;
+ ptr = devpriv->dma[i].buf;
+
+ disable_dma(devpriv->dma[i].chan);
+
+ devpriv->current_dma_index = 1 - i;
+
+ size = cfc_read_array_from_buffer(s, ptr, devpriv->dma_maxsize);
+ if (size == 0) {
+ rt_printk("dt282x: AO underrun\n");
+ dt282x_ao_cancel(dev, s);
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ return;
+ }
+ prep_ao_dma(dev, i, size);
+ return;
+}
+
+static void dt282x_ai_dma_interrupt(struct comedi_device * dev)
+{
+ void *ptr;
+ int size;
+ int i;
+ int ret;
+ struct comedi_subdevice *s = dev->subdevices;
+
+ update_supcsr(DT2821_CLRDMADNE);
+
+ if (!s->async->prealloc_buf) {
+ printk("async->data disappeared. dang!\n");
+ return;
+ }
+
+ i = devpriv->current_dma_index;
+ ptr = devpriv->dma[i].buf;
+ size = devpriv->dma[i].size;
+
+ disable_dma(devpriv->dma[i].chan);
+
+ devpriv->current_dma_index = 1 - i;
+
+ dt282x_munge(dev, ptr, size);
+ ret = cfc_write_array_to_buffer(s, ptr, size);
+ if (ret != size) {
+ dt282x_ai_cancel(dev, s);
+ return;
+ }
+ devpriv->nread -= size / 2;
+
+ if (devpriv->nread < 0) {
+ printk("dt282x: off by one\n");
+ devpriv->nread = 0;
+ }
+ if (!devpriv->nread) {
+ dt282x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ return;
+ }
+#if 0
+ /* clear the dual dma flag, making this the last dma segment */
+ /* XXX probably wrong */
+ if (!devpriv->ntrig) {
+ devpriv->supcsr &= ~(DT2821_DDMA);
+ update_supcsr(0);
+ }
+#endif
+ /* restart the channel */
+ prep_ai_dma(dev, i, 0);
+}
+
+static int prep_ai_dma(struct comedi_device * dev, int dma_index, int n)
+{
+ int dma_chan;
+ unsigned long dma_ptr;
+ unsigned long flags;
+
+ if (!devpriv->ntrig)
+ return 0;
+
+ if (n == 0)
+ n = devpriv->dma_maxsize;
+ if (n > devpriv->ntrig * 2)
+ n = devpriv->ntrig * 2;
+ devpriv->ntrig -= n / 2;
+
+ devpriv->dma[dma_index].size = n;
+ dma_chan = devpriv->dma[dma_index].chan;
+ dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
+
+ set_dma_mode(dma_chan, DMA_MODE_READ);
+ flags = claim_dma_lock();
+ clear_dma_ff(dma_chan);
+ set_dma_addr(dma_chan, dma_ptr);
+ set_dma_count(dma_chan, n);
+ release_dma_lock(flags);
+
+ enable_dma(dma_chan);
+
+ return n;
+}
+
+static int prep_ao_dma(struct comedi_device * dev, int dma_index, int n)
+{
+ int dma_chan;
+ unsigned long dma_ptr;
+ unsigned long flags;
+
+ devpriv->dma[dma_index].size = n;
+ dma_chan = devpriv->dma[dma_index].chan;
+ dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
+
+ set_dma_mode(dma_chan, DMA_MODE_WRITE);
+ flags = claim_dma_lock();
+ clear_dma_ff(dma_chan);
+ set_dma_addr(dma_chan, dma_ptr);
+ set_dma_count(dma_chan, n);
+ release_dma_lock(flags);
+
+ enable_dma(dma_chan);
+
+ return n;
+}
+
+static irqreturn_t dt282x_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s;
+ struct comedi_subdevice *s_ao;
+ unsigned int supcsr, adcsr, dacsr;
+ int handled = 0;
+
+ if (!dev->attached) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_HANDLED;
+ }
+
+ s = dev->subdevices + 0;
+ s_ao = dev->subdevices + 1;
+ adcsr = inw(dev->iobase + DT2821_ADCSR);
+ dacsr = inw(dev->iobase + DT2821_DACSR);
+ supcsr = inw(dev->iobase + DT2821_SUPCSR);
+ if (supcsr & DT2821_DMAD) {
+ if (devpriv->dma_dir == DMA_MODE_READ)
+ dt282x_ai_dma_interrupt(dev);
+ else
+ dt282x_ao_dma_interrupt(dev);
+ handled = 1;
+ }
+ if (adcsr & DT2821_ADERR) {
+ if (devpriv->nread != 0) {
+ comedi_error(dev, "A/D error");
+ dt282x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_ERROR;
+ }
+ handled = 1;
+ }
+ if (dacsr & DT2821_DAERR) {
+#if 0
+ static int warn = 5;
+ if (--warn <= 0) {
+ disable_irq(dev->irq);
+ printk("disabling irq\n");
+ }
+#endif
+ comedi_error(dev, "D/A error");
+ dt282x_ao_cancel(dev, s_ao);
+ s->async->events |= COMEDI_CB_ERROR;
+ handled = 1;
+ }
+#if 0
+ if (adcsr & DT2821_ADDONE) {
+ int ret;
+ short data;
+
+ data = (short) inw(dev->iobase + DT2821_ADDAT);
+ data &= (1 << boardtype.adbits) - 1;
+ if (devpriv->ad_2scomp) {
+ data ^= 1 << (boardtype.adbits - 1);
+ }
+ ret = comedi_buf_put(s->async, data);
+ if (ret == 0) {
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+
+ devpriv->nread--;
+ if (!devpriv->nread) {
+ s->async->events |= COMEDI_CB_EOA;
+ } else {
+ if (supcsr & DT2821_SCDN)
+ update_supcsr(DT2821_STRIG);
+ }
+ handled = 1;
+ }
+#endif
+ comedi_event(dev, s);
+ /* printk("adcsr=0x%02x dacsr-0x%02x supcsr=0x%02x\n", adcsr, dacsr, supcsr); */
+ return IRQ_RETVAL(handled);
+}
+
+static void dt282x_load_changain(struct comedi_device * dev, int n,
+ unsigned int *chanlist)
+{
+ unsigned int i;
+ unsigned int chan, range;
+
+ outw(DT2821_LLE | (n - 1), dev->iobase + DT2821_CHANCSR);
+ for (i = 0; i < n; i++) {
+ chan = CR_CHAN(chanlist[i]);
+ range = CR_RANGE(chanlist[i]);
+ update_adcsr((range << 4) | (chan));
+ }
+ outw(n - 1, dev->iobase + DT2821_CHANCSR);
+}
+
+/*
+ * Performs a single A/D conversion.
+ * - Put channel/gain into channel-gain list
+ * - preload multiplexer
+ * - trigger conversion and wait for it to finish
+ */
+static int dt282x_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+
+ /* XXX should we really be enabling the ad clock here? */
+ devpriv->adcsr = DT2821_ADCLK;
+ update_adcsr(0);
+
+ dt282x_load_changain(dev, 1, &insn->chanspec);
+
+ update_supcsr(DT2821_PRLD);
+ wait_for(!mux_busy(), comedi_error(dev, "timeout\n");
+ return -ETIME;
+ );
+
+ for (i = 0; i < insn->n; i++) {
+ update_supcsr(DT2821_STRIG);
+ wait_for(ad_done(), comedi_error(dev, "timeout\n");
+ return -ETIME;
+ );
+
+ data[i] =
+ inw(dev->iobase +
+ DT2821_ADDAT) & ((1 << boardtype.adbits) - 1);
+ if (devpriv->ad_2scomp)
+ data[i] ^= (1 << (boardtype.adbits - 1));
+ }
+
+ return i;
+}
+
+static int dt282x_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ /* internal trigger */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* should be level/edge, hi/lo specification here */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->convert_arg < 4000) {
+ /* XXX board dependent */
+ cmd->convert_arg = 4000;
+ err++;
+ }
+#define SLOWEST_TIMER (250*(1<<15)*255)
+ if (cmd->convert_arg > SLOWEST_TIMER) {
+ cmd->convert_arg = SLOWEST_TIMER;
+ err++;
+ }
+ if (cmd->convert_arg < this_board->ai_speed) {
+ cmd->convert_arg = this_board->ai_speed;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ /* any count is allowed */
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ tmp = cmd->convert_arg;
+ dt282x_ns_to_timer(&cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int dt282x_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int timer;
+
+ if (devpriv->usedma == 0) {
+ comedi_error(dev,
+ "driver requires 2 dma channels to execute command");
+ return -EIO;
+ }
+
+ dt282x_disable_dma(dev);
+
+ if (cmd->convert_arg < this_board->ai_speed)
+ cmd->convert_arg = this_board->ai_speed;
+ timer = dt282x_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_NEAREST);
+ outw(timer, dev->iobase + DT2821_TMRCTR);
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ /* internal trigger */
+ devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS0;
+ } else {
+ /* external trigger */
+ devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS0 | DT2821_DS1;
+ }
+ update_supcsr(DT2821_CLRDMADNE | DT2821_BUFFB | DT2821_ADCINIT);
+
+ devpriv->ntrig = cmd->stop_arg * cmd->scan_end_arg;
+ devpriv->nread = devpriv->ntrig;
+
+ devpriv->dma_dir = DMA_MODE_READ;
+ devpriv->current_dma_index = 0;
+ prep_ai_dma(dev, 0, 0);
+ if (devpriv->ntrig) {
+ prep_ai_dma(dev, 1, 0);
+ devpriv->supcsr |= DT2821_DDMA;
+ update_supcsr(0);
+ }
+
+ devpriv->adcsr = 0;
+
+ dt282x_load_changain(dev, cmd->chanlist_len, cmd->chanlist);
+
+ devpriv->adcsr = DT2821_ADCLK | DT2821_IADDONE;
+ update_adcsr(0);
+
+ update_supcsr(DT2821_PRLD);
+ wait_for(!mux_busy(), comedi_error(dev, "timeout\n");
+ return -ETIME;
+ );
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ update_supcsr(DT2821_STRIG);
+ } else {
+ devpriv->supcsr |= DT2821_XTRIG;
+ update_supcsr(0);
+ }
+
+ return 0;
+}
+
+static void dt282x_disable_dma(struct comedi_device * dev)
+{
+ if (devpriv->usedma) {
+ disable_dma(devpriv->dma[0].chan);
+ disable_dma(devpriv->dma[1].chan);
+ }
+}
+
+static int dt282x_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ dt282x_disable_dma(dev);
+
+ devpriv->adcsr = 0;
+ update_adcsr(0);
+
+ devpriv->supcsr = 0;
+ update_supcsr(DT2821_ADCINIT);
+
+ return 0;
+}
+
+static int dt282x_ns_to_timer(int *nanosec, int round_mode)
+{
+ int prescale, base, divider;
+
+ for (prescale = 0; prescale < 16; prescale++) {
+ if (prescale == 1)
+ continue;
+ base = 250 * (1 << prescale);
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ divider = (*nanosec + base / 2) / base;
+ break;
+ case TRIG_ROUND_DOWN:
+ divider = (*nanosec) / base;
+ break;
+ case TRIG_ROUND_UP:
+ divider = (*nanosec + base - 1) / base;
+ break;
+ }
+ if (divider < 256) {
+ *nanosec = divider * base;
+ return (prescale << 8) | (255 - divider);
+ }
+ }
+ base = 250 * (1 << 15);
+ divider = 255;
+ *nanosec = divider * base;
+ return (15 << 8) | (255 - divider);
+}
+
+/*
+ * Analog output routine. Selects single channel conversion,
+ * selects correct channel, converts from 2's compliment to
+ * offset binary if necessary, loads the data into the DAC
+ * data register, and performs the conversion.
+ */
+static int dt282x_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int dt282x_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ short d;
+ unsigned int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ d = data[0];
+ d &= (1 << boardtype.dabits) - 1;
+ devpriv->ao[chan] = d;
+
+ devpriv->dacsr |= DT2821_SSEL;
+
+ if (chan) {
+ /* select channel */
+ devpriv->dacsr |= DT2821_YSEL;
+ if (devpriv->da0_2scomp)
+ d ^= (1 << (boardtype.dabits - 1));
+ } else {
+ devpriv->dacsr &= ~DT2821_YSEL;
+ if (devpriv->da1_2scomp)
+ d ^= (1 << (boardtype.dabits - 1));
+ }
+
+ update_dacsr(0);
+
+ outw(d, dev->iobase + DT2821_DADAT);
+
+ update_supcsr(DT2821_DACON);
+
+ return 1;
+}
+
+static int dt282x_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_INT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg < 5000 /* XXX unknown */ ) {
+ cmd->scan_begin_arg = 5000;
+ err++;
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ if (cmd->scan_end_arg > 2) {
+ /* XXX chanlist stuff? */
+ cmd->scan_end_arg = 2;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ /* any count is allowed */
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ tmp = cmd->scan_begin_arg;
+ dt282x_ns_to_timer(&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+
+ if (err)
+ return 4;
+
+ return 0;
+
+}
+
+static int dt282x_ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int x)
+{
+ int size;
+
+ if (x != 0)
+ return -EINVAL;
+
+ size = cfc_read_array_from_buffer(s, devpriv->dma[0].buf,
+ devpriv->dma_maxsize);
+ if (size == 0) {
+ rt_printk("dt282x: AO underrun\n");
+ return -EPIPE;
+ }
+ prep_ao_dma(dev, 0, size);
+
+ size = cfc_read_array_from_buffer(s, devpriv->dma[1].buf,
+ devpriv->dma_maxsize);
+ if (size == 0) {
+ rt_printk("dt282x: AO underrun\n");
+ return -EPIPE;
+ }
+ prep_ao_dma(dev, 1, size);
+
+ update_supcsr(DT2821_STRIG);
+ s->async->inttrig = NULL;
+
+ return 1;
+}
+
+static int dt282x_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int timer;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (devpriv->usedma == 0) {
+ comedi_error(dev,
+ "driver requires 2 dma channels to execute command");
+ return -EIO;
+ }
+
+ dt282x_disable_dma(dev);
+
+ devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS1 | DT2821_DDMA;
+ update_supcsr(DT2821_CLRDMADNE | DT2821_BUFFB | DT2821_DACINIT);
+
+ devpriv->ntrig = cmd->stop_arg * cmd->chanlist_len;
+ devpriv->nread = devpriv->ntrig;
+
+ devpriv->dma_dir = DMA_MODE_WRITE;
+ devpriv->current_dma_index = 0;
+
+ timer = dt282x_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_NEAREST);
+ outw(timer, dev->iobase + DT2821_TMRCTR);
+
+ devpriv->dacsr = DT2821_SSEL | DT2821_DACLK | DT2821_IDARDY;
+ update_dacsr(0);
+
+ s->async->inttrig = dt282x_ao_inttrig;
+
+ return 0;
+}
+
+static int dt282x_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ dt282x_disable_dma(dev);
+
+ devpriv->dacsr = 0;
+ update_dacsr(0);
+
+ devpriv->supcsr = 0;
+ update_supcsr(DT2821_DACINIT);
+
+ return 0;
+}
+
+static int dt282x_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+
+ outw(s->state, dev->iobase + DT2821_DIODAT);
+ }
+ data[1] = inw(dev->iobase + DT2821_DIODAT);
+
+ return 2;
+}
+
+static int dt282x_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int mask;
+
+ mask = (CR_CHAN(insn->chanspec) < 8) ? 0x00ff : 0xff00;
+ if (data[0])
+ s->io_bits |= mask;
+ else
+ s->io_bits &= ~mask;
+
+ if (s->io_bits & 0x00ff)
+ devpriv->dacsr |= DT2821_LBOE;
+ else
+ devpriv->dacsr &= ~DT2821_LBOE;
+ if (s->io_bits & 0xff00)
+ devpriv->dacsr |= DT2821_HBOE;
+ else
+ devpriv->dacsr &= ~DT2821_HBOE;
+
+ outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
+
+ return 1;
+}
+
+static const struct comedi_lrange *const ai_range_table[] = {
+ &range_dt282x_ai_lo_bipolar,
+ &range_dt282x_ai_lo_unipolar,
+ &range_dt282x_ai_5_bipolar,
+ &range_dt282x_ai_5_unipolar
+};
+static const struct comedi_lrange *const ai_range_pgl_table[] = {
+ &range_dt282x_ai_hi_bipolar,
+ &range_dt282x_ai_hi_unipolar
+};
+static const struct comedi_lrange *opt_ai_range_lkup(int ispgl, int x)
+{
+ if (ispgl) {
+ if (x < 0 || x >= 2)
+ x = 0;
+ return ai_range_pgl_table[x];
+ } else {
+ if (x < 0 || x >= 4)
+ x = 0;
+ return ai_range_table[x];
+ }
+}
+static const struct comedi_lrange *const ao_range_table[] = {
+ &range_bipolar10,
+ &range_unipolar10,
+ &range_bipolar5,
+ &range_unipolar5,
+ &range_bipolar2_5
+};
+static const struct comedi_lrange *opt_ao_range_lkup(int x)
+{
+ if (x < 0 || x >= 5)
+ x = 0;
+ return ao_range_table[x];
+}
+
+enum { opt_iobase = 0, opt_irq, opt_dma1, opt_dma2, /* i/o base, irq, dma channels */
+ opt_diff, /* differential */
+ opt_ai_twos, opt_ao0_twos, opt_ao1_twos, /* twos comp */
+ opt_ai_range, opt_ao0_range, opt_ao1_range, /* range */
+};
+
+/*
+ options:
+ 0 i/o base
+ 1 irq
+ 2 dma1
+ 3 dma2
+ 4 0=single ended, 1=differential
+ 5 ai 0=straight binary, 1=2's comp
+ 6 ao0 0=straight binary, 1=2's comp
+ 7 ao1 0=straight binary, 1=2's comp
+ 8 ai 0=±10 V, 1=0-10 V, 2=±5 V, 3=0-5 V
+ 9 ao0 0=±10 V, 1=0-10 V, 2=±5 V, 3=0-5 V, 4=±2.5 V
+ 10 ao1 0=±10 V, 1=0-10 V, 2=±5 V, 3=0-5 V, 4=±2.5 V
+ */
+static int dt282x_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int i, irq;
+ int ret;
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ dev->board_name = this_board->name;
+
+ iobase = it->options[opt_iobase];
+ if (!iobase)
+ iobase = 0x240;
+
+ printk("comedi%d: dt282x: 0x%04lx", dev->minor, iobase);
+ if (!request_region(iobase, DT2821_SIZE, "dt282x")) {
+ printk(" I/O port conflict\n");
+ return -EBUSY;
+ }
+ dev->iobase = iobase;
+
+ outw(DT2821_BDINIT, dev->iobase + DT2821_SUPCSR);
+ i = inw(dev->iobase + DT2821_ADCSR);
+#ifdef DEBUG
+ printk(" fingerprint=%x,%x,%x,%x,%x",
+ inw(dev->iobase + DT2821_ADCSR),
+ inw(dev->iobase + DT2821_CHANCSR),
+ inw(dev->iobase + DT2821_DACSR),
+ inw(dev->iobase + DT2821_SUPCSR),
+ inw(dev->iobase + DT2821_TMRCTR));
+#endif
+
+ if (((inw(dev->iobase + DT2821_ADCSR) & DT2821_ADCSR_MASK)
+ != DT2821_ADCSR_VAL) ||
+ ((inw(dev->iobase + DT2821_CHANCSR) & DT2821_CHANCSR_MASK)
+ != DT2821_CHANCSR_VAL) ||
+ ((inw(dev->iobase + DT2821_DACSR) & DT2821_DACSR_MASK)
+ != DT2821_DACSR_VAL) ||
+ ((inw(dev->iobase + DT2821_SUPCSR) & DT2821_SUPCSR_MASK)
+ != DT2821_SUPCSR_VAL) ||
+ ((inw(dev->iobase + DT2821_TMRCTR) & DT2821_TMRCTR_MASK)
+ != DT2821_TMRCTR_VAL)) {
+ printk(" board not found");
+ return -EIO;
+ }
+ /* should do board test */
+
+ irq = it->options[opt_irq];
+#if 0
+ if (irq < 0) {
+ unsigned long flags;
+ int irqs;
+
+ save_flags(flags);
+ sti();
+ irqs = probe_irq_on();
+
+ /* trigger interrupt */
+
+ comedi_udelay(100);
+
+ irq = probe_irq_off(irqs);
+ restore_flags(flags);
+ if (0 /* error */ ) {
+ printk(" error probing irq (bad)");
+ }
+ }
+#endif
+ if (irq > 0) {
+ printk(" ( irq = %d )", irq);
+ ret = comedi_request_irq(irq, dt282x_interrupt, 0, "dt282x",
+ dev);
+ if (ret < 0) {
+ printk(" failed to get irq\n");
+ return -EIO;
+ }
+ dev->irq = irq;
+ } else if (irq == 0) {
+ printk(" (no irq)");
+ } else {
+#if 0
+ printk(" (probe returned multiple irqs--bad)");
+#else
+ printk(" (irq probe not implemented)");
+#endif
+ }
+
+ if ((ret = alloc_private(dev, sizeof(struct dt282x_private))) < 0)
+ return ret;
+
+ ret = dt282x_grab_dma(dev, it->options[opt_dma1],
+ it->options[opt_dma2]);
+ if (ret < 0)
+ return ret;
+
+ if ((ret = alloc_subdevices(dev, 3)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+
+ dev->read_subdev = s;
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ |
+ ((it->options[opt_diff]) ? SDF_DIFF : SDF_COMMON);
+ s->n_chan =
+ (it->options[opt_diff]) ? boardtype.adchan_di : boardtype.
+ adchan_se;
+ s->insn_read = dt282x_ai_insn_read;
+ s->do_cmdtest = dt282x_ai_cmdtest;
+ s->do_cmd = dt282x_ai_cmd;
+ s->cancel = dt282x_ai_cancel;
+ s->maxdata = (1 << boardtype.adbits) - 1;
+ s->len_chanlist = 16;
+ s->range_table =
+ opt_ai_range_lkup(boardtype.ispgl, it->options[opt_ai_range]);
+ devpriv->ad_2scomp = it->options[opt_ai_twos];
+
+ s++;
+ if ((s->n_chan = boardtype.dachan)) {
+ /* ao subsystem */
+ s->type = COMEDI_SUBD_AO;
+ dev->write_subdev = s;
+ s->subdev_flags = SDF_WRITABLE | SDF_CMD_WRITE;
+ s->insn_read = dt282x_ao_insn_read;
+ s->insn_write = dt282x_ao_insn_write;
+ s->do_cmdtest = dt282x_ao_cmdtest;
+ s->do_cmd = dt282x_ao_cmd;
+ s->cancel = dt282x_ao_cancel;
+ s->maxdata = (1 << boardtype.dabits) - 1;
+ s->len_chanlist = 2;
+ s->range_table_list = devpriv->darangelist;
+ devpriv->darangelist[0] =
+ opt_ao_range_lkup(it->options[opt_ao0_range]);
+ devpriv->darangelist[1] =
+ opt_ao_range_lkup(it->options[opt_ao1_range]);
+ devpriv->da0_2scomp = it->options[opt_ao0_twos];
+ devpriv->da1_2scomp = it->options[opt_ao1_twos];
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s++;
+ /* dio subsystem */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 16;
+ s->insn_bits = dt282x_dio_insn_bits;
+ s->insn_config = dt282x_dio_insn_config;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+
+ printk("\n");
+
+ return 0;
+}
+
+static void free_resources(struct comedi_device * dev)
+{
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (dev->iobase)
+ release_region(dev->iobase, DT2821_SIZE);
+ if (dev->private) {
+ if (devpriv->dma[0].chan)
+ free_dma(devpriv->dma[0].chan);
+ if (devpriv->dma[1].chan)
+ free_dma(devpriv->dma[1].chan);
+ if (devpriv->dma[0].buf)
+ free_page((unsigned long)devpriv->dma[0].buf);
+ if (devpriv->dma[1].buf)
+ free_page((unsigned long)devpriv->dma[1].buf);
+ }
+}
+
+static int dt282x_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: dt282x: remove\n", dev->minor);
+
+ free_resources(dev);
+
+ return 0;
+}
+
+static int dt282x_grab_dma(struct comedi_device * dev, int dma1, int dma2)
+{
+ int ret;
+
+ devpriv->usedma = 0;
+
+ if (!dma1 && !dma2) {
+ printk(" (no dma)");
+ return 0;
+ }
+
+ if (dma1 == dma2 || dma1 < 5 || dma2 < 5 || dma1 > 7 || dma2 > 7)
+ return -EINVAL;
+
+ if (dma2 < dma1) {
+ int i;
+ i = dma1;
+ dma1 = dma2;
+ dma2 = i;
+ }
+
+ ret = request_dma(dma1, "dt282x A");
+ if (ret)
+ return -EBUSY;
+ devpriv->dma[0].chan = dma1;
+
+ ret = request_dma(dma2, "dt282x B");
+ if (ret)
+ return -EBUSY;
+ devpriv->dma[1].chan = dma2;
+
+ devpriv->dma_maxsize = PAGE_SIZE;
+ devpriv->dma[0].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
+ devpriv->dma[1].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
+ if (!devpriv->dma[0].buf || !devpriv->dma[1].buf) {
+ printk(" can't get DMA memory");
+ return -ENOMEM;
+ }
+
+ printk(" (dma=%d,%d)", dma1, dma2);
+
+ devpriv->usedma = 1;
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
new file mode 100644
index 00000000000..d9467984706
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -0,0 +1,983 @@
+/*
+ comedi/drivers/dt3000.c
+ Data Translation DT3000 series driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: dt3000
+Description: Data Translation DT3000 series
+Author: ds
+Devices: [Data Translation] DT3001 (dt3000), DT3001-PGL, DT3002, DT3003,
+ DT3003-PGL, DT3004, DT3005, DT3004-200
+Updated: Mon, 14 Apr 2008 15:41:24 +0100
+Status: works
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+
+There is code to support AI commands, but it may not work.
+
+AO commands are not supported.
+*/
+
+/*
+ The DT3000 series is Data Translation's attempt to make a PCI
+ data acquisition board. The design of this series is very nice,
+ since each board has an on-board DSP (Texas Instruments TMS320C52).
+ However, a few details are a little annoying. The boards lack
+ bus-mastering DMA, which eliminates them from serious work.
+ They also are not capable of autocalibration, which is a common
+ feature in modern hardware. The default firmware is pretty bad,
+ making it nearly impossible to write an RT compatible driver.
+ It would make an interesting project to write a decent firmware
+ for these boards.
+
+ Data Translation originally wanted an NDA for the documentation
+ for the 3k series. However, if you ask nicely, they might send
+ you the docs without one, also.
+*/
+
+#define DEBUG 1
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+
+#define PCI_VENDOR_ID_DT 0x1116
+
+static const struct comedi_lrange range_dt3000_ai = { 4, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25)
+ }
+};
+static const struct comedi_lrange range_dt3000_ai_pgl = { 4, {
+ RANGE(-10, 10),
+ RANGE(-1, 1),
+ RANGE(-0.1, 0.1),
+ RANGE(-0.02, 0.02)
+ }
+};
+
+struct dt3k_boardtype {
+
+ const char *name;
+ unsigned int device_id;
+ int adchan;
+ int adbits;
+ int ai_speed;
+ const struct comedi_lrange *adrange;
+ int dachan;
+ int dabits;
+};
+
+
+static const struct dt3k_boardtype dt3k_boardtypes[] = {
+ {name:"dt3001",
+ device_id:0x22,
+ adchan: 16,
+ adbits: 12,
+ adrange: &range_dt3000_ai,
+ ai_speed:3000,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt3001-pgl",
+ device_id:0x27,
+ adchan: 16,
+ adbits: 12,
+ adrange: &range_dt3000_ai_pgl,
+ ai_speed:3000,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt3002",
+ device_id:0x23,
+ adchan: 32,
+ adbits: 12,
+ adrange: &range_dt3000_ai,
+ ai_speed:3000,
+ dachan: 0,
+ dabits: 0,
+ },
+ {name:"dt3003",
+ device_id:0x24,
+ adchan: 64,
+ adbits: 12,
+ adrange: &range_dt3000_ai,
+ ai_speed:3000,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt3003-pgl",
+ device_id:0x28,
+ adchan: 64,
+ adbits: 12,
+ adrange: &range_dt3000_ai_pgl,
+ ai_speed:3000,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt3004",
+ device_id:0x25,
+ adchan: 16,
+ adbits: 16,
+ adrange: &range_dt3000_ai,
+ ai_speed:10000,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt3005", /* a.k.a. 3004-200 */
+ device_id:0x26,
+ adchan: 16,
+ adbits: 16,
+ adrange: &range_dt3000_ai,
+ ai_speed:5000,
+ dachan: 2,
+ dabits: 12,
+ },
+};
+
+#define n_dt3k_boards sizeof(dt3k_boardtypes)/sizeof(struct dt3k_boardtype)
+#define this_board ((const struct dt3k_boardtype *)dev->board_ptr)
+
+static DEFINE_PCI_DEVICE_TABLE(dt3k_pci_table) = {
+ {PCI_VENDOR_ID_DT, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_DT, 0x0027, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_DT, 0x0023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_DT, 0x0024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_DT, 0x0028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_DT, 0x0025, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_DT, 0x0026, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, dt3k_pci_table);
+
+#define DT3000_SIZE (4*0x1000)
+
+/* dual-ported RAM location definitions */
+
+#define DPR_DAC_buffer (4*0x000)
+#define DPR_ADC_buffer (4*0x800)
+#define DPR_Command (4*0xfd3)
+#define DPR_SubSys (4*0xfd3)
+#define DPR_Encode (4*0xfd4)
+#define DPR_Params(a) (4*(0xfd5+(a)))
+#define DPR_Tick_Reg_Lo (4*0xff5)
+#define DPR_Tick_Reg_Hi (4*0xff6)
+#define DPR_DA_Buf_Front (4*0xff7)
+#define DPR_DA_Buf_Rear (4*0xff8)
+#define DPR_AD_Buf_Front (4*0xff9)
+#define DPR_AD_Buf_Rear (4*0xffa)
+#define DPR_Int_Mask (4*0xffb)
+#define DPR_Intr_Flag (4*0xffc)
+#define DPR_Response_Mbx (4*0xffe)
+#define DPR_Command_Mbx (4*0xfff)
+
+#define AI_FIFO_DEPTH 2003
+#define AO_FIFO_DEPTH 2048
+
+/* command list */
+
+#define CMD_GETBRDINFO 0
+#define CMD_CONFIG 1
+#define CMD_GETCONFIG 2
+#define CMD_START 3
+#define CMD_STOP 4
+#define CMD_READSINGLE 5
+#define CMD_WRITESINGLE 6
+#define CMD_CALCCLOCK 7
+#define CMD_READEVENTS 8
+#define CMD_WRITECTCTRL 16
+#define CMD_READCTCTRL 17
+#define CMD_WRITECT 18
+#define CMD_READCT 19
+#define CMD_WRITEDATA 32
+#define CMD_READDATA 33
+#define CMD_WRITEIO 34
+#define CMD_READIO 35
+#define CMD_WRITECODE 36
+#define CMD_READCODE 37
+#define CMD_EXECUTE 38
+#define CMD_HALT 48
+
+#define SUBS_AI 0
+#define SUBS_AO 1
+#define SUBS_DIN 2
+#define SUBS_DOUT 3
+#define SUBS_MEM 4
+#define SUBS_CT 5
+
+/* interrupt flags */
+#define DT3000_CMDONE 0x80
+#define DT3000_CTDONE 0x40
+#define DT3000_DAHWERR 0x20
+#define DT3000_DASWERR 0x10
+#define DT3000_DAEMPTY 0x08
+#define DT3000_ADHWERR 0x04
+#define DT3000_ADSWERR 0x02
+#define DT3000_ADFULL 0x01
+
+#define DT3000_COMPLETION_MASK 0xff00
+#define DT3000_COMMAND_MASK 0x00ff
+#define DT3000_NOTPROCESSED 0x0000
+#define DT3000_NOERROR 0x5500
+#define DT3000_ERROR 0xaa00
+#define DT3000_NOTSUPPORTED 0xff00
+
+#define DT3000_EXTERNAL_CLOCK 1
+#define DT3000_RISING_EDGE 2
+
+#define TMODE_MASK 0x1c
+
+#define DT3000_AD_TRIG_INTERNAL (0<<2)
+#define DT3000_AD_TRIG_EXTERNAL (1<<2)
+#define DT3000_AD_RETRIG_INTERNAL (2<<2)
+#define DT3000_AD_RETRIG_EXTERNAL (3<<2)
+#define DT3000_AD_EXTRETRIG (4<<2)
+
+#define DT3000_CHANNEL_MODE_SE 0
+#define DT3000_CHANNEL_MODE_DI 1
+
+struct dt3k_private {
+
+ struct pci_dev *pci_dev;
+ resource_size_t phys_addr;
+ void *io_addr;
+ unsigned int lock;
+ unsigned int ao_readback[2];
+ unsigned int ai_front;
+ unsigned int ai_rear;
+};
+
+#define devpriv ((struct dt3k_private *)dev->private)
+
+static int dt3000_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt3000_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt3000 = {
+ driver_name:"dt3000",
+ module:THIS_MODULE,
+ attach:dt3000_attach,
+ detach:dt3000_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_dt3000, dt3k_pci_table);
+
+static void dt3k_ai_empty_fifo(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *arg,
+ unsigned int round_mode);
+static int dt3k_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+#ifdef DEBUG
+static void debug_intr_flags(unsigned int flags);
+#endif
+
+#define TIMEOUT 100
+
+static int dt3k_send_cmd(struct comedi_device * dev, unsigned int cmd)
+{
+ int i;
+ unsigned int status = 0;
+
+ writew(cmd, devpriv->io_addr + DPR_Command_Mbx);
+
+ for (i = 0; i < TIMEOUT; i++) {
+ status = readw(devpriv->io_addr + DPR_Command_Mbx);
+ if ((status & DT3000_COMPLETION_MASK) != DT3000_NOTPROCESSED)
+ break;
+ comedi_udelay(1);
+ }
+ if ((status & DT3000_COMPLETION_MASK) == DT3000_NOERROR) {
+ return 0;
+ }
+
+ printk("dt3k_send_cmd() timeout/error status=0x%04x\n", status);
+
+ return -ETIME;
+}
+
+static unsigned int dt3k_readsingle(struct comedi_device * dev, unsigned int subsys,
+ unsigned int chan, unsigned int gain)
+{
+ writew(subsys, devpriv->io_addr + DPR_SubSys);
+
+ writew(chan, devpriv->io_addr + DPR_Params(0));
+ writew(gain, devpriv->io_addr + DPR_Params(1));
+
+ dt3k_send_cmd(dev, CMD_READSINGLE);
+
+ return readw(devpriv->io_addr + DPR_Params(2));
+}
+
+static void dt3k_writesingle(struct comedi_device * dev, unsigned int subsys,
+ unsigned int chan, unsigned int data)
+{
+ writew(subsys, devpriv->io_addr + DPR_SubSys);
+
+ writew(chan, devpriv->io_addr + DPR_Params(0));
+ writew(0, devpriv->io_addr + DPR_Params(1));
+ writew(data, devpriv->io_addr + DPR_Params(2));
+
+ dt3k_send_cmd(dev, CMD_WRITESINGLE);
+}
+
+static int debug_n_ints = 0;
+
+// FIXME! Assumes shared interrupt is for this card.
+// What's this debug_n_ints stuff? Obviously needs some work...
+static irqreturn_t dt3k_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s;
+ unsigned int status;
+
+ if (!dev->attached) {
+ return IRQ_NONE;
+ }
+
+ s = dev->subdevices + 0;
+ status = readw(devpriv->io_addr + DPR_Intr_Flag);
+#ifdef DEBUG
+ debug_intr_flags(status);
+#endif
+
+ if (status & DT3000_ADFULL) {
+ dt3k_ai_empty_fifo(dev, s);
+ s->async->events |= COMEDI_CB_BLOCK;
+ }
+
+ if (status & (DT3000_ADSWERR | DT3000_ADHWERR)) {
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ }
+
+ debug_n_ints++;
+ if (debug_n_ints >= 10) {
+ dt3k_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ }
+
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+#ifdef DEBUG
+static char *intr_flags[] = {
+ "AdFull", "AdSwError", "AdHwError", "DaEmpty",
+ "DaSwError", "DaHwError", "CtDone", "CmDone",
+};
+static void debug_intr_flags(unsigned int flags)
+{
+ int i;
+ printk("dt3k: intr_flags:");
+ for (i = 0; i < 8; i++) {
+ if (flags & (1 << i)) {
+ printk(" %s", intr_flags[i]);
+ }
+ }
+ printk("\n");
+}
+#endif
+
+static void dt3k_ai_empty_fifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int front;
+ int rear;
+ int count;
+ int i;
+ short data;
+
+ front = readw(devpriv->io_addr + DPR_AD_Buf_Front);
+ count = front - devpriv->ai_front;
+ if (count < 0)
+ count += AI_FIFO_DEPTH;
+
+ printk("reading %d samples\n", count);
+
+ rear = devpriv->ai_rear;
+
+ for (i = 0; i < count; i++) {
+ data = readw(devpriv->io_addr + DPR_ADC_buffer + rear);
+ comedi_buf_put(s->async, data);
+ rear++;
+ if (rear >= AI_FIFO_DEPTH)
+ rear = 0;
+ }
+
+ devpriv->ai_rear = rear;
+ writew(rear, devpriv->io_addr + DPR_AD_Buf_Rear);
+}
+
+static int dt3k_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < this_board->ai_speed) {
+ cmd->scan_begin_arg = this_board->ai_speed;
+ err++;
+ }
+ if (cmd->scan_begin_arg > 100 * 16 * 65535) {
+ cmd->scan_begin_arg = 100 * 16 * 65535;
+ err++;
+ }
+ } else {
+ /* not supported */
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ai_speed) {
+ cmd->convert_arg = this_board->ai_speed;
+ err++;
+ }
+ if (cmd->convert_arg > 50 * 16 * 65535) {
+ cmd->convert_arg = 50 * 16 * 65535;
+ err++;
+ }
+ } else {
+ /* not supported */
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg > 0x00ffffff) {
+ cmd->stop_arg = 0x00ffffff;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ } else {
+ /* not supported */
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ dt3k_ns_to_timer(50, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ } else {
+ /* not supported */
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
+ unsigned int round_mode)
+{
+ int divider, base, prescale;
+
+ /* This function needs improvment */
+ /* Don't know if divider==0 works. */
+
+ for (prescale = 0; prescale < 16; prescale++) {
+ base = timer_base * (prescale + 1);
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ divider = (*nanosec + base / 2) / base;
+ break;
+ case TRIG_ROUND_DOWN:
+ divider = (*nanosec) / base;
+ break;
+ case TRIG_ROUND_UP:
+ divider = (*nanosec) / base;
+ break;
+ }
+ if (divider < 65536) {
+ *nanosec = divider * base;
+ return (prescale << 16) | (divider);
+ }
+ }
+
+ prescale = 15;
+ base = timer_base * (1 << prescale);
+ divider = 65535;
+ *nanosec = divider * base;
+ return (prescale << 16) | (divider);
+}
+
+static int dt3k_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int i;
+ unsigned int chan, range, aref;
+ unsigned int divider;
+ unsigned int tscandiv;
+ int ret;
+ unsigned int mode;
+
+ printk("dt3k_ai_cmd:\n");
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ chan = CR_CHAN(cmd->chanlist[i]);
+ range = CR_RANGE(cmd->chanlist[i]);
+
+ writew((range << 6) | chan,
+ devpriv->io_addr + DPR_ADC_buffer + i);
+ }
+ aref = CR_AREF(cmd->chanlist[0]);
+
+ writew(cmd->scan_end_arg, devpriv->io_addr + DPR_Params(0));
+ printk("param[0]=0x%04x\n", cmd->scan_end_arg);
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ divider = dt3k_ns_to_timer(50, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ writew((divider >> 16), devpriv->io_addr + DPR_Params(1));
+ printk("param[1]=0x%04x\n", divider >> 16);
+ writew((divider & 0xffff), devpriv->io_addr + DPR_Params(2));
+ printk("param[2]=0x%04x\n", divider & 0xffff);
+ } else {
+ /* not supported */
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tscandiv = dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ writew((tscandiv >> 16), devpriv->io_addr + DPR_Params(3));
+ printk("param[3]=0x%04x\n", tscandiv >> 16);
+ writew((tscandiv & 0xffff), devpriv->io_addr + DPR_Params(4));
+ printk("param[4]=0x%04x\n", tscandiv & 0xffff);
+ } else {
+ /* not supported */
+ }
+
+ mode = DT3000_AD_RETRIG_INTERNAL | 0 | 0;
+ writew(mode, devpriv->io_addr + DPR_Params(5));
+ printk("param[5]=0x%04x\n", mode);
+ writew(aref == AREF_DIFF, devpriv->io_addr + DPR_Params(6));
+ printk("param[6]=0x%04x\n", aref == AREF_DIFF);
+
+ writew(AI_FIFO_DEPTH / 2, devpriv->io_addr + DPR_Params(7));
+ printk("param[7]=0x%04x\n", AI_FIFO_DEPTH / 2);
+
+ writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+ ret = dt3k_send_cmd(dev, CMD_CONFIG);
+
+ writew(DT3000_ADFULL | DT3000_ADSWERR | DT3000_ADHWERR,
+ devpriv->io_addr + DPR_Int_Mask);
+
+ debug_n_ints = 0;
+
+ writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+ ret = dt3k_send_cmd(dev, CMD_START);
+
+ return 0;
+}
+
+static int dt3k_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int ret;
+
+ writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+ ret = dt3k_send_cmd(dev, CMD_STOP);
+
+ writew(0, devpriv->io_addr + DPR_Int_Mask);
+
+ return 0;
+}
+
+static int dt3k_ai_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ unsigned int chan, gain, aref;
+
+ chan = CR_CHAN(insn->chanspec);
+ gain = CR_RANGE(insn->chanspec);
+ /* XXX docs don't explain how to select aref */
+ aref = CR_AREF(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = dt3k_readsingle(dev, SUBS_AI, chan, gain);
+ }
+
+ return i;
+}
+
+static int dt3k_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ unsigned int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ for (i = 0; i < insn->n; i++) {
+ dt3k_writesingle(dev, SUBS_AO, chan, data[i]);
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ return i;
+}
+
+static int dt3k_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ unsigned int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+static void dt3k_dio_config(struct comedi_device * dev, int bits)
+{
+ /* XXX */
+ writew(SUBS_DOUT, devpriv->io_addr + DPR_SubSys);
+
+ writew(bits, devpriv->io_addr + DPR_Params(0));
+#if 0
+ /* don't know */
+ writew(0, devpriv->io_addr + DPR_Params(1));
+ writew(0, devpriv->io_addr + DPR_Params(2));
+#endif
+
+ dt3k_send_cmd(dev, CMD_CONFIG);
+}
+
+static int dt3k_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int mask;
+
+ mask = (CR_CHAN(insn->chanspec) < 4) ? 0x0f : 0xf0;
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= mask;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~mask;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->io_bits & (1 << CR_CHAN(insn->
+ chanspec))) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ mask = (s->io_bits & 0x01) | ((s->io_bits & 0x10) >> 3);
+ dt3k_dio_config(dev, mask);
+
+ return insn->n;
+}
+
+static int dt3k_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[1] & data[0];
+ dt3k_writesingle(dev, SUBS_DOUT, 0, s->state);
+ }
+ data[1] = dt3k_readsingle(dev, SUBS_DIN, 0, 0);
+
+ return 2;
+}
+
+static int dt3k_mem_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int addr = CR_CHAN(insn->chanspec);
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ writew(SUBS_MEM, devpriv->io_addr + DPR_SubSys);
+ writew(addr, devpriv->io_addr + DPR_Params(0));
+ writew(1, devpriv->io_addr + DPR_Params(1));
+
+ dt3k_send_cmd(dev, CMD_READCODE);
+
+ data[i] = readw(devpriv->io_addr + DPR_Params(2));
+ }
+
+ return i;
+}
+
+static int dt_pci_probe(struct comedi_device * dev, int bus, int slot);
+
+static int dt3000_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int bus, slot;
+ int ret = 0;
+
+ printk("dt3000:");
+ bus = it->options[0];
+ slot = it->options[1];
+
+ if ((ret = alloc_private(dev, sizeof(struct dt3k_private))) < 0)
+ return ret;
+
+ ret = dt_pci_probe(dev, bus, slot);
+ if (ret < 0)
+ return ret;
+ if (ret == 0) {
+ printk(" no DT board found\n");
+ return -ENODEV;
+ }
+
+ dev->board_name = this_board->name;
+
+ if (comedi_request_irq(devpriv->pci_dev->irq, dt3k_interrupt,
+ IRQF_SHARED, "dt3000", dev)) {
+ printk(" unable to allocate IRQ %u\n", devpriv->pci_dev->irq);
+ return -EINVAL;
+ }
+ dev->irq = devpriv->pci_dev->irq;
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+
+ s = dev->subdevices;
+ dev->read_subdev = s;
+
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+ s->n_chan = this_board->adchan;
+ s->insn_read = dt3k_ai_insn;
+ s->maxdata = (1 << this_board->adbits) - 1;
+ s->len_chanlist = 512;
+ s->range_table = &range_dt3000_ai; /* XXX */
+ s->do_cmd = dt3k_ai_cmd;
+ s->do_cmdtest = dt3k_ai_cmdtest;
+ s->cancel = dt3k_ai_cancel;
+
+ s++;
+ /* ao subsystem */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->insn_read = dt3k_ao_insn_read;
+ s->insn_write = dt3k_ao_insn;
+ s->maxdata = (1 << this_board->dabits) - 1;
+ s->len_chanlist = 1;
+ s->range_table = &range_bipolar10;
+
+ s++;
+ /* dio subsystem */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->insn_config = dt3k_dio_insn_config;
+ s->insn_bits = dt3k_dio_insn_bits;
+ s->maxdata = 1;
+ s->len_chanlist = 8;
+ s->range_table = &range_digital;
+
+ s++;
+ /* mem subsystem */
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 0x1000;
+ s->insn_read = dt3k_mem_insn_read;
+ s->maxdata = 0xff;
+ s->len_chanlist = 1;
+ s->range_table = &range_unknown;
+
+#if 0
+ s++;
+ /* proc subsystem */
+ s->type = COMEDI_SUBD_PROC;
+#endif
+
+ return 0;
+}
+
+static int dt3000_detach(struct comedi_device * dev)
+{
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (devpriv) {
+ if (devpriv->pci_dev) {
+ if (devpriv->phys_addr) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ if (devpriv->io_addr)
+ iounmap(devpriv->io_addr);
+ }
+ /* XXX */
+
+ return 0;
+}
+
+static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board);
+static int setup_pci(struct comedi_device * dev);
+
+static int dt_pci_probe(struct comedi_device * dev, int bus, int slot)
+{
+ int board;
+ int ret;
+ struct pci_dev *pcidev;
+
+ pcidev = NULL;
+ while ((pcidev = dt_pci_find_device(pcidev, &board)) != NULL) {
+ if ((bus == 0 && slot == 0) ||
+ (pcidev->bus->number == bus &&
+ PCI_SLOT(pcidev->devfn) == slot)) {
+ break;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+
+ if (board >= 0)
+ dev->board_ptr = dt3k_boardtypes + board;
+
+ if (!devpriv->pci_dev)
+ return 0;
+
+ if ((ret = setup_pci(dev)) < 0)
+ return ret;
+
+ return 1;
+}
+
+static int setup_pci(struct comedi_device * dev)
+{
+ resource_size_t addr;
+ int ret;
+
+ ret = comedi_pci_enable(devpriv->pci_dev, "dt3000");
+ if (ret < 0)
+ return ret;
+
+ addr = pci_resource_start(devpriv->pci_dev, 0);
+ devpriv->phys_addr = addr;
+ devpriv->io_addr = ioremap(devpriv->phys_addr, DT3000_SIZE);
+ if (!devpriv->io_addr)
+ return -ENOMEM;
+#if DEBUG
+ printk("0x%08llx mapped to %p, ",
+ (unsigned long long)devpriv->phys_addr, devpriv->io_addr);
+#endif
+
+ return 0;
+}
+
+static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board)
+{
+ int i;
+
+ for (from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from);
+ from != NULL;
+ from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from)) {
+ for (i = 0; i < n_dt3k_boards; i++) {
+ if (from->device == dt3k_boardtypes[i].device_id) {
+ *board = i;
+ return from;
+ }
+ }
+ printk("unknown Data Translation PCI device found with device_id=0x%04x\n", from->device);
+ }
+ *board = -1;
+ return from;
+}
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index f2d2173d721..cc4c0463008 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -300,22 +300,22 @@ struct slot_dt9812 {
struct comedi_dt9812 *comedi;
};
-static const comedi_lrange dt9812_10_ain_range = { 1, {
+static const struct comedi_lrange dt9812_10_ain_range = { 1, {
BIP_RANGE(10),
}
};
-static const comedi_lrange dt9812_2pt5_ain_range = { 1, {
+static const struct comedi_lrange dt9812_2pt5_ain_range = { 1, {
UNI_RANGE(2.5),
}
};
-static const comedi_lrange dt9812_10_aout_range = { 1, {
+static const struct comedi_lrange dt9812_10_aout_range = { 1, {
BIP_RANGE(10),
}
};
-static const comedi_lrange dt9812_2pt5_aout_range = { 1, {
+static const struct comedi_lrange dt9812_2pt5_aout_range = { 1, {
UNI_RANGE(2.5),
}
};
@@ -892,12 +892,12 @@ static struct usb_driver dt9812_usb_driver = {
* Comedi functions
*/
-static void dt9812_comedi_open(comedi_device *dev)
+static void dt9812_comedi_open(struct comedi_device *dev)
{
down(&devpriv->slot->mutex);
if (devpriv->slot->usb) {
/* We have an attached device, fill in current range info */
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
s = &dev->subdevices[0];
s->n_chan = 8;
@@ -940,8 +940,8 @@ static void dt9812_comedi_open(comedi_device *dev)
up(&devpriv->slot->mutex);
}
-static int dt9812_di_rinsn(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int dt9812_di_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n;
u8 bits = 0;
@@ -952,8 +952,8 @@ static int dt9812_di_rinsn(comedi_device *dev, comedi_subdevice *s,
return n;
}
-static int dt9812_do_winsn(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int dt9812_do_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n;
u8 bits = 0;
@@ -970,8 +970,8 @@ static int dt9812_do_winsn(comedi_device *dev, comedi_subdevice *s,
return n;
}
-static int dt9812_ai_rinsn(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int dt9812_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n;
@@ -985,8 +985,8 @@ static int dt9812_ai_rinsn(comedi_device *dev, comedi_subdevice *s,
return n;
}
-static int dt9812_ao_rinsn(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int dt9812_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n;
u16 value;
@@ -999,8 +999,8 @@ static int dt9812_ao_rinsn(comedi_device *dev, comedi_subdevice *s,
return n;
}
-static int dt9812_ao_winsn(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int dt9812_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n;
@@ -1009,10 +1009,10 @@ static int dt9812_ao_winsn(comedi_device *dev, comedi_subdevice *s,
return n;
}
-static int dt9812_attach(comedi_device *dev, comedi_devconfig *it)
+static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
int i;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
dev->board_name = "dt9812";
@@ -1103,12 +1103,12 @@ static int dt9812_attach(comedi_device *dev, comedi_devconfig *it)
return 0;
}
-static int dt9812_detach(comedi_device *dev)
+static int dt9812_detach(struct comedi_device *dev)
{
return 0;
}
-static comedi_driver dt9812_comedi_driver = {
+static struct comedi_driver dt9812_comedi_driver = {
.module = THIS_MODULE,
.driver_name = "dt9812",
.attach = dt9812_attach,
diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c
new file mode 100644
index 00000000000..6d7bb37d2b1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/fl512.c
@@ -0,0 +1,186 @@
+/*
+ comedi/drivers/fl512.c
+ Anders Gnistrup <ex18@kalman.iau.dtu.dk>
+*/
+
+/*
+Driver: fl512
+Description: unknown
+Author: Anders Gnistrup <ex18@kalman.iau.dtu.dk>
+Devices: [unknown] FL512 (fl512)
+Status: unknown
+
+Digital I/O is not supported.
+
+Configuration options:
+ [0] - I/O port base address
+*/
+
+#define DEBUG 0
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/ioport.h>
+
+#define FL512_SIZE 16 /* the size of the used memory */
+struct fl512_private {
+
+ short ao_readback[2];
+};
+
+#define devpriv ((struct fl512_private *) dev->private)
+
+static const struct comedi_lrange range_fl512 = { 4, {
+ BIP_RANGE(0.5),
+ BIP_RANGE(1),
+ BIP_RANGE(5),
+ BIP_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(5),
+ UNI_RANGE(10),
+ }
+};
+
+static int fl512_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int fl512_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_fl512 = {
+ driver_name:"fl512",
+ module:THIS_MODULE,
+ attach:fl512_attach,
+ detach:fl512_detach,
+};
+
+COMEDI_INITCLEANUP(driver_fl512);
+
+static int fl512_ai_insn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int fl512_ao_insn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int fl512_ao_insn_readback(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * fl512_ai_insn : this is the analog input function
+ */
+static int fl512_ai_insn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ unsigned int lo_byte, hi_byte;
+ char chan = CR_CHAN(insn->chanspec);
+ unsigned long iobase = dev->iobase;
+
+ for (n = 0; n < insn->n; n++) { /* sample n times on selected channel */
+ /* XXX probably can move next step out of for() loop -- will make
+ * AI a little bit faster. */
+ outb(chan, iobase + 2); /* select chan */
+ outb(0, iobase + 3); /* start conversion */
+ /* XXX should test "done" flag instead of delay */
+ comedi_udelay(30); /* sleep 30 usec */
+ lo_byte = inb(iobase + 2); /* low 8 byte */
+ hi_byte = inb(iobase + 3) & 0xf; /* high 4 bit and mask */
+ data[n] = lo_byte + (hi_byte << 8);
+ }
+ return n;
+}
+
+/*
+ * fl512_ao_insn : used to write to a DA port n times
+ */
+static int fl512_ao_insn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec); /* get chan to write */
+ unsigned long iobase = dev->iobase; /* get base address */
+
+ for (n = 0; n < insn->n; n++) { /* write n data set */
+ outb(data[n] & 0x0ff, iobase + 4 + 2 * chan); /* write low byte */
+ outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan); /* write high byte */
+ inb(iobase + 4 + 2 * chan); /* trig */
+
+ devpriv->ao_readback[chan] = data[n];
+ }
+ return n;
+}
+
+/*
+ * fl512_ao_insn_readback : used to read previous values written to
+ * DA port
+ */
+static int fl512_ao_insn_readback(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ data[n] = devpriv->ao_readback[chan];
+ }
+
+ return n;
+}
+
+/*
+ * start attach
+ */
+static int fl512_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned long iobase;
+ struct comedi_subdevice *s; /* pointer to the subdevice:
+ Analog in, Analog out, ( not made ->and Digital IO) */
+
+ iobase = it->options[0];
+ printk("comedi:%d fl512: 0x%04lx", dev->minor, iobase);
+ if (!request_region(iobase, FL512_SIZE, "fl512")) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+ dev->board_name = "fl512";
+ if (alloc_private(dev, sizeof(struct fl512_private)) < 0)
+ return -ENOMEM;
+
+#if DEBUG
+ printk("malloc ok\n");
+#endif
+
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ /*
+ * this if the definitions of the supdevices, 2 have been defined
+ */
+ /* Analog indput */
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_AI; /* define subdevice as Analog In */
+ s->subdev_flags = SDF_READABLE | SDF_GROUND; /* you can read it from userspace */
+ s->n_chan = 16; /* Number of Analog input channels */
+ s->maxdata = 0x0fff; /* accept only 12 bits of data */
+ s->range_table = &range_fl512; /* device use one of the ranges */
+ s->insn_read = fl512_ai_insn; /* function to call when read AD */
+ printk("comedi: fl512: subdevice 0 initialized\n");
+
+ /* Analog output */
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_AO; /* define subdevice as Analog OUT */
+ s->subdev_flags = SDF_WRITABLE; /* you can write it from userspace */
+ s->n_chan = 2; /* Number of Analog output channels */
+ s->maxdata = 0x0fff; /* accept only 12 bits of data */
+ s->range_table = &range_fl512; /* device use one of the ranges */
+ s->insn_write = fl512_ao_insn; /* function to call when write DA */
+ s->insn_read = fl512_ao_insn_readback; /* function to call when reading DA */
+ printk("comedi: fl512: subdevice 1 initialized\n");
+
+ return 1;
+}
+
+static int fl512_detach(struct comedi_device * dev)
+{
+ if (dev->iobase)
+ release_region(dev->iobase, FL512_SIZE);
+ printk("comedi%d: fl512: dummy i detach\n", dev->minor);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
new file mode 100644
index 00000000000..49e5c86c2dd
--- /dev/null
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -0,0 +1,1060 @@
+/*
+ comedi/drivers/gsc_hpdi.c
+ This is a driver for the General Standards Corporation High
+ Speed Parallel Digital Interface rs485 boards.
+
+ Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+ Copyright (C) 2003 Coherent Imaging Systems
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************/
+
+/*
+
+Driver: gsc_hpdi
+Description: General Standards Corporation High
+ Speed Parallel Digital Interface rs485 boards
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Status: only receive mode works, transmit not supported
+Updated: 2003-02-20
+Devices: [General Standards Corporation] PCI-HPDI32 (gsc_hpdi),
+ PMC-HPDI32
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+
+There are some additional hpdi models available from GSC for which
+support could be added to this driver.
+
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "plx9080.h"
+#include "comedi_fc.h"
+
+static int hpdi_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int hpdi_detach(struct comedi_device * dev);
+void abort_dma(struct comedi_device * dev, unsigned int channel);
+static int hpdi_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int hpdi_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int hpdi_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG);
+static int dio_config_block_size(struct comedi_device * dev, unsigned int * data);
+
+#undef HPDI_DEBUG // disable debugging messages
+//#define HPDI_DEBUG // enable debugging code
+
+#ifdef HPDI_DEBUG
+#define DEBUG_PRINT(format, args...) rt_printk(format , ## args )
+#else
+#define DEBUG_PRINT(format, args...)
+#endif
+
+#define TIMER_BASE 50 // 20MHz master clock
+#define DMA_BUFFER_SIZE 0x10000
+#define NUM_DMA_BUFFERS 4
+#define NUM_DMA_DESCRIPTORS 256
+
+// indices of base address regions
+enum base_address_regions {
+ PLX9080_BADDRINDEX = 0,
+ HPDI_BADDRINDEX = 2,
+};
+
+enum hpdi_registers {
+ FIRMWARE_REV_REG = 0x0,
+ BOARD_CONTROL_REG = 0x4,
+ BOARD_STATUS_REG = 0x8,
+ TX_PROG_ALMOST_REG = 0xc,
+ RX_PROG_ALMOST_REG = 0x10,
+ FEATURES_REG = 0x14,
+ FIFO_REG = 0x18,
+ TX_STATUS_COUNT_REG = 0x1c,
+ TX_LINE_VALID_COUNT_REG = 0x20,
+ TX_LINE_INVALID_COUNT_REG = 0x24,
+ RX_STATUS_COUNT_REG = 0x28,
+ RX_LINE_COUNT_REG = 0x2c,
+ INTERRUPT_CONTROL_REG = 0x30,
+ INTERRUPT_STATUS_REG = 0x34,
+ TX_CLOCK_DIVIDER_REG = 0x38,
+ TX_FIFO_SIZE_REG = 0x40,
+ RX_FIFO_SIZE_REG = 0x44,
+ TX_FIFO_WORDS_REG = 0x48,
+ RX_FIFO_WORDS_REG = 0x4c,
+ INTERRUPT_EDGE_LEVEL_REG = 0x50,
+ INTERRUPT_POLARITY_REG = 0x54,
+};
+
+int command_channel_valid(unsigned int channel)
+{
+ if (channel == 0 || channel > 6) {
+ rt_printk("gsc_hpdi: bug! invalid cable command channel\n");
+ return 0;
+ }
+ return 1;
+}
+
+// bit definitions
+
+enum firmware_revision_bits {
+ FEATURES_REG_PRESENT_BIT = 0x8000,
+};
+int firmware_revision(uint32_t fwr_bits)
+{
+ return fwr_bits & 0xff;
+}
+
+int pcb_revision(uint32_t fwr_bits)
+{
+ return (fwr_bits >> 8) & 0xff;
+}
+
+int hpdi_subid(uint32_t fwr_bits)
+{
+ return (fwr_bits >> 16) & 0xff;
+}
+
+enum board_control_bits {
+ BOARD_RESET_BIT = 0x1, /* wait 10usec before accessing fifos */
+ TX_FIFO_RESET_BIT = 0x2,
+ RX_FIFO_RESET_BIT = 0x4,
+ TX_ENABLE_BIT = 0x10,
+ RX_ENABLE_BIT = 0x20,
+ DEMAND_DMA_DIRECTION_TX_BIT = 0x40, /* for channel 0, channel 1 can only transmit (when present) */
+ LINE_VALID_ON_STATUS_VALID_BIT = 0x80,
+ START_TX_BIT = 0x10,
+ CABLE_THROTTLE_ENABLE_BIT = 0x20,
+ TEST_MODE_ENABLE_BIT = 0x80000000,
+};
+uint32_t command_discrete_output_bits(unsigned int channel, int output,
+ int output_value)
+{
+ uint32_t bits = 0;
+
+ if (command_channel_valid(channel) == 0)
+ return 0;
+ if (output) {
+ bits |= 0x1 << (16 + channel);
+ if (output_value)
+ bits |= 0x1 << (24 + channel);
+ } else
+ bits |= 0x1 << (24 + channel);
+
+ return bits;
+}
+
+enum board_status_bits {
+ COMMAND_LINE_STATUS_MASK = 0x7f,
+ TX_IN_PROGRESS_BIT = 0x80,
+ TX_NOT_EMPTY_BIT = 0x100,
+ TX_NOT_ALMOST_EMPTY_BIT = 0x200,
+ TX_NOT_ALMOST_FULL_BIT = 0x400,
+ TX_NOT_FULL_BIT = 0x800,
+ RX_NOT_EMPTY_BIT = 0x1000,
+ RX_NOT_ALMOST_EMPTY_BIT = 0x2000,
+ RX_NOT_ALMOST_FULL_BIT = 0x4000,
+ RX_NOT_FULL_BIT = 0x8000,
+ BOARD_JUMPER0_INSTALLED_BIT = 0x10000,
+ BOARD_JUMPER1_INSTALLED_BIT = 0x20000,
+ TX_OVERRUN_BIT = 0x200000,
+ RX_UNDERRUN_BIT = 0x400000,
+ RX_OVERRUN_BIT = 0x800000,
+};
+
+uint32_t almost_full_bits(unsigned int num_words)
+{
+// XXX need to add or subtract one?
+ return (num_words << 16) & 0xff0000;
+}
+
+uint32_t almost_empty_bits(unsigned int num_words)
+{
+ return num_words & 0xffff;
+}
+unsigned int almost_full_num_words(uint32_t bits)
+{
+// XXX need to add or subtract one?
+ return (bits >> 16) & 0xffff;
+}
+unsigned int almost_empty_num_words(uint32_t bits)
+{
+ return bits & 0xffff;
+}
+
+enum features_bits {
+ FIFO_SIZE_PRESENT_BIT = 0x1,
+ FIFO_WORDS_PRESENT_BIT = 0x2,
+ LEVEL_EDGE_INTERRUPTS_PRESENT_BIT = 0x4,
+ GPIO_SUPPORTED_BIT = 0x8,
+ PLX_DMA_CH1_SUPPORTED_BIT = 0x10,
+ OVERRUN_UNDERRUN_SUPPORTED_BIT = 0x20,
+};
+
+enum interrupt_sources {
+ FRAME_VALID_START_INTR = 0,
+ FRAME_VALID_END_INTR = 1,
+ TX_FIFO_EMPTY_INTR = 8,
+ TX_FIFO_ALMOST_EMPTY_INTR = 9,
+ TX_FIFO_ALMOST_FULL_INTR = 10,
+ TX_FIFO_FULL_INTR = 11,
+ RX_EMPTY_INTR = 12,
+ RX_ALMOST_EMPTY_INTR = 13,
+ RX_ALMOST_FULL_INTR = 14,
+ RX_FULL_INTR = 15,
+};
+int command_intr_source(unsigned int channel)
+{
+ if (command_channel_valid(channel) == 0)
+ channel = 1;
+ return channel + 1;
+}
+
+uint32_t intr_bit(int interrupt_source)
+{
+ return 0x1 << interrupt_source;
+}
+
+uint32_t tx_clock_divisor_bits(unsigned int divisor)
+{
+ return divisor & 0xff;
+}
+
+unsigned int fifo_size(uint32_t fifo_size_bits)
+{
+ return fifo_size_bits & 0xfffff;
+}
+
+unsigned int fifo_words(uint32_t fifo_words_bits)
+{
+ return fifo_words_bits & 0xfffff;
+}
+
+uint32_t intr_edge_bit(int interrupt_source)
+{
+ return 0x1 << interrupt_source;
+}
+
+uint32_t intr_active_high_bit(int interrupt_source)
+{
+ return 0x1 << interrupt_source;
+}
+
+struct hpdi_board {
+
+ char *name;
+ int device_id; // pci device id
+ int subdevice_id; // pci subdevice id
+};
+
+
+static const struct hpdi_board hpdi_boards[] = {
+ {
+ name: "pci-hpdi32",
+ device_id:PCI_DEVICE_ID_PLX_9080,
+ subdevice_id:0x2400,
+ },
+#if 0
+ {
+ name: "pxi-hpdi32",
+ device_id:0x9656,
+ subdevice_id:0x2705,
+ },
+#endif
+};
+
+static inline unsigned int num_boards(void)
+{
+ return sizeof(hpdi_boards) / sizeof(struct hpdi_board);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(hpdi_pci_table) = {
+ {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX, 0x2400,
+ 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, hpdi_pci_table);
+
+static inline struct hpdi_board *board(const struct comedi_device * dev)
+{
+ return (struct hpdi_board *) dev->board_ptr;
+}
+
+struct hpdi_private {
+
+ struct pci_dev *hw_dev; // pointer to board's pci_dev struct
+ // base addresses (physical)
+ resource_size_t plx9080_phys_iobase;
+ resource_size_t hpdi_phys_iobase;
+ // base addresses (ioremapped)
+ void *plx9080_iobase;
+ void *hpdi_iobase;
+ uint32_t *dio_buffer[NUM_DMA_BUFFERS]; // dma buffers
+ dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS]; // physical addresses of dma buffers
+ struct plx_dma_desc *dma_desc; // array of dma descriptors read by plx9080, allocated to get proper alignment
+ dma_addr_t dma_desc_phys_addr; // physical address of dma descriptor array
+ unsigned int num_dma_descriptors;
+ uint32_t *desc_dio_buffer[NUM_DMA_DESCRIPTORS]; // pointer to start of buffers indexed by descriptor
+ volatile unsigned int dma_desc_index; // index of the dma descriptor that is currently being used
+ unsigned int tx_fifo_size;
+ unsigned int rx_fifo_size;
+ volatile unsigned long dio_count;
+ volatile uint32_t bits[24]; // software copies of values written to hpdi registers
+ volatile unsigned int block_size; // number of bytes at which to generate COMEDI_CB_BLOCK events
+ unsigned dio_config_output:1;
+};
+
+
+static inline struct hpdi_private *priv(struct comedi_device * dev)
+{
+ return dev->private;
+}
+
+static struct comedi_driver driver_hpdi = {
+ driver_name:"gsc_hpdi",
+ module:THIS_MODULE,
+ attach:hpdi_attach,
+ detach:hpdi_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_hpdi, hpdi_pci_table);
+
+static int dio_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ priv(dev)->dio_config_output = 1;
+ return insn->n;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ priv(dev)->dio_config_output = 0;
+ return insn->n;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ priv(dev)->
+ dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ case INSN_CONFIG_BLOCK_SIZE:
+ return dio_config_block_size(dev, data);
+ break;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static void disable_plx_interrupts(struct comedi_device * dev)
+{
+ writel(0, priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+}
+
+// initialize plx9080 chip
+static void init_plx9080(struct comedi_device * dev)
+{
+ uint32_t bits;
+ void *plx_iobase = priv(dev)->plx9080_iobase;
+
+ // plx9080 dump
+ DEBUG_PRINT(" plx interrupt status 0x%x\n",
+ readl(plx_iobase + PLX_INTRCS_REG));
+ DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
+ DEBUG_PRINT(" plx control reg 0x%x\n",
+ readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG));
+
+ DEBUG_PRINT(" plx revision 0x%x\n",
+ readl(plx_iobase + PLX_REVISION_REG));
+ DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_MODE_REG));
+ DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
+ readl(plx_iobase + PLX_DMA1_MODE_REG));
+ DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG));
+ DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG));
+ DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG));
+ DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG));
+ DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n",
+ readb(plx_iobase + PLX_DMA0_CS_REG));
+ DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
+ DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG));
+#ifdef __BIG_ENDIAN
+ bits = BIGEND_DMA0 | BIGEND_DMA1;
+#else
+ bits = 0;
+#endif
+ writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG);
+
+ disable_plx_interrupts(dev);
+
+ abort_dma(dev, 0);
+ abort_dma(dev, 1);
+
+ // configure dma0 mode
+ bits = 0;
+ // enable ready input
+ bits |= PLX_DMA_EN_READYIN_BIT;
+ // enable dma chaining
+ bits |= PLX_EN_CHAIN_BIT;
+ // enable interrupt on dma done (probably don't need this, since chain never finishes)
+ bits |= PLX_EN_DMA_DONE_INTR_BIT;
+ // don't increment local address during transfers (we are transferring from a fixed fifo register)
+ bits |= PLX_LOCAL_ADDR_CONST_BIT;
+ // route dma interrupt to pci bus
+ bits |= PLX_DMA_INTR_PCI_BIT;
+ // enable demand mode
+ bits |= PLX_DEMAND_MODE_BIT;
+ // enable local burst mode
+ bits |= PLX_DMA_LOCAL_BURST_EN_BIT;
+ bits |= PLX_LOCAL_BUS_32_WIDE_BITS;
+ writel(bits, plx_iobase + PLX_DMA0_MODE_REG);
+}
+
+/* Allocate and initialize the subdevice structures.
+ */
+static int setup_subdevices(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s;
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog input subdevice */
+ dev->read_subdev = s;
+/* dev->write_subdev = s; */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL | SDF_CMD_READ;
+ s->n_chan = 32;
+ s->len_chanlist = 32;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_config = dio_config_insn;
+ s->do_cmd = hpdi_cmd;
+ s->do_cmdtest = hpdi_cmd_test;
+ s->cancel = hpdi_cancel;
+
+ return 0;
+}
+
+static int init_hpdi(struct comedi_device * dev)
+{
+ uint32_t plx_intcsr_bits;
+
+ writel(BOARD_RESET_BIT, priv(dev)->hpdi_iobase + BOARD_CONTROL_REG);
+ comedi_udelay(10);
+
+ writel(almost_empty_bits(32) | almost_full_bits(32),
+ priv(dev)->hpdi_iobase + RX_PROG_ALMOST_REG);
+ writel(almost_empty_bits(32) | almost_full_bits(32),
+ priv(dev)->hpdi_iobase + TX_PROG_ALMOST_REG);
+
+ priv(dev)->tx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
+ TX_FIFO_SIZE_REG));
+ priv(dev)->rx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
+ RX_FIFO_SIZE_REG));
+
+ writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
+
+ // enable interrupts
+ plx_intcsr_bits =
+ ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
+ ICS_DMA0_E;
+ writel(plx_intcsr_bits, priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+
+ return 0;
+}
+
+// setup dma descriptors so a link completes every 'transfer_size' bytes
+static int setup_dma_descriptors(struct comedi_device * dev,
+ unsigned int transfer_size)
+{
+ unsigned int buffer_index, buffer_offset;
+ uint32_t next_bits = PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
+ PLX_XFER_LOCAL_TO_PCI;
+ unsigned int i;
+
+ if (transfer_size > DMA_BUFFER_SIZE)
+ transfer_size = DMA_BUFFER_SIZE;
+ transfer_size -= transfer_size % sizeof(uint32_t);
+ if (transfer_size == 0)
+ return -1;
+
+ DEBUG_PRINT(" transfer_size %i\n", transfer_size);
+ DEBUG_PRINT(" descriptors at 0x%lx\n",
+ (unsigned long)priv(dev)->dma_desc_phys_addr);
+
+ buffer_offset = 0;
+ buffer_index = 0;
+ for (i = 0; i < NUM_DMA_DESCRIPTORS &&
+ buffer_index < NUM_DMA_BUFFERS; i++) {
+ priv(dev)->dma_desc[i].pci_start_addr =
+ cpu_to_le32(priv(dev)->
+ dio_buffer_phys_addr[buffer_index] + buffer_offset);
+ priv(dev)->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG);
+ priv(dev)->dma_desc[i].transfer_size =
+ cpu_to_le32(transfer_size);
+ priv(dev)->dma_desc[i].next =
+ cpu_to_le32((priv(dev)->dma_desc_phys_addr + (i +
+ 1) *
+ sizeof(priv(dev)->dma_desc[0])) | next_bits);
+
+ priv(dev)->desc_dio_buffer[i] =
+ priv(dev)->dio_buffer[buffer_index] +
+ (buffer_offset / sizeof(uint32_t));
+
+ buffer_offset += transfer_size;
+ if (transfer_size + buffer_offset > DMA_BUFFER_SIZE) {
+ buffer_offset = 0;
+ buffer_index++;
+ }
+
+ DEBUG_PRINT(" desc %i\n", i);
+ DEBUG_PRINT(" start addr virt 0x%p, phys 0x%lx\n",
+ priv(dev)->desc_dio_buffer[i],
+ (unsigned long)priv(dev)->dma_desc[i].pci_start_addr);
+ DEBUG_PRINT(" next 0x%lx\n",
+ (unsigned long)priv(dev)->dma_desc[i].next);
+ }
+ priv(dev)->num_dma_descriptors = i;
+ // fix last descriptor to point back to first
+ priv(dev)->dma_desc[i - 1].next =
+ cpu_to_le32(priv(dev)->dma_desc_phys_addr | next_bits);
+ DEBUG_PRINT(" desc %i next fixup 0x%lx\n", i - 1,
+ (unsigned long)priv(dev)->dma_desc[i - 1].next);
+
+ priv(dev)->block_size = transfer_size;
+
+ return transfer_size;
+}
+
+static int hpdi_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev;
+ int i;
+ int retval;
+
+ printk("comedi%d: gsc_hpdi\n", dev->minor);
+
+ if (alloc_private(dev, sizeof(struct hpdi_private)) < 0)
+ return -ENOMEM;
+
+ pcidev = NULL;
+ for (i = 0; i < num_boards() && dev->board_ptr == NULL; i++) {
+ do {
+ pcidev = pci_get_subsys(PCI_VENDOR_ID_PLX,
+ hpdi_boards[i].device_id, PCI_VENDOR_ID_PLX,
+ hpdi_boards[i].subdevice_id, pcidev);
+ // was a particular bus/slot requested?
+ if (it->options[0] || it->options[1]) {
+ // are we on the wrong bus/slot?
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1])
+ continue;
+ }
+ if (pcidev) {
+ priv(dev)->hw_dev = pcidev;
+ dev->board_ptr = hpdi_boards + i;
+ break;
+ }
+ } while (pcidev != NULL);
+ }
+ if (dev->board_ptr == NULL) {
+ printk("gsc_hpdi: no hpdi card found\n");
+ return -EIO;
+ }
+
+ printk("gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name,
+ pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+
+ if (comedi_pci_enable(pcidev, driver_hpdi.driver_name)) {
+ printk(KERN_WARNING
+ " failed enable PCI device and request regions\n");
+ return -EIO;
+ }
+ pci_set_master(pcidev);
+
+ //Initialize dev->board_name
+ dev->board_name = board(dev)->name;
+
+ priv(dev)->plx9080_phys_iobase =
+ pci_resource_start(pcidev, PLX9080_BADDRINDEX);
+ priv(dev)->hpdi_phys_iobase =
+ pci_resource_start(pcidev, HPDI_BADDRINDEX);
+
+ // remap, won't work with 2.0 kernels but who cares
+ priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase,
+ pci_resource_len(pcidev, PLX9080_BADDRINDEX));
+ priv(dev)->hpdi_iobase = ioremap(priv(dev)->hpdi_phys_iobase,
+ pci_resource_len(pcidev, HPDI_BADDRINDEX));
+ if (!priv(dev)->plx9080_iobase || !priv(dev)->hpdi_iobase) {
+ printk(" failed to remap io memory\n");
+ return -ENOMEM;
+ }
+
+ DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase);
+ DEBUG_PRINT(" hpdi remapped to 0x%p\n", priv(dev)->hpdi_iobase);
+
+ init_plx9080(dev);
+
+ // get irq
+ if (comedi_request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
+ driver_hpdi.driver_name, dev)) {
+ printk(" unable to allocate irq %u\n", pcidev->irq);
+ return -EINVAL;
+ }
+ dev->irq = pcidev->irq;
+
+ printk(" irq %u\n", dev->irq);
+
+ // alocate pci dma buffers
+ for (i = 0; i < NUM_DMA_BUFFERS; i++) {
+ priv(dev)->dio_buffer[i] =
+ pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE,
+ &priv(dev)->dio_buffer_phys_addr[i]);
+ DEBUG_PRINT("dio_buffer at virt 0x%p, phys 0x%lx\n",
+ priv(dev)->dio_buffer[i],
+ (unsigned long)priv(dev)->dio_buffer_phys_addr[i]);
+ }
+ // allocate dma descriptors
+ priv(dev)->dma_desc = pci_alloc_consistent(priv(dev)->hw_dev,
+ sizeof(struct plx_dma_desc) * NUM_DMA_DESCRIPTORS,
+ &priv(dev)->dma_desc_phys_addr);
+ if (priv(dev)->dma_desc_phys_addr & 0xf) {
+ printk(" dma descriptors not quad-word aligned (bug)\n");
+ return -EIO;
+ }
+
+ retval = setup_dma_descriptors(dev, 0x1000);
+ if (retval < 0)
+ return retval;
+
+ retval = setup_subdevices(dev);
+ if (retval < 0)
+ return retval;
+
+ return init_hpdi(dev);
+}
+
+static int hpdi_detach(struct comedi_device * dev)
+{
+ unsigned int i;
+
+ printk("comedi%d: gsc_hpdi: remove\n", dev->minor);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (priv(dev)) {
+ if (priv(dev)->hw_dev) {
+ if (priv(dev)->plx9080_iobase) {
+ disable_plx_interrupts(dev);
+ iounmap((void *)priv(dev)->plx9080_iobase);
+ }
+ if (priv(dev)->hpdi_iobase)
+ iounmap((void *)priv(dev)->hpdi_iobase);
+ // free pci dma buffers
+ for (i = 0; i < NUM_DMA_BUFFERS; i++) {
+ if (priv(dev)->dio_buffer[i])
+ pci_free_consistent(priv(dev)->hw_dev,
+ DMA_BUFFER_SIZE,
+ priv(dev)->dio_buffer[i],
+ priv(dev)->
+ dio_buffer_phys_addr[i]);
+ }
+ // free dma descriptors
+ if (priv(dev)->dma_desc)
+ pci_free_consistent(priv(dev)->hw_dev,
+ sizeof(struct plx_dma_desc) *
+ NUM_DMA_DESCRIPTORS,
+ priv(dev)->dma_desc,
+ priv(dev)->dma_desc_phys_addr);
+ if (priv(dev)->hpdi_phys_iobase) {
+ comedi_pci_disable(priv(dev)->hw_dev);
+ }
+ pci_dev_put(priv(dev)->hw_dev);
+ }
+ }
+ return 0;
+}
+
+static int dio_config_block_size(struct comedi_device * dev, unsigned int * data)
+{
+ unsigned int requested_block_size;
+ int retval;
+
+ requested_block_size = data[1];
+
+ retval = setup_dma_descriptors(dev, requested_block_size);
+ if (retval < 0)
+ return retval;
+
+ data[1] = retval;
+
+ return 2;
+}
+
+static int di_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int i;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ // uniqueness check
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 32;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (err)
+ return 4;
+
+ if (cmd->chanlist) {
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) != i) {
+ // XXX could support 8 channels or 16 channels
+ comedi_error(dev,
+ "chanlist must be channels 0 to 31 in order");
+ err++;
+ break;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int hpdi_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ if (priv(dev)->dio_config_output) {
+ return -EINVAL;
+ } else
+ return di_cmd_test(dev, s, cmd);
+}
+
+static inline void hpdi_writel(struct comedi_device * dev, uint32_t bits,
+ unsigned int offset)
+{
+ writel(bits | priv(dev)->bits[offset / sizeof(uint32_t)],
+ priv(dev)->hpdi_iobase + offset);
+}
+
+static int di_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ uint32_t bits;
+ unsigned long flags;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+
+ hpdi_writel(dev, RX_FIFO_RESET_BIT, BOARD_CONTROL_REG);
+
+ DEBUG_PRINT("hpdi: in di_cmd\n");
+
+ abort_dma(dev, 0);
+
+ priv(dev)->dma_desc_index = 0;
+
+ /* These register are supposedly unused during chained dma,
+ * but I have found that left over values from last operation
+ * occasionally cause problems with transfer of first dma
+ * block. Initializing them to zero seems to fix the problem. */
+ writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
+ writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
+ writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
+ // give location of first dma descriptor
+ bits = priv(dev)->
+ dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
+ PLX_XFER_LOCAL_TO_PCI;
+ writel(bits, priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
+
+ // spinlock for plx dma control/status reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ // enable dma transfer
+ writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ priv(dev)->dio_count = cmd->stop_arg;
+ else
+ priv(dev)->dio_count = 1;
+
+ // clear over/under run status flags
+ writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT,
+ priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
+ // enable interrupts
+ writel(intr_bit(RX_FULL_INTR),
+ priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
+
+ DEBUG_PRINT("hpdi: starting rx\n");
+ hpdi_writel(dev, RX_ENABLE_BIT, BOARD_CONTROL_REG);
+
+ return 0;
+}
+
+static int hpdi_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (priv(dev)->dio_config_output) {
+ return -EINVAL;
+ } else
+ return di_cmd(dev, s);
+}
+
+static void drain_dma_buffers(struct comedi_device * dev, unsigned int channel)
+{
+ struct comedi_async *async = dev->read_subdev->async;
+ uint32_t next_transfer_addr;
+ int j;
+ int num_samples = 0;
+ void *pci_addr_reg;
+
+ if (channel)
+ pci_addr_reg =
+ priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
+ else
+ pci_addr_reg =
+ priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
+
+ // loop until we have read all the full buffers
+ j = 0;
+ for (next_transfer_addr = readl(pci_addr_reg);
+ (next_transfer_addr <
+ le32_to_cpu(priv(dev)->dma_desc[priv(dev)->
+ dma_desc_index].pci_start_addr)
+ || next_transfer_addr >=
+ le32_to_cpu(priv(dev)->dma_desc[priv(dev)->
+ dma_desc_index].pci_start_addr) +
+ priv(dev)->block_size)
+ && j < priv(dev)->num_dma_descriptors; j++) {
+ // transfer data from dma buffer to comedi buffer
+ num_samples = priv(dev)->block_size / sizeof(uint32_t);
+ if (async->cmd.stop_src == TRIG_COUNT) {
+ if (num_samples > priv(dev)->dio_count)
+ num_samples = priv(dev)->dio_count;
+ priv(dev)->dio_count -= num_samples;
+ }
+ cfc_write_array_to_buffer(dev->read_subdev,
+ priv(dev)->desc_dio_buffer[priv(dev)->dma_desc_index],
+ num_samples * sizeof(uint32_t));
+ priv(dev)->dma_desc_index++;
+ priv(dev)->dma_desc_index %= priv(dev)->num_dma_descriptors;
+
+ DEBUG_PRINT("next desc addr 0x%lx\n", (unsigned long)
+ priv(dev)->dma_desc[priv(dev)->dma_desc_index].next);
+ DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
+ }
+ // XXX check for buffer overrun somehow
+}
+
+static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async = s->async;
+ uint32_t hpdi_intr_status, hpdi_board_status;
+ uint32_t plx_status;
+ uint32_t plx_bits;
+ uint8_t dma0_status, dma1_status;
+ unsigned long flags;
+
+ if (!dev->attached) {
+ return IRQ_NONE;
+ }
+
+ plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+ if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0) {
+ return IRQ_NONE;
+ }
+
+ hpdi_intr_status = readl(priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
+ hpdi_board_status = readl(priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
+
+ async->events = 0;
+
+ if (hpdi_intr_status) {
+ DEBUG_PRINT("hpdi: intr status 0x%x, ", hpdi_intr_status);
+ writel(hpdi_intr_status,
+ priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
+ }
+ // spin lock makes sure noone else changes plx dma control reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ if (plx_status & ICS_DMA0_A) { // dma chan 0 interrupt
+ writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+
+ DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
+ if (dma0_status & PLX_DMA_EN_BIT) {
+ drain_dma_buffers(dev, 0);
+ }
+ DEBUG_PRINT(" cleared dma ch0 interrupt\n");
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // spin lock makes sure noone else changes plx dma control reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ if (plx_status & ICS_DMA1_A) // XXX
+ { // dma chan 1 interrupt
+ writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
+
+ DEBUG_PRINT(" cleared dma ch1 interrupt\n");
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // clear possible plx9080 interrupt sources
+ if (plx_status & ICS_LDIA) { // clear local doorbell interrupt
+ plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+ writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+ DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits);
+ }
+
+ if (hpdi_board_status & RX_OVERRUN_BIT) {
+ comedi_error(dev, "rx fifo overrun");
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ DEBUG_PRINT("dma0_status 0x%x\n",
+ (int)readb(priv(dev)->plx9080_iobase +
+ PLX_DMA0_CS_REG));
+ }
+
+ if (hpdi_board_status & RX_UNDERRUN_BIT) {
+ comedi_error(dev, "rx fifo underrun");
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ }
+
+ if (priv(dev)->dio_count == 0)
+ async->events |= COMEDI_CB_EOA;
+
+ DEBUG_PRINT("board status 0x%x, ", hpdi_board_status);
+ DEBUG_PRINT("plx status 0x%x\n", plx_status);
+ if (async->events)
+ DEBUG_PRINT(" events 0x%x\n", async->events);
+
+ cfc_handle_events(dev, s);
+
+ return IRQ_HANDLED;
+}
+
+void abort_dma(struct comedi_device * dev, unsigned int channel)
+{
+ unsigned long flags;
+
+ // spinlock for plx dma control/status reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+ plx9080_abort_dma(priv(dev)->plx9080_iobase, channel);
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static int hpdi_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ hpdi_writel(dev, 0, BOARD_CONTROL_REG);
+
+ writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
+
+ abort_dma(dev, 0);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c
index 59144d7cb0b..15fce0190b2 100644
--- a/drivers/staging/comedi/drivers/icp_multi.c
+++ b/drivers/staging/comedi/drivers/icp_multi.c
@@ -61,7 +61,7 @@ Options:
#define ICP_MULTI_EXTDEBUG
-// Hardware types of the cards
+/* Hardware types of the cards */
#define TYPE_ICP_MULTI 0
#define IORANGE_ICP_MULTI 32
@@ -81,20 +81,20 @@ Options:
#define ICP_MULTI_SIZE 0x20 /* 32 bytes */
-// Define bits from ADC command/status register
+/* Define bits from ADC command/status register */
#define ADC_ST 0x0001 /* Start ADC */
#define ADC_BSY 0x0001 /* ADC busy */
#define ADC_BI 0x0010 /* Bipolar input range 1 = bipolar */
#define ADC_RA 0x0020 /* Input range 0 = 5V, 1 = 10V */
#define ADC_DI 0x0040 /* Differential input mode 1 = differential */
-// Define bits from DAC command/status register
+/* Define bits from DAC command/status register */
#define DAC_ST 0x0001 /* Start DAC */
#define DAC_BSY 0x0001 /* DAC busy */
#define DAC_BI 0x0010 /* Bipolar input range 1 = bipolar */
#define DAC_RA 0x0020 /* Input range 0 = 5V, 1 = 10V */
-// Define bits from interrupt enable/status registers
+/* Define bits from interrupt enable/status registers */
#define ADC_READY 0x0001 /* A/d conversion ready interrupt */
#define DAC_READY 0x0002 /* D/a conversion ready interrupt */
#define DOUT_ERROR 0x0004 /* Digital output error interrupt */
@@ -104,11 +104,11 @@ Options:
#define CIE2 0x0040 /* Counter 2 overrun interrupt */
#define CIE3 0x0080 /* Counter 3 overrun interrupt */
-// Useful definitions
-#define Status_IRQ 0x00ff // All interrupts
+/* Useful definitions */
+#define Status_IRQ 0x00ff /* All interrupts */
-// Define analogue range
-static const comedi_lrange range_analog = { 4, {
+/* Define analogue range */
+static const struct comedi_lrange range_analog = { 4, {
UNI_RANGE(5),
UNI_RANGE(10),
BIP_RANGE(5),
@@ -123,8 +123,8 @@ static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 };
Forward declarations
==============================================================================
*/
-static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it);
-static int icp_multi_detach(comedi_device * dev);
+static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int icp_multi_detach(struct comedi_device *dev);
/*
==============================================================================
@@ -133,79 +133,79 @@ static int icp_multi_detach(comedi_device * dev);
*/
static unsigned short pci_list_builded = 0; /*>0 list of card is known */
-typedef struct {
- const char *name; // driver name
+struct boardtype {
+ const char *name; /* driver name */
int device_id;
- int iorange; // I/O range len
- char have_irq; // 1=card support IRQ
- char cardtype; // 0=ICP Multi
- int n_aichan; // num of A/D chans
- int n_aichand; // num of A/D chans in diff mode
- int n_aochan; // num of D/A chans
- int n_dichan; // num of DI chans
- int n_dochan; // num of DO chans
- int n_ctrs; // num of counters
- int ai_maxdata; // resolution of A/D
- int ao_maxdata; // resolution of D/A
- const comedi_lrange *rangelist_ai; // rangelist for A/D
- const char *rangecode; // range codes for programming
- const comedi_lrange *rangelist_ao; // rangelist for D/A
-} boardtype;
-
-static const boardtype boardtypes[] = {
- {"icp_multi", // Driver name
- DEVICE_ID, // PCI device ID
- IORANGE_ICP_MULTI, // I/O range length
- 1, // 1=Card supports interrupts
- TYPE_ICP_MULTI, // Card type = ICP MULTI
- 16, // Num of A/D channels
- 8, // Num of A/D channels in diff mode
- 4, // Num of D/A channels
- 16, // Num of digital inputs
- 8, // Num of digital outputs
- 4, // Num of counters
- 0x0fff, // Resolution of A/D
- 0x0fff, // Resolution of D/A
- &range_analog, // Rangelist for A/D
- range_codes_analog, // Range codes for programming
- &range_analog}, // Rangelist for D/A
+ int iorange; /* I/O range len */
+ char have_irq; /* 1=card support IRQ */
+ char cardtype; /* 0=ICP Multi */
+ int n_aichan; /* num of A/D chans */
+ int n_aichand; /* num of A/D chans in diff mode */
+ int n_aochan; /* num of D/A chans */
+ int n_dichan; /* num of DI chans */
+ int n_dochan; /* num of DO chans */
+ int n_ctrs; /* num of counters */
+ int ai_maxdata; /* resolution of A/D */
+ int ao_maxdata; /* resolution of D/A */
+ const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */
+ const char *rangecode; /* range codes for programming */
+ const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */
};
-#define n_boardtypes (sizeof(boardtypes)/sizeof(boardtype))
+static const struct boardtype boardtypes[] = {
+ {"icp_multi", /* Driver name */
+ DEVICE_ID, /* PCI device ID */
+ IORANGE_ICP_MULTI, /* I/O range length */
+ 1, /* 1=Card supports interrupts */
+ TYPE_ICP_MULTI, /* Card type = ICP MULTI */
+ 16, /* Num of A/D channels */
+ 8, /* Num of A/D channels in diff mode */
+ 4, /* Num of D/A channels */
+ 16, /* Num of digital inputs */
+ 8, /* Num of digital outputs */
+ 4, /* Num of counters */
+ 0x0fff, /* Resolution of A/D */
+ 0x0fff, /* Resolution of D/A */
+ &range_analog, /* Rangelist for A/D */
+ range_codes_analog, /* Range codes for programming */
+ &range_analog}, /* Rangelist for D/A */
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
-static comedi_driver driver_icp_multi = {
+static struct comedi_driver driver_icp_multi = {
driver_name:"icp_multi",
- module:THIS_MODULE,
- attach:icp_multi_attach,
- detach:icp_multi_detach,
- num_names:n_boardtypes,
- board_name:&boardtypes[0].name,
- offset:sizeof(boardtype),
+ module : THIS_MODULE,
+ attach : icp_multi_attach,
+ detach : icp_multi_detach,
+ num_names : n_boardtypes,
+ board_name : &boardtypes[0].name,
+ offset : sizeof(struct boardtype),
};
COMEDI_INITCLEANUP(driver_icp_multi);
-typedef struct {
- struct pcilst_struct *card; // pointer to card
- char valid; // card is usable
- void *io_addr; // Pointer to mapped io address
- resource_size_t phys_iobase; // Physical io address
- unsigned int AdcCmdStatus; // ADC Command/Status register
- unsigned int DacCmdStatus; // DAC Command/Status register
- unsigned int IntEnable; // Interrupt Enable register
- unsigned int IntStatus; // Interrupt Status register
- unsigned int act_chanlist[32]; // list of scaned channel
- unsigned char act_chanlist_len; // len of scanlist
- unsigned char act_chanlist_pos; // actual position in MUX list
- unsigned int *ai_chanlist; // actaul chanlist
- sampl_t *ai_data; // data buffer
- sampl_t ao_data[4]; // data output buffer
- sampl_t di_data; // Digital input data
- unsigned int do_data; // Remember digital output data
-} icp_multi_private;
-
-#define devpriv ((icp_multi_private *)dev->private)
-#define this_board ((const boardtype *)dev->board_ptr)
+struct icp_multi_private {
+ struct pcilst_struct *card; /* pointer to card */
+ char valid; /* card is usable */
+ void *io_addr; /* Pointer to mapped io address */
+ resource_size_t phys_iobase; /* Physical io address */
+ unsigned int AdcCmdStatus; /* ADC Command/Status register */
+ unsigned int DacCmdStatus; /* DAC Command/Status register */
+ unsigned int IntEnable; /* Interrupt Enable register */
+ unsigned int IntStatus; /* Interrupt Status register */
+ unsigned int act_chanlist[32]; /* list of scaned channel */
+ unsigned char act_chanlist_len; /* len of scanlist */
+ unsigned char act_chanlist_pos; /* actual position in MUX list */
+ unsigned int *ai_chanlist; /* actaul chanlist */
+ short *ai_data; /* data buffer */
+ short ao_data[4]; /* data output buffer */
+ short di_data; /* Digital input data */
+ unsigned int do_data; /* Remember digital output data */
+};
+
+#define devpriv ((struct icp_multi_private *)dev->private)
+#define this_board ((const struct boardtype *)dev->board_ptr)
/*
==============================================================================
@@ -214,12 +214,12 @@ typedef struct {
*/
#if 0
-static int check_channel_list(comedi_device * dev, comedi_subdevice * s,
+static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int *chanlist, unsigned int n_chan);
#endif
-static void setup_channel_list(comedi_device * dev, comedi_subdevice * s,
+static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int *chanlist, unsigned int n_chan);
-static int icp_multi_reset(comedi_device * dev);
+static int icp_multi_reset(struct comedi_device *dev);
/*
==============================================================================
@@ -236,32 +236,32 @@ static int icp_multi_reset(comedi_device * dev);
This function reads a single analogue input.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to analogue input data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to analogue input data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_read_ai(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n, timeout;
#ifdef ICP_MULTI_EXTDEBUG
printk("icp multi EDBG: BGN: icp_multi_insn_read_ai(...)\n");
#endif
- // Disable A/D conversion ready interrupt
+ /* Disable A/D conversion ready interrupt */
devpriv->IntEnable &= ~ADC_READY;
writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
- // Clear interrupt status
+ /* Clear interrupt status */
devpriv->IntStatus |= ADC_READY;
writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
- // Set up appropriate channel, mode and range data, for specified channel
+ /* Set up appropriate channel, mode and range data, for specified channel */
setup_channel_list(dev, s, &insn->chanspec, 1);
#ifdef ICP_MULTI_EXTDEBUG
@@ -271,7 +271,7 @@ static int icp_multi_insn_read_ai(comedi_device * dev, comedi_subdevice * s,
#endif
for (n = 0; n < insn->n; n++) {
- // Set start ADC bit
+ /* Set start ADC bit */
devpriv->AdcCmdStatus |= ADC_ST;
writew(devpriv->AdcCmdStatus,
devpriv->io_addr + ICP_MULTI_ADC_CSR);
@@ -289,7 +289,7 @@ static int icp_multi_insn_read_ai(comedi_device * dev, comedi_subdevice * s,
readw(devpriv->io_addr + ICP_MULTI_ADC_CSR));
#endif
- // Wait for conversion to complete, or get fed up waiting
+ /* Wait for conversion to complete, or get fed up waiting */
timeout = 100;
while (timeout--) {
if (!(readw(devpriv->io_addr +
@@ -307,19 +307,19 @@ static int icp_multi_insn_read_ai(comedi_device * dev, comedi_subdevice * s,
comedi_udelay(1);
}
- // If we reach here, a timeout has occurred
+ /* If we reach here, a timeout has occurred */
comedi_error(dev, "A/D insn timeout");
- // Disable interrupt
+ /* Disable interrupt */
devpriv->IntEnable &= ~ADC_READY;
writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
- // Clear interrupt status
+ /* Clear interrupt status */
devpriv->IntStatus |= ADC_READY;
writew(devpriv->IntStatus,
devpriv->io_addr + ICP_MULTI_INT_STAT);
- // Clear data received
+ /* Clear data received */
data[n] = 0;
#ifdef ICP_MULTI_EXTDEBUG
@@ -332,11 +332,11 @@ static int icp_multi_insn_read_ai(comedi_device * dev, comedi_subdevice * s,
(readw(devpriv->io_addr + ICP_MULTI_AI) >> 4) & 0x0fff;
}
- // Disable interrupt
+ /* Disable interrupt */
devpriv->IntEnable &= ~ADC_READY;
writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
- // Clear interrupt status
+ /* Clear interrupt status */
devpriv->IntStatus |= ADC_READY;
writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
@@ -355,40 +355,40 @@ static int icp_multi_insn_read_ai(comedi_device * dev, comedi_subdevice * s,
This function writes a single analogue output.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to analogue output data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to analogue output data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_write_ao(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n, chan, range, timeout;
#ifdef ICP_MULTI_EXTDEBUG
printk("icp multi EDBG: BGN: icp_multi_insn_write_ao(...)\n");
#endif
- // Disable D/A conversion ready interrupt
+ /* Disable D/A conversion ready interrupt */
devpriv->IntEnable &= ~DAC_READY;
writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
- // Clear interrupt status
+ /* Clear interrupt status */
devpriv->IntStatus |= DAC_READY;
writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
- // Get channel number and range
+ /* Get channel number and range */
chan = CR_CHAN(insn->chanspec);
range = CR_RANGE(insn->chanspec);
- // Set up range and channel data
- // Bit 4 = 1 : Bipolar
- // Bit 5 = 0 : 5V
- // Bit 5 = 1 : 10V
- // Bits 8-9 : Channel number
+ /* Set up range and channel data */
+ /* Bit 4 = 1 : Bipolar */
+ /* Bit 5 = 0 : 5V */
+ /* Bit 5 = 1 : 10V */
+ /* Bits 8-9 : Channel number */
devpriv->DacCmdStatus &= 0xfccf;
devpriv->DacCmdStatus |= this_board->rangecode[range];
devpriv->DacCmdStatus |= (chan << 8);
@@ -396,7 +396,7 @@ static int icp_multi_insn_write_ao(comedi_device * dev, comedi_subdevice * s,
writew(devpriv->DacCmdStatus, devpriv->io_addr + ICP_MULTI_DAC_CSR);
for (n = 0; n < insn->n; n++) {
- // Wait for analogue output data register to be ready for new data, or get fed up waiting
+ /* Wait for analogue output data register to be ready for new data, or get fed up waiting */
timeout = 100;
while (timeout--) {
if (!(readw(devpriv->io_addr +
@@ -414,19 +414,19 @@ static int icp_multi_insn_write_ao(comedi_device * dev, comedi_subdevice * s,
comedi_udelay(1);
}
- // If we reach here, a timeout has occurred
+ /* If we reach here, a timeout has occurred */
comedi_error(dev, "D/A insn timeout");
- // Disable interrupt
+ /* Disable interrupt */
devpriv->IntEnable &= ~DAC_READY;
writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
- // Clear interrupt status
+ /* Clear interrupt status */
devpriv->IntStatus |= DAC_READY;
writew(devpriv->IntStatus,
devpriv->io_addr + ICP_MULTI_INT_STAT);
- // Clear data received
+ /* Clear data received */
devpriv->ao_data[chan] = 0;
#ifdef ICP_MULTI_EXTDEBUG
@@ -435,16 +435,16 @@ static int icp_multi_insn_write_ao(comedi_device * dev, comedi_subdevice * s,
return -ETIME;
dac_ready:
- // Write data to analogue output data register
+ /* Write data to analogue output data register */
writew(data[n], devpriv->io_addr + ICP_MULTI_AO);
- // Set DAC_ST bit to write the data to selected channel
+ /* Set DAC_ST bit to write the data to selected channel */
devpriv->DacCmdStatus |= DAC_ST;
writew(devpriv->DacCmdStatus,
devpriv->io_addr + ICP_MULTI_DAC_CSR);
devpriv->DacCmdStatus &= ~DAC_ST;
- // Save analogue output data
+ /* Save analogue output data */
devpriv->ao_data[chan] = data[n];
}
@@ -463,24 +463,24 @@ static int icp_multi_insn_write_ao(comedi_device * dev, comedi_subdevice * s,
This function reads a single analogue output.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to analogue output data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to analogue output data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_read_ao(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n, chan;
- // Get channel number
+ /* Get channel number */
chan = CR_CHAN(insn->chanspec);
- // Read analogue outputs
+ /* Read analogue outputs */
for (n = 0; n < insn->n; n++)
data[n] = devpriv->ao_data[chan];
@@ -496,17 +496,17 @@ static int icp_multi_insn_read_ao(comedi_device * dev, comedi_subdevice * s,
This function reads the digital inputs.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to analogue output data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to analogue output data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_bits_di(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
data[1] = readw(devpriv->io_addr + ICP_MULTI_DI);
@@ -522,17 +522,17 @@ static int icp_multi_insn_bits_di(comedi_device * dev, comedi_subdevice * s,
This function writes the appropriate digital outputs.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to analogue output data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to analogue output data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_bits_do(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
#ifdef ICP_MULTI_EXTDEBUG
printk("icp multi EDBG: BGN: icp_multi_insn_bits_do(...)\n");
@@ -564,17 +564,17 @@ static int icp_multi_insn_bits_do(comedi_device * dev, comedi_subdevice * s,
This function reads the specified counter.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to counter data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to counter data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_read_ctr(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_read_ctr(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
return 0;
}
@@ -588,17 +588,17 @@ static int icp_multi_insn_read_ctr(comedi_device * dev, comedi_subdevice * s,
This function write to the specified counter.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to counter data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to counter data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_write_ctr(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_write_ctr(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
return 0;
}
@@ -620,7 +620,7 @@ static int icp_multi_insn_write_ctr(comedi_device * dev, comedi_subdevice * s,
*/
static irqreturn_t interrupt_service_icp_multi(int irq, void *d PT_REGS_ARG)
{
- comedi_device *dev = d;
+ struct comedi_device *dev = d;
int int_no;
#ifdef ICP_MULTI_EXTDEBUG
@@ -628,10 +628,10 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d PT_REGS_ARG)
irq);
#endif
- // Is this interrupt from our board?
+ /* Is this interrupt from our board? */
int_no = readw(devpriv->io_addr + ICP_MULTI_INT_STAT) & Status_IRQ;
if (!int_no)
- // No, exit
+ /* No, exit */
return IRQ_NONE;
#ifdef ICP_MULTI_EXTDEBUG
@@ -639,7 +639,7 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d PT_REGS_ARG)
readw(devpriv->io_addr + ICP_MULTI_INT_STAT));
#endif
- // Determine which interrupt is active & handle it
+ /* Determine which interrupt is active & handle it */
switch (int_no) {
case ADC_READY:
break;
@@ -679,8 +679,8 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d PT_REGS_ARG)
is built correctly
Parameters:
- comedi_device *dev Pointer to current sevice structure
- comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_device *dev Pointer to current sevice structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
unsigned int *chanlist Pointer to packed channel list
unsigned int n_chan Number of channels to scan
@@ -689,7 +689,7 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d PT_REGS_ARG)
==============================================================================
*/
-static int check_channel_list(comedi_device * dev, comedi_subdevice * s,
+static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int *chanlist, unsigned int n_chan)
{
unsigned int i;
@@ -697,14 +697,14 @@ static int check_channel_list(comedi_device * dev, comedi_subdevice * s,
#ifdef ICP_MULTI_EXTDEBUG
printk("icp multi EDBG: check_channel_list(...,%d)\n", n_chan);
#endif
- // Check that we at least have one channel to check
+ /* Check that we at least have one channel to check */
if (n_chan < 1) {
comedi_error(dev, "range/channel list is empty!");
return 0;
}
- // Check all channels
+ /* Check all channels */
for (i = 0; i < n_chan; i++) {
- // Check that channel number is < maximum
+ /* Check that channel number is < maximum */
if (CR_AREF(chanlist[i]) == AREF_DIFF) {
if (CR_CHAN(chanlist[i]) > this_board->n_aichand) {
comedi_error(dev,
@@ -734,8 +734,8 @@ static int check_channel_list(comedi_device * dev, comedi_subdevice * s,
Status register.
Parameters:
- comedi_device *dev Pointer to current sevice structure
- comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_device *dev Pointer to current sevice structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
unsigned int *chanlist Pointer to packed channel list
unsigned int n_chan Number of channels to scan
@@ -743,7 +743,7 @@ static int check_channel_list(comedi_device * dev, comedi_subdevice * s,
==============================================================================
*/
-static void setup_channel_list(comedi_device * dev, comedi_subdevice * s,
+static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int *chanlist, unsigned int n_chan)
{
unsigned int i, range, chanprog;
@@ -756,10 +756,10 @@ static void setup_channel_list(comedi_device * dev, comedi_subdevice * s,
devpriv->act_chanlist_pos = 0;
for (i = 0; i < n_chan; i++) {
- // Get channel
+ /* Get channel */
chanprog = CR_CHAN(chanlist[i]);
- // Determine if it is a differential channel (Bit 15 = 1)
+ /* Determine if it is a differential channel (Bit 15 = 1) */
if (CR_AREF(chanlist[i]) == AREF_DIFF) {
diff = 1;
chanprog &= 0x0007;
@@ -768,21 +768,21 @@ static void setup_channel_list(comedi_device * dev, comedi_subdevice * s,
chanprog &= 0x000f;
}
- // Clear channel, range and input mode bits in A/D command/status register
+ /* Clear channel, range and input mode bits in A/D command/status register */
devpriv->AdcCmdStatus &= 0xf00f;
- // Set channel number and differential mode status bit
+ /* Set channel number and differential mode status bit */
if (diff) {
- // Set channel number, bits 9-11 & mode, bit 6
+ /* Set channel number, bits 9-11 & mode, bit 6 */
devpriv->AdcCmdStatus |= (chanprog << 9);
devpriv->AdcCmdStatus |= ADC_DI;
} else
- // Set channel number, bits 8-11
+ /* Set channel number, bits 8-11 */
devpriv->AdcCmdStatus |= (chanprog << 8);
- // Get range for current channel
+ /* Get range for current channel */
range = this_board->rangecode[CR_RANGE(chanlist[i])];
- // Set range. bits 4-5
+ /* Set range. bits 4-5 */
devpriv->AdcCmdStatus |= range;
/* Output channel, range, mode to ICP Multi */
@@ -806,45 +806,45 @@ static void setup_channel_list(comedi_device * dev, comedi_subdevice * s,
This function resets the icp multi device to a 'safe' state
Parameters:
- comedi_device *dev Pointer to current sevice structure
+ struct comedi_device *dev Pointer to current sevice structure
Returns:int 0 = success
==============================================================================
*/
-static int icp_multi_reset(comedi_device * dev)
+static int icp_multi_reset(struct comedi_device *dev)
{
unsigned int i;
#ifdef ICP_MULTI_EXTDEBUG
printk("icp_multi EDBG: BGN: icp_multi_reset(...)\n");
#endif
- // Clear INT enables and requests
+ /* Clear INT enables and requests */
writew(0, devpriv->io_addr + ICP_MULTI_INT_EN);
writew(0x00ff, devpriv->io_addr + ICP_MULTI_INT_STAT);
if (this_board->n_aochan)
- // Set DACs to 0..5V range and 0V output
+ /* Set DACs to 0..5V range and 0V output */
for (i = 0; i < this_board->n_aochan; i++) {
devpriv->DacCmdStatus &= 0xfcce;
- // Set channel number
+ /* Set channel number */
devpriv->DacCmdStatus |= (i << 8);
- // Output 0V
+ /* Output 0V */
writew(0, devpriv->io_addr + ICP_MULTI_AO);
- // Set start conversion bit
+ /* Set start conversion bit */
devpriv->DacCmdStatus |= DAC_ST;
- // Output to command / status register
+ /* Output to command / status register */
writew(devpriv->DacCmdStatus,
devpriv->io_addr + ICP_MULTI_DAC_CSR);
- // Delay to allow DAC time to recover
+ /* Delay to allow DAC time to recover */
comedi_udelay(1);
}
- // Digital outputs to 0
+ /* Digital outputs to 0 */
writew(0, devpriv->io_addr + ICP_MULTI_DO);
#ifdef ICP_MULTI_EXTDEBUG
@@ -863,16 +863,16 @@ static int icp_multi_reset(comedi_device * dev)
device.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_devconfig *it Pointer to current device configuration
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_devconfig *it Pointer to current device configuration
Returns:int 0 = success
==============================================================================
*/
-static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it)
+static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
int ret, subdev, n_subdevices;
unsigned int irq;
struct pcilst_struct *card = NULL;
@@ -881,11 +881,12 @@ static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it)
printk("icp_multi EDBG: BGN: icp_multi_attach(...)\n");
- // Alocate private data storage space
- if ((ret = alloc_private(dev, sizeof(icp_multi_private))) < 0)
+ /* Alocate private data storage space */
+ ret = alloc_private(dev, sizeof(struct icp_multi_private));
+ if (ret < 0)
return ret;
- // Initialise list of PCI cards in system, if not already done so
+ /* Initialise list of PCI cards in system, if not already done so */
if (pci_list_builded++ == 0) {
pci_card_list_init(PCI_VENDOR_ID_ICP,
#ifdef ICP_MULTI_EXTDEBUG
@@ -899,9 +900,11 @@ static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it)
printk("Anne's comedi%d: icp_multi: board=%s", dev->minor,
this_board->name);
- if ((card = select_and_alloc_pci_card(PCI_VENDOR_ID_ICP,
- this_board->device_id, it->options[0],
- it->options[1])) == NULL)
+ card = select_and_alloc_pci_card(PCI_VENDOR_ID_ICP,
+ this_board->device_id, it->options[0],
+ it->options[1]);
+
+ if (card == NULL)
return -EIO;
devpriv->card = card;
@@ -943,9 +946,9 @@ static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it)
if (this_board->n_ctrs)
n_subdevices++;
- if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+ ret = alloc_subdevices(dev, n_subdevices);
+ if (ret < 0)
return ret;
- }
icp_multi_reset(dev);
@@ -1055,13 +1058,13 @@ static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it)
device.
Parameters:
- comedi_device *dev Pointer to current device structure
+ struct comedi_device *dev Pointer to current device structure
Returns:int 0 = success
==============================================================================
*/
-static int icp_multi_detach(comedi_device * dev)
+static int icp_multi_detach(struct comedi_device *dev)
{
if (dev->private)
@@ -1077,9 +1080,8 @@ static int icp_multi_detach(comedi_device * dev)
if (dev->private && devpriv->card)
pci_card_free(devpriv->card);
- if (--pci_list_builded == 0) {
+ if (--pci_list_builded == 0)
pci_card_list_cleanup(PCI_VENDOR_ID_ICP);
- }
return 0;
}
diff --git a/drivers/staging/comedi/drivers/icp_multi.h b/drivers/staging/comedi/drivers/icp_multi.h
index 6df4a8d15ff..21d84766fea 100644
--- a/drivers/staging/comedi/drivers/icp_multi.h
+++ b/drivers/staging/comedi/drivers/icp_multi.h
@@ -28,7 +28,8 @@ struct pcilst_struct {
unsigned int irq;
};
-struct pcilst_struct *inova_devices; // ptr to root list of all Inova devices
+struct pcilst_struct *inova_devices;
+/* ptr to root list of all Inova devices */
/****************************************************************************/
@@ -150,14 +151,14 @@ static int find_free_pci_card_by_position(unsigned short vendor_id,
&& (inova->pci_slot == pci_slot)) {
if (!(inova->used)) {
*card = inova;
- return 0; // ok, card is found
+ return 0; /* ok, card is found */
} else {
- return 2; // card exist but is used
+ return 2; /* card exist but is used */
}
}
}
- return 1; // no card found
+ return 1; /* no card found */
}
/****************************************************************************/
@@ -243,9 +244,10 @@ static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id,
struct pcilst_struct *card;
int err;
- if ((pci_bus < 1) & (pci_slot < 1)) { // use autodetection
- if ((card = find_free_pci_card_by_device(vendor_id,
- device_id)) == NULL) {
+ if ((pci_bus < 1) & (pci_slot < 1)) { /* use autodetection */
+
+ card = find_free_pci_card_by_device(vendor_id, device_id);
+ if (card == NULL) {
rt_printk(" - Unused card not found in system!\n");
return NULL;
}
@@ -265,7 +267,8 @@ static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id,
}
}
- if ((err = pci_card_alloc(card)) != 0) {
+ err = pci_card_alloc(card);
+ if (err != 0) {
if (err > 0)
rt_printk(" - Can't allocate card!\n");
/* else: error already printed. */
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
new file mode 100644
index 00000000000..80825ba2541
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -0,0 +1,612 @@
+/*
+ * comedi/drivers/ii_pci20kc.c
+ * Driver for Intelligent Instruments PCI-20001C carrier board
+ * and modules.
+ *
+ * Copyright (C) 2000 Markus Kempf <kempf@matsci.uni-sb.de>
+ * with suggestions from David Schleef
+ * 16.06.2000
+ *
+ * Linux device driver for COMEDI
+ * Intelligent Instrumentation
+ * PCI-20001 C-2A Carrier Board
+ * PCI-20341 M-1A 16-Bit analog input module
+ * - differential
+ * - range (-5V - +5V)
+ * - 16 bit
+ * PCI-20006 M-2 16-Bit analog output module
+ * - ranges (-10V - +10V) (0V - +10V) (-5V - +5V)
+ * - 16 bit
+ *
+ * only ONE PCI-20341 module possible
+ * only ONE PCI-20006 module possible
+ * no extern trigger implemented
+ *
+ * NOT WORKING (but soon) only 4 on-board differential channels supported
+ * NOT WORKING (but soon) only ONE di-port and ONE do-port supported instead of 4 digital ports
+ * di-port == Port 0
+ * do-port == Port 1
+ *
+ * The state of this driver is only a starting point for a complete
+ * COMEDI-driver. The final driver should support all features of the
+ * carrier board and modules.
+ *
+ * The test configuration:
+ *
+ * kernel 2.2.14 with RTAI v1.2 and patch-2.2.14rthal2
+ * COMEDI 0.7.45
+ * COMEDILIB 0.7.9
+ *
+ */
+/*
+Driver: ii_pci20kc
+Description: Intelligent Instruments PCI-20001C carrier board
+Author: Markus Kempf <kempf@matsci.uni-sb.de>
+Devices: [Intelligent Instrumentation] PCI-20001C (ii_pci20kc)
+Status: works
+
+Supports the PCI-20001 C-2a Carrier board, and could probably support
+the other carrier boards with small modifications. Modules supported
+are:
+ PCI-20006 M-2 16-bit analog output module
+ PCI-20341 M-1A 16-bit analog input module
+
+Options:
+ 0 Board base address
+ 1 IRQ
+ 2 first option for module 1
+ 3 second option for module 1
+ 4 first option for module 2
+ 5 second option for module 2
+ 6 first option for module 3
+ 7 second option for module 3
+
+options for PCI-20006M:
+ first: Analog output channel 0 range configuration
+ 0 bipolar 10 (-10V -- +10V)
+ 1 unipolar 10 (0V -- +10V)
+ 2 bipolar 5 (-5V -- 5V)
+ second: Analog output channel 1 range configuration
+
+options for PCI-20341M:
+ first: Analog input gain configuration
+ 0 1
+ 1 10
+ 2 100
+ 3 200
+*/
+
+/* XXX needs to use ioremap() for compatibility with 2.4 kernels. Should also
+ * check_mem_region() etc. - fmhess */
+
+#include "../comedidev.h"
+
+#define PCI20000_ID 0x1d
+#define PCI20341_ID 0x77
+#define PCI20006_ID 0xe3
+#define PCI20xxx_EMPTY_ID 0xff
+
+#define PCI20000_OFFSET 0x100
+#define PCI20000_MODULES 3
+
+#define PCI20000_DIO_0 0x80
+#define PCI20000_DIO_1 0x81
+#define PCI20000_DIO_2 0xc0
+#define PCI20000_DIO_3 0xc1
+#define PCI20000_DIO_CONTROL_01 0x83 /* port 0, 1 control */
+#define PCI20000_DIO_CONTROL_23 0xc3 /* port 2, 3 control */
+#define PCI20000_DIO_BUFFER 0x82 /* buffer direction and enable */
+#define PCI20000_DIO_EOC 0xef /* even port, control output */
+#define PCI20000_DIO_OOC 0xfd /* odd port, control output */
+#define PCI20000_DIO_EIC 0x90 /* even port, control input */
+#define PCI20000_DIO_OIC 0x82 /* odd port, control input */
+#define DIO_CAND 0x12 /* and bit 1, bit 4 of control */
+#define DIO_BE 0x01 /* buffer: port enable */
+#define DIO_BO 0x04 /* buffer: output */
+#define DIO_BI 0x05 /* buffer: input */
+#define DIO_PS_0 0x00 /* buffer: port shift 0 */
+#define DIO_PS_1 0x01 /* buffer: port shift 1 */
+#define DIO_PS_2 0x04 /* buffer: port shift 2 */
+#define DIO_PS_3 0x05 /* buffer: port shift 3 */
+
+#define PCI20006_LCHAN0 0x0d
+#define PCI20006_STROBE0 0x0b
+#define PCI20006_LCHAN1 0x15
+#define PCI20006_STROBE1 0x13
+
+#define PCI20341_INIT 0x04
+#define PCI20341_REPMODE 0x00 /* single shot mode */
+#define PCI20341_PACER 0x00 /* Hardware Pacer disabled */
+#define PCI20341_CHAN_NR 0x04 /* number of input channels */
+#define PCI20341_CONFIG_REG 0x10
+#define PCI20341_MOD_STATUS 0x01
+#define PCI20341_OPT_REG 0x11
+#define PCI20341_SET_TIME_REG 0x15
+#define PCI20341_LCHAN_ADDR_REG 0x13
+#define PCI20341_CHAN_LIST 0x80
+#define PCI20341_CC_RESET 0x1b
+#define PCI20341_CHAN_RESET 0x19
+#define PCI20341_SOFT_PACER 0x04
+#define PCI20341_STATUS_REG 0x12
+#define PCI20341_LDATA 0x02
+#define PCI20341_DAISY_CHAIN 0x20 /* On-board inputs only */
+#define PCI20341_MUX 0x04 /* Enable on-board MUX */
+#define PCI20341_SCANLIST 0x80 /* Channel/Gain Scan List */
+
+union pci20xxx_subdev_private {
+ void *iobase;
+ struct {
+ void *iobase;
+ const struct comedi_lrange *ao_range_list[2]; /* range of channels of ao module */
+ unsigned int last_data[2];
+ } pci20006;
+ struct {
+ void *iobase;
+ int timebase;
+ int settling_time;
+ int ai_gain;
+ } pci20341;
+};
+
+struct pci20xxx_private {
+
+ void *ioaddr;
+ union pci20xxx_subdev_private subdev_private[PCI20000_MODULES];
+};
+
+
+#define devpriv ((struct pci20xxx_private *)dev->private)
+#define CHAN (CR_CHAN(it->chanlist[0]))
+
+static int pci20xxx_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci20xxx_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_pci20xxx = {
+ driver_name:"ii_pci20kc",
+ module:THIS_MODULE,
+ attach:pci20xxx_attach,
+ detach:pci20xxx_detach,
+};
+
+static int pci20006_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ int opt0, int opt1);
+static int pci20341_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ int opt0, int opt1);
+static int pci20xxx_dio_init(struct comedi_device * dev, struct comedi_subdevice * s);
+
+/*
+ options[0] Board base address
+ options[1] IRQ
+ options[2] first option for module 1
+ options[3] second option for module 1
+ options[4] first option for module 2
+ options[5] second option for module 2
+ options[6] first option for module 3
+ options[7] second option for module 3
+
+ options for PCI-20341M:
+ first Analog input gain configuration
+ 0 == 1
+ 1 == 10
+ 2 == 100
+ 3 == 200
+
+ options for PCI-20006M:
+ first Analog output channel 0 range configuration
+ 0 == bipolar 10 (-10V -- +10V)
+ 1 == unipolar 10V (0V -- +10V)
+ 2 == bipolar 5V (-5V -- +5V)
+ second Analog output channel 1 range configuration
+ 0 == bipolar 10 (-10V -- +10V)
+ 1 == unipolar 10V (0V -- +10V)
+ 2 == bipolar 5V (-5V -- +5V)
+*/
+static int pci20xxx_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned char i;
+ int ret;
+ int id;
+ struct comedi_subdevice *s;
+ union pci20xxx_subdev_private *sdp;
+
+ if ((ret = alloc_subdevices(dev, 1 + PCI20000_MODULES)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct pci20xxx_private))) < 0)
+ return ret;
+
+ devpriv->ioaddr = (void *)(unsigned long)it->options[0];
+ dev->board_name = "pci20kc";
+
+ /* Check PCI-20001 C-2A Carrier Board ID */
+ if ((readb(devpriv->ioaddr) & PCI20000_ID) != PCI20000_ID) {
+ printk("comedi%d: ii_pci20kc", dev->minor);
+ printk(" PCI-20001 C-2A Carrier Board at base=0x%p not found !\n", devpriv->ioaddr);
+ return -EINVAL;
+ }
+ printk("comedi%d:\n", dev->minor);
+ printk("ii_pci20kc: PCI-20001 C-2A at base=0x%p\n", devpriv->ioaddr);
+
+ for (i = 0; i < PCI20000_MODULES; i++) {
+ s = dev->subdevices + i;
+ id = readb(devpriv->ioaddr + (i + 1) * PCI20000_OFFSET);
+ s->private = devpriv->subdev_private + i;
+ sdp = s->private;
+ switch (id) {
+ case PCI20006_ID:
+ sdp->pci20006.iobase =
+ devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
+ pci20006_init(dev, s, it->options[2 * i + 2],
+ it->options[2 * i + 3]);
+ printk("comedi%d: ii_pci20kc", dev->minor);
+ printk(" PCI-20006 module in slot %d \n", i + 1);
+ break;
+ case PCI20341_ID:
+ sdp->pci20341.iobase =
+ devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
+ pci20341_init(dev, s, it->options[2 * i + 2],
+ it->options[2 * i + 3]);
+ printk("comedi%d: ii_pci20kc", dev->minor);
+ printk(" PCI-20341 module in slot %d \n", i + 1);
+ break;
+ default:
+ printk("ii_pci20kc: unknown module code 0x%02x in slot %d: module disabled\n", id, i);
+ /* fall through */
+ case PCI20xxx_EMPTY_ID:
+ s->type = COMEDI_SUBD_UNUSED;
+ break;
+ }
+ }
+
+ /* initialize struct pci20xxx_private */
+ pci20xxx_dio_init(dev, dev->subdevices + PCI20000_MODULES);
+
+ return 1;
+}
+
+static int pci20xxx_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pci20xxx: remove\n", dev->minor);
+
+ return 0;
+}
+
+/* pci20006m */
+
+static int pci20006_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pci20006_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static const struct comedi_lrange *pci20006_range_list[] = {
+ &range_bipolar10,
+ &range_unipolar10,
+ &range_bipolar5,
+};
+
+static int pci20006_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ int opt0, int opt1)
+{
+ union pci20xxx_subdev_private *sdp = s->private;
+
+ if (opt0 < 0 || opt0 > 2)
+ opt0 = 0;
+ if (opt1 < 0 || opt1 > 2)
+ opt1 = 0;
+
+ sdp->pci20006.ao_range_list[0] = pci20006_range_list[opt0];
+ sdp->pci20006.ao_range_list[1] = pci20006_range_list[opt1];
+
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->len_chanlist = 2;
+ s->insn_read = pci20006_insn_read;
+ s->insn_write = pci20006_insn_write;
+ s->maxdata = 0xffff;
+ s->range_table_list = sdp->pci20006.ao_range_list;
+ return 0;
+}
+
+static int pci20006_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ union pci20xxx_subdev_private *sdp = s->private;
+
+ data[0] = sdp->pci20006.last_data[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int pci20006_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ union pci20xxx_subdev_private *sdp = s->private;
+ int hi, lo;
+ unsigned int boarddata;
+
+ sdp->pci20006.last_data[CR_CHAN(insn->chanspec)] = data[0];
+ boarddata = (((unsigned int)data[0] + 0x8000) & 0xffff); /* comedi-data -> board-data */
+ lo = (boarddata & 0xff);
+ hi = ((boarddata >> 8) & 0xff);
+
+ switch (CR_CHAN(insn->chanspec)) {
+ case 0:
+ writeb(lo, sdp->iobase + PCI20006_LCHAN0);
+ writeb(hi, sdp->iobase + PCI20006_LCHAN0 + 1);
+ writeb(0x00, sdp->iobase + PCI20006_STROBE0);
+ break;
+ case 1:
+ writeb(lo, sdp->iobase + PCI20006_LCHAN1);
+ writeb(hi, sdp->iobase + PCI20006_LCHAN1 + 1);
+ writeb(0x00, sdp->iobase + PCI20006_STROBE1);
+ break;
+ default:
+ printk(" comedi%d: pci20xxx: ao channel Error!\n", dev->minor);
+ return -EINVAL;
+ }
+
+ return 1;
+}
+
+/* PCI20341M */
+
+static int pci20341_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static const int pci20341_timebase[] = { 0x00, 0x00, 0x00, 0x04 };
+static const int pci20341_settling_time[] = { 0x58, 0x58, 0x93, 0x99 };
+
+static const struct comedi_lrange range_bipolar0_5 = { 1, {BIP_RANGE(0.5)} };
+static const struct comedi_lrange range_bipolar0_05 = { 1, {BIP_RANGE(0.05)} };
+static const struct comedi_lrange range_bipolar0_025 = { 1, {BIP_RANGE(0.025)} };
+
+static const struct comedi_lrange *const pci20341_ranges[] = {
+ &range_bipolar5,
+ &range_bipolar0_5,
+ &range_bipolar0_05,
+ &range_bipolar0_025,
+};
+
+static int pci20341_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ int opt0, int opt1)
+{
+ union pci20xxx_subdev_private *sdp = s->private;
+ int option;
+
+ /* options handling */
+ if (opt0 < 0 || opt0 > 3)
+ opt0 = 0;
+ sdp->pci20341.timebase = pci20341_timebase[opt0];
+ sdp->pci20341.settling_time = pci20341_settling_time[opt0];
+
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = PCI20341_CHAN_NR;
+ s->len_chanlist = PCI20341_SCANLIST;
+ s->insn_read = pci20341_insn_read;
+ s->maxdata = 0xffff;
+ s->range_table = pci20341_ranges[opt0];
+
+ option = sdp->pci20341.timebase | PCI20341_REPMODE; /* depends on gain, trigger, repetition mode */
+
+ writeb(PCI20341_INIT, sdp->iobase + PCI20341_CONFIG_REG); /* initialize Module */
+ writeb(PCI20341_PACER, sdp->iobase + PCI20341_MOD_STATUS); /* set Pacer */
+ writeb(option, sdp->iobase + PCI20341_OPT_REG); /* option register */
+ writeb(sdp->pci20341.settling_time, sdp->iobase + PCI20341_SET_TIME_REG); /* settling time counter */
+ /* trigger not implemented */
+ return 0;
+}
+
+static int pci20341_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ union pci20xxx_subdev_private *sdp = s->private;
+ unsigned int i = 0, j = 0;
+ int lo, hi;
+ unsigned char eoc; /* end of conversion */
+ unsigned int clb; /* channel list byte */
+ unsigned int boarddata;
+
+ writeb(1, sdp->iobase + PCI20341_LCHAN_ADDR_REG); /* write number of input channels */
+ clb = PCI20341_DAISY_CHAIN | PCI20341_MUX | (sdp->pci20341.ai_gain << 3)
+ | CR_CHAN(insn->chanspec);
+ writeb(clb, sdp->iobase + PCI20341_CHAN_LIST);
+ writeb(0x00, sdp->iobase + PCI20341_CC_RESET); /* reset settling time counter and trigger delay counter */
+ writeb(0x00, sdp->iobase + PCI20341_CHAN_RESET);
+
+ /* generate Pacer */
+
+ for (i = 0; i < insn->n; i++) {
+ /* data polling isn't the niciest way to get the data, I know,
+ * but there are only 6 cycles (mean) and it is easier than
+ * the whole interrupt stuff
+ */
+ j = 0;
+ readb(sdp->iobase + PCI20341_SOFT_PACER); /* generate Pacer */
+ eoc = readb(sdp->iobase + PCI20341_STATUS_REG);
+ while ((eoc < 0x80) && j < 100) { /* poll Interrupt Flag */
+ j++;
+ eoc = readb(sdp->iobase + PCI20341_STATUS_REG);
+ }
+ if (j >= 100) {
+ printk("comedi%d: pci20xxx: AI interrupt channel %i polling exit !\n", dev->minor, i);
+ return -EINVAL;
+ }
+ lo = readb(sdp->iobase + PCI20341_LDATA);
+ hi = readb(sdp->iobase + PCI20341_LDATA + 1);
+ boarddata = lo + 0x100 * hi;
+ data[i] = (short) ((boarddata + 0x8000) & 0xffff); /* board-data -> comedi-data */
+ }
+
+ return i;
+}
+
+/* native DIO */
+
+static void pci20xxx_dio_config(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci20xxx_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pci20xxx_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/* initialize struct pci20xxx_private */
+static int pci20xxx_dio_init(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 32;
+ s->insn_bits = pci20xxx_dio_insn_bits;
+ s->insn_config = pci20xxx_dio_insn_config;
+ s->maxdata = 1;
+ s->len_chanlist = 32;
+ s->range_table = &range_digital;
+ s->io_bits = 0;
+
+ /* digital I/O lines default to input on board reset. */
+ pci20xxx_dio_config(dev, s);
+
+ return 0;
+}
+
+static int pci20xxx_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int mask, bits;
+
+ mask = 1 << CR_CHAN(insn->chanspec);
+ if (mask & 0x000000ff) {
+ bits = 0x000000ff;
+ } else if (mask & 0x0000ff00) {
+ bits = 0x0000ff00;
+ } else if (mask & 0x00ff0000) {
+ bits = 0x00ff0000;
+ } else {
+ bits = 0xff000000;
+ }
+ if (data[0]) {
+ s->io_bits |= bits;
+ } else {
+ s->io_bits &= ~bits;
+ }
+ pci20xxx_dio_config(dev, s);
+
+ return 1;
+}
+
+static int pci20xxx_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int mask = data[0];
+
+ s->state &= ~mask;
+ s->state |= (mask & data[1]);
+
+ mask &= s->io_bits;
+ if (mask & 0x000000ff)
+ writeb((s->state >> 0) & 0xff,
+ devpriv->ioaddr + PCI20000_DIO_0);
+ if (mask & 0x0000ff00)
+ writeb((s->state >> 8) & 0xff,
+ devpriv->ioaddr + PCI20000_DIO_1);
+ if (mask & 0x00ff0000)
+ writeb((s->state >> 16) & 0xff,
+ devpriv->ioaddr + PCI20000_DIO_2);
+ if (mask & 0xff000000)
+ writeb((s->state >> 24) & 0xff,
+ devpriv->ioaddr + PCI20000_DIO_3);
+
+ data[1] = readb(devpriv->ioaddr + PCI20000_DIO_0);
+ data[1] |= readb(devpriv->ioaddr + PCI20000_DIO_1) << 8;
+ data[1] |= readb(devpriv->ioaddr + PCI20000_DIO_2) << 16;
+ data[1] |= readb(devpriv->ioaddr + PCI20000_DIO_3) << 24;
+
+ return 2;
+}
+
+static void pci20xxx_dio_config(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned char control_01;
+ unsigned char control_23;
+ unsigned char buffer;
+
+ control_01 = readb(devpriv->ioaddr + PCI20000_DIO_CONTROL_01);
+ control_23 = readb(devpriv->ioaddr + PCI20000_DIO_CONTROL_23);
+ buffer = readb(devpriv->ioaddr + PCI20000_DIO_BUFFER);
+
+ if (s->io_bits & 0x000000ff) {
+ /* output port 0 */
+ control_01 &= PCI20000_DIO_EOC;
+ buffer = (buffer & (~(DIO_BE << DIO_PS_0))) | (DIO_BO <<
+ DIO_PS_0);
+ } else {
+ /* input port 0 */
+ control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_EIC;
+ buffer = (buffer & (~(DIO_BI << DIO_PS_0)));
+ }
+ if (s->io_bits & 0x0000ff00) {
+ /* output port 1 */
+ control_01 &= PCI20000_DIO_OOC;
+ buffer = (buffer & (~(DIO_BE << DIO_PS_1))) | (DIO_BO <<
+ DIO_PS_1);
+ } else {
+ /* input port 1 */
+ control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_OIC;
+ buffer = (buffer & (~(DIO_BI << DIO_PS_1)));
+ }
+ if (s->io_bits & 0x00ff0000) {
+ /* output port 2 */
+ control_23 &= PCI20000_DIO_EOC;
+ buffer = (buffer & (~(DIO_BE << DIO_PS_2))) | (DIO_BO <<
+ DIO_PS_2);
+ } else {
+ /* input port 2 */
+ control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_EIC;
+ buffer = (buffer & (~(DIO_BI << DIO_PS_2)));
+ }
+ if (s->io_bits & 0xff000000) {
+ /* output port 3 */
+ control_23 &= PCI20000_DIO_OOC;
+ buffer = (buffer & (~(DIO_BE << DIO_PS_3))) | (DIO_BO <<
+ DIO_PS_3);
+ } else {
+ /* input port 3 */
+ control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_OIC;
+ buffer = (buffer & (~(DIO_BI << DIO_PS_3)));
+ }
+ writeb(control_01, devpriv->ioaddr + PCI20000_DIO_CONTROL_01);
+ writeb(control_23, devpriv->ioaddr + PCI20000_DIO_CONTROL_23);
+ writeb(buffer, devpriv->ioaddr + PCI20000_DIO_BUFFER);
+}
+
+#if 0
+static void pci20xxx_do(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ /* XXX if the channel is configured for input, does this
+ do bad things? */
+ /* XXX it would be a good idea to only update the registers
+ that _need_ to be updated. This requires changes to
+ comedi, however. */
+ writeb((s->state >> 0) & 0xff, devpriv->ioaddr + PCI20000_DIO_0);
+ writeb((s->state >> 8) & 0xff, devpriv->ioaddr + PCI20000_DIO_1);
+ writeb((s->state >> 16) & 0xff, devpriv->ioaddr + PCI20000_DIO_2);
+ writeb((s->state >> 24) & 0xff, devpriv->ioaddr + PCI20000_DIO_3);
+}
+
+static unsigned int pci20xxx_di(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ /* XXX same note as above */
+ unsigned int bits;
+
+ bits = readb(devpriv->ioaddr + PCI20000_DIO_0);
+ bits |= readb(devpriv->ioaddr + PCI20000_DIO_1) << 8;
+ bits |= readb(devpriv->ioaddr + PCI20000_DIO_2) << 16;
+ bits |= readb(devpriv->ioaddr + PCI20000_DIO_3) << 24;
+
+ return bits;
+}
+#endif
+
+COMEDI_INITCLEANUP(driver_pci20xxx);
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
new file mode 100644
index 00000000000..a3c887f3b2c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -0,0 +1,976 @@
+/*
+ comedi/drivers/jr3_pci.c
+ hardware driver for JR3/PCI force sensor board
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2007 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ 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.
+
+*/
+/*
+Driver: jr3_pci
+Description: JR3/PCI force sensor board
+Author: Anders Blomdell <anders.blomdell@control.lth.se>
+Status: works
+Devices: [JR3] PCI force sensor board (jr3_pci)
+
+ The DSP on the board requires initialization code, which can
+ be loaded by placing it in /lib/firmware/comedi.
+ The initialization code should be somewhere on the media you got
+ with your card. One version is available from http://www.comedi.org
+ in the comedi_nonfree_firmware tarball.
+
+ Configuration options:
+ [0] - PCI bus number - if bus number and slot number are 0,
+ then driver search for first unused card
+ [1] - PCI slot number
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/ctype.h>
+#include <linux/firmware.h>
+#include "comedi_pci.h"
+#include "jr3_pci.h"
+
+/* Hotplug firmware loading stuff */
+
+static void comedi_fw_release(struct device *dev)
+{
+ printk(KERN_DEBUG "firmware_sample_driver: ghost_release\n");
+}
+
+static struct device comedi_fw_device = {
+ .init_name = "comedi",
+ .release = comedi_fw_release
+};
+
+typedef int comedi_firmware_callback(struct comedi_device * dev,
+ const u8 * data, size_t size);
+
+static int comedi_load_firmware(struct comedi_device * dev,
+ char *name, comedi_firmware_callback cb)
+{
+ int result = 0;
+ const struct firmware *fw;
+ char *firmware_path;
+ static const char *prefix = "comedi/";
+
+ firmware_path = kmalloc(strlen(prefix) + strlen(name) + 1, GFP_KERNEL);
+ if (!firmware_path) {
+ result = -ENOMEM;
+ } else {
+ firmware_path[0] = '\0';
+ strcat(firmware_path, prefix);
+ strcat(firmware_path, name);
+ result = device_register(&comedi_fw_device);
+ if (result == 0) {
+ result = request_firmware(&fw, firmware_path,
+ &comedi_fw_device);
+ if (result == 0) {
+ if (!cb) {
+ result = -EINVAL;
+ } else {
+ result = cb(dev, fw->data, fw->size);
+ }
+ release_firmware(fw);
+ }
+ device_unregister(&comedi_fw_device);
+ }
+ kfree(firmware_path);
+ }
+ return result;
+}
+
+#define PCI_VENDOR_ID_JR3 0x1762
+#define PCI_DEVICE_ID_JR3_1_CHANNEL 0x3111
+#define PCI_DEVICE_ID_JR3_2_CHANNEL 0x3112
+#define PCI_DEVICE_ID_JR3_3_CHANNEL 0x3113
+#define PCI_DEVICE_ID_JR3_4_CHANNEL 0x3114
+
+static int jr3_pci_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int jr3_pci_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_jr3_pci = {
+ driver_name:"jr3_pci",
+ module:THIS_MODULE,
+ attach:jr3_pci_attach,
+ detach:jr3_pci_detach,
+};
+
+static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = {
+ {PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_3_CHANNEL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_4_CHANNEL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, jr3_pci_pci_table);
+
+struct jr3_pci_dev_private {
+
+ struct pci_dev *pci_dev;
+ int pci_enabled;
+ volatile struct jr3_t *iobase;
+ int n_channels;
+ struct timer_list timer;
+};
+
+
+struct poll_delay_t {
+
+ int min;
+ int max;
+};
+
+
+struct jr3_pci_subdev_private {
+ volatile struct jr3_channel *channel;
+ unsigned long next_time_min;
+ unsigned long next_time_max;
+ enum { state_jr3_poll,
+ state_jr3_init_wait_for_offset,
+ state_jr3_init_transform_complete,
+ state_jr3_init_set_full_scale_complete,
+ state_jr3_init_use_offset_complete,
+ state_jr3_done
+ } state;
+ int channel_no;
+ int serial_no;
+ int model_no;
+ struct {
+ int length;
+ struct comedi_krange range;
+ } range[9];
+ const struct comedi_lrange *range_table_list[8 * 7 + 2];
+ unsigned int maxdata_list[8 * 7 + 2];
+ u16 errors;
+ int retries;
+};
+
+static struct poll_delay_t poll_delay_min_max(int min, int max)
+{
+ struct poll_delay_t result;
+
+ result.min = min;
+ result.max = max;
+ return result;
+}
+
+static int is_complete(volatile struct jr3_channel *channel)
+{
+ return get_s16(&channel->command_word0) == 0;
+}
+
+struct transform_t {
+ struct {
+ u16 link_type;
+ s16 link_amount;
+ } link[8];
+};
+
+static void set_transforms(volatile struct jr3_channel *channel,
+ struct transform_t transf, short num)
+{
+ int i;
+
+ num &= 0x000f; // Make sure that 0 <= num <= 15
+ for (i = 0; i < 8; i++) {
+
+ set_u16(&channel->transforms[num].link[i].link_type,
+ transf.link[i].link_type);
+ comedi_udelay(1);
+ set_s16(&channel->transforms[num].link[i].link_amount,
+ transf.link[i].link_amount);
+ comedi_udelay(1);
+ if (transf.link[i].link_type == end_x_form) {
+ break;
+ }
+ }
+}
+
+static void use_transform(volatile struct jr3_channel *channel, short transf_num)
+{
+ set_s16(&channel->command_word0, 0x0500 + (transf_num & 0x000f));
+}
+
+static void use_offset(volatile struct jr3_channel *channel, short offset_num)
+{
+ set_s16(&channel->command_word0, 0x0600 + (offset_num & 0x000f));
+}
+
+static void set_offset(volatile struct jr3_channel *channel)
+{
+ set_s16(&channel->command_word0, 0x0700);
+}
+
+struct six_axis_t {
+ s16 fx;
+ s16 fy;
+ s16 fz;
+ s16 mx;
+ s16 my;
+ s16 mz;
+};
+
+static void set_full_scales(volatile struct jr3_channel *channel,
+ struct six_axis_t full_scale)
+{
+ printk("%d %d %d %d %d %d\n",
+ full_scale.fx,
+ full_scale.fy,
+ full_scale.fz, full_scale.mx, full_scale.my, full_scale.mz);
+ set_s16(&channel->full_scale.fx, full_scale.fx);
+ set_s16(&channel->full_scale.fy, full_scale.fy);
+ set_s16(&channel->full_scale.fz, full_scale.fz);
+ set_s16(&channel->full_scale.mx, full_scale.mx);
+ set_s16(&channel->full_scale.my, full_scale.my);
+ set_s16(&channel->full_scale.mz, full_scale.mz);
+ set_s16(&channel->command_word0, 0x0a00);
+}
+
+static struct six_axis_t get_min_full_scales(volatile struct jr3_channel *channel)
+{
+ struct six_axis_t result;
+ result.fx = get_s16(&channel->min_full_scale.fx);
+ result.fy = get_s16(&channel->min_full_scale.fy);
+ result.fz = get_s16(&channel->min_full_scale.fz);
+ result.mx = get_s16(&channel->min_full_scale.mx);
+ result.my = get_s16(&channel->min_full_scale.my);
+ result.mz = get_s16(&channel->min_full_scale.mz);
+ return result;
+}
+
+static struct six_axis_t get_max_full_scales(volatile struct jr3_channel *channel)
+{
+ struct six_axis_t result;
+ result.fx = get_s16(&channel->max_full_scale.fx);
+ result.fy = get_s16(&channel->max_full_scale.fy);
+ result.fz = get_s16(&channel->max_full_scale.fz);
+ result.mx = get_s16(&channel->max_full_scale.mx);
+ result.my = get_s16(&channel->max_full_scale.my);
+ result.mz = get_s16(&channel->max_full_scale.mz);
+ return result;
+}
+
+static int jr3_pci_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int result;
+ struct jr3_pci_subdev_private *p;
+ int channel;
+
+ p = s->private;
+ channel = CR_CHAN(insn->chanspec);
+ if (p == NULL || channel > 57) {
+ result = -EINVAL;
+ } else {
+ int i;
+
+ result = insn->n;
+ if (p->state != state_jr3_done ||
+ (get_u16(&p->channel->
+ errors) & (watch_dog | watch_dog2 |
+ sensor_change))) {
+ /* No sensor or sensor changed */
+ if (p->state == state_jr3_done) {
+ /* Restart polling */
+ p->state = state_jr3_poll;
+ }
+ result = -EAGAIN;
+ }
+ for (i = 0; i < insn->n; i++) {
+ if (channel < 56) {
+ int axis, filter;
+
+ axis = channel % 8;
+ filter = channel / 8;
+ if (p->state != state_jr3_done) {
+ data[i] = 0;
+ } else {
+ int F = 0;
+ switch (axis) {
+ case 0:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ fx);
+ }
+ break;
+ case 1:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ fy);
+ }
+ break;
+ case 2:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ fz);
+ }
+ break;
+ case 3:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ mx);
+ }
+ break;
+ case 4:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ my);
+ }
+ break;
+ case 5:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ mz);
+ }
+ break;
+ case 6:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ v1);
+ }
+ break;
+ case 7:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ v2);
+ }
+ break;
+ }
+ data[i] = F + 0x4000;
+ }
+ } else if (channel == 56) {
+ if (p->state != state_jr3_done) {
+ data[i] = 0;
+ } else {
+ data[i] =
+ get_u16(&p->channel->model_no);
+ }
+ } else if (channel == 57) {
+ if (p->state != state_jr3_done) {
+ data[i] = 0;
+ } else {
+ data[i] =
+ get_u16(&p->channel->serial_no);
+ }
+ }
+ }
+ }
+ return result;
+}
+
+static void jr3_pci_open(struct comedi_device * dev)
+{
+ int i;
+ struct jr3_pci_dev_private *devpriv = dev->private;
+
+ printk("jr3_pci_open\n");
+ for (i = 0; i < devpriv->n_channels; i++) {
+ struct jr3_pci_subdev_private *p;
+
+ p = dev->subdevices[i].private;
+ if (p) {
+ printk("serial: %p %d (%d)\n", p, p->serial_no,
+ p->channel_no);
+ }
+ }
+}
+
+int read_idm_word(const u8 * data, size_t size, int *pos, unsigned int *val)
+{
+ int result = 0;
+ if (pos != 0 && val != 0) {
+ // Skip over non hex
+ for (; *pos < size && !isxdigit(data[*pos]); (*pos)++) {
+ }
+ // Collect value
+ *val = 0;
+ for (; *pos < size && isxdigit(data[*pos]); (*pos)++) {
+ char ch = tolower(data[*pos]);
+ result = 1;
+ if ('0' <= ch && ch <= '9') {
+ *val = (*val << 4) + (ch - '0');
+ } else if ('a' <= ch && ch <= 'f') {
+ *val = (*val << 4) + (ch - 'a' + 10);
+ }
+ }
+ }
+ return result;
+}
+
+static int jr3_download_firmware(struct comedi_device * dev, const u8 * data,
+ size_t size)
+{
+ /*
+ * IDM file format is:
+ * { count, address, data <count> } *
+ * ffff
+ */
+ int result, more, pos, OK;
+
+ result = 0;
+ more = 1;
+ pos = 0;
+ OK = 0;
+ while (more) {
+ unsigned int count, addr;
+
+ more = more && read_idm_word(data, size, &pos, &count);
+ if (more && count == 0xffff) {
+ OK = 1;
+ break;
+ }
+ more = more && read_idm_word(data, size, &pos, &addr);
+ while (more && count > 0) {
+ unsigned int dummy;
+ more = more && read_idm_word(data, size, &pos, &dummy);
+ count--;
+ }
+ }
+
+ if (!OK) {
+ result = -ENODATA;
+ } else {
+ int i;
+ struct jr3_pci_dev_private *p = dev->private;
+
+ for (i = 0; i < p->n_channels; i++) {
+ struct jr3_pci_subdev_private *sp;
+
+ sp = dev->subdevices[i].private;
+ more = 1;
+ pos = 0;
+ while (more) {
+ unsigned int count, addr;
+ more = more
+ && read_idm_word(data, size, &pos,
+ &count);
+ if (more && count == 0xffff) {
+ break;
+ }
+ more = more
+ && read_idm_word(data, size, &pos,
+ &addr);
+ printk("Loading#%d %4.4x bytes at %4.4x\n", i,
+ count, addr);
+ while (more && count > 0) {
+ if (addr & 0x4000) {
+ // 16 bit data, never seen in real life!!
+ unsigned int data1;
+
+ more = more
+ && read_idm_word(data,
+ size, &pos, &data1);
+ count--;
+ // printk("jr3_data, not tested\n");
+ // jr3[addr + 0x20000 * pnum] = data1;
+ } else {
+ // Download 24 bit program
+ unsigned int data1, data2;
+
+ more = more
+ && read_idm_word(data,
+ size, &pos, &data1);
+ more = more
+ && read_idm_word(data,
+ size, &pos, &data2);
+ count -= 2;
+ if (more) {
+ set_u16(&p->iobase->
+ channel[i].
+ program_low
+ [addr], data1);
+ comedi_udelay(1);
+ set_u16(&p->iobase->
+ channel[i].
+ program_high
+ [addr], data2);
+ comedi_udelay(1);
+
+ }
+ }
+ addr++;
+ }
+ }
+ }
+ }
+ return result;
+}
+
+static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice * s)
+{
+ struct poll_delay_t result = poll_delay_min_max(1000, 2000);
+ struct jr3_pci_subdev_private *p = s->private;
+
+ if (p) {
+ volatile struct jr3_channel *channel = p->channel;
+ int errors = get_u16(&channel->errors);
+
+ if (errors != p->errors) {
+ printk("Errors: %x -> %x\n", p->errors, errors);
+ p->errors = errors;
+ }
+ if (errors & (watch_dog | watch_dog2 | sensor_change)) {
+ // Sensor communication lost, force poll mode
+ p->state = state_jr3_poll;
+
+ }
+ switch (p->state) {
+ case state_jr3_poll:{
+ u16 model_no = get_u16(&channel->model_no);
+ u16 serial_no = get_u16(&channel->serial_no);
+ if ((errors & (watch_dog | watch_dog2)) ||
+ model_no == 0 || serial_no == 0) {
+ // Still no sensor, keep on polling. Since it takes up to
+ // 10 seconds for offsets to stabilize, polling each
+ // second should suffice.
+ result = poll_delay_min_max(1000, 2000);
+ } else {
+ p->retries = 0;
+ p->state =
+ state_jr3_init_wait_for_offset;
+ result = poll_delay_min_max(1000, 2000);
+ }
+ }
+ break;
+ case state_jr3_init_wait_for_offset:{
+ p->retries++;
+ if (p->retries < 10) {
+ // Wait for offeset to stabilize (< 10 s according to manual)
+ result = poll_delay_min_max(1000, 2000);
+ } else {
+ struct transform_t transf;
+
+ p->model_no =
+ get_u16(&channel->model_no);
+ p->serial_no =
+ get_u16(&channel->serial_no);
+
+ printk("Setting transform for channel %d\n", p->channel_no);
+ printk("Sensor Model = %i\n",
+ p->model_no);
+ printk("Sensor Serial = %i\n",
+ p->serial_no);
+
+ // Transformation all zeros
+ transf.link[0].link_type =
+ (enum link_types)0;
+ transf.link[0].link_amount = 0;
+ transf.link[1].link_type =
+ (enum link_types)0;
+ transf.link[1].link_amount = 0;
+ transf.link[2].link_type =
+ (enum link_types)0;
+ transf.link[2].link_amount = 0;
+ transf.link[3].link_type =
+ (enum link_types)0;
+ transf.link[3].link_amount = 0;
+
+ set_transforms(channel, transf, 0);
+ use_transform(channel, 0);
+ p->state =
+ state_jr3_init_transform_complete;
+ result = poll_delay_min_max(20, 100); // Allow 20 ms for completion
+ }
+ } break;
+ case state_jr3_init_transform_complete:{
+ if (!is_complete(channel)) {
+ printk("state_jr3_init_transform_complete complete = %d\n", is_complete(channel));
+ result = poll_delay_min_max(20, 100);
+ } else {
+ // Set full scale
+ struct six_axis_t min_full_scale;
+ struct six_axis_t max_full_scale;
+
+ min_full_scale =
+ get_min_full_scales(channel);
+ printk("Obtained Min. Full Scales:\n");
+ printk("%i ", (min_full_scale).fx);
+ printk("%i ", (min_full_scale).fy);
+ printk("%i ", (min_full_scale).fz);
+ printk("%i ", (min_full_scale).mx);
+ printk("%i ", (min_full_scale).my);
+ printk("%i ", (min_full_scale).mz);
+ printk("\n");
+
+ max_full_scale =
+ get_max_full_scales(channel);
+ printk("Obtained Max. Full Scales:\n");
+ printk("%i ", (max_full_scale).fx);
+ printk("%i ", (max_full_scale).fy);
+ printk("%i ", (max_full_scale).fz);
+ printk("%i ", (max_full_scale).mx);
+ printk("%i ", (max_full_scale).my);
+ printk("%i ", (max_full_scale).mz);
+ printk("\n");
+
+ set_full_scales(channel,
+ max_full_scale);
+
+ p->state =
+ state_jr3_init_set_full_scale_complete;
+ result = poll_delay_min_max(20, 100); // Allow 20 ms for completion
+ }
+ }
+ break;
+ case state_jr3_init_set_full_scale_complete:{
+ if (!is_complete(channel)) {
+ printk("state_jr3_init_set_full_scale_complete complete = %d\n", is_complete(channel));
+ result = poll_delay_min_max(20, 100);
+ } else {
+ volatile struct force_array *full_scale;
+
+ // Use ranges in kN or we will overflow arount 2000N!
+ full_scale = &channel->full_scale;
+ p->range[0].range.min =
+ -get_s16(&full_scale->fx) *
+ 1000;
+ p->range[0].range.max =
+ get_s16(&full_scale->fx) * 1000;
+ p->range[1].range.min =
+ -get_s16(&full_scale->fy) *
+ 1000;
+ p->range[1].range.max =
+ get_s16(&full_scale->fy) * 1000;
+ p->range[2].range.min =
+ -get_s16(&full_scale->fz) *
+ 1000;
+ p->range[2].range.max =
+ get_s16(&full_scale->fz) * 1000;
+ p->range[3].range.min =
+ -get_s16(&full_scale->mx) * 100;
+ p->range[3].range.max =
+ get_s16(&full_scale->mx) * 100;
+ p->range[4].range.min =
+ -get_s16(&full_scale->my) * 100;
+ p->range[4].range.max =
+ get_s16(&full_scale->my) * 100;
+ p->range[5].range.min =
+ -get_s16(&full_scale->mz) * 100;
+ p->range[5].range.max =
+ get_s16(&full_scale->mz) * 100;
+ p->range[6].range.min = -get_s16(&full_scale->v1) * 100; // ??
+ p->range[6].range.max = get_s16(&full_scale->v1) * 100; // ??
+ p->range[7].range.min = -get_s16(&full_scale->v2) * 100; // ??
+ p->range[7].range.max = get_s16(&full_scale->v2) * 100; // ??
+ p->range[8].range.min = 0;
+ p->range[8].range.max = 65535;
+
+ {
+ int i;
+ for (i = 0; i < 9; i++) {
+ printk("%d %d - %d\n",
+ i,
+ p->range[i].
+ range.min,
+ p->range[i].
+ range.max);
+ }
+ }
+
+ use_offset(channel, 0);
+ p->state =
+ state_jr3_init_use_offset_complete;
+ result = poll_delay_min_max(40, 100); // Allow 40 ms for completion
+ }
+ }
+ break;
+ case state_jr3_init_use_offset_complete:{
+ if (!is_complete(channel)) {
+ printk("state_jr3_init_use_offset_complete complete = %d\n", is_complete(channel));
+ result = poll_delay_min_max(20, 100);
+ } else {
+ printk("Default offsets %d %d %d %d %d %d\n", get_s16(&channel->offsets.fx), get_s16(&channel->offsets.fy), get_s16(&channel->offsets.fz), get_s16(&channel->offsets.mx), get_s16(&channel->offsets.my), get_s16(&channel->offsets.mz));
+
+ set_s16(&channel->offsets.fx, 0);
+ set_s16(&channel->offsets.fy, 0);
+ set_s16(&channel->offsets.fz, 0);
+ set_s16(&channel->offsets.mx, 0);
+ set_s16(&channel->offsets.my, 0);
+ set_s16(&channel->offsets.mz, 0);
+
+ set_offset(channel);
+
+ p->state = state_jr3_done;
+ }
+ }
+ break;
+ case state_jr3_done:{
+ poll_delay_min_max(10000, 20000);
+ }
+ break;
+ default:{
+ poll_delay_min_max(1000, 2000);
+ }
+ break;
+ }
+ }
+ return result;
+}
+
+static void jr3_pci_poll_dev(unsigned long data)
+{
+ unsigned long flags;
+ struct comedi_device *dev = (struct comedi_device *) data;
+ struct jr3_pci_dev_private *devpriv = dev->private;
+ unsigned long now;
+ int delay;
+ int i;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ delay = 1000;
+ now = jiffies;
+ // Poll all channels that are ready to be polled
+ for (i = 0; i < devpriv->n_channels; i++) {
+ struct jr3_pci_subdev_private *subdevpriv = dev->subdevices[i].private;
+ if (now > subdevpriv->next_time_min) {
+ struct poll_delay_t sub_delay;
+
+ sub_delay = jr3_pci_poll_subdevice(&dev->subdevices[i]);
+ subdevpriv->next_time_min =
+ jiffies + msecs_to_jiffies(sub_delay.min);
+ subdevpriv->next_time_max =
+ jiffies + msecs_to_jiffies(sub_delay.max);
+ if (sub_delay.max && sub_delay.max < delay) {
+ // Wake up as late as possible -> poll as many channels as
+ // possible at once
+ delay = sub_delay.max;
+ }
+ }
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ devpriv->timer.expires = jiffies + msecs_to_jiffies(delay);
+ add_timer(&devpriv->timer);
+}
+
+static int jr3_pci_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int result = 0;
+ struct pci_dev *card = NULL;
+ int opt_bus, opt_slot, i;
+ struct jr3_pci_dev_private *devpriv;
+
+ printk("comedi%d: jr3_pci\n", dev->minor);
+
+ opt_bus = it->options[0];
+ opt_slot = it->options[1];
+
+ if (sizeof(struct jr3_channel) != 0xc00) {
+ printk("sizeof(struct jr3_channel) = %x [expected %x]\n",
+ (unsigned)sizeof(struct jr3_channel), 0xc00);
+ return -EINVAL;
+ }
+
+ result = alloc_private(dev, sizeof(struct jr3_pci_dev_private));
+ if (result < 0) {
+ return -ENOMEM;
+ }
+ card = NULL;
+ devpriv = dev->private;
+ init_timer(&devpriv->timer);
+ while (1) {
+ card = pci_get_device(PCI_VENDOR_ID_JR3, PCI_ANY_ID, card);
+ if (card == NULL) {
+ /* No card found */
+ break;
+ } else {
+ switch (card->device) {
+ case PCI_DEVICE_ID_JR3_1_CHANNEL:{
+ devpriv->n_channels = 1;
+ }
+ break;
+ case PCI_DEVICE_ID_JR3_2_CHANNEL:{
+ devpriv->n_channels = 2;
+ }
+ break;
+ case PCI_DEVICE_ID_JR3_3_CHANNEL:{
+ devpriv->n_channels = 3;
+ }
+ break;
+ case PCI_DEVICE_ID_JR3_4_CHANNEL:{
+ devpriv->n_channels = 4;
+ }
+ break;
+ default:{
+ devpriv->n_channels = 0;
+ }
+ }
+ if (devpriv->n_channels >= 1) {
+ if (opt_bus == 0 && opt_slot == 0) {
+ /* Take first available card */
+ break;
+ } else if (opt_bus == card->bus->number &&
+ opt_slot == PCI_SLOT(card->devfn)) {
+ /* Take requested card */
+ break;
+ }
+ }
+ }
+ }
+ if (!card) {
+ printk(" no jr3_pci found\n");
+ return -EIO;
+ } else {
+ devpriv->pci_dev = card;
+ dev->board_name = "jr3_pci";
+ }
+ if ((result = comedi_pci_enable(card, "jr3_pci")) < 0) {
+ return -EIO;
+ }
+ devpriv->pci_enabled = 1;
+ devpriv->iobase = ioremap(pci_resource_start(card, 0), sizeof(struct jr3_t));
+ result = alloc_subdevices(dev, devpriv->n_channels);
+ if (result < 0)
+ goto out;
+
+ dev->open = jr3_pci_open;
+ for (i = 0; i < devpriv->n_channels; i++) {
+ dev->subdevices[i].type = COMEDI_SUBD_AI;
+ dev->subdevices[i].subdev_flags = SDF_READABLE | SDF_GROUND;
+ dev->subdevices[i].n_chan = 8 * 7 + 2;
+ dev->subdevices[i].insn_read = jr3_pci_ai_insn_read;
+ dev->subdevices[i].private =
+ kzalloc(sizeof(struct jr3_pci_subdev_private), GFP_KERNEL);
+ if (dev->subdevices[i].private) {
+ struct jr3_pci_subdev_private *p;
+ int j;
+
+ p = dev->subdevices[i].private;
+ p->channel = &devpriv->iobase->channel[i].data;
+ printk("p->channel %p %p (%tx)\n",
+ p->channel, devpriv->iobase,
+ ((char *)(p->channel) -
+ (char *)(devpriv->iobase)));
+ p->channel_no = i;
+ for (j = 0; j < 8; j++) {
+ int k;
+
+ p->range[j].length = 1;
+ p->range[j].range.min = -1000000;
+ p->range[j].range.max = 1000000;
+ for (k = 0; k < 7; k++) {
+ p->range_table_list[j + k * 8] =
+ (struct comedi_lrange *) & p->range[j];
+ p->maxdata_list[j + k * 8] = 0x7fff;
+ }
+ }
+ p->range[8].length = 1;
+ p->range[8].range.min = 0;
+ p->range[8].range.max = 65536;
+
+ p->range_table_list[56] =
+ (struct comedi_lrange *) & p->range[8];
+ p->range_table_list[57] =
+ (struct comedi_lrange *) & p->range[8];
+ p->maxdata_list[56] = 0xffff;
+ p->maxdata_list[57] = 0xffff;
+ // Channel specific range and maxdata
+ dev->subdevices[i].range_table = 0;
+ dev->subdevices[i].range_table_list =
+ p->range_table_list;
+ dev->subdevices[i].maxdata = 0;
+ dev->subdevices[i].maxdata_list = p->maxdata_list;
+ }
+ }
+
+ // Reset DSP card
+ devpriv->iobase->channel[0].reset = 0;
+
+ result = comedi_load_firmware(dev, "jr3pci.idm", jr3_download_firmware);
+ printk("Firmare load %d\n", result);
+
+ if (result < 0) {
+ goto out;
+ }
+ // TODO: use firmware to load preferred offset tables. Suggested format:
+ // model serial Fx Fy Fz Mx My Mz\n
+ //
+ // comedi_load_firmware(dev, "jr3_offsets_table", jr3_download_firmware);
+
+ // It takes a few milliseconds for software to settle
+ // as much as we can read firmware version
+ msleep_interruptible(25);
+ for (i = 0; i < 0x18; i++) {
+ printk("%c",
+ get_u16(&devpriv->iobase->channel[0].data.
+ copyright[i]) >> 8);
+ }
+
+ // Start card timer
+ for (i = 0; i < devpriv->n_channels; i++) {
+ struct jr3_pci_subdev_private *p = dev->subdevices[i].private;
+
+ p->next_time_min = jiffies + msecs_to_jiffies(500);
+ p->next_time_max = jiffies + msecs_to_jiffies(2000);
+ }
+
+ devpriv->timer.data = (unsigned long)dev;
+ devpriv->timer.function = jr3_pci_poll_dev;
+ devpriv->timer.expires = jiffies + msecs_to_jiffies(1000);
+ add_timer(&devpriv->timer);
+
+ out:
+ return result;
+}
+
+static int jr3_pci_detach(struct comedi_device * dev)
+{
+ int i;
+ struct jr3_pci_dev_private *devpriv = dev->private;
+
+ printk("comedi%d: jr3_pci: remove\n", dev->minor);
+ if (devpriv) {
+ del_timer_sync(&devpriv->timer);
+
+ if (dev->subdevices) {
+ for (i = 0; i < devpriv->n_channels; i++) {
+ kfree(dev->subdevices[i].private);
+ }
+ }
+
+ if (devpriv->iobase) {
+ iounmap((void *)devpriv->iobase);
+ }
+ if (devpriv->pci_enabled) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+
+ if (devpriv->pci_dev) {
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+ return 0;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_jr3_pci, jr3_pci_pci_table);
diff --git a/drivers/staging/comedi/drivers/jr3_pci.h b/drivers/staging/comedi/drivers/jr3_pci.h
new file mode 100644
index 00000000000..3585f2941bc
--- /dev/null
+++ b/drivers/staging/comedi/drivers/jr3_pci.h
@@ -0,0 +1,681 @@
+/* Helper types to take care of the fact that the DSP card memory
+ * is 16 bits, but aligned on a 32 bit PCI boundary
+ */
+
+static inline u16 get_u16(volatile const u32 * p)
+{
+ return (u16) readl(p);
+}
+
+static inline void set_u16(volatile u32 * p, u16 val)
+{
+ writel(val, p);
+}
+
+static inline s16 get_s16(volatile const s32 * p)
+{
+ return (s16) readl(p);
+}
+
+static inline void set_s16(volatile s32 * p, s16 val)
+{
+ writel(val, p);
+}
+
+/* The raw data is stored in a format which facilitates rapid
+ * processing by the JR3 DSP chip. The raw_channel structure shows the
+ * format for a single channel of data. Each channel takes four,
+ * two-byte words.
+ *
+ * Raw_time is an unsigned integer which shows the value of the JR3
+ * DSP's internal clock at the time the sample was received. The clock
+ * runs at 1/10 the JR3 DSP cycle time. JR3's slowest DSP runs at 10
+ * Mhz. At 10 Mhz raw_time would therefore clock at 1 Mhz.
+ *
+ * Raw_data is the raw data received directly from the sensor. The
+ * sensor data stream is capable of representing 16 different
+ * channels. Channel 0 shows the excitation voltage at the sensor. It
+ * is used to regulate the voltage over various cable lengths.
+ * Channels 1-6 contain the coupled force data Fx through Mz. Channel
+ * 7 contains the sensor's calibration data. The use of channels 8-15
+ * varies with different sensors.
+ */
+
+struct raw_channel {
+ u32 raw_time;
+ s32 raw_data;
+ s32 reserved[2];
+};
+
+/* The force_array structure shows the layout for the decoupled and
+ * filtered force data.
+ */
+struct force_array {
+ s32 fx;
+ s32 fy;
+ s32 fz;
+ s32 mx;
+ s32 my;
+ s32 mz;
+ s32 v1;
+ s32 v2;
+};
+
+/* The six_axis_array structure shows the layout for the offsets and
+ * the full scales.
+ */
+struct six_axis_array {
+ s32 fx;
+ s32 fy;
+ s32 fz;
+ s32 mx;
+ s32 my;
+ s32 mz;
+};
+
+/* VECT_BITS */
+/* The vect_bits structure shows the layout for indicating
+ * which axes to use in computing the vectors. Each bit signifies
+ * selection of a single axis. The V1x axis bit corresponds to a hex
+ * value of 0x0001 and the V2z bit corresponds to a hex value of
+ * 0x0020. Example: to specify the axes V1x, V1y, V2x, and V2z the
+ * pattern would be 0x002b. Vector 1 defaults to a force vector and
+ * vector 2 defaults to a moment vector. It is possible to change one
+ * or the other so that two force vectors or two moment vectors are
+ * calculated. Setting the changeV1 bit or the changeV2 bit will
+ * change that vector to be the opposite of its default. Therefore to
+ * have two force vectors, set changeV1 to 1.
+ */
+
+/* vect_bits appears to be unused at this time */
+enum {
+ fx = 0x0001,
+ fy = 0x0002,
+ fz = 0x0004,
+ mx = 0x0008,
+ my = 0x0010,
+ mz = 0x0020,
+ changeV2 = 0x0040,
+ changeV1 = 0x0080
+} vect_bits_t;
+
+/* WARNING_BITS */
+/* The warning_bits structure shows the bit pattern for the warning
+ * word. The bit fields are shown from bit 0 (lsb) to bit 15 (msb).
+ */
+
+/* XX_NEAR_SET */
+/* The xx_near_sat bits signify that the indicated axis has reached or
+ * exceeded the near saturation value.
+ */
+
+enum {
+ fx_near_sat = 0x0001,
+ fy_near_sat = 0x0002,
+ fz_near_sat = 0x0004,
+ mx_near_sat = 0x0008,
+ my_near_sat = 0x0010,
+ mz_near_sat = 0x0020
+} warning_bits_t;
+
+/* ERROR_BITS */
+/* XX_SAT */
+/* MEMORY_ERROR */
+/* SENSOR_CHANGE */
+
+/* The error_bits structure shows the bit pattern for the error word.
+ * The bit fields are shown from bit 0 (lsb) to bit 15 (msb). The
+ * xx_sat bits signify that the indicated axis has reached or exceeded
+ * the saturation value. The memory_error bit indicates that a problem
+ * was detected in the on-board RAM during the power-up
+ * initialization. The sensor_change bit indicates that a sensor other
+ * than the one originally plugged in has passed its CRC check. This
+ * bit latches, and must be reset by the user.
+ *
+ */
+
+/* SYSTEM_BUSY */
+
+/* The system_busy bit indicates that the JR3 DSP is currently busy
+ * and is not calculating force data. This occurs when a new
+ * coordinate transformation, or new sensor full scale is set by the
+ * user. A very fast system using the force data for feedback might
+ * become unstable during the approximately 4 ms needed to accomplish
+ * these calculations. This bit will also become active when a new
+ * sensor is plugged in and the system needs to recalculate the
+ * calibration CRC.
+ */
+
+/* CAL_CRC_BAD */
+
+/* The cal_crc_bad bit indicates that the calibration CRC has not
+ * calculated to zero. CRC is short for cyclic redundancy code. It is
+ * a method for determining the integrity of messages in data
+ * communication. The calibration data stored inside the sensor is
+ * transmitted to the JR3 DSP along with the sensor data. The
+ * calibration data has a CRC attached to the end of it, to assist in
+ * determining the completeness and integrity of the calibration data
+ * received from the sensor. There are two reasons the CRC may not
+ * have calculated to zero. The first is that all the calibration data
+ * has not yet been received, the second is that the calibration data
+ * has been corrupted. A typical sensor transmits the entire contents
+ * of its calibration matrix over 30 times a second. Therefore, if
+ * this bit is not zero within a couple of seconds after the sensor
+ * has been plugged in, there is a problem with the sensor's
+ * calibration data.
+ */
+
+/* WATCH_DOG */
+/* WATCH_DOG2 */
+
+/* The watch_dog and watch_dog2 bits are sensor, not processor, watch
+ * dog bits. Watch_dog indicates that the sensor data line seems to be
+ * acting correctly, while watch_dog2 indicates that sensor data and
+ * clock are being received. It is possible for watch_dog2 to go off
+ * while watch_dog does not. This would indicate an improper clock
+ * signal, while data is acting correctly. If either watch dog barks,
+ * the sensor data is not being received correctly.
+ */
+
+enum error_bits_t {
+ fx_sat = 0x0001,
+ fy_sat = 0x0002,
+ fz_sat = 0x0004,
+ mx_sat = 0x0008,
+ my_sat = 0x0010,
+ mz_sat = 0x0020,
+ memory_error = 0x0400,
+ sensor_change = 0x0800,
+ system_busy = 0x1000,
+ cal_crc_bad = 0x2000,
+ watch_dog2 = 0x4000,
+ watch_dog = 0x8000
+};
+
+/* THRESH_STRUCT */
+
+/* This structure shows the layout for a single threshold packet inside of a
+ * load envelope. Each load envelope can contain several threshold structures.
+ * 1. data_address contains the address of the data for that threshold. This
+ * includes filtered, unfiltered, raw, rate, counters, error and warning data
+ * 2. threshold is the is the value at which, if data is above or below, the
+ * bits will be set ... (pag.24).
+ * 3. bit_pattern contains the bits that will be set if the threshold value is
+ * met or exceeded.
+ */
+
+struct thresh_struct {
+ s32 data_address;
+ s32 threshold;
+ s32 bit_pattern;
+};
+
+/* LE_STRUCT */
+
+/* Layout of a load enveloped packet. Four thresholds are showed ... for more
+ * see manual (pag.25)
+ * 1. latch_bits is a bit pattern that show which bits the user wants to latch.
+ * The latched bits will not be reset once the threshold which set them is
+ * no longer true. In that case the user must reset them using the reset_bit
+ * command.
+ * 2. number_of_xx_thresholds specify how many GE/LE threshold there are.
+ */
+struct le_struct {
+ s32 latch_bits;
+ s32 number_of_ge_thresholds;
+ s32 number_of_le_thresholds;
+ struct thresh_struct thresholds[4];
+ s32 reserved;
+};
+
+/* LINK_TYPES */
+/* Link types is an enumerated value showing the different possible transform
+ * link types.
+ * 0 - end transform packet
+ * 1 - translate along X axis (TX)
+ * 2 - translate along Y axis (TY)
+ * 3 - translate along Z axis (TZ)
+ * 4 - rotate about X axis (RX)
+ * 5 - rotate about Y axis (RY)
+ * 6 - rotate about Z axis (RZ)
+ * 7 - negate all axes (NEG)
+ */
+
+enum link_types {
+ end_x_form,
+ tx,
+ ty,
+ tz,
+ rx,
+ ry,
+ rz,
+ neg
+};
+
+/* TRANSFORM */
+/* Structure used to describe a transform. */
+struct intern_transform {
+ struct {
+ u32 link_type;
+ s32 link_amount;
+ } link[8];
+};
+
+/* JR3 force/torque sensor data definition. For more information see sensor and */
+/* hardware manuals. */
+
+struct jr3_channel {
+ /* Raw_channels is the area used to store the raw data coming from */
+ /* the sensor. */
+
+ struct raw_channel raw_channels[16]; /* offset 0x0000 */
+
+ /* Copyright is a null terminated ASCII string containing the JR3 */
+ /* copyright notice. */
+
+ u32 copyright[0x0018]; /* offset 0x0040 */
+ s32 reserved1[0x0008]; /* offset 0x0058 */
+
+ /* Shunts contains the sensor shunt readings. Some JR3 sensors have
+ * the ability to have their gains adjusted. This allows the
+ * hardware full scales to be adjusted to potentially allow
+ * better resolution or dynamic range. For sensors that have
+ * this ability, the gain of each sensor channel is measured at
+ * the time of calibration using a shunt resistor. The shunt
+ * resistor is placed across one arm of the resistor bridge, and
+ * the resulting change in the output of that channel is
+ * measured. This measurement is called the shunt reading, and
+ * is recorded here. If the user has changed the gain of the //
+ * sensor, and made new shunt measurements, those shunt
+ * measurements can be placed here. The JR3 DSP will then scale
+ * the calibration matrix such so that the gains are again
+ * proper for the indicated shunt readings. If shunts is 0, then
+ * the sensor cannot have its gain changed. For details on
+ * changing the sensor gain, and making shunts readings, please
+ * see the sensor manual. To make these values take effect the
+ * user must call either command (5) use transform # (pg. 33) or
+ * command (10) set new full scales (pg. 38).
+ */
+
+ struct six_axis_array shunts; /* offset 0x0060 */
+ s32 reserved2[2]; /* offset 0x0066 */
+
+ /* Default_FS contains the full scale that is used if the user does */
+ /* not set a full scale. */
+
+ struct six_axis_array default_FS; /* offset 0x0068 */
+ s32 reserved3; /* offset 0x006e */
+
+ /* Load_envelope_num is the load envelope number that is currently
+ * in use. This value is set by the user after one of the load
+ * envelopes has been initialized.
+ */
+
+ s32 load_envelope_num; /* offset 0x006f */
+
+ /* Min_full_scale is the recommend minimum full scale. */
+
+ /* These values in conjunction with max_full_scale (pg. 9) helps
+ * determine the appropriate value for setting the full scales. The
+ * software allows the user to set the sensor full scale to an
+ * arbitrary value. But setting the full scales has some hazards. If
+ * the full scale is set too low, the data will saturate
+ * prematurely, and dynamic range will be lost. If the full scale is
+ * set too high, then resolution is lost as the data is shifted to
+ * the right and the least significant bits are lost. Therefore the
+ * maximum full scale is the maximum value at which no resolution is
+ * lost, and the minimum full scale is the value at which the data
+ * will not saturate prematurely. These values are calculated
+ * whenever a new coordinate transformation is calculated. It is
+ * possible for the recommended maximum to be less than the
+ * recommended minimum. This comes about primarily when using
+ * coordinate translations. If this is the case, it means that any
+ * full scale selection will be a compromise between dynamic range
+ * and resolution. It is usually recommended to compromise in favor
+ * of resolution which means that the recommend maximum full scale
+ * should be chosen.
+ *
+ * WARNING: Be sure that the full scale is no less than 0.4% of the
+ * recommended minimum full scale. Full scales below this value will
+ * cause erroneous results.
+ */
+
+ struct six_axis_array min_full_scale; /* offset 0x0070 */
+ s32 reserved4; /* offset 0x0076 */
+
+ /* Transform_num is the transform number that is currently in use.
+ * This value is set by the JR3 DSP after the user has used command
+ * (5) use transform # (pg. 33).
+ */
+
+ s32 transform_num; /* offset 0x0077 */
+
+ /* Max_full_scale is the recommended maximum full scale. See */
+ /* min_full_scale (pg. 9) for more details. */
+
+ struct six_axis_array max_full_scale; /* offset 0x0078 */
+ s32 reserved5; /* offset 0x007e */
+
+ /* Peak_address is the address of the data which will be monitored
+ * by the peak routine. This value is set by the user. The peak
+ * routine will monitor any 8 contiguous addresses for peak values.
+ * (ex. to watch filter3 data for peaks, set this value to 0x00a8).
+ */
+
+ s32 peak_address; /* offset 0x007f */
+
+ /* Full_scale is the sensor full scales which are currently in use.
+ * Decoupled and filtered data is scaled so that +/- 16384 is equal
+ * to the full scales. The engineering units used are indicated by
+ * the units value discussed on page 16. The full scales for Fx, Fy,
+ * Fz, Mx, My and Mz can be written by the user prior to calling
+ * command (10) set new full scales (pg. 38). The full scales for V1
+ * and V2 are set whenever the full scales are changed or when the
+ * axes used to calculate the vectors are changed. The full scale of
+ * V1 and V2 will always be equal to the largest full scale of the
+ * axes used for each vector respectively.
+ */
+
+ struct force_array full_scale; /* offset 0x0080 */
+
+ /* Offsets contains the sensor offsets. These values are subtracted from
+ * the sensor data to obtain the decoupled data. The offsets are set a
+ * few seconds (< 10) after the calibration data has been received.
+ * They are set so that the output data will be zero. These values
+ * can be written as well as read. The JR3 DSP will use the values
+ * written here within 2 ms of being written. To set future
+ * decoupled data to zero, add these values to the current decoupled
+ * data values and place the sum here. The JR3 DSP will change these
+ * values when a new transform is applied. So if the offsets are
+ * such that FX is 5 and all other values are zero, after rotating
+ * about Z by 90 degrees, FY would be 5 and all others would be zero.
+ */
+
+ struct six_axis_array offsets; /* offset 0x0088 */
+
+ /* Offset_num is the number of the offset currently in use. This
+ * value is set by the JR3 DSP after the user has executed the use
+ * offset # command (pg. 34). It can vary between 0 and 15.
+ */
+
+ s32 offset_num; /* offset 0x008e */
+
+ /* Vect_axes is a bit map showing which of the axes are being used
+ * in the vector calculations. This value is set by the JR3 DSP
+ * after the user has executed the set vector axes command (pg. 37).
+ */
+
+ u32 vect_axes; /* offset 0x008f */
+
+ /* Filter0 is the decoupled, unfiltered data from the JR3 sensor.
+ * This data has had the offsets removed.
+ *
+ * These force_arrays hold the filtered data. The decoupled data is
+ * passed through cascaded low pass filters. Each succeeding filter
+ * has a cutoff frequency of 1/4 of the preceding filter. The cutoff
+ * frequency of filter1 is 1/16 of the sample rate from the sensor.
+ * For a typical sensor with a sample rate of 8 kHz, the cutoff
+ * frequency of filter1 would be 500 Hz. The following filters would
+ * cutoff at 125 Hz, 31.25 Hz, 7.813 Hz, 1.953 Hz and 0.4883 Hz.
+ */
+
+ struct force_array filter[7]; /* offset 0x0090,
+ offset 0x0098,
+ offset 0x00a0,
+ offset 0x00a8,
+ offset 0x00b0,
+ offset 0x00b8 ,
+ offset 0x00c0 */
+
+ /* Rate_data is the calculated rate data. It is a first derivative
+ * calculation. It is calculated at a frequency specified by the
+ * variable rate_divisor (pg. 12). The data on which the rate is
+ * calculated is specified by the variable rate_address (pg. 12).
+ */
+
+ struct force_array rate_data; /* offset 0x00c8 */
+
+ /* Minimum_data & maximum_data are the minimum and maximum (peak)
+ * data values. The JR3 DSP can monitor any 8 contiguous data items
+ * for minimums and maximums at full sensor bandwidth. This area is
+ * only updated at user request. This is done so that the user does
+ * not miss any peaks. To read the data, use either the read peaks
+ * command (pg. 40), or the read and reset peaks command (pg. 39).
+ * The address of the data to watch for peaks is stored in the
+ * variable peak_address (pg. 10). Peak data is lost when executing
+ * a coordinate transformation or a full scale change. Peak data is
+ * also lost when plugging in a new sensor.
+ */
+
+ struct force_array minimum_data; /* offset 0x00d0 */
+ struct force_array maximum_data; /* offset 0x00d8 */
+
+ /* Near_sat_value & sat_value contain the value used to determine if
+ * the raw sensor is saturated. Because of decoupling and offset
+ * removal, it is difficult to tell from the processed data if the
+ * sensor is saturated. These values, in conjunction with the error
+ * and warning words (pg. 14), provide this critical information.
+ * These two values may be set by the host processor. These values
+ * are positive signed values, since the saturation logic uses the
+ * absolute values of the raw data. The near_sat_value defaults to
+ * approximately 80% of the ADC's full scale, which is 26214, while
+ * sat_value defaults to the ADC's full scale:
+ *
+ * sat_value = 32768 - 2^(16 - ADC bits)
+ */
+
+ s32 near_sat_value; /* offset 0x00e0 */
+ s32 sat_value; /* offset 0x00e1 */
+
+ /* Rate_address, rate_divisor & rate_count contain the data used to
+ * control the calculations of the rates. Rate_address is the
+ * address of the data used for the rate calculation. The JR3 DSP
+ * will calculate rates for any 8 contiguous values (ex. to
+ * calculate rates for filter3 data set rate_address to 0x00a8).
+ * Rate_divisor is how often the rate is calculated. If rate_divisor
+ * is 1, the rates are calculated at full sensor bandwidth. If
+ * rate_divisor is 200, rates are calculated every 200 samples.
+ * Rate_divisor can be any value between 1 and 65536. Set
+ * rate_divisor to 0 to calculate rates every 65536 samples.
+ * Rate_count starts at zero and counts until it equals
+ * rate_divisor, at which point the rates are calculated, and
+ * rate_count is reset to 0. When setting a new rate divisor, it is
+ * a good idea to set rate_count to one less than rate divisor. This
+ * will minimize the time necessary to start the rate calculations.
+ */
+
+ s32 rate_address; /* offset 0x00e2 */
+ u32 rate_divisor; /* offset 0x00e3 */
+ u32 rate_count; /* offset 0x00e4 */
+
+ /* Command_word2 through command_word0 are the locations used to
+ * send commands to the JR3 DSP. Their usage varies with the command
+ * and is detailed later in the Command Definitions section (pg.
+ * 29). In general the user places values into various memory
+ * locations, and then places the command word into command_word0.
+ * The JR3 DSP will process the command and place a 0 into
+ * command_word0 to indicate successful completion. Alternatively
+ * the JR3 DSP will place a negative number into command_word0 to
+ * indicate an error condition. Please note the command locations
+ * are numbered backwards. (I.E. command_word2 comes before
+ * command_word1).
+ */
+
+ s32 command_word2; /* offset 0x00e5 */
+ s32 command_word1; /* offset 0x00e6 */
+ s32 command_word0; /* offset 0x00e7 */
+
+ /* Count1 through count6 are unsigned counters which are incremented
+ * every time the matching filters are calculated. Filter1 is
+ * calculated at the sensor data bandwidth. So this counter would
+ * increment at 8 kHz for a typical sensor. The rest of the counters
+ * are incremented at 1/4 the interval of the counter immediately
+ * preceding it, so they would count at 2 kHz, 500 Hz, 125 Hz etc.
+ * These counters can be used to wait for data. Each time the
+ * counter changes, the corresponding data set can be sampled, and
+ * this will insure that the user gets each sample, once, and only
+ * once.
+ */
+
+ u32 count1; /* offset 0x00e8 */
+ u32 count2; /* offset 0x00e9 */
+ u32 count3; /* offset 0x00ea */
+ u32 count4; /* offset 0x00eb */
+ u32 count5; /* offset 0x00ec */
+ u32 count6; /* offset 0x00ed */
+
+ /* Error_count is a running count of data reception errors. If this
+ * counter is changing rapidly, it probably indicates a bad sensor
+ * cable connection or other hardware problem. In most installations
+ * error_count should not change at all. But it is possible in an
+ * extremely noisy environment to experience occasional errors even
+ * without a hardware problem. If the sensor is well grounded, this
+ * is probably unavoidable in these environments. On the occasions
+ * where this counter counts a bad sample, that sample is ignored.
+ */
+
+ u32 error_count; /* offset 0x00ee */
+
+ /* Count_x is a counter which is incremented every time the JR3 DSP
+ * searches its job queues and finds nothing to do. It indicates the
+ * amount of idle time the JR3 DSP has available. It can also be
+ * used to determine if the JR3 DSP is alive. See the Performance
+ * Issues section on pg. 49 for more details.
+ */
+
+ u32 count_x; /* offset 0x00ef */
+
+ /* Warnings & errors contain the warning and error bits
+ * respectively. The format of these two words is discussed on page
+ * 21 under the headings warnings_bits and error_bits.
+ */
+
+ u32 warnings; /* offset 0x00f0 */
+ u32 errors; /* offset 0x00f1 */
+
+ /* Threshold_bits is a word containing the bits that are set by the
+ * load envelopes. See load_envelopes (pg. 17) and thresh_struct
+ * (pg. 23) for more details.
+ */
+
+ s32 threshold_bits; /* offset 0x00f2 */
+
+ /* Last_crc is the value that shows the actual calculated CRC. CRC
+ * is short for cyclic redundancy code. It should be zero. See the
+ * description for cal_crc_bad (pg. 21) for more information.
+ */
+
+ s32 last_CRC; /* offset 0x00f3 */
+
+ /* EEProm_ver_no contains the version number of the sensor EEProm.
+ * EEProm version numbers can vary between 0 and 255.
+ * Software_ver_no contains the software version number. Version
+ * 3.02 would be stored as 302.
+ */
+
+ s32 eeprom_ver_no; /* offset 0x00f4 */
+ s32 software_ver_no; /* offset 0x00f5 */
+
+ /* Software_day & software_year are the release date of the software
+ * the JR3 DSP is currently running. Day is the day of the year,
+ * with January 1 being 1, and December 31, being 365 for non leap
+ * years.
+ */
+
+ s32 software_day; /* offset 0x00f6 */
+ s32 software_year; /* offset 0x00f7 */
+
+ /* Serial_no & model_no are the two values which uniquely identify a
+ * sensor. This model number does not directly correspond to the JR3
+ * model number, but it will provide a unique identifier for
+ * different sensor configurations.
+ */
+
+ u32 serial_no; /* offset 0x00f8 */
+ u32 model_no; /* offset 0x00f9 */
+
+ /* Cal_day & cal_year are the sensor calibration date. Day is the
+ * day of the year, with January 1 being 1, and December 31, being
+ * 366 for leap years.
+ */
+
+ s32 cal_day; /* offset 0x00fa */
+ s32 cal_year; /* offset 0x00fb */
+
+ /* Units is an enumerated read only value defining the engineering
+ * units used in the sensor full scale. The meanings of particular
+ * values are discussed in the section detailing the force_units
+ * structure on page 22. The engineering units are setto customer
+ * specifications during sensor manufacture and cannot be changed by
+ * writing to Units.
+ *
+ * Bits contains the number of bits of resolution of the ADC
+ * currently in use.
+ *
+ * Channels is a bit field showing which channels the current sensor
+ * is capable of sending. If bit 0 is active, this sensor can send
+ * channel 0, if bit 13 is active, this sensor can send channel 13,
+ * etc. This bit can be active, even if the sensor is not currently
+ * sending this channel. Some sensors are configurable as to which
+ * channels to send, and this field only contains information on the
+ * channels available to send, not on the current configuration. To
+ * find which channels are currently being sent, monitor the
+ * Raw_time fields (pg. 19) in the raw_channels array (pg. 7). If
+ * the time is changing periodically, then that channel is being
+ * received.
+ */
+
+ u32 units; /* offset 0x00fc */
+ s32 bits; /* offset 0x00fd */
+ s32 channels; /* offset 0x00fe */
+
+ /* Thickness specifies the overall thickness of the sensor from
+ * flange to flange. The engineering units for this value are
+ * contained in units (pg. 16). The sensor calibration is relative
+ * to the center of the sensor. This value allows easy coordinate
+ * transformation from the center of the sensor to either flange.
+ */
+
+ s32 thickness; /* offset 0x00ff */
+
+ /* Load_envelopes is a table containing the load envelope
+ * descriptions. There are 16 possible load envelope slots in the
+ * table. The slots are on 16 word boundaries and are numbered 0-15.
+ * Each load envelope needs to start at the beginning of a slot but
+ * need not be fully contained in that slot. That is to say that a
+ * single load envelope can be larger than a single slot. The
+ * software has been tested and ran satisfactorily with 50
+ * thresholds active. A single load envelope this large would take
+ * up 5 of the 16 slots. The load envelope data is laid out in an
+ * order that is most efficient for the JR3 DSP. The structure is
+ * detailed later in the section showing the definition of the
+ * le_struct structure (pg. 23).
+ */
+
+ struct le_struct load_envelopes[0x10]; /* offset 0x0100 */
+
+ /* Transforms is a table containing the transform descriptions.
+ * There are 16 possible transform slots in the table. The slots are
+ * on 16 word boundaries and are numbered 0-15. Each transform needs
+ * to start at the beginning of a slot but need not be fully
+ * contained in that slot. That is to say that a single transform
+ * can be larger than a single slot. A transform is 2 * no of links
+ * + 1 words in length. So a single slot can contain a transform
+ * with 7 links. Two slots can contain a transform that is 15 links.
+ * The layout is detailed later in the section showing the
+ * definition of the transform structure (pg. 26).
+ */
+
+ struct intern_transform transforms[0x10]; /* offset 0x0200 */
+};
+
+struct jr3_t {
+ struct {
+ u32 program_low[0x4000]; /* 0x00000 - 0x10000 */
+ struct jr3_channel data; /* 0x10000 - 0x10c00 */
+ char pad2[0x30000 - 0x00c00]; /* 0x10c00 - 0x40000 */
+ u32 program_high[0x8000]; /* 0x40000 - 0x60000 */
+ u32 reset; /* 0x60000 - 0x60004 */
+ char pad3[0x20000 - 0x00004]; /* 0x60004 - 0x80000 */
+ } channel[4];
+};
diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c
new file mode 100644
index 00000000000..79f6fe5646c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ke_counter.c
@@ -0,0 +1,254 @@
+/*
+ comedi/drivers/ke_counter.c
+ Comedi driver for Kolter-Electronic PCI Counter 1 Card
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ke_counter
+Description: Driver for Kolter Electronic Counter Card
+Devices: [Kolter Electronic] PCI Counter Card (ke_counter)
+Author: Michael Hillmann
+Updated: Mon, 14 Apr 2008 15:42:42 +0100
+Status: tested
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+
+This driver is a simple driver to read the counter values from
+Kolter Electronic PCI Counter Card.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#define CNT_DRIVER_NAME "ke_counter"
+#define PCI_VENDOR_ID_KOLTER 0x1001
+#define CNT_CARD_DEVICE_ID 0x0014
+
+/*-- function prototypes ----------------------------------------------------*/
+
+static int cnt_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int cnt_detach(struct comedi_device * dev);
+
+static DEFINE_PCI_DEVICE_TABLE(cnt_pci_table) = {
+ {PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, cnt_pci_table);
+
+/*-- board specification structure ------------------------------------------*/
+
+struct cnt_board_struct {
+
+ const char *name;
+ int device_id;
+ int cnt_channel_nbr;
+ int cnt_bits;
+};
+
+
+static const struct cnt_board_struct cnt_boards[] = {
+ {
+ name: CNT_DRIVER_NAME,
+ device_id:CNT_CARD_DEVICE_ID,
+ cnt_channel_nbr:3,
+ cnt_bits:24}
+};
+
+#define cnt_board_nbr (sizeof(cnt_boards)/sizeof(struct cnt_board_struct))
+
+/*-- device private structure -----------------------------------------------*/
+
+struct cnt_device_private {
+
+ struct pci_dev *pcidev;
+};
+
+
+#define devpriv ((struct cnt_device_private *)dev->private)
+
+static struct comedi_driver cnt_driver = {
+ driver_name:CNT_DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:cnt_attach,
+ detach:cnt_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(cnt_driver, cnt_pci_table);
+
+/*-- counter write ----------------------------------------------------------*/
+
+/* This should be used only for resetting the counters; maybe it is better
+ to make a special command 'reset'. */
+static int cnt_winsn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+
+ outb((unsigned char)((data[0] >> 24) & 0xff),
+ dev->iobase + chan * 0x20 + 0x10);
+ outb((unsigned char)((data[0] >> 16) & 0xff),
+ dev->iobase + chan * 0x20 + 0x0c);
+ outb((unsigned char)((data[0] >> 8) & 0xff),
+ dev->iobase + chan * 0x20 + 0x08);
+ outb((unsigned char)((data[0] >> 0) & 0xff),
+ dev->iobase + chan * 0x20 + 0x04);
+
+ /* return the number of samples written */
+ return 1;
+}
+
+/*-- counter read -----------------------------------------------------------*/
+
+static int cnt_rinsn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned char a0, a1, a2, a3, a4;
+ int chan = CR_CHAN(insn->chanspec);
+ int result;
+
+ a0 = inb(dev->iobase + chan * 0x20);
+ a1 = inb(dev->iobase + chan * 0x20 + 0x04);
+ a2 = inb(dev->iobase + chan * 0x20 + 0x08);
+ a3 = inb(dev->iobase + chan * 0x20 + 0x0c);
+ a4 = inb(dev->iobase + chan * 0x20 + 0x10);
+
+ result = (a1 + (a2 * 256) + (a3 * 65536));
+ if (a4 > 0)
+ result = result - s->maxdata;
+
+ *data = (unsigned int) result;
+
+ /* return the number of samples read */
+ return 1;
+}
+
+/*-- attach -----------------------------------------------------------------*/
+
+static int cnt_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *subdevice;
+ struct pci_dev *pci_device;
+ struct cnt_board_struct *board;
+ unsigned long io_base;
+ int error, i;
+
+ /* allocate device private structure */
+ if ((error = alloc_private(dev, sizeof(struct cnt_device_private))) < 0) {
+ return error;
+ }
+
+ /* Probe the device to determine what device in the series it is. */
+ for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pci_device != NULL;
+ pci_device =
+ pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
+ if (pci_device->vendor == PCI_VENDOR_ID_KOLTER) {
+ for (i = 0; i < cnt_board_nbr; i++) {
+ if (cnt_boards[i].device_id ==
+ pci_device->device) {
+ /* was a particular bus/slot requested? */
+ if ((it->options[0] != 0)
+ || (it->options[1] != 0)) {
+ /* are we on the wrong bus/slot? */
+ if (pci_device->bus->number !=
+ it->options[0]
+ || PCI_SLOT(pci_device->
+ devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+
+ dev->board_ptr = cnt_boards + i;
+ board = (struct cnt_board_struct *) dev->
+ board_ptr;
+ goto found;
+ }
+ }
+ }
+ }
+ printk("comedi%d: no supported board found! (req. bus/slot: %d/%d)\n",
+ dev->minor, it->options[0], it->options[1]);
+ return -EIO;
+
+ found:
+ printk("comedi%d: found %s at PCI bus %d, slot %d\n", dev->minor,
+ board->name, pci_device->bus->number,
+ PCI_SLOT(pci_device->devfn));
+ devpriv->pcidev = pci_device;
+ dev->board_name = board->name;
+
+ /* enable PCI device and request regions */
+ if ((error = comedi_pci_enable(pci_device, CNT_DRIVER_NAME)) < 0) {
+ printk("comedi%d: failed to enable PCI device and request regions!\n", dev->minor);
+ return error;
+ }
+
+ /* read register base address [PCI_BASE_ADDRESS #0] */
+ io_base = pci_resource_start(pci_device, 0);
+ dev->iobase = io_base;
+
+ /* allocate the subdevice structures */
+ if ((error = alloc_subdevices(dev, 1)) < 0) {
+ return error;
+ }
+
+ subdevice = dev->subdevices + 0;
+ dev->read_subdev = subdevice;
+
+ subdevice->type = COMEDI_SUBD_COUNTER;
+ subdevice->subdev_flags = SDF_READABLE /* | SDF_COMMON */ ;
+ subdevice->n_chan = board->cnt_channel_nbr;
+ subdevice->maxdata = (1 << board->cnt_bits) - 1;
+ subdevice->insn_read = cnt_rinsn;
+ subdevice->insn_write = cnt_winsn;
+
+ // select 20MHz clock
+ outb(3, dev->iobase + 248);
+
+ // reset all counters
+ outb(0, dev->iobase);
+ outb(0, dev->iobase + 0x20);
+ outb(0, dev->iobase + 0x40);
+
+ printk("comedi%d: " CNT_DRIVER_NAME " attached.\n", dev->minor);
+ return 0;
+}
+
+/*-- detach -----------------------------------------------------------------*/
+
+static int cnt_detach(struct comedi_device * dev)
+{
+ if (devpriv && devpriv->pcidev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pcidev);
+ }
+ pci_dev_put(devpriv->pcidev);
+ }
+ printk("comedi%d: " CNT_DRIVER_NAME " remove\n", dev->minor);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index b432aa7d764..12481a032b9 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -92,7 +92,7 @@ static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
MODULE_DEVICE_TABLE(pci, me4000_pci_table);
-static const me4000_board_t me4000_boards[] = {
+static const struct me4000_board me4000_boards[] = {
{"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0}},
{"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3}},
@@ -113,108 +113,108 @@ static const me4000_board_t me4000_boards[] = {
{0},
};
-#define ME4000_BOARD_VERSIONS (sizeof(me4000_boards) / sizeof(me4000_board_t) - 1)
+#define ME4000_BOARD_VERSIONS (sizeof(me4000_boards) / sizeof(struct me4000_board) - 1)
/*-----------------------------------------------------------------------------
Comedi function prototypes
---------------------------------------------------------------------------*/
-static int me4000_attach(comedi_device * dev, comedi_devconfig * it);
-static int me4000_detach(comedi_device * dev);
-static comedi_driver driver_me4000 = {
+static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int me4000_detach(struct comedi_device *dev);
+static struct comedi_driver driver_me4000 = {
driver_name:"me4000",
- module:THIS_MODULE,
- attach:me4000_attach,
- detach:me4000_detach,
+ module : THIS_MODULE,
+ attach : me4000_attach,
+ detach : me4000_detach,
};
/*-----------------------------------------------------------------------------
Meilhaus function prototypes
---------------------------------------------------------------------------*/
-static int me4000_probe(comedi_device * dev, comedi_devconfig * it);
-static int get_registers(comedi_device * dev, struct pci_dev *pci_dev_p);
-static int init_board_info(comedi_device * dev, struct pci_dev *pci_dev_p);
-static int init_ao_context(comedi_device * dev);
-static int init_ai_context(comedi_device * dev);
-static int init_dio_context(comedi_device * dev);
-static int init_cnt_context(comedi_device * dev);
-static int xilinx_download(comedi_device * dev);
-static int reset_board(comedi_device * dev);
+static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it);
+static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p);
+static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p);
+static int init_ao_context(struct comedi_device *dev);
+static int init_ai_context(struct comedi_device *dev);
+static int init_dio_context(struct comedi_device *dev);
+static int init_cnt_context(struct comedi_device *dev);
+static int xilinx_download(struct comedi_device *dev);
+static int reset_board(struct comedi_device *dev);
-static int me4000_dio_insn_bits(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_dio_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
-static int me4000_dio_insn_config(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_dio_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
-static int cnt_reset(comedi_device * dev, unsigned int channel);
+static int cnt_reset(struct comedi_device *dev, unsigned int channel);
-static int cnt_config(comedi_device * dev,
+static int cnt_config(struct comedi_device *dev,
unsigned int channel, unsigned int mode);
-static int me4000_cnt_insn_config(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_cnt_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
-static int me4000_cnt_insn_write(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_cnt_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
-static int me4000_cnt_insn_read(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_cnt_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
-static int me4000_ai_insn_read(comedi_device * dev,
- comedi_subdevice * subdevice, comedi_insn * insn, lsampl_t * data);
+static int me4000_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data);
-static int me4000_ai_cancel(comedi_device * dev, comedi_subdevice * s);
+static int me4000_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
-static int ai_check_chanlist(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd);
+static int ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd);
-static int ai_round_cmd_args(comedi_device * dev,
- comedi_subdevice * s,
- comedi_cmd * cmd,
+static int ai_round_cmd_args(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd,
unsigned int *init_ticks,
unsigned int *scan_ticks, unsigned int *chan_ticks);
-static int ai_prepare(comedi_device * dev,
- comedi_subdevice * s,
- comedi_cmd * cmd,
+static int ai_prepare(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd,
unsigned int init_ticks,
unsigned int scan_ticks, unsigned int chan_ticks);
-static int ai_write_chanlist(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd);
+static int ai_write_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd);
static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG);
-static int me4000_ai_do_cmd_test(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd);
+static int me4000_ai_do_cmd_test(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd);
-static int me4000_ai_do_cmd(comedi_device * dev, comedi_subdevice * s);
+static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
-static int me4000_ao_insn_write(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_ao_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
-static int me4000_ao_insn_read(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_ao_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
/*-----------------------------------------------------------------------------
Meilhaus inline functions
---------------------------------------------------------------------------*/
-static inline void me4000_outb(comedi_device * dev, unsigned char value,
+static inline void me4000_outb(struct comedi_device *dev, unsigned char value,
unsigned long port)
{
PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
outb(value, port);
}
-static inline void me4000_outl(comedi_device * dev, unsigned long value,
+static inline void me4000_outl(struct comedi_device *dev, unsigned long value,
unsigned long port)
{
PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
outl(value, port);
}
-static inline unsigned long me4000_inl(comedi_device * dev, unsigned long port)
+static inline unsigned long me4000_inl(struct comedi_device *dev, unsigned long port)
{
unsigned long value;
value = inl(port);
@@ -222,7 +222,7 @@ static inline unsigned long me4000_inl(comedi_device * dev, unsigned long port)
return value;
}
-static inline unsigned char me4000_inb(comedi_device * dev, unsigned long port)
+static inline unsigned char me4000_inb(struct comedi_device *dev, unsigned long port)
{
unsigned char value;
value = inb(port);
@@ -230,7 +230,7 @@ static inline unsigned char me4000_inb(comedi_device * dev, unsigned long port)
return value;
}
-static const comedi_lrange me4000_ai_range = {
+static const struct comedi_lrange me4000_ai_range = {
4,
{
UNI_RANGE(2.5),
@@ -240,16 +240,16 @@ static const comedi_lrange me4000_ai_range = {
}
};
-static const comedi_lrange me4000_ao_range = {
+static const struct comedi_lrange me4000_ao_range = {
1,
{
BIP_RANGE(10),
}
};
-static int me4000_attach(comedi_device * dev, comedi_devconfig * it)
+static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
int result;
CALL_PDEBUG("In me4000_attach()\n");
@@ -277,7 +277,7 @@ static int me4000_attach(comedi_device * dev, comedi_devconfig * it)
s->subdev_flags =
SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
s->n_chan = thisboard->ai.count;
- s->maxdata = 0xFFFF; // 16 bit ADC
+ s->maxdata = 0xFFFF; /* 16 bit ADC */
s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
s->range_table = &me4000_ai_range;
s->insn_read = me4000_ai_insn_read;
@@ -312,7 +312,7 @@ static int me4000_attach(comedi_device * dev, comedi_devconfig * it)
s->type = COMEDI_SUBD_AO;
s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
s->n_chan = thisboard->ao.count;
- s->maxdata = 0xFFFF; // 16 bit DAC
+ s->maxdata = 0xFFFF; /* 16 bit DAC */
s->range_table = &me4000_ao_range;
s->insn_write = me4000_ao_insn_write;
s->insn_read = me4000_ao_insn_read;
@@ -358,7 +358,7 @@ static int me4000_attach(comedi_device * dev, comedi_devconfig * it)
s->type = COMEDI_SUBD_COUNTER;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
s->n_chan = thisboard->cnt.count;
- s->maxdata = 0xFFFF; // 16 bit counters
+ s->maxdata = 0xFFFF; /* 16 bit counters */
s->insn_read = me4000_cnt_insn_read;
s->insn_write = me4000_cnt_insn_write;
s->insn_config = me4000_cnt_insn_config;
@@ -369,18 +369,18 @@ static int me4000_attach(comedi_device * dev, comedi_devconfig * it)
return 0;
}
-static int me4000_probe(comedi_device * dev, comedi_devconfig * it)
+static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
{
struct pci_dev *pci_device;
int result, i;
- me4000_board_t *board;
+ struct me4000_board *board;
CALL_PDEBUG("In me4000_probe()\n");
/* Allocate private memory */
- if (alloc_private(dev, sizeof(me4000_info_t)) < 0) {
+ if (alloc_private(dev, sizeof(struct me4000_info)) < 0)
return -ENOMEM;
- }
+
/*
* Probe the device to determine what device in the series it is.
*/
@@ -405,7 +405,7 @@ static int me4000_probe(comedi_device * dev, comedi_devconfig * it)
}
}
dev->board_ptr = me4000_boards + i;
- board = (me4000_board_t *) dev->
+ board = (struct me4000_board *) dev->
board_ptr;
info->pci_dev_p = pci_device;
goto found;
@@ -512,7 +512,7 @@ static int me4000_probe(comedi_device * dev, comedi_devconfig * it)
return 0;
}
-static int get_registers(comedi_device * dev, struct pci_dev *pci_dev_p)
+static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p)
{
CALL_PDEBUG("In get_registers()\n");
@@ -564,27 +564,25 @@ static int get_registers(comedi_device * dev, struct pci_dev *pci_dev_p)
return 0;
}
-static int init_board_info(comedi_device * dev, struct pci_dev *pci_dev_p)
+static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p)
{
int result;
CALL_PDEBUG("In init_board_info()\n");
/* Init spin locks */
- //spin_lock_init(&info->preload_lock);
- //spin_lock_init(&info->ai_ctrl_lock);
+ /* spin_lock_init(&info->preload_lock); */
+ /* spin_lock_init(&info->ai_ctrl_lock); */
/* Get the serial number */
result = pci_read_config_dword(pci_dev_p, 0x2C, &info->serial_no);
- if (result != PCIBIOS_SUCCESSFUL) {
+ if (result != PCIBIOS_SUCCESSFUL)
return result;
- }
/* Get the hardware revision */
result = pci_read_config_byte(pci_dev_p, 0x08, &info->hw_revision);
- if (result != PCIBIOS_SUCCESSFUL) {
+ if (result != PCIBIOS_SUCCESSFUL)
return result;
- }
/* Get the vendor id */
info->vendor_id = pci_dev_p->vendor;
@@ -598,14 +596,14 @@ static int init_board_info(comedi_device * dev, struct pci_dev *pci_dev_p)
return 0;
}
-static int init_ao_context(comedi_device * dev)
+static int init_ao_context(struct comedi_device *dev)
{
int i;
CALL_PDEBUG("In init_ao_context()\n");
for (i = 0; i < thisboard->ao.count; i++) {
- //spin_lock_init(&info->ao_context[i].use_lock);
+ /* spin_lock_init(&info->ao_context[i].use_lock); */
info->ao_context[i].irq = info->irq;
switch (i) {
@@ -681,7 +679,7 @@ static int init_ao_context(comedi_device * dev)
return 0;
}
-static int init_ai_context(comedi_device * dev)
+static int init_ai_context(struct comedi_device *dev)
{
CALL_PDEBUG("In init_ai_context()\n");
@@ -715,7 +713,7 @@ static int init_ai_context(comedi_device * dev)
return 0;
}
-static int init_dio_context(comedi_device * dev)
+static int init_dio_context(struct comedi_device *dev)
{
CALL_PDEBUG("In init_dio_context()\n");
@@ -734,7 +732,7 @@ static int init_dio_context(comedi_device * dev)
return 0;
}
-static int init_cnt_context(comedi_device * dev)
+static int init_cnt_context(struct comedi_device *dev)
{
CALL_PDEBUG("In init_cnt_context()\n");
@@ -755,7 +753,7 @@ static int init_cnt_context(comedi_device * dev)
extern unsigned char *xilinx_firm;
#endif
-static int xilinx_download(comedi_device * dev)
+static int xilinx_download(struct comedi_device *dev)
{
u32 value = 0;
wait_queue_head_t queue;
@@ -782,7 +780,7 @@ static int xilinx_download(comedi_device * dev)
/* Wait until /INIT pin is set */
udelay(20);
- if (!inl(info->plx_regbase + PLX_INTCSR) & 0x20) {
+ if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) {
printk(KERN_ERR
"comedi%d: me4000: xilinx_download(): Can't init Xilinx\n",
dev->minor);
@@ -837,7 +835,7 @@ static int xilinx_download(comedi_device * dev)
return 0;
}
-static int reset_board(comedi_device * dev)
+static int reset_board(struct comedi_device *dev)
{
unsigned long icr;
@@ -895,16 +893,15 @@ static int reset_board(comedi_device * dev)
return 0;
}
-static int me4000_detach(comedi_device * dev)
+static int me4000_detach(struct comedi_device *dev)
{
CALL_PDEBUG("In me4000_detach()\n");
if (info) {
if (info->pci_dev_p) {
reset_board(dev);
- if (info->plx_regbase) {
+ if (info->plx_regbase)
comedi_pci_disable(info->pci_dev_p);
- }
pci_dev_put(info->pci_dev_p);
}
}
@@ -916,8 +913,8 @@ static int me4000_detach(comedi_device * dev)
Analog input section
===========================================================================*/
-static int me4000_ai_insn_read(comedi_device * dev,
- comedi_subdevice * subdevice, comedi_insn * insn, lsampl_t * data)
+static int me4000_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data)
{
int chan = CR_CHAN(insn->chanspec);
@@ -1040,7 +1037,7 @@ static int me4000_ai_insn_read(comedi_device * dev,
return 1;
}
-static int me4000_ai_cancel(comedi_device * dev, comedi_subdevice * s)
+static int me4000_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
unsigned long tmp;
@@ -1057,8 +1054,8 @@ static int me4000_ai_cancel(comedi_device * dev, comedi_subdevice * s)
return 0;
}
-static int ai_check_chanlist(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd)
+static int ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
int aref;
int i;
@@ -1138,9 +1135,9 @@ static int ai_check_chanlist(comedi_device * dev,
return 0;
}
-static int ai_round_cmd_args(comedi_device * dev,
- comedi_subdevice * s,
- comedi_cmd * cmd,
+static int ai_round_cmd_args(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd,
unsigned int *init_ticks,
unsigned int *scan_ticks, unsigned int *chan_ticks)
{
@@ -1163,9 +1160,8 @@ static int ai_round_cmd_args(comedi_device * dev,
rest = (cmd->start_arg * 33) % 1000;
if (cmd->flags & TRIG_ROUND_NEAREST) {
- if (rest > 33) {
+ if (rest > 33)
(*init_ticks)++;
- }
} else if (cmd->flags & TRIG_ROUND_UP) {
if (rest)
(*init_ticks)++;
@@ -1177,9 +1173,8 @@ static int ai_round_cmd_args(comedi_device * dev,
rest = (cmd->scan_begin_arg * 33) % 1000;
if (cmd->flags & TRIG_ROUND_NEAREST) {
- if (rest > 33) {
+ if (rest > 33)
(*scan_ticks)++;
- }
} else if (cmd->flags & TRIG_ROUND_UP) {
if (rest)
(*scan_ticks)++;
@@ -1191,9 +1186,8 @@ static int ai_round_cmd_args(comedi_device * dev,
rest = (cmd->convert_arg * 33) % 1000;
if (cmd->flags & TRIG_ROUND_NEAREST) {
- if (rest > 33) {
+ if (rest > 33)
(*chan_ticks)++;
- }
} else if (cmd->flags & TRIG_ROUND_UP) {
if (rest)
(*chan_ticks)++;
@@ -1207,7 +1201,7 @@ static int ai_round_cmd_args(comedi_device * dev,
return 0;
}
-static void ai_write_timer(comedi_device * dev,
+static void ai_write_timer(struct comedi_device *dev,
unsigned int init_ticks,
unsigned int scan_ticks, unsigned int chan_ticks)
{
@@ -1228,9 +1222,9 @@ static void ai_write_timer(comedi_device * dev,
me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_timer_reg);
}
-static int ai_prepare(comedi_device * dev,
- comedi_subdevice * s,
- comedi_cmd * cmd,
+static int ai_prepare(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd,
unsigned int init_ticks,
unsigned int scan_ticks, unsigned int chan_ticks)
{
@@ -1297,8 +1291,8 @@ static int ai_prepare(comedi_device * dev,
return 0;
}
-static int ai_write_chanlist(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd)
+static int ai_write_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
unsigned int entry;
unsigned int chan;
@@ -1337,13 +1331,13 @@ static int ai_write_chanlist(comedi_device * dev,
return 0;
}
-static int me4000_ai_do_cmd(comedi_device * dev, comedi_subdevice * s)
+static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
int err;
unsigned int init_ticks = 0;
unsigned int scan_ticks = 0;
unsigned int chan_ticks = 0;
- comedi_cmd *cmd = &s->async->cmd;
+ struct comedi_cmd *cmd = &s->async->cmd;
CALL_PDEBUG("In me4000_ai_do_cmd()\n");
@@ -1381,8 +1375,8 @@ static int me4000_ai_do_cmd(comedi_device * dev, comedi_subdevice * s)
* - invalid chanlist
* So I tried to adopt this scheme.
*/
-static int me4000_ai_do_cmd_test(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd)
+static int me4000_ai_do_cmd_test(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
unsigned int init_ticks;
@@ -1503,9 +1497,8 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
cmd->stop_src = TRIG_NONE;
err++;
}
- if (err) {
+ if (err)
return 1;
- }
/*
* Stage 2. Check for trigger source conflicts.
@@ -1553,9 +1546,8 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
cmd->scan_end_src = TRIG_NONE;
err++;
}
- if (err) {
+ if (err)
return 2;
- }
/*
* Stage 3. Check if arguments are generally valid.
@@ -1588,9 +1580,9 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
cmd->convert_arg = 2000;
err++;
}
- if (err) {
+
+ if (err)
return 3;
- }
/*
* Stage 4. Check for argument conflicts.
@@ -1604,21 +1596,21 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
dev->minor);
- cmd->start_arg = 2000; // 66 ticks at least
+ cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
dev->minor);
- cmd->convert_arg = 2000; // 66 ticks at least
+ cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
dev->minor);
- cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; // At least one tick more
+ cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; /* At least one tick more */
err++;
}
} else if (cmd->start_src == TRIG_NOW &&
@@ -1630,14 +1622,14 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
dev->minor);
- cmd->start_arg = 2000; // 66 ticks at least
+ cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
dev->minor);
- cmd->convert_arg = 2000; // 66 ticks at least
+ cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
} else if (cmd->start_src == TRIG_EXT &&
@@ -1649,21 +1641,21 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
dev->minor);
- cmd->start_arg = 2000; // 66 ticks at least
+ cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
dev->minor);
- cmd->convert_arg = 2000; // 66 ticks at least
+ cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
dev->minor);
- cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; // At least one tick more
+ cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; /* At least one tick more */
err++;
}
} else if (cmd->start_src == TRIG_EXT &&
@@ -1675,14 +1667,14 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
dev->minor);
- cmd->start_arg = 2000; // 66 ticks at least
+ cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
dev->minor);
- cmd->convert_arg = 2000; // 66 ticks at least
+ cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
} else if (cmd->start_src == TRIG_EXT &&
@@ -1694,14 +1686,14 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
dev->minor);
- cmd->start_arg = 2000; // 66 ticks at least
+ cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
dev->minor);
- cmd->convert_arg = 2000; // 66 ticks at least
+ cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
} else if (cmd->start_src == TRIG_EXT &&
@@ -1713,7 +1705,7 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
dev->minor);
- cmd->start_arg = 2000; // 66 ticks at least
+ cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
}
@@ -1735,9 +1727,9 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
err++;
}
}
- if (err) {
+
+ if (err)
return 4;
- }
/*
* Stage 5. Check the channel list.
@@ -1751,9 +1743,9 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG)
{
unsigned int tmp;
- comedi_device *dev = dev_id;
- comedi_subdevice *s = dev->subdevices;
- me4000_ai_context_t *ai_context = &info->ai_context;
+ struct comedi_device *dev = dev_id;
+ struct comedi_subdevice *s = dev->subdevices;
+ struct me4000_ai_context *ai_context = &info->ai_context;
int i;
int c = 0;
long lval;
@@ -1911,8 +1903,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG)
Analog output section
===========================================================================*/
-static int me4000_ao_insn_write(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_ao_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int chan = CR_CHAN(insn->chanspec);
@@ -1969,8 +1961,8 @@ static int me4000_ao_insn_write(comedi_device * dev,
return 1;
}
-static int me4000_ao_insn_read(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_ao_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int chan = CR_CHAN(insn->chanspec);
@@ -1990,16 +1982,16 @@ static int me4000_ao_insn_read(comedi_device * dev,
Digital I/O section
===========================================================================*/
-static int me4000_dio_insn_bits(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_dio_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
CALL_PDEBUG("In me4000_dio_insn_bits()\n");
/* Length of data must be 2 (mask and new data, see below) */
- if (insn->n == 0) {
+ if (insn->n == 0)
return 0;
- }
+
if (insn->n != 2) {
printk("comedi%d: me4000: me4000_dio_insn_bits(): Invalid instruction length\n", dev->minor);
return -EINVAL;
@@ -2041,8 +2033,8 @@ static int me4000_dio_insn_bits(comedi_device * dev,
return 2;
}
-static int me4000_dio_insn_config(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_dio_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
unsigned long tmp;
int chan = CR_CHAN(insn->chanspec);
@@ -2135,7 +2127,7 @@ static int me4000_dio_insn_config(comedi_device * dev,
Counter section
===========================================================================*/
-static int cnt_reset(comedi_device * dev, unsigned int channel)
+static int cnt_reset(struct comedi_device *dev, unsigned int channel)
{
CALL_PDEBUG("In cnt_reset()\n");
@@ -2166,7 +2158,7 @@ static int cnt_reset(comedi_device * dev, unsigned int channel)
return 0;
}
-static int cnt_config(comedi_device * dev, unsigned int channel,
+static int cnt_config(struct comedi_device *dev, unsigned int channel,
unsigned int mode)
{
int tmp = 0;
@@ -2223,8 +2215,8 @@ static int cnt_config(comedi_device * dev, unsigned int channel,
return 0;
}
-static int me4000_cnt_insn_config(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_cnt_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int err;
@@ -2266,17 +2258,17 @@ static int me4000_cnt_insn_config(comedi_device * dev,
return 2;
}
-static int me4000_cnt_insn_read(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_cnt_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
unsigned short tmp;
CALL_PDEBUG("In me4000_cnt_insn_read()\n");
- if (insn->n == 0) {
+ if (insn->n == 0)
return 0;
- }
+
if (insn->n > 1) {
printk(KERN_ERR
"comedi%d: me4000: me4000_cnt_insn_read(): Invalid instruction length %d\n",
@@ -2313,8 +2305,8 @@ static int me4000_cnt_insn_read(comedi_device * dev,
return 1;
}
-static int me4000_cnt_insn_write(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_cnt_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
unsigned short tmp;
diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h
index f12b8873ec3..733b19243c7 100644
--- a/drivers/staging/comedi/drivers/me4000.h
+++ b/drivers/staging/comedi/drivers/me4000.h
@@ -28,37 +28,37 @@
Debug section
===========================================================================*/
-#undef ME4000_CALL_DEBUG // Debug function entry and exit
-#undef ME4000_PORT_DEBUG // Debug port access
-#undef ME4000_ISR_DEBUG // Debug the interrupt service routine
-#undef ME4000_DEBUG // General purpose debug masseges
+#undef ME4000_CALL_DEBUG /* Debug function entry and exit */
+#undef ME4000_PORT_DEBUG /* Debug port access */
+#undef ME4000_ISR_DEBUG /* Debug the interrupt service routine */
+#undef ME4000_DEBUG /* General purpose debug masseges */
#ifdef ME4000_CALL_DEBUG
#undef CALL_PDEBUG
#define CALL_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args)
#else
-# define CALL_PDEBUG(fmt, args...) // no debugging, do nothing
+# define CALL_PDEBUG(fmt, args...) /* no debugging, do nothing */
#endif
#ifdef ME4000_PORT_DEBUG
#undef PORT_PDEBUG
#define PORT_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args)
#else
-#define PORT_PDEBUG(fmt, args...) // no debugging, do nothing
+#define PORT_PDEBUG(fmt, args...) /* no debugging, do nothing */
#endif
#ifdef ME4000_ISR_DEBUG
#undef ISR_PDEBUG
#define ISR_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args)
#else
-#define ISR_PDEBUG(fmt, args...) // no debugging, do nothing
+#define ISR_PDEBUG(fmt, args...) /* no debugging, do nothing */
#endif
#ifdef ME4000_DEBUG
#undef PDEBUG
#define PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args)
#else
-#define PDEBUG(fmt, args...) // no debugging, do nothing
+#define PDEBUG(fmt, args...) /* no debugging, do nothing */
#endif
/*=============================================================================
@@ -67,78 +67,78 @@
#define PCI_VENDOR_ID_MEILHAUS 0x1402
-#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650 // Low Cost version
+#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_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_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
+#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 */
/*=============================================================================
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
+#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
@@ -159,21 +159,21 @@
PLX base register offsets
===========================================================================*/
-#define PLX_INTCSR 0x4C // Interrupt control and status register
-#define PLX_ICR 0x50 // Initialization control register
+#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)
+#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
@@ -293,45 +293,45 @@
Information about the hardware capabilities
===========================================================================*/
-typedef struct me4000_ao_info {
+struct me4000_ao_info {
int count;
int fifo_count;
-} me4000_ao_info_t;
+};
-typedef struct me4000_ai_info {
+struct me4000_ai_info {
int count;
int sh_count;
int diff_count;
int ex_trig_analog;
-} me4000_ai_info_t;
+};
-typedef struct me4000_dio_info {
+struct me4000_dio_info {
int count;
-} me4000_dio_info_t;
+};
-typedef struct me4000_cnt_info {
+struct me4000_cnt_info {
int count;
-} me4000_cnt_info_t;
+};
-typedef struct me4000_board {
+struct me4000_board {
const char *name;
unsigned short device_id;
- me4000_ao_info_t ao;
- me4000_ai_info_t ai;
- me4000_dio_info_t dio;
- me4000_cnt_info_t cnt;
-} me4000_board_t;
+ struct me4000_ao_info ao;
+ struct me4000_ai_info ai;
+ struct me4000_dio_info dio;
+ struct me4000_cnt_info cnt;
+};
-#define thisboard ((const me4000_board_t *)dev->board_ptr)
+#define thisboard ((const struct me4000_board *)dev->board_ptr)
/*=============================================================================
Global board and subdevice information structures
===========================================================================*/
-typedef struct me4000_ao_context {
+struct me4000_ao_context {
int irq;
- unsigned long mirror; // Store the last written value
+ unsigned long mirror; /* Store the last written value */
unsigned long ctrl_reg;
unsigned long status_reg;
@@ -340,9 +340,9 @@ typedef struct me4000_ao_context {
unsigned long timer_reg;
unsigned long irq_status_reg;
unsigned long preload_reg;
-} me4000_ao_context_t;
+};
-typedef struct me4000_ai_context {
+struct me4000_ai_context {
int irq;
unsigned long ctrl_reg;
@@ -358,51 +358,51 @@ typedef struct me4000_ai_context {
unsigned long start_reg;
unsigned long irq_status_reg;
unsigned long sample_counter_reg;
-} me4000_ai_context_t;
+};
-typedef struct me4000_dio_context {
+struct me4000_dio_context {
unsigned long dir_reg;
unsigned long ctrl_reg;
unsigned long port_0_reg;
unsigned long port_1_reg;
unsigned long port_2_reg;
unsigned long port_3_reg;
-} me4000_dio_context_t;
+};
-typedef struct me4000_cnt_context {
+struct me4000_cnt_context {
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_info {
- 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
+struct me4000_info {
+ 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 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
- unsigned short device_id; // Device id
+ 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 */
+ unsigned short device_id; /* Device id */
- struct pci_dev *pci_dev_p; // General PCI information
+ struct pci_dev *pci_dev_p; /* General PCI information */
- unsigned int irq; // IRQ assigned from the PCI BIOS
+ unsigned int irq; /* IRQ assigned from the PCI BIOS */
- struct me4000_ai_context ai_context; // Analog input specific context
- struct me4000_ao_context ao_context[4]; // Vector with analog output specific context
- struct me4000_dio_context dio_context; // Digital I/O specific context
- struct me4000_cnt_context cnt_context; // Counter specific context
-} me4000_info_t;
+ struct me4000_ai_context ai_context; /* Analog input specific context */
+ struct me4000_ao_context ao_context[4]; /* Vector with analog output specific context */
+ struct me4000_dio_context dio_context; /* Digital I/O specific context */
+ struct me4000_cnt_context cnt_context; /* Counter specific context */
+};
-#define info ((me4000_info_t *)dev->private)
+#define info ((struct me4000_info *)dev->private)
/*-----------------------------------------------------------------------------
Defines for analog input
@@ -412,7 +412,7 @@ typedef struct me4000_info {
#define ME4000_AI_FIFO_COUNT 2048
#define ME4000_AI_MIN_TICKS 66
-#define ME4000_AI_MIN_SAMPLE_TIME 2000 // Minimum sample time [ns]
+#define ME4000_AI_MIN_SAMPLE_TIME 2000 /* Minimum sample time [ns] */
#define ME4000_AI_BASE_FREQUENCY (unsigned int) 33E6
/* Channel list defines and masks */
@@ -436,11 +436,11 @@ typedef struct me4000_info {
#define ME4000_CNT_COUNTER_1 0x40
#define ME4000_CNT_COUNTER_2 0x80
-#define ME4000_CNT_MODE_0 0x00 // Change state if zero crossing
-#define ME4000_CNT_MODE_1 0x02 // Retriggerable One-Shot
-#define ME4000_CNT_MODE_2 0x04 // Asymmetrical divider
-#define ME4000_CNT_MODE_3 0x06 // Symmetrical divider
-#define ME4000_CNT_MODE_4 0x08 // Counter start by software trigger
-#define ME4000_CNT_MODE_5 0x0A // Counter start by hardware trigger
+#define ME4000_CNT_MODE_0 0x00 /* Change state if zero crossing */
+#define ME4000_CNT_MODE_1 0x02 /* Retriggerable One-Shot */
+#define ME4000_CNT_MODE_2 0x04 /* Asymmetrical divider */
+#define ME4000_CNT_MODE_3 0x06 /* Symmetrical divider */
+#define ME4000_CNT_MODE_4 0x08 /* Counter start by software trigger */
+#define ME4000_CNT_MODE_5 0x0A /* Counter start by hardware trigger */
#endif
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
index 6accec20a0f..0f023d009e6 100644
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ b/drivers/staging/comedi/drivers/me_daq.c
@@ -144,10 +144,10 @@ from http://www.comedi.org
#define ME_COUNTER_VALUE_B 0x0022 /* R | - */
/* Function prototypes */
-static int me_attach(comedi_device *dev, comedi_devconfig *it);
-static int me_detach(comedi_device *dev);
+static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int me_detach(struct comedi_device *dev);
-static const comedi_lrange me2000_ai_range = {
+static const struct comedi_lrange me2000_ai_range = {
8,
{
BIP_RANGE(10),
@@ -161,7 +161,7 @@ static const comedi_lrange me2000_ai_range = {
}
};
-static const comedi_lrange me2600_ai_range = {
+static const struct comedi_lrange me2600_ai_range = {
8,
{
BIP_RANGE(10),
@@ -175,7 +175,7 @@ static const comedi_lrange me2600_ai_range = {
}
};
-static const comedi_lrange me2600_ao_range = {
+static const struct comedi_lrange me2600_ao_range = {
3,
{
BIP_RANGE(10),
@@ -201,11 +201,11 @@ struct me_board {
int ao_channel_nbr; /* DA config */
int ao_resolution;
int ao_resolution_mask;
- const comedi_lrange *ao_range_list;
+ const struct comedi_lrange *ao_range_list;
int ai_channel_nbr; /* AD config */
int ai_resolution;
int ai_resolution_mask;
- const comedi_lrange *ai_range_list;
+ const struct comedi_lrange *ai_range_list;
int dio_channel_nbr; /* DIO config */
};
@@ -246,7 +246,8 @@ static const struct me_board me_boards[] = {
#define me_board_nbr (sizeof(me_boards)/sizeof(struct me_board))
-static comedi_driver me_driver = {
+
+static struct comedi_driver me_driver = {
.driver_name = ME_DRIVER_NAME,
.module = THIS_MODULE,
.attach = me_attach,
@@ -290,8 +291,8 @@ static inline void sleep(unsigned sec)
*
* ------------------------------------------------------------------
*/
-static int me_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int bits;
int mask = 1 << CR_CHAN(insn->chanspec);
@@ -326,8 +327,8 @@ static int me_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
}
/* Digital instant input/outputs */
-static int me_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
unsigned int mask = data[0];
s->state &= ~mask;
@@ -362,8 +363,8 @@ static int me_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
*/
/* Analog instant input */
-static int me_ai_insn_read(comedi_device *dev, comedi_subdevice *subdevice,
- comedi_insn *insn, lsampl_t *data)
+static int me_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *subdevice,
+ struct comedi_insn *insn, unsigned int *data)
{
unsigned short value;
int chan = CR_CHAN((&insn->chanspec)[0]);
@@ -436,7 +437,7 @@ static int me_ai_insn_read(comedi_device *dev, comedi_subdevice *subdevice,
*/
/* Cancel analog input autoscan */
-static int me_ai_cancel(comedi_device *dev, comedi_subdevice *s)
+static int me_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
/* disable interrupts */
@@ -448,14 +449,14 @@ static int me_ai_cancel(comedi_device *dev, comedi_subdevice *s)
}
/* Test analog input command */
-static int me_ai_do_cmd_test(comedi_device *dev, comedi_subdevice *s,
- comedi_cmd *cmd)
+static int me_ai_do_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
return 0;
}
/* Analog input command */
-static int me_ai_do_cmd(comedi_device *dev, comedi_subdevice *subdevice)
+static int me_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *subdevice)
{
return 0;
}
@@ -469,8 +470,8 @@ static int me_ai_do_cmd(comedi_device *dev, comedi_subdevice *subdevice)
*/
/* Analog instant output */
-static int me_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int chan;
int rang;
@@ -519,8 +520,8 @@ static int me_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
}
/* Analog output readback */
-static int me_ao_insn_read(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int me_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i;
@@ -541,7 +542,7 @@ static int me_ao_insn_read(comedi_device *dev, comedi_subdevice *s,
*/
/* Xilinx firmware download for card: ME-2600i */
-static int me2600_xilinx_download(comedi_device *dev,
+static int me2600_xilinx_download(struct comedi_device *dev,
unsigned char *me2600_firmware,
unsigned int length)
{
@@ -609,7 +610,7 @@ static int me2600_xilinx_download(comedi_device *dev,
}
/* Reset device */
-static int me_reset(comedi_device *dev)
+static int me_reset(struct comedi_device *dev)
{
/* Reset board */
writew(0x00, dev_private->me_regbase + ME_CONTROL_1);
@@ -631,10 +632,10 @@ static int me_reset(comedi_device *dev)
* - Register PCI device
* - Declare device driver capability
*/
-static int me_attach(comedi_device *dev, comedi_devconfig *it)
+static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
struct pci_dev *pci_device;
- comedi_subdevice *subdevice;
+ struct comedi_subdevice *subdevice;
struct me_board *board;
resource_size_t plx_regbase_tmp;
unsigned long plx_regbase_size_tmp;
@@ -825,7 +826,7 @@ found:
}
/* Detach */
-static int me_detach(comedi_device *dev)
+static int me_detach(struct comedi_device *dev)
{
if (dev_private) {
if (dev_private->me_regbase) {
diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c
index 9cc527424d0..ae901774453 100644
--- a/drivers/staging/comedi/drivers/mite.c
+++ b/drivers/staging/comedi/drivers/mite.c
@@ -47,7 +47,7 @@
*/
-//#define USE_KMALLOC
+/* #define USE_KMALLOC */
#include "mite.h"
@@ -63,7 +63,7 @@
MODULE_LICENSE("GPL");
-struct mite_struct *mite_devices = NULL;
+struct mite_struct *mite_devices;
#define TOP_OF_PAGE(x) ((x)|(~(PAGE_MASK)))
@@ -103,7 +103,7 @@ static void dump_chip_signature(u32 csigr_bits)
printk("mite: num channels = %i, write post fifo depth = %i, wins = %i, iowins = %i\n", mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits), mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits));
}
-unsigned mite_fifo_size(struct mite_struct * mite, unsigned channel)
+unsigned mite_fifo_size(struct mite_struct *mite, unsigned channel)
{
unsigned fcr_bits = readl(mite->mite_io_addr +
MITE_FCR(channel));
@@ -139,7 +139,7 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
addr = pci_resource_start(mite->pcidev, 1);
mite->daq_phys_addr = addr;
length = pci_resource_len(mite->pcidev, 1);
- // In case of a 660x board, DAQ size is 8k instead of 4k (see as shown by lspci output)
+ /* In case of a 660x board, DAQ size is 8k instead of 4k (see as shown by lspci output) */
mite->daq_io_addr = ioremap(mite->daq_phys_addr, length);
if (!mite->daq_io_addr) {
printk("failed to remap daq io memory address\n");
@@ -212,7 +212,7 @@ void mite_cleanup(void)
void mite_unsetup(struct mite_struct *mite)
{
- //unsigned long offset, start, length;
+ /* unsigned long offset, start, length; */
if (!mite)
return;
@@ -257,7 +257,7 @@ struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite,
unsigned long flags;
struct mite_channel *channel = NULL;
- // spin lock so mite_release_channel can be called safely from interrupts
+ /* spin lock so mite_release_channel can be called safely from interrupts */
comedi_spin_lock_irqsave(&mite->lock, flags);
for (i = min_channel; i <= max_channel; ++i) {
if (mite->channel_allocated[i] == 0) {
@@ -276,7 +276,7 @@ void mite_release_channel(struct mite_channel *mite_chan)
struct mite_struct *mite = mite_chan->mite;
unsigned long flags;
- // spin lock to prevent races with mite_request_channel
+ /* spin lock to prevent races with mite_request_channel */
comedi_spin_lock_irqsave(&mite->lock, flags);
if (mite->channel_allocated[mite_chan->channel]) {
mite_dma_disarm(mite_chan);
@@ -312,12 +312,12 @@ void mite_dma_arm(struct mite_channel *mite_chan)
writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
mmiowb();
comedi_spin_unlock_irqrestore(&mite->lock, flags);
-// mite_dma_tcr(mite, channel);
+/* mite_dma_tcr(mite, channel); */
}
/**************************************/
-int mite_buf_change(struct mite_dma_descriptor_ring *ring, comedi_async * async)
+int mite_buf_change(struct mite_dma_descriptor_ring *ring, struct comedi_async * async)
{
unsigned int n_links;
int i;
@@ -331,9 +331,9 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, comedi_async * async)
ring->descriptors_dma_addr = 0;
ring->n_links = 0;
- if (async->prealloc_bufsz == 0) {
+ if (async->prealloc_bufsz == 0)
return 0;
- }
+
n_links = async->prealloc_bufsz >> PAGE_SHIFT;
MDPRINTK("ring->hw_dev=%p, n_links=0x%04x\n", ring->hw_dev, n_links);
@@ -395,9 +395,9 @@ void mite_prep_dma(struct mite_channel *mite_chan,
on e-series boards. */
chcr |= CHCR_BYTE_SWAP_DEVICE | CHCR_BYTE_SWAP_MEMORY;
}
- if (mite_chan->dir == COMEDI_INPUT) {
+ if (mite_chan->dir == COMEDI_INPUT)
chcr |= CHCR_DEV_TO_MEM;
- }
+
writel(chcr, mite->mite_io_addr + MITE_CHCR(mite_chan->channel));
/* to/from memory */
@@ -459,15 +459,15 @@ u32 mite_device_bytes_transferred(struct mite_channel *mite_chan)
return readl(mite->mite_io_addr + MITE_DAR(mite_chan->channel));
}
-u32 mite_bytes_in_transit(struct mite_channel * mite_chan)
+u32 mite_bytes_in_transit(struct mite_channel *mite_chan)
{
struct mite_struct *mite = mite_chan->mite;
return readl(mite->mite_io_addr +
MITE_FCR(mite_chan->channel)) & 0x000000FF;
}
-// returns lower bound for number of bytes transferred from device to memory
-u32 mite_bytes_written_to_memory_lb(struct mite_channel * mite_chan)
+/* returns lower bound for number of bytes transferred from device to memory */
+u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan)
{
u32 device_byte_count;
@@ -475,8 +475,8 @@ u32 mite_bytes_written_to_memory_lb(struct mite_channel * mite_chan)
return device_byte_count - mite_bytes_in_transit(mite_chan);
}
-// returns upper bound for number of bytes transferred from device to memory
-u32 mite_bytes_written_to_memory_ub(struct mite_channel * mite_chan)
+/* returns upper bound for number of bytes transferred from device to memory */
+u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan)
{
u32 in_transit_count;
@@ -484,8 +484,8 @@ u32 mite_bytes_written_to_memory_ub(struct mite_channel * mite_chan)
return mite_device_bytes_transferred(mite_chan) - in_transit_count;
}
-// returns lower bound for number of bytes read from memory for transfer to device
-u32 mite_bytes_read_from_memory_lb(struct mite_channel * mite_chan)
+/* returns lower bound for number of bytes read from memory for transfer to device */
+u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan)
{
u32 device_byte_count;
@@ -493,8 +493,8 @@ u32 mite_bytes_read_from_memory_lb(struct mite_channel * mite_chan)
return device_byte_count + mite_bytes_in_transit(mite_chan);
}
-// returns upper bound for number of bytes read from memory for transfer to device
-u32 mite_bytes_read_from_memory_ub(struct mite_channel * mite_chan)
+/* returns upper bound for number of bytes read from memory for transfer to device */
+u32 mite_bytes_read_from_memory_ub(struct mite_channel *mite_chan)
{
u32 in_transit_count;
@@ -526,14 +526,14 @@ void mite_dma_disarm(struct mite_channel *mite_chan)
writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
}
-int mite_sync_input_dma(struct mite_channel *mite_chan, comedi_async * async)
+int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_async * async)
{
int count;
unsigned int nbytes, old_alloc_count;
const unsigned bytes_per_scan = cfc_bytes_per_scan(async->subdevice);
old_alloc_count = async->buf_write_alloc_count;
- // write alloc as much as we can
+ /* write alloc as much as we can */
comedi_buf_write_alloc(async, async->prealloc_bufsz);
nbytes = mite_bytes_written_to_memory_lb(mite_chan);
@@ -547,9 +547,9 @@ int mite_sync_input_dma(struct mite_channel *mite_chan, comedi_async * async)
count = nbytes - async->buf_write_count;
/* it's possible count will be negative due to
* conservative value returned by mite_bytes_written_to_memory_lb */
- if (count <= 0) {
+ if (count <= 0)
return 0;
- }
+
comedi_buf_write_free(async, count);
async->scan_progress += count;
@@ -561,7 +561,7 @@ int mite_sync_input_dma(struct mite_channel *mite_chan, comedi_async * async)
return 0;
}
-int mite_sync_output_dma(struct mite_channel *mite_chan, comedi_async * async)
+int mite_sync_output_dma(struct mite_channel *mite_chan, struct comedi_async * async)
{
int count;
u32 nbytes_ub, nbytes_lb;
@@ -570,7 +570,7 @@ int mite_sync_output_dma(struct mite_channel *mite_chan, comedi_async * async)
async->cmd.stop_arg * cfc_bytes_per_scan(async->subdevice);
old_alloc_count = async->buf_read_alloc_count;
- // read alloc as much as we can
+ /* read alloc as much as we can */
comedi_buf_read_alloc(async, async->prealloc_bufsz);
nbytes_lb = mite_bytes_read_from_memory_lb(mite_chan);
if (async->cmd.stop_src == TRIG_COUNT &&
@@ -586,9 +586,9 @@ int mite_sync_output_dma(struct mite_channel *mite_chan, comedi_async * async)
return -1;
}
count = nbytes_lb - async->buf_read_count;
- if (count <= 0) {
+ if (count <= 0)
return 0;
- }
+
if (count) {
comedi_buf_read_free(async, count);
async->events |= COMEDI_CB_BLOCK;
@@ -753,9 +753,8 @@ static void mite_decode(char **bit_str, unsigned int bits)
int i;
for (i = 31; i >= 0; i--) {
- if (bits & (1 << i)) {
+ if (bits & (1 << i))
printk(" %s", bit_str[i]);
- }
}
printk("\n");
}
diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h
index b84eafa6ff2..cdaf8a31688 100644
--- a/drivers/staging/comedi/drivers/mite.h
+++ b/drivers/staging/comedi/drivers/mite.h
@@ -29,13 +29,13 @@
#define PCI_VENDOR_ID_NATINST 0x1093
-// #define DEBUG_MITE
+/* #define DEBUG_MITE */
#define PCIMIO_COMPAT
#ifdef DEBUG_MITE
-#define MDPRINTK(format,args...) printk(format , ## args )
+#define MDPRINTK(format, args...) printk(format , ## args)
#else
-#define MDPRINTK(format,args...)
+#define MDPRINTK(format, args...)
#endif
#define MAX_MITE_DMA_CHANNELS 8
@@ -142,8 +142,8 @@ void mite_release_channel(struct mite_channel *mite_chan);
unsigned mite_dma_tcr(struct mite_channel *mite_chan);
void mite_dma_arm(struct mite_channel *mite_chan);
void mite_dma_disarm(struct mite_channel *mite_chan);
-int mite_sync_input_dma(struct mite_channel *mite_chan, comedi_async * async);
-int mite_sync_output_dma(struct mite_channel *mite_chan, comedi_async * async);
+int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_async * async);
+int mite_sync_output_dma(struct mite_channel *mite_chan, struct comedi_async * async);
u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan);
u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan);
u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan);
@@ -153,7 +153,7 @@ unsigned mite_get_status(struct mite_channel *mite_chan);
int mite_done(struct mite_channel *mite_chan);
#if 0
-unsigned long mite_ll_from_kvmem(struct mite_struct *mite, comedi_async * async,
+unsigned long mite_ll_from_kvmem(struct mite_struct *mite, struct comedi_async * async,
int len);
void mite_setregs(struct mite_struct *mite, unsigned long ll_start, int chan,
int dir);
@@ -162,7 +162,7 @@ void mite_setregs(struct mite_struct *mite, unsigned long ll_start, int chan,
void mite_prep_dma(struct mite_channel *mite_chan,
unsigned int num_device_bits, unsigned int num_memory_bits);
int mite_buf_change(struct mite_dma_descriptor_ring *ring,
- comedi_async * async);
+ struct comedi_async *async);
#ifdef DEBUG_MITE
void mite_print_chsr(unsigned int chsr);
@@ -179,83 +179,83 @@ enum mite_registers {
written and read back. The bits 0x1f always read as 1.
The rest always read as zero. */
MITE_UNKNOWN_DMA_BURST_REG = 0x28,
- MITE_IODWBSR = 0xc0, //IO Device Window Base Size Register
- MITE_IODWBSR_1 = 0xc4, // IO Device Window Base Size Register 1
+ MITE_IODWBSR = 0xc0, /* IO Device Window Base Size Register */
+ MITE_IODWBSR_1 = 0xc4, /* IO Device Window Base Size Register 1 */
MITE_IODWCR_1 = 0xf4,
MITE_PCI_CONFIG_OFFSET = 0x300,
- MITE_CSIGR = 0x460 //chip signature
+ MITE_CSIGR = 0x460 /* chip signature */
};
-static inline int MITE_CHOR(int channel) // channel operation
+static inline int MITE_CHOR(int channel) /* channel operation */
{
return CHAN_OFFSET(channel) + 0x0;
};
-static inline int MITE_CHCR(int channel) // channel control
+static inline int MITE_CHCR(int channel) /* channel control */
{
return CHAN_OFFSET(channel) + 0x4;
};
-static inline int MITE_TCR(int channel) // transfer count
+static inline int MITE_TCR(int channel) /* transfer count */
{
return CHAN_OFFSET(channel) + 0x8;
};
-static inline int MITE_MCR(int channel) // memory configuration
+static inline int MITE_MCR(int channel) /* memory configuration */
{
return CHAN_OFFSET(channel) + 0xc;
};
-static inline int MITE_MAR(int channel) // memory address
+static inline int MITE_MAR(int channel) /* memory address */
{
return CHAN_OFFSET(channel) + 0x10;
};
-static inline int MITE_DCR(int channel) // device configuration
+static inline int MITE_DCR(int channel) /* device configuration */
{
return CHAN_OFFSET(channel) + 0x14;
};
-static inline int MITE_DAR(int channel) // device address
+static inline int MITE_DAR(int channel) /* device address */
{
return CHAN_OFFSET(channel) + 0x18;
};
-static inline int MITE_LKCR(int channel) // link configuration
+static inline int MITE_LKCR(int channel) /* link configuration */
{
return CHAN_OFFSET(channel) + 0x1c;
};
-static inline int MITE_LKAR(int channel) // link address
+static inline int MITE_LKAR(int channel) /* link address */
{
return CHAN_OFFSET(channel) + 0x20;
};
-static inline int MITE_LLKAR(int channel) // see mite section of tnt5002 manual
+static inline int MITE_LLKAR(int channel) /* see mite section of tnt5002 manual */
{
return CHAN_OFFSET(channel) + 0x24;
};
-static inline int MITE_BAR(int channel) // base address
+static inline int MITE_BAR(int channel) /* base address */
{
return CHAN_OFFSET(channel) + 0x28;
};
-static inline int MITE_BCR(int channel) // base count
+static inline int MITE_BCR(int channel) /* base count */
{
return CHAN_OFFSET(channel) + 0x2c;
};
-static inline int MITE_SAR(int channel) // ? address
+static inline int MITE_SAR(int channel) /* ? address */
{
return CHAN_OFFSET(channel) + 0x30;
};
-static inline int MITE_WSCR(int channel) // ?
+static inline int MITE_WSCR(int channel) /* ? */
{
return CHAN_OFFSET(channel) + 0x34;
};
-static inline int MITE_WSER(int channel) // ?
+static inline int MITE_WSER(int channel) /* ? */
{
return CHAN_OFFSET(channel) + 0x38;
};
-static inline int MITE_CHSR(int channel) // channel status
+static inline int MITE_CHSR(int channel) /* channel status */
{
return CHAN_OFFSET(channel) + 0x3c;
};
-static inline int MITE_FCR(int channel) // fifo count
+static inline int MITE_FCR(int channel) /* fifo count */
{
return CHAN_OFFSET(channel) + 0x40;
};
enum MITE_IODWBSR_bits {
- WENAB = 0x80, // window enable
+ WENAB = 0x80, /* window enable */
};
static inline unsigned MITE_IODWBSR_1_WSIZE_bits(unsigned size)
@@ -276,23 +276,23 @@ static inline int mite_csigr_version(u32 csigr_bits)
return csigr_bits & 0xf;
};
static inline int mite_csigr_type(u32 csigr_bits)
-{ // original mite = 0, minimite = 1
+{ /* original mite = 0, minimite = 1 */
return (csigr_bits >> 4) & 0xf;
};
static inline int mite_csigr_mmode(u32 csigr_bits)
-{ // mite mode, minimite = 1
+{ /* mite mode, minimite = 1 */
return (csigr_bits >> 8) & 0x3;
};
static inline int mite_csigr_imode(u32 csigr_bits)
-{ // cpu port interface mode, pci = 0x3
+{ /* cpu port interface mode, pci = 0x3 */
return (csigr_bits >> 12) & 0x3;
};
static inline int mite_csigr_dmac(u32 csigr_bits)
-{ // number of dma channels
+{ /* number of dma channels */
return (csigr_bits >> 16) & 0xf;
};
static inline int mite_csigr_wpdep(u32 csigr_bits)
-{ // write post fifo depth
+{ /* write post fifo depth */
unsigned int wpdep_bits = (csigr_bits >> 20) & 0x7;
if (wpdep_bits == 0)
return 0;
@@ -304,7 +304,7 @@ static inline int mite_csigr_wins(u32 csigr_bits)
return (csigr_bits >> 24) & 0x1f;
};
static inline int mite_csigr_iowins(u32 csigr_bits)
-{ // number of io windows
+{ /* number of io windows */
return (csigr_bits >> 29) & 0x7;
};
diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c
new file mode 100644
index 00000000000..a151602929d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/mpc624.c
@@ -0,0 +1,386 @@
+/*
+ comedi/drivers/mpc624.c
+ Hardware driver for a Micro/sys inc. MPC-624 PC/104 board
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: mpc624
+Description: Micro/sys MPC-624 PC/104 board
+Devices: [Micro/sys] MPC-624 (mpc624)
+Author: Stanislaw Raczynski <sraczynski@op.pl>
+Updated: Thu, 15 Sep 2005 12:01:18 +0200
+Status: working
+
+ The Micro/sys MPC-624 board is based on the LTC2440 24-bit sigma-delta
+ ADC chip.
+
+ Subdevices supported by the driver:
+ - Analog In: supported
+ - Digital I/O: not supported
+ - LEDs: not supported
+ - EEPROM: not supported
+
+Configuration Options:
+ [0] - I/O base address
+ [1] - convertion rate
+ Convertion rate RMS noise Effective Number Of Bits
+ 0 3.52kHz 23uV 17
+ 1 1.76kHz 3.5uV 20
+ 2 880Hz 2uV 21.3
+ 3 440Hz 1.4uV 21.8
+ 4 220Hz 1uV 22.4
+ 5 110Hz 750uV 22.9
+ 6 55Hz 510nV 23.4
+ 7 27.5Hz 375nV 24
+ 8 13.75Hz 250nV 24.4
+ 9 6.875Hz 200nV 24.6
+ [2] - voltage range
+ 0 -1.01V .. +1.01V
+ 1 -10.1V .. +10.1V
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+// Consecutive I/O port addresses
+#define MPC624_SIZE 16
+
+// Offsets of different ports
+#define MPC624_MASTER_CONTROL 0 // not used
+#define MPC624_GNMUXCH 1 // Gain, Mux, Channel of ADC
+#define MPC624_ADC 2 // read/write to/from ADC
+#define MPC624_EE 3 // read/write to/from serial EEPROM via I2C
+#define MPC624_LEDS 4 // write to LEDs
+#define MPC624_DIO 5 // read/write to/from digital I/O ports
+#define MPC624_IRQ_MASK 6 // IRQ masking enable/disable
+
+// Register bits' names
+#define MPC624_ADBUSY (1<<5)
+#define MPC624_ADSDO (1<<4)
+#define MPC624_ADFO (1<<3)
+#define MPC624_ADCS (1<<2)
+#define MPC624_ADSCK (1<<1)
+#define MPC624_ADSDI (1<<0)
+
+// SDI Speed/Resolution Programming bits
+#define MPC624_OSR4 (1<<31)
+#define MPC624_OSR3 (1<<30)
+#define MPC624_OSR2 (1<<29)
+#define MPC624_OSR1 (1<<28)
+#define MPC624_OSR0 (1<<27)
+
+// 32-bit output value bits' names
+#define MPC624_EOC_BIT (1<<31)
+#define MPC624_DMY_BIT (1<<30)
+#define MPC624_SGN_BIT (1<<29)
+
+// Convertion speeds
+/* OSR4 OSR3 OSR2 OSR1 OSR0 Convertion rate RMS noise ENOB^
+ * X 0 0 0 1 3.52kHz 23uV 17
+ * X 0 0 1 0 1.76kHz 3.5uV 20
+ * X 0 0 1 1 880Hz 2uV 21.3
+ * X 0 1 0 0 440Hz 1.4uV 21.8
+ * X 0 1 0 1 220Hz 1uV 22.4
+ * X 0 1 1 0 110Hz 750uV 22.9
+ * X 0 1 1 1 55Hz 510nV 23.4
+ * X 1 0 0 0 27.5Hz 375nV 24
+ * X 1 0 0 1 13.75Hz 250nV 24.4
+ * X 1 1 1 1 6.875Hz 200nV 24.6
+ *
+ * ^ - Effective Number Of Bits
+ */
+
+#define MPC624_SPEED_3_52_kHz (MPC624_OSR4 | MPC624_OSR0)
+#define MPC624_SPEED_1_76_kHz (MPC624_OSR4 | MPC624_OSR1 )
+#define MPC624_SPEED_880_Hz (MPC624_OSR4 | MPC624_OSR1 | MPC624_OSR0)
+#define MPC624_SPEED_440_Hz (MPC624_OSR4 | MPC624_OSR2 )
+#define MPC624_SPEED_220_Hz (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR0)
+#define MPC624_SPEED_110_Hz (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR1 )
+#define MPC624_SPEED_55_Hz (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0)
+#define MPC624_SPEED_27_5_Hz (MPC624_OSR4 | MPC624_OSR3 )
+#define MPC624_SPEED_13_75_Hz (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR0)
+#define MPC624_SPEED_6_875_Hz (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0)
+//----------------------------------------------------------------------------
+struct skel_private {
+
+ unsigned long int ulConvertionRate; // set by mpc624_attach() from driver's parameters
+};
+
+
+#define devpriv ((struct skel_private *)dev->private)
+//----------------------------------------------------------------------------
+static const struct comedi_lrange range_mpc624_bipolar1 = {
+ 1,
+ {
+// BIP_RANGE(1.01) // this is correct,
+ // but my MPC-624 actually seems to have a range of 2.02
+ BIP_RANGE(2.02)
+ }
+};
+static const struct comedi_lrange range_mpc624_bipolar10 = {
+ 1,
+ {
+// BIP_RANGE(10.1) // this is correct,
+ // but my MPC-624 actually seems to have a range of 20.2
+ BIP_RANGE(20.2)
+ }
+};
+
+//----------------------------------------------------------------------------
+static int mpc624_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int mpc624_detach(struct comedi_device * dev);
+//----------------------------------------------------------------------------
+static struct comedi_driver driver_mpc624 = {
+ driver_name:"mpc624",
+ module:THIS_MODULE,
+ attach:mpc624_attach,
+ detach:mpc624_detach
+};
+
+//----------------------------------------------------------------------------
+static int mpc624_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+//----------------------------------------------------------------------------
+static int mpc624_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ rt_printk("comedi%d: mpc624 [0x%04lx, ", dev->minor, iobase);
+ if (request_region(iobase, MPC624_SIZE, "mpc624") == NULL) {
+ rt_printk("I/O port(s) in use\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+ dev->board_name = "mpc624";
+
+ // Private structure initialization
+ if (alloc_private(dev, sizeof(struct skel_private)) < 0)
+ return -ENOMEM;
+
+ switch (it->options[1]) {
+ case 0:
+ devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
+ rt_printk("3.52 kHz, ");
+ break;
+ case 1:
+ devpriv->ulConvertionRate = MPC624_SPEED_1_76_kHz;
+ rt_printk("1.76 kHz, ");
+ break;
+ case 2:
+ devpriv->ulConvertionRate = MPC624_SPEED_880_Hz;
+ rt_printk("880 Hz, ");
+ break;
+ case 3:
+ devpriv->ulConvertionRate = MPC624_SPEED_440_Hz;
+ rt_printk("440 Hz, ");
+ break;
+ case 4:
+ devpriv->ulConvertionRate = MPC624_SPEED_220_Hz;
+ rt_printk("220 Hz, ");
+ break;
+ case 5:
+ devpriv->ulConvertionRate = MPC624_SPEED_110_Hz;
+ rt_printk("110 Hz, ");
+ break;
+ case 6:
+ devpriv->ulConvertionRate = MPC624_SPEED_55_Hz;
+ rt_printk("55 Hz, ");
+ break;
+ case 7:
+ devpriv->ulConvertionRate = MPC624_SPEED_27_5_Hz;
+ rt_printk("27.5 Hz, ");
+ break;
+ case 8:
+ devpriv->ulConvertionRate = MPC624_SPEED_13_75_Hz;
+ rt_printk("13.75 Hz, ");
+ break;
+ case 9:
+ devpriv->ulConvertionRate = MPC624_SPEED_6_875_Hz;
+ rt_printk("6.875 Hz, ");
+ break;
+ default:
+ rt_printk
+ ("illegal convertion rate setting! Valid numbers are 0..9. Using 9 => 6.875 Hz, ");
+ devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
+ }
+
+ // Subdevices structures
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_DIFF;
+ s->n_chan = 8;
+ switch (it->options[1]) {
+ default:
+ s->maxdata = 0x3FFFFFFF;
+ rt_printk("30 bit, ");
+ }
+
+ switch (it->options[1]) {
+ case 0:
+ s->range_table = &range_mpc624_bipolar1;
+ rt_printk("1.01V]: ");
+ break;
+ default:
+ s->range_table = &range_mpc624_bipolar10;
+ rt_printk("10.1V]: ");
+ }
+ s->len_chanlist = 1;
+ s->insn_read = mpc624_ai_rinsn;
+
+ rt_printk("attached\n");
+
+ return 1;
+}
+
+static int mpc624_detach(struct comedi_device * dev)
+{
+ rt_printk("comedi%d: mpc624: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, MPC624_SIZE);
+
+ return 0;
+}
+
+// Timeout 200ms
+#define TIMEOUT 200
+
+static int mpc624_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i;
+ unsigned long int data_in, data_out;
+ unsigned char ucPort;
+
+ // WARNING: We always write 0 to GNSWA bit, so the channel range is +-/10.1Vdc
+ outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH);
+// rt_printk("Channel %d: \n", insn->chanspec);
+ if (!insn->n) {
+ rt_printk("MPC624: Warning, no data to aquire\n");
+ return 0;
+ }
+
+ for (n = 0; n < insn->n; n++) {
+ // Trigger the convertion
+ outb(MPC624_ADSCK, dev->iobase + MPC624_ADC);
+ comedi_udelay(1);
+ outb(MPC624_ADCS | MPC624_ADSCK, dev->iobase + MPC624_ADC);
+ comedi_udelay(1);
+ outb(0, dev->iobase + MPC624_ADC);
+ comedi_udelay(1);
+
+ // Wait for the convertion to end
+ for (i = 0; i < TIMEOUT; i++) {
+ ucPort = inb(dev->iobase + MPC624_ADC);
+ if (ucPort & MPC624_ADBUSY)
+ comedi_udelay(1000);
+ else
+ break;
+ }
+ if (i == TIMEOUT) {
+ rt_printk("MPC624: timeout (%dms)\n", TIMEOUT);
+ data[n] = 0;
+ return -ETIMEDOUT;
+ }
+ // Start reading data
+ data_in = 0;
+ data_out = devpriv->ulConvertionRate;
+ comedi_udelay(1);
+ for (i = 0; i < 32; i++) {
+ // Set the clock low
+ outb(0, dev->iobase + MPC624_ADC);
+ comedi_udelay(1);
+
+ if (data_out & (1 << 31)) // the next bit is a 1
+ {
+ // Set the ADSDI line (send to MPC624)
+ outb(MPC624_ADSDI, dev->iobase + MPC624_ADC);
+ comedi_udelay(1);
+ // Set the clock high
+ outb(MPC624_ADSCK | MPC624_ADSDI,
+ dev->iobase + MPC624_ADC);
+ } else // the next bit is a 0
+ {
+ // Set the ADSDI line (send to MPC624)
+ outb(0, dev->iobase + MPC624_ADC);
+ comedi_udelay(1);
+ // Set the clock high
+ outb(MPC624_ADSCK, dev->iobase + MPC624_ADC);
+ }
+ // Read ADSDO on high clock (receive from MPC624)
+ comedi_udelay(1);
+ data_in <<= 1;
+ data_in |=
+ (inb(dev->iobase +
+ MPC624_ADC) & MPC624_ADSDO) >> 4;
+ comedi_udelay(1);
+
+ data_out <<= 1;
+ }
+
+ // Received 32-bit long value consist of:
+ // 31: EOC (End Of Transmission) bit - should be 0
+ // 30: DMY (Dummy) bit - should be 0
+ // 29: SIG (Sign) bit - 1 if the voltage is positive, 0 if negative
+ // 28: MSB (Most Significant Bit) - the first bit of convertion result
+ // ....
+ // 05: LSB (Least Significant Bit) - the last bit of convertion result
+ // 04: sub-LSB - sub-LSBs are basically noise, but when
+ // 03: sub-LSB averaged properly, they can increase convertion
+ // 02: sub-LSB precision up to 29 bits; they can be discarded
+ // 01: sub-LSB without loss of resolution.
+ // 00: sub-LSB
+
+ if (data_in & MPC624_EOC_BIT)
+ rt_printk("MPC624: EOC bit is set (data_in=%lu)!",
+ data_in);
+ if (data_in & MPC624_DMY_BIT)
+ rt_printk("MPC624: DMY bit is set (data_in=%lu)!",
+ data_in);
+ if (data_in & MPC624_SGN_BIT) // check the sign bit
+ { // The voltage is positive
+ data_in &= 0x3FFFFFFF; // EOC and DMY should be 0, but we will mask them out just to be sure
+ data[n] = data_in; // comedi operates on unsigned numbers, so we don't clear the SGN bit
+ // SGN bit is still set! It's correct, since we're converting to unsigned.
+ } else { // The voltage is negative
+ // data_in contains a number in 30-bit two's complement code and we must deal with it
+ data_in |= MPC624_SGN_BIT;
+ data_in = ~data_in;
+ data_in += 1;
+ data_in &= ~(MPC624_EOC_BIT | MPC624_DMY_BIT);
+ // clear EOC and DMY bits
+ data_in = 0x20000000 - data_in;
+ data[n] = data_in;
+ }
+ }
+
+ // Return the number of samples read/written
+ return n;
+}
+
+COMEDI_INITCLEANUP(driver_mpc624);
diff --git a/drivers/staging/comedi/drivers/mpc8260cpm.c b/drivers/staging/comedi/drivers/mpc8260cpm.c
new file mode 100644
index 00000000000..bac0a7bb9cb
--- /dev/null
+++ b/drivers/staging/comedi/drivers/mpc8260cpm.c
@@ -0,0 +1,169 @@
+/*
+ comedi/drivers/mpc8260.c
+ driver for digital I/O pins on the MPC 8260 CPM module
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000,2001 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: mpc8260cpm
+Description: MPC8260 CPM module generic digital I/O lines
+Devices: [Motorola] MPC8260 CPM (mpc8260cpm)
+Author: ds
+Status: experimental
+Updated: Sat, 16 Mar 2002 17:34:48 -0800
+
+This driver is specific to the Motorola MPC8260 processor, allowing
+you to access the processor's generic digital I/O lines.
+
+It is apparently missing some code.
+*/
+
+#include "../comedidev.h"
+
+extern unsigned long mpc8260_dio_reserved[4];
+
+struct mpc8260cpm_private {
+
+ int data;
+
+};
+
+#define devpriv ((struct mpc8260cpm_private *)dev->private)
+
+static int mpc8260cpm_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int mpc8260cpm_detach(struct comedi_device * dev);
+static struct comedi_driver driver_mpc8260cpm = {
+ driver_name:"mpc8260cpm",
+ module:THIS_MODULE,
+ attach:mpc8260cpm_attach,
+ detach:mpc8260cpm_detach,
+};
+
+COMEDI_INITCLEANUP(driver_mpc8260cpm);
+
+static int mpc8260cpm_dio_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int mpc8260cpm_dio_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int mpc8260cpm_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int i;
+
+ printk("comedi%d: mpc8260cpm: ", dev->minor);
+
+ dev->board_ptr = mpc8260cpm_boards + dev->board;
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ for (i = 0; i < 4; i++) {
+ s = dev->subdevices + i;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 32;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_config = mpc8260cpm_dio_config;
+ s->insn_bits = mpc8260cpm_dio_bits;
+ }
+
+ return 1;
+}
+
+static int mpc8260cpm_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: mpc8260cpm: remove\n", dev->minor);
+
+ return 0;
+}
+
+static unsigned long *cpm_pdat(int port)
+{
+ switch (port) {
+ case 0:
+ return &io->iop_pdata;
+ case 1:
+ return &io->iop_pdatb;
+ case 2:
+ return &io->iop_pdatc;
+ case 3:
+ return &io->iop_pdatd;
+ }
+}
+
+static int mpc8260cpm_dio_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ unsigned int d;
+ unsigned int mask;
+ int port;
+
+ port = (int)s->private;
+ mask = 1 << CR_CHAN(insn->chanspec);
+ if (mask & cpm_reserved_bits[port]) {
+ return -EINVAL;
+ }
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= mask;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~mask;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (port) {
+ case 0:
+ return &io->iop_pdira;
+ case 1:
+ return &io->iop_pdirb;
+ case 2:
+ return &io->iop_pdirc;
+ case 3:
+ return &io->iop_pdird;
+ }
+
+ return 1;
+}
+
+static int mpc8260cpm_dio_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int port;
+ unsigned long *p;
+
+ p = cpm_pdat((int)s->private);
+
+ return 2;
+}
diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c
new file mode 100644
index 00000000000..9e47574171d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/multiq3.c
@@ -0,0 +1,333 @@
+/*
+ comedi/drivers/multiq3.c
+ Hardware driver for Quanser Consulting MultiQ-3 board
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ 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.
+
+ */
+/*
+Driver: multiq3
+Description: Quanser Consulting MultiQ-3
+Author: Anders Blomdell <anders.blomdell@control.lth.se>
+Status: works
+Devices: [Quanser Consulting] MultiQ-3 (multiq3)
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define MULTIQ3_SIZE 16
+
+/*
+ * MULTIQ-3 port offsets
+ */
+#define MULTIQ3_DIGIN_PORT 0
+#define MULTIQ3_DIGOUT_PORT 0
+#define MULTIQ3_DAC_DATA 2
+#define MULTIQ3_AD_DATA 4
+#define MULTIQ3_AD_CS 4
+#define MULTIQ3_STATUS 6
+#define MULTIQ3_CONTROL 6
+#define MULTIQ3_CLK_DATA 8
+#define MULTIQ3_ENC_DATA 12
+#define MULTIQ3_ENC_CONTROL 14
+
+/*
+ * flags for CONTROL register
+ */
+#define MULTIQ3_AD_MUX_EN 0x0040
+#define MULTIQ3_AD_AUTOZ 0x0080
+#define MULTIQ3_AD_AUTOCAL 0x0100
+#define MULTIQ3_AD_SH 0x0200
+#define MULTIQ3_AD_CLOCK_4M 0x0400
+#define MULTIQ3_DA_LOAD 0x1800
+
+#define MULTIQ3_CONTROL_MUST 0x0600
+
+/*
+ * flags for STATUS register
+ */
+#define MULTIQ3_STATUS_EOC 0x008
+#define MULTIQ3_STATUS_EOC_I 0x010
+
+/*
+ * flags for encoder control
+ */
+#define MULTIQ3_CLOCK_DATA 0x00
+#define MULTIQ3_CLOCK_SETUP 0x18
+#define MULTIQ3_INPUT_SETUP 0x41
+#define MULTIQ3_QUAD_X4 0x38
+#define MULTIQ3_BP_RESET 0x01
+#define MULTIQ3_CNTR_RESET 0x02
+#define MULTIQ3_TRSFRPR_CTR 0x08
+#define MULTIQ3_TRSFRCNTR_OL 0x10
+#define MULTIQ3_EFLAG_RESET 0x06
+
+#define MULTIQ3_TIMEOUT 30
+
+static int multiq3_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int multiq3_detach(struct comedi_device * dev);
+static struct comedi_driver driver_multiq3 = {
+ driver_name:"multiq3",
+ module:THIS_MODULE,
+ attach:multiq3_attach,
+ detach:multiq3_detach,
+};
+
+COMEDI_INITCLEANUP(driver_multiq3);
+
+struct multiq3_private {
+ unsigned int ao_readback[2];
+};
+#define devpriv ((struct multiq3_private *)dev->private)
+
+static int multiq3_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int chan;
+ unsigned int hi, lo;
+
+ chan = CR_CHAN(insn->chanspec);
+ outw(MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3),
+ dev->iobase + MULTIQ3_CONTROL);
+
+ for (i = 0; i < MULTIQ3_TIMEOUT; i++) {
+ if (inw(dev->iobase + MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC)
+ break;
+ }
+ if (i == MULTIQ3_TIMEOUT)
+ return -ETIMEDOUT;
+
+ for (n = 0; n < insn->n; n++) {
+ outw(0, dev->iobase + MULTIQ3_AD_CS);
+ for (i = 0; i < MULTIQ3_TIMEOUT; i++) {
+ if (inw(dev->iobase +
+ MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC_I)
+ break;
+ }
+ if (i == MULTIQ3_TIMEOUT)
+ return -ETIMEDOUT;
+
+ hi = inb(dev->iobase + MULTIQ3_AD_CS);
+ lo = inb(dev->iobase + MULTIQ3_AD_CS);
+ data[n] = (((hi << 8) | lo) + 0x1000) & 0x1fff;
+ }
+
+ return n;
+}
+
+static int multiq3_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+static int multiq3_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ outw(MULTIQ3_CONTROL_MUST | MULTIQ3_DA_LOAD | chan,
+ dev->iobase + MULTIQ3_CONTROL);
+ outw(data[i], dev->iobase + MULTIQ3_DAC_DATA);
+ outw(MULTIQ3_CONTROL_MUST, dev->iobase + MULTIQ3_CONTROL);
+
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ return i;
+}
+
+static int multiq3_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inw(dev->iobase + MULTIQ3_DIGIN_PORT);
+
+ return 2;
+}
+
+static int multiq3_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ outw(s->state, dev->iobase + MULTIQ3_DIGOUT_PORT);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int multiq3_encoder_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+ int control = MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3);
+
+ for (n = 0; n < insn->n; n++) {
+ int value;
+ outw(control, dev->iobase + MULTIQ3_CONTROL);
+ outb(MULTIQ3_BP_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
+ outb(MULTIQ3_TRSFRCNTR_OL, dev->iobase + MULTIQ3_ENC_CONTROL);
+ value = inb(dev->iobase + MULTIQ3_ENC_DATA);
+ value |= (inb(dev->iobase + MULTIQ3_ENC_DATA) << 8);
+ value |= (inb(dev->iobase + MULTIQ3_ENC_DATA) << 16);
+ data[n] = (value + 0x800000) & 0xffffff;
+ }
+
+ return n;
+}
+
+static void encoder_reset(struct comedi_device * dev)
+{
+ int chan;
+ for (chan = 0; chan < dev->subdevices[4].n_chan; chan++) {
+ int control =
+ MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3);
+ outw(control, dev->iobase + MULTIQ3_CONTROL);
+ outb(MULTIQ3_EFLAG_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
+ outb(MULTIQ3_BP_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
+ outb(MULTIQ3_CLOCK_DATA, dev->iobase + MULTIQ3_ENC_DATA);
+ outb(MULTIQ3_CLOCK_SETUP, dev->iobase + MULTIQ3_ENC_CONTROL);
+ outb(MULTIQ3_INPUT_SETUP, dev->iobase + MULTIQ3_ENC_CONTROL);
+ outb(MULTIQ3_QUAD_X4, dev->iobase + MULTIQ3_ENC_CONTROL);
+ outb(MULTIQ3_CNTR_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
+ }
+}
+
+/*
+ options[0] - I/O port
+ options[1] - irq
+ options[2] - number of encoder chips installed
+ */
+
+static int multiq3_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int result = 0;
+ unsigned long iobase;
+ unsigned int irq;
+ struct comedi_subdevice *s;
+
+ iobase = it->options[0];
+ printk("comedi%d: multiq3: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, MULTIQ3_SIZE, "multiq3")) {
+ printk("comedi%d: I/O port conflict\n", dev->minor);
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+ irq = it->options[1];
+ if (irq) {
+ printk("comedi%d: irq = %u ignored\n", dev->minor, irq);
+ } else {
+ printk("comedi%d: no irq\n", dev->minor);
+ }
+ dev->board_name = "multiq3";
+ result = alloc_subdevices(dev, 5);
+ if (result < 0)
+ return result;
+
+ result = alloc_private(dev, sizeof(struct multiq3_private));
+ if (result < 0)
+ return result;
+
+ s = dev->subdevices + 0;
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 8;
+ s->insn_read = multiq3_ai_insn_read;
+ s->maxdata = 0x1fff;
+ s->range_table = &range_bipolar5;
+
+ s = dev->subdevices + 1;
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 8;
+ s->insn_read = multiq3_ao_insn_read;
+ s->insn_write = multiq3_ao_insn_write;
+ s->maxdata = 0xfff;
+ s->range_table = &range_bipolar5;
+
+ s = dev->subdevices + 2;
+ /* di subdevice */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 16;
+ s->insn_bits = multiq3_di_insn_bits;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+
+ s = dev->subdevices + 3;
+ /* do subdevice */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 16;
+ s->insn_bits = multiq3_do_insn_bits;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->state = 0;
+
+ s = dev->subdevices + 4;
+ /* encoder (counter) subdevice */
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
+ s->n_chan = it->options[2] * 2;
+ s->insn_read = multiq3_encoder_insn_read;
+ s->maxdata = 0xffffff;
+ s->range_table = &range_unknown;
+
+ encoder_reset(dev);
+
+ return 0;
+}
+
+static int multiq3_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: multiq3: remove\n", dev->minor);
+
+ if (dev->iobase) {
+ release_region(dev->iobase, MULTIQ3_SIZE);
+ }
+ if (dev->irq) {
+ free_irq(dev->irq, dev);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c
new file mode 100644
index 00000000000..e01ecb6760f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_6527.c
@@ -0,0 +1,489 @@
+/*
+ comedi/drivers/ni_6527.c
+ driver for National Instruments PCI-6527
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ni_6527
+Description: National Instruments 6527
+Author: ds
+Status: works
+Devices: [National Instruments] PCI-6527 (ni6527), PXI-6527
+Updated: Sat, 25 Jan 2003 13:24:40 -0800
+
+
+*/
+
+/*
+ Manuals (available from ftp://ftp.natinst.com/support/manuals)
+
+ 370106b.pdf 6527 Register Level Programmer Manual
+
+ */
+
+#define DEBUG 1
+#define DEBUG_FLAGS
+
+#include "../comedidev.h"
+
+#include "mite.h"
+
+#define NI6527_DIO_SIZE 4096
+#define NI6527_MITE_SIZE 4096
+
+#define Port_Register(x) (0x00+(x))
+#define ID_Register 0x06
+
+#define Clear_Register 0x07
+#define ClrEdge 0x08
+#define ClrOverflow 0x04
+#define ClrFilter 0x02
+#define ClrInterval 0x01
+
+#define Filter_Interval(x) (0x08+(x))
+#define Filter_Enable(x) (0x0c+(x))
+
+#define Change_Status 0x14
+#define MasterInterruptStatus 0x04
+#define Overflow 0x02
+#define EdgeStatus 0x01
+
+#define Master_Interrupt_Control 0x15
+#define FallingEdgeIntEnable 0x10
+#define RisingEdgeIntEnable 0x08
+#define MasterInterruptEnable 0x04
+#define OverflowIntEnable 0x02
+#define EdgeIntEnable 0x01
+
+#define Rising_Edge_Detection_Enable(x) (0x018+(x))
+#define Falling_Edge_Detection_Enable(x) (0x020+(x))
+
+static int ni6527_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni6527_detach(struct comedi_device * dev);
+static struct comedi_driver driver_ni6527 = {
+ driver_name:"ni6527",
+ module:THIS_MODULE,
+ attach:ni6527_attach,
+ detach:ni6527_detach,
+};
+
+struct ni6527_board {
+
+ int dev_id;
+ const char *name;
+};
+
+static const struct ni6527_board ni6527_boards[] = {
+ {
+ dev_id: 0x2b20,
+ name: "pci-6527",
+ },
+ {
+ dev_id: 0x2b10,
+ name: "pxi-6527",
+ },
+};
+
+#define n_ni6527_boards (sizeof(ni6527_boards)/sizeof(ni6527_boards[0]))
+#define this_board ((const struct ni6527_board *)dev->board_ptr)
+
+static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x2b10, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni6527_pci_table);
+
+struct ni6527_private {
+ struct mite_struct *mite;
+ unsigned int filter_interval;
+ unsigned int filter_enable;
+};
+
+#define devpriv ((struct ni6527_private *)dev->private)
+
+static int ni6527_find_device(struct comedi_device * dev, int bus, int slot);
+
+static int ni6527_di_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned int interval;
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0] != INSN_CONFIG_FILTER)
+ return -EINVAL;
+
+ if (data[1]) {
+ interval = (data[1] + 100) / 200;
+ data[1] = interval * 200;
+
+ if (interval != devpriv->filter_interval) {
+ writeb(interval & 0xff,
+ devpriv->mite->daq_io_addr +
+ Filter_Interval(0));
+ writeb((interval >> 8) & 0xff,
+ devpriv->mite->daq_io_addr +
+ Filter_Interval(1));
+ writeb((interval >> 16) & 0x0f,
+ devpriv->mite->daq_io_addr +
+ Filter_Interval(2));
+
+ writeb(ClrInterval,
+ devpriv->mite->daq_io_addr + Clear_Register);
+
+ devpriv->filter_interval = interval;
+ }
+
+ devpriv->filter_enable |= 1 << chan;
+ } else {
+ devpriv->filter_enable &= ~(1 << chan);
+ }
+
+ writeb(devpriv->filter_enable,
+ devpriv->mite->daq_io_addr + Filter_Enable(0));
+ writeb(devpriv->filter_enable >> 8,
+ devpriv->mite->daq_io_addr + Filter_Enable(1));
+ writeb(devpriv->filter_enable >> 16,
+ devpriv->mite->daq_io_addr + Filter_Enable(2));
+
+ return 2;
+}
+
+static int ni6527_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = readb(devpriv->mite->daq_io_addr + Port_Register(0));
+ data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(1)) << 8;
+ data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(2)) << 16;
+
+ return 2;
+}
+
+static int ni6527_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+
+ /* The open relay state on the board cooresponds to 1,
+ * but in Comedi, it is represented by 0. */
+ if (data[0] & 0x0000ff) {
+ writeb((s->state ^ 0xff),
+ devpriv->mite->daq_io_addr + Port_Register(3));
+ }
+ if (data[0] & 0x00ff00) {
+ writeb((s->state >> 8) ^ 0xff,
+ devpriv->mite->daq_io_addr + Port_Register(4));
+ }
+ if (data[0] & 0xff0000) {
+ writeb((s->state >> 16) ^ 0xff,
+ devpriv->mite->daq_io_addr + Port_Register(5));
+ }
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+static irqreturn_t ni6527_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 2;
+ unsigned int status;
+
+ status = readb(devpriv->mite->daq_io_addr + Change_Status);
+ if ((status & MasterInterruptStatus) == 0)
+ return IRQ_NONE;
+ if ((status & EdgeStatus) == 0)
+ return IRQ_NONE;
+
+ writeb(ClrEdge | ClrOverflow,
+ devpriv->mite->daq_io_addr + Clear_Register);
+
+ comedi_buf_put(s->async, 0);
+ s->async->events |= COMEDI_CB_EOS;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+static int ni6527_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_OTHER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_FOLLOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_end_arg != 1) {
+ cmd->scan_end_arg = 1;
+ err++;
+ }
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int ni6527_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ //struct comedi_cmd *cmd = &s->async->cmd;
+
+ writeb(ClrEdge | ClrOverflow,
+ devpriv->mite->daq_io_addr + Clear_Register);
+ writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
+ MasterInterruptEnable | EdgeIntEnable,
+ devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+
+ return 0;
+}
+
+static int ni6527_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+
+ return 0;
+}
+
+static int ni6527_intr_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n < 1)
+ return -EINVAL;
+
+ data[1] = 0;
+ return 2;
+}
+
+static int ni6527_intr_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n < 1)
+ return -EINVAL;
+ if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
+ return -EINVAL;
+
+ writeb(data[1],
+ devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0));
+ writeb(data[1] >> 8,
+ devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(1));
+ writeb(data[1] >> 16,
+ devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(2));
+
+ writeb(data[2],
+ devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0));
+ writeb(data[2] >> 8,
+ devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(1));
+ writeb(data[2] >> 16,
+ devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(2));
+
+ return 2;
+}
+
+static int ni6527_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret;
+
+ printk("comedi%d: ni6527:", dev->minor);
+
+ if ((ret = alloc_private(dev, sizeof(struct ni6527_private))) < 0)
+ return ret;
+
+ ret = ni6527_find_device(dev, it->options[0], it->options[1]);
+ if (ret < 0)
+ return ret;
+
+ ret = mite_setup(devpriv->mite);
+ if (ret < 0) {
+ printk("error setting up mite\n");
+ return ret;
+ }
+
+ dev->board_name = this_board->name;
+ printk(" %s", dev->board_name);
+
+ printk(" ID=0x%02x", readb(devpriv->mite->daq_io_addr + ID_Register));
+
+ if ((ret = alloc_subdevices(dev, 3)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 24;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_config = ni6527_di_insn_config;
+ s->insn_bits = ni6527_di_insn_bits;
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 24;
+ s->range_table = &range_unknown; /* FIXME: actually conductance */
+ s->maxdata = 1;
+ s->insn_bits = ni6527_do_insn_bits;
+
+ s = dev->subdevices + 2;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = 1;
+ s->range_table = &range_unknown;
+ s->maxdata = 1;
+ s->do_cmdtest = ni6527_intr_cmdtest;
+ s->do_cmd = ni6527_intr_cmd;
+ s->cancel = ni6527_intr_cancel;
+ s->insn_bits = ni6527_intr_insn_bits;
+ s->insn_config = ni6527_intr_insn_config;
+
+ writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(0));
+ writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(1));
+ writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(2));
+
+ writeb(ClrEdge | ClrOverflow | ClrFilter | ClrInterval,
+ devpriv->mite->daq_io_addr + Clear_Register);
+ writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+
+ ret = comedi_request_irq(mite_irq(devpriv->mite), ni6527_interrupt,
+ IRQF_SHARED, "ni6527", dev);
+ if (ret < 0) {
+ printk(" irq not available");
+ } else
+ dev->irq = mite_irq(devpriv->mite);
+
+ printk("\n");
+
+ return 0;
+}
+
+static int ni6527_detach(struct comedi_device * dev)
+{
+ if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) {
+ writeb(0x00,
+ devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+ }
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+
+ if (devpriv && devpriv->mite) {
+ mite_unsetup(devpriv->mite);
+ }
+
+ return 0;
+}
+
+static int ni6527_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number ||
+ slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+ for (i = 0; i < n_ni6527_boards; i++) {
+ if (mite_device_id(mite) == ni6527_boards[i].dev_id) {
+ dev->board_ptr = ni6527_boards + i;
+ devpriv->mite = mite;
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_ni6527, ni6527_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
new file mode 100644
index 00000000000..6e85da16a24
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -0,0 +1,809 @@
+/*
+ comedi/drivers/ni_6514.c
+ driver for National Instruments PCI-6514
+
+ Copyright (C) 2006 Jon Grierson <jd@renko.co.uk>
+ Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ni_65xx
+Description: National Instruments 65xx static dio boards
+Author: Jon Grierson <jd@renko.co.uk>, Frank Mori Hess <fmhess@users.sourceforge.net>
+Status: testing
+Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510, PCI-6511,
+ PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514, PXI-6514, PCI-6515,
+ PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519, PCI-6520, PCI-6521, PXI-6521,
+ PCI-6528, PXI-6528
+Updated: Wed Oct 18 08:59:11 EDT 2006
+
+Based on the PCI-6527 driver by ds.
+The interrupt subdevice (subdevice 3) is probably broken for all boards
+except maybe the 6514.
+
+*/
+
+/*
+ Manuals (available from ftp://ftp.natinst.com/support/manuals)
+
+ 370106b.pdf 6514 Register Level Programmer Manual
+
+ */
+
+#define _GNU_SOURCE
+#define DEBUG 1
+#define DEBUG_FLAGS
+#include "../comedidev.h"
+
+#include "mite.h"
+
+#define NI6514_DIO_SIZE 4096
+#define NI6514_MITE_SIZE 4096
+
+#define NI_65XX_MAX_NUM_PORTS 12
+static const unsigned ni_65xx_channels_per_port = 8;
+static const unsigned ni_65xx_port_offset = 0x10;
+
+static inline unsigned Port_Data(unsigned port)
+{
+ return 0x40 + port * ni_65xx_port_offset;
+}
+static inline unsigned Port_Select(unsigned port)
+{
+ return 0x41 + port * ni_65xx_port_offset;
+}
+static inline unsigned Rising_Edge_Detection_Enable(unsigned port)
+{
+ return 0x42 + port * ni_65xx_port_offset;
+}
+static inline unsigned Falling_Edge_Detection_Enable(unsigned port)
+{
+ return 0x43 + port * ni_65xx_port_offset;
+}
+static inline unsigned Filter_Enable(unsigned port)
+{
+ return 0x44 + port * ni_65xx_port_offset;
+}
+
+#define ID_Register 0x00
+
+#define Clear_Register 0x01
+#define ClrEdge 0x08
+#define ClrOverflow 0x04
+
+#define Filter_Interval 0x08
+
+#define Change_Status 0x02
+#define MasterInterruptStatus 0x04
+#define Overflow 0x02
+#define EdgeStatus 0x01
+
+#define Master_Interrupt_Control 0x03
+#define FallingEdgeIntEnable 0x10
+#define RisingEdgeIntEnable 0x08
+#define MasterInterruptEnable 0x04
+#define OverflowIntEnable 0x02
+#define EdgeIntEnable 0x01
+
+static int ni_65xx_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni_65xx_detach(struct comedi_device * dev);
+static struct comedi_driver driver_ni_65xx = {
+ driver_name:"ni_65xx",
+ module:THIS_MODULE,
+ attach:ni_65xx_attach,
+ detach:ni_65xx_detach,
+};
+
+struct ni_65xx_board {
+
+ int dev_id;
+ const char *name;
+ unsigned num_dio_ports;
+ unsigned num_di_ports;
+ unsigned num_do_ports;
+ unsigned invert_outputs:1;
+};
+
+static const struct ni_65xx_board ni_65xx_boards[] = {
+ {
+ dev_id: 0x7085,
+ name: "pci-6509",
+ num_dio_ports:12,
+ invert_outputs:0},
+ {
+ dev_id: 0x1710,
+ name: "pxi-6509",
+ num_dio_ports:12,
+ invert_outputs:0},
+ {
+ dev_id: 0x7124,
+ name: "pci-6510",
+ num_di_ports:4},
+ {
+ dev_id: 0x70c3,
+ name: "pci-6511",
+ num_di_ports:8},
+ {
+ dev_id: 0x70d3,
+ name: "pxi-6511",
+ num_di_ports:8},
+ {
+ dev_id: 0x70cc,
+ name: "pci-6512",
+ num_do_ports:8},
+ {
+ dev_id: 0x70d2,
+ name: "pxi-6512",
+ num_do_ports:8},
+ {
+ dev_id: 0x70c8,
+ name: "pci-6513",
+ num_do_ports:8,
+ invert_outputs:1},
+ {
+ dev_id: 0x70d1,
+ name: "pxi-6513",
+ num_do_ports:8,
+ invert_outputs:1},
+ {
+ dev_id: 0x7088,
+ name: "pci-6514",
+ num_di_ports:4,
+ num_do_ports:4,
+ invert_outputs:1},
+ {
+ dev_id: 0x70CD,
+ name: "pxi-6514",
+ num_di_ports:4,
+ num_do_ports:4,
+ invert_outputs:1},
+ {
+ dev_id: 0x7087,
+ name: "pci-6515",
+ num_di_ports:4,
+ num_do_ports:4,
+ invert_outputs:1},
+ {
+ dev_id: 0x70c9,
+ name: "pxi-6515",
+ num_di_ports:4,
+ num_do_ports:4,
+ invert_outputs:1},
+ {
+ dev_id: 0x7125,
+ name: "pci-6516",
+ num_do_ports:4,
+ invert_outputs:1},
+ {
+ dev_id: 0x7126,
+ name: "pci-6517",
+ num_do_ports:4,
+ invert_outputs:1},
+ {
+ dev_id: 0x7127,
+ name: "pci-6518",
+ num_di_ports:2,
+ num_do_ports:2,
+ invert_outputs:1},
+ {
+ dev_id: 0x7128,
+ name: "pci-6519",
+ num_di_ports:2,
+ num_do_ports:2,
+ invert_outputs:1},
+ {
+ dev_id: 0x71c5,
+ name: "pci-6520",
+ num_di_ports:1,
+ num_do_ports:1,
+ },
+ {
+ dev_id: 0x718b,
+ name: "pci-6521",
+ num_di_ports:1,
+ num_do_ports:1,
+ },
+ {
+ dev_id: 0x718c,
+ name: "pxi-6521",
+ num_di_ports:1,
+ num_do_ports:1,
+ },
+ {
+ dev_id: 0x70a9,
+ name: "pci-6528",
+ num_di_ports:3,
+ num_do_ports:3,
+ },
+ {
+ dev_id: 0x7086,
+ name: "pxi-6528",
+ num_di_ports:3,
+ num_do_ports:3,
+ },
+};
+
+#define n_ni_65xx_boards (sizeof(ni_65xx_boards)/sizeof(ni_65xx_boards[0]))
+static inline const struct ni_65xx_board *board(struct comedi_device * dev)
+{
+ return dev->board_ptr;
+}
+static inline unsigned ni_65xx_port_by_channel(unsigned channel)
+{
+ return channel / ni_65xx_channels_per_port;
+}
+static inline unsigned ni_65xx_total_num_ports(const struct ni_65xx_board * board)
+{
+ return board->num_dio_ports + board->num_di_ports + board->num_do_ports;
+}
+
+static DEFINE_PCI_DEVICE_TABLE(ni_65xx_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7085, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7086, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7087, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7088, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70a9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70c8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70c9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70d2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70d3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7126, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7127, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7128, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x718b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x718c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x71c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_65xx_pci_table);
+
+struct ni_65xx_private {
+ struct mite_struct *mite;
+ unsigned int filter_interval;
+ unsigned short filter_enable[NI_65XX_MAX_NUM_PORTS];
+ unsigned short output_bits[NI_65XX_MAX_NUM_PORTS];
+ unsigned short dio_direction[NI_65XX_MAX_NUM_PORTS];
+};
+
+static inline struct ni_65xx_private *private(struct comedi_device * dev)
+{
+ return dev->private;
+}
+
+struct ni_65xx_subdevice_private {
+ unsigned base_port;
+};
+
+static inline struct ni_65xx_subdevice_private *sprivate(struct comedi_subdevice * subdev)
+{
+ return subdev->private;
+}
+static struct ni_65xx_subdevice_private *ni_65xx_alloc_subdevice_private(void)
+{
+ struct ni_65xx_subdevice_private *subdev_private =
+ kzalloc(sizeof(struct ni_65xx_subdevice_private), GFP_KERNEL);
+ if (subdev_private == NULL)
+ return NULL;
+ return subdev_private;
+}
+
+static int ni_65xx_find_device(struct comedi_device * dev, int bus, int slot);
+
+static int ni_65xx_config_filter(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ const unsigned chan = CR_CHAN(insn->chanspec);
+ const unsigned port =
+ sprivate(s)->base_port + ni_65xx_port_by_channel(chan);
+
+ if (data[0] != INSN_CONFIG_FILTER)
+ return -EINVAL;
+ if (data[1]) {
+ static const unsigned filter_resolution_ns = 200;
+ static const unsigned max_filter_interval = 0xfffff;
+ unsigned interval =
+ (data[1] +
+ (filter_resolution_ns / 2)) / filter_resolution_ns;
+ if (interval > max_filter_interval)
+ interval = max_filter_interval;
+ data[1] = interval * filter_resolution_ns;
+
+ if (interval != private(dev)->filter_interval) {
+ writeb(interval,
+ private(dev)->mite->daq_io_addr +
+ Filter_Interval);
+ private(dev)->filter_interval = interval;
+ }
+
+ private(dev)->filter_enable[port] |=
+ 1 << (chan % ni_65xx_channels_per_port);
+ } else {
+ private(dev)->filter_enable[port] &=
+ ~(1 << (chan % ni_65xx_channels_per_port));
+ }
+
+ writeb(private(dev)->filter_enable[port],
+ private(dev)->mite->daq_io_addr + Filter_Enable(port));
+
+ return 2;
+}
+
+static int ni_65xx_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned port;
+
+ if (insn->n < 1)
+ return -EINVAL;
+ port = sprivate(s)->base_port +
+ ni_65xx_port_by_channel(CR_CHAN(insn->chanspec));
+ switch (data[0]) {
+ case INSN_CONFIG_FILTER:
+ return ni_65xx_config_filter(dev, s, insn, data);
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ if (s->type != COMEDI_SUBD_DIO)
+ return -EINVAL;
+ private(dev)->dio_direction[port] = COMEDI_OUTPUT;
+ writeb(0, private(dev)->mite->daq_io_addr + Port_Select(port));
+ return 1;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ if (s->type != COMEDI_SUBD_DIO)
+ return -EINVAL;
+ private(dev)->dio_direction[port] = COMEDI_INPUT;
+ writeb(1, private(dev)->mite->daq_io_addr + Port_Select(port));
+ return 1;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ if (s->type != COMEDI_SUBD_DIO)
+ return -EINVAL;
+ data[1] = private(dev)->dio_direction[port];
+ return insn->n;
+ break;
+ default:
+ break;
+ }
+ return -EINVAL;
+}
+
+static int ni_65xx_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned base_bitfield_channel;
+ const unsigned max_ports_per_bitfield = 5;
+ unsigned read_bits = 0;
+ unsigned j;
+ if (insn->n != 2)
+ return -EINVAL;
+ base_bitfield_channel = CR_CHAN(insn->chanspec);
+ for (j = 0; j < max_ports_per_bitfield; ++j) {
+ const unsigned port =
+ sprivate(s)->base_port +
+ ni_65xx_port_by_channel(base_bitfield_channel) + j;
+ unsigned base_port_channel;
+ unsigned port_mask, port_data, port_read_bits;
+ int bitshift;
+ if (port >= ni_65xx_total_num_ports(board(dev)))
+ break;
+ base_port_channel = port * ni_65xx_channels_per_port;
+ port_mask = data[0];
+ port_data = data[1];
+ bitshift = base_port_channel - base_bitfield_channel;
+ if (bitshift >= 32 || bitshift <= -32)
+ break;
+ if (bitshift > 0) {
+ port_mask >>= bitshift;
+ port_data >>= bitshift;
+ } else {
+ port_mask <<= -bitshift;
+ port_data <<= -bitshift;
+ }
+ port_mask &= 0xff;
+ port_data &= 0xff;
+ if (port_mask) {
+ unsigned bits;
+ private(dev)->output_bits[port] &= ~port_mask;
+ private(dev)->output_bits[port] |=
+ port_data & port_mask;
+ bits = private(dev)->output_bits[port];
+ if (board(dev)->invert_outputs)
+ bits = ~bits;
+ writeb(bits,
+ private(dev)->mite->daq_io_addr +
+ Port_Data(port));
+// rt_printk("wrote 0x%x to port %i\n", bits, port);
+ }
+ port_read_bits =
+ readb(private(dev)->mite->daq_io_addr +
+ Port_Data(port));
+// rt_printk("read 0x%x from port %i\n", port_read_bits, port);
+ if (bitshift > 0) {
+ port_read_bits <<= bitshift;
+ } else {
+ port_read_bits >>= -bitshift;
+ }
+ read_bits |= port_read_bits;
+ }
+ data[1] = read_bits;
+ return insn->n;
+}
+
+static irqreturn_t ni_65xx_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 2;
+ unsigned int status;
+
+ status = readb(private(dev)->mite->daq_io_addr + Change_Status);
+ if ((status & MasterInterruptStatus) == 0)
+ return IRQ_NONE;
+ if ((status & EdgeStatus) == 0)
+ return IRQ_NONE;
+
+ writeb(ClrEdge | ClrOverflow,
+ private(dev)->mite->daq_io_addr + Clear_Register);
+
+ comedi_buf_put(s->async, 0);
+ s->async->events |= COMEDI_CB_EOS;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+static int ni_65xx_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_OTHER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_FOLLOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_end_arg != 1) {
+ cmd->scan_end_arg = 1;
+ err++;
+ }
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int ni_65xx_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ //struct comedi_cmd *cmd = &s->async->cmd;
+
+ writeb(ClrEdge | ClrOverflow,
+ private(dev)->mite->daq_io_addr + Clear_Register);
+ writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
+ MasterInterruptEnable | EdgeIntEnable,
+ private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+
+ return 0;
+}
+
+static int ni_65xx_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ writeb(0x00,
+ private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+
+ return 0;
+}
+
+static int ni_65xx_intr_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n < 1)
+ return -EINVAL;
+
+ data[1] = 0;
+ return 2;
+}
+
+static int ni_65xx_intr_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n < 1)
+ return -EINVAL;
+ if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
+ return -EINVAL;
+
+ writeb(data[1],
+ private(dev)->mite->daq_io_addr +
+ Rising_Edge_Detection_Enable(0));
+ writeb(data[1] >> 8,
+ private(dev)->mite->daq_io_addr +
+ Rising_Edge_Detection_Enable(0x10));
+ writeb(data[1] >> 16,
+ private(dev)->mite->daq_io_addr +
+ Rising_Edge_Detection_Enable(0x20));
+ writeb(data[1] >> 24,
+ private(dev)->mite->daq_io_addr +
+ Rising_Edge_Detection_Enable(0x30));
+
+ writeb(data[2],
+ private(dev)->mite->daq_io_addr +
+ Falling_Edge_Detection_Enable(0));
+ writeb(data[2] >> 8,
+ private(dev)->mite->daq_io_addr +
+ Falling_Edge_Detection_Enable(0x10));
+ writeb(data[2] >> 16,
+ private(dev)->mite->daq_io_addr +
+ Falling_Edge_Detection_Enable(0x20));
+ writeb(data[2] >> 24,
+ private(dev)->mite->daq_io_addr +
+ Falling_Edge_Detection_Enable(0x30));
+
+ return 2;
+}
+
+static int ni_65xx_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned i;
+ int ret;
+
+ printk("comedi%d: ni_65xx:", dev->minor);
+
+ if ((ret = alloc_private(dev, sizeof(struct ni_65xx_private))) < 0)
+ return ret;
+
+ ret = ni_65xx_find_device(dev, it->options[0], it->options[1]);
+ if (ret < 0)
+ return ret;
+
+ ret = mite_setup(private(dev)->mite);
+ if (ret < 0) {
+ printk("error setting up mite\n");
+ return ret;
+ }
+
+ dev->board_name = board(dev)->name;
+ dev->irq = mite_irq(private(dev)->mite);
+ printk(" %s", dev->board_name);
+
+ printk(" ID=0x%02x",
+ readb(private(dev)->mite->daq_io_addr + ID_Register));
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ if (board(dev)->num_di_ports) {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan =
+ board(dev)->num_di_ports * ni_65xx_channels_per_port;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_config = ni_65xx_dio_insn_config;
+ s->insn_bits = ni_65xx_dio_insn_bits;
+ s->private = ni_65xx_alloc_subdevice_private();
+ if (s->private == NULL)
+ return -ENOMEM;
+ sprivate(s)->base_port = 0;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 1;
+ if (board(dev)->num_do_ports) {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan =
+ board(dev)->num_do_ports * ni_65xx_channels_per_port;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_bits = ni_65xx_dio_insn_bits;
+ s->private = ni_65xx_alloc_subdevice_private();
+ if (s->private == NULL)
+ return -ENOMEM;
+ sprivate(s)->base_port = board(dev)->num_di_ports;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 2;
+ if (board(dev)->num_dio_ports) {
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan =
+ board(dev)->num_dio_ports * ni_65xx_channels_per_port;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_config = ni_65xx_dio_insn_config;
+ s->insn_bits = ni_65xx_dio_insn_bits;
+ s->private = ni_65xx_alloc_subdevice_private();
+ if (s->private == NULL)
+ return -ENOMEM;
+ sprivate(s)->base_port = 0;
+ for (i = 0; i < board(dev)->num_dio_ports; ++i) {
+ // configure all ports for input
+ writeb(0x1,
+ private(dev)->mite->daq_io_addr +
+ Port_Select(i));
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 3;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = 1;
+ s->range_table = &range_unknown;
+ s->maxdata = 1;
+ s->do_cmdtest = ni_65xx_intr_cmdtest;
+ s->do_cmd = ni_65xx_intr_cmd;
+ s->cancel = ni_65xx_intr_cancel;
+ s->insn_bits = ni_65xx_intr_insn_bits;
+ s->insn_config = ni_65xx_intr_insn_config;
+
+ for (i = 0; i < ni_65xx_total_num_ports(board(dev)); ++i) {
+ writeb(0x00,
+ private(dev)->mite->daq_io_addr + Filter_Enable(i));
+ if (board(dev)->invert_outputs)
+ writeb(0x01,
+ private(dev)->mite->daq_io_addr + Port_Data(i));
+ else
+ writeb(0x00,
+ private(dev)->mite->daq_io_addr + Port_Data(i));
+ }
+ writeb(ClrEdge | ClrOverflow,
+ private(dev)->mite->daq_io_addr + Clear_Register);
+ writeb(0x00,
+ private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+
+ /* Set filter interval to 0 (32bit reg) */
+ writeb(0x00000000, private(dev)->mite->daq_io_addr + Filter_Interval);
+
+ ret = comedi_request_irq(dev->irq, ni_65xx_interrupt, IRQF_SHARED,
+ "ni_65xx", dev);
+ if (ret < 0) {
+ dev->irq = 0;
+ printk(" irq not available");
+ }
+
+ printk("\n");
+
+ return 0;
+}
+
+static int ni_65xx_detach(struct comedi_device * dev)
+{
+ if (private(dev) && private(dev)->mite
+ && private(dev)->mite->daq_io_addr) {
+ writeb(0x00,
+ private(dev)->mite->daq_io_addr +
+ Master_Interrupt_Control);
+ }
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+
+ if (private(dev)) {
+ unsigned i;
+ for (i = 0; i < dev->n_subdevices; ++i) {
+ if (dev->subdevices[i].private) {
+ kfree(dev->subdevices[i].private);
+ dev->subdevices[i].private = NULL;
+ }
+ }
+ if (private(dev)->mite) {
+ mite_unsetup(private(dev)->mite);
+ }
+ }
+ return 0;
+}
+
+static int ni_65xx_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number ||
+ slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+ for (i = 0; i < n_ni_65xx_boards; i++) {
+ if (mite_device_id(mite) == ni_65xx_boards[i].dev_id) {
+ dev->board_ptr = ni_65xx_boards + i;
+ private(dev)->mite = mite;
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_ni_65xx, ni_65xx_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c
new file mode 100644
index 00000000000..14e35ba721e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_660x.c
@@ -0,0 +1,1324 @@
+/*
+ comedi/drivers/ni_660x.c
+ Hardware driver for NI 660x devices
+
+ 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.
+*/
+
+/*
+Driver: ni_660x
+Description: National Instruments 660x counter/timer boards
+Devices:
+[National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602,
+ PXI-6608
+Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
+ Herman.Bruyninckx@mech.kuleuven.ac.be,
+ Wim.Meeussen@mech.kuleuven.ac.be,
+ Klaas.Gadeyne@mech.kuleuven.ac.be,
+ Frank Mori Hess <fmhess@users.sourceforge.net>
+Updated: Thu Oct 18 12:56:06 EDT 2007
+Status: experimental
+
+Encoders work. PulseGeneration (both single pulse and pulse train)
+works. Buffered commands work for input but not output.
+
+References:
+DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
+DAQ 6601/6602 User Manual (NI 322137B-01)
+
+*/
+
+#include "../comedidev.h"
+#include "mite.h"
+#include "ni_tio.h"
+
+enum ni_660x_constants {
+ min_counter_pfi_chan = 8,
+ max_dio_pfi_chan = 31,
+ counters_per_chip = 4
+};
+
+#define NUM_PFI_CHANNELS 40
+// really there are only up to 3 dma channels, but the register layout allows for 4
+#define MAX_DMA_CHANNEL 4
+
+/* See Register-Level Programmer Manual page 3.1 */
+enum NI_660x_Register {
+ G0InterruptAcknowledge,
+ G0StatusRegister,
+ G1InterruptAcknowledge,
+ G1StatusRegister,
+ G01StatusRegister,
+ G0CommandRegister,
+ STCDIOParallelInput,
+ G1CommandRegister,
+ G0HWSaveRegister,
+ G1HWSaveRegister,
+ STCDIOOutput,
+ STCDIOControl,
+ G0SWSaveRegister,
+ G1SWSaveRegister,
+ G0ModeRegister,
+ G01JointStatus1Register,
+ G1ModeRegister,
+ STCDIOSerialInput,
+ G0LoadARegister,
+ G01JointStatus2Register,
+ G0LoadBRegister,
+ G1LoadARegister,
+ G1LoadBRegister,
+ G0InputSelectRegister,
+ G1InputSelectRegister,
+ G0AutoincrementRegister,
+ G1AutoincrementRegister,
+ G01JointResetRegister,
+ G0InterruptEnable,
+ G1InterruptEnable,
+ G0CountingModeRegister,
+ G1CountingModeRegister,
+ G0SecondGateRegister,
+ G1SecondGateRegister,
+ G0DMAConfigRegister,
+ G0DMAStatusRegister,
+ G1DMAConfigRegister,
+ G1DMAStatusRegister,
+ G2InterruptAcknowledge,
+ G2StatusRegister,
+ G3InterruptAcknowledge,
+ G3StatusRegister,
+ G23StatusRegister,
+ G2CommandRegister,
+ G3CommandRegister,
+ G2HWSaveRegister,
+ G3HWSaveRegister,
+ G2SWSaveRegister,
+ G3SWSaveRegister,
+ G2ModeRegister,
+ G23JointStatus1Register,
+ G3ModeRegister,
+ G2LoadARegister,
+ G23JointStatus2Register,
+ G2LoadBRegister,
+ G3LoadARegister,
+ G3LoadBRegister,
+ G2InputSelectRegister,
+ G3InputSelectRegister,
+ G2AutoincrementRegister,
+ G3AutoincrementRegister,
+ G23JointResetRegister,
+ G2InterruptEnable,
+ G3InterruptEnable,
+ G2CountingModeRegister,
+ G3CountingModeRegister,
+ G3SecondGateRegister,
+ G2SecondGateRegister,
+ G2DMAConfigRegister,
+ G2DMAStatusRegister,
+ G3DMAConfigRegister,
+ G3DMAStatusRegister,
+ DIO32Input,
+ DIO32Output,
+ ClockConfigRegister,
+ GlobalInterruptStatusRegister,
+ DMAConfigRegister,
+ GlobalInterruptConfigRegister,
+ IOConfigReg0_1,
+ IOConfigReg2_3,
+ IOConfigReg4_5,
+ IOConfigReg6_7,
+ IOConfigReg8_9,
+ IOConfigReg10_11,
+ IOConfigReg12_13,
+ IOConfigReg14_15,
+ IOConfigReg16_17,
+ IOConfigReg18_19,
+ IOConfigReg20_21,
+ IOConfigReg22_23,
+ IOConfigReg24_25,
+ IOConfigReg26_27,
+ IOConfigReg28_29,
+ IOConfigReg30_31,
+ IOConfigReg32_33,
+ IOConfigReg34_35,
+ IOConfigReg36_37,
+ IOConfigReg38_39,
+ NumRegisters,
+};
+
+static inline unsigned IOConfigReg(unsigned pfi_channel)
+{
+ unsigned reg = IOConfigReg0_1 + pfi_channel / 2;
+ BUG_ON(reg > IOConfigReg38_39);
+ return reg;
+}
+
+enum ni_660x_register_width {
+ DATA_1B,
+ DATA_2B,
+ DATA_4B
+};
+
+enum ni_660x_register_direction {
+ NI_660x_READ,
+ NI_660x_WRITE,
+ NI_660x_READ_WRITE
+};
+
+enum ni_660x_pfi_output_select {
+ pfi_output_select_high_Z = 0,
+ pfi_output_select_counter = 1,
+ pfi_output_select_do = 2,
+ num_pfi_output_selects
+};
+
+enum ni_660x_subdevices {
+ NI_660X_DIO_SUBDEV = 1,
+ NI_660X_GPCT_SUBDEV_0 = 2
+};
+static inline unsigned NI_660X_GPCT_SUBDEV(unsigned index)
+{
+ return NI_660X_GPCT_SUBDEV_0 + index;
+}
+
+struct NI_660xRegisterData {
+
+ const char *name; // Register Name
+ int offset; // Offset from base address from GPCT chip
+ enum ni_660x_register_direction direction;
+ enum ni_660x_register_width size; // 1 byte, 2 bytes, or 4 bytes
+};
+
+
+static const struct NI_660xRegisterData registerData[NumRegisters] = {
+ {"G0 Interrupt Acknowledge", 0x004, NI_660x_WRITE, DATA_2B},
+ {"G0 Status Register", 0x004, NI_660x_READ, DATA_2B},
+ {"G1 Interrupt Acknowledge", 0x006, NI_660x_WRITE, DATA_2B},
+ {"G1 Status Register", 0x006, NI_660x_READ, DATA_2B},
+ {"G01 Status Register ", 0x008, NI_660x_READ, DATA_2B},
+ {"G0 Command Register", 0x00C, NI_660x_WRITE, DATA_2B},
+ {"STC DIO Parallel Input", 0x00E, NI_660x_READ, DATA_2B},
+ {"G1 Command Register", 0x00E, NI_660x_WRITE, DATA_2B},
+ {"G0 HW Save Register", 0x010, NI_660x_READ, DATA_4B},
+ {"G1 HW Save Register", 0x014, NI_660x_READ, DATA_4B},
+ {"STC DIO Output", 0x014, NI_660x_WRITE, DATA_2B},
+ {"STC DIO Control", 0x016, NI_660x_WRITE, DATA_2B},
+ {"G0 SW Save Register", 0x018, NI_660x_READ, DATA_4B},
+ {"G1 SW Save Register", 0x01C, NI_660x_READ, DATA_4B},
+ {"G0 Mode Register", 0x034, NI_660x_WRITE, DATA_2B},
+ {"G01 Joint Status 1 Register", 0x036, NI_660x_READ, DATA_2B},
+ {"G1 Mode Register", 0x036, NI_660x_WRITE, DATA_2B},
+ {"STC DIO Serial Input", 0x038, NI_660x_READ, DATA_2B},
+ {"G0 Load A Register", 0x038, NI_660x_WRITE, DATA_4B},
+ {"G01 Joint Status 2 Register", 0x03A, NI_660x_READ, DATA_2B},
+ {"G0 Load B Register", 0x03C, NI_660x_WRITE, DATA_4B},
+ {"G1 Load A Register", 0x040, NI_660x_WRITE, DATA_4B},
+ {"G1 Load B Register", 0x044, NI_660x_WRITE, DATA_4B},
+ {"G0 Input Select Register", 0x048, NI_660x_WRITE, DATA_2B},
+ {"G1 Input Select Register", 0x04A, NI_660x_WRITE, DATA_2B},
+ {"G0 Autoincrement Register", 0x088, NI_660x_WRITE, DATA_2B},
+ {"G1 Autoincrement Register", 0x08A, NI_660x_WRITE, DATA_2B},
+ {"G01 Joint Reset Register", 0x090, NI_660x_WRITE, DATA_2B},
+ {"G0 Interrupt Enable", 0x092, NI_660x_WRITE, DATA_2B},
+ {"G1 Interrupt Enable", 0x096, NI_660x_WRITE, DATA_2B},
+ {"G0 Counting Mode Register", 0x0B0, NI_660x_WRITE, DATA_2B},
+ {"G1 Counting Mode Register", 0x0B2, NI_660x_WRITE, DATA_2B},
+ {"G0 Second Gate Register", 0x0B4, NI_660x_WRITE, DATA_2B},
+ {"G1 Second Gate Register", 0x0B6, NI_660x_WRITE, DATA_2B},
+ {"G0 DMA Config Register", 0x0B8, NI_660x_WRITE, DATA_2B},
+ {"G0 DMA Status Register", 0x0B8, NI_660x_READ, DATA_2B},
+ {"G1 DMA Config Register", 0x0BA, NI_660x_WRITE, DATA_2B},
+ {"G1 DMA Status Register", 0x0BA, NI_660x_READ, DATA_2B},
+ {"G2 Interrupt Acknowledge", 0x104, NI_660x_WRITE, DATA_2B},
+ {"G2 Status Register", 0x104, NI_660x_READ, DATA_2B},
+ {"G3 Interrupt Acknowledge", 0x106, NI_660x_WRITE, DATA_2B},
+ {"G3 Status Register", 0x106, NI_660x_READ, DATA_2B},
+ {"G23 Status Register", 0x108, NI_660x_READ, DATA_2B},
+ {"G2 Command Register", 0x10C, NI_660x_WRITE, DATA_2B},
+ {"G3 Command Register", 0x10E, NI_660x_WRITE, DATA_2B},
+ {"G2 HW Save Register", 0x110, NI_660x_READ, DATA_4B},
+ {"G3 HW Save Register", 0x114, NI_660x_READ, DATA_4B},
+ {"G2 SW Save Register", 0x118, NI_660x_READ, DATA_4B},
+ {"G3 SW Save Register", 0x11C, NI_660x_READ, DATA_4B},
+ {"G2 Mode Register", 0x134, NI_660x_WRITE, DATA_2B},
+ {"G23 Joint Status 1 Register", 0x136, NI_660x_READ, DATA_2B},
+ {"G3 Mode Register", 0x136, NI_660x_WRITE, DATA_2B},
+ {"G2 Load A Register", 0x138, NI_660x_WRITE, DATA_4B},
+ {"G23 Joint Status 2 Register", 0x13A, NI_660x_READ, DATA_2B},
+ {"G2 Load B Register", 0x13C, NI_660x_WRITE, DATA_4B},
+ {"G3 Load A Register", 0x140, NI_660x_WRITE, DATA_4B},
+ {"G3 Load B Register", 0x144, NI_660x_WRITE, DATA_4B},
+ {"G2 Input Select Register", 0x148, NI_660x_WRITE, DATA_2B},
+ {"G3 Input Select Register", 0x14A, NI_660x_WRITE, DATA_2B},
+ {"G2 Autoincrement Register", 0x188, NI_660x_WRITE, DATA_2B},
+ {"G3 Autoincrement Register", 0x18A, NI_660x_WRITE, DATA_2B},
+ {"G23 Joint Reset Register", 0x190, NI_660x_WRITE, DATA_2B},
+ {"G2 Interrupt Enable", 0x192, NI_660x_WRITE, DATA_2B},
+ {"G3 Interrupt Enable", 0x196, NI_660x_WRITE, DATA_2B},
+ {"G2 Counting Mode Register", 0x1B0, NI_660x_WRITE, DATA_2B},
+ {"G3 Counting Mode Register", 0x1B2, NI_660x_WRITE, DATA_2B},
+ {"G3 Second Gate Register", 0x1B6, NI_660x_WRITE, DATA_2B},
+ {"G2 Second Gate Register", 0x1B4, NI_660x_WRITE, DATA_2B},
+ {"G2 DMA Config Register", 0x1B8, NI_660x_WRITE, DATA_2B},
+ {"G2 DMA Status Register", 0x1B8, NI_660x_READ, DATA_2B},
+ {"G3 DMA Config Register", 0x1BA, NI_660x_WRITE, DATA_2B},
+ {"G3 DMA Status Register", 0x1BA, NI_660x_READ, DATA_2B},
+ {"32 bit Digital Input", 0x414, NI_660x_READ, DATA_4B},
+ {"32 bit Digital Output", 0x510, NI_660x_WRITE, DATA_4B},
+ {"Clock Config Register", 0x73C, NI_660x_WRITE, DATA_4B},
+ {"Global Interrupt Status Register", 0x754, NI_660x_READ, DATA_4B},
+ {"DMA Configuration Register", 0x76C, NI_660x_WRITE, DATA_4B},
+ {"Global Interrupt Config Register", 0x770, NI_660x_WRITE, DATA_4B},
+ {"IO Config Register 0-1", 0x77C, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 2-3", 0x77E, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 4-5", 0x780, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 6-7", 0x782, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 8-9", 0x784, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 10-11", 0x786, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 12-13", 0x788, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 14-15", 0x78A, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 16-17", 0x78C, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 18-19", 0x78E, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 20-21", 0x790, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 22-23", 0x792, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 24-25", 0x794, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 26-27", 0x796, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 28-29", 0x798, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 30-31", 0x79A, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 32-33", 0x79C, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 34-35", 0x79E, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 36-37", 0x7A0, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 38-39", 0x7A2, NI_660x_READ_WRITE, DATA_2B}
+};
+
+// kind of ENABLE for the second counter
+enum clock_config_register_bits {
+ CounterSwap = 0x1 << 21
+};
+
+// ioconfigreg
+static inline unsigned ioconfig_bitshift(unsigned pfi_channel)
+{
+ if (pfi_channel % 2)
+ return 0;
+ else
+ return 8;
+}
+static inline unsigned pfi_output_select_mask(unsigned pfi_channel)
+{
+ return 0x3 << ioconfig_bitshift(pfi_channel);
+}
+static inline unsigned pfi_output_select_bits(unsigned pfi_channel,
+ unsigned output_select)
+{
+ return (output_select & 0x3) << ioconfig_bitshift(pfi_channel);
+}
+static inline unsigned pfi_input_select_mask(unsigned pfi_channel)
+{
+ return 0x7 << (4 + ioconfig_bitshift(pfi_channel));
+}
+static inline unsigned pfi_input_select_bits(unsigned pfi_channel,
+ unsigned input_select)
+{
+ return (input_select & 0x7) << (4 + ioconfig_bitshift(pfi_channel));
+}
+
+// dma configuration register bits
+static inline unsigned dma_select_mask(unsigned dma_channel)
+{
+ BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
+ return 0x1f << (8 * dma_channel);
+}
+enum dma_selection {
+ dma_selection_none = 0x1f,
+};
+static inline unsigned dma_selection_counter(unsigned counter_index)
+{
+ BUG_ON(counter_index >= counters_per_chip);
+ return counter_index;
+}
+static inline unsigned dma_select_bits(unsigned dma_channel, unsigned selection)
+{
+ BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
+ return (selection << (8 * dma_channel)) & dma_select_mask(dma_channel);
+}
+static inline unsigned dma_reset_bit(unsigned dma_channel)
+{
+ BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
+ return 0x80 << (8 * dma_channel);
+}
+
+enum global_interrupt_status_register_bits {
+ Counter_0_Int_Bit = 0x100,
+ Counter_1_Int_Bit = 0x200,
+ Counter_2_Int_Bit = 0x400,
+ Counter_3_Int_Bit = 0x800,
+ Cascade_Int_Bit = 0x20000000,
+ Global_Int_Bit = 0x80000000
+};
+
+enum global_interrupt_config_register_bits {
+ Cascade_Int_Enable_Bit = 0x20000000,
+ Global_Int_Polarity_Bit = 0x40000000,
+ Global_Int_Enable_Bit = 0x80000000
+};
+
+// Offset of the GPCT chips from the base-adress of the card
+static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; /* First chip is at base-address +
+ 0x00, etc. */
+
+/* Board description*/
+struct ni_660x_board {
+ unsigned short dev_id; /* `lspci` will show you this */
+ const char *name;
+ unsigned n_chips; /* total number of TIO chips */
+};
+
+static const struct ni_660x_board ni_660x_boards[] = {
+ {
+ dev_id: 0x2c60,
+ name: "PCI-6601",
+ n_chips: 1,
+ },
+ {
+ dev_id: 0x1310,
+ name: "PCI-6602",
+ n_chips: 2,
+ },
+ {
+ dev_id: 0x1360,
+ name: "PXI-6602",
+ n_chips: 2,
+ },
+ {
+ dev_id: 0x2cc0,
+ name: "PXI-6608",
+ n_chips: 2,
+ },
+};
+
+#define NI_660X_MAX_NUM_CHIPS 2
+#define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip)
+
+static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x2c60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2cc0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
+
+struct ni_660x_private {
+ struct mite_struct *mite;
+ struct ni_gpct_device *counter_dev;
+ uint64_t pfi_direction_bits;
+ struct mite_dma_descriptor_ring
+ *mite_rings[NI_660X_MAX_NUM_CHIPS][counters_per_chip];
+ spinlock_t mite_channel_lock;
+ unsigned dma_configuration_soft_copies[NI_660X_MAX_NUM_CHIPS];
+ spinlock_t soft_reg_copy_lock;
+ unsigned short pfi_output_selects[NUM_PFI_CHANNELS];
+};
+
+static inline struct ni_660x_private *private(struct comedi_device * dev)
+{
+ return dev->private;
+}
+
+/* initialized in ni_660x_find_device() */
+static inline const struct ni_660x_board *board(struct comedi_device * dev)
+{
+ return dev->board_ptr;
+}
+
+#define n_ni_660x_boards (sizeof(ni_660x_boards)/sizeof(ni_660x_boards[0]))
+
+static int ni_660x_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni_660x_detach(struct comedi_device * dev);
+static void init_tio_chip(struct comedi_device * dev, int chipset);
+static void ni_660x_select_pfi_output(struct comedi_device * dev, unsigned pfi_channel,
+ unsigned output_select);
+
+static struct comedi_driver driver_ni_660x = {
+ driver_name:"ni_660x",
+ module:THIS_MODULE,
+ attach:ni_660x_attach,
+ detach:ni_660x_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_ni_660x, ni_660x_pci_table);
+
+static int ni_660x_find_device(struct comedi_device * dev, int bus, int slot);
+static int ni_660x_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+ unsigned source);
+
+/* Possible instructions for a GPCT */
+static int ni_660x_GPCT_rinsn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int ni_660x_GPCT_insn_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int ni_660x_GPCT_winsn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+/* Possible instructions for Digital IO */
+static int ni_660x_dio_insn_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int ni_660x_dio_insn_bits(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static inline unsigned ni_660x_num_counters(struct comedi_device * dev)
+{
+ return board(dev)->n_chips * counters_per_chip;
+}
+
+static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
+{
+ enum NI_660x_Register ni_660x_register;
+ switch (reg) {
+ case NITIO_G0_Autoincrement_Reg:
+ ni_660x_register = G0AutoincrementRegister;
+ break;
+ case NITIO_G1_Autoincrement_Reg:
+ ni_660x_register = G1AutoincrementRegister;
+ break;
+ case NITIO_G2_Autoincrement_Reg:
+ ni_660x_register = G2AutoincrementRegister;
+ break;
+ case NITIO_G3_Autoincrement_Reg:
+ ni_660x_register = G3AutoincrementRegister;
+ break;
+ case NITIO_G0_Command_Reg:
+ ni_660x_register = G0CommandRegister;
+ break;
+ case NITIO_G1_Command_Reg:
+ ni_660x_register = G1CommandRegister;
+ break;
+ case NITIO_G2_Command_Reg:
+ ni_660x_register = G2CommandRegister;
+ break;
+ case NITIO_G3_Command_Reg:
+ ni_660x_register = G3CommandRegister;
+ break;
+ case NITIO_G0_HW_Save_Reg:
+ ni_660x_register = G0HWSaveRegister;
+ break;
+ case NITIO_G1_HW_Save_Reg:
+ ni_660x_register = G1HWSaveRegister;
+ break;
+ case NITIO_G2_HW_Save_Reg:
+ ni_660x_register = G2HWSaveRegister;
+ break;
+ case NITIO_G3_HW_Save_Reg:
+ ni_660x_register = G3HWSaveRegister;
+ break;
+ case NITIO_G0_SW_Save_Reg:
+ ni_660x_register = G0SWSaveRegister;
+ break;
+ case NITIO_G1_SW_Save_Reg:
+ ni_660x_register = G1SWSaveRegister;
+ break;
+ case NITIO_G2_SW_Save_Reg:
+ ni_660x_register = G2SWSaveRegister;
+ break;
+ case NITIO_G3_SW_Save_Reg:
+ ni_660x_register = G3SWSaveRegister;
+ break;
+ case NITIO_G0_Mode_Reg:
+ ni_660x_register = G0ModeRegister;
+ break;
+ case NITIO_G1_Mode_Reg:
+ ni_660x_register = G1ModeRegister;
+ break;
+ case NITIO_G2_Mode_Reg:
+ ni_660x_register = G2ModeRegister;
+ break;
+ case NITIO_G3_Mode_Reg:
+ ni_660x_register = G3ModeRegister;
+ break;
+ case NITIO_G0_LoadA_Reg:
+ ni_660x_register = G0LoadARegister;
+ break;
+ case NITIO_G1_LoadA_Reg:
+ ni_660x_register = G1LoadARegister;
+ break;
+ case NITIO_G2_LoadA_Reg:
+ ni_660x_register = G2LoadARegister;
+ break;
+ case NITIO_G3_LoadA_Reg:
+ ni_660x_register = G3LoadARegister;
+ break;
+ case NITIO_G0_LoadB_Reg:
+ ni_660x_register = G0LoadBRegister;
+ break;
+ case NITIO_G1_LoadB_Reg:
+ ni_660x_register = G1LoadBRegister;
+ break;
+ case NITIO_G2_LoadB_Reg:
+ ni_660x_register = G2LoadBRegister;
+ break;
+ case NITIO_G3_LoadB_Reg:
+ ni_660x_register = G3LoadBRegister;
+ break;
+ case NITIO_G0_Input_Select_Reg:
+ ni_660x_register = G0InputSelectRegister;
+ break;
+ case NITIO_G1_Input_Select_Reg:
+ ni_660x_register = G1InputSelectRegister;
+ break;
+ case NITIO_G2_Input_Select_Reg:
+ ni_660x_register = G2InputSelectRegister;
+ break;
+ case NITIO_G3_Input_Select_Reg:
+ ni_660x_register = G3InputSelectRegister;
+ break;
+ case NITIO_G01_Status_Reg:
+ ni_660x_register = G01StatusRegister;
+ break;
+ case NITIO_G23_Status_Reg:
+ ni_660x_register = G23StatusRegister;
+ break;
+ case NITIO_G01_Joint_Reset_Reg:
+ ni_660x_register = G01JointResetRegister;
+ break;
+ case NITIO_G23_Joint_Reset_Reg:
+ ni_660x_register = G23JointResetRegister;
+ break;
+ case NITIO_G01_Joint_Status1_Reg:
+ ni_660x_register = G01JointStatus1Register;
+ break;
+ case NITIO_G23_Joint_Status1_Reg:
+ ni_660x_register = G23JointStatus1Register;
+ break;
+ case NITIO_G01_Joint_Status2_Reg:
+ ni_660x_register = G01JointStatus2Register;
+ break;
+ case NITIO_G23_Joint_Status2_Reg:
+ ni_660x_register = G23JointStatus2Register;
+ break;
+ case NITIO_G0_Counting_Mode_Reg:
+ ni_660x_register = G0CountingModeRegister;
+ break;
+ case NITIO_G1_Counting_Mode_Reg:
+ ni_660x_register = G1CountingModeRegister;
+ break;
+ case NITIO_G2_Counting_Mode_Reg:
+ ni_660x_register = G2CountingModeRegister;
+ break;
+ case NITIO_G3_Counting_Mode_Reg:
+ ni_660x_register = G3CountingModeRegister;
+ break;
+ case NITIO_G0_Second_Gate_Reg:
+ ni_660x_register = G0SecondGateRegister;
+ break;
+ case NITIO_G1_Second_Gate_Reg:
+ ni_660x_register = G1SecondGateRegister;
+ break;
+ case NITIO_G2_Second_Gate_Reg:
+ ni_660x_register = G2SecondGateRegister;
+ break;
+ case NITIO_G3_Second_Gate_Reg:
+ ni_660x_register = G3SecondGateRegister;
+ break;
+ case NITIO_G0_DMA_Config_Reg:
+ ni_660x_register = G0DMAConfigRegister;
+ break;
+ case NITIO_G0_DMA_Status_Reg:
+ ni_660x_register = G0DMAStatusRegister;
+ break;
+ case NITIO_G1_DMA_Config_Reg:
+ ni_660x_register = G1DMAConfigRegister;
+ break;
+ case NITIO_G1_DMA_Status_Reg:
+ ni_660x_register = G1DMAStatusRegister;
+ break;
+ case NITIO_G2_DMA_Config_Reg:
+ ni_660x_register = G2DMAConfigRegister;
+ break;
+ case NITIO_G2_DMA_Status_Reg:
+ ni_660x_register = G2DMAStatusRegister;
+ break;
+ case NITIO_G3_DMA_Config_Reg:
+ ni_660x_register = G3DMAConfigRegister;
+ break;
+ case NITIO_G3_DMA_Status_Reg:
+ ni_660x_register = G3DMAStatusRegister;
+ break;
+ case NITIO_G0_Interrupt_Acknowledge_Reg:
+ ni_660x_register = G0InterruptAcknowledge;
+ break;
+ case NITIO_G1_Interrupt_Acknowledge_Reg:
+ ni_660x_register = G1InterruptAcknowledge;
+ break;
+ case NITIO_G2_Interrupt_Acknowledge_Reg:
+ ni_660x_register = G2InterruptAcknowledge;
+ break;
+ case NITIO_G3_Interrupt_Acknowledge_Reg:
+ ni_660x_register = G3InterruptAcknowledge;
+ break;
+ case NITIO_G0_Status_Reg:
+ ni_660x_register = G0StatusRegister;
+ break;
+ case NITIO_G1_Status_Reg:
+ ni_660x_register = G0StatusRegister;
+ break;
+ case NITIO_G2_Status_Reg:
+ ni_660x_register = G0StatusRegister;
+ break;
+ case NITIO_G3_Status_Reg:
+ ni_660x_register = G0StatusRegister;
+ break;
+ case NITIO_G0_Interrupt_Enable_Reg:
+ ni_660x_register = G0InterruptEnable;
+ break;
+ case NITIO_G1_Interrupt_Enable_Reg:
+ ni_660x_register = G1InterruptEnable;
+ break;
+ case NITIO_G2_Interrupt_Enable_Reg:
+ ni_660x_register = G2InterruptEnable;
+ break;
+ case NITIO_G3_Interrupt_Enable_Reg:
+ ni_660x_register = G3InterruptEnable;
+ break;
+ default:
+ rt_printk("%s: unhandled register 0x%x in switch.\n",
+ __FUNCTION__, reg);
+ BUG();
+ return 0;
+ break;
+ }
+ return ni_660x_register;
+}
+
+static inline void ni_660x_write_register(struct comedi_device * dev,
+ unsigned chip_index, unsigned bits, enum NI_660x_Register reg)
+{
+ void *const write_address =
+ private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
+ registerData[reg].offset;
+
+ switch (registerData[reg].size) {
+ case DATA_2B:
+ writew(bits, write_address);
+ break;
+ case DATA_4B:
+ writel(bits, write_address);
+ break;
+ default:
+ rt_printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
+ __FILE__, __FUNCTION__, reg);
+ BUG();
+ break;
+ }
+}
+
+static inline unsigned ni_660x_read_register(struct comedi_device * dev,
+ unsigned chip_index, enum NI_660x_Register reg)
+{
+ void *const read_address =
+ private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
+ registerData[reg].offset;
+
+ switch (registerData[reg].size) {
+ case DATA_2B:
+ return readw(read_address);
+ break;
+ case DATA_4B:
+ return readl(read_address);
+ break;
+ default:
+ rt_printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
+ __FILE__, __FUNCTION__, reg);
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
+ enum ni_gpct_register reg)
+{
+ struct comedi_device *dev = counter->counter_dev->dev;
+ enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg);
+ ni_660x_write_register(dev, counter->chip_index, bits,
+ ni_660x_register);
+}
+
+static unsigned ni_gpct_read_register(struct ni_gpct *counter,
+ enum ni_gpct_register reg)
+{
+ struct comedi_device *dev = counter->counter_dev->dev;
+ enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg);
+ return ni_660x_read_register(dev, counter->chip_index,
+ ni_660x_register);
+}
+
+static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private * priv,
+ struct ni_gpct *counter)
+{
+ return priv->mite_rings[counter->chip_index][counter->counter_index];
+}
+
+static inline void ni_660x_set_dma_channel(struct comedi_device * dev,
+ unsigned mite_channel, struct ni_gpct *counter)
+{
+ unsigned long flags;
+ comedi_spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
+ private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
+ ~dma_select_mask(mite_channel);
+ private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
+ dma_select_bits(mite_channel,
+ dma_selection_counter(counter->counter_index));
+ ni_660x_write_register(dev, counter->chip_index,
+ private(dev)->dma_configuration_soft_copies[counter->
+ chip_index] | dma_reset_bit(mite_channel),
+ DMAConfigRegister);
+ mmiowb();
+ comedi_spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
+}
+
+static inline void ni_660x_unset_dma_channel(struct comedi_device * dev,
+ unsigned mite_channel, struct ni_gpct *counter)
+{
+ unsigned long flags;
+ comedi_spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
+ private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
+ ~dma_select_mask(mite_channel);
+ private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
+ dma_select_bits(mite_channel, dma_selection_none);
+ ni_660x_write_register(dev, counter->chip_index,
+ private(dev)->dma_configuration_soft_copies[counter->
+ chip_index], DMAConfigRegister);
+ mmiowb();
+ comedi_spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
+}
+
+static int ni_660x_request_mite_channel(struct comedi_device * dev,
+ struct ni_gpct *counter, enum comedi_io_direction direction)
+{
+ unsigned long flags;
+ struct mite_channel *mite_chan;
+
+ comedi_spin_lock_irqsave(&private(dev)->mite_channel_lock, flags);
+ BUG_ON(counter->mite_chan);
+ mite_chan =
+ mite_request_channel(private(dev)->mite, mite_ring(private(dev),
+ counter));
+ if (mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&private(dev)->mite_channel_lock,
+ flags);
+ comedi_error(dev,
+ "failed to reserve mite dma channel for counter.");
+ return -EBUSY;
+ }
+ mite_chan->dir = direction;
+ ni_tio_set_mite_channel(counter, mite_chan);
+ ni_660x_set_dma_channel(dev, mite_chan->channel, counter);
+ comedi_spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
+ return 0;
+}
+
+void ni_660x_release_mite_channel(struct comedi_device * dev, struct ni_gpct *counter)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&private(dev)->mite_channel_lock, flags);
+ if (counter->mite_chan) {
+ struct mite_channel *mite_chan = counter->mite_chan;
+
+ ni_660x_unset_dma_channel(dev, mite_chan->channel, counter);
+ ni_tio_set_mite_channel(counter, NULL);
+ mite_release_channel(mite_chan);
+ }
+ comedi_spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
+}
+
+static int ni_660x_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int retval;
+
+ struct ni_gpct *counter = subdev_to_counter(s);
+// const struct comedi_cmd *cmd = &s->async->cmd;
+
+ retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
+ if (retval) {
+ comedi_error(dev,
+ "no dma channel available for use by counter");
+ return retval;
+ }
+ ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
+ retval = ni_tio_cmd(counter, s->async);
+
+ return retval;
+}
+
+static int ni_660x_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ struct ni_gpct *counter = subdev_to_counter(s);
+
+ return ni_tio_cmdtest(counter, cmd);
+}
+
+static int ni_660x_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct ni_gpct *counter = subdev_to_counter(s);
+ int retval;
+
+ retval = ni_tio_cancel(counter);
+ ni_660x_release_mite_channel(dev, counter);
+ return retval;
+}
+
+static void set_tio_counterswap(struct comedi_device * dev, int chipset)
+{
+ /* See P. 3.5 of the Register-Level Programming manual. The
+ CounterSwap bit has to be set on the second chip, otherwise
+ it will try to use the same pins as the first chip.
+ */
+ if (chipset)
+ ni_660x_write_register(dev, chipset, CounterSwap,
+ ClockConfigRegister);
+ else
+ ni_660x_write_register(dev, chipset, 0, ClockConfigRegister);
+}
+
+static void ni_660x_handle_gpct_interrupt(struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ ni_tio_handle_interrupt(subdev_to_counter(s), s);
+ if (s->async->events) {
+ if (s->async->
+ events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
+ COMEDI_CB_OVERFLOW)) {
+ ni_660x_cancel(dev, s);
+ }
+ comedi_event(dev, s);
+ }
+}
+
+static irqreturn_t ni_660x_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s;
+ unsigned i;
+
+ if (dev->attached == 0)
+ return IRQ_NONE;
+ smp_mb();
+ for (i = 0; i < ni_660x_num_counters(dev); ++i) {
+ s = dev->subdevices + NI_660X_GPCT_SUBDEV(i);
+ ni_660x_handle_gpct_interrupt(dev, s);
+ }
+ return IRQ_HANDLED;
+}
+
+static int ni_660x_buf_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(mite_ring(private(dev), subdev_to_counter(s)),
+ s->async);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int ni_660x_allocate_private(struct comedi_device * dev)
+{
+ int retval;
+ unsigned i;
+
+ if ((retval = alloc_private(dev, sizeof(struct ni_660x_private))) < 0)
+ return retval;
+ spin_lock_init(&private(dev)->mite_channel_lock);
+ spin_lock_init(&private(dev)->soft_reg_copy_lock);
+ for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
+ private(dev)->pfi_output_selects[i] = pfi_output_select_counter;
+ }
+ return 0;
+}
+
+static int ni_660x_alloc_mite_rings(struct comedi_device * dev)
+{
+ unsigned i;
+ unsigned j;
+
+ for (i = 0; i < board(dev)->n_chips; ++i) {
+ for (j = 0; j < counters_per_chip; ++j) {
+ private(dev)->mite_rings[i][j] =
+ mite_alloc_ring(private(dev)->mite);
+ if (private(dev)->mite_rings[i][j] == NULL) {
+ return -ENOMEM;
+ }
+ }
+ }
+ return 0;
+}
+
+static void ni_660x_free_mite_rings(struct comedi_device * dev)
+{
+ unsigned i;
+ unsigned j;
+
+ for (i = 0; i < board(dev)->n_chips; ++i) {
+ for (j = 0; j < counters_per_chip; ++j) {
+ mite_free_ring(private(dev)->mite_rings[i][j]);
+ }
+ }
+}
+
+static int ni_660x_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret;
+ unsigned i;
+ unsigned global_interrupt_config_bits;
+
+ printk("comedi%d: ni_660x: ", dev->minor);
+
+ ret = ni_660x_allocate_private(dev);
+ if (ret < 0)
+ return ret;
+ ret = ni_660x_find_device(dev, it->options[0], it->options[1]);
+ if (ret < 0)
+ return ret;
+
+ dev->board_name = board(dev)->name;
+
+ ret = mite_setup2(private(dev)->mite, 1);
+ if (ret < 0) {
+ printk("error setting up mite\n");
+ return ret;
+ }
+ comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev);
+ ret = ni_660x_alloc_mite_rings(dev);
+ if (ret < 0)
+ return ret;
+
+ printk(" %s ", dev->board_name);
+
+ dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS;
+
+ if (alloc_subdevices(dev, dev->n_subdevices) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */
+ s->type = COMEDI_SUBD_UNUSED;
+
+ s = dev->subdevices + NI_660X_DIO_SUBDEV;
+ /* DIGITAL I/O SUBDEVICE */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = NUM_PFI_CHANNELS;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = ni_660x_dio_insn_bits;
+ s->insn_config = ni_660x_dio_insn_config;
+ s->io_bits = 0; /* all bits default to input */
+ // we use the ioconfig registers to control dio direction, so zero output enables in stc dio control reg
+ ni_660x_write_register(dev, 0, 0, STCDIOControl);
+
+ private(dev)->counter_dev = ni_gpct_device_construct(dev,
+ &ni_gpct_write_register, &ni_gpct_read_register,
+ ni_gpct_variant_660x, ni_660x_num_counters(dev));
+ if (private(dev)->counter_dev == NULL)
+ return -ENOMEM;
+ for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) {
+ s = dev->subdevices + NI_660X_GPCT_SUBDEV(i);
+ if (i < ni_660x_num_counters(dev)) {
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
+ SDF_CMD_READ /* | SDF_CMD_WRITE */ ;
+ s->n_chan = 3;
+ s->maxdata = 0xffffffff;
+ s->insn_read = ni_660x_GPCT_rinsn;
+ s->insn_write = ni_660x_GPCT_winsn;
+ s->insn_config = ni_660x_GPCT_insn_config;
+ s->do_cmd = &ni_660x_cmd;
+ s->len_chanlist = 1;
+ s->do_cmdtest = &ni_660x_cmdtest;
+ s->cancel = &ni_660x_cancel;
+ s->async_dma_dir = DMA_BIDIRECTIONAL;
+ s->buf_change = &ni_660x_buf_change;
+ s->private = &private(dev)->counter_dev->counters[i];
+
+ private(dev)->counter_dev->counters[i].chip_index =
+ i / counters_per_chip;
+ private(dev)->counter_dev->counters[i].counter_index =
+ i % counters_per_chip;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ }
+ for (i = 0; i < board(dev)->n_chips; ++i) {
+ init_tio_chip(dev, i);
+ }
+ for (i = 0; i < ni_660x_num_counters(dev); ++i) {
+ ni_tio_init_counter(&private(dev)->counter_dev->counters[i]);
+ }
+ for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
+ if (i < min_counter_pfi_chan)
+ ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
+ else
+ ni_660x_set_pfi_routing(dev, i,
+ pfi_output_select_counter);
+ ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z);
+ }
+ /* to be safe, set counterswap bits on tio chips after all the counter
+ outputs have been set to high impedance mode */
+ for (i = 0; i < board(dev)->n_chips; ++i) {
+ set_tio_counterswap(dev, i);
+ }
+ if ((ret = comedi_request_irq(mite_irq(private(dev)->mite),
+ &ni_660x_interrupt, IRQF_SHARED, "ni_660x",
+ dev)) < 0) {
+ printk(" irq not available\n");
+ return ret;
+ }
+ dev->irq = mite_irq(private(dev)->mite);
+ global_interrupt_config_bits = Global_Int_Enable_Bit;
+ if (board(dev)->n_chips > 1)
+ global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
+ ni_660x_write_register(dev, 0, global_interrupt_config_bits,
+ GlobalInterruptConfigRegister);
+ printk("attached\n");
+ return 0;
+}
+
+static int ni_660x_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: ni_660x: remove\n", dev->minor);
+
+ /* Free irq */
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (dev->private) {
+ if (private(dev)->counter_dev)
+ ni_gpct_device_destroy(private(dev)->counter_dev);
+ if (private(dev)->mite) {
+ ni_660x_free_mite_rings(dev);
+ mite_unsetup(private(dev)->mite);
+ }
+ }
+ return 0;
+}
+
+static int
+ni_660x_GPCT_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ return ni_tio_rinsn(subdev_to_counter(s), insn, data);
+}
+
+static void init_tio_chip(struct comedi_device * dev, int chipset)
+{
+ unsigned i;
+
+ // init dma configuration register
+ private(dev)->dma_configuration_soft_copies[chipset] = 0;
+ for (i = 0; i < MAX_DMA_CHANNEL; ++i) {
+ private(dev)->dma_configuration_soft_copies[chipset] |=
+ dma_select_bits(i,
+ dma_selection_none) & dma_select_mask(i);
+ }
+ ni_660x_write_register(dev, chipset,
+ private(dev)->dma_configuration_soft_copies[chipset],
+ DMAConfigRegister);
+ for(i = 0; i < NUM_PFI_CHANNELS; ++i)
+ {
+ ni_660x_write_register(dev, chipset, 0, IOConfigReg(i));
+ }
+}
+
+static int
+ni_660x_GPCT_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ return ni_tio_insn_config(subdev_to_counter(s), insn, data);
+}
+
+static int ni_660x_GPCT_winsn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ return ni_tio_winsn(subdev_to_counter(s), insn, data);
+}
+
+static int ni_660x_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number ||
+ slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+
+ for (i = 0; i < n_ni_660x_boards; i++) {
+ if (mite_device_id(mite) == ni_660x_boards[i].dev_id) {
+ dev->board_ptr = ni_660x_boards + i;
+ private(dev)->mite = mite;
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
+
+static int ni_660x_dio_insn_bits(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned base_bitfield_channel = CR_CHAN(insn->chanspec);
+
+ // Check if we have to write some bits
+ if (data[0]) {
+ s->state &= ~(data[0] << base_bitfield_channel);
+ s->state |= (data[0] & data[1]) << base_bitfield_channel;
+ /* Write out the new digital output lines */
+ ni_660x_write_register(dev, 0, s->state, DIO32Output);
+ }
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ data[1] =
+ (ni_660x_read_register(dev, 0,
+ DIO32Input) >> base_bitfield_channel);
+ return 2;
+}
+
+static void ni_660x_select_pfi_output(struct comedi_device * dev, unsigned pfi_channel,
+ unsigned output_select)
+{
+ static const unsigned counter_4_7_first_pfi = 8;
+ static const unsigned counter_4_7_last_pfi = 23;
+ unsigned active_chipset = 0;
+ unsigned idle_chipset = 0;
+ unsigned active_bits;
+ unsigned idle_bits;
+
+ if(board(dev)->n_chips > 1) {
+ if(output_select == pfi_output_select_counter &&
+ pfi_channel >= counter_4_7_first_pfi &&
+ pfi_channel <= counter_4_7_last_pfi) {
+ active_chipset = 1;
+ idle_chipset = 0;
+ }else {
+ active_chipset = 0;
+ idle_chipset = 1;
+ }
+ }
+
+ if(idle_chipset != active_chipset) {
+ idle_bits = ni_660x_read_register(dev, idle_chipset, IOConfigReg(pfi_channel));
+ idle_bits &= ~pfi_output_select_mask(pfi_channel);
+ idle_bits |= pfi_output_select_bits(pfi_channel, pfi_output_select_high_Z);
+ ni_660x_write_register(dev, idle_chipset, idle_bits, IOConfigReg(pfi_channel));
+ }
+
+ active_bits = ni_660x_read_register(dev, active_chipset, IOConfigReg(pfi_channel));
+ active_bits &= ~pfi_output_select_mask(pfi_channel);
+ active_bits |= pfi_output_select_bits(pfi_channel, output_select);
+ ni_660x_write_register(dev, active_chipset, active_bits, IOConfigReg(pfi_channel));
+}
+
+static int ni_660x_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+ unsigned source)
+{
+ if (source > num_pfi_output_selects)
+ return -EINVAL;
+ if (source == pfi_output_select_high_Z)
+ return -EINVAL;
+ if (chan < min_counter_pfi_chan) {
+ if (source == pfi_output_select_counter)
+ return -EINVAL;
+ } else if (chan > max_dio_pfi_chan) {
+ if (source == pfi_output_select_do)
+ return -EINVAL;
+ }
+ BUG_ON(chan >= NUM_PFI_CHANNELS);
+
+ private(dev)->pfi_output_selects[chan] = source;
+ if (private(dev)->pfi_direction_bits & (((uint64_t) 1) << chan))
+ ni_660x_select_pfi_output(dev, chan,
+ private(dev)->pfi_output_selects[chan]);
+ return 0;
+}
+
+static unsigned ni_660x_get_pfi_routing(struct comedi_device * dev, unsigned chan)
+{
+ BUG_ON(chan >= NUM_PFI_CHANNELS);
+ return private(dev)->pfi_output_selects[chan];
+}
+
+static void ni660x_config_filter(struct comedi_device * dev, unsigned pfi_channel,
+ enum ni_gpct_filter_select filter)
+{
+ unsigned bits = ni_660x_read_register(dev, 0, IOConfigReg(pfi_channel));
+ bits &= ~pfi_input_select_mask(pfi_channel);
+ bits |= pfi_input_select_bits(pfi_channel, filter);
+ ni_660x_write_register(dev, 0, bits, IOConfigReg(pfi_channel));
+}
+
+static int ni_660x_dio_insn_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+
+ /* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ private(dev)->pfi_direction_bits |= ((uint64_t) 1) << chan;
+ ni_660x_select_pfi_output(dev, chan,
+ private(dev)->pfi_output_selects[chan]);
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ private(dev)->pfi_direction_bits &= ~(((uint64_t) 1) << chan);
+ ni_660x_select_pfi_output(dev, chan, pfi_output_select_high_Z);
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (private(dev)->
+ pfi_direction_bits & (((uint64_t) 1) << chan)) ?
+ COMEDI_OUTPUT : COMEDI_INPUT;
+ return 0;
+ case INSN_CONFIG_SET_ROUTING:
+ return ni_660x_set_pfi_routing(dev, chan, data[1]);
+ break;
+ case INSN_CONFIG_GET_ROUTING:
+ data[1] = ni_660x_get_pfi_routing(dev, chan);
+ break;
+ case INSN_CONFIG_FILTER:
+ ni660x_config_filter(dev, chan, data[1]);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ };
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c
new file mode 100644
index 00000000000..d1312e073a6
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -0,0 +1,337 @@
+/*
+ comedi/drivers/ni_670x.c
+ Hardware driver for NI 670x devices
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ni_670x
+Description: National Instruments 670x
+Author: Bart Joris <bjoris@advalvas.be>
+Updated: Wed, 11 Dec 2002 18:25:35 -0800
+Devices: [National Instruments] PCI-6703 (ni_670x), PCI-6704
+Status: unknown
+
+Commands are not supported.
+*/
+
+/*
+ Bart Joris <bjoris@advalvas.be> Last updated on 20/08/2001
+
+ Manuals:
+
+ 322110a.pdf PCI/PXI-6704 User Manual
+ 322110b.pdf PCI/PXI-6703/6704 User Manual
+
+*/
+
+#include "../comedidev.h"
+
+#include "mite.h"
+
+#define PCI_VENDOR_ID_NATINST 0x1093
+
+#define AO_VALUE_OFFSET 0x00
+#define AO_CHAN_OFFSET 0x0c
+#define AO_STATUS_OFFSET 0x10
+#define AO_CONTROL_OFFSET 0x10
+#define DIO_PORT0_DIR_OFFSET 0x20
+#define DIO_PORT0_DATA_OFFSET 0x24
+#define DIO_PORT1_DIR_OFFSET 0x28
+#define DIO_PORT1_DATA_OFFSET 0x2c
+#define MISC_STATUS_OFFSET 0x14
+#define MISC_CONTROL_OFFSET 0x14
+
+/* Board description*/
+
+struct ni_670x_board {
+ unsigned short dev_id;
+ const char *name;
+ unsigned short ao_chans;
+ unsigned short ao_bits;
+};
+
+static const struct ni_670x_board ni_670x_boards[] = {
+ {
+ dev_id: 0x2c90,
+ name: "PCI-6703",
+ ao_chans:16,
+ ao_bits: 16,
+ },
+ {
+ dev_id: 0x1920,
+ name: "PXI-6704",
+ ao_chans:32,
+ ao_bits: 16,
+ },
+ {
+ dev_id: 0x1290,
+ name: "PCI-6704",
+ ao_chans:32,
+ ao_bits: 16,
+ },
+};
+
+static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x2c90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ //{ PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_670x_pci_table);
+
+#define thisboard ((struct ni_670x_board *)dev->board_ptr)
+
+struct ni_670x_private {
+
+ struct mite_struct *mite;
+ int boardtype;
+ int dio;
+ unsigned int ao_readback[32];
+};
+
+
+#define devpriv ((struct ni_670x_private *)dev->private)
+#define n_ni_670x_boards (sizeof(ni_670x_boards)/sizeof(ni_670x_boards[0]))
+
+static int ni_670x_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni_670x_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_ni_670x = {
+ driver_name:"ni_670x",
+ module:THIS_MODULE,
+ attach:ni_670x_attach,
+ detach:ni_670x_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_ni_670x, ni_670x_pci_table);
+
+static struct comedi_lrange range_0_20mA = { 1, {RANGE_mA(0, 20)} };
+
+static int ni_670x_find_device(struct comedi_device * dev, int bus, int slot);
+
+static int ni_670x_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_670x_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_670x_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_670x_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int ni_670x_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret;
+ int i;
+
+ printk("comedi%d: ni_670x: ", dev->minor);
+
+ if ((ret = alloc_private(dev, sizeof(struct ni_670x_private))) < 0)
+ return ret;
+
+ ret = ni_670x_find_device(dev, it->options[0], it->options[1]);
+ if (ret < 0)
+ return ret;
+
+ ret = mite_setup(devpriv->mite);
+ if (ret < 0) {
+ printk("error setting up mite\n");
+ return ret;
+ }
+ dev->board_name = thisboard->name;
+ dev->irq = mite_irq(devpriv->mite);
+ printk(" %s", dev->board_name);
+
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->ao_chans;
+ s->maxdata = 0xffff;
+ if (s->n_chan == 32) {
+ const struct comedi_lrange **range_table_list;
+
+ range_table_list = kmalloc(sizeof(struct comedi_lrange *) * 32,
+ GFP_KERNEL);
+ if (!range_table_list)
+ return -ENOMEM;
+ s->range_table_list = range_table_list;
+ for (i = 0; i < 16; i++) {
+ range_table_list[i] = &range_bipolar10;
+ range_table_list[16 + i] = &range_0_20mA;
+ }
+ } else {
+ s->range_table = &range_bipolar10;
+ }
+ s->insn_write = &ni_670x_ao_winsn;
+ s->insn_read = &ni_670x_ao_rinsn;
+
+ s = dev->subdevices + 1;
+ /* digital i/o subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = ni_670x_dio_insn_bits;
+ s->insn_config = ni_670x_dio_insn_config;
+
+ writel(0x10, devpriv->mite->daq_io_addr + MISC_CONTROL_OFFSET); /* Config of misc registers */
+ writel(0x00, devpriv->mite->daq_io_addr + AO_CONTROL_OFFSET); /* Config of ao registers */
+
+ printk("attached\n");
+
+ return 1;
+}
+
+static int ni_670x_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: ni_670x: remove\n", dev->minor);
+
+ if (dev->subdevices[0].range_table_list) {
+ kfree(dev->subdevices[0].range_table_list);
+ }
+ if (dev->private && devpriv->mite)
+ mite_unsetup(devpriv->mite);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ return 0;
+}
+
+static int ni_670x_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ /* Channel number mapping :
+
+ NI 6703/ NI 6704 | NI 6704 Only
+ ----------------------------------------------------
+ vch(0) : 0 | ich(16) : 1
+ vch(1) : 2 | ich(17) : 3
+ . : . | . .
+ . : . | . .
+ . : . | . .
+ vch(15) : 30 | ich(31) : 31 */
+
+ for (i = 0; i < insn->n; i++) {
+ writel(((chan & 15) << 1) | ((chan & 16) >> 4), devpriv->mite->daq_io_addr + AO_CHAN_OFFSET); /* First write in channel register which channel to use */
+ writel(data[i], devpriv->mite->daq_io_addr + AO_VALUE_OFFSET); /* write channel value */
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ return i;
+}
+
+static int ni_670x_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+static int ni_670x_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ writel(s->state,
+ devpriv->mite->daq_io_addr + DIO_PORT0_DATA_OFFSET);
+ }
+
+ /* on return, data[1] contains the value of the digital
+ * input lines. */
+ data[1] = readl(devpriv->mite->daq_io_addr + DIO_PORT0_DATA_OFFSET);
+
+ return 2;
+}
+
+static int ni_670x_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= 1 << chan;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~(1 << chan);
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->
+ io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ writel(s->io_bits, devpriv->mite->daq_io_addr + DIO_PORT0_DIR_OFFSET);
+
+ return insn->n;
+}
+
+static int ni_670x_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number
+ || slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+
+ for (i = 0; i < n_ni_670x_boards; i++) {
+ if (mite_device_id(mite) == ni_670x_boards[i].dev_id) {
+ dev->board_ptr = ni_670x_boards + i;
+ devpriv->mite = mite;
+
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
new file mode 100644
index 00000000000..5d45bf24a5e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -0,0 +1,909 @@
+/*
+ comedi/drivers/ni_at_a2150.c
+ Driver for National Instruments AT-A2150 boards
+ Copyright (C) 2001, 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: ni_at_a2150
+Description: National Instruments AT-A2150
+Author: Frank Mori Hess
+Status: works
+Devices: [National Instruments] AT-A2150C (at_a2150c), AT-2150S (at_a2150s)
+
+If you want to ac couple the board's inputs, use AREF_OTHER.
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ (optional, required for timed conversions)
+ [2] - DMA (optional, required for timed conversions)
+
+*/
+/*
+Yet another driver for obsolete hardware brought to you by Frank Hess.
+Testing and debugging help provided by Dave Andruczyk.
+
+This driver supports the boards:
+
+AT-A2150C
+AT-A2150S
+
+The only difference is their master clock frequencies.
+
+Options:
+ [0] - base io address
+ [1] - irq
+ [2] - dma channel
+
+References (from ftp://ftp.natinst.com/support/manuals):
+
+ 320360.pdf AT-A2150 User Manual
+
+TODO:
+
+analog level triggering
+TRIG_WAKE_EOS
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+#include "comedi_fc.h"
+
+#define A2150_SIZE 28
+#define A2150_DMA_BUFFER_SIZE 0xff00 // size in bytes of dma buffer
+
+//#define A2150_DEBUG // enable debugging code
+#undef A2150_DEBUG // disable debugging code
+
+/* Registers and bits */
+#define CONFIG_REG 0x0
+#define CHANNEL_BITS(x) ((x) & 0x7)
+#define CHANNEL_MASK 0x7
+#define CLOCK_SELECT_BITS(x) (((x) & 0x3) << 3)
+#define CLOCK_DIVISOR_BITS(x) (((x) & 0x3) << 5)
+#define CLOCK_MASK (0xf << 3)
+#define ENABLE0_BIT 0x80 // enable (don't internally ground) channels 0 and 1
+#define ENABLE1_BIT 0x100 // enable (don't internally ground) channels 2 and 3
+#define AC0_BIT 0x200 // ac couple channels 0,1
+#define AC1_BIT 0x400 // ac couple channels 2,3
+#define APD_BIT 0x800 // analog power down
+#define DPD_BIT 0x1000 // digital power down
+#define TRIGGER_REG 0x2 // trigger config register
+#define POST_TRIGGER_BITS 0x2
+#define DELAY_TRIGGER_BITS 0x3
+#define HW_TRIG_EN 0x10 // enable hardware trigger
+#define FIFO_START_REG 0x6 // software start aquistion trigger
+#define FIFO_RESET_REG 0x8 // clears fifo + fifo flags
+#define FIFO_DATA_REG 0xa // read data
+#define DMA_TC_CLEAR_REG 0xe // clear dma terminal count interrupt
+#define STATUS_REG 0x12 // read only
+#define FNE_BIT 0x1 // fifo not empty
+#define OVFL_BIT 0x8 // fifo overflow
+#define EDAQ_BIT 0x10 // end of aquisition interrupt
+#define DCAL_BIT 0x20 // offset calibration in progress
+#define INTR_BIT 0x40 // interrupt has occured
+#define DMA_TC_BIT 0x80 // dma terminal count interrupt has occured
+#define ID_BITS(x) (((x) >> 8) & 0x3)
+#define IRQ_DMA_CNTRL_REG 0x12 // write only
+#define DMA_CHAN_BITS(x) ((x) & 0x7) // sets dma channel
+#define DMA_EN_BIT 0x8 // enables dma
+#define IRQ_LVL_BITS(x) (((x) & 0xf) << 4) // sets irq level
+#define FIFO_INTR_EN_BIT 0x100 // enable fifo interrupts
+#define FIFO_INTR_FHF_BIT 0x200 // interrupt fifo half full
+#define DMA_INTR_EN_BIT 0x800 // enable interrupt on dma terminal count
+#define DMA_DEM_EN_BIT 0x1000 // enables demand mode dma
+#define I8253_BASE_REG 0x14
+#define I8253_MODE_REG 0x17
+#define HW_COUNT_DISABLE 0x30 // disable hardware counting of conversions
+
+struct a2150_board {
+ const char *name;
+ int clock[4]; // master clock periods, in nanoseconds
+ int num_clocks; // number of available master clock speeds
+ int ai_speed; // maximum conversion rate in nanoseconds
+};
+
+//analog input range
+static const struct comedi_lrange range_a2150 = {
+ 1,
+ {
+ RANGE(-2.828, 2.828),
+ }
+};
+
+// enum must match board indices
+enum { a2150_c, a2150_s };
+static const struct a2150_board a2150_boards[] = {
+ {
+ name: "at-a2150c",
+ clock: {31250, 22676, 20833, 19531},
+ num_clocks:4,
+ ai_speed:19531,
+ },
+ {
+ name: "at-a2150s",
+ clock: {62500, 50000, 41667, 0},
+ num_clocks:3,
+ ai_speed:41667,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct a2150_board *)dev->board_ptr)
+
+struct a2150_private {
+
+ volatile unsigned int count; /* number of data points left to be taken */
+ unsigned int dma; // dma channel
+ s16 *dma_buffer; // dma buffer
+ unsigned int dma_transfer_size; // size in bytes of dma transfers
+ int irq_dma_bits; // irq/dma register bits
+ int config_bits; // config register bits
+};
+
+
+#define devpriv ((struct a2150_private *)dev->private)
+
+static int a2150_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int a2150_detach(struct comedi_device * dev);
+static int a2150_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static struct comedi_driver driver_a2150 = {
+ driver_name:"ni_at_a2150",
+ module:THIS_MODULE,
+ attach:a2150_attach,
+ detach:a2150_detach,
+};
+
+static irqreturn_t a2150_interrupt(int irq, void *d PT_REGS_ARG);
+static int a2150_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int a2150_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int a2150_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int a2150_get_timing(struct comedi_device * dev, unsigned int *period,
+ int flags);
+static int a2150_probe(struct comedi_device * dev);
+static int a2150_set_chanlist(struct comedi_device * dev, unsigned int start_channel,
+ unsigned int num_channels);
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_a2150);
+
+#ifdef A2150_DEBUG
+
+static void ni_dump_regs(struct comedi_device * dev)
+{
+ rt_printk("config bits 0x%x\n", devpriv->config_bits);
+ rt_printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits);
+ rt_printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG));
+}
+
+#endif
+
+/* interrupt service routine */
+static irqreturn_t a2150_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ int i;
+ int status;
+ unsigned long flags;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async;
+ struct comedi_cmd *cmd;
+ unsigned int max_points, num_points, residue, leftover;
+ short dpnt;
+ static const int sample_size = sizeof(devpriv->dma_buffer[0]);
+
+ if (dev->attached == 0) {
+ comedi_error(dev, "premature interrupt");
+ return IRQ_HANDLED;
+ }
+ // initialize async here to make sure s is not NULL
+ async = s->async;
+ async->events = 0;
+ cmd = &async->cmd;
+
+ status = inw(dev->iobase + STATUS_REG);
+
+ if ((status & INTR_BIT) == 0) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_NONE;
+ }
+
+ if (status & OVFL_BIT) {
+ comedi_error(dev, "fifo overflow");
+ a2150_cancel(dev, s);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ }
+
+ if ((status & DMA_TC_BIT) == 0) {
+ comedi_error(dev, "caught non-dma interrupt? Aborting.");
+ a2150_cancel(dev, s);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ flags = claim_dma_lock();
+ disable_dma(devpriv->dma);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma);
+
+ // figure out how many points to read
+ max_points = devpriv->dma_transfer_size / sample_size;
+ /* residue is the number of points left to be done on the dma
+ * transfer. It should always be zero at this point unless
+ * the stop_src is set to external triggering.
+ */
+ residue = get_dma_residue(devpriv->dma) / sample_size;
+ num_points = max_points - residue;
+ if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
+ num_points = devpriv->count;
+
+ // figure out how many points will be stored next time
+ leftover = 0;
+ if (cmd->stop_src == TRIG_NONE) {
+ leftover = devpriv->dma_transfer_size / sample_size;
+ } else if (devpriv->count > max_points) {
+ leftover = devpriv->count - max_points;
+ if (leftover > max_points)
+ leftover = max_points;
+ }
+ /* there should only be a residue if collection was stopped by having
+ * the stop_src set to an external trigger, in which case there
+ * will be no more data
+ */
+ if (residue)
+ leftover = 0;
+
+ for (i = 0; i < num_points; i++) {
+ /* write data point to comedi buffer */
+ dpnt = devpriv->dma_buffer[i];
+ // convert from 2's complement to unsigned coding
+ dpnt ^= 0x8000;
+ cfc_write_to_buffer(s, dpnt);
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (--devpriv->count == 0) { /* end of acquisition */
+ a2150_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA;
+ break;
+ }
+ }
+ }
+ // re-enable dma
+ if (leftover) {
+ set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
+ set_dma_count(devpriv->dma, leftover * sample_size);
+ enable_dma(devpriv->dma);
+ }
+ release_dma_lock(flags);
+
+ async->events |= COMEDI_CB_BLOCK;
+
+ comedi_event(dev, s);
+
+ /* clear interrupt */
+ outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
+
+ return IRQ_HANDLED;
+}
+
+// probes board type, returns offset
+static int a2150_probe(struct comedi_device * dev)
+{
+ int status = inw(dev->iobase + STATUS_REG);
+ return ID_BITS(status);
+}
+
+static int a2150_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = it->options[0];
+ unsigned int irq = it->options[1];
+ unsigned int dma = it->options[2];
+ static const int timeout = 2000;
+ int i;
+
+ printk("comedi%d: %s: io 0x%lx", dev->minor, driver_a2150.driver_name,
+ iobase);
+ if (irq) {
+ printk(", irq %u", irq);
+ } else {
+ printk(", no irq");
+ }
+ if (dma) {
+ printk(", dma %u", dma);
+ } else {
+ printk(", no dma");
+ }
+ printk("\n");
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(struct a2150_private)) < 0)
+ return -ENOMEM;
+
+ if (iobase == 0) {
+ printk(" io base address required\n");
+ return -EINVAL;
+ }
+
+ /* check if io addresses are available */
+ if (!request_region(iobase, A2150_SIZE, driver_a2150.driver_name)) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* grab our IRQ */
+ if (irq) {
+ // check that irq is supported
+ if (irq < 3 || irq == 8 || irq == 13 || irq > 15) {
+ printk(" invalid irq line %u\n", irq);
+ return -EINVAL;
+ }
+ if (comedi_request_irq(irq, a2150_interrupt, 0,
+ driver_a2150.driver_name, dev)) {
+ printk("unable to allocate irq %u\n", irq);
+ return -EINVAL;
+ }
+ devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq);
+ dev->irq = irq;
+ }
+ // initialize dma
+ if (dma) {
+ if (dma == 4 || dma > 7) {
+ printk(" invalid dma channel %u\n", dma);
+ return -EINVAL;
+ }
+ if (request_dma(dma, driver_a2150.driver_name)) {
+ printk(" failed to allocate dma channel %u\n", dma);
+ return -EINVAL;
+ }
+ devpriv->dma = dma;
+ devpriv->dma_buffer =
+ kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
+ if (devpriv->dma_buffer == NULL)
+ return -ENOMEM;
+
+ disable_dma(dma);
+ set_dma_mode(dma, DMA_MODE_READ);
+
+ devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma);
+ }
+
+ dev->board_ptr = a2150_boards + a2150_probe(dev);
+ dev->board_name = thisboard->name;
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+
+ /* analog input subdevice */
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ;
+ s->n_chan = 4;
+ s->len_chanlist = 4;
+ s->maxdata = 0xffff;
+ s->range_table = &range_a2150;
+ s->do_cmd = a2150_ai_cmd;
+ s->do_cmdtest = a2150_ai_cmdtest;
+ s->insn_read = a2150_ai_rinsn;
+ s->cancel = a2150_cancel;
+
+ /* need to do this for software counting of completed conversions, to
+ * prevent hardware count from stopping aquisition */
+ outw(HW_COUNT_DISABLE, dev->iobase + I8253_MODE_REG);
+
+ // set card's irq and dma levels
+ outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
+
+ // reset and sync adc clock circuitry
+ outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG);
+ outw_p(DPD_BIT, dev->iobase + CONFIG_REG);
+ // initialize configuration register
+ devpriv->config_bits = 0;
+ outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
+ // wait until offset calibration is done, then enable analog inputs
+ for (i = 0; i < timeout; i++) {
+ if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0)
+ break;
+ comedi_udelay(1000);
+ }
+ if (i == timeout) {
+ printk(" timed out waiting for offset calibration to complete\n");
+ return -ETIME;
+ }
+ devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
+ outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
+
+ return 0;
+};
+
+static int a2150_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: %s: remove\n", dev->minor, driver_a2150.driver_name);
+
+ /* only free stuff if it has been allocated by _attach */
+ if (dev->iobase) {
+ // put board in power-down mode
+ outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
+ release_region(dev->iobase, A2150_SIZE);
+ }
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (devpriv) {
+ if (devpriv->dma)
+ free_dma(devpriv->dma);
+ if (devpriv->dma_buffer)
+ kfree(devpriv->dma_buffer);
+ }
+
+ return 0;
+};
+
+static int a2150_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ // disable dma on card
+ devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
+ outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
+
+ // disable computer's dma
+ disable_dma(devpriv->dma);
+
+ // clear fifo and reset triggering circuitry
+ outw(0, dev->iobase + FIFO_RESET_REG);
+
+ return 0;
+}
+
+static int a2150_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int startChan;
+ int i;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ // check channel/gain list against card's limitations
+ if (cmd->chanlist) {
+ startChan = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) {
+ comedi_error(dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ err++;
+ }
+ }
+ if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) {
+ comedi_error(dev,
+ "length 2 chanlist must be channels 0,1 or channels 2,3");
+ err++;
+ }
+ if (cmd->chanlist_len == 3) {
+ comedi_error(dev,
+ "chanlist must have 1,2 or 4 channels");
+ err++;
+ }
+ if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) ||
+ CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3]))
+ {
+ comedi_error(dev,
+ "channels 0/1 and 2/3 must have the same analog reference");
+ err++;
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int a2150_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned long lock_flags;
+ unsigned int old_config_bits = devpriv->config_bits;
+ unsigned int trigger_bits;
+
+ if (!dev->irq || !devpriv->dma) {
+ comedi_error(dev,
+ " irq and dma required, cannot do hardware conversions");
+ return -1;
+ }
+ if (cmd->flags & TRIG_RT) {
+ comedi_error(dev,
+ " dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
+ return -1;
+ }
+ // clear fifo and reset triggering circuitry
+ outw(0, dev->iobase + FIFO_RESET_REG);
+
+ /* setup chanlist */
+ if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
+ cmd->chanlist_len) < 0)
+ return -1;
+
+ // setup ac/dc coupling
+ if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
+ devpriv->config_bits |= AC0_BIT;
+ else
+ devpriv->config_bits &= ~AC0_BIT;
+ if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER)
+ devpriv->config_bits |= AC1_BIT;
+ else
+ devpriv->config_bits &= ~AC1_BIT;
+
+ // setup timing
+ a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
+
+ // send timing, channel, config bits
+ outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
+
+ // initialize number of samples remaining
+ devpriv->count = cmd->stop_arg * cmd->chanlist_len;
+
+ // enable computer's dma
+ lock_flags = claim_dma_lock();
+ disable_dma(devpriv->dma);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma);
+ set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
+ // set size of transfer to fill in 1/3 second
+#define ONE_THIRD_SECOND 333333333
+ devpriv->dma_transfer_size =
+ sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len *
+ ONE_THIRD_SECOND / cmd->scan_begin_arg;
+ if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE)
+ devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE;
+ if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0]))
+ devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]);
+ devpriv->dma_transfer_size -=
+ devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]);
+ set_dma_count(devpriv->dma, devpriv->dma_transfer_size);
+ enable_dma(devpriv->dma);
+ release_dma_lock(lock_flags);
+
+ /* clear dma interrupt before enabling it, to try and get rid of that
+ * one spurious interrupt that has been happening */
+ outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
+
+ // enable dma on card
+ devpriv->irq_dma_bits |= DMA_INTR_EN_BIT | DMA_EN_BIT;
+ outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
+
+ // may need to wait 72 sampling periods if timing was changed
+ i8254_load(dev->iobase + I8253_BASE_REG, 0, 2, 72, 0);
+
+ // setup start triggering
+ trigger_bits = 0;
+ // decide if we need to wait 72 periods for valid data
+ if (cmd->start_src == TRIG_NOW &&
+ (old_config_bits & CLOCK_MASK) !=
+ (devpriv->config_bits & CLOCK_MASK)) {
+ // set trigger source to delay trigger
+ trigger_bits |= DELAY_TRIGGER_BITS;
+ } else {
+ // otherwise no delay
+ trigger_bits |= POST_TRIGGER_BITS;
+ }
+ // enable external hardware trigger
+ if (cmd->start_src == TRIG_EXT) {
+ trigger_bits |= HW_TRIG_EN;
+ } else if (cmd->start_src == TRIG_OTHER) {
+ // XXX add support for level/slope start trigger using TRIG_OTHER
+ comedi_error(dev, "you shouldn't see this?");
+ }
+ // send trigger config bits
+ outw(trigger_bits, dev->iobase + TRIGGER_REG);
+
+ // start aquisition for soft trigger
+ if (cmd->start_src == TRIG_NOW) {
+ outw(0, dev->iobase + FIFO_START_REG);
+ }
+#ifdef A2150_DEBUG
+ ni_dump_regs(dev);
+#endif
+
+ return 0;
+}
+
+static int a2150_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int i, n;
+ static const int timeout = 100000;
+ static const int filter_delay = 36;
+
+ // clear fifo and reset triggering circuitry
+ outw(0, dev->iobase + FIFO_RESET_REG);
+
+ /* setup chanlist */
+ if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0)
+ return -1;
+
+ // set dc coupling
+ devpriv->config_bits &= ~AC0_BIT;
+ devpriv->config_bits &= ~AC1_BIT;
+
+ // send timing, channel, config bits
+ outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
+
+ // disable dma on card
+ devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
+ outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
+
+ // setup start triggering
+ outw(0, dev->iobase + TRIGGER_REG);
+
+ // start aquisition for soft trigger
+ outw(0, dev->iobase + FIFO_START_REG);
+
+ /* there is a 35.6 sample delay for data to get through the antialias filter */
+ for (n = 0; n < filter_delay; n++) {
+ for (i = 0; i < timeout; i++) {
+ if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
+ break;
+ comedi_udelay(1);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timeout");
+ return -ETIME;
+ }
+ inw(dev->iobase + FIFO_DATA_REG);
+ }
+
+ // read data
+ for (n = 0; n < insn->n; n++) {
+ for (i = 0; i < timeout; i++) {
+ if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
+ break;
+ comedi_udelay(1);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timeout");
+ return -ETIME;
+ }
+#ifdef A2150_DEBUG
+ ni_dump_regs(dev);
+#endif
+ data[n] = inw(dev->iobase + FIFO_DATA_REG);
+#ifdef A2150_DEBUG
+ rt_printk(" data is %i\n", data[n]);
+#endif
+ data[n] ^= 0x8000;
+ }
+
+ // clear fifo and reset triggering circuitry
+ outw(0, dev->iobase + FIFO_RESET_REG);
+
+ return n;
+}
+
+/* sets bits in devpriv->clock_bits to nearest approximation of requested period,
+ * adjusts requested period to actual timing. */
+static int a2150_get_timing(struct comedi_device * dev, unsigned int *period,
+ int flags)
+{
+ int lub, glb, temp;
+ int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
+ int i, j;
+
+ // initialize greatest lower and least upper bounds
+ lub_divisor_shift = 3;
+ lub_index = 0;
+ lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
+ glb_divisor_shift = 0;
+ glb_index = thisboard->num_clocks - 1;
+ glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
+
+ // make sure period is in available range
+ if (*period < glb)
+ *period = glb;
+ if (*period > lub)
+ *period = lub;
+
+ // we can multiply period by 1, 2, 4, or 8, using (1 << i)
+ for (i = 0; i < 4; i++) {
+ // there are a maximum of 4 master clocks
+ for (j = 0; j < thisboard->num_clocks; j++) {
+ // temp is the period in nanosec we are evaluating
+ temp = thisboard->clock[j] * (1 << i);
+ // if it is the best match yet
+ if (temp < lub && temp >= *period) {
+ lub_divisor_shift = i;
+ lub_index = j;
+ lub = temp;
+ }
+ if (temp > glb && temp <= *period) {
+ glb_divisor_shift = i;
+ glb_index = j;
+ glb = temp;
+ }
+ }
+ }
+ flags &= TRIG_ROUND_MASK;
+ switch (flags) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ // if least upper bound is better approximation
+ if (lub - *period < *period - glb) {
+ *period = lub;
+ } else {
+ *period = glb;
+ }
+ break;
+ case TRIG_ROUND_UP:
+ *period = lub;
+ break;
+ case TRIG_ROUND_DOWN:
+ *period = glb;
+ break;
+ }
+
+ // set clock bits for config register appropriately
+ devpriv->config_bits &= ~CLOCK_MASK;
+ if (*period == lub) {
+ devpriv->config_bits |=
+ CLOCK_SELECT_BITS(lub_index) |
+ CLOCK_DIVISOR_BITS(lub_divisor_shift);
+ } else {
+ devpriv->config_bits |=
+ CLOCK_SELECT_BITS(glb_index) |
+ CLOCK_DIVISOR_BITS(glb_divisor_shift);
+ }
+
+ return 0;
+}
+
+static int a2150_set_chanlist(struct comedi_device * dev, unsigned int start_channel,
+ unsigned int num_channels)
+{
+ if (start_channel + num_channels > 4)
+ return -1;
+
+ devpriv->config_bits &= ~CHANNEL_MASK;
+
+ switch (num_channels) {
+ case 1:
+ devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
+ break;
+ case 2:
+ if (start_channel == 0) {
+ devpriv->config_bits |= CHANNEL_BITS(0x2);
+ } else if (start_channel == 2) {
+ devpriv->config_bits |= CHANNEL_BITS(0x3);
+ } else {
+ return -1;
+ }
+ break;
+ case 4:
+ devpriv->config_bits |= CHANNEL_BITS(0x1);
+ break;
+ default:
+ return -1;
+ break;
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c
new file mode 100644
index 00000000000..2cc46b67258
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_at_ao.c
@@ -0,0 +1,454 @@
+/*
+ comedi/drivers/ni_at_ao.c
+ Driver for NI AT-AO-6/10 boards
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000,2002 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ni_at_ao
+Description: National Instruments AT-AO-6/10
+Devices: [National Instruments] AT-AO-6 (at-ao-6), AT-AO-10 (at-ao-10)
+Status: should work
+Author: ds
+Updated: Sun Dec 26 12:26:28 EST 2004
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ (unused)
+ [2] - DMA (unused)
+ [3] - analog output range, set by jumpers on hardware (0 for -10 to 10V bipolar, 1 for 0V to 10V unipolar)
+
+*/
+/*
+ * Register-level programming information can be found in NI
+ * document 320379.pdf.
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+/* board egisters */
+/* registers with _2_ are accessed when GRP2WR is set in CFG1 */
+
+#define ATAO_SIZE 0x20
+
+#define ATAO_2_DMATCCLR 0x00 /* W 16 */
+#define ATAO_DIN 0x00 /* R 16 */
+#define ATAO_DOUT 0x00 /* W 16 */
+
+#define ATAO_CFG2 0x02 /* W 16 */
+#define CALLD1 0x8000
+#define CALLD0 0x4000
+#define FFRTEN 0x2000
+#define DAC2S8 0x1000
+#define DAC2S6 0x0800
+#define DAC2S4 0x0400
+#define DAC2S2 0x0200
+#define DAC2S0 0x0100
+#define LDAC8 0x0080
+#define LDAC6 0x0040
+#define LDAC4 0x0020
+#define LDAC2 0x0010
+#define LDAC0 0x0008
+#define PROMEN 0x0004
+#define SCLK 0x0002
+#define SDATA 0x0001
+
+#define ATAO_2_INT1CLR 0x02 /* W 16 */
+
+#define ATAO_CFG3 0x04 /* W 16 */
+#define DMAMODE 0x0040
+#define CLKOUT 0x0020
+#define RCLKEN 0x0010
+#define DOUTEN2 0x0008
+#define DOUTEN1 0x0004
+#define EN2_5V 0x0002
+#define SCANEN 0x0001
+
+#define ATAO_2_INT2CLR 0x04 /* W 16 */
+
+#define ATAO_82C53_BASE 0x06 /* RW 8 */
+
+#define ATAO_82C53_CNTR1 0x06 /* RW 8 */
+#define ATAO_82C53_CNTR2 0x07 /* RW 8 */
+#define ATAO_82C53_CNTR3 0x08 /* RW 8 */
+#define ATAO_82C53_CNTRCMD 0x09 /* W 8 */
+#define CNTRSEL1 0x80
+#define CNTRSEL0 0x40
+#define RWSEL1 0x20
+#define RWSEL0 0x10
+#define MODESEL2 0x08
+#define MODESEL1 0x04
+#define MODESEL0 0x02
+#define BCDSEL 0x01
+ /* read-back command */
+#define COUNT 0x20
+#define STATUS 0x10
+#define CNTR3 0x08
+#define CNTR2 0x04
+#define CNTR1 0x02
+ /* status */
+#define OUT 0x80
+#define _NULL 0x40
+#define RW1 0x20
+#define RW0 0x10
+#define MODE2 0x08
+#define MODE1 0x04
+#define MODE0 0x02
+#define BCD 0x01
+
+#define ATAO_2_RTSISHFT 0x06 /* W 8 */
+#define RSI 0x01
+
+#define ATAO_2_RTSISTRB 0x07 /* W 8 */
+
+#define ATAO_CFG1 0x0a /* W 16 */
+#define EXTINT2EN 0x8000
+#define EXTINT1EN 0x4000
+#define CNTINT2EN 0x2000
+#define CNTINT1EN 0x1000
+#define TCINTEN 0x0800
+#define CNT1SRC 0x0400
+#define CNT2SRC 0x0200
+#define FIFOEN 0x0100
+#define GRP2WR 0x0080
+#define EXTUPDEN 0x0040
+#define DMARQ 0x0020
+#define DMAEN 0x0010
+#define CH_mask 0x000f
+#define ATAO_STATUS 0x0a /* R 16 */
+#define FH 0x0040
+#define FE 0x0020
+#define FF 0x0010
+#define INT2 0x0008
+#define INT1 0x0004
+#define TCINT 0x0002
+#define PROMOUT 0x0001
+
+#define ATAO_FIFO_WRITE 0x0c /* W 16 */
+#define ATAO_FIFO_CLEAR 0x0c /* R 16 */
+#define ATAO_DACn(x) (0x0c + 2*(x)) /* W */
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct atao_board {
+ const char *name;
+ int n_ao_chans;
+};
+
+static const struct atao_board atao_boards[] = {
+ {
+ name: "ai-ao-6",
+ n_ao_chans:6,
+ },
+ {
+ name: "ai-ao-10",
+ n_ao_chans:10,
+ },
+};
+
+#define thisboard ((struct atao_board *)dev->board_ptr)
+
+struct atao_private {
+
+ unsigned short cfg1;
+ unsigned short cfg2;
+ unsigned short cfg3;
+
+ /* Used for AO readback */
+ unsigned int ao_readback[10];
+};
+
+#define devpriv ((struct atao_private *)dev->private)
+
+static int atao_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int atao_detach(struct comedi_device * dev);
+static struct comedi_driver driver_atao = {
+ driver_name:"ni_at_ao",
+ module:THIS_MODULE,
+ attach:atao_attach,
+ detach:atao_detach,
+ board_name:&atao_boards[0].name,
+ offset:sizeof(struct atao_board),
+ num_names:sizeof(atao_boards) / sizeof(struct atao_board),
+};
+
+COMEDI_INITCLEANUP(driver_atao);
+
+static void atao_reset(struct comedi_device * dev);
+
+static int atao_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int atao_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int atao_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int atao_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int atao_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int atao_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int atao_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+ int ao_unipolar;
+
+ iobase = it->options[0];
+ if (iobase == 0)
+ iobase = 0x1c0;
+ ao_unipolar = it->options[3];
+
+ printk("comedi%d: ni_at_ao: 0x%04lx", dev->minor, iobase);
+
+ if (!request_region(iobase, ATAO_SIZE, "ni_at_ao")) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ //dev->board_ptr = atao_probe(dev);
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_private(dev, sizeof(struct atao_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->n_ao_chans;
+ s->maxdata = (1 << 12) - 1;
+ if (ao_unipolar)
+ s->range_table = &range_unipolar10;
+ else
+ s->range_table = &range_bipolar10;
+ s->insn_write = &atao_ao_winsn;
+ s->insn_read = &atao_ao_rinsn;
+
+ s = dev->subdevices + 1;
+ /* digital i/o subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = atao_dio_insn_bits;
+ s->insn_config = atao_dio_insn_config;
+
+ s = dev->subdevices + 2;
+ /* caldac subdevice */
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 21;
+ s->maxdata = 0xff;
+ s->insn_read = atao_calib_insn_read;
+ s->insn_write = atao_calib_insn_write;
+
+ s = dev->subdevices + 3;
+ /* eeprom subdevice */
+ //s->type=COMEDI_SUBD_EEPROM;
+ s->type = COMEDI_SUBD_UNUSED;
+
+ atao_reset(dev);
+
+ printk("\n");
+
+ return 0;
+}
+
+static int atao_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: atao: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, ATAO_SIZE);
+
+ return 0;
+}
+
+static void atao_reset(struct comedi_device * dev)
+{
+ /* This is the reset sequence described in the manual */
+
+ devpriv->cfg1 = 0;
+ outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+
+ outb(RWSEL0 | MODESEL2, dev->iobase + ATAO_82C53_CNTRCMD);
+ outb(0x03, dev->iobase + ATAO_82C53_CNTR1);
+ outb(CNTRSEL0 | RWSEL0 | MODESEL2, dev->iobase + ATAO_82C53_CNTRCMD);
+
+ devpriv->cfg2 = 0;
+ outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
+
+ devpriv->cfg3 = 0;
+ outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
+
+ inw(dev->iobase + ATAO_FIFO_CLEAR);
+
+ devpriv->cfg1 |= GRP2WR;
+ outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+
+ outw(0, dev->iobase + ATAO_2_INT1CLR);
+ outw(0, dev->iobase + ATAO_2_INT2CLR);
+ outw(0, dev->iobase + ATAO_2_DMATCCLR);
+
+ devpriv->cfg1 &= ~GRP2WR;
+ outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+}
+
+static int atao_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ short bits;
+
+ for (i = 0; i < insn->n; i++) {
+ bits = data[i] - 0x800;
+ if (chan == 0) {
+ devpriv->cfg1 |= GRP2WR;
+ outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+ }
+ outw(bits, dev->iobase + ATAO_DACn(chan));
+ if (chan == 0) {
+ devpriv->cfg1 &= ~GRP2WR;
+ outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+ }
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ return i;
+}
+
+static int atao_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+static int atao_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ outw(s->state, dev->iobase + ATAO_DOUT);
+ }
+
+ data[1] = inw(dev->iobase + ATAO_DIN);
+
+ return 2;
+}
+
+static int atao_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned int mask, bit;
+
+ /* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+ mask = (chan < 4) ? 0x0f : 0xf0;
+ bit = (chan < 4) ? DOUTEN1 : DOUTEN2;
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= mask;
+ devpriv->cfg3 |= bit;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~mask;
+ devpriv->cfg3 &= ~bit;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->
+ io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
+
+ return 1;
+}
+
+/*
+ * Figure 2-1 in the manual shows 3 chips labeled DAC8800, which
+ * are 8-channel 8-bit DACs. These are most likely the calibration
+ * DACs. It is not explicitly stated in the manual how to access
+ * the caldacs, but we can guess.
+ */
+static int atao_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ for (i = 0; i < insn->n; i++) {
+ data[i] = 0; /* XXX */
+ }
+ return insn->n;
+}
+
+static int atao_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bitstring, bit;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+
+ bitstring = ((chan & 0x7) << 8) | (data[insn->n - 1] & 0xff);
+
+ for (bit = 1 << (11 - 1); bit; bit >>= 1) {
+ outw(devpriv->cfg2 | ((bit & bitstring) ? SDATA : 0),
+ dev->iobase + ATAO_CFG2);
+ outw(devpriv->cfg2 | SCLK | ((bit & bitstring) ? SDATA : 0),
+ dev->iobase + ATAO_CFG2);
+ }
+ /* strobe the appropriate caldac */
+ outw(devpriv->cfg2 | (((chan >> 3) + 1) << 14),
+ dev->iobase + ATAO_CFG2);
+ outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
+
+ return insn->n;
+}
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c
new file mode 100644
index 00000000000..fcc38535afc
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_atmio.c
@@ -0,0 +1,513 @@
+/*
+ comedi/drivers/ni_atmio.c
+ Hardware driver for NI AT-MIO E series cards
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: ni_atmio
+Description: National Instruments AT-MIO-E series
+Author: ds
+Devices: [National Instruments] AT-MIO-16E-1 (ni_atmio),
+ AT-MIO-16E-2, AT-MIO-16E-10, AT-MIO-16DE-10, AT-MIO-64E-3,
+ AT-MIO-16XE-50, AT-MIO-16XE-10, AT-AI-16XE-10
+Status: works
+Updated: Thu May 1 20:03:02 CDT 2003
+
+The driver has 2.6 kernel isapnp support, and
+will automatically probe for a supported board if the
+I/O base is left unspecified with comedi_config.
+However, many of
+the isapnp id numbers are unknown. If your board is not
+recognized, please send the output of 'cat /proc/isapnp'
+(you may need to modprobe the isa-pnp module for
+/proc/isapnp to exist) so the
+id numbers for your board can be added to the driver.
+
+Otherwise, you can use the isapnptools package to configure
+your board. Use isapnp to
+configure the I/O base and IRQ for the board, and then pass
+the same values as
+parameters in comedi_config. A sample isapnp.conf file is included
+in the etc/ directory of Comedilib.
+
+Comedilib includes a utility to autocalibrate these boards. The
+boards seem to boot into a state where the all calibration DACs
+are at one extreme of their range, thus the default calibration
+is terrible. Calibration at boot is strongly encouraged.
+
+To use the extended digital I/O on some of the boards, enable the
+8255 driver when configuring the Comedi source tree.
+
+External triggering is supported for some events. The channel index
+(scan_begin_arg, etc.) maps to PFI0 - PFI9.
+
+Some of the more esoteric triggering possibilities of these boards
+are not supported.
+*/
+/*
+ The real guts of the driver is in ni_mio_common.c, which is included
+ both here and in ni_pcimio.c
+
+ Interrupt support added by Truxton Fulton <trux@truxton.com>
+
+ References for specifications:
+
+ 340747b.pdf Register Level Programmer Manual (obsolete)
+ 340747c.pdf Register Level Programmer Manual (new)
+ DAQ-STC reference manual
+
+ Other possibly relevant info:
+
+ 320517c.pdf User manual (obsolete)
+ 320517f.pdf User manual (new)
+ 320889a.pdf delete
+ 320906c.pdf maximum signal ratings
+ 321066a.pdf about 16x
+ 321791a.pdf discontinuation of at-mio-16e-10 rev. c
+ 321808a.pdf about at-mio-16e-10 rev P
+ 321837a.pdf discontinuation of at-mio-16de-10 rev d
+ 321838a.pdf about at-mio-16de-10 rev N
+
+ ISSUES:
+
+ need to deal with external reference for DAC, and other DAC
+ properties in board properties
+
+ deal with at-mio-16de-10 revision D to N changes, etc.
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/isapnp.h>
+
+#include "ni_stc.h"
+#include "8255.h"
+
+#undef DEBUG
+
+#define ATMIO 1
+#undef PCIMIO
+
+/*
+ * AT specific setup
+ */
+
+#define NI_SIZE 0x20
+
+#define MAX_N_CALDACS 32
+
+static const ni_board ni_boards[] = {
+ {device_id:44,
+ isapnp_id:0x0000,/* XXX unknown */
+ name: "at-mio-16e-1",
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:8192,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:800,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ ao_unipolar:1,
+ ao_speed:1000,
+ has_8255:0,
+ .num_p0_dio_channels = 8,
+ caldac: {mb88341},
+ },
+ {device_id:25,
+ isapnp_id:0x1900,
+ name: "at-mio-16e-2",
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:2048,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:2000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ ao_unipolar:1,
+ ao_speed:1000,
+ has_8255:0,
+ .num_p0_dio_channels = 8,
+ caldac: {mb88341},
+ },
+ {device_id:36,
+ isapnp_id:0x2400,
+ name: "at-mio-16e-10",
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:512,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:10000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:0,
+ .ao_range_table = &range_ni_E_ao_ext,
+ ao_unipolar:1,
+ ao_speed:10000,
+ .num_p0_dio_channels = 8,
+ caldac: {ad8804_debug},
+ has_8255:0,
+ },
+ {device_id:37,
+ isapnp_id:0x2500,
+ name: "at-mio-16de-10",
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:512,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:10000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:0,
+ .ao_range_table = &range_ni_E_ao_ext,
+ ao_unipolar:1,
+ ao_speed:10000,
+ .num_p0_dio_channels = 8,
+ caldac: {ad8804_debug},
+ has_8255:1,
+ },
+ {device_id:38,
+ isapnp_id:0x2600,
+ name: "at-mio-64e-3",
+ n_adchan:64,
+ adbits: 12,
+ ai_fifo_depth:2048,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:2000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ ao_unipolar:1,
+ ao_speed:1000,
+ has_8255:0,
+ .num_p0_dio_channels = 8,
+ caldac: {ad8804_debug},
+ },
+ {device_id:39,
+ isapnp_id:0x2700,
+ name: "at-mio-16xe-50",
+ n_adchan:16,
+ adbits: 16,
+ ai_fifo_depth:512,
+ alwaysdither:1,
+ gainlkup:ai_gain_8,
+ ai_speed:50000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:0,
+ .ao_range_table = &range_bipolar10,
+ ao_unipolar:0,
+ ao_speed:50000,
+ .num_p0_dio_channels = 8,
+ caldac: {dac8800, dac8043},
+ has_8255:0,
+ },
+ {device_id:50,
+ isapnp_id:0x0000,/* XXX unknown */
+ name: "at-mio-16xe-10",
+ n_adchan:16,
+ adbits: 16,
+ ai_fifo_depth:512,
+ alwaysdither:1,
+ gainlkup:ai_gain_14,
+ ai_speed:10000,
+ n_aochan:2,
+ aobits: 16,
+ ao_fifo_depth:2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ ao_unipolar:1,
+ ao_speed:1000,
+ .num_p0_dio_channels = 8,
+ caldac: {dac8800, dac8043, ad8522},
+ has_8255:0,
+ },
+ {device_id:51,
+ isapnp_id:0x0000,/* XXX unknown */
+ name: "at-ai-16xe-10",
+ n_adchan:16,
+ adbits: 16,
+ ai_fifo_depth:512,
+ alwaysdither:1, /* unknown */
+ gainlkup:ai_gain_14,
+ ai_speed:10000,
+ n_aochan:0,
+ aobits: 0,
+ ao_fifo_depth:0,
+ ao_unipolar:0,
+ .num_p0_dio_channels = 8,
+ caldac: {dac8800, dac8043, ad8522},
+ has_8255:0,
+ }
+};
+
+static const int ni_irqpin[] =
+ { -1, -1, -1, 0, 1, 2, -1, 3, -1, -1, 4, 5, 6, -1, -1, 7 };
+
+#define interrupt_pin(a) (ni_irqpin[(a)])
+
+#define IRQ_POLARITY 0
+
+#define NI_E_IRQ_FLAGS 0
+
+typedef struct {
+ struct pnp_dev *isapnp_dev;
+ NI_PRIVATE_COMMON} ni_private;
+#define devpriv ((ni_private *)dev->private)
+
+/* How we access registers */
+
+#define ni_writel(a,b) (outl((a),(b)+dev->iobase))
+#define ni_readl(a) (inl((a)+dev->iobase))
+#define ni_writew(a,b) (outw((a),(b)+dev->iobase))
+#define ni_readw(a) (inw((a)+dev->iobase))
+#define ni_writeb(a,b) (outb((a),(b)+dev->iobase))
+#define ni_readb(a) (inb((a)+dev->iobase))
+
+/* How we access windowed registers */
+
+/* We automatically take advantage of STC registers that can be
+ * read/written directly in the I/O space of the board. The
+ * AT-MIO devices map the low 8 STC registers to iobase+addr*2. */
+
+static void ni_atmio_win_out(struct comedi_device * dev, uint16_t data, int addr)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ if ((addr) < 8) {
+ ni_writew(data, addr * 2);
+ } else {
+ ni_writew(addr, Window_Address);
+ ni_writew(data, Window_Data);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static uint16_t ni_atmio_win_in(struct comedi_device * dev, int addr)
+{
+ unsigned long flags;
+ uint16_t ret;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ if (addr < 8) {
+ ret = ni_readw(addr * 2);
+ } else {
+ ni_writew(addr, Window_Address);
+ ret = ni_readw(Window_Data);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+
+ return ret;
+}
+
+static struct pnp_device_id device_ids[] = {
+ {.id = "NIC1900",.driver_data = 0},
+ {.id = "NIC2400",.driver_data = 0},
+ {.id = "NIC2500",.driver_data = 0},
+ {.id = "NIC2600",.driver_data = 0},
+ {.id = "NIC2700",.driver_data = 0},
+ {.id = ""}
+};
+
+MODULE_DEVICE_TABLE(pnp, device_ids);
+
+static int ni_atmio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni_atmio_detach(struct comedi_device * dev);
+static struct comedi_driver driver_atmio = {
+ driver_name:"ni_atmio",
+ module:THIS_MODULE,
+ attach:ni_atmio_attach,
+ detach:ni_atmio_detach,
+};
+
+COMEDI_INITCLEANUP(driver_atmio);
+
+#include "ni_mio_common.c"
+
+static int ni_getboardtype(struct comedi_device * dev);
+
+/* clean up allocated resources */
+static int ni_atmio_detach(struct comedi_device * dev)
+{
+ mio_common_detach(dev);
+
+ if (dev->iobase)
+ release_region(dev->iobase, NI_SIZE);
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (devpriv->isapnp_dev)
+ pnp_device_detach(devpriv->isapnp_dev);
+
+ return 0;
+}
+
+static int ni_isapnp_find_board(struct pnp_dev **dev)
+{
+ struct pnp_dev *isapnp_dev = NULL;
+ int i;
+
+ for (i = 0; i < n_ni_boards; i++) {
+ isapnp_dev = pnp_find_dev(NULL,
+ ISAPNP_VENDOR('N', 'I', 'C'),
+ ISAPNP_FUNCTION(ni_boards[i].isapnp_id), NULL);
+
+ if (isapnp_dev == NULL || isapnp_dev->card == NULL)
+ continue;
+
+ if (pnp_device_attach(isapnp_dev) < 0) {
+ printk("ni_atmio: %s found but already active, skipping.\n", ni_boards[i].name);
+ continue;
+ }
+ if (pnp_activate_dev(isapnp_dev) < 0) {
+ pnp_device_detach(isapnp_dev);
+ return -EAGAIN;
+ }
+ if (!pnp_port_valid(isapnp_dev, 0)
+ || !pnp_irq_valid(isapnp_dev, 0)) {
+ pnp_device_detach(isapnp_dev);
+ printk("ni_atmio: pnp invalid port or irq, aborting\n");
+ return -ENOMEM;
+ }
+ break;
+ }
+ if (i == n_ni_boards)
+ return -ENODEV;
+ *dev = isapnp_dev;
+ return 0;
+}
+
+static int ni_atmio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pnp_dev *isapnp_dev;
+ int ret;
+ unsigned long iobase;
+ int board;
+ unsigned int irq;
+
+ /* allocate private area */
+ if ((ret = ni_alloc_private(dev)) < 0)
+ return ret;
+ devpriv->stc_writew = &ni_atmio_win_out;
+ devpriv->stc_readw = &ni_atmio_win_in;
+ devpriv->stc_writel = &win_out2;
+ devpriv->stc_readl = &win_in2;
+
+ iobase = it->options[0];
+ irq = it->options[1];
+ isapnp_dev = NULL;
+ if (iobase == 0) {
+ ret = ni_isapnp_find_board(&isapnp_dev);
+ if (ret < 0)
+ return ret;
+
+ iobase = pnp_port_start(isapnp_dev, 0);
+ irq = pnp_irq(isapnp_dev, 0);
+ devpriv->isapnp_dev = isapnp_dev;
+ }
+
+ /* reserve our I/O region */
+
+ printk("comedi%d: ni_atmio: 0x%04lx", dev->minor, iobase);
+ if (!request_region(iobase, NI_SIZE, "ni_atmio")) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+#ifdef DEBUG
+ /* board existence sanity check */
+ {
+ int i;
+
+ printk(" board fingerprint:");
+ for (i = 0; i < 16; i += 2) {
+ printk(" %04x %02x", inw(dev->iobase + i),
+ inb(dev->iobase + i + 1));
+ }
+ }
+#endif
+
+ /* get board type */
+
+ board = ni_getboardtype(dev);
+ if (board < 0)
+ return -EIO;
+
+ dev->board_ptr = ni_boards + board;
+
+ printk(" %s", boardtype.name);
+ dev->board_name = boardtype.name;
+
+ /* irq stuff */
+
+ if (irq != 0) {
+ if (irq > 15 || ni_irqpin[irq] == -1) {
+ printk(" invalid irq %u\n", irq);
+ return -EINVAL;
+ }
+ printk(" ( irq = %u )", irq);
+ if ((ret = comedi_request_irq(irq, ni_E_interrupt,
+ NI_E_IRQ_FLAGS, "ni_atmio", dev)) < 0) {
+ printk(" irq not available\n");
+ return -EINVAL;
+ }
+ dev->irq = irq;
+ }
+
+ /* generic E series stuff in ni_mio_common.c */
+
+ if ((ret = ni_E_init(dev, it)) < 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ni_getboardtype(struct comedi_device * dev)
+{
+ int device_id = ni_read_eeprom(dev, 511);
+ int i;
+
+ for (i = 0; i < n_ni_boards; i++) {
+ if (ni_boards[i].device_id == device_id) {
+ return i;
+ }
+ }
+ if (device_id == 255) {
+ printk(" can't find board\n");
+ } else if (device_id == 0) {
+ printk(" EEPROM read error (?) or device not found\n");
+ } else {
+ printk(" unknown device ID %d -- contact author\n", device_id);
+ }
+ return -1;
+}
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c
new file mode 100644
index 00000000000..35fcd172af2
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_atmio16d.c
@@ -0,0 +1,860 @@
+/*
+ comedi/drivers/ni_atmio16d.c
+ Hardware driver for National Instruments AT-MIO16D board
+ Copyright (C) 2000 Chris R. Baugher <baugher@enteract.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.
+
+ */
+/*
+Driver: ni_atmio16d
+Description: National Instruments AT-MIO-16D
+Author: Chris R. Baugher <baugher@enteract.com>
+Status: unknown
+Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d)
+*/
+/*
+ * I must give credit here to Michal Dobes <dobes@tesnet.cz> who
+ * wrote the driver for Advantec's pcl812 boards. I used the interrupt
+ * handling code from his driver as an example for this one.
+ *
+ * Chris Baugher
+ * 5/1/2000
+ *
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#include "8255.h"
+
+/* Configuration and Status Registers */
+#define COM_REG_1 0x00 /* wo 16 */
+#define STAT_REG 0x00 /* ro 16 */
+#define COM_REG_2 0x02 /* wo 16 */
+/* Event Strobe Registers */
+#define START_CONVERT_REG 0x08 /* wo 16 */
+#define START_DAQ_REG 0x0A /* wo 16 */
+#define AD_CLEAR_REG 0x0C /* wo 16 */
+#define EXT_STROBE_REG 0x0E /* wo 16 */
+/* Analog Output Registers */
+#define DAC0_REG 0x10 /* wo 16 */
+#define DAC1_REG 0x12 /* wo 16 */
+#define INT2CLR_REG 0x14 /* wo 16 */
+/* Analog Input Registers */
+#define MUX_CNTR_REG 0x04 /* wo 16 */
+#define MUX_GAIN_REG 0x06 /* wo 16 */
+#define AD_FIFO_REG 0x16 /* ro 16 */
+#define DMA_TC_INT_CLR_REG 0x16 /* wo 16 */
+/* AM9513A Counter/Timer Registers */
+#define AM9513A_DATA_REG 0x18 /* rw 16 */
+#define AM9513A_COM_REG 0x1A /* wo 16 */
+#define AM9513A_STAT_REG 0x1A /* ro 16 */
+/* MIO-16 Digital I/O Registers */
+#define MIO_16_DIG_IN_REG 0x1C /* ro 16 */
+#define MIO_16_DIG_OUT_REG 0x1C /* wo 16 */
+/* RTSI Switch Registers */
+#define RTSI_SW_SHIFT_REG 0x1E /* wo 8 */
+#define RTSI_SW_STROBE_REG 0x1F /* wo 8 */
+/* DIO-24 Registers */
+#define DIO_24_PORTA_REG 0x00 /* rw 8 */
+#define DIO_24_PORTB_REG 0x01 /* rw 8 */
+#define DIO_24_PORTC_REG 0x02 /* rw 8 */
+#define DIO_24_CNFG_REG 0x03 /* wo 8 */
+
+/* Command Register bits */
+#define COMREG1_2SCADC 0x0001
+#define COMREG1_1632CNT 0x0002
+#define COMREG1_SCANEN 0x0008
+#define COMREG1_DAQEN 0x0010
+#define COMREG1_DMAEN 0x0020
+#define COMREG1_CONVINTEN 0x0080
+#define COMREG2_SCN2 0x0010
+#define COMREG2_INTEN 0x0080
+#define COMREG2_DOUTEN0 0x0100
+#define COMREG2_DOUTEN1 0x0200
+/* Status Register bits */
+#define STAT_AD_OVERRUN 0x0100
+#define STAT_AD_OVERFLOW 0x0200
+#define STAT_AD_DAQPROG 0x0800
+#define STAT_AD_CONVAVAIL 0x2000
+#define STAT_AD_DAQSTOPINT 0x4000
+/* AM9513A Counter/Timer defines */
+#define CLOCK_1_MHZ 0x8B25
+#define CLOCK_100_KHZ 0x8C25
+#define CLOCK_10_KHZ 0x8D25
+#define CLOCK_1_KHZ 0x8E25
+#define CLOCK_100_HZ 0x8F25
+/* Other miscellaneous defines */
+#define ATMIO16D_SIZE 32 /* bus address range */
+#define devpriv ((struct atmio16d_private *)dev->private)
+#define ATMIO16D_TIMEOUT 10
+
+struct atmio16_board_t {
+
+ const char *name;
+ int has_8255;
+};
+
+static const struct atmio16_board_t atmio16_boards[] = {
+ {
+ name: "atmio16",
+ has_8255:0,
+ },
+ {
+ name: "atmio16d",
+ has_8255:1,
+ },
+};
+
+#define n_atmio16_boards sizeof(atmio16_boards)/sizeof(atmio16_boards[0])
+
+#define boardtype ((const struct atmio16_board_t *)dev->board_ptr)
+
+/* function prototypes */
+static int atmio16d_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int atmio16d_detach(struct comedi_device * dev);
+static irqreturn_t atmio16d_interrupt(int irq, void *d PT_REGS_ARG);
+static int atmio16d_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int atmio16d_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int atmio16d_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void reset_counters(struct comedi_device * dev);
+static void reset_atmio16d(struct comedi_device * dev);
+
+/* main driver struct */
+static struct comedi_driver driver_atmio16d = {
+ driver_name:"atmio16",
+ module:THIS_MODULE,
+ attach:atmio16d_attach,
+ detach:atmio16d_detach,
+ board_name:&atmio16_boards[0].name,
+ num_names:n_atmio16_boards,
+ offset:sizeof(struct atmio16_board_t),
+};
+
+COMEDI_INITCLEANUP(driver_atmio16d);
+
+/* range structs */
+static const struct comedi_lrange range_atmio16d_ai_10_bipolar = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.02)
+ }
+};
+
+static const struct comedi_lrange range_atmio16d_ai_5_bipolar = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.01)
+ }
+};
+
+static const struct comedi_lrange range_atmio16d_ai_unipolar = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.02)
+ }
+};
+
+/* private data struct */
+struct atmio16d_private {
+ enum { adc_diff, adc_singleended } adc_mux;
+ enum { adc_bipolar10, adc_bipolar5, adc_unipolar10 } adc_range;
+ enum { adc_2comp, adc_straight } adc_coding;
+ enum { dac_bipolar, dac_unipolar } dac0_range, dac1_range;
+ enum { dac_internal, dac_external } dac0_reference, dac1_reference;
+ enum { dac_2comp, dac_straight } dac0_coding, dac1_coding;
+ const struct comedi_lrange *ao_range_type_list[2];
+ unsigned int ao_readback[2];
+ unsigned int com_reg_1_state; /* current state of command register 1 */
+ unsigned int com_reg_2_state; /* current state of command register 2 */
+};
+
+static void reset_counters(struct comedi_device * dev)
+{
+ /* Counter 2 */
+ outw(0xFFC2, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF02, dev->iobase + AM9513A_COM_REG);
+ outw(0x4, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0A, dev->iobase + AM9513A_COM_REG);
+ outw(0x3, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF42, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF42, dev->iobase + AM9513A_COM_REG);
+ /* Counter 3 */
+ outw(0xFFC4, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF03, dev->iobase + AM9513A_COM_REG);
+ outw(0x4, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0B, dev->iobase + AM9513A_COM_REG);
+ outw(0x3, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF44, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF44, dev->iobase + AM9513A_COM_REG);
+ /* Counter 4 */
+ outw(0xFFC8, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF04, dev->iobase + AM9513A_COM_REG);
+ outw(0x4, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0C, dev->iobase + AM9513A_COM_REG);
+ outw(0x3, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF48, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF48, dev->iobase + AM9513A_COM_REG);
+ /* Counter 5 */
+ outw(0xFFD0, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF05, dev->iobase + AM9513A_COM_REG);
+ outw(0x4, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0D, dev->iobase + AM9513A_COM_REG);
+ outw(0x3, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF50, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF50, dev->iobase + AM9513A_COM_REG);
+
+ outw(0, dev->iobase + AD_CLEAR_REG);
+}
+
+static void reset_atmio16d(struct comedi_device * dev)
+{
+ int i;
+
+ /* now we need to initialize the board */
+ outw(0, dev->iobase + COM_REG_1);
+ outw(0, dev->iobase + COM_REG_2);
+ outw(0, dev->iobase + MUX_GAIN_REG);
+ /* init AM9513A timer */
+ outw(0xFFFF, dev->iobase + AM9513A_COM_REG);
+ outw(0xFFEF, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF17, dev->iobase + AM9513A_COM_REG);
+ outw(0xF000, dev->iobase + AM9513A_DATA_REG);
+ for (i = 1; i <= 5; ++i) {
+ outw(0xFF00 + i, dev->iobase + AM9513A_COM_REG);
+ outw(0x0004, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF08 + i, dev->iobase + AM9513A_COM_REG);
+ outw(0x3, dev->iobase + AM9513A_DATA_REG);
+ }
+ outw(0xFF5F, dev->iobase + AM9513A_COM_REG);
+ /* timer init done */
+ outw(0, dev->iobase + AD_CLEAR_REG);
+ outw(0, dev->iobase + INT2CLR_REG);
+ /* select straight binary mode for Analog Input */
+ devpriv->com_reg_1_state |= 1;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ devpriv->adc_coding = adc_straight;
+ /* zero the analog outputs */
+ outw(2048, dev->iobase + DAC0_REG);
+ outw(2048, dev->iobase + DAC1_REG);
+}
+
+static irqreturn_t atmio16d_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+
+// printk("atmio16d_interrupt!\n");
+
+ comedi_buf_put(s->async, inw(dev->iobase + AD_FIFO_REG));
+
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+static int atmio16d_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0, tmp;
+#ifdef DEBUG1
+ printk("atmio16d_ai_cmdtest\n");
+#endif
+ /* make sure triggers are valid */
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->scan_begin_src != TRIG_EXT &&
+ cmd->scan_begin_src != TRIG_TIMER)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ /* internal trigger */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ } else {
+#if 0
+ /* external trigger */
+ /* should be level/edge, hi/lo specification here */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+#endif
+ }
+
+ if (cmd->convert_arg < 10000) {
+ cmd->convert_arg = 10000;
+ err++;
+ }
+#if 0
+ if (cmd->convert_arg > SLOWEST_TIMER) {
+ cmd->convert_arg = SLOWEST_TIMER;
+ err++;
+ }
+#endif
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ /* any count is allowed */
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ return 0;
+}
+
+static int atmio16d_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int timer, base_clock;
+ unsigned int sample_count, tmp, chan, gain;
+ int i;
+#ifdef DEBUG1
+ printk("atmio16d_ai_cmd\n");
+#endif
+ /* This is slowly becoming a working command interface. *
+ * It is still uber-experimental */
+
+ reset_counters(dev);
+ s->async->cur_chan = 0;
+
+ /* check if scanning multiple channels */
+ if (cmd->chanlist_len < 2) {
+ devpriv->com_reg_1_state &= ~COMREG1_SCANEN;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ } else {
+ devpriv->com_reg_1_state |= COMREG1_SCANEN;
+ devpriv->com_reg_2_state |= COMREG2_SCN2;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ outw(devpriv->com_reg_2_state, dev->iobase + COM_REG_2);
+ }
+
+ /* Setup the Mux-Gain Counter */
+ for (i = 0; i < cmd->chanlist_len; ++i) {
+ chan = CR_CHAN(cmd->chanlist[i]);
+ gain = CR_RANGE(cmd->chanlist[i]);
+ outw(i, dev->iobase + MUX_CNTR_REG);
+ tmp = chan | (gain << 6);
+ if (i == cmd->scan_end_arg - 1)
+ tmp |= 0x0010; /* set LASTONE bit */
+ outw(tmp, dev->iobase + MUX_GAIN_REG);
+ }
+
+ /* Now program the sample interval timer */
+ /* Figure out which clock to use then get an
+ * appropriate timer value */
+ if (cmd->convert_arg < 65536000) {
+ base_clock = CLOCK_1_MHZ;
+ timer = cmd->convert_arg / 1000;
+ } else if (cmd->convert_arg < 655360000) {
+ base_clock = CLOCK_100_KHZ;
+ timer = cmd->convert_arg / 10000;
+ } else if (cmd->convert_arg <= 0xffffffff /* 6553600000 */ ) {
+ base_clock = CLOCK_10_KHZ;
+ timer = cmd->convert_arg / 100000;
+ } else if (cmd->convert_arg <= 0xffffffff /* 65536000000 */ ) {
+ base_clock = CLOCK_1_KHZ;
+ timer = cmd->convert_arg / 1000000;
+ }
+ outw(0xFF03, dev->iobase + AM9513A_COM_REG);
+ outw(base_clock, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0B, dev->iobase + AM9513A_COM_REG);
+ outw(0x2, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF44, dev->iobase + AM9513A_COM_REG);
+ outw(0xFFF3, dev->iobase + AM9513A_COM_REG);
+ outw(timer, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF24, dev->iobase + AM9513A_COM_REG);
+
+ /* Now figure out how many samples to get */
+ /* and program the sample counter */
+ sample_count = cmd->stop_arg * cmd->scan_end_arg;
+ outw(0xFF04, dev->iobase + AM9513A_COM_REG);
+ outw(0x1025, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0C, dev->iobase + AM9513A_COM_REG);
+ if (sample_count < 65536) {
+ /* use only Counter 4 */
+ outw(sample_count, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF48, dev->iobase + AM9513A_COM_REG);
+ outw(0xFFF4, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF28, dev->iobase + AM9513A_COM_REG);
+ devpriv->com_reg_1_state &= ~COMREG1_1632CNT;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ } else {
+ /* Counter 4 and 5 are needed */
+ if ((tmp = sample_count & 0xFFFF)) {
+ outw(tmp - 1, dev->iobase + AM9513A_DATA_REG);
+ } else {
+ outw(0xFFFF, dev->iobase + AM9513A_DATA_REG);
+ }
+ outw(0xFF48, dev->iobase + AM9513A_COM_REG);
+ outw(0, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF28, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF05, dev->iobase + AM9513A_COM_REG);
+ outw(0x25, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0D, dev->iobase + AM9513A_COM_REG);
+ tmp = sample_count & 0xFFFF;
+ if ((tmp == 0) || (tmp == 1)) {
+ outw((sample_count >> 16) & 0xFFFF,
+ dev->iobase + AM9513A_DATA_REG);
+ } else {
+ outw(((sample_count >> 16) & 0xFFFF) + 1,
+ dev->iobase + AM9513A_DATA_REG);
+ }
+ outw(0xFF70, dev->iobase + AM9513A_COM_REG);
+ devpriv->com_reg_1_state |= COMREG1_1632CNT;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ }
+
+ /* Program the scan interval timer ONLY IF SCANNING IS ENABLED */
+ /* Figure out which clock to use then get an
+ * appropriate timer value */
+ if (cmd->chanlist_len > 1) {
+ if (cmd->scan_begin_arg < 65536000) {
+ base_clock = CLOCK_1_MHZ;
+ timer = cmd->scan_begin_arg / 1000;
+ } else if (cmd->scan_begin_arg < 655360000) {
+ base_clock = CLOCK_100_KHZ;
+ timer = cmd->scan_begin_arg / 10000;
+ } else if (cmd->scan_begin_arg < 0xffffffff /* 6553600000 */ ) {
+ base_clock = CLOCK_10_KHZ;
+ timer = cmd->scan_begin_arg / 100000;
+ } else if (cmd->scan_begin_arg < 0xffffffff /* 65536000000 */ ) {
+ base_clock = CLOCK_1_KHZ;
+ timer = cmd->scan_begin_arg / 1000000;
+ }
+ outw(0xFF02, dev->iobase + AM9513A_COM_REG);
+ outw(base_clock, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0A, dev->iobase + AM9513A_COM_REG);
+ outw(0x2, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF42, dev->iobase + AM9513A_COM_REG);
+ outw(0xFFF2, dev->iobase + AM9513A_COM_REG);
+ outw(timer, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF22, dev->iobase + AM9513A_COM_REG);
+ }
+
+ /* Clear the A/D FIFO and reset the MUX counter */
+ outw(0, dev->iobase + AD_CLEAR_REG);
+ outw(0, dev->iobase + MUX_CNTR_REG);
+ outw(0, dev->iobase + INT2CLR_REG);
+ /* enable this acquisition operation */
+ devpriv->com_reg_1_state |= COMREG1_DAQEN;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ /* enable interrupts for conversion completion */
+ devpriv->com_reg_1_state |= COMREG1_CONVINTEN;
+ devpriv->com_reg_2_state |= COMREG2_INTEN;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ outw(devpriv->com_reg_2_state, dev->iobase + COM_REG_2);
+ /* apply a trigger. this starts the counters! */
+ outw(0, dev->iobase + START_DAQ_REG);
+
+ return 0;
+}
+
+/* This will cancel a running acquisition operation */
+static int atmio16d_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ reset_atmio16d(dev);
+
+ return 0;
+}
+
+/* Mode 0 is used to get a single conversion on demand */
+static int atmio16d_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, t;
+ int chan;
+ int gain;
+ int status;
+
+#ifdef DEBUG1
+ printk("atmio16d_ai_insn_read\n");
+#endif
+ chan = CR_CHAN(insn->chanspec);
+ gain = CR_RANGE(insn->chanspec);
+
+ /* reset the Analog input circuitry */
+ //outw( 0, dev->iobase+AD_CLEAR_REG );
+ /* reset the Analog Input MUX Counter to 0 */
+ //outw( 0, dev->iobase+MUX_CNTR_REG );
+
+ /* set the Input MUX gain */
+ outw(chan | (gain << 6), dev->iobase + MUX_GAIN_REG);
+
+ for (i = 0; i < insn->n; i++) {
+ /* start the conversion */
+ outw(0, dev->iobase + START_CONVERT_REG);
+ /* wait for it to finish */
+ for (t = 0; t < ATMIO16D_TIMEOUT; t++) {
+ /* check conversion status */
+ status = inw(dev->iobase + STAT_REG);
+#ifdef DEBUG1
+ printk("status=%x\n", status);
+#endif
+ if (status & STAT_AD_CONVAVAIL) {
+ /* read the data now */
+ data[i] = inw(dev->iobase + AD_FIFO_REG);
+ /* change to two's complement if need be */
+ if (devpriv->adc_coding == adc_2comp) {
+ data[i] ^= 0x800;
+ }
+ break;
+ }
+ if (status & STAT_AD_OVERFLOW) {
+ printk("atmio16d: a/d FIFO overflow\n");
+ outw(0, dev->iobase + AD_CLEAR_REG);
+
+ return -ETIME;
+ }
+ }
+ /* end waiting, now check if it timed out */
+ if (t == ATMIO16D_TIMEOUT) {
+ rt_printk("atmio16d: timeout\n");
+
+ return -ETIME;
+ }
+ }
+
+ return i;
+}
+
+static int atmio16d_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+#ifdef DEBUG1
+ printk("atmio16d_ao_insn_read\n");
+#endif
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
+ }
+
+ return i;
+}
+
+static int atmio16d_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan;
+ int d;
+#ifdef DEBUG1
+ printk("atmio16d_ao_insn_write\n");
+#endif
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ d = data[i];
+ switch (chan) {
+ case 0:
+ if (devpriv->dac0_coding == dac_2comp) {
+ d ^= 0x800;
+ }
+ outw(d, dev->iobase + DAC0_REG);
+ break;
+ case 1:
+ if (devpriv->dac1_coding == dac_2comp) {
+ d ^= 0x800;
+ }
+ outw(d, dev->iobase + DAC1_REG);
+ break;
+ default:
+ return -EINVAL;
+ }
+ devpriv->ao_readback[chan] = data[i];
+ }
+ return i;
+}
+
+static int atmio16d_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] | data[1]);
+ outw(s->state, dev->iobase + MIO_16_DIG_OUT_REG);
+ }
+ data[1] = inw(dev->iobase + MIO_16_DIG_IN_REG);
+
+ return 2;
+}
+
+static int atmio16d_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int mask;
+
+ for (i = 0; i < insn->n; i++) {
+ mask = (CR_CHAN(insn->chanspec) < 4) ? 0x0f : 0xf0;
+ s->io_bits &= ~mask;
+ if (data[i])
+ s->io_bits |= mask;
+ }
+ devpriv->com_reg_2_state &= ~(COMREG2_DOUTEN0 | COMREG2_DOUTEN1);
+ if (s->io_bits & 0x0f)
+ devpriv->com_reg_2_state |= COMREG2_DOUTEN0;
+ if (s->io_bits & 0xf0)
+ devpriv->com_reg_2_state |= COMREG2_DOUTEN1;
+ outw(devpriv->com_reg_2_state, dev->iobase + COM_REG_2);
+
+ return i;
+}
+
+/*
+ options[0] - I/O port
+ options[1] - MIO irq
+ 0 == no irq
+ N == irq N {3,4,5,6,7,9,10,11,12,14,15}
+ options[2] - DIO irq
+ 0 == no irq
+ N == irq N {3,4,5,6,7,9}
+ options[3] - DMA1 channel
+ 0 == no DMA
+ N == DMA N {5,6,7}
+ options[4] - DMA2 channel
+ 0 == no DMA
+ N == DMA N {5,6,7}
+
+ options[5] - a/d mux
+ 0=differential, 1=single
+ options[6] - a/d range
+ 0=bipolar10, 1=bipolar5, 2=unipolar10
+
+ options[7] - dac0 range
+ 0=bipolar, 1=unipolar
+ options[8] - dac0 reference
+ 0=internal, 1=external
+ options[9] - dac0 coding
+ 0=2's comp, 1=straight binary
+
+ options[10] - dac1 range
+ options[11] - dac1 reference
+ options[12] - dac1 coding
+ */
+
+static int atmio16d_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned int irq;
+ unsigned long iobase;
+ int ret;
+
+ struct comedi_subdevice *s;
+
+ /* make sure the address range is free and allocate it */
+ iobase = it->options[0];
+ printk("comedi%d: atmio16d: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, ATMIO16D_SIZE, "ni_atmio16d")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* board name */
+ dev->board_name = boardtype->name;
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct atmio16d_private))) < 0)
+ return ret;
+
+ /* reset the atmio16d hardware */
+ reset_atmio16d(dev);
+
+ /* check if our interrupt is available and get it */
+ irq = it->options[1];
+ if (irq) {
+ if ((ret = comedi_request_irq(irq, atmio16d_interrupt,
+ 0, "atmio16d", dev)) < 0) {
+ printk("failed to allocate irq %u\n", irq);
+ return ret;
+ }
+ dev->irq = irq;
+ printk("( irq = %u )\n", irq);
+ } else {
+ printk("( no irq )");
+ }
+
+ /* set device options */
+ devpriv->adc_mux = it->options[5];
+ devpriv->adc_range = it->options[6];
+
+ devpriv->dac0_range = it->options[7];
+ devpriv->dac0_reference = it->options[8];
+ devpriv->dac0_coding = it->options[9];
+ devpriv->dac1_range = it->options[10];
+ devpriv->dac1_reference = it->options[11];
+ devpriv->dac1_coding = it->options[12];
+
+ /* setup sub-devices */
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
+ s->n_chan = (devpriv->adc_mux ? 16 : 8);
+ s->len_chanlist = 16;
+ s->insn_read = atmio16d_ai_insn_read;
+ s->do_cmdtest = atmio16d_ai_cmdtest;
+ s->do_cmd = atmio16d_ai_cmd;
+ s->cancel = atmio16d_ai_cancel;
+ s->maxdata = 0xfff; /* 4095 decimal */
+ switch (devpriv->adc_range) {
+ case adc_bipolar10:
+ s->range_table = &range_atmio16d_ai_10_bipolar;
+ break;
+ case adc_bipolar5:
+ s->range_table = &range_atmio16d_ai_5_bipolar;
+ break;
+ case adc_unipolar10:
+ s->range_table = &range_atmio16d_ai_unipolar;
+ break;
+ }
+
+ /* ao subdevice */
+ s++;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->insn_read = atmio16d_ao_insn_read;
+ s->insn_write = atmio16d_ao_insn_write;
+ s->maxdata = 0xfff; /* 4095 decimal */
+ s->range_table_list = devpriv->ao_range_type_list;
+ switch (devpriv->dac0_range) {
+ case dac_bipolar:
+ devpriv->ao_range_type_list[0] = &range_bipolar10;
+ break;
+ case dac_unipolar:
+ devpriv->ao_range_type_list[0] = &range_unipolar10;
+ break;
+ }
+ switch (devpriv->dac1_range) {
+ case dac_bipolar:
+ devpriv->ao_range_type_list[1] = &range_bipolar10;
+ break;
+ case dac_unipolar:
+ devpriv->ao_range_type_list[1] = &range_unipolar10;
+ break;
+ }
+
+ /* Digital I/O */
+ s++;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 8;
+ s->insn_bits = atmio16d_dio_insn_bits;
+ s->insn_config = atmio16d_dio_insn_config;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+
+ /* 8255 subdevice */
+ s++;
+ if (boardtype->has_8255) {
+ subdev_8255_init(dev, s, NULL, dev->iobase);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+/* don't yet know how to deal with counter/timers */
+#if 0
+ s++;
+ /* do */
+ s->type = COMEDI_SUBD_TIMER;
+ s->n_chan = 0;
+ s->maxdata = 0
+#endif
+ printk("\n");
+
+ return 0;
+}
+
+static int atmio16d_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: atmio16d: remove\n", dev->minor);
+
+ if (dev->subdevices && boardtype->has_8255)
+ subdev_8255_cleanup(dev, dev->subdevices + 3);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ reset_atmio16d(dev);
+
+ if (dev->iobase)
+ release_region(dev->iobase, ATMIO16D_SIZE);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
new file mode 100644
index 00000000000..61a31ad2d03
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -0,0 +1,841 @@
+/*
+ * comedi/drivers/ni_daq_700.c
+ * Driver for DAQCard-700 DIO only
+ * copied from 8255
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+Driver: ni_daq_700
+Description: National Instruments PCMCIA DAQCard-700 DIO only
+Author: Fred Brooks <nsaspook@nsaspook.com>,
+ based on ni_daq_dio24 by Daniel Vecino Castel <dvecino@able.es>
+Devices: [National Instruments] PCMCIA DAQ-Card-700 (ni_daq_700)
+Status: works
+Updated: Thu, 21 Feb 2008 12:07:20 +0000
+
+The daqcard-700 appears in Comedi as a single digital I/O subdevice with
+16 channels. The channel 0 corresponds to the daqcard-700's output
+port, bit 0; channel 8 corresponds to the input port, bit 0.
+
+Direction configuration: channels 0-7 output, 8-15 input (8225 device
+emu as port A output, port B input, port C N/A).
+
+IRQ is assigned but not used.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+static struct pcmcia_device *pcmcia_cur_dev = NULL;
+
+#define DIO700_SIZE 8 // size of io region used by board
+
+static int dio700_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dio700_detach(struct comedi_device * dev);
+
+enum dio700_bustype { pcmcia_bustype };
+
+struct dio700_board {
+ const char *name;
+ int device_id; // device id for pcmcia board
+ enum dio700_bustype bustype; // PCMCIA
+ int have_dio; // have daqcard-700 dio
+ // function pointers so we can use inb/outb or readb/writeb
+ // as appropriate
+ unsigned int (*read_byte) (unsigned int address);
+ void (*write_byte) (unsigned int byte, unsigned int address);
+};
+
+static const struct dio700_board dio700_boards[] = {
+ {
+ name: "daqcard-700",
+ device_id:0x4743,// 0x10b is manufacturer id, 0x4743 is device id
+ bustype: pcmcia_bustype,
+ have_dio:1,
+ },
+ {
+ name: "ni_daq_700",
+ device_id:0x4743,// 0x10b is manufacturer id, 0x4743 is device id
+ bustype: pcmcia_bustype,
+ have_dio:1,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct dio700_board *)dev->board_ptr)
+
+struct dio700_private {
+
+ int data; /* number of data points left to be taken */
+};
+
+
+#define devpriv ((struct dio700_private *)dev->private)
+
+static struct comedi_driver driver_dio700 = {
+ driver_name:"ni_daq_700",
+ module:THIS_MODULE,
+ attach:dio700_attach,
+ detach:dio700_detach,
+ num_names:sizeof(dio700_boards) / sizeof(struct dio700_board),
+ board_name:&dio700_boards[0].name,
+ offset:sizeof(struct dio700_board),
+};
+
+/* the real driver routines */
+
+#define _700_SIZE 8
+
+#define _700_DATA 0
+
+#define DIO_W 0x04
+#define DIO_R 0x05
+
+struct subdev_700_struct {
+ unsigned long cb_arg;
+ int (*cb_func) (int, int, int, unsigned long);
+ int have_irq;
+};
+
+#define CALLBACK_ARG (((struct subdev_700_struct *)s->private)->cb_arg)
+#define CALLBACK_FUNC (((struct subdev_700_struct *)s->private)->cb_func)
+#define subdevpriv ((struct subdev_700_struct *)s->private)
+
+static void do_config(struct comedi_device * dev, struct comedi_subdevice * s);
+
+void subdev_700_interrupt(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ short d;
+
+ d = CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG);
+
+ comedi_buf_put(s->async, d);
+ s->async->events |= COMEDI_CB_EOS;
+
+ comedi_event(dev, s);
+}
+
+static int subdev_700_cb(int dir, int port, int data, unsigned long arg)
+{
+ /* port is always A for output and B for input (8255 emu) */
+ unsigned long iobase = arg;
+
+ if (dir) {
+ outb(data, iobase + DIO_W);
+ return 0;
+ } else {
+ return inb(iobase + DIO_R);
+ }
+}
+
+static int subdev_700_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+
+ if (data[0] & 0xff)
+ CALLBACK_FUNC(1, _700_DATA, s->state & 0xff,
+ CALLBACK_ARG);
+ }
+
+ data[1] = s->state & 0xff;
+ data[1] |= CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG) << 8;
+
+ return 2;
+}
+
+static int subdev_700_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_INPUT:
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->io_bits & (1 << CR_CHAN(insn->
+ chanspec))) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 1;
+}
+
+static void do_config(struct comedi_device * dev, struct comedi_subdevice * s)
+{ /* use powerup defaults */
+ return;
+}
+
+static int subdev_700_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* step 1 */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_FOLLOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2 */
+
+ if (err)
+ return 2;
+
+ /* step 3 */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ if (cmd->scan_end_arg != 1) {
+ cmd->scan_end_arg = 1;
+ err++;
+ }
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4 */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int subdev_700_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ /* FIXME */
+
+ return 0;
+}
+
+static int subdev_700_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ /* FIXME */
+
+ return 0;
+}
+
+int subdev_700_init(struct comedi_device * dev, struct comedi_subdevice * s, int (*cb) (int,
+ int, int, unsigned long), unsigned long arg)
+{
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 16;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+
+ s->private = kmalloc(sizeof(struct subdev_700_struct), GFP_KERNEL);
+ if (!s->private)
+ return -ENOMEM;
+
+ CALLBACK_ARG = arg;
+ if (cb == NULL) {
+ CALLBACK_FUNC = subdev_700_cb;
+ } else {
+ CALLBACK_FUNC = cb;
+ }
+ s->insn_bits = subdev_700_insn;
+ s->insn_config = subdev_700_insn_config;
+
+ s->state = 0;
+ s->io_bits = 0x00ff;
+ do_config(dev, s);
+
+ return 0;
+}
+
+int subdev_700_init_irq(struct comedi_device * dev, struct comedi_subdevice * s,
+ int (*cb) (int, int, int, unsigned long), unsigned long arg)
+{
+ int ret;
+
+ ret = subdev_700_init(dev, s, cb, arg);
+ if (ret < 0)
+ return ret;
+
+ s->do_cmdtest = subdev_700_cmdtest;
+ s->do_cmd = subdev_700_cmd;
+ s->cancel = subdev_700_cancel;
+
+ subdevpriv->have_irq = 1;
+
+ return 0;
+}
+
+void subdev_700_cleanup(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (s->private) {
+ if (subdevpriv->have_irq) {
+ }
+
+ kfree(s->private);
+ }
+}
+
+EXPORT_SYMBOL(subdev_700_init);
+EXPORT_SYMBOL(subdev_700_init_irq);
+EXPORT_SYMBOL(subdev_700_cleanup);
+EXPORT_SYMBOL(subdev_700_interrupt);
+
+static int dio700_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = 0;
+#ifdef incomplete
+ unsigned int irq = 0;
+#endif
+ struct pcmcia_device *link;
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(struct dio700_private)) < 0)
+ return -ENOMEM;
+
+ // get base address, irq etc. based on bustype
+ switch (thisboard->bustype) {
+ case pcmcia_bustype:
+ link = pcmcia_cur_dev; /* XXX hack */
+ if (!link)
+ return -EIO;
+ iobase = link->io.BasePort1;
+#ifdef incomplete
+ irq = link->irq.AssignedIRQ;
+#endif
+ break;
+ default:
+ printk("bug! couldn't determine board type\n");
+ return -EINVAL;
+ break;
+ }
+ printk("comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor,
+ thisboard->name, iobase);
+#ifdef incomplete
+ if (irq) {
+ printk(", irq %u", irq);
+ }
+#endif
+
+ printk("\n");
+
+ if (iobase == 0) {
+ printk("io base address is zero!\n");
+ return -EINVAL;
+ }
+
+ dev->iobase = iobase;
+
+#ifdef incomplete
+ /* grab our IRQ */
+ dev->irq = irq;
+#endif
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+
+ /* DAQCard-700 dio */
+ s = dev->subdevices + 0;
+ subdev_700_init(dev, s, NULL, dev->iobase);
+
+ return 0;
+};
+
+static int dio700_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: ni_daq_700: cs-remove\n", dev->minor);
+
+ if (dev->subdevices)
+ subdev_700_cleanup(dev, dev->subdevices + 0);
+
+ if (thisboard->bustype != pcmcia_bustype && dev->iobase)
+ release_region(dev->iobase, DIO700_SIZE);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ return 0;
+};
+
+// PCMCIA crap
+
+/*
+ All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
+ you do not define PCMCIA_DEBUG at all, all the debug code will be
+ left out. If you compile with PCMCIA_DEBUG=0, the debug code will
+ be present but disabled -- but it can then be enabled for specific
+ modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version = "ni_daq_700.c, based on dummy_cs.c";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+static void dio700_config(struct pcmcia_device *link);
+static void dio700_release(struct pcmcia_device *link);
+static int dio700_cs_suspend(struct pcmcia_device *p_dev);
+static int dio700_cs_resume(struct pcmcia_device *p_dev);
+
+/*
+ The attach() and detach() entry points are used to create and destroy
+ "instances" of the driver, where each instance represents everything
+ needed to manage one actual PCMCIA card.
+*/
+
+static int dio700_cs_attach(struct pcmcia_device *);
+static void dio700_cs_detach(struct pcmcia_device *);
+
+/*
+ You'll also need to prototype all the functions that will actually
+ be used to talk to your device. See 'memory_cs' for a good example
+ of a fully self-sufficient driver; the other drivers rely more or
+ less on other parts of the kernel.
+*/
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static const dev_info_t dev_info = "ni_daq_700";
+
+struct local_info_t {
+ struct pcmcia_device *link;
+ dev_node_t node;
+ int stop;
+ struct bus_operations *bus;
+};
+
+/*======================================================================
+
+ dio700_cs_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+
+ The dev_link structure is initialized, but we don't actually
+ configure the card at this point -- we wait until we receive a
+ card insertion event.
+
+======================================================================*/
+
+static int dio700_cs_attach(struct pcmcia_device *link)
+{
+ struct local_info_t *local;
+
+ printk(KERN_INFO "ni_daq_700: cs-attach\n");
+
+ DEBUG(0, "dio700_cs_attach()\n");
+
+ /* Allocate space for private device-specific data */
+ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
+ if (!local)
+ return -ENOMEM;
+ local->link = link;
+ link->priv = local;
+
+ /* Interrupt setup */
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = NULL;
+
+ /*
+ General socket configuration defaults can go here. In this
+ client, we assume very little, and rely on the CIS for almost
+ everything. In most clients, many details (i.e., number, sizes,
+ and attributes of IO windows) are fixed by the nature of the
+ device, and can be hard-wired here.
+ */
+ link->conf.Attributes = 0;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ pcmcia_cur_dev = link;
+
+ dio700_config(link);
+
+ return 0;
+} /* dio700_cs_attach */
+
+/*======================================================================
+
+ This deletes a driver "instance". The device is de-registered
+ with Card Services. If it has been released, all local data
+ structures are freed. Otherwise, the structures will be freed
+ when the device is released.
+
+======================================================================*/
+
+static void dio700_cs_detach(struct pcmcia_device *link)
+{
+
+ printk(KERN_INFO "ni_daq_700: cs-detach!\n");
+
+ DEBUG(0, "dio700_cs_detach(0x%p)\n", link);
+
+ if (link->dev_node) {
+ ((struct local_info_t *) link->priv)->stop = 1;
+ dio700_release(link);
+ }
+
+ /* This points to the parent struct local_info_t struct */
+ if (link->priv)
+ kfree(link->priv);
+
+} /* dio700_cs_detach */
+
+/*======================================================================
+
+ dio700_config() is scheduled to run after a CARD_INSERTION event
+ is received, to configure the PCMCIA socket, and to make the
+ device available to the system.
+
+======================================================================*/
+
+static void dio700_config(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+ tuple_t tuple;
+ cisparse_t parse;
+ int last_ret;
+ u_char buf[64];
+ win_req_t req;
+ memreq_t map;
+ cistpl_cftable_entry_t dflt = { 0 };
+
+ printk(KERN_INFO "ni_daq_700: cs-config\n");
+
+ DEBUG(0, "dio700_config(0x%p)\n", link);
+
+ /*
+ This reads the card's CONFIG tuple to find its configuration
+ registers.
+ */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) {
+ cs_error(link, GetTupleData, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) {
+ cs_error(link, ParseTuple, last_ret);
+ goto cs_failed;
+ }
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+ /*
+ In this loop, we scan the CIS for configuration table entries,
+ each of which describes a valid card configuration, including
+ voltage, IO window, memory window, and interrupt settings.
+
+ We make no assumptions about the card to be configured: we use
+ just the information available in the CIS. In an ideal world,
+ this would work for any PCMCIA card, but it requires a complete
+ and accurate CIS. In practice, a driver usually "knows" most of
+ these things without consulting the CIS, and most client drivers
+ will only use the CIS to fill in implementation-defined details.
+ */
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ while (1) {
+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ if (pcmcia_get_tuple_data(link, &tuple) != 0)
+ goto next_entry;
+ if (pcmcia_parse_tuple(&tuple, &parse) != 0)
+ goto next_entry;
+
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ if (cfg->index == 0)
+ goto next_entry;
+ link->conf.ConfigIndex = cfg->index;
+
+ /* Does this card need audio output? */
+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ link->conf.Attributes |= CONF_ENABLE_SPKR;
+ link->conf.Status = CCSR_AUDIO_ENA;
+ }
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(link, &link->io) != 0)
+ goto next_entry;
+ }
+
+ if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
+ cistpl_mem_t *mem =
+ (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
+ req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+ req.Attributes |= WIN_ENABLE;
+ req.Base = mem->win[0].host_addr;
+ req.Size = mem->win[0].len;
+ if (req.Size < 0x1000)
+ req.Size = 0x1000;
+ req.AccessSpeed = 0;
+ if (pcmcia_request_window(&link, &req, &link->win))
+ goto next_entry;
+ map.Page = 0;
+ map.CardOffset = mem->win[0].card_addr;
+ if (pcmcia_map_mem_page(link->win, &map))
+ goto next_entry;
+ }
+ /* If we got this far, we're cool! */
+ break;
+
+ next_entry:
+ if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) {
+ cs_error(link, GetNextTuple, last_ret);
+ goto cs_failed;
+ }
+ }
+
+ /*
+ 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 ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) {
+ cs_error(link, RequestIRQ, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping, and putting the
+ card and host interface into "Memory and IO" mode.
+ */
+ if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) {
+ cs_error(link, RequestConfiguration, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ At this point, the dev_node_t structure(s) need to be
+ initialized and arranged in a linked list at link->dev.
+ */
+ sprintf(dev->node.dev_name, "ni_daq_700");
+ dev->node.major = dev->node.minor = 0;
+ link->dev_node = &dev->node;
+
+ /* Finally, report what we've done */
+ printk(KERN_INFO "%s: index 0x%02x",
+ dev->node.dev_name, link->conf.ConfigIndex);
+ 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);
+ if (link->win)
+ printk(", mem 0x%06lx-0x%06lx", req.Base,
+ req.Base + req.Size - 1);
+ printk("\n");
+
+ return;
+
+ cs_failed:
+ printk(KERN_INFO "ni_daq_700 cs failed");
+ dio700_release(link);
+
+} /* dio700_config */
+
+static void dio700_release(struct pcmcia_device *link)
+{
+ DEBUG(0, "dio700_release(0x%p)\n", link);
+
+ pcmcia_disable_device(link);
+} /* dio700_release */
+
+/*======================================================================
+
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received.
+
+ When a CARD_REMOVAL event is received, we immediately set a
+ private flag to block future accesses to this device. All the
+ functions that actually access the device should check this flag
+ to make sure the card is still present.
+
+======================================================================*/
+
+static int dio700_cs_suspend(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ /* Mark the device as stopped, to block IO until later */
+ local->stop = 1;
+ return 0;
+} /* dio700_cs_suspend */
+
+static int dio700_cs_resume(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ local->stop = 0;
+ return 0;
+} /* dio700_cs_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id dio700_cs_ids[] = {
+ /* N.B. These IDs should match those in dio700_boards */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743), /* daqcard-700 */
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pcmcia, dio700_cs_ids);
+
+struct pcmcia_driver dio700_cs_driver = {
+ .probe = dio700_cs_attach,
+ .remove = dio700_cs_detach,
+ .suspend = dio700_cs_suspend,
+ .resume = dio700_cs_resume,
+ .id_table = dio700_cs_ids,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+static int __init init_dio700_cs(void)
+{
+ printk("ni_daq_700: cs-init \n");
+ DEBUG(0, "%s\n", version);
+ pcmcia_register_driver(&dio700_cs_driver);
+ return 0;
+}
+
+static void __exit exit_dio700_cs(void)
+{
+ DEBUG(0, "ni_daq_700: unloading\n");
+ pcmcia_unregister_driver(&dio700_cs_driver);
+}
+int __init init_module(void)
+{
+ int ret;
+
+ ret = init_dio700_cs();
+ if (ret < 0)
+ return ret;
+
+ return comedi_driver_register(&driver_dio700);
+}
+
+void __exit cleanup_module(void)
+{
+ exit_dio700_cs();
+ comedi_driver_unregister(&driver_dio700);
+}
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
new file mode 100644
index 00000000000..daec5c4b4c9
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -0,0 +1,598 @@
+/*
+ comedi/drivers/ni_daq_dio24.c
+ Driver for National Instruments PCMCIA DAQ-Card DIO-24
+ Copyright (C) 2002 Daniel Vecino Castel <dvecino@able.es>
+
+ PCMCIA crap at end of file is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13
+ from the pcmcia package.
+ The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
+ <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
+ are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: ni_daq_dio24
+Description: National Instruments PCMCIA DAQ-Card DIO-24
+Author: Daniel Vecino Castel <dvecino@able.es>
+Devices: [National Instruments] PCMCIA DAQ-Card DIO-24 (ni_daq_dio24)
+Status: ?
+Updated: Thu, 07 Nov 2002 21:53:06 -0800
+
+This is just a wrapper around the 8255.o driver to properly handle
+the PCMCIA interface.
+*/
+
+//#define LABPC_DEBUG // enable debugging messages
+#undef LABPC_DEBUG
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#include "8255.h"
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+static struct pcmcia_device *pcmcia_cur_dev = NULL;
+
+#define DIO24_SIZE 4 // size of io region used by board
+
+static int dio24_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dio24_detach(struct comedi_device * dev);
+
+enum dio24_bustype { pcmcia_bustype };
+
+typedef struct dio24_board_struct {
+ const char *name;
+ int device_id; // device id for pcmcia board
+ enum dio24_bustype bustype; // PCMCIA
+ int have_dio; // have 8255 chip
+ // function pointers so we can use inb/outb or readb/writeb as appropriate
+ unsigned int (*read_byte) (unsigned int address);
+ void (*write_byte) (unsigned int byte, unsigned int address);
+} dio24_board;
+
+static const dio24_board dio24_boards[] = {
+ {
+ name: "daqcard-dio24",
+ device_id:0x475c,// 0x10b is manufacturer id, 0x475c is device id
+ bustype: pcmcia_bustype,
+ have_dio:1,
+ },
+ {
+ name: "ni_daq_dio24",
+ device_id:0x475c,// 0x10b is manufacturer id, 0x475c is device id
+ bustype: pcmcia_bustype,
+ have_dio:1,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const dio24_board *)dev->board_ptr)
+
+struct dio24_private {
+
+ int data; /* number of data points left to be taken */
+};
+
+
+#define devpriv ((struct dio24_private *)dev->private)
+
+static struct comedi_driver driver_dio24 = {
+ driver_name:"ni_daq_dio24",
+ module:THIS_MODULE,
+ attach:dio24_attach,
+ detach:dio24_detach,
+ num_names:sizeof(dio24_boards) / sizeof(dio24_board),
+ board_name:&dio24_boards[0].name,
+ offset:sizeof(dio24_board),
+};
+
+static int dio24_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = 0;
+#ifdef incomplete
+ unsigned int irq = 0;
+#endif
+ struct pcmcia_device *link;
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(struct dio24_private)) < 0)
+ return -ENOMEM;
+
+ // get base address, irq etc. based on bustype
+ switch (thisboard->bustype) {
+ case pcmcia_bustype:
+ link = pcmcia_cur_dev; /* XXX hack */
+ if (!link)
+ return -EIO;
+ iobase = link->io.BasePort1;
+#ifdef incomplete
+ irq = link->irq.AssignedIRQ;
+#endif
+ break;
+ default:
+ printk("bug! couldn't determine board type\n");
+ return -EINVAL;
+ break;
+ }
+ printk("comedi%d: ni_daq_dio24: %s, io 0x%lx", dev->minor,
+ thisboard->name, iobase);
+#ifdef incomplete
+ if (irq) {
+ printk(", irq %u", irq);
+ }
+#endif
+
+ printk("\n");
+
+ if (iobase == 0) {
+ printk("io base address is zero!\n");
+ return -EINVAL;
+ }
+
+ dev->iobase = iobase;
+
+#ifdef incomplete
+ /* grab our IRQ */
+ dev->irq = irq;
+#endif
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+
+ /* 8255 dio */
+ s = dev->subdevices + 0;
+ subdev_8255_init(dev, s, NULL, dev->iobase);
+
+ return 0;
+};
+
+static int dio24_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: ni_daq_dio24: remove\n", dev->minor);
+
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 0);
+
+ if (thisboard->bustype != pcmcia_bustype && dev->iobase)
+ release_region(dev->iobase, DIO24_SIZE);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ return 0;
+};
+
+// PCMCIA crap
+
+/*
+ All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
+ you do not define PCMCIA_DEBUG at all, all the debug code will be
+ left out. If you compile with PCMCIA_DEBUG=0, the debug code will
+ be present but disabled -- but it can then be enabled for specific
+ modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version = "ni_daq_dio24.c, based on dummy_cs.c";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+static void dio24_config(struct pcmcia_device *link);
+static void dio24_release(struct pcmcia_device *link);
+static int dio24_cs_suspend(struct pcmcia_device *p_dev);
+static int dio24_cs_resume(struct pcmcia_device *p_dev);
+
+/*
+ The attach() and detach() entry points are used to create and destroy
+ "instances" of the driver, where each instance represents everything
+ needed to manage one actual PCMCIA card.
+*/
+
+static int dio24_cs_attach(struct pcmcia_device *);
+static void dio24_cs_detach(struct pcmcia_device *);
+
+/*
+ You'll also need to prototype all the functions that will actually
+ be used to talk to your device. See 'memory_cs' for a good example
+ of a fully self-sufficient driver; the other drivers rely more or
+ less on other parts of the kernel.
+*/
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static const dev_info_t dev_info = "ni_daq_dio24";
+
+typedef struct local_info_t {
+ struct pcmcia_device *link;
+ dev_node_t node;
+ int stop;
+ struct bus_operations *bus;
+} local_info_t;
+
+/*======================================================================
+
+ dio24_cs_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+
+ The dev_link structure is initialized, but we don't actually
+ configure the card at this point -- we wait until we receive a
+ card insertion event.
+
+======================================================================*/
+
+static int dio24_cs_attach(struct pcmcia_device *link)
+{
+ local_info_t *local;
+
+ printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");
+
+ DEBUG(0, "dio24_cs_attach()\n");
+
+ /* Allocate space for private device-specific data */
+ local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
+ if (!local)
+ return -ENOMEM;
+ local->link = link;
+ link->priv = local;
+
+ /* Interrupt setup */
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = NULL;
+
+ /*
+ General socket configuration defaults can go here. In this
+ client, we assume very little, and rely on the CIS for almost
+ everything. In most clients, many details (i.e., number, sizes,
+ and attributes of IO windows) are fixed by the nature of the
+ device, and can be hard-wired here.
+ */
+ link->conf.Attributes = 0;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ pcmcia_cur_dev = link;
+
+ dio24_config(link);
+
+ return 0;
+} /* dio24_cs_attach */
+
+/*======================================================================
+
+ This deletes a driver "instance". The device is de-registered
+ with Card Services. If it has been released, all local data
+ structures are freed. Otherwise, the structures will be freed
+ when the device is released.
+
+======================================================================*/
+
+static void dio24_cs_detach(struct pcmcia_device *link)
+{
+
+ printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n");
+
+ DEBUG(0, "dio24_cs_detach(0x%p)\n", link);
+
+ if (link->dev_node) {
+ ((local_info_t *) link->priv)->stop = 1;
+ dio24_release(link);
+ }
+
+ /* This points to the parent local_info_t struct */
+ if (link->priv)
+ kfree(link->priv);
+
+} /* dio24_cs_detach */
+
+/*======================================================================
+
+ dio24_config() is scheduled to run after a CARD_INSERTION event
+ is received, to configure the PCMCIA socket, and to make the
+ device available to the system.
+
+======================================================================*/
+
+static void dio24_config(struct pcmcia_device *link)
+{
+ local_info_t *dev = link->priv;
+ tuple_t tuple;
+ cisparse_t parse;
+ int last_ret;
+ u_char buf[64];
+ win_req_t req;
+ memreq_t map;
+ cistpl_cftable_entry_t dflt = { 0 };
+
+ printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
+
+ DEBUG(0, "dio24_config(0x%p)\n", link);
+
+ /*
+ This reads the card's CONFIG tuple to find its configuration
+ registers.
+ */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) {
+ cs_error(link, GetTupleData, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) {
+ cs_error(link, ParseTuple, last_ret);
+ goto cs_failed;
+ }
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+ /*
+ In this loop, we scan the CIS for configuration table entries,
+ each of which describes a valid card configuration, including
+ voltage, IO window, memory window, and interrupt settings.
+
+ We make no assumptions about the card to be configured: we use
+ just the information available in the CIS. In an ideal world,
+ this would work for any PCMCIA card, but it requires a complete
+ and accurate CIS. In practice, a driver usually "knows" most of
+ these things without consulting the CIS, and most client drivers
+ will only use the CIS to fill in implementation-defined details.
+ */
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ while (1) {
+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ if (pcmcia_get_tuple_data(link, &tuple) != 0)
+ goto next_entry;
+ if (pcmcia_parse_tuple(&tuple, &parse) != 0)
+ goto next_entry;
+
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ if (cfg->index == 0)
+ goto next_entry;
+ link->conf.ConfigIndex = cfg->index;
+
+ /* Does this card need audio output? */
+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ link->conf.Attributes |= CONF_ENABLE_SPKR;
+ link->conf.Status = CCSR_AUDIO_ENA;
+ }
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(link, &link->io) != 0)
+ goto next_entry;
+ }
+
+ if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
+ cistpl_mem_t *mem =
+ (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
+ req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+ req.Attributes |= WIN_ENABLE;
+ req.Base = mem->win[0].host_addr;
+ req.Size = mem->win[0].len;
+ if (req.Size < 0x1000)
+ req.Size = 0x1000;
+ req.AccessSpeed = 0;
+ if (pcmcia_request_window(&link, &req, &link->win))
+ goto next_entry;
+ map.Page = 0;
+ map.CardOffset = mem->win[0].card_addr;
+ if (pcmcia_map_mem_page(link->win, &map))
+ goto next_entry;
+ }
+ /* If we got this far, we're cool! */
+ break;
+
+ next_entry:
+ if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) {
+ cs_error(link, GetNextTuple, last_ret);
+ goto cs_failed;
+ }
+ }
+
+ /*
+ 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 ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) {
+ cs_error(link, RequestIRQ, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping, and putting the
+ card and host interface into "Memory and IO" mode.
+ */
+ if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) {
+ cs_error(link, RequestConfiguration, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ At this point, the dev_node_t structure(s) need to be
+ initialized and arranged in a linked list at link->dev.
+ */
+ sprintf(dev->node.dev_name, "ni_daq_dio24");
+ dev->node.major = dev->node.minor = 0;
+ link->dev_node = &dev->node;
+
+ /* Finally, report what we've done */
+ printk(KERN_INFO "%s: index 0x%02x",
+ dev->node.dev_name, link->conf.ConfigIndex);
+ 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);
+ if (link->win)
+ printk(", mem 0x%06lx-0x%06lx", req.Base,
+ req.Base + req.Size - 1);
+ printk("\n");
+
+ return;
+
+ cs_failed:
+ printk(KERN_INFO "Fallo");
+ dio24_release(link);
+
+} /* dio24_config */
+
+static void dio24_release(struct pcmcia_device *link)
+{
+ DEBUG(0, "dio24_release(0x%p)\n", link);
+
+ pcmcia_disable_device(link);
+} /* dio24_release */
+
+/*======================================================================
+
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received.
+
+ When a CARD_REMOVAL event is received, we immediately set a
+ private flag to block future accesses to this device. All the
+ functions that actually access the device should check this flag
+ to make sure the card is still present.
+
+======================================================================*/
+
+static int dio24_cs_suspend(struct pcmcia_device *link)
+{
+ local_info_t *local = link->priv;
+
+ /* Mark the device as stopped, to block IO until later */
+ local->stop = 1;
+ return 0;
+} /* dio24_cs_suspend */
+
+static int dio24_cs_resume(struct pcmcia_device *link)
+{
+ local_info_t *local = link->priv;
+
+ local->stop = 0;
+ return 0;
+} /* dio24_cs_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id dio24_cs_ids[] = {
+ /* N.B. These IDs should match those in dio24_boards */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x475c), /* daqcard-dio24 */
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, dio24_cs_ids);
+
+struct pcmcia_driver dio24_cs_driver = {
+ .probe = dio24_cs_attach,
+ .remove = dio24_cs_detach,
+ .suspend = dio24_cs_suspend,
+ .resume = dio24_cs_resume,
+ .id_table = dio24_cs_ids,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+static int __init init_dio24_cs(void)
+{
+ printk("ni_daq_dio24: HOLA SOY YO!\n");
+ DEBUG(0, "%s\n", version);
+ pcmcia_register_driver(&dio24_cs_driver);
+ return 0;
+}
+
+static void __exit exit_dio24_cs(void)
+{
+ DEBUG(0, "ni_dio24: unloading\n");
+ pcmcia_unregister_driver(&dio24_cs_driver);
+}
+
+int __init init_module(void)
+{
+ int ret;
+
+ ret = init_dio24_cs();
+ if (ret < 0)
+ return ret;
+
+ return comedi_driver_register(&driver_dio24);
+}
+
+void __exit cleanup_module(void)
+{
+ exit_dio24_cs();
+ comedi_driver_unregister(&driver_dio24);
+}
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
new file mode 100644
index 00000000000..37898d8474c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -0,0 +1,2005 @@
+/*
+ comedi/drivers/ni_labpc.c
+ Driver for National Instruments Lab-PC series boards and compatibles
+ Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: ni_labpc
+Description: National Instruments Lab-PC (& compatibles)
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [National Instruments] Lab-PC-1200 (labpc-1200),
+ Lab-PC-1200AI (labpc-1200ai), Lab-PC+ (lab-pc+), PCI-1200 (ni_labpc)
+Status: works
+
+Tested with lab-pc-1200. For the older Lab-PC+, not all input ranges
+and analog references will work, the available ranges/arefs will
+depend on how you have configured the jumpers on your board
+(see your owner's manual).
+
+Kernel-level ISA plug-and-play support for the lab-pc-1200
+boards has not
+yet been added to the driver, mainly due to the fact that
+I don't know the device id numbers. If you have one
+of these boards,
+please file a bug report at https://bugs.comedi.org/
+so I can get the necessary information from you.
+
+The 1200 series boards have onboard calibration dacs for correcting
+analog input/output offsets and gains. The proper settings for these
+caldacs are stored on the board's eeprom. To read the caldac values
+from the eeprom and store them into a file that can be then be used by
+comedilib, use the comedi_calibrate program.
+
+Configuration options - ISA boards:
+ [0] - I/O port base address
+ [1] - IRQ (optional, required for timed or externally triggered conversions)
+ [2] - DMA channel (optional)
+
+Configuration options - PCI boards:
+ [0] - bus (optional)
+ [1] - slot (optional)
+
+The Lab-pc+ has quirky chanlist requirements
+when scanning multiple channels. Multiple channel scan
+sequence must start at highest channel, then decrement down to
+channel 0. The rest of the cards can scan down like lab-pc+ or scan
+up from channel zero. Chanlists consisting of all one channel
+are also legal, and allow you to pace conversions in bursts.
+
+*/
+
+/*
+
+NI manuals:
+341309a (labpc-1200 register manual)
+340914a (pci-1200)
+320502b (lab-pc+)
+
+*/
+
+#undef LABPC_DEBUG
+//#define LABPC_DEBUG // enable debugging messages
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+#include "8255.h"
+#include "mite.h"
+#include "comedi_fc.h"
+#include "ni_labpc.h"
+
+#define DRV_NAME "ni_labpc"
+
+#define LABPC_SIZE 32 // size of io region used by board
+#define LABPC_TIMER_BASE 500 // 2 MHz master clock
+
+/* Registers for the lab-pc+ */
+
+//write-only registers
+#define COMMAND1_REG 0x0
+#define ADC_GAIN_MASK (0x7 << 4)
+#define ADC_CHAN_BITS(x) ((x) & 0x7)
+#define ADC_SCAN_EN_BIT 0x80 // enables multi channel scans
+#define COMMAND2_REG 0x1
+#define PRETRIG_BIT 0x1 // enable pretriggering (used in conjunction with SWTRIG)
+#define HWTRIG_BIT 0x2 // enable paced conversions on external trigger
+#define SWTRIG_BIT 0x4 // enable paced conversions
+#define CASCADE_BIT 0x8 // use two cascaded counters for pacing
+#define DAC_PACED_BIT(channel) (0x40 << ((channel) & 0x1))
+#define COMMAND3_REG 0x2
+#define DMA_EN_BIT 0x1 // enable dma transfers
+#define DIO_INTR_EN_BIT 0x2 // enable interrupts for 8255
+#define DMATC_INTR_EN_BIT 0x4 // enable dma terminal count interrupt
+#define TIMER_INTR_EN_BIT 0x8 // enable timer interrupt
+#define ERR_INTR_EN_BIT 0x10 // enable error interrupt
+#define ADC_FNE_INTR_EN_BIT 0x20 // enable fifo not empty interrupt
+#define ADC_CONVERT_REG 0x3
+#define DAC_LSB_REG(channel) (0x4 + 2 * ((channel) & 0x1))
+#define DAC_MSB_REG(channel) (0x5 + 2 * ((channel) & 0x1))
+#define ADC_CLEAR_REG 0x8
+#define DMATC_CLEAR_REG 0xa
+#define TIMER_CLEAR_REG 0xc
+#define COMMAND6_REG 0xe // 1200 boards only
+#define ADC_COMMON_BIT 0x1 // select ground or common-mode reference
+#define ADC_UNIP_BIT 0x2 // adc unipolar
+#define DAC_UNIP_BIT(channel) (0x4 << ((channel) & 0x1)) // dac unipolar
+#define ADC_FHF_INTR_EN_BIT 0x20 // enable fifo half full interrupt
+#define A1_INTR_EN_BIT 0x40 // enable interrupt on end of hardware count
+#define ADC_SCAN_UP_BIT 0x80 // scan up from channel zero instead of down to zero
+#define COMMAND4_REG 0xf
+#define INTERVAL_SCAN_EN_BIT 0x1 // enables 'interval' scanning
+#define EXT_SCAN_EN_BIT 0x2 // enables external signal on counter b1 output to trigger scan
+#define EXT_CONVERT_OUT_BIT 0x4 // chooses direction (output or input) for EXTCONV* line
+#define ADC_DIFF_BIT 0x8 // chooses differential inputs for adc (in conjunction with board jumper)
+#define EXT_CONVERT_DISABLE_BIT 0x10
+#define COMMAND5_REG 0x1c // 1200 boards only, calibration stuff
+#define EEPROM_WRITE_UNPROTECT_BIT 0x4 // enable eeprom for write
+#define DITHER_EN_BIT 0x8 // enable dithering
+#define CALDAC_LOAD_BIT 0x10 // load calibration dac
+#define SCLOCK_BIT 0x20 // serial clock - rising edge writes, falling edge reads
+#define SDATA_BIT 0x40 // serial data bit for writing to eeprom or calibration dacs
+#define EEPROM_EN_BIT 0x80 // enable eeprom for read/write
+#define INTERVAL_COUNT_REG 0x1e
+#define INTERVAL_LOAD_REG 0x1f
+#define INTERVAL_LOAD_BITS 0x1
+
+// read-only registers
+#define STATUS1_REG 0x0
+#define DATA_AVAIL_BIT 0x1 // data is available in fifo
+#define OVERRUN_BIT 0x2 // overrun has occurred
+#define OVERFLOW_BIT 0x4 // fifo overflow
+#define TIMER_BIT 0x8 // timer interrupt has occured
+#define DMATC_BIT 0x10 // dma terminal count has occured
+#define EXT_TRIG_BIT 0x40 // external trigger has occured
+#define STATUS2_REG 0x1d // 1200 boards only
+#define EEPROM_OUT_BIT 0x1 // programmable eeprom serial output
+#define A1_TC_BIT 0x2 // counter A1 terminal count
+#define FNHF_BIT 0x4 // fifo not half full
+#define ADC_FIFO_REG 0xa
+
+#define DIO_BASE_REG 0x10
+#define COUNTER_A_BASE_REG 0x14
+#define COUNTER_A_CONTROL_REG (COUNTER_A_BASE_REG + 0x3)
+#define INIT_A0_BITS 0x14 // check modes put conversion pacer output in harmless state (a0 mode 2)
+#define INIT_A1_BITS 0x70 // put hardware conversion counter output in harmless state (a1 mode 0)
+#define COUNTER_B_BASE_REG 0x18
+
+static int labpc_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int labpc_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t labpc_interrupt(int irq, void *d PT_REGS_ARG);
+static int labpc_drain_fifo(struct comedi_device * dev);
+static void labpc_drain_dma(struct comedi_device * dev);
+static void handle_isa_dma(struct comedi_device * dev);
+static void labpc_drain_dregs(struct comedi_device * dev);
+static int labpc_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int labpc_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int labpc_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int labpc_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int labpc_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int labpc_calib_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int labpc_calib_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int labpc_eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int labpc_eeprom_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd);
+static void labpc_adc_timing(struct comedi_device * dev, struct comedi_cmd * cmd);
+#ifdef CONFIG_COMEDI_PCI
+static int labpc_find_device(struct comedi_device *dev, int bus, int slot);
+#endif
+static int labpc_dio_mem_callback(int dir, int port, int data,
+ unsigned long arg);
+static void labpc_serial_out(struct comedi_device * dev, unsigned int value,
+ unsigned int num_bits);
+static unsigned int labpc_serial_in(struct comedi_device * dev);
+static unsigned int labpc_eeprom_read(struct comedi_device * dev,
+ unsigned int address);
+static unsigned int labpc_eeprom_read_status(struct comedi_device * dev);
+static unsigned int labpc_eeprom_write(struct comedi_device * dev,
+ unsigned int address, unsigned int value);
+static void write_caldac(struct comedi_device * dev, unsigned int channel,
+ unsigned int value);
+
+enum scan_mode {
+ MODE_SINGLE_CHAN,
+ MODE_SINGLE_CHAN_INTERVAL,
+ MODE_MULT_CHAN_UP,
+ MODE_MULT_CHAN_DOWN,
+};
+
+//analog input ranges
+#define NUM_LABPC_PLUS_AI_RANGES 16
+// indicates unipolar ranges
+static const int labpc_plus_is_unipolar[NUM_LABPC_PLUS_AI_RANGES] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+};
+
+// map range index to gain bits
+static const int labpc_plus_ai_gain_bits[NUM_LABPC_PLUS_AI_RANGES] = {
+ 0x00,
+ 0x10,
+ 0x20,
+ 0x30,
+ 0x40,
+ 0x50,
+ 0x60,
+ 0x70,
+ 0x00,
+ 0x10,
+ 0x20,
+ 0x30,
+ 0x40,
+ 0x50,
+ 0x60,
+ 0x70,
+};
+static const struct comedi_lrange range_labpc_plus_ai = {
+ NUM_LABPC_PLUS_AI_RANGES,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(4),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.25),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.05),
+ UNI_RANGE(10),
+ UNI_RANGE(8),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1),
+ UNI_RANGE(0.5),
+ UNI_RANGE(0.2),
+ UNI_RANGE(0.1),
+ }
+};
+
+#define NUM_LABPC_1200_AI_RANGES 14
+// indicates unipolar ranges
+const int labpc_1200_is_unipolar[NUM_LABPC_1200_AI_RANGES] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+};
+
+// map range index to gain bits
+const int labpc_1200_ai_gain_bits[NUM_LABPC_1200_AI_RANGES] = {
+ 0x00,
+ 0x20,
+ 0x30,
+ 0x40,
+ 0x50,
+ 0x60,
+ 0x70,
+ 0x00,
+ 0x20,
+ 0x30,
+ 0x40,
+ 0x50,
+ 0x60,
+ 0x70,
+};
+const struct comedi_lrange range_labpc_1200_ai = {
+ NUM_LABPC_1200_AI_RANGES,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.25),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.05),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1),
+ UNI_RANGE(0.5),
+ UNI_RANGE(0.2),
+ UNI_RANGE(0.1),
+ }
+};
+
+//analog output ranges
+#define AO_RANGE_IS_UNIPOLAR 0x1
+static const struct comedi_lrange range_labpc_ao = {
+ 2,
+ {
+ BIP_RANGE(5),
+ UNI_RANGE(10),
+ }
+};
+
+/* functions that do inb/outb and readb/writeb so we can use
+ * function pointers to decide which to use */
+static inline unsigned int labpc_inb(unsigned long address)
+{
+ return inb(address);
+}
+static inline void labpc_outb(unsigned int byte, unsigned long address)
+{
+ outb(byte, address);
+}
+static inline unsigned int labpc_readb(unsigned long address)
+{
+ return readb((void *)address);
+}
+static inline void labpc_writeb(unsigned int byte, unsigned long address)
+{
+ writeb(byte, (void *)address);
+}
+
+static const labpc_board labpc_boards[] = {
+ {
+ name: "lab-pc-1200",
+ ai_speed:10000,
+ bustype: isa_bustype,
+ register_layout:labpc_1200_layout,
+ has_ao: 1,
+ ai_range_table:&range_labpc_1200_ai,
+ ai_range_code:labpc_1200_ai_gain_bits,
+ ai_range_is_unipolar:labpc_1200_is_unipolar,
+ ai_scan_up:1,
+ memory_mapped_io:0,
+ },
+ {
+ name: "lab-pc-1200ai",
+ ai_speed:10000,
+ bustype: isa_bustype,
+ register_layout:labpc_1200_layout,
+ has_ao: 0,
+ ai_range_table:&range_labpc_1200_ai,
+ ai_range_code:labpc_1200_ai_gain_bits,
+ ai_range_is_unipolar:labpc_1200_is_unipolar,
+ ai_scan_up:1,
+ memory_mapped_io:0,
+ },
+ {
+ name: "lab-pc+",
+ ai_speed:12000,
+ bustype: isa_bustype,
+ register_layout:labpc_plus_layout,
+ has_ao: 1,
+ ai_range_table:&range_labpc_plus_ai,
+ ai_range_code:labpc_plus_ai_gain_bits,
+ ai_range_is_unipolar:labpc_plus_is_unipolar,
+ ai_scan_up:0,
+ memory_mapped_io:0,
+ },
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: "pci-1200",
+ device_id:0x161,
+ ai_speed:10000,
+ bustype: pci_bustype,
+ register_layout:labpc_1200_layout,
+ has_ao: 1,
+ ai_range_table:&range_labpc_1200_ai,
+ ai_range_code:labpc_1200_ai_gain_bits,
+ ai_range_is_unipolar:labpc_1200_is_unipolar,
+ ai_scan_up:1,
+ memory_mapped_io:1,
+ },
+ // dummy entry so pci board works when comedi_config is passed driver name
+ {
+ .name = DRV_NAME,
+ .bustype = pci_bustype,
+ },
+#endif
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((labpc_board *)dev->board_ptr)
+
+static const int dma_buffer_size = 0xff00; // size in bytes of dma buffer
+static const int sample_size = 2; // 2 bytes per sample
+
+#define devpriv ((labpc_private *)dev->private)
+
+static struct comedi_driver driver_labpc = {
+ .driver_name = DRV_NAME,
+ .module = THIS_MODULE,
+ .attach = labpc_attach,
+ .detach = labpc_common_detach,
+ .num_names = sizeof(labpc_boards) / sizeof(labpc_board),
+ .board_name = &labpc_boards[0].name,
+ .offset = sizeof(labpc_board),
+};
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x161, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, labpc_pci_table);
+#endif /* CONFIG_COMEDI_PCI */
+
+static inline int labpc_counter_load(struct comedi_device * dev,
+ unsigned long base_address, unsigned int counter_number,
+ unsigned int count, unsigned int mode)
+{
+ if (thisboard->memory_mapped_io)
+ return i8254_mm_load((void *)base_address, 0, counter_number,
+ count, mode);
+ else
+ return i8254_load(base_address, 0, counter_number, count, mode);
+}
+
+int labpc_common_attach(struct comedi_device * dev, unsigned long iobase,
+ unsigned int irq, unsigned int dma_chan)
+{
+ struct comedi_subdevice *s;
+ int i;
+ unsigned long dma_flags, isr_flags;
+ short lsb, msb;
+
+ printk("comedi%d: ni_labpc: %s, io 0x%lx", dev->minor, thisboard->name,
+ iobase);
+ if (irq) {
+ printk(", irq %u", irq);
+ }
+ if (dma_chan) {
+ printk(", dma %u", dma_chan);
+ }
+ printk("\n");
+
+ if (iobase == 0) {
+ printk("io base address is zero!\n");
+ return -EINVAL;
+ }
+ // request io regions for isa boards
+ if (thisboard->bustype == isa_bustype) {
+ /* check if io addresses are available */
+ if (!request_region(iobase, LABPC_SIZE,
+ driver_labpc.driver_name)) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ }
+ dev->iobase = iobase;
+
+ if (thisboard->memory_mapped_io) {
+ devpriv->read_byte = labpc_readb;
+ devpriv->write_byte = labpc_writeb;
+ } else {
+ devpriv->read_byte = labpc_inb;
+ devpriv->write_byte = labpc_outb;
+ }
+ // initialize board's command registers
+ devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
+ devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+ devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+ devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
+ if (thisboard->register_layout == labpc_1200_layout) {
+ devpriv->write_byte(devpriv->command5_bits,
+ dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->command6_bits,
+ dev->iobase + COMMAND6_REG);
+ }
+
+ /* grab our IRQ */
+ if (irq) {
+ isr_flags = 0;
+ if (thisboard->bustype == pci_bustype)
+ isr_flags |= IRQF_SHARED;
+ if (comedi_request_irq(irq, labpc_interrupt, isr_flags,
+ driver_labpc.driver_name, dev)) {
+ printk("unable to allocate irq %u\n", irq);
+ return -EINVAL;
+ }
+ }
+ dev->irq = irq;
+
+ // grab dma channel
+ if (dma_chan > 3) {
+ printk(" invalid dma channel %u\n", dma_chan);
+ return -EINVAL;
+ } else if (dma_chan) {
+ // allocate dma buffer
+ devpriv->dma_buffer =
+ kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA);
+ if (devpriv->dma_buffer == NULL) {
+ printk(" failed to allocate dma buffer\n");
+ return -ENOMEM;
+ }
+ if (request_dma(dma_chan, driver_labpc.driver_name)) {
+ printk(" failed to allocate dma channel %u\n",
+ dma_chan);
+ return -EINVAL;
+ }
+ devpriv->dma_chan = dma_chan;
+ dma_flags = claim_dma_lock();
+ disable_dma(devpriv->dma_chan);
+ set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
+ release_dma_lock(dma_flags);
+ }
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_subdevices(dev, 5) < 0)
+ return -ENOMEM;
+
+ /* analog input subdevice */
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags =
+ SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF |
+ SDF_CMD_READ;
+ s->n_chan = 8;
+ s->len_chanlist = 8;
+ s->maxdata = (1 << 12) - 1; // 12 bit resolution
+ s->range_table = thisboard->ai_range_table;
+ s->do_cmd = labpc_ai_cmd;
+ s->do_cmdtest = labpc_ai_cmdtest;
+ s->insn_read = labpc_ai_rinsn;
+ s->cancel = labpc_cancel;
+
+ /* analog output */
+ s = dev->subdevices + 1;
+ if (thisboard->has_ao) {
+/* Could provide command support, except it only has a one sample
+ * hardware buffer for analog output and no underrun flag. */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = NUM_AO_CHAN;
+ s->maxdata = (1 << 12) - 1; // 12 bit resolution
+ s->range_table = &range_labpc_ao;
+ s->insn_read = labpc_ao_rinsn;
+ s->insn_write = labpc_ao_winsn;
+ /* initialize analog outputs to a known value */
+ for (i = 0; i < s->n_chan; i++) {
+ devpriv->ao_value[i] = s->maxdata / 2;
+ lsb = devpriv->ao_value[i] & 0xff;
+ msb = (devpriv->ao_value[i] >> 8) & 0xff;
+ devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(i));
+ devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(i));
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* 8255 dio */
+ s = dev->subdevices + 2;
+ // if board uses io memory we have to give a custom callback function to the 8255 driver
+ if (thisboard->memory_mapped_io)
+ subdev_8255_init(dev, s, labpc_dio_mem_callback,
+ (unsigned long)(dev->iobase + DIO_BASE_REG));
+ else
+ subdev_8255_init(dev, s, NULL, dev->iobase + DIO_BASE_REG);
+
+ // calibration subdevices for boards that have one
+ s = dev->subdevices + 3;
+ if (thisboard->register_layout == labpc_1200_layout) {
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 16;
+ s->maxdata = 0xff;
+ s->insn_read = labpc_calib_read_insn;
+ s->insn_write = labpc_calib_write_insn;
+
+ for (i = 0; i < s->n_chan; i++)
+ write_caldac(dev, i, s->maxdata / 2);
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ /* EEPROM */
+ s = dev->subdevices + 4;
+ if (thisboard->register_layout == labpc_1200_layout) {
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = EEPROM_SIZE;
+ s->maxdata = 0xff;
+ s->insn_read = labpc_eeprom_read_insn;
+ s->insn_write = labpc_eeprom_write_insn;
+
+ for (i = 0; i < EEPROM_SIZE; i++) {
+ devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
+ }
+#ifdef LABPC_DEBUG
+ printk(" eeprom:");
+ for (i = 0; i < EEPROM_SIZE; i++) {
+ printk(" %i:0x%x ", i, devpriv->eeprom_data[i]);
+ }
+ printk("\n");
+#endif
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ return 0;
+}
+
+static int labpc_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned long iobase = 0;
+ unsigned int irq = 0;
+ unsigned int dma_chan = 0;
+#ifdef CONFIG_COMEDI_PCI
+ int retval;
+#endif
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(labpc_private)) < 0)
+ return -ENOMEM;
+
+ // get base address, irq etc. based on bustype
+ switch (thisboard->bustype) {
+ case isa_bustype:
+ iobase = it->options[0];
+ irq = it->options[1];
+ dma_chan = it->options[2];
+ break;
+ case pci_bustype:
+#ifdef CONFIG_COMEDI_PCI
+ retval = labpc_find_device(dev, it->options[0], it->options[1]);
+ if (retval < 0) {
+ return retval;
+ }
+ retval = mite_setup(devpriv->mite);
+ if (retval < 0)
+ return retval;
+ iobase = (unsigned long)devpriv->mite->daq_io_addr;
+ irq = mite_irq(devpriv->mite);
+#else
+ printk(" this driver has not been built with PCI support.\n");
+ return -EINVAL;
+#endif
+ break;
+ case pcmcia_bustype:
+ printk(" this driver does not support pcmcia cards, use ni_labpc_cs.o\n");
+ return -EINVAL;
+ break;
+ default:
+ printk("bug! couldn't determine board type\n");
+ return -EINVAL;
+ break;
+ }
+
+ return labpc_common_attach(dev, iobase, irq, dma_chan);
+}
+
+// adapted from ni_pcimio for finding mite based boards (pc-1200)
+#ifdef CONFIG_COMEDI_PCI
+static int labpc_find_device(struct comedi_device *dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ // if bus/slot are specified then make sure we have the right bus/slot
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number
+ || slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+ for (i = 0; i < driver_labpc.num_names; i++) {
+ if (labpc_boards[i].bustype != pci_bustype)
+ continue;
+ if (mite_device_id(mite) == labpc_boards[i].device_id) {
+ devpriv->mite = mite;
+ // fixup board pointer, in case we were using the dummy "ni_labpc" entry
+ dev->board_ptr = &labpc_boards[i];
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
+#endif
+
+int labpc_common_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: ni_labpc: detach\n", dev->minor);
+
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+
+ /* only free stuff if it has been allocated by _attach */
+ if (devpriv->dma_buffer)
+ kfree(devpriv->dma_buffer);
+ if (devpriv->dma_chan)
+ free_dma(devpriv->dma_chan);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (thisboard->bustype == isa_bustype && dev->iobase)
+ release_region(dev->iobase, LABPC_SIZE);
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->mite)
+ mite_unsetup(devpriv->mite);
+#endif
+
+ return 0;
+};
+
+static void labpc_clear_adc_fifo(const struct comedi_device * dev)
+{
+ devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
+ devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+ devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+}
+
+static int labpc_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
+ devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ devpriv->command3_bits = 0;
+ devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+
+ return 0;
+}
+
+static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd * cmd)
+{
+ if (cmd->chanlist_len == 1)
+ return MODE_SINGLE_CHAN;
+
+ /* chanlist may be NULL during cmdtest. */
+ if (cmd->chanlist == NULL)
+ return MODE_MULT_CHAN_UP;
+
+ if (CR_CHAN(cmd->chanlist[0]) == CR_CHAN(cmd->chanlist[1]))
+ return MODE_SINGLE_CHAN_INTERVAL;
+
+ if (CR_CHAN(cmd->chanlist[0]) < CR_CHAN(cmd->chanlist[1]))
+ return MODE_MULT_CHAN_UP;
+
+ if (CR_CHAN(cmd->chanlist[0]) > CR_CHAN(cmd->chanlist[1]))
+ return MODE_MULT_CHAN_DOWN;
+
+ rt_printk("ni_labpc: bug! this should never happen\n");
+
+ return 0;
+}
+
+static int labpc_ai_chanlist_invalid(const struct comedi_device * dev,
+ const struct comedi_cmd * cmd)
+{
+ int mode, channel, range, aref, i;
+
+ if (cmd->chanlist == NULL)
+ return 0;
+
+ mode = labpc_ai_scan_mode(cmd);
+
+ if (mode == MODE_SINGLE_CHAN)
+ return 0;
+
+ if (mode == MODE_SINGLE_CHAN_INTERVAL) {
+ if (cmd->chanlist_len > 0xff) {
+ comedi_error(dev,
+ "ni_labpc: chanlist too long for single channel interval mode\n");
+ return 1;
+ }
+ }
+
+ channel = CR_CHAN(cmd->chanlist[0]);
+ range = CR_RANGE(cmd->chanlist[0]);
+ aref = CR_AREF(cmd->chanlist[0]);
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+
+ switch (mode) {
+ case MODE_SINGLE_CHAN_INTERVAL:
+ if (CR_CHAN(cmd->chanlist[i]) != channel) {
+ comedi_error(dev,
+ "channel scanning order specified in chanlist is not supported by hardware.\n");
+ return 1;
+ }
+ break;
+ case MODE_MULT_CHAN_UP:
+ if (CR_CHAN(cmd->chanlist[i]) != i) {
+ comedi_error(dev,
+ "channel scanning order specified in chanlist is not supported by hardware.\n");
+ return 1;
+ }
+ break;
+ case MODE_MULT_CHAN_DOWN:
+ if (CR_CHAN(cmd->chanlist[i]) !=
+ cmd->chanlist_len - i - 1) {
+ comedi_error(dev,
+ "channel scanning order specified in chanlist is not supported by hardware.\n");
+ return 1;
+ }
+ break;
+ default:
+ rt_printk("ni_labpc: bug! in chanlist check\n");
+ return 1;
+ break;
+ }
+
+ if (CR_RANGE(cmd->chanlist[i]) != range) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same range\n");
+ return 1;
+ }
+
+ if (CR_AREF(cmd->chanlist[i]) != aref) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same reference\n");
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int labpc_use_continuous_mode(const struct comedi_cmd * cmd)
+{
+ if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN)
+ return 1;
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW)
+ return 1;
+
+ return 0;
+}
+
+static unsigned int labpc_ai_convert_period(const struct comedi_cmd * cmd)
+{
+ if (cmd->convert_src != TRIG_TIMER)
+ return 0;
+
+ if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
+ cmd->scan_begin_src == TRIG_TIMER)
+ return cmd->scan_begin_arg;
+
+ return cmd->convert_arg;
+}
+
+static void labpc_set_ai_convert_period(struct comedi_cmd * cmd, unsigned int ns)
+{
+ if (cmd->convert_src != TRIG_TIMER)
+ return;
+
+ if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
+ cmd->scan_begin_src == TRIG_TIMER) {
+ cmd->scan_begin_arg = ns;
+ if (cmd->convert_arg > cmd->scan_begin_arg)
+ cmd->convert_arg = cmd->scan_begin_arg;
+ } else
+ cmd->convert_arg = ns;
+}
+
+static unsigned int labpc_ai_scan_period(const struct comedi_cmd * cmd)
+{
+ if (cmd->scan_begin_src != TRIG_TIMER)
+ return 0;
+
+ if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
+ cmd->convert_src == TRIG_TIMER)
+ return 0;
+
+ return cmd->scan_begin_arg;
+}
+
+static void labpc_set_ai_scan_period(struct comedi_cmd * cmd, unsigned int ns)
+{
+ if (cmd->scan_begin_src != TRIG_TIMER)
+ return;
+
+ if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
+ cmd->convert_src == TRIG_TIMER)
+ return;
+
+ cmd->scan_begin_arg = ns;
+}
+
+static int labpc_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp, tmp2;
+ int stop_mask;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ stop_mask = TRIG_COUNT | TRIG_NONE;
+ if (thisboard->register_layout == labpc_1200_layout)
+ stop_mask |= TRIG_EXT;
+ cmd->stop_src &= stop_mask;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT &&
+ cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ // can't have external stop and start triggers at once
+ if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg == TRIG_NOW && cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (!cmd->chanlist_len) {
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+ // make sure scan timing is not too fast
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->convert_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->chanlist_len) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->scan_begin_arg <
+ thisboard->ai_speed * cmd->chanlist_len) {
+ cmd->scan_begin_arg =
+ thisboard->ai_speed * cmd->chanlist_len;
+ err++;
+ }
+ }
+ // stop source
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ // TRIG_EXT doesn't care since it doesn't trigger off a numbered channel
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ tmp = cmd->convert_arg;
+ tmp2 = cmd->scan_begin_arg;
+ labpc_adc_timing(dev, cmd);
+ if (tmp != cmd->convert_arg || tmp2 != cmd->scan_begin_arg)
+ err++;
+
+ if (err)
+ return 4;
+
+ if (labpc_ai_chanlist_invalid(dev, cmd))
+ return 5;
+
+ return 0;
+}
+
+static int labpc_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int channel, range, aref;
+ unsigned long irq_flags;
+ int ret;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ enum transfer_type xfer;
+ unsigned long flags;
+
+ if (!dev->irq) {
+ comedi_error(dev, "no irq assigned, cannot perform command");
+ return -1;
+ }
+
+ range = CR_RANGE(cmd->chanlist[0]);
+ aref = CR_AREF(cmd->chanlist[0]);
+
+ // make sure board is disabled before setting up aquisition
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
+ devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ devpriv->command3_bits = 0;
+ devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+
+ // initialize software conversion count
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->count = cmd->stop_arg * cmd->chanlist_len;
+ }
+ // setup hardware conversion counter
+ if (cmd->stop_src == TRIG_EXT) {
+ // load counter a1 with count of 3 (pc+ manual says this is minimum allowed) using mode 0
+ ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
+ 1, 3, 0);
+ if (ret < 0) {
+ comedi_error(dev, "error loading counter a1");
+ return -1;
+ }
+ } else // otherwise, just put a1 in mode 0 with no count to set its output low
+ devpriv->write_byte(INIT_A1_BITS,
+ dev->iobase + COUNTER_A_CONTROL_REG);
+
+ // figure out what method we will use to transfer data
+ if (devpriv->dma_chan && // need a dma channel allocated
+ // dma unsafe at RT priority, and too much setup time for TRIG_WAKE_EOS for
+ (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT)) == 0 &&
+ // only available on the isa boards
+ thisboard->bustype == isa_bustype) {
+ xfer = isa_dma_transfer;
+ } else if (thisboard->register_layout == labpc_1200_layout && // pc-plus has no fifo-half full interrupt
+ // wake-end-of-scan should interrupt on fifo not empty
+ (cmd->flags & TRIG_WAKE_EOS) == 0 &&
+ // make sure we are taking more than just a few points
+ (cmd->stop_src != TRIG_COUNT || devpriv->count > 256)) {
+ xfer = fifo_half_full_transfer;
+ } else
+ xfer = fifo_not_empty_transfer;
+ devpriv->current_transfer = xfer;
+
+ // setup command6 register for 1200 boards
+ if (thisboard->register_layout == labpc_1200_layout) {
+ // reference inputs to ground or common?
+ if (aref != AREF_GROUND)
+ devpriv->command6_bits |= ADC_COMMON_BIT;
+ else
+ devpriv->command6_bits &= ~ADC_COMMON_BIT;
+ // bipolar or unipolar range?
+ if (thisboard->ai_range_is_unipolar[range])
+ devpriv->command6_bits |= ADC_UNIP_BIT;
+ else
+ devpriv->command6_bits &= ~ADC_UNIP_BIT;
+ // interrupt on fifo half full?
+ if (xfer == fifo_half_full_transfer)
+ devpriv->command6_bits |= ADC_FHF_INTR_EN_BIT;
+ else
+ devpriv->command6_bits &= ~ADC_FHF_INTR_EN_BIT;
+ // enable interrupt on counter a1 terminal count?
+ if (cmd->stop_src == TRIG_EXT)
+ devpriv->command6_bits |= A1_INTR_EN_BIT;
+ else
+ devpriv->command6_bits &= ~A1_INTR_EN_BIT;
+ // are we scanning up or down through channels?
+ if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP)
+ devpriv->command6_bits |= ADC_SCAN_UP_BIT;
+ else
+ devpriv->command6_bits &= ~ADC_SCAN_UP_BIT;
+ // write to register
+ devpriv->write_byte(devpriv->command6_bits,
+ dev->iobase + COMMAND6_REG);
+ }
+
+ /* setup channel list, etc (command1 register) */
+ devpriv->command1_bits = 0;
+ if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP)
+ channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
+ else
+ channel = CR_CHAN(cmd->chanlist[0]);
+ // munge channel bits for differential / scan disabled mode
+ if (labpc_ai_scan_mode(cmd) != MODE_SINGLE_CHAN && aref == AREF_DIFF)
+ channel *= 2;
+ devpriv->command1_bits |= ADC_CHAN_BITS(channel);
+ devpriv->command1_bits |= thisboard->ai_range_code[range];
+ devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
+ // manual says to set scan enable bit on second pass
+ if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP ||
+ labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_DOWN) {
+ devpriv->command1_bits |= ADC_SCAN_EN_BIT;
+ /* need a brief delay before enabling scan, or scan list will get screwed when you switch
+ * between scan up to scan down mode - dunno why */
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command1_bits,
+ dev->iobase + COMMAND1_REG);
+ }
+ // setup any external triggering/pacing (command4 register)
+ devpriv->command4_bits = 0;
+ if (cmd->convert_src != TRIG_EXT)
+ devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
+ /* XXX should discard first scan when using interval scanning
+ * since manual says it is not synced with scan clock */
+ if (labpc_use_continuous_mode(cmd) == 0) {
+ devpriv->command4_bits |= INTERVAL_SCAN_EN_BIT;
+ if (cmd->scan_begin_src == TRIG_EXT)
+ devpriv->command4_bits |= EXT_SCAN_EN_BIT;
+ }
+ // single-ended/differential
+ if (aref == AREF_DIFF)
+ devpriv->command4_bits |= ADC_DIFF_BIT;
+ devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
+
+ devpriv->write_byte(cmd->chanlist_len,
+ dev->iobase + INTERVAL_COUNT_REG);
+ // load count
+ devpriv->write_byte(INTERVAL_LOAD_BITS,
+ dev->iobase + INTERVAL_LOAD_REG);
+
+ if (cmd->convert_src == TRIG_TIMER || cmd->scan_begin_src == TRIG_TIMER) {
+ // set up pacing
+ labpc_adc_timing(dev, cmd);
+ // load counter b0 in mode 3
+ ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
+ 0, devpriv->divisor_b0, 3);
+ if (ret < 0) {
+ comedi_error(dev, "error loading counter b0");
+ return -1;
+ }
+ }
+ // set up conversion pacing
+ if (labpc_ai_convert_period(cmd)) {
+ // load counter a0 in mode 2
+ ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
+ 0, devpriv->divisor_a0, 2);
+ if (ret < 0) {
+ comedi_error(dev, "error loading counter a0");
+ return -1;
+ }
+ } else
+ devpriv->write_byte(INIT_A0_BITS,
+ dev->iobase + COUNTER_A_CONTROL_REG);
+
+ // set up scan pacing
+ if (labpc_ai_scan_period(cmd)) {
+ // load counter b1 in mode 2
+ ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
+ 1, devpriv->divisor_b1, 2);
+ if (ret < 0) {
+ comedi_error(dev, "error loading counter b1");
+ return -1;
+ }
+ }
+
+ labpc_clear_adc_fifo(dev);
+
+ // set up dma transfer
+ if (xfer == isa_dma_transfer) {
+ irq_flags = claim_dma_lock();
+ disable_dma(devpriv->dma_chan);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma_chan);
+ set_dma_addr(devpriv->dma_chan,
+ virt_to_bus(devpriv->dma_buffer));
+ // set appropriate size of transfer
+ devpriv->dma_transfer_size = labpc_suggest_transfer_size(*cmd);
+ if (cmd->stop_src == TRIG_COUNT &&
+ devpriv->count * sample_size <
+ devpriv->dma_transfer_size) {
+ devpriv->dma_transfer_size =
+ devpriv->count * sample_size;
+ }
+ set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
+ enable_dma(devpriv->dma_chan);
+ release_dma_lock(irq_flags);
+ // enable board's dma
+ devpriv->command3_bits |= DMA_EN_BIT | DMATC_INTR_EN_BIT;
+ } else
+ devpriv->command3_bits &= ~DMA_EN_BIT & ~DMATC_INTR_EN_BIT;
+
+ // enable error interrupts
+ devpriv->command3_bits |= ERR_INTR_EN_BIT;
+ // enable fifo not empty interrupt?
+ if (xfer == fifo_not_empty_transfer)
+ devpriv->command3_bits |= ADC_FNE_INTR_EN_BIT;
+ else
+ devpriv->command3_bits &= ~ADC_FNE_INTR_EN_BIT;
+ devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+
+ // startup aquisition
+
+ // command2 reg
+ // use 2 cascaded counters for pacing
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->command2_bits |= CASCADE_BIT;
+ switch (cmd->start_src) {
+ case TRIG_EXT:
+ devpriv->command2_bits |= HWTRIG_BIT;
+ devpriv->command2_bits &= ~PRETRIG_BIT & ~SWTRIG_BIT;
+ break;
+ case TRIG_NOW:
+ devpriv->command2_bits |= SWTRIG_BIT;
+ devpriv->command2_bits &= ~PRETRIG_BIT & ~HWTRIG_BIT;
+ break;
+ default:
+ comedi_error(dev, "bug with start_src");
+ return -1;
+ break;
+ }
+ switch (cmd->stop_src) {
+ case TRIG_EXT:
+ devpriv->command2_bits |= HWTRIG_BIT | PRETRIG_BIT;
+ break;
+ case TRIG_COUNT:
+ case TRIG_NONE:
+ break;
+ default:
+ comedi_error(dev, "bug with stop_src");
+ return -1;
+ }
+ devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return 0;
+}
+
+/* interrupt service routine */
+static irqreturn_t labpc_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async;
+ struct comedi_cmd *cmd;
+
+ if (dev->attached == 0) {
+ comedi_error(dev, "premature interrupt");
+ return IRQ_HANDLED;
+ }
+
+ async = s->async;
+ cmd = &async->cmd;
+ async->events = 0;
+
+ // read board status
+ devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG);
+ if (thisboard->register_layout == labpc_1200_layout)
+ devpriv->status2_bits =
+ devpriv->read_byte(dev->iobase + STATUS2_REG);
+
+ if ((devpriv->status1_bits & (DMATC_BIT | TIMER_BIT | OVERFLOW_BIT |
+ OVERRUN_BIT | DATA_AVAIL_BIT)) == 0
+ && (devpriv->status2_bits & A1_TC_BIT) == 0
+ && (devpriv->status2_bits & FNHF_BIT)) {
+ return IRQ_NONE;
+ }
+
+ if (devpriv->status1_bits & OVERRUN_BIT) {
+ // clear error interrupt
+ devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ comedi_error(dev, "overrun");
+ return IRQ_HANDLED;
+ }
+
+ if (devpriv->current_transfer == isa_dma_transfer) {
+ // if a dma terminal count of external stop trigger has occurred
+ if (devpriv->status1_bits & DMATC_BIT ||
+ (thisboard->register_layout == labpc_1200_layout
+ && devpriv->status2_bits & A1_TC_BIT)) {
+ handle_isa_dma(dev);
+ }
+ } else
+ labpc_drain_fifo(dev);
+
+ if (devpriv->status1_bits & TIMER_BIT) {
+ comedi_error(dev, "handled timer interrupt?");
+ // clear it
+ devpriv->write_byte(0x1, dev->iobase + TIMER_CLEAR_REG);
+ }
+
+ if (devpriv->status1_bits & OVERFLOW_BIT) {
+ // clear error interrupt
+ devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ comedi_error(dev, "overflow");
+ return IRQ_HANDLED;
+ }
+ // handle external stop trigger
+ if (cmd->stop_src == TRIG_EXT) {
+ if (devpriv->status2_bits & A1_TC_BIT) {
+ labpc_drain_dregs(dev);
+ labpc_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA;
+ }
+ }
+
+ /* TRIG_COUNT end of acquisition */
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (devpriv->count == 0) {
+ labpc_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA;
+ }
+ }
+
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+// read all available samples from ai fifo
+static int labpc_drain_fifo(struct comedi_device * dev)
+{
+ unsigned int lsb, msb;
+ short data;
+ struct comedi_async *async = dev->read_subdev->async;
+ const int timeout = 10000;
+ unsigned int i;
+
+ devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG);
+
+ for (i = 0; (devpriv->status1_bits & DATA_AVAIL_BIT) && i < timeout;
+ i++) {
+ // quit if we have all the data we want
+ if (async->cmd.stop_src == TRIG_COUNT) {
+ if (devpriv->count == 0)
+ break;
+ devpriv->count--;
+ }
+ lsb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+ msb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+ data = (msb << 8) | lsb;
+ cfc_write_to_buffer(dev->read_subdev, data);
+ devpriv->status1_bits =
+ devpriv->read_byte(dev->iobase + STATUS1_REG);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "ai timeout, fifo never empties");
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ return -1;
+ }
+
+ return 0;
+}
+
+static void labpc_drain_dma(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async = s->async;
+ int status;
+ unsigned long flags;
+ unsigned int max_points, num_points, residue, leftover;
+ int i;
+
+ status = devpriv->status1_bits;
+
+ flags = claim_dma_lock();
+ disable_dma(devpriv->dma_chan);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma_chan);
+
+ // figure out how many points to read
+ max_points = devpriv->dma_transfer_size / sample_size;
+ /* residue is the number of points left to be done on the dma
+ * transfer. It should always be zero at this point unless
+ * the stop_src is set to external triggering.
+ */
+ residue = get_dma_residue(devpriv->dma_chan) / sample_size;
+ num_points = max_points - residue;
+ if (devpriv->count < num_points && async->cmd.stop_src == TRIG_COUNT)
+ num_points = devpriv->count;
+
+ // figure out how many points will be stored next time
+ leftover = 0;
+ if (async->cmd.stop_src != TRIG_COUNT) {
+ leftover = devpriv->dma_transfer_size / sample_size;
+ } else if (devpriv->count > num_points) {
+ leftover = devpriv->count - num_points;
+ if (leftover > max_points)
+ leftover = max_points;
+ }
+
+ /* write data to comedi buffer */
+ for (i = 0; i < num_points; i++) {
+ cfc_write_to_buffer(s, devpriv->dma_buffer[i]);
+ }
+ if (async->cmd.stop_src == TRIG_COUNT)
+ devpriv->count -= num_points;
+
+ // set address and count for next transfer
+ set_dma_addr(devpriv->dma_chan, virt_to_bus(devpriv->dma_buffer));
+ set_dma_count(devpriv->dma_chan, leftover * sample_size);
+ release_dma_lock(flags);
+
+ async->events |= COMEDI_CB_BLOCK;
+}
+
+static void handle_isa_dma(struct comedi_device * dev)
+{
+ labpc_drain_dma(dev);
+
+ enable_dma(devpriv->dma_chan);
+
+ // clear dma tc interrupt
+ devpriv->write_byte(0x1, dev->iobase + DMATC_CLEAR_REG);
+}
+
+/* makes sure all data aquired by board is transfered to comedi (used
+ * when aquisition is terminated by stop_src == TRIG_EXT). */
+static void labpc_drain_dregs(struct comedi_device * dev)
+{
+ if (devpriv->current_transfer == isa_dma_transfer)
+ labpc_drain_dma(dev);
+
+ labpc_drain_fifo(dev);
+}
+
+static int labpc_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int chan, range;
+ int lsb, msb;
+ int timeout = 1000;
+ unsigned long flags;
+
+ // disable timed conversions
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
+ devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // disable interrupt generation and dma
+ devpriv->command3_bits = 0;
+ devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+
+ /* set gain and channel */
+ devpriv->command1_bits = 0;
+ chan = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+ devpriv->command1_bits |= thisboard->ai_range_code[range];
+ // munge channel bits for differential/scan disabled mode
+ if (CR_AREF(insn->chanspec) == AREF_DIFF)
+ chan *= 2;
+ devpriv->command1_bits |= ADC_CHAN_BITS(chan);
+ devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
+
+ // setup command6 register for 1200 boards
+ if (thisboard->register_layout == labpc_1200_layout) {
+ // reference inputs to ground or common?
+ if (CR_AREF(insn->chanspec) != AREF_GROUND)
+ devpriv->command6_bits |= ADC_COMMON_BIT;
+ else
+ devpriv->command6_bits &= ~ADC_COMMON_BIT;
+ // bipolar or unipolar range?
+ if (thisboard->ai_range_is_unipolar[range])
+ devpriv->command6_bits |= ADC_UNIP_BIT;
+ else
+ devpriv->command6_bits &= ~ADC_UNIP_BIT;
+ // don't interrupt on fifo half full
+ devpriv->command6_bits &= ~ADC_FHF_INTR_EN_BIT;
+ // don't enable interrupt on counter a1 terminal count?
+ devpriv->command6_bits &= ~A1_INTR_EN_BIT;
+ // write to register
+ devpriv->write_byte(devpriv->command6_bits,
+ dev->iobase + COMMAND6_REG);
+ }
+ // setup command4 register
+ devpriv->command4_bits = 0;
+ devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
+ // single-ended/differential
+ if (CR_AREF(insn->chanspec) == AREF_DIFF)
+ devpriv->command4_bits |= ADC_DIFF_BIT;
+ devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
+
+ // initialize pacer counter output to make sure it doesn't cause any problems
+ devpriv->write_byte(INIT_A0_BITS, dev->iobase + COUNTER_A_CONTROL_REG);
+
+ labpc_clear_adc_fifo(dev);
+
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ devpriv->write_byte(0x1, dev->iobase + ADC_CONVERT_REG);
+
+ for (i = 0; i < timeout; i++) {
+ if (devpriv->read_byte(dev->iobase +
+ STATUS1_REG) & DATA_AVAIL_BIT)
+ break;
+ comedi_udelay(1);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timeout");
+ return -ETIME;
+ }
+ lsb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+ msb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+ data[n] = (msb << 8) | lsb;
+ }
+
+ return n;
+}
+
+// analog output insn
+static int labpc_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel, range;
+ unsigned long flags;
+ int lsb, msb;
+
+ channel = CR_CHAN(insn->chanspec);
+
+ // turn off pacing of analog output channel
+ /* note: hardware bug in daqcard-1200 means pacing cannot
+ * be independently enabled/disabled for its the two channels */
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->command2_bits &= ~DAC_PACED_BIT(channel);
+ devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // set range
+ if (thisboard->register_layout == labpc_1200_layout) {
+ range = CR_RANGE(insn->chanspec);
+ if (range & AO_RANGE_IS_UNIPOLAR)
+ devpriv->command6_bits |= DAC_UNIP_BIT(channel);
+ else
+ devpriv->command6_bits &= ~DAC_UNIP_BIT(channel);
+ // write to register
+ devpriv->write_byte(devpriv->command6_bits,
+ dev->iobase + COMMAND6_REG);
+ }
+ // send data
+ lsb = data[0] & 0xff;
+ msb = (data[0] >> 8) & 0xff;
+ devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(channel));
+ devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(channel));
+
+ // remember value for readback
+ devpriv->ao_value[channel] = data[0];
+
+ return 1;
+}
+
+// analog output readback insn
+static int labpc_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int labpc_calib_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->caldac[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int labpc_calib_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel = CR_CHAN(insn->chanspec);
+
+ write_caldac(dev, channel, data[0]);
+ return 1;
+}
+
+static int labpc_eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->eeprom_data[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int labpc_eeprom_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel = CR_CHAN(insn->chanspec);
+ int ret;
+
+ // only allow writes to user area of eeprom
+ if (channel < 16 || channel > 127) {
+ printk("eeprom writes are only allowed to channels 16 through 127 (the pointer and user areas)");
+ return -EINVAL;
+ }
+
+ ret = labpc_eeprom_write(dev, channel, data[0]);
+ if (ret < 0)
+ return ret;
+
+ return 1;
+}
+
+// utility function that suggests a dma transfer size in bytes
+static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd)
+{
+ unsigned int size;
+ unsigned int freq;
+
+ if (cmd.convert_src == TRIG_TIMER)
+ freq = 1000000000 / cmd.convert_arg;
+ // return some default value
+ else
+ freq = 0xffffffff;
+
+ // make buffer fill in no more than 1/3 second
+ size = (freq / 3) * sample_size;
+
+ // set a minimum and maximum size allowed
+ if (size > dma_buffer_size)
+ size = dma_buffer_size - dma_buffer_size % sample_size;
+ else if (size < sample_size)
+ size = sample_size;
+
+ return size;
+}
+
+// figures out what counter values to use based on command
+static void labpc_adc_timing(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+ const int max_counter_value = 0x10000; // max value for 16 bit counter in mode 2
+ const int min_counter_value = 2; // min value for 16 bit counter in mode 2
+ unsigned int base_period;
+
+ // if both convert and scan triggers are TRIG_TIMER, then they both rely on counter b0
+ if (labpc_ai_convert_period(cmd) && labpc_ai_scan_period(cmd)) {
+ // pick the lowest b0 divisor value we can (for maximum input clock speed on convert and scan counters)
+ devpriv->divisor_b0 = (labpc_ai_scan_period(cmd) - 1) /
+ (LABPC_TIMER_BASE * max_counter_value) + 1;
+ if (devpriv->divisor_b0 < min_counter_value)
+ devpriv->divisor_b0 = min_counter_value;
+ if (devpriv->divisor_b0 > max_counter_value)
+ devpriv->divisor_b0 = max_counter_value;
+
+ base_period = LABPC_TIMER_BASE * devpriv->divisor_b0;
+
+ // set a0 for conversion frequency and b1 for scan frequency
+ switch (cmd->flags & TRIG_ROUND_MASK) {
+ default:
+ case TRIG_ROUND_NEAREST:
+ devpriv->divisor_a0 =
+ (labpc_ai_convert_period(cmd) +
+ (base_period / 2)) / base_period;
+ devpriv->divisor_b1 =
+ (labpc_ai_scan_period(cmd) +
+ (base_period / 2)) / base_period;
+ break;
+ case TRIG_ROUND_UP:
+ devpriv->divisor_a0 =
+ (labpc_ai_convert_period(cmd) + (base_period -
+ 1)) / base_period;
+ devpriv->divisor_b1 =
+ (labpc_ai_scan_period(cmd) + (base_period -
+ 1)) / base_period;
+ break;
+ case TRIG_ROUND_DOWN:
+ devpriv->divisor_a0 =
+ labpc_ai_convert_period(cmd) / base_period;
+ devpriv->divisor_b1 =
+ labpc_ai_scan_period(cmd) / base_period;
+ break;
+ }
+ // make sure a0 and b1 values are acceptable
+ if (devpriv->divisor_a0 < min_counter_value)
+ devpriv->divisor_a0 = min_counter_value;
+ if (devpriv->divisor_a0 > max_counter_value)
+ devpriv->divisor_a0 = max_counter_value;
+ if (devpriv->divisor_b1 < min_counter_value)
+ devpriv->divisor_b1 = min_counter_value;
+ if (devpriv->divisor_b1 > max_counter_value)
+ devpriv->divisor_b1 = max_counter_value;
+ // write corrected timings to command
+ labpc_set_ai_convert_period(cmd,
+ base_period * devpriv->divisor_a0);
+ labpc_set_ai_scan_period(cmd,
+ base_period * devpriv->divisor_b1);
+ // if only one TRIG_TIMER is used, we can employ the generic cascaded timing functions
+ } else if (labpc_ai_scan_period(cmd)) {
+ unsigned int scan_period;
+
+ scan_period = labpc_ai_scan_period(cmd);
+ /* calculate cascaded counter values that give desired scan timing */
+ i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
+ &(devpriv->divisor_b1), &(devpriv->divisor_b0),
+ &scan_period, cmd->flags & TRIG_ROUND_MASK);
+ labpc_set_ai_scan_period(cmd, scan_period);
+ } else if (labpc_ai_convert_period(cmd)) {
+ unsigned int convert_period;
+
+ convert_period = labpc_ai_convert_period(cmd);
+ /* calculate cascaded counter values that give desired conversion timing */
+ i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
+ &(devpriv->divisor_a0), &(devpriv->divisor_b0),
+ &convert_period, cmd->flags & TRIG_ROUND_MASK);
+ labpc_set_ai_convert_period(cmd, convert_period);
+ }
+}
+
+static int labpc_dio_mem_callback(int dir, int port, int data,
+ unsigned long iobase)
+{
+ if (dir) {
+ writeb(data, (void *)(iobase + port));
+ return 0;
+ } else {
+ return readb((void *)(iobase + port));
+ }
+}
+
+// lowlevel write to eeprom/dac
+static void labpc_serial_out(struct comedi_device * dev, unsigned int value,
+ unsigned int value_width)
+{
+ int i;
+
+ for (i = 1; i <= value_width; i++) {
+ // clear serial clock
+ devpriv->command5_bits &= ~SCLOCK_BIT;
+ // send bits most significant bit first
+ if (value & (1 << (value_width - i)))
+ devpriv->command5_bits |= SDATA_BIT;
+ else
+ devpriv->command5_bits &= ~SDATA_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits,
+ dev->iobase + COMMAND5_REG);
+ // set clock to load bit
+ devpriv->command5_bits |= SCLOCK_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits,
+ dev->iobase + COMMAND5_REG);
+ }
+}
+
+// lowlevel read from eeprom
+static unsigned int labpc_serial_in(struct comedi_device * dev)
+{
+ unsigned int value = 0;
+ int i;
+ const int value_width = 8; // number of bits wide values are
+
+ for (i = 1; i <= value_width; i++) {
+ // set serial clock
+ devpriv->command5_bits |= SCLOCK_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits,
+ dev->iobase + COMMAND5_REG);
+ // clear clock bit
+ devpriv->command5_bits &= ~SCLOCK_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits,
+ dev->iobase + COMMAND5_REG);
+ // read bits most significant bit first
+ comedi_udelay(1);
+ devpriv->status2_bits =
+ devpriv->read_byte(dev->iobase + STATUS2_REG);
+ if (devpriv->status2_bits & EEPROM_OUT_BIT) {
+ value |= 1 << (value_width - i);
+ }
+ }
+
+ return value;
+}
+
+static unsigned int labpc_eeprom_read(struct comedi_device * dev, unsigned int address)
+{
+ unsigned int value;
+ const int read_instruction = 0x3; // bits to tell eeprom to expect a read
+ const int write_length = 8; // 8 bit write lengths to eeprom
+
+ // enable read/write to eeprom
+ devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->command5_bits |= EEPROM_EN_BIT | EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ // send read instruction
+ labpc_serial_out(dev, read_instruction, write_length);
+ // send 8 bit address to read from
+ labpc_serial_out(dev, address, write_length);
+ // read result
+ value = labpc_serial_in(dev);
+
+ // disable read/write to eeprom
+ devpriv->command5_bits &= ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ return value;
+}
+
+static unsigned int labpc_eeprom_write(struct comedi_device * dev,
+ unsigned int address, unsigned int value)
+{
+ const int write_enable_instruction = 0x6;
+ const int write_instruction = 0x2;
+ const int write_length = 8; // 8 bit write lengths to eeprom
+ const int write_in_progress_bit = 0x1;
+ const int timeout = 10000;
+ int i;
+
+ // make sure there isn't already a write in progress
+ for (i = 0; i < timeout; i++) {
+ if ((labpc_eeprom_read_status(dev) & write_in_progress_bit) ==
+ 0)
+ break;
+ }
+ if (i == timeout) {
+ comedi_error(dev, "eeprom write timed out");
+ return -ETIME;
+ }
+ // update software copy of eeprom
+ devpriv->eeprom_data[address] = value;
+
+ // enable read/write to eeprom
+ devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->command5_bits |= EEPROM_EN_BIT | EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ // send write_enable instruction
+ labpc_serial_out(dev, write_enable_instruction, write_length);
+ devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ // send write instruction
+ devpriv->command5_bits |= EEPROM_EN_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ labpc_serial_out(dev, write_instruction, write_length);
+ // send 8 bit address to write to
+ labpc_serial_out(dev, address, write_length);
+ // write value
+ labpc_serial_out(dev, value, write_length);
+ devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ // disable read/write to eeprom
+ devpriv->command5_bits &= ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ return 0;
+}
+
+static unsigned int labpc_eeprom_read_status(struct comedi_device * dev)
+{
+ unsigned int value;
+ const int read_status_instruction = 0x5;
+ const int write_length = 8; // 8 bit write lengths to eeprom
+
+ // enable read/write to eeprom
+ devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->command5_bits |= EEPROM_EN_BIT | EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ // send read status instruction
+ labpc_serial_out(dev, read_status_instruction, write_length);
+ // read result
+ value = labpc_serial_in(dev);
+
+ // disable read/write to eeprom
+ devpriv->command5_bits &= ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ return value;
+}
+
+// writes to 8 bit calibration dacs
+static void write_caldac(struct comedi_device * dev, unsigned int channel,
+ unsigned int value)
+{
+ if (value == devpriv->caldac[channel])
+ return;
+ devpriv->caldac[channel] = value;
+
+ // clear caldac load bit and make sure we don't write to eeprom
+ devpriv->command5_bits &=
+ ~CALDAC_LOAD_BIT & ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ // write 4 bit channel
+ labpc_serial_out(dev, channel, 4);
+ // write 8 bit caldac value
+ labpc_serial_out(dev, value, 8);
+
+ // set and clear caldac bit to load caldac value
+ devpriv->command5_bits |= CALDAC_LOAD_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->command5_bits &= ~CALDAC_LOAD_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+}
+
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_labpc, labpc_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_labpc);
+#endif
+
+EXPORT_SYMBOL_GPL(labpc_common_attach);
+EXPORT_SYMBOL_GPL(labpc_common_detach);
+EXPORT_SYMBOL_GPL(range_labpc_1200_ai);
+EXPORT_SYMBOL_GPL(labpc_1200_ai_gain_bits);
+EXPORT_SYMBOL_GPL(labpc_1200_is_unipolar);
diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h
new file mode 100644
index 00000000000..b44b0d3d02f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_labpc.h
@@ -0,0 +1,85 @@
+/*
+ ni_labpc.h
+
+ Header for ni_labpc.c and ni_labpc_cs.c
+
+ Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _NI_LABPC_H
+#define _NI_LABPC_H
+
+#define EEPROM_SIZE 256 // 256 byte eeprom
+#define NUM_AO_CHAN 2 // boards have two analog output channels
+
+enum labpc_bustype { isa_bustype, pci_bustype, pcmcia_bustype };
+enum labpc_register_layout { labpc_plus_layout, labpc_1200_layout };
+enum transfer_type { fifo_not_empty_transfer, fifo_half_full_transfer,
+ isa_dma_transfer };
+
+typedef struct labpc_board_struct {
+ const char *name;
+ int device_id; // device id for pci and pcmcia boards
+ int ai_speed; // maximum input speed in nanoseconds
+ enum labpc_bustype bustype; // ISA/PCI/etc.
+ enum labpc_register_layout register_layout; // 1200 has extra registers compared to pc+
+ int has_ao; // has analog output true/false
+ const struct comedi_lrange *ai_range_table;
+ const int *ai_range_code;
+ const int *ai_range_is_unipolar;
+ unsigned ai_scan_up:1; // board can auto scan up in ai channels, not just down
+ unsigned memory_mapped_io:1; /* uses memory mapped io instead of ioports */
+} labpc_board;
+
+typedef struct {
+ struct mite_struct *mite; // for mite chip on pci-1200
+ volatile unsigned long long count; /* number of data points left to be taken */
+ unsigned int ao_value[NUM_AO_CHAN]; // software copy of analog output values
+ // software copys of bits written to command registers
+ volatile unsigned int command1_bits;
+ volatile unsigned int command2_bits;
+ volatile unsigned int command3_bits;
+ volatile unsigned int command4_bits;
+ volatile unsigned int command5_bits;
+ volatile unsigned int command6_bits;
+ // store last read of board status registers
+ volatile unsigned int status1_bits;
+ volatile unsigned int status2_bits;
+ unsigned int divisor_a0; /* value to load into board's counter a0 (conversion pacing) for timed conversions */
+ unsigned int divisor_b0; /* value to load into board's counter b0 (master) for timed conversions */
+ unsigned int divisor_b1; /* value to load into board's counter b1 (scan pacing) for timed conversions */
+ unsigned int dma_chan; // dma channel to use
+ u16 *dma_buffer; // buffer ai will dma into
+ unsigned int dma_transfer_size; // transfer size in bytes for current transfer
+ enum transfer_type current_transfer; // we are using dma/fifo-half-full/etc.
+ unsigned int eeprom_data[EEPROM_SIZE]; // stores contents of board's eeprom
+ unsigned int caldac[16]; // stores settings of calibration dacs
+ // function pointers so we can use inb/outb or readb/writeb as appropriate
+ unsigned int (*read_byte) (unsigned long address);
+ void (*write_byte) (unsigned int byte, unsigned long address);
+} labpc_private;
+
+int labpc_common_attach(struct comedi_device * dev, unsigned long iobase,
+ unsigned int irq, unsigned int dma);
+int labpc_common_detach(struct comedi_device * dev);
+
+extern const int labpc_1200_is_unipolar[];
+extern const int labpc_1200_ai_gain_bits[];
+extern const struct comedi_lrange range_labpc_1200_ai;
+
+#endif /* _NI_LABPC_H */
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
new file mode 100644
index 00000000000..ac0ce2f58f5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -0,0 +1,573 @@
+/*
+ comedi/drivers/ni_labpc_cs.c
+ Driver for National Instruments daqcard-1200 boards
+ Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ PCMCIA crap is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13
+ from the pcmcia package.
+ The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
+ <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
+ are Copyright (C) 1999 David A. Hinds.
+
+ 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.
+
+************************************************************************
+*/
+/*
+Driver: ni_labpc_cs
+Description: National Instruments Lab-PC (& compatibles)
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [National Instruments] DAQCard-1200 (daqcard-1200)
+Status: works
+
+Thanks go to Fredrik Lingvall for much testing and perseverance in
+helping to debug daqcard-1200 support.
+
+The 1200 series boards have onboard calibration dacs for correcting
+analog input/output offsets and gains. The proper settings for these
+caldacs are stored on the board's eeprom. To read the caldac values
+from the eeprom and store them into a file that can be then be used by
+comedilib, use the comedi_calibrate program.
+
+Configuration options:
+ none
+
+The daqcard-1200 has quirky chanlist requirements
+when scanning multiple channels. Multiple channel scan
+sequence must start at highest channel, then decrement down to
+channel 0. Chanlists consisting of all one channel
+are also legal, and allow you to pace conversions in bursts.
+
+*/
+
+/*
+
+NI manuals:
+340988a (daqcard-1200)
+
+*/
+
+#undef LABPC_DEBUG
+//#define LABPC_DEBUG // enable debugging messages
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "8253.h"
+#include "8255.h"
+#include "comedi_fc.h"
+#include "ni_labpc.h"
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+static struct pcmcia_device *pcmcia_cur_dev = NULL;
+
+static int labpc_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+
+static const labpc_board labpc_cs_boards[] = {
+ {
+ name: "daqcard-1200",
+ device_id:0x103, // 0x10b is manufacturer id, 0x103 is device id
+ ai_speed:10000,
+ bustype: pcmcia_bustype,
+ register_layout:labpc_1200_layout,
+ has_ao: 1,
+ ai_range_table:&range_labpc_1200_ai,
+ ai_range_code:labpc_1200_ai_gain_bits,
+ ai_range_is_unipolar:labpc_1200_is_unipolar,
+ ai_scan_up:0,
+ memory_mapped_io:0,
+ },
+ /* duplicate entry, to support using alternate name */
+ {
+ name: "ni_labpc_cs",
+ device_id:0x103,
+ ai_speed:10000,
+ bustype: pcmcia_bustype,
+ register_layout:labpc_1200_layout,
+ has_ao: 1,
+ ai_range_table:&range_labpc_1200_ai,
+ ai_range_code:labpc_1200_ai_gain_bits,
+ ai_range_is_unipolar:labpc_1200_is_unipolar,
+ ai_scan_up:0,
+ memory_mapped_io:0,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const labpc_board *)dev->board_ptr)
+
+static struct comedi_driver driver_labpc_cs = {
+ .driver_name = "ni_labpc_cs",
+ .module = THIS_MODULE,
+ .attach = &labpc_attach,
+ .detach = &labpc_common_detach,
+ .num_names = sizeof(labpc_cs_boards) / sizeof(labpc_board),
+ .board_name = &labpc_cs_boards[0].name,
+ .offset = sizeof(labpc_board),
+};
+
+static int labpc_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned long iobase = 0;
+ unsigned int irq = 0;
+ struct pcmcia_device *link;
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(labpc_private)) < 0)
+ return -ENOMEM;
+
+ // get base address, irq etc. based on bustype
+ switch (thisboard->bustype) {
+ case pcmcia_bustype:
+ link = pcmcia_cur_dev; /* XXX hack */
+ if (!link)
+ return -EIO;
+ iobase = link->io.BasePort1;
+ irq = link->irq.AssignedIRQ;
+ break;
+ default:
+ printk("bug! couldn't determine board type\n");
+ return -EINVAL;
+ break;
+ }
+ return labpc_common_attach(dev, iobase, irq, 0);
+}
+
+/*
+ All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
+ you do not define PCMCIA_DEBUG at all, all the debug code will be
+ left out. If you compile with PCMCIA_DEBUG=0, the debug code will
+ be present but disabled -- but it can then be enabled for specific
+ modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static const char *version =
+ "ni_labpc.c, based on dummy_cs.c 1.31 2001/08/24 12:13:13";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+/*
+ The event() function is this driver's Card Services event handler.
+ It will be called by Card Services when an appropriate card status
+ event is received. The config() and release() entry points are
+ used to configure or release a socket, in response to card
+ insertion and ejection events. They are invoked from the dummy
+ event handler.
+
+ Kernel version 2.6.16 upwards uses suspend() and resume() functions
+ instead of an event() function.
+*/
+
+static void labpc_config(struct pcmcia_device *link);
+static void labpc_release(struct pcmcia_device *link);
+static int labpc_cs_suspend(struct pcmcia_device *p_dev);
+static int labpc_cs_resume(struct pcmcia_device *p_dev);
+
+/*
+ The attach() and detach() entry points are used to create and destroy
+ "instances" of the driver, where each instance represents everything
+ needed to manage one actual PCMCIA card.
+*/
+
+static int labpc_cs_attach(struct pcmcia_device *);
+static void labpc_cs_detach(struct pcmcia_device *);
+
+/*
+ You'll also need to prototype all the functions that will actually
+ be used to talk to your device. See 'memory_cs' for a good example
+ of a fully self-sufficient driver; the other drivers rely more or
+ less on other parts of the kernel.
+*/
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static const dev_info_t dev_info = "daqcard-1200";
+
+typedef struct local_info_t {
+ struct pcmcia_device *link;
+ dev_node_t node;
+ int stop;
+ struct bus_operations *bus;
+} local_info_t;
+
+/*======================================================================
+
+ labpc_cs_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+
+ The dev_link structure is initialized, but we don't actually
+ configure the card at this point -- we wait until we receive a
+ card insertion event.
+
+======================================================================*/
+
+static int labpc_cs_attach(struct pcmcia_device *link)
+{
+ local_info_t *local;
+
+ DEBUG(0, "labpc_cs_attach()\n");
+
+ /* Allocate space for private device-specific data */
+ local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
+ if (!local)
+ return -ENOMEM;
+ local->link = link;
+ link->priv = local;
+
+ /* Interrupt setup */
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE;
+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_PULSE_ID;
+ link->irq.Handler = NULL;
+
+ /*
+ General socket configuration defaults can go here. In this
+ client, we assume very little, and rely on the CIS for almost
+ everything. In most clients, many details (i.e., number, sizes,
+ and attributes of IO windows) are fixed by the nature of the
+ device, and can be hard-wired here.
+ */
+ link->conf.Attributes = 0;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ pcmcia_cur_dev = link;
+
+ labpc_config(link);
+
+ return 0;
+} /* labpc_cs_attach */
+
+/*======================================================================
+
+ This deletes a driver "instance". The device is de-registered
+ with Card Services. If it has been released, all local data
+ structures are freed. Otherwise, the structures will be freed
+ when the device is released.
+
+======================================================================*/
+
+static void labpc_cs_detach(struct pcmcia_device *link)
+{
+ DEBUG(0, "labpc_cs_detach(0x%p)\n", link);
+
+ /*
+ If the device is currently configured and active, we won't
+ actually delete it yet. Instead, it is marked so that when
+ the release() function is called, that will trigger a proper
+ detach().
+ */
+ if (link->dev_node) {
+ ((local_info_t *) link->priv)->stop = 1;
+ labpc_release(link);
+ }
+
+ /* This points to the parent local_info_t struct */
+ if (link->priv)
+ kfree(link->priv);
+
+} /* labpc_cs_detach */
+
+/*======================================================================
+
+ labpc_config() is scheduled to run after a CARD_INSERTION event
+ is received, to configure the PCMCIA socket, and to make the
+ device available to the system.
+
+======================================================================*/
+
+static void labpc_config(struct pcmcia_device *link)
+{
+ local_info_t *dev = link->priv;
+ tuple_t tuple;
+ cisparse_t parse;
+ int last_ret;
+ u_char buf[64];
+ win_req_t req;
+ memreq_t map;
+ cistpl_cftable_entry_t dflt = { 0 };
+
+ DEBUG(0, "labpc_config(0x%p)\n", link);
+
+ /*
+ This reads the card's CONFIG tuple to find its configuration
+ registers.
+ */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple))) {
+ cs_error(link, GetTupleData, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_parse_tuple(&tuple, &parse))) {
+ cs_error(link, ParseTuple, last_ret);
+ goto cs_failed;
+ }
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+ /*
+ In this loop, we scan the CIS for configuration table entries,
+ each of which describes a valid card configuration, including
+ voltage, IO window, memory window, and interrupt settings.
+
+ We make no assumptions about the card to be configured: we use
+ just the information available in the CIS. In an ideal world,
+ this would work for any PCMCIA card, but it requires a complete
+ and accurate CIS. In practice, a driver usually "knows" most of
+ these things without consulting the CIS, and most client drivers
+ will only use the CIS to fill in implementation-defined details.
+ */
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ while (1) {
+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ if (pcmcia_get_tuple_data(link, &tuple))
+ goto next_entry;
+ if (pcmcia_parse_tuple(&tuple, &parse))
+ goto next_entry;
+
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ if (cfg->index == 0)
+ goto next_entry;
+ link->conf.ConfigIndex = cfg->index;
+
+ /* Does this card need audio output? */
+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ link->conf.Attributes |= CONF_ENABLE_SPKR;
+ link->conf.Status = CCSR_AUDIO_ENA;
+ }
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(link, &link->io))
+ goto next_entry;
+ }
+
+ if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
+ cistpl_mem_t *mem =
+ (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
+ req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+ req.Attributes |= WIN_ENABLE;
+ req.Base = mem->win[0].host_addr;
+ req.Size = mem->win[0].len;
+ if (req.Size < 0x1000)
+ req.Size = 0x1000;
+ req.AccessSpeed = 0;
+ link->win = (window_handle_t) link;
+ if (pcmcia_request_window(&link, &req, &link->win))
+ goto next_entry;
+ map.Page = 0;
+ map.CardOffset = mem->win[0].card_addr;
+ if (pcmcia_map_mem_page(link->win, &map))
+ goto next_entry;
+ }
+ /* If we got this far, we're cool! */
+ break;
+
+ next_entry:
+ if ((last_ret = pcmcia_get_next_tuple(link, &tuple))) {
+ cs_error(link, GetNextTuple, last_ret);
+ goto cs_failed;
+ }
+ }
+
+ /*
+ 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 ((last_ret = pcmcia_request_irq(link, &link->irq))) {
+ cs_error(link, RequestIRQ, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping, and putting the
+ card and host interface into "Memory and IO" mode.
+ */
+ if ((last_ret = pcmcia_request_configuration(link, &link->conf))) {
+ cs_error(link, RequestConfiguration, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ At this point, the dev_node_t structure(s) need to be
+ initialized and arranged in a linked list at link->dev.
+ */
+ sprintf(dev->node.dev_name, "daqcard-1200");
+ dev->node.major = dev->node.minor = 0;
+ link->dev_node = &dev->node;
+
+ /* Finally, report what we've done */
+ printk(KERN_INFO "%s: index 0x%02x",
+ dev->node.dev_name, link->conf.ConfigIndex);
+ 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);
+ if (link->win)
+ printk(", mem 0x%06lx-0x%06lx", req.Base,
+ req.Base + req.Size - 1);
+ printk("\n");
+
+ return;
+
+ cs_failed:
+ labpc_release(link);
+
+} /* labpc_config */
+
+static void labpc_release(struct pcmcia_device *link)
+{
+ DEBUG(0, "labpc_release(0x%p)\n", link);
+
+ pcmcia_disable_device(link);
+} /* labpc_release */
+
+/*======================================================================
+
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received.
+
+ When a CARD_REMOVAL event is received, we immediately set a
+ private flag to block future accesses to this device. All the
+ functions that actually access the device should check this flag
+ to make sure the card is still present.
+
+======================================================================*/
+
+static int labpc_cs_suspend(struct pcmcia_device *link)
+{
+ local_info_t *local = link->priv;
+
+ /* Mark the device as stopped, to block IO until later */
+ local->stop = 1;
+ return 0;
+} /* labpc_cs_suspend */
+
+static int labpc_cs_resume(struct pcmcia_device *link)
+{
+ local_info_t *local = link->priv;
+
+ local->stop = 0;
+ return 0;
+} /* labpc_cs_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id labpc_cs_ids[] = {
+ /* N.B. These IDs should match those in labpc_cs_boards (ni_labpc.c) */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0103), /* daqcard-1200 */
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, labpc_cs_ids);
+
+struct pcmcia_driver labpc_cs_driver = {
+ .probe = labpc_cs_attach,
+ .remove = labpc_cs_detach,
+ .suspend = labpc_cs_suspend,
+ .resume = labpc_cs_resume,
+ .id_table = labpc_cs_ids,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+static int __init init_labpc_cs(void)
+{
+ DEBUG(0, "%s\n", version);
+ pcmcia_register_driver(&labpc_cs_driver);
+ return 0;
+}
+
+static void __exit exit_labpc_cs(void)
+{
+ DEBUG(0, "ni_labpc: unloading\n");
+ pcmcia_unregister_driver(&labpc_cs_driver);
+}
+
+int __init labpc_init_module(void)
+{
+ int ret;
+
+ ret = init_labpc_cs();
+ if (ret < 0)
+ return ret;
+
+ return comedi_driver_register(&driver_labpc_cs);
+}
+
+void __exit labpc_exit_module(void)
+{
+ exit_labpc_cs();
+ comedi_driver_unregister(&driver_labpc_cs);
+}
+
+MODULE_LICENSE("GPL");
+module_init(labpc_init_module);
+module_exit(labpc_exit_module);
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
new file mode 100644
index 00000000000..542bd0dcd44
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -0,0 +1,5862 @@
+/*
+ comedi/drivers/ni_mio_common.c
+ Hardware driver for DAQ-STC based boards
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
+ Copyright (C) 2002-2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/*
+ This file is meant to be included by another file, e.g.,
+ ni_atmio.c or ni_pcimio.c.
+
+ Interrupt support originally added by Truxton Fulton
+ <trux@truxton.com>
+
+ References (from ftp://ftp.natinst.com/support/manuals):
+
+ 340747b.pdf AT-MIO E series Register Level Programmer Manual
+ 341079b.pdf PCI E Series RLPM
+ 340934b.pdf DAQ-STC reference manual
+ 67xx and 611x registers (from http://www.ni.com/pdf/daq/us)
+ release_ni611x.pdf
+ release_ni67xx.pdf
+ Other possibly relevant info:
+
+ 320517c.pdf User manual (obsolete)
+ 320517f.pdf User manual (new)
+ 320889a.pdf delete
+ 320906c.pdf maximum signal ratings
+ 321066a.pdf about 16x
+ 321791a.pdf discontinuation of at-mio-16e-10 rev. c
+ 321808a.pdf about at-mio-16e-10 rev P
+ 321837a.pdf discontinuation of at-mio-16de-10 rev d
+ 321838a.pdf about at-mio-16de-10 rev N
+
+ ISSUES:
+
+ - the interrupt routine needs to be cleaned up
+
+ 2006-02-07: S-Series PCI-6143: Support has been added but is not
+ fully tested as yet. Terry Barnaby, BEAM Ltd.
+*/
+
+//#define DEBUG_INTERRUPT
+//#define DEBUG_STATUS_A
+//#define DEBUG_STATUS_B
+
+#include "8255.h"
+#include "mite.h"
+#include "comedi_fc.h"
+
+#ifndef MDPRINTK
+#define MDPRINTK(format,args...)
+#endif
+
+/* A timeout count */
+#define NI_TIMEOUT 1000
+static const unsigned old_RTSI_clock_channel = 7;
+
+/* Note: this table must match the ai_gain_* definitions */
+static const short ni_gainlkup[][16] = {
+ [ai_gain_16] = {0, 1, 2, 3, 4, 5, 6, 7,
+ 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107},
+ [ai_gain_8] = {1, 2, 4, 7, 0x101, 0x102, 0x104, 0x107},
+ [ai_gain_14] = {1, 2, 3, 4, 5, 6, 7,
+ 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107},
+ [ai_gain_4] = {0, 1, 4, 7},
+ [ai_gain_611x] = {0x00a, 0x00b, 0x001, 0x002,
+ 0x003, 0x004, 0x005, 0x006},
+ [ai_gain_622x] = {0, 1, 4, 5},
+ [ai_gain_628x] = {1, 2, 3, 4, 5, 6, 7},
+ [ai_gain_6143] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+};
+
+static const struct comedi_lrange range_ni_E_ai = { 16, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1, 1),
+ RANGE(-0.5, 0.5),
+ RANGE(-0.25, 0.25),
+ RANGE(-0.1, 0.1),
+ RANGE(-0.05, 0.05),
+ RANGE(0, 20),
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 2),
+ RANGE(0, 1),
+ RANGE(0, 0.5),
+ RANGE(0, 0.2),
+ RANGE(0, 0.1),
+ }
+};
+static const struct comedi_lrange range_ni_E_ai_limited = { 8, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-1, 1),
+ RANGE(-0.1, 0.1),
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 1),
+ RANGE(0, 0.1),
+ }
+};
+static const struct comedi_lrange range_ni_E_ai_limited14 = { 14, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2, 2),
+ RANGE(-1, 1),
+ RANGE(-0.5, 0.5),
+ RANGE(-0.2, 0.2),
+ RANGE(-0.1, 0.1),
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 2),
+ RANGE(0, 1),
+ RANGE(0, 0.5),
+ RANGE(0, 0.2),
+ RANGE(0, 0.1),
+ }
+};
+static const struct comedi_lrange range_ni_E_ai_bipolar4 = { 4, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-0.5, 0.5),
+ RANGE(-0.05, 0.05),
+ }
+};
+static const struct comedi_lrange range_ni_E_ai_611x = { 8, {
+ RANGE(-50, 50),
+ RANGE(-20, 20),
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2, 2),
+ RANGE(-1, 1),
+ RANGE(-0.5, 0.5),
+ RANGE(-0.2, 0.2),
+ }
+};
+static const struct comedi_lrange range_ni_M_ai_622x = { 4, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-1, 1),
+ RANGE(-0.2, 0.2),
+ }
+};
+static const struct comedi_lrange range_ni_M_ai_628x = { 7, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2, 2),
+ RANGE(-1, 1),
+ RANGE(-0.5, 0.5),
+ RANGE(-0.2, 0.2),
+ RANGE(-0.1, 0.1),
+ }
+};
+static const struct comedi_lrange range_ni_S_ai_6143 = { 1, {
+ RANGE(-5, +5),
+ }
+};
+static const struct comedi_lrange range_ni_E_ao_ext = { 4, {
+ RANGE(-10, 10),
+ RANGE(0, 10),
+ RANGE_ext(-1, 1),
+ RANGE_ext(0, 1),
+ }
+};
+
+static const struct comedi_lrange *const ni_range_lkup[] = {
+ [ai_gain_16] = &range_ni_E_ai,
+ [ai_gain_8] = &range_ni_E_ai_limited,
+ [ai_gain_14] = &range_ni_E_ai_limited14,
+ [ai_gain_4] = &range_ni_E_ai_bipolar4,
+ [ai_gain_611x] = &range_ni_E_ai_611x,
+ [ai_gain_622x] = &range_ni_M_ai_622x,
+ [ai_gain_628x] = &range_ni_M_ai_628x,
+ [ai_gain_6143] = &range_ni_S_ai_6143
+};
+
+static int ni_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_cdio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int ni_cdio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ni_cdio_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void handle_cdio_interrupt(struct comedi_device * dev);
+static int ni_cdo_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum);
+
+static int ni_serial_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_serial_hw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned char data_out, unsigned char *data_in);
+static int ni_serial_sw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned char data_out, unsigned char *data_in);
+
+static int ni_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int ni_eeprom_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_m_series_eeprom_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int ni_pfi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_pfi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static unsigned ni_old_get_pfi_routing(struct comedi_device * dev, unsigned chan);
+
+static void ni_rtsi_init(struct comedi_device * dev);
+static int ni_rtsi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_rtsi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static void caldac_setup(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ni_read_eeprom(struct comedi_device * dev, int addr);
+
+#ifdef DEBUG_STATUS_A
+static void ni_mio_print_status_a(int status);
+#else
+#define ni_mio_print_status_a(a)
+#endif
+#ifdef DEBUG_STATUS_B
+static void ni_mio_print_status_b(int status);
+#else
+#define ni_mio_print_status_b(a)
+#endif
+
+static int ni_ai_reset(struct comedi_device * dev, struct comedi_subdevice * s);
+#ifndef PCIDMA
+static void ni_handle_fifo_half_full(struct comedi_device * dev);
+static int ni_ao_fifo_half_empty(struct comedi_device * dev, struct comedi_subdevice * s);
+#endif
+static void ni_handle_fifo_dregs(struct comedi_device * dev);
+static int ni_ai_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum);
+static void ni_load_channelgain_list(struct comedi_device * dev, unsigned int n_chan,
+ unsigned int *list);
+static void shutdown_ai_command(struct comedi_device * dev);
+
+static int ni_ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum);
+
+static int ni_ao_reset(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static int ni_8255_callback(int dir, int port, int data, unsigned long arg);
+
+static int ni_gpct_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_gpct_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_gpct_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ni_gpct_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int ni_gpct_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void handle_gpct_interrupt(struct comedi_device * dev,
+ unsigned short counter_index);
+
+static int init_cs5529(struct comedi_device * dev);
+static int cs5529_do_conversion(struct comedi_device * dev, unsigned short *data);
+static int cs5529_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+#ifdef NI_CS5529_DEBUG
+static unsigned int cs5529_config_read(struct comedi_device * dev,
+ unsigned int reg_select_bits);
+#endif
+static void cs5529_config_write(struct comedi_device * dev, unsigned int value,
+ unsigned int reg_select_bits);
+
+static int ni_m_series_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_6143_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int ni_set_master_clock(struct comedi_device * dev, unsigned source,
+ unsigned period_ns);
+static void ack_a_interrupt(struct comedi_device * dev, unsigned short a_status);
+static void ack_b_interrupt(struct comedi_device * dev, unsigned short b_status);
+
+enum aimodes {
+ AIMODE_NONE = 0,
+ AIMODE_HALF_FULL = 1,
+ AIMODE_SCAN = 2,
+ AIMODE_SAMPLE = 3,
+};
+
+enum ni_common_subdevices {
+ NI_AI_SUBDEV,
+ NI_AO_SUBDEV,
+ NI_DIO_SUBDEV,
+ NI_8255_DIO_SUBDEV,
+ NI_UNUSED_SUBDEV,
+ NI_CALIBRATION_SUBDEV,
+ NI_EEPROM_SUBDEV,
+ NI_PFI_DIO_SUBDEV,
+ NI_CS5529_CALIBRATION_SUBDEV,
+ NI_SERIAL_SUBDEV,
+ NI_RTSI_SUBDEV,
+ NI_GPCT0_SUBDEV,
+ NI_GPCT1_SUBDEV,
+ NI_FREQ_OUT_SUBDEV,
+ NI_NUM_SUBDEVICES
+};
+static inline unsigned NI_GPCT_SUBDEV(unsigned counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NI_GPCT0_SUBDEV;
+ break;
+ case 1:
+ return NI_GPCT1_SUBDEV;
+ break;
+ default:
+ break;
+ }
+ BUG();
+ return NI_GPCT0_SUBDEV;
+}
+
+enum timebase_nanoseconds {
+ TIMEBASE_1_NS = 50,
+ TIMEBASE_2_NS = 10000
+};
+
+#define SERIAL_DISABLED 0
+#define SERIAL_600NS 600
+#define SERIAL_1_2US 1200
+#define SERIAL_10US 10000
+
+static const int num_adc_stages_611x = 3;
+
+static void handle_a_interrupt(struct comedi_device * dev, unsigned short status,
+ unsigned ai_mite_status);
+static void handle_b_interrupt(struct comedi_device * dev, unsigned short status,
+ unsigned ao_mite_status);
+static void get_last_sample_611x(struct comedi_device * dev);
+static void get_last_sample_6143(struct comedi_device * dev);
+
+static inline void ni_set_bitfield(struct comedi_device * dev, int reg,
+ unsigned bit_mask, unsigned bit_values)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
+ switch (reg) {
+ case Interrupt_A_Enable_Register:
+ devpriv->int_a_enable_reg &= ~bit_mask;
+ devpriv->int_a_enable_reg |= bit_values & bit_mask;
+ devpriv->stc_writew(dev, devpriv->int_a_enable_reg,
+ Interrupt_A_Enable_Register);
+ break;
+ case Interrupt_B_Enable_Register:
+ devpriv->int_b_enable_reg &= ~bit_mask;
+ devpriv->int_b_enable_reg |= bit_values & bit_mask;
+ devpriv->stc_writew(dev, devpriv->int_b_enable_reg,
+ Interrupt_B_Enable_Register);
+ break;
+ case IO_Bidirection_Pin_Register:
+ devpriv->io_bidirection_pin_reg &= ~bit_mask;
+ devpriv->io_bidirection_pin_reg |= bit_values & bit_mask;
+ devpriv->stc_writew(dev, devpriv->io_bidirection_pin_reg,
+ IO_Bidirection_Pin_Register);
+ break;
+ case AI_AO_Select:
+ devpriv->ai_ao_select_reg &= ~bit_mask;
+ devpriv->ai_ao_select_reg |= bit_values & bit_mask;
+ ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
+ break;
+ case G0_G1_Select:
+ devpriv->g0_g1_select_reg &= ~bit_mask;
+ devpriv->g0_g1_select_reg |= bit_values & bit_mask;
+ ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
+ break;
+ default:
+ rt_printk("Warning %s() called with invalid register\n",
+ __FUNCTION__);
+ rt_printk("reg is %d\n", reg);
+ break;
+ }
+ mmiowb();
+ comedi_spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
+}
+
+#ifdef PCIDMA
+static int ni_ai_drain_dma(struct comedi_device * dev);
+
+/* DMA channel setup */
+
+// negative channel means no channel
+static inline void ni_set_ai_dma_channel(struct comedi_device * dev, int channel)
+{
+ unsigned bitfield;
+
+ if (channel >= 0) {
+ bitfield =
+ (ni_stc_dma_channel_select_bitfield(channel) <<
+ AI_DMA_Select_Shift) & AI_DMA_Select_Mask;
+ } else {
+ bitfield = 0;
+ }
+ ni_set_bitfield(dev, AI_AO_Select, AI_DMA_Select_Mask, bitfield);
+}
+
+// negative channel means no channel
+static inline void ni_set_ao_dma_channel(struct comedi_device * dev, int channel)
+{
+ unsigned bitfield;
+
+ if (channel >= 0) {
+ bitfield =
+ (ni_stc_dma_channel_select_bitfield(channel) <<
+ AO_DMA_Select_Shift) & AO_DMA_Select_Mask;
+ } else {
+ bitfield = 0;
+ }
+ ni_set_bitfield(dev, AI_AO_Select, AO_DMA_Select_Mask, bitfield);
+}
+
+// negative mite_channel means no channel
+static inline void ni_set_gpct_dma_channel(struct comedi_device * dev,
+ unsigned gpct_index, int mite_channel)
+{
+ unsigned bitfield;
+
+ if (mite_channel >= 0) {
+ bitfield = GPCT_DMA_Select_Bits(gpct_index, mite_channel);
+ } else {
+ bitfield = 0;
+ }
+ ni_set_bitfield(dev, G0_G1_Select, GPCT_DMA_Select_Mask(gpct_index),
+ bitfield);
+}
+
+// negative mite_channel means no channel
+static inline void ni_set_cdo_dma_channel(struct comedi_device * dev, int mite_channel)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
+ devpriv->cdio_dma_select_reg &= ~CDO_DMA_Select_Mask;
+ if (mite_channel >= 0) {
+ /*XXX just guessing ni_stc_dma_channel_select_bitfield() returns the right bits,
+ under the assumption the cdio dma selection works just like ai/ao/gpct.
+ Definitely works for dma channels 0 and 1. */
+ devpriv->cdio_dma_select_reg |=
+ (ni_stc_dma_channel_select_bitfield(mite_channel) <<
+ CDO_DMA_Select_Shift) & CDO_DMA_Select_Mask;
+ }
+ ni_writeb(devpriv->cdio_dma_select_reg, M_Offset_CDIO_DMA_Select);
+ mmiowb();
+ comedi_spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
+}
+
+static int ni_request_ai_mite_channel(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ BUG_ON(devpriv->ai_mite_chan);
+ devpriv->ai_mite_chan =
+ mite_request_channel(devpriv->mite, devpriv->ai_mite_ring);
+ if (devpriv->ai_mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+ flags);
+ comedi_error(dev,
+ "failed to reserve mite dma channel for analog input.");
+ return -EBUSY;
+ }
+ devpriv->ai_mite_chan->dir = COMEDI_INPUT;
+ ni_set_ai_dma_channel(dev, devpriv->ai_mite_chan->channel);
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+ return 0;
+}
+
+static int ni_request_ao_mite_channel(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ BUG_ON(devpriv->ao_mite_chan);
+ devpriv->ao_mite_chan =
+ mite_request_channel(devpriv->mite, devpriv->ao_mite_ring);
+ if (devpriv->ao_mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+ flags);
+ comedi_error(dev,
+ "failed to reserve mite dma channel for analog outut.");
+ return -EBUSY;
+ }
+ devpriv->ao_mite_chan->dir = COMEDI_OUTPUT;
+ ni_set_ao_dma_channel(dev, devpriv->ao_mite_chan->channel);
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+ return 0;
+}
+
+static int ni_request_gpct_mite_channel(struct comedi_device * dev,
+ unsigned gpct_index, enum comedi_io_direction direction)
+{
+ unsigned long flags;
+ struct mite_channel *mite_chan;
+
+ BUG_ON(gpct_index >= NUM_GPCT);
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ BUG_ON(devpriv->counter_dev->counters[gpct_index].mite_chan);
+ mite_chan =
+ mite_request_channel(devpriv->mite,
+ devpriv->gpct_mite_ring[gpct_index]);
+ if (mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+ flags);
+ comedi_error(dev,
+ "failed to reserve mite dma channel for counter.");
+ return -EBUSY;
+ }
+ mite_chan->dir = direction;
+ ni_tio_set_mite_channel(&devpriv->counter_dev->counters[gpct_index],
+ mite_chan);
+ ni_set_gpct_dma_channel(dev, gpct_index, mite_chan->channel);
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+ return 0;
+}
+
+#endif // PCIDMA
+
+static int ni_request_cdo_mite_channel(struct comedi_device * dev)
+{
+#ifdef PCIDMA
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ BUG_ON(devpriv->cdo_mite_chan);
+ devpriv->cdo_mite_chan =
+ mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring);
+ if (devpriv->cdo_mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+ flags);
+ comedi_error(dev,
+ "failed to reserve mite dma channel for correlated digital outut.");
+ return -EBUSY;
+ }
+ devpriv->cdo_mite_chan->dir = COMEDI_OUTPUT;
+ ni_set_cdo_dma_channel(dev, devpriv->cdo_mite_chan->channel);
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+ return 0;
+}
+
+static void ni_release_ai_mite_channel(struct comedi_device * dev)
+{
+#ifdef PCIDMA
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ai_mite_chan) {
+ ni_set_ai_dma_channel(dev, -1);
+ mite_release_channel(devpriv->ai_mite_chan);
+ devpriv->ai_mite_chan = NULL;
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+}
+
+static void ni_release_ao_mite_channel(struct comedi_device * dev)
+{
+#ifdef PCIDMA
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ao_mite_chan) {
+ ni_set_ao_dma_channel(dev, -1);
+ mite_release_channel(devpriv->ao_mite_chan);
+ devpriv->ao_mite_chan = NULL;
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+}
+
+void ni_release_gpct_mite_channel(struct comedi_device * dev, unsigned gpct_index)
+{
+#ifdef PCIDMA
+ unsigned long flags;
+
+ BUG_ON(gpct_index >= NUM_GPCT);
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->counter_dev->counters[gpct_index].mite_chan) {
+ struct mite_channel *mite_chan =
+ devpriv->counter_dev->counters[gpct_index].mite_chan;
+
+ ni_set_gpct_dma_channel(dev, gpct_index, -1);
+ ni_tio_set_mite_channel(&devpriv->counter_dev->
+ counters[gpct_index], NULL);
+ mite_release_channel(mite_chan);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+}
+
+static void ni_release_cdo_mite_channel(struct comedi_device * dev)
+{
+#ifdef PCIDMA
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->cdo_mite_chan) {
+ ni_set_cdo_dma_channel(dev, -1);
+ mite_release_channel(devpriv->cdo_mite_chan);
+ devpriv->cdo_mite_chan = NULL;
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+}
+
+// e-series boards use the second irq signals to generate dma requests for their counters
+#ifdef PCIDMA
+static void ni_e_series_enable_second_irq(struct comedi_device * dev,
+ unsigned gpct_index, short enable)
+{
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ return;
+ switch (gpct_index) {
+ case 0:
+ if (enable) {
+ devpriv->stc_writew(dev, G0_Gate_Second_Irq_Enable,
+ Second_IRQ_A_Enable_Register);
+ } else {
+ devpriv->stc_writew(dev, 0,
+ Second_IRQ_A_Enable_Register);
+ }
+ break;
+ case 1:
+ if (enable) {
+ devpriv->stc_writew(dev, G1_Gate_Second_Irq_Enable,
+ Second_IRQ_B_Enable_Register);
+ } else {
+ devpriv->stc_writew(dev, 0,
+ Second_IRQ_B_Enable_Register);
+ }
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+#endif // PCIDMA
+
+static void ni_clear_ai_fifo(struct comedi_device * dev)
+{
+ if (boardtype.reg_type == ni_reg_6143) {
+ // Flush the 6143 data FIFO
+ ni_writel(0x10, AIFIFO_Control_6143); // Flush fifo
+ ni_writel(0x00, AIFIFO_Control_6143); // Flush fifo
+ while (ni_readl(AIFIFO_Status_6143) & 0x10) ; // Wait for complete
+ } else {
+ devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
+ if (boardtype.reg_type == ni_reg_625x) {
+ ni_writeb(0, M_Offset_Static_AI_Control(0));
+ ni_writeb(1, M_Offset_Static_AI_Control(0));
+#if 0
+ /* the NI example code does 3 convert pulses for 625x boards,
+ but that appears to be wrong in practice. */
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+#endif
+ }
+ }
+}
+
+static void win_out2(struct comedi_device * dev, uint32_t data, int reg)
+{
+ devpriv->stc_writew(dev, data >> 16, reg);
+ devpriv->stc_writew(dev, data & 0xffff, reg + 1);
+}
+
+static uint32_t win_in2(struct comedi_device * dev, int reg)
+{
+ uint32_t bits;
+ bits = devpriv->stc_readw(dev, reg) << 16;
+ bits |= devpriv->stc_readw(dev, reg + 1);
+ return bits;
+}
+
+#define ao_win_out(data,addr) ni_ao_win_outw(dev,data,addr)
+static inline void ni_ao_win_outw(struct comedi_device * dev, uint16_t data, int addr)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ ni_writew(addr, AO_Window_Address_611x);
+ ni_writew(data, AO_Window_Data_611x);
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static inline void ni_ao_win_outl(struct comedi_device * dev, uint32_t data, int addr)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ ni_writew(addr, AO_Window_Address_611x);
+ ni_writel(data, AO_Window_Data_611x);
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static inline unsigned short ni_ao_win_inw(struct comedi_device * dev, int addr)
+{
+ unsigned long flags;
+ unsigned short data;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ ni_writew(addr, AO_Window_Address_611x);
+ data = ni_readw(AO_Window_Data_611x);
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+ return data;
+}
+
+/* ni_set_bits( ) allows different parts of the ni_mio_common driver to
+* share registers (such as Interrupt_A_Register) without interfering with
+* each other.
+*
+* NOTE: the switch/case statements are optimized out for a constant argument
+* so this is actually quite fast--- If you must wrap another function around this
+* make it inline to avoid a large speed penalty.
+*
+* value should only be 1 or 0.
+*/
+static inline void ni_set_bits(struct comedi_device * dev, int reg, unsigned bits,
+ unsigned value)
+{
+ unsigned bit_values;
+
+ if (value)
+ bit_values = bits;
+ else
+ bit_values = 0;
+ ni_set_bitfield(dev, reg, bits, bit_values);
+}
+
+static irqreturn_t ni_E_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ unsigned short a_status;
+ unsigned short b_status;
+ unsigned int ai_mite_status = 0;
+ unsigned int ao_mite_status = 0;
+ unsigned long flags;
+#ifdef PCIDMA
+ struct mite_struct *mite = devpriv->mite;
+#endif
+
+ if (dev->attached == 0)
+ return IRQ_NONE;
+ smp_mb(); // make sure dev->attached is checked before handler does anything else.
+
+ // lock to avoid race with comedi_poll
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ a_status = devpriv->stc_readw(dev, AI_Status_1_Register);
+ b_status = devpriv->stc_readw(dev, AO_Status_1_Register);
+#ifdef PCIDMA
+ if (mite) {
+ unsigned long flags_too;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock,
+ flags_too);
+ if (devpriv->ai_mite_chan) {
+ ai_mite_status = mite_get_status(devpriv->ai_mite_chan);
+ if (ai_mite_status & CHSR_LINKC)
+ writel(CHOR_CLRLC,
+ devpriv->mite->mite_io_addr +
+ MITE_CHOR(devpriv->ai_mite_chan->
+ channel));
+ }
+ if (devpriv->ao_mite_chan) {
+ ao_mite_status = mite_get_status(devpriv->ao_mite_chan);
+ if (ao_mite_status & CHSR_LINKC)
+ writel(CHOR_CLRLC,
+ mite->mite_io_addr +
+ MITE_CHOR(devpriv->ao_mite_chan->
+ channel));
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+ flags_too);
+ }
+#endif
+ ack_a_interrupt(dev, a_status);
+ ack_b_interrupt(dev, b_status);
+ if ((a_status & Interrupt_A_St) || (ai_mite_status & CHSR_INT))
+ handle_a_interrupt(dev, a_status, ai_mite_status);
+ if ((b_status & Interrupt_B_St) || (ao_mite_status & CHSR_INT))
+ handle_b_interrupt(dev, b_status, ao_mite_status);
+ handle_gpct_interrupt(dev, 0);
+ handle_gpct_interrupt(dev, 1);
+ handle_cdio_interrupt(dev);
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ return IRQ_HANDLED;
+}
+
+#ifdef PCIDMA
+static void ni_sync_ai_dma(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ai_mite_chan)
+ mite_sync_input_dma(devpriv->ai_mite_chan, s->async);
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+}
+
+static void mite_handle_b_linkc(struct mite_struct *mite, struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV;
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ao_mite_chan) {
+ mite_sync_output_dma(devpriv->ao_mite_chan, s->async);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+}
+
+static int ni_ao_wait_for_dma_load(struct comedi_device * dev)
+{
+ static const int timeout = 10000;
+ int i;
+ for (i = 0; i < timeout; i++) {
+ unsigned short b_status;
+
+ b_status = devpriv->stc_readw(dev, AO_Status_1_Register);
+ if (b_status & AO_FIFO_Half_Full_St)
+ break;
+ /* if we poll too often, the pci bus activity seems
+ to slow the dma transfer down */
+ comedi_udelay(10);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timed out waiting for dma load");
+ return -EPIPE;
+ }
+ return 0;
+}
+
+#endif //PCIDMA
+static void ni_handle_eos(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (devpriv->aimode == AIMODE_SCAN) {
+#ifdef PCIDMA
+ static const int timeout = 10;
+ int i;
+
+ for (i = 0; i < timeout; i++) {
+ ni_sync_ai_dma(dev);
+ if ((s->async->events & COMEDI_CB_EOS))
+ break;
+ comedi_udelay(1);
+ }
+#else
+ ni_handle_fifo_dregs(dev);
+ s->async->events |= COMEDI_CB_EOS;
+#endif
+ }
+ /* handle special case of single scan using AI_End_On_End_Of_Scan */
+ if ((devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) {
+ shutdown_ai_command(dev);
+ }
+}
+
+static void shutdown_ai_command(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+
+#ifdef PCIDMA
+ ni_ai_drain_dma(dev);
+#endif
+ ni_handle_fifo_dregs(dev);
+ get_last_sample_611x(dev);
+ get_last_sample_6143(dev);
+
+ s->async->events |= COMEDI_CB_EOA;
+}
+
+static void ni_event(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (s->async->
+ events & (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW | COMEDI_CB_EOA))
+ {
+ switch (s - dev->subdevices) {
+ case NI_AI_SUBDEV:
+ ni_ai_reset(dev, s);
+ break;
+ case NI_AO_SUBDEV:
+ ni_ao_reset(dev, s);
+ break;
+ case NI_GPCT0_SUBDEV:
+ case NI_GPCT1_SUBDEV:
+ ni_gpct_cancel(dev, s);
+ break;
+ case NI_DIO_SUBDEV:
+ ni_cdio_cancel(dev, s);
+ break;
+ default:
+ break;
+ }
+ }
+ comedi_event(dev, s);
+}
+
+static void handle_gpct_interrupt(struct comedi_device * dev,
+ unsigned short counter_index)
+{
+#ifdef PCIDMA
+ struct comedi_subdevice *s = dev->subdevices + NI_GPCT_SUBDEV(counter_index);
+
+ ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index],
+ s);
+ if (s->async->events)
+ ni_event(dev, s);
+#endif
+}
+
+static void ack_a_interrupt(struct comedi_device * dev, unsigned short a_status)
+{
+ unsigned short ack = 0;
+
+ if (a_status & AI_SC_TC_St) {
+ ack |= AI_SC_TC_Interrupt_Ack;
+ }
+ if (a_status & AI_START1_St) {
+ ack |= AI_START1_Interrupt_Ack;
+ }
+ if (a_status & AI_START_St) {
+ ack |= AI_START_Interrupt_Ack;
+ }
+ if (a_status & AI_STOP_St) {
+ /* not sure why we used to ack the START here also, instead of doing it independently. Frank Hess 2007-07-06 */
+ ack |= AI_STOP_Interrupt_Ack /*| AI_START_Interrupt_Ack */ ;
+ }
+ if (ack)
+ devpriv->stc_writew(dev, ack, Interrupt_A_Ack_Register);
+}
+
+static void handle_a_interrupt(struct comedi_device * dev, unsigned short status,
+ unsigned ai_mite_status)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+
+ //67xx boards don't have ai subdevice, but their gpct0 might generate an a interrupt
+ if (s->type == COMEDI_SUBD_UNUSED)
+ return;
+
+#ifdef DEBUG_INTERRUPT
+ rt_printk
+ ("ni_mio_common: interrupt: a_status=%04x ai_mite_status=%08x\n",
+ status, ai_mite_status);
+ ni_mio_print_status_a(status);
+#endif
+#ifdef PCIDMA
+ if (ai_mite_status & CHSR_LINKC) {
+ ni_sync_ai_dma(dev);
+ }
+
+ if (ai_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
+ CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
+ CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
+ rt_printk
+ ("unknown mite interrupt, ack! (ai_mite_status=%08x)\n",
+ ai_mite_status);
+ //mite_print_chsr(ai_mite_status);
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ //disable_irq(dev->irq);
+ }
+#endif
+
+ /* test for all uncommon interrupt events at the same time */
+ if (status & (AI_Overrun_St | AI_Overflow_St | AI_SC_TC_Error_St |
+ AI_SC_TC_St | AI_START1_St)) {
+ if (status == 0xffff) {
+ rt_printk
+ ("ni_mio_common: a_status=0xffff. Card removed?\n");
+ /* we probably aren't even running a command now,
+ * so it's a good idea to be careful. */
+ if (comedi_get_subdevice_runflags(s) & SRF_RUNNING) {
+ s->async->events |=
+ COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ ni_event(dev, s);
+ }
+ return;
+ }
+ if (status & (AI_Overrun_St | AI_Overflow_St |
+ AI_SC_TC_Error_St)) {
+ rt_printk("ni_mio_common: ai error a_status=%04x\n",
+ status);
+ ni_mio_print_status_a(status);
+
+ shutdown_ai_command(dev);
+
+ s->async->events |= COMEDI_CB_ERROR;
+ if (status & (AI_Overrun_St | AI_Overflow_St))
+ s->async->events |= COMEDI_CB_OVERFLOW;
+
+ ni_event(dev, s);
+
+ return;
+ }
+ if (status & AI_SC_TC_St) {
+#ifdef DEBUG_INTERRUPT
+ rt_printk("ni_mio_common: SC_TC interrupt\n");
+#endif
+ if (!devpriv->ai_continuous) {
+ shutdown_ai_command(dev);
+ }
+ }
+ }
+#ifndef PCIDMA
+ if (status & AI_FIFO_Half_Full_St) {
+ int i;
+ static const int timeout = 10;
+ /* pcmcia cards (at least 6036) seem to stop producing interrupts if we
+ *fail to get the fifo less than half full, so loop to be sure.*/
+ for (i = 0; i < timeout; ++i) {
+ ni_handle_fifo_half_full(dev);
+ if ((devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Half_Full_St) == 0)
+ break;
+ }
+ }
+#endif // !PCIDMA
+
+ if ((status & AI_STOP_St)) {
+ ni_handle_eos(dev, s);
+ }
+
+ ni_event(dev, s);
+
+#ifdef DEBUG_INTERRUPT
+ status = devpriv->stc_readw(dev, AI_Status_1_Register);
+ if (status & Interrupt_A_St) {
+ rt_printk
+ ("handle_a_interrupt: didn't clear interrupt? status=0x%x\n",
+ status);
+ }
+#endif
+}
+
+static void ack_b_interrupt(struct comedi_device * dev, unsigned short b_status)
+{
+ unsigned short ack = 0;
+ if (b_status & AO_BC_TC_St) {
+ ack |= AO_BC_TC_Interrupt_Ack;
+ }
+ if (b_status & AO_Overrun_St) {
+ ack |= AO_Error_Interrupt_Ack;
+ }
+ if (b_status & AO_START_St) {
+ ack |= AO_START_Interrupt_Ack;
+ }
+ if (b_status & AO_START1_St) {
+ ack |= AO_START1_Interrupt_Ack;
+ }
+ if (b_status & AO_UC_TC_St) {
+ ack |= AO_UC_TC_Interrupt_Ack;
+ }
+ if (b_status & AO_UI2_TC_St) {
+ ack |= AO_UI2_TC_Interrupt_Ack;
+ }
+ if (b_status & AO_UPDATE_St) {
+ ack |= AO_UPDATE_Interrupt_Ack;
+ }
+ if (ack)
+ devpriv->stc_writew(dev, ack, Interrupt_B_Ack_Register);
+}
+
+static void handle_b_interrupt(struct comedi_device * dev, unsigned short b_status,
+ unsigned ao_mite_status)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV;
+ //unsigned short ack=0;
+#ifdef DEBUG_INTERRUPT
+ rt_printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n",
+ b_status, ao_mite_status);
+ ni_mio_print_status_b(b_status);
+#endif
+
+#ifdef PCIDMA
+ /* Currently, mite.c requires us to handle LINKC */
+ if (ao_mite_status & CHSR_LINKC) {
+ mite_handle_b_linkc(devpriv->mite, dev);
+ }
+
+ if (ao_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
+ CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
+ CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
+ rt_printk
+ ("unknown mite interrupt, ack! (ao_mite_status=%08x)\n",
+ ao_mite_status);
+ //mite_print_chsr(ao_mite_status);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ }
+#endif
+
+ if (b_status == 0xffff)
+ return;
+ if (b_status & AO_Overrun_St) {
+ rt_printk
+ ("ni_mio_common: AO FIFO underrun status=0x%04x status2=0x%04x\n",
+ b_status, devpriv->stc_readw(dev,
+ AO_Status_2_Register));
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+
+ if (b_status & AO_BC_TC_St) {
+ MDPRINTK("ni_mio_common: AO BC_TC status=0x%04x status2=0x%04x\n", b_status, devpriv->stc_readw(dev, AO_Status_2_Register));
+ s->async->events |= COMEDI_CB_EOA;
+ }
+#ifndef PCIDMA
+ if (b_status & AO_FIFO_Request_St) {
+ int ret;
+
+ ret = ni_ao_fifo_half_empty(dev, s);
+ if (!ret) {
+ rt_printk("ni_mio_common: AO buffer underrun\n");
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ AO_FIFO_Interrupt_Enable |
+ AO_Error_Interrupt_Enable, 0);
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+ }
+#endif
+
+ ni_event(dev, s);
+}
+
+#ifdef DEBUG_STATUS_A
+static const char *const status_a_strings[] = {
+ "passthru0", "fifo", "G0_gate", "G0_TC",
+ "stop", "start", "sc_tc", "start1",
+ "start2", "sc_tc_error", "overflow", "overrun",
+ "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_a"
+};
+
+static void ni_mio_print_status_a(int status)
+{
+ int i;
+
+ rt_printk("A status:");
+ for (i = 15; i >= 0; i--) {
+ if (status & (1 << i)) {
+ rt_printk(" %s", status_a_strings[i]);
+ }
+ }
+ rt_printk("\n");
+}
+#endif
+
+#ifdef DEBUG_STATUS_B
+static const char *const status_b_strings[] = {
+ "passthru1", "fifo", "G1_gate", "G1_TC",
+ "UI2_TC", "UPDATE", "UC_TC", "BC_TC",
+ "start1", "overrun", "start", "bc_tc_error",
+ "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_b"
+};
+
+static void ni_mio_print_status_b(int status)
+{
+ int i;
+
+ rt_printk("B status:");
+ for (i = 15; i >= 0; i--) {
+ if (status & (1 << i)) {
+ rt_printk(" %s", status_b_strings[i]);
+ }
+ }
+ rt_printk("\n");
+}
+#endif
+
+#ifndef PCIDMA
+
+static void ni_ao_fifo_load(struct comedi_device * dev, struct comedi_subdevice * s, int n)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ int chan;
+ int i;
+ short d;
+ u32 packed_data;
+ int range;
+ int err = 1;
+
+ chan = async->cur_chan;
+ for (i = 0; i < n; i++) {
+ err &= comedi_buf_get(async, &d);
+ if (err == 0)
+ break;
+
+ range = CR_RANGE(cmd->chanlist[chan]);
+
+ if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ packed_data = d & 0xffff;
+ /* 6711 only has 16 bit wide ao fifo */
+ if (boardtype.reg_type != ni_reg_6711) {
+ err &= comedi_buf_get(async, &d);
+ if (err == 0)
+ break;
+ chan++;
+ i++;
+ packed_data |= (d << 16) & 0xffff0000;
+ }
+ ni_writel(packed_data, DAC_FIFO_Data_611x);
+ } else {
+ ni_writew(d, DAC_FIFO_Data);
+ }
+ chan++;
+ chan %= cmd->chanlist_len;
+ }
+ async->cur_chan = chan;
+ if (err == 0) {
+ async->events |= COMEDI_CB_OVERFLOW;
+ }
+}
+
+/*
+ * There's a small problem if the FIFO gets really low and we
+ * don't have the data to fill it. Basically, if after we fill
+ * the FIFO with all the data available, the FIFO is _still_
+ * less than half full, we never clear the interrupt. If the
+ * IRQ is in edge mode, we never get another interrupt, because
+ * this one wasn't cleared. If in level mode, we get flooded
+ * with interrupts that we can't fulfill, because nothing ever
+ * gets put into the buffer.
+ *
+ * This kind of situation is recoverable, but it is easier to
+ * just pretend we had a FIFO underrun, since there is a good
+ * chance it will happen anyway. This is _not_ the case for
+ * RT code, as RT code might purposely be running close to the
+ * metal. Needs to be fixed eventually.
+ */
+static int ni_ao_fifo_half_empty(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int n;
+
+ n = comedi_buf_read_n_available(s->async);
+ if (n == 0) {
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ return 0;
+ }
+
+ n /= sizeof(short);
+ if (n > boardtype.ao_fifo_depth / 2)
+ n = boardtype.ao_fifo_depth / 2;
+
+ ni_ao_fifo_load(dev, s, n);
+
+ s->async->events |= COMEDI_CB_BLOCK;
+
+ return 1;
+}
+
+static int ni_ao_prep_fifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int n;
+
+ /* reset fifo */
+ devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
+ if (boardtype.reg_type & ni_reg_6xxx_mask)
+ ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
+
+ /* load some data */
+ n = comedi_buf_read_n_available(s->async);
+ if (n == 0)
+ return 0;
+
+ n /= sizeof(short);
+ if (n > boardtype.ao_fifo_depth)
+ n = boardtype.ao_fifo_depth;
+
+ ni_ao_fifo_load(dev, s, n);
+
+ return n;
+}
+
+static void ni_ai_fifo_read(struct comedi_device * dev, struct comedi_subdevice * s, int n)
+{
+ struct comedi_async *async = s->async;
+ int i;
+
+ if (boardtype.reg_type == ni_reg_611x) {
+ short data[2];
+ u32 dl;
+
+ for (i = 0; i < n / 2; i++) {
+ dl = ni_readl(ADC_FIFO_Data_611x);
+ /* This may get the hi/lo data in the wrong order */
+ data[0] = (dl >> 16) & 0xffff;
+ data[1] = dl & 0xffff;
+ cfc_write_array_to_buffer(s, data, sizeof(data));
+ }
+ /* Check if there's a single sample stuck in the FIFO */
+ if (n % 2) {
+ dl = ni_readl(ADC_FIFO_Data_611x);
+ data[0] = dl & 0xffff;
+ cfc_write_to_buffer(s, data[0]);
+ }
+ } else if (boardtype.reg_type == ni_reg_6143) {
+ short data[2];
+ u32 dl;
+
+ // This just reads the FIFO assuming the data is present, no checks on the FIFO status are performed
+ for (i = 0; i < n / 2; i++) {
+ dl = ni_readl(AIFIFO_Data_6143);
+
+ data[0] = (dl >> 16) & 0xffff;
+ data[1] = dl & 0xffff;
+ cfc_write_array_to_buffer(s, data, sizeof(data));
+ }
+ if (n % 2) {
+ /* Assume there is a single sample stuck in the FIFO */
+ ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO
+ dl = ni_readl(AIFIFO_Data_6143);
+ data[0] = (dl >> 16) & 0xffff;
+ cfc_write_to_buffer(s, data[0]);
+ }
+ } else {
+ if (n > sizeof(devpriv->ai_fifo_buffer) /
+ sizeof(devpriv->ai_fifo_buffer[0])) {
+ comedi_error(dev, "bug! ai_fifo_buffer too small");
+ async->events |= COMEDI_CB_ERROR;
+ return;
+ }
+ for (i = 0; i < n; i++) {
+ devpriv->ai_fifo_buffer[i] =
+ ni_readw(ADC_FIFO_Data_Register);
+ }
+ cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
+ n * sizeof(devpriv->ai_fifo_buffer[0]));
+ }
+}
+
+static void ni_handle_fifo_half_full(struct comedi_device * dev)
+{
+ int n;
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+
+ n = boardtype.ai_fifo_depth / 2;
+
+ ni_ai_fifo_read(dev, s, n);
+}
+#endif
+
+#ifdef PCIDMA
+static int ni_ai_drain_dma(struct comedi_device * dev)
+{
+ int i;
+ static const int timeout = 10000;
+ unsigned long flags;
+ int retval = 0;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ai_mite_chan) {
+ for (i = 0; i < timeout; i++) {
+ if ((devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St)
+ && mite_bytes_in_transit(devpriv->
+ ai_mite_chan) == 0)
+ break;
+ comedi_udelay(5);
+ }
+ if (i == timeout) {
+ rt_printk
+ ("ni_mio_common: wait for dma drain timed out\n");
+ rt_printk
+ ("mite_bytes_in_transit=%i, AI_Status1_Register=0x%x\n",
+ mite_bytes_in_transit(devpriv->ai_mite_chan),
+ devpriv->stc_readw(dev, AI_Status_1_Register));
+ retval = -1;
+ }
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+ ni_sync_ai_dma(dev);
+
+ return retval;
+}
+#endif
+/*
+ Empties the AI fifo
+*/
+static void ni_handle_fifo_dregs(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+ short data[2];
+ u32 dl;
+ short fifo_empty;
+ int i;
+
+ if (boardtype.reg_type == ni_reg_611x) {
+ while ((devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St) == 0) {
+ dl = ni_readl(ADC_FIFO_Data_611x);
+
+ /* This may get the hi/lo data in the wrong order */
+ data[0] = (dl >> 16);
+ data[1] = (dl & 0xffff);
+ cfc_write_array_to_buffer(s, data, sizeof(data));
+ }
+ } else if (boardtype.reg_type == ni_reg_6143) {
+ i = 0;
+ while (ni_readl(AIFIFO_Status_6143) & 0x04) {
+ dl = ni_readl(AIFIFO_Data_6143);
+
+ /* This may get the hi/lo data in the wrong order */
+ data[0] = (dl >> 16);
+ data[1] = (dl & 0xffff);
+ cfc_write_array_to_buffer(s, data, sizeof(data));
+ i += 2;
+ }
+ // Check if stranded sample is present
+ if (ni_readl(AIFIFO_Status_6143) & 0x01) {
+ ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO
+ dl = ni_readl(AIFIFO_Data_6143);
+ data[0] = (dl >> 16) & 0xffff;
+ cfc_write_to_buffer(s, data[0]);
+ }
+
+ } else {
+ fifo_empty =
+ devpriv->stc_readw(dev,
+ AI_Status_1_Register) & AI_FIFO_Empty_St;
+ while (fifo_empty == 0) {
+ for (i = 0;
+ i <
+ sizeof(devpriv->ai_fifo_buffer) /
+ sizeof(devpriv->ai_fifo_buffer[0]); i++) {
+ fifo_empty =
+ devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St;
+ if (fifo_empty)
+ break;
+ devpriv->ai_fifo_buffer[i] =
+ ni_readw(ADC_FIFO_Data_Register);
+ }
+ cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
+ i * sizeof(devpriv->ai_fifo_buffer[0]));
+ }
+ }
+}
+
+static void get_last_sample_611x(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+ short data;
+ u32 dl;
+
+ if (boardtype.reg_type != ni_reg_611x)
+ return;
+
+ /* Check if there's a single sample stuck in the FIFO */
+ if (ni_readb(XXX_Status) & 0x80) {
+ dl = ni_readl(ADC_FIFO_Data_611x);
+ data = (dl & 0xffff);
+ cfc_write_to_buffer(s, data);
+ }
+}
+
+static void get_last_sample_6143(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+ short data;
+ u32 dl;
+
+ if (boardtype.reg_type != ni_reg_6143)
+ return;
+
+ /* Check if there's a single sample stuck in the FIFO */
+ if (ni_readl(AIFIFO_Status_6143) & 0x01) {
+ ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO
+ dl = ni_readl(AIFIFO_Data_6143);
+
+ /* This may get the hi/lo data in the wrong order */
+ data = (dl >> 16) & 0xffff;
+ cfc_write_to_buffer(s, data);
+ }
+}
+
+static void ni_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *data, unsigned int num_bytes, unsigned int chan_index)
+{
+ struct comedi_async *async = s->async;
+ unsigned int i;
+ unsigned int length = num_bytes / bytes_per_sample(s);
+ short *array = data;
+ unsigned int *larray = data;
+ for (i = 0; i < length; i++) {
+#ifdef PCIDMA
+ if (s->subdev_flags & SDF_LSAMPL)
+ larray[i] = le32_to_cpu(larray[i]);
+ else
+ array[i] = le16_to_cpu(array[i]);
+#endif
+ if (s->subdev_flags & SDF_LSAMPL)
+ larray[i] += devpriv->ai_offset[chan_index];
+ else
+ array[i] += devpriv->ai_offset[chan_index];
+ chan_index++;
+ chan_index %= async->cmd.chanlist_len;
+ }
+}
+
+#ifdef PCIDMA
+
+static int ni_ai_setup_MITE_dma(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+ int retval;
+ unsigned long flags;
+
+ retval = ni_request_ai_mite_channel(dev);
+ if (retval)
+ return retval;
+// rt_printk("comedi_debug: using mite channel %i for ai.\n", devpriv->ai_mite_chan->channel);
+
+ /* write alloc the entire buffer */
+ comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if(devpriv->ai_mite_chan == NULL)
+ {
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+ return -EIO;
+ }
+
+ switch (boardtype.reg_type) {
+ case ni_reg_611x:
+ case ni_reg_6143:
+ mite_prep_dma(devpriv->ai_mite_chan, 32, 16);
+ break;
+ case ni_reg_628x:
+ mite_prep_dma(devpriv->ai_mite_chan, 32, 32);
+ break;
+ default:
+ mite_prep_dma(devpriv->ai_mite_chan, 16, 16);
+ break;
+ };
+ /*start the MITE */
+ mite_dma_arm(devpriv->ai_mite_chan);
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+ return 0;
+}
+
+static int ni_ao_setup_MITE_dma(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV;
+ int retval;
+ unsigned long flags;
+
+ retval = ni_request_ao_mite_channel(dev);
+ if (retval)
+ return retval;
+
+ /* read alloc the entire buffer */
+ comedi_buf_read_alloc(s->async, s->async->prealloc_bufsz);
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ao_mite_chan) {
+ if (boardtype.reg_type & (ni_reg_611x | ni_reg_6713)) {
+ mite_prep_dma(devpriv->ao_mite_chan, 32, 32);
+ } else {
+ /* doing 32 instead of 16 bit wide transfers from memory
+ makes the mite do 32 bit pci transfers, doubling pci bandwidth. */
+ mite_prep_dma(devpriv->ao_mite_chan, 16, 32);
+ }
+ mite_dma_arm(devpriv->ao_mite_chan);
+ } else
+ retval = -EIO;
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+ return retval;
+}
+
+#endif // PCIDMA
+
+/*
+ used for both cancel ioctl and board initialization
+
+ this is pretty harsh for a cancel, but it works...
+ */
+
+static int ni_ai_reset(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ ni_release_ai_mite_channel(dev);
+ /* ai configuration */
+ devpriv->stc_writew(dev, AI_Configuration_Start | AI_Reset,
+ Joint_Reset_Register);
+
+ ni_set_bits(dev, Interrupt_A_Enable_Register,
+ AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable |
+ AI_START2_Interrupt_Enable | AI_START_Interrupt_Enable |
+ AI_STOP_Interrupt_Enable | AI_Error_Interrupt_Enable |
+ AI_FIFO_Interrupt_Enable, 0);
+
+ ni_clear_ai_fifo(dev);
+
+ if (boardtype.reg_type != ni_reg_6143)
+ ni_writeb(0, Misc_Command);
+
+ devpriv->stc_writew(dev, AI_Disarm, AI_Command_1_Register); /* reset pulses */
+ devpriv->stc_writew(dev,
+ AI_Start_Stop | AI_Mode_1_Reserved /*| AI_Trigger_Once */ ,
+ AI_Mode_1_Register);
+ devpriv->stc_writew(dev, 0x0000, AI_Mode_2_Register);
+ /* generate FIFO interrupts on non-empty */
+ devpriv->stc_writew(dev, (0 << 6) | 0x0000, AI_Mode_3_Register);
+ if (boardtype.reg_type == ni_reg_611x) {
+ devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
+ AI_SOC_Polarity |
+ AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
+ devpriv->stc_writew(dev, AI_SCAN_IN_PROG_Output_Select(3) |
+ AI_EXTMUX_CLK_Output_Select(0) |
+ AI_LOCALMUX_CLK_Output_Select(2) |
+ AI_SC_TC_Output_Select(3) |
+ AI_CONVERT_Output_Select(AI_CONVERT_Output_Enable_High),
+ AI_Output_Control_Register);
+ } else if (boardtype.reg_type == ni_reg_6143) {
+ devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
+ AI_SOC_Polarity |
+ AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
+ devpriv->stc_writew(dev, AI_SCAN_IN_PROG_Output_Select(3) |
+ AI_EXTMUX_CLK_Output_Select(0) |
+ AI_LOCALMUX_CLK_Output_Select(2) |
+ AI_SC_TC_Output_Select(3) |
+ AI_CONVERT_Output_Select(AI_CONVERT_Output_Enable_Low),
+ AI_Output_Control_Register);
+ } else {
+ unsigned ai_output_control_bits;
+ devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
+ AI_SOC_Polarity |
+ AI_CONVERT_Pulse_Width |
+ AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
+ ai_output_control_bits = AI_SCAN_IN_PROG_Output_Select(3) |
+ AI_EXTMUX_CLK_Output_Select(0) |
+ AI_LOCALMUX_CLK_Output_Select(2) |
+ AI_SC_TC_Output_Select(3);
+ if (boardtype.reg_type == ni_reg_622x)
+ ai_output_control_bits |=
+ AI_CONVERT_Output_Select
+ (AI_CONVERT_Output_Enable_High);
+ else
+ ai_output_control_bits |=
+ AI_CONVERT_Output_Select
+ (AI_CONVERT_Output_Enable_Low);
+ devpriv->stc_writew(dev, ai_output_control_bits,
+ AI_Output_Control_Register);
+ }
+ /* the following registers should not be changed, because there
+ * are no backup registers in devpriv. If you want to change
+ * any of these, add a backup register and other appropriate code:
+ * AI_Mode_1_Register
+ * AI_Mode_3_Register
+ * AI_Personal_Register
+ * AI_Output_Control_Register
+ */
+ devpriv->stc_writew(dev, AI_SC_TC_Error_Confirm | AI_START_Interrupt_Ack | AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack | AI_SC_TC_Interrupt_Ack | AI_Error_Interrupt_Ack | AI_STOP_Interrupt_Ack, Interrupt_A_Ack_Register); /* clear interrupts */
+
+ devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
+
+ return 0;
+}
+
+static int ni_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags = 0;
+ int count;
+
+ // lock to avoid race with interrupt handler
+ if (in_interrupt() == 0)
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+#ifndef PCIDMA
+ ni_handle_fifo_dregs(dev);
+#else
+ ni_sync_ai_dma(dev);
+#endif
+ count = s->async->buf_write_count - s->async->buf_read_count;
+ if (in_interrupt() == 0)
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return count;
+}
+
+static int ni_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ const unsigned int mask = (1 << boardtype.adbits) - 1;
+ unsigned signbits;
+ unsigned short d;
+ unsigned long dl;
+
+ ni_load_channelgain_list(dev, 1, &insn->chanspec);
+
+ ni_clear_ai_fifo(dev);
+
+ signbits = devpriv->ai_offset[0];
+ if (boardtype.reg_type == ni_reg_611x) {
+ for (n = 0; n < num_adc_stages_611x; n++) {
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ comedi_udelay(1);
+ }
+ for (n = 0; n < insn->n; n++) {
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ /* The 611x has screwy 32-bit FIFOs. */
+ d = 0;
+ for (i = 0; i < NI_TIMEOUT; i++) {
+ if (ni_readb(XXX_Status) & 0x80) {
+ d = (ni_readl(ADC_FIFO_Data_611x) >> 16)
+ & 0xffff;
+ break;
+ }
+ if (!(devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St)) {
+ d = ni_readl(ADC_FIFO_Data_611x) &
+ 0xffff;
+ break;
+ }
+ }
+ if (i == NI_TIMEOUT) {
+ rt_printk
+ ("ni_mio_common: timeout in 611x ni_ai_insn_read\n");
+ return -ETIME;
+ }
+ d += signbits;
+ data[n] = d;
+ }
+ } else if (boardtype.reg_type == ni_reg_6143) {
+ for (n = 0; n < insn->n; n++) {
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+
+ /* The 6143 has 32-bit FIFOs. You need to strobe a bit to move a single 16bit stranded sample into the FIFO */
+ dl = 0;
+ for (i = 0; i < NI_TIMEOUT; i++) {
+ if (ni_readl(AIFIFO_Status_6143) & 0x01) {
+ ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO
+ dl = ni_readl(AIFIFO_Data_6143);
+ break;
+ }
+ }
+ if (i == NI_TIMEOUT) {
+ rt_printk
+ ("ni_mio_common: timeout in 6143 ni_ai_insn_read\n");
+ return -ETIME;
+ }
+ data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF;
+ }
+ } else {
+ for (n = 0; n < insn->n; n++) {
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ for (i = 0; i < NI_TIMEOUT; i++) {
+ if (!(devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St))
+ break;
+ }
+ if (i == NI_TIMEOUT) {
+ rt_printk
+ ("ni_mio_common: timeout in ni_ai_insn_read\n");
+ return -ETIME;
+ }
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ data[n] =
+ ni_readl(M_Offset_AI_FIFO_Data) & mask;
+ } else {
+ d = ni_readw(ADC_FIFO_Data_Register);
+ d += signbits; /* subtle: needs to be short addition */
+ data[n] = d;
+ }
+ }
+ }
+ return insn->n;
+}
+
+void ni_prime_channelgain_list(struct comedi_device * dev)
+{
+ int i;
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register);
+ for (i = 0; i < NI_TIMEOUT; ++i) {
+ if (!(devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St)) {
+ devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
+ return;
+ }
+ comedi_udelay(1);
+ }
+ rt_printk("ni_mio_common: timeout loading channel/gain list\n");
+}
+
+static void ni_m_series_load_channelgain_list(struct comedi_device * dev,
+ unsigned int n_chan, unsigned int *list)
+{
+ unsigned int chan, range, aref;
+ unsigned int i;
+ unsigned offset;
+ unsigned int dither;
+ unsigned range_code;
+
+ devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
+
+// offset = 1 << (boardtype.adbits - 1);
+ if ((list[0] & CR_ALT_SOURCE)) {
+ unsigned bypass_bits;
+ chan = CR_CHAN(list[0]);
+ range = CR_RANGE(list[0]);
+ range_code = ni_gainlkup[boardtype.gainlkup][range];
+ dither = ((list[0] & CR_ALT_FILTER) != 0);
+ bypass_bits = MSeries_AI_Bypass_Config_FIFO_Bit;
+ bypass_bits |= chan;
+ bypass_bits |=
+ (devpriv->
+ ai_calib_source) & (MSeries_AI_Bypass_Cal_Sel_Pos_Mask |
+ MSeries_AI_Bypass_Cal_Sel_Neg_Mask |
+ MSeries_AI_Bypass_Mode_Mux_Mask |
+ MSeries_AO_Bypass_AO_Cal_Sel_Mask);
+ bypass_bits |= MSeries_AI_Bypass_Gain_Bits(range_code);
+ if (dither)
+ bypass_bits |= MSeries_AI_Bypass_Dither_Bit;
+ // don't use 2's complement encoding
+ bypass_bits |= MSeries_AI_Bypass_Polarity_Bit;
+ ni_writel(bypass_bits, M_Offset_AI_Config_FIFO_Bypass);
+ } else {
+ ni_writel(0, M_Offset_AI_Config_FIFO_Bypass);
+ }
+ offset = 0;
+ for (i = 0; i < n_chan; i++) {
+ unsigned config_bits = 0;
+ chan = CR_CHAN(list[i]);
+ aref = CR_AREF(list[i]);
+ range = CR_RANGE(list[i]);
+ dither = ((list[i] & CR_ALT_FILTER) != 0);
+
+ range_code = ni_gainlkup[boardtype.gainlkup][range];
+ devpriv->ai_offset[i] = offset;
+ switch (aref) {
+ case AREF_DIFF:
+ config_bits |=
+ MSeries_AI_Config_Channel_Type_Differential_Bits;
+ break;
+ case AREF_COMMON:
+ config_bits |=
+ MSeries_AI_Config_Channel_Type_Common_Ref_Bits;
+ break;
+ case AREF_GROUND:
+ config_bits |=
+ MSeries_AI_Config_Channel_Type_Ground_Ref_Bits;
+ break;
+ case AREF_OTHER:
+ break;
+ }
+ config_bits |= MSeries_AI_Config_Channel_Bits(chan);
+ config_bits |=
+ MSeries_AI_Config_Bank_Bits(boardtype.reg_type, chan);
+ config_bits |= MSeries_AI_Config_Gain_Bits(range_code);
+ if (i == n_chan - 1)
+ config_bits |= MSeries_AI_Config_Last_Channel_Bit;
+ if (dither)
+ config_bits |= MSeries_AI_Config_Dither_Bit;
+ // don't use 2's complement encoding
+ config_bits |= MSeries_AI_Config_Polarity_Bit;
+ ni_writew(config_bits, M_Offset_AI_Config_FIFO_Data);
+ }
+ ni_prime_channelgain_list(dev);
+}
+
+/*
+ * Notes on the 6110 and 6111:
+ * These boards a slightly different than the rest of the series, since
+ * they have multiple A/D converters.
+ * From the driver side, the configuration memory is a
+ * little different.
+ * Configuration Memory Low:
+ * bits 15-9: same
+ * bit 8: unipolar/bipolar (should be 0 for bipolar)
+ * bits 0-3: gain. This is 4 bits instead of 3 for the other boards
+ * 1001 gain=0.1 (+/- 50)
+ * 1010 0.2
+ * 1011 0.1
+ * 0001 1
+ * 0010 2
+ * 0011 5
+ * 0100 10
+ * 0101 20
+ * 0110 50
+ * Configuration Memory High:
+ * bits 12-14: Channel Type
+ * 001 for differential
+ * 000 for calibration
+ * bit 11: coupling (this is not currently handled)
+ * 1 AC coupling
+ * 0 DC coupling
+ * bits 0-2: channel
+ * valid channels are 0-3
+ */
+static void ni_load_channelgain_list(struct comedi_device * dev, unsigned int n_chan,
+ unsigned int *list)
+{
+ unsigned int chan, range, aref;
+ unsigned int i;
+ unsigned int hi, lo;
+ unsigned offset;
+ unsigned int dither;
+
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ ni_m_series_load_channelgain_list(dev, n_chan, list);
+ return;
+ }
+ if (n_chan == 1 && (boardtype.reg_type != ni_reg_611x)
+ && (boardtype.reg_type != ni_reg_6143)) {
+ if (devpriv->changain_state
+ && devpriv->changain_spec == list[0]) {
+ // ready to go.
+ return;
+ }
+ devpriv->changain_state = 1;
+ devpriv->changain_spec = list[0];
+ } else {
+ devpriv->changain_state = 0;
+ }
+
+ devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
+
+ // Set up Calibration mode if required
+ if (boardtype.reg_type == ni_reg_6143) {
+ if ((list[0] & CR_ALT_SOURCE)
+ && !devpriv->ai_calib_source_enabled) {
+ // Strobe Relay enable bit
+ ni_writew(devpriv->
+ ai_calib_source |
+ Calibration_Channel_6143_RelayOn,
+ Calibration_Channel_6143);
+ ni_writew(devpriv->ai_calib_source,
+ Calibration_Channel_6143);
+ devpriv->ai_calib_source_enabled = 1;
+ msleep_interruptible(100); // Allow relays to change
+ } else if (!(list[0] & CR_ALT_SOURCE)
+ && devpriv->ai_calib_source_enabled) {
+ // Strobe Relay disable bit
+ ni_writew(devpriv->
+ ai_calib_source |
+ Calibration_Channel_6143_RelayOff,
+ Calibration_Channel_6143);
+ ni_writew(devpriv->ai_calib_source,
+ Calibration_Channel_6143);
+ devpriv->ai_calib_source_enabled = 0;
+ msleep_interruptible(100); // Allow relays to change
+ }
+ }
+
+ offset = 1 << (boardtype.adbits - 1);
+ for (i = 0; i < n_chan; i++) {
+ if ((boardtype.reg_type != ni_reg_6143)
+ && (list[i] & CR_ALT_SOURCE)) {
+ chan = devpriv->ai_calib_source;
+ } else {
+ chan = CR_CHAN(list[i]);
+ }
+ aref = CR_AREF(list[i]);
+ range = CR_RANGE(list[i]);
+ dither = ((list[i] & CR_ALT_FILTER) != 0);
+
+ /* fix the external/internal range differences */
+ range = ni_gainlkup[boardtype.gainlkup][range];
+ if (boardtype.reg_type == ni_reg_611x)
+ devpriv->ai_offset[i] = offset;
+ else
+ devpriv->ai_offset[i] = (range & 0x100) ? 0 : offset;
+
+ hi = 0;
+ if ((list[i] & CR_ALT_SOURCE)) {
+ if (boardtype.reg_type == ni_reg_611x)
+ ni_writew(CR_CHAN(list[i]) & 0x0003,
+ Calibration_Channel_Select_611x);
+ } else {
+ if (boardtype.reg_type == ni_reg_611x)
+ aref = AREF_DIFF;
+ else if (boardtype.reg_type == ni_reg_6143)
+ aref = AREF_OTHER;
+ switch (aref) {
+ case AREF_DIFF:
+ hi |= AI_DIFFERENTIAL;
+ break;
+ case AREF_COMMON:
+ hi |= AI_COMMON;
+ break;
+ case AREF_GROUND:
+ hi |= AI_GROUND;
+ break;
+ case AREF_OTHER:
+ break;
+ }
+ }
+ hi |= AI_CONFIG_CHANNEL(chan);
+
+ ni_writew(hi, Configuration_Memory_High);
+
+ if (boardtype.reg_type != ni_reg_6143) {
+ lo = range;
+ if (i == n_chan - 1)
+ lo |= AI_LAST_CHANNEL;
+ if (dither)
+ lo |= AI_DITHER;
+
+ ni_writew(lo, Configuration_Memory_Low);
+ }
+ }
+
+ /* prime the channel/gain list */
+ if ((boardtype.reg_type != ni_reg_611x)
+ && (boardtype.reg_type != ni_reg_6143)) {
+ ni_prime_channelgain_list(dev);
+ }
+}
+
+static int ni_ns_to_timer(const struct comedi_device * dev, unsigned nanosec,
+ int round_mode)
+{
+ int divider;
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ divider = (nanosec + devpriv->clock_ns / 2) / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_DOWN:
+ divider = (nanosec) / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_UP:
+ divider = (nanosec + devpriv->clock_ns - 1) / devpriv->clock_ns;
+ break;
+ }
+ return divider - 1;
+}
+
+static unsigned ni_timer_to_ns(const struct comedi_device * dev, int timer)
+{
+ return devpriv->clock_ns * (timer + 1);
+}
+
+static unsigned ni_min_ai_scan_period_ns(struct comedi_device * dev,
+ unsigned num_channels)
+{
+ switch (boardtype.reg_type) {
+ case ni_reg_611x:
+ case ni_reg_6143:
+ // simultaneously-sampled inputs
+ return boardtype.ai_speed;
+ break;
+ default:
+ // multiplexed inputs
+ break;
+ };
+ return boardtype.ai_speed * num_channels;
+}
+
+static int ni_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int sources;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ if ((cmd->flags & CMDF_WRITE)) {
+ cmd->flags &= ~CMDF_WRITE;
+ }
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_INT | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ sources = TRIG_TIMER | TRIG_EXT;
+ if ((boardtype.reg_type == ni_reg_611x)
+ || (boardtype.reg_type == ni_reg_6143))
+ sources |= TRIG_NOW;
+ cmd->convert_src &= sources;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->start_src != TRIG_NOW &&
+ cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT &&
+ cmd->scan_begin_src != TRIG_OTHER)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER &&
+ cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_src == TRIG_EXT) {
+ /* external trigger */
+ unsigned int tmp = CR_CHAN(cmd->start_arg);
+
+ if (tmp > 16)
+ tmp = 16;
+ tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
+ if (cmd->start_arg != tmp) {
+ cmd->start_arg = tmp;
+ err++;
+ }
+ } else {
+ if (cmd->start_arg != 0) {
+ /* true for both TRIG_NOW and TRIG_INT */
+ cmd->start_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < ni_min_ai_scan_period_ns(dev,
+ cmd->chanlist_len)) {
+ cmd->scan_begin_arg =
+ ni_min_ai_scan_period_ns(dev,
+ cmd->chanlist_len);
+ err++;
+ }
+ if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) {
+ cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff;
+ err++;
+ }
+ } else if (cmd->scan_begin_src == TRIG_EXT) {
+ /* external trigger */
+ unsigned int tmp = CR_CHAN(cmd->scan_begin_arg);
+
+ if (tmp > 16)
+ tmp = 16;
+ tmp |= (cmd->scan_begin_arg & (CR_INVERT | CR_EDGE));
+ if (cmd->scan_begin_arg != tmp) {
+ cmd->scan_begin_arg = tmp;
+ err++;
+ }
+ } else { /* TRIG_OTHER */
+ if (cmd->scan_begin_arg) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if ((boardtype.reg_type == ni_reg_611x)
+ || (boardtype.reg_type == ni_reg_6143)) {
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ } else {
+ if (cmd->convert_arg < boardtype.ai_speed) {
+ cmd->convert_arg = boardtype.ai_speed;
+ err++;
+ }
+ if (cmd->convert_arg > devpriv->clock_ns * 0xffff) {
+ cmd->convert_arg = devpriv->clock_ns * 0xffff;
+ err++;
+ }
+ }
+ } else if (cmd->convert_src == TRIG_EXT) {
+ /* external trigger */
+ unsigned int tmp = CR_CHAN(cmd->convert_arg);
+
+ if (tmp > 16)
+ tmp = 16;
+ tmp |= (cmd->convert_arg & (CR_ALT_FILTER | CR_INVERT));
+ if (cmd->convert_arg != tmp) {
+ cmd->convert_arg = tmp;
+ err++;
+ }
+ } else if (cmd->convert_src == TRIG_NOW) {
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ unsigned int max_count = 0x01000000;
+
+ if (boardtype.reg_type == ni_reg_611x)
+ max_count -= num_adc_stages_611x;
+ if (cmd->stop_arg > max_count) {
+ cmd->stop_arg = max_count;
+ err++;
+ }
+ if (cmd->stop_arg < 1) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ cmd->scan_begin_arg =
+ ni_timer_to_ns(dev, ni_ns_to_timer(dev,
+ cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK));
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if ((boardtype.reg_type != ni_reg_611x)
+ && (boardtype.reg_type != ni_reg_6143)) {
+ tmp = cmd->convert_arg;
+ cmd->convert_arg =
+ ni_timer_to_ns(dev, ni_ns_to_timer(dev,
+ cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK));
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int ni_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ const struct comedi_cmd *cmd = &s->async->cmd;
+ int timer;
+ int mode1 = 0; /* mode1 is needed for both stop and convert */
+ int mode2 = 0;
+ int start_stop_select = 0;
+ unsigned int stop_count;
+ int interrupt_a_enable = 0;
+
+ MDPRINTK("ni_ai_cmd\n");
+ if (dev->irq == 0) {
+ comedi_error(dev, "cannot run command without an irq");
+ return -EIO;
+ }
+ ni_clear_ai_fifo(dev);
+
+ ni_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
+
+ /* start configuration */
+ devpriv->stc_writew(dev, AI_Configuration_Start, Joint_Reset_Register);
+
+ /* disable analog triggering for now, since it
+ * interferes with the use of pfi0 */
+ devpriv->an_trig_etc_reg &= ~Analog_Trigger_Enable;
+ devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
+ Analog_Trigger_Etc_Register);
+
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ case TRIG_NOW:
+ devpriv->stc_writew(dev, AI_START2_Select(0) |
+ AI_START1_Sync | AI_START1_Edge | AI_START1_Select(0),
+ AI_Trigger_Select_Register);
+ break;
+ case TRIG_EXT:
+ {
+ int chan = CR_CHAN(cmd->start_arg);
+ unsigned int bits = AI_START2_Select(0) |
+ AI_START1_Sync | AI_START1_Select(chan + 1);
+
+ if (cmd->start_arg & CR_INVERT)
+ bits |= AI_START1_Polarity;
+ if (cmd->start_arg & CR_EDGE)
+ bits |= AI_START1_Edge;
+ devpriv->stc_writew(dev, bits,
+ AI_Trigger_Select_Register);
+ break;
+ }
+ }
+
+ mode2 &= ~AI_Pre_Trigger;
+ mode2 &= ~AI_SC_Initial_Load_Source;
+ mode2 &= ~AI_SC_Reload_Mode;
+ devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+
+ if (cmd->chanlist_len == 1 || (boardtype.reg_type == ni_reg_611x)
+ || (boardtype.reg_type == ni_reg_6143)) {
+ start_stop_select |= AI_STOP_Polarity;
+ start_stop_select |= AI_STOP_Select(31); // logic low
+ start_stop_select |= AI_STOP_Sync;
+ } else {
+ start_stop_select |= AI_STOP_Select(19); // ai configuration memory
+ }
+ devpriv->stc_writew(dev, start_stop_select,
+ AI_START_STOP_Select_Register);
+
+ devpriv->ai_cmd2 = 0;
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ stop_count = cmd->stop_arg - 1;
+
+ if (boardtype.reg_type == ni_reg_611x) {
+ // have to take 3 stage adc pipeline into account
+ stop_count += num_adc_stages_611x;
+ }
+ /* stage number of scans */
+ devpriv->stc_writel(dev, stop_count, AI_SC_Load_A_Registers);
+
+ mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;
+ devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+ /* load SC (Scan Count) */
+ devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
+
+ devpriv->ai_continuous = 0;
+ if (stop_count == 0) {
+ devpriv->ai_cmd2 |= AI_End_On_End_Of_Scan;
+ interrupt_a_enable |= AI_STOP_Interrupt_Enable;
+ // this is required to get the last sample for chanlist_len > 1, not sure why
+ if (cmd->chanlist_len > 1)
+ start_stop_select |=
+ AI_STOP_Polarity | AI_STOP_Edge;
+ }
+ break;
+ case TRIG_NONE:
+ /* stage number of scans */
+ devpriv->stc_writel(dev, 0, AI_SC_Load_A_Registers);
+
+ mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
+ devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+
+ /* load SC (Scan Count) */
+ devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
+
+ devpriv->ai_continuous = 1;
+
+ break;
+ }
+
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ /*
+ stop bits for non 611x boards
+ AI_SI_Special_Trigger_Delay=0
+ AI_Pre_Trigger=0
+ AI_START_STOP_Select_Register:
+ AI_START_Polarity=0 (?) rising edge
+ AI_START_Edge=1 edge triggered
+ AI_START_Sync=1 (?)
+ AI_START_Select=0 SI_TC
+ AI_STOP_Polarity=0 rising edge
+ AI_STOP_Edge=0 level
+ AI_STOP_Sync=1
+ AI_STOP_Select=19 external pin (configuration mem)
+ */
+ start_stop_select |= AI_START_Edge | AI_START_Sync;
+ devpriv->stc_writew(dev, start_stop_select,
+ AI_START_STOP_Select_Register);
+
+ mode2 |= AI_SI_Reload_Mode(0);
+ /* AI_SI_Initial_Load_Source=A */
+ mode2 &= ~AI_SI_Initial_Load_Source;
+ //mode2 |= AI_SC_Reload_Mode;
+ devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+
+ /* load SI */
+ timer = ni_ns_to_timer(dev, cmd->scan_begin_arg,
+ TRIG_ROUND_NEAREST);
+ devpriv->stc_writel(dev, timer, AI_SI_Load_A_Registers);
+ devpriv->stc_writew(dev, AI_SI_Load, AI_Command_1_Register);
+ break;
+ case TRIG_EXT:
+ if (cmd->scan_begin_arg & CR_EDGE)
+ start_stop_select |= AI_START_Edge;
+ /* AI_START_Polarity==1 is falling edge */
+ if (cmd->scan_begin_arg & CR_INVERT)
+ start_stop_select |= AI_START_Polarity;
+ if (cmd->scan_begin_src != cmd->convert_src ||
+ (cmd->scan_begin_arg & ~CR_EDGE) !=
+ (cmd->convert_arg & ~CR_EDGE))
+ start_stop_select |= AI_START_Sync;
+ start_stop_select |=
+ AI_START_Select(1 + CR_CHAN(cmd->scan_begin_arg));
+ devpriv->stc_writew(dev, start_stop_select,
+ AI_START_STOP_Select_Register);
+ break;
+ }
+
+ switch (cmd->convert_src) {
+ case TRIG_TIMER:
+ case TRIG_NOW:
+ if (cmd->convert_arg == 0 || cmd->convert_src == TRIG_NOW)
+ timer = 1;
+ else
+ timer = ni_ns_to_timer(dev, cmd->convert_arg,
+ TRIG_ROUND_NEAREST);
+ devpriv->stc_writew(dev, 1, AI_SI2_Load_A_Register); /* 0,0 does not work. */
+ devpriv->stc_writew(dev, timer, AI_SI2_Load_B_Register);
+
+ /* AI_SI2_Reload_Mode = alternate */
+ /* AI_SI2_Initial_Load_Source = A */
+ mode2 &= ~AI_SI2_Initial_Load_Source;
+ mode2 |= AI_SI2_Reload_Mode;
+ devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+
+ /* AI_SI2_Load */
+ devpriv->stc_writew(dev, AI_SI2_Load, AI_Command_1_Register);
+
+ mode2 |= AI_SI2_Reload_Mode; // alternate
+ mode2 |= AI_SI2_Initial_Load_Source; // B
+
+ devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+ break;
+ case TRIG_EXT:
+ mode1 |= AI_CONVERT_Source_Select(1 + cmd->convert_arg);
+ if ((cmd->convert_arg & CR_INVERT) == 0)
+ mode1 |= AI_CONVERT_Source_Polarity;
+ devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+
+ mode2 |= AI_Start_Stop_Gate_Enable | AI_SC_Gate_Enable;
+ devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+
+ break;
+ }
+
+ if (dev->irq) {
+
+ /* interrupt on FIFO, errors, SC_TC */
+ interrupt_a_enable |= AI_Error_Interrupt_Enable |
+ AI_SC_TC_Interrupt_Enable;
+
+#ifndef PCIDMA
+ interrupt_a_enable |= AI_FIFO_Interrupt_Enable;
+#endif
+
+ if (cmd->flags & TRIG_WAKE_EOS
+ || (devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) {
+ /* wake on end-of-scan */
+ devpriv->aimode = AIMODE_SCAN;
+ } else {
+ devpriv->aimode = AIMODE_HALF_FULL;
+ }
+
+ switch (devpriv->aimode) {
+ case AIMODE_HALF_FULL:
+ /*generate FIFO interrupts and DMA requests on half-full */
+#ifdef PCIDMA
+ devpriv->stc_writew(dev, AI_FIFO_Mode_HF_to_E,
+ AI_Mode_3_Register);
+#else
+ devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
+ AI_Mode_3_Register);
+#endif
+ break;
+ case AIMODE_SAMPLE:
+ /*generate FIFO interrupts on non-empty */
+ devpriv->stc_writew(dev, AI_FIFO_Mode_NE,
+ AI_Mode_3_Register);
+ break;
+ case AIMODE_SCAN:
+#ifdef PCIDMA
+ devpriv->stc_writew(dev, AI_FIFO_Mode_NE,
+ AI_Mode_3_Register);
+#else
+ devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
+ AI_Mode_3_Register);
+#endif
+ interrupt_a_enable |= AI_STOP_Interrupt_Enable;
+ break;
+ default:
+ break;
+ }
+
+ devpriv->stc_writew(dev, AI_Error_Interrupt_Ack | AI_STOP_Interrupt_Ack | AI_START_Interrupt_Ack | AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack | AI_SC_TC_Interrupt_Ack | AI_SC_TC_Error_Confirm, Interrupt_A_Ack_Register); /* clear interrupts */
+
+ ni_set_bits(dev, Interrupt_A_Enable_Register,
+ interrupt_a_enable, 1);
+
+ MDPRINTK("Interrupt_A_Enable_Register = 0x%04x\n",
+ devpriv->int_a_enable_reg);
+ } else {
+ /* interrupt on nothing */
+ ni_set_bits(dev, Interrupt_A_Enable_Register, ~0, 0);
+
+ /* XXX start polling if necessary */
+ MDPRINTK("interrupting on nothing\n");
+ }
+
+ /* end configuration */
+ devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
+
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ devpriv->stc_writew(dev,
+ AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
+ AI_Command_1_Register);
+ break;
+ case TRIG_EXT:
+ /* XXX AI_SI_Arm? */
+ devpriv->stc_writew(dev,
+ AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
+ AI_Command_1_Register);
+ break;
+ }
+
+#ifdef PCIDMA
+ {
+ int retval = ni_ai_setup_MITE_dma(dev);
+ if (retval)
+ return retval;
+ }
+ //mite_dump_regs(devpriv->mite);
+#endif
+
+ switch (cmd->start_src) {
+ case TRIG_NOW:
+ /* AI_START1_Pulse */
+ devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
+ AI_Command_2_Register);
+ s->async->inttrig = NULL;
+ break;
+ case TRIG_EXT:
+ s->async->inttrig = NULL;
+ break;
+ case TRIG_INT:
+ s->async->inttrig = &ni_ai_inttrig;
+ break;
+ }
+
+ MDPRINTK("exit ni_ai_cmd\n");
+
+ return 0;
+}
+
+static int ni_ai_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ if (trignum != 0)
+ return -EINVAL;
+
+ devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
+ AI_Command_2_Register);
+ s->async->inttrig = NULL;
+
+ return 1;
+}
+
+static int ni_ai_config_analog_trig(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int ni_ai_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n < 1)
+ return -EINVAL;
+
+ switch (data[0]) {
+ case INSN_CONFIG_ANALOG_TRIG:
+ return ni_ai_config_analog_trig(dev, s, insn, data);
+ case INSN_CONFIG_ALT_SOURCE:
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (data[1] & ~(MSeries_AI_Bypass_Cal_Sel_Pos_Mask |
+ MSeries_AI_Bypass_Cal_Sel_Neg_Mask |
+ MSeries_AI_Bypass_Mode_Mux_Mask |
+ MSeries_AO_Bypass_AO_Cal_Sel_Mask)) {
+ return -EINVAL;
+ }
+ devpriv->ai_calib_source = data[1];
+ } else if (boardtype.reg_type == ni_reg_6143) {
+ unsigned int calib_source;
+
+ calib_source = data[1] & 0xf;
+
+ if (calib_source > 0xF)
+ return -EINVAL;
+
+ devpriv->ai_calib_source = calib_source;
+ ni_writew(calib_source, Calibration_Channel_6143);
+ } else {
+ unsigned int calib_source;
+ unsigned int calib_source_adjust;
+
+ calib_source = data[1] & 0xf;
+ calib_source_adjust = (data[1] >> 4) & 0xff;
+
+ if (calib_source >= 8)
+ return -EINVAL;
+ devpriv->ai_calib_source = calib_source;
+ if (boardtype.reg_type == ni_reg_611x) {
+ ni_writeb(calib_source_adjust,
+ Cal_Gain_Select_611x);
+ }
+ }
+ return 2;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int ni_ai_config_analog_trig(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int a, b, modebits;
+ int err = 0;
+
+ /* data[1] is flags
+ * data[2] is analog line
+ * data[3] is set level
+ * data[4] is reset level */
+ if (!boardtype.has_analog_trig)
+ return -EINVAL;
+ if ((data[1] & 0xffff0000) != COMEDI_EV_SCAN_BEGIN) {
+ data[1] &= (COMEDI_EV_SCAN_BEGIN | 0xffff);
+ err++;
+ }
+ if (data[2] >= boardtype.n_adchan) {
+ data[2] = boardtype.n_adchan - 1;
+ err++;
+ }
+ if (data[3] > 255) { /* a */
+ data[3] = 255;
+ err++;
+ }
+ if (data[4] > 255) { /* b */
+ data[4] = 255;
+ err++;
+ }
+ /*
+ * 00 ignore
+ * 01 set
+ * 10 reset
+ *
+ * modes:
+ * 1 level: +b- +a-
+ * high mode 00 00 01 10
+ * low mode 00 00 10 01
+ * 2 level: (a<b)
+ * hysteresis low mode 10 00 00 01
+ * hysteresis high mode 01 00 00 10
+ * middle mode 10 01 01 10
+ */
+
+ a = data[3];
+ b = data[4];
+ modebits = data[1] & 0xff;
+ if (modebits & 0xf0) {
+ /* two level mode */
+ if (b < a) {
+ /* swap order */
+ a = data[4];
+ b = data[3];
+ modebits =
+ ((data[1] & 0xf) << 4) | ((data[1] & 0xf0) >>
+ 4);
+ }
+ devpriv->atrig_low = a;
+ devpriv->atrig_high = b;
+ switch (modebits) {
+ case 0x81: /* low hysteresis mode */
+ devpriv->atrig_mode = 6;
+ break;
+ case 0x42: /* high hysteresis mode */
+ devpriv->atrig_mode = 3;
+ break;
+ case 0x96: /* middle window mode */
+ devpriv->atrig_mode = 2;
+ break;
+ default:
+ data[1] &= ~0xff;
+ err++;
+ }
+ } else {
+ /* one level mode */
+ if (b != 0) {
+ data[4] = 0;
+ err++;
+ }
+ switch (modebits) {
+ case 0x06: /* high window mode */
+ devpriv->atrig_high = a;
+ devpriv->atrig_mode = 0;
+ break;
+ case 0x09: /* low window mode */
+ devpriv->atrig_low = a;
+ devpriv->atrig_mode = 1;
+ break;
+ default:
+ data[1] &= ~0xff;
+ err++;
+ }
+ }
+ if (err)
+ return -EAGAIN;
+ return 5;
+}
+
+/* munge data from unsigned to 2's complement for analog output bipolar modes */
+static void ni_ao_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *data, unsigned int num_bytes, unsigned int chan_index)
+{
+ struct comedi_async *async = s->async;
+ unsigned int range;
+ unsigned int i;
+ unsigned int offset;
+ unsigned int length = num_bytes / sizeof(short);
+ short *array = data;
+
+ offset = 1 << (boardtype.aobits - 1);
+ for (i = 0; i < length; i++) {
+ range = CR_RANGE(async->cmd.chanlist[chan_index]);
+ if (boardtype.ao_unipolar == 0 || (range & 1) == 0)
+ array[i] -= offset;
+#ifdef PCIDMA
+ array[i] = cpu_to_le16(array[i]);
+#endif
+ chan_index++;
+ chan_index %= async->cmd.chanlist_len;
+ }
+}
+
+static int ni_m_series_ao_config_chanlist(struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned int chanspec[], unsigned int n_chans,
+ int timed)
+{
+ unsigned int range;
+ unsigned int chan;
+ unsigned int conf;
+ int i;
+ int invert = 0;
+
+ if(timed) {
+ for (i = 0; i < boardtype.n_aochan; ++i) {
+ devpriv->ao_conf[i] &= ~MSeries_AO_Update_Timed_Bit;
+ ni_writeb(devpriv->ao_conf[i], M_Offset_AO_Config_Bank(i));
+ ni_writeb(0xf, M_Offset_AO_Waveform_Order(i));
+ }
+ }
+ for (i = 0; i < n_chans; i++) {
+ const struct comedi_krange *krange;
+ chan = CR_CHAN(chanspec[i]);
+ range = CR_RANGE(chanspec[i]);
+ krange = s->range_table->range + range;
+ invert = 0;
+ conf = 0;
+ switch (krange->max - krange->min) {
+ case 20000000:
+ conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits;
+ ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan));
+ break;
+ case 10000000:
+ conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits;
+ ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan));
+ break;
+ case 4000000:
+ conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits;
+ ni_writeb(MSeries_Attenuate_x5_Bit,
+ M_Offset_AO_Reference_Attenuation(chan));
+ break;
+ case 2000000:
+ conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits;
+ ni_writeb(MSeries_Attenuate_x5_Bit,
+ M_Offset_AO_Reference_Attenuation(chan));
+ break;
+ default:
+ rt_printk("%s: bug! unhandled ao reference voltage\n",
+ __FUNCTION__);
+ break;
+ }
+ switch (krange->max + krange->min) {
+ case 0:
+ conf |= MSeries_AO_DAC_Offset_0V_Bits;
+ break;
+ case 10000000:
+ conf |= MSeries_AO_DAC_Offset_5V_Bits;
+ break;
+ default:
+ rt_printk("%s: bug! unhandled ao offset voltage\n",
+ __FUNCTION__);
+ break;
+ }
+ if (timed)
+ conf |= MSeries_AO_Update_Timed_Bit;
+ ni_writeb(conf, M_Offset_AO_Config_Bank(chan));
+ devpriv->ao_conf[chan] = conf;
+ ni_writeb(i, M_Offset_AO_Waveform_Order(chan));
+ }
+ return invert;
+}
+
+static int ni_old_ao_config_chanlist(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int chanspec[], unsigned int n_chans)
+{
+ unsigned int range;
+ unsigned int chan;
+ unsigned int conf;
+ int i;
+ int invert = 0;
+
+ for (i = 0; i < n_chans; i++) {
+ chan = CR_CHAN(chanspec[i]);
+ range = CR_RANGE(chanspec[i]);
+ conf = AO_Channel(chan);
+
+ if (boardtype.ao_unipolar) {
+ if ((range & 1) == 0) {
+ conf |= AO_Bipolar;
+ invert = (1 << (boardtype.aobits - 1));
+ } else {
+ invert = 0;
+ }
+ if (range & 2)
+ conf |= AO_Ext_Ref;
+ } else {
+ conf |= AO_Bipolar;
+ invert = (1 << (boardtype.aobits - 1));
+ }
+
+ /* not all boards can deglitch, but this shouldn't hurt */
+ if (chanspec[i] & CR_DEGLITCH)
+ conf |= AO_Deglitch;
+
+ /* analog reference */
+ /* AREF_OTHER connects AO ground to AI ground, i think */
+ conf |= (CR_AREF(chanspec[i]) ==
+ AREF_OTHER) ? AO_Ground_Ref : 0;
+
+ ni_writew(conf, AO_Configuration);
+ devpriv->ao_conf[chan] = conf;
+ }
+ return invert;
+}
+
+static int ni_ao_config_chanlist(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int chanspec[], unsigned int n_chans, int timed)
+{
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ return ni_m_series_ao_config_chanlist(dev, s, chanspec, n_chans,
+ timed);
+ else
+ return ni_old_ao_config_chanlist(dev, s, chanspec, n_chans);
+}
+static int ni_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int ni_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int invert;
+
+ invert = ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
+
+ devpriv->ao[chan] = data[0];
+
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ ni_writew(data[0], M_Offset_DAC_Direct_Data(chan));
+ } else
+ ni_writew(data[0] ^ invert,
+ (chan) ? DAC1_Direct_Data : DAC0_Direct_Data);
+
+ return 1;
+}
+
+static int ni_ao_insn_write_671x(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int invert;
+
+ ao_win_out(1 << chan, AO_Immediate_671x);
+ invert = 1 << (boardtype.aobits - 1);
+
+ ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
+
+ devpriv->ao[chan] = data[0];
+ ao_win_out(data[0] ^ invert, DACx_Direct_Data_671x(chan));
+
+ return 1;
+}
+
+static int ni_ao_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE:
+ switch(data[1])
+ {
+ case COMEDI_OUTPUT:
+ data[2] = 1 + boardtype.ao_fifo_depth * sizeof(short);
+ if(devpriv->mite) data[2] += devpriv->mite->fifo_size;
+ break;
+ case COMEDI_INPUT:
+ data[2] = 0;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int ni_ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ int ret;
+ int interrupt_b_bits;
+ int i;
+ static const int timeout = 1000;
+
+ if (trignum != 0)
+ return -EINVAL;
+
+ /* Null trig at beginning prevent ao start trigger from executing more than
+ once per command (and doing things like trying to allocate the ao dma channel
+ multiple times) */
+ s->async->inttrig = NULL;
+
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ AO_FIFO_Interrupt_Enable | AO_Error_Interrupt_Enable, 0);
+ interrupt_b_bits = AO_Error_Interrupt_Enable;
+#ifdef PCIDMA
+ devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
+ if (boardtype.reg_type & ni_reg_6xxx_mask)
+ ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
+ ret = ni_ao_setup_MITE_dma(dev);
+ if (ret)
+ return ret;
+ ret = ni_ao_wait_for_dma_load(dev);
+ if (ret < 0)
+ return ret;
+#else
+ ret = ni_ao_prep_fifo(dev, s);
+ if (ret == 0)
+ return -EPIPE;
+
+ interrupt_b_bits |= AO_FIFO_Interrupt_Enable;
+#endif
+
+ devpriv->stc_writew(dev, devpriv->ao_mode3 | AO_Not_An_UPDATE,
+ AO_Mode_3_Register);
+ devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+ /* wait for DACs to be loaded */
+ for (i = 0; i < timeout; i++) {
+ comedi_udelay(1);
+ if ((devpriv->stc_readw(dev,
+ Joint_Status_2_Register) &
+ AO_TMRDACWRs_In_Progress_St) == 0)
+ break;
+ }
+ if (i == timeout) {
+ comedi_error(dev,
+ "timed out waiting for AO_TMRDACWRs_In_Progress_St to clear");
+ return -EIO;
+ }
+ // stc manual says we are need to clear error interrupt after AO_TMRDACWRs_In_Progress_St clears
+ devpriv->stc_writew(dev, AO_Error_Interrupt_Ack,
+ Interrupt_B_Ack_Register);
+
+ ni_set_bits(dev, Interrupt_B_Enable_Register, interrupt_b_bits, 1);
+
+ devpriv->stc_writew(dev,
+ devpriv->
+ ao_cmd1 | AO_UI_Arm | AO_UC_Arm | AO_BC_Arm |
+ AO_DAC1_Update_Mode | AO_DAC0_Update_Mode,
+ AO_Command_1_Register);
+
+ devpriv->stc_writew(dev, devpriv->ao_cmd2 | AO_START1_Pulse,
+ AO_Command_2_Register);
+
+ return 0;
+}
+
+static int ni_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ const struct comedi_cmd *cmd = &s->async->cmd;
+ int bits;
+ int i;
+ unsigned trigvar;
+
+ if (dev->irq == 0) {
+ comedi_error(dev, "cannot run command without an irq");
+ return -EIO;
+ }
+
+ devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
+
+ devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register);
+
+ if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ ao_win_out(CLEAR_WG, AO_Misc_611x);
+
+ bits = 0;
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ int chan;
+
+ chan = CR_CHAN(cmd->chanlist[i]);
+ bits |= 1 << chan;
+ ao_win_out(chan, AO_Waveform_Generation_611x);
+ }
+ ao_win_out(bits, AO_Timed_611x);
+ }
+
+ ni_ao_config_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len, 1);
+
+ if (cmd->stop_src == TRIG_NONE) {
+ devpriv->ao_mode1 |= AO_Continuous;
+ devpriv->ao_mode1 &= ~AO_Trigger_Once;
+ } else {
+ devpriv->ao_mode1 &= ~AO_Continuous;
+ devpriv->ao_mode1 |= AO_Trigger_Once;
+ }
+ devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ case TRIG_NOW:
+ devpriv->ao_trigger_select &=
+ ~(AO_START1_Polarity | AO_START1_Select(-1));
+ devpriv->ao_trigger_select |= AO_START1_Edge | AO_START1_Sync;
+ devpriv->stc_writew(dev, devpriv->ao_trigger_select,
+ AO_Trigger_Select_Register);
+ break;
+ case TRIG_EXT:
+ devpriv->ao_trigger_select = AO_START1_Select(CR_CHAN(cmd->start_arg)+1);
+ if (cmd->start_arg & CR_INVERT)
+ devpriv->ao_trigger_select |= AO_START1_Polarity; // 0=active high, 1=active low. see daq-stc 3-24 (p186)
+ if (cmd->start_arg & CR_EDGE)
+ devpriv->ao_trigger_select |= AO_START1_Edge; // 0=edge detection disabled, 1=enabled
+ devpriv->stc_writew(dev, devpriv->ao_trigger_select, AO_Trigger_Select_Register);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ devpriv->ao_mode3 &= ~AO_Trigger_Length;
+ devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+
+ devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ devpriv->ao_mode2 &= ~AO_BC_Initial_Load_Source;
+ devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ if (cmd->stop_src == TRIG_NONE) {
+ devpriv->stc_writel(dev, 0xffffff, AO_BC_Load_A_Register);
+ } else {
+ devpriv->stc_writel(dev, 0, AO_BC_Load_A_Register);
+ }
+ devpriv->stc_writew(dev, AO_BC_Load, AO_Command_1_Register);
+ devpriv->ao_mode2 &= ~AO_UC_Initial_Load_Source;
+ devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ if(boardtype.reg_type & ni_reg_m_series_mask)
+ {
+ // this is how the NI example code does it for m-series boards, verified correct with 6259
+ devpriv->stc_writel(dev, cmd->stop_arg - 1, AO_UC_Load_A_Register);
+ devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ }else
+ {
+ devpriv->stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register);
+ devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ devpriv->stc_writel(dev, cmd->stop_arg - 1,
+ AO_UC_Load_A_Register);
+ }
+ break;
+ case TRIG_NONE:
+ devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
+ devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
+ break;
+ default:
+ devpriv->stc_writel(dev, 0, AO_UC_Load_A_Register);
+ devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ devpriv->stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register);
+ }
+
+ devpriv->ao_mode1 &=
+ ~(AO_UI_Source_Select(0x1f) | AO_UI_Source_Polarity |
+ AO_UPDATE_Source_Select(0x1f) | AO_UPDATE_Source_Polarity);
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ devpriv->ao_cmd2 &= ~AO_BC_Gate_Enable;
+ trigvar =
+ ni_ns_to_timer(dev, cmd->scan_begin_arg,
+ TRIG_ROUND_NEAREST);
+ devpriv->stc_writel(dev, 1, AO_UI_Load_A_Register);
+ devpriv->stc_writew(dev, AO_UI_Load, AO_Command_1_Register);
+ devpriv->stc_writel(dev, trigvar, AO_UI_Load_A_Register);
+ break;
+ case TRIG_EXT:
+ devpriv->ao_mode1 |=
+ AO_UPDATE_Source_Select(cmd->scan_begin_arg);
+ if (cmd->scan_begin_arg & CR_INVERT)
+ devpriv->ao_mode1 |= AO_UPDATE_Source_Polarity;
+ devpriv->ao_cmd2 |= AO_BC_Gate_Enable;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
+ devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ devpriv->ao_mode2 &=
+ ~(AO_UI_Reload_Mode(3) | AO_UI_Initial_Load_Source);
+ devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+
+ if (cmd->scan_end_arg > 1) {
+ devpriv->ao_mode1 |= AO_Multiple_Channels;
+ devpriv->stc_writew(dev,
+ AO_Number_Of_Channels(cmd->scan_end_arg -
+ 1) |
+ AO_UPDATE_Output_Select
+ (AO_Update_Output_High_Z),
+ AO_Output_Control_Register);
+ } else {
+ unsigned bits;
+ devpriv->ao_mode1 &= ~AO_Multiple_Channels;
+ bits = AO_UPDATE_Output_Select(AO_Update_Output_High_Z);
+ if (boardtype.reg_type & (ni_reg_m_series_mask | ni_reg_6xxx_mask)) {
+ bits |= AO_Number_Of_Channels(0);
+ } else {
+ bits |= AO_Number_Of_Channels(CR_CHAN(cmd->
+ chanlist[0]));
+ }
+ devpriv->stc_writew(dev, bits,
+ AO_Output_Control_Register);
+ }
+ devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+
+ devpriv->stc_writew(dev, AO_DAC0_Update_Mode | AO_DAC1_Update_Mode,
+ AO_Command_1_Register);
+
+ devpriv->ao_mode3 |= AO_Stop_On_Overrun_Error;
+ devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+
+ devpriv->ao_mode2 &= ~AO_FIFO_Mode_Mask;
+#ifdef PCIDMA
+ devpriv->ao_mode2 |= AO_FIFO_Mode_HF_to_F;
+#else
+ devpriv->ao_mode2 |= AO_FIFO_Mode_HF;
+#endif
+ devpriv->ao_mode2 &= ~AO_FIFO_Retransmit_Enable;
+ devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+
+ bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
+ AO_TMRDACWR_Pulse_Width;
+ if (boardtype.ao_fifo_depth)
+ bits |= AO_FIFO_Enable;
+ else
+ bits |= AO_DMA_PIO_Control;
+#if 0
+ /* F Hess: windows driver does not set AO_Number_Of_DAC_Packages bit for 6281,
+ verified with bus analyzer. */
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ bits |= AO_Number_Of_DAC_Packages;
+#endif
+ devpriv->stc_writew(dev, bits, AO_Personal_Register);
+ // enable sending of ao dma requests
+ devpriv->stc_writew(dev, AO_AOFREQ_Enable, AO_Start_Select_Register);
+
+ devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->stc_writew(dev, AO_BC_TC_Interrupt_Ack,
+ Interrupt_B_Ack_Register);
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ AO_BC_TC_Interrupt_Enable, 1);
+ }
+
+ s->async->inttrig = &ni_ao_inttrig;
+
+ return 0;
+}
+
+static int ni_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ if ((cmd->flags & CMDF_WRITE) == 0) {
+ cmd->flags |= CMDF_WRITE;
+ }
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_INT | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_src == TRIG_EXT) {
+ /* external trigger */
+ unsigned int tmp = CR_CHAN(cmd->start_arg);
+
+ if (tmp > 18)
+ tmp = 18;
+ tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
+ if (cmd->start_arg != tmp) {
+ cmd->start_arg = tmp;
+ err++;
+ }
+ } else {
+ if (cmd->start_arg != 0) {
+ /* true for both TRIG_NOW and TRIG_INT */
+ cmd->start_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < boardtype.ao_speed) {
+ cmd->scan_begin_arg = boardtype.ao_speed;
+ err++;
+ }
+ if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) { /* XXX check */
+ cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff;
+ err++;
+ }
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) { /* XXX check */
+ if (cmd->stop_arg > 0x00ffffff) {
+ cmd->stop_arg = 0x00ffffff;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ cmd->scan_begin_arg =
+ ni_timer_to_ns(dev, ni_ns_to_timer(dev,
+ cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK));
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (err)
+ return 4;
+
+ /* step 5: fix up chanlist */
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int ni_ao_reset(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ //devpriv->ao0p=0x0000;
+ //ni_writew(devpriv->ao0p,AO_Configuration);
+
+ //devpriv->ao1p=AO_Channel(1);
+ //ni_writew(devpriv->ao1p,AO_Configuration);
+
+ ni_release_ao_mite_channel(dev);
+
+ devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
+ devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register);
+ ni_set_bits(dev, Interrupt_B_Enable_Register, ~0, 0);
+ devpriv->stc_writew(dev, AO_BC_Source_Select, AO_Personal_Register);
+ devpriv->stc_writew(dev, 0x3f98, Interrupt_B_Ack_Register);
+ devpriv->stc_writew(dev, AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
+ AO_TMRDACWR_Pulse_Width, AO_Personal_Register);
+ devpriv->stc_writew(dev, 0, AO_Output_Control_Register);
+ devpriv->stc_writew(dev, 0, AO_Start_Select_Register);
+ devpriv->ao_cmd1 = 0;
+ devpriv->stc_writew(dev, devpriv->ao_cmd1, AO_Command_1_Register);
+ devpriv->ao_cmd2 = 0;
+ devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
+ devpriv->ao_mode1 = 0;
+ devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ devpriv->ao_mode2 = 0;
+ devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ devpriv->ao_mode3 = AO_Last_Gate_Disable;
+ else
+ devpriv->ao_mode3 = 0;
+ devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+ devpriv->ao_trigger_select = 0;
+ devpriv->stc_writew(dev, devpriv->ao_trigger_select,
+ AO_Trigger_Select_Register);
+ if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ unsigned immediate_bits = 0;
+ unsigned i;
+ for(i = 0; i < s->n_chan; ++i)
+ {
+ immediate_bits |= 1 << i;
+ }
+ ao_win_out(immediate_bits, AO_Immediate_671x);
+ ao_win_out(CLEAR_WG, AO_Misc_611x);
+ }
+ devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
+
+ return 0;
+}
+
+// digital io
+
+static int ni_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef DEBUG_DIO
+ rt_printk("ni_dio_insn_config() chan=%d io=%d\n",
+ CR_CHAN(insn->chanspec), data[0]);
+#endif
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= 1 << CR_CHAN(insn->chanspec);
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->io_bits & (1 << CR_CHAN(insn->
+ chanspec))) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
+ devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
+ devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+
+ return 1;
+}
+
+static int ni_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef DEBUG_DIO
+ rt_printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]);
+#endif
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ /* Perform check to make sure we're not using the
+ serial part of the dio */
+ if ((data[0] & (DIO_SDIN | DIO_SDOUT))
+ && devpriv->serial_interval_ns)
+ return -EBUSY;
+
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ devpriv->dio_output &= ~DIO_Parallel_Data_Mask;
+ devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);
+ devpriv->stc_writew(dev, devpriv->dio_output,
+ DIO_Output_Register);
+ }
+ data[1] = devpriv->stc_readw(dev, DIO_Parallel_Input_Register);
+
+ return 2;
+}
+
+static int ni_m_series_dio_insn_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef DEBUG_DIO
+ rt_printk("ni_m_series_dio_insn_config() chan=%d io=%d\n",
+ CR_CHAN(insn->chanspec), data[0]);
+#endif
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= 1 << CR_CHAN(insn->chanspec);
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->io_bits & (1 << CR_CHAN(insn->
+ chanspec))) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ni_writel(s->io_bits, M_Offset_DIO_Direction);
+
+ return 1;
+}
+
+static int ni_m_series_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef DEBUG_DIO
+ rt_printk("ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0],
+ data[1]);
+#endif
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ ni_writel(s->state, M_Offset_Static_Digital_Output);
+ }
+ data[1] = ni_readl(M_Offset_Static_Digital_Input);
+
+ return 2;
+}
+
+static int ni_cdio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int sources;
+ unsigned i;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ sources = TRIG_INT;
+ cmd->start_src &= sources;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique... */
+
+ if (cmd->start_src != TRIG_INT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_NONE)
+ err++;
+ /* ... and mutually compatible */
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+ if (cmd->start_src == TRIG_INT) {
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->scan_begin_src == TRIG_EXT) {
+ tmp = cmd->scan_begin_arg;
+ tmp &= CR_PACK_FLAGS(CDO_Sample_Source_Select_Mask, 0, 0,
+ CR_INVERT);
+ if (tmp != cmd->scan_begin_arg) {
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_NOW) {
+ if (cmd->convert_arg) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if (cmd->stop_src == TRIG_NONE) {
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (err)
+ return 4;
+
+ /* step 5: check chanlist */
+
+ for (i = 0; i < cmd->chanlist_len; ++i) {
+ if (cmd->chanlist[i] != i)
+ err = 1;
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int ni_cdio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ const struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned cdo_mode_bits = CDO_FIFO_Mode_Bit | CDO_Halt_On_Error_Bit;
+ int retval;
+
+ ni_writel(CDO_Reset_Bit, M_Offset_CDIO_Command);
+ switch (cmd->scan_begin_src) {
+ case TRIG_EXT:
+ cdo_mode_bits |=
+ CR_CHAN(cmd->
+ scan_begin_arg) & CDO_Sample_Source_Select_Mask;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ if (cmd->scan_begin_arg & CR_INVERT)
+ cdo_mode_bits |= CDO_Polarity_Bit;
+ ni_writel(cdo_mode_bits, M_Offset_CDO_Mode);
+ if (s->io_bits) {
+ ni_writel(s->state, M_Offset_CDO_FIFO_Data);
+ ni_writel(CDO_SW_Update_Bit, M_Offset_CDIO_Command);
+ ni_writel(s->io_bits, M_Offset_CDO_Mask_Enable);
+ } else {
+ comedi_error(dev,
+ "attempted to run digital output command with no lines configured as outputs");
+ return -EIO;
+ }
+ retval = ni_request_cdo_mite_channel(dev);
+ if (retval < 0) {
+ return retval;
+ }
+ s->async->inttrig = &ni_cdo_inttrig;
+ return 0;
+}
+
+static int ni_cdo_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+#ifdef PCIDMA
+ unsigned long flags;
+#endif
+ int retval = 0;
+ unsigned i;
+ const unsigned timeout = 100;
+
+ s->async->inttrig = NULL;
+
+ /* read alloc the entire buffer */
+ comedi_buf_read_alloc(s->async, s->async->prealloc_bufsz);
+
+#ifdef PCIDMA
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->cdo_mite_chan) {
+ mite_prep_dma(devpriv->cdo_mite_chan, 32, 32);
+ mite_dma_arm(devpriv->cdo_mite_chan);
+ } else {
+ comedi_error(dev, "BUG: no cdo mite channel?");
+ retval = -EIO;
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+ if (retval < 0)
+ return retval;
+#endif
+// XXX not sure what interrupt C group does
+// ni_writeb(Interrupt_Group_C_Enable_Bit, M_Offset_Interrupt_C_Enable);
+ //wait for dma to fill output fifo
+ for (i = 0; i < timeout; ++i) {
+ if (ni_readl(M_Offset_CDIO_Status) & CDO_FIFO_Full_Bit)
+ break;
+ comedi_udelay(10);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "dma failed to fill cdo fifo!");
+ ni_cdio_cancel(dev, s);
+ return -EIO;
+ }
+ ni_writel(CDO_Arm_Bit | CDO_Error_Interrupt_Enable_Set_Bit |
+ CDO_Empty_FIFO_Interrupt_Enable_Set_Bit, M_Offset_CDIO_Command);
+ return retval;
+}
+
+static int ni_cdio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ ni_writel(CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit |
+ CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit |
+ CDO_FIFO_Request_Interrupt_Enable_Clear_Bit,
+ M_Offset_CDIO_Command);
+// XXX not sure what interrupt C group does
+// ni_writeb(0, M_Offset_Interrupt_C_Enable);
+ ni_writel(0, M_Offset_CDO_Mask_Enable);
+ ni_release_cdo_mite_channel(dev);
+ return 0;
+}
+
+static void handle_cdio_interrupt(struct comedi_device * dev)
+{
+ unsigned cdio_status;
+ struct comedi_subdevice *s = dev->subdevices + NI_DIO_SUBDEV;
+#ifdef PCIDMA
+ unsigned long flags;
+#endif
+
+ if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
+ return;
+ }
+#ifdef PCIDMA
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->cdo_mite_chan) {
+ unsigned cdo_mite_status =
+ mite_get_status(devpriv->cdo_mite_chan);
+ if (cdo_mite_status & CHSR_LINKC) {
+ writel(CHOR_CLRLC,
+ devpriv->mite->mite_io_addr +
+ MITE_CHOR(devpriv->cdo_mite_chan->channel));
+ }
+ mite_sync_output_dma(devpriv->cdo_mite_chan, s->async);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif
+
+ cdio_status = ni_readl(M_Offset_CDIO_Status);
+ if (cdio_status & (CDO_Overrun_Bit | CDO_Underflow_Bit)) {
+// rt_printk("cdio error: statux=0x%x\n", cdio_status);
+ ni_writel(CDO_Error_Interrupt_Confirm_Bit, M_Offset_CDIO_Command); // XXX just guessing this is needed and does something useful
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+ if (cdio_status & CDO_FIFO_Empty_Bit) {
+// rt_printk("cdio fifo empty\n");
+ ni_writel(CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit,
+ M_Offset_CDIO_Command);
+// s->async->events |= COMEDI_CB_EOA;
+ }
+ ni_event(dev, s);
+}
+
+static int ni_serial_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int err = insn->n;
+ unsigned char byte_out, byte_in = 0;
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ switch (data[0]) {
+ case INSN_CONFIG_SERIAL_CLOCK:
+
+#ifdef DEBUG_DIO
+ rt_printk("SPI serial clock Config cd\n", data[1]);
+#endif
+ devpriv->serial_hw_mode = 1;
+ devpriv->dio_control |= DIO_HW_Serial_Enable;
+
+ if (data[1] == SERIAL_DISABLED) {
+ devpriv->serial_hw_mode = 0;
+ devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
+ DIO_Software_Serial_Control);
+ data[1] = SERIAL_DISABLED;
+ devpriv->serial_interval_ns = data[1];
+ } else if (data[1] <= SERIAL_600NS) {
+ /* Warning: this clock speed is too fast to reliably
+ control SCXI. */
+ devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
+ devpriv->clock_and_fout |= Slow_Internal_Timebase;
+ devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2;
+ data[1] = SERIAL_600NS;
+ devpriv->serial_interval_ns = data[1];
+ } else if (data[1] <= SERIAL_1_2US) {
+ devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
+ devpriv->clock_and_fout |= Slow_Internal_Timebase |
+ DIO_Serial_Out_Divide_By_2;
+ data[1] = SERIAL_1_2US;
+ devpriv->serial_interval_ns = data[1];
+ } else if (data[1] <= SERIAL_10US) {
+ devpriv->dio_control |= DIO_HW_Serial_Timebase;
+ devpriv->clock_and_fout |= Slow_Internal_Timebase |
+ DIO_Serial_Out_Divide_By_2;
+ /* Note: DIO_Serial_Out_Divide_By_2 only affects
+ 600ns/1.2us. If you turn divide_by_2 off with the
+ slow clock, you will still get 10us, except then
+ all your delays are wrong. */
+ data[1] = SERIAL_10US;
+ devpriv->serial_interval_ns = data[1];
+ } else {
+ devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
+ DIO_Software_Serial_Control);
+ devpriv->serial_hw_mode = 0;
+ data[1] = (data[1] / 1000) * 1000;
+ devpriv->serial_interval_ns = data[1];
+ }
+
+ devpriv->stc_writew(dev, devpriv->dio_control,
+ DIO_Control_Register);
+ devpriv->stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+ return 1;
+
+ break;
+
+ case INSN_CONFIG_BIDIRECTIONAL_DATA:
+
+ if (devpriv->serial_interval_ns == 0) {
+ return -EINVAL;
+ }
+
+ byte_out = data[1] & 0xFF;
+
+ if (devpriv->serial_hw_mode) {
+ err = ni_serial_hw_readwrite8(dev, s, byte_out,
+ &byte_in);
+ } else if (devpriv->serial_interval_ns > 0) {
+ err = ni_serial_sw_readwrite8(dev, s, byte_out,
+ &byte_in);
+ } else {
+ rt_printk("ni_serial_insn_config: serial disabled!\n");
+ return -EINVAL;
+ }
+ if (err < 0)
+ return err;
+ data[1] = byte_in & 0xFF;
+ return insn->n;
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+}
+
+static int ni_serial_hw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned char data_out, unsigned char *data_in)
+{
+ unsigned int status1;
+ int err = 0, count = 20;
+
+#ifdef DEBUG_DIO
+ rt_printk("ni_serial_hw_readwrite8: outputting 0x%x\n", data_out);
+#endif
+
+ devpriv->dio_output &= ~DIO_Serial_Data_Mask;
+ devpriv->dio_output |= DIO_Serial_Data_Out(data_out);
+ devpriv->stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
+
+ status1 = devpriv->stc_readw(dev, Joint_Status_1_Register);
+ if (status1 & DIO_Serial_IO_In_Progress_St) {
+ err = -EBUSY;
+ goto Error;
+ }
+
+ devpriv->dio_control |= DIO_HW_Serial_Start;
+ devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+ devpriv->dio_control &= ~DIO_HW_Serial_Start;
+
+ /* Wait until STC says we're done, but don't loop infinitely. */
+ while ((status1 =
+ devpriv->stc_readw(dev,
+ Joint_Status_1_Register)) &
+ DIO_Serial_IO_In_Progress_St) {
+ /* Delay one bit per loop */
+ comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
+ if (--count < 0) {
+ rt_printk
+ ("ni_serial_hw_readwrite8: SPI serial I/O didn't finish in time!\n");
+ err = -ETIME;
+ goto Error;
+ }
+ }
+
+ /* Delay for last bit. This delay is absolutely necessary, because
+ DIO_Serial_IO_In_Progress_St goes high one bit too early. */
+ comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
+
+ if (data_in != NULL) {
+ *data_in = devpriv->stc_readw(dev, DIO_Serial_Input_Register);
+#ifdef DEBUG_DIO
+ rt_printk("ni_serial_hw_readwrite8: inputted 0x%x\n", *data_in);
+#endif
+ }
+
+ Error:
+ devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+
+ return err;
+}
+
+static int ni_serial_sw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned char data_out, unsigned char *data_in)
+{
+ unsigned char mask, input = 0;
+
+#ifdef DEBUG_DIO
+ rt_printk("ni_serial_sw_readwrite8: outputting 0x%x\n", data_out);
+#endif
+
+ /* Wait for one bit before transfer */
+ comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
+
+ for (mask = 0x80; mask; mask >>= 1) {
+ /* Output current bit; note that we cannot touch s->state
+ because it is a per-subdevice field, and serial is
+ a separate subdevice from DIO. */
+ devpriv->dio_output &= ~DIO_SDOUT;
+ if (data_out & mask) {
+ devpriv->dio_output |= DIO_SDOUT;
+ }
+ devpriv->stc_writew(dev, devpriv->dio_output,
+ DIO_Output_Register);
+
+ /* Assert SDCLK (active low, inverted), wait for half of
+ the delay, deassert SDCLK, and wait for the other half. */
+ devpriv->dio_control |= DIO_Software_Serial_Control;
+ devpriv->stc_writew(dev, devpriv->dio_control,
+ DIO_Control_Register);
+
+ comedi_udelay((devpriv->serial_interval_ns + 999) / 2000);
+
+ devpriv->dio_control &= ~DIO_Software_Serial_Control;
+ devpriv->stc_writew(dev, devpriv->dio_control,
+ DIO_Control_Register);
+
+ comedi_udelay((devpriv->serial_interval_ns + 999) / 2000);
+
+ /* Input current bit */
+ if (devpriv->stc_readw(dev,
+ DIO_Parallel_Input_Register) & DIO_SDIN) {
+/* rt_printk("DIO_P_I_R: 0x%x\n", devpriv->stc_readw(dev, DIO_Parallel_Input_Register)); */
+ input |= mask;
+ }
+ }
+#ifdef DEBUG_DIO
+ rt_printk("ni_serial_sw_readwrite8: inputted 0x%x\n", input);
+#endif
+ if (data_in)
+ *data_in = input;
+
+ return 0;
+}
+
+static void mio_common_detach(struct comedi_device * dev)
+{
+ if (dev->private) {
+ if (devpriv->counter_dev) {
+ ni_gpct_device_destroy(devpriv->counter_dev);
+ }
+ }
+ if (dev->subdevices && boardtype.has_8255)
+ subdev_8255_cleanup(dev, dev->subdevices + NI_8255_DIO_SUBDEV);
+}
+
+static void init_ao_67xx(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int i;
+
+ for (i = 0; i < s->n_chan; i++)
+ {
+ ni_ao_win_outw(dev, AO_Channel(i) | 0x0,
+ AO_Configuration_2_67xx);
+ }
+ ao_win_out(0x0, AO_Later_Single_Point_Updates);
+}
+
+static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg)
+{
+ unsigned stc_register;
+ switch (reg) {
+ case NITIO_G0_Autoincrement_Reg:
+ stc_register = G_Autoincrement_Register(0);
+ break;
+ case NITIO_G1_Autoincrement_Reg:
+ stc_register = G_Autoincrement_Register(1);
+ break;
+ case NITIO_G0_Command_Reg:
+ stc_register = G_Command_Register(0);
+ break;
+ case NITIO_G1_Command_Reg:
+ stc_register = G_Command_Register(1);
+ break;
+ case NITIO_G0_HW_Save_Reg:
+ stc_register = G_HW_Save_Register(0);
+ break;
+ case NITIO_G1_HW_Save_Reg:
+ stc_register = G_HW_Save_Register(1);
+ break;
+ case NITIO_G0_SW_Save_Reg:
+ stc_register = G_Save_Register(0);
+ break;
+ case NITIO_G1_SW_Save_Reg:
+ stc_register = G_Save_Register(1);
+ break;
+ case NITIO_G0_Mode_Reg:
+ stc_register = G_Mode_Register(0);
+ break;
+ case NITIO_G1_Mode_Reg:
+ stc_register = G_Mode_Register(1);
+ break;
+ case NITIO_G0_LoadA_Reg:
+ stc_register = G_Load_A_Register(0);
+ break;
+ case NITIO_G1_LoadA_Reg:
+ stc_register = G_Load_A_Register(1);
+ break;
+ case NITIO_G0_LoadB_Reg:
+ stc_register = G_Load_B_Register(0);
+ break;
+ case NITIO_G1_LoadB_Reg:
+ stc_register = G_Load_B_Register(1);
+ break;
+ case NITIO_G0_Input_Select_Reg:
+ stc_register = G_Input_Select_Register(0);
+ break;
+ case NITIO_G1_Input_Select_Reg:
+ stc_register = G_Input_Select_Register(1);
+ break;
+ case NITIO_G01_Status_Reg:
+ stc_register = G_Status_Register;
+ break;
+ case NITIO_G01_Joint_Reset_Reg:
+ stc_register = Joint_Reset_Register;
+ break;
+ case NITIO_G01_Joint_Status1_Reg:
+ stc_register = Joint_Status_1_Register;
+ break;
+ case NITIO_G01_Joint_Status2_Reg:
+ stc_register = Joint_Status_2_Register;
+ break;
+ case NITIO_G0_Interrupt_Acknowledge_Reg:
+ stc_register = Interrupt_A_Ack_Register;
+ break;
+ case NITIO_G1_Interrupt_Acknowledge_Reg:
+ stc_register = Interrupt_B_Ack_Register;
+ break;
+ case NITIO_G0_Status_Reg:
+ stc_register = AI_Status_1_Register;
+ break;
+ case NITIO_G1_Status_Reg:
+ stc_register = AO_Status_1_Register;
+ break;
+ case NITIO_G0_Interrupt_Enable_Reg:
+ stc_register = Interrupt_A_Enable_Register;
+ break;
+ case NITIO_G1_Interrupt_Enable_Reg:
+ stc_register = Interrupt_B_Enable_Register;
+ break;
+ default:
+ rt_printk("%s: unhandled register 0x%x in switch.\n",
+ __FUNCTION__, reg);
+ BUG();
+ return 0;
+ break;
+ }
+ return stc_register;
+}
+
+static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
+ enum ni_gpct_register reg)
+{
+ struct comedi_device *dev = counter->counter_dev->dev;
+ unsigned stc_register;
+ /* bits in the join reset register which are relevant to counters */
+ static const unsigned gpct_joint_reset_mask = G0_Reset | G1_Reset;
+ static const unsigned gpct_interrupt_a_enable_mask =
+ G0_Gate_Interrupt_Enable | G0_TC_Interrupt_Enable;
+ static const unsigned gpct_interrupt_b_enable_mask =
+ G1_Gate_Interrupt_Enable | G1_TC_Interrupt_Enable;
+
+ switch (reg) {
+ /* m-series-only registers */
+ case NITIO_G0_Counting_Mode_Reg:
+ ni_writew(bits, M_Offset_G0_Counting_Mode);
+ break;
+ case NITIO_G1_Counting_Mode_Reg:
+ ni_writew(bits, M_Offset_G1_Counting_Mode);
+ break;
+ case NITIO_G0_Second_Gate_Reg:
+ ni_writew(bits, M_Offset_G0_Second_Gate);
+ break;
+ case NITIO_G1_Second_Gate_Reg:
+ ni_writew(bits, M_Offset_G1_Second_Gate);
+ break;
+ case NITIO_G0_DMA_Config_Reg:
+ ni_writew(bits, M_Offset_G0_DMA_Config);
+ break;
+ case NITIO_G1_DMA_Config_Reg:
+ ni_writew(bits, M_Offset_G1_DMA_Config);
+ break;
+ case NITIO_G0_ABZ_Reg:
+ ni_writew(bits, M_Offset_G0_MSeries_ABZ);
+ break;
+ case NITIO_G1_ABZ_Reg:
+ ni_writew(bits, M_Offset_G1_MSeries_ABZ);
+ break;
+
+ /* 32 bit registers */
+ case NITIO_G0_LoadA_Reg:
+ case NITIO_G1_LoadA_Reg:
+ case NITIO_G0_LoadB_Reg:
+ case NITIO_G1_LoadB_Reg:
+ stc_register = ni_gpct_to_stc_register(reg);
+ devpriv->stc_writel(dev, bits, stc_register);
+ break;
+
+ /* 16 bit registers */
+ case NITIO_G0_Interrupt_Enable_Reg:
+ BUG_ON(bits & ~gpct_interrupt_a_enable_mask);
+ ni_set_bitfield(dev, Interrupt_A_Enable_Register,
+ gpct_interrupt_a_enable_mask, bits);
+ break;
+ case NITIO_G1_Interrupt_Enable_Reg:
+ BUG_ON(bits & ~gpct_interrupt_b_enable_mask);
+ ni_set_bitfield(dev, Interrupt_B_Enable_Register,
+ gpct_interrupt_b_enable_mask, bits);
+ break;
+ case NITIO_G01_Joint_Reset_Reg:
+ BUG_ON(bits & ~gpct_joint_reset_mask);
+ /* fall-through */
+ default:
+ stc_register = ni_gpct_to_stc_register(reg);
+ devpriv->stc_writew(dev, bits, stc_register);
+ }
+}
+
+static unsigned ni_gpct_read_register(struct ni_gpct *counter,
+ enum ni_gpct_register reg)
+{
+ struct comedi_device *dev = counter->counter_dev->dev;
+ unsigned stc_register;
+ switch (reg) {
+ /* m-series only registers */
+ case NITIO_G0_DMA_Status_Reg:
+ return ni_readw(M_Offset_G0_DMA_Status);
+ break;
+ case NITIO_G1_DMA_Status_Reg:
+ return ni_readw(M_Offset_G1_DMA_Status);
+ break;
+
+ /* 32 bit registers */
+ case NITIO_G0_HW_Save_Reg:
+ case NITIO_G1_HW_Save_Reg:
+ case NITIO_G0_SW_Save_Reg:
+ case NITIO_G1_SW_Save_Reg:
+ stc_register = ni_gpct_to_stc_register(reg);
+ return devpriv->stc_readl(dev, stc_register);
+ break;
+
+ /* 16 bit registers */
+ default:
+ stc_register = ni_gpct_to_stc_register(reg);
+ return devpriv->stc_readw(dev, stc_register);
+ break;
+ }
+ return 0;
+}
+
+static int ni_freq_out_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->clock_and_fout & FOUT_Divider_mask;
+ return 1;
+}
+
+static int ni_freq_out_insn_write(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ devpriv->clock_and_fout &= ~FOUT_Enable;
+ devpriv->stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+ devpriv->clock_and_fout &= ~FOUT_Divider_mask;
+ devpriv->clock_and_fout |= FOUT_Divider(data[0]);
+ devpriv->clock_and_fout |= FOUT_Enable;
+ devpriv->stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+ return insn->n;
+}
+
+static int ni_set_freq_out_clock(struct comedi_device * dev, unsigned int clock_source)
+{
+ switch (clock_source) {
+ case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC:
+ devpriv->clock_and_fout &= ~FOUT_Timebase_Select;
+ break;
+ case NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC:
+ devpriv->clock_and_fout |= FOUT_Timebase_Select;
+ break;
+ default:
+ return -EINVAL;
+ }
+ devpriv->stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+ return 3;
+}
+
+static void ni_get_freq_out_clock(struct comedi_device * dev, unsigned int * clock_source,
+ unsigned int * clock_period_ns)
+{
+ if (devpriv->clock_and_fout & FOUT_Timebase_Select) {
+ *clock_source = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC;
+ *clock_period_ns = TIMEBASE_2_NS;
+ } else {
+ *clock_source = NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC;
+ *clock_period_ns = TIMEBASE_1_NS * 2;
+ }
+}
+
+static int ni_freq_out_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case INSN_CONFIG_SET_CLOCK_SRC:
+ return ni_set_freq_out_clock(dev, data[1]);
+ break;
+ case INSN_CONFIG_GET_CLOCK_SRC:
+ ni_get_freq_out_clock(dev, &data[1], &data[2]);
+ return 3;
+ default:
+ break;
+ }
+ return -EINVAL;
+}
+
+static int ni_alloc_private(struct comedi_device * dev)
+{
+ int ret;
+
+ ret = alloc_private(dev, sizeof(ni_private));
+ if (ret < 0)
+ return ret;
+
+ spin_lock_init(&devpriv->window_lock);
+ spin_lock_init(&devpriv->soft_reg_copy_lock);
+ spin_lock_init(&devpriv->mite_channel_lock);
+
+ return 0;
+};
+
+static int ni_E_init(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned j;
+ enum ni_gpct_variant counter_variant;
+
+ if (boardtype.n_aochan > MAX_N_AO_CHAN) {
+ printk("bug! boardtype.n_aochan > MAX_N_AO_CHAN\n");
+ return -EINVAL;
+ }
+
+ if (alloc_subdevices(dev, NI_NUM_SUBDEVICES) < 0)
+ return -ENOMEM;
+
+ /* analog input subdevice */
+
+ s = dev->subdevices + NI_AI_SUBDEV;
+ dev->read_subdev = s;
+ if (boardtype.n_adchan) {
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags =
+ SDF_READABLE | SDF_DIFF | SDF_DITHER | SDF_CMD_READ;
+ if (boardtype.reg_type != ni_reg_611x)
+ s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
+ if (boardtype.adbits > 16)
+ s->subdev_flags |= SDF_LSAMPL;
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ s->subdev_flags |= SDF_SOFT_CALIBRATED;
+ s->n_chan = boardtype.n_adchan;
+ s->len_chanlist = 512;
+ s->maxdata = (1 << boardtype.adbits) - 1;
+ s->range_table = ni_range_lkup[boardtype.gainlkup];
+ s->insn_read = &ni_ai_insn_read;
+ s->insn_config = &ni_ai_insn_config;
+ s->do_cmdtest = &ni_ai_cmdtest;
+ s->do_cmd = &ni_ai_cmd;
+ s->cancel = &ni_ai_reset;
+ s->poll = &ni_ai_poll;
+ s->munge = &ni_ai_munge;
+#ifdef PCIDMA
+ s->async_dma_dir = DMA_FROM_DEVICE;
+#endif
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* analog output subdevice */
+
+ s = dev->subdevices + NI_AO_SUBDEV;
+ if (boardtype.n_aochan) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND;
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ s->subdev_flags |= SDF_SOFT_CALIBRATED;
+ s->n_chan = boardtype.n_aochan;
+ s->maxdata = (1 << boardtype.aobits) - 1;
+ s->range_table = boardtype.ao_range_table;
+ s->insn_read = &ni_ao_insn_read;
+ if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ s->insn_write = &ni_ao_insn_write_671x;
+ } else {
+ s->insn_write = &ni_ao_insn_write;
+ }
+ s->insn_config = &ni_ao_insn_config;
+#ifdef PCIDMA
+ if (boardtype.n_aochan) {
+ s->async_dma_dir = DMA_TO_DEVICE;
+#else
+ if (boardtype.ao_fifo_depth) {
+#endif
+ dev->write_subdev = s;
+ s->subdev_flags |= SDF_CMD_WRITE;
+ s->do_cmd = &ni_ao_cmd;
+ s->do_cmdtest = &ni_ao_cmdtest;
+ s->len_chanlist = boardtype.n_aochan;
+ if ((boardtype.reg_type & ni_reg_m_series_mask) == 0)
+ s->munge = ni_ao_munge;
+ }
+ s->cancel = &ni_ao_reset;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ if ((boardtype.reg_type & ni_reg_67xx_mask))
+ init_ao_67xx(dev, s);
+
+ /* digital i/o subdevice */
+
+ s = dev->subdevices + NI_DIO_SUBDEV;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->maxdata = 1;
+ s->io_bits = 0; /* all bits input */
+ s->range_table = &range_digital;
+ s->n_chan = boardtype.num_p0_dio_channels;
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ s->subdev_flags |=
+ SDF_LSAMPL | SDF_CMD_WRITE /* | SDF_CMD_READ */ ;
+ s->insn_bits = &ni_m_series_dio_insn_bits;
+ s->insn_config = &ni_m_series_dio_insn_config;
+ s->do_cmd = &ni_cdio_cmd;
+ s->do_cmdtest = &ni_cdio_cmdtest;
+ s->cancel = &ni_cdio_cancel;
+ s->async_dma_dir = DMA_BIDIRECTIONAL;
+ s->len_chanlist = s->n_chan;
+
+ ni_writel(CDO_Reset_Bit | CDI_Reset_Bit, M_Offset_CDIO_Command);
+ ni_writel(s->io_bits, M_Offset_DIO_Direction);
+ } else {
+ s->insn_bits = &ni_dio_insn_bits;
+ s->insn_config = &ni_dio_insn_config;
+ devpriv->dio_control = DIO_Pins_Dir(s->io_bits);
+ ni_writew(devpriv->dio_control, DIO_Control_Register);
+ }
+
+ /* 8255 device */
+ s = dev->subdevices + NI_8255_DIO_SUBDEV;
+ if (boardtype.has_8255) {
+ subdev_8255_init(dev, s, ni_8255_callback, (unsigned long)dev);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* formerly general purpose counter/timer device, but no longer used */
+ s = dev->subdevices + NI_UNUSED_SUBDEV;
+ s->type = COMEDI_SUBD_UNUSED;
+
+ /* calibration subdevice -- ai and ao */
+ s = dev->subdevices + NI_CALIBRATION_SUBDEV;
+ s->type = COMEDI_SUBD_CALIB;
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ // internal PWM analog output used for AI nonlinearity calibration
+ s->subdev_flags = SDF_INTERNAL;
+ s->insn_config = &ni_m_series_pwm_config;
+ s->n_chan = 1;
+ s->maxdata = 0;
+ ni_writel(0x0, M_Offset_Cal_PWM);
+ } else if (boardtype.reg_type == ni_reg_6143) {
+ // internal PWM analog output used for AI nonlinearity calibration
+ s->subdev_flags = SDF_INTERNAL;
+ s->insn_config = &ni_6143_pwm_config;
+ s->n_chan = 1;
+ s->maxdata = 0;
+ } else {
+ s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
+ s->insn_read = &ni_calib_insn_read;
+ s->insn_write = &ni_calib_insn_write;
+ caldac_setup(dev, s);
+ }
+
+ /* EEPROM */
+ s = dev->subdevices + NI_EEPROM_SUBDEV;
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+ s->maxdata = 0xff;
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ s->n_chan = M_SERIES_EEPROM_SIZE;
+ s->insn_read = &ni_m_series_eeprom_insn_read;
+ } else {
+ s->n_chan = 512;
+ s->insn_read = &ni_eeprom_insn_read;
+ }
+
+ /* PFI */
+ s = dev->subdevices + NI_PFI_DIO_SUBDEV;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ unsigned i;
+ s->n_chan = 16;
+ ni_writew(s->state, M_Offset_PFI_DO);
+ for (i = 0; i < NUM_PFI_OUTPUT_SELECT_REGS; ++i) {
+ ni_writew(devpriv->pfi_output_select_reg[i],
+ M_Offset_PFI_Output_Select(i + 1));
+ }
+ } else {
+ s->n_chan = 10;
+ }
+ s->maxdata = 1;
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ s->insn_bits = &ni_pfi_insn_bits;
+ }
+ s->insn_config = &ni_pfi_insn_config;
+ ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0);
+
+ /* cs5529 calibration adc */
+ s = dev->subdevices + NI_CS5529_CALIBRATION_SUBDEV;
+ if (boardtype.reg_type & ni_reg_67xx_mask) {
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL;
+ // one channel for each analog output channel
+ s->n_chan = boardtype.n_aochan;
+ s->maxdata = (1 << 16) - 1;
+ s->range_table = &range_unknown; /* XXX */
+ s->insn_read = cs5529_ai_insn_read;
+ s->insn_config = NULL;
+ init_cs5529(dev);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* Serial */
+ s = dev->subdevices + NI_SERIAL_SUBDEV;
+ s->type = COMEDI_SUBD_SERIAL;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 1;
+ s->maxdata = 0xff;
+ s->insn_config = ni_serial_insn_config;
+ devpriv->serial_interval_ns = 0;
+ devpriv->serial_hw_mode = 0;
+
+ /* RTSI */
+ s = dev->subdevices + NI_RTSI_SUBDEV;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->insn_bits = ni_rtsi_insn_bits;
+ s->insn_config = ni_rtsi_insn_config;
+ ni_rtsi_init(dev);
+
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ counter_variant = ni_gpct_variant_m_series;
+ } else {
+ counter_variant = ni_gpct_variant_e_series;
+ }
+ devpriv->counter_dev = ni_gpct_device_construct(dev,
+ &ni_gpct_write_register, &ni_gpct_read_register,
+ counter_variant, NUM_GPCT);
+ /* General purpose counters */
+ for (j = 0; j < NUM_GPCT; ++j) {
+ s = dev->subdevices + NI_GPCT_SUBDEV(j);
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ
+ /* | SDF_CMD_WRITE */ ;
+ s->n_chan = 3;
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ s->maxdata = 0xffffffff;
+ else
+ s->maxdata = 0xffffff;
+ s->insn_read = &ni_gpct_insn_read;
+ s->insn_write = &ni_gpct_insn_write;
+ s->insn_config = &ni_gpct_insn_config;
+ s->do_cmd = &ni_gpct_cmd;
+ s->len_chanlist = 1;
+ s->do_cmdtest = &ni_gpct_cmdtest;
+ s->cancel = &ni_gpct_cancel;
+ s->async_dma_dir = DMA_BIDIRECTIONAL;
+ s->private = &devpriv->counter_dev->counters[j];
+
+ devpriv->counter_dev->counters[j].chip_index = 0;
+ devpriv->counter_dev->counters[j].counter_index = j;
+ ni_tio_init_counter(&devpriv->counter_dev->counters[j]);
+ }
+
+ /* Frequency output */
+ s = dev->subdevices + NI_FREQ_OUT_SUBDEV;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 1;
+ s->maxdata = 0xf;
+ s->insn_read = &ni_freq_out_insn_read;
+ s->insn_write = &ni_freq_out_insn_write;
+ s->insn_config = &ni_freq_out_insn_config;
+
+ /* ai configuration */
+ ni_ai_reset(dev, dev->subdevices + NI_AI_SUBDEV);
+ if ((boardtype.reg_type & ni_reg_6xxx_mask) == 0) {
+ // BEAM is this needed for PCI-6143 ??
+ devpriv->clock_and_fout =
+ Slow_Internal_Time_Divide_By_2 |
+ Slow_Internal_Timebase |
+ Clock_To_Board_Divide_By_2 |
+ Clock_To_Board |
+ AI_Output_Divide_By_2 | AO_Output_Divide_By_2;
+ } else {
+ devpriv->clock_and_fout =
+ Slow_Internal_Time_Divide_By_2 |
+ Slow_Internal_Timebase |
+ Clock_To_Board_Divide_By_2 | Clock_To_Board;
+ }
+ devpriv->stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+
+ /* analog output configuration */
+ ni_ao_reset(dev, dev->subdevices + NI_AO_SUBDEV);
+
+ if (dev->irq) {
+ devpriv->stc_writew(dev,
+ (IRQ_POLARITY ? Interrupt_Output_Polarity : 0) |
+ (Interrupt_Output_On_3_Pins & 0) | Interrupt_A_Enable |
+ Interrupt_B_Enable |
+ Interrupt_A_Output_Select(interrupt_pin(dev->
+ irq)) |
+ Interrupt_B_Output_Select(interrupt_pin(dev->irq)),
+ Interrupt_Control_Register);
+ }
+
+ /* DMA setup */
+ ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
+ ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
+
+ if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ ni_writeb(0, Magic_611x);
+ } else if (boardtype.reg_type & ni_reg_m_series_mask) {
+ int channel;
+ for (channel = 0; channel < boardtype.n_aochan; ++channel) {
+ ni_writeb(0xf, M_Offset_AO_Waveform_Order(channel));
+ ni_writeb(0x0,
+ M_Offset_AO_Reference_Attenuation(channel));
+ }
+ ni_writeb(0x0, M_Offset_AO_Calibration);
+ }
+
+ printk("\n");
+ return 0;
+}
+
+static int ni_8255_callback(int dir, int port, int data, unsigned long arg)
+{
+ struct comedi_device *dev = (struct comedi_device *) arg;
+
+ if (dir) {
+ ni_writeb(data, Port_A + 2 * port);
+ return 0;
+ } else {
+ return ni_readb(Port_A + 2 * port);
+ }
+}
+
+/*
+ presents the EEPROM as a subdevice
+*/
+
+static int ni_eeprom_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = ni_read_eeprom(dev, CR_CHAN(insn->chanspec));
+
+ return 1;
+}
+
+/*
+ reads bytes out of eeprom
+*/
+
+static int ni_read_eeprom(struct comedi_device * dev, int addr)
+{
+ int bit;
+ int bitstring;
+
+ bitstring = 0x0300 | ((addr & 0x100) << 3) | (addr & 0xff);
+ ni_writeb(0x04, Serial_Command);
+ for (bit = 0x8000; bit; bit >>= 1) {
+ ni_writeb(0x04 | ((bit & bitstring) ? 0x02 : 0),
+ Serial_Command);
+ ni_writeb(0x05 | ((bit & bitstring) ? 0x02 : 0),
+ Serial_Command);
+ }
+ bitstring = 0;
+ for (bit = 0x80; bit; bit >>= 1) {
+ ni_writeb(0x04, Serial_Command);
+ ni_writeb(0x05, Serial_Command);
+ bitstring |= ((ni_readb(XXX_Status) & PROMOUT) ? bit : 0);
+ }
+ ni_writeb(0x00, Serial_Command);
+
+ return bitstring;
+}
+
+static int ni_m_series_eeprom_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int ni_get_pwm_config(struct comedi_device * dev, unsigned int * data)
+{
+ data[1] = devpriv->pwm_up_count * devpriv->clock_ns;
+ data[2] = devpriv->pwm_down_count * devpriv->clock_ns;
+ return 3;
+}
+
+static int ni_m_series_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned up_count, down_count;
+ switch (data[0]) {
+ case INSN_CONFIG_PWM_OUTPUT:
+ switch (data[1]) {
+ case TRIG_ROUND_NEAREST:
+ up_count =
+ (data[2] +
+ devpriv->clock_ns / 2) / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_DOWN:
+ up_count = data[2] / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_UP:
+ up_count =
+ (data[2] + devpriv->clock_ns -
+ 1) / devpriv->clock_ns;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ switch (data[3]) {
+ case TRIG_ROUND_NEAREST:
+ down_count =
+ (data[4] +
+ devpriv->clock_ns / 2) / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_DOWN:
+ down_count = data[4] / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_UP:
+ down_count =
+ (data[4] + devpriv->clock_ns -
+ 1) / devpriv->clock_ns;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ if (up_count * devpriv->clock_ns != data[2] ||
+ down_count * devpriv->clock_ns != data[4]) {
+ data[2] = up_count * devpriv->clock_ns;
+ data[4] = down_count * devpriv->clock_ns;
+ return -EAGAIN;
+ }
+ ni_writel(MSeries_Cal_PWM_High_Time_Bits(up_count) |
+ MSeries_Cal_PWM_Low_Time_Bits(down_count),
+ M_Offset_Cal_PWM);
+ devpriv->pwm_up_count = up_count;
+ devpriv->pwm_down_count = down_count;
+ return 5;
+ break;
+ case INSN_CONFIG_GET_PWM_OUTPUT:
+ return ni_get_pwm_config(dev, data);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+static int ni_6143_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned up_count, down_count;
+ switch (data[0]) {
+ case INSN_CONFIG_PWM_OUTPUT:
+ switch (data[1]) {
+ case TRIG_ROUND_NEAREST:
+ up_count =
+ (data[2] +
+ devpriv->clock_ns / 2) / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_DOWN:
+ up_count = data[2] / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_UP:
+ up_count =
+ (data[2] + devpriv->clock_ns -
+ 1) / devpriv->clock_ns;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ switch (data[3]) {
+ case TRIG_ROUND_NEAREST:
+ down_count =
+ (data[4] +
+ devpriv->clock_ns / 2) / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_DOWN:
+ down_count = data[4] / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_UP:
+ down_count =
+ (data[4] + devpriv->clock_ns -
+ 1) / devpriv->clock_ns;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ if (up_count * devpriv->clock_ns != data[2] ||
+ down_count * devpriv->clock_ns != data[4]) {
+ data[2] = up_count * devpriv->clock_ns;
+ data[4] = down_count * devpriv->clock_ns;
+ return -EAGAIN;
+ }
+ ni_writel(up_count, Calibration_HighTime_6143);
+ devpriv->pwm_up_count = up_count;
+ ni_writel(down_count, Calibration_LowTime_6143);
+ devpriv->pwm_down_count = down_count;
+ return 5;
+ break;
+ case INSN_CONFIG_GET_PWM_OUTPUT:
+ return ni_get_pwm_config(dev, data);
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+static void ni_write_caldac(struct comedi_device * dev, int addr, int val);
+/*
+ calibration subdevice
+*/
+static int ni_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ ni_write_caldac(dev, CR_CHAN(insn->chanspec), data[0]);
+
+ return 1;
+}
+
+static int ni_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int pack_mb88341(int addr, int val, int *bitstring);
+static int pack_dac8800(int addr, int val, int *bitstring);
+static int pack_dac8043(int addr, int val, int *bitstring);
+static int pack_ad8522(int addr, int val, int *bitstring);
+static int pack_ad8804(int addr, int val, int *bitstring);
+static int pack_ad8842(int addr, int val, int *bitstring);
+
+struct caldac_struct {
+ int n_chans;
+ int n_bits;
+ int (*packbits) (int, int, int *);
+};
+
+static struct caldac_struct caldacs[] = {
+ [mb88341] = {12, 8, pack_mb88341},
+ [dac8800] = {8, 8, pack_dac8800},
+ [dac8043] = {1, 12, pack_dac8043},
+ [ad8522] = {2, 12, pack_ad8522},
+ [ad8804] = {12, 8, pack_ad8804},
+ [ad8842] = {8, 8, pack_ad8842},
+ [ad8804_debug] = {16, 8, pack_ad8804},
+};
+
+static void caldac_setup(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int i, j;
+ int n_dacs;
+ int n_chans = 0;
+ int n_bits;
+ int diffbits = 0;
+ int type;
+ int chan;
+
+ type = boardtype.caldac[0];
+ if (type == caldac_none)
+ return;
+ n_bits = caldacs[type].n_bits;
+ for (i = 0; i < 3; i++) {
+ type = boardtype.caldac[i];
+ if (type == caldac_none)
+ break;
+ if (caldacs[type].n_bits != n_bits)
+ diffbits = 1;
+ n_chans += caldacs[type].n_chans;
+ }
+ n_dacs = i;
+ s->n_chan = n_chans;
+
+ if (diffbits) {
+ unsigned int *maxdata_list;
+
+ if (n_chans > MAX_N_CALDACS) {
+ printk("BUG! MAX_N_CALDACS too small\n");
+ }
+ s->maxdata_list = maxdata_list = devpriv->caldac_maxdata_list;
+ chan = 0;
+ for (i = 0; i < n_dacs; i++) {
+ type = boardtype.caldac[i];
+ for (j = 0; j < caldacs[type].n_chans; j++) {
+ maxdata_list[chan] =
+ (1 << caldacs[type].n_bits) - 1;
+ chan++;
+ }
+ }
+
+ for (chan = 0; chan < s->n_chan; chan++)
+ ni_write_caldac(dev, i, s->maxdata_list[i] / 2);
+ } else {
+ type = boardtype.caldac[0];
+ s->maxdata = (1 << caldacs[type].n_bits) - 1;
+
+ for (chan = 0; chan < s->n_chan; chan++)
+ ni_write_caldac(dev, i, s->maxdata / 2);
+ }
+}
+
+static void ni_write_caldac(struct comedi_device * dev, int addr, int val)
+{
+ unsigned int loadbit = 0, bits = 0, bit, bitstring = 0;
+ int i;
+ int type;
+
+ //printk("ni_write_caldac: chan=%d val=%d\n",addr,val);
+ if (devpriv->caldacs[addr] == val)
+ return;
+ devpriv->caldacs[addr] = val;
+
+ for (i = 0; i < 3; i++) {
+ type = boardtype.caldac[i];
+ if (type == caldac_none)
+ break;
+ if (addr < caldacs[type].n_chans) {
+ bits = caldacs[type].packbits(addr, val, &bitstring);
+ loadbit = SerDacLd(i);
+ //printk("caldac: using i=%d addr=%d %x\n",i,addr,bitstring);
+ break;
+ }
+ addr -= caldacs[type].n_chans;
+ }
+
+ for (bit = 1 << (bits - 1); bit; bit >>= 1) {
+ ni_writeb(((bit & bitstring) ? 0x02 : 0), Serial_Command);
+ comedi_udelay(1);
+ ni_writeb(1 | ((bit & bitstring) ? 0x02 : 0), Serial_Command);
+ comedi_udelay(1);
+ }
+ ni_writeb(loadbit, Serial_Command);
+ comedi_udelay(1);
+ ni_writeb(0, Serial_Command);
+}
+
+static int pack_mb88341(int addr, int val, int *bitstring)
+{
+ /*
+ Fujitsu MB 88341
+ Note that address bits are reversed. Thanks to
+ Ingo Keen for noticing this.
+
+ Note also that the 88341 expects address values from
+ 1-12, whereas we use channel numbers 0-11. The NI
+ docs use 1-12, also, so be careful here.
+ */
+ addr++;
+ *bitstring = ((addr & 0x1) << 11) |
+ ((addr & 0x2) << 9) |
+ ((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff);
+ return 12;
+}
+
+static int pack_dac8800(int addr, int val, int *bitstring)
+{
+ *bitstring = ((addr & 0x7) << 8) | (val & 0xff);
+ return 11;
+}
+
+static int pack_dac8043(int addr, int val, int *bitstring)
+{
+ *bitstring = val & 0xfff;
+ return 12;
+}
+
+static int pack_ad8522(int addr, int val, int *bitstring)
+{
+ *bitstring = (val & 0xfff) | (addr ? 0xc000 : 0xa000);
+ return 16;
+}
+
+static int pack_ad8804(int addr, int val, int *bitstring)
+{
+ *bitstring = ((addr & 0xf) << 8) | (val & 0xff);
+ return 12;
+}
+
+static int pack_ad8842(int addr, int val, int *bitstring)
+{
+ *bitstring = ((addr + 1) << 8) | (val & 0xff);
+ return 12;
+}
+
+#if 0
+/*
+ * Read the GPCTs current value.
+ */
+static int GPCT_G_Watch(struct comedi_device * dev, int chan)
+{
+ unsigned int hi1, hi2, lo;
+
+ devpriv->gpct_command[chan] &= ~G_Save_Trace;
+ devpriv->stc_writew(dev, devpriv->gpct_command[chan],
+ G_Command_Register(chan));
+
+ devpriv->gpct_command[chan] |= G_Save_Trace;
+ devpriv->stc_writew(dev, devpriv->gpct_command[chan],
+ G_Command_Register(chan));
+
+ /* This procedure is used because the two registers cannot
+ * be read atomically. */
+ do {
+ hi1 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
+ lo = devpriv->stc_readw(dev, G_Save_Register_Low(chan));
+ hi2 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
+ } while (hi1 != hi2);
+
+ return (hi1 << 16) | lo;
+}
+
+static void GPCT_Reset(struct comedi_device * dev, int chan)
+{
+ int temp_ack_reg = 0;
+
+ //printk("GPCT_Reset...");
+ devpriv->gpct_cur_operation[chan] = GPCT_RESET;
+
+ switch (chan) {
+ case 0:
+ devpriv->stc_writew(dev, G0_Reset, Joint_Reset_Register);
+ ni_set_bits(dev, Interrupt_A_Enable_Register,
+ G0_TC_Interrupt_Enable, 0);
+ ni_set_bits(dev, Interrupt_A_Enable_Register,
+ G0_Gate_Interrupt_Enable, 0);
+ temp_ack_reg |= G0_Gate_Error_Confirm;
+ temp_ack_reg |= G0_TC_Error_Confirm;
+ temp_ack_reg |= G0_TC_Interrupt_Ack;
+ temp_ack_reg |= G0_Gate_Interrupt_Ack;
+ devpriv->stc_writew(dev, temp_ack_reg,
+ Interrupt_A_Ack_Register);
+
+ //problem...this interferes with the other ctr...
+ devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable;
+ devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
+ Analog_Trigger_Etc_Register);
+ break;
+ case 1:
+ devpriv->stc_writew(dev, G1_Reset, Joint_Reset_Register);
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ G1_TC_Interrupt_Enable, 0);
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ G0_Gate_Interrupt_Enable, 0);
+ temp_ack_reg |= G1_Gate_Error_Confirm;
+ temp_ack_reg |= G1_TC_Error_Confirm;
+ temp_ack_reg |= G1_TC_Interrupt_Ack;
+ temp_ack_reg |= G1_Gate_Interrupt_Ack;
+ devpriv->stc_writew(dev, temp_ack_reg,
+ Interrupt_B_Ack_Register);
+
+ devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable;
+ devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
+ Analog_Trigger_Etc_Register);
+ break;
+ };
+
+ devpriv->gpct_mode[chan] = 0;
+ devpriv->gpct_input_select[chan] = 0;
+ devpriv->gpct_command[chan] = 0;
+
+ devpriv->gpct_command[chan] |= G_Synchronized_Gate;
+
+ devpriv->stc_writew(dev, devpriv->gpct_mode[chan],
+ G_Mode_Register(chan));
+ devpriv->stc_writew(dev, devpriv->gpct_input_select[chan],
+ G_Input_Select_Register(chan));
+ devpriv->stc_writew(dev, 0, G_Autoincrement_Register(chan));
+
+ //printk("exit GPCT_Reset\n");
+}
+
+#endif
+
+static int ni_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct ni_gpct *counter = s->private;
+ return ni_tio_insn_config(counter, insn, data);
+}
+
+static int ni_gpct_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct ni_gpct *counter = s->private;
+ return ni_tio_rinsn(counter, insn, data);
+}
+
+static int ni_gpct_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct ni_gpct *counter = s->private;
+ return ni_tio_winsn(counter, insn, data);
+}
+
+static int ni_gpct_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int retval;
+#ifdef PCIDMA
+ struct ni_gpct *counter = s->private;
+// const struct comedi_cmd *cmd = &s->async->cmd;
+
+ retval = ni_request_gpct_mite_channel(dev, counter->counter_index,
+ COMEDI_INPUT);
+ if (retval) {
+ comedi_error(dev,
+ "no dma channel available for use by counter");
+ return retval;
+ }
+ ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
+ ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
+ retval = ni_tio_cmd(counter, s->async);
+#else
+ retval = -ENOTSUPP;
+#endif
+ return retval;
+}
+
+static int ni_gpct_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+#ifdef PCIDMA
+ struct ni_gpct *counter = s->private;
+
+ return ni_tio_cmdtest(counter, cmd);
+#else
+ return -ENOTSUPP;
+#endif
+}
+
+static int ni_gpct_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+#ifdef PCIDMA
+ struct ni_gpct *counter = s->private;
+ int retval;
+
+ retval = ni_tio_cancel(counter);
+ ni_e_series_enable_second_irq(dev, counter->counter_index, 0);
+ ni_release_gpct_mite_channel(dev, counter->counter_index);
+ return retval;
+#else
+ return 0;
+#endif
+}
+
+/*
+ *
+ * Programmable Function Inputs
+ *
+ */
+
+static int ni_m_series_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+ unsigned source)
+{
+ unsigned pfi_reg_index;
+ unsigned array_offset;
+ if ((source & 0x1f) != source)
+ return -EINVAL;
+ pfi_reg_index = 1 + chan / 3;
+ array_offset = pfi_reg_index - 1;
+ devpriv->pfi_output_select_reg[array_offset] &=
+ ~MSeries_PFI_Output_Select_Mask(chan);
+ devpriv->pfi_output_select_reg[array_offset] |=
+ MSeries_PFI_Output_Select_Bits(chan, source);
+ ni_writew(devpriv->pfi_output_select_reg[array_offset],
+ M_Offset_PFI_Output_Select(pfi_reg_index));
+ return 2;
+}
+
+static int ni_old_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+ unsigned source)
+{
+ // pre-m-series boards have fixed signals on pfi pins
+ if (source != ni_old_get_pfi_routing(dev, chan))
+ return -EINVAL;
+ return 2;
+}
+
+static int ni_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+ unsigned source)
+{
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ return ni_m_series_set_pfi_routing(dev, chan, source);
+ else
+ return ni_old_set_pfi_routing(dev, chan, source);
+}
+
+static unsigned ni_m_series_get_pfi_routing(struct comedi_device * dev, unsigned chan)
+{
+ const unsigned array_offset = chan / 3;
+ return MSeries_PFI_Output_Select_Source(chan,
+ devpriv->pfi_output_select_reg[array_offset]);
+}
+
+static unsigned ni_old_get_pfi_routing(struct comedi_device * dev, unsigned chan)
+{
+ // pre-m-series boards have fixed signals on pfi pins
+ switch (chan) {
+ case 0:
+ return NI_PFI_OUTPUT_AI_START1;
+ break;
+ case 1:
+ return NI_PFI_OUTPUT_AI_START2;
+ break;
+ case 2:
+ return NI_PFI_OUTPUT_AI_CONVERT;
+ break;
+ case 3:
+ return NI_PFI_OUTPUT_G_SRC1;
+ break;
+ case 4:
+ return NI_PFI_OUTPUT_G_GATE1;
+ break;
+ case 5:
+ return NI_PFI_OUTPUT_AO_UPDATE_N;
+ break;
+ case 6:
+ return NI_PFI_OUTPUT_AO_START1;
+ break;
+ case 7:
+ return NI_PFI_OUTPUT_AI_START_PULSE;
+ break;
+ case 8:
+ return NI_PFI_OUTPUT_G_SRC0;
+ break;
+ case 9:
+ return NI_PFI_OUTPUT_G_GATE0;
+ break;
+ default:
+ rt_printk("%s: bug, unhandled case in switch.\n", __FUNCTION__);
+ break;
+ }
+ return 0;
+}
+
+static unsigned ni_get_pfi_routing(struct comedi_device * dev, unsigned chan)
+{
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ return ni_m_series_get_pfi_routing(dev, chan);
+ else
+ return ni_old_get_pfi_routing(dev, chan);
+}
+
+static int ni_config_filter(struct comedi_device * dev, unsigned pfi_channel,
+ enum ni_pfi_filter_select filter)
+{
+ unsigned bits;
+ if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
+ return -ENOTSUPP;
+ }
+ bits = ni_readl(M_Offset_PFI_Filter);
+ bits &= ~MSeries_PFI_Filter_Select_Mask(pfi_channel);
+ bits |= MSeries_PFI_Filter_Select_Bits(pfi_channel, filter);
+ ni_writel(bits, M_Offset_PFI_Filter);
+ return 0;
+}
+
+static int ni_pfi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
+ return -ENOTSUPP;
+ }
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ ni_writew(s->state, M_Offset_PFI_DO);
+ }
+ data[1] = ni_readw(M_Offset_PFI_DI);
+ return 2;
+}
+
+static int ni_pfi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int chan;
+
+ if (insn->n < 1)
+ return -EINVAL;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ switch (data[0]) {
+ case COMEDI_OUTPUT:
+ ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 1);
+ break;
+ case COMEDI_INPUT:
+ ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 0);
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (devpriv->
+ io_bidirection_pin_reg & (1 << chan)) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return 0;
+ break;
+ case INSN_CONFIG_SET_ROUTING:
+ return ni_set_pfi_routing(dev, chan, data[1]);
+ break;
+ case INSN_CONFIG_GET_ROUTING:
+ data[1] = ni_get_pfi_routing(dev, chan);
+ break;
+ case INSN_CONFIG_FILTER:
+ return ni_config_filter(dev, chan, data[1]);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ *
+ * NI RTSI Bus Functions
+ *
+ */
+static void ni_rtsi_init(struct comedi_device * dev)
+{
+ // Initialises the RTSI bus signal switch to a default state
+
+ // Set clock mode to internal
+ devpriv->clock_and_fout2 = MSeries_RTSI_10MHz_Bit;
+ if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0) {
+ rt_printk("ni_set_master_clock failed, bug?");
+ }
+ // default internal lines routing to RTSI bus lines
+ devpriv->rtsi_trig_a_output_reg =
+ RTSI_Trig_Output_Bits(0,
+ NI_RTSI_OUTPUT_ADR_START1) | RTSI_Trig_Output_Bits(1,
+ NI_RTSI_OUTPUT_ADR_START2) | RTSI_Trig_Output_Bits(2,
+ NI_RTSI_OUTPUT_SCLKG) | RTSI_Trig_Output_Bits(3,
+ NI_RTSI_OUTPUT_DACUPDN);
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
+ RTSI_Trig_A_Output_Register);
+ devpriv->rtsi_trig_b_output_reg =
+ RTSI_Trig_Output_Bits(4,
+ NI_RTSI_OUTPUT_DA_START1) | RTSI_Trig_Output_Bits(5,
+ NI_RTSI_OUTPUT_G_SRC0) | RTSI_Trig_Output_Bits(6,
+ NI_RTSI_OUTPUT_G_GATE0);
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ devpriv->rtsi_trig_b_output_reg |=
+ RTSI_Trig_Output_Bits(7, NI_RTSI_OUTPUT_RTSI_OSC);
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
+ RTSI_Trig_B_Output_Register);
+
+ // Sets the source and direction of the 4 on board lines
+// devpriv->stc_writew(dev, 0x0000, RTSI_Board_Register);
+}
+
+static int ni_rtsi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = 0;
+
+ return 2;
+}
+
+/* Find best multiplier/divider to try and get the PLL running at 80 MHz
+ * given an arbitrary frequency input clock */
+static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
+ unsigned *freq_divider, unsigned *freq_multiplier,
+ unsigned *actual_period_ns)
+{
+ unsigned div;
+ unsigned best_div = 1;
+ static const unsigned max_div = 0x10;
+ unsigned mult;
+ unsigned best_mult = 1;
+ static const unsigned max_mult = 0x100;
+ static const unsigned pico_per_nano = 1000;
+
+ const unsigned reference_picosec = reference_period_ns * pico_per_nano;
+ /* m-series wants the phased-locked loop to output 80MHz, which is divided by 4 to
+ * 20 MHz for most timing clocks */
+ static const unsigned target_picosec = 12500;
+ static const unsigned fudge_factor_80_to_20Mhz = 4;
+ int best_period_picosec = 0;
+ for (div = 1; div <= max_div; ++div) {
+ for (mult = 1; mult <= max_mult; ++mult) {
+ unsigned new_period_ps =
+ (reference_picosec * div) / mult;
+ if (abs(new_period_ps - target_picosec) <
+ abs(best_period_picosec - target_picosec)) {
+ best_period_picosec = new_period_ps;
+ best_div = div;
+ best_mult = mult;
+ }
+ }
+ }
+ if (best_period_picosec == 0) {
+ rt_printk("%s: bug, failed to find pll parameters\n",
+ __FUNCTION__);
+ return -EIO;
+ }
+ *freq_divider = best_div;
+ *freq_multiplier = best_mult;
+ *actual_period_ns =
+ (best_period_picosec * fudge_factor_80_to_20Mhz +
+ (pico_per_nano / 2)) / pico_per_nano;
+ return 0;
+}
+
+static inline unsigned num_configurable_rtsi_channels(struct comedi_device * dev)
+{
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ return 8;
+ else
+ return 7;
+}
+
+static int ni_mseries_set_pll_master_clock(struct comedi_device * dev, unsigned source,
+ unsigned period_ns)
+{
+ static const unsigned min_period_ns = 50;
+ static const unsigned max_period_ns = 1000;
+ static const unsigned timeout = 1000;
+ unsigned pll_control_bits;
+ unsigned freq_divider;
+ unsigned freq_multiplier;
+ unsigned i;
+ int retval;
+ if (source == NI_MIO_PLL_PXI10_CLOCK)
+ period_ns = 100;
+ // these limits are somewhat arbitrary, but NI advertises 1 to 20MHz range so we'll use that
+ if (period_ns < min_period_ns || period_ns > max_period_ns) {
+ rt_printk
+ ("%s: you must specify an input clock frequency between %i and %i nanosec "
+ "for the phased-lock loop.\n", __FUNCTION__,
+ min_period_ns, max_period_ns);
+ return -EINVAL;
+ }
+ devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
+ pll_control_bits =
+ MSeries_PLL_Enable_Bit | MSeries_PLL_VCO_Mode_75_150MHz_Bits;
+ devpriv->clock_and_fout2 |=
+ MSeries_Timebase1_Select_Bit | MSeries_Timebase3_Select_Bit;
+ devpriv->clock_and_fout2 &= ~MSeries_PLL_In_Source_Select_Mask;
+ switch (source) {
+ case NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK:
+ devpriv->clock_and_fout2 |=
+ MSeries_PLL_In_Source_Select_Star_Trigger_Bits;
+ retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
+ &freq_multiplier, &devpriv->clock_ns);
+ if (retval < 0)
+ return retval;
+ break;
+ case NI_MIO_PLL_PXI10_CLOCK:
+ /* pxi clock is 10MHz */
+ devpriv->clock_and_fout2 |=
+ MSeries_PLL_In_Source_Select_PXI_Clock10;
+ retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
+ &freq_multiplier, &devpriv->clock_ns);
+ if (retval < 0)
+ return retval;
+ break;
+ default:
+ {
+ unsigned rtsi_channel;
+ static const unsigned max_rtsi_channel = 7;
+ for (rtsi_channel = 0; rtsi_channel <= max_rtsi_channel;
+ ++rtsi_channel) {
+ if (source ==
+ NI_MIO_PLL_RTSI_CLOCK(rtsi_channel)) {
+ devpriv->clock_and_fout2 |=
+ MSeries_PLL_In_Source_Select_RTSI_Bits
+ (rtsi_channel);
+ break;
+ }
+ }
+ if (rtsi_channel > max_rtsi_channel)
+ return -EINVAL;
+ retval = ni_mseries_get_pll_parameters(period_ns,
+ &freq_divider, &freq_multiplier,
+ &devpriv->clock_ns);
+ if (retval < 0)
+ return retval;
+ }
+ break;
+ }
+ ni_writew(devpriv->clock_and_fout2, M_Offset_Clock_and_Fout2);
+ pll_control_bits |=
+ MSeries_PLL_Divisor_Bits(freq_divider) |
+ MSeries_PLL_Multiplier_Bits(freq_multiplier);
+// rt_printk("using divider=%i, multiplier=%i for PLL. pll_control_bits = 0x%x\n", freq_divider, freq_multiplier, pll_control_bits);
+// rt_printk("clock_ns=%d\n", devpriv->clock_ns);
+ ni_writew(pll_control_bits, M_Offset_PLL_Control);
+ devpriv->clock_source = source;
+ /* it seems to typically take a few hundred microseconds for PLL to lock */
+ for (i = 0; i < timeout; ++i) {
+ if (ni_readw(M_Offset_PLL_Status) & MSeries_PLL_Locked_Bit) {
+ break;
+ }
+ udelay(1);
+ }
+ if (i == timeout) {
+ rt_printk
+ ("%s: timed out waiting for PLL to lock to reference clock source %i with period %i ns.\n",
+ __FUNCTION__, source, period_ns);
+ return -ETIMEDOUT;
+ }
+ return 3;
+}
+
+static int ni_set_master_clock(struct comedi_device * dev, unsigned source,
+ unsigned period_ns)
+{
+ if (source == NI_MIO_INTERNAL_CLOCK) {
+ devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
+ devpriv->clock_ns = TIMEBASE_1_NS;
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ devpriv->clock_and_fout2 &=
+ ~(MSeries_Timebase1_Select_Bit |
+ MSeries_Timebase3_Select_Bit);
+ ni_writew(devpriv->clock_and_fout2,
+ M_Offset_Clock_and_Fout2);
+ ni_writew(0, M_Offset_PLL_Control);
+ }
+ devpriv->clock_source = source;
+ } else {
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ return ni_mseries_set_pll_master_clock(dev, source,
+ period_ns);
+ } else {
+ if (source == NI_MIO_RTSI_CLOCK) {
+ devpriv->rtsi_trig_direction_reg |=
+ Use_RTSI_Clock_Bit;
+ devpriv->stc_writew(dev,
+ devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
+ if (period_ns == 0) {
+ rt_printk
+ ("%s: we don't handle an unspecified clock period correctly yet, returning error.\n",
+ __FUNCTION__);
+ return -EINVAL;
+ } else {
+ devpriv->clock_ns = period_ns;
+ }
+ devpriv->clock_source = source;
+ } else
+ return -EINVAL;
+ }
+ }
+ return 3;
+}
+
+static int ni_valid_rtsi_output_source(struct comedi_device * dev, unsigned chan,
+ unsigned source)
+{
+ if (chan >= num_configurable_rtsi_channels(dev)) {
+ if (chan == old_RTSI_clock_channel) {
+ if (source == NI_RTSI_OUTPUT_RTSI_OSC)
+ return 1;
+ else {
+ rt_printk
+ ("%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards.\n",
+ __FUNCTION__, chan,
+ old_RTSI_clock_channel);
+ return 0;
+ }
+ }
+ return 0;
+ }
+ switch (source) {
+ case NI_RTSI_OUTPUT_ADR_START1:
+ case NI_RTSI_OUTPUT_ADR_START2:
+ case NI_RTSI_OUTPUT_SCLKG:
+ case NI_RTSI_OUTPUT_DACUPDN:
+ case NI_RTSI_OUTPUT_DA_START1:
+ case NI_RTSI_OUTPUT_G_SRC0:
+ case NI_RTSI_OUTPUT_G_GATE0:
+ case NI_RTSI_OUTPUT_RGOUT0:
+ case NI_RTSI_OUTPUT_RTSI_BRD_0:
+ return 1;
+ break;
+ case NI_RTSI_OUTPUT_RTSI_OSC:
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ return 1;
+ else
+ return 0;
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+static int ni_set_rtsi_routing(struct comedi_device * dev, unsigned chan,
+ unsigned source)
+{
+ if (ni_valid_rtsi_output_source(dev, chan, source) == 0)
+ return -EINVAL;
+ if (chan < 4) {
+ devpriv->rtsi_trig_a_output_reg &= ~RTSI_Trig_Output_Mask(chan);
+ devpriv->rtsi_trig_a_output_reg |=
+ RTSI_Trig_Output_Bits(chan, source);
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
+ RTSI_Trig_A_Output_Register);
+ } else if (chan < 8) {
+ devpriv->rtsi_trig_b_output_reg &= ~RTSI_Trig_Output_Mask(chan);
+ devpriv->rtsi_trig_b_output_reg |=
+ RTSI_Trig_Output_Bits(chan, source);
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
+ RTSI_Trig_B_Output_Register);
+ }
+ return 2;
+}
+
+static unsigned ni_get_rtsi_routing(struct comedi_device * dev, unsigned chan)
+{
+ if (chan < 4) {
+ return RTSI_Trig_Output_Source(chan,
+ devpriv->rtsi_trig_a_output_reg);
+ } else if (chan < num_configurable_rtsi_channels(dev)) {
+ return RTSI_Trig_Output_Source(chan,
+ devpriv->rtsi_trig_b_output_reg);
+ } else {
+ if (chan == old_RTSI_clock_channel)
+ return NI_RTSI_OUTPUT_RTSI_OSC;
+ rt_printk("%s: bug! should never get here?\n", __FUNCTION__);
+ return 0;
+ }
+}
+
+static int ni_rtsi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ if (chan < num_configurable_rtsi_channels(dev)) {
+ devpriv->rtsi_trig_direction_reg |=
+ RTSI_Output_Bit(chan,
+ (boardtype.reg_type & ni_reg_m_series_mask) !=
+ 0);
+ } else if (chan == old_RTSI_clock_channel) {
+ devpriv->rtsi_trig_direction_reg |=
+ Drive_RTSI_Clock_Bit;
+ }
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ if (chan < num_configurable_rtsi_channels(dev)) {
+ devpriv->rtsi_trig_direction_reg &=
+ ~RTSI_Output_Bit(chan,
+ (boardtype.reg_type & ni_reg_m_series_mask) !=
+ 0);
+ } else if (chan == old_RTSI_clock_channel) {
+ devpriv->rtsi_trig_direction_reg &=
+ ~Drive_RTSI_Clock_Bit;
+ }
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ if (chan < num_configurable_rtsi_channels(dev)) {
+ data[1] =
+ (devpriv->
+ rtsi_trig_direction_reg & RTSI_Output_Bit(chan,
+ (boardtype.
+ reg_type & ni_reg_m_series_mask)
+ !=
+ 0)) ? INSN_CONFIG_DIO_OUTPUT :
+ INSN_CONFIG_DIO_INPUT;
+ } else if (chan == old_RTSI_clock_channel) {
+ data[1] =
+ (devpriv->
+ rtsi_trig_direction_reg & Drive_RTSI_Clock_Bit)
+ ? INSN_CONFIG_DIO_OUTPUT :
+ INSN_CONFIG_DIO_INPUT;
+ }
+ return 2;
+ break;
+ case INSN_CONFIG_SET_CLOCK_SRC:
+ return ni_set_master_clock(dev, data[1], data[2]);
+ break;
+ case INSN_CONFIG_GET_CLOCK_SRC:
+ data[1] = devpriv->clock_source;
+ data[2] = devpriv->clock_ns;
+ return 3;
+ break;
+ case INSN_CONFIG_SET_ROUTING:
+ return ni_set_rtsi_routing(dev, chan, data[1]);
+ break;
+ case INSN_CONFIG_GET_ROUTING:
+ data[1] = ni_get_rtsi_routing(dev, chan);
+ return 2;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 1;
+}
+
+static int cs5529_wait_for_idle(struct comedi_device * dev)
+{
+ unsigned short status;
+ const int timeout = HZ;
+ int i;
+
+ for (i = 0; i < timeout; i++) {
+ status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
+ if ((status & CSS_ADC_BUSY) == 0) {
+ break;
+ }
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (schedule_timeout(1)) {
+ return -EIO;
+ }
+ }
+//printk("looped %i times waiting for idle\n", i);
+ if (i == timeout) {
+ rt_printk("%s: %s: timeout\n", __FILE__, __FUNCTION__);
+ return -ETIME;
+ }
+ return 0;
+}
+
+static void cs5529_command(struct comedi_device * dev, unsigned short value)
+{
+ static const int timeout = 100;
+ int i;
+
+ ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx);
+ /* give time for command to start being serially clocked into cs5529.
+ * this insures that the CSS_ADC_BUSY bit will get properly
+ * set before we exit this function.
+ */
+ for (i = 0; i < timeout; i++) {
+ if ((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY))
+ break;
+ comedi_udelay(1);
+ }
+//printk("looped %i times writing command to cs5529\n", i);
+ if (i == timeout) {
+ comedi_error(dev, "possible problem - never saw adc go busy?");
+ }
+}
+
+/* write to cs5529 register */
+static void cs5529_config_write(struct comedi_device * dev, unsigned int value,
+ unsigned int reg_select_bits)
+{
+ ni_ao_win_outw(dev, ((value >> 16) & 0xff),
+ CAL_ADC_Config_Data_High_Word_67xx);
+ ni_ao_win_outw(dev, (value & 0xffff),
+ CAL_ADC_Config_Data_Low_Word_67xx);
+ reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
+ cs5529_command(dev, CSCMD_COMMAND | reg_select_bits);
+ if (cs5529_wait_for_idle(dev))
+ comedi_error(dev, "time or signal in cs5529_config_write()");
+}
+
+#ifdef NI_CS5529_DEBUG
+/* read from cs5529 register */
+static unsigned int cs5529_config_read(struct comedi_device * dev,
+ unsigned int reg_select_bits)
+{
+ unsigned int value;
+
+ reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
+ cs5529_command(dev, CSCMD_COMMAND | CSCMD_READ | reg_select_bits);
+ if (cs5529_wait_for_idle(dev))
+ comedi_error(dev, "timeout or signal in cs5529_config_read()");
+ value = (ni_ao_win_inw(dev,
+ CAL_ADC_Config_Data_High_Word_67xx) << 16) & 0xff0000;
+ value |= ni_ao_win_inw(dev, CAL_ADC_Config_Data_Low_Word_67xx) & 0xffff;
+ return value;
+}
+#endif
+
+static int cs5529_do_conversion(struct comedi_device * dev, unsigned short *data)
+{
+ int retval;
+ unsigned short status;
+
+ cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION);
+ retval = cs5529_wait_for_idle(dev);
+ if (retval) {
+ comedi_error(dev,
+ "timeout or signal in cs5529_do_conversion()");
+ return -ETIME;
+ }
+ status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
+ if (status & CSS_OSC_DETECT) {
+ rt_printk
+ ("ni_mio_common: cs5529 conversion error, status CSS_OSC_DETECT\n");
+ return -EIO;
+ }
+ if (status & CSS_OVERRANGE) {
+ rt_printk
+ ("ni_mio_common: cs5529 conversion error, overrange (ignoring)\n");
+ }
+ if (data) {
+ *data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx);
+ /* cs5529 returns 16 bit signed data in bipolar mode */
+ *data ^= (1 << 15);
+ }
+ return 0;
+}
+
+static int cs5529_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, retval;
+ unsigned short sample;
+ unsigned int channel_select;
+ const unsigned int INTERNAL_REF = 0x1000;
+
+ /* Set calibration adc source. Docs lie, reference select bits 8 to 11
+ * do nothing. bit 12 seems to chooses internal reference voltage, bit
+ * 13 causes the adc input to go overrange (maybe reads external reference?) */
+ if (insn->chanspec & CR_ALT_SOURCE)
+ channel_select = INTERNAL_REF;
+ else
+ channel_select = CR_CHAN(insn->chanspec);
+ ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx);
+
+ for (n = 0; n < insn->n; n++) {
+ retval = cs5529_do_conversion(dev, &sample);
+ if (retval < 0)
+ return retval;
+ data[n] = sample;
+ }
+ return insn->n;
+}
+
+static int init_cs5529(struct comedi_device * dev)
+{
+ unsigned int config_bits =
+ CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES;
+
+#if 1
+ /* do self-calibration */
+ cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN,
+ CSCMD_CONFIG_REGISTER);
+ /* need to force a conversion for calibration to run */
+ cs5529_do_conversion(dev, NULL);
+#else
+ /* force gain calibration to 1 */
+ cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER);
+ cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET,
+ CSCMD_CONFIG_REGISTER);
+ if (cs5529_wait_for_idle(dev))
+ comedi_error(dev, "timeout or signal in init_cs5529()\n");
+#endif
+#ifdef NI_CS5529_DEBUG
+ rt_printk("config: 0x%x\n", cs5529_config_read(dev,
+ CSCMD_CONFIG_REGISTER));
+ rt_printk("gain: 0x%x\n", cs5529_config_read(dev,
+ CSCMD_GAIN_REGISTER));
+ rt_printk("offset: 0x%x\n", cs5529_config_read(dev,
+ CSCMD_OFFSET_REGISTER));
+#endif
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
new file mode 100644
index 00000000000..d6357c25aca
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -0,0 +1,551 @@
+/*
+ comedi/drivers/ni_mio_cs.c
+ Hardware driver for NI PCMCIA MIO E series cards
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ni_mio_cs
+Description: National Instruments DAQCard E series
+Author: ds
+Status: works
+Devices: [National Instruments] DAQCard-AI-16XE-50 (ni_mio_cs),
+ DAQCard-AI-16E-4, DAQCard-6062E, DAQCard-6024E, DAQCard-6036E
+Updated: Thu Oct 23 19:43:17 CDT 2003
+
+See the notes in the ni_atmio.o driver.
+*/
+/*
+ The real guts of the driver is in ni_mio_common.c, which is
+ included by all the E series drivers.
+
+ References for specifications:
+
+ 341080a.pdf DAQCard E Series Register Level Programmer Manual
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "ni_stc.h"
+#include "8255.h"
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+#undef DEBUG
+
+#define ATMIO 1
+#undef PCIMIO
+
+/*
+ * AT specific setup
+ */
+
+#define NI_SIZE 0x20
+
+#define MAX_N_CALDACS 32
+
+static const ni_board ni_boards[] = {
+ {device_id:0x010d,
+ name: "DAQCard-ai-16xe-50",
+ n_adchan:16,
+ adbits: 16,
+ ai_fifo_depth:1024,
+ alwaysdither:0,
+ gainlkup:ai_gain_8,
+ ai_speed:5000,
+ n_aochan:0,
+ aobits: 0,
+ ao_fifo_depth:0,
+ ao_unipolar:0,
+ num_p0_dio_channels:8,
+ has_8255:0,
+ caldac: {dac8800, dac8043},
+ },
+ {device_id:0x010c,
+ name: "DAQCard-ai-16e-4",
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:1024,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:4000,
+ n_aochan:0,
+ aobits: 0,
+ ao_fifo_depth:0,
+ ao_unipolar:0,
+ num_p0_dio_channels:8,
+ has_8255:0,
+ caldac: {mb88341}, /* verified */
+ },
+ {device_id:0x02c4,
+ name: "DAQCard-6062E",
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:8192,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:2000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:2048,
+ ao_range_table:&range_bipolar10,
+ ao_unipolar:0,
+ ao_speed:1176,
+ num_p0_dio_channels:8,
+ has_8255:0,
+ caldac: {ad8804_debug}, /* verified */
+ },
+ {device_id:0x075e,
+ name: "DAQCard-6024E", /* specs incorrect! */
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:1024,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:5000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:0,
+ ao_range_table:&range_bipolar10,
+ ao_unipolar:0,
+ ao_speed:1000000,
+ num_p0_dio_channels:8,
+ has_8255:0,
+ caldac: {ad8804_debug},
+ },
+ {device_id:0x0245,
+ name: "DAQCard-6036E", /* specs incorrect! */
+ n_adchan:16,
+ adbits: 16,
+ ai_fifo_depth:1024,
+ alwaysdither:1,
+ gainlkup:ai_gain_4,
+ ai_speed:5000,
+ n_aochan:2,
+ aobits: 16,
+ ao_fifo_depth:0,
+ ao_range_table:&range_bipolar10,
+ ao_unipolar:0,
+ ao_speed:1000000,
+ num_p0_dio_channels:8,
+ has_8255:0,
+ caldac: {ad8804_debug},
+ },
+#if 0
+ {device_id:0x0000, /* unknown */
+ name: "DAQCard-6715",
+ n_adchan:0,
+ n_aochan:8,
+ aobits: 12,
+ ao_671x: 8192,
+ num_p0_dio_channels:8,
+ caldac: {mb88341, mb88341},
+ },
+#endif
+ /* N.B. Update ni_mio_cs_ids[] when entries added above. */
+};
+
+#define interrupt_pin(a) 0
+
+#define IRQ_POLARITY 1
+
+#define NI_E_IRQ_FLAGS IRQF_SHARED
+
+struct ni_private {
+
+ struct pcmcia_device *link;
+
+ NI_PRIVATE_COMMON};
+
+#define devpriv ((struct ni_private *)dev->private)
+
+/* How we access registers */
+
+#define ni_writel(a,b) (outl((a),(b)+dev->iobase))
+#define ni_readl(a) (inl((a)+dev->iobase))
+#define ni_writew(a,b) (outw((a),(b)+dev->iobase))
+#define ni_readw(a) (inw((a)+dev->iobase))
+#define ni_writeb(a,b) (outb((a),(b)+dev->iobase))
+#define ni_readb(a) (inb((a)+dev->iobase))
+
+/* How we access windowed registers */
+
+/* We automatically take advantage of STC registers that can be
+ * read/written directly in the I/O space of the board. The
+ * DAQCard devices map the low 8 STC registers to iobase+addr*2. */
+
+static void mio_cs_win_out(struct comedi_device * dev, uint16_t data, int addr)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ if (addr < 8) {
+ ni_writew(data, addr * 2);
+ } else {
+ ni_writew(addr, Window_Address);
+ ni_writew(data, Window_Data);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static uint16_t mio_cs_win_in(struct comedi_device * dev, int addr)
+{
+ unsigned long flags;
+ uint16_t ret;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ if (addr < 8) {
+ ret = ni_readw(addr * 2);
+ } else {
+ ni_writew(addr, Window_Address);
+ ret = ni_readw(Window_Data);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+
+ return ret;
+}
+
+static int mio_cs_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int mio_cs_detach(struct comedi_device * dev);
+static struct comedi_driver driver_ni_mio_cs = {
+ driver_name:"ni_mio_cs",
+ module:THIS_MODULE,
+ attach:mio_cs_attach,
+ detach:mio_cs_detach,
+};
+
+#include "ni_mio_common.c"
+
+static int ni_getboardtype(struct comedi_device * dev, struct pcmcia_device *link);
+
+/* clean up allocated resources */
+/* called when driver is removed */
+static int mio_cs_detach(struct comedi_device * dev)
+{
+ mio_common_detach(dev);
+
+ /* PCMCIA layer frees the IO region */
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+
+ return 0;
+}
+
+static void mio_cs_config(struct pcmcia_device *link);
+static void cs_release(struct pcmcia_device *link);
+static void cs_detach(struct pcmcia_device *);
+
+static struct pcmcia_device *cur_dev = NULL;
+static const dev_info_t dev_info = "ni_mio_cs";
+static dev_node_t dev_node = {
+ "ni_mio_cs",
+ COMEDI_MAJOR, 0,
+ NULL
+};
+static int cs_attach(struct pcmcia_device *link)
+{
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ link->io.NumPorts1 = 16;
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->conf.Attributes = CONF_ENABLE_IRQ;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ cur_dev = link;
+
+ mio_cs_config(link);
+
+ return 0;
+}
+
+static void cs_release(struct pcmcia_device *link)
+{
+ pcmcia_disable_device(link);
+}
+
+static void cs_detach(struct pcmcia_device *link)
+{
+ DPRINTK("cs_detach(link=%p)\n", link);
+
+ if (link->dev_node) {
+ cs_release(link);
+ }
+}
+
+static int mio_cs_suspend(struct pcmcia_device *link)
+{
+ DPRINTK("pm suspend\n");
+
+ return 0;
+}
+
+static int mio_cs_resume(struct pcmcia_device *link)
+{
+ DPRINTK("pm resume\n");
+ return 0;
+}
+
+static void mio_cs_config(struct pcmcia_device *link)
+{
+ tuple_t tuple;
+ u_short buf[128];
+ cisparse_t parse;
+ int manfid = 0, prodid = 0;
+ int ret;
+
+ DPRINTK("mio_cs_config(link=%p)\n", link);
+
+ tuple.TupleData = (cisdata_t *) buf;
+ tuple.TupleOffset = 0;
+ tuple.TupleDataMax = 255;
+ tuple.Attributes = 0;
+
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ ret = pcmcia_get_first_tuple(link, &tuple);
+ ret = pcmcia_get_tuple_data(link, &tuple);
+ ret = pcmcia_parse_tuple(&tuple, &parse);
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+#if 0
+ tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
+ tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
+ info->multi(first_tuple(link, &tuple, &parse) == 0);
+#endif
+
+ tuple.DesiredTuple = CISTPL_MANFID;
+ tuple.Attributes = TUPLE_RETURN_COMMON;
+ if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
+ (pcmcia_get_tuple_data(link, &tuple) == 0)) {
+ manfid = le16_to_cpu(buf[0]);
+ prodid = le16_to_cpu(buf[1]);
+ }
+ //printk("manfid = 0x%04x, 0x%04x\n",manfid,prodid);
+
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ tuple.Attributes = 0;
+ ret = pcmcia_get_first_tuple(link, &tuple);
+ ret = pcmcia_get_tuple_data(link, &tuple);
+ ret = pcmcia_parse_tuple(&tuple, &parse);
+
+#if 0
+ printk(" index: 0x%x\n", parse.cftable_entry.index);
+ printk(" flags: 0x%x\n", parse.cftable_entry.flags);
+ printk(" io flags: 0x%x\n", parse.cftable_entry.io.flags);
+ printk(" io nwin: 0x%x\n", parse.cftable_entry.io.nwin);
+ printk(" io base: 0x%x\n", parse.cftable_entry.io.win[0].base);
+ printk(" io len: 0x%x\n", parse.cftable_entry.io.win[0].len);
+ printk(" irq1: 0x%x\n", parse.cftable_entry.irq.IRQInfo1);
+ printk(" irq2: 0x%x\n", parse.cftable_entry.irq.IRQInfo2);
+ printk(" mem flags: 0x%x\n", parse.cftable_entry.mem.flags);
+ printk(" mem nwin: 0x%x\n", parse.cftable_entry.mem.nwin);
+ printk(" subtuples: 0x%x\n", parse.cftable_entry.subtuples);
+#endif
+
+#if 0
+ link->io.NumPorts1 = 0x20;
+ link->io.IOAddrLines = 5;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+#endif
+ link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
+ link->io.IOAddrLines =
+ parse.cftable_entry.io.flags & CISTPL_IO_LINES_MASK;
+ link->io.NumPorts2 = 0;
+
+ {
+ int base;
+ for (base = 0x000; base < 0x400; base += 0x20) {
+ link->io.BasePort1 = base;
+ ret = pcmcia_request_io(link, &link->io);
+ //printk("RequestIO 0x%02x\n",ret);
+ if (!ret)
+ break;
+ }
+ }
+
+ link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
+ link->irq.IRQInfo2 = parse.cftable_entry.irq.IRQInfo2;
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret) {
+ printk("pcmcia_request_irq() returned error: %i\n", ret);
+ }
+ //printk("RequestIRQ 0x%02x\n",ret);
+
+ link->conf.ConfigIndex = 1;
+
+ ret = pcmcia_request_configuration(link, &link->conf);
+ //printk("RequestConfiguration %d\n",ret);
+
+ link->dev_node = &dev_node;
+}
+
+static int mio_cs_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pcmcia_device *link;
+ unsigned int irq;
+ int ret;
+
+ DPRINTK("mio_cs_attach(dev=%p,it=%p)\n", dev, it);
+
+ link = cur_dev; /* XXX hack */
+ if (!link)
+ return -EIO;
+
+ dev->driver = &driver_ni_mio_cs;
+ dev->iobase = link->io.BasePort1;
+
+ irq = link->irq.AssignedIRQ;
+
+ printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ",
+ dev->minor, dev->driver->driver_name, dev->iobase, irq);
+
+#if 0
+ {
+ int i;
+
+ printk(" board fingerprint:");
+ for (i = 0; i < 32; i += 2) {
+ printk(" %04x %02x", inw(dev->iobase + i),
+ inb(dev->iobase + i + 1));
+ }
+ printk("\n");
+ printk(" board fingerprint (windowed):");
+ for (i = 0; i < 10; i++) {
+ printk(" 0x%04x", win_in(i));
+ }
+ printk("\n");
+ }
+#endif
+
+ dev->board_ptr = ni_boards + ni_getboardtype(dev, link);
+
+ printk(" %s", boardtype.name);
+ dev->board_name = boardtype.name;
+
+ if ((ret = comedi_request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS,
+ "ni_mio_cs", dev)) < 0) {
+ printk(" irq not available\n");
+ return -EINVAL;
+ }
+ dev->irq = irq;
+
+ /* allocate private area */
+ if ((ret = ni_alloc_private(dev)) < 0)
+ return ret;
+ devpriv->stc_writew = &mio_cs_win_out;
+ devpriv->stc_readw = &mio_cs_win_in;
+ devpriv->stc_writel = &win_out2;
+ devpriv->stc_readl = &win_in2;
+
+ if ((ret = ni_E_init(dev, it)) < 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+static int get_prodid(struct comedi_device * dev, struct pcmcia_device *link)
+{
+ tuple_t tuple;
+ u_short buf[128];
+ int prodid = 0;
+
+ tuple.TupleData = (cisdata_t *) buf;
+ tuple.TupleOffset = 0;
+ tuple.TupleDataMax = 255;
+ tuple.DesiredTuple = CISTPL_MANFID;
+ tuple.Attributes = TUPLE_RETURN_COMMON;
+ if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
+ (pcmcia_get_tuple_data(link, &tuple) == 0)) {
+ prodid = le16_to_cpu(buf[1]);
+ }
+
+ return prodid;
+}
+
+static int ni_getboardtype(struct comedi_device * dev, struct pcmcia_device *link)
+{
+ int id;
+ int i;
+
+ id = get_prodid(dev, link);
+
+ for (i = 0; i < n_ni_boards; i++) {
+ if (ni_boards[i].device_id == id) {
+ return i;
+ }
+ }
+
+ printk("unknown board 0x%04x -- pretend it is a ", id);
+
+ return 0;
+}
+
+#ifdef MODULE
+
+MODULE_LICENSE("GPL");
+
+static struct pcmcia_device_id ni_mio_cs_ids[] = {
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010d), /* DAQCard-ai-16xe-50 */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010c), /* DAQCard-ai-16e-4 */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x02c4), /* DAQCard-6062E */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x075e), /* DAQCard-6024E */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0245), /* DAQCard-6036E */
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, ni_mio_cs_ids);
+
+struct pcmcia_driver ni_mio_cs_driver = {
+ .probe = &cs_attach,
+ .remove = &cs_detach,
+ .suspend = &mio_cs_suspend,
+ .resume = &mio_cs_resume,
+ .id_table = ni_mio_cs_ids,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+int init_module(void)
+{
+ pcmcia_register_driver(&ni_mio_cs_driver);
+ comedi_driver_register(&driver_ni_mio_cs);
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ pcmcia_unregister_driver(&ni_mio_cs_driver);
+#if 0
+ while (cur_dev != NULL)
+ cs_detach(cur_dev->handle);
+#endif
+ comedi_driver_unregister(&driver_ni_mio_cs);
+}
+#endif
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
new file mode 100644
index 00000000000..87def2cc9a2
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -0,0 +1,1302 @@
+/*
+ comedi/drivers/ni_pcidio.c
+ driver for National Instruments PCI-DIO-96/PCI-6508
+ National Instruments PCI-DIO-32HS
+ National Instruments PCI-6503
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ni_pcidio
+Description: National Instruments PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503
+Author: ds
+Status: works
+Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio), PXI-6533,
+ PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X,
+ PXI-6503, PCI-6533, PCI-6534
+Updated: Sun, 21 Apr 2002 21:03:38 -0700
+
+The DIO-96 appears as four 8255 subdevices. See the 8255
+driver notes for details.
+
+The DIO32HS board appears as one subdevice, with 32 channels.
+Each channel is individually I/O configurable. The channel order
+is 0=A0, 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0. The driver only
+supports simple digital I/O; no handshaking is supported.
+
+DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
+
+This driver could be easily modified to support AT-MIO32HS and
+AT-MIO96.
+
+The PCI-6534 requires a firmware upload after power-up to work, the
+firmware data and instructions for loading it with comedi_config
+it are contained in the
+comedi_nonfree_firmware tarball available from http://www.comedi.org
+*/
+
+/*
+ This driver is for both the NI PCI-DIO-32HS and the PCI-DIO-96,
+ which have very different architectures. But, since the '96 is
+ so simple, it is included here.
+
+ Manuals (available from ftp://ftp.natinst.com/support/manuals)
+
+ 320938c.pdf PCI-DIO-96/PXI-6508/PCI-6503 User Manual
+ 321464b.pdf AT/PCI-DIO-32HS User Manual
+ 341329A.pdf PCI-6533 Register-Level Programmer Manual
+ 341330A.pdf DAQ-DIO Technical Reference Manual
+
+ */
+
+#define USE_DMA
+//#define DEBUG 1
+//#define DEBUG_FLAGS
+
+#include "../comedidev.h"
+
+#include "mite.h"
+#include "8255.h"
+
+#undef DPRINTK
+#ifdef DEBUG
+#define DPRINTK(format, args...) printk(format, ## args)
+#else
+#define DPRINTK(format, args...)
+#endif
+
+#define PCI_VENDOR_ID_NATINST 0x1093
+
+#define PCI_DIO_SIZE 4096
+#define PCI_MITE_SIZE 4096
+
+/* defines for the PCI-DIO-96 */
+
+#define NIDIO_8255_BASE(x) ((x)*4)
+#define NIDIO_A 0
+#define NIDIO_B 4
+#define NIDIO_C 8
+#define NIDIO_D 12
+
+/* defines for the PCI-DIO-32HS */
+
+#define Window_Address 4 /* W */
+#define Interrupt_And_Window_Status 4 /* R */
+#define IntStatus1 (1<<0)
+#define IntStatus2 (1<<1)
+#define WindowAddressStatus_mask 0x7c
+
+#define Master_DMA_And_Interrupt_Control 5 /* W */
+#define InterruptLine(x) ((x)&3)
+#define OpenInt (1<<2)
+#define Group_Status 5 /* R */
+#define DataLeft (1<<0)
+#define Req (1<<2)
+#define StopTrig (1<<3)
+
+#define Group_1_Flags 6 /* R */
+#define Group_2_Flags 7 /* R */
+#define TransferReady (1<<0)
+#define CountExpired (1<<1)
+#define Waited (1<<5)
+#define PrimaryTC (1<<6)
+#define SecondaryTC (1<<7)
+ //#define SerialRose
+ //#define ReqRose
+ //#define Paused
+
+#define Group_1_First_Clear 6 /* W */
+#define Group_2_First_Clear 7 /* W */
+#define ClearWaited (1<<3)
+#define ClearPrimaryTC (1<<4)
+#define ClearSecondaryTC (1<<5)
+#define DMAReset (1<<6)
+#define FIFOReset (1<<7)
+#define ClearAll 0xf8
+
+#define Group_1_FIFO 8 /* W */
+#define Group_2_FIFO 12 /* W */
+
+#define Transfer_Count 20
+#define Chip_ID_D 24
+#define Chip_ID_I 25
+#define Chip_ID_O 26
+#define Chip_Version 27
+#define Port_IO(x) (28+(x))
+#define Port_Pin_Directions(x) (32+(x))
+#define Port_Pin_Mask(x) (36+(x))
+#define Port_Pin_Polarities(x) (40+(x))
+
+#define Master_Clock_Routing 45
+#define RTSIClocking(x) (((x)&3)<<4)
+
+#define Group_1_Second_Clear 46 /* W */
+#define Group_2_Second_Clear 47 /* W */
+#define ClearExpired (1<<0)
+
+#define Port_Pattern(x) (48+(x))
+
+#define Data_Path 64
+#define FIFOEnableA (1<<0)
+#define FIFOEnableB (1<<1)
+#define FIFOEnableC (1<<2)
+#define FIFOEnableD (1<<3)
+#define Funneling(x) (((x)&3)<<4)
+#define GroupDirection (1<<7)
+
+#define Protocol_Register_1 65
+#define OpMode Protocol_Register_1
+#define RunMode(x) ((x)&7)
+#define Numbered (1<<3)
+
+#define Protocol_Register_2 66
+#define ClockReg Protocol_Register_2
+#define ClockLine(x) (((x)&3)<<5)
+#define InvertStopTrig (1<<7)
+#define DataLatching(x) (((x)&3)<<5)
+
+#define Protocol_Register_3 67
+#define Sequence Protocol_Register_3
+
+#define Protocol_Register_14 68 /* 16 bit */
+#define ClockSpeed Protocol_Register_14
+
+#define Protocol_Register_4 70
+#define ReqReg Protocol_Register_4
+#define ReqConditioning(x) (((x)&7)<<3)
+
+#define Protocol_Register_5 71
+#define BlockMode Protocol_Register_5
+
+#define FIFO_Control 72
+#define ReadyLevel(x) ((x)&7)
+
+#define Protocol_Register_6 73
+#define LinePolarities Protocol_Register_6
+#define InvertAck (1<<0)
+#define InvertReq (1<<1)
+#define InvertClock (1<<2)
+#define InvertSerial (1<<3)
+#define OpenAck (1<<4)
+#define OpenClock (1<<5)
+
+#define Protocol_Register_7 74
+#define AckSer Protocol_Register_7
+#define AckLine(x) (((x)&3)<<2)
+#define ExchangePins (1<<7)
+
+#define Interrupt_Control 75
+ /* bits same as flags */
+
+#define DMA_Line_Control_Group1 76
+#define DMA_Line_Control_Group2 108
+// channel zero is none
+static inline unsigned primary_DMAChannel_bits(unsigned channel)
+{
+ return channel & 0x3;
+}
+static inline unsigned secondary_DMAChannel_bits(unsigned channel)
+{
+ return (channel << 2) & 0xc;
+}
+
+#define Transfer_Size_Control 77
+#define TransferWidth(x) ((x)&3)
+#define TransferLength(x) (((x)&3)<<3)
+#define RequireRLevel (1<<5)
+
+#define Protocol_Register_15 79
+#define DAQOptions Protocol_Register_15
+#define StartSource(x) ((x)&0x3)
+#define InvertStart (1<<2)
+#define StopSource(x) (((x)&0x3)<<3)
+#define ReqStart (1<<6)
+#define PreStart (1<<7)
+
+#define Pattern_Detection 81
+#define DetectionMethod (1<<0)
+#define InvertMatch (1<<1)
+#define IE_Pattern_Detection (1<<2)
+
+#define Protocol_Register_9 82
+#define ReqDelay Protocol_Register_9
+
+#define Protocol_Register_10 83
+#define ReqNotDelay Protocol_Register_10
+
+#define Protocol_Register_11 84
+#define AckDelay Protocol_Register_11
+
+#define Protocol_Register_12 85
+#define AckNotDelay Protocol_Register_12
+
+#define Protocol_Register_13 86
+#define Data1Delay Protocol_Register_13
+
+#define Protocol_Register_8 88 /* 32 bit */
+#define StartDelay Protocol_Register_8
+
+enum pci_6534_firmware_registers { /* 16 bit */
+ Firmware_Control_Register = 0x100,
+ Firmware_Status_Register = 0x104,
+ Firmware_Data_Register = 0x108,
+ Firmware_Mask_Register = 0x10c,
+ Firmware_Debug_Register = 0x110,
+};
+/* main fpga registers (32 bit)*/
+enum pci_6534_fpga_registers {
+ FPGA_Control1_Register = 0x200,
+ FPGA_Control2_Register = 0x204,
+ FPGA_Irq_Mask_Register = 0x208,
+ FPGA_Status_Register = 0x20c,
+ FPGA_Signature_Register = 0x210,
+ FPGA_SCALS_Counter_Register = 0x280, /*write-clear */
+ FPGA_SCAMS_Counter_Register = 0x284, /*write-clear */
+ FPGA_SCBLS_Counter_Register = 0x288, /*write-clear */
+ FPGA_SCBMS_Counter_Register = 0x28c, /*write-clear */
+ FPGA_Temp_Control_Register = 0x2a0,
+ FPGA_DAR_Register = 0x2a8,
+ FPGA_ELC_Read_Register = 0x2b8,
+ FPGA_ELC_Write_Register = 0x2bc,
+};
+enum FPGA_Control_Bits {
+ FPGA_Enable_Bit = 0x8000,
+};
+
+#define TIMER_BASE 50 /* nanoseconds */
+
+#ifdef USE_DMA
+#define IntEn (CountExpired|Waited|PrimaryTC|SecondaryTC)
+#else
+#define IntEn (TransferReady|CountExpired|Waited|PrimaryTC|SecondaryTC)
+#endif
+
+static int nidio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int nidio_detach(struct comedi_device * dev);
+static int ni_pcidio_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static struct comedi_driver driver_pcidio = {
+ driver_name:"ni_pcidio",
+ module:THIS_MODULE,
+ attach:nidio_attach,
+ detach:nidio_detach,
+};
+
+struct nidio_board {
+
+ int dev_id;
+ const char *name;
+ int n_8255;
+ unsigned int is_diodaq:1;
+ unsigned int uses_firmware:1;
+};
+
+static const struct nidio_board nidio_boards[] = {
+ {
+ dev_id: 0x1150,
+ name: "pci-dio-32hs",
+ n_8255: 0,
+ is_diodaq:1,
+ },
+ {
+ dev_id: 0x1320,
+ name: "pxi-6533",
+ n_8255: 0,
+ is_diodaq:1,
+ },
+ {
+ dev_id: 0x12b0,
+ name: "pci-6534",
+ n_8255: 0,
+ is_diodaq:1,
+ uses_firmware:1,
+ },
+ {
+ dev_id: 0x0160,
+ name: "pci-dio-96",
+ n_8255: 4,
+ is_diodaq:0,
+ },
+ {
+ dev_id: 0x1630,
+ name: "pci-dio-96b",
+ n_8255: 4,
+ is_diodaq:0,
+ },
+ {
+ dev_id: 0x13c0,
+ name: "pxi-6508",
+ n_8255: 4,
+ is_diodaq:0,
+ },
+ {
+ dev_id: 0x0400,
+ name: "pci-6503",
+ n_8255: 1,
+ is_diodaq:0,
+ },
+ {
+ dev_id: 0x1250,
+ name: "pci-6503b",
+ n_8255: 1,
+ is_diodaq:0,
+ },
+ {
+ dev_id: 0x17d0,
+ name: "pci-6503x",
+ n_8255: 1,
+ is_diodaq:0,
+ },
+ {
+ dev_id: 0x1800,
+ name: "pxi-6503",
+ n_8255: 1,
+ is_diodaq:0,
+ },
+};
+
+#define n_nidio_boards (sizeof(nidio_boards)/sizeof(nidio_boards[0]))
+#define this_board ((const struct nidio_board *)dev->board_ptr)
+
+static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x1150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x12b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x0160, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1630, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x13c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x0400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x17d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
+
+struct nidio96_private {
+ struct mite_struct *mite;
+ int boardtype;
+ int dio;
+ unsigned short OpModeBits;
+ struct mite_channel *di_mite_chan;
+ struct mite_dma_descriptor_ring *di_mite_ring;
+ spinlock_t mite_channel_lock;
+};
+#define devpriv ((struct nidio96_private *)dev->private)
+
+static int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ni_pcidio_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum);
+static int nidio_find_device(struct comedi_device * dev, int bus, int slot);
+static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode);
+static int setup_mite_dma(struct comedi_device * dev, struct comedi_subdevice * s);
+
+#ifdef DEBUG_FLAGS
+static void ni_pcidio_print_flags(unsigned int flags);
+static void ni_pcidio_print_status(unsigned int status);
+#else
+#define ni_pcidio_print_flags(x)
+#define ni_pcidio_print_status(x)
+#endif
+
+static int ni_pcidio_request_di_mite_channel(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ BUG_ON(devpriv->di_mite_chan);
+ devpriv->di_mite_chan =
+ mite_request_channel_in_range(devpriv->mite,
+ devpriv->di_mite_ring, 1, 2);
+ if (devpriv->di_mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+ flags);
+ comedi_error(dev, "failed to reserve mite dma channel.");
+ return -EBUSY;
+ }
+ writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
+ secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
+ devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+ mmiowb();
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+ return 0;
+}
+
+static void ni_pcidio_release_di_mite_channel(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->di_mite_chan) {
+ mite_dma_disarm(devpriv->di_mite_chan);
+ mite_dma_reset(devpriv->di_mite_chan);
+ mite_release_channel(devpriv->di_mite_chan);
+ devpriv->di_mite_chan = NULL;
+ writeb(primary_DMAChannel_bits(0) |
+ secondary_DMAChannel_bits(0),
+ devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+ mmiowb();
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+}
+
+static int nidio96_8255_cb(int dir, int port, int data, unsigned long iobase)
+{
+ if (dir) {
+ writeb(data, (void *)(iobase + port));
+ return 0;
+ } else {
+ return readb((void *)(iobase + port));
+ }
+}
+
+void ni_pcidio_event(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (s->async->
+ events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
+ {
+ ni_pcidio_cancel(dev, s);
+ }
+ comedi_event(dev, s);
+}
+
+static irqreturn_t nidio_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices;
+ struct comedi_async *async = s->async;
+ struct mite_struct *mite = devpriv->mite;
+
+ //int i, j;
+ long int AuxData = 0;
+ short data1 = 0;
+ short data2 = 0;
+ int flags;
+ int status;
+ int work = 0;
+ unsigned int m_status = 0;
+ unsigned long irq_flags;
+
+ //interrupcions parasites
+ if (dev->attached == 0) {
+ // assume it's from another card
+ return IRQ_NONE;
+ }
+
+ status = readb(devpriv->mite->daq_io_addr +
+ Interrupt_And_Window_Status);
+ flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+
+ DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n",
+ status, flags);
+ ni_pcidio_print_flags(flags);
+ ni_pcidio_print_status(status);
+
+ //printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf);
+ //printk("buf[4096]=%08x\n",*(unsigned int *)(async->prealloc_buf+4096));
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
+ if (devpriv->di_mite_chan)
+ m_status = mite_get_status(devpriv->di_mite_chan);
+#ifdef MITE_DEBUG
+ mite_print_chsr(m_status);
+#endif
+ //printk("mite_bytes_transferred: %d\n",mite_bytes_transferred(mite,DI_DMA_CHAN));
+ //mite_dump_regs(mite);
+ if (m_status & CHSR_INT) {
+ if (m_status & CHSR_LINKC) {
+ writel(CHOR_CLRLC,
+ mite->mite_io_addr +
+ MITE_CHOR(devpriv->di_mite_chan->channel));
+ mite_sync_input_dma(devpriv->di_mite_chan, s->async);
+ /* XXX need to byteswap */
+ }
+ if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
+ CHSR_DRQ1 | CHSR_MRDY)) {
+ DPRINTK("unknown mite interrupt, disabling IRQ\n");
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ disable_irq(dev->irq);
+ }
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, irq_flags);
+
+ while (status & DataLeft) {
+ work++;
+ if (work > 20) {
+ DPRINTK("too much work in interrupt\n");
+ writeb(0x00,
+ devpriv->mite->daq_io_addr +
+ Master_DMA_And_Interrupt_Control);
+ break;
+ }
+
+ flags &= IntEn;
+
+ if (flags & TransferReady) {
+ //DPRINTK("TransferReady\n");
+ while (flags & TransferReady) {
+ work++;
+ if (work > 100) {
+ DPRINTK("too much work in interrupt\n");
+ writeb(0x00,
+ devpriv->mite->daq_io_addr +
+ Master_DMA_And_Interrupt_Control);
+ goto out;
+ }
+ AuxData =
+ readl(devpriv->mite->daq_io_addr +
+ Group_1_FIFO);
+ data1 = AuxData & 0xffff;
+ data2 = (AuxData & 0xffff0000) >> 16;
+ comedi_buf_put(async, data1);
+ comedi_buf_put(async, data2);
+ //DPRINTK("read:%d, %d\n",data1,data2);
+ flags = readb(devpriv->mite->daq_io_addr +
+ Group_1_Flags);
+ }
+ //DPRINTK("buf_int_count: %d\n",async->buf_int_count);
+ //DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",IntEn,flags,status);
+ //ni_pcidio_print_flags(flags);
+ //ni_pcidio_print_status(status);
+ async->events |= COMEDI_CB_BLOCK;
+ }
+
+ if (flags & CountExpired) {
+ DPRINTK("CountExpired\n");
+ writeb(ClearExpired,
+ devpriv->mite->daq_io_addr +
+ Group_1_Second_Clear);
+ async->events |= COMEDI_CB_EOA;
+
+ writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
+ break;
+ } else if (flags & Waited) {
+ DPRINTK("Waited\n");
+ writeb(ClearWaited,
+ devpriv->mite->daq_io_addr +
+ Group_1_First_Clear);
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ break;
+ } else if (flags & PrimaryTC) {
+ DPRINTK("PrimaryTC\n");
+ writeb(ClearPrimaryTC,
+ devpriv->mite->daq_io_addr +
+ Group_1_First_Clear);
+ async->events |= COMEDI_CB_EOA;
+ } else if (flags & SecondaryTC) {
+ DPRINTK("SecondaryTC\n");
+ writeb(ClearSecondaryTC,
+ devpriv->mite->daq_io_addr +
+ Group_1_First_Clear);
+ async->events |= COMEDI_CB_EOA;
+ }
+#if 0
+ else {
+ printk("ni_pcidio: unknown interrupt\n");
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ writeb(0x00,
+ devpriv->mite->daq_io_addr +
+ Master_DMA_And_Interrupt_Control);
+ }
+#endif
+ flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+ status = readb(devpriv->mite->daq_io_addr +
+ Interrupt_And_Window_Status);
+ //DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,status=0x%02x\n",
+ // IntEn,flags,status);
+ //ni_pcidio_print_flags(flags);
+ //ni_pcidio_print_status(status);
+ }
+
+ out:
+ ni_pcidio_event(dev, s);
+#if 0
+ if (!tag) {
+ writeb(0x03,
+ devpriv->mite->daq_io_addr +
+ Master_DMA_And_Interrupt_Control);
+ }
+#endif
+ return IRQ_HANDLED;
+}
+
+#ifdef DEBUG_FLAGS
+static const char *const flags_strings[] = {
+ "TransferReady", "CountExpired", "2", "3",
+ "4", "Waited", "PrimaryTC", "SecondaryTC",
+};
+static void ni_pcidio_print_flags(unsigned int flags)
+{
+ int i;
+
+ printk("group_1_flags:");
+ for (i = 7; i >= 0; i--) {
+ if (flags & (1 << i)) {
+ printk(" %s", flags_strings[i]);
+ }
+ }
+ printk("\n");
+}
+static char *status_strings[] = {
+ "DataLeft1", "Reserved1", "Req1", "StopTrig1",
+ "DataLeft2", "Reserved2", "Req2", "StopTrig2",
+};
+static void ni_pcidio_print_status(unsigned int flags)
+{
+ int i;
+
+ printk("group_status:");
+ for (i = 7; i >= 0; i--) {
+ if (flags & (1 << i)) {
+ printk(" %s", status_strings[i]);
+ }
+ }
+ printk("\n");
+}
+#endif
+
+#ifdef unused
+static void debug_int(struct comedi_device * dev)
+{
+ int a, b;
+ static int n_int = 0;
+ struct timeval tv;
+
+ do_gettimeofday(&tv);
+ a = readb(devpriv->mite->daq_io_addr + Group_Status);
+ b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+
+ if (n_int < 10) {
+ DPRINTK("status 0x%02x flags 0x%02x time %06d\n", a, b,
+ (int)tv.tv_usec);
+ }
+
+ while (b & 1) {
+ writew(0xff, devpriv->mite->daq_io_addr + Group_1_FIFO);
+ b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+ }
+
+ b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+
+ if (n_int < 10) {
+ DPRINTK("new status 0x%02x\n", b);
+ n_int++;
+ }
+}
+#endif
+
+static int ni_pcidio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 1)
+ return -EINVAL;
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= 1 << CR_CHAN(insn->chanspec);
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->io_bits & (1 << CR_CHAN(insn->
+ chanspec))) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+ writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
+
+ return 1;
+}
+
+static int ni_pcidio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
+ }
+ data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
+
+ return 2;
+}
+
+static int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_INT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ /* same for both TRIG_INT and TRIG_NOW */
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED (TIMER_BASE) /* in nanoseconds */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < MAX_SPEED) {
+ cmd->scan_begin_arg = MAX_SPEED;
+ err++;
+ }
+ /* no minumum speed */
+ } else {
+ /* TRIG_EXT */
+ /* should be level/edge, hi/lo specification here */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ /* no limit */
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
+{
+ int divider, base;
+
+ base = TIMER_BASE;
+
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ divider = (*nanosec + base / 2) / base;
+ break;
+ case TRIG_ROUND_DOWN:
+ divider = (*nanosec) / base;
+ break;
+ case TRIG_ROUND_UP:
+ divider = (*nanosec + base - 1) / base;
+ break;
+ }
+
+ *nanosec = base * divider;
+ return divider;
+}
+
+static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ /* XXX configure ports for input */
+ writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
+
+ if (1) {
+ /* enable fifos A B C D */
+ writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path);
+
+ /* set transfer width a 32 bits */
+ writeb(TransferWidth(0) | TransferLength(0),
+ devpriv->mite->daq_io_addr + Transfer_Size_Control);
+ } else {
+ writeb(0x03, devpriv->mite->daq_io_addr + Data_Path);
+ writeb(TransferWidth(3) | TransferLength(0),
+ devpriv->mite->daq_io_addr + Transfer_Size_Control);
+ }
+
+ /* protocol configuration */
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* page 4-5, "input with internal REQs" */
+ writeb(0, devpriv->mite->daq_io_addr + OpMode);
+ writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
+ writeb(1, devpriv->mite->daq_io_addr + Sequence);
+ writeb(0x04, devpriv->mite->daq_io_addr + ReqReg);
+ writeb(4, devpriv->mite->daq_io_addr + BlockMode);
+ writeb(3, devpriv->mite->daq_io_addr + LinePolarities);
+ writeb(0xc0, devpriv->mite->daq_io_addr + AckSer);
+ writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
+ TRIG_ROUND_NEAREST),
+ devpriv->mite->daq_io_addr + StartDelay);
+ writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
+ writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
+ writeb(1, devpriv->mite->daq_io_addr + AckDelay);
+ writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay);
+ writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay);
+ /* manual, page 4-5: ClockSpeed comment is incorrectly listed
+ * on DAQOptions */
+ writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
+ writeb(0, devpriv->mite->daq_io_addr + DAQOptions);
+ } else {
+ /* TRIG_EXT */
+ /* page 4-5, "input with external REQs" */
+ writeb(0, devpriv->mite->daq_io_addr + OpMode);
+ writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
+ writeb(0, devpriv->mite->daq_io_addr + Sequence);
+ writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
+ writeb(4, devpriv->mite->daq_io_addr + BlockMode);
+ writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
+ writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
+ writel(1, devpriv->mite->daq_io_addr + StartDelay);
+ writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
+ writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
+ writeb(1, devpriv->mite->daq_io_addr + AckDelay);
+ writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay);
+ writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay);
+ writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
+ writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions);
+ }
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ writel(cmd->stop_arg,
+ devpriv->mite->daq_io_addr + Transfer_Count);
+ } else {
+ /* XXX */
+ }
+
+#ifdef USE_DMA
+ writeb(ClearPrimaryTC | ClearSecondaryTC,
+ devpriv->mite->daq_io_addr + Group_1_First_Clear);
+
+ {
+ int retval = setup_mite_dma(dev, s);
+ if (retval)
+ return retval;
+ }
+#else
+ writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+#endif
+ writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2);
+
+ /* clear and enable interrupts */
+ writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
+ //writeb(ClearExpired,devpriv->mite->daq_io_addr+Group_1_Second_Clear);
+
+ writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
+ writeb(0x03,
+ devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
+
+ if (cmd->stop_src == TRIG_NONE) {
+ devpriv->OpModeBits = DataLatching(0) | RunMode(7);
+ } else { // TRIG_TIMER
+ devpriv->OpModeBits = Numbered | RunMode(7);
+ }
+ if (cmd->start_src == TRIG_NOW) {
+ /* start */
+ writeb(devpriv->OpModeBits,
+ devpriv->mite->daq_io_addr + OpMode);
+ s->async->inttrig = NULL;
+ } else {
+ /* TRIG_INT */
+ s->async->inttrig = ni_pcidio_inttrig;
+ }
+
+ DPRINTK("ni_pcidio: command started\n");
+ return 0;
+}
+
+static int setup_mite_dma(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int retval;
+
+ retval = ni_pcidio_request_di_mite_channel(dev);
+ if (retval)
+ return retval;
+
+ devpriv->di_mite_chan->dir = COMEDI_INPUT;
+
+ mite_prep_dma(devpriv->di_mite_chan, 32, 32);
+
+ mite_dma_arm(devpriv->di_mite_chan);
+ return 0;
+}
+
+static int ni_pcidio_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ if (trignum != 0)
+ return -EINVAL;
+
+ writeb(devpriv->OpModeBits, devpriv->mite->daq_io_addr + OpMode);
+ s->async->inttrig = NULL;
+
+ return 1;
+}
+
+static int ni_pcidio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ writeb(0x00,
+ devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
+ ni_pcidio_release_di_mite_channel(dev);
+
+ return 0;
+}
+
+static int ni_pcidio_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(devpriv->di_mite_ring, s->async);
+ if (ret < 0)
+ return ret;
+
+ memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz);
+
+ return 0;
+}
+
+static int pci_6534_load_fpga(struct comedi_device * dev, int fpga_index, u8 * data,
+ int data_len)
+{
+ static const int timeout = 1000;
+ int i, j;
+ writew(0x80 | fpga_index,
+ devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ writew(0xc0 | fpga_index,
+ devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ for (i = 0;
+ (readw(devpriv->mite->daq_io_addr +
+ Firmware_Status_Register) & 0x2) == 0
+ && i < timeout; ++i) {
+ udelay(1);
+ }
+ if (i == timeout) {
+ printk("ni_pcidio: failed to load fpga %i, waiting for status 0x2\n", fpga_index);
+ return -EIO;
+ }
+ writew(0x80 | fpga_index,
+ devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ for (i = 0;
+ readw(devpriv->mite->daq_io_addr + Firmware_Status_Register) !=
+ 0x3 && i < timeout; ++i) {
+ udelay(1);
+ }
+ if (i == timeout) {
+ printk("ni_pcidio: failed to load fpga %i, waiting for status 0x3\n", fpga_index);
+ return -EIO;
+ }
+ for (j = 0; j + 1 < data_len;) {
+ unsigned int value = data[j++];
+ value |= data[j++] << 8;
+ writew(value,
+ devpriv->mite->daq_io_addr + Firmware_Data_Register);
+ for (i = 0;
+ (readw(devpriv->mite->daq_io_addr +
+ Firmware_Status_Register) & 0x2) == 0
+ && i < timeout; ++i) {
+ udelay(1);
+ }
+ if (i == timeout) {
+ printk("ni_pcidio: failed to load word into fpga %i\n",
+ fpga_index);
+ return -EIO;
+ }
+ if (need_resched())
+ schedule();
+ }
+ writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ return 0;
+}
+
+static int pci_6534_reset_fpga(struct comedi_device * dev, int fpga_index)
+{
+ return pci_6534_load_fpga(dev, fpga_index, NULL, 0);
+}
+
+static int pci_6534_reset_fpgas(struct comedi_device * dev)
+{
+ int ret;
+ int i;
+ writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ for (i = 0; i < 3; ++i) {
+ ret = pci_6534_reset_fpga(dev, i);
+ if (ret < 0)
+ break;
+ }
+ writew(0x0, devpriv->mite->daq_io_addr + Firmware_Mask_Register);
+ return ret;
+}
+
+static void pci_6534_init_main_fpga(struct comedi_device * dev)
+{
+ writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register);
+ writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register);
+ writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register);
+ writel(0, devpriv->mite->daq_io_addr + FPGA_SCAMS_Counter_Register);
+ writel(0, devpriv->mite->daq_io_addr + FPGA_SCBLS_Counter_Register);
+ writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register);
+}
+
+static int pci_6534_upload_firmware(struct comedi_device * dev, int options[])
+{
+ int ret;
+ void *main_fpga_data, *scarab_a_data, *scarab_b_data;
+ int main_fpga_data_len, scarab_a_data_len, scarab_b_data_len;
+
+ if (options[COMEDI_DEVCONF_AUX_DATA_LENGTH] == 0)
+ return 0;
+ ret = pci_6534_reset_fpgas(dev);
+ if (ret < 0)
+ return ret;
+ main_fpga_data = comedi_aux_data(options, 0);
+ main_fpga_data_len = options[COMEDI_DEVCONF_AUX_DATA0_LENGTH];
+ ret = pci_6534_load_fpga(dev, 2, main_fpga_data, main_fpga_data_len);
+ if (ret < 0)
+ return ret;
+ pci_6534_init_main_fpga(dev);
+ scarab_a_data = comedi_aux_data(options, 1);
+ scarab_a_data_len = options[COMEDI_DEVCONF_AUX_DATA1_LENGTH];
+ ret = pci_6534_load_fpga(dev, 0, scarab_a_data, scarab_a_data_len);
+ if (ret < 0)
+ return ret;
+ scarab_b_data = comedi_aux_data(options, 2);
+ scarab_b_data_len = options[COMEDI_DEVCONF_AUX_DATA2_LENGTH];
+ ret = pci_6534_load_fpga(dev, 1, scarab_b_data, scarab_b_data_len);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int nidio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int i;
+ int ret;
+ int n_subdevices;
+ unsigned int irq;
+
+ printk("comedi%d: nidio:", dev->minor);
+
+ if ((ret = alloc_private(dev, sizeof(struct nidio96_private))) < 0)
+ return ret;
+ spin_lock_init(&devpriv->mite_channel_lock);
+
+ ret = nidio_find_device(dev, it->options[0], it->options[1]);
+ if (ret < 0)
+ return ret;
+
+ ret = mite_setup(devpriv->mite);
+ if (ret < 0) {
+ printk("error setting up mite\n");
+ return ret;
+ }
+ comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
+ devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
+ if (devpriv->di_mite_ring == NULL)
+ return -ENOMEM;
+
+ dev->board_name = this_board->name;
+ irq = mite_irq(devpriv->mite);
+ printk(" %s", dev->board_name);
+ if (this_board->uses_firmware) {
+ ret = pci_6534_upload_firmware(dev, it->options);
+ if (ret < 0)
+ return ret;
+ }
+ if (!this_board->is_diodaq) {
+ n_subdevices = this_board->n_8255;
+ } else {
+ n_subdevices = 1;
+ }
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+ return ret;
+
+ if (!this_board->is_diodaq) {
+ for (i = 0; i < this_board->n_8255; i++) {
+ subdev_8255_init(dev, dev->subdevices + i,
+ nidio96_8255_cb,
+ (unsigned long)(devpriv->mite->daq_io_addr +
+ NIDIO_8255_BASE(i)));
+ }
+ } else {
+
+ printk(" rev=%d",
+ readb(devpriv->mite->daq_io_addr + Chip_Version));
+
+ s = dev->subdevices + 0;
+
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
+ SDF_CMD_READ;
+ s->n_chan = 32;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_config = &ni_pcidio_insn_config;
+ s->insn_bits = &ni_pcidio_insn_bits;
+ s->do_cmd = &ni_pcidio_cmd;
+ s->do_cmdtest = &ni_pcidio_cmdtest;
+ s->cancel = &ni_pcidio_cancel;
+ s->len_chanlist = 32; /* XXX */
+ s->buf_change = &ni_pcidio_change;
+ s->async_dma_dir = DMA_BIDIRECTIONAL;
+
+ writel(0, devpriv->mite->daq_io_addr + Port_IO(0));
+ writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
+ writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0));
+
+ /* disable interrupts on board */
+ writeb(0x00,
+ devpriv->mite->daq_io_addr +
+ Master_DMA_And_Interrupt_Control);
+
+ ret = comedi_request_irq(irq, nidio_interrupt, IRQF_SHARED,
+ "ni_pcidio", dev);
+ if (ret < 0) {
+ printk(" irq not available");
+ }
+ dev->irq = irq;
+ }
+
+ printk("\n");
+
+ return 0;
+}
+
+static int nidio_detach(struct comedi_device * dev)
+{
+ int i;
+
+ if (this_board && !this_board->is_diodaq) {
+ for (i = 0; i < this_board->n_8255; i++) {
+ subdev_8255_cleanup(dev, dev->subdevices + i);
+ }
+ }
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (devpriv) {
+ if (devpriv->di_mite_ring) {
+ mite_free_ring(devpriv->di_mite_ring);
+ devpriv->di_mite_ring = NULL;
+ }
+ if (devpriv->mite)
+ mite_unsetup(devpriv->mite);
+ }
+ return 0;
+}
+
+static int nidio_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number ||
+ slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+ for (i = 0; i < n_nidio_boards; i++) {
+ if (mite_device_id(mite) == nidio_boards[i].dev_id) {
+ dev->board_ptr = nidio_boards + i;
+ devpriv->mite = mite;
+
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_pcidio, ni_pcidio_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
new file mode 100644
index 00000000000..3a2aba7c8dd
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_pcimio.c
@@ -0,0 +1,1788 @@
+/*
+ comedi/drivers/ni_pcimio.c
+ Hardware driver for NI PCI-MIO E series cards
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: ni_pcimio
+Description: National Instruments PCI-MIO-E series and M series (all boards)
+Author: ds, John Hallen, Frank Mori Hess, Rolf Mueller, Herbert Peremans,
+ Herman Bruyninckx, Terry Barnaby
+Status: works
+Devices: [National Instruments] PCI-MIO-16XE-50 (ni_pcimio),
+ PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014, PCI-6040E,
+ PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E,
+ PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E,
+ PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224, PCI-6225,
+ PCI-6229, PCI-6250, PCI-6251, PCIe-6251, PCI-6254, PCI-6259, PCIe-6259,
+ PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289,
+ PCI-6711, PXI-6711, PCI-6713, PXI-6713,
+ PXI-6071E, PCI-6070E, PXI-6070E,
+ PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733,
+ PCI-6143, PXI-6143
+Updated: Wed, 03 Dec 2008 10:51:47 +0000
+
+These boards are almost identical to the AT-MIO E series, except that
+they use the PCI bus instead of ISA (i.e., AT). See the notes for
+the ni_atmio.o driver for additional information about these boards.
+
+Autocalibration is supported on many of the devices, using the
+comedi_calibrate (or comedi_soft_calibrate for m-series) utility.
+M-Series boards do analog input and analog output calibration entirely
+in software. The software calibration corrects
+the analog input for offset, gain and
+nonlinearity. The analog outputs are corrected for offset and gain.
+See the comedilib documentation on comedi_get_softcal_converter() for
+more information.
+
+By default, the driver uses DMA to transfer analog input data to
+memory. When DMA is enabled, not all triggering features are
+supported.
+
+Digital I/O may not work on 673x.
+
+Note that the PCI-6143 is a simultaineous sampling device with 8 convertors.
+With this board all of the convertors perform one simultaineous sample during
+a scan interval. The period for a scan is used for the convert time in a
+Comedi cmd. The convert trigger source is normally set to TRIG_NOW by default.
+
+The RTSI trigger bus is supported on these cards on
+subdevice 10. See the comedilib documentation for details.
+
+Information (number of channels, bits, etc.) for some devices may be
+incorrect. Please check this and submit a bug if there are problems
+for your device.
+
+SCXI is probably broken for m-series boards.
+
+Bugs:
+ - When DMA is enabled, COMEDI_EV_CONVERT does
+ not work correctly.
+
+*/
+/*
+ The PCI-MIO E series driver was originally written by
+ Tomasz Motylewski <...>, and ported to comedi by ds.
+
+ References:
+
+ 341079b.pdf PCI E Series Register-Level Programmer Manual
+ 340934b.pdf DAQ-STC reference manual
+
+ 322080b.pdf 6711/6713/6715 User Manual
+
+ 320945c.pdf PCI E Series User Manual
+ 322138a.pdf PCI-6052E and DAQPad-6052E User Manual
+
+ ISSUES:
+
+ need to deal with external reference for DAC, and other DAC
+ properties in board properties
+
+ deal with at-mio-16de-10 revision D to N changes, etc.
+
+ need to add other CALDAC type
+
+ need to slow down DAC loading. I don't trust NI's claim that
+ two writes to the PCI bus slows IO enough. I would prefer to
+ use comedi_udelay(). Timing specs: (clock)
+ AD8522 30ns
+ DAC8043 120ns
+ DAC8800 60ns
+ MB88341 ?
+
+*/
+
+#include "../comedidev.h"
+
+#include <asm/byteorder.h>
+#include <linux/delay.h>
+
+#include "ni_stc.h"
+#include "mite.h"
+
+//#define PCI_DEBUG
+
+#define PCIDMA
+
+#define PCIMIO 1
+#undef ATMIO
+
+#define MAX_N_CALDACS (16+16+2)
+
+#define DRV_NAME "ni_pcimio"
+
+/* The following two tables must be in the same order */
+static DEFINE_PCI_DEVICE_TABLE(ni_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x0162, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1170, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1190, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x11b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x11c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x11d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x14e0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x14f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1580, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x15b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1870, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x18b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x18c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2890, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x28c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2a60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2a70, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2a80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2ab0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2b80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2b90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2c80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2ca0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70aa, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70ab, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70ac, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70af, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70b4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70b6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70b7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70bd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70bf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x710d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x716c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x717f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x71bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x717d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_pci_table);
+
+/* These are not all the possible ao ranges for 628x boards.
+ They can do OFFSET +- REFERENCE where OFFSET can be
+ 0V, 5V, APFI<0,1>, or AO<0...3> and RANGE can
+ be 10V, 5V, 2V, 1V, APFI<0,1>, AO<0...3>. That's
+ 63 different possibilities. An AO channel
+ can not act as it's own OFFSET or REFERENCE.
+*/
+static const struct comedi_lrange range_ni_M_628x_ao = { 8, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2, 2),
+ RANGE(-1, 1),
+ RANGE(-5, 15),
+ RANGE(0, 10),
+ RANGE(3, 7),
+ RANGE(4, 6),
+ RANGE_ext(-1, 1)
+ }
+};
+static const struct comedi_lrange range_ni_M_625x_ao = { 3, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE_ext(-1, 1)
+ }
+};
+static const struct comedi_lrange range_ni_M_622x_ao = { 1, {
+ RANGE(-10, 10),
+ }
+};
+
+static const ni_board ni_boards[] = {
+ {
+ .device_id = 0x0162, // NI also says 0x1620. typo?
+ .name = "pci-mio-16xe-50",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 2048,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_8,
+ .ai_speed = 50000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_speed = 50000,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x1170,
+ .name = "pci-mio-16xe-10", // aka pci-6030E
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043, ad8522},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x28c0,
+ .name = "pci-6014",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x11d0,
+ .name = "pxi-6030e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043, ad8522},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x1180,
+ .name = "pci-mio-16e-1", /* aka pci-6070e */
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = {mb88341},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x1190,
+ .name = "pci-mio-16e-4", /* aka pci-6040e */
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_16,
+ /* Note: there have been reported problems with full speed
+ * on this board */
+ .ai_speed = 2000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 512,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug}, // doc says mb88341
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x11c0,
+ .name = "pxi-6040e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 2000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 512,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = {mb88341},
+ .has_8255 = 0,
+ },
+
+ {
+ .device_id = 0x1330,
+ .name = "pci-6031e",
+ .n_adchan = 64,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043, ad8522},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x1270,
+ .name = "pci-6032e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043, ad8522},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x1340,
+ .name = "pci-6033e",
+ .n_adchan = 64,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043, ad8522},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x1350,
+ .name = "pci-6071e",
+ .n_adchan = 64,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x2a60,
+ .name = "pci-6023e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug}, /* manual is wrong */
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x2a70,
+ .name = "pci-6024e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug}, /* manual is wrong */
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x2a80,
+ .name = "pci-6025e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug}, /* manual is wrong */
+ .has_8255 = 1,
+ },
+ {
+ .device_id = 0x2ab0,
+ .name = "pxi-6025e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug}, /* manual is wrong */
+ .has_8255 = 1,
+ },
+
+ {
+ .device_id = 0x2ca0,
+ .name = "pci-6034e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x2c80,
+ .name = "pci-6035e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x18b0,
+ .name = "pci-6052e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 3000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_unipolar = 1,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 3000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug, ad8804_debug, ad8522}, /* manual is wrong */
+ },
+ {.device_id = 0x14e0,
+ .name = "pci-6110",
+ .n_adchan = 4,
+ .adbits = 12,
+ .ai_fifo_depth = 8192,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_611x,
+ .ai_speed = 200,
+ .n_aochan = 2,
+ .aobits = 16,
+ .reg_type = ni_reg_611x,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 2048,
+ .ao_speed = 250,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804, ad8804},
+ },
+ {
+ .device_id = 0x14f0,
+ .name = "pci-6111",
+ .n_adchan = 2,
+ .adbits = 12,
+ .ai_fifo_depth = 8192,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_611x,
+ .ai_speed = 200,
+ .n_aochan = 2,
+ .aobits = 16,
+ .reg_type = ni_reg_611x,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 2048,
+ .ao_speed = 250,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804, ad8804},
+ },
+#if 0
+ /* The 6115 boards probably need their own driver */
+ {
+ .device_id = 0x2ed0,
+ .name = "pci-6115",
+ .n_adchan = 4,
+ .adbits = 12,
+ .ai_fifo_depth = 8192,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_611x,
+ .ai_speed = 100,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_671x = 1,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 2048,
+ .ao_speed = 250,
+ .num_p0_dio_channels = 8,
+ .reg_611x = 1,
+ .caldac = {ad8804_debug, ad8804_debug, ad8804_debug}, /* XXX */
+ },
+#endif
+#if 0
+ {
+ .device_id = 0x0000,
+ .name = "pxi-6115",
+ .n_adchan = 4,
+ .adbits = 12,
+ .ai_fifo_depth = 8192,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_611x,
+ .ai_speed = 100,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_671x = 1,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 2048,
+ .ao_speed = 250,
+ .reg_611x = 1,
+ .num_p0_dio_channels = 8,
+ caldac = {ad8804_debug, ad8804_debug, ad8804_debug}, /* XXX */
+ },
+#endif
+ {
+ .device_id = 0x1880,
+ .name = "pci-6711",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 4,
+ .aobits = 12,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 16384,
+ /* data sheet says 8192, but fifo really holds 16384 samples */
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6711,
+ .caldac = {ad8804_debug},
+ },
+ {
+ .device_id = 0x2b90,
+ .name = "pxi-6711",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 4,
+ .aobits = 12,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6711,
+ .caldac = {ad8804_debug},
+ },
+ {
+ .device_id = 0x1870,
+ .name = "pci-6713",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 8,
+ .aobits = 12,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6713,
+ .caldac = {ad8804_debug, ad8804_debug},
+ },
+ {
+ .device_id = 0x2b80,
+ .name = "pxi-6713",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 8,
+ .aobits = 12,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6713,
+ .caldac = {ad8804_debug, ad8804_debug},
+ },
+ {
+ .device_id = 0x2430,
+ .name = "pci-6731",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 8192,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6711,
+ .caldac = {ad8804_debug},
+ },
+#if 0 /* need device ids */
+ {
+ .device_id = 0x0,
+ .name = "pxi-6731",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 8192,
+ .ao_range_table = &range_bipolar10,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6711,
+ .caldac = {ad8804_debug},
+ },
+#endif
+ {
+ .device_id = 0x2410,
+ .name = "pci-6733",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 8,
+ .aobits = 16,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6713,
+ .caldac = {ad8804_debug, ad8804_debug},
+ },
+ {
+ .device_id = 0x2420,
+ .name = "pxi-6733",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 8,
+ .aobits = 16,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6713,
+ .caldac = {ad8804_debug, ad8804_debug},
+ },
+ {
+ .device_id = 0x15b0,
+ .name = "pxi-6071e",
+ .n_adchan = 64,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x11b0,
+ .name = "pxi-6070e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x18c0,
+ .name = "pxi-6052e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 3000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_unipolar = 1,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 3000,
+ .num_p0_dio_channels = 8,
+ .caldac = {mb88341, mb88341, ad8522},
+ },
+ {
+ .device_id = 0x1580,
+ .name = "pxi-6031e",
+ .n_adchan = 64,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043, ad8522},
+ },
+ {
+ .device_id = 0x2890,
+ .name = "pci-6036e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70b0,
+ .name = "pci-6220",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ //FIXME: guess
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70af,
+ .name = "pci-6221",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_622x_ao,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .ao_speed = 1200,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x71bc,
+ .name = "pci-6221_37pin",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_622x_ao,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .ao_speed = 1200,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70f2,
+ .name = "pci-6224",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70f3,
+ .name = "pxi-6224",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x716c,
+ .name = "pci-6225",
+ .n_adchan = 80,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_622x_ao,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .ao_speed = 1200,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70aa,
+ .name = "pci-6229",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_622x_ao,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .ao_speed = 1200,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70b4,
+ .name = "pci-6250",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70b8,
+ .name = "pci-6251",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x717d,
+ .name = "pcie-6251",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70b7,
+ .name = "pci-6254",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70ab,
+ .name = "pci-6259",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x717f,
+ .name = "pcie-6259",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70b6,
+ .name = "pci-6280",
+ .n_adchan = 16,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 8191,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70bd,
+ .name = "pci-6281",
+ .n_adchan = 16,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_628x_ao,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 1,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70bf,
+ .name = "pxi-6281",
+ .n_adchan = 16,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_628x_ao,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 1,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70bc,
+ .name = "pci-6284",
+ .n_adchan = 32,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70ac,
+ .name = "pci-6289",
+ .n_adchan = 32,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_628x_ao,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 1,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70C0,
+ .name = "pci-6143",
+ .n_adchan = 8,
+ .adbits = 16,
+ .ai_fifo_depth = 1024,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_6143,
+ .ai_speed = 4000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .reg_type = ni_reg_6143,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug, ad8804_debug},
+ },
+ {
+ .device_id = 0x710D,
+ .name = "pxi-6143",
+ .n_adchan = 8,
+ .adbits = 16,
+ .ai_fifo_depth = 1024,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_6143,
+ .ai_speed = 4000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .reg_type = ni_reg_6143,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug, ad8804_debug},
+ },
+};
+
+#define n_pcimio_boards ((sizeof(ni_boards)/sizeof(ni_boards[0])))
+
+static int pcimio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcimio_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcimio = {
+ driver_name: DRV_NAME,
+ module:THIS_MODULE,
+ attach:pcimio_attach,
+ detach:pcimio_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_pcimio, ni_pci_table)
+
+typedef struct {
+NI_PRIVATE_COMMON} ni_private;
+#define devpriv ((ni_private *)dev->private)
+
+/* How we access registers */
+
+#define ni_writel(a,b) (writel((a), devpriv->mite->daq_io_addr + (b)))
+#define ni_readl(a) (readl(devpriv->mite->daq_io_addr + (a)))
+#define ni_writew(a,b) (writew((a), devpriv->mite->daq_io_addr + (b)))
+#define ni_readw(a) (readw(devpriv->mite->daq_io_addr + (a)))
+#define ni_writeb(a,b) (writeb((a), devpriv->mite->daq_io_addr + (b)))
+#define ni_readb(a) (readb(devpriv->mite->daq_io_addr + (a)))
+
+/* How we access STC registers */
+
+/* We automatically take advantage of STC registers that can be
+ * read/written directly in the I/O space of the board. Most
+ * PCIMIO devices map the low 8 STC registers to iobase+addr*2.
+ * The 611x devices map the write registers to iobase+addr*2, and
+ * the read registers to iobase+(addr-1)*2. */
+/* However, the 611x boards still aren't working, so I'm disabling
+ * non-windowed STC access temporarily */
+
+static void e_series_win_out(struct comedi_device * dev, uint16_t data, int reg)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ ni_writew(reg, Window_Address);
+ ni_writew(data, Window_Data);
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static uint16_t e_series_win_in(struct comedi_device * dev, int reg)
+{
+ unsigned long flags;
+ uint16_t ret;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ ni_writew(reg, Window_Address);
+ ret = ni_readw(Window_Data);
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+
+ return ret;
+}
+
+static void m_series_stc_writew(struct comedi_device * dev, uint16_t data, int reg)
+{
+ unsigned offset;
+ switch (reg) {
+ case ADC_FIFO_Clear:
+ offset = M_Offset_AI_FIFO_Clear;
+ break;
+ case AI_Command_1_Register:
+ offset = M_Offset_AI_Command_1;
+ break;
+ case AI_Command_2_Register:
+ offset = M_Offset_AI_Command_2;
+ break;
+ case AI_Mode_1_Register:
+ offset = M_Offset_AI_Mode_1;
+ break;
+ case AI_Mode_2_Register:
+ offset = M_Offset_AI_Mode_2;
+ break;
+ case AI_Mode_3_Register:
+ offset = M_Offset_AI_Mode_3;
+ break;
+ case AI_Output_Control_Register:
+ offset = M_Offset_AI_Output_Control;
+ break;
+ case AI_Personal_Register:
+ offset = M_Offset_AI_Personal;
+ break;
+ case AI_SI2_Load_A_Register:
+ // this is actually a 32 bit register on m series boards
+ ni_writel(data, M_Offset_AI_SI2_Load_A);
+ return;
+ break;
+ case AI_SI2_Load_B_Register:
+ // this is actually a 32 bit register on m series boards
+ ni_writel(data, M_Offset_AI_SI2_Load_B);
+ return;
+ break;
+ case AI_START_STOP_Select_Register:
+ offset = M_Offset_AI_START_STOP_Select;
+ break;
+ case AI_Trigger_Select_Register:
+ offset = M_Offset_AI_Trigger_Select;
+ break;
+ case Analog_Trigger_Etc_Register:
+ offset = M_Offset_Analog_Trigger_Etc;
+ break;
+ case AO_Command_1_Register:
+ offset = M_Offset_AO_Command_1;
+ break;
+ case AO_Command_2_Register:
+ offset = M_Offset_AO_Command_2;
+ break;
+ case AO_Mode_1_Register:
+ offset = M_Offset_AO_Mode_1;
+ break;
+ case AO_Mode_2_Register:
+ offset = M_Offset_AO_Mode_2;
+ break;
+ case AO_Mode_3_Register:
+ offset = M_Offset_AO_Mode_3;
+ break;
+ case AO_Output_Control_Register:
+ offset = M_Offset_AO_Output_Control;
+ break;
+ case AO_Personal_Register:
+ offset = M_Offset_AO_Personal;
+ break;
+ case AO_Start_Select_Register:
+ offset = M_Offset_AO_Start_Select;
+ break;
+ case AO_Trigger_Select_Register:
+ offset = M_Offset_AO_Trigger_Select;
+ break;
+ case Clock_and_FOUT_Register:
+ offset = M_Offset_Clock_and_FOUT;
+ break;
+ case Configuration_Memory_Clear:
+ offset = M_Offset_Configuration_Memory_Clear;
+ break;
+ case DAC_FIFO_Clear:
+ offset = M_Offset_AO_FIFO_Clear;
+ break;
+ case DIO_Control_Register:
+ rt_printk
+ ("%s: FIXME: register 0x%x does not map cleanly on to m-series boards.\n",
+ __FUNCTION__, reg);
+ return;
+ break;
+ case G_Autoincrement_Register(0):
+ offset = M_Offset_G0_Autoincrement;
+ break;
+ case G_Autoincrement_Register(1):
+ offset = M_Offset_G1_Autoincrement;
+ break;
+ case G_Command_Register(0):
+ offset = M_Offset_G0_Command;
+ break;
+ case G_Command_Register(1):
+ offset = M_Offset_G1_Command;
+ break;
+ case G_Input_Select_Register(0):
+ offset = M_Offset_G0_Input_Select;
+ break;
+ case G_Input_Select_Register(1):
+ offset = M_Offset_G1_Input_Select;
+ break;
+ case G_Mode_Register(0):
+ offset = M_Offset_G0_Mode;
+ break;
+ case G_Mode_Register(1):
+ offset = M_Offset_G1_Mode;
+ break;
+ case Interrupt_A_Ack_Register:
+ offset = M_Offset_Interrupt_A_Ack;
+ break;
+ case Interrupt_A_Enable_Register:
+ offset = M_Offset_Interrupt_A_Enable;
+ break;
+ case Interrupt_B_Ack_Register:
+ offset = M_Offset_Interrupt_B_Ack;
+ break;
+ case Interrupt_B_Enable_Register:
+ offset = M_Offset_Interrupt_B_Enable;
+ break;
+ case Interrupt_Control_Register:
+ offset = M_Offset_Interrupt_Control;
+ break;
+ case IO_Bidirection_Pin_Register:
+ offset = M_Offset_IO_Bidirection_Pin;
+ break;
+ case Joint_Reset_Register:
+ offset = M_Offset_Joint_Reset;
+ break;
+ case RTSI_Trig_A_Output_Register:
+ offset = M_Offset_RTSI_Trig_A_Output;
+ break;
+ case RTSI_Trig_B_Output_Register:
+ offset = M_Offset_RTSI_Trig_B_Output;
+ break;
+ case RTSI_Trig_Direction_Register:
+ offset = M_Offset_RTSI_Trig_Direction;
+ break;
+ /* FIXME: DIO_Output_Register (16 bit reg) is replaced by M_Offset_Static_Digital_Output (32 bit)
+ and M_Offset_SCXI_Serial_Data_Out (8 bit) */
+ default:
+ rt_printk("%s: bug! unhandled register=0x%x in switch.\n",
+ __FUNCTION__, reg);
+ BUG();
+ return;
+ break;
+ }
+ ni_writew(data, offset);
+}
+
+static uint16_t m_series_stc_readw(struct comedi_device * dev, int reg)
+{
+ unsigned offset;
+ switch (reg) {
+ case AI_Status_1_Register:
+ offset = M_Offset_AI_Status_1;
+ break;
+ case AO_Status_1_Register:
+ offset = M_Offset_AO_Status_1;
+ break;
+ case AO_Status_2_Register:
+ offset = M_Offset_AO_Status_2;
+ break;
+ case DIO_Serial_Input_Register:
+ return ni_readb(M_Offset_SCXI_Serial_Data_In);
+ break;
+ case Joint_Status_1_Register:
+ offset = M_Offset_Joint_Status_1;
+ break;
+ case Joint_Status_2_Register:
+ offset = M_Offset_Joint_Status_2;
+ break;
+ case G_Status_Register:
+ offset = M_Offset_G01_Status;
+ break;
+ default:
+ rt_printk("%s: bug! unhandled register=0x%x in switch.\n",
+ __FUNCTION__, reg);
+ BUG();
+ return 0;
+ break;
+ }
+ return ni_readw(offset);
+}
+
+static void m_series_stc_writel(struct comedi_device * dev, uint32_t data, int reg)
+{
+ unsigned offset;
+ switch (reg) {
+ case AI_SC_Load_A_Registers:
+ offset = M_Offset_AI_SC_Load_A;
+ break;
+ case AI_SI_Load_A_Registers:
+ offset = M_Offset_AI_SI_Load_A;
+ break;
+ case AO_BC_Load_A_Register:
+ offset = M_Offset_AO_BC_Load_A;
+ break;
+ case AO_UC_Load_A_Register:
+ offset = M_Offset_AO_UC_Load_A;
+ break;
+ case AO_UI_Load_A_Register:
+ offset = M_Offset_AO_UI_Load_A;
+ break;
+ case G_Load_A_Register(0):
+ offset = M_Offset_G0_Load_A;
+ break;
+ case G_Load_A_Register(1):
+ offset = M_Offset_G1_Load_A;
+ break;
+ case G_Load_B_Register(0):
+ offset = M_Offset_G0_Load_B;
+ break;
+ case G_Load_B_Register(1):
+ offset = M_Offset_G1_Load_B;
+ break;
+ default:
+ rt_printk("%s: bug! unhandled register=0x%x in switch.\n",
+ __FUNCTION__, reg);
+ BUG();
+ return;
+ break;
+ }
+ ni_writel(data, offset);
+}
+
+static uint32_t m_series_stc_readl(struct comedi_device * dev, int reg)
+{
+ unsigned offset;
+ switch (reg) {
+ case G_HW_Save_Register(0):
+ offset = M_Offset_G0_HW_Save;
+ break;
+ case G_HW_Save_Register(1):
+ offset = M_Offset_G1_HW_Save;
+ break;
+ case G_Save_Register(0):
+ offset = M_Offset_G0_Save;
+ break;
+ case G_Save_Register(1):
+ offset = M_Offset_G1_Save;
+ break;
+ default:
+ rt_printk("%s: bug! unhandled register=0x%x in switch.\n",
+ __FUNCTION__, reg);
+ BUG();
+ return 0;
+ break;
+ }
+ return ni_readl(offset);
+}
+
+#define interrupt_pin(a) 0
+#define IRQ_POLARITY 1
+
+#define NI_E_IRQ_FLAGS IRQF_SHARED
+
+#include "ni_mio_common.c"
+
+static int pcimio_find_device(struct comedi_device * dev, int bus, int slot);
+static int pcimio_ai_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size);
+static int pcimio_ao_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size);
+static int pcimio_gpct0_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size);
+static int pcimio_gpct1_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size);
+static int pcimio_dio_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size);
+
+static void m_series_init_eeprom_buffer(struct comedi_device * dev)
+{
+ static const int Start_Cal_EEPROM = 0x400;
+ static const unsigned window_size = 10;
+ static const int serial_number_eeprom_offset = 0x4;
+ static const int serial_number_eeprom_length = 0x4;
+ unsigned old_iodwbsr_bits;
+ unsigned old_iodwbsr1_bits;
+ unsigned old_iodwcr1_bits;
+ int i;
+
+ old_iodwbsr_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWBSR);
+ old_iodwbsr1_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
+ old_iodwcr1_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWCR_1);
+ writel(0x0, devpriv->mite->mite_io_addr + MITE_IODWBSR);
+ writel(((0x80 | window_size) | devpriv->mite->daq_phys_addr),
+ devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
+ writel(0x1 | old_iodwcr1_bits, devpriv->mite->mite_io_addr + MITE_IODWCR_1);
+ writel(0xf, devpriv->mite->mite_io_addr + 0x30);
+
+ BUG_ON(serial_number_eeprom_length > sizeof(devpriv->serial_number));
+ for (i = 0; i < serial_number_eeprom_length; ++i) {
+ char *byte_ptr = (char*)&devpriv->serial_number + i;
+ *byte_ptr = ni_readb(serial_number_eeprom_offset + i);
+ }
+ devpriv->serial_number = be32_to_cpu(devpriv->serial_number);
+
+ for (i = 0; i < M_SERIES_EEPROM_SIZE; ++i) {
+ devpriv->eeprom_buffer[i] = ni_readb(Start_Cal_EEPROM + i);
+ }
+
+ writel(old_iodwbsr1_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
+ writel(old_iodwbsr_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR);
+ writel(old_iodwcr1_bits, devpriv->mite->mite_io_addr + MITE_IODWCR_1);
+ writel(0x0, devpriv->mite->mite_io_addr + 0x30);
+}
+
+static void init_6143(struct comedi_device * dev)
+{
+ // Disable interrupts
+ devpriv->stc_writew(dev, 0, Interrupt_Control_Register);
+
+ // Initialise 6143 AI specific bits
+ ni_writeb(0x00, Magic_6143); // Set G0,G1 DMA mode to E series version
+ ni_writeb(0x80, PipelineDelay_6143); // Set EOCMode, ADCMode and pipelinedelay
+ ni_writeb(0x00, EOC_Set_6143); // Set EOC Delay
+
+ ni_writel(boardtype.ai_fifo_depth / 2, AIFIFO_Flag_6143); // Set the FIFO half full level
+
+ // Strobe Relay disable bit
+ devpriv->ai_calib_source_enabled = 0;
+ ni_writew(devpriv->ai_calib_source | Calibration_Channel_6143_RelayOff,
+ Calibration_Channel_6143);
+ ni_writew(devpriv->ai_calib_source, Calibration_Channel_6143);
+}
+
+/* cleans up allocated resources */
+static int pcimio_detach(struct comedi_device * dev)
+{
+ mio_common_detach(dev);
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (dev->private) {
+ mite_free_ring(devpriv->ai_mite_ring);
+ mite_free_ring(devpriv->ao_mite_ring);
+ mite_free_ring(devpriv->cdo_mite_ring);
+ mite_free_ring(devpriv->gpct_mite_ring[0]);
+ mite_free_ring(devpriv->gpct_mite_ring[1]);
+ if (devpriv->mite)
+ mite_unsetup(devpriv->mite);
+ }
+
+ return 0;
+}
+
+static int pcimio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+
+ printk("comedi%d: ni_pcimio:", dev->minor);
+
+ ret = ni_alloc_private(dev);
+ if (ret < 0)
+ return ret;
+
+ ret = pcimio_find_device(dev, it->options[0], it->options[1]);
+ if (ret < 0)
+ return ret;
+
+ printk(" %s", boardtype.name);
+ dev->board_name = boardtype.name;
+
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ devpriv->stc_writew = &m_series_stc_writew;
+ devpriv->stc_readw = &m_series_stc_readw;
+ devpriv->stc_writel = &m_series_stc_writel;
+ devpriv->stc_readl = &m_series_stc_readl;
+ } else {
+ devpriv->stc_writew = &e_series_win_out;
+ devpriv->stc_readw = &e_series_win_in;
+ devpriv->stc_writel = &win_out2;
+ devpriv->stc_readl = &win_in2;
+ }
+
+ ret = mite_setup(devpriv->mite);
+ if (ret < 0) {
+ printk(" error setting up mite\n");
+ return ret;
+ }
+ comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
+ devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite);
+ if (devpriv->ai_mite_ring == NULL)
+ return -ENOMEM;
+ devpriv->ao_mite_ring = mite_alloc_ring(devpriv->mite);
+ if (devpriv->ao_mite_ring == NULL)
+ return -ENOMEM;
+ devpriv->cdo_mite_ring = mite_alloc_ring(devpriv->mite);
+ if (devpriv->cdo_mite_ring == NULL)
+ return -ENOMEM;
+ devpriv->gpct_mite_ring[0] = mite_alloc_ring(devpriv->mite);
+ if (devpriv->gpct_mite_ring[0] == NULL)
+ return -ENOMEM;
+ devpriv->gpct_mite_ring[1] = mite_alloc_ring(devpriv->mite);
+ if (devpriv->gpct_mite_ring[1] == NULL)
+ return -ENOMEM;
+
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ m_series_init_eeprom_buffer(dev);
+ if (boardtype.reg_type == ni_reg_6143)
+ init_6143(dev);
+
+ dev->irq = mite_irq(devpriv->mite);
+
+ if (dev->irq == 0) {
+ printk(" unknown irq (bad)\n");
+ } else {
+ printk(" ( irq = %u )", dev->irq);
+ if ((ret = comedi_request_irq(dev->irq, ni_E_interrupt,
+ NI_E_IRQ_FLAGS, DRV_NAME,
+ dev)) < 0) {
+ printk(" irq not available\n");
+ dev->irq = 0;
+ }
+ }
+
+ ret = ni_E_init(dev, it);
+ if (ret < 0)
+ return ret;
+
+ dev->subdevices[NI_AI_SUBDEV].buf_change = &pcimio_ai_change;
+ dev->subdevices[NI_AO_SUBDEV].buf_change = &pcimio_ao_change;
+ dev->subdevices[NI_GPCT_SUBDEV(0)].buf_change = &pcimio_gpct0_change;
+ dev->subdevices[NI_GPCT_SUBDEV(1)].buf_change = &pcimio_gpct1_change;
+ dev->subdevices[NI_DIO_SUBDEV].buf_change = &pcimio_dio_change;
+
+ return ret;
+}
+
+static int pcimio_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number ||
+ slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+
+ for (i = 0; i < n_pcimio_boards; i++) {
+ if (mite_device_id(mite) == ni_boards[i].device_id) {
+ dev->board_ptr = ni_boards + i;
+ devpriv->mite = mite;
+
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
+
+static int pcimio_ai_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(devpriv->ai_mite_ring, s->async);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int pcimio_ao_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(devpriv->ao_mite_ring, s->async);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int pcimio_gpct0_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(devpriv->gpct_mite_ring[0], s->async);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int pcimio_gpct1_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(devpriv->gpct_mite_ring[1], s->async);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int pcimio_dio_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(devpriv->cdo_mite_ring, s->async);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h
new file mode 100644
index 00000000000..1ebf521ab77
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_stc.h
@@ -0,0 +1,1498 @@
+/*
+ module/ni_stc.h
+ Register descriptions for NI DAQ-STC chip
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998-9 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/*
+ References:
+ DAQ-STC Technical Reference Manual
+*/
+
+#ifndef _COMEDI_NI_STC_H
+#define _COMEDI_NI_STC_H
+
+#include "ni_tio.h"
+
+#define _bit15 0x8000
+#define _bit14 0x4000
+#define _bit13 0x2000
+#define _bit12 0x1000
+#define _bit11 0x0800
+#define _bit10 0x0400
+#define _bit9 0x0200
+#define _bit8 0x0100
+#define _bit7 0x0080
+#define _bit6 0x0040
+#define _bit5 0x0020
+#define _bit4 0x0010
+#define _bit3 0x0008
+#define _bit2 0x0004
+#define _bit1 0x0002
+#define _bit0 0x0001
+
+#define NUM_PFI_OUTPUT_SELECT_REGS 6
+
+/* Registers in the National Instruments DAQ-STC chip */
+
+#define Interrupt_A_Ack_Register 2
+#define G0_Gate_Interrupt_Ack _bit15
+#define G0_TC_Interrupt_Ack _bit14
+#define AI_Error_Interrupt_Ack _bit13
+#define AI_STOP_Interrupt_Ack _bit12
+#define AI_START_Interrupt_Ack _bit11
+#define AI_START2_Interrupt_Ack _bit10
+#define AI_START1_Interrupt_Ack _bit9
+#define AI_SC_TC_Interrupt_Ack _bit8
+#define AI_SC_TC_Error_Confirm _bit7
+#define G0_TC_Error_Confirm _bit6
+#define G0_Gate_Error_Confirm _bit5
+
+#define AI_Status_1_Register 2
+#define Interrupt_A_St 0x8000
+#define AI_FIFO_Full_St 0x4000
+#define AI_FIFO_Half_Full_St 0x2000
+#define AI_FIFO_Empty_St 0x1000
+#define AI_Overrun_St 0x0800
+#define AI_Overflow_St 0x0400
+#define AI_SC_TC_Error_St 0x0200
+#define AI_START2_St 0x0100
+#define AI_START1_St 0x0080
+#define AI_SC_TC_St 0x0040
+#define AI_START_St 0x0020
+#define AI_STOP_St 0x0010
+#define G0_TC_St 0x0008
+#define G0_Gate_Interrupt_St 0x0004
+#define AI_FIFO_Request_St 0x0002
+#define Pass_Thru_0_Interrupt_St 0x0001
+
+#define AI_Status_2_Register 5
+
+#define Interrupt_B_Ack_Register 3
+enum Interrupt_B_Ack_Bits {
+ G1_Gate_Error_Confirm = _bit1,
+ G1_TC_Error_Confirm = _bit2,
+ AO_BC_TC_Trigger_Error_Confirm = _bit3,
+ AO_BC_TC_Error_Confirm = _bit4,
+ AO_UI2_TC_Error_Confrim = _bit5,
+ AO_UI2_TC_Interrupt_Ack = _bit6,
+ AO_UC_TC_Interrupt_Ack = _bit7,
+ AO_BC_TC_Interrupt_Ack = _bit8,
+ AO_START1_Interrupt_Ack = _bit9,
+ AO_UPDATE_Interrupt_Ack = _bit10,
+ AO_START_Interrupt_Ack = _bit11,
+ AO_STOP_Interrupt_Ack = _bit12,
+ AO_Error_Interrupt_Ack = _bit13,
+ G1_TC_Interrupt_Ack = _bit14,
+ G1_Gate_Interrupt_Ack = _bit15
+};
+
+#define AO_Status_1_Register 3
+#define Interrupt_B_St _bit15
+#define AO_FIFO_Full_St _bit14
+#define AO_FIFO_Half_Full_St _bit13
+#define AO_FIFO_Empty_St _bit12
+#define AO_BC_TC_Error_St _bit11
+#define AO_START_St _bit10
+#define AO_Overrun_St _bit9
+#define AO_START1_St _bit8
+#define AO_BC_TC_St _bit7
+#define AO_UC_TC_St _bit6
+#define AO_UPDATE_St _bit5
+#define AO_UI2_TC_St _bit4
+#define G1_TC_St _bit3
+#define G1_Gate_Interrupt_St _bit2
+#define AO_FIFO_Request_St _bit1
+#define Pass_Thru_1_Interrupt_St _bit0
+
+#define AI_Command_2_Register 4
+#define AI_End_On_SC_TC _bit15
+#define AI_End_On_End_Of_Scan _bit14
+#define AI_START1_Disable _bit11
+#define AI_SC_Save_Trace _bit10
+#define AI_SI_Switch_Load_On_SC_TC _bit9
+#define AI_SI_Switch_Load_On_STOP _bit8
+#define AI_SI_Switch_Load_On_TC _bit7
+#define AI_SC_Switch_Load_On_TC _bit4
+#define AI_STOP_Pulse _bit3
+#define AI_START_Pulse _bit2
+#define AI_START2_Pulse _bit1
+#define AI_START1_Pulse _bit0
+
+#define AO_Command_2_Register 5
+#define AO_End_On_BC_TC(x) (((x) & 0x3) << 14)
+#define AO_Start_Stop_Gate_Enable _bit13
+#define AO_UC_Save_Trace _bit12
+#define AO_BC_Gate_Enable _bit11
+#define AO_BC_Save_Trace _bit10
+#define AO_UI_Switch_Load_On_BC_TC _bit9
+#define AO_UI_Switch_Load_On_Stop _bit8
+#define AO_UI_Switch_Load_On_TC _bit7
+#define AO_UC_Switch_Load_On_BC_TC _bit6
+#define AO_UC_Switch_Load_On_TC _bit5
+#define AO_BC_Switch_Load_On_TC _bit4
+#define AO_Mute_B _bit3
+#define AO_Mute_A _bit2
+#define AO_UPDATE2_Pulse _bit1
+#define AO_START1_Pulse _bit0
+
+#define AO_Status_2_Register 6
+
+#define DIO_Parallel_Input_Register 7
+
+#define AI_Command_1_Register 8
+#define AI_Analog_Trigger_Reset _bit14
+#define AI_Disarm _bit13
+#define AI_SI2_Arm _bit12
+#define AI_SI2_Load _bit11
+#define AI_SI_Arm _bit10
+#define AI_SI_Load _bit9
+#define AI_DIV_Arm _bit8
+#define AI_DIV_Load _bit7
+#define AI_SC_Arm _bit6
+#define AI_SC_Load _bit5
+#define AI_SCAN_IN_PROG_Pulse _bit4
+#define AI_EXTMUX_CLK_Pulse _bit3
+#define AI_LOCALMUX_CLK_Pulse _bit2
+#define AI_SC_TC_Pulse _bit1
+#define AI_CONVERT_Pulse _bit0
+
+#define AO_Command_1_Register 9
+#define AO_Analog_Trigger_Reset _bit15
+#define AO_START_Pulse _bit14
+#define AO_Disarm _bit13
+#define AO_UI2_Arm_Disarm _bit12
+#define AO_UI2_Load _bit11
+#define AO_UI_Arm _bit10
+#define AO_UI_Load _bit9
+#define AO_UC_Arm _bit8
+#define AO_UC_Load _bit7
+#define AO_BC_Arm _bit6
+#define AO_BC_Load _bit5
+#define AO_DAC1_Update_Mode _bit4
+#define AO_LDAC1_Source_Select _bit3
+#define AO_DAC0_Update_Mode _bit2
+#define AO_LDAC0_Source_Select _bit1
+#define AO_UPDATE_Pulse _bit0
+
+#define DIO_Output_Register 10
+#define DIO_Parallel_Data_Out(a) ((a)&0xff)
+#define DIO_Parallel_Data_Mask 0xff
+#define DIO_SDOUT _bit0
+#define DIO_SDIN _bit4
+#define DIO_Serial_Data_Out(a) (((a)&0xff)<<8)
+#define DIO_Serial_Data_Mask 0xff00
+
+#define DIO_Control_Register 11
+#define DIO_Software_Serial_Control _bit11
+#define DIO_HW_Serial_Timebase _bit10
+#define DIO_HW_Serial_Enable _bit9
+#define DIO_HW_Serial_Start _bit8
+#define DIO_Pins_Dir(a) ((a)&0xff)
+#define DIO_Pins_Dir_Mask 0xff
+
+#define AI_Mode_1_Register 12
+#define AI_CONVERT_Source_Select(a) (((a) & 0x1f) << 11)
+#define AI_SI_Source_select(a) (((a) & 0x1f) << 6)
+#define AI_CONVERT_Source_Polarity _bit5
+#define AI_SI_Source_Polarity _bit4
+#define AI_Start_Stop _bit3
+#define AI_Mode_1_Reserved _bit2
+#define AI_Continuous _bit1
+#define AI_Trigger_Once _bit0
+
+#define AI_Mode_2_Register 13
+#define AI_SC_Gate_Enable _bit15
+#define AI_Start_Stop_Gate_Enable _bit14
+#define AI_Pre_Trigger _bit13
+#define AI_External_MUX_Present _bit12
+#define AI_SI2_Initial_Load_Source _bit9
+#define AI_SI2_Reload_Mode _bit8
+#define AI_SI_Initial_Load_Source _bit7
+#define AI_SI_Reload_Mode(a) (((a) & 0x7)<<4)
+#define AI_SI_Write_Switch _bit3
+#define AI_SC_Initial_Load_Source _bit2
+#define AI_SC_Reload_Mode _bit1
+#define AI_SC_Write_Switch _bit0
+
+#define AI_SI_Load_A_Registers 14
+#define AI_SI_Load_B_Registers 16
+#define AI_SC_Load_A_Registers 18
+#define AI_SC_Load_B_Registers 20
+#define AI_SI_Save_Registers 64
+#define AI_SC_Save_Registers 66
+
+#define AI_SI2_Load_A_Register 23
+#define AI_SI2_Load_B_Register 25
+
+#define Joint_Status_1_Register 27
+#define DIO_Serial_IO_In_Progress_St _bit12
+
+#define DIO_Serial_Input_Register 28
+#define Joint_Status_2_Register 29
+enum Joint_Status_2_Bits {
+ AO_TMRDACWRs_In_Progress_St = 0x20,
+};
+
+#define AO_Mode_1_Register 38
+#define AO_UPDATE_Source_Select(x) (((x)&0x1f)<<11)
+#define AO_UI_Source_Select(x) (((x)&0x1f)<<6)
+#define AO_Multiple_Channels _bit5
+#define AO_UPDATE_Source_Polarity _bit4
+#define AO_UI_Source_Polarity _bit3
+#define AO_UC_Switch_Load_Every_TC _bit2
+#define AO_Continuous _bit1
+#define AO_Trigger_Once _bit0
+
+#define AO_Mode_2_Register 39
+#define AO_FIFO_Mode_Mask ( 0x3 << 14 )
+enum AO_FIFO_Mode_Bits {
+ AO_FIFO_Mode_HF_to_F = (3 << 14),
+ AO_FIFO_Mode_F = (2 << 14),
+ AO_FIFO_Mode_HF = (1 << 14),
+ AO_FIFO_Mode_E = (0 << 14),
+};
+#define AO_FIFO_Retransmit_Enable _bit13
+#define AO_START1_Disable _bit12
+#define AO_UC_Initial_Load_Source _bit11
+#define AO_UC_Write_Switch _bit10
+#define AO_UI2_Initial_Load_Source _bit9
+#define AO_UI2_Reload_Mode _bit8
+#define AO_UI_Initial_Load_Source _bit7
+#define AO_UI_Reload_Mode(x) (((x) & 0x7) << 4)
+#define AO_UI_Write_Switch _bit3
+#define AO_BC_Initial_Load_Source _bit2
+#define AO_BC_Reload_Mode _bit1
+#define AO_BC_Write_Switch _bit0
+
+#define AO_UI_Load_A_Register 40
+#define AO_UI_Load_A_Register_High 40
+#define AO_UI_Load_A_Register_Low 41
+#define AO_UI_Load_B_Register 42
+#define AO_UI_Save_Registers 16
+#define AO_BC_Load_A_Register 44
+#define AO_BC_Load_A_Register_High 44
+#define AO_BC_Load_A_Register_Low 45
+#define AO_BC_Load_B_Register 46
+#define AO_BC_Load_B_Register_High 46
+#define AO_BC_Load_B_Register_Low 47
+#define AO_BC_Save_Registers 18
+#define AO_UC_Load_A_Register 48
+#define AO_UC_Load_A_Register_High 48
+#define AO_UC_Load_A_Register_Low 49
+#define AO_UC_Load_B_Register 50
+#define AO_UC_Save_Registers 20
+
+#define Clock_and_FOUT_Register 56
+enum Clock_and_FOUT_bits {
+ FOUT_Enable = _bit15,
+ FOUT_Timebase_Select = _bit14,
+ DIO_Serial_Out_Divide_By_2 = _bit13,
+ Slow_Internal_Time_Divide_By_2 = _bit12,
+ Slow_Internal_Timebase = _bit11,
+ G_Source_Divide_By_2 = _bit10,
+ Clock_To_Board_Divide_By_2 = _bit9,
+ Clock_To_Board = _bit8,
+ AI_Output_Divide_By_2 = _bit7,
+ AI_Source_Divide_By_2 = _bit6,
+ AO_Output_Divide_By_2 = _bit5,
+ AO_Source_Divide_By_2 = _bit4,
+ FOUT_Divider_mask = 0xf
+};
+static inline unsigned FOUT_Divider(unsigned divider)
+{
+ return (divider & FOUT_Divider_mask);
+}
+
+#define IO_Bidirection_Pin_Register 57
+#define RTSI_Trig_Direction_Register 58
+enum RTSI_Trig_Direction_Bits {
+ Drive_RTSI_Clock_Bit = 0x1,
+ Use_RTSI_Clock_Bit = 0x2,
+};
+static inline unsigned RTSI_Output_Bit(unsigned channel, int is_mseries)
+{
+ unsigned max_channel;
+ unsigned base_bit_shift;
+ if (is_mseries) {
+ base_bit_shift = 8;
+ max_channel = 7;
+ } else {
+ base_bit_shift = 9;
+ max_channel = 6;
+ }
+ if (channel > max_channel) {
+ rt_printk("%s: bug, invalid RTSI_channel=%i\n", __FUNCTION__,
+ channel);
+ return 0;
+ }
+ return 1 << (base_bit_shift + channel);
+}
+
+#define Interrupt_Control_Register 59
+#define Interrupt_B_Enable _bit15
+#define Interrupt_B_Output_Select(x) ((x)<<12)
+#define Interrupt_A_Enable _bit11
+#define Interrupt_A_Output_Select(x) ((x)<<8)
+#define Pass_Thru_0_Interrupt_Polarity _bit3
+#define Pass_Thru_1_Interrupt_Polarity _bit2
+#define Interrupt_Output_On_3_Pins _bit1
+#define Interrupt_Output_Polarity _bit0
+
+#define AI_Output_Control_Register 60
+#define AI_START_Output_Select _bit10
+#define AI_SCAN_IN_PROG_Output_Select(x) (((x) & 0x3) << 8)
+#define AI_EXTMUX_CLK_Output_Select(x) (((x) & 0x3) << 6)
+#define AI_LOCALMUX_CLK_Output_Select(x) ((x)<<4)
+#define AI_SC_TC_Output_Select(x) ((x)<<2)
+enum ai_convert_output_selection {
+ AI_CONVERT_Output_High_Z = 0,
+ AI_CONVERT_Output_Ground = 1,
+ AI_CONVERT_Output_Enable_Low = 2,
+ AI_CONVERT_Output_Enable_High = 3
+};
+static unsigned AI_CONVERT_Output_Select(enum ai_convert_output_selection
+ selection)
+{
+ return selection & 0x3;
+}
+
+#define AI_START_STOP_Select_Register 62
+#define AI_START_Polarity _bit15
+#define AI_STOP_Polarity _bit14
+#define AI_STOP_Sync _bit13
+#define AI_STOP_Edge _bit12
+#define AI_STOP_Select(a) (((a) & 0x1f)<<7)
+#define AI_START_Sync _bit6
+#define AI_START_Edge _bit5
+#define AI_START_Select(a) ((a) & 0x1f)
+
+#define AI_Trigger_Select_Register 63
+#define AI_START1_Polarity _bit15
+#define AI_START2_Polarity _bit14
+#define AI_START2_Sync _bit13
+#define AI_START2_Edge _bit12
+#define AI_START2_Select(a) (((a) & 0x1f) << 7)
+#define AI_START1_Sync _bit6
+#define AI_START1_Edge _bit5
+#define AI_START1_Select(a) ((a) & 0x1f)
+
+#define AI_DIV_Load_A_Register 64
+
+#define AO_Start_Select_Register 66
+#define AO_UI2_Software_Gate _bit15
+#define AO_UI2_External_Gate_Polarity _bit14
+#define AO_START_Polarity _bit13
+#define AO_AOFREQ_Enable _bit12
+#define AO_UI2_External_Gate_Select(a) (((a) & 0x1f) << 7)
+#define AO_START_Sync _bit6
+#define AO_START_Edge _bit5
+#define AO_START_Select(a) ((a) & 0x1f)
+
+#define AO_Trigger_Select_Register 67
+#define AO_UI2_External_Gate_Enable _bit15
+#define AO_Delayed_START1 _bit14
+#define AO_START1_Polarity _bit13
+#define AO_UI2_Source_Polarity _bit12
+#define AO_UI2_Source_Select(x) (((x)&0x1f)<<7)
+#define AO_START1_Sync _bit6
+#define AO_START1_Edge _bit5
+#define AO_START1_Select(x) (((x)&0x1f)<<0)
+
+#define AO_Mode_3_Register 70
+#define AO_UI2_Switch_Load_Next_TC _bit13
+#define AO_UC_Switch_Load_Every_BC_TC _bit12
+#define AO_Trigger_Length _bit11
+#define AO_Stop_On_Overrun_Error _bit5
+#define AO_Stop_On_BC_TC_Trigger_Error _bit4
+#define AO_Stop_On_BC_TC_Error _bit3
+#define AO_Not_An_UPDATE _bit2
+#define AO_Software_Gate _bit1
+#define AO_Last_Gate_Disable _bit0 /* M Series only */
+
+#define Joint_Reset_Register 72
+#define Software_Reset _bit11
+#define AO_Configuration_End _bit9
+#define AI_Configuration_End _bit8
+#define AO_Configuration_Start _bit5
+#define AI_Configuration_Start _bit4
+#define G1_Reset _bit3
+#define G0_Reset _bit2
+#define AO_Reset _bit1
+#define AI_Reset _bit0
+
+#define Interrupt_A_Enable_Register 73
+#define Pass_Thru_0_Interrupt_Enable _bit9
+#define G0_Gate_Interrupt_Enable _bit8
+#define AI_FIFO_Interrupt_Enable _bit7
+#define G0_TC_Interrupt_Enable _bit6
+#define AI_Error_Interrupt_Enable _bit5
+#define AI_STOP_Interrupt_Enable _bit4
+#define AI_START_Interrupt_Enable _bit3
+#define AI_START2_Interrupt_Enable _bit2
+#define AI_START1_Interrupt_Enable _bit1
+#define AI_SC_TC_Interrupt_Enable _bit0
+
+#define Interrupt_B_Enable_Register 75
+#define Pass_Thru_1_Interrupt_Enable _bit11
+#define G1_Gate_Interrupt_Enable _bit10
+#define G1_TC_Interrupt_Enable _bit9
+#define AO_FIFO_Interrupt_Enable _bit8
+#define AO_UI2_TC_Interrupt_Enable _bit7
+#define AO_UC_TC_Interrupt_Enable _bit6
+#define AO_Error_Interrupt_Enable _bit5
+#define AO_STOP_Interrupt_Enable _bit4
+#define AO_START_Interrupt_Enable _bit3
+#define AO_UPDATE_Interrupt_Enable _bit2
+#define AO_START1_Interrupt_Enable _bit1
+#define AO_BC_TC_Interrupt_Enable _bit0
+
+#define Second_IRQ_A_Enable_Register 74
+enum Second_IRQ_A_Enable_Bits {
+ AI_SC_TC_Second_Irq_Enable = _bit0,
+ AI_START1_Second_Irq_Enable = _bit1,
+ AI_START2_Second_Irq_Enable = _bit2,
+ AI_START_Second_Irq_Enable = _bit3,
+ AI_STOP_Second_Irq_Enable = _bit4,
+ AI_Error_Second_Irq_Enable = _bit5,
+ G0_TC_Second_Irq_Enable = _bit6,
+ AI_FIFO_Second_Irq_Enable = _bit7,
+ G0_Gate_Second_Irq_Enable = _bit8,
+ Pass_Thru_0_Second_Irq_Enable = _bit9
+};
+
+#define Second_IRQ_B_Enable_Register 76
+enum Second_IRQ_B_Enable_Bits {
+ AO_BC_TC_Second_Irq_Enable = _bit0,
+ AO_START1_Second_Irq_Enable = _bit1,
+ AO_UPDATE_Second_Irq_Enable = _bit2,
+ AO_START_Second_Irq_Enable = _bit3,
+ AO_STOP_Second_Irq_Enable = _bit4,
+ AO_Error_Second_Irq_Enable = _bit5,
+ AO_UC_TC_Second_Irq_Enable = _bit6,
+ AO_UI2_TC_Second_Irq_Enable = _bit7,
+ AO_FIFO_Second_Irq_Enable = _bit8,
+ G1_TC_Second_Irq_Enable = _bit9,
+ G1_Gate_Second_Irq_Enable = _bit10,
+ Pass_Thru_1_Second_Irq_Enable = _bit11
+};
+
+#define AI_Personal_Register 77
+#define AI_SHIFTIN_Pulse_Width _bit15
+#define AI_EOC_Polarity _bit14
+#define AI_SOC_Polarity _bit13
+#define AI_SHIFTIN_Polarity _bit12
+#define AI_CONVERT_Pulse_Timebase _bit11
+#define AI_CONVERT_Pulse_Width _bit10
+#define AI_CONVERT_Original_Pulse _bit9
+#define AI_FIFO_Flags_Polarity _bit8
+#define AI_Overrun_Mode _bit7
+#define AI_EXTMUX_CLK_Pulse_Width _bit6
+#define AI_LOCALMUX_CLK_Pulse_Width _bit5
+#define AI_AIFREQ_Polarity _bit4
+
+#define AO_Personal_Register 78
+enum AO_Personal_Bits {
+ AO_Interval_Buffer_Mode = 1 << 3,
+ AO_BC_Source_Select = 1 << 4,
+ AO_UPDATE_Pulse_Width = 1 << 5,
+ AO_UPDATE_Pulse_Timebase = 1 << 6,
+ AO_UPDATE_Original_Pulse = 1 << 7,
+ AO_DMA_PIO_Control = 1 << 8, /* M Series: reserved */
+ AO_AOFREQ_Polarity = 1 << 9, /* M Series: reserved */
+ AO_FIFO_Enable = 1 << 10,
+ AO_FIFO_Flags_Polarity = 1 << 11, /* M Series: reserved */
+ AO_TMRDACWR_Pulse_Width = 1 << 12,
+ AO_Fast_CPU = 1 << 13, /* M Series: reserved */
+ AO_Number_Of_DAC_Packages = 1 << 14, // 1 for "single" mode, 0 for "dual"
+ AO_Multiple_DACS_Per_Package = 1 << 15 // m-series only
+};
+#define RTSI_Trig_A_Output_Register 79
+#define RTSI_Trig_B_Output_Register 80
+enum RTSI_Trig_B_Output_Bits {
+ RTSI_Sub_Selection_1_Bit = 0x8000 // not for m-series
+};
+static inline unsigned RTSI_Trig_Output_Bits(unsigned rtsi_channel,
+ unsigned source)
+{
+ return (source & 0xf) << ((rtsi_channel % 4) * 4);
+};
+static inline unsigned RTSI_Trig_Output_Mask(unsigned rtsi_channel)
+{
+ return 0xf << ((rtsi_channel % 4) * 4);
+};
+
+// inverse to RTSI_Trig_Output_Bits()
+static inline unsigned RTSI_Trig_Output_Source(unsigned rtsi_channel,
+ unsigned bits)
+{
+ return (bits >> ((rtsi_channel % 4) * 4)) & 0xf;
+};
+
+#define RTSI_Board_Register 81
+#define Write_Strobe_0_Register 82
+#define Write_Strobe_1_Register 83
+#define Write_Strobe_2_Register 84
+#define Write_Strobe_3_Register 85
+
+#define AO_Output_Control_Register 86
+#define AO_External_Gate_Enable _bit15
+#define AO_External_Gate_Select(x) (((x)&0x1f)<<10)
+#define AO_Number_Of_Channels(x) (((x)&0xf)<<6)
+#define AO_UPDATE2_Output_Select(x) (((x)&0x3)<<4)
+#define AO_External_Gate_Polarity _bit3
+#define AO_UPDATE2_Output_Toggle _bit2
+enum ao_update_output_selection {
+ AO_Update_Output_High_Z = 0,
+ AO_Update_Output_Ground = 1,
+ AO_Update_Output_Enable_Low = 2,
+ AO_Update_Output_Enable_High = 3
+};
+static unsigned AO_UPDATE_Output_Select(enum ao_update_output_selection
+ selection)
+{
+ return selection & 0x3;
+}
+
+#define AI_Mode_3_Register 87
+#define AI_Trigger_Length _bit15
+#define AI_Delay_START _bit14
+#define AI_Software_Gate _bit13
+#define AI_SI_Special_Trigger_Delay _bit12
+#define AI_SI2_Source_Select _bit11
+#define AI_Delayed_START2 _bit10
+#define AI_Delayed_START1 _bit9
+#define AI_External_Gate_Mode _bit8
+#define AI_FIFO_Mode_HF_to_E (3<<6)
+#define AI_FIFO_Mode_F (2<<6)
+#define AI_FIFO_Mode_HF (1<<6)
+#define AI_FIFO_Mode_NE (0<<6)
+#define AI_External_Gate_Polarity _bit5
+#define AI_External_Gate_Select(a) ((a) & 0x1f)
+
+#define G_Autoincrement_Register(a) (68+(a))
+#define G_Command_Register(a) (6+(a))
+#define G_HW_Save_Register(a) (8+(a)*2)
+#define G_HW_Save_Register_High(a) (8+(a)*2)
+#define G_HW_Save_Register_Low(a) (9+(a)*2)
+#define G_Input_Select_Register(a) (36+(a))
+#define G_Load_A_Register(a) (28+(a)*4)
+#define G_Load_A_Register_High(a) (28+(a)*4)
+#define G_Load_A_Register_Low(a) (29+(a)*4)
+#define G_Load_B_Register(a) (30+(a)*4)
+#define G_Load_B_Register_High(a) (30+(a)*4)
+#define G_Load_B_Register_Low(a) (31+(a)*4)
+#define G_Mode_Register(a) (26+(a))
+#define G_Save_Register(a) (12+(a)*2)
+#define G_Save_Register_High(a) (12+(a)*2)
+#define G_Save_Register_Low(a) (13+(a)*2)
+#define G_Status_Register 4
+#define Analog_Trigger_Etc_Register 61
+
+/* command register */
+#define G_Disarm_Copy _bit15 /* strobe */
+#define G_Save_Trace_Copy _bit14
+#define G_Arm_Copy _bit13 /* strobe */
+#define G_Bank_Switch_Start _bit10 /* strobe */
+#define G_Little_Big_Endian _bit9
+#define G_Synchronized_Gate _bit8
+#define G_Write_Switch _bit7
+#define G_Up_Down(a) (((a)&0x03)<<5)
+#define G_Disarm _bit4 /* strobe */
+#define G_Analog_Trigger_Reset _bit3 /* strobe */
+#define G_Save_Trace _bit1
+#define G_Arm _bit0 /* strobe */
+
+/*channel agnostic names for the command register #defines */
+#define G_Bank_Switch_Enable _bit12
+#define G_Bank_Switch_Mode _bit11
+#define G_Load _bit2 /* strobe */
+
+/* input select register */
+#define G_Gate_Select(a) (((a)&0x1f)<<7)
+#define G_Source_Select(a) (((a)&0x1f)<<2)
+#define G_Write_Acknowledges_Irq _bit1
+#define G_Read_Acknowledges_Irq _bit0
+
+/* same input select register, but with channel agnostic names */
+#define G_Source_Polarity _bit15
+#define G_Output_Polarity _bit14
+#define G_OR_Gate _bit13
+#define G_Gate_Select_Load_Source _bit12
+
+/* mode register */
+#define G_Loading_On_TC _bit12
+#define G_Output_Mode(a) (((a)&0x03)<<8)
+#define G_Trigger_Mode_For_Edge_Gate(a) (((a)&0x03)<<3)
+#define G_Gating_Mode(a) (((a)&0x03)<<0)
+
+/* same input mode register, but with channel agnostic names */
+#define G_Load_Source_Select _bit7
+#define G_Reload_Source_Switching _bit15
+#define G_Loading_On_Gate _bit14
+#define G_Gate_Polarity _bit13
+
+#define G_Counting_Once(a) (((a)&0x03)<<10)
+#define G_Stop_Mode(a) (((a)&0x03)<<5)
+#define G_Gate_On_Both_Edges _bit2
+
+/* G_Status_Register */
+#define G1_Gate_Error_St _bit15
+#define G0_Gate_Error_St _bit14
+#define G1_TC_Error_St _bit13
+#define G0_TC_Error_St _bit12
+#define G1_No_Load_Between_Gates_St _bit11
+#define G0_No_Load_Between_Gates_St _bit10
+#define G1_Armed_St _bit9
+#define G0_Armed_St _bit8
+#define G1_Stale_Data_St _bit7
+#define G0_Stale_Data_St _bit6
+#define G1_Next_Load_Source_St _bit5
+#define G0_Next_Load_Source_St _bit4
+#define G1_Counting_St _bit3
+#define G0_Counting_St _bit2
+#define G1_Save_St _bit1
+#define G0_Save_St _bit0
+
+/* general purpose counter timer */
+#define G_Autoincrement(a) ((a)<<0)
+
+/*Analog_Trigger_Etc_Register*/
+#define Analog_Trigger_Mode(x) ((x) & 0x7)
+#define Analog_Trigger_Enable _bit3
+#define Analog_Trigger_Drive _bit4
+#define GPFO_1_Output_Select _bit7
+#define GPFO_0_Output_Select(a) ((a)<<11)
+#define GPFO_0_Output_Enable _bit14
+#define GPFO_1_Output_Enable _bit15
+
+/* Additional windowed registers unique to E series */
+
+/* 16 bit registers shadowed from DAQ-STC */
+#define Window_Address 0x00
+#define Window_Data 0x02
+
+#define Configuration_Memory_Clear 82
+#define ADC_FIFO_Clear 83
+#define DAC_FIFO_Clear 84
+
+/* i/o port offsets */
+
+/* 8 bit registers */
+#define XXX_Status 0x01
+enum XXX_Status_Bits {
+ PROMOUT = 0x1,
+ AI_FIFO_LOWER_NOT_EMPTY = 0x8,
+};
+#define Serial_Command 0x0d
+#define Misc_Command 0x0f
+#define Port_A 0x19
+#define Port_B 0x1b
+#define Port_C 0x1d
+#define Configuration 0x1f
+#define Strobes 0x01
+#define Channel_A_Mode 0x03
+#define Channel_B_Mode 0x05
+#define Channel_C_Mode 0x07
+#define AI_AO_Select 0x09
+enum AI_AO_Select_Bits {
+ AI_DMA_Select_Shift = 0,
+ AI_DMA_Select_Mask = 0xf,
+ AO_DMA_Select_Shift = 4,
+ AO_DMA_Select_Mask = 0xf << AO_DMA_Select_Shift
+};
+#define G0_G1_Select 0x0b
+static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel)
+{
+ if (channel < 4)
+ return 1 << channel;
+ if (channel == 4)
+ return 0x3;
+ if (channel == 5)
+ return 0x5;
+ BUG();
+ return 0;
+}
+static inline unsigned GPCT_DMA_Select_Bits(unsigned gpct_index,
+ unsigned mite_channel)
+{
+ BUG_ON(gpct_index > 1);
+ return ni_stc_dma_channel_select_bitfield(mite_channel) << (4 *
+ gpct_index);
+}
+static inline unsigned GPCT_DMA_Select_Mask(unsigned gpct_index)
+{
+ BUG_ON(gpct_index > 1);
+ return 0xf << (4 * gpct_index);
+}
+
+/* 16 bit registers */
+
+#define Configuration_Memory_Low 0x10
+enum Configuration_Memory_Low_Bits {
+ AI_DITHER = 0x200,
+ AI_LAST_CHANNEL = 0x8000,
+};
+#define Configuration_Memory_High 0x12
+enum Configuration_Memory_High_Bits {
+ AI_AC_COUPLE = 0x800,
+ AI_DIFFERENTIAL = 0x1000,
+ AI_COMMON = 0x2000,
+ AI_GROUND = 0x3000,
+};
+static inline unsigned int AI_CONFIG_CHANNEL(unsigned int channel)
+{
+ return (channel & 0x3f);
+}
+
+#define ADC_FIFO_Data_Register 0x1c
+
+#define AO_Configuration 0x16
+#define AO_Bipolar _bit0
+#define AO_Deglitch _bit1
+#define AO_Ext_Ref _bit2
+#define AO_Ground_Ref _bit3
+#define AO_Channel(x) ((x) << 8)
+
+#define DAC_FIFO_Data 0x1e
+#define DAC0_Direct_Data 0x18
+#define DAC1_Direct_Data 0x1a
+
+/* 611x registers (these boards differ from the e-series) */
+
+#define Magic_611x 0x19 /* w8 (new) */
+#define Calibration_Channel_Select_611x 0x1a /* w16 (new) */
+#define ADC_FIFO_Data_611x 0x1c /* r32 (incompatible) */
+#define AI_FIFO_Offset_Load_611x 0x05 /* r8 (new) */
+#define DAC_FIFO_Data_611x 0x14 /* w32 (incompatible) */
+#define Cal_Gain_Select_611x 0x05 /* w8 (new) */
+
+#define AO_Window_Address_611x 0x18
+#define AO_Window_Data_611x 0x1e
+
+/* 6143 registers */
+#define Magic_6143 0x19 /* w8 */
+#define G0G1_DMA_Select_6143 0x0B /* w8 */
+#define PipelineDelay_6143 0x1f /* w8 */
+#define EOC_Set_6143 0x1D /* w8 */
+#define AIDMA_Select_6143 0x09 /* w8 */
+#define AIFIFO_Data_6143 0x8C /* w32 */
+#define AIFIFO_Flag_6143 0x84 /* w32 */
+#define AIFIFO_Control_6143 0x88 /* w32 */
+#define AIFIFO_Status_6143 0x88 /* w32 */
+#define AIFIFO_DMAThreshold_6143 0x90 /* w32 */
+#define AIFIFO_Words_Available_6143 0x94 /* w32 */
+
+#define Calibration_Channel_6143 0x42 /* w16 */
+#define Calibration_LowTime_6143 0x20 /* w16 */
+#define Calibration_HighTime_6143 0x22 /* w16 */
+#define Relay_Counter_Load_Val__6143 0x4C /* w32 */
+#define Signature_6143 0x50 /* w32 */
+#define Release_Date_6143 0x54 /* w32 */
+#define Release_Oldest_Date_6143 0x58 /* w32 */
+
+#define Calibration_Channel_6143_RelayOn 0x8000 /* Calibration relay switch On */
+#define Calibration_Channel_6143_RelayOff 0x4000 /* Calibration relay switch Off */
+#define Calibration_Channel_Gnd_Gnd 0x00 /* Offset Calibration */
+#define Calibration_Channel_2v5_Gnd 0x02 /* 2.5V Reference */
+#define Calibration_Channel_Pwm_Gnd 0x05 /* +/- 5V Self Cal */
+#define Calibration_Channel_2v5_Pwm 0x0a /* PWM Calibration */
+#define Calibration_Channel_Pwm_Pwm 0x0d /* CMRR */
+#define Calibration_Channel_Gnd_Pwm 0x0e /* PWM Calibration */
+
+/* 671x, 611x registers */
+
+/* 671xi, 611x windowed ao registers */
+enum windowed_regs_67xx_61xx {
+ AO_Immediate_671x = 0x11, /* W 16 */
+ AO_Timed_611x = 0x10, /* W 16 */
+ AO_FIFO_Offset_Load_611x = 0x13, /* W32 */
+ AO_Later_Single_Point_Updates = 0x14, /* W 16 */
+ AO_Waveform_Generation_611x = 0x15, /* W 16 */
+ AO_Misc_611x = 0x16, /* W 16 */
+ AO_Calibration_Channel_Select_67xx = 0x17, /* W 16 */
+ AO_Configuration_2_67xx = 0x18, /* W 16 */
+ CAL_ADC_Command_67xx = 0x19, /* W 8 */
+ CAL_ADC_Status_67xx = 0x1a, /* R 8 */
+ CAL_ADC_Data_67xx = 0x1b, /* R 16 */
+ CAL_ADC_Config_Data_High_Word_67xx = 0x1c, /* RW 16 */
+ CAL_ADC_Config_Data_Low_Word_67xx = 0x1d, /* RW 16 */
+};
+static inline unsigned int DACx_Direct_Data_671x(int channel)
+{
+ return channel;
+}
+enum AO_Misc_611x_Bits {
+ CLEAR_WG = 1,
+};
+enum cs5529_configuration_bits {
+ CSCFG_CAL_CONTROL_MASK = 0x7,
+ CSCFG_SELF_CAL_OFFSET = 0x1,
+ CSCFG_SELF_CAL_GAIN = 0x2,
+ CSCFG_SELF_CAL_OFFSET_GAIN = 0x3,
+ CSCFG_SYSTEM_CAL_OFFSET = 0x5,
+ CSCFG_SYSTEM_CAL_GAIN = 0x6,
+ CSCFG_DONE = 1 << 3,
+ CSCFG_POWER_SAVE_SELECT = 1 << 4,
+ CSCFG_PORT_MODE = 1 << 5,
+ CSCFG_RESET_VALID = 1 << 6,
+ CSCFG_RESET = 1 << 7,
+ CSCFG_UNIPOLAR = 1 << 12,
+ CSCFG_WORD_RATE_2180_CYCLES = 0x0 << 13,
+ CSCFG_WORD_RATE_1092_CYCLES = 0x1 << 13,
+ CSCFG_WORD_RATE_532_CYCLES = 0x2 << 13,
+ CSCFG_WORD_RATE_388_CYCLES = 0x3 << 13,
+ CSCFG_WORD_RATE_324_CYCLES = 0x4 << 13,
+ CSCFG_WORD_RATE_17444_CYCLES = 0x5 << 13,
+ CSCFG_WORD_RATE_8724_CYCLES = 0x6 << 13,
+ CSCFG_WORD_RATE_4364_CYCLES = 0x7 << 13,
+ CSCFG_WORD_RATE_MASK = 0x7 << 13,
+ CSCFG_LOW_POWER = 1 << 16,
+};
+static inline unsigned int CS5529_CONFIG_DOUT(int output)
+{
+ return 1 << (18 + output);
+}
+static inline unsigned int CS5529_CONFIG_AOUT(int output)
+{
+ return 1 << (22 + output);
+}
+enum cs5529_command_bits {
+ CSCMD_POWER_SAVE = 0x1,
+ CSCMD_REGISTER_SELECT_MASK = 0xe,
+ CSCMD_OFFSET_REGISTER = 0x0,
+ CSCMD_GAIN_REGISTER = 0x2,
+ CSCMD_CONFIG_REGISTER = 0x4,
+ CSCMD_READ = 0x10,
+ CSCMD_CONTINUOUS_CONVERSIONS = 0x20,
+ CSCMD_SINGLE_CONVERSION = 0x40,
+ CSCMD_COMMAND = 0x80,
+};
+enum cs5529_status_bits {
+ CSS_ADC_BUSY = 0x1,
+ CSS_OSC_DETECT = 0x2, /* indicates adc error */
+ CSS_OVERRANGE = 0x4,
+};
+#define SerDacLd(x) (0x08<<(x))
+
+/*
+ This is stuff unique to the NI E series drivers,
+ but I thought I'd put it here anyway.
+*/
+
+enum { ai_gain_16 =
+ 0, ai_gain_8, ai_gain_14, ai_gain_4, ai_gain_611x, ai_gain_622x,
+ ai_gain_628x, ai_gain_6143 };
+enum caldac_enum { caldac_none = 0, mb88341, dac8800, dac8043, ad8522,
+ ad8804, ad8842, ad8804_debug
+};
+enum ni_reg_type {
+ ni_reg_normal = 0x0,
+ ni_reg_611x = 0x1,
+ ni_reg_6711 = 0x2,
+ ni_reg_6713 = 0x4,
+ ni_reg_67xx_mask = 0x6,
+ ni_reg_6xxx_mask = 0x7,
+ ni_reg_622x = 0x8,
+ ni_reg_625x = 0x10,
+ ni_reg_628x = 0x18,
+ ni_reg_m_series_mask = 0x18,
+ ni_reg_6143 = 0x20
+};
+
+static const struct comedi_lrange range_ni_E_ao_ext;
+
+enum m_series_register_offsets {
+ M_Offset_CDIO_DMA_Select = 0x7, // write
+ M_Offset_SCXI_Status = 0x7, // read
+ M_Offset_AI_AO_Select = 0x9, // write, same offset as e-series
+ M_Offset_SCXI_Serial_Data_In = 0x9, // read
+ M_Offset_G0_G1_Select = 0xb, // write, same offset as e-series
+ M_Offset_Misc_Command = 0xf,
+ M_Offset_SCXI_Serial_Data_Out = 0x11,
+ M_Offset_SCXI_Control = 0x13,
+ M_Offset_SCXI_Output_Enable = 0x15,
+ M_Offset_AI_FIFO_Data = 0x1c,
+ M_Offset_Static_Digital_Output = 0x24, // write
+ M_Offset_Static_Digital_Input = 0x24, // read
+ M_Offset_DIO_Direction = 0x28,
+ M_Offset_Cal_PWM = 0x40,
+ M_Offset_AI_Config_FIFO_Data = 0x5e,
+ M_Offset_Interrupt_C_Enable = 0x88, // write
+ M_Offset_Interrupt_C_Status = 0x88, // read
+ M_Offset_Analog_Trigger_Control = 0x8c,
+ M_Offset_AO_Serial_Interrupt_Enable = 0xa0,
+ M_Offset_AO_Serial_Interrupt_Ack = 0xa1, // write
+ M_Offset_AO_Serial_Interrupt_Status = 0xa1, // read
+ M_Offset_AO_Calibration = 0xa3,
+ M_Offset_AO_FIFO_Data = 0xa4,
+ M_Offset_PFI_Filter = 0xb0,
+ M_Offset_RTSI_Filter = 0xb4,
+ M_Offset_SCXI_Legacy_Compatibility = 0xbc,
+ M_Offset_Interrupt_A_Ack = 0x104, // write
+ M_Offset_AI_Status_1 = 0x104, // read
+ M_Offset_Interrupt_B_Ack = 0x106, // write
+ M_Offset_AO_Status_1 = 0x106, // read
+ M_Offset_AI_Command_2 = 0x108, // write
+ M_Offset_G01_Status = 0x108, // read
+ M_Offset_AO_Command_2 = 0x10a,
+ M_Offset_AO_Status_2 = 0x10c, // read
+ M_Offset_G0_Command = 0x10c, // write
+ M_Offset_G1_Command = 0x10e, // write
+ M_Offset_G0_HW_Save = 0x110,
+ M_Offset_G0_HW_Save_High = 0x110,
+ M_Offset_AI_Command_1 = 0x110,
+ M_Offset_G0_HW_Save_Low = 0x112,
+ M_Offset_AO_Command_1 = 0x112,
+ M_Offset_G1_HW_Save = 0x114,
+ M_Offset_G1_HW_Save_High = 0x114,
+ M_Offset_G1_HW_Save_Low = 0x116,
+ M_Offset_AI_Mode_1 = 0x118,
+ M_Offset_G0_Save = 0x118,
+ M_Offset_G0_Save_High = 0x118,
+ M_Offset_AI_Mode_2 = 0x11a,
+ M_Offset_G0_Save_Low = 0x11a,
+ M_Offset_AI_SI_Load_A = 0x11c,
+ M_Offset_G1_Save = 0x11c,
+ M_Offset_G1_Save_High = 0x11c,
+ M_Offset_G1_Save_Low = 0x11e,
+ M_Offset_AI_SI_Load_B = 0x120, // write
+ M_Offset_AO_UI_Save = 0x120, // read
+ M_Offset_AI_SC_Load_A = 0x124, // write
+ M_Offset_AO_BC_Save = 0x124, // read
+ M_Offset_AI_SC_Load_B = 0x128, // write
+ M_Offset_AO_UC_Save = 0x128, //read
+ M_Offset_AI_SI2_Load_A = 0x12c,
+ M_Offset_AI_SI2_Load_B = 0x130,
+ M_Offset_G0_Mode = 0x134,
+ M_Offset_G1_Mode = 0x136, // write
+ M_Offset_Joint_Status_1 = 0x136, // read
+ M_Offset_G0_Load_A = 0x138,
+ M_Offset_Joint_Status_2 = 0x13a,
+ M_Offset_G0_Load_B = 0x13c,
+ M_Offset_G1_Load_A = 0x140,
+ M_Offset_G1_Load_B = 0x144,
+ M_Offset_G0_Input_Select = 0x148,
+ M_Offset_G1_Input_Select = 0x14a,
+ M_Offset_AO_Mode_1 = 0x14c,
+ M_Offset_AO_Mode_2 = 0x14e,
+ M_Offset_AO_UI_Load_A = 0x150,
+ M_Offset_AO_UI_Load_B = 0x154,
+ M_Offset_AO_BC_Load_A = 0x158,
+ M_Offset_AO_BC_Load_B = 0x15c,
+ M_Offset_AO_UC_Load_A = 0x160,
+ M_Offset_AO_UC_Load_B = 0x164,
+ M_Offset_Clock_and_FOUT = 0x170,
+ M_Offset_IO_Bidirection_Pin = 0x172,
+ M_Offset_RTSI_Trig_Direction = 0x174,
+ M_Offset_Interrupt_Control = 0x176,
+ M_Offset_AI_Output_Control = 0x178,
+ M_Offset_Analog_Trigger_Etc = 0x17a,
+ M_Offset_AI_START_STOP_Select = 0x17c,
+ M_Offset_AI_Trigger_Select = 0x17e,
+ M_Offset_AI_SI_Save = 0x180, // read
+ M_Offset_AI_DIV_Load_A = 0x180, // write
+ M_Offset_AI_SC_Save = 0x184, // read
+ M_Offset_AO_Start_Select = 0x184, // write
+ M_Offset_AO_Trigger_Select = 0x186,
+ M_Offset_AO_Mode_3 = 0x18c,
+ M_Offset_G0_Autoincrement = 0x188,
+ M_Offset_G1_Autoincrement = 0x18a,
+ M_Offset_Joint_Reset = 0x190,
+ M_Offset_Interrupt_A_Enable = 0x192,
+ M_Offset_Interrupt_B_Enable = 0x196,
+ M_Offset_AI_Personal = 0x19a,
+ M_Offset_AO_Personal = 0x19c,
+ M_Offset_RTSI_Trig_A_Output = 0x19e,
+ M_Offset_RTSI_Trig_B_Output = 0x1a0,
+ M_Offset_RTSI_Shared_MUX = 0x1a2,
+ M_Offset_AO_Output_Control = 0x1ac,
+ M_Offset_AI_Mode_3 = 0x1ae,
+ M_Offset_Configuration_Memory_Clear = 0x1a4,
+ M_Offset_AI_FIFO_Clear = 0x1a6,
+ M_Offset_AO_FIFO_Clear = 0x1a8,
+ M_Offset_G0_Counting_Mode = 0x1b0,
+ M_Offset_G1_Counting_Mode = 0x1b2,
+ M_Offset_G0_Second_Gate = 0x1b4,
+ M_Offset_G1_Second_Gate = 0x1b6,
+ M_Offset_G0_DMA_Config = 0x1b8, // write
+ M_Offset_G0_DMA_Status = 0x1b8, // read
+ M_Offset_G1_DMA_Config = 0x1ba, // write
+ M_Offset_G1_DMA_Status = 0x1ba, // read
+ M_Offset_G0_MSeries_ABZ = 0x1c0,
+ M_Offset_G1_MSeries_ABZ = 0x1c2,
+ M_Offset_Clock_and_Fout2 = 0x1c4,
+ M_Offset_PLL_Control = 0x1c6,
+ M_Offset_PLL_Status = 0x1c8,
+ M_Offset_PFI_Output_Select_1 = 0x1d0,
+ M_Offset_PFI_Output_Select_2 = 0x1d2,
+ M_Offset_PFI_Output_Select_3 = 0x1d4,
+ M_Offset_PFI_Output_Select_4 = 0x1d6,
+ M_Offset_PFI_Output_Select_5 = 0x1d8,
+ M_Offset_PFI_Output_Select_6 = 0x1da,
+ M_Offset_PFI_DI = 0x1dc,
+ M_Offset_PFI_DO = 0x1de,
+ M_Offset_AI_Config_FIFO_Bypass = 0x218,
+ M_Offset_SCXI_DIO_Enable = 0x21c,
+ M_Offset_CDI_FIFO_Data = 0x220, // read
+ M_Offset_CDO_FIFO_Data = 0x220, // write
+ M_Offset_CDIO_Status = 0x224, // read
+ M_Offset_CDIO_Command = 0x224, // write
+ M_Offset_CDI_Mode = 0x228,
+ M_Offset_CDO_Mode = 0x22c,
+ M_Offset_CDI_Mask_Enable = 0x230,
+ M_Offset_CDO_Mask_Enable = 0x234,
+};
+static inline int M_Offset_AO_Waveform_Order(int channel)
+{
+ return 0xc2 + 0x4 * channel;
+};
+static inline int M_Offset_AO_Config_Bank(int channel)
+{
+ return 0xc3 + 0x4 * channel;
+};
+static inline int M_Offset_DAC_Direct_Data(int channel)
+{
+ return 0xc0 + 0x4 * channel;
+}
+static inline int M_Offset_Gen_PWM(int channel)
+{
+ return 0x44 + 0x2 * channel;
+}
+static inline int M_Offset_Static_AI_Control(int i)
+{
+ int offset[] = {
+ 0x64,
+ 0x261,
+ 0x262,
+ 0x263,
+ };
+ if (((unsigned)i) >= sizeof(offset) / sizeof(offset[0])) {
+ rt_printk("%s: invalid channel=%i\n", __FUNCTION__, i);
+ return offset[0];
+ }
+ return offset[i];
+};
+static inline int M_Offset_AO_Reference_Attenuation(int channel)
+{
+ int offset[] = {
+ 0x264,
+ 0x265,
+ 0x266,
+ 0x267
+ };
+ if (((unsigned)channel) >= sizeof(offset) / sizeof(offset[0])) {
+ rt_printk("%s: invalid channel=%i\n", __FUNCTION__, channel);
+ return offset[0];
+ }
+ return offset[channel];
+};
+static inline unsigned M_Offset_PFI_Output_Select(unsigned n)
+{
+ if (n < 1 || n > NUM_PFI_OUTPUT_SELECT_REGS) {
+ rt_printk("%s: invalid pfi output select register=%i\n",
+ __FUNCTION__, n);
+ return M_Offset_PFI_Output_Select_1;
+ }
+ return M_Offset_PFI_Output_Select_1 + (n - 1) * 2;
+}
+
+enum MSeries_AI_Config_FIFO_Data_Bits {
+ MSeries_AI_Config_Channel_Type_Mask = 0x7 << 6,
+ MSeries_AI_Config_Channel_Type_Calibration_Bits = 0x0,
+ MSeries_AI_Config_Channel_Type_Differential_Bits = 0x1 << 6,
+ MSeries_AI_Config_Channel_Type_Common_Ref_Bits = 0x2 << 6,
+ MSeries_AI_Config_Channel_Type_Ground_Ref_Bits = 0x3 << 6,
+ MSeries_AI_Config_Channel_Type_Aux_Bits = 0x5 << 6,
+ MSeries_AI_Config_Channel_Type_Ghost_Bits = 0x7 << 6,
+ MSeries_AI_Config_Polarity_Bit = 0x1000, // 0 for 2's complement encoding
+ MSeries_AI_Config_Dither_Bit = 0x2000,
+ MSeries_AI_Config_Last_Channel_Bit = 0x4000,
+};
+static inline unsigned MSeries_AI_Config_Channel_Bits(unsigned channel)
+{
+ return channel & 0xf;
+}
+static inline unsigned MSeries_AI_Config_Bank_Bits(enum ni_reg_type reg_type,
+ unsigned channel)
+{
+ unsigned bits = channel & 0x30;
+ if (reg_type == ni_reg_622x) {
+ if (channel & 0x40)
+ bits |= 0x400;
+ }
+ return bits;
+}
+static inline unsigned MSeries_AI_Config_Gain_Bits(unsigned range)
+{
+ return (range & 0x7) << 9;
+}
+
+enum MSeries_Clock_and_Fout2_Bits {
+ MSeries_PLL_In_Source_Select_RTSI0_Bits = 0xb,
+ MSeries_PLL_In_Source_Select_Star_Trigger_Bits = 0x14,
+ MSeries_PLL_In_Source_Select_RTSI7_Bits = 0x1b,
+ MSeries_PLL_In_Source_Select_PXI_Clock10 = 0x1d,
+ MSeries_PLL_In_Source_Select_Mask = 0x1f,
+ MSeries_Timebase1_Select_Bit = 0x20, // use PLL for timebase 1
+ MSeries_Timebase3_Select_Bit = 0x40, // use PLL for timebase 3
+ /* use 10MHz instead of 20MHz for RTSI clock frequency. Appears
+ to have no effect, at least on pxi-6281, which always uses
+ 20MHz rtsi clock frequency */
+ MSeries_RTSI_10MHz_Bit = 0x80
+};
+static inline unsigned MSeries_PLL_In_Source_Select_RTSI_Bits(unsigned
+ RTSI_channel)
+{
+ if (RTSI_channel > 7) {
+ rt_printk("%s: bug, invalid RTSI_channel=%i\n", __FUNCTION__,
+ RTSI_channel);
+ return 0;
+ }
+ if (RTSI_channel == 7)
+ return MSeries_PLL_In_Source_Select_RTSI7_Bits;
+ else
+ return MSeries_PLL_In_Source_Select_RTSI0_Bits + RTSI_channel;
+}
+
+enum MSeries_PLL_Control_Bits {
+ MSeries_PLL_Enable_Bit = 0x1000,
+ MSeries_PLL_VCO_Mode_200_325MHz_Bits = 0x0,
+ MSeries_PLL_VCO_Mode_175_225MHz_Bits = 0x2000,
+ MSeries_PLL_VCO_Mode_100_225MHz_Bits = 0x4000,
+ MSeries_PLL_VCO_Mode_75_150MHz_Bits = 0x6000,
+};
+static inline unsigned MSeries_PLL_Divisor_Bits(unsigned divisor)
+{
+ static const unsigned max_divisor = 0x10;
+ if (divisor < 1 || divisor > max_divisor) {
+ rt_printk("%s: bug, invalid divisor=%i\n", __FUNCTION__,
+ divisor);
+ return 0;
+ }
+ return (divisor & 0xf) << 8;
+}
+static inline unsigned MSeries_PLL_Multiplier_Bits(unsigned multiplier)
+{
+ static const unsigned max_multiplier = 0x100;
+ if (multiplier < 1 || multiplier > max_multiplier) {
+ rt_printk("%s: bug, invalid multiplier=%i\n", __FUNCTION__,
+ multiplier);
+ return 0;
+ }
+ return multiplier & 0xff;
+}
+
+enum MSeries_PLL_Status {
+ MSeries_PLL_Locked_Bit = 0x1
+};
+
+enum MSeries_AI_Config_FIFO_Bypass_Bits {
+ MSeries_AI_Bypass_Channel_Mask = 0x7,
+ MSeries_AI_Bypass_Bank_Mask = 0x78,
+ MSeries_AI_Bypass_Cal_Sel_Pos_Mask = 0x380,
+ MSeries_AI_Bypass_Cal_Sel_Neg_Mask = 0x1c00,
+ MSeries_AI_Bypass_Mode_Mux_Mask = 0x6000,
+ MSeries_AO_Bypass_AO_Cal_Sel_Mask = 0x38000,
+ MSeries_AI_Bypass_Gain_Mask = 0x1c0000,
+ MSeries_AI_Bypass_Dither_Bit = 0x200000,
+ MSeries_AI_Bypass_Polarity_Bit = 0x400000, // 0 for 2's complement encoding
+ MSeries_AI_Bypass_Config_FIFO_Bit = 0x80000000
+};
+static inline unsigned MSeries_AI_Bypass_Cal_Sel_Pos_Bits(int
+ calibration_source)
+{
+ return (calibration_source << 7) & MSeries_AI_Bypass_Cal_Sel_Pos_Mask;
+}
+static inline unsigned MSeries_AI_Bypass_Cal_Sel_Neg_Bits(int
+ calibration_source)
+{
+ return (calibration_source << 10) & MSeries_AI_Bypass_Cal_Sel_Pos_Mask;
+}
+static inline unsigned MSeries_AI_Bypass_Gain_Bits(int gain)
+{
+ return (gain << 18) & MSeries_AI_Bypass_Gain_Mask;
+}
+
+enum MSeries_AO_Config_Bank_Bits {
+ MSeries_AO_DAC_Offset_Select_Mask = 0x7,
+ MSeries_AO_DAC_Offset_0V_Bits = 0x0,
+ MSeries_AO_DAC_Offset_5V_Bits = 0x1,
+ MSeries_AO_DAC_Reference_Mask = 0x38,
+ MSeries_AO_DAC_Reference_10V_Internal_Bits = 0x0,
+ MSeries_AO_DAC_Reference_5V_Internal_Bits = 0x8,
+ MSeries_AO_Update_Timed_Bit = 0x40,
+ MSeries_AO_Bipolar_Bit = 0x80 // turns on 2's complement encoding
+};
+
+enum MSeries_AO_Reference_Attenuation_Bits {
+ MSeries_Attenuate_x5_Bit = 0x1
+};
+
+static inline unsigned MSeries_Cal_PWM_High_Time_Bits(unsigned count)
+{
+ return (count << 16) & 0xffff0000;
+}
+
+static inline unsigned MSeries_Cal_PWM_Low_Time_Bits(unsigned count)
+{
+ return count & 0xffff;
+}
+
+static inline unsigned MSeries_PFI_Output_Select_Mask(unsigned channel)
+{
+ return 0x1f << (channel % 3) * 5;
+};
+static inline unsigned MSeries_PFI_Output_Select_Bits(unsigned channel,
+ unsigned source)
+{
+ return (source & 0x1f) << ((channel % 3) * 5);
+};
+
+// inverse to MSeries_PFI_Output_Select_Bits
+static inline unsigned MSeries_PFI_Output_Select_Source(unsigned channel,
+ unsigned bits)
+{
+ return (bits >> ((channel % 3) * 5)) & 0x1f;
+};
+
+enum MSeries_Gi_DMA_Config_Bits {
+ Gi_DMA_BankSW_Error_Bit = 0x10,
+ Gi_DMA_Reset_Bit = 0x8,
+ Gi_DMA_Int_Enable_Bit = 0x4,
+ Gi_DMA_Write_Bit = 0x2,
+ Gi_DMA_Enable_Bit = 0x1,
+};
+
+static inline unsigned MSeries_PFI_Filter_Select_Mask(unsigned channel)
+{
+ return 0x3 << (channel * 2);
+}
+static inline unsigned MSeries_PFI_Filter_Select_Bits(unsigned channel,
+ unsigned filter)
+{
+ return (filter << (channel *
+ 2)) & MSeries_PFI_Filter_Select_Mask(channel);
+}
+
+enum CDIO_DMA_Select_Bits {
+ CDI_DMA_Select_Shift = 0,
+ CDI_DMA_Select_Mask = 0xf,
+ CDO_DMA_Select_Shift = 4,
+ CDO_DMA_Select_Mask = 0xf << CDO_DMA_Select_Shift
+};
+
+enum CDIO_Status_Bits {
+ CDO_FIFO_Empty_Bit = 0x1,
+ CDO_FIFO_Full_Bit = 0x2,
+ CDO_FIFO_Request_Bit = 0x4,
+ CDO_Overrun_Bit = 0x8,
+ CDO_Underflow_Bit = 0x10,
+ CDI_FIFO_Empty_Bit = 0x10000,
+ CDI_FIFO_Full_Bit = 0x20000,
+ CDI_FIFO_Request_Bit = 0x40000,
+ CDI_Overrun_Bit = 0x80000,
+ CDI_Overflow_Bit = 0x100000
+};
+
+enum CDIO_Command_Bits {
+ CDO_Disarm_Bit = 0x1,
+ CDO_Arm_Bit = 0x2,
+ CDI_Disarm_Bit = 0x4,
+ CDI_Arm_Bit = 0x8,
+ CDO_Reset_Bit = 0x10,
+ CDI_Reset_Bit = 0x20,
+ CDO_Error_Interrupt_Enable_Set_Bit = 0x40,
+ CDO_Error_Interrupt_Enable_Clear_Bit = 0x80,
+ CDI_Error_Interrupt_Enable_Set_Bit = 0x100,
+ CDI_Error_Interrupt_Enable_Clear_Bit = 0x200,
+ CDO_FIFO_Request_Interrupt_Enable_Set_Bit = 0x400,
+ CDO_FIFO_Request_Interrupt_Enable_Clear_Bit = 0x800,
+ CDI_FIFO_Request_Interrupt_Enable_Set_Bit = 0x1000,
+ CDI_FIFO_Request_Interrupt_Enable_Clear_Bit = 0x2000,
+ CDO_Error_Interrupt_Confirm_Bit = 0x4000,
+ CDI_Error_Interrupt_Confirm_Bit = 0x8000,
+ CDO_Empty_FIFO_Interrupt_Enable_Set_Bit = 0x10000,
+ CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit = 0x20000,
+ CDO_SW_Update_Bit = 0x80000,
+ CDI_SW_Update_Bit = 0x100000
+};
+
+enum CDI_Mode_Bits {
+ CDI_Sample_Source_Select_Mask = 0x3f,
+ CDI_Halt_On_Error_Bit = 0x200,
+ CDI_Polarity_Bit = 0x400, // sample clock on falling edge
+ CDI_FIFO_Mode_Bit = 0x800, // set for half full mode, clear for not empty mode
+ CDI_Data_Lane_Mask = 0x3000, // data lanes specify which dio channels map to byte or word accesses to the dio fifos
+ CDI_Data_Lane_0_15_Bits = 0x0,
+ CDI_Data_Lane_16_31_Bits = 0x1000,
+ CDI_Data_Lane_0_7_Bits = 0x0,
+ CDI_Data_Lane_8_15_Bits = 0x1000,
+ CDI_Data_Lane_16_23_Bits = 0x2000,
+ CDI_Data_Lane_24_31_Bits = 0x3000
+};
+
+enum CDO_Mode_Bits {
+ CDO_Sample_Source_Select_Mask = 0x3f,
+ CDO_Retransmit_Bit = 0x100,
+ CDO_Halt_On_Error_Bit = 0x200,
+ CDO_Polarity_Bit = 0x400, // sample clock on falling edge
+ CDO_FIFO_Mode_Bit = 0x800, // set for half full mode, clear for not full mode
+ CDO_Data_Lane_Mask = 0x3000, // data lanes specify which dio channels map to byte or word accesses to the dio fifos
+ CDO_Data_Lane_0_15_Bits = 0x0,
+ CDO_Data_Lane_16_31_Bits = 0x1000,
+ CDO_Data_Lane_0_7_Bits = 0x0,
+ CDO_Data_Lane_8_15_Bits = 0x1000,
+ CDO_Data_Lane_16_23_Bits = 0x2000,
+ CDO_Data_Lane_24_31_Bits = 0x3000
+};
+
+enum Interrupt_C_Enable_Bits {
+ Interrupt_Group_C_Enable_Bit = 0x1
+};
+
+enum Interrupt_C_Status_Bits {
+ Interrupt_Group_C_Status_Bit = 0x1
+};
+
+#define M_SERIES_EEPROM_SIZE 1024
+
+typedef struct ni_board_struct {
+ int device_id;
+ int isapnp_id;
+ char *name;
+
+ int n_adchan;
+ int adbits;
+
+ int ai_fifo_depth;
+ unsigned int alwaysdither:1;
+ int gainlkup;
+ int ai_speed;
+
+ int n_aochan;
+ int aobits;
+ int ao_fifo_depth;
+ const struct comedi_lrange *ao_range_table;
+ unsigned ao_speed;
+
+ unsigned num_p0_dio_channels;
+
+ int reg_type;
+ unsigned int ao_unipolar:1;
+ unsigned int has_8255:1;
+ unsigned int has_analog_trig:1;
+
+ enum caldac_enum caldac[3];
+} ni_board;
+
+#define n_ni_boards (sizeof(ni_boards)/sizeof(ni_board))
+
+#define boardtype (*(ni_board *)dev->board_ptr)
+
+#define MAX_N_AO_CHAN 8
+#define NUM_GPCT 2
+
+#define NI_PRIVATE_COMMON \
+ uint16_t (*stc_readw)(struct comedi_device *dev, int register); \
+ uint32_t (*stc_readl)(struct comedi_device *dev, int register); \
+ void (*stc_writew)(struct comedi_device *dev, uint16_t value, int register); \
+ void (*stc_writel)(struct comedi_device *dev, uint32_t value, int register); \
+ \
+ unsigned short dio_output; \
+ unsigned short dio_control; \
+ int ao0p,ao1p; \
+ int lastchan; \
+ int last_do; \
+ int rt_irq; \
+ int irqmask; \
+ int aimode; \
+ int ai_continuous; \
+ int blocksize; \
+ int n_left; \
+ unsigned int ai_calib_source; \
+ unsigned int ai_calib_source_enabled; \
+ spinlock_t window_lock; \
+ spinlock_t soft_reg_copy_lock; \
+ spinlock_t mite_channel_lock; \
+ \
+ int changain_state; \
+ unsigned int changain_spec; \
+ \
+ unsigned int caldac_maxdata_list[MAX_N_CALDACS]; \
+ unsigned short ao[MAX_N_AO_CHAN]; \
+ unsigned short caldacs[MAX_N_CALDACS]; \
+ \
+ unsigned short ai_cmd2; \
+ \
+ unsigned short ao_conf[MAX_N_AO_CHAN]; \
+ unsigned short ao_mode1; \
+ unsigned short ao_mode2; \
+ unsigned short ao_mode3; \
+ unsigned short ao_cmd1; \
+ unsigned short ao_cmd2; \
+ unsigned short ao_cmd3; \
+ unsigned short ao_trigger_select; \
+ \
+ struct ni_gpct_device *counter_dev; \
+ unsigned short an_trig_etc_reg; \
+ \
+ unsigned ai_offset[512]; \
+ \
+ unsigned long serial_interval_ns; \
+ unsigned char serial_hw_mode; \
+ unsigned short clock_and_fout; \
+ unsigned short clock_and_fout2; \
+ \
+ unsigned short int_a_enable_reg; \
+ unsigned short int_b_enable_reg; \
+ unsigned short io_bidirection_pin_reg; \
+ unsigned short rtsi_trig_direction_reg; \
+ unsigned short rtsi_trig_a_output_reg; \
+ unsigned short rtsi_trig_b_output_reg; \
+ unsigned short pfi_output_select_reg[NUM_PFI_OUTPUT_SELECT_REGS]; \
+ unsigned short ai_ao_select_reg; \
+ unsigned short g0_g1_select_reg; \
+ unsigned short cdio_dma_select_reg; \
+ \
+ unsigned clock_ns; \
+ unsigned clock_source; \
+ \
+ unsigned short atrig_mode; \
+ unsigned short atrig_high; \
+ unsigned short atrig_low; \
+ \
+ unsigned short pwm_up_count; \
+ unsigned short pwm_down_count; \
+ \
+ short ai_fifo_buffer[0x2000]; \
+ uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE]; \
+ uint32_t serial_number; \
+ \
+ struct mite_struct *mite; \
+ struct mite_channel *ai_mite_chan; \
+ struct mite_channel *ao_mite_chan;\
+ struct mite_channel *cdo_mite_chan;\
+ struct mite_dma_descriptor_ring *ai_mite_ring; \
+ struct mite_dma_descriptor_ring *ao_mite_ring; \
+ struct mite_dma_descriptor_ring *cdo_mite_ring; \
+ struct mite_dma_descriptor_ring *gpct_mite_ring[NUM_GPCT];
+
+#endif /* _COMEDI_NI_STC_H */
diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c
new file mode 100644
index 00000000000..05a95754039
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_tio.c
@@ -0,0 +1,1691 @@
+/*
+ comedi/drivers/ni_tio.c
+ Support for NI general purpose counters
+
+ Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+Driver: ni_tio
+Description: National Instruments general purpose counters
+Devices:
+Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
+ Herman.Bruyninckx@mech.kuleuven.ac.be,
+ Wim.Meeussen@mech.kuleuven.ac.be,
+ Klaas.Gadeyne@mech.kuleuven.ac.be,
+ Frank Mori Hess <fmhess@users.sourceforge.net>
+Updated: Thu Nov 16 09:50:32 EST 2006
+Status: works
+
+This module is not used directly by end-users. Rather, it
+is used by other drivers (for example ni_660x and ni_pcimio)
+to provide support for NI's general purpose counters. It was
+originally based on the counter code from ni_660x.c and
+ni_mio_common.c.
+
+References:
+DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
+DAQ 6601/6602 User Manual (NI 322137B-01)
+340934b.pdf DAQ-STC reference manual
+
+*/
+/*
+TODO:
+ Support use of both banks X and Y
+*/
+
+#include "ni_tio_internal.h"
+
+static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
+ unsigned generic_clock_source);
+static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter);
+
+MODULE_AUTHOR("Comedi <comedi@comedi.org>");
+MODULE_DESCRIPTION("Comedi support for NI general-purpose counters");
+MODULE_LICENSE("GPL");
+
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_Alternate_Sync_Bit(enum
+ ni_gpct_variant variant)
+{
+ switch (variant) {
+ case ni_gpct_variant_e_series:
+ return 0;
+ break;
+ case ni_gpct_variant_m_series:
+ return Gi_M_Series_Alternate_Sync_Bit;
+ break;
+ case ni_gpct_variant_660x:
+ return Gi_660x_Alternate_Sync_Bit;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X2_Bit(enum
+ ni_gpct_variant variant)
+{
+ switch (variant) {
+ case ni_gpct_variant_e_series:
+ return 0;
+ break;
+ case ni_gpct_variant_m_series:
+ return Gi_M_Series_Prescale_X2_Bit;
+ break;
+ case ni_gpct_variant_660x:
+ return Gi_660x_Prescale_X2_Bit;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X8_Bit(enum
+ ni_gpct_variant variant)
+{
+ switch (variant) {
+ case ni_gpct_variant_e_series:
+ return 0;
+ break;
+ case ni_gpct_variant_m_series:
+ return Gi_M_Series_Prescale_X8_Bit;
+ break;
+ case ni_gpct_variant_660x:
+ return Gi_660x_Prescale_X8_Bit;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_HW_Arm_Select_Mask(enum
+ ni_gpct_variant variant)
+{
+ switch (variant) {
+ case ni_gpct_variant_e_series:
+ return 0;
+ break;
+ case ni_gpct_variant_m_series:
+ return Gi_M_Series_HW_Arm_Select_Mask;
+ break;
+ case ni_gpct_variant_660x:
+ return Gi_660x_HW_Arm_Select_Mask;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+/* clock sources for ni_660x boards, get bits with Gi_Source_Select_Bits() */
+enum ni_660x_clock_source {
+ NI_660x_Timebase_1_Clock = 0x0, /* 20MHz */
+ NI_660x_Source_Pin_i_Clock = 0x1,
+ NI_660x_Next_Gate_Clock = 0xa,
+ NI_660x_Timebase_2_Clock = 0x12, /* 100KHz */
+ NI_660x_Next_TC_Clock = 0x13,
+ NI_660x_Timebase_3_Clock = 0x1e, /* 80MHz */
+ NI_660x_Logic_Low_Clock = 0x1f,
+};
+static const unsigned ni_660x_max_rtsi_channel = 6;
+static inline unsigned NI_660x_RTSI_Clock(unsigned n)
+{
+ BUG_ON(n > ni_660x_max_rtsi_channel);
+ return (0xb + n);
+}
+static const unsigned ni_660x_max_source_pin = 7;
+static inline unsigned NI_660x_Source_Pin_Clock(unsigned n)
+{
+ BUG_ON(n > ni_660x_max_source_pin);
+ return (0x2 + n);
+}
+
+/* clock sources for ni e and m series boards, get bits with Gi_Source_Select_Bits() */
+enum ni_m_series_clock_source {
+ NI_M_Series_Timebase_1_Clock = 0x0, /* 20MHz */
+ NI_M_Series_Timebase_2_Clock = 0x12, /* 100KHz */
+ NI_M_Series_Next_TC_Clock = 0x13,
+ NI_M_Series_Next_Gate_Clock = 0x14, /* when Gi_Src_SubSelect = 0 */
+ NI_M_Series_PXI_Star_Trigger_Clock = 0x14, /* when Gi_Src_SubSelect = 1 */
+ NI_M_Series_PXI10_Clock = 0x1d,
+ NI_M_Series_Timebase_3_Clock = 0x1e, /* 80MHz, when Gi_Src_SubSelect = 0 */
+ NI_M_Series_Analog_Trigger_Out_Clock = 0x1e, /* when Gi_Src_SubSelect = 1 */
+ NI_M_Series_Logic_Low_Clock = 0x1f,
+};
+static const unsigned ni_m_series_max_pfi_channel = 15;
+static inline unsigned NI_M_Series_PFI_Clock(unsigned n)
+{
+ BUG_ON(n > ni_m_series_max_pfi_channel);
+ if (n < 10)
+ return 1 + n;
+ else
+ return 0xb + n;
+}
+static const unsigned ni_m_series_max_rtsi_channel = 7;
+static inline unsigned NI_M_Series_RTSI_Clock(unsigned n)
+{
+ BUG_ON(n > ni_m_series_max_rtsi_channel);
+ if (n == 7)
+ return 0x1b;
+ else
+ return 0xb + n;
+}
+
+enum ni_660x_gate_select {
+ NI_660x_Source_Pin_i_Gate_Select = 0x0,
+ NI_660x_Gate_Pin_i_Gate_Select = 0x1,
+ NI_660x_Next_SRC_Gate_Select = 0xa,
+ NI_660x_Next_Out_Gate_Select = 0x14,
+ NI_660x_Logic_Low_Gate_Select = 0x1f,
+};
+static const unsigned ni_660x_max_gate_pin = 7;
+static inline unsigned NI_660x_Gate_Pin_Gate_Select(unsigned n)
+{
+ BUG_ON(n > ni_660x_max_gate_pin);
+ return 0x2 + n;
+}
+static inline unsigned NI_660x_RTSI_Gate_Select(unsigned n)
+{
+ BUG_ON(n > ni_660x_max_rtsi_channel);
+ return 0xb + n;
+}
+
+enum ni_m_series_gate_select {
+ NI_M_Series_Timestamp_Mux_Gate_Select = 0x0,
+ NI_M_Series_AI_START2_Gate_Select = 0x12,
+ NI_M_Series_PXI_Star_Trigger_Gate_Select = 0x13,
+ NI_M_Series_Next_Out_Gate_Select = 0x14,
+ NI_M_Series_AI_START1_Gate_Select = 0x1c,
+ NI_M_Series_Next_SRC_Gate_Select = 0x1d,
+ NI_M_Series_Analog_Trigger_Out_Gate_Select = 0x1e,
+ NI_M_Series_Logic_Low_Gate_Select = 0x1f,
+};
+static inline unsigned NI_M_Series_RTSI_Gate_Select(unsigned n)
+{
+ BUG_ON(n > ni_m_series_max_rtsi_channel);
+ if (n == 7)
+ return 0x1b;
+ return 0xb + n;
+}
+static inline unsigned NI_M_Series_PFI_Gate_Select(unsigned n)
+{
+ BUG_ON(n > ni_m_series_max_pfi_channel);
+ if (n < 10)
+ return 1 + n;
+ return 0xb + n;
+}
+
+static inline unsigned Gi_Source_Select_Bits(unsigned source)
+{
+ return (source << Gi_Source_Select_Shift) & Gi_Source_Select_Mask;
+}
+static inline unsigned Gi_Gate_Select_Bits(unsigned gate_select)
+{
+ return (gate_select << Gi_Gate_Select_Shift) & Gi_Gate_Select_Mask;
+}
+
+enum ni_660x_second_gate_select {
+ NI_660x_Source_Pin_i_Second_Gate_Select = 0x0,
+ NI_660x_Up_Down_Pin_i_Second_Gate_Select = 0x1,
+ NI_660x_Next_SRC_Second_Gate_Select = 0xa,
+ NI_660x_Next_Out_Second_Gate_Select = 0x14,
+ NI_660x_Selected_Gate_Second_Gate_Select = 0x1e,
+ NI_660x_Logic_Low_Second_Gate_Select = 0x1f,
+};
+static const unsigned ni_660x_max_up_down_pin = 7;
+static inline unsigned NI_660x_Up_Down_Pin_Second_Gate_Select(unsigned n)
+{
+ BUG_ON(n > ni_660x_max_up_down_pin);
+ return 0x2 + n;
+}
+static inline unsigned NI_660x_RTSI_Second_Gate_Select(unsigned n)
+{
+ BUG_ON(n > ni_660x_max_rtsi_channel);
+ return 0xb + n;
+}
+
+static const unsigned int counter_status_mask =
+ COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING;
+
+static int __init ni_tio_init_module(void)
+{
+ return 0;
+}
+
+module_init(ni_tio_init_module);
+
+static void __exit ni_tio_cleanup_module(void)
+{
+}
+
+module_exit(ni_tio_cleanup_module);
+
+struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device * dev,
+ void (*write_register) (struct ni_gpct * counter, unsigned bits,
+ enum ni_gpct_register reg),
+ unsigned (*read_register) (struct ni_gpct * counter,
+ enum ni_gpct_register reg), enum ni_gpct_variant variant,
+ unsigned num_counters)
+{
+ unsigned i;
+
+ struct ni_gpct_device *counter_dev =
+ kzalloc(sizeof(struct ni_gpct_device), GFP_KERNEL);
+ if (counter_dev == NULL)
+ return NULL;
+ counter_dev->dev = dev;
+ counter_dev->write_register = write_register;
+ counter_dev->read_register = read_register;
+ counter_dev->variant = variant;
+ spin_lock_init(&counter_dev->regs_lock);
+ BUG_ON(num_counters == 0);
+ counter_dev->counters =
+ kzalloc(sizeof(struct ni_gpct) * num_counters, GFP_KERNEL);
+ if (counter_dev->counters == NULL) {
+ kfree(counter_dev);
+ return NULL;
+ }
+ for (i = 0; i < num_counters; ++i) {
+ counter_dev->counters[i].counter_dev = counter_dev;
+ spin_lock_init(&counter_dev->counters[i].lock);
+ }
+ counter_dev->num_counters = num_counters;
+ return counter_dev;
+}
+
+void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
+{
+ if (counter_dev->counters == NULL)
+ return;
+ kfree(counter_dev->counters);
+ kfree(counter_dev);
+}
+
+static int ni_tio_second_gate_registers_present(const struct ni_gpct_device
+ *counter_dev)
+{
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ return 0;
+ break;
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x:
+ return 1;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter)
+{
+ write_register(counter, Gi_Reset_Bit(counter->counter_index),
+ NITIO_Gxx_Joint_Reset_Reg(counter->counter_index));
+}
+
+void ni_tio_init_counter(struct ni_gpct *counter)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+
+ ni_tio_reset_count_and_disarm(counter);
+ /* initialize counter registers */
+ counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->counter_index)] =
+ 0x0;
+ write_register(counter,
+ counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->
+ counter_index)],
+ NITIO_Gi_Autoincrement_Reg(counter->counter_index));
+ ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index),
+ ~0, Gi_Synchronize_Gate_Bit);
+ ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index), ~0,
+ 0);
+ counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] = 0x0;
+ write_register(counter,
+ counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)],
+ NITIO_Gi_LoadA_Reg(counter->counter_index));
+ counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] = 0x0;
+ write_register(counter,
+ counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)],
+ NITIO_Gi_LoadB_Reg(counter->counter_index));
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Input_Select_Reg(counter->counter_index), ~0, 0);
+ if (ni_tio_counting_mode_registers_present(counter_dev)) {
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Counting_Mode_Reg(counter->counter_index), ~0,
+ 0);
+ }
+ if (ni_tio_second_gate_registers_present(counter_dev)) {
+ counter_dev->regs[NITIO_Gi_Second_Gate_Reg(counter->
+ counter_index)] = 0x0;
+ write_register(counter,
+ counter_dev->regs[NITIO_Gi_Second_Gate_Reg(counter->
+ counter_index)],
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index));
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_DMA_Config_Reg(counter->counter_index), ~0, 0x0);
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index), ~0, 0x0);
+}
+
+static unsigned int ni_tio_counter_status(struct ni_gpct *counter)
+{
+ unsigned int status = 0;
+ const unsigned bits = read_register(counter,
+ NITIO_Gxx_Status_Reg(counter->counter_index));
+ if (bits & Gi_Armed_Bit(counter->counter_index)) {
+ status |= COMEDI_COUNTER_ARMED;
+ if (bits & Gi_Counting_Bit(counter->counter_index))
+ status |= COMEDI_COUNTER_COUNTING;
+ }
+ return status;
+}
+
+static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned counting_mode_reg =
+ NITIO_Gi_Counting_Mode_Reg(counter->counter_index);
+ static const uint64_t min_normal_sync_period_ps = 25000;
+ const uint64_t clock_period_ps = ni_tio_clock_period_ps(counter,
+ ni_tio_generic_clock_src_select(counter));
+
+ if (ni_tio_counting_mode_registers_present(counter_dev) == 0)
+ return;
+
+ switch (ni_tio_get_soft_copy(counter,
+ counting_mode_reg) & Gi_Counting_Mode_Mask) {
+ case Gi_Counting_Mode_QuadratureX1_Bits:
+ case Gi_Counting_Mode_QuadratureX2_Bits:
+ case Gi_Counting_Mode_QuadratureX4_Bits:
+ case Gi_Counting_Mode_Sync_Source_Bits:
+ force_alt_sync = 1;
+ break;
+ default:
+ break;
+ }
+ /* It's not clear what we should do if clock_period is unknown, so we are not
+ using the alt sync bit in that case, but allow the caller to decide by using the
+ force_alt_sync parameter. */
+ if (force_alt_sync ||
+ (clock_period_ps
+ && clock_period_ps < min_normal_sync_period_ps)) {
+ ni_tio_set_bits(counter, counting_mode_reg,
+ Gi_Alternate_Sync_Bit(counter_dev->variant),
+ Gi_Alternate_Sync_Bit(counter_dev->variant));
+ } else {
+ ni_tio_set_bits(counter, counting_mode_reg,
+ Gi_Alternate_Sync_Bit(counter_dev->variant), 0x0);
+ }
+}
+
+static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ unsigned mode_reg_mask;
+ unsigned mode_reg_values;
+ unsigned input_select_bits = 0;
+ /* these bits map directly on to the mode register */
+ static const unsigned mode_reg_direct_mask =
+ NI_GPCT_GATE_ON_BOTH_EDGES_BIT | NI_GPCT_EDGE_GATE_MODE_MASK |
+ NI_GPCT_STOP_MODE_MASK | NI_GPCT_OUTPUT_MODE_MASK |
+ NI_GPCT_HARDWARE_DISARM_MASK | NI_GPCT_LOADING_ON_TC_BIT |
+ NI_GPCT_LOADING_ON_GATE_BIT | NI_GPCT_LOAD_B_SELECT_BIT;
+
+ mode_reg_mask = mode_reg_direct_mask | Gi_Reload_Source_Switching_Bit;
+ mode_reg_values = mode & mode_reg_direct_mask;
+ switch (mode & NI_GPCT_RELOAD_SOURCE_MASK) {
+ case NI_GPCT_RELOAD_SOURCE_FIXED_BITS:
+ break;
+ case NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS:
+ mode_reg_values |= Gi_Reload_Source_Switching_Bit;
+ break;
+ case NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS:
+ input_select_bits |= Gi_Gate_Select_Load_Source_Bit;
+ mode_reg_mask |= Gi_Gating_Mode_Mask;
+ mode_reg_values |= Gi_Level_Gating_Bits;
+ break;
+ default:
+ break;
+ }
+ ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index),
+ mode_reg_mask, mode_reg_values);
+
+ if (ni_tio_counting_mode_registers_present(counter_dev)) {
+ unsigned counting_mode_bits = 0;
+ counting_mode_bits |=
+ (mode >> NI_GPCT_COUNTING_MODE_SHIFT) &
+ Gi_Counting_Mode_Mask;
+ counting_mode_bits |=
+ ((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT) <<
+ Gi_Index_Phase_Bitshift) & Gi_Index_Phase_Mask;
+ if (mode & NI_GPCT_INDEX_ENABLE_BIT) {
+ counting_mode_bits |= Gi_Index_Mode_Bit;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Counting_Mode_Reg(counter->counter_index),
+ Gi_Counting_Mode_Mask | Gi_Index_Phase_Mask |
+ Gi_Index_Mode_Bit, counting_mode_bits);
+ ni_tio_set_sync_mode(counter, 0);
+ }
+
+ ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index),
+ Gi_Up_Down_Mask,
+ (mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT) << Gi_Up_Down_Shift);
+
+ if (mode & NI_GPCT_OR_GATE_BIT) {
+ input_select_bits |= Gi_Or_Gate_Bit;
+ }
+ if (mode & NI_GPCT_INVERT_OUTPUT_BIT) {
+ input_select_bits |= Gi_Output_Polarity_Bit;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Input_Select_Reg(counter->counter_index),
+ Gi_Gate_Select_Load_Source_Bit | Gi_Or_Gate_Bit |
+ Gi_Output_Polarity_Bit, input_select_bits);
+
+ return 0;
+}
+
+int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+
+ unsigned command_transient_bits = 0;
+
+ if (arm) {
+ switch (start_trigger) {
+ case NI_GPCT_ARM_IMMEDIATE:
+ command_transient_bits |= Gi_Arm_Bit;
+ break;
+ case NI_GPCT_ARM_PAIRED_IMMEDIATE:
+ command_transient_bits |= Gi_Arm_Bit | Gi_Arm_Copy_Bit;
+ break;
+ default:
+ break;
+ }
+ if (ni_tio_counting_mode_registers_present(counter_dev)) {
+ unsigned counting_mode_bits = 0;
+
+ switch (start_trigger) {
+ case NI_GPCT_ARM_IMMEDIATE:
+ case NI_GPCT_ARM_PAIRED_IMMEDIATE:
+ break;
+ default:
+ if (start_trigger & NI_GPCT_ARM_UNKNOWN) {
+ /* pass-through the least significant bits so we can figure out what select later */
+ unsigned hw_arm_select_bits =
+ (start_trigger <<
+ Gi_HW_Arm_Select_Shift) &
+ Gi_HW_Arm_Select_Mask
+ (counter_dev->variant);
+
+ counting_mode_bits |=
+ Gi_HW_Arm_Enable_Bit |
+ hw_arm_select_bits;
+ } else {
+ return -EINVAL;
+ }
+ break;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Counting_Mode_Reg(counter->
+ counter_index),
+ Gi_HW_Arm_Select_Mask(counter_dev->
+ variant) | Gi_HW_Arm_Enable_Bit,
+ counting_mode_bits);
+ }
+ } else {
+ command_transient_bits |= Gi_Disarm_Bit;
+ }
+ ni_tio_set_bits_transient(counter,
+ NITIO_Gi_Command_Reg(counter->counter_index), 0, 0,
+ command_transient_bits);
+ return 0;
+}
+
+static unsigned ni_660x_source_select_bits(unsigned int clock_source)
+{
+ unsigned ni_660x_clock;
+ unsigned i;
+ const unsigned clock_select_bits =
+ clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
+
+ switch (clock_select_bits) {
+ case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Timebase_1_Clock;
+ break;
+ case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Timebase_2_Clock;
+ break;
+ case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Timebase_3_Clock;
+ break;
+ case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Logic_Low_Clock;
+ break;
+ case NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Source_Pin_i_Clock;
+ break;
+ case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Next_Gate_Clock;
+ break;
+ case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Next_TC_Clock;
+ break;
+ default:
+ for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+ if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
+ ni_660x_clock = NI_660x_RTSI_Clock(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_660x_max_source_pin; ++i) {
+ if (clock_select_bits ==
+ NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) {
+ ni_660x_clock = NI_660x_Source_Pin_Clock(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_source_pin)
+ break;
+ ni_660x_clock = 0;
+ BUG();
+ break;
+ }
+ return Gi_Source_Select_Bits(ni_660x_clock);
+}
+
+static unsigned ni_m_series_source_select_bits(unsigned int clock_source)
+{
+ unsigned ni_m_series_clock;
+ unsigned i;
+ const unsigned clock_select_bits =
+ clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
+ switch (clock_select_bits) {
+ case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Timebase_1_Clock;
+ break;
+ case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Timebase_2_Clock;
+ break;
+ case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Timebase_3_Clock;
+ break;
+ case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Logic_Low_Clock;
+ break;
+ case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Next_Gate_Clock;
+ break;
+ case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Next_TC_Clock;
+ break;
+ case NI_GPCT_PXI10_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_PXI10_Clock;
+ break;
+ case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_PXI_Star_Trigger_Clock;
+ break;
+ case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Analog_Trigger_Out_Clock;
+ break;
+ default:
+ for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
+ if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
+ ni_m_series_clock = NI_M_Series_RTSI_Clock(i);
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
+ if (clock_select_bits == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) {
+ ni_m_series_clock = NI_M_Series_PFI_Clock(i);
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_pfi_channel)
+ break;
+ rt_printk("invalid clock source 0x%lx\n",
+ (unsigned long)clock_source);
+ BUG();
+ ni_m_series_clock = 0;
+ break;
+ }
+ return Gi_Source_Select_Bits(ni_m_series_clock);
+};
+
+static void ni_tio_set_source_subselect(struct ni_gpct *counter,
+ unsigned int clock_source)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned second_gate_reg =
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+
+ if (counter_dev->variant != ni_gpct_variant_m_series)
+ return;
+ switch (clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
+ /* Gi_Source_Subselect is zero */
+ case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
+ case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+ counter_dev->regs[second_gate_reg] &= ~Gi_Source_Subselect_Bit;
+ break;
+ /* Gi_Source_Subselect is one */
+ case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
+ case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
+ counter_dev->regs[second_gate_reg] |= Gi_Source_Subselect_Bit;
+ break;
+ /* Gi_Source_Subselect doesn't matter */
+ default:
+ return;
+ break;
+ }
+ write_register(counter, counter_dev->regs[second_gate_reg],
+ second_gate_reg);
+}
+
+static int ni_tio_set_clock_src(struct ni_gpct *counter,
+ unsigned int clock_source, unsigned int period_ns)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ unsigned input_select_bits = 0;
+ static const uint64_t pico_per_nano = 1000;
+
+/*FIXME: validate clock source */
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_660x:
+ input_select_bits |= ni_660x_source_select_bits(clock_source);
+ break;
+ case ni_gpct_variant_e_series:
+ case ni_gpct_variant_m_series:
+ input_select_bits |=
+ ni_m_series_source_select_bits(clock_source);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT)
+ input_select_bits |= Gi_Source_Polarity_Bit;
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Input_Select_Reg(counter->counter_index),
+ Gi_Source_Select_Mask | Gi_Source_Polarity_Bit,
+ input_select_bits);
+ ni_tio_set_source_subselect(counter, clock_source);
+ if (ni_tio_counting_mode_registers_present(counter_dev)) {
+ const unsigned prescaling_mode =
+ clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK;
+ unsigned counting_mode_bits = 0;
+
+ switch (prescaling_mode) {
+ case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
+ break;
+ case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
+ counting_mode_bits |=
+ Gi_Prescale_X2_Bit(counter_dev->variant);
+ break;
+ case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
+ counting_mode_bits |=
+ Gi_Prescale_X8_Bit(counter_dev->variant);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Counting_Mode_Reg(counter->counter_index),
+ Gi_Prescale_X2_Bit(counter_dev->
+ variant) | Gi_Prescale_X8_Bit(counter_dev->
+ variant), counting_mode_bits);
+ }
+ counter->clock_period_ps = pico_per_nano * period_ns;
+ ni_tio_set_sync_mode(counter, 0);
+ return 0;
+}
+
+static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned counting_mode_bits = ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Counting_Mode_Reg(counter->counter_index));
+ unsigned bits = 0;
+
+ if (ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Input_Select_Reg(counter->
+ counter_index)) & Gi_Source_Polarity_Bit)
+ bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT;
+ if (counting_mode_bits & Gi_Prescale_X2_Bit(counter_dev->variant))
+ bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS;
+ if (counting_mode_bits & Gi_Prescale_X8_Bit(counter_dev->variant))
+ bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS;
+ return bits;
+}
+
+static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned second_gate_reg =
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+ unsigned clock_source = 0;
+ unsigned i;
+ const unsigned input_select = (ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Input_Select_Reg(counter->
+ counter_index)) & Gi_Source_Select_Mask) >>
+ Gi_Source_Select_Shift;
+
+ switch (input_select) {
+ case NI_M_Series_Timebase_1_Clock:
+ clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
+ break;
+ case NI_M_Series_Timebase_2_Clock:
+ clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
+ break;
+ case NI_M_Series_Timebase_3_Clock:
+ if (counter_dev->
+ regs[second_gate_reg] & Gi_Source_Subselect_Bit)
+ clock_source =
+ NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS;
+ else
+ clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
+ break;
+ case NI_M_Series_Logic_Low_Clock:
+ clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
+ break;
+ case NI_M_Series_Next_Gate_Clock:
+ if (counter_dev->
+ regs[second_gate_reg] & Gi_Source_Subselect_Bit)
+ clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS;
+ else
+ clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
+ break;
+ case NI_M_Series_PXI10_Clock:
+ clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS;
+ break;
+ case NI_M_Series_Next_TC_Clock:
+ clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
+ break;
+ default:
+ for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
+ if (input_select == NI_M_Series_RTSI_Clock(i)) {
+ clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
+ if (input_select == NI_M_Series_PFI_Clock(i)) {
+ clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_pfi_channel)
+ break;
+ BUG();
+ break;
+ }
+ clock_source |= ni_tio_clock_src_modifiers(counter);
+ return clock_source;
+}
+
+static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter)
+{
+ unsigned clock_source = 0;
+ unsigned i;
+ const unsigned input_select = (ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Input_Select_Reg(counter->
+ counter_index)) & Gi_Source_Select_Mask) >>
+ Gi_Source_Select_Shift;
+
+ switch (input_select) {
+ case NI_660x_Timebase_1_Clock:
+ clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
+ break;
+ case NI_660x_Timebase_2_Clock:
+ clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
+ break;
+ case NI_660x_Timebase_3_Clock:
+ clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
+ break;
+ case NI_660x_Logic_Low_Clock:
+ clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
+ break;
+ case NI_660x_Source_Pin_i_Clock:
+ clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS;
+ break;
+ case NI_660x_Next_Gate_Clock:
+ clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
+ break;
+ case NI_660x_Next_TC_Clock:
+ clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
+ break;
+ default:
+ for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+ if (input_select == NI_660x_RTSI_Clock(i)) {
+ clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_660x_max_source_pin; ++i) {
+ if (input_select == NI_660x_Source_Pin_Clock(i)) {
+ clock_source =
+ NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_source_pin)
+ break;
+ BUG();
+ break;
+ }
+ clock_source |= ni_tio_clock_src_modifiers(counter);
+ return clock_source;
+}
+
+static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter)
+{
+ switch (counter->counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ case ni_gpct_variant_m_series:
+ return ni_m_series_clock_src_select(counter);
+ break;
+ case ni_gpct_variant_660x:
+ return ni_660x_clock_src_select(counter);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
+ unsigned generic_clock_source)
+{
+ uint64_t clock_period_ps;
+
+ switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
+ case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
+ clock_period_ps = 50000;
+ break;
+ case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
+ clock_period_ps = 10000000;
+ break;
+ case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+ clock_period_ps = 12500;
+ break;
+ case NI_GPCT_PXI10_CLOCK_SRC_BITS:
+ clock_period_ps = 100000;
+ break;
+ default:
+ /* clock period is specified by user with prescaling already taken into account. */
+ return counter->clock_period_ps;
+ break;
+ }
+
+ switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
+ case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
+ break;
+ case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
+ clock_period_ps *= 2;
+ break;
+ case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
+ clock_period_ps *= 8;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return clock_period_ps;
+}
+
+static void ni_tio_get_clock_src(struct ni_gpct *counter,
+ unsigned int * clock_source, unsigned int * period_ns)
+{
+ static const unsigned pico_per_nano = 1000;
+ uint64_t temp64;
+ *clock_source = ni_tio_generic_clock_src_select(counter);
+ temp64 = ni_tio_clock_period_ps(counter, *clock_source);
+ do_div(temp64, pico_per_nano);
+ *period_ns = temp64;
+}
+
+static void ni_tio_set_first_gate_modifiers(struct ni_gpct *counter,
+ unsigned int gate_source)
+{
+ const unsigned mode_mask = Gi_Gate_Polarity_Bit | Gi_Gating_Mode_Mask;
+ unsigned mode_values = 0;
+
+ if (gate_source & CR_INVERT) {
+ mode_values |= Gi_Gate_Polarity_Bit;
+ }
+ if (gate_source & CR_EDGE) {
+ mode_values |= Gi_Rising_Edge_Gating_Bits;
+ } else {
+ mode_values |= Gi_Level_Gating_Bits;
+ }
+ ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index),
+ mode_mask, mode_values);
+}
+
+static int ni_660x_set_first_gate(struct ni_gpct *counter, unsigned int gate_source)
+{
+ const unsigned selected_gate = CR_CHAN(gate_source);
+ /* bits of selected_gate that may be meaningful to input select register */
+ const unsigned selected_gate_mask = 0x1f;
+ unsigned ni_660x_gate_select;
+ unsigned i;
+
+ switch (selected_gate) {
+ case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
+ ni_660x_gate_select = NI_660x_Next_SRC_Gate_Select;
+ break;
+ case NI_GPCT_NEXT_OUT_GATE_SELECT:
+ case NI_GPCT_LOGIC_LOW_GATE_SELECT:
+ case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
+ case NI_GPCT_GATE_PIN_i_GATE_SELECT:
+ ni_660x_gate_select = selected_gate & selected_gate_mask;
+ break;
+ default:
+ for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+ if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
+ ni_660x_gate_select =
+ selected_gate & selected_gate_mask;
+ break;
+ }
+ }
+ if (i <= ni_660x_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_660x_max_gate_pin; ++i) {
+ if (selected_gate == NI_GPCT_GATE_PIN_GATE_SELECT(i)) {
+ ni_660x_gate_select =
+ selected_gate & selected_gate_mask;
+ break;
+ }
+ }
+ if (i <= ni_660x_max_gate_pin)
+ break;
+ return -EINVAL;
+ break;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Input_Select_Reg(counter->counter_index),
+ Gi_Gate_Select_Mask, Gi_Gate_Select_Bits(ni_660x_gate_select));
+ return 0;
+}
+
+static int ni_m_series_set_first_gate(struct ni_gpct *counter,
+ unsigned int gate_source)
+{
+ const unsigned selected_gate = CR_CHAN(gate_source);
+ /* bits of selected_gate that may be meaningful to input select register */
+ const unsigned selected_gate_mask = 0x1f;
+ unsigned ni_m_series_gate_select;
+ unsigned i;
+
+ switch (selected_gate) {
+ case NI_GPCT_TIMESTAMP_MUX_GATE_SELECT:
+ case NI_GPCT_AI_START2_GATE_SELECT:
+ case NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT:
+ case NI_GPCT_NEXT_OUT_GATE_SELECT:
+ case NI_GPCT_AI_START1_GATE_SELECT:
+ case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
+ case NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT:
+ case NI_GPCT_LOGIC_LOW_GATE_SELECT:
+ ni_m_series_gate_select = selected_gate & selected_gate_mask;
+ break;
+ default:
+ for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
+ if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
+ ni_m_series_gate_select =
+ selected_gate & selected_gate_mask;
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
+ if (selected_gate == NI_GPCT_PFI_GATE_SELECT(i)) {
+ ni_m_series_gate_select =
+ selected_gate & selected_gate_mask;
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_pfi_channel)
+ break;
+ return -EINVAL;
+ break;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Input_Select_Reg(counter->counter_index),
+ Gi_Gate_Select_Mask,
+ Gi_Gate_Select_Bits(ni_m_series_gate_select));
+ return 0;
+}
+
+static int ni_660x_set_second_gate(struct ni_gpct *counter,
+ unsigned int gate_source)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned second_gate_reg =
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+ const unsigned selected_second_gate = CR_CHAN(gate_source);
+ /* bits of second_gate that may be meaningful to second gate register */
+ static const unsigned selected_second_gate_mask = 0x1f;
+ unsigned ni_660x_second_gate_select;
+ unsigned i;
+
+ switch (selected_second_gate) {
+ case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
+ case NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT:
+ case NI_GPCT_SELECTED_GATE_GATE_SELECT:
+ case NI_GPCT_NEXT_OUT_GATE_SELECT:
+ case NI_GPCT_LOGIC_LOW_GATE_SELECT:
+ ni_660x_second_gate_select =
+ selected_second_gate & selected_second_gate_mask;
+ break;
+ case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
+ ni_660x_second_gate_select =
+ NI_660x_Next_SRC_Second_Gate_Select;
+ break;
+ default:
+ for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+ if (selected_second_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
+ ni_660x_second_gate_select =
+ selected_second_gate &
+ selected_second_gate_mask;
+ break;
+ }
+ }
+ if (i <= ni_660x_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_660x_max_up_down_pin; ++i) {
+ if (selected_second_gate ==
+ NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) {
+ ni_660x_second_gate_select =
+ selected_second_gate &
+ selected_second_gate_mask;
+ break;
+ }
+ }
+ if (i <= ni_660x_max_up_down_pin)
+ break;
+ return -EINVAL;
+ break;
+ };
+ counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
+ counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
+ counter_dev->regs[second_gate_reg] |=
+ Gi_Second_Gate_Select_Bits(ni_660x_second_gate_select);
+ write_register(counter, counter_dev->regs[second_gate_reg],
+ second_gate_reg);
+ return 0;
+}
+
+static int ni_m_series_set_second_gate(struct ni_gpct *counter,
+ unsigned int gate_source)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned second_gate_reg =
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+ const unsigned selected_second_gate = CR_CHAN(gate_source);
+ /* bits of second_gate that may be meaningful to second gate register */
+ static const unsigned selected_second_gate_mask = 0x1f;
+ unsigned ni_m_series_second_gate_select;
+
+ /* FIXME: We don't know what the m-series second gate codes are, so we'll just pass
+ the bits through for now. */
+ switch (selected_second_gate) {
+ default:
+ ni_m_series_second_gate_select =
+ selected_second_gate & selected_second_gate_mask;
+ break;
+ };
+ counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
+ counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
+ counter_dev->regs[second_gate_reg] |=
+ Gi_Second_Gate_Select_Bits(ni_m_series_second_gate_select);
+ write_register(counter, counter_dev->regs[second_gate_reg],
+ second_gate_reg);
+ return 0;
+}
+
+int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
+ unsigned int gate_source)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned second_gate_reg =
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+
+ switch (gate_index) {
+ case 0:
+ if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) {
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Mode_Reg(counter->counter_index),
+ Gi_Gating_Mode_Mask, Gi_Gating_Disabled_Bits);
+ return 0;
+ }
+ ni_tio_set_first_gate_modifiers(counter, gate_source);
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ case ni_gpct_variant_m_series:
+ return ni_m_series_set_first_gate(counter, gate_source);
+ break;
+ case ni_gpct_variant_660x:
+ return ni_660x_set_first_gate(counter, gate_source);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ break;
+ case 1:
+ if (ni_tio_second_gate_registers_present(counter_dev) == 0)
+ return -EINVAL;
+ if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) {
+ counter_dev->regs[second_gate_reg] &=
+ ~Gi_Second_Gate_Mode_Bit;
+ write_register(counter,
+ counter_dev->regs[second_gate_reg],
+ second_gate_reg);
+ return 0;
+ }
+ if (gate_source & CR_INVERT) {
+ counter_dev->regs[second_gate_reg] |=
+ Gi_Second_Gate_Polarity_Bit;
+ } else {
+ counter_dev->regs[second_gate_reg] &=
+ ~Gi_Second_Gate_Polarity_Bit;
+ }
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_m_series:
+ return ni_m_series_set_second_gate(counter,
+ gate_source);
+ break;
+ case ni_gpct_variant_660x:
+ return ni_660x_set_second_gate(counter, gate_source);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index,
+ unsigned int source)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+
+ if (counter_dev->variant == ni_gpct_variant_m_series) {
+ unsigned int abz_reg, shift, mask;
+
+ abz_reg = NITIO_Gi_ABZ_Reg(counter->counter_index);
+ switch (index) {
+ case NI_GPCT_SOURCE_ENCODER_A:
+ shift = 10;
+ break;
+ case NI_GPCT_SOURCE_ENCODER_B:
+ shift = 5;
+ break;
+ case NI_GPCT_SOURCE_ENCODER_Z:
+ shift = 0;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ mask = 0x1f << shift;
+ if (source > 0x1f) {
+ /* Disable gate */
+ source = 0x1f;
+ }
+ counter_dev->regs[abz_reg] &= ~mask;
+ counter_dev->regs[abz_reg] |= (source << shift) & mask;
+ write_register(counter, counter_dev->regs[abz_reg], abz_reg);
+// rt_printk("%s %x %d %d\n", __FUNCTION__, counter_dev->regs[abz_reg], index, source);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static unsigned ni_660x_first_gate_to_generic_gate_source(unsigned
+ ni_660x_gate_select)
+{
+ unsigned i;
+
+ switch (ni_660x_gate_select) {
+ case NI_660x_Source_Pin_i_Gate_Select:
+ return NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
+ break;
+ case NI_660x_Gate_Pin_i_Gate_Select:
+ return NI_GPCT_GATE_PIN_i_GATE_SELECT;
+ break;
+ case NI_660x_Next_SRC_Gate_Select:
+ return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
+ break;
+ case NI_660x_Next_Out_Gate_Select:
+ return NI_GPCT_NEXT_OUT_GATE_SELECT;
+ break;
+ case NI_660x_Logic_Low_Gate_Select:
+ return NI_GPCT_LOGIC_LOW_GATE_SELECT;
+ break;
+ default:
+ for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+ if (ni_660x_gate_select == NI_660x_RTSI_Gate_Select(i)) {
+ return NI_GPCT_RTSI_GATE_SELECT(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_660x_max_gate_pin; ++i) {
+ if (ni_660x_gate_select ==
+ NI_660x_Gate_Pin_Gate_Select(i)) {
+ return NI_GPCT_GATE_PIN_GATE_SELECT(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_gate_pin)
+ break;
+ BUG();
+ break;
+ }
+ return 0;
+};
+
+static unsigned ni_m_series_first_gate_to_generic_gate_source(unsigned
+ ni_m_series_gate_select)
+{
+ unsigned i;
+
+ switch (ni_m_series_gate_select) {
+ case NI_M_Series_Timestamp_Mux_Gate_Select:
+ return NI_GPCT_TIMESTAMP_MUX_GATE_SELECT;
+ break;
+ case NI_M_Series_AI_START2_Gate_Select:
+ return NI_GPCT_AI_START2_GATE_SELECT;
+ break;
+ case NI_M_Series_PXI_Star_Trigger_Gate_Select:
+ return NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT;
+ break;
+ case NI_M_Series_Next_Out_Gate_Select:
+ return NI_GPCT_NEXT_OUT_GATE_SELECT;
+ break;
+ case NI_M_Series_AI_START1_Gate_Select:
+ return NI_GPCT_AI_START1_GATE_SELECT;
+ break;
+ case NI_M_Series_Next_SRC_Gate_Select:
+ return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
+ break;
+ case NI_M_Series_Analog_Trigger_Out_Gate_Select:
+ return NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT;
+ break;
+ case NI_M_Series_Logic_Low_Gate_Select:
+ return NI_GPCT_LOGIC_LOW_GATE_SELECT;
+ break;
+ default:
+ for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
+ if (ni_m_series_gate_select ==
+ NI_M_Series_RTSI_Gate_Select(i)) {
+ return NI_GPCT_RTSI_GATE_SELECT(i);
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
+ if (ni_m_series_gate_select ==
+ NI_M_Series_PFI_Gate_Select(i)) {
+ return NI_GPCT_PFI_GATE_SELECT(i);
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_pfi_channel)
+ break;
+ BUG();
+ break;
+ }
+ return 0;
+};
+
+static unsigned ni_660x_second_gate_to_generic_gate_source(unsigned
+ ni_660x_gate_select)
+{
+ unsigned i;
+
+ switch (ni_660x_gate_select) {
+ case NI_660x_Source_Pin_i_Second_Gate_Select:
+ return NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
+ break;
+ case NI_660x_Up_Down_Pin_i_Second_Gate_Select:
+ return NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT;
+ break;
+ case NI_660x_Next_SRC_Second_Gate_Select:
+ return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
+ break;
+ case NI_660x_Next_Out_Second_Gate_Select:
+ return NI_GPCT_NEXT_OUT_GATE_SELECT;
+ break;
+ case NI_660x_Selected_Gate_Second_Gate_Select:
+ return NI_GPCT_SELECTED_GATE_GATE_SELECT;
+ break;
+ case NI_660x_Logic_Low_Second_Gate_Select:
+ return NI_GPCT_LOGIC_LOW_GATE_SELECT;
+ break;
+ default:
+ for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+ if (ni_660x_gate_select ==
+ NI_660x_RTSI_Second_Gate_Select(i)) {
+ return NI_GPCT_RTSI_GATE_SELECT(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_660x_max_up_down_pin; ++i) {
+ if (ni_660x_gate_select ==
+ NI_660x_Up_Down_Pin_Second_Gate_Select(i)) {
+ return NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_up_down_pin)
+ break;
+ BUG();
+ break;
+ }
+ return 0;
+};
+
+static unsigned ni_m_series_second_gate_to_generic_gate_source(unsigned
+ ni_m_series_gate_select)
+{
+ /*FIXME: the second gate sources for the m series are undocumented, so we just return
+ * the raw bits for now. */
+ switch (ni_m_series_gate_select) {
+ default:
+ return ni_m_series_gate_select;
+ break;
+ }
+ return 0;
+};
+
+static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index,
+ unsigned int * gate_source)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned mode_bits = ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Mode_Reg(counter->counter_index));
+ const unsigned second_gate_reg =
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+ unsigned gate_select_bits;
+
+ switch (gate_index) {
+ case 0:
+ if ((mode_bits & Gi_Gating_Mode_Mask) ==
+ Gi_Gating_Disabled_Bits) {
+ *gate_source = NI_GPCT_DISABLED_GATE_SELECT;
+ return 0;
+ } else {
+ gate_select_bits =
+ (ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Input_Select_Reg(counter->
+ counter_index)) &
+ Gi_Gate_Select_Mask) >> Gi_Gate_Select_Shift;
+ }
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ case ni_gpct_variant_m_series:
+ *gate_source =
+ ni_m_series_first_gate_to_generic_gate_source
+ (gate_select_bits);
+ break;
+ case ni_gpct_variant_660x:
+ *gate_source =
+ ni_660x_first_gate_to_generic_gate_source
+ (gate_select_bits);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ if (mode_bits & Gi_Gate_Polarity_Bit) {
+ *gate_source |= CR_INVERT;
+ }
+ if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) {
+ *gate_source |= CR_EDGE;
+ }
+ break;
+ case 1:
+ if ((mode_bits & Gi_Gating_Mode_Mask) == Gi_Gating_Disabled_Bits
+ || (counter_dev->
+ regs[second_gate_reg] & Gi_Second_Gate_Mode_Bit)
+ == 0) {
+ *gate_source = NI_GPCT_DISABLED_GATE_SELECT;
+ return 0;
+ } else {
+ gate_select_bits =
+ (counter_dev->
+ regs[second_gate_reg] &
+ Gi_Second_Gate_Select_Mask) >>
+ Gi_Second_Gate_Select_Shift;
+ }
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ case ni_gpct_variant_m_series:
+ *gate_source =
+ ni_m_series_second_gate_to_generic_gate_source
+ (gate_select_bits);
+ break;
+ case ni_gpct_variant_660x:
+ *gate_source =
+ ni_660x_second_gate_to_generic_gate_source
+ (gate_select_bits);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ if (counter_dev->
+ regs[second_gate_reg] & Gi_Second_Gate_Polarity_Bit) {
+ *gate_source |= CR_INVERT;
+ }
+ /* second gate can't have edge/level mode set independently */
+ if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) {
+ *gate_source |= CR_EDGE;
+ }
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+int ni_tio_insn_config(struct ni_gpct *counter,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case INSN_CONFIG_SET_COUNTER_MODE:
+ return ni_tio_set_counter_mode(counter, data[1]);
+ break;
+ case INSN_CONFIG_ARM:
+ return ni_tio_arm(counter, 1, data[1]);
+ break;
+ case INSN_CONFIG_DISARM:
+ ni_tio_arm(counter, 0, 0);
+ return 0;
+ break;
+ case INSN_CONFIG_GET_COUNTER_STATUS:
+ data[1] = ni_tio_counter_status(counter);
+ data[2] = counter_status_mask;
+ return 0;
+ break;
+ case INSN_CONFIG_SET_CLOCK_SRC:
+ return ni_tio_set_clock_src(counter, data[1], data[2]);
+ break;
+ case INSN_CONFIG_GET_CLOCK_SRC:
+ ni_tio_get_clock_src(counter, &data[1], &data[2]);
+ return 0;
+ break;
+ case INSN_CONFIG_SET_GATE_SRC:
+ return ni_tio_set_gate_src(counter, data[1], data[2]);
+ break;
+ case INSN_CONFIG_GET_GATE_SRC:
+ return ni_tio_get_gate_src(counter, data[1], &data[2]);
+ break;
+ case INSN_CONFIG_SET_OTHER_SRC:
+ return ni_tio_set_other_src(counter, data[1], data[2]);
+ break;
+ case INSN_CONFIG_RESET:
+ ni_tio_reset_count_and_disarm(counter);
+ return 0;
+ break;
+ default:
+ break;
+ }
+ return -EINVAL;
+}
+
+int ni_tio_rinsn(struct ni_gpct *counter, struct comedi_insn * insn, unsigned int * data)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned channel = CR_CHAN(insn->chanspec);
+ unsigned first_read;
+ unsigned second_read;
+ unsigned correct_read;
+
+ if (insn->n < 1)
+ return 0;
+ switch (channel) {
+ case 0:
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Command_Reg(counter->counter_index),
+ Gi_Save_Trace_Bit, 0);
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Command_Reg(counter->counter_index),
+ Gi_Save_Trace_Bit, Gi_Save_Trace_Bit);
+ /* The count doesn't get latched until the next clock edge, so it is possible the count
+ may change (once) while we are reading. Since the read of the SW_Save_Reg isn't
+ atomic (apparently even when it's a 32 bit register according to 660x docs),
+ we need to read twice and make sure the reading hasn't changed. If it has,
+ a third read will be correct since the count value will definitely have latched by then. */
+ first_read =
+ read_register(counter,
+ NITIO_Gi_SW_Save_Reg(counter->counter_index));
+ second_read =
+ read_register(counter,
+ NITIO_Gi_SW_Save_Reg(counter->counter_index));
+ if (first_read != second_read)
+ correct_read =
+ read_register(counter,
+ NITIO_Gi_SW_Save_Reg(counter->counter_index));
+ else
+ correct_read = first_read;
+ data[0] = correct_read;
+ return 0;
+ break;
+ case 1:
+ data[0] =
+ counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->
+ counter_index)];
+ break;
+ case 2:
+ data[0] =
+ counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->
+ counter_index)];
+ break;
+ };
+ return 0;
+}
+
+static unsigned ni_tio_next_load_register(struct ni_gpct *counter)
+{
+ const unsigned bits = read_register(counter,
+ NITIO_Gxx_Status_Reg(counter->counter_index));
+
+ if (bits & Gi_Next_Load_Source_Bit(counter->counter_index)) {
+ return NITIO_Gi_LoadB_Reg(counter->counter_index);
+ } else {
+ return NITIO_Gi_LoadA_Reg(counter->counter_index);
+ }
+}
+
+int ni_tio_winsn(struct ni_gpct *counter, struct comedi_insn * insn, unsigned int * data)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned channel = CR_CHAN(insn->chanspec);
+ unsigned load_reg;
+
+ if (insn->n < 1)
+ return 0;
+ switch (channel) {
+ case 0:
+ /* Unsafe if counter is armed. Should probably check status and return -EBUSY if armed. */
+ /* Don't disturb load source select, just use whichever load register is already selected. */
+ load_reg = ni_tio_next_load_register(counter);
+ write_register(counter, data[0], load_reg);
+ ni_tio_set_bits_transient(counter,
+ NITIO_Gi_Command_Reg(counter->counter_index), 0, 0,
+ Gi_Load_Bit);
+ /* restore state of load reg to whatever the user set last set it to */
+ write_register(counter, counter_dev->regs[load_reg], load_reg);
+ break;
+ case 1:
+ counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] =
+ data[0];
+ write_register(counter, data[0],
+ NITIO_Gi_LoadA_Reg(counter->counter_index));
+ break;
+ case 2:
+ counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] =
+ data[0];
+ write_register(counter, data[0],
+ NITIO_Gi_LoadB_Reg(counter->counter_index));
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(ni_tio_rinsn);
+EXPORT_SYMBOL_GPL(ni_tio_winsn);
+EXPORT_SYMBOL_GPL(ni_tio_insn_config);
+EXPORT_SYMBOL_GPL(ni_tio_init_counter);
+EXPORT_SYMBOL_GPL(ni_tio_arm);
+EXPORT_SYMBOL_GPL(ni_tio_set_gate_src);
+EXPORT_SYMBOL_GPL(ni_gpct_device_construct);
+EXPORT_SYMBOL_GPL(ni_gpct_device_destroy);
diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h
new file mode 100644
index 00000000000..0729d60b01c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_tio.h
@@ -0,0 +1,163 @@
+/*
+ drivers/ni_tio.h
+ Header file for NI general purpose counter support code (ni_tio.c)
+
+ COMEDI - Linux Control and Measurement Device Interface
+
+ 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.
+
+*/
+
+#ifndef _COMEDI_NI_TIO_H
+#define _COMEDI_NI_TIO_H
+
+#include "../comedidev.h"
+
+// forward declarations
+struct mite_struct;
+struct ni_gpct_device;
+
+enum ni_gpct_register {
+ NITIO_G0_Autoincrement_Reg,
+ NITIO_G1_Autoincrement_Reg,
+ NITIO_G2_Autoincrement_Reg,
+ NITIO_G3_Autoincrement_Reg,
+ NITIO_G0_Command_Reg,
+ NITIO_G1_Command_Reg,
+ NITIO_G2_Command_Reg,
+ NITIO_G3_Command_Reg,
+ NITIO_G0_HW_Save_Reg,
+ NITIO_G1_HW_Save_Reg,
+ NITIO_G2_HW_Save_Reg,
+ NITIO_G3_HW_Save_Reg,
+ NITIO_G0_SW_Save_Reg,
+ NITIO_G1_SW_Save_Reg,
+ NITIO_G2_SW_Save_Reg,
+ NITIO_G3_SW_Save_Reg,
+ NITIO_G0_Mode_Reg,
+ NITIO_G1_Mode_Reg,
+ NITIO_G2_Mode_Reg,
+ NITIO_G3_Mode_Reg,
+ NITIO_G0_LoadA_Reg,
+ NITIO_G1_LoadA_Reg,
+ NITIO_G2_LoadA_Reg,
+ NITIO_G3_LoadA_Reg,
+ NITIO_G0_LoadB_Reg,
+ NITIO_G1_LoadB_Reg,
+ NITIO_G2_LoadB_Reg,
+ NITIO_G3_LoadB_Reg,
+ NITIO_G0_Input_Select_Reg,
+ NITIO_G1_Input_Select_Reg,
+ NITIO_G2_Input_Select_Reg,
+ NITIO_G3_Input_Select_Reg,
+ NITIO_G0_Counting_Mode_Reg,
+ NITIO_G1_Counting_Mode_Reg,
+ NITIO_G2_Counting_Mode_Reg,
+ NITIO_G3_Counting_Mode_Reg,
+ NITIO_G0_Second_Gate_Reg,
+ NITIO_G1_Second_Gate_Reg,
+ NITIO_G2_Second_Gate_Reg,
+ NITIO_G3_Second_Gate_Reg,
+ NITIO_G01_Status_Reg,
+ NITIO_G23_Status_Reg,
+ NITIO_G01_Joint_Reset_Reg,
+ NITIO_G23_Joint_Reset_Reg,
+ NITIO_G01_Joint_Status1_Reg,
+ NITIO_G23_Joint_Status1_Reg,
+ NITIO_G01_Joint_Status2_Reg,
+ NITIO_G23_Joint_Status2_Reg,
+ NITIO_G0_DMA_Config_Reg,
+ NITIO_G1_DMA_Config_Reg,
+ NITIO_G2_DMA_Config_Reg,
+ NITIO_G3_DMA_Config_Reg,
+ NITIO_G0_DMA_Status_Reg,
+ NITIO_G1_DMA_Status_Reg,
+ NITIO_G2_DMA_Status_Reg,
+ NITIO_G3_DMA_Status_Reg,
+ NITIO_G0_ABZ_Reg,
+ NITIO_G1_ABZ_Reg,
+ NITIO_G0_Interrupt_Acknowledge_Reg,
+ NITIO_G1_Interrupt_Acknowledge_Reg,
+ NITIO_G2_Interrupt_Acknowledge_Reg,
+ NITIO_G3_Interrupt_Acknowledge_Reg,
+ NITIO_G0_Status_Reg,
+ NITIO_G1_Status_Reg,
+ NITIO_G2_Status_Reg,
+ NITIO_G3_Status_Reg,
+ NITIO_G0_Interrupt_Enable_Reg,
+ NITIO_G1_Interrupt_Enable_Reg,
+ NITIO_G2_Interrupt_Enable_Reg,
+ NITIO_G3_Interrupt_Enable_Reg,
+ NITIO_Num_Registers,
+};
+
+enum ni_gpct_variant {
+ ni_gpct_variant_e_series,
+ ni_gpct_variant_m_series,
+ ni_gpct_variant_660x
+};
+
+struct ni_gpct {
+ struct ni_gpct_device *counter_dev;
+ unsigned counter_index;
+ unsigned chip_index;
+ uint64_t clock_period_ps; /* clock period in picoseconds */
+ struct mite_channel *mite_chan;
+ spinlock_t lock;
+};
+
+struct ni_gpct_device {
+ struct comedi_device *dev;
+ void (*write_register) (struct ni_gpct * counter, unsigned bits,
+ enum ni_gpct_register reg);
+ unsigned (*read_register) (struct ni_gpct * counter,
+ enum ni_gpct_register reg);
+ enum ni_gpct_variant variant;
+ struct ni_gpct *counters;
+ unsigned num_counters;
+ unsigned regs[NITIO_Num_Registers];
+ spinlock_t regs_lock;
+};
+
+extern struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device * dev,
+ void (*write_register) (struct ni_gpct * counter, unsigned bits,
+ enum ni_gpct_register reg),
+ unsigned (*read_register) (struct ni_gpct * counter,
+ enum ni_gpct_register reg), enum ni_gpct_variant variant,
+ unsigned num_counters);
+extern void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev);
+extern void ni_tio_init_counter(struct ni_gpct *counter);
+extern int ni_tio_rinsn(struct ni_gpct *counter,
+ struct comedi_insn * insn, unsigned int * data);
+extern int ni_tio_insn_config(struct ni_gpct *counter,
+ struct comedi_insn * insn, unsigned int * data);
+extern int ni_tio_winsn(struct ni_gpct *counter,
+ struct comedi_insn * insn, unsigned int * data);
+extern int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async);
+extern int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd * cmd);
+extern int ni_tio_cancel(struct ni_gpct *counter);
+extern void ni_tio_handle_interrupt(struct ni_gpct *counter,
+ struct comedi_subdevice * s);
+extern void ni_tio_set_mite_channel(struct ni_gpct *counter,
+ struct mite_channel *mite_chan);
+extern void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter,
+ int *gate_error, int *tc_error, int *perm_stale_data, int *stale_data);
+
+static inline struct ni_gpct *subdev_to_counter(struct comedi_subdevice * s)
+{
+ return s->private;
+}
+
+#endif /* _COMEDI_NI_TIO_H */
diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h
new file mode 100644
index 00000000000..ac5b171cbe1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_tio_internal.h
@@ -0,0 +1,774 @@
+/*
+ drivers/ni_tio_internal.h
+ Header file for NI general purpose counter support code (ni_tio.c and
+ ni_tiocmd.c)
+
+ COMEDI - Linux Control and Measurement Device Interface
+
+ 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.
+
+*/
+
+#ifndef _COMEDI_NI_TIO_INTERNAL_H
+#define _COMEDI_NI_TIO_INTERNAL_H
+
+#include "ni_tio.h"
+
+static inline enum ni_gpct_register NITIO_Gi_Autoincrement_Reg(unsigned
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Autoincrement_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Autoincrement_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Autoincrement_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Autoincrement_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Command_Reg(unsigned counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Command_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Command_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Command_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Command_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Counting_Mode_Reg(unsigned
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Counting_Mode_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Counting_Mode_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Counting_Mode_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Counting_Mode_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Input_Select_Reg(unsigned
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Input_Select_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Input_Select_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Input_Select_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Input_Select_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gxx_Joint_Reset_Reg(unsigned
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ case 1:
+ return NITIO_G01_Joint_Reset_Reg;
+ break;
+ case 2:
+ case 3:
+ return NITIO_G23_Joint_Reset_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gxx_Joint_Status1_Reg(unsigned
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ case 1:
+ return NITIO_G01_Joint_Status1_Reg;
+ break;
+ case 2:
+ case 3:
+ return NITIO_G23_Joint_Status1_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gxx_Joint_Status2_Reg(unsigned
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ case 1:
+ return NITIO_G01_Joint_Status2_Reg;
+ break;
+ case 2:
+ case 3:
+ return NITIO_G23_Joint_Status2_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gxx_Status_Reg(unsigned counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ case 1:
+ return NITIO_G01_Status_Reg;
+ break;
+ case 2:
+ case 3:
+ return NITIO_G23_Status_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_LoadA_Reg(unsigned counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_LoadA_Reg;
+ break;
+ case 1:
+ return NITIO_G1_LoadA_Reg;
+ break;
+ case 2:
+ return NITIO_G2_LoadA_Reg;
+ break;
+ case 3:
+ return NITIO_G3_LoadA_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_LoadB_Reg(unsigned counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_LoadB_Reg;
+ break;
+ case 1:
+ return NITIO_G1_LoadB_Reg;
+ break;
+ case 2:
+ return NITIO_G2_LoadB_Reg;
+ break;
+ case 3:
+ return NITIO_G3_LoadB_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Mode_Reg(unsigned counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Mode_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Mode_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Mode_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Mode_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_SW_Save_Reg(int counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_SW_Save_Reg;
+ break;
+ case 1:
+ return NITIO_G1_SW_Save_Reg;
+ break;
+ case 2:
+ return NITIO_G2_SW_Save_Reg;
+ break;
+ case 3:
+ return NITIO_G3_SW_Save_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Second_Gate_Reg(int counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Second_Gate_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Second_Gate_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Second_Gate_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Second_Gate_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_DMA_Config_Reg(int counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_DMA_Config_Reg;
+ break;
+ case 1:
+ return NITIO_G1_DMA_Config_Reg;
+ break;
+ case 2:
+ return NITIO_G2_DMA_Config_Reg;
+ break;
+ case 3:
+ return NITIO_G3_DMA_Config_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_DMA_Status_Reg(int counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_DMA_Status_Reg;
+ break;
+ case 1:
+ return NITIO_G1_DMA_Status_Reg;
+ break;
+ case 2:
+ return NITIO_G2_DMA_Status_Reg;
+ break;
+ case 3:
+ return NITIO_G3_DMA_Status_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_ABZ_Reg(int counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_ABZ_Reg;
+ break;
+ case 1:
+ return NITIO_G1_ABZ_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Interrupt_Acknowledge_Reg(int
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Interrupt_Acknowledge_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Interrupt_Acknowledge_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Interrupt_Acknowledge_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Interrupt_Acknowledge_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Status_Reg(int counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Status_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Status_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Status_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Status_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Interrupt_Enable_Reg(int
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Interrupt_Enable_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Interrupt_Enable_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Interrupt_Enable_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Interrupt_Enable_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+enum Gi_Auto_Increment_Reg_Bits {
+ Gi_Auto_Increment_Mask = 0xff
+};
+
+#define Gi_Up_Down_Shift 5
+enum Gi_Command_Reg_Bits {
+ Gi_Arm_Bit = 0x1,
+ Gi_Save_Trace_Bit = 0x2,
+ Gi_Load_Bit = 0x4,
+ Gi_Disarm_Bit = 0x10,
+ Gi_Up_Down_Mask = 0x3 << Gi_Up_Down_Shift,
+ Gi_Always_Down_Bits = 0x0 << Gi_Up_Down_Shift,
+ Gi_Always_Up_Bits = 0x1 << Gi_Up_Down_Shift,
+ Gi_Up_Down_Hardware_IO_Bits = 0x2 << Gi_Up_Down_Shift,
+ Gi_Up_Down_Hardware_Gate_Bits = 0x3 << Gi_Up_Down_Shift,
+ Gi_Write_Switch_Bit = 0x80,
+ Gi_Synchronize_Gate_Bit = 0x100,
+ Gi_Little_Big_Endian_Bit = 0x200,
+ Gi_Bank_Switch_Start_Bit = 0x400,
+ Gi_Bank_Switch_Mode_Bit = 0x800,
+ Gi_Bank_Switch_Enable_Bit = 0x1000,
+ Gi_Arm_Copy_Bit = 0x2000,
+ Gi_Save_Trace_Copy_Bit = 0x4000,
+ Gi_Disarm_Copy_Bit = 0x8000
+};
+
+#define Gi_Index_Phase_Bitshift 5
+#define Gi_HW_Arm_Select_Shift 8
+enum Gi_Counting_Mode_Reg_Bits {
+ Gi_Counting_Mode_Mask = 0x7,
+ Gi_Counting_Mode_Normal_Bits = 0x0,
+ Gi_Counting_Mode_QuadratureX1_Bits = 0x1,
+ Gi_Counting_Mode_QuadratureX2_Bits = 0x2,
+ Gi_Counting_Mode_QuadratureX4_Bits = 0x3,
+ Gi_Counting_Mode_Two_Pulse_Bits = 0x4,
+ Gi_Counting_Mode_Sync_Source_Bits = 0x6,
+ Gi_Index_Mode_Bit = 0x10,
+ Gi_Index_Phase_Mask = 0x3 << Gi_Index_Phase_Bitshift,
+ Gi_Index_Phase_LowA_LowB = 0x0 << Gi_Index_Phase_Bitshift,
+ Gi_Index_Phase_LowA_HighB = 0x1 << Gi_Index_Phase_Bitshift,
+ Gi_Index_Phase_HighA_LowB = 0x2 << Gi_Index_Phase_Bitshift,
+ Gi_Index_Phase_HighA_HighB = 0x3 << Gi_Index_Phase_Bitshift,
+ Gi_HW_Arm_Enable_Bit = 0x80, /* from m-series example code, not documented in 660x register level manual */
+ Gi_660x_HW_Arm_Select_Mask = 0x7 << Gi_HW_Arm_Select_Shift, /* from m-series example code, not documented in 660x register level manual */
+ Gi_660x_Prescale_X8_Bit = 0x1000,
+ Gi_M_Series_Prescale_X8_Bit = 0x2000,
+ Gi_M_Series_HW_Arm_Select_Mask = 0x1f << Gi_HW_Arm_Select_Shift,
+ /* must be set for clocks over 40MHz, which includes synchronous counting and quadrature modes */
+ Gi_660x_Alternate_Sync_Bit = 0x2000,
+ Gi_M_Series_Alternate_Sync_Bit = 0x4000,
+ Gi_660x_Prescale_X2_Bit = 0x4000, /* from m-series example code, not documented in 660x register level manual */
+ Gi_M_Series_Prescale_X2_Bit = 0x8000,
+};
+
+#define Gi_Source_Select_Shift 2
+#define Gi_Gate_Select_Shift 7
+enum Gi_Input_Select_Bits {
+ Gi_Read_Acknowledges_Irq = 0x1, // not present on 660x
+ Gi_Write_Acknowledges_Irq = 0x2, // not present on 660x
+ Gi_Source_Select_Mask = 0x7c,
+ Gi_Gate_Select_Mask = 0x1f << Gi_Gate_Select_Shift,
+ Gi_Gate_Select_Load_Source_Bit = 0x1000,
+ Gi_Or_Gate_Bit = 0x2000,
+ Gi_Output_Polarity_Bit = 0x4000, /* set to invert */
+ Gi_Source_Polarity_Bit = 0x8000 /* set to invert */
+};
+
+enum Gi_Mode_Bits {
+ Gi_Gating_Mode_Mask = 0x3,
+ Gi_Gating_Disabled_Bits = 0x0,
+ Gi_Level_Gating_Bits = 0x1,
+ Gi_Rising_Edge_Gating_Bits = 0x2,
+ Gi_Falling_Edge_Gating_Bits = 0x3,
+ Gi_Gate_On_Both_Edges_Bit = 0x4, /* used in conjunction with rising edge gating mode */
+ Gi_Trigger_Mode_for_Edge_Gate_Mask = 0x18,
+ Gi_Edge_Gate_Starts_Stops_Bits = 0x0,
+ Gi_Edge_Gate_Stops_Starts_Bits = 0x8,
+ Gi_Edge_Gate_Starts_Bits = 0x10,
+ Gi_Edge_Gate_No_Starts_or_Stops_Bits = 0x18,
+ Gi_Stop_Mode_Mask = 0x60,
+ Gi_Stop_on_Gate_Bits = 0x00,
+ Gi_Stop_on_Gate_or_TC_Bits = 0x20,
+ Gi_Stop_on_Gate_or_Second_TC_Bits = 0x40,
+ Gi_Load_Source_Select_Bit = 0x80,
+ Gi_Output_Mode_Mask = 0x300,
+ Gi_Output_TC_Pulse_Bits = 0x100,
+ Gi_Output_TC_Toggle_Bits = 0x200,
+ Gi_Output_TC_or_Gate_Toggle_Bits = 0x300,
+ Gi_Counting_Once_Mask = 0xc00,
+ Gi_No_Hardware_Disarm_Bits = 0x000,
+ Gi_Disarm_at_TC_Bits = 0x400,
+ Gi_Disarm_at_Gate_Bits = 0x800,
+ Gi_Disarm_at_TC_or_Gate_Bits = 0xc00,
+ Gi_Loading_On_TC_Bit = 0x1000,
+ Gi_Gate_Polarity_Bit = 0x2000,
+ Gi_Loading_On_Gate_Bit = 0x4000,
+ Gi_Reload_Source_Switching_Bit = 0x8000
+};
+
+#define Gi_Second_Gate_Select_Shift 7
+/*FIXME: m-series has a second gate subselect bit */
+/*FIXME: m-series second gate sources are undocumented (by NI)*/
+enum Gi_Second_Gate_Bits {
+ Gi_Second_Gate_Mode_Bit = 0x1,
+ Gi_Second_Gate_Select_Mask = 0x1f << Gi_Second_Gate_Select_Shift,
+ Gi_Second_Gate_Polarity_Bit = 0x2000,
+ Gi_Second_Gate_Subselect_Bit = 0x4000, /* m-series only */
+ Gi_Source_Subselect_Bit = 0x8000 /* m-series only */
+};
+static inline unsigned Gi_Second_Gate_Select_Bits(unsigned second_gate_select)
+{
+ return (second_gate_select << Gi_Second_Gate_Select_Shift) &
+ Gi_Second_Gate_Select_Mask;
+}
+
+enum Gxx_Status_Bits {
+ G0_Save_Bit = 0x1,
+ G1_Save_Bit = 0x2,
+ G0_Counting_Bit = 0x4,
+ G1_Counting_Bit = 0x8,
+ G0_Next_Load_Source_Bit = 0x10,
+ G1_Next_Load_Source_Bit = 0x20,
+ G0_Stale_Data_Bit = 0x40,
+ G1_Stale_Data_Bit = 0x80,
+ G0_Armed_Bit = 0x100,
+ G1_Armed_Bit = 0x200,
+ G0_No_Load_Between_Gates_Bit = 0x400,
+ G1_No_Load_Between_Gates_Bit = 0x800,
+ G0_TC_Error_Bit = 0x1000,
+ G1_TC_Error_Bit = 0x2000,
+ G0_Gate_Error_Bit = 0x4000,
+ G1_Gate_Error_Bit = 0x8000
+};
+static inline enum Gxx_Status_Bits Gi_Counting_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_Counting_Bit;
+ return G0_Counting_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_Armed_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_Armed_Bit;
+ return G0_Armed_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_Next_Load_Source_Bit(unsigned
+ counter_index)
+{
+ if (counter_index % 2)
+ return G1_Next_Load_Source_Bit;
+ return G0_Next_Load_Source_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_Stale_Data_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_Stale_Data_Bit;
+ return G0_Stale_Data_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_TC_Error_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_TC_Error_Bit;
+ return G0_TC_Error_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_Gate_Error_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_Gate_Error_Bit;
+ return G0_Gate_Error_Bit;
+}
+
+/* joint reset register bits */
+static inline unsigned Gi_Reset_Bit(unsigned counter_index)
+{
+ return 0x1 << (2 + (counter_index % 2));
+}
+
+enum Gxx_Joint_Status2_Bits {
+ G0_Output_Bit = 0x1,
+ G1_Output_Bit = 0x2,
+ G0_HW_Save_Bit = 0x1000,
+ G1_HW_Save_Bit = 0x2000,
+ G0_Permanent_Stale_Bit = 0x4000,
+ G1_Permanent_Stale_Bit = 0x8000
+};
+static inline enum Gxx_Joint_Status2_Bits Gi_Permanent_Stale_Bit(unsigned
+ counter_index)
+{
+ if (counter_index % 2)
+ return G1_Permanent_Stale_Bit;
+ return G0_Permanent_Stale_Bit;
+}
+
+enum Gi_DMA_Config_Reg_Bits {
+ Gi_DMA_Enable_Bit = 0x1,
+ Gi_DMA_Write_Bit = 0x2,
+ Gi_DMA_Int_Bit = 0x4
+};
+
+enum Gi_DMA_Status_Reg_Bits {
+ Gi_DMA_Readbank_Bit = 0x2000,
+ Gi_DRQ_Error_Bit = 0x4000,
+ Gi_DRQ_Status_Bit = 0x8000
+};
+
+enum G02_Interrupt_Acknowledge_Bits {
+ G0_Gate_Error_Confirm_Bit = 0x20,
+ G0_TC_Error_Confirm_Bit = 0x40
+};
+enum G13_Interrupt_Acknowledge_Bits {
+ G1_Gate_Error_Confirm_Bit = 0x2,
+ G1_TC_Error_Confirm_Bit = 0x4
+};
+static inline unsigned Gi_Gate_Error_Confirm_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_Gate_Error_Confirm_Bit;
+ return G0_Gate_Error_Confirm_Bit;
+}
+static inline unsigned Gi_TC_Error_Confirm_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_TC_Error_Confirm_Bit;
+ return G0_TC_Error_Confirm_Bit;
+}
+
+// bits that are the same in G0/G2 and G1/G3 interrupt acknowledge registers
+enum Gxx_Interrupt_Acknowledge_Bits {
+ Gi_TC_Interrupt_Ack_Bit = 0x4000,
+ Gi_Gate_Interrupt_Ack_Bit = 0x8000
+};
+
+enum Gi_Status_Bits {
+ Gi_Gate_Interrupt_Bit = 0x4,
+ Gi_TC_Bit = 0x8,
+ Gi_Interrupt_Bit = 0x8000
+};
+
+enum G02_Interrupt_Enable_Bits {
+ G0_TC_Interrupt_Enable_Bit = 0x40,
+ G0_Gate_Interrupt_Enable_Bit = 0x100
+};
+enum G13_Interrupt_Enable_Bits {
+ G1_TC_Interrupt_Enable_Bit = 0x200,
+ G1_Gate_Interrupt_Enable_Bit = 0x400
+};
+static inline unsigned Gi_Gate_Interrupt_Enable_Bit(unsigned counter_index)
+{
+ unsigned bit;
+
+ if (counter_index % 2) {
+ bit = G1_Gate_Interrupt_Enable_Bit;
+ } else {
+ bit = G0_Gate_Interrupt_Enable_Bit;
+ }
+ return bit;
+}
+
+static inline void write_register(struct ni_gpct *counter, unsigned bits,
+ enum ni_gpct_register reg)
+{
+ BUG_ON(reg >= NITIO_Num_Registers);
+ counter->counter_dev->write_register(counter, bits, reg);
+}
+
+static inline unsigned read_register(struct ni_gpct *counter,
+ enum ni_gpct_register reg)
+{
+ BUG_ON(reg >= NITIO_Num_Registers);
+ return counter->counter_dev->read_register(counter, reg);
+}
+
+static inline int ni_tio_counting_mode_registers_present(
+ const struct ni_gpct_device *counter_dev)
+{
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ return 0;
+ break;
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x:
+ return 1;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline void ni_tio_set_bits_transient(struct ni_gpct *counter,
+ enum ni_gpct_register register_index, unsigned bit_mask,
+ unsigned bit_values, unsigned transient_bit_values)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ unsigned long flags;
+
+ BUG_ON(register_index >= NITIO_Num_Registers);
+ comedi_spin_lock_irqsave(&counter_dev->regs_lock, flags);
+ counter_dev->regs[register_index] &= ~bit_mask;
+ counter_dev->regs[register_index] |= (bit_values & bit_mask);
+ write_register(counter,
+ counter_dev->regs[register_index] | transient_bit_values,
+ register_index);
+ mmiowb();
+ comedi_spin_unlock_irqrestore(&counter_dev->regs_lock, flags);
+}
+
+/* ni_tio_set_bits( ) is for safely writing to registers whose bits may be
+twiddled in interrupt context, or whose software copy may be read in interrupt context.
+*/
+static inline void ni_tio_set_bits(struct ni_gpct *counter,
+ enum ni_gpct_register register_index, unsigned bit_mask,
+ unsigned bit_values)
+{
+ ni_tio_set_bits_transient(counter, register_index, bit_mask, bit_values,
+ 0x0);
+}
+
+/* ni_tio_get_soft_copy( ) is for safely reading the software copy of a register
+whose bits might be modified in interrupt context, or whose software copy
+might need to be read in interrupt context.
+*/
+static inline unsigned ni_tio_get_soft_copy(const struct ni_gpct *counter,
+ enum ni_gpct_register register_index)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ unsigned long flags;
+ unsigned value;
+
+ BUG_ON(register_index >= NITIO_Num_Registers);
+ comedi_spin_lock_irqsave(&counter_dev->regs_lock, flags);
+ value = counter_dev->regs[register_index];
+ comedi_spin_unlock_irqrestore(&counter_dev->regs_lock, flags);
+ return value;
+}
+
+int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger);
+int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
+ unsigned int gate_source);
+
+#endif /* _COMEDI_NI_TIO_INTERNAL_H */
diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c
new file mode 100644
index 00000000000..16a26e73c99
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_tiocmd.c
@@ -0,0 +1,523 @@
+/*
+ comedi/drivers/ni_tiocmd.c
+ Command support for NI general purpose counters
+
+ Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+Driver: ni_tiocmd
+Description: National Instruments general purpose counters command support
+Devices:
+Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
+ Herman.Bruyninckx@mech.kuleuven.ac.be,
+ Wim.Meeussen@mech.kuleuven.ac.be,
+ Klaas.Gadeyne@mech.kuleuven.ac.be,
+ Frank Mori Hess <fmhess@users.sourceforge.net>
+Updated: Fri, 11 Apr 2008 12:32:35 +0100
+Status: works
+
+This module is not used directly by end-users. Rather, it
+is used by other drivers (for example ni_660x and ni_pcimio)
+to provide command support for NI's general purpose counters.
+It was originally split out of ni_tio.c to stop the 'ni_tio'
+module depending on the 'mite' module.
+
+References:
+DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
+DAQ 6601/6602 User Manual (NI 322137B-01)
+340934b.pdf DAQ-STC reference manual
+
+*/
+/*
+TODO:
+ Support use of both banks X and Y
+*/
+
+#include "ni_tio_internal.h"
+#include "mite.h"
+
+MODULE_AUTHOR("Comedi <comedi@comedi.org>");
+MODULE_DESCRIPTION("Comedi command support for NI general-purpose counters");
+MODULE_LICENSE("GPL");
+
+static void ni_tio_configure_dma(struct ni_gpct *counter, short enable,
+ short read_not_write)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ unsigned input_select_bits = 0;
+
+ if (enable) {
+ if (read_not_write) {
+ input_select_bits |= Gi_Read_Acknowledges_Irq;
+ } else {
+ input_select_bits |= Gi_Write_Acknowledges_Irq;
+ }
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Input_Select_Reg(counter->counter_index),
+ Gi_Read_Acknowledges_Irq | Gi_Write_Acknowledges_Irq,
+ input_select_bits);
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ break;
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x:
+ {
+ unsigned gi_dma_config_bits = 0;
+
+ if (enable) {
+ gi_dma_config_bits |= Gi_DMA_Enable_Bit;
+ gi_dma_config_bits |= Gi_DMA_Int_Bit;
+ }
+ if (read_not_write == 0) {
+ gi_dma_config_bits |= Gi_DMA_Write_Bit;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_DMA_Config_Reg(counter->counter_index),
+ Gi_DMA_Enable_Bit | Gi_DMA_Int_Bit |
+ Gi_DMA_Write_Bit, gi_dma_config_bits);
+ }
+ break;
+ }
+}
+
+static int ni_tio_input_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ unsigned long flags;
+ int retval = 0;
+ struct ni_gpct *counter = s->private;
+
+ BUG_ON(counter == NULL);
+ if (trignum != 0)
+ return -EINVAL;
+
+ comedi_spin_lock_irqsave(&counter->lock, flags);
+ if (counter->mite_chan)
+ mite_dma_arm(counter->mite_chan);
+ else
+ retval = -EIO;
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+ if (retval < 0)
+ return retval;
+ retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
+ s->async->inttrig = NULL;
+
+ return retval;
+}
+
+static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ struct comedi_cmd *cmd = &async->cmd;
+ int retval = 0;
+
+ /* write alloc the entire buffer */
+ comedi_buf_write_alloc(async, async->prealloc_bufsz);
+ counter->mite_chan->dir = COMEDI_INPUT;
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x:
+ mite_prep_dma(counter->mite_chan, 32, 32);
+ break;
+ case ni_gpct_variant_e_series:
+ mite_prep_dma(counter->mite_chan, 16, 32);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index),
+ Gi_Save_Trace_Bit, 0);
+ ni_tio_configure_dma(counter, 1, 1);
+ switch (cmd->start_src) {
+ case TRIG_NOW:
+ async->inttrig = NULL;
+ mite_dma_arm(counter->mite_chan);
+ retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
+ break;
+ case TRIG_INT:
+ async->inttrig = &ni_tio_input_inttrig;
+ break;
+ case TRIG_EXT:
+ async->inttrig = NULL;
+ mite_dma_arm(counter->mite_chan);
+ retval = ni_tio_arm(counter, 1, cmd->start_arg);
+ case TRIG_OTHER:
+ async->inttrig = NULL;
+ mite_dma_arm(counter->mite_chan);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return retval;
+}
+
+static int ni_tio_output_cmd(struct ni_gpct *counter, struct comedi_async *async)
+{
+ rt_printk("ni_tio: output commands not yet implemented.\n");
+ return -ENOTSUPP;
+
+ counter->mite_chan->dir = COMEDI_OUTPUT;
+ mite_prep_dma(counter->mite_chan, 32, 32);
+ ni_tio_configure_dma(counter, 1, 0);
+ mite_dma_arm(counter->mite_chan);
+ return ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
+}
+
+static int ni_tio_cmd_setup(struct ni_gpct *counter, struct comedi_async *async)
+{
+ struct comedi_cmd *cmd = &async->cmd;
+ int set_gate_source = 0;
+ unsigned gate_source;
+ int retval = 0;
+
+ if (cmd->scan_begin_src == TRIG_EXT) {
+ set_gate_source = 1;
+ gate_source = cmd->scan_begin_arg;
+ } else if (cmd->convert_src == TRIG_EXT) {
+ set_gate_source = 1;
+ gate_source = cmd->convert_arg;
+ }
+ if (set_gate_source) {
+ retval = ni_tio_set_gate_src(counter, 0, gate_source);
+ }
+ if (cmd->flags & TRIG_WAKE_EOS) {
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index),
+ Gi_Gate_Interrupt_Enable_Bit(counter->counter_index),
+ Gi_Gate_Interrupt_Enable_Bit(counter->counter_index));
+ }
+ return retval;
+}
+
+int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async)
+{
+ struct comedi_cmd *cmd = &async->cmd;
+ int retval = 0;
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&counter->lock, flags);
+ if (counter->mite_chan == NULL) {
+ rt_printk
+ ("ni_tio: commands only supported with DMA. Interrupt-driven commands not yet implemented.\n");
+ retval = -EIO;
+ } else {
+ retval = ni_tio_cmd_setup(counter, async);
+ if (retval == 0) {
+ if (cmd->flags & CMDF_WRITE) {
+ retval = ni_tio_output_cmd(counter, async);
+ } else {
+ retval = ni_tio_input_cmd(counter, async);
+ }
+ }
+ }
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+ return retval;
+}
+
+int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int sources;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ sources = TRIG_NOW | TRIG_INT | TRIG_OTHER;
+ if (ni_tio_counting_mode_registers_present(counter->counter_dev))
+ sources |= TRIG_EXT;
+ cmd->start_src &= sources;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_EXT | TRIG_OTHER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ sources = TRIG_NOW | TRIG_EXT | TRIG_OTHER;
+ cmd->convert_src &= sources;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique... */
+
+ if (cmd->start_src != TRIG_NOW &&
+ cmd->start_src != TRIG_INT &&
+ cmd->start_src != TRIG_EXT && cmd->start_src != TRIG_OTHER)
+ err++;
+ if (cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->scan_begin_src != TRIG_EXT &&
+ cmd->scan_begin_src != TRIG_OTHER)
+ err++;
+ if (cmd->convert_src != TRIG_OTHER &&
+ cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_NONE)
+ err++;
+ /* ... and mutually compatible */
+ if (cmd->convert_src != TRIG_NOW && cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+ if (cmd->start_src != TRIG_EXT) {
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->scan_begin_src != TRIG_EXT) {
+ if (cmd->scan_begin_arg) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->convert_src != TRIG_EXT) {
+ if (cmd->convert_arg) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if (cmd->stop_src == TRIG_NONE) {
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+int ni_tio_cancel(struct ni_gpct *counter)
+{
+ unsigned long flags;
+
+ ni_tio_arm(counter, 0, 0);
+ comedi_spin_lock_irqsave(&counter->lock, flags);
+ if (counter->mite_chan) {
+ mite_dma_disarm(counter->mite_chan);
+ }
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+ ni_tio_configure_dma(counter, 0, 0);
+
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index),
+ Gi_Gate_Interrupt_Enable_Bit(counter->counter_index), 0x0);
+ return 0;
+}
+
+ /* During buffered input counter operation for e-series, the gate interrupt is acked
+ automatically by the dma controller, due to the Gi_Read/Write_Acknowledges_IRQ bits
+ in the input select register. */
+static int should_ack_gate(struct ni_gpct *counter)
+{
+ unsigned long flags;
+ int retval = 0;
+
+ switch (counter->counter_dev->variant) {
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x: // not sure if 660x really supports gate interrupts (the bits are not listed in register-level manual)
+ return 1;
+ break;
+ case ni_gpct_variant_e_series:
+ comedi_spin_lock_irqsave(&counter->lock, flags);
+ {
+ if (counter->mite_chan == NULL ||
+ counter->mite_chan->dir != COMEDI_INPUT ||
+ (mite_done(counter->mite_chan))) {
+ retval = 1;
+ }
+ }
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+ break;
+ }
+ return retval;
+}
+
+void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
+ int *tc_error, int *perm_stale_data, int *stale_data)
+{
+ const unsigned short gxx_status = read_register(counter,
+ NITIO_Gxx_Status_Reg(counter->counter_index));
+ const unsigned short gi_status = read_register(counter,
+ NITIO_Gi_Status_Reg(counter->counter_index));
+ unsigned ack = 0;
+
+ if (gate_error)
+ *gate_error = 0;
+ if (tc_error)
+ *tc_error = 0;
+ if (perm_stale_data)
+ *perm_stale_data = 0;
+ if (stale_data)
+ *stale_data = 0;
+
+ if (gxx_status & Gi_Gate_Error_Bit(counter->counter_index)) {
+ ack |= Gi_Gate_Error_Confirm_Bit(counter->counter_index);
+ if (gate_error) {
+ /*660x don't support automatic acknowledgement of gate interrupt via dma read/write
+ and report bogus gate errors */
+ if (counter->counter_dev->variant !=
+ ni_gpct_variant_660x) {
+ *gate_error = 1;
+ }
+ }
+ }
+ if (gxx_status & Gi_TC_Error_Bit(counter->counter_index)) {
+ ack |= Gi_TC_Error_Confirm_Bit(counter->counter_index);
+ if (tc_error)
+ *tc_error = 1;
+ }
+ if (gi_status & Gi_TC_Bit) {
+ ack |= Gi_TC_Interrupt_Ack_Bit;
+ }
+ if (gi_status & Gi_Gate_Interrupt_Bit) {
+ if (should_ack_gate(counter))
+ ack |= Gi_Gate_Interrupt_Ack_Bit;
+ }
+ if (ack)
+ write_register(counter, ack,
+ NITIO_Gi_Interrupt_Acknowledge_Reg(counter->
+ counter_index));
+ if (ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Mode_Reg(counter->
+ counter_index)) & Gi_Loading_On_Gate_Bit) {
+ if (gxx_status & Gi_Stale_Data_Bit(counter->counter_index)) {
+ if (stale_data)
+ *stale_data = 1;
+ }
+ if (read_register(counter,
+ NITIO_Gxx_Joint_Status2_Reg(counter->
+ counter_index)) &
+ Gi_Permanent_Stale_Bit(counter->counter_index)) {
+ rt_printk("%s: Gi_Permanent_Stale_Data detected.\n",
+ __FUNCTION__);
+ if (perm_stale_data)
+ *perm_stale_data = 1;
+ }
+ }
+}
+
+void ni_tio_handle_interrupt(struct ni_gpct *counter, struct comedi_subdevice * s)
+{
+ unsigned gpct_mite_status;
+ unsigned long flags;
+ int gate_error;
+ int tc_error;
+ int perm_stale_data;
+
+ ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error,
+ &perm_stale_data, NULL);
+ if (gate_error) {
+ rt_printk("%s: Gi_Gate_Error detected.\n", __FUNCTION__);
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+ if (perm_stale_data) {
+ s->async->events |= COMEDI_CB_ERROR;
+ }
+ switch (counter->counter_dev->variant) {
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x:
+ if (read_register(counter,
+ NITIO_Gi_DMA_Status_Reg(counter->
+ counter_index)) & Gi_DRQ_Error_Bit) {
+ rt_printk("%s: Gi_DRQ_Error detected.\n", __FUNCTION__);
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+ break;
+ case ni_gpct_variant_e_series:
+ break;
+ }
+ comedi_spin_lock_irqsave(&counter->lock, flags);
+ if (counter->mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+ return;
+ }
+ gpct_mite_status = mite_get_status(counter->mite_chan);
+ if (gpct_mite_status & CHSR_LINKC) {
+ writel(CHOR_CLRLC,
+ counter->mite_chan->mite->mite_io_addr +
+ MITE_CHOR(counter->mite_chan->channel));
+ }
+ mite_sync_input_dma(counter->mite_chan, s->async);
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+}
+
+void ni_tio_set_mite_channel(struct ni_gpct *counter,
+ struct mite_channel *mite_chan)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&counter->lock, flags);
+ counter->mite_chan = mite_chan;
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+}
+
+static int __init ni_tiocmd_init_module(void)
+{
+ return 0;
+}
+
+module_init(ni_tiocmd_init_module);
+
+static void __exit ni_tiocmd_cleanup_module(void)
+{
+}
+
+module_exit(ni_tiocmd_cleanup_module);
+
+EXPORT_SYMBOL_GPL(ni_tio_cmd);
+EXPORT_SYMBOL_GPL(ni_tio_cmdtest);
+EXPORT_SYMBOL_GPL(ni_tio_cancel);
+EXPORT_SYMBOL_GPL(ni_tio_handle_interrupt);
+EXPORT_SYMBOL_GPL(ni_tio_set_mite_channel);
+EXPORT_SYMBOL_GPL(ni_tio_acknowledge_and_confirm);
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
new file mode 100644
index 00000000000..ce42506d47b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -0,0 +1,623 @@
+/*
+ comedi/drivers/pcl711.c
+ hardware driver for PC-LabCard PCL-711 and AdSys ACL-8112
+ and compatibles
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+ Janne Jalkanen <jalkanen@cs.hut.fi>
+ Eric Bunn <ebu@cs.hut.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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.
+
+ */
+/*
+Driver: pcl711
+Description: Advantech PCL-711 and 711b, ADLink ACL-8112
+Author: ds, Janne Jalkanen <jalkanen@cs.hut.fi>, Eric Bunn <ebu@cs.hut.fi>
+Status: mostly complete
+Devices: [Advantech] PCL-711 (pcl711), PCL-711B (pcl711b),
+ [AdLink] ACL-8112HG (acl8112hg), ACL-8112DG (acl8112dg)
+
+Since these boards do not have DMA or FIFOs, only immediate mode is
+supported.
+
+*/
+
+/*
+ Dave Andruczyk <dave@tech.buffalostate.edu> also wrote a
+ driver for the PCL-711. I used a few ideas from his driver
+ here. His driver also has more comments, if you are
+ interested in understanding how this driver works.
+ http://tech.buffalostate.edu/~dave/driver/
+
+ The ACL-8112 driver was hacked from the sources of the PCL-711
+ driver (the 744 chip used on the 8112 is almost the same as
+ the 711b chip, but it has more I/O channels) by
+ Janne Jalkanen (jalkanen@cs.hut.fi) and
+ Erik Bunn (ebu@cs.hut.fi). Remerged with the PCL-711 driver
+ by ds.
+
+ [acl-8112]
+ This driver supports both TRIGNOW and TRIGCLK,
+ but does not yet support DMA transfers. It also supports
+ both high (HG) and low (DG) versions of the card, though
+ the HG version has been untested.
+
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include "8253.h"
+
+#define PCL711_SIZE 16
+
+#define PCL711_CTR0 0
+#define PCL711_CTR1 1
+#define PCL711_CTR2 2
+#define PCL711_CTRCTL 3
+#define PCL711_AD_LO 4
+#define PCL711_DA0_LO 4
+#define PCL711_AD_HI 5
+#define PCL711_DA0_HI 5
+#define PCL711_DI_LO 6
+#define PCL711_DA1_LO 6
+#define PCL711_DI_HI 7
+#define PCL711_DA1_HI 7
+#define PCL711_CLRINTR 8
+#define PCL711_GAIN 9
+#define PCL711_MUX 10
+#define PCL711_MODE 11
+#define PCL711_SOFTTRIG 12
+#define PCL711_DO_LO 13
+#define PCL711_DO_HI 14
+
+static const struct comedi_lrange range_pcl711b_ai = { 5, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ BIP_RANGE(0.3125)
+ }
+};
+static const struct comedi_lrange range_acl8112hg_ai = { 12, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.005),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01),
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.01)
+ }
+};
+static const struct comedi_lrange range_acl8112dg_ai = { 9, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ BIP_RANGE(10)
+ }
+};
+
+/*
+ * flags
+ */
+
+#define PCL711_TIMEOUT 100
+#define PCL711_DRDY 0x10
+
+static const int i8253_osc_base = 500; /* 2 Mhz */
+
+struct pcl711_board {
+
+ const char *name;
+ int is_pcl711b;
+ int is_8112;
+ int is_dg;
+ int n_ranges;
+ int n_aichan;
+ int n_aochan;
+ int maxirq;
+ const struct comedi_lrange *ai_range_type;
+};
+
+
+static const struct pcl711_board boardtypes[] = {
+ {"pcl711", 0, 0, 0, 5, 8, 1, 0, &range_bipolar5},
+ {"pcl711b", 1, 0, 0, 5, 8, 1, 7, &range_pcl711b_ai},
+ {"acl8112hg", 0, 1, 0, 12, 16, 2, 15, &range_acl8112hg_ai},
+ {"acl8112dg", 0, 1, 1, 9, 16, 2, 15, &range_acl8112dg_ai},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl711_board))
+#define this_board ((const struct pcl711_board *)dev->board_ptr)
+
+static int pcl711_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl711_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcl711 = {
+ driver_name:"pcl711",
+ module:THIS_MODULE,
+ attach:pcl711_attach,
+ detach:pcl711_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl711_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl711);
+
+struct pcl711_private {
+
+ int board;
+ int adchan;
+ int ntrig;
+ int aip[8];
+ int mode;
+ unsigned int ao_readback[2];
+ unsigned int divisor1;
+ unsigned int divisor2;
+};
+
+
+#define devpriv ((struct pcl711_private *)dev->private)
+
+static irqreturn_t pcl711_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ int lo, hi;
+ int data;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+
+ if (!dev->attached) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_HANDLED;
+ }
+
+ hi = inb(dev->iobase + PCL711_AD_HI);
+ lo = inb(dev->iobase + PCL711_AD_LO);
+ outb(0, dev->iobase + PCL711_CLRINTR);
+
+ data = (hi << 8) | lo;
+
+ /* FIXME! Nothing else sets ntrig! */
+ if (!(--devpriv->ntrig)) {
+ if (this_board->is_8112) {
+ outb(1, dev->iobase + PCL711_MODE);
+ } else {
+ outb(0, dev->iobase + PCL711_MODE);
+ }
+
+ s->async->events |= COMEDI_CB_EOA;
+ }
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+static void pcl711_set_changain(struct comedi_device * dev, int chan)
+{
+ int chan_register;
+
+ outb(CR_RANGE(chan), dev->iobase + PCL711_GAIN);
+
+ chan_register = CR_CHAN(chan);
+
+ if (this_board->is_8112) {
+
+ /*
+ * Set the correct channel. The two channel banks are switched
+ * using the mask value.
+ * NB: To use differential channels, you should use mask = 0x30,
+ * but I haven't written the support for this yet. /JJ
+ */
+
+ if (chan_register >= 8) {
+ chan_register = 0x20 | (chan_register & 0x7);
+ } else {
+ chan_register |= 0x10;
+ }
+ } else {
+ outb(chan_register, dev->iobase + PCL711_MUX);
+ }
+}
+
+static int pcl711_ai_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int hi, lo;
+
+ pcl711_set_changain(dev, insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ /*
+ * Write the correct mode (software polling) and start polling by writing
+ * to the trigger register
+ */
+ outb(1, dev->iobase + PCL711_MODE);
+
+ if (this_board->is_8112) {
+ } else {
+ outb(0, dev->iobase + PCL711_SOFTTRIG);
+ }
+
+ i = PCL711_TIMEOUT;
+ while (--i) {
+ hi = inb(dev->iobase + PCL711_AD_HI);
+ if (!(hi & PCL711_DRDY))
+ goto ok;
+ comedi_udelay(1);
+ }
+ rt_printk("comedi%d: pcl711: A/D timeout\n", dev->minor);
+ return -ETIME;
+
+ ok:
+ lo = inb(dev->iobase + PCL711_AD_LO);
+
+ data[n] = ((hi & 0xf) << 8) | lo;
+ }
+
+ return n;
+}
+
+static int pcl711_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int tmp;
+ int err = 0;
+
+ /* step 1 */
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2 */
+
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3 */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_src == TRIG_EXT) {
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ } else {
+#define MAX_SPEED 1000
+#define TIMER_BASE 100
+ if (cmd->scan_begin_arg < MAX_SPEED) {
+ cmd->scan_begin_arg = MAX_SPEED;
+ err++;
+ }
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_NONE) {
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ } else {
+ /* ignore */
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4 */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &devpriv->divisor1, &devpriv->divisor2,
+ &cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int pcl711_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int timer1, timer2;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ pcl711_set_changain(dev, cmd->chanlist[0]);
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /*
+ * Set timers
+ * timer chip is an 8253, with timers 1 and 2
+ * cascaded
+ * 0x74 = Select Counter 1 | LSB/MSB | Mode=2 | Binary
+ * Mode 2 = Rate generator
+ *
+ * 0xb4 = Select Counter 2 | LSB/MSB | Mode=2 | Binary
+ */
+
+ i8253_cascade_ns_to_timer(i8253_osc_base, &timer1, &timer2,
+ &cmd->scan_begin_arg, TRIG_ROUND_NEAREST);
+
+ outb(0x74, dev->iobase + PCL711_CTRCTL);
+ outb(timer1 & 0xff, dev->iobase + PCL711_CTR1);
+ outb((timer1 >> 8) & 0xff, dev->iobase + PCL711_CTR1);
+ outb(0xb4, dev->iobase + PCL711_CTRCTL);
+ outb(timer2 & 0xff, dev->iobase + PCL711_CTR2);
+ outb((timer2 >> 8) & 0xff, dev->iobase + PCL711_CTR2);
+
+ /* clear pending interrupts (just in case) */
+ outb(0, dev->iobase + PCL711_CLRINTR);
+
+ /*
+ * Set mode to IRQ transfer
+ */
+ outb(devpriv->mode | 6, dev->iobase + PCL711_MODE);
+ } else {
+ /* external trigger */
+ outb(devpriv->mode | 3, dev->iobase + PCL711_MODE);
+ }
+
+ return 0;
+}
+
+/*
+ analog output
+*/
+static int pcl711_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ outb((data[n] & 0xff),
+ dev->iobase + (chan ? PCL711_DA1_LO : PCL711_DA0_LO));
+ outb((data[n] >> 8),
+ dev->iobase + (chan ? PCL711_DA1_HI : PCL711_DA0_HI));
+
+ devpriv->ao_readback[chan] = data[n];
+ }
+
+ return n;
+}
+
+static int pcl711_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ data[n] = devpriv->ao_readback[chan];
+ }
+
+ return n;
+
+}
+
+/* Digital port read - Untested on 8112 */
+static int pcl711_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + PCL711_DI_LO) |
+ (inb(dev->iobase + PCL711_DI_HI) << 8);
+
+ return 2;
+}
+
+/* Digital port write - Untested on 8112 */
+static int pcl711_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ }
+ if (data[0] & 0x00ff)
+ outb(s->state & 0xff, dev->iobase + PCL711_DO_LO);
+ if (data[0] & 0xff00)
+ outb((s->state >> 8), dev->iobase + PCL711_DO_HI);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+/* Free any resources that we have claimed */
+static int pcl711_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pcl711: remove\n", dev->minor);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (dev->iobase)
+ release_region(dev->iobase, PCL711_SIZE);
+
+ return 0;
+}
+
+/* Initialization */
+static int pcl711_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ unsigned long iobase;
+ unsigned int irq;
+ struct comedi_subdevice *s;
+
+ /* claim our I/O space */
+
+ iobase = it->options[0];
+ printk("comedi%d: pcl711: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, PCL711_SIZE, "pcl711")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* there should be a sanity check here */
+
+ /* set up some name stuff */
+ dev->board_name = this_board->name;
+
+ /* grab our IRQ */
+ irq = it->options[1];
+ if (irq > this_board->maxirq) {
+ printk("irq out of range\n");
+ return -EINVAL;
+ }
+ if (irq) {
+ if (comedi_request_irq(irq, pcl711_interrupt, 0, "pcl711", dev)) {
+ printk("unable to allocate irq %u\n", irq);
+ return -EINVAL;
+ } else {
+ printk("( irq = %u )\n", irq);
+ }
+ }
+ dev->irq = irq;
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct pcl711_private))) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ /* AI subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = this_board->n_aichan;
+ s->maxdata = 0xfff;
+ s->len_chanlist = 1;
+ s->range_table = this_board->ai_range_type;
+ s->insn_read = pcl711_ai_insn;
+ if (irq) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmdtest = pcl711_ai_cmdtest;
+ s->do_cmd = pcl711_ai_cmd;
+ }
+
+ s++;
+ /* AO subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = 0xfff;
+ s->len_chanlist = 1;
+ s->range_table = &range_bipolar5;
+ s->insn_write = pcl711_ao_insn;
+ s->insn_read = pcl711_ao_insn_read;
+
+ s++;
+ /* 16-bit digital input */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->len_chanlist = 16;
+ s->range_table = &range_digital;
+ s->insn_bits = pcl711_di_insn_bits;
+
+ s++;
+ /* 16-bit digital out */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->len_chanlist = 16;
+ s->range_table = &range_digital;
+ s->state = 0;
+ s->insn_bits = pcl711_do_insn_bits;
+
+ /*
+ this is the "base value" for the mode register, which is
+ used for the irq on the PCL711
+ */
+ if (this_board->is_pcl711b) {
+ devpriv->mode = (dev->irq << 4);
+ }
+
+ /* clear DAC */
+ outb(0, dev->iobase + PCL711_DA0_LO);
+ outb(0, dev->iobase + PCL711_DA0_HI);
+ outb(0, dev->iobase + PCL711_DA1_LO);
+ outb(0, dev->iobase + PCL711_DA1_HI);
+
+ printk("\n");
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c
new file mode 100644
index 00000000000..cd1e784f25f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl724.c
@@ -0,0 +1,222 @@
+/*
+ comedi/drivers/pcl724.c
+
+ Michal Dobes <dobes@tesnet.cz>
+
+ hardware driver for Advantech cards:
+ card: PCL-724, PCL-722, PCL-731
+ driver: pcl724, pcl722, pcl731
+ and ADLink cards:
+ card: ACL-7122, ACL-7124, PET-48DIO
+ driver: acl7122, acl7124, pet48dio
+
+ Options for PCL-724, PCL-731, ACL-7124 and PET-48DIO:
+ [0] - IO Base
+
+ Options for PCL-722 and ACL-7122:
+ [0] - IO Base
+ [1] - IRQ (0=disable IRQ) IRQ isn't supported at this time!
+ [2] -number of DIO:
+ 0, 144: 144 DIO configuration
+ 1, 96: 96 DIO configuration
+*/
+/*
+Driver: pcl724
+Description: Advantech PCL-724, PCL-722, PCL-731 ADLink ACL-7122, ACL-7124,
+ PET-48DIO
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCL-724 (pcl724), PCL-722 (pcl722), PCL-731 (pcl731),
+ [ADLink] ACL-7122 (acl7122), ACL-7124 (acl7124), PET-48DIO (pet48dio)
+Status: untested
+
+This is driver for digital I/O boards PCL-722/724/731 with 144/24/48 DIO
+and for digital I/O boards ACL-7122/7124/PET-48DIO with 144/24/48 DIO.
+It need 8255.o for operations and only immediate mode is supported.
+See the source for configuration details.
+*/
+/*
+ * check_driver overrides:
+ * struct comedi_insn
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include "8255.h"
+
+#define PCL722_SIZE 32
+#define PCL722_96_SIZE 16
+#define PCL724_SIZE 4
+#define PCL731_SIZE 8
+#define PET48_SIZE 2
+
+#define SIZE_8255 4
+
+// #define PCL724_IRQ 1 /* no IRQ support now */
+
+static int pcl724_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl724_detach(struct comedi_device * dev);
+
+struct pcl724_board {
+
+ const char *name; // board name
+ int dio; // num of DIO
+ int numofports; // num of 8255 subdevices
+ unsigned int IRQbits; // allowed interrupts
+ unsigned int io_range; // len of IO space
+ char can_have96;
+ char is_pet48;
+};
+
+
+static const struct pcl724_board boardtypes[] = {
+ {"pcl724", 24, 1, 0x00fc, PCL724_SIZE, 0, 0,},
+ {"pcl722", 144, 6, 0x00fc, PCL722_SIZE, 1, 0,},
+ {"pcl731", 48, 2, 0x9cfc, PCL731_SIZE, 0, 0,},
+ {"acl7122", 144, 6, 0x9ee8, PCL722_SIZE, 1, 0,},
+ {"acl7124", 24, 1, 0x00fc, PCL724_SIZE, 0, 0,},
+ {"pet48dio", 48, 2, 0x9eb8, PET48_SIZE, 0, 1,},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl724_board))
+#define this_board ((const struct pcl724_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcl724 = {
+ driver_name:"pcl724",
+ module:THIS_MODULE,
+ attach:pcl724_attach,
+ detach:pcl724_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl724_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl724);
+
+static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
+{
+ unsigned long iobase = arg;
+
+ if (dir) {
+ outb(data, iobase + port);
+ return 0;
+ } else {
+ return inb(iobase + port);
+ }
+}
+
+static int subdev_8255mapped_cb(int dir, int port, int data,
+ unsigned long iobase)
+{
+ int movport = SIZE_8255 * (iobase >> 12);
+
+ iobase &= 0x0fff;
+
+ if (dir) {
+ outb(port + movport, iobase);
+ outb(data, iobase + 1);
+ return 0;
+ } else {
+ outb(port + movport, iobase);
+ return inb(iobase + 1);
+ }
+}
+
+static int pcl724_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned long iobase;
+ unsigned int iorange;
+ int ret, i, n_subdevices;
+#ifdef PCL724_IRQ
+ unsigned int irq;
+#endif
+
+ iobase = it->options[0];
+ iorange = this_board->io_range;
+ if ((this_board->can_have96) && ((it->options[1] == 1)
+ || (it->options[1] == 96)))
+ iorange = PCL722_96_SIZE; // PCL-724 in 96 DIO configuration
+ printk("comedi%d: pcl724: board=%s, 0x%03lx ", dev->minor,
+ this_board->name, iobase);
+ if (!request_region(iobase, iorange, "pcl724")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+ dev->board_name = this_board->name;
+
+#ifdef PCL724_IRQ
+ irq = 0;
+ if (this_board->IRQbits != 0) { /* board support IRQ */
+ irq = it->options[1];
+ if (irq) { /* we want to use IRQ */
+ if (((1 << irq) & this_board->IRQbits) == 0) {
+ rt_printk
+ (", IRQ %u is out of allowed range, DISABLING IT",
+ irq);
+ irq = 0; /* Bad IRQ */
+ } else {
+ if (comedi_request_irq(irq, interrupt_pcl724, 0,
+ "pcl724", dev)) {
+ rt_printk
+ (", unable to allocate IRQ %u, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk(", irq=%u", irq);
+ }
+ }
+ }
+ }
+
+ dev->irq = irq;
+#endif
+
+ printk("\n");
+
+ n_subdevices = this_board->numofports;
+ if ((this_board->can_have96) && ((it->options[1] == 1)
+ || (it->options[1] == 96)))
+ n_subdevices = 4; // PCL-724 in 96 DIO configuration
+
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+ return ret;
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ if (this_board->is_pet48) {
+ subdev_8255_init(dev, dev->subdevices + i,
+ subdev_8255mapped_cb,
+ (unsigned long)(dev->iobase + i * 0x1000));
+ } else
+ subdev_8255_init(dev, dev->subdevices + i,
+ subdev_8255_cb,
+ (unsigned long)(dev->iobase + SIZE_8255 * i));
+ };
+
+ return 0;
+}
+
+static int pcl724_detach(struct comedi_device * dev)
+{
+ int i;
+
+// printk("comedi%d: pcl724: remove\n",dev->minor);
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ subdev_8255_cleanup(dev, dev->subdevices + i);
+ }
+
+#ifdef PCL724_IRQ
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+#endif
+
+ release_region(dev->iobase, this_board->io_range);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c
new file mode 100644
index 00000000000..0766ba02bd0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl725.c
@@ -0,0 +1,111 @@
+/*
+ * comedi/drivers/pcl725.c
+ * Driver for PCL725 and clones
+ * David A. Schleef
+ */
+/*
+Driver: pcl725
+Description: Advantech PCL-725 (& compatibles)
+Author: ds
+Status: unknown
+Devices: [Advantech] PCL-725 (pcl725)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define PCL725_SIZE 2
+
+#define PCL725_DO 0
+#define PCL725_DI 1
+
+static int pcl725_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl725_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcl725 = {
+ driver_name:"pcl725",
+ module:THIS_MODULE,
+ attach:pcl725_attach,
+ detach:pcl725_detach,
+};
+
+COMEDI_INITCLEANUP(driver_pcl725);
+
+static int pcl725_do_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ outb(s->state, dev->iobase + PCL725_DO);
+ }
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int pcl725_di_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + PCL725_DI);
+
+ return 2;
+}
+
+static int pcl725_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: pcl725: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, PCL725_SIZE, "pcl725")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->board_name = "pcl725";
+ dev->iobase = iobase;
+ dev->irq = 0;
+
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* do */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcl725_do_insn;
+ s->range_table = &range_digital;
+
+ s = dev->subdevices + 1;
+ /* di */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcl725_di_insn;
+ s->range_table = &range_digital;
+
+ printk("\n");
+
+ return 0;
+}
+
+static int pcl725_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pcl725: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, PCL725_SIZE);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c
new file mode 100644
index 00000000000..6dbd33d7907
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl726.c
@@ -0,0 +1,377 @@
+/*
+ comedi/drivers/pcl726.c
+
+ hardware driver for Advantech cards:
+ card: PCL-726, PCL-727, PCL-728
+ driver: pcl726, pcl727, pcl728
+ and for ADLink cards:
+ card: ACL-6126, ACL-6128
+ driver: acl6126, acl6128
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: pcl726
+Description: Advantech PCL-726 & compatibles
+Author: ds
+Status: untested
+Devices: [Advantech] PCL-726 (pcl726), PCL-727 (pcl727), PCL-728 (pcl728),
+ [ADLink] ACL-6126 (acl6126), ACL-6128 (acl6128)
+
+Interrupts are not supported.
+
+ Options for PCL-726:
+ [0] - IO Base
+ [2]...[7] - D/A output range for channel 1-6:
+ 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+ 4: 4-20mA, 5: unknown (external reference)
+
+ Options for PCL-727:
+ [0] - IO Base
+ [2]...[13] - D/A output range for channel 1-12:
+ 0: 0-5V, 1: 0-10V, 2: +/-5V,
+ 3: 4-20mA
+
+ Options for PCL-728 and ACL-6128:
+ [0] - IO Base
+ [2], [3] - D/A output range for channel 1 and 2:
+ 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+ 4: 4-20mA, 5: 0-20mA
+
+ Options for ACL-6126:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 3, 5, 6, 7, 9, 10, 11, 12, 15) (currently ignored)
+ [2]...[7] - D/A output range for channel 1-6:
+ 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+ 4: 4-20mA
+*/
+
+/*
+ Thanks to Circuit Specialists for having programming info (!) on
+ their web page. (http://www.cir.com/)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#undef ACL6126_IRQ /* no interrupt support (yet) */
+
+#define PCL726_SIZE 16
+#define PCL727_SIZE 32
+#define PCL728_SIZE 8
+
+#define PCL726_DAC0_HI 0
+#define PCL726_DAC0_LO 1
+
+#define PCL726_DO_HI 12
+#define PCL726_DO_LO 13
+#define PCL726_DI_HI 14
+#define PCL726_DI_LO 15
+
+#define PCL727_DO_HI 24
+#define PCL727_DO_LO 25
+#define PCL727_DI_HI 0
+#define PCL727_DI_LO 1
+
+static const struct comedi_lrange range_4_20mA = { 1, {RANGE_mA(4, 20)} };
+static const struct comedi_lrange range_0_20mA = { 1, {RANGE_mA(0, 20)} };
+
+static const struct comedi_lrange *const rangelist_726[] = {
+ &range_unipolar5, &range_unipolar10,
+ &range_bipolar5, &range_bipolar10,
+ &range_4_20mA, &range_unknown
+};
+
+static const struct comedi_lrange *const rangelist_727[] = {
+ &range_unipolar5, &range_unipolar10,
+ &range_bipolar5,
+ &range_4_20mA
+};
+
+static const struct comedi_lrange *const rangelist_728[] = {
+ &range_unipolar5, &range_unipolar10,
+ &range_bipolar5, &range_bipolar10,
+ &range_4_20mA, &range_0_20mA
+};
+
+static int pcl726_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl726_detach(struct comedi_device * dev);
+
+struct pcl726_board {
+
+ const char *name; // driver name
+ int n_aochan; // num of D/A chans
+ int num_of_ranges; // num of ranges
+ unsigned int IRQbits; // allowed interrupts
+ unsigned int io_range; // len of IO space
+ char have_dio; // 1=card have DI/DO ports
+ int di_hi; // ports for DI/DO operations
+ int di_lo;
+ int do_hi;
+ int do_lo;
+ const struct comedi_lrange *const *range_type_list; // list of supported ranges
+};
+
+
+static const struct pcl726_board boardtypes[] = {
+ {"pcl726", 6, 6, 0x0000, PCL726_SIZE, 1,
+ PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
+ &rangelist_726[0],},
+ {"pcl727", 12, 4, 0x0000, PCL727_SIZE, 1,
+ PCL727_DI_HI, PCL727_DI_LO, PCL727_DO_HI, PCL727_DO_LO,
+ &rangelist_727[0],},
+ {"pcl728", 2, 6, 0x0000, PCL728_SIZE, 0,
+ 0, 0, 0, 0,
+ &rangelist_728[0],},
+ {"acl6126", 6, 5, 0x96e8, PCL726_SIZE, 1,
+ PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
+ &rangelist_726[0],},
+ {"acl6128", 2, 6, 0x0000, PCL728_SIZE, 0,
+ 0, 0, 0, 0,
+ &rangelist_728[0],},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl726_board))
+#define this_board ((const struct pcl726_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcl726 = {
+ driver_name:"pcl726",
+ module:THIS_MODULE,
+ attach:pcl726_attach,
+ detach:pcl726_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl726_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl726);
+
+struct pcl726_private {
+
+ int bipolar[12];
+ const struct comedi_lrange *rangelist[12];
+ unsigned int ao_readback[12];
+};
+
+#define devpriv ((struct pcl726_private *)dev->private)
+
+static int pcl726_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int hi, lo;
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ lo = data[n] & 0xff;
+ hi = (data[n] >> 8) & 0xf;
+ if (devpriv->bipolar[chan])
+ hi ^= 0x8;
+ /*
+ * the programming info did not say which order
+ * to write bytes. switch the order of the next
+ * two lines if you get glitches.
+ */
+ outb(hi, dev->iobase + PCL726_DAC0_HI + 2 * chan);
+ outb(lo, dev->iobase + PCL726_DAC0_LO + 2 * chan);
+ devpriv->ao_readback[chan] = data[n];
+ }
+
+ return n;
+}
+
+static int pcl726_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int n;
+
+ for (n = 0; n < insn->n; n++) {
+ data[n] = devpriv->ao_readback[chan];
+ }
+ return n;
+}
+
+static int pcl726_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + this_board->di_lo) |
+ (inb(dev->iobase + this_board->di_hi) << 8);
+
+ return 2;
+}
+
+static int pcl726_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ }
+ if (data[1] & 0x00ff)
+ outb(s->state & 0xff, dev->iobase + this_board->do_lo);
+ if (data[1] & 0xff00)
+ outb((s->state >> 8), dev->iobase + this_board->do_hi);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int pcl726_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+ unsigned int iorange;
+ int ret, i;
+#ifdef ACL6126_IRQ
+ unsigned int irq;
+#endif
+
+ iobase = it->options[0];
+ iorange = this_board->io_range;
+ printk("comedi%d: pcl726: board=%s, 0x%03lx ", dev->minor,
+ this_board->name, iobase);
+ if (!request_region(iobase, iorange, "pcl726")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+ dev->board_name = this_board->name;
+
+ if ((ret = alloc_private(dev, sizeof(struct pcl726_private))) < 0)
+ return -ENOMEM;
+
+ for (i = 0; i < 12; i++) {
+ devpriv->bipolar[i] = 0;
+ devpriv->rangelist[i] = &range_unknown;
+ }
+
+#ifdef ACL6126_IRQ
+ irq = 0;
+ if (boardtypes[board].IRQbits != 0) { /* board support IRQ */
+ irq = it->options[1];
+ devpriv->first_chan = 2;
+ if (irq) { /* we want to use IRQ */
+ if (((1 << irq) & boardtypes[board].IRQbits) == 0) {
+ rt_printk
+ (", IRQ %d is out of allowed range, DISABLING IT",
+ irq);
+ irq = 0; /* Bad IRQ */
+ } else {
+ if (comedi_request_irq(irq, interrupt_pcl818, 0,
+ "pcl726", dev)) {
+ rt_printk
+ (", unable to allocate IRQ %d, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk(", irq=%d", irq);
+ }
+ }
+ }
+ }
+
+ dev->irq = irq;
+#endif
+
+ printk("\n");
+
+ if ((ret = alloc_subdevices(dev, 3)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ /* ao */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = 0xfff;
+ s->len_chanlist = 1;
+ s->insn_write = pcl726_ao_insn;
+ s->insn_read = pcl726_ao_insn_read;
+ s->range_table_list = devpriv->rangelist;
+ for (i = 0; i < this_board->n_aochan; i++) {
+ int j;
+
+ j = it->options[2 + 1];
+ if ((j < 0) || (j >= this_board->num_of_ranges)) {
+ printk("Invalid range for channel %d! Must be 0<=%d<%d\n", i, j, this_board->num_of_ranges - 1);
+ j = 0;
+ }
+ devpriv->rangelist[i] = this_board->range_type_list[j];
+ if (devpriv->rangelist[i]->range[0].min ==
+ -devpriv->rangelist[i]->range[0].max)
+ devpriv->bipolar[i] = 1; /* bipolar range */
+ }
+
+ s = dev->subdevices + 1;
+ /* di */
+ if (!this_board->have_dio) {
+ s->type = COMEDI_SUBD_UNUSED;
+ } else {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->len_chanlist = 1;
+ s->insn_bits = pcl726_di_insn_bits;
+ s->range_table = &range_digital;
+ }
+
+ s = dev->subdevices + 2;
+ /* do */
+ if (!this_board->have_dio) {
+ s->type = COMEDI_SUBD_UNUSED;
+ } else {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->len_chanlist = 1;
+ s->insn_bits = pcl726_do_insn_bits;
+ s->range_table = &range_digital;
+ }
+
+ return 0;
+}
+
+static int pcl726_detach(struct comedi_device * dev)
+{
+// printk("comedi%d: pcl726: remove\n",dev->minor);
+
+#ifdef ACL6126_IRQ
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+#endif
+
+ if (dev->iobase)
+ release_region(dev->iobase, this_board->io_range);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c
new file mode 100644
index 00000000000..f2c6d7c5693
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl730.c
@@ -0,0 +1,168 @@
+/*
+ * comedi/drivers/pcl730.c
+ * Driver for Advantech PCL-730 and clones
+ * José Luis Sánchez
+ */
+/*
+Driver: pcl730
+Description: Advantech PCL-730 (& compatibles)
+Author: José Luis Sánchez (jsanchezv@teleline.es)
+Status: untested
+Devices: [Advantech] PCL-730 (pcl730), [ICP] ISO-730 (iso730),
+ [Adlink] ACL-7130 (acl7130)
+
+Interrupts are not supported.
+The ACL-7130 card have an 8254 timer/counter not supported by this driver.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define PCL730_SIZE 4
+#define ACL7130_SIZE 8
+#define PCL730_IDIO_LO 0 /* Isolated Digital I/O low byte (ID0-ID7) */
+#define PCL730_IDIO_HI 1 /* Isolated Digital I/O high byte (ID8-ID15) */
+#define PCL730_DIO_LO 2 /* TTL Digital I/O low byte (D0-D7) */
+#define PCL730_DIO_HI 3 /* TTL Digital I/O high byte (D8-D15) */
+
+static int pcl730_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl730_detach(struct comedi_device * dev);
+
+struct pcl730_board {
+
+ const char *name; // board name
+ unsigned int io_range; // len of I/O space
+};
+
+
+static const struct pcl730_board boardtypes[] = {
+ {"pcl730", PCL730_SIZE,},
+ {"iso730", PCL730_SIZE,},
+ {"acl7130", ACL7130_SIZE,},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl730_board))
+#define this_board ((const struct pcl730_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcl730 = {
+ driver_name:"pcl730",
+ module:THIS_MODULE,
+ attach:pcl730_attach,
+ detach:pcl730_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl730_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl730);
+
+static int pcl730_do_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ }
+ if (data[0] & 0x00ff)
+ outb(s->state & 0xff,
+ dev->iobase + ((unsigned long)s->private));
+ if (data[0] & 0xff00)
+ outb((s->state >> 8),
+ dev->iobase + ((unsigned long)s->private) + 1);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int pcl730_di_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + ((unsigned long)s->private)) |
+ (inb(dev->iobase + ((unsigned long)s->private) + 1) << 8);
+
+ return 2;
+}
+
+static int pcl730_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+ unsigned int iorange;
+
+ iobase = it->options[0];
+ iorange = this_board->io_range;
+ printk("comedi%d: pcl730: board=%s 0x%04lx ", dev->minor,
+ this_board->name, iobase);
+ if (!request_region(iobase, iorange, "pcl730")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->board_name = this_board->name;
+ dev->iobase = iobase;
+ dev->irq = 0;
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* Isolated do */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = pcl730_do_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)PCL730_IDIO_LO;
+
+ s = dev->subdevices + 1;
+ /* Isolated di */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = pcl730_di_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)PCL730_IDIO_LO;
+
+ s = dev->subdevices + 2;
+ /* TTL do */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = pcl730_do_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)PCL730_DIO_LO;
+
+ s = dev->subdevices + 3;
+ /* TTL di */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = pcl730_di_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)PCL730_DIO_LO;
+
+ printk("\n");
+
+ return 0;
+}
+
+static int pcl730_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pcl730: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, this_board->io_range);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
new file mode 100644
index 00000000000..11dfd230e56
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -0,0 +1,1605 @@
+/*
+ * comedi/drivers/pcl812.c
+ *
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ *
+ * hardware driver for Advantech cards
+ * card: PCL-812, PCL-812PG, PCL-813, PCL-813B
+ * driver: pcl812, pcl812pg, pcl813, pcl813b
+ * and for ADlink cards
+ * card: ACL-8112DG, ACL-8112HG, ACL-8112PG, ACL-8113, ACL-8216
+ * driver: acl8112dg, acl8112hg, acl8112pg, acl8113, acl8216
+ * and for ICP DAS cards
+ * card: ISO-813, A-821PGH, A-821PGL, A-821PGL-NDA, A-822PGH, A-822PGL,
+ * driver: iso813, a821pgh, a-821pgl, a-821pglnda, a822pgh, a822pgl,
+ * card: A-823PGH, A-823PGL, A-826PG
+ * driver: a823pgh, a823pgl, a826pg
+ */
+/*
+Driver: pcl812
+Description: Advantech PCL-812/PG, PCL-813/B,
+ ADLink ACL-8112DG/HG/PG, ACL-8113, ACL-8216,
+ ICP DAS A-821PGH/PGL/PGL-NDA, A-822PGH/PGL, A-823PGH/PGL, A-826PG,
+ ICP DAS ISO-813
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCL-812 (pcl812), PCL-812PG (pcl812pg),
+ PCL-813 (pcl813), PCL-813B (pcl813b), [ADLink] ACL-8112DG (acl8112dg),
+ ACL-8112HG (acl8112hg), ACL-8113 (acl-8113), ACL-8216 (acl8216),
+ [ICP] ISO-813 (iso813), A-821PGH (a821pgh), A-821PGL (a821pgl),
+ A-821PGL-NDA (a821pclnda), A-822PGH (a822pgh), A-822PGL (a822pgl),
+ A-823PGH (a823pgh), A-823PGL (a823pgl), A-826PG (a826pg)
+Updated: Mon, 06 Aug 2007 12:03:15 +0100
+Status: works (I hope. My board fire up under my hands
+ and I cann't test all features.)
+
+This driver supports insn and cmd interfaces. Some boards support only insn
+becouse their hardware don't allow more (PCL-813/B, ACL-8113, ISO-813).
+Data transfer over DMA is supported only when you measure only one
+channel, this is too hardware limitation of these boards.
+
+Options for PCL-812:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0=trigger source is internal 8253 with 2MHz clock
+ 1=trigger source is external
+ [4] - 0=A/D input range is +/-10V
+ 1=A/D input range is +/-5V
+ 2=A/D input range is +/-2.5V
+ 3=A/D input range is +/-1.25V
+ 4=A/D input range is +/-0.625V
+ 5=A/D input range is +/-0.3125V
+ [5] - 0=D/A outputs 0-5V (internal reference -5V)
+ 1=D/A outputs 0-10V (internal reference -10V)
+ 2=D/A outputs unknow (external reference)
+
+Options for PCL-812PG, ACL-8112PG:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0=trigger source is internal 8253 with 2MHz clock
+ 1=trigger source is external
+ [4] - 0=A/D have max +/-5V input
+ 1=A/D have max +/-10V input
+ [5] - 0=D/A outputs 0-5V (internal reference -5V)
+ 1=D/A outputs 0-10V (internal reference -10V)
+ 2=D/A outputs unknow (external reference)
+
+Options for ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH, ACL-8216, A-826PG:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0=trigger source is internal 8253 with 2MHz clock
+ 1=trigger source is external
+ [4] - 0=A/D channels are S.E.
+ 1=A/D channels are DIFF
+ [5] - 0=D/A outputs 0-5V (internal reference -5V)
+ 1=D/A outputs 0-10V (internal reference -10V)
+ 2=D/A outputs unknow (external reference)
+
+Options for A-821PGL/PGH:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - 0=A/D channels are S.E.
+ 1=A/D channels are DIFF
+ [3] - 0=D/A output 0-5V (internal reference -5V)
+ 1=D/A output 0-10V (internal reference -10V)
+
+Options for A-821PGL-NDA:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - 0=A/D channels are S.E.
+ 1=A/D channels are DIFF
+
+Options for PCL-813:
+ [0] - IO Base
+
+Options for PCL-813B:
+ [0] - IO Base
+ [1] - 0= bipolar inputs
+ 1= unipolar inputs
+
+Options for ACL-8113, ISO-813:
+ [0] - IO Base
+ [1] - 0= 10V bipolar inputs
+ 1= 10V unipolar inputs
+ 2= 20V bipolar inputs
+ 3= 20V unipolar inputs
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+
+#undef PCL812_EXTDEBUG /* if this is defined then a lot of messages is printed */
+
+// hardware types of the cards
+#define boardPCL812PG 0 /* and ACL-8112PG */
+#define boardPCL813B 1
+#define boardPCL812 2
+#define boardPCL813 3
+#define boardISO813 5
+#define boardACL8113 6
+#define boardACL8112 7 /* ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH */
+#define boardACL8216 8 /* and ICP DAS A-826PG */
+#define boardA821 9 /* PGH, PGL, PGL/NDA versions */
+
+#define PCLx1x_IORANGE 16
+
+#define PCL812_CTR0 0
+#define PCL812_CTR1 1
+#define PCL812_CTR2 2
+#define PCL812_CTRCTL 3
+#define PCL812_AD_LO 4
+#define PCL812_DA1_LO 4
+#define PCL812_AD_HI 5
+#define PCL812_DA1_HI 5
+#define PCL812_DA2_LO 6
+#define PCL812_DI_LO 6
+#define PCL812_DA2_HI 7
+#define PCL812_DI_HI 7
+#define PCL812_CLRINT 8
+#define PCL812_GAIN 9
+#define PCL812_MUX 10
+#define PCL812_MODE 11
+#define PCL812_CNTENABLE 10
+#define PCL812_SOFTTRIG 12
+#define PCL812_DO_LO 13
+#define PCL812_DO_HI 14
+
+#define PCL812_DRDY 0x10 /* =0 data ready */
+
+#define ACL8216_STATUS 8 /* 5. bit signalize data ready */
+
+#define ACL8216_DRDY 0x20 /* =0 data ready */
+
+#define MAX_CHANLIST_LEN 256 /* length of scan list */
+
+static const struct comedi_lrange range_pcl812pg_ai = { 5, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ BIP_RANGE(0.3125),
+ }
+};
+static const struct comedi_lrange range_pcl812pg2_ai = { 5, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ }
+};
+static const struct comedi_lrange range812_bipolar1_25 = { 1, {
+ BIP_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range812_bipolar0_625 = { 1, {
+ BIP_RANGE(0.625),
+ }
+};
+static const struct comedi_lrange range812_bipolar0_3125 = { 1, {
+ BIP_RANGE(0.3125),
+ }
+};
+static const struct comedi_lrange range_pcl813b_ai = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ }
+};
+static const struct comedi_lrange range_pcl813b2_ai = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_iso813_1_ai = { 5, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ BIP_RANGE(0.3125),
+ }
+};
+static const struct comedi_lrange range_iso813_1_2_ai = { 5, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ UNI_RANGE(0.625),
+ }
+};
+static const struct comedi_lrange range_iso813_2_ai = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ }
+};
+static const struct comedi_lrange range_iso813_2_2_ai = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_acl8113_1_ai = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ }
+};
+static const struct comedi_lrange range_acl8113_1_2_ai = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_acl8113_2_ai = { 3, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_acl8113_2_2_ai = { 3, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ }
+};
+static const struct comedi_lrange range_acl8112dg_ai = { 9, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ BIP_RANGE(10),
+ }
+};
+static const struct comedi_lrange range_acl8112hg_ai = { 12, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.005),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01),
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.01),
+ }
+};
+static const struct comedi_lrange range_a821pgh_ai = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.005),
+ }
+};
+
+static int pcl812_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl812_detach(struct comedi_device * dev);
+
+struct pcl812_board {
+
+ const char *name; // board name
+ int board_type; // type of this board
+ int n_aichan; // num of AI chans in S.E.
+ int n_aichan_diff; // DIFF num of chans
+ int n_aochan; // num of DA chans
+ int n_dichan; // DI and DO chans
+ int n_dochan;
+ int ai_maxdata; // AI resolution
+ unsigned int ai_ns_min; // max sample speed of card v ns
+ unsigned int i8254_osc_base; // clock base
+ const struct comedi_lrange *rangelist_ai; // rangelist for A/D
+ const struct comedi_lrange *rangelist_ao; // rangelist for D/A
+ unsigned int IRQbits; // allowed IRQ
+ unsigned char DMAbits; // allowed DMA chans
+ unsigned char io_range; // iorange for this board
+ unsigned char haveMPC508; // 1=board use MPC508A multiplexor
+};
+
+
+static const struct pcl812_board boardtypes[] = {
+ {"pcl812", boardPCL812, 16, 0, 2, 16, 16, 0x0fff,
+ 33000, 500, &range_bipolar10, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"pcl812pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff,
+ 33000, 500, &range_pcl812pg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"acl8112pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff,
+ 10000, 500, &range_pcl812pg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"acl8112dg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+ 10000, 500, &range_acl8112dg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
+ {"acl8112hg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+ 10000, 500, &range_acl8112hg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
+ {"a821pgl", boardA821, 16, 8, 1, 16, 16, 0x0fff,
+ 10000, 500, &range_pcl813b_ai, &range_unipolar5,
+ 0x000c, 0x00, PCLx1x_IORANGE, 0},
+ {"a821pglnda", boardA821, 16, 8, 0, 0, 0, 0x0fff,
+ 10000, 500, &range_pcl813b_ai, NULL,
+ 0x000c, 0x00, PCLx1x_IORANGE, 0},
+ {"a821pgh", boardA821, 16, 8, 1, 16, 16, 0x0fff,
+ 10000, 500, &range_a821pgh_ai, &range_unipolar5,
+ 0x000c, 0x00, PCLx1x_IORANGE, 0},
+ {"a822pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+ 10000, 500, &range_acl8112dg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"a822pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+ 10000, 500, &range_acl8112hg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"a823pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+ 8000, 500, &range_acl8112dg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"a823pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+ 8000, 500, &range_acl8112hg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"pcl813", boardPCL813, 32, 0, 0, 0, 0, 0x0fff,
+ 0, 0, &range_pcl813b_ai, NULL,
+ 0x0000, 0x00, PCLx1x_IORANGE, 0},
+ {"pcl813b", boardPCL813B, 32, 0, 0, 0, 0, 0x0fff,
+ 0, 0, &range_pcl813b_ai, NULL,
+ 0x0000, 0x00, PCLx1x_IORANGE, 0},
+ {"acl8113", boardACL8113, 32, 0, 0, 0, 0, 0x0fff,
+ 0, 0, &range_acl8113_1_ai, NULL,
+ 0x0000, 0x00, PCLx1x_IORANGE, 0},
+ {"iso813", boardISO813, 32, 0, 0, 0, 0, 0x0fff,
+ 0, 0, &range_iso813_1_ai, NULL,
+ 0x0000, 0x00, PCLx1x_IORANGE, 0},
+ {"acl8216", boardACL8216, 16, 8, 2, 16, 16, 0xffff,
+ 10000, 500, &range_pcl813b2_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
+ {"a826pg", boardACL8216, 16, 8, 2, 16, 16, 0xffff,
+ 10000, 500, &range_pcl813b2_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl812_board))
+#define this_board ((const struct pcl812_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcl812 = {
+ driver_name:"pcl812",
+ module:THIS_MODULE,
+ attach:pcl812_attach,
+ detach:pcl812_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl812_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl812);
+
+struct pcl812_private {
+
+ unsigned char valid; // =1 device is OK
+ unsigned char dma; // >0 use dma ( usedDMA channel)
+ unsigned char use_diff; // =1 diff inputs
+ unsigned char use_MPC; // 1=board uses MPC508A multiplexor
+ unsigned char use_ext_trg; // 1=board uses external trigger
+ unsigned char range_correction; // =1 we must add 1 to range number
+ unsigned char old_chan_reg; // lastly used chan/gain pair
+ unsigned char old_gain_reg;
+ unsigned char mode_reg_int; // there is stored INT number for some card
+ unsigned char ai_neverending; // =1 we do unlimited AI
+ unsigned char ai_eos; // 1=EOS wake up
+ unsigned char ai_dma; // =1 we use DMA
+ unsigned int ai_poll_ptr; // how many sampes transfer poll
+ unsigned int ai_scans; // len of scanlist
+ unsigned int ai_act_scan; // how many scans we finished
+ unsigned int ai_chanlist[MAX_CHANLIST_LEN]; // our copy of channel/range list
+ unsigned int ai_n_chan; // how many channels is measured
+ unsigned int ai_flags; // flaglist
+ unsigned int ai_data_len; // len of data buffer
+ short *ai_data; // data buffer
+ unsigned int ai_is16b; // =1 we have 16 bit card
+ unsigned long dmabuf[2]; // PTR to DMA buf
+ unsigned int dmapages[2]; // how many pages we have allocated
+ unsigned int hwdmaptr[2]; // HW PTR to DMA buf
+ unsigned int hwdmasize[2]; // DMA buf size in bytes
+ unsigned int dmabytestomove[2]; // how many bytes DMA transfer
+ int next_dma_buf; // which buffer is next to use
+ unsigned int dma_runs_to_end; // how many times we must switch DMA buffers
+ unsigned int last_dma_run; // how many bytes to transfer on last DMA buffer
+ unsigned int max_812_ai_mode0_rangewait; // setling time for gain
+ unsigned int ao_readback[2]; // data for AO readback
+};
+
+
+#define devpriv ((struct pcl812_private *)dev->private)
+
+/*
+==============================================================================
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2);
+static void setup_range_channel(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int rangechan, char wait);
+static int pcl812_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+/*
+==============================================================================
+*/
+static int pcl812_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int timeout, hi;
+
+ outb(devpriv->mode_reg_int | 1, dev->iobase + PCL812_MODE); /* select software trigger */
+ setup_range_channel(dev, s, insn->chanspec, 1); // select channel and renge
+ for (n = 0; n < insn->n; n++) {
+ outb(255, dev->iobase + PCL812_SOFTTRIG); /* start conversion */
+ comedi_udelay(5);
+ timeout = 50; /* wait max 50us, it must finish under 33us */
+ while (timeout--) {
+ hi = inb(dev->iobase + PCL812_AD_HI);
+ if (!(hi & PCL812_DRDY))
+ goto conv_finish;
+ comedi_udelay(1);
+ }
+ rt_printk
+ ("comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n",
+ dev->minor, dev->board_name, dev->iobase);
+ outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE);
+ return -ETIME;
+
+ conv_finish:
+ data[n] = ((hi & 0xf) << 8) | inb(dev->iobase + PCL812_AD_LO);
+ }
+ outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE);
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int acl8216_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int timeout;
+
+ outb(1, dev->iobase + PCL812_MODE); /* select software trigger */
+ setup_range_channel(dev, s, insn->chanspec, 1); // select channel and renge
+ for (n = 0; n < insn->n; n++) {
+ outb(255, dev->iobase + PCL812_SOFTTRIG); /* start conversion */
+ comedi_udelay(5);
+ timeout = 50; /* wait max 50us, it must finish under 33us */
+ while (timeout--) {
+ if (!(inb(dev->iobase + ACL8216_STATUS) & ACL8216_DRDY))
+ goto conv_finish;
+ comedi_udelay(1);
+ }
+ rt_printk
+ ("comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n",
+ dev->minor, dev->board_name, dev->iobase);
+ outb(0, dev->iobase + PCL812_MODE);
+ return -ETIME;
+
+ conv_finish:
+ data[n] =
+ (inb(dev->iobase +
+ PCL812_AD_HI) << 8) | inb(dev->iobase +
+ PCL812_AD_LO);
+ }
+ outb(0, dev->iobase + PCL812_MODE);
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ outb((data[i] & 0xff),
+ dev->iobase + (chan ? PCL812_DA2_LO : PCL812_DA1_LO));
+ outb((data[i] >> 8) & 0x0f,
+ dev->iobase + (chan ? PCL812_DA2_HI : PCL812_DA1_HI));
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ return i;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + PCL812_DI_LO);
+ data[1] |= inb(dev->iobase + PCL812_DI_HI) << 8;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ outb(s->state & 0xff, dev->iobase + PCL812_DO_LO);
+ outb((s->state >> 8), dev->iobase + PCL812_DO_HI);
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+#ifdef PCL812_EXTDEBUG
+/*
+==============================================================================
+*/
+static void pcl812_cmdtest_out(int e, struct comedi_cmd * cmd)
+{
+ rt_printk("pcl812 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
+ cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
+ rt_printk("pcl812 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
+ cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
+ rt_printk("pcl812 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
+ cmd->scan_end_src);
+ rt_printk("pcl812 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", e,
+ cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+}
+#endif
+
+/*
+==============================================================================
+*/
+static int pcl812_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp, divisor1, divisor2;
+
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...)\n");
+ pcl812_cmdtest_out(-1, cmd);
+#endif
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ if (devpriv->use_ext_trg) {
+ cmd->convert_src &= TRIG_EXT;
+ } else {
+ cmd->convert_src &= TRIG_TIMER;
+ }
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err) {
+#ifdef PCL812_EXTDEBUG
+ pcl812_cmdtest_out(1, cmd);
+ rt_printk
+ ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=1\n",
+ err);
+#endif
+ return 1;
+ }
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ cmd->scan_begin_src = TRIG_FOLLOW;
+ err++;
+ }
+
+ if (devpriv->use_ext_trg) {
+ if (cmd->convert_src != TRIG_EXT) {
+ cmd->convert_src = TRIG_EXT;
+ err++;
+ }
+ } else {
+ if (cmd->convert_src != TRIG_TIMER) {
+ cmd->convert_src = TRIG_TIMER;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ if (err) {
+#ifdef PCL812_EXTDEBUG
+ pcl812_cmdtest_out(2, cmd);
+ rt_printk
+ ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=2\n",
+ err);
+#endif
+ return 2;
+ }
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ai_ns_min) {
+ cmd->convert_arg = this_board->ai_ns_min;
+ err++;
+ }
+ } else { /* TRIG_EXT */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->chanlist_len > MAX_CHANLIST_LEN) {
+ cmd->chanlist_len = this_board->n_aichan;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err) {
+#ifdef PCL812_EXTDEBUG
+ pcl812_cmdtest_out(3, cmd);
+ rt_printk
+ ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=3\n",
+ err);
+#endif
+ return 3;
+ }
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer(this_board->i8254_osc_base, &divisor1,
+ &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err) {
+#ifdef PCL812_EXTDEBUG
+ rt_printk
+ ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=4\n",
+ err);
+#endif
+ return 4;
+ }
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned int divisor1 = 0, divisor2 = 0, i, dma_flags, bytes;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: BGN: pcl812_ai_cmd(...)\n");
+#endif
+
+ if (cmd->start_src != TRIG_NOW)
+ return -EINVAL;
+ if (cmd->scan_begin_src != TRIG_FOLLOW)
+ return -EINVAL;
+ if (devpriv->use_ext_trg) {
+ if (cmd->convert_src != TRIG_EXT)
+ return -EINVAL;
+ } else {
+ if (cmd->convert_src != TRIG_TIMER)
+ return -EINVAL;
+ }
+ if (cmd->scan_end_src != TRIG_COUNT)
+ return -EINVAL;
+ if (cmd->scan_end_arg != cmd->chanlist_len)
+ return -EINVAL;
+ if (cmd->chanlist_len > MAX_CHANLIST_LEN)
+ return -EINVAL;
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+ i8253_cascade_ns_to_timer(this_board->i8254_osc_base,
+ &divisor1, &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ }
+
+ start_pacer(dev, -1, 0, 0); // stop pacer
+
+ devpriv->ai_n_chan = cmd->chanlist_len;
+ memcpy(devpriv->ai_chanlist, cmd->chanlist,
+ sizeof(unsigned int) * cmd->scan_end_arg);
+ setup_range_channel(dev, s, devpriv->ai_chanlist[0], 1); // select first channel and range
+
+ if (devpriv->dma) { // check if we can use DMA transfer
+ devpriv->ai_dma = 1;
+ for (i = 1; i < devpriv->ai_n_chan; i++)
+ if (devpriv->ai_chanlist[0] != devpriv->ai_chanlist[i]) {
+ devpriv->ai_dma = 0; // we cann't use DMA :-(
+ break;
+ }
+ } else
+ devpriv->ai_dma = 0;
+
+ devpriv->ai_flags = cmd->flags;
+ devpriv->ai_data_len = s->async->prealloc_bufsz;
+ devpriv->ai_data = s->async->prealloc_buf;
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ai_scans = cmd->stop_arg;
+ devpriv->ai_neverending = 0;
+ } else {
+ devpriv->ai_scans = 0;
+ devpriv->ai_neverending = 1;
+ }
+
+ devpriv->ai_act_scan = 0;
+ devpriv->ai_poll_ptr = 0;
+ s->async->cur_chan = 0;
+
+ if ((devpriv->ai_flags & TRIG_WAKE_EOS)) { // don't we want wake up every scan?
+ devpriv->ai_eos = 1;
+ if (devpriv->ai_n_chan == 1)
+ devpriv->ai_dma = 0; // DMA is useless for this situation
+ }
+
+ if (devpriv->ai_dma) {
+ if (devpriv->ai_eos) { // we use EOS, so adapt DMA buffer to one scan
+ devpriv->dmabytestomove[0] =
+ devpriv->ai_n_chan * sizeof(short);
+ devpriv->dmabytestomove[1] =
+ devpriv->ai_n_chan * sizeof(short);
+ devpriv->dma_runs_to_end = 1;
+ } else {
+ devpriv->dmabytestomove[0] = devpriv->hwdmasize[0];
+ devpriv->dmabytestomove[1] = devpriv->hwdmasize[1];
+ if (devpriv->ai_data_len < devpriv->hwdmasize[0])
+ devpriv->dmabytestomove[0] =
+ devpriv->ai_data_len;
+ if (devpriv->ai_data_len < devpriv->hwdmasize[1])
+ devpriv->dmabytestomove[1] =
+ devpriv->ai_data_len;
+ if (devpriv->ai_neverending) {
+ devpriv->dma_runs_to_end = 1;
+ } else {
+ bytes = devpriv->ai_n_chan * devpriv->ai_scans * sizeof(short); // how many samples we must transfer?
+ devpriv->dma_runs_to_end = bytes / devpriv->dmabytestomove[0]; // how many DMA pages we must fill
+ devpriv->last_dma_run = bytes % devpriv->dmabytestomove[0]; //on last dma transfer must be moved
+ if (devpriv->dma_runs_to_end == 0)
+ devpriv->dmabytestomove[0] =
+ devpriv->last_dma_run;
+ devpriv->dma_runs_to_end--;
+ }
+ }
+ if (devpriv->dmabytestomove[0] > devpriv->hwdmasize[0]) {
+ devpriv->dmabytestomove[0] = devpriv->hwdmasize[0];
+ devpriv->ai_eos = 0;
+ }
+ if (devpriv->dmabytestomove[1] > devpriv->hwdmasize[1]) {
+ devpriv->dmabytestomove[1] = devpriv->hwdmasize[1];
+ devpriv->ai_eos = 0;
+ }
+ devpriv->next_dma_buf = 0;
+ set_dma_mode(devpriv->dma, DMA_MODE_READ);
+ dma_flags = claim_dma_lock();
+ clear_dma_ff(devpriv->dma);
+ set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
+ set_dma_count(devpriv->dma, devpriv->dmabytestomove[0]);
+ release_dma_lock(dma_flags);
+ enable_dma(devpriv->dma);
+#ifdef PCL812_EXTDEBUG
+ rt_printk
+ ("pcl812 EDBG: DMA %d PTR 0x%0x/0x%0x LEN %u/%u EOS %d\n",
+ devpriv->dma, devpriv->hwdmaptr[0],
+ devpriv->hwdmaptr[1], devpriv->dmabytestomove[0],
+ devpriv->dmabytestomove[1], devpriv->ai_eos);
+#endif
+ }
+
+ switch (cmd->convert_src) {
+ case TRIG_TIMER:
+ start_pacer(dev, 1, divisor1, divisor2);
+ break;
+ }
+
+ if (devpriv->ai_dma) {
+ outb(devpriv->mode_reg_int | 2, dev->iobase + PCL812_MODE); // let's go!
+ } else {
+ outb(devpriv->mode_reg_int | 6, dev->iobase + PCL812_MODE); // let's go!
+ }
+
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: END: pcl812_ai_cmd(...)\n");
+#endif
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
+{
+ char err = 1;
+ unsigned int mask, timeout;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+
+ s->async->events = 0;
+
+ timeout = 50; /* wait max 50us, it must finish under 33us */
+ if (devpriv->ai_is16b) {
+ mask = 0xffff;
+ while (timeout--) {
+ if (!(inb(dev->iobase + ACL8216_STATUS) & ACL8216_DRDY)) {
+ err = 0;
+ break;
+ }
+ comedi_udelay(1);
+ }
+ } else {
+ mask = 0x0fff;
+ while (timeout--) {
+ if (!(inb(dev->iobase + PCL812_AD_HI) & PCL812_DRDY)) {
+ err = 0;
+ break;
+ }
+ comedi_udelay(1);
+ }
+ }
+
+ if (err) {
+ rt_printk
+ ("comedi%d: pcl812: (%s at 0x%lx) A/D cmd IRQ without DRDY!\n",
+ dev->minor, dev->board_name, dev->iobase);
+ pcl812_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ comedi_buf_put(s->async,
+ ((inb(dev->iobase + PCL812_AD_HI) << 8) | inb(dev->iobase +
+ PCL812_AD_LO)) & mask);
+
+ outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */
+
+ if (s->async->cur_chan == 0) { /* one scan done */
+ devpriv->ai_act_scan++;
+ if (!(devpriv->ai_neverending))
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
+ pcl812_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ }
+ }
+
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+*/
+static void transfer_from_dma_buf(struct comedi_device * dev, struct comedi_subdevice * s,
+ short * ptr, unsigned int bufptr, unsigned int len)
+{
+ unsigned int i;
+
+ s->async->events = 0;
+ for (i = len; i; i--) {
+ comedi_buf_put(s->async, ptr[bufptr++]); // get one sample
+
+ if (s->async->cur_chan == 0) {
+ devpriv->ai_act_scan++;
+ if (!devpriv->ai_neverending)
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
+ pcl812_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ break;
+ }
+ }
+ }
+
+ comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ unsigned long dma_flags;
+ int len, bufptr;
+ short *ptr;
+
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: BGN: interrupt_pcl812_ai_dma(...)\n");
+#endif
+ ptr = (short *) devpriv->dmabuf[devpriv->next_dma_buf];
+ len = (devpriv->dmabytestomove[devpriv->next_dma_buf] >> 1) -
+ devpriv->ai_poll_ptr;
+
+ devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
+ disable_dma(devpriv->dma);
+ set_dma_mode(devpriv->dma, DMA_MODE_READ);
+ dma_flags = claim_dma_lock();
+ set_dma_addr(devpriv->dma, devpriv->hwdmaptr[devpriv->next_dma_buf]);
+ if (devpriv->ai_eos) {
+ set_dma_count(devpriv->dma,
+ devpriv->dmabytestomove[devpriv->next_dma_buf]);
+ } else {
+ if (devpriv->dma_runs_to_end) {
+ set_dma_count(devpriv->dma,
+ devpriv->dmabytestomove[devpriv->next_dma_buf]);
+ } else {
+ set_dma_count(devpriv->dma, devpriv->last_dma_run);
+ }
+ devpriv->dma_runs_to_end--;
+ }
+ release_dma_lock(dma_flags);
+ enable_dma(devpriv->dma);
+
+ outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */
+
+ bufptr = devpriv->ai_poll_ptr;
+ devpriv->ai_poll_ptr = 0;
+
+ transfer_from_dma_buf(dev, s, ptr, bufptr, len);
+
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: END: interrupt_pcl812_ai_dma(...)\n");
+#endif
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_pcl812(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+
+ if (!dev->attached) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_HANDLED;
+ }
+ if (devpriv->ai_dma) {
+ return interrupt_pcl812_ai_dma(irq, d);
+ } else {
+ return interrupt_pcl812_ai_int(irq, d);
+ };
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+ unsigned int top1, top2, i;
+
+ if (!devpriv->ai_dma)
+ return 0; // poll is valid only for DMA transfer
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+ for (i = 0; i < 10; i++) {
+ top1 = get_dma_residue(devpriv->ai_dma); // where is now DMA
+ top2 = get_dma_residue(devpriv->ai_dma);
+ if (top1 == top2)
+ break;
+ }
+
+ if (top1 != top2) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ return 0;
+ }
+
+ top1 = devpriv->dmabytestomove[1 - devpriv->next_dma_buf] - top1; // where is now DMA in buffer
+ top1 >>= 1; // sample position
+ top2 = top1 - devpriv->ai_poll_ptr;
+ if (top2 < 1) { // no new samples
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ return 0;
+ }
+
+ transfer_from_dma_buf(dev, s,
+ (void *)devpriv->dmabuf[1 - devpriv->next_dma_buf],
+ devpriv->ai_poll_ptr, top2);
+
+ devpriv->ai_poll_ptr = top1; // new buffer position
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return s->async->buf_write_count - s->async->buf_read_count;
+}
+
+/*
+==============================================================================
+*/
+static void setup_range_channel(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int rangechan, char wait)
+{
+ unsigned char chan_reg = CR_CHAN(rangechan); // normal board
+ unsigned char gain_reg = CR_RANGE(rangechan) + devpriv->range_correction; // gain index
+
+ if ((chan_reg == devpriv->old_chan_reg)
+ && (gain_reg == devpriv->old_gain_reg))
+ return; // we can return, no change
+
+ devpriv->old_chan_reg = chan_reg;
+ devpriv->old_gain_reg = gain_reg;
+
+ if (devpriv->use_MPC) {
+ if (devpriv->use_diff) {
+ chan_reg = chan_reg | 0x30; // DIFF inputs
+ } else {
+ if (chan_reg & 0x80) {
+ chan_reg = chan_reg | 0x20; // SE inputs 8-15
+ } else {
+ chan_reg = chan_reg | 0x10; // SE inputs 0-7
+ }
+ }
+ }
+
+ outb(chan_reg, dev->iobase + PCL812_MUX); /* select channel */
+ outb(gain_reg, dev->iobase + PCL812_GAIN); /* select gain */
+
+ if (wait) {
+ comedi_udelay(devpriv->max_812_ai_mode0_rangewait); // XXX this depends on selected range and can be very long for some high gain ranges!
+ }
+}
+
+/*
+==============================================================================
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2)
+{
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode, divisor1,
+ divisor2);
+#endif
+ outb(0xb4, dev->iobase + PCL812_CTRCTL);
+ outb(0x74, dev->iobase + PCL812_CTRCTL);
+ comedi_udelay(1);
+
+ if (mode == 1) {
+ outb(divisor2 & 0xff, dev->iobase + PCL812_CTR2);
+ outb((divisor2 >> 8) & 0xff, dev->iobase + PCL812_CTR2);
+ outb(divisor1 & 0xff, dev->iobase + PCL812_CTR1);
+ outb((divisor1 >> 8) & 0xff, dev->iobase + PCL812_CTR1);
+ }
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: END: start_pacer(...)\n");
+#endif
+}
+
+/*
+==============================================================================
+*/
+static void free_resources(struct comedi_device * dev)
+{
+
+ if (dev->private) {
+ if (devpriv->dmabuf[0])
+ free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
+ if (devpriv->dmabuf[1])
+ free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
+ if (devpriv->dma)
+ free_dma(devpriv->dma);
+ }
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (dev->iobase)
+ release_region(dev->iobase, this_board->io_range);
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: BGN: pcl812_ai_cancel(...)\n");
+#endif
+ if (devpriv->ai_dma)
+ disable_dma(devpriv->dma);
+ outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */
+ outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE); /* Stop A/D */
+ start_pacer(dev, -1, 0, 0); // stop 8254
+ outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: END: pcl812_ai_cancel(...)\n");
+#endif
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static void pcl812_reset(struct comedi_device * dev)
+{
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: BGN: pcl812_reset(...)\n");
+#endif
+ outb(0, dev->iobase + PCL812_MUX);
+ outb(0 + devpriv->range_correction, dev->iobase + PCL812_GAIN);
+ devpriv->old_chan_reg = -1; // invalidate chain/gain memory
+ devpriv->old_gain_reg = -1;
+
+ switch (this_board->board_type) {
+ case boardPCL812PG:
+ case boardPCL812:
+ case boardACL8112:
+ case boardACL8216:
+ outb(0, dev->iobase + PCL812_DA2_LO);
+ outb(0, dev->iobase + PCL812_DA2_HI);
+ case boardA821:
+ outb(0, dev->iobase + PCL812_DA1_LO);
+ outb(0, dev->iobase + PCL812_DA1_HI);
+ start_pacer(dev, -1, 0, 0); // stop 8254
+ outb(0, dev->iobase + PCL812_DO_HI);
+ outb(0, dev->iobase + PCL812_DO_LO);
+ outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE);
+ outb(0, dev->iobase + PCL812_CLRINT);
+ break;
+ case boardPCL813B:
+ case boardPCL813:
+ case boardISO813:
+ case boardACL8113:
+ comedi_udelay(5);
+ break;
+ }
+ comedi_udelay(5);
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: END: pcl812_reset(...)\n");
+#endif
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret, subdev;
+ unsigned long iobase;
+ unsigned int irq;
+ unsigned int dma;
+ unsigned long pages;
+ struct comedi_subdevice *s;
+ int n_subdevices;
+
+ iobase = it->options[0];
+ printk("comedi%d: pcl812: board=%s, ioport=0x%03lx", dev->minor,
+ this_board->name, iobase);
+
+ if (!request_region(iobase, this_board->io_range, "pcl812")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ if ((ret = alloc_private(dev, sizeof(struct pcl812_private))) < 0) {
+ free_resources(dev);
+ return ret; /* Can't alloc mem */
+ }
+
+ dev->board_name = this_board->name;
+
+ irq = 0;
+ if (this_board->IRQbits != 0) { /* board support IRQ */
+ irq = it->options[1];
+ if (irq) { /* we want to use IRQ */
+ if (((1 << irq) & this_board->IRQbits) == 0) {
+ printk(", IRQ %u is out of allowed range, DISABLING IT", irq);
+ irq = 0; /* Bad IRQ */
+ } else {
+ if (comedi_request_irq(irq, interrupt_pcl812, 0,
+ "pcl812", dev)) {
+ printk(", unable to allocate IRQ %u, DISABLING IT", irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ printk(", irq=%u", irq);
+ }
+ }
+ }
+ }
+
+ dev->irq = irq;
+
+ dma = 0;
+ devpriv->dma = dma;
+ if (!dev->irq)
+ goto no_dma; /* if we haven't IRQ, we can't use DMA */
+ if (this_board->DMAbits != 0) { /* board support DMA */
+ dma = it->options[2];
+ if (((1 << dma) & this_board->DMAbits) == 0) {
+ printk(", DMA is out of allowed range, FAIL!\n");
+ return -EINVAL; /* Bad DMA */
+ }
+ ret = request_dma(dma, "pcl812");
+ if (ret) {
+ printk(", unable to allocate DMA %u, FAIL!\n", dma);
+ return -EBUSY; /* DMA isn't free */
+ }
+ devpriv->dma = dma;
+ printk(", dma=%u", dma);
+ pages = 1; /* we want 8KB */
+ devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
+ if (!devpriv->dmabuf[0]) {
+ printk(", unable to allocate DMA buffer, FAIL!\n");
+ /* maybe experiment with try_to_free_pages() will help .... */
+ free_resources(dev);
+ return -EBUSY; /* no buffer :-( */
+ }
+ devpriv->dmapages[0] = pages;
+ devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
+ devpriv->hwdmasize[0] = PAGE_SIZE * (1 << pages);
+ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
+ if (!devpriv->dmabuf[1]) {
+ printk(", unable to allocate DMA buffer, FAIL!\n");
+ free_resources(dev);
+ return -EBUSY;
+ }
+ devpriv->dmapages[1] = pages;
+ devpriv->hwdmaptr[1] = virt_to_bus((void *)devpriv->dmabuf[1]);
+ devpriv->hwdmasize[1] = PAGE_SIZE * (1 << pages);
+ }
+ no_dma:
+
+ n_subdevices = 0;
+ if (this_board->n_aichan > 0)
+ n_subdevices++;
+ if (this_board->n_aochan > 0)
+ n_subdevices++;
+ if (this_board->n_dichan > 0)
+ n_subdevices++;
+ if (this_board->n_dochan > 0)
+ n_subdevices++;
+
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+ free_resources(dev);
+ return ret;
+ }
+
+ subdev = 0;
+
+ /* analog input */
+ if (this_board->n_aichan > 0) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE;
+ switch (this_board->board_type) {
+ case boardA821:
+ if (it->options[2] == 1) {
+ s->n_chan = this_board->n_aichan_diff;
+ s->subdev_flags |= SDF_DIFF;
+ devpriv->use_diff = 1;
+ } else {
+ s->n_chan = this_board->n_aichan;
+ s->subdev_flags |= SDF_GROUND;
+ }
+ break;
+ case boardACL8112:
+ case boardACL8216:
+ if (it->options[4] == 1) {
+ s->n_chan = this_board->n_aichan_diff;
+ s->subdev_flags |= SDF_DIFF;
+ devpriv->use_diff = 1;
+ } else {
+ s->n_chan = this_board->n_aichan;
+ s->subdev_flags |= SDF_GROUND;
+ }
+ break;
+ default:
+ s->n_chan = this_board->n_aichan;
+ s->subdev_flags |= SDF_GROUND;
+ break;
+ }
+ s->maxdata = this_board->ai_maxdata;
+ s->len_chanlist = MAX_CHANLIST_LEN;
+ s->range_table = this_board->rangelist_ai;
+ if (this_board->board_type == boardACL8216) {
+ s->insn_read = acl8216_ai_insn_read;
+ } else {
+ s->insn_read = pcl812_ai_insn_read;
+ }
+ devpriv->use_MPC = this_board->haveMPC508;
+ s->cancel = pcl812_ai_cancel;
+ if (dev->irq) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmdtest = pcl812_ai_cmdtest;
+ s->do_cmd = pcl812_ai_cmd;
+ s->poll = pcl812_ai_poll;
+ }
+ switch (this_board->board_type) {
+ case boardPCL812PG:
+ if (it->options[4] == 1)
+ s->range_table = &range_pcl812pg2_ai;
+ break;
+ case boardPCL812:
+ switch (it->options[4]) {
+ case 0:
+ s->range_table = &range_bipolar10;
+ break;
+ case 1:
+ s->range_table = &range_bipolar5;
+ break;
+ case 2:
+ s->range_table = &range_bipolar2_5;
+ break;
+ case 3:
+ s->range_table = &range812_bipolar1_25;
+ break;
+ case 4:
+ s->range_table = &range812_bipolar0_625;
+ break;
+ case 5:
+ s->range_table = &range812_bipolar0_3125;
+ break;
+ default:
+ s->range_table = &range_bipolar10;
+ break;
+ printk(", incorrect range number %d, changing to 0 (+/-10V)", it->options[4]);
+ break;
+ }
+ break;
+ break;
+ case boardPCL813B:
+ if (it->options[1] == 1)
+ s->range_table = &range_pcl813b2_ai;
+ break;
+ case boardISO813:
+ switch (it->options[1]) {
+ case 0:
+ s->range_table = &range_iso813_1_ai;
+ break;
+ case 1:
+ s->range_table = &range_iso813_1_2_ai;
+ break;
+ case 2:
+ s->range_table = &range_iso813_2_ai;
+ devpriv->range_correction = 1;
+ break;
+ case 3:
+ s->range_table = &range_iso813_2_2_ai;
+ devpriv->range_correction = 1;
+ break;
+ default:
+ s->range_table = &range_iso813_1_ai;
+ break;
+ printk(", incorrect range number %d, changing to 0 ", it->options[1]);
+ break;
+ }
+ break;
+ case boardACL8113:
+ switch (it->options[1]) {
+ case 0:
+ s->range_table = &range_acl8113_1_ai;
+ break;
+ case 1:
+ s->range_table = &range_acl8113_1_2_ai;
+ break;
+ case 2:
+ s->range_table = &range_acl8113_2_ai;
+ devpriv->range_correction = 1;
+ break;
+ case 3:
+ s->range_table = &range_acl8113_2_2_ai;
+ devpriv->range_correction = 1;
+ break;
+ default:
+ s->range_table = &range_acl8113_1_ai;
+ break;
+ printk(", incorrect range number %d, changing to 0 ", it->options[1]);
+ break;
+ }
+ break;
+ }
+ subdev++;
+ }
+
+ /* analog output */
+ if (this_board->n_aochan > 0) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = 0xfff;
+ s->len_chanlist = 1;
+ s->range_table = this_board->rangelist_ao;
+ s->insn_read = pcl812_ao_insn_read;
+ s->insn_write = pcl812_ao_insn_write;
+ switch (this_board->board_type) {
+ case boardA821:
+ if (it->options[3] == 1)
+ s->range_table = &range_unipolar10;
+ break;
+ case boardPCL812:
+ case boardACL8112:
+ case boardPCL812PG:
+ case boardACL8216:
+ if (it->options[5] == 1)
+ s->range_table = &range_unipolar10;
+ if (it->options[5] == 2)
+ s->range_table = &range_unknown;
+ break;
+ }
+ subdev++;
+ }
+
+ /* digital input */
+ if (this_board->n_dichan > 0) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = this_board->n_dichan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dichan;
+ s->range_table = &range_digital;
+ s->insn_bits = pcl812_di_insn_bits;
+ subdev++;
+ }
+
+ /* digital output */
+ if (this_board->n_dochan > 0) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = this_board->n_dochan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dochan;
+ s->range_table = &range_digital;
+ s->insn_bits = pcl812_do_insn_bits;
+ subdev++;
+ }
+
+ switch (this_board->board_type) {
+ case boardACL8216:
+ devpriv->ai_is16b = 1;
+ case boardPCL812PG:
+ case boardPCL812:
+ case boardACL8112:
+ devpriv->max_812_ai_mode0_rangewait = 1;
+ if (it->options[3] > 0)
+ devpriv->use_ext_trg = 1; // we use external trigger
+ case boardA821:
+ devpriv->max_812_ai_mode0_rangewait = 1;
+ devpriv->mode_reg_int = (irq << 4) & 0xf0;
+ break;
+ case boardPCL813B:
+ case boardPCL813:
+ case boardISO813:
+ case boardACL8113:
+ devpriv->max_812_ai_mode0_rangewait = 5; /* maybe there must by greatest timeout */
+ break;
+ }
+
+ printk("\n");
+ devpriv->valid = 1;
+
+ pcl812_reset(dev);
+
+ return 0;
+}
+
+/*
+==============================================================================
+ */
+static int pcl812_detach(struct comedi_device * dev)
+{
+
+#ifdef PCL812_EXTDEBUG
+ rt_printk("comedi%d: pcl812: remove\n", dev->minor);
+#endif
+ free_resources(dev);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
new file mode 100644
index 00000000000..515ba74cc7f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -0,0 +1,1251 @@
+/*
+ comedi/drivers/pcl816.c
+
+ Author: Juan Grigera <juan@grigera.com.ar>
+ based on pcl818 by Michal Dobes <dobes@tesnet.cz> and bits of pcl812
+
+ hardware driver for Advantech cards:
+ card: PCL-816, PCL814B
+ driver: pcl816
+*/
+/*
+Driver: pcl816
+Description: Advantech PCL-816 cards, PCL-814
+Author: Juan Grigera <juan@grigera.com.ar>
+Devices: [Advantech] PCL-816 (pcl816), PCL-814B (pcl814b)
+Status: works
+Updated: Tue, 2 Apr 2002 23:15:21 -0800
+
+PCL 816 and 814B have 16 SE/DIFF ADCs, 16 DACs, 16 DI and 16 DO.
+Differences are at resolution (16 vs 12 bits).
+
+The driver support AI command mode, other subdevices not written.
+
+Analog output and digital input and output are not supported.
+
+Configuration Options:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0, 10=10MHz clock for 8254
+ 1= 1MHz clock for 8254
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+
+#define DEBUG(x) x
+
+// boards constants
+// IO space len
+#define PCLx1x_RANGE 16
+
+//#define outb(x,y) printk("OUTB(%x, 200+%d)\n", x,y-0x200); outb(x,y)
+
+// INTEL 8254 counters
+#define PCL816_CTR0 4
+#define PCL816_CTR1 5
+#define PCL816_CTR2 6
+// R: counter read-back register W: counter control
+#define PCL816_CTRCTL 7
+
+// R: A/D high byte W: A/D range control
+#define PCL816_RANGE 9
+// W: clear INT request
+#define PCL816_CLRINT 10
+// R: next mux scan channel W: mux scan channel & range control pointer
+#define PCL816_MUX 11
+// R/W: operation control register
+#define PCL816_CONTROL 12
+
+// R: return status byte W: set DMA/IRQ
+#define PCL816_STATUS 13
+#define PCL816_STATUS_DRDY_MASK 0x80
+
+// R: low byte of A/D W: soft A/D trigger
+#define PCL816_AD_LO 8
+// R: high byte of A/D W: A/D range control
+#define PCL816_AD_HI 9
+
+// type of interrupt handler
+#define INT_TYPE_AI1_INT 1
+#define INT_TYPE_AI1_DMA 2
+#define INT_TYPE_AI3_INT 4
+#define INT_TYPE_AI3_DMA 5
+#ifdef unused
+#define INT_TYPE_AI1_DMA_RTC 9
+#define INT_TYPE_AI3_DMA_RTC 10
+
+// RTC stuff...
+#define RTC_IRQ 8
+#define RTC_IO_EXTENT 0x10
+#endif
+
+#define MAGIC_DMA_WORD 0x5a5a
+
+static const struct comedi_lrange range_pcl816 = { 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+struct pcl816_board {
+
+ const char *name; // board name
+ int n_ranges; // len of range list
+ int n_aichan; // num of A/D chans in diferencial mode
+ unsigned int ai_ns_min; // minimal alllowed delay between samples (in ns)
+ int n_aochan; // num of D/A chans
+ int n_dichan; // num of DI chans
+ int n_dochan; // num of DO chans
+ const struct comedi_lrange *ai_range_type; // default A/D rangelist
+ const struct comedi_lrange *ao_range_type; // dafault D/A rangelist
+ unsigned int io_range; // len of IO space
+ unsigned int IRQbits; // allowed interrupts
+ unsigned int DMAbits; // allowed DMA chans
+ int ai_maxdata; // maxdata for A/D
+ int ao_maxdata; // maxdata for D/A
+ int ai_chanlist; // allowed len of channel list A/D
+ int ao_chanlist; // allowed len of channel list D/A
+ int i8254_osc_base; // 1/frequency of on board oscilator in ns
+};
+
+
+static const struct pcl816_board boardtypes[] = {
+ {"pcl816", 8, 16, 10000, 1, 16, 16, &range_pcl816,
+ &range_pcl816, PCLx1x_RANGE,
+ 0x00fc, // IRQ mask
+ 0x0a, // DMA mask
+ 0xffff, // 16-bit card
+ 0xffff, // D/A maxdata
+ 1024,
+ 1, // ao chan list
+ 100},
+ {"pcl814b", 8, 16, 10000, 1, 16, 16, &range_pcl816,
+ &range_pcl816, PCLx1x_RANGE,
+ 0x00fc,
+ 0x0a,
+ 0x3fff, /* 14 bit card */
+ 0x3fff,
+ 1024,
+ 1,
+ 100},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl816_board))
+#define devpriv ((struct pcl816_private *)dev->private)
+#define this_board ((const struct pcl816_board *)dev->board_ptr)
+
+static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl816_detach(struct comedi_device * dev);
+
+#ifdef unused
+static int RTC_lock = 0; /* RTC lock */
+static int RTC_timer_lock = 0; /* RTC int lock */
+#endif
+
+static struct comedi_driver driver_pcl816 = {
+ driver_name:"pcl816",
+ module:THIS_MODULE,
+ attach:pcl816_attach,
+ detach:pcl816_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl816_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl816);
+
+struct pcl816_private {
+
+ unsigned int dma; // used DMA, 0=don't use DMA
+ int dma_rtc; // 1=RTC used with DMA, 0=no RTC alloc
+#ifdef unused
+ unsigned long rtc_iobase; // RTC port region
+ unsigned int rtc_iosize;
+ unsigned int rtc_irq;
+#endif
+ unsigned long dmabuf[2]; // pointers to begin of DMA buffers
+ unsigned int dmapages[2]; // len of DMA buffers in PAGE_SIZEs
+ unsigned int hwdmaptr[2]; // hardware address of DMA buffers
+ unsigned int hwdmasize[2]; // len of DMA buffers in Bytes
+ unsigned int dmasamplsize; // size in samples hwdmasize[0]/2
+ unsigned int last_top_dma; // DMA pointer in last RTC int
+ int next_dma_buf; // which DMA buffer will be used next round
+ long dma_runs_to_end; // how many we must permorm DMA transfer to end of record
+ unsigned long last_dma_run; // how many bytes we must transfer on last DMA page
+
+ unsigned int ai_scans; // len of scanlist
+ unsigned char ai_neverending; // if=1, then we do neverending record (you must use cancel())
+ int irq_free; // 1=have allocated IRQ
+ int irq_blocked; // 1=IRQ now uses any subdev
+#ifdef unused
+ int rtc_irq_blocked; // 1=we now do AI with DMA&RTC
+#endif
+ int irq_was_now_closed; // when IRQ finish, there's stored int816_mode for last interrupt
+ int int816_mode; // who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma
+ struct comedi_subdevice *last_int_sub; // ptr to subdevice which now finish
+ int ai_act_scan; // how many scans we finished
+ unsigned int ai_act_chanlist[16]; // MUX setting for actual AI operations
+ unsigned int ai_act_chanlist_len; // how long is actual MUX list
+ unsigned int ai_act_chanlist_pos; // actual position in MUX list
+ unsigned int ai_poll_ptr; // how many sampes transfer poll
+ struct comedi_subdevice *sub_ai; // ptr to AI subdevice
+#ifdef unused
+ struct timer_list rtc_irq_timer; // timer for RTC sanity check
+ unsigned long rtc_freq; // RTC int freq
+#endif
+};
+
+
+/*
+==============================================================================
+*/
+static int check_and_setup_channel_list(struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned int *chanlist, int chanlen);
+static int pcl816_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2);
+#ifdef unused
+static int set_rtc_irq_bit(unsigned char bit);
+#endif
+
+static int pcl816_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+
+/*
+==============================================================================
+ ANALOG INPUT MODE0, 816 cards, slow version
+*/
+static int pcl816_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int timeout;
+
+ DPRINTK("mode 0 analog input\n");
+ // software trigger, DMA and INT off
+ outb(0, dev->iobase + PCL816_CONTROL);
+ // clear INT (conversion end) flag
+ outb(0, dev->iobase + PCL816_CLRINT);
+
+ // Set the input channel
+ outb(CR_CHAN(insn->chanspec) & 0xf, dev->iobase + PCL816_MUX);
+ outb(CR_RANGE(insn->chanspec), dev->iobase + PCL816_RANGE); /* select gain */
+
+ for (n = 0; n < insn->n; n++) {
+
+ outb(0, dev->iobase + PCL816_AD_LO); /* start conversion */
+
+ timeout = 100;
+ while (timeout--) {
+ if (!(inb(dev->iobase + PCL816_STATUS) &
+ PCL816_STATUS_DRDY_MASK)) {
+ // return read value
+ data[n] =
+ ((inb(dev->iobase +
+ PCL816_AD_HI) << 8) |
+ (inb(dev->iobase + PCL816_AD_LO)));
+
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT (conversion end) flag */
+ break;
+ }
+ comedi_udelay(1);
+ }
+ // Return timeout error
+ if (!timeout) {
+ comedi_error(dev, "A/D insn timeout\n");
+ data[0] = 0;
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT (conversion end) flag */
+ return -EIO;
+ }
+
+ }
+ return n;
+}
+
+/*
+==============================================================================
+ analog input interrupt mode 1 & 3, 818 cards
+ one sample per interrupt version
+*/
+static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int low, hi;
+ int timeout = 50; /* wait max 50us */
+
+ while (timeout--) {
+ if (!(inb(dev->iobase + PCL816_STATUS) &
+ PCL816_STATUS_DRDY_MASK))
+ break;
+ comedi_udelay(1);
+ }
+ if (!timeout) { // timeout, bail error
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */
+ comedi_error(dev, "A/D mode1/3 IRQ without DRDY!");
+ pcl816_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+
+ }
+
+ // get the sample
+ low = inb(dev->iobase + PCL816_AD_LO);
+ hi = inb(dev->iobase + PCL816_AD_HI);
+
+ comedi_buf_put(s->async, (hi << 8) | low);
+
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */
+
+ if (++devpriv->ai_act_chanlist_pos >= devpriv->ai_act_chanlist_len)
+ devpriv->ai_act_chanlist_pos = 0;
+
+ if (s->async->cur_chan == 0) {
+ devpriv->ai_act_scan++;
+ }
+
+ if (!devpriv->ai_neverending)
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
+ /* all data sampled */
+ pcl816_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ }
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+ analog input dma mode 1 & 3, 816 cards
+*/
+static void transfer_from_dma_buf(struct comedi_device * dev, struct comedi_subdevice * s,
+ short * ptr, unsigned int bufptr, unsigned int len)
+{
+ int i;
+
+ s->async->events = 0;
+
+ for (i = 0; i < len; i++) {
+
+ comedi_buf_put(s->async, ptr[bufptr++]);
+
+ if (++devpriv->ai_act_chanlist_pos >=
+ devpriv->ai_act_chanlist_len) {
+ devpriv->ai_act_chanlist_pos = 0;
+ devpriv->ai_act_scan++;
+ }
+
+ if (!devpriv->ai_neverending)
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { // all data sampled
+ pcl816_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ s->async->events |= COMEDI_CB_BLOCK;
+ break;
+ }
+ }
+
+ comedi_event(dev, s);
+}
+
+static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int len, bufptr, this_dma_buf;
+ unsigned long dma_flags;
+ short *ptr;
+
+ disable_dma(devpriv->dma);
+ this_dma_buf = devpriv->next_dma_buf;
+
+ if ((devpriv->dma_runs_to_end > -1) || devpriv->ai_neverending) { // switch dma bufs
+
+ devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
+ set_dma_mode(devpriv->dma, DMA_MODE_READ);
+ dma_flags = claim_dma_lock();
+// clear_dma_ff (devpriv->dma);
+ set_dma_addr(devpriv->dma,
+ devpriv->hwdmaptr[devpriv->next_dma_buf]);
+ if (devpriv->dma_runs_to_end) {
+ set_dma_count(devpriv->dma,
+ devpriv->hwdmasize[devpriv->next_dma_buf]);
+ } else {
+ set_dma_count(devpriv->dma, devpriv->last_dma_run);
+ }
+ release_dma_lock(dma_flags);
+ enable_dma(devpriv->dma);
+ }
+
+ devpriv->dma_runs_to_end--;
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */
+
+ ptr = (short *) devpriv->dmabuf[this_dma_buf];
+
+ len = (devpriv->hwdmasize[0] >> 1) - devpriv->ai_poll_ptr;
+ bufptr = devpriv->ai_poll_ptr;
+ devpriv->ai_poll_ptr = 0;
+
+ transfer_from_dma_buf(dev, s, ptr, bufptr, len);
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+ INT procedure
+*/
+static irqreturn_t interrupt_pcl816(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ DPRINTK("<I>");
+
+ if (!dev->attached) {
+ comedi_error(dev, "premature interrupt");
+ return IRQ_HANDLED;
+ }
+
+ switch (devpriv->int816_mode) {
+ case INT_TYPE_AI1_DMA:
+ case INT_TYPE_AI3_DMA:
+ return interrupt_pcl816_ai_mode13_dma(irq, d);
+ case INT_TYPE_AI1_INT:
+ case INT_TYPE_AI3_INT:
+ return interrupt_pcl816_ai_mode13_int(irq, d);
+ }
+
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */
+ if ((!dev->irq) | (!devpriv->irq_free) | (!devpriv->irq_blocked) |
+ (!devpriv->int816_mode)) {
+ if (devpriv->irq_was_now_closed) {
+ devpriv->irq_was_now_closed = 0;
+ // comedi_error(dev,"last IRQ..");
+ return IRQ_HANDLED;
+ }
+ comedi_error(dev, "bad IRQ!");
+ return IRQ_NONE;
+ }
+ comedi_error(dev, "IRQ from unknow source!");
+ return IRQ_NONE;
+}
+
+/*
+==============================================================================
+ COMMAND MODE
+*/
+static void pcl816_cmdtest_out(int e, struct comedi_cmd * cmd)
+{
+ rt_printk("pcl816 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
+ cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
+ rt_printk("pcl816 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
+ cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
+ rt_printk("pcl816 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
+ cmd->scan_end_src);
+ rt_printk("pcl816 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", e,
+ cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+}
+
+/*
+==============================================================================
+*/
+static int pcl816_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp, divisor1, divisor2;
+
+ DEBUG(rt_printk("pcl816 pcl812_ai_cmdtest\n");
+ pcl816_cmdtest_out(-1, cmd););
+
+ /* step 1: make sure trigger sources are trivially valid */
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ if (!cmd->convert_src & (TRIG_EXT | TRIG_TIMER))
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err) {
+ return 1;
+ }
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ cmd->scan_begin_src = TRIG_FOLLOW;
+ err++;
+ }
+
+ if (cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_TIMER) {
+ cmd->convert_src = TRIG_TIMER;
+ err++;
+ }
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ if (err) {
+ return 2;
+ }
+
+ /* step 3: make sure arguments are trivially compatible */
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ai_ns_min) {
+ cmd->convert_arg = this_board->ai_ns_min;
+ err++;
+ }
+ } else { /* TRIG_EXT */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->chanlist_len > this_board->n_aichan) {
+ cmd->chanlist_len = this_board->n_aichan;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err) {
+ return 3;
+ }
+
+ /* step 4: fix up any arguments */
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer(this_board->i8254_osc_base,
+ &divisor1, &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err) {
+ return 4;
+ }
+
+ return 0;
+}
+
+static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (cmd->start_src != TRIG_NOW)
+ return -EINVAL;
+ if (cmd->scan_begin_src != TRIG_FOLLOW)
+ return -EINVAL;
+ if (cmd->scan_end_src != TRIG_COUNT)
+ return -EINVAL;
+ if (cmd->scan_end_arg != cmd->chanlist_len)
+ return -EINVAL;
+// if(cmd->chanlist_len>MAX_CHANLIST_LEN) return -EINVAL;
+ if (devpriv->irq_blocked)
+ return -EBUSY;
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+
+ i8253_cascade_ns_to_timer(this_board->i8254_osc_base, &divisor1,
+ &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (divisor1 == 1) { // PCL816 crash if any divisor is set to 1
+ divisor1 = 2;
+ divisor2 /= 2;
+ }
+ if (divisor2 == 1) {
+ divisor2 = 2;
+ divisor1 /= 2;
+ }
+ }
+
+ start_pacer(dev, -1, 0, 0); // stop pacer
+
+ if (!check_and_setup_channel_list(dev, s, cmd->chanlist,
+ cmd->chanlist_len))
+ return -EINVAL;
+ comedi_udelay(1);
+
+ devpriv->ai_act_scan = 0;
+ s->async->cur_chan = 0;
+ devpriv->irq_blocked = 1;
+ devpriv->ai_poll_ptr = 0;
+ devpriv->irq_was_now_closed = 0;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ai_scans = cmd->stop_arg;
+ devpriv->ai_neverending = 0;
+ } else {
+ devpriv->ai_scans = 0;
+ devpriv->ai_neverending = 1;
+ }
+
+ if ((cmd->flags & TRIG_WAKE_EOS)) { // don't we want wake up every scan?
+ printk("pl816: You wankt WAKE_EOS but I dont want handle it");
+ // devpriv->ai_eos=1;
+ //if (devpriv->ai_n_chan==1)
+ // devpriv->dma=0; // DMA is useless for this situation
+ }
+
+ if (devpriv->dma) {
+ bytes = devpriv->hwdmasize[0];
+ if (!devpriv->ai_neverending) {
+ bytes = s->async->cmd.chanlist_len * s->async->cmd.chanlist_len * sizeof(short); // how many
+ devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0]; // how many DMA pages we must fill
+ devpriv->last_dma_run = bytes % devpriv->hwdmasize[0]; //on last dma transfer must be moved
+ devpriv->dma_runs_to_end--;
+ if (devpriv->dma_runs_to_end >= 0)
+ bytes = devpriv->hwdmasize[0];
+ } else
+ devpriv->dma_runs_to_end = -1;
+
+ devpriv->next_dma_buf = 0;
+ set_dma_mode(devpriv->dma, DMA_MODE_READ);
+ dma_flags = claim_dma_lock();
+ clear_dma_ff(devpriv->dma);
+ set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
+ set_dma_count(devpriv->dma, bytes);
+ release_dma_lock(dma_flags);
+ enable_dma(devpriv->dma);
+ }
+
+ start_pacer(dev, 1, divisor1, divisor2);
+ dmairq = ((devpriv->dma & 0x3) << 4) | (dev->irq & 0x7);
+
+ switch (cmd->convert_src) {
+ case TRIG_TIMER:
+ devpriv->int816_mode = INT_TYPE_AI1_DMA;
+ outb(0x32, dev->iobase + PCL816_CONTROL); // Pacer+IRQ+DMA
+ outb(dmairq, dev->iobase + PCL816_STATUS); // write irq and DMA to card
+ break;
+
+ default:
+ devpriv->int816_mode = INT_TYPE_AI3_DMA;
+ outb(0x34, dev->iobase + PCL816_CONTROL); // Ext trig+IRQ+DMA
+ outb(dmairq, dev->iobase + PCL816_STATUS); // write irq to card
+ break;
+ }
+
+ DPRINTK("pcl816 END: pcl812_ai_cmd()\n");
+ return 0;
+}
+
+static int pcl816_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+ unsigned int top1, top2, i;
+
+ if (!devpriv->dma)
+ return 0; // poll is valid only for DMA transfer
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+ for (i = 0; i < 20; i++) {
+ top1 = get_dma_residue(devpriv->dma); // where is now DMA
+ top2 = get_dma_residue(devpriv->dma);
+ if (top1 == top2)
+ break;
+ }
+ if (top1 != top2) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ return 0;
+ }
+
+ top1 = devpriv->hwdmasize[0] - top1; // where is now DMA in buffer
+ top1 >>= 1; // sample position
+ top2 = top1 - devpriv->ai_poll_ptr;
+ if (top2 < 1) { // no new samples
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ return 0;
+ }
+
+ transfer_from_dma_buf(dev, s,
+ (short *) devpriv->dmabuf[devpriv->next_dma_buf],
+ devpriv->ai_poll_ptr, top2);
+
+ devpriv->ai_poll_ptr = top1; // new buffer position
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return s->async->buf_write_count - s->async->buf_read_count;
+}
+
+/*
+==============================================================================
+ cancel any mode 1-4 AI
+*/
+static int pcl816_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+// DEBUG(rt_printk("pcl816_ai_cancel()\n");)
+
+ if (devpriv->irq_blocked > 0) {
+ switch (devpriv->int816_mode) {
+#ifdef unused
+ case INT_TYPE_AI1_DMA_RTC:
+ case INT_TYPE_AI3_DMA_RTC:
+ set_rtc_irq_bit(0); // stop RTC
+ del_timer(&devpriv->rtc_irq_timer);
+#endif
+ case INT_TYPE_AI1_DMA:
+ case INT_TYPE_AI3_DMA:
+ disable_dma(devpriv->dma);
+ case INT_TYPE_AI1_INT:
+ case INT_TYPE_AI3_INT:
+ outb(inb(dev->iobase + PCL816_CONTROL) & 0x73, dev->iobase + PCL816_CONTROL); /* Stop A/D */
+ comedi_udelay(1);
+ outb(0, dev->iobase + PCL816_CONTROL); /* Stop A/D */
+ outb(0xb0, dev->iobase + PCL816_CTRCTL); /* Stop pacer */
+ outb(0x70, dev->iobase + PCL816_CTRCTL);
+ outb(0, dev->iobase + PCL816_AD_LO);
+ inb(dev->iobase + PCL816_AD_LO);
+ inb(dev->iobase + PCL816_AD_HI);
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */
+ outb(0, dev->iobase + PCL816_CONTROL); /* Stop A/D */
+ devpriv->irq_blocked = 0;
+ devpriv->irq_was_now_closed = devpriv->int816_mode;
+ devpriv->int816_mode = 0;
+ devpriv->last_int_sub = s;
+// s->busy = 0;
+ break;
+ }
+ }
+
+ DEBUG(rt_printk("comedi: pcl816_ai_cancel() successful\n");
+ )
+ return 0;
+}
+
+/*
+==============================================================================
+ chech for PCL816
+*/
+static int pcl816_check(unsigned long iobase)
+{
+ outb(0x00, iobase + PCL816_MUX);
+ comedi_udelay(1);
+ if (inb(iobase + PCL816_MUX) != 0x00)
+ return 1; //there isn't card
+ outb(0x55, iobase + PCL816_MUX);
+ comedi_udelay(1);
+ if (inb(iobase + PCL816_MUX) != 0x55)
+ return 1; //there isn't card
+ outb(0x00, iobase + PCL816_MUX);
+ comedi_udelay(1);
+ outb(0x18, iobase + PCL816_CONTROL);
+ comedi_udelay(1);
+ if (inb(iobase + PCL816_CONTROL) != 0x18)
+ return 1; //there isn't card
+ return 0; // ok, card exist
+}
+
+/*
+==============================================================================
+ reset whole PCL-816 cards
+*/
+static void pcl816_reset(struct comedi_device * dev)
+{
+// outb (0, dev->iobase + PCL818_DA_LO); // DAC=0V
+// outb (0, dev->iobase + PCL818_DA_HI);
+// comedi_udelay (1);
+// outb (0, dev->iobase + PCL818_DO_HI); // DO=$0000
+// outb (0, dev->iobase + PCL818_DO_LO);
+// comedi_udelay (1);
+ outb(0, dev->iobase + PCL816_CONTROL);
+ outb(0, dev->iobase + PCL816_MUX);
+ outb(0, dev->iobase + PCL816_CLRINT);
+ outb(0xb0, dev->iobase + PCL816_CTRCTL); /* Stop pacer */
+ outb(0x70, dev->iobase + PCL816_CTRCTL);
+ outb(0x30, dev->iobase + PCL816_CTRCTL);
+ outb(0, dev->iobase + PCL816_RANGE);
+}
+
+/*
+==============================================================================
+ Start/stop pacer onboard pacer
+*/
+static void
+start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2)
+{
+ outb(0x32, dev->iobase + PCL816_CTRCTL);
+ outb(0xff, dev->iobase + PCL816_CTR0);
+ outb(0x00, dev->iobase + PCL816_CTR0);
+ comedi_udelay(1);
+ outb(0xb4, dev->iobase + PCL816_CTRCTL); // set counter 2 as mode 3
+ outb(0x74, dev->iobase + PCL816_CTRCTL); // set counter 1 as mode 3
+ comedi_udelay(1);
+
+ if (mode == 1) {
+ DPRINTK("mode %d, divisor1 %d, divisor2 %d\n", mode, divisor1,
+ divisor2);
+ outb(divisor2 & 0xff, dev->iobase + PCL816_CTR2);
+ outb((divisor2 >> 8) & 0xff, dev->iobase + PCL816_CTR2);
+ outb(divisor1 & 0xff, dev->iobase + PCL816_CTR1);
+ outb((divisor1 >> 8) & 0xff, dev->iobase + PCL816_CTR1);
+ }
+
+ /* clear pending interrupts (just in case) */
+// outb(0, dev->iobase + PCL816_CLRINT);
+}
+
+/*
+==============================================================================
+ Check if channel list from user is builded correctly
+ If it's ok, then program scan/gain logic
+*/
+static int
+check_and_setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, int chanlen)
+{
+ unsigned int chansegment[16];
+ unsigned int i, nowmustbechan, seglen, segpos;
+
+ // correct channel and range number check itself comedi/range.c
+ if (chanlen < 1) {
+ comedi_error(dev, "range/channel list is empty!");
+ return 0;
+ }
+
+ if (chanlen > 1) {
+ chansegment[0] = chanlist[0]; // first channel is everytime ok
+ for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
+ // build part of chanlist
+ DEBUG(rt_printk("%d. %d %d\n", i, CR_CHAN(chanlist[i]),
+ CR_RANGE(chanlist[i]));
+ )
+ if (chanlist[0] == chanlist[i])
+ break; // we detect loop, this must by finish
+ nowmustbechan =
+ (CR_CHAN(chansegment[i - 1]) + 1) % chanlen;
+ if (nowmustbechan != CR_CHAN(chanlist[i])) {
+ // channel list isn't continous :-(
+ rt_printk
+ ("comedi%d: pcl816: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
+ dev->minor, i, CR_CHAN(chanlist[i]),
+ nowmustbechan, CR_CHAN(chanlist[0]));
+ return 0;
+ }
+ chansegment[i] = chanlist[i]; // well, this is next correct channel in list
+ }
+
+ for (i = 0, segpos = 0; i < chanlen; i++) { // check whole chanlist
+ DEBUG(rt_printk("%d %d=%d %d\n",
+ CR_CHAN(chansegment[i % seglen]),
+ CR_RANGE(chansegment[i % seglen]),
+ CR_CHAN(chanlist[i]),
+ CR_RANGE(chanlist[i]));
+ )
+ if (chanlist[i] != chansegment[i % seglen]) {
+ rt_printk
+ ("comedi%d: pcl816: bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
+ dev->minor, i, CR_CHAN(chansegment[i]),
+ CR_RANGE(chansegment[i]),
+ CR_AREF(chansegment[i]),
+ CR_CHAN(chanlist[i % seglen]),
+ CR_RANGE(chanlist[i % seglen]),
+ CR_AREF(chansegment[i % seglen]));
+ return 0; // chan/gain list is strange
+ }
+ }
+ } else {
+ seglen = 1;
+ }
+
+ devpriv->ai_act_chanlist_len = seglen;
+ devpriv->ai_act_chanlist_pos = 0;
+
+ for (i = 0; i < seglen; i++) { // store range list to card
+ devpriv->ai_act_chanlist[i] = CR_CHAN(chanlist[i]);
+ outb(CR_CHAN(chanlist[0]) & 0xf, dev->iobase + PCL816_MUX);
+ outb(CR_RANGE(chanlist[0]), dev->iobase + PCL816_RANGE); /* select gain */
+ }
+
+ comedi_udelay(1);
+
+ outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX); /* select channel interval to scan */
+
+ return 1; // we can serve this with MUX logic
+}
+
+#ifdef unused
+/*
+==============================================================================
+ Enable(1)/disable(0) periodic interrupts from RTC
+*/
+static int set_rtc_irq_bit(unsigned char bit)
+{
+ unsigned char val;
+ unsigned long flags;
+
+ if (bit == 1) {
+ RTC_timer_lock++;
+ if (RTC_timer_lock > 1)
+ return 0;
+ } else {
+ RTC_timer_lock--;
+ if (RTC_timer_lock < 0)
+ RTC_timer_lock = 0;
+ if (RTC_timer_lock > 0)
+ return 0;
+ }
+
+ save_flags(flags);
+ cli();
+ val = CMOS_READ(RTC_CONTROL);
+ if (bit) {
+ val |= RTC_PIE;
+ } else {
+ val &= ~RTC_PIE;
+ }
+ CMOS_WRITE(val, RTC_CONTROL);
+ CMOS_READ(RTC_INTR_FLAGS);
+ restore_flags(flags);
+ return 0;
+}
+#endif
+
+/*
+==============================================================================
+ Free any resources that we have claimed
+*/
+static void free_resources(struct comedi_device * dev)
+{
+ //rt_printk("free_resource()\n");
+ if (dev->private) {
+ pcl816_ai_cancel(dev, devpriv->sub_ai);
+ pcl816_reset(dev);
+ if (devpriv->dma)
+ free_dma(devpriv->dma);
+ if (devpriv->dmabuf[0])
+ free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
+ if (devpriv->dmabuf[1])
+ free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
+#ifdef unused
+ if (devpriv->rtc_irq)
+ comedi_free_irq(devpriv->rtc_irq, dev);
+ if ((devpriv->dma_rtc) && (RTC_lock == 1)) {
+ if (devpriv->rtc_iobase)
+ release_region(devpriv->rtc_iobase,
+ devpriv->rtc_iosize);
+ }
+#endif
+ }
+
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ if (dev->iobase)
+ release_region(dev->iobase, this_board->io_range);
+ //rt_printk("free_resource() end\n");
+}
+
+/*
+==============================================================================
+
+ Initialization
+
+*/
+static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ unsigned long iobase;
+ unsigned int irq, dma;
+ unsigned long pages;
+ //int i;
+ struct comedi_subdevice *s;
+
+ /* claim our I/O space */
+ iobase = it->options[0];
+ printk("comedi%d: pcl816: board=%s, ioport=0x%03lx", dev->minor,
+ this_board->name, iobase);
+
+ if (!request_region(iobase, this_board->io_range, "pcl816")) {
+ rt_printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+ if (pcl816_check(iobase)) {
+ rt_printk(", I cann't detect board. FAIL!\n");
+ return -EIO;
+ }
+
+ if ((ret = alloc_private(dev, sizeof(struct pcl816_private))) < 0)
+ return ret; /* Can't alloc mem */
+
+ /* set up some name stuff */
+ dev->board_name = this_board->name;
+
+ /* grab our IRQ */
+ irq = 0;
+ if (this_board->IRQbits != 0) { /* board support IRQ */
+ irq = it->options[1];
+ if (irq) { /* we want to use IRQ */
+ if (((1 << irq) & this_board->IRQbits) == 0) {
+ rt_printk
+ (", IRQ %u is out of allowed range, DISABLING IT",
+ irq);
+ irq = 0; /* Bad IRQ */
+ } else {
+ if (comedi_request_irq(irq, interrupt_pcl816, 0,
+ "pcl816", dev)) {
+ rt_printk
+ (", unable to allocate IRQ %u, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk(", irq=%u", irq);
+ }
+ }
+ }
+ }
+
+ dev->irq = irq;
+ if (irq) {
+ devpriv->irq_free = 1;
+ } /* 1=we have allocated irq */
+ else {
+ devpriv->irq_free = 0;
+ }
+ devpriv->irq_blocked = 0; /* number of subdevice which use IRQ */
+ devpriv->int816_mode = 0; /* mode of irq */
+
+#ifdef unused
+ /* grab RTC for DMA operations */
+ devpriv->dma_rtc = 0;
+ if (it->options[2] > 0) { // we want to use DMA
+ if (RTC_lock == 0) {
+ if (!request_region(RTC_PORT(0), RTC_IO_EXTENT,
+ "pcl816 (RTC)"))
+ goto no_rtc;
+ }
+ devpriv->rtc_iobase = RTC_PORT(0);
+ devpriv->rtc_iosize = RTC_IO_EXTENT;
+ RTC_lock++;
+#ifdef UNTESTED_CODE
+ if (!comedi_request_irq(RTC_IRQ,
+ interrupt_pcl816_ai_mode13_dma_rtc, 0,
+ "pcl816 DMA (RTC)", dev)) {
+ devpriv->dma_rtc = 1;
+ devpriv->rtc_irq = RTC_IRQ;
+ rt_printk(", dma_irq=%u", devpriv->rtc_irq);
+ } else {
+ RTC_lock--;
+ if (RTC_lock == 0) {
+ if (devpriv->rtc_iobase)
+ release_region(devpriv->rtc_iobase,
+ devpriv->rtc_iosize);
+ }
+ devpriv->rtc_iobase = 0;
+ devpriv->rtc_iosize = 0;
+ }
+#else
+ printk("pcl816: RTC code missing");
+#endif
+
+ }
+
+ no_rtc:
+#endif
+ /* grab our DMA */
+ dma = 0;
+ devpriv->dma = dma;
+ if ((devpriv->irq_free == 0) && (devpriv->dma_rtc == 0))
+ goto no_dma; /* if we haven't IRQ, we can't use DMA */
+
+ if (this_board->DMAbits != 0) { /* board support DMA */
+ dma = it->options[2];
+ if (dma < 1)
+ goto no_dma; /* DMA disabled */
+
+ if (((1 << dma) & this_board->DMAbits) == 0) {
+ rt_printk(", DMA is out of allowed range, FAIL!\n");
+ return -EINVAL; /* Bad DMA */
+ }
+ ret = request_dma(dma, "pcl816");
+ if (ret) {
+ rt_printk(", unable to allocate DMA %u, FAIL!\n", dma);
+ return -EBUSY; /* DMA isn't free */
+ }
+
+ devpriv->dma = dma;
+ rt_printk(", dma=%u", dma);
+ pages = 2; /* we need 16KB */
+ devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
+
+ if (!devpriv->dmabuf[0]) {
+ rt_printk(", unable to allocate DMA buffer, FAIL!\n");
+ /* maybe experiment with try_to_free_pages() will help .... */
+ return -EBUSY; /* no buffer :-( */
+ }
+ devpriv->dmapages[0] = pages;
+ devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
+ devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE;
+ //rt_printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE);
+
+ if (devpriv->dma_rtc == 0) { // we must do duble buff :-(
+ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
+ if (!devpriv->dmabuf[1]) {
+ rt_printk
+ (", unable to allocate DMA buffer, FAIL!\n");
+ return -EBUSY;
+ }
+ devpriv->dmapages[1] = pages;
+ devpriv->hwdmaptr[1] =
+ virt_to_bus((void *)devpriv->dmabuf[1]);
+ devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
+ }
+ }
+
+ no_dma:
+
+/* if (this_board->n_aochan > 0)
+ subdevs[1] = COMEDI_SUBD_AO;
+ if (this_board->n_dichan > 0)
+ subdevs[2] = COMEDI_SUBD_DI;
+ if (this_board->n_dochan > 0)
+ subdevs[3] = COMEDI_SUBD_DO;
+*/
+ if ((ret = alloc_subdevices(dev, 1)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ if (this_board->n_aichan > 0) {
+ s->type = COMEDI_SUBD_AI;
+ devpriv->sub_ai = s;
+ dev->read_subdev = s;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = this_board->n_aichan;
+ s->subdev_flags |= SDF_DIFF;
+ //printk (", %dchans DIFF DAC - %d", s->n_chan, i);
+ s->maxdata = this_board->ai_maxdata;
+ s->len_chanlist = this_board->ai_chanlist;
+ s->range_table = this_board->ai_range_type;
+ s->cancel = pcl816_ai_cancel;
+ s->do_cmdtest = pcl816_ai_cmdtest;
+ s->do_cmd = pcl816_ai_cmd;
+ s->poll = pcl816_ai_poll;
+ s->insn_read = pcl816_ai_insn_read;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+#if 0
+case COMEDI_SUBD_AO:
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = this_board->ao_maxdata;
+ s->len_chanlist = this_board->ao_chanlist;
+ s->range_table = this_board->ao_range_type;
+ break;
+
+case COMEDI_SUBD_DI:
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = this_board->n_dichan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dichan;
+ s->range_table = &range_digital;
+ break;
+
+case COMEDI_SUBD_DO:
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = this_board->n_dochan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dochan;
+ s->range_table = &range_digital;
+ break;
+#endif
+
+ pcl816_reset(dev);
+
+ rt_printk("\n");
+
+ return 0;
+}
+
+/*
+==============================================================================
+ Removes device
+ */
+static int pcl816_detach(struct comedi_device * dev)
+{
+ DEBUG(rt_printk("comedi%d: pcl816: remove\n", dev->minor);
+ )
+ free_resources(dev);
+#ifdef unused
+ if (devpriv->dma_rtc)
+ RTC_lock--;
+#endif
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
new file mode 100644
index 00000000000..43a9d56c6a4
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -0,0 +1,1988 @@
+/*
+ comedi/drivers/pcl818.c
+
+ Author: Michal Dobes <dobes@tesnet.cz>
+
+ hardware driver for Advantech cards:
+ card: PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818, PCL-718
+ driver: pcl818l, pcl818h, pcl818hd, pcl818hg, pcl818, pcl718
+*/
+/*
+Driver: pcl818
+Description: Advantech PCL-818 cards, PCL-718
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCL-818L (pcl818l), PCL-818H (pcl818h),
+ PCL-818HD (pcl818hd), PCL-818HG (pcl818hg), PCL-818 (pcl818),
+ PCL-718 (pcl718)
+Status: works
+
+All cards have 16 SE/8 DIFF ADCs, one or two DACs, 16 DI and 16 DO.
+Differences are only at maximal sample speed, range list and FIFO
+support.
+The driver support AI mode 0, 1, 3 other subdevices (AO, DI, DO) support
+only mode 0. If DMA/FIFO/INT are disabled then AI support only mode 0.
+PCL-818HD and PCL-818HG support 1kword FIFO. Driver support this FIFO
+but this code is untested.
+A word or two about DMA. Driver support DMA operations at two ways:
+1) DMA uses two buffers and after one is filled then is generated
+ INT and DMA restart with second buffer. With this mode I'm unable run
+ more that 80Ksamples/secs without data dropouts on K6/233.
+2) DMA uses one buffer and run in autoinit mode and the data are
+ from DMA buffer moved on the fly with 2kHz interrupts from RTC.
+ This mode is used if the interrupt 8 is available for allocation.
+ If not, then first DMA mode is used. With this I can run at
+ full speed one card (100ksamples/secs) or two cards with
+ 60ksamples/secs each (more is problem on account of ISA limitations).
+ To use this mode you must have compiled kernel with disabled
+ "Enhanced Real Time Clock Support".
+ Maybe you can have problems if you use xntpd or similar.
+ If you've data dropouts with DMA mode 2 then:
+ a) disable IDE DMA
+ b) switch text mode console to fb.
+
+ Options for PCL-818L:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0, 10=10MHz clock for 8254
+ 1= 1MHz clock for 8254
+ [4] - 0, 5=A/D input -5V.. +5V
+ 1, 10=A/D input -10V..+10V
+ [5] - 0, 5=D/A output 0-5V (internal reference -5V)
+ 1, 10=D/A output 0-10V (internal reference -10V)
+ 2 =D/A output unknow (external reference)
+
+ Options for PCL-818, PCL-818H:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0, 10=10MHz clock for 8254
+ 1= 1MHz clock for 8254
+ [4] - 0, 5=D/A output 0-5V (internal reference -5V)
+ 1, 10=D/A output 0-10V (internal reference -10V)
+ 2 =D/A output unknow (external reference)
+
+ Options for PCL-818HD, PCL-818HG:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - DMA/FIFO (-1=use FIFO, 0=disable both FIFO and DMA,
+ 1=use DMA ch 1, 3=use DMA ch 3)
+ [3] - 0, 10=10MHz clock for 8254
+ 1= 1MHz clock for 8254
+ [4] - 0, 5=D/A output 0-5V (internal reference -5V)
+ 1, 10=D/A output 0-10V (internal reference -10V)
+ 2 =D/A output unknow (external reference)
+
+ Options for PCL-718:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0, 10=10MHz clock for 8254
+ 1= 1MHz clock for 8254
+ [4] - 0=A/D Range is +/-10V
+ 1= +/-5V
+ 2= +/-2.5V
+ 3= +/-1V
+ 4= +/-0.5V
+ 5= user defined bipolar
+ 6= 0-10V
+ 7= 0-5V
+ 8= 0-2V
+ 9= 0-1V
+ 10= user defined unipolar
+ [5] - 0, 5=D/A outputs 0-5V (internal reference -5V)
+ 1, 10=D/A outputs 0-10V (internal reference -10V)
+ 2=D/A outputs unknow (external reference)
+ [6] - 0, 60=max 60kHz A/D sampling
+ 1,100=max 100kHz A/D sampling (PCL-718 with Option 001 installed)
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+
+// #define PCL818_MODE13_AO 1
+
+// boards constants
+
+#define boardPCL818L 0
+#define boardPCL818H 1
+#define boardPCL818HD 2
+#define boardPCL818HG 3
+#define boardPCL818 4
+#define boardPCL718 5
+
+// IO space len
+#define PCLx1x_RANGE 16
+// IO space len if we use FIFO
+#define PCLx1xFIFO_RANGE 32
+
+// W: clear INT request
+#define PCL818_CLRINT 8
+// R: return status byte
+#define PCL818_STATUS 8
+// R: A/D high byte W: A/D range control
+#define PCL818_RANGE 1
+// R: next mux scan channel W: mux scan channel & range control pointer
+#define PCL818_MUX 2
+// R/W: operation control register
+#define PCL818_CONTROL 9
+// W: counter enable
+#define PCL818_CNTENABLE 10
+
+// R: low byte of A/D W: soft A/D trigger
+#define PCL818_AD_LO 0
+// R: high byte of A/D W: A/D range control
+#define PCL818_AD_HI 1
+// W: D/A low&high byte
+#define PCL818_DA_LO 4
+#define PCL818_DA_HI 5
+// R: low&high byte of DI
+#define PCL818_DI_LO 3
+#define PCL818_DI_HI 11
+// W: low&high byte of DO
+#define PCL818_DO_LO 3
+#define PCL818_DO_HI 11
+// W: PCL718 second D/A
+#define PCL718_DA2_LO 6
+#define PCL718_DA2_HI 7
+// counters
+#define PCL818_CTR0 12
+#define PCL818_CTR1 13
+#define PCL818_CTR2 14
+// W: counter control
+#define PCL818_CTRCTL 15
+
+// W: fifo enable/disable
+#define PCL818_FI_ENABLE 6
+// W: fifo interrupt clear
+#define PCL818_FI_INTCLR 20
+// W: fifo interrupt clear
+#define PCL818_FI_FLUSH 25
+// R: fifo status
+#define PCL818_FI_STATUS 25
+// R: one record from FIFO
+#define PCL818_FI_DATALO 23
+#define PCL818_FI_DATAHI 23
+
+// type of interrupt handler
+#define INT_TYPE_AI1_INT 1
+#define INT_TYPE_AI1_DMA 2
+#define INT_TYPE_AI1_FIFO 3
+#define INT_TYPE_AI3_INT 4
+#define INT_TYPE_AI3_DMA 5
+#define INT_TYPE_AI3_FIFO 6
+#ifdef PCL818_MODE13_AO
+#define INT_TYPE_AO1_INT 7
+#define INT_TYPE_AO3_INT 8
+#endif
+
+#ifdef unused
+// RTC stuff...
+#define INT_TYPE_AI1_DMA_RTC 9
+#define INT_TYPE_AI3_DMA_RTC 10
+
+#define RTC_IRQ 8
+#define RTC_IO_EXTENT 0x10
+#endif
+
+#define MAGIC_DMA_WORD 0x5a5a
+
+static const struct comedi_lrange range_pcl818h_ai = { 9, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ BIP_RANGE(10),
+ }
+};
+
+static const struct comedi_lrange range_pcl818hg_ai = { 10, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.005),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01),
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.01),
+ }
+};
+
+static const struct comedi_lrange range_pcl818l_l_ai = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ }
+};
+
+static const struct comedi_lrange range_pcl818l_h_ai = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ }
+};
+
+static const struct comedi_lrange range718_bipolar1 = { 1, {BIP_RANGE(1),} };
+static const struct comedi_lrange range718_bipolar0_5 = { 1, {BIP_RANGE(0.5),} };
+static const struct comedi_lrange range718_unipolar2 = { 1, {UNI_RANGE(2),} };
+static const struct comedi_lrange range718_unipolar1 = { 1, {BIP_RANGE(1),} };
+
+static int pcl818_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl818_detach(struct comedi_device * dev);
+
+#ifdef unused
+static int RTC_lock = 0; /* RTC lock */
+static int RTC_timer_lock = 0; /* RTC int lock */
+#endif
+
+struct pcl818_board {
+
+ const char *name; // driver name
+ int n_ranges; // len of range list
+ int n_aichan_se; // num of A/D chans in single ended mode
+ int n_aichan_diff; // num of A/D chans in diferencial mode
+ unsigned int ns_min; // minimal alllowed delay between samples (in ns)
+ int n_aochan; // num of D/A chans
+ int n_dichan; // num of DI chans
+ int n_dochan; // num of DO chans
+ const struct comedi_lrange *ai_range_type; // default A/D rangelist
+ const struct comedi_lrange *ao_range_type; // default D/A rangelist
+ unsigned int io_range; // len of IO space
+ unsigned int IRQbits; // allowed interrupts
+ unsigned int DMAbits; // allowed DMA chans
+ int ai_maxdata; // maxdata for A/D
+ int ao_maxdata; // maxdata for D/A
+ unsigned char fifo; // 1=board has FIFO
+ int is_818;
+};
+
+
+static const struct pcl818_board boardtypes[] = {
+ {"pcl818l", 4, 16, 8, 25000, 1, 16, 16, &range_pcl818l_l_ai,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 0, 1},
+ {"pcl818h", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 0, 1},
+ {"pcl818hd", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 1, 1},
+ {"pcl818hg", 12, 16, 8, 10000, 1, 16, 16, &range_pcl818hg_ai,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 1, 1},
+ {"pcl818", 9, 16, 8, 10000, 2, 16, 16, &range_pcl818h_ai,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 0, 1},
+ {"pcl718", 1, 16, 8, 16000, 2, 16, 16, &range_unipolar5,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 0, 0},
+ /* pcm3718 */
+ {"pcm3718", 9, 16, 8, 10000, 0, 16, 16, &range_pcl818h_ai,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 0, 1 /* XXX ? */ },
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl818_board))
+
+static struct comedi_driver driver_pcl818 = {
+ driver_name:"pcl818",
+ module:THIS_MODULE,
+ attach:pcl818_attach,
+ detach:pcl818_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl818_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl818);
+
+struct pcl818_private {
+
+ unsigned int dma; // used DMA, 0=don't use DMA
+ int dma_rtc; // 1=RTC used with DMA, 0=no RTC alloc
+ unsigned int io_range;
+#ifdef unused
+ unsigned long rtc_iobase; // RTC port region
+ unsigned int rtc_iosize;
+ unsigned int rtc_irq;
+ struct timer_list rtc_irq_timer; // timer for RTC sanity check
+ unsigned long rtc_freq; // RTC int freq
+ int rtc_irq_blocked; // 1=we now do AI with DMA&RTC
+#endif
+ unsigned long dmabuf[2]; // pointers to begin of DMA buffers
+ unsigned int dmapages[2]; // len of DMA buffers in PAGE_SIZEs
+ unsigned int hwdmaptr[2]; // hardware address of DMA buffers
+ unsigned int hwdmasize[2]; // len of DMA buffers in Bytes
+ unsigned int dmasamplsize; // size in samples hwdmasize[0]/2
+ unsigned int last_top_dma; // DMA pointer in last RTC int
+ int next_dma_buf; // which DMA buffer will be used next round
+ long dma_runs_to_end; // how many we must permorm DMA transfer to end of record
+ unsigned long last_dma_run; // how many bytes we must transfer on last DMA page
+ unsigned char neverending_ai; // if=1, then we do neverending record (you must use cancel())
+ unsigned int ns_min; // manimal alllowed delay between samples (in us) for actual card
+ int i8253_osc_base; // 1/frequency of on board oscilator in ns
+ int irq_free; // 1=have allocated IRQ
+ int irq_blocked; // 1=IRQ now uses any subdev
+ int irq_was_now_closed; // when IRQ finish, there's stored int818_mode for last interrupt
+ int ai_mode; // who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma
+ struct comedi_subdevice *last_int_sub; // ptr to subdevice which now finish
+ int ai_act_scan; // how many scans we finished
+ int ai_act_chan; // actual position in actual scan
+ unsigned int act_chanlist[16]; // MUX setting for actual AI operations
+ unsigned int act_chanlist_len; // how long is actual MUX list
+ unsigned int act_chanlist_pos; // actual position in MUX list
+ unsigned int ai_scans; // len of scanlist
+ unsigned int ai_n_chan; // how many channels is measured
+ unsigned int *ai_chanlist; // actaul chanlist
+ unsigned int ai_flags; // flaglist
+ unsigned int ai_data_len; // len of data buffer
+ short *ai_data; // data buffer
+ unsigned int ai_timer1; // timers
+ unsigned int ai_timer2;
+ struct comedi_subdevice *sub_ai; // ptr to AI subdevice
+ unsigned char usefifo; // 1=use fifo
+ unsigned int ao_readback[2];
+};
+
+
+static const unsigned int muxonechan[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // used for gain list programming
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
+};
+
+#define devpriv ((struct pcl818_private *)dev->private)
+#define this_board ((const struct pcl818_board *)dev->board_ptr)
+
+/*
+==============================================================================
+*/
+static void setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan, unsigned int seglen);
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan);
+
+static int pcl818_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2);
+
+#ifdef unused
+static int set_rtc_irq_bit(unsigned char bit);
+static void rtc_dropped_irq(unsigned long data);
+static int rtc_setfreq_irq(int freq);
+#endif
+
+/*
+==============================================================================
+ ANALOG INPUT MODE0, 818 cards, slow version
+*/
+static int pcl818_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int timeout;
+
+ /* software trigger, DMA and INT off */
+ outb(0, dev->iobase + PCL818_CONTROL);
+
+ /* select channel */
+ outb(muxonechan[CR_CHAN(insn->chanspec)], dev->iobase + PCL818_MUX);
+
+ /* select gain */
+ outb(CR_RANGE(insn->chanspec), dev->iobase + PCL818_RANGE);
+
+ for (n = 0; n < insn->n; n++) {
+
+ /* clear INT (conversion end) flag */
+ outb(0, dev->iobase + PCL818_CLRINT);
+
+ /* start conversion */
+ outb(0, dev->iobase + PCL818_AD_LO);
+
+ timeout = 100;
+ while (timeout--) {
+ if (inb(dev->iobase + PCL818_STATUS) & 0x10)
+ goto conv_finish;
+ comedi_udelay(1);
+ }
+ comedi_error(dev, "A/D insn timeout");
+ /* clear INT (conversion end) flag */
+ outb(0, dev->iobase + PCL818_CLRINT);
+ return -EIO;
+
+ conv_finish:
+ data[n] = ((inb(dev->iobase + PCL818_AD_HI) << 4) |
+ (inb(dev->iobase + PCL818_AD_LO) >> 4));
+ }
+
+ return n;
+}
+
+/*
+==============================================================================
+ ANALOG OUTPUT MODE0, 818 cards
+ only one sample per call is supported
+*/
+static int pcl818_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ data[n] = devpriv->ao_readback[chan];
+ }
+
+ return n;
+}
+
+static int pcl818_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ devpriv->ao_readback[chan] = data[n];
+ outb((data[n] & 0x000f) << 4, dev->iobase +
+ (chan) ? PCL718_DA2_LO : PCL818_DA_LO);
+ outb((data[n] & 0x0ff0) >> 4, dev->iobase +
+ (chan) ? PCL718_DA2_HI : PCL818_DA_HI);
+ }
+
+ return n;
+}
+
+/*
+==============================================================================
+ DIGITAL INPUT MODE0, 818 cards
+
+ only one sample per call is supported
+*/
+static int pcl818_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + PCL818_DI_LO) |
+ (inb(dev->iobase + PCL818_DI_HI) << 8);
+
+ return 2;
+}
+
+/*
+==============================================================================
+ DIGITAL OUTPUT MODE0, 818 cards
+
+ only one sample per call is supported
+*/
+static int pcl818_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+
+ outb(s->state & 0xff, dev->iobase + PCL818_DO_LO);
+ outb((s->state >> 8), dev->iobase + PCL818_DO_HI);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+==============================================================================
+ analog input interrupt mode 1 & 3, 818 cards
+ one sample per interrupt version
+*/
+static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int low;
+ int timeout = 50; /* wait max 50us */
+
+ while (timeout--) {
+ if (inb(dev->iobase + PCL818_STATUS) & 0x10)
+ goto conv_finish;
+ comedi_udelay(1);
+ }
+ outb(0, dev->iobase + PCL818_STATUS); /* clear INT request */
+ comedi_error(dev, "A/D mode1/3 IRQ without DRDY!");
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+
+ conv_finish:
+ low = inb(dev->iobase + PCL818_AD_LO);
+ comedi_buf_put(s->async, ((inb(dev->iobase + PCL818_AD_HI) << 4) | (low >> 4))); // get one sample
+ outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
+
+ if ((low & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!
+ rt_printk
+ ("comedi: A/D mode1/3 IRQ - channel dropout %x!=%x !\n",
+ (low & 0xf),
+ devpriv->act_chanlist[devpriv->act_chanlist_pos]);
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+ if (s->async->cur_chan == 0) {
+ // rt_printk("E");
+ devpriv->ai_act_scan--;
+ }
+
+ if (!devpriv->neverending_ai) {
+ if (devpriv->ai_act_scan == 0) { /* all data sampled */
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ }
+ }
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+ analog input dma mode 1 & 3, 818 cards
+*/
+static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int i, len, bufptr;
+ unsigned long flags;
+ short *ptr;
+
+ disable_dma(devpriv->dma);
+ devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
+ if ((devpriv->dma_runs_to_end) > -1 || devpriv->neverending_ai) { // switch dma bufs
+ set_dma_mode(devpriv->dma, DMA_MODE_READ);
+ flags = claim_dma_lock();
+ set_dma_addr(devpriv->dma,
+ devpriv->hwdmaptr[devpriv->next_dma_buf]);
+ if (devpriv->dma_runs_to_end || devpriv->neverending_ai) {
+ set_dma_count(devpriv->dma,
+ devpriv->hwdmasize[devpriv->next_dma_buf]);
+ } else {
+ set_dma_count(devpriv->dma, devpriv->last_dma_run);
+ }
+ release_dma_lock(flags);
+ enable_dma(devpriv->dma);
+ }
+ rt_printk("comedi: A/D mode1/3 IRQ \n");
+
+ devpriv->dma_runs_to_end--;
+ outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
+ ptr = (short *) devpriv->dmabuf[1 - devpriv->next_dma_buf];
+
+ len = devpriv->hwdmasize[0] >> 1;
+ bufptr = 0;
+
+ for (i = 0; i < len; i++) {
+ if ((ptr[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!
+ rt_printk
+ ("comedi: A/D mode1/3 DMA - channel dropout %d(card)!=%d(chanlist) at %d !\n",
+ (ptr[bufptr] & 0xf),
+ devpriv->act_chanlist[devpriv->
+ act_chanlist_pos],
+ devpriv->act_chanlist_pos);
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ comedi_buf_put(s->async, ptr[bufptr++] >> 4); // get one sample
+
+ devpriv->act_chanlist_pos++;
+ if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+ devpriv->ai_act_scan--;
+ devpriv->act_chanlist_pos = 0;
+ }
+
+ if (!devpriv->neverending_ai)
+ if (devpriv->ai_act_scan == 0) { /* all data sampled */
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ // printk("done int ai13 dma\n");
+ return IRQ_HANDLED;
+ }
+ }
+
+ if (len > 0)
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+#ifdef unused
+/*
+==============================================================================
+ analog input dma mode 1 & 3 over RTC, 818 cards
+*/
+static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ unsigned long tmp;
+ unsigned int top1, top2, i, bufptr;
+ long ofs_dats;
+ short *dmabuf = (short *) devpriv->dmabuf[0];
+
+ //outb(2,0x378);
+ switch (devpriv->ai_mode) {
+ case INT_TYPE_AI1_DMA_RTC:
+ case INT_TYPE_AI3_DMA_RTC:
+ tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
+ mod_timer(&devpriv->rtc_irq_timer,
+ jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100);
+
+ for (i = 0; i < 10; i++) {
+ top1 = get_dma_residue(devpriv->dma);
+ top2 = get_dma_residue(devpriv->dma);
+ if (top1 == top2)
+ break;
+ }
+
+ if (top1 != top2)
+ return IRQ_HANDLED;
+ top1 = devpriv->hwdmasize[0] - top1; // where is now DMA in buffer
+ top1 >>= 1;
+ ofs_dats = top1 - devpriv->last_top_dma; // new samples from last call
+ if (ofs_dats < 0)
+ ofs_dats = (devpriv->dmasamplsize) + ofs_dats;
+ if (!ofs_dats)
+ return IRQ_HANDLED; // exit=no new samples from last call
+ // obsluz data
+ i = devpriv->last_top_dma - 1;
+ i &= (devpriv->dmasamplsize - 1);
+
+ if (dmabuf[i] != MAGIC_DMA_WORD) { // DMA overflow!
+ comedi_error(dev, "A/D mode1/3 DMA buffer overflow!");
+ //rt_printk("I %d dmabuf[i] %d %d\n",i,dmabuf[i],devpriv->dmasamplsize);
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+ //rt_printk("r %ld ",ofs_dats);
+
+ bufptr = devpriv->last_top_dma;
+
+ for (i = 0; i < ofs_dats; i++) {
+ if ((dmabuf[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!
+ rt_printk
+ ("comedi: A/D mode1/3 DMA - channel dropout %d!=%d !\n",
+ (dmabuf[bufptr] & 0xf),
+ devpriv->act_chanlist[devpriv->
+ act_chanlist_pos]);
+ pcl818_ai_cancel(dev, s);
+ s->async->events |=
+ COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ comedi_buf_put(s->async, dmabuf[bufptr++] >> 4); // get one sample
+ bufptr &= (devpriv->dmasamplsize - 1);
+
+ if (s->async->cur_chan == 0) {
+ devpriv->ai_act_scan--;
+ }
+
+ if (!devpriv->neverending_ai)
+ if (devpriv->ai_act_scan == 0) { /* all data sampled */
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ //printk("done int ai13 dma\n");
+ return IRQ_HANDLED;
+ }
+ }
+
+ devpriv->last_top_dma = bufptr;
+ bufptr--;
+ bufptr &= (devpriv->dmasamplsize - 1);
+ dmabuf[bufptr] = MAGIC_DMA_WORD;
+ comedi_event(dev, s);
+ //outb(0,0x378);
+ return IRQ_HANDLED;
+ }
+
+ //outb(0,0x378);
+ return IRQ_HANDLED;
+}
+#endif
+
+/*
+==============================================================================
+ analog input interrupt mode 1 & 3, 818HD/HG cards
+*/
+static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int i, len, lo;
+
+ outb(0, dev->iobase + PCL818_FI_INTCLR); // clear fifo int request
+
+ lo = inb(dev->iobase + PCL818_FI_STATUS);
+
+ if (lo & 4) {
+ comedi_error(dev, "A/D mode1/3 FIFO overflow!");
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ if (lo & 1) {
+ comedi_error(dev, "A/D mode1/3 FIFO interrupt without data!");
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ if (lo & 2) {
+ len = 512;
+ } else {
+ len = 0;
+ }
+
+ for (i = 0; i < len; i++) {
+ lo = inb(dev->iobase + PCL818_FI_DATALO);
+ if ((lo & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!
+ rt_printk
+ ("comedi: A/D mode1/3 FIFO - channel dropout %d!=%d !\n",
+ (lo & 0xf),
+ devpriv->act_chanlist[devpriv->
+ act_chanlist_pos]);
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4)); // get one sample
+
+ if (s->async->cur_chan == 0) {
+ devpriv->ai_act_scan--;
+ }
+
+ if (!devpriv->neverending_ai)
+ if (devpriv->ai_act_scan == 0) { /* all data sampled */
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+ }
+
+ if (len > 0)
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+ INT procedure
+*/
+static irqreturn_t interrupt_pcl818(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+
+ if (!dev->attached) {
+ comedi_error(dev, "premature interrupt");
+ return IRQ_HANDLED;
+ }
+ //rt_printk("I\n");
+
+ switch (devpriv->ai_mode) {
+ case INT_TYPE_AI1_DMA:
+ case INT_TYPE_AI3_DMA:
+ return interrupt_pcl818_ai_mode13_dma(irq, d);
+ case INT_TYPE_AI1_INT:
+ case INT_TYPE_AI3_INT:
+ return interrupt_pcl818_ai_mode13_int(irq, d);
+ case INT_TYPE_AI1_FIFO:
+ case INT_TYPE_AI3_FIFO:
+ return interrupt_pcl818_ai_mode13_fifo(irq, d);
+#ifdef PCL818_MODE13_AO
+ case INT_TYPE_AO1_INT:
+ case INT_TYPE_AO3_INT:
+ return interrupt_pcl818_ao_mode13_int(irq, d);
+#endif
+ default:
+ break;
+ }
+
+ outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
+
+ if ((!dev->irq) || (!devpriv->irq_free) || (!devpriv->irq_blocked)
+ || (!devpriv->ai_mode)) {
+ if (devpriv->irq_was_now_closed) {
+ if (devpriv->neverending_ai &&
+ (devpriv->ai_mode == INT_TYPE_AI1_DMA
+ || devpriv->ai_mode ==
+ INT_TYPE_AI3_DMA)) {
+ /* we had neverending ai but ai_cancel() has been called
+ the cleanup from ai_cancel() has been delayed until know
+ because the card doesn't seem to like being reprogrammed
+ while a DMA transfer is in progress
+ */
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ devpriv->ai_mode = devpriv->irq_was_now_closed;
+ devpriv->irq_was_now_closed = 0;
+ devpriv->neverending_ai = 0;
+ pcl818_ai_cancel(dev, s);
+ }
+ devpriv->irq_was_now_closed = 0;
+ return IRQ_HANDLED;
+ }
+ comedi_error(dev, "bad IRQ!");
+ return IRQ_NONE;
+ }
+
+ comedi_error(dev, "IRQ from unknow source!");
+ return IRQ_NONE;
+}
+
+/*
+==============================================================================
+ ANALOG INPUT MODE 1 or 3 DMA , 818 cards
+*/
+static void pcl818_ai_mode13dma_int(int mode, struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ unsigned int flags;
+ unsigned int bytes;
+
+ rt_printk("mode13dma_int, mode: %d\n", mode);
+ disable_dma(devpriv->dma); // disable dma
+ bytes = devpriv->hwdmasize[0];
+ if (!devpriv->neverending_ai) {
+ bytes = devpriv->ai_n_chan * devpriv->ai_scans * sizeof(short); // how many
+ devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0]; // how many DMA pages we must fiil
+ devpriv->last_dma_run = bytes % devpriv->hwdmasize[0]; //on last dma transfer must be moved
+ devpriv->dma_runs_to_end--;
+ if (devpriv->dma_runs_to_end >= 0)
+ bytes = devpriv->hwdmasize[0];
+ }
+
+ devpriv->next_dma_buf = 0;
+ set_dma_mode(devpriv->dma, DMA_MODE_READ);
+ flags = claim_dma_lock();
+ clear_dma_ff(devpriv->dma);
+ set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
+ set_dma_count(devpriv->dma, bytes);
+ release_dma_lock(flags);
+ enable_dma(devpriv->dma);
+
+ if (mode == 1) {
+ devpriv->ai_mode = INT_TYPE_AI1_DMA;
+ outb(0x87 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+IRQ+DMA */
+ } else {
+ devpriv->ai_mode = INT_TYPE_AI3_DMA;
+ outb(0x86 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ+DMA */
+ };
+}
+
+#ifdef unused
+/*
+==============================================================================
+ ANALOG INPUT MODE 1 or 3 DMA rtc, 818 cards
+*/
+static void pcl818_ai_mode13dma_rtc(int mode, struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ unsigned int flags;
+ short *pole;
+
+ set_dma_mode(devpriv->dma, DMA_MODE_READ | DMA_AUTOINIT);
+ flags = claim_dma_lock();
+ clear_dma_ff(devpriv->dma);
+ set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
+ set_dma_count(devpriv->dma, devpriv->hwdmasize[0]);
+ release_dma_lock(flags);
+ enable_dma(devpriv->dma);
+ devpriv->last_top_dma = 0; //devpriv->hwdmasize[0];
+ pole = (short *) devpriv->dmabuf[0];
+ devpriv->dmasamplsize = devpriv->hwdmasize[0] / 2;
+ pole[devpriv->dmasamplsize - 1] = MAGIC_DMA_WORD;
+#ifdef unused
+ devpriv->rtc_freq = rtc_setfreq_irq(2048);
+ devpriv->rtc_irq_timer.expires =
+ jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100;
+ devpriv->rtc_irq_timer.data = (unsigned long)dev;
+ devpriv->rtc_irq_timer.function = rtc_dropped_irq;
+
+ add_timer(&devpriv->rtc_irq_timer);
+#endif
+
+ if (mode == 1) {
+ devpriv->int818_mode = INT_TYPE_AI1_DMA_RTC;
+ outb(0x07 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+DMA */
+ } else {
+ devpriv->int818_mode = INT_TYPE_AI3_DMA_RTC;
+ outb(0x06 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+DMA */
+ };
+}
+#endif
+
+/*
+==============================================================================
+ ANALOG INPUT MODE 1 or 3, 818 cards
+*/
+static int pcl818_ai_cmd_mode(int mode, struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int divisor1, divisor2;
+ unsigned int seglen;
+
+ rt_printk("pcl818_ai_cmd_mode()\n");
+ if ((!dev->irq) && (!devpriv->dma_rtc)) {
+ comedi_error(dev, "IRQ not defined!");
+ return -EINVAL;
+ }
+
+ if (devpriv->irq_blocked)
+ return -EBUSY;
+
+ start_pacer(dev, -1, 0, 0); // stop pacer
+
+ seglen = check_channel_list(dev, s, devpriv->ai_chanlist,
+ devpriv->ai_n_chan);
+ if (seglen < 1)
+ return -EINVAL;
+ setup_channel_list(dev, s, devpriv->ai_chanlist,
+ devpriv->ai_n_chan, seglen);
+
+ comedi_udelay(1);
+
+ devpriv->ai_act_scan = devpriv->ai_scans;
+ devpriv->ai_act_chan = 0;
+ devpriv->irq_blocked = 1;
+ devpriv->irq_was_now_closed = 0;
+ devpriv->neverending_ai = 0;
+ devpriv->act_chanlist_pos = 0;
+ devpriv->dma_runs_to_end = 0;
+
+ if ((devpriv->ai_scans == 0) || (devpriv->ai_scans == -1))
+ devpriv->neverending_ai = 1; //well, user want neverending
+
+ if (mode == 1) {
+ i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
+ &divisor2, &cmd->convert_arg, TRIG_ROUND_NEAREST);
+ if (divisor1 == 1) { /* PCL718/818 crash if any divisor is set to 1 */
+ divisor1 = 2;
+ divisor2 /= 2;
+ }
+ if (divisor2 == 1) {
+ divisor2 = 2;
+ divisor1 /= 2;
+ }
+ }
+
+ outb(0, dev->iobase + PCL818_CNTENABLE); /* enable pacer */
+
+ switch (devpriv->dma) {
+ case 1: // DMA
+ case 3:
+ if (devpriv->dma_rtc == 0) {
+ pcl818_ai_mode13dma_int(mode, dev, s);
+ }
+#ifdef unused
+ else {
+ pcl818_ai_mode13dma_rtc(mode, dev, s);
+ }
+#else
+ else {
+ return -EINVAL;
+ }
+#endif
+ break;
+ case 0: // IRQ
+ // rt_printk("IRQ\n");
+ if (mode == 1) {
+ devpriv->ai_mode = INT_TYPE_AI1_INT;
+ outb(0x83 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+IRQ */
+ } else {
+ devpriv->ai_mode = INT_TYPE_AI3_INT;
+ outb(0x82 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ */
+ };
+ break;
+ case -1: // FIFO
+ outb(1, dev->iobase + PCL818_FI_ENABLE); // enable FIFO
+ if (mode == 1) {
+ devpriv->ai_mode = INT_TYPE_AI1_FIFO;
+ outb(0x03, dev->iobase + PCL818_CONTROL); /* Pacer */
+ } else {
+ devpriv->ai_mode = INT_TYPE_AI3_FIFO;
+ outb(0x02, dev->iobase + PCL818_CONTROL);
+ }; /* Ext trig */
+ break;
+ }
+
+ start_pacer(dev, mode, divisor1, divisor2);
+
+#ifdef unused
+ switch (devpriv->ai_mode) {
+ case INT_TYPE_AI1_DMA_RTC:
+ case INT_TYPE_AI3_DMA_RTC:
+ set_rtc_irq_bit(1); /* start RTC */
+ break;
+ }
+#endif
+ rt_printk("pcl818_ai_cmd_mode() end\n");
+ return 0;
+}
+
+#ifdef unused
+/*
+==============================================================================
+ ANALOG OUTPUT MODE 1 or 3, 818 cards
+*/
+#ifdef PCL818_MODE13_AO
+static int pcl818_ao_mode13(int mode, struct comedi_device * dev, struct comedi_subdevice * s,
+ comedi_trig * it)
+{
+ int divisor1, divisor2;
+
+ if (!dev->irq) {
+ comedi_error(dev, "IRQ not defined!");
+ return -EINVAL;
+ }
+
+ if (devpriv->irq_blocked)
+ return -EBUSY;
+
+ start_pacer(dev, -1, 0, 0); // stop pacer
+
+ devpriv->int13_act_scan = it->n;
+ devpriv->int13_act_chan = 0;
+ devpriv->irq_blocked = 1;
+ devpriv->irq_was_now_closed = 0;
+ devpriv->neverending_ai = 0;
+ devpriv->act_chanlist_pos = 0;
+
+ if (mode == 1) {
+ i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
+ &divisor2, &it->trigvar, TRIG_ROUND_NEAREST);
+ if (divisor1 == 1) { /* PCL818 crash if any divisor is set to 1 */
+ divisor1 = 2;
+ divisor2 /= 2;
+ }
+ if (divisor2 == 1) {
+ divisor2 = 2;
+ divisor1 /= 2;
+ }
+ }
+
+ outb(0, dev->iobase + PCL818_CNTENABLE); /* enable pacer */
+ if (mode == 1) {
+ devpriv->int818_mode = INT_TYPE_AO1_INT;
+ outb(0x83 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+IRQ */
+ } else {
+ devpriv->int818_mode = INT_TYPE_AO3_INT;
+ outb(0x82 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ */
+ };
+
+ start_pacer(dev, mode, divisor1, divisor2);
+
+ return 0;
+}
+
+/*
+==============================================================================
+ ANALOG OUTPUT MODE 1, 818 cards
+*/
+static int pcl818_ao_mode1(struct comedi_device * dev, struct comedi_subdevice * s,
+ comedi_trig * it)
+{
+ return pcl818_ao_mode13(1, dev, s, it);
+}
+
+/*
+==============================================================================
+ ANALOG OUTPUT MODE 3, 818 cards
+*/
+static int pcl818_ao_mode3(struct comedi_device * dev, struct comedi_subdevice * s,
+ comedi_trig * it)
+{
+ return pcl818_ao_mode13(3, dev, s, it);
+}
+#endif
+#endif
+
+/*
+==============================================================================
+ Start/stop pacer onboard pacer
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2)
+{
+ outb(0xb4, dev->iobase + PCL818_CTRCTL);
+ outb(0x74, dev->iobase + PCL818_CTRCTL);
+ comedi_udelay(1);
+
+ if (mode == 1) {
+ outb(divisor2 & 0xff, dev->iobase + PCL818_CTR2);
+ outb((divisor2 >> 8) & 0xff, dev->iobase + PCL818_CTR2);
+ outb(divisor1 & 0xff, dev->iobase + PCL818_CTR1);
+ outb((divisor1 >> 8) & 0xff, dev->iobase + PCL818_CTR1);
+ }
+}
+
+/*
+==============================================================================
+ Check if channel list from user is builded correctly
+ If it's ok, then program scan/gain logic
+*/
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan)
+{
+ unsigned int chansegment[16];
+ unsigned int i, nowmustbechan, seglen, segpos;
+
+ /* correct channel and range number check itself comedi/range.c */
+ if (n_chan < 1) {
+ comedi_error(dev, "range/channel list is empty!");
+ return 0;
+ }
+
+ if (n_chan > 1) {
+ // first channel is everytime ok
+ chansegment[0] = chanlist[0];
+ // build part of chanlist
+ for (i = 1, seglen = 1; i < n_chan; i++, seglen++) {
+ // rt_printk("%d. %d %d\n",i,CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i]));
+ // we detect loop, this must by finish
+ if (chanlist[0] == chanlist[i])
+ break;
+ nowmustbechan =
+ (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
+ if (nowmustbechan != CR_CHAN(chanlist[i])) { // channel list isn't continous :-(
+ rt_printk
+ ("comedi%d: pcl818: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
+ dev->minor, i, CR_CHAN(chanlist[i]),
+ nowmustbechan, CR_CHAN(chanlist[0]));
+ return 0;
+ }
+ // well, this is next correct channel in list
+ chansegment[i] = chanlist[i];
+ }
+
+ // check whole chanlist
+ for (i = 0, segpos = 0; i < n_chan; i++) {
+ //rt_printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i]));
+ if (chanlist[i] != chansegment[i % seglen]) {
+ rt_printk
+ ("comedi%d: pcl818: bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
+ dev->minor, i, CR_CHAN(chansegment[i]),
+ CR_RANGE(chansegment[i]),
+ CR_AREF(chansegment[i]),
+ CR_CHAN(chanlist[i % seglen]),
+ CR_RANGE(chanlist[i % seglen]),
+ CR_AREF(chansegment[i % seglen]));
+ return 0; // chan/gain list is strange
+ }
+ }
+ } else {
+ seglen = 1;
+ }
+ rt_printk("check_channel_list: seglen %d\n", seglen);
+ return seglen;
+}
+
+static void setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan, unsigned int seglen)
+{
+ int i;
+
+ devpriv->act_chanlist_len = seglen;
+ devpriv->act_chanlist_pos = 0;
+
+ for (i = 0; i < seglen; i++) { // store range list to card
+ devpriv->act_chanlist[i] = CR_CHAN(chanlist[i]);
+ outb(muxonechan[CR_CHAN(chanlist[i])], dev->iobase + PCL818_MUX); /* select channel */
+ outb(CR_RANGE(chanlist[i]), dev->iobase + PCL818_RANGE); /* select gain */
+ }
+
+ comedi_udelay(1);
+
+ /* select channel interval to scan */
+ outb(devpriv->act_chanlist[0] | (devpriv->act_chanlist[seglen -
+ 1] << 4), dev->iobase + PCL818_MUX);
+}
+
+/*
+==============================================================================
+ Check if board is switched to SE (1) or DIFF(0) mode
+*/
+static int check_single_ended(unsigned int port)
+{
+ if (inb(port + PCL818_STATUS) & 0x20) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/*
+==============================================================================
+*/
+static int ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp, divisor1, divisor2;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err) {
+ return 1;
+ }
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ cmd->scan_begin_src = TRIG_FOLLOW;
+ err++;
+ }
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ if (err) {
+ return 2;
+ }
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ns_min) {
+ cmd->convert_arg = this_board->ns_min;
+ err++;
+ }
+ } else { /* TRIG_EXT */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->chanlist_len > s->n_chan) {
+ cmd->chanlist_len = s->n_chan;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err) {
+ return 3;
+ }
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
+ &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (cmd->convert_arg < this_board->ns_min)
+ cmd->convert_arg = this_board->ns_min;
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err) {
+ return 4;
+ }
+
+ /* step 5: complain about special chanlist considerations */
+
+ if (cmd->chanlist) {
+ if (!check_channel_list(dev, s, cmd->chanlist,
+ cmd->chanlist_len))
+ return 5; // incorrect channels list
+ }
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int retval;
+
+ rt_printk("pcl818_ai_cmd()\n");
+ devpriv->ai_n_chan = cmd->chanlist_len;
+ devpriv->ai_chanlist = cmd->chanlist;
+ devpriv->ai_flags = cmd->flags;
+ devpriv->ai_data_len = s->async->prealloc_bufsz;
+ devpriv->ai_data = s->async->prealloc_buf;
+ devpriv->ai_timer1 = 0;
+ devpriv->ai_timer2 = 0;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ai_scans = cmd->stop_arg;
+ } else {
+ devpriv->ai_scans = 0;
+ }
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) { // mode 1, 3
+ if (cmd->convert_src == TRIG_TIMER) { // mode 1
+ devpriv->ai_timer1 = cmd->convert_arg;
+ retval = pcl818_ai_cmd_mode(1, dev, s);
+ rt_printk("pcl818_ai_cmd() end\n");
+ return retval;
+ }
+ if (cmd->convert_src == TRIG_EXT) { // mode 3
+ return pcl818_ai_cmd_mode(3, dev, s);
+ }
+ }
+
+ return -1;
+}
+
+/*
+==============================================================================
+ cancel any mode 1-4 AI
+*/
+static int pcl818_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (devpriv->irq_blocked > 0) {
+ rt_printk("pcl818_ai_cancel()\n");
+ devpriv->irq_was_now_closed = devpriv->ai_mode;
+ devpriv->ai_mode = 0;
+
+ switch (devpriv->irq_was_now_closed) {
+#ifdef unused
+ case INT_TYPE_AI1_DMA_RTC:
+ case INT_TYPE_AI3_DMA_RTC:
+ set_rtc_irq_bit(0); // stop RTC
+ del_timer(&devpriv->rtc_irq_timer);
+#endif
+ case INT_TYPE_AI1_DMA:
+ case INT_TYPE_AI3_DMA:
+ if (devpriv->neverending_ai) {
+ /* wait for running dma transfer to end, do cleanup in interrupt */
+ goto end;
+ }
+ disable_dma(devpriv->dma);
+ case INT_TYPE_AI1_INT:
+ case INT_TYPE_AI3_INT:
+ case INT_TYPE_AI1_FIFO:
+ case INT_TYPE_AI3_FIFO:
+#ifdef PCL818_MODE13_AO
+ case INT_TYPE_AO1_INT:
+ case INT_TYPE_AO3_INT:
+#endif
+ outb(inb(dev->iobase + PCL818_CONTROL) & 0x73, dev->iobase + PCL818_CONTROL); /* Stop A/D */
+ comedi_udelay(1);
+ start_pacer(dev, -1, 0, 0);
+ outb(0, dev->iobase + PCL818_AD_LO);
+ inb(dev->iobase + PCL818_AD_LO);
+ inb(dev->iobase + PCL818_AD_HI);
+ outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
+ outb(0, dev->iobase + PCL818_CONTROL); /* Stop A/D */
+ if (devpriv->usefifo) { // FIFO shutdown
+ outb(0, dev->iobase + PCL818_FI_INTCLR);
+ outb(0, dev->iobase + PCL818_FI_FLUSH);
+ outb(0, dev->iobase + PCL818_FI_ENABLE);
+ }
+ devpriv->irq_blocked = 0;
+ devpriv->last_int_sub = s;
+ devpriv->neverending_ai = 0;
+ break;
+ }
+ }
+
+ end:
+ rt_printk("pcl818_ai_cancel() end\n");
+ return 0;
+}
+
+/*
+==============================================================================
+ chech for PCL818
+*/
+static int pcl818_check(unsigned long iobase)
+{
+ outb(0x00, iobase + PCL818_MUX);
+ comedi_udelay(1);
+ if (inb(iobase + PCL818_MUX) != 0x00)
+ return 1; //there isn't card
+ outb(0x55, iobase + PCL818_MUX);
+ comedi_udelay(1);
+ if (inb(iobase + PCL818_MUX) != 0x55)
+ return 1; //there isn't card
+ outb(0x00, iobase + PCL818_MUX);
+ comedi_udelay(1);
+ outb(0x18, iobase + PCL818_CONTROL);
+ comedi_udelay(1);
+ if (inb(iobase + PCL818_CONTROL) != 0x18)
+ return 1; //there isn't card
+ return 0; // ok, card exist
+}
+
+/*
+==============================================================================
+ reset whole PCL-818 cards
+*/
+static void pcl818_reset(struct comedi_device * dev)
+{
+ if (devpriv->usefifo) { // FIFO shutdown
+ outb(0, dev->iobase + PCL818_FI_INTCLR);
+ outb(0, dev->iobase + PCL818_FI_FLUSH);
+ outb(0, dev->iobase + PCL818_FI_ENABLE);
+ }
+ outb(0, dev->iobase + PCL818_DA_LO); // DAC=0V
+ outb(0, dev->iobase + PCL818_DA_HI);
+ comedi_udelay(1);
+ outb(0, dev->iobase + PCL818_DO_HI); // DO=$0000
+ outb(0, dev->iobase + PCL818_DO_LO);
+ comedi_udelay(1);
+ outb(0, dev->iobase + PCL818_CONTROL);
+ outb(0, dev->iobase + PCL818_CNTENABLE);
+ outb(0, dev->iobase + PCL818_MUX);
+ outb(0, dev->iobase + PCL818_CLRINT);
+ outb(0xb0, dev->iobase + PCL818_CTRCTL); /* Stop pacer */
+ outb(0x70, dev->iobase + PCL818_CTRCTL);
+ outb(0x30, dev->iobase + PCL818_CTRCTL);
+ if (this_board->is_818) {
+ outb(0, dev->iobase + PCL818_RANGE);
+ } else {
+ outb(0, dev->iobase + PCL718_DA2_LO);
+ outb(0, dev->iobase + PCL718_DA2_HI);
+ }
+}
+
+#ifdef unused
+/*
+==============================================================================
+ Enable(1)/disable(0) periodic interrupts from RTC
+*/
+static int set_rtc_irq_bit(unsigned char bit)
+{
+ unsigned char val;
+ unsigned long flags;
+
+ if (bit == 1) {
+ RTC_timer_lock++;
+ if (RTC_timer_lock > 1)
+ return 0;
+ } else {
+ RTC_timer_lock--;
+ if (RTC_timer_lock < 0)
+ RTC_timer_lock = 0;
+ if (RTC_timer_lock > 0)
+ return 0;
+ }
+
+ save_flags(flags);
+ cli();
+ val = CMOS_READ(RTC_CONTROL);
+ if (bit) {
+ val |= RTC_PIE;
+ } else {
+ val &= ~RTC_PIE;
+ }
+ CMOS_WRITE(val, RTC_CONTROL);
+ CMOS_READ(RTC_INTR_FLAGS);
+ restore_flags(flags);
+ return 0;
+}
+
+/*
+==============================================================================
+ Restart RTC if something stop it (xntpd every 11 mins or large IDE transfers)
+*/
+static void rtc_dropped_irq(unsigned long data)
+{
+ struct comedi_device *dev = (void *)data;
+ unsigned long flags, tmp;
+
+ switch (devpriv->int818_mode) {
+ case INT_TYPE_AI1_DMA_RTC:
+ case INT_TYPE_AI3_DMA_RTC:
+ mod_timer(&devpriv->rtc_irq_timer,
+ jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100);
+ save_flags(flags);
+ cli();
+ tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); /* restart */
+ restore_flags(flags);
+ break;
+ };
+}
+
+/*
+==============================================================================
+ Set frequency of interrupts from RTC
+*/
+static int rtc_setfreq_irq(int freq)
+{
+ int tmp = 0;
+ int rtc_freq;
+ unsigned char val;
+ unsigned long flags;
+
+ if (freq < 2)
+ freq = 2;
+ if (freq > 8192)
+ freq = 8192;
+
+ while (freq > (1 << tmp))
+ tmp++;
+
+ rtc_freq = 1 << tmp;
+
+ save_flags(flags);
+ cli();
+ val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
+ val |= (16 - tmp);
+ CMOS_WRITE(val, RTC_FREQ_SELECT);
+ restore_flags(flags);
+ return rtc_freq;
+}
+#endif
+
+/*
+==============================================================================
+ Free any resources that we have claimed
+*/
+static void free_resources(struct comedi_device * dev)
+{
+ //rt_printk("free_resource()\n");
+ if (dev->private) {
+ pcl818_ai_cancel(dev, devpriv->sub_ai);
+ pcl818_reset(dev);
+ if (devpriv->dma)
+ free_dma(devpriv->dma);
+ if (devpriv->dmabuf[0])
+ free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
+ if (devpriv->dmabuf[1])
+ free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
+#ifdef unused
+ if (devpriv->rtc_irq)
+ comedi_free_irq(devpriv->rtc_irq, dev);
+ if ((devpriv->dma_rtc) && (RTC_lock == 1)) {
+ if (devpriv->rtc_iobase)
+ release_region(devpriv->rtc_iobase,
+ devpriv->rtc_iosize);
+ }
+ if (devpriv->dma_rtc)
+ RTC_lock--;
+#endif
+ }
+
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ if (dev->iobase)
+ release_region(dev->iobase, devpriv->io_range);
+ //rt_printk("free_resource() end\n");
+}
+
+/*
+==============================================================================
+
+ Initialization
+
+*/
+static int pcl818_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ unsigned long iobase;
+ unsigned int irq, dma;
+ unsigned long pages;
+ struct comedi_subdevice *s;
+
+ if ((ret = alloc_private(dev, sizeof(struct pcl818_private))) < 0)
+ return ret; /* Can't alloc mem */
+
+ /* claim our I/O space */
+ iobase = it->options[0];
+ printk("comedi%d: pcl818: board=%s, ioport=0x%03lx",
+ dev->minor, this_board->name, iobase);
+ devpriv->io_range = this_board->io_range;
+ if ((this_board->fifo) && (it->options[2] == -1)) { // we've board with FIFO and we want to use FIFO
+ devpriv->io_range = PCLx1xFIFO_RANGE;
+ devpriv->usefifo = 1;
+ }
+ if (!request_region(iobase, devpriv->io_range, "pcl818")) {
+ rt_printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+ if (pcl818_check(iobase)) {
+ rt_printk(", I can't detect board. FAIL!\n");
+ return -EIO;
+ }
+
+ /* set up some name stuff */
+ dev->board_name = this_board->name;
+ /* grab our IRQ */
+ irq = 0;
+ if (this_board->IRQbits != 0) { /* board support IRQ */
+ irq = it->options[1];
+ if (irq) { /* we want to use IRQ */
+ if (((1 << irq) & this_board->IRQbits) == 0) {
+ rt_printk
+ (", IRQ %u is out of allowed range, DISABLING IT",
+ irq);
+ irq = 0; /* Bad IRQ */
+ } else {
+ if (comedi_request_irq(irq, interrupt_pcl818, 0,
+ "pcl818", dev)) {
+ rt_printk
+ (", unable to allocate IRQ %u, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk(", irq=%u", irq);
+ }
+ }
+ }
+ }
+
+ dev->irq = irq;
+ if (irq) {
+ devpriv->irq_free = 1;
+ } /* 1=we have allocated irq */
+ else {
+ devpriv->irq_free = 0;
+ }
+ devpriv->irq_blocked = 0; /* number of subdevice which use IRQ */
+ devpriv->ai_mode = 0; /* mode of irq */
+
+#ifdef unused
+ /* grab RTC for DMA operations */
+ devpriv->dma_rtc = 0;
+ if (it->options[2] > 0) { // we want to use DMA
+ if (RTC_lock == 0) {
+ if (!request_region(RTC_PORT(0), RTC_IO_EXTENT,
+ "pcl818 (RTC)"))
+ goto no_rtc;
+ }
+ devpriv->rtc_iobase = RTC_PORT(0);
+ devpriv->rtc_iosize = RTC_IO_EXTENT;
+ RTC_lock++;
+ if (!comedi_request_irq(RTC_IRQ,
+ interrupt_pcl818_ai_mode13_dma_rtc, 0,
+ "pcl818 DMA (RTC)", dev)) {
+ devpriv->dma_rtc = 1;
+ devpriv->rtc_irq = RTC_IRQ;
+ rt_printk(", dma_irq=%u", devpriv->rtc_irq);
+ } else {
+ RTC_lock--;
+ if (RTC_lock == 0) {
+ if (devpriv->rtc_iobase)
+ release_region(devpriv->rtc_iobase,
+ devpriv->rtc_iosize);
+ }
+ devpriv->rtc_iobase = 0;
+ devpriv->rtc_iosize = 0;
+ }
+ }
+
+ no_rtc:
+#endif
+ /* grab our DMA */
+ dma = 0;
+ devpriv->dma = dma;
+ if ((devpriv->irq_free == 0) && (devpriv->dma_rtc == 0))
+ goto no_dma; /* if we haven't IRQ, we can't use DMA */
+ if (this_board->DMAbits != 0) { /* board support DMA */
+ dma = it->options[2];
+ if (dma < 1)
+ goto no_dma; /* DMA disabled */
+ if (((1 << dma) & this_board->DMAbits) == 0) {
+ rt_printk(", DMA is out of allowed range, FAIL!\n");
+ return -EINVAL; /* Bad DMA */
+ }
+ ret = request_dma(dma, "pcl818");
+ if (ret) {
+ rt_printk(", unable to allocate DMA %u, FAIL!\n", dma);
+ return -EBUSY; /* DMA isn't free */
+ }
+ devpriv->dma = dma;
+ rt_printk(", dma=%u", dma);
+ pages = 2; /* we need 16KB */
+ devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
+ if (!devpriv->dmabuf[0]) {
+ rt_printk(", unable to allocate DMA buffer, FAIL!\n");
+ /* maybe experiment with try_to_free_pages() will help .... */
+ return -EBUSY; /* no buffer :-( */
+ }
+ devpriv->dmapages[0] = pages;
+ devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
+ devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE;
+ //rt_printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE);
+ if (devpriv->dma_rtc == 0) { // we must do duble buff :-(
+ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
+ if (!devpriv->dmabuf[1]) {
+ rt_printk
+ (", unable to allocate DMA buffer, FAIL!\n");
+ return -EBUSY;
+ }
+ devpriv->dmapages[1] = pages;
+ devpriv->hwdmaptr[1] =
+ virt_to_bus((void *)devpriv->dmabuf[1]);
+ devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
+ }
+ }
+
+ no_dma:
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ if (!this_board->n_aichan_se) {
+ s->type = COMEDI_SUBD_UNUSED;
+ } else {
+ s->type = COMEDI_SUBD_AI;
+ devpriv->sub_ai = s;
+ s->subdev_flags = SDF_READABLE;
+ if (check_single_ended(dev->iobase)) {
+ s->n_chan = this_board->n_aichan_se;
+ s->subdev_flags |= SDF_COMMON | SDF_GROUND;
+ printk(", %dchans S.E. DAC", s->n_chan);
+ } else {
+ s->n_chan = this_board->n_aichan_diff;
+ s->subdev_flags |= SDF_DIFF;
+ printk(", %dchans DIFF DAC", s->n_chan);
+ }
+ s->maxdata = this_board->ai_maxdata;
+ s->len_chanlist = s->n_chan;
+ s->range_table = this_board->ai_range_type;
+ s->cancel = pcl818_ai_cancel;
+ s->insn_read = pcl818_ai_insn_read;
+ if ((irq) || (devpriv->dma_rtc)) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmdtest = ai_cmdtest;
+ s->do_cmd = ai_cmd;
+ }
+ if (this_board->is_818) {
+ if ((it->options[4] == 1) || (it->options[4] == 10))
+ s->range_table = &range_pcl818l_h_ai; // secondary range list jumper selectable
+ } else {
+ switch (it->options[4]) {
+ case 0:
+ s->range_table = &range_bipolar10;
+ break;
+ case 1:
+ s->range_table = &range_bipolar5;
+ break;
+ case 2:
+ s->range_table = &range_bipolar2_5;
+ break;
+ case 3:
+ s->range_table = &range718_bipolar1;
+ break;
+ case 4:
+ s->range_table = &range718_bipolar0_5;
+ break;
+ case 6:
+ s->range_table = &range_unipolar10;
+ break;
+ case 7:
+ s->range_table = &range_unipolar5;
+ break;
+ case 8:
+ s->range_table = &range718_unipolar2;
+ break;
+ case 9:
+ s->range_table = &range718_unipolar1;
+ break;
+ default:
+ s->range_table = &range_unknown;
+ break;
+ }
+ }
+ }
+
+ s = dev->subdevices + 1;
+ if (!this_board->n_aochan) {
+ s->type = COMEDI_SUBD_UNUSED;
+ } else {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = this_board->ao_maxdata;
+ s->len_chanlist = this_board->n_aochan;
+ s->range_table = this_board->ao_range_type;
+ s->insn_read = pcl818_ao_insn_read;
+ s->insn_write = pcl818_ao_insn_write;
+#ifdef unused
+#ifdef PCL818_MODE13_AO
+ if (irq) {
+ s->trig[1] = pcl818_ao_mode1;
+ s->trig[3] = pcl818_ao_mode3;
+ }
+#endif
+#endif
+ if (this_board->is_818) {
+ if ((it->options[4] == 1) || (it->options[4] == 10))
+ s->range_table = &range_unipolar10;
+ if (it->options[4] == 2)
+ s->range_table = &range_unknown;
+ } else {
+ if ((it->options[5] == 1) || (it->options[5] == 10))
+ s->range_table = &range_unipolar10;
+ if (it->options[5] == 2)
+ s->range_table = &range_unknown;
+ }
+ }
+
+ s = dev->subdevices + 2;
+ if (!this_board->n_dichan) {
+ s->type = COMEDI_SUBD_UNUSED;
+ } else {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = this_board->n_dichan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dichan;
+ s->range_table = &range_digital;
+ s->insn_bits = pcl818_di_insn_bits;
+ }
+
+ s = dev->subdevices + 3;
+ if (!this_board->n_dochan) {
+ s->type = COMEDI_SUBD_UNUSED;
+ } else {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = this_board->n_dochan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dochan;
+ s->range_table = &range_digital;
+ s->insn_bits = pcl818_do_insn_bits;
+ }
+
+ /* select 1/10MHz oscilator */
+ if ((it->options[3] == 0) || (it->options[3] == 10)) {
+ devpriv->i8253_osc_base = 100;
+ } else {
+ devpriv->i8253_osc_base = 1000;
+ }
+
+ /* max sampling speed */
+ devpriv->ns_min = this_board->ns_min;
+
+ if (!this_board->is_818) {
+ if ((it->options[6] == 1) || (it->options[6] == 100))
+ devpriv->ns_min = 10000; /* extended PCL718 to 100kHz DAC */
+ }
+
+ pcl818_reset(dev);
+
+ rt_printk("\n");
+
+ return 0;
+}
+
+/*
+==============================================================================
+ Removes device
+ */
+static int pcl818_detach(struct comedi_device * dev)
+{
+ // rt_printk("comedi%d: pcl818: remove\n", dev->minor);
+ free_resources(dev);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c
new file mode 100644
index 00000000000..a3ed3a0e855
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcm3724.c
@@ -0,0 +1,307 @@
+/*
+ comedi/drivers/pcm724.c
+
+ Drew Csillag <drew_csillag@yahoo.com>
+
+ hardware driver for Advantech card:
+ card: PCM-3724
+ driver: pcm3724
+
+ Options for PCM-3724
+ [0] - IO Base
+*/
+/*
+Driver: pcm3724
+Description: Advantech PCM-3724
+Author: Drew Csillag <drew_csillag@yahoo.com>
+Devices: [Advantech] PCM-3724 (pcm724)
+Status: tested
+
+This is driver for digital I/O boards PCM-3724 with 48 DIO.
+It needs 8255.o for operations and only immediate mode is supported.
+See the source for configuration details.
+
+Copy/pasted/hacked from pcm724.c
+*/
+/*
+ * check_driver overrides:
+ * struct comedi_insn
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include "8255.h"
+
+#define PCM3724_SIZE 16
+#define SIZE_8255 4
+
+#define BUF_C0 0x1
+#define BUF_B0 0x2
+#define BUF_A0 0x4
+#define BUF_C1 0x8
+#define BUF_B1 0x10
+#define BUF_A1 0x20
+
+#define GATE_A0 0x4
+#define GATE_B0 0x2
+#define GATE_C0 0x1
+#define GATE_A1 0x20
+#define GATE_B1 0x10
+#define GATE_C1 0x8
+
+/* from 8255.c */
+#define CR_CW 0x80
+#define _8255_CR 3
+#define CR_B_IO 0x02
+#define CR_B_MODE 0x04
+#define CR_C_IO 0x09
+#define CR_A_IO 0x10
+#define CR_A_MODE(a) ((a)<<5)
+#define CR_CW 0x80
+
+static int pcm3724_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcm3724_detach(struct comedi_device * dev);
+
+struct pcm3724_board {
+ const char *name; // driver name
+ int dio; // num of DIO
+ int numofports; // num of 8255 subdevices
+ unsigned int IRQbits; // allowed interrupts
+ unsigned int io_range; // len of IO space
+};
+
+//used to track configured dios
+struct priv_pcm3724 {
+ int dio_1;
+ int dio_2;
+};
+
+static const struct pcm3724_board boardtypes[] = {
+ {"pcm3724", 48, 2, 0x00fc, PCM3724_SIZE,},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcm3724_board))
+#define this_board ((const struct pcm3724_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcm3724 = {
+ driver_name:"pcm3724",
+ module:THIS_MODULE,
+ attach:pcm3724_attach,
+ detach:pcm3724_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcm3724_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcm3724);
+
+// (setq c-basic-offset 8)
+
+static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
+{
+ unsigned long iobase = arg;
+ unsigned char inbres;
+ //printk("8255cb %d %d %d %lx\n", dir,port,data,arg);
+ if (dir) {
+ //printk("8255 cb outb(%x, %lx)\n", data, iobase+port);
+ outb(data, iobase + port);
+ return 0;
+ } else {
+ inbres = inb(iobase + port);
+ //printk("8255 cb inb(%lx) = %x\n", iobase+port, inbres);
+ return inbres;
+ }
+}
+
+static int compute_buffer(int config, int devno, struct comedi_subdevice * s)
+{
+ /* 1 in io_bits indicates output */
+ if (s->io_bits & 0x0000ff) {
+ if (devno == 0) {
+ config |= BUF_A0;
+ } else {
+ config |= BUF_A1;
+ }
+ }
+ if (s->io_bits & 0x00ff00) {
+ if (devno == 0) {
+ config |= BUF_B0;
+ } else {
+ config |= BUF_B1;
+ }
+ }
+ if (s->io_bits & 0xff0000) {
+ if (devno == 0) {
+ config |= BUF_C0;
+ } else {
+ config |= BUF_C1;
+ }
+ }
+ return config;
+}
+
+static void do_3724_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ int chanspec)
+{
+ int config;
+ int buffer_config;
+ unsigned long port_8255_cfg;
+
+ config = CR_CW;
+ buffer_config = 0;
+
+ /* 1 in io_bits indicates output, 1 in config indicates input */
+ if (!(s->io_bits & 0x0000ff)) {
+ config |= CR_A_IO;
+ }
+ if (!(s->io_bits & 0x00ff00)) {
+ config |= CR_B_IO;
+ }
+ if (!(s->io_bits & 0xff0000)) {
+ config |= CR_C_IO;
+ }
+
+ buffer_config = compute_buffer(0, 0, dev->subdevices);
+ buffer_config = compute_buffer(buffer_config, 1, (dev->subdevices) + 1);
+
+ if (s == dev->subdevices) {
+ port_8255_cfg = dev->iobase + _8255_CR;
+ } else {
+ port_8255_cfg = dev->iobase + SIZE_8255 + _8255_CR;
+ }
+ outb(buffer_config, dev->iobase + 8); /* update buffer register */
+ //printk("pcm3724 buffer_config (%lx) %d, %x\n", dev->iobase + _8255_CR, chanspec, buffer_config);
+ outb(config, port_8255_cfg);
+}
+
+static void enable_chan(struct comedi_device * dev, struct comedi_subdevice * s, int chanspec)
+{
+ unsigned int mask;
+ int gatecfg;
+ struct priv_pcm3724 *priv;
+
+ gatecfg = 0;
+ priv = (struct priv_pcm3724 *) (dev->private);
+
+ mask = 1 << CR_CHAN(chanspec);
+ if (s == dev->subdevices) { // subdev 0
+ priv->dio_1 |= mask;
+ } else { //subdev 1
+ priv->dio_2 |= mask;
+ }
+ if (priv->dio_1 & 0xff0000) {
+ gatecfg |= GATE_C0;
+ }
+ if (priv->dio_1 & 0xff00) {
+ gatecfg |= GATE_B0;
+ }
+ if (priv->dio_1 & 0xff) {
+ gatecfg |= GATE_A0;
+ }
+ if (priv->dio_2 & 0xff0000) {
+ gatecfg |= GATE_C1;
+ }
+ if (priv->dio_2 & 0xff00) {
+ gatecfg |= GATE_B1;
+ }
+ if (priv->dio_2 & 0xff) {
+ gatecfg |= GATE_A1;
+ }
+ // printk("gate control %x\n", gatecfg);
+ outb(gatecfg, dev->iobase + 9);
+}
+
+/* overriding the 8255 insn config */
+static int subdev_3724_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int mask;
+ unsigned int bits;
+
+ mask = 1 << CR_CHAN(insn->chanspec);
+ if (mask & 0x0000ff) {
+ bits = 0x0000ff;
+ } else if (mask & 0x00ff00) {
+ bits = 0x00ff00;
+ } else if (mask & 0x0f0000) {
+ bits = 0x0f0000;
+ } else {
+ bits = 0xf00000;
+ }
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~bits;
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= bits;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ do_3724_config(dev, s, insn->chanspec);
+ enable_chan(dev, s, insn->chanspec);
+ return 1;
+}
+
+static int pcm3724_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned long iobase;
+ unsigned int iorange;
+ int ret, i, n_subdevices;
+
+ iobase = it->options[0];
+ iorange = this_board->io_range;
+ if ((ret = alloc_private(dev, sizeof(struct priv_pcm3724))) < 0)
+ return -ENOMEM;
+
+ ((struct priv_pcm3724 *) (dev->private))->dio_1 = 0;
+ ((struct priv_pcm3724 *) (dev->private))->dio_2 = 0;
+
+ printk("comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor,
+ this_board->name, iobase);
+ if (!iobase || !request_region(iobase, iorange, "pcm3724")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+ dev->board_name = this_board->name;
+ printk("\n");
+
+ n_subdevices = this_board->numofports;
+
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+ return ret;
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ subdev_8255_init(dev, dev->subdevices + i, subdev_8255_cb,
+ (unsigned long)(dev->iobase + SIZE_8255 * i));
+ ((dev->subdevices) + i)->insn_config = subdev_3724_insn_config;
+ };
+ return 0;
+}
+
+static int pcm3724_detach(struct comedi_device * dev)
+{
+ int i;
+
+ if (dev->subdevices) {
+ for (i = 0; i < dev->n_subdevices; i++) {
+ subdev_8255_cleanup(dev, dev->subdevices + i);
+ }
+ }
+ if (dev->iobase) {
+ release_region(dev->iobase, this_board->io_range);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c
new file mode 100644
index 00000000000..1de555fe645
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcm3730.c
@@ -0,0 +1,152 @@
+/*
+ * comedi/drivers/pcm3730.c
+ * Driver for PCM3730 and clones
+ * Blaine Lee
+ * from pcl725 by David S.
+ */
+/*
+Driver: pcm3730
+Description: PCM3730
+Author: Blaine Lee
+Devices: [Advantech] PCM-3730 (pcm3730)
+Status: unknown
+
+Configuration options:
+ [0] - I/O port base
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define PCM3730_SIZE 4 // consecutive io port addresses
+
+#define PCM3730_DOA 0 // offsets for each port
+#define PCM3730_DOB 2
+#define PCM3730_DOC 3
+#define PCM3730_DIA 0
+#define PCM3730_DIB 2
+#define PCM3730_DIC 3
+
+static int pcm3730_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcm3730_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcm3730 = {
+ driver_name:"pcm3730",
+ module:THIS_MODULE,
+ attach:pcm3730_attach,
+ detach:pcm3730_detach,
+};
+
+COMEDI_INITCLEANUP(driver_pcm3730);
+
+static int pcm3730_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ outb(s->state, dev->iobase + (unsigned long)(s->private));
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int pcm3730_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+ data[1] = inb(dev->iobase + (unsigned long)(s->private));
+ return 2;
+}
+
+static int pcm3730_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, PCM3730_SIZE, "pcm3730")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+ dev->board_name = "pcm3730";
+ dev->iobase = dev->iobase;
+ dev->irq = 0;
+
+ if (alloc_subdevices(dev, 6) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcm3730_do_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)PCM3730_DOA;
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcm3730_do_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)PCM3730_DOB;
+
+ s = dev->subdevices + 2;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcm3730_do_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)PCM3730_DOC;
+
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcm3730_di_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)PCM3730_DIA;
+
+ s = dev->subdevices + 4;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcm3730_di_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)PCM3730_DIB;
+
+ s = dev->subdevices + 5;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcm3730_di_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)PCM3730_DIC;
+
+ printk("\n");
+
+ return 0;
+}
+
+static int pcm3730_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pcm3730: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, PCM3730_SIZE);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c
new file mode 100644
index 00000000000..fc2a73d97c2
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcmad.c
@@ -0,0 +1,173 @@
+/*
+ comedi/drivers/pcmad.c
+ Hardware driver for Winsystems PCM-A/D12 and PCM-A/D16
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000,2001 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: pcmad
+Description: Winsystems PCM-A/D12, PCM-A/D16
+Author: ds
+Devices: [Winsystems] PCM-A/D12 (pcmad12), PCM-A/D16 (pcmad16)
+Status: untested
+
+This driver was written on a bet that I couldn't write a driver
+in less than 2 hours. I won the bet, but never got paid. =(
+
+Configuration options:
+ [0] - I/O port base
+ [1] - unused
+ [2] - Analog input reference
+ 0 = single ended
+ 1 = differential
+ [3] - Analog input encoding (must match jumpers)
+ 0 = straight binary
+ 1 = two's complement
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define PCMAD_SIZE 4
+
+#define PCMAD_STATUS 0
+#define PCMAD_LSB 1
+#define PCMAD_MSB 2
+#define PCMAD_CONVERT 1
+
+struct pcmad_board_struct {
+ const char *name;
+ int n_ai_bits;
+};
+static const struct pcmad_board_struct pcmad_boards[] = {
+ {
+ name: "pcmad12",
+ n_ai_bits:12,
+ },
+ {
+ name: "pcmad16",
+ n_ai_bits:16,
+ },
+};
+
+#define this_board ((const struct pcmad_board_struct *)(dev->board_ptr))
+#define n_pcmad_boards (sizeof(pcmad_boards)/sizeof(pcmad_boards[0]))
+
+struct pcmad_priv_struct {
+ int differential;
+ int twos_comp;
+};
+#define devpriv ((struct pcmad_priv_struct *)dev->private)
+
+static int pcmad_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcmad_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcmad = {
+ driver_name:"pcmad",
+ module:THIS_MODULE,
+ attach:pcmad_attach,
+ detach:pcmad_detach,
+ board_name:&pcmad_boards[0].name,
+ num_names:n_pcmad_boards,
+ offset:sizeof(pcmad_boards[0]),
+};
+
+COMEDI_INITCLEANUP(driver_pcmad);
+
+#define TIMEOUT 100
+
+static int pcmad_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan;
+ int n;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ outb(chan, dev->iobase + PCMAD_CONVERT);
+
+ for (i = 0; i < TIMEOUT; i++) {
+ if ((inb(dev->iobase + PCMAD_STATUS) & 0x3) == 0x3)
+ break;
+ }
+ data[n] = inb(dev->iobase + PCMAD_LSB);
+ data[n] |= (inb(dev->iobase + PCMAD_MSB) << 8);
+
+ if (devpriv->twos_comp) {
+ data[n] ^= (1 << (this_board->n_ai_bits - 1));
+ }
+ }
+
+ return n;
+}
+
+/*
+ * options:
+ * 0 i/o base
+ * 1 unused
+ * 2 0=single ended 1=differential
+ * 3 0=straight binary 1=two's comp
+ */
+static int pcmad_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: pcmad: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, PCMAD_SIZE, "pcmad")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ if ((ret = alloc_subdevices(dev, 1)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct pcmad_priv_struct))) < 0)
+ return ret;
+
+ dev->board_name = this_board->name;
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | AREF_GROUND;
+ s->n_chan = 16; /* XXX */
+ s->len_chanlist = 1;
+ s->insn_read = pcmad_ai_insn_read;
+ s->maxdata = (1 << this_board->n_ai_bits) - 1;
+ s->range_table = &range_unknown;
+
+ return 0;
+}
+
+static int pcmad_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pcmad: remove\n", dev->minor);
+
+ if (dev->irq) {
+ free_irq(dev->irq, dev);
+ }
+ if (dev->iobase)
+ release_region(dev->iobase, PCMAD_SIZE);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c
new file mode 100644
index 00000000000..2a1ff465602
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcmda12.c
@@ -0,0 +1,306 @@
+/*
+ comedi/drivers/pcmda12.c
+ Driver for Winsystems PC-104 based PCM-D/A-12 8-channel AO board.
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2006 Calin A. Culianu <calin@ajvar.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: pcmda12
+Description: A driver for the Winsystems PCM-D/A-12
+Devices: [Winsystems] PCM-D/A-12 (pcmda12)
+Author: Calin Culianu <calin@ajvar.org>
+Updated: Fri, 13 Jan 2006 12:01:01 -0500
+Status: works
+
+A driver for the relatively straightforward-to-program PCM-D/A-12.
+This board doesn't support commands, and the only way to set its
+analog output range is to jumper the board. As such,
+comedi_data_write() ignores the range value specified.
+
+The board uses 16 consecutive I/O addresses starting at the I/O port
+base address. Each address corresponds to the LSB then MSB of a
+particular channel from 0-7.
+
+Note that the board is not ISA-PNP capable and thus
+needs the I/O port comedi_config parameter.
+
+Note that passing a nonzero value as the second config option will
+enable "simultaneous xfer" mode for this board, in which AO writes
+will not take effect until a subsequent read of any AO channel. This
+is so that one can speed up programming by preloading all AO registers
+with values before simultaneously setting them to take effect with one
+read command.
+
+Configuration Options:
+ [0] - I/O port base address
+ [1] - Do Simultaneous Xfer (see description)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/pci.h> /* for PCI devices */
+
+#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
+#define SDEV_NO ((int)(s - dev->subdevices))
+#define CHANS 8
+#define IOSIZE 16
+#define LSB(x) ((unsigned char)((x) & 0xff))
+#define MSB(x) ((unsigned char)((((unsigned short)(x))>>8) & 0xff))
+#define LSB_PORT(chan) (dev->iobase + (chan)*2)
+#define MSB_PORT(chan) (LSB_PORT(chan)+1)
+#define BITS 12
+
+/*
+ * Bords
+ */
+struct pcmda12_board {
+ const char *name;
+};
+
+/* note these have no effect and are merely here for reference..
+ these are configured by jumpering the board! */
+static const struct comedi_lrange pcmda12_ranges = {
+ 3,
+ {
+ UNI_RANGE(5), UNI_RANGE(10), BIP_RANGE(5)
+ }
+};
+
+static const struct pcmda12_board pcmda12_boards[] = {
+ {
+ name: "pcmda12",
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pcmda12_board *)dev->board_ptr)
+
+struct pcmda12_private {
+
+ unsigned int ao_readback[CHANS];
+ int simultaneous_xfer_mode;
+};
+
+
+#define devpriv ((struct pcmda12_private *)(dev->private))
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pcmda12_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcmda12_detach(struct comedi_device * dev);
+
+static void zero_chans(struct comedi_device * dev);
+
+static struct comedi_driver driver = {
+ driver_name:"pcmda12",
+ module:THIS_MODULE,
+ attach:pcmda12_attach,
+ detach:pcmda12_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+ /* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in pcmda12_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+ board_name:&pcmda12_boards[0].name,
+ offset:sizeof(struct pcmda12_board),
+ num_names:sizeof(pcmda12_boards) / sizeof(struct pcmda12_board),
+};
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pcmda12_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: %s: io: %lx %s ", dev->minor, driver.driver_name,
+ iobase, it->options[1] ? "simultaneous xfer mode enabled" : "");
+
+ if (!request_region(iobase, IOSIZE, driver.driver_name)) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct pcmda12_private)) < 0) {
+ printk("cannot allocate private data structure\n");
+ return -ENOMEM;
+ }
+
+ devpriv->simultaneous_xfer_mode = it->options[1];
+
+ /*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ *
+ * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the
+ * 96-channel version of the board.
+ */
+ if (alloc_subdevices(dev, 1) < 0) {
+ printk("cannot allocate subdevice data structures\n");
+ return -ENOMEM;
+ }
+
+ s = dev->subdevices;
+ s->private = NULL;
+ s->maxdata = (0x1 << BITS) - 1;
+ s->range_table = &pcmda12_ranges;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = CHANS;
+ s->insn_write = &ao_winsn;
+ s->insn_read = &ao_rinsn;
+
+ zero_chans(dev); /* clear out all the registers, basically */
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pcmda12_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: %s: remove\n", dev->minor, driver.driver_name);
+ if (dev->iobase)
+ release_region(dev->iobase, IOSIZE);
+ return 0;
+}
+
+static void zero_chans(struct comedi_device * dev)
+{ /* sets up an
+ ASIC chip to defaults */
+ int i;
+ for (i = 0; i < CHANS; ++i) {
+/* /\* do this as one instruction?? *\/ */
+/* outw(0, LSB_PORT(chan)); */
+ outb(0, LSB_PORT(i));
+ outb(0, MSB_PORT(i));
+ }
+ inb(LSB_PORT(0)); /* update chans. */
+}
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; ++i) {
+
+/* /\* do this as one instruction?? *\/ */
+/* outw(data[i], LSB_PORT(chan)); */
+
+ /* Need to do this as two instructions due to 8-bit bus?? */
+ /* first, load the low byte */
+ outb(LSB(data[i]), LSB_PORT(chan));
+ /* next, write the high byte */
+ outb(MSB(data[i]), MSB_PORT(chan));
+
+ /* save shadow register */
+ devpriv->ao_readback[chan] = data[i];
+
+ if (!devpriv->simultaneous_xfer_mode)
+ inb(LSB_PORT(chan));
+ }
+
+ /* return the number of samples written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+
+ Usually this means copying a value stored in devpriv->ao_readback.
+ However, since this driver supports simultaneous xfer then sometimes
+ this function actually accomplishes work.
+
+ Simultaneaous xfer mode is accomplished by loading ALL the values
+ you want for AO in all the channels, then READing off one of the AO
+ registers to initiate the instantaneous simultaneous update of all
+ DAC outputs, which makes all AO channels update simultaneously.
+ This is useful for some control applications, I would imagine.
+*/
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ if (devpriv->simultaneous_xfer_mode)
+ inb(LSB_PORT(chan));
+ /* read back shadow register */
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver);
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
new file mode 100644
index 00000000000..01e40f1b562
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -0,0 +1,1333 @@
+/*
+ comedi/drivers/pcmmio.c
+ Driver for Winsystems PC-104 based multifunction IO board.
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2007 Calin A. Culianu <calin@ajvar.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: pcmmio
+Description: A driver for the PCM-MIO multifunction board
+Devices: [Winsystems] PCM-MIO (pcmmio)
+Author: Calin Culianu <calin@ajvar.org>
+Updated: Wed, May 16 2007 16:21:10 -0500
+Status: works
+
+A driver for the relatively new PCM-MIO multifunction board from
+Winsystems. This board is a PC-104 based I/O board. It contains
+four subdevices:
+ subdevice 0 - 16 channels of 16-bit AI
+ subdevice 1 - 8 channels of 16-bit AO
+ subdevice 2 - first 24 channels of the 48 channel of DIO (with edge-triggered interrupt support)
+ subdevice 3 - last 24 channels of the 48 channel DIO (no interrupt support for this bank of channels)
+
+ Some notes:
+
+ Synchronous reads and writes are the only things implemented for AI and AO,
+ even though the hardware itself can do streaming acquisition, etc. Anyone
+ want to add asynchronous I/O for AI/AO as a feature? Be my guest...
+
+ Asynchronous I/O for the DIO subdevices *is* implemented, however! They are
+ basically edge-triggered interrupts for any configuration of the first
+ 24 DIO-lines.
+
+ Also note that this interrupt support is untested.
+
+ A few words about edge-detection IRQ support (commands on DIO):
+
+ * To use edge-detection IRQ support for the DIO subdevice, pass the IRQ
+ of the board to the comedi_config command. The board IRQ is not jumpered
+ but rather configured through software, so any IRQ from 1-15 is OK.
+
+ * Due to the genericity of the comedi API, you need to create a special
+ comedi_command in order to use edge-triggered interrupts for DIO.
+
+ * Use comedi_commands with TRIG_NOW. Your callback will be called each
+ time an edge is detected on the specified DIO line(s), and the data
+ values will be two sample_t's, which should be concatenated to form
+ one 32-bit unsigned int. This value is the mask of channels that had
+ edges detected from your channel list. Note that the bits positions
+ in the mask correspond to positions in your chanlist when you
+ specified the command and *not* channel id's!
+
+ * To set the polarity of the edge-detection interrupts pass a nonzero value
+ for either CR_RANGE or CR_AREF for edge-up polarity, or a zero
+ value for both CR_RANGE and CR_AREF if you want edge-down polarity.
+
+Configuration Options:
+ [0] - I/O port base address
+ [1] - IRQ (optional -- for edge-detect interrupt support only, leave out if you don't need this feature)
+*/
+
+#include "../comedidev.h"
+#include <linux/pci.h> /* for PCI devices */
+
+#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
+
+/* This stuff is all from pcmuio.c -- it refers to the DIO subdevices only */
+#define CHANS_PER_PORT 8
+#define PORTS_PER_ASIC 6
+#define INTR_PORTS_PER_ASIC 3
+#define MAX_CHANS_PER_SUBDEV 24 /* number of channels per comedi subdevice */
+#define PORTS_PER_SUBDEV (MAX_CHANS_PER_SUBDEV/CHANS_PER_PORT)
+#define CHANS_PER_ASIC (CHANS_PER_PORT*PORTS_PER_ASIC)
+#define INTR_CHANS_PER_ASIC 24
+#define INTR_PORTS_PER_SUBDEV (INTR_CHANS_PER_ASIC/CHANS_PER_PORT)
+#define MAX_DIO_CHANS (PORTS_PER_ASIC*1*CHANS_PER_PORT)
+#define MAX_ASICS (MAX_DIO_CHANS/CHANS_PER_ASIC)
+#define SDEV_NO ((int)(s - dev->subdevices))
+#define CALC_N_DIO_SUBDEVS(nchans) ((nchans)/MAX_CHANS_PER_SUBDEV + (!!((nchans)%MAX_CHANS_PER_SUBDEV)) /*+ (nchans > INTR_CHANS_PER_ASIC ? 2 : 1)*/)
+/* IO Memory sizes */
+#define ASIC_IOSIZE (0x0B)
+#define PCMMIO48_IOSIZE ASIC_IOSIZE
+
+/* Some offsets - these are all in the 16byte IO memory offset from
+ the base address. Note that there is a paging scheme to swap out
+ offsets 0x8-0xA using the PAGELOCK register. See the table below.
+
+ Register(s) Pages R/W? Description
+ --------------------------------------------------------------
+ REG_PORTx All R/W Read/Write/Configure IO
+ REG_INT_PENDING All ReadOnly Quickly see which INT_IDx has int.
+ REG_PAGELOCK All WriteOnly Select a page
+ REG_POLx Pg. 1 only WriteOnly Select edge-detection polarity
+ REG_ENABx Pg. 2 only WriteOnly Enable/Disable edge-detect. int.
+ REG_INT_IDx Pg. 3 only R/W See which ports/bits have ints.
+ */
+#define REG_PORT0 0x0
+#define REG_PORT1 0x1
+#define REG_PORT2 0x2
+#define REG_PORT3 0x3
+#define REG_PORT4 0x4
+#define REG_PORT5 0x5
+#define REG_INT_PENDING 0x6
+#define REG_PAGELOCK 0x7 /* page selector register, upper 2 bits select a page
+ and bits 0-5 are used to 'lock down' a particular
+ port above to make it readonly. */
+#define REG_POL0 0x8
+#define REG_POL1 0x9
+#define REG_POL2 0xA
+#define REG_ENAB0 0x8
+#define REG_ENAB1 0x9
+#define REG_ENAB2 0xA
+#define REG_INT_ID0 0x8
+#define REG_INT_ID1 0x9
+#define REG_INT_ID2 0xA
+
+#define NUM_PAGED_REGS 3
+#define NUM_PAGES 4
+#define FIRST_PAGED_REG 0x8
+#define REG_PAGE_BITOFFSET 6
+#define REG_LOCK_BITOFFSET 0
+#define REG_PAGE_MASK (~((0x1<<REG_PAGE_BITOFFSET)-1))
+#define REG_LOCK_MASK ~(REG_PAGE_MASK)
+#define PAGE_POL 1
+#define PAGE_ENAB 2
+#define PAGE_INT_ID 3
+
+typedef int (*comedi_insn_fn_t) (struct comedi_device *, struct comedi_subdevice *,
+ struct comedi_insn *, unsigned int *);
+
+static int ai_rinsn(struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+static int ao_rinsn(struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+static int ao_winsn(struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct pcmmio_board {
+ const char *name;
+ const int dio_num_asics;
+ const int dio_num_ports;
+ const int total_iosize;
+ const int ai_bits;
+ const int ao_bits;
+ const int n_ai_chans;
+ const int n_ao_chans;
+ const struct comedi_lrange *ai_range_table, *ao_range_table;
+ comedi_insn_fn_t ai_rinsn, ao_rinsn, ao_winsn;
+};
+
+static const struct comedi_lrange ranges_ai =
+ { 4, {RANGE(-5., 5.), RANGE(-10., 10.), RANGE(0., 5.), RANGE(0.,
+ 10.)}
+};
+
+static const struct comedi_lrange ranges_ao =
+ { 6, {RANGE(0., 5.), RANGE(0., 10.), RANGE(-5., 5.), RANGE(-10., 10.),
+ RANGE(-2.5, 2.5), RANGE(-2.5, 7.5)}
+};
+
+static const struct pcmmio_board pcmmio_boards[] = {
+ {
+ name: "pcmmio",
+ dio_num_asics:1,
+ dio_num_ports:6,
+ total_iosize:32,
+ ai_bits: 16,
+ ao_bits: 16,
+ n_ai_chans:16,
+ n_ao_chans:8,
+ ai_range_table:&ranges_ai,
+ ao_range_table:&ranges_ao,
+ ai_rinsn:ai_rinsn,
+ ao_rinsn:ao_rinsn,
+ ao_winsn:ao_winsn},
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pcmmio_board *)dev->board_ptr)
+
+/* this structure is for data unique to this subdevice. */
+struct pcmmio_subdev_private {
+
+ union {
+ /* for DIO: mapping of halfwords (bytes) in port/chanarray to iobase */
+ unsigned long iobases[PORTS_PER_SUBDEV];
+
+ /* for AI/AO */
+ unsigned long iobase;
+ };
+ union {
+ struct {
+
+ /* The below is only used for intr subdevices */
+ struct {
+ int asic; /* if non-negative, this subdev has an interrupt asic */
+ int first_chan; /* if nonnegative, the first channel id for
+ interrupts. */
+ int num_asic_chans; /* the number of asic channels in this subdev
+ that have interrutps */
+ int asic_chan; /* if nonnegative, the first channel id with
+ respect to the asic that has interrupts */
+ int enabled_mask; /* subdev-relative channel mask for channels
+ we are interested in */
+ int active;
+ int stop_count;
+ int continuous;
+ spinlock_t spinlock;
+ } intr;
+ } dio;
+ struct {
+ unsigned int shadow_samples[8]; /* the last unsigned int data written */
+ } ao;
+ };
+};
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct pcmmio_private {
+ /* stuff for DIO */
+ struct {
+ unsigned char pagelock; /* current page and lock */
+ unsigned char pol[NUM_PAGED_REGS]; /* shadow of POLx registers */
+ unsigned char enab[NUM_PAGED_REGS]; /* shadow of ENABx registers */
+ int num;
+ unsigned long iobase;
+ unsigned int irq;
+ spinlock_t spinlock;
+ } asics[MAX_ASICS];
+ struct pcmmio_subdev_private *sprivs;
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct pcmmio_private *)dev->private)
+#define subpriv ((struct pcmmio_subdev_private *)s->private)
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pcmmio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcmmio_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver = {
+ driver_name:"pcmmio",
+ module:THIS_MODULE,
+ attach:pcmmio_attach,
+ detach:pcmmio_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+ /* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in pcmmio_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+ board_name:&pcmmio_boards[0].name,
+ offset:sizeof(struct pcmmio_board),
+ num_names:sizeof(pcmmio_boards) / sizeof(struct pcmmio_board),
+};
+
+static int pcmmio_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pcmmio_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static irqreturn_t interrupt_pcmmio(int irq, void *d PT_REGS_ARG);
+static void pcmmio_stop_intr(struct comedi_device *, struct comedi_subdevice *);
+static int pcmmio_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pcmmio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pcmmio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+
+/* some helper functions to deal with specifics of this device's registers */
+static void init_asics(struct comedi_device * dev); /* sets up/clears ASIC chips to defaults */
+static void switch_page(struct comedi_device * dev, int asic, int page);
+#ifdef notused
+static void lock_port(struct comedi_device * dev, int asic, int port);
+static void unlock_port(struct comedi_device * dev, int asic, int port);
+#endif
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pcmmio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic,
+ thisasic_chanct = 0;
+ unsigned long iobase;
+ unsigned int irq[MAX_ASICS];
+
+ iobase = it->options[0];
+ irq[0] = it->options[1];
+
+ printk("comedi%d: %s: io: %lx ", dev->minor, driver.driver_name,
+ iobase);
+
+ dev->iobase = iobase;
+
+ if (!iobase || !request_region(iobase,
+ thisboard->total_iosize, driver.driver_name)) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct pcmmio_private)) < 0) {
+ printk("cannot allocate private data structure\n");
+ return -ENOMEM;
+ }
+
+ for (asic = 0; asic < MAX_ASICS; ++asic) {
+ devpriv->asics[asic].num = asic;
+ devpriv->asics[asic].iobase =
+ dev->iobase + 16 + asic * ASIC_IOSIZE;
+ devpriv->asics[asic].irq = 0; /* this gets actually set at the end of
+ this function when we
+ comedi_request_irqs */
+ spin_lock_init(&devpriv->asics[asic].spinlock);
+ }
+
+ chans_left = CHANS_PER_ASIC * thisboard->dio_num_asics;
+ n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left);
+ n_subdevs = n_dio_subdevs + 2;
+ devpriv->sprivs =
+ kcalloc(n_subdevs, sizeof(struct pcmmio_subdev_private), GFP_KERNEL);
+ if (!devpriv->sprivs) {
+ printk("cannot allocate subdevice private data structures\n");
+ return -ENOMEM;
+ }
+ /*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ *
+ * Allocate 1 AI + 1 AO + 2 DIO subdevs (24 lines per DIO)
+ */
+ if (alloc_subdevices(dev, n_subdevs) < 0) {
+ printk("cannot allocate subdevice data structures\n");
+ return -ENOMEM;
+ }
+
+ /* First, AI */
+ sdev_no = 0;
+ s = dev->subdevices + sdev_no;
+ s->private = devpriv->sprivs + sdev_no;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = thisboard->ai_range_table;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
+ s->type = COMEDI_SUBD_AI;
+ s->n_chan = thisboard->n_ai_chans;
+ s->len_chanlist = s->n_chan;
+ s->insn_read = thisboard->ai_rinsn;
+ subpriv->iobase = dev->iobase + 0;
+ /* initialize the resource enable register by clearing it */
+ outb(0, subpriv->iobase + 3);
+ outb(0, subpriv->iobase + 4 + 3);
+
+ /* Next, AO */
+ ++sdev_no;
+ s = dev->subdevices + sdev_no;
+ s->private = devpriv->sprivs + sdev_no;
+ s->maxdata = (1 << thisboard->ao_bits) - 1;
+ s->range_table = thisboard->ao_range_table;
+ s->subdev_flags = SDF_READABLE;
+ s->type = COMEDI_SUBD_AO;
+ s->n_chan = thisboard->n_ao_chans;
+ s->len_chanlist = s->n_chan;
+ s->insn_read = thisboard->ao_rinsn;
+ s->insn_write = thisboard->ao_winsn;
+ subpriv->iobase = dev->iobase + 8;
+ /* initialize the resource enable register by clearing it */
+ outb(0, subpriv->iobase + 3);
+ outb(0, subpriv->iobase + 4 + 3);
+
+ ++sdev_no;
+ port = 0;
+ asic = 0;
+ for (; sdev_no < (int)dev->n_subdevices; ++sdev_no) {
+ int byte_no;
+
+ s = dev->subdevices + sdev_no;
+ s->private = devpriv->sprivs + sdev_no;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->type = COMEDI_SUBD_DIO;
+ s->insn_bits = pcmmio_dio_insn_bits;
+ s->insn_config = pcmmio_dio_insn_config;
+ s->n_chan = MIN(chans_left, MAX_CHANS_PER_SUBDEV);
+ subpriv->dio.intr.asic = -1;
+ subpriv->dio.intr.first_chan = -1;
+ subpriv->dio.intr.asic_chan = -1;
+ subpriv->dio.intr.num_asic_chans = -1;
+ subpriv->dio.intr.active = 0;
+ s->len_chanlist = 1;
+
+ /* save the ioport address for each 'port' of 8 channels in the
+ subdevice */
+ for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) {
+ if (port >= PORTS_PER_ASIC) {
+ port = 0;
+ ++asic;
+ thisasic_chanct = 0;
+ }
+ subpriv->iobases[byte_no] =
+ devpriv->asics[asic].iobase + port;
+
+ if (thisasic_chanct <
+ CHANS_PER_PORT * INTR_PORTS_PER_ASIC
+ && subpriv->dio.intr.asic < 0) {
+ /* this is an interrupt subdevice, so setup the struct */
+ subpriv->dio.intr.asic = asic;
+ subpriv->dio.intr.active = 0;
+ subpriv->dio.intr.stop_count = 0;
+ subpriv->dio.intr.first_chan = byte_no * 8;
+ subpriv->dio.intr.asic_chan = thisasic_chanct;
+ subpriv->dio.intr.num_asic_chans =
+ s->n_chan -
+ subpriv->dio.intr.first_chan;
+ s->cancel = pcmmio_cancel;
+ s->do_cmd = pcmmio_cmd;
+ s->do_cmdtest = pcmmio_cmdtest;
+ s->len_chanlist =
+ subpriv->dio.intr.num_asic_chans;
+ }
+ thisasic_chanct += CHANS_PER_PORT;
+ }
+ spin_lock_init(&subpriv->dio.intr.spinlock);
+
+ chans_left -= s->n_chan;
+
+ if (!chans_left) {
+ asic = 0; /* reset the asic to our first asic, to do intr subdevs */
+ port = 0;
+ }
+
+ }
+
+ init_asics(dev); /* clear out all the registers, basically */
+
+ for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) {
+ if (irq[asic]
+ && comedi_request_irq(irq[asic], interrupt_pcmmio,
+ IRQF_SHARED, thisboard->name, dev)) {
+ int i;
+ /* unroll the allocated irqs.. */
+ for (i = asic - 1; i >= 0; --i) {
+ comedi_free_irq(irq[i], dev);
+ devpriv->asics[i].irq = irq[i] = 0;
+ }
+ irq[asic] = 0;
+ }
+ devpriv->asics[asic].irq = irq[asic];
+ }
+
+ dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple
+ irqs.. */
+
+ if (irq[0]) {
+ printk("irq: %u ", irq[0]);
+ if (irq[1] && thisboard->dio_num_asics == 2)
+ printk("second ASIC irq: %u ", irq[1]);
+ } else {
+ printk("(IRQ mode disabled) ");
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pcmmio_detach(struct comedi_device * dev)
+{
+ int i;
+
+ printk("comedi%d: %s: remove\n", dev->minor, driver.driver_name);
+ if (dev->iobase)
+ release_region(dev->iobase, thisboard->total_iosize);
+
+ for (i = 0; i < MAX_ASICS; ++i) {
+ if (devpriv && devpriv->asics[i].irq)
+ comedi_free_irq(devpriv->asics[i].irq, dev);
+ }
+
+ if (devpriv && devpriv->sprivs)
+ kfree(devpriv->sprivs);
+
+ return 0;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int pcmmio_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int byte_no;
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* NOTE:
+ reading a 0 means this channel was high
+ writine a 0 sets the channel high
+ reading a 1 means this channel was low
+ writing a 1 means set this channel low
+
+ Therefore everything is always inverted. */
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("write mask: %08x data: %08x\n", data[0], data[1]);
+#endif
+
+ s->state = 0;
+
+ for (byte_no = 0; byte_no < s->n_chan / CHANS_PER_PORT; ++byte_no) {
+ /* address of 8-bit port */
+ unsigned long ioaddr = subpriv->iobases[byte_no],
+ /* bit offset of port in 32-bit doubleword */
+ offset = byte_no * 8;
+ /* this 8-bit port's data */
+ unsigned char byte = 0,
+ /* The write mask for this port (if any) */
+ write_mask_byte = (data[0] >> offset) & 0xff,
+ /* The data byte for this port */
+ data_byte = (data[1] >> offset) & 0xff;
+
+ byte = inb(ioaddr); /* read all 8-bits for this port */
+
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("byte %d wmb %02x db %02x offset %02d io %04x, data_in %02x ", byte_no, (unsigned)write_mask_byte, (unsigned)data_byte, offset, ioaddr, (unsigned)byte);
+#endif
+
+ if (write_mask_byte) {
+ /* this byte has some write_bits -- so set the output lines */
+ byte &= ~write_mask_byte; /* clear bits for write mask */
+ byte |= ~data_byte & write_mask_byte; /* set to inverted data_byte */
+ /* Write out the new digital output state */
+ outb(byte, ioaddr);
+ }
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("data_out_byte %02x\n", (unsigned)byte);
+#endif
+ /* save the digital input lines for this byte.. */
+ s->state |= ((unsigned int)byte) << offset;
+ }
+
+ /* now return the DIO lines to data[1] - note they came inverted! */
+ data[1] = ~s->state;
+
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("s->state %08x data_out %08x\n", s->state, data[1]);
+#endif
+
+ return 2;
+}
+
+/* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+static int pcmmio_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec), byte_no = chan / 8, bit_no =
+ chan % 8;
+ unsigned long ioaddr;
+ unsigned char byte;
+
+ /* Compute ioaddr for this channel */
+ ioaddr = subpriv->iobases[byte_no];
+
+ /* NOTE:
+ writing a 0 an IO channel's bit sets the channel to INPUT
+ and pulls the line high as well
+
+ writing a 1 to an IO channel's bit pulls the line low
+
+ All channels are implicitly always in OUTPUT mode -- but when
+ they are high they can be considered to be in INPUT mode..
+
+ Thus, we only force channels low if the config request was INPUT,
+ otherwise we do nothing to the hardware. */
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ /* save to io_bits -- don't actually do anything since
+ all input channels are also output channels... */
+ s->io_bits |= 1 << chan;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ /* write a 0 to the actual register representing the channel
+ to set it to 'input'. 0 means "float high". */
+ byte = inb(ioaddr);
+ byte &= ~(1 << bit_no);
+ /**< set input channel to '0' */
+
+ /* write out byte -- this is the only time we actually affect the
+ hardware as all channels are implicitly output -- but input
+ channels are set to float-high */
+ outb(byte, ioaddr);
+
+ /* save to io_bits */
+ s->io_bits &= ~(1 << chan);
+ break;
+
+ case INSN_CONFIG_DIO_QUERY:
+ /* retreive from shadow register */
+ data[1] =
+ (s->
+ io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ return insn->n;
+}
+
+static void init_asics(struct comedi_device * dev)
+{ /* sets up an
+ ASIC chip to defaults */
+ int asic;
+
+ for (asic = 0; asic < thisboard->dio_num_asics; ++asic) {
+ int port, page;
+ unsigned long baseaddr = devpriv->asics[asic].iobase;
+
+ switch_page(dev, asic, 0); /* switch back to page 0 */
+
+ /* first, clear all the DIO port bits */
+ for (port = 0; port < PORTS_PER_ASIC; ++port)
+ outb(0, baseaddr + REG_PORT0 + port);
+
+ /* Next, clear all the paged registers for each page */
+ for (page = 1; page < NUM_PAGES; ++page) {
+ int reg;
+ /* now clear all the paged registers */
+ switch_page(dev, asic, page);
+ for (reg = FIRST_PAGED_REG;
+ reg < FIRST_PAGED_REG + NUM_PAGED_REGS; ++reg)
+ outb(0, baseaddr + reg);
+ }
+
+ /* DEBUG set rising edge interrupts on port0 of both asics */
+ /*switch_page(dev, asic, PAGE_POL);
+ outb(0xff, baseaddr + REG_POL0);
+ switch_page(dev, asic, PAGE_ENAB);
+ outb(0xff, baseaddr + REG_ENAB0); */
+ /* END DEBUG */
+
+ switch_page(dev, asic, 0); /* switch back to default page 0 */
+
+ }
+}
+
+static void switch_page(struct comedi_device * dev, int asic, int page)
+{
+ if (asic < 0 || asic >= thisboard->dio_num_asics)
+ return; /* paranoia */
+ if (page < 0 || page >= NUM_PAGES)
+ return; /* more paranoia */
+
+ devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK;
+ devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET;
+
+ /* now write out the shadow register */
+ outb(devpriv->asics[asic].pagelock,
+ devpriv->asics[asic].iobase + REG_PAGELOCK);
+}
+
+#ifdef notused
+static void lock_port(struct comedi_device * dev, int asic, int port)
+{
+ if (asic < 0 || asic >= thisboard->dio_num_asics)
+ return; /* paranoia */
+ if (port < 0 || port >= PORTS_PER_ASIC)
+ return; /* more paranoia */
+
+ devpriv->asics[asic].pagelock |= 0x1 << port;
+ /* now write out the shadow register */
+ outb(devpriv->asics[asic].pagelock,
+ devpriv->asics[asic].iobase + REG_PAGELOCK);
+ return;
+}
+
+static void unlock_port(struct comedi_device * dev, int asic, int port)
+{
+ if (asic < 0 || asic >= thisboard->dio_num_asics)
+ return; /* paranoia */
+ if (port < 0 || port >= PORTS_PER_ASIC)
+ return; /* more paranoia */
+ devpriv->asics[asic].pagelock &= ~(0x1 << port) | REG_LOCK_MASK;
+ /* now write out the shadow register */
+ outb(devpriv->asics[asic].pagelock,
+ devpriv->asics[asic].iobase + REG_PAGELOCK);
+}
+#endif /* notused */
+
+static irqreturn_t interrupt_pcmmio(int irq, void *d PT_REGS_ARG)
+{
+ int asic, got1 = 0;
+ struct comedi_device *dev = (struct comedi_device *) d;
+
+ for (asic = 0; asic < MAX_ASICS; ++asic) {
+ if (irq == devpriv->asics[asic].irq) {
+ unsigned long flags;
+ unsigned triggered = 0;
+ unsigned long iobase = devpriv->asics[asic].iobase;
+ /* it is an interrupt for ASIC #asic */
+ unsigned char int_pend;
+
+ comedi_spin_lock_irqsave(&devpriv->asics[asic].spinlock,
+ flags);
+
+ int_pend = inb(iobase + REG_INT_PENDING) & 0x07;
+
+ if (int_pend) {
+ int port;
+ for (port = 0; port < INTR_PORTS_PER_ASIC;
+ ++port) {
+ if (int_pend & (0x1 << port)) {
+ unsigned char
+ io_lines_with_edges = 0;
+ switch_page(dev, asic,
+ PAGE_INT_ID);
+ io_lines_with_edges =
+ inb(iobase +
+ REG_INT_ID0 + port);
+
+ if (io_lines_with_edges)
+ /* clear pending interrupt */
+ outb(0, iobase +
+ REG_INT_ID0 +
+ port);
+
+ triggered |=
+ io_lines_with_edges <<
+ port * 8;
+ }
+ }
+
+ ++got1;
+ }
+
+ comedi_spin_unlock_irqrestore(&devpriv->asics[asic].
+ spinlock, flags);
+
+ if (triggered) {
+ struct comedi_subdevice *s;
+ /* TODO here: dispatch io lines to subdevs with commands.. */
+ printk("PCMMIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n", irq, asic, triggered);
+ for (s = dev->subdevices + 2;
+ s < dev->subdevices + dev->n_subdevices;
+ ++s) {
+ if (subpriv->dio.intr.asic == asic) { /* this is an interrupt subdev, and it matches this asic! */
+ unsigned long flags;
+ unsigned oldevents;
+
+ comedi_spin_lock_irqsave
+ (&subpriv->dio.intr.
+ spinlock, flags);
+
+ oldevents = s->async->events;
+
+ if (subpriv->dio.intr.active) {
+ unsigned mytrig =
+ ((triggered >>
+ subpriv->
+ dio.
+ intr.
+ asic_chan)
+ & ((0x1 << subpriv->dio.intr.num_asic_chans) - 1)) << subpriv->dio.intr.first_chan;
+ if (mytrig & subpriv->
+ dio.intr.
+ enabled_mask) {
+ unsigned int val =
+ 0;
+ unsigned int n,
+ ch, len;
+
+ len = s->async->
+ cmd.
+ chanlist_len;
+ for (n = 0;
+ n < len;
+ n++) {
+ ch = CR_CHAN(s->async->cmd.chanlist[n]);
+ if (mytrig & (1U << ch)) {
+ val |= (1U << n);
+ }
+ }
+ /* Write the scan to the buffer. */
+ if (comedi_buf_put(s->async, ((short *) & val)[0])
+ &&
+ comedi_buf_put
+ (s->async, ((short *) & val)[1])) {
+ s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+ } else {
+ /* Overflow! Stop acquisition!! */
+ /* TODO: STOP_ACQUISITION_CALL_HERE!! */
+ pcmmio_stop_intr
+ (dev,
+ s);
+ }
+
+ /* Check for end of acquisition. */
+ if (!subpriv->
+ dio.
+ intr.
+ continuous)
+ {
+ /* stop_src == TRIG_COUNT */
+ if (subpriv->dio.intr.stop_count > 0) {
+ subpriv->
+ dio.
+ intr.
+ stop_count--;
+ if (subpriv->dio.intr.stop_count == 0) {
+ s->async->events |= COMEDI_CB_EOA;
+ /* TODO: STOP_ACQUISITION_CALL_HERE!! */
+ pcmmio_stop_intr
+ (dev,
+ s);
+ }
+ }
+ }
+ }
+ }
+
+ comedi_spin_unlock_irqrestore
+ (&subpriv->dio.intr.
+ spinlock, flags);
+
+ if (oldevents !=
+ s->async->events) {
+ comedi_event(dev, s);
+ }
+
+ }
+
+ }
+ }
+
+ }
+ }
+ if (!got1)
+ return IRQ_NONE; /* interrupt from other source */
+ return IRQ_HANDLED;
+}
+
+static void pcmmio_stop_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int nports, firstport, asic, port;
+
+ if ((asic = subpriv->dio.intr.asic) < 0)
+ return; /* not an interrupt subdev */
+
+ subpriv->dio.intr.enabled_mask = 0;
+ subpriv->dio.intr.active = 0;
+ s->async->inttrig = 0;
+ nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT;
+ firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT;
+ switch_page(dev, asic, PAGE_ENAB);
+ for (port = firstport; port < firstport + nports; ++port) {
+ /* disable all intrs for this subdev.. */
+ outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port);
+ }
+}
+
+static int pcmmio_start_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (!subpriv->dio.intr.continuous && subpriv->dio.intr.stop_count == 0) {
+ /* An empty acquisition! */
+ s->async->events |= COMEDI_CB_EOA;
+ subpriv->dio.intr.active = 0;
+ return 1;
+ } else {
+ unsigned bits = 0, pol_bits = 0, n;
+ int nports, firstport, asic, port;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if ((asic = subpriv->dio.intr.asic) < 0)
+ return 1; /* not an interrupt
+ subdev */
+ subpriv->dio.intr.enabled_mask = 0;
+ subpriv->dio.intr.active = 1;
+ nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT;
+ firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT;
+ if (cmd->chanlist) {
+ for (n = 0; n < cmd->chanlist_len; n++) {
+ bits |= (1U << CR_CHAN(cmd->chanlist[n]));
+ pol_bits |= (CR_AREF(cmd->chanlist[n])
+ || CR_RANGE(cmd->chanlist[n]) ? 1U : 0U)
+ << CR_CHAN(cmd->chanlist[n]);
+ }
+ }
+ bits &= ((0x1 << subpriv->dio.intr.num_asic_chans) -
+ 1) << subpriv->dio.intr.first_chan;
+ subpriv->dio.intr.enabled_mask = bits;
+
+ { /* the below code configures the board to use a specific IRQ from 0-15. */
+ unsigned char b;
+ /* set resource enable register to enable IRQ operation */
+ outb(1 << 4, dev->iobase + 3);
+ /* set bits 0-3 of b to the irq number from 0-15 */
+ b = dev->irq & ((1 << 4) - 1);
+ outb(b, dev->iobase + 2);
+ /* done, we told the board what irq to use */
+ }
+
+ switch_page(dev, asic, PAGE_ENAB);
+ for (port = firstport; port < firstport + nports; ++port) {
+ unsigned enab =
+ bits >> (subpriv->dio.intr.first_chan + (port -
+ firstport) * 8) & 0xff, pol =
+ pol_bits >> (subpriv->dio.intr.first_chan +
+ (port - firstport) * 8) & 0xff;
+ /* set enab intrs for this subdev.. */
+ outb(enab,
+ devpriv->asics[asic].iobase + REG_ENAB0 + port);
+ switch_page(dev, asic, PAGE_POL);
+ outb(pol,
+ devpriv->asics[asic].iobase + REG_ENAB0 + port);
+ }
+ }
+ return 0;
+}
+
+static int pcmmio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags);
+ if (subpriv->dio.intr.active)
+ pcmmio_stop_intr(dev, s);
+ comedi_spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
+
+ return 0;
+}
+
+/*
+ * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int
+pcmmio_inttrig_start_intr(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ unsigned long flags;
+ int event = 0;
+
+ if (trignum != 0)
+ return -EINVAL;
+
+ comedi_spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags);
+ s->async->inttrig = 0;
+ if (subpriv->dio.intr.active) {
+ event = pcmmio_start_intr(dev, s);
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
+
+ if (event) {
+ comedi_event(dev, s);
+ }
+
+ return 1;
+}
+
+/*
+ * 'do_cmd' function for an 'INTERRUPT' subdevice.
+ */
+static int pcmmio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned long flags;
+ int event = 0;
+
+ comedi_spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags);
+ subpriv->dio.intr.active = 1;
+
+ /* Set up end of acquisition. */
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ subpriv->dio.intr.continuous = 0;
+ subpriv->dio.intr.stop_count = cmd->stop_arg;
+ break;
+ default:
+ /* TRIG_NONE */
+ subpriv->dio.intr.continuous = 1;
+ subpriv->dio.intr.stop_count = 0;
+ break;
+ }
+
+ /* Set up start of acquisition. */
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ s->async->inttrig = pcmmio_inttrig_start_intr;
+ break;
+ default:
+ /* TRIG_NOW */
+ event = pcmmio_start_intr(dev, s);
+ break;
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
+
+ if (event) {
+ comedi_event(dev, s);
+ }
+
+ return 0;
+}
+
+/*
+ * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
+ */
+static int
+pcmmio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= (TRIG_NOW | TRIG_INT);
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* these tests are true if more than one _src bit is set */
+ if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+ err++;
+ if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+ err++;
+ if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_begin_src == TRIG_EXT */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ /* cmd->convert_src == TRIG_NOW */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_end_src == TRIG_COUNT */
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ /* any count allowed */
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ /* if (err) return 4; */
+
+ return 0;
+}
+
+static int adc_wait_ready(unsigned long iobase)
+{
+ unsigned long retry = 100000;
+ while (retry--)
+ if (inb(iobase + 3) & 0x80)
+ return 0;
+ return 1;
+}
+
+/* All this is for AI and AO */
+static int ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ unsigned long iobase = subpriv->iobase;
+
+ /*
+ 1. write the CMD byte (to BASE+2)
+ 2. read junk lo byte (BASE+0)
+ 3. read junk hi byte (BASE+1)
+ 4. (mux settled so) write CMD byte again (BASE+2)
+ 5. read valid lo byte(BASE+0)
+ 6. read valid hi byte(BASE+1)
+
+ Additionally note that the BASE += 4 if the channel >= 8
+ */
+
+ /* convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ unsigned chan = CR_CHAN(insn->chanspec), range =
+ CR_RANGE(insn->chanspec), aref =
+ CR_AREF(insn->chanspec);
+ unsigned char command_byte = 0;
+ unsigned iooffset = 0;
+ short sample, adc_adjust = 0;
+
+ if (chan > 7)
+ chan -= 8, iooffset = 4; /* use the second dword for channels > 7 */
+
+ if (aref != AREF_DIFF) {
+ aref = AREF_GROUND;
+ command_byte |= 1 << 7; /* set bit 7 to indicate single-ended */
+ }
+ if (range < 2)
+ adc_adjust = 0x8000; /* bipolar ranges (-5,5 .. -10,10 need to be adjusted -- that is.. they need to wrap around by adding 0x8000 */
+
+ if (chan % 2) {
+ command_byte |= 1 << 6; /* odd-numbered channels have bit 6 set */
+ }
+
+ /* select the channel, bits 4-5 == chan/2 */
+ command_byte |= ((chan / 2) & 0x3) << 4;
+
+ /* set the range, bits 2-3 */
+ command_byte |= (range & 0x3) << 2;
+
+ /* need to do this twice to make sure mux settled */
+ outb(command_byte, iobase + iooffset + 2); /* chan/range/aref select */
+
+ adc_wait_ready(iobase + iooffset); /* wait for the adc to say it finised the conversion */
+
+ outb(command_byte, iobase + iooffset + 2); /* select the chan/range/aref AGAIN */
+
+ adc_wait_ready(iobase + iooffset);
+
+ sample = inb(iobase + iooffset + 0); /* read data lo byte */
+ sample |= inb(iobase + iooffset + 1) << 8; /* read data hi byte */
+ sample += adc_adjust; /* adjustment .. munge data */
+ data[n] = sample;
+ }
+ /* return the number of samples read/written */
+ return n;
+}
+
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ for (n = 0; n < insn->n; n++) {
+ unsigned chan = CR_CHAN(insn->chanspec);
+ if (chan < s->n_chan)
+ data[n] = subpriv->ao.shadow_samples[chan];
+ }
+ return n;
+}
+
+static int wait_dac_ready(unsigned long iobase)
+{
+ unsigned long retry = 100000L;
+
+ /* This may seem like an absurd way to handle waiting and violates the
+ "no busy waiting" policy. The fact is that the hardware is
+ normally so fast that we usually only need one time through the loop
+ anyway. The longer timeout is for rare occasions and for detecting
+ non-existant hardware. */
+
+ while (retry--) {
+ if (inb(iobase + 3) & 0x80)
+ return 0;
+
+ }
+ return 1;
+}
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ unsigned iobase = subpriv->iobase, iooffset = 0;
+
+ for (n = 0; n < insn->n; n++) {
+ unsigned chan = CR_CHAN(insn->chanspec), range =
+ CR_RANGE(insn->chanspec);
+ if (chan < s->n_chan) {
+ unsigned char command_byte = 0, range_byte =
+ range & ((1 << 4) - 1);
+ if (chan >= 4)
+ chan -= 4, iooffset += 4;
+ /* set the range.. */
+ outb(range_byte, iobase + iooffset + 0);
+ outb(0, iobase + iooffset + 1);
+
+ /* tell it to begin */
+ command_byte = (chan << 1) | 0x60;
+ outb(command_byte, iobase + iooffset + 2);
+
+ wait_dac_ready(iobase + iooffset);
+
+ outb(data[n] & 0xff, iobase + iooffset + 0); /* low order byte */
+ outb((data[n] >> 8) & 0xff, iobase + iooffset + 1); /* high order byte */
+ command_byte = 0x70 | (chan << 1); /* set bit 4 of command byte to indicate data is loaded and trigger conversion */
+ /* trigger converion */
+ outb(command_byte, iobase + iooffset + 2);
+
+ wait_dac_ready(iobase + iooffset);
+
+ subpriv->ao.shadow_samples[chan] = data[n]; /* save to shadow register for ao_rinsn */
+ }
+ }
+ return n;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver);
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
new file mode 100644
index 00000000000..4e7d8b6327f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -0,0 +1,1101 @@
+/*
+ comedi/drivers/pcmuio.c
+ Driver for Winsystems PC-104 based 48-channel and 96-channel DIO boards.
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2006 Calin A. Culianu <calin@ajvar.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: pcmuio
+Description: A driver for the PCM-UIO48A and PCM-UIO96A boards from Winsystems.
+Devices: [Winsystems] PCM-UIO48A (pcmuio48), PCM-UIO96A (pcmuio96)
+Author: Calin Culianu <calin@ajvar.org>
+Updated: Fri, 13 Jan 2006 12:01:01 -0500
+Status: works
+
+A driver for the relatively straightforward-to-program PCM-UIO48A and
+PCM-UIO96A boards from Winsystems. These boards use either one or two
+(in the 96-DIO version) WS16C48 ASIC HighDensity I/O Chips (HDIO).
+This chip is interesting in that each I/O line is individually
+programmable for INPUT or OUTPUT (thus comedi_dio_config can be done
+on a per-channel basis). Also, each chip supports edge-triggered
+interrupts for the first 24 I/O lines. Of course, since the
+96-channel version of the board has two ASICs, it can detect polarity
+changes on up to 48 I/O lines. Since this is essentially an (non-PnP)
+ISA board, I/O Address and IRQ selection are done through jumpers on
+the board. You need to pass that information to this driver as the
+first and second comedi_config option, respectively. Note that the
+48-channel version uses 16 bytes of IO memory and the 96-channel
+version uses 32-bytes (in case you are worried about conflicts). The
+48-channel board is split into two 24-channel comedi subdevices.
+The 96-channel board is split into 4 24-channel DIO subdevices.
+
+Note that IRQ support has been added, but it is untested.
+
+To use edge-detection IRQ support, pass the IRQs of both ASICS
+(for the 96 channel version) or just 1 ASIC (for 48-channel version).
+Then, use use comedi_commands with TRIG_NOW.
+Your callback will be called each time an edge is triggered, and the data
+values will be two sample_t's, which should be concatenated to form one
+32-bit unsigned int. This value is the mask of channels that had
+edges detected from your channel list. Note that the bits positions
+in the mask correspond to positions in your chanlist when you specified
+the command and *not* channel id's!
+
+To set the polarity of the edge-detection interrupts pass a nonzero value for
+either CR_RANGE or CR_AREF for edge-up polarity, or a zero value for both
+CR_RANGE and CR_AREF if you want edge-down polarity.
+
+In the 48-channel version:
+
+On subdev 0, the first 24 channels channels are edge-detect channels.
+
+In the 96-channel board you have the collowing channels that can do edge detection:
+
+subdev 0, channels 0-24 (first 24 channels of 1st ASIC)
+subdev 2, channels 0-24 (first 24 channels of 2nd ASIC)
+
+Configuration Options:
+ [0] - I/O port base address
+ [1] - IRQ (for first ASIC, or first 24 channels)
+ [2] - IRQ for second ASIC (pcmuio96 only - IRQ for chans 48-72 .. can be the same as first irq!)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/pci.h> /* for PCI devices */
+
+#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
+#define CHANS_PER_PORT 8
+#define PORTS_PER_ASIC 6
+#define INTR_PORTS_PER_ASIC 3
+#define MAX_CHANS_PER_SUBDEV 24 /* number of channels per comedi subdevice */
+#define PORTS_PER_SUBDEV (MAX_CHANS_PER_SUBDEV/CHANS_PER_PORT)
+#define CHANS_PER_ASIC (CHANS_PER_PORT*PORTS_PER_ASIC)
+#define INTR_CHANS_PER_ASIC 24
+#define INTR_PORTS_PER_SUBDEV (INTR_CHANS_PER_ASIC/CHANS_PER_PORT)
+#define MAX_DIO_CHANS (PORTS_PER_ASIC*2*CHANS_PER_PORT)
+#define MAX_ASICS (MAX_DIO_CHANS/CHANS_PER_ASIC)
+#define SDEV_NO ((int)(s - dev->subdevices))
+#define CALC_N_SUBDEVS(nchans) ((nchans)/MAX_CHANS_PER_SUBDEV + (!!((nchans)%MAX_CHANS_PER_SUBDEV)) /*+ (nchans > INTR_CHANS_PER_ASIC ? 2 : 1)*/)
+/* IO Memory sizes */
+#define ASIC_IOSIZE (0x10)
+#define PCMUIO48_IOSIZE ASIC_IOSIZE
+#define PCMUIO96_IOSIZE (ASIC_IOSIZE*2)
+
+/* Some offsets - these are all in the 16byte IO memory offset from
+ the base address. Note that there is a paging scheme to swap out
+ offsets 0x8-0xA using the PAGELOCK register. See the table below.
+
+ Register(s) Pages R/W? Description
+ --------------------------------------------------------------
+ REG_PORTx All R/W Read/Write/Configure IO
+ REG_INT_PENDING All ReadOnly Quickly see which INT_IDx has int.
+ REG_PAGELOCK All WriteOnly Select a page
+ REG_POLx Pg. 1 only WriteOnly Select edge-detection polarity
+ REG_ENABx Pg. 2 only WriteOnly Enable/Disable edge-detect. int.
+ REG_INT_IDx Pg. 3 only R/W See which ports/bits have ints.
+ */
+#define REG_PORT0 0x0
+#define REG_PORT1 0x1
+#define REG_PORT2 0x2
+#define REG_PORT3 0x3
+#define REG_PORT4 0x4
+#define REG_PORT5 0x5
+#define REG_INT_PENDING 0x6
+#define REG_PAGELOCK 0x7 /* page selector register, upper 2 bits select a page
+ and bits 0-5 are used to 'lock down' a particular
+ port above to make it readonly. */
+#define REG_POL0 0x8
+#define REG_POL1 0x9
+#define REG_POL2 0xA
+#define REG_ENAB0 0x8
+#define REG_ENAB1 0x9
+#define REG_ENAB2 0xA
+#define REG_INT_ID0 0x8
+#define REG_INT_ID1 0x9
+#define REG_INT_ID2 0xA
+
+#define NUM_PAGED_REGS 3
+#define NUM_PAGES 4
+#define FIRST_PAGED_REG 0x8
+#define REG_PAGE_BITOFFSET 6
+#define REG_LOCK_BITOFFSET 0
+#define REG_PAGE_MASK (~((0x1<<REG_PAGE_BITOFFSET)-1))
+#define REG_LOCK_MASK ~(REG_PAGE_MASK)
+#define PAGE_POL 1
+#define PAGE_ENAB 2
+#define PAGE_INT_ID 3
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct pcmuio_board {
+ const char *name;
+ const int num_asics;
+ const int num_channels_per_port;
+ const int num_ports;
+};
+
+static const struct pcmuio_board pcmuio_boards[] = {
+ {
+ name: "pcmuio48",
+ num_asics:1,
+ num_ports:6,
+ },
+ {
+ name: "pcmuio96",
+ num_asics:2,
+ num_ports:12,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pcmuio_board *)dev->board_ptr)
+
+/* this structure is for data unique to this subdevice. */
+struct pcmuio_subdev_private {
+ /* mapping of halfwords (bytes) in port/chanarray to iobase */
+ unsigned long iobases[PORTS_PER_SUBDEV];
+
+ /* The below is only used for intr subdevices */
+ struct {
+ int asic; /* if non-negative, this subdev has an interrupt asic */
+ int first_chan; /* if nonnegative, the first channel id for
+ interrupts. */
+ int num_asic_chans; /* the number of asic channels in this subdev
+ that have interrutps */
+ int asic_chan; /* if nonnegative, the first channel id with
+ respect to the asic that has interrupts */
+ int enabled_mask; /* subdev-relative channel mask for channels
+ we are interested in */
+ int active;
+ int stop_count;
+ int continuous;
+ spinlock_t spinlock;
+ } intr;
+};
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct pcmuio_private {
+ struct {
+ unsigned char pagelock; /* current page and lock */
+ unsigned char pol[NUM_PAGED_REGS]; /* shadow of POLx registers */
+ unsigned char enab[NUM_PAGED_REGS]; /* shadow of ENABx registers */
+ int num;
+ unsigned long iobase;
+ unsigned int irq;
+ spinlock_t spinlock;
+ } asics[MAX_ASICS];
+ struct pcmuio_subdev_private *sprivs;
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct pcmuio_private *)dev->private)
+#define subpriv ((struct pcmuio_subdev_private *)s->private)
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pcmuio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcmuio_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver = {
+ driver_name:"pcmuio",
+ module:THIS_MODULE,
+ attach:pcmuio_attach,
+ detach:pcmuio_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+ /* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in pcmuio_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+ board_name:&pcmuio_boards[0].name,
+ offset:sizeof(struct pcmuio_board),
+ num_names:sizeof(pcmuio_boards) / sizeof(struct pcmuio_board),
+};
+
+static int pcmuio_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pcmuio_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static irqreturn_t interrupt_pcmuio(int irq, void *d PT_REGS_ARG);
+static void pcmuio_stop_intr(struct comedi_device *, struct comedi_subdevice *);
+static int pcmuio_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pcmuio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pcmuio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+
+/* some helper functions to deal with specifics of this device's registers */
+static void init_asics(struct comedi_device * dev); /* sets up/clears ASIC chips to defaults */
+static void switch_page(struct comedi_device * dev, int asic, int page);
+#ifdef notused
+static void lock_port(struct comedi_device * dev, int asic, int port);
+static void unlock_port(struct comedi_device * dev, int asic, int port);
+#endif
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pcmuio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0;
+ unsigned long iobase;
+ unsigned int irq[MAX_ASICS];
+
+ iobase = it->options[0];
+ irq[0] = it->options[1];
+ irq[1] = it->options[2];
+
+ printk("comedi%d: %s: io: %lx ", dev->minor, driver.driver_name,
+ iobase);
+
+ dev->iobase = iobase;
+
+ if (!iobase || !request_region(iobase,
+ thisboard->num_asics * ASIC_IOSIZE,
+ driver.driver_name)) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct pcmuio_private)) < 0) {
+ printk("cannot allocate private data structure\n");
+ return -ENOMEM;
+ }
+
+ for (asic = 0; asic < MAX_ASICS; ++asic) {
+ devpriv->asics[asic].num = asic;
+ devpriv->asics[asic].iobase = dev->iobase + asic * ASIC_IOSIZE;
+ devpriv->asics[asic].irq = 0; /* this gets actually set at the end of
+ this function when we
+ comedi_request_irqs */
+ spin_lock_init(&devpriv->asics[asic].spinlock);
+ }
+
+ chans_left = CHANS_PER_ASIC * thisboard->num_asics;
+ n_subdevs = CALC_N_SUBDEVS(chans_left);
+ devpriv->sprivs =
+ kcalloc(n_subdevs, sizeof(struct pcmuio_subdev_private), GFP_KERNEL);
+ if (!devpriv->sprivs) {
+ printk("cannot allocate subdevice private data structures\n");
+ return -ENOMEM;
+ }
+ /*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ *
+ * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the
+ * 96-channel version of the board.
+ */
+ if (alloc_subdevices(dev, n_subdevs) < 0) {
+ printk("cannot allocate subdevice data structures\n");
+ return -ENOMEM;
+ }
+
+ port = 0;
+ asic = 0;
+ for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) {
+ int byte_no;
+
+ s = dev->subdevices + sdev_no;
+ s->private = devpriv->sprivs + sdev_no;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->type = COMEDI_SUBD_DIO;
+ s->insn_bits = pcmuio_dio_insn_bits;
+ s->insn_config = pcmuio_dio_insn_config;
+ s->n_chan = MIN(chans_left, MAX_CHANS_PER_SUBDEV);
+ subpriv->intr.asic = -1;
+ subpriv->intr.first_chan = -1;
+ subpriv->intr.asic_chan = -1;
+ subpriv->intr.num_asic_chans = -1;
+ subpriv->intr.active = 0;
+ s->len_chanlist = 1;
+
+ /* save the ioport address for each 'port' of 8 channels in the
+ subdevice */
+ for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) {
+ if (port >= PORTS_PER_ASIC) {
+ port = 0;
+ ++asic;
+ thisasic_chanct = 0;
+ }
+ subpriv->iobases[byte_no] =
+ devpriv->asics[asic].iobase + port;
+
+ if (thisasic_chanct <
+ CHANS_PER_PORT * INTR_PORTS_PER_ASIC
+ && subpriv->intr.asic < 0) {
+ /* this is an interrupt subdevice, so setup the struct */
+ subpriv->intr.asic = asic;
+ subpriv->intr.active = 0;
+ subpriv->intr.stop_count = 0;
+ subpriv->intr.first_chan = byte_no * 8;
+ subpriv->intr.asic_chan = thisasic_chanct;
+ subpriv->intr.num_asic_chans =
+ s->n_chan - subpriv->intr.first_chan;
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->cancel = pcmuio_cancel;
+ s->do_cmd = pcmuio_cmd;
+ s->do_cmdtest = pcmuio_cmdtest;
+ s->len_chanlist = subpriv->intr.num_asic_chans;
+ }
+ thisasic_chanct += CHANS_PER_PORT;
+ }
+ spin_lock_init(&subpriv->intr.spinlock);
+
+ chans_left -= s->n_chan;
+
+ if (!chans_left) {
+ asic = 0; /* reset the asic to our first asic, to do intr subdevs */
+ port = 0;
+ }
+
+ }
+
+ init_asics(dev); /* clear out all the registers, basically */
+
+ for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) {
+ if (irq[asic]
+ && comedi_request_irq(irq[asic], interrupt_pcmuio,
+ IRQF_SHARED, thisboard->name, dev)) {
+ int i;
+ /* unroll the allocated irqs.. */
+ for (i = asic - 1; i >= 0; --i) {
+ comedi_free_irq(irq[i], dev);
+ devpriv->asics[i].irq = irq[i] = 0;
+ }
+ irq[asic] = 0;
+ }
+ devpriv->asics[asic].irq = irq[asic];
+ }
+
+ dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple
+ irqs.. */
+
+ if (irq[0]) {
+ printk("irq: %u ", irq[0]);
+ if (irq[1] && thisboard->num_asics == 2)
+ printk("second ASIC irq: %u ", irq[1]);
+ } else {
+ printk("(IRQ mode disabled) ");
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pcmuio_detach(struct comedi_device * dev)
+{
+ int i;
+
+ printk("comedi%d: %s: remove\n", dev->minor, driver.driver_name);
+ if (dev->iobase)
+ release_region(dev->iobase, ASIC_IOSIZE * thisboard->num_asics);
+
+ for (i = 0; i < MAX_ASICS; ++i) {
+ if (devpriv->asics[i].irq)
+ comedi_free_irq(devpriv->asics[i].irq, dev);
+ }
+
+ if (devpriv && devpriv->sprivs)
+ kfree(devpriv->sprivs);
+
+ return 0;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int pcmuio_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int byte_no;
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* NOTE:
+ reading a 0 means this channel was high
+ writine a 0 sets the channel high
+ reading a 1 means this channel was low
+ writing a 1 means set this channel low
+
+ Therefore everything is always inverted. */
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("write mask: %08x data: %08x\n", data[0], data[1]);
+#endif
+
+ s->state = 0;
+
+ for (byte_no = 0; byte_no < s->n_chan / CHANS_PER_PORT; ++byte_no) {
+ /* address of 8-bit port */
+ unsigned long ioaddr = subpriv->iobases[byte_no],
+ /* bit offset of port in 32-bit doubleword */
+ offset = byte_no * 8;
+ /* this 8-bit port's data */
+ unsigned char byte = 0,
+ /* The write mask for this port (if any) */
+ write_mask_byte = (data[0] >> offset) & 0xff,
+ /* The data byte for this port */
+ data_byte = (data[1] >> offset) & 0xff;
+
+ byte = inb(ioaddr); /* read all 8-bits for this port */
+
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("byte %d wmb %02x db %02x offset %02d io %04x, data_in %02x ", byte_no, (unsigned)write_mask_byte, (unsigned)data_byte, offset, ioaddr, (unsigned)byte);
+#endif
+
+ if (write_mask_byte) {
+ /* this byte has some write_bits -- so set the output lines */
+ byte &= ~write_mask_byte; /* clear bits for write mask */
+ byte |= ~data_byte & write_mask_byte; /* set to inverted data_byte */
+ /* Write out the new digital output state */
+ outb(byte, ioaddr);
+ }
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("data_out_byte %02x\n", (unsigned)byte);
+#endif
+ /* save the digital input lines for this byte.. */
+ s->state |= ((unsigned int)byte) << offset;
+ }
+
+ /* now return the DIO lines to data[1] - note they came inverted! */
+ data[1] = ~s->state;
+
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("s->state %08x data_out %08x\n", s->state, data[1]);
+#endif
+
+ return 2;
+}
+
+/* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+static int pcmuio_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec), byte_no = chan / 8, bit_no =
+ chan % 8;
+ unsigned long ioaddr;
+ unsigned char byte;
+
+ /* Compute ioaddr for this channel */
+ ioaddr = subpriv->iobases[byte_no];
+
+ /* NOTE:
+ writing a 0 an IO channel's bit sets the channel to INPUT
+ and pulls the line high as well
+
+ writing a 1 to an IO channel's bit pulls the line low
+
+ All channels are implicitly always in OUTPUT mode -- but when
+ they are high they can be considered to be in INPUT mode..
+
+ Thus, we only force channels low if the config request was INPUT,
+ otherwise we do nothing to the hardware. */
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ /* save to io_bits -- don't actually do anything since
+ all input channels are also output channels... */
+ s->io_bits |= 1 << chan;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ /* write a 0 to the actual register representing the channel
+ to set it to 'input'. 0 means "float high". */
+ byte = inb(ioaddr);
+ byte &= ~(1 << bit_no);
+ /**< set input channel to '0' */
+
+ /* write out byte -- this is the only time we actually affect the
+ hardware as all channels are implicitly output -- but input
+ channels are set to float-high */
+ outb(byte, ioaddr);
+
+ /* save to io_bits */
+ s->io_bits &= ~(1 << chan);
+ break;
+
+ case INSN_CONFIG_DIO_QUERY:
+ /* retreive from shadow register */
+ data[1] =
+ (s->
+ io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ return insn->n;
+}
+
+static void init_asics(struct comedi_device * dev)
+{ /* sets up an
+ ASIC chip to defaults */
+ int asic;
+
+ for (asic = 0; asic < thisboard->num_asics; ++asic) {
+ int port, page;
+ unsigned long baseaddr = dev->iobase + asic * ASIC_IOSIZE;
+
+ switch_page(dev, asic, 0); /* switch back to page 0 */
+
+ /* first, clear all the DIO port bits */
+ for (port = 0; port < PORTS_PER_ASIC; ++port)
+ outb(0, baseaddr + REG_PORT0 + port);
+
+ /* Next, clear all the paged registers for each page */
+ for (page = 1; page < NUM_PAGES; ++page) {
+ int reg;
+ /* now clear all the paged registers */
+ switch_page(dev, asic, page);
+ for (reg = FIRST_PAGED_REG;
+ reg < FIRST_PAGED_REG + NUM_PAGED_REGS; ++reg)
+ outb(0, baseaddr + reg);
+ }
+
+ /* DEBUG set rising edge interrupts on port0 of both asics */
+ /*switch_page(dev, asic, PAGE_POL);
+ outb(0xff, baseaddr + REG_POL0);
+ switch_page(dev, asic, PAGE_ENAB);
+ outb(0xff, baseaddr + REG_ENAB0); */
+ /* END DEBUG */
+
+ switch_page(dev, asic, 0); /* switch back to default page 0 */
+
+ }
+}
+
+static void switch_page(struct comedi_device * dev, int asic, int page)
+{
+ if (asic < 0 || asic >= thisboard->num_asics)
+ return; /* paranoia */
+ if (page < 0 || page >= NUM_PAGES)
+ return; /* more paranoia */
+
+ devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK;
+ devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET;
+
+ /* now write out the shadow register */
+ outb(devpriv->asics[asic].pagelock,
+ dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
+}
+
+#ifdef notused
+static void lock_port(struct comedi_device * dev, int asic, int port)
+{
+ if (asic < 0 || asic >= thisboard->num_asics)
+ return; /* paranoia */
+ if (port < 0 || port >= PORTS_PER_ASIC)
+ return; /* more paranoia */
+
+ devpriv->asics[asic].pagelock |= 0x1 << port;
+ /* now write out the shadow register */
+ outb(devpriv->asics[asic].pagelock,
+ dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
+}
+
+static void unlock_port(struct comedi_device * dev, int asic, int port)
+{
+ if (asic < 0 || asic >= thisboard->num_asics)
+ return; /* paranoia */
+ if (port < 0 || port >= PORTS_PER_ASIC)
+ return; /* more paranoia */
+ devpriv->asics[asic].pagelock &= ~(0x1 << port) | REG_LOCK_MASK;
+ /* now write out the shadow register */
+ outb(devpriv->asics[asic].pagelock,
+ dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
+}
+#endif /* notused */
+
+static irqreturn_t interrupt_pcmuio(int irq, void *d PT_REGS_ARG)
+{
+ int asic, got1 = 0;
+ struct comedi_device *dev = (struct comedi_device *) d;
+
+ for (asic = 0; asic < MAX_ASICS; ++asic) {
+ if (irq == devpriv->asics[asic].irq) {
+ unsigned long flags;
+ unsigned triggered = 0;
+ unsigned long iobase = devpriv->asics[asic].iobase;
+ /* it is an interrupt for ASIC #asic */
+ unsigned char int_pend;
+
+ comedi_spin_lock_irqsave(&devpriv->asics[asic].spinlock,
+ flags);
+
+ int_pend = inb(iobase + REG_INT_PENDING) & 0x07;
+
+ if (int_pend) {
+ int port;
+ for (port = 0; port < INTR_PORTS_PER_ASIC;
+ ++port) {
+ if (int_pend & (0x1 << port)) {
+ unsigned char
+ io_lines_with_edges = 0;
+ switch_page(dev, asic,
+ PAGE_INT_ID);
+ io_lines_with_edges =
+ inb(iobase +
+ REG_INT_ID0 + port);
+
+ if (io_lines_with_edges)
+ /* clear pending interrupt */
+ outb(0, iobase +
+ REG_INT_ID0 +
+ port);
+
+ triggered |=
+ io_lines_with_edges <<
+ port * 8;
+ }
+ }
+
+ ++got1;
+ }
+
+ comedi_spin_unlock_irqrestore(&devpriv->asics[asic].
+ spinlock, flags);
+
+ if (triggered) {
+ struct comedi_subdevice *s;
+ /* TODO here: dispatch io lines to subdevs with commands.. */
+ printk("PCMUIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n", irq, asic, triggered);
+ for (s = dev->subdevices;
+ s < dev->subdevices + dev->n_subdevices;
+ ++s) {
+ if (subpriv->intr.asic == asic) { /* this is an interrupt subdev, and it matches this asic! */
+ unsigned long flags;
+ unsigned oldevents;
+
+ comedi_spin_lock_irqsave
+ (&subpriv->intr.
+ spinlock, flags);
+
+ oldevents = s->async->events;
+
+ if (subpriv->intr.active) {
+ unsigned mytrig =
+ ((triggered >>
+ subpriv->
+ intr.
+ asic_chan)
+ & ((0x1 << subpriv->intr.num_asic_chans) - 1)) << subpriv->intr.first_chan;
+ if (mytrig & subpriv->
+ intr.
+ enabled_mask) {
+ unsigned int val =
+ 0;
+ unsigned int n,
+ ch, len;
+
+ len = s->async->
+ cmd.
+ chanlist_len;
+ for (n = 0;
+ n < len;
+ n++) {
+ ch = CR_CHAN(s->async->cmd.chanlist[n]);
+ if (mytrig & (1U << ch)) {
+ val |= (1U << n);
+ }
+ }
+ /* Write the scan to the buffer. */
+ if (comedi_buf_put(s->async, ((short *) & val)[0])
+ &&
+ comedi_buf_put
+ (s->async, ((short *) & val)[1])) {
+ s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+ } else {
+ /* Overflow! Stop acquisition!! */
+ /* TODO: STOP_ACQUISITION_CALL_HERE!! */
+ pcmuio_stop_intr
+ (dev,
+ s);
+ }
+
+ /* Check for end of acquisition. */
+ if (!subpriv->
+ intr.
+ continuous)
+ {
+ /* stop_src == TRIG_COUNT */
+ if (subpriv->intr.stop_count > 0) {
+ subpriv->
+ intr.
+ stop_count--;
+ if (subpriv->intr.stop_count == 0) {
+ s->async->events |= COMEDI_CB_EOA;
+ /* TODO: STOP_ACQUISITION_CALL_HERE!! */
+ pcmuio_stop_intr
+ (dev,
+ s);
+ }
+ }
+ }
+ }
+ }
+
+ comedi_spin_unlock_irqrestore
+ (&subpriv->intr.
+ spinlock, flags);
+
+ if (oldevents !=
+ s->async->events) {
+ comedi_event(dev, s);
+ }
+
+ }
+
+ }
+ }
+
+ }
+ }
+ if (!got1)
+ return IRQ_NONE; /* interrupt from other source */
+ return IRQ_HANDLED;
+}
+
+static void pcmuio_stop_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int nports, firstport, asic, port;
+
+ if ((asic = subpriv->intr.asic) < 0)
+ return; /* not an interrupt subdev */
+
+ subpriv->intr.enabled_mask = 0;
+ subpriv->intr.active = 0;
+ s->async->inttrig = 0;
+ nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT;
+ firstport = subpriv->intr.asic_chan / CHANS_PER_PORT;
+ switch_page(dev, asic, PAGE_ENAB);
+ for (port = firstport; port < firstport + nports; ++port) {
+ /* disable all intrs for this subdev.. */
+ outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port);
+ }
+}
+
+static int pcmuio_start_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (!subpriv->intr.continuous && subpriv->intr.stop_count == 0) {
+ /* An empty acquisition! */
+ s->async->events |= COMEDI_CB_EOA;
+ subpriv->intr.active = 0;
+ return 1;
+ } else {
+ unsigned bits = 0, pol_bits = 0, n;
+ int nports, firstport, asic, port;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if ((asic = subpriv->intr.asic) < 0)
+ return 1; /* not an interrupt
+ subdev */
+ subpriv->intr.enabled_mask = 0;
+ subpriv->intr.active = 1;
+ nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT;
+ firstport = subpriv->intr.asic_chan / CHANS_PER_PORT;
+ if (cmd->chanlist) {
+ for (n = 0; n < cmd->chanlist_len; n++) {
+ bits |= (1U << CR_CHAN(cmd->chanlist[n]));
+ pol_bits |= (CR_AREF(cmd->chanlist[n])
+ || CR_RANGE(cmd->chanlist[n]) ? 1U : 0U)
+ << CR_CHAN(cmd->chanlist[n]);
+ }
+ }
+ bits &= ((0x1 << subpriv->intr.num_asic_chans) -
+ 1) << subpriv->intr.first_chan;
+ subpriv->intr.enabled_mask = bits;
+
+ switch_page(dev, asic, PAGE_ENAB);
+ for (port = firstport; port < firstport + nports; ++port) {
+ unsigned enab =
+ bits >> (subpriv->intr.first_chan + (port -
+ firstport) * 8) & 0xff, pol =
+ pol_bits >> (subpriv->intr.first_chan + (port -
+ firstport) * 8) & 0xff;
+ /* set enab intrs for this subdev.. */
+ outb(enab,
+ devpriv->asics[asic].iobase + REG_ENAB0 + port);
+ switch_page(dev, asic, PAGE_POL);
+ outb(pol,
+ devpriv->asics[asic].iobase + REG_ENAB0 + port);
+ }
+ }
+ return 0;
+}
+
+static int pcmuio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&subpriv->intr.spinlock, flags);
+ if (subpriv->intr.active)
+ pcmuio_stop_intr(dev, s);
+ comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+
+ return 0;
+}
+
+/*
+ * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int
+pcmuio_inttrig_start_intr(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ unsigned long flags;
+ int event = 0;
+
+ if (trignum != 0)
+ return -EINVAL;
+
+ comedi_spin_lock_irqsave(&subpriv->intr.spinlock, flags);
+ s->async->inttrig = 0;
+ if (subpriv->intr.active) {
+ event = pcmuio_start_intr(dev, s);
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+
+ if (event) {
+ comedi_event(dev, s);
+ }
+
+ return 1;
+}
+
+/*
+ * 'do_cmd' function for an 'INTERRUPT' subdevice.
+ */
+static int pcmuio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned long flags;
+ int event = 0;
+
+ comedi_spin_lock_irqsave(&subpriv->intr.spinlock, flags);
+ subpriv->intr.active = 1;
+
+ /* Set up end of acquisition. */
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ subpriv->intr.continuous = 0;
+ subpriv->intr.stop_count = cmd->stop_arg;
+ break;
+ default:
+ /* TRIG_NONE */
+ subpriv->intr.continuous = 1;
+ subpriv->intr.stop_count = 0;
+ break;
+ }
+
+ /* Set up start of acquisition. */
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ s->async->inttrig = pcmuio_inttrig_start_intr;
+ break;
+ default:
+ /* TRIG_NOW */
+ event = pcmuio_start_intr(dev, s);
+ break;
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+
+ if (event) {
+ comedi_event(dev, s);
+ }
+
+ return 0;
+}
+
+/*
+ * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
+ */
+static int
+pcmuio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= (TRIG_NOW | TRIG_INT);
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* these tests are true if more than one _src bit is set */
+ if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+ err++;
+ if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+ err++;
+ if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_begin_src == TRIG_EXT */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ /* cmd->convert_src == TRIG_NOW */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_end_src == TRIG_COUNT */
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ /* any count allowed */
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ /* if (err) return 4; */
+
+ return 0;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver);
diff --git a/drivers/staging/comedi/drivers/plx9052.h b/drivers/staging/comedi/drivers/plx9052.h
new file mode 100644
index 00000000000..5894739ff42
--- /dev/null
+++ b/drivers/staging/comedi/drivers/plx9052.h
@@ -0,0 +1,86 @@
+/*
+ comedi/drivers/plx9052.h
+ Definitions for the PLX-9052 PCI interface chip
+
+ Copyright (C) 2002 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _PLX9052_H_
+#define _PLX9052_H_
+
+/*
+ * PLX PCI9052 INTCSR register.
+ */
+#define PLX9052_INTCSR 0x4C /* Offset in Local Configuration Registers */
+/* Local Interrupt 1 Enable */
+#define PLX9052_INTCSR_LI1ENAB_MASK 0x0001
+#define PLX9052_INTCSR_LI1ENAB_DISABLED 0x0000
+#define PLX9052_INTCSR_LI1ENAB_ENABLED 0x0001
+/* Local Interrupt 1 Polarity */
+#define PLX9052_INTCSR_LI1POL_MASK 0x0002
+#define PLX9052_INTCSR_LI1POL_LOW 0x0000
+#define PLX9052_INTCSR_LI1POL_HIGH 0x0002
+/* Local Interrupt 1 Status (read-only) */
+#define PLX9052_INTCSR_LI1STAT_MASK 0x0004
+#define PLX9052_INTCSR_LI1STAT_INACTIVE 0x0000
+#define PLX9052_INTCSR_LI1STAT_ACTIVE 0x0004
+/* Local Interrupt 2 Enable */
+#define PLX9052_INTCSR_LI2ENAB_MASK 0x0008
+#define PLX9052_INTCSR_LI2ENAB_DISABLED 0x0000
+#define PLX9052_INTCSR_LI2ENAB_ENABLED 0x0008
+/* Local Interrupt 2 Polarity */
+#define PLX9052_INTCSR_LI2POL_MASK 0x0010
+#define PLX9052_INTCSR_LI2POL_LOW 0x0000
+#define PLX9052_INTCSR_LI2POL_HIGH 0x0010
+/* Local Interrupt 2 Status (read-only) */
+#define PLX9052_INTCSR_LI2STAT_MASK 0x0020
+#define PLX9052_INTCSR_LI2STAT_INACTIVE 0x0000
+#define PLX9052_INTCSR_LI2STAT_ACTIVE 0x0020
+/* PCI Interrupt Enable */
+#define PLX9052_INTCSR_PCIENAB_MASK 0x0040
+#define PLX9052_INTCSR_PCIENAB_DISABLED 0x0000
+#define PLX9052_INTCSR_PCIENAB_ENABLED 0x0040
+/* Software Interrupt */
+#define PLX9052_INTCSR_SOFTINT_MASK 0x0080
+#define PLX9052_INTCSR_SOFTINT_UNASSERTED 0x0000
+#define PLX9052_INTCSR_SOFTINT_ASSERTED 0x0080
+/* Local Interrupt 1 Select Enable */
+#define PLX9052_INTCSR_LI1SEL_MASK 0x0100
+#define PLX9052_INTCSR_LI1SEL_LEVEL 0x0000
+#define PLX9052_INTCSR_LI1SEL_EDGE 0x0100
+/* Local Interrupt 2 Select Enable */
+#define PLX9052_INTCSR_LI2SEL_MASK 0x0200
+#define PLX9052_INTCSR_LI2SEL_LEVEL 0x0000
+#define PLX9052_INTCSR_LI2SEL_EDGE 0x0200
+/* Local Edge Triggerable Interrupt 1 Clear Bit */
+#define PLX9052_INTCSR_LI1CLRINT_MASK 0x0400
+#define PLX9052_INTCSR_LI1CLRINT_UNASSERTED 0x0000
+#define PLX9052_INTCSR_LI1CLRINT_ASSERTED 0x0400
+/* Local Edge Triggerable Interrupt 2 Clear Bit */
+#define PLX9052_INTCSR_LI2CLRINT_MASK 0x0800
+#define PLX9052_INTCSR_LI2CLRINT_UNASSERTED 0x0000
+#define PLX9052_INTCSR_LI2CLRINT_ASSERTED 0x0800
+/* ISA Interface Mode Enable (read-only over PCI bus) */
+#define PLX9052_INTCSR_ISAMODE_MASK 0x1000
+#define PLX9052_INTCSR_ISAMODE_DISABLED 0x0000
+#define PLX9052_INTCSR_ISAMODE_ENABLED 0x1000
+
+#endif /* _PLX9052_H_ */
diff --git a/drivers/staging/comedi/drivers/plx9080.h b/drivers/staging/comedi/drivers/plx9080.h
index a5a1a6808c5..9231ba80203 100644
--- a/drivers/staging/comedi/drivers/plx9080.h
+++ b/drivers/staging/comedi/drivers/plx9080.h
@@ -27,7 +27,7 @@
#ifndef __COMEDI_PLX9080_H
#define __COMEDI_PLX9080_H
-// descriptor block used for chained dma transfers
+/* descriptor block used for chained dma transfers */
struct plx_dma_desc {
volatile uint32_t pci_start_addr;
volatile uint32_t local_start_addr;
@@ -52,14 +52,14 @@ struct plx_dma_desc {
#define LRNG_ANY32 0x00000000 /* Locate anywhere in 32 bit */
#define LRNG_LT1MB 0x00000002 /* Locate in 1st meg */
#define LRNG_ANY64 0x00000004 /* Locate anywhere in 64 bit */
-#define LRNG_MEM_MASK 0xfffffff0 // bits that specify range for memory io
-#define LRNG_IO_MASK 0xfffffffa // bits that specify range for normal io
+#define LRNG_MEM_MASK 0xfffffff0 /* bits that specify range for memory io */
+#define LRNG_IO_MASK 0xfffffffa /* bits that specify range for normal io */
#define PLX_LAS0MAP_REG 0x0004 /* L, Local Addr Space 0 Remap Register */
#define PLX_LAS1MAP_REG 0x00f4 /* L, Local Addr Space 1 Remap Register */
#define LMAP_EN 0x00000001 /* Enable slave decode */
-#define LMAP_MEM_MASK 0xfffffff0 // bits that specify decode for memory io
-#define LMAP_IO_MASK 0xfffffffa // bits that specify decode bits for normal io
+#define LMAP_MEM_MASK 0xfffffff0 /* bits that specify decode for memory io */
+#define LMAP_IO_MASK 0xfffffffa /* bits that specify decode bits for normal io */
/* Mode/Arbitration Register.
*/
@@ -169,7 +169,7 @@ enum bigend_bits {
#define ICS_AERR 0x00000001 /* Assert LSERR on ABORT */
#define ICS_PERR 0x00000002 /* Assert LSERR on Parity Error */
#define ICS_SERR 0x00000004 /* Generate PCI SERR# */
-#define ICS_MBIE 0x00000008 // mailbox interrupt enable
+#define ICS_MBIE 0x00000008 /* mailbox interrupt enable */
#define ICS_PIE 0x00000100 /* PCI Interrupt Enable */
#define ICS_PDIE 0x00000200 /* PCI Doorbell Interrupt Enable */
#define ICS_PAIE 0x00000400 /* PCI Abort Interrupt Enable */
@@ -190,7 +190,7 @@ enum bigend_bits {
#define ICS_TA_DMA0 0x02000000 /* Target Abort - DMA #0 */
#define ICS_TA_DMA1 0x04000000 /* Target Abort - DMA #1 */
#define ICS_TA_RA 0x08000000 /* Target Abort - Retry Timeout */
-#define ICS_MBIA(x) (0x10000000 << ((x) & 0x3)) // mailbox x is active
+#define ICS_MBIA(x) (0x10000000 << ((x) & 0x3)) /* mailbox x is active */
#define PLX_CONTROL_REG 0x006C /* L, EEPROM Cntl & PCI Cmd Codes */
#define CTL_RDMA 0x0000000E /* DMA Read Command */
@@ -208,51 +208,51 @@ enum bigend_bits {
#define CTL_RESET 0x40000000 /* !! Adapter Reset !! */
#define CTL_READY 0x80000000 /* Local Init Done */
-#define PLX_ID_REG 0x70 // hard-coded plx vendor and device ids
+#define PLX_ID_REG 0x70 /* hard-coded plx vendor and device ids */
-#define PLX_REVISION_REG 0x74 // silicon revision
+#define PLX_REVISION_REG 0x74 /* silicon revision */
-#define PLX_DMA0_MODE_REG 0x80 // dma channel 0 mode register
-#define PLX_DMA1_MODE_REG 0x94 // dma channel 0 mode register
+#define PLX_DMA0_MODE_REG 0x80 /* dma channel 0 mode register */
+#define PLX_DMA1_MODE_REG 0x94 /* dma channel 0 mode register */
#define PLX_LOCAL_BUS_16_WIDE_BITS 0x1
#define PLX_LOCAL_BUS_32_WIDE_BITS 0x3
#define PLX_LOCAL_BUS_WIDTH_MASK 0x3
-#define PLX_DMA_EN_READYIN_BIT 0x40 // enable ready in input
-#define PLX_EN_BTERM_BIT 0x80 // enable BTERM# input
-#define PLX_DMA_LOCAL_BURST_EN_BIT 0x100 // enable local burst mode
-#define PLX_EN_CHAIN_BIT 0x200 // enables chaining
-#define PLX_EN_DMA_DONE_INTR_BIT 0x400 // enables interrupt on dma done
-#define PLX_LOCAL_ADDR_CONST_BIT 0x800 // hold local address constant (don't increment)
-#define PLX_DEMAND_MODE_BIT 0x1000 // enables demand-mode for dma transfer
+#define PLX_DMA_EN_READYIN_BIT 0x40 /* enable ready in input */
+#define PLX_EN_BTERM_BIT 0x80 /* enable BTERM# input */
+#define PLX_DMA_LOCAL_BURST_EN_BIT 0x100 /* enable local burst mode */
+#define PLX_EN_CHAIN_BIT 0x200 /* enables chaining */
+#define PLX_EN_DMA_DONE_INTR_BIT 0x400 /* enables interrupt on dma done */
+#define PLX_LOCAL_ADDR_CONST_BIT 0x800 /* hold local address constant (don't increment) */
+#define PLX_DEMAND_MODE_BIT 0x1000 /* enables demand-mode for dma transfer */
#define PLX_EOT_ENABLE_BIT 0x4000
#define PLX_STOP_MODE_BIT 0x8000
-#define PLX_DMA_INTR_PCI_BIT 0x20000 // routes dma interrupt to pci bus (instead of local bus)
+#define PLX_DMA_INTR_PCI_BIT 0x20000 /* routes dma interrupt to pci bus (instead of local bus) */
-#define PLX_DMA0_PCI_ADDRESS_REG 0x84 // pci address that dma transfers start at
+#define PLX_DMA0_PCI_ADDRESS_REG 0x84 /* pci address that dma transfers start at */
#define PLX_DMA1_PCI_ADDRESS_REG 0x98
-#define PLX_DMA0_LOCAL_ADDRESS_REG 0x88 // local address that dma transfers start at
+#define PLX_DMA0_LOCAL_ADDRESS_REG 0x88 /* local address that dma transfers start at */
#define PLX_DMA1_LOCAL_ADDRESS_REG 0x9c
-#define PLX_DMA0_TRANSFER_SIZE_REG 0x8c // number of bytes to transfer (first 23 bits)
+#define PLX_DMA0_TRANSFER_SIZE_REG 0x8c /* number of bytes to transfer (first 23 bits) */
#define PLX_DMA1_TRANSFER_SIZE_REG 0xa0
-#define PLX_DMA0_DESCRIPTOR_REG 0x90 // descriptor pointer register
+#define PLX_DMA0_DESCRIPTOR_REG 0x90 /* descriptor pointer register */
#define PLX_DMA1_DESCRIPTOR_REG 0xa4
-#define PLX_DESC_IN_PCI_BIT 0x1 // descriptor is located in pci space (not local space)
-#define PLX_END_OF_CHAIN_BIT 0x2 // end of chain bit
-#define PLX_INTR_TERM_COUNT 0x4 // interrupt when this descriptor's transfer is finished
-#define PLX_XFER_LOCAL_TO_PCI 0x8 // transfer from local to pci bus (not pci to local)
+#define PLX_DESC_IN_PCI_BIT 0x1 /* descriptor is located in pci space (not local space) */
+#define PLX_END_OF_CHAIN_BIT 0x2 /* end of chain bit */
+#define PLX_INTR_TERM_COUNT 0x4 /* interrupt when this descriptor's transfer is finished */
+#define PLX_XFER_LOCAL_TO_PCI 0x8 /* transfer from local to pci bus (not pci to local) */
-#define PLX_DMA0_CS_REG 0xa8 // command status register
+#define PLX_DMA0_CS_REG 0xa8 /* command status register */
#define PLX_DMA1_CS_REG 0xa9
-#define PLX_DMA_EN_BIT 0x1 // enable dma channel
-#define PLX_DMA_START_BIT 0x2 // start dma transfer
-#define PLX_DMA_ABORT_BIT 0x4 // abort dma transfer
-#define PLX_CLEAR_DMA_INTR_BIT 0x8 // clear dma interrupt
-#define PLX_DMA_DONE_BIT 0x10 // transfer done status bit
+#define PLX_DMA_EN_BIT 0x1 /* enable dma channel */
+#define PLX_DMA_START_BIT 0x2 /* start dma transfer */
+#define PLX_DMA_ABORT_BIT 0x4 /* abort dma transfer */
+#define PLX_CLEAR_DMA_INTR_BIT 0x8 /* clear dma interrupt */
+#define PLX_DMA_DONE_BIT 0x10 /* transfer done status bit */
-#define PLX_DMA0_THRESHOLD_REG 0xb0 // command status register
+#define PLX_DMA0_THRESHOLD_REG 0xb0 /* command status register */
/*
* Accesses near the end of memory can cause the PLX chip
@@ -392,12 +392,12 @@ static inline int plx9080_abort_dma(void *iobase, unsigned int channel)
else
dma_cs_addr = iobase + PLX_DMA0_CS_REG;
- // abort dma transfer if necessary
+ /* abort dma transfer if necessary */
dma_status = readb(dma_cs_addr);
- if ((dma_status & PLX_DMA_EN_BIT) == 0) {
+ if ((dma_status & PLX_DMA_EN_BIT) == 0)
return 0;
- }
- // wait to make sure done bit is zero
+
+ /* wait to make sure done bit is zero */
for (i = 0; (dma_status & PLX_DMA_DONE_BIT) && i < timeout; i++) {
comedi_udelay(1);
dma_status = readb(dma_cs_addr);
@@ -408,9 +408,9 @@ static inline int plx9080_abort_dma(void *iobase, unsigned int channel)
channel);
return -ETIMEDOUT;
}
- // disable and abort channel
+ /* disable and abort channel */
writeb(PLX_DMA_ABORT_BIT, dma_cs_addr);
- // wait for dma done bit
+ /* wait for dma done bit */
dma_status = readb(dma_cs_addr);
for (i = 0; (dma_status & PLX_DMA_DONE_BIT) == 0 && i < timeout; i++) {
comedi_udelay(1);
diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c
new file mode 100644
index 00000000000..8a0bf685493
--- /dev/null
+++ b/drivers/staging/comedi/drivers/poc.c
@@ -0,0 +1,247 @@
+/*
+ comedi/drivers/poc.c
+ Mini-drivers for POC (Piece of Crap) boards
+ Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
+ Copyright (C) 2001 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: poc
+Description: Generic driver for very simple devices
+Author: ds
+Devices: [Keithley Metrabyte] DAC-02 (dac02), [Advantech] PCL-733 (pcl733),
+ PCL-734 (pcl734)
+Updated: Sat, 16 Mar 2002 17:34:48 -0800
+Status: unknown
+
+This driver is indended to support very simple ISA-based devices,
+including:
+ dac02 - Keithley DAC-02 analog output board
+ pcl733 - Advantech PCL-733
+ pcl734 - Advantech PCL-734
+
+Configuration options:
+ [0] - I/O port base
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+static int poc_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int poc_detach(struct comedi_device * dev);
+static int readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int dac02_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pcl733_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pcl734_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+struct boarddef_struct {
+ const char *name;
+ unsigned int iosize;
+ int (*setup) (struct comedi_device *);
+ int type;
+ int n_chan;
+ int n_bits;
+ int (*winsn) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+ int (*rinsn) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+ int (*insnbits) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+ const struct comedi_lrange *range;
+};
+static const struct boarddef_struct boards[] = {
+ {
+ name: "dac02",
+ iosize: 8,
+ //setup: dac02_setup,
+ type: COMEDI_SUBD_AO,
+ n_chan: 2,
+ n_bits: 12,
+ winsn: dac02_ao_winsn,
+ rinsn: readback_insn,
+ range: &range_unknown,
+ },
+ {
+ name: "pcl733",
+ iosize: 4,
+ type: COMEDI_SUBD_DI,
+ n_chan: 32,
+ n_bits: 1,
+ insnbits:pcl733_insn_bits,
+ range: &range_digital,
+ },
+ {
+ name: "pcl734",
+ iosize: 4,
+ type: COMEDI_SUBD_DO,
+ n_chan: 32,
+ n_bits: 1,
+ insnbits:pcl734_insn_bits,
+ range: &range_digital,
+ },
+};
+
+#define n_boards (sizeof(boards)/sizeof(boards[0]))
+#define this_board ((const struct boarddef_struct *)dev->board_ptr)
+
+static struct comedi_driver driver_poc = {
+ driver_name:"poc",
+ module:THIS_MODULE,
+ attach:poc_attach,
+ detach:poc_detach,
+ board_name:&boards[0].name,
+ num_names:n_boards,
+ offset:sizeof(boards[0]),
+};
+
+static int poc_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+ unsigned int iosize;
+
+ iobase = it->options[0];
+ printk("comedi%d: poc: using %s iobase 0x%lx\n", dev->minor,
+ this_board->name, iobase);
+
+ dev->board_name = this_board->name;
+
+ if (iobase == 0) {
+ printk("io base address required\n");
+ return -EINVAL;
+ }
+
+ iosize = this_board->iosize;
+ /* check if io addresses are available */
+ if (!request_region(iobase, iosize, "dac02")) {
+ printk("I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase, iobase + iosize - 1);
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+ if (alloc_private(dev, sizeof(unsigned int) * this_board->n_chan) < 0)
+ return -ENOMEM;
+
+ /* analog output subdevice */
+ s = dev->subdevices + 0;
+ s->type = this_board->type;
+ s->n_chan = this_board->n_chan;
+ s->maxdata = (1 << this_board->n_bits) - 1;
+ s->range_table = this_board->range;
+ s->insn_write = this_board->winsn;
+ s->insn_read = this_board->rinsn;
+ s->insn_bits = this_board->insnbits;
+ if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO) {
+ s->subdev_flags = SDF_WRITABLE;
+ }
+
+ return 0;
+}
+
+static int poc_detach(struct comedi_device * dev)
+{
+ /* only free stuff if it has been allocated by _attach */
+ if (dev->iobase)
+ release_region(dev->iobase, this_board->iosize);
+
+ printk("comedi%d: dac02: remove\n", dev->minor);
+
+ return 0;
+}
+
+static int readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ data[0] = ((unsigned int *) dev->private)[chan];
+
+ return 1;
+}
+
+/* DAC-02 registers */
+#define DAC02_LSB(a) (2 * a)
+#define DAC02_MSB(a) (2 * a + 1)
+
+static int dac02_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int temp;
+ int chan;
+ int output;
+
+ chan = CR_CHAN(insn->chanspec);
+ ((unsigned int *) dev->private)[chan] = data[0];
+ output = data[0];
+#ifdef wrong
+ // convert to complementary binary if range is bipolar
+ if ((CR_RANGE(insn->chanspec) & 0x2) == 0)
+ output = ~output;
+#endif
+ temp = (output << 4) & 0xf0;
+ outb(temp, dev->iobase + DAC02_LSB(chan));
+ temp = (output >> 4) & 0xff;
+ outb(temp, dev->iobase + DAC02_MSB(chan));
+
+ return 1;
+}
+
+static int pcl733_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + 0);
+ data[1] |= (inb(dev->iobase + 1) << 8);
+ data[1] |= (inb(dev->iobase + 2) << 16);
+ data[1] |= (inb(dev->iobase + 3) << 24);
+
+ return 2;
+}
+
+static int pcl734_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ if ((data[0] >> 0) & 0xff)
+ outb((s->state >> 0) & 0xff, dev->iobase + 0);
+ if ((data[0] >> 8) & 0xff)
+ outb((s->state >> 8) & 0xff, dev->iobase + 1);
+ if ((data[0] >> 16) & 0xff)
+ outb((s->state >> 16) & 0xff, dev->iobase + 2);
+ if ((data[0] >> 24) & 0xff)
+ outb((s->state >> 24) & 0xff, dev->iobase + 3);
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+COMEDI_INITCLEANUP(driver_poc);
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
new file mode 100644
index 00000000000..795c4522867
--- /dev/null
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -0,0 +1,1363 @@
+/*======================================================================
+
+ comedi/drivers/quatech_daqp_cs.c
+
+ Quatech DAQP PCMCIA data capture cards COMEDI client driver
+ Copyright (C) 2000, 2003 Brent Baccala <baccala@freesoft.org>
+ The DAQP interface code in this file is released into the public domain.
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+ http://www.comedi.org/
+
+ quatech_daqp_cs.c 1.10
+
+ Documentation for the DAQP PCMCIA cards can be found on Quatech's site:
+
+ ftp://ftp.quatech.com/Manuals/daqp-208.pdf
+
+ This manual is for both the DAQP-208 and the DAQP-308.
+
+ What works:
+
+ - A/D conversion
+ - 8 channels
+ - 4 gain ranges
+ - ground ref or differential
+ - single-shot and timed both supported
+ - D/A conversion, single-shot
+ - digital I/O
+
+ What doesn't:
+
+ - any kind of triggering - external or D/A channel 1
+ - the card's optional expansion board
+ - the card's timer (for anything other than A/D conversion)
+ - D/A update modes other than immediate (i.e, timed)
+ - fancier timing modes
+ - setting card's FIFO buffer thresholds to anything but default
+
+======================================================================*/
+
+/*
+Driver: quatech_daqp_cs
+Description: Quatech DAQP PCMCIA data capture cards
+Author: Brent Baccala <baccala@freesoft.org>
+Status: works
+Devices: [Quatech] DAQP-208 (daqp), DAQP-308
+*/
+
+#include "../comedidev.h"
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+/*
+ All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
+ you do not define PCMCIA_DEBUG at all, all the debug code will be
+ left out. If you compile with PCMCIA_DEBUG=0, the debug code will
+ be present but disabled -- but it can then be enabled for specific
+ modules at load time with a 'pc_debug=#' option to insmod.
+*/
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version = "quatech_daqp_cs.c 1.10 2003/04/21 (Brent Baccala)";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/* Maximum number of separate DAQP devices we'll allow */
+#define MAX_DEV 4
+
+struct local_info_t {
+ struct pcmcia_device *link;
+ dev_node_t node;
+ int stop;
+ int table_index;
+ char board_name[32];
+
+ enum { semaphore, buffer } interrupt_mode;
+
+ struct semaphore eos;
+
+ struct comedi_device *dev;
+ struct comedi_subdevice *s;
+ int count;
+};
+
+/* A list of "instances" of the device. */
+
+static struct local_info_t *dev_table[MAX_DEV] = { NULL, /* ... */ };
+
+/* The DAQP communicates with the system through a 16 byte I/O window. */
+
+#define DAQP_FIFO_SIZE 4096
+
+#define DAQP_FIFO 0
+#define DAQP_SCANLIST 1
+#define DAQP_CONTROL 2
+#define DAQP_STATUS 2
+#define DAQP_DIGITAL_IO 3
+#define DAQP_PACER_LOW 4
+#define DAQP_PACER_MID 5
+#define DAQP_PACER_HIGH 6
+#define DAQP_COMMAND 7
+#define DAQP_DA 8
+#define DAQP_TIMER 10
+#define DAQP_AUX 15
+
+#define DAQP_SCANLIST_DIFFERENTIAL 0x4000
+#define DAQP_SCANLIST_GAIN(x) ((x)<<12)
+#define DAQP_SCANLIST_CHANNEL(x) ((x)<<8)
+#define DAQP_SCANLIST_START 0x0080
+#define DAQP_SCANLIST_EXT_GAIN(x) ((x)<<4)
+#define DAQP_SCANLIST_EXT_CHANNEL(x) (x)
+
+#define DAQP_CONTROL_PACER_100kHz 0xc0
+#define DAQP_CONTROL_PACER_1MHz 0x80
+#define DAQP_CONTROL_PACER_5MHz 0x40
+#define DAQP_CONTROL_PACER_EXTERNAL 0x00
+#define DAQP_CONTORL_EXPANSION 0x20
+#define DAQP_CONTROL_EOS_INT_ENABLE 0x10
+#define DAQP_CONTROL_FIFO_INT_ENABLE 0x08
+#define DAQP_CONTROL_TRIGGER_ONESHOT 0x00
+#define DAQP_CONTROL_TRIGGER_CONTINUOUS 0x04
+#define DAQP_CONTROL_TRIGGER_INTERNAL 0x00
+#define DAQP_CONTROL_TRIGGER_EXTERNAL 0x02
+#define DAQP_CONTROL_TRIGGER_RISING 0x00
+#define DAQP_CONTROL_TRIGGER_FALLING 0x01
+
+#define DAQP_STATUS_IDLE 0x80
+#define DAQP_STATUS_RUNNING 0x40
+#define DAQP_STATUS_EVENTS 0x38
+#define DAQP_STATUS_DATA_LOST 0x20
+#define DAQP_STATUS_END_OF_SCAN 0x10
+#define DAQP_STATUS_FIFO_THRESHOLD 0x08
+#define DAQP_STATUS_FIFO_FULL 0x04
+#define DAQP_STATUS_FIFO_NEARFULL 0x02
+#define DAQP_STATUS_FIFO_EMPTY 0x01
+
+#define DAQP_COMMAND_ARM 0x80
+#define DAQP_COMMAND_RSTF 0x40
+#define DAQP_COMMAND_RSTQ 0x20
+#define DAQP_COMMAND_STOP 0x10
+#define DAQP_COMMAND_LATCH 0x08
+#define DAQP_COMMAND_100kHz 0x00
+#define DAQP_COMMAND_50kHz 0x02
+#define DAQP_COMMAND_25kHz 0x04
+#define DAQP_COMMAND_FIFO_DATA 0x01
+#define DAQP_COMMAND_FIFO_PROGRAM 0x00
+
+#define DAQP_AUX_TRIGGER_TTL 0x00
+#define DAQP_AUX_TRIGGER_ANALOG 0x80
+#define DAQP_AUX_TRIGGER_PRETRIGGER 0x40
+#define DAQP_AUX_TIMER_INT_ENABLE 0x20
+#define DAQP_AUX_TIMER_RELOAD 0x00
+#define DAQP_AUX_TIMER_PAUSE 0x08
+#define DAQP_AUX_TIMER_GO 0x10
+#define DAQP_AUX_TIMER_GO_EXTERNAL 0x18
+#define DAQP_AUX_TIMER_EXTERNAL_SRC 0x04
+#define DAQP_AUX_TIMER_INTERNAL_SRC 0x00
+#define DAQP_AUX_DA_DIRECT 0x00
+#define DAQP_AUX_DA_OVERFLOW 0x01
+#define DAQP_AUX_DA_EXTERNAL 0x02
+#define DAQP_AUX_DA_PACER 0x03
+
+#define DAQP_AUX_RUNNING 0x80
+#define DAQP_AUX_TRIGGERED 0x40
+#define DAQP_AUX_DA_BUFFER 0x20
+#define DAQP_AUX_TIMER_OVERFLOW 0x10
+#define DAQP_AUX_CONVERSION 0x08
+#define DAQP_AUX_DATA_LOST 0x04
+#define DAQP_AUX_FIFO_NEARFULL 0x02
+#define DAQP_AUX_FIFO_EMPTY 0x01
+
+/* These range structures tell COMEDI how the sample values map to
+ * voltages. The A/D converter has four ranges: +/- 10V through
+ * +/- 1.25V, and the D/A converter has only one: +/- 5V.
+ */
+
+static const struct comedi_lrange range_daqp_ai = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25)
+ }
+};
+
+static const struct comedi_lrange range_daqp_ao = { 1, {BIP_RANGE(5)} };
+
+/*====================================================================*/
+
+/* comedi interface code */
+
+static int daqp_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int daqp_detach(struct comedi_device * dev);
+static struct comedi_driver driver_daqp = {
+ driver_name:"quatech_daqp_cs",
+ module:THIS_MODULE,
+ attach:daqp_attach,
+ detach:daqp_detach,
+};
+
+#ifdef DAQP_DEBUG
+
+static void daqp_dump(struct comedi_device * dev)
+{
+ printk("DAQP: status %02x; aux status %02x\n",
+ inb(dev->iobase + DAQP_STATUS), inb(dev->iobase + DAQP_AUX));
+}
+
+static void hex_dump(char *str, void *ptr, int len)
+{
+ unsigned char *cptr = ptr;
+ int i;
+
+ printk(str);
+
+ for (i = 0; i < len; i++) {
+ if (i % 16 == 0) {
+ printk("\n0x%08x:", (unsigned int)cptr);
+ }
+ printk(" %02x", *(cptr++));
+ }
+ printk("\n");
+}
+
+#endif
+
+/* Cancel a running acquisition */
+
+static int daqp_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct local_info_t *local = (struct local_info_t *) s->private;
+
+ if (local->stop) {
+ return -EIO;
+ }
+
+ outb(DAQP_COMMAND_STOP, dev->iobase + DAQP_COMMAND);
+
+ /* flush any linguring data in FIFO - superfluous here */
+ /* outb(DAQP_COMMAND_RSTF, dev->iobase+DAQP_COMMAND); */
+
+ local->interrupt_mode = semaphore;
+
+ return 0;
+}
+
+/* Interrupt handler
+ *
+ * Operates in one of two modes. If local->interrupt_mode is
+ * 'semaphore', just signal the local->eos semaphore and return
+ * (one-shot mode). Otherwise (continuous mode), read data in from
+ * the card, transfer it to the buffer provided by the higher-level
+ * comedi kernel module, and signal various comedi callback routines,
+ * which run pretty quick.
+ */
+
+static void daqp_interrupt(int irq, void *dev_id PT_REGS_ARG)
+{
+ struct local_info_t *local = (struct local_info_t *) dev_id;
+ struct comedi_device *dev;
+ struct comedi_subdevice *s;
+ int loop_limit = 10000;
+ int status;
+
+ if (local == NULL) {
+ printk(KERN_WARNING
+ "daqp_interrupt(): irq %d for unknown device.\n", irq);
+ return;
+ }
+
+ dev = local->dev;
+ if (dev == NULL) {
+ printk(KERN_WARNING "daqp_interrupt(): NULL comedi_device.\n");
+ return;
+ }
+
+ if (!dev->attached) {
+ printk(KERN_WARNING
+ "daqp_interrupt(): struct comedi_device not yet attached.\n");
+ return;
+ }
+
+ s = local->s;
+ if (s == NULL) {
+ printk(KERN_WARNING
+ "daqp_interrupt(): NULL comedi_subdevice.\n");
+ return;
+ }
+
+ if ((struct local_info_t *) s->private != local) {
+ printk(KERN_WARNING
+ "daqp_interrupt(): invalid comedi_subdevice.\n");
+ return;
+ }
+
+ switch (local->interrupt_mode) {
+
+ case semaphore:
+
+ up(&local->eos);
+ break;
+
+ case buffer:
+
+ while (!((status = inb(dev->iobase + DAQP_STATUS))
+ & DAQP_STATUS_FIFO_EMPTY)) {
+
+ short data;
+
+ if (status & DAQP_STATUS_DATA_LOST) {
+ s->async->events |=
+ COMEDI_CB_EOA | COMEDI_CB_OVERFLOW;
+ printk("daqp: data lost\n");
+ daqp_ai_cancel(dev, s);
+ break;
+ }
+
+ data = inb(dev->iobase + DAQP_FIFO);
+ data |= inb(dev->iobase + DAQP_FIFO) << 8;
+ data ^= 0x8000;
+
+ comedi_buf_put(s->async, data);
+
+ /* If there's a limit, decrement it
+ * and stop conversion if zero
+ */
+
+ if (local->count > 0) {
+ local->count--;
+ if (local->count == 0) {
+ daqp_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ break;
+ }
+ }
+
+ if ((loop_limit--) <= 0)
+ break;
+ }
+
+ if (loop_limit <= 0) {
+ printk(KERN_WARNING
+ "loop_limit reached in daqp_interrupt()\n");
+ daqp_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ }
+
+ s->async->events |= COMEDI_CB_BLOCK;
+
+ comedi_event(dev, s);
+ }
+}
+
+/* One-shot analog data acquisition routine */
+
+static int daqp_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct local_info_t *local = (struct local_info_t *) s->private;
+ int i;
+ int v;
+ int counter = 10000;
+
+ if (local->stop) {
+ return -EIO;
+ }
+
+ /* Stop any running conversion */
+ daqp_ai_cancel(dev, s);
+
+ outb(0, dev->iobase + DAQP_AUX);
+
+ /* Reset scan list queue */
+ outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
+
+ /* Program one scan list entry */
+
+ v = DAQP_SCANLIST_CHANNEL(CR_CHAN(insn->chanspec))
+ | DAQP_SCANLIST_GAIN(CR_RANGE(insn->chanspec));
+
+ if (CR_AREF(insn->chanspec) == AREF_DIFF) {
+ v |= DAQP_SCANLIST_DIFFERENTIAL;
+ }
+
+ v |= DAQP_SCANLIST_START;
+
+ outb(v & 0xff, dev->iobase + DAQP_SCANLIST);
+ outb(v >> 8, dev->iobase + DAQP_SCANLIST);
+
+ /* Reset data FIFO (see page 28 of DAQP User's Manual) */
+
+ outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
+
+ /* Set trigger */
+
+ v = DAQP_CONTROL_TRIGGER_ONESHOT | DAQP_CONTROL_TRIGGER_INTERNAL
+ | DAQP_CONTROL_PACER_100kHz | DAQP_CONTROL_EOS_INT_ENABLE;
+
+ outb(v, dev->iobase + DAQP_CONTROL);
+
+ /* Reset any pending interrupts (my card has a tendancy to require
+ * require multiple reads on the status register to achieve this)
+ */
+
+ while (--counter
+ && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
+ if (!counter) {
+ printk("daqp: couldn't clear interrupts in status register\n");
+ return -1;
+ }
+
+ /* Make sure semaphore is blocked */
+ sema_init(&local->eos, 0);
+ local->interrupt_mode = semaphore;
+ local->dev = dev;
+ local->s = s;
+
+ for (i = 0; i < insn->n; i++) {
+
+ /* Start conversion */
+ outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
+ dev->iobase + DAQP_COMMAND);
+
+ /* Wait for interrupt service routine to unblock semaphore */
+ /* Maybe could use a timeout here, but it's interruptible */
+ if (down_interruptible(&local->eos))
+ return -EINTR;
+
+ data[i] = inb(dev->iobase + DAQP_FIFO);
+ data[i] |= inb(dev->iobase + DAQP_FIFO) << 8;
+ data[i] ^= 0x8000;
+ }
+
+ return insn->n;
+}
+
+/* This function converts ns nanoseconds to a counter value suitable
+ * for programming the device. We always use the DAQP's 5 MHz clock,
+ * which with its 24-bit counter, allows values up to 84 seconds.
+ * Also, the function adjusts ns so that it cooresponds to the actual
+ * time that the device will use.
+ */
+
+static int daqp_ns_to_timer(unsigned int *ns, int round)
+{
+ int timer;
+
+ timer = *ns / 200;
+ *ns = timer * 200;
+
+ return timer;
+}
+
+/* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executed by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes.
+ */
+
+static int daqp_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+ if (cmd->convert_src != TRIG_NOW && cmd->convert_src != TRIG_TIMER)
+ err++;
+ if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED 10000 /* 100 kHz - in nanoseconds */
+
+ if (cmd->scan_begin_src == TRIG_TIMER
+ && cmd->scan_begin_arg < MAX_SPEED) {
+ cmd->scan_begin_arg = MAX_SPEED;
+ err++;
+ }
+
+ /* If both scan_begin and convert are both timer values, the only
+ * way that can make sense is if the scan time is the number of
+ * conversions times the convert time
+ */
+
+ if (cmd->scan_begin_src == TRIG_TIMER && cmd->convert_src == TRIG_TIMER
+ && cmd->scan_begin_arg !=
+ cmd->convert_arg * cmd->scan_end_arg) {
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_TIMER && cmd->convert_arg < MAX_SPEED) {
+ cmd->convert_arg = MAX_SPEED;
+ err++;
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg > 0x00ffffff) {
+ cmd->stop_arg = 0x00ffffff;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ daqp_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ daqp_ns_to_timer(&cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int daqp_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct local_info_t *local = (struct local_info_t *) s->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int counter = 100;
+ int scanlist_start_on_every_entry;
+ int threshold;
+
+ int i;
+ int v;
+
+ if (local->stop) {
+ return -EIO;
+ }
+
+ /* Stop any running conversion */
+ daqp_ai_cancel(dev, s);
+
+ outb(0, dev->iobase + DAQP_AUX);
+
+ /* Reset scan list queue */
+ outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
+
+ /* Program pacer clock
+ *
+ * There's two modes we can operate in. If convert_src is
+ * TRIG_TIMER, then convert_arg specifies the time between
+ * each conversion, so we program the pacer clock to that
+ * frequency and set the SCANLIST_START bit on every scanlist
+ * entry. Otherwise, convert_src is TRIG_NOW, which means
+ * we want the fastest possible conversions, scan_begin_src
+ * is TRIG_TIMER, and scan_begin_arg specifies the time between
+ * each scan, so we program the pacer clock to this frequency
+ * and only set the SCANLIST_START bit on the first entry.
+ */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ int counter = daqp_ns_to_timer(&cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
+ outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
+ outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
+ scanlist_start_on_every_entry = 1;
+ } else {
+ int counter = daqp_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
+ outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
+ outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
+ scanlist_start_on_every_entry = 0;
+ }
+
+ /* Program scan list */
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+
+ int chanspec = cmd->chanlist[i];
+
+ /* Program one scan list entry */
+
+ v = DAQP_SCANLIST_CHANNEL(CR_CHAN(chanspec))
+ | DAQP_SCANLIST_GAIN(CR_RANGE(chanspec));
+
+ if (CR_AREF(chanspec) == AREF_DIFF) {
+ v |= DAQP_SCANLIST_DIFFERENTIAL;
+ }
+
+ if (i == 0 || scanlist_start_on_every_entry) {
+ v |= DAQP_SCANLIST_START;
+ }
+
+ outb(v & 0xff, dev->iobase + DAQP_SCANLIST);
+ outb(v >> 8, dev->iobase + DAQP_SCANLIST);
+ }
+
+ /* Now it's time to program the FIFO threshold, basically the
+ * number of samples the card will buffer before it interrupts
+ * the CPU.
+ *
+ * If we don't have a stop count, then use half the size of
+ * the FIFO (the manufacturer's recommendation). Consider
+ * that the FIFO can hold 2K samples (4K bytes). With the
+ * threshold set at half the FIFO size, we have a margin of
+ * error of 1024 samples. At the chip's maximum sample rate
+ * of 100,000 Hz, the CPU would have to delay interrupt
+ * service for a full 10 milliseconds in order to lose data
+ * here (as opposed to higher up in the kernel). I've never
+ * seen it happen. However, for slow sample rates it may
+ * buffer too much data and introduce too much delay for the
+ * user application.
+ *
+ * If we have a stop count, then things get more interesting.
+ * If the stop count is less than the FIFO size (actually
+ * three-quarters of the FIFO size - see below), we just use
+ * the stop count itself as the threshold, the card interrupts
+ * us when that many samples have been taken, and we kill the
+ * acquisition at that point and are done. If the stop count
+ * is larger than that, then we divide it by 2 until it's less
+ * than three quarters of the FIFO size (we always leave the
+ * top quarter of the FIFO as protection against sluggish CPU
+ * interrupt response) and use that as the threshold. So, if
+ * the stop count is 4000 samples, we divide by two twice to
+ * get 1000 samples, use that as the threshold, take four
+ * interrupts to get our 4000 samples and are done.
+ *
+ * The algorithm could be more clever. For example, if 81000
+ * samples are requested, we could set the threshold to 1500
+ * samples and take 54 interrupts to get 81000. But 54 isn't
+ * a power of two, so this algorithm won't find that option.
+ * Instead, it'll set the threshold at 1266 and take 64
+ * interrupts to get 81024 samples, of which the last 24 will
+ * be discarded... but we won't get the last interrupt until
+ * they've been collected. To find the first option, the
+ * computer could look at the prime decomposition of the
+ * sample count (81000 = 3^4 * 5^3 * 2^3) and factor it into a
+ * threshold (1500 = 3 * 5^3 * 2^2) and an interrupt count (54
+ * = 3^3 * 2). Hmmm... a one-line while loop or prime
+ * decomposition of integers... I'll leave it the way it is.
+ *
+ * I'll also note a mini-race condition before ignoring it in
+ * the code. Let's say we're taking 4000 samples, as before.
+ * After 1000 samples, we get an interrupt. But before that
+ * interrupt is completely serviced, another sample is taken
+ * and loaded into the FIFO. Since the interrupt handler
+ * empties the FIFO before returning, it will read 1001 samples.
+ * If that happens four times, we'll end up taking 4004 samples,
+ * not 4000. The interrupt handler will discard the extra four
+ * samples (by halting the acquisition with four samples still
+ * in the FIFO), but we will have to wait for them.
+ *
+ * In short, this code works pretty well, but for either of
+ * the two reasons noted, might end up waiting for a few more
+ * samples than actually requested. Shouldn't make too much
+ * of a difference.
+ */
+
+ /* Save away the number of conversions we should perform, and
+ * compute the FIFO threshold (in bytes, not samples - that's
+ * why we multiple local->count by 2 = sizeof(sample))
+ */
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ local->count = cmd->stop_arg * cmd->scan_end_arg;
+ threshold = 2 * local->count;
+ while (threshold > DAQP_FIFO_SIZE * 3 / 4)
+ threshold /= 2;
+ } else {
+ local->count = -1;
+ threshold = DAQP_FIFO_SIZE / 2;
+ }
+
+ /* Reset data FIFO (see page 28 of DAQP User's Manual) */
+
+ outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
+
+ /* Set FIFO threshold. First two bytes are near-empty
+ * threshold, which is unused; next two bytes are near-full
+ * threshold. We computed the number of bytes we want in the
+ * FIFO when the interrupt is generated, what the card wants
+ * is actually the number of available bytes left in the FIFO
+ * when the interrupt is to happen.
+ */
+
+ outb(0x00, dev->iobase + DAQP_FIFO);
+ outb(0x00, dev->iobase + DAQP_FIFO);
+
+ outb((DAQP_FIFO_SIZE - threshold) & 0xff, dev->iobase + DAQP_FIFO);
+ outb((DAQP_FIFO_SIZE - threshold) >> 8, dev->iobase + DAQP_FIFO);
+
+ /* Set trigger */
+
+ v = DAQP_CONTROL_TRIGGER_CONTINUOUS | DAQP_CONTROL_TRIGGER_INTERNAL
+ | DAQP_CONTROL_PACER_5MHz | DAQP_CONTROL_FIFO_INT_ENABLE;
+
+ outb(v, dev->iobase + DAQP_CONTROL);
+
+ /* Reset any pending interrupts (my card has a tendancy to require
+ * require multiple reads on the status register to achieve this)
+ */
+
+ while (--counter
+ && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
+ if (!counter) {
+ printk("daqp: couldn't clear interrupts in status register\n");
+ return -1;
+ }
+
+ local->interrupt_mode = buffer;
+ local->dev = dev;
+ local->s = s;
+
+ /* Start conversion */
+ outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
+ dev->iobase + DAQP_COMMAND);
+
+ return 0;
+}
+
+/* Single-shot analog output routine */
+
+static int daqp_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct local_info_t *local = (struct local_info_t *) s->private;
+ int d;
+ unsigned int chan;
+
+ if (local->stop) {
+ return -EIO;
+ }
+
+ chan = CR_CHAN(insn->chanspec);
+ d = data[0];
+ d &= 0x0fff;
+ d ^= 0x0800; /* Flip the sign */
+ d |= chan << 12;
+
+ /* Make sure D/A update mode is direct update */
+ outb(0, dev->iobase + DAQP_AUX);
+
+ outw(d, dev->iobase + DAQP_DA);
+
+ return 1;
+}
+
+/* Digital input routine */
+
+static int daqp_di_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct local_info_t *local = (struct local_info_t *) s->private;
+
+ if (local->stop) {
+ return -EIO;
+ }
+
+ data[0] = inb(dev->iobase + DAQP_DIGITAL_IO);
+
+ return 1;
+}
+
+/* Digital output routine */
+
+static int daqp_do_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct local_info_t *local = (struct local_info_t *) s->private;
+
+ if (local->stop) {
+ return -EIO;
+ }
+
+ outw(data[0] & 0xf, dev->iobase + DAQP_DIGITAL_IO);
+
+ return 1;
+}
+
+/* daqp_attach is called via comedi_config to attach a comedi device
+ * to a /dev/comedi*. Note that this is different from daqp_cs_attach()
+ * which is called by the pcmcia subsystem to attach the PCMCIA card
+ * when it is inserted.
+ */
+
+static int daqp_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ struct local_info_t *local = dev_table[it->options[0]];
+ tuple_t tuple;
+ int i;
+ struct comedi_subdevice *s;
+
+ if (it->options[0] < 0 || it->options[0] >= MAX_DEV || !local) {
+ printk("comedi%d: No such daqp device %d\n",
+ dev->minor, it->options[0]);
+ return -EIO;
+ }
+
+ /* Typically brittle code that I don't completely understand,
+ * but "it works on my card". The intent is to pull the model
+ * number of the card out the PCMCIA CIS and stash it away as
+ * the COMEDI board_name. Looks like the third field in
+ * CISTPL_VERS_1 (offset 2) holds what we're looking for. If
+ * it doesn't work, who cares, just leave it as "DAQP".
+ */
+
+ strcpy(local->board_name, "DAQP");
+ dev->board_name = local->board_name;
+
+ tuple.DesiredTuple = CISTPL_VERS_1;
+ if (pcmcia_get_first_tuple(local->link, &tuple) == 0) {
+ u_char buf[128];
+
+ buf[0] = buf[sizeof(buf) - 1] = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 2;
+ if (pcmcia_get_tuple_data(local->link, &tuple) == 0) {
+
+ for (i = 0; i < tuple.TupleDataLen - 4; i++)
+ if (buf[i] == 0)
+ break;
+ for (i++; i < tuple.TupleDataLen - 4; i++)
+ if (buf[i] == 0)
+ break;
+ i++;
+ if ((i < tuple.TupleDataLen - 4)
+ && (strncmp(buf + i, "DAQP", 4) == 0)) {
+ strncpy(local->board_name, buf + i,
+ sizeof(local->board_name));
+ }
+ }
+ }
+
+ dev->iobase = local->link->io.BasePort1;
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+
+ printk("comedi%d: attaching daqp%d (io 0x%04lx)\n",
+ dev->minor, it->options[0], dev->iobase);
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->private = local;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+ s->n_chan = 8;
+ s->len_chanlist = 2048;
+ s->maxdata = 0xffff;
+ s->range_table = &range_daqp_ai;
+ s->insn_read = daqp_ai_insn_read;
+ s->do_cmdtest = daqp_ai_cmdtest;
+ s->do_cmd = daqp_ai_cmd;
+ s->cancel = daqp_ai_cancel;
+
+ s = dev->subdevices + 1;
+ dev->write_subdev = s;
+ s->private = local;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 2;
+ s->len_chanlist = 1;
+ s->maxdata = 0x0fff;
+ s->range_table = &range_daqp_ao;
+ s->insn_write = daqp_ao_insn_write;
+
+ s = dev->subdevices + 2;
+ s->private = local;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 1;
+ s->len_chanlist = 1;
+ s->insn_read = daqp_di_insn_read;
+
+ s = dev->subdevices + 3;
+ s->private = local;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 1;
+ s->len_chanlist = 1;
+ s->insn_write = daqp_do_insn_write;
+
+ return 1;
+}
+
+/* daqp_detach (called from comedi_comdig) does nothing. If the PCMCIA
+ * card is removed, daqp_cs_detach() is called by the pcmcia subsystem.
+ */
+
+static int daqp_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: detaching daqp\n", dev->minor);
+
+ return 0;
+}
+
+/*====================================================================
+
+ PCMCIA interface code
+
+ The rest of the code in this file is based on dummy_cs.c v1.24
+ from the Linux pcmcia_cs distribution v3.1.8 and is subject
+ to the following license agreement.
+
+ The remaining 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.
+
+ The initial developer of the original code is David A. Hinds
+ <dhinds@pcmcia.sourceforge.org>. Portions created by David A. Hinds
+ are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+
+ 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.
+
+======================================================================*/
+
+/*
+ The event() function is this driver's Card Services event handler.
+ It will be called by Card Services when an appropriate card status
+ event is received. The config() and release() entry points are
+ used to configure or release a socket, in response to card
+ insertion and ejection events.
+
+ Kernel version 2.6.16 upwards uses suspend() and resume() functions
+ instead of an event() function.
+*/
+
+static void daqp_cs_config(struct pcmcia_device *link);
+static void daqp_cs_release(struct pcmcia_device *link);
+static int daqp_cs_suspend(struct pcmcia_device *p_dev);
+static int daqp_cs_resume(struct pcmcia_device *p_dev);
+
+/*
+ The attach() and detach() entry points are used to create and destroy
+ "instances" of the driver, where each instance represents everything
+ needed to manage one actual PCMCIA card.
+*/
+
+static int daqp_cs_attach(struct pcmcia_device *);
+static void daqp_cs_detach(struct pcmcia_device *);
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static const dev_info_t dev_info = "quatech_daqp_cs";
+
+/*======================================================================
+
+ daqp_cs_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+
+ The dev_link structure is initialized, but we don't actually
+ configure the card at this point -- we wait until we receive a
+ card insertion event.
+
+======================================================================*/
+
+static int daqp_cs_attach(struct pcmcia_device *link)
+{
+ struct local_info_t *local;
+ int i;
+
+ DEBUG(0, "daqp_cs_attach()\n");
+
+ for (i = 0; i < MAX_DEV; i++)
+ if (dev_table[i] == NULL)
+ break;
+ if (i == MAX_DEV) {
+ printk(KERN_NOTICE "daqp_cs: no devices available\n");
+ return -ENODEV;
+ }
+
+ /* Allocate space for private device-specific data */
+ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
+ if (!local)
+ return -ENOMEM;
+
+ local->table_index = i;
+ dev_table[i] = local;
+ local->link = link;
+ link->priv = local;
+
+ /* Interrupt setup */
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = daqp_interrupt;
+ link->irq.Instance = local;
+
+ /*
+ General socket configuration defaults can go here. In this
+ client, we assume very little, and rely on the CIS for almost
+ everything. In most clients, many details (i.e., number, sizes,
+ and attributes of IO windows) are fixed by the nature of the
+ device, and can be hard-wired here.
+ */
+ link->conf.Attributes = 0;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ daqp_cs_config(link);
+
+ return 0;
+} /* daqp_cs_attach */
+
+/*======================================================================
+
+ This deletes a driver "instance". The device is de-registered
+ with Card Services. If it has been released, all local data
+ structures are freed. Otherwise, the structures will be freed
+ when the device is released.
+
+======================================================================*/
+
+static void daqp_cs_detach(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+
+ DEBUG(0, "daqp_cs_detach(0x%p)\n", link);
+
+ if (link->dev_node) {
+ dev->stop = 1;
+ daqp_cs_release(link);
+ }
+
+ /* Unlink device structure, and free it */
+ dev_table[dev->table_index] = NULL;
+ if (dev)
+ kfree(dev);
+
+} /* daqp_cs_detach */
+
+/*======================================================================
+
+ daqp_cs_config() is scheduled to run after a CARD_INSERTION event
+ is received, to configure the PCMCIA socket, and to make the
+ device available to the system.
+
+======================================================================*/
+
+static void daqp_cs_config(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+ tuple_t tuple;
+ cisparse_t parse;
+ int last_ret;
+ u_char buf[64];
+
+ DEBUG(0, "daqp_cs_config(0x%p)\n", link);
+
+ /*
+ This reads the card's CONFIG tuple to find its configuration
+ registers.
+ */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple))) {
+ cs_error(link, GetTupleData, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_parse_tuple(&tuple, &parse))) {
+ cs_error(link, ParseTuple, last_ret);
+ goto cs_failed;
+ }
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+ /*
+ In this loop, we scan the CIS for configuration table entries,
+ each of which describes a valid card configuration, including
+ voltage, IO window, memory window, and interrupt settings.
+
+ We make no assumptions about the card to be configured: we use
+ just the information available in the CIS. In an ideal world,
+ this would work for any PCMCIA card, but it requires a complete
+ and accurate CIS. In practice, a driver usually "knows" most of
+ these things without consulting the CIS, and most client drivers
+ will only use the CIS to fill in implementation-defined details.
+ */
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ while (1) {
+ cistpl_cftable_entry_t dflt = { 0 };
+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ if (pcmcia_get_tuple_data(link, &tuple))
+ goto next_entry;
+ if (pcmcia_parse_tuple(&tuple, &parse))
+ goto next_entry;
+
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ if (cfg->index == 0)
+ goto next_entry;
+ link->conf.ConfigIndex = cfg->index;
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ }
+
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(link, &link->io))
+ goto next_entry;
+
+ /* If we got this far, we're cool! */
+ break;
+
+ next_entry:
+ if ((last_ret = pcmcia_get_next_tuple(link, &tuple))) {
+ cs_error(link, GetNextTuple, last_ret);
+ goto cs_failed;
+ }
+ }
+
+ /*
+ 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 ((last_ret = pcmcia_request_irq(link, &link->irq))) {
+ cs_error(link, RequestIRQ, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping, and putting the
+ card and host interface into "Memory and IO" mode.
+ */
+ if ((last_ret = pcmcia_request_configuration(link, &link->conf))) {
+ cs_error(link, RequestConfiguration, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ At this point, the dev_node_t structure(s) need to be
+ initialized and arranged in a linked list at link->dev.
+ */
+ /* Comedi's PCMCIA script uses this device name (extracted
+ * from /var/lib/pcmcia/stab) to pass to comedi_config
+ */
+ /* sprintf(dev->node.dev_name, "daqp%d", dev->table_index); */
+ sprintf(dev->node.dev_name, "quatech_daqp_cs");
+ dev->node.major = dev->node.minor = 0;
+ link->dev_node = &dev->node;
+
+ /* Finally, report what we've done */
+ printk(KERN_INFO "%s: index 0x%02x",
+ dev->node.dev_name, link->conf.ConfigIndex);
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ printk(", irq %u", 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");
+
+ return;
+
+ cs_failed:
+ daqp_cs_release(link);
+
+} /* daqp_cs_config */
+
+static void daqp_cs_release(struct pcmcia_device *link)
+{
+ DEBUG(0, "daqp_cs_release(0x%p)\n", link);
+
+ pcmcia_disable_device(link);
+} /* daqp_cs_release */
+
+/*======================================================================
+
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received.
+
+ When a CARD_REMOVAL event is received, we immediately set a
+ private flag to block future accesses to this device. All the
+ functions that actually access the device should check this flag
+ to make sure the card is still present.
+
+======================================================================*/
+
+static int daqp_cs_suspend(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ /* Mark the device as stopped, to block IO until later */
+ local->stop = 1;
+ return 0;
+}
+
+static int daqp_cs_resume(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ local->stop = 0;
+
+ return 0;
+}
+
+/*====================================================================*/
+
+#ifdef MODULE
+
+static struct pcmcia_device_id daqp_cs_id_table[] = {
+ PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0027),
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, daqp_cs_id_table);
+
+struct pcmcia_driver daqp_cs_driver = {
+ .probe = daqp_cs_attach,
+ .remove = daqp_cs_detach,
+ .suspend = daqp_cs_suspend,
+ .resume = daqp_cs_resume,
+ .id_table = daqp_cs_id_table,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+int __init init_module(void)
+{
+ DEBUG(0, "%s\n", version);
+ pcmcia_register_driver(&daqp_cs_driver);
+ comedi_driver_register(&driver_daqp);
+ return 0;
+}
+
+void __exit cleanup_module(void)
+{
+ DEBUG(0, "daqp_cs: unloading\n");
+ comedi_driver_unregister(&driver_daqp);
+ pcmcia_unregister_driver(&daqp_cs_driver);
+}
+
+#endif
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index 65d5242a258..ca347f21d14 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -196,7 +196,7 @@ Configuration options:
/*
The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
*/
-static const comedi_lrange rtd_ai_7520_range = { 18, {
+static const struct comedi_lrange rtd_ai_7520_range = { 18, {
/* +-5V input range gain steps */
BIP_RANGE(5.0),
BIP_RANGE(5.0 / 2),
@@ -223,7 +223,7 @@ static const comedi_lrange rtd_ai_7520_range = { 18, {
};
/* PCI4520 has two more gains (6 more entries) */
-static const comedi_lrange rtd_ai_4520_range = { 24, {
+static const struct comedi_lrange rtd_ai_4520_range = { 24, {
/* +-5V input range gain steps */
BIP_RANGE(5.0),
BIP_RANGE(5.0 / 2),
@@ -255,7 +255,7 @@ static const comedi_lrange rtd_ai_4520_range = { 24, {
};
/* Table order matches range values */
-static const comedi_lrange rtd_ao_range = { 4, {
+static const struct comedi_lrange rtd_ao_range = { 4, {
RANGE(0, 5),
RANGE(0, 10),
RANGE(-5, 5),
@@ -266,7 +266,7 @@ static const comedi_lrange rtd_ao_range = { 4, {
/*
Board descriptions
*/
-typedef struct rtdBoard_struct {
+struct rtdBoard {
const char *name; /* must be first */
int device_id;
int aiChans;
@@ -274,12 +274,12 @@ typedef struct rtdBoard_struct {
int aiMaxGain;
int range10Start; /* start of +-10V range */
int rangeUniStart; /* start of +10V range */
-} rtdBoard;
+};
-static const rtdBoard rtd520Boards[] = {
+static const struct rtdBoard rtd520Boards[] = {
{
name: "DM7520",
- device_id:0x7520,
+ device_id : 0x7520,
aiChans: 16,
aiBits: 12,
aiMaxGain:32,
@@ -288,7 +288,7 @@ static const rtdBoard rtd520Boards[] = {
},
{
name: "PCI4520",
- device_id:0x4520,
+ device_id : 0x4520,
aiChans: 16,
aiBits: 12,
aiMaxGain:128,
@@ -308,13 +308,13 @@ MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
/*
* Useful for shorthand access to the particular board structure
*/
-#define thisboard ((const rtdBoard *)dev->board_ptr)
+#define thisboard ((const struct rtdBoard *)dev->board_ptr)
/*
This structure is for data unique to this hardware driver.
This is also unique for each board in the system.
*/
-typedef struct {
+struct rtdPrivate {
/* memory mapped board structures */
void *las0;
void *las1;
@@ -334,7 +334,7 @@ typedef struct {
unsigned char chanBipolar[RTD_MAX_CHANLIST / 8]; /* bit array */
/* read back data */
- lsampl_t aoValue[2]; /* Used for AO read back */
+ unsigned int aoValue[2]; /* Used for AO read back */
/* timer gate (when enabled) */
u8 utcGate[4]; /* 1 extra allows simple range check */
@@ -358,7 +358,7 @@ typedef struct {
u8 dma1Control;
#endif /* USE_DMA */
unsigned fifoLen;
-} rtdPrivate;
+};
/* bit defines for "flags" */
#define SEND_EOS 0x01 /* send End Of Scan events */
@@ -366,18 +366,18 @@ typedef struct {
#define DMA1_ACTIVE 0x04 /* DMA1 is active */
/* Macros for accessing channel list bit array */
-#define CHAN_ARRAY_TEST(array,index) \
+#define CHAN_ARRAY_TEST(array, index) \
(((array)[(index)/8] >> ((index) & 0x7)) & 0x1)
-#define CHAN_ARRAY_SET(array,index) \
+#define CHAN_ARRAY_SET(array, index) \
(((array)[(index)/8] |= 1 << ((index) & 0x7)))
-#define CHAN_ARRAY_CLEAR(array,index) \
+#define CHAN_ARRAY_CLEAR(array, index) \
(((array)[(index)/8] &= ~(1 << ((index) & 0x7))))
/*
* most drivers define the following macro to make it easy to
* access the private structure.
*/
-#define devpriv ((rtdPrivate *)dev->private)
+#define devpriv ((struct rtdPrivate *)dev->private)
/* Macros to access registers */
@@ -394,15 +394,15 @@ typedef struct {
writel (0, devpriv->las0+LAS0_CGT_CLEAR)
/* Reset channel gain table read and write pointers */
-#define RtdEnableCGT(dev,v) \
+#define RtdEnableCGT(dev, v) \
writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_CGT_ENABLE)
/* Write channel gain table entry */
-#define RtdWriteCGTable(dev,v) \
+#define RtdWriteCGTable(dev, v) \
writel (v, devpriv->las0+LAS0_CGT_WRITE)
/* Write Channel Gain Latch */
-#define RtdWriteCGLatch(dev,v) \
+#define RtdWriteCGLatch(dev, v) \
writel (v, devpriv->las0+LAS0_CGL_WRITE)
/* Reset ADC FIFO */
@@ -410,39 +410,39 @@ typedef struct {
writel (0, devpriv->las0+LAS0_ADC_FIFO_CLEAR)
/* Set ADC start conversion source select (write only) */
-#define RtdAdcConversionSource(dev,v) \
+#define RtdAdcConversionSource(dev, v) \
writel (v, devpriv->las0+LAS0_ADC_CONVERSION)
/* Set burst start source select (write only) */
-#define RtdBurstStartSource(dev,v) \
+#define RtdBurstStartSource(dev, v) \
writel (v, devpriv->las0+LAS0_BURST_START)
/* Set Pacer start source select (write only) */
-#define RtdPacerStartSource(dev,v) \
+#define RtdPacerStartSource(dev, v) \
writel (v, devpriv->las0+LAS0_PACER_START)
/* Set Pacer stop source select (write only) */
-#define RtdPacerStopSource(dev,v) \
+#define RtdPacerStopSource(dev, v) \
writel (v, devpriv->las0+LAS0_PACER_STOP)
/* Set Pacer clock source select (write only) 0=external 1=internal */
-#define RtdPacerClockSource(dev,v) \
+#define RtdPacerClockSource(dev, v) \
writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_SELECT)
/* Set sample counter source select (write only) */
-#define RtdAdcSampleCounterSource(dev,v) \
+#define RtdAdcSampleCounterSource(dev, v) \
writel (v, devpriv->las0+LAS0_ADC_SCNT_SRC)
/* Set Pacer trigger mode select (write only) 0=single cycle, 1=repeat */
-#define RtdPacerTriggerMode(dev,v) \
+#define RtdPacerTriggerMode(dev, v) \
writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_REPEAT)
/* Set About counter stop enable (write only) */
-#define RtdAboutStopEnable(dev,v) \
+#define RtdAboutStopEnable(dev, v) \
writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ACNT_STOP_ENABLE)
/* Set external trigger polarity (write only) 0=positive edge, 1=negative */
-#define RtdTriggerPolarity(dev,v) \
+#define RtdTriggerPolarity(dev, v) \
writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ETRG_POLARITY)
/* Start single ADC conversion */
@@ -473,15 +473,15 @@ typedef struct {
readw (devpriv->las0+LAS0_IT)
/* Interrupt mask */
-#define RtdInterruptMask(dev,v) \
- writew ((devpriv->intMask = (v)),devpriv->las0+LAS0_IT)
+#define RtdInterruptMask(dev, v) \
+ writew ((devpriv->intMask = (v)), devpriv->las0+LAS0_IT)
/* Interrupt status clear (only bits set in mask) */
#define RtdInterruptClear(dev) \
readw (devpriv->las0+LAS0_CLEAR)
/* Interrupt clear mask */
-#define RtdInterruptClearMask(dev,v) \
+#define RtdInterruptClearMask(dev, v) \
writew ((devpriv->intClearMask = (v)), devpriv->las0+LAS0_CLEAR)
/* Interrupt overrun status */
@@ -495,92 +495,92 @@ typedef struct {
/* Pacer counter, 24bit */
#define RtdPacerCount(dev) \
readl (devpriv->las0+LAS0_PCLK)
-#define RtdPacerCounter(dev,v) \
- writel ((v) & 0xffffff,devpriv->las0+LAS0_PCLK)
+#define RtdPacerCounter(dev, v) \
+ writel ((v) & 0xffffff, devpriv->las0+LAS0_PCLK)
/* Burst counter, 10bit */
#define RtdBurstCount(dev) \
readl (devpriv->las0+LAS0_BCLK)
-#define RtdBurstCounter(dev,v) \
- writel ((v) & 0x3ff,devpriv->las0+LAS0_BCLK)
+#define RtdBurstCounter(dev, v) \
+ writel ((v) & 0x3ff, devpriv->las0+LAS0_BCLK)
/* Delay counter, 16bit */
#define RtdDelayCount(dev) \
readl (devpriv->las0+LAS0_DCLK)
-#define RtdDelayCounter(dev,v) \
+#define RtdDelayCounter(dev, v) \
writel ((v) & 0xffff, devpriv->las0+LAS0_DCLK)
/* About counter, 16bit */
#define RtdAboutCount(dev) \
readl (devpriv->las0+LAS0_ACNT)
-#define RtdAboutCounter(dev,v) \
+#define RtdAboutCounter(dev, v) \
writel ((v) & 0xffff, devpriv->las0+LAS0_ACNT)
/* ADC sample counter, 10bit */
#define RtdAdcSampleCount(dev) \
readl (devpriv->las0+LAS0_ADC_SCNT)
-#define RtdAdcSampleCounter(dev,v) \
+#define RtdAdcSampleCounter(dev, v) \
writel ((v) & 0x3ff, devpriv->las0+LAS0_ADC_SCNT)
/* User Timer/Counter (8254) */
-#define RtdUtcCounterGet(dev,n) \
+#define RtdUtcCounterGet(dev, n) \
readb (devpriv->las0 \
+ ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))
-#define RtdUtcCounterPut(dev,n,v) \
+#define RtdUtcCounterPut(dev, n, v) \
writeb ((v) & 0xff, devpriv->las0 \
+ ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))
/* Set UTC (8254) control byte */
-#define RtdUtcCtrlPut(dev,n,v) \
+#define RtdUtcCtrlPut(dev, n, v) \
writeb (devpriv->utcCtrl[(n) & 3] = (((n) & 3) << 6) | ((v) & 0x3f), \
devpriv->las0 + LAS0_UTC_CTRL)
/* Set UTCn clock source (write only) */
-#define RtdUtcClockSource(dev,n,v) \
+#define RtdUtcClockSource(dev, n, v) \
writew (v, devpriv->las0 \
+ ((n <= 0) ? LAS0_UTC0_CLOCK : \
((1 == n) ? LAS0_UTC1_CLOCK : LAS0_UTC2_CLOCK)))
/* Set UTCn gate source (write only) */
-#define RtdUtcGateSource(dev,n,v) \
+#define RtdUtcGateSource(dev, n, v) \
writew (v, devpriv->las0 \
+ ((n <= 0) ? LAS0_UTC0_GATE : \
((1 == n) ? LAS0_UTC1_GATE : LAS0_UTC2_GATE)))
/* User output N source select (write only) */
-#define RtdUsrOutSource(dev,n,v) \
- writel (v,devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : LAS0_UOUT1_SELECT))
+#define RtdUsrOutSource(dev, n, v) \
+ writel (v, devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : LAS0_UOUT1_SELECT))
/* Digital IO */
#define RtdDio0Read(dev) \
(readw (devpriv->las0+LAS0_DIO0) & 0xff)
-#define RtdDio0Write(dev,v) \
+#define RtdDio0Write(dev, v) \
writew ((v) & 0xff, devpriv->las0+LAS0_DIO0)
#define RtdDio1Read(dev) \
(readw (devpriv->las0+LAS0_DIO1) & 0xff)
-#define RtdDio1Write(dev,v) \
+#define RtdDio1Write(dev, v) \
writew ((v) & 0xff, devpriv->las0+LAS0_DIO1)
#define RtdDioStatusRead(dev) \
(readw (devpriv->las0+LAS0_DIO_STATUS) & 0xff)
-#define RtdDioStatusWrite(dev,v) \
+#define RtdDioStatusWrite(dev, v) \
writew ((devpriv->dioStatus = (v)), devpriv->las0+LAS0_DIO_STATUS)
#define RtdDio0CtrlRead(dev) \
(readw (devpriv->las0+LAS0_DIO0_CTRL) & 0xff)
-#define RtdDio0CtrlWrite(dev,v) \
+#define RtdDio0CtrlWrite(dev, v) \
writew ((v) & 0xff, devpriv->las0+LAS0_DIO0_CTRL)
/* Digital to Analog converter */
/* Write one data value (sign + 12bit + marker bits) */
/* Note: matches what DMA would put. Actual value << 3 */
-#define RtdDacFifoPut(dev,n,v) \
+#define RtdDacFifoPut(dev, n, v) \
writew ((v), devpriv->las1 +(((n) == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO))
/* Start single DAC conversion */
-#define RtdDacUpdate(dev,n) \
+#define RtdDacUpdate(dev, n) \
writew (0, devpriv->las0 +(((n) == 0) ? LAS0_DAC1 : LAS0_DAC2))
/* Start single DAC conversion on both DACs */
@@ -588,20 +588,20 @@ typedef struct {
writew (0, devpriv->las0+LAS0_DAC)
/* Set DAC output type and range */
-#define RtdDacRange(dev,n,v) \
+#define RtdDacRange(dev, n, v) \
writew ((v) & 7, devpriv->las0 \
+(((n) == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL))
/* Reset DAC FIFO */
-#define RtdDacClearFifo(dev,n) \
+#define RtdDacClearFifo(dev, n) \
writel (0, devpriv->las0+(((n) == 0) ? LAS0_DAC1_RESET : LAS0_DAC2_RESET))
/* Set source for DMA 0 (write only, shadow?) */
-#define RtdDma0Source(dev,n) \
+#define RtdDma0Source(dev, n) \
writel ((n) & 0xf, devpriv->las0+LAS0_DMA0_SRC)
/* Set source for DMA 1 (write only, shadow?) */
-#define RtdDma1Source(dev,n) \
+#define RtdDma1Source(dev, n) \
writel ((n) & 0xf, devpriv->las0+LAS0_DMA1_SRC)
/* Reset board state for DMA 0 */
@@ -615,51 +615,51 @@ typedef struct {
/* PLX9080 interrupt mask and status */
#define RtdPlxInterruptRead(dev) \
readl (devpriv->lcfg+LCFG_ITCSR)
-#define RtdPlxInterruptWrite(dev,v) \
+#define RtdPlxInterruptWrite(dev, v) \
writel (v, devpriv->lcfg+LCFG_ITCSR)
/* Set mode for DMA 0 */
-#define RtdDma0Mode(dev,m) \
+#define RtdDma0Mode(dev, m) \
writel ((m), devpriv->lcfg+LCFG_DMAMODE0)
/* Set PCI address for DMA 0 */
-#define RtdDma0PciAddr(dev,a) \
+#define RtdDma0PciAddr(dev, a) \
writel ((a), devpriv->lcfg+LCFG_DMAPADR0)
/* Set local address for DMA 0 */
-#define RtdDma0LocalAddr(dev,a) \
+#define RtdDma0LocalAddr(dev, a) \
writel ((a), devpriv->lcfg+LCFG_DMALADR0)
/* Set byte count for DMA 0 */
-#define RtdDma0Count(dev,c) \
+#define RtdDma0Count(dev, c) \
writel ((c), devpriv->lcfg+LCFG_DMASIZ0)
/* Set next descriptor for DMA 0 */
-#define RtdDma0Next(dev,a) \
+#define RtdDma0Next(dev, a) \
writel ((a), devpriv->lcfg+LCFG_DMADPR0)
/* Set mode for DMA 1 */
-#define RtdDma1Mode(dev,m) \
+#define RtdDma1Mode(dev, m) \
writel ((m), devpriv->lcfg+LCFG_DMAMODE1)
/* Set PCI address for DMA 1 */
-#define RtdDma1PciAddr(dev,a) \
+#define RtdDma1PciAddr(dev, a) \
writel ((a), devpriv->lcfg+LCFG_DMAADR1)
/* Set local address for DMA 1 */
-#define RtdDma1LocalAddr(dev,a) \
+#define RtdDma1LocalAddr(dev, a) \
writel ((a), devpriv->lcfg+LCFG_DMALADR1)
/* Set byte count for DMA 1 */
-#define RtdDma1Count(dev,c) \
+#define RtdDma1Count(dev, c) \
writel ((c), devpriv->lcfg+LCFG_DMASIZ1)
/* Set next descriptor for DMA 1 */
-#define RtdDma1Next(dev,a) \
+#define RtdDma1Next(dev, a) \
writel ((a), devpriv->lcfg+LCFG_DMADPR1)
/* Set control for DMA 0 (write only, shadow?) */
-#define RtdDma0Control(dev,n) \
+#define RtdDma0Control(dev, n) \
writeb (devpriv->dma0Control = (n), devpriv->lcfg+LCFG_DMACSR0)
/* Get status for DMA 0 */
@@ -667,7 +667,7 @@ typedef struct {
readb (devpriv->lcfg+LCFG_DMACSR0)
/* Set control for DMA 1 (write only, shadow?) */
-#define RtdDma1Control(dev,n) \
+#define RtdDma1Control(dev, n) \
writeb (devpriv->dma1Control = (n), devpriv->lcfg+LCFG_DMACSR1)
/* Get status for DMA 1 */
@@ -675,39 +675,39 @@ typedef struct {
readb (devpriv->lcfg+LCFG_DMACSR1)
/*
- * The comedi_driver structure tells the Comedi core module
+ * The struct comedi_driver structure tells the Comedi core module
* which functions to call to configure/deconfigure (attac/detach)
* the board, and also about the kernel module that contains
* the device code.
*/
-static int rtd_attach(comedi_device * dev, comedi_devconfig * it);
-static int rtd_detach(comedi_device * dev);
+static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int rtd_detach(struct comedi_device *dev);
-static comedi_driver rtd520Driver = {
+static struct comedi_driver rtd520Driver = {
driver_name: DRV_NAME,
- module:THIS_MODULE,
- attach:rtd_attach,
- detach:rtd_detach,
+ module : THIS_MODULE,
+ attach : rtd_attach,
+ detach : rtd_detach,
};
-static int rtd_ai_rinsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int rtd_ao_winsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int rtd_ao_rinsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int rtd_dio_insn_bits(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int rtd_dio_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int rtd_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,
- comedi_cmd * cmd);
-static int rtd_ai_cmd(comedi_device * dev, comedi_subdevice * s);
-static int rtd_ai_cancel(comedi_device * dev, comedi_subdevice * s);
-//static int rtd_ai_poll (comedi_device *dev,comedi_subdevice *s);
+static int rtd_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int rtd_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int rtd_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int rtd_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int rtd_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int rtd_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd);
+static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
+static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
+/* static int rtd_ai_poll (struct comedi_device *dev,struct comedi_subdevice *s); */
static int rtd_ns_to_timer(unsigned int *ns, int roundMode);
static irqreturn_t rtd_interrupt(int irq, void *d PT_REGS_ARG);
-static int rtd520_probe_fifo_depth(comedi_device *dev);
+static int rtd520_probe_fifo_depth(struct comedi_device *dev);
/*
* Attach is called by the Comedi core to configure the driver
@@ -715,9 +715,9 @@ static int rtd520_probe_fifo_depth(comedi_device *dev);
* in the driver structure, dev->board_ptr contains that
* address.
*/
-static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
+static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{ /* board name and options flags */
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
struct pci_dev *pcidev;
int ret;
resource_size_t physLas0; /* configuation */
@@ -739,7 +739,7 @@ static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
* Allocate the private structure area. alloc_private() is a
* convenient macro defined in comedidev.h.
*/
- if (alloc_private(dev, sizeof(rtdPrivate)) < 0)
+ if (alloc_private(dev, sizeof(struct rtdPrivate)) < 0)
return -ENOMEM;
/*
@@ -779,7 +779,8 @@ static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
devpriv->pci_dev = pcidev;
dev->board_name = thisboard->name;
- if ((ret = comedi_pci_enable(pcidev, DRV_NAME)) < 0) {
+ ret = comedi_pci_enable(pcidev, DRV_NAME);
+ if (ret < 0) {
printk("Failed to enable PCI device and request regions.\n");
return ret;
}
@@ -866,7 +867,7 @@ static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
s->do_cmd = rtd_ai_cmd;
s->do_cmdtest = rtd_ai_cmdtest;
s->cancel = rtd_ai_cancel;
- /*s->poll = rtd_ai_poll; *//* not ready yet */
+ /* s->poll = rtd_ai_poll; */ /* not ready yet */
s = dev->subdevices + 1;
/* analog output subdevice */
@@ -918,8 +919,10 @@ static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
/* TODO: set user out source ??? */
/* check if our interrupt is available and get it */
- if ((ret = comedi_request_irq(devpriv->pci_dev->irq, rtd_interrupt,
- IRQF_SHARED, DRV_NAME, dev)) < 0) {
+ ret = comedi_request_irq(devpriv->pci_dev->irq, rtd_interrupt,
+ IRQF_SHARED, DRV_NAME, dev);
+
+ if (ret < 0) {
printk("Could not get interrupt! (%u)\n",
devpriv->pci_dev->irq);
return ret;
@@ -1005,7 +1008,7 @@ static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
#if 0
/* hit an error, clean up memory and return ret */
-//rtd_attach_die_error:
+/* rtd_attach_die_error: */
#ifdef USE_DMA
for (index = 0; index < DMA_CHAIN_COUNT; index++) {
if (NULL != devpriv->dma0Buff[index]) { /* free buffer memory */
@@ -1057,7 +1060,7 @@ static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
* allocated by _attach(). dev->private and dev->subdevices are
* deallocated automatically by the core.
*/
-static int rtd_detach(comedi_device * dev)
+static int rtd_detach(struct comedi_device *dev)
{
#ifdef USE_DMA
int index;
@@ -1137,7 +1140,7 @@ static int rtd_detach(comedi_device * dev)
/*
Convert a single comedi channel-gain entry to a RTD520 table entry
*/
-static unsigned short rtdConvertChanGain(comedi_device * dev,
+static unsigned short rtdConvertChanGain(struct comedi_device *dev,
unsigned int comediChan, int chanIndex)
{ /* index in channel list */
unsigned int chan, range, aref;
@@ -1187,7 +1190,7 @@ static unsigned short rtdConvertChanGain(comedi_device * dev,
/*
Setup the channel-gain table from a comedi list
*/
-static void rtd_load_channelgain_list(comedi_device * dev,
+static void rtd_load_channelgain_list(struct comedi_device *dev,
unsigned int n_chan, unsigned int *list)
{
if (n_chan > 1) { /* setup channel gain table */
@@ -1206,9 +1209,9 @@ static void rtd_load_channelgain_list(comedi_device * dev,
/* determine fifo size by doing adc conversions until the fifo half
empty status flag clears */
-static int rtd520_probe_fifo_depth(comedi_device *dev)
+static int rtd520_probe_fifo_depth(struct comedi_device *dev)
{
- lsampl_t chanspec = CR_PACK(0, 0, AREF_GROUND);
+ unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
unsigned i;
static const unsigned limit = 0x2000;
unsigned fifo_size = 0;
@@ -1234,7 +1237,7 @@ static int rtd520_probe_fifo_depth(comedi_device *dev)
return -EIO;
}
RtdAdcClearFifo(dev);
- if(fifo_size != 0x400 || fifo_size != 0x2000)
+ if(fifo_size != 0x400 && fifo_size != 0x2000)
{
rt_printk("\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n",
DRV_NAME, fifo_size);
@@ -1251,8 +1254,8 @@ static int rtd520_probe_fifo_depth(comedi_device *dev)
Note, we don't do any settling delays. Use a instruction list to
select, delay, then read.
*/
-static int rtd_ai_rinsn(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_ai_rinsn(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int n, ii;
int stat;
@@ -1304,12 +1307,12 @@ static int rtd_ai_rinsn(comedi_device * dev,
The manual claims that we can do a lword read, but it doesn't work here.
*/
-static int ai_read_n(comedi_device * dev, comedi_subdevice * s, int count)
+static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, int count)
{
int ii;
for (ii = 0; ii < count; ii++) {
- sampl_t sample;
+ short sample;
s16 d;
if (0 == devpriv->aiCount) { /* done */
@@ -1343,10 +1346,10 @@ static int ai_read_n(comedi_device * dev, comedi_subdevice * s, int count)
/*
unknown amout of data is waiting in fifo.
*/
-static int ai_read_dregs(comedi_device * dev, comedi_subdevice * s)
+static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
{
while (RtdFifoStatus(dev) & FS_ADC_NOT_EMPTY) { /* 1 -> not empty */
- sampl_t sample;
+ short sample;
s16 d = RtdAdcFifoGet(dev); /* get 2s comp value */
if (0 == devpriv->aiCount) { /* done */
@@ -1372,20 +1375,20 @@ static int ai_read_dregs(comedi_device * dev, comedi_subdevice * s)
/*
Terminate a DMA transfer and wait for everything to quiet down
*/
-void abort_dma(comedi_device * dev, unsigned int channel)
+void abort_dma(struct comedi_device *dev, unsigned int channel)
{ /* DMA channel 0, 1 */
unsigned long dma_cs_addr; /* the control/status register */
uint8_t status;
unsigned int ii;
- //unsigned long flags;
+ /* unsigned long flags; */
dma_cs_addr = (unsigned long)devpriv->lcfg
+ ((channel == 0) ? LCFG_DMACSR0 : LCFG_DMACSR1);
- // spinlock for plx dma control/status reg
- //comedi_spin_lock_irqsave( &dev->spinlock, flags );
+ /* spinlock for plx dma control/status reg */
+ /* comedi_spin_lock_irqsave( &dev->spinlock, flags ); */
- // abort dma transfer if necessary
+ /* abort dma transfer if necessary */
status = readb(dma_cs_addr);
if ((status & PLX_DMA_EN_BIT) == 0) { /* not enabled (Error?) */
DPRINTK("rtd520: AbortDma on non-active channel %d (0x%x)\n",
@@ -1410,7 +1413,7 @@ void abort_dma(comedi_device * dev, unsigned int channel)
/* set abort bit for channel */
writeb(PLX_DMA_ABORT_BIT, dma_cs_addr);
- // wait for dma done bit to be set
+ /* wait for dma done bit to be set */
status = readb(dma_cs_addr);
for (ii = 0;
(status & PLX_DMA_DONE_BIT) == 0 && ii < RTD_DMA_TIMEOUT;
@@ -1424,14 +1427,14 @@ void abort_dma(comedi_device * dev, unsigned int channel)
}
abortDmaExit:
- //comedi_spin_unlock_irqrestore( &dev->spinlock, flags );
+ /* comedi_spin_unlock_irqrestore( &dev->spinlock, flags ); */
}
/*
Process what is in the DMA transfer buffer and pass to comedi
Note: this is not re-entrant
*/
-static int ai_process_dma(comedi_device * dev, comedi_subdevice * s)
+static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s)
{
int ii, n;
s16 *dp;
@@ -1441,7 +1444,7 @@ static int ai_process_dma(comedi_device * dev, comedi_subdevice * s)
dp = devpriv->dma0Buff[devpriv->dma0Offset];
for (ii = 0; ii < devpriv->fifoLen / 2;) { /* convert samples */
- sampl_t sample;
+ short sample;
if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
sample = (*dp >> 3) + 2048; /* convert to comedi unsigned data */
@@ -1494,10 +1497,10 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */
void *d /* our data */
PT_REGS_ARG)
{ /* cpu context (ignored) */
- comedi_device *dev = d; /* must be called "dev" for devpriv */
+ struct comedi_device *dev = d; /* must be called "dev" for devpriv */
u16 status;
u16 fifoStatus;
- comedi_subdevice *s = dev->subdevices + 0; /* analog in subdevice */
+ struct comedi_subdevice *s = dev->subdevices + 0; /* analog in subdevice */
if (!dev->attached) {
return IRQ_NONE;
@@ -1645,7 +1648,7 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */
/*
return the number of samples available
*/
-static int rtd_ai_poll(comedi_device * dev, comedi_subdevice * s)
+static int rtd_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
{
/* TODO: This needs to mask interrupts, read_dregs, and then re-enable */
/* Not sure what to do if DMA is active */
@@ -1662,8 +1665,8 @@ static int rtd_ai_poll(comedi_device * dev, comedi_subdevice * s)
the command passes.
*/
-static int rtd_ai_cmdtest(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd)
+static int rtd_ai_cmdtest(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
int err = 0;
int tmp;
@@ -1867,9 +1870,9 @@ static int rtd_ai_cmdtest(comedi_device * dev,
This is usually done by an interrupt handler.
Userland gets to the data using read calls.
*/
-static int rtd_ai_cmd(comedi_device * dev, comedi_subdevice * s)
+static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->async->cmd;
+ struct comedi_cmd *cmd = &s->async->cmd;
int timer;
/* stop anything currently running */
@@ -2064,7 +2067,7 @@ static int rtd_ai_cmd(comedi_device * dev, comedi_subdevice * s)
/*
Stop a running data aquisition.
*/
-static int rtd_ai_cancel(comedi_device * dev, comedi_subdevice * s)
+static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
u16 status;
@@ -2132,8 +2135,8 @@ static int rtd_ns_to_timer(unsigned int *ns, int round_mode)
/*
Output one (or more) analog values to a single port as fast as possible.
*/
-static int rtd_ao_winsn(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_ao_winsn(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -2152,7 +2155,7 @@ static int rtd_ao_winsn(comedi_device * dev,
/* VERIFY: comedi range and offset conversions */
if ((range > 1) /* bipolar */
- &&(data[i] < 2048)) {
+ && (data[i] < 2048)) {
/* offset and sign extend */
val = (((int)data[i]) - 2048) << 3;
} else { /* unipolor */
@@ -2187,8 +2190,8 @@ static int rtd_ao_winsn(comedi_device * dev,
/* AO subdevices should have a read insn as well as a write insn.
* Usually this means copying a value stored in devpriv. */
-static int rtd_ao_rinsn(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_ao_rinsn(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -2210,8 +2213,8 @@ static int rtd_ao_rinsn(comedi_device * dev,
* This allows packed reading/writing of the DIO channels. The
* comedi core can convert between insn_bits and insn_read/write
*/
-static int rtd_dio_insn_bits(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_dio_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
if (insn->n != 2)
return -EINVAL;
@@ -2237,8 +2240,8 @@ static int rtd_dio_insn_bits(comedi_device * dev,
/*
Configure one bit on a IO port as Input or Output (hence the name :-).
*/
-static int rtd_dio_insn_config(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_dio_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int chan = CR_CHAN(insn->chanspec);
diff --git a/drivers/staging/comedi/drivers/rtd520.h b/drivers/staging/comedi/drivers/rtd520.h
index 0eb50b8e605..a3ec2599c4b 100644
--- a/drivers/staging/comedi/drivers/rtd520.h
+++ b/drivers/staging/comedi/drivers/rtd520.h
@@ -29,366 +29,366 @@
LAS0 Runtime Area
Local Address Space 0 Offset Read Function Write Function
*/
-#define LAS0_SPARE_00 0x0000 // - -
-#define LAS0_SPARE_04 0x0004 // - -
-#define LAS0_USER_IO 0x0008 // Read User Inputs Write User Outputs
-#define LAS0_SPARE_0C 0x000C // - -
-#define LAS0_ADC 0x0010 // Read FIFO Status Software A/D Start
-#define LAS0_DAC1 0x0014 // - Software D/A1 Update
-#define LAS0_DAC2 0x0018 // - Software D/A2 Update
-#define LAS0_SPARE_1C 0x001C // - -
-#define LAS0_SPARE_20 0x0020 // - -
-#define LAS0_DAC 0x0024 // - Software Simultaneous D/A1 and D/A2 Update
-#define LAS0_PACER 0x0028 // Software Pacer Start Software Pacer Stop
-#define LAS0_TIMER 0x002C // Read Timer Counters Status HDIN Software Trigger
-#define LAS0_IT 0x0030 // Read Interrupt Status Write Interrupt Enable Mask Register
-#define LAS0_CLEAR 0x0034 // Clear ITs set by Clear Mask Set Interrupt Clear Mask
-#define LAS0_OVERRUN 0x0038 // Read pending interrupts Clear Overrun Register
-#define LAS0_SPARE_3C 0x003C // - -
+#define LAS0_SPARE_00 0x0000 /* - - */
+#define LAS0_SPARE_04 0x0004 /* - - */
+#define LAS0_USER_IO 0x0008 /* Read User Inputs Write User Outputs */
+#define LAS0_SPARE_0C 0x000C /* - - */
+#define LAS0_ADC 0x0010 /* Read FIFO Status Software A/D Start */
+#define LAS0_DAC1 0x0014 /* - Software D/A1 Update */
+#define LAS0_DAC2 0x0018 /* - Software D/A2 Update */
+#define LAS0_SPARE_1C 0x001C /* - - */
+#define LAS0_SPARE_20 0x0020 /* - - */
+#define LAS0_DAC 0x0024 /* - Software Simultaneous D/A1 and D/A2 Update */
+#define LAS0_PACER 0x0028 /* Software Pacer Start Software Pacer Stop */
+#define LAS0_TIMER 0x002C /* Read Timer Counters Status HDIN Software Trigger */
+#define LAS0_IT 0x0030 /* Read Interrupt Status Write Interrupt Enable Mask Register */
+#define LAS0_CLEAR 0x0034 /* Clear ITs set by Clear Mask Set Interrupt Clear Mask */
+#define LAS0_OVERRUN 0x0038 /* Read pending interrupts Clear Overrun Register */
+#define LAS0_SPARE_3C 0x003C /* - - */
/*
LAS0 Runtime Area Timer/Counter,Dig.IO
Name Local Address Function
*/
-#define LAS0_PCLK 0x0040 // Pacer Clock value (24bit) Pacer Clock load (24bit)
-#define LAS0_BCLK 0x0044 // Burst Clock value (10bit) Burst Clock load (10bit)
-#define LAS0_ADC_SCNT 0x0048 // A/D Sample counter value (10bit) A/D Sample counter load (10bit)
-#define LAS0_DAC1_UCNT 0x004C // D/A1 Update counter value (10 bit) D/A1 Update counter load (10bit)
-#define LAS0_DAC2_UCNT 0x0050 // D/A2 Update counter value (10 bit) D/A2 Update counter load (10bit)
-#define LAS0_DCNT 0x0054 // Delay counter value (16 bit) Delay counter load (16bit)
-#define LAS0_ACNT 0x0058 // About counter value (16 bit) About counter load (16bit)
-#define LAS0_DAC_CLK 0x005C // DAC clock value (16bit) DAC clock load (16bit)
-#define LAS0_UTC0 0x0060 // 8254 TC Counter 0 User TC 0 value Load count in TC Counter 0
-#define LAS0_UTC1 0x0064 // 8254 TC Counter 1 User TC 1 value Load count in TC Counter 1
-#define LAS0_UTC2 0x0068 // 8254 TC Counter 2 User TC 2 value Load count in TC Counter 2
-#define LAS0_UTC_CTRL 0x006C // 8254 TC Control Word Program counter mode for TC
-#define LAS0_DIO0 0x0070 // Digital I/O Port 0 Read Port Digital I/O Port 0 Write Port
-#define LAS0_DIO1 0x0074 // Digital I/O Port 1 Read Port Digital I/O Port 1 Write Port
-#define LAS0_DIO0_CTRL 0x0078 // Clear digital IRQ status flag/read Clear digital chip/program Port 0
-#define LAS0_DIO_STATUS 0x007C // Read Digital I/O Status word Program digital control register &
+#define LAS0_PCLK 0x0040 /* Pacer Clock value (24bit) Pacer Clock load (24bit) */
+#define LAS0_BCLK 0x0044 /* Burst Clock value (10bit) Burst Clock load (10bit) */
+#define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter value (10bit) A/D Sample counter load (10bit) */
+#define LAS0_DAC1_UCNT 0x004C /* D/A1 Update counter value (10 bit) D/A1 Update counter load (10bit) */
+#define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter value (10 bit) D/A2 Update counter load (10bit) */
+#define LAS0_DCNT 0x0054 /* Delay counter value (16 bit) Delay counter load (16bit) */
+#define LAS0_ACNT 0x0058 /* About counter value (16 bit) About counter load (16bit) */
+#define LAS0_DAC_CLK 0x005C /* DAC clock value (16bit) DAC clock load (16bit) */
+#define LAS0_UTC0 0x0060 /* 8254 TC Counter 0 User TC 0 value Load count in TC Counter 0 */
+#define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 User TC 1 value Load count in TC Counter 1 */
+#define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 User TC 2 value Load count in TC Counter 2 */
+#define LAS0_UTC_CTRL 0x006C /* 8254 TC Control Word Program counter mode for TC */
+#define LAS0_DIO0 0x0070 /* Digital I/O Port 0 Read Port Digital I/O Port 0 Write Port */
+#define LAS0_DIO1 0x0074 /* Digital I/O Port 1 Read Port Digital I/O Port 1 Write Port */
+#define LAS0_DIO0_CTRL 0x0078 /* Clear digital IRQ status flag/read Clear digital chip/program Port 0 */
+#define LAS0_DIO_STATUS 0x007C /* Read Digital I/O Status word Program digital control register & */
/*
LAS0 Setup Area
Name Local Address Function
*/
-#define LAS0_BOARD_RESET 0x0100 // Board reset
-#define LAS0_DMA0_SRC 0x0104 // DMA 0 Sources select
-#define LAS0_DMA1_SRC 0x0108 // DMA 1 Sources select
-#define LAS0_ADC_CONVERSION 0x010C // A/D Conversion Signal select
-#define LAS0_BURST_START 0x0110 // Burst Clock Start Trigger select
-#define LAS0_PACER_START 0x0114 // Pacer Clock Start Trigger select
-#define LAS0_PACER_STOP 0x0118 // Pacer Clock Stop Trigger select
-#define LAS0_ACNT_STOP_ENABLE 0x011C // About Counter Stop Enable
-#define LAS0_PACER_REPEAT 0x0120 // Pacer Start Trigger Mode select
-#define LAS0_DIN_START 0x0124 // High Speed Digital Input Sampling Signal select
-#define LAS0_DIN_FIFO_CLEAR 0x0128 // Digital Input FIFO Clear
-#define LAS0_ADC_FIFO_CLEAR 0x012C // A/D FIFO Clear
-#define LAS0_CGT_WRITE 0x0130 // Channel Gain Table Write
-#define LAS0_CGL_WRITE 0x0134 // Channel Gain Latch Write
-#define LAS0_CG_DATA 0x0138 // Digital Table Write
-#define LAS0_CGT_ENABLE 0x013C // Channel Gain Table Enable
-#define LAS0_CG_ENABLE 0x0140 // Digital Table Enable
-#define LAS0_CGT_PAUSE 0x0144 // Table Pause Enable
-#define LAS0_CGT_RESET 0x0148 // Reset Channel Gain Table
-#define LAS0_CGT_CLEAR 0x014C // Clear Channel Gain Table
-#define LAS0_DAC1_CTRL 0x0150 // D/A1 output type/range
-#define LAS0_DAC1_SRC 0x0154 // D/A1 update source
-#define LAS0_DAC1_CYCLE 0x0158 // D/A1 cycle mode
-#define LAS0_DAC1_RESET 0x015C // D/A1 FIFO reset
-#define LAS0_DAC1_FIFO_CLEAR 0x0160 // D/A1 FIFO clear
-#define LAS0_DAC2_CTRL 0x0164 // D/A2 output type/range
-#define LAS0_DAC2_SRC 0x0168 // D/A2 update source
-#define LAS0_DAC2_CYCLE 0x016C // D/A2 cycle mode
-#define LAS0_DAC2_RESET 0x0170 // D/A2 FIFO reset
-#define LAS0_DAC2_FIFO_CLEAR 0x0174 // D/A2 FIFO clear
-#define LAS0_ADC_SCNT_SRC 0x0178 // A/D Sample Counter Source select
-#define LAS0_PACER_SELECT 0x0180 // Pacer Clock select
-#define LAS0_SBUS0_SRC 0x0184 // SyncBus 0 Source select
-#define LAS0_SBUS0_ENABLE 0x0188 // SyncBus 0 enable
-#define LAS0_SBUS1_SRC 0x018C // SyncBus 1 Source select
-#define LAS0_SBUS1_ENABLE 0x0190 // SyncBus 1 enable
-#define LAS0_SBUS2_SRC 0x0198 // SyncBus 2 Source select
-#define LAS0_SBUS2_ENABLE 0x019C // SyncBus 2 enable
-#define LAS0_ETRG_POLARITY 0x01A4 // External Trigger polarity select
-#define LAS0_EINT_POLARITY 0x01A8 // External Interrupt polarity select
-#define LAS0_UTC0_CLOCK 0x01AC // UTC0 Clock select
-#define LAS0_UTC0_GATE 0x01B0 // UTC0 Gate select
-#define LAS0_UTC1_CLOCK 0x01B4 // UTC1 Clock select
-#define LAS0_UTC1_GATE 0x01B8 // UTC1 Gate select
-#define LAS0_UTC2_CLOCK 0x01BC // UTC2 Clock select
-#define LAS0_UTC2_GATE 0x01C0 // UTC2 Gate select
-#define LAS0_UOUT0_SELECT 0x01C4 // User Output 0 source select
-#define LAS0_UOUT1_SELECT 0x01C8 // User Output 1 source select
-#define LAS0_DMA0_RESET 0x01CC // DMA0 Request state machine reset
-#define LAS0_DMA1_RESET 0x01D0 // DMA1 Request state machine reset
+#define LAS0_BOARD_RESET 0x0100 /* Board reset */
+#define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */
+#define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */
+#define LAS0_ADC_CONVERSION 0x010C /* A/D Conversion Signal select */
+#define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */
+#define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */
+#define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */
+#define LAS0_ACNT_STOP_ENABLE 0x011C /* About Counter Stop Enable */
+#define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */
+#define LAS0_DIN_START 0x0124 /* High Speed Digital Input Sampling Signal select */
+#define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */
+#define LAS0_ADC_FIFO_CLEAR 0x012C /* A/D FIFO Clear */
+#define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */
+#define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */
+#define LAS0_CG_DATA 0x0138 /* Digital Table Write */
+#define LAS0_CGT_ENABLE 0x013C /* Channel Gain Table Enable */
+#define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */
+#define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */
+#define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */
+#define LAS0_CGT_CLEAR 0x014C /* Clear Channel Gain Table */
+#define LAS0_DAC1_CTRL 0x0150 /* D/A1 output type/range */
+#define LAS0_DAC1_SRC 0x0154 /* D/A1 update source */
+#define LAS0_DAC1_CYCLE 0x0158 /* D/A1 cycle mode */
+#define LAS0_DAC1_RESET 0x015C /* D/A1 FIFO reset */
+#define LAS0_DAC1_FIFO_CLEAR 0x0160 /* D/A1 FIFO clear */
+#define LAS0_DAC2_CTRL 0x0164 /* D/A2 output type/range */
+#define LAS0_DAC2_SRC 0x0168 /* D/A2 update source */
+#define LAS0_DAC2_CYCLE 0x016C /* D/A2 cycle mode */
+#define LAS0_DAC2_RESET 0x0170 /* D/A2 FIFO reset */
+#define LAS0_DAC2_FIFO_CLEAR 0x0174 /* D/A2 FIFO clear */
+#define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */
+#define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */
+#define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */
+#define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */
+#define LAS0_SBUS1_SRC 0x018C /* SyncBus 1 Source select */
+#define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */
+#define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */
+#define LAS0_SBUS2_ENABLE 0x019C /* SyncBus 2 enable */
+#define LAS0_ETRG_POLARITY 0x01A4 /* External Trigger polarity select */
+#define LAS0_EINT_POLARITY 0x01A8 /* External Interrupt polarity select */
+#define LAS0_UTC0_CLOCK 0x01AC /* UTC0 Clock select */
+#define LAS0_UTC0_GATE 0x01B0 /* UTC0 Gate select */
+#define LAS0_UTC1_CLOCK 0x01B4 /* UTC1 Clock select */
+#define LAS0_UTC1_GATE 0x01B8 /* UTC1 Gate select */
+#define LAS0_UTC2_CLOCK 0x01BC /* UTC2 Clock select */
+#define LAS0_UTC2_GATE 0x01C0 /* UTC2 Gate select */
+#define LAS0_UOUT0_SELECT 0x01C4 /* User Output 0 source select */
+#define LAS0_UOUT1_SELECT 0x01C8 /* User Output 1 source select */
+#define LAS0_DMA0_RESET 0x01CC /* DMA0 Request state machine reset */
+#define LAS0_DMA1_RESET 0x01D0 /* DMA1 Request state machine reset */
/*
LAS1
Name Local Address Function
*/
-#define LAS1_ADC_FIFO 0x0000 // Read A/D FIFO (16bit) -
-#define LAS1_HDIO_FIFO 0x0004 // Read High Speed Digital Input FIFO (16bit) -
-#define LAS1_DAC1_FIFO 0x0008 // - Write D/A1 FIFO (16bit)
-#define LAS1_DAC2_FIFO 0x000C // - Write D/A2 FIFO (16bit)
+#define LAS1_ADC_FIFO 0x0000 /* Read A/D FIFO (16bit) - */
+#define LAS1_HDIO_FIFO 0x0004 /* Read High Speed Digital Input FIFO (16bit) - */
+#define LAS1_DAC1_FIFO 0x0008 /* - Write D/A1 FIFO (16bit) */
+#define LAS1_DAC2_FIFO 0x000C /* - Write D/A2 FIFO (16bit) */
/*
LCFG: PLX 9080 local config & runtime registers
Name Local Address Function
*/
-#define LCFG_ITCSR 0x0068 // INTCSR, Interrupt Control/Status Register
-#define LCFG_DMAMODE0 0x0080 // DMA Channel 0 Mode Register
-#define LCFG_DMAPADR0 0x0084 // DMA Channel 0 PCI Address Register
-#define LCFG_DMALADR0 0x0088 // DMA Channel 0 Local Address Reg
-#define LCFG_DMASIZ0 0x008C // DMA Channel 0 Transfer Size (Bytes) Register
-#define LCFG_DMADPR0 0x0090 // DMA Channel 0 Descriptor Pointer Register
-#define LCFG_DMAMODE1 0x0094 // DMA Channel 1 Mode Register
-#define LCFG_DMAPADR1 0x0098 // DMA Channel 1 PCI Address Register
-#define LCFG_DMALADR1 0x009C // DMA Channel 1 Local Address Register
-#define LCFG_DMASIZ1 0x00A0 // DMA Channel 1 Transfer Size (Bytes) Register
-#define LCFG_DMADPR1 0x00A4 // DMA Channel 1 Descriptor Pointer Register
-#define LCFG_DMACSR0 0x00A8 // DMA Channel 0 Command/Status Register
-#define LCFG_DMACSR1 0x00A9 // DMA Channel 0 Command/Status Register
-#define LCFG_DMAARB 0x00AC // DMA Arbitration Register
-#define LCFG_DMATHR 0x00B0 // DMA Threshold Register
+#define LCFG_ITCSR 0x0068 /* INTCSR, Interrupt Control/Status Register */
+#define LCFG_DMAMODE0 0x0080 /* DMA Channel 0 Mode Register */
+#define LCFG_DMAPADR0 0x0084 /* DMA Channel 0 PCI Address Register */
+#define LCFG_DMALADR0 0x0088 /* DMA Channel 0 Local Address Reg */
+#define LCFG_DMASIZ0 0x008C /* DMA Channel 0 Transfer Size (Bytes) Register */
+#define LCFG_DMADPR0 0x0090 /* DMA Channel 0 Descriptor Pointer Register */
+#define LCFG_DMAMODE1 0x0094 /* DMA Channel 1 Mode Register */
+#define LCFG_DMAPADR1 0x0098 /* DMA Channel 1 PCI Address Register */
+#define LCFG_DMALADR1 0x009C /* DMA Channel 1 Local Address Register */
+#define LCFG_DMASIZ1 0x00A0 /* DMA Channel 1 Transfer Size (Bytes) Register */
+#define LCFG_DMADPR1 0x00A4 /* DMA Channel 1 Descriptor Pointer Register */
+#define LCFG_DMACSR0 0x00A8 /* DMA Channel 0 Command/Status Register */
+#define LCFG_DMACSR1 0x00A9 /* DMA Channel 0 Command/Status Register */
+#define LCFG_DMAARB 0x00AC /* DMA Arbitration Register */
+#define LCFG_DMATHR 0x00B0 /* DMA Threshold Register */
/*======================================================================
Resister bit definitions
======================================================================*/
-// FIFO Status Word Bits (RtdFifoStatus)
-#define FS_DAC1_NOT_EMPTY 0x0001 // D0 - DAC1 FIFO not empty
-#define FS_DAC1_HEMPTY 0x0002 // D1 - DAC1 FIFO half empty
-#define FS_DAC1_NOT_FULL 0x0004 // D2 - DAC1 FIFO not full
-#define FS_DAC2_NOT_EMPTY 0x0010 // D4 - DAC2 FIFO not empty
-#define FS_DAC2_HEMPTY 0x0020 // D5 - DAC2 FIFO half empty
-#define FS_DAC2_NOT_FULL 0x0040 // D6 - DAC2 FIFO not full
-#define FS_ADC_NOT_EMPTY 0x0100 // D8 - ADC FIFO not empty
-#define FS_ADC_HEMPTY 0x0200 // D9 - ADC FIFO half empty
-#define FS_ADC_NOT_FULL 0x0400 // D10 - ADC FIFO not full
-#define FS_DIN_NOT_EMPTY 0x1000 // D12 - DIN FIFO not empty
-#define FS_DIN_HEMPTY 0x2000 // D13 - DIN FIFO half empty
-#define FS_DIN_NOT_FULL 0x4000 // D14 - DIN FIFO not full
-
-// Timer Status Word Bits (GetTimerStatus)
+/* FIFO Status Word Bits (RtdFifoStatus) */
+#define FS_DAC1_NOT_EMPTY 0x0001 /* D0 - DAC1 FIFO not empty */
+#define FS_DAC1_HEMPTY 0x0002 /* D1 - DAC1 FIFO half empty */
+#define FS_DAC1_NOT_FULL 0x0004 /* D2 - DAC1 FIFO not full */
+#define FS_DAC2_NOT_EMPTY 0x0010 /* D4 - DAC2 FIFO not empty */
+#define FS_DAC2_HEMPTY 0x0020 /* D5 - DAC2 FIFO half empty */
+#define FS_DAC2_NOT_FULL 0x0040 /* D6 - DAC2 FIFO not full */
+#define FS_ADC_NOT_EMPTY 0x0100 /* D8 - ADC FIFO not empty */
+#define FS_ADC_HEMPTY 0x0200 /* D9 - ADC FIFO half empty */
+#define FS_ADC_NOT_FULL 0x0400 /* D10 - ADC FIFO not full */
+#define FS_DIN_NOT_EMPTY 0x1000 /* D12 - DIN FIFO not empty */
+#define FS_DIN_HEMPTY 0x2000 /* D13 - DIN FIFO half empty */
+#define FS_DIN_NOT_FULL 0x4000 /* D14 - DIN FIFO not full */
+
+/* Timer Status Word Bits (GetTimerStatus) */
#define TS_PCLK_GATE 0x0001
-// D0 - Pacer Clock Gate [0 - gated, 1 - enabled]
+/* D0 - Pacer Clock Gate [0 - gated, 1 - enabled] */
#define TS_BCLK_GATE 0x0002
-// D1 - Burst Clock Gate [0 - disabled, 1 - running]
+/* D1 - Burst Clock Gate [0 - disabled, 1 - running] */
#define TS_DCNT_GATE 0x0004
-// D2 - Pacer Clock Delayed Start Trigger [0 - delay over, 1 - delay in
-// progress]
+/* D2 - Pacer Clock Delayed Start Trigger [0 - delay over, 1 - delay in */
+/* progress] */
#define TS_ACNT_GATE 0x0008
-// D3 - Pacer Clock About Trigger [0 - completed, 1 - in progress]
+/* D3 - Pacer Clock About Trigger [0 - completed, 1 - in progress] */
#define TS_PCLK_RUN 0x0010
-// D4 - Pacer Clock Shutdown Flag [0 - Pacer Clock cannot be start
-// triggered only by Software Pacer Start Command, 1 - Pacer Clock can
-// be start triggered]
-
-// External Trigger polarity select
-// External Interrupt polarity select
-#define POL_POSITIVE 0x0 // positive edge
-#define POL_NEGATIVE 0x1 // negative edge
-
-// User Output Signal select (SetUout0Source, SetUout1Source)
-#define UOUT_ADC 0x0 // A/D Conversion Signal
-#define UOUT_DAC1 0x1 // D/A1 Update
-#define UOUT_DAC2 0x2 // D/A2 Update
-#define UOUT_SOFTWARE 0x3 // Software Programmable
-
-// Pacer clock select (SetPacerSource)
-#define PCLK_INTERNAL 1 // Internal Pacer Clock
-#define PCLK_EXTERNAL 0 // External Pacer Clock
-
-// A/D Sample Counter Sources (SetAdcntSource, SetupSampleCounter)
-#define ADC_SCNT_CGT_RESET 0x0 // needs restart with StartPacer
+/* D4 - Pacer Clock Shutdown Flag [0 - Pacer Clock cannot be start */
+/* triggered only by Software Pacer Start Command, 1 - Pacer Clock can */
+/* be start triggered] */
+
+/* External Trigger polarity select */
+/* External Interrupt polarity select */
+#define POL_POSITIVE 0x0 /* positive edge */
+#define POL_NEGATIVE 0x1 /* negative edge */
+
+/* User Output Signal select (SetUout0Source, SetUout1Source) */
+#define UOUT_ADC 0x0 /* A/D Conversion Signal */
+#define UOUT_DAC1 0x1 /* D/A1 Update */
+#define UOUT_DAC2 0x2 /* D/A2 Update */
+#define UOUT_SOFTWARE 0x3 /* Software Programmable */
+
+/* Pacer clock select (SetPacerSource) */
+#define PCLK_INTERNAL 1 /* Internal Pacer Clock */
+#define PCLK_EXTERNAL 0 /* External Pacer Clock */
+
+/* A/D Sample Counter Sources (SetAdcntSource, SetupSampleCounter) */
+#define ADC_SCNT_CGT_RESET 0x0 /* needs restart with StartPacer */
#define ADC_SCNT_FIFO_WRITE 0x1
-// A/D Conversion Signal Select (for SetConversionSelect)
-#define ADC_START_SOFTWARE 0x0 // Software A/D Start
-#define ADC_START_PCLK 0x1 // Pacer Clock (Ext. Int. see Func.509)
-#define ADC_START_BCLK 0x2 // Burst Clock
-#define ADC_START_DIGITAL_IT 0x3 // Digital Interrupt
-#define ADC_START_DAC1_MARKER1 0x4 // D/A 1 Data Marker 1
-#define ADC_START_DAC2_MARKER1 0x5 // D/A 2 Data Marker 1
-#define ADC_START_SBUS0 0x6 // SyncBus 0
-#define ADC_START_SBUS1 0x7 // SyncBus 1
-#define ADC_START_SBUS2 0x8 // SyncBus 2
-
-// Burst Clock start trigger select (SetBurstStart)
-#define BCLK_START_SOFTWARE 0x0 // Software A/D Start (StartBurst)
-#define BCLK_START_PCLK 0x1 // Pacer Clock
-#define BCLK_START_ETRIG 0x2 // External Trigger
-#define BCLK_START_DIGITAL_IT 0x3 // Digital Interrupt
-#define BCLK_START_SBUS0 0x4 // SyncBus 0
-#define BCLK_START_SBUS1 0x5 // SyncBus 1
-#define BCLK_START_SBUS2 0x6 // SyncBus 2
-
-// Pacer Clock start trigger select (SetPacerStart)
-#define PCLK_START_SOFTWARE 0x0 // Software Pacer Start (StartPacer)
-#define PCLK_START_ETRIG 0x1 // External trigger
-#define PCLK_START_DIGITAL_IT 0x2 // Digital interrupt
-#define PCLK_START_UTC2 0x3 // User TC 2 out
-#define PCLK_START_SBUS0 0x4 // SyncBus 0
-#define PCLK_START_SBUS1 0x5 // SyncBus 1
-#define PCLK_START_SBUS2 0x6 // SyncBus 2
-#define PCLK_START_D_SOFTWARE 0x8 // Delayed Software Pacer Start
-#define PCLK_START_D_ETRIG 0x9 // Delayed external trigger
-#define PCLK_START_D_DIGITAL_IT 0xA // Delayed digital interrupt
-#define PCLK_START_D_UTC2 0xB // Delayed User TC 2 out
-#define PCLK_START_D_SBUS0 0xC // Delayed SyncBus 0
-#define PCLK_START_D_SBUS1 0xD // Delayed SyncBus 1
-#define PCLK_START_D_SBUS2 0xE // Delayed SyncBus 2
-#define PCLK_START_ETRIG_GATED 0xF // External Trigger Gated controlled mode
-
-// Pacer Clock Stop Trigger select (SetPacerStop)
-#define PCLK_STOP_SOFTWARE 0x0 // Software Pacer Stop (StopPacer)
-#define PCLK_STOP_ETRIG 0x1 // External Trigger
-#define PCLK_STOP_DIGITAL_IT 0x2 // Digital Interrupt
-#define PCLK_STOP_ACNT 0x3 // About Counter
-#define PCLK_STOP_UTC2 0x4 // User TC2 out
-#define PCLK_STOP_SBUS0 0x5 // SyncBus 0
-#define PCLK_STOP_SBUS1 0x6 // SyncBus 1
-#define PCLK_STOP_SBUS2 0x7 // SyncBus 2
-#define PCLK_STOP_A_SOFTWARE 0x8 // About Software Pacer Stop
-#define PCLK_STOP_A_ETRIG 0x9 // About External Trigger
-#define PCLK_STOP_A_DIGITAL_IT 0xA // About Digital Interrupt
-#define PCLK_STOP_A_UTC2 0xC // About User TC2 out
-#define PCLK_STOP_A_SBUS0 0xD // About SyncBus 0
-#define PCLK_STOP_A_SBUS1 0xE // About SyncBus 1
-#define PCLK_STOP_A_SBUS2 0xF // About SyncBus 2
-
-// About Counter Stop Enable
-#define ACNT_STOP 0x0 // stop enable
-#define ACNT_NO_STOP 0x1 // stop disabled
-
-// DAC update source (SetDAC1Start & SetDAC2Start)
-#define DAC_START_SOFTWARE 0x0 // Software Update
-#define DAC_START_CGT 0x1 // CGT controlled Update
-#define DAC_START_DAC_CLK 0x2 // D/A Clock
-#define DAC_START_EPCLK 0x3 // External Pacer Clock
-#define DAC_START_SBUS0 0x4 // SyncBus 0
-#define DAC_START_SBUS1 0x5 // SyncBus 1
-#define DAC_START_SBUS2 0x6 // SyncBus 2
-
-// DAC Cycle Mode (SetDAC1Cycle, SetDAC2Cycle, SetupDAC)
-#define DAC_CYCLE_SINGLE 0x0 // not cycle
-#define DAC_CYCLE_MULTI 0x1 // cycle
-
-// 8254 Operation Modes (Set8254Mode, SetupTimerCounter)
-#define M8254_EVENT_COUNTER 0 // Event Counter
-#define M8254_HW_ONE_SHOT 1 // Hardware-Retriggerable One-Shot
-#define M8254_RATE_GENERATOR 2 // Rate Generator
-#define M8254_SQUARE_WAVE 3 // Square Wave Mode
-#define M8254_SW_STROBE 4 // Software Triggered Strobe
-#define M8254_HW_STROBE 5 // Hardware Triggered Strobe (Retriggerable)
-
-// User Timer/Counter 0 Clock Select (SetUtc0Clock)
-#define CUTC0_8MHZ 0x0 // 8MHz
-#define CUTC0_EXT_TC_CLOCK1 0x1 // Ext. TC Clock 1
-#define CUTC0_EXT_TC_CLOCK2 0x2 // Ext. TC Clock 2
-#define CUTC0_EXT_PCLK 0x3 // Ext. Pacer Clock
-
-// User Timer/Counter 1 Clock Select (SetUtc1Clock)
-#define CUTC1_8MHZ 0x0 // 8MHz
-#define CUTC1_EXT_TC_CLOCK1 0x1 // Ext. TC Clock 1
-#define CUTC1_EXT_TC_CLOCK2 0x2 // Ext. TC Clock 2
-#define CUTC1_EXT_PCLK 0x3 // Ext. Pacer Clock
-#define CUTC1_UTC0_OUT 0x4 // User Timer/Counter 0 out
-#define CUTC1_DIN_SIGNAL 0x5 // High-Speed Digital Input Sampling signal
-
-// User Timer/Counter 2 Clock Select (SetUtc2Clock)
-#define CUTC2_8MHZ 0x0 // 8MHz
-#define CUTC2_EXT_TC_CLOCK1 0x1 // Ext. TC Clock 1
-#define CUTC2_EXT_TC_CLOCK2 0x2 // Ext. TC Clock 2
-#define CUTC2_EXT_PCLK 0x3 // Ext. Pacer Clock
-#define CUTC2_UTC1_OUT 0x4 // User Timer/Counter 1 out
-
-// User Timer/Counter 0 Gate Select (SetUtc0Gate)
-#define GUTC0_NOT_GATED 0x0 // Not gated
-#define GUTC0_GATED 0x1 // Gated
-#define GUTC0_EXT_TC_GATE1 0x2 // Ext. TC Gate 1
-#define GUTC0_EXT_TC_GATE2 0x3 // Ext. TC Gate 2
-
-// User Timer/Counter 1 Gate Select (SetUtc1Gate)
-#define GUTC1_NOT_GATED 0x0 // Not gated
-#define GUTC1_GATED 0x1 // Gated
-#define GUTC1_EXT_TC_GATE1 0x2 // Ext. TC Gate 1
-#define GUTC1_EXT_TC_GATE2 0x3 // Ext. TC Gate 2
-#define GUTC1_UTC0_OUT 0x4 // User Timer/Counter 0 out
-
-// User Timer/Counter 2 Gate Select (SetUtc2Gate)
-#define GUTC2_NOT_GATED 0x0 // Not gated
-#define GUTC2_GATED 0x1 // Gated
-#define GUTC2_EXT_TC_GATE1 0x2 // Ext. TC Gate 1
-#define GUTC2_EXT_TC_GATE2 0x3 // Ext. TC Gate 2
-#define GUTC2_UTC1_OUT 0x4 // User Timer/Counter 1 out
-
-// Interrupt Source Masks (SetITMask, ClearITMask, GetITStatus)
-#define IRQM_ADC_FIFO_WRITE 0x0001 // ADC FIFO Write
-#define IRQM_CGT_RESET 0x0002 // Reset CGT
-#define IRQM_CGT_PAUSE 0x0008 // Pause CGT
-#define IRQM_ADC_ABOUT_CNT 0x0010 // About Counter out
-#define IRQM_ADC_DELAY_CNT 0x0020 // Delay Counter out
-#define IRQM_ADC_SAMPLE_CNT 0x0040 // ADC Sample Counter
-#define IRQM_DAC1_UCNT 0x0080 // DAC1 Update Counter
-#define IRQM_DAC2_UCNT 0x0100 // DAC2 Update Counter
-#define IRQM_UTC1 0x0200 // User TC1 out
-#define IRQM_UTC1_INV 0x0400 // User TC1 out, inverted
-#define IRQM_UTC2 0x0800 // User TC2 out
-#define IRQM_DIGITAL_IT 0x1000 // Digital Interrupt
-#define IRQM_EXTERNAL_IT 0x2000 // External Interrupt
-#define IRQM_ETRIG_RISING 0x4000 // External Trigger rising-edge
-#define IRQM_ETRIG_FALLING 0x8000 // External Trigger falling-edge
-
-// DMA Request Sources (LAS0)
-#define DMAS_DISABLED 0x0 // DMA Disabled
-#define DMAS_ADC_SCNT 0x1 // ADC Sample Counter
-#define DMAS_DAC1_UCNT 0x2 // D/A1 Update Counter
-#define DMAS_DAC2_UCNT 0x3 // D/A2 Update Counter
-#define DMAS_UTC1 0x4 // User TC1 out
-#define DMAS_ADFIFO_HALF_FULL 0x8 // A/D FIFO half full
-#define DMAS_DAC1_FIFO_HALF_EMPTY 0x9 // D/A1 FIFO half empty
-#define DMAS_DAC2_FIFO_HALF_EMPTY 0xA // D/A2 FIFO half empty
-
-// DMA Local Addresses (0x40000000+LAS1 offset)
-#define DMALADDR_ADC 0x40000000 // A/D FIFO
-#define DMALADDR_HDIN 0x40000004 // High Speed Digital Input FIFO
-#define DMALADDR_DAC1 0x40000008 // D/A1 FIFO
-#define DMALADDR_DAC2 0x4000000C // D/A2 FIFO
-
-// Port 0 compare modes (SetDIO0CompareMode)
-#define DIO_MODE_EVENT 0 // Event Mode
-#define DIO_MODE_MATCH 1 // Match Mode
-
-// Digital Table Enable (Port 1 disable)
-#define DTBL_DISABLE 0 // Enable Digital Table
-#define DTBL_ENABLE 1 // Disable Digital Table
-
-// Sampling Signal for High Speed Digital Input (SetHdinStart)
-#define HDIN_SOFTWARE 0x0 // Software Trigger
-#define HDIN_ADC 0x1 // A/D Conversion Signal
-#define HDIN_UTC0 0x2 // User TC out 0
-#define HDIN_UTC1 0x3 // User TC out 1
-#define HDIN_UTC2 0x4 // User TC out 2
-#define HDIN_EPCLK 0x5 // External Pacer Clock
-#define HDIN_ETRG 0x6 // External Trigger
-
-// Channel Gain Table / Channel Gain Latch
-#define CSC_LATCH 0 // Channel Gain Latch mode
-#define CSC_CGT 1 // Channel Gain Table mode
-
-// Channel Gain Table Pause Enable
-#define CGT_PAUSE_DISABLE 0 // Channel Gain Table Pause Disable
-#define CGT_PAUSE_ENABLE 1 // Channel Gain Table Pause Enable
-
-// DAC output type/range (p63)
-#define AOUT_UNIP5 0 // 0..+5 Volt
-#define AOUT_UNIP10 1 // 0..+10 Volt
-#define AOUT_BIP5 2 // -5..+5 Volt
-#define AOUT_BIP10 3 // -10..+10 Volt
-
-// Ghannel Gain Table field definitions (p61)
-// Gain
+/* A/D Conversion Signal Select (for SetConversionSelect) */
+#define ADC_START_SOFTWARE 0x0 /* Software A/D Start */
+#define ADC_START_PCLK 0x1 /* Pacer Clock (Ext. Int. see Func.509) */
+#define ADC_START_BCLK 0x2 /* Burst Clock */
+#define ADC_START_DIGITAL_IT 0x3 /* Digital Interrupt */
+#define ADC_START_DAC1_MARKER1 0x4 /* D/A 1 Data Marker 1 */
+#define ADC_START_DAC2_MARKER1 0x5 /* D/A 2 Data Marker 1 */
+#define ADC_START_SBUS0 0x6 /* SyncBus 0 */
+#define ADC_START_SBUS1 0x7 /* SyncBus 1 */
+#define ADC_START_SBUS2 0x8 /* SyncBus 2 */
+
+/* Burst Clock start trigger select (SetBurstStart) */
+#define BCLK_START_SOFTWARE 0x0 /* Software A/D Start (StartBurst) */
+#define BCLK_START_PCLK 0x1 /* Pacer Clock */
+#define BCLK_START_ETRIG 0x2 /* External Trigger */
+#define BCLK_START_DIGITAL_IT 0x3 /* Digital Interrupt */
+#define BCLK_START_SBUS0 0x4 /* SyncBus 0 */
+#define BCLK_START_SBUS1 0x5 /* SyncBus 1 */
+#define BCLK_START_SBUS2 0x6 /* SyncBus 2 */
+
+/* Pacer Clock start trigger select (SetPacerStart) */
+#define PCLK_START_SOFTWARE 0x0 /* Software Pacer Start (StartPacer) */
+#define PCLK_START_ETRIG 0x1 /* External trigger */
+#define PCLK_START_DIGITAL_IT 0x2 /* Digital interrupt */
+#define PCLK_START_UTC2 0x3 /* User TC 2 out */
+#define PCLK_START_SBUS0 0x4 /* SyncBus 0 */
+#define PCLK_START_SBUS1 0x5 /* SyncBus 1 */
+#define PCLK_START_SBUS2 0x6 /* SyncBus 2 */
+#define PCLK_START_D_SOFTWARE 0x8 /* Delayed Software Pacer Start */
+#define PCLK_START_D_ETRIG 0x9 /* Delayed external trigger */
+#define PCLK_START_D_DIGITAL_IT 0xA /* Delayed digital interrupt */
+#define PCLK_START_D_UTC2 0xB /* Delayed User TC 2 out */
+#define PCLK_START_D_SBUS0 0xC /* Delayed SyncBus 0 */
+#define PCLK_START_D_SBUS1 0xD /* Delayed SyncBus 1 */
+#define PCLK_START_D_SBUS2 0xE /* Delayed SyncBus 2 */
+#define PCLK_START_ETRIG_GATED 0xF /* External Trigger Gated controlled mode */
+
+/* Pacer Clock Stop Trigger select (SetPacerStop) */
+#define PCLK_STOP_SOFTWARE 0x0 /* Software Pacer Stop (StopPacer) */
+#define PCLK_STOP_ETRIG 0x1 /* External Trigger */
+#define PCLK_STOP_DIGITAL_IT 0x2 /* Digital Interrupt */
+#define PCLK_STOP_ACNT 0x3 /* About Counter */
+#define PCLK_STOP_UTC2 0x4 /* User TC2 out */
+#define PCLK_STOP_SBUS0 0x5 /* SyncBus 0 */
+#define PCLK_STOP_SBUS1 0x6 /* SyncBus 1 */
+#define PCLK_STOP_SBUS2 0x7 /* SyncBus 2 */
+#define PCLK_STOP_A_SOFTWARE 0x8 /* About Software Pacer Stop */
+#define PCLK_STOP_A_ETRIG 0x9 /* About External Trigger */
+#define PCLK_STOP_A_DIGITAL_IT 0xA /* About Digital Interrupt */
+#define PCLK_STOP_A_UTC2 0xC /* About User TC2 out */
+#define PCLK_STOP_A_SBUS0 0xD /* About SyncBus 0 */
+#define PCLK_STOP_A_SBUS1 0xE /* About SyncBus 1 */
+#define PCLK_STOP_A_SBUS2 0xF /* About SyncBus 2 */
+
+/* About Counter Stop Enable */
+#define ACNT_STOP 0x0 /* stop enable */
+#define ACNT_NO_STOP 0x1 /* stop disabled */
+
+/* DAC update source (SetDAC1Start & SetDAC2Start) */
+#define DAC_START_SOFTWARE 0x0 /* Software Update */
+#define DAC_START_CGT 0x1 /* CGT controlled Update */
+#define DAC_START_DAC_CLK 0x2 /* D/A Clock */
+#define DAC_START_EPCLK 0x3 /* External Pacer Clock */
+#define DAC_START_SBUS0 0x4 /* SyncBus 0 */
+#define DAC_START_SBUS1 0x5 /* SyncBus 1 */
+#define DAC_START_SBUS2 0x6 /* SyncBus 2 */
+
+/* DAC Cycle Mode (SetDAC1Cycle, SetDAC2Cycle, SetupDAC) */
+#define DAC_CYCLE_SINGLE 0x0 /* not cycle */
+#define DAC_CYCLE_MULTI 0x1 /* cycle */
+
+/* 8254 Operation Modes (Set8254Mode, SetupTimerCounter) */
+#define M8254_EVENT_COUNTER 0 /* Event Counter */
+#define M8254_HW_ONE_SHOT 1 /* Hardware-Retriggerable One-Shot */
+#define M8254_RATE_GENERATOR 2 /* Rate Generator */
+#define M8254_SQUARE_WAVE 3 /* Square Wave Mode */
+#define M8254_SW_STROBE 4 /* Software Triggered Strobe */
+#define M8254_HW_STROBE 5 /* Hardware Triggered Strobe (Retriggerable) */
+
+/* User Timer/Counter 0 Clock Select (SetUtc0Clock) */
+#define CUTC0_8MHZ 0x0 /* 8MHz */
+#define CUTC0_EXT_TC_CLOCK1 0x1 /* Ext. TC Clock 1 */
+#define CUTC0_EXT_TC_CLOCK2 0x2 /* Ext. TC Clock 2 */
+#define CUTC0_EXT_PCLK 0x3 /* Ext. Pacer Clock */
+
+/* User Timer/Counter 1 Clock Select (SetUtc1Clock) */
+#define CUTC1_8MHZ 0x0 /* 8MHz */
+#define CUTC1_EXT_TC_CLOCK1 0x1 /* Ext. TC Clock 1 */
+#define CUTC1_EXT_TC_CLOCK2 0x2 /* Ext. TC Clock 2 */
+#define CUTC1_EXT_PCLK 0x3 /* Ext. Pacer Clock */
+#define CUTC1_UTC0_OUT 0x4 /* User Timer/Counter 0 out */
+#define CUTC1_DIN_SIGNAL 0x5 /* High-Speed Digital Input Sampling signal */
+
+/* User Timer/Counter 2 Clock Select (SetUtc2Clock) */
+#define CUTC2_8MHZ 0x0 /* 8MHz */
+#define CUTC2_EXT_TC_CLOCK1 0x1 /* Ext. TC Clock 1 */
+#define CUTC2_EXT_TC_CLOCK2 0x2 /* Ext. TC Clock 2 */
+#define CUTC2_EXT_PCLK 0x3 /* Ext. Pacer Clock */
+#define CUTC2_UTC1_OUT 0x4 /* User Timer/Counter 1 out */
+
+/* User Timer/Counter 0 Gate Select (SetUtc0Gate) */
+#define GUTC0_NOT_GATED 0x0 /* Not gated */
+#define GUTC0_GATED 0x1 /* Gated */
+#define GUTC0_EXT_TC_GATE1 0x2 /* Ext. TC Gate 1 */
+#define GUTC0_EXT_TC_GATE2 0x3 /* Ext. TC Gate 2 */
+
+/* User Timer/Counter 1 Gate Select (SetUtc1Gate) */
+#define GUTC1_NOT_GATED 0x0 /* Not gated */
+#define GUTC1_GATED 0x1 /* Gated */
+#define GUTC1_EXT_TC_GATE1 0x2 /* Ext. TC Gate 1 */
+#define GUTC1_EXT_TC_GATE2 0x3 /* Ext. TC Gate 2 */
+#define GUTC1_UTC0_OUT 0x4 /* User Timer/Counter 0 out */
+
+/* User Timer/Counter 2 Gate Select (SetUtc2Gate) */
+#define GUTC2_NOT_GATED 0x0 /* Not gated */
+#define GUTC2_GATED 0x1 /* Gated */
+#define GUTC2_EXT_TC_GATE1 0x2 /* Ext. TC Gate 1 */
+#define GUTC2_EXT_TC_GATE2 0x3 /* Ext. TC Gate 2 */
+#define GUTC2_UTC1_OUT 0x4 /* User Timer/Counter 1 out */
+
+/* Interrupt Source Masks (SetITMask, ClearITMask, GetITStatus) */
+#define IRQM_ADC_FIFO_WRITE 0x0001 /* ADC FIFO Write */
+#define IRQM_CGT_RESET 0x0002 /* Reset CGT */
+#define IRQM_CGT_PAUSE 0x0008 /* Pause CGT */
+#define IRQM_ADC_ABOUT_CNT 0x0010 /* About Counter out */
+#define IRQM_ADC_DELAY_CNT 0x0020 /* Delay Counter out */
+#define IRQM_ADC_SAMPLE_CNT 0x0040 /* ADC Sample Counter */
+#define IRQM_DAC1_UCNT 0x0080 /* DAC1 Update Counter */
+#define IRQM_DAC2_UCNT 0x0100 /* DAC2 Update Counter */
+#define IRQM_UTC1 0x0200 /* User TC1 out */
+#define IRQM_UTC1_INV 0x0400 /* User TC1 out, inverted */
+#define IRQM_UTC2 0x0800 /* User TC2 out */
+#define IRQM_DIGITAL_IT 0x1000 /* Digital Interrupt */
+#define IRQM_EXTERNAL_IT 0x2000 /* External Interrupt */
+#define IRQM_ETRIG_RISING 0x4000 /* External Trigger rising-edge */
+#define IRQM_ETRIG_FALLING 0x8000 /* External Trigger falling-edge */
+
+/* DMA Request Sources (LAS0) */
+#define DMAS_DISABLED 0x0 /* DMA Disabled */
+#define DMAS_ADC_SCNT 0x1 /* ADC Sample Counter */
+#define DMAS_DAC1_UCNT 0x2 /* D/A1 Update Counter */
+#define DMAS_DAC2_UCNT 0x3 /* D/A2 Update Counter */
+#define DMAS_UTC1 0x4 /* User TC1 out */
+#define DMAS_ADFIFO_HALF_FULL 0x8 /* A/D FIFO half full */
+#define DMAS_DAC1_FIFO_HALF_EMPTY 0x9 /* D/A1 FIFO half empty */
+#define DMAS_DAC2_FIFO_HALF_EMPTY 0xA /* D/A2 FIFO half empty */
+
+/* DMA Local Addresses (0x40000000+LAS1 offset) */
+#define DMALADDR_ADC 0x40000000 /* A/D FIFO */
+#define DMALADDR_HDIN 0x40000004 /* High Speed Digital Input FIFO */
+#define DMALADDR_DAC1 0x40000008 /* D/A1 FIFO */
+#define DMALADDR_DAC2 0x4000000C /* D/A2 FIFO */
+
+/* Port 0 compare modes (SetDIO0CompareMode) */
+#define DIO_MODE_EVENT 0 /* Event Mode */
+#define DIO_MODE_MATCH 1 /* Match Mode */
+
+/* Digital Table Enable (Port 1 disable) */
+#define DTBL_DISABLE 0 /* Enable Digital Table */
+#define DTBL_ENABLE 1 /* Disable Digital Table */
+
+/* Sampling Signal for High Speed Digital Input (SetHdinStart) */
+#define HDIN_SOFTWARE 0x0 /* Software Trigger */
+#define HDIN_ADC 0x1 /* A/D Conversion Signal */
+#define HDIN_UTC0 0x2 /* User TC out 0 */
+#define HDIN_UTC1 0x3 /* User TC out 1 */
+#define HDIN_UTC2 0x4 /* User TC out 2 */
+#define HDIN_EPCLK 0x5 /* External Pacer Clock */
+#define HDIN_ETRG 0x6 /* External Trigger */
+
+/* Channel Gain Table / Channel Gain Latch */
+#define CSC_LATCH 0 /* Channel Gain Latch mode */
+#define CSC_CGT 1 /* Channel Gain Table mode */
+
+/* Channel Gain Table Pause Enable */
+#define CGT_PAUSE_DISABLE 0 /* Channel Gain Table Pause Disable */
+#define CGT_PAUSE_ENABLE 1 /* Channel Gain Table Pause Enable */
+
+/* DAC output type/range (p63) */
+#define AOUT_UNIP5 0 /* 0..+5 Volt */
+#define AOUT_UNIP10 1 /* 0..+10 Volt */
+#define AOUT_BIP5 2 /* -5..+5 Volt */
+#define AOUT_BIP10 3 /* -10..+10 Volt */
+
+/* Ghannel Gain Table field definitions (p61) */
+/* Gain */
#define GAIN1 0
#define GAIN2 1
#define GAIN4 2
@@ -398,15 +398,15 @@
#define GAIN64 6
#define GAIN128 7
-// Input range/polarity
-#define AIN_BIP5 0 // -5..+5 Volt
-#define AIN_BIP10 1 // -10..+10 Volt
-#define AIN_UNIP10 2 // 0..+10 Volt
+/* Input range/polarity */
+#define AIN_BIP5 0 /* -5..+5 Volt */
+#define AIN_BIP10 1 /* -10..+10 Volt */
+#define AIN_UNIP10 2 /* 0..+10 Volt */
-// non referenced single ended select bit
-#define NRSE_AGND 0 // AGND referenced SE input
-#define NRSE_AINS 1 // AIN SENSE referenced SE input
+/* non referenced single ended select bit */
+#define NRSE_AGND 0 /* AGND referenced SE input */
+#define NRSE_AINS 1 /* AIN SENSE referenced SE input */
-// single ended vs differential
-#define GND_SE 0 // Single-Ended
-#define GND_DIFF 1 // Differential
+/* single ended vs differential */
+#define GND_SE 0 /* Single-Ended */
+#define GND_DIFF 1 /* Differential */
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c
new file mode 100644
index 00000000000..334ac5773a1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/rti800.c
@@ -0,0 +1,458 @@
+/*
+ comedi/drivers/rti800.c
+ Hardware driver for Analog Devices RTI-800/815 board
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: rti800
+Description: Analog Devices RTI-800/815
+Author: ds
+Status: unknown
+Updated: Fri, 05 Sep 2008 14:50:44 +0100
+Devices: [Analog Devices] RTI-800 (rti800), RTI-815 (rti815)
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ
+ [2] - A/D reference
+ 0 = differential
+ 1 = pseudodifferential (common)
+ 2 = single-ended
+ [3] - A/D range
+ 0 = [-10,10]
+ 1 = [-5,5]
+ 2 = [0,10]
+ [4] - A/D encoding
+ 0 = two's complement
+ 1 = straight binary
+ [5] - DAC 0 range
+ 0 = [-10,10]
+ 1 = [0,10]
+ [6] - DAC 0 encoding
+ 0 = two's complement
+ 1 = straight binary
+ [7] - DAC 1 range (same as DAC 0)
+ [8] - DAC 1 encoding (same as DAC 0)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define RTI800_SIZE 16
+
+#define RTI800_CSR 0
+#define RTI800_MUXGAIN 1
+#define RTI800_CONVERT 2
+#define RTI800_ADCLO 3
+#define RTI800_ADCHI 4
+#define RTI800_DAC0LO 5
+#define RTI800_DAC0HI 6
+#define RTI800_DAC1LO 7
+#define RTI800_DAC1HI 8
+#define RTI800_CLRFLAGS 9
+#define RTI800_DI 10
+#define RTI800_DO 11
+#define RTI800_9513A_DATA 12
+#define RTI800_9513A_CNTRL 13
+#define RTI800_9513A_STATUS 13
+
+/*
+ * flags for CSR register
+ */
+
+#define RTI800_BUSY 0x80
+#define RTI800_DONE 0x40
+#define RTI800_OVERRUN 0x20
+#define RTI800_TCR 0x10
+#define RTI800_DMA_ENAB 0x08
+#define RTI800_INTR_TC 0x04
+#define RTI800_INTR_EC 0x02
+#define RTI800_INTR_OVRN 0x01
+
+#define Am9513_8BITBUS
+
+#define Am9513_output_control(a) outb(a,dev->iobase+RTI800_9513A_CNTRL)
+#define Am9513_output_data(a) outb(a,dev->iobase+RTI800_9513A_DATA)
+#define Am9513_input_data() inb(dev->iobase+RTI800_9513A_DATA)
+#define Am9513_input_status() inb(dev->iobase+RTI800_9513A_STATUS)
+
+#include "am9513.h"
+
+static const struct comedi_lrange range_rti800_ai_10_bipolar = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.02)
+ }
+};
+static const struct comedi_lrange range_rti800_ai_5_bipolar = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.01)
+ }
+};
+static const struct comedi_lrange range_rti800_ai_unipolar = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.02)
+ }
+};
+
+struct rti800_board {
+
+ const char *name;
+ int has_ao;
+};
+
+static const struct rti800_board boardtypes[] = {
+ {"rti800", 0},
+ {"rti815", 1},
+};
+
+#define this_board ((const struct rti800_board *)dev->board_ptr)
+
+static int rti800_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int rti800_detach(struct comedi_device * dev);
+static struct comedi_driver driver_rti800 = {
+ driver_name:"rti800",
+ module:THIS_MODULE,
+ attach:rti800_attach,
+ detach:rti800_detach,
+ num_names:sizeof(boardtypes) / sizeof(struct rti800_board),
+ board_name:&boardtypes[0].name,
+ offset:sizeof(struct rti800_board),
+};
+
+COMEDI_INITCLEANUP(driver_rti800);
+
+static irqreturn_t rti800_interrupt(int irq, void *dev PT_REGS_ARG);
+
+struct rti800_private {
+ enum {
+ adc_diff, adc_pseudodiff, adc_singleended
+ } adc_mux;
+ enum {
+ adc_bipolar10, adc_bipolar5, adc_unipolar10
+ } adc_range;
+ enum {
+ adc_2comp, adc_straight
+ } adc_coding;
+ enum {
+ dac_bipolar10, dac_unipolar10
+ } dac0_range, dac1_range;
+ enum {
+ dac_2comp, dac_straight
+ } dac0_coding, dac1_coding;
+ const struct comedi_lrange *ao_range_type_list[2];
+ unsigned int ao_readback[2];
+ int muxgain_bits;
+};
+
+#define devpriv ((struct rti800_private *)dev->private)
+
+#define RTI800_TIMEOUT 100
+
+static irqreturn_t rti800_interrupt(int irq, void *dev PT_REGS_ARG)
+{
+ return IRQ_HANDLED;
+}
+
+// settling delay times in usec for different gains
+static const int gaindelay[] = { 10, 20, 40, 80 };
+
+static int rti800_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, t;
+ int status;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned gain = CR_RANGE(insn->chanspec);
+ unsigned muxgain_bits;
+
+ inb(dev->iobase + RTI800_ADCHI);
+ outb(0, dev->iobase + RTI800_CLRFLAGS);
+
+ muxgain_bits = chan | (gain << 5);
+ if (muxgain_bits != devpriv->muxgain_bits) {
+ devpriv->muxgain_bits = muxgain_bits;
+ outb(devpriv->muxgain_bits, dev->iobase + RTI800_MUXGAIN);
+ /* without a delay here, the RTI_OVERRUN bit
+ * gets set, and you will have an error. */
+ if (insn->n > 0) {
+ BUG_ON(gain >=
+ sizeof(gaindelay) / sizeof(gaindelay[0]));
+ comedi_udelay(gaindelay[gain]);
+ }
+ }
+
+ for (i = 0; i < insn->n; i++) {
+ outb(0, dev->iobase + RTI800_CONVERT);
+ for (t = RTI800_TIMEOUT; t; t--) {
+ status = inb(dev->iobase + RTI800_CSR);
+ if (status & RTI800_OVERRUN) {
+ rt_printk("rti800: a/d overrun\n");
+ outb(0, dev->iobase + RTI800_CLRFLAGS);
+ return -EIO;
+ }
+ if (status & RTI800_DONE)
+ break;
+ comedi_udelay(1);
+ }
+ if (t == 0) {
+ rt_printk("rti800: timeout\n");
+ return -ETIME;
+ }
+ data[i] = inb(dev->iobase + RTI800_ADCLO);
+ data[i] |= (0xf & inb(dev->iobase + RTI800_ADCHI)) << 8;
+
+ if (devpriv->adc_coding == adc_2comp) {
+ data[i] ^= 0x800;
+ }
+ }
+
+ return i;
+}
+
+static int rti800_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+static int rti800_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int d;
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ devpriv->ao_readback[chan] = d = data[i];
+ if (devpriv->dac0_coding == dac_2comp) {
+ d ^= 0x800;
+ }
+ outb(d & 0xff,
+ dev->iobase + (chan ? RTI800_DAC1LO : RTI800_DAC0LO));
+ outb(d >> 8,
+ dev->iobase + (chan ? RTI800_DAC1HI : RTI800_DAC0HI));
+ }
+ return i;
+}
+
+static int rti800_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+ data[1] = inb(dev->iobase + RTI800_DI);
+ return 2;
+}
+
+static int rti800_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ /* Outputs are inverted... */
+ outb(s->state ^ 0xff, dev->iobase + RTI800_DO);
+ }
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+ options[0] - I/O port
+ options[1] - irq
+ options[2] - a/d mux
+ 0=differential, 1=pseudodiff, 2=single
+ options[3] - a/d range
+ 0=bipolar10, 1=bipolar5, 2=unipolar10
+ options[4] - a/d coding
+ 0=2's comp, 1=straight binary
+ options[5] - dac0 range
+ 0=bipolar10, 1=unipolar10
+ options[6] - dac0 coding
+ 0=2's comp, 1=straight binary
+ options[7] - dac1 range
+ options[8] - dac1 coding
+ */
+
+static int rti800_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned int irq;
+ unsigned long iobase;
+ int ret;
+ struct comedi_subdevice *s;
+
+ iobase = it->options[0];
+ printk("comedi%d: rti800: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, RTI800_SIZE, "rti800")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+#ifdef DEBUG
+ printk("fingerprint=%x,%x,%x,%x,%x ",
+ inb(dev->iobase + 0),
+ inb(dev->iobase + 1),
+ inb(dev->iobase + 2),
+ inb(dev->iobase + 3), inb(dev->iobase + 4));
+#endif
+
+ outb(0, dev->iobase + RTI800_CSR);
+ inb(dev->iobase + RTI800_ADCHI);
+ outb(0, dev->iobase + RTI800_CLRFLAGS);
+
+ irq = it->options[1];
+ if (irq) {
+ printk("( irq = %u )", irq);
+ if ((ret = comedi_request_irq(irq, rti800_interrupt, 0,
+ "rti800", dev)) < 0) {
+ printk(" Failed to allocate IRQ\n");
+ return ret;
+ }
+ dev->irq = irq;
+ } else {
+ printk("( no irq )");
+ }
+
+ dev->board_name = this_board->name;
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct rti800_private))) < 0)
+ return ret;
+
+ devpriv->adc_mux = it->options[2];
+ devpriv->adc_range = it->options[3];
+ devpriv->adc_coding = it->options[4];
+ devpriv->dac0_range = it->options[5];
+ devpriv->dac0_coding = it->options[6];
+ devpriv->dac1_range = it->options[7];
+ devpriv->dac1_coding = it->options[8];
+ devpriv->muxgain_bits = -1;
+
+ s = dev->subdevices + 0;
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = (devpriv->adc_mux ? 16 : 8);
+ s->insn_read = rti800_ai_insn_read;
+ s->maxdata = 0xfff;
+ switch (devpriv->adc_range) {
+ case adc_bipolar10:
+ s->range_table = &range_rti800_ai_10_bipolar;
+ break;
+ case adc_bipolar5:
+ s->range_table = &range_rti800_ai_5_bipolar;
+ break;
+ case adc_unipolar10:
+ s->range_table = &range_rti800_ai_unipolar;
+ break;
+ }
+
+ s++;
+ if (this_board->has_ao) {
+ /* ao subdevice (only on rti815) */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->insn_read = rti800_ao_insn_read;
+ s->insn_write = rti800_ao_insn_write;
+ s->maxdata = 0xfff;
+ s->range_table_list = devpriv->ao_range_type_list;
+ switch (devpriv->dac0_range) {
+ case dac_bipolar10:
+ devpriv->ao_range_type_list[0] = &range_bipolar10;
+ break;
+ case dac_unipolar10:
+ devpriv->ao_range_type_list[0] = &range_unipolar10;
+ break;
+ }
+ switch (devpriv->dac1_range) {
+ case dac_bipolar10:
+ devpriv->ao_range_type_list[1] = &range_bipolar10;
+ break;
+ case dac_unipolar10:
+ devpriv->ao_range_type_list[1] = &range_unipolar10;
+ break;
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s++;
+ /* di */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 8;
+ s->insn_bits = rti800_di_insn_bits;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+
+ s++;
+ /* do */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 8;
+ s->insn_bits = rti800_do_insn_bits;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+
+/* don't yet know how to deal with counter/timers */
+#if 0
+ s++;
+ /* do */
+ s->type = COMEDI_SUBD_TIMER;
+#endif
+
+ printk("\n");
+
+ return 0;
+}
+
+static int rti800_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: rti800: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, RTI800_SIZE);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c
new file mode 100644
index 00000000000..cc2c385db0b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/rti802.c
@@ -0,0 +1,151 @@
+/*
+ comedi/drivers/rti802.c
+ Hardware driver for Analog Devices RTI-802 board
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ 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.
+
+ */
+/*
+Driver: rti802
+Description: Analog Devices RTI-802
+Author: Anders Blomdell <anders.blomdell@control.lth.se>
+Devices: [Analog Devices] RTI-802 (rti802)
+Status: works
+
+Configuration Options:
+ [0] - i/o base
+ [1] - unused
+ [2] - dac#0 0=two's comp, 1=straight
+ [3] - dac#0 0=bipolar, 1=unipolar
+ [4] - dac#1 ...
+ ...
+ [17] - dac#7 ...
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define RTI802_SIZE 4
+
+#define RTI802_SELECT 0
+#define RTI802_DATALOW 1
+#define RTI802_DATAHIGH 2
+
+static int rti802_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int rti802_detach(struct comedi_device * dev);
+static struct comedi_driver driver_rti802 = {
+ driver_name:"rti802",
+ module:THIS_MODULE,
+ attach:rti802_attach,
+ detach:rti802_detach,
+};
+
+COMEDI_INITCLEANUP(driver_rti802);
+
+struct rti802_private {
+ enum {
+ dac_2comp, dac_straight
+ } dac_coding[8];
+ const struct comedi_lrange *range_type_list[8];
+ unsigned int ao_readback[8];
+};
+
+#define devpriv ((struct rti802_private *)dev->private)
+
+static int rti802_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
+
+ return i;
+}
+
+static int rti802_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, d;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ d = devpriv->ao_readback[chan] = data[i];
+ if (devpriv->dac_coding[chan] == dac_2comp)
+ d ^= 0x800;
+ outb(chan, dev->iobase + RTI802_SELECT);
+ outb(d & 0xff, dev->iobase + RTI802_DATALOW);
+ outb(d >> 8, dev->iobase + RTI802_DATAHIGH);
+ }
+ return i;
+}
+
+static int rti802_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int i;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: rti802: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, RTI802_SIZE, "rti802")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ dev->board_name = "rti802";
+
+ if (alloc_subdevices(dev, 1) < 0
+ || alloc_private(dev, sizeof(struct rti802_private))) {
+ return -ENOMEM;
+ }
+
+ s = dev->subdevices;
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 0xfff;
+ s->n_chan = 8;
+ s->insn_read = rti802_ao_insn_read;
+ s->insn_write = rti802_ao_insn_write;
+ s->range_table_list = devpriv->range_type_list;
+
+ for (i = 0; i < 8; i++) {
+ devpriv->dac_coding[i] = (it->options[3 + 2 * i])
+ ? (dac_straight)
+ : (dac_2comp);
+ devpriv->range_type_list[i] = (it->options[2 + 2 * i])
+ ? &range_unipolar10 : &range_bipolar10;
+ }
+
+ printk("\n");
+
+ return 0;
+}
+
+static int rti802_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: rti802: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, RTI802_SIZE);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c
new file mode 100644
index 00000000000..a7b6f711afc
--- /dev/null
+++ b/drivers/staging/comedi/drivers/s526.c
@@ -0,0 +1,977 @@
+/*
+ comedi/drivers/s526.c
+ Sensoray s526 Comedi driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: s526
+Description: Sensoray 526 driver
+Devices: [Sensoray] 526 (s526)
+Author: Richie
+ Everett Wang <everett.wang@everteq.com>
+Updated: Thu, 14 Sep. 2006
+Status: experimental
+
+Encoder works
+Analog input works
+Analog output works
+PWM output works
+Commands are not supported yet.
+
+Configuration Options:
+
+comedi_config /dev/comedi0 s526 0x2C0,0x3
+
+*/
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+
+#define S526_SIZE 64
+
+#define S526_START_AI_CONV 0
+#define S526_AI_READ 0
+
+/* Ports */
+#define S526_IOSIZE 0x40
+#define S526_NUM_PORTS 27
+
+/* registers */
+#define REG_TCR 0x00
+#define REG_WDC 0x02
+#define REG_DAC 0x04
+#define REG_ADC 0x06
+#define REG_ADD 0x08
+#define REG_DIO 0x0A
+#define REG_IER 0x0C
+#define REG_ISR 0x0E
+#define REG_MSC 0x10
+#define REG_C0L 0x12
+#define REG_C0H 0x14
+#define REG_C0M 0x16
+#define REG_C0C 0x18
+#define REG_C1L 0x1A
+#define REG_C1H 0x1C
+#define REG_C1M 0x1E
+#define REG_C1C 0x20
+#define REG_C2L 0x22
+#define REG_C2H 0x24
+#define REG_C2M 0x26
+#define REG_C2C 0x28
+#define REG_C3L 0x2A
+#define REG_C3H 0x2C
+#define REG_C3M 0x2E
+#define REG_C3C 0x30
+#define REG_EED 0x32
+#define REG_EEC 0x34
+
+static const int s526_ports[] = {
+ REG_TCR,
+ REG_WDC,
+ REG_DAC,
+ REG_ADC,
+ REG_ADD,
+ REG_DIO,
+ REG_IER,
+ REG_ISR,
+ REG_MSC,
+ REG_C0L,
+ REG_C0H,
+ REG_C0M,
+ REG_C0C,
+ REG_C1L,
+ REG_C1H,
+ REG_C1M,
+ REG_C1C,
+ REG_C2L,
+ REG_C2H,
+ REG_C2M,
+ REG_C2C,
+ REG_C3L,
+ REG_C3H,
+ REG_C3M,
+ REG_C3C,
+ REG_EED,
+ REG_EEC
+};
+
+struct counter_mode_register_t {
+ unsigned short coutSource:1;
+ unsigned short coutPolarity:1;
+ unsigned short autoLoadResetRcap:3;
+ unsigned short hwCtEnableSource:2;
+ unsigned short ctEnableCtrl:2;
+ unsigned short clockSource:2;
+ unsigned short countDir:1;
+ unsigned short countDirCtrl:1;
+ unsigned short outputRegLatchCtrl:1;
+ unsigned short preloadRegSel:1;
+ unsigned short reserved:1;
+};
+
+union {
+ struct counter_mode_register_t reg;
+ unsigned short value;
+} cmReg;
+
+#define MAX_GPCT_CONFIG_DATA 6
+
+/* Different Application Classes for GPCT Subdevices */
+/* The list is not exhaustive and needs discussion! */
+enum S526_GPCT_APP_CLASS {
+ CountingAndTimeMeasurement,
+ SinglePulseGeneration,
+ PulseTrainGeneration,
+ PositionMeasurement,
+ Miscellaneous
+};
+
+/* Config struct for different GPCT subdevice Application Classes and
+ their options
+*/
+struct s526GPCTConfig {
+ enum S526_GPCT_APP_CLASS app;
+ int data[MAX_GPCT_CONFIG_DATA];
+};
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct s526_board {
+ const char *name;
+ int gpct_chans;
+ int gpct_bits;
+ int ad_chans;
+ int ad_bits;
+ int da_chans;
+ int da_bits;
+ int have_dio;
+};
+
+static const struct s526_board s526_boards[] = {
+ {
+ name: "s526",
+ gpct_chans:4,
+ gpct_bits:24,
+ ad_chans:8,
+ ad_bits: 16,
+ da_chans:4,
+ da_bits: 16,
+ have_dio:1,
+ }
+};
+
+#define ADDR_REG(reg) (dev->iobase + (reg))
+#define ADDR_CHAN_REG(reg, chan) (dev->iobase + (reg) + (chan) * 8)
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct s526_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct s526_private {
+
+ int data;
+
+ /* would be useful for a PCI device */
+ struct pci_dev *pci_dev;
+
+ /* Used for AO readback */
+ unsigned int ao_readback[2];
+
+ struct s526GPCTConfig s526_gpct_config[4];
+ unsigned short s526_ai_config;
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct s526_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int s526_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int s526_detach(struct comedi_device * dev);
+static struct comedi_driver driver_s526 = {
+ driver_name:"s526",
+ module:THIS_MODULE,
+ attach:s526_attach,
+ detach:s526_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+ /* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in s526_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+ board_name:&s526_boards[0].name,
+ offset:sizeof(struct s526_board),
+ num_names:sizeof(s526_boards) / sizeof(struct s526_board),
+};
+
+static int s526_gpct_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_gpct_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_ai_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int s526_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int iobase;
+ int i, n;
+// short value;
+// int subdev_channel = 0;
+
+ printk("comedi%d: s526: ", dev->minor);
+
+ iobase = it->options[0];
+ if (!iobase || !request_region(iobase, S526_IOSIZE, thisboard->name)) {
+ comedi_error(dev, "I/O port conflict");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ printk("iobase=0x%lx\n", dev->iobase);
+
+ /*** make it a little quieter, exw, 8/29/06
+ for (i = 0; i < S526_NUM_PORTS; i++) {
+ printk("0x%02x: 0x%04x\n", ADDR_REG(s526_ports[i]), inw(ADDR_REG(s526_ports[i])));
+ }
+ ***/
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_ptr = &s526_boards[0];
+
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct s526_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ dev->n_subdevices = 4;
+ if (alloc_subdevices(dev, dev->n_subdevices) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* GENERAL-PURPOSE COUNTER/TIME (GPCT) */
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
+ /* KG: What does SDF_LSAMPL (see multiq3.c) mean? */
+ s->n_chan = thisboard->gpct_chans;
+ s->maxdata = 0x00ffffff; /* 24 bit counter */
+ s->insn_read = s526_gpct_rinsn;
+ s->insn_config = s526_gpct_insn_config;
+ s->insn_write = s526_gpct_winsn;
+
+ /* Command are not implemented yet, however they are necessary to
+ allocate the necessary memory for the comedi_async struct (used
+ to trigger the GPCT in case of pulsegenerator function */
+ //s->do_cmd = s526_gpct_cmd;
+ //s->do_cmdtest = s526_gpct_cmdtest;
+ //s->cancel = s526_gpct_cancel;
+
+ s = dev->subdevices + 1;
+ //dev->read_subdev=s;
+ /* analog input subdevice */
+ s->type = COMEDI_SUBD_AI;
+ /* we support differential */
+ s->subdev_flags = SDF_READABLE | SDF_DIFF;
+ /* channels 0 to 7 are the regular differential inputs */
+ /* channel 8 is "reference 0" (+10V), channel 9 is "reference 1" (0V) */
+ s->n_chan = 10;
+ s->maxdata = 0xffff;
+ s->range_table = &range_bipolar10;
+ s->len_chanlist = 16; /* This is the maximum chanlist length that
+ the board can handle */
+ s->insn_read = s526_ai_rinsn;
+ s->insn_config = s526_ai_insn_config;
+
+ s = dev->subdevices + 2;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->range_table = &range_bipolar10;
+ s->insn_write = s526_ao_winsn;
+ s->insn_read = s526_ao_rinsn;
+
+ s = dev->subdevices + 3;
+ /* digital i/o subdevice */
+ if (thisboard->have_dio) {
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 2;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = s526_dio_insn_bits;
+ s->insn_config = s526_dio_insn_config;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ printk("attached\n");
+
+ return 1;
+
+#if 0
+ // Example of Counter Application
+ //One-shot (software trigger)
+ cmReg.reg.coutSource = 0; // out RCAP
+ cmReg.reg.coutPolarity = 1; // Polarity inverted
+ cmReg.reg.autoLoadResetRcap = 1; // Auto load 0:disabled, 1:enabled
+ cmReg.reg.hwCtEnableSource = 3; // NOT RCAP
+ cmReg.reg.ctEnableCtrl = 2; // Hardware
+ cmReg.reg.clockSource = 2; // Internal
+ cmReg.reg.countDir = 1; // Down
+ cmReg.reg.countDirCtrl = 1; // Software
+ cmReg.reg.outputRegLatchCtrl = 0; // latch on read
+ cmReg.reg.preloadRegSel = 0; // PR0
+ cmReg.reg.reserved = 0;
+
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+ outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Reset the counter
+ outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Load the counter from PR0
+
+ outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Reset RCAP (fires one-shot)
+
+#else
+
+ // Set Counter Mode Register
+ cmReg.reg.coutSource = 0; // out RCAP
+ cmReg.reg.coutPolarity = 0; // Polarity inverted
+ cmReg.reg.autoLoadResetRcap = 0; // Auto load disabled
+ cmReg.reg.hwCtEnableSource = 2; // NOT RCAP
+ cmReg.reg.ctEnableCtrl = 1; // 1: Software, >1 : Hardware
+ cmReg.reg.clockSource = 3; // x4
+ cmReg.reg.countDir = 0; // up
+ cmReg.reg.countDirCtrl = 0; // quadrature
+ cmReg.reg.outputRegLatchCtrl = 0; // latch on read
+ cmReg.reg.preloadRegSel = 0; // PR0
+ cmReg.reg.reserved = 0;
+
+ n = 0;
+ printk("Mode reg=0x%04x, 0x%04lx\n", cmReg.value, ADDR_CHAN_REG(REG_C0M,
+ n));
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n));
+ udelay(1000);
+ printk("Read back mode reg=0x%04x\n", inw(ADDR_CHAN_REG(REG_C0M, n)));
+
+ // Load the pre-laod register high word
+// value = (short) (0x55);
+// outw(value, ADDR_CHAN_REG(REG_C0H, n));
+
+ // Load the pre-laod register low word
+// value = (short)(0xaa55);
+// outw(value, ADDR_CHAN_REG(REG_C0L, n));
+
+ // Write the Counter Control Register
+// outw(value, ADDR_CHAN_REG(REG_C0C, 0));
+
+ // Reset the counter if it is software preload
+ if (cmReg.reg.autoLoadResetRcap == 0) {
+ outw(0x8000, ADDR_CHAN_REG(REG_C0C, n)); // Reset the counter
+ outw(0x4000, ADDR_CHAN_REG(REG_C0C, n)); // Load the counter from PR0
+ }
+
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n));
+ udelay(1000);
+ printk("Read back mode reg=0x%04x\n", inw(ADDR_CHAN_REG(REG_C0M, n)));
+
+#endif
+ printk("Current registres:\n");
+
+ for (i = 0; i < S526_NUM_PORTS; i++) {
+ printk("0x%02lx: 0x%04x\n", ADDR_REG(s526_ports[i]),
+ inw(ADDR_REG(s526_ports[i])));
+ }
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int s526_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: s526: remove\n", dev->minor);
+
+ if (dev->iobase > 0)
+ release_region(dev->iobase, S526_IOSIZE);
+
+ return 0;
+}
+
+static int s526_gpct_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i; // counts the Data
+ int counter_channel = CR_CHAN(insn->chanspec);
+ unsigned short datalow;
+ unsigned short datahigh;
+
+ // Check if (n > 0)
+ if (insn->n <= 0) {
+ printk("s526: INSN_READ: n should be > 0\n");
+ return -EINVAL;
+ }
+ // Read the low word first
+ for (i = 0; i < insn->n; i++) {
+ datalow = inw(ADDR_CHAN_REG(REG_C0L, counter_channel));
+ datahigh = inw(ADDR_CHAN_REG(REG_C0H, counter_channel));
+ data[i] = (int)(datahigh & 0x00FF);
+ data[i] = (data[i] << 16) | (datalow & 0xFFFF);
+// printk("s526 GPCT[%d]: %x(0x%04x, 0x%04x)\n", counter_channel, data[i], datahigh, datalow);
+ }
+ return i;
+}
+
+static int s526_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int subdev_channel = CR_CHAN(insn->chanspec); // Unpack chanspec
+ int i;
+ short value;
+
+// printk("s526: GPCT_INSN_CONFIG: Configuring Channel %d\n", subdev_channel);
+
+ for (i = 0; i < MAX_GPCT_CONFIG_DATA; i++) {
+ devpriv->s526_gpct_config[subdev_channel].data[i] =
+ insn->data[i];
+// printk("data[%d]=%x\n", i, insn->data[i]);
+ }
+
+ // Check what type of Counter the user requested, data[0] contains
+ // the Application type
+ switch (insn->data[0]) {
+ case INSN_CONFIG_GPCT_QUADRATURE_ENCODER:
+ /*
+ data[0]: Application Type
+ data[1]: Counter Mode Register Value
+ data[2]: Pre-load Register Value
+ data[3]: Conter Control Register
+ */
+ printk("s526: GPCT_INSN_CONFIG: Configuring Encoder\n");
+ devpriv->s526_gpct_config[subdev_channel].app =
+ PositionMeasurement;
+
+/*
+ // Example of Counter Application
+ //One-shot (software trigger)
+ cmReg.reg.coutSource = 0; // out RCAP
+ cmReg.reg.coutPolarity = 1; // Polarity inverted
+ cmReg.reg.autoLoadResetRcap = 0; // Auto load disabled
+ cmReg.reg.hwCtEnableSource = 3; // NOT RCAP
+ cmReg.reg.ctEnableCtrl = 2; // Hardware
+ cmReg.reg.clockSource = 2; // Internal
+ cmReg.reg.countDir = 1; // Down
+ cmReg.reg.countDirCtrl = 1; // Software
+ cmReg.reg.outputRegLatchCtrl = 0; // latch on read
+ cmReg.reg.preloadRegSel = 0; // PR0
+ cmReg.reg.reserved = 0;
+
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+ outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Reset the counter
+ outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Load the counter from PR0
+
+ outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Reset RCAP (fires one-shot)
+
+*/
+
+#if 1
+ // Set Counter Mode Register
+ cmReg.reg.coutSource = 0; // out RCAP
+ cmReg.reg.coutPolarity = 0; // Polarity inverted
+ cmReg.reg.autoLoadResetRcap = 0; // Auto load disabled
+ cmReg.reg.hwCtEnableSource = 2; // NOT RCAP
+ cmReg.reg.ctEnableCtrl = 1; // 1: Software, >1 : Hardware
+ cmReg.reg.clockSource = 3; // x4
+ cmReg.reg.countDir = 0; // up
+ cmReg.reg.countDirCtrl = 0; // quadrature
+ cmReg.reg.outputRegLatchCtrl = 0; // latch on read
+ cmReg.reg.preloadRegSel = 0; // PR0
+ cmReg.reg.reserved = 0;
+
+ // Set Counter Mode Register
+// printk("s526: Counter Mode register=%x\n", cmReg.value);
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ // Reset the counter if it is software preload
+ if (cmReg.reg.autoLoadResetRcap == 0) {
+ outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Reset the counter
+// outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Load the counter from PR0
+ }
+#else
+ cmReg.reg.countDirCtrl = 0; // 0 quadrature, 1 software control
+
+ // data[1] contains GPCT_X1, GPCT_X2 or GPCT_X4
+ if (insn->data[1] == GPCT_X2) {
+ cmReg.reg.clockSource = 1;
+ } else if (insn->data[1] == GPCT_X4) {
+ cmReg.reg.clockSource = 2;
+ } else {
+ cmReg.reg.clockSource = 0;
+ }
+
+ // When to take into account the indexpulse:
+ if (insn->data[2] == GPCT_IndexPhaseLowLow) {
+ } else if (insn->data[2] == GPCT_IndexPhaseLowHigh) {
+ } else if (insn->data[2] == GPCT_IndexPhaseHighLow) {
+ } else if (insn->data[2] == GPCT_IndexPhaseHighHigh) {
+ }
+ // Take into account the index pulse?
+ if (insn->data[3] == GPCT_RESET_COUNTER_ON_INDEX)
+ cmReg.reg.autoLoadResetRcap = 4; // Auto load with INDEX^
+
+ // Set Counter Mode Register
+ cmReg.value = (short) (insn->data[1] & 0xFFFF);
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ // Load the pre-laod register high word
+ value = (short) ((insn->data[2] >> 16) & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+ // Load the pre-laod register low word
+ value = (short) (insn->data[2] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ // Write the Counter Control Register
+ if (insn->data[3] != 0) {
+ value = (short) (insn->data[3] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+ }
+ // Reset the counter if it is software preload
+ if (cmReg.reg.autoLoadResetRcap == 0) {
+ outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Reset the counter
+ outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Load the counter from PR0
+ }
+#endif
+ break;
+
+ case INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR:
+ /*
+ data[0]: Application Type
+ data[1]: Counter Mode Register Value
+ data[2]: Pre-load Register 0 Value
+ data[3]: Pre-load Register 1 Value
+ data[4]: Conter Control Register
+ */
+ printk("s526: GPCT_INSN_CONFIG: Configuring SPG\n");
+ devpriv->s526_gpct_config[subdev_channel].app =
+ SinglePulseGeneration;
+
+ // Set Counter Mode Register
+ cmReg.value = (short) (insn->data[1] & 0xFFFF);
+ cmReg.reg.preloadRegSel = 0; // PR0
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ // Load the pre-laod register 0 high word
+ value = (short) ((insn->data[2] >> 16) & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+ // Load the pre-laod register 0 low word
+ value = (short) (insn->data[2] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ // Set Counter Mode Register
+ cmReg.value = (short) (insn->data[1] & 0xFFFF);
+ cmReg.reg.preloadRegSel = 1; // PR1
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ // Load the pre-laod register 1 high word
+ value = (short) ((insn->data[3] >> 16) & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+ // Load the pre-laod register 1 low word
+ value = (short) (insn->data[3] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ // Write the Counter Control Register
+ if (insn->data[3] != 0) {
+ value = (short) (insn->data[3] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+ }
+ break;
+
+ case INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR:
+ /*
+ data[0]: Application Type
+ data[1]: Counter Mode Register Value
+ data[2]: Pre-load Register 0 Value
+ data[3]: Pre-load Register 1 Value
+ data[4]: Conter Control Register
+ */
+ printk("s526: GPCT_INSN_CONFIG: Configuring PTG\n");
+ devpriv->s526_gpct_config[subdev_channel].app =
+ PulseTrainGeneration;
+
+ // Set Counter Mode Register
+ cmReg.value = (short) (insn->data[1] & 0xFFFF);
+ cmReg.reg.preloadRegSel = 0; // PR0
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ // Load the pre-laod register 0 high word
+ value = (short) ((insn->data[2] >> 16) & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+ // Load the pre-laod register 0 low word
+ value = (short) (insn->data[2] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ // Set Counter Mode Register
+ cmReg.value = (short) (insn->data[1] & 0xFFFF);
+ cmReg.reg.preloadRegSel = 1; // PR1
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ // Load the pre-laod register 1 high word
+ value = (short) ((insn->data[3] >> 16) & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+ // Load the pre-laod register 1 low word
+ value = (short) (insn->data[3] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ // Write the Counter Control Register
+ if (insn->data[3] != 0) {
+ value = (short) (insn->data[3] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+ }
+ break;
+
+ default:
+ printk("s526: unsupported GPCT_insn_config\n");
+ return -EINVAL;
+ break;
+ }
+
+ return insn->n;
+}
+
+static int s526_gpct_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int subdev_channel = CR_CHAN(insn->chanspec); // Unpack chanspec
+ short value;
+
+ printk("s526: GPCT_INSN_WRITE on channel %d\n", subdev_channel);
+ cmReg.value = inw(ADDR_CHAN_REG(REG_C0M, subdev_channel));
+ printk("s526: Counter Mode Register: %x\n", cmReg.value);
+ // Check what Application of Counter this channel is configured for
+ switch (devpriv->s526_gpct_config[subdev_channel].app) {
+ case PositionMeasurement:
+ printk("S526: INSN_WRITE: PM\n");
+ outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H,
+ subdev_channel));
+ outw(0xFFFF & (*data), ADDR_CHAN_REG(REG_C0L, subdev_channel));
+ break;
+
+ case SinglePulseGeneration:
+ printk("S526: INSN_WRITE: SPG\n");
+ outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H,
+ subdev_channel));
+ outw(0xFFFF & (*data), ADDR_CHAN_REG(REG_C0L, subdev_channel));
+ break;
+
+ case PulseTrainGeneration:
+ /* data[0] contains the PULSE_WIDTH
+ data[1] contains the PULSE_PERIOD
+ @pre PULSE_PERIOD > PULSE_WIDTH > 0
+ The above periods must be expressed as a multiple of the
+ pulse frequency on the selected source
+ */
+ printk("S526: INSN_WRITE: PTG\n");
+ if ((insn->data[1] > insn->data[0]) && (insn->data[0] > 0)) {
+ (devpriv->s526_gpct_config[subdev_channel]).data[0] =
+ insn->data[0];
+ (devpriv->s526_gpct_config[subdev_channel]).data[1] =
+ insn->data[1];
+ } else {
+ printk("%d \t %d\n", insn->data[1], insn->data[2]);
+ printk("s526: INSN_WRITE: PTG: Problem with Pulse params\n");
+ return -EINVAL;
+ }
+
+ value = (short) ((*data >> 16) & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+ value = (short) (*data & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+ break;
+ default: // Impossible
+ printk("s526: INSN_WRITE: Functionality %d not implemented yet\n", devpriv->s526_gpct_config[subdev_channel].app);
+ return -EINVAL;
+ break;
+ }
+ // return the number of samples written
+ return insn->n;
+}
+
+#define ISR_ADC_DONE 0x4
+static int s526_ai_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int result = -EINVAL;
+
+ if (insn->n < 1)
+ return result;
+
+ result = insn->n;
+
+ /* data[0] : channels was set in relevant bits.
+ data[1] : delay
+ */
+ /* COMMENT: abbotti 2008-07-24: I don't know why you'd want to
+ * enable channels here. The channel should be enabled in the
+ * INSN_READ handler. */
+
+ // Enable ADC interrupt
+ outw(ISR_ADC_DONE, ADDR_REG(REG_IER));
+// printk("s526: ADC current value: 0x%04x\n", inw(ADDR_REG(REG_ADC)));
+ devpriv->s526_ai_config = (data[0] & 0x3FF) << 5;
+ if (data[1] > 0)
+ devpriv->s526_ai_config |= 0x8000; //set the delay
+
+ devpriv->s526_ai_config |= 0x0001; // ADC start bit.
+
+ return result;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int s526_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned short value;
+ unsigned int d;
+ unsigned int status;
+
+ /* Set configured delay, enable channel for this channel only,
+ * select "ADC read" channel, set "ADC start" bit. */
+ value = (devpriv->s526_ai_config & 0x8000) |
+ ((1 << 5) << chan) | (chan << 1) | 0x0001;
+
+ /* convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ outw(value, ADDR_REG(REG_ADC));
+// printk("s526: Wrote 0x%04x to ADC\n", value);
+// printk("s526: ADC reg=0x%04x\n", inw(ADDR_REG(REG_ADC)));
+
+#define TIMEOUT 100
+ /* wait for conversion to end */
+ for (i = 0; i < TIMEOUT; i++) {
+ status = inw(ADDR_REG(REG_ISR));
+ if (status & ISR_ADC_DONE) {
+ outw(ISR_ADC_DONE, ADDR_REG(REG_ISR));
+ break;
+ }
+ }
+ if (i == TIMEOUT) {
+ /* rt_printk() should be used instead of printk()
+ * whenever the code can be called from real-time. */
+ rt_printk("s526: ADC(0x%04x) timeout\n",
+ inw(ADDR_REG(REG_ISR)));
+ return -ETIMEDOUT;
+ }
+
+ /* read data */
+ d = inw(ADDR_REG(REG_ADD));
+// printk("AI[%d]=0x%04x\n", n, (unsigned short)(d & 0xFFFF));
+
+ /* munge data */
+ data[n] = d ^ 0x8000;
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+static int s526_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned short val;
+
+// printk("s526_ao_winsn\n");
+ val = chan << 1;
+// outw(val, dev->iobase + REG_DAC);
+ outw(val, ADDR_REG(REG_DAC));
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ /* a typical programming sequence */
+// outw(data[i], dev->iobase + REG_ADD); // write the data to preload register
+ outw(data[i], ADDR_REG(REG_ADD)); // write the data to preload register
+ devpriv->ao_readback[chan] = data[i];
+// outw(val + 1, dev->iobase + REG_DAC); // starts the D/A conversion.
+ outw(val + 1, ADDR_REG(REG_DAC)); // starts the D/A conversion.
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int s526_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int s526_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ /* Write out the new digital output lines */
+ outw(s->state, ADDR_REG(REG_DIO));
+ }
+
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ data[1] = inw(ADDR_REG(REG_DIO)) & 0xFF; // low 8 bits are the data
+ /* or we could just return the software copy of the output values if
+ * it was a purely digital output subdevice */
+ //data[1]=s->state;
+
+ return 2;
+}
+
+static int s526_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ short value;
+
+ printk("S526 DIO insn_config\n");
+
+ if (insn->n != 1)
+ return -EINVAL;
+
+ value = inw(ADDR_REG(REG_DIO));
+
+ /* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+ if (data[0] == COMEDI_OUTPUT) {
+ value |= 1 << (chan + 10); // bit 10/11 set the group 1/2's mode
+ s->io_bits |= (0xF << chan);
+ } else {
+ value &= ~(1 << (chan + 10)); // 1 is output, 0 is input.
+ s->io_bits &= ~(0xF << chan);
+ }
+ outw(value, ADDR_REG(REG_DIO));
+
+ return 1;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_s526);
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index 469ee8c474c..30dec9dab19 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -82,7 +82,7 @@ MODULE_AUTHOR("Gianluca Palli <gpalli@deis.unibo.it>");
MODULE_DESCRIPTION("Sensoray 626 Comedi driver module");
MODULE_LICENSE("GPL");
-typedef struct s626_board_struct {
+struct s626_board {
const char *name;
int ai_chans;
int ai_bits;
@@ -91,22 +91,22 @@ typedef struct s626_board_struct {
int dio_chans;
int dio_banks;
int enc_chans;
-} s626_board;
+};
-static const s626_board s626_boards[] = {
+static const struct s626_board s626_boards[] = {
{
name: "s626",
- ai_chans:S626_ADC_CHANNELS,
+ ai_chans : S626_ADC_CHANNELS,
ai_bits: 14,
- ao_chans:S626_DAC_CHANNELS,
+ ao_chans : S626_DAC_CHANNELS,
ao_bits: 13,
- dio_chans:S626_DIO_CHANNELS,
- dio_banks:S626_DIO_BANKS,
- enc_chans:S626_ENCODER_CHANNELS,
+ dio_chans : S626_DIO_CHANNELS,
+ dio_banks : S626_DIO_BANKS,
+ enc_chans : S626_ENCODER_CHANNELS,
}
};
-#define thisboard ((const s626_board *)dev->board_ptr)
+#define thisboard ((const struct s626_board *)dev->board_ptr)
#define PCI_VENDOR_ID_S626 0x1131
#define PCI_DEVICE_ID_S626 0x7146
@@ -118,57 +118,49 @@ static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = {
MODULE_DEVICE_TABLE(pci, s626_pci_table);
-static int s626_attach(comedi_device * dev, comedi_devconfig * it);
-static int s626_detach(comedi_device * dev);
+static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int s626_detach(struct comedi_device *dev);
-static comedi_driver driver_s626 = {
+static struct comedi_driver driver_s626 = {
driver_name:"s626",
- module:THIS_MODULE,
- attach:s626_attach,
- detach:s626_detach,
+ module : THIS_MODULE,
+ attach : s626_attach,
+ detach : s626_detach,
};
-typedef struct {
+struct s626_private {
struct pci_dev *pdev;
void *base_addr;
int got_regions;
short allocatedBuf;
- uint8_t ai_cmd_running; // ai_cmd is running
- uint8_t ai_continous; // continous aquisition
- int ai_sample_count; // number of samples to aquire
- unsigned int ai_sample_timer; // time between samples in
- // units of the timer
- int ai_convert_count; // conversion counter
- unsigned int ai_convert_timer; // time between conversion in
- // units of the timer
- uint16_t CounterIntEnabs; //Counter interrupt enable
- //mask for MISC2 register.
- uint8_t AdcItems; //Number of items in ADC poll
- //list.
- DMABUF RPSBuf; //DMA buffer used to hold ADC
- //(RPS1) program.
- DMABUF ANABuf; //DMA buffer used to receive
- //ADC data and hold DAC data.
- uint32_t *pDacWBuf; //Pointer to logical adrs of
- //DMA buffer used to hold DAC
- //data.
- uint16_t Dacpol; //Image of DAC polarity
- //register.
- uint8_t TrimSetpoint[12]; //Images of TrimDAC setpoints.
- //registers.
- uint16_t ChargeEnabled; //Image of MISC2 Battery
- //Charge Enabled (0 or
- //WRMISC2_CHARGE_ENABLE).
- uint16_t WDInterval; //Image of MISC2 watchdog
- //interval control bits.
- uint32_t I2CAdrs; //I2C device address for
- //onboard EEPROM (board rev
- //dependent).
- // short I2Cards;
- lsampl_t ao_readback[S626_DAC_CHANNELS];
-} s626_private;
-
-typedef struct {
+ uint8_t ai_cmd_running; /* ai_cmd is running */
+ uint8_t ai_continous; /* continous aquisition */
+ int ai_sample_count; /* number of samples to aquire */
+ unsigned int ai_sample_timer;
+ /* time between samples in units of the timer */
+ int ai_convert_count; /* conversion counter */
+ unsigned int ai_convert_timer;
+ /* time between conversion in units of the timer */
+ uint16_t CounterIntEnabs;
+ /* Counter interrupt enable mask for MISC2 register. */
+ uint8_t AdcItems; /* Number of items in ADC poll list. */
+ struct bufferDMA RPSBuf; /* DMA buffer used to hold ADC (RPS1) program. */
+ struct bufferDMA ANABuf;
+ /* DMA buffer used to receive ADC data and hold DAC data. */
+ uint32_t *pDacWBuf;
+ /* Pointer to logical adrs of DMA buffer used to hold DAC data. */
+ uint16_t Dacpol; /* Image of DAC polarity register. */
+ uint8_t TrimSetpoint[12]; /* Images of TrimDAC setpoints */
+ uint16_t ChargeEnabled; /* Image of MISC2 Battery */
+ /* Charge Enabled (0 or WRMISC2_CHARGE_ENABLE). */
+ uint16_t WDInterval; /* Image of MISC2 watchdog interval control bits. */
+ uint32_t I2CAdrs;
+ /* I2C device address for onboard EEPROM (board rev dependent). */
+ /* short I2Cards; */
+ unsigned int ao_readback[S626_DAC_CHANNELS];
+};
+
+struct dio_private {
uint16_t RDDIn;
uint16_t WRDOut;
uint16_t RDEdgSel;
@@ -178,324 +170,322 @@ typedef struct {
uint16_t RDCapFlg;
uint16_t RDIntSel;
uint16_t WRIntSel;
-} dio_private;
+};
-static dio_private dio_private_A = {
+static struct dio_private dio_private_A = {
RDDIn:LP_RDDINA,
- WRDOut:LP_WRDOUTA,
- RDEdgSel:LP_RDEDGSELA,
- WREdgSel:LP_WREDGSELA,
- RDCapSel:LP_RDCAPSELA,
- WRCapSel:LP_WRCAPSELA,
- RDCapFlg:LP_RDCAPFLGA,
- RDIntSel:LP_RDINTSELA,
- WRIntSel:LP_WRINTSELA,
+ WRDOut : LP_WRDOUTA,
+ RDEdgSel : LP_RDEDGSELA,
+ WREdgSel : LP_WREDGSELA,
+ RDCapSel : LP_RDCAPSELA,
+ WRCapSel : LP_WRCAPSELA,
+ RDCapFlg : LP_RDCAPFLGA,
+ RDIntSel : LP_RDINTSELA,
+ WRIntSel : LP_WRINTSELA,
};
-static dio_private dio_private_B = {
+static struct dio_private dio_private_B = {
RDDIn:LP_RDDINB,
- WRDOut:LP_WRDOUTB,
- RDEdgSel:LP_RDEDGSELB,
- WREdgSel:LP_WREDGSELB,
- RDCapSel:LP_RDCAPSELB,
- WRCapSel:LP_WRCAPSELB,
- RDCapFlg:LP_RDCAPFLGB,
- RDIntSel:LP_RDINTSELB,
- WRIntSel:LP_WRINTSELB,
+ WRDOut : LP_WRDOUTB,
+ RDEdgSel : LP_RDEDGSELB,
+ WREdgSel : LP_WREDGSELB,
+ RDCapSel : LP_RDCAPSELB,
+ WRCapSel : LP_WRCAPSELB,
+ RDCapFlg : LP_RDCAPFLGB,
+ RDIntSel : LP_RDINTSELB,
+ WRIntSel : LP_WRINTSELB,
};
-static dio_private dio_private_C = {
+static struct dio_private dio_private_C = {
RDDIn:LP_RDDINC,
- WRDOut:LP_WRDOUTC,
- RDEdgSel:LP_RDEDGSELC,
- WREdgSel:LP_WREDGSELC,
- RDCapSel:LP_RDCAPSELC,
- WRCapSel:LP_WRCAPSELC,
- RDCapFlg:LP_RDCAPFLGC,
- RDIntSel:LP_RDINTSELC,
- WRIntSel:LP_WRINTSELC,
+ WRDOut : LP_WRDOUTC,
+ RDEdgSel : LP_RDEDGSELC,
+ WREdgSel : LP_WREDGSELC,
+ RDCapSel : LP_RDCAPSELC,
+ WRCapSel : LP_WRCAPSELC,
+ RDCapFlg : LP_RDCAPFLGC,
+ RDIntSel : LP_RDINTSELC,
+ WRIntSel : LP_WRINTSELC,
};
/* to group dio devices (48 bits mask and data are not allowed ???)
-static dio_private *dio_private_word[]={
+static struct dio_private *dio_private_word[]={
&dio_private_A,
&dio_private_B,
&dio_private_C,
};
*/
-#define devpriv ((s626_private *)dev->private)
-#define diopriv ((dio_private *)s->private)
+#define devpriv ((struct s626_private *)dev->private)
+#define diopriv ((struct dio_private *)s->private)
COMEDI_PCI_INITCLEANUP_NOMODULE(driver_s626, s626_pci_table);
-//ioctl routines
-static int s626_ai_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-/* static int s626_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data); */
-static int s626_ai_insn_read(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s);
-static int s626_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,
- comedi_cmd * cmd);
-static int s626_ai_cancel(comedi_device * dev, comedi_subdevice * s);
-static int s626_ao_winsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_ao_rinsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_dio_insn_bits(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_dio_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_dio_set_irq(comedi_device * dev, unsigned int chan);
-static int s626_dio_reset_irq(comedi_device * dev, unsigned int gruop,
+/* ioctl routines */
+static int s626_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+/* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data); */
+static int s626_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
+static int s626_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd);
+static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
+static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan);
+static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int gruop,
unsigned int mask);
-static int s626_dio_clear_irq(comedi_device * dev);
-static int s626_enc_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_enc_insn_read(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_enc_insn_write(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
+static int s626_dio_clear_irq(struct comedi_device *dev);
+static int s626_enc_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_enc_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_enc_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
static int s626_ns_to_timer(int *nanosec, int round_mode);
-static int s626_ai_load_polllist(uint8_t * ppl, comedi_cmd * cmd);
-static int s626_ai_inttrig(comedi_device * dev, comedi_subdevice * s,
+static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd);
+static int s626_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trignum);
static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG);
-static lsampl_t s626_ai_reg_to_uint(int data);
-/* static lsampl_t s626_uint_to_reg(comedi_subdevice *s, int data); */
+static unsigned int s626_ai_reg_to_uint(int data);
+/* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data); */
-//end ioctl routines
+/* end ioctl routines */
-//internal routines
-static void s626_dio_init(comedi_device * dev);
-static void ResetADC(comedi_device * dev, uint8_t * ppl);
-static void LoadTrimDACs(comedi_device * dev);
-static void WriteTrimDAC(comedi_device * dev, uint8_t LogicalChan,
+/* internal routines */
+static void s626_dio_init(struct comedi_device *dev);
+static void ResetADC(struct comedi_device *dev, uint8_t *ppl);
+static void LoadTrimDACs(struct comedi_device *dev);
+static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
uint8_t DacData);
-static uint8_t I2Cread(comedi_device * dev, uint8_t addr);
-static uint32_t I2Chandshake(comedi_device * dev, uint32_t val);
-static void SetDAC(comedi_device * dev, uint16_t chan, short dacdata);
-static void SendDAC(comedi_device * dev, uint32_t val);
-static void WriteMISC2(comedi_device * dev, uint16_t NewImage);
-static void DEBItransfer(comedi_device * dev);
-static uint16_t DEBIread(comedi_device * dev, uint16_t addr);
-static void DEBIwrite(comedi_device * dev, uint16_t addr, uint16_t wdata);
-static void DEBIreplace(comedi_device * dev, uint16_t addr, uint16_t mask,
+static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr);
+static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val);
+static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata);
+static void SendDAC(struct comedi_device *dev, uint32_t val);
+static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage);
+static void DEBItransfer(struct comedi_device *dev);
+static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr);
+static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata);
+static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
uint16_t wdata);
-static void CloseDMAB(comedi_device * dev, DMABUF * pdma, size_t bsize);
-
-// COUNTER OBJECT ------------------------------------------------
-typedef struct enc_private_struct {
- // Pointers to functions that differ for A and B counters:
- uint16_t(*GetEnable) (comedi_device * dev, struct enc_private_struct *); //Return clock enable.
- uint16_t(*GetIntSrc) (comedi_device * dev, struct enc_private_struct *); //Return interrupt source.
- uint16_t(*GetLoadTrig) (comedi_device * dev, struct enc_private_struct *); //Return preload trigger source.
- uint16_t(*GetMode) (comedi_device * dev, struct enc_private_struct *); //Return standardized operating mode.
- void (*PulseIndex) (comedi_device * dev, struct enc_private_struct *); //Generate soft index strobe.
- void (*SetEnable) (comedi_device * dev, struct enc_private_struct *, uint16_t enab); //Program clock enable.
- void (*SetIntSrc) (comedi_device * dev, struct enc_private_struct *, uint16_t IntSource); //Program interrupt source.
- void (*SetLoadTrig) (comedi_device * dev, struct enc_private_struct *, uint16_t Trig); //Program preload trigger source.
- void (*SetMode) (comedi_device * dev, struct enc_private_struct *, uint16_t Setup, uint16_t DisableIntSrc); //Program standardized operating mode.
- void (*ResetCapFlags) (comedi_device * dev, struct enc_private_struct *); //Reset event capture flags.
-
- uint16_t MyCRA; // Address of CRA register.
- uint16_t MyCRB; // Address of CRB register.
- uint16_t MyLatchLsw; // Address of Latch least-significant-word
- // register.
- uint16_t MyEventBits[4]; // Bit translations for IntSrc -->RDMISC2.
-} enc_private; //counter object
-
-#define encpriv ((enc_private *)(dev->subdevices+5)->private)
-
-//counters routines
-static void s626_timer_load(comedi_device * dev, enc_private * k, int tick);
-static uint32_t ReadLatch(comedi_device * dev, enc_private * k);
-static void ResetCapFlags_A(comedi_device * dev, enc_private * k);
-static void ResetCapFlags_B(comedi_device * dev, enc_private * k);
-static uint16_t GetMode_A(comedi_device * dev, enc_private * k);
-static uint16_t GetMode_B(comedi_device * dev, enc_private * k);
-static void SetMode_A(comedi_device * dev, enc_private * k, uint16_t Setup,
+static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, size_t bsize);
+
+/* COUNTER OBJECT ------------------------------------------------ */
+struct enc_private {
+ /* Pointers to functions that differ for A and B counters: */
+ uint16_t(*GetEnable) (struct comedi_device *dev, struct enc_private *); /* Return clock enable. */
+ uint16_t(*GetIntSrc) (struct comedi_device *dev, struct enc_private *); /* Return interrupt source. */
+ uint16_t(*GetLoadTrig) (struct comedi_device *dev, struct enc_private *); /* Return preload trigger source. */
+ uint16_t(*GetMode) (struct comedi_device *dev, struct enc_private *); /* Return standardized operating mode. */
+ void (*PulseIndex) (struct comedi_device *dev, struct enc_private *); /* Generate soft index strobe. */
+ void (*SetEnable) (struct comedi_device *dev, struct enc_private *, uint16_t enab); /* Program clock enable. */
+ void (*SetIntSrc) (struct comedi_device *dev, struct enc_private *, uint16_t IntSource); /* Program interrupt source. */
+ void (*SetLoadTrig) (struct comedi_device *dev, struct enc_private *, uint16_t Trig); /* Program preload trigger source. */
+ void (*SetMode) (struct comedi_device *dev, struct enc_private *, uint16_t Setup, uint16_t DisableIntSrc); /* Program standardized operating mode. */
+ void (*ResetCapFlags) (struct comedi_device *dev, struct enc_private *); /* Reset event capture flags. */
+
+ uint16_t MyCRA; /* Address of CRA register. */
+ uint16_t MyCRB; /* Address of CRB register. */
+ uint16_t MyLatchLsw; /* Address of Latch least-significant-word */
+ /* register. */
+ uint16_t MyEventBits[4]; /* Bit translations for IntSrc -->RDMISC2. */
+};
+
+#define encpriv ((struct enc_private *)(dev->subdevices+5)->private)
+
+/* counters routines */
+static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, int tick);
+static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k);
+static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k);
+static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k);
+static void SetMode_A(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
uint16_t DisableIntSrc);
-static void SetMode_B(comedi_device * dev, enc_private * k, uint16_t Setup,
+static void SetMode_B(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
uint16_t DisableIntSrc);
-static void SetEnable_A(comedi_device * dev, enc_private * k, uint16_t enab);
-static void SetEnable_B(comedi_device * dev, enc_private * k, uint16_t enab);
-static uint16_t GetEnable_A(comedi_device * dev, enc_private * k);
-static uint16_t GetEnable_B(comedi_device * dev, enc_private * k);
-static void SetLatchSource(comedi_device * dev, enc_private * k,
+static void SetEnable_A(struct comedi_device *dev, struct enc_private *k, uint16_t enab);
+static void SetEnable_B(struct comedi_device *dev, struct enc_private *k, uint16_t enab);
+static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k);
+static void SetLatchSource(struct comedi_device *dev, struct enc_private *k,
uint16_t value);
-/* static uint16_t GetLatchSource(comedi_device *dev, enc_private *k ); */
-static void SetLoadTrig_A(comedi_device * dev, enc_private * k, uint16_t Trig);
-static void SetLoadTrig_B(comedi_device * dev, enc_private * k, uint16_t Trig);
-static uint16_t GetLoadTrig_A(comedi_device * dev, enc_private * k);
-static uint16_t GetLoadTrig_B(comedi_device * dev, enc_private * k);
-static void SetIntSrc_B(comedi_device * dev, enc_private * k,
+/* static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k ); */
+static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k, uint16_t Trig);
+static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k, uint16_t Trig);
+static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k);
+static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
uint16_t IntSource);
-static void SetIntSrc_A(comedi_device * dev, enc_private * k,
+static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
uint16_t IntSource);
-static uint16_t GetIntSrc_A(comedi_device * dev, enc_private * k);
-static uint16_t GetIntSrc_B(comedi_device * dev, enc_private * k);
-/* static void SetClkMult(comedi_device *dev, enc_private *k, uint16_t value ) ; */
-/* static uint16_t GetClkMult(comedi_device *dev, enc_private *k ) ; */
-/* static void SetIndexPol(comedi_device *dev, enc_private *k, uint16_t value ); */
-/* static uint16_t GetClkPol(comedi_device *dev, enc_private *k ) ; */
-/* static void SetIndexSrc( comedi_device *dev,enc_private *k, uint16_t value ); */
-/* static uint16_t GetClkSrc( comedi_device *dev,enc_private *k ); */
-/* static void SetIndexSrc( comedi_device *dev,enc_private *k, uint16_t value ); */
-/* static uint16_t GetIndexSrc( comedi_device *dev,enc_private *k ); */
-static void PulseIndex_A(comedi_device * dev, enc_private * k);
-static void PulseIndex_B(comedi_device * dev, enc_private * k);
-static void Preload(comedi_device * dev, enc_private * k, uint32_t value);
-static void CountersInit(comedi_device * dev);
-//end internal routines
-
-/////////////////////////////////////////////////////////////////////////
-// Counter objects constructor.
-
-// Counter overflow/index event flag masks for RDMISC2.
-#define INDXMASK(C) ( 1 << ( ( (C) > 2 ) ? ( (C) * 2 - 1 ) : ( (C) * 2 + 4 ) ) )
-#define OVERMASK(C) ( 1 << ( ( (C) > 2 ) ? ( (C) * 2 + 5 ) : ( (C) * 2 + 10 ) ) )
+static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k);
+/* static void SetClkMult(struct comedi_device *dev, struct enc_private *k, uint16_t value ) ; */
+/* static uint16_t GetClkMult(struct comedi_device *dev, struct enc_private *k ) ; */
+/* static void SetIndexPol(struct comedi_device *dev, struct enc_private *k, uint16_t value ); */
+/* static uint16_t GetClkPol(struct comedi_device *dev, struct enc_private *k ) ; */
+/* static void SetIndexSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value ); */
+/* static uint16_t GetClkSrc( struct comedi_device *dev,struct enc_private *k ); */
+/* static void SetIndexSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value ); */
+/* static uint16_t GetIndexSrc( struct comedi_device *dev,struct enc_private *k ); */
+static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k);
+static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k);
+static void Preload(struct comedi_device *dev, struct enc_private *k, uint32_t value);
+static void CountersInit(struct comedi_device *dev);
+/* end internal routines */
+
+/* Counter objects constructor. */
+
+/* Counter overflow/index event flag masks for RDMISC2. */
+#define INDXMASK(C) (1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 + 4)))
+#define OVERMASK(C) (1 << (((C) > 2) ? ((C) * 2 + 5) : ((C) * 2 + 10)))
#define EVBITS(C) { 0, OVERMASK(C), INDXMASK(C), OVERMASK(C) | INDXMASK(C) }
-// Translation table to map IntSrc into equivalent RDMISC2 event flag
-// bits.
-//static const uint16_t EventBits[][4] = { EVBITS(0), EVBITS(1), EVBITS(2), EVBITS(3), EVBITS(4), EVBITS(5) };
+/* Translation table to map IntSrc into equivalent RDMISC2 event flag bits. */
+/* static const uint16_t EventBits[][4] = { EVBITS(0), EVBITS(1), EVBITS(2), EVBITS(3), EVBITS(4), EVBITS(5) }; */
-/* enc_private; */
-static enc_private enc_private_data[] = {
+/* struct enc_private; */
+static struct enc_private enc_private_data[] = {
{
GetEnable:GetEnable_A,
- GetIntSrc:GetIntSrc_A,
- GetLoadTrig:GetLoadTrig_A,
- GetMode: GetMode_A,
- PulseIndex:PulseIndex_A,
- SetEnable:SetEnable_A,
- SetIntSrc:SetIntSrc_A,
- SetLoadTrig:SetLoadTrig_A,
- SetMode: SetMode_A,
- ResetCapFlags:ResetCapFlags_A,
- MyCRA: LP_CR0A,
- MyCRB: LP_CR0B,
- MyLatchLsw:LP_CNTR0ALSW,
- MyEventBits:EVBITS(0),
+ GetIntSrc : GetIntSrc_A,
+ GetLoadTrig : GetLoadTrig_A,
+ GetMode : GetMode_A,
+ PulseIndex : PulseIndex_A,
+ SetEnable : SetEnable_A,
+ SetIntSrc : SetIntSrc_A,
+ SetLoadTrig : SetLoadTrig_A,
+ SetMode : SetMode_A,
+ ResetCapFlags : ResetCapFlags_A,
+ MyCRA : LP_CR0A,
+ MyCRB : LP_CR0B,
+ MyLatchLsw : LP_CNTR0ALSW,
+ MyEventBits : EVBITS(0),
},
{
GetEnable:GetEnable_A,
- GetIntSrc:GetIntSrc_A,
- GetLoadTrig:GetLoadTrig_A,
- GetMode: GetMode_A,
- PulseIndex:PulseIndex_A,
- SetEnable:SetEnable_A,
- SetIntSrc:SetIntSrc_A,
- SetLoadTrig:SetLoadTrig_A,
- SetMode: SetMode_A,
- ResetCapFlags:ResetCapFlags_A,
- MyCRA: LP_CR1A,
- MyCRB: LP_CR1B,
- MyLatchLsw:LP_CNTR1ALSW,
- MyEventBits:EVBITS(1),
+ GetIntSrc : GetIntSrc_A,
+ GetLoadTrig : GetLoadTrig_A,
+ GetMode : GetMode_A,
+ PulseIndex : PulseIndex_A,
+ SetEnable : SetEnable_A,
+ SetIntSrc : SetIntSrc_A,
+ SetLoadTrig : SetLoadTrig_A,
+ SetMode : SetMode_A,
+ ResetCapFlags : ResetCapFlags_A,
+ MyCRA : LP_CR1A,
+ MyCRB : LP_CR1B,
+ MyLatchLsw : LP_CNTR1ALSW,
+ MyEventBits : EVBITS(1),
},
{
GetEnable:GetEnable_A,
- GetIntSrc:GetIntSrc_A,
- GetLoadTrig:GetLoadTrig_A,
- GetMode: GetMode_A,
- PulseIndex:PulseIndex_A,
- SetEnable:SetEnable_A,
- SetIntSrc:SetIntSrc_A,
- SetLoadTrig:SetLoadTrig_A,
- SetMode: SetMode_A,
- ResetCapFlags:ResetCapFlags_A,
- MyCRA: LP_CR2A,
- MyCRB: LP_CR2B,
- MyLatchLsw:LP_CNTR2ALSW,
- MyEventBits:EVBITS(2),
+ GetIntSrc : GetIntSrc_A,
+ GetLoadTrig : GetLoadTrig_A,
+ GetMode : GetMode_A,
+ PulseIndex : PulseIndex_A,
+ SetEnable : SetEnable_A,
+ SetIntSrc : SetIntSrc_A,
+ SetLoadTrig : SetLoadTrig_A,
+ SetMode : SetMode_A,
+ ResetCapFlags : ResetCapFlags_A,
+ MyCRA : LP_CR2A,
+ MyCRB : LP_CR2B,
+ MyLatchLsw : LP_CNTR2ALSW,
+ MyEventBits : EVBITS(2),
},
{
GetEnable:GetEnable_B,
- GetIntSrc:GetIntSrc_B,
- GetLoadTrig:GetLoadTrig_B,
- GetMode: GetMode_B,
- PulseIndex:PulseIndex_B,
- SetEnable:SetEnable_B,
- SetIntSrc:SetIntSrc_B,
- SetLoadTrig:SetLoadTrig_B,
- SetMode: SetMode_B,
- ResetCapFlags:ResetCapFlags_B,
- MyCRA: LP_CR0A,
- MyCRB: LP_CR0B,
- MyLatchLsw:LP_CNTR0BLSW,
- MyEventBits:EVBITS(3),
+ GetIntSrc : GetIntSrc_B,
+ GetLoadTrig : GetLoadTrig_B,
+ GetMode : GetMode_B,
+ PulseIndex : PulseIndex_B,
+ SetEnable : SetEnable_B,
+ SetIntSrc : SetIntSrc_B,
+ SetLoadTrig : SetLoadTrig_B,
+ SetMode : SetMode_B,
+ ResetCapFlags : ResetCapFlags_B,
+ MyCRA : LP_CR0A,
+ MyCRB : LP_CR0B,
+ MyLatchLsw : LP_CNTR0BLSW,
+ MyEventBits : EVBITS(3),
},
{
GetEnable:GetEnable_B,
- GetIntSrc:GetIntSrc_B,
- GetLoadTrig:GetLoadTrig_B,
- GetMode: GetMode_B,
- PulseIndex:PulseIndex_B,
- SetEnable:SetEnable_B,
- SetIntSrc:SetIntSrc_B,
- SetLoadTrig:SetLoadTrig_B,
- SetMode: SetMode_B,
- ResetCapFlags:ResetCapFlags_B,
- MyCRA: LP_CR1A,
- MyCRB: LP_CR1B,
- MyLatchLsw:LP_CNTR1BLSW,
- MyEventBits:EVBITS(4),
+ GetIntSrc : GetIntSrc_B,
+ GetLoadTrig : GetLoadTrig_B,
+ GetMode : GetMode_B,
+ PulseIndex : PulseIndex_B,
+ SetEnable : SetEnable_B,
+ SetIntSrc : SetIntSrc_B,
+ SetLoadTrig : SetLoadTrig_B,
+ SetMode : SetMode_B,
+ ResetCapFlags : ResetCapFlags_B,
+ MyCRA : LP_CR1A,
+ MyCRB : LP_CR1B,
+ MyLatchLsw : LP_CNTR1BLSW,
+ MyEventBits : EVBITS(4),
},
{
GetEnable:GetEnable_B,
- GetIntSrc:GetIntSrc_B,
- GetLoadTrig:GetLoadTrig_B,
- GetMode: GetMode_B,
- PulseIndex:PulseIndex_B,
- SetEnable:SetEnable_B,
- SetIntSrc:SetIntSrc_B,
- SetLoadTrig:SetLoadTrig_B,
- SetMode: SetMode_B,
- ResetCapFlags:ResetCapFlags_B,
- MyCRA: LP_CR2A,
- MyCRB: LP_CR2B,
- MyLatchLsw:LP_CNTR2BLSW,
- MyEventBits:EVBITS(5),
+ GetIntSrc : GetIntSrc_B,
+ GetLoadTrig : GetLoadTrig_B,
+ GetMode : GetMode_B,
+ PulseIndex : PulseIndex_B,
+ SetEnable : SetEnable_B,
+ SetIntSrc : SetIntSrc_B,
+ SetLoadTrig : SetLoadTrig_B,
+ SetMode : SetMode_B,
+ ResetCapFlags : ResetCapFlags_B,
+ MyCRA : LP_CR2A,
+ MyCRB : LP_CR2B,
+ MyLatchLsw : LP_CNTR2BLSW,
+ MyEventBits : EVBITS(5),
},
};
-// enab/disable a function or test status bit(s) that are accessed
-// through Main Control Registers 1 or 2.
-#define MC_ENABLE( REGADRS, CTRLWORD ) writel( ( (uint32_t)( CTRLWORD ) << 16 ) | (uint32_t)( CTRLWORD ),devpriv->base_addr+( REGADRS ) )
+/* enab/disable a function or test status bit(s) that are accessed */
+/* through Main Control Registers 1 or 2. */
+#define MC_ENABLE(REGADRS, CTRLWORD) writel(((uint32_t)(CTRLWORD) << 16) | (uint32_t)(CTRLWORD), devpriv->base_addr+(REGADRS))
-#define MC_DISABLE( REGADRS, CTRLWORD ) writel( (uint32_t)( CTRLWORD ) << 16 , devpriv->base_addr+( REGADRS ) )
+#define MC_DISABLE(REGADRS, CTRLWORD) writel((uint32_t)(CTRLWORD) << 16 , devpriv->base_addr+(REGADRS))
-#define MC_TEST( REGADRS, CTRLWORD ) ( ( readl(devpriv->base_addr+( REGADRS )) & CTRLWORD ) != 0 )
+#define MC_TEST(REGADRS, CTRLWORD) ((readl(devpriv->base_addr+(REGADRS)) & CTRLWORD) != 0)
/* #define WR7146(REGARDS,CTRLWORD)
writel(CTRLWORD,(uint32_t)(devpriv->base_addr+(REGARDS))) */
-#define WR7146(REGARDS,CTRLWORD) writel(CTRLWORD,devpriv->base_addr+(REGARDS))
+#define WR7146(REGARDS, CTRLWORD) writel(CTRLWORD, devpriv->base_addr+(REGARDS))
/* #define RR7146(REGARDS)
readl((uint32_t)(devpriv->base_addr+(REGARDS))) */
#define RR7146(REGARDS) readl(devpriv->base_addr+(REGARDS))
-#define BUGFIX_STREG(REGADRS) ( REGADRS - 4 )
+#define BUGFIX_STREG(REGADRS) (REGADRS - 4)
-// Write a time slot control record to TSL2.
-#define VECTPORT( VECTNUM ) (P_TSL2 + ( (VECTNUM) << 2 ))
-#define SETVECT( VECTNUM, VECTVAL ) WR7146(VECTPORT( VECTNUM ), (VECTVAL))
+/* Write a time slot control record to TSL2. */
+#define VECTPORT(VECTNUM) (P_TSL2 + ((VECTNUM) << 2))
+#define SETVECT(VECTNUM, VECTVAL) WR7146(VECTPORT(VECTNUM), (VECTVAL))
-// Code macros used for constructing I2C command bytes.
-#define I2C_B2(ATTR,VAL) ( ( (ATTR) << 6 ) | ( (VAL) << 24 ) )
-#define I2C_B1(ATTR,VAL) ( ( (ATTR) << 4 ) | ( (VAL) << 16 ) )
-#define I2C_B0(ATTR,VAL) ( ( (ATTR) << 2 ) | ( (VAL) << 8 ) )
+/* Code macros used for constructing I2C command bytes. */
+#define I2C_B2(ATTR, VAL) (((ATTR) << 6) | ((VAL) << 24))
+#define I2C_B1(ATTR, VAL) (((ATTR) << 4) | ((VAL) << 16))
+#define I2C_B0(ATTR, VAL) (((ATTR) << 2) | ((VAL) << 8))
-static const comedi_lrange s626_range_table = { 2, {
+static const struct comedi_lrange s626_range_table = { 2, {
RANGE(-5, 5),
RANGE(-10, 10),
}
};
-static int s626_attach(comedi_device * dev, comedi_devconfig * it)
+static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
/* uint8_t PollList; */
/* uint16_t AdcData; */
@@ -507,10 +497,10 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
int ret;
resource_size_t resourceStart;
dma_addr_t appdma;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
struct pci_dev *pdev;
- if (alloc_private(dev, sizeof(s626_private)) < 0)
+ if (alloc_private(dev, sizeof(struct s626_private)) < 0)
return -ENOMEM;
for (pdev = pci_get_device(PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626,
@@ -535,7 +525,8 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
return -ENODEV;
}
- if ((result = comedi_pci_enable(pdev, "s626")) < 0) {
+ result = comedi_pci_enable(pdev, "s626");
+ if (result < 0) {
printk("s626_attach: comedi_pci_enable fails\n");
return -ENODEV;
}
@@ -550,21 +541,22 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
}
if (devpriv->base_addr) {
- //disable master interrupt
+ /* disable master interrupt */
writel(0, devpriv->base_addr + P_IER);
- //soft reset
+ /* soft reset */
writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1);
- //DMA FIXME DMA//
+ /* DMA FIXME DMA// */
DEBUG("s626_attach: DMA ALLOCATION\n");
- //adc buffer allocation
+ /* adc buffer allocation */
devpriv->allocatedBuf = 0;
- if ((devpriv->ANABuf.LogicalBase =
- pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE,
- &appdma)) == NULL) {
+ devpriv->ANABuf.LogicalBase =
+ pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
+
+ if (devpriv->ANABuf.LogicalBase == NULL) {
printk("s626_attach: DMA Memory mapping error\n");
return -ENOMEM;
}
@@ -575,9 +567,10 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
devpriv->allocatedBuf++;
- if ((devpriv->RPSBuf.LogicalBase =
- pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE,
- &appdma)) == NULL) {
+ devpriv->RPSBuf.LogicalBase =
+ pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
+
+ if (devpriv->RPSBuf.LogicalBase == NULL) {
printk("s626_attach: DMA Memory mapping error\n");
return -ENOMEM;
}
@@ -599,12 +592,14 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
dev->iobase = (unsigned long)devpriv->base_addr;
dev->irq = devpriv->pdev->irq;
- //set up interrupt handler
+ /* set up interrupt handler */
if (dev->irq == 0) {
printk(" unknown irq (bad)\n");
} else {
- if ((ret = comedi_request_irq(dev->irq, s626_irq_handler,
- IRQF_SHARED, "s626", dev)) < 0) {
+ ret = comedi_request_irq(dev->irq, s626_irq_handler,
+ IRQF_SHARED, "s626", dev);
+
+ if (ret < 0) {
printk(" irq not available\n");
dev->irq = 0;
}
@@ -689,119 +684,121 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
s->maxdata = 0xffffff;
s->range_table = &range_unknown;
- //stop ai_command
+ /* stop ai_command */
devpriv->ai_cmd_running = 0;
if (devpriv->base_addr && (devpriv->allocatedBuf == 2)) {
dma_addr_t pPhysBuf;
uint16_t chan;
- // enab DEBI and audio pins, enable I2C interface.
+ /* enab DEBI and audio pins, enable I2C interface. */
MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C);
- // Configure DEBI operating mode.
- WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 // Local bus is 16
- // bits wide.
- | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) // Declare DEBI
- // transfer timeout
- // interval.
- | DEBI_SWAP // Set up byte lane
- // steering.
- | DEBI_CFG_INTEL); // Intel-compatible
- // local bus (DEBI
- // never times out).
+ /* Configure DEBI operating mode. */
+ WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 /* Local bus is 16 */
+ /* bits wide. */
+ | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) /* Declare DEBI */
+ /* transfer timeout */
+ /* interval. */
+ | DEBI_SWAP /* Set up byte lane */
+ /* steering. */
+ | DEBI_CFG_INTEL); /* Intel-compatible */
+ /* local bus (DEBI */
+ /* never times out). */
DEBUG("s626_attach: %d debi init -- %d\n",
DEBI_CFG_SLAVE16 | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) |
DEBI_SWAP | DEBI_CFG_INTEL,
DEBI_CFG_INTEL | DEBI_CFG_TOQ | DEBI_CFG_INCQ |
DEBI_CFG_16Q);
- //DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ
- //| DEBI_CFG_INCQ| DEBI_CFG_16Q); //end
+ /* DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ */
+ /* | DEBI_CFG_INCQ| DEBI_CFG_16Q); //end */
- // Paging is disabled.
- WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE); // Disable MMU paging.
+ /* Paging is disabled. */
+ WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE); /* Disable MMU paging. */
- // Init GPIO so that ADC Start* is negated.
+ /* Init GPIO so that ADC Start* is negated. */
WR7146(P_GPIO, GPIO_BASE | GPIO1_HI);
- //IsBoardRevA is a boolean that indicates whether the board is
- //RevA.
-
- // VERSION 2.01 CHANGE: REV A & B BOARDS NOW SUPPORTED BY DYNAMIC
- // EEPROM ADDRESS SELECTION. Initialize the I2C interface, which
- // is used to access the onboard serial EEPROM. The EEPROM's I2C
- // DeviceAddress is hardwired to a value that is dependent on the
- // 626 board revision. On all board revisions, the EEPROM stores
- // TrimDAC calibration constants for analog I/O. On RevB and
- // higher boards, the DeviceAddress is hardwired to 0 to enable
- // the EEPROM to also store the PCI SubVendorID and SubDeviceID;
- // this is the address at which the SAA7146 expects a
- // configuration EEPROM to reside. On RevA boards, the EEPROM
- // device address, which is hardwired to 4, prevents the SAA7146
- // from retrieving PCI sub-IDs, so the SAA7146 uses its built-in
- // default values, instead.
-
- // devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM
- // DeviceType (0xA0)
- // and DeviceAddress<<1.
-
- devpriv->I2CAdrs = 0xA0; // I2C device address for onboard
- // eeprom(revb)
-
- // Issue an I2C ABORT command to halt any I2C operation in
- //progress and reset BUSY flag.
- WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT); // Write I2C control:
- // abort any I2C
- // activity.
- MC_ENABLE(P_MC2, MC2_UPLD_IIC); // Invoke command
- // upload
- while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) ; // and wait for
- // upload to
- // complete.
-
- // Per SAA7146 data sheet, write to STATUS reg twice to reset all
- // I2C error flags.
+ /* IsBoardRevA is a boolean that indicates whether the board is RevA.
+ *
+ * VERSION 2.01 CHANGE: REV A & B BOARDS NOW SUPPORTED BY DYNAMIC
+ * EEPROM ADDRESS SELECTION. Initialize the I2C interface, which
+ * is used to access the onboard serial EEPROM. The EEPROM's I2C
+ * DeviceAddress is hardwired to a value that is dependent on the
+ * 626 board revision. On all board revisions, the EEPROM stores
+ * TrimDAC calibration constants for analog I/O. On RevB and
+ * higher boards, the DeviceAddress is hardwired to 0 to enable
+ * the EEPROM to also store the PCI SubVendorID and SubDeviceID;
+ * this is the address at which the SAA7146 expects a
+ * configuration EEPROM to reside. On RevA boards, the EEPROM
+ * device address, which is hardwired to 4, prevents the SAA7146
+ * from retrieving PCI sub-IDs, so the SAA7146 uses its built-in
+ * default values, instead.
+ */
+
+ /* devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM */
+ /* DeviceType (0xA0) */
+ /* and DeviceAddress<<1. */
+
+ devpriv->I2CAdrs = 0xA0; /* I2C device address for onboard */
+ /* eeprom(revb) */
+
+ /* Issue an I2C ABORT command to halt any I2C operation in */
+ /* progress and reset BUSY flag. */
+ WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT);
+ /* Write I2C control: abort any I2C activity. */
+ MC_ENABLE(P_MC2, MC2_UPLD_IIC);
+ /* Invoke command upload */
+ while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0)
+ ;
+ /* and wait for upload to complete. */
+
+ /* Per SAA7146 data sheet, write to STATUS reg twice to
+ * reset all I2C error flags. */
for (i = 0; i < 2; i++) {
- WR7146(P_I2CSTAT, I2C_CLKSEL); // Write I2C control: reset
- // error flags.
- MC_ENABLE(P_MC2, MC2_UPLD_IIC); // Invoke command upload
- while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) ; // and wait for
- // upload to
- // complete.
+ WR7146(P_I2CSTAT, I2C_CLKSEL);
+ /* Write I2C control: reset error flags. */
+ MC_ENABLE(P_MC2, MC2_UPLD_IIC); /* Invoke command upload */
+ while (!MC_TEST(P_MC2, MC2_UPLD_IIC))
+ ;
+ /* and wait for upload to complete. */
}
- // Init audio interface functional attributes: set DAC/ADC serial
- // clock rates, invert DAC serial clock so that DAC data setup
- // times are satisfied, enable DAC serial clock out.
+ /* Init audio interface functional attributes: set DAC/ADC
+ * serial clock rates, invert DAC serial clock so that
+ * DAC data setup times are satisfied, enable DAC serial
+ * clock out.
+ */
+
WR7146(P_ACON2, ACON2_INIT);
- // Set up TSL1 slot list, which is used to control the
- // accumulation of ADC data: RSD1 = shift data in on SD1. SIB_A1
- // = store data uint8_t at next available location in FB BUFFER1
- // register.
- WR7146(P_TSL1, RSD1 | SIB_A1); // Fetch ADC high data
- // uint8_t.
- WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS); // Fetch ADC low data
- // uint8_t; end of
- // TSL1.
-
- // enab TSL1 slot list so that it executes all the time.
+ /* Set up TSL1 slot list, which is used to control the
+ * accumulation of ADC data: RSD1 = shift data in on SD1.
+ * SIB_A1 = store data uint8_t at next available location in
+ * FB BUFFER1 register. */
+ WR7146(P_TSL1, RSD1 | SIB_A1);
+ /* Fetch ADC high data uint8_t. */
+ WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS);
+ /* Fetch ADC low data uint8_t; end of TSL1. */
+
+ /* enab TSL1 slot list so that it executes all the time. */
WR7146(P_ACON1, ACON1_ADCSTART);
- // Initialize RPS registers used for ADC.
+ /* Initialize RPS registers used for ADC. */
- //Physical start of RPS program.
+ /* Physical start of RPS program. */
WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase);
- WR7146(P_RPSPAGE1, 0); // RPS program performs no
- // explicit mem writes.
- WR7146(P_RPS1_TOUT, 0); // Disable RPS timeouts.
+ WR7146(P_RPSPAGE1, 0);
+ /* RPS program performs no explicit mem writes. */
+ WR7146(P_RPS1_TOUT, 0); /* Disable RPS timeouts. */
- // SAA7146 BUG WORKAROUND. Initialize SAA7146 ADC interface to a
- // known state by invoking ADCs until FB BUFFER 1 register shows
- // that it is correctly receiving ADC data. This is necessary
- // because the SAA7146 ADC interface does not start up in a
- // defined state after a PCI reset.
+ /* SAA7146 BUG WORKAROUND. Initialize SAA7146 ADC interface
+ * to a known state by invoking ADCs until FB BUFFER 1
+ * register shows that it is correctly receiving ADC data.
+ * This is necessary because the SAA7146 ADC interface does
+ * not start up in a defined state after a PCI reset.
+ */
/* PollList = EOPL; // Create a simple polling */
/* // list for analog input */
@@ -829,115 +826,123 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
/* break; */
/* } */
- // end initADC
+ /* end initADC */
- // init the DAC interface
+ /* init the DAC interface */
- // Init Audio2's output DMAC attributes: burst length = 1 DWORD,
- // threshold = 1 DWORD.
+ /* Init Audio2's output DMAC attributes: burst length = 1
+ * DWORD, threshold = 1 DWORD.
+ */
WR7146(P_PCI_BT_A, 0);
- // Init Audio2's output DMA physical addresses. The protection
- // address is set to 1 DWORD past the base address so that a
- // single DWORD will be transferred each time a DMA transfer is
- // enabled.
+ /* Init Audio2's output DMA physical addresses. The protection
+ * address is set to 1 DWORD past the base address so that a
+ * single DWORD will be transferred each time a DMA transfer is
+ * enabled. */
pPhysBuf =
devpriv->ANABuf.PhysicalBase +
(DAC_WDMABUF_OS * sizeof(uint32_t));
- WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf); // Buffer base adrs.
- WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); // Protection address.
+ WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf); /* Buffer base adrs. */
+ WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); /* Protection address. */
- // Cache Audio2's output DMA buffer logical address. This is
- // where DAC data is buffered for A2 output DMA transfers.
+ /* Cache Audio2's output DMA buffer logical address. This is
+ * where DAC data is buffered for A2 output DMA transfers. */
devpriv->pDacWBuf =
(uint32_t *) devpriv->ANABuf.LogicalBase +
DAC_WDMABUF_OS;
- // Audio2's output channels does not use paging. The protection
- // violation handling bit is set so that the DMAC will
- // automatically halt and its PCI address pointer will be reset
- // when the protection address is reached.
+ /* Audio2's output channels does not use paging. The protection
+ * violation handling bit is set so that the DMAC will
+ * automatically halt and its PCI address pointer will be reset
+ * when the protection address is reached. */
+
WR7146(P_PAGEA2_OUT, 8);
- // Initialize time slot list 2 (TSL2), which is used to control
- // the clock generation for and serialization of data to be sent
- // to the DAC devices. Slot 0 is a NOP that is used to trap TSL
- // execution; this permits other slots to be safely modified
- // without first turning off the TSL sequencer (which is
- // apparently impossible to do). Also, SD3 (which is driven by a
- // pull-up resistor) is shifted in and stored to the MSB of
- // FB_BUFFER2 to be used as evidence that the slot sequence has
- // not yet finished executing.
- SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS); // Slot 0: Trap TSL
- // execution, shift 0xFF
- // into FB_BUFFER2.
-
- // Initialize slot 1, which is constant. Slot 1 causes a DWORD to
- // be transferred from audio channel 2's output FIFO to the FIFO's
- // output buffer so that it can be serialized and sent to the DAC
- // during subsequent slots. All remaining slots are dynamically
- // populated as required by the target DAC device.
- SETVECT(1, LF_A2); // Slot 1: Fetch DWORD from Audio2's
- // output FIFO.
-
- // Start DAC's audio interface (TSL2) running.
+ /* Initialize time slot list 2 (TSL2), which is used to control
+ * the clock generation for and serialization of data to be sent
+ * to the DAC devices. Slot 0 is a NOP that is used to trap TSL
+ * execution; this permits other slots to be safely modified
+ * without first turning off the TSL sequencer (which is
+ * apparently impossible to do). Also, SD3 (which is driven by a
+ * pull-up resistor) is shifted in and stored to the MSB of
+ * FB_BUFFER2 to be used as evidence that the slot sequence has
+ * not yet finished executing.
+ */
+
+ SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS);
+ /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2. */
+
+ /* Initialize slot 1, which is constant. Slot 1 causes a
+ * DWORD to be transferred from audio channel 2's output FIFO
+ * to the FIFO's output buffer so that it can be serialized
+ * and sent to the DAC during subsequent slots. All remaining
+ * slots are dynamically populated as required by the target
+ * DAC device.
+ */
+ SETVECT(1, LF_A2);
+ /* Slot 1: Fetch DWORD from Audio2's output FIFO. */
+
+ /* Start DAC's audio interface (TSL2) running. */
WR7146(P_ACON1, ACON1_DACSTART);
- ////////////////////////////////////////////////////////
+ /* end init DAC interface */
- // end init DAC interface
-
- // Init Trim DACs to calibrated values. Do it twice because the
- // SAA7146 audio channel does not always reset properly and
- // sometimes causes the first few TrimDAC writes to malfunction.
+ /* Init Trim DACs to calibrated values. Do it twice because the
+ * SAA7146 audio channel does not always reset properly and
+ * sometimes causes the first few TrimDAC writes to malfunction.
+ */
LoadTrimDACs(dev);
- LoadTrimDACs(dev); // Insurance.
+ LoadTrimDACs(dev); /* Insurance. */
- //////////////////////////////////////////////////////////////////
- // Manually init all gate array hardware in case this is a soft
- // reset (we have no way of determining whether this is a warm or
- // cold start). This is necessary because the gate array will
- // reset only in response to a PCI hard reset; there is no soft
- // reset function.
+ /* Manually init all gate array hardware in case this is a soft
+ * reset (we have no way of determining whether this is a warm
+ * or cold start). This is necessary because the gate array will
+ * reset only in response to a PCI hard reset; there is no soft
+ * reset function. */
- // Init all DAC outputs to 0V and init all DAC setpoint and
- // polarity images.
+ /* Init all DAC outputs to 0V and init all DAC setpoint and
+ * polarity images.
+ */
for (chan = 0; chan < S626_DAC_CHANNELS; chan++)
SetDAC(dev, chan, 0);
- // Init image of WRMISC2 Battery Charger Enabled control bit.
- // This image is used when the state of the charger control bit,
- // which has no direct hardware readback mechanism, is queried.
+ /* Init image of WRMISC2 Battery Charger Enabled control bit.
+ * This image is used when the state of the charger control bit,
+ * which has no direct hardware readback mechanism, is queried.
+ */
devpriv->ChargeEnabled = 0;
- // Init image of watchdog timer interval in WRMISC2. This image
- // maintains the value of the control bits of MISC2 are
- // continuously reset to zero as long as the WD timer is disabled.
+ /* Init image of watchdog timer interval in WRMISC2. This image
+ * maintains the value of the control bits of MISC2 are
+ * continuously reset to zero as long as the WD timer is disabled.
+ */
devpriv->WDInterval = 0;
- // Init Counter Interrupt enab mask for RDMISC2. This mask is
- // applied against MISC2 when testing to determine which timer
- // events are requesting interrupt service.
+ /* Init Counter Interrupt enab mask for RDMISC2. This mask is
+ * applied against MISC2 when testing to determine which timer
+ * events are requesting interrupt service.
+ */
devpriv->CounterIntEnabs = 0;
- // Init counters.
+ /* Init counters. */
CountersInit(dev);
- // Without modifying the state of the Battery Backup enab, disable
- // the watchdog timer, set DIO channels 0-5 to operate in the
- // standard DIO (vs. counter overflow) mode, disable the battery
- // charger, and reset the watchdog interval selector to zero.
+ /* Without modifying the state of the Battery Backup enab, disable
+ * the watchdog timer, set DIO channels 0-5 to operate in the
+ * standard DIO (vs. counter overflow) mode, disable the battery
+ * charger, and reset the watchdog interval selector to zero.
+ */
WriteMISC2(dev, (uint16_t) (DEBIread(dev,
LP_RDMISC2) & MISC2_BATT_ENABLE));
- // Initialize the digital I/O subsystem.
+ /* Initialize the digital I/O subsystem. */
s626_dio_init(dev);
- //enable interrupt test
- // writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER);
+ /* enable interrupt test */
+ /* writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); */
}
DEBUG("s626_attach: comedi%d s626 attached %04x\n", dev->minor,
@@ -946,9 +951,9 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
return 1;
}
-static lsampl_t s626_ai_reg_to_uint(int data)
+static unsigned int s626_ai_reg_to_uint(int data)
{
- lsampl_t tempdata;
+ unsigned int tempdata;
tempdata = (data >> 18);
if (tempdata & 0x2000)
@@ -959,21 +964,21 @@ static lsampl_t s626_ai_reg_to_uint(int data)
return tempdata;
}
-/* static lsampl_t s626_uint_to_reg(comedi_subdevice *s, int data){ */
+/* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data){ */
/* return 0; */
/* } */
static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
{
- comedi_device *dev = d;
- comedi_subdevice *s;
- comedi_cmd *cmd;
- enc_private *k;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s;
+ struct comedi_cmd *cmd;
+ struct enc_private *k;
unsigned long flags;
int32_t *readaddr;
uint32_t irqtype, irqstatus;
int i = 0;
- sampl_t tempdata;
+ short tempdata;
uint8_t group;
uint16_t irqbit;
@@ -981,47 +986,48 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
if (dev->attached == 0)
return IRQ_NONE;
- // lock to avoid race with comedi_poll
+ /* lock to avoid race with comedi_poll */
comedi_spin_lock_irqsave(&dev->spinlock, flags);
- //save interrupt enable register state
+ /* save interrupt enable register state */
irqstatus = readl(devpriv->base_addr + P_IER);
- //read interrupt type
+ /* read interrupt type */
irqtype = readl(devpriv->base_addr + P_ISR);
- //disable master interrupt
+ /* disable master interrupt */
writel(0, devpriv->base_addr + P_IER);
- //clear interrupt
+ /* clear interrupt */
writel(irqtype, devpriv->base_addr + P_ISR);
- //do somethings
+ /* do somethings */
DEBUG("s626_irq_handler: interrupt type %d\n", irqtype);
switch (irqtype) {
- case IRQ_RPS1: // end_of_scan occurs
+ case IRQ_RPS1: /* end_of_scan occurs */
DEBUG("s626_irq_handler: RPS1 irq detected\n");
- // manage ai subdevice
+ /* manage ai subdevice */
s = dev->subdevices;
cmd = &(s->async->cmd);
- // Init ptr to DMA buffer that holds new ADC data. We skip the
- // first uint16_t in the buffer because it contains junk data from
- // the final ADC of the previous poll list scan.
+ /* Init ptr to DMA buffer that holds new ADC data. We skip the
+ * first uint16_t in the buffer because it contains junk data from
+ * the final ADC of the previous poll list scan.
+ */
readaddr = (int32_t *) devpriv->ANABuf.LogicalBase + 1;
- // get the data and hand it over to comedi
+ /* get the data and hand it over to comedi */
for (i = 0; i < (s->async->cmd.chanlist_len); i++) {
- // Convert ADC data to 16-bit integer values and copy to application
- // buffer.
+ /* Convert ADC data to 16-bit integer values and copy to application */
+ /* buffer. */
tempdata = s626_ai_reg_to_uint((int)*readaddr);
readaddr++;
- //put data into read buffer
- // comedi_buf_put(s->async, tempdata);
+ /* put data into read buffer */
+ /* comedi_buf_put(s->async, tempdata); */
if (cfc_write_to_buffer(s, tempdata) == 0)
printk("s626_irq_handler: cfc_write_to_buffer error!\n");
@@ -1029,7 +1035,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
i, tempdata);
}
- //end of scan occurs
+ /* end of scan occurs */
s->async->events |= COMEDI_CB_EOS;
if (!(devpriv->ai_continous))
@@ -1037,13 +1043,13 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
if (devpriv->ai_sample_count <= 0) {
devpriv->ai_cmd_running = 0;
- // Stop RPS program.
+ /* Stop RPS program. */
MC_DISABLE(P_MC1, MC1_ERPS1);
- //send end of acquisition
+ /* send end of acquisition */
s->async->events |= COMEDI_CB_EOA;
- //disable master interrupt
+ /* disable master interrupt */
irqstatus = 0;
}
@@ -1054,40 +1060,40 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
DEBUG("s626_irq_handler: External trigger is set!!!\n");
}
- // tell comedi that data is there
+ /* tell comedi that data is there */
DEBUG("s626_irq_handler: events %d\n", s->async->events);
comedi_event(dev, s);
break;
- case IRQ_GPIO3: //check dio and conter interrupt
+ case IRQ_GPIO3: /* check dio and conter interrupt */
DEBUG("s626_irq_handler: GPIO3 irq detected\n");
- // manage ai subdevice
+ /* manage ai subdevice */
s = dev->subdevices;
cmd = &(s->async->cmd);
- //s626_dio_clear_irq(dev);
+ /* s626_dio_clear_irq(dev); */
for (group = 0; group < S626_DIO_BANKS; group++) {
irqbit = 0;
- //read interrupt type
+ /* read interrupt type */
irqbit = DEBIread(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->RDCapFlg);
- //check if interrupt is generated from dio channels
+ /* check if interrupt is generated from dio channels */
if (irqbit) {
s626_dio_reset_irq(dev, group, irqbit);
DEBUG("s626_irq_handler: check interrupt on dio group %d %d\n", group, i);
if (devpriv->ai_cmd_running) {
- //check if interrupt is an ai acquisition start trigger
+ /* check if interrupt is an ai acquisition start trigger */
if ((irqbit >> (cmd->start_arg -
(16 * group)))
== 1
&& cmd->start_src == TRIG_EXT) {
DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", cmd->start_arg);
- // Start executing the RPS program.
+ /* Start executing the RPS program. */
MC_ENABLE(P_MC1, MC1_ERPS1);
DEBUG("s626_irq_handler: aquisition start triggered!!!\n");
@@ -1110,7 +1116,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
TRIG_EXT) {
DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", cmd->scan_begin_arg);
- // Trigger ADC scan loop start by setting RPS Signal 0.
+ /* Trigger ADC scan loop start by setting RPS Signal 0. */
MC_ENABLE(P_MC2, MC2_ADC_RPS);
DEBUG("s626_irq_handler: scan triggered!!! %d\n", devpriv->ai_sample_count);
@@ -1151,7 +1157,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
TRIG_EXT) {
DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", cmd->convert_arg);
- // Trigger ADC scan loop start by setting RPS Signal 0.
+ /* Trigger ADC scan loop start by setting RPS Signal 0. */
MC_ENABLE(P_MC2, MC2_ADC_RPS);
DEBUG("s626_irq_handler: adc convert triggered!!!\n");
@@ -1175,10 +1181,10 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
}
}
- //read interrupt type
+ /* read interrupt type */
irqbit = DEBIread(dev, LP_RDMISC2);
- //check interrupt on counters
+ /* check interrupt on counters */
DEBUG("s626_irq_handler: check counters interrupt %d\n",
irqbit);
@@ -1186,35 +1192,35 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
DEBUG("s626_irq_handler: interrupt on counter 1A overflow\n");
k = &encpriv[0];
- //clear interrupt capture flag
+ /* clear interrupt capture flag */
k->ResetCapFlags(dev, k);
}
if (irqbit & IRQ_COINT2A) {
DEBUG("s626_irq_handler: interrupt on counter 2A overflow\n");
k = &encpriv[1];
- //clear interrupt capture flag
+ /* clear interrupt capture flag */
k->ResetCapFlags(dev, k);
}
if (irqbit & IRQ_COINT3A) {
DEBUG("s626_irq_handler: interrupt on counter 3A overflow\n");
k = &encpriv[2];
- //clear interrupt capture flag
+ /* clear interrupt capture flag */
k->ResetCapFlags(dev, k);
}
if (irqbit & IRQ_COINT1B) {
DEBUG("s626_irq_handler: interrupt on counter 1B overflow\n");
k = &encpriv[3];
- //clear interrupt capture flag
+ /* clear interrupt capture flag */
k->ResetCapFlags(dev, k);
}
if (irqbit & IRQ_COINT2B) {
DEBUG("s626_irq_handler: interrupt on counter 2B overflow\n");
k = &encpriv[4];
- //clear interrupt capture flag
+ /* clear interrupt capture flag */
k->ResetCapFlags(dev, k);
if (devpriv->ai_convert_count > 0) {
@@ -1225,7 +1231,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
if (cmd->convert_src == TRIG_TIMER) {
DEBUG("s626_irq_handler: conver timer trigger!!! %d\n", devpriv->ai_convert_count);
- // Trigger ADC scan loop start by setting RPS Signal 0.
+ /* Trigger ADC scan loop start by setting RPS Signal 0. */
MC_ENABLE(P_MC2, MC2_ADC_RPS);
}
}
@@ -1234,13 +1240,13 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
DEBUG("s626_irq_handler: interrupt on counter 3B overflow\n");
k = &encpriv[5];
- //clear interrupt capture flag
+ /* clear interrupt capture flag */
k->ResetCapFlags(dev, k);
if (cmd->scan_begin_src == TRIG_TIMER) {
DEBUG("s626_irq_handler: scan timer trigger!!!\n");
- // Trigger ADC scan loop start by setting RPS Signal 0.
+ /* Trigger ADC scan loop start by setting RPS Signal 0. */
MC_ENABLE(P_MC2, MC2_ADC_RPS);
}
@@ -1253,7 +1259,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
}
}
- //enable interrupt
+ /* enable interrupt */
writel(irqstatus, devpriv->base_addr + P_IER);
DEBUG("s626_irq_handler: exit interrupt service routine.\n");
@@ -1262,21 +1268,21 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
return IRQ_HANDLED;
}
-static int s626_detach(comedi_device * dev)
+static int s626_detach(struct comedi_device *dev)
{
if (devpriv) {
- //stop ai_command
+ /* stop ai_command */
devpriv->ai_cmd_running = 0;
if (devpriv->base_addr) {
- //interrupt mask
- WR7146(P_IER, 0); // Disable master interrupt.
- WR7146(P_ISR, IRQ_GPIO3 | IRQ_RPS1); // Clear board's IRQ status flag.
+ /* interrupt mask */
+ WR7146(P_IER, 0); /* Disable master interrupt. */
+ WR7146(P_ISR, IRQ_GPIO3 | IRQ_RPS1); /* Clear board's IRQ status flag. */
- // Disable the watchdog timer and battery charger.
+ /* Disable the watchdog timer and battery charger. */
WriteMISC2(dev, 0);
- // Close all interfaces on 7146 device.
+ /* Close all interfaces on 7146 device. */
WR7146(P_MC1, MC1_SHUTDOWN);
WR7146(P_ACON1, ACON1_BASE);
@@ -1284,18 +1290,15 @@ static int s626_detach(comedi_device * dev)
CloseDMAB(dev, &devpriv->ANABuf, DMABUF_SIZE);
}
- if (dev->irq) {
+ if (dev->irq)
comedi_free_irq(dev->irq, dev);
- }
- if (devpriv->base_addr) {
+ if (devpriv->base_addr)
iounmap(devpriv->base_addr);
- }
if (devpriv->pdev) {
- if (devpriv->got_regions) {
+ if (devpriv->got_regions)
comedi_pci_disable(devpriv->pdev);
- }
pci_dev_put(devpriv->pdev);
}
}
@@ -1308,213 +1311,225 @@ static int s626_detach(comedi_device * dev)
/*
* this functions build the RPS program for hardware driven acquistion
*/
-void ResetADC(comedi_device * dev, uint8_t * ppl)
+void ResetADC(struct comedi_device *dev, uint8_t *ppl)
{
register uint32_t *pRPS;
uint32_t JmpAdrs;
uint16_t i;
uint16_t n;
uint32_t LocalPPL;
- comedi_cmd *cmd = &(dev->subdevices->async->cmd);
+ struct comedi_cmd *cmd = &(dev->subdevices->async->cmd);
- // Stop RPS program in case it is currently running.
+ /* Stop RPS program in case it is currently running. */
MC_DISABLE(P_MC1, MC1_ERPS1);
- // Set starting logical address to write RPS commands.
+ /* Set starting logical address to write RPS commands. */
pRPS = (uint32_t *) devpriv->RPSBuf.LogicalBase;
- // Initialize RPS instruction pointer.
+ /* Initialize RPS instruction pointer. */
WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase);
- // Construct RPS program in RPSBuf DMA buffer
+ /* Construct RPS program in RPSBuf DMA buffer */
if (cmd != NULL && cmd->scan_begin_src != TRIG_FOLLOW) {
DEBUG("ResetADC: scan_begin pause inserted\n");
- // Wait for Start trigger.
+ /* Wait for Start trigger. */
*pRPS++ = RPS_PAUSE | RPS_SIGADC;
*pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
}
- // SAA7146 BUG WORKAROUND Do a dummy DEBI Write. This is necessary
- // because the first RPS DEBI Write following a non-RPS DEBI write
- // seems to always fail. If we don't do this dummy write, the ADC
- // gain might not be set to the value required for the first slot in
- // the poll list; the ADC gain would instead remain unchanged from
- // the previously programmed value.
- *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); // Write DEBI Write command
- // and address to shadow RAM.
+
+ /* SAA7146 BUG WORKAROUND Do a dummy DEBI Write. This is necessary
+ * because the first RPS DEBI Write following a non-RPS DEBI write
+ * seems to always fail. If we don't do this dummy write, the ADC
+ * gain might not be set to the value required for the first slot in
+ * the poll list; the ADC gain would instead remain unchanged from
+ * the previously programmed value.
+ */
+ *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
+ /* Write DEBI Write command and address to shadow RAM. */
+
*pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
- *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); // Write DEBI immediate data
- // to shadow RAM:
- *pRPS++ = GSEL_BIPOLAR5V; // arbitrary immediate data
- // value.
- *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; // Reset "shadow RAM
- // uploaded" flag.
- *pRPS++ = RPS_UPLOAD | RPS_DEBI; // Invoke shadow RAM upload.
- *pRPS++ = RPS_PAUSE | RPS_DEBI; // Wait for shadow upload to finish.
-
- // Digitize all slots in the poll list. This is implemented as a
- // for loop to limit the slot count to 16 in case the application
- // forgot to set the EOPL flag in the final slot.
+ *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
+ /* Write DEBI immediate data to shadow RAM: */
+
+ *pRPS++ = GSEL_BIPOLAR5V;
+ /* arbitrary immediate data value. */
+
+ *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
+ /* Reset "shadow RAM uploaded" flag. */
+ *pRPS++ = RPS_UPLOAD | RPS_DEBI; /* Invoke shadow RAM upload. */
+ *pRPS++ = RPS_PAUSE | RPS_DEBI; /* Wait for shadow upload to finish. */
+
+ /* Digitize all slots in the poll list. This is implemented as a
+ * for loop to limit the slot count to 16 in case the application
+ * forgot to set the EOPL flag in the final slot.
+ */
for (devpriv->AdcItems = 0; devpriv->AdcItems < 16; devpriv->AdcItems++) {
- // Convert application's poll list item to private board class
- // format. Each app poll list item is an uint8_t with form
- // (EOPL,x,x,RANGE,CHAN<3:0>), where RANGE code indicates 0 =
- // +-10V, 1 = +-5V, and EOPL = End of Poll List marker.
+ /* Convert application's poll list item to private board class
+ * format. Each app poll list item is an uint8_t with form
+ * (EOPL,x,x,RANGE,CHAN<3:0>), where RANGE code indicates 0 =
+ * +-10V, 1 = +-5V, and EOPL = End of Poll List marker.
+ */
LocalPPL =
(*ppl << 8) | (*ppl & 0x10 ? GSEL_BIPOLAR5V :
GSEL_BIPOLAR10V);
- // Switch ADC analog gain.
- *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); // Write DEBI command
- // and address to
- // shadow RAM.
+ /* Switch ADC analog gain. */
+ *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); /* Write DEBI command */
+ /* and address to */
+ /* shadow RAM. */
*pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
- *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); // Write DEBI
- // immediate data to
- // shadow RAM.
+ *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); /* Write DEBI */
+ /* immediate data to */
+ /* shadow RAM. */
*pRPS++ = LocalPPL;
- *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; // Reset "shadow RAM uploaded"
- // flag.
- *pRPS++ = RPS_UPLOAD | RPS_DEBI; // Invoke shadow RAM upload.
- *pRPS++ = RPS_PAUSE | RPS_DEBI; // Wait for shadow upload to
- // finish.
-
- // Select ADC analog input channel.
- *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); // Write DEBI command
- // and address to
- // shadow RAM.
+ *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; /* Reset "shadow RAM uploaded" */
+ /* flag. */
+ *pRPS++ = RPS_UPLOAD | RPS_DEBI; /* Invoke shadow RAM upload. */
+ *pRPS++ = RPS_PAUSE | RPS_DEBI; /* Wait for shadow upload to */
+ /* finish. */
+
+ /* Select ADC analog input channel. */
+ *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
+ /* Write DEBI command and address to shadow RAM. */
*pRPS++ = DEBI_CMD_WRWORD | LP_ISEL;
- *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); // Write DEBI
- // immediate data to
- // shadow RAM.
+ *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
+ /* Write DEBI immediate data to shadow RAM. */
*pRPS++ = LocalPPL;
- *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; // Reset "shadow RAM uploaded"
- // flag.
- *pRPS++ = RPS_UPLOAD | RPS_DEBI; // Invoke shadow RAM upload.
- *pRPS++ = RPS_PAUSE | RPS_DEBI; // Wait for shadow upload to
- // finish.
-
- // Delay at least 10 microseconds for analog input settling.
- // Instead of padding with NOPs, we use RPS_JUMP instructions
- // here; this allows us to produce a longer delay than is
- // possible with NOPs because each RPS_JUMP flushes the RPS'
- // instruction prefetch pipeline.
+ *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
+ /* Reset "shadow RAM uploaded" flag. */
+
+ *pRPS++ = RPS_UPLOAD | RPS_DEBI;
+ /* Invoke shadow RAM upload. */
+
+ *pRPS++ = RPS_PAUSE | RPS_DEBI;
+ /* Wait for shadow upload to finish. */
+
+ /* Delay at least 10 microseconds for analog input settling.
+ * Instead of padding with NOPs, we use RPS_JUMP instructions
+ * here; this allows us to produce a longer delay than is
+ * possible with NOPs because each RPS_JUMP flushes the RPS'
+ * instruction prefetch pipeline.
+ */
JmpAdrs =
(uint32_t) devpriv->RPSBuf.PhysicalBase +
(uint32_t) ((unsigned long)pRPS -
(unsigned long)devpriv->RPSBuf.LogicalBase);
for (i = 0; i < (10 * RPSCLK_PER_US / 2); i++) {
- JmpAdrs += 8; // Repeat to implement time delay:
- *pRPS++ = RPS_JUMP; // Jump to next RPS instruction.
+ JmpAdrs += 8; /* Repeat to implement time delay: */
+ *pRPS++ = RPS_JUMP; /* Jump to next RPS instruction. */
*pRPS++ = JmpAdrs;
}
if (cmd != NULL && cmd->convert_src != TRIG_NOW) {
DEBUG("ResetADC: convert pause inserted\n");
- // Wait for Start trigger.
+ /* Wait for Start trigger. */
*pRPS++ = RPS_PAUSE | RPS_SIGADC;
*pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
}
- // Start ADC by pulsing GPIO1.
- *pRPS++ = RPS_LDREG | (P_GPIO >> 2); // Begin ADC Start pulse.
+ /* Start ADC by pulsing GPIO1. */
+ *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* Begin ADC Start pulse. */
*pRPS++ = GPIO_BASE | GPIO1_LO;
*pRPS++ = RPS_NOP;
- // VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE.
- *pRPS++ = RPS_LDREG | (P_GPIO >> 2); // End ADC Start pulse.
+ /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
+ *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* End ADC Start pulse. */
*pRPS++ = GPIO_BASE | GPIO1_HI;
- // Wait for ADC to complete (GPIO2 is asserted high when ADC not
- // busy) and for data from previous conversion to shift into FB
- // BUFFER 1 register.
- *pRPS++ = RPS_PAUSE | RPS_GPIO2; // Wait for ADC done.
+ /* Wait for ADC to complete (GPIO2 is asserted high when ADC not
+ * busy) and for data from previous conversion to shift into FB
+ * BUFFER 1 register.
+ */
+ *pRPS++ = RPS_PAUSE | RPS_GPIO2; /* Wait for ADC done. */
- // Transfer ADC data from FB BUFFER 1 register to DMA buffer.
+ /* Transfer ADC data from FB BUFFER 1 register to DMA buffer. */
*pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2);
*pRPS++ =
(uint32_t) devpriv->ANABuf.PhysicalBase +
(devpriv->AdcItems << 2);
- // If this slot's EndOfPollList flag is set, all channels have
- // now been processed.
+ /* If this slot's EndOfPollList flag is set, all channels have */
+ /* now been processed. */
if (*ppl++ & EOPL) {
- devpriv->AdcItems++; // Adjust poll list item count.
- break; // Exit poll list processing loop.
+ devpriv->AdcItems++; /* Adjust poll list item count. */
+ break; /* Exit poll list processing loop. */
}
}
DEBUG("ResetADC: ADC items %d \n", devpriv->AdcItems);
- // VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US. Allow the
- // ADC to stabilize for 2 microseconds before starting the final
- // (dummy) conversion. This delay is necessary to allow sufficient
- // time between last conversion finished and the start of the dummy
- // conversion. Without this delay, the last conversion's data value
- // is sometimes set to the previous conversion's data value.
+ /* VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US. Allow the
+ * ADC to stabilize for 2 microseconds before starting the final
+ * (dummy) conversion. This delay is necessary to allow sufficient
+ * time between last conversion finished and the start of the dummy
+ * conversion. Without this delay, the last conversion's data value
+ * is sometimes set to the previous conversion's data value.
+ */
for (n = 0; n < (2 * RPSCLK_PER_US); n++)
*pRPS++ = RPS_NOP;
- // Start a dummy conversion to cause the data from the last
- // conversion of interest to be shifted in.
- *pRPS++ = RPS_LDREG | (P_GPIO >> 2); // Begin ADC Start pulse.
+ /* Start a dummy conversion to cause the data from the last
+ * conversion of interest to be shifted in.
+ */
+ *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* Begin ADC Start pulse. */
*pRPS++ = GPIO_BASE | GPIO1_LO;
*pRPS++ = RPS_NOP;
- // VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE.
- *pRPS++ = RPS_LDREG | (P_GPIO >> 2); // End ADC Start pulse.
+ /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
+ *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* End ADC Start pulse. */
*pRPS++ = GPIO_BASE | GPIO1_HI;
- // Wait for the data from the last conversion of interest to arrive
- // in FB BUFFER 1 register.
- *pRPS++ = RPS_PAUSE | RPS_GPIO2; // Wait for ADC done.
+ /* Wait for the data from the last conversion of interest to arrive
+ * in FB BUFFER 1 register.
+ */
+ *pRPS++ = RPS_PAUSE | RPS_GPIO2; /* Wait for ADC done. */
- // Transfer final ADC data from FB BUFFER 1 register to DMA buffer.
- *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2); //
+ /* Transfer final ADC data from FB BUFFER 1 register to DMA buffer. */
+ *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2); /* */
*pRPS++ =
(uint32_t) devpriv->ANABuf.PhysicalBase +
(devpriv->AdcItems << 2);
- // Indicate ADC scan loop is finished.
- // *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ; // Signal ReadADC() that scan is done.
+ /* Indicate ADC scan loop is finished. */
+ /* *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ; // Signal ReadADC() that scan is done. */
- //invoke interrupt
+ /* invoke interrupt */
if (devpriv->ai_cmd_running == 1) {
DEBUG("ResetADC: insert irq in ADC RPS task\n");
*pRPS++ = RPS_IRQ;
}
- // Restart RPS program at its beginning.
- *pRPS++ = RPS_JUMP; // Branch to start of RPS program.
+ /* Restart RPS program at its beginning. */
+ *pRPS++ = RPS_JUMP; /* Branch to start of RPS program. */
*pRPS++ = (uint32_t) devpriv->RPSBuf.PhysicalBase;
- // End of RPS program build
- // ------------------------------------------------------------
+ /* End of RPS program build */
}
/* TO COMPLETE, IF NECESSARY */
-static int s626_ai_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
return -EINVAL;
}
-/* static int s626_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) */
+/* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) */
/* { */
/* register uint8_t i; */
/* register int32_t *readaddr; */
/* DEBUG("as626_ai_rinsn: ai_rinsn enter \n"); */
-/* // Trigger ADC scan loop start by setting RPS Signal 0. */
+/* Trigger ADC scan loop start by setting RPS Signal 0. */
/* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */
-/* // Wait until ADC scan loop is finished (RPS Signal 0 reset). */
+/* Wait until ADC scan loop is finished (RPS Signal 0 reset). */
/* while ( MC_TEST( P_MC2, MC2_ADC_RPS ) ); */
-/* // Init ptr to DMA buffer that holds new ADC data. We skip the */
-/* // first uint16_t in the buffer because it contains junk data from */
-/* // the final ADC of the previous poll list scan. */
+/* Init ptr to DMA buffer that holds new ADC data. We skip the
+ * first uint16_t in the buffer because it contains junk data from
+ * the final ADC of the previous poll list scan.
+ */
/* readaddr = (uint32_t *)devpriv->ANABuf.LogicalBase + 1; */
-/* // Convert ADC data to 16-bit integer values and copy to application */
-/* // buffer. */
+/* Convert ADC data to 16-bit integer values and copy to application buffer. */
/* for ( i = 0; i < devpriv->AdcItems; i++ ) { */
/* *data = s626_ai_reg_to_uint( *readaddr++ ); */
/* DEBUG("s626_ai_rinsn: data %d \n",*data); */
@@ -1525,8 +1540,8 @@ static int s626_ai_insn_config(comedi_device * dev, comedi_subdevice * s,
/* return i; */
/* } */
-static int s626_ai_insn_read(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
uint16_t chan = CR_CHAN(insn->chanspec);
uint16_t range = CR_RANGE(insn->chanspec);
@@ -1534,86 +1549,87 @@ static int s626_ai_insn_read(comedi_device * dev, comedi_subdevice * s,
uint32_t GpioImage;
int n;
-/* //interrupt call test */
-/* writel(IRQ_GPIO3,devpriv->base_addr+P_PSR); //Writing a logical 1 */
-/* //into any of the RPS_PSR */
-/* //bits causes the */
-/* //corresponding interrupt */
-/* //to be generated if */
-/* //enabled */
+ /* interrupt call test */
+/* writel(IRQ_GPIO3,devpriv->base_addr+P_PSR); */
+ /* Writing a logical 1 into any of the RPS_PSR bits causes the
+ * corresponding interrupt to be generated if enabled
+ */
DEBUG("s626_ai_insn_read: entering\n");
- // Convert application's ADC specification into form
- // appropriate for register programming.
+ /* Convert application's ADC specification into form
+ * appropriate for register programming.
+ */
if (range == 0)
AdcSpec = (chan << 8) | (GSEL_BIPOLAR5V);
else
AdcSpec = (chan << 8) | (GSEL_BIPOLAR10V);
- // Switch ADC analog gain.
- DEBIwrite(dev, LP_GSEL, AdcSpec); // Set gain.
+ /* Switch ADC analog gain. */
+ DEBIwrite(dev, LP_GSEL, AdcSpec); /* Set gain. */
- // Select ADC analog input channel.
- DEBIwrite(dev, LP_ISEL, AdcSpec); // Select channel.
+ /* Select ADC analog input channel. */
+ DEBIwrite(dev, LP_ISEL, AdcSpec); /* Select channel. */
for (n = 0; n < insn->n; n++) {
- // Delay 10 microseconds for analog input settling.
+ /* Delay 10 microseconds for analog input settling. */
comedi_udelay(10);
- // Start ADC by pulsing GPIO1 low.
+ /* Start ADC by pulsing GPIO1 low. */
GpioImage = RR7146(P_GPIO);
- // Assert ADC Start command
+ /* Assert ADC Start command */
WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- // and stretch it out.
+ /* and stretch it out. */
WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- // Negate ADC Start command.
+ /* Negate ADC Start command. */
WR7146(P_GPIO, GpioImage | GPIO1_HI);
- // Wait for ADC to complete (GPIO2 is asserted high when
- // ADC not busy) and for data from previous conversion to
- // shift into FB BUFFER 1 register.
+ /* Wait for ADC to complete (GPIO2 is asserted high when */
+ /* ADC not busy) and for data from previous conversion to */
+ /* shift into FB BUFFER 1 register. */
- // Wait for ADC done.
- while (!(RR7146(P_PSR) & PSR_GPIO2)) ;
+ /* Wait for ADC done. */
+ while (!(RR7146(P_PSR) & PSR_GPIO2))
+ ;
- // Fetch ADC data.
+ /* Fetch ADC data. */
if (n != 0)
data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1));
- // Allow the ADC to stabilize for 4 microseconds before
- // starting the next (final) conversion. This delay is
- // necessary to allow sufficient time between last
- // conversion finished and the start of the next
- // conversion. Without this delay, the last conversion's
- // data value is sometimes set to the previous
- // conversion's data value.
+ /* Allow the ADC to stabilize for 4 microseconds before
+ * starting the next (final) conversion. This delay is
+ * necessary to allow sufficient time between last
+ * conversion finished and the start of the next
+ * conversion. Without this delay, the last conversion's
+ * data value is sometimes set to the previous
+ * conversion's data value.
+ */
comedi_udelay(4);
}
- // Start a dummy conversion to cause the data from the
- // previous conversion to be shifted in.
+ /* Start a dummy conversion to cause the data from the
+ * previous conversion to be shifted in. */
GpioImage = RR7146(P_GPIO);
- //Assert ADC Start command
+ /* Assert ADC Start command */
WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- // and stretch it out.
+ /* and stretch it out. */
WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- // Negate ADC Start command.
+ /* Negate ADC Start command. */
WR7146(P_GPIO, GpioImage | GPIO1_HI);
- // Wait for the data to arrive in FB BUFFER 1 register.
+ /* Wait for the data to arrive in FB BUFFER 1 register. */
- // Wait for ADC done.
- while (!(RR7146(P_PSR) & PSR_GPIO2)) ;
+ /* Wait for ADC done. */
+ while (!(RR7146(P_PSR) & PSR_GPIO2))
+ ;
- // Fetch ADC data from audio interface's input shift
- // register.
+ /* Fetch ADC data from audio interface's input shift register. */
- // Fetch ADC data.
+ /* Fetch ADC data. */
if (n != 0)
data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1));
@@ -1622,7 +1638,7 @@ static int s626_ai_insn_read(comedi_device * dev, comedi_subdevice * s,
return n;
}
-static int s626_ai_load_polllist(uint8_t * ppl, comedi_cmd * cmd)
+static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd)
{
int n;
@@ -1638,7 +1654,7 @@ static int s626_ai_load_polllist(uint8_t * ppl, comedi_cmd * cmd)
return n;
}
-static int s626_ai_inttrig(comedi_device * dev, comedi_subdevice * s,
+static int s626_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trignum)
{
if (trignum != 0)
@@ -1646,7 +1662,7 @@ static int s626_ai_inttrig(comedi_device * dev, comedi_subdevice * s,
DEBUG("s626_ai_inttrig: trigger adc start...");
- // Start executing the RPS program.
+ /* Start executing the RPS program. */
MC_ENABLE(P_MC1, MC1_ERPS1);
s->async->inttrig = NULL;
@@ -1657,12 +1673,12 @@ static int s626_ai_inttrig(comedi_device * dev, comedi_subdevice * s,
}
/* TO COMPLETE */
-static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
+static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
uint8_t ppl[16];
- comedi_cmd *cmd = &s->async->cmd;
- enc_private *k;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ struct enc_private *k;
int tick;
DEBUG("s626_ai_cmd: entering command function\n");
@@ -1672,20 +1688,20 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
dev->minor);
return -EBUSY;
}
- //disable interrupt
+ /* disable interrupt */
writel(0, devpriv->base_addr + P_IER);
- //clear interrupt request
+ /* clear interrupt request */
writel(IRQ_RPS1 | IRQ_GPIO3, devpriv->base_addr + P_ISR);
- //clear any pending interrupt
+ /* clear any pending interrupt */
s626_dio_clear_irq(dev);
- // s626_enc_clear_irq(dev);
+ /* s626_enc_clear_irq(dev); */
- //reset ai_cmd_running flag
+ /* reset ai_cmd_running flag */
devpriv->ai_cmd_running = 0;
- // test if cmd is valid
+ /* test if cmd is valid */
if (cmd == NULL) {
DEBUG("s626_ai_cmd: NULL command\n");
return -EINVAL;
@@ -1707,12 +1723,12 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
case TRIG_FOLLOW:
break;
case TRIG_TIMER:
- // set a conter to generate adc trigger at scan_begin_arg interval
+ /* set a conter to generate adc trigger at scan_begin_arg interval */
k = &encpriv[5];
tick = s626_ns_to_timer((int *)&cmd->scan_begin_arg,
cmd->flags & TRIG_ROUND_MASK);
- //load timer value and enable interrupt
+ /* load timer value and enable interrupt */
s626_timer_load(dev, k, tick);
k->SetEnable(dev, k, CLKENAB_ALWAYS);
@@ -1721,7 +1737,7 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
break;
case TRIG_EXT:
- // set the digital line and interrupt for scan trigger
+ /* set the digital line and interrupt for scan trigger */
if (cmd->start_src != TRIG_EXT)
s626_dio_set_irq(dev, cmd->scan_begin_arg);
@@ -1734,19 +1750,19 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
case TRIG_NOW:
break;
case TRIG_TIMER:
- // set a conter to generate adc trigger at convert_arg interval
+ /* set a conter to generate adc trigger at convert_arg interval */
k = &encpriv[4];
tick = s626_ns_to_timer((int *)&cmd->convert_arg,
cmd->flags & TRIG_ROUND_MASK);
- //load timer value and enable interrupt
+ /* load timer value and enable interrupt */
s626_timer_load(dev, k, tick);
k->SetEnable(dev, k, CLKENAB_INDEX);
DEBUG("s626_ai_cmd: convert trigger timer is set with value %d\n", tick);
break;
case TRIG_EXT:
- // set the digital line and interrupt for convert trigger
+ /* set the digital line and interrupt for convert trigger */
if (cmd->scan_begin_src != TRIG_EXT
&& cmd->start_src == TRIG_EXT)
s626_dio_set_irq(dev, cmd->convert_arg);
@@ -1758,12 +1774,12 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
switch (cmd->stop_src) {
case TRIG_COUNT:
- // data arrives as one packet
+ /* data arrives as one packet */
devpriv->ai_sample_count = cmd->stop_arg;
devpriv->ai_continous = 0;
break;
case TRIG_NONE:
- // continous aquisition
+ /* continous aquisition */
devpriv->ai_continous = 1;
devpriv->ai_sample_count = 0;
break;
@@ -1773,17 +1789,17 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
switch (cmd->start_src) {
case TRIG_NOW:
- // Trigger ADC scan loop start by setting RPS Signal 0.
- // MC_ENABLE( P_MC2, MC2_ADC_RPS );
+ /* Trigger ADC scan loop start by setting RPS Signal 0. */
+ /* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */
- // Start executing the RPS program.
+ /* Start executing the RPS program. */
MC_ENABLE(P_MC1, MC1_ERPS1);
DEBUG("s626_ai_cmd: ADC triggered\n");
s->async->inttrig = NULL;
break;
case TRIG_EXT:
- //configure DIO channel for acquisition trigger
+ /* configure DIO channel for acquisition trigger */
s626_dio_set_irq(dev, cmd->start_arg);
DEBUG("s626_ai_cmd: External start trigger is set!!!\n");
@@ -1795,7 +1811,7 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
break;
}
- //enable interrupt
+ /* enable interrupt */
writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER);
DEBUG("s626_ai_cmd: command function terminated\n");
@@ -1803,8 +1819,8 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
return 0;
}
-static int s626_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,
- comedi_cmd * cmd)
+static int s626_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
int err = 0;
int tmp;
@@ -1988,12 +2004,12 @@ static int s626_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,
return 0;
}
-static int s626_ai_cancel(comedi_device * dev, comedi_subdevice * s)
+static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
- // Stop RPS program in case it is currently running.
+ /* Stop RPS program in case it is currently running. */
MC_DISABLE(P_MC1, MC1_ERPS1);
- //disable master interrupt
+ /* disable master interrupt */
writel(0, devpriv->base_addr + P_IER);
devpriv->ai_cmd_running = 0;
@@ -2010,7 +2026,7 @@ static int s626_ns_to_timer(int *nanosec, int round_mode)
{
int divider, base;
- base = 500; //2MHz internal clock
+ base = 500; /* 2MHz internal clock */
switch (round_mode) {
case TRIG_ROUND_NEAREST:
@@ -2029,8 +2045,8 @@ static int s626_ns_to_timer(int *nanosec, int round_mode)
return divider - 1;
}
-static int s626_ao_winsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i;
@@ -2048,45 +2064,42 @@ static int s626_ao_winsn(comedi_device * dev, comedi_subdevice * s,
return i;
}
-static int s626_ao_rinsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i;
- for (i = 0; i < insn->n; i++) {
+ for (i = 0; i < insn->n; i++)
data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
- }
return i;
}
-/////////////////////////////////////////////////////////////////////
-/////////////// DIGITAL I/O FUNCTIONS /////////////////////////////
-/////////////////////////////////////////////////////////////////////
-// All DIO functions address a group of DIO channels by means of
-// "group" argument. group may be 0, 1 or 2, which correspond to DIO
-// ports A, B and C, respectively.
-/////////////////////////////////////////////////////////////////////
+/* *************** DIGITAL I/O FUNCTIONS ***************
+ * All DIO functions address a group of DIO channels by means of
+ * "group" argument. group may be 0, 1 or 2, which correspond to DIO
+ * ports A, B and C, respectively.
+ */
-static void s626_dio_init(comedi_device * dev)
+static void s626_dio_init(struct comedi_device *dev)
{
uint16_t group;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
- // Prepare to treat writes to WRCapSel as capture disables.
+ /* Prepare to treat writes to WRCapSel as capture disables. */
DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
- // For each group of sixteen channels ...
+ /* For each group of sixteen channels ... */
for (group = 0; group < S626_DIO_BANKS; group++) {
s = dev->subdevices + 2 + group;
- DEBIwrite(dev, diopriv->WRIntSel, 0); // Disable all interrupts.
- DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF); // Disable all event
- // captures.
- DEBIwrite(dev, diopriv->WREdgSel, 0); // Init all DIOs to
- // default edge
- // polarity.
- DEBIwrite(dev, diopriv->WRDOut, 0); // Program all outputs
- // to inactive state.
+ DEBIwrite(dev, diopriv->WRIntSel, 0); /* Disable all interrupts. */
+ DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF); /* Disable all event */
+ /* captures. */
+ DEBIwrite(dev, diopriv->WREdgSel, 0); /* Init all DIOs to */
+ /* default edge */
+ /* polarity. */
+ DEBIwrite(dev, diopriv->WRDOut, 0); /* Program all outputs */
+ /* to inactive state. */
}
DEBUG("s626_dio_init: DIO initialized \n");
}
@@ -2097,14 +2110,14 @@ static void s626_dio_init(comedi_device * dev)
* This allows packed reading/writing of the DIO channels. The comedi
* core can convert between insn_bits and insn_read/write */
-static int s626_dio_insn_bits(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
/* Length of data must be 2 (mask and new data, see below) */
- if (insn->n == 0) {
+ if (insn->n == 0)
return 0;
- }
+
if (insn->n != 2) {
printk("comedi%d: s626: s626_dio_insn_bits(): Invalid instruction length\n", dev->minor);
return -EINVAL;
@@ -2133,8 +2146,8 @@ static int s626_dio_insn_bits(comedi_device * dev, comedi_subdevice * s,
return 2;
}
-static int s626_dio_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
switch (data[0]) {
@@ -2160,75 +2173,75 @@ static int s626_dio_insn_config(comedi_device * dev, comedi_subdevice * s,
return 1;
}
-static int s626_dio_set_irq(comedi_device * dev, unsigned int chan)
+static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan)
{
unsigned int group;
unsigned int bitmask;
unsigned int status;
- //select dio bank
+ /* select dio bank */
group = chan / 16;
bitmask = 1 << (chan - (16 * group));
DEBUG("s626_dio_set_irq: enable interrupt on dio channel %d group %d\n",
chan - (16 * group), group);
- //set channel to capture positive edge
+ /* set channel to capture positive edge */
status = DEBIread(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->RDEdgSel);
DEBIwrite(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->WREdgSel, bitmask | status);
- //enable interrupt on selected channel
+ /* enable interrupt on selected channel */
status = DEBIread(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->RDIntSel);
DEBIwrite(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->WRIntSel, bitmask | status);
- //enable edge capture write command
+ /* enable edge capture write command */
DEBIwrite(dev, LP_MISC1, MISC1_EDCAP);
- //enable edge capture on selected channel
+ /* enable edge capture on selected channel */
status = DEBIread(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->RDCapSel);
DEBIwrite(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->WRCapSel, bitmask | status);
return 0;
}
-static int s626_dio_reset_irq(comedi_device * dev, unsigned int group,
+static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group,
unsigned int mask)
{
DEBUG("s626_dio_reset_irq: disable interrupt on dio channel %d group %d\n", mask, group);
- //disable edge capture write command
+ /* disable edge capture write command */
DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
- //enable edge capture on selected channel
+ /* enable edge capture on selected channel */
DEBIwrite(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->WRCapSel, mask);
return 0;
}
-static int s626_dio_clear_irq(comedi_device * dev)
+static int s626_dio_clear_irq(struct comedi_device *dev)
{
unsigned int group;
- //disable edge capture write command
+ /* disable edge capture write command */
DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
for (group = 0; group < S626_DIO_BANKS; group++) {
- //clear pending events and interrupt
+ /* clear pending events and interrupt */
DEBIwrite(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->WRCapSel, 0xffff);
}
@@ -2238,26 +2251,26 @@ static int s626_dio_clear_irq(comedi_device * dev)
/* Now this function initializes the value of the counter (data[0])
and set the subdevice. To complete with trigger and interrupt
configuration */
-static int s626_enc_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_enc_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
- uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | // Preload upon
- // index.
- (INDXSRC_SOFT << BF_INDXSRC) | // Disable hardware index.
- (CLKSRC_COUNTER << BF_CLKSRC) | // Operating mode is Counter.
- (CLKPOL_POS << BF_CLKPOL) | // Active high clock.
- //( CNTDIR_UP << BF_CLKPOL ) | // Count direction is Down.
- (CLKMULT_1X << BF_CLKMULT) | // Clock multiplier is 1x.
+ uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */
+ /* index. */
+ (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */
+ (CLKSRC_COUNTER << BF_CLKSRC) | /* Operating mode is Counter. */
+ (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */
+ /* ( CNTDIR_UP << BF_CLKPOL ) | // Count direction is Down. */
+ (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */
(CLKENAB_INDEX << BF_CLKENAB);
/* uint16_t DisableIntSrc=TRUE; */
- // uint32_t Preloadvalue; //Counter initial value
+ /* uint32_t Preloadvalue; //Counter initial value */
uint16_t valueSrclatch = LATCHSRC_AB_READ;
uint16_t enab = CLKENAB_ALWAYS;
- enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
+ struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
DEBUG("s626_enc_insn_config: encoder config\n");
- // (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]);
+ /* (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */
k->SetMode(dev, k, Setup, TRUE);
Preload(dev, k, *(insn->data));
@@ -2268,12 +2281,12 @@ static int s626_enc_insn_config(comedi_device * dev, comedi_subdevice * s,
return insn->n;
}
-static int s626_enc_insn_read(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_enc_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n;
- enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
+ struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
DEBUG("s626_enc_insn_read: encoder read channel %d \n",
CR_CHAN(insn->chanspec));
@@ -2286,20 +2299,20 @@ static int s626_enc_insn_read(comedi_device * dev, comedi_subdevice * s,
return n;
}
-static int s626_enc_insn_write(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_enc_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
- enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
+ struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
DEBUG("s626_enc_insn_write: encoder write channel %d \n",
CR_CHAN(insn->chanspec));
- // Set the preload register
+ /* Set the preload register */
Preload(dev, k, data[0]);
- // Software index pulse forces the preload register to load
- // into the counter
+ /* Software index pulse forces the preload register to load */
+ /* into the counter */
k->SetLoadTrig(dev, k, 0);
k->PulseIndex(dev, k);
k->SetLoadTrig(dev, k, 2);
@@ -2309,175 +2322,165 @@ static int s626_enc_insn_write(comedi_device * dev, comedi_subdevice * s,
return 1;
}
-static void s626_timer_load(comedi_device * dev, enc_private * k, int tick)
+static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, int tick)
{
- uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | // Preload upon
- // index.
- (INDXSRC_SOFT << BF_INDXSRC) | // Disable hardware index.
- (CLKSRC_TIMER << BF_CLKSRC) | // Operating mode is Timer.
- (CLKPOL_POS << BF_CLKPOL) | // Active high clock.
- (CNTDIR_DOWN << BF_CLKPOL) | // Count direction is Down.
- (CLKMULT_1X << BF_CLKMULT) | // Clock multiplier is 1x.
+ uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */
+ /* index. */
+ (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */
+ (CLKSRC_TIMER << BF_CLKSRC) | /* Operating mode is Timer. */
+ (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */
+ (CNTDIR_DOWN << BF_CLKPOL) | /* Count direction is Down. */
+ (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */
(CLKENAB_INDEX << BF_CLKENAB);
uint16_t valueSrclatch = LATCHSRC_A_INDXA;
- // uint16_t enab=CLKENAB_ALWAYS;
+ /* uint16_t enab=CLKENAB_ALWAYS; */
k->SetMode(dev, k, Setup, FALSE);
- // Set the preload register
+ /* Set the preload register */
Preload(dev, k, tick);
- // Software index pulse forces the preload register to load
- // into the counter
+ /* Software index pulse forces the preload register to load */
+ /* into the counter */
k->SetLoadTrig(dev, k, 0);
k->PulseIndex(dev, k);
- //set reload on counter overflow
+ /* set reload on counter overflow */
k->SetLoadTrig(dev, k, 1);
- //set interrupt on overflow
+ /* set interrupt on overflow */
k->SetIntSrc(dev, k, INTSRC_OVER);
SetLatchSource(dev, k, valueSrclatch);
- // k->SetEnable(dev,k,(uint16_t)(enab != 0));
+ /* k->SetEnable(dev,k,(uint16_t)(enab != 0)); */
}
-///////////////////////////////////////////////////////////////////////
-///////////////////// DAC FUNCTIONS /////////////////////////////////
-///////////////////////////////////////////////////////////////////////
+/* *********** DAC FUNCTIONS *********** */
-// Slot 0 base settings.
-#define VECT0 ( XSD2 | RSD3 | SIB_A2 ) // Slot 0 always shifts in
- // 0xFF and store it to
- // FB_BUFFER2.
+/* Slot 0 base settings. */
+#define VECT0 (XSD2 | RSD3 | SIB_A2)
+/* Slot 0 always shifts in 0xFF and store it to FB_BUFFER2. */
-// TrimDac LogicalChan-to-PhysicalChan mapping table.
+/* TrimDac LogicalChan-to-PhysicalChan mapping table. */
static uint8_t trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 };
-// TrimDac LogicalChan-to-EepromAdrs mapping table.
+/* TrimDac LogicalChan-to-EepromAdrs mapping table. */
static uint8_t trimadrs[] =
{ 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 };
-static void LoadTrimDACs(comedi_device * dev)
+static void LoadTrimDACs(struct comedi_device *dev)
{
register uint8_t i;
- // Copy TrimDac setpoint values from EEPROM to TrimDacs.
+ /* Copy TrimDac setpoint values from EEPROM to TrimDacs. */
for (i = 0; i < (sizeof(trimchan) / sizeof(trimchan[0])); i++)
WriteTrimDAC(dev, i, I2Cread(dev, trimadrs[i]));
}
-static void WriteTrimDAC(comedi_device * dev, uint8_t LogicalChan,
+static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
uint8_t DacData)
{
uint32_t chan;
- // Save the new setpoint in case the application needs to read it back later.
+ /* Save the new setpoint in case the application needs to read it back later. */
devpriv->TrimSetpoint[LogicalChan] = (uint8_t) DacData;
- // Map logical channel number to physical channel number.
+ /* Map logical channel number to physical channel number. */
chan = (uint32_t) trimchan[LogicalChan];
- // Set up TSL2 records for TrimDac write operation. All slots shift
- // 0xFF in from pulled-up SD3 so that the end of the slot sequence
- // can be detected.
- SETVECT(2, XSD2 | XFIFO_1 | WS3); // Slot 2: Send high uint8_t
- // to target TrimDac.
- SETVECT(3, XSD2 | XFIFO_0 | WS3); // Slot 3: Send low uint8_t to
- // target TrimDac.
- SETVECT(4, XSD2 | XFIFO_3 | WS1); // Slot 4: Send NOP high
- // uint8_t to DAC0 to keep
- // clock running.
- SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS); // Slot 5: Send NOP low
- // uint8_t to DAC0.
-
- // Construct and transmit target DAC's serial packet: ( 0000 AAAA
- // ),( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the DAC
- // channel's address, and D<7:0> is the DAC setpoint. Append a WORD
- // value (that writes a channel 0 NOP command to a non-existent main
- // DAC channel) that serves to keep the clock running after the
- // packet has been sent to the target DAC.
-
- SendDAC(dev, ((uint32_t) chan << 8) // Address the DAC channel
- // within the trimdac device.
- | (uint32_t) DacData); // Include DAC setpoint data.
-}
+ /* Set up TSL2 records for TrimDac write operation. All slots shift
+ * 0xFF in from pulled-up SD3 so that the end of the slot sequence
+ * can be detected.
+ */
-/////////////////////////////////////////////////////////////////////////
-//////////////// EEPROM ACCESS FUNCTIONS //////////////////////////////
-/////////////////////////////////////////////////////////////////////////
+ SETVECT(2, XSD2 | XFIFO_1 | WS3);
+ /* Slot 2: Send high uint8_t to target TrimDac. */
+ SETVECT(3, XSD2 | XFIFO_0 | WS3);
+ /* Slot 3: Send low uint8_t to target TrimDac. */
+ SETVECT(4, XSD2 | XFIFO_3 | WS1);
+ /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running. */
+ SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS);
+ /* Slot 5: Send NOP low uint8_t to DAC0. */
+
+ /* Construct and transmit target DAC's serial packet:
+ * ( 0000 AAAA ), ( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the
+ * DAC channel's address, and D<7:0> is the DAC setpoint. Append a
+ * WORD value (that writes a channel 0 NOP command to a non-existent
+ * main DAC channel) that serves to keep the clock running after the
+ * packet has been sent to the target DAC.
+ */
+
+ /* Address the DAC channel within the trimdac device. */
+ SendDAC(dev, ((uint32_t) chan << 8)
+ | (uint32_t) DacData); /* Include DAC setpoint data. */
+}
-///////////////////////////////////////////
-// Read uint8_t from EEPROM.
+/* ************** EEPROM ACCESS FUNCTIONS ************** */
+/* Read uint8_t from EEPROM. */
-static uint8_t I2Cread(comedi_device * dev, uint8_t addr)
+static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr)
{
uint8_t rtnval;
- // Send EEPROM target address.
- if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW) // Byte2 = I2C
- // command:
- // write to
- // I2C EEPROM
- // device.
- | I2C_B1(I2C_ATTRSTOP, addr) // Byte1 = EEPROM
- // internal target
- // address.
- | I2C_B0(I2C_ATTRNOP, 0))) // Byte0 = Not
- // sent.
- {
- // Abort function and declare error if handshake failed.
+ /* Send EEPROM target address. */
+ if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW)
+ /* Byte2 = I2C command: write to I2C EEPROM device. */
+ | I2C_B1(I2C_ATTRSTOP, addr)
+ /* Byte1 = EEPROM internal target address. */
+ | I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */
+ /* Abort function and declare error if handshake failed. */
DEBUG("I2Cread: error handshake I2Cread a\n");
return 0;
}
- // Execute EEPROM read.
- if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR) // Byte2 = I2C
- // command: read
- // from I2C EEPROM
- // device.
- | I2C_B1(I2C_ATTRSTOP, 0) // Byte1 receives
- // uint8_t from
- // EEPROM.
- | I2C_B0(I2C_ATTRNOP, 0))) // Byte0 = Not
- // sent.
- {
- // Abort function and declare error if handshake failed.
+ /* Execute EEPROM read. */
+ if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR) /* Byte2 = I2C */
+ /* command: read */
+ /* from I2C EEPROM */
+ /* device. */
+ | I2C_B1(I2C_ATTRSTOP, 0) /* Byte1 receives */
+ /* uint8_t from */
+ /* EEPROM. */
+ | I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */
+
+ /* Abort function and declare error if handshake failed. */
DEBUG("I2Cread: error handshake I2Cread b\n");
return 0;
}
- // Return copy of EEPROM value.
+ /* Return copy of EEPROM value. */
rtnval = (uint8_t) (RR7146(P_I2CCTRL) >> 16);
return rtnval;
}
-static uint32_t I2Chandshake(comedi_device * dev, uint32_t val)
+static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val)
{
- // Write I2C command to I2C Transfer Control shadow register.
+ /* Write I2C command to I2C Transfer Control shadow register. */
WR7146(P_I2CCTRL, val);
- // Upload I2C shadow registers into working registers and wait for
- // upload confirmation.
+ /* Upload I2C shadow registers into working registers and wait for */
+ /* upload confirmation. */
MC_ENABLE(P_MC2, MC2_UPLD_IIC);
- while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) ;
+ while (!MC_TEST(P_MC2, MC2_UPLD_IIC))
+ ;
- // Wait until I2C bus transfer is finished or an error occurs.
- while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY) ;
+ /* Wait until I2C bus transfer is finished or an error occurs. */
+ while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY)
+ ;
- // Return non-zero if I2C error occured.
+ /* Return non-zero if I2C error occured. */
return RR7146(P_I2CCTRL) & I2C_ERR;
}
-// Private helper function: Write setpoint to an application DAC channel.
+/* Private helper function: Write setpoint to an application DAC channel. */
-static void SetDAC(comedi_device * dev, uint16_t chan, short dacdata)
+static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata)
{
register uint16_t signmask;
register uint32_t WSImage;
- // Adjust DAC data polarity and set up Polarity Control Register
- // image.
+ /* Adjust DAC data polarity and set up Polarity Control Register */
+ /* image. */
signmask = 1 << chan;
if (dacdata < 0) {
dacdata = -dacdata;
@@ -2485,237 +2488,252 @@ static void SetDAC(comedi_device * dev, uint16_t chan, short dacdata)
} else
devpriv->Dacpol &= ~signmask;
- // Limit DAC setpoint value to valid range.
+ /* Limit DAC setpoint value to valid range. */
if ((uint16_t) dacdata > 0x1FFF)
dacdata = 0x1FFF;
- // Set up TSL2 records (aka "vectors") for DAC update. Vectors V2
- // and V3 transmit the setpoint to the target DAC. V4 and V5 send
- // data to a non-existent TrimDac channel just to keep the clock
- // running after sending data to the target DAC. This is necessary
- // to eliminate the clock glitch that would otherwise occur at the
- // end of the target DAC's serial data stream. When the sequence
- // restarts at V0 (after executing V5), the gate array automatically
- // disables gating for the DAC clock and all DAC chip selects.
- WSImage = (chan & 2) ? WS1 : WS2; // Choose DAC chip select to
- // be asserted.
- SETVECT(2, XSD2 | XFIFO_1 | WSImage); // Slot 2: Transmit high
- // data byte to target DAC.
- SETVECT(3, XSD2 | XFIFO_0 | WSImage); // Slot 3: Transmit low data
- // byte to target DAC.
- SETVECT(4, XSD2 | XFIFO_3 | WS3); // Slot 4: Transmit to
- // non-existent TrimDac
- // channel to keep clock
- SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS); // Slot 5: running after
- // writing target DAC's
- // low data byte.
-
- // Construct and transmit target DAC's serial packet: ( A10D DDDD
- // ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>, and D<12:0>
- // is the DAC setpoint. Append a WORD value (that writes to a
- // non-existent TrimDac channel) that serves to keep the clock
- // running after the packet has been sent to the target DAC.
- SendDAC(dev, 0x0F000000 //Continue clock after target DAC
- //data (write to non-existent
- //trimdac).
- | 0x00004000 // Address the two main dual-DAC
- // devices (TSL's chip select enables
- // target device).
- | ((uint32_t) (chan & 1) << 15) // Address the DAC
- // channel within the
- // device.
- | (uint32_t) dacdata); // Include DAC setpoint data.
+ /* Set up TSL2 records (aka "vectors") for DAC update. Vectors V2
+ * and V3 transmit the setpoint to the target DAC. V4 and V5 send
+ * data to a non-existent TrimDac channel just to keep the clock
+ * running after sending data to the target DAC. This is necessary
+ * to eliminate the clock glitch that would otherwise occur at the
+ * end of the target DAC's serial data stream. When the sequence
+ * restarts at V0 (after executing V5), the gate array automatically
+ * disables gating for the DAC clock and all DAC chip selects.
+ */
+
+ WSImage = (chan & 2) ? WS1 : WS2;
+ /* Choose DAC chip select to be asserted. */
+ SETVECT(2, XSD2 | XFIFO_1 | WSImage);
+ /* Slot 2: Transmit high data byte to target DAC. */
+ SETVECT(3, XSD2 | XFIFO_0 | WSImage);
+ /* Slot 3: Transmit low data byte to target DAC. */
+ SETVECT(4, XSD2 | XFIFO_3 | WS3);
+ /* Slot 4: Transmit to non-existent TrimDac channel to keep clock */
+ SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS);
+ /* Slot 5: running after writing target DAC's low data byte. */
+
+ /* Construct and transmit target DAC's serial packet:
+ * ( A10D DDDD ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>,
+ * and D<12:0> is the DAC setpoint. Append a WORD value (that writes
+ * to a non-existent TrimDac channel) that serves to keep the clock
+ * running after the packet has been sent to the target DAC.
+ */
+ SendDAC(dev, 0x0F000000
+ /* Continue clock after target DAC data (write to non-existent trimdac). */
+ | 0x00004000
+ /* Address the two main dual-DAC devices (TSL's chip select enables
+ * target device). */
+ | ((uint32_t) (chan & 1) << 15)
+ /* Address the DAC channel within the device. */
+ | (uint32_t) dacdata); /* Include DAC setpoint data. */
}
-////////////////////////////////////////////////////////
-// Private helper function: Transmit serial data to DAC via Audio
-// channel 2. Assumes: (1) TSL2 slot records initialized, and (2)
-// Dacpol contains valid target image.
+/* Private helper function: Transmit serial data to DAC via Audio
+ * channel 2. Assumes: (1) TSL2 slot records initialized, and (2)
+ * Dacpol contains valid target image.
+ */
-static void SendDAC(comedi_device * dev, uint32_t val)
+static void SendDAC(struct comedi_device *dev, uint32_t val)
{
- // START THE SERIAL CLOCK RUNNING -------------
+ /* START THE SERIAL CLOCK RUNNING ------------- */
- // Assert DAC polarity control and enable gating of DAC serial clock
- // and audio bit stream signals. At this point in time we must be
- // assured of being in time slot 0. If we are not in slot 0, the
- // serial clock and audio stream signals will be disabled; this is
- // because the following DEBIwrite statement (which enables signals
- // to be passed through the gate array) would execute before the
- // trailing edge of WS1/WS3 (which turns off the signals), thus
- // causing the signals to be inactive during the DAC write.
+ /* Assert DAC polarity control and enable gating of DAC serial clock
+ * and audio bit stream signals. At this point in time we must be
+ * assured of being in time slot 0. If we are not in slot 0, the
+ * serial clock and audio stream signals will be disabled; this is
+ * because the following DEBIwrite statement (which enables signals
+ * to be passed through the gate array) would execute before the
+ * trailing edge of WS1/WS3 (which turns off the signals), thus
+ * causing the signals to be inactive during the DAC write.
+ */
DEBIwrite(dev, LP_DACPOL, devpriv->Dacpol);
- // TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ----------------
+ /* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */
- // Copy DAC setpoint value to DAC's output DMA buffer.
+ /* Copy DAC setpoint value to DAC's output DMA buffer. */
- //WR7146( (uint32_t)devpriv->pDacWBuf, val );
+ /* WR7146( (uint32_t)devpriv->pDacWBuf, val ); */
*devpriv->pDacWBuf = val;
- // enab the output DMA transfer. This will cause the DMAC to copy
- // the DAC's data value to A2's output FIFO. The DMA transfer will
- // then immediately terminate because the protection address is
- // reached upon transfer of the first DWORD value.
+ /* enab the output DMA transfer. This will cause the DMAC to copy
+ * the DAC's data value to A2's output FIFO. The DMA transfer will
+ * then immediately terminate because the protection address is
+ * reached upon transfer of the first DWORD value.
+ */
MC_ENABLE(P_MC1, MC1_A2OUT);
- // While the DMA transfer is executing ...
+ /* While the DMA transfer is executing ... */
- // Reset Audio2 output FIFO's underflow flag (along with any other
- // FIFO underflow/overflow flags). When set, this flag will
- // indicate that we have emerged from slot 0.
+ /* Reset Audio2 output FIFO's underflow flag (along with any other
+ * FIFO underflow/overflow flags). When set, this flag will
+ * indicate that we have emerged from slot 0.
+ */
WR7146(P_ISR, ISR_AFOU);
- // Wait for the DMA transfer to finish so that there will be data
- // available in the FIFO when time slot 1 tries to transfer a DWORD
- // from the FIFO to the output buffer register. We test for DMA
- // Done by polling the DMAC enable flag; this flag is automatically
- // cleared when the transfer has finished.
- while ((RR7146(P_MC1) & MC1_A2OUT) != 0) ;
+ /* Wait for the DMA transfer to finish so that there will be data
+ * available in the FIFO when time slot 1 tries to transfer a DWORD
+ * from the FIFO to the output buffer register. We test for DMA
+ * Done by polling the DMAC enable flag; this flag is automatically
+ * cleared when the transfer has finished.
+ */
+ while ((RR7146(P_MC1) & MC1_A2OUT) != 0)
+ ;
- // START THE OUTPUT STREAM TO THE TARGET DAC --------------------
+ /* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */
- // FIFO data is now available, so we enable execution of time slots
- // 1 and higher by clearing the EOS flag in slot 0. Note that SD3
- // will be shifted in and stored in FB_BUFFER2 for end-of-slot-list
- // detection.
+ /* FIFO data is now available, so we enable execution of time slots
+ * 1 and higher by clearing the EOS flag in slot 0. Note that SD3
+ * will be shifted in and stored in FB_BUFFER2 for end-of-slot-list
+ * detection.
+ */
SETVECT(0, XSD2 | RSD3 | SIB_A2);
- // Wait for slot 1 to execute to ensure that the Packet will be
- // transmitted. This is detected by polling the Audio2 output FIFO
- // underflow flag, which will be set when slot 1 execution has
- // finished transferring the DAC's data DWORD from the output FIFO
- // to the output buffer register.
- while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0) ;
-
- // Set up to trap execution at slot 0 when the TSL sequencer cycles
- // back to slot 0 after executing the EOS in slot 5. Also,
- // simultaneously shift out and in the 0x00 that is ALWAYS the value
- // stored in the last byte to be shifted out of the FIFO's DWORD
- // buffer register.
+ /* Wait for slot 1 to execute to ensure that the Packet will be
+ * transmitted. This is detected by polling the Audio2 output FIFO
+ * underflow flag, which will be set when slot 1 execution has
+ * finished transferring the DAC's data DWORD from the output FIFO
+ * to the output buffer register.
+ */
+ while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0)
+ ;
+
+ /* Set up to trap execution at slot 0 when the TSL sequencer cycles
+ * back to slot 0 after executing the EOS in slot 5. Also,
+ * simultaneously shift out and in the 0x00 that is ALWAYS the value
+ * stored in the last byte to be shifted out of the FIFO's DWORD
+ * buffer register.
+ */
SETVECT(0, XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS);
- // WAIT FOR THE TRANSACTION TO FINISH -----------------------
-
- // Wait for the TSL to finish executing all time slots before
- // exiting this function. We must do this so that the next DAC
- // write doesn't start, thereby enabling clock/chip select signals:
- // 1. Before the TSL sequence cycles back to slot 0, which disables
- // the clock/cs signal gating and traps slot // list execution. If
- // we have not yet finished slot 5 then the clock/cs signals are
- // still gated and we have // not finished transmitting the stream.
- // 2. While slots 2-5 are executing due to a late slot 0 trap. In
- // this case, the slot sequence is currently // repeating, but with
- // clock/cs signals disabled. We must wait for slot 0 to trap
- // execution before setting // up the next DAC setpoint DMA transfer
- // and enabling the clock/cs signals. To detect the end of slot 5,
- // we test for the FB_BUFFER2 MSB contents to be equal to 0xFF. If
- // the TSL has not yet finished executing slot 5 ...
+ /* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */
+
+ /* Wait for the TSL to finish executing all time slots before
+ * exiting this function. We must do this so that the next DAC
+ * write doesn't start, thereby enabling clock/chip select signals:
+ *
+ * 1. Before the TSL sequence cycles back to slot 0, which disables
+ * the clock/cs signal gating and traps slot // list execution.
+ * we have not yet finished slot 5 then the clock/cs signals are
+ * still gated and we have not finished transmitting the stream.
+ *
+ * 2. While slots 2-5 are executing due to a late slot 0 trap. In
+ * this case, the slot sequence is currently repeating, but with
+ * clock/cs signals disabled. We must wait for slot 0 to trap
+ * execution before setting up the next DAC setpoint DMA transfer
+ * and enabling the clock/cs signals. To detect the end of slot 5,
+ * we test for the FB_BUFFER2 MSB contents to be equal to 0xFF. If
+ * the TSL has not yet finished executing slot 5 ...
+ */
if ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) {
- // The trap was set on time and we are still executing somewhere
- // in slots 2-5, so we now wait for slot 0 to execute and trap
- // TSL execution. This is detected when FB_BUFFER2 MSB changes
- // from 0xFF to 0x00, which slot 0 causes to happen by shifting
- // out/in on SD2 the 0x00 that is always referenced by slot 5.
- while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) ;
+ /* The trap was set on time and we are still executing somewhere
+ * in slots 2-5, so we now wait for slot 0 to execute and trap
+ * TSL execution. This is detected when FB_BUFFER2 MSB changes
+ * from 0xFF to 0x00, which slot 0 causes to happen by shifting
+ * out/in on SD2 the 0x00 that is always referenced by slot 5.
+ */
+ while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0)
+ ;
}
- // Either (1) we were too late setting the slot 0 trap; the TSL
- // sequencer restarted slot 0 before we could set the EOS trap flag,
- // or (2) we were not late and execution is now trapped at slot 0.
- // In either case, we must now change slot 0 so that it will store
- // value 0xFF (instead of 0x00) to FB_BUFFER2 next time it executes.
- // In order to do this, we reprogram slot 0 so that it will shift in
- // SD3, which is driven only by a pull-up resistor.
+ /* Either (1) we were too late setting the slot 0 trap; the TSL
+ * sequencer restarted slot 0 before we could set the EOS trap flag,
+ * or (2) we were not late and execution is now trapped at slot 0.
+ * In either case, we must now change slot 0 so that it will store
+ * value 0xFF (instead of 0x00) to FB_BUFFER2 next time it executes.
+ * In order to do this, we reprogram slot 0 so that it will shift in
+ * SD3, which is driven only by a pull-up resistor.
+ */
SETVECT(0, RSD3 | SIB_A2 | EOS);
- // Wait for slot 0 to execute, at which time the TSL is setup for
- // the next DAC write. This is detected when FB_BUFFER2 MSB changes
- // from 0x00 to 0xFF.
- while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0) ;
+ /* Wait for slot 0 to execute, at which time the TSL is setup for
+ * the next DAC write. This is detected when FB_BUFFER2 MSB changes
+ * from 0x00 to 0xFF.
+ */
+ while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0)
+ ;
}
-static void WriteMISC2(comedi_device * dev, uint16_t NewImage)
+static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage)
{
- DEBIwrite(dev, LP_MISC1, MISC1_WENABLE); // enab writes to
- // MISC2 register.
- DEBIwrite(dev, LP_WRMISC2, NewImage); // Write new image to MISC2.
- DEBIwrite(dev, LP_MISC1, MISC1_WDISABLE); // Disable writes to MISC2.
+ DEBIwrite(dev, LP_MISC1, MISC1_WENABLE); /* enab writes to */
+ /* MISC2 register. */
+ DEBIwrite(dev, LP_WRMISC2, NewImage); /* Write new image to MISC2. */
+ DEBIwrite(dev, LP_MISC1, MISC1_WDISABLE); /* Disable writes to MISC2. */
}
-/////////////////////////////////////////////////////////////////////
-// Initialize the DEBI interface for all transfers.
+/* Initialize the DEBI interface for all transfers. */
-static uint16_t DEBIread(comedi_device * dev, uint16_t addr)
+static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr)
{
uint16_t retval;
- // Set up DEBI control register value in shadow RAM.
+ /* Set up DEBI control register value in shadow RAM. */
WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);
- // Execute the DEBI transfer.
+ /* Execute the DEBI transfer. */
DEBItransfer(dev);
- // Fetch target register value.
+ /* Fetch target register value. */
retval = (uint16_t) RR7146(P_DEBIAD);
- // Return register value.
+ /* Return register value. */
return retval;
}
-// Execute a DEBI transfer. This must be called from within a
-// critical section.
-static void DEBItransfer(comedi_device * dev)
+/* Execute a DEBI transfer. This must be called from within a */
+/* critical section. */
+static void DEBItransfer(struct comedi_device *dev)
{
- // Initiate upload of shadow RAM to DEBI control register.
+ /* Initiate upload of shadow RAM to DEBI control register. */
MC_ENABLE(P_MC2, MC2_UPLD_DEBI);
- // Wait for completion of upload from shadow RAM to DEBI control
- // register.
- while (!MC_TEST(P_MC2, MC2_UPLD_DEBI)) ;
+ /* Wait for completion of upload from shadow RAM to DEBI control */
+ /* register. */
+ while (!MC_TEST(P_MC2, MC2_UPLD_DEBI))
+ ;
- // Wait until DEBI transfer is done.
- while (RR7146(P_PSR) & PSR_DEBI_S) ;
+ /* Wait until DEBI transfer is done. */
+ while (RR7146(P_PSR) & PSR_DEBI_S)
+ ;
}
-// Write a value to a gate array register.
-static void DEBIwrite(comedi_device * dev, uint16_t addr, uint16_t wdata)
+/* Write a value to a gate array register. */
+static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata)
{
- // Set up DEBI control register value in shadow RAM.
+ /* Set up DEBI control register value in shadow RAM. */
WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);
WR7146(P_DEBIAD, wdata);
- // Execute the DEBI transfer.
+ /* Execute the DEBI transfer. */
DEBItransfer(dev);
}
-/////////////////////////////////////////////////////////////////////////////
-// Replace the specified bits in a gate array register. Imports: mask
-// specifies bits that are to be preserved, wdata is new value to be
-// or'd with the masked original.
-static void DEBIreplace(comedi_device * dev, uint16_t addr, uint16_t mask,
+/* Replace the specified bits in a gate array register. Imports: mask
+ * specifies bits that are to be preserved, wdata is new value to be
+ * or'd with the masked original.
+ */
+static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
uint16_t wdata)
{
- // Copy target gate array register into P_DEBIAD register.
- WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); // Set up DEBI control
- // reg value in shadow
- // RAM.
- DEBItransfer(dev); // Execute the DEBI
- // Read transfer.
+ /* Copy target gate array register into P_DEBIAD register. */
+ WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);
+ /* Set up DEBI control reg value in shadow RAM. */
+ DEBItransfer(dev); /* Execute the DEBI Read transfer. */
- // Write back the modified image.
- WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); // Set up DEBI control
- // reg value in shadow
- // RAM.
+ /* Write back the modified image. */
+ WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);
+ /* Set up DEBI control reg value in shadow RAM. */
- WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask)); // Modify the register image.
- DEBItransfer(dev); // Execute the DEBI Write transfer.
+ WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask));
+ /* Modify the register image. */
+ DEBItransfer(dev); /* Execute the DEBI Write transfer. */
}
-static void CloseDMAB(comedi_device * dev, DMABUF * pdma, size_t bsize)
+static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, size_t bsize)
{
void *vbptr;
dma_addr_t vpptr;
@@ -2723,7 +2741,7 @@ static void CloseDMAB(comedi_device * dev, DMABUF * pdma, size_t bsize)
DEBUG("CloseDMAB: Entering S626DRV_CloseDMAB():\n");
if (pdma == NULL)
return;
- //find the matching allocation from the board struct
+ /* find the matching allocation from the board struct */
vbptr = pdma->LogicalBase;
vpptr = pdma->PhysicalBase;
@@ -2737,268 +2755,260 @@ static void CloseDMAB(comedi_device * dev, DMABUF * pdma, size_t bsize)
}
}
-////////////////////////////////////////////////////////////////////////
-///////////////// COUNTER FUNCTIONS //////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-// All counter functions address a specific counter by means of the
-// "Counter" argument, which is a logical counter number. The Counter
-// argument may have any of the following legal values: 0=0A, 1=1A,
-// 2=2A, 3=0B, 4=1B, 5=2B.
-////////////////////////////////////////////////////////////////////////
+/* ****** COUNTER FUNCTIONS ******* */
+/* All counter functions address a specific counter by means of the
+ * "Counter" argument, which is a logical counter number. The Counter
+ * argument may have any of the following legal values: 0=0A, 1=1A,
+ * 2=2A, 3=0B, 4=1B, 5=2B.
+ */
-// Forward declarations for functions that are common to both A and B
-// counters:
+/* Forward declarations for functions that are common to both A and B counters: */
-/////////////////////////////////////////////////////////////////////
-//////////////////// PRIVATE COUNTER FUNCTIONS /////////////////////
-/////////////////////////////////////////////////////////////////////
+/* ****** PRIVATE COUNTER FUNCTIONS ****** */
-/////////////////////////////////////////////////////////////////
-// Read a counter's output latch.
+/* Read a counter's output latch. */
-static uint32_t ReadLatch(comedi_device * dev, enc_private * k)
+static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k)
{
register uint32_t value;
- //DEBUG FIXME DEBUG("ReadLatch: Read Latch enter\n");
+ /* DEBUG FIXME DEBUG("ReadLatch: Read Latch enter\n"); */
- // Latch counts and fetch LSW of latched counts value.
+ /* Latch counts and fetch LSW of latched counts value. */
value = (uint32_t) DEBIread(dev, k->MyLatchLsw);
- // Fetch MSW of latched counts and combine with LSW.
+ /* Fetch MSW of latched counts and combine with LSW. */
value |= ((uint32_t) DEBIread(dev, k->MyLatchLsw + 2) << 16);
- // DEBUG FIXME DEBUG("ReadLatch: Read Latch exit\n");
+ /* DEBUG FIXME DEBUG("ReadLatch: Read Latch exit\n"); */
- // Return latched counts.
+ /* Return latched counts. */
return value;
}
-///////////////////////////////////////////////////////////////////
-// Reset a counter's index and overflow event capture flags.
+/* Reset a counter's index and overflow event capture flags. */
-static void ResetCapFlags_A(comedi_device * dev, enc_private * k)
+static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k)
{
DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
}
-static void ResetCapFlags_B(comedi_device * dev, enc_private * k)
+static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k)
{
DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B);
}
-/////////////////////////////////////////////////////////////////////////
-// Return counter setup in a format (COUNTER_SETUP) that is consistent
-// for both A and B counters.
+/* Return counter setup in a format (COUNTER_SETUP) that is consistent */
+/* for both A and B counters. */
-static uint16_t GetMode_A(comedi_device * dev, enc_private * k)
+static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k)
{
register uint16_t cra;
register uint16_t crb;
register uint16_t setup;
- // Fetch CRA and CRB register images.
+ /* Fetch CRA and CRB register images. */
cra = DEBIread(dev, k->MyCRA);
crb = DEBIread(dev, k->MyCRB);
- // Populate the standardized counter setup bit fields. Note:
- // IndexSrc is restricted to ENC_X or IndxPol.
- setup = ((cra & STDMSK_LOADSRC) // LoadSrc = LoadSrcA.
- | ((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC) // LatchSrc = LatchSrcA.
- | ((cra << (STDBIT_INTSRC - CRABIT_INTSRC_A)) & STDMSK_INTSRC) // IntSrc = IntSrcA.
- | ((cra << (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))) & STDMSK_INDXSRC) // IndxSrc = IndxSrcA<1>.
- | ((cra >> (CRABIT_INDXPOL_A - STDBIT_INDXPOL)) & STDMSK_INDXPOL) // IndxPol = IndxPolA.
- | ((crb >> (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)) & STDMSK_CLKENAB)); // ClkEnab = ClkEnabA.
-
- // Adjust mode-dependent parameters.
- if (cra & (2 << CRABIT_CLKSRC_A)) // If Timer mode (ClkSrcA<1> == 1):
- setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC) // Indicate Timer mode.
- | ((cra << (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) & STDMSK_CLKPOL) // Set ClkPol to indicate count direction (ClkSrcA<0>).
- | (MULT_X1 << STDBIT_CLKMULT)); // ClkMult must be 1x in Timer mode.
-
- else // If Counter mode (ClkSrcA<1> == 0):
- setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC) // Indicate Counter mode.
- | ((cra >> (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) & STDMSK_CLKPOL) // Pass through ClkPol.
- | (((cra & CRAMSK_CLKMULT_A) == (MULT_X0 << CRABIT_CLKMULT_A)) ? // Force ClkMult to 1x if not legal, else pass through.
+ /* Populate the standardized counter setup bit fields. Note: */
+ /* IndexSrc is restricted to ENC_X or IndxPol. */
+ setup = ((cra & STDMSK_LOADSRC) /* LoadSrc = LoadSrcA. */
+ | ((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC) /* LatchSrc = LatchSrcA. */
+ | ((cra << (STDBIT_INTSRC - CRABIT_INTSRC_A)) & STDMSK_INTSRC) /* IntSrc = IntSrcA. */
+ | ((cra << (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))) & STDMSK_INDXSRC) /* IndxSrc = IndxSrcA<1>. */
+ | ((cra >> (CRABIT_INDXPOL_A - STDBIT_INDXPOL)) & STDMSK_INDXPOL) /* IndxPol = IndxPolA. */
+ | ((crb >> (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)) & STDMSK_CLKENAB)); /* ClkEnab = ClkEnabA. */
+
+ /* Adjust mode-dependent parameters. */
+ if (cra & (2 << CRABIT_CLKSRC_A)) /* If Timer mode (ClkSrcA<1> == 1): */
+ setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC) /* Indicate Timer mode. */
+ | ((cra << (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) & STDMSK_CLKPOL) /* Set ClkPol to indicate count direction (ClkSrcA<0>). */
+ | (MULT_X1 << STDBIT_CLKMULT)); /* ClkMult must be 1x in Timer mode. */
+
+ else /* If Counter mode (ClkSrcA<1> == 0): */
+ setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC) /* Indicate Counter mode. */
+ | ((cra >> (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) & STDMSK_CLKPOL) /* Pass through ClkPol. */
+ | (((cra & CRAMSK_CLKMULT_A) == (MULT_X0 << CRABIT_CLKMULT_A)) ? /* Force ClkMult to 1x if not legal, else pass through. */
(MULT_X1 << STDBIT_CLKMULT) :
((cra >> (CRABIT_CLKMULT_A -
STDBIT_CLKMULT)) &
STDMSK_CLKMULT)));
- // Return adjusted counter setup.
+ /* Return adjusted counter setup. */
return setup;
}
-static uint16_t GetMode_B(comedi_device * dev, enc_private * k)
+static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k)
{
register uint16_t cra;
register uint16_t crb;
register uint16_t setup;
- // Fetch CRA and CRB register images.
+ /* Fetch CRA and CRB register images. */
cra = DEBIread(dev, k->MyCRA);
crb = DEBIread(dev, k->MyCRB);
- // Populate the standardized counter setup bit fields. Note:
- // IndexSrc is restricted to ENC_X or IndxPol.
- setup = (((crb << (STDBIT_INTSRC - CRBBIT_INTSRC_B)) & STDMSK_INTSRC) // IntSrc = IntSrcB.
- | ((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC) // LatchSrc = LatchSrcB.
- | ((crb << (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)) & STDMSK_LOADSRC) // LoadSrc = LoadSrcB.
- | ((crb << (STDBIT_INDXPOL - CRBBIT_INDXPOL_B)) & STDMSK_INDXPOL) // IndxPol = IndxPolB.
- | ((crb >> (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) & STDMSK_CLKENAB) // ClkEnab = ClkEnabB.
- | ((cra >> ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)) & STDMSK_INDXSRC)); // IndxSrc = IndxSrcB<1>.
-
- // Adjust mode-dependent parameters.
- if ((crb & CRBMSK_CLKMULT_B) == (MULT_X0 << CRBBIT_CLKMULT_B)) // If Extender mode (ClkMultB == MULT_X0):
- setup |= ((CLKSRC_EXTENDER << STDBIT_CLKSRC) // Indicate Extender mode.
- | (MULT_X1 << STDBIT_CLKMULT) // Indicate multiplier is 1x.
- | ((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL)); // Set ClkPol equal to Timer count direction (ClkSrcB<0>).
-
- else if (cra & (2 << CRABIT_CLKSRC_B)) // If Timer mode (ClkSrcB<1> == 1):
- setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC) // Indicate Timer mode.
- | (MULT_X1 << STDBIT_CLKMULT) // Indicate multiplier is 1x.
- | ((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL)); // Set ClkPol equal to Timer count direction (ClkSrcB<0>).
-
- else // If Counter mode (ClkSrcB<1> == 0):
- setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC) // Indicate Timer mode.
- | ((crb >> (CRBBIT_CLKMULT_B - STDBIT_CLKMULT)) & STDMSK_CLKMULT) // Clock multiplier is passed through.
- | ((crb << (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) & STDMSK_CLKPOL)); // Clock polarity is passed through.
-
- // Return adjusted counter setup.
+ /* Populate the standardized counter setup bit fields. Note: */
+ /* IndexSrc is restricted to ENC_X or IndxPol. */
+ setup = (((crb << (STDBIT_INTSRC - CRBBIT_INTSRC_B)) & STDMSK_INTSRC) /* IntSrc = IntSrcB. */
+ | ((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC) /* LatchSrc = LatchSrcB. */
+ | ((crb << (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)) & STDMSK_LOADSRC) /* LoadSrc = LoadSrcB. */
+ | ((crb << (STDBIT_INDXPOL - CRBBIT_INDXPOL_B)) & STDMSK_INDXPOL) /* IndxPol = IndxPolB. */
+ | ((crb >> (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) & STDMSK_CLKENAB) /* ClkEnab = ClkEnabB. */
+ | ((cra >> ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)) & STDMSK_INDXSRC)); /* IndxSrc = IndxSrcB<1>. */
+
+ /* Adjust mode-dependent parameters. */
+ if ((crb & CRBMSK_CLKMULT_B) == (MULT_X0 << CRBBIT_CLKMULT_B)) /* If Extender mode (ClkMultB == MULT_X0): */
+ setup |= ((CLKSRC_EXTENDER << STDBIT_CLKSRC) /* Indicate Extender mode. */
+ | (MULT_X1 << STDBIT_CLKMULT) /* Indicate multiplier is 1x. */
+ | ((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL)); /* Set ClkPol equal to Timer count direction (ClkSrcB<0>). */
+
+ else if (cra & (2 << CRABIT_CLKSRC_B)) /* If Timer mode (ClkSrcB<1> == 1): */
+ setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC) /* Indicate Timer mode. */
+ | (MULT_X1 << STDBIT_CLKMULT) /* Indicate multiplier is 1x. */
+ | ((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL)); /* Set ClkPol equal to Timer count direction (ClkSrcB<0>). */
+
+ else /* If Counter mode (ClkSrcB<1> == 0): */
+ setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC) /* Indicate Timer mode. */
+ | ((crb >> (CRBBIT_CLKMULT_B - STDBIT_CLKMULT)) & STDMSK_CLKMULT) /* Clock multiplier is passed through. */
+ | ((crb << (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) & STDMSK_CLKPOL)); /* Clock polarity is passed through. */
+
+ /* Return adjusted counter setup. */
return setup;
}
-/////////////////////////////////////////////////////////////////////////////////////////////
-// Set the operating mode for the specified counter. The setup
-// parameter is treated as a COUNTER_SETUP data type. The following
-// parameters are programmable (all other parms are ignored): ClkMult,
-// ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
+/*
+ * Set the operating mode for the specified counter. The setup
+ * parameter is treated as a COUNTER_SETUP data type. The following
+ * parameters are programmable (all other parms are ignored): ClkMult,
+ * ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
+ */
-static void SetMode_A(comedi_device * dev, enc_private * k, uint16_t Setup,
+static void SetMode_A(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
uint16_t DisableIntSrc)
{
register uint16_t cra;
register uint16_t crb;
- register uint16_t setup = Setup; // Cache the Standard Setup.
+ register uint16_t setup = Setup; /* Cache the Standard Setup. */
- // Initialize CRA and CRB images.
- cra = ((setup & CRAMSK_LOADSRC_A) // Preload trigger is passed through.
- | ((setup & STDMSK_INDXSRC) >> (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1)))); // IndexSrc is restricted to ENC_X or IndxPol.
+ /* Initialize CRA and CRB images. */
+ cra = ((setup & CRAMSK_LOADSRC_A) /* Preload trigger is passed through. */
+ | ((setup & STDMSK_INDXSRC) >> (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1)))); /* IndexSrc is restricted to ENC_X or IndxPol. */
- crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A // Reset any pending CounterA event captures.
- | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_A - STDBIT_CLKENAB))); // Clock enable is passed through.
+ crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A /* Reset any pending CounterA event captures. */
+ | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_A - STDBIT_CLKENAB))); /* Clock enable is passed through. */
- // Force IntSrc to Disabled if DisableIntSrc is asserted.
+ /* Force IntSrc to Disabled if DisableIntSrc is asserted. */
if (!DisableIntSrc)
cra |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
CRABIT_INTSRC_A));
- // Populate all mode-dependent attributes of CRA & CRB images.
+ /* Populate all mode-dependent attributes of CRA & CRB images. */
switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
- case CLKSRC_EXTENDER: // Extender Mode: Force to Timer mode
- // (Extender valid only for B counters).
-
- case CLKSRC_TIMER: // Timer Mode:
- cra |= ((2 << CRABIT_CLKSRC_A) // ClkSrcA<1> selects system clock
- | ((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) // with count direction (ClkSrcA<0>) obtained from ClkPol.
- | (1 << CRABIT_CLKPOL_A) // ClkPolA behaves as always-on clock enable.
- | (MULT_X1 << CRABIT_CLKMULT_A)); // ClkMult must be 1x.
+ case CLKSRC_EXTENDER: /* Extender Mode: Force to Timer mode */
+ /* (Extender valid only for B counters). */
+
+ case CLKSRC_TIMER: /* Timer Mode: */
+ cra |= ((2 << CRABIT_CLKSRC_A) /* ClkSrcA<1> selects system clock */
+ | ((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) /* with count direction (ClkSrcA<0>) obtained from ClkPol. */
+ | (1 << CRABIT_CLKPOL_A) /* ClkPolA behaves as always-on clock enable. */
+ | (MULT_X1 << CRABIT_CLKMULT_A)); /* ClkMult must be 1x. */
break;
- default: // Counter Mode:
- cra |= (CLKSRC_COUNTER // Select ENC_C and ENC_D as clock/direction inputs.
- | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) // Clock polarity is passed through.
- | (((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ? // Force multiplier to x1 if not legal, otherwise pass through.
+ default: /* Counter Mode: */
+ cra |= (CLKSRC_COUNTER /* Select ENC_C and ENC_D as clock/direction inputs. */
+ | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) /* Clock polarity is passed through. */
+ | (((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ? /* Force multiplier to x1 if not legal, otherwise pass through. */
(MULT_X1 << CRABIT_CLKMULT_A) :
((setup & STDMSK_CLKMULT) << (CRABIT_CLKMULT_A -
STDBIT_CLKMULT))));
}
- // Force positive index polarity if IndxSrc is software-driven only,
- // otherwise pass it through.
+ /* Force positive index polarity if IndxSrc is software-driven only, */
+ /* otherwise pass it through. */
if (~setup & STDMSK_INDXSRC)
cra |= ((setup & STDMSK_INDXPOL) << (CRABIT_INDXPOL_A -
STDBIT_INDXPOL));
- // If IntSrc has been forced to Disabled, update the MISC2 interrupt
- // enable mask to indicate the counter interrupt is disabled.
+ /* If IntSrc has been forced to Disabled, update the MISC2 interrupt */
+ /* enable mask to indicate the counter interrupt is disabled. */
if (DisableIntSrc)
devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
- // While retaining CounterB and LatchSrc configurations, program the
- // new counter operating mode.
+ /* While retaining CounterB and LatchSrc configurations, program the */
+ /* new counter operating mode. */
DEBIreplace(dev, k->MyCRA, CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B, cra);
DEBIreplace(dev, k->MyCRB,
(uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), crb);
}
-static void SetMode_B(comedi_device * dev, enc_private * k, uint16_t Setup,
+static void SetMode_B(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
uint16_t DisableIntSrc)
{
register uint16_t cra;
register uint16_t crb;
- register uint16_t setup = Setup; // Cache the Standard Setup.
+ register uint16_t setup = Setup; /* Cache the Standard Setup. */
- // Initialize CRA and CRB images.
- cra = ((setup & STDMSK_INDXSRC) << ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)); // IndexSrc field is restricted to ENC_X or IndxPol.
+ /* Initialize CRA and CRB images. */
+ cra = ((setup & STDMSK_INDXSRC) << ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)); /* IndexSrc field is restricted to ENC_X or IndxPol. */
- crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B // Reset event captures and disable interrupts.
- | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) // Clock enable is passed through.
- | ((setup & STDMSK_LOADSRC) >> (STDBIT_LOADSRC - CRBBIT_LOADSRC_B))); // Preload trigger source is passed through.
+ crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B /* Reset event captures and disable interrupts. */
+ | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) /* Clock enable is passed through. */
+ | ((setup & STDMSK_LOADSRC) >> (STDBIT_LOADSRC - CRBBIT_LOADSRC_B))); /* Preload trigger source is passed through. */
- // Force IntSrc to Disabled if DisableIntSrc is asserted.
+ /* Force IntSrc to Disabled if DisableIntSrc is asserted. */
if (!DisableIntSrc)
crb |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
CRBBIT_INTSRC_B));
- // Populate all mode-dependent attributes of CRA & CRB images.
+ /* Populate all mode-dependent attributes of CRA & CRB images. */
switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
- case CLKSRC_TIMER: // Timer Mode:
- cra |= ((2 << CRABIT_CLKSRC_B) // ClkSrcB<1> selects system clock
- | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL))); // with direction (ClkSrcB<0>) obtained from ClkPol.
- crb |= ((1 << CRBBIT_CLKPOL_B) // ClkPolB behaves as always-on clock enable.
- | (MULT_X1 << CRBBIT_CLKMULT_B)); // ClkMultB must be 1x.
+ case CLKSRC_TIMER: /* Timer Mode: */
+ cra |= ((2 << CRABIT_CLKSRC_B) /* ClkSrcB<1> selects system clock */
+ | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL))); /* with direction (ClkSrcB<0>) obtained from ClkPol. */
+ crb |= ((1 << CRBBIT_CLKPOL_B) /* ClkPolB behaves as always-on clock enable. */
+ | (MULT_X1 << CRBBIT_CLKMULT_B)); /* ClkMultB must be 1x. */
break;
- case CLKSRC_EXTENDER: // Extender Mode:
- cra |= ((2 << CRABIT_CLKSRC_B) // ClkSrcB source is OverflowA (same as "timer")
- | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL))); // with direction obtained from ClkPol.
- crb |= ((1 << CRBBIT_CLKPOL_B) // ClkPolB controls IndexB -- always set to active.
- | (MULT_X0 << CRBBIT_CLKMULT_B)); // ClkMultB selects OverflowA as the clock source.
+ case CLKSRC_EXTENDER: /* Extender Mode: */
+ cra |= ((2 << CRABIT_CLKSRC_B) /* ClkSrcB source is OverflowA (same as "timer") */
+ | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL))); /* with direction obtained from ClkPol. */
+ crb |= ((1 << CRBBIT_CLKPOL_B) /* ClkPolB controls IndexB -- always set to active. */
+ | (MULT_X0 << CRBBIT_CLKMULT_B)); /* ClkMultB selects OverflowA as the clock source. */
break;
- default: // Counter Mode:
- cra |= (CLKSRC_COUNTER << CRABIT_CLKSRC_B); // Select ENC_C and ENC_D as clock/direction inputs.
- crb |= (((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) // ClkPol is passed through.
- | (((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ? // Force ClkMult to x1 if not legal, otherwise pass through.
+ default: /* Counter Mode: */
+ cra |= (CLKSRC_COUNTER << CRABIT_CLKSRC_B); /* Select ENC_C and ENC_D as clock/direction inputs. */
+ crb |= (((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) /* ClkPol is passed through. */
+ | (((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ? /* Force ClkMult to x1 if not legal, otherwise pass through. */
(MULT_X1 << CRBBIT_CLKMULT_B) :
((setup & STDMSK_CLKMULT) << (CRBBIT_CLKMULT_B -
STDBIT_CLKMULT))));
}
- // Force positive index polarity if IndxSrc is software-driven only,
- // otherwise pass it through.
+ /* Force positive index polarity if IndxSrc is software-driven only, */
+ /* otherwise pass it through. */
if (~setup & STDMSK_INDXSRC)
crb |= ((setup & STDMSK_INDXPOL) >> (STDBIT_INDXPOL -
CRBBIT_INDXPOL_B));
- // If IntSrc has been forced to Disabled, update the MISC2 interrupt
- // enable mask to indicate the counter interrupt is disabled.
+ /* If IntSrc has been forced to Disabled, update the MISC2 interrupt */
+ /* enable mask to indicate the counter interrupt is disabled. */
if (DisableIntSrc)
devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
- // While retaining CounterA and LatchSrc configurations, program the
- // new counter operating mode.
+ /* While retaining CounterA and LatchSrc configurations, program the */
+ /* new counter operating mode. */
DEBIreplace(dev, k->MyCRA,
(uint16_t) (~(CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B)), cra);
DEBIreplace(dev, k->MyCRB, CRBMSK_CLKENAB_A | CRBMSK_LATCHSRC, crb);
}
-////////////////////////////////////////////////////////////////////////
-// Return/set a counter's enable. enab: 0=always enabled, 1=enabled by index.
+/* Return/set a counter's enable. enab: 0=always enabled, 1=enabled by index. */
-static void SetEnable_A(comedi_device * dev, enc_private * k, uint16_t enab)
+static void SetEnable_A(struct comedi_device *dev, struct enc_private *k, uint16_t enab)
{
DEBUG("SetEnable_A: SetEnable_A enter 3541\n");
DEBIreplace(dev, k->MyCRB,
@@ -3006,29 +3016,29 @@ static void SetEnable_A(comedi_device * dev, enc_private * k, uint16_t enab)
(uint16_t) (enab << CRBBIT_CLKENAB_A));
}
-static void SetEnable_B(comedi_device * dev, enc_private * k, uint16_t enab)
+static void SetEnable_B(struct comedi_device *dev, struct enc_private *k, uint16_t enab)
{
DEBIreplace(dev, k->MyCRB,
(uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B)),
(uint16_t) (enab << CRBBIT_CLKENAB_B));
}
-static uint16_t GetEnable_A(comedi_device * dev, enc_private * k)
+static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k)
{
return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_A) & 1;
}
-static uint16_t GetEnable_B(comedi_device * dev, enc_private * k)
+static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k)
{
return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_B) & 1;
}
-////////////////////////////////////////////////////////////////////////
-// Return/set a counter pair's latch trigger source. 0: On read
-// access, 1: A index latches A, 2: B index latches B, 3: A overflow
-// latches B.
+/* Return/set a counter pair's latch trigger source. 0: On read
+ * access, 1: A index latches A, 2: B index latches B, 3: A overflow
+ * latches B.
+ */
-static void SetLatchSource(comedi_device * dev, enc_private * k, uint16_t value)
+static void SetLatchSource(struct comedi_device *dev, struct enc_private *k, uint16_t value)
{
DEBUG("SetLatchSource: SetLatchSource enter 3550 \n");
DEBIreplace(dev, k->MyCRB,
@@ -3038,210 +3048,206 @@ static void SetLatchSource(comedi_device * dev, enc_private * k, uint16_t value)
DEBUG("SetLatchSource: SetLatchSource exit \n");
}
-/* static uint16_t GetLatchSource(comedi_device *dev, enc_private *k ) */
-/* { */
-/* return ( DEBIread( dev, k->MyCRB) >> CRBBIT_LATCHSRC ) & 3; */
-/* } */
+/*
+ * static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k )
+ * {
+ * return ( DEBIread( dev, k->MyCRB) >> CRBBIT_LATCHSRC ) & 3;
+ * }
+ */
-/////////////////////////////////////////////////////////////////////////
-// Return/set the event that will trigger transfer of the preload
-// register into the counter. 0=ThisCntr_Index, 1=ThisCntr_Overflow,
-// 2=OverflowA (B counters only), 3=disabled.
+/*
+ * Return/set the event that will trigger transfer of the preload
+ * register into the counter. 0=ThisCntr_Index, 1=ThisCntr_Overflow,
+ * 2=OverflowA (B counters only), 3=disabled.
+ */
-static void SetLoadTrig_A(comedi_device * dev, enc_private * k, uint16_t Trig)
+static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k, uint16_t Trig)
{
DEBIreplace(dev, k->MyCRA, (uint16_t) (~CRAMSK_LOADSRC_A),
(uint16_t) (Trig << CRABIT_LOADSRC_A));
}
-static void SetLoadTrig_B(comedi_device * dev, enc_private * k, uint16_t Trig)
+static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k, uint16_t Trig)
{
DEBIreplace(dev, k->MyCRB,
(uint16_t) (~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL)),
(uint16_t) (Trig << CRBBIT_LOADSRC_B));
}
-static uint16_t GetLoadTrig_A(comedi_device * dev, enc_private * k)
+static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k)
{
return (DEBIread(dev, k->MyCRA) >> CRABIT_LOADSRC_A) & 3;
}
-static uint16_t GetLoadTrig_B(comedi_device * dev, enc_private * k)
+static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k)
{
return (DEBIread(dev, k->MyCRB) >> CRBBIT_LOADSRC_B) & 3;
}
-////////////////////
-// Return/set counter interrupt source and clear any captured
-// index/overflow events. IntSource: 0=Disabled, 1=OverflowOnly,
-// 2=IndexOnly, 3=IndexAndOverflow.
+/* Return/set counter interrupt source and clear any captured
+ * index/overflow events. IntSource: 0=Disabled, 1=OverflowOnly,
+ * 2=IndexOnly, 3=IndexAndOverflow.
+ */
-static void SetIntSrc_A(comedi_device * dev, enc_private * k,
+static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
uint16_t IntSource)
{
- // Reset any pending counter overflow or index captures.
+ /* Reset any pending counter overflow or index captures. */
DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
- // Program counter interrupt source.
+ /* Program counter interrupt source. */
DEBIreplace(dev, k->MyCRA, ~CRAMSK_INTSRC_A,
(uint16_t) (IntSource << CRABIT_INTSRC_A));
- // Update MISC2 interrupt enable mask.
+ /* Update MISC2 interrupt enable mask. */
devpriv->CounterIntEnabs =
(devpriv->CounterIntEnabs & ~k->MyEventBits[3]) | k->
MyEventBits[IntSource];
}
-static void SetIntSrc_B(comedi_device * dev, enc_private * k,
+static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
uint16_t IntSource)
{
uint16_t crb;
- // Cache writeable CRB register image.
+ /* Cache writeable CRB register image. */
crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL;
- // Reset any pending counter overflow or index captures.
+ /* Reset any pending counter overflow or index captures. */
DEBIwrite(dev, k->MyCRB,
(uint16_t) (crb | CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B));
- // Program counter interrupt source.
+ /* Program counter interrupt source. */
DEBIwrite(dev, k->MyCRB,
(uint16_t) ((crb & ~CRBMSK_INTSRC_B) | (IntSource <<
CRBBIT_INTSRC_B)));
- // Update MISC2 interrupt enable mask.
+ /* Update MISC2 interrupt enable mask. */
devpriv->CounterIntEnabs =
(devpriv->CounterIntEnabs & ~k->MyEventBits[3]) | k->
MyEventBits[IntSource];
}
-static uint16_t GetIntSrc_A(comedi_device * dev, enc_private * k)
+static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k)
{
return (DEBIread(dev, k->MyCRA) >> CRABIT_INTSRC_A) & 3;
}
-static uint16_t GetIntSrc_B(comedi_device * dev, enc_private * k)
+static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k)
{
return (DEBIread(dev, k->MyCRB) >> CRBBIT_INTSRC_B) & 3;
}
-/////////////////////////////////////////////////////////////////////////
-// Return/set the clock multiplier.
+/* Return/set the clock multiplier. */
-/* static void SetClkMult(comedi_device *dev, enc_private *k, uint16_t value ) */
+/* static void SetClkMult(struct comedi_device *dev, struct enc_private *k, uint16_t value ) */
/* { */
/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKMULT ) | ( value << STDBIT_CLKMULT ) ), FALSE ); */
/* } */
-/* static uint16_t GetClkMult(comedi_device *dev, enc_private *k ) */
+/* static uint16_t GetClkMult(struct comedi_device *dev, struct enc_private *k ) */
/* { */
/* return ( k->GetMode(dev, k ) >> STDBIT_CLKMULT ) & 3; */
/* } */
-/* ////////////////////////////////////////////////////////////////////////// */
-/* // Return/set the clock polarity. */
+/* Return/set the clock polarity. */
-/* static void SetClkPol( comedi_device *dev,enc_private *k, uint16_t value ) */
+/* static void SetClkPol( struct comedi_device *dev,struct enc_private *k, uint16_t value ) */
/* { */
/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKPOL ) | ( value << STDBIT_CLKPOL ) ), FALSE ); */
/* } */
-/* static uint16_t GetClkPol(comedi_device *dev, enc_private *k ) */
+/* static uint16_t GetClkPol(struct comedi_device *dev, struct enc_private *k ) */
/* { */
/* return ( k->GetMode(dev, k ) >> STDBIT_CLKPOL ) & 1; */
/* } */
-/* /////////////////////////////////////////////////////////////////////// */
-/* // Return/set the clock source. */
+/* Return/set the clock source. */
-/* static void SetClkSrc( comedi_device *dev,enc_private *k, uint16_t value ) */
+/* static void SetClkSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value ) */
/* { */
/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKSRC ) | ( value << STDBIT_CLKSRC ) ), FALSE ); */
/* } */
-/* static uint16_t GetClkSrc( comedi_device *dev,enc_private *k ) */
+/* static uint16_t GetClkSrc( struct comedi_device *dev,struct enc_private *k ) */
/* { */
/* return ( k->GetMode(dev, k ) >> STDBIT_CLKSRC ) & 3; */
/* } */
-/* //////////////////////////////////////////////////////////////////////// */
-/* // Return/set the index polarity. */
+/* Return/set the index polarity. */
-/* static void SetIndexPol(comedi_device *dev, enc_private *k, uint16_t value ) */
+/* static void SetIndexPol(struct comedi_device *dev, struct enc_private *k, uint16_t value ) */
/* { */
/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXPOL ) | ( (value != 0) << STDBIT_INDXPOL ) ), FALSE ); */
/* } */
-/* static uint16_t GetIndexPol(comedi_device *dev, enc_private *k ) */
+/* static uint16_t GetIndexPol(struct comedi_device *dev, struct enc_private *k ) */
/* { */
/* return ( k->GetMode(dev, k ) >> STDBIT_INDXPOL ) & 1; */
/* } */
-/* //////////////////////////////////////////////////////////////////////// */
-/* // Return/set the index source. */
+/* Return/set the index source. */
-/* static void SetIndexSrc(comedi_device *dev, enc_private *k, uint16_t value ) */
+/* static void SetIndexSrc(struct comedi_device *dev, struct enc_private *k, uint16_t value ) */
/* { */
/* DEBUG("SetIndexSrc: set index src enter 3700\n"); */
/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXSRC ) | ( (value != 0) << STDBIT_INDXSRC ) ), FALSE ); */
/* } */
-/* static uint16_t GetIndexSrc(comedi_device *dev, enc_private *k ) */
+/* static uint16_t GetIndexSrc(struct comedi_device *dev, struct enc_private *k ) */
/* { */
/* return ( k->GetMode(dev, k ) >> STDBIT_INDXSRC ) & 1; */
/* } */
-///////////////////////////////////////////////////////////////////
-// Generate an index pulse.
+/* Generate an index pulse. */
-static void PulseIndex_A(comedi_device * dev, enc_private * k)
+static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k)
{
register uint16_t cra;
DEBUG("PulseIndex_A: pulse index enter\n");
- cra = DEBIread(dev, k->MyCRA); // Pulse index.
+ cra = DEBIread(dev, k->MyCRA); /* Pulse index. */
DEBIwrite(dev, k->MyCRA, (uint16_t) (cra ^ CRAMSK_INDXPOL_A));
DEBUG("PulseIndex_A: pulse index step1\n");
DEBIwrite(dev, k->MyCRA, cra);
}
-static void PulseIndex_B(comedi_device * dev, enc_private * k)
+static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k)
{
register uint16_t crb;
- crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL; // Pulse index.
+ crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL; /* Pulse index. */
DEBIwrite(dev, k->MyCRB, (uint16_t) (crb ^ CRBMSK_INDXPOL_B));
DEBIwrite(dev, k->MyCRB, crb);
}
-/////////////////////////////////////////////////////////
-// Write value into counter preload register.
+/* Write value into counter preload register. */
-static void Preload(comedi_device * dev, enc_private * k, uint32_t value)
+static void Preload(struct comedi_device *dev, struct enc_private *k, uint32_t value)
{
DEBUG("Preload: preload enter\n");
- DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value); // Write value to preload register.
+ DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value); /* Write value to preload register. */
DEBUG("Preload: preload step 1\n");
DEBIwrite(dev, (uint16_t) (k->MyLatchLsw + 2),
(uint16_t) (value >> 16));
}
-static void CountersInit(comedi_device * dev)
+static void CountersInit(struct comedi_device *dev)
{
int chan;
- enc_private *k;
- uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | // Preload upon
- // index.
- (INDXSRC_SOFT << BF_INDXSRC) | // Disable hardware index.
- (CLKSRC_COUNTER << BF_CLKSRC) | // Operating mode is counter.
- (CLKPOL_POS << BF_CLKPOL) | // Active high clock.
- (CNTDIR_UP << BF_CLKPOL) | // Count direction is up.
- (CLKMULT_1X << BF_CLKMULT) | // Clock multiplier is 1x.
- (CLKENAB_INDEX << BF_CLKENAB); // Enabled by index
-
- // Disable all counter interrupts and clear any captured counter events.
+ struct enc_private *k;
+ uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */
+ /* index. */
+ (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */
+ (CLKSRC_COUNTER << BF_CLKSRC) | /* Operating mode is counter. */
+ (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */
+ (CNTDIR_UP << BF_CLKPOL) | /* Count direction is up. */
+ (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */
+ (CLKENAB_INDEX << BF_CLKENAB); /* Enabled by index */
+
+ /* Disable all counter interrupts and clear any captured counter events. */
for (chan = 0; chan < S626_ENCODER_CHANNELS; chan++) {
k = &encpriv[chan];
k->SetMode(dev, k, Setup, TRUE);
diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h
index 11d8b1ceb0b..891126f2509 100644
--- a/drivers/staging/comedi/drivers/s626.h
+++ b/drivers/staging/comedi/drivers/s626.h
@@ -51,15 +51,15 @@
Example code
- insn.insn=INSN_CONFIG; //configuration instruction
- insn.n=1; //number of operation (must be 1)
- insn.data=&initialvalue; //initial value loaded into encoder
- //during configuration
- insn.subdev=5; //encoder subdevice
- insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); //encoder_channel
- //to configure
-
- comedi_do_insn(cf,&insn); //executing configuration
+ insn.insn=INSN_CONFIG; // configuration instruction
+ insn.n=1; // number of operation (must be 1)
+ insn.data=&initialvalue; // initial value loaded into encoder
+ // during configuration
+ insn.subdev=5; // encoder subdevice
+ insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); // encoder_channel
+ // to configure
+
+ comedi_do_insn(cf,&insn); // executing configuration
*/
#ifdef _DEBUG_
@@ -88,147 +88,136 @@
#define INLINE static __inline
#endif
-/////////////////////////////////////////////////////
#include<linux/slab.h>
#define S626_SIZE 0x0200
#define SIZEOF_ADDRESS_SPACE 0x0200
-#define DMABUF_SIZE 4096 // 4k pages
+#define DMABUF_SIZE 4096 /* 4k pages */
#define S626_ADC_CHANNELS 16
#define S626_DAC_CHANNELS 4
#define S626_ENCODER_CHANNELS 6
#define S626_DIO_CHANNELS 48
-#define S626_DIO_BANKS 3 // Number of DIO groups.
-#define S626_DIO_EXTCHANS 40 // Number of
- // extended-capability
- // DIO channels.
+#define S626_DIO_BANKS 3 /* Number of DIO groups. */
+#define S626_DIO_EXTCHANS 40 /* Number of */
+ /* extended-capability */
+ /* DIO channels. */
-#define NUM_TRIMDACS 12 // Number of valid TrimDAC channels.
+#define NUM_TRIMDACS 12 /* Number of valid TrimDAC channels. */
-// PCI bus interface types.
-#define INTEL 1 // Intel bus type.
-#define MOTOROLA 2 // Motorola bus type.
+/* PCI bus interface types. */
+#define INTEL 1 /* Intel bus type. */
+#define MOTOROLA 2 /* Motorola bus type. */
-//////////////////////////////////////////////////////////
+#define PLATFORM INTEL /* *** SELECT PLATFORM TYPE *** */
-//////////////////////////////////////////////////////////
-#define PLATFORM INTEL // *** SELECT PLATFORM TYPE ***
-//////////////////////////////////////////////////////////
+#define RANGE_5V 0x10 /* +/-5V range */
+#define RANGE_10V 0x00 /* +/-10V range */
-#define RANGE_5V 0x10 // +/-5V range
-#define RANGE_10V 0x00 // +/-10V range
+#define EOPL 0x80 /* End of ADC poll list marker. */
+#define GSEL_BIPOLAR5V 0x00F0 /* LP_GSEL setting for 5V bipolar range. */
+#define GSEL_BIPOLAR10V 0x00A0 /* LP_GSEL setting for 10V bipolar range. */
-#define EOPL 0x80 // End of ADC poll list marker.
-#define GSEL_BIPOLAR5V 0x00F0 // LP_GSEL setting for 5V bipolar range.
-#define GSEL_BIPOLAR10V 0x00A0 // LP_GSEL setting for 10V bipolar range.
+/* Error codes that must be visible to this base class. */
+#define ERR_ILLEGAL_PARM 0x00010000 /* Illegal function parameter value was specified. */
+#define ERR_I2C 0x00020000 /* I2C error. */
+#define ERR_COUNTERSETUP 0x00200000 /* Illegal setup specified for counter channel. */
+#define ERR_DEBI_TIMEOUT 0x00400000 /* DEBI transfer timed out. */
-// Error codes that must be visible to this base class.
-#define ERR_ILLEGAL_PARM 0x00010000 // Illegal function parameter value was specified.
-#define ERR_I2C 0x00020000 // I2C error.
-#define ERR_COUNTERSETUP 0x00200000 // Illegal setup specified for counter channel.
-#define ERR_DEBI_TIMEOUT 0x00400000 // DEBI transfer timed out.
+/* Organization (physical order) and size (in DWORDs) of logical DMA buffers contained by ANA_DMABUF. */
+#define ADC_DMABUF_DWORDS 40 /* ADC DMA buffer must hold 16 samples, plus pre/post garbage samples. */
+#define DAC_WDMABUF_DWORDS 1 /* DAC output DMA buffer holds a single sample. */
-// Organization (physical order) and size (in DWORDs) of logical DMA buffers contained by ANA_DMABUF.
-#define ADC_DMABUF_DWORDS 40 // ADC DMA buffer must hold 16 samples, plus pre/post garbage samples.
-#define DAC_WDMABUF_DWORDS 1 // DAC output DMA buffer holds a single sample.
+/* All remaining space in 4KB DMA buffer is available for the RPS1 program. */
-// All remaining space in 4KB DMA buffer is available for the RPS1 program.
-
-// Address offsets, in DWORDS, from base of DMA buffer.
+/* Address offsets, in DWORDS, from base of DMA buffer. */
#define DAC_WDMABUF_OS ADC_DMABUF_DWORDS
-// Interrupt enab bit in ISR and IER.
-#define IRQ_GPIO3 0x00000040 // IRQ enable for GPIO3.
+/* Interrupt enab bit in ISR and IER. */
+#define IRQ_GPIO3 0x00000040 /* IRQ enable for GPIO3. */
#define IRQ_RPS1 0x10000000
-#define ISR_AFOU 0x00000800 // Audio fifo
- // under/overflow
- // detected.
-#define IRQ_COINT1A 0x0400 // conter 1A overflow
- // interrupt mask
-#define IRQ_COINT1B 0x0800 // conter 1B overflow
- // interrupt mask
-#define IRQ_COINT2A 0x1000 // conter 2A overflow
- // interrupt mask
-#define IRQ_COINT2B 0x2000 // conter 2B overflow
- // interrupt mask
-#define IRQ_COINT3A 0x4000 // conter 3A overflow
- // interrupt mask
-#define IRQ_COINT3B 0x8000 // conter 3B overflow
- // interrupt mask
-
-// RPS command codes.
-#define RPS_CLRSIGNAL 0x00000000 // CLEAR SIGNAL
-#define RPS_SETSIGNAL 0x10000000 // SET SIGNAL
-#define RPS_NOP 0x00000000 // NOP
-#define RPS_PAUSE 0x20000000 // PAUSE
-#define RPS_UPLOAD 0x40000000 // UPLOAD
-#define RPS_JUMP 0x80000000 // JUMP
-#define RPS_LDREG 0x90000100 // LDREG (1 uint32_t only)
-#define RPS_STREG 0xA0000100 // STREG (1 uint32_t only)
-#define RPS_STOP 0x50000000 // STOP
-#define RPS_IRQ 0x60000000 // IRQ
-
-#define RPS_LOGICAL_OR 0x08000000 // Logical OR conditionals.
-#define RPS_INVERT 0x04000000 // Test for negated semaphores.
-#define RPS_DEBI 0x00000002 // DEBI done
-
-#define RPS_SIG0 0x00200000 // RPS semaphore 0 (used by ADC).
-#define RPS_SIG1 0x00400000 // RPS semaphore 1 (used by DAC).
-#define RPS_SIG2 0x00800000 // RPS semaphore 2 (not used).
-#define RPS_GPIO2 0x00080000 // RPS GPIO2
-#define RPS_GPIO3 0x00100000 // RPS GPIO3
-
-#define RPS_SIGADC RPS_SIG0 // Trigger/status for ADC's RPS program.
-#define RPS_SIGDAC RPS_SIG1 // Trigger/status for DAC's RPS program.
-
-// RPS clock parameters.
-#define RPSCLK_SCALAR 8 // This is apparent ratio of PCI/RPS clks (undocumented!!).
-#define RPSCLK_PER_US ( 33 / RPSCLK_SCALAR ) // Number of RPS clocks in one microsecond.
-
-// Event counter source addresses.
-#define SBA_RPS_A0 0x27 // Time of RPS0 busy, in PCI clocks.
-
-// GPIO constants.
-#define GPIO_BASE 0x10004000 // GPIO 0,2,3 = inputs, GPIO3 = IRQ; GPIO1 = out.
-#define GPIO1_LO 0x00000000 // GPIO1 set to LOW.
-#define GPIO1_HI 0x00001000 // GPIO1 set to HIGH.
-
-// Primary Status Register (PSR) constants.
-#define PSR_DEBI_E 0x00040000 // DEBI event flag.
-#define PSR_DEBI_S 0x00080000 // DEBI status flag.
-#define PSR_A2_IN 0x00008000 // Audio output DMA2 protection address reached.
-#define PSR_AFOU 0x00000800 // Audio FIFO under/overflow detected.
-#define PSR_GPIO2 0x00000020 // GPIO2 input pin: 0=AdcBusy, 1=AdcIdle.
-#define PSR_EC0S 0x00000001 // Event counter 0 threshold reached.
-
-// Secondary Status Register (SSR) constants.
-#define SSR_AF2_OUT 0x00000200 // Audio 2 output FIFO under/overflow detected.
-
-// Master Control Register 1 (MC1) constants.
-#define MC1_SOFT_RESET 0x80000000 // Invoke 7146 soft reset.
-#define MC1_SHUTDOWN 0x3FFF0000 // Shut down all MC1-controlled enables.
-
-#define MC1_ERPS1 0x2000 // enab/disable RPS task 1.
-#define MC1_ERPS0 0x1000 // enab/disable RPS task 0.
-#define MC1_DEBI 0x0800 // enab/disable DEBI pins.
-#define MC1_AUDIO 0x0200 // enab/disable audio port pins.
-#define MC1_I2C 0x0100 // enab/disable I2C interface.
-#define MC1_A2OUT 0x0008 // enab/disable transfer on A2 out.
-#define MC1_A2IN 0x0004 // enab/disable transfer on A2 in.
-#define MC1_A1IN 0x0001 // enab/disable transfer on A1 in.
-
-// Master Control Register 2 (MC2) constants.
-#define MC2_UPLD_DEBIq 0x00020002 // Upload DEBI registers.
-#define MC2_UPLD_IICq 0x00010001 // Upload I2C registers.
-#define MC2_RPSSIG2_ONq 0x20002000 // Assert RPS_SIG2.
-#define MC2_RPSSIG1_ONq 0x10001000 // Assert RPS_SIG1.
-#define MC2_RPSSIG0_ONq 0x08000800 // Assert RPS_SIG0.
-#define MC2_UPLD_DEBI_MASKq 0x00000002 // Upload DEBI mask.
-#define MC2_UPLD_IIC_MASKq 0x00000001 // Upload I2C mask.
-#define MC2_RPSSIG2_MASKq 0x00002000 // RPS_SIG2 bit mask.
-#define MC2_RPSSIG1_MASKq 0x00001000 // RPS_SIG1 bit mask.
-#define MC2_RPSSIG0_MASKq 0x00000800 // RPS_SIG0 bit mask.
+#define ISR_AFOU 0x00000800
+/* Audio fifo under/overflow detected. */
+
+#define IRQ_COINT1A 0x0400 /* conter 1A overflow interrupt mask */
+#define IRQ_COINT1B 0x0800 /* conter 1B overflow interrupt mask */
+#define IRQ_COINT2A 0x1000 /* conter 2A overflow interrupt mask */
+#define IRQ_COINT2B 0x2000 /* conter 2B overflow interrupt mask */
+#define IRQ_COINT3A 0x4000 /* conter 3A overflow interrupt mask */
+#define IRQ_COINT3B 0x8000 /* conter 3B overflow interrupt mask */
+
+/* RPS command codes. */
+#define RPS_CLRSIGNAL 0x00000000 /* CLEAR SIGNAL */
+#define RPS_SETSIGNAL 0x10000000 /* SET SIGNAL */
+#define RPS_NOP 0x00000000 /* NOP */
+#define RPS_PAUSE 0x20000000 /* PAUSE */
+#define RPS_UPLOAD 0x40000000 /* UPLOAD */
+#define RPS_JUMP 0x80000000 /* JUMP */
+#define RPS_LDREG 0x90000100 /* LDREG (1 uint32_t only) */
+#define RPS_STREG 0xA0000100 /* STREG (1 uint32_t only) */
+#define RPS_STOP 0x50000000 /* STOP */
+#define RPS_IRQ 0x60000000 /* IRQ */
+
+#define RPS_LOGICAL_OR 0x08000000 /* Logical OR conditionals. */
+#define RPS_INVERT 0x04000000 /* Test for negated semaphores. */
+#define RPS_DEBI 0x00000002 /* DEBI done */
+
+#define RPS_SIG0 0x00200000 /* RPS semaphore 0 (used by ADC). */
+#define RPS_SIG1 0x00400000 /* RPS semaphore 1 (used by DAC). */
+#define RPS_SIG2 0x00800000 /* RPS semaphore 2 (not used). */
+#define RPS_GPIO2 0x00080000 /* RPS GPIO2 */
+#define RPS_GPIO3 0x00100000 /* RPS GPIO3 */
+
+#define RPS_SIGADC RPS_SIG0 /* Trigger/status for ADC's RPS program. */
+#define RPS_SIGDAC RPS_SIG1 /* Trigger/status for DAC's RPS program. */
+
+/* RPS clock parameters. */
+#define RPSCLK_SCALAR 8 /* This is apparent ratio of PCI/RPS clks (undocumented!!). */
+#define RPSCLK_PER_US (33 / RPSCLK_SCALAR) /* Number of RPS clocks in one microsecond. */
+
+/* Event counter source addresses. */
+#define SBA_RPS_A0 0x27 /* Time of RPS0 busy, in PCI clocks. */
+
+/* GPIO constants. */
+#define GPIO_BASE 0x10004000 /* GPIO 0,2,3 = inputs, GPIO3 = IRQ; GPIO1 = out. */
+#define GPIO1_LO 0x00000000 /* GPIO1 set to LOW. */
+#define GPIO1_HI 0x00001000 /* GPIO1 set to HIGH. */
+
+/* Primary Status Register (PSR) constants. */
+#define PSR_DEBI_E 0x00040000 /* DEBI event flag. */
+#define PSR_DEBI_S 0x00080000 /* DEBI status flag. */
+#define PSR_A2_IN 0x00008000 /* Audio output DMA2 protection address reached. */
+#define PSR_AFOU 0x00000800 /* Audio FIFO under/overflow detected. */
+#define PSR_GPIO2 0x00000020 /* GPIO2 input pin: 0=AdcBusy, 1=AdcIdle. */
+#define PSR_EC0S 0x00000001 /* Event counter 0 threshold reached. */
+
+/* Secondary Status Register (SSR) constants. */
+#define SSR_AF2_OUT 0x00000200 /* Audio 2 output FIFO under/overflow detected. */
+
+/* Master Control Register 1 (MC1) constants. */
+#define MC1_SOFT_RESET 0x80000000 /* Invoke 7146 soft reset. */
+#define MC1_SHUTDOWN 0x3FFF0000 /* Shut down all MC1-controlled enables. */
+
+#define MC1_ERPS1 0x2000 /* enab/disable RPS task 1. */
+#define MC1_ERPS0 0x1000 /* enab/disable RPS task 0. */
+#define MC1_DEBI 0x0800 /* enab/disable DEBI pins. */
+#define MC1_AUDIO 0x0200 /* enab/disable audio port pins. */
+#define MC1_I2C 0x0100 /* enab/disable I2C interface. */
+#define MC1_A2OUT 0x0008 /* enab/disable transfer on A2 out. */
+#define MC1_A2IN 0x0004 /* enab/disable transfer on A2 in. */
+#define MC1_A1IN 0x0001 /* enab/disable transfer on A1 in. */
+
+/* Master Control Register 2 (MC2) constants. */
+#define MC2_UPLD_DEBIq 0x00020002 /* Upload DEBI registers. */
+#define MC2_UPLD_IICq 0x00010001 /* Upload I2C registers. */
+#define MC2_RPSSIG2_ONq 0x20002000 /* Assert RPS_SIG2. */
+#define MC2_RPSSIG1_ONq 0x10001000 /* Assert RPS_SIG1. */
+#define MC2_RPSSIG0_ONq 0x08000800 /* Assert RPS_SIG0. */
+#define MC2_UPLD_DEBI_MASKq 0x00000002 /* Upload DEBI mask. */
+#define MC2_UPLD_IIC_MASKq 0x00000001 /* Upload I2C mask. */
+#define MC2_RPSSIG2_MASKq 0x00002000 /* RPS_SIG2 bit mask. */
+#define MC2_RPSSIG1_MASKq 0x00001000 /* RPS_SIG1 bit mask. */
+#define MC2_RPSSIG0_MASKq 0x00000800 /* RPS_SIG0 bit mask. */
#define MC2_DELAYTRIG_4USq MC2_RPSSIG1_ON
#define MC2_DELAYBUSY_4USq MC2_RPSSIG1_MASK
@@ -236,469 +225,425 @@
#define MC2_DELAYTRIG_6USq MC2_RPSSIG2_ON
#define MC2_DELAYBUSY_6USq MC2_RPSSIG2_MASK
-#define MC2_UPLD_DEBI 0x0002 // Upload DEBI.
-#define MC2_UPLD_IIC 0x0001 // Upload I2C.
-#define MC2_RPSSIG2 0x2000 // RPS signal 2 (not used).
-#define MC2_RPSSIG1 0x1000 // RPS signal 1 (DAC RPS busy).
-#define MC2_RPSSIG0 0x0800 // RPS signal 0 (ADC RPS busy).
-
-#define MC2_ADC_RPS MC2_RPSSIG0 // ADC RPS busy.
-#define MC2_DAC_RPS MC2_RPSSIG1 // DAC RPS busy.
-
-///////////////////oldies///////////
-#define MC2_UPLD_DEBIQ 0x00020002 // Upload DEBI registers.
-#define MC2_UPLD_IICQ 0x00010001 // Upload I2C registers.
-////////////////////////////////////////
-
-// PCI BUS (SAA7146) REGISTER ADDRESS OFFSETS ////////////////////////
-#define P_PCI_BT_A 0x004C // Audio DMA
- // burst/threshold
- // control.
-#define P_DEBICFG 0x007C // DEBI configuration.
-#define P_DEBICMD 0x0080 // DEBI command.
-#define P_DEBIPAGE 0x0084 // DEBI page.
-#define P_DEBIAD 0x0088 // DEBI target address.
-#define P_I2CCTRL 0x008C // I2C control.
-#define P_I2CSTAT 0x0090 // I2C status.
-#define P_BASEA2_IN 0x00AC // Audio input 2 base
- // physical DMAbuf
- // address.
-#define P_PROTA2_IN 0x00B0 // Audio input 2
- // physical DMAbuf
- // protection address.
-#define P_PAGEA2_IN 0x00B4 // Audio input 2
- // paging attributes.
-#define P_BASEA2_OUT 0x00B8 // Audio output 2 base
- // physical DMAbuf
- // address.
-#define P_PROTA2_OUT 0x00BC // Audio output 2
- // physical DMAbuf
- // protection address.
-#define P_PAGEA2_OUT 0x00C0 // Audio output 2
- // paging attributes.
-#define P_RPSPAGE0 0x00C4 // RPS0 page.
-#define P_RPSPAGE1 0x00C8 // RPS1 page.
-#define P_RPS0_TOUT 0x00D4 // RPS0 time-out.
-#define P_RPS1_TOUT 0x00D8 // RPS1 time-out.
-#define P_IER 0x00DC // Interrupt enable.
-#define P_GPIO 0x00E0 // General-purpose I/O.
-#define P_EC1SSR 0x00E4 // Event counter set 1
- // source select.
-#define P_ECT1R 0x00EC // Event counter
- // threshold set 1.
-#define P_ACON1 0x00F4 // Audio control 1.
-#define P_ACON2 0x00F8 // Audio control 2.
-#define P_MC1 0x00FC // Master control 1.
-#define P_MC2 0x0100 // Master control 2.
-#define P_RPSADDR0 0x0104 // RPS0 instruction pointer.
-#define P_RPSADDR1 0x0108 // RPS1 instruction pointer.
-#define P_ISR 0x010C // Interrupt status.
-#define P_PSR 0x0110 // Primary status.
-#define P_SSR 0x0114 // Secondary status.
-#define P_EC1R 0x0118 // Event counter set 1.
-#define P_ADP4 0x0138 // Logical audio DMA
- // pointer of audio
- // input FIFO A2_IN.
-#define P_FB_BUFFER1 0x0144 // Audio feedback buffer 1.
-#define P_FB_BUFFER2 0x0148 // Audio feedback buffer 2.
-#define P_TSL1 0x0180 // Audio time slot list 1.
-#define P_TSL2 0x01C0 // Audio time slot list 2.
-
-// LOCAL BUS (GATE ARRAY) REGISTER ADDRESS OFFSETS /////////////////
-// Analog I/O registers:
-#define LP_DACPOL 0x0082 // Write DAC polarity.
-#define LP_GSEL 0x0084 // Write ADC gain.
-#define LP_ISEL 0x0086 // Write ADC channel select.
-// Digital I/O (write only):
-#define LP_WRINTSELA 0x0042 // Write A interrupt enable.
-#define LP_WREDGSELA 0x0044 // Write A edge selection.
-#define LP_WRCAPSELA 0x0046 // Write A capture enable.
-#define LP_WRDOUTA 0x0048 // Write A digital output.
-#define LP_WRINTSELB 0x0052 // Write B interrupt enable.
-#define LP_WREDGSELB 0x0054 // Write B edge selection.
-#define LP_WRCAPSELB 0x0056 // Write B capture enable.
-#define LP_WRDOUTB 0x0058 // Write B digital output.
-#define LP_WRINTSELC 0x0062 // Write C interrupt enable.
-#define LP_WREDGSELC 0x0064 // Write C edge selection.
-#define LP_WRCAPSELC 0x0066 // Write C capture enable.
-#define LP_WRDOUTC 0x0068 // Write C digital output.
-
-// Digital I/O (read only):
-#define LP_RDDINA 0x0040 // Read digital input.
-#define LP_RDCAPFLGA 0x0048 // Read edges captured.
-#define LP_RDINTSELA 0x004A // Read interrupt
- // enable register.
-#define LP_RDEDGSELA 0x004C // Read edge
- // selection
- // register.
-#define LP_RDCAPSELA 0x004E // Read capture
- // enable register.
-#define LP_RDDINB 0x0050 // Read digital input.
-#define LP_RDCAPFLGB 0x0058 // Read edges captured.
-#define LP_RDINTSELB 0x005A // Read interrupt
- // enable register.
-#define LP_RDEDGSELB 0x005C // Read edge
- // selection
- // register.
-#define LP_RDCAPSELB 0x005E // Read capture
- // enable register.
-#define LP_RDDINC 0x0060 // Read digital input.
-#define LP_RDCAPFLGC 0x0068 // Read edges captured.
-#define LP_RDINTSELC 0x006A // Read interrupt
- // enable register.
-#define LP_RDEDGSELC 0x006C // Read edge
- // selection
- // register.
-#define LP_RDCAPSELC 0x006E // Read capture
- // enable register.
-// Counter Registers (read/write):
-#define LP_CR0A 0x0000 // 0A setup register.
-#define LP_CR0B 0x0002 // 0B setup register.
-#define LP_CR1A 0x0004 // 1A setup register.
-#define LP_CR1B 0x0006 // 1B setup register.
-#define LP_CR2A 0x0008 // 2A setup register.
-#define LP_CR2B 0x000A // 2B setup register.
-// Counter PreLoad (write) and Latch (read) Registers:
-#define LP_CNTR0ALSW 0x000C // 0A lsw.
-#define LP_CNTR0AMSW 0x000E // 0A msw.
-#define LP_CNTR0BLSW 0x0010 // 0B lsw.
-#define LP_CNTR0BMSW 0x0012 // 0B msw.
-#define LP_CNTR1ALSW 0x0014 // 1A lsw.
-#define LP_CNTR1AMSW 0x0016 // 1A msw.
-#define LP_CNTR1BLSW 0x0018 // 1B lsw.
-#define LP_CNTR1BMSW 0x001A // 1B msw.
-#define LP_CNTR2ALSW 0x001C // 2A lsw.
-#define LP_CNTR2AMSW 0x001E // 2A msw.
-#define LP_CNTR2BLSW 0x0020 // 2B lsw.
-#define LP_CNTR2BMSW 0x0022 // 2B msw.
-// Miscellaneous Registers (read/write):
-#define LP_MISC1 0x0088 // Read/write Misc1.
-#define LP_WRMISC2 0x0090 // Write Misc2.
-#define LP_RDMISC2 0x0082 // Read Misc2.
-
-// Bit masks for MISC1 register that are the same for reads and writes.
-#define MISC1_WENABLE 0x8000 // enab writes to
- // MISC2 (except Clear
- // Watchdog bit).
-#define MISC1_WDISABLE 0x0000 // Disable writes to MISC2.
-#define MISC1_EDCAP 0x1000 // enab edge capture
- // on DIO chans
- // specified by
- // LP_WRCAPSELx.
-#define MISC1_NOEDCAP 0x0000 // Disable edge
- // capture on
- // specified DIO
- // chans.
-
-// Bit masks for MISC1 register reads.
-#define RDMISC1_WDTIMEOUT 0x4000 // Watchdog timer timed out.
-
-// Bit masks for MISC2 register writes.
-#define WRMISC2_WDCLEAR 0x8000 // Reset watchdog
- // timer to zero.
-#define WRMISC2_CHARGE_ENABLE 0x4000 // enab battery
- // trickle charging.
-
-// Bit masks for MISC2 register that are the same for reads and writes.
-#define MISC2_BATT_ENABLE 0x0008 // Backup battery enable.
-#define MISC2_WDENABLE 0x0004 // Watchdog timer enable.
-#define MISC2_WDPERIOD_MASK 0x0003 // Watchdog interval
- // select mask.
-
-// Bit masks for ACON1 register.
-#define A2_RUN 0x40000000 // Run A2 based on TSL2.
-#define A1_RUN 0x20000000 // Run A1 based on TSL1.
-#define A1_SWAP 0x00200000 // Use big-endian for A1.
-#define A2_SWAP 0x00100000 // Use big-endian for A2.
-#define WS_MODES 0x00019999 // WS0 = TSL1 trigger
- // input, WS1-WS4 =
- // CS* outputs.
-
-#if PLATFORM == INTEL // Base ACON1 config:
- // always run A1 based
- // on TSL1.
-#define ACON1_BASE ( WS_MODES | A1_RUN )
+#define MC2_UPLD_DEBI 0x0002 /* Upload DEBI. */
+#define MC2_UPLD_IIC 0x0001 /* Upload I2C. */
+#define MC2_RPSSIG2 0x2000 /* RPS signal 2 (not used). */
+#define MC2_RPSSIG1 0x1000 /* RPS signal 1 (DAC RPS busy). */
+#define MC2_RPSSIG0 0x0800 /* RPS signal 0 (ADC RPS busy). */
+
+#define MC2_ADC_RPS MC2_RPSSIG0 /* ADC RPS busy. */
+#define MC2_DAC_RPS MC2_RPSSIG1 /* DAC RPS busy. */
+
+/* ***** oldies ***** */
+#define MC2_UPLD_DEBIQ 0x00020002 /* Upload DEBI registers. */
+#define MC2_UPLD_IICQ 0x00010001 /* Upload I2C registers. */
+
+/* PCI BUS (SAA7146) REGISTER ADDRESS OFFSETS */
+#define P_PCI_BT_A 0x004C /* Audio DMA burst/threshold control. */
+#define P_DEBICFG 0x007C /* DEBI configuration. */
+#define P_DEBICMD 0x0080 /* DEBI command. */
+#define P_DEBIPAGE 0x0084 /* DEBI page. */
+#define P_DEBIAD 0x0088 /* DEBI target address. */
+#define P_I2CCTRL 0x008C /* I2C control. */
+#define P_I2CSTAT 0x0090 /* I2C status. */
+#define P_BASEA2_IN 0x00AC /* Audio input 2 base physical DMAbuf
+ * address. */
+#define P_PROTA2_IN 0x00B0 /* Audio input 2 physical DMAbuf
+ * protection address. */
+#define P_PAGEA2_IN 0x00B4 /* Audio input 2 paging attributes. */
+#define P_BASEA2_OUT 0x00B8 /* Audio output 2 base physical DMAbuf
+ * address. */
+#define P_PROTA2_OUT 0x00BC /* Audio output 2 physical DMAbuf
+ * protection address. */
+#define P_PAGEA2_OUT 0x00C0 /* Audio output 2 paging attributes. */
+#define P_RPSPAGE0 0x00C4 /* RPS0 page. */
+#define P_RPSPAGE1 0x00C8 /* RPS1 page. */
+#define P_RPS0_TOUT 0x00D4 /* RPS0 time-out. */
+#define P_RPS1_TOUT 0x00D8 /* RPS1 time-out. */
+#define P_IER 0x00DC /* Interrupt enable. */
+#define P_GPIO 0x00E0 /* General-purpose I/O. */
+#define P_EC1SSR 0x00E4 /* Event counter set 1 source select. */
+#define P_ECT1R 0x00EC /* Event counter threshold set 1. */
+#define P_ACON1 0x00F4 /* Audio control 1. */
+#define P_ACON2 0x00F8 /* Audio control 2. */
+#define P_MC1 0x00FC /* Master control 1. */
+#define P_MC2 0x0100 /* Master control 2. */
+#define P_RPSADDR0 0x0104 /* RPS0 instruction pointer. */
+#define P_RPSADDR1 0x0108 /* RPS1 instruction pointer. */
+#define P_ISR 0x010C /* Interrupt status. */
+#define P_PSR 0x0110 /* Primary status. */
+#define P_SSR 0x0114 /* Secondary status. */
+#define P_EC1R 0x0118 /* Event counter set 1. */
+#define P_ADP4 0x0138 /* Logical audio DMA pointer of audio
+ * input FIFO A2_IN. */
+#define P_FB_BUFFER1 0x0144 /* Audio feedback buffer 1. */
+#define P_FB_BUFFER2 0x0148 /* Audio feedback buffer 2. */
+#define P_TSL1 0x0180 /* Audio time slot list 1. */
+#define P_TSL2 0x01C0 /* Audio time slot list 2. */
+
+/* LOCAL BUS (GATE ARRAY) REGISTER ADDRESS OFFSETS */
+/* Analog I/O registers: */
+#define LP_DACPOL 0x0082 /* Write DAC polarity. */
+#define LP_GSEL 0x0084 /* Write ADC gain. */
+#define LP_ISEL 0x0086 /* Write ADC channel select. */
+/* Digital I/O (write only): */
+#define LP_WRINTSELA 0x0042 /* Write A interrupt enable. */
+#define LP_WREDGSELA 0x0044 /* Write A edge selection. */
+#define LP_WRCAPSELA 0x0046 /* Write A capture enable. */
+#define LP_WRDOUTA 0x0048 /* Write A digital output. */
+#define LP_WRINTSELB 0x0052 /* Write B interrupt enable. */
+#define LP_WREDGSELB 0x0054 /* Write B edge selection. */
+#define LP_WRCAPSELB 0x0056 /* Write B capture enable. */
+#define LP_WRDOUTB 0x0058 /* Write B digital output. */
+#define LP_WRINTSELC 0x0062 /* Write C interrupt enable. */
+#define LP_WREDGSELC 0x0064 /* Write C edge selection. */
+#define LP_WRCAPSELC 0x0066 /* Write C capture enable. */
+#define LP_WRDOUTC 0x0068 /* Write C digital output. */
+
+/* Digital I/O (read only): */
+#define LP_RDDINA 0x0040 /* Read digital input. */
+#define LP_RDCAPFLGA 0x0048 /* Read edges captured. */
+#define LP_RDINTSELA 0x004A /* Read interrupt enable register. */
+#define LP_RDEDGSELA 0x004C /* Read edge selection register. */
+#define LP_RDCAPSELA 0x004E /* Read capture enable register. */
+#define LP_RDDINB 0x0050 /* Read digital input. */
+#define LP_RDCAPFLGB 0x0058 /* Read edges captured. */
+#define LP_RDINTSELB 0x005A /* Read interrupt enable register. */
+#define LP_RDEDGSELB 0x005C /* Read edge selection register. */
+#define LP_RDCAPSELB 0x005E /* Read capture enable register. */
+#define LP_RDDINC 0x0060 /* Read digital input. */
+#define LP_RDCAPFLGC 0x0068 /* Read edges captured. */
+#define LP_RDINTSELC 0x006A /* Read interrupt enable register. */
+#define LP_RDEDGSELC 0x006C /* Read edge selection register. */
+#define LP_RDCAPSELC 0x006E /* Read capture enable register. */
+
+/* Counter Registers (read/write): */
+#define LP_CR0A 0x0000 /* 0A setup register. */
+#define LP_CR0B 0x0002 /* 0B setup register. */
+#define LP_CR1A 0x0004 /* 1A setup register. */
+#define LP_CR1B 0x0006 /* 1B setup register. */
+#define LP_CR2A 0x0008 /* 2A setup register. */
+#define LP_CR2B 0x000A /* 2B setup register. */
+
+/* Counter PreLoad (write) and Latch (read) Registers: */
+#define LP_CNTR0ALSW 0x000C /* 0A lsw. */
+#define LP_CNTR0AMSW 0x000E /* 0A msw. */
+#define LP_CNTR0BLSW 0x0010 /* 0B lsw. */
+#define LP_CNTR0BMSW 0x0012 /* 0B msw. */
+#define LP_CNTR1ALSW 0x0014 /* 1A lsw. */
+#define LP_CNTR1AMSW 0x0016 /* 1A msw. */
+#define LP_CNTR1BLSW 0x0018 /* 1B lsw. */
+#define LP_CNTR1BMSW 0x001A /* 1B msw. */
+#define LP_CNTR2ALSW 0x001C /* 2A lsw. */
+#define LP_CNTR2AMSW 0x001E /* 2A msw. */
+#define LP_CNTR2BLSW 0x0020 /* 2B lsw. */
+#define LP_CNTR2BMSW 0x0022 /* 2B msw. */
+
+/* Miscellaneous Registers (read/write): */
+#define LP_MISC1 0x0088 /* Read/write Misc1. */
+#define LP_WRMISC2 0x0090 /* Write Misc2. */
+#define LP_RDMISC2 0x0082 /* Read Misc2. */
+
+/* Bit masks for MISC1 register that are the same for reads and writes. */
+#define MISC1_WENABLE 0x8000 /* enab writes to MISC2 (except Clear
+ * Watchdog bit). */
+#define MISC1_WDISABLE 0x0000 /* Disable writes to MISC2. */
+#define MISC1_EDCAP 0x1000 /* enab edge capture on DIO chans
+ * specified by LP_WRCAPSELx. */
+#define MISC1_NOEDCAP 0x0000 /* Disable edge capture on specified
+ * DIO chans. */
+
+/* Bit masks for MISC1 register reads. */
+#define RDMISC1_WDTIMEOUT 0x4000 /* Watchdog timer timed out. */
+
+/* Bit masks for MISC2 register writes. */
+#define WRMISC2_WDCLEAR 0x8000 /* Reset watchdog timer to zero. */
+#define WRMISC2_CHARGE_ENABLE 0x4000 /* enab battery trickle charging. */
+
+/* Bit masks for MISC2 register that are the same for reads and writes. */
+#define MISC2_BATT_ENABLE 0x0008 /* Backup battery enable. */
+#define MISC2_WDENABLE 0x0004 /* Watchdog timer enable. */
+#define MISC2_WDPERIOD_MASK 0x0003 /* Watchdog interval */
+ /* select mask. */
+
+/* Bit masks for ACON1 register. */
+#define A2_RUN 0x40000000 /* Run A2 based on TSL2. */
+#define A1_RUN 0x20000000 /* Run A1 based on TSL1. */
+#define A1_SWAP 0x00200000 /* Use big-endian for A1. */
+#define A2_SWAP 0x00100000 /* Use big-endian for A2. */
+#define WS_MODES 0x00019999 /* WS0 = TSL1 trigger */
+ /* input, WS1-WS4 = */
+ /* CS* outputs. */
+
+#if PLATFORM == INTEL /* Base ACON1 config: always run A1 based
+ * on TSL1. */
+#define ACON1_BASE (WS_MODES | A1_RUN)
#elif PLATFORM == MOTOROLA
-#define ACON1_BASE ( WS_MODES | A1_RUN | A1_SWAP | A2_SWAP )
+#define ACON1_BASE (WS_MODES | A1_RUN | A1_SWAP | A2_SWAP)
#endif
-#define ACON1_ADCSTART ACON1_BASE // Start ADC: run A1
- // based on TSL1.
-#define ACON1_DACSTART ( ACON1_BASE | A2_RUN ) // Start
- // transmit to
- // DAC: run A2
- // based on
- // TSL2.
-#define ACON1_DACSTOP ACON1_BASE // Halt A2.
-
-// Bit masks for ACON2 register.
-#define A1_CLKSRC_BCLK1 0x00000000 // A1 bit rate = BCLK1 (ADC).
-#define A2_CLKSRC_X1 0x00800000 // A2 bit rate = ACLK/1 (DACs).
-#define A2_CLKSRC_X2 0x00C00000 // A2 bit rate = ACLK/2 (DACs).
-#define A2_CLKSRC_X4 0x01400000 // A2 bit rate = ACLK/4 (DACs).
-#define INVERT_BCLK2 0x00100000 // Invert BCLK2 (DACs).
-#define BCLK2_OE 0x00040000 // enab BCLK2 (DACs).
-#define ACON2_XORMASK 0x000C0000 // XOR mask for ACON2
- // active-low bits.
-
-#define ACON2_INIT ( ACON2_XORMASK ^ ( A1_CLKSRC_BCLK1 | A2_CLKSRC_X2 | INVERT_BCLK2 | BCLK2_OE ) )
-
-// Bit masks for timeslot records.
-#define WS1 0x40000000 // WS output to assert.
+#define ACON1_ADCSTART ACON1_BASE /* Start ADC: run A1
+ * based on TSL1. */
+#define ACON1_DACSTART (ACON1_BASE | A2_RUN)
+/* Start transmit to DAC: run A2 based on TSL2. */
+#define ACON1_DACSTOP ACON1_BASE /* Halt A2. */
+
+/* Bit masks for ACON2 register. */
+#define A1_CLKSRC_BCLK1 0x00000000 /* A1 bit rate = BCLK1 (ADC). */
+#define A2_CLKSRC_X1 0x00800000 /* A2 bit rate = ACLK/1 (DACs). */
+#define A2_CLKSRC_X2 0x00C00000 /* A2 bit rate = ACLK/2 (DACs). */
+#define A2_CLKSRC_X4 0x01400000 /* A2 bit rate = ACLK/4 (DACs). */
+#define INVERT_BCLK2 0x00100000 /* Invert BCLK2 (DACs). */
+#define BCLK2_OE 0x00040000 /* enab BCLK2 (DACs). */
+#define ACON2_XORMASK 0x000C0000 /* XOR mask for ACON2 */
+ /* active-low bits. */
+
+#define ACON2_INIT (ACON2_XORMASK ^ (A1_CLKSRC_BCLK1 | A2_CLKSRC_X2 | INVERT_BCLK2 | BCLK2_OE))
+
+/* Bit masks for timeslot records. */
+#define WS1 0x40000000 /* WS output to assert. */
#define WS2 0x20000000
#define WS3 0x10000000
#define WS4 0x08000000
-#define RSD1 0x01000000 // Shift A1 data in on SD1.
-#define SDW_A1 0x00800000 // Store rcv'd char at
- // next char slot of
- // DWORD1 buffer.
-#define SIB_A1 0x00400000 // Store rcv'd char at
- // next char slot of
- // FB1 buffer.
-#define SF_A1 0x00200000 // Write unsigned long
- // buffer to input
- // FIFO.
-
-//Select parallel-to-serial converter's data source:
-#define XFIFO_0 0x00000000 // Data fifo byte 0.
-#define XFIFO_1 0x00000010 // Data fifo byte 1.
-#define XFIFO_2 0x00000020 // Data fifo byte 2.
-#define XFIFO_3 0x00000030 // Data fifo byte 3.
-#define XFB0 0x00000040 // FB_BUFFER byte 0.
-#define XFB1 0x00000050 // FB_BUFFER byte 1.
-#define XFB2 0x00000060 // FB_BUFFER byte 2.
-#define XFB3 0x00000070 // FB_BUFFER byte 3.
-#define SIB_A2 0x00000200 // Store next dword
- // from A2's input
- // shifter to FB2
- // buffer.
-#define SF_A2 0x00000100 // Store next dword
- // from A2's input
- // shifter to its
- // input fifo.
-#define LF_A2 0x00000080 // Load next dword
- // from A2's output
- // fifo into its
- // output dword
- // buffer.
-#define XSD2 0x00000008 // Shift data out on SD2.
-#define RSD3 0x00001800 // Shift data in on SD3.
-#define RSD2 0x00001000 // Shift data in on SD2.
-#define LOW_A2 0x00000002 // Drive last SD low
- // for 7 clks, then
- // tri-state.
-#define EOS 0x00000001 // End of superframe.
-
-//////////////////////
-
-// I2C configuration constants.
-#define I2C_CLKSEL 0x0400 // I2C bit rate =
- // PCIclk/480 = 68.75
- // KHz.
-#define I2C_BITRATE 68.75 // I2C bus data bit
- // rate (determined by
- // I2C_CLKSEL) in KHz.
-#define I2C_WRTIME 15.0 // Worst case time,in
- // msec, for EEPROM
- // internal write op.
-
-// I2C manifest constants.
-
-// Max retries to wait for EEPROM write.
-#define I2C_RETRIES ( I2C_WRTIME * I2C_BITRATE / 9.0 )
-#define I2C_ERR 0x0002 // I2C control/status
- // flag ERROR.
-#define I2C_BUSY 0x0001 // I2C control/status
- // flag BUSY.
-#define I2C_ABORT 0x0080 // I2C status flag ABORT.
-#define I2C_ATTRSTART 0x3 // I2C attribute START.
-#define I2C_ATTRCONT 0x2 // I2C attribute CONT.
-#define I2C_ATTRSTOP 0x1 // I2C attribute STOP.
-#define I2C_ATTRNOP 0x0 // I2C attribute NOP.
-
-// I2C read command | EEPROM address.
-#define I2CR ( devpriv->I2CAdrs | 1 )
-
-// I2C write command | EEPROM address.
-#define I2CW ( devpriv->I2CAdrs )
-
-// Code macros used for constructing I2C command bytes.
-#define I2C_B2(ATTR,VAL) ( ( (ATTR) << 6 ) | ( (VAL) << 24 ) )
-#define I2C_B1(ATTR,VAL) ( ( (ATTR) << 4 ) | ( (VAL) << 16 ) )
-#define I2C_B0(ATTR,VAL) ( ( (ATTR) << 2 ) | ( (VAL) << 8 ) )
-
-////////////////////////////////////////////////////////
-//oldest
-#define P_DEBICFGq 0x007C // DEBI configuration.
-#define P_DEBICMDq 0x0080 // DEBI command.
-#define P_DEBIPAGEq 0x0084 // DEBI page.
-#define P_DEBIADq 0x0088 // DEBI target address.
-
-#define DEBI_CFG_TOQ 0x03C00000 // timeout (15 PCI cycles)
-#define DEBI_CFG_FASTQ 0x10000000 // fast mode enable
-#define DEBI_CFG_16Q 0x00080000 // 16-bit access enable
-#define DEBI_CFG_INCQ 0x00040000 // enable address increment
-#define DEBI_CFG_TIMEROFFQ 0x00010000 // disable timer
-#define DEBI_CMD_RDQ 0x00050000 // read immediate 2 bytes
-#define DEBI_CMD_WRQ 0x00040000 // write immediate 2 bytes
-#define DEBI_PAGE_DISABLEQ 0x00000000 // paging disable
-
-///////////////////////////////////////////
-// DEBI command constants.
-#define DEBI_CMD_SIZE16 ( 2 << 17 ) // Transfer size is
- // always 2 bytes.
-#define DEBI_CMD_READ 0x00010000 // Read operation.
-#define DEBI_CMD_WRITE 0x00000000 // Write operation.
-
-// Read immediate 2 bytes.
-#define DEBI_CMD_RDWORD ( DEBI_CMD_READ | DEBI_CMD_SIZE16 )
-
-// Write immediate 2 bytes.
-#define DEBI_CMD_WRWORD ( DEBI_CMD_WRITE | DEBI_CMD_SIZE16 )
-
-// DEBI configuration constants.
-#define DEBI_CFG_XIRQ_EN 0x80000000 // enab external
- // interrupt on GPIO3.
-#define DEBI_CFG_XRESUME 0x40000000 // Resume block
- // transfer when XIRQ
- // deasserted.
-#define DEBI_CFG_FAST 0x10000000 // Fast mode enable.
-
-// 4-bit field that specifies DEBI timeout value in PCI clock cycles:
-#define DEBI_CFG_TOUT_BIT 22 // Finish DEBI cycle after
- // this many clocks.
-
-// 2-bit field that specifies Endian byte lane steering:
-#define DEBI_CFG_SWAP_NONE 0x00000000 // Straight - don't
- // swap any bytes
- // (Intel).
-#define DEBI_CFG_SWAP_2 0x00100000 // 2-byte swap (Motorola).
-#define DEBI_CFG_SWAP_4 0x00200000 // 4-byte swap.
-#define DEBI_CFG_16 0x00080000 // Slave is able to
- // serve 16-bit
- // cycles.
-
-#define DEBI_CFG_SLAVE16 0x00080000 // Slave is able to
- // serve 16-bit
- // cycles.
-#define DEBI_CFG_INC 0x00040000 // enab address
- // increment for block
- // transfers.
-#define DEBI_CFG_INTEL 0x00020000 // Intel style local bus.
-#define DEBI_CFG_TIMEROFF 0x00010000 // Disable timer.
+#define RSD1 0x01000000 /* Shift A1 data in on SD1. */
+#define SDW_A1 0x00800000 /* Store rcv'd char at next
+ * char slot of DWORD1 buffer. */
+#define SIB_A1 0x00400000 /* Store rcv'd char at next
+ * char slot of FB1 buffer. */
+#define SF_A1 0x00200000 /* Write unsigned long
+ * buffer to input FIFO. */
+
+/* Select parallel-to-serial converter's data source: */
+#define XFIFO_0 0x00000000 /* Data fifo byte 0. */
+#define XFIFO_1 0x00000010 /* Data fifo byte 1. */
+#define XFIFO_2 0x00000020 /* Data fifo byte 2. */
+#define XFIFO_3 0x00000030 /* Data fifo byte 3. */
+#define XFB0 0x00000040 /* FB_BUFFER byte 0. */
+#define XFB1 0x00000050 /* FB_BUFFER byte 1. */
+#define XFB2 0x00000060 /* FB_BUFFER byte 2. */
+#define XFB3 0x00000070 /* FB_BUFFER byte 3. */
+#define SIB_A2 0x00000200 /* Store next dword from A2's
+ * input shifter to FB2 buffer. */
+#define SF_A2 0x00000100 /* Store next dword from A2's
+ * input shifter to its input
+ * fifo. */
+#define LF_A2 0x00000080 /* Load next dword from A2's
+ * output fifo into its
+ * output dword buffer. */
+#define XSD2 0x00000008 /* Shift data out on SD2. */
+#define RSD3 0x00001800 /* Shift data in on SD3. */
+#define RSD2 0x00001000 /* Shift data in on SD2. */
+#define LOW_A2 0x00000002 /* Drive last SD low */
+ /* for 7 clks, then */
+ /* tri-state. */
+#define EOS 0x00000001 /* End of superframe. */
+
+
+/* I2C configuration constants. */
+#define I2C_CLKSEL 0x0400
+/* I2C bit rate = PCIclk/480 = 68.75 KHz. */
+
+#define I2C_BITRATE 68.75
+/* I2C bus data bit rate (determined by I2C_CLKSEL) in KHz. */
+
+#define I2C_WRTIME 15.0
+/* Worst case time, in msec, for EEPROM internal write op. */
+
+/* I2C manifest constants. */
+
+/* Max retries to wait for EEPROM write. */
+#define I2C_RETRIES (I2C_WRTIME * I2C_BITRATE / 9.0)
+#define I2C_ERR 0x0002 /* I2C control/status */
+ /* flag ERROR. */
+#define I2C_BUSY 0x0001 /* I2C control/status */
+ /* flag BUSY. */
+#define I2C_ABORT 0x0080 /* I2C status flag ABORT. */
+#define I2C_ATTRSTART 0x3 /* I2C attribute START. */
+#define I2C_ATTRCONT 0x2 /* I2C attribute CONT. */
+#define I2C_ATTRSTOP 0x1 /* I2C attribute STOP. */
+#define I2C_ATTRNOP 0x0 /* I2C attribute NOP. */
+
+/* I2C read command | EEPROM address. */
+#define I2CR (devpriv->I2CAdrs | 1)
+
+/* I2C write command | EEPROM address. */
+#define I2CW (devpriv->I2CAdrs)
+
+/* Code macros used for constructing I2C command bytes. */
+#define I2C_B2(ATTR, VAL) (((ATTR) << 6) | ((VAL) << 24))
+#define I2C_B1(ATTR, VAL) (((ATTR) << 4) | ((VAL) << 16))
+#define I2C_B0(ATTR, VAL) (((ATTR) << 2) | ((VAL) << 8))
+
+/* oldest */
+#define P_DEBICFGq 0x007C /* DEBI configuration. */
+#define P_DEBICMDq 0x0080 /* DEBI command. */
+#define P_DEBIPAGEq 0x0084 /* DEBI page. */
+#define P_DEBIADq 0x0088 /* DEBI target address. */
+
+#define DEBI_CFG_TOQ 0x03C00000 /* timeout (15 PCI cycles) */
+#define DEBI_CFG_FASTQ 0x10000000 /* fast mode enable */
+#define DEBI_CFG_16Q 0x00080000 /* 16-bit access enable */
+#define DEBI_CFG_INCQ 0x00040000 /* enable address increment */
+#define DEBI_CFG_TIMEROFFQ 0x00010000 /* disable timer */
+#define DEBI_CMD_RDQ 0x00050000 /* read immediate 2 bytes */
+#define DEBI_CMD_WRQ 0x00040000 /* write immediate 2 bytes */
+#define DEBI_PAGE_DISABLEQ 0x00000000 /* paging disable */
+
+/* DEBI command constants. */
+#define DEBI_CMD_SIZE16 (2 << 17) /* Transfer size is */
+ /* always 2 bytes. */
+#define DEBI_CMD_READ 0x00010000 /* Read operation. */
+#define DEBI_CMD_WRITE 0x00000000 /* Write operation. */
+
+/* Read immediate 2 bytes. */
+#define DEBI_CMD_RDWORD (DEBI_CMD_READ | DEBI_CMD_SIZE16)
+
+/* Write immediate 2 bytes. */
+#define DEBI_CMD_WRWORD (DEBI_CMD_WRITE | DEBI_CMD_SIZE16)
+
+/* DEBI configuration constants. */
+#define DEBI_CFG_XIRQ_EN 0x80000000 /* enab external */
+ /* interrupt on GPIO3. */
+#define DEBI_CFG_XRESUME 0x40000000 /* Resume block */
+ /* transfer when XIRQ */
+ /* deasserted. */
+#define DEBI_CFG_FAST 0x10000000 /* Fast mode enable. */
+
+/* 4-bit field that specifies DEBI timeout value in PCI clock cycles: */
+#define DEBI_CFG_TOUT_BIT 22 /* Finish DEBI cycle after */
+ /* this many clocks. */
+
+/* 2-bit field that specifies Endian byte lane steering: */
+#define DEBI_CFG_SWAP_NONE 0x00000000 /* Straight - don't */
+ /* swap any bytes */
+ /* (Intel). */
+#define DEBI_CFG_SWAP_2 0x00100000 /* 2-byte swap (Motorola). */
+#define DEBI_CFG_SWAP_4 0x00200000 /* 4-byte swap. */
+#define DEBI_CFG_16 0x00080000 /* Slave is able to */
+ /* serve 16-bit */
+ /* cycles. */
+
+#define DEBI_CFG_SLAVE16 0x00080000 /* Slave is able to */
+ /* serve 16-bit */
+ /* cycles. */
+#define DEBI_CFG_INC 0x00040000 /* enab address */
+ /* increment for block */
+ /* transfers. */
+#define DEBI_CFG_INTEL 0x00020000 /* Intel style local bus. */
+#define DEBI_CFG_TIMEROFF 0x00010000 /* Disable timer. */
#if PLATFORM == INTEL
-#define DEBI_TOUT 7 // Wait 7 PCI clocks
- // (212 ns) before
- // polling RDY.
+#define DEBI_TOUT 7 /* Wait 7 PCI clocks */
+ /* (212 ns) before */
+ /* polling RDY. */
-// Intel byte lane steering (pass through all byte lanes).
+/* Intel byte lane steering (pass through all byte lanes). */
#define DEBI_SWAP DEBI_CFG_SWAP_NONE
#elif PLATFORM == MOTOROLA
-#define DEBI_TOUT 15 // Wait 15 PCI clocks (454 ns)
- // maximum before timing out.
-#define DEBI_SWAP DEBI_CFG_SWAP_2 // Motorola byte lane steering.
+#define DEBI_TOUT 15 /* Wait 15 PCI clocks (454 ns) */
+ /* maximum before timing out. */
+#define DEBI_SWAP DEBI_CFG_SWAP_2 /* Motorola byte lane steering. */
#endif
-// DEBI page table constants.
-#define DEBI_PAGE_DISABLE 0x00000000 // Paging disable.
-
-///////////////////EXTRA FROM OTHER SANSORAY * .h////////
-
-// LoadSrc values:
-#define LOADSRC_INDX 0 // Preload core in response to
- // Index.
-#define LOADSRC_OVER 1 // Preload core in response to
- // Overflow.
-#define LOADSRCB_OVERA 2 // Preload B core in response
- // to A Overflow.
-#define LOADSRC_NONE 3 // Never preload core.
-
-// IntSrc values:
-#define INTSRC_NONE 0 // Interrupts disabled.
-#define INTSRC_OVER 1 // Interrupt on Overflow.
-#define INTSRC_INDX 2 // Interrupt on Index.
-#define INTSRC_BOTH 3 // Interrupt on Index or Overflow.
-
-// LatchSrc values:
-#define LATCHSRC_AB_READ 0 // Latch on read.
-#define LATCHSRC_A_INDXA 1 // Latch A on A Index.
-#define LATCHSRC_B_INDXB 2 // Latch B on B Index.
-#define LATCHSRC_B_OVERA 3 // Latch B on A Overflow.
-
-// IndxSrc values:
-#define INDXSRC_HARD 0 // Hardware or software index.
-#define INDXSRC_SOFT 1 // Software index only.
-
-// IndxPol values:
-#define INDXPOL_POS 0 // Index input is active high.
-#define INDXPOL_NEG 1 // Index input is active low.
-
-// ClkSrc values:
-#define CLKSRC_COUNTER 0 // Counter mode.
-#define CLKSRC_TIMER 2 // Timer mode.
-#define CLKSRC_EXTENDER 3 // Extender mode.
-
-// ClkPol values:
-#define CLKPOL_POS 0 // Counter/Extender clock is
- // active high.
-#define CLKPOL_NEG 1 // Counter/Extender clock is
- // active low.
-#define CNTDIR_UP 0 // Timer counts up.
-#define CNTDIR_DOWN 1 // Timer counts down.
-
-// ClkEnab values:
-#define CLKENAB_ALWAYS 0 // Clock always enabled.
-#define CLKENAB_INDEX 1 // Clock is enabled by index.
-
-// ClkMult values:
-#define CLKMULT_4X 0 // 4x clock multiplier.
-#define CLKMULT_2X 1 // 2x clock multiplier.
-#define CLKMULT_1X 2 // 1x clock multiplier.
-
-// Bit Field positions in COUNTER_SETUP structure:
-#define BF_LOADSRC 9 // Preload trigger.
-#define BF_INDXSRC 7 // Index source.
-#define BF_INDXPOL 6 // Index polarity.
-#define BF_CLKSRC 4 // Clock source.
-#define BF_CLKPOL 3 // Clock polarity/count direction.
-#define BF_CLKMULT 1 // Clock multiplier.
-#define BF_CLKENAB 0 // Clock enable.
-
-// Enumerated counter operating modes specified by ClkSrc bit field in
-// a COUNTER_SETUP.
-
-#define CLKSRC_COUNTER 0 // Counter: ENC_C clock, ENC_D
- // direction.
-#define CLKSRC_TIMER 2 // Timer: SYS_C clock,
- // direction specified by
- // ClkPol.
-#define CLKSRC_EXTENDER 3 // Extender: OVR_A clock,
- // ENC_D direction.
-
-// Enumerated counter clock multipliers.
-
-#define MULT_X0 0x0003 // Supports no multipliers;
- // fixed physical multiplier =
- // 3.
-#define MULT_X1 0x0002 // Supports multiplier x1;
- // fixed physical multiplier =
- // 2.
-#define MULT_X2 0x0001 // Supports multipliers x1,
- // x2; physical multipliers =
- // 1 or 2.
-#define MULT_X4 0x0000 // Supports multipliers x1,
- // x2, x4; physical
- // multipliers = 0, 1 or 2.
-
-// Sanity-check limits for parameters.
-
-#define NUM_COUNTERS 6 // Maximum valid counter
- // logical channel number.
+/* DEBI page table constants. */
+#define DEBI_PAGE_DISABLE 0x00000000 /* Paging disable. */
+
+/* ******* EXTRA FROM OTHER SANSORAY * .h ******* */
+
+/* LoadSrc values: */
+#define LOADSRC_INDX 0 /* Preload core in response to */
+ /* Index. */
+#define LOADSRC_OVER 1 /* Preload core in response to */
+ /* Overflow. */
+#define LOADSRCB_OVERA 2 /* Preload B core in response */
+ /* to A Overflow. */
+#define LOADSRC_NONE 3 /* Never preload core. */
+
+/* IntSrc values: */
+#define INTSRC_NONE 0 /* Interrupts disabled. */
+#define INTSRC_OVER 1 /* Interrupt on Overflow. */
+#define INTSRC_INDX 2 /* Interrupt on Index. */
+#define INTSRC_BOTH 3 /* Interrupt on Index or Overflow. */
+
+/* LatchSrc values: */
+#define LATCHSRC_AB_READ 0 /* Latch on read. */
+#define LATCHSRC_A_INDXA 1 /* Latch A on A Index. */
+#define LATCHSRC_B_INDXB 2 /* Latch B on B Index. */
+#define LATCHSRC_B_OVERA 3 /* Latch B on A Overflow. */
+
+/* IndxSrc values: */
+#define INDXSRC_HARD 0 /* Hardware or software index. */
+#define INDXSRC_SOFT 1 /* Software index only. */
+
+/* IndxPol values: */
+#define INDXPOL_POS 0 /* Index input is active high. */
+#define INDXPOL_NEG 1 /* Index input is active low. */
+
+/* ClkSrc values: */
+#define CLKSRC_COUNTER 0 /* Counter mode. */
+#define CLKSRC_TIMER 2 /* Timer mode. */
+#define CLKSRC_EXTENDER 3 /* Extender mode. */
+
+/* ClkPol values: */
+#define CLKPOL_POS 0 /* Counter/Extender clock is */
+ /* active high. */
+#define CLKPOL_NEG 1 /* Counter/Extender clock is */
+ /* active low. */
+#define CNTDIR_UP 0 /* Timer counts up. */
+#define CNTDIR_DOWN 1 /* Timer counts down. */
+
+/* ClkEnab values: */
+#define CLKENAB_ALWAYS 0 /* Clock always enabled. */
+#define CLKENAB_INDEX 1 /* Clock is enabled by index. */
+
+/* ClkMult values: */
+#define CLKMULT_4X 0 /* 4x clock multiplier. */
+#define CLKMULT_2X 1 /* 2x clock multiplier. */
+#define CLKMULT_1X 2 /* 1x clock multiplier. */
+
+/* Bit Field positions in COUNTER_SETUP structure: */
+#define BF_LOADSRC 9 /* Preload trigger. */
+#define BF_INDXSRC 7 /* Index source. */
+#define BF_INDXPOL 6 /* Index polarity. */
+#define BF_CLKSRC 4 /* Clock source. */
+#define BF_CLKPOL 3 /* Clock polarity/count direction. */
+#define BF_CLKMULT 1 /* Clock multiplier. */
+#define BF_CLKENAB 0 /* Clock enable. */
+
+/* Enumerated counter operating modes specified by ClkSrc bit field in */
+/* a COUNTER_SETUP. */
+
+#define CLKSRC_COUNTER 0 /* Counter: ENC_C clock, ENC_D */
+ /* direction. */
+#define CLKSRC_TIMER 2 /* Timer: SYS_C clock, */
+ /* direction specified by */
+ /* ClkPol. */
+#define CLKSRC_EXTENDER 3 /* Extender: OVR_A clock, */
+ /* ENC_D direction. */
+
+/* Enumerated counter clock multipliers. */
+
+#define MULT_X0 0x0003 /* Supports no multipliers; */
+ /* fixed physical multiplier = */
+ /* 3. */
+#define MULT_X1 0x0002 /* Supports multiplier x1; */
+ /* fixed physical multiplier = */
+ /* 2. */
+#define MULT_X2 0x0001 /* Supports multipliers x1, */
+ /* x2; physical multipliers = */
+ /* 1 or 2. */
+#define MULT_X4 0x0000 /* Supports multipliers x1, */
+ /* x2, x4; physical */
+ /* multipliers = 0, 1 or 2. */
+
+/* Sanity-check limits for parameters. */
+
+#define NUM_COUNTERS 6 /* Maximum valid counter */
+ /* logical channel number. */
#define NUM_INTSOURCES 4
#define NUM_LATCHSOURCES 4
#define NUM_CLKMULTS 4
@@ -708,59 +653,59 @@
#define NUM_INDEXSOURCES 2
#define NUM_LOADTRIGS 4
-// Bit field positions in CRA and CRB counter control registers.
-
-// Bit field positions in CRA:
-#define CRABIT_INDXSRC_B 14 // B index source.
-#define CRABIT_CLKSRC_B 12 // B clock source.
-#define CRABIT_INDXPOL_A 11 // A index polarity.
-#define CRABIT_LOADSRC_A 9 // A preload trigger.
-#define CRABIT_CLKMULT_A 7 // A clock multiplier.
-#define CRABIT_INTSRC_A 5 // A interrupt source.
-#define CRABIT_CLKPOL_A 4 // A clock polarity.
-#define CRABIT_INDXSRC_A 2 // A index source.
-#define CRABIT_CLKSRC_A 0 // A clock source.
-
-// Bit field positions in CRB:
-#define CRBBIT_INTRESETCMD 15 // Interrupt reset command.
-#define CRBBIT_INTRESET_B 14 // B interrupt reset enable.
-#define CRBBIT_INTRESET_A 13 // A interrupt reset enable.
-#define CRBBIT_CLKENAB_A 12 // A clock enable.
-#define CRBBIT_INTSRC_B 10 // B interrupt source.
-#define CRBBIT_LATCHSRC 8 // A/B latch source.
-#define CRBBIT_LOADSRC_B 6 // B preload trigger.
-#define CRBBIT_CLKMULT_B 3 // B clock multiplier.
-#define CRBBIT_CLKENAB_B 2 // B clock enable.
-#define CRBBIT_INDXPOL_B 1 // B index polarity.
-#define CRBBIT_CLKPOL_B 0 // B clock polarity.
-
-// Bit field masks for CRA and CRB.
-
-#define CRAMSK_INDXSRC_B ( (uint16_t)( 3 << CRABIT_INDXSRC_B) )
-#define CRAMSK_CLKSRC_B ( (uint16_t)( 3 << CRABIT_CLKSRC_B) )
-#define CRAMSK_INDXPOL_A ( (uint16_t)( 1 << CRABIT_INDXPOL_A) )
-#define CRAMSK_LOADSRC_A ( (uint16_t)( 3 << CRABIT_LOADSRC_A) )
-#define CRAMSK_CLKMULT_A ( (uint16_t)( 3 << CRABIT_CLKMULT_A) )
-#define CRAMSK_INTSRC_A ( (uint16_t)( 3 << CRABIT_INTSRC_A) )
-#define CRAMSK_CLKPOL_A ( (uint16_t)( 3 << CRABIT_CLKPOL_A) )
-#define CRAMSK_INDXSRC_A ( (uint16_t)( 3 << CRABIT_INDXSRC_A) )
-#define CRAMSK_CLKSRC_A ( (uint16_t)( 3 << CRABIT_CLKSRC_A) )
-
-#define CRBMSK_INTRESETCMD ( (uint16_t)( 1 << CRBBIT_INTRESETCMD) )
-#define CRBMSK_INTRESET_B ( (uint16_t)( 1 << CRBBIT_INTRESET_B) )
-#define CRBMSK_INTRESET_A ( (uint16_t)( 1 << CRBBIT_INTRESET_A) )
-#define CRBMSK_CLKENAB_A ( (uint16_t)( 1 << CRBBIT_CLKENAB_A) )
-#define CRBMSK_INTSRC_B ( (uint16_t)( 3 << CRBBIT_INTSRC_B) )
-#define CRBMSK_LATCHSRC ( (uint16_t)( 3 << CRBBIT_LATCHSRC) )
-#define CRBMSK_LOADSRC_B ( (uint16_t)( 3 << CRBBIT_LOADSRC_B) )
-#define CRBMSK_CLKMULT_B ( (uint16_t)( 3 << CRBBIT_CLKMULT_B) )
-#define CRBMSK_CLKENAB_B ( (uint16_t)( 1 << CRBBIT_CLKENAB_B) )
-#define CRBMSK_INDXPOL_B ( (uint16_t)( 1 << CRBBIT_INDXPOL_B) )
-#define CRBMSK_CLKPOL_B ( (uint16_t)( 1 << CRBBIT_CLKPOL_B) )
-
-#define CRBMSK_INTCTRL ( CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A | CRBMSK_INTRESET_B ) // Interrupt reset control bits.
-
-// Bit field positions for standardized SETUP structure.
+/* Bit field positions in CRA and CRB counter control registers. */
+
+/* Bit field positions in CRA: */
+#define CRABIT_INDXSRC_B 14 /* B index source. */
+#define CRABIT_CLKSRC_B 12 /* B clock source. */
+#define CRABIT_INDXPOL_A 11 /* A index polarity. */
+#define CRABIT_LOADSRC_A 9 /* A preload trigger. */
+#define CRABIT_CLKMULT_A 7 /* A clock multiplier. */
+#define CRABIT_INTSRC_A 5 /* A interrupt source. */
+#define CRABIT_CLKPOL_A 4 /* A clock polarity. */
+#define CRABIT_INDXSRC_A 2 /* A index source. */
+#define CRABIT_CLKSRC_A 0 /* A clock source. */
+
+/* Bit field positions in CRB: */
+#define CRBBIT_INTRESETCMD 15 /* Interrupt reset command. */
+#define CRBBIT_INTRESET_B 14 /* B interrupt reset enable. */
+#define CRBBIT_INTRESET_A 13 /* A interrupt reset enable. */
+#define CRBBIT_CLKENAB_A 12 /* A clock enable. */
+#define CRBBIT_INTSRC_B 10 /* B interrupt source. */
+#define CRBBIT_LATCHSRC 8 /* A/B latch source. */
+#define CRBBIT_LOADSRC_B 6 /* B preload trigger. */
+#define CRBBIT_CLKMULT_B 3 /* B clock multiplier. */
+#define CRBBIT_CLKENAB_B 2 /* B clock enable. */
+#define CRBBIT_INDXPOL_B 1 /* B index polarity. */
+#define CRBBIT_CLKPOL_B 0 /* B clock polarity. */
+
+/* Bit field masks for CRA and CRB. */
+
+#define CRAMSK_INDXSRC_B ((uint16_t)(3 << CRABIT_INDXSRC_B))
+#define CRAMSK_CLKSRC_B ((uint16_t)(3 << CRABIT_CLKSRC_B))
+#define CRAMSK_INDXPOL_A ((uint16_t)(1 << CRABIT_INDXPOL_A))
+#define CRAMSK_LOADSRC_A ((uint16_t)(3 << CRABIT_LOADSRC_A))
+#define CRAMSK_CLKMULT_A ((uint16_t)(3 << CRABIT_CLKMULT_A))
+#define CRAMSK_INTSRC_A ((uint16_t)(3 << CRABIT_INTSRC_A))
+#define CRAMSK_CLKPOL_A ((uint16_t)(3 << CRABIT_CLKPOL_A))
+#define CRAMSK_INDXSRC_A ((uint16_t)(3 << CRABIT_INDXSRC_A))
+#define CRAMSK_CLKSRC_A ((uint16_t)(3 << CRABIT_CLKSRC_A))
+
+#define CRBMSK_INTRESETCMD ((uint16_t)(1 << CRBBIT_INTRESETCMD))
+#define CRBMSK_INTRESET_B ((uint16_t)(1 << CRBBIT_INTRESET_B))
+#define CRBMSK_INTRESET_A ((uint16_t)(1 << CRBBIT_INTRESET_A))
+#define CRBMSK_CLKENAB_A ((uint16_t)(1 << CRBBIT_CLKENAB_A))
+#define CRBMSK_INTSRC_B ((uint16_t)(3 << CRBBIT_INTSRC_B))
+#define CRBMSK_LATCHSRC ((uint16_t)(3 << CRBBIT_LATCHSRC))
+#define CRBMSK_LOADSRC_B ((uint16_t)(3 << CRBBIT_LOADSRC_B))
+#define CRBMSK_CLKMULT_B ((uint16_t)(3 << CRBBIT_CLKMULT_B))
+#define CRBMSK_CLKENAB_B ((uint16_t)(1 << CRBBIT_CLKENAB_B))
+#define CRBMSK_INDXPOL_B ((uint16_t)(1 << CRBBIT_INDXPOL_B))
+#define CRBMSK_CLKPOL_B ((uint16_t)(1 << CRBBIT_CLKPOL_B))
+
+#define CRBMSK_INTCTRL (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A | CRBMSK_INTRESET_B) /* Interrupt reset control bits. */
+
+/* Bit field positions for standardized SETUP structure. */
#define STDBIT_INTSRC 13
#define STDBIT_LATCHSRC 11
@@ -772,19 +717,18 @@
#define STDBIT_CLKMULT 1
#define STDBIT_CLKENAB 0
-// Bit field masks for standardized SETUP structure.
+/* Bit field masks for standardized SETUP structure. */
-#define STDMSK_INTSRC ( (uint16_t)( 3 << STDBIT_INTSRC ) )
-#define STDMSK_LATCHSRC ( (uint16_t)( 3 << STDBIT_LATCHSRC ) )
-#define STDMSK_LOADSRC ( (uint16_t)( 3 << STDBIT_LOADSRC ) )
-#define STDMSK_INDXSRC ( (uint16_t)( 1 << STDBIT_INDXSRC ) )
-#define STDMSK_INDXPOL ( (uint16_t)( 1 << STDBIT_INDXPOL ) )
-#define STDMSK_CLKSRC ( (uint16_t)( 3 << STDBIT_CLKSRC ) )
-#define STDMSK_CLKPOL ( (uint16_t)( 1 << STDBIT_CLKPOL ) )
-#define STDMSK_CLKMULT ( (uint16_t)( 3 << STDBIT_CLKMULT ) )
-#define STDMSK_CLKENAB ( (uint16_t)( 1 << STDBIT_CLKENAB ) )
+#define STDMSK_INTSRC ((uint16_t)(3 << STDBIT_INTSRC))
+#define STDMSK_LATCHSRC ((uint16_t)(3 << STDBIT_LATCHSRC))
+#define STDMSK_LOADSRC ((uint16_t)(3 << STDBIT_LOADSRC))
+#define STDMSK_INDXSRC ((uint16_t)(1 << STDBIT_INDXSRC))
+#define STDMSK_INDXPOL ((uint16_t)(1 << STDBIT_INDXPOL))
+#define STDMSK_CLKSRC ((uint16_t)(3 << STDBIT_CLKSRC))
+#define STDMSK_CLKPOL ((uint16_t)(1 << STDBIT_CLKPOL))
+#define STDMSK_CLKMULT ((uint16_t)(3 << STDBIT_CLKMULT))
+#define STDMSK_CLKENAB ((uint16_t)(1 << STDBIT_CLKENAB))
-//////////////////////////////////////////////////////////
/* typedef struct indexCounter */
/* { */
@@ -795,8 +739,8 @@
/* unsigned int enc; */
/* }CallCounter; */
-typedef struct bufferDMA {
+struct bufferDMA {
dma_addr_t PhysicalBase;
void *LogicalBase;
uint32_t DMAHandle;
-} DMABUF;
+};
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
new file mode 100644
index 00000000000..844fd5e2e3a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -0,0 +1,870 @@
+/*
+ comedi/drivers/serial2002.c
+ Skeleton code for a Comedi driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2002 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ 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.
+
+*/
+
+/*
+Driver: serial2002
+Description: Driver for serial connected hardware
+Devices:
+Author: Anders Blomdell
+Updated: Fri, 7 Jun 2002 12:56:45 -0700
+Status: in development
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/ioport.h>
+
+#include <asm/termios.h>
+#include <asm/ioctls.h>
+#include <linux/serial.h>
+#include <linux/poll.h>
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct serial2002_board {
+ const char *name;
+};
+
+static const struct serial2002_board serial2002_boards[] = {
+ {
+ name: "serial2002"}
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct serial2002_board *)dev->board_ptr)
+
+struct serial2002_range_table_t {
+
+ // HACK...
+ int length;
+ struct comedi_krange range;
+};
+
+
+struct serial2002_private {
+
+ int port; // /dev/ttyS<port>
+ int speed; // baudrate
+ struct file *tty;
+ unsigned int ao_readback[32];
+ unsigned char digital_in_mapping[32];
+ unsigned char digital_out_mapping[32];
+ unsigned char analog_in_mapping[32];
+ unsigned char analog_out_mapping[32];
+ unsigned char encoder_in_mapping[32];
+ struct serial2002_range_table_t in_range[32], out_range[32];
+};
+
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct serial2002_private *)dev->private)
+
+static int serial2002_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int serial2002_detach(struct comedi_device * dev);
+struct comedi_driver driver_serial2002 = {
+ driver_name:"serial2002",
+ module:THIS_MODULE,
+ attach:serial2002_attach,
+ detach:serial2002_detach,
+ board_name:&serial2002_boards[0].name,
+ offset:sizeof(struct serial2002_board),
+ num_names:sizeof(serial2002_boards) / sizeof(struct serial2002_board),
+};
+
+static int serial2002_di_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int serial2002_do_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int serial2002_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int serial2002_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int serial2002_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+struct serial_data {
+ enum { is_invalid, is_digital, is_channel } kind;
+ int index;
+ unsigned long value;
+};
+
+static long tty_ioctl(struct file *f, unsigned op, unsigned long param)
+{
+#ifdef HAVE_UNLOCKED_IOCTL
+ if (f->f_op->unlocked_ioctl) {
+ return f->f_op->unlocked_ioctl(f, op, param);
+ }
+#endif
+ if (f->f_op->ioctl) {
+ return f->f_op->ioctl(f->f_dentry->d_inode, f, op, param);
+ }
+ return -ENOSYS;
+}
+
+static int tty_write(struct file *f, unsigned char *buf, int count)
+{
+ int result;
+ mm_segment_t oldfs;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ f->f_pos = 0;
+ result = f->f_op->write(f, buf, count, &f->f_pos);
+ set_fs(oldfs);
+ return result;
+}
+
+#if 0
+/*
+ * On 2.6.26.3 this occaisonally gave me page faults, worked around by
+ * settings.c_cc[VMIN] = 0; settings.c_cc[VTIME] = 0
+ */
+static int tty_available(struct file *f)
+{
+ long result = 0;
+ mm_segment_t oldfs;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ tty_ioctl(f, FIONREAD, (unsigned long)&result);
+ set_fs(oldfs);
+ return result;
+}
+#endif
+
+static int tty_read(struct file *f, int timeout)
+{
+ int result;
+
+ result = -1;
+ if (!IS_ERR(f)) {
+ mm_segment_t oldfs;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ if (f->f_op->poll) {
+ struct poll_wqueues table;
+ struct timeval start, now;
+
+ do_gettimeofday(&start);
+ poll_initwait(&table);
+ while (1) {
+ long elapsed;
+ int mask;
+
+ mask = f->f_op->poll(f, &table.pt);
+ if (mask & (POLLRDNORM | POLLRDBAND | POLLIN |
+ POLLHUP | POLLERR)) {
+ break;
+ }
+ do_gettimeofday(&now);
+ elapsed =
+ (1000000 * (now.tv_sec - start.tv_sec) +
+ now.tv_usec - start.tv_usec);
+ if (elapsed > timeout) {
+ break;
+ }
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(((timeout -
+ elapsed) * HZ) / 10000);
+ }
+ poll_freewait(&table);
+ {
+ unsigned char ch;
+
+ f->f_pos = 0;
+ if (f->f_op->read(f, &ch, 1, &f->f_pos) == 1) {
+ result = ch;
+ }
+ }
+ } else {
+ /* Device does not support poll, busy wait */
+ int retries = 0;
+ while (1) {
+ unsigned char ch;
+
+ retries++;
+ if (retries >= timeout) {
+ break;
+ }
+
+ f->f_pos = 0;
+ if (f->f_op->read(f, &ch, 1, &f->f_pos) == 1) {
+ result = ch;
+ break;
+ }
+ comedi_udelay(100);
+ }
+ }
+ set_fs(oldfs);
+ }
+ return result;
+}
+
+static void tty_setspeed(struct file *f, int speed)
+{
+ mm_segment_t oldfs;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ {
+ // Set speed
+ struct termios settings;
+
+ tty_ioctl(f, TCGETS, (unsigned long)&settings);
+// printk("Speed: %d\n", settings.c_cflag & (CBAUD | CBAUDEX));
+ settings.c_iflag = 0;
+ settings.c_oflag = 0;
+ settings.c_lflag = 0;
+ settings.c_cflag = CLOCAL | CS8 | CREAD;
+ settings.c_cc[VMIN] = 0;
+ settings.c_cc[VTIME] = 0;
+ switch (speed) {
+ case 2400:{
+ settings.c_cflag |= B2400;
+ }
+ break;
+ case 4800:{
+ settings.c_cflag |= B4800;
+ }
+ break;
+ case 9600:{
+ settings.c_cflag |= B9600;
+ }
+ break;
+ case 19200:{
+ settings.c_cflag |= B19200;
+ }
+ break;
+ case 38400:{
+ settings.c_cflag |= B38400;
+ }
+ break;
+ case 57600:{
+ settings.c_cflag |= B57600;
+ }
+ break;
+ case 115200:{
+ settings.c_cflag |= B115200;
+ }
+ break;
+ default:{
+ settings.c_cflag |= B9600;
+ }
+ break;
+ }
+ tty_ioctl(f, TCSETS, (unsigned long)&settings);
+// printk("Speed: %d\n", settings.c_cflag & (CBAUD | CBAUDEX));
+ }
+ {
+ // Set low latency
+ struct serial_struct settings;
+
+ tty_ioctl(f, TIOCGSERIAL, (unsigned long)&settings);
+ settings.flags |= ASYNC_LOW_LATENCY;
+ tty_ioctl(f, TIOCSSERIAL, (unsigned long)&settings);
+ }
+
+ set_fs(oldfs);
+}
+
+static void poll_digital(struct file *f, int channel)
+{
+ char cmd;
+
+ cmd = 0x40 | (channel & 0x1f);
+ tty_write(f, &cmd, 1);
+}
+
+static void poll_channel(struct file *f, int channel)
+{
+ char cmd;
+
+ cmd = 0x60 | (channel & 0x1f);
+ tty_write(f, &cmd, 1);
+}
+
+static struct serial_data serial_read(struct file *f, int timeout)
+{
+ struct serial_data result;
+ int length;
+
+ result.kind = is_invalid;
+ result.index = 0;
+ result.value = 0;
+ length = 0;
+ while (1) {
+ int data = tty_read(f, timeout);
+
+ length++;
+ if (data < 0) {
+ printk("serial2002 error\n");
+ break;
+ } else if (data & 0x80) {
+ result.value = (result.value << 7) | (data & 0x7f);
+ } else {
+ if (length == 1) {
+ switch ((data >> 5) & 0x03) {
+ case 0:{
+ result.value = 0;
+ result.kind = is_digital;
+ }
+ break;
+ case 1:{
+ result.value = 1;
+ result.kind = is_digital;
+ }
+ break;
+ }
+ } else {
+ result.value =
+ (result.
+ value << 2) | ((data & 0x60) >> 5);
+ result.kind = is_channel;
+ }
+ result.index = data & 0x1f;
+ break;
+ }
+ }
+ return result;
+
+}
+
+static void serial_write(struct file *f, struct serial_data data)
+{
+ if (data.kind == is_digital) {
+ unsigned char ch =
+ ((data.value << 5) & 0x20) | (data.index & 0x1f);
+ tty_write(f, &ch, 1);
+ } else {
+ unsigned char ch[6];
+ int i = 0;
+ if (data.value >= (1L << 30)) {
+ ch[i] = 0x80 | ((data.value >> 30) & 0x03);
+ i++;
+ }
+ if (data.value >= (1L << 23)) {
+ ch[i] = 0x80 | ((data.value >> 23) & 0x7f);
+ i++;
+ }
+ if (data.value >= (1L << 16)) {
+ ch[i] = 0x80 | ((data.value >> 16) & 0x7f);
+ i++;
+ }
+ if (data.value >= (1L << 9)) {
+ ch[i] = 0x80 | ((data.value >> 9) & 0x7f);
+ i++;
+ }
+ ch[i] = 0x80 | ((data.value >> 2) & 0x7f);
+ i++;
+ ch[i] = ((data.value << 5) & 0x60) | (data.index & 0x1f);
+ i++;
+ tty_write(f, ch, i);
+ }
+}
+
+static void serial_2002_open(struct comedi_device * dev)
+{
+ char port[20];
+
+ sprintf(port, "/dev/ttyS%d", devpriv->port);
+ devpriv->tty = filp_open(port, 0, O_RDWR);
+ if (IS_ERR(devpriv->tty)) {
+ printk("serial_2002: file open error = %ld\n",
+ PTR_ERR(devpriv->tty));
+ } else {
+ struct config_t {
+
+ int kind;
+ int bits;
+ int min;
+ int max;
+ };
+
+ struct config_t dig_in_config[32];
+ struct config_t dig_out_config[32];
+ struct config_t chan_in_config[32];
+ struct config_t chan_out_config[32];
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ dig_in_config[i].kind = 0;
+ dig_in_config[i].bits = 0;
+ dig_in_config[i].min = 0;
+ dig_in_config[i].max = 0;
+ dig_out_config[i].kind = 0;
+ dig_out_config[i].bits = 0;
+ dig_out_config[i].min = 0;
+ dig_out_config[i].max = 0;
+ chan_in_config[i].kind = 0;
+ chan_in_config[i].bits = 0;
+ chan_in_config[i].min = 0;
+ chan_in_config[i].max = 0;
+ chan_out_config[i].kind = 0;
+ chan_out_config[i].bits = 0;
+ chan_out_config[i].min = 0;
+ chan_out_config[i].max = 0;
+ }
+
+ tty_setspeed(devpriv->tty, devpriv->speed);
+ poll_channel(devpriv->tty, 31); // Start reading configuration
+ while (1) {
+ struct serial_data data;
+
+ data = serial_read(devpriv->tty, 1000);
+ if (data.kind != is_channel || data.index != 31
+ || !(data.value & 0xe0)) {
+ break;
+ } else {
+ int command, channel, kind;
+ struct config_t *cur_config = 0;
+
+ channel = data.value & 0x1f;
+ kind = (data.value >> 5) & 0x7;
+ command = (data.value >> 8) & 0x3;
+ switch (kind) {
+ case 1:{
+ cur_config = dig_in_config;
+ }
+ break;
+ case 2:{
+ cur_config = dig_out_config;
+ }
+ break;
+ case 3:{
+ cur_config = chan_in_config;
+ }
+ break;
+ case 4:{
+ cur_config = chan_out_config;
+ }
+ break;
+ case 5:{
+ cur_config = chan_in_config;
+ }
+ break;
+ }
+
+ if (cur_config) {
+ cur_config[channel].kind = kind;
+ switch (command) {
+ case 0:{
+ cur_config[channel].
+ bits =
+ (data.
+ value >> 10) &
+ 0x3f;
+ }
+ break;
+ case 1:{
+ int unit, sign, min;
+ unit = (data.
+ value >> 10) &
+ 0x7;
+ sign = (data.
+ value >> 13) &
+ 0x1;
+ min = (data.
+ value >> 14) &
+ 0xfffff;
+
+ switch (unit) {
+ case 0:{
+ min = min * 1000000;
+ }
+ break;
+ case 1:{
+ min = min * 1000;
+ }
+ break;
+ case 2:{
+ min = min * 1;
+ }
+ break;
+ }
+ if (sign) {
+ min = -min;
+ }
+ cur_config[channel].
+ min = min;
+ }
+ break;
+ case 2:{
+ int unit, sign, max;
+ unit = (data.
+ value >> 10) &
+ 0x7;
+ sign = (data.
+ value >> 13) &
+ 0x1;
+ max = (data.
+ value >> 14) &
+ 0xfffff;
+
+ switch (unit) {
+ case 0:{
+ max = max * 1000000;
+ }
+ break;
+ case 1:{
+ max = max * 1000;
+ }
+ break;
+ case 2:{
+ max = max * 1;
+ }
+ break;
+ }
+ if (sign) {
+ max = -max;
+ }
+ cur_config[channel].
+ max = max;
+ }
+ break;
+ }
+ }
+ }
+ }
+ for (i = 0; i <= 4; i++) {
+ // Fill in subdev data
+ struct config_t *c;
+ unsigned char *mapping = 0;
+ struct serial2002_range_table_t *range = 0;
+ int kind = 0;
+
+ switch (i) {
+ case 0:{
+ c = dig_in_config;
+ mapping = devpriv->digital_in_mapping;
+ kind = 1;
+ }
+ break;
+ case 1:{
+ c = dig_out_config;
+ mapping = devpriv->digital_out_mapping;
+ kind = 2;
+ }
+ break;
+ case 2:{
+ c = chan_in_config;
+ mapping = devpriv->analog_in_mapping;
+ range = devpriv->in_range;
+ kind = 3;
+ }
+ break;
+ case 3:{
+ c = chan_out_config;
+ mapping = devpriv->analog_out_mapping;
+ range = devpriv->out_range;
+ kind = 4;
+ }
+ break;
+ case 4:{
+ c = chan_in_config;
+ mapping = devpriv->encoder_in_mapping;
+ range = devpriv->in_range;
+ kind = 5;
+ }
+ break;
+ default:{
+ c = 0;
+ }
+ break;
+ }
+ if (c) {
+ struct comedi_subdevice *s;
+ const struct comedi_lrange **range_table_list = NULL;
+ unsigned int *maxdata_list;
+ int j, chan;
+
+ for (chan = 0, j = 0; j < 32; j++) {
+ if (c[j].kind == kind) {
+ chan++;
+ }
+ }
+ s = &dev->subdevices[i];
+ s->n_chan = chan;
+ s->maxdata = 0;
+ if (s->maxdata_list) {
+ kfree(s->maxdata_list);
+ }
+ s->maxdata_list = maxdata_list =
+ kmalloc(sizeof(unsigned int) * s->n_chan,
+ GFP_KERNEL);
+ if (s->range_table_list) {
+ kfree(s->range_table_list);
+ }
+ if (range) {
+ s->range_table = 0;
+ s->range_table_list = range_table_list =
+ kmalloc(sizeof
+ (struct serial2002_range_table_t) *
+ s->n_chan, GFP_KERNEL);
+ }
+ for (chan = 0, j = 0; j < 32; j++) {
+ if (c[j].kind == kind) {
+ if (mapping) {
+ mapping[chan] = j;
+ }
+ if (range) {
+ range[j].length = 1;
+ range[j].range.min =
+ c[j].min;
+ range[j].range.max =
+ c[j].max;
+ range_table_list[chan] =
+ (const struct
+ comedi_lrange *)
+ &range[j];
+ }
+ maxdata_list[chan] =
+ ((long long)1 << c[j].
+ bits) - 1;
+ chan++;
+ }
+ }
+ }
+ }
+ }
+}
+
+static void serial_2002_close(struct comedi_device * dev)
+{
+ if (!IS_ERR(devpriv->tty) && (devpriv->tty != 0)) {
+ filp_close(devpriv->tty, 0);
+ }
+}
+
+static int serial2002_di_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan;
+
+ chan = devpriv->digital_in_mapping[CR_CHAN(insn->chanspec)];
+ for (n = 0; n < insn->n; n++) {
+ struct serial_data read;
+
+ poll_digital(devpriv->tty, chan);
+ while (1) {
+ read = serial_read(devpriv->tty, 1000);
+ if (read.kind != is_digital || read.index == chan) {
+ break;
+ }
+ }
+ data[n] = read.value;
+ }
+ return n;
+}
+
+static int serial2002_do_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan;
+
+ chan = devpriv->digital_out_mapping[CR_CHAN(insn->chanspec)];
+ for (n = 0; n < insn->n; n++) {
+ struct serial_data write;
+
+ write.kind = is_digital;
+ write.index = chan;
+ write.value = data[n];
+ serial_write(devpriv->tty, write);
+ }
+ return n;
+}
+
+static int serial2002_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan;
+
+ chan = devpriv->analog_in_mapping[CR_CHAN(insn->chanspec)];
+ for (n = 0; n < insn->n; n++) {
+ struct serial_data read;
+
+ poll_channel(devpriv->tty, chan);
+ while (1) {
+ read = serial_read(devpriv->tty, 1000);
+ if (read.kind != is_channel || read.index == chan) {
+ break;
+ }
+ }
+ data[n] = read.value;
+ }
+ return n;
+}
+
+static int serial2002_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan;
+
+ chan = devpriv->analog_out_mapping[CR_CHAN(insn->chanspec)];
+ for (n = 0; n < insn->n; n++) {
+ struct serial_data write;
+
+ write.kind = is_channel;
+ write.index = chan;
+ write.value = data[n];
+ serial_write(devpriv->tty, write);
+ devpriv->ao_readback[chan] = data[n];
+ }
+ return n;
+}
+
+static int serial2002_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ data[n] = devpriv->ao_readback[chan];
+ }
+
+ return n;
+}
+
+static int serial2002_ei_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan;
+
+ chan = devpriv->encoder_in_mapping[CR_CHAN(insn->chanspec)];
+ for (n = 0; n < insn->n; n++) {
+ struct serial_data read;
+
+ poll_channel(devpriv->tty, chan);
+ while (1) {
+ read = serial_read(devpriv->tty, 1000);
+ if (read.kind != is_channel || read.index == chan) {
+ break;
+ }
+ }
+ data[n] = read.value;
+ }
+ return n;
+}
+
+static int serial2002_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+
+ printk("comedi%d: serial2002: ", dev->minor);
+ dev->board_name = thisboard->name;
+ if (alloc_private(dev, sizeof(struct serial2002_private)) < 0) {
+ return -ENOMEM;
+ }
+ dev->open = serial_2002_open;
+ dev->close = serial_2002_close;
+ devpriv->port = it->options[0];
+ devpriv->speed = it->options[1];
+ printk("/dev/ttyS%d @ %d\n", devpriv->port, devpriv->speed);
+
+ if (alloc_subdevices(dev, 5) < 0)
+ return -ENOMEM;
+
+ /* digital input subdevice */
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_read = &serial2002_di_rinsn;
+
+ /* digital output subdevice */
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_write = &serial2002_do_winsn;
+
+ /* analog input subdevice */
+ s = dev->subdevices + 2;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = 0;
+ s->insn_read = &serial2002_ai_rinsn;
+
+ /* analog output subdevice */
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = 0;
+ s->insn_write = &serial2002_ao_winsn;
+ s->insn_read = &serial2002_ao_rinsn;
+
+ /* encoder input subdevice */
+ s = dev->subdevices + 4;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = 0;
+ s->insn_read = &serial2002_ei_rinsn;
+
+ return 1;
+}
+
+static int serial2002_detach(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s;
+ int i;
+
+ printk("comedi%d: serial2002: remove\n", dev->minor);
+ for (i = 0; i < 4; i++) {
+ s = &dev->subdevices[i];
+ if (s->maxdata_list) {
+ kfree(s->maxdata_list);
+ }
+ if (s->range_table_list) {
+ kfree(s->range_table_list);
+ }
+ }
+ return 0;
+}
+
+COMEDI_INITCLEANUP(driver_serial2002);
diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c
new file mode 100644
index 00000000000..c7700d134cc
--- /dev/null
+++ b/drivers/staging/comedi/drivers/skel.c
@@ -0,0 +1,624 @@
+/*
+ comedi/drivers/skel.c
+ Skeleton code for a Comedi driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: skel
+Description: Skeleton driver, an example for driver writers
+Devices:
+Author: ds
+Updated: Mon, 18 Mar 2002 15:34:01 -0800
+Status: works
+
+This driver is a documented example on how Comedi drivers are
+written.
+
+Configuration Options:
+ none
+*/
+
+/*
+ * The previous block comment is used to automatically generate
+ * documentation in Comedi and Comedilib. The fields:
+ *
+ * Driver: the name of the driver
+ * Description: a short phrase describing the driver. Don't list boards.
+ * Devices: a full list of the boards that attempt to be supported by
+ * the driver. Format is "(manufacturer) board name [comedi name]",
+ * where comedi_name is the name that is used to configure the board.
+ * See the comment near board_name: in the struct comedi_driver structure
+ * below. If (manufacturer) or [comedi name] is missing, the previous
+ * value is used.
+ * Author: you
+ * Updated: date when the _documentation_ was last updated. Use 'date -R'
+ * to get a value for this.
+ * Status: a one-word description of the status. Valid values are:
+ * works - driver works correctly on most boards supported, and
+ * passes comedi_test.
+ * unknown - unknown. Usually put there by ds.
+ * experimental - may not work in any particular release. Author
+ * probably wants assistance testing it.
+ * bitrotten - driver has not been update in a long time, probably
+ * doesn't work, and probably is missing support for significant
+ * Comedi interface features.
+ * untested - author probably wrote it "blind", and is believed to
+ * work, but no confirmation.
+ *
+ * These headers should be followed by a blank line, and any comments
+ * you wish to say about the driver. The comment area is the place
+ * to put any known bugs, limitations, unsupported features, supported
+ * command triggers, whether or not commands are supported on particular
+ * subdevices, etc.
+ *
+ * Somewhere in the comment should be information about configuration
+ * options that are used with comedi_config.
+ */
+
+#include "../comedidev.h"
+
+#include <linux/pci.h> /* for PCI devices */
+
+/* Imaginary registers for the imaginary board */
+
+#define SKEL_SIZE 0
+
+#define SKEL_START_AI_CONV 0
+#define SKEL_AI_READ 0
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct skel_board {
+ const char *name;
+ int ai_chans;
+ int ai_bits;
+ int have_dio;
+};
+
+static const struct skel_board skel_boards[] = {
+ {
+ name: "skel-100",
+ ai_chans:16,
+ ai_bits: 12,
+ have_dio:1,
+ },
+ {
+ name: "skel-200",
+ ai_chans:8,
+ ai_bits: 16,
+ have_dio:0,
+ },
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers. Should
+ * only be used for PCI and ISA-PnP devices */
+/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
+ * upstream. */
+#define PCI_VENDOR_ID_SKEL 0xdafe
+static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = {
+ {PCI_VENDOR_ID_SKEL, 0x0100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_SKEL, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, skel_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct skel_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct skel_private {
+
+ int data;
+
+ /* would be useful for a PCI device */
+ struct pci_dev *pci_dev;
+
+ /* Used for AO readback */
+ unsigned int ao_readback[2];
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct skel_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int skel_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int skel_detach(struct comedi_device * dev);
+static struct comedi_driver driver_skel = {
+ driver_name:"dummy",
+ module:THIS_MODULE,
+ attach:skel_attach,
+ detach:skel_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+ /* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in skel_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+ board_name:&skel_boards[0].name,
+ offset:sizeof(struct skel_board),
+ num_names:sizeof(skel_boards) / sizeof(struct skel_board),
+};
+
+static int skel_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int skel_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int skel_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int skel_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int skel_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int skel_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int skel_ns_to_timer(unsigned int *ns, int round);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int skel_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+
+ printk("comedi%d: skel: ", dev->minor);
+
+/*
+ * If you can probe the device to determine what device in a series
+ * it is, this is the place to do it. Otherwise, dev->board_ptr
+ * should already be initialized.
+ */
+ /* dev->board_ptr = skel_probe(dev, it); */
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct skel_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* dev->read_subdev=s; */
+ /* analog input subdevice */
+ s->type = COMEDI_SUBD_AI;
+ /* we support single-ended (ground) and differential */
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
+ s->n_chan = thisboard->ai_chans;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = &range_bipolar10;
+ s->len_chanlist = 16; /* This is the maximum chanlist length that
+ the board can handle */
+ s->insn_read = skel_ai_rinsn;
+/*
+* s->subdev_flags |= SDF_CMD_READ;
+* s->do_cmd = skel_ai_cmd;
+*/
+ s->do_cmdtest = skel_ai_cmdtest;
+
+ s = dev->subdevices + 1;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 1;
+ s->maxdata = 0xffff;
+ s->range_table = &range_bipolar5;
+ s->insn_write = skel_ao_winsn;
+ s->insn_read = skel_ao_rinsn;
+
+ s = dev->subdevices + 2;
+ /* digital i/o subdevice */
+ if (thisboard->have_dio) {
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = skel_dio_insn_bits;
+ s->insn_config = skel_dio_insn_config;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ printk("attached\n");
+
+ return 0;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int skel_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: skel: remove\n", dev->minor);
+
+ return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int skel_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i;
+ unsigned int d;
+ unsigned int status;
+
+ /* a typical programming sequence */
+
+ /* write channel to multiplexer */
+ /* outw(chan,dev->iobase + SKEL_MUX); */
+
+ /* don't wait for mux to settle */
+
+ /* convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ /* outw(0,dev->iobase + SKEL_CONVERT); */
+
+#define TIMEOUT 100
+ /* wait for conversion to end */
+ for (i = 0; i < TIMEOUT; i++) {
+ status = 1;
+ /* status = inb(dev->iobase + SKEL_STATUS); */
+ if (status)
+ break;
+ }
+ if (i == TIMEOUT) {
+ /* rt_printk() should be used instead of printk()
+ * whenever the code can be called from real-time. */
+ rt_printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ /* read data */
+ /* d = inw(dev->iobase + SKEL_AI_DATA); */
+ d = 0;
+
+ /* mangle the data as necessary */
+ d ^= 1 << (thisboard->ai_bits - 1);
+
+ data[n] = d;
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+static int skel_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED 10000 /* in nanoseconds */
+#define MIN_SPEED 1000000000 /* in nanoseconds */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < MAX_SPEED) {
+ cmd->scan_begin_arg = MAX_SPEED;
+ err++;
+ }
+ if (cmd->scan_begin_arg > MIN_SPEED) {
+ cmd->scan_begin_arg = MIN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* should be level/edge, hi/lo specification here */
+ /* should specify multiple external triggers */
+ if (cmd->scan_begin_arg > 9) {
+ cmd->scan_begin_arg = 9;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < MAX_SPEED) {
+ cmd->convert_arg = MAX_SPEED;
+ err++;
+ }
+ if (cmd->convert_arg > MIN_SPEED) {
+ cmd->convert_arg = MIN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* see above */
+ if (cmd->convert_arg > 9) {
+ cmd->convert_arg = 9;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg > 0x00ffffff) {
+ cmd->stop_arg = 0x00ffffff;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ skel_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ skel_ns_to_timer(&cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+/* This function doesn't require a particular form, this is just
+ * what happens to be used in some of the drivers. It should
+ * convert ns nanoseconds to a counter value suitable for programming
+ * the device. Also, it should adjust ns so that it cooresponds to
+ * the actual time that the device will use. */
+static int skel_ns_to_timer(unsigned int *ns, int round)
+{
+ /* trivial timer */
+ /* if your timing is done through two cascaded timers, the
+ * i8253_cascade_ns_to_timer() function in 8253.h can be
+ * very helpful. There are also i8254_load() and i8254_mm_load()
+ * which can be used to load values into the ubiquitous 8254 counters
+ */
+
+ return *ns;
+}
+
+static int skel_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ printk("skel_ao_winsn\n");
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ /* a typical programming sequence */
+ /* outw(data[i],dev->iobase + SKEL_DA0 + chan); */
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int skel_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int skel_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ /* Write out the new digital output lines */
+ /* outw(s->state,dev->iobase + SKEL_DIO); */
+ }
+
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ /* data[1]=inw(dev->iobase + SKEL_DIO); */
+ /* or we could just return the software copy of the output values if
+ * it was a purely digital output subdevice */
+ /* data[1]=s->state; */
+
+ return 2;
+}
+
+static int skel_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+
+ /* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= 1 << chan;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~(1 << chan);
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->
+ io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ /* outw(s->io_bits,dev->iobase + SKEL_DIO_CONFIG); */
+
+ return insn->n;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_skel);
+/* If you are writing a PCI driver you should use COMEDI_PCI_INITCLEANUP instead.
+*/
+/* COMEDI_PCI_INITCLEANUP(driver_skel, skel_pci_table) */
diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c
new file mode 100644
index 00000000000..1628d216cdd
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ssv_dnp.c
@@ -0,0 +1,311 @@
+/*
+ comedi/drivers/ssv_dnp.c
+ generic comedi driver for SSV Embedded Systems' DIL/Net-PCs
+ Copyright (C) 2001 Robert Schwebel <robert@schwebel.de>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ssv_dnp
+Description: SSV Embedded Systems DIL/Net-PC
+Author: Robert Schwebel <robert@schwebel.de>
+Devices: [SSV Embedded Systems] DIL/Net-PC 1486 (dnp-1486)
+Status: unknown
+*/
+
+/* include files ----------------------------------------------------------- */
+
+#include "../comedidev.h"
+
+/* Some global definitions: the registers of the DNP ----------------------- */
+/* */
+/* For port A and B the mode register has bits corresponding to the output */
+/* pins, where Bit-N = 0 -> input, Bit-N = 1 -> output. Note that bits */
+/* 4 to 7 correspond to pin 0..3 for port C data register. Ensure that bits */
+/* 0..3 remain unchanged! For details about Port C Mode Register see */
+/* the remarks in dnp_insn_config() below. */
+
+#define CSCIR 0x22 /* Chip Setup and Control Index Register */
+#define CSCDR 0x23 /* Chip Setup and Control Data Register */
+#define PAMR 0xa5 /* Port A Mode Register */
+#define PADR 0xa9 /* Port A Data Register */
+#define PBMR 0xa4 /* Port B Mode Register */
+#define PBDR 0xa8 /* Port B Data Register */
+#define PCMR 0xa3 /* Port C Mode Register */
+#define PCDR 0xa7 /* Port C Data Register */
+
+/* This data structure holds information about the supported boards -------- */
+
+struct dnp_board {
+ const char *name;
+ int ai_chans;
+ int ai_bits;
+ int have_dio;
+};
+
+static const struct dnp_board dnp_boards[] = { /* we only support one DNP 'board' */
+ { /* variant at the moment */
+ name: "dnp-1486",
+ ai_chans:16,
+ ai_bits: 12,
+ have_dio:1,
+ },
+};
+
+/* Useful for shorthand access to the particular board structure ----------- */
+#define thisboard ((const struct dnp_board *)dev->board_ptr)
+
+/* This structure is for data unique to the DNP driver --------------------- */
+struct dnp_private_data {
+
+ //
+};
+
+
+/* Shorthand macro for faster access to the private data ------------------- */
+#define devpriv ((dnp_private *)dev->private)
+
+/* ------------------------------------------------------------------------- */
+/* The struct comedi_driver structure tells the Comedi core module which functions */
+/* to call to configure/deconfigure (attach/detach) the board, and also */
+/* about the kernel module that contains the device code. */
+/* */
+/* In the following section we define the API of this driver. */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dnp_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_dnp = {
+ driver_name:"ssv_dnp",
+ module:THIS_MODULE,
+ attach:dnp_attach,
+ detach:dnp_detach,
+ board_name:&dnp_boards[0].name,
+ /* only necessary for non-PnP devs */
+ offset:sizeof(struct dnp_board),/* like ISA-PnP, PCI or PCMCIA. */
+ num_names:sizeof(dnp_boards) / sizeof(struct dnp_board),
+};
+
+COMEDI_INITCLEANUP(driver_dnp);
+
+static int dnp_dio_insn_bits(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int dnp_dio_insn_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+/* ------------------------------------------------------------------------- */
+/* Attach is called by comedi core to configure the driver for a particular */
+/* board. If you specified a board_name array in the driver structure, */
+/* dev->board_ptr contains that address. */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+
+ struct comedi_subdevice *s;
+
+ printk("comedi%d: dnp: ", dev->minor);
+
+ /* Autoprobing: this should find out which board we have. Currently only */
+ /* the 1486 board is supported and autoprobing is not implemented :-) */
+ //dev->board_ptr = dnp_probe(dev);
+
+ /* Initialize the name of the board. We can use the "thisboard" macro now. */
+ dev->board_name = thisboard->name;
+
+ /* Allocate the private structure area. alloc_private() is a convenient */
+ /* macro defined in comedidev.h. */
+ if (alloc_private(dev, sizeof(struct dnp_private_data)) < 0)
+ return -ENOMEM;
+
+ /* Allocate the subdevice structures. alloc_subdevice() is a convenient */
+ /* macro defined in comedidev.h. */
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* digital i/o subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 20;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = dnp_dio_insn_bits;
+ s->insn_config = dnp_dio_insn_config;
+
+ printk("attached\n");
+
+ /* We use the I/O ports 0x22,0x23 and 0xa3-0xa9, which are always
+ * allocated for the primary 8259, so we don't need to allocate them
+ * ourselves. */
+
+ /* configure all ports as input (default) */
+ outb(PAMR, CSCIR);
+ outb(0x00, CSCDR);
+ outb(PBMR, CSCIR);
+ outb(0x00, CSCDR);
+ outb(PCMR, CSCIR);
+ outb((inb(CSCDR) & 0xAA), CSCDR);
+
+ return 1;
+
+}
+
+/* ------------------------------------------------------------------------- */
+/* detach is called to deconfigure a device. It should deallocate the */
+/* resources. This function is also called when _attach() fails, so it */
+/* should be careful not to release resources that were not necessarily */
+/* allocated by _attach(). dev->private and dev->subdevices are */
+/* deallocated automatically by the core. */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_detach(struct comedi_device * dev)
+{
+
+ /* configure all ports as input (default) */
+ outb(PAMR, CSCIR);
+ outb(0x00, CSCDR);
+ outb(PBMR, CSCIR);
+ outb(0x00, CSCDR);
+ outb(PCMR, CSCIR);
+ outb((inb(CSCDR) & 0xAA), CSCDR);
+
+ /* announce that we are finished */
+ printk("comedi%d: dnp: remove\n", dev->minor);
+
+ return 0;
+
+}
+
+/* ------------------------------------------------------------------------- */
+/* The insn_bits interface allows packed reading/writing of DIO channels. */
+/* The comedi core can convert between insn_bits and insn_read/write, so you */
+/* are able to use these instructions as well. */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_dio_insn_bits(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+ if (insn->n != 2)
+ return -EINVAL; /* insn uses data[0] and data[1] */
+
+ /* The insn data is a mask in data[0] and the new data in data[1], each */
+ /* channel cooresponding to a bit. */
+
+ /* Ports A and B are straight forward: each bit corresponds to an output */
+ /* pin with the same order. Port C is different: bits 0...3 correspond to */
+ /* bits 4...7 of the output register (PCDR). */
+
+ if (data[0]) {
+
+ outb(PADR, CSCIR);
+ outb((inb(CSCDR)
+ & ~(u8) (data[0] & 0x0000FF))
+ | (u8) (data[1] & 0x0000FF), CSCDR);
+
+ outb(PBDR, CSCIR);
+ outb((inb(CSCDR)
+ & ~(u8) ((data[0] & 0x00FF00) >> 8))
+ | (u8) ((data[1] & 0x00FF00) >> 8), CSCDR);
+
+ outb(PCDR, CSCIR);
+ outb((inb(CSCDR)
+ & ~(u8) ((data[0] & 0x0F0000) >> 12))
+ | (u8) ((data[1] & 0x0F0000) >> 12), CSCDR);
+ }
+
+ /* on return, data[1] contains the value of the digital input lines. */
+ outb(PADR, CSCIR);
+ data[0] = inb(CSCDR);
+ outb(PBDR, CSCIR);
+ data[0] += inb(CSCDR) << 8;
+ outb(PCDR, CSCIR);
+ data[0] += ((inb(CSCDR) & 0xF0) << 12);
+
+ return 2;
+
+}
+
+/* ------------------------------------------------------------------------- */
+/* Configure the direction of the bidirectional digital i/o pins. chanspec */
+/* contains the channel to be changed and data[0] contains either */
+/* COMEDI_INPUT or COMEDI_OUTPUT. */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_dio_insn_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+ u8 register_buffer;
+
+ int chan = CR_CHAN(insn->chanspec); /* reduces chanspec to lower 16 bits */
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ case INSN_CONFIG_DIO_INPUT:
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (inb(CSCDR) & (1 << chan)) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ /* Test: which port does the channel belong to? */
+
+ /* We have to pay attention with port C: this is the meaning of PCMR: */
+ /* Bit in PCMR: 7 6 5 4 3 2 1 0 */
+ /* Corresponding port C pin: d 3 d 2 d 1 d 0 d= don't touch */
+
+ if ((chan >= 0) && (chan <= 7)) {
+ /* this is port A */
+ outb(PAMR, CSCIR);
+ } else if ((chan >= 8) && (chan <= 15)) {
+ /* this is port B */
+ chan -= 8;
+ outb(PBMR, CSCIR);
+ } else if ((chan >= 16) && (chan <= 19)) {
+ /* this is port C; multiplication with 2 brings bits into correct */
+ /* position for PCMR! */
+ chan -= 16;
+ chan *= 2;
+ outb(PCMR, CSCIR);
+ } else {
+ return -EINVAL;
+ }
+
+ /* read 'old' direction of the port and set bits (out=1, in=0) */
+ register_buffer = inb(CSCDR);
+ if (data[0] == COMEDI_OUTPUT) {
+ register_buffer |= (1 << chan);
+ } else {
+ register_buffer &= ~(1 << chan);
+ }
+ outb(register_buffer, CSCDR);
+
+ return 1;
+
+}
diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c
new file mode 100644
index 00000000000..dd3b1119319
--- /dev/null
+++ b/drivers/staging/comedi/drivers/unioxx5.c
@@ -0,0 +1,515 @@
+/***************************************************************************
+ * *
+ * comedi/drivers/unioxx5.c *
+ * Driver for Fastwel UNIOxx-5 (analog and digital i/o) boards. *
+ * *
+ * Copyright (C) 2006 Kruchinin Daniil (asgard) [asgard@etersoft.ru] *
+ * *
+ * COMEDI - Linux Control and Measurement Device Interface *
+ * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
+ * *
+ ***************************************************************************/
+/*
+
+Driver: unioxx5
+Description: Driver for Fastwel UNIOxx-5 (analog and digital i/o) boards.
+Author: Kruchinin Daniil (asgard) <asgard@etersoft.ru>
+Status: unknown
+Updated: 2006-10-09
+Devices: [Fastwel] UNIOxx-5 (unioxx5),
+
+ This card supports digital and analog I/O. It written for g01
+ subdevices only.
+ channels range: 0 .. 23 dio channels
+ and 0 .. 11 analog modules range
+ During attaching unioxx5 module displays modules identifiers
+ (see dmesg after comedi_config) in format:
+ | [module_number] module_id |
+
+*/
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+
+#define DRIVER_NAME "unioxx5"
+#define UNIOXX5_SIZE 0x10
+#define UNIOXX5_SUBDEV_BASE 0xA000 /* base addr of first subdev */
+#define UNIOXX5_SUBDEV_ODDS 0x400
+
+/* modules types */
+#define MODULE_DIGITAL 0
+#define MODULE_OUTPUT_MASK 0x80 /* analog input/output */
+
+/* constants for digital i/o */
+#define UNIOXX5_NUM_OF_CHANS 24
+
+/* constants for analog i/o */
+#define TxBE 0x10 /* transmit buffer enable */
+#define RxCA 0x20 /* 1 receive character available */
+#define Rx2CA 0x40 /* 2 receive character available */
+#define Rx4CA 0x80 /* 4 receive character available */
+
+/* bytes mask errors */
+#define Rx2CA_ERR_MASK 0x04 /* 2 bytes receiving error */
+#define Rx4CA_ERR_MASK 0x08 /* 4 bytes receiving error */
+
+/* channel modes */
+#define ALL_2_INPUT 0 /* config all digital channels to input */
+#define ALL_2_OUTPUT 1 /* config all digital channels to output */
+
+/* 'private' structure for each subdevice */
+struct unioxx5_subd_priv {
+ int usp_iobase;
+ unsigned char usp_module_type[12]; /* 12 modules. each can be 70L or 73L */
+ unsigned char usp_extra_data[12][4]; /* for saving previous written value for analog modules */
+ unsigned char usp_prev_wr_val[3]; /* previous written value */
+ unsigned char usp_prev_cn_val[3]; /* previous channel value */
+};
+
+static int unioxx5_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int unioxx5_subdev_write(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ struct comedi_insn * insn, unsigned int * data);
+static int unioxx5_subdev_read(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ struct comedi_insn * insn, unsigned int * data);
+static int unioxx5_insn_config(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ struct comedi_insn * insn, unsigned int * data);
+static int unioxx5_detach(struct comedi_device * dev);
+static int __unioxx5_subdev_init(struct comedi_subdevice * subdev, int subdev_iobase,
+ int minor);
+static int __unioxx5_digital_write(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor);
+static int __unioxx5_digital_read(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor);
+//static void __unioxx5_digital_config(struct unioxx5_subd_priv* usp, int mode);
+static int __unioxx5_analog_write(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor);
+static int __unioxx5_analog_read(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor);
+static int __unioxx5_define_chan_offset(int chan_num);
+static void __unioxx5_analog_config(struct unioxx5_subd_priv * usp, int channel);
+
+static struct comedi_driver unioxx5_driver = {
+ driver_name:DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:unioxx5_attach,
+ detach:unioxx5_detach
+};
+
+COMEDI_INITCLEANUP(unioxx5_driver);
+
+static int unioxx5_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int iobase, i, n_subd;
+ int id, num, ba;
+
+ iobase = it->options[0];
+
+ dev->board_name = DRIVER_NAME;
+ dev->iobase = iobase;
+ iobase += UNIOXX5_SUBDEV_BASE;
+
+ /* defining number of subdevices and getting they types (it must be 'g01') */
+ for (i = n_subd = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) {
+ id = inb(ba + 0xE);
+ num = inb(ba + 0xF);
+
+ if (id != 'g' || num != 1)
+ continue;
+
+ n_subd++;
+ }
+
+ /* unioxx5 can has from two to four subdevices */
+ if (n_subd < 2) {
+ printk(KERN_ERR
+ "your card must has at least 2 'g01' subdevices\n");
+ return -1;
+ }
+
+ if (alloc_subdevices(dev, n_subd) < 0) {
+ printk(KERN_ERR "out of memory\n");
+ return -ENOMEM;
+ }
+
+ /* initializing each of for same subdevices */
+ for (i = 0; i < n_subd; i++, iobase += UNIOXX5_SUBDEV_ODDS) {
+ if (__unioxx5_subdev_init(&dev->subdevices[i], iobase,
+ dev->minor) < 0)
+ return -1;
+ }
+
+ printk("attached\n");
+ return 0;
+}
+
+static int unioxx5_subdev_read(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct unioxx5_subd_priv *usp = subdev->private;
+ int channel, type;
+
+ channel = CR_CHAN(insn->chanspec);
+ type = usp->usp_module_type[channel / 2]; /* defining module type(analog or digital) */
+
+ if (type == MODULE_DIGITAL) {
+ if (!__unioxx5_digital_read(usp, data, channel, dev->minor))
+ return -1;
+ } else {
+ if (!__unioxx5_analog_read(usp, data, channel, dev->minor))
+ return -1;
+ }
+
+ return 1;
+}
+
+static int unioxx5_subdev_write(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct unioxx5_subd_priv *usp = subdev->private;
+ int channel, type;
+
+ channel = CR_CHAN(insn->chanspec);
+ type = usp->usp_module_type[channel / 2]; /* defining module type(analog or digital) */
+
+ if (type == MODULE_DIGITAL) {
+ if (!__unioxx5_digital_write(usp, data, channel, dev->minor))
+ return -1;
+ } else {
+ if (!__unioxx5_analog_write(usp, data, channel, dev->minor))
+ return -1;
+ }
+
+ return 1;
+}
+
+/* for digital modules only */
+static int unioxx5_insn_config(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel_offset, flags, channel = CR_CHAN(insn->chanspec), type;
+ struct unioxx5_subd_priv *usp = subdev->private;
+ int mask = 1 << (channel & 0x07);
+
+ type = usp->usp_module_type[channel / 2];
+
+ if (type != MODULE_DIGITAL) {
+ printk(KERN_ERR
+ "comedi%d: channel configuration accessible only for digital modules\n",
+ dev->minor);
+ return -1;
+ }
+
+ if ((channel_offset = __unioxx5_define_chan_offset(channel)) < 0) {
+ printk(KERN_ERR
+ "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+ dev->minor, channel);
+ return -1;
+ }
+
+ /* gets previously written value */
+ flags = usp->usp_prev_cn_val[channel_offset - 1];
+
+ switch (*data) {
+ case COMEDI_INPUT:
+ flags &= ~mask;
+ break;
+ case COMEDI_OUTPUT:
+ flags |= mask;
+ break;
+ default:
+ printk(KERN_ERR "comedi%d: unknown flag\n", dev->minor);
+ return -1;
+ }
+
+ /* *\
+ * sets channels buffer to 1(after this we are allowed to *
+ * change channel type on input or output) *
+ \* */
+ outb(1, usp->usp_iobase + 0);
+ outb(flags, usp->usp_iobase + channel_offset); /* changes type of _one_ channel */
+ outb(0, usp->usp_iobase + 0); /* sets channels bank to 0(allows directly input/output) */
+ usp->usp_prev_cn_val[channel_offset - 1] = flags; /* saves written value */
+
+ return 0;
+}
+
+static int unioxx5_detach(struct comedi_device * dev)
+{
+ int i;
+ struct comedi_subdevice *subdev;
+ struct unioxx5_subd_priv *usp;
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ subdev = &dev->subdevices[i];
+ usp = subdev->private;
+ release_region(usp->usp_iobase, UNIOXX5_SIZE);
+ kfree(subdev->private);
+ }
+
+ return 0;
+}
+
+/* initializing subdevice with given address */
+static int __unioxx5_subdev_init(struct comedi_subdevice * subdev, int subdev_iobase,
+ int minor)
+{
+ struct unioxx5_subd_priv *usp;
+ int i, to, ndef_flag = 0;
+
+ if (!request_region(subdev_iobase, UNIOXX5_SIZE, DRIVER_NAME)) {
+ printk(KERN_ERR "comedi%d: I/O port conflict\n", minor);
+ return -EIO;
+ }
+
+ if ((usp = (struct unioxx5_subd_priv *) kzalloc(sizeof(*usp),
+ GFP_KERNEL)) == NULL) {
+ printk(KERN_ERR "comedi%d: erorr! --> out of memory!\n", minor);
+ return -1;
+ }
+
+ usp->usp_iobase = subdev_iobase;
+ printk("comedi%d: |", minor);
+
+ /* defining modules types */
+ for (i = 0; i < 12; i++) {
+ to = 10000;
+
+ __unioxx5_analog_config(usp, i * 2);
+ outb(i + 1, subdev_iobase + 5); /* sends channel number to card */
+ outb('H', subdev_iobase + 6); /* requests EEPROM world */
+ while (!(inb(subdev_iobase + 0) & TxBE)) ; /* waits while writting will be allowed */
+ outb(0, subdev_iobase + 6);
+
+ /* waits while reading of two bytes will be allowed */
+ while (!(inb(subdev_iobase + 0) & Rx2CA)) {
+ if (--to <= 0) {
+ ndef_flag = 1;
+ break;
+ }
+ }
+
+ if (ndef_flag) {
+ usp->usp_module_type[i] = 0;
+ ndef_flag = 0;
+ } else
+ usp->usp_module_type[i] = inb(subdev_iobase + 6);
+
+ printk(" [%d] 0x%02x |", i, usp->usp_module_type[i]);
+ comedi_udelay(1);
+ }
+
+ printk("\n");
+
+ /* initial subdevice for digital or analog i/o */
+ subdev->type = COMEDI_SUBD_DIO;
+ subdev->private = usp;
+ subdev->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ subdev->n_chan = UNIOXX5_NUM_OF_CHANS;
+ subdev->maxdata = 0xFFF;
+ subdev->range_table = &range_digital;
+ subdev->insn_read = unioxx5_subdev_read;
+ subdev->insn_write = unioxx5_subdev_write;
+ subdev->insn_config = unioxx5_insn_config; /* for digital modules only!!! */
+
+ printk("subdevice configured\n");
+
+ return 0;
+}
+
+static int __unioxx5_digital_write(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor)
+{
+ int channel_offset, val;
+ int mask = 1 << (channel & 0x07);
+
+ if ((channel_offset = __unioxx5_define_chan_offset(channel)) < 0) {
+ printk(KERN_ERR
+ "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+ minor, channel);
+ return 0;
+ }
+
+ val = usp->usp_prev_wr_val[channel_offset - 1]; /* getting previous written value */
+
+ if (*data)
+ val |= mask;
+ else
+ val &= ~mask;
+
+ outb(val, usp->usp_iobase + channel_offset);
+ usp->usp_prev_wr_val[channel_offset - 1] = val; /* saving new written value */
+
+ return 1;
+}
+
+/* function for digital reading */
+static int __unioxx5_digital_read(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor)
+{
+ int channel_offset, mask = 1 << (channel & 0x07);
+
+ if ((channel_offset = __unioxx5_define_chan_offset(channel)) < 0) {
+ printk(KERN_ERR
+ "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+ minor, channel);
+ return 0;
+ }
+
+ *data = inb(usp->usp_iobase + channel_offset);
+ *data &= mask;
+
+ if (channel_offset > 1)
+ channel -= 2 << channel_offset; /* this operation is created for correct readed value to 0 or 1 */
+
+ *data >>= channel;
+ return 1;
+}
+
+#if 0 /* not used? */
+static void __unioxx5_digital_config(struct unioxx5_subd_priv * usp, int mode)
+{
+ int i, mask;
+
+ mask = (mode == ALL_2_OUTPUT) ? 0xFF : 0x00;
+ printk("COMEDI: mode = %d\n", mask);
+
+ outb(1, usp->usp_iobase + 0);
+
+ for (i = 0; i < 3; i++)
+ outb(mask, usp->usp_iobase + i);
+
+ outb(0, usp->usp_iobase + 0);
+}
+#endif
+
+static int __unioxx5_analog_write(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor)
+{
+ int module, i;
+
+ module = channel / 2; /* definig module number(0 .. 11) */
+ i = (channel % 2) << 1; /* depends on type of channel (A or B) */
+
+ /* defining if given module can work on output */
+ if (!(usp->usp_module_type[module] & MODULE_OUTPUT_MASK)) {
+ printk(KERN_ERR
+ "comedi%d: module in position %d with id 0x%0x is for input only!\n",
+ minor, module, usp->usp_module_type[module]);
+ return 0;
+ }
+
+ __unioxx5_analog_config(usp, channel);
+ /* saving minor byte */
+ usp->usp_extra_data[module][i++] = (unsigned char)(*data & 0x00FF);
+ /* saving major byte */
+ usp->usp_extra_data[module][i] = (unsigned char)((*data & 0xFF00) >> 8);
+
+ //while(!((inb(usp->usp_iobase + 0)) & TxBE));
+ outb(module + 1, usp->usp_iobase + 5); /* sending module number to card(1 .. 12) */
+ outb('W', usp->usp_iobase + 6); /* sends (W)rite command to module */
+
+ /* sending for bytes to module(one byte per cycle iteration) */
+ for (i = 0; i < 4; i++) {
+ while (!((inb(usp->usp_iobase + 0)) & TxBE)) ; /* waits while writting will be allowed */
+ outb(usp->usp_extra_data[module][i], usp->usp_iobase + 6);
+ }
+
+ return 1;
+}
+
+static int __unioxx5_analog_read(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor)
+{
+ int module_no, read_ch;
+ char control;
+
+ module_no = channel / 2;
+ read_ch = channel % 2; /* depend on type of channel (A or B) */
+
+ /* defining if given module can work on input */
+ if (usp->usp_module_type[module_no] & MODULE_OUTPUT_MASK) {
+ printk(KERN_ERR
+ "comedi%d: module in position %d with id 0x%02x is for output only",
+ minor, module_no, usp->usp_module_type[module_no]);
+ return 0;
+ }
+
+ __unioxx5_analog_config(usp, channel);
+ outb(module_no + 1, usp->usp_iobase + 5); /* sends module number to card(1 .. 12) */
+ outb('V', usp->usp_iobase + 6); /* sends to module (V)erify command */
+ control = inb(usp->usp_iobase); /* get control register byte */
+
+ /* waits while reading four bytes will be allowed */
+ while (!((control = inb(usp->usp_iobase + 0)) & Rx4CA)) ;
+
+ /* if four bytes readding error occurs - return 0(false) */
+ if ((control & Rx4CA_ERR_MASK)) {
+ printk("COMEDI: 4 bytes error\n");
+ return 0;
+ }
+
+ if (read_ch)
+ *data = inw(usp->usp_iobase + 6); /* channel B */
+ else
+ *data = inw(usp->usp_iobase + 4); /* channel A */
+
+ return 1;
+}
+
+/* configure channels for analog i/o (even to output, odd to input) */
+static void __unioxx5_analog_config(struct unioxx5_subd_priv * usp, int channel)
+{
+ int chan_a, chan_b, conf, channel_offset;
+
+ channel_offset = __unioxx5_define_chan_offset(channel);
+ conf = usp->usp_prev_cn_val[channel_offset - 1];
+ chan_a = chan_b = 1;
+
+ /* setting channel A and channel B mask */
+ if (channel % 2 == 0) {
+ chan_a <<= channel & 0x07;
+ chan_b <<= (channel + 1) & 0x07;
+ } else {
+ chan_a <<= (channel - 1) & 0x07;
+ chan_b <<= channel & 0x07;
+ }
+
+ conf |= chan_a; /* even channel ot output */
+ conf &= ~chan_b; /* odd channel to input */
+
+ outb(1, usp->usp_iobase + 0);
+ outb(conf, usp->usp_iobase + channel_offset);
+ outb(0, usp->usp_iobase + 0);
+
+ usp->usp_prev_cn_val[channel_offset - 1] = conf;
+}
+
+/* *\
+ * this function defines if the given channel number *
+ * enters in default numeric interspace(from 0 to 23) *
+ * and it returns address offset for usage needed *
+ * channel. *
+\* */
+
+static int __unioxx5_define_chan_offset(int chan_num)
+{
+
+ if (chan_num < 0 || chan_num > 23)
+ return -1;
+
+ return (chan_num >> 3) + 1;
+}
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 35138257be7..d0b59e98314 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -1,4 +1,4 @@
-#define DRIVER_VERSION "v2.1"
+#define DRIVER_VERSION "v2.2"
#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
#define DRIVER_DESC "Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"
/*
@@ -25,8 +25,8 @@ Driver: usbdux
Description: University of Stirling USB DAQ & INCITE Technology Limited
Devices: [ITL] USB-DUX (usbdux.o)
Author: Bernd Porr <BerndPorr@f2s.com>
-Updated: 25 Nov 2007
-Status: Testing
+Updated: 8 Dec 2008
+Status: Stable
Configuration options:
You have to upload firmware with the -i option. The
firmware is usually installed under /usr/share/usb or
@@ -79,6 +79,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
* 1.2: added PWM suport via EP4
* 2.0: PWM seems to be stable and is not interfering with the other functions
* 2.1: changed PWM API
+ * 2.2: added firmware kernel request to fix an udev problem
*
*/
@@ -94,6 +95,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
#include <linux/smp_lock.h>
#include <linux/fcntl.h>
#include <linux/compiler.h>
+#include <linux/firmware.h>
#include "../comedidev.h"
@@ -212,7 +214,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
/**************************************************/
/* comedi constants */
-static const comedi_lrange range_usbdux_ai_range = { 4, {
+static const struct comedi_lrange range_usbdux_ai_range = { 4, {
BIP_RANGE(4.096),
BIP_RANGE(4.096 / 2),
UNI_RANGE(4.096),
@@ -220,7 +222,7 @@ static const comedi_lrange range_usbdux_ai_range = { 4, {
}
};
-static const comedi_lrange range_usbdux_ao_range = { 2, {
+static const struct comedi_lrange range_usbdux_ao_range = { 2, {
BIP_RANGE(4.096),
UNI_RANGE(4.096),
}
@@ -251,7 +253,7 @@ struct usbduxsub {
/* pwm-transfer handling */
struct urb *urbPwm;
/* PWM period */
- lsampl_t pwmPeriod;
+ unsigned int pwmPeriod;
/* PWM internal delay for the GPIF in the FX2 */
int8_t pwmDelay;
/* size of the PWM buffer which holds the bit pattern */
@@ -267,7 +269,7 @@ struct usbduxsub {
/* interface structure in 2.6 */
struct usb_interface *interface;
/* comedi device for the interrupt context */
- comedi_device *comedidev;
+ struct comedi_device *comedidev;
/* is it USB_SPEED_HIGH or not? */
short int high_speed;
/* asynchronous command is running */
@@ -361,7 +363,7 @@ static int usbdux_ai_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
* This will cancel a running acquisition operation.
* This is called by comedi but never from inside the driver.
*/
-static int usbdux_ai_cancel(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct usbduxsub *this_usbduxsub;
int res = 0;
@@ -390,8 +392,8 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
{
int i, err, n;
struct usbduxsub *this_usbduxsub;
- comedi_device *this_comedidev;
- comedi_subdevice *s;
+ struct comedi_device *this_comedidev;
+ struct comedi_subdevice *s;
/* the context variable points to the subdevice */
this_comedidev = urb->context;
@@ -559,7 +561,7 @@ static int usbdux_ao_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
}
/* force unlink, is called by comedi */
-static int usbdux_ao_cancel(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct usbduxsub *this_usbduxsub = dev->private;
int res = 0;
@@ -584,8 +586,8 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
int i, ret;
int8_t *datap;
struct usbduxsub *this_usbduxsub;
- comedi_device *this_comedidev;
- comedi_subdevice *s;
+ struct comedi_device *this_comedidev;
+ struct comedi_subdevice *s;
/* the context variable points to the subdevice */
this_comedidev = urb->context;
@@ -654,7 +656,7 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
((uint8_t *) (urb->transfer_buffer))[0] =
s->async->cmd.chanlist_len;
for (i = 0; i < s->async->cmd.chanlist_len; i++) {
- sampl_t temp;
+ short temp;
if (i >= NUMOUTCHANNELS)
break;
@@ -718,31 +720,29 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub)
int errcode = 0;
uint8_t local_transfer_buffer[16];
- if (usbduxsub->probed) {
- /* 7f92 to zero */
- local_transfer_buffer[0] = 0;
- errcode = usb_control_msg(usbduxsub->usbdev,
- /* create a pipe for a control transfer */
- usb_sndctrlpipe(usbduxsub->usbdev, 0),
- /* bRequest, "Firmware" */
- USBDUXSUB_FIRMWARE,
- /* bmRequestType */
- VENDOR_DIR_OUT,
- /* Value */
- USBDUXSUB_CPUCS,
- /* Index */
- 0x0000,
- /* address of the transfer buffer */
- local_transfer_buffer,
- /* Length */
- 1,
- /* Timeout */
- EZTIMEOUT);
- if (errcode < 0) {
- dev_err(&usbduxsub->interface->dev,
- "comedi_: control msg failed (start)\n");
- return errcode;
- }
+ /* 7f92 to zero */
+ local_transfer_buffer[0] = 0;
+ errcode = usb_control_msg(usbduxsub->usbdev,
+ /* create a pipe for a control transfer */
+ usb_sndctrlpipe(usbduxsub->usbdev, 0),
+ /* bRequest, "Firmware" */
+ USBDUXSUB_FIRMWARE,
+ /* bmRequestType */
+ VENDOR_DIR_OUT,
+ /* Value */
+ USBDUXSUB_CPUCS,
+ /* Index */
+ 0x0000,
+ /* address of the transfer buffer */
+ local_transfer_buffer,
+ /* Length */
+ 1,
+ /* Timeout */
+ EZTIMEOUT);
+ if (errcode < 0) {
+ dev_err(&usbduxsub->interface->dev,
+ "comedi_: control msg failed (start)\n");
+ return errcode;
}
return 0;
}
@@ -752,28 +752,27 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub)
int errcode = 0;
uint8_t local_transfer_buffer[16];
- if (usbduxsub->probed) {
- /* 7f92 to one */
- local_transfer_buffer[0] = 1;
- errcode = usb_control_msg(usbduxsub->usbdev,
- usb_sndctrlpipe(usbduxsub->usbdev, 0),
- /* bRequest, "Firmware" */
- USBDUXSUB_FIRMWARE,
- /* bmRequestType */
- VENDOR_DIR_OUT,
- /* Value */
- USBDUXSUB_CPUCS,
- /* Index */
- 0x0000, local_transfer_buffer,
- /* Length */
- 1,
- /* Timeout */
- EZTIMEOUT);
- if (errcode < 0) {
- dev_err(&usbduxsub->interface->dev,
- "comedi_: control msg failed (stop)\n");
- return errcode;
- }
+
+ /* 7f92 to one */
+ local_transfer_buffer[0] = 1;
+ errcode = usb_control_msg(usbduxsub->usbdev,
+ usb_sndctrlpipe(usbduxsub->usbdev, 0),
+ /* bRequest, "Firmware" */
+ USBDUXSUB_FIRMWARE,
+ /* bmRequestType */
+ VENDOR_DIR_OUT,
+ /* Value */
+ USBDUXSUB_CPUCS,
+ /* Index */
+ 0x0000, local_transfer_buffer,
+ /* Length */
+ 1,
+ /* Timeout */
+ EZTIMEOUT);
+ if (errcode < 0) {
+ dev_err(&usbduxsub->interface->dev,
+ "comedi_: control msg failed (stop)\n");
+ return errcode;
}
return 0;
}
@@ -784,13 +783,7 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub,
{
int errcode;
- if (usbduxsub->probed) {
- dev_dbg(&usbduxsub->interface->dev,
- "comedi%d: usbdux: uploading %d bytes"
- " to addr %d, first byte=%d.\n",
- usbduxsub->comedidev->minor, len,
- startAddr, local_transfer_buffer[0]);
- errcode = usb_control_msg(usbduxsub->usbdev,
+ errcode = usb_control_msg(usbduxsub->usbdev,
usb_sndctrlpipe(usbduxsub->usbdev, 0),
/* brequest, firmware */
USBDUXSUB_FIRMWARE,
@@ -806,16 +799,12 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub,
len,
/* timeout */
EZTIMEOUT);
- dev_dbg(&usbduxsub->interface->dev,
- "comedi_: result=%d\n", errcode);
- if (errcode < 0) {
- dev_err(&usbduxsub->interface->dev,
- "comedi_: upload failed\n");
- return errcode;
- }
- } else {
- /* no device on the bus for this index */
- return -EFAULT;
+ dev_dbg(&usbduxsub->interface->dev,
+ "comedi_: result=%d\n", errcode);
+ if (errcode < 0) {
+ dev_err(&usbduxsub->interface->dev,
+ "comedi_: upload failed\n");
+ return errcode;
}
return 0;
}
@@ -907,8 +896,8 @@ static int usbduxsub_submit_OutURBs(struct usbduxsub *usbduxsub)
return 0;
}
-static int usbdux_ai_cmdtest(comedi_device *dev, comedi_subdevice *s,
- comedi_cmd *cmd)
+static int usbdux_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
int err = 0, tmp, i;
unsigned int tmpTimer;
@@ -1127,7 +1116,7 @@ static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command)
return -EFAULT;
}
-static int usbdux_ai_inttrig(comedi_device *dev, comedi_subdevice *s,
+static int usbdux_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trignum)
{
int ret;
@@ -1171,9 +1160,9 @@ static int usbdux_ai_inttrig(comedi_device *dev, comedi_subdevice *s,
return 1;
}
-static int usbdux_ai_cmd(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->async->cmd;
+ struct comedi_cmd *cmd = &s->async->cmd;
unsigned int chan, range;
int i, ret;
struct usbduxsub *this_usbduxsub = dev->private;
@@ -1287,11 +1276,11 @@ static int usbdux_ai_cmd(comedi_device *dev, comedi_subdevice *s)
}
/* Mode 0 is used to get a single conversion on demand */
-static int usbdux_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i;
- lsampl_t one = 0;
+ unsigned int one = 0;
int chan, range;
int err;
struct usbduxsub *this_usbduxsub = dev->private;
@@ -1348,8 +1337,8 @@ static int usbdux_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
/************************************/
/* analog out */
-static int usbdux_ao_insn_read(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -1370,8 +1359,8 @@ static int usbdux_ao_insn_read(comedi_device *dev, comedi_subdevice *s,
return i;
}
-static int usbdux_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i, err;
int chan = CR_CHAN(insn->chanspec);
@@ -1420,7 +1409,7 @@ static int usbdux_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
return i;
}
-static int usbdux_ao_inttrig(comedi_device *dev, comedi_subdevice *s,
+static int usbdux_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trignum)
{
int ret;
@@ -1461,8 +1450,8 @@ static int usbdux_ao_inttrig(comedi_device *dev, comedi_subdevice *s,
return 1;
}
-static int usbdux_ao_cmdtest(comedi_device *dev, comedi_subdevice *s,
- comedi_cmd *cmd)
+static int usbdux_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
int err = 0, tmp;
struct usbduxsub *this_usbduxsub = dev->private;
@@ -1600,9 +1589,9 @@ static int usbdux_ao_cmdtest(comedi_device *dev, comedi_subdevice *s,
return 0;
}
-static int usbdux_ao_cmd(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->async->cmd;
+ struct comedi_cmd *cmd = &s->async->cmd;
unsigned int chan, gain;
int i, ret;
struct usbduxsub *this_usbduxsub = dev->private;
@@ -1708,8 +1697,8 @@ static int usbdux_ao_cmd(comedi_device *dev, comedi_subdevice *s)
return 0;
}
-static int usbdux_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int chan = CR_CHAN(insn->chanspec);
@@ -1739,8 +1728,8 @@ static int usbdux_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
return insn->n;
}
-static int usbdux_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
struct usbduxsub *this_usbduxsub = dev->private;
@@ -1786,8 +1775,8 @@ static int usbdux_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
}
/* reads the 4 counters, only two are used just now */
-static int usbdux_counter_read(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_counter_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
struct usbduxsub *this_usbduxsub = dev->private;
int chan = insn->chanspec;
@@ -1820,8 +1809,8 @@ static int usbdux_counter_read(comedi_device *dev, comedi_subdevice *s,
return 1;
}
-static int usbdux_counter_write(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_counter_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
struct usbduxsub *this_usbduxsub = dev->private;
int err;
@@ -1850,8 +1839,8 @@ static int usbdux_counter_write(comedi_device *dev, comedi_subdevice *s,
return 1;
}
-static int usbdux_counter_config(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_counter_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
/* nothing to do so far */
return 2;
@@ -1894,7 +1883,7 @@ static int usbdux_pwm_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
}
/* force unlink - is called by comedi */
-static int usbdux_pwm_cancel(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_pwm_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct usbduxsub *this_usbduxsub = dev->private;
int res = 0;
@@ -1916,8 +1905,8 @@ static void usbduxsub_pwm_irq(struct urb *urb)
{
int ret;
struct usbduxsub *this_usbduxsub;
- comedi_device *this_comedidev;
- comedi_subdevice *s;
+ struct comedi_device *this_comedidev;
+ struct comedi_subdevice *s;
/* printk(KERN_DEBUG "PWM: IRQ\n"); */
@@ -2007,8 +1996,8 @@ static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub)
return 0;
}
-static int usbdux_pwm_period(comedi_device *dev, comedi_subdevice *s,
- lsampl_t period)
+static int usbdux_pwm_period(struct comedi_device *dev, struct comedi_subdevice *s,
+ unsigned int period)
{
struct usbduxsub *this_usbduxsub = dev->private;
int fx2delay = 255;
@@ -2035,7 +2024,7 @@ static int usbdux_pwm_period(comedi_device *dev, comedi_subdevice *s,
}
/* is called from insn so there's no need to do all the sanity checks */
-static int usbdux_pwm_start(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_pwm_start(struct comedi_device *dev, struct comedi_subdevice *s)
{
int ret, i;
struct usbduxsub *this_usbduxsub = dev->private;
@@ -2067,8 +2056,8 @@ static int usbdux_pwm_start(comedi_device *dev, comedi_subdevice *s)
}
/* generates the bit pattern for PWM with the optional sign bit */
-static int usbdux_pwm_pattern(comedi_device *dev, comedi_subdevice *s,
- int channel, lsampl_t value, lsampl_t sign)
+static int usbdux_pwm_pattern(struct comedi_device *dev, struct comedi_subdevice *s,
+ int channel, unsigned int value, unsigned int sign)
{
struct usbduxsub *this_usbduxsub = dev->private;
int i, szbuf;
@@ -2108,8 +2097,8 @@ static int usbdux_pwm_pattern(comedi_device *dev, comedi_subdevice *s,
return 1;
}
-static int usbdux_pwm_write(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_pwm_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
struct usbduxsub *this_usbduxsub = dev->private;
@@ -2133,16 +2122,16 @@ static int usbdux_pwm_write(comedi_device *dev, comedi_subdevice *s,
data[0], 0);
}
-static int usbdux_pwm_read(comedi_device *x1, comedi_subdevice *x2,
- comedi_insn *x3, lsampl_t *x4)
+static int usbdux_pwm_read(struct comedi_device *x1, struct comedi_subdevice *x2,
+ struct comedi_insn *x3, unsigned int *x4)
{
/* not needed */
return -EINVAL;
};
/* switches on/off PWM */
-static int usbdux_pwm_config(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_pwm_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
struct usbduxsub *this_usbduxsub = dev->private;
switch (data[0]) {
@@ -2292,13 +2281,13 @@ static unsigned hex2unsigned(char *h)
#define FIRMWARE_MAX_LEN 0x2000
/* taken from David Brownell's fxload and adjusted for this driver */
-static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
+static int read_firmware(struct usbduxsub *usbduxsub, const void *firmwarePtr,
long size)
{
struct device *dev = &usbduxsub->interface->dev;
int i = 0;
unsigned char *fp = (char *)firmwarePtr;
- unsigned char *firmwareBinary = NULL;
+ unsigned char *firmwareBinary;
int res = 0;
int maxAddr = 0;
@@ -2322,6 +2311,7 @@ static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
j++;
if (j >= sizeof(buf)) {
dev_err(dev, "comedi_: bogus firmware file!\n");
+ kfree(firmwareBinary);
return -1;
}
}
@@ -2344,6 +2334,7 @@ static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
if (buf[0] != ':') {
dev_err(dev, "comedi_: upload: not an ihex record: %s",
buf);
+ kfree(firmwareBinary);
return -EFAULT;
}
@@ -2360,6 +2351,7 @@ static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
if (maxAddr >= FIRMWARE_MAX_LEN) {
dev_err(dev, "comedi_: firmware upload goes "
"beyond FX2 RAM boundaries.\n");
+ kfree(firmwareBinary);
return -EFAULT;
}
/* dev_dbg(dev, "comedi_: off=%x, len=%x:\n", off, len); */
@@ -2375,6 +2367,7 @@ static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
if (type != 0) {
dev_err(dev, "comedi_: unsupported record type: %u\n",
type);
+ kfree(firmwareBinary);
return -EFAULT;
}
@@ -2395,6 +2388,34 @@ static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
return res;
}
+static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
+ void *context)
+{
+ struct usbduxsub *usbduxsub_tmp = context;
+ struct usb_device *usbdev = usbduxsub_tmp->usbdev;
+ int ret;
+
+ if (fw == NULL) {
+ dev_err(&usbdev->dev,
+ "Firmware complete handler without firmware!\n");
+ return;
+ }
+
+ /*
+ * we need to upload the firmware here because fw will be
+ * freed once we've left this function
+ */
+ ret = read_firmware(usbduxsub_tmp, fw->data, fw->size);
+
+ if (ret) {
+ dev_err(&usbdev->dev,
+ "Could not upload firmware (err=%d)\n",
+ ret);
+ return;
+ }
+ comedi_usb_auto_config(usbdev, BOARDNAME);
+}
+
/* allocate memory for the urbs and initialise them */
static int usbduxsub_probe(struct usb_interface *uinterf,
const struct usb_device_id *id)
@@ -2403,6 +2424,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
struct device *dev = &uinterf->dev;
int i;
int index;
+ int ret;
dev_dbg(dev, "comedi_: usbdux_: "
"finding a free structure for the usb-device\n");
@@ -2637,6 +2659,19 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
/* we've reached the bottom of the function */
usbduxsub[index].probed = 1;
up(&start_stop_sem);
+
+ ret = request_firmware_nowait(THIS_MODULE,
+ FW_ACTION_HOTPLUG,
+ "usbdux_firmware.hex",
+ &udev->dev,
+ usbduxsub + index,
+ usbdux_firmware_request_complete_handler);
+
+ if (ret) {
+ dev_err(dev, "Could not load firmware (err=%d)\n", ret);
+ return ret;
+ }
+
dev_info(dev, "comedi_: usbdux%d "
"has been successfully initialised.\n", index);
/* success */
@@ -2658,6 +2693,7 @@ static void usbduxsub_disconnect(struct usb_interface *intf)
"comedi_: BUG! called with wrong ptr!!!\n");
return;
}
+ comedi_usb_auto_unconfig(udev);
down(&start_stop_sem);
down(&usbduxsub_tmp->sem);
tidy_up(usbduxsub_tmp);
@@ -2667,14 +2703,14 @@ static void usbduxsub_disconnect(struct usb_interface *intf)
}
/* is called when comedi-config is called */
-static int usbdux_attach(comedi_device *dev, comedi_devconfig *it)
+static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
int ret;
int index;
int i;
struct usbduxsub *udev;
- comedi_subdevice *s = NULL;
+ struct comedi_subdevice *s = NULL;
dev->private = NULL;
down(&start_stop_sem);
@@ -2834,7 +2870,7 @@ static int usbdux_attach(comedi_device *dev, comedi_devconfig *it)
return 0;
}
-static int usbdux_detach(comedi_device *dev)
+static int usbdux_detach(struct comedi_device *dev)
{
struct usbduxsub *usbduxsub_tmp;
@@ -2867,26 +2903,13 @@ static int usbdux_detach(comedi_device *dev)
}
/* main driver struct */
-static comedi_driver driver_usbdux = {
+static struct comedi_driver driver_usbdux = {
.driver_name = "usbdux",
.module = THIS_MODULE,
.attach = usbdux_attach,
.detach = usbdux_detach,
};
-static void init_usb_devices(void)
-{
- int index;
-
- /* all devices entries are invalid to begin with */
- /* they will become valid by the probe function */
- /* and then finally by the attach-function */
- for (index = 0; index < NUMUSBDUX; index++) {
- memset(&(usbduxsub[index]), 0x00, sizeof(usbduxsub[index]));
- init_MUTEX(&(usbduxsub[index].sem));
- }
-}
-
/* Table with the USB-devices: just now only testing IDs */
static struct usb_device_id usbduxsub_table[] = {
{USB_DEVICE(0x13d8, 0x0001) },
@@ -2907,18 +2930,17 @@ static struct usb_driver usbduxsub_driver = {
/* Can't use the nice macro as I have also to initialise the USB */
/* subsystem: */
/* registering the usb-system _and_ the comedi-driver */
-static int init_usbdux(void)
+static int __init init_usbdux(void)
{
printk(KERN_INFO KBUILD_MODNAME ": "
DRIVER_VERSION ":" DRIVER_DESC "\n");
- init_usb_devices();
usb_register(&usbduxsub_driver);
comedi_driver_register(&driver_usbdux);
return 0;
}
/* deregistering the comedi driver and the usb-subsystem */
-static void exit_usbdux(void)
+static void __exit exit_usbdux(void)
{
comedi_driver_unregister(&driver_usbdux);
usb_deregister(&usbduxsub_driver);
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index 3a00ff0cfc5..2fb64de3f86 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -1,33 +1,20 @@
-#define DRIVER_VERSION "v0.99a"
-#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
-#define DRIVER_DESC "USB-DUXfast, BerndPorr@f2s.com"
-/*
- comedi/drivers/usbduxfast.c
- Copyright (C) 2004 Bernd Porr, Bernd.Porr@f2s.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.
-*/
-
/*
-Driver: usbduxfast
-Description: ITL USB-DUXfast
-Devices: [ITL] USB-DUX (usbduxfast.o)
-Author: Bernd Porr <BerndPorr@f2s.com>
-Updated: 04 Dec 2006
-Status: testing
-*/
+ * Copyright (C) 2004 Bernd Porr, Bernd.Porr@f2s.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.
+ */
/*
* I must give credit here to Chris Baugher who
@@ -42,12 +29,16 @@ Status: testing
* 0.9: Dropping the first data packet which seems to be from the last transfer.
* Buffer overflows in the FX2 are handed over to comedi.
* 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
- * Added insn command basically for testing. Sample rate is 1MHz/16ch=62.5kHz
+ * Added insn command basically for testing. Sample rate is
+ * 1MHz/16ch=62.5kHz
* 0.99: Ian Abbott pointed out a bug which has been corrected. Thanks!
* 0.99a: added external trigger.
+ * 1.00: added firmware kernel request to the driver which fixed
+ * udev coldplug problem
*/
#include <linux/kernel.h>
+#include <linux/firmware.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -59,536 +50,549 @@ Status: testing
#include "comedi_fc.h"
#include "../comedidev.h"
-// (un)comment this if you want to have debug info.
-//#define CONFIG_COMEDI_DEBUG
-#undef CONFIG_COMEDI_DEBUG
+#define DRIVER_VERSION "v1.0"
+#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
+#define DRIVER_DESC "USB-DUXfast, BerndPorr@f2s.com"
#define BOARDNAME "usbduxfast"
-// timeout for the USB-transfer
-#define EZTIMEOUT 30
+/*
+ * timeout for the USB-transfer
+ */
+#define EZTIMEOUT 30
-// constants for "firmware" upload and download
-#define USBDUXFASTSUB_FIRMWARE 0xA0
-#define VENDOR_DIR_IN 0xC0
-#define VENDOR_DIR_OUT 0x40
+/*
+ * constants for "firmware" upload and download
+ */
+#define USBDUXFASTSUB_FIRMWARE 0xA0
+#define VENDOR_DIR_IN 0xC0
+#define VENDOR_DIR_OUT 0x40
-// internal adresses of the 8051 processor
-#define USBDUXFASTSUB_CPUCS 0xE600
+/*
+ * internal adresses of the 8051 processor
+ */
+#define USBDUXFASTSUB_CPUCS 0xE600
-// max lenghth of the transfer-buffer for software upload
-#define TB_LEN 0x2000
+/*
+ * max lenghth of the transfer-buffer for software upload
+ */
+#define TB_LEN 0x2000
-// Input endpoint number
-#define BULKINEP 6
+/*
+ * input endpoint number
+ */
+#define BULKINEP 6
-// Endpoint for the A/D channellist: bulk OUT
-#define CHANNELLISTEP 4
+/*
+ * endpoint for the A/D channellist: bulk OUT
+ */
+#define CHANNELLISTEP 4
-// Number of channels
-#define NUMCHANNELS 32
+/*
+ * number of channels
+ */
+#define NUMCHANNELS 32
-// size of the waveform descriptor
-#define WAVESIZE 0x20
+/*
+ * size of the waveform descriptor
+ */
+#define WAVESIZE 0x20
-// Size of one A/D value
-#define SIZEADIN ((sizeof(int16_t)))
+/*
+ * size of one A/D value
+ */
+#define SIZEADIN (sizeof(int16_t))
-// Size of the input-buffer IN BYTES
-#define SIZEINBUF 512
+/*
+ * size of the input-buffer IN BYTES
+ */
+#define SIZEINBUF 512
-// 16 bytes.
-#define SIZEINSNBUF 512
+/*
+ * 16 bytes
+ */
+#define SIZEINSNBUF 512
-// Size of the buffer for the dux commands
-#define SIZEOFDUXBUFFER 256 // bytes
+/*
+ * size of the buffer for the dux commands in bytes
+ */
+#define SIZEOFDUXBUFFER 256
-// Number of in-URBs which receive the data: min=5
-#define NUMOFINBUFFERSHIGH 10
+/*
+ * number of in-URBs which receive the data: min=5
+ */
+#define NUMOFINBUFFERSHIGH 10
-// Total number of usbduxfast devices
-#define NUMUSBDUXFAST 16
+/*
+ * total number of usbduxfast devices
+ */
+#define NUMUSBDUXFAST 16
-// Number of subdevices
-#define N_SUBDEVICES 1
+/*
+ * number of subdevices
+ */
+#define N_SUBDEVICES 1
-// Analogue in subdevice
-#define SUBDEV_AD 0
+/*
+ * analogue in subdevice
+ */
+#define SUBDEV_AD 0
-// min delay steps for more than one channel
-// basically when the mux gives up. ;-)
-#define MIN_SAMPLING_PERIOD 9 // steps at 30MHz in the FX2
+/*
+ * min delay steps for more than one channel
+ * basically when the mux gives up ;-)
+ *
+ * steps at 30MHz in the FX2
+ */
+#define MIN_SAMPLING_PERIOD 9
-// Max number of 1/30MHz delay steps:
-#define MAX_SAMPLING_PERIOD 500
+/*
+ * max number of 1/30MHz delay steps
+ */
+#define MAX_SAMPLING_PERIOD 500
-// Number of received packets to ignore before we start handing data over to comedi.
-// It's quad buffering and we have to ignore 4 packets.
-#define PACKETS_TO_IGNORE 4
+/*
+ * number of received packets to ignore before we start handing data
+ * over to comedi, it's quad buffering and we have to ignore 4 packets
+ */
+#define PACKETS_TO_IGNORE 4
-/////////////////////////////////////////////
-// comedi constants
-static const comedi_lrange range_usbduxfast_ai_range = { 2, {
- BIP_RANGE(0.75),
- BIP_RANGE(0.5),
- }
+/*
+ * comedi constants
+ */
+static const struct comedi_lrange range_usbduxfast_ai_range = {
+ 2, { BIP_RANGE(0.75), BIP_RANGE(0.5) }
};
/*
* private structure of one subdevice
+ *
+ * this is the structure which holds all the data of this driver
+ * one sub device just now: A/D
*/
-
-// This is the structure which holds all the data of this driver
-// one sub device just now: A/D
-typedef struct {
- // attached?
- int attached;
- // is it associated with a subdevice?
- int probed;
- // pointer to the usb-device
- struct usb_device *usbdev;
- // BULK-transfer handling: urb
- struct urb *urbIn;
+struct usbduxfastsub_s {
+ int attached; /* is attached? */
+ int probed; /* is it associated with a subdevice? */
+ struct usb_device *usbdev; /* pointer to the usb-device */
+ struct urb *urbIn; /* BULK-transfer handling: urb */
int8_t *transfer_buffer;
- // input buffer for single insn
- int16_t *insnBuffer;
- // interface number
- int ifnum;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- // interface structure in 2.6
- struct usb_interface *interface;
-#endif
- // comedi device for the interrupt context
- comedi_device *comedidev;
- // asynchronous command is running
- short int ai_cmd_running;
- // continous aquisition
- short int ai_continous;
- // number of samples to aquire
- long int ai_sample_count;
- // commands
- uint8_t *dux_commands;
- // counter which ignores the first buffers
- int ignore;
+ int16_t *insnBuffer; /* input buffer for single insn */
+ int ifnum; /* interface number */
+ struct usb_interface *interface; /* interface structure */
+ struct comedi_device *comedidev; /* comedi device for the interrupt
+ context */
+ short int ai_cmd_running; /* asynchronous command is running */
+ short int ai_continous; /* continous aquisition */
+ long int ai_sample_count; /* number of samples to aquire */
+ uint8_t *dux_commands; /* commands */
+ int ignore; /* counter which ignores the first
+ buffers */
struct semaphore sem;
-} usbduxfastsub_t;
+};
-// The pointer to the private usb-data of the driver
-// is also the private data for the comedi-device.
-// This has to be global as the usb subsystem needs
-// global variables. The other reason is that this
-// structure must be there _before_ any comedi
-// command is issued. The usb subsystem must be
-// initialised before comedi can access it.
-static usbduxfastsub_t usbduxfastsub[NUMUSBDUXFAST];
+/*
+ * The pointer to the private usb-data of the driver
+ * is also the private data for the comedi-device.
+ * This has to be global as the usb subsystem needs
+ * global variables. The other reason is that this
+ * structure must be there _before_ any comedi
+ * command is issued. The usb subsystem must be
+ * initialised before comedi can access it.
+ */
+static struct usbduxfastsub_s usbduxfastsub[NUMUSBDUXFAST];
static DECLARE_MUTEX(start_stop_sem);
-// bulk transfers to usbduxfast
-
+/*
+ * bulk transfers to usbduxfast
+ */
#define SENDADCOMMANDS 0
#define SENDINITEP6 1
-static int send_dux_commands(usbduxfastsub_t * this_usbduxfastsub, int cmd_type)
+static int send_dux_commands(struct usbduxfastsub_s *udfs, int cmd_type)
{
- int result, nsent;
- this_usbduxfastsub->dux_commands[0] = cmd_type;
+ int tmp, nsent;
+
+ udfs->dux_commands[0] = cmd_type;
+
#ifdef CONFIG_COMEDI_DEBUG
- int i;
- printk("comedi%d: usbduxfast: dux_commands: ",
- this_usbduxfastsub->comedidev->minor);
- for (i = 0; i < SIZEOFDUXBUFFER; i++) {
- printk(" %02x", this_usbduxfastsub->dux_commands[i]);
- }
+ printk(KERN_DEBUG "comedi%d: usbduxfast: dux_commands: ",
+ udfs->comedidev->minor);
+ for (tmp = 0; tmp < SIZEOFDUXBUFFER; tmp++)
+ printk(" %02x", udfs->dux_commands[tmp]);
printk("\n");
#endif
- result = usb_bulk_msg(this_usbduxfastsub->usbdev,
- usb_sndbulkpipe(this_usbduxfastsub->usbdev,
- CHANNELLISTEP),
- this_usbduxfastsub->dux_commands, SIZEOFDUXBUFFER,
- &nsent, 10000);
- if (result < 0) {
- printk("comedi%d: could not transmit dux_commands to the usb-device, err=%d\n", this_usbduxfastsub->comedidev->minor, result);
- }
- return result;
+
+ tmp = usb_bulk_msg(udfs->usbdev,
+ usb_sndbulkpipe(udfs->usbdev, CHANNELLISTEP),
+ udfs->dux_commands, SIZEOFDUXBUFFER, &nsent, 10000);
+ if (tmp < 0)
+ printk(KERN_ERR "comedi%d: could not transmit dux_commands to"
+ "the usb-device, err=%d\n", udfs->comedidev->minor, tmp);
+ return tmp;
}
-// Stops the data acquision
-// It should be safe to call this function from any context
-static int usbduxfastsub_unlink_InURBs(usbduxfastsub_t * usbduxfastsub_tmp)
+/*
+ * Stops the data acquision.
+ * It should be safe to call this function from any context.
+ */
+static int usbduxfastsub_unlink_InURBs(struct usbduxfastsub_s *udfs)
{
int j = 0;
int err = 0;
- if (usbduxfastsub_tmp && usbduxfastsub_tmp->urbIn) {
- usbduxfastsub_tmp->ai_cmd_running = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)
- j = usb_unlink_urb(usbduxfastsub_tmp->urbIn);
- if (j < 0) {
- err = j;
- }
-#else
- // waits until a running transfer is over
- usb_kill_urb(usbduxfastsub_tmp->urbIn);
+ if (udfs && udfs->urbIn) {
+ udfs->ai_cmd_running = 0;
+ /* waits until a running transfer is over */
+ usb_kill_urb(udfs->urbIn);
j = 0;
-#endif
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi: usbduxfast: unlinked InURB: res=%d\n", j);
+ printk(KERN_DEBUG "comedi: usbduxfast: unlinked InURB: res=%d\n", j);
#endif
return err;
}
-/* This will stop a running acquisition operation */
-// Is called from within this driver from both the
-// interrupt context and from comedi
-static int usbduxfast_ai_stop(usbduxfastsub_t * this_usbduxfastsub,
+/*
+ * This will stop a running acquisition operation.
+ * Is called from within this driver from both the
+ * interrupt context and from comedi.
+ */
+static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs,
int do_unlink)
{
int ret = 0;
- if (!this_usbduxfastsub) {
- printk("comedi?: usbduxfast_ai_stop: this_usbduxfastsub=NULL!\n");
+ if (!udfs) {
+ printk(KERN_ERR "comedi?: usbduxfast_ai_stop: udfs=NULL!\n");
return -EFAULT;
}
+
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi: usbduxfast_ai_stop\n");
+ printk(KERN_DEBUG "comedi: usbduxfast_ai_stop\n");
#endif
- this_usbduxfastsub->ai_cmd_running = 0;
+ udfs->ai_cmd_running = 0;
- if (do_unlink) {
- // stop aquistion
- ret = usbduxfastsub_unlink_InURBs(this_usbduxfastsub);
- }
+ if (do_unlink)
+ ret = usbduxfastsub_unlink_InURBs(udfs); /* stop aquistion */
return ret;
}
-// This will cancel a running acquisition operation.
-// This is called by comedi but never from inside the
-// driver.
-static int usbduxfast_ai_cancel(comedi_device * dev, comedi_subdevice * s)
+/*
+ * This will cancel a running acquisition operation.
+ * This is called by comedi but never from inside the driver.
+ */
+static int usbduxfast_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
- usbduxfastsub_t *this_usbduxfastsub;
- int res = 0;
+ struct usbduxfastsub_s *udfs;
+ int ret;
- // force unlink of all urbs
+ /* force unlink of all urbs */
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi: usbduxfast_ai_cancel\n");
+ printk(KERN_DEBUG "comedi: usbduxfast_ai_cancel\n");
#endif
- this_usbduxfastsub = dev->private;
- if (!this_usbduxfastsub) {
- printk("comedi: usbduxfast_ai_cancel: this_usbduxfastsub=NULL\n");
+ udfs = dev->private;
+ if (!udfs) {
+ printk(KERN_ERR "comedi: usbduxfast_ai_cancel: udfs=NULL\n");
return -EFAULT;
}
- down(&this_usbduxfastsub->sem);
- if (!(this_usbduxfastsub->probed)) {
- up(&this_usbduxfastsub->sem);
+ down(&udfs->sem);
+ if (!udfs->probed) {
+ up(&udfs->sem);
return -ENODEV;
}
- // unlink
- res = usbduxfast_ai_stop(this_usbduxfastsub, 1);
- up(&this_usbduxfastsub->sem);
+ /* unlink */
+ ret = usbduxfast_ai_stop(udfs, 1);
+ up(&udfs->sem);
- return res;
+ return ret;
}
-// analogue IN
-// interrupt service routine
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void usbduxfastsub_ai_Irq(struct urb *urb)
-#else
+/*
+ * analogue IN
+ * interrupt service routine
+ */
static void usbduxfastsub_ai_Irq(struct urb *urb PT_REGS_ARG)
-#endif
{
int n, err;
- usbduxfastsub_t *this_usbduxfastsub;
- comedi_device *this_comedidev;
- comedi_subdevice *s;
+ struct usbduxfastsub_s *udfs;
+ struct comedi_device *this_comedidev;
+ struct comedi_subdevice *s;
uint16_t *p;
- // sanity checks
- // is the urb there?
+ /* sanity checks - is the urb there? */
if (!urb) {
- printk("comedi_: usbduxfast_: ao int-handler called with urb=NULL!\n");
+ printk(KERN_ERR "comedi_: usbduxfast_: ao int-handler called "
+ "with urb=NULL!\n");
return;
}
- // the context variable points to the subdevice
+ /* the context variable points to the subdevice */
this_comedidev = urb->context;
if (!this_comedidev) {
- printk("comedi_: usbduxfast_: urb context is a NULL pointer!\n");
+ printk(KERN_ERR "comedi_: usbduxfast_: urb context is a NULL "
+ "pointer!\n");
return;
}
- // the private structure of the subdevice is usbduxfastsub_t
- this_usbduxfastsub = this_comedidev->private;
- if (!this_usbduxfastsub) {
- printk("comedi_: usbduxfast_: private of comedi subdev is a NULL pointer!\n");
+ /* the private structure of the subdevice is usbduxfastsub_s */
+ udfs = this_comedidev->private;
+ if (!udfs) {
+ printk(KERN_ERR "comedi_: usbduxfast_: private of comedi "
+ "subdev is a NULL pointer!\n");
return;
}
- // are we running a command?
- if (unlikely(!(this_usbduxfastsub->ai_cmd_running))) {
- // not running a command
- // do not continue execution if no asynchronous command is running
- // in particular not resubmit
+ /* are we running a command? */
+ if (unlikely(!udfs->ai_cmd_running)) {
+ /*
+ * not running a command
+ * do not continue execution if no asynchronous command
+ * is running in particular not resubmit
+ */
return;
}
- if (unlikely(!(this_usbduxfastsub->attached))) {
- // no comedi device there
+ if (unlikely(!udfs->attached)) {
+ /* no comedi device there */
return;
}
- // subdevice which is the AD converter
+ /* subdevice which is the AD converter */
s = this_comedidev->subdevices + SUBDEV_AD;
- // first we test if something unusual has just happened
+ /* first we test if something unusual has just happened */
switch (urb->status) {
case 0:
break;
- // happens after an unlink command or when the device is plugged out
+ /*
+ * happens after an unlink command or when the device
+ * is plugged out
+ */
case -ECONNRESET:
case -ENOENT:
case -ESHUTDOWN:
case -ECONNABORTED:
- // tell this comedi
+ /* tell this comedi */
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
- comedi_event(this_usbduxfastsub->comedidev, s);
- // stop the transfer w/o unlink
- usbduxfast_ai_stop(this_usbduxfastsub, 0);
+ comedi_event(udfs->comedidev, s);
+ /* stop the transfer w/o unlink */
+ usbduxfast_ai_stop(udfs, 0);
return;
default:
- printk("comedi%d: usbduxfast: non-zero urb status received in ai intr context: %d\n", this_usbduxfastsub->comedidev->minor, urb->status);
+ printk("comedi%d: usbduxfast: non-zero urb status received in "
+ "ai intr context: %d\n",
+ udfs->comedidev->minor, urb->status);
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
- comedi_event(this_usbduxfastsub->comedidev, s);
- usbduxfast_ai_stop(this_usbduxfastsub, 0);
+ comedi_event(udfs->comedidev, s);
+ usbduxfast_ai_stop(udfs, 0);
return;
}
p = urb->transfer_buffer;
- if (!this_usbduxfastsub->ignore) {
- if (!(this_usbduxfastsub->ai_continous)) {
- // not continous, fixed number of samples
+ if (!udfs->ignore) {
+ if (!udfs->ai_continous) {
+ /* not continous, fixed number of samples */
n = urb->actual_length / sizeof(uint16_t);
- if (unlikely(this_usbduxfastsub->ai_sample_count < n)) {
- // we have send only a fraction of the bytes received
+ if (unlikely(udfs->ai_sample_count < n)) {
+ /*
+ * we have send only a fraction of the bytes
+ * received
+ */
cfc_write_array_to_buffer(s,
urb->transfer_buffer,
- this_usbduxfastsub->ai_sample_count *
- sizeof(uint16_t));
- usbduxfast_ai_stop(this_usbduxfastsub, 0);
- // say comedi that the acquistion is over
+ udfs->ai_sample_count
+ * sizeof(uint16_t));
+ usbduxfast_ai_stop(udfs, 0);
+ /* say comedi that the acquistion is over */
s->async->events |= COMEDI_CB_EOA;
- comedi_event(this_usbduxfastsub->comedidev, s);
+ comedi_event(udfs->comedidev, s);
return;
}
- this_usbduxfastsub->ai_sample_count -= n;
+ udfs->ai_sample_count -= n;
}
- // write the full buffer to comedi
- cfc_write_array_to_buffer(s,
- urb->transfer_buffer, urb->actual_length);
+ /* write the full buffer to comedi */
+ cfc_write_array_to_buffer(s, urb->transfer_buffer,
+ urb->actual_length);
- // tell comedi that data is there
- comedi_event(this_usbduxfastsub->comedidev, s);
+ /* tell comedi that data is there */
+ comedi_event(udfs->comedidev, s);
} else {
- // ignore this packet
- this_usbduxfastsub->ignore--;
+ /* ignore this packet */
+ udfs->ignore--;
}
- // command is still running
- // resubmit urb for BULK transfer
- urb->dev = this_usbduxfastsub->usbdev;
+ /*
+ * command is still running
+ * resubmit urb for BULK transfer
+ */
+ urb->dev = udfs->usbdev;
urb->status = 0;
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
- printk("comedi%d: usbduxfast: urb resubm failed: %d",
- this_usbduxfastsub->comedidev->minor, err);
+ printk(KERN_ERR "comedi%d: usbduxfast: urb resubm failed: %d",
+ udfs->comedidev->minor, err);
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
- comedi_event(this_usbduxfastsub->comedidev, s);
- usbduxfast_ai_stop(this_usbduxfastsub, 0);
+ comedi_event(udfs->comedidev, s);
+ usbduxfast_ai_stop(udfs, 0);
}
}
-static int usbduxfastsub_start(usbduxfastsub_t * usbduxfastsub)
+static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
{
- int errcode = 0;
+ int ret;
unsigned char local_transfer_buffer[16];
- if (usbduxfastsub->probed) {
- // 7f92 to zero
- local_transfer_buffer[0] = 0;
- errcode = usb_control_msg(usbduxfastsub->usbdev,
- // create a pipe for a control transfer
- usb_sndctrlpipe(usbduxfastsub->usbdev, 0),
- // bRequest, "Firmware"
- USBDUXFASTSUB_FIRMWARE,
- // bmRequestType
- VENDOR_DIR_OUT,
- // Value
- USBDUXFASTSUB_CPUCS,
- // Index
- 0x0000,
- // address of the transfer buffer
- local_transfer_buffer,
- // Length
- 1,
- // Timeout
- EZTIMEOUT);
- if (errcode < 0) {
- printk("comedi_: usbduxfast_: control msg failed (start)\n");
- return errcode;
- }
+ /* 7f92 to zero */
+ local_transfer_buffer[0] = 0;
+ ret = usb_control_msg(udfs->usbdev,
+ usb_sndctrlpipe(udfs->usbdev, 0),
+ USBDUXFASTSUB_FIRMWARE, /* bRequest, "Firmware" */
+ VENDOR_DIR_OUT, /* bmRequestType */
+ USBDUXFASTSUB_CPUCS, /* Value */
+ 0x0000, /* Index */
+ local_transfer_buffer, /* address of the transfer buffer */
+ 1, /* Length */
+ EZTIMEOUT); /* Timeout */
+ if (ret < 0) {
+ printk("comedi_: usbduxfast_: control msg failed (start)\n");
+ return ret;
}
+
return 0;
}
-static int usbduxfastsub_stop(usbduxfastsub_t * usbduxfastsub)
+static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
{
- int errcode = 0;
-
+ int ret;
unsigned char local_transfer_buffer[16];
- if (usbduxfastsub->probed) {
- // 7f92 to one
- local_transfer_buffer[0] = 1;
- errcode = usb_control_msg(usbduxfastsub->usbdev,
- usb_sndctrlpipe(usbduxfastsub->usbdev, 0),
- // bRequest, "Firmware"
- USBDUXFASTSUB_FIRMWARE,
- // bmRequestType
- VENDOR_DIR_OUT,
- // Value
- USBDUXFASTSUB_CPUCS,
- // Index
- 0x0000, local_transfer_buffer,
- // Length
- 1,
- // Timeout
- EZTIMEOUT);
- if (errcode < 0) {
- printk("comedi_: usbduxfast: control msg failed (stop)\n");
- return errcode;
- }
+
+ /* 7f92 to one */
+ local_transfer_buffer[0] = 1;
+ ret = usb_control_msg(udfs->usbdev,
+ usb_sndctrlpipe(udfs->usbdev, 0),
+ USBDUXFASTSUB_FIRMWARE, /* bRequest, "Firmware" */
+ VENDOR_DIR_OUT, /* bmRequestType */
+ USBDUXFASTSUB_CPUCS, /* Value */
+ 0x0000, /* Index */
+ local_transfer_buffer,
+ 1, /* Length */
+ EZTIMEOUT); /* Timeout */
+ if (ret < 0) {
+ printk(KERN_ERR "comedi_: usbduxfast: control msg failed "
+ "(stop)\n");
+ return ret;
}
+
return 0;
}
-static int usbduxfastsub_upload(usbduxfastsub_t * usbduxfastsub,
+static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs,
unsigned char *local_transfer_buffer,
unsigned int startAddr, unsigned int len)
{
- int errcode;
+ int ret;
- if (usbduxfastsub->probed) {
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast: uploading %d bytes",
- usbduxfastsub->comedidev->minor, len);
- printk(" to addr %d, first byte=%d.\n",
- startAddr, local_transfer_buffer[0]);
+ printk(KERN_DEBUG "comedi: usbduxfast: uploading %d bytes", len);
+ printk(KERN_DEBUG " to addr %d, first byte=%d.\n",
+ startAddr, local_transfer_buffer[0]);
#endif
- errcode = usb_control_msg(usbduxfastsub->usbdev,
- usb_sndctrlpipe(usbduxfastsub->usbdev, 0),
- // brequest, firmware
- USBDUXFASTSUB_FIRMWARE,
- // bmRequestType
- VENDOR_DIR_OUT,
- // value
- startAddr,
- // index
- 0x0000,
- // our local safe buffer
- local_transfer_buffer,
- // length
- len,
- // timeout
- EZTIMEOUT);
+ ret = usb_control_msg(udfs->usbdev,
+ usb_sndctrlpipe(udfs->usbdev, 0),
+ USBDUXFASTSUB_FIRMWARE, /* brequest, firmware */
+ VENDOR_DIR_OUT, /* bmRequestType */
+ startAddr, /* value */
+ 0x0000, /* index */
+ local_transfer_buffer, /* our local safe buffer */
+ len, /* length */
+ EZTIMEOUT); /* timeout */
+
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast: result=%d\n", errcode);
+ printk(KERN_DEBUG "comedi_: usbduxfast: result=%d\n", ret);
#endif
- if (errcode < 0) {
- printk("comedi_: usbduxfast: uppload failed\n");
- return errcode;
- }
- } else {
- // no device on the bus for this index
- return -EFAULT;
+
+ if (ret < 0) {
+ printk(KERN_ERR "comedi_: usbduxfast: uppload failed\n");
+ return ret;
}
+
return 0;
}
-int firmwareUpload(usbduxfastsub_t * usbduxfastsub,
- unsigned char *firmwareBinary, int sizeFirmware)
+int firmwareUpload(struct usbduxfastsub_s *udfs, unsigned char *firmwareBinary,
+ int sizeFirmware)
{
int ret;
- if (!firmwareBinary) {
+ if (!firmwareBinary)
return 0;
- }
- ret = usbduxfastsub_stop(usbduxfastsub);
+
+ ret = usbduxfastsub_stop(udfs);
if (ret < 0) {
- printk("comedi_: usbduxfast: can not stop firmware\n");
+ printk(KERN_ERR "comedi_: usbduxfast: can not stop firmware\n");
return ret;
}
- ret = usbduxfastsub_upload(usbduxfastsub,
- firmwareBinary, 0, sizeFirmware);
+ ret = usbduxfastsub_upload(udfs, firmwareBinary, 0, sizeFirmware);
if (ret < 0) {
- printk("comedi_: usbduxfast: firmware upload failed\n");
+ printk(KERN_ERR "comedi_: usbduxfast: firmware upload failed\n");
return ret;
}
- ret = usbduxfastsub_start(usbduxfastsub);
+ ret = usbduxfastsub_start(udfs);
if (ret < 0) {
- printk("comedi_: usbduxfast: can not start firmware\n");
+ printk(KERN_ERR "comedi_: usbduxfast: can not start firmware\n");
return ret;
}
+
return 0;
}
-int usbduxfastsub_submit_InURBs(usbduxfastsub_t * usbduxfastsub)
+int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs)
{
- int errFlag;
+ int ret;
- if (!usbduxfastsub) {
+ if (!udfs)
return -EFAULT;
- }
- usb_fill_bulk_urb(usbduxfastsub->urbIn,
- usbduxfastsub->usbdev,
- usb_rcvbulkpipe(usbduxfastsub->usbdev, BULKINEP),
- usbduxfastsub->transfer_buffer,
- SIZEINBUF, usbduxfastsub_ai_Irq, usbduxfastsub->comedidev);
+
+ usb_fill_bulk_urb(udfs->urbIn, udfs->usbdev,
+ usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
+ udfs->transfer_buffer,
+ SIZEINBUF, usbduxfastsub_ai_Irq, udfs->comedidev);
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast: submitting in-urb: %x,%x\n",
- usbduxfastsub->comedidev->minor,
- (int)(usbduxfastsub->urbIn->context),
- (int)(usbduxfastsub->urbIn->dev));
+ printk(KERN_DEBUG "comedi%d: usbduxfast: submitting in-urb: "
+ "0x%p,0x%p\n", udfs->comedidev->minor, udfs->urbIn->context,
+ udfs->urbIn->dev);
#endif
- errFlag = usb_submit_urb(usbduxfastsub->urbIn, GFP_ATOMIC);
- if (errFlag) {
- printk("comedi_: usbduxfast: ai: usb_submit_urb error %d\n",
- errFlag);
- return errFlag;
+ ret = usb_submit_urb(udfs->urbIn, GFP_ATOMIC);
+ if (ret) {
+ printk(KERN_ERR "comedi_: usbduxfast: ai: usb_submit_urb error"
+ " %d\n", ret);
+ return ret;
}
return 0;
}
-static int usbduxfast_ai_cmdtest(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd)
+static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
int err = 0, stop_mask = 0;
- long int steps, tmp = 0;
+ long int steps, tmp;
int minSamplPer;
- usbduxfastsub_t *this_usbduxfastsub = dev->private;
- if (!(this_usbduxfastsub->probed)) {
+ struct usbduxfastsub_s *udfs = dev->private;
+
+ if (!udfs->probed)
return -ENODEV;
- }
+
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast_ai_cmdtest\n", dev->minor);
- printk("comedi%d: usbduxfast: convert_arg=%u scan_begin_arg=%u\n",
- dev->minor, cmd->convert_arg, cmd->scan_begin_arg);
+ printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmdtest\n", dev->minor);
+ printk(KERN_DEBUG "comedi%d: usbduxfast: convert_arg=%u "
+ "scan_begin_arg=%u\n",
+ dev->minor, cmd->convert_arg, cmd->scan_begin_arg);
#endif
/* step 1: make sure trigger sources are trivially valid */
@@ -621,7 +625,9 @@ static int usbduxfast_ai_cmdtest(comedi_device * dev,
if (err)
return 1;
- /* step 2: make sure trigger sources are unique and mutually compatible */
+ /*
+ * step 2: make sure trigger sources are unique and mutually compatible
+ */
if (cmd->start_src != TRIG_NOW &&
cmd->start_src != TRIG_EXT && cmd->start_src != TRIG_INT)
@@ -636,7 +642,7 @@ static int usbduxfast_ai_cmdtest(comedi_device * dev,
cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE)
err++;
- // can't have external stop and start triggers at once
+ /* can't have external stop and start triggers at once */
if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
err++;
@@ -650,29 +656,28 @@ static int usbduxfast_ai_cmdtest(comedi_device * dev,
err++;
}
- if (!cmd->chanlist_len) {
+ if (!cmd->chanlist_len)
err++;
- }
+
if (cmd->scan_end_arg != cmd->chanlist_len) {
cmd->scan_end_arg = cmd->chanlist_len;
err++;
}
- if (cmd->chanlist_len == 1) {
+ if (cmd->chanlist_len == 1)
minSamplPer = 1;
- } else {
+ else
minSamplPer = MIN_SAMPLING_PERIOD;
- }
if (cmd->convert_src == TRIG_TIMER) {
steps = cmd->convert_arg * 30;
- if (steps < (minSamplPer * 1000)) {
+ if (steps < (minSamplPer * 1000))
steps = minSamplPer * 1000;
- }
- if (steps > (MAX_SAMPLING_PERIOD * 1000)) {
+
+ if (steps > (MAX_SAMPLING_PERIOD * 1000))
steps = MAX_SAMPLING_PERIOD * 1000;
- }
- // calc arg again
+
+ /* calc arg again */
tmp = steps / 30;
if (cmd->convert_arg != tmp) {
cmd->convert_arg = tmp;
@@ -680,10 +685,10 @@ static int usbduxfast_ai_cmdtest(comedi_device * dev,
}
}
- if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_src == TRIG_TIMER)
err++;
- }
- // stop source
+
+ /* stop source */
switch (cmd->stop_src) {
case TRIG_COUNT:
if (!cmd->stop_arg) {
@@ -697,7 +702,10 @@ static int usbduxfast_ai_cmdtest(comedi_device * dev,
err++;
}
break;
- // TRIG_EXT doesn't care since it doesn't trigger off a numbered channel
+ /*
+ * TRIG_EXT doesn't care since it doesn't trigger
+ * off a numbered channel
+ */
default:
break;
}
@@ -711,600 +719,688 @@ static int usbduxfast_ai_cmdtest(comedi_device * dev,
}
-static int usbduxfast_ai_inttrig(comedi_device * dev,
- comedi_subdevice * s, unsigned int trignum)
+static int usbduxfast_ai_inttrig(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int trignum)
{
int ret;
- usbduxfastsub_t *this_usbduxfastsub = dev->private;
- if (!this_usbduxfastsub) {
+ struct usbduxfastsub_s *udfs = dev->private;
+
+ if (!udfs)
return -EFAULT;
- }
- down(&this_usbduxfastsub->sem);
- if (!(this_usbduxfastsub->probed)) {
- up(&this_usbduxfastsub->sem);
+
+ down(&udfs->sem);
+ if (!udfs->probed) {
+ up(&udfs->sem);
return -ENODEV;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast_ai_inttrig\n", dev->minor);
+ printk(KERN_DEBUG "comedi%d: usbduxfast_ai_inttrig\n", dev->minor);
#endif
if (trignum != 0) {
- printk("comedi%d: usbduxfast_ai_inttrig: invalid trignum\n",
- dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: invalid"
+ " trignum\n", dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
- if (!(this_usbduxfastsub->ai_cmd_running)) {
- this_usbduxfastsub->ai_cmd_running = 1;
- ret = usbduxfastsub_submit_InURBs(this_usbduxfastsub);
+ if (!udfs->ai_cmd_running) {
+ udfs->ai_cmd_running = 1;
+ ret = usbduxfastsub_submit_InURBs(udfs);
if (ret < 0) {
- printk("comedi%d: usbduxfast_ai_inttrig: urbSubmit: err=%d\n", dev->minor, ret);
- this_usbduxfastsub->ai_cmd_running = 0;
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: "
+ "urbSubmit: err=%d\n", dev->minor, ret);
+ udfs->ai_cmd_running = 0;
+ up(&udfs->sem);
return ret;
}
s->async->inttrig = NULL;
} else {
- printk("comedi%d: ai_inttrig but acqu is already running\n",
- dev->minor);
+ printk(KERN_ERR "comedi%d: ai_inttrig but acqu is already"
+ " running\n", dev->minor);
}
- up(&this_usbduxfastsub->sem);
+ up(&udfs->sem);
return 1;
}
-// offsets for the GPIF bytes
-// the first byte is the command byte
-#define LENBASE 1+0x00
-#define OPBASE 1+0x08
-#define OUTBASE 1+0x10
-#define LOGBASE 1+0x18
+/*
+ * offsets for the GPIF bytes
+ * the first byte is the command byte
+ */
+#define LENBASE (1+0x00)
+#define OPBASE (1+0x08)
+#define OUTBASE (1+0x10)
+#define LOGBASE (1+0x18)
-static int usbduxfast_ai_cmd(comedi_device * dev, comedi_subdevice * s)
+static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->async->cmd;
+ struct comedi_cmd *cmd = &s->async->cmd;
unsigned int chan, gain, rngmask = 0xff;
int i, j, ret;
- usbduxfastsub_t *this_usbduxfastsub = dev->private;
+ struct usbduxfastsub_s *udfs;
int result;
long steps, steps_tmp;
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast_ai_cmd\n", dev->minor);
+ printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmd\n", dev->minor);
#endif
- if (!this_usbduxfastsub) {
+ udfs = dev->private;
+ if (!udfs)
return -EFAULT;
- }
- down(&this_usbduxfastsub->sem);
- if (!(this_usbduxfastsub->probed)) {
- up(&this_usbduxfastsub->sem);
+
+ down(&udfs->sem);
+ if (!udfs->probed) {
+ up(&udfs->sem);
return -ENODEV;
}
- if (this_usbduxfastsub->ai_cmd_running) {
- printk("comedi%d: ai_cmd not possible. Another ai_cmd is running.\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ if (udfs->ai_cmd_running) {
+ printk(KERN_ERR "comedi%d: ai_cmd not possible. Another ai_cmd"
+ " is running.\n", dev->minor);
+ up(&udfs->sem);
return -EBUSY;
}
- // set current channel of the running aquisition to zero
+ /* set current channel of the running aquisition to zero */
s->async->cur_chan = 0;
- // ignore the first buffers from the device if there is an error condition
- this_usbduxfastsub->ignore = PACKETS_TO_IGNORE;
+ /*
+ * ignore the first buffers from the device if there
+ * is an error condition
+ */
+ udfs->ignore = PACKETS_TO_IGNORE;
if (cmd->chanlist_len > 0) {
gain = CR_RANGE(cmd->chanlist[0]);
for (i = 0; i < cmd->chanlist_len; ++i) {
chan = CR_CHAN(cmd->chanlist[i]);
if (chan != i) {
- printk("comedi%d: cmd is accepting only consecutive channels.\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: cmd is accepting "
+ "only consecutive channels.\n",
+ dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
if ((gain != CR_RANGE(cmd->chanlist[i]))
&& (cmd->chanlist_len > 3)) {
- printk("comedi%d: the gain must be the same for all channels.\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: the gain must be"
+ " the same for all channels.\n",
+ dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
if (i >= NUMCHANNELS) {
- printk("comedi%d: channel list too long\n",
- dev->minor);
+ printk(KERN_ERR "comedi%d: channel list too"
+ " long\n", dev->minor);
break;
}
}
}
steps = 0;
if (cmd->scan_begin_src == TRIG_TIMER) {
- printk("comedi%d: usbduxfast: scan_begin_src==TRIG_TIMER not valid.\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: usbduxfast: "
+ "scan_begin_src==TRIG_TIMER not valid.\n", dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
- if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_src == TRIG_TIMER)
steps = (cmd->convert_arg * 30) / 1000;
- }
+
if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
- printk("comedi%d: usbduxfast: ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n", dev->minor, steps, cmd->scan_begin_arg);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: steps=%ld, "
+ "scan_begin_arg=%d. Not properly tested by cmdtest?\n",
+ dev->minor, steps, cmd->scan_begin_arg);
+ up(&udfs->sem);
return -EINVAL;
}
if (steps > MAX_SAMPLING_PERIOD) {
- printk("comedi%d: usbduxfast: ai_cmd: sampling rate too low.\n",
- dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: sampling rate "
+ "too low.\n", dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
&& (cmd->chanlist_len != 16)) {
- printk("comedi%d: usbduxfast: ai_cmd: TRIG_EXT only with 1 or 16 channels possible.\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: TRIG_EXT only"
+ " with 1 or 16 channels possible.\n", dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast: steps=%ld, convert_arg=%u, ai_timer=%u\n",
- dev->minor,
- steps, cmd->convert_arg, this_usbduxfastsub->ai_timer);
+ printk(KERN_DEBUG "comedi%d: usbduxfast: steps=%ld, convert_arg=%u\n",
+ dev->minor, steps, cmd->convert_arg);
#endif
switch (cmd->chanlist_len) {
- // one channel
case 1:
+ /*
+ * one channel
+ */
+
if (CR_RANGE(cmd->chanlist[0]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // for external trigger: looping in this state until the RDY0 pin
- // becomes zero
- if (cmd->start_src == TRIG_EXT) { // we loop here until ready has been set
- this_usbduxfastsub->dux_commands[LENBASE + 0] = 0x01; // branch back to state 0
- this_usbduxfastsub->dux_commands[OPBASE + 0] = 0x01; // deceision state w/o data
- this_usbduxfastsub->dux_commands[OUTBASE + 0] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0x00; // RDY0 = 0
- } else { // we just proceed to state 1
- this_usbduxfastsub->dux_commands[LENBASE + 0] = 1;
- this_usbduxfastsub->dux_commands[OPBASE + 0] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 0] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
+ /*
+ * for external trigger: looping in this state until
+ * the RDY0 pin becomes zero
+ */
+
+ /* we loop here until ready has been set */
+ if (cmd->start_src == TRIG_EXT) {
+ /* branch back to state 0 */
+ udfs->dux_commands[LENBASE+0] = 0x01;
+ /* deceision state w/o data */
+ udfs->dux_commands[OPBASE+0] = 0x01;
+ udfs->dux_commands[OUTBASE+0] = 0xFF & rngmask;
+ /* RDY0 = 0 */
+ udfs->dux_commands[LOGBASE+0] = 0x00;
+ } else { /* we just proceed to state 1 */
+ udfs->dux_commands[LENBASE+0] = 1;
+ udfs->dux_commands[OPBASE+0] = 0;
+ udfs->dux_commands[OUTBASE+0] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+0] = 0;
}
if (steps < MIN_SAMPLING_PERIOD) {
- // for fast single channel aqu without mux
+ /* for fast single channel aqu without mux */
if (steps <= 1) {
- // we just stay here at state 1 and rexecute the same state
- // this gives us 30MHz sampling rate
- this_usbduxfastsub->dux_commands[LENBASE + 1] = 0x89; // branch back to state 1
- this_usbduxfastsub->dux_commands[OPBASE + 1] = 0x03; // deceision state with data
- this_usbduxfastsub->dux_commands[OUTBASE + 1] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0xFF; // doesn't matter
+ /*
+ * we just stay here at state 1 and rexecute
+ * the same state this gives us 30MHz sampling
+ * rate
+ */
+
+ /* branch back to state 1 */
+ udfs->dux_commands[LENBASE+1] = 0x89;
+ /* deceision state with data */
+ udfs->dux_commands[OPBASE+1] = 0x03;
+ udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+ /* doesn't matter */
+ udfs->dux_commands[LOGBASE+1] = 0xFF;
} else {
- // we loop through two states: data and delay: max rate is 15Mhz
- this_usbduxfastsub->dux_commands[LENBASE + 1] =
- steps - 1;
- this_usbduxfastsub->dux_commands[OPBASE + 1] = 0x02; // data
- this_usbduxfastsub->dux_commands[OUTBASE + 1] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0; // doesn't matter
-
- this_usbduxfastsub->dux_commands[LENBASE + 2] = 0x09; // branch back to state 1
- this_usbduxfastsub->dux_commands[OPBASE + 2] = 0x01; // deceision state w/o data
- this_usbduxfastsub->dux_commands[OUTBASE + 2] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 2] = 0xFF; // doesn't matter
+ /*
+ * we loop through two states: data and delay
+ * max rate is 15MHz
+ */
+ udfs->dux_commands[LENBASE+1] = steps - 1;
+ /* data */
+ udfs->dux_commands[OPBASE+1] = 0x02;
+ udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+ /* doesn't matter */
+ udfs->dux_commands[LOGBASE+1] = 0;
+ /* branch back to state 1 */
+ udfs->dux_commands[LENBASE+2] = 0x09;
+ /* deceision state w/o data */
+ udfs->dux_commands[OPBASE+2] = 0x01;
+ udfs->dux_commands[OUTBASE+2] = 0xFF & rngmask;
+ /* doesn't matter */
+ udfs->dux_commands[LOGBASE+2] = 0xFF;
}
} else {
- // we loop through 3 states: 2x delay and 1x data. This gives a min
- // sampling rate of 60kHz.
+ /*
+ * we loop through 3 states: 2x delay and 1x data
+ * this gives a min sampling rate of 60kHz
+ */
- // we have 1 state with duration 1
+ /* we have 1 state with duration 1 */
steps = steps - 1;
- // do the first part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + 1] =
- steps / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 1] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 1] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0;
-
- // and the second part
- this_usbduxfastsub->dux_commands[LENBASE + 2] =
- steps - steps / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 2] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 2] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 2] = 0;
-
- // get the data and branch back
- this_usbduxfastsub->dux_commands[LENBASE + 3] = 0x09; // branch back to state 1
- this_usbduxfastsub->dux_commands[OPBASE + 3] = 0x03; // deceision state w data
- this_usbduxfastsub->dux_commands[OUTBASE + 3] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 3] = 0xFF; // doesn't matter
+ /* do the first part of the delay */
+ udfs->dux_commands[LENBASE+1] = steps / 2;
+ udfs->dux_commands[OPBASE+1] = 0;
+ udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+1] = 0;
+
+ /* and the second part */
+ udfs->dux_commands[LENBASE+2] = steps - steps / 2;
+ udfs->dux_commands[OPBASE+2] = 0;
+ udfs->dux_commands[OUTBASE+2] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+2] = 0;
+
+ /* get the data and branch back */
+
+ /* branch back to state 1 */
+ udfs->dux_commands[LENBASE+3] = 0x09;
+ /* deceision state w data */
+ udfs->dux_commands[OPBASE+3] = 0x03;
+ udfs->dux_commands[OUTBASE+3] = 0xFF & rngmask;
+ /* doesn't matter */
+ udfs->dux_commands[LOGBASE+3] = 0xFF;
}
break;
case 2:
- // two channels
- // commit data to the FIFO
+ /*
+ * two channels
+ * commit data to the FIFO
+ */
+
if (CR_RANGE(cmd->chanlist[0]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- this_usbduxfastsub->dux_commands[LENBASE + 0] = 1;
- this_usbduxfastsub->dux_commands[OPBASE + 0] = 0x02; // data
- this_usbduxfastsub->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
- // we have 1 state with duration 1: state 0
+ udfs->dux_commands[LENBASE+0] = 1;
+ /* data */
+ udfs->dux_commands[OPBASE+0] = 0x02;
+ udfs->dux_commands[OUTBASE+0] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+0] = 0;
+
+ /* we have 1 state with duration 1: state 0 */
steps_tmp = steps - 1;
if (CR_RANGE(cmd->chanlist[1]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // do the first part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + 1] = steps_tmp / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 1] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 1] = 0xFE & rngmask; //count
- this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0;
-
- // and the second part
- this_usbduxfastsub->dux_commands[LENBASE + 2] =
- steps_tmp - steps_tmp / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 2] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 2] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 2] = 0;
-
- this_usbduxfastsub->dux_commands[LENBASE + 3] = 1;
- this_usbduxfastsub->dux_commands[OPBASE + 3] = 0x02; // data
- this_usbduxfastsub->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 3] = 0;
-
- // we have 2 states with duration 1: step 6 and the IDLE state
+
+ /* do the first part of the delay */
+ udfs->dux_commands[LENBASE+1] = steps_tmp / 2;
+ udfs->dux_commands[OPBASE+1] = 0;
+ /* count */
+ udfs->dux_commands[OUTBASE+1] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+1] = 0;
+
+ /* and the second part */
+ udfs->dux_commands[LENBASE+2] = steps_tmp - steps_tmp / 2;
+ udfs->dux_commands[OPBASE+2] = 0;
+ udfs->dux_commands[OUTBASE+2] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+2] = 0;
+
+ udfs->dux_commands[LENBASE+3] = 1;
+ /* data */
+ udfs->dux_commands[OPBASE+3] = 0x02;
+ udfs->dux_commands[OUTBASE+3] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+3] = 0;
+
+ /*
+ * we have 2 states with duration 1: step 6 and
+ * the IDLE state
+ */
steps_tmp = steps - 2;
if (CR_RANGE(cmd->chanlist[0]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // do the first part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + 4] = steps_tmp / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 4] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 4] = (0xFF - 0x02) & rngmask; //reset
- this_usbduxfastsub->dux_commands[LOGBASE + 4] = 0;
-
- // and the second part
- this_usbduxfastsub->dux_commands[LENBASE + 5] =
- steps_tmp - steps_tmp / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 5] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 5] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 5] = 0;
-
- this_usbduxfastsub->dux_commands[LENBASE + 6] = 1;
- this_usbduxfastsub->dux_commands[OPBASE + 6] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 6] = 0;
+
+ /* do the first part of the delay */
+ udfs->dux_commands[LENBASE+4] = steps_tmp / 2;
+ udfs->dux_commands[OPBASE+4] = 0;
+ /* reset */
+ udfs->dux_commands[OUTBASE+4] = (0xFF - 0x02) & rngmask;
+ udfs->dux_commands[LOGBASE+4] = 0;
+
+ /* and the second part */
+ udfs->dux_commands[LENBASE+5] = steps_tmp - steps_tmp / 2;
+ udfs->dux_commands[OPBASE+5] = 0;
+ udfs->dux_commands[OUTBASE+5] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+5] = 0;
+
+ udfs->dux_commands[LENBASE+6] = 1;
+ udfs->dux_commands[OPBASE+6] = 0;
+ udfs->dux_commands[OUTBASE+6] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+6] = 0;
break;
case 3:
- // three channels
+ /*
+ * three channels
+ */
for (j = 0; j < 1; j++) {
if (CR_RANGE(cmd->chanlist[j]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // commit data to the FIFO and do the first part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + j * 2] =
- steps / 2;
- this_usbduxfastsub->dux_commands[OPBASE + j * 2] = 0x02; // data
- this_usbduxfastsub->dux_commands[OUTBASE + j * 2] = 0xFF & rngmask; // no change
- this_usbduxfastsub->dux_commands[LOGBASE + j * 2] = 0;
+ /*
+ * commit data to the FIFO and do the first part
+ * of the delay
+ */
+ udfs->dux_commands[LENBASE+j*2] = steps / 2;
+ /* data */
+ udfs->dux_commands[OPBASE+j*2] = 0x02;
+ /* no change */
+ udfs->dux_commands[OUTBASE+j*2] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+j*2] = 0;
if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // do the second part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + j * 2 + 1] =
- steps - steps / 2;
- this_usbduxfastsub->dux_commands[OPBASE + j * 2 + 1] = 0; // no data
- this_usbduxfastsub->dux_commands[OUTBASE + j * 2 + 1] = 0xFE & rngmask; //count
- this_usbduxfastsub->dux_commands[LOGBASE + j * 2 + 1] =
- 0;
+
+ /* do the second part of the delay */
+ udfs->dux_commands[LENBASE+j*2+1] = steps - steps / 2;
+ /* no data */
+ udfs->dux_commands[OPBASE+j*2+1] = 0;
+ /* count */
+ udfs->dux_commands[OUTBASE+j*2+1] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+j*2+1] = 0;
}
- // 2 steps with duration 1: the idele step and step 6:
+ /* 2 steps with duration 1: the idele step and step 6: */
steps_tmp = steps - 2;
- // commit data to the FIFO and do the first part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + 4] = steps_tmp / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 4] = 0x02; // data
- this_usbduxfastsub->dux_commands[OUTBASE + 4] = 0xFF & rngmask; // no change
- this_usbduxfastsub->dux_commands[LOGBASE + 4] = 0;
+
+ /* commit data to the FIFO and do the first part of the delay */
+ udfs->dux_commands[LENBASE+4] = steps_tmp / 2;
+ /* data */
+ udfs->dux_commands[OPBASE+4] = 0x02;
+ udfs->dux_commands[OUTBASE+4] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+4] = 0;
if (CR_RANGE(cmd->chanlist[0]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // do the second part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + 5] =
- steps_tmp - steps_tmp / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 5] = 0; // no data
- this_usbduxfastsub->dux_commands[OUTBASE + 5] = (0xFF - 0x02) & rngmask; // reset
- this_usbduxfastsub->dux_commands[LOGBASE + 5] = 0;
-
- this_usbduxfastsub->dux_commands[LENBASE + 6] = 1;
- this_usbduxfastsub->dux_commands[OPBASE + 6] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 6] = 0;
+
+ /* do the second part of the delay */
+ udfs->dux_commands[LENBASE+5] = steps_tmp - steps_tmp / 2;
+ /* no data */
+ udfs->dux_commands[OPBASE+5] = 0;
+ /* reset */
+ udfs->dux_commands[OUTBASE+5] = (0xFF - 0x02) & rngmask;
+ udfs->dux_commands[LOGBASE+5] = 0;
+
+ udfs->dux_commands[LENBASE+6] = 1;
+ udfs->dux_commands[OPBASE+6] = 0;
+ udfs->dux_commands[OUTBASE+6] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+6] = 0;
case 16:
if (CR_RANGE(cmd->chanlist[0]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- if (cmd->start_src == TRIG_EXT) { // we loop here until ready has been set
- this_usbduxfastsub->dux_commands[LENBASE + 0] = 0x01; // branch back to state 0
- this_usbduxfastsub->dux_commands[OPBASE + 0] = 0x01; // deceision state w/o data
- this_usbduxfastsub->dux_commands[OUTBASE + 0] = (0xFF - 0x02) & rngmask; // reset
- this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0x00; // RDY0 = 0
- } else { // we just proceed to state 1
- this_usbduxfastsub->dux_commands[LENBASE + 0] = 255; // 30us reset pulse
- this_usbduxfastsub->dux_commands[OPBASE + 0] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 0] = (0xFF - 0x02) & rngmask; // reset
- this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
+
+ if (cmd->start_src == TRIG_EXT) {
+ /*
+ * we loop here until ready has been set
+ */
+
+ /* branch back to state 0 */
+ udfs->dux_commands[LENBASE+0] = 0x01;
+ /* deceision state w/o data */
+ udfs->dux_commands[OPBASE+0] = 0x01;
+ /* reset */
+ udfs->dux_commands[OUTBASE+0] = (0xFF-0x02) & rngmask;
+ /* RDY0 = 0 */
+ udfs->dux_commands[LOGBASE+0] = 0x00;
+ } else {
+ /*
+ * we just proceed to state 1
+ */
+
+ /* 30us reset pulse */
+ udfs->dux_commands[LENBASE+0] = 255;
+ udfs->dux_commands[OPBASE+0] = 0;
+ /* reset */
+ udfs->dux_commands[OUTBASE+0] = (0xFF-0x02) & rngmask;
+ udfs->dux_commands[LOGBASE+0] = 0;
}
- // commit data to the FIFO
- this_usbduxfastsub->dux_commands[LENBASE + 1] = 1;
- this_usbduxfastsub->dux_commands[OPBASE + 1] = 0x02; // data
- this_usbduxfastsub->dux_commands[OUTBASE + 1] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0;
+ /* commit data to the FIFO */
+ udfs->dux_commands[LENBASE+1] = 1;
+ /* data */
+ udfs->dux_commands[OPBASE+1] = 0x02;
+ udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+1] = 0;
- // we have 2 states with duration 1
+ /* we have 2 states with duration 1 */
steps = steps - 2;
- // do the first part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + 2] = steps / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 2] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 2] = 0xFE & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 2] = 0;
-
- // and the second part
- this_usbduxfastsub->dux_commands[LENBASE + 3] =
- steps - steps / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 3] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 3] = 0;
-
- this_usbduxfastsub->dux_commands[LENBASE + 4] = 0x09; // branch back to state 1
- this_usbduxfastsub->dux_commands[OPBASE + 4] = 0x01; // deceision state w/o data
- this_usbduxfastsub->dux_commands[OUTBASE + 4] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 4] = 0xFF; // doesn't matter
+ /* do the first part of the delay */
+ udfs->dux_commands[LENBASE+2] = steps / 2;
+ udfs->dux_commands[OPBASE+2] = 0;
+ udfs->dux_commands[OUTBASE+2] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+2] = 0;
+
+ /* and the second part */
+ udfs->dux_commands[LENBASE+3] = steps - steps / 2;
+ udfs->dux_commands[OPBASE+3] = 0;
+ udfs->dux_commands[OUTBASE+3] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+3] = 0;
+
+ /* branch back to state 1 */
+ udfs->dux_commands[LENBASE+4] = 0x09;
+ /* deceision state w/o data */
+ udfs->dux_commands[OPBASE+4] = 0x01;
+ udfs->dux_commands[OUTBASE+4] = 0xFF & rngmask;
+ /* doesn't matter */
+ udfs->dux_commands[LOGBASE+4] = 0xFF;
break;
default:
- printk("comedi %d: unsupported combination of channels\n",
- dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi %d: unsupported combination of "
+ "channels\n", dev->minor);
+ up(&udfs->sem);
return -EFAULT;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi %d: sending commands to the usb device\n", dev->minor);
+ printk(KERN_DEBUG "comedi %d: sending commands to the usb device\n",
+ dev->minor);
#endif
- // 0 means that the AD commands are sent
- result = send_dux_commands(this_usbduxfastsub, SENDADCOMMANDS);
+ /* 0 means that the AD commands are sent */
+ result = send_dux_commands(udfs, SENDADCOMMANDS);
if (result < 0) {
- printk("comedi%d: adc command could not be submitted. Aborting...\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: adc command could not be submitted."
+ "Aborting...\n", dev->minor);
+ up(&udfs->sem);
return result;
}
if (cmd->stop_src == TRIG_COUNT) {
- this_usbduxfastsub->ai_sample_count =
- (cmd->stop_arg) * (cmd->scan_end_arg);
- if (usbduxfastsub->ai_sample_count < 1) {
- printk("comedi%d: (cmd->stop_arg)*(cmd->scan_end_arg)<1, aborting.\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ udfs->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg;
+ if (udfs->ai_sample_count < 1) {
+ printk(KERN_ERR "comedi%d: "
+ "(cmd->stop_arg)*(cmd->scan_end_arg)<1, "
+ "aborting.\n", dev->minor);
+ up(&udfs->sem);
return -EFAULT;
}
- this_usbduxfastsub->ai_continous = 0;
+ udfs->ai_continous = 0;
} else {
- // continous aquisition
- this_usbduxfastsub->ai_continous = 1;
- this_usbduxfastsub->ai_sample_count = 0;
+ /* continous aquisition */
+ udfs->ai_continous = 1;
+ udfs->ai_sample_count = 0;
}
if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
- // enable this acquisition operation
- this_usbduxfastsub->ai_cmd_running = 1;
- ret = usbduxfastsub_submit_InURBs(this_usbduxfastsub);
+ /* enable this acquisition operation */
+ udfs->ai_cmd_running = 1;
+ ret = usbduxfastsub_submit_InURBs(udfs);
if (ret < 0) {
- this_usbduxfastsub->ai_cmd_running = 0;
- // fixme: unlink here??
- up(&this_usbduxfastsub->sem);
+ udfs->ai_cmd_running = 0;
+ /* fixme: unlink here?? */
+ up(&udfs->sem);
return ret;
}
s->async->inttrig = NULL;
} else {
- /* TRIG_INT */
- // don't enable the acquision operation
- // wait for an internal signal
+ /*
+ * TRIG_INT
+ * don't enable the acquision operation
+ * wait for an internal signal
+ */
s->async->inttrig = usbduxfast_ai_inttrig;
}
- up(&this_usbduxfastsub->sem);
+ up(&udfs->sem);
return 0;
}
-/* Mode 0 is used to get a single conversion on demand */
-static int usbduxfast_ai_insn_read(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+/*
+ * Mode 0 is used to get a single conversion on demand.
+ */
+static int usbduxfast_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int i, j, n, actual_length;
int chan, range, rngmask;
int err;
- usbduxfastsub_t *usbduxfastsub = dev->private;
+ struct usbduxfastsub_s *udfs;
- if (!usbduxfastsub) {
- printk("comedi%d: ai_insn_read: no usb dev.\n", dev->minor);
+ udfs = dev->private;
+ if (!udfs) {
+ printk(KERN_ERR "comedi%d: ai_insn_read: no usb dev.\n",
+ dev->minor);
return -ENODEV;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n",
- dev->minor, insn->n, insn->subdev);
+ printk(KERN_DEBUG "comedi%d: ai_insn_read, insn->n=%d, "
+ "insn->subdev=%d\n", dev->minor, insn->n, insn->subdev);
#endif
- down(&usbduxfastsub->sem);
- if (!(usbduxfastsub->probed)) {
- up(&usbduxfastsub->sem);
+ down(&udfs->sem);
+ if (!udfs->probed) {
+ up(&udfs->sem);
return -ENODEV;
}
- if (usbduxfastsub->ai_cmd_running) {
- printk("comedi%d: ai_insn_read not possible. Async Command is running.\n", dev->minor);
- up(&usbduxfastsub->sem);
+ if (udfs->ai_cmd_running) {
+ printk(KERN_ERR "comedi%d: ai_insn_read not possible. Async "
+ "Command is running.\n", dev->minor);
+ up(&udfs->sem);
return -EBUSY;
}
- // sample one channel
+ /* sample one channel */
chan = CR_CHAN(insn->chanspec);
range = CR_RANGE(insn->chanspec);
- // set command for the first channel
+ /* set command for the first channel */
if (range > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // commit data to the FIFO
- usbduxfastsub->dux_commands[LENBASE + 0] = 1;
- usbduxfastsub->dux_commands[OPBASE + 0] = 0x02; // data
- usbduxfastsub->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
-
- // do the first part of the delay
- usbduxfastsub->dux_commands[LENBASE + 1] = 12;
- usbduxfastsub->dux_commands[OPBASE + 1] = 0;
- usbduxfastsub->dux_commands[OUTBASE + 1] = 0xFE & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 1] = 0;
-
- usbduxfastsub->dux_commands[LENBASE + 2] = 1;
- usbduxfastsub->dux_commands[OPBASE + 2] = 0;
- usbduxfastsub->dux_commands[OUTBASE + 2] = 0xFE & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 2] = 0;
-
- usbduxfastsub->dux_commands[LENBASE + 3] = 1;
- usbduxfastsub->dux_commands[OPBASE + 3] = 0;
- usbduxfastsub->dux_commands[OUTBASE + 3] = 0xFE & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 3] = 0;
-
- usbduxfastsub->dux_commands[LENBASE + 4] = 1;
- usbduxfastsub->dux_commands[OPBASE + 4] = 0;
- usbduxfastsub->dux_commands[OUTBASE + 4] = 0xFE & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 4] = 0;
-
- // second part
- usbduxfastsub->dux_commands[LENBASE + 5] = 12;
- usbduxfastsub->dux_commands[OPBASE + 5] = 0;
- usbduxfastsub->dux_commands[OUTBASE + 5] = 0xFF & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 5] = 0;
-
- usbduxfastsub->dux_commands[LENBASE + 6] = 1;
- usbduxfastsub->dux_commands[OPBASE + 6] = 0;
- usbduxfastsub->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
+
+ /* commit data to the FIFO */
+ udfs->dux_commands[LENBASE+0] = 1;
+ /* data */
+ udfs->dux_commands[OPBASE+0] = 0x02;
+ udfs->dux_commands[OUTBASE+0] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+0] = 0;
+
+ /* do the first part of the delay */
+ udfs->dux_commands[LENBASE+1] = 12;
+ udfs->dux_commands[OPBASE+1] = 0;
+ udfs->dux_commands[OUTBASE+1] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+1] = 0;
+
+ udfs->dux_commands[LENBASE+2] = 1;
+ udfs->dux_commands[OPBASE+2] = 0;
+ udfs->dux_commands[OUTBASE+2] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+2] = 0;
+
+ udfs->dux_commands[LENBASE+3] = 1;
+ udfs->dux_commands[OPBASE+3] = 0;
+ udfs->dux_commands[OUTBASE+3] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+3] = 0;
+
+ udfs->dux_commands[LENBASE+4] = 1;
+ udfs->dux_commands[OPBASE+4] = 0;
+ udfs->dux_commands[OUTBASE+4] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+4] = 0;
+
+ /* second part */
+ udfs->dux_commands[LENBASE+5] = 12;
+ udfs->dux_commands[OPBASE+5] = 0;
+ udfs->dux_commands[OUTBASE+5] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+5] = 0;
+
+ udfs->dux_commands[LENBASE+6] = 1;
+ udfs->dux_commands[OPBASE+6] = 0;
+ udfs->dux_commands[OUTBASE+6] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+0] = 0;
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi %d: sending commands to the usb device\n", dev->minor);
+ printk(KERN_DEBUG "comedi %d: sending commands to the usb device\n",
+ dev->minor);
#endif
- // 0 means that the AD commands are sent
- err = send_dux_commands(usbduxfastsub, SENDADCOMMANDS);
+ /* 0 means that the AD commands are sent */
+ err = send_dux_commands(udfs, SENDADCOMMANDS);
if (err < 0) {
- printk("comedi%d: adc command could not be submitted. Aborting...\n", dev->minor);
- up(&usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: adc command could not be submitted."
+ "Aborting...\n", dev->minor);
+ up(&udfs->sem);
return err;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast: submitting in-urb: %x,%x\n",
- usbduxfastsub->comedidev->minor,
- (int)(usbduxfastsub->urbIn->context),
- (int)(usbduxfastsub->urbIn->dev));
+ printk(KERN_DEBUG "comedi%d: usbduxfast: submitting in-urb: "
+ "0x%p,0x%p\n", udfs->comedidev->minor, udfs->urbIn->context,
+ udfs->urbIn->dev);
#endif
for (i = 0; i < PACKETS_TO_IGNORE; i++) {
- err = usb_bulk_msg(usbduxfastsub->usbdev,
- usb_rcvbulkpipe(usbduxfastsub->usbdev,
- BULKINEP),
- usbduxfastsub->transfer_buffer, SIZEINBUF,
+ err = usb_bulk_msg(udfs->usbdev,
+ usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
+ udfs->transfer_buffer, SIZEINBUF,
&actual_length, 10000);
if (err < 0) {
- printk("comedi%d: insn timeout. No data.\n",
+ printk(KERN_ERR "comedi%d: insn timeout. No data.\n",
dev->minor);
- up(&usbduxfastsub->sem);
+ up(&udfs->sem);
return err;
}
}
- // data points
+ /* data points */
for (i = 0; i < insn->n;) {
- err = usb_bulk_msg(usbduxfastsub->usbdev,
- usb_rcvbulkpipe(usbduxfastsub->usbdev,
- BULKINEP),
- usbduxfastsub->transfer_buffer, SIZEINBUF,
+ err = usb_bulk_msg(udfs->usbdev,
+ usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
+ udfs->transfer_buffer, SIZEINBUF,
&actual_length, 10000);
if (err < 0) {
- printk("comedi%d: insn data error: %d\n",
+ printk(KERN_ERR "comedi%d: insn data error: %d\n",
dev->minor, err);
- up(&usbduxfastsub->sem);
+ up(&udfs->sem);
return err;
}
n = actual_length / sizeof(uint16_t);
if ((n % 16) != 0) {
- printk("comedi%d: insn data packet corrupted.\n",
- dev->minor);
- up(&usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: insn data packet "
+ "corrupted.\n", dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
- data[i] =
- ((uint16_t *) (usbduxfastsub->
- transfer_buffer))[j];
+ data[i] = ((uint16_t *) (udfs->transfer_buffer))[j];
i++;
}
}
- up(&usbduxfastsub->sem);
+ up(&udfs->sem);
return i;
}
static unsigned hex2unsigned(char *h)
{
unsigned hi, lo;
- if (h[0] > '9') {
+
+ if (h[0] > '9')
hi = h[0] - 'A' + 0x0a;
- } else {
+ else
hi = h[0] - '0';
- }
- if (h[1] > '9') {
+
+ if (h[1] > '9')
lo = h[1] - 'A' + 0x0a;
- } else {
+ else
lo = h[1] - '0';
- }
+
return hi * 0x10 + lo;
}
-// for FX2
+/* for FX2 */
#define FIRMWARE_MAX_LEN 0x2000
-// taken from David Brownell's fxload and adjusted for this driver
-static int read_firmware(usbduxfastsub_t * usbduxfastsub, void *firmwarePtr,
- long size)
+/*
+ * taken from David Brownell's fxload and adjusted for this driver
+ */
+static int read_firmware(struct usbduxfastsub_s *udfs, const void *firmwarePtr,
+ long size)
{
int i = 0;
unsigned char *fp = (char *)firmwarePtr;
- unsigned char *firmwareBinary = NULL;
+ unsigned char *firmwareBinary;
int res = 0;
int maxAddr = 0;
firmwareBinary = kmalloc(FIRMWARE_MAX_LEN, GFP_KERNEL);
if (!firmwareBinary) {
- printk("comedi_: usbduxfast: mem alloc for firmware failed\n");
+ printk(KERN_ERR "comedi_: usbduxfast: mem alloc for firmware "
+ " failed\n");
return -ENOMEM;
}
@@ -1315,31 +1411,37 @@ static int read_firmware(usbduxfastsub_t * usbduxfastsub, void *firmwarePtr,
int idx, off;
int j = 0;
- // get one line
+ /* get one line */
while ((i < size) && (fp[i] != 13) && (fp[i] != 10)) {
buf[j] = fp[i];
i++;
j++;
if (j >= sizeof(buf)) {
- printk("comedi_: usbduxfast: bogus firmware file!\n");
+ printk(KERN_ERR "comedi_: usbduxfast: bogus "
+ "firmware file!\n");
+ kfree(firmwareBinary);
return -1;
}
}
- // get rid of LF/CR/...
+ /* get rid of LF/CR/... */
while ((i < size) && ((fp[i] == 13) || (fp[i] == 10)
- || (fp[i] == 0))) {
+ || (fp[i] == 0)))
i++;
- }
buf[j] = 0;
- //printk("comedi_: buf=%s\n",buf);
+ /* printk("comedi_: buf=%s\n",buf); */
- /* EXTENSION: "# comment-till-end-of-line", for copyrights etc */
+ /*
+ * EXTENSION: "# comment-till-end-of-line",
+ * for copyrights etc
+ */
if (buf[0] == '#')
continue;
if (buf[0] != ':') {
- printk("comedi_: usbduxfast: upload: not an ihex record: %s", buf);
+ printk(KERN_ERR "comedi_: usbduxfast: upload: not an "
+ "ihex record: %s", buf);
+ kfree(firmwareBinary);
return -EFAULT;
}
@@ -1349,266 +1451,309 @@ static int read_firmware(usbduxfastsub_t * usbduxfastsub, void *firmwarePtr,
/* Read the target offset */
off = (hex2unsigned(buf + 3) * 0x0100) + hex2unsigned(buf + 5);
- if ((off + len) > maxAddr) {
+ if ((off + len) > maxAddr)
maxAddr = off + len;
- }
if (maxAddr >= FIRMWARE_MAX_LEN) {
- printk("comedi_: usbduxfast: firmware upload goes beyond FX2 RAM boundaries.");
+ printk(KERN_ERR "comedi_: usbduxfast: firmware upload "
+ "goes beyond FX2 RAM boundaries.");
+ kfree(firmwareBinary);
return -EFAULT;
}
- //printk("comedi_: usbduxfast: off=%x, len=%x:",off,len);
+ /* printk("comedi_: usbduxfast: off=%x, len=%x:",off,len); */
/* Read the record type */
type = hex2unsigned(buf + 7);
/* If this is an EOF record, then make it so. */
- if (type == 1) {
+ if (type == 1)
break;
- }
if (type != 0) {
- printk("comedi_: usbduxfast: unsupported record type: %u\n", type);
+ printk(KERN_ERR "comedi_: usbduxfast: unsupported "
+ "record type: %u\n", type);
+ kfree(firmwareBinary);
return -EFAULT;
}
for (idx = 0, cp = buf + 9; idx < len; idx += 1, cp += 2) {
firmwareBinary[idx + off] = hex2unsigned(cp);
- //printk("%02x ",firmwareBinary[idx+off]);
+ /* printk("%02x ",firmwareBinary[idx+off]); */
}
- //printk("\n");
+
+ /* printk("\n"); */
if (i >= size) {
- printk("comedi_: usbduxfast: unexpected end of hex file\n");
+ printk(KERN_ERR "comedi_: usbduxfast: unexpected end "
+ "of hex file\n");
break;
}
}
- res = firmwareUpload(usbduxfastsub, firmwareBinary, maxAddr + 1);
+ res = firmwareUpload(udfs, firmwareBinary, maxAddr + 1);
kfree(firmwareBinary);
return res;
}
-static void tidy_up(usbduxfastsub_t * usbduxfastsub_tmp)
+static void tidy_up(struct usbduxfastsub_s *udfs)
{
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast: tiding up\n");
+ printk(KERN_DEBUG "comedi_: usbduxfast: tiding up\n");
#endif
- if (!usbduxfastsub_tmp) {
+
+ if (!udfs)
return;
- }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- // shows the usb subsystem that the driver is down
- if (usbduxfastsub_tmp->interface) {
- usb_set_intfdata(usbduxfastsub_tmp->interface, NULL);
- }
-#endif
- usbduxfastsub_tmp->probed = 0;
+ /* shows the usb subsystem that the driver is down */
+ if (udfs->interface)
+ usb_set_intfdata(udfs->interface, NULL);
- if (usbduxfastsub_tmp->urbIn) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
- // waits until a running transfer is over
- // thus, under 2.4 hotplugging while a command
- // is running is not safe
- usb_kill_urb(usbduxfastsub_tmp->urbIn);
-#endif
- if (usbduxfastsub_tmp->transfer_buffer) {
- kfree(usbduxfastsub_tmp->transfer_buffer);
- usbduxfastsub_tmp->transfer_buffer = NULL;
- }
- usb_free_urb(usbduxfastsub_tmp->urbIn);
- usbduxfastsub_tmp->urbIn = NULL;
- }
- if (usbduxfastsub_tmp->insnBuffer) {
- kfree(usbduxfastsub_tmp->insnBuffer);
- usbduxfastsub_tmp->insnBuffer = NULL;
- }
- if (usbduxfastsub_tmp->dux_commands) {
- kfree(usbduxfastsub_tmp->dux_commands);
- usbduxfastsub_tmp->dux_commands = NULL;
+ udfs->probed = 0;
+
+ if (udfs->urbIn) {
+ /* waits until a running transfer is over */
+ usb_kill_urb(udfs->urbIn);
+
+ kfree(udfs->transfer_buffer);
+ udfs->transfer_buffer = NULL;
+
+ usb_free_urb(udfs->urbIn);
+ udfs->urbIn = NULL;
}
- usbduxfastsub_tmp->ai_cmd_running = 0;
+
+ kfree(udfs->insnBuffer);
+ udfs->insnBuffer = NULL;
+
+ kfree(udfs->dux_commands);
+ udfs->dux_commands = NULL;
+
+ udfs->ai_cmd_running = 0;
}
-// allocate memory for the urbs and initialise them
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void *usbduxfastsub_probe(struct usb_device *udev,
- unsigned int interfnum, const struct usb_device_id *id)
+static void usbduxfast_firmware_request_complete_handler(const struct firmware *fw,
+ void *context)
{
-#else
+ struct usbduxfastsub_s *usbduxfastsub_tmp = context;
+ struct usb_device *usbdev = usbduxfastsub_tmp->usbdev;
+ int ret;
+
+ if (fw == NULL)
+ return;
+
+ /*
+ * we need to upload the firmware here because fw will be
+ * freed once we've left this function
+ */
+ ret = read_firmware(usbduxfastsub_tmp, fw->data, fw->size);
+
+ if (ret) {
+ dev_err(&usbdev->dev,
+ "Could not upload firmware (err=%d)\n",
+ ret);
+ return;
+ }
+
+ comedi_usb_auto_config(usbdev, BOARDNAME);
+}
+
+/*
+ * allocate memory for the urbs and initialise them
+ */
static int usbduxfastsub_probe(struct usb_interface *uinterf,
const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(uinterf);
-#endif
int i;
int index;
+ int ret;
if (udev->speed != USB_SPEED_HIGH) {
- printk("comedi_: usbduxfast_: This driver needs USB 2.0 to operate. Aborting...\n");
+ printk(KERN_ERR "comedi_: usbduxfast_: This driver needs"
+ "USB 2.0 to operate. Aborting...\n");
return -ENODEV;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast_: finding a free structure for the usb-device\n");
+ printk(KERN_DEBUG "comedi_: usbduxfast_: finding a free structure for "
+ "the usb-device\n");
#endif
down(&start_stop_sem);
- // look for a free place in the usbduxfast array
+ /* look for a free place in the usbduxfast array */
index = -1;
for (i = 0; i < NUMUSBDUXFAST; i++) {
- if (!(usbduxfastsub[i].probed)) {
+ if (!usbduxfastsub[i].probed) {
index = i;
break;
}
}
- // no more space
+ /* no more space */
if (index == -1) {
- printk("Too many usbduxfast-devices connected.\n");
+ printk(KERN_ERR "Too many usbduxfast-devices connected.\n");
up(&start_stop_sem);
return -EMFILE;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast: usbduxfastsub[%d] is ready to connect to comedi.\n", index);
+ printk(KERN_DEBUG "comedi_: usbduxfast: usbduxfastsub[%d] is ready to "
+ "connect to comedi.\n", index);
#endif
init_MUTEX(&(usbduxfastsub[index].sem));
- // save a pointer to the usb device
+ /* save a pointer to the usb device */
usbduxfastsub[index].usbdev = udev;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- // save the interface number
- usbduxfastsub[index].ifnum = interfnum;
-#else
- // 2.6: save the interface itself
+ /* save the interface itself */
usbduxfastsub[index].interface = uinterf;
- // get the interface number from the interface
+ /* get the interface number from the interface */
usbduxfastsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
- // hand the private data over to the usb subsystem
- // will be needed for disconnect
+ /*
+ * hand the private data over to the usb subsystem
+ * will be needed for disconnect
+ */
usb_set_intfdata(uinterf, &(usbduxfastsub[index]));
-#endif
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast: ifnum=%d\n", usbduxfastsub[index].ifnum);
+ printk(KERN_DEBUG "comedi_: usbduxfast: ifnum=%d\n",
+ usbduxfastsub[index].ifnum);
#endif
- // create space for the commands going to the usb device
+ /* create space for the commands going to the usb device */
usbduxfastsub[index].dux_commands = kmalloc(SIZEOFDUXBUFFER,
- GFP_KERNEL);
+ GFP_KERNEL);
if (!usbduxfastsub[index].dux_commands) {
- printk("comedi_: usbduxfast: error alloc space for dac commands\n");
+ printk(KERN_ERR "comedi_: usbduxfast: error alloc space for "
+ "dac commands\n");
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
- // create space of the instruction buffer
+ /* create space of the instruction buffer */
usbduxfastsub[index].insnBuffer = kmalloc(SIZEINSNBUF, GFP_KERNEL);
- if (!(usbduxfastsub[index].insnBuffer)) {
- printk("comedi_: usbduxfast: could not alloc space for insnBuffer\n");
+ if (!usbduxfastsub[index].insnBuffer) {
+ printk(KERN_ERR "comedi_: usbduxfast: could not alloc space "
+ "for insnBuffer\n");
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
- // setting to alternate setting 1: enabling bulk ep
+ /* setting to alternate setting 1: enabling bulk ep */
i = usb_set_interface(usbduxfastsub[index].usbdev,
usbduxfastsub[index].ifnum, 1);
if (i < 0) {
- printk("comedi_: usbduxfast%d: could not switch to alternate setting 1.\n", index);
+ printk(KERN_ERR "comedi_: usbduxfast%d: could not switch to "
+ "alternate setting 1.\n", index);
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENODEV;
}
usbduxfastsub[index].urbIn = usb_alloc_urb(0, GFP_KERNEL);
- if (usbduxfastsub[index].urbIn == NULL) {
- printk("comedi_: usbduxfast%d: Could not alloc. urb\n", index);
+ if (!usbduxfastsub[index].urbIn) {
+ printk(KERN_ERR "comedi_: usbduxfast%d: Could not alloc."
+ "urb\n", index);
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
usbduxfastsub[index].transfer_buffer = kmalloc(SIZEINBUF, GFP_KERNEL);
- if (!(usbduxfastsub[index].transfer_buffer)) {
- printk("comedi_: usbduxfast%d: could not alloc. transb.\n",
- index);
+ if (!usbduxfastsub[index].transfer_buffer) {
+ printk(KERN_ERR "comedi_: usbduxfast%d: could not alloc. "
+ "transb.\n", index);
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
- // we've reached the bottom of the function
+ /* we've reached the bottom of the function */
usbduxfastsub[index].probed = 1;
up(&start_stop_sem);
- printk("comedi_: usbduxfast%d has been successfully initialized.\n",
- index);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- return (void *)(&usbduxfastsub[index]);
-#else
- // success
+
+ ret = request_firmware_nowait(THIS_MODULE,
+ FW_ACTION_HOTPLUG,
+ "usbduxfast_firmware.hex",
+ &udev->dev,
+ usbduxfastsub + index,
+ usbduxfast_firmware_request_complete_handler);
+
+ if (ret) {
+ dev_err(&udev->dev, "could not load firmware (err=%d)\n",
+ ret);
+ return ret;
+ }
+
+ printk(KERN_INFO "comedi_: usbduxfast%d has been successfully "
+ "initialized.\n", index);
+ /* success */
return 0;
-#endif
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void usbduxfastsub_disconnect(struct usb_device *udev, void *ptr)
-{
- usbduxfastsub_t *usbduxfastsub_tmp = (usbduxfastsub_t *) ptr;
-#else
static void usbduxfastsub_disconnect(struct usb_interface *intf)
{
- usbduxfastsub_t *usbduxfastsub_tmp = usb_get_intfdata(intf);
+ struct usbduxfastsub_s *udfs = usb_get_intfdata(intf);
struct usb_device *udev = interface_to_usbdev(intf);
-#endif
- if (!usbduxfastsub_tmp) {
- printk("comedi_: usbduxfast: disconnect called with null pointer.\n");
+
+ if (!udfs) {
+ printk(KERN_ERR "comedi_: usbduxfast: disconnect called with "
+ "null pointer.\n");
return;
}
- if (usbduxfastsub_tmp->usbdev != udev) {
- printk("comedi_: usbduxfast: BUG! called with wrong ptr!!!\n");
+ if (udfs->usbdev != udev) {
+ printk(KERN_ERR "comedi_: usbduxfast: BUG! called with wrong "
+ "ptr!!!\n");
return;
}
+
+ comedi_usb_auto_unconfig(udev);
+
down(&start_stop_sem);
- down(&usbduxfastsub_tmp->sem);
- tidy_up(usbduxfastsub_tmp);
- up(&usbduxfastsub_tmp->sem);
+ down(&udfs->sem);
+ tidy_up(udfs);
+ up(&udfs->sem);
up(&start_stop_sem);
+
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast: disconnected from the usb\n");
+ printk(KERN_DEBUG "comedi_: usbduxfast: disconnected from the usb\n");
#endif
}
-// is called when comedi-config is called
-static int usbduxfast_attach(comedi_device * dev, comedi_devconfig * it)
+/*
+ * is called when comedi-config is called
+ */
+static int usbduxfast_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
int ret;
int index;
int i;
- comedi_subdevice *s = NULL;
+ struct comedi_subdevice *s = NULL;
dev->private = NULL;
down(&start_stop_sem);
- // find a valid device which has been detected by the probe function of the usb
+ /*
+ * find a valid device which has been detected by the
+ * probe function of the usb
+ */
index = -1;
for (i = 0; i < NUMUSBDUXFAST; i++) {
- if ((usbduxfastsub[i].probed) && (!usbduxfastsub[i].attached)) {
+ if (usbduxfastsub[i].probed && !usbduxfastsub[i].attached) {
index = i;
break;
}
}
if (index < 0) {
- printk("comedi%d: usbduxfast: error: attach failed, no usbduxfast devs connected to the usb bus.\n", dev->minor);
+ printk(KERN_ERR "comedi%d: usbduxfast: error: attach failed, "
+ "no usbduxfast devs connected to the usb bus.\n",
+ dev->minor);
up(&start_stop_sem);
return -ENODEV;
}
down(&(usbduxfastsub[index].sem));
- // pointer back to the corresponding comedi device
+ /* pointer back to the corresponding comedi device */
usbduxfastsub[index].comedidev = dev;
- // trying to upload the firmware into the chip
+ /* trying to upload the firmware into the chip */
if (comedi_aux_data(it->options, 0) &&
- it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
- read_firmware(usbduxfastsub,
- comedi_aux_data(it->options, 0),
- it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
+ it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
+ read_firmware(&usbduxfastsub[index],
+ comedi_aux_data(it->options, 0),
+ it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
}
dev->board_name = BOARDNAME;
@@ -1616,155 +1761,150 @@ static int usbduxfast_attach(comedi_device * dev, comedi_devconfig * it)
/* set number of subdevices */
dev->n_subdevices = N_SUBDEVICES;
- // allocate space for the subdevices
- if ((ret = alloc_subdevices(dev, N_SUBDEVICES)) < 0) {
- printk("comedi%d: usbduxfast: error alloc space for subdev\n",
- dev->minor);
+ /* allocate space for the subdevices */
+ ret = alloc_subdevices(dev, N_SUBDEVICES);
+ if (ret < 0) {
+ printk(KERN_ERR "comedi%d: usbduxfast: error alloc space for "
+ "subdev\n", dev->minor);
+ up(&(usbduxfastsub[index].sem));
up(&start_stop_sem);
return ret;
}
- printk("comedi%d: usbduxfast: usb-device %d is attached to comedi.\n",
- dev->minor, index);
- // private structure is also simply the usb-structure
+ printk(KERN_INFO "comedi%d: usbduxfast: usb-device %d is attached to "
+ "comedi.\n", dev->minor, index);
+ /* private structure is also simply the usb-structure */
dev->private = usbduxfastsub + index;
- // the first subdevice is the A/D converter
+ /* the first subdevice is the A/D converter */
s = dev->subdevices + SUBDEV_AD;
- // the URBs get the comedi subdevice
- // which is responsible for reading
- // this is the subdevice which reads data
+ /*
+ * the URBs get the comedi subdevice which is responsible for reading
+ * this is the subdevice which reads data
+ */
dev->read_subdev = s;
- // the subdevice receives as private structure the
- // usb-structure
+ /* the subdevice receives as private structure the usb-structure */
s->private = NULL;
- // analog input
+ /* analog input */
s->type = COMEDI_SUBD_AI;
- // readable and ref is to ground
+ /* readable and ref is to ground */
s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
- // 16 channels
+ /* 16 channels */
s->n_chan = 16;
- // length of the channellist
+ /* length of the channellist */
s->len_chanlist = 16;
- // callback functions
+ /* callback functions */
s->insn_read = usbduxfast_ai_insn_read;
s->do_cmdtest = usbduxfast_ai_cmdtest;
s->do_cmd = usbduxfast_ai_cmd;
s->cancel = usbduxfast_ai_cancel;
- // max value from the A/D converter (12bit+1 bit for overflow)
+ /* max value from the A/D converter (12bit+1 bit for overflow) */
s->maxdata = 0x1000;
- // range table to convert to physical units
+ /* range table to convert to physical units */
s->range_table = &range_usbduxfast_ai_range;
- // finally decide that it's attached
+ /* finally decide that it's attached */
usbduxfastsub[index].attached = 1;
up(&(usbduxfastsub[index].sem));
-
up(&start_stop_sem);
-
- printk("comedi%d: successfully attached to usbduxfast.\n", dev->minor);
+ printk(KERN_INFO "comedi%d: successfully attached to usbduxfast.\n",
+ dev->minor);
return 0;
}
-static int usbduxfast_detach(comedi_device * dev)
+static int usbduxfast_detach(struct comedi_device *dev)
{
- usbduxfastsub_t *usbduxfastsub_tmp;
-
-#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast: detach usb device\n", dev->minor);
-#endif
+ struct usbduxfastsub_s *udfs;
if (!dev) {
- printk("comedi?: usbduxfast: detach without dev variable...\n");
+ printk(KERN_ERR "comedi?: usbduxfast: detach without dev "
+ "variable...\n");
return -EFAULT;
}
- usbduxfastsub_tmp = dev->private;
- if (!usbduxfastsub_tmp) {
- printk("comedi?: usbduxfast: detach without ptr to usbduxfastsub[]\n");
+#ifdef CONFIG_COMEDI_DEBUG
+ printk(KERN_DEBUG "comedi%d: usbduxfast: detach usb device\n",
+ dev->minor);
+#endif
+
+ udfs = dev->private;
+ if (!udfs) {
+ printk(KERN_ERR "comedi?: usbduxfast: detach without ptr to "
+ "usbduxfastsub[]\n");
return -EFAULT;
}
- down(&usbduxfastsub_tmp->sem);
+ down(&udfs->sem);
down(&start_stop_sem);
- // Don't allow detach to free the private structure
- // It's one entry of of usbduxfastsub[]
+ /*
+ * Don't allow detach to free the private structure
+ * It's one entry of of usbduxfastsub[]
+ */
dev->private = NULL;
- usbduxfastsub_tmp->attached = 0;
- usbduxfastsub_tmp->comedidev = NULL;
+ udfs->attached = 0;
+ udfs->comedidev = NULL;
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast: detach: successfully removed\n",
- dev->minor);
+ printk(KERN_DEBUG "comedi%d: usbduxfast: detach: successfully "
+ "removed\n", dev->minor);
#endif
up(&start_stop_sem);
- up(&usbduxfastsub_tmp->sem);
+ up(&udfs->sem);
return 0;
}
-/* main driver struct */
-static comedi_driver driver_usbduxfast = {
- driver_name:"usbduxfast",
- module:THIS_MODULE,
- attach:usbduxfast_attach,
- detach:usbduxfast_detach,
+/*
+ * main driver struct
+ */
+static struct comedi_driver driver_usbduxfast = {
+ .driver_name = "usbduxfast",
+ .module = THIS_MODULE,
+ .attach = usbduxfast_attach,
+ .detach = usbduxfast_detach
};
-static void init_usb_devices(void)
-{
- int index;
-#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast: setting all possible devs to invalid\n");
-#endif
- // all devices entries are invalid to begin with
- // they will become valid by the probe function
- // and then finally by the attach-function
- for (index = 0; index < NUMUSBDUXFAST; index++) {
- memset(&(usbduxfastsub[index]), 0x00,
- sizeof(usbduxfastsub[index]));
- init_MUTEX(&(usbduxfastsub[index].sem));
- }
-}
-
-// Table with the USB-devices: just now only testing IDs
+/*
+ * Table with the USB-devices: just now only testing IDs
+ */
static struct usb_device_id usbduxfastsub_table[] = {
- // { USB_DEVICE(0x4b4, 0x8613), //testing
- // },
- {USB_DEVICE(0x13d8, 0x0010) //real ID
- },
- {USB_DEVICE(0x13d8, 0x0011) //real ID
- },
- {} /* Terminating entry */
+ /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
+ { USB_DEVICE(0x13d8, 0x0010) }, /* real ID */
+ { USB_DEVICE(0x13d8, 0x0011) }, /* real ID */
+ { } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, usbduxfastsub_table);
-// The usbduxfastsub-driver
+/*
+ * The usbduxfastsub-driver
+ */
static struct usb_driver usbduxfastsub_driver = {
#ifdef COMEDI_HAVE_USB_DRIVER_OWNER
- owner:THIS_MODULE,
+ .owner = THIS_MODULE,
#endif
- name:BOARDNAME,
- probe:usbduxfastsub_probe,
- disconnect:usbduxfastsub_disconnect,
- id_table:usbduxfastsub_table,
+ .name = BOARDNAME,
+ .probe = usbduxfastsub_probe,
+ .disconnect = usbduxfastsub_disconnect,
+ .id_table = usbduxfastsub_table
};
-// Can't use the nice macro as I have also to initialise the USB
-// subsystem:
-// registering the usb-system _and_ the comedi-driver
-static int init_usbduxfast(void)
+/*
+ * Can't use the nice macro as I have also to initialise the USB subsystem:
+ * registering the usb-system _and_ the comedi-driver
+ */
+static int __init init_usbduxfast(void)
{
- printk(KERN_INFO KBUILD_MODNAME ": "
- DRIVER_VERSION ":" DRIVER_DESC "\n");
- init_usb_devices();
+ printk(KERN_INFO
+ KBUILD_MODNAME ": " DRIVER_VERSION ":" DRIVER_DESC "\n");
usb_register(&usbduxfastsub_driver);
comedi_driver_register(&driver_usbduxfast);
return 0;
}
-// deregistering the comedi driver and the usb-subsystem
-static void exit_usbduxfast(void)
+/*
+ * deregistering the comedi driver and the usb-subsystem
+ */
+static void __exit exit_usbduxfast(void)
{
comedi_driver_unregister(&driver_usbduxfast);
usb_deregister(&usbduxfastsub_driver);
diff --git a/drivers/staging/comedi/interrupt.h b/drivers/staging/comedi/interrupt.h
index 3038e461948..d1f09892da2 100644
--- a/drivers/staging/comedi/interrupt.h
+++ b/drivers/staging/comedi/interrupt.h
@@ -21,15 +21,6 @@
#include <linux/interrupt.h>
-#include <linux/version.h>
-
-#ifndef IRQ_NONE
-typedef void irqreturn_t;
-#define IRQ_NONE
-#define IRQ_HANDLED
-#define IRQ_RETVAL(x) (void)(x)
-#endif
-
#ifndef IRQF_DISABLED
#define IRQF_DISABLED SA_INTERRUPT
#define IRQF_SAMPLE_RANDOM SA_SAMPLE_RANDOM
diff --git a/drivers/staging/comedi/kcomedilib/data.c b/drivers/staging/comedi/kcomedilib/data.c
index 79aec204115..9797e13e377 100644
--- a/drivers/staging/comedi/kcomedilib/data.c
+++ b/drivers/staging/comedi/kcomedilib/data.c
@@ -27,10 +27,10 @@
#include <linux/string.h>
-int comedi_data_write(comedi_t * dev, unsigned int subdev, unsigned int chan,
- unsigned int range, unsigned int aref, lsampl_t data)
+int comedi_data_write(void *dev, unsigned int subdev, unsigned int chan,
+ unsigned int range, unsigned int aref, unsigned int data)
{
- comedi_insn insn;
+ struct comedi_insn insn;
memset(&insn, 0, sizeof(insn));
insn.insn = INSN_WRITE;
@@ -42,10 +42,10 @@ int comedi_data_write(comedi_t * dev, unsigned int subdev, unsigned int chan,
return comedi_do_insn(dev, &insn);
}
-int comedi_data_read(comedi_t * dev, unsigned int subdev, unsigned int chan,
- unsigned int range, unsigned int aref, lsampl_t * data)
+int comedi_data_read(void *dev, unsigned int subdev, unsigned int chan,
+ unsigned int range, unsigned int aref, unsigned int *data)
{
- comedi_insn insn;
+ struct comedi_insn insn;
memset(&insn, 0, sizeof(insn));
insn.insn = INSN_READ;
@@ -57,11 +57,11 @@ int comedi_data_read(comedi_t * dev, unsigned int subdev, unsigned int chan,
return comedi_do_insn(dev, &insn);
}
-int comedi_data_read_hint(comedi_t * dev, unsigned int subdev,
+int comedi_data_read_hint(void *dev, unsigned int subdev,
unsigned int chan, unsigned int range, unsigned int aref)
{
- comedi_insn insn;
- lsampl_t dummy_data;
+ struct comedi_insn insn;
+ unsigned int dummy_data;
memset(&insn, 0, sizeof(insn));
insn.insn = INSN_READ;
@@ -73,9 +73,9 @@ int comedi_data_read_hint(comedi_t * dev, unsigned int subdev,
return comedi_do_insn(dev, &insn);
}
-int comedi_data_read_delayed(comedi_t * dev, unsigned int subdev,
+int comedi_data_read_delayed(void *dev, unsigned int subdev,
unsigned int chan, unsigned int range, unsigned int aref,
- lsampl_t * data, unsigned int nano_sec)
+ unsigned int *data, unsigned int nano_sec)
{
int retval;
diff --git a/drivers/staging/comedi/kcomedilib/dio.c b/drivers/staging/comedi/kcomedilib/dio.c
index a9f488aed36..8595567e48f 100644
--- a/drivers/staging/comedi/kcomedilib/dio.c
+++ b/drivers/staging/comedi/kcomedilib/dio.c
@@ -26,10 +26,10 @@
#include <linux/string.h>
-int comedi_dio_config(comedi_t * dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan,
unsigned int io)
{
- comedi_insn insn;
+ struct comedi_insn insn;
memset(&insn, 0, sizeof(insn));
insn.insn = INSN_CONFIG;
@@ -41,10 +41,10 @@ int comedi_dio_config(comedi_t * dev, unsigned int subdev, unsigned int chan,
return comedi_do_insn(dev, &insn);
}
-int comedi_dio_read(comedi_t * dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan,
unsigned int *val)
{
- comedi_insn insn;
+ struct comedi_insn insn;
memset(&insn, 0, sizeof(insn));
insn.insn = INSN_READ;
@@ -56,10 +56,10 @@ int comedi_dio_read(comedi_t * dev, unsigned int subdev, unsigned int chan,
return comedi_do_insn(dev, &insn);
}
-int comedi_dio_write(comedi_t * dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_write(void *dev, unsigned int subdev, unsigned int chan,
unsigned int val)
{
- comedi_insn insn;
+ struct comedi_insn insn;
memset(&insn, 0, sizeof(insn));
insn.insn = INSN_WRITE;
@@ -71,11 +71,11 @@ int comedi_dio_write(comedi_t * dev, unsigned int subdev, unsigned int chan,
return comedi_do_insn(dev, &insn);
}
-int comedi_dio_bitfield(comedi_t * dev, unsigned int subdev, unsigned int mask,
+int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask,
unsigned int *bits)
{
- comedi_insn insn;
- lsampl_t data[2];
+ struct comedi_insn insn;
+ unsigned int data[2];
int ret;
memset(&insn, 0, sizeof(insn));
diff --git a/drivers/staging/comedi/kcomedilib/get.c b/drivers/staging/comedi/kcomedilib/get.c
index 2004ad4480c..b6b726a69f1 100644
--- a/drivers/staging/comedi/kcomedilib/get.c
+++ b/drivers/staging/comedi/kcomedilib/get.c
@@ -26,51 +26,51 @@
#include "../comedilib.h"
#include "../comedidev.h"
-int comedi_get_n_subdevices(comedi_t * d)
+int comedi_get_n_subdevices(void *d)
{
- comedi_device *dev = (comedi_device *) d;
+ struct comedi_device *dev = (struct comedi_device *) d;
return dev->n_subdevices;
}
-int comedi_get_version_code(comedi_t * d)
+int comedi_get_version_code(void *d)
{
return COMEDI_VERSION_CODE;
}
-const char *comedi_get_driver_name(comedi_t * d)
+const char *comedi_get_driver_name(void * d)
{
- comedi_device *dev = (comedi_device *) d;
+ struct comedi_device *dev = (struct comedi_device *) d;
return dev->driver->driver_name;
}
-const char *comedi_get_board_name(comedi_t * d)
+const char *comedi_get_board_name(void * d)
{
- comedi_device *dev = (comedi_device *) d;
+ struct comedi_device *dev = (struct comedi_device *) d;
return dev->board_name;
}
-int comedi_get_subdevice_type(comedi_t * d, unsigned int subdevice)
+int comedi_get_subdevice_type(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
return s->type;
}
-unsigned int comedi_get_subdevice_flags(comedi_t * d, unsigned int subdevice)
+unsigned int comedi_get_subdevice_flags(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
return s->subdev_flags;
}
-int comedi_find_subdevice_by_type(comedi_t * d, int type, unsigned int subd)
+int comedi_find_subdevice_by_type(void *d, int type, unsigned int subd)
{
- comedi_device *dev = (comedi_device *) d;
+ struct comedi_device *dev = (struct comedi_device *) d;
if (subd > dev->n_subdevices)
return -ENODEV;
@@ -82,27 +82,27 @@ int comedi_find_subdevice_by_type(comedi_t * d, int type, unsigned int subd)
return -1;
}
-int comedi_get_n_channels(comedi_t * d, unsigned int subdevice)
+int comedi_get_n_channels(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
return s->n_chan;
}
-int comedi_get_len_chanlist(comedi_t * d, unsigned int subdevice)
+int comedi_get_len_chanlist(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
return s->len_chanlist;
}
-lsampl_t comedi_get_maxdata(comedi_t * d, unsigned int subdevice,
+unsigned int comedi_get_maxdata(void *d, unsigned int subdevice,
unsigned int chan)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
if (s->maxdata_list)
return s->maxdata_list[chan];
@@ -111,11 +111,11 @@ lsampl_t comedi_get_maxdata(comedi_t * d, unsigned int subdevice,
}
#ifdef KCOMEDILIB_DEPRECATED
-int comedi_get_rangetype(comedi_t * d, unsigned int subdevice,
+int comedi_get_rangetype(void *d, unsigned int subdevice,
unsigned int chan)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
int ret;
if (s->range_table_list) {
@@ -130,10 +130,10 @@ int comedi_get_rangetype(comedi_t * d, unsigned int subdevice,
}
#endif
-int comedi_get_n_ranges(comedi_t * d, unsigned int subdevice, unsigned int chan)
+int comedi_get_n_ranges(void *d, unsigned int subdevice, unsigned int chan)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
int ret;
if (s->range_table_list) {
@@ -148,22 +148,22 @@ int comedi_get_n_ranges(comedi_t * d, unsigned int subdevice, unsigned int chan)
/*
* ALPHA (non-portable)
*/
-int comedi_get_krange(comedi_t * d, unsigned int subdevice, unsigned int chan,
- unsigned int range, comedi_krange * krange)
+int comedi_get_krange(void *d, unsigned int subdevice, unsigned int chan,
+ unsigned int range, struct comedi_krange *krange)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- const comedi_lrange *lr;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ const struct comedi_lrange *lr;
if (s->range_table_list) {
lr = s->range_table_list[chan];
} else {
lr = s->range_table;
}
- if (range >= lr->length) {
+ if (range >= lr->length)
return -EINVAL;
- }
- memcpy(krange, lr->range + range, sizeof(comedi_krange));
+
+ memcpy(krange, lr->range + range, sizeof(struct comedi_krange));
return 0;
}
@@ -171,11 +171,11 @@ int comedi_get_krange(comedi_t * d, unsigned int subdevice, unsigned int chan,
/*
* ALPHA (may be renamed)
*/
-unsigned int comedi_get_buf_head_pos(comedi_t * d, unsigned int subdevice)
+unsigned int comedi_get_buf_head_pos(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_async *async;
async = s->async;
if (async == NULL)
@@ -184,11 +184,11 @@ unsigned int comedi_get_buf_head_pos(comedi_t * d, unsigned int subdevice)
return async->buf_write_count;
}
-int comedi_get_buffer_contents(comedi_t * d, unsigned int subdevice)
+int comedi_get_buffer_contents(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_async *async;
unsigned int num_bytes;
if (subdevice >= dev->n_subdevices)
@@ -203,12 +203,12 @@ int comedi_get_buffer_contents(comedi_t * d, unsigned int subdevice)
/*
* ALPHA
*/
-int comedi_set_user_int_count(comedi_t * d, unsigned int subdevice,
+int comedi_set_user_int_count(void *d, unsigned int subdevice,
unsigned int buf_user_count)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_async *async;
int num_bytes;
async = s->async;
@@ -224,12 +224,12 @@ int comedi_set_user_int_count(comedi_t * d, unsigned int subdevice,
return 0;
}
-int comedi_mark_buffer_read(comedi_t * d, unsigned int subdevice,
+int comedi_mark_buffer_read(void *d, unsigned int subdevice,
unsigned int num_bytes)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_async *async;
if (subdevice >= dev->n_subdevices)
return -1;
@@ -243,12 +243,12 @@ int comedi_mark_buffer_read(comedi_t * d, unsigned int subdevice,
return 0;
}
-int comedi_mark_buffer_written(comedi_t * d, unsigned int subdevice,
+int comedi_mark_buffer_written(void *d, unsigned int subdevice,
unsigned int num_bytes)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_async *async;
int bytes_written;
if (subdevice >= dev->n_subdevices)
@@ -263,11 +263,11 @@ int comedi_mark_buffer_written(comedi_t * d, unsigned int subdevice,
return 0;
}
-int comedi_get_buffer_size(comedi_t * d, unsigned int subdev)
+int comedi_get_buffer_size(void *d, unsigned int subdev)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdev;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdev;
+ struct comedi_async *async;
if (subdev >= dev->n_subdevices)
return -1;
@@ -278,11 +278,11 @@ int comedi_get_buffer_size(comedi_t * d, unsigned int subdev)
return async->prealloc_bufsz;
}
-int comedi_get_buffer_offset(comedi_t * d, unsigned int subdevice)
+int comedi_get_buffer_offset(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_async *async;
if (subdevice >= dev->n_subdevices)
return -1;
diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
index 510fbdcec49..a4fa9571c58 100644
--- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
+++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
@@ -42,10 +42,10 @@ MODULE_AUTHOR("David Schleef <ds@schleef.org>");
MODULE_DESCRIPTION("Comedi kernel library");
MODULE_LICENSE("GPL");
-comedi_t *comedi_open(const char *filename)
+void *comedi_open(const char *filename)
{
struct comedi_device_file_info *dev_file_info;
- comedi_device *dev;
+ struct comedi_device *dev;
unsigned int minor;
if (strncmp(filename, "/dev/comedi", 11) != 0)
@@ -57,41 +57,41 @@ comedi_t *comedi_open(const char *filename)
return NULL;
dev_file_info = comedi_get_device_file_info(minor);
- if(dev_file_info == NULL)
+ if (dev_file_info == NULL)
return NULL;
dev = dev_file_info->device;
- if(dev == NULL || !dev->attached)
+ if (dev == NULL || !dev->attached)
return NULL;
if (!try_module_get(dev->driver->module))
return NULL;
- return (comedi_t *) dev;
+ return (void *) dev;
}
-comedi_t *comedi_open_old(unsigned int minor)
+void *comedi_open_old(unsigned int minor)
{
struct comedi_device_file_info *dev_file_info;
- comedi_device *dev;
+ struct comedi_device *dev;
if (minor >= COMEDI_NUM_MINORS)
return NULL;
dev_file_info = comedi_get_device_file_info(minor);
- if(dev_file_info == NULL)
+ if (dev_file_info == NULL)
return NULL;
dev = dev_file_info->device;
- if(dev == NULL || !dev->attached)
+ if (dev == NULL || !dev->attached)
return NULL;
- return (comedi_t *) dev;
+ return (void *) dev;
}
-int comedi_close(comedi_t * d)
+int comedi_close(void *d)
{
- comedi_device *dev = (comedi_device *) d;
+ struct comedi_device *dev = (struct comedi_device *) d;
module_put(dev->driver->module);
@@ -113,19 +113,19 @@ char *comedi_strerror(int err)
return "unknown error";
}
-int comedi_fileno(comedi_t * d)
+int comedi_fileno(void *d)
{
- comedi_device *dev = (comedi_device *) d;
+ struct comedi_device *dev = (struct comedi_device *) d;
/* return something random */
return dev->minor;
}
-int comedi_command(comedi_t * d, comedi_cmd * cmd)
+int comedi_command(void *d, struct comedi_cmd *cmd)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
unsigned runflags;
if (cmd->subdev >= dev->n_subdevices)
@@ -161,10 +161,10 @@ int comedi_command(comedi_t * d, comedi_cmd * cmd)
return s->do_cmd(dev, s);
}
-int comedi_command_test(comedi_t * d, comedi_cmd * cmd)
+int comedi_command_test(void *d, struct comedi_cmd *cmd)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
if (cmd->subdev >= dev->n_subdevices)
return -ENODEV;
@@ -183,10 +183,10 @@ int comedi_command_test(comedi_t * d, comedi_cmd * cmd)
* COMEDI_INSN
* perform an instruction
*/
-int comedi_do_insn(comedi_t * d, comedi_insn * insn)
+int comedi_do_insn(void *d, struct comedi_insn *insn)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
int ret = 0;
if (insn->insn & INSN_MASK_SPECIAL) {
@@ -256,7 +256,8 @@ int comedi_do_insn(comedi_t * d, comedi_insn * insn)
/* XXX check lock */
- if ((ret = check_chanlist(s, 1, &insn->chanspec)) < 0) {
+ ret = check_chanlist(s, 1, &insn->chanspec);
+ if (ret < 0) {
rt_printk("bad chanspec\n");
ret = -EINVAL;
goto error;
@@ -323,16 +324,16 @@ int comedi_do_insn(comedi_t * d, comedi_insn * insn)
- lock while subdevice being programmed
*/
-int comedi_lock(comedi_t * d, unsigned int subdevice)
+int comedi_lock(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
unsigned long flags;
int ret = 0;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
comedi_spin_lock_irqsave(&s->spin_lock, flags);
@@ -366,17 +367,17 @@ int comedi_lock(comedi_t * d, unsigned int subdevice)
none
*/
-int comedi_unlock(comedi_t * d, unsigned int subdevice)
+int comedi_unlock(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
unsigned long flags;
- comedi_async *async;
+ struct comedi_async *async;
int ret;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
async = s->async;
@@ -418,15 +419,15 @@ int comedi_unlock(comedi_t * d, unsigned int subdevice)
nothing
*/
-int comedi_cancel(comedi_t * d, unsigned int subdevice)
+int comedi_cancel(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
int ret = 0;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
if (s->lock && s->lock != d)
@@ -443,13 +444,15 @@ int comedi_cancel(comedi_t * d, unsigned int subdevice)
if (!s->cancel || !s->async)
return -EINVAL;
- if ((ret = s->cancel(dev, s)))
+ ret = s->cancel(dev, s);
+
+ if (ret)
return ret;
#ifdef CONFIG_COMEDI_RT
- if (comedi_get_subdevice_runflags(s) & SRF_RT) {
+ if (comedi_get_subdevice_runflags(s) & SRF_RT)
comedi_switch_to_non_rt(dev);
- }
+
#endif
comedi_set_subdevice_runflags(s, SRF_RUNNING | SRF_RT, 0);
s->async->inttrig = NULL;
@@ -461,16 +464,16 @@ int comedi_cancel(comedi_t * d, unsigned int subdevice)
/*
registration of callback functions
*/
-int comedi_register_callback(comedi_t * d, unsigned int subdevice,
+int comedi_register_callback(void *d, unsigned int subdevice,
unsigned int mask, int (*cb) (unsigned int, void *), void *arg)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
async = s->async;
@@ -498,15 +501,15 @@ int comedi_register_callback(comedi_t * d, unsigned int subdevice,
return 0;
}
-int comedi_poll(comedi_t * d, unsigned int subdevice)
+int comedi_poll(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices;
+ struct comedi_async *async;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
async = s->async;
@@ -525,22 +528,21 @@ int comedi_poll(comedi_t * d, unsigned int subdevice)
}
/* WARNING: not portable */
-int comedi_map(comedi_t * d, unsigned int subdevice, void *ptr)
+int comedi_map(void *d, unsigned int subdevice, void *ptr)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
if (!s->async)
return -EINVAL;
- if (ptr) {
+ if (ptr)
*((void **)ptr) = s->async->prealloc_buf;
- }
/* XXX no reference counting */
@@ -548,14 +550,14 @@ int comedi_map(comedi_t * d, unsigned int subdevice, void *ptr)
}
/* WARNING: not portable */
-int comedi_unmap(comedi_t * d, unsigned int subdevice)
+int comedi_unmap(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
if (!s->async)
diff --git a/drivers/staging/comedi/kcomedilib/ksyms.c b/drivers/staging/comedi/kcomedilib/ksyms.c
index 76b45063a9f..3db86dabf87 100644
--- a/drivers/staging/comedi/kcomedilib/ksyms.c
+++ b/drivers/staging/comedi/kcomedilib/ksyms.c
@@ -40,8 +40,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
-#if LINUX_VERSION_CODE >= 0x020200
-
/* functions specific to kcomedilib */
EXPORT_SYMBOL(comedi_register_callback);
@@ -140,5 +138,3 @@ EXPORT_SYMBOL(comedi_get_len_chanlist);
/* alpha */
//EXPORT_SYMBOL(comedi_set_global_oor_behavior);
-
-#endif
diff --git a/drivers/staging/comedi/pci_ids.h b/drivers/staging/comedi/pci_ids.h
index c61ba90f960..d979aa8e396 100644
--- a/drivers/staging/comedi/pci_ids.h
+++ b/drivers/staging/comedi/pci_ids.h
@@ -28,4 +28,4 @@
#define PCI_DEVICE_ID_QUANCOM_GPIB 0x3302
#endif
-#endif // __COMPAT_LINUX_PCI_IDS_H
+#endif /* __COMPAT_LINUX_PCI_IDS_H */
diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c
index 5a2b72d8757..36ae2cd92ad 100644
--- a/drivers/staging/comedi/proc.c
+++ b/drivers/staging/comedi/proc.c
@@ -31,12 +31,12 @@
#define __NO_VERSION__
#include "comedidev.h"
#include <linux/proc_fs.h>
-//#include <linux/string.h>
+/* #include <linux/string.h> */
int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
int *eof, void *data);
-extern comedi_driver *comedi_drivers;
+extern struct comedi_driver *comedi_drivers;
int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
int *eof, void *data)
@@ -44,7 +44,7 @@ int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
int i;
int devices_q = 0;
int l = 0;
- comedi_driver *driv;
+ struct comedi_driver *driv;
l += sprintf(buf + l,
"comedi version " COMEDI_RELEASE "\n"
@@ -53,9 +53,10 @@ int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(i);
- comedi_device *dev;
+ struct comedi_device *dev;
- if(dev_file_info == NULL) continue;
+ if (dev_file_info == NULL)
+ continue;
dev = dev_file_info->device;
if (dev->attached) {
@@ -66,9 +67,8 @@ int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
dev->board_name, dev->n_subdevices);
}
}
- if (!devices_q) {
+ if (!devices_q)
l += sprintf(buf + l, "no devices\n");
- }
for (driv = comedi_drivers; driv; driv = driv->next) {
l += sprintf(buf + l, "%s:\n", driv->driver_name);
@@ -77,9 +77,8 @@ int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
*(char **)((char *)driv->board_name +
i * driv->offset));
}
- if (!driv->num_names) {
+ if (!driv->num_names)
l += sprintf(buf + l, " %s\n", driv->driver_name);
- }
}
return l;
diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c
index 61dc3cd6a9f..ac200d929f3 100644
--- a/drivers/staging/comedi/range.c
+++ b/drivers/staging/comedi/range.c
@@ -24,12 +24,12 @@
#include "comedidev.h"
#include <asm/uaccess.h>
-const comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} };
-const comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} };
-const comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} };
-const comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} };
-const comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} };
-const comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none}} };
+const struct comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} };
+const struct comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} };
+const struct comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} };
+const struct comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} };
+const struct comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} };
+const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none}} };
/*
COMEDI_RANGEINFO
@@ -42,16 +42,16 @@ const comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none}} };
range info structure
writes:
- n comedi_krange structures to rangeinfo->range_ptr
+ n struct comedi_krange structures to rangeinfo->range_ptr
*/
-int do_rangeinfo_ioctl(comedi_device * dev, comedi_rangeinfo * arg)
+int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg)
{
- comedi_rangeinfo it;
+ struct comedi_rangeinfo it;
int subd, chan;
- const comedi_lrange *lr;
- comedi_subdevice *s;
+ const struct comedi_lrange *lr;
+ struct comedi_subdevice *s;
- if (copy_from_user(&it, arg, sizeof(comedi_rangeinfo)))
+ if (copy_from_user(&it, arg, sizeof(struct comedi_rangeinfo)))
return -EFAULT;
subd = (it.range_type >> 24) & 0xf;
chan = (it.range_type >> 16) & 0xff;
@@ -78,17 +78,17 @@ int do_rangeinfo_ioctl(comedi_device * dev, comedi_rangeinfo * arg)
}
if (copy_to_user(it.range_ptr, lr->range,
- sizeof(comedi_krange) * lr->length))
+ sizeof(struct comedi_krange) * lr->length))
return -EFAULT;
return 0;
}
-static int aref_invalid(comedi_subdevice * s, unsigned int chanspec)
+static int aref_invalid(struct comedi_subdevice *s, unsigned int chanspec)
{
unsigned int aref;
- // disable reporting invalid arefs... maybe someday
+ /* disable reporting invalid arefs... maybe someday */
return 0;
aref = CR_AREF(chanspec);
@@ -120,7 +120,7 @@ static int aref_invalid(comedi_subdevice * s, unsigned int chanspec)
This function checks each element in a channel/gain list to make
make sure it is valid.
*/
-int check_chanlist(comedi_subdevice * s, int n, unsigned int *chanlist)
+int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist)
{
int i;
int chan;
@@ -135,9 +135,8 @@ int check_chanlist(comedi_subdevice * s, int n, unsigned int *chanlist)
i, chanlist[i], s->n_chan,
s->range_table->length);
#if 0
- for (i = 0; i < n; i++) {
+ for (i = 0; i < n; i++)
printk("[%d]=0x%08x\n", i, chanlist[i]);
- }
#endif
return -EINVAL;
}
diff --git a/drivers/staging/comedi/rt.c b/drivers/staging/comedi/rt.c
index 385b81b94ac..e9f5777595a 100644
--- a/drivers/staging/comedi/rt.c
+++ b/drivers/staging/comedi/rt.c
@@ -57,7 +57,7 @@ struct comedi_irq_struct {
irqreturn_t(*handler) (int irq, void *dev_id PT_REGS_ARG);
unsigned long flags;
const char *device;
- comedi_device *dev_id;
+ struct comedi_device *dev_id;
};
static int comedi_rt_get_irq(struct comedi_irq_struct *it);
@@ -67,7 +67,7 @@ static struct comedi_irq_struct *comedi_irqs[NR_IRQS];
int comedi_request_irq(unsigned irq, irqreturn_t(*handler) (int,
void *PT_REGS_ARG), unsigned long flags, const char *device,
- comedi_device * dev_id)
+ struct comedi_device *dev_id)
{
struct comedi_irq_struct *it;
int ret;
@@ -78,15 +78,15 @@ int comedi_request_irq(unsigned irq, irqreturn_t(*handler) (int,
ret = request_irq(irq, handler, unshared_flags, device, dev_id);
if (ret < 0) {
- // we failed, so fall back on allowing shared interrupt (which we won't ever make RT)
+ /* we failed, so fall back on allowing shared interrupt (which we won't ever make RT) */
if (flags & IRQF_SHARED) {
rt_printk
("comedi: cannot get unshared interrupt, will not use RT interrupts.\n");
ret = request_irq(irq, handler, flags, device, dev_id);
}
- if (ret < 0) {
+ if (ret < 0)
return ret;
- }
+
} else {
it = kzalloc(sizeof(struct comedi_irq_struct), GFP_KERNEL);
if (!it)
@@ -102,7 +102,7 @@ int comedi_request_irq(unsigned irq, irqreturn_t(*handler) (int,
return 0;
}
-void comedi_free_irq(unsigned int irq, comedi_device * dev_id)
+void comedi_free_irq(unsigned int irq, struct comedi_device *dev_id)
{
struct comedi_irq_struct *it;
@@ -121,7 +121,7 @@ void comedi_free_irq(unsigned int irq, comedi_device * dev_id)
comedi_irqs[irq] = NULL;
}
-int comedi_switch_to_rt(comedi_device * dev)
+int comedi_switch_to_rt(struct comedi_device *dev)
{
struct comedi_irq_struct *it;
unsigned long flags;
@@ -145,7 +145,7 @@ int comedi_switch_to_rt(comedi_device * dev)
return 0;
}
-void comedi_switch_to_non_rt(comedi_device * dev)
+void comedi_switch_to_non_rt(struct comedi_device *dev)
{
struct comedi_irq_struct *it;
unsigned long flags;
@@ -170,7 +170,7 @@ void wake_up_int_handler(int arg1, void *arg2)
wake_up_interruptible((wait_queue_head_t *) arg2);
}
-void comedi_rt_pend_wakeup(wait_queue_head_t * q)
+void comedi_rt_pend_wakeup(wait_queue_head_t *q)
{
rt_pend_call(wake_up_int_handler, 0, q);
}
@@ -180,7 +180,7 @@ void comedi_rt_pend_wakeup(wait_queue_head_t * q)
#ifndef HAVE_RT_REQUEST_IRQ_WITH_ARG
#define DECLARE_VOID_IRQ(irq) \
-static void handle_void_irq_ ## irq (void){ handle_void_irq(irq);}
+static void handle_void_irq_ ## irq (void){ handle_void_irq(irq); }
static void handle_void_irq(int irq)
{
@@ -192,7 +192,7 @@ static void handle_void_irq(int irq)
return;
}
it->handler(irq, it->dev_id PT_REGS_NULL);
- rt_enable_irq(irq); //needed by rtai-adeos, seems like it shouldn't hurt earlier versions
+ rt_enable_irq(irq); /* needed by rtai-adeos, seems like it shouldn't hurt earlier versions */
}
DECLARE_VOID_IRQ(0);
@@ -220,8 +220,7 @@ DECLARE_VOID_IRQ(21);
DECLARE_VOID_IRQ(22);
DECLARE_VOID_IRQ(23);
-typedef void (*V_FP_V) (void);
-static V_FP_V handle_void_irq_ptrs[] = {
+static void handle_void_irq_ptrs[] = {
handle_void_irq_0,
handle_void_irq_1,
handle_void_irq_2,
@@ -402,11 +401,11 @@ static int comedi_rt_release_irq(struct comedi_irq_struct *it)
void comedi_rt_init(void)
{
- //rt_pend_tq_init();
+ /* rt_pend_tq_init(); */
}
void comedi_rt_cleanup(void)
{
- //rt_pend_tq_cleanup();
+ /* rt_pend_tq_cleanup(); */
}
#endif
diff --git a/drivers/staging/comedi/rt_pend_tq.c b/drivers/staging/comedi/rt_pend_tq.c
index 995f076e0af..f9dfd9d40cd 100644
--- a/drivers/staging/comedi/rt_pend_tq.c
+++ b/drivers/staging/comedi/rt_pend_tq.c
@@ -3,7 +3,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/sched.h>
-#include "comedidev.h" // for rt spinlocks
+#include "comedidev.h" /* for rt spinlocks */
#include "rt_pend_tq.h"
#ifdef CONFIG_COMEDI_RTAI
#include <rtai.h>
@@ -25,9 +25,9 @@ volatile static struct rt_pend_tq rt_pend_tq[RT_PEND_TQ_SIZE];
volatile static struct rt_pend_tq *volatile rt_pend_head = rt_pend_tq,
*volatile rt_pend_tail = rt_pend_tq;
int rt_pend_tq_irq = 0;
-spinlock_t rt_pend_tq_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rt_pend_tq_lock);
-// WARNING: following code not checked against race conditions yet.
+/* WARNING: following code not checked against race conditions yet. */
#define INC_CIRCULAR_PTR(ptr,begin,size) do {if(++(ptr)>=(begin)+(size)) (ptr)=(begin); } while(0)
#define DEC_CIRCULAR_PTR(ptr,begin,size) do {if(--(ptr)<(begin)) (ptr)=(begin)+(size)-1; } while(0)
@@ -42,7 +42,7 @@ int rt_pend_call(void (*func) (int arg1, void *arg2), int arg1, void *arg2)
comedi_spin_lock_irqsave(&rt_pend_tq_lock, flags);
INC_CIRCULAR_PTR(rt_pend_head, rt_pend_tq, RT_PEND_TQ_SIZE);
if (rt_pend_head == rt_pend_tail) {
- // overflow, we just refuse to take this request
+ /* overflow, we just refuse to take this request */
DEC_CIRCULAR_PTR(rt_pend_head, rt_pend_tq, RT_PEND_TQ_SIZE);
comedi_spin_unlock_irqrestore(&rt_pend_tq_lock, flags);
return -EAGAIN;
diff --git a/drivers/staging/dst/Kconfig b/drivers/staging/dst/Kconfig
new file mode 100644
index 00000000000..448d342ac2a
--- /dev/null
+++ b/drivers/staging/dst/Kconfig
@@ -0,0 +1,67 @@
+config DST
+ tristate "Distributed storage"
+ depends on NET && CRYPTO && SYSFS && BLK_DEV
+ select CONNECTOR
+ ---help---
+ DST is a network block device storage, which can be used to organize
+ exported storage on the remote nodes into the local block device.
+
+ DST works on top of any network media and protocol; it is just a matter
+ of configuration utility to understand the correct addresses. The most
+ common example is TCP over IP, which allows to pass through firewalls and
+ create remote backup storage in a different datacenter. DST requires
+ single port to be enabled on the exporting node and outgoing connections
+ on the local node.
+
+ DST works with in-kernel client and server, which improves performance by
+ eliminating unneded data copies and by not depending on the version
+ of the external IO components. It requires userspace configuration utility
+ though.
+
+ DST uses transaction model, when each store has to be explicitly acked
+ from the remote node to be considered as successfully written. There
+ may be lots of in-flight transactions. When remote host does not ack
+ the transaction it will be resent predefined number of times with specified
+ timeouts between them. All those parameters are configurable. Transactions
+ are marked as failed after all resends complete unsuccessfully; having
+ long enough resend timeout and/or large number of resends allows not to
+ return error to the higher (FS usually) layer in case of short network
+ problems or remote node outages. In case of network RAID setup this means
+ that storage will not degrade until transactions are marked as failed, and
+ thus will not force checksum recalculation and data rebuild. In case of
+ connection failure DST will try to reconnect to the remote node automatically.
+ DST sends ping commands at idle time to detect if remote node is alive.
+
+ Because of transactional model it is possible to use zero-copy sending
+ without worry of data corruption (which in turn could be detected by the
+ strong checksums though).
+
+ DST may fully encrypt the data channel in case of untrusted channel and implement
+ strong checksum of the transferred data. It is possible to configure algorithms
+ and crypto keys; they should match on both sides of the network channel.
+ Crypto processing does not introduce noticeble performance overhead, since DST
+ uses configurable pool of threads to perform crypto processing.
+
+ DST utilizes memory pool model of all its transaction allocations (it is the
+ only additional allocation on the client) and server allocations (bio pools,
+ while pages are allocated from the slab).
+
+ At startup DST performs a simple negotiation with the export node to determine
+ access permissions and size of the exported storage. It can be extended if
+ new parameters should be autonegotiated.
+
+ DST carries block IO flags in the protocol, which allows to transparently implement
+ barriers and sync/flush operations. Those flags are used in the export node where
+ IO against the local storage is performed, which means that sync write will be sync
+ on the remote node too, which in turn improves data integrity and improved resistance
+ to errors and data corruption during power outages or storage damages.
+
+ Homepage: http://www.ioremap.net/projects/dst
+ Userspace configuration utility and the latest releases: http://www.ioremap.net/archive/dst/
+
+config DST_DEBUG
+ bool "DST debug"
+ depends on DST
+ ---help---
+ This option will enable HEAVY debugging of the DST.
+ Turn it on ONLY if you have to debug some really obscure problem.
diff --git a/drivers/staging/dst/Makefile b/drivers/staging/dst/Makefile
new file mode 100644
index 00000000000..3a8b0cf9643
--- /dev/null
+++ b/drivers/staging/dst/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DST) += nst.o
+
+nst-y := dcore.o state.o export.o thread_pool.o crypto.o trans.o
diff --git a/drivers/staging/dst/crypto.c b/drivers/staging/dst/crypto.c
new file mode 100644
index 00000000000..7250f90f592
--- /dev/null
+++ b/drivers/staging/dst/crypto.c
@@ -0,0 +1,731 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/bio.h>
+#include <linux/crypto.h>
+#include <linux/dst.h>
+#include <linux/kernel.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+
+/*
+ * Tricky bastard, but IV can be more complex with time...
+ */
+static inline u64 dst_gen_iv(struct dst_trans *t)
+{
+ return t->gen;
+}
+
+/*
+ * Crypto machinery: hash/cipher support for the given crypto controls.
+ */
+static struct crypto_hash *dst_init_hash(struct dst_crypto_ctl *ctl, u8 *key)
+{
+ int err;
+ struct crypto_hash *hash;
+
+ hash = crypto_alloc_hash(ctl->hash_algo, 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(hash)) {
+ err = PTR_ERR(hash);
+ dprintk("%s: failed to allocate hash '%s', err: %d.\n",
+ __func__, ctl->hash_algo, err);
+ goto err_out_exit;
+ }
+
+ ctl->crypto_attached_size = crypto_hash_digestsize(hash);
+
+ if (!ctl->hash_keysize)
+ return hash;
+
+ err = crypto_hash_setkey(hash, key, ctl->hash_keysize);
+ if (err) {
+ dprintk("%s: failed to set key for hash '%s', err: %d.\n",
+ __func__, ctl->hash_algo, err);
+ goto err_out_free;
+ }
+
+ return hash;
+
+err_out_free:
+ crypto_free_hash(hash);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+static struct crypto_ablkcipher *dst_init_cipher(struct dst_crypto_ctl *ctl, u8 *key)
+{
+ int err = -EINVAL;
+ struct crypto_ablkcipher *cipher;
+
+ if (!ctl->cipher_keysize)
+ goto err_out_exit;
+
+ cipher = crypto_alloc_ablkcipher(ctl->cipher_algo, 0, 0);
+ if (IS_ERR(cipher)) {
+ err = PTR_ERR(cipher);
+ dprintk("%s: failed to allocate cipher '%s', err: %d.\n",
+ __func__, ctl->cipher_algo, err);
+ goto err_out_exit;
+ }
+
+ crypto_ablkcipher_clear_flags(cipher, ~0);
+
+ err = crypto_ablkcipher_setkey(cipher, key, ctl->cipher_keysize);
+ if (err) {
+ dprintk("%s: failed to set key for cipher '%s', err: %d.\n",
+ __func__, ctl->cipher_algo, err);
+ goto err_out_free;
+ }
+
+ return cipher;
+
+err_out_free:
+ crypto_free_ablkcipher(cipher);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+/*
+ * Crypto engine has a pool of pages to encrypt data into before sending
+ * it over the network. This pool is freed/allocated here.
+ */
+static void dst_crypto_pages_free(struct dst_crypto_engine *e)
+{
+ unsigned int i;
+
+ for (i=0; i<e->page_num; ++i)
+ __free_page(e->pages[i]);
+ kfree(e->pages);
+}
+
+static int dst_crypto_pages_alloc(struct dst_crypto_engine *e, int num)
+{
+ int i;
+
+ e->pages = kmalloc(num * sizeof(struct page **), GFP_KERNEL);
+ if (!e->pages)
+ return -ENOMEM;
+
+ for (i=0; i<num; ++i) {
+ e->pages[i] = alloc_page(GFP_KERNEL);
+ if (!e->pages[i])
+ goto err_out_free_pages;
+ }
+
+ e->page_num = num;
+ return 0;
+
+err_out_free_pages:
+ while (--i >= 0)
+ __free_page(e->pages[i]);
+
+ kfree(e->pages);
+ return -ENOMEM;
+}
+
+/*
+ * Initialize crypto engine for given node.
+ * Setup cipher/hash, keys, pool of threads and private data.
+ */
+static int dst_crypto_engine_init(struct dst_crypto_engine *e, struct dst_node *n)
+{
+ int err;
+ struct dst_crypto_ctl *ctl = &n->crypto;
+
+ err = dst_crypto_pages_alloc(e, n->max_pages);
+ if (err)
+ goto err_out_exit;
+
+ e->size = PAGE_SIZE;
+ e->data = kmalloc(e->size, GFP_KERNEL);
+ if (!e->data) {
+ err = -ENOMEM;
+ goto err_out_free_pages;
+ }
+
+ if (ctl->hash_algo[0]) {
+ e->hash = dst_init_hash(ctl, n->hash_key);
+ if (IS_ERR(e->hash)) {
+ err = PTR_ERR(e->hash);
+ e->hash = NULL;
+ goto err_out_free;
+ }
+ }
+
+ if (ctl->cipher_algo[0]) {
+ e->cipher = dst_init_cipher(ctl, n->cipher_key);
+ if (IS_ERR(e->cipher)) {
+ err = PTR_ERR(e->cipher);
+ e->cipher = NULL;
+ goto err_out_free_hash;
+ }
+ }
+
+ return 0;
+
+err_out_free_hash:
+ crypto_free_hash(e->hash);
+err_out_free:
+ kfree(e->data);
+err_out_free_pages:
+ dst_crypto_pages_free(e);
+err_out_exit:
+ return err;
+}
+
+static void dst_crypto_engine_exit(struct dst_crypto_engine *e)
+{
+ if (e->hash)
+ crypto_free_hash(e->hash);
+ if (e->cipher)
+ crypto_free_ablkcipher(e->cipher);
+ dst_crypto_pages_free(e);
+ kfree(e->data);
+}
+
+/*
+ * Waiting for cipher processing to be completed.
+ */
+struct dst_crypto_completion
+{
+ struct completion complete;
+ int error;
+};
+
+static void dst_crypto_complete(struct crypto_async_request *req, int err)
+{
+ struct dst_crypto_completion *c = req->data;
+
+ if (err == -EINPROGRESS)
+ return;
+
+ dprintk("%s: req: %p, err: %d.\n", __func__, req, err);
+ c->error = err;
+ complete(&c->complete);
+}
+
+static int dst_crypto_process(struct ablkcipher_request *req,
+ struct scatterlist *sg_dst, struct scatterlist *sg_src,
+ void *iv, int enc, unsigned long timeout)
+{
+ struct dst_crypto_completion c;
+ int err;
+
+ init_completion(&c.complete);
+ c.error = -EINPROGRESS;
+
+ ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ dst_crypto_complete, &c);
+
+ ablkcipher_request_set_crypt(req, sg_src, sg_dst, sg_src->length, iv);
+
+ if (enc)
+ err = crypto_ablkcipher_encrypt(req);
+ else
+ err = crypto_ablkcipher_decrypt(req);
+
+ switch (err) {
+ case -EINPROGRESS:
+ case -EBUSY:
+ err = wait_for_completion_interruptible_timeout(&c.complete,
+ timeout);
+ if (!err)
+ err = -ETIMEDOUT;
+ else
+ err = c.error;
+ break;
+ default:
+ break;
+ }
+
+ return err;
+}
+
+/*
+ * DST uses generic iteration approach for data crypto processing.
+ * Single block IO request is switched into array of scatterlists,
+ * which are submitted to the crypto processing iterator.
+ *
+ * Input and output iterator initialization are different, since
+ * in output case we can not encrypt data in-place and need a
+ * temporary storage, which is then being sent to the remote peer.
+ */
+static int dst_trans_iter_out(struct bio *bio, struct dst_crypto_engine *e,
+ int (* iterator) (struct dst_crypto_engine *e,
+ struct scatterlist *dst,
+ struct scatterlist *src))
+{
+ struct bio_vec *bv;
+ int err, i;
+
+ sg_init_table(e->src, bio->bi_vcnt);
+ sg_init_table(e->dst, bio->bi_vcnt);
+
+ bio_for_each_segment(bv, bio, i) {
+ sg_set_page(&e->src[i], bv->bv_page, bv->bv_len, bv->bv_offset);
+ sg_set_page(&e->dst[i], e->pages[i], bv->bv_len, bv->bv_offset);
+
+ err = iterator(e, &e->dst[i], &e->src[i]);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int dst_trans_iter_in(struct bio *bio, struct dst_crypto_engine *e,
+ int (* iterator) (struct dst_crypto_engine *e,
+ struct scatterlist *dst,
+ struct scatterlist *src))
+{
+ struct bio_vec *bv;
+ int err, i;
+
+ sg_init_table(e->src, bio->bi_vcnt);
+ sg_init_table(e->dst, bio->bi_vcnt);
+
+ bio_for_each_segment(bv, bio, i) {
+ sg_set_page(&e->src[i], bv->bv_page, bv->bv_len, bv->bv_offset);
+ sg_set_page(&e->dst[i], bv->bv_page, bv->bv_len, bv->bv_offset);
+
+ err = iterator(e, &e->dst[i], &e->src[i]);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int dst_crypt_iterator(struct dst_crypto_engine *e,
+ struct scatterlist *sg_dst, struct scatterlist *sg_src)
+{
+ struct ablkcipher_request *req = e->data;
+ u8 iv[32];
+
+ memset(iv, 0, sizeof(iv));
+
+ memcpy(iv, &e->iv, sizeof(e->iv));
+
+ return dst_crypto_process(req, sg_dst, sg_src, iv, e->enc, e->timeout);
+}
+
+static int dst_crypt(struct dst_crypto_engine *e, struct bio *bio)
+{
+ struct ablkcipher_request *req = e->data;
+
+ memset(req, 0, sizeof(struct ablkcipher_request));
+ ablkcipher_request_set_tfm(req, e->cipher);
+
+ if (e->enc)
+ return dst_trans_iter_out(bio, e, dst_crypt_iterator);
+ else
+ return dst_trans_iter_in(bio, e, dst_crypt_iterator);
+}
+
+static int dst_hash_iterator(struct dst_crypto_engine *e,
+ struct scatterlist *sg_dst, struct scatterlist *sg_src)
+{
+ return crypto_hash_update(e->data, sg_src, sg_src->length);
+}
+
+static int dst_hash(struct dst_crypto_engine *e, struct bio *bio, void *dst)
+{
+ struct hash_desc *desc = e->data;
+ int err;
+
+ desc->tfm = e->hash;
+ desc->flags = 0;
+
+ err = crypto_hash_init(desc);
+ if (err)
+ return err;
+
+ err = dst_trans_iter_in(bio, e, dst_hash_iterator);
+ if (err)
+ return err;
+
+ err = crypto_hash_final(desc, dst);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+/*
+ * Initialize/cleanup a crypto thread. The only thing it should
+ * do is to allocate a pool of pages as temporary storage.
+ * And to setup cipher and/or hash.
+ */
+static void *dst_crypto_thread_init(void *data)
+{
+ struct dst_node *n = data;
+ struct dst_crypto_engine *e;
+ int err = -ENOMEM;
+
+ e = kzalloc(sizeof(struct dst_crypto_engine), GFP_KERNEL);
+ if (!e)
+ goto err_out_exit;
+ e->src = kcalloc(2 * n->max_pages, sizeof(struct scatterlist),
+ GFP_KERNEL);
+ if (!e->src)
+ goto err_out_free;
+
+ e->dst = e->src + n->max_pages;
+
+ err = dst_crypto_engine_init(e, n);
+ if (err)
+ goto err_out_free_all;
+
+ return e;
+
+err_out_free_all:
+ kfree(e->src);
+err_out_free:
+ kfree(e);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+static void dst_crypto_thread_cleanup(void *private)
+{
+ struct dst_crypto_engine *e = private;
+
+ dst_crypto_engine_exit(e);
+ kfree(e->src);
+ kfree(e);
+}
+
+/*
+ * Initialize crypto engine for given node: store keys, create pool
+ * of threads, initialize each one.
+ *
+ * Each thread has unique ID, but 0 and 1 are reserved for receiving and accepting
+ * threads (if export node), so IDs could start from 2, but starting them
+ * from 10 allows easily understand what this thread is for.
+ */
+int dst_node_crypto_init(struct dst_node *n, struct dst_crypto_ctl *ctl)
+{
+ void *key = (ctl + 1);
+ int err = -ENOMEM, i;
+ char name[32];
+
+ if (ctl->hash_keysize) {
+ n->hash_key = kmalloc(ctl->hash_keysize, GFP_KERNEL);
+ if (!n->hash_key)
+ goto err_out_exit;
+ memcpy(n->hash_key, key, ctl->hash_keysize);
+ }
+
+ if (ctl->cipher_keysize) {
+ n->cipher_key = kmalloc(ctl->cipher_keysize, GFP_KERNEL);
+ if (!n->cipher_key)
+ goto err_out_free_hash;
+ memcpy(n->cipher_key, key, ctl->cipher_keysize);
+ }
+ memcpy(&n->crypto, ctl, sizeof(struct dst_crypto_ctl));
+
+ for (i=0; i<ctl->thread_num; ++i) {
+ snprintf(name, sizeof(name), "%s-crypto-%d", n->name, i);
+ /* Unique ids... */
+ err = thread_pool_add_worker(n->pool, name, i+10,
+ dst_crypto_thread_init, dst_crypto_thread_cleanup, n);
+ if (err)
+ goto err_out_free_threads;
+ }
+
+ return 0;
+
+err_out_free_threads:
+ while (--i >= 0)
+ thread_pool_del_worker_id(n->pool, i+10);
+
+ if (ctl->cipher_keysize)
+ kfree(n->cipher_key);
+ ctl->cipher_keysize = 0;
+err_out_free_hash:
+ if (ctl->hash_keysize)
+ kfree(n->hash_key);
+ ctl->hash_keysize = 0;
+err_out_exit:
+ return err;
+}
+
+void dst_node_crypto_exit(struct dst_node *n)
+{
+ struct dst_crypto_ctl *ctl = &n->crypto;
+
+ if (ctl->cipher_algo[0] || ctl->hash_algo[0]) {
+ kfree(n->hash_key);
+ kfree(n->cipher_key);
+ }
+}
+
+/*
+ * Thrad pool setup callback. Just stores a transaction in private data.
+ */
+static int dst_trans_crypto_setup(void *crypto_engine, void *trans)
+{
+ struct dst_crypto_engine *e = crypto_engine;
+
+ e->private = trans;
+ return 0;
+}
+
+#if 0
+static void dst_dump_bio(struct bio *bio)
+{
+ u8 *p;
+ struct bio_vec *bv;
+ int i;
+
+ bio_for_each_segment(bv, bio, i) {
+ dprintk("%s: %llu/%u: size: %u, offset: %u, data: ",
+ __func__, bio->bi_sector, bio->bi_size,
+ bv->bv_len, bv->bv_offset);
+
+ p = kmap(bv->bv_page) + bv->bv_offset;
+ for (i=0; i<bv->bv_len; ++i)
+ printk("%02x ", p[i]);
+ kunmap(bv->bv_page);
+ printk("\n");
+ }
+}
+#endif
+
+/*
+ * Encrypt/hash data and send it to the network.
+ */
+static int dst_crypto_process_sending(struct dst_crypto_engine *e,
+ struct bio *bio, u8 *hash)
+{
+ int err;
+
+ if (e->cipher) {
+ err = dst_crypt(e, bio);
+ if (err)
+ goto err_out_exit;
+ }
+
+ if (e->hash) {
+ err = dst_hash(e, bio, hash);
+ if (err)
+ goto err_out_exit;
+
+#ifdef CONFIG_DST_DEBUG
+ {
+ unsigned int i;
+
+ /* dst_dump_bio(bio); */
+
+ printk(KERN_DEBUG "%s: bio: %llu/%u, rw: %lu, hash: ",
+ __func__, (u64)bio->bi_sector,
+ bio->bi_size, bio_data_dir(bio));
+ for (i=0; i<crypto_hash_digestsize(e->hash); ++i)
+ printk("%02x ", hash[i]);
+ printk("\n");
+ }
+#endif
+ }
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+/*
+ * Check if received data is valid. Decipher if it is.
+ */
+static int dst_crypto_process_receiving(struct dst_crypto_engine *e,
+ struct bio *bio, u8 *hash, u8 *recv_hash)
+{
+ int err;
+
+ if (e->hash) {
+ int mismatch;
+
+ err = dst_hash(e, bio, hash);
+ if (err)
+ goto err_out_exit;
+
+ mismatch = !!memcmp(recv_hash, hash,
+ crypto_hash_digestsize(e->hash));
+#ifdef CONFIG_DST_DEBUG
+ /* dst_dump_bio(bio); */
+
+ printk(KERN_DEBUG "%s: bio: %llu/%u, rw: %lu, hash mismatch: %d",
+ __func__, (u64)bio->bi_sector, bio->bi_size,
+ bio_data_dir(bio), mismatch);
+ if (mismatch) {
+ unsigned int i;
+
+ printk(", recv/calc: ");
+ for (i=0; i<crypto_hash_digestsize(e->hash); ++i) {
+ printk("%02x/%02x ", recv_hash[i], hash[i]);
+ }
+ }
+ printk("\n");
+#endif
+ err = -1;
+ if (mismatch)
+ goto err_out_exit;
+ }
+
+ if (e->cipher) {
+ err = dst_crypt(e, bio);
+ if (err)
+ goto err_out_exit;
+ }
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+/*
+ * Thread pool callback to encrypt data and send it to the netowork.
+ */
+static int dst_trans_crypto_action(void *crypto_engine, void *schedule_data)
+{
+ struct dst_crypto_engine *e = crypto_engine;
+ struct dst_trans *t = schedule_data;
+ struct bio *bio = t->bio;
+ int err;
+
+ dprintk("%s: t: %p, gen: %llu, cipher: %p, hash: %p.\n",
+ __func__, t, t->gen, e->cipher, e->hash);
+
+ e->enc = t->enc;
+ e->iv = dst_gen_iv(t);
+
+ if (bio_data_dir(bio) == WRITE) {
+ err = dst_crypto_process_sending(e, bio, t->cmd.hash);
+ if (err)
+ goto err_out_exit;
+
+ if (e->hash) {
+ t->cmd.csize = crypto_hash_digestsize(e->hash);
+ t->cmd.size += t->cmd.csize;
+ }
+
+ return dst_trans_send(t);
+ } else {
+ u8 *hash = e->data + e->size/2;
+
+ err = dst_crypto_process_receiving(e, bio, hash, t->cmd.hash);
+ if (err)
+ goto err_out_exit;
+
+ dst_trans_remove(t);
+ dst_trans_put(t);
+ }
+
+ return 0;
+
+err_out_exit:
+ t->error = err;
+ dst_trans_put(t);
+ return err;
+}
+
+/*
+ * Schedule crypto processing for given transaction.
+ */
+int dst_trans_crypto(struct dst_trans *t)
+{
+ struct dst_node *n = t->n;
+ int err;
+
+ err = thread_pool_schedule(n->pool,
+ dst_trans_crypto_setup, dst_trans_crypto_action,
+ t, MAX_SCHEDULE_TIMEOUT);
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ dst_trans_put(t);
+ return err;
+}
+
+/*
+ * Crypto machinery for the export node.
+ */
+static int dst_export_crypto_setup(void *crypto_engine, void *bio)
+{
+ struct dst_crypto_engine *e = crypto_engine;
+
+ e->private = bio;
+ return 0;
+}
+
+static int dst_export_crypto_action(void *crypto_engine, void *schedule_data)
+{
+ struct dst_crypto_engine *e = crypto_engine;
+ struct bio *bio = schedule_data;
+ struct dst_export_priv *p = bio->bi_private;
+ int err;
+
+ dprintk("%s: e: %p, data: %p, bio: %llu/%u, dir: %lu.\n", __func__,
+ e, e->data, (u64)bio->bi_sector, bio->bi_size, bio_data_dir(bio));
+
+ e->enc = (bio_data_dir(bio) == READ);
+ e->iv = p->cmd.id;
+
+ if (bio_data_dir(bio) == WRITE) {
+ u8 *hash = e->data + e->size/2;
+
+ err = dst_crypto_process_receiving(e, bio, hash, p->cmd.hash);
+ if (err)
+ goto err_out_exit;
+
+ generic_make_request(bio);
+ } else {
+ err = dst_crypto_process_sending(e, bio, p->cmd.hash);
+ if (err)
+ goto err_out_exit;
+
+ if (e->hash) {
+ p->cmd.csize = crypto_hash_digestsize(e->hash);
+ p->cmd.size += p->cmd.csize;
+ }
+
+ err = dst_export_send_bio(bio);
+ }
+ return 0;
+
+err_out_exit:
+ bio_put(bio);
+ return err;
+}
+
+int dst_export_crypto(struct dst_node *n, struct bio *bio)
+{
+ int err;
+
+ err = thread_pool_schedule(n->pool,
+ dst_export_crypto_setup, dst_export_crypto_action,
+ bio, MAX_SCHEDULE_TIMEOUT);
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ bio_put(bio);
+ return err;
+}
diff --git a/drivers/staging/dst/dcore.c b/drivers/staging/dst/dcore.c
new file mode 100644
index 00000000000..fad25b75304
--- /dev/null
+++ b/drivers/staging/dst/dcore.c
@@ -0,0 +1,995 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/blkdev.h>
+#include <linux/bio.h>
+#include <linux/buffer_head.h>
+#include <linux/connector.h>
+#include <linux/dst.h>
+#include <linux/device.h>
+#include <linux/jhash.h>
+#include <linux/idr.h>
+#include <linux/init.h>
+#include <linux/namei.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+
+#include <linux/in.h>
+#include <linux/in6.h>
+
+#include <net/sock.h>
+
+static int dst_major;
+
+static DEFINE_MUTEX(dst_hash_lock);
+static struct list_head *dst_hashtable;
+static unsigned int dst_hashtable_size = 128;
+module_param(dst_hashtable_size, uint, 0644);
+
+static char dst_name[] = "Dementianting goldfish";
+
+static DEFINE_IDR(dst_index_idr);
+static struct cb_id cn_dst_id = { CN_DST_IDX, CN_DST_VAL };
+
+/*
+ * DST sysfs tree for device called 'storage':
+ *
+ * /sys/bus/dst/devices/storage/
+ * /sys/bus/dst/devices/storage/type : 192.168.4.80:1025
+ * /sys/bus/dst/devices/storage/size : 800
+ * /sys/bus/dst/devices/storage/name : storage
+ */
+
+static int dst_dev_match(struct device *dev, struct device_driver *drv)
+{
+ return 1;
+}
+
+static struct bus_type dst_dev_bus_type = {
+ .name = "dst",
+ .match = &dst_dev_match,
+};
+
+static void dst_node_release(struct device *dev)
+{
+ struct dst_info *info = container_of(dev, struct dst_info, device);
+
+ kfree(info);
+}
+
+static struct device dst_node_dev = {
+ .bus = &dst_dev_bus_type,
+ .release = &dst_node_release
+};
+
+/*
+ * Setting size of the node after it was changed.
+ */
+static void dst_node_set_size(struct dst_node *n)
+{
+ struct block_device *bdev;
+
+ set_capacity(n->disk, n->size >> 9);
+
+ bdev = bdget_disk(n->disk, 0);
+ if (bdev) {
+ mutex_lock(&bdev->bd_inode->i_mutex);
+ i_size_write(bdev->bd_inode, n->size);
+ mutex_unlock(&bdev->bd_inode->i_mutex);
+ bdput(bdev);
+ }
+}
+
+/*
+ * Distributed storage request processing function.
+ */
+static int dst_request(struct request_queue *q, struct bio *bio)
+{
+ struct dst_node *n = q->queuedata;
+ int err = -EIO;
+
+ if (bio_empty_barrier(bio) && !q->prepare_discard_fn) {
+ /*
+ * This is a dirty^Wnice hack, but if we complete this
+ * operation with -EOPNOTSUPP like intended, XFS
+ * will stuck and freeze the machine. This may be
+ * not particulary XFS problem though, but it is the
+ * only FS which sends empty barrier at umount time
+ * I worked with.
+ *
+ * Empty barriers are not allowed anyway, see 51fd77bd9f512
+ * for example, although later it was changed to bio_discard()
+ * only, which does not work in this case.
+ */
+ //err = -EOPNOTSUPP;
+ err = 0;
+ goto end_io;
+ }
+
+ bio_get(bio);
+
+ return dst_process_bio(n, bio);
+
+end_io:
+ bio_endio(bio, err);
+ return err;
+}
+
+/*
+ * Open/close callbacks for appropriate block device.
+ */
+static int dst_bdev_open(struct block_device *bdev, fmode_t mode)
+{
+ struct dst_node *n = bdev->bd_disk->private_data;
+
+ dst_node_get(n);
+ return 0;
+}
+
+static int dst_bdev_release(struct gendisk *disk, fmode_t mode)
+{
+ struct dst_node *n = disk->private_data;
+
+ dst_node_put(n);
+ return 0;
+}
+
+static struct block_device_operations dst_blk_ops = {
+ .open = dst_bdev_open,
+ .release = dst_bdev_release,
+ .owner = THIS_MODULE,
+};
+
+/*
+ * Block layer binding - disk is created when array is fully configured
+ * by userspace request.
+ */
+static int dst_node_create_disk(struct dst_node *n)
+{
+ int err = -ENOMEM;
+ u32 index = 0;
+
+ n->queue = blk_init_queue(NULL, NULL);
+ if (!n->queue)
+ goto err_out_exit;
+
+ n->queue->queuedata = n;
+ blk_queue_make_request(n->queue, dst_request);
+ blk_queue_max_phys_segments(n->queue, n->max_pages);
+ blk_queue_max_hw_segments(n->queue, n->max_pages);
+
+ err = -ENOMEM;
+ n->disk = alloc_disk(1);
+ if (!n->disk)
+ goto err_out_free_queue;
+
+ if (!(n->state->permissions & DST_PERM_WRITE)) {
+ printk(KERN_INFO "DST node %s attached read-only.\n", n->name);
+ set_disk_ro(n->disk, 1);
+ }
+
+ if (!idr_pre_get(&dst_index_idr, GFP_KERNEL))
+ goto err_out_put;
+
+ mutex_lock(&dst_hash_lock);
+ err = idr_get_new(&dst_index_idr, NULL, &index);
+ mutex_unlock(&dst_hash_lock);
+ if (err)
+ goto err_out_put;
+
+ n->disk->major = dst_major;
+ n->disk->first_minor = index;
+ n->disk->fops = &dst_blk_ops;
+ n->disk->queue = n->queue;
+ n->disk->private_data = n;
+ snprintf(n->disk->disk_name, sizeof(n->disk->disk_name), "dst-%s", n->name);
+
+ return 0;
+
+err_out_put:
+ put_disk(n->disk);
+err_out_free_queue:
+ blk_cleanup_queue(n->queue);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Sysfs machinery: show device's size.
+ */
+static ssize_t dst_show_size(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct dst_info *info = container_of(dev, struct dst_info, device);
+
+ return sprintf(buf, "%llu\n", info->size);
+}
+
+/*
+ * Show local exported device.
+ */
+static ssize_t dst_show_local(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct dst_info *info = container_of(dev, struct dst_info, device);
+
+ return sprintf(buf, "%s\n", info->local);
+}
+
+/*
+ * Shows type of the remote node - device major/minor number
+ * for local nodes and address (af_inet ipv4/ipv6 only) for remote nodes.
+ */
+static ssize_t dst_show_type(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct dst_info *info = container_of(dev, struct dst_info, device);
+ int family = info->net.addr.sa_family;
+
+ if (family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)&info->net.addr;
+ return sprintf(buf, "%u.%u.%u.%u:%d\n",
+ NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+ } else if (family == AF_INET6) {
+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&info->net.addr;
+ return sprintf(buf,
+ "%pi6:%d\n",
+ &sin->sin6_addr, ntohs(sin->sin6_port));
+ } else {
+ int i, sz = PAGE_SIZE - 2; /* 0 symbol and '\n' below */
+ int size, addrlen = info->net.addr.sa_data_len;
+ unsigned char *a = (unsigned char *)&info->net.addr.sa_data;
+ char *buf_orig = buf;
+
+ size = snprintf(buf, sz, "family: %d, addrlen: %u, addr: ",
+ family, addrlen);
+ sz -= size;
+ buf += size;
+
+ for (i=0; i<addrlen; ++i) {
+ if (sz < 3)
+ break;
+
+ size = snprintf(buf, sz, "%02x ", a[i]);
+ sz -= size;
+ buf += size;
+ }
+ buf += sprintf(buf, "\n");
+
+ return buf - buf_orig;
+ }
+ return 0;
+}
+
+static struct device_attribute dst_node_attrs[] = {
+ __ATTR(size, 0444, dst_show_size, NULL),
+ __ATTR(type, 0444, dst_show_type, NULL),
+ __ATTR(local, 0444, dst_show_local, NULL),
+};
+
+static int dst_create_node_attributes(struct dst_node *n)
+{
+ int err, i;
+
+ for (i=0; i<ARRAY_SIZE(dst_node_attrs); ++i) {
+ err = device_create_file(&n->info->device,
+ &dst_node_attrs[i]);
+ if (err)
+ goto err_out_remove_all;
+ }
+ return 0;
+
+err_out_remove_all:
+ while (--i >= 0)
+ device_remove_file(&n->info->device,
+ &dst_node_attrs[i]);
+
+ return err;
+}
+
+static void dst_remove_node_attributes(struct dst_node *n)
+{
+ int i;
+
+ for (i=0; i<ARRAY_SIZE(dst_node_attrs); ++i)
+ device_remove_file(&n->info->device,
+ &dst_node_attrs[i]);
+}
+
+/*
+ * Sysfs cleanup and initialization.
+ * Shows number of useful parameters.
+ */
+static void dst_node_sysfs_exit(struct dst_node *n)
+{
+ if (n->info) {
+ dst_remove_node_attributes(n);
+ device_unregister(&n->info->device);
+ n->info = NULL;
+ }
+}
+
+static int dst_node_sysfs_init(struct dst_node *n)
+{
+ int err;
+
+ n->info = kzalloc(sizeof(struct dst_info), GFP_KERNEL);
+ if (!n->info)
+ return -ENOMEM;
+
+ memcpy(&n->info->device, &dst_node_dev, sizeof(struct device));
+ n->info->size = n->size;
+
+ dev_set_name(&n->info->device, "dst-%s", n->name);
+ err = device_register(&n->info->device);
+ if (err) {
+ dprintk(KERN_ERR "Failed to register node '%s', err: %d.\n",
+ n->name, err);
+ goto err_out_exit;
+ }
+
+ dst_create_node_attributes(n);
+
+ return 0;
+
+err_out_exit:
+ kfree(n->info);
+ n->info = NULL;
+ return err;
+}
+
+/*
+ * DST node hash tables machinery.
+ */
+static inline unsigned int dst_hash(char *str, unsigned int size)
+{
+ return (jhash(str, size, 0) % dst_hashtable_size);
+}
+
+static void dst_node_remove(struct dst_node *n)
+{
+ mutex_lock(&dst_hash_lock);
+ list_del_init(&n->node_entry);
+ mutex_unlock(&dst_hash_lock);
+}
+
+static void dst_node_add(struct dst_node *n)
+{
+ unsigned hash = dst_hash(n->name, sizeof(n->name));
+
+ mutex_lock(&dst_hash_lock);
+ list_add_tail(&n->node_entry, &dst_hashtable[hash]);
+ mutex_unlock(&dst_hash_lock);
+}
+
+/*
+ * Cleaning node when it is about to be freed.
+ * There are still users of the socket though,
+ * so connection cleanup should be protected.
+ */
+static void dst_node_cleanup(struct dst_node *n)
+{
+ struct dst_state *st = n->state;
+
+ if (!st)
+ return;
+
+ if (n->queue) {
+ blk_cleanup_queue(n->queue);
+
+ mutex_lock(&dst_hash_lock);
+ idr_remove(&dst_index_idr, n->disk->first_minor);
+ mutex_unlock(&dst_hash_lock);
+
+ put_disk(n->disk);
+ }
+
+ if (n->bdev) {
+ sync_blockdev(n->bdev);
+ blkdev_put(n->bdev, FMODE_READ|FMODE_WRITE);
+ }
+
+ dst_state_lock(st);
+ st->need_exit = 1;
+ dst_state_exit_connected(st);
+ dst_state_unlock(st);
+
+ wake_up(&st->thread_wait);
+
+ dst_state_put(st);
+ n->state = NULL;
+}
+
+/*
+ * Free security attributes attached to given node.
+ */
+static void dst_security_exit(struct dst_node *n)
+{
+ struct dst_secure *s, *tmp;
+
+ list_for_each_entry_safe(s, tmp, &n->security_list, sec_entry) {
+ list_del(&s->sec_entry);
+ kfree(s);
+ }
+}
+
+/*
+ * Free node when there are no more users.
+ * Actually node has to be freed on behalf od userspace process,
+ * since there are number of threads, which are embedded in the
+ * node, so they can not exit and free node from there, that is
+ * why there is a wakeup if reference counter is not equal to zero.
+ */
+void dst_node_put(struct dst_node *n)
+{
+ if (unlikely(!n))
+ return;
+
+ dprintk("%s: n: %p, refcnt: %d.\n",
+ __func__, n, atomic_read(&n->refcnt));
+
+ if (atomic_dec_and_test(&n->refcnt)) {
+ dst_node_remove(n);
+ n->trans_scan_timeout = 0;
+ dst_node_cleanup(n);
+ thread_pool_destroy(n->pool);
+ dst_node_sysfs_exit(n);
+ dst_node_crypto_exit(n);
+ dst_security_exit(n);
+ dst_node_trans_exit(n);
+
+ kfree(n);
+
+ dprintk("%s: freed n: %p.\n", __func__, n);
+ } else {
+ wake_up(&n->wait);
+ }
+}
+
+/*
+ * This function finds devices major/minor numbers for given pathname.
+ */
+static int dst_lookup_device(const char *path, dev_t *dev)
+{
+ int err;
+ struct nameidata nd;
+ struct inode *inode;
+
+ err = path_lookup(path, LOOKUP_FOLLOW, &nd);
+ if (err)
+ return err;
+
+ inode = nd.path.dentry->d_inode;
+ if (!inode) {
+ err = -ENOENT;
+ goto out;
+ }
+
+ if (!S_ISBLK(inode->i_mode)) {
+ err = -ENOTBLK;
+ goto out;
+ }
+
+ *dev = inode->i_rdev;
+
+out:
+ path_put(&nd.path);
+ return err;
+}
+
+/*
+ * Setting up export device: lookup by the name, get its size
+ * and setup listening socket, which will accept clients, which
+ * will submit IO for given storage.
+ */
+static int dst_setup_export(struct dst_node *n, struct dst_ctl *ctl,
+ struct dst_export_ctl *le)
+{
+ int err;
+ dev_t dev = 0; /* gcc likes to scream here */
+
+ snprintf(n->info->local, sizeof(n->info->local), "%s", le->device);
+
+ err = dst_lookup_device(le->device, &dev);
+ if (err)
+ return err;
+
+ n->bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE);
+ if (!n->bdev)
+ return -ENODEV;
+
+ if (n->size != 0)
+ n->size = min_t(loff_t, n->bdev->bd_inode->i_size, n->size);
+ else
+ n->size = n->bdev->bd_inode->i_size;
+
+ n->info->size = n->size;
+ err = dst_node_init_listened(n, le);
+ if (err)
+ goto err_out_cleanup;
+
+ return 0;
+
+err_out_cleanup:
+ blkdev_put(n->bdev, FMODE_READ|FMODE_WRITE);
+ n->bdev = NULL;
+
+ return err;
+}
+
+/* Empty thread pool callbacks for the network processing threads. */
+static inline void *dst_thread_network_init(void *data)
+{
+ dprintk("%s: data: %p.\n", __func__, data);
+ return data;
+}
+
+static inline void dst_thread_network_cleanup(void *data)
+{
+ dprintk("%s: data: %p.\n", __func__, data);
+}
+
+/*
+ * Allocate DST node and initialize some of its parameters.
+ */
+static struct dst_node *dst_alloc_node(struct dst_ctl *ctl,
+ int (*start)(struct dst_node *),
+ int num)
+{
+ struct dst_node *n;
+ int err;
+
+ n = kzalloc(sizeof(struct dst_node), GFP_KERNEL);
+ if (!n)
+ return NULL;
+
+ INIT_LIST_HEAD(&n->node_entry);
+
+ INIT_LIST_HEAD(&n->security_list);
+ mutex_init(&n->security_lock);
+
+ init_waitqueue_head(&n->wait);
+
+ n->trans_scan_timeout = msecs_to_jiffies(ctl->trans_scan_timeout);
+ if (!n->trans_scan_timeout)
+ n->trans_scan_timeout = HZ;
+
+ n->trans_max_retries = ctl->trans_max_retries;
+ if (!n->trans_max_retries)
+ n->trans_max_retries = 10;
+
+ /*
+ * Pretty much arbitrary default numbers.
+ * 32 matches maximum number of pages in bio originated from ext3 (31).
+ */
+ n->max_pages = ctl->max_pages;
+ if (!n->max_pages)
+ n->max_pages = 32;
+
+ if (n->max_pages > 1024)
+ n->max_pages = 1024;
+
+ n->start = start;
+ n->size = ctl->size;
+
+ atomic_set(&n->refcnt, 1);
+ atomic_long_set(&n->gen, 0);
+ snprintf(n->name, sizeof(n->name), "%s", ctl->name);
+
+ err = dst_node_sysfs_init(n);
+ if (err)
+ goto err_out_free;
+
+ n->pool = thread_pool_create(num, n->name, dst_thread_network_init,
+ dst_thread_network_cleanup, n);
+ if (IS_ERR(n->pool)) {
+ err = PTR_ERR(n->pool);
+ goto err_out_sysfs_exit;
+ }
+
+ dprintk("%s: n: %p, name: %s.\n", __func__, n, n->name);
+
+ return n;
+
+err_out_sysfs_exit:
+ dst_node_sysfs_exit(n);
+err_out_free:
+ kfree(n);
+ return NULL;
+}
+
+/*
+ * Starting a node, connected to the remote server:
+ * register block device and initialize transaction mechanism.
+ * In revers order though.
+ *
+ * It will autonegotiate some parameters with the remote node
+ * and update local if needed.
+ *
+ * Transaction initialization should be the last thing before
+ * starting the node, since transaction should include not only
+ * block IO, but also crypto related data (if any), which are
+ * initialized separately.
+ */
+static int dst_start_remote(struct dst_node *n)
+{
+ int err;
+
+ err = dst_node_trans_init(n, sizeof(struct dst_trans));
+ if (err)
+ return err;
+
+ err = dst_node_create_disk(n);
+ if (err)
+ return err;
+
+ dst_node_set_size(n);
+ add_disk(n->disk);
+
+ dprintk("DST: started remote node '%s', minor: %d.\n", n->name, n->disk->first_minor);
+
+ return 0;
+}
+
+/*
+ * Adding remote node and initialize connection.
+ */
+static int dst_add_remote(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size)
+{
+ int err;
+ struct dst_network_ctl *rctl = data;
+
+ if (n)
+ return -EEXIST;
+
+ if (size != sizeof(struct dst_network_ctl))
+ return -EINVAL;
+
+ n = dst_alloc_node(ctl, dst_start_remote, 1);
+ if (!n)
+ return -ENOMEM;
+
+ memcpy(&n->info->net, rctl, sizeof(struct dst_network_ctl));
+ err = dst_node_init_connected(n, rctl);
+ if (err)
+ goto err_out_free;
+
+ dst_node_add(n);
+
+ return 0;
+
+err_out_free:
+ dst_node_put(n);
+ return err;
+}
+
+/*
+ * Adding export node: initializing block device and listening socket.
+ */
+static int dst_add_export(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size)
+{
+ int err;
+ struct dst_export_ctl *le = data;
+
+ if (n)
+ return -EEXIST;
+
+ if (size != sizeof(struct dst_export_ctl))
+ return -EINVAL;
+
+ n = dst_alloc_node(ctl, dst_start_export, 2);
+ if (!n)
+ return -EINVAL;
+
+ err = dst_setup_export(n, ctl, le);
+ if (err)
+ goto err_out_free;
+
+ dst_node_add(n);
+
+ return 0;
+
+err_out_free:
+ dst_node_put(n);
+ return err;
+}
+
+static int dst_node_remove_unload(struct dst_node *n)
+{
+ printk(KERN_INFO "STOPPED name: '%s', size: %llu.\n",
+ n->name, n->size);
+
+ if (n->disk)
+ del_gendisk(n->disk);
+
+ dst_node_remove(n);
+ dst_node_sysfs_exit(n);
+
+ /*
+ * This is not a hack. Really.
+ * Node's reference counter allows to implement fine grained
+ * node freeing, but since all transactions (which hold node's
+ * reference counter) are processed in the dedicated thread,
+ * it is possible that reference will hit zero in that thread,
+ * so we will not be able to exit thread and cleanup the node.
+ *
+ * So, we remove disk, so no new activity is possible, and
+ * wait until all pending transaction are completed (either
+ * in receiving thread or by timeout in workqueue), in this
+ * case reference counter will be less or equal to 2 (once set in
+ * dst_alloc_node() and then in connector message parser;
+ * or when we force module unloading, and connector message
+ * parser does not hold a reference, in this case reference
+ * counter will be equal to 1),
+ * and subsequent dst_node_put() calls will free the node.
+ */
+ dprintk("%s: going to sleep with %d refcnt.\n", __func__, atomic_read(&n->refcnt));
+ wait_event(n->wait, atomic_read(&n->refcnt) <= 2);
+
+ dst_node_put(n);
+ return 0;
+}
+
+/*
+ * Remove node from the hash table.
+ */
+static int dst_del_node(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size)
+{
+ if (!n)
+ return -ENODEV;
+
+ return dst_node_remove_unload(n);
+}
+
+/*
+ * Initialize crypto processing for given node.
+ */
+static int dst_crypto_init(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size)
+{
+ struct dst_crypto_ctl *crypto = data;
+
+ if (!n)
+ return -ENODEV;
+
+ if (size != sizeof(struct dst_crypto_ctl) + crypto->hash_keysize +
+ crypto->cipher_keysize)
+ return -EINVAL;
+
+ if (n->trans_cache)
+ return -EEXIST;
+
+ return dst_node_crypto_init(n, crypto);
+}
+
+/*
+ * Security attributes for given node.
+ */
+static int dst_security_init(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size)
+{
+ struct dst_secure *s;
+
+ if (!n)
+ return -ENODEV;
+
+ if (size != sizeof(struct dst_secure_user))
+ return -EINVAL;
+
+ s = kmalloc(sizeof(struct dst_secure), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+
+ memcpy(&s->sec, data, size);
+
+ mutex_lock(&n->security_lock);
+ list_add_tail(&s->sec_entry, &n->security_list);
+ mutex_unlock(&n->security_lock);
+
+ return 0;
+}
+
+/*
+ * Kill'em all!
+ */
+static int dst_start_node(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size)
+{
+ int err;
+
+ if (!n)
+ return -ENODEV;
+
+ if (n->trans_cache)
+ return 0;
+
+ err = n->start(n);
+ if (err)
+ return err;
+
+ printk(KERN_INFO "STARTED name: '%s', size: %llu.\n", n->name, n->size);
+ return 0;
+}
+
+typedef int (*dst_command_func)(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size);
+
+/*
+ * List of userspace commands.
+ */
+static dst_command_func dst_commands[] = {
+ [DST_ADD_REMOTE] = &dst_add_remote,
+ [DST_ADD_EXPORT] = &dst_add_export,
+ [DST_DEL_NODE] = &dst_del_node,
+ [DST_CRYPTO] = &dst_crypto_init,
+ [DST_SECURITY] = &dst_security_init,
+ [DST_START] = &dst_start_node,
+};
+
+/*
+ * Configuration parser.
+ */
+static void cn_dst_callback(void *data)
+{
+ struct dst_ctl *ctl;
+ struct cn_msg *msg = data;
+ int err;
+ struct dst_ctl_ack ack;
+ struct dst_node *n = NULL, *tmp;
+ unsigned int hash;
+
+ if (msg->len < sizeof(struct dst_ctl)) {
+ err = -EBADMSG;
+ goto out;
+ }
+
+ ctl = (struct dst_ctl *)msg->data;
+
+ if (ctl->cmd >= DST_CMD_MAX) {
+ err = -EINVAL;
+ goto out;
+ }
+ hash = dst_hash(ctl->name, sizeof(ctl->name));
+
+ mutex_lock(&dst_hash_lock);
+ list_for_each_entry(tmp, &dst_hashtable[hash], node_entry) {
+ if (!memcmp(tmp->name, ctl->name, sizeof(tmp->name))) {
+ n = tmp;
+ dst_node_get(n);
+ break;
+ }
+ }
+ mutex_unlock(&dst_hash_lock);
+
+ err = dst_commands[ctl->cmd](n, ctl, msg->data + sizeof(struct dst_ctl),
+ msg->len - sizeof(struct dst_ctl));
+
+ dst_node_put(n);
+out:
+ memcpy(&ack.msg, msg, sizeof(struct cn_msg));
+
+ ack.msg.ack = msg->ack + 1;
+ ack.msg.len = sizeof(struct dst_ctl_ack) - sizeof(struct cn_msg);
+
+ ack.error = err;
+
+ cn_netlink_send(&ack.msg, 0, GFP_KERNEL);
+}
+
+/*
+ * Global initialization: sysfs, hash table, block device registration,
+ * connector and various caches.
+ */
+static int __init dst_sysfs_init(void)
+{
+ return bus_register(&dst_dev_bus_type);
+}
+
+static void dst_sysfs_exit(void)
+{
+ bus_unregister(&dst_dev_bus_type);
+}
+
+static int __init dst_hashtable_init(void)
+{
+ unsigned int i;
+
+ dst_hashtable = kcalloc(dst_hashtable_size, sizeof(struct list_head),
+ GFP_KERNEL);
+ if (!dst_hashtable)
+ return -ENOMEM;
+
+ for (i=0; i<dst_hashtable_size; ++i)
+ INIT_LIST_HEAD(&dst_hashtable[i]);
+
+ return 0;
+}
+
+static void dst_hashtable_exit(void)
+{
+ unsigned int i;
+ struct dst_node *n, *tmp;
+
+ for (i=0; i<dst_hashtable_size; ++i) {
+ list_for_each_entry_safe(n, tmp, &dst_hashtable[i], node_entry) {
+ dst_node_remove_unload(n);
+ }
+ }
+
+ kfree(dst_hashtable);
+}
+
+static int __init dst_sys_init(void)
+{
+ int err = -ENOMEM;
+
+ err = dst_hashtable_init();
+ if (err)
+ goto err_out_exit;
+
+ err = dst_export_init();
+ if (err)
+ goto err_out_hashtable_exit;
+
+ err = register_blkdev(dst_major, DST_NAME);
+ if (err < 0)
+ goto err_out_export_exit;
+ if (err)
+ dst_major = err;
+
+ err = dst_sysfs_init();
+ if (err)
+ goto err_out_unregister;
+
+ err = cn_add_callback(&cn_dst_id, "DST", cn_dst_callback);
+ if (err)
+ goto err_out_sysfs_exit;
+
+ printk(KERN_INFO "Distributed storage, '%s' release.\n", dst_name);
+
+ return 0;
+
+err_out_sysfs_exit:
+ dst_sysfs_exit();
+err_out_unregister:
+ unregister_blkdev(dst_major, DST_NAME);
+err_out_export_exit:
+ dst_export_exit();
+err_out_hashtable_exit:
+ dst_hashtable_exit();
+err_out_exit:
+ return err;
+}
+
+static void __exit dst_sys_exit(void)
+{
+ cn_del_callback(&cn_dst_id);
+ unregister_blkdev(dst_major, DST_NAME);
+ dst_hashtable_exit();
+ dst_sysfs_exit();
+ dst_export_exit();
+}
+
+module_init(dst_sys_init);
+module_exit(dst_sys_exit);
+
+MODULE_DESCRIPTION("Distributed storage");
+MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/dst/export.c b/drivers/staging/dst/export.c
new file mode 100644
index 00000000000..80ae4ebe610
--- /dev/null
+++ b/drivers/staging/dst/export.c
@@ -0,0 +1,657 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/blkdev.h>
+#include <linux/bio.h>
+#include <linux/dst.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+
+#include <net/sock.h>
+
+/*
+ * Export bioset is used for server block IO requests.
+ */
+static struct bio_set *dst_bio_set;
+
+int __init dst_export_init(void)
+{
+ int err = -ENOMEM;
+
+ dst_bio_set = bioset_create(32, sizeof(struct dst_export_priv));
+ if (!dst_bio_set)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+void dst_export_exit(void)
+{
+ bioset_free(dst_bio_set);
+}
+
+/*
+ * When client connects and autonegotiates with the server node,
+ * its permissions are checked in a security attributes and sent
+ * back.
+ */
+static unsigned int dst_check_permissions(struct dst_state *main, struct dst_state *st)
+{
+ struct dst_node *n = main->node;
+ struct dst_secure *sentry;
+ struct dst_secure_user *s;
+ struct saddr *sa = &st->ctl.addr;
+ unsigned int perm = 0;
+
+ mutex_lock(&n->security_lock);
+ list_for_each_entry(sentry, &n->security_list, sec_entry) {
+ s = &sentry->sec;
+
+ if (s->addr.sa_family != sa->sa_family)
+ continue;
+
+ if (s->addr.sa_data_len != sa->sa_data_len)
+ continue;
+
+ /*
+ * This '2' below is a port field. This may be very wrong to do
+ * in atalk for example though. If there will be any need to extent
+ * protocol to something else, I can create per-family helpers and
+ * use them instead of this memcmp.
+ */
+ if (memcmp(s->addr.sa_data + 2, sa->sa_data + 2,
+ sa->sa_data_len - 2))
+ continue;
+
+ perm = s->permissions;
+ }
+ mutex_unlock(&n->security_lock);
+
+ return perm;
+}
+
+/*
+ * Accept new client: allocate appropriate network state and check permissions.
+ */
+static struct dst_state *dst_accept_client(struct dst_state *st)
+{
+ unsigned int revents = 0;
+ unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
+ unsigned int mask = err_mask | POLLIN;
+ struct dst_node *n = st->node;
+ int err = 0;
+ struct socket *sock = NULL;
+ struct dst_state *new;
+
+ while (!err && !sock) {
+ revents = dst_state_poll(st);
+
+ if (!(revents & mask)) {
+ DEFINE_WAIT(wait);
+
+ for (;;) {
+ prepare_to_wait(&st->thread_wait,
+ &wait, TASK_INTERRUPTIBLE);
+ if (!n->trans_scan_timeout || st->need_exit)
+ break;
+
+ revents = dst_state_poll(st);
+
+ if (revents & mask)
+ break;
+
+ if (signal_pending(current))
+ break;
+
+ /*
+ * Magic HZ? Polling check above is not safe in
+ * all cases (like socket reset in BH context),
+ * so it is simpler just to postpone it to the
+ * process context instead of implementing special
+ * locking there.
+ */
+ schedule_timeout(HZ);
+ }
+ finish_wait(&st->thread_wait, &wait);
+ }
+
+ err = -ECONNRESET;
+ dst_state_lock(st);
+
+ dprintk("%s: st: %p, revents: %x [err: %d, in: %d].\n",
+ __func__, st, revents, revents & err_mask,
+ revents & POLLIN);
+
+ if (revents & err_mask) {
+ dprintk("%s: revents: %x, socket: %p, err: %d.\n",
+ __func__, revents, st->socket, err);
+ err = -ECONNRESET;
+ }
+
+ if (!n->trans_scan_timeout || st->need_exit)
+ err = -ENODEV;
+
+ if (st->socket && (revents & POLLIN))
+ err = kernel_accept(st->socket, &sock, 0);
+
+ dst_state_unlock(st);
+ }
+
+ if (err)
+ goto err_out_exit;
+
+ new = dst_state_alloc(st->node);
+ if (!new) {
+ err = -ENOMEM;
+ goto err_out_release;
+ }
+ new->socket = sock;
+
+ new->ctl.addr.sa_data_len = sizeof(struct sockaddr);
+ err = kernel_getpeername(sock, (struct sockaddr *)&new->ctl.addr,
+ (int *)&new->ctl.addr.sa_data_len);
+ if (err)
+ goto err_out_put;
+
+ new->permissions = dst_check_permissions(st, new);
+ if (new->permissions == 0) {
+ err = -EPERM;
+ dst_dump_addr(sock, (struct sockaddr *)&new->ctl.addr,
+ "Client is not allowed to connect");
+ goto err_out_put;
+ }
+
+ err = dst_poll_init(new);
+ if (err)
+ goto err_out_put;
+
+ dst_dump_addr(sock, (struct sockaddr *)&new->ctl.addr,
+ "Connected client");
+
+ return new;
+
+err_out_put:
+ dst_state_put(new);
+err_out_release:
+ sock_release(sock);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+/*
+ * Each server's block request sometime finishes.
+ * Usually it happens in hard irq context of the appropriate controller,
+ * so to play good with all cases we just queue BIO into the queue
+ * and wake up processing thread, which gets completed request and
+ * send (encrypting if needed) it back to the client (if it was a read
+ * request), or sends back reply that writing succesfully completed.
+ */
+static int dst_export_process_request_queue(struct dst_state *st)
+{
+ unsigned long flags;
+ struct dst_export_priv *p = NULL;
+ struct bio *bio;
+ int err = 0;
+
+ while (!list_empty(&st->request_list)) {
+ spin_lock_irqsave(&st->request_lock, flags);
+ if (!list_empty(&st->request_list)) {
+ p = list_first_entry(&st->request_list,
+ struct dst_export_priv, request_entry);
+ list_del(&p->request_entry);
+ }
+ spin_unlock_irqrestore(&st->request_lock, flags);
+
+ if (!p)
+ break;
+
+ bio = p->bio;
+
+ if (dst_need_crypto(st->node) && (bio_data_dir(bio) == READ))
+ err = dst_export_crypto(st->node, bio);
+ else
+ err = dst_export_send_bio(bio);
+
+ if (err)
+ break;
+ }
+
+ return err;
+}
+
+/*
+ * Cleanup export state.
+ * It has to wait until all requests are finished,
+ * and then free them all.
+ */
+static void dst_state_cleanup_export(struct dst_state *st)
+{
+ struct dst_export_priv *p;
+ unsigned long flags;
+
+ /*
+ * This loop waits for all pending bios to be completed and freed.
+ */
+ while (atomic_read(&st->refcnt) > 1) {
+ dprintk("%s: st: %p, refcnt: %d, list_empty: %d.\n",
+ __func__, st, atomic_read(&st->refcnt),
+ list_empty(&st->request_list));
+ wait_event_timeout(st->thread_wait,
+ (atomic_read(&st->refcnt) == 1) ||
+ !list_empty(&st->request_list),
+ HZ/2);
+
+ while (!list_empty(&st->request_list)) {
+ p = NULL;
+ spin_lock_irqsave(&st->request_lock, flags);
+ if (!list_empty(&st->request_list)) {
+ p = list_first_entry(&st->request_list,
+ struct dst_export_priv, request_entry);
+ list_del(&p->request_entry);
+ }
+ spin_unlock_irqrestore(&st->request_lock, flags);
+
+ if (p)
+ bio_put(p->bio);
+
+ dprintk("%s: st: %p, refcnt: %d, list_empty: %d, p: %p.\n",
+ __func__, st, atomic_read(&st->refcnt),
+ list_empty(&st->request_list), p);
+ }
+ }
+
+ dst_state_put(st);
+}
+
+/*
+ * Client accepting thread.
+ * Not only accepts new connection, but also schedules receiving thread
+ * and performs request completion described above.
+ */
+static int dst_accept(void *init_data, void *schedule_data)
+{
+ struct dst_state *main_st = schedule_data;
+ struct dst_node *n = init_data;
+ struct dst_state *st;
+ int err;
+
+ while (n->trans_scan_timeout && !main_st->need_exit) {
+ dprintk("%s: main_st: %p, n: %p.\n", __func__, main_st, n);
+ st = dst_accept_client(main_st);
+ if (IS_ERR(st))
+ continue;
+
+ err = dst_state_schedule_receiver(st);
+ if (!err) {
+ while (n->trans_scan_timeout) {
+ err = wait_event_interruptible_timeout(st->thread_wait,
+ !list_empty(&st->request_list) ||
+ !n->trans_scan_timeout ||
+ st->need_exit,
+ HZ);
+
+ if (!n->trans_scan_timeout || st->need_exit)
+ break;
+
+ if (list_empty(&st->request_list))
+ continue;
+
+ err = dst_export_process_request_queue(st);
+ if (err)
+ break;
+ }
+
+ st->need_exit = 1;
+ wake_up(&st->thread_wait);
+ }
+
+ dst_state_cleanup_export(st);
+ }
+
+ dprintk("%s: freeing listening socket st: %p.\n", __func__, main_st);
+
+ dst_state_lock(main_st);
+ dst_poll_exit(main_st);
+ dst_state_socket_release(main_st);
+ dst_state_unlock(main_st);
+ dst_state_put(main_st);
+ dprintk("%s: freed listening socket st: %p.\n", __func__, main_st);
+
+ return 0;
+}
+
+int dst_start_export(struct dst_node *n)
+{
+ if (list_empty(&n->security_list)) {
+ printk(KERN_ERR "You are trying to export node '%s' without security attributes.\n"
+ "No clients will be allowed to connect. Exiting.\n", n->name);
+ return -EINVAL;
+ }
+ return dst_node_trans_init(n, sizeof(struct dst_export_priv));
+}
+
+/*
+ * Initialize listening state and schedule accepting thread.
+ */
+int dst_node_init_listened(struct dst_node *n, struct dst_export_ctl *le)
+{
+ struct dst_state *st;
+ int err = -ENOMEM;
+ struct dst_network_ctl *ctl = &le->ctl;
+
+ memcpy(&n->info->net, ctl, sizeof(struct dst_network_ctl));
+
+ st = dst_state_alloc(n);
+ if (IS_ERR(st)) {
+ err = PTR_ERR(st);
+ goto err_out_exit;
+ }
+ memcpy(&st->ctl, ctl, sizeof(struct dst_network_ctl));
+
+ err = dst_state_socket_create(st);
+ if (err)
+ goto err_out_put;
+
+ st->socket->sk->sk_reuse = 1;
+
+ err = kernel_bind(st->socket, (struct sockaddr *)&ctl->addr,
+ ctl->addr.sa_data_len);
+ if (err)
+ goto err_out_socket_release;
+
+ err = kernel_listen(st->socket, 1024);
+ if (err)
+ goto err_out_socket_release;
+ n->state = st;
+
+ err = dst_poll_init(st);
+ if (err)
+ goto err_out_socket_release;
+
+ dst_state_get(st);
+
+ err = thread_pool_schedule(n->pool, dst_thread_setup,
+ dst_accept, st, MAX_SCHEDULE_TIMEOUT);
+ if (err)
+ goto err_out_poll_exit;
+
+ return 0;
+
+err_out_poll_exit:
+ dst_poll_exit(st);
+err_out_socket_release:
+ dst_state_socket_release(st);
+err_out_put:
+ dst_state_put(st);
+err_out_exit:
+ n->state = NULL;
+ return err;
+}
+
+/*
+ * Free bio and related private data.
+ * Also drop a reference counter for appropriate state,
+ * which waits when there are no more block IOs in-flight.
+ */
+static void dst_bio_destructor(struct bio *bio)
+{
+ struct bio_vec *bv;
+ struct dst_export_priv *priv = bio->bi_private;
+ int i;
+
+ bio_for_each_segment(bv, bio, i) {
+ if (!bv->bv_page)
+ break;
+
+ __free_page(bv->bv_page);
+ }
+
+ if (priv)
+ dst_state_put(priv->state);
+ bio_free(bio, dst_bio_set);
+}
+
+/*
+ * Block IO completion. Queue request to be sent back to
+ * the client (or just confirmation).
+ */
+static void dst_bio_end_io(struct bio *bio, int err)
+{
+ struct dst_export_priv *p = bio->bi_private;
+ struct dst_state *st = p->state;
+ unsigned long flags;
+
+ spin_lock_irqsave(&st->request_lock, flags);
+ list_add_tail(&p->request_entry, &st->request_list);
+ spin_unlock_irqrestore(&st->request_lock, flags);
+
+ wake_up(&st->thread_wait);
+}
+
+/*
+ * Allocate read request for the server.
+ */
+static int dst_export_read_request(struct bio *bio, unsigned int total_size)
+{
+ unsigned int size;
+ struct page *page;
+ int err;
+
+ while (total_size) {
+ err = -ENOMEM;
+ page = alloc_page(GFP_KERNEL);
+ if (!page)
+ goto err_out_exit;
+
+ size = min_t(unsigned int, PAGE_SIZE, total_size);
+
+ err = bio_add_page(bio, page, size, 0);
+ dprintk("%s: bio: %llu/%u, size: %u, err: %d.\n",
+ __func__, (u64)bio->bi_sector, bio->bi_size,
+ size, err);
+ if (err <= 0)
+ goto err_out_free_page;
+
+ total_size -= size;
+ }
+
+ return 0;
+
+err_out_free_page:
+ __free_page(page);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Allocate write request for the server.
+ * Should not only get pages, but also read data from the network.
+ */
+static int dst_export_write_request(struct dst_state *st,
+ struct bio *bio, unsigned int total_size)
+{
+ unsigned int size;
+ struct page *page;
+ void *data;
+ int err;
+
+ while (total_size) {
+ err = -ENOMEM;
+ page = alloc_page(GFP_KERNEL);
+ if (!page)
+ goto err_out_exit;
+
+ data = kmap(page);
+ if (!data)
+ goto err_out_free_page;
+
+ size = min_t(unsigned int, PAGE_SIZE, total_size);
+
+ err = dst_data_recv(st, data, size);
+ if (err)
+ goto err_out_unmap_page;
+
+ err = bio_add_page(bio, page, size, 0);
+ if (err <= 0)
+ goto err_out_unmap_page;
+
+ kunmap(page);
+
+ total_size -= size;
+ }
+
+ return 0;
+
+err_out_unmap_page:
+ kunmap(page);
+err_out_free_page:
+ __free_page(page);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Groovy, we've gotten an IO request from the client.
+ * Allocate BIO from the bioset, private data from the mempool
+ * and lots of pages for IO.
+ */
+int dst_process_io(struct dst_state *st)
+{
+ struct dst_node *n = st->node;
+ struct dst_cmd *cmd = st->data;
+ struct bio *bio;
+ struct dst_export_priv *priv;
+ int err = -ENOMEM;
+
+ if (unlikely(!n->bdev)) {
+ err = -EINVAL;
+ goto err_out_exit;
+ }
+
+ bio = bio_alloc_bioset(GFP_KERNEL,
+ PAGE_ALIGN(cmd->size) >> PAGE_SHIFT,
+ dst_bio_set);
+ if (!bio)
+ goto err_out_exit;
+
+ priv = (struct dst_export_priv *)(((void *)bio) - sizeof (struct dst_export_priv));
+
+ priv->state = dst_state_get(st);
+ priv->bio = bio;
+
+ bio->bi_private = priv;
+ bio->bi_end_io = dst_bio_end_io;
+ bio->bi_destructor = dst_bio_destructor;
+ bio->bi_bdev = n->bdev;
+
+ /*
+ * Server side is only interested in two low bits:
+ * uptodate (set by itself actually) and rw block
+ */
+ bio->bi_flags |= cmd->flags & 3;
+
+ bio->bi_rw = cmd->rw;
+ bio->bi_size = 0;
+ bio->bi_sector = cmd->sector;
+
+ dst_bio_to_cmd(bio, &priv->cmd, DST_IO_RESPONSE, cmd->id);
+
+ priv->cmd.flags = 0;
+ priv->cmd.size = cmd->size;
+
+ if (bio_data_dir(bio) == WRITE) {
+ err = dst_recv_cdata(st, priv->cmd.hash);
+ if (err)
+ goto err_out_free;
+
+ err = dst_export_write_request(st, bio, cmd->size);
+ if (err)
+ goto err_out_free;
+
+ if (dst_need_crypto(n))
+ return dst_export_crypto(n, bio);
+ } else {
+ err = dst_export_read_request(bio, cmd->size);
+ if (err)
+ goto err_out_free;
+ }
+
+ dprintk("%s: bio: %llu/%u, rw: %lu, dir: %lu, flags: %lx, phys: %d.\n",
+ __func__, (u64)bio->bi_sector, bio->bi_size,
+ bio->bi_rw, bio_data_dir(bio),
+ bio->bi_flags, bio->bi_phys_segments);
+
+ generic_make_request(bio);
+
+ return 0;
+
+err_out_free:
+ bio_put(bio);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Ok, block IO is ready, let's send it back to the client...
+ */
+int dst_export_send_bio(struct bio *bio)
+{
+ struct dst_export_priv *p = bio->bi_private;
+ struct dst_state *st = p->state;
+ struct dst_cmd *cmd = &p->cmd;
+ int err;
+
+ dprintk("%s: id: %llu, bio: %llu/%u, csize: %u, flags: %lu, rw: %lu.\n",
+ __func__, cmd->id, (u64)bio->bi_sector, bio->bi_size,
+ cmd->csize, bio->bi_flags, bio->bi_rw);
+
+ dst_convert_cmd(cmd);
+
+ dst_state_lock(st);
+ if (!st->socket) {
+ err = -ECONNRESET;
+ goto err_out_unlock;
+ }
+
+ if (bio_data_dir(bio) == WRITE) {
+ /* ... or just confirmation that writing has completed. */
+ cmd->size = cmd->csize = 0;
+ err = dst_data_send_header(st->socket, cmd,
+ sizeof(struct dst_cmd), 0);
+ if (err)
+ goto err_out_unlock;
+ } else {
+ err = dst_send_bio(st, cmd, bio);
+ if (err)
+ goto err_out_unlock;
+ }
+
+ dst_state_unlock(st);
+
+ bio_put(bio);
+ return 0;
+
+err_out_unlock:
+ dst_state_unlock(st);
+
+ bio_put(bio);
+ return err;
+}
diff --git a/drivers/staging/dst/state.c b/drivers/staging/dst/state.c
new file mode 100644
index 00000000000..d057e52f3b6
--- /dev/null
+++ b/drivers/staging/dst/state.c
@@ -0,0 +1,839 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/buffer_head.h>
+#include <linux/blkdev.h>
+#include <linux/bio.h>
+#include <linux/connector.h>
+#include <linux/dst.h>
+#include <linux/device.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/socket.h>
+#include <linux/slab.h>
+
+#include <net/sock.h>
+
+/*
+ * Polling machinery.
+ */
+
+struct dst_poll_helper
+{
+ poll_table pt;
+ struct dst_state *st;
+};
+
+static int dst_queue_wake(wait_queue_t *wait, unsigned mode, int sync, void *key)
+{
+ struct dst_state *st = container_of(wait, struct dst_state, wait);
+
+ wake_up(&st->thread_wait);
+ return 1;
+}
+
+static void dst_queue_func(struct file *file, wait_queue_head_t *whead,
+ poll_table *pt)
+{
+ struct dst_state *st = container_of(pt, struct dst_poll_helper, pt)->st;
+
+ st->whead = whead;
+ init_waitqueue_func_entry(&st->wait, dst_queue_wake);
+ add_wait_queue(whead, &st->wait);
+}
+
+void dst_poll_exit(struct dst_state *st)
+{
+ if (st->whead) {
+ remove_wait_queue(st->whead, &st->wait);
+ st->whead = NULL;
+ }
+}
+
+int dst_poll_init(struct dst_state *st)
+{
+ struct dst_poll_helper ph;
+
+ ph.st = st;
+ init_poll_funcptr(&ph.pt, &dst_queue_func);
+
+ st->socket->ops->poll(NULL, st->socket, &ph.pt);
+ return 0;
+}
+
+/*
+ * Header receiving function - may block.
+ */
+static int dst_data_recv_header(struct socket *sock,
+ void *data, unsigned int size, int block)
+{
+ struct msghdr msg;
+ struct kvec iov;
+ int err;
+
+ iov.iov_base = data;
+ iov.iov_len = size;
+
+ msg.msg_iov = (struct iovec *)&iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = (block)?MSG_WAITALL:MSG_DONTWAIT;
+
+ err = kernel_recvmsg(sock, &msg, &iov, 1, iov.iov_len,
+ msg.msg_flags);
+ if (err != size)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Header sending function - may block.
+ */
+int dst_data_send_header(struct socket *sock,
+ void *data, unsigned int size, int more)
+{
+ struct msghdr msg;
+ struct kvec iov;
+ int err;
+
+ iov.iov_base = data;
+ iov.iov_len = size;
+
+ msg.msg_iov = (struct iovec *)&iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = MSG_WAITALL | (more)?MSG_MORE:0;
+
+ err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
+ if (err != size) {
+ dprintk("%s: size: %u, more: %d, err: %d.\n",
+ __func__, size, more, err);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Block autoconfiguration: request size of the storage and permissions.
+ */
+static int dst_request_remote_config(struct dst_state *st)
+{
+ struct dst_node *n = st->node;
+ int err = -EINVAL;
+ struct dst_cmd *cmd = st->data;
+
+ memset(cmd, 0, sizeof(struct dst_cmd));
+ cmd->cmd = DST_CFG;
+
+ dst_convert_cmd(cmd);
+
+ err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0);
+ if (err)
+ goto out;
+
+ err = dst_data_recv_header(st->socket, cmd, sizeof(struct dst_cmd), 1);
+ if (err)
+ goto out;
+
+ dst_convert_cmd(cmd);
+
+ if (cmd->cmd != DST_CFG) {
+ err = -EINVAL;
+ dprintk("%s: checking result: cmd: %d, size reported: %llu.\n",
+ __func__, cmd->cmd, cmd->sector);
+ goto out;
+ }
+
+ if (n->size != 0)
+ n->size = min_t(loff_t, n->size, cmd->sector);
+ else
+ n->size = cmd->sector;
+
+ n->info->size = n->size;
+ st->permissions = cmd->rw;
+
+out:
+ dprintk("%s: n: %p, err: %d, size: %llu, permission: %x.\n",
+ __func__, n, err, n->size, st->permissions);
+ return err;
+}
+
+/*
+ * Socket machinery.
+ */
+
+#define DST_DEFAULT_TIMEO 20000
+
+int dst_state_socket_create(struct dst_state *st)
+{
+ int err;
+ struct socket *sock;
+ struct dst_network_ctl *ctl = &st->ctl;
+
+ err = sock_create(ctl->addr.sa_family, ctl->type, ctl->proto, &sock);
+ if (err < 0)
+ return err;
+
+ sock->sk->sk_sndtimeo = sock->sk->sk_rcvtimeo =
+ msecs_to_jiffies(DST_DEFAULT_TIMEO);
+ sock->sk->sk_allocation = GFP_NOIO;
+
+ st->socket = st->read_socket = sock;
+ return 0;
+}
+
+void dst_state_socket_release(struct dst_state *st)
+{
+ dprintk("%s: st: %p, socket: %p, n: %p.\n",
+ __func__, st, st->socket, st->node);
+ if (st->socket) {
+ sock_release(st->socket);
+ st->socket = NULL;
+ st->read_socket = NULL;
+ }
+}
+
+void dst_dump_addr(struct socket *sk, struct sockaddr *sa, char *str)
+{
+ if (sk->ops->family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+ printk(KERN_INFO "%s %u.%u.%u.%u:%d.\n",
+ str, NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+ } else if (sk->ops->family == AF_INET6) {
+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa;
+ printk(KERN_INFO "%s %pi6:%d",
+ str, &sin->sin6_addr, ntohs(sin->sin6_port));
+ }
+}
+
+void dst_state_exit_connected(struct dst_state *st)
+{
+ if (st->socket) {
+ dst_poll_exit(st);
+ st->socket->ops->shutdown(st->socket, 2);
+
+ dst_dump_addr(st->socket, (struct sockaddr *)&st->ctl.addr,
+ "Disconnected peer");
+ dst_state_socket_release(st);
+ }
+}
+
+static int dst_state_init_connected(struct dst_state *st)
+{
+ int err;
+ struct dst_network_ctl *ctl = &st->ctl;
+
+ err = dst_state_socket_create(st);
+ if (err)
+ goto err_out_exit;
+
+ err = kernel_connect(st->socket, (struct sockaddr *)&st->ctl.addr,
+ st->ctl.addr.sa_data_len, 0);
+ if (err)
+ goto err_out_release;
+
+ err = dst_poll_init(st);
+ if (err)
+ goto err_out_release;
+
+ dst_dump_addr(st->socket, (struct sockaddr *)&ctl->addr,
+ "Connected to peer");
+
+ return 0;
+
+err_out_release:
+ dst_state_socket_release(st);
+err_out_exit:
+ return err;
+}
+
+/*
+ * State reset is used to reconnect to the remote peer.
+ * May fail, but who cares, we will try again later.
+ */
+static void inline dst_state_reset_nolock(struct dst_state *st)
+{
+ dst_state_exit_connected(st);
+ dst_state_init_connected(st);
+}
+
+static void inline dst_state_reset(struct dst_state *st)
+{
+ dst_state_lock(st);
+ dst_state_reset_nolock(st);
+ dst_state_unlock(st);
+}
+
+/*
+ * Basic network sending/receiving functions.
+ * Blocked mode is used.
+ */
+static int dst_data_recv_raw(struct dst_state *st, void *buf, u64 size)
+{
+ struct msghdr msg;
+ struct kvec iov;
+ int err;
+
+ BUG_ON(!size);
+
+ iov.iov_base = buf;
+ iov.iov_len = size;
+
+ msg.msg_iov = (struct iovec *)&iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = MSG_DONTWAIT;
+
+ err = kernel_recvmsg(st->socket, &msg, &iov, 1, iov.iov_len,
+ msg.msg_flags);
+ if (err <= 0) {
+ dprintk("%s: failed to recv data: size: %llu, err: %d.\n",
+ __func__, size, err);
+ if (err == 0)
+ err = -ECONNRESET;
+
+ dst_state_exit_connected(st);
+ }
+
+ return err;
+}
+
+/*
+ * Ping command to early detect failed nodes.
+ */
+static int dst_send_ping(struct dst_state *st)
+{
+ struct dst_cmd *cmd = st->data;
+ int err = -ECONNRESET;
+
+ dst_state_lock(st);
+ if (st->socket) {
+ memset(cmd, 0, sizeof(struct dst_cmd));
+
+ cmd->cmd = __cpu_to_be32(DST_PING);
+
+ err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0);
+ }
+ dprintk("%s: st: %p, socket: %p, err: %d.\n", __func__, st, st->socket, err);
+ dst_state_unlock(st);
+
+ return err;
+}
+
+/*
+ * Receiving function, which should either return error or read
+ * whole block request. If there was no traffic for a one second,
+ * send a ping, since remote node may die.
+ */
+int dst_data_recv(struct dst_state *st, void *data, unsigned int size)
+{
+ unsigned int revents = 0;
+ unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
+ unsigned int mask = err_mask | POLLIN;
+ struct dst_node *n = st->node;
+ int err = 0;
+
+ while (size && !err) {
+ revents = dst_state_poll(st);
+
+ if (!(revents & mask)) {
+ DEFINE_WAIT(wait);
+
+ for (;;) {
+ prepare_to_wait(&st->thread_wait, &wait,
+ TASK_INTERRUPTIBLE);
+ if (!n->trans_scan_timeout || st->need_exit)
+ break;
+
+ revents = dst_state_poll(st);
+
+ if (revents & mask)
+ break;
+
+ if (signal_pending(current))
+ break;
+
+ if (!schedule_timeout(HZ)) {
+ err = dst_send_ping(st);
+ if (err)
+ return err;
+ }
+
+ continue;
+ }
+ finish_wait(&st->thread_wait, &wait);
+ }
+
+ err = -ECONNRESET;
+ dst_state_lock(st);
+
+ if ( st->socket &&
+ (st->read_socket == st->socket) &&
+ (revents & POLLIN)) {
+ err = dst_data_recv_raw(st, data, size);
+ if (err > 0) {
+ data += err;
+ size -= err;
+ err = 0;
+ }
+ }
+
+ if (revents & err_mask || !st->socket) {
+ dprintk("%s: revents: %x, socket: %p, size: %u, err: %d.\n",
+ __func__, revents, st->socket, size, err);
+ err = -ECONNRESET;
+ }
+
+ dst_state_unlock(st);
+
+ if (!n->trans_scan_timeout)
+ err = -ENODEV;
+ }
+
+ return err;
+}
+
+/*
+ * Send block autoconf reply.
+ */
+static int dst_process_cfg(struct dst_state *st)
+{
+ struct dst_node *n = st->node;
+ struct dst_cmd *cmd = st->data;
+ int err;
+
+ cmd->sector = n->size;
+ cmd->rw = st->permissions;
+
+ dst_convert_cmd(cmd);
+
+ dst_state_lock(st);
+ err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0);
+ dst_state_unlock(st);
+
+ return err;
+}
+
+/*
+ * Receive block IO from the network.
+ */
+static int dst_recv_bio(struct dst_state *st, struct bio *bio, unsigned int total_size)
+{
+ struct bio_vec *bv;
+ int i, err;
+ void *data;
+ unsigned int sz;
+
+ bio_for_each_segment(bv, bio, i) {
+ sz = min(total_size, bv->bv_len);
+
+ dprintk("%s: bio: %llu/%u, total: %u, len: %u, sz: %u, off: %u.\n",
+ __func__, (u64)bio->bi_sector, bio->bi_size, total_size,
+ bv->bv_len, sz, bv->bv_offset);
+
+ data = kmap(bv->bv_page) + bv->bv_offset;
+ err = dst_data_recv(st, data, sz);
+ kunmap(bv->bv_page);
+
+ bv->bv_len = sz;
+
+ if (err)
+ return err;
+
+ total_size -= sz;
+ if (total_size == 0)
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * Our block IO has just completed and arrived: get it.
+ */
+static int dst_process_io_response(struct dst_state *st)
+{
+ struct dst_node *n = st->node;
+ struct dst_cmd *cmd = st->data;
+ struct dst_trans *t;
+ int err = 0;
+ struct bio *bio;
+
+ mutex_lock(&n->trans_lock);
+ t = dst_trans_search(n, cmd->id);
+ mutex_unlock(&n->trans_lock);
+
+ if (!t)
+ goto err_out_exit;
+
+ bio = t->bio;
+
+ dprintk("%s: bio: %llu/%u, cmd_size: %u, csize: %u, dir: %lu.\n",
+ __func__, (u64)bio->bi_sector, bio->bi_size, cmd->size,
+ cmd->csize, bio_data_dir(bio));
+
+ if (bio_data_dir(bio) == READ) {
+ if (bio->bi_size != cmd->size - cmd->csize)
+ goto err_out_exit;
+
+ if (dst_need_crypto(n)) {
+ err = dst_recv_cdata(st, t->cmd.hash);
+ if (err)
+ goto err_out_exit;
+ }
+
+ err = dst_recv_bio(st, t->bio, bio->bi_size);
+ if (err)
+ goto err_out_exit;
+
+ if (dst_need_crypto(n))
+ return dst_trans_crypto(t);
+ } else {
+ err = -EBADMSG;
+ if (cmd->size || cmd->csize)
+ goto err_out_exit;
+ }
+
+ dst_trans_remove(t);
+ dst_trans_put(t);
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+/*
+ * Receive crypto data.
+ */
+int dst_recv_cdata(struct dst_state *st, void *cdata)
+{
+ struct dst_cmd *cmd = st->data;
+ struct dst_node *n = st->node;
+ struct dst_crypto_ctl *c = &n->crypto;
+ int err;
+
+ if (cmd->csize != c->crypto_attached_size) {
+ dprintk("%s: cmd: cmd: %u, sector: %llu, size: %u, "
+ "csize: %u != digest size %u.\n",
+ __func__, cmd->cmd, cmd->sector, cmd->size,
+ cmd->csize, c->crypto_attached_size);
+ err = -EINVAL;
+ goto err_out_exit;
+ }
+
+ err = dst_data_recv(st, cdata, cmd->csize);
+ if (err)
+ goto err_out_exit;
+
+ cmd->size -= cmd->csize;
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+/*
+ * Receive the command and start its processing.
+ */
+static int dst_recv_processing(struct dst_state *st)
+{
+ int err = -EINTR;
+ struct dst_cmd *cmd = st->data;
+
+ /*
+ * If socket will be reset after this statement, then
+ * dst_data_recv() will just fail and loop will
+ * start again, so it can be done without any locks.
+ *
+ * st->read_socket is needed to prevents state machine
+ * breaking between this data reading and subsequent one
+ * in protocol specific functions during connection reset.
+ * In case of reset we have to read next command and do
+ * not expect data for old command to magically appear in
+ * new connection.
+ */
+ st->read_socket = st->socket;
+ err = dst_data_recv(st, cmd, sizeof(struct dst_cmd));
+ if (err)
+ goto out_exit;
+
+ dst_convert_cmd(cmd);
+
+ dprintk("%s: cmd: %u, size: %u, csize: %u, id: %llu, "
+ "sector: %llu, flags: %llx, rw: %llx.\n",
+ __func__, cmd->cmd, cmd->size,
+ cmd->csize, cmd->id, cmd->sector,
+ cmd->flags, cmd->rw);
+
+ /*
+ * This should catch protocol breakage and random garbage instead of commands.
+ */
+ if (unlikely(cmd->csize > st->size - sizeof(struct dst_cmd))) {
+ err = -EBADMSG;
+ goto out_exit;
+ }
+
+ err = -EPROTO;
+ switch (cmd->cmd) {
+ case DST_IO_RESPONSE:
+ err = dst_process_io_response(st);
+ break;
+ case DST_IO:
+ err = dst_process_io(st);
+ break;
+ case DST_CFG:
+ err = dst_process_cfg(st);
+ break;
+ case DST_PING:
+ err = 0;
+ break;
+ default:
+ break;
+ }
+
+out_exit:
+ return err;
+}
+
+/*
+ * Receiving thread. For the client node we should try to reconnect,
+ * for accepted client we just drop the state and expect it to reconnect.
+ */
+static int dst_recv(void *init_data, void *schedule_data)
+{
+ struct dst_state *st = schedule_data;
+ struct dst_node *n = init_data;
+ int err = 0;
+
+ dprintk("%s: start st: %p, n: %p, scan: %lu, need_exit: %d.\n",
+ __func__, st, n, n->trans_scan_timeout, st->need_exit);
+
+ while (n->trans_scan_timeout && !st->need_exit) {
+ err = dst_recv_processing(st);
+ if (err < 0) {
+ if (!st->ctl.type)
+ break;
+
+ if (!n->trans_scan_timeout || st->need_exit)
+ break;
+
+ dst_state_reset(st);
+ msleep(1000);
+ }
+ }
+
+ st->need_exit = 1;
+ wake_up(&st->thread_wait);
+
+ dprintk("%s: freeing receiving socket st: %p.\n", __func__, st);
+ dst_state_lock(st);
+ dst_state_exit_connected(st);
+ dst_state_unlock(st);
+ dst_state_put(st);
+
+ dprintk("%s: freed receiving socket st: %p.\n", __func__, st);
+
+ return err;
+}
+
+/*
+ * Network state dies here and borns couple of lines below.
+ * This object is the main network state processing engine:
+ * sending, receiving, reconnections, all network related
+ * tasks are handled on behalf of the state.
+ */
+static void dst_state_free(struct dst_state *st)
+{
+ dprintk("%s: st: %p.\n", __func__, st);
+ if (st->cleanup)
+ st->cleanup(st);
+ kfree(st->data);
+ kfree(st);
+}
+
+struct dst_state *dst_state_alloc(struct dst_node *n)
+{
+ struct dst_state *st;
+ int err = -ENOMEM;
+
+ st = kzalloc(sizeof(struct dst_state), GFP_KERNEL);
+ if (!st)
+ goto err_out_exit;
+
+ st->node = n;
+ st->need_exit = 0;
+
+ st->size = PAGE_SIZE;
+ st->data = kmalloc(st->size, GFP_KERNEL);
+ if (!st->data)
+ goto err_out_free;
+
+ spin_lock_init(&st->request_lock);
+ INIT_LIST_HEAD(&st->request_list);
+
+ mutex_init(&st->state_lock);
+ init_waitqueue_head(&st->thread_wait);
+
+ /*
+ * One for processing thread, another one for node itself.
+ */
+ atomic_set(&st->refcnt, 2);
+
+ dprintk("%s: st: %p, n: %p.\n", __func__, st, st->node);
+
+ return st;
+
+err_out_free:
+ kfree(st);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+int dst_state_schedule_receiver(struct dst_state *st)
+{
+ return thread_pool_schedule_private(st->node->pool, dst_thread_setup,
+ dst_recv, st, MAX_SCHEDULE_TIMEOUT, st->node);
+}
+
+/*
+ * Initialize client's connection to the remote peer: allocate state,
+ * connect and perform block IO autoconfiguration.
+ */
+int dst_node_init_connected(struct dst_node *n, struct dst_network_ctl *r)
+{
+ struct dst_state *st;
+ int err = -ENOMEM;
+
+ st = dst_state_alloc(n);
+ if (IS_ERR(st)) {
+ err = PTR_ERR(st);
+ goto err_out_exit;
+ }
+ memcpy(&st->ctl, r, sizeof(struct dst_network_ctl));
+
+ err = dst_state_init_connected(st);
+ if (err)
+ goto err_out_free_data;
+
+ err = dst_request_remote_config(st);
+ if (err)
+ goto err_out_exit_connected;
+ n->state = st;
+
+ err = dst_state_schedule_receiver(st);
+ if (err)
+ goto err_out_exit_connected;
+
+ return 0;
+
+err_out_exit_connected:
+ dst_state_exit_connected(st);
+err_out_free_data:
+ dst_state_free(st);
+err_out_exit:
+ n->state = NULL;
+ return err;
+}
+
+void dst_state_put(struct dst_state *st)
+{
+ dprintk("%s: st: %p, refcnt: %d.\n",
+ __func__, st, atomic_read(&st->refcnt));
+ if (atomic_dec_and_test(&st->refcnt))
+ dst_state_free(st);
+}
+
+/*
+ * Send block IO to the network one by one using zero-copy ->sendpage().
+ */
+int dst_send_bio(struct dst_state *st, struct dst_cmd *cmd, struct bio *bio)
+{
+ struct bio_vec *bv;
+ struct dst_crypto_ctl *c = &st->node->crypto;
+ int err, i = 0;
+ int flags = MSG_WAITALL;
+
+ err = dst_data_send_header(st->socket, cmd,
+ sizeof(struct dst_cmd) + c->crypto_attached_size, bio->bi_vcnt);
+ if (err)
+ goto err_out_exit;
+
+ bio_for_each_segment(bv, bio, i) {
+ if (i < bio->bi_vcnt - 1)
+ flags |= MSG_MORE;
+
+ err = kernel_sendpage(st->socket, bv->bv_page, bv->bv_offset,
+ bv->bv_len, flags);
+ if (err <= 0)
+ goto err_out_exit;
+ }
+
+ return 0;
+
+err_out_exit:
+ dprintk("%s: %d/%d, flags: %x, err: %d.\n",
+ __func__, i, bio->bi_vcnt, flags, err);
+ return err;
+}
+
+/*
+ * Send transaction to the remote peer.
+ */
+int dst_trans_send(struct dst_trans *t)
+{
+ int err;
+ struct dst_state *st = t->n->state;
+ struct bio *bio = t->bio;
+
+ dst_convert_cmd(&t->cmd);
+
+ dst_state_lock(st);
+ if (!st->socket) {
+ err = dst_state_init_connected(st);
+ if (err)
+ goto err_out_unlock;
+ }
+
+ if (bio_data_dir(bio) == WRITE) {
+ err = dst_send_bio(st, &t->cmd, t->bio);
+ } else {
+ err = dst_data_send_header(st->socket, &t->cmd,
+ sizeof(struct dst_cmd), 0);
+ }
+ if (err)
+ goto err_out_reset;
+
+ dst_state_unlock(st);
+ return 0;
+
+err_out_reset:
+ dst_state_reset_nolock(st);
+err_out_unlock:
+ dst_state_unlock(st);
+
+ return err;
+}
diff --git a/drivers/staging/dst/thread_pool.c b/drivers/staging/dst/thread_pool.c
new file mode 100644
index 00000000000..7bed4e85102
--- /dev/null
+++ b/drivers/staging/dst/thread_pool.c
@@ -0,0 +1,345 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dst.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+
+/*
+ * Thread pool abstraction allows to schedule a work to be performed
+ * on behalf of kernel thread. One does not operate with threads itself,
+ * instead user provides setup and cleanup callbacks for thread pool itself,
+ * and action and cleanup callbacks for each submitted work.
+ *
+ * Each worker has private data initialized at creation time and data,
+ * provided by user at scheduling time.
+ *
+ * When action is being performed, thread can not be used by other users,
+ * instead they will sleep until there is free thread to pick their work.
+ */
+struct thread_pool_worker
+{
+ struct list_head worker_entry;
+
+ struct task_struct *thread;
+
+ struct thread_pool *pool;
+
+ int error;
+ int has_data;
+ int need_exit;
+ unsigned int id;
+
+ wait_queue_head_t wait;
+
+ void *private;
+ void *schedule_data;
+
+ int (* action)(void *private, void *schedule_data);
+ void (* cleanup)(void *private);
+};
+
+static void thread_pool_exit_worker(struct thread_pool_worker *w)
+{
+ kthread_stop(w->thread);
+
+ w->cleanup(w->private);
+ kfree(w);
+}
+
+/*
+ * Called to mark thread as ready and allow users to schedule new work.
+ */
+static void thread_pool_worker_make_ready(struct thread_pool_worker *w)
+{
+ struct thread_pool *p = w->pool;
+
+ mutex_lock(&p->thread_lock);
+
+ if (!w->need_exit) {
+ list_move_tail(&w->worker_entry, &p->ready_list);
+ w->has_data = 0;
+ mutex_unlock(&p->thread_lock);
+
+ wake_up(&p->wait);
+ } else {
+ p->thread_num--;
+ list_del(&w->worker_entry);
+ mutex_unlock(&p->thread_lock);
+
+ thread_pool_exit_worker(w);
+ }
+}
+
+/*
+ * Thread action loop: waits until there is new work.
+ */
+static int thread_pool_worker_func(void *data)
+{
+ struct thread_pool_worker *w = data;
+
+ while (!kthread_should_stop()) {
+ wait_event_interruptible(w->wait,
+ kthread_should_stop() || w->has_data);
+
+ if (kthread_should_stop())
+ break;
+
+ if (!w->has_data)
+ continue;
+
+ w->action(w->private, w->schedule_data);
+ thread_pool_worker_make_ready(w);
+ }
+
+ return 0;
+}
+
+/*
+ * Remove single worker without specifying which one.
+ */
+void thread_pool_del_worker(struct thread_pool *p)
+{
+ struct thread_pool_worker *w = NULL;
+
+ while (!w && p->thread_num) {
+ wait_event(p->wait, !list_empty(&p->ready_list) || !p->thread_num);
+
+ dprintk("%s: locking list_empty: %d, thread_num: %d.\n",
+ __func__, list_empty(&p->ready_list), p->thread_num);
+
+ mutex_lock(&p->thread_lock);
+ if (!list_empty(&p->ready_list)) {
+ w = list_first_entry(&p->ready_list,
+ struct thread_pool_worker,
+ worker_entry);
+
+ dprintk("%s: deleting w: %p, thread_num: %d, list: %p [%p.%p].\n",
+ __func__, w, p->thread_num, &p->ready_list,
+ p->ready_list.prev, p->ready_list.next);
+
+ p->thread_num--;
+ list_del(&w->worker_entry);
+ }
+ mutex_unlock(&p->thread_lock);
+ }
+
+ if (w)
+ thread_pool_exit_worker(w);
+ dprintk("%s: deleted w: %p, thread_num: %d.\n",
+ __func__, w, p->thread_num);
+}
+
+/*
+ * Remove a worker with given ID.
+ */
+void thread_pool_del_worker_id(struct thread_pool *p, unsigned int id)
+{
+ struct thread_pool_worker *w;
+ int found = 0;
+
+ mutex_lock(&p->thread_lock);
+ list_for_each_entry(w, &p->ready_list, worker_entry) {
+ if (w->id == id) {
+ found = 1;
+ p->thread_num--;
+ list_del(&w->worker_entry);
+ break;
+ }
+ }
+
+ if (!found) {
+ list_for_each_entry(w, &p->active_list, worker_entry) {
+ if (w->id == id) {
+ w->need_exit = 1;
+ break;
+ }
+ }
+ }
+ mutex_unlock(&p->thread_lock);
+
+ if (found)
+ thread_pool_exit_worker(w);
+}
+
+/*
+ * Add new worker thread with given parameters.
+ * If initialization callback fails, return error.
+ */
+int thread_pool_add_worker(struct thread_pool *p,
+ char *name,
+ unsigned int id,
+ void *(* init)(void *private),
+ void (* cleanup)(void *private),
+ void *private)
+{
+ struct thread_pool_worker *w;
+ int err = -ENOMEM;
+
+ w = kzalloc(sizeof(struct thread_pool_worker), GFP_KERNEL);
+ if (!w)
+ goto err_out_exit;
+
+ w->pool = p;
+ init_waitqueue_head(&w->wait);
+ w->cleanup = cleanup;
+ w->id = id;
+
+ w->thread = kthread_run(thread_pool_worker_func, w, "%s", name);
+ if (IS_ERR(w->thread)) {
+ err = PTR_ERR(w->thread);
+ goto err_out_free;
+ }
+
+ w->private = init(private);
+ if (IS_ERR(w->private)) {
+ err = PTR_ERR(w->private);
+ goto err_out_stop_thread;
+ }
+
+ mutex_lock(&p->thread_lock);
+ list_add_tail(&w->worker_entry, &p->ready_list);
+ p->thread_num++;
+ mutex_unlock(&p->thread_lock);
+
+ return 0;
+
+err_out_stop_thread:
+ kthread_stop(w->thread);
+err_out_free:
+ kfree(w);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Destroy the whole pool.
+ */
+void thread_pool_destroy(struct thread_pool *p)
+{
+ while (p->thread_num) {
+ dprintk("%s: num: %d.\n", __func__, p->thread_num);
+ thread_pool_del_worker(p);
+ }
+
+ kfree(p);
+}
+
+/*
+ * Create a pool with given number of threads.
+ * They will have sequential IDs started from zero.
+ */
+struct thread_pool *thread_pool_create(int num, char *name,
+ void *(* init)(void *private),
+ void (* cleanup)(void *private),
+ void *private)
+{
+ struct thread_pool_worker *w, *tmp;
+ struct thread_pool *p;
+ int err = -ENOMEM;
+ int i;
+
+ p = kzalloc(sizeof(struct thread_pool), GFP_KERNEL);
+ if (!p)
+ goto err_out_exit;
+
+ init_waitqueue_head(&p->wait);
+ mutex_init(&p->thread_lock);
+ INIT_LIST_HEAD(&p->ready_list);
+ INIT_LIST_HEAD(&p->active_list);
+ p->thread_num = 0;
+
+ for (i=0; i<num; ++i) {
+ err = thread_pool_add_worker(p, name, i, init,
+ cleanup, private);
+ if (err)
+ goto err_out_free_all;
+ }
+
+ return p;
+
+err_out_free_all:
+ list_for_each_entry_safe(w, tmp, &p->ready_list, worker_entry) {
+ list_del(&w->worker_entry);
+ thread_pool_exit_worker(w);
+ }
+ kfree(p);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+/*
+ * Schedule execution of the action on a given thread,
+ * provided ID pointer has to match previously stored
+ * private data.
+ */
+int thread_pool_schedule_private(struct thread_pool *p,
+ int (* setup)(void *private, void *data),
+ int (* action)(void *private, void *data),
+ void *data, long timeout, void *id)
+{
+ struct thread_pool_worker *w, *tmp, *worker = NULL;
+ int err = 0;
+
+ while (!worker && !err) {
+ timeout = wait_event_interruptible_timeout(p->wait,
+ !list_empty(&p->ready_list),
+ timeout);
+
+ if (!timeout) {
+ err = -ETIMEDOUT;
+ break;
+ }
+
+ worker = NULL;
+ mutex_lock(&p->thread_lock);
+ list_for_each_entry_safe(w, tmp, &p->ready_list, worker_entry) {
+ if (id && id != w->private)
+ continue;
+
+ worker = w;
+
+ list_move_tail(&w->worker_entry, &p->active_list);
+
+ err = setup(w->private, data);
+ if (!err) {
+ w->schedule_data = data;
+ w->action = action;
+ w->has_data = 1;
+ wake_up(&w->wait);
+ } else {
+ list_move_tail(&w->worker_entry, &p->ready_list);
+ }
+
+ break;
+ }
+ mutex_unlock(&p->thread_lock);
+ }
+
+ return err;
+}
+
+/*
+ * Schedule execution on arbitrary thread from the pool.
+ */
+int thread_pool_schedule(struct thread_pool *p,
+ int (* setup)(void *private, void *data),
+ int (* action)(void *private, void *data),
+ void *data, long timeout)
+{
+ return thread_pool_schedule_private(p, setup,
+ action, data, timeout, NULL);
+}
diff --git a/drivers/staging/dst/trans.c b/drivers/staging/dst/trans.c
new file mode 100644
index 00000000000..557d372a496
--- /dev/null
+++ b/drivers/staging/dst/trans.c
@@ -0,0 +1,335 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/bio.h>
+#include <linux/dst.h>
+#include <linux/slab.h>
+#include <linux/mempool.h>
+
+/*
+ * Transaction memory pool size.
+ */
+static int dst_mempool_num = 32;
+module_param(dst_mempool_num, int, 0644);
+
+/*
+ * Transaction tree management.
+ */
+static inline int dst_trans_cmp(dst_gen_t gen, dst_gen_t new)
+{
+ if (gen < new)
+ return 1;
+ if (gen > new)
+ return -1;
+ return 0;
+}
+
+struct dst_trans *dst_trans_search(struct dst_node *node, dst_gen_t gen)
+{
+ struct rb_root *root = &node->trans_root;
+ struct rb_node *n = root->rb_node;
+ struct dst_trans *t, *ret = NULL;
+ int cmp;
+
+ while (n) {
+ t = rb_entry(n, struct dst_trans, trans_entry);
+
+ cmp = dst_trans_cmp(t->gen, gen);
+ if (cmp < 0)
+ n = n->rb_left;
+ else if (cmp > 0)
+ n = n->rb_right;
+ else {
+ ret = t;
+ break;
+ }
+ }
+
+ dprintk("%s: %s transaction: id: %llu.\n", __func__,
+ (ret)?"found":"not found", gen);
+
+ return ret;
+}
+
+static int dst_trans_insert(struct dst_trans *new)
+{
+ struct rb_root *root = &new->n->trans_root;
+ struct rb_node **n = &root->rb_node, *parent = NULL;
+ struct dst_trans *ret = NULL, *t;
+ int cmp;
+
+ while (*n) {
+ parent = *n;
+
+ t = rb_entry(parent, struct dst_trans, trans_entry);
+
+ cmp = dst_trans_cmp(t->gen, new->gen);
+ if (cmp < 0)
+ n = &parent->rb_left;
+ else if (cmp > 0)
+ n = &parent->rb_right;
+ else {
+ ret = t;
+ break;
+ }
+ }
+
+ new->send_time = jiffies;
+ if (ret) {
+ printk("%s: exist: old: gen: %llu, bio: %llu/%u, send_time: %lu, "
+ "new: gen: %llu, bio: %llu/%u, send_time: %lu.\n",
+ __func__,
+ ret->gen, (u64)ret->bio->bi_sector,
+ ret->bio->bi_size, ret->send_time,
+ new->gen, (u64)new->bio->bi_sector,
+ new->bio->bi_size, new->send_time);
+ return -EEXIST;
+ }
+
+ rb_link_node(&new->trans_entry, parent, n);
+ rb_insert_color(&new->trans_entry, root);
+
+ dprintk("%s: inserted: gen: %llu, bio: %llu/%u, send_time: %lu.\n",
+ __func__, new->gen, (u64)new->bio->bi_sector,
+ new->bio->bi_size, new->send_time);
+
+ return 0;
+}
+
+int dst_trans_remove_nolock(struct dst_trans *t)
+{
+ struct dst_node *n = t->n;
+
+ if (t->trans_entry.rb_parent_color) {
+ rb_erase(&t->trans_entry, &n->trans_root);
+ t->trans_entry.rb_parent_color = 0;
+ }
+ return 0;
+}
+
+int dst_trans_remove(struct dst_trans *t)
+{
+ int ret;
+ struct dst_node *n = t->n;
+
+ mutex_lock(&n->trans_lock);
+ ret = dst_trans_remove_nolock(t);
+ mutex_unlock(&n->trans_lock);
+
+ return ret;
+}
+
+/*
+ * When transaction is completed and there are no more users,
+ * we complete appriate block IO request with given error status.
+ */
+void dst_trans_put(struct dst_trans *t)
+{
+ if (atomic_dec_and_test(&t->refcnt)) {
+ struct bio *bio = t->bio;
+
+ dprintk("%s: completed t: %p, gen: %llu, bio: %p.\n",
+ __func__, t, t->gen, bio);
+
+ bio_endio(bio, t->error);
+ bio_put(bio);
+
+ dst_node_put(t->n);
+ mempool_free(t, t->n->trans_pool);
+ }
+}
+
+/*
+ * Process given block IO request: allocate transaction, insert it into the tree
+ * and send/schedule crypto processing.
+ */
+int dst_process_bio(struct dst_node *n, struct bio *bio)
+{
+ struct dst_trans *t;
+ int err = -ENOMEM;
+
+ t = mempool_alloc(n->trans_pool, GFP_NOFS);
+ if (!t)
+ goto err_out_exit;
+
+ t->n = dst_node_get(n);
+ t->bio = bio;
+ t->error = 0;
+ t->retries = 0;
+ atomic_set(&t->refcnt, 1);
+ t->gen = atomic_long_inc_return(&n->gen);
+
+ t->enc = bio_data_dir(bio);
+ dst_bio_to_cmd(bio, &t->cmd, DST_IO, t->gen);
+
+ mutex_lock(&n->trans_lock);
+ err = dst_trans_insert(t);
+ mutex_unlock(&n->trans_lock);
+ if (err)
+ goto err_out_free;
+
+ dprintk("%s: gen: %llu, bio: %llu/%u, dir/enc: %d, need_crypto: %d.\n",
+ __func__, t->gen, (u64)bio->bi_sector,
+ bio->bi_size, t->enc, dst_need_crypto(n));
+
+ if (dst_need_crypto(n) && t->enc)
+ dst_trans_crypto(t);
+ else
+ dst_trans_send(t);
+
+ return 0;
+
+err_out_free:
+ dst_node_put(n);
+ mempool_free(t, n->trans_pool);
+err_out_exit:
+ bio_endio(bio, err);
+ bio_put(bio);
+ return err;
+}
+
+/*
+ * Scan for timeout/stale transactions.
+ * Each transaction is being resent multiple times before error completion.
+ */
+static void dst_trans_scan(struct work_struct *work)
+{
+ struct dst_node *n = container_of(work, struct dst_node, trans_work.work);
+ struct rb_node *rb_node;
+ struct dst_trans *t;
+ unsigned long timeout = n->trans_scan_timeout;
+ int num = 10 * n->trans_max_retries;
+
+ mutex_lock(&n->trans_lock);
+
+ for (rb_node = rb_first(&n->trans_root); rb_node; ) {
+ t = rb_entry(rb_node, struct dst_trans, trans_entry);
+
+ if (timeout && time_after(t->send_time + timeout, jiffies)
+ && t->retries == 0)
+ break;
+#if 0
+ dprintk("%s: t: %p, gen: %llu, n: %s, retries: %u, max: %u.\n",
+ __func__, t, t->gen, n->name,
+ t->retries, n->trans_max_retries);
+#endif
+ if (--num == 0)
+ break;
+
+ dst_trans_get(t);
+
+ rb_node = rb_next(rb_node);
+
+ if (timeout && (++t->retries < n->trans_max_retries)) {
+ dst_trans_send(t);
+ } else {
+ t->error = -ETIMEDOUT;
+ dst_trans_remove_nolock(t);
+ dst_trans_put(t);
+ }
+
+ dst_trans_put(t);
+ }
+
+ mutex_unlock(&n->trans_lock);
+
+ /*
+ * If no timeout specified then system is in the middle of exiting process,
+ * so no need to reschedule scanning process again.
+ */
+ if (timeout) {
+ if (!num)
+ timeout = HZ;
+ schedule_delayed_work(&n->trans_work, timeout);
+ }
+}
+
+/*
+ * Flush all transactions and mark them as timed out.
+ * Destroy transaction pools.
+ */
+void dst_node_trans_exit(struct dst_node *n)
+{
+ struct dst_trans *t;
+ struct rb_node *rb_node;
+
+ if (!n->trans_cache)
+ return;
+
+ dprintk("%s: n: %p, cancelling the work.\n", __func__, n);
+ cancel_delayed_work_sync(&n->trans_work);
+ flush_scheduled_work();
+ dprintk("%s: n: %p, work has been cancelled.\n", __func__, n);
+
+ for (rb_node = rb_first(&n->trans_root); rb_node; ) {
+ t = rb_entry(rb_node, struct dst_trans, trans_entry);
+
+ dprintk("%s: t: %p, gen: %llu, n: %s.\n",
+ __func__, t, t->gen, n->name);
+
+ rb_node = rb_next(rb_node);
+
+ t->error = -ETIMEDOUT;
+ dst_trans_remove_nolock(t);
+ dst_trans_put(t);
+ }
+
+ mempool_destroy(n->trans_pool);
+ kmem_cache_destroy(n->trans_cache);
+}
+
+/*
+ * Initialize transaction storage for given node.
+ * Transaction stores not only control information,
+ * but also network command and crypto data (if needed)
+ * to reduce number of allocations. Thus transaction size
+ * differs from node to node.
+ */
+int dst_node_trans_init(struct dst_node *n, unsigned int size)
+{
+ /*
+ * We need this, since node with given name can be dropped from the
+ * hash table, but be still alive, so subsequent creation of the node
+ * with the same name may collide with existing cache name.
+ */
+
+ snprintf(n->cache_name, sizeof(n->cache_name), "%s-%p", n->name, n);
+
+ n->trans_cache = kmem_cache_create(n->cache_name,
+ size + n->crypto.crypto_attached_size,
+ 0, 0, NULL);
+ if (!n->trans_cache)
+ goto err_out_exit;
+
+ n->trans_pool = mempool_create_slab_pool(dst_mempool_num, n->trans_cache);
+ if (!n->trans_pool)
+ goto err_out_cache_destroy;
+
+ mutex_init(&n->trans_lock);
+ n->trans_root = RB_ROOT;
+
+ INIT_DELAYED_WORK(&n->trans_work, dst_trans_scan);
+ schedule_delayed_work(&n->trans_work, n->trans_scan_timeout);
+
+ dprintk("%s: n: %p, size: %u, crypto: %u.\n",
+ __func__, n, size, n->crypto.crypto_attached_size);
+
+ return 0;
+
+err_out_cache_destroy:
+ kmem_cache_destroy(n->trans_cache);
+err_out_exit:
+ return -ENOMEM;
+}
diff --git a/drivers/staging/echo/bit_operations.h b/drivers/staging/echo/bit_operations.h
index cecdcf3fd75..4c4ccbc9731 100644
--- a/drivers/staging/echo/bit_operations.h
+++ b/drivers/staging/echo/bit_operations.h
@@ -21,8 +21,6 @@
* 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 */
@@ -34,7 +32,7 @@
/*! \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)
+static inline int top_bit(unsigned int bits)
{
int res;
@@ -50,7 +48,7 @@ static __inline__ int top_bit(unsigned int bits)
/*! \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)
+static inline int bottom_bit(unsigned int bits)
{
int res;
@@ -63,7 +61,7 @@ static __inline__ int bottom_bit(unsigned int bits)
return res;
}
#else
-static __inline__ int top_bit(unsigned int bits)
+static inline int top_bit(unsigned int bits)
{
int i;
@@ -93,7 +91,7 @@ static __inline__ int top_bit(unsigned int bits)
return i;
}
-static __inline__ int bottom_bit(unsigned int bits)
+static inline int bottom_bit(unsigned int bits)
{
int i;
@@ -127,7 +125,7 @@ static __inline__ int bottom_bit(unsigned int bits)
/*! \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)
+static inline uint8_t bit_reverse8(uint8_t x)
{
#if defined(__i386__) || defined(__x86_64__)
/* If multiply is fast */
@@ -172,32 +170,32 @@ uint32_t make_mask32(uint32_t x);
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.
+ 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)
+static inline uint32_t least_significant_one32(uint32_t x)
{
- return (x & (-(int32_t) x));
+ return x & (-(int32_t) x);
}
/*! \brief Find the most significant one in a word, and return a word
- with just that bit set.
+ 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)
+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));
+ return x ^ (x >> 1);
#endif
}
/*! \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)
+static inline int parity8(uint8_t x)
{
x = (x ^ (x >> 4)) & 0x0F;
return (0x6996 >> x) & 1;
@@ -206,7 +204,7 @@ static __inline__ int parity8(uint8_t x)
/*! \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)
+static inline int parity16(uint16_t x)
{
x ^= (x >> 8);
x = (x ^ (x >> 4)) & 0x0F;
@@ -216,7 +214,7 @@ static __inline__ int parity16(uint16_t x)
/*! \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)
+static inline int parity32(uint32_t x)
{
x ^= (x >> 16);
x ^= (x >> 8);
diff --git a/drivers/staging/echo/echo.c b/drivers/staging/echo/echo.c
index fd4007e329e..6d7217e1bd0 100644
--- a/drivers/staging/echo/echo.c
+++ b/drivers/staging/echo/echo.c
@@ -27,8 +27,6 @@
* 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 */
@@ -113,17 +111,17 @@
#define MIN_TX_POWER_FOR_ADAPTION 64
#define MIN_RX_POWER_FOR_ADAPTION 64
-#define DTD_HANGOVER 600 /* 600 samples, or 75ms */
-#define DC_LOG2BETA 3 /* log2() of DC filter Beta */
+#define DTD_HANGOVER 600 /* 600 samples, or 75ms */
+#define DC_LOG2BETA 3 /* log2() of DC filter Beta */
/*-----------------------------------------------------------------------*\
- FUNCTIONS
+ FUNCTIONS
\*-----------------------------------------------------------------------*/
/* adapting coeffs using the traditional stochastic descent (N)LMS algorithm */
#ifdef __bfin__
-static void __inline__ lms_adapt_bg(struct oslec_state *ec, int clean,
+static inline void lms_adapt_bg(struct oslec_state *ec, int clean,
int shift)
{
int i, j;
@@ -147,13 +145,13 @@ static void __inline__ lms_adapt_bg(struct oslec_state *ec, int clean,
/* st: and en: help us locate the assembler in echo.s */
- //asm("st:");
+ /* 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:");
+ /* 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):
@@ -195,7 +193,7 @@ static void __inline__ lms_adapt_bg(struct oslec_state *ec, int clean,
*/
#else
-static __inline__ void lms_adapt_bg(struct oslec_state *ec, int clean,
+static inline void lms_adapt_bg(struct oslec_state *ec, int clean,
int shift)
{
int i;
@@ -249,9 +247,8 @@ struct oslec_state *oslec_create(int len, int adaption_mode)
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++) {
+ for (i = 0; i < 5; i++)
ec->xvtx[i] = ec->yvtx[i] = ec->xvrx[i] = ec->yvrx[i] = 0;
- }
ec->cng_level = 1000;
oslec_adaption_mode(ec, adaption_mode);
@@ -271,14 +268,13 @@ struct oslec_state *oslec_create(int len, int adaption_mode)
return ec;
- error_oom:
+error_oom:
for (i = 0; i < 2; i++)
kfree(ec->fir_taps16[i]);
kfree(ec);
return NULL;
}
-
EXPORT_SYMBOL_GPL(oslec_create);
void oslec_free(struct oslec_state *ec)
@@ -292,14 +288,12 @@ void oslec_free(struct oslec_state *ec)
kfree(ec->snapshot);
kfree(ec);
}
-
EXPORT_SYMBOL_GPL(oslec_free);
void oslec_adaption_mode(struct oslec_state *ec, int adaption_mode)
{
ec->adaption_mode = adaption_mode;
}
-
EXPORT_SYMBOL_GPL(oslec_adaption_mode);
void oslec_flush(struct oslec_state *ec)
@@ -326,14 +320,12 @@ void oslec_flush(struct oslec_state *ec)
ec->curr_pos = ec->taps - 1;
ec->Pstates = 0;
}
-
EXPORT_SYMBOL_GPL(oslec_flush);
void oslec_snapshot(struct oslec_state *ec)
{
memcpy(ec->snapshot, ec->fir_taps16[0], ec->taps * sizeof(int16_t));
}
-
EXPORT_SYMBOL_GPL(oslec_snapshot);
/* Dual Path Echo Canceller ------------------------------------------------*/
@@ -399,7 +391,7 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
/* 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;
+ 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 +=
@@ -498,15 +490,15 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
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) */ ) {
+ /* (ec->Lclean_bg < 0.875*ec->Lclean) */
+ (8 * ec->Lclean_bg < 7 * ec->Lclean) &&
+ /* (ec->Lclean_bg < 0.125*ec->Ltx) */
+ (8 * ec->Lclean_bg < 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));
+ ec->taps * sizeof(int16_t));
} else
ec->cond_met++;
} else
@@ -580,7 +572,6 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
return (int16_t) ec->clean_nlp << 1;
}
-
EXPORT_SYMBOL_GPL(oslec_update);
/* This function is seperated from the echo canceller is it is usually called
@@ -604,7 +595,7 @@ EXPORT_SYMBOL_GPL(oslec_update);
precision, which noise shapes things, giving very clean DC removal.
*/
-int16_t oslec_hpf_tx(struct oslec_state * ec, int16_t tx)
+int16_t oslec_hpf_tx(struct oslec_state *ec, int16_t tx)
{
int tmp, tmp1;
@@ -629,7 +620,6 @@ int16_t oslec_hpf_tx(struct oslec_state * ec, int16_t tx)
return tx;
}
-
EXPORT_SYMBOL_GPL(oslec_hpf_tx);
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/echo/echo.h b/drivers/staging/echo/echo.h
index 34fb816b15c..c835e5c5314 100644
--- a/drivers/staging/echo/echo.h
+++ b/drivers/staging/echo/echo.h
@@ -23,8 +23,6 @@
* 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
diff --git a/drivers/staging/echo/fir.h b/drivers/staging/echo/fir.h
index d35f16805f4..ac6c553e89f 100644
--- a/drivers/staging/echo/fir.h
+++ b/drivers/staging/echo/fir.h
@@ -21,8 +21,6 @@
* 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
@@ -102,8 +100,8 @@ struct fir_float_state_t {
float *history;
};
-static __inline__ const int16_t *fir16_create(struct fir16_state_t *fir,
- const int16_t * coeffs, int taps)
+static inline const int16_t *fir16_create(struct fir16_state_t *fir,
+ const int16_t *coeffs, int taps)
{
fir->taps = taps;
fir->curr_pos = taps - 1;
@@ -116,7 +114,7 @@ static __inline__ const int16_t *fir16_create(struct fir16_state_t *fir,
return fir->history;
}
-static __inline__ void fir16_flush(struct fir16_state_t *fir)
+static inline void fir16_flush(struct fir16_state_t *fir)
{
#if defined(USE_MMX) || defined(USE_SSE2) || defined(__bfin__)
memset(fir->history, 0, 2 * fir->taps * sizeof(int16_t));
@@ -125,7 +123,7 @@ static __inline__ void fir16_flush(struct fir16_state_t *fir)
#endif
}
-static __inline__ void fir16_free(struct fir16_state_t *fir)
+static inline void fir16_free(struct fir16_state_t *fir)
{
kfree(fir->history);
}
@@ -148,16 +146,16 @@ static inline int32_t dot_asm(short *x, short *y, int len)
"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"
+ : "=&d"(dot)
+ : "a"(x), "a"(y), "a"(len)
+ : "I0", "I1", "A1", "A0", "R0", "R1"
);
return dot;
}
#endif
-static __inline__ int16_t fir16(struct fir16_state_t *fir, int16_t sample)
+static inline int16_t fir16(struct fir16_state_t *fir, int16_t sample)
{
int32_t y;
#if defined(USE_MMX)
@@ -250,8 +248,8 @@ static __inline__ int16_t fir16(struct fir16_state_t *fir, int16_t sample)
return (int16_t) (y >> 15);
}
-static __inline__ const int16_t *fir32_create(struct fir32_state_t *fir,
- const int32_t * coeffs, int taps)
+static inline const int16_t *fir32_create(struct fir32_state_t *fir,
+ const int32_t *coeffs, int taps)
{
fir->taps = taps;
fir->curr_pos = taps - 1;
@@ -260,17 +258,17 @@ static __inline__ const int16_t *fir32_create(struct fir32_state_t *fir,
return fir->history;
}
-static __inline__ void fir32_flush(struct fir32_state_t *fir)
+static inline void fir32_flush(struct fir32_state_t *fir)
{
memset(fir->history, 0, fir->taps * sizeof(int16_t));
}
-static __inline__ void fir32_free(struct fir32_state_t *fir)
+static inline void fir32_free(struct fir32_state_t *fir)
{
kfree(fir->history);
}
-static __inline__ int16_t fir32(struct fir32_state_t *fir, int16_t sample)
+static inline int16_t fir32(struct fir32_state_t *fir, int16_t sample)
{
int i;
int32_t y;
diff --git a/drivers/staging/echo/mmx.h b/drivers/staging/echo/mmx.h
index 44e5cfebc18..c1dcd7299cb 100644
--- a/drivers/staging/echo/mmx.h
+++ b/drivers/staging/echo/mmx.h
@@ -44,238 +44,238 @@ union xmm_t {
char b[16];
};
-#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)
+#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)
+#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_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 mmx_fetch(mem, hint) \
+ __asm__ __volatile__ ("prefetch" #hint " %0" \
+ : /* nothing */ \
+ : "m" (mem))
-#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg)
+#define maskmovq(regs, maskreg) mmx_r2ri(maskmovq, regs, maskreg)
-#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var)
+#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 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 pextrw_r2r(mmreg, reg, imm) mmx_r2ri(pextrw, mmreg, reg, imm)
-#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, 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 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 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 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 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 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 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 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 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 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")
+#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 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 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 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 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 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)
+#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/epl/Benchmark.h b/drivers/staging/epl/Benchmark.h
index 62dee3b1437..4cc01bd12a1 100644
--- a/drivers/staging/epl/Benchmark.h
+++ b/drivers/staging/epl/Benchmark.h
@@ -73,12 +73,6 @@
#include "global.h"
-#if (TARGET_SYSTEM == _NO_OS_) && (DEV_SYSTEM == _DEV_GNU_CF548X_)
-#include "common.h"
-
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
-
-// #include <linux/config.h>
#include <linux/kernel.h>
#ifdef CONFIG_COLDFIRE
@@ -93,12 +87,6 @@
#define BENCHMARK_MODULES 0x00000000
#endif
-#else
- // disable Benchmarking
-#undef BENCHMARK_MODULES
-#define BENCHMARK_MODULES 0x00000000
-#endif
-
/***************************************************************************/
/* */
/* */
diff --git a/drivers/staging/epl/Debug.h b/drivers/staging/epl/Debug.h
index 05de9d541fd..851a22213ad 100644
--- a/drivers/staging/epl/Debug.h
+++ b/drivers/staging/epl/Debug.h
@@ -163,25 +163,6 @@
#endif
//---------------------------------------------------------------------------
-#if (DEV_SYSTEM == _DEV_WIN32_) && defined (TRACE_MSG)
-
- // For WIN32 the macro DEBUG_TRACE0 can be defined as function call TraceLvl()
- // or as macro TRACE().
- //
- // Here the parameter 'lvl' can be used with more than one
- // debug-level (using OR).
- //
- // Example: DEBUG_TRACE1(DEBUG_LVL_30 | DEBUG_LVL_02, "Hello %d", bCount);
-
-#define DEBUG_TRACE0(lvl,str) TraceLvl((lvl),str)
-#define DEBUG_TRACE1(lvl,str,p1) TraceLvl((lvl),str,p1)
-#define DEBUG_TRACE2(lvl,str,p1,p2) TraceLvl((lvl),str,p1,p2)
-#define DEBUG_TRACE3(lvl,str,p1,p2,p3) TraceLvl((lvl),str,p1,p2,p3)
-#define DEBUG_TRACE4(lvl,str,p1,p2,p3,p4) TraceLvl((lvl),str,p1,p2,p3,p4)
-#define DEBUG_GLB_LVL() dwDebugLevel_g
-
-#else
-
// At microcontrollers we do reduce the memory usage by deleting DEBUG_TRACE-lines
// (compiler does delete the lines).
//
@@ -643,25 +624,23 @@
#define DEBUG_TRACE3(lvl,str,p1,p2,p3) lvl##_TRACE3(str,p1,p2,p3)
#define DEBUG_TRACE4(lvl,str,p1,p2,p3,p4) lvl##_TRACE4(str,p1,p2,p3,p4)
-#endif
-
//---------------------------------------------------------------------------
// The macro DEBUG_DUMP_DATA() can be used with the same debug-levels to dump
// out data bytes. Function DumpData() has to be included.
// NOTE: DUMP_DATA has to be defined in project settings.
-#if (!defined (NDEBUG) && defined (DUMP_DATA)) || (DEV_SYSTEM == _DEV_WIN32_)
+#if (!defined (NDEBUG) && defined (DUMP_DATA))
#ifdef __cplusplus
extern "C" {
#endif
- void DumpData(char *szStr_p, BYTE MEM * pbData_p, WORD wSize_p);
+ void DumpData(char *szStr_p, u8 *pbData_p, u16 wSize_p);
#ifdef __cplusplus
} // von extern "C"
#endif
#define DEBUG_DUMP_DATA(lvl,str,ptr,siz) if ((DEBUG_GLB_LVL() & (lvl))==(lvl)) \
- DumpData (str, (BYTE MEM*) (ptr), (WORD) (siz));
+ DumpData (str, (u8 *)(ptr), (u16)(siz));
#else
#define DEBUG_DUMP_DATA(lvl,str,ptr,siz)
@@ -675,24 +654,6 @@ extern "C" {
// deleted from compiler (in release version too).
#if !defined (NDEBUG) || defined (DEBUG_KEEP_ASSERT)
-#if (DEV_SYSTEM == _DEV_WIN32_)
-
- // For WIN32 process will be killed after closing message box.
-
-#define DEBUG_ASSERT0(expr,str) if (!(expr ) && ((DEBUG_GLB_LVL() & DEBUG_LVL_ASSERT)!=0)) { \
- MessageBox (NULL, \
- "Assertion failed: line " __LINE__ " file " __FILE__ \
- "\n -> " str "\n"); \
- ExitProcess (-1); }
-
-#define DEBUG_ASSERT1(expr,str,p1) if (!(expr ) && ((DEBUG_GLB_LVL() & DEBUG_LVL_ASSERT)!=0)) { \
- MessageBox (NULL, \
- "Assertion failed: line " __LINE__ " file " __FILE__ \
- "\n -> " str "\n"); \
- ExitProcess (-1); }
-
-#else
-
// For microcontrollers process will be stopped using endless loop.
#define DEBUG_ASSERT0(expr,str) if (!(expr )) { \
@@ -705,10 +666,9 @@ extern "C" {
DEBUG_LVL_ASSERT_TRACE4 ( \
"Assertion failed: line %d file '%s'\n" \
" -> '%s'\n" \
- " -> 0x%08lX\n", __LINE__, __FILE__, str, (DWORD) p1); \
+ " -> 0x%08lX\n", __LINE__, __FILE__, str, (u32) p1); \
while (1); }
-#endif
#else
diff --git a/drivers/staging/epl/Edrv8139.c b/drivers/staging/epl/Edrv8139.c
index 296354aaa9c..44e3f7b144b 100644
--- a/drivers/staging/epl/Edrv8139.c
+++ b/drivers/staging/epl/Edrv8139.c
@@ -81,7 +81,6 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/major.h>
-#include <linux/version.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
@@ -234,8 +233,8 @@
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -282,9 +281,9 @@ typedef struct
typedef struct {
struct pci_dev *m_pPciDev; // pointer to PCI device structure
void *m_pIoAddr; // pointer to register space of Ethernet controller
- BYTE *m_pbRxBuf; // pointer to Rx buffer
+ u8 *m_pbRxBuf; // pointer to Rx buffer
dma_addr_t m_pRxBufDma;
- BYTE *m_pbTxBuf; // pointer to Tx buffer
+ u8 *m_pbTxBuf; // pointer to Tx buffer
dma_addr_t m_pTxBufDma;
BOOL m_afTxBufUsed[EDRV_MAX_TX_BUFFERS];
unsigned int m_uiCurTxDesc;
@@ -359,7 +358,7 @@ static struct pci_driver EdrvDriver = {
// local function prototypes
//---------------------------------------------------------------------------
-static BYTE EdrvCalcHash(BYTE * pbMAC_p);
+static u8 EdrvCalcHash(u8 * pbMAC_p);
//---------------------------------------------------------------------------
//
@@ -453,20 +452,20 @@ tEplKernel EdrvShutdown(void)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel EdrvDefineRxMacAddrEntry(BYTE * pbMacAddr_p)
+tEplKernel EdrvDefineRxMacAddrEntry(u8 * pbMacAddr_p)
{
tEplKernel Ret = kEplSuccessful;
- DWORD dwData;
- BYTE bHash;
+ u32 dwData;
+ u8 bHash;
bHash = EdrvCalcHash(pbMacAddr_p);
/*
dwData = ether_crc(6, pbMacAddr_p);
printk("EdrvDefineRxMacAddrEntry('%02X:%02X:%02X:%02X:%02X:%02X') hash = %u / %u ether_crc = 0x%08lX\n",
- (WORD) pbMacAddr_p[0], (WORD) pbMacAddr_p[1], (WORD) pbMacAddr_p[2],
- (WORD) pbMacAddr_p[3], (WORD) pbMacAddr_p[4], (WORD) pbMacAddr_p[5],
- (WORD) bHash, (WORD) (dwData >> 26), dwData);
+ (u16) pbMacAddr_p[0], (u16) pbMacAddr_p[1], (u16) pbMacAddr_p[2],
+ (u16) pbMacAddr_p[3], (u16) pbMacAddr_p[4], (u16) pbMacAddr_p[5],
+ (u16) bHash, (u16) (dwData >> 26), dwData);
*/
if (bHash > 31) {
dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR4);
@@ -494,11 +493,11 @@ tEplKernel EdrvDefineRxMacAddrEntry(BYTE * pbMacAddr_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel EdrvUndefineRxMacAddrEntry(BYTE * pbMacAddr_p)
+tEplKernel EdrvUndefineRxMacAddrEntry(u8 * pbMacAddr_p)
{
tEplKernel Ret = kEplSuccessful;
- DWORD dwData;
- BYTE bHash;
+ u32 dwData;
+ u8 bHash;
bHash = EdrvCalcHash(pbMacAddr_p);
@@ -532,7 +531,7 @@ tEplKernel EdrvUndefineRxMacAddrEntry(BYTE * pbMacAddr_p)
tEplKernel EdrvAllocTxMsgBuffer(tEdrvTxBuffer * pBuffer_p)
{
tEplKernel Ret = kEplSuccessful;
- DWORD i;
+ u32 i;
if (pBuffer_p->m_uiMaxBufferLen > EDRV_MAX_FRAME_SIZE) {
Ret = kEplEdrvNoFreeBufEntry;
@@ -605,7 +604,7 @@ tEplKernel EdrvSendTxMsg(tEdrvTxBuffer * pBuffer_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiBufferNumber;
- DWORD dwTemp;
+ u32 dwTemp;
uiBufferNumber = pBuffer_p->m_uiBufferNumber;
@@ -620,11 +619,11 @@ tEplKernel EdrvSendTxMsg(tEdrvTxBuffer * pBuffer_p)
dwTemp =
EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
(EdrvInstance_l.m_uiCurTxDesc *
- sizeof(DWORD))));
- printk("%s InvOp TSD%u = 0x%08lX", __func__,
+ sizeof(u32))));
+ printk("%s InvOp TSD%u = 0x%08X", __func__,
EdrvInstance_l.m_uiCurTxDesc, dwTemp);
printk(" Cmd = 0x%02X\n",
- (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+ (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
goto Exit;
}
// save pointer to buffer structure for TxHandler
@@ -640,22 +639,22 @@ tEplKernel EdrvSendTxMsg(tEdrvTxBuffer * pBuffer_p)
}
// set DMA address of buffer
EDRV_REGDW_WRITE((EDRV_REGDW_TSAD0 +
- (EdrvInstance_l.m_uiCurTxDesc * sizeof(DWORD))),
+ (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))),
(EdrvInstance_l.m_pTxBufDma +
(uiBufferNumber * EDRV_MAX_FRAME_SIZE)));
dwTemp =
EDRV_REGDW_READ((EDRV_REGDW_TSAD0 +
- (EdrvInstance_l.m_uiCurTxDesc * sizeof(DWORD))));
+ (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))));
// printk("%s TSAD%u = 0x%08lX", __func__, EdrvInstance_l.m_uiCurTxDesc, dwTemp);
// start transmission
EDRV_REGDW_WRITE((EDRV_REGDW_TSD0 +
- (EdrvInstance_l.m_uiCurTxDesc * sizeof(DWORD))),
+ (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))),
(EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
dwTemp =
EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
- (EdrvInstance_l.m_uiCurTxDesc * sizeof(DWORD))));
-// printk(" TSD%u = 0x%08lX / 0x%08lX\n", EdrvInstance_l.m_uiCurTxDesc, dwTemp, (DWORD)(EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
+ (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))));
+// printk(" TSD%u = 0x%08lX / 0x%08lX\n", EdrvInstance_l.m_uiCurTxDesc, dwTemp, (u32)(EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
Exit:
return Ret;
@@ -720,7 +719,7 @@ tEplKernel EdrvTxMsgStart(tEdrvTxBuffer * pBuffer_p)
//---------------------------------------------------------------------------
static void EdrvReinitRx(void)
{
- BYTE bCmd;
+ u8 bCmd;
// simply switch off and on the receiver
// this will reset the CAPR register
@@ -751,21 +750,16 @@ void EdrvInterruptHandler(void)
}
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p)
-#else
-static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p,
- struct pt_regs *ptRegs_p)
-#endif
{
// EdrvInterruptHandler();
tEdrvRxBuffer RxBuffer;
tEdrvTxBuffer *pTxBuffer;
- WORD wStatus;
- DWORD dwTxStatus;
- DWORD dwRxStatus;
- WORD wCurRx;
- BYTE *pbRxBuf;
+ u16 wStatus;
+ u32 dwTxStatus;
+ u32 dwRxStatus;
+ u16 wCurRx;
+ u8 *pbRxBuf;
unsigned int uiLength;
int iHandled = IRQ_HANDLED;
@@ -793,7 +787,7 @@ static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p,
dwTxStatus =
EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
(EdrvInstance_l.m_uiCurTxDesc *
- sizeof(DWORD))));
+ sizeof(u32))));
if ((dwTxStatus & (EDRV_REGDW_TSD_TOK | EDRV_REGDW_TSD_TABT | EDRV_REGDW_TSD_TUN)) != 0) { // transmit finished
EdrvInstance_l.m_uiCurTxDesc =
(EdrvInstance_l.m_uiCurTxDesc + 1) & 0x03;
@@ -855,8 +849,8 @@ static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p,
// calculate pointer to current frame in receive buffer
pbRxBuf = EdrvInstance_l.m_pbRxBuf + wCurRx;
- // read receive status DWORD
- dwRxStatus = le32_to_cpu(*((DWORD *) pbRxBuf));
+ // read receive status u32
+ dwRxStatus = le32_to_cpu(*((u32 *) pbRxBuf));
// calculate length of received frame
uiLength = dwRxStatus >> 16;
@@ -896,9 +890,9 @@ static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p,
m_pfnRxHandler(&RxBuffer);
}
- // calulate new offset (DWORD aligned)
+ // calulate new offset (u32 aligned)
wCurRx =
- (WORD) ((wCurRx + uiLength + sizeof(dwRxStatus) +
+ (u16) ((wCurRx + uiLength + sizeof(dwRxStatus) +
3) & ~0x3);
EDRV_TRACE_CAPR(wCurRx - 0x10);
EDRV_REGW_WRITE(EDRV_REGW_CAPR, wCurRx - 0x10);
@@ -941,7 +935,7 @@ static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p,
static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
{
int iResult = 0;
- DWORD dwTemp;
+ u32 dwTemp;
if (EdrvInstance_l.m_pPciDev != NULL) { // Edrv is already connected to a PCI device
printk("%s device %s discarded\n", __func__,
@@ -1008,7 +1002,7 @@ static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TCR);
if (((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_C)
&& ((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_D)) { // unsupported chip
- printk("%s Unsupported chip! TCR = 0x%08lX\n", __func__,
+ printk("%s Unsupported chip! TCR = 0x%08X\n", __func__,
dwTemp);
iResult = -ENODEV;
goto Exit;
@@ -1043,11 +1037,11 @@ static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
printk("%s set local MAC address\n", __func__);
// write this MAC address to controller
EDRV_REGDW_WRITE(EDRV_REGDW_IDR0,
- le32_to_cpu(*((DWORD*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[0])));
+ le32_to_cpu(*((u32*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[0])));
dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR0);
EDRV_REGDW_WRITE(EDRV_REGDW_IDR4,
- le32_to_cpu(*((DWORD*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[4])));
+ le32_to_cpu(*((u32*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[4])));
dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR4);
break;
}
@@ -1087,7 +1081,7 @@ static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD3);
printk(" Command = 0x%02X\n",
- (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+ (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
// set pointer for receive buffer in controller
printk("%s set pointer to Rx buffer\n", __func__);
@@ -1098,7 +1092,7 @@ static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
EDRV_REGB_WRITE(EDRV_REGB_COMMAND,
(EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE));
printk(" Command = 0x%02X\n",
- (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+ (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
// clear missed packet counter to enable Rx/Tx process
EDRV_REGDW_WRITE(EDRV_REGDW_MPC, 0);
@@ -1123,7 +1117,7 @@ static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
// enable transmitter and receiver
printk("%s enable Tx and Rx", __func__);
EDRV_REGB_WRITE(EDRV_REGB_COMMAND, (EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE));
- printk(" Command = 0x%02X\n", (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+ printk(" Command = 0x%02X\n", (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
*/
// disable early interrupts
EDRV_REGW_WRITE(EDRV_REGW_MULINT, 0);
@@ -1215,15 +1209,15 @@ static void EdrvRemoveOne(struct pci_dev *pPciDev)
//#define CRC32_POLY 0xEDB88320 //
// G(x) = x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
-static BYTE EdrvCalcHash(BYTE * pbMAC_p)
+static u8 EdrvCalcHash(u8 * pbMAC_p)
{
- DWORD dwByteCounter;
- DWORD dwBitCounter;
- DWORD dwData;
- DWORD dwCrc;
- DWORD dwCarry;
- BYTE *pbData;
- BYTE bHash;
+ u32 dwByteCounter;
+ u32 dwBitCounter;
+ u32 dwData;
+ u32 dwCrc;
+ u32 dwCarry;
+ u8 *pbData;
+ u8 bHash;
pbData = pbMAC_p;
@@ -1246,7 +1240,7 @@ static BYTE EdrvCalcHash(BYTE * pbMAC_p)
// printk("MyCRC = 0x%08lX\n", dwCrc);
// only upper 6 bits (HASH_BITS) are used
// which point to specific bit in the hash registers
- bHash = (BYTE) ((dwCrc >> (32 - HASH_BITS)) & 0x3f);
+ bHash = (u8) ((dwCrc >> (32 - HASH_BITS)) & 0x3f);
return bHash;
}
diff --git a/drivers/staging/epl/EdrvFec.h b/drivers/staging/epl/EdrvFec.h
index 5f252fbed74..56728d1e95e 100644
--- a/drivers/staging/epl/EdrvFec.h
+++ b/drivers/staging/epl/EdrvFec.h
@@ -96,9 +96,9 @@
// Rx and Tx buffer descriptor format
typedef struct {
- WORD m_wStatus; // control / status --- used by edrv, do not change in application
- WORD m_wLength; // transfer length
- BYTE *m_pbData; // buffer address
+ u16 m_wStatus; // control / status --- used by edrv, do not change in application
+ u16 m_wLength; // transfer length
+ u8 *m_pbData; // buffer address
} tBufferDescr;
#if ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5282)
diff --git a/drivers/staging/epl/EdrvFec5282.h b/drivers/staging/epl/EdrvFec5282.h
deleted file mode 100644
index a16bb1d4da7..00000000000
--- a/drivers/staging/epl/EdrvFec5282.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: openPOWERLINK
-
- Description: interface for ethernetdriver
- "fast ethernet controller" (FEC)
- freescale coldfire MCF528x and compatible FEC
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS 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.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- $RCSfile: EdrvFec5282.h,v $
-
- $Author: D.Krueger $
-
- $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $
-
- $State: Exp $
-
- Build Environment:
- Dev C++ and GNU-Compiler for m68k
-
- -------------------------------------------------------------------------
-
- Revision History:
-
- 2005/08/01 m.b.: start of implementation
-
-****************************************************************************/
-
-#ifndef _EDRVFEC_H_
-#define _EDRVFEC_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-// base addresses
-#define FEC0_ADDR 0x0000
-#define FEC1_ADDR 0x0000 //tbd
-
-// control / status registers
-#define FEC_EIR 0x1004 // interrupt event register
-#define FEC_EIMR 0x1008 // interrupt mask register
-#define FEC_RDAR 0x1010 // receive descriptor active register
-#define FEC_TDAR 0x1014 // transmit descriptor active register
-#define FEC_ECR 0x1024 // ethernet control register
-#define FEC_MMFR 0x1040 // MII data register
-#define FEC_MSCR 0x1044 // MII speed register
-#define FEC_MIBC 0x1064 // MIB control/status register
-#define FEC_RCR 0x1084 // receive control register
-#define FEC_TCR 0x10C4 // transmit control register
-#define FEC_PALR 0x10E4 // physical address low register
-#define FEC_PAUR 0x10E8 // physical address high + type register
-#define FEC_OPD 0x10EC // opcode + pause register
-#define FEC_IAUR 0x1118 // upper 32 bit of individual hash table
-#define FEC_IALR 0x111C // lower 32 bit of individual hash table
-#define FEC_GAUR 0x1120 // upper 32 bit of group hash table
-#define FEC_GALR 0x1124 // lower 32 bit of group hash table
-#define FEC_TFWR 0x1144 // transmit FIFO watermark
-#define FEC_FRBR 0x114C // FIFO receive bound register
-#define FEC_FRSR 0x1150 // FIFO receive FIFO start register
-#define FEC_ERDSR 0x1180 // pointer to receive descriptor ring
-#define FEC_ETDSR 0x1184 // pointer to transmit descriptor ring
-#define FEC_EMRBR 0x1188 // maximum receive buffer size
-
-// mib block counters memory map
-#define FEC_RMON_T_DROP 0x1200 // count of frames not counted correctly
-#define FEC_RMON_T_PACKETS 0x1204 // RMON tx packet count
-#define FEC_RMON_T_BC_PKT 0x1208 // RMON tx broadcast packets
-#define FEC_RMON_T_MC_PKT 0x120C // RMON tx multicast packets
-#define FEC_RMON_T_CRC_ALIGN 0x1210 // RMON tx packets w CRC/align error
-#define FEC_RMON_T_UNDERSIZE 0x1214 // RMON tx packets < 64 bytes, good CRC
-#define FEC_RMON_T_OVERSIZE 0x1218 // RMON tx packets > MAX_FL bytes, good CRC
-#define FEC_RMON_T_FRAG 0x121C // RMON tx packets < 64 bytes, bad CRC
-#define FEC_RMON_T_JAB 0x1220 // RMON tx packets > MAX_FL bytes, bad CRC
-#define FEC_RMON_T_COL 0x1224 // RMON tx collision count
-#define FEC_RMON_T_P64 0x1228 // RMON tx 64 byte packets
-#define FEC_RMON_T_P65TO127 0x122C // RMON tx 65 to 127 byte packets
-#define FEC_RMON_T_P128TO255 0x1230 // RMON tx 128 to 255 byte packets
-#define FEC_RMON_T_P256TO511 0x1234 // RMON tx 256 to 511 byte packets
-#define FEC_RMON_T_P512TO1023 0x1238 // RMON tx 512 to 1023 byte packets
-#define FEC_RMON_T_P1024TO2047 0x123C // RMON tx 1024 to 2047 byte packets
-#define FEC_RMON_T_P_GTE2048 0x1240 // RMON tx w > 2048 bytes
-#define FEC_RMON_T_OCTETS 0x1244 // RMON tx octets
-#define FEC_IEEE_T_DROP 0x1248 // count of frames not counted correctly
-#define FEC_IEEE_T_FRAME_OK 0x124C // frames transmitted OK
-#define FEC_IEEE_T_1COL 0x1250 // frames transmitted with single collision
-#define FEC_IEEE_T_MCOL 0x1254 // frames transmitted with multiple collisions
-#define FEC_IEEE_T_DEF 0x1258 // frames transmitted after deferral delay
-#define FEC_IEEE_T_LCOL 0x125C // frames transmitted with late collisions
-#define FEC_IEEE_T_EXCOL 0x1260 // frames transmitted with excessive collisions
-#define FEC_IEEE_T_MACERR 0x1264 // frames transmitted with tx-FIFO underrun
-#define FEC_IEEE_T_CSERR 0x1268 // frames transmitted with carrier sense error
-#define FEC_IEEE_T_SQE 0x126C // frames transmitted with SQE error
-#define FEC_IEEE_T_FDXFC 0x1270 // flow control pause frames transmitted
-#define FEC_IEEE_T_OCTETS_OK 0x1274 // octet count for frames transmitted w/o error
-#define FEC_RMON_R_PACKETS 0x1284 // RMON rx packet count
-#define FEC_RMON_R_BC_PKT 0x1288 // RMON rx broadcast packets
-#define FEC_RMON_R_MC_PKT 0x128C // RMON rx multicast packets
-#define FEC_RMON_R_CRC_ALIGN 0x1290 // RMON rx packets w CRC/align error
-#define FEC_RMON_R_UNDERSIZE 0x1294 // RMON rx packets < 64 bytes, good CRC
-#define FEC_RMON_R_OVERSIZE 0x1298 // RMON rx packets > MAX_FL bytes, good CRC
-#define FEC_RMON_R_FRAG 0x129C // RMON rx packets < 64 bytes, bad CRC
-#define FEC_RMON_R_JAB 0x12A0 // RMON rx packets > MAX_FL bytes, bad CRC
-#define FEC_RMON_R_RESVD_0 0x12A4 //
-#define FEC_RMON_R_P64 0x12A8 // RMON rx 64 byte packets
-#define FEC_RMON_R_P65T0127 0x12AC // RMON rx 65 to 127 byte packets
-#define FEC_RMON_R_P128TO255 0x12B0 // RMON rx 128 to 255 byte packets
-#define FEC_RMON_R_P256TO511 0x12B4 // RMON rx 256 to 511 byte packets
-#define FEC_RMON_R_P512TO1023 0x12B8 // RMON rx 512 to 1023 byte packets
-#define FEC_RMON_R_P1024TO2047 0x12BC // RMON rx 1024 to 2047 byte packets
-#define FEC_RMON_R_GTE2048 0x12C0 // RMON rx w > 2048 bytes
-#define FEC_RMON_R_OCTETS 0x12C4 // RMON rx octets
-#define FEC_IEEE_R_DROP 0x12C8 // count of frames not counted correctly
-#define FEC_IEEE_R_FRAME_OK 0x12CC // frames received OK
-#define FEC_IEEE_R_CRC 0x12D0 // frames received with CRC error
-#define FEC_IEEE_R_ALIGN 0x12D4 // frames received with alignment error
-#define FEC_IEEE_R_MACERR 0x12D8 // receive FIFO overflow count
-#define FEC_IEEE_R_FDXFC 0x12DC // flow control pause frames received
-#define FEC_IEEE_R_OCTETS_OK 0x12E0 // octet count for frames rcvd w/o error
-
-// register bit definitions and macros
-#define FEC_EIR_UN (0x00080000)
-#define FEC_EIR_RL (0x00100000)
-#define FEC_EIR_LC (0x00200000)
-#define FEC_EIR_EBERR (0x00400000)
-#define FEC_EIR_MII (0x00800000)
-#define FEC_EIR_RXB (0x01000000)
-#define FEC_EIR_RXF (0x02000000)
-#define FEC_EIR_TXB (0x04000000)
-#define FEC_EIR_TXF (0x08000000)
-#define FEC_EIR_GRA (0x10000000)
-#define FEC_EIR_BABT (0x20000000)
-#define FEC_EIR_BABR (0x40000000)
-#define FEC_EIR_HBERR (0x80000000)
-
-#define FEC_EIMR_UN (0x00080000)
-#define FEC_EIMR_RL (0x00100000)
-#define FEC_EIMR_LC (0x00200000)
-#define FEC_EIMR_EBERR (0x00400000)
-#define FEC_EIMR_MII (0x00800000)
-#define FEC_EIMR_RXB (0x01000000)
-#define FEC_EIMR_RXF (0x02000000)
-#define FEC_EIMR_TXB (0x04000000)
-#define FEC_EIMR_TXF (0x08000000)
-#define FEC_EIMR_GRA (0x10000000)
-#define FEC_EIMR_BABT (0x20000000)
-#define FEC_EIMR_BABR (0x40000000)
-#define FEC_EIMR_HBERR (0x80000000)
-
-#define FEC_RDAR_R_DES_ACTIVE (0x01000000)
-
-#define FEC_TDAR_X_DES_ACTIVE (0x01000000)
-
-#define FEC_ECR_RESET (0x00000001)
-#define FEC_ECR_ETHER_EN (0x00000002)
-
-#define FEC_MMFR_DATA(x) (((x) & 0xFFFF))
-#define FEC_MMFR_TA (0x00020000)
-#define FEC_MMFR_RA(x) (((x) & 0x1F) << 18)
-#define FEC_MMFR_PA(x) (((x) & 0x1F) << 23)
-#define FEC_MMFR_OP_WR (0x10000000)
-#define FEC_MMFR_OP_RD (0x20000000)
-#define FEC_MMFR_ST (0x40000000)
-
-#define FEC_MSCR_MII_SPEED(x) (((x) & 0x1F) << 1)
-#define FEC_MSCR_DIS_PREAMBLE (0x00000008)
-
-#define FEC_MIBC_MIB_IDLE (0x40000000)
-#define FEC_MIBC_MIB_DISABLE (0x80000000)
-
-#define FEC_RCR_LOOP (0x00000001)
-#define FEC_RCR_DRT (0x00000002)
-#define FEC_RCR_MII_MODE (0x00000004)
-#define FEC_RCR_PROM (0x00000008)
-#define FEC_RCR_BC_REJ (0x00000010)
-#define FEC_RCR_FCE (0x00000020)
-#define FEC_RCR_MAX_FL(x) (((x) & 0x07FF) << 16)
-
-#define FEC_TCR_GTS (0x00000001)
-#define FEC_TCR_HBC (0x00000002)
-#define FEC_TCR_FDEN (0x00000004)
-#define FEC_TCR_TFC_PAUSE (0x00000008)
-#define FEC_TCR_RFC_PAUSE (0x00000010)
-
-#define FEC_PALR_BYTE3(x) (((x) & 0xFF) << 0)
-#define FEC_PALR_BYTE2(x) (((x) & 0xFF) << 8)
-#define FEC_PALR_BYTE1(x) (((x) & 0xFF) << 16)
-#define FEC_PALR_BYTE0(x) (((x) & 0xFF) << 24)
-
-//#define FEC_PAUR_TYPE(x) (((x) & 0xFFFF) << 0)
-#define FEC_PAUR_BYTE5(x) (((x) & 0xFF) << 16)
-#define FEC_PAUR_BYTE4(x) (((x) & 0xFF) << 24)
-
-#define FEC_OPD_PAUSE_DUR(x) (((x) & 0xFFFF))
-//#define FEC_OPD_OPCODE(x) (((x) & 0xFFFF) << 16)
-
-//m.b.
-#define FEC_IAUR_BYTE7(x) (((x) & 0xFF) << 0)
-#define FEC_IAUR_BYTE6(x) (((x) & 0xFF) << 8)
-#define FEC_IAUR_BYTE5(x) (((x) & 0xFF) << 16)
-#define FEC_IAUR_BYTE4(x) (((x) & 0xFF) << 24)
-
-#define FEC_IALR_BYTE3(x) (((x) & 0xFF) << 0)
-#define FEC_IALR_BYTE2(x) (((x) & 0xFF) << 8)
-#define FEC_IALR_BYTE1(x) (((x) & 0xFF) << 16)
-#define FEC_IALR_BYTE0(x) (((x) & 0xFF) << 24)
-
-#define FEC_GAUR_BYTE7(x) (((x) & 0xFF) << 0)
-#define FEC_GAUR_BYTE6(x) (((x) & 0xFF) << 8)
-#define FEC_GAUR_BYTE5(x) (((x) & 0xFF) << 16)
-#define FEC_GAUR_BYTE4(x) (((x) & 0xFF) << 24)
-
-#define FEC_GALR_BYTE3(x) (((x) & 0xFF) << 0)
-#define FEC_GALR_BYTE2(x) (((x) & 0xFF) << 8)
-#define FEC_GALR_BYTE1(x) (((x) & 0xFF) << 16)
-#define FEC_GALR_BYTE0(x) (((x) & 0xFF) << 24)
-// ^^^^
-
-#define FEC_TFWR_X_WMRK_64 (0x00000001)
-#define FEC_TFWR_X_WMRK_128 (0x00000002)
-#define FEC_TFWR_X_WMRK_192 (0x00000003)
-
-//m.b.
-#define FEC_FRBR_R_BOUND(x) (((x) & 0xFF) << 2)
-
-//m.b.
-#define FEC_FRSR_R_FSTART(x) (((x) & 0xFF) << 2)
-
-//m.b.
-#define FEC_ERDSR_R_DES_START(x) (((x) & 0x3FFFFFFF) << 2)
-
-//m.b.
-#define FEC_ETSDR_X_DES_START(x) (((x) & 0x3FFFFFFF) << 2)
-
-#define FEC_EMRBR_R_BUF_SIZE(x) (((x) & 0x7F) << 4)
-
-#define FEC_RxBD_TR 0x0001
-#define FEC_RxBD_OV 0x0002
-#define FEC_RxBD_CR 0x0004
-#define FEC_RxBD_NO 0x0010
-#define FEC_RxBD_LG 0x0020
-#define FEC_RxBD_MC 0x0040
-#define FEC_RxBD_BC 0x0080
-#define FEC_RxBD_M 0x0100
-#define FEC_RxBD_L 0x0800
-#define FEC_RxBD_R02 0x1000
-#define FEC_RxBD_W 0x2000
-#define FEC_RxBD_R01 0x4000
-#define FEC_RxBD_INUSE 0x4000
-#define FEC_RxBD_E 0x8000
-
-//m.b.
-//#define FEC_TxBD_CSL 0x0001
-//#define FEC_TxBD_UN 0x0002
-//#define FEC_TxBD_RL 0x0040
-//#define FEC_TxBD_LC 0x0080
-//#define FEC_TxBD_HB 0x0100
-//#define FEC_TxBD_DEF 0x0200
-#define FEC_TxBD_ABC 0x0200
-// ^^^^
-#define FEC_TxBD_TC 0x0400
-#define FEC_TxBD_L 0x0800
-#define FEC_TxBD_TO2 0x1000
-#define FEC_TxBD_W 0x2000
-#define FEC_TxBD_TO1 0x4000
-#define FEC_TxBD_INUSE 0x4000
-#define FEC_TxBD_R 0x8000
-
-//---------------------------------------------------------------------------
-// types
-//---------------------------------------------------------------------------
-
-// Rx and Tx buffer descriptor format
-typedef struct {
- WORD m_wStatus; // control / status --- used by edrv, do not change in application
- WORD m_wLength; // transfer length
- BYTE *m_pbData; // buffer address
-} tBufferDescr;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#if (NO_OF_INSTANCES > 1)
-#define ECI_WRITE_DW_REG(off,val) (*(DWORD *)(void *)(&__IPSBAR[off]) = val)
-#define ECI_READ_DW_REG(off) (*(DWORD *)(void *)(&__IPSBAR[off]))
-#else
-#if (EDRV_USED_ETH_CTRL == 0)
-#define ECI_WRITE_DW_REG(off,val) (*(DWORD *)(void *)(&__IPSBAR[FEC0_ADDR+off]) = val)
-#define ECI_READ_DW_REG(off) (*(DWORD *)(void *)(&__IPSBAR[FEC0_ADDR+off]))
-#else
-#define ECI_WRITE_DW_REG(off,val) (*(DWORD *)(void *)(&__IPSBAR[FEC1_ADDR+off]) = val)
-#define ECI_READ_DW_REG(off) (*(DWORD *)(void *)(&__IPSBAR[FEC1_ADDR+off]))
-#endif
-#endif
-
-#endif // #ifndef _EDRV_FEC_H_
diff --git a/drivers/staging/epl/EdrvSim.h b/drivers/staging/epl/EdrvSim.h
index 39300e321d6..191ec1457d2 100644
--- a/drivers/staging/epl/EdrvSim.h
+++ b/drivers/staging/epl/EdrvSim.h
@@ -83,7 +83,7 @@
// function prototypes
//---------------------------------------------------------------------------
-void EdrvRxInterruptHandler(BYTE bBufferInFrame_p, BYTE * pbEthernetData_p,
- WORD wDataLen_p);
+void EdrvRxInterruptHandler(u8 bBufferInFrame_p, u8 * pbEthernetData_p,
+ u16 wDataLen_p);
#endif // #ifndef _EDRVSIM_H_
diff --git a/drivers/staging/epl/Epl.h b/drivers/staging/epl/Epl.h
index be60f771b63..7f22b04022b 100644
--- a/drivers/staging/epl/Epl.h
+++ b/drivers/staging/epl/Epl.h
@@ -89,7 +89,7 @@ typedef struct {
unsigned int m_uiNodeId;
tEplNmtState m_NmtState;
tEplNmtNodeEvent m_NodeEvent;
- WORD m_wErrorCode; // EPL error code if m_NodeEvent == kEplNmtNodeEventError
+ u16 m_wErrorCode; // EPL error code if m_NodeEvent == kEplNmtNodeEventError
BOOL m_fMandatory;
} tEplApiEventNode;
@@ -97,7 +97,7 @@ typedef struct {
typedef struct {
tEplNmtState m_NmtState; // local NMT state
tEplNmtBootEvent m_BootEvent;
- WORD m_wErrorCode; // EPL error code if m_BootEvent == kEplNmtBootEventError
+ u16 m_wErrorCode; // EPL error code if m_BootEvent == kEplNmtBootEventError
} tEplApiEventBoot;
@@ -131,33 +131,33 @@ typedef union {
} tEplApiEventArg;
-typedef tEplKernel(PUBLIC ROM * tEplApiCbEvent) (tEplApiEventType EventType_p, // IN: event type (enum)
- tEplApiEventArg * pEventArg_p, // IN: event argument (union)
- void GENERIC * pUserArg_p);
+typedef tEplKernel(*tEplApiCbEvent) (tEplApiEventType EventType_p, // IN: event type (enum)
+ tEplApiEventArg *pEventArg_p, // IN: event argument (union)
+ void *pUserArg_p);
typedef struct {
unsigned int m_uiSizeOfStruct;
BOOL m_fAsyncOnly; // do not need to register PRes
unsigned int m_uiNodeId; // local node ID
- BYTE m_abMacAddress[6]; // local MAC address
+ u8 m_abMacAddress[6]; // local MAC address
// 0x1F82: NMT_FeatureFlags_U32
- DWORD m_dwFeatureFlags;
+ u32 m_dwFeatureFlags;
// Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
- DWORD m_dwCycleLen; // required for error detection
+ u32 m_dwCycleLen; // required for error detection
// 0x1F98: NMT_CycleTiming_REC
// 0x1F98.1: IsochrTxMaxPayload_U16
unsigned int m_uiIsochrTxMaxPayload; // const
// 0x1F98.2: IsochrRxMaxPayload_U16
unsigned int m_uiIsochrRxMaxPayload; // const
// 0x1F98.3: PResMaxLatency_U32
- DWORD m_dwPresMaxLatency; // const in [ns], only required for IdentRes
+ u32 m_dwPresMaxLatency; // const in [ns], only required for IdentRes
// 0x1F98.4: PReqActPayloadLimit_U16
unsigned int m_uiPreqActPayloadLimit; // required for initialisation (+28 bytes)
// 0x1F98.5: PResActPayloadLimit_U16
unsigned int m_uiPresActPayloadLimit; // required for initialisation of Pres frame (+28 bytes)
// 0x1F98.6: ASndMaxLatency_U32
- DWORD m_dwAsndMaxLatency; // const in [ns], only required for IdentRes
+ u32 m_dwAsndMaxLatency; // const in [ns], only required for IdentRes
// 0x1F98.7: MultiplCycleCnt_U8
unsigned int m_uiMultiplCycleCnt; // required for error detection
// 0x1F98.8: AsyncMTU_U16
@@ -167,30 +167,30 @@ typedef struct {
// $$$ Multiplexed Slot
// 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
- DWORD m_dwLossOfFrameTolerance;
+ u32 m_dwLossOfFrameTolerance;
// 0x1F8A: NMT_MNCycleTiming_REC
// 0x1F8A.1: WaitSoCPReq_U32 in [ns]
- DWORD m_dwWaitSocPreq;
+ u32 m_dwWaitSocPreq;
// 0x1F8A.2: AsyncSlotTimeout_U32 in [ns]
- DWORD m_dwAsyncSlotTimeout;
-
- DWORD m_dwDeviceType; // NMT_DeviceType_U32
- DWORD m_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32
- DWORD m_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32
- DWORD m_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32
- DWORD m_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32
- QWORD m_qwVendorSpecificExt1;
- DWORD m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
- DWORD m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
- DWORD m_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
- DWORD m_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
- DWORD m_dwIpAddress;
- DWORD m_dwSubnetMask;
- DWORD m_dwDefaultGateway;
- BYTE m_sHostname[32];
- BYTE m_abVendorSpecificExt2[48];
+ u32 m_dwAsyncSlotTimeout;
+
+ u32 m_dwDeviceType; // NMT_DeviceType_U32
+ u32 m_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32
+ u32 m_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32
+ u32 m_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32
+ u32 m_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32
+ u64 m_qwVendorSpecificExt1;
+ u32 m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
+ u32 m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
+ u32 m_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
+ u32 m_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
+ u32 m_dwIpAddress;
+ u32 m_dwSubnetMask;
+ u32 m_dwDefaultGateway;
+ u8 m_sHostname[32];
+ u8 m_abVendorSpecificExt2[48];
char *m_pszDevName; // NMT_ManufactDevName_VS (0x1008/0 local OD)
char *m_pszHwVersion; // NMT_ManufactHwVers_VS (0x1009/0 local OD)
@@ -212,62 +212,61 @@ typedef struct {
// function prototypes
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam * pInitParam_p);
+tEplKernel EplApiInitialize(tEplApiInitParam *pInitParam_p);
-tEplKernel PUBLIC EplApiShutdown(void);
+tEplKernel EplApiShutdown(void);
-tEplKernel PUBLIC EplApiReadObject(tEplSdoComConHdl * pSdoComConHdl_p,
- unsigned int uiNodeId_p,
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pDstData_le_p,
- unsigned int *puiSize_p,
- tEplSdoType SdoType_p, void *pUserArg_p);
+tEplKernel EplApiReadObject(tEplSdoComConHdl *pSdoComConHdl_p,
+ unsigned int uiNodeId_p,
+ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pDstData_le_p,
+ unsigned int *puiSize_p,
+ tEplSdoType SdoType_p, void *pUserArg_p);
-tEplKernel PUBLIC EplApiWriteObject(tEplSdoComConHdl * pSdoComConHdl_p,
- unsigned int uiNodeId_p,
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pSrcData_le_p,
- unsigned int uiSize_p,
- tEplSdoType SdoType_p, void *pUserArg_p);
+tEplKernel EplApiWriteObject(tEplSdoComConHdl *pSdoComConHdl_p,
+ unsigned int uiNodeId_p,
+ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pSrcData_le_p,
+ unsigned int uiSize_p,
+ tEplSdoType SdoType_p, void *pUserArg_p);
-tEplKernel PUBLIC EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p);
+tEplKernel EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p);
-tEplKernel PUBLIC EplApiReadLocalObject(unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pDstData_p,
- unsigned int *puiSize_p);
+tEplKernel EplApiReadLocalObject(unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pDstData_p,
+ unsigned int *puiSize_p);
-tEplKernel PUBLIC EplApiWriteLocalObject(unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pSrcData_p,
- unsigned int uiSize_p);
+tEplKernel EplApiWriteLocalObject(unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pSrcData_p,
+ unsigned int uiSize_p);
-tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p);
+tEplKernel EplApiCbObdAccess(tEplObdCbParam *pParam_p);
-tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
- void *pVar_p,
- unsigned int *puiVarEntries_p,
- tEplObdSize * pEntrySize_p,
- unsigned int uiFirstSubindex_p);
+tEplKernel EplApiLinkObject(unsigned int uiObjIndex_p,
+ void *pVar_p,
+ unsigned int *puiVarEntries_p,
+ tEplObdSize *pEntrySize_p,
+ unsigned int uiFirstSubindex_p);
-tEplKernel PUBLIC EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p);
+tEplKernel EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p);
-tEplKernel PUBLIC EplApiProcess(void);
+tEplKernel EplApiProcess(void);
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-tEplKernel PUBLIC EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
- tEplNmtNodeCommand NodeCommand_p);
+tEplKernel EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
+ tEplNmtNodeCommand NodeCommand_p);
#endif
-tEplKernel PUBLIC EplApiGetIdentResponse(unsigned int uiNodeId_p,
- tEplIdentResponse **
- ppIdentResponse_p);
+tEplKernel EplApiGetIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentResponse **ppIdentResponse_p);
// functions for process image will be implemented in separate file
-tEplKernel PUBLIC EplApiProcessImageSetup(void);
-tEplKernel PUBLIC EplApiProcessImageExchangeIn(tEplApiProcessImage * pPI_p);
-tEplKernel PUBLIC EplApiProcessImageExchangeOut(tEplApiProcessImage * pPI_p);
+tEplKernel EplApiProcessImageSetup(void);
+tEplKernel EplApiProcessImageExchangeIn(tEplApiProcessImage *pPI_p);
+tEplKernel EplApiProcessImageExchangeOut(tEplApiProcessImage *pPI_p);
#endif // #ifndef _EPL_API_H_
diff --git a/drivers/staging/epl/EplAmi.h b/drivers/staging/epl/EplAmi.h
index 6fa04a4f0a1..3b46ea11442 100644
--- a/drivers/staging/epl/EplAmi.h
+++ b/drivers/staging/epl/EplAmi.h
@@ -69,7 +69,7 @@
16.09.2002 -as
To save code space the functions AmiSetByte and AmiGetByte
- are replaced by macros. For targets which assign BYTE by
+ are replaced by macros. For targets which assign u8 by
an 16Bit type, the definition of macros must changed to
functions.
@@ -86,11 +86,6 @@
#ifndef _EPLAMI_H_
#define _EPLAMI_H_
-#if ((DEV_SYSTEM & _DEV_64BIT_SUPPORT_) == 0)
-// #ifdef USE_VAR64
-#error 'ERROR: development system does not support 64 bit operations!'
-// #endif
-#endif
//---------------------------------------------------------------------------
// types
@@ -104,44 +99,21 @@
extern "C" {
#endif
-#if (TARGET_SYSTEM == _WIN32_)
-#if defined(INLINE_FUNCTION_DEF)
-#undef INLINE_FUNCTION
-#define INLINE_FUNCTION INLINE_FUNCTION_DEF
-#define INLINE_ENABLED TRUE
-#define EPL_AMI_INLINED
-#include "../EplStack/amix86.c"
-#endif
-
-#elif (TARGET_SYSTEM == _LINUX_)
-#if defined(__m68k__) // it is an big endian machine
-#if defined(INLINE_FUNCTION_DEF)
-#undef INLINE_FUNCTION
-#define INLINE_FUNCTION INLINE_FUNCTION_DEF
-#define INLINE_ENABLED TRUE
-#define EPL_AMI_INLINED
-#include "../EplStack/amibe.c"
-#endif
-#endif
-#endif
-
//---------------------------------------------------------------------------
//
// write functions
//
// To save code space the function AmiSetByte is replaced by
// an macro.
-// void PUBLIC AmiSetByte (void FAR* pAddr_p, BYTE bByteVal_p);
+// void AmiSetByte (void * pAddr_p, u8 bByteVal_p);
-#define AmiSetByteToBe(pAddr_p, bByteVal_p) {*(BYTE FAR*)(pAddr_p) = (bByteVal_p);}
-#define AmiSetByteToLe(pAddr_p, bByteVal_p) {*(BYTE FAR*)(pAddr_p) = (bByteVal_p);}
+#define AmiSetByteToBe(pAddr_p, bByteVal_p) {*(u8 *)(pAddr_p) = (bByteVal_p);}
+#define AmiSetByteToLe(pAddr_p, bByteVal_p) {*(u8 *)(pAddr_p) = (bByteVal_p);}
-#if !defined(INLINE_ENABLED)
- void PUBLIC AmiSetWordToBe(void FAR * pAddr_p, WORD wWordVal_p);
- void PUBLIC AmiSetDwordToBe(void FAR * pAddr_p, DWORD dwDwordVal_p);
- void PUBLIC AmiSetWordToLe(void FAR * pAddr_p, WORD wWordVal_p);
- void PUBLIC AmiSetDwordToLe(void FAR * pAddr_p, DWORD dwDwordVal_p);
-#endif
+void AmiSetWordToBe(void *pAddr_p, u16 wWordVal_p);
+void AmiSetDwordToBe(void *pAddr_p, u32 dwDwordVal_p);
+void AmiSetWordToLe(void *pAddr_p, u16 wWordVal_p);
+void AmiSetDwordToLe(void *pAddr_p, u32 dwDwordVal_p);
//---------------------------------------------------------------------------
//
@@ -149,17 +121,15 @@ extern "C" {
//
// To save code space the function AmiGetByte is replaced by
// an macro.
-// BYTE PUBLIC AmiGetByte (void FAR* pAddr_p);
-
-#define AmiGetByteFromBe(pAddr_p) (*(BYTE FAR*)(pAddr_p))
-#define AmiGetByteFromLe(pAddr_p) (*(BYTE FAR*)(pAddr_p))
+// u8 AmiGetByte (void * pAddr_p);
-#if !defined(INLINE_ENABLED)
+#define AmiGetByteFromBe(pAddr_p) (*(u8 *)(pAddr_p))
+#define AmiGetByteFromLe(pAddr_p) (*(u8 *)(pAddr_p))
- WORD PUBLIC AmiGetWordFromBe(void FAR * pAddr_p);
- DWORD PUBLIC AmiGetDwordFromBe(void FAR * pAddr_p);
- WORD PUBLIC AmiGetWordFromLe(void FAR * pAddr_p);
- DWORD PUBLIC AmiGetDwordFromLe(void FAR * pAddr_p);
+u16 AmiGetWordFromBe(void *pAddr_p);
+u32 AmiGetDwordFromBe(void *pAddr_p);
+u16 AmiGetWordFromLe(void *pAddr_p);
+u32 AmiGetDwordFromLe(void *pAddr_p);
//---------------------------------------------------------------------------
//
@@ -174,8 +144,8 @@ extern "C" {
//
//---------------------------------------------------------------------------
- void PUBLIC AmiSetDword24ToBe(void FAR * pAddr_p, DWORD dwDwordVal_p);
- void PUBLIC AmiSetDword24ToLe(void FAR * pAddr_p, DWORD dwDwordVal_p);
+void AmiSetDword24ToBe(void *pAddr_p, u32 dwDwordVal_p);
+void AmiSetDword24ToLe(void *pAddr_p, u32 dwDwordVal_p);
//---------------------------------------------------------------------------
//
@@ -185,12 +155,12 @@ extern "C" {
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: DWORD = read value
+// Return: u32 = read value
//
//---------------------------------------------------------------------------
- DWORD PUBLIC AmiGetDword24FromBe(void FAR * pAddr_p);
- DWORD PUBLIC AmiGetDword24FromLe(void FAR * pAddr_p);
+u32 AmiGetDword24FromBe(void *pAddr_p);
+u32 AmiGetDword24FromLe(void *pAddr_p);
//#ifdef USE_VAR64
@@ -207,8 +177,8 @@ extern "C" {
//
//---------------------------------------------------------------------------
- void PUBLIC AmiSetQword40ToBe(void FAR * pAddr_p, QWORD qwQwordVal_p);
- void PUBLIC AmiSetQword40ToLe(void FAR * pAddr_p, QWORD qwQwordVal_p);
+void AmiSetQword40ToBe(void *pAddr_p, u64 qwQwordVal_p);
+void AmiSetQword40ToLe(void *pAddr_p, u64 qwQwordVal_p);
//---------------------------------------------------------------------------
//
@@ -218,12 +188,12 @@ extern "C" {
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
//---------------------------------------------------------------------------
- QWORD PUBLIC AmiGetQword40FromBe(void FAR * pAddr_p);
- QWORD PUBLIC AmiGetQword40FromLe(void FAR * pAddr_p);
+u64 AmiGetQword40FromBe(void *pAddr_p);
+u64 AmiGetQword40FromLe(void *pAddr_p);
//---------------------------------------------------------------------------
//
@@ -238,8 +208,8 @@ extern "C" {
//
//---------------------------------------------------------------------------
- void PUBLIC AmiSetQword48ToBe(void FAR * pAddr_p, QWORD qwQwordVal_p);
- void PUBLIC AmiSetQword48ToLe(void FAR * pAddr_p, QWORD qwQwordVal_p);
+void AmiSetQword48ToBe(void *pAddr_p, u64 qwQwordVal_p);
+void AmiSetQword48ToLe(void *pAddr_p, u64 qwQwordVal_p);
//---------------------------------------------------------------------------
//
@@ -249,12 +219,12 @@ extern "C" {
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
//---------------------------------------------------------------------------
- QWORD PUBLIC AmiGetQword48FromBe(void FAR * pAddr_p);
- QWORD PUBLIC AmiGetQword48FromLe(void FAR * pAddr_p);
+u64 AmiGetQword48FromBe(void *pAddr_p);
+u64 AmiGetQword48FromLe(void *pAddr_p);
//---------------------------------------------------------------------------
//
@@ -269,8 +239,8 @@ extern "C" {
//
//---------------------------------------------------------------------------
- void PUBLIC AmiSetQword56ToBe(void FAR * pAddr_p, QWORD qwQwordVal_p);
- void PUBLIC AmiSetQword56ToLe(void FAR * pAddr_p, QWORD qwQwordVal_p);
+void AmiSetQword56ToBe(void *pAddr_p, u64 qwQwordVal_p);
+void AmiSetQword56ToLe(void *pAddr_p, u64 qwQwordVal_p);
//---------------------------------------------------------------------------
//
@@ -280,12 +250,12 @@ extern "C" {
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
//---------------------------------------------------------------------------
- QWORD PUBLIC AmiGetQword56FromBe(void FAR * pAddr_p);
- QWORD PUBLIC AmiGetQword56FromLe(void FAR * pAddr_p);
+u64 AmiGetQword56FromBe(void *pAddr_p);
+u64 AmiGetQword56FromLe(void *pAddr_p);
//---------------------------------------------------------------------------
//
@@ -300,8 +270,8 @@ extern "C" {
//
//---------------------------------------------------------------------------
- void PUBLIC AmiSetQword64ToBe(void FAR * pAddr_p, QWORD qwQwordVal_p);
- void PUBLIC AmiSetQword64ToLe(void FAR * pAddr_p, QWORD qwQwordVal_p);
+void AmiSetQword64ToBe(void *pAddr_p, u64 qwQwordVal_p);
+void AmiSetQword64ToLe(void *pAddr_p, u64 qwQwordVal_p);
//---------------------------------------------------------------------------
//
@@ -315,8 +285,8 @@ extern "C" {
//
//---------------------------------------------------------------------------
- QWORD PUBLIC AmiGetQword64FromBe(void FAR * pAddr_p);
- QWORD PUBLIC AmiGetQword64FromLe(void FAR * pAddr_p);
+u64 AmiGetQword64FromBe(void *pAddr_p);
+u64 AmiGetQword64FromLe(void *pAddr_p);
//---------------------------------------------------------------------------
//
@@ -330,9 +300,7 @@ extern "C" {
// Return: void
//
//---------------------------------------------------------------------------
-
- void PUBLIC AmiSetTimeOfDay(void FAR * pAddr_p,
- tTimeOfDay FAR * pTimeOfDay_p);
+void AmiSetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p);
//---------------------------------------------------------------------------
//
@@ -346,14 +314,7 @@ extern "C" {
// Return: void
//
//---------------------------------------------------------------------------
-
- void PUBLIC AmiGetTimeOfDay(void FAR * pAddr_p,
- tTimeOfDay FAR * pTimeOfDay_p);
-
-#endif
-
-#undef INLINE_ENABLED // disable actual inlining of functions
-#define EPL_AMI_INCLUDED
+void AmiGetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p);
#ifdef __cplusplus
}
diff --git a/drivers/staging/epl/EplApiGeneric.c b/drivers/staging/epl/EplApiGeneric.c
index ae19e34cd7b..c4419569183 100644
--- a/drivers/staging/epl/EplApiGeneric.c
+++ b/drivers/staging/epl/EplApiGeneric.c
@@ -162,44 +162,41 @@ static tEplApiInstance EplApiInstance_g;
//---------------------------------------------------------------------------
// NMT state change event callback function
-static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange
- NmtStateChange_p);
+static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
// update DLL configuration from OD
-static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p);
+static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p);
// update OD from init param
-static tEplKernel PUBLIC EplApiUpdateObd(void);
+static tEplKernel EplApiUpdateObd(void);
// process events from user event queue
-static tEplKernel PUBLIC EplApiProcessEvent(tEplEvent * pEplEvent_p);
+static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p);
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
// callback function of SDO module
-static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished * pSdoComFinished_p);
+static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p);
#endif
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
// callback functions of NmtMnu module
-static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p,
- tEplNmtNodeEvent NodeEvent_p,
- tEplNmtState NmtState_p,
- WORD wErrorCode_p,
- BOOL fMandatory_p);
-
-static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
- tEplNmtState NmtState_p,
- WORD wErrorCode_p);
+static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p,
+ tEplNmtNodeEvent NodeEvent_p,
+ tEplNmtState NmtState_p,
+ u16 wErrorCode_p, BOOL fMandatory_p);
+
+static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
+ tEplNmtState NmtState_p,
+ u16 wErrorCode_p);
#endif
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
// callback function of Ledu module
-static tEplKernel PUBLIC EplApiCbLedStateChange(tEplLedType LedType_p,
- BOOL fOn_p);
+static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p);
#endif
// OD initialization function (implemented in Objdict.c)
-tEplKernel PUBLIC EplObdInitRam(tEplObdInitParam MEM * pInitParam_p);
+tEplKernel EplObdInitRam(tEplObdInitParam *pInitParam_p);
//=========================================================================//
// //
@@ -226,7 +223,7 @@ tEplKernel PUBLIC EplObdInitRam(tEplObdInitParam MEM * pInitParam_p);
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam * pInitParam_p)
+tEplKernel EplApiInitialize(tEplApiInitParam *pInitParam_p)
{
tEplKernel Ret = kEplSuccessful;
tEplObdInitParam ObdInitParam;
@@ -415,7 +412,7 @@ tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam * pInitParam_p)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiShutdown(void)
+tEplKernel EplApiShutdown(void)
{
tEplKernel Ret = kEplSuccessful;
@@ -523,7 +520,7 @@ tEplKernel PUBLIC EplApiShutdown(void)
// State:
//----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
+tEplKernel EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -553,15 +550,15 @@ tEplKernel PUBLIC EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
// State:
//----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
- void *pVar_p,
- unsigned int *puiVarEntries_p,
- tEplObdSize * pEntrySize_p,
- unsigned int uiFirstSubindex_p)
+tEplKernel EplApiLinkObject(unsigned int uiObjIndex_p,
+ void *pVar_p,
+ unsigned int *puiVarEntries_p,
+ tEplObdSize *pEntrySize_p,
+ unsigned int uiFirstSubindex_p)
{
- BYTE bVarEntries;
- BYTE bIndexEntries;
- BYTE MEM *pbData;
+ u8 bVarEntries;
+ u8 bIndexEntries;
+ u8 *pbData;
unsigned int uiSubindex;
tEplVarParam VarParam;
tEplObdSize EntrySize;
@@ -577,8 +574,8 @@ tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
goto Exit;
}
- pbData = (BYTE MEM *) pVar_p;
- bVarEntries = (BYTE) * puiVarEntries_p;
+ pbData = (u8 *)pVar_p;
+ bVarEntries = (u8) * puiVarEntries_p;
UsedSize = 0;
// init VarParam structure with default values
@@ -591,7 +588,7 @@ tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
EntrySize = (tEplObdSize) sizeof(bIndexEntries);
RetCode = EplObdReadEntry(uiObjIndex_p,
0x00,
- (void GENERIC *)&bIndexEntries,
+ (void *)&bIndexEntries,
&EntrySize);
if ((RetCode != kEplSuccessful) || (bIndexEntries == 0x00)) {
@@ -610,7 +607,7 @@ tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
// object actually has.
if ((bIndexEntries > (bVarEntries + uiFirstSubindex_p - 1)) &&
(bVarEntries != 0x00)) {
- bIndexEntries = (BYTE) (bVarEntries + uiFirstSubindex_p - 1);
+ bIndexEntries = (u8) (bVarEntries + uiFirstSubindex_p - 1);
}
// map entries
for (uiSubindex = uiFirstSubindex_p; uiSubindex <= bIndexEntries;
@@ -677,13 +674,13 @@ tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
//
// ----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiReadObject(tEplSdoComConHdl * pSdoComConHdl_p,
- unsigned int uiNodeId_p,
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pDstData_le_p,
- unsigned int *puiSize_p,
- tEplSdoType SdoType_p, void *pUserArg_p)
+tEplKernel EplApiReadObject(tEplSdoComConHdl *pSdoComConHdl_p,
+ unsigned int uiNodeId_p,
+ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pDstData_le_p,
+ unsigned int *puiSize_p,
+ tEplSdoType SdoType_p, void *pUserArg_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -765,13 +762,13 @@ tEplKernel PUBLIC EplApiReadObject(tEplSdoComConHdl * pSdoComConHdl_p,
//
// ----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiWriteObject(tEplSdoComConHdl * pSdoComConHdl_p,
- unsigned int uiNodeId_p,
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pSrcData_le_p,
- unsigned int uiSize_p,
- tEplSdoType SdoType_p, void *pUserArg_p)
+tEplKernel EplApiWriteObject(tEplSdoComConHdl *pSdoComConHdl_p,
+ unsigned int uiNodeId_p,
+ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pSrcData_le_p,
+ unsigned int uiSize_p,
+ tEplSdoType SdoType_p, void *pUserArg_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -850,7 +847,7 @@ tEplKernel PUBLIC EplApiWriteObject(tEplSdoComConHdl * pSdoComConHdl_p,
//
// ----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p)
+tEplKernel EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -881,10 +878,9 @@ tEplKernel PUBLIC EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p)
//
// ----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiReadLocalObject(unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pDstData_p,
- unsigned int *puiSize_p)
+tEplKernel EplApiReadLocalObject(unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pDstData_p, unsigned int *puiSize_p)
{
tEplKernel Ret = kEplSuccessful;
tEplObdSize ObdSize;
@@ -911,10 +907,10 @@ tEplKernel PUBLIC EplApiReadLocalObject(unsigned int uiIndex_p,
//
// ----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiWriteLocalObject(unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pSrcData_p,
- unsigned int uiSize_p)
+tEplKernel EplApiWriteLocalObject(unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pSrcData_p,
+ unsigned int uiSize_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -939,8 +935,8 @@ tEplKernel PUBLIC EplApiWriteLocalObject(unsigned int uiIndex_p,
//
// ----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
- tEplNmtNodeCommand NodeCommand_p)
+tEplKernel EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
+ tEplNmtNodeCommand NodeCommand_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -966,7 +962,7 @@ tEplKernel PUBLIC EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p)
+tEplKernel EplApiCbObdAccess(tEplObdCbParam *pParam_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -1001,8 +997,8 @@ tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p)
{
if ((pParam_p->m_ObdEvent == kEplObdEvPostWrite)
&& (pParam_p->m_uiSubIndex == 3)
- && (*((DWORD *) pParam_p->m_pArg) != 0)) {
- DWORD dwVerifyConfInvalid = 0;
+ && (*((u32 *) pParam_p->m_pArg) != 0)) {
+ u32 dwVerifyConfInvalid = 0;
// set CFM_VerifyConfiguration_REC.VerifyConfInvalid_U32 to 0
Ret =
EplObdWriteEntry(0x1020, 4,
@@ -1016,9 +1012,9 @@ tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p)
case 0x1F9E: // NMT_ResetCmd_U8
{
if (pParam_p->m_ObdEvent == kEplObdEvPreWrite) {
- BYTE bNmtCommand;
+ u8 bNmtCommand;
- bNmtCommand = *((BYTE *) pParam_p->m_pArg);
+ bNmtCommand = *((u8 *) pParam_p->m_pArg);
// check value range
switch ((tEplNmtCommand) bNmtCommand) {
case kEplNmtCmdResetNode:
@@ -1036,9 +1032,9 @@ tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p)
break;
}
} else if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) {
- BYTE bNmtCommand;
+ u8 bNmtCommand;
- bNmtCommand = *((BYTE *) pParam_p->m_pArg);
+ bNmtCommand = *((u8 *) pParam_p->m_pArg);
// check value range
switch ((tEplNmtCommand) bNmtCommand) {
case kEplNmtCmdResetNode:
@@ -1115,7 +1111,7 @@ tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiProcessEvent(tEplEvent * pEplEvent_p)
+static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p)
{
tEplKernel Ret;
tEplEventError *pEventError;
@@ -1188,15 +1184,14 @@ static tEplKernel PUBLIC EplApiProcessEvent(tEplEvent * pEplEvent_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange
- NmtStateChange_p)
+static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
{
tEplKernel Ret = kEplSuccessful;
- BYTE bNmtState;
+ u8 bNmtState;
tEplApiEventArg EventArg;
// save NMT state in OD
- bNmtState = (BYTE) NmtStateChange_p.m_NewNmtState;
+ bNmtState = (u8) NmtStateChange_p.m_NewNmtState;
Ret = EplObdWriteEntry(0x1F8C, 0, &bNmtState, 1);
if (Ret != kEplSuccessful) {
goto Exit;
@@ -1275,7 +1270,7 @@ static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange
case kEplNmtCsNotActive:
{
// indicate completion of reset in NMT_ResetCmd_U8
- bNmtState = (BYTE) kEplNmtCmdInvalidService;
+ bNmtState = (u8) kEplNmtCmdInvalidService;
Ret = EplObdWriteEntry(0x1F9E, 0, &bNmtState, 1);
if (Ret != kEplSuccessful) {
goto Exit;
@@ -1411,14 +1406,14 @@ static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
+static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
{
tEplKernel Ret = kEplSuccessful;
tEplDllConfigParam DllConfigParam;
tEplDllIdentParam DllIdentParam;
tEplObdSize ObdSize;
- WORD wTemp;
- BYTE bTemp;
+ u16 wTemp;
+ u8 bTemp;
// configure Dll
EPL_MEMSET(&DllConfigParam, 0, sizeof(DllConfigParam));
@@ -1634,11 +1629,11 @@ static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiUpdateObd(void)
+static tEplKernel EplApiUpdateObd(void)
{
tEplKernel Ret = kEplSuccessful;
- WORD wTemp;
- BYTE bTemp;
+ u16 wTemp;
+ u8 bTemp;
// set node id in OD
Ret = EplObdSetNodeId(EplApiInstance_g.m_InitParam.m_uiNodeId, // node id
@@ -1680,14 +1675,14 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
} */
}
- wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload;
+ wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload;
Ret = EplObdWriteEntry(0x1F98, 1, &wTemp, 2);
/* if(Ret != kEplSuccessful)
{
goto Exit;
}*/
- wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload;
+ wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload;
Ret = EplObdWriteEntry(0x1F98, 2, &wTemp, 2);
/* if(Ret != kEplSuccessful)
{
@@ -1706,7 +1701,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
if (EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit <=
EPL_C_DLL_ISOCHR_MAX_PAYL) {
wTemp =
- (WORD) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit;
+ (u16) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit;
Ret = EplObdWriteEntry(0x1F98, 4, &wTemp, 2);
/* if(Ret != kEplSuccessful)
{
@@ -1717,7 +1712,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
if (EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit <=
EPL_C_DLL_ISOCHR_MAX_PAYL) {
wTemp =
- (WORD) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit;
+ (u16) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit;
Ret = EplObdWriteEntry(0x1F98, 5, &wTemp, 2);
/* if(Ret != kEplSuccessful)
{
@@ -1735,7 +1730,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
}*/
if (EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt <= 0xFF) {
- bTemp = (BYTE) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt;
+ bTemp = (u8) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt;
Ret = EplObdWriteEntry(0x1F98, 7, &bTemp, 1);
/* if(Ret != kEplSuccessful)
{
@@ -1745,7 +1740,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
if (EplApiInstance_g.m_InitParam.m_uiAsyncMtu <=
EPL_C_DLL_MAX_ASYNC_MTU) {
- wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiAsyncMtu;
+ wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiAsyncMtu;
Ret = EplObdWriteEntry(0x1F98, 8, &wTemp, 2);
/* if(Ret != kEplSuccessful)
{
@@ -1754,7 +1749,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
}
if (EplApiInstance_g.m_InitParam.m_uiPrescaler <= 1000) {
- wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiPrescaler;
+ wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiPrescaler;
Ret = EplObdWriteEntry(0x1F98, 9, &wTemp, 2);
// ignore return code
Ret = kEplSuccessful;
@@ -1844,7 +1839,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
// write Device Name (0x1008)
Ret =
EplObdWriteEntry(0x1008, 0,
- (void GENERIC *)EplApiInstance_g.
+ (void *)EplApiInstance_g.
m_InitParam.m_pszDevName,
(tEplObdSize) strlen(EplApiInstance_g.
m_InitParam.
@@ -1859,7 +1854,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
// write Hardware version (0x1009)
Ret =
EplObdWriteEntry(0x1009, 0,
- (void GENERIC *)EplApiInstance_g.
+ (void *)EplApiInstance_g.
m_InitParam.m_pszHwVersion,
(tEplObdSize) strlen(EplApiInstance_g.
m_InitParam.
@@ -1874,7 +1869,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
// write Software version (0x100A)
Ret =
EplObdWriteEntry(0x100A, 0,
- (void GENERIC *)EplApiInstance_g.
+ (void *)EplApiInstance_g.
m_InitParam.m_pszSwVersion,
(tEplObdSize) strlen(EplApiInstance_g.
m_InitParam.
@@ -1905,7 +1900,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
//---------------------------------------------------------------------------
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished * pSdoComFinished_p)
+static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p)
{
tEplKernel Ret;
tEplApiEventArg EventArg;
@@ -1946,10 +1941,10 @@ static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished * pSdoComFinished_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p,
- tEplNmtNodeEvent NodeEvent_p,
- tEplNmtState NmtState_p,
- WORD wErrorCode_p, BOOL fMandatory_p)
+static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p,
+ tEplNmtNodeEvent NodeEvent_p,
+ tEplNmtState NmtState_p,
+ u16 wErrorCode_p, BOOL fMandatory_p)
{
tEplKernel Ret;
tEplApiEventArg EventArg;
@@ -1990,9 +1985,9 @@ static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
- tEplNmtState NmtState_p,
- WORD wErrorCode_p)
+static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
+ tEplNmtState NmtState_p,
+ u16 wErrorCode_p)
{
tEplKernel Ret;
tEplApiEventArg EventArg;
@@ -2033,8 +2028,7 @@ static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiCbLedStateChange(tEplLedType LedType_p,
- BOOL fOn_p)
+static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p)
{
tEplKernel Ret;
tEplApiEventArg EventArg;
diff --git a/drivers/staging/epl/EplApiLinuxKernel.c b/drivers/staging/epl/EplApiLinuxKernel.c
index 05ca0628d6a..cb3e275e3aa 100644
--- a/drivers/staging/epl/EplApiLinuxKernel.c
+++ b/drivers/staging/epl/EplApiLinuxKernel.c
@@ -72,9 +72,6 @@
// kernel modul and driver
-//#include <linux/version.h>
-//#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
@@ -92,25 +89,11 @@
#include <asm/uaccess.h>
#include <linux/vmalloc.h>
-#ifdef CONFIG_DEVFS_FS
-#include <linux/major.h>
-#include <linux/devfs_fs_kernel.h>
-#endif
-
#include "Epl.h"
#include "EplApiLinux.h"
//#include "kernel/EplPdokCal.h"
#include "proc_fs.h"
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- // remove ("make invisible") obsolete symbols for kernel versions 2.6
- // and higher
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#define EXPORT_NO_SYMBOLS
-#else
-#error "This driver needs a 2.6.x kernel or higher"
-#endif
/***************************************************************************/
/* */
@@ -139,7 +122,7 @@ MODULE_DESCRIPTION("EPL API driver");
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#else
#define TGT_DBG_SIGNAL_TRACE_POINT(p)
@@ -159,19 +142,10 @@ void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
// Global variables
//---------------------------------------------------------------------------
-#ifdef CONFIG_DEVFS_FS
-
- // driver major number
-static int nDrvMajorNumber_g;
-
-#else
-
// device number (major and minor)
static dev_t nDevNum_g;
static struct cdev *pEpl_cdev_g;
-#endif
-
static volatile unsigned int uiEplState_g = EPL_STATE_NOTOPEN;
static struct semaphore SemaphoreCbEvent_g; // semaphore for EplLinCbEvent
@@ -204,11 +178,11 @@ typedef struct {
// Prototypes of internal functions
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
- tEplApiEventArg * pEventArg_p, // IN: event argument (union)
- void GENERIC * pUserArg_p);
+tEplKernel EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
+ tEplApiEventArg *pEventArg_p, // IN: event argument (union)
+ void *pUserArg_p);
-tEplKernel PUBLIC EplLinCbSync(void);
+tEplKernel EplLinCbSync(void);
static int __init EplLinInit(void);
static void __exit EplLinExit(void);
@@ -226,8 +200,6 @@ static int EplLinIoctl(struct inode *pDeviceFile_p, struct file *pInstance_p,
// Kernel Module specific Data Structures
//---------------------------------------------------------------------------
-EXPORT_NO_SYMBOLS;
-
module_init(EplLinInit);
module_exit(EplLinExit);
@@ -259,9 +231,6 @@ static int __init EplLinInit(void)
tEplKernel EplRet;
int iErr;
int iRet;
-#ifdef CONFIG_DEVFS_FS
- int nMinorNumber;
-#endif
TRACE0("EPL: + EplLinInit...\n");
TRACE2("EPL: Driver build: %s / %s\n", __DATE__, __TIME__);
@@ -275,44 +244,6 @@ static int __init EplLinInit(void)
init_waitqueue_head(&WaitQueueProcess_g);
init_waitqueue_head(&WaitQueueRelease_g);
-#ifdef CONFIG_DEVFS_FS
-
- // register character device handler
- TRACE2("EPL: Installing Driver '%s', Version %s...\n",
- EPLLIN_DRV_NAME, EPL_PRODUCT_VERSION);
- TRACE0("EPL: (using dynamic major number assignment)\n");
- nDrvMajorNumber_g =
- register_chrdev(0, EPLLIN_DRV_NAME, &EplLinFileOps_g);
- if (nDrvMajorNumber_g != 0) {
- TRACE2
- ("EPL: Driver '%s' installed successful, assigned MajorNumber=%d\n",
- EPLLIN_DRV_NAME, nDrvMajorNumber_g);
- } else {
- TRACE1
- ("EPL: ERROR: Driver '%s' is unable to get a free MajorNumber!\n",
- EPLLIN_DRV_NAME);
- iRet = -EIO;
- goto Exit;
- }
-
- // create device node in DEVFS
- nMinorNumber = 0;
- TRACE1("EPL: Creating device node '/dev/%s'...\n", EPLLIN_DEV_NAME);
- iErr =
- devfs_mk_cdev(MKDEV(nDrvMajorNumber_g, nMinorNumber),
- S_IFCHR | S_IRUGO | S_IWUGO, EPLLIN_DEV_NAME);
- if (iErr == 0) {
- TRACE1("EPL: Device node '/dev/%s' created successful.\n",
- EPLLIN_DEV_NAME);
- } else {
- TRACE1("EPL: ERROR: unable to create device node '/dev/%s'\n",
- EPLLIN_DEV_NAME);
- iRet = -EIO;
- goto Exit;
- }
-
-#else
-
// register character device handler
// only one Minor required
TRACE2("EPL: Installing Driver '%s', Version %s...\n",
@@ -341,7 +272,6 @@ static int __init EplLinInit(void)
iRet = -EIO;
goto Exit;
}
-#endif
// create device node in PROCFS
EplRet = EplLinProcInit();
@@ -377,25 +307,12 @@ static void __exit EplLinExit(void)
TRACE0("EPL: + EplLinExit...\n");
-#ifdef CONFIG_DEVFS_FS
-
- // remove device node from DEVFS
- devfs_remove(EPLLIN_DEV_NAME);
- TRACE1("EPL: Device node '/dev/%s' removed.\n", EPLLIN_DEV_NAME);
-
- // unregister character device handler
- unregister_chrdev(nDrvMajorNumber_g, EPLLIN_DRV_NAME);
-
-#else
-
// remove cdev structure
cdev_del(pEpl_cdev_g);
// unregister character device handler
unregister_chrdev_region(nDevNum_g, 1);
-#endif
-
TRACE1("EPL: Driver '%s' removed.\n", EPLLIN_DRV_NAME);
TRACE0("EPL: - EplLinExit\n");
@@ -416,8 +333,6 @@ static int EplLinOpen(struct inode *pDeviceFile_p, // information about the devi
TRACE0("EPL: + EplLinOpen...\n");
- MOD_INC_USE_COUNT;
-
if (uiEplState_g != EPL_STATE_NOTOPEN) { // stack already initialized
iRet = -EALREADY;
} else {
@@ -490,8 +405,6 @@ static int EplLinRelease(struct inode *pDeviceFile_p, // information about the d
uiEplState_g = EPL_STATE_NOTOPEN;
iRet = 0;
- MOD_DEC_USE_COUNT;
-
TRACE1("EPL: - EplLinRelease (iRet=%d)\n", iRet);
return (iRet);
@@ -1158,9 +1071,9 @@ static int EplLinIoctl(struct inode *pDeviceFile_p, // information about the dev
// //
//=========================================================================//
-tEplKernel PUBLIC EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
- tEplApiEventArg * pEventArg_p, // IN: event argument (union)
- void GENERIC * pUserArg_p)
+tEplKernel EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
+ tEplApiEventArg *pEventArg_p, // IN: event argument (union)
+ void *pUserArg_p)
{
tEplKernel EplRet = kEplSuccessful;
int iErr;
@@ -1224,7 +1137,7 @@ tEplKernel PUBLIC EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type
return EplRet;
}
-tEplKernel PUBLIC EplLinCbSync(void)
+tEplKernel EplLinCbSync(void)
{
tEplKernel EplRet = kEplSuccessful;
int iErr;
diff --git a/drivers/staging/epl/EplApiProcessImage.c b/drivers/staging/epl/EplApiProcessImage.c
index 2b2fdf229a7..7d55086a8e4 100644
--- a/drivers/staging/epl/EplApiProcessImage.c
+++ b/drivers/staging/epl/EplApiProcessImage.c
@@ -69,11 +69,8 @@
****************************************************************************/
#include "Epl.h"
-//#include "kernel/EplPdokCal.h"
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
-#include <asm/uaccess.h>
-#endif
+#include <linux/uaccess.h>
/***************************************************************************/
/* */
@@ -129,10 +126,10 @@
#if ((EPL_API_PROCESS_IMAGE_SIZE_IN > 0) || (EPL_API_PROCESS_IMAGE_SIZE_OUT > 0))
typedef struct {
#if EPL_API_PROCESS_IMAGE_SIZE_IN > 0
- BYTE m_abProcessImageInput[EPL_API_PROCESS_IMAGE_SIZE_IN];
+ u8 m_abProcessImageInput[EPL_API_PROCESS_IMAGE_SIZE_IN];
#endif
#if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0
- BYTE m_abProcessImageOutput[EPL_API_PROCESS_IMAGE_SIZE_OUT];
+ u8 m_abProcessImageOutput[EPL_API_PROCESS_IMAGE_SIZE_OUT];
#endif
} tEplApiProcessImageInstance;
@@ -169,7 +166,7 @@ static tEplApiProcessImageInstance EplApiProcessImageInstance_g;
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiProcessImageSetup(void)
+tEplKernel EplApiProcessImageSetup(void)
{
tEplKernel Ret = kEplSuccessful;
#if ((EPL_API_PROCESS_IMAGE_SIZE_IN > 0) || (EPL_API_PROCESS_IMAGE_SIZE_OUT > 0))
@@ -280,24 +277,16 @@ tEplKernel PUBLIC EplApiProcessImageSetup(void)
// State:
//----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiProcessImageExchangeIn(tEplApiProcessImage * pPI_p)
+tEplKernel EplApiProcessImageExchangeIn(tEplApiProcessImage *pPI_p)
{
tEplKernel Ret = kEplSuccessful;
#if EPL_API_PROCESS_IMAGE_SIZE_IN > 0
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
copy_to_user(pPI_p->m_pImage,
EplApiProcessImageInstance_g.m_abProcessImageInput,
min(pPI_p->m_uiSize,
sizeof(EplApiProcessImageInstance_g.
m_abProcessImageInput)));
-#else
- EPL_MEMCPY(pPI_p->m_pImage,
- EplApiProcessImageInstance_g.m_abProcessImageInput,
- min(pPI_p->m_uiSize,
- sizeof(EplApiProcessImageInstance_g.
- m_abProcessImageInput)));
-#endif
#endif
return Ret;
@@ -315,24 +304,16 @@ tEplKernel PUBLIC EplApiProcessImageExchangeIn(tEplApiProcessImage * pPI_p)
// State:
//----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiProcessImageExchangeOut(tEplApiProcessImage * pPI_p)
+tEplKernel EplApiProcessImageExchangeOut(tEplApiProcessImage *pPI_p)
{
tEplKernel Ret = kEplSuccessful;
#if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
copy_from_user(EplApiProcessImageInstance_g.m_abProcessImageOutput,
pPI_p->m_pImage,
min(pPI_p->m_uiSize,
sizeof(EplApiProcessImageInstance_g.
m_abProcessImageOutput)));
-#else
- EPL_MEMCPY(EplApiProcessImageInstance_g.m_abProcessImageOutput,
- pPI_p->m_pImage,
- min(pPI_p->m_uiSize,
- sizeof(EplApiProcessImageInstance_g.
- m_abProcessImageOutput)));
-#endif
#endif
return Ret;
diff --git a/drivers/staging/epl/EplDll.h b/drivers/staging/epl/EplDll.h
index 36657f2daf8..b960199bd0e 100644
--- a/drivers/staging/epl/EplDll.h
+++ b/drivers/staging/epl/EplDll.h
@@ -135,22 +135,22 @@ typedef struct {
unsigned int m_uiNodeId; // local node ID
// 0x1F82: NMT_FeatureFlags_U32
- DWORD m_dwFeatureFlags;
+ u32 m_dwFeatureFlags;
// Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
- DWORD m_dwCycleLen; // required for error detection
+ u32 m_dwCycleLen; // required for error detection
// 0x1F98: NMT_CycleTiming_REC
// 0x1F98.1: IsochrTxMaxPayload_U16
unsigned int m_uiIsochrTxMaxPayload; // const
// 0x1F98.2: IsochrRxMaxPayload_U16
unsigned int m_uiIsochrRxMaxPayload; // const
// 0x1F98.3: PResMaxLatency_U32
- DWORD m_dwPresMaxLatency; // const in [ns], only required for IdentRes
+ u32 m_dwPresMaxLatency; // const in [ns], only required for IdentRes
// 0x1F98.4: PReqActPayloadLimit_U16
unsigned int m_uiPreqActPayloadLimit; // required for initialisation (+24 bytes)
// 0x1F98.5: PResActPayloadLimit_U16
unsigned int m_uiPresActPayloadLimit; // required for initialisation of Pres frame (+24 bytes)
// 0x1F98.6: ASndMaxLatency_U32
- DWORD m_dwAsndMaxLatency; // const in [ns], only required for IdentRes
+ u32 m_dwAsndMaxLatency; // const in [ns], only required for IdentRes
// 0x1F98.7: MultiplCycleCnt_U8
unsigned int m_uiMultiplCycleCnt; // required for error detection
// 0x1F98.8: AsyncMTU_U16
@@ -159,42 +159,42 @@ typedef struct {
// $$$ Multiplexed Slot
// 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
- DWORD m_dwLossOfFrameTolerance;
+ u32 m_dwLossOfFrameTolerance;
// 0x1F8A: NMT_MNCycleTiming_REC
// 0x1F8A.1: WaitSoCPReq_U32 in [ns]
- DWORD m_dwWaitSocPreq;
+ u32 m_dwWaitSocPreq;
// 0x1F8A.2: AsyncSlotTimeout_U32 in [ns]
- DWORD m_dwAsyncSlotTimeout;
+ u32 m_dwAsyncSlotTimeout;
} tEplDllConfigParam;
typedef struct {
unsigned int m_uiSizeOfStruct;
- DWORD m_dwDeviceType; // NMT_DeviceType_U32
- DWORD m_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32
- DWORD m_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32
- DWORD m_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32
- DWORD m_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32
- QWORD m_qwVendorSpecificExt1;
- DWORD m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
- DWORD m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
- DWORD m_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
- DWORD m_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
- DWORD m_dwIpAddress;
- DWORD m_dwSubnetMask;
- DWORD m_dwDefaultGateway;
- BYTE m_sHostname[32];
- BYTE m_abVendorSpecificExt2[48];
+ u32 m_dwDeviceType; // NMT_DeviceType_U32
+ u32 m_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32
+ u32 m_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32
+ u32 m_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32
+ u32 m_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32
+ u64 m_qwVendorSpecificExt1;
+ u32 m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
+ u32 m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
+ u32 m_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
+ u32 m_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
+ u32 m_dwIpAddress;
+ u32 m_dwSubnetMask;
+ u32 m_dwDefaultGateway;
+ u8 m_sHostname[32];
+ u8 m_abVendorSpecificExt2[48];
} tEplDllIdentParam;
typedef struct {
unsigned int m_uiNodeId;
- WORD m_wPreqPayloadLimit; // object 0x1F8B: NMT_MNPReqPayloadLimitList_AU16
- WORD m_wPresPayloadLimit; // object 0x1F8D: NMT_PResPayloadLimitList_AU16
- DWORD m_dwPresTimeout; // object 0x1F92: NMT_MNCNPResTimeout_AU32
+ u16 m_wPreqPayloadLimit; // object 0x1F8B: NMT_MNPReqPayloadLimitList_AU16
+ u16 m_wPresPayloadLimit; // object 0x1F8D: NMT_PResPayloadLimitList_AU16
+ u32 m_dwPresTimeout; // object 0x1F92: NMT_MNCNPResTimeout_AU32
} tEplDllNodeInfo;
diff --git a/drivers/staging/epl/EplDllCal.h b/drivers/staging/epl/EplDllCal.h
index 24460087e98..70b27b1b676 100644
--- a/drivers/staging/epl/EplDllCal.h
+++ b/drivers/staging/epl/EplDllCal.h
@@ -112,7 +112,7 @@ typedef struct {
typedef struct {
tEplDllReqServiceId m_Service;
unsigned int m_uiNodeId;
- BYTE m_bSoaFlag1;
+ u8 m_bSoaFlag1;
} tEplDllCalIssueRequest;
diff --git a/drivers/staging/epl/EplDllk.c b/drivers/staging/epl/EplDllk.c
index 9e22641055c..25d2c34325d 100644
--- a/drivers/staging/epl/EplDllk.c
+++ b/drivers/staging/epl/EplDllk.c
@@ -121,8 +121,8 @@
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -195,12 +195,12 @@ typedef enum {
} tEplDllState;
typedef struct {
- BYTE m_be_abSrcMac[6];
+ u8 m_be_abSrcMac[6];
tEdrvTxBuffer *m_pTxBuffer; // Buffers for Tx-Frames
unsigned int m_uiMaxTxFrames;
- BYTE m_bFlag1; // Flag 1 with EN, EC for PRes, StatusRes
- BYTE m_bMnFlag1; // Flag 1 with EA, ER from PReq, SoA of MN
- BYTE m_bFlag2; // Flag 2 with PR and RS for PRes, StatusRes, IdentRes
+ u8 m_bFlag1; // Flag 1 with EN, EC for PRes, StatusRes
+ u8 m_bMnFlag1; // Flag 1 with EA, ER from PReq, SoA of MN
+ u8 m_bFlag2; // Flag 2 with PR and RS for PRes, StatusRes, IdentRes
tEplDllConfigParam m_DllConfigParam;
tEplDllIdentParam m_DllIdentParam;
tEplDllState m_DllState;
@@ -257,7 +257,7 @@ static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
// called by high resolution timer module to monitor EPL cycle as CN
#if EPL_TIMER_USE_HIGHRES != FALSE
-static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg * pEventArg_p);
+static tEplKernel EplDllkCbCnTimer(tEplTimerEventArg *pEventArg_p);
#endif
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
@@ -278,10 +278,9 @@ static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId
ReqServiceId_p,
unsigned int uiNodeId_p);
-static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg * pEventArg_p);
+static tEplKernel EplDllkCbMnTimerCycle(tEplTimerEventArg *pEventArg_p);
-static tEplKernel PUBLIC EplDllkCbMnTimerResponse(tEplTimerEventArg *
- pEventArg_p);
+static tEplKernel EplDllkCbMnTimerResponse(tEplTimerEventArg *pEventArg_p);
#endif
@@ -514,7 +513,7 @@ tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
EPL_C_DLL_ETHERTYPE_EPL);
// source node ID
AmiSetByteToLe(&pTxFrame->m_le_bSrcNodeId,
- (BYTE) EplDllkInstance_g.m_DllConfigParam.
+ (u8) EplDllkInstance_g.m_DllConfigParam.
m_uiNodeId);
// source MAC address
EPL_MEMCPY(&pTxFrame->m_be_abSrcMac[0],
@@ -531,7 +530,7 @@ tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
{ // IdentResponses and StatusResponses are Broadcast
AmiSetByteToLe(&pTxFrame->
m_le_bDstNodeId,
- (BYTE)
+ (u8)
EPL_C_ADR_BROADCAST);
break;
}
@@ -550,10 +549,10 @@ tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
EPL_C_DLL_MULTICAST_SOC);
// destination node ID
AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
- (BYTE) EPL_C_ADR_BROADCAST);
+ (u8) EPL_C_ADR_BROADCAST);
// reset Flags
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag1, (BYTE) 0);
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag2, (BYTE) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag1, (u8) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag2, (u8) 0);
break;
case kEplMsgTypeSoa:
@@ -562,13 +561,13 @@ tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
EPL_C_DLL_MULTICAST_SOA);
// destination node ID
AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
- (BYTE) EPL_C_ADR_BROADCAST);
+ (u8) EPL_C_ADR_BROADCAST);
// reset Flags
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag1, (BYTE) 0);
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag2, (BYTE) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag1, (u8) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag2, (u8) 0);
// EPL profile version
AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bEplVersion,
- (BYTE) EPL_SPEC_VERSION);
+ (u8) EPL_SPEC_VERSION);
break;
case kEplMsgTypePres:
@@ -577,18 +576,18 @@ tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
EPL_C_DLL_MULTICAST_PRES);
// destination node ID
AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
- (BYTE) EPL_C_ADR_BROADCAST);
+ (u8) EPL_C_ADR_BROADCAST);
// reset Flags
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, (BYTE) 0);
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, (BYTE) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, (u8) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, (u8) 0);
// PDO size
//AmiSetWordToLe(&pTxFrame->m_Data.m_Pres.m_le_wSize, 0);
break;
case kEplMsgTypePreq:
// reset Flags
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, (BYTE) 0);
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag2, (BYTE) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, (u8) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag2, (u8) 0);
// PDO size
//AmiSetWordToLe(&pTxFrame->m_Data.m_Preq.m_le_wSize, 0);
break;
@@ -597,7 +596,7 @@ tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
break;
}
// EPL message type
- AmiSetByteToLe(&pTxFrame->m_le_bMessageType, (BYTE) MsgType_p);
+ AmiSetByteToLe(&pTxFrame->m_le_bMessageType, (u8) MsgType_p);
}
*ppFrame_p = pTxFrame;
@@ -673,7 +672,7 @@ tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
tEdrvTxBuffer *pTxBuffer;
unsigned int uiHandle;
unsigned int uiFrameSize;
- BYTE abMulticastMac[6];
+ u8 abMulticastMac[6];
tEplDllAsyncReqPriority AsyncReqPriority;
unsigned int uiFrameCount;
tEplNmtState NmtState;
@@ -712,7 +711,7 @@ tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
// EPL profile version
AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
m_IdentResponse.m_le_bEplProfileVersion,
- (BYTE) EPL_SPEC_VERSION);
+ (u8) EPL_SPEC_VERSION);
// FeatureFlags
AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
m_IdentResponse.m_le_dwFeatureFlags,
@@ -721,18 +720,18 @@ tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
// MTU
AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
m_IdentResponse.m_le_wMtu,
- (WORD) EplDllkInstance_g.
+ (u16) EplDllkInstance_g.
m_DllConfigParam.m_uiAsyncMtu);
// PollInSize
AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
m_IdentResponse.m_le_wPollInSize,
- (WORD) EplDllkInstance_g.
+ (u16) EplDllkInstance_g.
m_DllConfigParam.
m_uiPreqActPayloadLimit);
// PollOutSize
AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
m_IdentResponse.m_le_wPollOutSize,
- (WORD) EplDllkInstance_g.
+ (u16) EplDllkInstance_g.
m_DllConfigParam.
m_uiPresActPayloadLimit);
// ResponseTime / PresMaxLatency
@@ -936,7 +935,7 @@ tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
// EplDllkInstance_g.m_aNodeInfo[uiIndex].m_uiNodeId = uiIndex + 1;
EplDllkInstance_g.m_aNodeInfo[uiIndex].
m_wPresPayloadLimit =
- (WORD) EplDllkInstance_g.
+ (u16) EplDllkInstance_g.
m_DllConfigParam.
m_uiIsochrRxMaxPayload;
}
@@ -1233,7 +1232,7 @@ tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
}
if (uiFrameCount > 0) {
EplDllkInstance_g.m_bFlag2 =
- (BYTE) (((AsyncReqPriority <<
+ (u8) (((AsyncReqPriority <<
EPL_FRAME_FLAG2_PR_SHIFT)
& EPL_FRAME_FLAG2_PR)
| (uiFrameCount &
@@ -1307,7 +1306,7 @@ tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
}
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bFlag2,
EplDllkInstance_g.
@@ -1533,7 +1532,7 @@ tEplKernel EplDllkSetAsndServiceIdFilter(tEplDllAsndServiceId ServiceId_p,
//
//---------------------------------------------------------------------------
-tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
+tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, u8 bSoaFlag1_p)
{
tEplKernel Ret = kEplSuccessful;
tEplDllkNodeInfo *pNodeInfo;
@@ -1664,7 +1663,7 @@ tEplKernel EplDllkAddNode(tEplDllNodeInfo * pNodeInfo_p)
pIntNodeInfo->m_pPreqTxBuffer =
&EplDllkInstance_g.m_pTxBuffer[uiHandle];
AmiSetByteToLe(&pFrame->m_le_bDstNodeId,
- (BYTE) pNodeInfo_p->m_uiNodeId);
+ (u8) pNodeInfo_p->m_uiNodeId);
// set up destination MAC address
EPL_MEMCPY(pFrame->m_be_abDstMac, pIntNodeInfo->m_be_abMacAddr,
@@ -2431,7 +2430,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
tEplDllReqServiceId ReqServiceId;
unsigned int uiAsndServiceId;
unsigned int uiNodeId;
- BYTE bFlag1;
+ u8 bFlag1;
BENCHMARK_MOD_02_SET(3);
NmtState = EplNmtkGetNmtState();
@@ -2466,7 +2465,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
// update frame (NMT state, RD, RS, PR, MS, EN flags)
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bFlag2,
EplDllkInstance_g.
@@ -2541,7 +2540,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
// update frame (NMT state, RD, RS, PR, MS, EN flags)
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bFlag2,
EplDllkInstance_g.
@@ -2803,7 +2802,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
}
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bFlag2,
EplDllkInstance_g.m_bFlag2);
@@ -2888,7 +2887,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
m_Payload.
m_StatusResponse.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->
m_Data.m_Asnd.
m_Payload.
@@ -2954,7 +2953,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
m_Payload.
m_IdentResponse.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->
m_Data.m_Asnd.
m_Payload.
@@ -3155,7 +3154,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
Exit:
if (Ret != kEplSuccessful) {
- DWORD dwArg;
+ u32 dwArg;
BENCHMARK_MOD_02_TOGGLE(9);
@@ -3286,7 +3285,7 @@ static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p)
m_Payload.
m_StatusResponse.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
m_Payload.
m_StatusResponse.
@@ -3322,7 +3321,7 @@ static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p)
m_Payload.
m_IdentResponse.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
m_Payload.
m_IdentResponse.
@@ -3362,12 +3361,12 @@ static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p)
if ((AmiGetByteFromLe
(&pTxFrame->
m_le_bMessageType)
- == (BYTE) kEplMsgTypeAsnd)
+ == (u8) kEplMsgTypeAsnd)
&&
(AmiGetByteFromLe
(&pTxFrame->m_Data.m_Asnd.
m_le_bServiceId)
- == (BYTE) kEplDllAsndNmtCommand)) { // post event directly to NmtMnu module
+ == (u8) kEplDllAsndNmtCommand)) { // post event directly to NmtMnu module
Event.m_EventSink =
kEplEventSinkNmtMnu;
Event.m_EventType =
@@ -3449,7 +3448,7 @@ static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p)
Exit:
if (Ret != kEplSuccessful) {
- DWORD dwArg;
+ u32 dwArg;
BENCHMARK_MOD_02_TOGGLE(9);
@@ -3485,7 +3484,7 @@ static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
unsigned int uiFrameSize_p)
{
tEplMsgType MsgType;
- WORD wEtherType;
+ u16 wEtherType;
// check frame
if (pFrame_p != NULL) {
@@ -3506,7 +3505,7 @@ static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
if (wEtherType == EPL_C_DLL_ETHERTYPE_EPL) {
// source node ID
AmiSetByteToLe(&pFrame_p->m_le_bSrcNodeId,
- (BYTE) EplDllkInstance_g.
+ (u8) EplDllkInstance_g.
m_DllConfigParam.m_uiNodeId);
// check message type
@@ -3515,7 +3514,7 @@ static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
if (MsgType == 0) {
MsgType = kEplMsgTypeAsnd;
AmiSetByteToLe(&pFrame_p->m_le_bMessageType,
- (BYTE) MsgType);
+ (u8) MsgType);
}
if (MsgType == kEplMsgTypeAsnd) {
@@ -3546,7 +3545,7 @@ static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
//---------------------------------------------------------------------------
#if EPL_TIMER_USE_HIGHRES != FALSE
-static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg * pEventArg_p)
+static tEplKernel EplDllkCbCnTimer(tEplTimerEventArg *pEventArg_p)
{
tEplKernel Ret = kEplSuccessful;
tEplNmtState NmtState;
@@ -3583,7 +3582,7 @@ static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg * pEventArg_p)
Exit:
if (Ret != kEplSuccessful) {
- DWORD dwArg;
+ u32 dwArg;
BENCHMARK_MOD_02_TOGGLE(9);
@@ -3617,7 +3616,7 @@ static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg * pEventArg_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg * pEventArg_p)
+static tEplKernel EplDllkCbMnTimerCycle(tEplTimerEventArg *pEventArg_p)
{
tEplKernel Ret = kEplSuccessful;
tEplNmtState NmtState;
@@ -3639,7 +3638,7 @@ static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg * pEventArg_p)
Exit:
if (Ret != kEplSuccessful) {
- DWORD dwArg;
+ u32 dwArg;
BENCHMARK_MOD_02_TOGGLE(9);
@@ -3670,8 +3669,7 @@ static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg * pEventArg_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplDllkCbMnTimerResponse(tEplTimerEventArg *
- pEventArg_p)
+static tEplKernel EplDllkCbMnTimerResponse(tEplTimerEventArg *pEventArg_p)
{
tEplKernel Ret = kEplSuccessful;
tEplNmtState NmtState;
@@ -3693,7 +3691,7 @@ static tEplKernel PUBLIC EplDllkCbMnTimerResponse(tEplTimerEventArg *
Exit:
if (Ret != kEplSuccessful) {
- DWORD dwArg;
+ u32 dwArg;
BENCHMARK_MOD_02_TOGGLE(9);
@@ -3827,24 +3825,24 @@ static tEplKernel EplDllkMnSendSoa(tEplNmtState NmtState_p,
// update frame (target)
AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
m_le_bReqServiceId,
- (BYTE) EplDllkInstance_g.
+ (u8) EplDllkInstance_g.
m_LastReqServiceId);
AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
m_le_bReqServiceTarget,
- (BYTE) EplDllkInstance_g.
+ (u8) EplDllkInstance_g.
m_uiLastTargetNodeId);
} else { // invite nobody
// update frame (target)
AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
- m_le_bReqServiceId, (BYTE) 0);
+ m_le_bReqServiceId, (u8) 0);
AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
- m_le_bReqServiceTarget, (BYTE) 0);
+ m_le_bReqServiceTarget, (u8) 0);
}
// update frame (NMT state)
AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bNmtStatus,
- (BYTE) NmtState_p);
+ (u8) NmtState_p);
// send SoA frame
Ret = EdrvSendTxMsg(pTxBuffer);
@@ -3921,7 +3919,7 @@ static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p,
tEplKernel Ret = kEplSuccessful;
tEdrvTxBuffer *pTxBuffer = NULL;
tEplFrame *pTxFrame;
- BYTE bFlag1 = 0;
+ u8 bFlag1 = 0;
if (EplDllkInstance_g.m_pCurNodeInfo == NULL) { // start with first isochronous CN
EplDllkInstance_g.m_pCurNodeInfo =
@@ -3972,7 +3970,7 @@ static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p,
if (pTxBuffer == &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]) { // PRes of MN will be sent
// update NMT state
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bNmtStatus,
- (BYTE) NmtState_p);
+ (u8) NmtState_p);
*pDllStateProposed_p = kEplDllMsWaitSoaTrig;
}
// $$$ d.k. set EPL_FRAME_FLAG1_MS if necessary
@@ -4015,7 +4013,7 @@ static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId
unsigned int uiNodeId_p)
{
tEplKernel Ret = kEplSuccessful;
- BYTE abBuffer[18];
+ u8 abBuffer[18];
tEplFrame *pFrame = (tEplFrame *) abBuffer;
tEplFrameInfo FrameInfo;
@@ -4026,13 +4024,13 @@ static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId
// ASnd service registered?
if (EplDllkInstance_g.m_aAsndFilter[ReqServiceId_p] == kEplDllAsndFilterAny) { // ASnd service ID is registered
AmiSetByteToLe(&pFrame->m_le_bSrcNodeId,
- (BYTE) uiNodeId_p);
+ (u8) uiNodeId_p);
// EPL MsgType ASnd
AmiSetByteToLe(&pFrame->m_le_bMessageType,
- (BYTE) kEplMsgTypeAsnd);
+ (u8) kEplMsgTypeAsnd);
// ASnd Service ID
AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId,
- (BYTE) ReqServiceId_p);
+ (u8) ReqServiceId_p);
// create frame info structure
FrameInfo.m_pFrame = pFrame;
FrameInfo.m_uiFrameSize = 18; // empty non existing ASnd frame
diff --git a/drivers/staging/epl/EplDllkCal.c b/drivers/staging/epl/EplDllkCal.c
index 359083ebe12..0e283d5d018 100644
--- a/drivers/staging/epl/EplDllkCal.c
+++ b/drivers/staging/epl/EplDllkCal.c
@@ -142,9 +142,9 @@ typedef struct {
tShbInstance m_ShbInstanceTxGen; // FIFO for Tx frames with generic priority
#else
unsigned int m_uiFrameSizeNmt;
- BYTE m_abFrameNmt[1500];
+ u8 m_abFrameNmt[1500];
unsigned int m_uiFrameSizeGen;
- BYTE m_abFrameGen[1500];
+ u8 m_abFrameGen[1500];
#endif
tEplDllkCalStatistics m_Statistics;
@@ -202,7 +202,7 @@ static tEplDllkCalInstance EplDllkCalInstance_g;
//
//---------------------------------------------------------------------------
-tEplKernel EplDllkCalAddInstance()
+tEplKernel EplDllkCalAddInstance(void)
{
tEplKernel Ret = kEplSuccessful;
#ifndef EPL_NO_FIFO
@@ -279,7 +279,7 @@ tEplKernel EplDllkCalAddInstance()
//
//---------------------------------------------------------------------------
-tEplKernel EplDllkCalDelInstance()
+tEplKernel EplDllkCalDelInstance(void)
{
tEplKernel Ret = kEplSuccessful;
#ifndef EPL_NO_FIFO
@@ -536,7 +536,7 @@ tEplKernel EplDllkCalAsyncGetTxFrame(void *pFrame_p,
case kEplDllAsyncReqPrioNmt: // NMT request priority
ShbError =
ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxNmt,
- (BYTE *) pFrame_p, *puiFrameSize_p,
+ (u8 *) pFrame_p, *puiFrameSize_p,
&ulFrameSize);
// returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
break;
@@ -544,7 +544,7 @@ tEplKernel EplDllkCalAsyncGetTxFrame(void *pFrame_p,
default: // generic priority
ShbError =
ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxGen,
- (BYTE *) pFrame_p, *puiFrameSize_p,
+ (u8 *) pFrame_p, *puiFrameSize_p,
&ulFrameSize);
// returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
break;
@@ -876,7 +876,7 @@ tEplKernel EplDllkCalGetStatistics(tEplDllkCalStatistics ** ppStatistics)
//---------------------------------------------------------------------------
tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p,
- unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
+ unsigned int uiNodeId_p, u8 bSoaFlag1_p)
{
tEplKernel Ret = kEplSuccessful;
diff --git a/drivers/staging/epl/EplDlluCal.c b/drivers/staging/epl/EplDlluCal.c
index 7f4a1745023..f96fe84c497 100644
--- a/drivers/staging/epl/EplDlluCal.c
+++ b/drivers/staging/epl/EplDlluCal.c
@@ -173,7 +173,7 @@ static tEplKernel EplDlluCalSetAsndServiceIdFilter(tEplDllAsndServiceId
//
//---------------------------------------------------------------------------
-tEplKernel EplDlluCalAddInstance()
+tEplKernel EplDlluCalAddInstance(void)
{
tEplKernel Ret = kEplSuccessful;
@@ -198,7 +198,7 @@ tEplKernel EplDlluCalAddInstance()
//
//---------------------------------------------------------------------------
-tEplKernel EplDlluCalDelInstance()
+tEplKernel EplDlluCalDelInstance(void)
{
tEplKernel Ret = kEplSuccessful;
@@ -355,7 +355,7 @@ tEplKernel EplDlluCalAsyncSend(tEplFrameInfo * pFrameInfo_p,
//---------------------------------------------------------------------------
tEplKernel EplDlluCalIssueRequest(tEplDllReqServiceId Service_p,
- unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
+ unsigned int uiNodeId_p, u8 bSoaFlag1_p)
{
tEplKernel Ret = kEplSuccessful;
diff --git a/drivers/staging/epl/EplErrorHandlerk.c b/drivers/staging/epl/EplErrorHandlerk.c
index d12521fc99a..6baed04ef11 100644
--- a/drivers/staging/epl/EplErrorHandlerk.c
+++ b/drivers/staging/epl/EplErrorHandlerk.c
@@ -97,9 +97,9 @@
//---------------------------------------------------------------------------
typedef struct {
- DWORD m_dwCumulativeCnt; // subindex 1
- DWORD m_dwThresholdCnt; // subindex 2
- DWORD m_dwThreshold; // subindex 3
+ u32 m_dwCumulativeCnt; // subindex 1
+ u32 m_dwThresholdCnt; // subindex 2
+ u32 m_dwThreshold; // subindex 3
} tEplErrorHandlerkErrorCounter;
@@ -112,9 +112,9 @@ typedef struct {
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
tEplErrorHandlerkErrorCounter m_MnCrcErr; // object 0x1C00
tEplErrorHandlerkErrorCounter m_MnCycTimeExceed; // object 0x1C02
- DWORD m_adwMnCnLossPresCumCnt[254]; // object 0x1C07
- DWORD m_adwMnCnLossPresThrCnt[254]; // object 0x1C08
- DWORD m_adwMnCnLossPresThreshold[254]; // object 0x1C09
+ u32 m_adwMnCnLossPresCumCnt[254]; // object 0x1C07
+ u32 m_adwMnCnLossPresThrCnt[254]; // object 0x1C08
+ u32 m_adwMnCnLossPresThreshold[254]; // object 0x1C09
BOOL m_afMnCnLossPresEvent[254];
#endif
@@ -135,7 +135,7 @@ static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
unsigned int uiIndex_p);
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-static tEplKernel EplErrorHandlerkLinkArray(DWORD * pdwValue_p,
+static tEplKernel EplErrorHandlerkLinkArray(u32 * pdwValue_p,
unsigned int uiValueCount_p,
unsigned int uiIndex_p);
#endif
@@ -176,7 +176,7 @@ static tEplKernel EplErrorHandlerkLinkArray(DWORD * pdwValue_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplErrorHandlerkInit(void)
+tEplKernel EplErrorHandlerkInit(void)
{
tEplKernel Ret;
@@ -203,7 +203,7 @@ tEplKernel PUBLIC EplErrorHandlerkInit(void)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplErrorHandlerkAddInstance(void)
+tEplKernel EplErrorHandlerkAddInstance(void)
{
tEplKernel Ret;
@@ -306,7 +306,7 @@ tEplKernel PUBLIC EplErrorHandlerkAddInstance(void)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplErrorHandlerkDelInstance()
+tEplKernel EplErrorHandlerkDelInstance(void)
{
tEplKernel Ret;
@@ -333,7 +333,7 @@ tEplKernel PUBLIC EplErrorHandlerkDelInstance()
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplErrorHandlerkProcess(tEplEvent * pEvent_p)
+tEplKernel EplErrorHandlerkProcess(tEplEvent *pEvent_p)
{
tEplKernel Ret;
unsigned long ulDllErrorEvents;
@@ -713,7 +713,7 @@ static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
tEplVarParam VarParam;
VarParam.m_pData = &pErrorCounter_p->m_dwCumulativeCnt;
- VarParam.m_Size = sizeof(DWORD);
+ VarParam.m_Size = sizeof(u32);
VarParam.m_uiIndex = uiIndex_p;
VarParam.m_uiSubindex = 0x01;
VarParam.m_ValidFlag = kVarValidAll;
@@ -723,7 +723,7 @@ static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
}
VarParam.m_pData = &pErrorCounter_p->m_dwThresholdCnt;
- VarParam.m_Size = sizeof(DWORD);
+ VarParam.m_Size = sizeof(u32);
VarParam.m_uiIndex = uiIndex_p;
VarParam.m_uiSubindex = 0x02;
VarParam.m_ValidFlag = kVarValidAll;
@@ -733,7 +733,7 @@ static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
}
VarParam.m_pData = &pErrorCounter_p->m_dwThreshold;
- VarParam.m_Size = sizeof(DWORD);
+ VarParam.m_Size = sizeof(u32);
VarParam.m_uiIndex = uiIndex_p;
VarParam.m_uiSubindex = 0x03;
VarParam.m_ValidFlag = kVarValidAll;
@@ -763,18 +763,18 @@ static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
//---------------------------------------------------------------------------
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-static tEplKernel EplErrorHandlerkLinkArray(DWORD * pdwValue_p,
+static tEplKernel EplErrorHandlerkLinkArray(u32 * pdwValue_p,
unsigned int uiValueCount_p,
unsigned int uiIndex_p)
{
tEplKernel Ret = kEplSuccessful;
tEplVarParam VarParam;
tEplObdSize EntrySize;
- BYTE bIndexEntries;
+ u8 bIndexEntries;
EntrySize = (tEplObdSize) sizeof(bIndexEntries);
Ret = EplObdReadEntry(uiIndex_p,
- 0x00, (void GENERIC *)&bIndexEntries, &EntrySize);
+ 0x00, (void *)&bIndexEntries, &EntrySize);
if ((Ret != kEplSuccessful) || (bIndexEntries == 0x00)) {
// Object doesn't exist or invalid entry number
@@ -786,7 +786,7 @@ static tEplKernel EplErrorHandlerkLinkArray(DWORD * pdwValue_p,
uiValueCount_p = bIndexEntries;
}
- VarParam.m_Size = sizeof(DWORD);
+ VarParam.m_Size = sizeof(u32);
VarParam.m_uiIndex = uiIndex_p;
VarParam.m_ValidFlag = kVarValidAll;
diff --git a/drivers/staging/epl/EplEvent.h b/drivers/staging/epl/EplEvent.h
index b6dc1b9b2ab..910bd69a18c 100644
--- a/drivers/staging/epl/EplEvent.h
+++ b/drivers/staging/epl/EplEvent.h
@@ -248,8 +248,8 @@ typedef struct {
tEplEventSource m_EventSource; // module which posted this error event
tEplKernel m_EplError; // EPL error which occured
union {
- BYTE m_bArg;
- DWORD m_dwArg;
+ u8 m_bArg;
+ u32 m_dwArg;
tEplEventSource m_EventSource; // from Eventk/u module (originating error source)
tEplEventObdError m_ObdError; // from Obd module
// tEplErrHistoryEntry m_HistoryEntry; // from Nmtk/u module
@@ -267,10 +267,10 @@ typedef struct {
} tEplErrorHandlerkEvent;
// callback function to get informed about sync event
-typedef tEplKernel(PUBLIC * tEplSyncCb) (void);
+typedef tEplKernel(*tEplSyncCb) (void);
// callback function for generic events
-typedef tEplKernel(PUBLIC * tEplProcessEventCb) (tEplEvent * pEplEvent_p);
+typedef tEplKernel(*tEplProcessEventCb) (tEplEvent *pEplEvent_p);
//---------------------------------------------------------------------------
// function prototypes
diff --git a/drivers/staging/epl/EplEventk.c b/drivers/staging/epl/EplEventk.c
index 8068a6c5a0d..ef36815c798 100644
--- a/drivers/staging/epl/EplEventk.c
+++ b/drivers/staging/epl/EplEventk.c
@@ -100,8 +100,8 @@
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -172,7 +172,7 @@ static void EplEventkRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventkInit(tEplSyncCb pfnCbSync_p)
+tEplKernel EplEventkInit(tEplSyncCb pfnCbSync_p)
{
tEplKernel Ret;
@@ -196,7 +196,7 @@ tEplKernel PUBLIC EplEventkInit(tEplSyncCb pfnCbSync_p)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventkAddInstance(tEplSyncCb pfnCbSync_p)
+tEplKernel EplEventkAddInstance(tEplSyncCb pfnCbSync_p)
{
tEplKernel Ret;
#ifndef EPL_NO_FIFO
@@ -275,7 +275,7 @@ tEplKernel PUBLIC EplEventkAddInstance(tEplSyncCb pfnCbSync_p)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventkDelInstance()
+tEplKernel EplEventkDelInstance(void)
{
tEplKernel Ret;
#ifndef EPL_NO_FIFO
@@ -339,7 +339,7 @@ tEplKernel PUBLIC EplEventkDelInstance()
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventkProcess(tEplEvent * pEvent_p)
+tEplKernel EplEventkProcess(tEplEvent *pEvent_p)
{
tEplKernel Ret;
tEplEventSource EventSource;
@@ -562,7 +562,7 @@ tEplKernel PUBLIC EplEventkProcess(tEplEvent * pEvent_p)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventkPost(tEplEvent * pEvent_p)
+tEplKernel EplEventkPost(tEplEvent *pEvent_p)
{
tEplKernel Ret;
#ifndef EPL_NO_FIFO
@@ -755,12 +755,12 @@ tEplKernel PUBLIC EplEventkPost(tEplEvent * pEvent_p)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventkPostError(tEplEventSource EventSource_p,
- tEplKernel EplError_p,
- unsigned int uiArgSize_p, void *pArg_p)
+tEplKernel EplEventkPostError(tEplEventSource EventSource_p,
+ tEplKernel EplError_p,
+ unsigned int uiArgSize_p, void *pArg_p)
{
tEplKernel Ret;
- BYTE abBuffer[EPL_MAX_EVENT_ARG_SIZE];
+ u8 abBuffer[EPL_MAX_EVENT_ARG_SIZE];
tEplEventError *pEventError = (tEplEventError *) abBuffer;
tEplEvent EplEvent;
@@ -814,7 +814,7 @@ static void EplEventkRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
tShbError ShbError;
//unsigned long ulBlockCount;
//unsigned long ulDataSize;
- BYTE abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
+ u8 abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
// d.k.: abDataBuffer contains the complete tEplEvent structure
// and behind this the argument
diff --git a/drivers/staging/epl/EplEventu.c b/drivers/staging/epl/EplEventu.c
index 815f9a87abf..3ae2841ad02 100644
--- a/drivers/staging/epl/EplEventu.c
+++ b/drivers/staging/epl/EplEventu.c
@@ -96,8 +96,8 @@
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -172,7 +172,7 @@ static void EplEventuRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p)
+tEplKernel EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p)
{
tEplKernel Ret;
@@ -199,8 +199,7 @@ tEplKernel PUBLIC EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuAddInstance(tEplProcessEventCb
- pfnApiProcessEventCb_p)
+tEplKernel EplEventuAddInstance(tEplProcessEventCb pfnApiProcessEventCb_p)
{
tEplKernel Ret;
#ifndef EPL_NO_FIFO
@@ -280,7 +279,7 @@ tEplKernel PUBLIC EplEventuAddInstance(tEplProcessEventCb
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuDelInstance()
+tEplKernel EplEventuDelInstance(void)
{
tEplKernel Ret;
#ifndef EPL_NO_FIFO
@@ -348,7 +347,7 @@ tEplKernel PUBLIC EplEventuDelInstance()
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuProcess(tEplEvent * pEvent_p)
+tEplKernel EplEventuProcess(tEplEvent *pEvent_p)
{
tEplKernel Ret;
tEplEventSource EventSource;
@@ -515,7 +514,7 @@ tEplKernel PUBLIC EplEventuProcess(tEplEvent * pEvent_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuPost(tEplEvent * pEvent_p)
+tEplKernel EplEventuPost(tEplEvent *pEvent_p)
{
tEplKernel Ret;
#ifndef EPL_NO_FIFO
@@ -689,12 +688,12 @@ tEplKernel PUBLIC EplEventuPost(tEplEvent * pEvent_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuPostError(tEplEventSource EventSource_p,
- tEplKernel EplError_p,
- unsigned int uiArgSize_p, void *pArg_p)
+tEplKernel EplEventuPostError(tEplEventSource EventSource_p,
+ tEplKernel EplError_p,
+ unsigned int uiArgSize_p, void *pArg_p)
{
tEplKernel Ret;
- BYTE abBuffer[EPL_MAX_EVENT_ARG_SIZE];
+ u8 abBuffer[EPL_MAX_EVENT_ARG_SIZE];
tEplEventError *pEventError = (tEplEventError *) abBuffer;
tEplEvent EplEvent;
@@ -751,7 +750,7 @@ static void EplEventuRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
tShbError ShbError;
//unsigned long ulBlockCount;
//unsigned long ulDataSize;
- BYTE abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
+ u8 abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
// d.k.: abDataBuffer contains the complete tEplEvent structure
// and behind this the argument
diff --git a/drivers/staging/epl/EplFrame.h b/drivers/staging/epl/EplFrame.h
index 9a7f8b9f594..ba1ae9e9e90 100644
--- a/drivers/staging/epl/EplFrame.h
+++ b/drivers/staging/epl/EplFrame.h
@@ -122,155 +122,155 @@
typedef struct {
// Offset 17
- BYTE m_le_bRes1; // reserved
+ u8 m_le_bRes1; // reserved
// Offset 18
- BYTE m_le_bFlag1; // Flags: MC, PS
+ u8 m_le_bFlag1; // Flags: MC, PS
// Offset 19
- BYTE m_le_bFlag2; // Flags: res
+ u8 m_le_bFlag2; // Flags: res
// Offset 20
tEplNetTime m_le_NetTime; // supported if D_NMT_NetTimeIsRealTime_BOOL is set
// Offset 28
- QWORD m_le_RelativeTime; // in us (supported if D_NMT_RelativeTime_BOOL is set)
+ u64 m_le_RelativeTime; // in us (supported if D_NMT_RelativeTime_BOOL is set)
} PACK_STRUCT tEplSocFrame;
typedef struct {
// Offset 17
- BYTE m_le_bRes1; // reserved
+ u8 m_le_bRes1; // reserved
// Offset 18
- BYTE m_le_bFlag1; // Flags: MS, EA, RD
+ u8 m_le_bFlag1; // Flags: MS, EA, RD
// Offset 19
- BYTE m_le_bFlag2; // Flags: res
+ u8 m_le_bFlag2; // Flags: res
// Offset 20
- BYTE m_le_bPdoVersion;
+ u8 m_le_bPdoVersion;
// Offset 21
- BYTE m_le_bRes2; // reserved
+ u8 m_le_bRes2; // reserved
// Offset 22
- WORD m_le_wSize;
+ u16 m_le_wSize;
// Offset 24
- BYTE m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16 */ ];
+ u8 m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16 */ ];
} PACK_STRUCT tEplPreqFrame;
typedef struct {
// Offset 17
- BYTE m_le_bNmtStatus; // NMT state
+ u8 m_le_bNmtStatus; // NMT state
// Offset 18
- BYTE m_le_bFlag1; // Flags: MS, EN, RD
+ u8 m_le_bFlag1; // Flags: MS, EN, RD
// Offset 19
- BYTE m_le_bFlag2; // Flags: PR, RS
+ u8 m_le_bFlag2; // Flags: PR, RS
// Offset 20
- BYTE m_le_bPdoVersion;
+ u8 m_le_bPdoVersion;
// Offset 21
- BYTE m_le_bRes2; // reserved
+ u8 m_le_bRes2; // reserved
// Offset 22
- WORD m_le_wSize;
+ u16 m_le_wSize;
// Offset 24
- BYTE m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16
+ u8 m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16
/ D_NMT_IsochrTxMaxPayload_U16 */ ];
} PACK_STRUCT tEplPresFrame;
typedef struct {
// Offset 17
- BYTE m_le_bNmtStatus; // NMT state
+ u8 m_le_bNmtStatus; // NMT state
// Offset 18
- BYTE m_le_bFlag1; // Flags: EA, ER
+ u8 m_le_bFlag1; // Flags: EA, ER
// Offset 19
- BYTE m_le_bFlag2; // Flags: res
+ u8 m_le_bFlag2; // Flags: res
// Offset 20
- BYTE m_le_bReqServiceId;
+ u8 m_le_bReqServiceId;
// Offset 21
- BYTE m_le_bReqServiceTarget;
+ u8 m_le_bReqServiceTarget;
// Offset 22
- BYTE m_le_bEplVersion;
+ u8 m_le_bEplVersion;
} PACK_STRUCT tEplSoaFrame;
typedef struct {
- WORD m_wEntryType;
- WORD m_wErrorCode;
+ u16 m_wEntryType;
+ u16 m_wErrorCode;
tEplNetTime m_TimeStamp;
- BYTE m_abAddInfo[8];
+ u8 m_abAddInfo[8];
} PACK_STRUCT tEplErrHistoryEntry;
typedef struct {
// Offset 18
- BYTE m_le_bFlag1; // Flags: EN, EC
- BYTE m_le_bFlag2; // Flags: PR, RS
- BYTE m_le_bNmtStatus; // NMT state
- BYTE m_le_bRes1[3];
- QWORD m_le_qwStaticError; // static error bit field
+ u8 m_le_bFlag1; // Flags: EN, EC
+ u8 m_le_bFlag2; // Flags: PR, RS
+ u8 m_le_bNmtStatus; // NMT state
+ u8 m_le_bRes1[3];
+ u64 m_le_qwStaticError; // static error bit field
tEplErrHistoryEntry m_le_aErrHistoryEntry[14];
} PACK_STRUCT tEplStatusResponse;
typedef struct {
// Offset 18
- BYTE m_le_bFlag1; // Flags: res
- BYTE m_le_bFlag2; // Flags: PR, RS
- BYTE m_le_bNmtStatus; // NMT state
- BYTE m_le_bIdentRespFlags; // Flags: FW
- BYTE m_le_bEplProfileVersion;
- BYTE m_le_bRes1;
- DWORD m_le_dwFeatureFlags; // NMT_FeatureFlags_U32
- WORD m_le_wMtu; // NMT_CycleTiming_REC.AsyncMTU_U16: C_IP_MIN_MTU - C_IP_MAX_MTU
- WORD m_le_wPollInSize; // NMT_CycleTiming_REC.PReqActPayload_U16
- WORD m_le_wPollOutSize; // NMT_CycleTiming_REC.PResActPayload_U16
- DWORD m_le_dwResponseTime; // NMT_CycleTiming_REC.PResMaxLatency_U32
- WORD m_le_wRes2;
- DWORD m_le_dwDeviceType; // NMT_DeviceType_U32
- DWORD m_le_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32
- DWORD m_le_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32
- DWORD m_le_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32
- DWORD m_le_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32
- QWORD m_le_qwVendorSpecificExt1;
- DWORD m_le_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
- DWORD m_le_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
- DWORD m_le_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
- DWORD m_le_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
- DWORD m_le_dwIpAddress;
- DWORD m_le_dwSubnetMask;
- DWORD m_le_dwDefaultGateway;
- BYTE m_le_sHostname[32];
- BYTE m_le_abVendorSpecificExt2[48];
+ u8 m_le_bFlag1; // Flags: res
+ u8 m_le_bFlag2; // Flags: PR, RS
+ u8 m_le_bNmtStatus; // NMT state
+ u8 m_le_bIdentRespFlags; // Flags: FW
+ u8 m_le_bEplProfileVersion;
+ u8 m_le_bRes1;
+ u32 m_le_dwFeatureFlags; // NMT_FeatureFlags_U32
+ u16 m_le_wMtu; // NMT_CycleTiming_REC.AsyncMTU_U16: C_IP_MIN_MTU - C_IP_MAX_MTU
+ u16 m_le_wPollInSize; // NMT_CycleTiming_REC.PReqActPayload_U16
+ u16 m_le_wPollOutSize; // NMT_CycleTiming_REC.PResActPayload_U16
+ u32 m_le_dwResponseTime; // NMT_CycleTiming_REC.PResMaxLatency_U32
+ u16 m_le_wRes2;
+ u32 m_le_dwDeviceType; // NMT_DeviceType_U32
+ u32 m_le_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32
+ u32 m_le_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32
+ u32 m_le_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32
+ u32 m_le_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32
+ u64 m_le_qwVendorSpecificExt1;
+ u32 m_le_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
+ u32 m_le_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
+ u32 m_le_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
+ u32 m_le_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
+ u32 m_le_dwIpAddress;
+ u32 m_le_dwSubnetMask;
+ u32 m_le_dwDefaultGateway;
+ u8 m_le_sHostname[32];
+ u8 m_le_abVendorSpecificExt2[48];
} PACK_STRUCT tEplIdentResponse;
typedef struct {
// Offset 18
- BYTE m_le_bNmtCommandId;
- BYTE m_le_bRes1;
- BYTE m_le_abNmtCommandData[32];
+ u8 m_le_bNmtCommandId;
+ u8 m_le_bRes1;
+ u8 m_le_abNmtCommandData[32];
} PACK_STRUCT tEplNmtCommandService;
typedef struct {
- BYTE m_le_bReserved;
- BYTE m_le_bTransactionId;
- BYTE m_le_bFlags;
- BYTE m_le_bCommandId;
- WORD m_le_wSegmentSize;
- WORD m_le_wReserved;
- BYTE m_le_abCommandData[8]; // just reserve a minimum number of bytes as a placeholder
+ u8 m_le_bReserved;
+ u8 m_le_bTransactionId;
+ u8 m_le_bFlags;
+ u8 m_le_bCommandId;
+ u16 m_le_wSegmentSize;
+ u16 m_le_wReserved;
+ u8 m_le_abCommandData[8]; // just reserve a minimum number of bytes as a placeholder
} PACK_STRUCT tEplAsySdoCom;
// asynchronous SDO Sequence Header
typedef struct {
- BYTE m_le_bRecSeqNumCon;
- BYTE m_le_bSendSeqNumCon;
- BYTE m_le_abReserved[2];
+ u8 m_le_bRecSeqNumCon;
+ u8 m_le_bSendSeqNumCon;
+ u8 m_le_abReserved[2];
tEplAsySdoCom m_le_abSdoSeqPayload;
} PACK_STRUCT tEplAsySdoSeq;
typedef struct {
// Offset 18
- BYTE m_le_bNmtCommandId;
- BYTE m_le_bTargetNodeId;
- BYTE m_le_abNmtCommandData[32];
+ u8 m_le_bNmtCommandId;
+ u8 m_le_bTargetNodeId;
+ u8 m_le_abNmtCommandData[32];
} PACK_STRUCT tEplNmtRequestService;
@@ -281,14 +281,14 @@ typedef union {
tEplNmtCommandService m_NmtCommandService;
tEplNmtRequestService m_NmtRequestService;
tEplAsySdoSeq m_SdoSequenceFrame;
- BYTE m_le_abPayload[256 /*D_NMT_ASndTxMaxPayload_U16
+ u8 m_le_abPayload[256 /*D_NMT_ASndTxMaxPayload_U16
/ D_NMT_ASndRxMaxPayload_U16 */ ];
} tEplAsndPayload;
typedef struct {
// Offset 17
- BYTE m_le_bServiceId;
+ u8 m_le_bServiceId;
// Offset 18
tEplAsndPayload m_Payload;
@@ -306,17 +306,17 @@ typedef union {
typedef struct {
// Offset 0
- BYTE m_be_abDstMac[6]; // MAC address of the addressed nodes
+ u8 m_be_abDstMac[6]; // MAC address of the addressed nodes
// Offset 6
- BYTE m_be_abSrcMac[6]; // MAC address of the transmitting node
+ u8 m_be_abSrcMac[6]; // MAC address of the transmitting node
// Offset 12
- WORD m_be_wEtherType; // Ethernet message type (big endian)
+ u16 m_be_wEtherType; // Ethernet message type (big endian)
// Offset 14
- BYTE m_le_bMessageType; // EPL message type
+ u8 m_le_bMessageType; // EPL message type
// Offset 15
- BYTE m_le_bDstNodeId; // EPL node ID of the addressed nodes
+ u8 m_le_bDstNodeId; // EPL node ID of the addressed nodes
// Offset 16
- BYTE m_le_bSrcNodeId; // EPL node ID of the transmitting node
+ u8 m_le_bSrcNodeId; // EPL node ID of the transmitting node
// Offset 17
tEplFrameData m_Data;
diff --git a/drivers/staging/epl/EplIdentu.c b/drivers/staging/epl/EplIdentu.c
index ce59ef09ccd..93d5a40a2f7 100644
--- a/drivers/staging/epl/EplIdentu.c
+++ b/drivers/staging/epl/EplIdentu.c
@@ -138,7 +138,7 @@ static tEplIdentuInstance EplIdentuInstance_g;
// local function prototypes
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplIdentuCbIdentResponse(tEplFrameInfo * pFrameInfo_p);
+static tEplKernel EplIdentuCbIdentResponse(tEplFrameInfo *pFrameInfo_p);
//=========================================================================//
// //
@@ -164,7 +164,7 @@ static tEplKernel PUBLIC EplIdentuCbIdentResponse(tEplFrameInfo * pFrameInfo_p);
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplIdentuInit()
+tEplKernel EplIdentuInit(void)
{
tEplKernel Ret;
@@ -191,7 +191,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplIdentuInit()
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplIdentuAddInstance()
+tEplKernel EplIdentuAddInstance(void)
{
tEplKernel Ret;
@@ -228,7 +228,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplIdentuAddInstance()
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplIdentuDelInstance()
+tEplKernel EplIdentuDelInstance(void)
{
tEplKernel Ret;
@@ -263,7 +263,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplIdentuDelInstance()
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplIdentuReset()
+tEplKernel EplIdentuReset(void)
{
tEplKernel Ret;
int iIndex;
@@ -300,9 +300,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplIdentuReset()
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
- tEplIdentResponse **
- ppIdentResponse_p)
+tEplKernel EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentResponse **ppIdentResponse_p)
{
tEplKernel Ret;
@@ -338,9 +337,8 @@ tEplKernel PUBLIC EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
- tEplIdentuCbResponse
- pfnCbResponse_p)
+tEplKernel EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentuCbResponse pfnCbResponse_p)
{
tEplKernel Ret;
@@ -388,9 +386,9 @@ tEplKernel PUBLIC EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT DWORD PUBLIC EplIdentuGetRunningRequests(void)
+u32 EplIdentuGetRunningRequests(void)
{
- DWORD dwReqs = 0;
+ u32 dwReqs = 0;
unsigned int uiIndex;
for (uiIndex = 0; uiIndex < 32; uiIndex++) {
@@ -426,7 +424,7 @@ EPLDLLEXPORT DWORD PUBLIC EplIdentuGetRunningRequests(void)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplIdentuCbIdentResponse(tEplFrameInfo * pFrameInfo_p)
+static tEplKernel EplIdentuCbIdentResponse(tEplFrameInfo *pFrameInfo_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiNodeId;
diff --git a/drivers/staging/epl/EplInc.h b/drivers/staging/epl/EplInc.h
index 77f93d14416..f91797a3687 100644
--- a/drivers/staging/epl/EplInc.h
+++ b/drivers/staging/epl/EplInc.h
@@ -140,8 +140,8 @@
// IEEE 1588 conformant net time structure
typedef struct {
- DWORD m_dwSec;
- DWORD m_dwNanoSec;
+ u32 m_dwSec;
+ u32 m_dwNanoSec;
} tEplNetTime;
@@ -154,8 +154,8 @@ typedef struct {
// -------------------------------------------------------------------------
#define EPL_SPEC_VERSION 0x20 // ETHERNET Powerlink V. 2.0
-#define EPL_STACK_VERSION(ver,rev,rel) ((((DWORD)(ver)) & 0xFF)|((((DWORD)(rev))&0xFF)<<8)|(((DWORD)(rel))<<16))
-#define EPL_OBJ1018_VERSION(ver,rev,rel) ((((DWORD)(ver))<<16) |(((DWORD)(rev))&0xFFFF))
+#define EPL_STACK_VERSION(ver,rev,rel) ((((u32)(ver)) & 0xFF)|((((u32)(rev))&0xFF)<<8)|(((u32)(rel))<<16))
+#define EPL_OBJ1018_VERSION(ver,rev,rel) ((((u32)(ver))<<16) |(((u32)(rev))&0xFFFF))
#define EPL_STRING_VERSION(ver,rev,rel) "V" #ver "." #rev " r" #rel
#include "EplVersion.h"
@@ -236,21 +236,6 @@ typedef struct {
#define tabentries(a) (sizeof(a)/sizeof(*(a)))
#endif
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// definitions for DLL export
-#if ((DEV_SYSTEM == _DEV_WIN32_) || (DEV_SYSTEM == _DEV_WIN_CE_)) && defined (COP_LIB)
-
-#define EPLDLLEXPORT __declspec (dllexport)
-
-#else
-
-#define EPLDLLEXPORT
-
-#endif
-
// ============================================================================
// common debug macros
// ============================================================================
diff --git a/drivers/staging/epl/EplInstDef.h b/drivers/staging/epl/EplInstDef.h
index 89efbf27826..29ab7fb7888 100644
--- a/drivers/staging/epl/EplInstDef.h
+++ b/drivers/staging/epl/EplInstDef.h
@@ -71,6 +71,8 @@
#ifndef _EPLINSTDEF_H_
#define _EPLINSTDEF_H_
+#include <linux/kernel.h>
+
// =========================================================================
// types and macros for generating instances
// =========================================================================
@@ -83,8 +85,8 @@ typedef enum {
//------------------------------------------------------------------------------------------
-typedef void MEM *tEplPtrInstance;
-typedef BYTE tEplInstanceHdl;
+typedef void *tEplPtrInstance;
+typedef u8 tEplInstanceHdl;
// define const for illegale values
#define CCM_ILLINSTANCE NULL
@@ -99,8 +101,6 @@ typedef BYTE tEplInstanceHdl;
//--------------------------------------------------------------------------------------
// memory attributes for instance table
-#define INST_NEAR // faster access to variables
-#define INST_FAR // variables wich have to located in xdata
#define STATIC // prevent warnings for variables with same name
#define INSTANCE_TYPE_BEGIN typedef struct {
@@ -117,12 +117,12 @@ typedef BYTE tEplInstanceHdl;
#define CCM_DECL_INSTANCE_HDL_ tEplInstanceHdl InstanceHandle,
// macros for declaration of pointer to instance handle within function header or prototype of API functions
-#define CCM_DECL_PTR_INSTANCE_HDL tEplInstanceHdl MEM* pInstanceHandle
-#define CCM_DECL_PTR_INSTANCE_HDL_ tEplInstanceHdl MEM* pInstanceHandle,
+#define CCM_DECL_PTR_INSTANCE_HDL tEplInstanceHdl *pInstanceHandle
+#define CCM_DECL_PTR_INSTANCE_HDL_ tEplInstanceHdl *pInstanceHandle,
// macros for declaration instance as lokacl variable within functions
-#define CCM_DECL_INSTANCE_PTR_LOCAL tCcmInstanceInfo MEM* pInstance;
-#define CCM_DECL_PTR_INSTANCE_HDL_LOCAL tEplInstanceHdl MEM* pInstanceHandle;
+#define CCM_DECL_INSTANCE_PTR_LOCAL tCcmInstanceInfo *pInstance;
+#define CCM_DECL_PTR_INSTANCE_HDL_LOCAL tEplInstanceHdl *pInstanceHandle;
// reference:
@@ -163,10 +163,10 @@ typedef BYTE tEplInstanceHdl;
//--------------------------------------------------------------------------------------
// macros for declaration within the function header, prototype or local var list
- // Declaration of pointers within function paramater list must defined as void MEM*
+ // Declaration of pointers within function paramater list must defined as void *
// pointer.
-#define EPL_MCO_DECL_INSTANCE_PTR void MEM* pInstance
-#define EPL_MCO_DECL_INSTANCE_PTR_ void MEM* pInstance,
+#define EPL_MCO_DECL_INSTANCE_PTR void *pInstance
+#define EPL_MCO_DECL_INSTANCE_PTR_ void *pInstance,
#define EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplPtrInstance pInstance;
// macros for reference of pointer to instance
@@ -191,8 +191,8 @@ typedef BYTE tEplInstanceHdl;
ASSERT (((tEplPtrInstance)pInstance)->m_InstState == kStateUsed);
// macros for declaration of pointer to instance pointer
-#define EPL_MCO_DECL_PTR_INSTANCE_PTR void MEM* MEM* pInstancePtr
-#define EPL_MCO_DECL_PTR_INSTANCE_PTR_ void MEM* MEM* pInstancePtr,
+#define EPL_MCO_DECL_PTR_INSTANCE_PTR void **pInstancePtr
+#define EPL_MCO_DECL_PTR_INSTANCE_PTR_ void **pInstancePtr,
// macros for reference of pointer to instance pointer
// These macros are used for parameter passing to called function.
@@ -212,12 +212,12 @@ typedef BYTE tEplInstanceHdl;
// this macro deletes all instance entries as unused
#define EPL_MCO_DELETE_INSTANCE_TABLE() \
{ \
- tEplInstanceInfo MEM* pInstance = &aEplInstanceTable_g[0]; \
- tFastByte InstNumber = 0; \
- tFastByte i = EPL_MAX_INSTANCES; \
+ tEplInstanceInfo * pInstance = &aEplInstanceTable_g[0]; \
+ tFastByte InstNumber = 0; \
+ tFastByte i = EPL_MAX_INSTANCES; \
do { \
- pInstance->m_InstState = (BYTE) kStateUnused; \
- pInstance->m_bInstIndex = (BYTE) InstNumber; \
+ pInstance->m_InstState = (u8) kStateUnused; \
+ pInstance->m_bInstIndex = (u8) InstNumber; \
pInstance++; InstNumber++; i--; \
} while (i != 0); \
}
@@ -230,8 +230,8 @@ typedef BYTE tEplInstanceHdl;
static tEplPtrInstance GetInstancePtr (tEplInstanceHdl InstHandle_p) { \
return &aEplInstanceTable_g[InstHandle_p]; } \
static tEplPtrInstance GetFreeInstance (void) { \
- tEplInstanceInfo MEM* pInstance = &aEplInstanceTable_g[0]; \
- tFastByte i = EPL_MAX_INSTANCES; \
+ tEplInstanceInfo *pInstance = &aEplInstanceTable_g[0]; \
+ tFastByte i = EPL_MAX_INSTANCES; \
do { if (pInstance->m_InstState != kStateUsed) { \
return (tEplPtrInstance) pInstance; } \
pInstance++; i--; } \
@@ -240,13 +240,13 @@ typedef BYTE tEplInstanceHdl;
// this macro defines the instance table. Each entry is reserved for an instance of CANopen.
#define EPL_MCO_DECL_INSTANCE_VAR() \
- static tEplInstanceInfo MEM aEplInstanceTable_g [EPL_MAX_INSTANCES];
+ static tEplInstanceInfo aEplInstanceTable_g [EPL_MAX_INSTANCES];
// this macro defines member variables in instance table which are needed in
// all modules of Epl stack
#define EPL_MCO_DECL_INSTANCE_MEMBER() \
- STATIC BYTE m_InstState; \
- STATIC BYTE m_bInstIndex;
+ STATIC u8 m_InstState; \
+ STATIC u8 m_bInstIndex;
#define EPL_MCO_INSTANCE_PARAM_IDX_() EPL_MCO_INSTANCE_PARAM_ (EPL_MCO_GLB_VAR (m_bInstIndex))
#define EPL_MCO_INSTANCE_PARAM_IDX() EPL_MCO_INSTANCE_PARAM (EPL_MCO_GLB_VAR (m_bInstIndex))
@@ -254,8 +254,6 @@ typedef BYTE tEplInstanceHdl;
#else // only one instance is used
// Memory attributes for instance table.
-#define INST_NEAR NEAR // faster access to variables
-#define INST_FAR MEM // variables wich have to located in xdata
#define STATIC static // prevent warnings for variables with same name
#define INSTANCE_TYPE_BEGIN
@@ -359,18 +357,6 @@ typedef BYTE tEplInstanceHdl;
#endif
-/*
-#if (CDRV_MAX_INSTANCES > 1)
-
- #define CDRV_REENTRANT REENTRANT
-
-#else
-
- #define CDRV_REENTRANT
-
-#endif
-*/
-
#endif // _EPLINSTDEF_H_
// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
diff --git a/drivers/staging/epl/EplNmt.h b/drivers/staging/epl/EplNmt.h
index 4c11e5bc74a..e351b55eea6 100644
--- a/drivers/staging/epl/EplNmt.h
+++ b/drivers/staging/epl/EplNmt.h
@@ -185,7 +185,7 @@ typedef struct {
typedef struct {
unsigned int m_uiNodeId; // NodeId
tEplNmtState m_NmtState; // NMT state (remember distinguish between MN / CN)
- WORD m_wErrorCode; // EPL error code in case of NMT state NotActive
+ u16 m_wErrorCode; // EPL error code in case of NMT state NotActive
} tEplHeartbeatEvent;
diff --git a/drivers/staging/epl/EplNmtCnu.c b/drivers/staging/epl/EplNmtCnu.c
index f2f46da08c7..c27ca8f8c2f 100644
--- a/drivers/staging/epl/EplNmtCnu.c
+++ b/drivers/staging/epl/EplNmtCnu.c
@@ -108,9 +108,9 @@ static tEplNmtCnuInstance EplNmtCnuInstance_g;
static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p);
-static BOOL EplNmtCnuNodeIdList(BYTE * pbNmtCommandDate_p);
+static BOOL EplNmtCnuNodeIdList(u8 * pbNmtCommandDate_p);
-static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p);
+static tEplKernel EplNmtCnuCommandCb(tEplFrameInfo *pFrameInfo_p);
//=========================================================================//
// //
@@ -135,7 +135,7 @@ static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p);
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuInit(unsigned int uiNodeId_p)
+tEplKernel EplNmtCnuInit(unsigned int uiNodeId_p)
{
tEplKernel Ret;
@@ -161,7 +161,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuInit(unsigned int uiNodeId_p)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuAddInstance(unsigned int uiNodeId_p)
+tEplKernel EplNmtCnuAddInstance(unsigned int uiNodeId_p)
{
tEplKernel Ret;
@@ -201,7 +201,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuAddInstance(unsigned int uiNodeId_p)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuDelInstance()
+tEplKernel EplNmtCnuDelInstance(void)
{
tEplKernel Ret;
@@ -234,9 +234,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuDelInstance()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
- tEplNmtCommand
- NmtCommand_p)
+tEplKernel EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
+ tEplNmtCommand NmtCommand_p)
{
tEplKernel Ret;
tEplFrameInfo NmtRequestFrameInfo;
@@ -249,15 +248,15 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
EPL_MEMSET(&NmtRequestFrame.m_be_abSrcMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abSrcMac)); // set by DLL
AmiSetWordToBe(&NmtRequestFrame.m_be_wEtherType,
EPL_C_DLL_ETHERTYPE_EPL);
- AmiSetByteToLe(&NmtRequestFrame.m_le_bDstNodeId, (BYTE) EPL_C_ADR_MN_DEF_NODE_ID); // node id of the MN
+ AmiSetByteToLe(&NmtRequestFrame.m_le_bDstNodeId, (u8) EPL_C_ADR_MN_DEF_NODE_ID); // node id of the MN
AmiSetByteToLe(&NmtRequestFrame.m_le_bMessageType,
- (BYTE) kEplMsgTypeAsnd);
+ (u8) kEplMsgTypeAsnd);
AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_le_bServiceId,
- (BYTE) kEplDllAsndNmtRequest);
+ (u8) kEplDllAsndNmtRequest);
AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.
m_NmtRequestService.m_le_bNmtCommandId,
- (BYTE) NmtCommand_p);
- AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bTargetNodeId, (BYTE) uiNodeId_p); // target for the nmt command
+ (u8) NmtCommand_p);
+ AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bTargetNodeId, (u8) uiNodeId_p); // target for the nmt command
EPL_MEMSET(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.
m_le_abNmtCommandData[0], 0x00,
sizeof(NmtRequestFrame.m_Data.m_Asnd.m_Payload.
@@ -297,9 +296,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback
- pfnEplNmtCheckEventCb_p)
+tEplKernel EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p)
{
tEplKernel Ret;
@@ -335,7 +332,7 @@ EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback
// State:
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p)
+static tEplKernel EplNmtCnuCommandCb(tEplFrameInfo *pFrameInfo_p)
{
tEplKernel Ret = kEplSuccessful;
tEplNmtCommand NmtCommand;
@@ -676,18 +673,18 @@ static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p)
// State:
//
//---------------------------------------------------------------------------
-static BOOL EplNmtCnuNodeIdList(BYTE * pbNmtCommandDate_p)
+static BOOL EplNmtCnuNodeIdList(u8 * pbNmtCommandDate_p)
{
BOOL fNodeIdInList;
unsigned int uiByteOffset;
- BYTE bBitOffset;
- BYTE bNodeListByte;
+ u8 bBitOffset;
+ u8 bNodeListByte;
// get byte-offset of the own nodeid in NodeIdList
// devide though 8
uiByteOffset = (unsigned int)(EplNmtCnuInstance_g.m_uiNodeId >> 3);
// get bitoffset
- bBitOffset = (BYTE) EplNmtCnuInstance_g.m_uiNodeId % 8;
+ bBitOffset = (u8) EplNmtCnuInstance_g.m_uiNodeId % 8;
bNodeListByte = AmiGetByteFromLe(&pbNmtCommandDate_p[uiByteOffset]);
if ((bNodeListByte & bBitOffset) == 0) {
diff --git a/drivers/staging/epl/EplNmtMnu.c b/drivers/staging/epl/EplNmtMnu.c
index 4ed0b6ce487..d19434f5f6f 100644
--- a/drivers/staging/epl/EplNmtMnu.c
+++ b/drivers/staging/epl/EplNmtMnu.c
@@ -94,8 +94,8 @@
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -211,8 +211,8 @@ typedef struct {
tEplTimerHdl m_TimerHdlStatReq; // timer to delay StatusRequests and IdentRequests
tEplTimerHdl m_TimerHdlLonger; // 2nd timer for NMT command EnableReadyToOp and CheckCommunication
tEplNmtMnuNodeState m_NodeState; // internal node state (kind of sub state of NMT state)
- DWORD m_dwNodeCfg; // subindex from 0x1F81
- WORD m_wFlags; // flags: CN is being accessed isochronously
+ u32 m_dwNodeCfg; // subindex from 0x1F81
+ u16 m_wFlags; // flags: CN is being accessed isochronously
} tEplNmtMnuNodeInfo;
@@ -224,8 +224,8 @@ typedef struct {
unsigned long m_ulStatusRequestDelay; // in [ms] (object 0x1006 * EPL_C_NMT_STATREQ_CYCLE)
unsigned long m_ulTimeoutReadyToOp; // in [ms] (object 0x1F89/5)
unsigned long m_ulTimeoutCheckCom; // in [ms] (object 0x1006 * MultiplexedCycleCount)
- WORD m_wFlags; // global flags
- DWORD m_dwNmtStartup; // object 0x1F80 NMT_StartUp_U32
+ u16 m_wFlags; // global flags
+ u32 m_dwNmtStartup; // object 0x1F80 NMT_StartUp_U32
tEplNmtMnuCbNodeEvent m_pfnCbNodeEvent;
tEplNmtMnuCbBootEvent m_pfnCbBootEvent;
@@ -241,20 +241,18 @@ static tEplNmtMnuInstance EplNmtMnuInstance_g;
// local function prototypes
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p);
+static tEplKernel EplNmtMnuCbNmtRequest(tEplFrameInfo *pFrameInfo_p);
-static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
- tEplIdentResponse *
- pIdentResponse_p);
+static tEplKernel EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentResponse *pIdentResponse_p);
-static tEplKernel PUBLIC EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
- tEplStatusResponse *
- pStatusResponse_p);
+static tEplKernel EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
+ tEplStatusResponse *pStatusResponse_p);
static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
tEplNmtMnuNodeInfo * pNodeInfo_p,
tEplNmtState NodeNmtState_p,
- WORD wErrorCode_p,
+ u16 wErrorCode_p,
tEplNmtState LocalNmtState_p);
static tEplKernel EplNmtMnuStartBootStep1(void);
@@ -273,7 +271,7 @@ static tEplKernel EplNmtMnuStartNodes(void);
static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
tEplNmtState NodeNmtState_p,
- WORD wErrorCode_p,
+ u16 wErrorCode_p,
tEplNmtMnuIntNodeEvent
NodeEvent_p);
@@ -380,7 +378,7 @@ tEplKernel EplNmtMnuAddInstance(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
//
//---------------------------------------------------------------------------
-tEplKernel EplNmtMnuDelInstance()
+tEplKernel EplNmtMnuDelInstance(void)
{
tEplKernel Ret;
@@ -419,7 +417,7 @@ tEplKernel EplNmtMnuSendNmtCommandEx(unsigned int uiNodeId_p,
{
tEplKernel Ret = kEplSuccessful;
tEplFrameInfo FrameInfo;
- BYTE abBuffer[EPL_C_DLL_MINSIZE_NMTCMDEXT];
+ u8 abBuffer[EPL_C_DLL_MINSIZE_NMTCMDEXT];
tEplFrame *pFrame = (tEplFrame *) abBuffer;
BOOL fSoftDeleteNode = FALSE;
@@ -439,11 +437,11 @@ tEplKernel EplNmtMnuSendNmtCommandEx(unsigned int uiNodeId_p,
// build frame
EPL_MEMSET(pFrame, 0x00, sizeof(abBuffer));
- AmiSetByteToLe(&pFrame->m_le_bDstNodeId, (BYTE) uiNodeId_p);
+ AmiSetByteToLe(&pFrame->m_le_bDstNodeId, (u8) uiNodeId_p);
AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId,
- (BYTE) kEplDllAsndNmtCommand);
+ (u8) kEplDllAsndNmtCommand);
AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.
- m_le_bNmtCommandId, (BYTE) NmtCommand_p);
+ m_le_bNmtCommandId, (u8) NmtCommand_p);
if ((pNmtCommandData_p != NULL) && (uiDataSize_p > 0)) { // copy command data to frame
EPL_MEMCPY(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.
m_le_abNmtCommandData[0], pNmtCommandData_p,
@@ -574,8 +572,8 @@ tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p,
tEplKernel Ret = kEplSuccessful;
tEplNmtMnuIntNodeEvent NodeEvent;
tEplObdSize ObdSize;
- BYTE bNmtState;
- WORD wErrorCode = EPL_E_NO_ERROR;
+ u8 bNmtState;
+ u16 wErrorCode = EPL_E_NO_ERROR;
if ((uiNodeId_p == 0) || (uiNodeId_p >= EPL_C_ADR_BROADCAST)) {
Ret = kEplInvalidNodeId;
@@ -645,8 +643,7 @@ tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
- NmtStateChange_p)
+tEplKernel EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -676,7 +673,7 @@ tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
// build the configuration with infos from OD
case kEplNmtGsResetConfiguration:
{
- DWORD dwTimeout;
+ u32 dwTimeout;
tEplObdSize ObdSize;
// read object 0x1F80 NMT_StartUp_U32
@@ -788,7 +785,7 @@ tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
// node processes only async frames
case kEplNmtMsPreOperational1:
{
- DWORD dwTimeout;
+ u32 dwTimeout;
tEplTimerArg TimerArg;
tEplObdSize ObdSize;
tEplEvent Event;
@@ -928,7 +925,7 @@ tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p)
+tEplKernel EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -949,7 +946,7 @@ tEplKernel PUBLIC EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p)
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p)
+tEplKernel EplNmtMnuProcessEvent(tEplEvent *pEvent_p)
{
tEplKernel Ret;
@@ -970,7 +967,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p)
EPL_NMTMNU_TIMERARG_NODE_MASK);
if (uiNodeId != 0) {
tEplObdSize ObdSize;
- BYTE bNmtState;
+ u8 bNmtState;
tEplNmtMnuNodeInfo *pNodeInfo;
pNodeInfo = EPL_NMTMNU_GET_NODEINFO(uiNodeId);
@@ -1150,7 +1147,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p)
tEplFrame *pFrame = (tEplFrame *) pEvent_p->m_pArg;
unsigned int uiNodeId;
tEplNmtCommand NmtCommand;
- BYTE bNmtState;
+ u8 bNmtState;
uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bDstNodeId);
NmtCommand =
@@ -1162,30 +1159,30 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p)
switch (NmtCommand) {
case kEplNmtCmdStartNode:
bNmtState =
- (BYTE) (kEplNmtCsOperational & 0xFF);
+ (u8) (kEplNmtCsOperational & 0xFF);
break;
case kEplNmtCmdStopNode:
- bNmtState = (BYTE) (kEplNmtCsStopped & 0xFF);
+ bNmtState = (u8) (kEplNmtCsStopped & 0xFF);
break;
case kEplNmtCmdEnterPreOperational2:
bNmtState =
- (BYTE) (kEplNmtCsPreOperational2 & 0xFF);
+ (u8) (kEplNmtCsPreOperational2 & 0xFF);
break;
case kEplNmtCmdEnableReadyToOperate:
// d.k. do not change expected node state, because of DS 1.0.0 7.3.1.2.1 Plain NMT State Command
// and because node may not change NMT state within EPL_C_NMT_STATE_TOLERANCE
bNmtState =
- (BYTE) (kEplNmtCsPreOperational2 & 0xFF);
+ (u8) (kEplNmtCsPreOperational2 & 0xFF);
break;
case kEplNmtCmdResetNode:
case kEplNmtCmdResetCommunication:
case kEplNmtCmdResetConfiguration:
case kEplNmtCmdSwReset:
- bNmtState = (BYTE) (kEplNmtCsNotActive & 0xFF);
+ bNmtState = (u8) (kEplNmtCsNotActive & 0xFF);
// EplNmtMnuProcessInternalEvent() sets internal node state to kEplNmtMnuNodeStateUnknown
// after next unresponded IdentRequest/StatusRequest
break;
@@ -1258,11 +1255,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplNmtMnuGetDiagnosticInfo(unsigned int
- *puiMandatorySlaveCount_p,
- unsigned int
- *puiSignalSlaveCount_p,
- WORD * pwFlags_p)
+tEplKernel EplNmtMnuGetDiagnosticInfo(unsigned int *puiMandatorySlaveCount_p,
+ unsigned int *puiSignalSlaveCount_p,
+ u16 *pwFlags_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -1296,7 +1291,7 @@ tEplKernel PUBLIC EplNmtMnuGetDiagnosticInfo(unsigned int
//
//---------------------------------------------------------------------------
/*
-DWORD EplNmtMnuGetRunningTimerStatReq(void)
+u32 EplNmtMnuGetRunningTimerStatReq(void)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiIndex;
@@ -1347,7 +1342,7 @@ Exit:
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p)
+static tEplKernel EplNmtMnuCbNmtRequest(tEplFrameInfo *pFrameInfo_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -1371,9 +1366,8 @@ static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
- tEplIdentResponse *
- pIdentResponse_p)
+static tEplKernel EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentResponse *pIdentResponse_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -1382,8 +1376,8 @@ static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
kEplNmtMnuIntNodeEventNoIdentResponse);
} else { // node answered IdentRequest
tEplObdSize ObdSize;
- DWORD dwDevType;
- WORD wErrorCode = EPL_E_NO_ERROR;
+ u32 dwDevType;
+ u16 wErrorCode = EPL_E_NO_ERROR;
tEplNmtState NmtState =
(tEplNmtState) (AmiGetByteFromLe
(&pIdentResponse_p->
@@ -1431,9 +1425,8 @@ static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
- tEplStatusResponse *
- pStatusResponse_p)
+static tEplKernel EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
+ tEplStatusResponse *pStatusResponse_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -1473,7 +1466,7 @@ static tEplKernel EplNmtMnuStartBootStep1(void)
tEplKernel Ret = kEplSuccessful;
unsigned int uiSubIndex;
unsigned int uiLocalNodeId;
- DWORD dwNodeCfg;
+ u32 dwNodeCfg;
tEplObdSize ObdSize;
// $$$ d.k.: save current time for 0x1F89/2 MNTimeoutPreOp1_U32
@@ -1633,7 +1626,7 @@ static tEplKernel EplNmtMnuNodeBootStep2(unsigned int uiNodeId_p,
{
tEplKernel Ret = kEplSuccessful;
tEplDllNodeInfo DllNodeInfo;
- DWORD dwNodeCfg;
+ u32 dwNodeCfg;
tEplObdSize ObdSize;
tEplTimerArg TimerArg;
@@ -1782,7 +1775,7 @@ static tEplKernel EplNmtMnuNodeCheckCom(unsigned int uiNodeId_p,
tEplNmtMnuNodeInfo * pNodeInfo_p)
{
tEplKernel Ret = kEplSuccessful;
- DWORD dwNodeCfg;
+ u32 dwNodeCfg;
tEplTimerArg TimerArg;
dwNodeCfg = pNodeInfo_p->m_dwNodeCfg;
@@ -1916,7 +1909,7 @@ static tEplKernel EplNmtMnuStartNodes(void)
static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
tEplNmtState NodeNmtState_p,
- WORD wErrorCode_p,
+ u16 wErrorCode_p,
tEplNmtMnuIntNodeEvent
NodeEvent_p)
{
@@ -1934,7 +1927,7 @@ static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
switch (NodeEvent_p) {
case kEplNmtMnuIntNodeEventIdentResponse:
{
- BYTE bNmtState;
+ u8 bNmtState;
EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
uiNodeId_p,
@@ -1961,7 +1954,7 @@ static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
}
// update object 0x1F8F NMT_MNNodeExpState_AU8 to PreOp1 (even if local state >= PreOp2)
- bNmtState = (BYTE) (kEplNmtCsPreOperational1 & 0xFF);
+ bNmtState = (u8) (kEplNmtCsPreOperational1 & 0xFF);
Ret =
EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState,
1);
@@ -2441,11 +2434,11 @@ static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
case kEplNmtMnuIntNodeEventNmtCmdSent:
{
- BYTE bNmtState;
+ u8 bNmtState;
// update expected NMT state with the one that results
// from the sent NMT command
- bNmtState = (BYTE) (NodeNmtState_p & 0xFF);
+ bNmtState = (u8) (NodeNmtState_p & 0xFF);
// write object 0x1F8F NMT_MNNodeExpState_AU8
Ret =
@@ -2630,13 +2623,13 @@ static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
tEplNmtMnuNodeInfo * pNodeInfo_p,
tEplNmtState NodeNmtState_p,
- WORD wErrorCode_p,
+ u16 wErrorCode_p,
tEplNmtState LocalNmtState_p)
{
tEplKernel Ret = kEplSuccessful;
tEplObdSize ObdSize;
- BYTE bNmtState;
- BYTE bNmtStatePrev;
+ u8 bNmtState;
+ u8 bNmtStatePrev;
tEplNmtState ExpNmtState;
ObdSize = 1;
@@ -2647,8 +2640,8 @@ static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
}
// compute expected NMT state
ExpNmtState = (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS);
- // compute BYTE of current NMT state
- bNmtState = ((BYTE) NodeNmtState_p & 0xFF);
+ // compute u8 of current NMT state
+ bNmtState = ((u8) NodeNmtState_p & 0xFF);
if (ExpNmtState == kEplNmtCsNotActive) { // ignore the current state, because the CN shall be not active
Ret = kEplReject;
@@ -2706,7 +2699,7 @@ static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
} else if ((ExpNmtState != NodeNmtState_p)
&& !((ExpNmtState == kEplNmtCsPreOperational1)
&& (NodeNmtState_p == kEplNmtCsPreOperational2))) { // CN is not in expected NMT state (without the exceptions above)
- WORD wbeErrorCode;
+ u16 wbeErrorCode;
if ((pNodeInfo_p->
m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0) {
diff --git a/drivers/staging/epl/EplNmtk.c b/drivers/staging/epl/EplNmtk.c
index 4e2d0e15e94..609d5c02bde 100644
--- a/drivers/staging/epl/EplNmtk.c
+++ b/drivers/staging/epl/EplNmtk.c
@@ -88,8 +88,8 @@
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -107,12 +107,12 @@ void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
// struct for instance table
INSTANCE_TYPE_BEGIN EPL_MCO_DECL_INSTANCE_MEMBER()
-STATIC volatile tEplNmtState INST_FAR m_NmtState;
-STATIC volatile BOOL INST_FAR m_fEnableReadyToOperate;
-STATIC volatile BOOL INST_FAR m_fAppReadyToOperate;
-STATIC volatile BOOL INST_FAR m_fTimerMsPreOp2;
-STATIC volatile BOOL INST_FAR m_fAllMandatoryCNIdent;
-STATIC volatile BOOL INST_FAR m_fFrozen;
+STATIC volatile tEplNmtState m_NmtState;
+STATIC volatile BOOL m_fEnableReadyToOperate;
+STATIC volatile BOOL m_fAppReadyToOperate;
+STATIC volatile BOOL m_fTimerMsPreOp2;
+STATIC volatile BOOL m_fAllMandatoryCNIdent;
+STATIC volatile BOOL m_fFrozen;
INSTANCE_TYPE_END
//---------------------------------------------------------------------------
@@ -121,7 +121,7 @@ INSTANCE_TYPE_END
// This macro replace the unspecific pointer to an instance through
// the modul specific type for the local instance table. This macro
// must defined in each modul.
-//#define tEplPtrInstance tEplInstanceInfo MEM*
+//#define tEplPtrInstance tEplInstanceInfo*
EPL_MCO_DECL_INSTANCE_VAR()
//---------------------------------------------------------------------------
// local function prototypes
@@ -163,7 +163,7 @@ EPL_MCO_DEFINE_INSTANCE_FCT()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+tEplKernel EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR)
{
tEplKernel Ret;
@@ -189,7 +189,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+tEplKernel EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
{
EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret;
//tEplEvent Event;
@@ -258,7 +258,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
//
//---------------------------------------------------------------------------
#if (EPL_USE_DELETEINST_FUNC != FALSE)
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+tEplKernel EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
{
tEplKernel Ret = kEplSuccessful;
// check for all API function if instance is valid
@@ -296,8 +296,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- tEplEvent * pEvent_p)
+tEplKernel EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplEvent *pEvent_p)
{
tEplKernel Ret;
tEplNmtState OldNmtState;
@@ -1804,8 +1803,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplNmtState PUBLIC
-EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+tEplNmtState EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR)
{
tEplNmtState NmtState;
diff --git a/drivers/staging/epl/EplNmtkCal.c b/drivers/staging/epl/EplNmtkCal.c
index 4ad71a71e01..4453c09838c 100644
--- a/drivers/staging/epl/EplNmtkCal.c
+++ b/drivers/staging/epl/EplNmtkCal.c
@@ -69,8 +69,6 @@
****************************************************************************/
-#include "kernel/EplNmtkCal.h"
-
// TODO: init function needed to prepare EplNmtkGetNmtState for
// io-controll-call from EplNmtuCal-Modul
diff --git a/drivers/staging/epl/EplNmtu.c b/drivers/staging/epl/EplNmtu.c
index 3de16a1eff5..9ac2e8e4845 100644
--- a/drivers/staging/epl/EplNmtu.c
+++ b/drivers/staging/epl/EplNmtu.c
@@ -132,7 +132,7 @@ static tEplNmtuInstance EplNmtuInstance_g;
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuInit()
+tEplKernel EplNmtuInit(void)
{
tEplKernel Ret;
@@ -158,7 +158,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuInit()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuAddInstance()
+tEplKernel EplNmtuAddInstance(void)
{
tEplKernel Ret;
@@ -187,7 +187,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuAddInstance()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuDelInstance()
+tEplKernel EplNmtuDelInstance(void)
{
tEplKernel Ret;
@@ -219,7 +219,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuDelInstance()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p)
+tEplKernel EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p)
{
tEplKernel Ret;
tEplEvent Event;
@@ -253,7 +253,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplNmtState PUBLIC EplNmtuGetNmtState()
+tEplNmtState EplNmtuGetNmtState(void)
{
tEplNmtState NmtState;
@@ -284,7 +284,7 @@ EPLDLLEXPORT tEplNmtState PUBLIC EplNmtuGetNmtState()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p)
+tEplKernel EplNmtuProcessEvent(tEplEvent *pEplEvent_p)
{
tEplKernel Ret;
@@ -382,7 +382,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p)
// node listens for EPL-Frames and check timeout
case kEplNmtCsNotActive:
{
- DWORD dwBuffer;
+ u32 dwBuffer;
tEplObdSize ObdSize;
tEplTimerArg TimerArg;
@@ -475,7 +475,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p)
// node listens for EPL-Frames and check timeout
case kEplNmtMsNotActive:
{
- DWORD dwBuffer;
+ u32 dwBuffer;
tEplObdSize ObdSize;
tEplTimerArg TimerArg;
@@ -544,7 +544,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p)
// node processes only async frames
case kEplNmtMsPreOperational1:
{
- DWORD dwBuffer = 0;
+ u32 dwBuffer = 0;
tEplObdSize ObdSize;
tEplTimerArg TimerArg;
@@ -664,9 +664,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback
- pfnEplNmtStateChangeCb_p)
+tEplKernel EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p)
{
tEplKernel Ret;
diff --git a/drivers/staging/epl/EplNmtuCal.c b/drivers/staging/epl/EplNmtuCal.c
index 4a29ef58bf9..92164c57ea1 100644
--- a/drivers/staging/epl/EplNmtuCal.c
+++ b/drivers/staging/epl/EplNmtuCal.c
@@ -119,7 +119,7 @@
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplNmtState PUBLIC EplNmtkCalGetNmtState()
+tEplNmtState EplNmtkCalGetNmtState(void)
{
tEplNmtState NmtState;
// for test direkt call for EplNmtkGetNmtState()
diff --git a/drivers/staging/epl/EplObd.c b/drivers/staging/epl/EplObd.c
index efbb1967a5d..1e463234d81 100644
--- a/drivers/staging/epl/EplObd.c
+++ b/drivers/staging/epl/EplObd.c
@@ -101,8 +101,8 @@
// struct for instance table
INSTANCE_TYPE_BEGIN EPL_MCO_DECL_INSTANCE_MEMBER()
-STATIC tEplObdInitParam INST_FAR m_ObdInitParam;
-STATIC tEplObdStoreLoadObjCallback INST_NEAR m_fpStoreLoadObjCallback;
+STATIC tEplObdInitParam m_ObdInitParam;
+STATIC tEplObdStoreLoadObjCallback m_fpStoreLoadObjCallback;
INSTANCE_TYPE_END
// decomposition of float
@@ -119,11 +119,11 @@ typedef union {
// This macro replace the unspecific pointer to an instance through
// the modul specific type for the local instance table. This macro
// must defined in each modul.
-//#define tEplPtrInstance tEplInstanceInfo MEM*
+//#define tEplPtrInstance tEplInstanceInfo *
EPL_MCO_DECL_INSTANCE_VAR()
-BYTE MEM abEplObdTrashObject_g[8];
+u8 abEplObdTrashObject_g[8];
//---------------------------------------------------------------------------
// local function prototypes
@@ -133,7 +133,7 @@ EPL_MCO_DEFINE_INSTANCE_FCT()
static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_
tEplObdCallback fpCallback_p,
- tEplObdCbParam MEM * pCbParam_p);
+ tEplObdCbParam *pCbParam_p);
static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p);
@@ -146,7 +146,7 @@ static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,
#endif
static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,
- tEplObdVarEntry MEM ** ppVarEntry_p);
+ tEplObdVarEntry **ppVarEntry_p);
static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
unsigned int uiIndex_p,
@@ -156,7 +156,7 @@ static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p);
-static tEplKernel EplObdGetIndexIntern(tEplObdInitParam MEM * pInitParam_p,
+static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p,
unsigned int uiIndex_p,
tEplObdEntryPtr * ppObdEntry_p);
@@ -170,17 +170,15 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
tEplObdDir Direction_p);
static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p);
-static void MEM *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p);
+static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p);
#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
-static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdCbStoreParam MEM *
- pCbStoreParam_p);
+static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdCbStoreParam *pCbStoreParam_p);
#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
-static void EplObdCopyObjectData(void MEM * pDstData_p,
+static void EplObdCopyObjectData(void *pDstData_p,
void *pSrcData_p,
tEplObdSize ObjSize_p, tEplObdType ObjType_p);
@@ -189,24 +187,22 @@ void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p);
static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
BOOL * pfEntryNumerical_p);
-static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- void **ppDstData_p,
- tEplObdSize Size_p,
- tEplObdEntryPtr * ppObdEntry_p,
- tEplObdSubEntryPtr * ppSubEntry_p,
- tEplObdCbParam MEM * pCbParam_p,
- tEplObdSize * pObdSize_p);
-
-static tEplKernel PUBLIC EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdEntryPtr pObdEntry_p,
- tEplObdSubEntryPtr pSubEntry_p,
- tEplObdCbParam MEM * pCbParam_p,
- void *pSrcData_p,
- void *pDstData_p,
- tEplObdSize ObdSize_p);
+static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p,
+ void **ppDstData_p,
+ tEplObdSize Size_p,
+ tEplObdEntryPtr *ppObdEntry_p,
+ tEplObdSubEntryPtr *ppSubEntry_p,
+ tEplObdCbParam *pCbParam_p,
+ tEplObdSize *pObdSize_p);
+
+static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p,
+ tEplObdSubEntryPtr pSubEntry_p,
+ tEplObdCbParam *pCbParam_p,
+ void *pSrcData_p,
+ void *pDstData_p,
+ tEplObdSize ObdSize_p);
//=========================================================================//
// //
@@ -228,8 +224,7 @@ static tEplKernel PUBLIC EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- tEplObdInitParam MEM * pInitParam_p)
+tEplKernel EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p)
{
tEplKernel Ret;
@@ -261,9 +256,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- tEplObdInitParam MEM *
- pInitParam_p)
+tEplKernel EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p)
{
EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret;
@@ -308,7 +301,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
#if (EPL_USE_DELETEINST_FUNC != FALSE)
-EPLDLLEXPORT tEplKernel PUBLIC EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR)
+tEplKernel EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR)
{
// check for all API function if instance is valid
EPL_MCO_CHECK_INSTANCE_STATE();
@@ -341,18 +334,16 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR)
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p)
+tEplKernel EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
tEplObdSubEntryPtr pSubEntry;
- tEplObdCbParam MEM CbParam;
- void MEM *pDstData;
+ tEplObdCbParam CbParam;
+ void *pDstData;
tEplObdSize ObdSize;
Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
@@ -402,17 +393,15 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p)
+tEplKernel EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p, tEplObdSize *pSize_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
tEplObdSubEntryPtr pSubEntry;
- tEplObdCbParam MEM CbParam;
+ tEplObdCbParam CbParam;
void *pSrcData;
tEplObdSize ObdSize;
@@ -487,9 +476,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdPart ObdPart_p,
- tEplObdDir Direction_p)
+tEplKernel EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p,
+ tEplObdDir Direction_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -587,12 +575,11 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_
- tEplVarParam MEM * pVarParam_p)
+tEplKernel EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam *pVarParam_p)
{
tEplKernel Ret;
- tEplObdVarEntry MEM *pVarEntry;
+ tEplObdVarEntry *pVarEntry;
tEplVarParamValid VarValid;
tEplObdSubEntryPtr pSubindexEntry;
@@ -674,9 +661,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p)
+void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p)
{
tEplKernel Ret;
void *pData;
@@ -719,8 +705,7 @@ EPLDLLEXPORT void *PUBLIC EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdEntryPtr pUserOd_p)
+tEplKernel EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p)
{
EPL_MCO_CHECK_INSTANCE_STATE();
@@ -749,10 +734,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdVarEntry MEM * pVarEntry_p,
- tEplObdType Type_p,
- tEplObdSize ObdSize_p)
+void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry *pVarEntry_p,
+ tEplObdType Type_p, tEplObdSize ObdSize_p)
{
/*
#if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
@@ -803,9 +786,8 @@ EPLDLLEXPORT void PUBLIC EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p)
+tEplObdSize EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p)
{
tEplKernel Ret;
tEplObdSize ObdSize;
@@ -845,11 +827,11 @@ EPLDLLEXPORT tEplObdSize PUBLIC EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)
+unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)
{
tEplKernel Ret;
tEplObdSize ObdSize;
- BYTE bNodeId;
+ u8 bNodeId;
bNodeId = 0;
ObdSize = sizeof(bNodeId);
@@ -882,22 +864,21 @@ EPLDLLEXPORT unsigned int PUBLIC EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- unsigned int uiNodeId_p,
- tEplObdNodeIdType NodeIdType_p)
+tEplKernel EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_ unsigned int uiNodeId_p,
+ tEplObdNodeIdType NodeIdType_p)
{
tEplKernel Ret;
tEplObdSize ObdSize;
- BYTE fHwBool;
- BYTE bNodeId;
+ u8 fHwBool;
+ u8 bNodeId;
// check Node Id
if (uiNodeId_p == EPL_C_ADR_INVALID) {
Ret = kEplInvalidNodeId;
goto Exit;
}
- bNodeId = (BYTE) uiNodeId_p;
- ObdSize = sizeof(BYTE);
+ bNodeId = (u8) uiNodeId_p;
+ ObdSize = sizeof(u8);
// write NodeId to OD entry
Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR_
EPL_OBD_NODE_ID_INDEX,
@@ -966,10 +947,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- BOOL * pfEntryNumerical_p)
+tEplKernel EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ BOOL *pfEntryNumerical_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
@@ -1018,16 +998,14 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p)
+tEplKernel EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p, tEplObdSize *pSize_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
tEplObdSubEntryPtr pSubEntry;
- tEplObdCbParam MEM CbParam;
+ tEplObdCbParam CbParam;
void *pSrcData;
tEplObdSize ObdSize;
@@ -1091,7 +1069,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt8:
case kEplObdTypUInt8:
{
- AmiSetByteToLe(pDstData_p, *((BYTE *) pSrcData));
+ AmiSetByteToLe(pDstData_p, *((u8 *) pSrcData));
break;
}
@@ -1099,7 +1077,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt16:
case kEplObdTypUInt16:
{
- AmiSetWordToLe(pDstData_p, *((WORD *) pSrcData));
+ AmiSetWordToLe(pDstData_p, *((u16 *) pSrcData));
break;
}
@@ -1107,7 +1085,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt24:
case kEplObdTypUInt24:
{
- AmiSetDword24ToLe(pDstData_p, *((DWORD *) pSrcData));
+ AmiSetDword24ToLe(pDstData_p, *((u32 *) pSrcData));
break;
}
@@ -1116,7 +1094,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypUInt32:
case kEplObdTypReal32:
{
- AmiSetDwordToLe(pDstData_p, *((DWORD *) pSrcData));
+ AmiSetDwordToLe(pDstData_p, *((u32 *) pSrcData));
break;
}
@@ -1124,7 +1102,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt40:
case kEplObdTypUInt40:
{
- AmiSetQword40ToLe(pDstData_p, *((QWORD *) pSrcData));
+ AmiSetQword40ToLe(pDstData_p, *((u64 *) pSrcData));
break;
}
@@ -1132,7 +1110,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt48:
case kEplObdTypUInt48:
{
- AmiSetQword48ToLe(pDstData_p, *((QWORD *) pSrcData));
+ AmiSetQword48ToLe(pDstData_p, *((u64 *) pSrcData));
break;
}
@@ -1140,7 +1118,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt56:
case kEplObdTypUInt56:
{
- AmiSetQword56ToLe(pDstData_p, *((QWORD *) pSrcData));
+ AmiSetQword56ToLe(pDstData_p, *((u64 *) pSrcData));
break;
}
@@ -1149,7 +1127,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypUInt64:
case kEplObdTypReal64:
{
- AmiSetQword64ToLe(pDstData_p, *((QWORD *) pSrcData));
+ AmiSetQword64ToLe(pDstData_p, *((u64 *) pSrcData));
break;
}
@@ -1199,19 +1177,17 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p)
+tEplKernel EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
tEplObdSubEntryPtr pSubEntry;
- tEplObdCbParam MEM CbParam;
- void MEM *pDstData;
+ tEplObdCbParam CbParam;
+ void *pDstData;
tEplObdSize ObdSize;
- QWORD qwBuffer;
+ u64 qwBuffer;
void *pBuffer = &qwBuffer;
Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
@@ -1242,7 +1218,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt8:
case kEplObdTypUInt8:
{
- *((BYTE *) pBuffer) = AmiGetByteFromLe(pSrcData_p);
+ *((u8 *) pBuffer) = AmiGetByteFromLe(pSrcData_p);
break;
}
@@ -1250,7 +1226,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt16:
case kEplObdTypUInt16:
{
- *((WORD *) pBuffer) = AmiGetWordFromLe(pSrcData_p);
+ *((u16 *) pBuffer) = AmiGetWordFromLe(pSrcData_p);
break;
}
@@ -1258,7 +1234,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt24:
case kEplObdTypUInt24:
{
- *((DWORD *) pBuffer) = AmiGetDword24FromLe(pSrcData_p);
+ *((u32 *) pBuffer) = AmiGetDword24FromLe(pSrcData_p);
break;
}
@@ -1267,7 +1243,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypUInt32:
case kEplObdTypReal32:
{
- *((DWORD *) pBuffer) = AmiGetDwordFromLe(pSrcData_p);
+ *((u32 *) pBuffer) = AmiGetDwordFromLe(pSrcData_p);
break;
}
@@ -1275,7 +1251,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt40:
case kEplObdTypUInt40:
{
- *((QWORD *) pBuffer) = AmiGetQword40FromLe(pSrcData_p);
+ *((u64 *) pBuffer) = AmiGetQword40FromLe(pSrcData_p);
break;
}
@@ -1283,7 +1259,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt48:
case kEplObdTypUInt48:
{
- *((QWORD *) pBuffer) = AmiGetQword48FromLe(pSrcData_p);
+ *((u64 *) pBuffer) = AmiGetQword48FromLe(pSrcData_p);
break;
}
@@ -1291,7 +1267,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt56:
case kEplObdTypUInt56:
{
- *((QWORD *) pBuffer) = AmiGetQword56FromLe(pSrcData_p);
+ *((u64 *) pBuffer) = AmiGetQword56FromLe(pSrcData_p);
break;
}
@@ -1300,7 +1276,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypUInt64:
case kEplObdTypReal64:
{
- *((QWORD *) pBuffer) = AmiGetQword64FromLe(pSrcData_p);
+ *((u64 *) pBuffer) = AmiGetQword64FromLe(pSrcData_p);
break;
}
@@ -1345,10 +1321,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- tEplObdAccess * pAccessTyp_p)
+tEplKernel EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ tEplObdAccess *pAccessTyp_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
@@ -1388,10 +1363,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- tEplObdVarEntry MEM ** ppVarEntry_p)
+tEplKernel EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ tEplObdVarEntry **ppVarEntry_p)
{
tEplKernel Ret;
@@ -1435,11 +1409,11 @@ EPL_MCO_DECL_INSTANCE_FCT()
//---------------------------------------------------------------------------
static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_
tEplObdCallback fpCallback_p,
- tEplObdCbParam MEM * pCbParam_p)
+ tEplObdCbParam *pCbParam_p)
{
tEplKernel Ret;
- tEplObdCallback MEM fpCallback;
+ tEplObdCallback fpCallback;
// check for all API function if instance is valid
EPL_MCO_CHECK_INSTANCE_STATE();
@@ -1481,7 +1455,7 @@ static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p)
{
tEplObdSize DataSize;
- void MEM *pData;
+ void *pData;
// If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
// then the current pointer is always NULL. The function
@@ -1490,8 +1464,7 @@ static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p)
if (pSubIndexEntry_p->m_Type == kEplObdTypVString) {
// The pointer to current value can be received from EplObdGetObjectCurrentPtr()
- pData =
- ((void MEM *)EplObdGetObjectCurrentPtr(pSubIndexEntry_p));
+ pData = ((void *)EplObdGetObjectCurrentPtr(pSubIndexEntry_p));
if (pData != NULL) {
DataSize =
EplObdGetStrLen((void *)pData, DataSize,
@@ -1526,7 +1499,7 @@ static tEplObdSize EplObdGetStrLen(void *pObjData_p,
{
tEplObdSize StrLen = 0;
- BYTE *pbString;
+ u8 *pbString;
if (pObjData_p == NULL) {
goto Exit;
@@ -1763,18 +1736,18 @@ static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,
case kEplObdTypInt64:
// switch to lower limit
- pRangeData = ((signed QWORD *)pRangeData) + 1;
+ pRangeData = ((signed u64 *)pRangeData) + 1;
// check if value is to low
- if (*((signed QWORD *)pData_p) < *((signed QWORD *)pRangeData)) {
+ if (*((signed u64 *)pData_p) < *((signed u64 *)pRangeData)) {
Ret = kEplObdValueTooLow;
break;
}
// switch to higher limit
- pRangeData = ((signed QWORD *)pRangeData) + 1;
+ pRangeData = ((signed u64 *)pRangeData) + 1;
// check if value is to high
- if (*((signed QWORD *)pData_p) > *((signed QWORD *)pRangeData)) {
+ if (*((signed u64 *)pData_p) > *((signed u64 *)pRangeData)) {
Ret = kEplObdValueTooHigh;
}
@@ -1787,20 +1760,20 @@ static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,
case kEplObdTypUInt64:
// switch to lower limit
- pRangeData = ((unsigned QWORD *)pRangeData) + 1;
+ pRangeData = ((unsigned u64 *)pRangeData) + 1;
// check if value is to low
- if (*((unsigned QWORD *)pData_p) <
- *((unsigned QWORD *)pRangeData)) {
+ if (*((unsigned u64 *)pData_p) <
+ *((unsigned u64 *)pRangeData)) {
Ret = kEplObdValueTooLow;
break;
}
// switch to higher limit
- pRangeData = ((unsigned QWORD *)pRangeData) + 1;
+ pRangeData = ((unsigned u64 *)pRangeData) + 1;
// check if value is to high
- if (*((unsigned QWORD *)pData_p) >
- *((unsigned QWORD *)pRangeData)) {
+ if (*((unsigned u64 *)pData_p) >
+ *((unsigned u64 *)pRangeData)) {
Ret = kEplObdValueTooHigh;
}
@@ -1870,29 +1843,28 @@ static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- void **ppDstData_p,
- tEplObdSize Size_p,
- tEplObdEntryPtr * ppObdEntry_p,
- tEplObdSubEntryPtr * ppSubEntry_p,
- tEplObdCbParam MEM * pCbParam_p,
- tEplObdSize * pObdSize_p)
+static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p,
+ void **ppDstData_p,
+ tEplObdSize Size_p,
+ tEplObdEntryPtr *ppObdEntry_p,
+ tEplObdSubEntryPtr *ppSubEntry_p,
+ tEplObdCbParam *pCbParam_p,
+ tEplObdSize *pObdSize_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
tEplObdSubEntryPtr pSubEntry;
tEplObdAccess Access;
- void MEM *pDstData;
+ void *pDstData;
tEplObdSize ObdSize;
BOOL fEntryNumerical;
#if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
- tEplObdVStringDomain MEM MemVStringDomain;
- void MEM *pCurrData;
+ tEplObdVStringDomain MemVStringDomain;
+ void *pCurrData;
#endif
// check for all API function if instance is valid
@@ -1908,7 +1880,7 @@ static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
goto Exit;
}
// get pointer to object data
- pDstData = (void MEM *)EplObdGetObjectDataPtrIntern(pSubEntry);
+ pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry);
Access = (tEplObdAccess) pSubEntry->m_Access;
@@ -1933,7 +1905,7 @@ static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
// adapted by user callback function, re-read
// this values.
ObdSize = EplObdGetObjectSize(pSubEntry);
- pDstData = (void MEM *)EplObdGetObjectDataPtrIntern(pSubEntry);
+ pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry);
// 09-dec-2004 r.d.:
// Function EplObdWriteEntry() calls new event kEplObdEvWrStringDomain
@@ -1967,23 +1939,19 @@ static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
pCurrData = pSubEntry->m_pCurrent;
if ((pSubEntry->m_Type == kEplObdTypVString)
|| (pSubEntry->m_Type == kEplObdTypOString)) {
- ((tEplObdVString MEM *) pCurrData)->m_Size =
- MemVStringDomain.m_ObjSize;
- ((tEplObdVString MEM *) pCurrData)->m_pString =
- MemVStringDomain.m_pData;
+ ((tEplObdVString *)pCurrData)->m_Size = MemVStringDomain.m_ObjSize;
+ ((tEplObdVString *)pCurrData)->m_pString = MemVStringDomain.m_pData;
} else // if (pSdosTableEntry_p->m_bObjType == kEplObdTypDomain)
{
- ((tEplObdVarEntry MEM *) pCurrData)->m_Size =
- MemVStringDomain.m_ObjSize;
- ((tEplObdVarEntry MEM *) pCurrData)->m_pData =
- (void MEM *)MemVStringDomain.m_pData;
+ ((tEplObdVarEntry *)pCurrData)->m_Size = MemVStringDomain.m_ObjSize;
+ ((tEplObdVarEntry *)pCurrData)->m_pData = (void *)MemVStringDomain.m_pData;
}
// Because object size and object pointer are
// adapted by user callback function, re-read
// this values.
ObdSize = MemVStringDomain.m_ObjSize;
- pDstData = (void MEM *)MemVStringDomain.m_pData;
+ pDstData = (void *)MemVStringDomain.m_pData;
}
#endif //#if (OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
@@ -2004,7 +1972,7 @@ static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
}
if (pSubEntry->m_Type == kEplObdTypVString) {
- if (((char MEM *)pSrcData_p)[Size_p - 1] == '\0') { // last byte of source string contains null character
+ if (((char *)pSrcData_p)[Size_p - 1] == '\0') { // last byte of source string contains null character
// reserve one byte in destination for 0-termination
Size_p -= 1;
@@ -2064,13 +2032,12 @@ static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdEntryPtr pObdEntry_p,
- tEplObdSubEntryPtr pSubEntry_p,
- tEplObdCbParam MEM * pCbParam_p,
- void *pSrcData_p,
- void *pDstData_p,
- tEplObdSize ObdSize_p)
+static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p,
+ tEplObdSubEntryPtr pSubEntry_p,
+ tEplObdCbParam *pCbParam_p,
+ void *pSrcData_p,
+ void *pDstData_p,
+ tEplObdSize ObdSize_p)
{
tEplKernel Ret;
@@ -2103,7 +2070,7 @@ static tEplKernel PUBLIC EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_
// terminate string with 0
if (pSubEntry_p->m_Type == kEplObdTypVString) {
- ((char MEM *)pDstData_p)[ObdSize_p] = '\0';
+ ((char *)pDstData_p)[ObdSize_p] = '\0';
}
// write address of destination to structure of callback parameters
// so callback function can change data subsequently
@@ -2123,7 +2090,7 @@ static tEplKernel PUBLIC EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_
// Function: EplObdGetObjectSize()
//
// Description: function to get size of object
-// The function determines if an object type an fixed data type (BYTE, WORD, ...)
+// The function determines if an object type an fixed data type (u8, u16, ...)
// or non fixed object (string, domain). This information is used to decide
// if download data are stored temporary or not. For objects with fixed data length
// and types a value range checking can process.
@@ -2192,8 +2159,8 @@ static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p)
case kEplObdTypDomain:
pData = (void *)pSubIndexEntry_p->m_pCurrent;
- if ((void MEM *)pData != (void MEM *)NULL) {
- DataSize = ((tEplObdVarEntry MEM *) pData)->m_Size;
+ if ((void *)pData != (void *)NULL) {
+ DataSize = ((tEplObdVarEntry *) pData)->m_Size;
}
break;
@@ -2205,21 +2172,19 @@ static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p)
// then the current pointer is always NULL. The function
// returns the length of default string.
pData = (void *)pSubIndexEntry_p->m_pCurrent;
- if ((void MEM *)pData != (void MEM *)NULL) {
+ if ((void *)pData != (void *)NULL) {
// The max. size of strings defined by STRING-Macro is stored in
// tEplObdVString of current value.
// (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
- DataSize = ((tEplObdVString MEM *) pData)->m_Size;
+ DataSize = ((tEplObdVString *) pData)->m_Size;
} else {
// The current position is not decleared. The string
// is located in ROM, therefor use default pointer.
pData = (void *)pSubIndexEntry_p->m_pDefault;
- if ((CONST void ROM *)pData != (CONST void ROM *)NULL) {
+ if ((const void *)pData != (const void *)NULL) {
// The max. size of strings defined by STRING-Macro is stored in
// tEplObdVString of default value.
- DataSize =
- ((CONST tEplObdVString ROM *) pData)->
- m_Size;
+ DataSize = ((const tEplObdVString *)pData)->m_Size;
}
}
@@ -2229,21 +2194,19 @@ static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p)
case kEplObdTypOString:
pData = (void *)pSubIndexEntry_p->m_pCurrent;
- if ((void MEM *)pData != (void MEM *)NULL) {
+ if ((void *)pData != (void *)NULL) {
// The max. size of strings defined by STRING-Macro is stored in
// tEplObdVString of current value.
// (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
- DataSize = ((tEplObdOString MEM *) pData)->m_Size;
+ DataSize = ((tEplObdOString *) pData)->m_Size;
} else {
// The current position is not decleared. The string
// is located in ROM, therefor use default pointer.
pData = (void *)pSubIndexEntry_p->m_pDefault;
- if ((CONST void ROM *)pData != (CONST void ROM *)NULL) {
+ if ((const void *)pData != (const void *)NULL) {
// The max. size of strings defined by STRING-Macro is stored in
// tEplObdVString of default value.
- DataSize =
- ((CONST tEplObdOString ROM *) pData)->
- m_Size;
+ DataSize = ((const tEplObdOString *)pData)->m_Size;
}
}
break;
@@ -2366,7 +2329,7 @@ static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
//---------------------------------------------------------------------------
static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,
- tEplObdVarEntry MEM ** ppVarEntry_p)
+ tEplObdVarEntry **ppVarEntry_p)
{
tEplKernel Ret = kEplObdVarEntryNotExist;
@@ -2378,13 +2341,9 @@ static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,
if ((pSubindexEntry_p->m_Access & kEplObdAccVar) != 0) {
// check if object is an array
if ((pSubindexEntry_p->m_Access & kEplObdAccArray) != 0) {
- *ppVarEntry_p =
- &((tEplObdVarEntry MEM *) pSubindexEntry_p->
- m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1];
+ *ppVarEntry_p = &((tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1];
} else {
- *ppVarEntry_p =
- (tEplObdVarEntry MEM *) pSubindexEntry_p->
- m_pCurrent;
+ *ppVarEntry_p = (tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent;
}
Ret = kEplSuccessful;
@@ -2420,7 +2379,7 @@ static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
{
tEplObdEntryPtr pObdEntry;
- tEplObdCbParam MEM CbParam;
+ tEplObdCbParam CbParam;
tEplKernel Ret;
// check for all API function if instance is valid
@@ -2474,16 +2433,16 @@ static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
//
// Parameters: pSubIndexEntry_p
//
-// Return: void MEM*
+// Return: void *
//
// State:
//
//---------------------------------------------------------------------------
-static void MEM *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
+static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
{
- void MEM *pData;
+ void *pData;
unsigned int uiArrayIndex;
tEplObdSize Size;
@@ -2500,24 +2459,21 @@ static void MEM *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
} else {
Size = EplObdGetObjectSize(pSubIndexEntry_p);
}
- pData = ((BYTE MEM *) pData) + (Size * uiArrayIndex);
+ pData = ((u8 *) pData) + (Size * uiArrayIndex);
}
// check if VarEntry
if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) {
// The data pointer is stored in VarEntry->pData
- pData = ((tEplObdVarEntry MEM *) pData)->m_pData;
+ pData = ((tEplObdVarEntry *) pData)->m_pData;
}
// the default pointer is stored for strings in tEplObdVString
else if ((pSubIndexEntry_p->m_Type == kEplObdTypVString) /* ||
(pSubIndexEntry_p->m_Type == kEplObdTypUString) */
) {
- pData =
- (void MEM *)((tEplObdVString MEM *) pData)->
- m_pString;
+ pData = (void *)((tEplObdVString *)pData)->m_pString;
} else if (pSubIndexEntry_p->m_Type == kEplObdTypOString) {
pData =
- (void MEM *)((tEplObdOString MEM *) pData)->
- m_pString;
+ (void *)((tEplObdOString *)pData)->m_pString;
}
}
@@ -2541,7 +2497,7 @@ static void MEM *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
//
//---------------------------------------------------------------------------
-static tEplKernel EplObdGetIndexIntern(tEplObdInitParam MEM * pInitParam_p,
+static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p,
unsigned int uiIndex_p,
tEplObdEntryPtr * ppObdEntry_p)
{
@@ -2762,9 +2718,7 @@ static tEplKernel EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p,
//
//---------------------------------------------------------------------------
#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
-EPLDLLEXPORT tEplKernel PUBLIC
-EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdStoreLoadObjCallback fpCallback_p)
+tEplKernel EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p)
{
EPL_MCO_CHECK_INSTANCE_STATE();
@@ -2802,26 +2756,26 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
tEplObdSubEntryPtr pSubIndex;
unsigned int nSubIndexCount;
tEplObdAccess Access;
- void MEM *pDstData;
+ void *pDstData;
void *pDefault;
tEplObdSize ObjSize;
tEplKernel Ret;
- tEplObdCbStoreParam MEM CbStore;
- tEplObdVarEntry MEM *pVarEntry;
+ tEplObdCbStoreParam CbStore;
+ tEplObdVarEntry *pVarEntry;
ASSERT(pObdEnty_p != NULL);
Ret = kEplSuccessful;
// prepare structure for STORE RESTORE callback function
- CbStore.m_bCurrentOdPart = (BYTE) CurrentOdPart_p;
+ CbStore.m_bCurrentOdPart = (u8) CurrentOdPart_p;
CbStore.m_pData = NULL;
CbStore.m_ObjSize = 0;
// command of first action depends on direction to access
#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
if (Direction_p == kEplObdDirLoad) {
- CbStore.m_bCommand = (BYTE) kEplObdCommOpenRead;
+ CbStore.m_bCommand = (u8) kEplObdCommOpenRead;
// call callback function for previous command
Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
@@ -2829,9 +2783,9 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
goto Exit;
}
// set command for index and subindex loop
- CbStore.m_bCommand = (BYTE) kEplObdCommReadObj;
+ CbStore.m_bCommand = (u8) kEplObdCommReadObj;
} else if (Direction_p == kEplObdDirStore) {
- CbStore.m_bCommand = (BYTE) kEplObdCommOpenWrite;
+ CbStore.m_bCommand = (u8) kEplObdCommOpenWrite;
// call callback function for previous command
Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
@@ -2839,7 +2793,7 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
goto Exit;
}
// set command for index and subindex loop
- CbStore.m_bCommand = (BYTE) kEplObdCommWriteObj;
+ CbStore.m_bCommand = (u8) kEplObdCommWriteObj;
}
#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
@@ -2890,7 +2844,7 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
}
else
{
- EplObdInitVarEntry ((tEplObdVarEntry MEM*) (((BYTE MEM*) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)),
+ EplObdInitVarEntry ((tEplObdVarEntry *) (((u8 *) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)),
pSubIndex->m_Type, ObjSize);
}
*/
@@ -2911,29 +2865,17 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
pSubIndex->m_pCurrent;
if (pDstData != NULL) {
// 08-dec-2004: code optimization !!!
- // entries ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_pString
- // and ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read
+ // entries ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString
+ // and ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_Size were read
// twice. thats not necessary!
// For copying data we have to set the destination pointer to the real RAM string. This
// pointer to RAM string is located in default string info structure. (translated r.d.)
- pDstData =
- (void MEM
- *)((tEplObdVStringDef ROM *) pSubIndex->m_pDefault)->m_pString;
- ObjSize =
- ((tEplObdVStringDef
- ROM *) pSubIndex->
- m_pDefault)->
- m_Size;
-
- ((tEplObdVString MEM *)
- pSubIndex->
- m_pCurrent)->
- m_pString = pDstData;
- ((tEplObdVString MEM *)
- pSubIndex->
- m_pCurrent)->m_Size =
- ObjSize;
+ pDstData = (void *)((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString;
+ ObjSize = ((tEplObdVStringDef *)pSubIndex->m_pDefault)->m_Size;
+
+ ((tEplObdVString *)pSubIndex->m_pCurrent)->m_pString = pDstData;
+ ((tEplObdVString *)pSubIndex->m_pCurrent)->m_Size = ObjSize;
}
} else if (pSubIndex->m_Type ==
@@ -2942,29 +2884,17 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
pSubIndex->m_pCurrent;
if (pDstData != NULL) {
// 08-dec-2004: code optimization !!!
- // entries ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_pString
- // and ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read
+ // entries ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_pString
+ // and ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_Size were read
// twice. thats not necessary!
// For copying data we have to set the destination pointer to the real RAM string. This
// pointer to RAM string is located in default string info structure. (translated r.d.)
- pDstData =
- (void MEM
- *)((tEplObdOStringDef ROM *) pSubIndex->m_pDefault)->m_pString;
- ObjSize =
- ((tEplObdOStringDef
- ROM *) pSubIndex->
- m_pDefault)->
- m_Size;
-
- ((tEplObdOString MEM *)
- pSubIndex->
- m_pCurrent)->
- m_pString = pDstData;
- ((tEplObdOString MEM *)
- pSubIndex->
- m_pCurrent)->m_Size =
- ObjSize;
+ pDstData = (void *)((tEplObdOStringDef *) pSubIndex->m_pDefault)->m_pString;
+ ObjSize = ((tEplObdOStringDef *)pSubIndex->m_pDefault)->m_Size;
+
+ ((tEplObdOString *)pSubIndex->m_pCurrent)->m_pString = pDstData;
+ ((tEplObdOString *)pSubIndex->m_pCurrent)->m_Size = ObjSize;
}
}
@@ -3069,11 +2999,11 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
else {
if (Direction_p == kEplObdDirLoad) {
- CbStore.m_bCommand = (BYTE) kEplObdCommCloseRead;
+ CbStore.m_bCommand = (u8) kEplObdCommCloseRead;
} else if (Direction_p == kEplObdDirStore) {
- CbStore.m_bCommand = (BYTE) kEplObdCommCloseWrite;
+ CbStore.m_bCommand = (u8) kEplObdCommCloseWrite;
} else if (Direction_p == kEplObdDirRestore) {
- CbStore.m_bCommand = (BYTE) kEplObdCommClear;
+ CbStore.m_bCommand = (u8) kEplObdCommClear;
} else {
goto Exit;
}
@@ -3104,7 +3034,7 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
// Returns: tEplKernel = error code
// ----------------------------------------------------------------------------
-static void EplObdCopyObjectData(void MEM * pDstData_p,
+static void EplObdCopyObjectData(void *pDstData_p,
void *pSrcData_p,
tEplObdSize ObjSize_p, tEplObdType ObjType_p)
{
@@ -3135,7 +3065,7 @@ static void EplObdCopyObjectData(void MEM * pDstData_p,
EPL_MEMCPY(pDstData_p, pSrcData_p, ObjSize_p);
if (ObjType_p == kEplObdTypVString) {
- ((char MEM *)pDstData_p)[StrSize] = '\0';
+ ((char *)pDstData_p)[StrSize] = '\0';
}
}
}
@@ -3196,7 +3126,7 @@ static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
// ----------------------------------------------------------------------------
#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdCbStoreParam MEM *
+ tEplObdCbStoreParam *
pCbStoreParam_p)
{
diff --git a/drivers/staging/epl/EplObd.h b/drivers/staging/epl/EplObd.h
index 88cc11e34cc..6bb5a278068 100644
--- a/drivers/staging/epl/EplObd.h
+++ b/drivers/staging/epl/EplObd.h
@@ -68,11 +68,11 @@
****************************************************************************/
-#include "EplInc.h"
-
#ifndef _EPLOBD_H_
#define _EPLOBD_H_
+#include "EplInc.h"
+
// ============================================================================
// defines
// ============================================================================
@@ -206,7 +206,7 @@ typedef unsigned int tEplObdSize; // For all objects as objects size are used an
// -------------------------------------------------------------------------
// types of objects in object dictionary
-// DS-301 defines these types as WORD
+// DS-301 defines these types as u16
typedef enum {
// types which are always supported
kEplObdTypBool = 0x0001,
@@ -255,15 +255,15 @@ typedef unsigned char tEplObdDomain; // 000F
typedef signed long tEplObdInteger24; // 0010
typedef unsigned long tEplObdUnsigned24; // 0016
-typedef signed QWORD tEplObdInteger40; // 0012
-typedef signed QWORD tEplObdInteger48; // 0013
-typedef signed QWORD tEplObdInteger56; // 0014
-typedef signed QWORD tEplObdInteger64; // 0015
+typedef s64 tEplObdInteger40; // 0012
+typedef s64 tEplObdInteger48; // 0013
+typedef s64 tEplObdInteger56; // 0014
+typedef s64 tEplObdInteger64; // 0015
-typedef unsigned QWORD tEplObdUnsigned40; // 0018
-typedef unsigned QWORD tEplObdUnsigned48; // 0019
-typedef unsigned QWORD tEplObdUnsigned56; // 001A
-typedef unsigned QWORD tEplObdUnsigned64; // 001B
+typedef u64 tEplObdUnsigned40; // 0018
+typedef u64 tEplObdUnsigned48; // 0019
+typedef u64 tEplObdUnsigned56; // 001A
+typedef u64 tEplObdUnsigned64; // 001B
typedef double tEplObdReal64; // 0011
@@ -283,22 +283,21 @@ typedef enum {
kVarValidAll = 0x03 // currently only size and data are implemented and used
} tEplVarParamValid;
-typedef tEplKernel(PUBLIC ROM * tEplVarCallback) (CCM_DECL_INSTANCE_HDL_
- void *pParam_p);
+typedef tEplKernel(*tEplVarCallback) (CCM_DECL_INSTANCE_HDL_ void *pParam_p);
typedef struct {
tEplVarParamValid m_ValidFlag;
unsigned int m_uiIndex;
unsigned int m_uiSubindex;
tEplObdSize m_Size;
- void MEM *m_pData;
+ void *m_pData;
// tEplVarCallback m_fpCallback;
// void * m_pArg;
} tEplVarParam;
typedef struct {
- void MEM *m_pData;
+ void *m_pData;
tEplObdSize m_Size;
/*
#if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
@@ -310,7 +309,7 @@ typedef struct {
typedef struct {
tEplObdSize m_Size;
- BYTE *m_pString;
+ u8 *m_pString;
} tEplObdOString; // 000C
@@ -328,8 +327,8 @@ typedef struct {
typedef struct {
tEplObdSize m_Size;
- BYTE *m_pDefString; // $$$ d.k. it is unused, so we could delete it
- BYTE *m_pString;
+ u8 *m_pDefString; // $$$ d.k. it is unused, so we could delete it
+ u8 *m_pString;
} tEplObdOStringDef;
@@ -354,7 +353,7 @@ typedef struct {
tEplObdType m_Type;
tEplObdAccess m_Access;
void *m_pDefault;
- void MEM *m_pCurrent; // points always to RAM
+ void *m_pCurrent; // points always to RAM
} tEplObdSubEntry;
@@ -371,14 +370,12 @@ typedef struct {
unsigned int m_uiIndex;
unsigned int m_uiSubIndex;
void *m_pArg;
- DWORD m_dwAbortCode;
+ u32 m_dwAbortCode;
} tEplObdCbParam;
// define type for callback function: pParam_p points to tEplObdCbParam
-typedef tEplKernel(PUBLIC ROM * tEplObdCallback) (CCM_DECL_INSTANCE_HDL_
- tEplObdCbParam MEM *
- pParam_p);
+typedef tEplKernel(*tEplObdCallback) (CCM_DECL_INSTANCE_HDL_ tEplObdCbParam *pParam_p);
// do not change the order for this struct!!!
@@ -417,19 +414,14 @@ typedef struct {
typedef struct {
tEplObdCommand m_bCommand;
tEplObdPart m_bCurrentOdPart;
- void MEM *m_pData;
+ void *m_pData;
tEplObdSize m_ObjSize;
} tEplObdCbStoreParam;
-typedef tEplKernel(PUBLIC ROM * tInitTabEntryCallback) (void MEM * pTabEntry_p,
- unsigned int
- uiObjIndex_p);
+typedef tEplKernel(*tInitTabEntryCallback) (void *pTabEntry_p, unsigned int uiObjIndex_p);
-typedef tEplKernel(PUBLIC ROM *
- tEplObdStoreLoadObjCallback) (CCM_DECL_INSTANCE_HDL_
- tEplObdCbStoreParam MEM *
- pCbStoreParam_p);
+typedef tEplKernel(*tEplObdStoreLoadObjCallback) (CCM_DECL_INSTANCE_HDL_ tEplObdCbStoreParam *pCbStoreParam_p);
// -------------------------------------------------------------------------
// this stucture is used for parameters for function ObdInitModuleTab()
@@ -438,8 +430,8 @@ typedef struct {
unsigned int m_uiLowerObjIndex; // lower limit of ObjIndex
unsigned int m_uiUpperObjIndex; // upper limit of ObjIndex
tInitTabEntryCallback m_fpInitTabEntry; // will be called if ObjIndex was found
- void MEM *m_pTabBase; // base address of table
- unsigned int m_uiEntrySize; // size of table entry // 25-feb-2005 r.d.: expansion from BYTE to WORD necessary for PDO bit mapping
+ void *m_pTabBase; // base address of table
+ unsigned int m_uiEntrySize; // size of table entry // 25-feb-2005 r.d.: expansion from u8 to u16 necessary for PDO bit mapping
unsigned int m_uiMaxEntries; // max. tabel entries
} tEplObdModulTabParam;
diff --git a/drivers/staging/epl/EplObdMacro.h b/drivers/staging/epl/EplObdMacro.h
index 23f2ad80dde..fc325bfd604 100644
--- a/drivers/staging/epl/EplObdMacro.h
+++ b/drivers/staging/epl/EplObdMacro.h
@@ -80,7 +80,7 @@
// #pragma message ("EPL_OBD_CREATE_ROM_DATA")
-#define EPL_OBD_BEGIN() static DWORD dwObd_OBK_g = 0x0000;
+#define EPL_OBD_BEGIN() static u32 dwObd_OBK_g = 0x0000;
#define EPL_OBD_END()
//---------------------------------------------------------------------------------------
@@ -102,11 +102,11 @@
#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val) static dtyp xDef##ind##_##sub##_g = val;
#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static dtyp xDef##ind##_##sub##_g[3] = {val,low,high};
#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)
-#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) static char MEM szCur##ind##_##sub##_g[size+1]; \
+#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) static char szCur##ind##_##sub##_g[size+1]; \
static tEplObdVStringDef xDef##ind##_##sub##_g = {size, val, szCur##ind##_##sub##_g};
-#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) static BYTE MEM bCur##ind##_##sub##_g[size]; \
- static tEplObdOStringDef xDef##ind##_##sub##_g = {size, ((BYTE*)""), bCur##ind##_##sub##_g};
+#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) static u8 bCur##ind##_##sub##_g[size]; \
+ static tEplObdOStringDef xDef##ind##_##sub##_g = {size, ((u8*)""), bCur##ind##_##sub##_g};
#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)
#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val) static dtyp xDef##ind##_##sub##_g = val;
#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static dtyp xDef##ind##_##sub##_g[3] = {val,low,high};
@@ -129,20 +129,20 @@
//---------------------------------------------------------------------------------------
#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)
#define EPL_OBD_END_INDEX(ind)
-#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static dtyp MEM axCur##ind##_g[cnt];
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdVarEntry MEM aVarEntry##ind##_g[cnt];
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) static tEplObdVarEntry MEM aVarEntry##ind##_g[cnt];
+#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static dtyp axCur##ind##_g[cnt];
+#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdVarEntry aVarEntry##ind##_g[cnt];
+#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) static tEplObdVarEntry aVarEntry##ind##_g[cnt];
//---------------------------------------------------------------------------------------
-#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val) static dtyp MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static dtyp MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) static tEplObdVString MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) static tEplObdOString MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name) static dtyp MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name) static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val) static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name) static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val) static dtyp xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static dtyp xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) static tEplObdVString xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) static tEplObdOString xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name) static dtyp xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name) static tEplObdVarEntry VarEntry##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val) static tEplObdVarEntry VarEntry##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static tEplObdVarEntry VarEntry##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name) static tEplObdVarEntry VarEntry##ind##_##sub##_g;
//-------------------------------------------------------------------------------------------
#elif defined (EPL_OBD_CREATE_SUBINDEX_TAB)
@@ -159,17 +159,17 @@
#define EPL_OBD_END_PART()
//---------------------------------------------------------------------------------------
-#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call) static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[cnt]= {
+#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call) static tEplObdSubEntry aObdSubEntry##ind##Ram_g[cnt]= {
#define EPL_OBD_END_INDEX(ind) EPL_OBD_END_SUBINDEX()};
-#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[]= { \
+#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdSubEntry aObdSubEntry##ind##Ram_g[]= { \
{0, kEplObdTypUInt8, kEplObdAccCR, &xDef##ind##_0x00_g, NULL}, \
{1, typ, (acc)|kEplObdAccArray, &xDef##ind##_0x01_g, &axCur##ind##_g[0]}, \
EPL_OBD_END_SUBINDEX()};
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[]= { \
+#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdSubEntry aObdSubEntry##ind##Ram_g[]= { \
{0, kEplObdTypUInt8, kEplObdAccCR, &xDef##ind##_0x00_g, NULL}, \
{1, typ, (acc)|kEplObdAccArray|kEplObdAccVar, &xDef##ind##_0x01_g, &aVarEntry##ind##_g[0]}, \
EPL_OBD_END_SUBINDEX()};
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[]= { \
+#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) static tEplObdSubEntry aObdSubEntry##ind##Ram_g[]= { \
{0, kEplObdTypUInt8, kEplObdAccCR, &xDef##ind##_0x00_g, NULL}, \
{1, typ, (acc)|kEplObdAccArray|kEplObdAccVar, NULL, &aVarEntry##ind##_g[0]}, \
EPL_OBD_END_SUBINDEX()};
diff --git a/drivers/staging/epl/EplObdkCal.c b/drivers/staging/epl/EplObdkCal.c
index 4c9af89719e..02bd72224ab 100644
--- a/drivers/staging/epl/EplObdkCal.c
+++ b/drivers/staging/epl/EplObdkCal.c
@@ -70,7 +70,6 @@
****************************************************************************/
#include "EplInc.h"
-#include "kernel/EplObdkCal.h"
/***************************************************************************/
/* */
diff --git a/drivers/staging/epl/EplObdu.c b/drivers/staging/epl/EplObdu.c
index 218d152897c..5f1d9986254 100644
--- a/drivers/staging/epl/EplObdu.c
+++ b/drivers/staging/epl/EplObdu.c
@@ -121,10 +121,9 @@
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p)
+tEplKernel EplObduWriteEntry(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p)
{
tEplKernel Ret;
@@ -153,10 +152,10 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntry(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p)
+tEplKernel EplObduReadEntry(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p,
+ tEplObdSize *pSize_p)
{
tEplKernel Ret;
@@ -179,8 +178,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntry(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduAccessOdPart(tEplObdPart ObdPart_p,
- tEplObdDir Direction_p)
+tEplKernel EplObduAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p)
{
tEplKernel Ret;
@@ -202,7 +200,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduAccessOdPart(tEplObdPart ObdPart_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduDefineVar(tEplVarParam MEM * pVarParam_p)
+tEplKernel EplObduDefineVar(tEplVarParam *pVarParam_p)
{
tEplKernel Ret;
@@ -226,8 +224,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduDefineVar(tEplVarParam MEM * pVarParam_p)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObduGetObjectDataPtr(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p)
+void *EplObduGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p)
{
void *pData;
@@ -250,7 +247,7 @@ EPLDLLEXPORT void *PUBLIC EplObduGetObjectDataPtr(unsigned int uiIndex_p,
//
//---------------------------------------------------------------------------
#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-EPLDLLEXPORT tEplKernel PUBLIC EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p)
+tEplKernel EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p)
{
tEplKernel Ret;
@@ -275,9 +272,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObduInitVarEntry(tEplObdVarEntry MEM * pVarEntry_p,
- BYTE bType_p,
- tEplObdSize ObdSize_p)
+void EplObduInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p, tEplObdSize ObdSize_p)
{
EplObduCalInitVarEntry(pVarEntry_p, bType_p, ObdSize_p);
}
@@ -299,8 +294,7 @@ EPLDLLEXPORT void PUBLIC EplObduInitVarEntry(tEplObdVarEntry MEM * pVarEntry_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObduGetDataSize(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p)
+tEplObdSize EplObduGetDataSize(unsigned int uiIndex_p, unsigned int uiSubIndex_p)
{
tEplObdSize Size;
@@ -323,7 +317,7 @@ EPLDLLEXPORT tEplObdSize PUBLIC EplObduGetDataSize(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObduGetNodeId()
+unsigned int EplObduGetNodeId(void)
{
unsigned int uiNodeId;
@@ -347,8 +341,7 @@ EPLDLLEXPORT unsigned int PUBLIC EplObduGetNodeId()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduSetNodeId(unsigned int uiNodeId_p,
- tEplObdNodeIdType NodeIdType_p)
+tEplKernel EplObduSetNodeId(unsigned int uiNodeId_p, tEplObdNodeIdType NodeIdType_p)
{
tEplKernel Ret;
@@ -373,10 +366,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduSetNodeId(unsigned int uiNodeId_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduGetAccessType(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- tEplObdAccess *
- pAccessTyp_p)
+tEplKernel EplObduGetAccessType(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ tEplObdAccess *pAccessTyp_p)
{
tEplObdAccess AccessType;
@@ -410,10 +402,10 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduGetAccessType(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntryToLe(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p)
+tEplKernel EplObduReadEntryToLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p,
+ tEplObdSize *pSize_p)
{
tEplKernel Ret;
@@ -445,11 +437,10 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntryToLe(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntryFromLe(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p)
+tEplKernel EplObduWriteEntryFromLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p,
+ tEplObdSize Size_p)
{
tEplKernel Ret;
@@ -475,11 +466,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntryFromLe(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- tEplObdVarEntry MEM **
- ppVarEntry_p)
+tEplKernel EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ tEplObdVarEntry **ppVarEntry_p)
{
tEplKernel Ret;
diff --git a/drivers/staging/epl/EplObduCal.c b/drivers/staging/epl/EplObduCal.c
index 85b3df0886b..55612cff821 100644
--- a/drivers/staging/epl/EplObduCal.c
+++ b/drivers/staging/epl/EplObduCal.c
@@ -121,10 +121,9 @@
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p)
+tEplKernel EplObduCalWriteEntry(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p)
{
tEplKernel Ret;
@@ -155,10 +154,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntry(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p)
+tEplKernel EplObduCalReadEntry(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p, tEplObdSize *pSize_p)
{
tEplKernel Ret;
@@ -185,8 +183,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntry(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalAccessOdPart(tEplObdPart ObdPart_p,
- tEplObdDir Direction_p)
+tEplKernel EplObduCalAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p)
{
tEplKernel Ret;
@@ -212,8 +209,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalAccessOdPart(tEplObdPart ObdPart_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalDefineVar(tEplVarParam MEM *
- pVarParam_p)
+tEplKernel EplObduCalDefineVar(tEplVarParam *pVarParam_p)
{
tEplKernel Ret;
@@ -240,8 +236,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalDefineVar(tEplVarParam MEM *
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObduCalGetObjectDataPtr(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p)
+void *EplObduCalGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p)
{
void *pData;
@@ -268,8 +263,7 @@ EPLDLLEXPORT void *PUBLIC EplObduCalGetObjectDataPtr(unsigned int uiIndex_p,
//
//---------------------------------------------------------------------------
#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalRegisterUserOd(tEplObdEntryPtr
- pUserOd_p)
+tEplKernel EplObduCalRegisterUserOd(tEplObdEntryPtr pUserOd_p)
{
tEplKernel Ret;
@@ -298,9 +292,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalRegisterUserOd(tEplObdEntryPtr
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObduCalInitVarEntry(tEplObdVarEntry MEM *
- pVarEntry_p, BYTE bType_p,
- tEplObdSize ObdSize_p)
+void EplObduCalInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p,
+ tEplObdSize ObdSize_p)
{
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
EplObdInitVarEntry(pVarEntry_p, bType_p, ObdSize_p);
@@ -324,8 +317,8 @@ EPLDLLEXPORT void PUBLIC EplObduCalInitVarEntry(tEplObdVarEntry MEM *
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObduCalGetDataSize(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p)
+tEplObdSize EplObduCalGetDataSize(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p)
{
tEplObdSize Size;
@@ -352,7 +345,7 @@ EPLDLLEXPORT tEplObdSize PUBLIC EplObduCalGetDataSize(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObduCalGetNodeId()
+unsigned int EplObduCalGetNodeId(void)
{
unsigned int uiNodeId;
@@ -380,9 +373,8 @@ EPLDLLEXPORT unsigned int PUBLIC EplObduCalGetNodeId()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalSetNodeId(unsigned int uiNodeId_p,
- tEplObdNodeIdType
- NodeIdType_p)
+tEplKernel EplObduCalSetNodeId(unsigned int uiNodeId_p,
+ tEplObdNodeIdType NodeIdType_p)
{
tEplKernel Ret;
@@ -411,11 +403,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalSetNodeId(unsigned int uiNodeId_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalGetAccessType(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p,
- tEplObdAccess *
- pAccessTyp_p)
+tEplKernel EplObduCalGetAccessType(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ tEplObdAccess *pAccessTyp_p)
{
tEplObdAccess AccesType;
@@ -447,11 +437,10 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalGetAccessType(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntryToLe(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p)
+tEplKernel EplObduCalReadEntryToLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p,
+ tEplObdSize *pSize_p)
{
tEplKernel Ret;
@@ -481,12 +470,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntryToLe(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntryFromLe(unsigned int
- uiIndex_p,
- unsigned int
- uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p)
+tEplKernel EplObduCalWriteEntryFromLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p)
{
tEplKernel Ret;
@@ -514,10 +500,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntryFromLe(unsigned int
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- tEplObdVarEntry MEM ** ppVarEntry_p)
+tEplKernel EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ tEplObdVarEntry **ppVarEntry_p)
{
tEplKernel Ret;
diff --git a/drivers/staging/epl/EplObjDef.h b/drivers/staging/epl/EplObjDef.h
deleted file mode 100644
index 7713125a3e8..00000000000
--- a/drivers/staging/epl/EplObjDef.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: openPOWERLINK
-
- Description: defines objdict dictionary
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS 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.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- $RCSfile: EplObjDef.h,v $
-
- $Author: D.Krueger $
-
- $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $
-
- $State: Exp $
-
- Build Environment:
- GCC V3.4
-
- -------------------------------------------------------------------------
-
- Revision History:
-
- 2006/06/06 k.t.: take ObjDef.h from CANopen and modify for EPL
-
-****************************************************************************/
-
-#ifndef _EPLOBJDEF_H_
-#define _EPLOBJDEF_H_
-
-//---------------------------------------------------------------------------
-// security checks
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// macros to help building OD
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-#if (defined (EPL_OBD_USE_VARIABLE_SUBINDEX_TAB) && (EPL_OBD_USE_VARIABLE_SUBINDEX_TAB != FALSE))
-
-#define CCM_SUBINDEX_RAM_ONLY(a) a;
-#define CCM_SUBINDEX_RAM_ONEOF(a,b) a
-
-#else
-
-#define CCM_SUBINDEX_RAM_ONLY(a)
-#define CCM_SUBINDEX_RAM_ONEOF(a,b) b
-
-#endif
-
-//---------------------------------------------------------------------------
-// To prevent unused memory in subindex tables we need this macro.
-// But not all compilers support to preset the last struct value followed by a comma.
-// Compilers which does not support a comma after last struct value has to place in a dummy subindex.
-#if ((DEV_SYSTEM & _DEV_COMMA_EXT_) != 0)
-
-#define EPL_OBD_END_SUBINDEX()
-#define EPL_OBD_MAX_ARRAY_SUBENTRIES 2
-
-#else
-
-#define EPL_OBD_END_SUBINDEX() {0,0,0,NULL,NULL}
-#define EPL_OBD_MAX_ARRAY_SUBENTRIES 3
-
-#endif
-
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-// globale vars
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-
-// -------------------------------------------------------------------------
-// creation of data in ROM memory
-// -------------------------------------------------------------------------
-#define EPL_OBD_CREATE_ROM_DATA
-#include "objdict.h"
-#undef EPL_OBD_CREATE_ROM_DATA
-
-// -------------------------------------------------------------------------
-// creation of data in RAM memory
-// -------------------------------------------------------------------------
-
-#define EPL_OBD_CREATE_RAM_DATA
-#include "objdict.h"
-#undef EPL_OBD_CREATE_RAM_DATA
-
-// -------------------------------------------------------------------------
-// creation of subindex tables in ROM and RAM
-// -------------------------------------------------------------------------
-
-#define EPL_OBD_CREATE_SUBINDEX_TAB
-#include "objdict.h"
-#undef EPL_OBD_CREATE_SUBINDEX_TAB
-
-// -------------------------------------------------------------------------
-// creation of index tables for generic, manufacturer and device part
-// -------------------------------------------------------------------------
-
-#define EPL_OBD_CREATE_INDEX_TAB
-#include "objdict.h"
-#undef EPL_OBD_CREATE_INDEX_TAB
-
-//=========================================================================//
-// //
-// P U B L I C F U N C T I O N S //
-// //
-//=========================================================================//
-
-// ----------------------------------------------------------------------------
-//
-// Function: EPL_OBD_INIT_RAM_NAME()
-//
-// Description: function to initialize object dictionary
-//
-// Parameters: pInitParam_p = pointer to init param struct of Epl
-//
-// Returns: tEplKernel = error code
-//
-// State:
-//
-// ----------------------------------------------------------------------------
-
-EPLDLLEXPORT tEplKernel PUBLIC EPL_OBD_INIT_RAM_NAME(tEplObdInitParam MEM *
- pInitParam_p)
-{
-
- tEplObdInitParam MEM *pInitParam = pInitParam_p;
-
- // check if pointer to parameter structure is valid
- // if not then only copy subindex tables below
- if (pInitParam != NULL) {
- // at first delete all parameters (all pointers will be set zu NULL)
- EPL_MEMSET(pInitParam, 0, sizeof(tEplObdInitParam));
-
-#define EPL_OBD_CREATE_INIT_FUNCTION
- {
- // inserts code to init pointer to index tables
-#include "objdict.h"
- }
-#undef EPL_OBD_CREATE_INIT_FUNCTION
-
-#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
- {
- // to begin no user OD is defined
- pInitParam_p->m_pUserPart = NULL;
- }
-#endif
- }
-#define EPL_OBD_CREATE_INIT_SUBINDEX
- {
- // inserts code to copy subindex tables
-#include "objdict.h"
- }
-#undef EPL_OBD_CREATE_INIT_SUBINDEX
-
- return kEplSuccessful;
-
-}
-
-#endif // _EPLOBJDEF_H_
-
-// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
-// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder).
diff --git a/drivers/staging/epl/EplPdo.h b/drivers/staging/epl/EplPdo.h
index d22ac86e85b..0b3ad5bc7d5 100644
--- a/drivers/staging/epl/EplPdo.h
+++ b/drivers/staging/epl/EplPdo.h
@@ -90,8 +90,8 @@
typedef struct {
void *m_pVar;
- WORD m_wOffset; // in Bits
- WORD m_wSize; // in Bits
+ u16 m_wOffset; // in Bits
+ u16 m_wSize; // in Bits
BOOL m_fNumeric; // numeric value -> use AMI functions
} tEplPdoMapping;
@@ -104,7 +104,7 @@ typedef struct {
// TPDO: 0x00=PRes, MN: CnNodeId=PReq
BOOL m_fTxRx;
- BYTE m_bMappingVersion;
+ u8 m_bMappingVersion;
unsigned int m_uiMaxMappingEntries; // maximum number of mapping entries, i.e. size of m_aPdoMapping
tEplPdoMapping m_aPdoMapping[1];
diff --git a/drivers/staging/epl/EplPdok.c b/drivers/staging/epl/EplPdok.c
index 15999b4f575..db9b3f08384 100644
--- a/drivers/staging/epl/EplPdok.c
+++ b/drivers/staging/epl/EplPdok.c
@@ -73,11 +73,6 @@
#include "kernel/EplEventk.h"
#include "kernel/EplObdk.h"
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
-#include "plccore.h"
-#define PDO_LED 0x08
-#endif
-
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) == 0)
@@ -226,11 +221,6 @@ tEplKernel EplPdokCbPdoReceived(tEplFrameInfo * pFrameInfo_p)
tEplKernel Ret = kEplSuccessful;
tEplEvent Event;
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
- // reset LED
-// MCF_GPIO_PODR_PCIBG &= ~PDO_LED; // Level
-#endif
-
Event.m_EventSink = kEplEventSinkPdok;
Event.m_EventType = kEplEventTypePdoRx;
// limit copied data to size of PDO (because from some CNs the frame is larger than necessary)
@@ -238,11 +228,6 @@ tEplKernel EplPdokCbPdoReceived(tEplFrameInfo * pFrameInfo_p)
Event.m_pArg = pFrameInfo_p->m_pFrame;
Ret = EplEventkPost(&Event);
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
- // set LED
-// MCF_GPIO_PODR_PCIBG |= PDO_LED; // Level
-#endif
-
return Ret;
}
@@ -269,22 +254,12 @@ tEplKernel EplPdokCbPdoTransmitted(tEplFrameInfo * pFrameInfo_p)
tEplKernel Ret = kEplSuccessful;
tEplEvent Event;
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
- // reset LED
- MCF_GPIO_PODR_PCIBG &= ~PDO_LED; // Level
-#endif
-
Event.m_EventSink = kEplEventSinkPdok;
Event.m_EventType = kEplEventTypePdoTx;
Event.m_uiSize = sizeof(tEplFrameInfo);
Event.m_pArg = pFrameInfo_p;
Ret = EplEventkPost(&Event);
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
- // set LED
- MCF_GPIO_PODR_PCIBG |= PDO_LED; // Level
-#endif
-
return Ret;
}
@@ -339,19 +314,19 @@ tEplKernel EplPdokCbSoa(tEplFrameInfo * pFrameInfo_p)
tEplKernel EplPdokProcess(tEplEvent * pEvent_p)
{
tEplKernel Ret = kEplSuccessful;
- WORD wPdoSize;
- WORD wBitOffset;
- WORD wBitSize;
- WORD wVarSize;
- QWORD qwObjectMapping;
- BYTE bMappSubindex;
- BYTE bObdSubindex;
- WORD wObdMappIndex;
- WORD wObdCommIndex;
- WORD wPdoId;
- BYTE bObdData;
- BYTE bObjectCount;
- BYTE bFrameData;
+ u16 wPdoSize;
+ u16 wBitOffset;
+ u16 wBitSize;
+ u16 wVarSize;
+ u64 qwObjectMapping;
+ u8 bMappSubindex;
+ u8 bObdSubindex;
+ u16 wObdMappIndex;
+ u16 wObdCommIndex;
+ u16 wPdoId;
+ u8 bObdData;
+ u8 bObjectCount;
+ u8 bFrameData;
BOOL fValid;
tEplObdSize ObdSize;
tEplFrame *pFrame;
@@ -448,7 +423,7 @@ tEplKernel EplPdokProcess(tEplEvent * pEvent_p)
// process mapping
for (bMappSubindex = 1; bMappSubindex <= bObjectCount;
bMappSubindex++) {
- ObdSize = 8; // QWORD
+ ObdSize = 8; // u64
// read object mapping from OD
Ret =
EplObdReadEntry(wObdMappIndex,
@@ -463,16 +438,16 @@ tEplKernel EplPdokProcess(tEplEvent * pEvent_p)
}
// decode object mapping
wObdCommIndex =
- (WORD) (qwObjectMapping &
+ (u16) (qwObjectMapping &
0x000000000000FFFFLL);
bObdSubindex =
- (BYTE) ((qwObjectMapping &
+ (u8) ((qwObjectMapping &
0x0000000000FF0000LL) >> 16);
wBitOffset =
- (WORD) ((qwObjectMapping &
+ (u16) ((qwObjectMapping &
0x0000FFFF00000000LL) >> 32);
wBitSize =
- (WORD) ((qwObjectMapping &
+ (u16) ((qwObjectMapping &
0xFFFF000000000000LL) >> 48);
// check if object exceeds PDO size
@@ -578,7 +553,7 @@ tEplKernel EplPdokProcess(tEplEvent * pEvent_p)
// process mapping
for (bMappSubindex = 1; bMappSubindex <= bObjectCount;
bMappSubindex++) {
- ObdSize = 8; // QWORD
+ ObdSize = 8; // u64
// read object mapping from OD
Ret =
EplObdReadEntry(wObdMappIndex,
@@ -593,21 +568,21 @@ tEplKernel EplPdokProcess(tEplEvent * pEvent_p)
}
// decode object mapping
wObdCommIndex =
- (WORD) (qwObjectMapping &
+ (u16) (qwObjectMapping &
0x000000000000FFFFLL);
bObdSubindex =
- (BYTE) ((qwObjectMapping &
+ (u8) ((qwObjectMapping &
0x0000000000FF0000LL) >> 16);
wBitOffset =
- (WORD) ((qwObjectMapping &
+ (u16) ((qwObjectMapping &
0x0000FFFF00000000LL) >> 32);
wBitSize =
- (WORD) ((qwObjectMapping &
+ (u16) ((qwObjectMapping &
0xFFFF000000000000LL) >> 48);
// calculate max PDO size
ObdSize = wBitSize >> 3;
- wVarSize = (wBitOffset >> 3) + (WORD) ObdSize;
+ wVarSize = (wBitOffset >> 3) + (u16) ObdSize;
if ((unsigned int)(wVarSize + 24) > pFrameInfo->m_uiFrameSize) { // TPDO is too short
// $$$ raise PDO error, set Ret
goto Exit;
diff --git a/drivers/staging/epl/EplPdou.c b/drivers/staging/epl/EplPdou.c
index e7b10653a0e..d6d06242d74 100644
--- a/drivers/staging/epl/EplPdou.c
+++ b/drivers/staging/epl/EplPdou.c
@@ -149,18 +149,18 @@
// local function prototypes
//---------------------------------------------------------------------------
-static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam MEM * pParam_p,
+static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam *pParam_p,
unsigned int uiIndex_p);
-static void EplPdouDecodeObjectMapping(QWORD qwObjectMapping_p,
+static void EplPdouDecodeObjectMapping(u64 qwObjectMapping_p,
unsigned int *puiIndex_p,
unsigned int *puiSubIndex_p,
unsigned int *puiBitOffset_p,
unsigned int *puiBitSize_p);
-static tEplKernel EplPdouCheckObjectMapping(QWORD qwObjectMapping_p,
+static tEplKernel EplPdouCheckObjectMapping(u64 qwObjectMapping_p,
tEplObdAccess AccessType_p,
- DWORD * pdwAbortCode_p,
+ u32 * pdwAbortCode_p,
unsigned int *puiPdoSize_p);
//=========================================================================//
@@ -226,18 +226,18 @@ tEplKernel EplPdouDelInstance(void)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p)
+tEplKernel EplPdouCbObdAccess(tEplObdCbParam *pParam_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiPdoId;
unsigned int uiIndexType;
tEplObdSize ObdSize;
- BYTE bObjectCount;
- QWORD qwObjectMapping;
+ u8 bObjectCount;
+ u64 qwObjectMapping;
tEplObdAccess AccessType;
- BYTE bMappSubindex;
+ u8 bMappSubindex;
unsigned int uiCurPdoSize;
- WORD wMaxPdoSize;
+ u16 wMaxPdoSize;
unsigned int uiSubIndex;
// fetch PDO ID
@@ -293,7 +293,7 @@ tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p)
if (pParam_p->m_uiSubIndex == 0) { // object mapping count accessed
// PDO is enabled or disabled
- bObjectCount = *((BYTE *) pParam_p->m_pArg);
+ bObjectCount = *((u8 *) pParam_p->m_pArg);
if (bObjectCount == 0) { // PDO shall be disabled
@@ -326,7 +326,7 @@ tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p)
for (bMappSubindex = 1; bMappSubindex <= bObjectCount;
bMappSubindex++) {
// read object mapping from OD
- ObdSize = sizeof(qwObjectMapping); // QWORD
+ ObdSize = sizeof(qwObjectMapping); // u64
Ret = EplObduReadEntry(pParam_p->m_uiIndex,
bMappSubindex, &qwObjectMapping,
&ObdSize);
@@ -360,7 +360,7 @@ tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p)
}
// check existence of object and validity of object length
- qwObjectMapping = *((QWORD *) pParam_p->m_pArg);
+ qwObjectMapping = *((u64 *) pParam_p->m_pArg);
Ret = EplPdouCheckObjectMapping(qwObjectMapping,
AccessType,
@@ -394,12 +394,12 @@ tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p)
//
//---------------------------------------------------------------------------
-static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam MEM * pParam_p,
+static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam *pParam_p,
unsigned int uiIndex_p)
{
tEplKernel Ret = kEplSuccessful;
tEplObdSize ObdSize;
- BYTE bObjectCount;
+ u8 bObjectCount;
ObdSize = 1;
// read number of mapped objects from OD; this indicates if the PDO is valid
@@ -439,7 +439,7 @@ static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam MEM * pParam_p,
//
//---------------------------------------------------------------------------
-static void EplPdouDecodeObjectMapping(QWORD qwObjectMapping_p,
+static void EplPdouDecodeObjectMapping(u64 qwObjectMapping_p,
unsigned int *puiIndex_p,
unsigned int *puiSubIndex_p,
unsigned int *puiBitOffset_p,
@@ -480,9 +480,9 @@ static void EplPdouDecodeObjectMapping(QWORD qwObjectMapping_p,
//
//---------------------------------------------------------------------------
-static tEplKernel EplPdouCheckObjectMapping(QWORD qwObjectMapping_p,
+static tEplKernel EplPdouCheckObjectMapping(u64 qwObjectMapping_p,
tEplObdAccess AccessType_p,
- DWORD * pdwAbortCode_p,
+ u32 * pdwAbortCode_p,
unsigned int *puiPdoSize_p)
{
tEplKernel Ret = kEplSuccessful;
diff --git a/drivers/staging/epl/EplSdo.h b/drivers/staging/epl/EplSdo.h
index 1cb3f2de4a3..8002e0cc4d9 100644
--- a/drivers/staging/epl/EplSdo.h
+++ b/drivers/staging/epl/EplSdo.h
@@ -116,20 +116,18 @@ typedef unsigned int tEplSdoConHdl;
// callback function pointer for Protocol Abstraction Layer to call
// asynchronuus SDO Sequence Layer
-typedef tEplKernel(PUBLIC * tEplSequLayerReceiveCb) (tEplSdoConHdl ConHdl_p,
- tEplAsySdoSeq *
- pSdoSeqData_p,
- unsigned int uiDataSize_p);
+typedef tEplKernel(*tEplSequLayerReceiveCb) (tEplSdoConHdl ConHdl_p,
+ tEplAsySdoSeq *pSdoSeqData_p,
+ unsigned int uiDataSize_p);
// handle between asynchronuus SDO Sequence Layer and SDO Command layer
typedef unsigned int tEplSdoSeqConHdl;
// callback function pointer for asynchronuus SDO Sequence Layer to call
// SDO Command layer for received data
-typedef tEplKernel(PUBLIC *
- tEplSdoComReceiveCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
- tEplAsySdoCom * pAsySdoCom_p,
- unsigned int uiDataSize_p);
+typedef tEplKernel(* tEplSdoComReceiveCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
+ tEplAsySdoCom *pAsySdoCom_p,
+ unsigned int uiDataSize_p);
// status of connection
typedef enum {
@@ -143,9 +141,8 @@ typedef enum {
// callback function pointer for asynchronuus SDO Sequence Layer to call
// SDO Command layer for connection status
-typedef tEplKernel(PUBLIC * tEplSdoComConCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
- tEplAsySdoConState
- AsySdoConState_p);
+typedef tEplKernel(* tEplSdoComConCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
+ tEplAsySdoConState AsySdoConState_p);
// handle between SDO Command layer and application
typedef unsigned int tEplSdoComConHdl;
@@ -210,7 +207,7 @@ typedef enum {
typedef struct {
tEplSdoComConHdl m_SdoComConHdl;
tEplSdoComConState m_SdoComConState;
- DWORD m_dwAbortCode;
+ u32 m_dwAbortCode;
tEplSdoAccessType m_SdoAccessType;
unsigned int m_uiNodeId; // NodeId of the target
unsigned int m_uiTargetIndex; // index which was accessed
@@ -221,8 +218,7 @@ typedef struct {
} tEplSdoComFinished;
// callback function pointer to inform application about connection
-typedef tEplKernel(PUBLIC * tEplSdoFinishedCb) (tEplSdoComFinished *
- pSdoComFinished_p);
+typedef tEplKernel(* tEplSdoFinishedCb) (tEplSdoComFinished *pSdoComFinished_p);
// structure to init SDO transfer to Read or Write by Index
typedef struct {
diff --git a/drivers/staging/epl/EplSdoAsndu.c b/drivers/staging/epl/EplSdoAsndu.c
index 05a00c9a731..aa8bdef317c 100644
--- a/drivers/staging/epl/EplSdoAsndu.c
+++ b/drivers/staging/epl/EplSdoAsndu.c
@@ -110,7 +110,7 @@ static tEplSdoAsndInstance SdoAsndInstance_g;
// local function prototypes
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p);
+tEplKernel EplSdoAsnduCb(tEplFrameInfo *pFrameInfo_p);
/***************************************************************************/
/* */
@@ -149,7 +149,7 @@ tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p);
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)
+tEplKernel EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)
{
tEplKernel Ret;
@@ -176,7 +176,7 @@ tEplKernel PUBLIC EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
+tEplKernel EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
{
tEplKernel Ret;
@@ -218,7 +218,7 @@ tEplKernel PUBLIC EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduDelInstance()
+tEplKernel EplSdoAsnduDelInstance(void)
{
tEplKernel Ret;
@@ -251,8 +251,8 @@ tEplKernel PUBLIC EplSdoAsnduDelInstance()
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduInitCon(tEplSdoConHdl * pSdoConHandle_p,
- unsigned int uiTargetNodeId_p)
+tEplKernel EplSdoAsnduInitCon(tEplSdoConHdl *pSdoConHandle_p,
+ unsigned int uiTargetNodeId_p)
{
tEplKernel Ret;
unsigned int uiCount;
@@ -319,9 +319,9 @@ tEplKernel PUBLIC EplSdoAsnduInitCon(tEplSdoConHdl * pSdoConHandle_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
- tEplFrame * pSrcData_p,
- DWORD dwDataSize_p)
+tEplKernel EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
+ tEplFrame *pSrcData_p,
+ u32 dwDataSize_p)
{
tEplKernel Ret;
unsigned int uiArray;
@@ -339,10 +339,10 @@ tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
// own node id not needed -> filled by DLL
// set message type
- AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, (BYTE) kEplMsgTypeAsnd); // ASnd == 0x06
+ AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, (u8) kEplMsgTypeAsnd); // ASnd == 0x06
// target node id
AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId,
- (BYTE) SdoAsndInstance_g.
+ (u8) SdoAsndInstance_g.
m_auiSdoAsndConnection[uiArray]);
// set source-nodeid (filled by DLL 0)
AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00);
@@ -379,7 +379,7 @@ tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)
+tEplKernel EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)
{
tEplKernel Ret;
unsigned int uiArray;
@@ -422,7 +422,7 @@ tEplKernel PUBLIC EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p)
+tEplKernel EplSdoAsnduCb(tEplFrameInfo *pFrameInfo_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiCount;
diff --git a/drivers/staging/epl/EplSdoAsySequ.c b/drivers/staging/epl/EplSdoAsySequ.c
index 6b6a9975d78..256d7086634 100644
--- a/drivers/staging/epl/EplSdoAsySequ.c
+++ b/drivers/staging/epl/EplSdoAsySequ.c
@@ -128,11 +128,11 @@ typedef enum {
// structure for History-Buffer
typedef struct {
- BYTE m_bFreeEntries;
- BYTE m_bWrite; // index of the next free buffer entry
- BYTE m_bAck; // index of the next message which should become acknowledged
- BYTE m_bRead; // index between m_bAck and m_bWrite to the next message for retransmission
- BYTE m_aabHistoryFrame[EPL_SDO_HISTORY_SIZE]
+ u8 m_bFreeEntries;
+ u8 m_bWrite; // index of the next free buffer entry
+ u8 m_bAck; // index of the next message which should become acknowledged
+ u8 m_bRead; // index between m_bAck and m_bWrite to the next message for retransmission
+ u8 m_aabHistoryFrame[EPL_SDO_HISTORY_SIZE]
[EPL_SEQ_HISTROY_FRAME_SIZE];
unsigned int m_auiFrameSize[EPL_SDO_HISTORY_SIZE];
@@ -152,8 +152,8 @@ typedef enum {
typedef struct {
tEplSdoConHdl m_ConHandle;
tEplAsySdoState m_SdoState;
- BYTE m_bRecSeqNum; // name from view of the communication partner
- BYTE m_bSendSeqNum; // name from view of the communication partner
+ u8 m_bRecSeqNum; // name from view of the communication partner
+ u8 m_bSendSeqNum; // name from view of the communication partner
tEplAsySdoConHistory m_SdoConHistory;
tEplTimerHdl m_EplTimerHdl;
unsigned int m_uiRetryCount; // retry counter
@@ -203,9 +203,9 @@ static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
unsigned int uiDataSize_p,
tEplFrame * pEplFrame_p);
-tEplKernel PUBLIC EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
- tEplAsySdoSeq * pSdoSeqData_p,
- unsigned int uiDataSize_p);
+tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
+ tEplAsySdoSeq *pSdoSeqData_p,
+ unsigned int uiDataSize_p);
static tEplKernel EplSdoAsyInitHistory(void);
@@ -214,7 +214,7 @@ static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
unsigned int uiSize_p);
static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
- BYTE bRecSeqNumber_p);
+ u8 bRecSeqNumber_p);
static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
tEplFrame ** ppFrame_p,
@@ -267,8 +267,8 @@ static tEplKernel EplSdoAsySeqSetTimer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
- tEplSdoComConCb fpSdoComConCb_p)
+tEplKernel EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
+ tEplSdoComConCb fpSdoComConCb_p)
{
tEplKernel Ret;
@@ -297,8 +297,8 @@ tEplKernel PUBLIC EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
- tEplSdoComConCb fpSdoComConCb_p)
+tEplKernel EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
+ tEplSdoComConCb fpSdoComConCb_p)
{
tEplKernel Ret;
@@ -380,7 +380,7 @@ tEplKernel PUBLIC EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqDelInstance()
+tEplKernel EplSdoAsySeqDelInstance(void)
{
tEplKernel Ret;
unsigned int uiCount;
@@ -439,9 +439,9 @@ tEplKernel PUBLIC EplSdoAsySeqDelInstance()
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqInitCon(tEplSdoSeqConHdl * pSdoSeqConHdl_p,
- unsigned int uiNodeId_p,
- tEplSdoType SdoType)
+tEplKernel EplSdoAsySeqInitCon(tEplSdoSeqConHdl *pSdoSeqConHdl_p,
+ unsigned int uiNodeId_p,
+ tEplSdoType SdoType)
{
tEplKernel Ret;
unsigned int uiCount;
@@ -594,9 +594,9 @@ tEplKernel PUBLIC EplSdoAsySeqInitCon(tEplSdoSeqConHdl * pSdoSeqConHdl_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
- unsigned int uiDataSize_p,
- tEplFrame * pabData_p)
+tEplKernel EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
+ unsigned int uiDataSize_p,
+ tEplFrame *pabData_p)
{
tEplKernel Ret;
unsigned int uiHandle;
@@ -640,7 +640,7 @@ tEplKernel PUBLIC EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqProcessEvent(tEplEvent * pEvent_p)
+tEplKernel EplSdoAsySeqProcessEvent(tEplEvent *pEvent_p)
{
tEplKernel Ret;
tEplTimerEventArg *pTimerEventArg;
@@ -714,7 +714,7 @@ tEplKernel PUBLIC EplSdoAsySeqProcessEvent(tEplEvent * pEvent_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p)
+tEplKernel EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiHandle;
@@ -1498,7 +1498,7 @@ static tEplKernel EplSdoAsySeqProcess(unsigned int uiHandle_p,
// frame received
case kAsySdoSeqEventFrameRec:
{
- BYTE bSendSeqNumCon =
+ u8 bSendSeqNumCon =
AmiGetByteFromLe(&pRecFrame_p->
m_le_bSendSeqNumCon);
@@ -2016,7 +2016,7 @@ static tEplKernel EplSdoAsySeqSendIntern(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
BOOL fFrameInHistory_p)
{
tEplKernel Ret;
- BYTE abFrame[EPL_SEQ_FRAME_SIZE];
+ u8 abFrame[EPL_SEQ_FRAME_SIZE];
tEplFrame *pEplFrame;
unsigned int uiFreeEntries;
@@ -2139,9 +2139,9 @@ static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
- tEplAsySdoSeq * pSdoSeqData_p,
- unsigned int uiDataSize_p)
+tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
+ tEplAsySdoSeq *pSdoSeqData_p,
+ unsigned int uiDataSize_p)
{
tEplKernel Ret;
unsigned int uiCount = 0;
@@ -2154,7 +2154,7 @@ tEplKernel PUBLIC EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
#endif
EPL_DBGLVL_SDO_TRACE2("Handle: 0x%x , First Databyte 0x%x\n", ConHdl_p,
- ((BYTE *) pSdoSeqData_p)[0]);
+ ((u8 *) pSdoSeqData_p)[0]);
// search controll structure for this connection
pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiCount];
@@ -2328,12 +2328,12 @@ static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
//
//---------------------------------------------------------------------------
static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
- BYTE bRecSeqNumber_p)
+ u8 bRecSeqNumber_p)
{
tEplKernel Ret;
tEplAsySdoConHistory *pHistory;
- BYTE bAckIndex;
- BYTE bCurrentSeqNum;
+ u8 bAckIndex;
+ u8 bCurrentSeqNum;
Ret = kEplSuccessful;
@@ -2422,8 +2422,8 @@ static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
// check if entries are available for reading
if ((pHistory->m_bFreeEntries < EPL_SDO_HISTORY_SIZE)
&& (pHistory->m_bWrite != pHistory->m_bRead)) {
-// PRINTF4("EplSdoAsyReadFromHistory(): init = %d, read = %u, write = %u, ack = %u", (int) fInitRead_p, (WORD)pHistory->m_bRead, (WORD)pHistory->m_bWrite, (WORD)pHistory->m_bAck);
-// PRINTF2(", free entries = %u, next frame size = %u\n", (WORD)pHistory->m_bFreeEntries, pHistory->m_auiFrameSize[pHistory->m_bRead]);
+// PRINTF4("EplSdoAsyReadFromHistory(): init = %d, read = %u, write = %u, ack = %u", (int) fInitRead_p, (u16)pHistory->m_bRead, (u16)pHistory->m_bWrite, (u16)pHistory->m_bAck);
+// PRINTF2(", free entries = %u, next frame size = %u\n", (u16)pHistory->m_bFreeEntries, pHistory->m_auiFrameSize[pHistory->m_bRead]);
// return pointer to stored frame
*ppFrame_p =
@@ -2439,7 +2439,7 @@ static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
}
} else {
-// PRINTF3("EplSdoAsyReadFromHistory(): read = %u, ack = %u, free entries = %u, no frame\n", (WORD)pHistory->m_bRead, (WORD)pHistory->m_bAck, (WORD)pHistory->m_bFreeEntries);
+// PRINTF3("EplSdoAsyReadFromHistory(): read = %u, ack = %u, free entries = %u, no frame\n", (u16)pHistory->m_bRead, (u16)pHistory->m_bAck, (u16)pHistory->m_bFreeEntries);
// no more frames to send
// return null pointer
diff --git a/drivers/staging/epl/EplSdoComu.c b/drivers/staging/epl/EplSdoComu.c
index ce0eb33f4c4..bf35afab152 100644
--- a/drivers/staging/epl/EplSdoComu.c
+++ b/drivers/staging/epl/EplSdoComu.c
@@ -156,14 +156,14 @@ typedef enum {
typedef struct {
tEplSdoSeqConHdl m_SdoSeqConHdl; // if != 0 -> entry used
tEplSdoComState m_SdoComState;
- BYTE m_bTransactionId;
+ u8 m_bTransactionId;
unsigned int m_uiNodeId; // NodeId of the target
// -> needed to reinit connection
// after timeout
tEplSdoTransType m_SdoTransType; // Auto, Expedited, Segmented
tEplSdoServiceType m_SdoServiceType; // WriteByIndex, ReadByIndex
tEplSdoType m_SdoProtType; // protocol layer: Auto, Udp, Asnd, Pdo
- BYTE *m_pData; // pointer to data
+ u8 *m_pData; // pointer to data
unsigned int m_uiTransSize; // number of bytes
// to transfer
unsigned int m_uiTransferredByte; // number of bytes
@@ -174,7 +174,7 @@ typedef struct {
// the SDO transfer
void *m_pUserArg; // user definable argument pointer
- DWORD m_dwLastAbortCode; // save the last abort code
+ u32 m_dwLastAbortCode; // save the last abort code
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
// only for client
unsigned int m_uiTargetIndex; // index to access
@@ -205,12 +205,12 @@ static tEplSdoComInstance SdoComInstance_g;
//---------------------------------------------------------------------------
// local function prototypes
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
- tEplAsySdoCom * pAsySdoCom_p,
- unsigned int uiDataSize_p);
+tEplKernel EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
+ tEplAsySdoCom *pAsySdoCom_p,
+ unsigned int uiDataSize_p);
-tEplKernel PUBLIC EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
- tEplAsySdoConState AsySdoConState_p);
+tEplKernel EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
+ tEplAsySdoConState AsySdoConState_p);
static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p,
tEplSdoComConEvent SdoComConEvent_p,
@@ -246,7 +246,7 @@ static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
tEplAsySdoCom * pAsySdoCom_p);
static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
- DWORD dwAbortCode_p);
+ u32 dwAbortCode_p);
#endif
/***************************************************************************/
@@ -285,7 +285,7 @@ static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComInit(void)
+tEplKernel EplSdoComInit(void)
{
tEplKernel Ret;
@@ -312,7 +312,7 @@ tEplKernel PUBLIC EplSdoComInit(void)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComAddInstance(void)
+tEplKernel EplSdoComAddInstance(void)
{
tEplKernel Ret;
@@ -354,7 +354,7 @@ tEplKernel PUBLIC EplSdoComAddInstance(void)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComDelInstance(void)
+tEplKernel EplSdoComDelInstance(void)
{
tEplKernel Ret;
@@ -398,9 +398,9 @@ tEplKernel PUBLIC EplSdoComDelInstance(void)
//
//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComDefineCon(tEplSdoComConHdl * pSdoComConHdl_p,
- unsigned int uiTargetNodeId_p,
- tEplSdoType ProtType_p)
+tEplKernel EplSdoComDefineCon(tEplSdoComConHdl *pSdoComConHdl_p,
+ unsigned int uiTargetNodeId_p,
+ tEplSdoType ProtType_p)
{
tEplKernel Ret;
unsigned int uiCount;
@@ -511,8 +511,7 @@ tEplKernel PUBLIC EplSdoComDefineCon(tEplSdoComConHdl * pSdoComConHdl_p,
//
//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *
- pSdoComTransParam_p)
+tEplKernel EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *pSdoComTransParam_p)
{
tEplKernel Ret;
tEplSdoComCon *pSdoComCon;
@@ -603,7 +602,7 @@ tEplKernel PUBLIC EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *
//
//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p)
+tEplKernel EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p)
{
tEplKernel Ret;
tEplSdoComCon *pSdoComCon;
@@ -669,8 +668,8 @@ tEplKernel PUBLIC EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p)
//
//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
- tEplSdoComFinished * pSdoComFinished_p)
+tEplKernel EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
+ tEplSdoComFinished *pSdoComFinished_p)
{
tEplKernel Ret;
tEplSdoComCon *pSdoComCon;
@@ -747,8 +746,8 @@ tEplKernel PUBLIC EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
//
//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
- DWORD dwAbortCode_p)
+tEplKernel EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
+ u32 dwAbortCode_p)
{
tEplKernel Ret;
tEplSdoComCon *pSdoComCon;
@@ -766,7 +765,7 @@ tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
goto Exit;
}
// save pointer to abort code
- pSdoComCon->m_pData = (BYTE *) & dwAbortCode_p;
+ pSdoComCon->m_pData = (u8 *) & dwAbortCode_p;
Ret = EplSdoComProcessIntern(SdoComConHdl_p,
kEplSdoComConEventAbort,
@@ -803,9 +802,9 @@ tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
- tEplAsySdoCom * pAsySdoCom_p,
- unsigned int uiDataSize_p)
+tEplKernel EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
+ tEplAsySdoCom *pAsySdoCom_p,
+ unsigned int uiDataSize_p)
{
tEplKernel Ret;
@@ -815,7 +814,7 @@ tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
EPL_DBGLVL_SDO_TRACE3
("EplSdoComReceiveCb SdoSeqConHdl: 0x%X, First Byte of pAsySdoCom_p: 0x%02X, uiDataSize_p: 0x%04X\n",
- SdoSeqConHdl_p, (WORD) pAsySdoCom_p->m_le_abCommandData[0],
+ SdoSeqConHdl_p, (u16) pAsySdoCom_p->m_le_abCommandData[0],
uiDataSize_p);
return Ret;
@@ -840,8 +839,8 @@ tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
- tEplAsySdoConState AsySdoConState_p)
+tEplKernel EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
+ tEplAsySdoConState AsySdoConState_p)
{
tEplKernel Ret;
tEplSdoComConEvent SdoComConEvent = kEplSdoComConEventSendFirst;
@@ -999,10 +998,10 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
{
tEplKernel Ret;
tEplSdoComCon *pSdoComCon;
- BYTE bFlag;
+ u8 bFlag;
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
- DWORD dwAbortCode;
+ u32 dwAbortCode;
unsigned int uiSize;
#endif
@@ -1138,7 +1137,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
pSdoComCon->
m_pData
=
- (BYTE
+ (u8
*)
&
dwAbortCode;
@@ -1283,7 +1282,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
if (pSdoComCon->
m_dwLastAbortCode ==
0) {
- ( /*(BYTE*) */
+ ( /*(u8*) */
pSdoComCon->
m_pData) +=
uiSize;
@@ -1321,7 +1320,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
pSdoComCon->
m_pData
=
- (BYTE
+ (u8
*)
&
pSdoComCon->
@@ -1667,7 +1666,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
case kEplSdoComConEventAbort:
{
EplSdoComClientSendAbort(pSdoComCon,
- *((DWORD *)
+ *((u32 *)
pSdoComCon->
m_pData));
@@ -1675,7 +1674,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
pSdoComCon->m_bTransactionId++;
// call callback of application
pSdoComCon->m_dwLastAbortCode =
- *((DWORD *) pSdoComCon->m_pData);
+ *((u32 *) pSdoComCon->m_pData);
Ret =
EplSdoComTransferFinished
(SdoComCon_p, pSdoComCon,
@@ -1869,7 +1868,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
case kEplSdoComConEventAbort:
{
EplSdoComClientSendAbort(pSdoComCon,
- *((DWORD *)
+ *((u32 *)
pSdoComCon->
m_pData));
@@ -1880,7 +1879,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
kEplSdoComStateClientConnected;
// call callback of application
pSdoComCon->m_dwLastAbortCode =
- *((DWORD *) pSdoComCon->m_pData);
+ *((u32 *) pSdoComCon->m_pData);
Ret =
EplSdoComTransferFinished
(SdoComCon_p, pSdoComCon,
@@ -1965,7 +1964,7 @@ static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
unsigned int uiSubindex;
tEplObdSize EntrySize;
tEplObdAccess AccessType;
- DWORD dwAbortCode;
+ u32 dwAbortCode;
dwAbortCode = 0;
@@ -1987,7 +1986,7 @@ static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
if (Ret == kEplObdSubindexNotExist) { // subentry doesn't exist
dwAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
// send abort
- pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
+ pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -1996,7 +1995,7 @@ static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
} else if (Ret != kEplSuccessful) { // entry doesn't exist
dwAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
// send abort
- pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
+ pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2014,7 +2013,7 @@ static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
dwAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS;
}
// send abort
- pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
+ pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2051,7 +2050,7 @@ static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
// error -> abort
dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
// send abort
- pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
+ pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2090,11 +2089,11 @@ static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
tEplSdoComSendType SendType_p)
{
tEplKernel Ret;
- BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
+ u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
tEplFrame *pFrame;
tEplAsySdoCom *pCommandFrame;
unsigned int uiSizeOfFrame;
- BYTE bFlag;
+ u8 bFlag;
Ret = kEplSuccessful;
@@ -2167,7 +2166,7 @@ static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
// set size of frame
AmiSetWordToLe(&pCommandFrame->
m_le_wSegmentSize,
- (WORD) pSdoComCon_p->
+ (u16) pSdoComCon_p->
m_uiTransSize);
// correct byte-counter
@@ -2297,7 +2296,7 @@ static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
// set segment size
AmiSetWordToLe(&pCommandFrame->
m_le_wSegmentSize,
- (WORD) pSdoComCon_p->
+ (u16) pSdoComCon_p->
m_uiTransSize);
// send frame
@@ -2324,18 +2323,18 @@ static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
// copy abortcode to frame
AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0],
- *((DWORD *) pSdoComCon_p->m_pData));
+ *((u32 *) pSdoComCon_p->m_pData));
// set size of segment
AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize,
- sizeof(DWORD));
+ sizeof(u32));
// update counter
- pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
+ pSdoComCon_p->m_uiTransferredByte = sizeof(u32);
pSdoComCon_p->m_uiTransSize = 0;
// calc framesize
- uiSizeOfFrame += sizeof(DWORD);
+ uiSizeOfFrame += sizeof(u32);
Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
uiSizeOfFrame, pFrame);
break;
@@ -2373,8 +2372,8 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
unsigned int uiBytesToTransfer;
tEplObdSize EntrySize;
tEplObdAccess AccessType;
- DWORD dwAbortCode;
- BYTE *pbSrcData;
+ u32 dwAbortCode;
+ u8 *pbSrcData;
dwAbortCode = 0;
@@ -2427,7 +2426,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
// send abort
// d.k. This is wrong: k.t. not needed send abort on end of write
- /*pSdoComCon_p->m_pData = (BYTE*)pSdoComCon_p->m_dwLastAbortCode;
+ /*pSdoComCon_p->m_pData = (u8*)pSdoComCon_p->m_dwLastAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2438,7 +2437,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
// send abort
// d.k. This is wrong: k.t. not needed send abort on end of write
/*
- pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+ pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2458,7 +2457,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
}
// send abort
// d.k. This is wrong: k.t. not needed send abort on end of write
- /*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+ /*pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2549,7 +2548,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
// send abort
// d.k. This is wrong: k.t. not needed send abort on end of write
- /*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+ /*pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2571,7 +2570,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
EPL_SDOAC_GENERAL_ERROR;
// send abort
// d.k. This is wrong: k.t. not needed send abort on end of write
-/* pSdoComCon_p->m_pData = (BYTE*)&pSdoComCon_p->m_dwLastAbortCode;
+/* pSdoComCon_p->m_pData = (u8*)&pSdoComCon_p->m_dwLastAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2586,7 +2585,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
pSdoComCon_p->m_uiTransSize -= uiBytesToTransfer;
// update target pointer
- ( /*(BYTE*) */ pSdoComCon_p->m_pData) += uiBytesToTransfer;
+ ( /*(u8*) */ pSdoComCon_p->m_pData) += uiBytesToTransfer;
// send acknowledge without any Command layer data
Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
@@ -2598,7 +2597,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
if (pSdoComCon_p->m_dwLastAbortCode != 0) {
// send abort
pSdoComCon_p->m_pData =
- (BYTE *) & pSdoComCon_p->m_dwLastAbortCode;
+ (u8 *) & pSdoComCon_p->m_dwLastAbortCode;
Ret =
EplSdoComServerSendFrameIntern(pSdoComCon_p, uiIndex,
uiSubindex,
@@ -2635,12 +2634,12 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
{
tEplKernel Ret;
- BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
+ u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
tEplFrame *pFrame;
tEplAsySdoCom *pCommandFrame;
unsigned int uiSizeOfFrame;
- BYTE bFlags;
- BYTE *pbPayload;
+ u8 bFlags;
+ u8 *pbPayload;
Ret = kEplSuccessful;
@@ -2680,11 +2679,11 @@ static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
// create command header
AmiSetWordToLe(pbPayload,
- (WORD) pSdoComCon_p->
+ (u16) pSdoComCon_p->
m_uiTargetIndex);
pbPayload += 2;
AmiSetByteToLe(pbPayload,
- (BYTE) pSdoComCon_p->
+ (u8) pSdoComCon_p->
m_uiTargetSubIndex);
// calc size
uiSizeOfFrame += 4;
@@ -2721,12 +2720,12 @@ static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
bFlags);
// create command header
AmiSetWordToLe(pbPayload,
- (WORD)
+ (u16)
pSdoComCon_p->
m_uiTargetIndex);
pbPayload += 2;
AmiSetByteToLe(pbPayload,
- (BYTE)
+ (u8)
pSdoComCon_p->
m_uiTargetSubIndex);
// on byte for reserved
@@ -2760,12 +2759,12 @@ static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
// create command header
AmiSetWordToLe(pbPayload,
- (WORD)
+ (u16)
pSdoComCon_p->
m_uiTargetIndex);
pbPayload += 2;
AmiSetByteToLe(pbPayload,
- (BYTE)
+ (u8)
pSdoComCon_p->
m_uiTargetSubIndex);
// + 2 -> one byte for subindex and one byte reserved
@@ -2784,7 +2783,7 @@ static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
// fill rest of header
AmiSetWordToLe(&pCommandFrame->
m_le_wSegmentSize,
- (WORD) (4 +
+ (u16) (4 +
pSdoComCon_p->
m_uiTransSize));
@@ -2855,7 +2854,7 @@ static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
AmiSetWordToLe
(&pCommandFrame->
m_le_wSegmentSize,
- (WORD)
+ (u16)
pSdoComCon_p->
m_uiTransSize);
bFlags = 0x30;
@@ -2944,7 +2943,7 @@ static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
tEplAsySdoCom * pAsySdoCom_p)
{
tEplKernel Ret;
- BYTE bBuffer;
+ u8 bBuffer;
unsigned int uiBuffer;
unsigned int uiDataSize;
unsigned long ulBuffer;
@@ -3217,10 +3216,10 @@ static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
- DWORD dwAbortCode_p)
+ u32 dwAbortCode_p)
{
tEplKernel Ret;
- BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
+ u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
tEplFrame *pFrame;
tEplAsySdoCom *pCommandFrame;
unsigned int uiSizeOfFrame;
@@ -3250,14 +3249,14 @@ static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], dwAbortCode_p);
// set size of segment
- AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(DWORD));
+ AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(u32));
// update counter
- pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
+ pSdoComCon_p->m_uiTransferredByte = sizeof(u32);
pSdoComCon_p->m_uiTransSize = 0;
// calc framesize
- uiSizeOfFrame += sizeof(DWORD);
+ uiSizeOfFrame += sizeof(u32);
// save abort code
pSdoComCon_p->m_dwLastAbortCode = dwAbortCode_p;
diff --git a/drivers/staging/epl/EplSdoUdpu.c b/drivers/staging/epl/EplSdoUdpu.c
index be52233b3ee..b409c9b7be4 100644
--- a/drivers/staging/epl/EplSdoUdpu.c
+++ b/drivers/staging/epl/EplSdoUdpu.c
@@ -72,11 +72,9 @@
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
#include "SocketLinuxKernel.h"
#include <linux/completion.h>
#include <linux/sched.h>
-#endif
/***************************************************************************/
/* */
@@ -110,17 +108,9 @@ typedef struct {
tEplSequLayerReceiveCb m_fpSdoAsySeqCb;
SOCKET m_UdpSocket;
-#if (TARGET_SYSTEM == _WIN32_)
- HANDLE m_ThreadHandle;
- LPCRITICAL_SECTION m_pCriticalSection;
- CRITICAL_SECTION m_CriticalSection;
-
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
struct completion m_CompletionUdpThread;
int m_ThreadHandle;
int m_iTerminateThread;
-#endif
-
} tEplSdoUdpInstance;
//---------------------------------------------------------------------------
@@ -133,12 +123,7 @@ static tEplSdoUdpInstance SdoUdpInstance_g;
// local function prototypes
//---------------------------------------------------------------------------
-#if (TARGET_SYSTEM == _WIN32_)
-static DWORD PUBLIC EplSdoUdpThread(LPVOID lpParameter);
-
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
static int EplSdoUdpThread(void *pArg_p);
-#endif
/***************************************************************************/
/* */
@@ -177,7 +162,7 @@ static int EplSdoUdpThread(void *pArg_p);
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
+tEplKernel EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
{
tEplKernel Ret;
@@ -205,16 +190,10 @@ tEplKernel PUBLIC EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
+tEplKernel EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
{
tEplKernel Ret;
-#if (TARGET_SYSTEM == _WIN32_)
- int iError;
- WSADATA Wsa;
-
-#endif
-
// set instance variables to 0
EPL_MEMSET(&SdoUdpInstance_g, 0x00, sizeof(SdoUdpInstance_g));
@@ -228,24 +207,8 @@ tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
goto Exit;
}
-#if (TARGET_SYSTEM == _WIN32_)
- // start winsock2 for win32
- // windows specific start of socket
- iError = WSAStartup(MAKEWORD(2, 0), &Wsa);
- if (iError != 0) {
- Ret = kEplSdoUdpNoSocket;
- goto Exit;
- }
- // create critical section for acccess of instnace variables
- SdoUdpInstance_g.m_pCriticalSection =
- &SdoUdpInstance_g.m_CriticalSection;
- InitializeCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
-
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
init_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
SdoUdpInstance_g.m_iTerminateThread = 0;
-#endif
-
SdoUdpInstance_g.m_ThreadHandle = 0;
SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
@@ -273,32 +236,18 @@ tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuDelInstance()
+tEplKernel EplSdoUdpuDelInstance(void)
{
tEplKernel Ret;
-#if (TARGET_SYSTEM == _WIN32_)
- BOOL fTermError;
-#endif
-
Ret = kEplSuccessful;
if (SdoUdpInstance_g.m_ThreadHandle != 0) { // listen thread was started
// close thread
-#if (TARGET_SYSTEM == _WIN32_)
- fTermError =
- TerminateThread(SdoUdpInstance_g.m_ThreadHandle, 0);
- if (fTermError == FALSE) {
- Ret = kEplSdoUdpThreadError;
- goto Exit;
- }
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
SdoUdpInstance_g.m_iTerminateThread = 1;
/* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
-#endif
-
SdoUdpInstance_g.m_ThreadHandle = 0;
}
@@ -307,19 +256,6 @@ tEplKernel PUBLIC EplSdoUdpuDelInstance()
closesocket(SdoUdpInstance_g.m_UdpSocket);
SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
}
-#if (TARGET_SYSTEM == _WIN32_)
- // delete critical section
- DeleteCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
-#endif
-
-#if (TARGET_SYSTEM == _WIN32_)
- // for win 32
- WSACleanup();
-#endif
-
-#if (TARGET_SYSTEM == _WIN32_)
- Exit:
-#endif
return Ret;
}
@@ -340,18 +276,12 @@ tEplKernel PUBLIC EplSdoUdpuDelInstance()
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
- unsigned int uiPort_p)
+tEplKernel EplSdoUdpuConfig(unsigned long ulIpAddr_p, unsigned int uiPort_p)
{
tEplKernel Ret;
struct sockaddr_in Addr;
int iError;
-#if (TARGET_SYSTEM == _WIN32_)
- BOOL fTermError;
- unsigned long ulThreadId;
-#endif
-
Ret = kEplSuccessful;
if (uiPort_p == 0) { // set UDP port to default port number
@@ -364,21 +294,11 @@ tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
if (SdoUdpInstance_g.m_ThreadHandle != 0) { // listen thread was started
// close old thread
-#if (TARGET_SYSTEM == _WIN32_)
- fTermError =
- TerminateThread(SdoUdpInstance_g.m_ThreadHandle, 0);
- if (fTermError == FALSE) {
- Ret = kEplSdoUdpThreadError;
- goto Exit;
- }
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
SdoUdpInstance_g.m_iTerminateThread = 1;
/* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
SdoUdpInstance_g.m_iTerminateThread = 0;
-#endif
-
SdoUdpInstance_g.m_ThreadHandle = 0;
}
@@ -413,28 +333,12 @@ tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
goto Exit;
}
// create Listen-Thread
-#if (TARGET_SYSTEM == _WIN32_)
- // for win32
-
- // create thread
- SdoUdpInstance_g.m_ThreadHandle = CreateThread(NULL,
- 0,
- EplSdoUdpThread,
- &SdoUdpInstance_g,
- 0, &ulThreadId);
- if (SdoUdpInstance_g.m_ThreadHandle == NULL) {
- Ret = kEplSdoUdpThreadError;
- goto Exit;
- }
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
-
SdoUdpInstance_g.m_ThreadHandle =
kernel_thread(EplSdoUdpThread, &SdoUdpInstance_g, CLONE_KERNEL);
if (SdoUdpInstance_g.m_ThreadHandle == 0) {
Ret = kEplSdoUdpThreadError;
goto Exit;
}
-#endif
Exit:
return Ret;
@@ -459,8 +363,8 @@ tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuInitCon(tEplSdoConHdl * pSdoConHandle_p,
- unsigned int uiTargetNodeId_p)
+tEplKernel EplSdoUdpuInitCon(tEplSdoConHdl *pSdoConHandle_p,
+ unsigned int uiTargetNodeId_p)
{
tEplKernel Ret;
unsigned int uiCount;
@@ -526,8 +430,8 @@ tEplKernel PUBLIC EplSdoUdpuInitCon(tEplSdoConHdl * pSdoConHandle_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
- tEplFrame * pSrcData_p, DWORD dwDataSize_p)
+tEplKernel EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
+ tEplFrame *pSrcData_p, u32 dwDataSize_p)
{
tEplKernel Ret;
int iError;
@@ -553,22 +457,12 @@ tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
// call sendto
Addr.sin_family = AF_INET;
-#if (TARGET_SYSTEM == _WIN32_)
- // enter critical section for process function
- EnterCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
-#endif
-
Addr.sin_port =
(unsigned short)SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].
m_uiPort;
Addr.sin_addr.s_addr =
SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr;
-#if (TARGET_SYSTEM == _WIN32_)
- // leave critical section for process function
- LeaveCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
-#endif
-
iError = sendto(SdoUdpInstance_g.m_UdpSocket, // sockethandle
(const char *)&pSrcData_p->m_le_bMessageType, // data to send
dwDataSize_p, // number of bytes to send
@@ -603,7 +497,7 @@ tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
+tEplKernel EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
{
tEplKernel Ret;
unsigned int uiArray;
@@ -642,17 +536,13 @@ tEplKernel PUBLIC EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
// Parameters: lpParameter = pointer to parameter type tEplSdoUdpThreadPara
//
//
-// Returns: DWORD = errorcode
+// Returns: u32 = errorcode
//
//
// State:
//
//---------------------------------------------------------------------------
-#if (TARGET_SYSTEM == _WIN32_)
-static DWORD PUBLIC EplSdoUdpThread(LPVOID lpParameter)
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
static int EplSdoUdpThread(void *pArg_p)
-#endif
{
tEplSdoUdpInstance *pInstance;
@@ -660,21 +550,15 @@ static int EplSdoUdpThread(void *pArg_p)
int iError;
int iCount;
int iFreeEntry;
- BYTE abBuffer[EPL_MAX_SDO_REC_FRAME_SIZE];
+ u8 abBuffer[EPL_MAX_SDO_REC_FRAME_SIZE];
unsigned int uiSize;
tEplSdoConHdl SdoConHdl;
-#if (TARGET_SYSTEM == _WIN32_)
- pInstance = (tEplSdoUdpInstance *) lpParameter;
-
- for (;;)
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
pInstance = (tEplSdoUdpInstance *) pArg_p;
daemonize("EplSdoUdpThread");
allow_signal(SIGTERM);
for (; pInstance->m_iTerminateThread == 0;)
-#endif
{
// wait for data
@@ -685,20 +569,13 @@ static int EplSdoUdpThread(void *pArg_p)
0, // flags
(struct sockaddr *)&RemoteAddr,
(int *)&uiSize);
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
if (iError == -ERESTARTSYS) {
break;
}
-#endif
if (iError > 0) {
// get handle for higher layer
iCount = 0;
iFreeEntry = 0xFFFF;
-#if (TARGET_SYSTEM == _WIN32_)
- // enter critical section for process function
- EnterCriticalSection(SdoUdpInstance_g.
- m_pCriticalSection);
-#endif
while (iCount < EPL_SDO_MAX_CONNECTION_UDP) {
// check if this connection is already known
if ((pInstance->m_aSdoAbsUdpConnection[iCount].
@@ -734,11 +611,6 @@ static int EplSdoUdpThread(void *pArg_p)
pInstance->
m_aSdoAbsUdpConnection[iFreeEntry].
m_uiPort = RemoteAddr.sin_port;
-#if (TARGET_SYSTEM == _WIN32_)
- // leave critical section for process function
- LeaveCriticalSection(SdoUdpInstance_g.
- m_pCriticalSection);
-#endif
// call callback
SdoConHdl = iFreeEntry;
SdoConHdl |= EPL_SDO_UDP_HANDLE;
@@ -752,11 +624,6 @@ static int EplSdoUdpThread(void *pArg_p)
} else {
EPL_DBGLVL_SDO_TRACE0
("Error in EplSdoUdpThread() no free handle\n");
-#if (TARGET_SYSTEM == _WIN32_)
- // leave critical section for process function
- LeaveCriticalSection(SdoUdpInstance_g.
- m_pCriticalSection);
-#endif
}
} else {
@@ -764,11 +631,6 @@ static int EplSdoUdpThread(void *pArg_p)
// call callback with correct handle
SdoConHdl = iCount;
SdoConHdl |= EPL_SDO_UDP_HANDLE;
-#if (TARGET_SYSTEM == _WIN32_)
- // leave critical section for process function
- LeaveCriticalSection(SdoUdpInstance_g.
- m_pCriticalSection);
-#endif
// offset 4 -> start of SDO Sequence header
pInstance->m_fpSdoAsySeqCb(SdoConHdl,
(tEplAsySdoSeq *) &
@@ -778,10 +640,7 @@ static int EplSdoUdpThread(void *pArg_p)
} // end of if(iError!=SOCKET_ERROR)
} // end of for(;;)
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
complete_and_exit(&SdoUdpInstance_g.m_CompletionUdpThread, 0);
-#endif
-
return 0;
}
diff --git a/drivers/staging/epl/EplStatusu.c b/drivers/staging/epl/EplStatusu.c
index 689f9124ae2..b291399af10 100644
--- a/drivers/staging/epl/EplStatusu.c
+++ b/drivers/staging/epl/EplStatusu.c
@@ -137,8 +137,7 @@ static tEplStatusuInstance EplStatusuInstance_g;
// local function prototypes
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplStatusuCbStatusResponse(tEplFrameInfo *
- pFrameInfo_p);
+static tEplKernel EplStatusuCbStatusResponse(tEplFrameInfo *pFrameInfo_p);
//=========================================================================//
// //
@@ -164,7 +163,7 @@ static tEplKernel PUBLIC EplStatusuCbStatusResponse(tEplFrameInfo *
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplStatusuInit()
+tEplKernel EplStatusuInit(void)
{
tEplKernel Ret;
@@ -191,7 +190,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplStatusuInit()
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplStatusuAddInstance()
+tEplKernel EplStatusuAddInstance(void)
{
tEplKernel Ret;
@@ -228,7 +227,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplStatusuAddInstance()
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplStatusuDelInstance()
+tEplKernel EplStatusuDelInstance(void)
{
tEplKernel Ret;
@@ -258,7 +257,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplStatusuDelInstance()
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplStatusuReset()
+tEplKernel EplStatusuReset(void)
{
tEplKernel Ret;
@@ -287,9 +286,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplStatusuReset()
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
- tEplStatusuCbResponse
- pfnCbResponse_p)
+tEplKernel EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
+ tEplStatusuCbResponse pfnCbResponse_p)
{
tEplKernel Ret;
@@ -342,8 +340,7 @@ tEplKernel PUBLIC EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
// State:
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplStatusuCbStatusResponse(tEplFrameInfo *
- pFrameInfo_p)
+static tEplKernel EplStatusuCbStatusResponse(tEplFrameInfo *pFrameInfo_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiNodeId;
diff --git a/drivers/staging/epl/EplTarget.h b/drivers/staging/epl/EplTarget.h
index b2b66f82c03..e76d21ff9d9 100644
--- a/drivers/staging/epl/EplTarget.h
+++ b/drivers/staging/epl/EplTarget.h
@@ -83,95 +83,11 @@
// applications needs to use one common library function (e.g. memcpy()). So
// you can set (or change) it here.
-#if (TARGET_SYSTEM == _WIN32_)
-
-#define _WIN32_WINDOWS 0x0401
-#define _WIN32_WINNT 0x0400
-
-#include <stdlib.h>
-#include <stdio.h>
-
- //29.11.2004 f.j. sonst ist memcpy und memset unbekannt
-#include <string.h>
-
-#define EPL_MEMCPY(dst,src,siz) memcpy((void*)(dst),(const void*)(src),(size_t)(siz));
-#define EPL_MEMSET(dst,val,siz) memset((void*)(dst),(int)(val),(size_t)(siz));
-
- // f.j.: die Funktionen für <MemAlloc> und <MemFree> sind in WinMem.c definiert
- //definition der Prototypen
-void FAR *MemAlloc(DWORD dwMemSize_p);
-void MemFree(void FAR * pMem_p);
-
-#define EPL_MALLOC(siz) malloc((size_t)(siz))
-#define EPL_FREE(ptr) free((void *)ptr)
-
-#ifndef PRINTF0
-void trace(const char *fmt, ...);
-#define PRINTF TRACE
-#define PRINTF0(arg) TRACE0(arg)
-#define PRINTF1(arg,p1) TRACE1(arg,p1)
-#define PRINTF2(arg,p1,p2) TRACE2(arg,p1,p2)
-#define PRINTF3(arg,p1,p2,p3) TRACE3(arg,p1,p2,p3)
-#define PRINTF4(arg,p1,p2,p3,p4) TRACE4(arg,p1,p2,p3,p4)
- //#define PRINTF printf
- //#define PRINTF0(arg) PRINTF(arg)
- //#define PRINTF1(arg,p1) PRINTF(arg,p1)
- //#define PRINTF2(arg,p1,p2) PRINTF(arg,p1,p2)
- //#define PRINTF3(arg,p1,p2,p3) PRINTF(arg,p1,p2,p3)
- //#define PRINTF4(arg,p1,p2,p3,p4) PRINTF(arg,p1,p2,p3,p4)
-#endif
-
-#ifdef ASSERTMSG
-#undef ASSERTMSG
-#endif
-
-#define ASSERTMSG(expr,string) if (!(expr)) { \
- MessageBox (NULL, string, "Assertion failed", MB_OK | MB_ICONERROR); \
- exit (-1);}
-
-#elif (TARGET_SYSTEM == _NO_OS_)
-
-#include <stdlib.h>
-#include <stdio.h>
-
- //29.11.2004 f.j. sonst ist memcpy und memset unbekannt
-// #include <string.h>
-
-#define EPL_MEMCPY(dst,src,siz) memcpy((void*)(dst),(const void*)(src),(size_t)(siz));
-#define EPL_MEMSET(dst,val,siz) memset((void*)(dst),(int)(val),(size_t)(siz));
-
-#define EPL_MALLOC(siz) malloc((size_t)(siz))
-#define EPL_FREE(ptr) free((void *)ptr)
-
-#ifndef PRINTF0
-#define PRINTF TRACE
-#define PRINTF0(arg) TRACE0(arg)
-#define PRINTF1(arg,p1) TRACE1(arg,p1)
-#define PRINTF2(arg,p1,p2) TRACE2(arg,p1,p2)
-#define PRINTF3(arg,p1,p2,p3) TRACE3(arg,p1,p2,p3)
-#define PRINTF4(arg,p1,p2,p3,p4) TRACE4(arg,p1,p2,p3,p4)
- //#define PRINTF printf
- //#define PRINTF0(arg) PRINTF(arg)
- //#define PRINTF1(arg,p1) PRINTF(arg,p1)
- //#define PRINTF2(arg,p1,p2) PRINTF(arg,p1,p2)
- //#define PRINTF3(arg,p1,p2,p3) PRINTF(arg,p1,p2,p3)
- //#define PRINTF4(arg,p1,p2,p3,p4) PRINTF(arg,p1,p2,p3,p4)
-#endif
-
-#elif (TARGET_SYSTEM == _LINUX_)
-
-#ifndef __KERNEL__
-#include <stdlib.h>
-#include <stdio.h>
-#else
-// #include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/major.h>
-#include <linux/version.h>
-#endif
//29.11.2004 f.j. sonst ist memcpy und memset unbekannt
// #include <string.h>
@@ -179,13 +95,8 @@ void trace(const char *fmt, ...);
#define EPL_MEMCPY(dst,src,siz) memcpy((void*)(dst),(const void*)(src),(size_t)(siz));
#define EPL_MEMSET(dst,val,siz) memset((void*)(dst),(int)(val),(size_t)(siz));
-#ifndef __KERNEL__
-#define EPL_MALLOC(siz) malloc((size_t)(siz))
-#define EPL_FREE(ptr) free((void *)ptr)
-#else
#define EPL_MALLOC(siz) kmalloc((size_t)(siz), GFP_KERNEL)
#define EPL_FREE(ptr) kfree((void *)ptr)
-#endif
#ifndef PRINTF0
#define PRINTF TRACE
@@ -202,8 +113,6 @@ void trace(const char *fmt, ...);
//#define PRINTF4(arg,p1,p2,p3,p4) PRINTF(arg,p1,p2,p3,p4)
#endif
-#endif
-
#define EPL_TGT_INTMASK_ETH 0x0001 // ethernet interrupt
#define EPL_TGT_INTMASK_DMA 0x0002 // DMA interrupt
@@ -217,17 +126,15 @@ void trace(const char *fmt, ...);
// currently no Timer functions are needed by EPL stack
// so they are not implemented yet
-//void PUBLIC TgtTimerInit(void);
-//DWORD PUBLIC TgtGetTickCount(void);
-//void PUBLIC TgtGetNetTime(tEplNetTime * pNetTime_p);
+//void TgtTimerInit(void);
+//u32 TgtGetTickCount(void);
+//void TgtGetNetTime(tEplNetTime * pNetTime_p);
// functions for ethernet driver
-tEplKernel PUBLIC TgtInitEthIsr(void);
-void PUBLIC TgtFreeEthIsr(void);
-void PUBLIC TgtEnableGlobalInterrupt(BYTE fEnable_p);
-void PUBLIC TgtEnableEthInterrupt0(BYTE fEnable_p,
- unsigned int uiInterruptMask_p);
-void PUBLIC TgtEnableEthInterrupt1(BYTE fEnable_p,
- unsigned int uiInterruptMask_p);
+tEplKernel TgtInitEthIsr(void);
+void TgtFreeEthIsr(void);
+void TgtEnableGlobalInterrupt(u8 fEnable_p);
+void TgtEnableEthInterrupt0(u8 fEnable_p, unsigned int uiInterruptMask_p);
+void TgtEnableEthInterrupt1(u8 fEnable_p, unsigned int uiInterruptMask_p);
#endif // #ifndef _EPLTARGET_H_
diff --git a/drivers/staging/epl/EplTimer.h b/drivers/staging/epl/EplTimer.h
index facbfd8740e..d1a73eaf65c 100644
--- a/drivers/staging/epl/EplTimer.h
+++ b/drivers/staging/epl/EplTimer.h
@@ -107,8 +107,7 @@ typedef struct {
} tEplTimerEventArg;
-typedef tEplKernel(PUBLIC * tEplTimerkCallback) (tEplTimerEventArg *
- pEventArg_p);
+typedef tEplKernel(* tEplTimerkCallback) (tEplTimerEventArg *pEventArg_p);
//---------------------------------------------------------------------------
// function prototypes
diff --git a/drivers/staging/epl/EplTimeruLinuxKernel.c b/drivers/staging/epl/EplTimeruLinuxKernel.c
index 08820d18405..ff80fc80d02 100644
--- a/drivers/staging/epl/EplTimeruLinuxKernel.c
+++ b/drivers/staging/epl/EplTimeruLinuxKernel.c
@@ -99,7 +99,7 @@ typedef struct {
//---------------------------------------------------------------------------
// local function prototypes
//---------------------------------------------------------------------------
-static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p);
+static void EplTimeruCbMs(unsigned long ulParameter_p);
/***************************************************************************/
/* */
@@ -134,7 +134,7 @@ static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p);
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruInit()
+tEplKernel EplTimeruInit(void)
{
tEplKernel Ret;
@@ -157,7 +157,7 @@ tEplKernel PUBLIC EplTimeruInit()
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruAddInstance()
+tEplKernel EplTimeruAddInstance(void)
{
tEplKernel Ret;
@@ -182,7 +182,7 @@ tEplKernel PUBLIC EplTimeruAddInstance()
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDelInstance()
+tEplKernel EplTimeruDelInstance(void)
{
tEplKernel Ret;
@@ -207,9 +207,9 @@ tEplKernel PUBLIC EplTimeruDelInstance()
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p)
+tEplKernel EplTimeruSetTimerMs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long ulTime_p,
+ tEplTimerArg Argument_p)
{
tEplKernel Ret = kEplSuccessful;
tEplTimeruData *pData;
@@ -257,9 +257,9 @@ tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p)
+tEplKernel EplTimeruModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long ulTime_p,
+ tEplTimerArg Argument_p)
{
tEplKernel Ret = kEplSuccessful;
tEplTimeruData *pData;
@@ -315,7 +315,7 @@ tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
+tEplKernel EplTimeruDeleteTimer(tEplTimerHdl *pTimerHdl_p)
{
tEplKernel Ret = kEplSuccessful;
tEplTimeruData *pData;
@@ -370,7 +370,7 @@ tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
//
//---------------------------------------------------------------------------
-BOOL PUBLIC EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
+BOOL EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
{
BOOL fActive = FALSE;
tEplTimeruData *pData;
@@ -417,7 +417,7 @@ BOOL PUBLIC EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
// State:
//
//---------------------------------------------------------------------------
-static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p)
+static void EplTimeruCbMs(unsigned long ulParameter_p)
{
tEplKernel Ret = kEplSuccessful;
tEplTimeruData *pData;
diff --git a/drivers/staging/epl/EplTimeruNull.c b/drivers/staging/epl/EplTimeruNull.c
deleted file mode 100644
index 40ce403cbd0..00000000000
--- a/drivers/staging/epl/EplTimeruNull.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: openPOWERLINK
-
- Description: source file for Epl Userspace-Timermodule NULL-Implementation
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS 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.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- $RCSfile: EplTimeruNull.c,v $
-
- $Author: D.Krueger $
-
- $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $
-
- $State: Exp $
-
- Build Environment:
- KEIL uVision 2
-
- -------------------------------------------------------------------------
-
- Revision History:
-
- 2006/07/06 k.t.: start of the implementation
-
-****************************************************************************/
-
-#include "user/EplTimeru.h"
-
-/***************************************************************************/
-/* */
-/* */
-/* G L O B A L D E F I N I T I O N S */
-/* */
-/* */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-/***************************************************************************/
-/* */
-/* */
-/* C L A S S <Epl Userspace-Timermodule NULL-Implementation> */
-/* */
-/* */
-/***************************************************************************/
-//
-// Description: Epl Userspace-Timermodule NULL-Implementation
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-// //
-// P U B L I C F U N C T I O N S //
-// //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruInit
-//
-// Description: function init first instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruInit()
-{
- tEplKernel Ret;
-
- Ret = EplTimeruAddInstance();
-
- return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruAddInstance
-//
-// Description: function init additional instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruAddInstance()
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruDelInstance
-//
-// Description: function delte instance
-// -> under Win32 nothing to do
-// -> no instnace table needed
-//
-//
-//
-// Parameters:
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDelInstance()
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruSetTimerMs
-//
-// Description: function create a timer and return a handle to the pointer
-//
-//
-//
-// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
-// ulTime_p = time for timer in ms
-// Argument_p = argument for timer
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p)
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- // check handle
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
-
- Exit:
- return Ret;
-}
-
- //---------------------------------------------------------------------------
-//
-// Function: EplTimeruModifyTimerMs
-//
-// Description: function change a timer and return a handle to the pointer
-//
-//
-//
-// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
-// ulTime_p = time for timer in ms
-// Argument_p = argument for timer
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p)
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- // check parameter
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
-
- Exit:
- return Ret;
-}
-
- //---------------------------------------------------------------------------
-//
-// Function: EplTimeruDeleteTimer
-//
-// Description: function delte a timer
-//
-//
-//
-// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- // check parameter
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
- // set handle invalide
- *pTimerHdl_p = 0;
-
- Exit:
- return Ret;
-
-}
-
-//=========================================================================//
-// //
-// P R I V A T E F U N C T I O N S //
-// //
-//=========================================================================//
-
-// EOF
diff --git a/drivers/staging/epl/EplTimeruWin32.c b/drivers/staging/epl/EplTimeruWin32.c
deleted file mode 100644
index a967b4e59d4..00000000000
--- a/drivers/staging/epl/EplTimeruWin32.c
+++ /dev/null
@@ -1,513 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: openPOWERLINK
-
- Description: source file for Epl Userspace-Timermodule for Win32
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS 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.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- $RCSfile: EplTimeruWin32.c,v $
-
- $Author: D.Krueger $
-
- $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $
-
- $State: Exp $
-
- Build Environment:
- GCC V3.4
-
- -------------------------------------------------------------------------
-
- Revision History:
-
- 2006/07/06 k.t.: start of the implementation
-
-****************************************************************************/
-
-#include "user/EplTimeru.h"
-
-/***************************************************************************/
-/* */
-/* */
-/* G L O B A L D E F I N I T I O N S */
-/* */
-/* */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-typedef struct {
- tEplTimerArg TimerArgument;
- HANDLE DelteHandle;
- unsigned long ulTimeout;
-
-} tEplTimeruThread;
-
-typedef struct {
- LPCRITICAL_SECTION m_pCriticalSection;
- CRITICAL_SECTION m_CriticalSection;
-} tEplTimeruInstance;
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-static tEplTimeruInstance EplTimeruInstance_g;
-static tEplTimeruThread ThreadData_l;
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter);
-
-/***************************************************************************/
-/* */
-/* */
-/* C L A S S <Epl Userspace-Timermodule for Win32> */
-/* */
-/* */
-/***************************************************************************/
-//
-// Description: Epl Userspace-Timermodule for Win32
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-// //
-// P U B L I C F U N C T I O N S //
-// //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruInit
-//
-// Description: function init first instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruInit()
-{
- tEplKernel Ret;
-
- Ret = EplTimeruAddInstance();
-
- return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruAddInstance
-//
-// Description: function init additional instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruAddInstance()
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- // create critical section
- EplTimeruInstance_g.m_pCriticalSection =
- &EplTimeruInstance_g.m_CriticalSection;
- InitializeCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
- return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruDelInstance
-//
-// Description: function delte instance
-// -> under Win32 nothing to do
-// -> no instnace table needed
-//
-//
-//
-// Parameters:
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDelInstance()
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruSetTimerMs
-//
-// Description: function create a timer and return a handle to the pointer
-//
-//
-//
-// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
-// ulTime_p = time for timer in ms
-// Argument_p = argument for timer
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p)
-{
- tEplKernel Ret;
- HANDLE DeleteHandle;
- HANDLE ThreadHandle;
- DWORD ThreadId;
-
- Ret = kEplSuccessful;
-
- // check handle
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
- // enter critical section
- EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
- // first create event to delete timer
- DeleteHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (DeleteHandle == NULL) {
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
- // set handle for caller
- *pTimerHdl_p = (tEplTimerHdl) DeleteHandle;
-
- // fill data for thread
- ThreadData_l.DelteHandle = DeleteHandle;
- EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p,
- sizeof(tEplTimerArg));
- ThreadData_l.ulTimeout = ulTime_p;
-
- // create thread to create waitable timer and wait for timer
- ThreadHandle = CreateThread(NULL,
- 0,
- EplSdoTimeruThreadms,
- &ThreadData_l, 0, &ThreadId);
- if (ThreadHandle == NULL) {
- // leave critical section
- LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
- // delte handle
- CloseHandle(DeleteHandle);
-
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
-
- Exit:
- return Ret;
-}
-
- //---------------------------------------------------------------------------
-//
-// Function: EplTimeruModifyTimerMs
-//
-// Description: function change a timer and return a handle to the pointer
-//
-//
-//
-// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
-// ulTime_p = time for timer in ms
-// Argument_p = argument for timer
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p)
-{
- tEplKernel Ret;
- HANDLE DeleteHandle;
- HANDLE ThreadHandle;
- DWORD ThreadId;
-
- Ret = kEplSuccessful;
-
- // check parameter
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
-
- DeleteHandle = (HANDLE) (*pTimerHdl_p);
-
- // set event to end timer task for this timer
- SetEvent(DeleteHandle);
-
- // create new timer
- // first create event to delete timer
- DeleteHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (DeleteHandle == NULL) {
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
- // set handle for caller
- *pTimerHdl_p = (tEplTimerHdl) DeleteHandle;
-
- // enter critical section
- EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
- // fill data for thread
- ThreadData_l.DelteHandle = DeleteHandle;
- EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p,
- sizeof(tEplTimerArg));
- ThreadData_l.ulTimeout = ulTime_p;
-
- // create thread to create waitable timer and wait for timer
- ThreadHandle = CreateThread(NULL,
- 0,
- EplSdoTimeruThreadms,
- &ThreadData_l, 0, &ThreadId);
- if (ThreadHandle == NULL) {
- // leave critical section
- LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
- // delte handle
-
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
-
- Exit:
- return Ret;
-}
-
- //---------------------------------------------------------------------------
-//
-// Function: EplTimeruDeleteTimer
-//
-// Description: function delte a timer
-//
-//
-//
-// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
-{
- tEplKernel Ret;
- HANDLE DeleteHandle;
-
- Ret = kEplSuccessful;
-
- // check parameter
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
-
- DeleteHandle = (HANDLE) (*pTimerHdl_p);
-
- // set event to end timer task for this timer
- SetEvent(DeleteHandle);
-
- // set handle invalide
- *pTimerHdl_p = 0;
-
- Exit:
- return Ret;
-
-}
-
-//=========================================================================//
-// //
-// P R I V A T E F U N C T I O N S //
-// //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function: EplSdoTimeruThreadms
-//
-// Description: function to process timer as thread
-//
-//
-//
-// Parameters: lpParameter = pointer to structur of type tEplTimeruThread
-//
-//
-// Returns: DWORD = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter)
-{
- tEplKernel Ret;
- tEplTimeruThread *pThreadData;
- HANDLE aHandles[2];
- BOOL fReturn;
- LARGE_INTEGER TimeoutTime;
- unsigned long ulEvent;
- tEplEvent EplEvent;
- tEplTimeruThread ThreadData;
- tEplTimerEventArg TimerEventArg;
-
- Ret = kEplSuccessful;
-
- // get pointer to data
- pThreadData = (tEplTimeruThread *) lpParameter;
- // copy thread data
- EPL_MEMCPY(&ThreadData, pThreadData, sizeof(ThreadData));
- pThreadData = &ThreadData;
-
- // leave critical section
- LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
- // create waitable timer
- aHandles[1] = CreateWaitableTimer(NULL, FALSE, NULL);
- if (aHandles[1] == NULL) {
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
- // set timer
- // set timeout interval -> needed to be negativ
- // -> because relative timeout
- // -> multiply by 10000 for 100 ns timebase of function
- TimeoutTime.QuadPart = (((long long)pThreadData->ulTimeout) * -10000);
- fReturn = SetWaitableTimer(aHandles[1],
- &TimeoutTime, 0, NULL, NULL, FALSE);
- if (fReturn == 0) {
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
- // save delte event handle in handle array
- aHandles[0] = pThreadData->DelteHandle;
-
- // wait for one of the events
- ulEvent = WaitForMultipleObjects(2, &aHandles[0], FALSE, INFINITE);
- if (ulEvent == WAIT_OBJECT_0) { // delte event
-
- // close handels
- CloseHandle(aHandles[1]);
- // terminate thread
- goto Exit;
- } else if (ulEvent == (WAIT_OBJECT_0 + 1)) { // timer event
- // call event function
- TimerEventArg.m_TimerHdl =
- (tEplTimerHdl) pThreadData->DelteHandle;
- TimerEventArg.m_ulArg = pThreadData->TimerArgument.m_ulArg;
-
- EplEvent.m_EventSink = pThreadData->TimerArgument.m_EventSink;
- EplEvent.m_EventType = kEplEventTypeTimer;
- EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime));
- EplEvent.m_pArg = &TimerEventArg;
- EplEvent.m_uiSize = sizeof(TimerEventArg);
-
- Ret = EplEventuPost(&EplEvent);
-
- // close handels
- CloseHandle(aHandles[1]);
- // terminate thread
- goto Exit;
-
- } else { // error
- ulEvent = GetLastError();
- TRACE1("Error in WaitForMultipleObjects Errorcode: 0x%x\n",
- ulEvent);
- // terminate thread
- goto Exit;
- }
-
- Exit:
- return Ret;
-}
-
-// EOF
diff --git a/drivers/staging/epl/SharedBuff.c b/drivers/staging/epl/SharedBuff.c
index 9fb09d6bc28..2b10c375f3e 100644
--- a/drivers/staging/epl/SharedBuff.c
+++ b/drivers/staging/epl/SharedBuff.c
@@ -85,14 +85,8 @@
#include "SharedBuff.h"
#include "ShbIpc.h"
-// d.k. Linux kernel modules needs other header files for memcpy()
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
#include <linux/string.h>
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
+#include <linux/kernel.h>
/***************************************************************************/
/* */
@@ -102,8 +96,6 @@
/* */
/***************************************************************************/
-#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// Configuration
//---------------------------------------------------------------------------
@@ -177,7 +169,7 @@ typedef struct {
// Get pointer to Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbCirBuff *ShbCirGetBuffer(tShbInstance pShbInstance_p)
+tShbCirBuff *ShbCirGetBuffer(tShbInstance pShbInstance_p)
{
tShbCirBuff *pShbCirBuff;
@@ -193,7 +185,7 @@ INLINE_FUNCTION tShbCirBuff *ShbCirGetBuffer(tShbInstance pShbInstance_p)
// Get pointer to Linear Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbLinBuff *ShbLinGetBuffer(tShbInstance pShbInstance_p)
+tShbLinBuff *ShbLinGetBuffer(tShbInstance pShbInstance_p)
{
tShbLinBuff *pShbLinBuff;
@@ -210,7 +202,6 @@ int ShbCirSignalHandlerNewData(tShbInstance pShbInstance_p);
void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p,
unsigned int fTimeOut_p);
-#endif
//=========================================================================//
// //
@@ -218,7 +209,6 @@ void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p,
// //
//=========================================================================//
-#if !defined(INLINE_ENABLED)
// not inlined external functions
//---------------------------------------------------------------------------
@@ -363,18 +353,13 @@ tShbError ShbCirReleaseBuffer(tShbInstance pShbInstance_p)
}
-#endif // !defined(INLINE_ENABLED)
-
-#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// Reset Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
- unsigned long ulTimeOut_p,
- tShbCirSigHndlrReset
- pfnSignalHandlerReset_p)
+tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
+ unsigned long ulTimeOut_p,
+ tShbCirSigHndlrReset pfnSignalHandlerReset_p)
{
tShbCirBuff *pShbCirBuff;
@@ -440,9 +425,9 @@ INLINE_FUNCTION tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
// Write data block to Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p,
- const void *pSrcDataBlock_p,
- unsigned long ulDataBlockSize_p)
+tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p,
+ const void *pSrcDataBlock_p,
+ unsigned long ulDataBlockSize_p)
{
tShbCirBuff *pShbCirBuff;
@@ -608,9 +593,9 @@ INLINE_FUNCTION tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p,
// Allocate block within the Circular Shared Buffer for chunk writing
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p,
- tShbCirChunk * pShbCirChunk_p,
- unsigned long ulDataBufferSize_p)
+tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p,
+ tShbCirChunk * pShbCirChunk_p,
+ unsigned long ulDataBufferSize_p)
{
tShbCirBuff *pShbCirBuff;
@@ -717,12 +702,11 @@ INLINE_FUNCTION tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p,
// Write data chunk into an allocated buffer of the Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p,
- tShbCirChunk * pShbCirChunk_p,
- const void *pSrcDataChunk_p,
- unsigned long ulDataChunkSize_p,
- unsigned int
- *pfBufferCompleted_p)
+tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p,
+ tShbCirChunk *pShbCirChunk_p,
+ const void *pSrcDataChunk_p,
+ unsigned long ulDataChunkSize_p,
+ unsigned int *pfBufferCompleted_p)
{
tShbCirBuff *pShbCirBuff;
@@ -857,10 +841,10 @@ INLINE_FUNCTION tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p,
// Read data block from Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p,
- void *pDstDataBlock_p,
- unsigned long ulRdBuffSize_p,
- unsigned long *pulDataBlockSize_p)
+tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p,
+ void *pDstDataBlock_p,
+ unsigned long ulRdBuffSize_p,
+ unsigned long *pulDataBlockSize_p)
{
tShbCirBuff *pShbCirBuff;
@@ -1009,9 +993,8 @@ INLINE_FUNCTION tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p,
// Get data size of next readable block from Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p,
- unsigned long
- *pulDataBlockSize_p)
+tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p,
+ unsigned long *pulDataBlockSize_p)
{
tShbCirBuff *pShbCirBuff;
@@ -1070,9 +1053,8 @@ INLINE_FUNCTION tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p,
// Get number of readable blocks from Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p,
- unsigned long
- *pulDataBlockCount_p)
+tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p,
+ unsigned long *pulDataBlockCount_p)
{
tShbCirBuff *pShbCirBuff;
@@ -1113,12 +1095,9 @@ INLINE_FUNCTION tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p,
// d.k.: new parameter priority as enum
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirSetSignalHandlerNewData(tShbInstance
- pShbInstance_p,
- tShbCirSigHndlrNewData
- pfnSignalHandlerNewData_p,
- tShbPriority
- ShbPriority_p)
+tShbError ShbCirSetSignalHandlerNewData(tShbInstance pShbInstance_p,
+ tShbCirSigHndlrNewData pfnSignalHandlerNewData_p,
+ tShbPriority ShbPriority_p)
{
tShbCirBuff *pShbCirBuff;
@@ -1165,10 +1144,6 @@ INLINE_FUNCTION tShbError ShbCirSetSignalHandlerNewData(tShbInstance
}
-#endif
-
-#if !defined(INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// DEBUG: Trace Circular Shared Buffer
//---------------------------------------------------------------------------
@@ -1413,18 +1388,13 @@ tShbError ShbLinReleaseBuffer(tShbInstance pShbInstance_p)
}
-#endif // !defined(INLINE_ENABLED)
-
-#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// Write data block to Linear Shared Buffer
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
- unsigned long ulDstBufferOffs_p,
- const void *pSrcDataBlock_p,
- unsigned long ulDataBlockSize_p)
+tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
+ unsigned long ulDstBufferOffs_p,
+ const void *pSrcDataBlock_p,
+ unsigned long ulDataBlockSize_p)
{
tShbLinBuff *pShbLinBuff;
@@ -1489,11 +1459,10 @@ INLINE_FUNCTION tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
//---------------------------------------------------------------------------
// Read data block from Linear Shared Buffer
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p,
- void *pDstDataBlock_p,
- unsigned long ulSrcBufferOffs_p,
- unsigned long ulDataBlockSize_p)
+tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p,
+ void *pDstDataBlock_p,
+ unsigned long ulSrcBufferOffs_p,
+ unsigned long ulDataBlockSize_p)
{
tShbLinBuff *pShbLinBuff;
@@ -1555,10 +1524,6 @@ INLINE_FUNCTION tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p,
}
-#endif
-
-#if !defined(INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// DEBUG: Trace Linear Shared Buffer
//---------------------------------------------------------------------------
@@ -1639,7 +1604,7 @@ tShbError ShbTraceDump(const unsigned char *pabStartAddr_p,
ulBuffSize = ulDataSize_p;
if (pszInfoText_p != NULL) {
- TRACE0(pszInfoText_p);
+ TRACE1("%s", pszInfoText_p);
}
// dump buffer contents
for (nRow = 0;; nRow++) {
@@ -1794,6 +1759,4 @@ void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p,
}
-#endif
-
// EOF
diff --git a/drivers/staging/epl/SharedBuff.h b/drivers/staging/epl/SharedBuff.h
index 0ec1b4b9e6a..4edbd0b2bd5 100644
--- a/drivers/staging/epl/SharedBuff.h
+++ b/drivers/staging/epl/SharedBuff.h
@@ -110,15 +110,6 @@ typedef void (*tShbCirSigHndlrReset) (tShbInstance pShbInstance_p,
extern "C" {
#endif
-/*#if defined(INLINE_FUNCTION_DEF)
- #undef INLINE_FUNCTION
- #define INLINE_FUNCTION INLINE_FUNCTION_DEF
- #define INLINE_ENABLED TRUE
- #define SHAREDBUFF_INLINED
- #include "SharedBuff.c"
-#endif
-*/
-
tShbError ShbInit(void);
tShbError ShbExit(void);
@@ -129,7 +120,6 @@ extern "C" {
unsigned int *pfShbNewCreated_p);
tShbError ShbCirReleaseBuffer(tShbInstance pShbInstance_p);
-#if !defined(INLINE_ENABLED)
tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
unsigned long ulTimeOut_p,
@@ -159,7 +149,6 @@ extern "C" {
pfnShbSignalHandlerNewData_p,
tShbPriority ShbPriority_p);
-#endif
// Linear Shared Buffer
tShbError ShbLinAllocBuffer(unsigned long ulBufferSize_p,
@@ -168,7 +157,6 @@ extern "C" {
unsigned int *pfShbNewCreated_p);
tShbError ShbLinReleaseBuffer(tShbInstance pShbInstance_p);
-#if !defined(INLINE_ENABLED)
tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
unsigned long ulDstBufferOffs_p,
@@ -179,7 +167,6 @@ extern "C" {
unsigned long ulSrcBufferOffs_p,
unsigned long ulDataBlockSize_p);
-#endif
#ifndef NDEBUG
tShbError ShbCirTraceBuffer(tShbInstance pShbInstance_p);
@@ -194,10 +181,6 @@ extern "C" {
#define ShbTraceDump(p0, p1, p2, p3)
#endif
-#undef INLINE_ENABLED // disable actual inlining of functions
-#undef INLINE_FUNCTION
-#define INLINE_FUNCTION // define INLINE_FUNCTION to nothing
-
#ifdef __cplusplus
}
#endif
diff --git a/drivers/staging/epl/ShbIpc-LinuxKernel.c b/drivers/staging/epl/ShbIpc-LinuxKernel.c
index 1d3cb3f13de..497938bd09b 100644
--- a/drivers/staging/epl/ShbIpc-LinuxKernel.c
+++ b/drivers/staging/epl/ShbIpc-LinuxKernel.c
@@ -79,8 +79,6 @@
/* */
/***************************************************************************/
-#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// Configuration
//---------------------------------------------------------------------------
@@ -211,13 +209,11 @@ static inline tShbMemHeader *ShbIpcGetShbMemHeader(tShbMemInst * pShbMemInst_p)
// not inlined internal functions
int ShbIpcThreadSignalNewData(void *pvThreadParam_p);
int ShbIpcThreadSignalJobReady(void *pvThreadParam_p);
-#endif
//---------------------------------------------------------------------------
// modul globale vars
//---------------------------------------------------------------------------
-#if !defined(SHBIPC_INLINE_ENABLED)
struct sShbMemTable *psMemTableElementFirst_g;
static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p);
@@ -230,7 +226,6 @@ static void ShbIpcCrc32GenTable(unsigned long aulCrcTable[256]);
static unsigned long ShbIpcCrc32GetCrc(const char *pcString,
unsigned long aulCrcTable[256]);
-#endif
//=========================================================================//
// //
@@ -238,7 +233,6 @@ static unsigned long ShbIpcCrc32GetCrc(const char *pcString,
// //
//=========================================================================//
-#if !defined(SHBIPC_INLINE_ENABLED)
// not inlined external functions
//---------------------------------------------------------------------------
@@ -433,15 +427,11 @@ tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p)
return (ShbError);
}
-#endif // !defined(SHBIPC_INLINE_ENABLED)
-
-#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// Enter atomic section for Shared Buffer access
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
+tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
{
tShbMemInst *pShbMemInst;
@@ -469,7 +459,7 @@ INLINE_FUNCTION tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
// Leave atomic section for Shared Buffer access
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
+tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
{
tShbMemInst *pShbMemInst;
@@ -496,12 +486,9 @@ INLINE_FUNCTION tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
// Start signaling of new data (called from reading process)
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcStartSignalingNewData(tShbInstance
- pShbInstance_p,
- tSigHndlrNewData
- pfnSignalHandlerNewData_p,
- tShbPriority
- ShbPriority_p)
+tShbError ShbIpcStartSignalingNewData(tShbInstance pShbInstance_p,
+ tSigHndlrNewData pfnSignalHandlerNewData_p,
+ tShbPriority ShbPriority_p)
{
tShbMemInst *pShbMemInst;
tShbMemHeader *pShbMemHeader;
@@ -557,8 +544,7 @@ INLINE_FUNCTION tShbError ShbIpcStartSignalingNewData(tShbInstance
// Stop signaling of new data (called from reading process)
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcStopSignalingNewData(tShbInstance
- pShbInstance_p)
+tShbError ShbIpcStopSignalingNewData(tShbInstance pShbInstance_p)
{
tShbMemInst *pShbMemInst;
tShbMemHeader *pShbMemHeader;
@@ -604,7 +590,7 @@ INLINE_FUNCTION tShbError ShbIpcStopSignalingNewData(tShbInstance
// Signal new data (called from writing process)
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
+tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
{
tShbMemHeader *pShbMemHeader;
@@ -625,12 +611,9 @@ INLINE_FUNCTION tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
// Start signaling for job ready (called from waiting process)
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcStartSignalingJobReady(tShbInstance
- pShbInstance_p,
- unsigned long
- ulTimeOut_p,
- tSigHndlrJobReady
- pfnSignalHandlerJobReady_p)
+tShbError ShbIpcStartSignalingJobReady(tShbInstance pShbInstance_p,
+ unsigned long ulTimeOut_p,
+ tSigHndlrJobReady pfnSignalHandlerJobReady_p)
{
tShbMemInst *pShbMemInst;
tShbMemHeader *pShbMemHeader;
@@ -663,7 +646,7 @@ INLINE_FUNCTION tShbError ShbIpcStartSignalingJobReady(tShbInstance
// Signal job ready (called from executing process)
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
+tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
{
tShbMemHeader *pShbMemHeader;
@@ -685,7 +668,7 @@ INLINE_FUNCTION tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
// Get pointer to common used share memory area
//---------------------------------------------------------------------------
-INLINE_FUNCTION void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
+void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
{
tShbMemHeader *pShbMemHeader;
@@ -694,7 +677,7 @@ INLINE_FUNCTION void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
pShbMemHeader =
ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p));
if (pShbMemHeader != NULL) {
- pShbShMemPtr = (BYTE *) pShbMemHeader + sizeof(tShbMemHeader);
+ pShbShMemPtr = (u8 *) pShbMemHeader + sizeof(tShbMemHeader);
} else {
pShbShMemPtr = NULL;
}
@@ -703,16 +686,12 @@ INLINE_FUNCTION void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
}
-#endif
-
//=========================================================================//
// //
// P R I V A T E F U N C T I O N S //
// //
//=========================================================================//
-#if !defined(SHBIPC_INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// Get pointer to process local information structure
//---------------------------------------------------------------------------
@@ -963,4 +942,3 @@ static void ShbIpcDeleteListElement(int iBufferId)
}
-#endif
diff --git a/drivers/staging/epl/ShbIpc-Win32.c b/drivers/staging/epl/ShbIpc-Win32.c
deleted file mode 100644
index b9181471ae0..00000000000
--- a/drivers/staging/epl/ShbIpc-Win32.c
+++ /dev/null
@@ -1,1202 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: Project independend shared buffer (linear + circular)
-
- Description: Implementation of platform specific part for the
- shared buffer
- (Implementation for Win32)
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS 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.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- 2006/06/27 -rs: V 1.00 (initial version)
-
-****************************************************************************/
-
-#define WINVER 0x0400 // #defines necessary for usage of
-#define _WIN32_WINNT 0x0400 // function <SignalObjectAndWait>
-
-#include <windows.h>
-#include <stdio.h>
-#include "global.h"
-#include "sharedbuff.h"
-#include "shbipc.h"
-
-/***************************************************************************/
-/* */
-/* */
-/* G L O B A L D E F I N I T I O N S */
-/* */
-/* */
-/***************************************************************************/
-
-#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
-
-//---------------------------------------------------------------------------
-// Configuration
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Constant definitions
-//---------------------------------------------------------------------------
-
-#define MAX_LEN_BUFFER_ID MAX_PATH
-
-#define IDX_EVENT_NEW_DATA 0
-#define IDX_EVENT_TERM_REQU 1
-#define IDX_EVENT_TERM_RESP 2
-
-#define NAME_MUTEX_BUFF_ACCESS "BuffAccess"
-#define NAME_EVENT_NEW_DATA "NewData"
-#define NAME_EVENT_TERM_REQU "TermRequ"
-#define NAME_EVENT_TERM_RESP "TermResp"
-#define NAME_EVENT_JOB_READY "JobReady"
-
-#define TIMEOUT_ENTER_ATOMIC 1000 // for debgging: INFINITE
-#define TIMEOUT_TERM_THREAD 2000
-
-#define SBI_MAGIC_ID 0x5342492B // magic ID ("SBI+")
-#define SBH_MAGIC_ID 0x5342482A // magic ID ("SBH*")
-
-//---------------------------------------------------------------------------
-// Local types
-//---------------------------------------------------------------------------
-
-// This structure is the common header for the shared memory region used
-// by all processes attached this shared memory. It includes common
-// information to administrate/manage the shared buffer from a couple of
-// separated processes (e.g. the refernce counter). This structure is
-// located at the start of the shared memory region itself and exists
-// consequently only one times per shared memory instance.
-typedef struct {
- unsigned long m_SbhMagicID; // magic ID ("SBH*")
- unsigned long m_ulShMemSize;
- unsigned long m_ulRefCount;
- char m_szBufferID[MAX_LEN_BUFFER_ID];
-
-#ifndef NDEBUG
- unsigned long m_ulOwnerProcID;
-#endif
-
-} tShbMemHeader;
-
-// This structure is the "external entry point" from a separate process
-// to get access to a shared buffer. This structure includes all platform
-// resp. target specific information to administrate/manage the shared
-// buffer from a separate process. Every process attached to the shared
-// buffer has its own runtime instance of this structure with its individual
-// runtime data (e.g. the scope of an event handle is limitted to the
-// owner process only). The structure member <m_pShbMemHeader> points
-// to the (process specific) start address of the shared memory region
-// itself.
-typedef struct {
- unsigned long m_SbiMagicID; // magic ID ("SBI+")
- HANDLE m_hSharedMem;
- HANDLE m_hMutexBuffAccess;
- HANDLE m_hThreadNewData; // thraed to signal that new data are available
- HANDLE m_ahEventNewData[3]; // IDX_EVENT_NEW_DATA + IDX_EVENT_TERM_REQU + ID_EVENT_TERM_RESP
- tSigHndlrNewData m_pfnSigHndlrNewData;
- HANDLE m_hThreadJobReady; // thread to signal that a job/operation is ready now (e.g. reset buffer)
- HANDLE m_hEventJobReady;
- unsigned long m_ulTimeOutJobReady;
- tSigHndlrJobReady m_pfnSigHndlrJobReady;
- tShbMemHeader *m_pShbMemHeader;
-
-#ifndef NDEBUG
- unsigned long m_ulThreadIDNewData;
- unsigned long m_ulThreadIDJobReady;
-#endif
-
-} tShbMemInst;
-
-//---------------------------------------------------------------------------
-// Global variables
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Local variables
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Prototypes of internal functions
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Get pointer to process local information structure
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbMemInst *ShbIpcGetShbMemInst(tShbInstance pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
-
- pShbMemInst = (tShbMemInst *) pShbInstance_p;
- ASSERT(pShbMemInst->m_SbiMagicID == SBI_MAGIC_ID);
-
- return (pShbMemInst);
-
-}
-
-//---------------------------------------------------------------------------
-// Get pointer to shared memory header
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbMemHeader *ShbIpcGetShbMemHeader(tShbInstance
- pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- tShbMemHeader *pShbMemHeader;
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
- pShbMemHeader = pShbMemInst->m_pShbMemHeader;
- ASSERT(pShbMemHeader->m_SbhMagicID == SBH_MAGIC_ID);
-
- return (pShbMemHeader);
-
-}
-
-// not inlined internal functions
-DWORD WINAPI ShbIpcThreadSignalNewData(LPVOID pvThreadParam_p);
-DWORD WINAPI ShbIpcThreadSignalJobReady(LPVOID pvThreadParam_p);
-const char *ShbIpcGetUniformObjectName(const char *pszEventJobName_p,
- const char *pszBufferID_p,
- BOOL fGlobalObject_p);
-
-#endif
-
-#if !defined(SHBIPC_INLINE_ENABLED)
-// true internal functions (not inlined)
-static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p);
-static void ShbIpcReleasePrivateMem(void *pMem_p);
-#endif
-
-//=========================================================================//
-// //
-// P U B L I C F U N C T I O N S //
-// //
-//=========================================================================//
-
-#if !defined(SHBIPC_INLINE_ENABLED)
-// not inlined external functions
-
-//---------------------------------------------------------------------------
-// Initialize IPC for Shared Buffer Module
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcInit(void)
-{
-
- return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-// Deinitialize IPC for Shared Buffer Module
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcExit(void)
-{
-
- return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-// Allocate Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcAllocBuffer(unsigned long ulBufferSize_p,
- const char *pszBufferID_p,
- tShbInstance * ppShbInstance_p,
- unsigned int *pfShbNewCreated_p)
-{
-
- HANDLE hSharedMem;
- LPVOID pSharedMem;
- unsigned long ulShMemSize;
- tShbMemInst *pShbMemInst;
- tShbMemHeader *pShbMemHeader;
- tShbInstance pShbInstance;
- unsigned int fShMemNewCreated;
- const char *pszObjectName;
- HANDLE hMutexBuffAccess;
- HANDLE hEventNewData;
- HANDLE hEventJobReady;
- tShbError ShbError;
-
- ulShMemSize = ulBufferSize_p + sizeof(tShbMemHeader);
- pSharedMem = NULL;
- pShbInstance = NULL;
- fShMemNewCreated = FALSE;
- ShbError = kShbOk;
-
- //---------------------------------------------------------------
- // (1) open an existing or create a new shared memory
- //---------------------------------------------------------------
- // try to open an already existing shared memory
- // (created by an another process)
- hSharedMem = OpenFileMapping(FILE_MAP_ALL_ACCESS, // DWORD dwDesiredAccess
- FALSE, // BOOL bInheritHandle
- pszBufferID_p); // LPCTSTR lpName
- if (hSharedMem != NULL) {
- // a shared memory already exists
- fShMemNewCreated = FALSE;
- } else {
- // it seams that this process is the first who wants to use the
- // shared memory, so it has to create a new shared memory
- hSharedMem = CreateFileMapping(INVALID_HANDLE_VALUE, // HANDLE hFile
- NULL, // LPSECURITY_ATTRIBUTES lpAttributes
- PAGE_READWRITE, // DWORD flProtect
- 0, // DWORD dwMaximumSizeHigh
- ulShMemSize, // DWORD dwMaximumSizeLow
- pszBufferID_p); // LPCTSTR lpName
-
- fShMemNewCreated = TRUE;
- }
-
- if (hSharedMem == NULL) {
- ShbError = kShbOutOfMem;
- goto Exit;
- }
-
- //---------------------------------------------------------------
- // (2) get the pointer to the shared memory
- //---------------------------------------------------------------
- pSharedMem = MapViewOfFile(hSharedMem, // HANDLE hFileMappingObject
- FILE_MAP_ALL_ACCESS, // DWORD dwDesiredAccess,
- 0, // DWORD dwFileOffsetHigh,
- 0, // DWORD dwFileOffsetLow,
- ulShMemSize); // SIZE_T dwNumberOfBytesToMap
-
- if (pSharedMem == NULL) {
- ShbError = kShbOutOfMem;
- goto Exit;
- }
-
- //---------------------------------------------------------------
- // (3) setup or update header and management information
- //---------------------------------------------------------------
- pShbMemHeader = (tShbMemHeader *) pSharedMem;
-
- // allocate a memory block from process specific mempool to save
- // process local information to administrate/manage the shared buffer
- pShbMemInst =
- (tShbMemInst *) ShbIpcAllocPrivateMem(sizeof(tShbMemInst));
- if (pShbMemInst == NULL) {
- ShbError = kShbOutOfMem;
- goto Exit;
- }
- // reset complete header to default values
- pShbMemInst->m_SbiMagicID = SBI_MAGIC_ID;
- pShbMemInst->m_hSharedMem = hSharedMem;
- pShbMemInst->m_hMutexBuffAccess = INVALID_HANDLE_VALUE;
- pShbMemInst->m_hThreadNewData = INVALID_HANDLE_VALUE;
- pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] =
- INVALID_HANDLE_VALUE;
- pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] =
- INVALID_HANDLE_VALUE;
- pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] =
- INVALID_HANDLE_VALUE;
- pShbMemInst->m_pfnSigHndlrNewData = NULL;
- pShbMemInst->m_hThreadJobReady = INVALID_HANDLE_VALUE;
- pShbMemInst->m_hEventJobReady = INVALID_HANDLE_VALUE;
- pShbMemInst->m_ulTimeOutJobReady = 0;
- pShbMemInst->m_pfnSigHndlrJobReady = NULL;
- pShbMemInst->m_pShbMemHeader = pShbMemHeader;
-
-#ifndef NDEBUG
- {
- pShbMemInst->m_ulThreadIDNewData = 0;
- pShbMemInst->m_ulThreadIDJobReady = 0;
- }
-#endif
-
- // create mutex for buffer access
- pszObjectName =
- ShbIpcGetUniformObjectName(NAME_MUTEX_BUFF_ACCESS, pszBufferID_p,
- TRUE);
- hMutexBuffAccess = CreateMutex(NULL, // LPSECURITY_ATTRIBUTES lpMutexAttributes
- FALSE, // BOOL bInitialOwner
- pszObjectName); // LPCTSTR lpName
- pShbMemInst->m_hMutexBuffAccess = hMutexBuffAccess;
- ASSERT(pShbMemInst->m_hMutexBuffAccess != NULL);
-
- // The EventNewData is used for signaling of new data after a write
- // operation (SetEvent) as well as for waiting for new data on the
- // reader side (WaitForMultipleObjects). Because it's not known if
- // this process will be read or write data, the event will be
- // always created here.
- pszObjectName =
- ShbIpcGetUniformObjectName(NAME_EVENT_NEW_DATA, pszBufferID_p,
- TRUE);
- hEventNewData = CreateEvent(NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes
- FALSE, // BOOL bManualReset
- FALSE, // BOOL bInitialState
- pszObjectName); // LPCTSTR lpName
- pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] = hEventNewData;
- ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] != NULL);
-
- // The EventJobReady is used for signaling that a job is done (SetEvent)
- // as well as for waiting for finishing of a job (WaitForMultipleObjects).
- // Because it's not known if this process will signal or wait, the event
- // will be always created here.
- pszObjectName =
- ShbIpcGetUniformObjectName(NAME_EVENT_JOB_READY, pszBufferID_p,
- TRUE);
- hEventJobReady = CreateEvent(NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes
- FALSE, // BOOL bManualReset
- FALSE, // BOOL bInitialState
- pszObjectName); // LPCTSTR lpName
- pShbMemInst->m_hEventJobReady = hEventJobReady;
- ASSERT(pShbMemInst->m_hEventJobReady != NULL);
-
- if (fShMemNewCreated) {
- // this process was the first who wanted to use the shared memory,
- // so a new shared memory was created
- // -> setup new header information inside the shared memory region
- // itself
- pShbMemHeader->m_SbhMagicID = SBH_MAGIC_ID;
- pShbMemHeader->m_ulShMemSize = ulShMemSize;
- pShbMemHeader->m_ulRefCount = 1;
- strncpy(pShbMemHeader->m_szBufferID, pszBufferID_p,
- sizeof(pShbMemHeader->m_szBufferID) - 1);
-
-#ifndef NDEBUG
- {
- pShbMemHeader->m_ulOwnerProcID = GetCurrentProcessId();
- }
-#endif
- } else {
- // any other process has created the shared memory and this
- // process has only attached to it
- // -> check and update existing header information inside the
- // shared memory region itself
- if (pShbMemHeader->m_ulShMemSize != ulShMemSize) {
- ShbError = kShbOpenMismatch;
- goto Exit;
- }
-#ifndef NDEBUG
- {
- if (strncmp
- (pShbMemHeader->m_szBufferID, pszBufferID_p,
- sizeof(pShbMemHeader->m_szBufferID) - 1)) {
- ShbError = kShbOpenMismatch;
- goto Exit;
- }
- }
-#endif
-
- pShbMemHeader->m_ulRefCount++;
- }
-
- // set abstarct "handle" for returning to application
- pShbInstance = (tShbInstance *) pShbMemInst;
-
- Exit:
-
- if (ShbError != kShbOk) {
- if (pShbMemInst != NULL) {
- ShbIpcReleasePrivateMem(pShbMemInst);
- }
- if (pSharedMem != NULL) {
- UnmapViewOfFile(pSharedMem);
- }
- if (hSharedMem != NULL) {
- CloseHandle(hSharedMem);
- }
- }
-
- *pfShbNewCreated_p = fShMemNewCreated;
- *ppShbInstance_p = pShbInstance;
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Release Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- tShbMemHeader *pShbMemHeader;
- HANDLE hEventNewData;
- HANDLE hMutexBuffAccess;
- tShbError ShbError;
- tShbError ShbError2;
-
- if (pShbInstance_p == NULL) {
- return (kShbOk);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
- pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p);
-
- if (!--pShbMemHeader->m_ulRefCount) {
- ShbError = kShbOk;
- } else {
- ShbError = kShbMemUsedByOtherProcs;
- }
-
- ShbError2 = ShbIpcStopSignalingNewData(pShbInstance_p);
- hEventNewData = pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA];
- if (hEventNewData != INVALID_HANDLE_VALUE) {
- CloseHandle(hEventNewData);
- pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] =
- INVALID_HANDLE_VALUE;
- }
-
- hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess;
- if (hMutexBuffAccess != INVALID_HANDLE_VALUE) {
- CloseHandle(hMutexBuffAccess);
- pShbMemInst->m_hMutexBuffAccess = INVALID_HANDLE_VALUE;
- }
-
- UnmapViewOfFile(pShbMemHeader);
- if (pShbMemInst->m_hSharedMem != INVALID_HANDLE_VALUE) {
- CloseHandle(pShbMemInst->m_hSharedMem);
- pShbMemInst->m_hSharedMem = INVALID_HANDLE_VALUE;
- }
-
- ShbIpcReleasePrivateMem(pShbMemInst);
-
- if (ShbError == kShbOk) {
- ShbError = ShbError2;
- }
-
- return (ShbError);
-
-}
-
-#endif // !defined(SHBIPC_INLINE_ENABLED)
-
-#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
-
-//---------------------------------------------------------------------------
-// Enter atomic section for Shared Buffer access
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- HANDLE hMutexBuffAccess;
- DWORD dwWaitResult;
- tShbError ShbError;
-
- if (pShbInstance_p == NULL) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
- ShbError = kShbOk;
-
- hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess;
- if (hMutexBuffAccess != INVALID_HANDLE_VALUE) {
- dwWaitResult =
- WaitForSingleObject(hMutexBuffAccess, TIMEOUT_ENTER_ATOMIC);
- switch (dwWaitResult) {
- case WAIT_OBJECT_0 + 0:
- {
- break;
- }
-
- case WAIT_TIMEOUT:
- {
- TRACE0
- ("\nShbIpcEnterAtomicSection(): WAIT_TIMEOUT");
- ASSERT(0);
- ShbError = kShbBufferInvalid;
- break;
- }
-
- case WAIT_ABANDONED:
- {
- TRACE0
- ("\nShbIpcEnterAtomicSection(): WAIT_ABANDONED");
- ASSERT(0);
- ShbError = kShbBufferInvalid;
- break;
- }
-
- case WAIT_FAILED:
- {
- TRACE1
- ("\nShbIpcEnterAtomicSection(): WAIT_FAILED -> LastError=%ld",
- GetLastError());
- ASSERT(0);
- ShbError = kShbBufferInvalid;
- break;
- }
-
- default:
- {
- TRACE1
- ("\nShbIpcEnterAtomicSection(): unknown error -> LastError=%ld",
- GetLastError());
- ASSERT(0);
- ShbError = kShbBufferInvalid;
- break;
- }
- }
- } else {
- ShbError = kShbBufferInvalid;
- }
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Leave atomic section for Shared Buffer access
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- HANDLE hMutexBuffAccess;
- BOOL fRes;
- tShbError ShbError;
-
- if (pShbInstance_p == NULL) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
- ShbError = kShbOk;
-
- hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess;
- if (hMutexBuffAccess != INVALID_HANDLE_VALUE) {
- fRes = ReleaseMutex(hMutexBuffAccess);
- ASSERT(fRes);
- } else {
- ShbError = kShbBufferInvalid;
- }
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Start signaling of new data (called from reading process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcStartSignalingNewData(tShbInstance
- pShbInstance_p,
- tSigHndlrNewData
- pfnSignalHandlerNewData_p,
- tShbPriority
- ShbPriority_p)
-{
-
- tShbMemInst *pShbMemInst;
- tShbMemHeader *pShbMemHeader;
- const char *pszObjectName;
- HANDLE hEventTermRequ;
- HANDLE hEventTermResp;
- HANDLE hThreadNewData;
- unsigned long ulThreadIDNewData;
- tShbError ShbError;
- int iPriority;
-
- if ((pShbInstance_p == NULL) || (pfnSignalHandlerNewData_p == NULL)) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
- pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p);
- ShbError = kShbOk;
-
- if ((pShbMemInst->m_hThreadNewData != INVALID_HANDLE_VALUE) ||
- (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] !=
- INVALID_HANDLE_VALUE)
- || (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] !=
- INVALID_HANDLE_VALUE)
- || (pShbMemInst->m_pfnSigHndlrNewData != NULL)) {
- ShbError = kShbAlreadySignaling;
- goto Exit;
- }
-
- pShbMemInst->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;
-
- // Because the event <pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA]>
- // is used for signaling of new data after a write operation too (using
- // SetEvent), it is always created here (see <ShbIpcAllocBuffer>).
-
- pszObjectName =
- ShbIpcGetUniformObjectName(NAME_EVENT_TERM_REQU,
- pShbMemHeader->m_szBufferID, FALSE);
- hEventTermRequ = CreateEvent(NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes
- FALSE, // BOOL bManualReset
- FALSE, // BOOL bInitialState
- pszObjectName); // LPCTSTR lpName
- pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] = hEventTermRequ;
- ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] != NULL);
-
- pszObjectName =
- ShbIpcGetUniformObjectName(NAME_EVENT_TERM_RESP,
- pShbMemHeader->m_szBufferID, FALSE);
- hEventTermResp = CreateEvent(NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes
- FALSE, // BOOL bManualReset
- FALSE, // BOOL bInitialState
- pszObjectName); // LPCTSTR lpName
- pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] = hEventTermResp;
- ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] != NULL);
-
- hThreadNewData = CreateThread(NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes
- 0, // SIZE_T dwStackSize
- ShbIpcThreadSignalNewData, // LPTHREAD_START_ROUTINE lpStartAddress
- pShbInstance_p, // LPVOID lpParameter
- 0, // DWORD dwCreationFlags
- &ulThreadIDNewData); // LPDWORD lpThreadId
-
- switch (ShbPriority_p) {
- case kShbPriorityLow:
- iPriority = THREAD_PRIORITY_BELOW_NORMAL;
- break;
-
- case kShbPriorityNormal:
- iPriority = THREAD_PRIORITY_NORMAL;
- break;
-
- case kshbPriorityHigh:
- iPriority = THREAD_PRIORITY_ABOVE_NORMAL;
- break;
-
- }
-
- ASSERT(pShbMemInst->m_hThreadNewData != NULL);
-
- SetThreadPriority(hThreadNewData, iPriority);
-
- pShbMemInst->m_hThreadNewData = hThreadNewData;
-
-#ifndef NDEBUG
- {
- pShbMemInst->m_ulThreadIDNewData = ulThreadIDNewData;
- }
-#endif
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Stop signaling of new data (called from reading process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcStopSignalingNewData(tShbInstance
- pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- HANDLE hEventTermRequ;
- HANDLE hEventTermResp;
- DWORD dwWaitResult;
-
- if (pShbInstance_p == NULL) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-
- // terminate new data signaling thread
- // (set event <hEventTermRequ> to wakeup the thread and dispose it
- // to exit, then wait for confirmation using event <hEventTermResp>)
- hEventTermRequ = pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU];
- hEventTermResp = pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP];
- if ((hEventTermRequ != INVALID_HANDLE_VALUE) &&
- (hEventTermResp != INVALID_HANDLE_VALUE)) {
- TRACE0("\nShbIpcStopSignalingNewData(): enter wait state");
- dwWaitResult = SignalObjectAndWait(hEventTermRequ, // HANDLE hObjectToSignal
- hEventTermResp, // HANDLE hObjectToWaitOn
- TIMEOUT_TERM_THREAD, // DWORD dwMilliseconds
- FALSE); // BOOL bAlertable
- TRACE0
- ("\nShbIpcStopSignalingNewData(): wait state leaved: ---> ");
- switch (dwWaitResult) {
- case WAIT_OBJECT_0 + 0: // event "new data signaling thread terminated"
- {
- TRACE0("Event = WAIT_OBJECT_0+0");
- break;
- }
-
- default:
- {
- TRACE0("Unhandled Event");
- ASSERT(0);
- break;
- }
- }
- }
-
- if (pShbMemInst->m_hThreadNewData != INVALID_HANDLE_VALUE) {
- CloseHandle(pShbMemInst->m_hThreadNewData);
- pShbMemInst->m_hThreadNewData = INVALID_HANDLE_VALUE;
- }
-
- if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] !=
- INVALID_HANDLE_VALUE) {
- CloseHandle(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU]);
- pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] =
- INVALID_HANDLE_VALUE;
- }
-
- if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] !=
- INVALID_HANDLE_VALUE) {
- CloseHandle(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP]);
- pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] =
- INVALID_HANDLE_VALUE;
- }
-
- pShbMemInst->m_pfnSigHndlrNewData = NULL;
-
- return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-// Signal new data (called from writing process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- HANDLE hEventNewData;
- BOOL fRes;
-
- // TRACE0("\nShbIpcSignalNewData(): enter\n");
-
- if (pShbInstance_p == NULL) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-
- ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] !=
- INVALID_HANDLE_VALUE);
- hEventNewData = pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA];
- if (hEventNewData != INVALID_HANDLE_VALUE) {
- fRes = SetEvent(hEventNewData);
- // TRACE1("\nShbIpcSignalNewData(): EventNewData set (Result=%d)\n", (int)fRes);
- ASSERT(fRes);
- }
- // TRACE0("\nShbIpcSignalNewData(): leave\n");
- return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-// Start signaling for job ready (called from waiting process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcStartSignalingJobReady(tShbInstance
- pShbInstance_p,
- unsigned long
- ulTimeOut_p,
- tSigHndlrJobReady
- pfnSignalHandlerJobReady_p)
-{
-
- tShbMemInst *pShbMemInst;
- tShbMemHeader *pShbMemHeader;
- HANDLE hThreadJobReady;
- unsigned long ulThreadIDJobReady;
- tShbError ShbError;
-
- if ((pShbInstance_p == NULL) || (pfnSignalHandlerJobReady_p == NULL)) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
- pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p);
- ShbError = kShbOk;
-
- if ((pShbMemInst->m_hThreadJobReady != INVALID_HANDLE_VALUE) ||
- (pShbMemInst->m_pfnSigHndlrJobReady != NULL)) {
- ShbError = kShbAlreadySignaling;
- goto Exit;
- }
-
- pShbMemInst->m_ulTimeOutJobReady = ulTimeOut_p;
- pShbMemInst->m_pfnSigHndlrJobReady = pfnSignalHandlerJobReady_p;
-
- // Because the event <pShbMemInst->m_ahEventJobReady> is used for
- // signaling of a finished job too (using SetEvent), it is always
- // created here (see <ShbIpcAllocBuffer>).
-
- hThreadJobReady = CreateThread(NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes
- 0, // SIZE_T dwStackSize
- ShbIpcThreadSignalJobReady, // LPTHREAD_START_ROUTINE lpStartAddress
- pShbInstance_p, // LPVOID lpParameter
- 0, // DWORD dwCreationFlags
- &ulThreadIDJobReady); // LPDWORD lpThreadId
-
- pShbMemInst->m_hThreadJobReady = hThreadJobReady;
- ASSERT(pShbMemInst->m_hThreadJobReady != NULL);
-
-#ifndef NDEBUG
- {
- pShbMemInst->m_ulThreadIDJobReady = ulThreadIDJobReady;
- }
-#endif
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Signal job ready (called from executing process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- HANDLE hEventJobReady;
- BOOL fRes;
-
- // TRACE0("\nShbIpcSignalJobReady(): enter\n");
-
- if (pShbInstance_p == NULL) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-
- ASSERT(pShbMemInst->m_hEventJobReady != INVALID_HANDLE_VALUE);
- hEventJobReady = pShbMemInst->m_hEventJobReady;
- if (hEventJobReady != INVALID_HANDLE_VALUE) {
- fRes = SetEvent(hEventJobReady);
- // TRACE1("\nShbIpcSignalJobReady(): EventJobReady set (Result=%d)\n", (int)fRes);
- ASSERT(fRes);
- }
- // TRACE0("\nShbIpcSignalJobReady(): leave\n");
- return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-// Get pointer to common used share memory area
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
-{
-
- tShbMemHeader *pShbMemHeader;
- void *pShbShMemPtr;
-
- pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p);
- if (pShbMemHeader != NULL) {
- pShbShMemPtr = (BYTE *) pShbMemHeader + sizeof(tShbMemHeader);
- } else {
- pShbShMemPtr = NULL;
- }
-
- return (pShbShMemPtr);
-
-}
-
-#endif
-
-//=========================================================================//
-// //
-// P R I V A T E F U N C T I O N S //
-// //
-//=========================================================================//
-
-#if !defined(SHBIPC_INLINE_ENABLED)
-
-//---------------------------------------------------------------------------
-// Allocate a memory block from process specific mempool
-//---------------------------------------------------------------------------
-
-static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p)
-{
-
- HGLOBAL hMem;
- void *pMem;
-
- hMem = GlobalAlloc(GMEM_FIXED, ulMemSize_p + sizeof(HGLOBAL));
- pMem = GlobalLock(hMem);
- if (pMem != NULL) {
- *(HGLOBAL *) pMem = hMem;
- (BYTE *) pMem += sizeof(HGLOBAL);
- }
-
-#ifndef NDEBUG
- {
- memset(pMem, 0xaa, ulMemSize_p);
- }
-#endif
-
- return (pMem);
-
-}
-
-//---------------------------------------------------------------------------
-// Release a memory block from process specific mempool
-//---------------------------------------------------------------------------
-
-static void ShbIpcReleasePrivateMem(void *pMem_p)
-{
-
- HGLOBAL hMem;
-
- if (pMem_p == NULL) {
- return;
- }
-
- (BYTE *) pMem_p -= sizeof(HGLOBAL);
- hMem = *(HGLOBAL *) pMem_p;
-
- GlobalUnlock(hMem);
- GlobalFree(hMem);
-
- return;
-
-}
-
-//---------------------------------------------------------------------------
-// Create uniform object name (needed for inter-process communication)
-//---------------------------------------------------------------------------
-
-const char *ShbIpcGetUniformObjectName(const char *pszObjectJobName_p,
- const char *pszBufferID_p,
- BOOL fGlobalObject_p)
-{
-
- static char szObjectName[MAX_PATH];
- char szObjectPrefix[MAX_PATH];
-
- if (fGlobalObject_p) {
- strncpy(szObjectPrefix, "Global\\", sizeof(szObjectPrefix));
- } else {
- _snprintf(szObjectPrefix, sizeof(szObjectPrefix), "PID%08lX_",
- (unsigned long)GetCurrentProcessId());
- }
-
- _snprintf(szObjectName, sizeof(szObjectName), "%s%s#%s",
- szObjectPrefix, pszBufferID_p, pszObjectJobName_p);
-
- return (szObjectName);
-
-}
-
-//---------------------------------------------------------------------------
-// Thread for new data signaling
-//---------------------------------------------------------------------------
-
-DWORD WINAPI ShbIpcThreadSignalNewData(LPVOID pvThreadParam_p)
-{
-
- tShbInstance pShbInstance;
- tShbMemInst *pShbMemInst;
- DWORD dwWaitResult;
- BOOL fTermRequ;
- int fCallAgain;
-
- TRACE1
- ("\nShbIpcThreadSignalNewData(): SignalThread started (pShbInstance=0x%08lX)\n",
- (DWORD) pvThreadParam_p);
-
- pShbInstance = (tShbMemInst *) pvThreadParam_p;
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance);
- fTermRequ = FALSE;
-
- do {
- ASSERT((pShbMemInst->m_ahEventNewData[0] !=
- INVALID_HANDLE_VALUE)
- && (pShbMemInst->m_ahEventNewData[0] != NULL));
- ASSERT((pShbMemInst->m_ahEventNewData[1] !=
- INVALID_HANDLE_VALUE)
- && (pShbMemInst->m_ahEventNewData[1] != NULL));
-
- TRACE0("\nShbIpcThreadSignalNewData(): enter wait state");
- dwWaitResult = WaitForMultipleObjects(2, // DWORD nCount
- pShbMemInst->m_ahEventNewData, // const HANDLE* lpHandles
- FALSE, // BOOL bWaitAll
- INFINITE); // DWORD dwMilliseconds
- TRACE0
- ("\nShbIpcThreadSignalNewData(): wait state leaved: ---> ");
- switch (dwWaitResult) {
- case WAIT_OBJECT_0 + 0: // event "new data"
- {
- TRACE0("Event = WAIT_OBJECT_0+0");
- if (pShbMemInst->m_pfnSigHndlrNewData != NULL) {
- TRACE0
- ("\nShbIpcThreadSignalNewData(): calling SignalHandlerNewData");
- do {
- fCallAgain =
- pShbMemInst->
- m_pfnSigHndlrNewData
- (pShbInstance);
- // d.k.: try to run any shared buffer which has higher priority.
- // under Windows this is not really necessary because the Windows scheduler
- // already preempts tasks with lower priority.
- } while (fCallAgain != FALSE);
- }
- break;
- }
-
- case WAIT_OBJECT_0 + 1: // event "terminate"
- {
- TRACE0("Event = WAIT_OBJECT_0+1");
- fTermRequ = TRUE;
- break;
- }
-
- default:
- {
- TRACE0("Unhandled Event");
- ASSERT(0);
- fTermRequ = TRUE;
- break;
- }
- }
- }
- while (!fTermRequ);
-
- if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] !=
- INVALID_HANDLE_VALUE) {
- SetEvent(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP]);
- }
-
- TRACE1
- ("\nShbIpcThreadSignalNewData(): SignalThread terminated (pShbInstance=0x%08lX)\n",
- (DWORD) pShbInstance);
-
- ExitThread(0);
-
-}
-
-//---------------------------------------------------------------------------
-// Thread for new data signaling
-//---------------------------------------------------------------------------
-
-DWORD WINAPI ShbIpcThreadSignalJobReady(LPVOID pvThreadParam_p)
-{
-
- tShbInstance *pShbInstance;
- tShbMemInst *pShbMemInst;
- DWORD ulTimeOut;
- DWORD dwWaitResult;
- unsigned int fTimeOut;
-
- TRACE1
- ("\nShbIpcThreadSignalJobReady(): SignalThread started (pShbInstance=0x%08lX)\n",
- (DWORD) pvThreadParam_p);
-
- pShbInstance = (tShbInstance *) pvThreadParam_p;
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance);
- fTimeOut = FALSE;
-
- if (pShbMemInst->m_ulTimeOutJobReady != 0) {
- ulTimeOut = pShbMemInst->m_ulTimeOutJobReady;
- } else {
- ulTimeOut = INFINITE;
- }
-
- ASSERT((pShbMemInst->m_hEventJobReady != INVALID_HANDLE_VALUE)
- && (pShbMemInst->m_hEventJobReady != NULL));
-
- TRACE0("\nShbIpcThreadSignalJobReady(): enter wait state");
- dwWaitResult = WaitForSingleObject(pShbMemInst->m_hEventJobReady, // HANDLE hHandle
- ulTimeOut); // DWORD dwMilliseconds
- TRACE0("\nShbIpcThreadSignalJobReady(): wait state leaved: ---> ");
- switch (dwWaitResult) {
- case WAIT_OBJECT_0 + 0: // event "new data"
- {
- TRACE0("Event = WAIT_OBJECT_0+0");
- fTimeOut = FALSE;
- break;
- }
-
- case WAIT_TIMEOUT:
- {
- TRACE0("\nEvent = WAIT_TIMEOUT");
- fTimeOut = TRUE;
- // ASSERT(0);
- break;
- }
-
- default:
- {
- TRACE0("Unhandled Event");
- fTimeOut = TRUE;
- ASSERT(0);
- break;
- }
- }
-
- if (pShbMemInst->m_pfnSigHndlrJobReady != NULL) {
- TRACE0
- ("\nShbIpcThreadSignalJobReady(): calling SignalHandlerJobReady");
- pShbMemInst->m_pfnSigHndlrJobReady(pShbInstance, fTimeOut);
- }
-
- pShbMemInst->m_hThreadJobReady = INVALID_HANDLE_VALUE;
- pShbMemInst->m_pfnSigHndlrJobReady = NULL;
-
- TRACE1
- ("\nShbIpcThreadSignalJobReady(): SignalThread terminated (pShbInstance=0x%08lX)\n",
- (DWORD) pShbInstance);
-
- ExitThread(0);
-
-}
-
-#endif
-
-// EOF
diff --git a/drivers/staging/epl/ShbIpc.h b/drivers/staging/epl/ShbIpc.h
index cad8846a082..285f096e771 100644
--- a/drivers/staging/epl/ShbIpc.h
+++ b/drivers/staging/epl/ShbIpc.h
@@ -65,25 +65,6 @@ typedef int (*tSigHndlrNewData) (tShbInstance pShbInstance_p);
typedef void (*tSigHndlrJobReady) (tShbInstance pShbInstance_p,
unsigned int fTimeOut_p);
-#if (TARGET_SYSTEM == _WIN32_)
-#if defined(INLINE_FUNCTION_DEF)
-#undef INLINE_FUNCTION
-#define INLINE_FUNCTION INLINE_FUNCTION_DEF
-#define SHBIPC_INLINE_ENABLED TRUE
-#define SHBIPC_INLINED
-#include "ShbIpc-Win32.c"
-#endif
-
-#elif (TARGET_SYSTEM == _LINUX_)
-#if defined(INLINE_FUNCTION_DEF)
-#undef INLINE_FUNCTION
-#define INLINE_FUNCTION INLINE_FUNCTION_DEF
-#define SHBIPC_INLINE_ENABLED TRUE
-#define SHBIPC_INLINED
-#include "ShbIpc-LinuxKernel.c"
-#endif
-#endif
-
//---------------------------------------------------------------------------
// Prototypes
//---------------------------------------------------------------------------
@@ -97,8 +78,6 @@ tShbError ShbIpcAllocBuffer(unsigned long ulBufferSize_p,
unsigned int *pfShbNewCreated_p);
tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p);
-#if !defined(SHBIPC_INLINE_ENABLED)
-
tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p);
tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p);
@@ -116,10 +95,5 @@ tShbError ShbIpcStartSignalingJobReady(tShbInstance pShbInstance_p,
tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p);
void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p);
-#endif
-
-#undef SHBIPC_INLINE_ENABLED // disable actual inlining of functions
-#undef INLINE_FUNCTION
-#define INLINE_FUNCTION // define INLINE_FUNCTION to nothing
#endif // #ifndef _SHBIPC_H_
diff --git a/drivers/staging/epl/TimerHighReskX86.c b/drivers/staging/epl/TimerHighReskX86.c
index 82eee4702aa..d6897de4f14 100644
--- a/drivers/staging/epl/TimerHighReskX86.c
+++ b/drivers/staging/epl/TimerHighReskX86.c
@@ -97,14 +97,10 @@
#define PROVE_OVERRUN
-#ifndef CONFIG_HIGH_RES_TIMERS
-#error "Kernel symbol CONFIG_HIGH_RES_TIMERS is required."
-#endif
-
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -172,7 +168,7 @@ enum hrtimer_restart EplTimerHighReskCallback(struct hrtimer *pTimer_p);
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimerHighReskInit(void)
+tEplKernel EplTimerHighReskInit(void)
{
tEplKernel Ret;
@@ -196,7 +192,7 @@ tEplKernel PUBLIC EplTimerHighReskInit(void)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimerHighReskAddInstance(void)
+tEplKernel EplTimerHighReskAddInstance(void)
{
tEplKernel Ret;
unsigned int uiIndex;
@@ -206,13 +202,6 @@ tEplKernel PUBLIC EplTimerHighReskAddInstance(void)
EPL_MEMSET(&EplTimerHighReskInstance_l, 0,
sizeof(EplTimerHighReskInstance_l));
-#ifndef CONFIG_HIGH_RES_TIMERS
- printk
- ("EplTimerHighResk: Kernel symbol CONFIG_HIGH_RES_TIMERS is required.\n");
- Ret = kEplNoResource;
- return Ret;
-#endif
-
/*
* Initialize hrtimer structures for all usable timers.
*/
@@ -244,7 +233,7 @@ tEplKernel PUBLIC EplTimerHighReskAddInstance(void)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimerHighReskDelInstance(void)
+tEplKernel EplTimerHighReskDelInstance(void)
{
tEplTimerHighReskTimerInfo *pTimerInfo;
tEplKernel Ret;
@@ -298,12 +287,11 @@ tEplKernel PUBLIC EplTimerHighReskDelInstance(void)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimerHighReskModifyTimerNs(tEplTimerHdl * pTimerHdl_p,
- unsigned long long ullTimeNs_p,
- tEplTimerkCallback
- pfnCallback_p,
- unsigned long ulArgument_p,
- BOOL fContinuously_p)
+tEplKernel EplTimerHighReskModifyTimerNs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long long ullTimeNs_p,
+ tEplTimerkCallback pfnCallback_p,
+ unsigned long ulArgument_p,
+ BOOL fContinuously_p)
{
tEplKernel Ret;
unsigned int uiIndex;
@@ -396,7 +384,7 @@ tEplKernel PUBLIC EplTimerHighReskModifyTimerNs(tEplTimerHdl * pTimerHdl_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimerHighReskDeleteTimer(tEplTimerHdl * pTimerHdl_p)
+tEplKernel EplTimerHighReskDeleteTimer(tEplTimerHdl *pTimerHdl_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiIndex;
diff --git a/drivers/staging/epl/VirtualEthernetLinux.c b/drivers/staging/epl/VirtualEthernetLinux.c
index 5d838dbf73a..21206c4d22f 100644
--- a/drivers/staging/epl/VirtualEthernetLinux.c
+++ b/drivers/staging/epl/VirtualEthernetLinux.c
@@ -74,7 +74,6 @@
****************************************************************************/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -285,7 +284,7 @@ static tEplKernel VEthRecvFrame(tEplFrameInfo * pFrameInfo_p)
return Ret;
}
-tEplKernel PUBLIC VEthAddInstance(tEplDllkInitParam * pInitParam_p)
+tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -324,7 +323,7 @@ tEplKernel PUBLIC VEthAddInstance(tEplDllkInitParam * pInitParam_p)
return Ret;
}
-tEplKernel PUBLIC VEthDelInstance(void)
+tEplKernel VEthDelInstance(void)
{
tEplKernel Ret = kEplSuccessful;
diff --git a/drivers/staging/epl/amix86.c b/drivers/staging/epl/amix86.c
index 9f742384dac..d40ad918d3b 100644
--- a/drivers/staging/epl/amix86.c
+++ b/drivers/staging/epl/amix86.c
@@ -74,24 +74,22 @@
//#include "EplAmi.h"
#include "EplInc.h"
-#if (!defined(EPL_AMI_INLINED)) || defined(INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// typedef
//---------------------------------------------------------------------------
typedef struct {
- WORD m_wWord;
+ u16 m_wWord;
} twStruct;
typedef struct {
- DWORD m_dwDword;
+ u32 m_dwDword;
} tdwStruct;
typedef struct {
- QWORD m_qwQword;
+ u64 m_qwQword;
} tqwStruct;
@@ -117,37 +115,36 @@ typedef struct {
//
//---------------------------------------------------------------------------
-//------------< write BYTE in big endian >--------------------------
+//------------< write u8 in big endian >--------------------------
/*
-void PUBLIC AmiSetByteToBe (void FAR* pAddr_p, BYTE bByteVal_p)
+void AmiSetByteToBe (void *pAddr_p, u8 bByteVal_p)
{
- *(BYTE FAR*)pAddr_p = bByteVal_p;
+ *(u8 *)pAddr_p = bByteVal_p;
}
*/
-//------------< write WORD in big endian >--------------------------
+//------------< write u16 in big endian >--------------------------
-INLINE_FUNCTION void PUBLIC AmiSetWordToBe(void FAR * pAddr_p, WORD wWordVal_p)
+void AmiSetWordToBe(void * pAddr_p, u16 wWordVal_p)
{
- twStruct FAR *pwStruct;
+ twStruct *pwStruct;
twStruct wValue;
- wValue.m_wWord = (WORD) ((wWordVal_p & 0x00FF) << 8); //LSB to MSB
- wValue.m_wWord |= (WORD) ((wWordVal_p & 0xFF00) >> 8); //MSB to LSB
+ wValue.m_wWord = (u16) ((wWordVal_p & 0x00FF) << 8); //LSB to MSB
+ wValue.m_wWord |= (u16) ((wWordVal_p & 0xFF00) >> 8); //MSB to LSB
- pwStruct = (twStruct FAR *) pAddr_p;
+ pwStruct = (twStruct *) pAddr_p;
pwStruct->m_wWord = wValue.m_wWord;
}
-//------------< write DWORD in big endian >-------------------------
+//------------< write u32 in big endian >-------------------------
-INLINE_FUNCTION void PUBLIC AmiSetDwordToBe(void FAR * pAddr_p,
- DWORD dwDwordVal_p)
+void AmiSetDwordToBe(void *pAddr_p, u32 dwDwordVal_p)
{
- tdwStruct FAR *pdwStruct;
+ tdwStruct *pdwStruct;
tdwStruct dwValue;
dwValue.m_dwDword = ((dwDwordVal_p & 0x000000FF) << 24); //LSB to MSB
@@ -155,7 +152,7 @@ INLINE_FUNCTION void PUBLIC AmiSetDwordToBe(void FAR * pAddr_p,
dwValue.m_dwDword |= ((dwDwordVal_p & 0x00FF0000) >> 8);
dwValue.m_dwDword |= ((dwDwordVal_p & 0xFF000000) >> 24); //MSB to LSB
- pdwStruct = (tdwStruct FAR *) pAddr_p;
+ pdwStruct = (tdwStruct *) pAddr_p;
pdwStruct->m_dwDword = dwValue.m_dwDword;
}
@@ -176,35 +173,34 @@ INLINE_FUNCTION void PUBLIC AmiSetDwordToBe(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-//------------< write BYTE in little endian >--------------------------
+//------------< write u8 in little endian >--------------------------
/*
-void PUBLIC AmiSetByteToLe (void FAR* pAddr_p, BYTE bByteVal_p)
+void AmiSetByteToLe (void *pAddr_p, u8 bByteVal_p)
{
- *(BYTE FAR*)pAddr_p = bByteVal_p;
+ *(u8 *)pAddr_p = bByteVal_p;
}
*/
-//------------< write WORD in little endian >--------------------------
+//------------< write u16 in little endian >--------------------------
-INLINE_FUNCTION void PUBLIC AmiSetWordToLe(void FAR * pAddr_p, WORD wWordVal_p)
+void AmiSetWordToLe(void *pAddr_p, u16 wWordVal_p)
{
- twStruct FAR *pwStruct;
+ twStruct *pwStruct;
- pwStruct = (twStruct FAR *) pAddr_p;
+ pwStruct = (twStruct *) pAddr_p;
pwStruct->m_wWord = wWordVal_p;
}
-//------------< write DWORD in little endian >-------------------------
+//------------< write u32 in little endian >-------------------------
-INLINE_FUNCTION void PUBLIC AmiSetDwordToLe(void FAR * pAddr_p,
- DWORD dwDwordVal_p)
+void AmiSetDwordToLe(void *pAddr_p, u32 dwDwordVal_p)
{
- tdwStruct FAR *pdwStruct;
+ tdwStruct *pdwStruct;
- pdwStruct = (tdwStruct FAR *) pAddr_p;
+ pdwStruct = (tdwStruct *) pAddr_p;
pdwStruct->m_dwDword = dwDwordVal_p;
}
@@ -224,40 +220,40 @@ INLINE_FUNCTION void PUBLIC AmiSetDwordToLe(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-//------------< read BYTE in big endian >---------------------------
+//------------< read u8 in big endian >---------------------------
/*
-BYTE PUBLIC AmiGetByteFromBe (void FAR* pAddr_p)
+u8 AmiGetByteFromBe (void *pAddr_p)
{
- return ( *(BYTE FAR*)pAddr_p );
+ return ( *(u8 *)pAddr_p );
}
*/
-//------------< read WORD in big endian >---------------------------
+//------------< read u16 in big endian >---------------------------
-INLINE_FUNCTION WORD PUBLIC AmiGetWordFromBe(void FAR * pAddr_p)
+u16 AmiGetWordFromBe(void *pAddr_p)
{
- twStruct FAR *pwStruct;
+ twStruct *pwStruct;
twStruct wValue;
- pwStruct = (twStruct FAR *) pAddr_p;
+ pwStruct = (twStruct *) pAddr_p;
- wValue.m_wWord = (WORD) ((pwStruct->m_wWord & 0x00FF) << 8); //LSB to MSB
- wValue.m_wWord |= (WORD) ((pwStruct->m_wWord & 0xFF00) >> 8); //MSB to LSB
+ wValue.m_wWord = (u16) ((pwStruct->m_wWord & 0x00FF) << 8); //LSB to MSB
+ wValue.m_wWord |= (u16) ((pwStruct->m_wWord & 0xFF00) >> 8); //MSB to LSB
return (wValue.m_wWord);
}
-//------------< read DWORD in big endian >--------------------------
+//------------< read u32 in big endian >--------------------------
-INLINE_FUNCTION DWORD PUBLIC AmiGetDwordFromBe(void FAR * pAddr_p)
+u32 AmiGetDwordFromBe(void *pAddr_p)
{
- tdwStruct FAR *pdwStruct;
+ tdwStruct *pdwStruct;
tdwStruct dwValue;
- pdwStruct = (tdwStruct FAR *) pAddr_p;
+ pdwStruct = (tdwStruct *) pAddr_p;
dwValue.m_dwDword = ((pdwStruct->m_dwDword & 0x000000FF) << 24); //LSB to MSB
dwValue.m_dwDword |= ((pdwStruct->m_dwDword & 0x0000FF00) << 8);
@@ -283,36 +279,34 @@ INLINE_FUNCTION DWORD PUBLIC AmiGetDwordFromBe(void FAR * pAddr_p)
//
//---------------------------------------------------------------------------
-//------------< read BYTE in little endian >---------------------------
+//------------< read u8 in little endian >---------------------------
/*
-BYTE PUBLIC AmiGetByteFromLe (void FAR* pAddr_p)
+u8 AmiGetByteFromLe (void *pAddr_p)
{
- return ( *(BYTE FAR*)pAddr_p );
+ return ( *(u8 *)pAddr_p );
}
*/
-//------------< read WORD in little endian >---------------------------
+//------------< read u16 in little endian >---------------------------
-INLINE_FUNCTION WORD PUBLIC AmiGetWordFromLe(void FAR * pAddr_p)
+u16 AmiGetWordFromLe(void *pAddr_p)
{
- twStruct FAR *pwStruct;
+ twStruct *pwStruct;
- pwStruct = (twStruct FAR *) pAddr_p;
+ pwStruct = (twStruct *) pAddr_p;
return (pwStruct->m_wWord);
-
}
-//------------< read DWORD in little endian >--------------------------
+//------------< read u32 in little endian >--------------------------
-INLINE_FUNCTION DWORD PUBLIC AmiGetDwordFromLe(void FAR * pAddr_p)
+u32 AmiGetDwordFromLe(void *pAddr_p)
{
- tdwStruct FAR *pdwStruct;
+ tdwStruct *pdwStruct;
- pdwStruct = (tdwStruct FAR *) pAddr_p;
+ pdwStruct = (tdwStruct *) pAddr_p;
return (pdwStruct->m_dwDword);
-
}
//---------------------------------------------------------------------------
@@ -330,14 +324,11 @@ INLINE_FUNCTION DWORD PUBLIC AmiGetDwordFromLe(void FAR * pAddr_p)
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetDword24ToBe(void FAR * pAddr_p,
- DWORD dwDwordVal_p)
+void AmiSetDword24ToBe(void *pAddr_p, u32 dwDwordVal_p)
{
-
- ((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & dwDwordVal_p)[2];
- ((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & dwDwordVal_p)[1];
- ((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & dwDwordVal_p)[0];
-
+ ((u8 *) pAddr_p)[0] = ((u8 *) & dwDwordVal_p)[2];
+ ((u8 *) pAddr_p)[1] = ((u8 *) & dwDwordVal_p)[1];
+ ((u8 *) pAddr_p)[2] = ((u8 *) & dwDwordVal_p)[0];
}
//---------------------------------------------------------------------------
@@ -355,14 +346,11 @@ INLINE_FUNCTION void PUBLIC AmiSetDword24ToBe(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetDword24ToLe(void FAR * pAddr_p,
- DWORD dwDwordVal_p)
+void AmiSetDword24ToLe(void *pAddr_p, u32 dwDwordVal_p)
{
-
- ((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & dwDwordVal_p)[0];
- ((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & dwDwordVal_p)[1];
- ((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & dwDwordVal_p)[2];
-
+ ((u8 *) pAddr_p)[0] = ((u8 *) & dwDwordVal_p)[0];
+ ((u8 *) pAddr_p)[1] = ((u8 *) & dwDwordVal_p)[1];
+ ((u8 *) pAddr_p)[2] = ((u8 *) & dwDwordVal_p)[2];
}
//---------------------------------------------------------------------------
@@ -373,22 +361,19 @@ INLINE_FUNCTION void PUBLIC AmiSetDword24ToLe(void FAR * pAddr_p,
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: DWORD = read value
+// Return: u32 = read value
//
// State: not tested
//
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION DWORD PUBLIC AmiGetDword24FromBe(void FAR * pAddr_p)
+u32 AmiGetDword24FromBe(void *pAddr_p)
{
-
tdwStruct dwStruct;
dwStruct.m_dwDword = AmiGetDwordFromBe(pAddr_p);
dwStruct.m_dwDword >>= 8;
return (dwStruct.m_dwDword);
-
}
//---------------------------------------------------------------------------
@@ -399,22 +384,19 @@ INLINE_FUNCTION DWORD PUBLIC AmiGetDword24FromBe(void FAR * pAddr_p)
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: DWORD = read value
+// Return: u32 = read value
//
// State: not tested
//
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION DWORD PUBLIC AmiGetDword24FromLe(void FAR * pAddr_p)
+u32 AmiGetDword24FromLe(void *pAddr_p)
{
-
tdwStruct dwStruct;
dwStruct.m_dwDword = AmiGetDwordFromLe(pAddr_p);
dwStruct.m_dwDword &= 0x00FFFFFF;
return (dwStruct.m_dwDword);
-
}
//#ifdef USE_VAR64
@@ -433,20 +415,16 @@ INLINE_FUNCTION DWORD PUBLIC AmiGetDword24FromLe(void FAR * pAddr_p)
// State: not tested
//
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION void PUBLIC AmiSetQword64ToBe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword64ToBe(void *pAddr_p, u64 qwQwordVal_p)
{
-
- ((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & qwQwordVal_p)[7];
- ((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & qwQwordVal_p)[6];
- ((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & qwQwordVal_p)[5];
- ((BYTE FAR *) pAddr_p)[3] = ((BYTE FAR *) & qwQwordVal_p)[4];
- ((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[3];
- ((BYTE FAR *) pAddr_p)[5] = ((BYTE FAR *) & qwQwordVal_p)[2];
- ((BYTE FAR *) pAddr_p)[6] = ((BYTE FAR *) & qwQwordVal_p)[1];
- ((BYTE FAR *) pAddr_p)[7] = ((BYTE FAR *) & qwQwordVal_p)[0];
-
+ ((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[7];
+ ((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[6];
+ ((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[5];
+ ((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[4];
+ ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[3];
+ ((u8 *) pAddr_p)[5] = ((u8 *) & qwQwordVal_p)[2];
+ ((u8 *) pAddr_p)[6] = ((u8 *) & qwQwordVal_p)[1];
+ ((u8 *) pAddr_p)[7] = ((u8 *) & qwQwordVal_p)[0];
}
//---------------------------------------------------------------------------
@@ -463,16 +441,12 @@ INLINE_FUNCTION void PUBLIC AmiSetQword64ToBe(void FAR * pAddr_p,
// State: not tested
//
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION void PUBLIC AmiSetQword64ToLe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword64ToLe(void *pAddr_p, u64 qwQwordVal_p)
{
+ u64 *pqwDst;
- QWORD FAR *pqwDst;
-
- pqwDst = (QWORD FAR *) pAddr_p;
+ pqwDst = (u64 *) pAddr_p;
*pqwDst = qwQwordVal_p;
-
}
//---------------------------------------------------------------------------
@@ -488,23 +462,20 @@ INLINE_FUNCTION void PUBLIC AmiSetQword64ToLe(void FAR * pAddr_p,
// State: not tested
//
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword64FromBe(void FAR * pAddr_p)
+u64 AmiGetQword64FromBe(void *pAddr_p)
{
-
tqwStruct qwStruct;
- ((BYTE FAR *) & qwStruct.m_qwQword)[0] = ((BYTE FAR *) pAddr_p)[7];
- ((BYTE FAR *) & qwStruct.m_qwQword)[1] = ((BYTE FAR *) pAddr_p)[6];
- ((BYTE FAR *) & qwStruct.m_qwQword)[2] = ((BYTE FAR *) pAddr_p)[5];
- ((BYTE FAR *) & qwStruct.m_qwQword)[3] = ((BYTE FAR *) pAddr_p)[4];
- ((BYTE FAR *) & qwStruct.m_qwQword)[4] = ((BYTE FAR *) pAddr_p)[3];
- ((BYTE FAR *) & qwStruct.m_qwQword)[5] = ((BYTE FAR *) pAddr_p)[2];
- ((BYTE FAR *) & qwStruct.m_qwQword)[6] = ((BYTE FAR *) pAddr_p)[1];
- ((BYTE FAR *) & qwStruct.m_qwQword)[7] = ((BYTE FAR *) pAddr_p)[0];
+ ((u8 *) & qwStruct.m_qwQword)[0] = ((u8 *) pAddr_p)[7];
+ ((u8 *) & qwStruct.m_qwQword)[1] = ((u8 *) pAddr_p)[6];
+ ((u8 *) & qwStruct.m_qwQword)[2] = ((u8 *) pAddr_p)[5];
+ ((u8 *) & qwStruct.m_qwQword)[3] = ((u8 *) pAddr_p)[4];
+ ((u8 *) & qwStruct.m_qwQword)[4] = ((u8 *) pAddr_p)[3];
+ ((u8 *) & qwStruct.m_qwQword)[5] = ((u8 *) pAddr_p)[2];
+ ((u8 *) & qwStruct.m_qwQword)[6] = ((u8 *) pAddr_p)[1];
+ ((u8 *) & qwStruct.m_qwQword)[7] = ((u8 *) pAddr_p)[0];
return (qwStruct.m_qwQword);
-
}
//---------------------------------------------------------------------------
@@ -520,18 +491,15 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword64FromBe(void FAR * pAddr_p)
// State: not tested
//
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword64FromLe(void FAR * pAddr_p)
+u64 AmiGetQword64FromLe(void *pAddr_p)
{
-
- tqwStruct FAR *pqwStruct;
+ tqwStruct *pqwStruct;
tqwStruct qwStruct;
- pqwStruct = (tqwStruct FAR *) pAddr_p;
+ pqwStruct = (tqwStruct *) pAddr_p;
qwStruct.m_qwQword = pqwStruct->m_qwQword;
return (qwStruct.m_qwQword);
-
}
//---------------------------------------------------------------------------
@@ -549,15 +517,14 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword64FromLe(void FAR * pAddr_p)
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetQword40ToBe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword40ToBe(void *pAddr_p, u64 qwQwordVal_p)
{
- ((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & qwQwordVal_p)[4];
- ((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & qwQwordVal_p)[3];
- ((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & qwQwordVal_p)[2];
- ((BYTE FAR *) pAddr_p)[3] = ((BYTE FAR *) & qwQwordVal_p)[1];
- ((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[0];
+ ((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[4];
+ ((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[3];
+ ((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[2];
+ ((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[1];
+ ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[0];
}
@@ -576,12 +543,11 @@ INLINE_FUNCTION void PUBLIC AmiSetQword40ToBe(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetQword40ToLe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword40ToLe(void *pAddr_p, u64 qwQwordVal_p)
{
- ((DWORD FAR *) pAddr_p)[0] = ((DWORD FAR *) & qwQwordVal_p)[0];
- ((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[4];
+ ((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0];
+ ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[4];
}
@@ -593,13 +559,13 @@ INLINE_FUNCTION void PUBLIC AmiSetQword40ToLe(void FAR * pAddr_p,
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
// State: not tested
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword40FromBe(void FAR * pAddr_p)
+u64 AmiGetQword40FromBe(void *pAddr_p)
{
tqwStruct qwStruct;
@@ -619,13 +585,13 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword40FromBe(void FAR * pAddr_p)
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
// State: not tested
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword40FromLe(void FAR * pAddr_p)
+u64 AmiGetQword40FromLe(void *pAddr_p)
{
tqwStruct qwStruct;
@@ -652,16 +618,15 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword40FromLe(void FAR * pAddr_p)
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetQword48ToBe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword48ToBe(void *pAddr_p, u64 qwQwordVal_p)
{
- ((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & qwQwordVal_p)[5];
- ((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & qwQwordVal_p)[4];
- ((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & qwQwordVal_p)[3];
- ((BYTE FAR *) pAddr_p)[3] = ((BYTE FAR *) & qwQwordVal_p)[2];
- ((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[1];
- ((BYTE FAR *) pAddr_p)[5] = ((BYTE FAR *) & qwQwordVal_p)[0];
+ ((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[5];
+ ((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[4];
+ ((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[3];
+ ((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[2];
+ ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[1];
+ ((u8 *) pAddr_p)[5] = ((u8 *) & qwQwordVal_p)[0];
}
@@ -680,12 +645,11 @@ INLINE_FUNCTION void PUBLIC AmiSetQword48ToBe(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetQword48ToLe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword48ToLe(void *pAddr_p, u64 qwQwordVal_p)
{
- ((DWORD FAR *) pAddr_p)[0] = ((DWORD FAR *) & qwQwordVal_p)[0];
- ((WORD FAR *) pAddr_p)[2] = ((WORD FAR *) & qwQwordVal_p)[2];
+ ((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0];
+ ((u16 *) pAddr_p)[2] = ((u16 *) & qwQwordVal_p)[2];
}
@@ -697,13 +661,13 @@ INLINE_FUNCTION void PUBLIC AmiSetQword48ToLe(void FAR * pAddr_p,
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
// State: not tested
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword48FromBe(void FAR * pAddr_p)
+u64 AmiGetQword48FromBe(void *pAddr_p)
{
tqwStruct qwStruct;
@@ -723,13 +687,13 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword48FromBe(void FAR * pAddr_p)
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
// State: not tested
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword48FromLe(void FAR * pAddr_p)
+u64 AmiGetQword48FromLe(void *pAddr_p)
{
tqwStruct qwStruct;
@@ -756,17 +720,16 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword48FromLe(void FAR * pAddr_p)
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetQword56ToBe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword56ToBe(void *pAddr_p, u64 qwQwordVal_p)
{
- ((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & qwQwordVal_p)[6];
- ((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & qwQwordVal_p)[5];
- ((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & qwQwordVal_p)[4];
- ((BYTE FAR *) pAddr_p)[3] = ((BYTE FAR *) & qwQwordVal_p)[3];
- ((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[2];
- ((BYTE FAR *) pAddr_p)[5] = ((BYTE FAR *) & qwQwordVal_p)[1];
- ((BYTE FAR *) pAddr_p)[6] = ((BYTE FAR *) & qwQwordVal_p)[0];
+ ((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[6];
+ ((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[5];
+ ((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[4];
+ ((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[3];
+ ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[2];
+ ((u8 *) pAddr_p)[5] = ((u8 *) & qwQwordVal_p)[1];
+ ((u8 *) pAddr_p)[6] = ((u8 *) & qwQwordVal_p)[0];
}
@@ -785,13 +748,12 @@ INLINE_FUNCTION void PUBLIC AmiSetQword56ToBe(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetQword56ToLe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword56ToLe(void *pAddr_p, u64 qwQwordVal_p)
{
- ((DWORD FAR *) pAddr_p)[0] = ((DWORD FAR *) & qwQwordVal_p)[0];
- ((WORD FAR *) pAddr_p)[2] = ((WORD FAR *) & qwQwordVal_p)[2];
- ((BYTE FAR *) pAddr_p)[6] = ((BYTE FAR *) & qwQwordVal_p)[6];
+ ((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0];
+ ((u16 *) pAddr_p)[2] = ((u16 *) & qwQwordVal_p)[2];
+ ((u8 *) pAddr_p)[6] = ((u8 *) & qwQwordVal_p)[6];
}
@@ -803,13 +765,13 @@ INLINE_FUNCTION void PUBLIC AmiSetQword56ToLe(void FAR * pAddr_p,
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
// State: not tested
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword56FromBe(void FAR * pAddr_p)
+u64 AmiGetQword56FromBe(void *pAddr_p)
{
tqwStruct qwStruct;
@@ -829,13 +791,13 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword56FromBe(void FAR * pAddr_p)
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
// State: not tested
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword56FromLe(void FAR * pAddr_p)
+u64 AmiGetQword56FromLe(void *pAddr_p)
{
tqwStruct qwStruct;
@@ -862,13 +824,11 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword56FromLe(void FAR * pAddr_p)
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetTimeOfDay(void FAR * pAddr_p,
- tTimeOfDay FAR * pTimeOfDay_p)
+void AmiSetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p)
{
- AmiSetDwordToLe(((BYTE FAR *) pAddr_p),
- pTimeOfDay_p->m_dwMs & 0x0FFFFFFF);
- AmiSetWordToLe(((BYTE FAR *) pAddr_p) + 4, pTimeOfDay_p->m_wDays);
+ AmiSetDwordToLe(((u8 *) pAddr_p), pTimeOfDay_p->m_dwMs & 0x0FFFFFFF);
+ AmiSetWordToLe(((u8 *) pAddr_p) + 4, pTimeOfDay_p->m_wDays);
}
@@ -887,18 +847,14 @@ INLINE_FUNCTION void PUBLIC AmiSetTimeOfDay(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiGetTimeOfDay(void FAR * pAddr_p,
- tTimeOfDay FAR * pTimeOfDay_p)
+void AmiGetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p)
{
- pTimeOfDay_p->m_dwMs =
- AmiGetDwordFromLe(((BYTE FAR *) pAddr_p)) & 0x0FFFFFFF;
- pTimeOfDay_p->m_wDays = AmiGetWordFromLe(((BYTE FAR *) pAddr_p) + 4);
+ pTimeOfDay_p->m_dwMs = AmiGetDwordFromLe(((u8 *) pAddr_p)) & 0x0FFFFFFF;
+ pTimeOfDay_p->m_wDays = AmiGetWordFromLe(((u8 *) pAddr_p) + 4);
}
-#endif
-
// EOF
// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
diff --git a/drivers/staging/epl/demo_main.c b/drivers/staging/epl/demo_main.c
index 263fa042291..7ad10fc2b1d 100644
--- a/drivers/staging/epl/demo_main.c
+++ b/drivers/staging/epl/demo_main.c
@@ -74,7 +74,6 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/major.h>
-#include <linux/version.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
@@ -87,16 +86,6 @@
#include "Epl.h"
#include "proc_fs.h"
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- // remove ("make invisible") obsolete symbols for kernel versions 2.6
- // and higher
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#define EXPORT_NO_SYMBOLS
-#else
-#error "This driver needs a 2.6.x kernel or higher"
-#endif
-
/***************************************************************************/
/* */
/* */
@@ -118,7 +107,7 @@ MODULE_DESCRIPTION("EPL MN demo");
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#else
#define TGT_DBG_SIGNAL_TRACE_POINT(p)
@@ -148,30 +137,30 @@ void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
// modul globale vars
//---------------------------------------------------------------------------
-CONST BYTE abMacAddr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const u8 abMacAddr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-BYTE bVarIn1_l;
-BYTE bVarOut1_l;
-BYTE bVarOut1Old_l;
-BYTE bModeSelect_l; // state of the pushbuttons to select the mode
-BYTE bSpeedSelect_l; // state of the pushbuttons to increase/decrease the speed
-BYTE bSpeedSelectOld_l; // old state of the pushbuttons
-DWORD dwLeds_l; // current state of all LEDs
-BYTE bLedsRow1_l; // current state of the LEDs in row 1
-BYTE bLedsRow2_l; // current state of the LEDs in row 2
-BYTE abSelect_l[3]; // pushbuttons from CNs
+static u8 bVarIn1_l;
+static u8 bVarOut1_l;
+static u8 bVarOut1Old_l;
+static u8 bModeSelect_l; // state of the pushbuttons to select the mode
+static u8 bSpeedSelect_l; // state of the pushbuttons to increase/decrease the speed
+static u8 bSpeedSelectOld_l; // old state of the pushbuttons
+static u32 dwLeds_l; // current state of all LEDs
+static u8 bLedsRow1_l; // current state of the LEDs in row 1
+static u8 bLedsRow2_l; // current state of the LEDs in row 2
+static u8 abSelect_l[3]; // pushbuttons from CNs
-DWORD dwMode_l; // current mode
-int iCurCycleCount_l; // current cycle count
-int iMaxCycleCount_l; // maximum cycle count (i.e. number of cycles until next light movement step)
-int iToggle; // indicates the light movement direction
+static u32 dwMode_l; // current mode
+static int iCurCycleCount_l; // current cycle count
+static int iMaxCycleCount_l; // maximum cycle count (i.e. number of cycles until next light movement step)
+static int iToggle; // indicates the light movement direction
-BYTE abDomain_l[3000];
+//static u8 abDomain_l[3000];
static wait_queue_head_t WaitQueueShutdown_g; // wait queue for tEplNmtEventSwitchOff
static atomic_t AtomicShutdown_g = ATOMIC_INIT(FALSE);
-static DWORD dw_le_CycleLen_g;
+static u32 dw_le_CycleLen_g;
static uint uiNodeId_g = EPL_C_ADR_INVALID;
module_param_named(nodeid, uiNodeId_g, uint, 0);
@@ -188,23 +177,19 @@ module_param_named(cyclelen, uiCycleLen_g, uint, 0);
// this function prototype here. If you want to use more than one Epl
// instances then the function name of each object dictionary has to differ.
-tEplKernel PUBLIC EplObdInitRam(tEplObdInitParam MEM * pInitParam_p);
+tEplKernel EplObdInitRam(tEplObdInitParam *pInitParam_p);
-tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
- tEplApiEventArg * pEventArg_p, // IN: event argument (union)
- void GENERIC * pUserArg_p);
+tEplKernel AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
+ tEplApiEventArg *pEventArg_p, // IN: event argument (union)
+ void *pUserArg_p);
-tEplKernel PUBLIC AppCbSync(void);
+tEplKernel AppCbSync(void);
-static int __init EplLinInit(void);
-static void __exit EplLinExit(void);
//---------------------------------------------------------------------------
// Kernel Module specific Data Structures
//---------------------------------------------------------------------------
-EXPORT_NO_SYMBOLS;
-
//module_init(EplLinInit);
//module_exit(EplLinExit);
@@ -231,6 +216,7 @@ EXPORT_NO_SYMBOLS;
// State:
//
//---------------------------------------------------------------------------
+#if 0
static int __init EplLinInit(void)
{
tEplKernel EplRet;
@@ -263,7 +249,7 @@ static int __init EplLinInit(void)
EplApiInitParam.m_uiSizeOfStruct = sizeof(EplApiInitParam);
EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr,
sizeof(EplApiInitParam.m_abMacAddress));
-// EplApiInitParam.m_abMacAddress[5] = (BYTE) EplApiInitParam.m_uiNodeId;
+// EplApiInitParam.m_abMacAddress[5] = (u8) EplApiInitParam.m_uiNodeId;
EplApiInitParam.m_dwFeatureFlags = -1;
EplApiInitParam.m_dwCycleLen = uiCycleLen_g; // required for error detection
EplApiInitParam.m_uiIsochrTxMaxPayload = 100; // const
@@ -401,7 +387,7 @@ static int __init EplLinInit(void)
// configure IP address of virtual network interface
// for TCP/IP communication over the POWERLINK network
- sprintf(sBuffer, "%lu.%lu.%lu.%lu",
+ sprintf(sBuffer, "%u.%u.%u.%u",
(EplApiInitParam.m_dwIpAddress >> 24),
((EplApiInitParam.m_dwIpAddress >> 16) & 0xFF),
((EplApiInitParam.m_dwIpAddress >> 8) & 0xFF),
@@ -456,7 +442,7 @@ static void __exit EplLinExit(void)
printk("EplLinProcFree(): 0x%X\n", EplRet);
}
-
+#endif
//=========================================================================//
// //
// P R I V A T E F U N C T I O N S //
@@ -484,9 +470,9 @@ static void __exit EplLinExit(void)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
- tEplApiEventArg * pEventArg_p, // IN: event argument (union)
- void GENERIC * pUserArg_p)
+tEplKernel AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
+ tEplApiEventArg *pEventArg_p, // IN: event argument (union)
+ void *pUserArg_p)
{
tEplKernel EplRet = kEplSuccessful;
@@ -515,7 +501,7 @@ tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p, // IN: event type (en
case kEplNmtGsResetCommunication:
{
- DWORD dwBuffer;
+ u32 dwBuffer;
// configure OD for MN in state ResetComm after reseting the OD
// TODO: setup your own network configuration here
@@ -677,8 +663,8 @@ tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p, // IN: event type (en
case kEplEventSourceDllk:
{ // error occured within the data link layer (e.g. interrupt processing)
- // the DWORD argument contains the DLL state and the NMT event
- printk(" val=%lX\n",
+ // the u32 argument contains the DLL state and the NMT event
+ printk(" val=%X\n",
pEventArg_p->m_InternalError.
m_Arg.m_dwArg);
break;
@@ -802,7 +788,7 @@ tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p, // IN: event type (en
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC AppCbSync(void)
+tEplKernel AppCbSync(void)
{
tEplKernel EplRet = kEplSuccessful;
@@ -810,7 +796,7 @@ tEplKernel PUBLIC AppCbSync(void)
bVarOut1Old_l = bVarOut1_l;
// set LEDs
-// printk("bVarIn = 0x%02X bVarOut = 0x%02X\n", (WORD) bVarIn_l, (WORD) bVarOut_l);
+// printk("bVarIn = 0x%02X bVarOut = 0x%02X\n", (u16) bVarIn_l, (u16) bVarOut_l);
}
if (uiNodeId_g != EPL_C_ADR_MN_DEF_NODE_ID) {
bVarIn1_l++;
diff --git a/drivers/staging/epl/edrv.h b/drivers/staging/epl/edrv.h
index a45984dfb09..62b4e77e069 100644
--- a/drivers/staging/epl/edrv.h
+++ b/drivers/staging/epl/edrv.h
@@ -104,7 +104,7 @@ typedef struct _tEdrvTxBuffer {
unsigned int m_uiTxMsgLen; // IN: length of message to be send (set for each transmit call)
// ----------------------
unsigned int m_uiBufferNumber; // OUT: number of the buffer, set by ethernetdriver
- BYTE *m_pbBuffer; // OUT: pointer to the buffer, set by ethernetdriver
+ u8 *m_pbBuffer; // OUT: pointer to the buffer, set by ethernetdriver
tEplNetTime m_NetTime; // OUT: Timestamp of end of transmission, set by ethernetdriver
// ----------------------
unsigned int m_uiMaxBufferLen; // IN/OUT: maximum length of the buffer
@@ -114,23 +114,23 @@ typedef struct _tEdrvTxBuffer {
typedef struct _tEdrvRxBuffer {
tEdrvBufferInFrame m_BufferInFrame; // OUT position of received buffer in an ethernet-frame
unsigned int m_uiRxMsgLen; // OUT: length of received buffer (without CRC)
- BYTE *m_pbBuffer; // OUT: pointer to the buffer, set by ethernetdriver
+ u8 *m_pbBuffer; // OUT: pointer to the buffer, set by ethernetdriver
tEplNetTime m_NetTime; // OUT: Timestamp of end of receiption
} tEdrvRxBuffer;
-//typedef void (*tEdrvRxHandler) (BYTE bBufferInFrame_p, tBufferDescr * pbBuffer_p);
-//typedef void (*tEdrvRxHandler) (BYTE bBufferInFrame_p, BYTE * pbEthernetData_p, WORD wDataLen_p);
+//typedef void (*tEdrvRxHandler) (u8 bBufferInFrame_p, tBufferDescr * pbBuffer_p);
+//typedef void (*tEdrvRxHandler) (u8 bBufferInFrame_p, u8 * pbEthernetData_p, u16 wDataLen_p);
typedef void (*tEdrvRxHandler) (tEdrvRxBuffer * pRxBuffer_p);
typedef void (*tEdrvTxHandler) (tEdrvTxBuffer * pTxBuffer_p);
// format of init structure
typedef struct {
- BYTE m_abMyMacAddr[6]; // the own MAC address
+ u8 m_abMyMacAddr[6]; // the own MAC address
-// BYTE m_bNoOfRxBuffDescr; // number of entries in rx bufferdescriptor table
+// u8 m_bNoOfRxBuffDescr; // number of entries in rx bufferdescriptor table
// tBufferDescr * m_pRxBuffDescrTable; // rx bufferdescriptor table
-// WORD m_wRxBufferSize; // size of the whole rx buffer
+// u16 m_wRxBufferSize; // size of the whole rx buffer
tEdrvRxHandler m_pfnRxHandler;
tEdrvTxHandler m_pfnTxHandler;
@@ -145,11 +145,11 @@ tEplKernel EdrvInit(tEdrvInitParam * pEdrvInitParam_p);
tEplKernel EdrvShutdown(void);
-tEplKernel EdrvDefineRxMacAddrEntry(BYTE * pbMacAddr_p);
-tEplKernel EdrvUndefineRxMacAddrEntry(BYTE * pbMacAddr_p);
+tEplKernel EdrvDefineRxMacAddrEntry(u8 * pbMacAddr_p);
+tEplKernel EdrvUndefineRxMacAddrEntry(u8 * pbMacAddr_p);
-//tEplKernel EdrvDefineUnicastEntry (BYTE * pbUCEntry_p);
-//tEplKernel EdrvUndfineUnicastEntry (BYTE * pbUCEntry_p);
+//tEplKernel EdrvDefineUnicastEntry (u8 * pbUCEntry_p);
+//tEplKernel EdrvUndfineUnicastEntry (u8 * pbUCEntry_p);
tEplKernel EdrvAllocTxMsgBuffer(tEdrvTxBuffer * pBuffer_p);
tEplKernel EdrvReleaseTxMsgBuffer(tEdrvTxBuffer * pBuffer_p);
diff --git a/drivers/staging/epl/global.h b/drivers/staging/epl/global.h
index fe167165a83..8c52d97ec9c 100644
--- a/drivers/staging/epl/global.h
+++ b/drivers/staging/epl/global.h
@@ -22,1261 +22,21 @@
#ifndef _GLOBAL_H_
#define _GLOBAL_H_
-//---------------------------------------------------------------------------
-// elements of defines for development system
-//---------------------------------------------------------------------------
-
-// these defines are necessary to check some of characteristics of the development system
-#define _DEV_BIGEND_ 0x80000000L // big endian (motorolla format)
-#define _DEV_ALIGNMENT_4_ 0x00400000L // the CPU needs alignment of 4 bytes
-#define _DEV_ONLY_INT_MAIN_ 0x00004000L // the compiler needs "int main(int)" instead of "void main(void)"
-#define _DEV_COMMA_EXT_ 0x00002000L // support of last comma in struct predefinition
-#define _DEV_64BIT_SUPPORT_ 0x00001000L // support of 64 bit operations
-#define _DEV_BIT64_ 0x00000400L // count of bits: 64 bit
-#define _DEV_BIT32_ 0x00000300L // 32 bit
-#define _DEV_BIT16_ 0x00000200L // 16 bit
-#define _DEV_BIT8_ 0x00000100L // 8 bit
-#define _DEV_RVCT_ARM_ 0x0000001CL // RealView ARM
-#define _DEV_RENESASM32C 0x0000001BL // compiler from: Renesas
-#define _DEV_GNUC_MIPS2_ 0x0000001AL // GNU for MIPS2
-#define _DEV_MPLAB_C30_ 0x00000019L // MPLAB C30 for Microchip dsPIC33F series
-#define _DEV_GNUC_TC_ 0x00000018L // GNU for Infineon TriCore
-#define _DEV_GNUC_X86_ 0x00000017L // GNU for I386
-#define _DEV_IAR_ARM_ 0x00000016L // ARM IAR C/C++ Compiler
-#define _DEV_PARADGM_X86 0x00000015L // Paradigm C/C++ for Beck 1x3
-#define _DEV_GNUC_CF_ 0x00000014L // GNU for Coldfire
-#define _DEV_KEIL_ARM_ 0x00000013L // Keil ARM
-#define _DEV_MSEVC_ 0x00000012L // Microsoft embedded Visual C/C++
-#define _DEV_HIGHTEC_GNUC_X86_ 0x00000011L // Hightec elf386 gcc
-#define _DEV_MSVC_RTX_ 0x00000010L // VC600 + RTX
-#define _DEV_MSVC_V1_5_ 0x0000000FL // Microsoft Visual C/C++ V1.5
-#define _DEV_GNUC_ARM7_ 0x0000000EL // GNU Compiler gcc for ARM7
-#define _DEV_METROWERKS_CW_ 0x0000000DL // Metrowerks Code Warrior
-#define _DEV_MITSUBISHIM16C_ 0x0000000CL //compiler from: Mitsubishi
-#define _DEV_GNUC_C16X_ 0x0000000BL // GNU Compiler gcc166 for Infineon C16x
-#define _DEV_LINUX_GCC_ 0x0000000AL // Linux GNU Compiler gcc
-#define _DEV_GNUC_MPC5X5 0x00000009L // GNU for Motorola PPC5x5
-#define _DEV_TASKINGM16C_ 0x00000008L // Tasking for Mitsubishi M16C
-#define _DEV_FUJITSU_ 0x00000007L // Fujitsu
-#define _DEV_TASKING8_ 0x00000006L // Tasking 8051
-#define _DEV_TASKING16_ 0x00000005L // Tasking 166
-#define _DEV_KEIL8_ 0x00000004L // Keil C51
-#define _DEV_KEIL16_ 0x00000003L // Keil C166
-#define _DEV_BORLANDC_ 0x00000002L // Borland C/C++
-#define _DEV_MSVC16_ 0x00000001L // Microsoft Visual C/C++
-#define _DEV_MSVC32_ 0x00000000L // Microsoft Visual C/C++
-
-// these defines can be used to mask previous elements
-#define _DEV_MASK_COMPILER 0x000000FFL
-#define _DEV_MASK_BITCOUNT 0x00000F00L
-#define _DEV_MASK_ADDSUPPORT 0x0000F000L
-#define _DEV_MASK_ALIGNMENT 0x00F00000L
-
-//---------------------------------------------------------------------------
-// defines for development system (DEV_SYSTEM) including previous elements
-//---------------------------------------------------------------------------
-
-#define _DEV_WIN16_ (_DEV_BIT16_ | _DEV_MSVC16_ )
-#define _DEV_WIN32_ (_DEV_BIT32_ | _DEV_MSVC32_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_MSVC_DOS_ (_DEV_BIT32_ | _DEV_MSVC_V1_5_ )
-#define _DEV_BORLAND_DOS_ (_DEV_BIT32_ | _DEV_BORLANDC_ ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_KEIL_C51X_ (_DEV_BIT8_ | _DEV_KEIL8_ | _DEV_BIGEND_ | _DEV_COMMA_EXT_) // at least C51 version 7.05 supports comma extension
-#define _DEV_KEIL_C16X_ (_DEV_BIT16_ | _DEV_KEIL16_ | _DEV_COMMA_EXT_) // at least C166 version 5.03 supports comma extension
-#define _DEV_TASKING_C51X_ (_DEV_BIT8_ | _DEV_TASKING8_ | _DEV_BIGEND_)
-#define _DEV_TASKING_C16X_ (_DEV_BIT16_ | _DEV_TASKING16_ )
-#define _DEV_FUJITSU_F590_ (_DEV_BIT8_ | _DEV_FUJITSU_ | _DEV_COMMA_EXT_) // softune is not able to support 64 bit variables QWORD !!!
-//f.j.29.04.03 M16C kann effektiv mit Bytes umgehen
-//#define _DEV_TASKING_M16C_ (_DEV_BIT16_ | _DEV_TASKINGM16C_ )
-#define _DEV_TASKING_M16C_ (_DEV_BIT8_ | _DEV_TASKINGM16C_ )
-#define _DEV_MITSUBISHI_M16C_ (_DEV_BIT8_ | _DEV_MITSUBISHIM16C_ )
-#define _DEV_GNU_MPC5X5_ (_DEV_BIT32_ | _DEV_GNUC_MPC5X5| _DEV_BIGEND_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_LINUX_ (_DEV_BIT32_ | _DEV_LINUX_GCC_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_GNU_C16X_ (_DEV_BIT16_ | _DEV_GNUC_C16X_ ) //| _DEV_COMMA_EXT_)
-#define _DEV_MCW_MPC5X5_ (_DEV_BIT32_ | _DEV_METROWERKS_CW_ ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_GNU_ARM7_ (_DEV_BIT32_ | _DEV_GNUC_ARM7_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
-#define _DEV_WIN32_RTX_ (_DEV_BIT32_ | _DEV_MSVC_RTX_ ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_HIGHTEC_X86_ (_DEV_BIT32_ | _DEV_HIGHTEC_GNUC_X86_ ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_WIN_CE_ (_DEV_BIT32_ | _DEV_MSEVC_ ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_KEIL_CARM_ (_DEV_BIT32_ | _DEV_KEIL_ARM_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_IAR_CARM_ (_DEV_BIT32_ | _DEV_IAR_ARM_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_RVCT_CARM_ (_DEV_BIT32_ | _DEV_RVCT_ARM_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
-#define _DEV_MCW_MCF5XXX_ (_DEV_BIT32_ | _DEV_METROWERKS_CW_ ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_GNU_CF5282_ (_DEV_BIT32_ | _DEV_GNUC_CF_ | _DEV_BIGEND_)
-#define _DEV_PAR_BECK1X3_ (_DEV_BIT16_ | _DEV_PARADGM_X86)
-#define _DEV_GNU_CF548X_ (_DEV_BIT32_ | _DEV_GNUC_CF_ | _DEV_BIGEND_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_GNU_I386_ (_DEV_BIT32_ | _DEV_GNUC_X86_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
-#define _DEV_GNU_TRICORE_ (_DEV_BIT32_ | _DEV_GNUC_TC_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_ | _DEV_ALIGNMENT_4_)
-#define _DEV_MPLAB_DSPIC33F_ (_DEV_BIT16_ | _DEV_MPLAB_C30_ ) //| _DEV_COMMA_EXT_)
-#define _DEV_GNU_MIPSEL_ (_DEV_BIT32_ | _DEV_GNUC_MIPS2_ | _DEV_BIGEND_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
-
-#define _DEV_RENESAS_M32C_ (_DEV_BIT32_ | _DEV_RENESASM32C)
-
-//---------------------------------------------------------------------------
-// usefull macros
-//---------------------------------------------------------------------------
-
-#define CHECK_IF_ONLY_INT_MAIN() (DEV_SYSTEM & _DEV_ONLY_INT_MAIN_)
-#define CHECK_MEMORY_ALINMENT() (DEV_SYSTEM & _DEV_MASK_ALIGNMENT)
-
-//---------------------------------------------------------------------------
-// defines for target system (TARGET_SYSTEM)
-//---------------------------------------------------------------------------
-
-#define _DOS_ (16 + 0x10000)
-#define _WIN16_ 16
-#define _WIN32_ 32
-#define _WINCE_ (32 + 0x20000)
-#define _NO_OS_ 0
-#define _LINUX_ 1
-#define _PXROS_ 2
-#define _ECOSPRO_ 3
-
-//---------------------------------------------------------------------------
-// definitions for function inlining
-//---------------------------------------------------------------------------
-
-#define INLINE_FUNCTION // empty define
-#undef INLINE_ENABLED // disable actual inlining of functions
-#undef INLINE_FUNCTION_DEF // disable inlining for all compilers per default
-
-//---------------------------------------------------------------------------
-// definitions for Keil C51
-//---------------------------------------------------------------------------
-
-#ifdef __C51__
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_KEIL_C51X_
-
-#pragma DEBUG OBJECTEXTEND
-#pragma WARNINGLEVEL(2) // maximum warning level
-
-#define NEAR idata // variables mapped to internal data storage location
-#define FAR xdata // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM code // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC xdata // hardware access through external memory (i.e. CAN)
-#define LARGE large // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM xdata // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT reentrant
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for GNU Compiler for Infineon C16x
-// - it have to be befor Keil (it has __C166__ too)
-//---------------------------------------------------------------------------
-#elif defined (__GNUC__) && defined (__C166__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_GNU_C16X_
-
-// #define NEAR idata // variables mapped to internal data storage location
-#define NEAR near // variables mapped to internal data storage location
-// #define FAR xhuge // variables mapped to external data storage location
-#define FAR huge // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-// #define HWACC sdata // hardware access through external memory (i.e. CAN)
-#define HWACC huge // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-// #define GENERIC xhuge // generic pointer to point to application data
-#define GENERIC huge // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-
-#define ASSERT(p) \
- if (p) \
- { \
- ; \
- } \
- else \
- { \
- PRINTF0("Assert failed: " #p " (file %s line %d)\n", __FILE__, (int) __LINE__ ); \
- while (1); \
- }
-#else
-#define ASSERT(p)
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Keil C166
-//---------------------------------------------------------------------------
-#elif defined (__C166__) // 24.01.2005 r.d.: Keil ARM7 needs directive 'defined'
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_KEIL_C16X_
-
-#pragma CODE
-#pragma MOD167
-#pragma NOINIT
-#pragma DEBUG
-#pragma WARNINGLEVEL(3) // maximum warning level
-#pragma WARNING DISABLE = 47 // warning <unreferenced parameter> = OFF
-#pragma WARNING DISABLE = 38 // warning <empty translation unit> = OFF
-// #pragma WARNING DISABLE = 102 // warning <different const/volatile qualifiers> = OFF
-#pragma WARNING DISABLE = 174 // warning <unreferenced 'static' function> = OFF
-#pragma WARNING DISABLE = 183 // warning <dead assignement eliminated> = OFF
-
-#define NEAR idata // variables mapped to internal data storage location
-#define FAR xhuge // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-// #define HWACC sdata // hardware access through external memory (i.e. CAN)
-#define HWACC huge // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC xhuge // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for MPLAB C30 for dsPIC33F series
-//---------------------------------------------------------------------------
-#elif defined (__C30__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_MPLAB_DSPIC33F_
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-// #ifndef QWORD
-// #define QWORD long long
-// #endif
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Keil ARM
-//---------------------------------------------------------------------------
-#elif defined (__CA__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_KEIL_CARM_
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for RealView ARM compilation tools (provided by recent Keil Microcontroller Development Kits)
-//---------------------------------------------------------------------------
-#elif defined (__ARMCC_VERSION)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_RVCT_CARM_
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long
-#endif
-
-#ifndef NDEBUG
-#define ASSERT(expr) if (!(expr)) {\
- TRACE0 ("Assertion failed: " #expr );\
- while (1);}
-#else
-#define ASSERT(expr)
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for ARM IAR C Compiler
-//---------------------------------------------------------------------------
-#elif defined (__ICCARM__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_IAR_CARM_
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long
-#endif
-
- // Workaround:
- // If we use IAR and want to debug but don't want to use C-Spy Debugger
- // assert() doesn't work in debug mode because it needs support for FILE descriptors
- // (_DLIB_FILE_DESCRIPTOR == 1).
-#ifndef NDEBUG
-#define ASSERT(expr) if (!(expr)) {\
- TRACE0 ("Assertion failed: " #expr );\
- while (1);}
-#else
-#define ASSERT(expr)
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-// #define TRACE PRINTF4
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Tasking 8051
-//---------------------------------------------------------------------------
-
-#elif defined (_CC51)
-
-#include <cc51.h>
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_TASKING_C51X_
-
-#define NEAR _data // variables mapped to internal data storage location
-#define FAR _xdat // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC _xdat // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM _xdat // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT _reentrant
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Tasking C167CR and C164CI
-//---------------------------------------------------------------------------
-
-#elif defined (_C166)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_TASKING_C16X_
-
-#define NEAR near // variables mapped to internal data storage location
-#define FAR far // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC /* to be defined */ // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
- // Stdio.h has to be alway included here. If printf() is used stdio.h defines NULL
- // without checking if it is already included. So an error occurs while compiling.
- // (r.d.)
-#include <stdio.h> // prototype printf() (for TRACE)
-#ifndef NDEBUG
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for FUJITSU FFMC-16LX MB90590
-//---------------------------------------------------------------------------
-
-//#elif (defined (F590) || defined (F543) || defined (F598) || defined (F495) || defined (F350))
-#elif defined(__COMPILER_FCC907__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_FUJITSU_F590_
-
-#define NEAR /* to be defined */ // variables mapped to internal data storage location
-#define FAR /* to be defined */ // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM /* to be defined */ // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC /* to be defined */ // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
- // softune is not able to support 64 bit variables QWORD !!!
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Mitsubishi M16C family for TASKING Compiler CM16
-//---------------------------------------------------------------------------
-
-#elif defined (_CM16C)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_TASKING_M16C_
-
-#define NEAR _near // variables mapped to internal data storage location
-#define FAR _far // variables mapped to external data storage location
-#define CONST _farrom // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC _near // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC _far // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
- // do you use memory model SMALL, than you have to set _far
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
- // Stdio.h has to be alway included here. If printf() is used stdio.h defines NULL
- // without checking if it is already included. So an error occurs while compiling.
- // (r.d.)
-#include <stdio.h> // prototype printf() (for TRACE)
-#ifndef NDEBUG
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Mitsubishi M16C family for Mitsubishi Compiler NC30
-//---------------------------------------------------------------------------
-// name NC30, andere Form will der Compiler nicht !!
-#elif defined (NC30)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_MITSUBISHI_M16C_
-
-#define NEAR near // variables mapped to internal data storage location
-#define FAR far // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC near // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC far // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Renesas M32C family for Renesas Compiler
-//---------------------------------------------------------------------------
-#elif defined (NC308)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_RENESAS_M32C_
-
-#define NEAR near // variables mapped to internal data storage location
-#define FAR far // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
-#define HWACC // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM far // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-// #error ("RENESAS o.k.")
-
-//---------------------------------------------------------------------------
-// definitions for ARM7 family with GNU compiler
-//---------------------------------------------------------------------------
-
-#elif defined(__GNUC__) && defined(__arm__) && !defined(__LINUX_ARM_ARCH__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_GNU_ARM7_
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-#define HWACC // hardware access through external memory (i.e. CAN)
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long // i.A. durch Herr Kuschel
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Motorola PowerPC family 5x5 (555/565)
-// definitions Linux-PC
-//---------------------------------------------------------------------------
-
-#elif defined (__GNUC__)
-
-#if defined (LINUX) || defined (linux) || defined (__linux__)
-#define LINUX_SYSTEM // define 'LINUX_SYSTEM' uniform for all Linux based systems
- // r.d.: We will need an other solution here! There are two sections here which do check the preproc-definitions:
- // LINUX and __linux__ . The first one was Linux for PC, the second one is this section for embedded Linux (MCF5xxx).
- // But Linux for PC does not need the definitions for embedded Linux.
-#endif
-
- // GNU C compiler supports function inlining
-#define INLINE_FUNCTION_DEF extern inline
-
- // to actually enable inlining just include the following three lines
- // #undef INLINE_FUNCTION
- // #define INLINE_FUNCTION INLINE_FUNCTION_DEF
- // #define INLINE_ENABLED TRUE
-
-#ifdef PXROS
-#define TARGET_SYSTEM _PXROS_
-#ifdef __i386__
-#undef LINUX // this define seems to be set from compiler
-#define DEV_SYSTEM _DEV_HIGHTEC_X86_
-#elif defined (__tricore__)
-#define DEV_SYSTEM _DEV_GNU_TRICORE_
-#else // MPC5x5
-#define DEV_SYSTEM _DEV_GNU_MPC5X5_
-#endif
-
-#elif defined (LINUX) || defined (__linux__)
-#define TARGET_SYSTEM _LINUX_ // Linux definition
-#define DEV_SYSTEM _DEV_LINUX_
-
-#elif defined (GNU_CF5282)
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_GNU_CF5282_
-
-#elif defined (ECOSPRO_I386_PEAK_PCI)
-#define TARGET_SYSTEM _ECOSPRO_
-#define DEV_SYSTEM _DEV_GNU_I386_
-
-#elif defined (GNU_CF548X)
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_GNU_CF548X_
-#else
-#error 'ERROR: DEV_SYSTEM not found!'
-#endif
-
-#ifndef QWORD
-#define QWORD long long int
-#endif
-
-#if (TARGET_SYSTEM == _PXROS_)
-
-#ifndef __KERNEL__
-#include <string.h>
-#endif
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM /* to be defined */ // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define HWACC // hardware access through external memory (i.e. CAN)
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long int
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-#endif
-
- // ------------------ GNUC for I386 ---------------------------------------------
-
-#if (TARGET_SYSTEM == _LINUX_) || (TARGET_SYSTEM == _ECOSPRO_)
-
-#ifndef __KERNEL__
-#include <string.h>
-#endif
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR // variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#ifndef __KERNEL__
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#else
#define TRACE printk
-#endif
-#endif
-#endif
-
- // ------------------ GNU without OS ---------------------------------------------
-
-#if (TARGET_SYSTEM == _NO_OS_)
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR // variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-// #include "xuartdrv.h"
-// #include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-// #define TRACE mprintf
-// #ifndef TRACE
-// #define TRACE trace
-// void trace (char *fmt, ...);
-// #endif
-#endif
-
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for MPC565
-//---------------------------------------------------------------------------
-#elif __MWERKS__
-
-#ifdef __MC68K__
-
-#define TARGET_SYSTEM = _MCF548X_
-#define DEV_SYSTEM _DEV_MCW_MCF5XXX_
-
-#else
-#define TARGET_SYSTEM = _MPC565_
-#define DEV_SYSTEM _DEV_MCW_MPC5X5_
-#endif
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define HWACC // hardware access through external memory (i.e. CAN)
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for BECK 1x3
-//---------------------------------------------------------------------------
-#elif defined (__BORLANDC__) && defined (__PARADIGM__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_PAR_BECK1X3_
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-#define NEAR __near // variables mapped to internal data storage location
-#define FAR __far // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#ifndef TRACE
-#include <stdio.h>
-#define TRACE printf
-#endif
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for PC
-//---------------------------------------------------------------------------
-
-#elif defined (__BORLANDC__)
-
- // ------------------ definition target system --------------------------
-
-#ifdef _WIN32
-#define TARGET_SYSTEM _WIN32_ // WIN32 definition
-#define DEV_SYSTEM _DEV_WIN32_
-#else
-#define TARGET_SYSTEM _DOS_
-#define DEV_SYSTEM _DEV_BORLAND_DOS_
-#endif
-
- // ------------------ WIN32 ---------------------------------------------
-
-#if (TARGET_SYSTEM == _WIN32_)
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR // variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC __stdcall
-
-#ifndef NDEBUG
-#ifndef TRACE
-#include <stdio.h>
-#define TRACE printf
-#endif
-#endif
-
-#elif (TARGET_SYSTEM == _DOS_)
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-#define NEAR near // variables mapped to internal data storage location
-#define FAR far // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-#ifndef NDEBUG
-#ifndef TRACE
-#include <stdio.h>
-#define TRACE printf
-#endif
-#endif
-
-#endif
-
-#elif (_MSC_VER == 800) // PC MS Visual C/C++ for DOS applications
-
-#define TARGET_SYSTEM _DOS_
-#define DEV_SYSTEM _DEV_MSVC_DOS_
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC near // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-#define NEAR near // variables mapped to internal data storage location
-#define FAR far // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#ifndef TRACE
-#include <stdio.h>
-#define TRACE printf
-#endif
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for RTX under WIN32
-//---------------------------------------------------------------------------
-#elif (defined (UNDER_RTSS) && defined (WIN32))
-
- // ------------------ definition target system --------------------------
-#define TARGET_SYSTEM _WIN32_RTX_
-#define DEV_SYSTEM _DEV_WIN32_RTX_
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR // variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC __stdcall
-
-#ifndef NDEBUG
-#ifndef TRACE
-#define TRACE RtPrintf
-#endif
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for WinCE
-//---------------------------------------------------------------------------
-#elif defined (_WIN32_WCE)
-
- // ------------------ definition target system --------------------------
-#define TARGET_SYSTEM _WINCE_
-#define DEV_SYSTEM _DEV_WIN_CE_
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR // variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#ifndef QWORD
- //#define QWORD long long int // MSVC .NET can use "long long int" too (like GNU)
-#define QWORD __int64
-#endif
-
-#define REENTRANT
-#define PUBLIC __cdecl
-
-#ifdef ASSERTMSG
-#undef ASSERTMSG
-#endif
-
-#ifndef NDEBUG
-#ifndef TRACE
-#define TRACE printf
-// void trace (char *fmt, ...);
-#endif
-#endif
-
-#else // ===> PC MS Visual C/C++
-
- // ------------------ definition target system --------------------------
-
-#ifdef _WIN32
-#define TARGET_SYSTEM _WIN32_ // WIN32 definition
-#define DEV_SYSTEM _DEV_WIN32_
-#else
-#define TARGET_SYSTEM _WIN16_ // WIN16 definition
-#define DEV_SYSTEM _DEV_WIN16_
-#endif
-
- // ------------------ WIN16 ---------------------------------------------
-
-#if (TARGET_SYSTEM == _WIN16_)
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR far // variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC _far _pascal _export
-
-#ifndef NDEBUG
-#ifndef TRACE
-#define TRACE trace
-#ifdef __cplusplus
-extern "C" {
-#endif
- void trace(const char *fmt, ...);
-#ifdef __cplusplus
-}
-#endif
-#endif
-#endif
-#endif
- // ------------------ WIN32 ---------------------------------------------
-#if (TARGET_SYSTEM == _WIN32_)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
- // These types can be adjusted by users to match application requirements. The goal is to// minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external// or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-#ifndef FAR
-#define FAR // variables mapped to external data storage location
-#endif
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-#define LARGE
-#define REENTRANT
-#define PUBLIC __stdcall
-#ifndef QWORD
- //#define QWORD long long int // MSVC .NET can use "long long int" too (like GNU)
-#define QWORD __int64
-#endif
-#ifndef NDEBUG
-#ifndef TRACE
-#define TRACE trace
-#ifdef __cplusplus
-extern "C" {
-#endif
- void trace(const char *fmt, ...);
-#ifdef __cplusplus
-}
-#endif
-#endif
-#endif
- // MS Visual C++ compiler supports function inlining
-#define INLINE_FUNCTION_DEF __forceinline
- // to actually enable inlining just include the following two lines// #define INLINE_FUNCTION INLINE_FUNCTION_DEF// #define INLINE_ENABLED TRUE
-#endif
-#endif // ===> PC
-//---------------------------------------------------------------------------// definitions of basic types//---------------------------------------------------------------------------
-#ifndef _WINDEF_ // defined in WINDEF.H, included by <windows.h>
- // --- arithmetic types ---
-#ifndef SHORT
-#define SHORT short int
-#endif
-#ifndef USHORT
-#define USHORT unsigned short int
-#endif
-#ifndef INT
-#define INT int
-#endif
-#ifndef UINT
-#define UINT unsigned int
-#endif
-#ifndef LONG
-#define LONG long int
-#endif
-#ifndef ULONG
-#define ULONG unsigned long int
-#endif
- // --- logic types ---
-#ifndef BYTE
-#define BYTE unsigned char
-#endif
-#ifndef WORD
-#define WORD unsigned short int
-#endif
-#ifndef DWORD
-#define DWORD unsigned long int
-#endif
+// --- logic types ---
#ifndef BOOL
#define BOOL unsigned char
#endif
- // --- alias types ---
+
+// --- alias types ---
#ifndef TRUE
#define TRUE 0xFF
#endif
#ifndef FALSE
#define FALSE 0x00
#endif
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-#endif
#ifndef _TIME_OF_DAY_DEFINED_
typedef struct {
unsigned long int m_dwMs;
@@ -1359,15 +119,8 @@ typedef struct {
//---------------------------------------------------------------------------
#ifndef ASSERT
-#if !defined (__linux__) && !defined (__KERNEL__)
-#include <assert.h>
-#ifndef ASSERT
-#define ASSERT(p) assert(p)
-#endif
-#else
#define ASSERT(p)
#endif
-#endif
//---------------------------------------------------------------------------
// SYS TEC extensions
diff --git a/drivers/staging/epl/kernel/EplDllk.h b/drivers/staging/epl/kernel/EplDllk.h
index 588e871a922..a97920ab884 100644
--- a/drivers/staging/epl/kernel/EplDllk.h
+++ b/drivers/staging/epl/kernel/EplDllk.h
@@ -74,18 +74,10 @@
#include "../EplDll.h"
#include "../EplEvent.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
typedef tEplKernel(*tEplDllkCbAsync) (tEplFrameInfo * pFrameInfo_p);
typedef struct {
- BYTE m_be_abSrcMac[6];
+ u8 m_be_abSrcMac[6];
} tEplDllkInitParam;
@@ -96,22 +88,18 @@ struct _tEplDllkNodeInfo {
struct _tEplDllkNodeInfo *m_pNextNodeInfo;
struct _tEdrvTxBuffer *m_pPreqTxBuffer;
unsigned int m_uiNodeId;
- DWORD m_dwPresTimeout;
+ u32 m_dwPresTimeout;
unsigned long m_ulDllErrorEvents;
tEplNmtState m_NmtState;
- WORD m_wPresPayloadLimit;
- BYTE m_be_abMacAddr[6];
- BYTE m_bSoaFlag1;
+ u16 m_wPresPayloadLimit;
+ u8 m_be_abMacAddr[6];
+ u8 m_bSoaFlag1;
BOOL m_fSoftDelete; // delete node after error and ignore error
};
typedef struct _tEplDllkNodeInfo tEplDllkNodeInfo;
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
tEplKernel EplDllkAddInstance(tEplDllkInitParam * pInitParam_p);
@@ -154,7 +142,7 @@ tEplKernel EplDllkDeleteNode(unsigned int uiNodeId_p);
tEplKernel EplDllkSoftDeleteNode(unsigned int uiNodeId_p);
-tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, BYTE bSoaFlag1_p);
+tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, u8 bSoaFlag1_p);
tEplKernel EplDllkGetFirstNodeInfo(tEplDllkNodeInfo ** ppNodeInfo_p);
diff --git a/drivers/staging/epl/kernel/EplDllkCal.h b/drivers/staging/epl/kernel/EplDllkCal.h
index 6c4dc7e4a80..ddec1d5e8cc 100644
--- a/drivers/staging/epl/kernel/EplDllkCal.h
+++ b/drivers/staging/epl/kernel/EplDllkCal.h
@@ -74,14 +74,6 @@
#include "../EplDll.h"
#include "../EplEvent.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
typedef struct {
unsigned long m_ulCurTxFrameCountGen;
unsigned long m_ulCurTxFrameCountNmt;
@@ -92,10 +84,6 @@ typedef struct {
} tEplDllkCalStatistics;
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
tEplKernel EplDllkCalAddInstance(void);
@@ -124,7 +112,7 @@ tEplKernel EplDllkCalProcess(tEplEvent * pEvent_p);
tEplKernel EplDllkCalAsyncClearQueues(void);
tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p,
- unsigned int uiNodeId_p, BYTE bSoaFlag1_p);
+ unsigned int uiNodeId_p, u8 bSoaFlag1_p);
tEplKernel EplDllkCalAsyncGetSoaRequest(tEplDllReqServiceId * pReqServiceId_p,
unsigned int *puiNodeId_p);
diff --git a/drivers/staging/epl/kernel/EplErrorHandlerk.h b/drivers/staging/epl/kernel/EplErrorHandlerk.h
index 4a67ef88b97..185b597d6e5 100644
--- a/drivers/staging/epl/kernel/EplErrorHandlerk.h
+++ b/drivers/staging/epl/kernel/EplErrorHandlerk.h
@@ -73,28 +73,16 @@
#include "../EplEvent.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
// init function
-tEplKernel PUBLIC EplErrorHandlerkInit(void);
+tEplKernel EplErrorHandlerkInit(void);
// add instance
-tEplKernel PUBLIC EplErrorHandlerkAddInstance(void);
+tEplKernel EplErrorHandlerkAddInstance(void);
// delete instance
-tEplKernel PUBLIC EplErrorHandlerkDelInstance(void);
+tEplKernel EplErrorHandlerkDelInstance(void);
// processes error events
-tEplKernel PUBLIC EplErrorHandlerkProcess(tEplEvent * pEvent_p);
+tEplKernel EplErrorHandlerkProcess(tEplEvent *pEvent_p);
#endif // #ifndef _EPL_ERRORHANDLERK_H_
diff --git a/drivers/staging/epl/kernel/EplEventk.h b/drivers/staging/epl/kernel/EplEventk.h
index 1d25aaa2ed4..0c2a60f7207 100644
--- a/drivers/staging/epl/kernel/EplEventk.h
+++ b/drivers/staging/epl/kernel/EplEventk.h
@@ -73,36 +73,24 @@
#include "../EplEvent.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
// init function
-tEplKernel PUBLIC EplEventkInit(tEplSyncCb fpSyncCb);
+tEplKernel EplEventkInit(tEplSyncCb fpSyncCb);
// add instance
-tEplKernel PUBLIC EplEventkAddInstance(tEplSyncCb fpSyncCb);
+tEplKernel EplEventkAddInstance(tEplSyncCb fpSyncCb);
// delete instance
-tEplKernel PUBLIC EplEventkDelInstance(void);
+tEplKernel EplEventkDelInstance(void);
// Kernelthread that dispatches events in kernelspace
-tEplKernel PUBLIC EplEventkProcess(tEplEvent * pEvent_p);
+tEplKernel EplEventkProcess(tEplEvent *pEvent_p);
// post events from kernelspace
-tEplKernel PUBLIC EplEventkPost(tEplEvent * pEvent_p);
+tEplKernel EplEventkPost(tEplEvent *pEvent_p);
// post errorevents from kernelspace
-tEplKernel PUBLIC EplEventkPostError(tEplEventSource EventSource_p,
- tEplKernel EplError_p,
- unsigned int uiArgSize_p, void *pArg_p);
+tEplKernel EplEventkPostError(tEplEventSource EventSource_p,
+ tEplKernel EplError_p,
+ unsigned int uiArgSize_p, void *pArg_p);
#endif // #ifndef _EPL_EVENTK_H_
diff --git a/drivers/staging/epl/kernel/EplNmtk.h b/drivers/staging/epl/kernel/EplNmtk.h
index 53409cc8992..5dc8a373159 100644
--- a/drivers/staging/epl/kernel/EplNmtk.h
+++ b/drivers/staging/epl/kernel/EplNmtk.h
@@ -74,31 +74,16 @@
#include "../EplNmt.h"
#include "EplEventk.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+tEplKernel EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR);
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+tEplKernel EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+tEplKernel EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- tEplEvent * pEvent_p);
+tEplKernel EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplEvent *pEvent_p);
-EPLDLLEXPORT tEplNmtState PUBLIC
-EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+tEplNmtState EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR);
#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
diff --git a/drivers/staging/epl/kernel/EplNmtkCal.h b/drivers/staging/epl/kernel/EplNmtkCal.h
deleted file mode 100644
index 9edeafca492..00000000000
--- a/drivers/staging/epl/kernel/EplNmtkCal.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: openPOWERLINK
-
- Description: include file for communication abstraction layer of the
- NMT-Kernel-Module
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS 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.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- $RCSfile: EplNmtkCal.h,v $
-
- $Author: D.Krueger $
-
- $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $
-
- $State: Exp $
-
- Build Environment:
- KEIL uVision 2
-
- -------------------------------------------------------------------------
-
- Revision History:
-
- 2006/06/16 -k.t.: start of the implementation
-
-****************************************************************************/
-
-#include "EplNmtk.h"
-
-#ifndef _EPLNMTKCAL_H_
-#define _EPLNMTKCAL_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPLNMTKCAL_H_
diff --git a/drivers/staging/epl/kernel/EplObdk.h b/drivers/staging/epl/kernel/EplObdk.h
index cf9f5837dd3..78c4d961342 100644
--- a/drivers/staging/epl/kernel/EplObdk.h
+++ b/drivers/staging/epl/kernel/EplObdk.h
@@ -68,128 +68,88 @@
****************************************************************************/
-#include "../EplObd.h"
-
#ifndef _EPLOBDK_H_
#define _EPLOBDK_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// global variables
-//---------------------------------------------------------------------------
+#include "../EplObd.h"
-extern BYTE MEM abEplObdTrashObject_g[8];
+extern u8 abEplObdTrashObject_g[8];
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- tEplObdInitParam MEM * pInitParam_p);
+tEplKernel EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- tEplObdInitParam MEM *
- pInitParam_p);
+tEplKernel EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR);
+tEplKernel EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p);
+tEplKernel EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p);
+tEplKernel EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p, tEplObdSize *pSize_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdStoreLoadObjCallback fpCallback_p);
+tEplKernel EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdPart ObdPart_p,
- tEplObdDir Direction_p);
+tEplKernel EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p,
+ tEplObdDir Direction_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_
- tEplVarParam MEM * pVarParam_p);
+tEplKernel EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam *pVarParam_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p);
+void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdEntryPtr pUserOd_p);
+tEplKernel EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdVarEntry MEM * pVarEntry_p,
- tEplObdType Type_p,
- tEplObdSize ObdSize_p);
+void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry *pVarEntry_p,
+ tEplObdType Type_p, tEplObdSize ObdSize_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p);
+tEplObdSize EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR);
+unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdSetNodeId(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiNodeId_p,
- tEplObdNodeIdType NodeIdType_p);
+tEplKernel EplObdSetNodeId(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiNodeId_p,
+ tEplObdNodeIdType NodeIdType_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- BOOL * pfEntryNumerical);
+tEplKernel EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p, BOOL *pfEntryNumerical);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p);
+tEplKernel EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p,
+ tEplObdSize Size_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p);
+tEplKernel EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p,
+ tEplObdSize *pSize_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- tEplObdAccess *
- pAccessTyp_p);
+tEplKernel EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ tEplObdAccess *pAccessTyp_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- tEplObdVarEntry MEM **
- ppVarEntry_p);
+tEplKernel EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ tEplObdVarEntry **ppVarEntry_p);
#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
diff --git a/drivers/staging/epl/kernel/EplObdkCal.h b/drivers/staging/epl/kernel/EplObdkCal.h
deleted file mode 100644
index c173a950054..00000000000
--- a/drivers/staging/epl/kernel/EplObdkCal.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: openPOWERLINK
-
- Description: include file for communication abstraction layer
- for the Epl-Obd-Kernelspace-Modul
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS 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.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- $RCSfile: EplObdkCal.h,v $
-
- $Author: D.Krueger $
-
- $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $
-
- $State: Exp $
-
- Build Environment:
- GCC V3.4
-
- -------------------------------------------------------------------------
-
- Revision History:
-
- 2006/06/19 k.t.: start of the implementation
-
-****************************************************************************/
-
-#include "../EplObd.h"
-
-#ifndef _EPLOBDKCAL_H_
-#define _EPLOBDKCAL_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPLOBDKCAL_H_
diff --git a/drivers/staging/epl/kernel/EplPdok.h b/drivers/staging/epl/kernel/EplPdok.h
index b5b18f4cf68..24bfc3f73e9 100644
--- a/drivers/staging/epl/kernel/EplPdok.h
+++ b/drivers/staging/epl/kernel/EplPdok.h
@@ -75,18 +75,6 @@
#include "../EplEvent.h"
#include "../EplDll.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
// process events from queue (PDOs/frames and SoA for synchronization)
tEplKernel EplPdokProcess(tEplEvent * pEvent_p);
diff --git a/drivers/staging/epl/kernel/EplPdokCal.h b/drivers/staging/epl/kernel/EplPdokCal.h
index 6a183ebe81e..8a31edfdb4f 100644
--- a/drivers/staging/epl/kernel/EplPdokCal.h
+++ b/drivers/staging/epl/kernel/EplPdokCal.h
@@ -72,19 +72,6 @@
#define _EPL_PDOKCAL_H_
#include "../EplInc.h"
-//#include "EplPdo.h"
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
tEplKernel EplPdokCalAddInstance(void);
diff --git a/drivers/staging/epl/kernel/EplTimerHighResk.h b/drivers/staging/epl/kernel/EplTimerHighResk.h
index d5d046d4d37..a2124ee49f7 100644
--- a/drivers/staging/epl/kernel/EplTimerHighResk.h
+++ b/drivers/staging/epl/kernel/EplTimerHighResk.h
@@ -68,42 +68,29 @@
****************************************************************************/
-#include "../EplTimer.h"
-
#ifndef _EPLTIMERHIGHRESK_H_
#define _EPLTIMERHIGHRESK_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+#include "../EplTimer.h"
-tEplKernel PUBLIC EplTimerHighReskInit(void);
+tEplKernel EplTimerHighReskInit(void);
-tEplKernel PUBLIC EplTimerHighReskAddInstance(void);
+tEplKernel EplTimerHighReskAddInstance(void);
-tEplKernel PUBLIC EplTimerHighReskDelInstance(void);
+tEplKernel EplTimerHighReskDelInstance(void);
-tEplKernel PUBLIC EplTimerHighReskSetTimerNs(tEplTimerHdl * pTimerHdl_p,
- unsigned long long ullTimeNs_p,
- tEplTimerkCallback pfnCallback_p,
- unsigned long ulArgument_p,
- BOOL fContinuously_p);
+tEplKernel EplTimerHighReskSetTimerNs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long long ullTimeNs_p,
+ tEplTimerkCallback pfnCallback_p,
+ unsigned long ulArgument_p,
+ BOOL fContinuously_p);
-tEplKernel PUBLIC EplTimerHighReskModifyTimerNs(tEplTimerHdl * pTimerHdl_p,
- unsigned long long ullTimeNs_p,
- tEplTimerkCallback
- pfnCallback_p,
- unsigned long ulArgument_p,
- BOOL fContinuously_p);
+tEplKernel EplTimerHighReskModifyTimerNs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long long ullTimeNs_p,
+ tEplTimerkCallback pfnCallback_p,
+ unsigned long ulArgument_p,
+ BOOL fContinuously_p);
-tEplKernel PUBLIC EplTimerHighReskDeleteTimer(tEplTimerHdl * pTimerHdl_p);
+tEplKernel EplTimerHighReskDeleteTimer(tEplTimerHdl *pTimerHdl_p);
#endif // #ifndef _EPLTIMERHIGHRESK_H_
diff --git a/drivers/staging/epl/kernel/EplTimerk.h b/drivers/staging/epl/kernel/EplTimerk.h
index 9160e7260de..47c5f47b8aa 100644
--- a/drivers/staging/epl/kernel/EplTimerk.h
+++ b/drivers/staging/epl/kernel/EplTimerk.h
@@ -68,19 +68,16 @@
****************************************************************************/
-#include "../EplTimer.h"
-#include "../user/EplEventu.h"
-
#ifndef _EPLTIMERK_H_
#define _EPLTIMERK_H_
+#include "../EplTimer.h"
+#include "../user/EplEventu.h"
+
#if EPL_TIMER_USE_USER != FALSE
#include "../user/EplTimeru.h"
#endif
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
#if EPL_TIMER_USE_USER != FALSE
#define EplTimerkInit EplTimeruInit
@@ -91,28 +88,21 @@
#define EplTimerkDeleteTimer EplTimeruDeleteTimer
#endif
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
#if EPL_TIMER_USE_USER == FALSE
-tEplKernel PUBLIC EplTimerkInit(void);
+tEplKernel EplTimerkInit(void);
-tEplKernel PUBLIC EplTimerkAddInstance(void);
+tEplKernel EplTimerkAddInstance(void);
-tEplKernel PUBLIC EplTimerkDelInstance(void);
+tEplKernel EplTimerkDelInstance(void);
-tEplKernel PUBLIC EplTimerkSetTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p);
+tEplKernel EplTimerkSetTimerMs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long ulTime_p,
+ tEplTimerArg Argument_p);
-tEplKernel PUBLIC EplTimerkModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p);
+tEplKernel EplTimerkModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long ulTime_p,
+ tEplTimerArg Argument_p);
-tEplKernel PUBLIC EplTimerkDeleteTimer(tEplTimerHdl * pTimerHdl_p);
+tEplKernel EplTimerkDeleteTimer(tEplTimerHdl *pTimerHdl_p);
#endif
#endif // #ifndef _EPLTIMERK_H_
diff --git a/drivers/staging/epl/kernel/VirtualEthernet.h b/drivers/staging/epl/kernel/VirtualEthernet.h
index deff8720e37..4a42cce66ca 100644
--- a/drivers/staging/epl/kernel/VirtualEthernet.h
+++ b/drivers/staging/epl/kernel/VirtualEthernet.h
@@ -73,23 +73,11 @@
#include "EplDllk.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
-tEplKernel PUBLIC VEthAddInstance(tEplDllkInitParam * pInitParam_p);
+tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p);
-tEplKernel PUBLIC VEthDelInstance(void);
+tEplKernel VEthDelInstance(void);
#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
diff --git a/drivers/staging/epl/proc_fs.c b/drivers/staging/epl/proc_fs.c
index f4910332d3c..9ccf079e67e 100644
--- a/drivers/staging/epl/proc_fs.c
+++ b/drivers/staging/epl/proc_fs.c
@@ -83,7 +83,6 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/major.h>
-#include <linux/version.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
@@ -95,6 +94,8 @@
#include "fec.h"
#endif
+#include "proc_fs.h"
+
/***************************************************************************/
/* */
/* */
@@ -129,8 +130,8 @@
#ifdef _DBG_TRACE_POINTS_
atomic_t aatmDbgTracePoint_l[DBG_TRACE_POINTS];
-DWORD adwDbgTraceValue_l[DBG_TRACE_VALUES];
-DWORD dwDbgTraceValueOld_l;
+u32 adwDbgTraceValue_l[DBG_TRACE_VALUES];
+u32 dwDbgTraceValueOld_l;
unsigned int uiDbgTraceValuePos_l;
spinlock_t spinlockDbgTraceValue_l;
unsigned long ulDbTraceValueFlags_l;
@@ -145,10 +146,10 @@ static int EplLinProcRead(char *pcBuffer_p, char **ppcStart_p, off_t Offset_p,
static int EplLinProcWrite(struct file *file, const char __user * buffer,
unsigned long count, void *data);
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
-EPLDLLEXPORT DWORD PUBLIC EplIdentuGetRunningRequests(void);
+extern u32 EplIdentuGetRunningRequests(void);
//=========================================================================//
// //
@@ -191,7 +192,7 @@ tEplKernel EplLinProcFree(void)
//---------------------------------------------------------------------------
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p)
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p)
{
if (bTracePointNumber_p >=
@@ -207,7 +208,7 @@ void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p)
}
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p)
+void TgtDbgPostTraceValue(u32 dwTraceValue_p)
{
spin_lock_irqsave(&spinlockDbgTraceValue_l, ulDbTraceValueFlags_l);
@@ -263,7 +264,7 @@ static int EplLinProcRead(char *pcBuffer_p,
// ---- EPL state ----
nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
"NMT state: 0x%04X\n",
- (WORD) EplNmtkGetNmtState());
+ (u16) EplNmtkGetNmtState());
EplDllkCalGetStatistics(&pDllkCalStats);
@@ -279,14 +280,14 @@ static int EplLinProcRead(char *pcBuffer_p,
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
// fetch running IdentRequests
nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
- "running IdentRequests: 0x%08lX\n",
+ "running IdentRequests: 0x%08X\n",
EplIdentuGetRunningRequests());
// fetch state of NmtMnu module
{
unsigned int uiMandatorySlaveCount;
unsigned int uiSignalSlaveCount;
- WORD wFlags;
+ u16 wFlags;
EplNmtMnuGetDiagnosticInfo(&uiMandatorySlaveCount,
&uiSignalSlaveCount, &wFlags);
diff --git a/drivers/staging/epl/user/EplCfgMau.h b/drivers/staging/epl/user/EplCfgMau.h
index d25a1e9d36c..4ac770f1310 100644
--- a/drivers/staging/epl/user/EplCfgMau.h
+++ b/drivers/staging/epl/user/EplCfgMau.h
@@ -69,25 +69,22 @@
****************************************************************************/
-#include "../EplInc.h"
-
#ifndef _EPLCFGMA_H_
#define _EPLCFGMA_H_
+#include "../EplInc.h"
+
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0)
#include "EplObdu.h"
#include "EplSdoComu.h"
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
//define max number of timeouts for configuration of 1 device
#define EPL_CFGMA_MAX_TIMEOUT 3
//callbackfunction, called if configuration is finished
-typedef void (PUBLIC * tfpEplCfgMaCb) (unsigned int uiNodeId_p,
- tEplKernel Errorstate_p);
+typedef void (* tfpEplCfgMaCb)(unsigned int uiNodeId_p,
+ tEplKernel Errorstate_p);
//State for configuartion manager Statemachine
typedef enum {
@@ -131,33 +128,29 @@ typedef enum {
typedef struct {
tEplCfgState m_CfgState; // state of the configuration state maschine
tEplSdoComConHdl m_SdoComConHdl; // handle for sdo connection
- DWORD m_dwLastAbortCode;
+ u32 m_dwLastAbortCode;
unsigned int m_uiLastIndex; // last index of configuration, to compair with actual index
- BYTE *m_pbConcise; // Ptr to concise DCF
- BYTE *m_pbActualIndex; // Ptr to actual index in the DCF segment
+ u8 *m_pbConcise; // Ptr to concise DCF
+ u8 *m_pbActualIndex; // Ptr to actual index in the DCF segment
tfpEplCfgMaCb m_pfnCfgMaCb; // Ptr to CfgMa Callback, is call if configuration finished
tEplKernel m_EplKernelError; // errorcode
- DWORD m_dwNumValueCopy; // numeric values are copied in this variable
+ u32 m_dwNumValueCopy; // numeric values are copied in this variable
unsigned int m_uiPdoNodeId; // buffer for PDO node id
- BYTE m_bNrOfMappedObject; // number of mapped objects
+ u8 m_bNrOfMappedObject; // number of mapped objects
unsigned int m_uiNodeId; // Epl node addresse
tEplSdocState m_SdocState; // bitcoded state of the SDO transfer
unsigned int m_uiLastSubIndex; // last subindex of configuration
BOOL m_fOneTranferOk; // atleased one transfer was successful
- BYTE m_bEventFlag; // for Eventsignaling to the State Maschine
- DWORD m_dwCntObjectInDcf; // number of Objects in DCF
+ u8 m_bEventFlag; // for Eventsignaling to the State Maschine
+ u32 m_dwCntObjectInDcf; // number of Objects in DCF
tEplCfgMaIndexType m_SkipCfg; // TRUE if a adsitional Configurationprocess
// have to insert e.g. PDO-mapping
- WORD m_wTimeOutCnt; // Timeout Counter, break configuration is
+ u16 m_wTimeOutCnt; // Timeout Counter, break configuration is
// m_wTimeOutCnt == CFGMA_MAX_TIMEOUT
} tEplCfgMaNode;
//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
// Function: EplCfgMaInit()
//
// Description: Function creates first instance of Configuration Manager
@@ -166,7 +159,7 @@ typedef struct {
//
// Returns: tEplKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaInit();
+tEplKernel EplCfgMaInit(void);
//---------------------------------------------------------------------------
// Function: EplCfgMaAddInstance()
@@ -177,7 +170,7 @@ tEplKernel PUBLIC EplCfgMaInit();
//
// Returns: tEplKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaAddInstance();
+tEplKernel EplCfgMaAddInstance(void);
//---------------------------------------------------------------------------
// Function: EplCfgMaDelInstance()
@@ -188,7 +181,7 @@ tEplKernel PUBLIC EplCfgMaAddInstance();
//
// Returns: tEplKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaDelInstance();
+tEplKernel plCfgMaDelInstance(void);
//---------------------------------------------------------------------------
// Function: EplCfgMaStartConfig()
@@ -199,16 +192,16 @@ tEplKernel PUBLIC EplCfgMaDelInstance();
// Parameters: uiNodeId_p = NodeId of the node to configure
// pbConcise_p = pointer to DCF
// fpCfgMaCb_p = pointer to callback function (should not be NULL)
-// SizeOfConcise_p = size of DCF in BYTE -> for future use
+// SizeOfConcise_p = size of DCF in u8 -> for future use
// DcfType_p = type of the DCF
//
// Returns: tCopKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaStartConfig(unsigned int uiNodeId_p,
- BYTE * pbConcise_p,
- tfpEplCfgMaCb fpCfgMaCb_p,
- tEplObdSize SizeOfConcise_p,
- tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaStartConfig(unsigned int uiNodeId_p,
+ u8 * pbConcise_p,
+ tfpEplCfgMaCb fpCfgMaCb_p,
+ tEplObdSize SizeOfConcise_p,
+ tEplCfgMaDcfTyp DcfType_p);
//---------------------------------------------------------------------------
// Function: CfgMaStartConfigurationNode()
@@ -222,9 +215,9 @@ tEplKernel PUBLIC EplCfgMaStartConfig(unsigned int uiNodeId_p,
//
// Returns: tCopKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaStartConfigNode(unsigned int uiNodeId_p,
- tfpEplCfgMaCb fpCfgMaCb_p,
- tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaStartConfigNode(unsigned int uiNodeId_p,
+ tfpEplCfgMaCb fpCfgMaCb_p,
+ tEplCfgMaDcfTyp DcfType_p);
//---------------------------------------------------------------------------
// Function: EplCfgMaStartConfigNodeDcf()
@@ -235,16 +228,16 @@ tEplKernel PUBLIC EplCfgMaStartConfigNode(unsigned int uiNodeId_p,
// Parameters: uiNodeId_p = NodeId of the node to configure
// pbConcise_p = pointer to DCF
// fpCfgMaCb_p = pointer to callback function (should not be NULL)
-// SizeOfConcise_p = size of DCF in BYTE -> for future use
+// SizeOfConcise_p = size of DCF in u8 -> for future use
// DcfType_p = type of the DCF
//
// Returns: tCopKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaStartConfigNodeDcf(unsigned int uiNodeId_p,
- BYTE * pbConcise_p,
- tfpEplCfgMaCb fpCfgMaCb_p,
- tEplObdSize SizeOfConcise_p,
- tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaStartConfigNodeDcf(unsigned int uiNodeId_p,
+ u8 * pbConcise_p,
+ tfpEplCfgMaCb fpCfgMaCb_p,
+ tEplObdSize SizeOfConcise_p,
+ tEplCfgMaDcfTyp DcfType_p);
//---------------------------------------------------------------------------
// Function: EplCfgMaLinkDcf()
@@ -253,15 +246,15 @@ tEplKernel PUBLIC EplCfgMaStartConfigNodeDcf(unsigned int uiNodeId_p,
//
// Parameters: uiNodeId_p = NodeId of the node to configure
// pbConcise_p = pointer to DCF
-// SizeOfConcise_p = size of DCF in BYTE -> for future use
+// SizeOfConcise_p = size of DCF in u8 -> for future use
// DcfType_p = type of the DCF
//
// Returns: tCopKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaLinkDcf(unsigned int uiNodeId_p,
- BYTE * pbConcise_p,
- tEplObdSize SizeOfConcise_p,
- tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaLinkDcf(unsigned int uiNodeId_p,
+ u8 * pbConcise_p,
+ tEplObdSize SizeOfConcise_p,
+ tEplCfgMaDcfTyp DcfType_p);
//---------------------------------------------------------------------------
// Function: EplCfgMaCheckDcf()
@@ -274,8 +267,7 @@ tEplKernel PUBLIC EplCfgMaLinkDcf(unsigned int uiNodeId_p,
//
// Returns: tCopKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaCheckDcf(unsigned int uiNodeId_p,
- tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaCheckDcf(unsigned int uiNodeId_p, tEplCfgMaDcfTyp DcfType_p);
#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0)
diff --git a/drivers/staging/epl/user/EplDllu.h b/drivers/staging/epl/user/EplDllu.h
index 36f8bb76f7c..890f83759ca 100644
--- a/drivers/staging/epl/user/EplDllu.h
+++ b/drivers/staging/epl/user/EplDllu.h
@@ -73,19 +73,7 @@
#include "../EplDll.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef tEplKernel(PUBLIC * tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
diff --git a/drivers/staging/epl/user/EplDlluCal.h b/drivers/staging/epl/user/EplDlluCal.h
index b1dcd060957..bc9126b1627 100644
--- a/drivers/staging/epl/user/EplDlluCal.h
+++ b/drivers/staging/epl/user/EplDlluCal.h
@@ -74,19 +74,8 @@
#include "../EplDll.h"
#include "../EplEvent.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef tEplKernel(PUBLIC * tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
tEplKernel EplDlluCalAddInstance(void);
@@ -110,7 +99,7 @@ tEplKernel EplDlluCalDeleteNode(unsigned int uiNodeId_p);
tEplKernel EplDlluCalSoftDeleteNode(unsigned int uiNodeId_p);
tEplKernel EplDlluCalIssueRequest(tEplDllReqServiceId Service_p,
- unsigned int uiNodeId_p, BYTE bSoaFlag1_p);
+ unsigned int uiNodeId_p, u8 bSoaFlag1_p);
#endif
diff --git a/drivers/staging/epl/user/EplEventu.h b/drivers/staging/epl/user/EplEventu.h
index 322cffd1187..ab85205b239 100644
--- a/drivers/staging/epl/user/EplEventu.h
+++ b/drivers/staging/epl/user/EplEventu.h
@@ -73,36 +73,24 @@
#include "../EplEvent.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
// init function
-tEplKernel PUBLIC EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p);
+tEplKernel EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p);
// add instance
-tEplKernel PUBLIC EplEventuAddInstance(tEplProcessEventCb
- pfnApiProcessEventCb_p);
+tEplKernel EplEventuAddInstance(tEplProcessEventCb pfnApiProcessEventCb_p);
// delete instance
-tEplKernel PUBLIC EplEventuDelInstance(void);
+tEplKernel EplEventuDelInstance(void);
// Task that dispatches events in userspace
-tEplKernel PUBLIC EplEventuProcess(tEplEvent * pEvent_p);
+tEplKernel EplEventuProcess(tEplEvent * pEvent_p);
// post events from userspace
-tEplKernel PUBLIC EplEventuPost(tEplEvent * pEvent_p);
+tEplKernel EplEventuPost(tEplEvent * pEvent_p);
// post errorevents from userspace
-tEplKernel PUBLIC EplEventuPostError(tEplEventSource EventSource_p,
- tEplKernel EplError_p,
- unsigned int uiArgSize_p, void *pArg_p);
+tEplKernel EplEventuPostError(tEplEventSource EventSource_p,
+ tEplKernel EplError_p,
+ unsigned int uiArgSize_p, void *pArg_p);
#endif // #ifndef _EPL_EVENTU_H_
diff --git a/drivers/staging/epl/user/EplIdentu.h b/drivers/staging/epl/user/EplIdentu.h
index e7302106c74..057c9029e98 100644
--- a/drivers/staging/epl/user/EplIdentu.h
+++ b/drivers/staging/epl/user/EplIdentu.h
@@ -68,41 +68,27 @@
****************************************************************************/
-#include "../EplDll.h"
-
#ifndef _EPLIDENTU_H_
#define _EPLIDENTU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+#include "../EplDll.h"
-typedef tEplKernel(PUBLIC * tEplIdentuCbResponse) (unsigned int uiNodeId_p,
+typedef tEplKernel(* tEplIdentuCbResponse) (unsigned int uiNodeId_p,
tEplIdentResponse *
pIdentResponse_p);
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-tEplKernel PUBLIC EplIdentuInit(void);
+tEplKernel EplIdentuInit(void);
-tEplKernel PUBLIC EplIdentuAddInstance(void);
+tEplKernel EplIdentuAddInstance(void);
-tEplKernel PUBLIC EplIdentuDelInstance(void);
+tEplKernel EplIdentuDelInstance(void);
-tEplKernel PUBLIC EplIdentuReset(void);
+tEplKernel EplIdentuReset(void);
-tEplKernel PUBLIC EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
- tEplIdentResponse **
- ppIdentResponse_p);
+tEplKernel EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentResponse **ppIdentResponse_p);
-tEplKernel PUBLIC EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
- tEplIdentuCbResponse
- pfnCbResponse_p);
+tEplKernel EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentuCbResponse pfnCbResponse_p);
#endif // #ifndef _EPLIDENTU_H_
diff --git a/drivers/staging/epl/user/EplLedu.h b/drivers/staging/epl/user/EplLedu.h
index 78e70d06445..ca9eb431100 100644
--- a/drivers/staging/epl/user/EplLedu.h
+++ b/drivers/staging/epl/user/EplLedu.h
@@ -68,41 +68,27 @@
****************************************************************************/
-#include "../EplLed.h"
-#include "../EplNmt.h"
-#include "EplEventu.h"
-
#ifndef _EPLLEDU_H_
#define _EPLLEDU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+#include "../EplLed.h"
+#include "../EplNmt.h"
+#include "EplEventu.h"
-typedef tEplKernel(PUBLIC * tEplLeduStateChangeCallback) (tEplLedType LedType_p,
+typedef tEplKernel(* tEplLeduStateChangeCallback) (tEplLedType LedType_p,
BOOL fOn_p);
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
-tEplKernel PUBLIC EplLeduInit(tEplLeduStateChangeCallback pfnCbStateChange_p);
+tEplKernel EplLeduInit(tEplLeduStateChangeCallback pfnCbStateChange_p);
-tEplKernel PUBLIC EplLeduAddInstance(tEplLeduStateChangeCallback
- pfnCbStateChange_p);
+tEplKernel EplLeduAddInstance(tEplLeduStateChangeCallback pfnCbStateChange_p);
-tEplKernel PUBLIC EplLeduDelInstance(void);
+tEplKernel EplLeduDelInstance(void);
-tEplKernel PUBLIC EplLeduCbNmtStateChange(tEplEventNmtStateChange
- NmtStateChange_p);
+tEplKernel EplLeduCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
-tEplKernel PUBLIC EplLeduProcessEvent(tEplEvent * pEplEvent_p);
+tEplKernel EplLeduProcessEvent(tEplEvent * pEplEvent_p);
#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
diff --git a/drivers/staging/epl/user/EplNmtCnu.h b/drivers/staging/epl/user/EplNmtCnu.h
index e508055b5b8..7d230297f43 100644
--- a/drivers/staging/epl/user/EplNmtCnu.h
+++ b/drivers/staging/epl/user/EplNmtCnu.h
@@ -68,40 +68,24 @@
****************************************************************************/
-#include "EplNmtu.h"
-#include "../EplDll.h"
-#include "../EplFrame.h"
-
#ifndef _EPLNMTCNU_H_
#define _EPLNMTCNU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+#include "EplNmtu.h"
+#include "../EplDll.h"
+#include "../EplFrame.h"
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuInit(unsigned int uiNodeId_p);
+tEplKernel EplNmtCnuInit(unsigned int uiNodeId_p);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuAddInstance(unsigned int uiNodeId_p);
+tEplKernel EplNmtCnuAddInstance(unsigned int uiNodeId_p);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuDelInstance(void);
+tEplKernel EplNmtCnuDelInstance(void);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
- tEplNmtCommand
- NmtCommand_p);
+tEplKernel EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p, tEplNmtCommand NmtCommand_p);
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback
- pfnEplNmtCheckEventCb_p);
+tEplKernel EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p);
#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
diff --git a/drivers/staging/epl/user/EplNmtMnu.h b/drivers/staging/epl/user/EplNmtMnu.h
index c54efeba303..5e5e0cda324 100644
--- a/drivers/staging/epl/user/EplNmtMnu.h
+++ b/drivers/staging/epl/user/EplNmtMnu.h
@@ -68,34 +68,20 @@
****************************************************************************/
-#include "EplNmtu.h"
-
#ifndef _EPLNMTMNU_H_
#define _EPLNMTMNU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef tEplKernel(PUBLIC * tEplNmtMnuCbNodeEvent) (unsigned int uiNodeId_p,
- tEplNmtNodeEvent
- NodeEvent_p,
- tEplNmtState NmtState_p,
- WORD wErrorCode_p,
- BOOL fMandatory_p);
+#include "EplNmtu.h"
-typedef tEplKernel(PUBLIC *
- tEplNmtMnuCbBootEvent) (tEplNmtBootEvent BootEvent_p,
- tEplNmtState NmtState_p,
- WORD wErrorCode_p);
+typedef tEplKernel(* tEplNmtMnuCbNodeEvent) (unsigned int uiNodeId_p,
+ tEplNmtNodeEvent NodeEvent_p,
+ tEplNmtState NmtState_p,
+ u16 wErrorCode_p,
+ BOOL fMandatory_p);
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplNmtMnuCbBootEvent) (tEplNmtBootEvent BootEvent_p,
+ tEplNmtState NmtState_p,
+ u16 wErrorCode_p);
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
@@ -107,7 +93,7 @@ tEplKernel EplNmtMnuAddInstance(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
tEplKernel EplNmtMnuDelInstance(void);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p);
+tEplKernel EplNmtMnuProcessEvent(tEplEvent *pEvent_p);
tEplKernel EplNmtMnuSendNmtCommand(unsigned int uiNodeId_p,
tEplNmtCommand NmtCommand_p);
@@ -115,16 +101,16 @@ tEplKernel EplNmtMnuSendNmtCommand(unsigned int uiNodeId_p,
tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p,
tEplNmtNodeCommand NodeCommand_p);
-tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
+tEplKernel EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
NmtStateChange_p);
-tEplKernel PUBLIC EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p);
+tEplKernel EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p);
-tEplKernel PUBLIC EplNmtMnuGetDiagnosticInfo(unsigned int
+tEplKernel EplNmtMnuGetDiagnosticInfo(unsigned int
*puiMandatorySlaveCount_p,
unsigned int
*puiSignalSlaveCount_p,
- WORD * pwFlags_p);
+ u16 * pwFlags_p);
#endif
diff --git a/drivers/staging/epl/user/EplNmtu.h b/drivers/staging/epl/user/EplNmtu.h
index 5a56c583060..c1fca80f5a0 100644
--- a/drivers/staging/epl/user/EplNmtu.h
+++ b/drivers/staging/epl/user/EplNmtu.h
@@ -68,19 +68,12 @@
****************************************************************************/
-#include "../EplNmt.h"
-#include "EplEventu.h"
-
#ifndef _EPLNMTU_H_
#define _EPLNMTU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+#include "../EplNmt.h"
+#include "EplEventu.h"
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
// nmt commands
typedef enum {
// requestable ASnd ServiceIds 0x01..0x1F
@@ -121,34 +114,25 @@ typedef enum {
kEplNmtCmdInvalidService = 0xFF
} tEplNmtCommand;
-typedef tEplKernel(PUBLIC *
- tEplNmtuStateChangeCallback) (tEplEventNmtStateChange
- NmtStateChange_p);
-
-typedef tEplKernel(PUBLIC *
- tEplNmtuCheckEventCallback) (tEplNmtEvent NmtEvent_p);
+typedef tEplKernel(* tEplNmtuStateChangeCallback) (tEplEventNmtStateChange NmtStateChange_p);
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplNmtuCheckEventCallback) (tEplNmtEvent NmtEvent_p);
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuInit(void);
+tEplKernel EplNmtuInit(void);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuAddInstance(void);
+tEplKernel EplNmtuAddInstance(void);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuDelInstance(void);
+tEplKernel EplNmtuDelInstance(void);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p);
+tEplKernel EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p);
-EPLDLLEXPORT tEplNmtState PUBLIC EplNmtuGetNmtState(void);
+tEplNmtState EplNmtuGetNmtState(void);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p);
+tEplKernel EplNmtuProcessEvent(tEplEvent *pEplEvent_p);
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback
- pfnEplNmtStateChangeCb_p);
+tEplKernel EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p);
#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
diff --git a/drivers/staging/epl/user/EplNmtuCal.h b/drivers/staging/epl/user/EplNmtuCal.h
index c881582702b..b9850372a4a 100644
--- a/drivers/staging/epl/user/EplNmtuCal.h
+++ b/drivers/staging/epl/user/EplNmtuCal.h
@@ -69,23 +69,12 @@
****************************************************************************/
-#include "EplNmtu.h"
-#include "../kernel/EplNmtk.h"
-
#ifndef _EPLNMTUCAL_H_
#define _EPLNMTUCAL_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+#include "EplNmtu.h"
+#include "../kernel/EplNmtk.h"
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplNmtState PUBLIC EplNmtkCalGetNmtState(void);
+tEplNmtState EplNmtkCalGetNmtState(void);
#endif // #ifndef _EPLNMTUCAL_H_
diff --git a/drivers/staging/epl/user/EplObdu.h b/drivers/staging/epl/user/EplObdu.h
index bc1e1730301..086371276cf 100644
--- a/drivers/staging/epl/user/EplObdu.h
+++ b/drivers/staging/epl/user/EplObdu.h
@@ -68,22 +68,10 @@
****************************************************************************/
-#include "../EplObd.h"
-
#ifndef _EPLOBDU_H_
#define _EPLOBDU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+#include "../EplObd.h"
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
@@ -91,68 +79,57 @@
#error "EPL OBDu module enabled, but OBD_USE_KERNEL == TRUE"
#endif
-EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p);
+tEplKernel EplObduWriteEntry(unsigned int uiIndex_p, unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p);
+tEplKernel EplObduReadEntry(unsigned int uiIndex_p, unsigned int uiSubIndex_p,
+ void *pDstData_p, tEplObdSize *pSize_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduAccessOdPart(tEplObdPart ObdPart_p,
- tEplObdDir Direction_p);
+tEplKernel EplObduAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduDefineVar(tEplVarParam MEM * pVarParam_p);
+tEplKernel EplObduDefineVar(tEplVarParam *pVarParam_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObduGetObjectDataPtr(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p);
+void *EplObduGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p);
+
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p);
+tEplKernel EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObduInitVarEntry(tEplObdVarEntry MEM * pVarEntry_p,
- BYTE bType_p,
- tEplObdSize ObdSize_p);
+void EplObduInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p,
+ tEplObdSize ObdSize_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObduGetDataSize(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p);
+tEplObdSize EplObduGetDataSize(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObduGetNodeId(void);
+unsigned int EplObduGetNodeId(void);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduSetNodeId(unsigned int uiNodeId_p,
- tEplObdNodeIdType NodeIdType_p);
+tEplKernel EplObduSetNodeId(unsigned int uiNodeId_p,
+ tEplObdNodeIdType NodeIdType_p);
+
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduGetAccessType(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- tEplObdAccess *
- pAccessTyp_p);
+tEplKernel EplObduGetAccessType(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ tEplObdAccess *pAccessTyp_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntryToLe(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p);
+tEplKernel EplObduReadEntryToLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p, tEplObdSize *pSize_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntryFromLe(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p);
+tEplKernel EplObduWriteEntryFromLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- tEplObdVarEntry MEM **
- ppVarEntry_p);
+tEplKernel EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ tEplObdVarEntry **ppVarEntry_p);
#elif EPL_OBD_USE_KERNEL != FALSE
#include "../kernel/EplObdk.h"
diff --git a/drivers/staging/epl/user/EplObduCal.h b/drivers/staging/epl/user/EplObduCal.h
index 498e0112fac..07277777219 100644
--- a/drivers/staging/epl/user/EplObduCal.h
+++ b/drivers/staging/epl/user/EplObduCal.h
@@ -69,80 +69,58 @@
****************************************************************************/
-#include "../EplObd.h"
-
#ifndef _EPLOBDUCAL_H_
#define _EPLOBDUCAL_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+#include "../EplObd.h"
+tEplKernel EplObduCalWriteEntry(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p,
+ tEplObdSize Size_p);
//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p);
-//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p);
+tEplKernel EplObduCalReadEntry(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p,
+ tEplObdSize *pSize_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalAccessOdPart(tEplObdPart ObdPart_p,
- tEplObdDir Direction_p);
+tEplKernel EplObduCalAccessOdPart(tEplObdPart ObdPart_p,
+ tEplObdDir Direction_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalDefineVar(tEplVarParam MEM *
- pVarParam_p);
+tEplKernel EplObduCalDefineVar(tEplVarParam *pVarParam_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObduCalGetObjectDataPtr(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p);
+void *EplObduCalGetObjectDataPtr(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalRegisterUserOd(tEplObdEntryPtr
- pUserOd_p);
+tEplKernel EplObduCalRegisterUserOd(tEplObdEntryPtr pUserOd_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObduCalInitVarEntry(tEplObdVarEntry MEM *
- pVarEntry_p, BYTE bType_p,
- tEplObdSize ObdSize_p);
+void EplObduCalInitVarEntry(tEplObdVarEntry *pVarEntry_p,
+ u8 bType_p, tEplObdSize ObdSize_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObduCalGetDataSize(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p);
+tEplObdSize EplObduCalGetDataSize(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObduCalGetNodeId(void);
+unsigned int EplObduCalGetNodeId(void);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalSetNodeId(unsigned int uiNodeId_p,
- tEplObdNodeIdType
- NodeIdType_p);
+tEplKernel EplObduCalSetNodeId(unsigned int uiNodeId_p,
+ tEplObdNodeIdType NodeIdType_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalGetAccessType(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p,
- tEplObdAccess *
- pAccessTyp_p);
+tEplKernel EplObduCalGetAccessType(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ tEplObdAccess *pAccessTyp_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntryToLe(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p);
+tEplKernel EplObduCalReadEntryToLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p,
+ tEplObdSize *pSize_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntryFromLe(unsigned int
- uiIndex_p,
- unsigned int
- uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p);
+tEplKernel EplObduCalWriteEntryFromLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p,
+ tEplObdSize Size_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- tEplObdVarEntry MEM ** ppVarEntry_p);
+tEplKernel EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ tEplObdVarEntry **ppVarEntry_p);
#endif // #ifndef _EPLOBDUCAL_H_
diff --git a/drivers/staging/epl/user/EplPdou.h b/drivers/staging/epl/user/EplPdou.h
index 11de4862e8b..b8c832b09db 100644
--- a/drivers/staging/epl/user/EplPdou.h
+++ b/drivers/staging/epl/user/EplPdou.h
@@ -72,24 +72,12 @@
#include "../EplPdo.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
tEplKernel EplPdouAddInstance(void);
tEplKernel EplPdouDelInstance(void);
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOU)) != 0)
-tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p);
+tEplKernel EplPdouCbObdAccess(tEplObdCbParam *pParam_p);
#else
#define EplPdouCbObdAccess NULL
#endif
@@ -97,12 +85,12 @@ tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p);
// returns error if bPdoId_p is already valid
/*
tEplKernel EplPdouSetMapping(
- BYTE bPdoId_p, BOOL fTxRx_p, BYTE bNodeId, BYTE bMappingVersion,
- tEplPdoMapping * pMapping_p, BYTE bMaxEntries_p);
+ u8 bPdoId_p, BOOL fTxRx_p, u8 bNodeId, u8 bMappingVersion,
+ tEplPdoMapping * pMapping_p, u8 bMaxEntries_p);
tEplKernel EplPdouGetMapping(
- BYTE bPdoId_p, BOOL fTxRx_p, BYTE * pbNodeId, BYTE * pbMappingVersion,
- tEplPdoMapping * pMapping_p, BYTE * pbMaxEntries_p);
+ u8 bPdoId_p, BOOL fTxRx_p, u8 * pbNodeId, u8 * pbMappingVersion,
+ tEplPdoMapping * pMapping_p, u8 * pbMaxEntries_p);
*/
#endif // #ifndef _EPL_PDOU_H_
diff --git a/drivers/staging/epl/user/EplSdoAsndu.h b/drivers/staging/epl/user/EplSdoAsndu.h
index e34959f4279..a62d4c97870 100644
--- a/drivers/staging/epl/user/EplSdoAsndu.h
+++ b/drivers/staging/epl/user/EplSdoAsndu.h
@@ -68,39 +68,28 @@
****************************************************************************/
-#include "../EplSdo.h"
-#include "../EplDll.h"
-
#ifndef _EPLSDOASNDU_H_
#define _EPLSDOASNDU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+#include "../EplSdo.h"
+#include "../EplDll.h"
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-tEplKernel PUBLIC EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p);
+tEplKernel EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p);
-tEplKernel PUBLIC EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
+tEplKernel EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
-tEplKernel PUBLIC EplSdoAsnduDelInstance(void);
+tEplKernel EplSdoAsnduDelInstance(void);
-tEplKernel PUBLIC EplSdoAsnduInitCon(tEplSdoConHdl * pSdoConHandle_p,
- unsigned int uiTargetNodeId_p);
+tEplKernel EplSdoAsnduInitCon(tEplSdoConHdl *pSdoConHandle_p,
+ unsigned int uiTargetNodeId_p);
-tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
- tEplFrame * pSrcData_p,
- DWORD dwDataSize_p);
+tEplKernel EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
+ tEplFrame *pSrcData_p,
+ u32 dwDataSize_p);
-tEplKernel PUBLIC EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p);
+tEplKernel EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p);
#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
diff --git a/drivers/staging/epl/user/EplSdoAsySequ.h b/drivers/staging/epl/user/EplSdoAsySequ.h
index 4658b5f8c53..cc862de1a5b 100644
--- a/drivers/staging/epl/user/EplSdoAsySequ.h
+++ b/drivers/staging/epl/user/EplSdoAsySequ.h
@@ -68,44 +68,33 @@
****************************************************************************/
+#ifndef _EPLSDOASYSEQU_H_
+#define _EPLSDOASYSEQU_H_
+
#include "../EplSdo.h"
#include "EplSdoUdpu.h"
#include "EplSdoAsndu.h"
#include "../EplEvent.h"
#include "EplTimeru.h"
-#ifndef _EPLSDOASYSEQU_H_
-#define _EPLSDOASYSEQU_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+tEplKernel EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
+ tEplSdoComConCb fpSdoComConCb_p);
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
+tEplKernel EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
tEplSdoComConCb fpSdoComConCb_p);
-tEplKernel PUBLIC EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
- tEplSdoComConCb fpSdoComConCb_p);
-
-tEplKernel PUBLIC EplSdoAsySeqDelInstance(void);
+tEplKernel EplSdoAsySeqDelInstance(void);
-tEplKernel PUBLIC EplSdoAsySeqInitCon(tEplSdoSeqConHdl * pSdoSeqConHdl_p,
- unsigned int uiNodeId_p,
- tEplSdoType SdoType);
+tEplKernel EplSdoAsySeqInitCon(tEplSdoSeqConHdl *pSdoSeqConHdl_p,
+ unsigned int uiNodeId_p,
+ tEplSdoType SdoType);
-tEplKernel PUBLIC EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
- unsigned int uiDataSize_p,
- tEplFrame * pData_p);
+tEplKernel EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
+ unsigned int uiDataSize_p,
+ tEplFrame *pData_p);
-tEplKernel PUBLIC EplSdoAsySeqProcessEvent(tEplEvent * pEvent_p);
+tEplKernel EplSdoAsySeqProcessEvent(tEplEvent *pEvent_p);
-tEplKernel PUBLIC EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p);
+tEplKernel EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p);
#endif // #ifndef _EPLSDOASYSEQU_H_
diff --git a/drivers/staging/epl/user/EplSdoComu.h b/drivers/staging/epl/user/EplSdoComu.h
index 3e454c7a355..4eee6fa6974 100644
--- a/drivers/staging/epl/user/EplSdoComu.h
+++ b/drivers/staging/epl/user/EplSdoComu.h
@@ -68,58 +68,46 @@
****************************************************************************/
+#ifndef _EPLSDOCOMU_H_
+#define _EPLSDOCOMU_H_
+
#include "../EplSdo.h"
#include "../EplObd.h"
#include "../EplSdoAc.h"
#include "EplObdu.h"
#include "EplSdoAsySequ.h"
-#ifndef _EPLSDOCOMU_H_
-#define _EPLSDOCOMU_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComInit(void);
+tEplKernel EplSdoComInit(void);
-tEplKernel PUBLIC EplSdoComAddInstance(void);
+tEplKernel EplSdoComAddInstance(void);
-tEplKernel PUBLIC EplSdoComDelInstance(void);
+tEplKernel EplSdoComDelInstance(void);
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComDefineCon(tEplSdoComConHdl * pSdoComConHdl_p,
- unsigned int uiTargetNodeId_p,
- tEplSdoType ProtType_p);
+tEplKernel EplSdoComDefineCon(tEplSdoComConHdl *pSdoComConHdl_p,
+ unsigned int uiTargetNodeId_p,
+ tEplSdoType ProtType_p);
-tEplKernel PUBLIC EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *
- pSdoComTransParam_p);
+tEplKernel EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *pSdoComTransParam_p);
-tEplKernel PUBLIC EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p);
+tEplKernel EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p);
-tEplKernel PUBLIC EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
- tEplSdoComFinished * pSdoComFinished_p);
+tEplKernel EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
+ tEplSdoComFinished *pSdoComFinished_p);
-tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
- DWORD dwAbortCode_p);
+tEplKernel EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
+ u32 dwAbortCode_p);
#endif
// for future extention
/*
-tEplKernel PUBLIC EplSdoComInitTransferAllByIndex(tEplSdoComTransParamAllByIndex* pSdoComTransParam_p);
+tEplKernel EplSdoComInitTransferAllByIndex(tEplSdoComTransParamAllByIndex* pSdoComTransParam_p);
-tEplKernel PUBLIC EplSdoComInitTransferByName(tEplSdoComTransParamByName* pSdoComTransParam_p);
+tEplKernel EplSdoComInitTransferByName(tEplSdoComTransParamByName* pSdoComTransParam_p);
-tEplKernel PUBLIC EplSdoComInitTransferFile(tEplSdoComTransParamFile* pSdoComTransParam_p);
+tEplKernel EplSdoComInitTransferFile(tEplSdoComTransParamFile* pSdoComTransParam_p);
*/
diff --git a/drivers/staging/epl/user/EplSdoUdpu.h b/drivers/staging/epl/user/EplSdoUdpu.h
index 2d77b6fff19..13e2a278c11 100644
--- a/drivers/staging/epl/user/EplSdoUdpu.h
+++ b/drivers/staging/epl/user/EplSdoUdpu.h
@@ -68,41 +68,29 @@
****************************************************************************/
-#include "../EplSdo.h"
-
#ifndef _EPLSDOUDPU_H_
#define _EPLSDOUDPU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+#include "../EplSdo.h"
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-tEplKernel PUBLIC EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p);
+tEplKernel EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p);
-tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
+tEplKernel EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
-tEplKernel PUBLIC EplSdoUdpuDelInstance(void);
+tEplKernel EplSdoUdpuDelInstance(void);
-tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
- unsigned int uiPort_p);
+tEplKernel EplSdoUdpuConfig(unsigned long ulIpAddr_p,
+ unsigned int uiPort_p);
-tEplKernel PUBLIC EplSdoUdpuInitCon(tEplSdoConHdl * pSdoConHandle_p,
- unsigned int uiTargetNodeId_p);
+tEplKernel EplSdoUdpuInitCon(tEplSdoConHdl *pSdoConHandle_p,
+ unsigned int uiTargetNodeId_p);
-tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
- tEplFrame * pSrcData_p,
- DWORD dwDataSize_p);
+tEplKernel EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
+ tEplFrame *pSrcData_p, u32 dwDataSize_p);
-tEplKernel PUBLIC EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p);
+tEplKernel EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p);
#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
diff --git a/drivers/staging/epl/user/EplStatusu.h b/drivers/staging/epl/user/EplStatusu.h
index d211935f0e8..0fd3ebb76dc 100644
--- a/drivers/staging/epl/user/EplStatusu.h
+++ b/drivers/staging/epl/user/EplStatusu.h
@@ -68,37 +68,23 @@
****************************************************************************/
-#include "../EplDll.h"
-
#ifndef _EPLSTATUSU_H_
#define _EPLSTATUSU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef tEplKernel(PUBLIC * tEplStatusuCbResponse) (unsigned int uiNodeId_p,
- tEplStatusResponse *
- pStatusResponse_p);
+#include "../EplDll.h"
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplStatusuCbResponse) (unsigned int uiNodeId_p,
+ tEplStatusResponse *pStatusResponse_p);
-tEplKernel PUBLIC EplStatusuInit(void);
+tEplKernel EplStatusuInit(void);
-tEplKernel PUBLIC EplStatusuAddInstance(void);
+tEplKernel EplStatusuAddInstance(void);
-tEplKernel PUBLIC EplStatusuDelInstance(void);
+tEplKernel EplStatusuDelInstance(void);
-tEplKernel PUBLIC EplStatusuReset(void);
+tEplKernel EplStatusuReset(void);
-tEplKernel PUBLIC EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
- tEplStatusuCbResponse
- pfnCbResponse_p);
+tEplKernel EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
+ tEplStatusuCbResponse pfnCbResponse_p);
#endif // #ifndef _EPLSTATUSU_H_
diff --git a/drivers/staging/epl/user/EplTimeru.h b/drivers/staging/epl/user/EplTimeru.h
index 404495501b8..5c447485245 100644
--- a/drivers/staging/epl/user/EplTimeru.h
+++ b/drivers/staging/epl/user/EplTimeru.h
@@ -68,40 +68,28 @@
****************************************************************************/
-#include "../EplTimer.h"
-#include "EplEventu.h"
-
#ifndef _EPLTIMERU_H_
#define _EPLTIMERU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+#include "../EplTimer.h"
+#include "EplEventu.h"
-tEplKernel PUBLIC EplTimeruInit(void);
+tEplKernel EplTimeruInit(void);
-tEplKernel PUBLIC EplTimeruAddInstance(void);
+tEplKernel EplTimeruAddInstance(void);
-tEplKernel PUBLIC EplTimeruDelInstance(void);
+tEplKernel EplTimeruDelInstance(void);
-tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p);
+tEplKernel EplTimeruSetTimerMs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long ulTime_p,
+ tEplTimerArg Argument_p);
-tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p);
+tEplKernel EplTimeruModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long ulTime_p,
+ tEplTimerArg Argument_p);
-tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p);
+tEplKernel EplTimeruDeleteTimer(tEplTimerHdl *pTimerHdl_p);
-BOOL PUBLIC EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p);
+BOOL EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p);
#endif // #ifndef _EPLTIMERU_H_
diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c
index ec98da5da5b..8dc559a77ad 100644
--- a/drivers/staging/et131x/et1310_rx.c
+++ b/drivers/staging/et131x/et1310_rx.c
@@ -1203,8 +1203,7 @@ void et131x_reset_recv(struct et131x_adapter *pAdapter)
pMpRfd = (PMP_RFD) list_entry(element, MP_RFD, list_node);
- list_del(&pMpRfd->list_node);
- list_add_tail(&pMpRfd->list_node, &pAdapter->RxRing.RecvList);
+ list_move_tail(&pMpRfd->list_node, &pAdapter->RxRing.RecvList);
}
DBG_LEAVE(et131x_dbginfo);
diff --git a/drivers/staging/frontier/README b/drivers/staging/frontier/README
index 07c9ef9b8fc..cd07af22406 100644
--- a/drivers/staging/frontier/README
+++ b/drivers/staging/frontier/README
@@ -1,28 +1,47 @@
-This directory contains the USB Tranzport and Alphatrack Kernel drivers for Linux.
+This directory contains the Linux USB Tranzport and Alphatrack Kernel drivers.
-At present the tranzport does reads/writes of 8 byte cmds to /dev/tranzport0 to control
-the lights and screen and wheel
+See http://www.frontierdesign.com for details on these devices.
-At present the alphatrack accepts reads/writes of 12 byte cmds to /dev/tranzport0 to control
-the lights and screen and fader.
+Userspace test code is available from
-Both drivers also have some sysfs hooks that are non-functional at the moment.
+git://toutatis.isc.org/home/d/src/git/frontier.git
-The API is currently closely tied to the ardour revision and WILL change.
+At present the tranzport does reads/writes of 8 byte cmds to
+/dev/tranzport0 to control the lights, screen, and wheel.
-A sysfs interface is PERFECT for simple userspace apps to do fun things with the
-lights and screen. It's fairly lousy for handling input events and very lousy
-for watching the state of the shuttle wheel.
+At present the alphatrack accepts reads/writes of 12 byte cmds to
+/dev/tranzport0 to control the lights, screen, fader and touchpad.
-A linux input events interface is great for the input events and shuttle wheel. It's
-theoretically OK on LEDs. A Fader can be mapped to an absolute mouse device.
-But there is no LCD support at all.
+The tranzport driver provides a rudimentary sysfs interface for the status of
+the device and a writable parameter for turning wheel compression on and off.
-In the end this is going to be driven by a midi layer, which handles all those
-cases via a defined API, but - among other things - is slow, doesn't do
-flow control, and is a LOT of extra work. Frankly, I'd like to keep the
+The API is nothing more than the USB commands issued to the device. Why?
+
+The control wheel/fader can generate events far too quickly for
+a typical userspace application to keep up with them via libusb. Input
+needs to be 100% accurate and fast in order for the alphatrack or tranzport
+to be useful.
+
+UIO would be useful except that usb disconnect events need
+to be handled correctly.
+
+A sysfs interface is perfect for simple userspace apps to do fun things with
+the lights and screen. But it's fairly lousy for handling input events and
+very lousy for watching the state of the shuttle wheel.
+
+A linux input events interface is great for the input events and shuttle wheel.
+* It's theoretically OK on LEDs.
+* A fader can be mapped to an absolute mouse device.
+* But there is no LCD support at all, or fader feedback support in that API
+
+So, thus, these stubby drivers exist.
+
+In the end this could be driven by a midi layer, which handles all those
+cases via a well defined API, but - among other things - is slow, doesn't do
+flow control, and is a LOT of extra work, none of which is required at
+the kernel level (probably). Frankly, I'd like to keep the
core driver simple because the only realtime work really required is
the bottom half interrupt handler and the output overlapping.
-Exposing some sort of clean aio api to userspace would be perfect. What that
+Exposing some sort of clean api to userspace would be perfect. What that
API looks like? Gah. beats me.
diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c
index 6136e3f8762..bcba17eae92 100644
--- a/drivers/staging/frontier/alphatrack.c
+++ b/drivers/staging/frontier/alphatrack.c
@@ -41,19 +41,11 @@
#include <linux/mutex.h>
#include <linux/version.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/poll.h>
-#include "surface_sysfs.h"
-
-/* make this work on older kernel versions */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-#include "frontier_compat.h"
-#endif /* older kernel versions */
-
#include "alphatrack.h"
#define VENDOR_ID 0x165b
@@ -62,19 +54,18 @@
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define USB_ALPHATRACK_MINOR_BASE 0
#else
-// FIXME 176 - is another driver's minor - apply for that
-// #define USB_ALPHATRACK_MINOR_BASE 177
+/* FIXME 176 - is another driver's minor - apply for that */
#define USB_ALPHATRACK_MINOR_BASE 176
#endif
/* table of devices that work with this driver */
-static struct usb_device_id usb_alphatrack_table [] = {
- { USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
- { } /* Terminating entry */
+static struct usb_device_id usb_alphatrack_table[] = {
+ {USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
+ {} /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, usb_alphatrack_table);
-MODULE_VERSION("0.40");
+MODULE_VERSION("0.41");
MODULE_AUTHOR("Mike Taht <m@taht.net>");
MODULE_DESCRIPTION("Alphatrack USB Driver");
MODULE_LICENSE("GPL");
@@ -93,18 +84,18 @@ MODULE_SUPPORTED_DEVICE("Frontier Designs Alphatrack Control Surface");
#define ALPHATRACK_USB_TIMEOUT 10
#define OUTPUT_CMD_SIZE 8
#define INPUT_CMD_SIZE 12
+#define ALPHATRACK_DEBUG 0
-
-static int debug = 0;
+static int debug = ALPHATRACK_DEBUG;
/* Use our own dbg macro */
-#define dbg_info(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
+#define dbg_info(dev, format, arg...) do \
+ { if (debug) dev_info(dev , format , ## arg); } while (0)
#define alphatrack_ocmd_info(dev, cmd, format, arg...)
#define alphatrack_icmd_info(dev, cmd, format, arg...)
-
/* Module parameters */
module_param(debug, int, S_IRUGO | S_IWUSR);
@@ -116,14 +107,14 @@ MODULE_PARM_DESC(debug, "Debug enabled or not");
static int ring_buffer_size = RING_BUFFER_SIZE;
-module_param(ring_buffer_size, int, S_IRUGO);
+module_param(ring_buffer_size, int, S_IRUGO);
MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size");
/* The write_buffer can one day contain more than one interrupt out transfer.
*/
static int write_buffer_size = WRITE_BUFFER_SIZE;
-module_param(write_buffer_size, int, S_IRUGO);
+module_param(write_buffer_size, int, S_IRUGO);
MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
/*
@@ -133,55 +124,56 @@ MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
static int min_interrupt_in_interval = ALPHATRACK_USB_TIMEOUT;
module_param(min_interrupt_in_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_in_interval, "Minimum interrupt in interval in ms");
+MODULE_PARM_DESC(min_interrupt_in_interval,
+ "Minimum interrupt in interval in ms");
static int min_interrupt_out_interval = ALPHATRACK_USB_TIMEOUT;
module_param(min_interrupt_out_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in ms");
-
-
+MODULE_PARM_DESC(min_interrupt_out_interval,
+ "Minimum interrupt out interval in ms");
/* Structure to hold all of our device specific stuff */
struct usb_alphatrack {
- struct semaphore sem; /* locks this structure */
- struct usb_interface* intf; /* save off the usb interface pointer */
- int open_count; /* number of times this port has been opened */
-
- struct alphatrack_icmd (*ring_buffer)[RING_BUFFER_SIZE]; /* just make c happy */
- struct alphatrack_ocmd (*write_buffer)[WRITE_BUFFER_SIZE]; /* just make c happy */
- unsigned int ring_head;
- unsigned int ring_tail;
-
- wait_queue_head_t read_wait;
- wait_queue_head_t write_wait;
-
- unsigned char* interrupt_in_buffer;
- unsigned char* oldi_buffer;
- struct usb_endpoint_descriptor* interrupt_in_endpoint;
- struct urb* interrupt_in_urb;
- int interrupt_in_interval;
- size_t interrupt_in_endpoint_size;
- int interrupt_in_running;
- int interrupt_in_done;
-
- char* interrupt_out_buffer;
- struct usb_endpoint_descriptor* interrupt_out_endpoint;
- struct urb* interrupt_out_urb;
- int interrupt_out_interval;
- size_t interrupt_out_endpoint_size;
- int interrupt_out_busy;
+ struct semaphore sem; /* locks this structure */
+ struct usb_interface *intf; /* save off the usb interface pointer */
+ int open_count; /* number of times this port has been opened */
+
+ /* make gcc happy */
+ struct alphatrack_icmd (*ring_buffer)[RING_BUFFER_SIZE];
+ struct alphatrack_ocmd (*write_buffer)[WRITE_BUFFER_SIZE];
+ unsigned int ring_head;
+ unsigned int ring_tail;
+
+ wait_queue_head_t read_wait;
+ wait_queue_head_t write_wait;
+
+ unsigned char *interrupt_in_buffer;
+ unsigned char *oldi_buffer;
+ struct usb_endpoint_descriptor *interrupt_in_endpoint;
+ struct urb *interrupt_in_urb;
+ int interrupt_in_interval;
+ size_t interrupt_in_endpoint_size;
+ int interrupt_in_running;
+ int interrupt_in_done;
+
+ char *interrupt_out_buffer;
+ struct usb_endpoint_descriptor *interrupt_out_endpoint;
+ struct urb *interrupt_out_urb;
+ int interrupt_out_interval;
+ size_t interrupt_out_endpoint_size;
+ int interrupt_out_busy;
atomic_t writes_pending;
- int event; /* alternate interface to events */
- int fader; /* 10 bits */
- int lights; /* 23 bits */
- unsigned char dump_state; /* 0 if disabled 1 if enabled */
- unsigned char enable; /* 0 if disabled 1 if enabled */
- unsigned char offline; /* if the device is out of range or asleep */
- unsigned char verbose; /* be verbose in error reporting */
- unsigned char last_cmd[OUTPUT_CMD_SIZE];
- unsigned char screen[32];
+ int event; /* alternate interface to events */
+ int fader; /* 10 bits */
+ int lights; /* 23 bits */
+ unsigned char dump_state; /* 0 if disabled 1 if enabled */
+ unsigned char enable; /* 0 if disabled 1 if enabled */
+ unsigned char offline; /* if the device is out of range or asleep */
+ unsigned char verbose; /* be verbose in error reporting */
+ unsigned char last_cmd[OUTPUT_CMD_SIZE];
+ unsigned char screen[32];
};
/* prevent races between open() and disconnect() */
@@ -219,7 +211,7 @@ static void usb_alphatrack_delete(struct usb_alphatrack *dev)
kfree(dev->ring_buffer);
kfree(dev->interrupt_in_buffer);
kfree(dev->interrupt_out_buffer);
- kfree(dev); // fixme oldi_buffer
+ kfree(dev); /* fixme oldi_buffer */
}
/**
@@ -234,39 +226,52 @@ static void usb_alphatrack_interrupt_in_callback(struct urb *urb)
if (urb->status) {
if (urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN) {
+ urb->status == -ECONNRESET || urb->status == -ESHUTDOWN) {
goto exit;
} else {
- dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
- __func__, urb->status);
- goto resubmit; /* maybe we can recover */
+ dbg_info(&dev->intf->dev,
+ "%s: nonzero status received: %d\n", __func__,
+ urb->status);
+ goto resubmit; /* maybe we can recover */
}
}
if (urb->actual_length != INPUT_CMD_SIZE) {
dev_warn(&dev->intf->dev,
- "Urb length was %d bytes!! Do something intelligent \n", urb->actual_length);
+ "Urb length was %d bytes!!"
+ "Do something intelligent \n", urb->actual_length);
} else {
- alphatrack_ocmd_info(&dev->intf->dev,&(*dev->ring_buffer)[dev->ring_tail].cmd,"%s", "bla");
- if(memcmp(dev->interrupt_in_buffer,dev->oldi_buffer,INPUT_CMD_SIZE)==0) {
- goto resubmit;
+ alphatrack_ocmd_info(&dev->intf->dev,
+ &(*dev->ring_buffer)[dev->ring_tail].cmd,
+ "%s", "bla");
+ if (memcmp
+ (dev->interrupt_in_buffer, dev->oldi_buffer,
+ INPUT_CMD_SIZE) == 0) {
+ goto resubmit;
}
- memcpy(dev->oldi_buffer,dev->interrupt_in_buffer,INPUT_CMD_SIZE);
+ memcpy(dev->oldi_buffer, dev->interrupt_in_buffer,
+ INPUT_CMD_SIZE);
#if SUPPRESS_EXTRA_OFFLINE_EVENTS
- if(dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff) { goto resubmit; }
- if(dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 2; goto resubmit; }
+ if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff)
+ goto resubmit;
+ if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) {
+ dev->offline = 2;
+ goto resubmit;
+ }
/* Always pass one offline event up the stack */
- if(dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff) { dev->offline = 0; }
- if(dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 1; }
+ if (dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff)
+ dev->offline = 0;
+ if (dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff)
+ dev->offline = 1;
#endif
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
- next_ring_head = (dev->ring_head+1) % ring_buffer_size;
+ dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
+ __func__, dev->ring_head, dev->ring_tail);
+ next_ring_head = (dev->ring_head + 1) % ring_buffer_size;
if (next_ring_head != dev->ring_tail) {
memcpy(&((*dev->ring_buffer)[dev->ring_head]),
- dev->interrupt_in_buffer, urb->actual_length);
+ dev->interrupt_in_buffer, urb->actual_length);
dev->ring_head = next_ring_head;
retval = 0;
memset(dev->interrupt_in_buffer, 0, urb->actual_length);
@@ -330,7 +335,7 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file)
if (!interface) {
err("%s - error, can't find device for minor %d\n",
- __func__, subminor);
+ __func__, subminor);
retval = -ENODEV;
goto unlock_disconnect_exit;
}
@@ -361,11 +366,11 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file)
usb_fill_int_urb(dev->interrupt_in_urb,
interface_to_usbdev(interface),
usb_rcvintpipe(interface_to_usbdev(interface),
- dev->interrupt_in_endpoint->bEndpointAddress),
+ dev->interrupt_in_endpoint->
+ bEndpointAddress),
dev->interrupt_in_buffer,
dev->interrupt_in_endpoint_size,
- usb_alphatrack_interrupt_in_callback,
- dev,
+ usb_alphatrack_interrupt_in_callback, dev,
dev->interrupt_in_interval);
dev->interrupt_in_running = 1;
@@ -375,7 +380,8 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file)
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
if (retval) {
- dev_err(&interface->dev, "Couldn't submit interrupt_in_urb %d\n", retval);
+ dev_err(&interface->dev,
+ "Couldn't submit interrupt_in_urb %d\n", retval);
dev->interrupt_in_running = 0;
dev->open_count = 0;
goto unlock_exit;
@@ -384,7 +390,6 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file)
/* save device in the file's private structure */
file->private_data = dev;
-
unlock_exit:
up(&dev->sem);
@@ -430,7 +435,9 @@ static int usb_alphatrack_release(struct inode *inode, struct file *file)
/* wait until write transfer is finished */
if (dev->interrupt_out_busy)
- wait_event_interruptible_timeout(dev->write_wait, !dev->interrupt_out_busy, 2 * HZ);
+ wait_event_interruptible_timeout(dev->write_wait,
+ !dev->interrupt_out_busy,
+ 2 * HZ);
usb_alphatrack_abort_transfers(dev);
dev->open_count = 0;
@@ -444,7 +451,7 @@ exit:
/**
* usb_alphatrack_poll
*/
-static unsigned int usb_alphatrack_poll(struct file *file, poll_table *wait)
+static unsigned int usb_alphatrack_poll(struct file *file, poll_table * wait)
{
struct usb_alphatrack *dev;
unsigned int mask = 0;
@@ -465,8 +472,8 @@ static unsigned int usb_alphatrack_poll(struct file *file, poll_table *wait)
/**
* usb_alphatrack_read
*/
-static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer, size_t count,
- loff_t *ppos)
+static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ppos)
{
struct usb_alphatrack *dev;
int retval = 0;
@@ -493,30 +500,36 @@ static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer, size_
}
while (dev->ring_head == dev->ring_tail) {
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- goto unlock_exit;
- }
- dev->interrupt_in_done = 0 ;
- retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);
- if (retval < 0) {
- goto unlock_exit;
- }
- }
-
- alphatrack_ocmd_info(&dev->intf->dev, &(*dev->ring_buffer)[dev->ring_tail].cmd, "%s", ": copying to userspace");
-
- c = 0;
- while((c < count) && (dev->ring_tail != dev->ring_head)) {
- if (copy_to_user(&buffer[c], &(*dev->ring_buffer)[dev->ring_tail], INPUT_CMD_SIZE)) {
- retval = -EFAULT;
- goto unlock_exit;
- }
- dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;
- c+=INPUT_CMD_SIZE;
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
- }
- retval = c;
+ if (file->f_flags & O_NONBLOCK) {
+ retval = -EAGAIN;
+ goto unlock_exit;
+ }
+ dev->interrupt_in_done = 0;
+ retval =
+ wait_event_interruptible(dev->read_wait,
+ dev->interrupt_in_done);
+ if (retval < 0)
+ goto unlock_exit;
+ }
+
+ alphatrack_ocmd_info(&dev->intf->dev,
+ &(*dev->ring_buffer)[dev->ring_tail].cmd, "%s",
+ ": copying to userspace");
+
+ c = 0;
+ while ((c < count) && (dev->ring_tail != dev->ring_head)) {
+ if (copy_to_user
+ (&buffer[c], &(*dev->ring_buffer)[dev->ring_tail],
+ INPUT_CMD_SIZE)) {
+ retval = -EFAULT;
+ goto unlock_exit;
+ }
+ dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
+ c += INPUT_CMD_SIZE;
+ dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
+ __func__, dev->ring_head, dev->ring_tail);
+ }
+ retval = c;
unlock_exit:
/* unlock the device */
@@ -529,8 +542,9 @@ exit:
/**
* usb_alphatrack_write
*/
-static ssize_t usb_alphatrack_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
+static ssize_t usb_alphatrack_write(struct file *file,
+ const char __user *buffer, size_t count,
+ loff_t *ppos)
{
struct usb_alphatrack *dev;
size_t bytes_to_write;
@@ -561,19 +575,24 @@ static ssize_t usb_alphatrack_write(struct file *file, const char __user *buffer
retval = -EAGAIN;
goto unlock_exit;
}
- retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy);
- if (retval < 0) {
+ retval =
+ wait_event_interruptible(dev->write_wait,
+ !dev->interrupt_out_busy);
+ if (retval < 0)
goto unlock_exit;
- }
}
/* write the data into interrupt_out_buffer from userspace */
- /* FIXME - if you write more than 12 bytes this breaks */
- bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
+ /* FIXME - if you write more than 12 bytes this breaks */
+ bytes_to_write =
+ min(count, write_buffer_size * dev->interrupt_out_endpoint_size);
if (bytes_to_write < count)
- dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write);
+ dev_warn(&dev->intf->dev,
+ "Write buffer overflow, %zd bytes dropped\n",
+ count - bytes_to_write);
- dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write);
+ dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n",
+ __func__, count, bytes_to_write);
if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
retval = -EFAULT;
@@ -589,11 +608,10 @@ static ssize_t usb_alphatrack_write(struct file *file, const char __user *buffer
usb_fill_int_urb(dev->interrupt_out_urb,
interface_to_usbdev(dev->intf),
usb_sndintpipe(interface_to_usbdev(dev->intf),
- dev->interrupt_out_endpoint->bEndpointAddress),
- dev->interrupt_out_buffer,
- bytes_to_write,
- usb_alphatrack_interrupt_out_callback,
- dev,
+ dev->interrupt_out_endpoint->
+ bEndpointAddress),
+ dev->interrupt_out_buffer, bytes_to_write,
+ usb_alphatrack_interrupt_out_callback, dev,
dev->interrupt_out_interval);
dev->interrupt_out_busy = 1;
atomic_inc(&dev->writes_pending);
@@ -618,12 +636,12 @@ exit:
/* file operations needed when we register this driver */
static const struct file_operations usb_alphatrack_fops = {
- .owner = THIS_MODULE,
- .read = usb_alphatrack_read,
- .write = usb_alphatrack_write,
- .open = usb_alphatrack_open,
- .release = usb_alphatrack_release,
- .poll = usb_alphatrack_poll,
+ .owner = THIS_MODULE,
+ .read = usb_alphatrack_read,
+ .write = usb_alphatrack_write,
+ .open = usb_alphatrack_open,
+ .release = usb_alphatrack_release,
+ .poll = usb_alphatrack_poll,
};
/*
@@ -632,19 +650,19 @@ static const struct file_operations usb_alphatrack_fops = {
*/
static struct usb_class_driver usb_alphatrack_class = {
- .name = "alphatrack%d",
- .fops = &usb_alphatrack_fops,
- .minor_base = USB_ALPHATRACK_MINOR_BASE,
+ .name = "alphatrack%d",
+ .fops = &usb_alphatrack_fops,
+ .minor_base = USB_ALPHATRACK_MINOR_BASE,
};
-
/**
* usb_alphatrack_probe
*
* Called by the usb core when a new device is connected that it thinks
* this driver might be interested in.
*/
-static int usb_alphatrack_probe(struct usb_interface *intf, const struct usb_device_id *id)
+static int usb_alphatrack_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);
struct usb_alphatrack *dev = NULL;
@@ -683,28 +701,35 @@ static int usb_alphatrack_probe(struct usb_interface *intf, const struct usb_dev
goto error;
}
if (dev->interrupt_out_endpoint == NULL)
- dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");
+ dev_warn(&intf->dev,
+ "Interrupt out endpoint not found"
+ "(using control endpoint instead)\n");
- dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
+ dev->interrupt_in_endpoint_size =
+ le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
if (dev->interrupt_in_endpoint_size != 64)
- dev_warn(&intf->dev, "Interrupt in endpoint size is not 64!\n");
-
- if(ring_buffer_size == 0) { ring_buffer_size = RING_BUFFER_SIZE; }
+ dev_warn(&intf->dev, "Interrupt in endpoint size is not 64!\n");
- true_size = min(ring_buffer_size,RING_BUFFER_SIZE);
+ if (ring_buffer_size == 0)
+ ring_buffer_size = RING_BUFFER_SIZE;
- /* FIXME - there are more usb_alloc routines for dma correctness. Needed? */
+ true_size = min(ring_buffer_size, RING_BUFFER_SIZE);
-// dev->ring_buffer = kmalloc((true_size*sizeof(struct alphatrack_icmd))+12, GFP_KERNEL);
- dev->ring_buffer = kmalloc((true_size*sizeof(struct alphatrack_icmd)), GFP_KERNEL);
+ /* FIXME - there are more usb_alloc routines for dma correctness.
+ Needed? */
+ dev->ring_buffer =
+ kmalloc((true_size * sizeof(struct alphatrack_icmd)), GFP_KERNEL);
if (!dev->ring_buffer) {
- dev_err(&intf->dev, "Couldn't allocate input ring_buffer of size %d\n",true_size);
+ dev_err(&intf->dev,
+ "Couldn't allocate input ring_buffer of size %d\n",
+ true_size);
goto error;
}
- dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
+ dev->interrupt_in_buffer =
+ kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
if (!dev->interrupt_in_buffer) {
dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n");
@@ -721,23 +746,30 @@ static int usb_alphatrack_probe(struct usb_interface *intf, const struct usb_dev
goto error;
}
- dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
- udev->descriptor.bMaxPacketSize0;
+ dev->interrupt_out_endpoint_size =
+ dev->interrupt_out_endpoint ? le16_to_cpu(dev->
+ interrupt_out_endpoint->
+ wMaxPacketSize) : udev->
+ descriptor.bMaxPacketSize0;
- if (dev->interrupt_out_endpoint_size !=64)
- dev_warn(&intf->dev, "Interrupt out endpoint size is not 64!)\n");
+ if (dev->interrupt_out_endpoint_size != 64)
+ dev_warn(&intf->dev,
+ "Interrupt out endpoint size is not 64!)\n");
- if(write_buffer_size == 0) { write_buffer_size = WRITE_BUFFER_SIZE; }
- true_size = min(write_buffer_size,WRITE_BUFFER_SIZE);
+ if (write_buffer_size == 0)
+ write_buffer_size = WRITE_BUFFER_SIZE;
+ true_size = min(write_buffer_size, WRITE_BUFFER_SIZE);
- dev->interrupt_out_buffer = kmalloc(true_size*dev->interrupt_out_endpoint_size, GFP_KERNEL);
+ dev->interrupt_out_buffer =
+ kmalloc(true_size * dev->interrupt_out_endpoint_size, GFP_KERNEL);
if (!dev->interrupt_out_buffer) {
dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n");
goto error;
}
- dev->write_buffer = kmalloc(sizeof(struct alphatrack_ocmd)*true_size, GFP_KERNEL);
+ dev->write_buffer =
+ kmalloc(sizeof(struct alphatrack_ocmd) * true_size, GFP_KERNEL);
if (!dev->write_buffer) {
dev_err(&intf->dev, "Couldn't allocate write_buffer \n");
@@ -749,25 +781,36 @@ static int usb_alphatrack_probe(struct usb_interface *intf, const struct usb_dev
dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
goto error;
}
- dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
+ dev->interrupt_in_interval =
+ min_interrupt_in_interval >
+ dev->interrupt_in_endpoint->
+ bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->
+ bInterval;
if (dev->interrupt_out_endpoint)
- dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;
+ dev->interrupt_out_interval =
+ min_interrupt_out_interval >
+ dev->interrupt_out_endpoint->
+ bInterval ? min_interrupt_out_interval : dev->
+ interrupt_out_endpoint->bInterval;
/* we can register the device now, as it is ready */
usb_set_intfdata(intf, dev);
- atomic_set(&dev->writes_pending,0);
+ atomic_set(&dev->writes_pending, 0);
retval = usb_register_dev(intf, &usb_alphatrack_class);
if (retval) {
/* something prevented us from registering this driver */
- dev_err(&intf->dev, "Not able to get a minor for this device.\n");
+ dev_err(&intf->dev,
+ "Not able to get a minor for this device.\n");
usb_set_intfdata(intf, NULL);
goto error;
}
/* let the user know what node this device is now attached to */
- dev_info(&intf->dev, "Alphatrack Device #%d now attached to major %d minor %d\n",
- (intf->minor - USB_ALPHATRACK_MINOR_BASE), USB_MAJOR, intf->minor);
+ dev_info(&intf->dev,
+ "Alphatrack Device #%d now attached to major %d minor %d\n",
+ (intf->minor - USB_ALPHATRACK_MINOR_BASE), USB_MAJOR,
+ intf->minor);
exit:
return retval;
@@ -809,7 +852,7 @@ static void usb_alphatrack_disconnect(struct usb_interface *intf)
up(&dev->sem);
}
- atomic_set(&dev->writes_pending,0);
+ atomic_set(&dev->writes_pending, 0);
mutex_unlock(&disconnect_mutex);
dev_info(&intf->dev, "Alphatrack Surface #%d now disconnected\n",
@@ -818,10 +861,10 @@ static void usb_alphatrack_disconnect(struct usb_interface *intf)
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver usb_alphatrack_driver = {
- .name = "alphatrack",
- .probe = usb_alphatrack_probe,
- .disconnect = usb_alphatrack_disconnect,
- .id_table = usb_alphatrack_table,
+ .name = "alphatrack",
+ .probe = usb_alphatrack_probe,
+ .disconnect = usb_alphatrack_disconnect,
+ .id_table = usb_alphatrack_table,
};
/**
@@ -834,7 +877,8 @@ static int __init usb_alphatrack_init(void)
/* register this driver with the USB subsystem */
retval = usb_register(&usb_alphatrack_driver);
if (retval)
- err("usb_register failed for the "__FILE__" driver. Error number %d\n", retval);
+ err("usb_register failed for the " __FILE__
+ " driver. Error number %d\n", retval);
return retval;
}
@@ -850,4 +894,3 @@ static void __exit usb_alphatrack_exit(void)
module_init(usb_alphatrack_init);
module_exit(usb_alphatrack_exit);
-
diff --git a/drivers/staging/frontier/alphatrack.h b/drivers/staging/frontier/alphatrack.h
index 35c90a90eb0..10a79726359 100644
--- a/drivers/staging/frontier/alphatrack.h
+++ b/drivers/staging/frontier/alphatrack.h
@@ -1,42 +1,38 @@
-#define show_set_bit(a) show_set_mbit(alphatrack,a)
-#define show_set_cmd(a) show_set_mcmd(alphatrack,a)
-#define show_set_int(a) show_set_mint(alphatrack,a)
-#define show_set_char(a) show_set_mchar(alphatrack,a)
-#define show_set_light(a) show_set_ebit(alphatrack,LightID,lights,a)
-#define show_set_button(a) show_set_ebit(alphatrack,ButtonID,button,a)
-
struct alphatrack_icmd {
- unsigned char cmd[12];
+ unsigned char cmd[12];
};
struct alphatrack_ocmd {
- unsigned char cmd[8];
+ unsigned char cmd[8];
};
+/* These are unused by the present driver but provide documentation for the
+ * userspace API.
+ */
enum LightID {
- LIGHT_EQ = 0,
- LIGHT_OUT,
- LIGHT_F2,
- LIGHT_SEND,
- LIGHT_IN,
- LIGHT_F1,
- LIGHT_PAN,
- LIGHT_UNDEF1,
- LIGHT_UNDEF2,
- LIGHT_SHIFT,
- LIGHT_TRACKMUTE,
- LIGHT_TRACKSOLO,
- LIGHT_TRACKREC,
- LIGHT_READ,
- LIGHT_WRITE,
- LIGHT_ANYSOLO,
- LIGHT_AUTO,
- LIGHT_F4,
- LIGHT_RECORD,
- LIGHT_WINDOW,
- LIGHT_PLUGIN,
- LIGHT_F3,
- LIGHT_LOOP
+ LIGHT_EQ = 0,
+ LIGHT_OUT,
+ LIGHT_F2,
+ LIGHT_SEND,
+ LIGHT_IN,
+ LIGHT_F1,
+ LIGHT_PAN,
+ LIGHT_UNDEF1,
+ LIGHT_UNDEF2,
+ LIGHT_SHIFT,
+ LIGHT_TRACKMUTE,
+ LIGHT_TRACKSOLO,
+ LIGHT_TRACKREC,
+ LIGHT_READ,
+ LIGHT_WRITE,
+ LIGHT_ANYSOLO,
+ LIGHT_AUTO,
+ LIGHT_F4,
+ LIGHT_RECORD,
+ LIGHT_WINDOW,
+ LIGHT_PLUGIN,
+ LIGHT_F3,
+ LIGHT_LOOP
};
#define BUTTONMASK_BATTERY 0x00004000
@@ -62,8 +58,9 @@ enum LightID {
#define BUTTONMASK_PRESS2 0x00008010
#define BUTTONMASK_PRESS3 0x00002020
-// last 3 bytes are the slider position
-// 40 is the actual slider moving, the most sig bits, and 3 lsb
+/* last 3 bytes are the slider position
+ * 40 is the actual slider moving, the most sig bits, and 3 lsb
+ */
#define BUTTONMASK_FLIP 0x40000000
#define BUTTONMASK_F1 0x00100000
@@ -76,17 +73,4 @@ enum LightID {
#define BUTTONMASK_PLUGIN 0x00000400
#define BUTTONMASK_AUTO 0x00000100
-
-// #define BUTTONMASK_FOOTSWITCH FIXME
-
-// Lookup. name. midi out. midi in.
-
-struct buttonmap_t {
- u32 mask;
- short midi_in;
- short midi_out;
- char *name;
-// void (*function) (buttonmap_t *);
- void (*function) (void);
-};
-
+/* #define BUTTONMASK_FOOTSWITCH FIXME */
diff --git a/drivers/staging/frontier/frontier_compat.h b/drivers/staging/frontier/frontier_compat.h
deleted file mode 100644
index 00450e637ac..00000000000
--- a/drivers/staging/frontier/frontier_compat.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* USB defines for older kernels */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-
-/**
- * usb_endpoint_dir_out - check if the endpoint has OUT direction
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint is of type OUT, otherwise it returns false.
- */
-
-static inline int usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd)
-{
- return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
-}
-
-static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
-{
- return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
-}
-
-
-/**
- * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint is of type interrupt, otherwise it returns
- * false.
- */
-static inline int usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd)
-{
- return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
- USB_ENDPOINT_XFER_INT);
-}
-
-
-/**
- * usb_endpoint_is_int_in - check if the endpoint is interrupt IN
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint has interrupt transfer type and IN direction,
- * otherwise it returns false.
- */
-
-static inline int usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd)
-{
- return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd));
-}
-
-/**
- * usb_endpoint_is_int_out - check if the endpoint is interrupt OUT
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint has interrupt transfer type and OUT direction,
- * otherwise it returns false.
- */
-
-static inline int usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd)
-{
- return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd));
-}
-
-#endif /* older kernel versions */
diff --git a/drivers/staging/frontier/surface_sysfs.h b/drivers/staging/frontier/surface_sysfs.h
deleted file mode 100644
index d50a562d658..00000000000
--- a/drivers/staging/frontier/surface_sysfs.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* If you are going to abuse the preprocessor, why not ABUSE the preprocessor?
- I stuck this header in a separate file so I don't have to look at it */
-
-// FIXME Need locking or atomic ops
-
-#define show_set_mbit(dname,value,bit) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int temp = (1 && (t->value & (1 << bit))); \
- return sprintf(buf, "%d\n", temp); \
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- if(temp > 0) { long b = 1 << bit; t->value |= b; } \
- else { long b = ~(1 << bit); t->value &= b ; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-#define show_set_ebit(dname,enumname,value,bit) \
-static ssize_t show_##bit(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- enum enumname l = bit; \
- int temp = t->value & (1 << l); \
- return sprintf(buf, "%d\n", temp); \
-} \
-static ssize_t set_##bit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- enum enumname l = bit;\
- long b = 1 << l; \
- if(temp > 0) { t->value |= b; } \
- else { t->value &= ~b ; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-// FIXME FOR CORRECTLY SETTING HEX from a string
-#define show_set_mcmd(dname,value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int count = 0;\
- int i; \
- for (i = 0,i<sizeof(dname); i++) count += snprintf(buf, "%02x",t->dname[i]); \
- return(count);\
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- t->value = temp; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-#define show_set_mint(dname,value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- return sprintf(buf, "%d\n", t->value); \
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- t->value = temp; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-#define show_set_mchar(dname,value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- return sprintf(buf, "%c\n", t->value); \
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- t->value = temp; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c
index 79abb6b16f7..274b82bd786 100644
--- a/drivers/staging/frontier/tranzport.c
+++ b/drivers/staging/frontier/tranzport.c
@@ -18,7 +18,7 @@
*
*/
-/**
+/*
* This driver uses a ring buffer for time critical reading of
* interrupt in reports and provides read and write methods for
* raw interrupt reports.
@@ -30,7 +30,7 @@
* as we only have 17 commands for the tranzport. In particular this is
* key for getting lights to flash in time as otherwise many commands
* can be buffered up before the light change makes it to the interface.
-*/
+ */
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -40,56 +40,47 @@
#include <linux/mutex.h>
#include <linux/version.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/poll.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-#include frontier_compat.h
-#endif
-
/* Define these values to match your devices */
#define VENDOR_ID 0x165b
-#define PRODUCT_ID 0x8101
+#define PRODUCT_ID 0x8101
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define USB_TRANZPORT_MINOR_BASE 0
-#else
-// FIXME 176 - is the ldusb driver's minor - apply for a minor soon
+#else /* FIXME 177- is the another driver's minor - apply for a minor soon */
#define USB_TRANZPORT_MINOR_BASE 177
#endif
/* table of devices that work with this driver */
-static struct usb_device_id usb_tranzport_table [] = {
- { USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
- { } /* Terminating entry */
+static struct usb_device_id usb_tranzport_table[] = {
+ {USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
+ {} /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, usb_tranzport_table);
-MODULE_VERSION("0.33");
+MODULE_VERSION("0.35");
MODULE_AUTHOR("Mike Taht <m@taht.net>");
MODULE_DESCRIPTION("Tranzport USB Driver");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("Frontier Designs Tranzport Control Surface");
-/* These two aren't done yet */
-
-#define SUPPRESS_EXTRA_ONLINE_EVENTS 0
-#define BUFFERED_WRITES 0
-
#define SUPPRESS_EXTRA_OFFLINE_EVENTS 1
#define COMPRESS_WHEEL_EVENTS 1
#define BUFFERED_READS 1
#define RING_BUFFER_SIZE 1000
#define WRITE_BUFFER_SIZE 34
#define TRANZPORT_USB_TIMEOUT 10
+#define TRANZPORT_DEBUG 0
-
-static int debug = 0;
+static int debug = TRANZPORT_DEBUG;
/* Use our own dbg macro */
-#define dbg_info(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
+#define dbg_info(dev, format, arg...) do \
+ { if (debug) dev_info(dev , format , ## arg); } while (0)
/* Module parameters */
@@ -102,13 +93,13 @@ MODULE_PARM_DESC(debug, "Debug enabled or not");
static int ring_buffer_size = RING_BUFFER_SIZE;
-module_param(ring_buffer_size, int, S_IRUGO);
+module_param(ring_buffer_size, int, S_IRUGO);
MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size in reports");
/* The write_buffer can one day contain more than one interrupt out transfer.
*/
static int write_buffer_size = WRITE_BUFFER_SIZE;
-module_param(write_buffer_size, int, S_IRUGO);
+module_param(write_buffer_size, int, S_IRUGO);
MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
/*
@@ -118,69 +109,48 @@ MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
static int min_interrupt_in_interval = TRANZPORT_USB_TIMEOUT;
module_param(min_interrupt_in_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_in_interval, "Minimum interrupt in interval in ms");
+MODULE_PARM_DESC(min_interrupt_in_interval,
+ "Minimum interrupt in interval in ms");
static int min_interrupt_out_interval = TRANZPORT_USB_TIMEOUT;
module_param(min_interrupt_out_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in ms");
+MODULE_PARM_DESC(min_interrupt_out_interval,
+ "Minimum interrupt out interval in ms");
struct tranzport_cmd {
- unsigned char cmd[8];
+ unsigned char cmd[8];
};
-enum LightID {
- LightRecord = 0,
- LightTrackrec,
- LightTrackmute,
- LightTracksolo,
- LightAnysolo,
- LightLoop,
- LightPunch
- };
-
/* Structure to hold all of our device specific stuff */
struct usb_tranzport {
- struct semaphore sem; /* locks this structure */
- struct usb_interface* intf; /* save off the usb interface pointer */
-
- int open_count; /* number of times this port has been opened */
-
- struct tranzport_cmd (*ring_buffer)[RING_BUFFER_SIZE]; /* just make c happy */
- unsigned int ring_head;
- unsigned int ring_tail;
-
- wait_queue_head_t read_wait;
- wait_queue_head_t write_wait;
-
- unsigned char* interrupt_in_buffer;
- struct usb_endpoint_descriptor* interrupt_in_endpoint;
- struct urb* interrupt_in_urb;
- int interrupt_in_interval;
- size_t interrupt_in_endpoint_size;
- int interrupt_in_running;
- int interrupt_in_done;
-
- char* interrupt_out_buffer;
- struct usb_endpoint_descriptor* interrupt_out_endpoint;
- struct urb* interrupt_out_urb;
- int interrupt_out_interval;
- size_t interrupt_out_endpoint_size;
- int interrupt_out_busy;
-
- /* Sysfs and translation support */
-
- int event; /* alternate interface to events */
- int wheel; /* - for negative, 0 for none, + for positive */
- unsigned char dump_state; /* 0 if disabled 1 if enabled */
- unsigned char enable; /* 0 if disabled 1 if enabled */
- unsigned char offline; /* if the device is out of range or asleep */
- unsigned char compress_wheel; /* flag to compress wheel events */
- unsigned char light; /* 7 bits used */
- unsigned char last_cmd[8];
- unsigned char last_input[8];
- unsigned char screen[40]; // We'll also have cells
-
+ struct semaphore sem; /* locks this structure */
+ struct usb_interface *intf; /* save off the usb interface pointer */
+ int open_count; /* number of times this port opened */
+ struct tranzport_cmd (*ring_buffer)[RING_BUFFER_SIZE];
+ unsigned int ring_head;
+ unsigned int ring_tail;
+ wait_queue_head_t read_wait;
+ wait_queue_head_t write_wait;
+ unsigned char *interrupt_in_buffer;
+ struct usb_endpoint_descriptor *interrupt_in_endpoint;
+ struct urb *interrupt_in_urb;
+ int interrupt_in_interval;
+ size_t interrupt_in_endpoint_size;
+ int interrupt_in_running;
+ int interrupt_in_done;
+ char *interrupt_out_buffer;
+ struct usb_endpoint_descriptor *interrupt_out_endpoint;
+ struct urb *interrupt_out_urb;
+ int interrupt_out_interval;
+ size_t interrupt_out_endpoint_size;
+ int interrupt_out_busy;
+
+ /* Sysfs support */
+
+ unsigned char enable; /* 0 if disabled 1 if enabled */
+ unsigned char offline; /* if the device is out of range or asleep */
+ unsigned char compress_wheel; /* flag to compress wheel events */
};
/* prevent races between open() and disconnect() */
@@ -205,84 +175,39 @@ static void usb_tranzport_abort_transfers(struct usb_tranzport *dev)
usb_kill_urb(dev->interrupt_out_urb);
}
-// FIXME ~light not good enough or correct - need atomic set_bit
-
-#define show_set_light(value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- enum LightID light = value; \
- int temp = (1 && (t->light & (1 << light))); \
- return sprintf(buf, "%d\n", temp ); \
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- enum LightID light = (temp << value) & (t->light << value); \
- t->light = (t->light & ~light) ; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-show_set_light(LightRecord);
-show_set_light(LightTrackrec);
-show_set_light(LightTrackmute);
-show_set_light(LightTracksolo);
-show_set_light(LightAnysolo);
-show_set_light(LightLoop);
-show_set_light(LightPunch);
-
-
-#define show_set_int(value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- \
- return sprintf(buf, "%d\n", t->value); \
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- \
- t->value = temp; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-show_set_int(enable);
-show_set_int(offline);
+#define show_int(value) \
+ static ssize_t show_##value(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+ { \
+ struct usb_interface *intf = to_usb_interface(dev); \
+ struct usb_tranzport *t = usb_get_intfdata(intf); \
+ return sprintf(buf, "%d\n", t->value); \
+ } \
+ static DEVICE_ATTR(value, S_IRUGO, show_##value, NULL);
+
+#define show_set_int(value) \
+ static ssize_t show_##value(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+ { \
+ struct usb_interface *intf = to_usb_interface(dev); \
+ struct usb_tranzport *t = usb_get_intfdata(intf); \
+ return sprintf(buf, "%d\n", t->value); \
+ } \
+ static ssize_t set_##value(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t count) \
+ { \
+ struct usb_interface *intf = to_usb_interface(dev); \
+ struct usb_tranzport *t = usb_get_intfdata(intf); \
+ int temp = simple_strtoul(buf, NULL, 10); \
+ t->value = temp; \
+ return count; \
+ } \
+ static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
+
+show_int(enable);
+show_int(offline);
show_set_int(compress_wheel);
-show_set_int(dump_state);
-show_set_int(wheel);
-show_set_int(event);
-
-#define show_set_cmd(value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- \
- return sprintf(buf, "%d\n", t->value); \
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- \
- t->value = temp; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-
-
/**
* usb_tranzport_delete
@@ -290,23 +215,10 @@ static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
static void usb_tranzport_delete(struct usb_tranzport *dev)
{
usb_tranzport_abort_transfers(dev);
- /* This is just too twisted to be correct */
- if(dev->intf != NULL) {
- device_remove_file(&dev->intf->dev, &dev_attr_LightRecord);
- device_remove_file(&dev->intf->dev, &dev_attr_LightTrackrec);
- device_remove_file(&dev->intf->dev, &dev_attr_LightTrackmute);
- device_remove_file(&dev->intf->dev, &dev_attr_LightTracksolo);
- device_remove_file(&dev->intf->dev, &dev_attr_LightTrackmute);
- device_remove_file(&dev->intf->dev, &dev_attr_LightAnysolo);
- device_remove_file(&dev->intf->dev, &dev_attr_LightLoop);
- device_remove_file(&dev->intf->dev, &dev_attr_LightPunch);
- device_remove_file(&dev->intf->dev, &dev_attr_wheel);
- device_remove_file(&dev->intf->dev, &dev_attr_enable);
- device_remove_file(&dev->intf->dev, &dev_attr_event);
- device_remove_file(&dev->intf->dev, &dev_attr_offline);
- device_remove_file(&dev->intf->dev, &dev_attr_compress_wheel);
-
- device_remove_file(&dev->intf->dev, &dev_attr_dump_state);
+ if (dev->intf != NULL) {
+ device_remove_file(&dev->intf->dev, &dev_attr_enable);
+ device_remove_file(&dev->intf->dev, &dev_attr_offline);
+ device_remove_file(&dev->intf->dev, &dev_attr_compress_wheel);
}
/* free data structures */
@@ -330,37 +242,56 @@ static void usb_tranzport_interrupt_in_callback(struct urb *urb)
if (urb->status) {
if (urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN) {
+ urb->status == -ECONNRESET ||
+ urb->status == -ESHUTDOWN) {
goto exit;
} else {
- dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
+ dbg_info(&dev->intf->dev,
+ "%s: nonzero status received: %d\n",
__func__, urb->status);
- goto resubmit; /* maybe we can recover */
+ goto resubmit; /* maybe we can recover */
}
}
if (urb->actual_length != 8) {
dev_warn(&dev->intf->dev,
- "Urb length was %d bytes!! Do something intelligent \n", urb->actual_length);
+ "Urb length was %d bytes!!"
+ "Do something intelligent \n",
+ urb->actual_length);
} else {
- dbg_info(&dev->intf->dev, "%s: received: %02x%02x%02x%02x%02x%02x%02x%02x\n",
- __func__, dev->interrupt_in_buffer[0],dev->interrupt_in_buffer[1],dev->interrupt_in_buffer[2],dev->interrupt_in_buffer[3],dev->interrupt_in_buffer[4],dev->interrupt_in_buffer[5],dev->interrupt_in_buffer[6],dev->interrupt_in_buffer[7]);
+ dbg_info(&dev->intf->dev,
+ "%s: received: %02x%02x%02x%02x%02x%02x%02x%02x\n",
+ __func__, dev->interrupt_in_buffer[0],
+ dev->interrupt_in_buffer[1],
+ dev->interrupt_in_buffer[2],
+ dev->interrupt_in_buffer[3],
+ dev->interrupt_in_buffer[4],
+ dev->interrupt_in_buffer[5],
+ dev->interrupt_in_buffer[6],
+ dev->interrupt_in_buffer[7]);
#if SUPPRESS_EXTRA_OFFLINE_EVENTS
- if(dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff) { goto resubmit; }
- if(dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 2; goto resubmit; }
+ if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff)
+ goto resubmit;
+ if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) {
+ dev->offline = 2;
+ goto resubmit;
+ }
-/* Always pass one offline event up the stack */
- if(dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff) { dev->offline = 0; }
- if(dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 1; }
+ /* Always pass one offline event up the stack */
+ if (dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff)
+ dev->offline = 0;
+ if (dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff)
+ dev->offline = 1;
-#endif
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
+#endif /* SUPPRESS_EXTRA_OFFLINE_EVENTS */
+ dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
+ __func__, dev->ring_head, dev->ring_tail);
- next_ring_head = (dev->ring_head+1) % ring_buffer_size;
+ next_ring_head = (dev->ring_head + 1) % ring_buffer_size;
if (next_ring_head != dev->ring_tail) {
- memcpy(&((*dev->ring_buffer)[dev->ring_head]), dev->interrupt_in_buffer, urb->actual_length);
+ memcpy(&((*dev->ring_buffer)[dev->ring_head]),
+ dev->interrupt_in_buffer, urb->actual_length);
dev->ring_head = next_ring_head;
retval = 0;
memset(dev->interrupt_in_buffer, 0, urb->actual_length);
@@ -373,7 +304,7 @@ static void usb_tranzport_interrupt_in_callback(struct urb *urb)
}
resubmit:
- /* resubmit if we're still running */
+/* resubmit if we're still running */
if (dev->interrupt_in_running && dev->intf) {
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
if (retval)
@@ -392,19 +323,17 @@ exit:
static void usb_tranzport_interrupt_out_callback(struct urb *urb)
{
struct usb_tranzport *dev = urb->context;
-
/* sync/async unlink faults aren't errors */
if (urb->status && !(urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN))
+ urb->status == -ECONNRESET ||
+ urb->status == -ESHUTDOWN))
dbg_info(&dev->intf->dev,
- "%s - nonzero write interrupt status received: %d\n",
- __func__, urb->status);
+ "%s - nonzero write interrupt status received: %d\n",
+ __func__, urb->status);
dev->interrupt_out_busy = 0;
wake_up_interruptible(&dev->write_wait);
}
-
/**
* usb_tranzport_open
*/
@@ -424,7 +353,7 @@ static int usb_tranzport_open(struct inode *inode, struct file *file)
if (!interface) {
err("%s - error, can't find device for minor %d\n",
- __func__, subminor);
+ __func__, subminor);
retval = -ENODEV;
goto unlock_disconnect_exit;
}
@@ -453,14 +382,14 @@ static int usb_tranzport_open(struct inode *inode, struct file *file)
dev->ring_head = 0;
dev->ring_tail = 0;
usb_fill_int_urb(dev->interrupt_in_urb,
- interface_to_usbdev(interface),
- usb_rcvintpipe(interface_to_usbdev(interface),
- dev->interrupt_in_endpoint->bEndpointAddress),
- dev->interrupt_in_buffer,
- dev->interrupt_in_endpoint_size,
- usb_tranzport_interrupt_in_callback,
- dev,
- dev->interrupt_in_interval);
+ interface_to_usbdev(interface),
+ usb_rcvintpipe(interface_to_usbdev(interface),
+ dev->interrupt_in_endpoint->
+ bEndpointAddress),
+ dev->interrupt_in_buffer,
+ dev->interrupt_in_endpoint_size,
+ usb_tranzport_interrupt_in_callback, dev,
+ dev->interrupt_in_interval);
dev->interrupt_in_running = 1;
dev->interrupt_in_done = 0;
@@ -470,7 +399,8 @@ static int usb_tranzport_open(struct inode *inode, struct file *file)
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
if (retval) {
- dev_err(&interface->dev, "Couldn't submit interrupt_in_urb %d\n", retval);
+ dev_err(&interface->dev,
+ "Couldn't submit interrupt_in_urb %d\n", retval);
dev->interrupt_in_running = 0;
dev->open_count = 0;
goto unlock_exit;
@@ -479,7 +409,6 @@ static int usb_tranzport_open(struct inode *inode, struct file *file)
/* save device in the file's private structure */
file->private_data = dev;
-
unlock_exit:
up(&dev->sem);
@@ -525,7 +454,9 @@ static int usb_tranzport_release(struct inode *inode, struct file *file)
/* wait until write transfer is finished */
if (dev->interrupt_out_busy)
- wait_event_interruptible_timeout(dev->write_wait, !dev->interrupt_out_busy, 2 * HZ);
+ wait_event_interruptible_timeout(dev->write_wait,
+ !dev->interrupt_out_busy,
+ 2 * HZ);
usb_tranzport_abort_transfers(dev);
dev->open_count = 0;
@@ -539,37 +470,31 @@ exit:
/**
* usb_tranzport_poll
*/
-static unsigned int usb_tranzport_poll(struct file *file, poll_table *wait)
+static unsigned int usb_tranzport_poll(struct file *file, poll_table * wait)
{
struct usb_tranzport *dev;
unsigned int mask = 0;
-
dev = file->private_data;
-
poll_wait(file, &dev->read_wait, wait);
poll_wait(file, &dev->write_wait, wait);
-
if (dev->ring_head != dev->ring_tail)
mask |= POLLIN | POLLRDNORM;
if (!dev->interrupt_out_busy)
mask |= POLLOUT | POLLWRNORM;
-
return mask;
}
-
/**
* usb_tranzport_read
*/
-static ssize_t usb_tranzport_read(struct file *file, char __user *buffer, size_t count,
- loff_t *ppos)
+
+static ssize_t usb_tranzport_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ppos)
{
struct usb_tranzport *dev;
int retval = 0;
-
#if BUFFERED_READS
int c = 0;
#endif
-
#if COMPRESS_WHEEL_EVENTS
signed char oldwheel;
signed char newwheel;
@@ -577,7 +502,7 @@ static ssize_t usb_tranzport_read(struct file *file, char __user *buffer, size_t
int next_tail;
#endif
-/* do I have such a thing as a null event? */
+ /* do I have such a thing as a null event? */
dev = file->private_data;
@@ -591,8 +516,7 @@ static ssize_t usb_tranzport_read(struct file *file, char __user *buffer, size_t
goto exit;
}
- /* verify that the device wasn't unplugged */
- if (dev->intf == NULL) {
+ /* verify that the device wasn't unplugged */ if (dev->intf == NULL) {
retval = -ENODEV;
err("No device or device unplugged %d\n", retval);
goto unlock_exit;
@@ -604,104 +528,149 @@ static ssize_t usb_tranzport_read(struct file *file, char __user *buffer, size_t
retval = -EAGAIN;
goto unlock_exit;
}
- // atomic_cmp_exchange(&dev->interrupt_in_done,0,0);
- dev->interrupt_in_done = 0 ; /* tiny race - FIXME: make atomic? */
- retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);
- if (retval < 0) {
+ /* tiny race - FIXME: make atomic? */
+ /* atomic_cmp_exchange(&dev->interrupt_in_done,0,0); */
+ dev->interrupt_in_done = 0;
+ retval = wait_event_interruptible(dev->read_wait,
+ dev->interrupt_in_done);
+ if (retval < 0)
goto unlock_exit;
- }
}
- dbg_info(&dev->intf->dev, "%s: copying to userspace: %02x%02x%02x%02x%02x%02x%02x%02x\n",
- __func__, (*dev->ring_buffer)[dev->ring_tail].cmd[0],(*dev->ring_buffer)[dev->ring_tail].cmd[1],(*dev->ring_buffer)[dev->ring_tail].cmd[2],(*dev->ring_buffer)[dev->ring_tail].cmd[3],(*dev->ring_buffer)[dev->ring_tail].cmd[4],(*dev->ring_buffer)[dev->ring_tail].cmd[5],(*dev->ring_buffer)[dev->ring_tail].cmd[6],(*dev->ring_buffer)[dev->ring_tail].cmd[7]);
+ dbg_info(&dev->intf->dev,
+ "%s: copying to userspace: "
+ "%02x%02x%02x%02x%02x%02x%02x%02x\n",
+ __func__,
+ (*dev->ring_buffer)[dev->ring_tail].cmd[0],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[1],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[2],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[3],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[4],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[5],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[6],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[7]);
#if BUFFERED_READS
- c = 0;
- while((c < count) && (dev->ring_tail != dev->ring_head)) {
+ c = 0;
+ while ((c < count) && (dev->ring_tail != dev->ring_head)) {
-/* This started off in the lower level service routine, and I moved it here. Then my brain died. Not done yet. */
#if COMPRESS_WHEEL_EVENTS
next_tail = (dev->ring_tail+1) % ring_buffer_size;
- if(dev->compress_wheel) cancompress = 1;
- while(dev->ring_head != next_tail && cancompress == 1 ) {
+ if (dev->compress_wheel)
+ cancompress = 1;
+ while (dev->ring_head != next_tail && cancompress == 1) {
newwheel = (*dev->ring_buffer)[next_tail].cmd[6];
oldwheel = (*dev->ring_buffer)[dev->ring_tail].cmd[6];
- // if both are wheel events, and no buttons have changes (FIXME, do I have to check?),
- // and we are the same sign, we can compress +- 7F
- // FIXME: saner check for overflow! - max of +- 7F
- // FIXME the math is wrong for going in reverse, actually, as the midi spec doesn't allow signed chars
-
- dbg_info(&dev->intf->dev, "%s: trying to compress: %02x%02x%02x%02x%02x %02x %02x %02x\n",
- __func__, (*dev->ring_buffer)[dev->ring_tail].cmd[0],(*dev->ring_buffer)[dev->ring_tail].cmd[1],(*dev->ring_buffer)[dev->ring_tail].cmd[2],(*dev->ring_buffer)[dev->ring_tail].cmd[3],(*dev->ring_buffer)[dev->ring_tail].cmd[4],(*dev->ring_buffer)[dev->ring_tail].cmd[5],(*dev->ring_buffer)[dev->ring_tail].cmd[6],(*dev->ring_buffer)[dev->ring_tail].cmd[7]);
-
-
- if(((*dev->ring_buffer)[dev->ring_tail].cmd[6] != 0 &&
- (*dev->ring_buffer)[next_tail].cmd[6] != 0 ) &&
+ /* if both are wheel events, and
+ no buttons have changes (FIXME, do I have to check?),
+ and we are the same sign, we can compress +- 7F
+ */
+ dbg_info(&dev->intf->dev,
+ "%s: trying to compress: "
+ "%02x%02x%02x%02x%02x%02x%02x%02x\n",
+ __func__,
+ (*dev->ring_buffer)[dev->ring_tail].cmd[0],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[1],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[2],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[3],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[4],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[5],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[6],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[7]);
+
+ if (((*dev->ring_buffer)[dev->ring_tail].cmd[6] != 0 &&
+ (*dev->ring_buffer)[next_tail].cmd[6] != 0) &&
((newwheel > 0 && oldwheel > 0) ||
- (newwheel < 0 && oldwheel < 0)) &&
- ((*dev->ring_buffer)[dev->ring_tail].cmd[2] == (*dev->ring_buffer)[next_tail].cmd[2]) &&
- ((*dev->ring_buffer)[dev->ring_tail].cmd[3] == (*dev->ring_buffer)[next_tail].cmd[3]) &&
- ((*dev->ring_buffer)[dev->ring_tail].cmd[4] == (*dev->ring_buffer)[next_tail].cmd[4]) &&
- ((*dev->ring_buffer)[dev->ring_tail].cmd[5] == (*dev->ring_buffer)[next_tail].cmd[5]))
- {
- dbg_info(&dev->intf->dev, "%s: should compress: %02x%02x%02x%02x%02x%02x%02x%02x\n",
- __func__, (*dev->ring_buffer)[dev->ring_tail].cmd[0],(*dev->ring_buffer)[dev->ring_tail].cmd[1],(*dev->ring_buffer)[dev->ring_tail].cmd[2],(*dev->ring_buffer)[dev->ring_tail].cmd[3],(*dev->ring_buffer)[dev->ring_tail].cmd[4],(*dev->ring_buffer)[dev->ring_tail].cmd[5],(*dev->ring_buffer)[dev->ring_tail].cmd[6],(*dev->ring_buffer)[dev->ring_tail].cmd[7]);
-
+ (newwheel < 0 && oldwheel < 0)) &&
+ ((*dev->ring_buffer)[dev->ring_tail].cmd[2] ==
+ (*dev->ring_buffer)[next_tail].cmd[2]) &&
+ ((*dev->ring_buffer)[dev->ring_tail].cmd[3] ==
+ (*dev->ring_buffer)[next_tail].cmd[3]) &&
+ ((*dev->ring_buffer)[dev->ring_tail].cmd[4] ==
+ (*dev->ring_buffer)[next_tail].cmd[4]) &&
+ ((*dev->ring_buffer)[dev->ring_tail].cmd[5] ==
+ (*dev->ring_buffer)[next_tail].cmd[5])) {
+ dbg_info(&dev->intf->dev,
+ "%s: should compress: "
+ "%02x%02x%02x%02x%02x%02x%02x%02x\n",
+ __func__,
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[0],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[1],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[2],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[3],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[4],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[5],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[6],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[7]);
newwheel += oldwheel;
- if(oldwheel > 0 && !(newwheel > 0)) {
+ if (oldwheel > 0 && !(newwheel > 0)) {
newwheel = 0x7f;
cancompress = 0;
}
- if(oldwheel < 0 && !(newwheel < 0)) {
+ if (oldwheel < 0 && !(newwheel < 0)) {
newwheel = 0x80;
cancompress = 0;
}
- (*dev->ring_buffer)[next_tail].cmd[6] = newwheel;
+ (*dev->ring_buffer)[next_tail].cmd[6] =
+ newwheel;
dev->ring_tail = next_tail;
- next_tail = (dev->ring_tail+1) % ring_buffer_size;
+ next_tail =
+ (dev->ring_tail + 1) % ring_buffer_size;
} else {
cancompress = 0;
}
}
#endif /* COMPRESS_WHEEL_EVENTS */
-
- if (copy_to_user(&buffer[c], &(*dev->ring_buffer)[dev->ring_tail], 8)) {
+ if (copy_to_user(
+ &buffer[c],
+ &(*dev->ring_buffer)[dev->ring_tail], 8)) {
retval = -EFAULT;
goto unlock_exit;
}
-
- dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;
- c+=8;
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
- }
- retval = c;
+ dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
+ c += 8;
+ dbg_info(&dev->intf->dev,
+ "%s: head, tail are %x, %x\n",
+ __func__, dev->ring_head, dev->ring_tail);
+ }
+ retval = c;
#else
- if (copy_to_user(buffer, &(*dev->ring_buffer)[dev->ring_tail], 8)) {
- retval = -EFAULT;
- goto unlock_exit;
- }
+/* if (copy_to_user(buffer, &(*dev->ring_buffer)[dev->ring_tail], 8)) { */
+ retval = -EFAULT;
+ goto unlock_exit;
+}
- dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
+dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
+dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
+ __func__, dev->ring_head, dev->ring_tail);
- retval = 8;
+retval = 8;
#endif /* BUFFERED_READS */
unlock_exit:
- /* unlock the device */
- up(&dev->sem);
+/* unlock the device */
+up(&dev->sem);
exit:
- return retval;
+return retval;
}
/**
* usb_tranzport_write
*/
-static ssize_t usb_tranzport_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
+static ssize_t usb_tranzport_write(struct file *file,
+ const char __user *buffer, size_t count,
+ loff_t *ppos)
{
struct usb_tranzport *dev;
size_t bytes_to_write;
@@ -718,7 +687,6 @@ static ssize_t usb_tranzport_write(struct file *file, const char __user *buffer,
retval = -ERESTARTSYS;
goto exit;
}
-
/* verify that the device wasn't unplugged */
if (dev->intf == NULL) {
retval = -ENODEV;
@@ -732,18 +700,24 @@ static ssize_t usb_tranzport_write(struct file *file, const char __user *buffer,
retval = -EAGAIN;
goto unlock_exit;
}
- retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy);
- if (retval < 0) {
+ retval = wait_event_interruptible(dev->write_wait,
+ !dev->interrupt_out_busy);
+ if (retval < 0)
goto unlock_exit;
- }
}
/* write the data into interrupt_out_buffer from userspace */
- bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
+ bytes_to_write = min(count,
+ write_buffer_size *
+ dev->interrupt_out_endpoint_size);
if (bytes_to_write < count)
- dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write);
+ dev_warn(&dev->intf->dev,
+ "Write buffer overflow, %zd bytes dropped\n",
+ count - bytes_to_write);
- dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write);
+ dbg_info(&dev->intf->dev,
+ "%s: count = %zd, bytes_to_write = %zd\n", __func__,
+ count, bytes_to_write);
if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
retval = -EFAULT;
@@ -757,14 +731,13 @@ static ssize_t usb_tranzport_write(struct file *file, const char __user *buffer,
/* send off the urb */
usb_fill_int_urb(dev->interrupt_out_urb,
- interface_to_usbdev(dev->intf),
- usb_sndintpipe(interface_to_usbdev(dev->intf),
- dev->interrupt_out_endpoint->bEndpointAddress),
- dev->interrupt_out_buffer,
- bytes_to_write,
- usb_tranzport_interrupt_out_callback,
- dev,
- dev->interrupt_out_interval);
+ interface_to_usbdev(dev->intf),
+ usb_sndintpipe(interface_to_usbdev(dev->intf),
+ dev->interrupt_out_endpoint->
+ bEndpointAddress),
+ dev->interrupt_out_buffer, bytes_to_write,
+ usb_tranzport_interrupt_out_callback, dev,
+ dev->interrupt_out_interval);
dev->interrupt_out_busy = 1;
wmb();
@@ -787,12 +760,12 @@ exit:
/* file operations needed when we register this driver */
static const struct file_operations usb_tranzport_fops = {
- .owner = THIS_MODULE,
- .read = usb_tranzport_read,
- .write = usb_tranzport_write,
- .open = usb_tranzport_open,
- .release = usb_tranzport_release,
- .poll = usb_tranzport_poll,
+ .owner = THIS_MODULE,
+ .read = usb_tranzport_read,
+ .write = usb_tranzport_write,
+ .open = usb_tranzport_open,
+ .release = usb_tranzport_release,
+ .poll = usb_tranzport_poll,
};
/*
@@ -800,20 +773,19 @@ static const struct file_operations usb_tranzport_fops = {
* and to have the device registered with the driver core
*/
static struct usb_class_driver usb_tranzport_class = {
- .name = "tranzport%d",
- .fops = &usb_tranzport_fops,
- .minor_base = USB_TRANZPORT_MINOR_BASE,
+ .name = "tranzport%d",
+ .fops = &usb_tranzport_fops,
+ .minor_base = USB_TRANZPORT_MINOR_BASE,
};
-
/**
* usb_tranzport_probe
*
* Called by the usb core when a new device is connected that it thinks
* this driver might be interested in.
*/
-static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
+static int usb_tranzport_probe(struct usb_interface *intf,
+ const struct usb_device_id *id) {
struct usb_device *udev = interface_to_usbdev(intf);
struct usb_tranzport *dev = NULL;
struct usb_host_interface *iface_desc;
@@ -824,7 +796,7 @@ static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_devi
/* allocate memory for our device state and intialize it */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
dev_err(&intf->dev, "Out of memory\n");
goto exit;
@@ -851,25 +823,33 @@ static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_devi
goto error;
}
if (dev->interrupt_out_endpoint == NULL)
- dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");
-
+ dev_warn(&intf->dev,
+ "Interrupt out endpoint not found"
+ "(using control endpoint instead)\n");
- dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
+ dev->interrupt_in_endpoint_size =
+ le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
if (dev->interrupt_in_endpoint_size != 8)
- dev_warn(&intf->dev, "Interrupt in endpoint size is not 8!\n");
+ dev_warn(&intf->dev, "Interrupt in endpoint size is not 8!\n");
- if(ring_buffer_size == 0) { ring_buffer_size = RING_BUFFER_SIZE; }
- true_size = min(ring_buffer_size,RING_BUFFER_SIZE);
- /* FIXME - there are more usb_alloc routines for dma correctness. Needed? */
+ if (ring_buffer_size == 0)
+ ring_buffer_size = RING_BUFFER_SIZE;
+ true_size = min(ring_buffer_size, RING_BUFFER_SIZE);
- dev->ring_buffer = kmalloc((true_size*sizeof(struct tranzport_cmd))+8, GFP_KERNEL);
+ /* FIXME - there are more usb_alloc routines for dma correctness.
+ Needed? */
+
+ dev->ring_buffer =
+ kmalloc((true_size * sizeof(struct tranzport_cmd)) + 8, GFP_KERNEL);
if (!dev->ring_buffer) {
- dev_err(&intf->dev, "Couldn't allocate ring_buffer of size %d\n",true_size);
+ dev_err(&intf->dev,
+ "Couldn't allocate ring_buffer size %d\n", true_size);
goto error;
}
- dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
+ dev->interrupt_in_buffer =
+ kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
if (!dev->interrupt_in_buffer) {
dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n");
goto error;
@@ -879,13 +859,18 @@ static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_devi
dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n");
goto error;
}
- dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
- udev->descriptor.bMaxPacketSize0;
+ dev->interrupt_out_endpoint_size =
+ dev->interrupt_out_endpoint ?
+ le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
+ udev->descriptor.bMaxPacketSize0;
- if (dev->interrupt_out_endpoint_size !=8)
- dev_warn(&intf->dev, "Interrupt out endpoint size is not 8!)\n");
+ if (dev->interrupt_out_endpoint_size != 8)
+ dev_warn(&intf->dev,
+ "Interrupt out endpoint size is not 8!)\n");
- dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL);
+ dev->interrupt_out_buffer =
+ kmalloc(write_buffer_size * dev->interrupt_out_endpoint_size,
+ GFP_KERNEL);
if (!dev->interrupt_out_buffer) {
dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n");
goto error;
@@ -895,9 +880,18 @@ static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_devi
dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
goto error;
}
- dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
- if (dev->interrupt_out_endpoint)
- dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;
+ dev->interrupt_in_interval =
+ min_interrupt_in_interval >
+ dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval
+ : dev->interrupt_in_endpoint->bInterval;
+
+ if (dev->interrupt_out_endpoint) {
+ dev->interrupt_out_interval =
+ min_interrupt_out_interval >
+ dev->interrupt_out_endpoint->bInterval ?
+ min_interrupt_out_interval :
+ dev->interrupt_out_endpoint->bInterval;
+ }
/* we can register the device now, as it is ready */
usb_set_intfdata(intf, dev);
@@ -905,35 +899,33 @@ static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_devi
retval = usb_register_dev(intf, &usb_tranzport_class);
if (retval) {
/* something prevented us from registering this driver */
- dev_err(&intf->dev, "Not able to get a minor for this device.\n");
+ dev_err(&intf->dev,
+ "Not able to get a minor for this device.\n");
usb_set_intfdata(intf, NULL);
goto error;
}
- if((retval = device_create_file(&intf->dev, &dev_attr_LightRecord))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_LightTrackrec))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_LightTrackmute))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_LightTracksolo))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_LightAnysolo))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_LightLoop))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_LightPunch))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_wheel))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_event))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_dump_state))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_compress_wheel))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_enable))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_offline))) goto error;
+ retval = device_create_file(&intf->dev, &dev_attr_compress_wheel);
+ if (retval)
+ goto error;
+ retval = device_create_file(&intf->dev, &dev_attr_enable);
+ if (retval)
+ goto error;
+ retval = device_create_file(&intf->dev, &dev_attr_offline);
+ if (retval)
+ goto error;
/* let the user know what node this device is now attached to */
- dev_info(&intf->dev, "Tranzport Device #%d now attached to major %d minor %d\n",
- (intf->minor - USB_TRANZPORT_MINOR_BASE), USB_MAJOR, intf->minor);
+ dev_info(&intf->dev,
+ "Tranzport Device #%d now attached to major %d minor %d\n",
+ (intf->minor - USB_TRANZPORT_MINOR_BASE), USB_MAJOR,
+ intf->minor);
exit:
return retval;
error:
usb_tranzport_delete(dev);
-
return retval;
}
@@ -966,15 +958,15 @@ static void usb_tranzport_disconnect(struct usb_interface *intf)
mutex_unlock(&disconnect_mutex);
dev_info(&intf->dev, "Tranzport Surface #%d now disconnected\n",
- (minor - USB_TRANZPORT_MINOR_BASE));
+ (minor - USB_TRANZPORT_MINOR_BASE));
}
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver usb_tranzport_driver = {
- .name = "tranzport",
- .probe = usb_tranzport_probe,
- .disconnect = usb_tranzport_disconnect,
- .id_table = usb_tranzport_table,
+ .name = "tranzport",
+ .probe = usb_tranzport_probe,
+ .disconnect = usb_tranzport_disconnect,
+ .id_table = usb_tranzport_table,
};
/**
@@ -987,14 +979,14 @@ static int __init usb_tranzport_init(void)
/* register this driver with the USB subsystem */
retval = usb_register(&usb_tranzport_driver);
if (retval)
- err("usb_register failed for the "__FILE__" driver. Error number %d\n", retval);
-
+ err("usb_register failed for the " __FILE__
+ " driver. Error number %d\n", retval);
return retval;
}
-
/**
* usb_tranzport_exit
*/
+
static void __exit usb_tranzport_exit(void)
{
/* deregister this driver with the USB subsystem */
@@ -1003,4 +995,3 @@ static void __exit usb_tranzport_exit(void)
module_init(usb_tranzport_init);
module_exit(usb_tranzport_exit);
-
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig
index f2cf7f66ae0..ca6ade6c4b4 100644
--- a/drivers/staging/go7007/Kconfig
+++ b/drivers/staging/go7007/Kconfig
@@ -10,7 +10,7 @@ config VIDEO_GO7007
select CRC32
default N
---help---
- This is a video4linux driver for some wierd device...
+ This is a video4linux driver for some weird device...
To compile this driver as a module, choose M here: the
module will be called go7007
@@ -20,7 +20,7 @@ config VIDEO_GO7007_USB
depends on VIDEO_GO7007 && USB
default N
---help---
- This is a video4linux driver for some wierd device...
+ This is a video4linux driver for some weird device...
To compile this driver as a module, choose M here: the
module will be called go7007-usb
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
index 868edb65e7b..06cacd37bbd 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -1827,7 +1827,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
static struct video_device go7007_template = {
.name = "go7007",
- .vfl_type = VID_TYPE_CAPTURE,
.fops = &go7007_fops,
.minor = -1,
.release = go7007_vfl_release,
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index fb6845e3788..d333ea2cd77 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -149,7 +149,7 @@ static int go7007_usb_vendor_request(struct go7007 *go, u16 request,
static int write_reg(struct i2c_client *client, u8 reg, u8 value)
{
struct go7007 *go = i2c_get_adapdata(client->adapter);
- struct go7007_usb *usb = go->hpi_context;
+ struct go7007_usb *usb;
int rc;
int dev_addr = client->addr;
u8 *buf;
@@ -164,8 +164,10 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value)
if (buf == NULL)
return -ENOMEM;
+ usb = go->hpi_context;
if (down_interruptible(&usb->i2c_lock) != 0) {
printk(KERN_INFO "i2c lock failed\n");
+ kfree(buf);
return -EINTR;
}
rc = go7007_usb_vendor_request(go, 0x55, dev_addr,
@@ -181,7 +183,7 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value)
static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
{
struct go7007 *go = i2c_get_adapdata(client->adapter);
- struct go7007_usb *usb = go->hpi_context;
+ struct go7007_usb *usb;
u8 *buf;
struct s2250 *dec = i2c_get_clientdata(client);
@@ -200,6 +202,7 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
memset(buf, 0xcd, 6);
+ usb = go->hpi_context;
if (down_interruptible(&usb->i2c_lock) != 0) {
printk(KERN_INFO "i2c lock failed\n");
return -EINTR;
diff --git a/drivers/staging/heci/Kconfig b/drivers/staging/heci/Kconfig
new file mode 100644
index 00000000000..ae8d588d3a2
--- /dev/null
+++ b/drivers/staging/heci/Kconfig
@@ -0,0 +1,6 @@
+config HECI
+ tristate "Intel Management Engine Interface (MEI) Support"
+ ---help---
+ The Intel Management Engine Interface (Intel MEI) driver allows
+ applications to access the Active Management Technology
+ firmware and other Management Engine sub-systems.
diff --git a/drivers/staging/heci/Makefile b/drivers/staging/heci/Makefile
new file mode 100644
index 00000000000..0524856fa3a
--- /dev/null
+++ b/drivers/staging/heci/Makefile
@@ -0,0 +1,9 @@
+obj-$(CONFIG_HECI) += heci.o
+
+heci-objs := \
+ heci_init.o \
+ interrupt.o \
+ heci_interface.o \
+ io_heci.o \
+ heci_main.o
+
diff --git a/drivers/staging/heci/TODO b/drivers/staging/heci/TODO
new file mode 100644
index 00000000000..f86715d631c
--- /dev/null
+++ b/drivers/staging/heci/TODO
@@ -0,0 +1,6 @@
+TODO:
+ - fix user/kernel pointer mess in the ioctl handlers as pointed
+ out by sparse.
+ - resolve the ioctls and see if most of them can just be simple
+ sysfs files
+ - fix locking issues that sparse points out at the least.
diff --git a/drivers/staging/heci/heci.h b/drivers/staging/heci/heci.h
new file mode 100644
index 00000000000..14192e0cc22
--- /dev/null
+++ b/drivers/staging/heci/heci.h
@@ -0,0 +1,176 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#ifndef _HECI_H_
+#define _HECI_H_
+
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+#include <linux/aio.h>
+#include <linux/types.h>
+#include "heci_data_structures.h"
+
+extern const struct guid heci_pthi_guid;
+extern const struct guid heci_wd_guid;
+extern const __u8 heci_start_wd_params[];
+extern const __u8 heci_stop_wd_params[];
+extern const __u8 heci_wd_state_independence_msg[3][4];
+
+/*
+ * heci device ID
+ */
+#define HECI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */
+#define HECI_DEV_ID_82G35 0x2984 /* 82G35 Express */
+#define HECI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */
+#define HECI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */
+
+#define HECI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */
+#define HECI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */
+
+#define HECI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */
+#define HECI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */
+#define HECI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */
+#define HECI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */
+#define HECI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */
+
+#define HECI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */
+#define HECI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */
+#define HECI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */
+#define HECI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */
+#define HECI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */
+
+#define HECI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */
+#define HECI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */
+#define HECI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */
+#define HECI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */
+
+#define HECI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */
+#define HECI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */
+#define HECI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */
+#define HECI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */
+
+/*
+ * heci init function prototypes
+ */
+struct iamt_heci_device *init_heci_device(struct pci_dev *pdev);
+void heci_reset(struct iamt_heci_device *dev, int interrupts);
+int heci_hw_init(struct iamt_heci_device *dev);
+int heci_task_initialize_clients(void *data);
+int heci_initialize_clients(struct iamt_heci_device *dev);
+struct heci_file_private *heci_alloc_file_private(struct file *file);
+int heci_disconnect_host_client(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+void heci_initialize_list(struct io_heci_list *list,
+ struct iamt_heci_device *dev);
+void heci_flush_list(struct io_heci_list *list,
+ struct heci_file_private *file_ext);
+void heci_flush_queues(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+
+void heci_remove_client_from_file_list(struct iamt_heci_device *dev,
+ __u8 host_client_id);
+
+/*
+ * interrupt function prototype
+ */
+irqreturn_t heci_isr_interrupt(int irq, void *dev_id);
+
+void heci_wd_timer(unsigned long data);
+
+/*
+ * input output function prototype
+ */
+int heci_ioctl_get_version(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data __user *u_msg,
+ struct heci_message_data k_msg,
+ struct heci_file_private *file_ext);
+
+int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data __user *u_msg,
+ struct heci_message_data k_msg,
+ struct file *file);
+
+int heci_ioctl_wd(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data k_msg,
+ struct heci_file_private *file_ext);
+
+int heci_ioctl_bypass_wd(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data k_msg,
+ struct heci_file_private *file_ext);
+
+int heci_start_read(struct iamt_heci_device *dev, int if_num,
+ struct heci_file_private *file_ext);
+
+int pthi_write(struct iamt_heci_device *dev,
+ struct heci_cb_private *priv_cb);
+
+int pthi_read(struct iamt_heci_device *dev, int if_num, struct file *file,
+ char __user *ubuf, size_t length, loff_t *offset);
+
+struct heci_cb_private *find_pthi_read_list_entry(
+ struct iamt_heci_device *dev,
+ struct file *file);
+
+void run_next_iamthif_cmd(struct iamt_heci_device *dev);
+
+void heci_free_cb_private(struct heci_cb_private *priv_cb);
+
+/**
+ * heci_fe_same_id - tell if file private data have same id
+ *
+ * @fe1: private data of 1. file object
+ * @fe2: private data of 2. file object
+ *
+ * returns !=0 - if ids are the same, 0 - if differ.
+ */
+static inline int heci_fe_same_id(const struct heci_file_private *fe1,
+ const struct heci_file_private *fe2)
+{
+ return ((fe1->host_client_id == fe2->host_client_id)
+ && (fe1->me_client_id == fe2->me_client_id));
+}
+
+#endif /* _HECI_H_ */
diff --git a/drivers/staging/heci/heci_data_structures.h b/drivers/staging/heci/heci_data_structures.h
new file mode 100644
index 00000000000..575e8f8e88a
--- /dev/null
+++ b/drivers/staging/heci/heci_data_structures.h
@@ -0,0 +1,530 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#ifndef _HECI_DATA_STRUCTURES_H_
+#define _HECI_DATA_STRUCTURES_H_
+
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+#include <linux/aio.h>
+#include <linux/types.h>
+
+/*
+ * error code definition
+ */
+#define ESLOTS_OVERFLOW 1
+#define ECORRUPTED_MESSAGE_HEADER 1000
+#define ECOMPLETE_MESSAGE 1001
+
+#define HECI_FC_MESSAGE_RESERVED_LENGTH 5
+
+/*
+ * Number of queue lists used by this driver
+ */
+#define HECI_IO_LISTS_NUMBER 7
+
+/*
+ * Maximum transmission unit (MTU) of heci messages
+ */
+#define IAMTHIF_MTU 4160
+
+
+/*
+ * HECI HW Section
+ */
+
+/* HECI registers */
+/* H_CB_WW - Host Circular Buffer (CB) Write Window register */
+#define H_CB_WW 0
+/* H_CSR - Host Control Status register */
+#define H_CSR 4
+/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */
+#define ME_CB_RW 8
+/* ME_CSR_HA - ME Control Status Host Access register (read only) */
+#define ME_CSR_HA 0xC
+
+
+/* register bits of H_CSR (Host Control Status register) */
+/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */
+#define H_CBD 0xFF000000
+/* Host Circular Buffer Write Pointer */
+#define H_CBWP 0x00FF0000
+/* Host Circular Buffer Read Pointer */
+#define H_CBRP 0x0000FF00
+/* Host Reset */
+#define H_RST 0x00000010
+/* Host Ready */
+#define H_RDY 0x00000008
+/* Host Interrupt Generate */
+#define H_IG 0x00000004
+/* Host Interrupt Status */
+#define H_IS 0x00000002
+/* Host Interrupt Enable */
+#define H_IE 0x00000001
+
+
+/* register bits of ME_CSR_HA (ME Control Status Host Access register) */
+/* ME CB (Circular Buffer) Depth HRA (Host Read Access)
+ * - host read only access to ME_CBD */
+#define ME_CBD_HRA 0xFF000000
+/* ME CB Write Pointer HRA - host read only access to ME_CBWP */
+#define ME_CBWP_HRA 0x00FF0000
+/* ME CB Read Pointer HRA - host read only access to ME_CBRP */
+#define ME_CBRP_HRA 0x0000FF00
+/* ME Reset HRA - host read only access to ME_RST */
+#define ME_RST_HRA 0x00000010
+/* ME Ready HRA - host read only access to ME_RDY */
+#define ME_RDY_HRA 0x00000008
+/* ME Interrupt Generate HRA - host read only access to ME_IG */
+#define ME_IG_HRA 0x00000004
+/* ME Interrupt Status HRA - host read only access to ME_IS */
+#define ME_IS_HRA 0x00000002
+/* ME Interrupt Enable HRA - host read only access to ME_IE */
+#define ME_IE_HRA 0x00000001
+
+#define HECI_MINORS_BASE 1
+#define HECI_MINORS_COUNT 1
+
+#define HECI_MINOR_NUMBER 1
+#define HECI_MAX_OPEN_HANDLE_COUNT 253
+
+/*
+ * debug kernel print macro define
+ */
+extern int heci_debug;
+
+#define DBG(format, arg...) do { \
+ if (heci_debug) \
+ printk(KERN_INFO "heci: %s: " format, __func__, ## arg); \
+} while (0)
+
+
+/*
+ * time to wait HECI become ready after init
+ */
+#define HECI_INTEROP_TIMEOUT (HZ * 7)
+
+/*
+ * watch dog definition
+ */
+#define HECI_WATCHDOG_DATA_SIZE 16
+#define HECI_START_WD_DATA_SIZE 20
+#define HECI_WD_PARAMS_SIZE 4
+#define HECI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0)
+
+#define HECI_WD_HOST_CLIENT_ID 1
+#define HECI_IAMTHIF_HOST_CLIENT_ID 2
+
+struct guid {
+ __u32 data1;
+ __u16 data2;
+ __u16 data3;
+ __u8 data4[8];
+};
+
+/* File state */
+enum file_state {
+ HECI_FILE_INITIALIZING = 0,
+ HECI_FILE_CONNECTING,
+ HECI_FILE_CONNECTED,
+ HECI_FILE_DISCONNECTING,
+ HECI_FILE_DISCONNECTED
+};
+
+/* HECI device states */
+enum heci_states {
+ HECI_INITIALIZING = 0,
+ HECI_ENABLED,
+ HECI_RESETING,
+ HECI_DISABLED,
+ HECI_RECOVERING_FROM_RESET,
+ HECI_POWER_DOWN,
+ HECI_POWER_UP
+};
+
+enum iamthif_states {
+ HECI_IAMTHIF_IDLE,
+ HECI_IAMTHIF_WRITING,
+ HECI_IAMTHIF_FLOW_CONTROL,
+ HECI_IAMTHIF_READING,
+ HECI_IAMTHIF_READ_COMPLETE
+};
+
+enum heci_file_transaction_states {
+ HECI_IDLE,
+ HECI_WRITING,
+ HECI_WRITE_COMPLETE,
+ HECI_FLOW_CONTROL,
+ HECI_READING,
+ HECI_READ_COMPLETE
+};
+
+/* HECI CB */
+enum heci_cb_major_types {
+ HECI_READ = 0,
+ HECI_WRITE,
+ HECI_IOCTL,
+ HECI_OPEN,
+ HECI_CLOSE
+};
+
+/* HECI user data struct */
+struct heci_message_data {
+ __u32 size;
+ char *data;
+} __attribute__((packed));
+
+#define HECI_CONNECT_TIMEOUT 3 /* at least 2 seconds */
+
+#define IAMTHIF_STALL_TIMER 12 /* seconds */
+#define IAMTHIF_READ_TIMER 15 /* seconds */
+
+struct heci_cb_private {
+ struct list_head cb_list;
+ enum heci_cb_major_types major_file_operations;
+ void *file_private;
+ struct heci_message_data request_buffer;
+ struct heci_message_data response_buffer;
+ unsigned long information;
+ unsigned long read_time;
+ struct file *file_object;
+};
+
+/* Private file struct */
+struct heci_file_private {
+ struct list_head link;
+ struct file *file;
+ enum file_state state;
+ wait_queue_head_t tx_wait;
+ wait_queue_head_t rx_wait;
+ wait_queue_head_t wait;
+ spinlock_t file_lock; /* file lock */
+ spinlock_t read_io_lock; /* read lock */
+ spinlock_t write_io_lock; /* write lock */
+ int read_pending;
+ int status;
+ /* ID of client connected */
+ __u8 host_client_id;
+ __u8 me_client_id;
+ __u8 flow_ctrl_creds;
+ __u8 timer_count;
+ enum heci_file_transaction_states reading_state;
+ enum heci_file_transaction_states writing_state;
+ int sm_state;
+ struct heci_cb_private *read_cb;
+};
+
+struct io_heci_list {
+ struct heci_cb_private heci_cb;
+ int status;
+ struct iamt_heci_device *device_extension;
+};
+
+struct heci_driver_version {
+ __u8 major;
+ __u8 minor;
+ __u8 hotfix;
+ __u16 build;
+} __attribute__((packed));
+
+
+struct heci_client {
+ __u32 max_msg_length;
+ __u8 protocol_version;
+} __attribute__((packed));
+
+/*
+ * HECI BUS Interface Section
+ */
+struct heci_msg_hdr {
+ __u32 me_addr:8;
+ __u32 host_addr:8;
+ __u32 length:9;
+ __u32 reserved:6;
+ __u32 msg_complete:1;
+} __attribute__((packed));
+
+
+struct hbm_cmd {
+ __u8 cmd:7;
+ __u8 is_response:1;
+} __attribute__((packed));
+
+
+struct heci_bus_message {
+ struct hbm_cmd cmd;
+ __u8 command_specific_data[];
+} __attribute__((packed));
+
+struct hbm_version {
+ __u8 minor_version;
+ __u8 major_version;
+} __attribute__((packed));
+
+struct hbm_host_version_request {
+ struct hbm_cmd cmd;
+ __u8 reserved;
+ struct hbm_version host_version;
+} __attribute__((packed));
+
+struct hbm_host_version_response {
+ struct hbm_cmd cmd;
+ int host_version_supported;
+ struct hbm_version me_max_version;
+} __attribute__((packed));
+
+struct hbm_host_stop_request {
+ struct hbm_cmd cmd;
+ __u8 reason;
+ __u8 reserved[2];
+} __attribute__((packed));
+
+struct hbm_host_stop_response {
+ struct hbm_cmd cmd;
+ __u8 reserved[3];
+} __attribute__((packed));
+
+struct hbm_me_stop_request {
+ struct hbm_cmd cmd;
+ __u8 reason;
+ __u8 reserved[2];
+} __attribute__((packed));
+
+struct hbm_host_enum_request {
+ struct hbm_cmd cmd;
+ __u8 reserved[3];
+} __attribute__((packed));
+
+struct hbm_host_enum_response {
+ struct hbm_cmd cmd;
+ __u8 reserved[3];
+ __u8 valid_addresses[32];
+} __attribute__((packed));
+
+struct heci_client_properties {
+ struct guid protocol_name;
+ __u8 protocol_version;
+ __u8 max_number_of_connections;
+ __u8 fixed_address;
+ __u8 single_recv_buf;
+ __u32 max_msg_length;
+} __attribute__((packed));
+
+struct hbm_props_request {
+ struct hbm_cmd cmd;
+ __u8 address;
+ __u8 reserved[2];
+} __attribute__((packed));
+
+
+struct hbm_props_response {
+ struct hbm_cmd cmd;
+ __u8 address;
+ __u8 status;
+ __u8 reserved[1];
+ struct heci_client_properties client_properties;
+} __attribute__((packed));
+
+struct hbm_client_connect_request {
+ struct hbm_cmd cmd;
+ __u8 me_addr;
+ __u8 host_addr;
+ __u8 reserved;
+} __attribute__((packed));
+
+struct hbm_client_connect_response {
+ struct hbm_cmd cmd;
+ __u8 me_addr;
+ __u8 host_addr;
+ __u8 status;
+} __attribute__((packed));
+
+struct hbm_client_disconnect_request {
+ struct hbm_cmd cmd;
+ __u8 me_addr;
+ __u8 host_addr;
+ __u8 reserved[1];
+} __attribute__((packed));
+
+struct hbm_flow_control {
+ struct hbm_cmd cmd;
+ __u8 me_addr;
+ __u8 host_addr;
+ __u8 reserved[HECI_FC_MESSAGE_RESERVED_LENGTH];
+} __attribute__((packed));
+
+struct heci_me_client {
+ struct heci_client_properties props;
+ __u8 client_id;
+ __u8 flow_ctrl_creds;
+} __attribute__((packed));
+
+/* private device struct */
+struct iamt_heci_device {
+ struct pci_dev *pdev; /* pointer to pci device struct */
+ /*
+ * lists of queues
+ */
+ /* array of pointers to aio lists */
+ struct io_heci_list *io_list_array[HECI_IO_LISTS_NUMBER];
+ struct io_heci_list read_list; /* driver read queue */
+ struct io_heci_list write_list; /* driver write queue */
+ struct io_heci_list write_waiting_list; /* write waiting queue */
+ struct io_heci_list ctrl_wr_list; /* managed write IOCTL list */
+ struct io_heci_list ctrl_rd_list; /* managed read IOCTL list */
+ struct io_heci_list pthi_cmd_list; /* PTHI list for cmd waiting */
+
+ /* driver managed PTHI list for reading completed pthi cmd data */
+ struct io_heci_list pthi_read_complete_list;
+ /*
+ * list of files
+ */
+ struct list_head file_list;
+ /*
+ * memory of device
+ */
+ unsigned int mem_base;
+ unsigned int mem_length;
+ void __iomem *mem_addr;
+ /*
+ * lock for the device
+ */
+ spinlock_t device_lock; /* device lock*/
+ struct work_struct work;
+ int recvd_msg;
+
+ struct task_struct *reinit_tsk;
+
+ struct timer_list wd_timer;
+ /*
+ * hw states of host and fw(ME)
+ */
+ __u32 host_hw_state;
+ __u32 me_hw_state;
+ /*
+ * waiting queue for receive message from FW
+ */
+ wait_queue_head_t wait_recvd_msg;
+ wait_queue_head_t wait_stop_wd;
+ /*
+ * heci device states
+ */
+ enum heci_states heci_state;
+ int stop;
+
+ __u32 extra_write_index;
+ __u32 rd_msg_buf[128]; /* used for control messages */
+ __u32 wr_msg_buf[128]; /* used for control messages */
+ __u32 ext_msg_buf[8]; /* for control responses */
+ __u32 rd_msg_hdr;
+
+ struct hbm_version version;
+
+ int host_buffer_is_empty;
+ struct heci_file_private wd_file_ext;
+ struct heci_me_client *me_clients; /* Note: memory has to be allocated*/
+ __u8 heci_me_clients[32]; /* list of existing clients */
+ __u8 num_heci_me_clients;
+ __u8 heci_host_clients[32]; /* list of existing clients */
+ __u8 current_host_client_id;
+
+ int wd_pending;
+ int wd_stoped;
+ __u16 wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */
+ unsigned char wd_data[HECI_START_WD_DATA_SIZE];
+
+
+ __u16 wd_due_counter;
+ int asf_mode;
+ int wd_bypass; /* if 1, don't refresh watchdog ME client */
+
+ struct file *iamthif_file_object;
+ struct heci_file_private iamthif_file_ext;
+ int iamthif_ioctl;
+ int iamthif_canceled;
+ __u32 iamthif_timer;
+ __u32 iamthif_stall_timer;
+ unsigned char iamthif_msg_buf[IAMTHIF_MTU];
+ __u32 iamthif_msg_buf_size;
+ __u32 iamthif_msg_buf_index;
+ int iamthif_flow_control_pending;
+ enum iamthif_states iamthif_state;
+
+ struct heci_cb_private *iamthif_current_cb;
+ __u8 write_hang;
+ int need_reset;
+ long open_handle_count;
+
+};
+
+/**
+ * read_heci_register - Read a byte from the heci device
+ *
+ * @dev: the device structure
+ * @offset: offset from which to read the data
+ *
+ * returns the byte read.
+ */
+static inline __u32 read_heci_register(struct iamt_heci_device *dev,
+ unsigned long offset)
+{
+ return readl(dev->mem_addr + offset);
+}
+
+/**
+ * write_heci_register - Write 4 bytes to the heci device
+ *
+ * @dev: the device structure
+ * @offset: offset from which to write the data
+ * @value: the byte to write
+ */
+static inline void write_heci_register(struct iamt_heci_device *dev,
+ unsigned long offset, __u32 value)
+{
+ writel(value, dev->mem_addr + offset);
+}
+
+#endif /* _HECI_DATA_STRUCTURES_H_ */
diff --git a/drivers/staging/heci/heci_init.c b/drivers/staging/heci/heci_init.c
new file mode 100644
index 00000000000..a8a0da910cf
--- /dev/null
+++ b/drivers/staging/heci/heci_init.c
@@ -0,0 +1,1077 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/reboot.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/moduleparam.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
+
+#include "heci_data_structures.h"
+#include "heci_interface.h"
+#include "heci.h"
+
+
+const __u8 heci_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 };
+const __u8 heci_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 };
+
+const __u8 heci_wd_state_independence_msg[3][4] = {
+ {0x05, 0x02, 0x51, 0x10},
+ {0x05, 0x02, 0x52, 0x10},
+ {0x07, 0x02, 0x01, 0x10}
+};
+
+static const struct guid heci_asf_guid = {
+ 0x75B30CD6, 0xA29E, 0x4AF7,
+ {0xA7, 0x12, 0xE6, 0x17, 0x43, 0x93, 0xC8, 0xA6}
+};
+const struct guid heci_wd_guid = {
+ 0x05B79A6F, 0x4628, 0x4D7F,
+ {0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB}
+};
+const struct guid heci_pthi_guid = {
+ 0x12f80028, 0xb4b7, 0x4b2d,
+ {0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c}
+};
+
+
+/*
+ * heci init function prototypes
+ */
+static void heci_check_asf_mode(struct iamt_heci_device *dev);
+static int host_start_message(struct iamt_heci_device *dev);
+static int host_enum_clients_message(struct iamt_heci_device *dev);
+static int allocate_me_clients_storage(struct iamt_heci_device *dev);
+static void host_init_wd(struct iamt_heci_device *dev);
+static void host_init_iamthif(struct iamt_heci_device *dev);
+static int heci_wait_event_int_timeout(struct iamt_heci_device *dev,
+ long timeout);
+
+
+/**
+ * heci_initialize_list - Sets up a queue list.
+ *
+ * @list: An instance of our list structure
+ * @dev: Device object for our driver
+ */
+void heci_initialize_list(struct io_heci_list *list,
+ struct iamt_heci_device *dev)
+{
+ /* initialize our queue list */
+ INIT_LIST_HEAD(&list->heci_cb.cb_list);
+ list->status = 0;
+ list->device_extension = dev;
+}
+
+/**
+ * heci_flush_queues - flush our queues list belong to file_ext.
+ *
+ * @dev: Device object for our driver
+ * @file_ext: private data of the file object
+ */
+void heci_flush_queues(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ int i;
+
+ if (!dev || !file_ext)
+ return;
+
+ /* flush our queue list belong to file_ext */
+ for (i = 0; i < HECI_IO_LISTS_NUMBER; i++) {
+ DBG("remove list entry belong to file_ext\n");
+ heci_flush_list(dev->io_list_array[i], file_ext);
+ }
+}
+
+
+/**
+ * heci_flush_list - remove list entry belong to file_ext.
+ *
+ * @list: An instance of our list structure
+ * @file_ext: private data of the file object
+ */
+void heci_flush_list(struct io_heci_list *list,
+ struct heci_file_private *file_ext)
+{
+ struct heci_file_private *file_ext_tmp;
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb_next = NULL;
+
+ if (!list || !file_ext)
+ return;
+
+ if (list->status != 0)
+ return;
+
+ if (list_empty(&list->heci_cb.cb_list))
+ return;
+
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &list->heci_cb.cb_list, cb_list) {
+ if (priv_cb_pos) {
+ file_ext_tmp = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+ if (file_ext_tmp) {
+ if (heci_fe_same_id(file_ext, file_ext_tmp))
+ list_del(&priv_cb_pos->cb_list);
+ }
+ }
+ }
+}
+
+/**
+ * heci_reset_iamthif_params - initializes heci device iamthif
+ *
+ * @dev: The heci device structure
+ */
+static void heci_reset_iamthif_params(struct iamt_heci_device *dev)
+{
+ /* reset iamthif parameters. */
+ dev->iamthif_current_cb = NULL;
+ dev->iamthif_msg_buf_size = 0;
+ dev->iamthif_msg_buf_index = 0;
+ dev->iamthif_canceled = 0;
+ dev->iamthif_file_ext.file = NULL;
+ dev->iamthif_ioctl = 0;
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+ dev->iamthif_timer = 0;
+}
+
+/**
+ * init_heci_device - allocates and initializes the heci device structure
+ *
+ * @pdev: The pci device structure
+ *
+ * returns The heci_device_device pointer on success, NULL on failure.
+ */
+struct iamt_heci_device *init_heci_device(struct pci_dev *pdev)
+{
+ int i;
+ struct iamt_heci_device *dev;
+
+ dev = kzalloc(sizeof(struct iamt_heci_device), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ /* setup our list array */
+ dev->io_list_array[0] = &dev->read_list;
+ dev->io_list_array[1] = &dev->write_list;
+ dev->io_list_array[2] = &dev->write_waiting_list;
+ dev->io_list_array[3] = &dev->ctrl_wr_list;
+ dev->io_list_array[4] = &dev->ctrl_rd_list;
+ dev->io_list_array[5] = &dev->pthi_cmd_list;
+ dev->io_list_array[6] = &dev->pthi_read_complete_list;
+ INIT_LIST_HEAD(&dev->file_list);
+ INIT_LIST_HEAD(&dev->wd_file_ext.link);
+ INIT_LIST_HEAD(&dev->iamthif_file_ext.link);
+ spin_lock_init(&dev->device_lock);
+ init_waitqueue_head(&dev->wait_recvd_msg);
+ init_waitqueue_head(&dev->wait_stop_wd);
+ dev->heci_state = HECI_INITIALIZING;
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+
+ /* init work for schedule work */
+ INIT_WORK(&dev->work, NULL);
+ for (i = 0; i < HECI_IO_LISTS_NUMBER; i++)
+ heci_initialize_list(dev->io_list_array[i], dev);
+ dev->pdev = pdev;
+ return dev;
+}
+
+
+
+
+static int heci_wait_event_int_timeout(struct iamt_heci_device *dev,
+ long timeout)
+{
+ return wait_event_interruptible_timeout(dev->wait_recvd_msg,
+ (dev->recvd_msg), timeout);
+}
+
+/**
+ * heci_hw_init - init host and fw to start work.
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_hw_init(struct iamt_heci_device *dev)
+{
+ int err = 0;
+
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+ DBG("host_hw_state = 0x%08x, mestate = 0x%08x.\n",
+ dev->host_hw_state, dev->me_hw_state);
+
+ if ((dev->host_hw_state & H_IS) == H_IS) {
+ /* acknowledge interrupt and stop interupts */
+ heci_set_csr_register(dev);
+ }
+ dev->recvd_msg = 0;
+ DBG("reset in start the heci device.\n");
+
+ heci_reset(dev, 1);
+
+ DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+ dev->host_hw_state, dev->me_hw_state);
+
+ /* wait for ME to turn on ME_RDY */
+ if (!dev->recvd_msg)
+ err = heci_wait_event_int_timeout(dev, HECI_INTEROP_TIMEOUT);
+
+ if (!err && !dev->recvd_msg) {
+ dev->heci_state = HECI_DISABLED;
+ DBG("wait_event_interruptible_timeout failed"
+ "on wait for ME to turn on ME_RDY.\n");
+ return -ENODEV;
+ } else {
+ if (!(((dev->host_hw_state & H_RDY) == H_RDY)
+ && ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) {
+ dev->heci_state = HECI_DISABLED;
+ DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+ dev->host_hw_state,
+ dev->me_hw_state);
+
+ if (!(dev->host_hw_state & H_RDY) != H_RDY)
+ DBG("host turn off H_RDY.\n");
+
+ if (!(dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA)
+ DBG("ME turn off ME_RDY.\n");
+
+ printk(KERN_ERR
+ "heci: link layer initialization failed.\n");
+ return -ENODEV;
+ }
+ }
+ dev->recvd_msg = 0;
+ DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+ dev->host_hw_state, dev->me_hw_state);
+ DBG("ME turn on ME_RDY and host turn on H_RDY.\n");
+ printk(KERN_INFO "heci: link layer has been established.\n");
+ return 0;
+}
+
+/**
+ * heci_hw_reset - reset fw via heci csr register.
+ *
+ * @dev: Device object for our driver
+ * @interrupts: if interrupt should be enable after reset.
+ */
+static void heci_hw_reset(struct iamt_heci_device *dev, int interrupts)
+{
+ dev->host_hw_state |= (H_RST | H_IG);
+
+ if (interrupts)
+ heci_csr_enable_interrupts(dev);
+ else
+ heci_csr_disable_interrupts(dev);
+
+ BUG_ON((dev->host_hw_state & H_RST) != H_RST);
+ BUG_ON((dev->host_hw_state & H_RDY) != 0);
+}
+
+/**
+ * heci_reset - reset host and fw.
+ *
+ * @dev: Device object for our driver
+ * @interrupts: if interrupt should be enable after reset.
+ */
+void heci_reset(struct iamt_heci_device *dev, int interrupts)
+{
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb_next = NULL;
+ int unexpected = 0;
+
+ if (dev->heci_state == HECI_RECOVERING_FROM_RESET) {
+ dev->need_reset = 1;
+ return;
+ }
+
+ if (dev->heci_state != HECI_INITIALIZING &&
+ dev->heci_state != HECI_DISABLED &&
+ dev->heci_state != HECI_POWER_DOWN &&
+ dev->heci_state != HECI_POWER_UP)
+ unexpected = 1;
+
+ if (dev->reinit_tsk != NULL) {
+ kthread_stop(dev->reinit_tsk);
+ dev->reinit_tsk = NULL;
+ }
+
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+
+ DBG("before reset host_hw_state = 0x%08x.\n",
+ dev->host_hw_state);
+
+ heci_hw_reset(dev, interrupts);
+
+ dev->host_hw_state &= ~H_RST;
+ dev->host_hw_state |= H_IG;
+
+ write_heci_register(dev, H_CSR, dev->host_hw_state);
+
+ DBG("currently saved host_hw_state = 0x%08x.\n",
+ dev->host_hw_state);
+
+ dev->need_reset = 0;
+
+ if (dev->heci_state != HECI_INITIALIZING) {
+ if ((dev->heci_state != HECI_DISABLED) &&
+ (dev->heci_state != HECI_POWER_DOWN))
+ dev->heci_state = HECI_RESETING;
+
+ list_for_each_entry_safe(file_pos,
+ file_next, &dev->file_list, link) {
+ file_pos->state = HECI_FILE_DISCONNECTED;
+ file_pos->flow_ctrl_creds = 0;
+ file_pos->read_cb = NULL;
+ file_pos->timer_count = 0;
+ }
+ /* remove entry if already in list */
+ DBG("list del iamthif and wd file list.\n");
+ heci_remove_client_from_file_list(dev,
+ dev->wd_file_ext.host_client_id);
+
+ heci_remove_client_from_file_list(dev,
+ dev->iamthif_file_ext.host_client_id);
+
+ heci_reset_iamthif_params(dev);
+ dev->wd_due_counter = 0;
+ dev->extra_write_index = 0;
+ }
+
+ dev->num_heci_me_clients = 0;
+ dev->rd_msg_hdr = 0;
+ dev->stop = 0;
+ dev->wd_pending = 0;
+
+ /* update the state of the registers after reset */
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+
+ DBG("after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+ dev->host_hw_state, dev->me_hw_state);
+
+ if (unexpected)
+ printk(KERN_WARNING "heci: unexpected reset.\n");
+
+ /* Wake up all readings so they can be interrupted */
+ list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) {
+ if (&file_pos->rx_wait &&
+ waitqueue_active(&file_pos->rx_wait)) {
+ printk(KERN_INFO "heci: Waking up client!\n");
+ wake_up_interruptible(&file_pos->rx_wait);
+ }
+ }
+ /* remove all waiting requests */
+ if (dev->write_list.status == 0 &&
+ !list_empty(&dev->write_list.heci_cb.cb_list)) {
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->write_list.heci_cb.cb_list, cb_list) {
+ if (priv_cb_pos) {
+ list_del(&priv_cb_pos->cb_list);
+ heci_free_cb_private(priv_cb_pos);
+ }
+ }
+ }
+}
+
+/**
+ * heci_initialize_clients - heci communication initialization.
+ *
+ * @dev: Device object for our driver
+ */
+int heci_initialize_clients(struct iamt_heci_device *dev)
+{
+ int status;
+
+ msleep(100); /* FW needs time to be ready to talk with us */
+ DBG("link is established start sending messages.\n");
+ /* link is established start sending messages. */
+ status = host_start_message(dev);
+ if (status != 0) {
+ spin_lock_bh(&dev->device_lock);
+ dev->heci_state = HECI_DISABLED;
+ spin_unlock_bh(&dev->device_lock);
+ DBG("start sending messages failed.\n");
+ return status;
+ }
+
+ /* enumerate clients */
+ status = host_enum_clients_message(dev);
+ if (status != 0) {
+ spin_lock_bh(&dev->device_lock);
+ dev->heci_state = HECI_DISABLED;
+ spin_unlock_bh(&dev->device_lock);
+ DBG("enum clients failed.\n");
+ return status;
+ }
+ /* allocate storage for ME clients representation */
+ status = allocate_me_clients_storage(dev);
+ if (status != 0) {
+ spin_lock_bh(&dev->device_lock);
+ dev->num_heci_me_clients = 0;
+ dev->heci_state = HECI_DISABLED;
+ spin_unlock_bh(&dev->device_lock);
+ DBG("allocate clients failed.\n");
+ return status;
+ }
+
+ heci_check_asf_mode(dev);
+ /*heci initialization wd */
+ host_init_wd(dev);
+ /*heci initialization iamthif client */
+ host_init_iamthif(dev);
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->need_reset) {
+ dev->need_reset = 0;
+ dev->heci_state = HECI_DISABLED;
+ spin_unlock_bh(&dev->device_lock);
+ return -ENODEV;
+ }
+
+ memset(dev->heci_host_clients, 0, sizeof(dev->heci_host_clients));
+ dev->open_handle_count = 0;
+ dev->heci_host_clients[0] |= 7;
+ dev->current_host_client_id = 3;
+ dev->heci_state = HECI_ENABLED;
+ spin_unlock_bh(&dev->device_lock);
+ DBG("initialization heci clients successful.\n");
+ return 0;
+}
+
+/**
+ * heci_task_initialize_clients - heci reinitialization task
+ *
+ * @data: Device object for our driver
+ */
+int heci_task_initialize_clients(void *data)
+{
+ int ret;
+ struct iamt_heci_device *dev = (struct iamt_heci_device *) data;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->reinit_tsk != NULL) {
+ spin_unlock_bh(&dev->device_lock);
+ DBG("reinit task already started.\n");
+ return 0;
+ }
+ dev->reinit_tsk = current;
+ current->flags |= PF_NOFREEZE;
+ spin_unlock_bh(&dev->device_lock);
+
+ ret = heci_initialize_clients(dev);
+
+ spin_lock_bh(&dev->device_lock);
+ dev->reinit_tsk = NULL;
+ spin_unlock_bh(&dev->device_lock);
+
+ return ret;
+}
+
+/**
+ * host_start_message - heci host send start message.
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int host_start_message(struct iamt_heci_device *dev)
+{
+ long timeout = 60; /* 60 second */
+
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_host_version_request *host_start_req;
+ struct hbm_host_stop_request *host_stop_req;
+ int err = 0;
+
+ /* host start message */
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_host_version_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ host_start_req =
+ (struct hbm_host_version_request *) &dev->wr_msg_buf[1];
+ memset(host_start_req, 0, sizeof(struct hbm_host_version_request));
+ host_start_req->cmd.cmd = HOST_START_REQ_CMD;
+ host_start_req->host_version.major_version = HBM_MAJOR_VERSION;
+ host_start_req->host_version.minor_version = HBM_MINOR_VERSION;
+ dev->recvd_msg = 0;
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *) (host_start_req),
+ heci_hdr->length)) {
+ DBG("send version to fw fail.\n");
+ return -ENODEV;
+ }
+ DBG("call wait_event_interruptible_timeout for response message.\n");
+ /* wait for response */
+ err = heci_wait_event_int_timeout(dev, timeout * HZ);
+ if (!err && !dev->recvd_msg) {
+ DBG("wait_timeout failed on host start response message.\n");
+ return -ENODEV;
+ }
+ dev->recvd_msg = 0;
+ DBG("wait_timeout successful on host start response message.\n");
+ if ((dev->version.major_version != HBM_MAJOR_VERSION) ||
+ (dev->version.minor_version != HBM_MINOR_VERSION)) {
+ /* send stop message */
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_host_stop_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ host_stop_req =
+ (struct hbm_host_stop_request *) &dev->wr_msg_buf[1];
+
+ memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request));
+ host_stop_req->cmd.cmd = HOST_STOP_REQ_CMD;
+ host_stop_req->reason = DRIVER_STOP_REQUEST;
+ heci_write_message(dev, heci_hdr,
+ (unsigned char *) (host_stop_req),
+ heci_hdr->length);
+ DBG("version mismatch.\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/**
+ * host_enum_clients_message - host send enumeration client request message.
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int host_enum_clients_message(struct iamt_heci_device *dev)
+{
+ long timeout = 5; /*5 second */
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_host_enum_request *host_enum_req;
+ int err = 0;
+ int i, j;
+
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ /* enumerate clients */
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_host_enum_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1];
+ memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request));
+ host_enum_req->cmd.cmd = HOST_ENUM_REQ_CMD;
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *) (host_enum_req),
+ heci_hdr->length)) {
+ DBG("send enumeration request failed.\n");
+ return -ENODEV;
+ }
+ /* wait for response */
+ dev->recvd_msg = 0;
+ err = heci_wait_event_int_timeout(dev, timeout * HZ);
+ if (!err && !dev->recvd_msg) {
+ DBG("wait_event_interruptible_timeout failed "
+ "on enumeration clients response message.\n");
+ return -ENODEV;
+ }
+ dev->recvd_msg = 0;
+
+ spin_lock_bh(&dev->device_lock);
+ /* count how many ME clients we have */
+ for (i = 0; i < sizeof(dev->heci_me_clients); i++) {
+ for (j = 0; j < 8; j++) {
+ if ((dev->heci_me_clients[i] & (1 << j)) != 0)
+ dev->num_heci_me_clients++;
+
+ }
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ return 0;
+}
+
+/**
+ * host_client_properties - reads properties for client
+ *
+ * @dev: Device object for our driver
+ * @idx: client index in me client array
+ * @client_id: id of the client
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int host_client_properties(struct iamt_heci_device *dev,
+ struct heci_me_client *client)
+{
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_props_request *host_cli_req;
+ int err;
+
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_props_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ host_cli_req = (struct hbm_props_request *) &dev->wr_msg_buf[1];
+ memset(host_cli_req, 0, sizeof(struct hbm_props_request));
+ host_cli_req->cmd.cmd = HOST_CLIENT_PROPERTEIS_REQ_CMD;
+ host_cli_req->address = client->client_id;
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *) (host_cli_req),
+ heci_hdr->length)) {
+ DBG("send props request failed.\n");
+ return -ENODEV;
+ }
+ /* wait for response */
+ dev->recvd_msg = 0;
+ err = heci_wait_event_int_timeout(dev, 10 * HZ);
+ if (!err && !dev->recvd_msg) {
+ DBG("wait failed on props resp msg.\n");
+ return -ENODEV;
+ }
+ dev->recvd_msg = 0;
+ return 0;
+}
+
+/**
+ * allocate_me_clients_storage - allocate storage for me clients
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int allocate_me_clients_storage(struct iamt_heci_device *dev)
+{
+ struct heci_me_client *clients;
+ struct heci_me_client *client;
+ __u8 num, i, j;
+ int err;
+
+ if (dev->num_heci_me_clients <= 0)
+ return 0;
+
+ spin_lock_bh(&dev->device_lock);
+ kfree(dev->me_clients);
+ dev->me_clients = NULL;
+ spin_unlock_bh(&dev->device_lock);
+
+ /* allocate storage for ME clients representation */
+ clients = kcalloc(dev->num_heci_me_clients,
+ sizeof(struct heci_me_client), GFP_KERNEL);
+ if (!clients) {
+ DBG("memory allocation for ME clients failed.\n");
+ return -ENOMEM;
+ }
+
+ spin_lock_bh(&dev->device_lock);
+ dev->me_clients = clients;
+ spin_unlock_bh(&dev->device_lock);
+
+ num = 0;
+ for (i = 0; i < sizeof(dev->heci_me_clients); i++) {
+ for (j = 0; j < 8; j++) {
+ if ((dev->heci_me_clients[i] & (1 << j)) != 0) {
+ client = &dev->me_clients[num];
+ client->client_id = (i * 8) + j;
+ client->flow_ctrl_creds = 0;
+ err = host_client_properties(dev, client);
+ if (err != 0) {
+ spin_lock_bh(&dev->device_lock);
+ kfree(dev->me_clients);
+ dev->me_clients = NULL;
+ spin_unlock_bh(&dev->device_lock);
+ return err;
+ }
+ num++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * heci_init_file_private - initializes private file structure.
+ *
+ * @priv: private file structure to be initialized
+ * @file: the file structure
+ */
+static void heci_init_file_private(struct heci_file_private *priv,
+ struct file *file)
+{
+ memset(priv, 0, sizeof(struct heci_file_private));
+ spin_lock_init(&priv->file_lock);
+ spin_lock_init(&priv->read_io_lock);
+ spin_lock_init(&priv->write_io_lock);
+ init_waitqueue_head(&priv->wait);
+ init_waitqueue_head(&priv->rx_wait);
+ DBG("priv->rx_wait =%p\n", &priv->rx_wait);
+ init_waitqueue_head(&priv->tx_wait);
+ INIT_LIST_HEAD(&priv->link);
+ priv->reading_state = HECI_IDLE;
+ priv->writing_state = HECI_IDLE;
+}
+
+/**
+ * heci_find_me_client - search for ME client guid
+ * sets client_id in heci_file_private if found
+ * @dev: Device object for our driver
+ * @priv: private file structure to set client_id in
+ * @cguid: searched guid of ME client
+ * @client_id: id of host client to be set in file private structure
+ *
+ * returns ME client index
+ */
+static __u8 heci_find_me_client(struct iamt_heci_device *dev,
+ struct heci_file_private *priv,
+ const struct guid *cguid, __u8 client_id)
+{
+ __u8 i;
+
+ if ((dev == NULL) || (priv == NULL) || (cguid == NULL))
+ return 0;
+
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (memcmp(cguid,
+ &dev->me_clients[i].props.protocol_name,
+ sizeof(struct guid)) == 0) {
+ priv->me_client_id = dev->me_clients[i].client_id;
+ priv->state = HECI_FILE_CONNECTING;
+ priv->host_client_id = client_id;
+
+ list_add_tail(&priv->link, &dev->file_list);
+ return i;
+ }
+ }
+ return 0;
+}
+
+/**
+ * heci_check_asf_mode - check for ASF client
+ *
+ * @dev: Device object for our driver
+ */
+static void heci_check_asf_mode(struct iamt_heci_device *dev)
+{
+ __u8 i;
+
+ spin_lock_bh(&dev->device_lock);
+ dev->asf_mode = 0;
+ /* find ME ASF client - otherwise assume AMT mode */
+ DBG("find ME ASF client - otherwise assume AMT mode.\n");
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (memcmp(&heci_asf_guid,
+ &dev->me_clients[i].props.protocol_name,
+ sizeof(struct guid)) == 0) {
+ dev->asf_mode = 1;
+ spin_unlock_bh(&dev->device_lock);
+ DBG("found ME ASF client.\n");
+ return;
+ }
+ }
+ spin_unlock_bh(&dev->device_lock);
+ DBG("assume AMT mode.\n");
+}
+
+/**
+ * heci_connect_me_client - connect ME client
+ * @dev: Device object for our driver
+ * @priv: private file structure
+ * @timeout: connect timeout in seconds
+ *
+ * returns 1 - if connected, 0 - if not
+ */
+static __u8 heci_connect_me_client(struct iamt_heci_device *dev,
+ struct heci_file_private *priv,
+ long timeout)
+{
+ int err = 0;
+
+ if ((dev == NULL) || (priv == NULL))
+ return 0;
+
+ if (!heci_connect(dev, priv)) {
+ DBG("failed to call heci_connect for client_id=%d.\n",
+ priv->host_client_id);
+ spin_lock_bh(&dev->device_lock);
+ heci_remove_client_from_file_list(dev, priv->host_client_id);
+ priv->state = HECI_FILE_DISCONNECTED;
+ spin_unlock_bh(&dev->device_lock);
+ return 0;
+ }
+
+ err = wait_event_timeout(dev->wait_recvd_msg,
+ (HECI_FILE_CONNECTED == priv->state ||
+ HECI_FILE_DISCONNECTED == priv->state),
+ timeout * HZ);
+ if (HECI_FILE_CONNECTED != priv->state) {
+ spin_lock_bh(&dev->device_lock);
+ heci_remove_client_from_file_list(dev, priv->host_client_id);
+ DBG("failed to connect client_id=%d state=%d.\n",
+ priv->host_client_id, priv->state);
+ if (err)
+ DBG("failed connect err=%08x\n", err);
+ priv->state = HECI_FILE_DISCONNECTED;
+ spin_unlock_bh(&dev->device_lock);
+ return 0;
+ }
+ DBG("successfully connected client_id=%d.\n",
+ priv->host_client_id);
+ return 1;
+}
+
+/**
+ * host_init_wd - heci initialization wd.
+ *
+ * @dev: Device object for our driver
+ */
+static void host_init_wd(struct iamt_heci_device *dev)
+{
+ spin_lock_bh(&dev->device_lock);
+
+ heci_init_file_private(&dev->wd_file_ext, NULL);
+
+ /* look for WD client and connect to it */
+ dev->wd_file_ext.state = HECI_FILE_DISCONNECTED;
+ dev->wd_timeout = 0;
+
+ if (dev->asf_mode) {
+ memcpy(dev->wd_data, heci_stop_wd_params, HECI_WD_PARAMS_SIZE);
+ } else {
+ /* AMT mode */
+ dev->wd_timeout = AMT_WD_VALUE;
+ DBG("dev->wd_timeout=%d.\n", dev->wd_timeout);
+ memcpy(dev->wd_data, heci_start_wd_params, HECI_WD_PARAMS_SIZE);
+ memcpy(dev->wd_data + HECI_WD_PARAMS_SIZE,
+ &dev->wd_timeout, sizeof(__u16));
+ }
+
+ /* find ME WD client */
+ heci_find_me_client(dev, &dev->wd_file_ext,
+ &heci_wd_guid, HECI_WD_HOST_CLIENT_ID);
+ spin_unlock_bh(&dev->device_lock);
+
+ DBG("check wd_file_ext\n");
+ if (HECI_FILE_CONNECTING == dev->wd_file_ext.state) {
+ if (heci_connect_me_client(dev, &dev->wd_file_ext, 15) == 1) {
+ DBG("dev->wd_timeout=%d.\n", dev->wd_timeout);
+ if (dev->wd_timeout != 0)
+ dev->wd_due_counter = 1;
+ else
+ dev->wd_due_counter = 0;
+ DBG("successfully connected to WD client.\n");
+ }
+ } else
+ DBG("failed to find WD client.\n");
+
+
+ spin_lock_bh(&dev->device_lock);
+ dev->wd_timer.function = &heci_wd_timer;
+ dev->wd_timer.data = (unsigned long) dev;
+ spin_unlock_bh(&dev->device_lock);
+}
+
+
+/**
+ * host_init_iamthif - heci initialization iamthif client.
+ *
+ * @dev: Device object for our driver
+ *
+ */
+static void host_init_iamthif(struct iamt_heci_device *dev)
+{
+ __u8 i;
+
+ spin_lock_bh(&dev->device_lock);
+
+ heci_init_file_private(&dev->iamthif_file_ext, NULL);
+ dev->iamthif_file_ext.state = HECI_FILE_DISCONNECTED;
+
+ /* find ME PTHI client */
+ i = heci_find_me_client(dev, &dev->iamthif_file_ext,
+ &heci_pthi_guid, HECI_IAMTHIF_HOST_CLIENT_ID);
+ if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTING) {
+ DBG("failed to find iamthif client.\n");
+ spin_unlock_bh(&dev->device_lock);
+ return;
+ }
+
+ BUG_ON(dev->me_clients[i].props.max_msg_length != IAMTHIF_MTU);
+
+ spin_unlock_bh(&dev->device_lock);
+ if (heci_connect_me_client(dev, &dev->iamthif_file_ext, 15) == 1) {
+ DBG("connected to iamthif client.\n");
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+ }
+}
+
+/**
+ * heci_alloc_file_private - allocates a private file structure and set it up.
+ * @file: the file structure
+ *
+ * returns The allocated file or NULL on failure
+ */
+struct heci_file_private *heci_alloc_file_private(struct file *file)
+{
+ struct heci_file_private *priv;
+
+ priv = kmalloc(sizeof(struct heci_file_private), GFP_KERNEL);
+ if (!priv)
+ return NULL;
+
+ heci_init_file_private(priv, file);
+
+ return priv;
+}
+
+
+
+/**
+ * heci_disconnect_host_client - send disconnect message to fw from host client.
+ *
+ * @dev: Device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_disconnect_host_client(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ int rets, err;
+ long timeout = 15; /* 15 seconds */
+ struct heci_cb_private *priv_cb;
+
+ if ((!dev) || (!file_ext))
+ return -ENODEV;
+
+ if (file_ext->state != HECI_FILE_DISCONNECTING)
+ return 0;
+
+ priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
+ if (!priv_cb)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&priv_cb->cb_list);
+ priv_cb->file_private = file_ext;
+ priv_cb->major_file_operations = HECI_CLOSE;
+ spin_lock_bh(&dev->device_lock);
+ if (dev->host_buffer_is_empty) {
+ dev->host_buffer_is_empty = 0;
+ if (heci_disconnect(dev, file_ext)) {
+ list_add_tail(&priv_cb->cb_list,
+ &dev->ctrl_rd_list.heci_cb.cb_list);
+ } else {
+ spin_unlock_bh(&dev->device_lock);
+ rets = -ENODEV;
+ DBG("failed to call heci_disconnect.\n");
+ goto free;
+ }
+ } else {
+ DBG("add disconnect cb to control write list\n");
+ list_add_tail(&priv_cb->cb_list,
+ &dev->ctrl_wr_list.heci_cb.cb_list);
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ err = wait_event_timeout(dev->wait_recvd_msg,
+ (HECI_FILE_DISCONNECTED == file_ext->state),
+ timeout * HZ);
+ if (HECI_FILE_DISCONNECTED == file_ext->state) {
+ rets = 0;
+ DBG("successfully disconnected from fw client.\n");
+ } else {
+ rets = -ENODEV;
+ if (HECI_FILE_DISCONNECTED != file_ext->state)
+ DBG("wrong status client disconnect.\n");
+
+ if (err)
+ DBG("wait failed disconnect err=%08x\n", err);
+
+ DBG("failed to disconnect from fw client.\n");
+ }
+
+ spin_lock_bh(&dev->device_lock);
+ heci_flush_list(&dev->ctrl_rd_list, file_ext);
+ heci_flush_list(&dev->ctrl_wr_list, file_ext);
+ spin_unlock_bh(&dev->device_lock);
+free:
+ heci_free_cb_private(priv_cb);
+ return rets;
+}
+
+/**
+ * heci_remove_client_from_file_list -
+ * remove file private data from device file list
+ *
+ * @dev: Device object for our driver
+ * @host_client_id: host client id to be removed
+ */
+void heci_remove_client_from_file_list(struct iamt_heci_device *dev,
+ __u8 host_client_id)
+{
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+ list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) {
+ if (host_client_id == file_pos->host_client_id) {
+ DBG("remove host client = %d, ME client = %d\n",
+ file_pos->host_client_id,
+ file_pos->me_client_id);
+ list_del_init(&file_pos->link);
+ break;
+ }
+ }
+}
diff --git a/drivers/staging/heci/heci_interface.c b/drivers/staging/heci/heci_interface.c
new file mode 100644
index 00000000000..c5f51a7ddf2
--- /dev/null
+++ b/drivers/staging/heci/heci_interface.c
@@ -0,0 +1,485 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+
+#include "heci.h"
+#include "heci_interface.h"
+
+
+/**
+ * heci_set_csr_register - write H_CSR register to the heci device
+ *
+ * @dev: device object for our driver
+ */
+void heci_set_csr_register(struct iamt_heci_device *dev)
+{
+ write_heci_register(dev, H_CSR, dev->host_hw_state);
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+}
+
+/**
+ * heci_csr_enable_interrupts - enable heci device interrupts
+ *
+ * @dev: device object for our driver
+ */
+void heci_csr_enable_interrupts(struct iamt_heci_device *dev)
+{
+ dev->host_hw_state |= H_IE;
+ heci_set_csr_register(dev);
+}
+
+/**
+ * heci_csr_disable_interrupts - disable heci device interrupts
+ *
+ * @dev: device object for our driver
+ */
+void heci_csr_disable_interrupts(struct iamt_heci_device *dev)
+{
+ dev->host_hw_state &= ~H_IE;
+ heci_set_csr_register(dev);
+}
+
+
+/**
+ * _host_get_filled_slots - get number of device filled buffer slots
+ *
+ * @device: the device structure
+ *
+ * returns numer of filled slots
+ */
+static unsigned char _host_get_filled_slots(const struct iamt_heci_device *dev)
+{
+ char read_ptr, write_ptr;
+
+ read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8);
+ write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16);
+
+ return (unsigned char) (write_ptr - read_ptr);
+}
+
+/**
+ * host_buffer_is_empty - check if host buffer is empty.
+ *
+ * @dev: device object for our driver
+ *
+ * returns 1 if empty, 0 - otherwise.
+ */
+int host_buffer_is_empty(struct iamt_heci_device *dev)
+{
+ unsigned char filled_slots;
+
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ filled_slots = _host_get_filled_slots(dev);
+
+ if (filled_slots > 0)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * count_empty_write_slots - count write empty slots.
+ *
+ * @dev: device object for our driver
+ *
+ * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count
+ */
+__s32 count_empty_write_slots(const struct iamt_heci_device *dev)
+{
+ unsigned char buffer_depth, filled_slots, empty_slots;
+
+ buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24);
+ filled_slots = _host_get_filled_slots(dev);
+ empty_slots = buffer_depth - filled_slots;
+
+ if (filled_slots > buffer_depth) {
+ /* overflow */
+ return -ESLOTS_OVERFLOW;
+ }
+
+ return (__s32) empty_slots;
+}
+
+/**
+ * heci_write_message - write a message to heci device.
+ *
+ * @dev: device object for our driver
+ * @heci_hdr: header of message
+ * @write_buffer: message buffer will be write
+ * @write_length: message size will be write
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_write_message(struct iamt_heci_device *dev,
+ struct heci_msg_hdr *header,
+ unsigned char *write_buffer,
+ unsigned long write_length)
+{
+ __u32 temp_msg = 0;
+ unsigned long bytes_written = 0;
+ unsigned char buffer_depth, filled_slots, empty_slots;
+ unsigned long dw_to_write;
+
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ DBG("host_hw_state = 0x%08x.\n", dev->host_hw_state);
+ DBG("heci_write_message header=%08x.\n", *((__u32 *) header));
+ buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24);
+ filled_slots = _host_get_filled_slots(dev);
+ empty_slots = buffer_depth - filled_slots;
+ DBG("filled = %hu, empty = %hu.\n", filled_slots, empty_slots);
+
+ dw_to_write = ((write_length + 3) / 4);
+
+ if (dw_to_write > empty_slots)
+ return 0;
+
+ write_heci_register(dev, H_CB_WW, *((__u32 *) header));
+
+ while (write_length >= 4) {
+ write_heci_register(dev, H_CB_WW,
+ *(__u32 *) (write_buffer + bytes_written));
+ bytes_written += 4;
+ write_length -= 4;
+ }
+
+ if (write_length > 0) {
+ memcpy(&temp_msg, &write_buffer[bytes_written], write_length);
+ write_heci_register(dev, H_CB_WW, temp_msg);
+ }
+
+ dev->host_hw_state |= H_IG;
+ write_heci_register(dev, H_CSR, dev->host_hw_state);
+ dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+ if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA)
+ return 0;
+
+ dev->write_hang = 0;
+ return 1;
+}
+
+/**
+ * count_full_read_slots - count read full slots.
+ *
+ * @dev: device object for our driver
+ *
+ * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count
+ */
+__s32 count_full_read_slots(struct iamt_heci_device *dev)
+{
+ char read_ptr, write_ptr;
+ unsigned char buffer_depth, filled_slots;
+
+ dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+ buffer_depth = (unsigned char)((dev->me_hw_state & ME_CBD_HRA) >> 24);
+ read_ptr = (char) ((dev->me_hw_state & ME_CBRP_HRA) >> 8);
+ write_ptr = (char) ((dev->me_hw_state & ME_CBWP_HRA) >> 16);
+ filled_slots = (unsigned char) (write_ptr - read_ptr);
+
+ if (filled_slots > buffer_depth) {
+ /* overflow */
+ return -ESLOTS_OVERFLOW;
+ }
+
+ DBG("filled_slots =%08x \n", filled_slots);
+ return (__s32) filled_slots;
+}
+
+/**
+ * heci_read_slots - read a message from heci device.
+ *
+ * @dev: device object for our driver
+ * @buffer: message buffer will be write
+ * @buffer_length: message size will be read
+ */
+void heci_read_slots(struct iamt_heci_device *dev,
+ unsigned char *buffer, unsigned long buffer_length)
+{
+ __u32 i = 0;
+ unsigned char temp_buf[sizeof(__u32)];
+
+ while (buffer_length >= sizeof(__u32)) {
+ ((__u32 *) buffer)[i] = read_heci_register(dev, ME_CB_RW);
+ DBG("buffer[%d]= %d\n", i, ((__u32 *) buffer)[i]);
+ i++;
+ buffer_length -= sizeof(__u32);
+ }
+
+ if (buffer_length > 0) {
+ *((__u32 *) &temp_buf) = read_heci_register(dev, ME_CB_RW);
+ memcpy(&buffer[i * 4], temp_buf, buffer_length);
+ }
+
+ dev->host_hw_state |= H_IG;
+ heci_set_csr_register(dev);
+}
+
+/**
+ * flow_ctrl_creds - check flow_control credentials.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if flow_ctrl_creds >0, 0 - otherwise.
+ */
+int flow_ctrl_creds(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ __u8 i;
+
+ if (!dev->num_heci_me_clients)
+ return 0;
+
+ if (file_ext == NULL)
+ return 0;
+
+ if (file_ext->flow_ctrl_creds > 0)
+ return 1;
+
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id == file_ext->me_client_id) {
+ if (dev->me_clients[i].flow_ctrl_creds > 0) {
+ BUG_ON(dev->me_clients[i].props.single_recv_buf
+ == 0);
+ return 1;
+ }
+ return 0;
+ }
+ }
+ BUG();
+ return 0;
+}
+
+/**
+ * flow_ctrl_reduce - reduce flow_control.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ */
+void flow_ctrl_reduce(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ __u8 i;
+
+ if (!dev->num_heci_me_clients)
+ return;
+
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id == file_ext->me_client_id) {
+ if (dev->me_clients[i].props.single_recv_buf != 0) {
+ BUG_ON(dev->me_clients[i].flow_ctrl_creds <= 0);
+ dev->me_clients[i].flow_ctrl_creds--;
+ } else {
+ BUG_ON(file_ext->flow_ctrl_creds <= 0);
+ file_ext->flow_ctrl_creds--;
+ }
+ return;
+ }
+ }
+ BUG();
+}
+
+/**
+ * heci_send_flow_control - send flow control to fw.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_send_flow_control(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_flow_control *heci_flow_control;
+
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_flow_control);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ heci_flow_control = (struct hbm_flow_control *) &dev->wr_msg_buf[1];
+ memset(heci_flow_control, 0, sizeof(heci_flow_control));
+ heci_flow_control->host_addr = file_ext->host_client_id;
+ heci_flow_control->me_addr = file_ext->me_client_id;
+ heci_flow_control->cmd.cmd = HECI_FLOW_CONTROL_CMD;
+ memset(heci_flow_control->reserved, 0,
+ sizeof(heci_flow_control->reserved));
+ DBG("sending flow control host client = %d, me client = %d\n",
+ file_ext->host_client_id, file_ext->me_client_id);
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *) heci_flow_control,
+ sizeof(struct hbm_flow_control)))
+ return 0;
+
+ return 1;
+
+}
+
+/**
+ * other_client_is_connecting - check if other
+ * client with the same client id is connected.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if other client is connected, 0 - otherwise.
+ */
+int other_client_is_connecting(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+
+ list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) {
+ if ((file_pos->state == HECI_FILE_CONNECTING)
+ && (file_pos != file_ext)
+ && file_ext->me_client_id == file_pos->me_client_id)
+ return 1;
+
+ }
+ return 0;
+}
+
+/**
+ * heci_send_wd - send watch dog message to fw.
+ *
+ * @dev: device object for our driver
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_send_wd(struct iamt_heci_device *dev)
+{
+ struct heci_msg_hdr *heci_hdr;
+
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = dev->wd_file_ext.host_client_id;
+ heci_hdr->me_addr = dev->wd_file_ext.me_client_id;
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ if (!memcmp(dev->wd_data, heci_start_wd_params,
+ HECI_WD_PARAMS_SIZE)) {
+ heci_hdr->length = HECI_START_WD_DATA_SIZE;
+ } else {
+ BUG_ON(memcmp(dev->wd_data, heci_stop_wd_params,
+ HECI_WD_PARAMS_SIZE));
+ heci_hdr->length = HECI_WD_PARAMS_SIZE;
+ }
+
+ if (!heci_write_message(dev, heci_hdr, dev->wd_data, heci_hdr->length))
+ return 0;
+
+ return 1;
+}
+
+/**
+ * heci_disconnect - send disconnect message to fw.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_disconnect(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_client_disconnect_request *heci_cli_disconnect;
+
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_client_disconnect_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ heci_cli_disconnect =
+ (struct hbm_client_disconnect_request *) &dev->wr_msg_buf[1];
+ memset(heci_cli_disconnect, 0, sizeof(heci_cli_disconnect));
+ heci_cli_disconnect->host_addr = file_ext->host_client_id;
+ heci_cli_disconnect->me_addr = file_ext->me_client_id;
+ heci_cli_disconnect->cmd.cmd = CLIENT_DISCONNECT_REQ_CMD;
+ heci_cli_disconnect->reserved[0] = 0;
+
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *) heci_cli_disconnect,
+ sizeof(struct hbm_client_disconnect_request)))
+ return 0;
+
+ return 1;
+}
+
+/**
+ * heci_connect - send connect message to fw.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_connect(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_client_connect_request *heci_cli_connect;
+
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_client_connect_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ heci_cli_connect =
+ (struct hbm_client_connect_request *) &dev->wr_msg_buf[1];
+ heci_cli_connect->host_addr = file_ext->host_client_id;
+ heci_cli_connect->me_addr = file_ext->me_client_id;
+ heci_cli_connect->cmd.cmd = CLIENT_CONNECT_REQ_CMD;
+ heci_cli_connect->reserved = 0;
+
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *) heci_cli_connect,
+ sizeof(struct hbm_client_connect_request)))
+ return 0;
+
+ return 1;
+}
diff --git a/drivers/staging/heci/heci_interface.h b/drivers/staging/heci/heci_interface.h
new file mode 100644
index 00000000000..37336ebc0a5
--- /dev/null
+++ b/drivers/staging/heci/heci_interface.h
@@ -0,0 +1,170 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+
+#ifndef _HECI_INTERFACE_H_
+#define _HECI_INTERFACE_H_
+
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+#include <linux/aio.h>
+#include <linux/types.h>
+#include "heci_data_structures.h"
+
+
+#define HBM_MINOR_VERSION 0
+#define HBM_MAJOR_VERSION 1
+#define HBM_TIMEOUT 1 /* 1 second */
+
+
+#define HOST_START_REQ_CMD 0x01
+#define HOST_START_RES_CMD 0x81
+
+#define HOST_STOP_REQ_CMD 0x02
+#define HOST_STOP_RES_CMD 0x82
+
+#define ME_STOP_REQ_CMD 0x03
+
+#define HOST_ENUM_REQ_CMD 0x04
+#define HOST_ENUM_RES_CMD 0x84
+
+#define HOST_CLIENT_PROPERTEIS_REQ_CMD 0x05
+#define HOST_CLIENT_PROPERTEIS_RES_CMD 0x85
+
+#define CLIENT_CONNECT_REQ_CMD 0x06
+#define CLIENT_CONNECT_RES_CMD 0x86
+
+#define CLIENT_DISCONNECT_REQ_CMD 0x07
+#define CLIENT_DISCONNECT_RES_CMD 0x87
+
+#define HECI_FLOW_CONTROL_CMD 0x08
+
+
+#define AMT_WD_VALUE 120 /* seconds */
+
+#define HECI_WATCHDOG_DATA_SIZE 16
+#define HECI_START_WD_DATA_SIZE 20
+#define HECI_WD_PARAMS_SIZE 4
+
+/* IOCTL commands */
+#define IOCTL_HECI_GET_VERSION \
+ _IOWR('H' , 0x0, struct heci_message_data)
+#define IOCTL_HECI_CONNECT_CLIENT \
+ _IOWR('H' , 0x01, struct heci_message_data)
+#define IOCTL_HECI_WD \
+ _IOWR('H' , 0x02, struct heci_message_data)
+#define IOCTL_HECI_BYPASS_WD \
+ _IOWR('H' , 0x10, struct heci_message_data)
+
+enum heci_stop_reason_types{
+ DRIVER_STOP_REQUEST = 0x00,
+ DEVICE_D1_ENTRY = 0x01,
+ DEVICE_D2_ENTRY = 0x02,
+ DEVICE_D3_ENTRY = 0x03,
+ SYSTEM_S1_ENTRY = 0x04,
+ SYSTEM_S2_ENTRY = 0x05,
+ SYSTEM_S3_ENTRY = 0x06,
+ SYSTEM_S4_ENTRY = 0x07,
+ SYSTEM_S5_ENTRY = 0x08
+};
+
+enum me_stop_reason_types{
+ FW_UPDATE = 0x00
+};
+
+enum client_connect_status_types{
+ CCS_SUCCESS = 0x00,
+ CCS_NOT_FOUND = 0x01,
+ CCS_ALREADY_STARTED = 0x02,
+ CCS_OUT_OF_RESOURCES = 0x03,
+ CCS_MESSAGE_SMALL = 0x04
+};
+
+enum client_disconnect_status_types{
+ CDS_SUCCESS = 0x00
+};
+
+
+/*
+ * heci interface function prototypes
+ */
+void heci_set_csr_register(struct iamt_heci_device *dev);
+void heci_csr_enable_interrupts(struct iamt_heci_device *dev);
+void heci_csr_disable_interrupts(struct iamt_heci_device *dev);
+
+void heci_read_slots(struct iamt_heci_device *dev,
+ unsigned char *buffer, unsigned long buffer_length);
+
+int heci_write_message(struct iamt_heci_device *dev,
+ struct heci_msg_hdr *header,
+ unsigned char *write_buffer,
+ unsigned long write_length);
+
+int host_buffer_is_empty(struct iamt_heci_device *dev);
+
+__s32 count_full_read_slots(struct iamt_heci_device *dev);
+
+__s32 count_empty_write_slots(const struct iamt_heci_device *dev);
+
+int flow_ctrl_creds(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+
+int heci_send_wd(struct iamt_heci_device *dev);
+
+void flow_ctrl_reduce(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+
+int heci_send_flow_control(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+
+int heci_disconnect(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+int other_client_is_connecting(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+int heci_connect(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+
+#endif /* _HECI_INTERFACE_H_ */
diff --git a/drivers/staging/heci/heci_main.c b/drivers/staging/heci/heci_main.c
new file mode 100644
index 00000000000..00e44c78142
--- /dev/null
+++ b/drivers/staging/heci/heci_main.c
@@ -0,0 +1,1564 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/aio.h>
+#include <linux/pci.h>
+#include <linux/reboot.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/unistd.h>
+#include <linux/kthread.h>
+
+#include "heci.h"
+#include "heci_interface.h"
+#include "heci_version.h"
+
+
+#define HECI_READ_TIMEOUT 45
+
+#define HECI_DRIVER_NAME "heci"
+
+/*
+ * heci driver strings
+ */
+static char heci_driver_name[] = HECI_DRIVER_NAME;
+static char heci_driver_string[] = "Intel(R) Management Engine Interface";
+static char heci_driver_version[] = HECI_DRIVER_VERSION;
+static char heci_copyright[] = "Copyright (c) 2003 - 2008 Intel Corporation.";
+
+
+#ifdef HECI_DEBUG
+int heci_debug = 1;
+#else
+int heci_debug;
+#endif
+MODULE_PARM_DESC(heci_debug, "Debug enabled or not");
+module_param(heci_debug, int, 0644);
+
+
+#define HECI_DEV_NAME "heci"
+
+/* heci char device for registration */
+static struct cdev heci_cdev;
+
+/* major number for device */
+static int heci_major;
+/* The device pointer */
+static struct pci_dev *heci_device;
+
+static struct class *heci_class;
+
+
+/* heci_pci_tbl - PCI Device ID Table */
+static struct pci_device_id heci_pci_tbl[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82946GZ)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82G35)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82Q965)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82G965)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82GM965)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82GME965)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82Q35)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82G33)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82Q33)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82X38)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_3200)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_6)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_7)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_8)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_9)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_10)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_1)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_2)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_3)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_4)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_1)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_2)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_3)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_4)},
+ /* required last entry */
+ {0, }
+};
+
+MODULE_DEVICE_TABLE(pci, heci_pci_tbl);
+
+/*
+ * Local Function Prototypes
+ */
+static int __init heci_init_module(void);
+static void __exit heci_exit_module(void);
+static int __devinit heci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+static void __devexit heci_remove(struct pci_dev *pdev);
+static int heci_open(struct inode *inode, struct file *file);
+static int heci_release(struct inode *inode, struct file *file);
+static ssize_t heci_read(struct file *file, char __user *ubuf,
+ size_t length, loff_t *offset);
+static int heci_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long data);
+static ssize_t heci_write(struct file *file, const char __user *ubuf,
+ size_t length, loff_t *offset);
+static unsigned int heci_poll(struct file *file, poll_table *wait);
+static struct heci_cb_private *find_read_list_entry(
+ struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+#ifdef CONFIG_PM
+static int heci_suspend(struct pci_dev *pdev, pm_message_t state);
+static int heci_resume(struct pci_dev *pdev);
+static __u16 g_sus_wd_timeout;
+#else
+#define heci_suspend NULL
+#define heci_resume NULL
+#endif
+/*
+ * PCI driver structure
+ */
+static struct pci_driver heci_driver = {
+ .name = heci_driver_name,
+ .id_table = heci_pci_tbl,
+ .probe = heci_probe,
+ .remove = __devexit_p(heci_remove),
+ .shutdown = __devexit_p(heci_remove),
+ .suspend = heci_suspend,
+ .resume = heci_resume
+};
+
+/*
+ * file operations structure will be use heci char device.
+ */
+static const struct file_operations heci_fops = {
+ .owner = THIS_MODULE,
+ .read = heci_read,
+ .ioctl = heci_ioctl,
+ .open = heci_open,
+ .release = heci_release,
+ .write = heci_write,
+ .poll = heci_poll,
+};
+
+/**
+ * heci_registration_cdev - set up the cdev structure for heci device.
+ *
+ * @dev: char device struct
+ * @hminor: minor number for registration char device
+ * @fops: file operations structure
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_registration_cdev(struct cdev *dev, int hminor,
+ const struct file_operations *fops)
+{
+ int ret, devno = MKDEV(heci_major, hminor);
+
+ cdev_init(dev, fops);
+ dev->owner = THIS_MODULE;
+ ret = cdev_add(dev, devno, 1);
+ /* Fail gracefully if need be */
+ if (ret) {
+ printk(KERN_ERR "heci: Error %d registering heci device %d\n",
+ ret, hminor);
+ }
+ return ret;
+}
+
+/* Display the version of heci driver. */
+static ssize_t version_show(struct class *dev, char *buf)
+{
+ return sprintf(buf, "%s %s.\n",
+ heci_driver_string, heci_driver_version);
+}
+
+static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
+
+/**
+ * heci_register_cdev - registers heci char device
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_register_cdev(void)
+{
+ int ret;
+ dev_t dev;
+
+ /* registration of char devices */
+ ret = alloc_chrdev_region(&dev, HECI_MINORS_BASE, HECI_MINORS_COUNT,
+ HECI_DRIVER_NAME);
+ if (ret) {
+ printk(KERN_ERR "heci: Error allocating char device region.\n");
+ return ret;
+ }
+
+ heci_major = MAJOR(dev);
+
+ ret = heci_registration_cdev(&heci_cdev, HECI_MINOR_NUMBER,
+ &heci_fops);
+ if (ret)
+ unregister_chrdev_region(MKDEV(heci_major, HECI_MINORS_BASE),
+ HECI_MINORS_COUNT);
+
+ return ret;
+}
+
+/**
+ * heci_unregister_cdev - unregisters heci char device
+ */
+static void heci_unregister_cdev(void)
+{
+ cdev_del(&heci_cdev);
+ unregister_chrdev_region(MKDEV(heci_major, HECI_MINORS_BASE),
+ HECI_MINORS_COUNT);
+}
+
+#ifndef HECI_DEVICE_CREATE
+#define HECI_DEVICE_CREATE device_create
+#endif
+/**
+ * heci_sysfs_device_create - adds device entry to sysfs
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_sysfs_device_create(void)
+{
+ struct class *class;
+ void *tmphdev;
+ int err = 0;
+
+ class = class_create(THIS_MODULE, HECI_DRIVER_NAME);
+ if (IS_ERR(class)) {
+ err = PTR_ERR(class);
+ printk(KERN_ERR "heci: Error creating heci class.\n");
+ goto err_out;
+ }
+
+ err = class_create_file(class, &class_attr_version);
+ if (err) {
+ class_destroy(class);
+ printk(KERN_ERR "heci: Error creating heci class file.\n");
+ goto err_out;
+ }
+
+ tmphdev = HECI_DEVICE_CREATE(class, NULL, heci_cdev.dev, NULL,
+ HECI_DEV_NAME);
+ if (IS_ERR(tmphdev)) {
+ err = PTR_ERR(tmphdev);
+ class_remove_file(class, &class_attr_version);
+ class_destroy(class);
+ goto err_out;
+ }
+
+ heci_class = class;
+err_out:
+ return err;
+}
+
+/**
+ * heci_sysfs_device_remove - unregisters the device entry on sysfs
+ */
+static void heci_sysfs_device_remove(void)
+{
+ if ((heci_class == NULL) || (IS_ERR(heci_class)))
+ return;
+
+ device_destroy(heci_class, heci_cdev.dev);
+ class_remove_file(heci_class, &class_attr_version);
+ class_destroy(heci_class);
+}
+
+/**
+ * heci_init_module - Driver Registration Routine
+ *
+ * heci_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int __init heci_init_module(void)
+{
+ int ret = 0;
+
+ printk(KERN_INFO "heci: %s - version %s\n", heci_driver_string,
+ heci_driver_version);
+ printk(KERN_INFO "heci: %s\n", heci_copyright);
+
+ /* init pci module */
+ ret = pci_register_driver(&heci_driver);
+ if (ret < 0) {
+ printk(KERN_ERR "heci: Error registering driver.\n");
+ goto end;
+ }
+
+ ret = heci_register_cdev();
+ if (ret)
+ goto unregister_pci;
+
+ ret = heci_sysfs_device_create();
+ if (ret)
+ goto unregister_cdev;
+
+ return ret;
+
+unregister_cdev:
+ heci_unregister_cdev();
+unregister_pci:
+ pci_unregister_driver(&heci_driver);
+end:
+ return ret;
+}
+
+module_init(heci_init_module);
+
+
+/**
+ * heci_exit_module - Driver Exit Cleanup Routine
+ *
+ * heci_exit_module is called just before the driver is removed
+ * from memory.
+ */
+static void __exit heci_exit_module(void)
+{
+ pci_unregister_driver(&heci_driver);
+ heci_sysfs_device_remove();
+ heci_unregister_cdev();
+}
+
+module_exit(heci_exit_module);
+
+
+/**
+ * heci_probe - Device Initialization Routine
+ *
+ * @pdev: PCI device information struct
+ * @ent: entry in kcs_pci_tbl
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int __devinit heci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct iamt_heci_device *dev = NULL;
+ int i, err = 0;
+
+ if (heci_device) {
+ err = -EEXIST;
+ goto end;
+ }
+ /* enable pci dev */
+ err = pci_enable_device(pdev);
+ if (err) {
+ printk(KERN_ERR "heci: Failed to enable pci device.\n");
+ goto end;
+ }
+ /* set PCI host mastering */
+ pci_set_master(pdev);
+ /* pci request regions for heci driver */
+ err = pci_request_regions(pdev, heci_driver_name);
+ if (err) {
+ printk(KERN_ERR "heci: Failed to get pci regions.\n");
+ goto disable_device;
+ }
+ /* allocates and initializes the heci dev structure */
+ dev = init_heci_device(pdev);
+ if (!dev) {
+ err = -ENOMEM;
+ goto release_regions;
+ }
+ /* mapping IO device memory */
+ for (i = 0; i <= 5; i++) {
+ if (pci_resource_len(pdev, i) == 0)
+ continue;
+ if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
+ printk(KERN_ERR "heci: heci has IO ports.\n");
+ goto free_device;
+ } else if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) {
+ if (dev->mem_base) {
+ printk(KERN_ERR
+ "heci: Too many mem addresses.\n");
+ goto free_device;
+ }
+ dev->mem_base = pci_resource_start(pdev, i);
+ dev->mem_length = pci_resource_len(pdev, i);
+ }
+ }
+ if (!dev->mem_base) {
+ printk(KERN_ERR "heci: No address to use.\n");
+ err = -ENODEV;
+ goto free_device;
+ }
+ dev->mem_addr = ioremap_nocache(dev->mem_base,
+ dev->mem_length);
+ if (!dev->mem_addr) {
+ printk(KERN_ERR "heci: Remap IO device memory failure.\n");
+ err = -ENOMEM;
+ goto free_device;
+ }
+ /* request and enable interrupt */
+ err = request_irq(pdev->irq, heci_isr_interrupt, IRQF_SHARED,
+ heci_driver_name, dev);
+ if (err) {
+ printk(KERN_ERR "heci: Request_irq failure. irq = %d \n",
+ pdev->irq);
+ goto unmap_memory;
+ }
+
+ if (heci_hw_init(dev)) {
+ printk(KERN_ERR "heci: Init hw failure.\n");
+ err = -ENODEV;
+ goto release_irq;
+ }
+ init_timer(&dev->wd_timer);
+
+ heci_initialize_clients(dev);
+ if (dev->heci_state != HECI_ENABLED) {
+ err = -ENODEV;
+ goto release_hw;
+ }
+
+ spin_lock_bh(&dev->device_lock);
+ heci_device = pdev;
+ pci_set_drvdata(pdev, dev);
+ spin_unlock_bh(&dev->device_lock);
+
+ if (dev->wd_timeout)
+ mod_timer(&dev->wd_timer, jiffies);
+
+#ifdef CONFIG_PM
+ g_sus_wd_timeout = 0;
+#endif
+ printk(KERN_INFO "heci driver initialization successful.\n");
+ return 0;
+
+release_hw:
+ /* disable interrupts */
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ heci_csr_disable_interrupts(dev);
+
+ del_timer_sync(&dev->wd_timer);
+
+ flush_scheduled_work();
+
+release_irq:
+ free_irq(pdev->irq, dev);
+unmap_memory:
+ if (dev->mem_addr)
+ iounmap(dev->mem_addr);
+free_device:
+ kfree(dev);
+release_regions:
+ pci_release_regions(pdev);
+disable_device:
+ pci_disable_device(pdev);
+end:
+ printk(KERN_ERR "heci driver initialization failed.\n");
+ return err;
+}
+
+/**
+ * heci_remove - Device Removal Routine
+ *
+ * @pdev: PCI device information struct
+ *
+ * heci_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device.
+ */
+static void __devexit heci_remove(struct pci_dev *pdev)
+{
+ struct iamt_heci_device *dev = pci_get_drvdata(pdev);
+
+ if (heci_device != pdev)
+ return;
+
+ if (dev == NULL)
+ return;
+
+ spin_lock_bh(&dev->device_lock);
+ if (heci_device != pdev) {
+ spin_unlock_bh(&dev->device_lock);
+ return;
+ }
+
+ if (dev->reinit_tsk != NULL) {
+ kthread_stop(dev->reinit_tsk);
+ dev->reinit_tsk = NULL;
+ }
+
+ del_timer_sync(&dev->wd_timer);
+ if (dev->wd_file_ext.state == HECI_FILE_CONNECTED
+ && dev->wd_timeout) {
+ dev->wd_timeout = 0;
+ dev->wd_due_counter = 0;
+ memcpy(dev->wd_data, heci_stop_wd_params, HECI_WD_PARAMS_SIZE);
+ dev->stop = 1;
+ if (dev->host_buffer_is_empty &&
+ flow_ctrl_creds(dev, &dev->wd_file_ext)) {
+ dev->host_buffer_is_empty = 0;
+
+ if (!heci_send_wd(dev))
+ DBG("send stop WD failed\n");
+ else
+ flow_ctrl_reduce(dev, &dev->wd_file_ext);
+
+ dev->wd_pending = 0;
+ } else {
+ dev->wd_pending = 1;
+ }
+ dev->wd_stoped = 0;
+ spin_unlock_bh(&dev->device_lock);
+
+ wait_event_interruptible_timeout(dev->wait_stop_wd,
+ (dev->wd_stoped), 10 * HZ);
+ spin_lock_bh(&dev->device_lock);
+ if (!dev->wd_stoped)
+ DBG("stop wd failed to complete.\n");
+ else
+ DBG("stop wd complete.\n");
+
+ }
+
+ heci_device = NULL;
+ spin_unlock_bh(&dev->device_lock);
+
+ if (dev->iamthif_file_ext.state == HECI_FILE_CONNECTED) {
+ dev->iamthif_file_ext.state = HECI_FILE_DISCONNECTING;
+ heci_disconnect_host_client(dev,
+ &dev->iamthif_file_ext);
+ }
+ if (dev->wd_file_ext.state == HECI_FILE_CONNECTED) {
+ dev->wd_file_ext.state = HECI_FILE_DISCONNECTING;
+ heci_disconnect_host_client(dev,
+ &dev->wd_file_ext);
+ }
+
+ spin_lock_bh(&dev->device_lock);
+
+ /* remove entry if already in list */
+ DBG("list del iamthif and wd file list.\n");
+ heci_remove_client_from_file_list(dev, dev->wd_file_ext.
+ host_client_id);
+ heci_remove_client_from_file_list(dev,
+ dev->iamthif_file_ext.host_client_id);
+
+ dev->iamthif_current_cb = NULL;
+ dev->iamthif_file_ext.file = NULL;
+ dev->num_heci_me_clients = 0;
+
+ spin_unlock_bh(&dev->device_lock);
+
+ flush_scheduled_work();
+
+ /* disable interrupts */
+ heci_csr_disable_interrupts(dev);
+
+ free_irq(pdev->irq, dev);
+ pci_set_drvdata(pdev, NULL);
+
+ if (dev->mem_addr)
+ iounmap(dev->mem_addr);
+
+ kfree(dev);
+
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+}
+
+/**
+ * heci_clear_list - remove all callbacks associated with file
+ * from heci_cb_list
+ *
+ * @file: file information struct
+ * @heci_cb_list: callbacks list
+ *
+ * heci_clear_list is called to clear resources associated with file
+ * when application calls close function or Ctrl-C was pressed
+ *
+ * returns 1 if callback removed from the list, 0 otherwise
+ */
+static int heci_clear_list(struct iamt_heci_device *dev,
+ struct file *file, struct list_head *heci_cb_list)
+{
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb_next = NULL;
+ struct file *file_temp;
+ int rets = 0;
+
+ /* list all list member */
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ heci_cb_list, cb_list) {
+ file_temp = (struct file *)priv_cb_pos->file_object;
+ /* check if list member associated with a file */
+ if (file_temp == file) {
+ /* remove member from the list */
+ list_del(&priv_cb_pos->cb_list);
+ /* check if cb equal to current iamthif cb */
+ if (dev->iamthif_current_cb == priv_cb_pos) {
+ dev->iamthif_current_cb = NULL;
+ /* send flow control to iamthif client */
+ heci_send_flow_control(dev,
+ &dev->iamthif_file_ext);
+ }
+ /* free all allocated buffers */
+ heci_free_cb_private(priv_cb_pos);
+ rets = 1;
+ }
+ }
+ return rets;
+}
+
+/**
+ * heci_clear_lists - remove all callbacks associated with file
+ *
+ * @dev: device information struct
+ * @file: file information struct
+ *
+ * heci_clear_lists is called to clear resources associated with file
+ * when application calls close function or Ctrl-C was pressed
+ *
+ * returns 1 if callback removed from the list, 0 otherwise
+ */
+static int heci_clear_lists(struct iamt_heci_device *dev, struct file *file)
+{
+ int rets = 0;
+
+ /* remove callbacks associated with a file */
+ heci_clear_list(dev, file, &dev->pthi_cmd_list.heci_cb.cb_list);
+ if (heci_clear_list(dev, file,
+ &dev->pthi_read_complete_list.heci_cb.cb_list))
+ rets = 1;
+
+ heci_clear_list(dev, file, &dev->ctrl_rd_list.heci_cb.cb_list);
+
+ if (heci_clear_list(dev, file, &dev->ctrl_wr_list.heci_cb.cb_list))
+ rets = 1;
+
+ if (heci_clear_list(dev, file,
+ &dev->write_waiting_list.heci_cb.cb_list))
+ rets = 1;
+
+ if (heci_clear_list(dev, file, &dev->write_list.heci_cb.cb_list))
+ rets = 1;
+
+ /* check if iamthif_current_cb not NULL */
+ if (dev->iamthif_current_cb && (!rets)) {
+ /* check file and iamthif current cb association */
+ if (dev->iamthif_current_cb->file_object == file) {
+ /* remove cb */
+ heci_free_cb_private(dev->iamthif_current_cb);
+ dev->iamthif_current_cb = NULL;
+ rets = 1;
+ }
+ }
+ return rets;
+}
+
+/**
+ * heci_open - the open function
+ *
+ * @inode: pointer to inode structure
+ * @file: pointer to file structure
+ *
+ * returns 0 on success, <0 on error
+ */
+static int heci_open(struct inode *inode, struct file *file)
+{
+ struct heci_file_private *file_ext;
+ int if_num = iminor(inode);
+ struct iamt_heci_device *dev;
+
+ if (!heci_device)
+ return -ENODEV;
+
+ dev = pci_get_drvdata(heci_device);
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev))
+ return -ENODEV;
+
+ file_ext = heci_alloc_file_private(file);
+ if (file_ext == NULL)
+ return -ENOMEM;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ kfree(file_ext);
+ return -ENODEV;
+ }
+ if (dev->open_handle_count >= HECI_MAX_OPEN_HANDLE_COUNT) {
+ spin_unlock_bh(&dev->device_lock);
+ kfree(file_ext);
+ return -ENFILE;
+ };
+ dev->open_handle_count++;
+ list_add_tail(&file_ext->link, &dev->file_list);
+ while ((dev->heci_host_clients[dev->current_host_client_id / 8]
+ & (1 << (dev->current_host_client_id % 8))) != 0) {
+
+ dev->current_host_client_id++; /* allow overflow */
+ DBG("current_host_client_id = %d\n",
+ dev->current_host_client_id);
+ DBG("dev->open_handle_count = %lu\n",
+ dev->open_handle_count);
+ }
+ DBG("current_host_client_id = %d\n", dev->current_host_client_id);
+ file_ext->host_client_id = dev->current_host_client_id;
+ dev->heci_host_clients[file_ext->host_client_id / 8] |=
+ (1 << (file_ext->host_client_id % 8));
+ spin_unlock_bh(&dev->device_lock);
+ spin_lock(&file_ext->file_lock);
+ file_ext->state = HECI_FILE_INITIALIZING;
+ file_ext->sm_state = 0;
+
+ file->private_data = file_ext;
+ spin_unlock(&file_ext->file_lock);
+
+ return 0;
+}
+
+/**
+ * heci_release - the release function
+ *
+ * @inode: pointer to inode structure
+ * @file: pointer to file structure
+ *
+ * returns 0 on success, <0 on error
+ */
+static int heci_release(struct inode *inode, struct file *file)
+{
+ int rets = 0;
+ int if_num = iminor(inode);
+ struct heci_file_private *file_ext = file->private_data;
+ struct heci_cb_private *priv_cb = NULL;
+ struct iamt_heci_device *dev;
+
+ if (!heci_device)
+ return -ENODEV;
+
+ dev = pci_get_drvdata(heci_device);
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+ return -ENODEV;
+
+ if (file_ext != &dev->iamthif_file_ext) {
+ spin_lock(&file_ext->file_lock);
+ if (file_ext->state == HECI_FILE_CONNECTED) {
+ file_ext->state = HECI_FILE_DISCONNECTING;
+ spin_unlock(&file_ext->file_lock);
+ DBG("disconnecting client host client = %d, "
+ "ME client = %d\n",
+ file_ext->host_client_id,
+ file_ext->me_client_id);
+ rets = heci_disconnect_host_client(dev, file_ext);
+ spin_lock(&file_ext->file_lock);
+ }
+ spin_lock_bh(&dev->device_lock);
+ heci_flush_queues(dev, file_ext);
+ DBG("remove client host client = %d, ME client = %d\n",
+ file_ext->host_client_id,
+ file_ext->me_client_id);
+
+ if (dev->open_handle_count > 0) {
+ dev->heci_host_clients[file_ext->host_client_id / 8] &=
+ ~(1 << (file_ext->host_client_id % 8));
+ dev->open_handle_count--;
+ }
+ heci_remove_client_from_file_list(dev,
+ file_ext->host_client_id);
+
+ /* free read cb */
+ if (file_ext->read_cb != NULL) {
+ priv_cb = find_read_list_entry(dev, file_ext);
+ /* Remove entry from read list */
+ if (priv_cb != NULL)
+ list_del(&priv_cb->cb_list);
+
+ priv_cb = file_ext->read_cb;
+ file_ext->read_cb = NULL;
+ }
+
+ spin_unlock_bh(&dev->device_lock);
+ file->private_data = NULL;
+ spin_unlock(&file_ext->file_lock);
+
+ if (priv_cb != NULL)
+ heci_free_cb_private(priv_cb);
+
+ kfree(file_ext);
+ } else {
+ spin_lock_bh(&dev->device_lock);
+
+ if (dev->open_handle_count > 0)
+ dev->open_handle_count--;
+
+ if (dev->iamthif_file_object == file
+ && dev->iamthif_state != HECI_IAMTHIF_IDLE) {
+ DBG("pthi canceled iamthif state %d\n",
+ dev->iamthif_state);
+ dev->iamthif_canceled = 1;
+ if (dev->iamthif_state == HECI_IAMTHIF_READ_COMPLETE) {
+ DBG("run next pthi iamthif cb\n");
+ run_next_iamthif_cmd(dev);
+ }
+ }
+
+ if (heci_clear_lists(dev, file))
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+
+ spin_unlock_bh(&dev->device_lock);
+ }
+ return rets;
+}
+
+static struct heci_cb_private *find_read_list_entry(
+ struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb_next = NULL;
+ struct heci_file_private *file_ext_list_temp;
+
+ if (dev->read_list.status == 0
+ && !list_empty(&dev->read_list.heci_cb.cb_list)) {
+ DBG("remove read_list CB \n");
+ list_for_each_entry_safe(priv_cb_pos,
+ priv_cb_next,
+ &dev->read_list.heci_cb.cb_list, cb_list) {
+
+ file_ext_list_temp = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+
+ if ((file_ext_list_temp != NULL) &&
+ heci_fe_same_id(file_ext, file_ext_list_temp))
+ return priv_cb_pos;
+
+ }
+ }
+ return NULL;
+}
+
+/**
+ * heci_read - the read client message function.
+ *
+ * @file: pointer to file structure
+ * @ubuf: pointer to user buffer
+ * @length: buffer length
+ * @offset: data offset in buffer
+ *
+ * returns >=0 data length on success , <0 on error
+ */
+static ssize_t heci_read(struct file *file, char __user *ubuf,
+ size_t length, loff_t *offset)
+{
+ int i;
+ int rets = 0, err = 0;
+ int if_num = iminor(file->f_dentry->d_inode);
+ struct heci_file_private *file_ext = file->private_data;
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb = NULL;
+ struct iamt_heci_device *dev;
+
+ if (!heci_device)
+ return -ENODEV;
+
+ dev = pci_get_drvdata(heci_device);
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+ return -ENODEV;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ return -ENODEV;
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ spin_lock(&file_ext->file_lock);
+ if ((file_ext->sm_state & HECI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) {
+ spin_unlock(&file_ext->file_lock);
+ /* Do not allow to read watchdog client */
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (memcmp(&heci_wd_guid,
+ &dev->me_clients[i].props.protocol_name,
+ sizeof(struct guid)) == 0) {
+ if (file_ext->me_client_id ==
+ dev->me_clients[i].client_id)
+ return -EBADF;
+ }
+ }
+ } else {
+ file_ext->sm_state &= ~HECI_WD_STATE_INDEPENDENCE_MSG_SENT;
+ spin_unlock(&file_ext->file_lock);
+ }
+
+ if (file_ext == &dev->iamthif_file_ext) {
+ rets = pthi_read(dev, if_num, file, ubuf, length, offset);
+ goto out;
+ }
+
+ if (file_ext->read_cb && file_ext->read_cb->information > *offset) {
+ priv_cb = file_ext->read_cb;
+ goto copy_buffer;
+ } else if (file_ext->read_cb && file_ext->read_cb->information > 0 &&
+ file_ext->read_cb->information <= *offset) {
+ priv_cb = file_ext->read_cb;
+ rets = 0;
+ goto free;
+ } else if ((!file_ext->read_cb || file_ext->read_cb->information == 0)
+ && *offset > 0) {
+ /*Offset needs to be cleaned for contingous reads*/
+ *offset = 0;
+ rets = 0;
+ goto out;
+ }
+
+ spin_lock(&file_ext->read_io_lock);
+ err = heci_start_read(dev, if_num, file_ext);
+ if (err != 0 && err != -EBUSY) {
+ DBG("heci start read failure with status = %d\n", err);
+ spin_unlock(&file_ext->read_io_lock);
+ rets = err;
+ goto out;
+ }
+ if (HECI_READ_COMPLETE != file_ext->reading_state
+ && !waitqueue_active(&file_ext->rx_wait)) {
+ if (file->f_flags & O_NONBLOCK) {
+ rets = -EAGAIN;
+ spin_unlock(&file_ext->read_io_lock);
+ goto out;
+ }
+ spin_unlock(&file_ext->read_io_lock);
+
+ if (wait_event_interruptible(file_ext->rx_wait,
+ (HECI_READ_COMPLETE == file_ext->reading_state
+ || HECI_FILE_INITIALIZING == file_ext->state
+ || HECI_FILE_DISCONNECTED == file_ext->state
+ || HECI_FILE_DISCONNECTING == file_ext->state))) {
+ if (signal_pending(current)) {
+ rets = -EINTR;
+ goto out;
+ }
+ return -ERESTARTSYS;
+ }
+
+ if (HECI_FILE_INITIALIZING == file_ext->state ||
+ HECI_FILE_DISCONNECTED == file_ext->state ||
+ HECI_FILE_DISCONNECTING == file_ext->state) {
+ rets = -EBUSY;
+ goto out;
+ }
+ spin_lock(&file_ext->read_io_lock);
+ }
+
+ priv_cb = file_ext->read_cb;
+
+ if (!priv_cb) {
+ spin_unlock(&file_ext->read_io_lock);
+ return -ENODEV;
+ }
+ if (file_ext->reading_state != HECI_READ_COMPLETE) {
+ spin_unlock(&file_ext->read_io_lock);
+ return 0;
+ }
+ spin_unlock(&file_ext->read_io_lock);
+ /* now copy the data to user space */
+copy_buffer:
+ DBG("priv_cb->response_buffer size - %d\n",
+ priv_cb->response_buffer.size);
+ DBG("priv_cb->information - %lu\n",
+ priv_cb->information);
+ if (length == 0 || ubuf == NULL ||
+ *offset > priv_cb->information) {
+ rets = -EMSGSIZE;
+ goto free;
+ }
+
+ /* length is being turncated to PAGE_SIZE, however, */
+ /* information size may be longer */
+ length = (length < (priv_cb->information - *offset) ?
+ length : (priv_cb->information - *offset));
+
+ if (copy_to_user(ubuf,
+ priv_cb->response_buffer.data + *offset,
+ length)) {
+ rets = -EFAULT;
+ goto free;
+ }
+
+ rets = length;
+ *offset += length;
+ if ((unsigned long)*offset < priv_cb->information)
+ goto out;
+
+free:
+ spin_lock_bh(&dev->device_lock);
+ priv_cb_pos = find_read_list_entry(dev, file_ext);
+ /* Remove entry from read list */
+ if (priv_cb_pos != NULL)
+ list_del(&priv_cb_pos->cb_list);
+ spin_unlock_bh(&dev->device_lock);
+ heci_free_cb_private(priv_cb);
+ spin_lock(&file_ext->read_io_lock);
+ file_ext->reading_state = HECI_IDLE;
+ file_ext->read_cb = NULL;
+ file_ext->read_pending = 0;
+ spin_unlock(&file_ext->read_io_lock);
+out: DBG("end heci read rets= %d\n", rets);
+ return rets;
+}
+
+/**
+ * heci_write - the write function.
+ *
+ * @file: pointer to file structure
+ * @ubuf: pointer to user buffer
+ * @length: buffer length
+ * @offset: data offset in buffer
+ *
+ * returns >=0 data length on success , <0 on error
+ */
+static ssize_t heci_write(struct file *file, const char __user *ubuf,
+ size_t length, loff_t *offset)
+{
+ int rets = 0;
+ __u8 i;
+ int if_num = iminor(file->f_dentry->d_inode);
+ struct heci_file_private *file_ext = file->private_data;
+ struct heci_cb_private *priv_write_cb = NULL;
+ struct heci_msg_hdr heci_hdr;
+ struct iamt_heci_device *dev;
+ unsigned long currtime = get_seconds();
+
+ if (!heci_device)
+ return -ENODEV;
+
+ dev = pci_get_drvdata(heci_device);
+
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+ return -ENODEV;
+
+ spin_lock_bh(&dev->device_lock);
+
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ return -ENODEV;
+ }
+ if (file_ext == &dev->iamthif_file_ext) {
+ priv_write_cb = find_pthi_read_list_entry(dev, file);
+ if ((priv_write_cb != NULL) &&
+ (((currtime - priv_write_cb->read_time) >
+ IAMTHIF_READ_TIMER) ||
+ (file_ext->reading_state == HECI_READ_COMPLETE))) {
+ (*offset) = 0;
+ list_del(&priv_write_cb->cb_list);
+ heci_free_cb_private(priv_write_cb);
+ priv_write_cb = NULL;
+ }
+ }
+
+ /* free entry used in read */
+ if (file_ext->reading_state == HECI_READ_COMPLETE) {
+ *offset = 0;
+ priv_write_cb = find_read_list_entry(dev, file_ext);
+ if (priv_write_cb != NULL) {
+ list_del(&priv_write_cb->cb_list);
+ heci_free_cb_private(priv_write_cb);
+ priv_write_cb = NULL;
+ spin_lock(&file_ext->read_io_lock);
+ file_ext->reading_state = HECI_IDLE;
+ file_ext->read_cb = NULL;
+ file_ext->read_pending = 0;
+ spin_unlock(&file_ext->read_io_lock);
+ }
+ } else if (file_ext->reading_state == HECI_IDLE &&
+ file_ext->read_pending == 0)
+ (*offset) = 0;
+
+ spin_unlock_bh(&dev->device_lock);
+
+ priv_write_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
+ if (!priv_write_cb)
+ return -ENOMEM;
+
+ priv_write_cb->file_object = file;
+ priv_write_cb->file_private = file_ext;
+ priv_write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL);
+ if (!priv_write_cb->request_buffer.data) {
+ kfree(priv_write_cb);
+ return -ENOMEM;
+ }
+ DBG("length =%d\n", (int) length);
+
+ if (copy_from_user(priv_write_cb->request_buffer.data,
+ ubuf, length)) {
+ rets = -EFAULT;
+ goto fail;
+ }
+
+ spin_lock(&file_ext->file_lock);
+ file_ext->sm_state = 0;
+ if ((length == 4) &&
+ ((memcmp(heci_wd_state_independence_msg[0], ubuf, 4) == 0) ||
+ (memcmp(heci_wd_state_independence_msg[1], ubuf, 4) == 0) ||
+ (memcmp(heci_wd_state_independence_msg[2], ubuf, 4) == 0)))
+ file_ext->sm_state |= HECI_WD_STATE_INDEPENDENCE_MSG_SENT;
+ spin_unlock(&file_ext->file_lock);
+
+ INIT_LIST_HEAD(&priv_write_cb->cb_list);
+ if (file_ext == &dev->iamthif_file_ext) {
+ priv_write_cb->response_buffer.data =
+ kmalloc(IAMTHIF_MTU, GFP_KERNEL);
+ if (!priv_write_cb->response_buffer.data) {
+ rets = -ENOMEM;
+ goto fail;
+ }
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ rets = -ENODEV;
+ goto fail;
+ }
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id ==
+ dev->iamthif_file_ext.me_client_id)
+ break;
+ }
+
+ BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
+ if ((i == dev->num_heci_me_clients) ||
+ (dev->me_clients[i].client_id !=
+ dev->iamthif_file_ext.me_client_id)) {
+
+ spin_unlock_bh(&dev->device_lock);
+ rets = -ENODEV;
+ goto fail;
+ } else if ((length > dev->me_clients[i].props.max_msg_length)
+ || (length <= 0)) {
+ spin_unlock_bh(&dev->device_lock);
+ rets = -EMSGSIZE;
+ goto fail;
+ }
+
+
+ priv_write_cb->response_buffer.size = IAMTHIF_MTU;
+ priv_write_cb->major_file_operations = HECI_IOCTL;
+ priv_write_cb->information = 0;
+ priv_write_cb->request_buffer.size = length;
+ if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTED) {
+ spin_unlock_bh(&dev->device_lock);
+ rets = -ENODEV;
+ goto fail;
+ }
+
+ if (!list_empty(&dev->pthi_cmd_list.heci_cb.cb_list)
+ || dev->iamthif_state != HECI_IAMTHIF_IDLE) {
+ DBG("pthi_state = %d\n", (int) dev->iamthif_state);
+ DBG("add PTHI cb to pthi cmd waiting list\n");
+ list_add_tail(&priv_write_cb->cb_list,
+ &dev->pthi_cmd_list.heci_cb.cb_list);
+ rets = length;
+ } else {
+ DBG("call pthi write\n");
+ rets = pthi_write(dev, priv_write_cb);
+
+ if (rets != 0) {
+ DBG("pthi write failed with status = %d\n",
+ rets);
+ spin_unlock_bh(&dev->device_lock);
+ goto fail;
+ }
+ rets = length;
+ }
+ spin_unlock_bh(&dev->device_lock);
+ return rets;
+ }
+
+ priv_write_cb->major_file_operations = HECI_WRITE;
+ /* make sure information is zero before we start */
+
+ priv_write_cb->information = 0;
+ priv_write_cb->request_buffer.size = length;
+
+ spin_lock(&file_ext->write_io_lock);
+ DBG("host client = %d, ME client = %d\n",
+ file_ext->host_client_id, file_ext->me_client_id);
+ if (file_ext->state != HECI_FILE_CONNECTED) {
+ rets = -ENODEV;
+ DBG("host client = %d, is not connected to ME client = %d",
+ file_ext->host_client_id,
+ file_ext->me_client_id);
+
+ goto unlock;
+ }
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id ==
+ file_ext->me_client_id)
+ break;
+ }
+ BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
+ if (i == dev->num_heci_me_clients) {
+ rets = -ENODEV;
+ goto unlock;
+ }
+ if (length > dev->me_clients[i].props.max_msg_length || length <= 0) {
+ rets = -EINVAL;
+ goto unlock;
+ }
+ priv_write_cb->file_private = file_ext;
+
+ spin_lock_bh(&dev->device_lock);
+ if (flow_ctrl_creds(dev, file_ext) &&
+ dev->host_buffer_is_empty) {
+ spin_unlock_bh(&dev->device_lock);
+ dev->host_buffer_is_empty = 0;
+ if (length > ((((dev->host_hw_state & H_CBD) >> 24) *
+ sizeof(__u32)) - sizeof(struct heci_msg_hdr))) {
+
+ heci_hdr.length =
+ (((dev->host_hw_state & H_CBD) >> 24) *
+ sizeof(__u32)) -
+ sizeof(struct heci_msg_hdr);
+ heci_hdr.msg_complete = 0;
+ } else {
+ heci_hdr.length = length;
+ heci_hdr.msg_complete = 1;
+ }
+ heci_hdr.host_addr = file_ext->host_client_id;
+ heci_hdr.me_addr = file_ext->me_client_id;
+ heci_hdr.reserved = 0;
+ DBG("call heci_write_message header=%08x.\n",
+ *((__u32 *) &heci_hdr));
+ spin_unlock(&file_ext->write_io_lock);
+ /* protect heci low level write */
+ spin_lock_bh(&dev->device_lock);
+ if (!heci_write_message(dev, &heci_hdr,
+ (unsigned char *) (priv_write_cb->request_buffer.data),
+ heci_hdr.length)) {
+
+ spin_unlock_bh(&dev->device_lock);
+ heci_free_cb_private(priv_write_cb);
+ rets = -ENODEV;
+ priv_write_cb->information = 0;
+ return rets;
+ }
+ file_ext->writing_state = HECI_WRITING;
+ priv_write_cb->information = heci_hdr.length;
+ if (heci_hdr.msg_complete) {
+ flow_ctrl_reduce(dev, file_ext);
+ list_add_tail(&priv_write_cb->cb_list,
+ &dev->write_waiting_list.heci_cb.cb_list);
+ } else {
+ list_add_tail(&priv_write_cb->cb_list,
+ &dev->write_list.heci_cb.cb_list);
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ } else {
+
+ spin_unlock_bh(&dev->device_lock);
+ priv_write_cb->information = 0;
+ file_ext->writing_state = HECI_WRITING;
+ spin_unlock(&file_ext->write_io_lock);
+ list_add_tail(&priv_write_cb->cb_list,
+ &dev->write_list.heci_cb.cb_list);
+ }
+ return length;
+
+unlock:
+ spin_unlock(&file_ext->write_io_lock);
+fail:
+ heci_free_cb_private(priv_write_cb);
+ return rets;
+
+}
+
+/**
+ * heci_ioctl - the IOCTL function
+ *
+ * @inode: pointer to inode structure
+ * @file: pointer to file structure
+ * @cmd: ioctl command
+ * @data: pointer to heci message structure
+ *
+ * returns 0 on success , <0 on error
+ */
+static int heci_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long data)
+{
+ int rets = 0;
+ int if_num = iminor(inode);
+ struct heci_file_private *file_ext = file->private_data;
+ /* in user space */
+ struct heci_message_data __user *u_msg;
+ struct heci_message_data k_msg; /* all in kernel on the stack */
+ struct iamt_heci_device *dev;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (!heci_device)
+ return -ENODEV;
+
+ dev = pci_get_drvdata(heci_device);
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+ return -ENODEV;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ return -ENODEV;
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ /* first copy from user all data needed */
+ u_msg = (struct heci_message_data __user *)data;
+ if (copy_from_user(&k_msg, u_msg, sizeof(k_msg))) {
+ DBG("first copy from user all data needed filled\n");
+ return -EFAULT;
+ }
+ DBG("user message size is %d\n", k_msg.size);
+
+ switch (cmd) {
+ case IOCTL_HECI_GET_VERSION:
+ DBG(": IOCTL_HECI_GET_VERSION\n");
+ rets = heci_ioctl_get_version(dev, if_num, u_msg, k_msg,
+ file_ext);
+ break;
+
+ case IOCTL_HECI_CONNECT_CLIENT:
+ DBG(": IOCTL_HECI_CONNECT_CLIENT.\n");
+ rets = heci_ioctl_connect_client(dev, if_num, u_msg, k_msg,
+ file);
+ break;
+
+ case IOCTL_HECI_WD:
+ DBG(": IOCTL_HECI_WD.\n");
+ rets = heci_ioctl_wd(dev, if_num, k_msg, file_ext);
+ break;
+
+ case IOCTL_HECI_BYPASS_WD:
+ DBG(": IOCTL_HECI_BYPASS_WD.\n");
+ rets = heci_ioctl_bypass_wd(dev, if_num, k_msg, file_ext);
+ break;
+
+ default:
+ rets = -EINVAL;
+ break;
+ }
+ return rets;
+}
+
+/**
+ * heci_poll - the poll function
+ *
+ * @file: pointer to file structure
+ * @wait: pointer to poll_table structure
+ *
+ * returns poll mask
+ */
+static unsigned int heci_poll(struct file *file, poll_table *wait)
+{
+ int if_num = iminor(file->f_dentry->d_inode);
+ unsigned int mask = 0;
+ struct heci_file_private *file_ext = file->private_data;
+ struct iamt_heci_device *dev;
+
+ if (!heci_device)
+ return mask;
+
+ dev = pci_get_drvdata(heci_device);
+
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+ return mask;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ return mask;
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ if (file_ext == &dev->iamthif_file_ext) {
+ poll_wait(file, &dev->iamthif_file_ext.wait, wait);
+ spin_lock(&dev->iamthif_file_ext.file_lock);
+ if (dev->iamthif_state == HECI_IAMTHIF_READ_COMPLETE
+ && dev->iamthif_file_object == file) {
+ mask |= (POLLIN | POLLRDNORM);
+ spin_lock_bh(&dev->device_lock);
+ DBG("run next pthi cb\n");
+ run_next_iamthif_cmd(dev);
+ spin_unlock_bh(&dev->device_lock);
+ }
+ spin_unlock(&dev->iamthif_file_ext.file_lock);
+
+ } else{
+ poll_wait(file, &file_ext->tx_wait, wait);
+ spin_lock(&file_ext->write_io_lock);
+ if (HECI_WRITE_COMPLETE == file_ext->writing_state)
+ mask |= (POLLIN | POLLRDNORM);
+
+ spin_unlock(&file_ext->write_io_lock);
+ }
+
+ return mask;
+}
+
+#ifdef CONFIG_PM
+static int heci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct iamt_heci_device *dev = pci_get_drvdata(pdev);
+ int err = 0;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->reinit_tsk != NULL) {
+ kthread_stop(dev->reinit_tsk);
+ dev->reinit_tsk = NULL;
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ /* Stop watchdog if exists */
+ del_timer_sync(&dev->wd_timer);
+ if (dev->wd_file_ext.state == HECI_FILE_CONNECTED
+ && dev->wd_timeout) {
+ spin_lock_bh(&dev->device_lock);
+ g_sus_wd_timeout = dev->wd_timeout;
+ dev->wd_timeout = 0;
+ dev->wd_due_counter = 0;
+ memcpy(dev->wd_data, heci_stop_wd_params,
+ HECI_WD_PARAMS_SIZE);
+ dev->stop = 1;
+ if (dev->host_buffer_is_empty &&
+ flow_ctrl_creds(dev, &dev->wd_file_ext)) {
+ dev->host_buffer_is_empty = 0;
+ if (!heci_send_wd(dev))
+ DBG("send stop WD failed\n");
+ else
+ flow_ctrl_reduce(dev, &dev->wd_file_ext);
+
+ dev->wd_pending = 0;
+ } else {
+ dev->wd_pending = 1;
+ }
+ spin_unlock_bh(&dev->device_lock);
+ dev->wd_stoped = 0;
+
+ err = wait_event_interruptible_timeout(dev->wait_stop_wd,
+ (dev->wd_stoped),
+ 10 * HZ);
+ if (!dev->wd_stoped)
+ DBG("stop wd failed to complete.\n");
+ else {
+ DBG("stop wd complete %d.\n", err);
+ err = 0;
+ }
+ }
+ /* Set new heci state */
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state == HECI_ENABLED ||
+ dev->heci_state == HECI_RECOVERING_FROM_RESET) {
+ dev->heci_state = HECI_POWER_DOWN;
+ heci_reset(dev, 0);
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ pci_save_state(pdev);
+
+ pci_disable_device(pdev);
+ free_irq(pdev->irq, dev);
+
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ return err;
+}
+
+static int heci_resume(struct pci_dev *pdev)
+{
+ struct iamt_heci_device *dev;
+ int err = 0;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ dev = pci_get_drvdata(pdev);
+ if (!dev)
+ return -ENODEV;
+
+ /* request and enable interrupt */
+ err = request_irq(pdev->irq, heci_isr_interrupt, IRQF_SHARED,
+ heci_driver_name, dev);
+ if (err) {
+ printk(KERN_ERR "heci: Request_irq failure. irq = %d \n",
+ pdev->irq);
+ return err;
+ }
+
+ spin_lock_bh(&dev->device_lock);
+ dev->heci_state = HECI_POWER_UP;
+ heci_reset(dev, 1);
+ spin_unlock_bh(&dev->device_lock);
+
+ /* Start watchdog if stopped in suspend */
+ if (g_sus_wd_timeout != 0) {
+ dev->wd_timeout = g_sus_wd_timeout;
+
+ memcpy(dev->wd_data, heci_start_wd_params,
+ HECI_WD_PARAMS_SIZE);
+ memcpy(dev->wd_data + HECI_WD_PARAMS_SIZE,
+ &dev->wd_timeout, sizeof(__u16));
+ dev->wd_due_counter = 1;
+
+ if (dev->wd_timeout)
+ mod_timer(&dev->wd_timer, jiffies);
+
+ g_sus_wd_timeout = 0;
+ }
+ return err;
+}
+#endif
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(HECI_DRIVER_VERSION);
diff --git a/drivers/staging/heci/heci_version.h b/drivers/staging/heci/heci_version.h
new file mode 100644
index 00000000000..3007aa6e17d
--- /dev/null
+++ b/drivers/staging/heci/heci_version.h
@@ -0,0 +1,54 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#ifndef HECI_VERSION_H
+#define HECI_VERSION_H
+
+#define MAJOR_VERSION 5
+#define MINOR_VERSION 0
+#define QUICK_FIX_NUMBER 0
+#define VER_BUILD 31
+
+#define HECI_DRV_VER1 __stringify(MAJOR_VERSION) "." __stringify(MINOR_VERSION)
+#define HECI_DRV_VER2 __stringify(QUICK_FIX_NUMBER) "." __stringify(VER_BUILD)
+
+#define HECI_DRIVER_VERSION HECI_DRV_VER1 "." HECI_DRV_VER2
+
+#endif
diff --git a/drivers/staging/heci/interrupt.c b/drivers/staging/heci/interrupt.c
new file mode 100644
index 00000000000..aacd2624398
--- /dev/null
+++ b/drivers/staging/heci/interrupt.c
@@ -0,0 +1,1553 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include <linux/kthread.h>
+
+#include "heci.h"
+#include "heci_interface.h"
+
+/*
+ * interrupt function prototypes
+ */
+static void heci_bh_handler(struct work_struct *work);
+static int heci_bh_read_handler(struct io_heci_list *complete_list,
+ struct iamt_heci_device *dev,
+ __s32 *slots);
+static int heci_bh_write_handler(struct io_heci_list *complete_list,
+ struct iamt_heci_device *dev,
+ __s32 *slots);
+static void heci_bh_read_bus_message(struct iamt_heci_device *dev,
+ struct heci_msg_hdr *heci_hdr);
+static int heci_bh_read_pthi_message(struct io_heci_list *complete_list,
+ struct iamt_heci_device *dev,
+ struct heci_msg_hdr *heci_hdr);
+static int heci_bh_read_client_message(struct io_heci_list *complete_list,
+ struct iamt_heci_device *dev,
+ struct heci_msg_hdr *heci_hdr);
+static void heci_client_connect_response(struct iamt_heci_device *dev,
+ struct hbm_client_connect_response *connect_res);
+static void heci_client_disconnect_response(struct iamt_heci_device *dev,
+ struct hbm_client_connect_response *disconnect_res);
+static void heci_client_flow_control_response(struct iamt_heci_device *dev,
+ struct hbm_flow_control *flow_control);
+static void heci_client_disconnect_request(struct iamt_heci_device *dev,
+ struct hbm_client_disconnect_request *disconnect_req);
+
+
+/**
+ * heci_isr_interrupt - The ISR of the HECI device
+ *
+ * @irq: The irq number
+ * @dev_id: pointer to the device structure
+ *
+ * returns irqreturn_t
+ */
+irqreturn_t heci_isr_interrupt(int irq, void *dev_id)
+{
+ int err;
+ struct iamt_heci_device *dev = (struct iamt_heci_device *) dev_id;
+
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+
+ if ((dev->host_hw_state & H_IS) != H_IS)
+ return IRQ_NONE;
+
+ /* disable interrupts */
+ heci_csr_disable_interrupts(dev);
+
+ /*
+ * Our device interrupted, schedule work the heci_bh_handler
+ * to handle the interrupt processing. This needs to be a
+ * workqueue item since the handler can sleep.
+ */
+ PREPARE_WORK(&dev->work, heci_bh_handler);
+ DBG("schedule work the heci_bh_handler.\n");
+ err = schedule_work(&dev->work);
+ if (!err) {
+ printk(KERN_ERR "heci: schedule the heci_bh_handler"
+ " failed error=%x\n", err);
+ }
+ return IRQ_HANDLED;
+}
+
+/**
+ * _heci_cmpl - process completed operation.
+ *
+ * @file_ext: private data of the file object.
+ * @priv_cb_pos: callback block.
+ */
+static void _heci_cmpl(struct heci_file_private *file_ext,
+ struct heci_cb_private *priv_cb_pos)
+{
+ if (priv_cb_pos->major_file_operations == HECI_WRITE) {
+ heci_free_cb_private(priv_cb_pos);
+ DBG("completing write call back.\n");
+ file_ext->writing_state = HECI_WRITE_COMPLETE;
+ if ((&file_ext->tx_wait) &&
+ waitqueue_active(&file_ext->tx_wait))
+ wake_up_interruptible(&file_ext->tx_wait);
+
+ } else if (priv_cb_pos->major_file_operations == HECI_READ
+ && HECI_READING == file_ext->reading_state) {
+ DBG("completing read call back information= %lu\n",
+ priv_cb_pos->information);
+ file_ext->reading_state = HECI_READ_COMPLETE;
+ if ((&file_ext->rx_wait) &&
+ waitqueue_active(&file_ext->rx_wait))
+ wake_up_interruptible(&file_ext->rx_wait);
+
+ }
+}
+
+/**
+ * _heci_cmpl_iamthif - process completed iamthif operation.
+ *
+ * @dev: Device object for our driver.
+ * @priv_cb_pos: callback block.
+ */
+static void _heci_cmpl_iamthif(struct iamt_heci_device *dev,
+ struct heci_cb_private *priv_cb_pos)
+{
+ if (dev->iamthif_canceled != 1) {
+ dev->iamthif_state = HECI_IAMTHIF_READ_COMPLETE;
+ dev->iamthif_stall_timer = 0;
+ memcpy(priv_cb_pos->response_buffer.data,
+ dev->iamthif_msg_buf,
+ dev->iamthif_msg_buf_index);
+ list_add_tail(&priv_cb_pos->cb_list,
+ &dev->pthi_read_complete_list.heci_cb.cb_list);
+ DBG("pthi read completed.\n");
+ } else {
+ run_next_iamthif_cmd(dev);
+ }
+ if (&dev->iamthif_file_ext.wait) {
+ DBG("completing pthi call back.\n");
+ wake_up_interruptible(&dev->iamthif_file_ext.wait);
+ }
+}
+/**
+ * heci_bh_handler - function called after ISR to handle the interrupt
+ * processing.
+ *
+ * @work: pointer to the work structure
+ *
+ * NOTE: This function is called by schedule work
+ */
+static void heci_bh_handler(struct work_struct *work)
+{
+ struct iamt_heci_device *dev =
+ container_of(work, struct iamt_heci_device, work);
+ struct io_heci_list complete_list;
+ __s32 slots;
+ int rets;
+ struct heci_cb_private *cb_pos = NULL, *cb_next = NULL;
+ struct heci_file_private *file_ext;
+ int bus_message_received = 0;
+ struct task_struct *tsk;
+
+ DBG("function called after ISR to handle the interrupt processing.\n");
+ /* initialize our complete list */
+ spin_lock_bh(&dev->device_lock);
+ heci_initialize_list(&complete_list, dev);
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+
+ /* check if ME wants a reset */
+ if (((dev->me_hw_state & ME_RDY_HRA) == 0)
+ && (dev->heci_state != HECI_RESETING)
+ && (dev->heci_state != HECI_INITIALIZING)) {
+ DBG("FW not ready.\n");
+ heci_reset(dev, 1);
+ spin_unlock_bh(&dev->device_lock);
+ return;
+ }
+
+ /* check if we need to start the dev */
+ if ((dev->host_hw_state & H_RDY) == 0) {
+ if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) {
+ DBG("we need to start the dev.\n");
+ dev->host_hw_state |= (H_IE | H_IG | H_RDY);
+ heci_set_csr_register(dev);
+ if (dev->heci_state == HECI_INITIALIZING) {
+ dev->recvd_msg = 1;
+ spin_unlock_bh(&dev->device_lock);
+ wake_up_interruptible(&dev->wait_recvd_msg);
+ return;
+
+ } else {
+ spin_unlock_bh(&dev->device_lock);
+ tsk = kthread_run(heci_task_initialize_clients,
+ dev, "heci_reinit");
+ if (IS_ERR(tsk)) {
+ int rc = PTR_ERR(tsk);
+ printk(KERN_WARNING "heci: Unable to"
+ "start the heci thread: %d\n", rc);
+ }
+ return;
+ }
+ } else {
+ DBG("enable interrupt FW not ready.\n");
+ heci_csr_enable_interrupts(dev);
+ spin_unlock_bh(&dev->device_lock);
+ return;
+ }
+ }
+ /* check slots avalable for reading */
+ slots = count_full_read_slots(dev);
+ DBG("slots =%08x extra_write_index =%08x.\n",
+ slots, dev->extra_write_index);
+ while ((slots > 0) && (!dev->extra_write_index)) {
+ DBG("slots =%08x extra_write_index =%08x.\n", slots,
+ dev->extra_write_index);
+ DBG("call heci_bh_read_handler.\n");
+ rets = heci_bh_read_handler(&complete_list, dev, &slots);
+ if (rets != 0)
+ goto end;
+ }
+ rets = heci_bh_write_handler(&complete_list, dev, &slots);
+end:
+ DBG("end of bottom half function.\n");
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ dev->host_buffer_is_empty = host_buffer_is_empty(dev);
+
+ if ((dev->host_hw_state & H_IS) == H_IS) {
+ /* acknowledge interrupt and disable interrupts */
+ heci_csr_disable_interrupts(dev);
+
+ PREPARE_WORK(&dev->work, heci_bh_handler);
+ DBG("schedule work the heci_bh_handler.\n");
+ rets = schedule_work(&dev->work);
+ if (!rets) {
+ printk(KERN_ERR "heci: schedule the heci_bh_handler"
+ " failed error=%x\n", rets);
+ }
+ } else {
+ heci_csr_enable_interrupts(dev);
+ }
+
+ if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
+ DBG("received waiting bus message\n");
+ bus_message_received = 1;
+ }
+ spin_unlock_bh(&dev->device_lock);
+ if (bus_message_received) {
+ DBG("wake up dev->wait_recvd_msg\n");
+ wake_up_interruptible(&dev->wait_recvd_msg);
+ bus_message_received = 0;
+ }
+ if ((complete_list.status != 0)
+ || list_empty(&complete_list.heci_cb.cb_list))
+ return;
+
+
+ list_for_each_entry_safe(cb_pos, cb_next,
+ &complete_list.heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)cb_pos->file_private;
+ list_del(&cb_pos->cb_list);
+ if (file_ext != NULL) {
+ if (file_ext != &dev->iamthif_file_ext) {
+ DBG("completing call back.\n");
+ _heci_cmpl(file_ext, cb_pos);
+ cb_pos = NULL;
+ } else if (file_ext == &dev->iamthif_file_ext) {
+ _heci_cmpl_iamthif(dev, cb_pos);
+ }
+ }
+ }
+}
+
+
+/**
+ * heci_bh_read_handler - bottom half read routine after ISR to
+ * handle the read processing.
+ *
+ * @cmpl_list: An instance of our list structure
+ * @dev: Device object for our driver
+ * @slots: slots to read.
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_bh_read_handler(struct io_heci_list *cmpl_list,
+ struct iamt_heci_device *dev,
+ __s32 *slots)
+{
+ struct heci_msg_hdr *heci_hdr;
+ int ret = 0;
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+
+ if (!dev->rd_msg_hdr) {
+ dev->rd_msg_hdr = read_heci_register(dev, ME_CB_RW);
+ DBG("slots=%08x.\n", *slots);
+ (*slots)--;
+ DBG("slots=%08x.\n", *slots);
+ }
+ heci_hdr = (struct heci_msg_hdr *) &dev->rd_msg_hdr;
+ DBG("heci_hdr->length =%d\n", heci_hdr->length);
+
+ if ((heci_hdr->reserved) || !(dev->rd_msg_hdr)) {
+ DBG("corrupted message header.\n");
+ ret = -ECORRUPTED_MESSAGE_HEADER;
+ goto end;
+ }
+
+ if ((heci_hdr->host_addr) || (heci_hdr->me_addr)) {
+ list_for_each_entry_safe(file_pos, file_next,
+ &dev->file_list, link) {
+ DBG("list_for_each_entry_safe read host"
+ " client = %d, ME client = %d\n",
+ file_pos->host_client_id,
+ file_pos->me_client_id);
+ if ((file_pos->host_client_id == heci_hdr->host_addr)
+ && (file_pos->me_client_id == heci_hdr->me_addr))
+ break;
+ }
+
+ if (&file_pos->link == &dev->file_list) {
+ DBG("corrupted message header\n");
+ ret = -ECORRUPTED_MESSAGE_HEADER;
+ goto end;
+ }
+ }
+ if (((*slots) * sizeof(__u32)) < heci_hdr->length) {
+ DBG("we can't read the message slots=%08x.\n", *slots);
+ /* we can't read the message */
+ ret = -ERANGE;
+ goto end;
+ }
+
+ /* decide where to read the message too */
+ if (!heci_hdr->host_addr) {
+ DBG("call heci_bh_read_bus_message.\n");
+ heci_bh_read_bus_message(dev, heci_hdr);
+ DBG("end heci_bh_read_bus_message.\n");
+ } else if ((heci_hdr->host_addr == dev->iamthif_file_ext.host_client_id)
+ && (HECI_FILE_CONNECTED == dev->iamthif_file_ext.state)
+ && (dev->iamthif_state == HECI_IAMTHIF_READING)) {
+ DBG("call heci_bh_read_iamthif_message.\n");
+ DBG("heci_hdr->length =%d\n", heci_hdr->length);
+ ret = heci_bh_read_pthi_message(cmpl_list, dev, heci_hdr);
+ if (ret != 0)
+ goto end;
+
+ } else {
+ DBG("call heci_bh_read_client_message.\n");
+ ret = heci_bh_read_client_message(cmpl_list, dev, heci_hdr);
+ if (ret != 0)
+ goto end;
+
+ }
+
+ /* reset the number of slots and header */
+ *slots = count_full_read_slots(dev);
+ dev->rd_msg_hdr = 0;
+
+ if (*slots == -ESLOTS_OVERFLOW) {
+ /* overflow - reset */
+ DBG("reseting due to slots overflow.\n");
+ /* set the event since message has been read */
+ ret = -ERANGE;
+ goto end;
+ }
+end:
+ return ret;
+}
+
+
+/**
+ * heci_bh_read_bus_message - bottom half read routine after ISR to
+ * handle the read bus message cmd processing.
+ *
+ * @dev: Device object for our driver
+ * @heci_hdr: header of bus message
+ */
+static void heci_bh_read_bus_message(struct iamt_heci_device *dev,
+ struct heci_msg_hdr *heci_hdr)
+{
+ struct heci_bus_message *heci_msg;
+ struct hbm_host_version_response *version_res;
+ struct hbm_client_connect_response *connect_res;
+ struct hbm_client_connect_response *disconnect_res;
+ struct hbm_flow_control *flow_control;
+ struct hbm_props_response *props_res;
+ struct hbm_host_enum_response *enum_res;
+ struct hbm_client_disconnect_request *disconnect_req;
+ struct hbm_host_stop_request *h_stop_req;
+ int i;
+ unsigned char *buffer;
+
+ /* read the message to our buffer */
+ buffer = (unsigned char *) dev->rd_msg_buf;
+ BUG_ON(heci_hdr->length >= sizeof(dev->rd_msg_buf));
+ heci_read_slots(dev, buffer, heci_hdr->length);
+ heci_msg = (struct heci_bus_message *) buffer;
+
+ switch (*(__u8 *) heci_msg) {
+ case HOST_START_RES_CMD:
+ version_res = (struct hbm_host_version_response *) heci_msg;
+ if (version_res->host_version_supported) {
+ dev->version.major_version = HBM_MAJOR_VERSION;
+ dev->version.minor_version = HBM_MINOR_VERSION;
+ } else {
+ dev->version = version_res->me_max_version;
+ }
+ dev->recvd_msg = 1;
+ DBG("host start response message received.\n");
+ break;
+
+ case CLIENT_CONNECT_RES_CMD:
+ connect_res =
+ (struct hbm_client_connect_response *) heci_msg;
+ heci_client_connect_response(dev, connect_res);
+ DBG("client connect response message received.\n");
+ wake_up(&dev->wait_recvd_msg);
+ break;
+
+ case CLIENT_DISCONNECT_RES_CMD:
+ disconnect_res =
+ (struct hbm_client_connect_response *) heci_msg;
+ heci_client_disconnect_response(dev, disconnect_res);
+ DBG("client disconnect response message received.\n");
+ wake_up(&dev->wait_recvd_msg);
+ break;
+
+ case HECI_FLOW_CONTROL_CMD:
+ flow_control = (struct hbm_flow_control *) heci_msg;
+ heci_client_flow_control_response(dev, flow_control);
+ DBG("client flow control response message received.\n");
+ break;
+
+ case HOST_CLIENT_PROPERTEIS_RES_CMD:
+ props_res = (struct hbm_props_response *) heci_msg;
+ if (props_res->status != 0) {
+ BUG();
+ break;
+ }
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id ==
+ props_res->address) {
+ dev->me_clients[i].props =
+ props_res->client_properties;
+ break;
+ }
+
+ }
+ dev->recvd_msg = 1;
+ break;
+
+ case HOST_ENUM_RES_CMD:
+ enum_res = (struct hbm_host_enum_response *) heci_msg;
+ memcpy(dev->heci_me_clients, enum_res->valid_addresses, 32);
+ dev->recvd_msg = 1;
+ break;
+
+ case HOST_STOP_RES_CMD:
+ dev->heci_state = HECI_DISABLED;
+ DBG("reseting because of FW stop response.\n");
+ heci_reset(dev, 1);
+ break;
+
+ case CLIENT_DISCONNECT_REQ_CMD:
+ /* search for client */
+ disconnect_req =
+ (struct hbm_client_disconnect_request *) heci_msg;
+ heci_client_disconnect_request(dev, disconnect_req);
+ break;
+
+ case ME_STOP_REQ_CMD:
+ /* prepare stop request */
+ heci_hdr = (struct heci_msg_hdr *) &dev->ext_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_host_stop_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+ h_stop_req =
+ (struct hbm_host_stop_request *) &dev->ext_msg_buf[1];
+ memset(h_stop_req, 0, sizeof(struct hbm_host_stop_request));
+ h_stop_req->cmd.cmd = HOST_STOP_REQ_CMD;
+ h_stop_req->reason = DRIVER_STOP_REQUEST;
+ h_stop_req->reserved[0] = 0;
+ h_stop_req->reserved[1] = 0;
+ dev->extra_write_index = 2;
+ break;
+
+ default:
+ BUG();
+ break;
+
+ }
+}
+
+/**
+ * heci_bh_read_pthi_message - bottom half read routine after ISR to
+ * handle the read pthi message data processing.
+ *
+ * @complete_list: An instance of our list structure
+ * @dev: Device object for our driver
+ * @heci_hdr: header of pthi message
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_bh_read_pthi_message(struct io_heci_list *complete_list,
+ struct iamt_heci_device *dev,
+ struct heci_msg_hdr *heci_hdr)
+{
+ struct heci_file_private *file_ext;
+ struct heci_cb_private *priv_cb;
+ unsigned char *buffer;
+
+ BUG_ON(heci_hdr->me_addr != dev->iamthif_file_ext.me_client_id);
+ BUG_ON(dev->iamthif_state != HECI_IAMTHIF_READING);
+
+ buffer = (unsigned char *) (dev->iamthif_msg_buf +
+ dev->iamthif_msg_buf_index);
+ BUG_ON(sizeof(dev->iamthif_msg_buf) <
+ (dev->iamthif_msg_buf_index + heci_hdr->length));
+
+ heci_read_slots(dev, buffer, heci_hdr->length);
+
+ dev->iamthif_msg_buf_index += heci_hdr->length;
+
+ if (!(heci_hdr->msg_complete))
+ return 0;
+
+ DBG("pthi_message_buffer_index=%d\n", heci_hdr->length);
+ DBG("completed pthi read.\n ");
+ if (!dev->iamthif_current_cb)
+ return -ENODEV;
+
+ priv_cb = dev->iamthif_current_cb;
+ dev->iamthif_current_cb = NULL;
+
+ file_ext = (struct heci_file_private *)priv_cb->file_private;
+ if (!file_ext)
+ return -ENODEV;
+
+ dev->iamthif_stall_timer = 0;
+ priv_cb->information = dev->iamthif_msg_buf_index;
+ priv_cb->read_time = get_seconds();
+ if ((dev->iamthif_ioctl) && (file_ext == &dev->iamthif_file_ext)) {
+ /* found the iamthif cb */
+ DBG("complete the pthi read cb.\n ");
+ if (&dev->iamthif_file_ext) {
+ DBG("add the pthi read cb to complete.\n ");
+ list_add_tail(&priv_cb->cb_list,
+ &complete_list->heci_cb.cb_list);
+ }
+ }
+ return 0;
+}
+
+/**
+ * _heci_bh_state_ok - check if heci header matches file private data
+ *
+ * @file_ext: private data of the file object
+ * @heci_hdr: header of heci client message
+ *
+ * returns !=0 if matches, 0 if no match.
+ */
+static int _heci_bh_state_ok(struct heci_file_private *file_ext,
+ struct heci_msg_hdr *heci_hdr)
+{
+ return ((file_ext->host_client_id == heci_hdr->host_addr)
+ && (file_ext->me_client_id == heci_hdr->me_addr)
+ && (file_ext->state == HECI_FILE_CONNECTED)
+ && (HECI_READ_COMPLETE != file_ext->reading_state));
+}
+
+/**
+ * heci_bh_read_client_message - bottom half read routine after ISR to
+ * handle the read heci client message data processing.
+ *
+ * @complete_list: An instance of our list structure
+ * @dev: Device object for our driver
+ * @heci_hdr: header of heci client message
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_bh_read_client_message(struct io_heci_list *complete_list,
+ struct iamt_heci_device *dev,
+ struct heci_msg_hdr *heci_hdr)
+{
+ struct heci_file_private *file_ext;
+ struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL;
+ unsigned char *buffer = NULL;
+
+ DBG("start client msg\n");
+ if (!((dev->read_list.status == 0) &&
+ !list_empty(&dev->read_list.heci_cb.cb_list)))
+ goto quit;
+
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->read_list.heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+ if ((file_ext != NULL) &&
+ (_heci_bh_state_ok(file_ext, heci_hdr))) {
+ spin_lock(&file_ext->read_io_lock);
+ file_ext->reading_state = HECI_READING;
+ buffer = (unsigned char *)
+ (priv_cb_pos->response_buffer.data +
+ priv_cb_pos->information);
+ BUG_ON(priv_cb_pos->response_buffer.size <
+ heci_hdr->length +
+ priv_cb_pos->information);
+
+ if (priv_cb_pos->response_buffer.size <
+ heci_hdr->length +
+ priv_cb_pos->information) {
+ DBG("message overflow.\n");
+ list_del(&priv_cb_pos->cb_list);
+ spin_unlock(&file_ext->read_io_lock);
+ return -ENOMEM;
+ }
+ if (buffer) {
+ heci_read_slots(dev, buffer,
+ heci_hdr->length);
+ }
+ priv_cb_pos->information += heci_hdr->length;
+ if (heci_hdr->msg_complete) {
+ file_ext->status = 0;
+ list_del(&priv_cb_pos->cb_list);
+ spin_unlock(&file_ext->read_io_lock);
+ DBG("completed read host client = %d,"
+ "ME client = %d, "
+ "data length = %lu\n",
+ file_ext->host_client_id,
+ file_ext->me_client_id,
+ priv_cb_pos->information);
+
+ *(priv_cb_pos->response_buffer.data +
+ priv_cb_pos->information) = '\0';
+ DBG("priv_cb_pos->res_buffer - %s\n",
+ priv_cb_pos->response_buffer.data);
+ list_add_tail(&priv_cb_pos->cb_list,
+ &complete_list->heci_cb.cb_list);
+ } else {
+ spin_unlock(&file_ext->read_io_lock);
+ }
+
+ break;
+ }
+
+ }
+
+quit:
+ DBG("message read\n");
+ if (!buffer) {
+ heci_read_slots(dev, (unsigned char *) dev->rd_msg_buf,
+ heci_hdr->length);
+ DBG("discarding message, header=%08x.\n",
+ *(__u32 *) dev->rd_msg_buf);
+ }
+
+ return 0;
+}
+
+/**
+ * _heci_bh_iamthif_read - prepare to read iamthif data.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _heci_bh_iamthif_read(struct iamt_heci_device *dev, __s32 *slots)
+{
+
+ if (((*slots) * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr)
+ + sizeof(struct hbm_flow_control))) {
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_flow_control) + 3) / 4;
+ if (!heci_send_flow_control(dev, &dev->iamthif_file_ext)) {
+ DBG("iamthif flow control failed\n");
+ } else {
+ DBG("iamthif flow control success\n");
+ dev->iamthif_state = HECI_IAMTHIF_READING;
+ dev->iamthif_flow_control_pending = 0;
+ dev->iamthif_msg_buf_index = 0;
+ dev->iamthif_msg_buf_size = 0;
+ dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER;
+ dev->host_buffer_is_empty = host_buffer_is_empty(dev);
+ }
+ return 0;
+ } else {
+ return -ECOMPLETE_MESSAGE;
+ }
+}
+
+/**
+ * _heci_bh_close - process close related operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _heci_bh_close(struct iamt_heci_device *dev, __s32 *slots,
+ struct heci_cb_private *priv_cb_pos,
+ struct heci_file_private *file_ext,
+ struct io_heci_list *cmpl_list)
+{
+ if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_client_disconnect_request))) {
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_client_disconnect_request) + 3) / 4;
+
+ if (!heci_disconnect(dev, file_ext)) {
+ file_ext->status = 0;
+ priv_cb_pos->information = 0;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &cmpl_list->heci_cb.cb_list);
+ return -ECOMPLETE_MESSAGE;
+ } else {
+ file_ext->state = HECI_FILE_DISCONNECTING;
+ file_ext->status = 0;
+ priv_cb_pos->information = 0;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &dev->ctrl_rd_list.heci_cb.cb_list);
+ file_ext->timer_count = HECI_CONNECT_TIMEOUT;
+ }
+ } else {
+ /* return the cancel routine */
+ return -ECORRUPTED_MESSAGE_HEADER;
+ }
+
+ return 0;
+}
+
+/**
+ * _heci_hb_close - process read related operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _heci_bh_read(struct iamt_heci_device *dev, __s32 *slots,
+ struct heci_cb_private *priv_cb_pos,
+ struct heci_file_private *file_ext,
+ struct io_heci_list *cmpl_list)
+{
+ if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_flow_control))) {
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_flow_control) + 3) / 4;
+ if (!heci_send_flow_control(dev, file_ext)) {
+ file_ext->status = -ENODEV;
+ priv_cb_pos->information = 0;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &cmpl_list->heci_cb.cb_list);
+ return -ENODEV;
+ } else {
+ list_move_tail(&priv_cb_pos->cb_list,
+ &dev->read_list.heci_cb.cb_list);
+ }
+ } else {
+ /* return the cancel routine */
+ list_del(&priv_cb_pos->cb_list);
+ return -ECORRUPTED_MESSAGE_HEADER;
+ }
+
+ return 0;
+}
+
+
+/**
+ * _heci_bh_ioctl - process ioctl related operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _heci_bh_ioctl(struct iamt_heci_device *dev, __s32 *slots,
+ struct heci_cb_private *priv_cb_pos,
+ struct heci_file_private *file_ext,
+ struct io_heci_list *cmpl_list)
+{
+ if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_client_connect_request))) {
+ file_ext->state = HECI_FILE_CONNECTING;
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_client_connect_request) + 3) / 4;
+ if (!heci_connect(dev, file_ext)) {
+ file_ext->status = -ENODEV;
+ priv_cb_pos->information = 0;
+ list_del(&priv_cb_pos->cb_list);
+ return -ENODEV;
+ } else {
+ list_move_tail(&priv_cb_pos->cb_list,
+ &dev->ctrl_rd_list.heci_cb.cb_list);
+ file_ext->timer_count = HECI_CONNECT_TIMEOUT;
+ }
+ } else {
+ /* return the cancel routine */
+ list_del(&priv_cb_pos->cb_list);
+ return -ECORRUPTED_MESSAGE_HEADER;
+ }
+
+ return 0;
+}
+
+/**
+ * _heci_bh_cmpl - process completed and no-iamthif operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _heci_bh_cmpl(struct iamt_heci_device *dev, __s32 *slots,
+ struct heci_cb_private *priv_cb_pos,
+ struct heci_file_private *file_ext,
+ struct io_heci_list *cmpl_list)
+{
+ struct heci_msg_hdr *heci_hdr;
+
+ if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+ (priv_cb_pos->request_buffer.size -
+ priv_cb_pos->information))) {
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = file_ext->host_client_id;
+ heci_hdr->me_addr = file_ext->me_client_id;
+ heci_hdr->length = ((priv_cb_pos->request_buffer.size) -
+ (priv_cb_pos->information));
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+ DBG("priv_cb_pos->request_buffer.size =%d"
+ "heci_hdr->msg_complete= %d\n",
+ priv_cb_pos->request_buffer.size,
+ heci_hdr->msg_complete);
+ DBG("priv_cb_pos->information =%lu\n",
+ priv_cb_pos->information);
+ DBG("heci_hdr->length =%d\n",
+ heci_hdr->length);
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ heci_hdr->length + 3) / 4;
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *)
+ (priv_cb_pos->request_buffer.data +
+ priv_cb_pos->information),
+ heci_hdr->length)) {
+ file_ext->status = -ENODEV;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &cmpl_list->heci_cb.cb_list);
+ return -ENODEV;
+ } else {
+ flow_ctrl_reduce(dev, file_ext);
+ file_ext->status = 0;
+ priv_cb_pos->information += heci_hdr->length;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &dev->write_waiting_list.heci_cb.cb_list);
+ }
+ } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
+ /* buffer is still empty */
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = file_ext->host_client_id;
+ heci_hdr->me_addr = file_ext->me_client_id;
+ heci_hdr->length =
+ (*slots * sizeof(__u32)) - sizeof(struct heci_msg_hdr);
+ heci_hdr->msg_complete = 0;
+ heci_hdr->reserved = 0;
+
+ (*slots) -= (sizeof(struct heci_msg_hdr) +
+ heci_hdr->length + 3) / 4;
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *)
+ (priv_cb_pos->request_buffer.data +
+ priv_cb_pos->information),
+ heci_hdr->length)) {
+ file_ext->status = -ENODEV;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &cmpl_list->heci_cb.cb_list);
+ return -ENODEV;
+ } else {
+ priv_cb_pos->information += heci_hdr->length;
+ DBG("priv_cb_pos->request_buffer.size =%d"
+ " heci_hdr->msg_complete= %d\n",
+ priv_cb_pos->request_buffer.size,
+ heci_hdr->msg_complete);
+ DBG("priv_cb_pos->information =%lu\n",
+ priv_cb_pos->information);
+ DBG("heci_hdr->length =%d\n", heci_hdr->length);
+ }
+ return -ECOMPLETE_MESSAGE;
+ } else {
+ return -ECORRUPTED_MESSAGE_HEADER;
+ }
+
+ return 0;
+}
+
+/**
+ * _heci_bh_cmpl_iamthif - process completed iamthif operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _heci_bh_cmpl_iamthif(struct iamt_heci_device *dev, __s32 *slots,
+ struct heci_cb_private *priv_cb_pos,
+ struct heci_file_private *file_ext,
+ struct io_heci_list *cmpl_list)
+{
+ struct heci_msg_hdr *heci_hdr;
+
+ if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+ dev->iamthif_msg_buf_size -
+ dev->iamthif_msg_buf_index)) {
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = file_ext->host_client_id;
+ heci_hdr->me_addr = file_ext->me_client_id;
+ heci_hdr->length = dev->iamthif_msg_buf_size -
+ dev->iamthif_msg_buf_index;
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ heci_hdr->length + 3) / 4;
+
+ if (!heci_write_message(dev, heci_hdr,
+ (dev->iamthif_msg_buf +
+ dev->iamthif_msg_buf_index),
+ heci_hdr->length)) {
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+ file_ext->status = -ENODEV;
+ list_del(&priv_cb_pos->cb_list);
+ return -ENODEV;
+ } else {
+ flow_ctrl_reduce(dev, file_ext);
+ dev->iamthif_msg_buf_index += heci_hdr->length;
+ priv_cb_pos->information = dev->iamthif_msg_buf_index;
+ file_ext->status = 0;
+ dev->iamthif_state = HECI_IAMTHIF_FLOW_CONTROL;
+ dev->iamthif_flow_control_pending = 1;
+ /* save iamthif cb sent to pthi client */
+ dev->iamthif_current_cb = priv_cb_pos;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &dev->write_waiting_list.heci_cb.cb_list);
+
+ }
+ } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
+ /* buffer is still empty */
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = file_ext->host_client_id;
+ heci_hdr->me_addr = file_ext->me_client_id;
+ heci_hdr->length =
+ (*slots * sizeof(__u32)) - sizeof(struct heci_msg_hdr);
+ heci_hdr->msg_complete = 0;
+ heci_hdr->reserved = 0;
+
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ heci_hdr->length + 3) / 4;
+
+ if (!heci_write_message(dev, heci_hdr,
+ (dev->iamthif_msg_buf +
+ dev->iamthif_msg_buf_index),
+ heci_hdr->length)) {
+ file_ext->status = -ENODEV;
+ list_del(&priv_cb_pos->cb_list);
+ } else {
+ dev->iamthif_msg_buf_index += heci_hdr->length;
+ }
+ return -ECOMPLETE_MESSAGE;
+ } else {
+ return -ECORRUPTED_MESSAGE_HEADER;
+ }
+
+ return 0;
+}
+
+/**
+ * heci_bh_write_handler - bottom half write routine after
+ * ISR to handle the write processing.
+ *
+ * @cmpl_list: An instance of our list structure
+ * @dev: Device object for our driver
+ * @slots: slots to write.
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_bh_write_handler(struct io_heci_list *cmpl_list,
+ struct iamt_heci_device *dev,
+ __s32 *slots)
+{
+
+ struct heci_file_private *file_ext;
+ struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL;
+ struct io_heci_list *list;
+ int ret;
+
+ if (!host_buffer_is_empty(dev)) {
+ DBG("host buffer is not empty.\n");
+ return 0;
+ }
+ dev->write_hang = -1;
+ *slots = count_empty_write_slots(dev);
+ /* complete all waiting for write CB */
+ DBG("complete all waiting for write cb.\n");
+
+ list = &dev->write_waiting_list;
+ if ((list->status == 0)
+ && !list_empty(&list->heci_cb.cb_list)) {
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &list->heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+ if (file_ext != NULL) {
+ file_ext->status = 0;
+ list_del(&priv_cb_pos->cb_list);
+ if ((HECI_WRITING == file_ext->writing_state) &&
+ (priv_cb_pos->major_file_operations ==
+ HECI_WRITING) &&
+ (file_ext != &dev->iamthif_file_ext)) {
+ DBG("HECI WRITE COMPLETE\n");
+ file_ext->writing_state =
+ HECI_WRITE_COMPLETE;
+ list_add_tail(&priv_cb_pos->cb_list,
+ &cmpl_list->heci_cb.cb_list);
+ }
+ if (file_ext == &dev->iamthif_file_ext) {
+ DBG("check iamthif flow control.\n");
+ if (dev->iamthif_flow_control_pending) {
+ ret = _heci_bh_iamthif_read(dev,
+ slots);
+ if (ret != 0)
+ return ret;
+ }
+ }
+ }
+
+ }
+ }
+
+ if ((dev->stop) && (!dev->wd_pending)) {
+ dev->wd_stoped = 1;
+ wake_up_interruptible(&dev->wait_stop_wd);
+ return 0;
+ }
+
+ if (dev->extra_write_index != 0) {
+ DBG("extra_write_index =%d.\n", dev->extra_write_index);
+ heci_write_message(dev,
+ (struct heci_msg_hdr *) &dev->ext_msg_buf[0],
+ (unsigned char *) &dev->ext_msg_buf[1],
+ (dev->extra_write_index - 1) * sizeof(__u32));
+ *slots -= dev->extra_write_index;
+ dev->extra_write_index = 0;
+ }
+ if (dev->heci_state == HECI_ENABLED) {
+ if ((dev->wd_pending)
+ && flow_ctrl_creds(dev, &dev->wd_file_ext)) {
+ if (!heci_send_wd(dev))
+ DBG("wd send failed.\n");
+ else
+ flow_ctrl_reduce(dev, &dev->wd_file_ext);
+
+ dev->wd_pending = 0;
+
+ if (dev->wd_timeout != 0) {
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ HECI_START_WD_DATA_SIZE + 3) / 4;
+ dev->wd_due_counter = 2;
+ } else {
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ HECI_WD_PARAMS_SIZE + 3) / 4;
+ dev->wd_due_counter = 0;
+ }
+
+ }
+ }
+ if (dev->stop)
+ return ~ENODEV;
+
+ /* complete control write list CB */
+ if (dev->ctrl_wr_list.status == 0) {
+ /* complete control write list CB */
+ DBG("complete control write list cb.\n");
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->ctrl_wr_list.heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+ if (file_ext == NULL) {
+ list_del(&priv_cb_pos->cb_list);
+ return -ENODEV;
+ }
+ switch (priv_cb_pos->major_file_operations) {
+ case HECI_CLOSE:
+ /* send disconnect message */
+ ret = _heci_bh_close(dev, slots,
+ priv_cb_pos,
+ file_ext, cmpl_list);
+ if (ret != 0)
+ return ret;
+
+ break;
+ case HECI_READ:
+ /* send flow control message */
+ ret = _heci_bh_read(dev, slots,
+ priv_cb_pos,
+ file_ext, cmpl_list);
+ if (ret != 0)
+ return ret;
+
+ break;
+ case HECI_IOCTL:
+ /* connect message */
+ if (!other_client_is_connecting(dev, file_ext))
+ continue;
+ ret = _heci_bh_ioctl(dev, slots,
+ priv_cb_pos,
+ file_ext, cmpl_list);
+ if (ret != 0)
+ return ret;
+
+ break;
+
+ default:
+ BUG();
+ }
+
+ }
+ }
+ /* complete write list CB */
+ if ((dev->write_list.status == 0)
+ && !list_empty(&dev->write_list.heci_cb.cb_list)) {
+ DBG("complete write list cb.\n");
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->write_list.heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+
+ if (file_ext != NULL) {
+ if (file_ext != &dev->iamthif_file_ext) {
+ if (!flow_ctrl_creds(dev, file_ext)) {
+ DBG("No flow control"
+ " credentials for client"
+ " %d, not sending.\n",
+ file_ext->host_client_id);
+ continue;
+ }
+ ret = _heci_bh_cmpl(dev, slots,
+ priv_cb_pos,
+ file_ext,
+ cmpl_list);
+ if (ret != 0)
+ return ret;
+
+ } else if (file_ext == &dev->iamthif_file_ext) {
+ /* IAMTHIF IOCTL */
+ DBG("complete pthi write cb.\n");
+ if (!flow_ctrl_creds(dev, file_ext)) {
+ DBG("No flow control"
+ " credentials for pthi"
+ " client %d.\n",
+ file_ext->host_client_id);
+ continue;
+ }
+ ret = _heci_bh_cmpl_iamthif(dev, slots,
+ priv_cb_pos,
+ file_ext,
+ cmpl_list);
+ if (ret != 0)
+ return ret;
+
+ }
+ }
+
+ }
+ }
+ return 0;
+}
+
+
+/**
+ * is_treat_specially_client - check if the message belong
+ * to the file private data.
+ *
+ * @file_ext: private data of the file object
+ * @rs: connect response bus message
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int is_treat_specially_client(struct heci_file_private *file_ext,
+ struct hbm_client_connect_response *rs)
+{
+ int ret = 0;
+
+ if ((file_ext->host_client_id == rs->host_addr) &&
+ (file_ext->me_client_id == rs->me_addr)) {
+ if (rs->status == 0) {
+ DBG("client connect status = 0x%08x.\n", rs->status);
+ file_ext->state = HECI_FILE_CONNECTED;
+ file_ext->status = 0;
+ } else {
+ DBG("client connect status = 0x%08x.\n", rs->status);
+ file_ext->state = HECI_FILE_DISCONNECTED;
+ file_ext->status = -ENODEV;
+ }
+ ret = 1;
+ }
+ DBG("client state = %d.\n", file_ext->state);
+ return ret;
+}
+
+/**
+ * heci_client_connect_response - connect response bh routine
+ *
+ * @dev: Device object for our driver
+ * @rs: connect response bus message
+ */
+static void heci_client_connect_response(struct iamt_heci_device *dev,
+ struct hbm_client_connect_response *rs)
+{
+
+ struct heci_file_private *file_ext;
+ struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL;
+
+ /* if WD or iamthif client treat specially */
+
+ if ((is_treat_specially_client(&(dev->wd_file_ext), rs)) ||
+ (is_treat_specially_client(&(dev->iamthif_file_ext), rs)))
+ return;
+
+ if (dev->ctrl_rd_list.status == 0
+ && !list_empty(&dev->ctrl_rd_list.heci_cb.cb_list)) {
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->ctrl_rd_list.heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+ if (file_ext == NULL) {
+ list_del(&priv_cb_pos->cb_list);
+ return;
+ }
+ if (HECI_IOCTL == priv_cb_pos->major_file_operations) {
+ if (is_treat_specially_client(file_ext, rs)) {
+ list_del(&priv_cb_pos->cb_list);
+ file_ext->status = 0;
+ file_ext->timer_count = 0;
+ break;
+ }
+ }
+ }
+ }
+}
+
+/**
+ * heci_client_disconnect_response - disconnect response bh routine
+ *
+ * @dev: Device object for our driver
+ * @rs: disconnect response bus message
+ */
+static void heci_client_disconnect_response(struct iamt_heci_device *dev,
+ struct hbm_client_connect_response *rs)
+{
+ struct heci_file_private *file_ext;
+ struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL;
+
+ if (dev->ctrl_rd_list.status == 0
+ && !list_empty(&dev->ctrl_rd_list.heci_cb.cb_list)) {
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->ctrl_rd_list.heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+
+ if (file_ext == NULL) {
+ list_del(&priv_cb_pos->cb_list);
+ return;
+ }
+
+ DBG("list_for_each_entry_safe in ctrl_rd_list.\n");
+ if ((file_ext->host_client_id == rs->host_addr) &&
+ (file_ext->me_client_id == rs->me_addr)) {
+
+ list_del(&priv_cb_pos->cb_list);
+ if (rs->status == 0) {
+ file_ext->state =
+ HECI_FILE_DISCONNECTED;
+ }
+
+ file_ext->status = 0;
+ file_ext->timer_count = 0;
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * same_flow_addr - tell they have same address.
+ *
+ * @file: private data of the file object.
+ * @flow: flow control.
+ *
+ * returns !=0, same; 0,not.
+ */
+static int same_flow_addr(struct heci_file_private *file,
+ struct hbm_flow_control *flow)
+{
+ return ((file->host_client_id == flow->host_addr)
+ && (file->me_client_id == flow->me_addr));
+}
+
+/**
+ * add_single_flow_creds - add single buffer credentials.
+ *
+ * @file: private data ot the file object.
+ * @flow: flow control.
+ */
+static void add_single_flow_creds(struct iamt_heci_device *dev,
+ struct hbm_flow_control *flow)
+{
+ struct heci_me_client *client;
+ int i;
+
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ client = &dev->me_clients[i];
+ if ((client != NULL) &&
+ (flow->me_addr == client->client_id)) {
+ if (client->props.single_recv_buf != 0) {
+ client->flow_ctrl_creds++;
+ DBG("recv flow ctrl msg ME %d (single).\n",
+ flow->me_addr);
+ DBG("flow control credentials=%d.\n",
+ client->flow_ctrl_creds);
+ } else {
+ BUG(); /* error in flow control */
+ }
+ }
+ }
+}
+
+/**
+ * heci_client_flow_control_response - flow control response bh routine
+ *
+ * @dev: Device object for our driver
+ * @flow_control: flow control response bus message
+ */
+static void heci_client_flow_control_response(struct iamt_heci_device *dev,
+ struct hbm_flow_control *flow_control)
+{
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+
+ if (flow_control->host_addr == 0) {
+ /* single receive buffer */
+ add_single_flow_creds(dev, flow_control);
+ } else {
+ /* normal connection */
+ list_for_each_entry_safe(file_pos, file_next,
+ &dev->file_list, link) {
+ DBG("list_for_each_entry_safe in file_list\n");
+
+ DBG("file_ext of host client %d ME client %d.\n",
+ file_pos->host_client_id,
+ file_pos->me_client_id);
+ DBG("flow ctrl msg for host %d ME %d.\n",
+ flow_control->host_addr,
+ flow_control->me_addr);
+ if (same_flow_addr(file_pos, flow_control)) {
+ DBG("recv ctrl msg for host %d ME %d.\n",
+ flow_control->host_addr,
+ flow_control->me_addr);
+ file_pos->flow_ctrl_creds++;
+ DBG("flow control credentials=%d.\n",
+ file_pos->flow_ctrl_creds);
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * same_disconn_addr - tell they have same address
+ *
+ * @file: private data of the file object.
+ * @disconn: disconnection request.
+ *
+ * returns !=0, same; 0,not.
+ */
+static int same_disconn_addr(struct heci_file_private *file,
+ struct hbm_client_disconnect_request *disconn)
+{
+ return ((file->host_client_id == disconn->host_addr)
+ && (file->me_client_id == disconn->me_addr));
+}
+
+/**
+ * heci_client_disconnect_request - disconnect request bh routine
+ *
+ * @dev: Device object for our driver.
+ * @disconnect_req: disconnect request bus message.
+ */
+static void heci_client_disconnect_request(struct iamt_heci_device *dev,
+ struct hbm_client_disconnect_request *disconnect_req)
+{
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_client_connect_response *disconnect_res;
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+
+ list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) {
+ if (same_disconn_addr(file_pos, disconnect_req)) {
+ DBG("disconnect request host client %d ME client %d.\n",
+ disconnect_req->host_addr,
+ disconnect_req->me_addr);
+ file_pos->state = HECI_FILE_DISCONNECTED;
+ file_pos->timer_count = 0;
+ if (file_pos == &dev->wd_file_ext) {
+ dev->wd_due_counter = 0;
+ dev->wd_pending = 0;
+ } else if (file_pos == &dev->iamthif_file_ext)
+ dev->iamthif_timer = 0;
+
+ /* prepare disconnect response */
+ heci_hdr =
+ (struct heci_msg_hdr *) &dev->ext_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length =
+ sizeof(struct hbm_client_connect_response);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ disconnect_res =
+ (struct hbm_client_connect_response *)
+ &dev->ext_msg_buf[1];
+ disconnect_res->host_addr = file_pos->host_client_id;
+ disconnect_res->me_addr = file_pos->me_client_id;
+ *(__u8 *) (&disconnect_res->cmd) =
+ CLIENT_DISCONNECT_RES_CMD;
+ disconnect_res->status = 0;
+ dev->extra_write_index = 2;
+ break;
+ }
+ }
+}
+
+/**
+ * heci_timer - timer function.
+ *
+ * @data: pointer to the device structure
+ *
+ * NOTE: This function is called by timer interrupt work
+ */
+void heci_wd_timer(unsigned long data)
+{
+ struct iamt_heci_device *dev = (struct iamt_heci_device *) data;
+
+ DBG("send watchdog.\n");
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ mod_timer(&dev->wd_timer, round_jiffies(jiffies + 2 * HZ));
+ spin_unlock_bh(&dev->device_lock);
+ return;
+ }
+ if (dev->wd_file_ext.state != HECI_FILE_CONNECTED) {
+ mod_timer(&dev->wd_timer, round_jiffies(jiffies + 2 * HZ));
+ spin_unlock_bh(&dev->device_lock);
+ return;
+ }
+ /* Watchdog */
+ if ((dev->wd_due_counter != 0) && (dev->wd_bypass == 0)) {
+ if (--dev->wd_due_counter == 0) {
+ if (dev->host_buffer_is_empty &&
+ flow_ctrl_creds(dev, &dev->wd_file_ext)) {
+ dev->host_buffer_is_empty = 0;
+ if (!heci_send_wd(dev)) {
+ DBG("wd send failed.\n");
+ } else {
+ flow_ctrl_reduce(dev,
+ &dev->wd_file_ext);
+ }
+
+ if (dev->wd_timeout != 0)
+ dev->wd_due_counter = 2;
+ else
+ dev->wd_due_counter = 0;
+
+ } else
+ dev->wd_pending = 1;
+
+ }
+ }
+ if (dev->iamthif_stall_timer != 0) {
+ if (--dev->iamthif_stall_timer == 0) {
+ DBG("reseting because of hang to PTHI.\n");
+ heci_reset(dev, 1);
+ dev->iamthif_msg_buf_size = 0;
+ dev->iamthif_msg_buf_index = 0;
+ dev->iamthif_canceled = 0;
+ dev->iamthif_ioctl = 1;
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+ dev->iamthif_timer = 0;
+ spin_unlock_bh(&dev->device_lock);
+
+ if (dev->iamthif_current_cb)
+ heci_free_cb_private(dev->iamthif_current_cb);
+
+ spin_lock_bh(&dev->device_lock);
+ dev->iamthif_file_object = NULL;
+ dev->iamthif_current_cb = NULL;
+ run_next_iamthif_cmd(dev);
+ }
+ }
+ mod_timer(&dev->wd_timer, round_jiffies(jiffies + 2 * HZ));
+ spin_unlock_bh(&dev->device_lock);
+}
diff --git a/drivers/staging/heci/io_heci.c b/drivers/staging/heci/io_heci.c
new file mode 100644
index 00000000000..f7544a7bbbe
--- /dev/null
+++ b/drivers/staging/heci/io_heci.c
@@ -0,0 +1,847 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/aio.h>
+#include <linux/pci.h>
+#include <linux/reboot.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/list.h>
+#include <linux/unistd.h>
+#include <linux/delay.h>
+
+#include "heci_data_structures.h"
+#include "heci.h"
+#include "heci_interface.h"
+#include "heci_version.h"
+
+
+/**
+ * heci_ioctl_get_version - the get driver version IOCTL function
+ *
+ * @dev: Device object for our driver
+ * @if_num: minor number
+ * @*u_msg: pointer to user data struct in user space
+ * @k_msg: data in kernel on the stack
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_ioctl_get_version(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data __user *u_msg,
+ struct heci_message_data k_msg,
+ struct heci_file_private *file_ext)
+{
+ int rets = 0;
+ struct heci_driver_version *version;
+ struct heci_message_data res_msg;
+
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev)
+ || (!file_ext))
+ return -ENODEV;
+
+ if (k_msg.size < (sizeof(struct heci_driver_version) - 2)) {
+ DBG("user buffer less than heci_driver_version.\n");
+ return -EMSGSIZE;
+ }
+
+ res_msg.data = kmalloc(sizeof(struct heci_driver_version), GFP_KERNEL);
+ if (!res_msg.data) {
+ DBG("failed allocation response buffer size = %d.\n",
+ (int) sizeof(struct heci_driver_version));
+ return -ENOMEM;
+ }
+
+ version = (struct heci_driver_version *) res_msg.data;
+ version->major = MAJOR_VERSION;
+ version->minor = MINOR_VERSION;
+ version->hotfix = QUICK_FIX_NUMBER;
+ version->build = VER_BUILD;
+ res_msg.size = sizeof(struct heci_driver_version);
+ if (k_msg.size < sizeof(struct heci_driver_version))
+ res_msg.size -= 2;
+
+ rets = file_ext->status;
+ /* now copy the data to user space */
+ if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ if (put_user(res_msg.size, &u_msg->size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+end:
+ kfree(res_msg.data);
+ return rets;
+}
+
+/**
+ * heci_ioctl_connect_client - the connect to fw client IOCTL function
+ *
+ * @dev: Device object for our driver
+ * @if_num: minor number
+ * @*u_msg: pointer to user data struct in user space
+ * @k_msg: data in kernel on the stack
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data __user *u_msg,
+ struct heci_message_data k_msg,
+ struct file *file)
+{
+ int rets = 0;
+ struct heci_message_data req_msg, res_msg;
+ struct heci_cb_private *priv_cb = NULL;
+ struct heci_client *client;
+ struct heci_file_private *file_ext;
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+ long timeout = 15; /*15 second */
+ __u8 i;
+ int err = 0;
+
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file))
+ return -ENODEV;
+
+ file_ext = file->private_data;
+ if (!file_ext)
+ return -ENODEV;
+
+ if (k_msg.size != sizeof(struct guid)) {
+ DBG("user buffer size is not equal to size of struct "
+ "guid(16).\n");
+ return -EMSGSIZE;
+ }
+
+ if (!k_msg.data)
+ return -EIO;
+
+ req_msg.data = kmalloc(sizeof(struct guid), GFP_KERNEL);
+ res_msg.data = kmalloc(sizeof(struct heci_client), GFP_KERNEL);
+
+ if (!res_msg.data) {
+ DBG("failed allocation response buffer size = %d.\n",
+ (int) sizeof(struct heci_client));
+ kfree(req_msg.data);
+ return -ENOMEM;
+ }
+ if (!req_msg.data) {
+ DBG("failed allocation request buffer size = %d.\n",
+ (int) sizeof(struct guid));
+ kfree(res_msg.data);
+ return -ENOMEM;
+ }
+ req_msg.size = sizeof(struct guid);
+ res_msg.size = sizeof(struct heci_client);
+
+ /* copy the message to kernel space -
+ * use a pointer already copied into kernel space
+ */
+ if (copy_from_user(req_msg.data, k_msg.data, k_msg.size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ /* buffered ioctl cb */
+ priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
+ if (!priv_cb) {
+ rets = -ENOMEM;
+ goto end;
+ }
+ INIT_LIST_HEAD(&priv_cb->cb_list);
+ priv_cb->response_buffer.data = res_msg.data;
+ priv_cb->response_buffer.size = res_msg.size;
+ priv_cb->request_buffer.data = req_msg.data;
+ priv_cb->request_buffer.size = req_msg.size;
+ priv_cb->major_file_operations = HECI_IOCTL;
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ rets = -ENODEV;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+ if ((file_ext->state != HECI_FILE_INITIALIZING) &&
+ (file_ext->state != HECI_FILE_DISCONNECTED)) {
+ rets = -EBUSY;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+
+ /* find ME client we're trying to connect to */
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (memcmp((struct guid *)req_msg.data,
+ &dev->me_clients[i].props.protocol_name,
+ sizeof(struct guid)) == 0) {
+ if (dev->me_clients[i].props.fixed_address == 0) {
+ file_ext->me_client_id =
+ dev->me_clients[i].client_id;
+ file_ext->state = HECI_FILE_CONNECTING;
+ }
+ break;
+ }
+ }
+ /* if we're connecting to PTHI client so we will use the exist
+ * connection
+ */
+ if (memcmp((struct guid *)req_msg.data, &heci_pthi_guid,
+ sizeof(struct guid)) == 0) {
+ if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTED) {
+ rets = -ENODEV;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+ dev->heci_host_clients[file_ext->host_client_id / 8] &=
+ ~(1 << (file_ext->host_client_id % 8));
+ list_for_each_entry_safe(file_pos,
+ file_next, &dev->file_list, link) {
+ if (heci_fe_same_id(file_ext, file_pos)) {
+ DBG("remove file private data node host"
+ " client = %d, ME client = %d.\n",
+ file_pos->host_client_id,
+ file_pos->me_client_id);
+ list_del(&file_pos->link);
+ }
+
+ }
+ DBG("free file private data memory.\n");
+ kfree(file_ext);
+ file_ext = NULL;
+ file->private_data = &dev->iamthif_file_ext;
+ client = (struct heci_client *) res_msg.data;
+ client->max_msg_length =
+ dev->me_clients[i].props.max_msg_length;
+ client->protocol_version =
+ dev->me_clients[i].props.protocol_version;
+ rets = dev->iamthif_file_ext.status;
+ spin_unlock_bh(&dev->device_lock);
+
+ /* now copy the data to user space */
+ if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ if (put_user(res_msg.size, &u_msg->size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ goto end;
+ }
+ spin_lock(&file_ext->file_lock);
+ if (file_ext->state != HECI_FILE_CONNECTING) {
+ rets = -ENODEV;
+ spin_unlock(&file_ext->file_lock);
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+ spin_unlock(&file_ext->file_lock);
+ /* prepare the output buffer */
+ client = (struct heci_client *) res_msg.data;
+ client->max_msg_length = dev->me_clients[i].props.max_msg_length;
+ client->protocol_version = dev->me_clients[i].props.protocol_version;
+ if (dev->host_buffer_is_empty
+ && !other_client_is_connecting(dev, file_ext)) {
+ dev->host_buffer_is_empty = 0;
+ if (!heci_connect(dev, file_ext)) {
+ rets = -ENODEV;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ } else {
+ file_ext->timer_count = HECI_CONNECT_TIMEOUT;
+ priv_cb->file_private = file_ext;
+ list_add_tail(&priv_cb->cb_list,
+ &dev->ctrl_rd_list.heci_cb.
+ cb_list);
+ }
+
+
+ } else {
+ priv_cb->file_private = file_ext;
+ DBG("add connect cb to control write list.\n");
+ list_add_tail(&priv_cb->cb_list,
+ &dev->ctrl_wr_list.heci_cb.cb_list);
+ }
+ spin_unlock_bh(&dev->device_lock);
+ err = wait_event_timeout(dev->wait_recvd_msg,
+ (HECI_FILE_CONNECTED == file_ext->state
+ || HECI_FILE_DISCONNECTED == file_ext->state),
+ timeout * HZ);
+
+ if (HECI_FILE_CONNECTED == file_ext->state) {
+ DBG("successfully connected to FW client.\n");
+ rets = file_ext->status;
+ /* now copy the data to user space */
+ if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ if (put_user(res_msg.size, &u_msg->size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ goto end;
+ } else {
+ DBG("failed to connect to FW client.file_ext->state = %d.\n",
+ file_ext->state);
+ if (!err) {
+ DBG("wait_event_interruptible_timeout failed on client"
+ " connect message fw response message.\n");
+ }
+ rets = -EFAULT;
+ goto remove_list;
+ }
+
+remove_list:
+ if (priv_cb) {
+ spin_lock_bh(&dev->device_lock);
+ heci_flush_list(&dev->ctrl_rd_list, file_ext);
+ heci_flush_list(&dev->ctrl_wr_list, file_ext);
+ spin_unlock_bh(&dev->device_lock);
+ }
+end:
+ DBG("free connect cb memory.");
+ kfree(req_msg.data);
+ kfree(res_msg.data);
+ kfree(priv_cb);
+ return rets;
+}
+
+/**
+ * heci_ioctl_wd - the wd IOCTL function
+ *
+ * @dev: Device object for our driver
+ * @if_num: minor number
+ * @k_msg: data in kernel on the stack
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_ioctl_wd(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data k_msg,
+ struct heci_file_private *file_ext)
+{
+ int rets = 0;
+ struct heci_message_data req_msg; /*in kernel on the stack */
+
+ if (if_num != HECI_MINOR_NUMBER)
+ return -ENODEV;
+
+ spin_lock(&file_ext->file_lock);
+ if (k_msg.size != HECI_WATCHDOG_DATA_SIZE) {
+ DBG("user buffer has invalid size.\n");
+ spin_unlock(&file_ext->file_lock);
+ return -EMSGSIZE;
+ }
+ spin_unlock(&file_ext->file_lock);
+
+ req_msg.data = kmalloc(HECI_WATCHDOG_DATA_SIZE, GFP_KERNEL);
+ if (!req_msg.data) {
+ DBG("failed allocation request buffer size = %d.\n",
+ HECI_WATCHDOG_DATA_SIZE);
+ return -ENOMEM;
+ }
+ req_msg.size = HECI_WATCHDOG_DATA_SIZE;
+
+ /* copy the message to kernel space - use a pointer already
+ * copied into kernel space
+ */
+ if (copy_from_user(req_msg.data, k_msg.data, req_msg.size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ rets = -ENODEV;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+
+ if (dev->wd_file_ext.state != HECI_FILE_CONNECTED) {
+ rets = -ENODEV;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+ if (!dev->asf_mode) {
+ rets = -EIO;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+
+ memcpy(&dev->wd_data[HECI_WD_PARAMS_SIZE], req_msg.data,
+ HECI_WATCHDOG_DATA_SIZE);
+
+ dev->wd_timeout = (req_msg.data[1] << 8) + req_msg.data[0];
+ dev->wd_pending = 0;
+ dev->wd_due_counter = 1; /* next timer */
+ if (dev->wd_timeout == 0) {
+ memcpy(dev->wd_data, heci_stop_wd_params,
+ HECI_WD_PARAMS_SIZE);
+ } else {
+ memcpy(dev->wd_data, heci_start_wd_params,
+ HECI_WD_PARAMS_SIZE);
+ mod_timer(&dev->wd_timer, jiffies);
+ }
+ spin_unlock_bh(&dev->device_lock);
+end:
+ kfree(req_msg.data);
+ return rets;
+}
+
+
+/**
+ * heci_ioctl_bypass_wd - the bypass_wd IOCTL function
+ *
+ * @dev: Device object for our driver
+ * @if_num: minor number
+ * @k_msg: data in kernel on the stack
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_ioctl_bypass_wd(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data k_msg,
+ struct heci_file_private *file_ext)
+{
+ __u8 flag = 0;
+ int rets = 0;
+
+ if (if_num != HECI_MINOR_NUMBER)
+ return -ENODEV;
+
+ spin_lock(&file_ext->file_lock);
+ if (k_msg.size < 1) {
+ DBG("user buffer less than HECI_WATCHDOG_DATA_SIZE.\n");
+ spin_unlock(&file_ext->file_lock);
+ return -EMSGSIZE;
+ }
+ spin_unlock(&file_ext->file_lock);
+ if (copy_from_user(&flag, k_msg.data, 1)) {
+ rets = -EFAULT;
+ goto end;
+ }
+
+ spin_lock_bh(&dev->device_lock);
+ flag = flag ? (1) : (0);
+ dev->wd_bypass = flag;
+ spin_unlock_bh(&dev->device_lock);
+end:
+ return rets;
+}
+
+/**
+ * find_pthi_read_list_entry - finds a PTHIlist entry for current file
+ *
+ * @dev: Device object for our driver
+ * @file: pointer to file object
+ *
+ * returns returned a list entry on success, NULL on failure.
+ */
+struct heci_cb_private *find_pthi_read_list_entry(
+ struct iamt_heci_device *dev,
+ struct file *file)
+{
+ struct heci_file_private *file_ext_temp;
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb_next = NULL;
+
+ if ((dev->pthi_read_complete_list.status == 0) &&
+ !list_empty(&dev->pthi_read_complete_list.heci_cb.cb_list)) {
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->pthi_read_complete_list.heci_cb.cb_list, cb_list) {
+ file_ext_temp = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+ if ((file_ext_temp != NULL) &&
+ (file_ext_temp == &dev->iamthif_file_ext) &&
+ (priv_cb_pos->file_object == file))
+ return priv_cb_pos;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * pthi_read - read data from pthi client
+ *
+ * @dev: Device object for our driver
+ * @if_num: minor number
+ * @file: pointer to file object
+ * @*ubuf: pointer to user data in user space
+ * @length: data length to read
+ * @offset: data read offset
+ *
+ * returns
+ * returned data length on success,
+ * zero if no data to read,
+ * negative on failure.
+ */
+int pthi_read(struct iamt_heci_device *dev, int if_num, struct file *file,
+ char __user *ubuf, size_t length, loff_t *offset)
+{
+ int rets = 0;
+ struct heci_cb_private *priv_cb = NULL;
+ struct heci_file_private *file_ext = file->private_data;
+ __u8 i;
+ unsigned long currtime = get_seconds();
+
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev))
+ return -ENODEV;
+
+ if ((file_ext == NULL) || (file_ext != &dev->iamthif_file_ext))
+ return -ENODEV;
+
+ spin_lock_bh(&dev->device_lock);
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id ==
+ dev->iamthif_file_ext.me_client_id)
+ break;
+ }
+ BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
+ if ((i == dev->num_heci_me_clients)
+ || (dev->me_clients[i].client_id !=
+ dev->iamthif_file_ext.me_client_id)) {
+ DBG("PTHI client not found.\n");
+ spin_unlock_bh(&dev->device_lock);
+ return -ENODEV;
+ }
+ priv_cb = find_pthi_read_list_entry(dev, file);
+ if (!priv_cb) {
+ spin_unlock_bh(&dev->device_lock);
+ return 0; /* No more data to read */
+ } else {
+ if (priv_cb &&
+ (currtime - priv_cb->read_time > IAMTHIF_READ_TIMER)) {
+ /* 15 sec for the message has expired */
+ list_del(&priv_cb->cb_list);
+ spin_unlock_bh(&dev->device_lock);
+ rets = -ETIMEDOUT;
+ goto free;
+ }
+ /* if the whole message will fit remove it from the list */
+ if ((priv_cb->information >= *offset) &&
+ (length >= (priv_cb->information - *offset)))
+ list_del(&priv_cb->cb_list);
+ else if ((priv_cb->information > 0) &&
+ (priv_cb->information <= *offset)) {
+ /* end of the message has been reached */
+ list_del(&priv_cb->cb_list);
+ rets = 0;
+ spin_unlock_bh(&dev->device_lock);
+ goto free;
+ }
+ /* else means that not full buffer will be read and do not
+ * remove message from deletion list
+ */
+ }
+ DBG("pthi priv_cb->response_buffer size - %d\n",
+ priv_cb->response_buffer.size);
+ DBG("pthi priv_cb->information - %lu\n",
+ priv_cb->information);
+ spin_unlock_bh(&dev->device_lock);
+
+ /* length is being turncated to PAGE_SIZE, however,
+ * the information may be longer */
+ length = length < (priv_cb->information - *offset) ?
+ length : (priv_cb->information - *offset);
+
+ if (copy_to_user(ubuf,
+ priv_cb->response_buffer.data + *offset,
+ length))
+ rets = -EFAULT;
+ else {
+ rets = length;
+ if ((*offset + length) < priv_cb->information) {
+ *offset += length;
+ goto out;
+ }
+ }
+free:
+ DBG("free pthi cb memory.\n");
+ *offset = 0;
+ heci_free_cb_private(priv_cb);
+out:
+ return rets;
+}
+
+/**
+ * heci_start_read - the start read client message function.
+ *
+ * @dev: Device object for our driver
+ * @if_num: minor number
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_start_read(struct iamt_heci_device *dev, int if_num,
+ struct heci_file_private *file_ext)
+{
+ int rets = 0;
+ __u8 i;
+ struct heci_cb_private *priv_cb = NULL;
+
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext)) {
+ DBG("received wrong function input param.\n");
+ return -ENODEV;
+ }
+ if (file_ext->state != HECI_FILE_CONNECTED)
+ return -ENODEV;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ return -ENODEV;
+ }
+ spin_unlock_bh(&dev->device_lock);
+ DBG("check if read is pending.\n");
+ if ((file_ext->read_pending) || (file_ext->read_cb != NULL)) {
+ DBG("read is pending.\n");
+ return -EBUSY;
+ }
+ priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
+ if (!priv_cb)
+ return -ENOMEM;
+
+ DBG("allocation call back success\n"
+ "host client = %d, ME client = %d\n",
+ file_ext->host_client_id, file_ext->me_client_id);
+ spin_lock_bh(&dev->device_lock);
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id == file_ext->me_client_id)
+ break;
+
+ }
+
+ BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
+ if (i == dev->num_heci_me_clients) {
+ rets = -ENODEV;
+ goto unlock;
+ }
+
+ priv_cb->response_buffer.size = dev->me_clients[i].props.max_msg_length;
+ spin_unlock_bh(&dev->device_lock);
+ priv_cb->response_buffer.data =
+ kmalloc(priv_cb->response_buffer.size, GFP_KERNEL);
+ if (!priv_cb->response_buffer.data) {
+ rets = -ENOMEM;
+ goto fail;
+ }
+ DBG("allocation call back data success.\n");
+ priv_cb->major_file_operations = HECI_READ;
+ /* make sure information is zero before we start */
+ priv_cb->information = 0;
+ priv_cb->file_private = (void *) file_ext;
+ file_ext->read_cb = priv_cb;
+ spin_lock_bh(&dev->device_lock);
+ if (dev->host_buffer_is_empty) {
+ dev->host_buffer_is_empty = 0;
+ if (!heci_send_flow_control(dev, file_ext)) {
+ rets = -ENODEV;
+ goto unlock;
+ } else {
+ list_add_tail(&priv_cb->cb_list,
+ &dev->read_list.heci_cb.cb_list);
+ }
+ } else {
+ list_add_tail(&priv_cb->cb_list,
+ &dev->ctrl_wr_list.heci_cb.cb_list);
+ }
+ spin_unlock_bh(&dev->device_lock);
+ return rets;
+unlock:
+ spin_unlock_bh(&dev->device_lock);
+fail:
+ heci_free_cb_private(priv_cb);
+ return rets;
+}
+
+/**
+ * pthi_write - write iamthif data to pthi client
+ *
+ * @dev: Device object for our driver
+ * @priv_cb: heci call back struct
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int pthi_write(struct iamt_heci_device *dev,
+ struct heci_cb_private *priv_cb)
+{
+ int rets = 0;
+ struct heci_msg_hdr heci_hdr;
+
+ if ((!dev) || (!priv_cb))
+ return -ENODEV;
+
+ DBG("write data to pthi client.\n");
+
+ dev->iamthif_state = HECI_IAMTHIF_WRITING;
+ dev->iamthif_current_cb = priv_cb;
+ dev->iamthif_file_object = priv_cb->file_object;
+ dev->iamthif_canceled = 0;
+ dev->iamthif_ioctl = 1;
+ dev->iamthif_msg_buf_size = priv_cb->request_buffer.size;
+ memcpy(dev->iamthif_msg_buf, priv_cb->request_buffer.data,
+ priv_cb->request_buffer.size);
+
+ if (flow_ctrl_creds(dev, &dev->iamthif_file_ext) &&
+ dev->host_buffer_is_empty) {
+ dev->host_buffer_is_empty = 0;
+ if (priv_cb->request_buffer.size >
+ (((dev->host_hw_state & H_CBD) >> 24) *
+ sizeof(__u32)) - sizeof(struct heci_msg_hdr)) {
+ heci_hdr.length =
+ (((dev->host_hw_state & H_CBD) >> 24) *
+ sizeof(__u32)) - sizeof(struct heci_msg_hdr);
+ heci_hdr.msg_complete = 0;
+ } else {
+ heci_hdr.length = priv_cb->request_buffer.size;
+ heci_hdr.msg_complete = 1;
+ }
+
+ heci_hdr.host_addr = dev->iamthif_file_ext.host_client_id;
+ heci_hdr.me_addr = dev->iamthif_file_ext.me_client_id;
+ heci_hdr.reserved = 0;
+ dev->iamthif_msg_buf_index += heci_hdr.length;
+ if (!heci_write_message(dev, &heci_hdr,
+ (unsigned char *)(dev->iamthif_msg_buf),
+ heci_hdr.length))
+ return -ENODEV;
+
+ if (heci_hdr.msg_complete) {
+ flow_ctrl_reduce(dev, &dev->iamthif_file_ext);
+ dev->iamthif_flow_control_pending = 1;
+ dev->iamthif_state = HECI_IAMTHIF_FLOW_CONTROL;
+ DBG("add pthi cb to write waiting list\n");
+ dev->iamthif_current_cb = priv_cb;
+ dev->iamthif_file_object = priv_cb->file_object;
+ list_add_tail(&priv_cb->cb_list,
+ &dev->write_waiting_list.heci_cb.cb_list);
+ } else {
+ DBG("message does not complete, "
+ "so add pthi cb to write list.\n");
+ list_add_tail(&priv_cb->cb_list,
+ &dev->write_list.heci_cb.cb_list);
+ }
+ } else {
+ if (!(dev->host_buffer_is_empty))
+ DBG("host buffer is not empty");
+
+ DBG("No flow control credentials, "
+ "so add iamthif cb to write list.\n");
+ list_add_tail(&priv_cb->cb_list,
+ &dev->write_list.heci_cb.cb_list);
+ }
+ return rets;
+}
+
+/**
+ * iamthif_ioctl_send_msg - send cmd data to pthi client
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+void run_next_iamthif_cmd(struct iamt_heci_device *dev)
+{
+ struct heci_file_private *file_ext_tmp;
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb_next = NULL;
+ int status = 0;
+
+ if (!dev)
+ return;
+
+ dev->iamthif_msg_buf_size = 0;
+ dev->iamthif_msg_buf_index = 0;
+ dev->iamthif_canceled = 0;
+ dev->iamthif_ioctl = 1;
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+ dev->iamthif_timer = 0;
+ dev->iamthif_file_object = NULL;
+
+ if (dev->pthi_cmd_list.status == 0 &&
+ !list_empty(&dev->pthi_cmd_list.heci_cb.cb_list)) {
+ DBG("complete pthi cmd_list cb.\n");
+
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->pthi_cmd_list.heci_cb.cb_list, cb_list) {
+ list_del(&priv_cb_pos->cb_list);
+ file_ext_tmp = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+
+ if ((file_ext_tmp != NULL) &&
+ (file_ext_tmp == &dev->iamthif_file_ext)) {
+ status = pthi_write(dev, priv_cb_pos);
+ if (status != 0) {
+ DBG("pthi write failed status = %d\n",
+ status);
+ return;
+ }
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * heci_free_cb_private - free heci_cb_private related memory
+ *
+ * @priv_cb: heci callback struct
+ */
+void heci_free_cb_private(struct heci_cb_private *priv_cb)
+{
+ if (priv_cb == NULL)
+ return;
+
+ kfree(priv_cb->request_buffer.data);
+ kfree(priv_cb->response_buffer.data);
+ kfree(priv_cb);
+}
+
diff --git a/drivers/staging/line6/Kconfig b/drivers/staging/line6/Kconfig
new file mode 100644
index 00000000000..7852d4a960c
--- /dev/null
+++ b/drivers/staging/line6/Kconfig
@@ -0,0 +1,21 @@
+config LINE6_USB
+ tristate "Line6 USB support"
+ depends on USB && SND
+ select SND_RAWMIDI
+ help
+ This is a driver for the guitar amp, cab, and effects modeller
+ PODxt Pro by Line6 (and similar devices), supporting the
+ following features:
+ * Reading/writing individual parameters
+ * Reading/writing complete channel, effects setup, and amp
+ setup data
+ * Channel switching
+ * Virtual MIDI interface
+ * Tuner access
+ * Playback/capture/mixer device for any ALSA-compatible PCM
+ audio application
+ * Signal routing (record clean/processed guitar signal,
+ re-amping)
+
+ Preliminary support for the Variax Workbench is included.
+
diff --git a/drivers/staging/line6/Makefile b/drivers/staging/line6/Makefile
new file mode 100644
index 00000000000..a1c93edc6b1
--- /dev/null
+++ b/drivers/staging/line6/Makefile
@@ -0,0 +1,15 @@
+obj-$(CONFIG_LINE6_USB) += line6usb.o
+
+line6usb-objs := \
+ audio.o \
+ capture.o \
+ control.o \
+ driver.o \
+ dumprequest.o \
+ midi.o \
+ midibuf.o \
+ pcm.o \
+ playback.o \
+ pod.o \
+ toneport.o \
+ variax.o
diff --git a/drivers/staging/line6/audio.c b/drivers/staging/line6/audio.c
new file mode 100644
index 00000000000..3aa946899ce
--- /dev/null
+++ b/drivers/staging/line6/audio.c
@@ -0,0 +1,72 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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 "driver.h"
+#include "audio.h"
+
+#include <sound/core.h>
+#include <sound/initval.h>
+
+
+static int line6_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *line6_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+
+
+/*
+ Initialize the Line6 USB audio system.
+*/
+int line6_init_audio(struct usb_line6 *line6)
+{
+ static int dev;
+ struct snd_card *card;
+
+ card = snd_card_new(line6_index[dev], line6_id[dev], THIS_MODULE, 0);
+
+ if (card == NULL)
+ return -ENOMEM;
+
+ line6->card = card;
+
+ strcpy(card->driver, DRIVER_NAME);
+ strcpy(card->shortname, "Line6-USB");
+ sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name,
+ dev_name(line6->ifcdev)); /* 80 chars - see asound.h */
+ return 0;
+}
+
+/*
+ Register the Line6 USB audio system.
+*/
+int line6_register_audio(struct usb_line6 *line6)
+{
+ int err;
+
+ err = snd_card_register(line6->card);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+/*
+ Cleanup the Line6 USB audio system.
+*/
+void line6_cleanup_audio(struct usb_line6 *line6)
+{
+ struct snd_card *card = line6->card;
+
+ if (card == NULL)
+ return;
+
+ snd_card_disconnect(card);
+ snd_card_free(card);
+ line6->card = NULL;
+}
diff --git a/drivers/staging/line6/audio.h b/drivers/staging/line6/audio.h
new file mode 100644
index 00000000000..cc0245adbcd
--- /dev/null
+++ b/drivers/staging/line6/audio.h
@@ -0,0 +1,24 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+#ifndef AUDIO_H
+#define AUDIO_H
+
+
+#include "driver.h"
+
+
+extern void line6_cleanup_audio(struct usb_line6 *);
+extern int line6_init_audio(struct usb_line6 *);
+extern int line6_register_audio(struct usb_line6 *);
+
+
+#endif
diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c
new file mode 100644
index 00000000000..8393e25a10b
--- /dev/null
+++ b/drivers/staging/line6/capture.c
@@ -0,0 +1,372 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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 "driver.h"
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include "audio.h"
+#include "pcm.h"
+#include "pod.h"
+#include "capture.h"
+
+
+/*
+ Find a free URB and submit it.
+*/
+static int submit_audio_in_urb(struct snd_pcm_substream *substream)
+{
+ int index;
+ unsigned long flags;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ int i, urb_size;
+ struct urb *urb_in;
+
+ spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
+ index = find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS);
+
+ if (index < 0 || index >= LINE6_ISO_BUFFERS) {
+ spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
+ dev_err(s2m(substream), "no free URB found\n");
+ return -EINVAL;
+ }
+
+ urb_in = line6pcm->urb_audio_in[index];
+ urb_size = 0;
+
+ for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+ struct usb_iso_packet_descriptor *fin = &urb_in->iso_frame_desc[i];
+ fin->offset = urb_size;
+ fin->length = line6pcm->max_packet_size;
+ urb_size += line6pcm->max_packet_size;
+ }
+
+ urb_in->transfer_buffer = line6pcm->buffer_in + index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
+ urb_in->transfer_buffer_length = urb_size;
+ urb_in->context = substream;
+
+ if (usb_submit_urb(urb_in, GFP_ATOMIC) == 0)
+ set_bit(index, &line6pcm->active_urb_in);
+ else
+ dev_err(s2m(substream), "URB in #%d submission failed\n", index);
+
+ spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
+ return 0;
+}
+
+/*
+ Submit all currently available capture URBs.
+*/
+static int submit_audio_in_all_urbs(struct snd_pcm_substream *substream)
+{
+ int ret, i;
+
+ for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+ ret = submit_audio_in_urb(substream);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ Unlink all currently active capture URBs.
+*/
+static void unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+{
+ unsigned int i;
+
+ for (i = LINE6_ISO_BUFFERS; i--;) {
+ if (test_bit(i, &line6pcm->active_urb_in)) {
+ if (!test_and_set_bit(i, &line6pcm->unlink_urb_in)) {
+ struct urb *u = line6pcm->urb_audio_in[i];
+ usb_unlink_urb(u);
+ }
+ }
+ }
+}
+
+/*
+ Wait until unlinking of all currently active capture URBs has been
+ finished.
+*/
+static void wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+{
+ int timeout = HZ;
+ unsigned int i;
+ int alive;
+
+ do {
+ alive = 0;
+ for (i = LINE6_ISO_BUFFERS; i--;) {
+ if (test_bit(i, &line6pcm->active_urb_in))
+ alive++;
+ }
+ if (!alive)
+ break;
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1);
+ } while (--timeout > 0);
+ if (alive)
+ snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
+
+ line6pcm->active_urb_in = 0;
+ line6pcm->unlink_urb_in = 0;
+}
+
+/*
+ Unlink all currently active capture URBs, and wait for finishing.
+*/
+void unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+{
+ unlink_audio_in_urbs(line6pcm);
+ wait_clear_audio_in_urbs(line6pcm);
+}
+
+/*
+ Callback for completed capture URB.
+*/
+static void audio_in_callback(struct urb *urb)
+{
+ int i, index, length = 0, shutdown = 0;
+ int frames;
+ unsigned long flags;
+
+ struct snd_pcm_substream *substream = (struct snd_pcm_substream *)urb->context;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ /* find index of URB */
+ for (index = 0; index < LINE6_ISO_BUFFERS; ++index)
+ if (urb == line6pcm->urb_audio_in[index])
+ break;
+
+#if DO_DUMP_PCM_RECEIVE
+ for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+ struct usb_iso_packet_descriptor *fout = &urb->iso_frame_desc[i];
+ line6_write_hexdump(line6pcm->line6, 'C', urb->transfer_buffer + fout->offset, fout->length);
+ }
+#endif
+
+ spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
+
+ for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+ char *fbuf;
+ int fsize;
+ struct usb_iso_packet_descriptor *fin = &urb->iso_frame_desc[i];
+
+ if (fin->status == -18) {
+ shutdown = 1;
+ break;
+ }
+
+ fbuf = urb->transfer_buffer + fin->offset;
+ fsize = fin->actual_length;
+ length += fsize;
+
+ if (fsize > 0) {
+ frames = fsize / bytes_per_frame;
+
+ if (line6pcm->pos_in_done + frames > runtime->buffer_size) {
+ /*
+ The transferred area goes over buffer boundary,
+ copy two separate chunks.
+ */
+ int len;
+ len = runtime->buffer_size - line6pcm->pos_in_done;
+
+ if (len > 0) {
+ memcpy(runtime->dma_area + line6pcm->pos_in_done * bytes_per_frame, fbuf, len * bytes_per_frame);
+ memcpy(runtime->dma_area, fbuf + len * bytes_per_frame, (frames - len) * bytes_per_frame);
+ } else
+ dev_err(s2m(substream), "driver bug: len = %d\n", len); /* this is somewhat paranoid */
+ } else {
+ /* copy single chunk */
+ memcpy(runtime->dma_area + line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize * bytes_per_frame);
+ }
+
+ if ((line6pcm->pos_in_done += frames) >= runtime->buffer_size)
+ line6pcm->pos_in_done -= runtime->buffer_size;
+ }
+ }
+
+ clear_bit(index, &line6pcm->active_urb_in);
+
+ if (test_bit(index, &line6pcm->unlink_urb_in))
+ shutdown = 1;
+
+ spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
+
+ if (!shutdown) {
+ submit_audio_in_urb(substream);
+
+ if ((line6pcm->bytes_in += length) >= line6pcm->period_in) {
+ line6pcm->bytes_in -= line6pcm->period_in;
+ snd_pcm_period_elapsed(substream);
+ }
+ }
+}
+
+/* open capture callback */
+static int snd_line6_capture_open(struct snd_pcm_substream *substream)
+{
+ int err;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+ err = snd_pcm_hw_constraint_ratdens(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ (&line6pcm->properties->snd_line6_rates));
+ if (err < 0)
+ return err;
+
+ runtime->hw = line6pcm->properties->snd_line6_capture_hw;
+ return 0;
+}
+
+/* close capture callback */
+static int snd_line6_capture_close(struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
+/* hw_params capture callback */
+static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ int ret;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+ /* -- Florian Demski [FD] */
+ /* don't ask me why, but this fixes the bug on my machine */
+ if (line6pcm == NULL) {
+ if (substream->pcm == NULL)
+ return -ENOMEM;
+ if (substream->pcm->private_data == NULL)
+ return -ENOMEM;
+ substream->private_data = substream->pcm->private_data;
+ line6pcm = snd_pcm_substream_chip(substream);
+ }
+ /* -- [FD] end */
+
+ ret = snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+ if (ret < 0)
+ return ret;
+
+ line6pcm->period_in = params_period_bytes(hw_params);
+ line6pcm->buffer_in = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL);
+
+ if (!line6pcm->buffer_in) {
+ dev_err(s2m(substream), "cannot malloc buffer_in\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/* hw_free capture callback */
+static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ unlink_wait_clear_audio_in_urbs(line6pcm);
+
+ kfree(line6pcm->buffer_in);
+ line6pcm->buffer_in = NULL;
+
+ return snd_pcm_lib_free_pages(substream);
+}
+
+/* trigger callback */
+int snd_line6_capture_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ int err;
+ line6pcm->count_in = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ if (!test_and_set_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags)) {
+ err = submit_audio_in_all_urbs(substream);
+
+ if (err < 0) {
+ clear_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags);
+ return err;
+ }
+ }
+
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ if (test_and_clear_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags))
+ unlink_audio_in_urbs(line6pcm);
+
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* capture pointer callback */
+static snd_pcm_uframes_t
+snd_line6_capture_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ return line6pcm->pos_in_done;
+}
+
+/* capture operators */
+struct snd_pcm_ops snd_line6_capture_ops = {
+ .open = snd_line6_capture_open,
+ .close = snd_line6_capture_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_line6_capture_hw_params,
+ .hw_free = snd_line6_capture_hw_free,
+ .prepare = snd_line6_prepare,
+ .trigger = snd_line6_trigger,
+ .pointer = snd_line6_capture_pointer,
+};
+
+int create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+{
+ int i;
+
+ /* create audio URBs and fill in constant values: */
+ for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+ struct urb *urb;
+
+ /* URB for audio in: */
+ urb = line6pcm->urb_audio_in[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
+
+ if (urb == NULL) {
+ dev_err(line6pcm->line6->ifcdev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+ urb->dev = line6pcm->line6->usbdev;
+ urb->pipe = usb_rcvisocpipe(line6pcm->line6->usbdev, line6pcm->ep_audio_read & USB_ENDPOINT_NUMBER_MASK);
+ urb->transfer_flags = URB_ISO_ASAP;
+ urb->start_frame = -1;
+ urb->number_of_packets = LINE6_ISO_PACKETS;
+ urb->interval = LINE6_ISO_INTERVAL;
+ urb->error_count = 0;
+ urb->complete = audio_in_callback;
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/line6/capture.h b/drivers/staging/line6/capture.h
new file mode 100644
index 00000000000..5c44464d29d
--- /dev/null
+++ b/drivers/staging/line6/capture.h
@@ -0,0 +1,32 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+#ifndef CAPTURE_H
+#define CAPTURE_H
+
+
+#include "driver.h"
+
+#include <sound/pcm.h>
+
+#include "pcm.h"
+
+
+extern struct snd_pcm_ops snd_line6_capture_ops;
+
+
+extern int create_audio_in_urbs(struct snd_line6_pcm *line6pcm);
+extern int snd_line6_capture_trigger(struct snd_pcm_substream *substream,
+ int cmd);
+extern void unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm);
+
+
+#endif
diff --git a/drivers/staging/line6/config.h b/drivers/staging/line6/config.h
new file mode 100644
index 00000000000..adad130c5dc
--- /dev/null
+++ b/drivers/staging/line6/config.h
@@ -0,0 +1,48 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+
+#ifdef CONFIG_USB_DEBUG
+#define DEBUG 1
+#endif
+
+
+/**
+ Development tools.
+*/
+#define DO_DEBUG_MESSAGES 0
+#define DO_DUMP_URB_SEND DO_DEBUG_MESSAGES
+#define DO_DUMP_URB_RECEIVE DO_DEBUG_MESSAGES
+#define DO_DUMP_PCM_SEND 0
+#define DO_DUMP_PCM_RECEIVE 0
+#define DO_DUMP_MIDI_SEND DO_DEBUG_MESSAGES
+#define DO_DUMP_MIDI_RECEIVE DO_DEBUG_MESSAGES
+#define DO_DUMP_ANY (DO_DUMP_URB_SEND || DO_DUMP_URB_RECEIVE || \
+ DO_DUMP_PCM_SEND || DO_DUMP_PCM_RECEIVE || \
+ DO_DUMP_MIDI_SEND || DO_DUMP_MIDI_RECEIVE)
+#define CREATE_RAW_FILE 0
+
+#if DO_DEBUG_MESSAGES
+#define CHECKPOINT printk(KERN_INFO "line6usb: %s (%s:%d)\n", \
+ __func__, __FILE__, __LINE__)
+#endif
+
+#if DO_DEBUG_MESSAGES
+#define DEBUG_MESSAGES(x) (x)
+#else
+#define DEBUG_MESSAGES(x)
+#endif
+
+
+#endif
diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c
new file mode 100644
index 00000000000..23ad08e17f8
--- /dev/null
+++ b/drivers/staging/line6/control.c
@@ -0,0 +1,840 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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 "driver.h"
+
+#include <linux/usb.h>
+
+#include "control.h"
+#include "pod.h"
+#include "usbdefs.h"
+#include "variax.h"
+
+#define DEVICE_ATTR2(_name1, _name2, _mode, _show, _store) \
+struct device_attribute dev_attr_##_name1 = __ATTR(_name2, _mode, _show, _store)
+
+#define LINE6_PARAM_R(PREFIX, prefix, type, param) \
+static ssize_t prefix ## _get_ ## param(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ return prefix ## _get_param_ ## type(dev, buf, PREFIX ## _ ## param); \
+}
+
+#define LINE6_PARAM_RW(PREFIX, prefix, type, param) \
+LINE6_PARAM_R(PREFIX, prefix, type, param); \
+static ssize_t prefix ## _set_ ## param(struct device *dev, \
+ struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+ return prefix ## _set_param_ ## type(dev, buf, count, PREFIX ## _ ## param); \
+}
+
+#define POD_PARAM_R(type, param) LINE6_PARAM_R(POD, pod, type, param)
+#define POD_PARAM_RW(type, param) LINE6_PARAM_RW(POD, pod, type, param)
+#define VARIAX_PARAM_R(type, param) LINE6_PARAM_R(VARIAX, variax, type, param)
+#define VARIAX_PARAM_RW(type, param) LINE6_PARAM_RW(VARIAX, variax, type, param)
+
+
+static ssize_t pod_get_param_int(struct device *dev, char *buf, int param)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int retval = line6_wait_dump(&pod->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+ return sprintf(buf, "%d\n", pod->prog_data.control[param]);
+}
+
+static ssize_t pod_set_param_int(struct device *dev, const char *buf, size_t count, int param)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int value = simple_strtoul(buf, NULL, 10);
+ pod_transmit_parameter(pod, param, value);
+ return count;
+}
+
+static ssize_t variax_get_param_int(struct device *dev, char *buf, int param)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_variax *variax = usb_get_intfdata(interface);
+ int retval = line6_wait_dump(&variax->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+ return sprintf(buf, "%d\n", variax->model_data.control[param]);
+}
+
+static ssize_t variax_get_param_float(struct device *dev, char *buf, int param)
+{
+ /*
+ We do our own floating point handling here since floats in the
+ kernel are problematic for at least two reasons: - many distros
+ are still shipped with binary kernels optimized for the ancient
+ 80386 without FPU
+ - there isn't a printf("%f")
+ (see http://www.kernelthread.com/publications/faq/335.html)
+ */
+
+ static const int BIAS = 0x7f;
+ static const int OFFSET = 0xf;
+ static const int PRECISION = 1000;
+
+ int len = 0;
+ unsigned part_int, part_frac;
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_variax *variax = usb_get_intfdata(interface);
+ const unsigned char *p = variax->model_data.control + param;
+ int retval = line6_wait_dump(&variax->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+
+ if ((p[0] == 0) && (p[1] == 0) && (p[2] == 0))
+ part_int = part_frac = 0;
+ else {
+ int exponent = (((p[0] & 0x7f) << 1) | (p[1] >> 7)) - BIAS;
+ unsigned mantissa = (p[1] << 8) | p[2] | 0x8000;
+ exponent -= OFFSET;
+
+ if (exponent >= 0) {
+ part_int = mantissa << exponent;
+ part_frac = 0;
+ } else {
+ part_int = mantissa >> -exponent;
+ part_frac = (mantissa << (32 + exponent)) & 0xffffffff;
+ }
+
+ part_frac = (part_frac / ((1UL << 31) / (PRECISION / 2 * 10)) + 5) / 10;
+ }
+
+ len += sprintf(buf + len, "%s%d.%03d\n", ((p[0] & 0x80) ? "-" : ""), part_int, part_frac);
+ return len;
+}
+
+POD_PARAM_RW(int, tweak);
+POD_PARAM_RW(int, wah_position);
+POD_PARAM_RW(int, compression_gain);
+POD_PARAM_RW(int, vol_pedal_position);
+POD_PARAM_RW(int, compression_threshold);
+POD_PARAM_RW(int, pan);
+POD_PARAM_RW(int, amp_model_setup);
+POD_PARAM_RW(int, amp_model);
+POD_PARAM_RW(int, drive);
+POD_PARAM_RW(int, bass);
+POD_PARAM_RW(int, mid);
+POD_PARAM_RW(int, lowmid);
+POD_PARAM_RW(int, treble);
+POD_PARAM_RW(int, highmid);
+POD_PARAM_RW(int, chan_vol);
+POD_PARAM_RW(int, reverb_mix);
+POD_PARAM_RW(int, effect_setup);
+POD_PARAM_RW(int, band_1_frequency);
+POD_PARAM_RW(int, presence);
+POD_PARAM_RW(int, treble__bass);
+POD_PARAM_RW(int, noise_gate_enable);
+POD_PARAM_RW(int, gate_threshold);
+POD_PARAM_RW(int, gate_decay_time);
+POD_PARAM_RW(int, stomp_enable);
+POD_PARAM_RW(int, comp_enable);
+POD_PARAM_RW(int, stomp_time);
+POD_PARAM_RW(int, delay_enable);
+POD_PARAM_RW(int, mod_param_1);
+POD_PARAM_RW(int, delay_param_1);
+POD_PARAM_RW(int, delay_param_1_note_value);
+POD_PARAM_RW(int, band_2_frequency__bass);
+POD_PARAM_RW(int, delay_param_2);
+POD_PARAM_RW(int, delay_volume_mix);
+POD_PARAM_RW(int, delay_param_3);
+POD_PARAM_RW(int, reverb_enable);
+POD_PARAM_RW(int, reverb_type);
+POD_PARAM_RW(int, reverb_decay);
+POD_PARAM_RW(int, reverb_tone);
+POD_PARAM_RW(int, reverb_pre_delay);
+POD_PARAM_RW(int, reverb_pre_post);
+POD_PARAM_RW(int, band_2_frequency);
+POD_PARAM_RW(int, band_3_frequency__bass);
+POD_PARAM_RW(int, wah_enable);
+POD_PARAM_RW(int, modulation_lo_cut);
+POD_PARAM_RW(int, delay_reverb_lo_cut);
+POD_PARAM_RW(int, volume_pedal_minimum);
+POD_PARAM_RW(int, eq_pre_post);
+POD_PARAM_RW(int, volume_pre_post);
+POD_PARAM_RW(int, di_model);
+POD_PARAM_RW(int, di_delay);
+POD_PARAM_RW(int, mod_enable);
+POD_PARAM_RW(int, mod_param_1_note_value);
+POD_PARAM_RW(int, mod_param_2);
+POD_PARAM_RW(int, mod_param_3);
+POD_PARAM_RW(int, mod_param_4);
+POD_PARAM_RW(int, mod_param_5);
+POD_PARAM_RW(int, mod_volume_mix);
+POD_PARAM_RW(int, mod_pre_post);
+POD_PARAM_RW(int, modulation_model);
+POD_PARAM_RW(int, band_3_frequency);
+POD_PARAM_RW(int, band_4_frequency__bass);
+POD_PARAM_RW(int, mod_param_1_double_precision);
+POD_PARAM_RW(int, delay_param_1_double_precision);
+POD_PARAM_RW(int, eq_enable);
+POD_PARAM_RW(int, tap);
+POD_PARAM_RW(int, volume_tweak_pedal_assign);
+POD_PARAM_RW(int, band_5_frequency);
+POD_PARAM_RW(int, tuner);
+POD_PARAM_RW(int, mic_selection);
+POD_PARAM_RW(int, cabinet_model);
+POD_PARAM_RW(int, stomp_model);
+POD_PARAM_RW(int, roomlevel);
+POD_PARAM_RW(int, band_4_frequency);
+POD_PARAM_RW(int, band_6_frequency);
+POD_PARAM_RW(int, stomp_param_1_note_value);
+POD_PARAM_RW(int, stomp_param_2);
+POD_PARAM_RW(int, stomp_param_3);
+POD_PARAM_RW(int, stomp_param_4);
+POD_PARAM_RW(int, stomp_param_5);
+POD_PARAM_RW(int, stomp_param_6);
+POD_PARAM_RW(int, amp_switch_select);
+POD_PARAM_RW(int, delay_param_4);
+POD_PARAM_RW(int, delay_param_5);
+POD_PARAM_RW(int, delay_pre_post);
+POD_PARAM_RW(int, delay_model);
+POD_PARAM_RW(int, delay_verb_model);
+POD_PARAM_RW(int, tempo_msb);
+POD_PARAM_RW(int, tempo_lsb);
+POD_PARAM_RW(int, wah_model);
+POD_PARAM_RW(int, bypass_volume);
+POD_PARAM_RW(int, fx_loop_on_off);
+POD_PARAM_RW(int, tweak_param_select);
+POD_PARAM_RW(int, amp1_engage);
+POD_PARAM_RW(int, band_1_gain);
+POD_PARAM_RW(int, band_2_gain__bass);
+POD_PARAM_RW(int, band_2_gain);
+POD_PARAM_RW(int, band_3_gain__bass);
+POD_PARAM_RW(int, band_3_gain);
+POD_PARAM_RW(int, band_4_gain__bass);
+POD_PARAM_RW(int, band_5_gain__bass);
+POD_PARAM_RW(int, band_4_gain);
+POD_PARAM_RW(int, band_6_gain__bass);
+VARIAX_PARAM_R(int, body);
+VARIAX_PARAM_R(int, pickup1_enable);
+VARIAX_PARAM_R(int, pickup1_type);
+VARIAX_PARAM_R(float, pickup1_position);
+VARIAX_PARAM_R(float, pickup1_angle);
+VARIAX_PARAM_R(float, pickup1_level);
+VARIAX_PARAM_R(int, pickup2_enable);
+VARIAX_PARAM_R(int, pickup2_type);
+VARIAX_PARAM_R(float, pickup2_position);
+VARIAX_PARAM_R(float, pickup2_angle);
+VARIAX_PARAM_R(float, pickup2_level);
+VARIAX_PARAM_R(int, pickup_phase);
+VARIAX_PARAM_R(float, capacitance);
+VARIAX_PARAM_R(float, tone_resistance);
+VARIAX_PARAM_R(float, volume_resistance);
+VARIAX_PARAM_R(int, taper);
+VARIAX_PARAM_R(float, tone_dump);
+VARIAX_PARAM_R(int, save_tone);
+VARIAX_PARAM_R(float, volume_dump);
+VARIAX_PARAM_R(int, tuning_enable);
+VARIAX_PARAM_R(int, tuning6);
+VARIAX_PARAM_R(int, tuning5);
+VARIAX_PARAM_R(int, tuning4);
+VARIAX_PARAM_R(int, tuning3);
+VARIAX_PARAM_R(int, tuning2);
+VARIAX_PARAM_R(int, tuning1);
+VARIAX_PARAM_R(float, detune6);
+VARIAX_PARAM_R(float, detune5);
+VARIAX_PARAM_R(float, detune4);
+VARIAX_PARAM_R(float, detune3);
+VARIAX_PARAM_R(float, detune2);
+VARIAX_PARAM_R(float, detune1);
+VARIAX_PARAM_R(float, mix6);
+VARIAX_PARAM_R(float, mix5);
+VARIAX_PARAM_R(float, mix4);
+VARIAX_PARAM_R(float, mix3);
+VARIAX_PARAM_R(float, mix2);
+VARIAX_PARAM_R(float, mix1);
+VARIAX_PARAM_R(int, pickup_wiring);
+
+static DEVICE_ATTR(tweak, S_IWUGO | S_IRUGO, pod_get_tweak, pod_set_tweak);
+static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position, pod_set_wah_position);
+static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO, pod_get_compression_gain, pod_set_compression_gain);
+static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO, pod_get_vol_pedal_position, pod_set_vol_pedal_position);
+static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO, pod_get_compression_threshold, pod_set_compression_threshold);
+static DEVICE_ATTR(pan, S_IWUGO | S_IRUGO, pod_get_pan, pod_set_pan);
+static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup, pod_set_amp_model_setup);
+static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model, pod_set_amp_model);
+static DEVICE_ATTR(drive, S_IWUGO | S_IRUGO, pod_get_drive, pod_set_drive);
+static DEVICE_ATTR(bass, S_IWUGO | S_IRUGO, pod_get_bass, pod_set_bass);
+static DEVICE_ATTR(mid, S_IWUGO | S_IRUGO, pod_get_mid, pod_set_mid);
+static DEVICE_ATTR(lowmid, S_IWUGO | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
+static DEVICE_ATTR(treble, S_IWUGO | S_IRUGO, pod_get_treble, pod_set_treble);
+static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid, pod_set_highmid);
+static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol, pod_set_chan_vol);
+static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix, pod_set_reverb_mix);
+static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup, pod_set_effect_setup);
+static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO, pod_get_band_1_frequency, pod_set_band_1_frequency);
+static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence, pod_set_presence);
+static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO, pod_get_treble__bass, pod_set_treble__bass);
+static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO, pod_get_noise_gate_enable, pod_set_noise_gate_enable);
+static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold, pod_set_gate_threshold);
+static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time, pod_set_gate_decay_time);
+static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable, pod_set_stomp_enable);
+static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable, pod_set_comp_enable);
+static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time, pod_set_stomp_time);
+static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable, pod_set_delay_enable);
+static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1, pod_set_mod_param_1);
+static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1, pod_set_delay_param_1);
+static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_delay_param_1_note_value, pod_set_delay_param_1_note_value);
+static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency__bass, pod_set_band_2_frequency__bass);
+static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2, pod_set_delay_param_2);
+static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO, pod_get_delay_volume_mix, pod_set_delay_volume_mix);
+static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3, pod_set_delay_param_3);
+static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable, pod_set_reverb_enable);
+static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type, pod_set_reverb_type);
+static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay, pod_set_reverb_decay);
+static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone, pod_set_reverb_tone);
+static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO, pod_get_reverb_pre_delay, pod_set_reverb_pre_delay);
+static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post, pod_set_reverb_pre_post);
+static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency, pod_set_band_2_frequency);
+static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency__bass, pod_set_band_3_frequency__bass);
+static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable, pod_set_wah_enable);
+static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO, pod_get_modulation_lo_cut, pod_set_modulation_lo_cut);
+static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO, pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut);
+static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO, pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum);
+static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post, pod_set_eq_pre_post);
+static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post, pod_set_volume_pre_post);
+static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model, pod_set_di_model);
+static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay, pod_set_di_delay);
+static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable, pod_set_mod_enable);
+static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_mod_param_1_note_value, pod_set_mod_param_1_note_value);
+static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2, pod_set_mod_param_2);
+static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3, pod_set_mod_param_3);
+static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4, pod_set_mod_param_4);
+static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5, pod_set_mod_param_5);
+static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix, pod_set_mod_volume_mix);
+static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post, pod_set_mod_pre_post);
+static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO, pod_get_modulation_model, pod_set_modulation_model);
+static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency, pod_set_band_3_frequency);
+static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency__bass, pod_set_band_4_frequency__bass);
+static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO, pod_get_mod_param_1_double_precision, pod_set_mod_param_1_double_precision);
+static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO, pod_get_delay_param_1_double_precision, pod_set_delay_param_1_double_precision);
+static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable, pod_set_eq_enable);
+static DEVICE_ATTR(tap, S_IWUGO | S_IRUGO, pod_get_tap, pod_set_tap);
+static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO, pod_get_volume_tweak_pedal_assign, pod_set_volume_tweak_pedal_assign);
+static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO, pod_get_band_5_frequency, pod_set_band_5_frequency);
+static DEVICE_ATTR(tuner, S_IWUGO | S_IRUGO, pod_get_tuner, pod_set_tuner);
+static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection, pod_set_mic_selection);
+static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model, pod_set_cabinet_model);
+static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model, pod_set_stomp_model);
+static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel, pod_set_roomlevel);
+static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency, pod_set_band_4_frequency);
+static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO, pod_get_band_6_frequency, pod_set_band_6_frequency);
+static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_stomp_param_1_note_value, pod_set_stomp_param_1_note_value);
+static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2, pod_set_stomp_param_2);
+static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3, pod_set_stomp_param_3);
+static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4, pod_set_stomp_param_4);
+static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5, pod_set_stomp_param_5);
+static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6, pod_set_stomp_param_6);
+static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO, pod_get_amp_switch_select, pod_set_amp_switch_select);
+static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4, pod_set_delay_param_4);
+static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5, pod_set_delay_param_5);
+static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post, pod_set_delay_pre_post);
+static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model, pod_set_delay_model);
+static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO, pod_get_delay_verb_model, pod_set_delay_verb_model);
+static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb, pod_set_tempo_msb);
+static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb, pod_set_tempo_lsb);
+static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model, pod_set_wah_model);
+static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume, pod_set_bypass_volume);
+static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off, pod_set_fx_loop_on_off);
+static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO, pod_get_tweak_param_select, pod_set_tweak_param_select);
+static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage, pod_set_amp1_engage);
+static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain, pod_set_band_1_gain);
+static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain__bass, pod_set_band_2_gain__bass);
+static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain, pod_set_band_2_gain);
+static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain__bass, pod_set_band_3_gain__bass);
+static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain, pod_set_band_3_gain);
+static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain__bass, pod_set_band_4_gain__bass);
+static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO, pod_get_band_5_gain__bass, pod_set_band_5_gain__bass);
+static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain, pod_set_band_4_gain);
+static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO, pod_get_band_6_gain__bass, pod_set_band_6_gain__bass);
+static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write);
+static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable, line6_nop_write);
+static DEVICE_ATTR(pickup1_type, S_IRUGO, variax_get_pickup1_type, line6_nop_write);
+static DEVICE_ATTR(pickup1_position, S_IRUGO, variax_get_pickup1_position, line6_nop_write);
+static DEVICE_ATTR(pickup1_angle, S_IRUGO, variax_get_pickup1_angle, line6_nop_write);
+static DEVICE_ATTR(pickup1_level, S_IRUGO, variax_get_pickup1_level, line6_nop_write);
+static DEVICE_ATTR(pickup2_enable, S_IRUGO, variax_get_pickup2_enable, line6_nop_write);
+static DEVICE_ATTR(pickup2_type, S_IRUGO, variax_get_pickup2_type, line6_nop_write);
+static DEVICE_ATTR(pickup2_position, S_IRUGO, variax_get_pickup2_position, line6_nop_write);
+static DEVICE_ATTR(pickup2_angle, S_IRUGO, variax_get_pickup2_angle, line6_nop_write);
+static DEVICE_ATTR(pickup2_level, S_IRUGO, variax_get_pickup2_level, line6_nop_write);
+static DEVICE_ATTR(pickup_phase, S_IRUGO, variax_get_pickup_phase, line6_nop_write);
+static DEVICE_ATTR(capacitance, S_IRUGO, variax_get_capacitance, line6_nop_write);
+static DEVICE_ATTR(tone_resistance, S_IRUGO, variax_get_tone_resistance, line6_nop_write);
+static DEVICE_ATTR(volume_resistance, S_IRUGO, variax_get_volume_resistance, line6_nop_write);
+static DEVICE_ATTR(taper, S_IRUGO, variax_get_taper, line6_nop_write);
+static DEVICE_ATTR(tone_dump, S_IRUGO, variax_get_tone_dump, line6_nop_write);
+static DEVICE_ATTR(save_tone, S_IRUGO, variax_get_save_tone, line6_nop_write);
+static DEVICE_ATTR(volume_dump, S_IRUGO, variax_get_volume_dump, line6_nop_write);
+static DEVICE_ATTR(tuning_enable, S_IRUGO, variax_get_tuning_enable, line6_nop_write);
+static DEVICE_ATTR(tuning6, S_IRUGO, variax_get_tuning6, line6_nop_write);
+static DEVICE_ATTR(tuning5, S_IRUGO, variax_get_tuning5, line6_nop_write);
+static DEVICE_ATTR(tuning4, S_IRUGO, variax_get_tuning4, line6_nop_write);
+static DEVICE_ATTR(tuning3, S_IRUGO, variax_get_tuning3, line6_nop_write);
+static DEVICE_ATTR(tuning2, S_IRUGO, variax_get_tuning2, line6_nop_write);
+static DEVICE_ATTR(tuning1, S_IRUGO, variax_get_tuning1, line6_nop_write);
+static DEVICE_ATTR(detune6, S_IRUGO, variax_get_detune6, line6_nop_write);
+static DEVICE_ATTR(detune5, S_IRUGO, variax_get_detune5, line6_nop_write);
+static DEVICE_ATTR(detune4, S_IRUGO, variax_get_detune4, line6_nop_write);
+static DEVICE_ATTR(detune3, S_IRUGO, variax_get_detune3, line6_nop_write);
+static DEVICE_ATTR(detune2, S_IRUGO, variax_get_detune2, line6_nop_write);
+static DEVICE_ATTR(detune1, S_IRUGO, variax_get_detune1, line6_nop_write);
+static DEVICE_ATTR(mix6, S_IRUGO, variax_get_mix6, line6_nop_write);
+static DEVICE_ATTR(mix5, S_IRUGO, variax_get_mix5, line6_nop_write);
+static DEVICE_ATTR(mix4, S_IRUGO, variax_get_mix4, line6_nop_write);
+static DEVICE_ATTR(mix3, S_IRUGO, variax_get_mix3, line6_nop_write);
+static DEVICE_ATTR(mix2, S_IRUGO, variax_get_mix2, line6_nop_write);
+static DEVICE_ATTR(mix1, S_IRUGO, variax_get_mix1, line6_nop_write);
+static DEVICE_ATTR(pickup_wiring, S_IRUGO, variax_get_pickup_wiring, line6_nop_write);
+
+int pod_create_files(int firmware, int type, struct device *dev)
+{
+ int err;
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tweak));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_wah_position));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_compression_gain));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_vol_pedal_position));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_compression_threshold));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pan));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_amp_model_setup));
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_amp_model));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_drive));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_bass));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mid));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_lowmid));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_treble));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_highmid));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_chan_vol));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_mix));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_effect_setup));
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_1_frequency));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_presence));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_treble__bass));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_noise_gate_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_gate_threshold));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_gate_decay_time));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_comp_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_time));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1_note_value));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_frequency__bass));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_2));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_volume_mix));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_3));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_enable));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_type));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_decay));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_tone));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_pre_delay));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_pre_post));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_frequency));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_frequency__bass));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_wah_enable));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_modulation_lo_cut));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_reverb_lo_cut));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_volume_pedal_minimum));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_eq_pre_post));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_volume_pre_post));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_di_model));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_di_delay));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1_note_value));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_2));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_3));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_4));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_5));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_volume_mix));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_pre_post));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_modulation_model));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_frequency));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_frequency__bass));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1_double_precision));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1_double_precision));
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_eq_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tap));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_volume_tweak_pedal_assign));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_5_frequency));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuner));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mic_selection));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_cabinet_model));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_model));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_roomlevel));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_frequency));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_6_frequency));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_1_note_value));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_2));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_3));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_4));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_5));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_6));
+ if ((type & (LINE6_BITS_LIVE)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_amp_switch_select));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_4));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_5));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_pre_post));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_model));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_verb_model));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_msb));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_lsb));
+ if (firmware >= 300)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_wah_model));
+ if (firmware >= 214)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_bypass_volume));
+ if ((type & (LINE6_BITS_PRO)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_fx_loop_on_off));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tweak_param_select));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_amp1_engage));
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_1_gain));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_gain__bass));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_gain));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_gain__bass));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_gain));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_gain__bass));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_5_gain__bass));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_gain));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_6_gain__bass));
+ return 0;
+}
+
+void pod_remove_files(int firmware, int type, struct device *dev)
+{
+ device_remove_file(dev, &dev_attr_tweak);
+ device_remove_file(dev, &dev_attr_wah_position);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_compression_gain);
+ device_remove_file(dev, &dev_attr_vol_pedal_position);
+ device_remove_file(dev, &dev_attr_compression_threshold);
+ device_remove_file(dev, &dev_attr_pan);
+ device_remove_file(dev, &dev_attr_amp_model_setup);
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_amp_model);
+ device_remove_file(dev, &dev_attr_drive);
+ device_remove_file(dev, &dev_attr_bass);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_mid);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_lowmid);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_treble);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_highmid);
+ device_remove_file(dev, &dev_attr_chan_vol);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_mix);
+ device_remove_file(dev, &dev_attr_effect_setup);
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_1_frequency);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_presence);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_treble__bass);
+ device_remove_file(dev, &dev_attr_noise_gate_enable);
+ device_remove_file(dev, &dev_attr_gate_threshold);
+ device_remove_file(dev, &dev_attr_gate_decay_time);
+ device_remove_file(dev, &dev_attr_stomp_enable);
+ device_remove_file(dev, &dev_attr_comp_enable);
+ device_remove_file(dev, &dev_attr_stomp_time);
+ device_remove_file(dev, &dev_attr_delay_enable);
+ device_remove_file(dev, &dev_attr_mod_param_1);
+ device_remove_file(dev, &dev_attr_delay_param_1);
+ device_remove_file(dev, &dev_attr_delay_param_1_note_value);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_2_frequency__bass);
+ device_remove_file(dev, &dev_attr_delay_param_2);
+ device_remove_file(dev, &dev_attr_delay_volume_mix);
+ device_remove_file(dev, &dev_attr_delay_param_3);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_enable);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_type);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_decay);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_tone);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_pre_delay);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_pre_post);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_2_frequency);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_3_frequency__bass);
+ device_remove_file(dev, &dev_attr_wah_enable);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_modulation_lo_cut);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_delay_reverb_lo_cut);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_volume_pedal_minimum);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_eq_pre_post);
+ device_remove_file(dev, &dev_attr_volume_pre_post);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_di_model);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_di_delay);
+ device_remove_file(dev, &dev_attr_mod_enable);
+ device_remove_file(dev, &dev_attr_mod_param_1_note_value);
+ device_remove_file(dev, &dev_attr_mod_param_2);
+ device_remove_file(dev, &dev_attr_mod_param_3);
+ device_remove_file(dev, &dev_attr_mod_param_4);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_mod_param_5);
+ device_remove_file(dev, &dev_attr_mod_volume_mix);
+ device_remove_file(dev, &dev_attr_mod_pre_post);
+ device_remove_file(dev, &dev_attr_modulation_model);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_3_frequency);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_4_frequency__bass);
+ device_remove_file(dev, &dev_attr_mod_param_1_double_precision);
+ device_remove_file(dev, &dev_attr_delay_param_1_double_precision);
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_eq_enable);
+ device_remove_file(dev, &dev_attr_tap);
+ device_remove_file(dev, &dev_attr_volume_tweak_pedal_assign);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_5_frequency);
+ device_remove_file(dev, &dev_attr_tuner);
+ device_remove_file(dev, &dev_attr_mic_selection);
+ device_remove_file(dev, &dev_attr_cabinet_model);
+ device_remove_file(dev, &dev_attr_stomp_model);
+ device_remove_file(dev, &dev_attr_roomlevel);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_4_frequency);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_6_frequency);
+ device_remove_file(dev, &dev_attr_stomp_param_1_note_value);
+ device_remove_file(dev, &dev_attr_stomp_param_2);
+ device_remove_file(dev, &dev_attr_stomp_param_3);
+ device_remove_file(dev, &dev_attr_stomp_param_4);
+ device_remove_file(dev, &dev_attr_stomp_param_5);
+ device_remove_file(dev, &dev_attr_stomp_param_6);
+ if ((type & (LINE6_BITS_LIVE)) != 0)
+ device_remove_file(dev, &dev_attr_amp_switch_select);
+ device_remove_file(dev, &dev_attr_delay_param_4);
+ device_remove_file(dev, &dev_attr_delay_param_5);
+ device_remove_file(dev, &dev_attr_delay_pre_post);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_delay_model);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_delay_verb_model);
+ device_remove_file(dev, &dev_attr_tempo_msb);
+ device_remove_file(dev, &dev_attr_tempo_lsb);
+ if (firmware >= 300)
+ device_remove_file(dev, &dev_attr_wah_model);
+ if (firmware >= 214)
+ device_remove_file(dev, &dev_attr_bypass_volume);
+ if ((type & (LINE6_BITS_PRO)) != 0)
+ device_remove_file(dev, &dev_attr_fx_loop_on_off);
+ device_remove_file(dev, &dev_attr_tweak_param_select);
+ device_remove_file(dev, &dev_attr_amp1_engage);
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_1_gain);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_2_gain__bass);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_2_gain);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_3_gain__bass);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_3_gain);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_4_gain__bass);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_5_gain__bass);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_4_gain);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_6_gain__bass);
+}
+
+EXPORT_SYMBOL(pod_create_files);
+EXPORT_SYMBOL(pod_remove_files);
+
+int variax_create_files(int firmware, int type, struct device *dev)
+{
+ int err;
+ CHECK_RETURN(device_create_file(dev, &dev_attr_body));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_type));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_position));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_angle));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_level));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_type));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_position));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_angle));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_level));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_phase));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_capacitance));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tone_resistance));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_volume_resistance));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_taper));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tone_dump));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_save_tone));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_volume_dump));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning6));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning5));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning4));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning3));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning2));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning1));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_detune6));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_detune5));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_detune4));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_detune3));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_detune2));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_detune1));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mix6));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mix5));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mix4));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mix3));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mix2));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mix1));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_wiring));
+ return 0;
+}
+
+void variax_remove_files(int firmware, int type, struct device *dev)
+{
+ device_remove_file(dev, &dev_attr_body);
+ device_remove_file(dev, &dev_attr_pickup1_enable);
+ device_remove_file(dev, &dev_attr_pickup1_type);
+ device_remove_file(dev, &dev_attr_pickup1_position);
+ device_remove_file(dev, &dev_attr_pickup1_angle);
+ device_remove_file(dev, &dev_attr_pickup1_level);
+ device_remove_file(dev, &dev_attr_pickup2_enable);
+ device_remove_file(dev, &dev_attr_pickup2_type);
+ device_remove_file(dev, &dev_attr_pickup2_position);
+ device_remove_file(dev, &dev_attr_pickup2_angle);
+ device_remove_file(dev, &dev_attr_pickup2_level);
+ device_remove_file(dev, &dev_attr_pickup_phase);
+ device_remove_file(dev, &dev_attr_capacitance);
+ device_remove_file(dev, &dev_attr_tone_resistance);
+ device_remove_file(dev, &dev_attr_volume_resistance);
+ device_remove_file(dev, &dev_attr_taper);
+ device_remove_file(dev, &dev_attr_tone_dump);
+ device_remove_file(dev, &dev_attr_save_tone);
+ device_remove_file(dev, &dev_attr_volume_dump);
+ device_remove_file(dev, &dev_attr_tuning_enable);
+ device_remove_file(dev, &dev_attr_tuning6);
+ device_remove_file(dev, &dev_attr_tuning5);
+ device_remove_file(dev, &dev_attr_tuning4);
+ device_remove_file(dev, &dev_attr_tuning3);
+ device_remove_file(dev, &dev_attr_tuning2);
+ device_remove_file(dev, &dev_attr_tuning1);
+ device_remove_file(dev, &dev_attr_detune6);
+ device_remove_file(dev, &dev_attr_detune5);
+ device_remove_file(dev, &dev_attr_detune4);
+ device_remove_file(dev, &dev_attr_detune3);
+ device_remove_file(dev, &dev_attr_detune2);
+ device_remove_file(dev, &dev_attr_detune1);
+ device_remove_file(dev, &dev_attr_mix6);
+ device_remove_file(dev, &dev_attr_mix5);
+ device_remove_file(dev, &dev_attr_mix4);
+ device_remove_file(dev, &dev_attr_mix3);
+ device_remove_file(dev, &dev_attr_mix2);
+ device_remove_file(dev, &dev_attr_mix1);
+ device_remove_file(dev, &dev_attr_pickup_wiring);
+}
+
+EXPORT_SYMBOL(variax_create_files);
+EXPORT_SYMBOL(variax_remove_files);
diff --git a/drivers/staging/line6/control.h b/drivers/staging/line6/control.h
new file mode 100644
index 00000000000..2f19665d95a
--- /dev/null
+++ b/drivers/staging/line6/control.h
@@ -0,0 +1,187 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+#ifndef LINE6_CONTROL_H
+#define LINE6_CONTROL_H
+
+
+/**
+ List of PODxt Pro controls.
+ See Appendix C of the "PODxt (Pro) Pilot's Handbook" by Line6.
+ Comments after the number refer to the PODxt Pro firmware version required
+ for this feature.
+*/
+enum {
+ POD_tweak = 1,
+ POD_wah_position = 4,
+ POD_compression_gain = 5, /* device: LINE6_BITS_PODXTALL */
+ POD_vol_pedal_position = 7,
+ POD_compression_threshold = 9,
+ POD_pan = 10,
+ POD_amp_model_setup = 11,
+ POD_amp_model = 12, /* firmware: 2.0 */
+ POD_drive = 13,
+ POD_bass = 14,
+ POD_mid = 15, /* device: LINE6_BITS_PODXTALL */
+ POD_lowmid = 15, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_treble = 16, /* device: LINE6_BITS_PODXTALL */
+ POD_highmid = 16, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_chan_vol = 17,
+ POD_reverb_mix = 18, /* device: LINE6_BITS_PODXTALL */
+ POD_effect_setup = 19,
+ POD_band_1_frequency = 20, /* firmware: 2.0 */
+ POD_presence = 21, /* device: LINE6_BITS_PODXTALL */
+ POD_treble__bass = 21, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_noise_gate_enable = 22,
+ POD_gate_threshold = 23,
+ POD_gate_decay_time = 24,
+ POD_stomp_enable = 25,
+ POD_comp_enable = 26,
+ POD_stomp_time = 27,
+ POD_delay_enable = 28,
+ POD_mod_param_1 = 29,
+ POD_delay_param_1 = 30,
+ POD_delay_param_1_note_value = 31,
+ POD_band_2_frequency__bass = 32, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_delay_param_2 = 33,
+ POD_delay_volume_mix = 34,
+ POD_delay_param_3 = 35,
+ POD_reverb_enable = 36, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_type = 37, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_decay = 38, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_tone = 39, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_pre_delay = 40, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_pre_post = 41, /* device: LINE6_BITS_PODXTALL */
+ POD_band_2_frequency = 42, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_3_frequency__bass = 42, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_wah_enable = 43,
+ POD_modulation_lo_cut = 44, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_delay_reverb_lo_cut = 45, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_volume_pedal_minimum = 46, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_eq_pre_post = 46, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_volume_pre_post = 47,
+ POD_di_model = 48, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_di_delay = 49, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_mod_enable = 50,
+ POD_mod_param_1_note_value = 51,
+ POD_mod_param_2 = 52,
+ POD_mod_param_3 = 53,
+ POD_mod_param_4 = 54,
+ POD_mod_param_5 = 55, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_mod_volume_mix = 56,
+ POD_mod_pre_post = 57,
+ POD_modulation_model = 58,
+ POD_band_3_frequency = 60, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_4_frequency__bass = 60, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_mod_param_1_double_precision = 61,
+ POD_delay_param_1_double_precision = 62,
+ POD_eq_enable = 63, /* firmware: 2.0 */
+ POD_tap = 64,
+ POD_volume_tweak_pedal_assign = 65,
+ POD_band_5_frequency = 68, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_tuner = 69,
+ POD_mic_selection = 70,
+ POD_cabinet_model = 71,
+ POD_stomp_model = 75,
+ POD_roomlevel = 76,
+ POD_band_4_frequency = 77, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_6_frequency = 77, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_stomp_param_1_note_value = 78,
+ POD_stomp_param_2 = 79,
+ POD_stomp_param_3 = 80,
+ POD_stomp_param_4 = 81,
+ POD_stomp_param_5 = 82,
+ POD_stomp_param_6 = 83,
+ POD_amp_switch_select = 84, /* device: LINE6_BITS_LIVE */
+ POD_delay_param_4 = 85,
+ POD_delay_param_5 = 86,
+ POD_delay_pre_post = 87,
+ POD_delay_model = 88, /* device: LINE6_BITS_PODXTALL */
+ POD_delay_verb_model = 88, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_tempo_msb = 89,
+ POD_tempo_lsb = 90,
+ POD_wah_model = 91, /* firmware: 3.0 */
+ POD_bypass_volume = 105, /* firmware: 2.14 */
+ POD_fx_loop_on_off = 107, /* device: LINE6_BITS_PRO */
+ POD_tweak_param_select = 108,
+ POD_amp1_engage = 111,
+ POD_band_1_gain = 114, /* firmware: 2.0 */
+ POD_band_2_gain__bass = 115, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_band_2_gain = 116, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_3_gain__bass = 116, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_band_3_gain = 117, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_4_gain__bass = 117, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_band_5_gain__bass = 118, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_band_4_gain = 119, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_6_gain__bass = 119 /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+};
+
+/**
+ List of Variax workbench controls (dump).
+*/
+enum {
+ VARIAX_body = 3,
+ VARIAX_pickup1_enable = 4, /* 0: enabled, 1: disabled */
+ VARIAX_pickup1_type = 8,
+ VARIAX_pickup1_position = 9, /* type: 24 bit float */
+ VARIAX_pickup1_angle = 12, /* type: 24 bit float */
+ VARIAX_pickup1_level = 15, /* type: 24 bit float */
+ VARIAX_pickup2_enable = 18, /* 0: enabled, 1: disabled */
+ VARIAX_pickup2_type = 22,
+ VARIAX_pickup2_position = 23, /* type: 24 bit float */
+ VARIAX_pickup2_angle = 26, /* type: 24 bit float */
+ VARIAX_pickup2_level = 29, /* type: 24 bit float */
+ VARIAX_pickup_phase = 32, /* 0: in phase, 1: out of phase */
+ VARIAX_capacitance = 33, /* type: 24 bit float */
+ VARIAX_tone_resistance = 36, /* type: 24 bit float */
+ VARIAX_volume_resistance = 39, /* type: 24 bit float */
+ VARIAX_taper = 42, /* 0: Linear, 1: Audio */
+ VARIAX_tone_dump = 43, /* type: 24 bit float */
+ VARIAX_save_tone = 46,
+ VARIAX_volume_dump = 47, /* type: 24 bit float */
+ VARIAX_tuning_enable = 50,
+ VARIAX_tuning6 = 51,
+ VARIAX_tuning5 = 52,
+ VARIAX_tuning4 = 53,
+ VARIAX_tuning3 = 54,
+ VARIAX_tuning2 = 55,
+ VARIAX_tuning1 = 56,
+ VARIAX_detune6 = 57, /* type: 24 bit float */
+ VARIAX_detune5 = 60, /* type: 24 bit float */
+ VARIAX_detune4 = 63, /* type: 24 bit float */
+ VARIAX_detune3 = 66, /* type: 24 bit float */
+ VARIAX_detune2 = 69, /* type: 24 bit float */
+ VARIAX_detune1 = 72, /* type: 24 bit float */
+ VARIAX_mix6 = 75, /* type: 24 bit float */
+ VARIAX_mix5 = 78, /* type: 24 bit float */
+ VARIAX_mix4 = 81, /* type: 24 bit float */
+ VARIAX_mix3 = 84, /* type: 24 bit float */
+ VARIAX_mix2 = 87, /* type: 24 bit float */
+ VARIAX_mix1 = 90, /* type: 24 bit float */
+ VARIAX_pickup_wiring = 96 /* 0: parallel, 1: series */
+};
+
+/**
+ List of Variax workbench controls (MIDI).
+*/
+enum {
+ VARIAXMIDI_volume = 7,
+ VARIAXMIDI_tone = 79,
+};
+
+
+extern int pod_create_files(int firmware, int type, struct device *dev);
+extern void pod_remove_files(int firmware, int type, struct device *dev);
+extern int variax_create_files(int firmware, int type, struct device *dev);
+extern void variax_remove_files(int firmware, int type, struct device *dev);
+
+
+#endif
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
new file mode 100644
index 00000000000..85a20d0002c
--- /dev/null
+++ b/drivers/staging/line6/driver.c
@@ -0,0 +1,1102 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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 "driver.h"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "audio.h"
+#include "capture.h"
+#include "control.h"
+#include "midi.h"
+#include "playback.h"
+#include "pod.h"
+#include "revision.h"
+#include "toneport.h"
+#include "usbdefs.h"
+#include "variax.h"
+
+
+#define DRIVER_AUTHOR "Markus Grabner <grabner@icg.tugraz.at>"
+#define DRIVER_DESC "Line6 USB Driver"
+#define DRIVER_VERSION "0.8.0"
+
+
+/* table of devices that work with this driver */
+static struct usb_device_id line6_id_table[] = {
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_GX) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX1) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX2) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_VARIAX) },
+ { },
+};
+MODULE_DEVICE_TABLE(usb, line6_id_table);
+
+static struct line6_properties line6_properties_table[] = {
+ { "BassPODxt", LINE6_BIT_BASSPODXT, LINE6_BIT_CONTROL_PCM },
+ { "BassPODxt Live", LINE6_BIT_BASSPODXTLIVE, LINE6_BIT_CONTROL_PCM },
+ { "BassPODxt Pro", LINE6_BIT_BASSPODXTPRO, LINE6_BIT_CONTROL_PCM },
+ { "GuitarPort", LINE6_BIT_GUITARPORT, LINE6_BIT_PCM },
+ { "Pocket POD", LINE6_BIT_POCKETPOD, LINE6_BIT_CONTROL_PCM },
+ { "POD X3", LINE6_BIT_PODX3, LINE6_BIT_PCM },
+ { "POD X3 Live", LINE6_BIT_PODX3LIVE, LINE6_BIT_PCM },
+ { "PODxt", LINE6_BIT_PODXT, LINE6_BIT_CONTROL_PCM },
+ { "PODxt Live", LINE6_BIT_PODXTLIVE, LINE6_BIT_CONTROL_PCM },
+ { "PODxt Pro", LINE6_BIT_PODXTPRO, LINE6_BIT_CONTROL_PCM },
+ { "TonePort GX", LINE6_BIT_TONEPORT_GX, LINE6_BIT_PCM },
+ { "TonePort UX1", LINE6_BIT_TONEPORT_UX1, LINE6_BIT_PCM },
+ { "TonePort UX2", LINE6_BIT_TONEPORT_UX2, LINE6_BIT_PCM },
+ { "Variax Workbench", LINE6_BIT_VARIAX, LINE6_BIT_CONTROL }
+};
+
+
+/*
+ This is Line6's MIDI manufacturer ID.
+*/
+const unsigned char line6_midi_id[] = { 0x00, 0x01, 0x0c };
+
+struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
+struct workqueue_struct *line6_workqueue;
+
+
+/**
+ Class for asynchronous messages.
+*/
+struct message {
+ struct usb_line6 *line6;
+ const char *buffer;
+ int size;
+ int done;
+};
+
+
+/*
+ Forward declarations.
+*/
+static void line6_data_received(struct urb *urb);
+static int line6_send_raw_message_async_part(struct message *msg,
+ struct urb *urb);
+
+
+/*
+ Start to listen on endpoint.
+*/
+static int line6_start_listen(struct usb_line6 *line6)
+{
+ usb_fill_int_urb(line6->urb_listen, line6->usbdev,
+ usb_rcvintpipe(line6->usbdev, line6->ep_control_read),
+ line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
+ line6_data_received, line6, line6->interval);
+ line6->urb_listen->actual_length = 0;
+ return usb_submit_urb(line6->urb_listen, GFP_KERNEL);
+}
+
+#if DO_DUMP_ANY
+/*
+ Write hexdump to syslog.
+*/
+void line6_write_hexdump(struct usb_line6 *line6, char dir,
+ const unsigned char *buffer, int size)
+{
+ static const int BYTES_PER_LINE = 8;
+ char hexdump[100];
+ char asc[BYTES_PER_LINE + 1];
+ int i, j;
+
+ for (i = 0; i < size; i += BYTES_PER_LINE) {
+ int hexdumpsize = sizeof(hexdump);
+ char *p = hexdump;
+ int n = min(size - i, BYTES_PER_LINE);
+ asc[n] = 0;
+
+ for (j = 0; j < BYTES_PER_LINE; ++j) {
+ int bytes;
+
+ if (j < n) {
+ unsigned char val = buffer[i + j];
+ bytes = snprintf(p, hexdumpsize, " %02X", val);
+ asc[j] = ((val >= 0x20) && (val < 0x7f)) ? val : '.';
+ } else
+ bytes = snprintf(p, hexdumpsize, " ");
+
+ if (bytes > hexdumpsize)
+ break; /* buffer overflow */
+
+ p += bytes;
+ hexdumpsize -= bytes;
+ }
+
+ dev_info(line6->ifcdev, "%c%04X:%s %s\n", dir, i, hexdump, asc);
+ }
+}
+#endif
+
+#if DO_DUMP_URB_RECEIVE
+/*
+ Dump URB data to syslog.
+*/
+static void line6_dump_urb(struct urb *urb)
+{
+ struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
+
+ if (urb->status < 0)
+ return;
+
+ line6_write_hexdump(line6, 'R', (unsigned char *)urb->transfer_buffer,
+ urb->actual_length);
+}
+#endif
+
+/*
+ Send raw message in pieces of wMaxPacketSize bytes.
+*/
+int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
+ int size)
+{
+ int i, done = 0;
+
+#if DO_DUMP_URB_SEND
+ line6_write_hexdump(line6, 'S', buffer, size);
+#endif
+
+ for (i = 0; i < size; i += line6->max_packet_size) {
+ int partial;
+ const char *frag_buf = buffer + i;
+ int frag_size = min(line6->max_packet_size, size - i);
+ int retval;
+
+ retval = usb_interrupt_msg(line6->usbdev,
+ usb_sndintpipe(line6->usbdev,
+ line6->ep_control_write),
+ (char *)frag_buf, frag_size,
+ &partial, LINE6_TIMEOUT * HZ);
+
+ if (retval) {
+ dev_err(line6->ifcdev,
+ "usb_interrupt_msg failed (%d)\n", retval);
+ break;
+ }
+
+ done += frag_size;
+ }
+
+ return done;
+}
+
+/*
+ Notification of completion of asynchronous request transmission.
+*/
+static void line6_async_request_sent(struct urb *urb)
+{
+ struct message *msg = (struct message *)urb->context;
+
+ if (msg->done >= msg->size) {
+ usb_free_urb(urb);
+ kfree(msg);
+ } else
+ line6_send_raw_message_async_part(msg, urb);
+}
+
+/*
+ Asynchronously send part of a raw message.
+*/
+static int line6_send_raw_message_async_part(struct message *msg,
+ struct urb *urb)
+{
+ int retval;
+ struct usb_line6 *line6 = msg->line6;
+ int done = msg->done;
+ int bytes = min(msg->size - done, line6->max_packet_size);
+
+ usb_fill_int_urb(urb, line6->usbdev,
+ usb_sndintpipe(line6->usbdev, line6->ep_control_write),
+ (char *)msg->buffer + done, bytes,
+ line6_async_request_sent, msg, line6->interval);
+
+#if DO_DUMP_URB_SEND
+ line6_write_hexdump(line6, 'S', (char *)msg->buffer + done, bytes);
+#endif
+
+ msg->done += bytes;
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+
+ if (retval < 0) {
+ dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n",
+ __func__, retval);
+ usb_free_urb(urb);
+ kfree(msg);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ Asynchronously send raw message.
+*/
+int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
+ int size)
+{
+ struct message *msg;
+ struct urb *urb;
+
+ /* create message: */
+ msg = kmalloc(sizeof(struct message), GFP_ATOMIC);
+
+ if (msg == NULL) {
+ dev_err(line6->ifcdev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+ /* create URB: */
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+ if (urb == NULL) {
+ kfree(msg);
+ dev_err(line6->ifcdev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+ /* set message data: */
+ msg->line6 = line6;
+ msg->buffer = buffer;
+ msg->size = size;
+ msg->done = 0;
+
+ /* start sending: */
+ return line6_send_raw_message_async_part(msg, urb);
+}
+
+/*
+ Send sysex message in pieces of wMaxPacketSize bytes.
+*/
+int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
+ int size)
+{
+ return line6_send_raw_message(line6, buffer, size + SYSEX_EXTRA_SIZE) - SYSEX_EXTRA_SIZE;
+}
+
+/*
+ Allocate buffer for sysex message and prepare header.
+ @param code sysex message code
+ @param size number of bytes between code and sysex end
+*/
+char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,
+ int size)
+{
+ char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_KERNEL);
+
+ if (!buffer) {
+ dev_err(line6->ifcdev, "out of memory\n");
+ return NULL;
+ }
+
+ buffer[0] = LINE6_SYSEX_BEGIN;
+ memcpy(buffer + 1, line6_midi_id, sizeof(line6_midi_id));
+ buffer[sizeof(line6_midi_id) + 1] = code1;
+ buffer[sizeof(line6_midi_id) + 2] = code2;
+ buffer[sizeof(line6_midi_id) + 3 + size] = LINE6_SYSEX_END;
+ return buffer;
+}
+
+/*
+ Notification of data received from the Line6 device.
+*/
+static void line6_data_received(struct urb *urb)
+{
+ struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
+ struct MidiBuffer *mb = &line6->line6midi->midibuf_in;
+ int done;
+
+ if (urb->status == -ESHUTDOWN)
+ return;
+
+#if DO_DUMP_URB_RECEIVE
+ line6_dump_urb(urb);
+#endif
+
+ done = midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
+
+ if (done < urb->actual_length) {
+ midibuf_ignore(mb, done);
+ DEBUG_MESSAGES(dev_err(line6->ifcdev, "%d %d buffer overflow - message skipped\n", done, urb->actual_length));
+ }
+
+ for (;;) {
+ done = midibuf_read(mb, line6->buffer_message, LINE6_MESSAGE_MAXLEN);
+
+ if (done == 0)
+ break;
+
+ /* MIDI input filter */
+ if (midibuf_skip_message(mb, line6->line6midi->midi_mask_receive))
+ continue;
+
+ line6->message_length = done;
+#if DO_DUMP_MIDI_RECEIVE
+ line6_write_hexdump(line6, 'r', line6->buffer_message, done);
+#endif
+ line6_midi_receive(line6, line6->buffer_message, done);
+
+ switch (line6->usbdev->descriptor.idProduct) {
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTPRO:
+ case LINE6_DEVID_POCKETPOD:
+ pod_process_message((struct usb_line6_pod *)line6);
+ break;
+
+ case LINE6_DEVID_PODXTLIVE:
+ switch (line6->interface_number) {
+ case PODXTLIVE_INTERFACE_POD:
+ pod_process_message((struct usb_line6_pod *)line6);
+ break;
+
+ case PODXTLIVE_INTERFACE_VARIAX:
+ variax_process_message((struct usb_line6_variax *)line6);
+ break;
+
+ default:
+ dev_err(line6->ifcdev, "PODxt Live interface %d not supported\n", line6->interface_number);
+ }
+ break;
+
+ case LINE6_DEVID_VARIAX:
+ variax_process_message((struct usb_line6_variax *)line6);
+ break;
+
+ default:
+ MISSING_CASE;
+ }
+ }
+
+ line6_start_listen(line6);
+}
+
+/*
+ Send channel number (i.e., switch to a different sound).
+*/
+int line6_send_program(struct usb_line6 *line6, int value)
+{
+ int retval;
+ unsigned char *buffer;
+ unsigned int partial;
+
+ buffer = kmalloc(2, GFP_KERNEL);
+
+ if (!buffer) {
+ dev_err(line6->ifcdev, "out of memory\n");
+ return -ENOMEM;
+ }
+
+ buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;
+ buffer[1] = value;
+
+#if DO_DUMP_URB_SEND
+ line6_write_hexdump(line6, 'S', buffer, 2);
+#endif
+
+ retval = usb_interrupt_msg(line6->usbdev,
+ usb_sndintpipe(line6->usbdev,
+ line6->ep_control_write),
+ buffer, 2, &partial, LINE6_TIMEOUT * HZ);
+
+ if (retval)
+ dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);
+
+ kfree(buffer);
+ return retval;
+}
+
+/*
+ Transmit Line6 control parameter.
+*/
+int line6_transmit_parameter(struct usb_line6 *line6, int param, int value)
+{
+ int retval;
+ unsigned char *buffer;
+ unsigned int partial;
+
+ buffer = kmalloc(3, GFP_KERNEL);
+
+ if (!buffer) {
+ dev_err(line6->ifcdev, "out of memory\n");
+ return -ENOMEM;
+ }
+
+ buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST;
+ buffer[1] = param;
+ buffer[2] = value;
+
+#if DO_DUMP_URB_SEND
+ line6_write_hexdump(line6, 'S', buffer, 3);
+#endif
+
+ retval = usb_interrupt_msg(line6->usbdev,
+ usb_sndintpipe(line6->usbdev, line6->ep_control_write),
+ buffer, 3, &partial, LINE6_TIMEOUT * HZ);
+
+ if (retval)
+ dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);
+
+ kfree(buffer);
+ return retval;
+}
+
+/*
+ Read data from device.
+*/
+int line6_read_data(struct usb_line6 *line6, int address, void *data, size_t datalen)
+{
+ struct usb_device *usbdev = line6->usbdev;
+ int ret;
+ unsigned char len;
+
+ /* query the serial number: */
+ ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ (datalen << 8) | 0x21, address, NULL, 0, LINE6_TIMEOUT * HZ);
+
+ if (ret < 0) {
+ dev_err(line6->ifcdev, "read request failed (error %d)\n", ret);
+ return ret;
+ }
+
+ /* Wait for data length. We'll get a couple of 0xff until length arrives. */
+ do {
+ ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE |
+ USB_DIR_IN,
+ 0x0012, 0x0000, &len, 1,
+ LINE6_TIMEOUT * HZ);
+ if (ret < 0) {
+ dev_err(line6->ifcdev,
+ "receive length failed (error %d)\n", ret);
+ return ret;
+ }
+ }
+ while (len == 0xff)
+ ;
+
+ if (len != datalen) {
+ /* should be equal or something went wrong */
+ dev_err(line6->ifcdev,
+ "length mismatch (expected %d, got %d)\n",
+ (int)datalen, (int)len);
+ return -EINVAL;
+ }
+
+ /* receive the result: */
+ ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+ 0x0013, 0x0000, data, datalen,
+ LINE6_TIMEOUT * HZ);
+
+ if (ret < 0) {
+ dev_err(line6->ifcdev, "read failed (error %d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ Write data to device.
+*/
+int line6_write_data(struct usb_line6 *line6, int address, void *data,
+ size_t datalen)
+{
+ struct usb_device *usbdev = line6->usbdev;
+ int ret;
+ unsigned char status;
+
+ ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 0x0022, address, data, datalen,
+ LINE6_TIMEOUT * HZ);
+
+ if (ret < 0) {
+ dev_err(line6->ifcdev,
+ "write request failed (error %d)\n", ret);
+ return ret;
+ }
+
+ do {
+ ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
+ 0x67,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE |
+ USB_DIR_IN,
+ 0x0012, 0x0000,
+ &status, 1, LINE6_TIMEOUT * HZ);
+
+ if (ret < 0) {
+ dev_err(line6->ifcdev,
+ "receiving status failed (error %d)\n", ret);
+ return ret;
+ }
+ }
+ while (status == 0xff)
+ ;
+
+ if (status != 0) {
+ dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ Read Line6 device serial number.
+ (POD, TonePort, GuitarPort)
+*/
+int line6_read_serial_number(struct usb_line6 *line6, int *serial_number)
+{
+ return line6_read_data(line6, 0x80d0, serial_number, sizeof(*serial_number));
+}
+
+/*
+ No operation (i.e., unsupported).
+*/
+ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return 0;
+}
+
+/*
+ No operation (i.e., unsupported).
+*/
+ssize_t line6_nop_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return count;
+}
+
+/*
+ "write" request on "raw" special file.
+*/
+#if CREATE_RAW_FILE
+ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+ line6_send_raw_message(line6, buf, count);
+ return count;
+}
+#endif
+
+/*
+ Generic destructor.
+*/
+static void line6_destruct(struct usb_interface *interface)
+{
+ struct usb_line6 *line6;
+
+ if (interface == NULL)
+ return;
+ line6 = usb_get_intfdata(interface);
+ if (line6 == NULL)
+ return;
+
+ /* free buffer memory first: */
+ kfree(line6->buffer_message);
+ kfree(line6->buffer_listen);
+
+ /* then free URBs: */
+ usb_free_urb(line6->urb_listen);
+
+ /* make sure the device isn't destructed twice: */
+ usb_set_intfdata(interface, NULL);
+
+ /* free interface data: */
+ kfree(line6);
+}
+
+static void line6_list_devices(void)
+{
+ int i;
+
+ for (i = 0; i < LINE6_MAX_DEVICES; ++i) {
+ struct usb_line6 *dev = line6_devices[i];
+ printk(KERN_INFO "Line6 device %d: ", i);
+
+ if (dev == NULL)
+ printk("(not used)\n");
+ else
+ printk("%s:%d\n", dev->properties->name, dev->interface_number);
+ }
+}
+
+/*
+ Probe USB device.
+*/
+static int line6_probe(struct usb_interface *interface, const struct usb_device_id *id)
+{
+ int devtype;
+ struct usb_device *usbdev = NULL;
+ struct usb_line6 *line6 = NULL;
+ const struct line6_properties *properties;
+ int devnum;
+ int interface_number, alternate = 0;
+ int product;
+ int size = 0;
+ int ep_read = 0, ep_write = 0;
+ int ret;
+
+ if (interface == NULL)
+ return -ENODEV;
+ usbdev = interface_to_usbdev(interface);
+ if (usbdev == NULL)
+ return -ENODEV;
+
+ /* increment reference counters: */
+ usb_get_intf(interface);
+ usb_get_dev(usbdev);
+
+ /* we don't handle multiple configurations */
+ if (usbdev->descriptor.bNumConfigurations != 1)
+ return -ENODEV;
+
+ /* check vendor and product id */
+ for (devtype = sizeof(line6_id_table) / sizeof(line6_id_table[0]) - 1; devtype--;)
+ if ((le16_to_cpu(usbdev->descriptor.idVendor) == line6_id_table[devtype].idVendor) &&
+ (le16_to_cpu(usbdev->descriptor.idProduct) == line6_id_table[devtype].idProduct))
+ break;
+
+ if (devtype < 0)
+ return -ENODEV;
+
+ /* find free slot in device table: */
+ for (devnum = 0; devnum < LINE6_MAX_DEVICES; ++devnum)
+ if (line6_devices[devnum] == NULL)
+ break;
+
+ if (devnum == LINE6_MAX_DEVICES)
+ return -ENODEV;
+
+ /* initialize device info: */
+ properties = &line6_properties_table[devtype];
+ dev_info(&interface->dev, "Line6 %s found\n", properties->name);
+ product = le16_to_cpu(usbdev->descriptor.idProduct);
+
+ /* query interface number */
+ interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
+
+ switch (product) {
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_POCKETPOD:
+ case LINE6_DEVID_PODXTLIVE:
+ case LINE6_DEVID_VARIAX:
+ alternate = 1;
+ break;
+
+ case LINE6_DEVID_PODX3:
+ case LINE6_DEVID_PODX3LIVE:
+ switch (interface_number) {
+ case 0:
+ alternate = 1;
+ break;
+ case 1:
+ alternate = 0;
+ break;
+ default:
+ MISSING_CASE;
+ }
+ break;
+
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTPRO:
+ alternate = 5;
+ break;
+
+ case LINE6_DEVID_TONEPORT_GX:
+ case LINE6_DEVID_GUITARPORT:
+ alternate = 2; /* 1..4 seem to be ok */
+ break;
+
+ case LINE6_DEVID_TONEPORT_UX1:
+ case LINE6_DEVID_TONEPORT_UX2:
+ switch (interface_number) {
+ case 0:
+ /* defaults to 44.1kHz, 16-bit */
+ alternate = 2;
+ break;
+ case 1:
+ alternate = 0;
+ break;
+ default:
+ MISSING_CASE;
+ }
+ break;
+
+ default:
+ MISSING_CASE;
+ return -ENODEV;
+ }
+
+ ret = usb_set_interface(usbdev, interface_number, alternate);
+ if (ret < 0) {
+ dev_err(&interface->dev, "set_interface failed\n");
+ return ret;
+ }
+
+ /* initialize device data based on product id: */
+ switch (product) {
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_POCKETPOD:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTPRO:
+ size = sizeof(struct usb_line6_pod);
+ ep_read = 0x84;
+ ep_write = 0x03;
+ break;
+
+ case LINE6_DEVID_PODX3:
+ case LINE6_DEVID_PODX3LIVE:
+ /* currently unused! */
+ size = sizeof(struct usb_line6_pod);
+ ep_read = 0x81;
+ ep_write = 0x01;
+ break;
+
+ case LINE6_DEVID_TONEPORT_GX:
+ case LINE6_DEVID_TONEPORT_UX1:
+ case LINE6_DEVID_TONEPORT_UX2:
+ case LINE6_DEVID_GUITARPORT:
+ size = sizeof(struct usb_line6_toneport);
+ /* these don't have a control channel */
+ break;
+
+ case LINE6_DEVID_PODXTLIVE:
+ switch (interface_number) {
+ case PODXTLIVE_INTERFACE_POD:
+ size = sizeof(struct usb_line6_pod);
+ ep_read = 0x84;
+ ep_write = 0x03;
+ break;
+
+ case PODXTLIVE_INTERFACE_VARIAX:
+ size = sizeof(struct usb_line6_variax);
+ ep_read = 0x86;
+ ep_write = 0x05;
+ break;
+
+ default:
+ return -ENODEV;
+ }
+ break;
+
+ case LINE6_DEVID_VARIAX:
+ size = sizeof(struct usb_line6_variax);
+ ep_read = 0x82;
+ ep_write = 0x01;
+ break;
+
+ default:
+ MISSING_CASE;
+ return -ENODEV;
+ }
+
+ if (size == 0) {
+ dev_err(line6->ifcdev, "driver bug: interface data size not set\n");
+ return -ENODEV;
+ }
+
+ line6 = kzalloc(size, GFP_KERNEL);
+
+ if (line6 == NULL) {
+ dev_err(&interface->dev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+ /* store basic data: */
+ line6->interface_number = interface_number;
+ line6->properties = properties;
+ line6->usbdev = usbdev;
+ line6->ifcdev = &interface->dev;
+ line6->ep_control_read = ep_read;
+ line6->ep_control_write = ep_write;
+ line6->product = product;
+
+ /* get data from endpoint descriptor (see usb_maxpacket): */
+ {
+ struct usb_host_endpoint *ep;
+ unsigned epnum = usb_pipeendpoint(usb_rcvintpipe(usbdev, ep_read));
+ ep = usbdev->ep_in[epnum];
+
+ if (ep != NULL) {
+ line6->interval = ep->desc.bInterval;
+ line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
+ } else {
+ line6->interval = LINE6_FALLBACK_INTERVAL;
+ line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
+ dev_err(line6->ifcdev, "endpoint not available, using fallback values");
+ }
+ }
+
+ usb_set_intfdata(interface, line6);
+
+ if (properties->capabilities & LINE6_BIT_CONTROL) {
+ /* initialize USB buffers: */
+ line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
+
+ if (line6->buffer_listen == NULL) {
+ dev_err(&interface->dev, "Out of memory\n");
+ line6_destruct(interface);
+ return -ENOMEM;
+ }
+
+ line6->buffer_message = kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
+
+ if (line6->buffer_message == NULL) {
+ dev_err(&interface->dev, "Out of memory\n");
+ line6_destruct(interface);
+ return -ENOMEM;
+ }
+
+ line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);
+
+ if (line6->urb_listen == NULL) {
+ dev_err(&interface->dev, "Out of memory\n");
+ line6_destruct(interface);
+ return -ENOMEM;
+ }
+
+ ret = line6_start_listen(line6);
+ if (ret < 0) {
+ dev_err(&interface->dev, "%s: usb_submit_urb failed\n",
+ __func__);
+ line6_destruct(interface);
+ return ret;
+ }
+ }
+
+ /* initialize device data based on product id: */
+ switch (product) {
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_POCKETPOD:
+ case LINE6_DEVID_PODX3:
+ case LINE6_DEVID_PODX3LIVE:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTPRO:
+ ret = pod_init(interface, (struct usb_line6_pod *)line6);
+ break;
+
+ case LINE6_DEVID_PODXTLIVE:
+ switch (interface_number) {
+ case PODXTLIVE_INTERFACE_POD:
+ ret = pod_init(interface, (struct usb_line6_pod *)line6);
+ break;
+
+ case PODXTLIVE_INTERFACE_VARIAX:
+ ret = variax_init(interface, (struct usb_line6_variax *)line6);
+ break;
+
+ default:
+ dev_err(&interface->dev,
+ "PODxt Live interface %d not supported\n",
+ interface_number);
+ ret = -ENODEV;
+ }
+
+ break;
+
+ case LINE6_DEVID_VARIAX:
+ ret = variax_init(interface, (struct usb_line6_variax *)line6);
+ break;
+
+ case LINE6_DEVID_TONEPORT_GX:
+ case LINE6_DEVID_TONEPORT_UX1:
+ case LINE6_DEVID_TONEPORT_UX2:
+ case LINE6_DEVID_GUITARPORT:
+ ret = toneport_init(interface, (struct usb_line6_toneport *)line6);
+ break;
+
+ default:
+ MISSING_CASE;
+ ret = -ENODEV;
+ }
+
+ if (ret < 0) {
+ line6_destruct(interface);
+ return ret;
+ }
+
+ ret = sysfs_create_link(&interface->dev.kobj, &usbdev->dev.kobj,
+ "usb_device");
+ if (ret < 0) {
+ line6_destruct(interface);
+ return ret;
+ }
+
+ dev_info(&interface->dev, "Line6 %s now attached\n",
+ line6->properties->name);
+ line6_devices[devnum] = line6;
+ line6_list_devices();
+ return ret;
+}
+
+/*
+ Line6 device disconnected.
+*/
+static void line6_disconnect(struct usb_interface *interface)
+{
+ struct usb_line6 *line6;
+ struct usb_device *usbdev;
+ int interface_number, i;
+
+ if (interface == NULL)
+ return;
+ usbdev = interface_to_usbdev(interface);
+ if (usbdev == NULL)
+ return;
+
+ sysfs_remove_link(&interface->dev.kobj, "usb_device");
+
+ interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
+ line6 = usb_get_intfdata(interface);
+
+ if (line6 != NULL) {
+ if (line6->urb_listen != NULL)
+ usb_kill_urb(line6->urb_listen);
+
+ if (usbdev != line6->usbdev)
+ dev_err(line6->ifcdev,
+ "driver bug: inconsistent usb device\n");
+
+ switch (line6->usbdev->descriptor.idProduct) {
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_POCKETPOD:
+ case LINE6_DEVID_PODX3:
+ case LINE6_DEVID_PODX3LIVE:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTPRO:
+ pod_disconnect(interface);
+ break;
+
+ case LINE6_DEVID_PODXTLIVE:
+ switch (interface_number) {
+ case PODXTLIVE_INTERFACE_POD:
+ pod_disconnect(interface);
+ break;
+
+ case PODXTLIVE_INTERFACE_VARIAX:
+ variax_disconnect(interface);
+ break;
+ }
+
+ break;
+
+ case LINE6_DEVID_VARIAX:
+ variax_disconnect(interface);
+ break;
+
+ case LINE6_DEVID_TONEPORT_GX:
+ case LINE6_DEVID_TONEPORT_UX1:
+ case LINE6_DEVID_TONEPORT_UX2:
+ case LINE6_DEVID_GUITARPORT:
+ toneport_disconnect(interface);
+ break;
+
+ default:
+ MISSING_CASE;
+ }
+
+ dev_info(&interface->dev, "Line6 %s now disconnected\n", line6->properties->name);
+
+ for (i = LINE6_MAX_DEVICES; i--;)
+ if (line6_devices[i] == line6)
+ line6_devices[i] = NULL;
+ }
+
+ line6_destruct(interface);
+
+ /* decrement reference counters: */
+ usb_put_intf(interface);
+ usb_put_dev(usbdev);
+
+ line6_list_devices();
+}
+
+static struct usb_driver line6_driver = {
+ .name = DRIVER_NAME,
+ .probe = line6_probe,
+ .disconnect = line6_disconnect,
+ .id_table = line6_id_table,
+};
+
+/*
+ Module initialization.
+*/
+static int __init line6_init(void)
+{
+ int i, retval;
+
+ printk(KERN_INFO "%s driver version %s%s\n",
+ DRIVER_NAME, DRIVER_VERSION, DRIVER_REVISION);
+ line6_workqueue = create_workqueue(DRIVER_NAME);
+
+ if (line6_workqueue == NULL) {
+ err("couldn't create workqueue");
+ return -EINVAL;
+ }
+
+ for (i = LINE6_MAX_DEVICES; i--;)
+ line6_devices[i] = NULL;
+
+ retval = usb_register(&line6_driver);
+
+ if (retval)
+ err("usb_register failed. Error number %d", retval);
+
+ return retval;
+}
+
+/*
+ Module cleanup.
+*/
+static void __exit line6_exit(void)
+{
+ destroy_workqueue(line6_workqueue);
+ usb_deregister(&line6_driver);
+}
+
+module_init(line6_init);
+module_exit(line6_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h
new file mode 100644
index 00000000000..9908bfa6afa
--- /dev/null
+++ b/drivers/staging/line6/driver.h
@@ -0,0 +1,204 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+#ifndef DRIVER_H
+#define DRIVER_H
+
+
+#include "config.h"
+
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+#include <sound/core.h>
+
+#include "midi.h"
+
+#define DRIVER_NAME "line6usb"
+
+#define LINE6_TIMEOUT 1
+#define LINE6_MAX_DEVICES 8
+#define LINE6_BUFSIZE_LISTEN 32
+#define LINE6_MESSAGE_MAXLEN 256
+
+
+/*
+ Line6 MIDI control commands
+*/
+#define LINE6_PARAM_CHANGE 0xb0
+#define LINE6_PROGRAM_CHANGE 0xc0
+#define LINE6_SYSEX_BEGIN 0xf0
+#define LINE6_SYSEX_END 0xf7
+#define LINE6_RESET 0xff
+
+/*
+ MIDI channel for messages initiated by the host
+ (and eventually echoed back by the device)
+*/
+#define LINE6_CHANNEL_HOST 0x00
+
+/*
+ MIDI channel for messages initiated by the device
+*/
+#define LINE6_CHANNEL_DEVICE 0x02
+
+#define LINE6_CHANNEL_UNKNOWN 5 /* don't know yet what this is good for */
+
+#define LINE6_CHANNEL_MASK 0x0f
+
+
+#define MISSING_CASE \
+ printk(KERN_ERR "line6usb driver bug: missing case in %s:%d\n", \
+ __FILE__, __LINE__)
+
+
+#define CHECK_RETURN(x) \
+do { \
+ err = x; \
+ if (err < 0) \
+ return err; \
+} while (0)
+
+
+extern const unsigned char line6_midi_id[3];
+extern struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
+extern struct workqueue_struct *line6_workqueue;
+
+static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3;
+static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4;
+
+
+/**
+ Common properties of Line6 devices.
+*/
+struct line6_properties {
+ const char *name;
+ int device_bit;
+ int capabilities;
+};
+
+/**
+ Common data shared by all Line6 devices.
+ Corresponds to a pair of USB endpoints.
+*/
+struct usb_line6 {
+ /**
+ USB device.
+ */
+ struct usb_device *usbdev;
+
+ /**
+ Product id.
+ */
+ int product;
+
+ /**
+ Properties.
+ */
+ const struct line6_properties *properties;
+
+ /**
+ Interface number.
+ */
+ int interface_number;
+
+ /**
+ Interval (ms).
+ */
+ int interval;
+
+ /**
+ Maximum size of USB packet.
+ */
+ int max_packet_size;
+
+ /**
+ Device representing the USB interface.
+ */
+ struct device *ifcdev;
+
+ /**
+ Line6 sound card data structure.
+ Each device has at least MIDI or PCM.
+ */
+ struct snd_card *card;
+
+ /**
+ Line6 PCM device data structure.
+ */
+ struct snd_line6_pcm *line6pcm;
+
+ /**
+ Line6 MIDI device data structure.
+ */
+ struct snd_line6_midi *line6midi;
+
+ /**
+ USB endpoint for listening to control commands.
+ */
+ int ep_control_read;
+
+ /**
+ USB endpoint for writing control commands.
+ */
+ int ep_control_write;
+
+ /**
+ URB for listening to PODxt Pro control endpoint.
+ */
+ struct urb *urb_listen;
+
+ /**
+ Buffer for listening to PODxt Pro control endpoint.
+ */
+ unsigned char *buffer_listen;
+
+ /**
+ Buffer for message to be processed.
+ */
+ unsigned char *buffer_message;
+
+ /**
+ Length of message to be processed.
+ */
+ int message_length;
+};
+
+
+extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1,
+ int code2, int size);
+extern ssize_t line6_nop_read(struct device *dev,
+ struct device_attribute *attr, char *buf);
+extern ssize_t line6_nop_write(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+extern int line6_read_data(struct usb_line6 *line6, int address, void *data,
+ size_t datalen);
+extern int line6_read_serial_number(struct usb_line6 *line6,
+ int *serial_number);
+extern int line6_send_program(struct usb_line6 *line6, int value);
+extern int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
+ int size);
+extern int line6_send_raw_message_async(struct usb_line6 *line6,
+ const char *buffer, int size);
+extern int line6_send_sysex_message(struct usb_line6 *line6,
+ const char *buffer, int size);
+extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count);
+extern int line6_transmit_parameter(struct usb_line6 *line6, int param,
+ int value);
+extern int line6_write_data(struct usb_line6 *line6, int address, void *data,
+ size_t datalen);
+extern void line6_write_hexdump(struct usb_line6 *line6, char dir,
+ const unsigned char *buffer, int size);
+
+
+#endif
diff --git a/drivers/staging/line6/dumprequest.c b/drivers/staging/line6/dumprequest.c
new file mode 100644
index 00000000000..decbaa971b6
--- /dev/null
+++ b/drivers/staging/line6/dumprequest.c
@@ -0,0 +1,151 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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 "driver.h"
+#include "dumprequest.h"
+
+
+/*
+ Set "dump in progress" flag.
+*/
+void line6_dump_started(struct line6_dump_request *l6dr, int dest)
+{
+ l6dr->in_progress = dest;
+}
+
+/*
+ Invalidate current channel, i.e., set "dump in progress" flag.
+ Reading from the "dump" special file blocks until dump is completed.
+*/
+void line6_invalidate_current(struct line6_dump_request *l6dr)
+{
+ line6_dump_started(l6dr, LINE6_DUMP_CURRENT);
+}
+
+/*
+ Clear "dump in progress" flag and notify waiting processes.
+*/
+void line6_dump_finished(struct line6_dump_request *l6dr)
+{
+ l6dr->in_progress = LINE6_DUMP_NONE;
+ wake_up_interruptible(&l6dr->wait);
+}
+
+/*
+ Send an asynchronous channel dump request.
+*/
+int line6_dump_request_async(struct line6_dump_request *l6dr,
+ struct usb_line6 *line6, int num)
+{
+ int ret;
+ line6_invalidate_current(l6dr);
+ ret = line6_send_raw_message_async(line6, l6dr->reqbufs[num].buffer,
+ l6dr->reqbufs[num].length);
+
+ if (ret < 0)
+ line6_dump_finished(l6dr);
+
+ return ret;
+}
+
+/*
+ Send an asynchronous dump request after a given interval.
+*/
+void line6_startup_delayed(struct line6_dump_request *l6dr, int seconds,
+ void (*function)(unsigned long), void *data)
+{
+ l6dr->timer.expires = jiffies + seconds * HZ;
+ l6dr->timer.function = function;
+ l6dr->timer.data = (unsigned long)data;
+ add_timer(&l6dr->timer);
+}
+
+/*
+ Wait for completion.
+*/
+int line6_wait_dump(struct line6_dump_request *l6dr, int nonblock)
+{
+ int retval = 0;
+ DECLARE_WAITQUEUE(wait, current);
+ add_wait_queue(&l6dr->wait, &wait);
+ current->state = TASK_INTERRUPTIBLE;
+
+ while (l6dr->in_progress) {
+ if (nonblock) {
+ retval = -EAGAIN;
+ break;
+ }
+
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ break;
+ } else
+ schedule();
+ }
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&l6dr->wait, &wait);
+ return retval;
+}
+
+/*
+ Initialize dump request buffer.
+*/
+int line6_dumpreq_initbuf(struct line6_dump_request *l6dr, const void *buf,
+ size_t len, int num)
+{
+ l6dr->reqbufs[num].buffer = kmalloc(len, GFP_KERNEL);
+ if (l6dr->reqbufs[num].buffer == NULL)
+ return -ENOMEM;
+ memcpy(l6dr->reqbufs[num].buffer, buf, len);
+ l6dr->reqbufs[num].length = len;
+ return 0;
+}
+
+/*
+ Initialize dump request data structure (including one buffer).
+*/
+int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf,
+ size_t len)
+{
+ int ret;
+ ret = line6_dumpreq_initbuf(l6dr, buf, len, 0);
+ if (ret < 0)
+ return ret;
+ init_waitqueue_head(&l6dr->wait);
+ init_timer(&l6dr->timer);
+ return 0;
+}
+
+/*
+ Destruct dump request data structure.
+*/
+void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num)
+{
+ if (l6dr == NULL)
+ return;
+ if (l6dr->reqbufs[num].buffer == NULL)
+ return;
+ kfree(l6dr->reqbufs[num].buffer);
+ l6dr->reqbufs[num].buffer = NULL;
+}
+
+/*
+ Destruct dump request data structure.
+*/
+void line6_dumpreq_destruct(struct line6_dump_request *l6dr)
+{
+ if (l6dr->reqbufs[0].buffer == NULL)
+ return;
+ line6_dumpreq_destructbuf(l6dr, 0);
+ l6dr->ok = 1;
+ del_timer_sync(&l6dr->timer);
+}
diff --git a/drivers/staging/line6/dumprequest.h b/drivers/staging/line6/dumprequest.h
new file mode 100644
index 00000000000..1975d54b3c2
--- /dev/null
+++ b/drivers/staging/line6/dumprequest.h
@@ -0,0 +1,90 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+#ifndef DUMPREQUEST_H
+#define DUMPREQUEST_H
+
+
+#include <linux/usb.h>
+#include <linux/wait.h>
+
+#include <sound/core.h>
+
+
+enum {
+ LINE6_DUMP_NONE,
+ LINE6_DUMP_CURRENT
+};
+
+
+struct line6_dump_reqbuf {
+ /**
+ Buffer for dump requests.
+ */
+ unsigned char *buffer;
+
+ /**
+ Size of dump request.
+ */
+ size_t length;
+};
+
+/**
+ Provides the functionality to request channel/model/... dump data from a
+ Line6 device.
+*/
+struct line6_dump_request {
+ /**
+ Wait queue for access to program dump data.
+ */
+ wait_queue_head_t wait;
+
+ /**
+ Indicates an unfinished program dump request.
+ 0: no dump
+ 1: dump current settings
+ Other device-specific values are also allowed.
+ */
+ int in_progress;
+
+ /**
+ Timer for delayed dump request.
+ */
+ struct timer_list timer;
+
+ /**
+ Flag if initial dump request has been successful.
+ */
+ char ok;
+
+ /**
+ Dump request buffers
+ */
+ struct line6_dump_reqbuf reqbufs[1];
+};
+
+extern void line6_dump_finished(struct line6_dump_request *l6dr);
+extern int line6_dump_request_async(struct line6_dump_request *l6dr,
+ struct usb_line6 *line6, int num);
+extern void line6_dump_started(struct line6_dump_request *l6dr, int dest);
+extern void line6_dumpreq_destruct(struct line6_dump_request *l6dr);
+extern void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num);
+extern int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf,
+ size_t len);
+extern int line6_dumpreq_initbuf(struct line6_dump_request *l6dr,
+ const void *buf, size_t len, int num);
+extern void line6_invalidate_current(struct line6_dump_request *l6dr);
+extern void line6_startup_delayed(struct line6_dump_request *l6dr, int seconds,
+ void (*function)(unsigned long), void *data);
+extern int line6_wait_dump(struct line6_dump_request *l6dr, int nonblock);
+
+
+#endif
diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c
new file mode 100644
index 00000000000..89a2b17e9ca
--- /dev/null
+++ b/drivers/staging/line6/midi.c
@@ -0,0 +1,422 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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 "driver.h"
+
+#include <linux/usb.h>
+
+#include <sound/core.h>
+#include <sound/rawmidi.h>
+
+#include "audio.h"
+#include "midi.h"
+#include "pod.h"
+#include "usbdefs.h"
+
+
+#define USE_MIDIBUF 1
+#define OUTPUT_DUMP_ONLY 0
+
+
+#define line6_rawmidi_substream_midi(substream) \
+ ((struct snd_line6_midi *)((substream)->rmidi->private_data))
+
+
+static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
+ int length);
+
+
+/*
+ Pass data received via USB to MIDI.
+*/
+void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
+ int length)
+{
+ if (line6->line6midi->substream_receive)
+ snd_rawmidi_receive(line6->line6midi->substream_receive,
+ data, length);
+}
+
+/*
+ Read data from MIDI buffer and transmit them via USB.
+*/
+static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
+{
+ struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+ struct snd_line6_midi *line6midi = line6->line6midi;
+ struct MidiBuffer *mb = &line6midi->midibuf_out;
+ unsigned long flags;
+ unsigned char chunk[line6->max_packet_size];
+ int req, done;
+
+ spin_lock_irqsave(&line6->line6midi->midi_transmit_lock, flags);
+
+ for (;;) {
+ req = min(midibuf_bytes_free(mb), line6->max_packet_size);
+ done = snd_rawmidi_transmit_peek(substream, chunk, req);
+
+ if (done == 0)
+ break;
+
+#if DO_DUMP_MIDI_SEND
+ line6_write_hexdump(line6, 's', chunk, done);
+#endif
+ midibuf_write(mb, chunk, done);
+ snd_rawmidi_transmit_ack(substream, done);
+ }
+
+ for (;;) {
+ done = midibuf_read(mb, chunk, line6->max_packet_size);
+
+ if (done == 0)
+ break;
+
+ if (midibuf_skip_message(mb, line6midi->midi_mask_transmit))
+ continue;
+
+ send_midi_async(line6, chunk, done);
+ }
+
+ spin_unlock_irqrestore(&line6->line6midi->midi_transmit_lock, flags);
+}
+
+/*
+ Notification of completion of MIDI transmission.
+*/
+static void midi_sent(struct urb *urb)
+{
+ unsigned long flags;
+ int status;
+ int num;
+ struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
+
+ status = urb->status;
+ kfree(urb->transfer_buffer);
+ usb_free_urb(urb);
+
+ if (status == -ESHUTDOWN)
+ return;
+
+ spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags);
+ num = --line6->line6midi->num_active_send_urbs;
+
+ if (num == 0) {
+ line6_midi_transmit(line6->line6midi->substream_transmit);
+ num = line6->line6midi->num_active_send_urbs;
+ }
+
+ if (num == 0)
+ wake_up_interruptible(&line6->line6midi->send_wait);
+
+ spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags);
+}
+
+/*
+ Send an asynchronous MIDI message.
+ Assumes that line6->line6midi->send_urb_lock is held
+ (i.e., this function is serialized).
+*/
+static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
+ int length)
+{
+ struct urb *urb;
+ int retval;
+ unsigned char *transfer_buffer;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+ if (urb == 0) {
+ dev_err(line6->ifcdev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+#if DO_DUMP_URB_SEND
+ line6_write_hexdump(line6, 'S', data, length);
+#endif
+
+ transfer_buffer = kmalloc(length, GFP_ATOMIC);
+
+ if (transfer_buffer == 0) {
+ usb_free_urb(urb);
+ dev_err(line6->ifcdev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+ memcpy(transfer_buffer, data, length);
+ usb_fill_int_urb(urb, line6->usbdev,
+ usb_sndbulkpipe(line6->usbdev,
+ line6->ep_control_write),
+ transfer_buffer, length, midi_sent, line6,
+ line6->interval);
+ urb->actual_length = 0;
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+
+ if (retval < 0) {
+ dev_err(line6->ifcdev, "usb_submit_urb failed\n");
+ usb_free_urb(urb);
+ return -EINVAL;
+ }
+
+ ++line6->line6midi->num_active_send_urbs;
+
+ switch (line6->usbdev->descriptor.idProduct) {
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTLIVE:
+ case LINE6_DEVID_PODXTPRO:
+ case LINE6_DEVID_POCKETPOD:
+ pod_midi_postprocess((struct usb_line6_pod *)line6, data,
+ length);
+ break;
+
+ default:
+ MISSING_CASE;
+ }
+
+ return 0;
+}
+
+static int line6_midi_output_open(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+static int line6_midi_output_close(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream,
+ int up)
+{
+ unsigned long flags;
+ struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+
+ line6->line6midi->substream_transmit = substream;
+ spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags);
+
+ if (line6->line6midi->num_active_send_urbs == 0)
+ line6_midi_transmit(substream);
+
+ spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags);
+}
+
+static void line6_midi_output_drain(struct snd_rawmidi_substream *substream)
+{
+ struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+ wait_queue_head_t *head = &line6->line6midi->send_wait;
+ DECLARE_WAITQUEUE(wait, current);
+ add_wait_queue(head, &wait);
+ current->state = TASK_INTERRUPTIBLE;
+
+ while (line6->line6midi->num_active_send_urbs > 0)
+ if (signal_pending(current))
+ break;
+ else
+ schedule();
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue(head, &wait);
+}
+
+static int line6_midi_input_open(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+static int line6_midi_input_close(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream,
+ int up)
+{
+ struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+
+ if (up)
+ line6->line6midi->substream_receive = substream;
+ else
+ line6->line6midi->substream_receive = 0;
+}
+
+static struct snd_rawmidi_ops line6_midi_output_ops = {
+ .open = line6_midi_output_open,
+ .close = line6_midi_output_close,
+ .trigger = line6_midi_output_trigger,
+ .drain = line6_midi_output_drain,
+};
+
+static struct snd_rawmidi_ops line6_midi_input_ops = {
+ .open = line6_midi_input_open,
+ .close = line6_midi_input_close,
+ .trigger = line6_midi_input_trigger,
+};
+
+/*
+ Cleanup the Line6 MIDI device.
+*/
+static void line6_cleanup_midi(struct snd_rawmidi *rmidi)
+{
+}
+
+/* Create a MIDI device */
+static int snd_line6_new_midi(struct snd_line6_midi *line6midi)
+{
+ struct snd_rawmidi *rmidi;
+ int err;
+
+ err = snd_rawmidi_new(line6midi->line6->card, "Line6 MIDI", 0, 1, 1,
+ &rmidi);
+ if (err < 0)
+ return err;
+
+ rmidi->private_data = line6midi;
+ rmidi->private_free = line6_cleanup_midi;
+ strcpy(rmidi->name, line6midi->line6->properties->name);
+
+ rmidi->info_flags =
+ SNDRV_RAWMIDI_INFO_OUTPUT |
+ SNDRV_RAWMIDI_INFO_INPUT |
+ SNDRV_RAWMIDI_INFO_DUPLEX;
+
+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
+ &line6_midi_output_ops);
+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
+ &line6_midi_input_ops);
+ return 0;
+}
+
+/*
+ "read" request on "midi_mask_transmit" special file.
+*/
+static ssize_t midi_get_midi_mask_transmit(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+ return sprintf(buf, "%d\n", line6->line6midi->midi_mask_transmit);
+}
+
+/*
+ "write" request on "midi_mask" special file.
+*/
+static ssize_t midi_set_midi_mask_transmit(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+ int value = simple_strtoul(buf, NULL, 10);
+ line6->line6midi->midi_mask_transmit = value;
+ return count;
+}
+
+/*
+ "read" request on "midi_mask_receive" special file.
+*/
+static ssize_t midi_get_midi_mask_receive(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+ return sprintf(buf, "%d\n", line6->line6midi->midi_mask_receive);
+}
+
+/*
+ "write" request on "midi_mask" special file.
+*/
+static ssize_t midi_set_midi_mask_receive(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+ int value = simple_strtoul(buf, NULL, 10);
+ line6->line6midi->midi_mask_receive = value;
+ return count;
+}
+
+static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
+static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive);
+
+/* MIDI device destructor */
+static int snd_line6_midi_free(struct snd_device *device)
+{
+ struct snd_line6_midi *line6midi = device->device_data;
+ device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_transmit);
+ device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_receive);
+ midibuf_destroy(&line6midi->midibuf_in);
+ midibuf_destroy(&line6midi->midibuf_out);
+ return 0;
+}
+
+/*
+ Initialize the Line6 MIDI subsystem.
+*/
+int line6_init_midi(struct usb_line6 *line6)
+{
+ static struct snd_device_ops midi_ops = {
+ .dev_free = snd_line6_midi_free,
+ };
+
+ int err;
+ struct snd_line6_midi *line6midi;
+
+ if (!(line6->properties->capabilities & LINE6_BIT_CONTROL))
+ return 0; /* skip MIDI initialization and report success */
+
+ line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL);
+
+ if (line6midi == NULL)
+ return -ENOMEM;
+
+ err = midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
+ if (err < 0)
+ return err;
+
+ err = midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1);
+ if (err < 0)
+ return err;
+
+ line6midi->line6 = line6;
+ line6midi->midi_mask_transmit = 1;
+ line6midi->midi_mask_receive = 4;
+ line6->line6midi = line6midi;
+
+ err = snd_device_new(line6->card, SNDRV_DEV_RAWMIDI, line6midi,
+ &midi_ops);
+ if (err < 0)
+ return err;
+
+ snd_card_set_dev(line6->card, line6->ifcdev);
+
+ err = snd_line6_new_midi(line6midi);
+ if (err < 0)
+ return err;
+
+ err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_transmit);
+ if (err < 0)
+ return err;
+
+ err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_receive);
+ if (err < 0)
+ return err;
+
+ init_waitqueue_head(&line6midi->send_wait);
+ spin_lock_init(&line6midi->send_urb_lock);
+ spin_lock_init(&line6midi->midi_transmit_lock);
+ return 0;
+}
diff --git a/drivers/staging/line6/midi.h b/drivers/staging/line6/midi.h
new file mode 100644
index 00000000000..c69fd118957
--- /dev/null
+++ b/drivers/staging/line6/midi.h
@@ -0,0 +1,87 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+#ifndef MIDI_H
+#define MIDI_H
+
+
+#include <sound/rawmidi.h>
+
+#include "midibuf.h"
+
+
+#define MIDI_BUFFER_SIZE 1024
+
+
+struct snd_line6_midi {
+ /**
+ Pointer back to the Line6 driver data structure.
+ */
+ struct usb_line6 *line6;
+
+ /**
+ MIDI substream for receiving (or NULL if not active).
+ */
+ struct snd_rawmidi_substream *substream_receive;
+
+ /**
+ MIDI substream for transmitting (or NULL if not active).
+ */
+ struct snd_rawmidi_substream *substream_transmit;
+
+ /**
+ Number of currently active MIDI send URBs.
+ */
+ int num_active_send_urbs;
+
+ /**
+ Spin lock to protect updates of send_urb.
+ */
+ spinlock_t send_urb_lock;
+
+ /**
+ Spin lock to protect MIDI buffer handling.
+ */
+ spinlock_t midi_transmit_lock;
+
+ /**
+ Wait queue for MIDI transmission.
+ */
+ wait_queue_head_t send_wait;
+
+ /**
+ Bit mask for output MIDI channels.
+ */
+ int midi_mask_transmit;
+
+ /**
+ Bit mask for input MIDI channels.
+ */
+ int midi_mask_receive;
+
+ /**
+ Buffer for incoming MIDI stream.
+ */
+ struct MidiBuffer midibuf_in;
+
+ /**
+ Buffer for outgoing MIDI stream.
+ */
+ struct MidiBuffer midibuf_out;
+};
+
+
+extern int line6_init_midi(struct usb_line6 *line6);
+extern void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
+ int length);
+
+
+#endif
diff --git a/drivers/staging/line6/midibuf.c b/drivers/staging/line6/midibuf.c
new file mode 100644
index 00000000000..ab0a5f30fbc
--- /dev/null
+++ b/drivers/staging/line6/midibuf.c
@@ -0,0 +1,262 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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 "config.h"
+
+#include <linux/slab.h>
+
+#include "midibuf.h"
+
+
+static int midibuf_message_length(unsigned char code)
+{
+ if (code < 0x80)
+ return -1;
+ else if (code < 0xf0) {
+ static const int length[] = { 3, 3, 3, 3, 2, 2, 3 };
+ return length[(code >> 4) - 8];
+ } else {
+ /*
+ Note that according to the MIDI specification 0xf2 is
+ the "Song Position Pointer", but this is used by Line6
+ to send sysex messages to the host.
+ */
+ static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
+ 1, 1, 1, -1, 1, 1 };
+ return length[code & 0x0f];
+ }
+}
+
+void midibuf_reset(struct MidiBuffer *this)
+{
+ this->pos_read = this->pos_write = this->full = 0;
+ this->command_prev = -1;
+}
+
+int midibuf_init(struct MidiBuffer *this, int size, int split)
+{
+ this->buf = kmalloc(size, GFP_KERNEL);
+
+ if (this->buf == NULL)
+ return -ENOMEM;
+
+ this->size = size;
+ this->split = split;
+ midibuf_reset(this);
+ return 0;
+}
+
+void midibuf_status(struct MidiBuffer *this)
+{
+ printk(KERN_DEBUG "midibuf size=%d split=%d pos_read=%d pos_write=%d "
+ "full=%d command_prev=%02x\n", this->size, this->split,
+ this->pos_read, this->pos_write, this->full, this->command_prev);
+}
+
+static int midibuf_is_empty(struct MidiBuffer *this)
+{
+ return (this->pos_read == this->pos_write) && !this->full;
+}
+
+static int midibuf_is_full(struct MidiBuffer *this)
+{
+ return this->full;
+}
+
+int midibuf_bytes_free(struct MidiBuffer *this)
+{
+ return
+ midibuf_is_full(this) ?
+ 0 :
+ (this->pos_read - this->pos_write + this->size - 1) % this->size + 1;
+}
+
+int midibuf_bytes_used(struct MidiBuffer *this)
+{
+ return
+ midibuf_is_empty(this) ?
+ 0 :
+ (this->pos_write - this->pos_read + this->size - 1) % this->size + 1;
+}
+
+int midibuf_write(struct MidiBuffer *this, unsigned char *data, int length)
+{
+ int bytes_free;
+ int length1, length2;
+ int skip_active_sense = 0;
+
+ if (midibuf_is_full(this) || (length <= 0))
+ return 0;
+
+ /* skip trailing active sense */
+ if (data[length - 1] == 0xfe) {
+ --length;
+ skip_active_sense = 1;
+ }
+
+ bytes_free = midibuf_bytes_free(this);
+
+ if (length > bytes_free)
+ length = bytes_free;
+
+ if (length > 0) {
+ length1 = this->size - this->pos_write;
+
+ if (length < length1) {
+ /* no buffer wraparound */
+ memcpy(this->buf + this->pos_write, data, length);
+ this->pos_write += length;
+ } else {
+ /* buffer wraparound */
+ length2 = length - length1;
+ memcpy(this->buf + this->pos_write, data, length1);
+ memcpy(this->buf, data + length1, length2);
+ this->pos_write = length2;
+ }
+
+ if (this->pos_write == this->pos_read)
+ this->full = 1;
+ }
+
+ return length + skip_active_sense;
+}
+
+int midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
+{
+ int bytes_used;
+ int length1, length2;
+ int command;
+ int midi_length;
+ int repeat = 0;
+ int i;
+
+ /* we need to be able to store at least a 3 byte MIDI message */
+ if (length < 3)
+ return -EINVAL;
+
+ if (midibuf_is_empty(this))
+ return 0;
+
+ bytes_used = midibuf_bytes_used(this);
+
+ if (length > bytes_used)
+ length = bytes_used;
+
+ length1 = this->size - this->pos_read;
+
+ /* check MIDI command length */
+ command = this->buf[this->pos_read];
+
+ if (command & 0x80) {
+ midi_length = midibuf_message_length(command);
+ this->command_prev = command;
+ } else {
+ if (this->command_prev > 0) {
+ int midi_length_prev = midibuf_message_length(this->command_prev);
+
+ if (midi_length_prev > 0) {
+ midi_length = midi_length_prev - 1;
+ repeat = 1;
+ } else
+ midi_length = -1;
+ } else
+ midi_length = -1;
+ }
+
+ if (midi_length < 0) {
+ /* search for end of message */
+ if (length < length1) {
+ /* no buffer wraparound */
+ for (i = 1; i < length; ++i)
+ if (this->buf[this->pos_read + i] & 0x80)
+ break;
+
+ midi_length = i;
+ } else {
+ /* buffer wraparound */
+ length2 = length - length1;
+
+ for (i = 1; i < length1; ++i)
+ if (this->buf[this->pos_read + i] & 0x80)
+ break;
+
+ if (i < length1)
+ midi_length = i;
+ else {
+ for (i = 0; i < length2; ++i)
+ if (this->buf[i] & 0x80)
+ break;
+
+ midi_length = length1 + i;
+ }
+ }
+
+ if (midi_length == length)
+ midi_length = -1; /* end of message not found */
+ }
+
+ if (midi_length < 0) {
+ if (!this->split)
+ return 0; /* command is not yet complete */
+ } else {
+ if (length < midi_length)
+ return 0; /* command is not yet complete */
+
+ length = midi_length;
+ }
+
+ if (length < length1) {
+ /* no buffer wraparound */
+ memcpy(data + repeat, this->buf + this->pos_read, length);
+ this->pos_read += length;
+ } else {
+ /* buffer wraparound */
+ length2 = length - length1;
+ memcpy(data + repeat, this->buf + this->pos_read, length1);
+ memcpy(data + repeat + length1, this->buf, length2);
+ this->pos_read = length2;
+ }
+
+ if (repeat)
+ data[0] = this->command_prev;
+
+ this->full = 0;
+ return length + repeat;
+}
+
+int midibuf_ignore(struct MidiBuffer *this, int length)
+{
+ int bytes_used = midibuf_bytes_used(this);
+
+ if (length > bytes_used)
+ length = bytes_used;
+
+ this->pos_read = (this->pos_read + length) % this->size;
+ this->full = 0;
+ return length;
+}
+
+int midibuf_skip_message(struct MidiBuffer *this, unsigned short mask)
+{
+ int cmd = this->command_prev;
+
+ if ((cmd >= 0x80) && (cmd < 0xf0))
+ if ((mask & (1 << (cmd & 0x0f))) == 0)
+ return 1;
+
+ return 0;
+}
+
+void midibuf_destroy(struct MidiBuffer *this)
+{
+ kfree(this->buf);
+ this->buf = NULL;
+}
diff --git a/drivers/staging/line6/midibuf.h b/drivers/staging/line6/midibuf.h
new file mode 100644
index 00000000000..9877581bcd9
--- /dev/null
+++ b/drivers/staging/line6/midibuf.h
@@ -0,0 +1,39 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+#ifndef MIDIBUF_H
+#define MIDIBUF_H
+
+
+struct MidiBuffer {
+ unsigned char *buf;
+ int size;
+ int split;
+ int pos_read, pos_write;
+ int full;
+ int command_prev;
+};
+
+
+extern int midibuf_bytes_used(struct MidiBuffer *mb);
+extern int midibuf_bytes_free(struct MidiBuffer *mb);
+extern void midibuf_destroy(struct MidiBuffer *mb);
+extern int midibuf_ignore(struct MidiBuffer *mb, int length);
+extern int midibuf_init(struct MidiBuffer *mb, int size, int split);
+extern int midibuf_read(struct MidiBuffer *mb, unsigned char *data, int length);
+extern void midibuf_reset(struct MidiBuffer *mb);
+extern int midibuf_skip_message(struct MidiBuffer *mb, unsigned short mask);
+extern void midibuf_status(struct MidiBuffer *mb);
+extern int midibuf_write(struct MidiBuffer *mb, unsigned char *data,
+ int length);
+
+
+#endif
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
new file mode 100644
index 00000000000..fc4113f3315
--- /dev/null
+++ b/drivers/staging/line6/pcm.c
@@ -0,0 +1,301 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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 "driver.h"
+
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include "audio.h"
+#include "capture.h"
+#include "playback.h"
+#include "pod.h"
+
+
+/* trigger callback */
+int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ struct snd_pcm_substream *s;
+ int err;
+ unsigned long flags;
+
+ spin_lock_irqsave(&line6pcm->lock_trigger, flags);
+ clear_bit(BIT_PREPARED, &line6pcm->flags);
+
+ snd_pcm_group_for_each_entry(s, substream) {
+ switch (s->stream) {
+ case SNDRV_PCM_STREAM_PLAYBACK:
+ err = snd_line6_playback_trigger(s, cmd);
+
+ if (err < 0) {
+ spin_unlock_irqrestore(&line6pcm->lock_trigger,
+ flags);
+ return err;
+ }
+
+ break;
+
+ case SNDRV_PCM_STREAM_CAPTURE:
+ err = snd_line6_capture_trigger(s, cmd);
+
+ if (err < 0) {
+ spin_unlock_irqrestore(&line6pcm->lock_trigger,
+ flags);
+ return err;
+ }
+
+ break;
+
+ default:
+ dev_err(s2m(substream), "Unknown stream direction %d\n",
+ s->stream);
+ }
+ }
+
+ spin_unlock_irqrestore(&line6pcm->lock_trigger, flags);
+ return 0;
+}
+
+/* control info callback */
+static int snd_line6_control_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 2;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 256;
+ return 0;
+}
+
+/* control get callback */
+static int snd_line6_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int i;
+ struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+ for (i = 2; i--;)
+ ucontrol->value.integer.value[i] = line6pcm->volume[i];
+
+ return 0;
+}
+
+/* control put callback */
+static int snd_line6_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int i, changed = 0;
+ struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+ for (i = 2; i--;)
+ if (line6pcm->volume[i] != ucontrol->value.integer.value[i]) {
+ line6pcm->volume[i] = ucontrol->value.integer.value[i];
+ changed = 1;
+ }
+
+ return changed;
+}
+
+/* control definition */
+static struct snd_kcontrol_new line6_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "PCM Playback Volume",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = snd_line6_control_info,
+ .get = snd_line6_control_get,
+ .put = snd_line6_control_put
+};
+
+/*
+ Cleanup the PCM device.
+*/
+static void line6_cleanup_pcm(struct snd_pcm *pcm)
+{
+ int i;
+ struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
+
+ for (i = LINE6_ISO_BUFFERS; i--;) {
+ if (line6pcm->urb_audio_out[i]) {
+ usb_kill_urb(line6pcm->urb_audio_out[i]);
+ usb_free_urb(line6pcm->urb_audio_out[i]);
+ }
+ if (line6pcm->urb_audio_in[i]) {
+ usb_kill_urb(line6pcm->urb_audio_in[i]);
+ usb_free_urb(line6pcm->urb_audio_in[i]);
+ }
+ }
+}
+
+/* create a PCM device */
+static int snd_line6_new_pcm(struct snd_line6_pcm *line6pcm)
+{
+ struct snd_pcm *pcm;
+ int err;
+
+ err = snd_pcm_new(line6pcm->line6->card,
+ (char *)line6pcm->line6->properties->name,
+ 0, 1, 1, &pcm);
+ if (err < 0)
+ return err;
+
+ pcm->private_data = line6pcm;
+ pcm->private_free = line6_cleanup_pcm;
+ line6pcm->pcm = pcm;
+ strcpy(pcm->name, line6pcm->line6->properties->name);
+
+ /* set operators */
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_line6_playback_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops);
+
+ /* pre-allocation of buffers */
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
+ snd_dma_continuous_data(GFP_KERNEL),
+ 64 * 1024, 128 * 1024);
+
+ return 0;
+}
+
+/* PCM device destructor */
+static int snd_line6_pcm_free(struct snd_device *device)
+{
+ return 0;
+}
+
+/*
+ Create and register the PCM device and mixer entries.
+ Create URBs for playback and capture.
+*/
+int line6_init_pcm(struct usb_line6 *line6,
+ struct line6_pcm_properties *properties)
+{
+ static struct snd_device_ops pcm_ops = {
+ .dev_free = snd_line6_pcm_free,
+ };
+
+ int err;
+ int ep_read = 0, ep_write = 0;
+ struct snd_line6_pcm *line6pcm;
+
+ if (!(line6->properties->capabilities & LINE6_BIT_PCM))
+ return 0; /* skip PCM initialization and report success */
+
+ /* initialize PCM subsystem based on product id: */
+ switch (line6->product) {
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTLIVE:
+ case LINE6_DEVID_PODXTPRO:
+ ep_read = 0x82;
+ ep_write = 0x01;
+ break;
+
+ case LINE6_DEVID_PODX3:
+ case LINE6_DEVID_PODX3LIVE:
+ ep_read = 0x86;
+ ep_write = 0x02;
+ break;
+
+ case LINE6_DEVID_POCKETPOD:
+ ep_read = 0x82;
+ ep_write = 0x02;
+ break;
+
+ case LINE6_DEVID_GUITARPORT:
+ case LINE6_DEVID_TONEPORT_GX:
+ ep_read = 0x82;
+ ep_write = 0x01;
+ break;
+
+ case LINE6_DEVID_TONEPORT_UX1:
+ ep_read = 0x00;
+ ep_write = 0x00;
+ break;
+
+ case LINE6_DEVID_TONEPORT_UX2:
+ ep_read = 0x87;
+ ep_write = 0x00;
+ break;
+
+ default:
+ MISSING_CASE;
+ }
+
+ line6pcm = kzalloc(sizeof(struct snd_line6_pcm), GFP_KERNEL);
+
+ if (line6pcm == NULL)
+ return -ENOMEM;
+
+ line6pcm->volume[0] = line6pcm->volume[1] = 128;
+ line6pcm->line6 = line6;
+ line6pcm->ep_audio_read = ep_read;
+ line6pcm->ep_audio_write = ep_write;
+ line6pcm->max_packet_size = usb_maxpacket(line6->usbdev,
+ usb_rcvintpipe(line6->usbdev,
+ ep_read),
+ 0);
+ line6pcm->properties = properties;
+ line6->line6pcm = line6pcm;
+
+ /* PCM device: */
+ err = snd_device_new(line6->card, SNDRV_DEV_PCM, line6, &pcm_ops);
+ if (err < 0)
+ return err;
+
+ snd_card_set_dev(line6->card, line6->ifcdev);
+
+ err = snd_line6_new_pcm(line6pcm);
+ if (err < 0)
+ return err;
+
+ spin_lock_init(&line6pcm->lock_audio_out);
+ spin_lock_init(&line6pcm->lock_audio_in);
+ spin_lock_init(&line6pcm->lock_trigger);
+
+ err = create_audio_out_urbs(line6pcm);
+ if (err < 0)
+ return err;
+
+ err = create_audio_in_urbs(line6pcm);
+ if (err < 0)
+ return err;
+
+ /* mixer: */
+ err = snd_ctl_add(line6->card, snd_ctl_new1(&line6_control, line6pcm));
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+/* prepare pcm callback */
+int snd_line6_prepare(struct snd_pcm_substream *substream)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+ if (!test_and_set_bit(BIT_PREPARED, &line6pcm->flags)) {
+ unlink_wait_clear_audio_out_urbs(line6pcm);
+ line6pcm->pos_out = 0;
+ line6pcm->pos_out_done = 0;
+
+ unlink_wait_clear_audio_in_urbs(line6pcm);
+ line6pcm->bytes_out = 0;
+ line6pcm->pos_in_done = 0;
+ line6pcm->bytes_in = 0;
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h
new file mode 100644
index 00000000000..53db217cd42
--- /dev/null
+++ b/drivers/staging/line6/pcm.h
@@ -0,0 +1,222 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+/*
+ PCM interface to POD series devices.
+*/
+
+#ifndef PCM_H
+#define PCM_H
+
+
+#include <sound/pcm.h>
+
+#include "driver.h"
+#include "usbdefs.h"
+
+
+/* number of URBs */
+#define LINE6_ISO_BUFFERS 8
+
+/* number of USB frames per URB */
+#define LINE6_ISO_PACKETS 2
+
+/* in a "full speed" device (such as the PODxt Pro) this means 1ms */
+#define LINE6_ISO_INTERVAL 1
+
+/* this should be queried dynamically from the USB interface! */
+#define LINE6_ISO_PACKET_SIZE_MAX 252
+
+
+/*
+ Extract the messaging device from the substream instance
+*/
+#define s2m(s) (((struct snd_line6_pcm *) \
+ snd_pcm_substream_chip(s))->line6->ifcdev)
+
+
+enum {
+ BIT_RUNNING_PLAYBACK,
+ BIT_RUNNING_CAPTURE,
+ BIT_PAUSE_PLAYBACK,
+ BIT_PREPARED
+};
+
+struct line6_pcm_properties {
+ struct snd_pcm_hardware snd_line6_playback_hw, snd_line6_capture_hw;
+ struct snd_pcm_hw_constraint_ratdens snd_line6_rates;
+ int bytes_per_frame;
+};
+
+struct snd_line6_pcm {
+ /**
+ Pointer back to the Line6 driver data structure.
+ */
+ struct usb_line6 *line6;
+
+ /**
+ Properties.
+ */
+ struct line6_pcm_properties *properties;
+
+ /**
+ ALSA pcm stream
+ */
+ struct snd_pcm *pcm;
+
+ /**
+ URBs for audio playback.
+ */
+ struct urb *urb_audio_out[LINE6_ISO_BUFFERS];
+
+ /**
+ URBs for audio capture.
+ */
+ struct urb *urb_audio_in[LINE6_ISO_BUFFERS];
+
+ /**
+ Temporary buffer to hold data when playback buffer wraps.
+ */
+ unsigned char *wrap_out;
+
+ /**
+ Temporary buffer for capture.
+ Since the packet size is not known in advance, this buffer is
+ large enough to store maximum size packets.
+ */
+ unsigned char *buffer_in;
+
+ /**
+ Free frame position in the playback buffer.
+ */
+ snd_pcm_uframes_t pos_out;
+
+ /**
+ Count processed bytes for playback.
+ This is modulo period size (to determine when a period is
+ finished).
+ */
+ unsigned bytes_out;
+
+ /**
+ Counter to create desired playback sample rate.
+ */
+ unsigned count_out;
+
+ /**
+ Playback period size in bytes
+ */
+ unsigned period_out;
+
+ /**
+ Processed frame position in the playback buffer.
+ The contents of the output ring buffer have been consumed by
+ the USB subsystem (i.e., sent to the USB device) up to this
+ position.
+ */
+ snd_pcm_uframes_t pos_out_done;
+
+ /**
+ Count processed bytes for capture.
+ This is modulo period size (to determine when a period is
+ finished).
+ */
+ unsigned bytes_in;
+
+ /**
+ Counter to create desired capture sample rate.
+ */
+ unsigned count_in;
+
+ /**
+ Capture period size in bytes
+ */
+ unsigned period_in;
+
+ /**
+ Processed frame position in the capture buffer.
+ The contents of the output ring buffer have been consumed by
+ the USB subsystem (i.e., sent to the USB device) up to this
+ position.
+ */
+ snd_pcm_uframes_t pos_in_done;
+
+ /**
+ Bit mask of active playback URBs.
+ */
+ unsigned long active_urb_out;
+
+ /**
+ Maximum size of USB packet.
+ */
+ int max_packet_size;
+
+ /**
+ USB endpoint for listening to audio data.
+ */
+ int ep_audio_read;
+
+ /**
+ USB endpoint for writing audio data.
+ */
+ int ep_audio_write;
+
+ /**
+ Bit mask of active capture URBs.
+ */
+ unsigned long active_urb_in;
+
+ /**
+ Bit mask of playback URBs currently being unlinked.
+ */
+ unsigned long unlink_urb_out;
+
+ /**
+ Bit mask of capture URBs currently being unlinked.
+ */
+ unsigned long unlink_urb_in;
+
+ /**
+ Spin lock to protect updates of the playback buffer positions (not
+ contents!)
+ */
+ spinlock_t lock_audio_out;
+
+ /**
+ Spin lock to protect updates of the capture buffer positions (not
+ contents!)
+ */
+ spinlock_t lock_audio_in;
+
+ /**
+ Spin lock to protect trigger.
+ */
+ spinlock_t lock_trigger;
+
+ /**
+ PCM playback volume (left and right).
+ */
+ int volume[2];
+
+ /**
+ Several status bits (see BIT_*).
+ */
+ unsigned long flags;
+};
+
+
+extern int line6_init_pcm(struct usb_line6 *line6,
+ struct line6_pcm_properties *properties);
+extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);
+extern int snd_line6_prepare(struct snd_pcm_substream *substream);
+
+
+#endif
diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c
new file mode 100644
index 00000000000..acb06126a6a
--- /dev/null
+++ b/drivers/staging/line6/playback.c
@@ -0,0 +1,427 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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 "driver.h"
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include "audio.h"
+#include "pcm.h"
+#include "pod.h"
+#include "playback.h"
+
+
+/*
+ Software stereo volume control.
+*/
+static void change_volume(struct urb *urb_out, int volume[],
+ int bytes_per_frame)
+{
+ int chn = 0;
+
+ if (volume[0] == 256 && volume[1] == 256)
+ return; /* maximum volume - no change */
+
+ if (bytes_per_frame == 4) {
+ short *p, *buf_end;
+ p = (short *)urb_out->transfer_buffer;
+ buf_end = p + urb_out->transfer_buffer_length / sizeof(*p);
+
+ for (; p < buf_end; ++p) {
+ *p = (*p * volume[chn & 1]) >> 8;
+ ++chn;
+ }
+ } else if (bytes_per_frame == 6) {
+ unsigned char *p, *buf_end;
+ p = (unsigned char *)urb_out->transfer_buffer;
+ buf_end = p + urb_out->transfer_buffer_length;
+
+ for (; p < buf_end; p += 3) {
+ int val;
+ val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16);
+ val = (val * volume[chn & 1]) >> 8;
+ p[0] = val;
+ p[1] = val >> 8;
+ p[2] = val >> 16;
+ ++chn;
+ }
+ }
+}
+
+/*
+ Find a free URB, prepare audio data, and submit URB.
+*/
+static int submit_audio_out_urb(struct snd_pcm_substream *substream)
+{
+ int index;
+ unsigned long flags;
+ int i, urb_size, urb_frames;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
+ const int frame_increment = line6pcm->properties->snd_line6_rates.rats[0].num_min;
+ const int frame_factor = line6pcm->properties->snd_line6_rates.rats[0].den * (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct urb *urb_out;
+
+ spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
+ index = find_first_zero_bit(&line6pcm->active_urb_out, LINE6_ISO_BUFFERS);
+
+ if (index < 0 || index >= LINE6_ISO_BUFFERS) {
+ spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+ dev_err(s2m(substream), "no free URB found\n");
+ return -EINVAL;
+ }
+
+ urb_out = line6pcm->urb_audio_out[index];
+ urb_size = 0;
+
+ for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+ /* compute frame size for given sampling rate */
+ int n, fs;
+ struct usb_iso_packet_descriptor *fout = &urb_out->iso_frame_desc[i];
+ line6pcm->count_out += frame_increment;
+ n = line6pcm->count_out / frame_factor;
+ line6pcm->count_out -= n * frame_factor;
+ fs = n * bytes_per_frame;
+ fout->offset = urb_size;
+ fout->length = fs;
+ urb_size += fs;
+ }
+
+ urb_frames = urb_size / bytes_per_frame;
+
+ if (test_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags)) {
+ urb_out->transfer_buffer = line6pcm->wrap_out;
+ memset(line6pcm->wrap_out, 0, urb_size);
+ } else {
+ if (line6pcm->pos_out + urb_frames > runtime->buffer_size) {
+ /*
+ The transferred area goes over buffer boundary,
+ copy the data to the temp buffer.
+ */
+ int len;
+ len = runtime->buffer_size - line6pcm->pos_out;
+ urb_out->transfer_buffer = line6pcm->wrap_out;
+
+ if (len > 0) {
+ memcpy(line6pcm->wrap_out, runtime->dma_area + line6pcm->pos_out * bytes_per_frame, len * bytes_per_frame);
+ memcpy(line6pcm->wrap_out + len * bytes_per_frame, runtime->dma_area, (urb_frames - len) * bytes_per_frame);
+ } else
+ dev_err(s2m(substream), "driver bug: len = %d\n", len); /* this is somewhat paranoid */
+ } else {
+ /* set the buffer pointer */
+ urb_out->transfer_buffer = runtime->dma_area + line6pcm->pos_out * bytes_per_frame;
+ }
+ }
+
+ if ((line6pcm->pos_out += urb_frames) >= runtime->buffer_size)
+ line6pcm->pos_out -= runtime->buffer_size;
+
+ urb_out->transfer_buffer_length = urb_size;
+ urb_out->context = substream;
+ change_volume(urb_out, line6pcm->volume, bytes_per_frame);
+
+#if DO_DUMP_PCM_SEND
+ for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+ struct usb_iso_packet_descriptor *fout = &urb_out->iso_frame_desc[i];
+ line6_write_hexdump(line6pcm->line6, 'P', urb_out->transfer_buffer + fout->offset, fout->length);
+ }
+#endif
+
+ if (usb_submit_urb(urb_out, GFP_ATOMIC) == 0)
+ set_bit(index, &line6pcm->active_urb_out);
+ else
+ dev_err(s2m(substream), "URB out #%d submission failed\n", index);
+
+ spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+ return 0;
+}
+
+/*
+ Submit all currently available playback URBs.
+*/
+static int submit_audio_out_all_urbs(struct snd_pcm_substream *substream)
+{
+ int ret, i;
+
+ for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+ ret = submit_audio_out_urb(substream);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ Unlink all currently active playback URBs.
+*/
+static void unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+{
+ unsigned int i;
+
+ for (i = LINE6_ISO_BUFFERS; i--;) {
+ if (test_bit(i, &line6pcm->active_urb_out)) {
+ if (!test_and_set_bit(i, &line6pcm->unlink_urb_out)) {
+ struct urb *u = line6pcm->urb_audio_out[i];
+ usb_unlink_urb(u);
+ }
+ }
+ }
+}
+
+/*
+ Wait until unlinking of all currently active playback URBs has been finished.
+*/
+static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+{
+ int timeout = HZ;
+ unsigned int i;
+ int alive;
+
+ do {
+ alive = 0;
+ for (i = LINE6_ISO_BUFFERS; i--;) {
+ if (test_bit(i, &line6pcm->active_urb_out))
+ alive++;
+ }
+ if (!alive)
+ break;
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1);
+ } while (--timeout > 0);
+ if (alive)
+ snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
+
+ line6pcm->active_urb_out = 0;
+ line6pcm->unlink_urb_out = 0;
+}
+
+/*
+ Unlink all currently active playback URBs, and wait for finishing.
+*/
+void unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+{
+ unlink_audio_out_urbs(line6pcm);
+ wait_clear_audio_out_urbs(line6pcm);
+}
+
+/*
+ Callback for completed playback URB.
+*/
+static void audio_out_callback(struct urb *urb)
+{
+ int i, index, length = 0, shutdown = 0;
+ unsigned long flags;
+
+ struct snd_pcm_substream *substream = (struct snd_pcm_substream *)urb->context;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ /* find index of URB */
+ for (index = LINE6_ISO_BUFFERS; index--;)
+ if (urb == line6pcm->urb_audio_out[index])
+ break;
+
+ if (index < 0)
+ return; /* URB has been unlinked asynchronously */
+
+ for (i = LINE6_ISO_PACKETS; i--;)
+ length += urb->iso_frame_desc[i].length;
+
+ spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
+ line6pcm->pos_out_done += length / line6pcm->properties->bytes_per_frame;
+
+ if (line6pcm->pos_out_done >= runtime->buffer_size)
+ line6pcm->pos_out_done -= runtime->buffer_size;
+
+ clear_bit(index, &line6pcm->active_urb_out);
+
+ for (i = LINE6_ISO_PACKETS; i--;)
+ if (urb->iso_frame_desc[i].status == -ESHUTDOWN) {
+ shutdown = 1;
+ break;
+ }
+
+ if (test_bit(index, &line6pcm->unlink_urb_out))
+ shutdown = 1;
+
+ spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+
+ if (!shutdown) {
+ submit_audio_out_urb(substream);
+
+ if ((line6pcm->bytes_out += length) >= line6pcm->period_out) {
+ line6pcm->bytes_out -= line6pcm->period_out;
+ snd_pcm_period_elapsed(substream);
+ }
+ }
+}
+
+/* open playback callback */
+static int snd_line6_playback_open(struct snd_pcm_substream *substream)
+{
+ int err;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+ err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ (&line6pcm->properties->snd_line6_rates));
+ if (err < 0)
+ return err;
+
+ runtime->hw = line6pcm->properties->snd_line6_playback_hw;
+ return 0;
+}
+
+/* close playback callback */
+static int snd_line6_playback_close(struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
+/* hw_params playback callback */
+static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params)
+{
+ int ret;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+ /* -- Florian Demski [FD] */
+ /* don't ask me why, but this fixes the bug on my machine */
+ if (line6pcm == NULL) {
+ if (substream->pcm == NULL)
+ return -ENOMEM;
+ if (substream->pcm->private_data == NULL)
+ return -ENOMEM;
+ substream->private_data = substream->pcm->private_data;
+ line6pcm = snd_pcm_substream_chip(substream);
+ }
+ /* -- [FD] end */
+
+ ret = snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+ if (ret < 0)
+ return ret;
+
+ line6pcm->period_out = params_period_bytes(hw_params);
+ line6pcm->wrap_out = kmalloc(2 * LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL);
+
+ if (!line6pcm->wrap_out) {
+ dev_err(s2m(substream), "cannot malloc wrap_out\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/* hw_free playback callback */
+static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ unlink_wait_clear_audio_out_urbs(line6pcm);
+
+ kfree(line6pcm->wrap_out);
+ line6pcm->wrap_out = NULL;
+
+ return snd_pcm_lib_free_pages(substream);
+}
+
+/* trigger playback callback */
+int snd_line6_playback_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ int err;
+ line6pcm->count_out = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ if (!test_and_set_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags)) {
+ err = submit_audio_out_all_urbs(substream);
+
+ if (err < 0) {
+ clear_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags);
+ return err;
+ }
+ }
+
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ if (test_and_clear_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags))
+ unlink_audio_out_urbs(line6pcm);
+
+ break;
+
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ set_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags);
+ break;
+
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ clear_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* playback pointer callback */
+static snd_pcm_uframes_t
+snd_line6_playback_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ return line6pcm->pos_out_done;
+}
+
+/* playback operators */
+struct snd_pcm_ops snd_line6_playback_ops = {
+ .open = snd_line6_playback_open,
+ .close = snd_line6_playback_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_line6_playback_hw_params,
+ .hw_free = snd_line6_playback_hw_free,
+ .prepare = snd_line6_prepare,
+ .trigger = snd_line6_trigger,
+ .pointer = snd_line6_playback_pointer,
+};
+
+int create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+{
+ int i;
+
+ /* create audio URBs and fill in constant values: */
+ for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+ struct urb *urb;
+
+ /* URB for audio out: */
+ urb = line6pcm->urb_audio_out[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
+
+ if (urb == NULL) {
+ dev_err(line6pcm->line6->ifcdev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+ urb->dev = line6pcm->line6->usbdev;
+ urb->pipe = usb_sndisocpipe(line6pcm->line6->usbdev, line6pcm->ep_audio_write & USB_ENDPOINT_NUMBER_MASK);
+ urb->transfer_flags = URB_ISO_ASAP;
+ urb->start_frame = -1;
+ urb->number_of_packets = LINE6_ISO_PACKETS;
+ urb->interval = LINE6_ISO_INTERVAL;
+ urb->error_count = 0;
+ urb->complete = audio_out_callback;
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/line6/playback.h b/drivers/staging/line6/playback.h
new file mode 100644
index 00000000000..db1e48b3596
--- /dev/null
+++ b/drivers/staging/line6/playback.h
@@ -0,0 +1,30 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+#ifndef PLAYBACK_H
+#define PLAYBACK_H
+
+
+#include "driver.h"
+
+#include <sound/pcm.h>
+
+
+extern struct snd_pcm_ops snd_line6_playback_ops;
+
+
+extern int create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
+extern int snd_line6_playback_trigger(struct snd_pcm_substream *substream,
+ int cmd);
+extern void unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm);
+
+
+#endif
diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c
new file mode 100644
index 00000000000..fa5caa245d8
--- /dev/null
+++ b/drivers/staging/line6/pod.c
@@ -0,0 +1,1151 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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 "driver.h"
+
+#include "audio.h"
+#include "capture.h"
+#include "control.h"
+#include "playback.h"
+#include "pod.h"
+
+
+#define POD_SYSEX_CODE 3
+#define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
+
+
+enum {
+ POD_SYSEX_CLIP = 0x0f,
+ POD_SYSEX_SAVE = 0x24,
+ POD_SYSEX_SYSTEM = 0x56,
+ POD_SYSEX_SYSTEMREQ = 0x57,
+ /* POD_SYSEX_UPDATE = 0x6c, */ /* software update! */
+ POD_SYSEX_STORE = 0x71,
+ POD_SYSEX_FINISH = 0x72,
+ POD_SYSEX_DUMPMEM = 0x73,
+ POD_SYSEX_DUMP = 0x74,
+ POD_SYSEX_DUMPREQ = 0x75
+ /* POD_SYSEX_DUMPMEM2 = 0x76 */ /* dumps entire internal memory of PODxt Pro */
+};
+
+enum {
+ POD_monitor_level = 0x04,
+ POD_routing = 0x05,
+ POD_tuner_mute = 0x13,
+ POD_tuner_freq = 0x15,
+ POD_tuner_note = 0x16,
+ POD_tuner_pitch = 0x17,
+ POD_system_invalid = 0x7fff
+};
+
+enum {
+ POD_DUMP_MEMORY = 2
+};
+
+enum {
+ POD_BUSY_READ,
+ POD_BUSY_WRITE,
+ POD_CHANNEL_DIRTY,
+ POD_SAVE_PRESSED,
+ POD_BUSY_MIDISEND
+};
+
+
+static struct snd_ratden pod_ratden = {
+ .num_min = 78125,
+ .num_max = 78125,
+ .num_step = 1,
+ .den = 2
+};
+
+static struct line6_pcm_properties pod_pcm_properties = {
+ .snd_line6_playback_hw = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = 39062,
+ .rate_max = 39063,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 60000,
+ .period_bytes_min = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME, /* at least one URB must fit into one period */
+ .period_bytes_max = 8192,
+ .periods_min = 1,
+ .periods_max = 1024
+ },
+ .snd_line6_capture_hw = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = 39062,
+ .rate_max = 39063,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 60000,
+ .period_bytes_min = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME, /* at least one URB must fit into one period */
+ .period_bytes_max = 8192,
+ .periods_min = 1,
+ .periods_max = 1024
+ },
+ .snd_line6_rates = {
+ .nrats = 1,
+ .rats = &pod_ratden
+ },
+ .bytes_per_frame = POD_BYTES_PER_FRAME
+};
+
+static const char pod_request_version[] = { 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 };
+static const char pod_request_channel[] = { 0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7 };
+static const char pod_version_header[] = { 0xf2, 0x7e, 0x7f, 0x06, 0x02 };
+
+
+/*
+ Mark all parameters as dirty and notify waiting processes.
+*/
+static void pod_mark_batch_all_dirty(struct usb_line6_pod *pod)
+{
+ int i;
+
+ for (i = POD_CONTROL_SIZE; i--;)
+ set_bit(i, pod->param_dirty);
+}
+
+/*
+ Send an asynchronous request for the POD firmware version and device ID.
+*/
+static int pod_version_request_async(struct usb_line6_pod *pod)
+{
+ return line6_send_raw_message_async(&pod->line6, pod->buffer_versionreq, sizeof(pod_request_version));
+}
+
+static void pod_create_files_work(struct work_struct *work)
+{
+ struct usb_line6_pod *pod = container_of(work, struct usb_line6_pod, create_files_work);
+
+ pod_create_files(pod->firmware_version, pod->line6.properties->device_bit, pod->line6.ifcdev);
+}
+
+static void pod_startup_timeout(unsigned long arg)
+{
+ enum {
+ REQUEST_NONE,
+ REQUEST_DUMP,
+ REQUEST_VERSION
+ };
+
+ int request = REQUEST_NONE;
+ struct usb_line6_pod *pod = (struct usb_line6_pod *)arg;
+
+ if (pod->dumpreq.ok) {
+ if (!pod->versionreq_ok)
+ request = REQUEST_VERSION;
+ } else {
+ if (pod->versionreq_ok)
+ request = REQUEST_DUMP;
+ else if (pod->startup_count++ & 1)
+ request = REQUEST_DUMP;
+ else
+ request = REQUEST_VERSION;
+ }
+
+ switch (request) {
+ case REQUEST_DUMP:
+ line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
+ break;
+
+ case REQUEST_VERSION:
+ pod_version_request_async(pod);
+ break;
+
+ default:
+ return;
+ }
+
+ line6_startup_delayed(&pod->dumpreq, 1, pod_startup_timeout, pod);
+}
+
+static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, int size)
+{
+ return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code, size);
+}
+
+/*
+ Send channel dump data to the PODxt Pro.
+*/
+static void pod_dump(struct usb_line6_pod *pod, const unsigned char *data)
+{
+ int size = 1 + sizeof(pod->prog_data);
+ char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMP, size);
+ if (!sysex)
+ return;
+ /* Don't know what this is good for, but PODxt Pro transmits it, so we
+ * also do... */
+ sysex[SYSEX_DATA_OFS] = 5;
+ memcpy(sysex + SYSEX_DATA_OFS + 1, data, sizeof(pod->prog_data));
+ line6_send_sysex_message(&pod->line6, sysex, size);
+ memcpy(&pod->prog_data, data, sizeof(pod->prog_data));
+ pod_mark_batch_all_dirty(pod);
+ kfree(sysex);
+}
+
+/*
+ Store parameter value in driver memory and mark it as dirty.
+*/
+static void pod_store_parameter(struct usb_line6_pod *pod, int param, int value)
+{
+ pod->prog_data.control[param] = value;
+ set_bit(param, pod->param_dirty);
+ pod->dirty = 1;
+}
+
+/*
+ Handle SAVE button
+*/
+static void pod_save_button_pressed(struct usb_line6_pod *pod, int type, int index)
+{
+ pod->dirty = 0;
+ set_bit(POD_SAVE_PRESSED, &pod->atomic_flags);
+}
+
+/*
+ Process a completely received message.
+*/
+void pod_process_message(struct usb_line6_pod *pod)
+{
+ const unsigned char *buf = pod->line6.buffer_message;
+
+ /* filter messages by type */
+ switch (buf[0] & 0xf0) {
+ case LINE6_PARAM_CHANGE:
+ case LINE6_PROGRAM_CHANGE:
+ case LINE6_SYSEX_BEGIN:
+ break; /* handle these further down */
+
+ default:
+ return; /* ignore all others */
+ }
+
+ /* process all remaining messages */
+ switch (buf[0]) {
+ case LINE6_PARAM_CHANGE | LINE6_CHANNEL_DEVICE:
+ pod_store_parameter(pod, buf[1], buf[2]);
+ /* intentionally no break here! */
+
+ case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
+ if ((buf[1] == POD_amp_model_setup) ||
+ (buf[1] == POD_effect_setup))
+ /* these also affect other settings */
+ line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
+
+ break;
+
+ case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
+ case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
+ pod->channel_num = buf[1];
+ pod->dirty = 0;
+ set_bit(POD_CHANNEL_DIRTY, &pod->atomic_flags);
+ line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
+ break;
+
+ case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE:
+ case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN:
+ if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) == 0) {
+ switch (buf[5]) {
+ case POD_SYSEX_DUMP:
+ if (pod->line6.message_length == sizeof(pod->prog_data) + 7) {
+ switch (pod->dumpreq.in_progress) {
+ case LINE6_DUMP_CURRENT:
+ memcpy(&pod->prog_data, buf + 7, sizeof(pod->prog_data));
+ pod_mark_batch_all_dirty(pod);
+ pod->dumpreq.ok = 1;
+ break;
+
+ case POD_DUMP_MEMORY:
+ memcpy(&pod->prog_data_buf, buf + 7, sizeof(pod->prog_data_buf));
+ break;
+
+ default:
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown dump code %02X\n", pod->dumpreq.in_progress));
+ }
+
+ line6_dump_finished(&pod->dumpreq);
+ } else
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "wrong size of channel dump message (%d instead of %d)\n",
+ pod->line6.message_length, (int)sizeof(pod->prog_data) + 7));
+
+ break;
+
+ case POD_SYSEX_SYSTEM: {
+ short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) | ((int)buf[9] << 4) | (int)buf[10];
+
+#define PROCESS_SYSTEM_PARAM(x) \
+ case POD_ ## x: \
+ pod->x.value = value; \
+ wake_up_interruptible(&pod->x.wait); \
+ break;
+
+ switch (buf[6]) {
+ PROCESS_SYSTEM_PARAM(monitor_level);
+ PROCESS_SYSTEM_PARAM(routing);
+ PROCESS_SYSTEM_PARAM(tuner_mute);
+ PROCESS_SYSTEM_PARAM(tuner_freq);
+ PROCESS_SYSTEM_PARAM(tuner_note);
+ PROCESS_SYSTEM_PARAM(tuner_pitch);
+
+#undef PROCESS_SYSTEM_PARAM
+
+ default:
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown tuner/system response %02X\n", buf[6]));
+ }
+
+ break;
+ }
+
+ case POD_SYSEX_FINISH:
+ /* do we need to respond to this? */
+ break;
+
+ case POD_SYSEX_SAVE:
+ pod_save_button_pressed(pod, buf[6], buf[7]);
+ break;
+
+ case POD_SYSEX_CLIP:
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "audio clipped\n"));
+ pod->clipping.value = 1;
+ wake_up_interruptible(&pod->clipping.wait);
+ break;
+
+ case POD_SYSEX_STORE:
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "message %02X not yet implemented\n", buf[5]));
+ break;
+
+ default:
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex message %02X\n", buf[5]));
+ }
+ } else if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
+ if (pod->versionreq_ok == 0) {
+ pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
+ pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)buf[10];
+ pod->versionreq_ok = 1;
+
+ /* Now we know the firmware version, so we schedule a bottom half
+ handler to create the special files: */
+ INIT_WORK(&pod->create_files_work, pod_create_files_work);
+ queue_work(line6_workqueue, &pod->create_files_work);
+ } else
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "multiple firmware version message\n"));
+ } else
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex header\n"));
+
+ break;
+
+ case LINE6_SYSEX_END:
+ break;
+
+ default:
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "POD: unknown message %02X\n", buf[0]));
+ }
+}
+
+/*
+ Detect some cases that require a channel dump after sending a command to the
+ device. Important notes:
+ *) The actual dump request can not be sent here since we are not allowed to
+ wait for the completion of the first message in this context, and sending
+ the dump request before completion of the previous message leaves the POD
+ in an undefined state. The dump request will be sent when the echoed
+ commands are received.
+ *) This method fails if a param change message is "chopped" after the first
+ byte.
+*/
+void pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data, int length)
+{
+ int i;
+
+ if (!pod->midi_postprocess)
+ return;
+
+ for (i = 0; i < length; ++i) {
+ if (data[i] == (LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST)) {
+ line6_invalidate_current(&pod->dumpreq);
+ break;
+ } else if ((data[i] == (LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST)) && (i < length - 1))
+ if ((data[i + 1] == POD_amp_model_setup) || (data[i + 1] == POD_effect_setup)) {
+ line6_invalidate_current(&pod->dumpreq);
+ break;
+ }
+ }
+}
+
+/*
+ Send channel number (i.e., switch to a different sound).
+*/
+static void pod_send_channel(struct usb_line6_pod *pod, int value)
+{
+ line6_invalidate_current(&pod->dumpreq);
+
+ if (line6_send_program(&pod->line6, value) == 0)
+ pod->channel_num = value;
+ else
+ line6_dump_finished(&pod->dumpreq);
+}
+
+/*
+ Transmit PODxt Pro control parameter.
+*/
+void pod_transmit_parameter(struct usb_line6_pod *pod, int param, int value)
+{
+ if (line6_transmit_parameter(&pod->line6, param, value) == 0)
+ pod_store_parameter(pod, param, value);
+
+ if ((param == POD_amp_model_setup) || (param == POD_effect_setup)) /* these also affect other settings */
+ line6_invalidate_current(&pod->dumpreq);
+}
+
+/*
+ Resolve value to memory location.
+*/
+static void pod_resolve(const char *buf, short block0, short block1, unsigned char *location)
+{
+ int value = simple_strtoul(buf, NULL, 10);
+ short block = (value < 0x40) ? block0 : block1;
+ value &= 0x3f;
+ location[0] = block >> 7;
+ location[1] = value | (block & 0x7f);
+}
+
+/*
+ Send command to store channel/effects setup/amp setup to PODxt Pro.
+*/
+static ssize_t pod_send_store_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+
+ int size = 3 + sizeof(pod->prog_data_buf);
+ char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_STORE, size);
+ if (!sysex)
+ return 0;
+
+ sysex[SYSEX_DATA_OFS] = 5; /* see pod_dump() */
+ pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS + 1);
+ memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
+
+ line6_send_sysex_message(&pod->line6, sysex, size);
+ kfree(sysex);
+ /* needs some delay here on AMD64 platform */
+ return count;
+}
+
+/*
+ Send command to retrieve channel/effects setup/amp setup to PODxt Pro.
+*/
+static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int size = 4;
+ char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMPMEM, size);
+
+ if (!sysex)
+ return 0;
+
+ pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS);
+ sysex[SYSEX_DATA_OFS + 2] = 0;
+ sysex[SYSEX_DATA_OFS + 3] = 0;
+ line6_dump_started(&pod->dumpreq, POD_DUMP_MEMORY);
+
+ if (line6_send_sysex_message(&pod->line6, sysex, size) < size)
+ line6_dump_finished(&pod->dumpreq);
+
+ kfree(sysex);
+ /* needs some delay here on AMD64 platform */
+ return count;
+}
+
+/*
+ Generic get name function.
+*/
+static ssize_t get_name_generic(struct usb_line6_pod *pod, const char *str, char *buf)
+{
+ int length = 0;
+ const char *p1;
+ char *p2;
+ char *last_non_space = buf;
+
+ int retval = line6_wait_dump(&pod->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+
+ for (p1 = str, p2 = buf; *p1; ++p1, ++p2) {
+ *p2 = *p1;
+ if (*p2 != ' ')
+ last_non_space = p2;
+ if (++length == POD_NAME_LENGTH)
+ break;
+ }
+
+ *(last_non_space + 1) = '\n';
+ return last_non_space - buf + 2;
+}
+
+/*
+ "read" request on "channel" special file.
+*/
+static ssize_t pod_get_channel(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return sprintf(buf, "%d\n", pod->channel_num);
+}
+
+/*
+ "write" request on "channel" special file.
+*/
+static ssize_t pod_set_channel(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int value = simple_strtoul(buf, NULL, 10);
+ pod_send_channel(pod, value);
+ return count;
+}
+
+/*
+ "read" request on "name" special file.
+*/
+static ssize_t pod_get_name(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return get_name_generic(pod, pod->prog_data.header + POD_NAME_OFFSET, buf);
+}
+
+/*
+ "read" request on "name" special file.
+*/
+static ssize_t pod_get_name_buf(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return get_name_generic(pod, pod->prog_data_buf.header + POD_NAME_OFFSET, buf);
+}
+
+/*
+ "read" request on "dump" special file.
+*/
+static ssize_t pod_get_dump(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int retval = line6_wait_dump(&pod->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+ memcpy(buf, &pod->prog_data, sizeof(pod->prog_data));
+ return sizeof(pod->prog_data);
+}
+
+/*
+ "write" request on "dump" special file.
+*/
+static ssize_t pod_set_dump(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+
+ if (count != sizeof(pod->prog_data)) {
+ dev_err(pod->line6.ifcdev,
+ "data block must be exactly %d bytes\n",
+ (int)sizeof(pod->prog_data));
+ return -EINVAL;
+ }
+
+ pod_dump(pod, buf);
+ return sizeof(pod->prog_data);
+}
+
+/*
+ Request system parameter.
+ @param tuner non-zero, if code refers to a tuner parameter
+*/
+static ssize_t pod_get_system_param(struct usb_line6_pod *pod, char *buf, int code, struct ValueWait *param, int tuner, int sign)
+{
+ char *sysex;
+ int value;
+ static const int size = 1;
+ int retval = 0;
+ DECLARE_WAITQUEUE(wait, current);
+
+ if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner)
+ return -ENODEV;
+
+ /* send value request to tuner: */
+ param->value = POD_system_invalid;
+ sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEMREQ, size);
+ if (!sysex)
+ return 0;
+ sysex[SYSEX_DATA_OFS] = code;
+ line6_send_sysex_message(&pod->line6, sysex, size);
+ kfree(sysex);
+
+ /* wait for tuner to respond: */
+ add_wait_queue(&param->wait, &wait);
+ current->state = TASK_INTERRUPTIBLE;
+
+ while (param->value == POD_system_invalid) {
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ break;
+ } else
+ schedule();
+ }
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&param->wait, &wait);
+
+ if (retval < 0)
+ return retval;
+
+ value = sign ? (int)(signed short)param->value : (int)(unsigned short)param->value;
+ return sprintf(buf, "%d\n", value);
+}
+
+/*
+ Send system parameter.
+ @param tuner non-zero, if code refers to a tuner parameter
+*/
+static ssize_t pod_set_system_param(struct usb_line6_pod *pod, const char *buf,
+ int count, int code, unsigned short mask,
+ int tuner)
+{
+ char *sysex;
+ static const int size = 5;
+ unsigned short value;
+
+ if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner)
+ return -EINVAL;
+
+ /* send value to tuner: */
+ sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
+ if (!sysex)
+ return 0;
+ value = simple_strtoul(buf, NULL, 10) & mask;
+ sysex[SYSEX_DATA_OFS] = code;
+ sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
+ sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
+ sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
+ sysex[SYSEX_DATA_OFS + 4] = (value ) & 0x0f;
+ line6_send_sysex_message(&pod->line6, sysex, size);
+ kfree(sysex);
+ return count;
+}
+
+/*
+ "read" request on "dump_buf" special file.
+*/
+static ssize_t pod_get_dump_buf(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int retval = line6_wait_dump(&pod->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+ memcpy(buf, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
+ return sizeof(pod->prog_data_buf);
+}
+
+/*
+ "write" request on "dump_buf" special file.
+*/
+static ssize_t pod_set_dump_buf(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+
+ if (count != sizeof(pod->prog_data)) {
+ dev_err(pod->line6.ifcdev,
+ "data block must be exactly %d bytes\n",
+ (int)sizeof(pod->prog_data));
+ return -EINVAL;
+ }
+
+ memcpy(&pod->prog_data_buf, buf, sizeof(pod->prog_data));
+ return sizeof(pod->prog_data);
+}
+
+/*
+ "write" request on "finish" special file.
+*/
+static ssize_t pod_set_finish(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int size = 0;
+ char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_FINISH, size);
+ if (!sysex)
+ return 0;
+ line6_send_sysex_message(&pod->line6, sysex, size);
+ kfree(sysex);
+ return count;
+}
+
+/*
+ "write" request on "store_channel" special file.
+*/
+static ssize_t pod_set_store_channel(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return pod_send_store_command(dev, buf, count, 0x0000, 0x00c0);
+}
+
+/*
+ "write" request on "store_effects_setup" special file.
+*/
+static ssize_t pod_set_store_effects_setup(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return pod_send_store_command(dev, buf, count, 0x0080, 0x0080);
+}
+
+/*
+ "write" request on "store_amp_setup" special file.
+*/
+static ssize_t pod_set_store_amp_setup(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return pod_send_store_command(dev, buf, count, 0x0040, 0x0100);
+}
+
+/*
+ "write" request on "retrieve_channel" special file.
+*/
+static ssize_t pod_set_retrieve_channel(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return pod_send_retrieve_command(dev, buf, count, 0x0000, 0x00c0);
+}
+
+/*
+ "write" request on "retrieve_effects_setup" special file.
+*/
+static ssize_t pod_set_retrieve_effects_setup(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return pod_send_retrieve_command(dev, buf, count, 0x0080, 0x0080);
+}
+
+/*
+ "write" request on "retrieve_amp_setup" special file.
+*/
+static ssize_t pod_set_retrieve_amp_setup(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return pod_send_retrieve_command(dev, buf, count, 0x0040, 0x0100);
+}
+
+/*
+ "read" request on "dirty" special file.
+*/
+static ssize_t pod_get_dirty(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ buf[0] = pod->dirty ? '1' : '0';
+ buf[1] = '\n';
+ return 2;
+}
+
+/*
+ "read" request on "midi_postprocess" special file.
+*/
+static ssize_t pod_get_midi_postprocess(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return sprintf(buf, "%d\n", pod->midi_postprocess);
+}
+
+/*
+ "write" request on "midi_postprocess" special file.
+*/
+static ssize_t pod_set_midi_postprocess(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int value = simple_strtoul(buf, NULL, 10);
+ pod->midi_postprocess = value ? 1 : 0;
+ return count;
+}
+
+/*
+ "read" request on "serial_number" special file.
+*/
+static ssize_t pod_get_serial_number(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return sprintf(buf, "%d\n", pod->serial_number);
+}
+
+/*
+ "read" request on "firmware_version" special file.
+*/
+static ssize_t pod_get_firmware_version(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
+ pod->firmware_version % 100);
+}
+
+/*
+ "read" request on "device_id" special file.
+*/
+static ssize_t pod_get_device_id(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return sprintf(buf, "%d\n", pod->device_id);
+}
+
+/*
+ "read" request on "clip" special file.
+*/
+static ssize_t pod_wait_for_clip(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int err = 0;
+ DECLARE_WAITQUEUE(wait, current);
+ pod->clipping.value = 0;
+ add_wait_queue(&pod->clipping.wait, &wait);
+ current->state = TASK_INTERRUPTIBLE;
+
+ while (pod->clipping.value == 0) {
+ if (signal_pending(current)) {
+ err = -ERESTARTSYS;
+ break;
+ } else
+ schedule();
+ }
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&pod->clipping.wait, &wait);
+ return err;
+}
+
+#define POD_GET_SYSTEM_PARAM(code, tuner, sign) \
+static ssize_t pod_get_ ## code(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct usb_interface *interface = to_usb_interface(dev); \
+ struct usb_line6_pod *pod = usb_get_intfdata(interface); \
+ return pod_get_system_param(pod, buf, POD_ ## code, &pod->code, \
+ tuner, sign); \
+}
+
+#define POD_GET_SET_SYSTEM_PARAM(code, mask, tuner, sign) \
+POD_GET_SYSTEM_PARAM(code, tuner, sign) \
+static ssize_t pod_set_ ## code(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t count) \
+{ \
+ struct usb_interface *interface = to_usb_interface(dev); \
+ struct usb_line6_pod *pod = usb_get_intfdata(interface); \
+ return pod_set_system_param(pod, buf, count, POD_ ## code, mask, \
+ tuner); \
+}
+
+POD_GET_SET_SYSTEM_PARAM(monitor_level, 0xffff, 0, 0);
+POD_GET_SET_SYSTEM_PARAM(routing, 0x0003, 0, 0);
+POD_GET_SET_SYSTEM_PARAM(tuner_mute, 0x0001, 1, 0);
+POD_GET_SET_SYSTEM_PARAM(tuner_freq, 0xffff, 1, 0);
+POD_GET_SYSTEM_PARAM(tuner_note, 1, 1);
+POD_GET_SYSTEM_PARAM(tuner_pitch, 1, 1);
+
+#undef GET_SET_SYSTEM_PARAM
+#undef GET_SYSTEM_PARAM
+
+/* POD special files: */
+static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel, pod_set_channel);
+static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
+static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
+static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
+static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump);
+static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf);
+static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish);
+static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version, line6_nop_write);
+static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess);
+static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level);
+static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
+static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
+static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_amp_setup);
+static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read, pod_set_retrieve_channel);
+static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_effects_setup);
+static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing, pod_set_routing);
+static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number, line6_nop_write);
+static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read, pod_set_store_amp_setup);
+static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read, pod_set_store_channel);
+static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read, pod_set_store_effects_setup);
+static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq);
+static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute);
+static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
+static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
+
+#if CREATE_RAW_FILE
+static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
+#endif
+
+/*
+ POD destructor.
+*/
+static void pod_destruct(struct usb_interface *interface)
+{
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ struct usb_line6 *line6;
+
+ if (pod == NULL)
+ return;
+ line6 = &pod->line6;
+ if (line6 == NULL)
+ return;
+ line6_cleanup_audio(line6);
+
+ /* free dump request data: */
+ line6_dumpreq_destruct(&pod->dumpreq);
+
+ kfree(pod->buffer_versionreq);
+}
+
+/*
+ Create sysfs entries.
+*/
+static int pod_create_files2(struct device *dev)
+{
+ int err;
+
+ CHECK_RETURN(device_create_file(dev, &dev_attr_channel));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_clip));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_dirty));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_dump_buf));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_finish));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_midi_postprocess));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_monitor_level));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_name));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_name_buf));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_amp_setup));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_channel));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_effects_setup));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_routing));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_store_amp_setup));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_store_channel));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_store_effects_setup));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_freq));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_mute));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_note));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_pitch));
+
+#if CREATE_RAW_FILE
+ CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
+#endif
+
+ return 0;
+}
+
+/*
+ Init POD device.
+*/
+int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
+{
+ int err;
+ struct usb_line6 *line6 = &pod->line6;
+
+ if ((interface == NULL) || (pod == NULL))
+ return -ENODEV;
+
+ pod->channel_num = 255;
+
+ /* initialize wait queues: */
+ init_waitqueue_head(&pod->monitor_level.wait);
+ init_waitqueue_head(&pod->routing.wait);
+ init_waitqueue_head(&pod->tuner_mute.wait);
+ init_waitqueue_head(&pod->tuner_freq.wait);
+ init_waitqueue_head(&pod->tuner_note.wait);
+ init_waitqueue_head(&pod->tuner_pitch.wait);
+ init_waitqueue_head(&pod->clipping.wait);
+
+ memset(pod->param_dirty, 0xff, sizeof(pod->param_dirty));
+
+ /* initialize USB buffers: */
+ err = line6_dumpreq_init(&pod->dumpreq, pod_request_channel,
+ sizeof(pod_request_channel));
+ if (err < 0) {
+ dev_err(&interface->dev, "Out of memory\n");
+ pod_destruct(interface);
+ return -ENOMEM;
+ }
+
+ pod->buffer_versionreq = kmalloc(sizeof(pod_request_version),
+ GFP_KERNEL);
+
+ if (pod->buffer_versionreq == NULL) {
+ dev_err(&interface->dev, "Out of memory\n");
+ pod_destruct(interface);
+ return -ENOMEM;
+ }
+
+ memcpy(pod->buffer_versionreq, pod_request_version,
+ sizeof(pod_request_version));
+
+ /* create sysfs entries: */
+ err = pod_create_files2(&interface->dev);
+ if (err < 0) {
+ pod_destruct(interface);
+ return err;
+ }
+
+ /* initialize audio system: */
+ err = line6_init_audio(line6);
+ if (err < 0) {
+ pod_destruct(interface);
+ return err;
+ }
+
+ /* initialize MIDI subsystem: */
+ err = line6_init_midi(line6);
+ if (err < 0) {
+ pod_destruct(interface);
+ return err;
+ }
+
+ /* initialize PCM subsystem: */
+ err = line6_init_pcm(line6, &pod_pcm_properties);
+ if (err < 0) {
+ pod_destruct(interface);
+ return err;
+ }
+
+ /* register audio system: */
+ err = line6_register_audio(line6);
+ if (err < 0) {
+ pod_destruct(interface);
+ return err;
+ }
+
+ if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
+ /* query some data: */
+ line6_startup_delayed(&pod->dumpreq, POD_STARTUP_DELAY,
+ pod_startup_timeout, pod);
+ line6_read_serial_number(&pod->line6, &pod->serial_number);
+ }
+
+ return 0;
+}
+
+/*
+ POD device disconnected.
+*/
+void pod_disconnect(struct usb_interface *interface)
+{
+ struct usb_line6_pod *pod;
+
+ if (interface == NULL)
+ return;
+ pod = usb_get_intfdata(interface);
+
+ if (pod != NULL) {
+ struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
+ struct device *dev = &interface->dev;
+
+ if (line6pcm != NULL) {
+ unlink_wait_clear_audio_out_urbs(line6pcm);
+ unlink_wait_clear_audio_in_urbs(line6pcm);
+ }
+
+ if (dev != NULL) {
+ /* remove sysfs entries: */
+ if (pod->versionreq_ok)
+ pod_remove_files(pod->firmware_version, pod->line6.properties->device_bit, dev);
+
+ device_remove_file(dev, &dev_attr_channel);
+ device_remove_file(dev, &dev_attr_clip);
+ device_remove_file(dev, &dev_attr_device_id);
+ device_remove_file(dev, &dev_attr_dirty);
+ device_remove_file(dev, &dev_attr_dump);
+ device_remove_file(dev, &dev_attr_dump_buf);
+ device_remove_file(dev, &dev_attr_finish);
+ device_remove_file(dev, &dev_attr_firmware_version);
+ device_remove_file(dev, &dev_attr_midi_postprocess);
+ device_remove_file(dev, &dev_attr_monitor_level);
+ device_remove_file(dev, &dev_attr_name);
+ device_remove_file(dev, &dev_attr_name_buf);
+ device_remove_file(dev, &dev_attr_retrieve_amp_setup);
+ device_remove_file(dev, &dev_attr_retrieve_channel);
+ device_remove_file(dev, &dev_attr_retrieve_effects_setup);
+ device_remove_file(dev, &dev_attr_routing);
+ device_remove_file(dev, &dev_attr_serial_number);
+ device_remove_file(dev, &dev_attr_store_amp_setup);
+ device_remove_file(dev, &dev_attr_store_channel);
+ device_remove_file(dev, &dev_attr_store_effects_setup);
+ device_remove_file(dev, &dev_attr_tuner_freq);
+ device_remove_file(dev, &dev_attr_tuner_mute);
+ device_remove_file(dev, &dev_attr_tuner_note);
+ device_remove_file(dev, &dev_attr_tuner_pitch);
+
+#if CREATE_RAW_FILE
+ device_remove_file(dev, &dev_attr_raw);
+#endif
+ }
+ }
+
+ pod_destruct(interface);
+}
diff --git a/drivers/staging/line6/pod.h b/drivers/staging/line6/pod.h
new file mode 100644
index 00000000000..7051ca61381
--- /dev/null
+++ b/drivers/staging/line6/pod.h
@@ -0,0 +1,204 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+#ifndef POD_H
+#define POD_H
+
+
+#include "driver.h"
+
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include <sound/core.h>
+
+#include "dumprequest.h"
+
+
+/*
+ PODxt Live interfaces
+*/
+#define PODXTLIVE_INTERFACE_POD 0
+#define PODXTLIVE_INTERFACE_VARIAX 1
+
+/*
+ Locate name in binary program dump
+*/
+#define POD_NAME_OFFSET 0
+#define POD_NAME_LENGTH 16
+
+/*
+ Other constants
+*/
+#define POD_CONTROL_SIZE 0x80
+#define POD_BUFSIZE_DUMPREQ 7
+#define POD_STARTUP_DELAY 3
+
+
+/**
+ Data structure for values that need to be requested explicitly.
+ This is the case for system and tuner settings.
+*/
+struct ValueWait {
+ unsigned short value;
+ wait_queue_head_t wait;
+};
+
+/**
+ Binary PodXT Pro program dump
+*/
+struct pod_program {
+ /**
+ Header information (including program name).
+ */
+ unsigned char header[0x20];
+
+ /**
+ Program parameters.
+ */
+ unsigned char control[POD_CONTROL_SIZE];
+};
+
+struct usb_line6_pod {
+ /**
+ Generic Line6 USB data.
+ */
+ struct usb_line6 line6;
+
+ /**
+ Dump request structure.
+ */
+ struct line6_dump_request dumpreq;
+
+ /**
+ Current program number.
+ */
+ unsigned char channel_num;
+
+ /**
+ Current program settings.
+ */
+ struct pod_program prog_data;
+
+ /**
+ Buffer for data retrieved from or to be stored on PODxt Pro.
+ */
+ struct pod_program prog_data_buf;
+
+ /**
+ Buffer for requesting version number.
+ */
+ unsigned char *buffer_versionreq;
+
+ /**
+ Tuner mute mode.
+ */
+ struct ValueWait tuner_mute;
+
+ /**
+ Tuner base frequency (typically 440Hz).
+ */
+ struct ValueWait tuner_freq;
+
+ /**
+ Note received from tuner.
+ */
+ struct ValueWait tuner_note;
+
+ /**
+ Pitch value received from tuner.
+ */
+ struct ValueWait tuner_pitch;
+
+ /**
+ Instrument monitor level.
+ */
+ struct ValueWait monitor_level;
+
+ /**
+ Audio routing mode.
+ 0: send processed guitar
+ 1: send clean guitar
+ 2: send clean guitar re-amp playback
+ 3: send re-amp playback
+ */
+ struct ValueWait routing;
+
+ /**
+ Wait for audio clipping event.
+ */
+ struct ValueWait clipping;
+
+ /**
+ Bottom-half for creation of sysfs special files.
+ */
+ struct work_struct create_files_work;
+
+ /**
+ Dirty flags for access to parameter data.
+ */
+ unsigned long param_dirty[POD_CONTROL_SIZE / sizeof(unsigned long)];
+
+ /**
+ Some atomic flags.
+ */
+ unsigned long atomic_flags;
+
+ /**
+ Counter for startup process.
+ */
+ int startup_count;
+
+ /**
+ Serial number of device.
+ */
+ int serial_number;
+
+ /**
+ Firmware version (x 100).
+ */
+ int firmware_version;
+
+ /**
+ Device ID.
+ */
+ int device_id;
+
+ /**
+ Flag to indicate modification of current program settings.
+ */
+ char dirty;
+
+ /**
+ Flag if initial firmware version request has been successful.
+ */
+ char versionreq_ok;
+
+ /**
+ Flag to enable MIDI postprocessing.
+ */
+ char midi_postprocess;
+};
+
+
+extern void pod_disconnect(struct usb_interface *interface);
+extern int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod);
+extern void pod_midi_postprocess(struct usb_line6_pod *pod,
+ unsigned char *data, int length);
+extern void pod_process_message(struct usb_line6_pod *pod);
+extern void pod_receive_parameter(struct usb_line6_pod *pod, int param);
+extern void pod_transmit_parameter(struct usb_line6_pod *pod, int param,
+ int value);
+
+
+#endif
diff --git a/drivers/staging/line6/revision.h b/drivers/staging/line6/revision.h
new file mode 100644
index 00000000000..b2a0a85efe6
--- /dev/null
+++ b/drivers/staging/line6/revision.h
@@ -0,0 +1,4 @@
+#ifndef DRIVER_REVISION
+/* current subversion revision */
+#define DRIVER_REVISION " (revision 529)"
+#endif
diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c
new file mode 100644
index 00000000000..eaa1229002a
--- /dev/null
+++ b/drivers/staging/line6/toneport.c
@@ -0,0 +1,241 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Emil Myhrman (emil.myhrman@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "driver.h"
+
+#include "audio.h"
+#include "capture.h"
+#include "playback.h"
+#include "toneport.h"
+
+
+static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
+
+
+static struct snd_ratden toneport_ratden = {
+ .num_min = 44100,
+ .num_max = 44100,
+ .num_step = 1,
+ .den = 1
+};
+
+static struct line6_pcm_properties toneport_pcm_properties = {
+ .snd_line6_playback_hw = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = 44100,
+ .rate_max = 44100,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 60000,
+ .period_bytes_min = 180 * 4,
+ .period_bytes_max = 8192,
+ .periods_min = 1,
+ .periods_max = 1024
+ },
+ .snd_line6_capture_hw = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = 44100,
+ .rate_max = 44100,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 60000,
+ .period_bytes_min = 188 * 4,
+ .period_bytes_max = 8192,
+ .periods_min = 1,
+ .periods_max = 1024
+ },
+ .snd_line6_rates = {
+ .nrats = 1,
+ .rats = &toneport_ratden
+ },
+ .bytes_per_frame = 4
+};
+
+/*
+ For the led on Guitarport.
+ Brightness goes from 0x00 to 0x26. Set a value above this to have led
+ blink.
+ (void cmd_0x02(byte red, byte green)
+*/
+static int led_red = 0x00;
+static int led_green = 0x26;
+
+static void toneport_update_led(struct device *dev)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_toneport *tp = usb_get_intfdata(interface);
+ struct usb_line6 *line6;
+
+ if (!tp)
+ return;
+
+ line6 = &tp->line6;
+ if (line6)
+ toneport_send_cmd(line6->usbdev, (led_red << 8) | 0x0002,
+ led_green);
+}
+
+static ssize_t toneport_set_led_red(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ char *c;
+ led_red = simple_strtol(buf, &c, 10);
+ toneport_update_led(dev);
+ return count;
+}
+
+static ssize_t toneport_set_led_green(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ char *c;
+ led_green = simple_strtol(buf, &c, 10);
+ toneport_update_led(dev);
+ return count;
+}
+
+static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read, toneport_set_led_red);
+static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read, toneport_set_led_green);
+
+
+static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
+{
+ int ret;
+
+ ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ);
+
+ if (ret < 0) {
+ err("send failed (error %d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ Toneport destructor.
+*/
+static void toneport_destruct(struct usb_interface *interface)
+{
+ struct usb_line6_toneport *toneport = usb_get_intfdata(interface);
+ struct usb_line6 *line6;
+
+ if (toneport == NULL)
+ return;
+ line6 = &toneport->line6;
+ if (line6 == NULL)
+ return;
+ line6_cleanup_audio(line6);
+}
+
+/*
+ Init Toneport device.
+*/
+int toneport_init(struct usb_interface *interface,
+ struct usb_line6_toneport *toneport)
+{
+ int err, ticks;
+ struct usb_line6 *line6 = &toneport->line6;
+ struct usb_device *usbdev;
+
+ if ((interface == NULL) || (toneport == NULL))
+ return -ENODEV;
+
+ /* initialize audio system: */
+ err = line6_init_audio(line6);
+ if (err < 0) {
+ toneport_destruct(interface);
+ return err;
+ }
+
+ /* initialize PCM subsystem: */
+ err = line6_init_pcm(line6, &toneport_pcm_properties);
+ if (err < 0) {
+ toneport_destruct(interface);
+ return err;
+ }
+
+ /* register audio system: */
+ err = line6_register_audio(line6);
+ if (err < 0) {
+ toneport_destruct(interface);
+ return err;
+ }
+
+ usbdev = line6->usbdev;
+ line6_read_serial_number(line6, &toneport->serial_number);
+ line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
+
+ /* sync time on device with host: */
+ ticks = (int)get_seconds();
+ line6_write_data(line6, 0x80c6, &ticks, 4);
+
+ /*
+ seems to work without the first two...
+ */
+ /* toneport_send_cmd(usbdev, 0x0201, 0x0002); */
+ /* toneport_send_cmd(usbdev, 0x0801, 0x0000); */
+ /* only one that works for me; on GP, TP might be different? */
+ toneport_send_cmd(usbdev, 0x0301, 0x0000);
+
+ if (usbdev->descriptor.idProduct != LINE6_DEVID_GUITARPORT) {
+ CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_red));
+ CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_green));
+ toneport_update_led(&usbdev->dev);
+ }
+
+ return 0;
+}
+
+/*
+ Toneport device disconnected.
+*/
+void toneport_disconnect(struct usb_interface *interface)
+{
+ struct usb_line6_toneport *toneport;
+
+ if (interface == NULL)
+ return;
+ toneport = usb_get_intfdata(interface);
+
+ if (toneport->line6.usbdev->descriptor.idProduct != LINE6_DEVID_GUITARPORT) {
+ device_remove_file(&interface->dev, &dev_attr_led_red);
+ device_remove_file(&interface->dev, &dev_attr_led_green);
+ }
+
+ if (toneport != NULL) {
+ struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm;
+
+ if (line6pcm != NULL) {
+ unlink_wait_clear_audio_out_urbs(line6pcm);
+ unlink_wait_clear_audio_in_urbs(line6pcm);
+ }
+ }
+
+ toneport_destruct(interface);
+}
diff --git a/drivers/staging/line6/toneport.h b/drivers/staging/line6/toneport.h
new file mode 100644
index 00000000000..bddc58dd7e3
--- /dev/null
+++ b/drivers/staging/line6/toneport.h
@@ -0,0 +1,45 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+#ifndef TONEPORT_H
+#define TONEPORT_H
+
+
+#include "driver.h"
+
+#include <linux/usb.h>
+#include <sound/core.h>
+
+
+struct usb_line6_toneport {
+ /**
+ Generic Line6 USB data.
+ */
+ struct usb_line6 line6;
+
+ /**
+ Serial number of device.
+ */
+ int serial_number;
+
+ /**
+ Firmware version (x 100).
+ */
+ int firmware_version;
+};
+
+
+extern void toneport_disconnect(struct usb_interface *interface);
+extern int toneport_init(struct usb_interface *interface,
+ struct usb_line6_toneport *toneport);
+
+
+#endif
diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h
new file mode 100644
index 00000000000..c38f31f2f42
--- /dev/null
+++ b/drivers/staging/line6/usbdefs.h
@@ -0,0 +1,74 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+#ifndef USBDEFS_H
+#define USBDEFS_H
+
+
+#define LINE6_VENDOR_ID 0x0e41
+
+#define USB_INTERVALS_PER_SECOND 1000
+
+/*
+ Device ids.
+*/
+#define LINE6_DEVID_BASSPODXT 0x4250
+#define LINE6_DEVID_BASSPODXTLIVE 0x4642
+#define LINE6_DEVID_BASSPODXTPRO 0x4252
+#define LINE6_DEVID_GUITARPORT 0x4750
+#define LINE6_DEVID_POCKETPOD 0x5051
+#define LINE6_DEVID_PODX3 0x414a
+#define LINE6_DEVID_PODX3LIVE 0x414b
+#define LINE6_DEVID_PODXT 0x5044
+#define LINE6_DEVID_PODXTLIVE 0x4650
+#define LINE6_DEVID_PODXTPRO 0x5050
+#define LINE6_DEVID_TONEPORT_GX 0x4147
+#define LINE6_DEVID_TONEPORT_UX1 0x4141
+#define LINE6_DEVID_TONEPORT_UX2 0x4142
+#define LINE6_DEVID_VARIAX 0x534d
+
+#define LINE6_BIT_BASSPODXT (1 << 0)
+#define LINE6_BIT_BASSPODXTLIVE (1 << 1)
+#define LINE6_BIT_BASSPODXTPRO (1 << 2)
+#define LINE6_BIT_GUITARPORT (1 << 3)
+#define LINE6_BIT_POCKETPOD (1 << 4)
+#define LINE6_BIT_PODX3 (1 << 5)
+#define LINE6_BIT_PODX3LIVE (1 << 6)
+#define LINE6_BIT_PODXT (1 << 7)
+#define LINE6_BIT_PODXTLIVE (1 << 8)
+#define LINE6_BIT_PODXTPRO (1 << 9)
+#define LINE6_BIT_TONEPORT_GX (1 << 10)
+#define LINE6_BIT_TONEPORT_UX1 (1 << 11)
+#define LINE6_BIT_TONEPORT_UX2 (1 << 12)
+#define LINE6_BIT_VARIAX (1 << 13)
+
+#define LINE6_BITS_PRO (LINE6_BIT_BASSPODXTPRO | \
+ LINE6_BIT_PODXTPRO)
+#define LINE6_BITS_LIVE (LINE6_BIT_BASSPODXTLIVE | \
+ LINE6_BIT_PODXTLIVE | \
+ LINE6_BIT_PODX3LIVE)
+#define LINE6_BITS_PODXTALL (LINE6_BIT_PODXT | \
+ LINE6_BIT_PODXTLIVE | \
+ LINE6_BIT_PODXTPRO)
+#define LINE6_BITS_BASSPODXTALL (LINE6_BIT_BASSPODXT | \
+ LINE6_BIT_BASSPODXTLIVE | \
+ LINE6_BIT_BASSPODXTPRO)
+
+/* device supports settings parameter via USB */
+#define LINE6_BIT_CONTROL (1 << 0)
+/* device supports PCM input/output via USB */
+#define LINE6_BIT_PCM (1 << 1)
+#define LINE6_BIT_CONTROL_PCM (LINE6_BIT_CONTROL | LINE6_BIT_PCM)
+
+#define LINE6_FALLBACK_INTERVAL 10
+#define LINE6_FALLBACK_MAXPACKETSIZE 16
+
+#endif
diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c
new file mode 100644
index 00000000000..f9d96984733
--- /dev/null
+++ b/drivers/staging/line6/variax.c
@@ -0,0 +1,546 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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 "driver.h"
+
+#include "audio.h"
+#include "control.h"
+#include "variax.h"
+
+
+#define VARIAX_SYSEX_CODE 7
+#define VARIAX_SYSEX_PARAM 0x3b
+#define VARIAX_SYSEX_ACTIVATE 0x2a
+#define VARIAX_MODEL_HEADER_LENGTH 7
+#define VARIAX_MODEL_MESSAGE_LENGTH 199
+#define VARIAX_OFFSET_ACTIVATE 7
+
+
+static const char variax_activate[] = {
+ 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
+ 0xf7
+};
+static const char variax_request_bank[] = {
+ 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7
+};
+static const char variax_request_model1[] = {
+ 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x03,
+ 0x00, 0x00, 0x00, 0xf7
+};
+static const char variax_request_model2[] = {
+ 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03,
+ 0x00, 0x00, 0x00, 0xf7
+};
+
+
+/*
+ Decode data transmitted by workbench.
+*/
+static void variax_decode(const unsigned char *raw_data, unsigned char *data,
+ int raw_size)
+{
+ for (; raw_size > 0; raw_size -= 6) {
+ data[2] = raw_data[0] | (raw_data[1] << 4);
+ data[1] = raw_data[2] | (raw_data[3] << 4);
+ data[0] = raw_data[4] | (raw_data[5] << 4);
+ raw_data += 6;
+ data += 3;
+ }
+}
+
+static void variax_activate_timeout(unsigned long arg)
+{
+ struct usb_line6_variax *variax = (struct usb_line6_variax *)arg;
+ variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = 1;
+ line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
+ sizeof(variax_activate));
+}
+
+/*
+ Send an asynchronous activation request after a given interval.
+*/
+static void variax_activate_delayed(struct usb_line6_variax *variax,
+ int seconds)
+{
+ variax->activate_timer.expires = jiffies + seconds * HZ;
+ variax->activate_timer.function = variax_activate_timeout;
+ variax->activate_timer.data = (unsigned long)variax;
+ add_timer(&variax->activate_timer);
+}
+
+static void variax_startup_timeout(unsigned long arg)
+{
+ struct usb_line6_variax *variax = (struct usb_line6_variax *)arg;
+
+ if (variax->dumpreq.ok)
+ return;
+
+ line6_dump_request_async(&variax->dumpreq, &variax->line6, 0);
+ line6_startup_delayed(&variax->dumpreq, 1, variax_startup_timeout,
+ variax);
+}
+
+/*
+ Process a completely received message.
+*/
+void variax_process_message(struct usb_line6_variax *variax)
+{
+ const unsigned char *buf = variax->line6.buffer_message;
+
+ switch (buf[0]) {
+ case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
+ switch (buf[1]) {
+ case VARIAXMIDI_volume:
+ variax->volume = buf[2];
+ break;
+
+ case VARIAXMIDI_tone:
+ variax->tone = buf[2];
+ }
+
+ break;
+
+ case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
+ case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
+ variax->model = buf[1];
+ line6_dump_request_async(&variax->dumpreq, &variax->line6, 0);
+ break;
+
+ case LINE6_RESET:
+ dev_info(variax->line6.ifcdev, "VARIAX reset\n");
+ variax_activate_delayed(variax, VARIAX_ACTIVATE_DELAY);
+ break;
+
+ case LINE6_SYSEX_BEGIN:
+ if (memcmp(buf + 1, variax_request_model1 + 1,
+ VARIAX_MODEL_HEADER_LENGTH - 1) == 0) {
+ if (variax->line6.message_length ==
+ VARIAX_MODEL_MESSAGE_LENGTH) {
+ switch (variax->dumpreq.in_progress) {
+ case VARIAX_DUMP_PASS1:
+ variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH, (unsigned char *)&variax->model_data,
+ (sizeof(variax->model_data.name) + sizeof(variax->model_data.control) / 2) * 2);
+ line6_dump_request_async(&variax->dumpreq, &variax->line6, 1);
+ line6_dump_started(&variax->dumpreq, VARIAX_DUMP_PASS2);
+ break;
+
+ case VARIAX_DUMP_PASS2:
+ /* model name is transmitted twice, so skip it here: */
+ variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH,
+ (unsigned char *)&variax->model_data.control + sizeof(variax->model_data.control) / 2,
+ sizeof(variax->model_data.control) / 2 * 2);
+ variax->dumpreq.ok = 1;
+ line6_dump_request_async(&variax->dumpreq, &variax->line6, 2);
+ line6_dump_started(&variax->dumpreq, VARIAX_DUMP_PASS3);
+ }
+ } else {
+ DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "illegal length %d of model data\n", variax->line6.message_length));
+ line6_dump_finished(&variax->dumpreq);
+ }
+ } else if (memcmp(buf + 1, variax_request_bank + 1,
+ sizeof(variax_request_bank) - 2) == 0) {
+ memcpy(variax->bank,
+ buf + sizeof(variax_request_bank) - 1,
+ sizeof(variax->bank));
+ variax->dumpreq.ok = 1;
+ line6_dump_finished(&variax->dumpreq);
+ }
+
+ break;
+
+ case LINE6_SYSEX_END:
+ break;
+
+ default:
+ DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "Variax: unknown message %02X\n", buf[0]));
+ }
+}
+
+/*
+ "read" request on "volume" special file.
+*/
+static ssize_t variax_get_volume(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ return sprintf(buf, "%d\n", variax->volume);
+}
+
+/*
+ "write" request on "volume" special file.
+*/
+static ssize_t variax_set_volume(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ int value = simple_strtoul(buf, NULL, 10);
+
+ if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_volume,
+ value) == 0)
+ variax->volume = value;
+
+ return count;
+}
+
+/*
+ "read" request on "model" special file.
+*/
+static ssize_t variax_get_model(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ return sprintf(buf, "%d\n", variax->model);
+}
+
+/*
+ "write" request on "model" special file.
+*/
+static ssize_t variax_set_model(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ int value = simple_strtoul(buf, NULL, 10);
+
+ if (line6_send_program(&variax->line6, value) == 0)
+ variax->model = value;
+
+ return count;
+}
+
+/*
+ "read" request on "active" special file.
+*/
+static ssize_t variax_get_active(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ return sprintf(buf, "%d\n", variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]);
+}
+
+/*
+ "write" request on "active" special file.
+*/
+static ssize_t variax_set_active(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ int value = simple_strtoul(buf, NULL, 10) ? 1 : 0;
+ variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value;
+ line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
+ sizeof(variax_activate));
+ return count;
+}
+
+/*
+ "read" request on "tone" special file.
+*/
+static ssize_t variax_get_tone(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ return sprintf(buf, "%d\n", variax->tone);
+}
+
+/*
+ "write" request on "tone" special file.
+*/
+static ssize_t variax_set_tone(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ int value = simple_strtoul(buf, NULL, 10);
+
+ if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_tone,
+ value) == 0)
+ variax->tone = value;
+
+ return count;
+}
+
+static ssize_t get_string(char *buf, const char *data, int length)
+{
+ int i;
+ memcpy(buf, data, length);
+
+ for (i = length; i--;) {
+ char c = buf[i];
+
+ if ((c != 0) && (c != ' '))
+ break;
+ }
+
+ buf[i + 1] = '\n';
+ return i + 2;
+}
+
+/*
+ "read" request on "name" special file.
+*/
+static ssize_t variax_get_name(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ line6_wait_dump(&variax->dumpreq, 0);
+ return get_string(buf, variax->model_data.name,
+ sizeof(variax->model_data.name));
+}
+
+/*
+ "read" request on "bank" special file.
+*/
+static ssize_t variax_get_bank(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ line6_wait_dump(&variax->dumpreq, 0);
+ return get_string(buf, variax->bank, sizeof(variax->bank));
+}
+
+/*
+ "read" request on "dump" special file.
+*/
+static ssize_t variax_get_dump(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ int retval;
+ retval = line6_wait_dump(&variax->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+ memcpy(buf, &variax->model_data.control,
+ sizeof(variax->model_data.control));
+ return sizeof(variax->model_data.control);
+}
+
+#if CREATE_RAW_FILE
+
+/*
+ "write" request on "raw" special file.
+*/
+static ssize_t variax_set_raw2(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ int size;
+ int i;
+ char *sysex;
+
+ count -= count % 3;
+ size = count * 2;
+ sysex = variax_alloc_sysex_buffer(variax, VARIAX_SYSEX_PARAM, size);
+
+ if (!sysex)
+ return 0;
+
+ for (i = 0; i < count; i += 3) {
+ const unsigned char *p1 = buf + i;
+ char *p2 = sysex + SYSEX_DATA_OFS + i * 2;
+ p2[0] = p1[2] & 0x0f;
+ p2[1] = p1[2] >> 4;
+ p2[2] = p1[1] & 0x0f;
+ p2[3] = p1[1] >> 4;
+ p2[4] = p1[0] & 0x0f;
+ p2[5] = p1[0] >> 4;
+ }
+
+ line6_send_sysex_message(&variax->line6, sysex, size);
+ kfree(sysex);
+ return count;
+}
+
+#endif
+
+/* Variax workbench special files: */
+static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model, variax_set_model);
+static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume, variax_set_volume);
+static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone);
+static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
+static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
+static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
+static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active, variax_set_active);
+
+#if CREATE_RAW_FILE
+static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2);
+#endif
+
+
+/*
+ Variax destructor.
+*/
+static void variax_destruct(struct usb_interface *interface)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(interface);
+ struct usb_line6 *line6;
+
+ if (variax == NULL)
+ return;
+ line6 = &variax->line6;
+ if (line6 == NULL)
+ return;
+ line6_cleanup_audio(line6);
+
+ /* free dump request data: */
+ line6_dumpreq_destructbuf(&variax->dumpreq, 2);
+ line6_dumpreq_destructbuf(&variax->dumpreq, 1);
+ line6_dumpreq_destruct(&variax->dumpreq);
+
+ kfree(variax->buffer_activate);
+ del_timer_sync(&variax->activate_timer);
+}
+
+/*
+ Create sysfs entries.
+*/
+static int variax_create_files2(struct device *dev)
+{
+ int err;
+ CHECK_RETURN(device_create_file(dev, &dev_attr_model));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_volume));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tone));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_name));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_bank));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_active));
+#if CREATE_RAW_FILE
+ CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_raw2));
+#endif
+ return 0;
+}
+
+/*
+ Init workbench device.
+*/
+int variax_init(struct usb_interface *interface,
+ struct usb_line6_variax *variax)
+{
+ int err;
+
+ if ((interface == NULL) || (variax == NULL))
+ return -ENODEV;
+
+ /* initialize USB buffers: */
+ err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1,
+ sizeof(variax_request_model1));
+
+ if (err < 0) {
+ dev_err(&interface->dev, "Out of memory\n");
+ variax_destruct(interface);
+ return err;
+ }
+
+ err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_model2,
+ sizeof(variax_request_model2), 1);
+
+ if (err < 0) {
+ dev_err(&interface->dev, "Out of memory\n");
+ variax_destruct(interface);
+ return err;
+ }
+
+ err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_bank,
+ sizeof(variax_request_bank), 2);
+
+ if (err < 0) {
+ dev_err(&interface->dev, "Out of memory\n");
+ variax_destruct(interface);
+ return err;
+ }
+
+ variax->buffer_activate = kmalloc(sizeof(variax_activate), GFP_KERNEL);
+
+ if (variax->buffer_activate == NULL) {
+ dev_err(&interface->dev, "Out of memory\n");
+ variax_destruct(interface);
+ return -ENOMEM;
+ }
+
+ memcpy(variax->buffer_activate, variax_activate,
+ sizeof(variax_activate));
+ init_timer(&variax->activate_timer);
+
+ /* create sysfs entries: */
+ err = variax_create_files(0, 0, &interface->dev);
+ if (err < 0) {
+ variax_destruct(interface);
+ return err;
+ }
+
+ err = variax_create_files2(&interface->dev);
+ if (err < 0) {
+ variax_destruct(interface);
+ return err;
+ }
+
+ /* initialize audio system: */
+ err = line6_init_audio(&variax->line6);
+ if (err < 0) {
+ variax_destruct(interface);
+ return err;
+ }
+
+ /* initialize MIDI subsystem: */
+ err = line6_init_midi(&variax->line6);
+ if (err < 0) {
+ variax_destruct(interface);
+ return err;
+ }
+
+ /* register audio system: */
+ err = line6_register_audio(&variax->line6);
+ if (err < 0) {
+ variax_destruct(interface);
+ return err;
+ }
+
+ variax_activate_delayed(variax, VARIAX_ACTIVATE_DELAY);
+ line6_startup_delayed(&variax->dumpreq, VARIAX_STARTUP_DELAY,
+ variax_startup_timeout, variax);
+ return 0;
+}
+
+/*
+ Workbench device disconnected.
+*/
+void variax_disconnect(struct usb_interface *interface)
+{
+ struct device *dev;
+
+ if (interface == NULL)
+ return;
+ dev = &interface->dev;
+
+ if (dev != NULL) {
+ /* remove sysfs entries: */
+ variax_remove_files(0, 0, dev);
+ device_remove_file(dev, &dev_attr_model);
+ device_remove_file(dev, &dev_attr_volume);
+ device_remove_file(dev, &dev_attr_tone);
+ device_remove_file(dev, &dev_attr_name);
+ device_remove_file(dev, &dev_attr_bank);
+ device_remove_file(dev, &dev_attr_dump);
+ device_remove_file(dev, &dev_attr_active);
+#if CREATE_RAW_FILE
+ device_remove_file(dev, &dev_attr_raw);
+ device_remove_file(dev, &dev_attr_raw2);
+#endif
+ }
+
+ variax_destruct(interface);
+}
diff --git a/drivers/staging/line6/variax.h b/drivers/staging/line6/variax.h
new file mode 100644
index 00000000000..ee330ba3089
--- /dev/null
+++ b/drivers/staging/line6/variax.h
@@ -0,0 +1,108 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * 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.
+ *
+ */
+
+#ifndef VARIAX_H
+#define VARIAX_H
+
+
+#include "driver.h"
+
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+
+#include <sound/core.h>
+
+#include "dumprequest.h"
+
+
+#define VARIAX_ACTIVATE_DELAY 10
+#define VARIAX_STARTUP_DELAY 3
+
+
+enum {
+ VARIAX_DUMP_PASS1 = LINE6_DUMP_CURRENT,
+ VARIAX_DUMP_PASS2,
+ VARIAX_DUMP_PASS3
+};
+
+
+/**
+ Binary Variax model dump
+*/
+struct variax_model {
+ /**
+ Header information (including program name).
+ */
+ unsigned char name[18];
+
+ /**
+ Model parameters.
+ */
+ unsigned char control[78 * 2];
+};
+
+struct usb_line6_variax {
+ /**
+ Generic Line6 USB data.
+ */
+ struct usb_line6 line6;
+
+ /**
+ Dump request structure.
+ Append two extra buffers for 3-pass data query.
+ */
+ struct line6_dump_request dumpreq; struct line6_dump_reqbuf extrabuf[2];
+
+ /**
+ Buffer for activation code.
+ */
+ unsigned char *buffer_activate;
+
+ /**
+ Model number.
+ */
+ int model;
+
+ /**
+ Current model settings.
+ */
+ struct variax_model model_data;
+
+ /**
+ Name of current model bank.
+ */
+ unsigned char bank[18];
+
+ /**
+ Position of volume dial.
+ */
+ int volume;
+
+ /**
+ Position of tone control dial.
+ */
+ int tone;
+
+ /**
+ Timer for delayed activation request.
+ */
+ struct timer_list activate_timer;
+};
+
+
+extern void variax_disconnect(struct usb_interface *interface);
+extern int variax_init(struct usb_interface *interface,
+ struct usb_line6_variax *variax);
+extern void variax_process_message(struct usb_line6_variax *variax);
+
+
+#endif
diff --git a/drivers/staging/me4000/me4000.c b/drivers/staging/me4000/me4000.c
index e1c4a807890..01017b731d0 100644
--- a/drivers/staging/me4000/me4000.c
+++ b/drivers/staging/me4000/me4000.c
@@ -36,8 +36,8 @@
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
#include <asm/system.h>
/* Include-File for the Meilhaus ME-4000 I/O board */
@@ -246,17 +246,17 @@ static irqreturn_t me4000_ext_int_isr(int, void *);
Inline functions
---------------------------------------------------------------------------*/
-static int inline me4000_buf_count(struct me4000_circ_buf buf, int size)
+static inline int me4000_buf_count(struct me4000_circ_buf buf, int size)
{
- return ((buf.head - buf.tail) & (size - 1));
+ return (buf.head - buf.tail) & (size - 1);
}
-static int inline me4000_buf_space(struct me4000_circ_buf buf, int size)
+static inline int me4000_buf_space(struct me4000_circ_buf buf, int size)
{
- return ((buf.tail - (buf.head + 1)) & (size - 1));
+ return (buf.tail - (buf.head + 1)) & (size - 1);
}
-static int inline me4000_values_to_end(struct me4000_circ_buf buf, int size)
+static inline int me4000_values_to_end(struct me4000_circ_buf buf, int size)
{
int end;
int n;
@@ -265,7 +265,7 @@ static int inline me4000_values_to_end(struct me4000_circ_buf buf, int size)
return (n < end) ? n : end;
}
-static int inline me4000_space_to_end(struct me4000_circ_buf buf, int size)
+static inline int me4000_space_to_end(struct me4000_circ_buf buf, int size)
{
int end;
int n;
@@ -275,19 +275,19 @@ static int inline me4000_space_to_end(struct me4000_circ_buf buf, int size)
return (n <= end) ? n : (end + 1);
}
-static void inline me4000_outb(unsigned char value, unsigned long port)
+static inline void me4000_outb(unsigned char value, unsigned long port)
{
PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
outb(value, port);
}
-static void inline me4000_outl(unsigned long value, unsigned long port)
+static inline 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 inline me4000_inl(unsigned long port)
+static inline unsigned long me4000_inl(unsigned long port)
{
unsigned long value;
value = inl(port);
@@ -295,7 +295,7 @@ static unsigned long inline me4000_inl(unsigned long port)
return value;
}
-static unsigned char inline me4000_inb(unsigned long port)
+static inline unsigned char me4000_inb(unsigned long port)
{
unsigned char value;
value = inb(port);
@@ -309,7 +309,7 @@ static struct pci_driver me4000_driver = {
.probe = me4000_probe
};
-static struct file_operations me4000_ao_fops_sing = {
+static const struct file_operations me4000_ao_fops_sing = {
.owner = THIS_MODULE,
.write = me4000_ao_write_sing,
.ioctl = me4000_ao_ioctl_sing,
@@ -317,7 +317,7 @@ static struct file_operations me4000_ao_fops_sing = {
.release = me4000_release,
};
-static struct file_operations me4000_ao_fops_wrap = {
+static const struct file_operations me4000_ao_fops_wrap = {
.owner = THIS_MODULE,
.write = me4000_ao_write_wrap,
.ioctl = me4000_ao_ioctl_wrap,
@@ -325,7 +325,7 @@ static struct file_operations me4000_ao_fops_wrap = {
.release = me4000_release,
};
-static struct file_operations me4000_ao_fops_cont = {
+static const struct file_operations me4000_ao_fops_cont = {
.owner = THIS_MODULE,
.write = me4000_ao_write_cont,
.poll = me4000_ao_poll_cont,
@@ -335,14 +335,14 @@ static struct file_operations me4000_ao_fops_cont = {
.fsync = me4000_ao_fsync_cont,
};
-static struct file_operations me4000_ai_fops_sing = {
+static const 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 = {
+static const struct file_operations me4000_ai_fops_cont_sw = {
.owner = THIS_MODULE,
.read = me4000_ai_read,
.poll = me4000_ai_poll,
@@ -352,7 +352,7 @@ static struct file_operations me4000_ai_fops_cont_sw = {
.fasync = me4000_ai_fasync,
};
-static struct file_operations me4000_ai_fops_cont_et = {
+static const struct file_operations me4000_ai_fops_cont_et = {
.owner = THIS_MODULE,
.read = me4000_ai_read,
.poll = me4000_ai_poll,
@@ -361,7 +361,7 @@ static struct file_operations me4000_ai_fops_cont_et = {
.release = me4000_release,
};
-static struct file_operations me4000_ai_fops_cont_et_value = {
+static const struct file_operations me4000_ai_fops_cont_et_value = {
.owner = THIS_MODULE,
.read = me4000_ai_read,
.poll = me4000_ai_poll,
@@ -370,7 +370,7 @@ static struct file_operations me4000_ai_fops_cont_et_value = {
.release = me4000_release,
};
-static struct file_operations me4000_ai_fops_cont_et_chanlist = {
+static const struct file_operations me4000_ai_fops_cont_et_chanlist = {
.owner = THIS_MODULE,
.read = me4000_ai_read,
.poll = me4000_ai_poll,
@@ -379,21 +379,21 @@ static struct file_operations me4000_ai_fops_cont_et_chanlist = {
.release = me4000_release,
};
-static struct file_operations me4000_dio_fops = {
+static const 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 = {
+static const 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 = {
+static const struct file_operations me4000_ext_int_fops = {
.owner = THIS_MODULE,
.ioctl = me4000_ext_int_ioctl,
.open = me4000_open,
@@ -401,18 +401,26 @@ static struct file_operations me4000_ext_int_fops = {
.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 const struct file_operations *me4000_ao_fops_array[] = {
+ /* single operations */
+ &me4000_ao_fops_sing,
+ /* wraparound operations */
+ &me4000_ao_fops_wrap,
+ /* continuous operations */
+ &me4000_ao_fops_cont,
};
-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
+static const struct file_operations *me4000_ai_fops_array[] = {
+ /* single operations */
+ &me4000_ai_fops_sing,
+ /* continuous operations with software start */
+ &me4000_ai_fops_cont_sw,
+ /* continuous operations with external trigger */
+ &me4000_ai_fops_cont_et,
+ /* sample values by external trigger */
+ &me4000_ai_fops_cont_et_value,
+ /* work through one channel list by external trigger */
+ &me4000_ai_fops_cont_et_chanlist,
};
static int __init me4000_init_module(void)
@@ -546,15 +554,13 @@ static void clear_board_info_list(void)
&board_info->ao_context_list, 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);
+ kfree(ao_context->circ_buf.buf);
list_del(&ao_context->list);
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->circ_buf.buf);
kfree(board_info->ai_context);
/* Clear digital I/O context */
@@ -1263,9 +1269,8 @@ static int me4000_reset_board(struct me4000_info *info)
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)) {
+ if (!(me4000_inl(info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1))
me4000_outl(0x1, info->me4000_regbase + ME4000_DIO_CTRL_REG);
- }
return 0;
}
@@ -1463,7 +1468,7 @@ static int me4000_open(struct inode *inode_p, struct file *file_p)
/* Set file operations pointer to single functions */
file_p->f_op = &me4000_dio_fops;
- //me4000_dio_reset(dio_context);
+ /* me4000_dio_reset(dio_context); */
}
/* Counters */
else if (MAJOR(inode_p->i_rdev) == me4000_cnt_major_driver_no) {
@@ -2058,7 +2063,7 @@ static ssize_t me4000_ao_write_cont(struct file *filep, const char *buff,
ME4000_AO_BUFFER_COUNT);
if (c == 0)
- return (2 * ret);
+ return 2 * ret;
/* Only able to write size of free buffer or size of count */
if (count < c)
@@ -2104,9 +2109,8 @@ static ssize_t me4000_ao_write_cont(struct file *filep, const char *buff,
}
}
- if (filep->f_flags & O_NONBLOCK) {
+ if (filep->f_flags & O_NONBLOCK)
return (ret == 0) ? -EAGAIN : 2 * ret;
- }
return 2 * ret;
}
@@ -2201,7 +2205,7 @@ static int me4000_ao_ioctl_sing(struct inode *inode_p, struct file *file_p,
case ME4000_AO_SIMULTANEOUS_UPDATE:
return
me4000_ao_simultaneous_update(
- (struct me4000_ao_channel_list *)arg,
+ (struct me4000_ao_channel_list *)arg,
ao_context);
case ME4000_AO_EX_TRIG_TIMEOUT:
return me4000_ao_ex_trig_timeout((unsigned long *)arg,
@@ -2361,7 +2365,9 @@ static int me4000_ao_start(unsigned long *arg,
"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
+ /* kernel 2.6 has different definitions for HZ
+ * in user and kernel space */
+ if ((jiffies - ref) > (timeout * HZ / USER_HZ)) {
printk(KERN_ERR
"ME4000:me4000_ao_start():Timeout reached\n");
return -EIO;
@@ -2402,8 +2408,8 @@ static int me4000_ao_stop(struct me4000_ao_context *ao_context)
}
/* Clear the stop bit */
- //tmp &= ~ME4000_AO_CTRL_BIT_STOP;
- //me4000_outl(tmp, ao_context->ctrl_reg);
+ /* tmp &= ~ME4000_AO_CTRL_BIT_STOP; */
+ /* me4000_outl(tmp, ao_context->ctrl_reg); */
return 0;
}
@@ -2434,8 +2440,8 @@ static int me4000_ao_immediate_stop(struct me4000_ao_context *ao_context)
}
/* Clear the stop bits */
- //tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
- //me4000_outl(tmp, ao_context->ctrl_reg);
+ /* tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP); */
+ /* me4000_outl(tmp, ao_context->ctrl_reg); */
return 0;
}
@@ -2598,8 +2604,10 @@ static int me4000_ao_simultaneous_disable(struct me4000_ao_context *ao_context)
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
+ /* Disable preload bit */
+ tmp &= ~(0x1 << ao_context->index);
+ /* Disable hw simultaneous bit */
+ tmp &= ~(0x1 << (ao_context->index + 16));
me4000_outl(tmp, ao_context->preload_reg);
spin_unlock(&ao_context->board_info->preload_lock);
@@ -2614,8 +2622,10 @@ static int me4000_ao_simultaneous_ex_trig(struct me4000_ao_context *ao_context)
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
+ /* Enable preload bit */
+ tmp |= (0x1 << ao_context->index);
+ /* Enable hw simulatenous bit */
+ tmp |= (0x1 << (ao_context->index + 16));
me4000_outl(tmp, ao_context->preload_reg);
spin_unlock(&ao_context->board_info->preload_lock);
@@ -2630,8 +2640,10 @@ static int me4000_ao_simultaneous_sw(struct me4000_ao_context *ao_context)
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
+ /* Enable preload bit */
+ tmp |= (0x1 << ao_context->index);
+ /* Enable hw simulatenous bit */
+ tmp &= ~(0x1 << (ao_context->index + 16));
me4000_outl(tmp, ao_context->preload_reg);
spin_unlock(&ao_context->board_info->preload_lock);
@@ -2669,11 +2681,11 @@ static int me4000_ao_preload_update(struct me4000_ao_context *ao_context)
(tmp &
(0x1 <<
(((struct me4000_ao_context *)entry)->index
- + 16)))) {
+ + 16)))) {
tmp &=
~(0x1 <<
(((struct me4000_ao_context *)entry)->
- index));
+ index));
}
}
}
@@ -2732,8 +2744,10 @@ static int me4000_ao_simultaneous_update(struct me4000_ao_channel_list *arg,
"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
+ /* Clear the preload bit */
+ tmp &= ~(0x1 << channels.list[i]);
+ /* Clear the hw simultaneous bit */
+ tmp &= ~(0x1 << (channels.list[i] + 16));
}
me4000_outl(tmp, ao_context->preload_reg);
spin_unlock(&ao_context->board_info->preload_lock);
@@ -2759,8 +2773,10 @@ static int me4000_ao_synchronous_ex_trig(struct me4000_ao_context *ao_context)
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
+ /* Disable synchronous sw bit */
+ tmp &= ~(0x1 << ao_context->index);
+ /* Enable synchronous hw bit */
+ tmp |= 0x1 << (ao_context->index + 16);
me4000_outl(tmp, ao_context->preload_reg);
spin_unlock(&ao_context->board_info->preload_lock);
@@ -2794,8 +2810,10 @@ static int me4000_ao_synchronous_sw(struct me4000_ao_context *ao_context)
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
+ /* Enable synchronous sw bit */
+ tmp |= 0x1 << ao_context->index;
+ /* Disable synchronous hw bit */
+ tmp &= ~(0x1 << (ao_context->index + 16));
me4000_outl(tmp, ao_context->preload_reg);
spin_unlock(&ao_context->board_info->preload_lock);
@@ -2867,7 +2885,9 @@ static int me4000_ao_ex_trig_timeout(unsigned long *arg,
"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
+ /* kernel 2.6 has different definitions for HZ
+ * in user and kernel space */
+ if ((jiffies - ref) > (timeout * HZ / USER_HZ)) {
printk(KERN_ERR
"ME4000:me4000_ao_ex_trig_timeout():Timeout reached\n");
return -EIO;
@@ -3243,7 +3263,8 @@ static int me4000_ai_single(struct me4000_ai_single *arg,
"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
+ /* 2.6 has different definitions for HZ in user and kernel space */
+ if (((jiffies - jiffy) > (cmd.timeout * HZ / USER_HZ)) && cmd.timeout) {
printk(KERN_ERR
"ME4000:me4000_ai_single():Timeout reached\n");
return -EIO;
@@ -3622,9 +3643,8 @@ static int me4000_ai_config(struct me4000_ai_config *arg,
me4000_outl(tmp, ai_context->ctrl_reg);
/* Write the channel list */
- for (i = 0; i < cmd.channel_list.count; i++) {
+ 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) {
@@ -3663,8 +3683,7 @@ AI_CONFIG_ERR:
tmp &=
~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_SAMPLE_HOLD);
- if (list)
- kfree(list);
+ kfree(list);
return err;
@@ -3774,25 +3793,22 @@ static int me4000_ai_start_ex(unsigned long *arg,
if (timeout) {
ref = jiffies;
- while (!
- (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM))
- {
+ 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
+ /* 2.6 has different definitions for HZ in user and kernel space */
+ if ((jiffies - ref) > (timeout * HZ / USER_HZ)) {
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))
- {
+ while (!(inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM)) {
interruptible_sleep_on_timeout(&queue, 1);
if (signal_pending(current)) {
printk(KERN_ERR
@@ -4113,9 +4129,8 @@ static ssize_t me4000_ai_read(struct file *filep, char *buff, size_t cnt,
return -EPIPE;
}
- if (filep->f_flags & O_NONBLOCK) {
+ if (filep->f_flags & O_NONBLOCK)
return (k == 0) ? -EAGAIN : 2 * ret;
- }
CALL_PDEBUG("me4000_ai_read() is leaved\n");
return ret * 2;
@@ -4254,11 +4269,10 @@ static int eeprom_write_cmd(struct me4000_ai_context *ai_context, unsigned long
udelay(EEPROM_DELAY);
for (i = 0; i < length; i++) {
- if (cmd & ((0x1 << (length - 1)) >> i)) {
+ if (cmd & ((0x1 << (length - 1)) >> i))
value |= PLX_ICR_BIT_EEPROM_WRITE;
- } else {
+ else
value &= ~PLX_ICR_BIT_EEPROM_WRITE;
- }
/* Write to EEPROM */
me4000_outl(value,
@@ -4314,11 +4328,11 @@ static unsigned short eeprom_read_cmd(struct me4000_ai_context *ai_context,
/* Write the read command to the eeprom */
for (i = 0; i < length; i++) {
- if (cmd & ((0x1 << (length - 1)) >> i)) {
+ if (cmd & ((0x1 << (length - 1)) >> i))
value |= PLX_ICR_BIT_EEPROM_WRITE;
- } else {
+ else
value &= ~PLX_ICR_BIT_EEPROM_WRITE;
- }
+
me4000_outl(value,
ai_context->board_info->plx_regbase + PLX_ICR);
udelay(EEPROM_DELAY);
@@ -5440,8 +5454,6 @@ static irqreturn_t me4000_ao_isr(int irq, void *dev_id)
int i;
int c = 0;
int c1 = 0;
- //unsigned long before;
- //unsigned long after;
ISR_PDEBUG("me4000_ao_isr() is executed\n");
@@ -5493,7 +5505,6 @@ static irqreturn_t me4000_ao_isr(int irq, void *dev_id)
("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++) {
@@ -5509,8 +5520,6 @@ static irqreturn_t me4000_ao_isr(int irq, void *dev_id)
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 -
@@ -5542,8 +5551,10 @@ static irqreturn_t me4000_ao_isr(int irq, void *dev_id)
/* 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
+ /* Set flag in order to inform write routine */
+ ao_context->pipe_flag = 1;
+ /* Disable interrupt */
+ tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_IRQ;
}
me4000_outl(tmp, ao_context->ctrl_reg);
spin_unlock(&ao_context->int_lock);
diff --git a/drivers/staging/meilhaus/me0600_device.c b/drivers/staging/meilhaus/me0600_device.c
index 8950e47e0e8..bae17d26416 100644
--- a/drivers/staging/meilhaus/me0600_device.c
+++ b/drivers/staging/meilhaus/me0600_device.c
@@ -186,6 +186,7 @@ me_device_t *me0600_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me0600_device;
}
+EXPORT_SYMBOL(me0600_pci_constructor);
// Init and exit of module.
@@ -210,6 +211,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for ME-6xx Device");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-6xx Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me0600_pci_constructor);
diff --git a/drivers/staging/meilhaus/me0600_dio.c b/drivers/staging/meilhaus/me0600_dio.c
index 3a2775749a2..d29303518be 100644
--- a/drivers/staging/meilhaus/me0600_dio.c
+++ b/drivers/staging/meilhaus/me0600_dio.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -91,7 +91,7 @@ static int me0600_dio_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_dio_io_single_config(me_subdevice_t * subdevice,
+static int me0600_dio_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -162,7 +162,7 @@ static int me0600_dio_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me0600_dio_io_single_read(me_subdevice_t * subdevice,
+static int me0600_dio_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -242,7 +242,7 @@ static int me0600_dio_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me0600_dio_io_single_write(me_subdevice_t * subdevice,
+static int me0600_dio_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -329,7 +329,7 @@ static int me0600_dio_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me0600_dio_query_number_channels(me_subdevice_t * subdevice,
+static int me0600_dio_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -337,7 +337,7 @@ static int me0600_dio_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_dio_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0600_dio_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -346,7 +346,7 @@ static int me0600_dio_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_dio_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me0600_dio_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -356,7 +356,7 @@ static int me0600_dio_query_subdevice_caps(me_subdevice_t * subdevice,
me0600_dio_subdevice_t *me0600_dio_constructor(uint32_t reg_base,
unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me0600_dio_subdevice_t *subdevice;
int err;
@@ -381,7 +381,7 @@ me0600_dio_subdevice_t *me0600_dio_constructor(uint32_t reg_base,
kfree(subdevice);
return NULL;
}
- // Initialize spin locks.
+ /* Initialize spin locks. */
spin_lock_init(&subdevice->subdevice_lock);
subdevice->ctrl_reg_lock = ctrl_reg_lock;
diff --git a/drivers/staging/meilhaus/me0600_ext_irq.c b/drivers/staging/meilhaus/me0600_ext_irq.c
index eba18adecb7..2f6fedca322 100644
--- a/drivers/staging/meilhaus/me0600_ext_irq.c
+++ b/drivers/staging/meilhaus/me0600_ext_irq.c
@@ -37,7 +37,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/interrupt.h>
@@ -337,11 +337,7 @@ static void me0600_ext_irq_destructor(struct me_subdevice *subdevice)
kfree(instance);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me0600_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me0600_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
me0600_ext_irq_subdevice_t *instance;
uint32_t status;
@@ -397,7 +393,7 @@ static irqreturn_t me0600_isr(int irq, void *dev_id, struct pt_regs *regs)
me0600_ext_irq_subdevice_t *me0600_ext_irq_constructor(uint32_t plx_reg_base,
uint32_t me0600_reg_base,
- spinlock_t * intcsr_lock,
+ spinlock_t *intcsr_lock,
unsigned ext_irq_idx,
int irq)
{
diff --git a/drivers/staging/meilhaus/me0600_optoi.c b/drivers/staging/meilhaus/me0600_optoi.c
index b6d977f228c..43f710ffd27 100644
--- a/drivers/staging/meilhaus/me0600_optoi.c
+++ b/drivers/staging/meilhaus/me0600_optoi.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -68,7 +68,7 @@ static int me0600_optoi_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_optoi_io_single_config(me_subdevice_t * subdevice,
+static int me0600_optoi_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -118,7 +118,7 @@ static int me0600_optoi_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me0600_optoi_io_single_read(me_subdevice_t * subdevice,
+static int me0600_optoi_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -169,7 +169,7 @@ static int me0600_optoi_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me0600_optoi_query_number_channels(me_subdevice_t * subdevice,
+static int me0600_optoi_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -177,7 +177,7 @@ static int me0600_optoi_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_optoi_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0600_optoi_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -186,7 +186,7 @@ static int me0600_optoi_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_optoi_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me0600_optoi_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -219,7 +219,7 @@ me0600_optoi_subdevice_t *me0600_optoi_constructor(uint32_t reg_base)
kfree(subdevice);
return NULL;
}
- // Initialize spin locks.
+ /* Initialize spin locks. */
spin_lock_init(&subdevice->subdevice_lock);
/* Save the subdevice index */
diff --git a/drivers/staging/meilhaus/me0600_relay.c b/drivers/staging/meilhaus/me0600_relay.c
index 2665c69addd..03835e3df25 100644
--- a/drivers/staging/meilhaus/me0600_relay.c
+++ b/drivers/staging/meilhaus/me0600_relay.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -85,7 +85,7 @@ static int me0600_relay_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_relay_io_single_config(me_subdevice_t * subdevice,
+static int me0600_relay_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -135,7 +135,7 @@ static int me0600_relay_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me0600_relay_io_single_read(me_subdevice_t * subdevice,
+static int me0600_relay_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -203,7 +203,7 @@ static int me0600_relay_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me0600_relay_io_single_write(me_subdevice_t * subdevice,
+static int me0600_relay_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -279,7 +279,7 @@ static int me0600_relay_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me0600_relay_query_number_channels(me_subdevice_t * subdevice,
+static int me0600_relay_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -287,7 +287,7 @@ static int me0600_relay_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_relay_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0600_relay_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -296,7 +296,7 @@ static int me0600_relay_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_relay_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me0600_relay_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
diff --git a/drivers/staging/meilhaus/me0600_ttli.c b/drivers/staging/meilhaus/me0600_ttli.c
index ab8e13b6f32..7d970f584cc 100644
--- a/drivers/staging/meilhaus/me0600_ttli.c
+++ b/drivers/staging/meilhaus/me0600_ttli.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -67,7 +67,7 @@ static int me0600_ttli_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_ttli_io_single_config(me_subdevice_t * subdevice,
+static int me0600_ttli_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -116,7 +116,7 @@ static int me0600_ttli_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me0600_ttli_io_single_read(me_subdevice_t * subdevice,
+static int me0600_ttli_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -164,7 +164,7 @@ static int me0600_ttli_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me0600_ttli_query_number_channels(me_subdevice_t * subdevice,
+static int me0600_ttli_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -172,7 +172,7 @@ static int me0600_ttli_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_ttli_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0600_ttli_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -181,7 +181,7 @@ static int me0600_ttli_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_ttli_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me0600_ttli_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
diff --git a/drivers/staging/meilhaus/me0900_device.c b/drivers/staging/meilhaus/me0900_device.c
index 764d5d307c4..e9c6884b5d2 100644
--- a/drivers/staging/meilhaus/me0900_device.c
+++ b/drivers/staging/meilhaus/me0900_device.c
@@ -152,6 +152,7 @@ me_device_t *me0900_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me0900_device;
}
+EXPORT_SYMBOL(me0900_pci_constructor);
// Init and exit of module.
@@ -175,6 +176,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for ME-9x Device");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-9x Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me0900_pci_constructor);
diff --git a/drivers/staging/meilhaus/me0900_di.c b/drivers/staging/meilhaus/me0900_di.c
index d7d7394f800..4665b2acbea 100644
--- a/drivers/staging/meilhaus/me0900_di.c
+++ b/drivers/staging/meilhaus/me0900_di.c
@@ -35,7 +35,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/version.h>
@@ -71,7 +71,7 @@ static int me0900_di_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0900_di_io_single_config(me_subdevice_t * subdevice,
+static int me0900_di_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -115,7 +115,7 @@ static int me0900_di_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me0900_di_io_single_read(me_subdevice_t * subdevice,
+static int me0900_di_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -161,7 +161,7 @@ static int me0900_di_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me0900_di_query_number_channels(me_subdevice_t * subdevice,
+static int me0900_di_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -169,7 +169,7 @@ static int me0900_di_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0900_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0900_di_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -178,7 +178,7 @@ static int me0900_di_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0900_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me0900_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = 0;
diff --git a/drivers/staging/meilhaus/me0900_do.c b/drivers/staging/meilhaus/me0900_do.c
index b5b9c3a98c9..a2275faf1a0 100644
--- a/drivers/staging/meilhaus/me0900_do.c
+++ b/drivers/staging/meilhaus/me0900_do.c
@@ -35,7 +35,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -81,7 +81,7 @@ static int me0900_do_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0900_do_io_single_config(me_subdevice_t * subdevice,
+static int me0900_do_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -125,7 +125,7 @@ static int me0900_do_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me0900_do_io_single_read(me_subdevice_t * subdevice,
+static int me0900_do_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -171,7 +171,7 @@ static int me0900_do_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me0900_do_io_single_write(me_subdevice_t * subdevice,
+static int me0900_do_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -223,7 +223,7 @@ static int me0900_do_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me0900_do_query_number_channels(me_subdevice_t * subdevice,
+static int me0900_do_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -231,7 +231,7 @@ static int me0900_do_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0900_do_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0900_do_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -240,7 +240,7 @@ static int me0900_do_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0900_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me0900_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = 0;
diff --git a/drivers/staging/meilhaus/me1000_device.c b/drivers/staging/meilhaus/me1000_device.c
index c44e214af26..cf0fb92f24c 100644
--- a/drivers/staging/meilhaus/me1000_device.c
+++ b/drivers/staging/meilhaus/me1000_device.c
@@ -49,8 +49,8 @@
#include "mesubdevice.h"
#include "me1000_dio.h"
-static int me1000_config_load(me_device_t * me_device, struct file *filep,
- me_cfg_device_entry_t * config)
+static int me1000_config_load(me_device_t *me_device, struct file *filep,
+ me_cfg_device_entry_t *config)
{
me1000_device_t *me1000_device;
me1000_dio_subdevice_t *dio;
@@ -181,6 +181,7 @@ me_device_t *me1000_pci_constructor(struct pci_dev * pci_device)
return (me_device_t *) me1000_device;
}
+EXPORT_SYMBOL(me1000_pci_constructor);
// Init and exit of module.
static int __init me1000_init(void)
@@ -203,6 +204,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-1000 Devices");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-1000 Digital I/O Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me1000_pci_constructor);
diff --git a/drivers/staging/meilhaus/me1000_dio.c b/drivers/staging/meilhaus/me1000_dio.c
index 87605a9108a..2d7ed07d1f3 100644
--- a/drivers/staging/meilhaus/me1000_dio.c
+++ b/drivers/staging/meilhaus/me1000_dio.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -371,7 +371,7 @@ static int me1000_dio_query_subdevice_caps(struct me_subdevice *subdevice,
me1000_dio_subdevice_t *me1000_dio_constructor(uint32_t reg_base,
unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me1000_dio_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me1400_device.c b/drivers/staging/meilhaus/me1400_device.c
index b95bb4fce6a..ca7498b9056 100644
--- a/drivers/staging/meilhaus/me1400_device.c
+++ b/drivers/staging/meilhaus/me1400_device.c
@@ -228,6 +228,7 @@ me_device_t *me1400_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me1400_device;
}
+EXPORT_SYMBOL(me1400_pci_constructor);
// Init and exit of module.
@@ -251,6 +252,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-14xx devices");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-14xx MIO devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me1400_pci_constructor);
diff --git a/drivers/staging/meilhaus/me1400_ext_irq.c b/drivers/staging/meilhaus/me1400_ext_irq.c
index b4df7cc58ab..0dc6b4519b5 100644
--- a/drivers/staging/meilhaus/me1400_ext_irq.c
+++ b/drivers/staging/meilhaus/me1400_ext_irq.c
@@ -37,7 +37,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/interrupt.h>
@@ -323,12 +323,7 @@ static int me1400_ext_irq_query_subdevice_caps_args(struct me_subdevice
return ME_ERRNO_NOT_SUPPORTED;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me1400_ext_irq_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me1400_ext_irq_isr(int irq, void *dev_id,
- struct pt_regs *regs)
-#endif
{
me1400_ext_irq_subdevice_t *instance;
uint32_t status;
diff --git a/drivers/staging/meilhaus/me1600_ao.c b/drivers/staging/meilhaus/me1600_ao.c
index d127c6b0030..12e3c70e982 100644
--- a/drivers/staging/meilhaus/me1600_ao.c
+++ b/drivers/staging/meilhaus/me1600_ao.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/sched.h>
@@ -55,36 +55,32 @@
static void me1600_ao_destructor(struct me_subdevice *subdevice);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me1600_ao_work_control_task(void *subdevice);
-#else
static void me1600_ao_work_control_task(struct work_struct *work);
-#endif
-static int me1600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me1600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags);
-static int me1600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep, int channel,
int single_config, int ref, int trig_chan,
int trig_type, int trig_edge, int flags);
-static int me1600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep, int channel, int *value,
int time_out, int flags);
-static int me1600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep, int channel, int value,
int time_out, int flags);
-static int me1600_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me1600_ao_query_number_channels(me_subdevice_t *subdevice,
int *number);
-static int me1600_ao_query_subdevice_type(me_subdevice_t * subdevice, int *type,
+static int me1600_ao_query_subdevice_type(me_subdevice_t *subdevice, int *type,
int *subtype);
-static int me1600_ao_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me1600_ao_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps);
-static int me1600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me1600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
int unit, int *min, int *max,
int *maxdata, int *range);
-static int me1600_ao_query_number_ranges(me_subdevice_t * subdevice, int unit,
+static int me1600_ao_query_number_ranges(me_subdevice_t *subdevice, int unit,
int *count);
-static int me1600_ao_query_range_info(me_subdevice_t * subdevice, int range,
+static int me1600_ao_query_range_info(me_subdevice_t *subdevice, int range,
int *unit, int *min, int *max,
int *maxdata);
@@ -94,10 +90,9 @@ static int me1600_ao_query_range_info(me_subdevice_t * subdevice, int range,
me1600_ao_subdevice_t *me1600_ao_constructor(uint32_t reg_base,
unsigned int ao_idx,
int curr,
- spinlock_t * config_regs_lock,
- spinlock_t * ao_shadows_lock,
- me1600_ao_shadow_t *
- ao_regs_shadows,
+ spinlock_t *config_regs_lock,
+ spinlock_t *ao_shadows_lock,
+ me1600_ao_shadow_t *ao_regs_shadows,
struct workqueue_struct *me1600_wq)
{
me1600_ao_subdevice_t *subdevice;
@@ -200,13 +195,8 @@ me1600_ao_subdevice_t *me1600_ao_constructor(uint32_t reg_base,
subdevice->me1600_workqueue = me1600_wq;
/* workqueue API changed in kernel 2.6.20 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
- INIT_WORK(&subdevice->ao_control_task, me1600_ao_work_control_task,
- (void *)subdevice);
-#else
INIT_DELAYED_WORK(&subdevice->ao_control_task,
me1600_ao_work_control_task);
-#endif
return subdevice;
}
@@ -231,7 +221,7 @@ static void me1600_ao_destructor(struct me_subdevice *subdevice)
}
}
-static int me1600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me1600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags)
{
me1600_ao_subdevice_t *instance;
@@ -313,7 +303,7 @@ static int me1600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -545,7 +535,7 @@ static int me1600_ao_io_single_config(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -612,7 +602,7 @@ static int me1600_ao_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me1600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -756,7 +746,9 @@ static int me1600_ao_io_single_write(me_subdevice_t * subdevice,
queue_delayed_work(instance->me1600_workqueue,
&instance->ao_control_task, 1);
- if ((!flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING) && ((instance->ao_regs_shadows)->trigger & instance->ao_idx)) { //Blocking mode. Wait for software trigger.
+ if ((!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) &&
+ ((instance->ao_regs_shadows)->trigger & instance->ao_idx)) {
+ /* Blocking mode. Wait for software trigger. */
if (time_out) {
delay = (time_out * HZ) / 1000;
if (delay == 0)
@@ -793,7 +785,7 @@ static int me1600_ao_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me1600_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me1600_ao_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
me1600_ao_subdevice_t *instance;
@@ -805,7 +797,7 @@ static int me1600_ao_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_query_subdevice_type(me_subdevice_t * subdevice, int *type,
+static int me1600_ao_query_subdevice_type(me_subdevice_t *subdevice, int *type,
int *subtype)
{
me1600_ao_subdevice_t *instance;
@@ -818,14 +810,14 @@ static int me1600_ao_query_subdevice_type(me_subdevice_t * subdevice, int *type,
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me1600_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = ME_CAPS_AO_TRIG_SYNCHRONOUS;
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me1600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range)
@@ -903,7 +895,7 @@ static int me1600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me1600_ao_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count)
{
me1600_ao_subdevice_t *instance;
@@ -928,7 +920,7 @@ static int me1600_ao_query_number_ranges(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_query_range_info(me_subdevice_t * subdevice,
+static int me1600_ao_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata)
@@ -960,22 +952,14 @@ static int me1600_ao_query_range_info(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me1600_ao_work_control_task(void *subdevice)
-#else
static void me1600_ao_work_control_task(struct work_struct *work)
-#endif
{
me1600_ao_subdevice_t *instance;
int reschedule = 1;
int signaling = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- instance = (me1600_ao_subdevice_t *) subdevice;
-#else
instance =
container_of((void *)work, me1600_ao_subdevice_t, ao_control_task);
-#endif
PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
instance->ao_idx);
diff --git a/drivers/staging/meilhaus/me1600_ao.h b/drivers/staging/meilhaus/me1600_ao.h
index b82bf5a1676..4827dcb4bf4 100644
--- a/drivers/staging/meilhaus/me1600_ao.h
+++ b/drivers/staging/meilhaus/me1600_ao.h
@@ -98,11 +98,7 @@ typedef struct me1600_ao_subdevice {
wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
me1600_ao_timeout_t timeout; /**< The timeout for start in blocking and non-blocking mode. */
struct workqueue_struct *me1600_workqueue;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- struct work_struct ao_control_task;
-#else
struct delayed_work ao_control_task;
-#endif
volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */
} me1600_ao_subdevice_t;
diff --git a/drivers/staging/meilhaus/me1600_device.c b/drivers/staging/meilhaus/me1600_device.c
index 3bc2cb1dc86..c244e984049 100644
--- a/drivers/staging/meilhaus/me1600_device.c
+++ b/drivers/staging/meilhaus/me1600_device.c
@@ -48,7 +48,7 @@
#include "mesubdevice.h"
#include "me1600_device.h"
-static void me1600_set_registry(me1600_device_t * subdevice, uint32_t reg_base);
+static void me1600_set_registry(me1600_device_t *subdevice, uint32_t reg_base);
static void me1600_destructor(struct me_device *device);
/**
@@ -142,6 +142,7 @@ me_device_t *me1600_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me1600_device;
}
+EXPORT_SYMBOL(me1600_pci_constructor);
static void me1600_destructor(struct me_device *device)
{
@@ -157,7 +158,7 @@ static void me1600_destructor(struct me_device *device)
kfree(me1600_device);
}
-static void me1600_set_registry(me1600_device_t * subdevice, uint32_t reg_base)
+static void me1600_set_registry(me1600_device_t *subdevice, uint32_t reg_base)
{ // Create shadow structure.
if (subdevice->ao_regs_shadows.count >= 1) {
subdevice->ao_regs_shadows.registry[0] =
@@ -256,6 +257,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for ME-1600 Device");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-1600 Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me1600_pci_constructor);
diff --git a/drivers/staging/meilhaus/me4600_ai.c b/drivers/staging/meilhaus/me4600_ai.c
index 0a8c9d737e9..a3cfef09a4d 100644
--- a/drivers/staging/meilhaus/me4600_ai.c
+++ b/drivers/staging/meilhaus/me4600_ai.c
@@ -36,8 +36,8 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
@@ -57,10 +57,10 @@
*/
static void me4600_ai_destructor(struct me_subdevice *subdevice);
-static int me4600_ai_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ai_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags);
-static int me4600_ai_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ai_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -68,120 +68,112 @@ static int me4600_ai_io_single_config(me_subdevice_t * subdevice,
int trig_chan,
int trig_type, int trig_edge, int flags);
-static int me4600_ai_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ai_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags);
-static int me4600_ai_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags);
-static int me4600_ai_io_stream_read(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_read(me_subdevice_t *subdevice,
struct file *filep,
int read_mode,
int *values, int *count, int flags);
-static int me4600_ai_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags);
-static int inline me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
+static inline int me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
instance, int *values,
const int count,
const int flags);
-static int me4600_ai_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags);
-static int me4600_ai_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags);
-static int me4600_ai_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags);
-static int me4600_ai_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me4600_ai_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range);
-static int me4600_ai_query_number_ranges(me_subdevice_t * subdevice,
+static int me4600_ai_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count);
-static int me4600_ai_query_range_info(me_subdevice_t * subdevice,
+static int me4600_ai_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata);
-static int me4600_ai_query_timer(me_subdevice_t * subdevice,
+static int me4600_ai_query_timer(me_subdevice_t *subdevice,
int timer,
int *base_frequency,
long long *min_ticks, long long *max_ticks);
-static int me4600_ai_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ai_query_number_channels(me_subdevice_t *subdevice,
int *number);
-static int me4600_ai_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ai_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype);
-static int me4600_ai_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me4600_ai_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps);
static int me4600_ai_query_subdevice_caps_args(struct me_subdevice *subdevice,
int cap, int *args, int count);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me4600_ai_isr(int irq, void *dev_id);
-#else
-static irqreturn_t me4600_ai_isr(int irq, void *dev_id, struct pt_regs *regs);
-#endif
-static int ai_mux_toggler(me4600_ai_subdevice_t * subdevice);
+static int ai_mux_toggler(me4600_ai_subdevice_t *subdevice);
/** Immidiate stop.
* Reset all IRQ's sources. (block laches)
* Preserve FIFO
*/
-static int ai_stop_immediately(me4600_ai_subdevice_t * instance);
+static int ai_stop_immediately(me4600_ai_subdevice_t *instance);
/** Immidiate stop.
* Reset all IRQ's sources. (block laches)
* Reset data FIFO
*/
-void inline ai_stop_isr(me4600_ai_subdevice_t * instance);
+inline void ai_stop_isr(me4600_ai_subdevice_t *instance);
/** Interrupt logics.
* Read datas
* Reset latches
*/
-void ai_limited_isr(me4600_ai_subdevice_t * instance, const uint32_t irq_status,
+void ai_limited_isr(me4600_ai_subdevice_t *instance, const uint32_t irq_status,
const uint32_t ctrl_status);
-void ai_infinite_isr(me4600_ai_subdevice_t * instance,
+void ai_infinite_isr(me4600_ai_subdevice_t *instance,
const uint32_t irq_status, const uint32_t ctrl_status);
/** Last chunck of datas. We must reschedule sample counter.
* Leaving SC_RELOAD doesn't do any harm, but in some bad case can make extra interrupts.
* When threshold is wrongly set some IRQ are lost.(!!!)
*/
-void inline ai_reschedule_SC(me4600_ai_subdevice_t * instance);
+inline void ai_reschedule_SC(me4600_ai_subdevice_t *instance);
/** Read datas from FIFO and copy them to buffer */
-static int inline ai_read_data(me4600_ai_subdevice_t * instance,
+static inline int ai_read_data(me4600_ai_subdevice_t *instance,
const int count);
/** Copy rest of data from fifo to circular buffer.*/
-static int inline ai_read_data_pooling(me4600_ai_subdevice_t * instance);
+static inline int ai_read_data_pooling(me4600_ai_subdevice_t *instance);
/** Set ISM to next state for infinite data aqusation mode*/
-void inline ai_infinite_ISM(me4600_ai_subdevice_t * instance);
+inline void ai_infinite_ISM(me4600_ai_subdevice_t *instance);
/** Set ISM to next state for define amount of data aqusation mode*/
-void inline ai_limited_ISM(me4600_ai_subdevice_t * instance,
+inline void ai_limited_ISM(me4600_ai_subdevice_t *instance,
uint32_t irq_status);
/** Set ISM to next stage for limited mode */
-void inline ai_data_acquisition_logic(me4600_ai_subdevice_t * instance);
+inline void ai_data_acquisition_logic(me4600_ai_subdevice_t *instance);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me4600_ai_work_control_task(void *subdevice);
-#else
static void me4600_ai_work_control_task(struct work_struct *work);
-#endif
/* Definitions
*/
@@ -192,7 +184,7 @@ me4600_ai_subdevice_t *me4600_ai_constructor(uint32_t reg_base,
int isolated,
int sh,
int irq,
- spinlock_t * ctrl_reg_lock,
+ spinlock_t *ctrl_reg_lock,
struct workqueue_struct *me4600_wq)
{
me4600_ai_subdevice_t *subdevice;
@@ -360,13 +352,8 @@ me4600_ai_subdevice_t *me4600_ai_constructor(uint32_t reg_base,
subdevice->me4600_workqueue = me4600_wq;
/* workqueue API changed in kernel 2.6.20 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
- INIT_WORK(&subdevice->ai_control_task, me4600_ai_work_control_task,
- (void *)subdevice);
-#else
INIT_DELAYED_WORK(&subdevice->ai_control_task,
me4600_ai_work_control_task);
-#endif
return subdevice;
}
@@ -397,7 +384,7 @@ static void me4600_ai_destructor(struct me_subdevice *subdevice)
kfree(instance);
}
-static int me4600_ai_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ai_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags)
{
me4600_ai_subdevice_t *instance;
@@ -519,7 +506,7 @@ static int me4600_ai_io_reset_subdevice(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ai_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ai_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -709,7 +696,7 @@ static int me4600_ai_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ai_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ai_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -915,11 +902,11 @@ static int me4600_ai_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ai_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
me4600_ai_subdevice_t *instance;
@@ -1586,15 +1573,15 @@ static int me4600_ai_io_stream_config(me_subdevice_t * subdevice,
ME_SINGLE_CHANNEL_NOT_CONFIGURED;
}
- VERIFY_ERROR: // Error in code. Wrong setting check. This should never ever happend!
+VERIFY_ERROR: // Error in code. Wrong setting check. This should never ever happend!
spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- ERROR: // Error in settings.
+ERROR: // Error in settings.
ME_SUBDEVICE_EXIT;
return err;
}
-static int me4600_ai_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags)
{
@@ -1677,7 +1664,7 @@ static int me4600_ai_io_stream_new_values(me_subdevice_t * subdevice,
return err;
}
-static int inline me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
+static inline int me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
instance, int *values,
const int count,
const int flags)
@@ -1712,7 +1699,7 @@ static int inline me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
return n;
}
-static int me4600_ai_io_stream_read(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_read(me_subdevice_t *subdevice,
struct file *filep,
int read_mode,
int *values, int *count, int flags)
@@ -1838,7 +1825,7 @@ static int me4600_ai_io_stream_read(me_subdevice_t * subdevice,
* @param instance The subdevice instance (pointer).
*/
-static int ai_stop_immediately(me4600_ai_subdevice_t * instance)
+static int ai_stop_immediately(me4600_ai_subdevice_t *instance)
{
unsigned long cpu_flags = 0;
volatile uint32_t ctrl;
@@ -1877,7 +1864,7 @@ static int ai_stop_immediately(me4600_ai_subdevice_t * instance)
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags)
{
@@ -2055,13 +2042,13 @@ static int me4600_ai_io_stream_start(me_subdevice_t * subdevice,
(tmp & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" : "work");
#endif
- ERROR:
+ERROR:
ME_SUBDEVICE_EXIT;
return err;
}
-static int me4600_ai_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags)
@@ -2139,7 +2126,7 @@ static int me4600_ai_io_stream_status(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ai_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags)
{
@@ -2236,7 +2223,7 @@ static int me4600_ai_io_stream_stop(me_subdevice_t * subdevice,
return ret;
}
-static int me4600_ai_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me4600_ai_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range)
@@ -2288,7 +2275,7 @@ static int me4600_ai_query_range_by_min_max(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_query_number_ranges(me_subdevice_t * subdevice,
+static int me4600_ai_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count)
{
me4600_ai_subdevice_t *instance;
@@ -2306,7 +2293,7 @@ static int me4600_ai_query_number_ranges(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_query_range_info(me_subdevice_t * subdevice,
+static int me4600_ai_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata)
@@ -2330,7 +2317,7 @@ static int me4600_ai_query_range_info(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_query_timer(me_subdevice_t * subdevice,
+static int me4600_ai_query_timer(me_subdevice_t *subdevice,
int timer,
int *base_frequency,
long long *min_ticks, long long *max_ticks)
@@ -2370,7 +2357,7 @@ static int me4600_ai_query_timer(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ai_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
me4600_ai_subdevice_t *instance;
@@ -2383,7 +2370,7 @@ static int me4600_ai_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ai_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed. idx=0\n");
@@ -2394,7 +2381,7 @@ static int me4600_ai_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me4600_ai_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed. idx=0\n");
@@ -2439,7 +2426,7 @@ static int me4600_ai_query_subdevice_caps_args(struct me_subdevice *subdevice,
return err;
}
-void ai_limited_isr(me4600_ai_subdevice_t * instance, const uint32_t irq_status,
+void ai_limited_isr(me4600_ai_subdevice_t *instance, const uint32_t irq_status,
const uint32_t ctrl_status)
{
int to_read;
@@ -2547,7 +2534,7 @@ void ai_limited_isr(me4600_ai_subdevice_t * instance, const uint32_t irq_status,
}
}
-void ai_infinite_isr(me4600_ai_subdevice_t * instance,
+void ai_infinite_isr(me4600_ai_subdevice_t *instance,
const uint32_t irq_status, const uint32_t ctrl_status)
{
int to_read;
@@ -2603,11 +2590,7 @@ void ai_infinite_isr(me4600_ai_subdevice_t * instance,
}
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me4600_ai_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me4600_ai_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{ /// @note This is time critical function!
uint32_t irq_status;
uint32_t ctrl_status;
@@ -2803,7 +2786,7 @@ static irqreturn_t me4600_ai_isr(int irq, void *dev_id, struct pt_regs *regs)
*
* @param instance The subdevice instance (pointer).
*/
-void inline ai_stop_isr(me4600_ai_subdevice_t * instance)
+inline void ai_stop_isr(me4600_ai_subdevice_t *instance)
{ /// @note This is soft time critical function!
register uint32_t tmp;
@@ -2829,7 +2812,7 @@ void inline ai_stop_isr(me4600_ai_subdevice_t * instance)
* @return On success: Number of copied values.
* @return On error: -ME_ERRNO_RING_BUFFER_OVERFLOW.
*/
-static int inline ai_read_data(me4600_ai_subdevice_t * instance,
+static inline int ai_read_data(me4600_ai_subdevice_t *instance,
const int count)
{ /// @note This is time critical function!
int c = count;
@@ -2875,7 +2858,7 @@ static int inline ai_read_data(me4600_ai_subdevice_t * instance,
return copied;
}
-void inline ai_infinite_ISM(me4600_ai_subdevice_t * instance)
+inline void ai_infinite_ISM(me4600_ai_subdevice_t *instance)
{ /// @note This is time critical function!
register volatile uint32_t ctrl_set, ctrl_reset, tmp;
@@ -2925,7 +2908,7 @@ void inline ai_infinite_ISM(me4600_ai_subdevice_t * instance)
}
-void inline ai_limited_ISM(me4600_ai_subdevice_t * instance,
+inline void ai_limited_ISM(me4600_ai_subdevice_t *instance,
uint32_t irq_status)
{ /// @note This is time critical function!
register volatile uint32_t ctrl_set, ctrl_reset = 0xFFFFFFFF, tmp;
@@ -2986,7 +2969,7 @@ void inline ai_limited_ISM(me4600_ai_subdevice_t * instance,
* Leaving SC_RELOAD doesn't do any harm, but in some bad case can make extra interrupts.
* @warning When threshold is wrongly set some IRQ are lost.(!!!)
*/
-void inline ai_reschedule_SC(me4600_ai_subdevice_t * instance)
+inline void ai_reschedule_SC(me4600_ai_subdevice_t *instance)
{
register uint32_t rest;
@@ -3018,7 +3001,7 @@ void inline ai_reschedule_SC(me4600_ai_subdevice_t * instance)
}
/** Start the ISM. All must be reseted before enter to this function. */
-void inline ai_data_acquisition_logic(me4600_ai_subdevice_t * instance)
+inline void ai_data_acquisition_logic(me4600_ai_subdevice_t *instance)
{
register uint32_t tmp;
@@ -3166,7 +3149,7 @@ void inline ai_data_acquisition_logic(me4600_ai_subdevice_t * instance)
}
}
-static int ai_mux_toggler(me4600_ai_subdevice_t * instance)
+static int ai_mux_toggler(me4600_ai_subdevice_t *instance)
{
uint32_t tmp;
@@ -3276,7 +3259,7 @@ static int ai_mux_toggler(me4600_ai_subdevice_t * instance)
* @return On success: Number of copied values.
* @return On error: Negative error code -ME_ERRNO_RING_BUFFER_OVERFLOW.
*/
-static int inline ai_read_data_pooling(me4600_ai_subdevice_t * instance)
+static inline int ai_read_data_pooling(me4600_ai_subdevice_t *instance)
{ /// @note This is time critical function!
int empty_space;
int copied = 0;
@@ -3310,11 +3293,7 @@ static int inline ai_read_data_pooling(me4600_ai_subdevice_t * instance)
return (!status) ? copied : -ME_ERRNO_RING_BUFFER_OVERFLOW;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me4600_ai_work_control_task(void *subdevice)
-#else
static void me4600_ai_work_control_task(struct work_struct *work)
-#endif
{
me4600_ai_subdevice_t *instance;
uint32_t status;
@@ -3323,12 +3302,8 @@ static void me4600_ai_work_control_task(struct work_struct *work)
int reschedule = 0;
int signaling = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- instance = (me4600_ai_subdevice_t *) subdevice;
-#else
instance =
container_of((void *)work, me4600_ai_subdevice_t, ai_control_task);
-#endif
PINFO("<%s: %ld> executed.\n", __func__, jiffies);
status = inl(instance->status_reg);
diff --git a/drivers/staging/meilhaus/me4600_ai.h b/drivers/staging/meilhaus/me4600_ai.h
index 1d5a1b9c6f9..106e1959f9f 100644
--- a/drivers/staging/meilhaus/me4600_ai.h
+++ b/drivers/staging/meilhaus/me4600_ai.h
@@ -139,11 +139,7 @@ typedef struct me4600_ai_subdevice {
wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
struct workqueue_struct *me4600_workqueue;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- struct work_struct ai_control_task;
-#else
struct delayed_work ai_control_task;
-#endif
volatile int ai_control_task_flag; /**< Flag controling reexecuting of control task */
diff --git a/drivers/staging/meilhaus/me4600_ao.c b/drivers/staging/meilhaus/me4600_ao.c
index e2bec8229ab..eb472692a7c 100644
--- a/drivers/staging/meilhaus/me4600_ao.c
+++ b/drivers/staging/meilhaus/me4600_ao.c
@@ -38,8 +38,8 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
#include <linux/types.h>
#include <linux/version.h>
#include <linux/interrupt.h>
@@ -58,31 +58,31 @@
/* Defines
*/
-static int me4600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me4600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range);
-static int me4600_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me4600_ao_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count);
-static int me4600_ao_query_range_info(me_subdevice_t * subdevice,
+static int me4600_ao_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata);
-static int me4600_ao_query_timer(me_subdevice_t * subdevice,
+static int me4600_ao_query_timer(me_subdevice_t *subdevice,
int timer,
int *base_frequency,
long long *min_ticks, long long *max_ticks);
-static int me4600_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ao_query_number_channels(me_subdevice_t *subdevice,
int *number);
-static int me4600_ao_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ao_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype);
-static int me4600_ao_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me4600_ao_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps);
static int me4600_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
@@ -105,12 +105,12 @@ static void me4600_ao_destructor(struct me_subdevice *subdevice);
/** Reset subdevice. Stop all actions. Reset registry. Disable FIFO. Set output to 0V and status to 'none'.
*/
-static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags);
/** Set output as single
*/
-static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -120,103 +120,93 @@ static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
/** Pass to user actual value of output.
*/
-static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags);
/** Write to output requed value.
*/
-static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags);
/** Set output as streamed device.
*/
-static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags);
/** Wait for / Check empty space in buffer.
*/
-static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags);
/** Start streaming.
*/
-static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags);
/** Check actual state. / Wait for end.
*/
-static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags);
/** Stop streaming.
*/
-static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags);
/** Write datas to buffor.
*/
-static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
struct file *filep,
int write_mode,
int *values, int *count, int flags);
/** Interrupt handler. Copy from buffer to FIFO.
*/
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
- , struct pt_regs *regs
-#endif
- );
+static irqreturn_t me4600_ao_isr(int irq, void *dev_id);
/** Copy data from circular buffer to fifo (fast) in wraparound mode.
*/
-int inline ao_write_data_wraparound(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data_wraparound(me4600_ao_subdevice_t *instance, int count,
int start_pos);
/** Copy data from circular buffer to fifo (fast).
*/
-int inline ao_write_data(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data(me4600_ao_subdevice_t *instance, int count,
int start_pos);
/** Copy data from circular buffer to fifo (slow).
*/
-int inline ao_write_data_pooling(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data_pooling(me4600_ao_subdevice_t *instance, int count,
int start_pos);
/** Copy data from user space to circular buffer.
*/
-int inline ao_get_data_from_user(me4600_ao_subdevice_t * instance, int count,
+inline int ao_get_data_from_user(me4600_ao_subdevice_t *instance, int count,
int *user_values);
/** Stop presentation. Preserve FIFOs.
*/
-int inline ao_stop_immediately(me4600_ao_subdevice_t * instance);
+inline int ao_stop_immediately(me4600_ao_subdevice_t *instance);
/** Task for asynchronical state verifying.
*/
-static void me4600_ao_work_control_task(
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- void *subdevice
-#else
- struct work_struct *work
-#endif
- );
+static void me4600_ao_work_control_task(struct work_struct *work);
/* Functions
*/
-static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags)
{
me4600_ao_subdevice_t *instance;
@@ -290,7 +280,7 @@ static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -463,7 +453,7 @@ static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -547,7 +537,7 @@ static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -989,11 +979,11 @@ static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
me4600_ao_subdevice_t *instance;
@@ -1025,7 +1015,7 @@ static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
}
if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {
- if (!flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
+ if (!(flags & ME_IO_STREAM_CONFIG_WRAPAROUND)) {
PERROR
("Hardware ME_IO_STREAM_CONFIG_HARDWARE_ONLY has to be with ME_IO_STREAM_CONFIG_WRAPAROUND.\n");
return ME_ERRNO_INVALID_FLAGS;
@@ -1327,7 +1317,7 @@ static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags)
{
@@ -1408,7 +1398,7 @@ static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags)
{
@@ -1845,7 +1835,7 @@ static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags)
@@ -1943,7 +1933,7 @@ static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags)
{ // Stop work and empty buffer and FIFO
@@ -2048,7 +2038,7 @@ static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
struct file *filep,
int write_mode,
int *values, int *count, int flags)
@@ -2272,11 +2262,7 @@ static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
return err;
}
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
- , struct pt_regs *regs
-#endif
- )
+static irqreturn_t me4600_ao_isr(int irq, void *dev_id)
{
me4600_ao_subdevice_t *instance = dev_id;
uint32_t irq_status;
@@ -2498,8 +2484,8 @@ static void me4600_ao_destructor(struct me_subdevice *subdevice)
}
me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
- spinlock_t * preload_reg_lock,
- uint32_t * preload_flags,
+ spinlock_t *preload_reg_lock,
+ uint32_t *preload_flags,
int ao_idx,
int fifo,
int irq,
@@ -2689,13 +2675,8 @@ me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
subdevice->me4600_workqueue = me4600_wq;
/* workqueue API changed in kernel 2.6.20 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
- INIT_WORK(&subdevice->ao_control_task, me4600_ao_work_control_task,
- (void *)subdevice);
-#else
INIT_DELAYED_WORK(&subdevice->ao_control_task,
me4600_ao_work_control_task);
-#endif
if (subdevice->fifo) { // Set speed for single operations.
outl(ME4600_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg);
@@ -2709,7 +2690,7 @@ me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
*
* @param instance The subdevice instance (pointer).
*/
-int inline ao_stop_immediately(me4600_ao_subdevice_t * instance)
+inline int ao_stop_immediately(me4600_ao_subdevice_t *instance)
{
unsigned long cpu_flags;
uint32_t ctrl;
@@ -2762,7 +2743,7 @@ int inline ao_stop_immediately(me4600_ao_subdevice_t * instance)
* @return On error/success: 0. No datas were copied => no data in buffer.
* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
*/
-int inline ao_write_data_wraparound(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data_wraparound(me4600_ao_subdevice_t *instance, int count,
int start_pos)
{ /// @note This is time critical function!
uint32_t status;
@@ -2827,7 +2808,7 @@ int inline ao_write_data_wraparound(me4600_ao_subdevice_t * instance, int count,
* @return On error/success: 0. No datas were copied => no data in buffer.
* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
*/
-int inline ao_write_data(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data(me4600_ao_subdevice_t *instance, int count,
int start_pos)
{ /// @note This is time critical function!
uint32_t status;
@@ -2897,7 +2878,7 @@ int inline ao_write_data(me4600_ao_subdevice_t * instance, int count,
* @return On error/success: 0. FIFO was full at begining.
* @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW.
*/
-int inline ao_write_data_pooling(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data_pooling(me4600_ao_subdevice_t *instance, int count,
int start_pos)
{ /// @note This is slow function!
uint32_t status;
@@ -2955,7 +2936,7 @@ int inline ao_write_data_pooling(me4600_ao_subdevice_t * instance, int count,
* @return On success: Number of copied values.
* @return On error: -ME_ERRNO_INTERNAL.
*/
-int inline ao_get_data_from_user(me4600_ao_subdevice_t * instance, int count,
+inline int ao_get_data_from_user(me4600_ao_subdevice_t *instance, int count,
int *user_values)
{
int i, err;
@@ -2987,13 +2968,7 @@ int inline ao_get_data_from_user(me4600_ao_subdevice_t * instance, int count,
/** @brief Checking actual hardware and logical state.
* @param instance The subdevice instance (pointer).
*/
-static void me4600_ao_work_control_task(
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- void *subdevice
-#else
- struct work_struct *work
-#endif
- )
+static void me4600_ao_work_control_task(struct work_struct *work)
{
me4600_ao_subdevice_t *instance;
unsigned long cpu_flags = 0;
@@ -3003,12 +2978,8 @@ static void me4600_ao_work_control_task(
int reschedule = 0;
int signaling = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- instance = (me4600_ao_subdevice_t *) subdevice;
-#else
instance =
container_of((void *)work, me4600_ao_subdevice_t, ao_control_task);
-#endif
PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
instance->ao_idx);
@@ -3323,7 +3294,7 @@ static void me4600_ao_work_control_task(
#else
/// @note SPECIAL BUILD FOR BOSCH
/// @author Guenter Gebhardt
-static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags)
{
me4600_ao_subdevice_t *instance;
@@ -3365,7 +3336,7 @@ static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -3636,7 +3607,7 @@ static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
goto ERROR;
}
- ERROR:
+ERROR:
spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
@@ -3645,7 +3616,7 @@ static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -3682,7 +3653,7 @@ static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -3830,18 +3801,18 @@ static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
}
- ERROR:
+ERROR:
ME_SUBDEVICE_EXIT;
return err;
}
-static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
me4600_ao_subdevice_t *instance;
@@ -4150,7 +4121,7 @@ static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
PDEBUG("Ctrl word = 0x%lX.\n", ctrl);
outl(ctrl, instance->ctrl_reg); // Write the control word
- ERROR:
+ERROR:
spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
@@ -4159,7 +4130,7 @@ static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags)
{
@@ -4238,7 +4209,7 @@ static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
return err;
}
-static void stop_immediately(me4600_ao_subdevice_t * instance)
+static void stop_immediately(me4600_ao_subdevice_t *instance)
{
unsigned long cpu_flags;
uint32_t tmp;
@@ -4253,7 +4224,7 @@ static void stop_immediately(me4600_ao_subdevice_t * instance)
spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
}
-static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags)
{
@@ -4778,14 +4749,14 @@ static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
goto ERROR;
}
- ERROR:
+ERROR:
ME_SUBDEVICE_EXIT;
return err;
}
-static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags)
@@ -4842,14 +4813,14 @@ static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
goto ERROR;
}
- ERROR:
+ERROR:
ME_SUBDEVICE_EXIT;
return err;
}
-static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags)
{
@@ -4891,14 +4862,14 @@ static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
goto ERROR;
}
- ERROR:
+ERROR:
ME_SUBDEVICE_EXIT;
return err;
}
-static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
struct file *filep,
int write_mode,
int *values, int *count, int flags)
@@ -5432,18 +5403,14 @@ static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
goto ERROR;
}
- ERROR:
+ERROR:
ME_SUBDEVICE_EXIT;
return err;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me4600_ao_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
unsigned long tmp;
int value;
@@ -5660,8 +5627,8 @@ static void me4600_ao_destructor(struct me_subdevice *subdevice)
}
me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
- spinlock_t * preload_reg_lock,
- uint32_t * preload_flags,
+ spinlock_t *preload_reg_lock,
+ uint32_t *preload_flags,
int ao_idx, int fifo, int irq)
{
me4600_ao_subdevice_t *subdevice;
@@ -5823,7 +5790,7 @@ me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
/* Common functions
*/
-static int me4600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me4600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range)
@@ -5858,7 +5825,7 @@ static int me4600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me4600_ao_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count)
{
me4600_ao_subdevice_t *instance;
@@ -5876,7 +5843,7 @@ static int me4600_ao_query_number_ranges(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ao_query_range_info(me_subdevice_t * subdevice,
+static int me4600_ao_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata)
@@ -5900,7 +5867,7 @@ static int me4600_ao_query_range_info(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ao_query_timer(me_subdevice_t * subdevice,
+static int me4600_ao_query_timer(me_subdevice_t *subdevice,
int timer,
int *base_frequency,
long long *min_ticks, long long *max_ticks)
@@ -5934,7 +5901,7 @@ static int me4600_ao_query_timer(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ao_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
me4600_ao_subdevice_t *instance;
@@ -5947,7 +5914,7 @@ static int me4600_ao_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ao_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ao_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
me4600_ao_subdevice_t *instance;
@@ -5962,7 +5929,7 @@ static int me4600_ao_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ao_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me4600_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
me4600_ao_subdevice_t *instance;
instance = (me4600_ao_subdevice_t *) subdevice;
diff --git a/drivers/staging/meilhaus/me4600_ao.h b/drivers/staging/meilhaus/me4600_ao.h
index 6fbc4a2dd9d..7579435adc6 100644
--- a/drivers/staging/meilhaus/me4600_ao.h
+++ b/drivers/staging/meilhaus/me4600_ao.h
@@ -225,11 +225,7 @@ typedef struct me4600_ao_subdevice {
wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
struct workqueue_struct *me4600_workqueue;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- struct work_struct ao_control_task;
-#else
struct delayed_work ao_control_task;
-#endif
volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */
diff --git a/drivers/staging/meilhaus/me4600_device.c b/drivers/staging/meilhaus/me4600_device.c
index fa455844f4e..457666ef61a 100644
--- a/drivers/staging/meilhaus/me4600_device.c
+++ b/drivers/staging/meilhaus/me4600_device.c
@@ -336,6 +336,7 @@ me_device_t *me4600_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me4600_device;
}
+EXPORT_SYMBOL(me4600_pci_constructor);
// Init and exit of module.
@@ -368,6 +369,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for ME-46xx Devices");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-46xx Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me4600_pci_constructor);
diff --git a/drivers/staging/meilhaus/me4600_di.c b/drivers/staging/meilhaus/me4600_di.c
index 7e3c9f4d2df..e107e506138 100644
--- a/drivers/staging/meilhaus/me4600_di.c
+++ b/drivers/staging/meilhaus/me4600_di.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -91,7 +91,7 @@ static int me4600_di_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_di_io_single_config(me_subdevice_t * subdevice,
+static int me4600_di_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -133,7 +133,7 @@ static int me4600_di_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_di_io_single_read(me_subdevice_t * subdevice,
+static int me4600_di_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -177,7 +177,7 @@ static int me4600_di_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me4600_di_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_di_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -185,7 +185,7 @@ static int me4600_di_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_di_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -194,7 +194,7 @@ static int me4600_di_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me4600_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = 0;
@@ -202,7 +202,7 @@ static int me4600_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
}
me4600_di_subdevice_t *me4600_di_constructor(uint32_t reg_base,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me4600_di_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me4600_dio.c b/drivers/staging/meilhaus/me4600_dio.c
index 0af95d1a8f5..baa28ff6b6b 100644
--- a/drivers/staging/meilhaus/me4600_dio.c
+++ b/drivers/staging/meilhaus/me4600_dio.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -94,7 +94,7 @@ static int me4600_dio_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_dio_io_single_config(me_subdevice_t * subdevice,
+static int me4600_dio_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -268,7 +268,7 @@ static int me4600_dio_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_dio_io_single_read(me_subdevice_t * subdevice,
+static int me4600_dio_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -342,7 +342,7 @@ static int me4600_dio_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me4600_dio_io_single_write(me_subdevice_t * subdevice,
+static int me4600_dio_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -425,7 +425,7 @@ static int me4600_dio_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me4600_dio_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_dio_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -433,7 +433,7 @@ static int me4600_dio_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_dio_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_dio_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -442,7 +442,7 @@ static int me4600_dio_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_dio_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me4600_dio_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -452,7 +452,7 @@ static int me4600_dio_query_subdevice_caps(me_subdevice_t * subdevice,
me4600_dio_subdevice_t *me4600_dio_constructor(uint32_t reg_base,
unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me4600_dio_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me4600_do.c b/drivers/staging/meilhaus/me4600_do.c
index ee591bc1185..39510f3e6e6 100644
--- a/drivers/staging/meilhaus/me4600_do.c
+++ b/drivers/staging/meilhaus/me4600_do.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -93,7 +93,7 @@ static int me4600_do_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_do_io_single_config(me_subdevice_t * subdevice,
+static int me4600_do_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -224,7 +224,7 @@ static int me4600_do_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_do_io_single_read(me_subdevice_t * subdevice,
+static int me4600_do_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -284,7 +284,7 @@ static int me4600_do_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me4600_do_io_single_write(me_subdevice_t * subdevice,
+static int me4600_do_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -352,7 +352,7 @@ static int me4600_do_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me4600_do_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_do_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -360,7 +360,7 @@ static int me4600_do_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_do_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_do_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -369,7 +369,7 @@ static int me4600_do_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me4600_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = 0;
@@ -377,7 +377,7 @@ static int me4600_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
}
me4600_do_subdevice_t *me4600_do_constructor(uint32_t reg_base,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me4600_do_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me4600_ext_irq.c b/drivers/staging/meilhaus/me4600_ext_irq.c
index adc1e1babf4..6b33cba3da8 100644
--- a/drivers/staging/meilhaus/me4600_ext_irq.c
+++ b/drivers/staging/meilhaus/me4600_ext_irq.c
@@ -37,7 +37,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/version.h>
@@ -60,7 +60,7 @@
* Functions
*/
-static int me4600_ext_irq_io_irq_start(me_subdevice_t * subdevice,
+static int me4600_ext_irq_io_irq_start(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int irq_source,
@@ -135,7 +135,7 @@ static int me4600_ext_irq_io_irq_start(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ext_irq_io_irq_wait(me_subdevice_t * subdevice,
+static int me4600_ext_irq_io_irq_wait(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *irq_count,
@@ -214,7 +214,7 @@ static int me4600_ext_irq_io_irq_wait(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ext_irq_io_irq_stop(me_subdevice_t * subdevice,
+static int me4600_ext_irq_io_irq_stop(me_subdevice_t *subdevice,
struct file *filep,
int channel, int flags)
{
@@ -256,7 +256,7 @@ static int me4600_ext_irq_io_irq_stop(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ext_irq_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ext_irq_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags)
{
me4600_ext_irq_subdevice_t *instance;
@@ -308,7 +308,7 @@ static void me4600_ext_irq_destructor(struct me_subdevice *subdevice)
kfree(instance);
}
-static int me4600_ext_irq_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ext_irq_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -316,7 +316,7 @@ static int me4600_ext_irq_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ext_irq_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ext_irq_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -325,7 +325,7 @@ static int me4600_ext_irq_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ext_irq_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me4600_ext_irq_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -335,12 +335,7 @@ static int me4600_ext_irq_query_subdevice_caps(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me4600_ext_irq_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me4600_ext_irq_isr(int irq, void *dev_id,
- struct pt_regs *regs)
-#endif
{
me4600_ext_irq_subdevice_t *instance;
uint32_t ctrl;
diff --git a/drivers/staging/meilhaus/me6000_ao.c b/drivers/staging/meilhaus/me6000_ao.c
index 94f01231f79..f7abdbd485e 100644
--- a/drivers/staging/meilhaus/me6000_ao.c
+++ b/drivers/staging/meilhaus/me6000_ao.c
@@ -36,8 +36,8 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
@@ -57,31 +57,31 @@
/* Defines
*/
-static int me6000_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me6000_ao_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range);
-static int me6000_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me6000_ao_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count);
-static int me6000_ao_query_range_info(me_subdevice_t * subdevice,
+static int me6000_ao_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata);
-static int me6000_ao_query_timer(me_subdevice_t * subdevice,
+static int me6000_ao_query_timer(me_subdevice_t *subdevice,
int timer,
int *base_frequency,
long long *min_ticks, long long *max_ticks);
-static int me6000_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me6000_ao_query_number_channels(me_subdevice_t *subdevice,
int *number);
-static int me6000_ao_query_subdevice_type(me_subdevice_t * subdevice,
+static int me6000_ao_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype);
-static int me6000_ao_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me6000_ao_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps);
static int me6000_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
@@ -91,11 +91,11 @@ static int me6000_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
static void me6000_ao_destructor(struct me_subdevice *subdevice);
/** Reset subdevice. Stop all actions. Reset registry. Disable FIFO. Set output to 0V and status to 'none'. */
-static int me6000_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me6000_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags);
/** Set output as single */
-static int me6000_ao_io_single_config(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -104,89 +104,81 @@ static int me6000_ao_io_single_config(me_subdevice_t * subdevice,
int trig_type, int trig_edge, int flags);
/** Pass to user actual value of output. */
-static int me6000_ao_io_single_read(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags);
/** Write to output requed value. */
-static int me6000_ao_io_single_write(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags);
/** Set output as streamed device. */
-static int me6000_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags);
/** Wait for / Check empty space in buffer. */
-static int me6000_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags);
/** Start streaming. */
-static int me6000_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags);
/** Check actual state. / Wait for end. */
-static int me6000_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags);
/** Stop streaming. */
-static int me6000_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags);
/** Write datas to buffor. */
-static int me6000_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_write(me_subdevice_t *subdevice,
struct file *filep,
int write_mode,
int *values, int *count, int flags);
/** Interrupt handler. Copy from buffer to FIFO. */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me6000_ao_isr(int irq, void *dev_id);
-#else
-static irqreturn_t me6000_ao_isr(int irq, void *dev_id, struct pt_regs *regs);
-#endif
/** Copy data from circular buffer to fifo (fast) in wraparound mode. */
-int inline ao_write_data_wraparound(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data_wraparound(me6000_ao_subdevice_t *instance, int count,
int start_pos);
/** Copy data from circular buffer to fifo (fast).*/
-int inline ao_write_data(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data(me6000_ao_subdevice_t *instance, int count,
int start_pos);
/** Copy data from circular buffer to fifo (slow).*/
-int inline ao_write_data_pooling(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data_pooling(me6000_ao_subdevice_t *instance, int count,
int start_pos);
/** Copy data from user space to circular buffer. */
-int inline ao_get_data_from_user(me6000_ao_subdevice_t * instance, int count,
+inline int ao_get_data_from_user(me6000_ao_subdevice_t *instance, int count,
int *user_values);
/** Stop presentation. Preserve FIFOs. */
-int inline ao_stop_immediately(me6000_ao_subdevice_t * instance);
+inline int ao_stop_immediately(me6000_ao_subdevice_t *instance);
/** Function for checking timeout in non-blocking mode. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me6000_ao_work_control_task(void *subdevice);
-#else
static void me6000_ao_work_control_task(struct work_struct *work);
-#endif
/* Functions
*/
-static int me6000_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me6000_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags)
{
me6000_ao_subdevice_t *instance;
@@ -274,7 +266,7 @@ static int me6000_ao_io_reset_subdevice(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_single_config(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -473,7 +465,7 @@ static int me6000_ao_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_single_read(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -555,7 +547,7 @@ static int me6000_ao_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_single_write(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -1027,11 +1019,11 @@ static int me6000_ao_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
me6000_ao_subdevice_t *instance;
@@ -1063,7 +1055,7 @@ static int me6000_ao_io_stream_config(me_subdevice_t * subdevice,
}
if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {
- if (!flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
+ if (!(flags & ME_IO_STREAM_CONFIG_WRAPAROUND)) {
PERROR
("Hardware ME_IO_STREAM_CONFIG_HARDWARE_ONLY has to be with ME_IO_STREAM_CONFIG_WRAPAROUND.\n");
return ME_ERRNO_INVALID_FLAGS;
@@ -1359,7 +1351,7 @@ static int me6000_ao_io_stream_config(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags)
{
@@ -1440,7 +1432,7 @@ static int me6000_ao_io_stream_new_values(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags)
{
@@ -1889,7 +1881,7 @@ static int me6000_ao_io_stream_start(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags)
@@ -1987,7 +1979,7 @@ static int me6000_ao_io_stream_status(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags)
{ /// @note Stop work and empty buffer and FIFO
@@ -2094,7 +2086,7 @@ static int me6000_ao_io_stream_stop(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_write(me_subdevice_t *subdevice,
struct file *filep,
int write_mode,
int *values, int *count, int flags)
@@ -2324,11 +2316,7 @@ static int me6000_ao_io_stream_write(me_subdevice_t * subdevice,
return err;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me6000_ao_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me6000_ao_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
me6000_ao_subdevice_t *instance = dev_id;
uint32_t irq_status;
@@ -2544,9 +2532,9 @@ static void me6000_ao_destructor(struct me_subdevice *subdevice)
}
me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base,
- spinlock_t * preload_reg_lock,
- uint32_t * preload_flags,
- uint32_t * triggering_flags,
+ spinlock_t *preload_reg_lock,
+ uint32_t *preload_flags,
+ uint32_t *triggering_flags,
int ao_idx,
int fifo,
int irq,
@@ -2797,13 +2785,8 @@ me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base,
subdevice->me6000_workqueue = me6000_wq;
/* workqueue API changed in kernel 2.6.20 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
- INIT_WORK(&subdevice->ao_control_task, me6000_ao_work_control_task,
- (void *)subdevice);
-#else
INIT_DELAYED_WORK(&subdevice->ao_control_task,
me6000_ao_work_control_task);
-#endif
if (subdevice->fifo) { //Set speed
outl(ME6000_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg);
@@ -2817,7 +2800,7 @@ me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base,
*
* @param instance The subdevice instance (pointer).
*/
-int inline ao_stop_immediately(me6000_ao_subdevice_t * instance)
+inline int ao_stop_immediately(me6000_ao_subdevice_t *instance)
{
unsigned long cpu_flags;
uint32_t ctrl;
@@ -2825,10 +2808,11 @@ int inline ao_stop_immediately(me6000_ao_subdevice_t * instance)
int i;
uint32_t single_mask;
- single_mask =
- (instance->ao_idx - ME6000_AO_SINGLE_STATUS_OFFSET <
- 0) ? 0x0000 : (0x0001 << (instance->ao_idx -
- ME6000_AO_SINGLE_STATUS_OFFSET));
+ if (instance->ao_idx < ME6000_AO_SINGLE_STATUS_OFFSET)
+ single_mask = 0x0000;
+ else
+ single_mask = 0x0001 << (instance->ao_idx -
+ ME6000_AO_SINGLE_STATUS_OFFSET);
timeout =
(instance->hardware_stop_delay >
@@ -2887,7 +2871,7 @@ int inline ao_stop_immediately(me6000_ao_subdevice_t * instance)
* @return On error/success: 0. No datas were copied => no data in buffer.
* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
*/
-int inline ao_write_data_wraparound(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data_wraparound(me6000_ao_subdevice_t *instance, int count,
int start_pos)
{ /// @note This is time critical function!
uint32_t status;
@@ -2952,7 +2936,7 @@ int inline ao_write_data_wraparound(me6000_ao_subdevice_t * instance, int count,
* @return On error/success: 0. No datas were copied => no data in buffer.
* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
*/
-int inline ao_write_data(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data(me6000_ao_subdevice_t *instance, int count,
int start_pos)
{ /// @note This is time critical function!
uint32_t status;
@@ -3022,7 +3006,7 @@ int inline ao_write_data(me6000_ao_subdevice_t * instance, int count,
* @return On error/success: 0. FIFO was full at begining.
* @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW.
*/
-int inline ao_write_data_pooling(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data_pooling(me6000_ao_subdevice_t *instance, int count,
int start_pos)
{ /// @note This is slow function!
uint32_t status;
@@ -3080,7 +3064,7 @@ int inline ao_write_data_pooling(me6000_ao_subdevice_t * instance, int count,
* @return On success: Number of copied values.
* @return On error: -ME_ERRNO_INTERNAL.
*/
-int inline ao_get_data_from_user(me6000_ao_subdevice_t * instance, int count,
+inline int ao_get_data_from_user(me6000_ao_subdevice_t *instance, int count,
int *user_values)
{
int i, err;
@@ -3109,13 +3093,7 @@ int inline ao_get_data_from_user(me6000_ao_subdevice_t * instance, int count,
return copied;
}
-static void me6000_ao_work_control_task(
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- void *subdevice
-#else
- struct work_struct *work
-#endif
- )
+static void me6000_ao_work_control_task(struct work_struct *work)
{
me6000_ao_subdevice_t *instance;
unsigned long cpu_flags = 0;
@@ -3126,12 +3104,8 @@ static void me6000_ao_work_control_task(
int signaling = 0;
uint32_t single_mask;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- instance = (me6000_ao_subdevice_t *) subdevice;
-#else
instance =
container_of((void *)work, me6000_ao_subdevice_t, ao_control_task);
-#endif
PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
instance->ao_idx);
@@ -3555,7 +3529,7 @@ static void me6000_ao_work_control_task(
}
-static int me6000_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me6000_ao_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range)
@@ -3589,7 +3563,7 @@ static int me6000_ao_query_range_by_min_max(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me6000_ao_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count)
{
me6000_ao_subdevice_t *instance;
@@ -3607,7 +3581,7 @@ static int me6000_ao_query_number_ranges(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_ao_query_range_info(me_subdevice_t * subdevice,
+static int me6000_ao_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata)
@@ -3631,7 +3605,7 @@ static int me6000_ao_query_range_info(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_ao_query_timer(me_subdevice_t * subdevice,
+static int me6000_ao_query_timer(me_subdevice_t *subdevice,
int timer,
int *base_frequency,
long long *min_ticks, long long *max_ticks)
@@ -3660,7 +3634,7 @@ static int me6000_ao_query_timer(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me6000_ao_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
me6000_ao_subdevice_t *instance;
@@ -3672,7 +3646,7 @@ static int me6000_ao_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_ao_query_subdevice_type(me_subdevice_t * subdevice,
+static int me6000_ao_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
me6000_ao_subdevice_t *instance;
@@ -3690,7 +3664,7 @@ static int me6000_ao_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_ao_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me6000_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
me6000_ao_subdevice_t *instance;
instance = (me6000_ao_subdevice_t *) subdevice;
diff --git a/drivers/staging/meilhaus/me6000_ao.h b/drivers/staging/meilhaus/me6000_ao.h
index 9629649cd41..ef4d0189bde 100644
--- a/drivers/staging/meilhaus/me6000_ao.h
+++ b/drivers/staging/meilhaus/me6000_ao.h
@@ -160,11 +160,7 @@ typedef struct me6000_ao_subdevice {
wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
struct workqueue_struct *me6000_workqueue;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- struct work_struct ao_control_task;
-#else
struct delayed_work ao_control_task;
-#endif
volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */
diff --git a/drivers/staging/meilhaus/me6000_device.c b/drivers/staging/meilhaus/me6000_device.c
index fee4c58b846..1a6cf7f4325 100644
--- a/drivers/staging/meilhaus/me6000_device.c
+++ b/drivers/staging/meilhaus/me6000_device.c
@@ -178,6 +178,7 @@ me_device_t *me6000_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me6000_device;
}
+EXPORT_SYMBOL(me6000_pci_constructor);
// Init and exit of module.
@@ -206,6 +207,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for ME-6000 Device");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-6000 Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me6000_pci_constructor);
diff --git a/drivers/staging/meilhaus/me6000_dio.c b/drivers/staging/meilhaus/me6000_dio.c
index 07f1069f9ac..c90686efc38 100644
--- a/drivers/staging/meilhaus/me6000_dio.c
+++ b/drivers/staging/meilhaus/me6000_dio.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -91,7 +91,7 @@ static int me6000_dio_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_dio_io_single_config(me_subdevice_t * subdevice,
+static int me6000_dio_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -161,7 +161,7 @@ static int me6000_dio_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me6000_dio_io_single_read(me_subdevice_t * subdevice,
+static int me6000_dio_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -233,7 +233,7 @@ static int me6000_dio_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me6000_dio_io_single_write(me_subdevice_t * subdevice,
+static int me6000_dio_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -314,7 +314,7 @@ static int me6000_dio_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me6000_dio_query_number_channels(me_subdevice_t * subdevice,
+static int me6000_dio_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -322,7 +322,7 @@ static int me6000_dio_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_dio_query_subdevice_type(me_subdevice_t * subdevice,
+static int me6000_dio_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -331,7 +331,7 @@ static int me6000_dio_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_dio_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me6000_dio_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -341,7 +341,7 @@ static int me6000_dio_query_subdevice_caps(me_subdevice_t * subdevice,
me6000_dio_subdevice_t *me6000_dio_constructor(uint32_t reg_base,
unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me6000_dio_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me8100_device.c b/drivers/staging/meilhaus/me8100_device.c
index 1fb79e49026..41a9345cee5 100644
--- a/drivers/staging/meilhaus/me8100_device.c
+++ b/drivers/staging/meilhaus/me8100_device.c
@@ -159,6 +159,7 @@ me_device_t *me8100_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me8100_device;
}
+EXPORT_SYMBOL(me8100_pci_constructor);
// Init and exit of module.
@@ -182,6 +183,3 @@ MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
MODULE_DESCRIPTION("Device Driver Module for Template Device");
MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me8100_pci_constructor);
diff --git a/drivers/staging/meilhaus/me8100_di.c b/drivers/staging/meilhaus/me8100_di.c
index 971727c9e30..301dbd8f96a 100644
--- a/drivers/staging/meilhaus/me8100_di.c
+++ b/drivers/staging/meilhaus/me8100_di.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/version.h>
@@ -114,7 +114,7 @@ static int me8100_di_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_di_io_irq_start(me_subdevice_t * subdevice,
+static int me8100_di_io_irq_start(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int irq_source,
@@ -208,7 +208,7 @@ static int me8100_di_io_irq_start(me_subdevice_t * subdevice,
return err;
}
-static int me8100_di_io_irq_wait(me_subdevice_t * subdevice,
+static int me8100_di_io_irq_wait(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *irq_count,
@@ -315,7 +315,7 @@ static int me8100_di_io_irq_wait(me_subdevice_t * subdevice,
return err;
}
-static int me8100_di_io_irq_stop(me_subdevice_t * subdevice,
+static int me8100_di_io_irq_stop(me_subdevice_t *subdevice,
struct file *filep, int channel, int flags)
{
me8100_di_subdevice_t *instance;
@@ -358,7 +358,7 @@ static int me8100_di_io_irq_stop(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_di_io_single_config(me_subdevice_t * subdevice,
+static int me8100_di_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -405,7 +405,7 @@ static int me8100_di_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me8100_di_io_single_read(me_subdevice_t * subdevice,
+static int me8100_di_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -466,7 +466,7 @@ static int me8100_di_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me8100_di_query_number_channels(me_subdevice_t * subdevice,
+static int me8100_di_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -474,7 +474,7 @@ static int me8100_di_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8100_di_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -483,7 +483,7 @@ static int me8100_di_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me8100_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = ME_CAPS_DIO_BIT_PATTERN_IRQ | ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY;
@@ -503,11 +503,7 @@ static void me8100_di_destructor(struct me_subdevice *subdevice)
kfree(instance);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me8100_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me8100_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
me8100_di_subdevice_t *instance;
uint32_t icsr;
@@ -598,7 +594,7 @@ me8100_di_subdevice_t *me8100_di_constructor(uint32_t me8100_reg_base,
uint32_t plx_reg_base,
unsigned int di_idx,
int irq,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me8100_di_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me8100_do.c b/drivers/staging/meilhaus/me8100_do.c
index 957b9f92f76..81651a90cc0 100644
--- a/drivers/staging/meilhaus/me8100_do.c
+++ b/drivers/staging/meilhaus/me8100_do.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -92,7 +92,7 @@ static int me8100_do_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_do_io_single_config(me_subdevice_t * subdevice,
+static int me8100_do_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -158,7 +158,7 @@ static int me8100_do_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me8100_do_io_single_read(me_subdevice_t * subdevice,
+static int me8100_do_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -215,7 +215,7 @@ static int me8100_do_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me8100_do_io_single_write(me_subdevice_t * subdevice,
+static int me8100_do_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -297,7 +297,7 @@ static int me8100_do_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me8100_do_query_number_channels(me_subdevice_t * subdevice,
+static int me8100_do_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -305,7 +305,7 @@ static int me8100_do_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_do_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8100_do_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -314,7 +314,7 @@ static int me8100_do_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me8100_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = ME_CAPS_DIO_SINK_SOURCE;
@@ -323,7 +323,7 @@ static int me8100_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
me8100_do_subdevice_t *me8100_do_constructor(uint32_t reg_base,
unsigned int do_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me8100_do_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me8200_device.c b/drivers/staging/meilhaus/me8200_device.c
index 261c0cbd9d0..b313679fc5c 100644
--- a/drivers/staging/meilhaus/me8200_device.c
+++ b/drivers/staging/meilhaus/me8200_device.c
@@ -166,6 +166,7 @@ me_device_t *me8200_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me8200_device;
}
+EXPORT_SYMBOL(me8200_pci_constructor);
// Init and exit of module.
@@ -189,6 +190,3 @@ MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
MODULE_DESCRIPTION("Device Driver Module for Template Device");
MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me8200_pci_constructor);
diff --git a/drivers/staging/meilhaus/me8200_di.c b/drivers/staging/meilhaus/me8200_di.c
index 27525bc067b..a931fb817c7 100644
--- a/drivers/staging/meilhaus/me8200_di.c
+++ b/drivers/staging/meilhaus/me8200_di.c
@@ -34,7 +34,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/version.h>
@@ -50,52 +50,44 @@
/// Defines
static void me8200_di_destructor(struct me_subdevice *subdevice);
-static int me8200_di_io_irq_start(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_start(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int irq_source,
int irq_edge, int irq_arg, int flags);
-static int me8200_di_io_irq_wait(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_wait(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *irq_count,
int *value, int time_out, int flags);
-static int me8200_di_io_irq_stop(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_stop(me_subdevice_t *subdevice,
struct file *filep, int channel, int flags);
-static int me8200_di_io_single_config(me_subdevice_t * subdevice,
+static int me8200_di_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
int ref,
int trig_chan,
int trig_type, int trig_edge, int flags);
-static int me8200_di_io_single_read(me_subdevice_t * subdevice,
+static int me8200_di_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags);
static int me8200_di_io_reset_subdevice(struct me_subdevice *subdevice,
struct file *filep, int flags);
-static int me8200_di_query_number_channels(me_subdevice_t * subdevice,
+static int me8200_di_query_number_channels(me_subdevice_t *subdevice,
int *number);
-static int me8200_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8200_di_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype);
-static int me8200_di_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me8200_di_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me8200_isr(int irq, void *dev_id);
-#else
-static irqreturn_t me8200_isr(int irq, void *dev_id, struct pt_regs *regs);
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me8200_isr_EX(int irq, void *dev_id);
-#else
-static irqreturn_t me8200_isr_EX(int irq, void *dev_id, struct pt_regs *regs);
-#endif
-static void me8200_di_check_version(me8200_di_subdevice_t * instance,
+static void me8200_di_check_version(me8200_di_subdevice_t *instance,
unsigned long addr);
///Functions
-static int me8200_di_io_irq_start(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_start(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int irq_source,
@@ -246,7 +238,7 @@ static int me8200_di_io_irq_start(me_subdevice_t * subdevice,
return err;
}
-static int me8200_di_io_irq_wait(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_wait(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *irq_count,
@@ -352,7 +344,7 @@ static int me8200_di_io_irq_wait(me_subdevice_t * subdevice,
return err;
}
-static int me8200_di_io_irq_stop(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_stop(me_subdevice_t *subdevice,
struct file *filep, int channel, int flags)
{
me8200_di_subdevice_t *instance;
@@ -406,7 +398,7 @@ static int me8200_di_io_irq_stop(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_di_io_single_config(me_subdevice_t * subdevice,
+static int me8200_di_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -453,7 +445,7 @@ static int me8200_di_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me8200_di_io_single_read(me_subdevice_t * subdevice,
+static int me8200_di_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -518,7 +510,7 @@ static int me8200_di_io_reset_subdevice(struct me_subdevice *subdevice,
return me8200_di_io_irq_stop(subdevice, filep, 0, 0);
}
-static int me8200_di_query_number_channels(me_subdevice_t * subdevice,
+static int me8200_di_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -526,7 +518,7 @@ static int me8200_di_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8200_di_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -535,7 +527,7 @@ static int me8200_di_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me8200_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps =
@@ -546,11 +538,7 @@ static int me8200_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
return ME_ERRNO_SUCCESS;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me8200_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me8200_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
me8200_di_subdevice_t *instance;
uint8_t ctrl;
@@ -629,11 +617,7 @@ static irqreturn_t me8200_isr(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me8200_isr_EX(int irq, void *dev_id)
-#else
-static irqreturn_t me8200_isr_EX(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
me8200_di_subdevice_t *instance;
uint8_t irq_status = 0;
@@ -715,8 +699,8 @@ static void me8200_di_destructor(struct me_subdevice *subdevice)
me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_regbase,
unsigned int di_idx,
int irq,
- spinlock_t * irq_ctrl_lock,
- spinlock_t * irq_mode_lock)
+ spinlock_t *irq_ctrl_lock,
+ spinlock_t *irq_mode_lock)
{
me8200_di_subdevice_t *subdevice;
int err;
@@ -843,7 +827,7 @@ me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_regbase,
return subdevice;
}
-static void me8200_di_check_version(me8200_di_subdevice_t * instance,
+static void me8200_di_check_version(me8200_di_subdevice_t *instance,
unsigned long addr)
{
diff --git a/drivers/staging/meilhaus/me8200_dio.c b/drivers/staging/meilhaus/me8200_dio.c
index ff8ca1b8b7f..c7f43f011f3 100644
--- a/drivers/staging/meilhaus/me8200_dio.c
+++ b/drivers/staging/meilhaus/me8200_dio.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -90,7 +90,7 @@ static int me8200_dio_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_dio_io_single_config(me_subdevice_t * subdevice,
+static int me8200_dio_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -164,7 +164,7 @@ static int me8200_dio_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me8200_dio_io_single_read(me_subdevice_t * subdevice,
+static int me8200_dio_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -241,7 +241,7 @@ static int me8200_dio_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me8200_dio_io_single_write(me_subdevice_t * subdevice,
+static int me8200_dio_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -332,7 +332,7 @@ static int me8200_dio_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me8200_dio_query_number_channels(me_subdevice_t * subdevice,
+static int me8200_dio_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -340,7 +340,7 @@ static int me8200_dio_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_dio_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8200_dio_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -349,7 +349,7 @@ static int me8200_dio_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_dio_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me8200_dio_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -359,7 +359,7 @@ static int me8200_dio_query_subdevice_caps(me_subdevice_t * subdevice,
me8200_dio_subdevice_t *me8200_dio_constructor(uint32_t reg_base,
unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me8200_dio_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me8200_do.c b/drivers/staging/meilhaus/me8200_do.c
index d2bebd16ff4..40d536c71d5 100644
--- a/drivers/staging/meilhaus/me8200_do.c
+++ b/drivers/staging/meilhaus/me8200_do.c
@@ -37,7 +37,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/version.h>
@@ -59,7 +59,7 @@
* Functions
*/
-static int me8200_do_io_irq_start(me_subdevice_t * subdevice,
+static int me8200_do_io_irq_start(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int irq_source,
@@ -109,7 +109,7 @@ static int me8200_do_io_irq_start(me_subdevice_t * subdevice,
return err;
}
-static int me8200_do_io_irq_wait(me_subdevice_t * subdevice,
+static int me8200_do_io_irq_wait(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *irq_count,
@@ -184,7 +184,7 @@ static int me8200_do_io_irq_wait(me_subdevice_t * subdevice,
return err;
}
-static int me8200_do_io_irq_stop(me_subdevice_t * subdevice,
+static int me8200_do_io_irq_stop(me_subdevice_t *subdevice,
struct file *filep, int channel, int flags)
{
me8200_do_subdevice_t *instance;
@@ -262,7 +262,7 @@ static int me8200_do_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_do_io_single_config(me_subdevice_t * subdevice,
+static int me8200_do_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -307,7 +307,7 @@ static int me8200_do_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me8200_do_io_single_read(me_subdevice_t * subdevice,
+static int me8200_do_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -354,7 +354,7 @@ static int me8200_do_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me8200_do_io_single_write(me_subdevice_t * subdevice,
+static int me8200_do_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -415,7 +415,7 @@ static int me8200_do_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me8200_do_query_number_channels(me_subdevice_t * subdevice,
+static int me8200_do_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -423,7 +423,7 @@ static int me8200_do_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_do_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8200_do_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -432,7 +432,7 @@ static int me8200_do_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me8200_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = ME_CAPS_DIO_OVER_TEMP_IRQ;
@@ -452,11 +452,7 @@ static void me8200_do_destructor(struct me_subdevice *subdevice)
kfree(instance);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me8200_do_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me8200_do_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
me8200_do_subdevice_t *instance;
uint16_t ctrl;
@@ -505,7 +501,7 @@ static irqreturn_t me8200_do_isr(int irq, void *dev_id, struct pt_regs *regs)
me8200_do_subdevice_t *me8200_do_constructor(uint32_t reg_base,
unsigned int do_idx,
int irq,
- spinlock_t * irq_mode_lock)
+ spinlock_t *irq_mode_lock)
{
me8200_do_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me8254.c b/drivers/staging/meilhaus/me8254.c
index 6e44c3d7a0c..d8f742a8ca9 100644
--- a/drivers/staging/meilhaus/me8254.c
+++ b/drivers/staging/meilhaus/me8254.c
@@ -35,7 +35,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -183,7 +183,7 @@ static int me8254_io_reset_subdevice(struct me_subdevice *subdevice,
return err;
}
-static int me1400_ab_ref_config(me8254_subdevice_t * instance, int ref)
+static int me1400_ab_ref_config(me8254_subdevice_t *instance, int ref)
{
uint8_t clk_src;
@@ -291,7 +291,7 @@ static int me1400_ab_ref_config(me8254_subdevice_t * instance, int ref)
return ME_ERRNO_SUCCESS;
}
-static int me1400_cd_ref_config(me8254_subdevice_t * instance, int ref)
+static int me1400_cd_ref_config(me8254_subdevice_t *instance, int ref)
{
uint8_t clk_src;
@@ -436,7 +436,7 @@ static int me1400_cd_ref_config(me8254_subdevice_t * instance, int ref)
return ME_ERRNO_SUCCESS;
}
-static int me4600_ref_config(me8254_subdevice_t * instance, int ref)
+static int me4600_ref_config(me8254_subdevice_t *instance, int ref)
{
switch (ref) {
@@ -453,7 +453,7 @@ static int me4600_ref_config(me8254_subdevice_t * instance, int ref)
return ME_ERRNO_SUCCESS;
}
-static int me8100_ref_config(me8254_subdevice_t * instance, int ref)
+static int me8100_ref_config(me8254_subdevice_t *instance, int ref)
{
switch (ref) {
@@ -962,8 +962,8 @@ me8254_subdevice_t *me8254_constructor(uint32_t device_id,
uint32_t reg_base,
unsigned int me8254_idx,
unsigned int ctr_idx,
- spinlock_t * ctrl_reg_lock,
- spinlock_t * clk_src_reg_lock)
+ spinlock_t *ctrl_reg_lock,
+ spinlock_t *clk_src_reg_lock)
{
me8254_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me8255.c b/drivers/staging/meilhaus/me8255.c
index 180e7f8d214..ec9c6389752 100644
--- a/drivers/staging/meilhaus/me8255.c
+++ b/drivers/staging/meilhaus/me8255.c
@@ -35,7 +35,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -318,7 +318,7 @@ me8255_subdevice_t *me8255_constructor(uint32_t device_id,
unsigned int me8255_idx,
unsigned int dio_idx,
int *ctrl_reg_mirror,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me8255_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/mecirc_buf.h b/drivers/staging/meilhaus/mecirc_buf.h
index e9b591eaa34..516658522ef 100644
--- a/drivers/staging/meilhaus/mecirc_buf.h
+++ b/drivers/staging/meilhaus/mecirc_buf.h
@@ -40,19 +40,19 @@ typedef struct me_circ_buf {
int volatile tail;
} me_circ_buf_t;
-static int inline me_circ_buf_values(me_circ_buf_t * buf)
+static inline int me_circ_buf_values(me_circ_buf_t * buf)
{
// return ((buf->head - buf->tail) & (buf->count - 1));
return ((buf->head - buf->tail) & (buf->mask));
}
-static int inline me_circ_buf_space(me_circ_buf_t * buf)
+static inline int me_circ_buf_space(me_circ_buf_t * buf)
{
// return ((buf->tail - (buf->head + 1)) & (buf->count - 1));
return ((buf->tail - (buf->head + 1)) & (buf->mask));
}
-static int inline me_circ_buf_values_to_end(me_circ_buf_t * buf)
+static inline int me_circ_buf_values_to_end(me_circ_buf_t * buf)
{
int end;
int n;
@@ -63,7 +63,7 @@ static int inline me_circ_buf_values_to_end(me_circ_buf_t * buf)
return (n < end) ? n : end;
}
-static int inline me_circ_buf_space_to_end(me_circ_buf_t * buf)
+static inline int me_circ_buf_space_to_end(me_circ_buf_t * buf)
{
int end;
int n;
@@ -99,19 +99,19 @@ typedef struct me_circ_buf_16b {
# endif //_CBUFF_32b_t
/** How many values is in buffer */
-static int inline me_circ_buf_values(me_circ_buf_t * buf)
+static inline int me_circ_buf_values(me_circ_buf_t * buf)
{
return ((buf->head - buf->tail) & (buf->mask));
}
/** How many space left */
-static int inline me_circ_buf_space(me_circ_buf_t * buf)
+static inline int me_circ_buf_space(me_circ_buf_t * buf)
{
return ((buf->tail - (buf->head + 1)) & (buf->mask));
}
/** How many values can be read from buffor in one chunck. */
-static int inline me_circ_buf_values_to_end(me_circ_buf_t * buf)
+static inline int me_circ_buf_values_to_end(me_circ_buf_t * buf)
{
return (buf->tail <=
buf->head) ? (buf->head - buf->tail) : (buf->mask - buf->tail +
@@ -119,7 +119,7 @@ static int inline me_circ_buf_values_to_end(me_circ_buf_t * buf)
}
/** How many values can be write to buffer in one chunck. */
-static int inline me_circ_buf_space_to_end(me_circ_buf_t * buf)
+static inline int me_circ_buf_space_to_end(me_circ_buf_t * buf)
{
return (buf->tail <=
buf->head) ? (buf->mask - buf->head + 1) : (buf->tail -
diff --git a/drivers/staging/meilhaus/medevice.c b/drivers/staging/meilhaus/medevice.c
index 8f62e16c7a3..75aaec0f681 100644
--- a/drivers/staging/meilhaus/medevice.c
+++ b/drivers/staging/meilhaus/medevice.c
@@ -390,9 +390,9 @@ static int me_device_io_single_write(struct me_device *device,
static int me_device_io_stream_config(struct me_device *device,
struct file *filep,
int subdevice,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
int err = ME_ERRNO_SUCCESS;
@@ -1040,7 +1040,7 @@ static int me_device_query_timer(struct me_device *device,
int subdevice,
int timer,
int *base_frequency,
- uint64_t * min_ticks, uint64_t * max_ticks)
+ uint64_t *min_ticks, uint64_t *max_ticks)
{
int err = ME_ERRNO_SUCCESS;
me_subdevice_t *s;
@@ -1082,14 +1082,14 @@ static int me_device_query_version_device_driver(struct me_device *device,
}
static int me_device_config_load(struct me_device *device, struct file *filep,
- me_cfg_device_entry_t * config)
+ me_cfg_device_entry_t *config)
{
PDEBUG("executed.\n");
return ME_ERRNO_SUCCESS; //If no need for config return success.
// return ME_ERRNO_NOT_SUPPORTED;
}
-static void me_device_destructor(me_device_t * me_device)
+static void me_device_destructor(me_device_t *me_device)
{
PDEBUG("executed.\n");
me_device_deinit(me_device);
@@ -1581,7 +1581,7 @@ static int get_device_descriptions(uint16_t device_id,
return 0;
}
-int me_device_pci_init(me_device_t * me_device, struct pci_dev *pci_device)
+int me_device_pci_init(me_device_t *me_device, struct pci_dev *pci_device)
{
int err;
int i;
@@ -1720,7 +1720,7 @@ int me_device_pci_init(me_device_t * me_device, struct pci_dev *pci_device)
return 1;
}
-void me_device_deinit(me_device_t * me_device)
+void me_device_deinit(me_device_t *me_device)
{
PDEBUG("executed.\n");
diff --git a/drivers/staging/meilhaus/medlist.c b/drivers/staging/meilhaus/medlist.c
index ef4e36955dc..b6a4065d2da 100644
--- a/drivers/staging/meilhaus/medlist.c
+++ b/drivers/staging/meilhaus/medlist.c
@@ -69,7 +69,7 @@ me_device_t *me_dlist_get_device(struct me_dlist * dlist, unsigned int index)
return device;
}
-void me_dlist_add_device_tail(struct me_dlist *dlist, me_device_t * device)
+void me_dlist_add_device_tail(struct me_dlist *dlist, me_device_t *device)
{
PDEBUG_LOCKS("called.\n");
@@ -99,7 +99,7 @@ me_device_t *me_dlist_del_device_tail(struct me_dlist *dlist)
return device;
}
-int me_dlist_init(me_dlist_t * dlist)
+int me_dlist_init(me_dlist_t *dlist)
{
PDEBUG_LOCKS("called.\n");
@@ -108,7 +108,7 @@ int me_dlist_init(me_dlist_t * dlist)
return 0;
}
-void me_dlist_deinit(me_dlist_t * dlist)
+void me_dlist_deinit(me_dlist_t *dlist)
{
struct list_head *s;
diff --git a/drivers/staging/meilhaus/medlock.c b/drivers/staging/meilhaus/medlock.c
index f649e3da4f0..8ded397214f 100644
--- a/drivers/staging/meilhaus/medlock.c
+++ b/drivers/staging/meilhaus/medlock.c
@@ -65,7 +65,7 @@ int me_dlock_exit(struct me_dlock *dlock, struct file *filep)
}
int me_dlock_lock(struct me_dlock *dlock,
- struct file *filep, int lock, int flags, me_slist_t * slist)
+ struct file *filep, int lock, int flags, me_slist_t *slist)
{
int err = ME_ERRNO_SUCCESS;
int i;
@@ -183,7 +183,7 @@ void me_dlock_deinit(struct me_dlock *dlock)
PDEBUG_LOCKS("executed.\n");
}
-int me_dlock_init(me_dlock_t * dlock)
+int me_dlock_init(me_dlock_t *dlock)
{
PDEBUG_LOCKS("executed.\n");
diff --git a/drivers/staging/meilhaus/medummy.c b/drivers/staging/meilhaus/medummy.c
index 6a9f08d50bb..2423745f957 100644
--- a/drivers/staging/meilhaus/medummy.c
+++ b/drivers/staging/meilhaus/medummy.c
@@ -47,7 +47,7 @@
#include "medummy.h"
-static int medummy_io_irq_start(me_device_t * device,
+static int medummy_io_irq_start(me_device_t *device,
struct file *filep,
int subdevice,
int channel,
@@ -58,7 +58,7 @@ static int medummy_io_irq_start(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_irq_wait(me_device_t * device,
+static int medummy_io_irq_wait(me_device_t *device,
struct file *filep,
int subdevice,
int channel,
@@ -69,7 +69,7 @@ static int medummy_io_irq_wait(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_irq_stop(me_device_t * device,
+static int medummy_io_irq_stop(me_device_t *device,
struct file *filep,
int subdevice, int channel, int flags)
{
@@ -77,14 +77,14 @@ static int medummy_io_irq_stop(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_reset_device(me_device_t * device,
+static int medummy_io_reset_device(me_device_t *device,
struct file *filep, int flags)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_reset_subdevice(me_device_t * device,
+static int medummy_io_reset_subdevice(me_device_t *device,
struct file *filep,
int subdevice, int flags)
{
@@ -92,7 +92,7 @@ static int medummy_io_reset_subdevice(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_single_config(me_device_t * device,
+static int medummy_io_single_config(me_device_t *device,
struct file *filep,
int subdevice,
int channel,
@@ -105,7 +105,7 @@ static int medummy_io_single_config(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_single_read(me_device_t * device,
+static int medummy_io_single_read(me_device_t *device,
struct file *filep,
int subdevice,
int channel,
@@ -115,7 +115,7 @@ static int medummy_io_single_read(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_single_write(me_device_t * device,
+static int medummy_io_single_write(me_device_t *device,
struct file *filep,
int subdevice,
int channel,
@@ -125,19 +125,19 @@ static int medummy_io_single_write(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_config(me_device_t * device,
+static int medummy_io_stream_config(me_device_t *device,
struct file *filep,
int subdevice,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_new_values(me_device_t * device,
+static int medummy_io_stream_new_values(me_device_t *device,
struct file *filep,
int subdevice,
int timeout, int *count, int flags)
@@ -146,7 +146,7 @@ static int medummy_io_stream_new_values(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_read(me_device_t * device,
+static int medummy_io_stream_read(me_device_t *device,
struct file *filep,
int subdevice,
int read_mode,
@@ -156,7 +156,7 @@ static int medummy_io_stream_read(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_start(me_device_t * device,
+static int medummy_io_stream_start(me_device_t *device,
struct file *filep,
int subdevice,
int start_mode, int time_out, int flags)
@@ -165,7 +165,7 @@ static int medummy_io_stream_start(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_status(me_device_t * device,
+static int medummy_io_stream_status(me_device_t *device,
struct file *filep,
int subdevice,
int wait,
@@ -175,7 +175,7 @@ static int medummy_io_stream_status(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_stop(me_device_t * device,
+static int medummy_io_stream_stop(me_device_t *device,
struct file *filep,
int subdevice, int stop_mode, int flags)
{
@@ -183,7 +183,7 @@ static int medummy_io_stream_stop(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_write(me_device_t * device,
+static int medummy_io_stream_write(me_device_t *device,
struct file *filep,
int subdevice,
int write_mode,
@@ -193,14 +193,14 @@ static int medummy_io_stream_write(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_lock_device(me_device_t * device,
+static int medummy_lock_device(me_device_t *device,
struct file *filep, int lock, int flags)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_lock_subdevice(me_device_t * device,
+static int medummy_lock_subdevice(me_device_t *device,
struct file *filep,
int subdevice, int lock, int flags)
{
@@ -208,7 +208,7 @@ static int medummy_lock_subdevice(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_description_device(me_device_t * device,
+static int medummy_query_description_device(me_device_t *device,
char **description)
{
medummy_device_t *instance = (medummy_device_t *) device;
@@ -602,7 +602,7 @@ static int medummy_query_description_device(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_info_device(me_device_t * device,
+static int medummy_query_info_device(me_device_t *device,
int *vendor_id,
int *device_id,
int *serial_no,
@@ -632,14 +632,14 @@ static int medummy_query_info_device(me_device_t * device,
return ME_ERRNO_SUCCESS;
}
-static int medummy_query_name_device_driver(me_device_t * device, char **name)
+static int medummy_query_name_device_driver(me_device_t *device, char **name)
{
PDEBUG("executed.\n");
*name = MEDUMMY_NAME_DRIVER;
return ME_ERRNO_SUCCESS;
}
-static int medummy_query_name_device(me_device_t * device, char **name)
+static int medummy_query_name_device(me_device_t *device, char **name)
{
medummy_device_t *instance = (medummy_device_t *) device;
@@ -1012,41 +1012,41 @@ static int medummy_query_name_device(me_device_t * device, char **name)
return ME_ERRNO_SUCCESS;
}
-static int medummy_query_number_subdevices(me_device_t * device, int *number)
+static int medummy_query_number_subdevices(me_device_t *device, int *number)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_number_channels(me_device_t * device,
+static int medummy_query_number_channels(me_device_t *device,
int subdevice, int *number)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_number_ranges(me_device_t * device,
+static int medummy_query_number_ranges(me_device_t *device,
int subdevice, int unit, int *count)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_subdevice_type(me_device_t * device,
+static int medummy_query_subdevice_type(me_device_t *device,
int subdevice, int *type, int *subtype)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_subdevice_caps(me_device_t * device,
+static int medummy_query_subdevice_caps(me_device_t *device,
int subdevice, int *caps)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_subdevice_caps_args(me_device_t * device,
+static int medummy_query_subdevice_caps_args(me_device_t *device,
int subdevice,
int cap, int *args, int count)
{
@@ -1054,7 +1054,7 @@ static int medummy_query_subdevice_caps_args(me_device_t * device,
return ME_ERRNO_NOT_SUPPORTED;
}
-static int medummy_query_subdevice_by_type(me_device_t * device,
+static int medummy_query_subdevice_by_type(me_device_t *device,
int start_subdevice,
int type,
int subtype, int *subdevice)
@@ -1063,7 +1063,7 @@ static int medummy_query_subdevice_by_type(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_range_by_min_max(me_device_t * device,
+static int medummy_query_range_by_min_max(me_device_t *device,
int subdevice,
int unit,
int *min,
@@ -1073,7 +1073,7 @@ static int medummy_query_range_by_min_max(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_range_info(me_device_t * device,
+static int medummy_query_range_info(me_device_t *device,
int subdevice,
int range,
int *unit, int *min, int *max, int *maxdata)
@@ -1082,17 +1082,17 @@ static int medummy_query_range_info(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-int medummy_query_timer(me_device_t * device,
+int medummy_query_timer(me_device_t *device,
int subdevice,
int timer,
int *base_frequency,
- uint64_t * min_ticks, uint64_t * max_ticks)
+ uint64_t *min_ticks, uint64_t *max_ticks)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_version_device_driver(me_device_t * device,
+static int medummy_query_version_device_driver(me_device_t *device,
int *version)
{
PDEBUG("executed.\n");
@@ -1101,7 +1101,7 @@ static int medummy_query_version_device_driver(me_device_t * device,
return ME_ERRNO_SUCCESS;
}
-static void medummy_destructor(me_device_t * device)
+static void medummy_destructor(me_device_t *device)
{
PDEBUG("executed.\n");
kfree(device);
@@ -1113,7 +1113,7 @@ static int init_device_info(unsigned short vendor_id,
int bus_type,
int bus_no,
int dev_no,
- int func_no, medummy_device_t * instance)
+ int func_no, medummy_device_t *instance)
{
PDEBUG("executed.\n");
@@ -1129,14 +1129,14 @@ static int init_device_info(unsigned short vendor_id,
return 0;
}
-static int medummy_config_load(me_device_t * device, struct file *filep,
- me_cfg_device_entry_t * config)
+static int medummy_config_load(me_device_t *device, struct file *filep,
+ me_cfg_device_entry_t *config)
{
PDEBUG("executed.\n");
return ME_ERRNO_SUCCESS;
}
-static int init_device_instance(me_device_t * device)
+static int init_device_instance(me_device_t *device)
{
PDEBUG("executed.\n");
@@ -1238,6 +1238,7 @@ me_device_t *medummy_constructor(unsigned short vendor_id,
return (me_device_t *) instance;
}
+EXPORT_SYMBOL(medummy_constructor);
// Init and exit of module.
@@ -1261,6 +1262,3 @@ MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-DUMMY Devices");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-DUMMY Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(medummy_constructor);
diff --git a/drivers/staging/meilhaus/memain.c b/drivers/staging/meilhaus/memain.c
index b09d1a6c766..fd9f079b0ed 100644
--- a/drivers/staging/meilhaus/memain.c
+++ b/drivers/staging/meilhaus/memain.c
@@ -37,7 +37,7 @@
#include <linux/pci.h>
//#include <linux/usb.h>
#include <linux/errno.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/cdev.h>
#include <linux/rwsem.h>
@@ -56,6 +56,7 @@
#ifdef BOSCH
static unsigned int me_bosch_fw = 0;
+EXPORT_SYMBOL(me_bosch_fw);
# ifdef module_param
module_param(me_bosch_fw, int, S_IRUGO);
@@ -79,7 +80,7 @@ MODULE_PARM(major, "i");
static struct file *me_filep = NULL;
static int me_count = 0;
-static spinlock_t me_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(me_lock);
static DECLARE_RWSEM(me_rwsem);
/* Board instances are kept in a global list */
@@ -90,7 +91,7 @@ LIST_HEAD(me_device_list);
static int me_probe_pci(struct pci_dev *dev, const struct pci_device_id *id);
static void me_remove_pci(struct pci_dev *dev);
-static int insert_to_device_list(me_device_t * n_device);
+static int insert_to_device_list(me_device_t *n_device);
static int replace_with_dummy(int vendor_id, int device_id, int serial_no);
static void clear_device_list(void);
static int me_open(struct inode *inode_ptr, struct file *filep);
@@ -472,7 +473,7 @@ static int me_probe_pci(struct pci_dev *dev, const struct pci_device_id *id)
return ME_ERRNO_SUCCESS;
}
-static void release_instance(me_device_t * device)
+static void release_instance(me_device_t *device)
{
int vendor_id;
int device_id;
@@ -517,7 +518,7 @@ static void release_instance(me_device_t * device)
}
}
-static int insert_to_device_list(me_device_t * n_device)
+static int insert_to_device_list(me_device_t *n_device)
{
me_device_t *o_device = NULL;
@@ -762,7 +763,7 @@ static int lock_driver(struct file *filep, int lock, int flags)
return err;
}
-static int me_lock_driver(struct file *filep, me_lock_driver_t * arg)
+static int me_lock_driver(struct file *filep, me_lock_driver_t *arg)
{
int err = 0;
@@ -807,7 +808,7 @@ static int me_release(struct inode *inode_ptr, struct file *filep)
}
static int me_query_version_main_driver(struct file *filep,
- me_query_version_main_driver_t * arg)
+ me_query_version_main_driver_t *arg)
{
int err;
me_query_version_main_driver_t karg;
@@ -828,7 +829,7 @@ static int me_query_version_main_driver(struct file *filep,
}
static int me_config_load_device(struct file *filep,
- me_cfg_device_entry_t * karg, int device_no)
+ me_cfg_device_entry_t *karg, int device_no)
{
int err = ME_ERRNO_SUCCESS;
@@ -874,7 +875,7 @@ static int me_config_load_device(struct file *filep,
return err;
}
-static int me_config_load(struct file *filep, me_config_load_t * arg)
+static int me_config_load(struct file *filep, me_config_load_t *arg)
{
int err;
int i;
@@ -1170,7 +1171,7 @@ static int me_config_load(struct file *filep, me_config_load_t * arg)
return 0;
}
-static int me_io_stream_start(struct file *filep, me_io_stream_start_t * arg)
+static int me_io_stream_start(struct file *filep, me_io_stream_start_t *arg)
{
int err;
int i, k;
@@ -1292,7 +1293,7 @@ static int me_io_stream_start(struct file *filep, me_io_stream_start_t * arg)
return err;
}
-static int me_io_single(struct file *filep, me_io_single_t * arg)
+static int me_io_single(struct file *filep, me_io_single_t *arg)
{
int err;
int i, k;
@@ -1448,7 +1449,7 @@ static int me_io_single(struct file *filep, me_io_single_t * arg)
return err;
}
-static int me_io_stream_config(struct file *filep, me_io_stream_config_t * arg)
+static int me_io_stream_config(struct file *filep, me_io_stream_config_t *arg)
{
int err;
int k = 0;
@@ -1540,7 +1541,7 @@ static int me_io_stream_config(struct file *filep, me_io_stream_config_t * arg)
}
static int me_query_number_devices(struct file *filep,
- me_query_number_devices_t * arg)
+ me_query_number_devices_t *arg)
{
int err;
me_query_number_devices_t karg;
@@ -1569,7 +1570,7 @@ static int me_query_number_devices(struct file *filep,
return 0;
}
-static int me_io_stream_stop(struct file *filep, me_io_stream_stop_t * arg)
+static int me_io_stream_stop(struct file *filep, me_io_stream_stop_t *arg)
{
int err;
int i, k;
@@ -2015,8 +2016,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Central module for Meilhaus Driver System.");
MODULE_SUPPORTED_DEVICE("Meilhaus PCI/cPCI boards.");
MODULE_LICENSE("GPL");
-
-#ifdef BOSCH
-// Export the flag for the BOSCH firmware.
-EXPORT_SYMBOL(me_bosch_fw);
-#endif // BOSCH
diff --git a/drivers/staging/meilhaus/meslist.c b/drivers/staging/meilhaus/meslist.c
index 7e8b66c05f7..ce49114df55 100644
--- a/drivers/staging/meilhaus/meslist.c
+++ b/drivers/staging/meilhaus/meslist.c
@@ -115,7 +115,7 @@ int me_slist_get_subdevice_by_type(struct me_slist *slist,
}
void me_slist_add_subdevice_tail(struct me_slist *slist,
- me_subdevice_t * subdevice)
+ me_subdevice_t *subdevice)
{
PDEBUG_LOCKS("called.\n");
@@ -145,7 +145,7 @@ me_subdevice_t *me_slist_del_subdevice_tail(struct me_slist *slist)
return subdevice;
}
-int me_slist_init(me_slist_t * slist)
+int me_slist_init(me_slist_t *slist)
{
PDEBUG_LOCKS("called.\n");
@@ -154,7 +154,7 @@ int me_slist_init(me_slist_t * slist)
return 0;
}
-void me_slist_deinit(me_slist_t * slist)
+void me_slist_deinit(me_slist_t *slist)
{
struct list_head *s;
diff --git a/drivers/staging/meilhaus/meslock.c b/drivers/staging/meilhaus/meslock.c
index 5230b89b45b..abcdb4a2eba 100644
--- a/drivers/staging/meilhaus/meslock.c
+++ b/drivers/staging/meilhaus/meslock.c
@@ -124,7 +124,7 @@ void me_slock_deinit(struct me_slock *slock)
PDEBUG_LOCKS("executed.\n");
}
-int me_slock_init(me_slock_t * slock)
+int me_slock_init(me_slock_t *slock)
{
PDEBUG_LOCKS("executed.\n");
diff --git a/drivers/staging/meilhaus/mesubdevice.c b/drivers/staging/meilhaus/mesubdevice.c
index 98d4f1f7a82..b2e956726b5 100644
--- a/drivers/staging/meilhaus/mesubdevice.c
+++ b/drivers/staging/meilhaus/mesubdevice.c
@@ -101,9 +101,9 @@ static int me_subdevice_io_single_write(struct me_subdevice *subdevice,
static int me_subdevice_io_stream_config(struct me_subdevice *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
PDEBUG("executed.\n");
@@ -162,7 +162,7 @@ static int me_subdevice_io_stream_write(struct me_subdevice *subdevice,
return ME_ERRNO_NOT_SUPPORTED;
}
-static int me_subdevice_lock_subdevice(me_subdevice_t * subdevice,
+static int me_subdevice_lock_subdevice(me_subdevice_t *subdevice,
struct file *filep, int lock, int flags)
{
PDEBUG("executed.\n");
@@ -235,7 +235,7 @@ static int me_subdevice_query_timer(struct me_subdevice *subdevice,
}
static int me_subdevice_config_load(struct me_subdevice *subdevice,
- me_cfg_device_entry_t * config)
+ me_cfg_device_entry_t *config)
{
PDEBUG("executed.\n");
return ME_ERRNO_SUCCESS;
@@ -248,7 +248,7 @@ static void me_subdevice_destructor(struct me_subdevice *subdevice)
kfree(subdevice);
}
-int me_subdevice_init(me_subdevice_t * subdevice)
+int me_subdevice_init(me_subdevice_t *subdevice)
{
int err;
@@ -308,7 +308,7 @@ int me_subdevice_init(me_subdevice_t * subdevice)
return 0;
}
-void me_subdevice_deinit(me_subdevice_t * subdevice)
+void me_subdevice_deinit(me_subdevice_t *subdevice)
{
PDEBUG("executed.\n");
me_subdevice_io_reset_subdevice(subdevice, NULL,
diff --git a/drivers/staging/meilhaus/metempl_device.c b/drivers/staging/meilhaus/metempl_device.c
index e48632ddc1a..bdaf6df7277 100644
--- a/drivers/staging/meilhaus/metempl_device.c
+++ b/drivers/staging/meilhaus/metempl_device.c
@@ -109,6 +109,7 @@ me_device_t *metempl_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) metempl_device;
}
+EXPORT_SYMBOL(metempl_pci_constructor);
// Init and exit of module.
@@ -132,6 +133,3 @@ MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
MODULE_DESCRIPTION("Device Driver Module for Template Device");
MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(metempl_pci_constructor);
diff --git a/drivers/staging/meilhaus/metempl_sub.c b/drivers/staging/meilhaus/metempl_sub.c
index f1d65d889e2..b5a6a978b50 100644
--- a/drivers/staging/meilhaus/metempl_sub.c
+++ b/drivers/staging/meilhaus/metempl_sub.c
@@ -35,7 +35,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -68,7 +68,7 @@ static void metempl_sub_destructor(struct me_subdevice *subdevice)
kfree(instance);
}
-static int metempl_sub_query_number_channels(me_subdevice_t * subdevice,
+static int metempl_sub_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -76,7 +76,7 @@ static int metempl_sub_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int metempl_sub_query_subdevice_type(me_subdevice_t * subdevice,
+static int metempl_sub_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -85,7 +85,7 @@ static int metempl_sub_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int metempl_sub_query_subdevice_caps(me_subdevice_t * subdevice,
+static int metempl_sub_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -95,7 +95,7 @@ static int metempl_sub_query_subdevice_caps(me_subdevice_t * subdevice,
metempl_sub_subdevice_t *metempl_sub_constructor(uint32_t reg_base,
unsigned int sub_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
metempl_sub_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/mimio/Kconfig b/drivers/staging/mimio/Kconfig
index c0ba4c800df..505dcb27579 100644
--- a/drivers/staging/mimio/Kconfig
+++ b/drivers/staging/mimio/Kconfig
@@ -1,6 +1,6 @@
config INPUT_MIMIO
tristate "Mimio Xi interactive whiteboard support"
- depends on USB
+ depends on USB && INPUT
default N
help
Say Y here if you want to use a Mimio Xi interactive
diff --git a/drivers/staging/otus/80211core/amsdu.c b/drivers/staging/otus/80211core/amsdu.c
index c9123d58b82..0321288d107 100644
--- a/drivers/staging/otus/80211core/amsdu.c
+++ b/drivers/staging/otus/80211core/amsdu.c
@@ -34,53 +34,53 @@
/* Stephen Chen Atheros Communications, INC. 2007.2 */
/* */
/************************************************************************/
-zbuf_t* zfGetAmsduSubFrame(zdev_t* dev, zbuf_t* buf, u16_t* offset)
+zbuf_t *zfGetAmsduSubFrame(zdev_t *dev, zbuf_t *buf, u16_t *offset)
{
- u16_t subframeLen;
- u16_t amsduLen = zfwBufGetSize(dev, buf);
- zbuf_t* newBuf;
-
- ZM_PERFORMANCE_RX_AMSDU(dev, buf, amsduLen);
-
- /* Verify A-MSDU length */
- if (amsduLen < (*offset + 14))
- {
- return NULL;
- }
-
- /* Locate A-MSDU subframe by offset and verify subframe length */
- subframeLen = (zmw_buf_readb(dev, buf, *offset + 12) << 8) +
- zmw_buf_readb(dev, buf, *offset + 13);
- if (subframeLen == 0)
- {
- return NULL;
- }
-
- /* Verify A-MSDU subframe length */
- if ((*offset+14+subframeLen) <= amsduLen)
- {
- /* Allocate a new buffer */
- if ((newBuf = zfwBufAllocate(dev, 24+2+subframeLen)) != NULL)
- {
-#ifdef ZM_ENABLE_NATIVE_WIFI
- /* Copy and convert subframe to wlan frame format */
- /* SHALL NOT INCLUDE QOS and AMSDU header. Ray 20070807 For Vista */
- zfRxBufferCopy(dev, newBuf, buf, 0, 0, 24);
- zfRxBufferCopy(dev, newBuf, buf, 24, *offset+14, subframeLen);
- zfwBufSetSize(dev, newBuf, 24+subframeLen);
-#else
- /* Copy subframe to new buffer */
- zfRxBufferCopy(dev, newBuf, buf, 0, *offset, 14+subframeLen);
- zfwBufSetSize(dev, newBuf, 14+subframeLen);
-#endif
- /* Update offset */
- *offset += (((14+subframeLen)+3) & 0xfffc);
-
- /* Return buffer pointer */
- return newBuf;
- }
- }
- return NULL;
+ u16_t subframeLen;
+ u16_t amsduLen = zfwBufGetSize(dev, buf);
+ zbuf_t *newBuf;
+
+ ZM_PERFORMANCE_RX_AMSDU(dev, buf, amsduLen);
+
+ /* Verify A-MSDU length */
+ if (amsduLen < (*offset + 14))
+ return NULL;
+
+ /* Locate A-MSDU subframe by offset and verify subframe length */
+ subframeLen = (zmw_buf_readb(dev, buf, *offset + 12) << 8) +
+ zmw_buf_readb(dev, buf, *offset + 13);
+
+ if (subframeLen == 0)
+ return NULL;
+
+ /* Verify A-MSDU subframe length */
+ if ((*offset+14+subframeLen) <= amsduLen) {
+ /* Allocate a new buffer */
+ newBuf = zfwBufAllocate(dev, 24+2+subframeLen);
+ if (newBuf != NULL) {
+ #ifdef ZM_ENABLE_NATIVE_WIFI
+ /* Copy and convert subframe to wlan frame format
+ * SHALL NOT INCLUDE QOS and AMSDU header.
+ * Ray 20070807 For Vista
+ */
+ zfRxBufferCopy(dev, newBuf, buf, 0, 0, 24);
+ zfRxBufferCopy(dev, newBuf, buf, 24, *offset+14,
+ subframeLen);
+ zfwBufSetSize(dev, newBuf, 24+subframeLen);
+ #else
+ /* Copy subframe to new buffer */
+ zfRxBufferCopy(dev, newBuf, buf, 0, *offset,
+ 14+subframeLen);
+ zfwBufSetSize(dev, newBuf, 14+subframeLen);
+ #endif
+ /* Update offset */
+ *offset += (((14+subframeLen)+3) & 0xfffc);
+
+ /* Return buffer pointer */
+ return newBuf;
+ }
+ }
+ return NULL;
}
@@ -101,34 +101,29 @@ zbuf_t* zfGetAmsduSubFrame(zdev_t* dev, zbuf_t* buf, u16_t* offset)
/* Stephen Chen Atheros Communications, INC. 2007.2 */
/* */
/************************************************************************/
-void zfDeAmsdu(zdev_t* dev, zbuf_t* buf, u16_t vap, u8_t encryMode)
+void zfDeAmsdu(zdev_t *dev, zbuf_t *buf, u16_t vap, u8_t encryMode)
{
- u16_t offset = ZM_SIZE_OF_WLAN_DATA_HEADER+ZM_SIZE_OF_QOS_CTRL;
- zbuf_t* subframeBuf;
- zmw_get_wlan_dev(dev);
-
- ZM_BUFFER_TRACE(dev, buf)
-
- if (encryMode == ZM_AES || encryMode == ZM_TKIP)
- {
- offset += (ZM_SIZE_OF_IV + ZM_SIZE_OF_EXT_IV);
- }
- else if (encryMode == ZM_WEP64 || encryMode == ZM_WEP128)
- {
- offset += ZM_SIZE_OF_IV;
- }
-
- /* Repeatly calling zfGetAmsduSubFrame() until NULL returned */
- while ((subframeBuf = zfGetAmsduSubFrame(dev, buf, &offset)) != NULL)
- {
- wd->commTally.NotifyNDISRxFrmCnt++;
- if (wd->zfcbRecvEth != NULL)
- {
- wd->zfcbRecvEth(dev, subframeBuf, (u8_t)vap);
- ZM_PERFORMANCE_RX_MSDU(dev, wd->tick);
- }
- }
- zfwBufFree(dev, buf, 0);
-
- return;
+ u16_t offset = ZM_SIZE_OF_WLAN_DATA_HEADER+ZM_SIZE_OF_QOS_CTRL;
+ zbuf_t *subframeBuf;
+ zmw_get_wlan_dev(dev);
+
+ ZM_BUFFER_TRACE(dev, buf)
+
+ if (encryMode == ZM_AES || encryMode == ZM_TKIP)
+ offset += (ZM_SIZE_OF_IV + ZM_SIZE_OF_EXT_IV);
+ else if (encryMode == ZM_WEP64 || encryMode == ZM_WEP128)
+ offset += ZM_SIZE_OF_IV;
+
+
+ /* Repeatly calling zfGetAmsduSubFrame() until NULL returned */
+ while ((subframeBuf = zfGetAmsduSubFrame(dev, buf, &offset)) != NULL) {
+ wd->commTally.NotifyNDISRxFrmCnt++;
+ if (wd->zfcbRecvEth != NULL) {
+ wd->zfcbRecvEth(dev, subframeBuf, (u8_t)vap);
+ ZM_PERFORMANCE_RX_MSDU(dev, wd->tick);
+ }
+ }
+ zfwBufFree(dev, buf, 0);
+
+ return;
}
diff --git a/drivers/staging/otus/80211core/cmmsta.c b/drivers/staging/otus/80211core/cmmsta.c
index c75ba11ee43..b28a4e25e10 100644
--- a/drivers/staging/otus/80211core/cmmsta.c
+++ b/drivers/staging/otus/80211core/cmmsta.c
@@ -724,6 +724,9 @@ void zfStaUpdateWmeParameter(zdev_t* dev, zbuf_t* buf)
/* process 802.11h Dynamic Frequency Selection */
void zfStaUpdateDot11HDFS(zdev_t* dev, zbuf_t* buf)
{
+ //u8_t length, channel, is5G;
+ u16_t offset;
+
zmw_get_wlan_dev(dev);
/*
@@ -736,8 +739,6 @@ void zfStaUpdateDot11HDFS(zdev_t* dev, zbuf_t* buf)
|Value | 37 | 3 | 0 or 1 |unsigned integer |unsigned integer |
+------+----------+------+-------------------+------------------+--------------------+
*/
- //u8_t length, channel, is5G;
- u16_t offset;
/* get EID(Channel Switch Announcement) */
if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CHANNEL_SWITCH_ANNOUNCE)) == 0xffff )
diff --git a/drivers/staging/otus/80211core/coid.c b/drivers/staging/otus/80211core/coid.c
index 6007f3131f8..88f8d3491a8 100644
--- a/drivers/staging/otus/80211core/coid.c
+++ b/drivers/staging/otus/80211core/coid.c
@@ -214,10 +214,10 @@ u32_t zfiWlanQuerySupportMode(zdev_t* dev)
u32_t zfiWlanQueryTransmitPower(zdev_t* dev)
{
- zmw_get_wlan_dev(dev);
-
u32_t ret = 0;
+ zmw_get_wlan_dev(dev);
+
if (zfStaIsConnected(dev)) {
ret = wd->sta.connPowerInHalfDbm;
} else {
@@ -1432,12 +1432,12 @@ u32_t zfiWlanQueryCurrentFrequency(zdev_t* dev, u8_t qmode)
u32_t zfiWlanQueryFrequencyAttribute(zdev_t* dev, u32_t freq)
{
- zmw_get_wlan_dev(dev);
-
u8_t i;
u16_t frequency = (u16_t) (freq/1000);
u32_t ret = 0;
+ zmw_get_wlan_dev(dev);
+
for (i = 0; i < wd->regulationTable.allowChannelCnt; i++)
{
if ( wd->regulationTable.allowChannel[i].channel == frequency )
diff --git a/drivers/staging/otus/80211core/cwm.c b/drivers/staging/otus/80211core/cwm.c
index 80f1141bf91..1bd0b1ff12d 100644
--- a/drivers/staging/otus/80211core/cwm.c
+++ b/drivers/staging/otus/80211core/cwm.c
@@ -75,9 +75,9 @@ void zfCoreCwmBusy(zdev_t* dev, u16_t busy)
if((wd->wlanMode == ZM_MODE_INFRASTRUCTURE || wd->wlanMode == ZM_MODE_PSEUDO ||
wd->wlanMode == ZM_MODE_IBSS)) {
- if (wd->sta.ie.HtCap.HtCapInfo && HTCAP_SupChannelWidthSet != 0 &&
- wd->sta.ie.HtInfo.ChannelInfo && ExtHtCap_RecomTxWidthSet != 0 &&
- (wd->sta.ie.HtInfo.ChannelInfo && ExtHtCap_ExtChannelOffsetAbove) == 1) {
+ if ((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) &&
+ (wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_RecomTxWidthSet) &&
+ (wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_ExtChannelOffsetAbove)) {
wd->cwm.cw_width = CWM_WIDTH40;
}
diff --git a/drivers/staging/otus/TODO b/drivers/staging/otus/TODO
index e912293ed1e..4caf026a491 100644
--- a/drivers/staging/otus/TODO
+++ b/drivers/staging/otus/TODO
@@ -1,8 +1,15 @@
+I'm hesitant to add a TODO file here, as the wireless developers would
+really have people help them out on the "clean" ar9170 driver that can
+be found at the linux-wireless developer site.
+
+But, if you wish to clean up this driver instead, here's a short list of
+things that need to be done to get it into a more mergable shape:
+
TODO:
- checkpatch.pl cleanups
- sparse cleanups
- port to in-kernel 80211 stack
- - proper network developer maintainer
+ - review by the wireless developer community
Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
Luis Rodriguez <Luis.Rodriguez@Atheros.com> and the
diff --git a/drivers/staging/otus/hal/hpani.c b/drivers/staging/otus/hal/hpani.c
index ba95b5d012a..0afecd8c2de 100644
--- a/drivers/staging/otus/hal/hpani.c
+++ b/drivers/staging/otus/hal/hpani.c
@@ -55,10 +55,10 @@ extern u16_t zfFlushDelayWrite(zdev_t* dev);
s32_t BEACON_RSSI(zdev_t* dev)
{
s32_t rssi;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
rssi = ZM_HAL_EP_RND(HpPriv->stats.ast_nodestats.ns_avgbrssi, ZM_HAL_RSSI_EP_MULTIPLIER);
@@ -74,16 +74,16 @@ void zfHpAniAttach(zdev_t* dev)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
u32_t i;
-
- zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ struct zsHpPriv *HpPriv;
const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
const int coarseHigh[] = { -14, -14, -14, -14, -12 };
const int coarseLow[] = { -64, -64, -64, -64, -70 };
const int firpwr[] = { -78, -78, -78, -78, -80 };
+ zmw_get_wlan_dev(dev);
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+
for (i = 0; i < 5; i++)
{
HpPriv->totalSizeDesired[i] = totalSizeDesired[i];
@@ -139,12 +139,12 @@ u8_t zfHpAniControl(zdev_t* dev, ZM_HAL_ANI_CMD cmd, int param)
{
#define N(a) (sizeof(a)/sizeof(a[0]))
typedef s32_t TABLE[];
+ struct zsHpPriv *HpPriv;
+ struct zsAniState *aniState;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
-
- struct zsAniState *aniState = HpPriv->curani;
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ aniState = HpPriv->curani;
switch (cmd)
{
@@ -346,11 +346,10 @@ u8_t zfHpAniControl(zdev_t* dev, ZM_HAL_ANI_CMD cmd, int param)
void zfHpAniRestart(zdev_t* dev)
{
struct zsAniState *aniState;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
-
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
aniState = HpPriv->curani;
aniState->listenTime = 0;
@@ -387,10 +386,10 @@ void zfHpAniOfdmErrTrigger(zdev_t* dev)
{
struct zsAniState *aniState;
s32_t rssi;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
//HALASSERT(chan != NULL);
@@ -466,10 +465,10 @@ void zfHpAniCckErrTrigger(zdev_t* dev)
{
struct zsAniState *aniState;
s32_t rssi;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
//HALASSERT(chan != NULL);
@@ -511,11 +510,10 @@ void zfHpAniLowerImmunity(zdev_t* dev)
{
struct zsAniState *aniState;
s32_t rssi;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
-
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
aniState = HpPriv->curani;
rssi = BEACON_RSSI(dev);
@@ -586,10 +584,10 @@ s32_t zfHpAniGetListenTime(zdev_t* dev)
struct zsAniState *aniState;
u32_t txFrameCount, rxFrameCount, cycleCount;
s32_t listenTime;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
txFrameCount = 0;//OS_REG_READ(ah, AR_TFCNT);
rxFrameCount = 0;//OS_REG_READ(ah, AR_RFCNT);
@@ -627,10 +625,10 @@ void zfHpAniArPoll(zdev_t* dev, u32_t listenTime, u32_t phyCnt1, u32_t phyCnt2)
{
struct zsAniState *aniState;
//s32_t listenTime;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
/*
* Since we're called from end of rx tasklet, we also check for
diff --git a/drivers/staging/otus/hal/hpmain.c b/drivers/staging/otus/hal/hpmain.c
index 2e65c466aae..322585be2c8 100644
--- a/drivers/staging/otus/hal/hpmain.c
+++ b/drivers/staging/otus/hal/hpmain.c
@@ -152,7 +152,7 @@ u16_t zfHpInit(zdev_t* dev, u32_t frequency)
else
{
#ifndef ZM_OTUS_LINUX_PHASE_2
- /* donwload the normal frimware */
+ /* download the normal firmware */
if ((ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage,
(u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS)
{
@@ -328,8 +328,8 @@ void zfInitPhy(zdev_t* dev, u32_t frequency, u8_t bw40)
u16_t modesIndex = 0;
u16_t freqIndex = 0;
u32_t tmp, tmp1;
- zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ struct zsHpPriv* hpPriv;
+
u32_t eepromBoardData[15][6] = {
/* Register A-20 A-20/40 G-20/40 G-20 G-Turbo */
{0x9964, 0, 0, 0, 0, 0},
@@ -349,6 +349,9 @@ void zfInitPhy(zdev_t* dev, u32_t frequency, u8_t bw40)
{0xa258, 0, 0, 0, 0, 0},
};
+ zmw_get_wlan_dev(dev);
+ hpPriv=wd->hpPrivate;
+
/* #1 Save the initial value of the related RIFS register settings */
//((struct zsHpPriv*)wd->hpPrivate)->isInitialPhy++;
@@ -1324,9 +1327,10 @@ void zfHpSetFrequencyEx(zdev_t* dev, u32_t frequency, u8_t bw40,
int delta_slope_coeff_man;
int delta_slope_coeff_exp_shgi;
int delta_slope_coeff_man_shgi;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
zm_msg1_scan(ZM_LV_1, "Frequency = ", frequency);
zm_msg1_scan(ZM_LV_1, "bw40 = ", bw40);
@@ -1560,9 +1564,10 @@ u16_t zfHpResetKeyCache(zdev_t* dev)
{
u8_t i;
u32_t key[4] = {0, 0, 0, 0};
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
for(i=0;i<4;i++)
{
@@ -1601,9 +1606,10 @@ u32_t zfHpSetKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t type,
u32_t cmd[(ZM_MAX_CMD_SIZE/4)];
u16_t ret;
u16_t i;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
#if 0 /* remove to zfCoreSetKey() */
zmw_declare_for_critical_section();
@@ -1670,8 +1676,10 @@ u32_t zfHpSetDefaultKey(zdev_t* dev, u8_t keyId, u8_t type, u32_t* key, u32_t* m
u16_t macAddr[3] = {0, 0, 0};
#ifdef ZM_ENABLE_IBSS_WPA2PSK
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
if ( hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_WPA2PSK )
{ /* If not wpa2psk , use traditional */
@@ -1702,8 +1710,10 @@ u32_t zfHpSetDefaultKey(zdev_t* dev, u8_t keyId, u8_t type, u32_t* key, u32_t* m
u32_t zfHpSetPerUserKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t* mac, u8_t type, u32_t* key, u32_t* micKey)
{
#ifdef ZM_ENABLE_IBSS_WPA2PSK
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
if ( hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_WPA2PSK )
{ /* If not wpa2psk , use traditional */
@@ -1918,9 +1928,10 @@ u16_t zfHpSetSnifferMode(zdev_t* dev, u16_t on)
u16_t zfHpSetApStaMode(zdev_t* dev, u8_t mode)
{
- zmw_get_wlan_dev(dev);
+ struct zsHpPriv* hpPriv;
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ zmw_get_wlan_dev(dev);
+ hpPriv = wd->hpPrivate;
hpPriv->dot11Mode = mode;
switch(mode)
@@ -1993,8 +2004,10 @@ u16_t zfHpSetBssid(zdev_t* dev, u8_t* bssidSrc)
u8_t zfHpUpdateQosParameter(zdev_t* dev, u16_t* cwminTbl, u16_t* cwmaxTbl,
u16_t* aifsTbl, u16_t* txopTbl)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
zm_msg0_mm(ZM_LV_0, "zfHalUpdateQosParameter()");
@@ -2259,9 +2272,11 @@ u32_t zfHpCwmUpdate(zdev_t* dev)
//
//ret = zfIssueCmd(dev, cmd, 12, ZM_CWM_READ, 0);
//return ret;
- zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ struct zsHpPriv* hpPriv;
+
+ zmw_get_wlan_dev(dev);
+ hpPriv=wd->hpPrivate;
zfCoreCwmBusy(dev, zfCwmIsExtChanBusy(hpPriv->ctlBusy, hpPriv->extBusy));
@@ -2291,9 +2306,10 @@ u32_t zfHpAniUpdate(zdev_t* dev)
*/
u32_t zfHpAniUpdateRssi(zdev_t* dev, u8_t rssi)
{
- zmw_get_wlan_dev(dev);
+ struct zsHpPriv* hpPriv;
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ zmw_get_wlan_dev(dev);
+ hpPriv=wd->hpPrivate;
hpPriv->stats.ast_nodestats.ns_avgbrssi = rssi;
@@ -2325,11 +2341,12 @@ u32_t zfHpGetMacAddress(zdev_t* dev)
u32_t zfHpGetTransmitPower(zdev_t* dev)
{
- zmw_get_wlan_dev(dev);
-
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ struct zsHpPriv* hpPriv;
u16_t tpc = 0;
+ zmw_get_wlan_dev(dev);
+ hpPriv = wd->hpPrivate;
+
if (hpPriv->hwFrequency < 3000) {
tpc = hpPriv->tPow2x2g[0] & 0x3f;
wd->maxTxPower2 &= 0x3f;
@@ -2345,11 +2362,12 @@ u32_t zfHpGetTransmitPower(zdev_t* dev)
u8_t zfHpGetMinTxPower(zdev_t* dev)
{
- zmw_get_wlan_dev(dev);
-
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ struct zsHpPriv* hpPriv;
u8_t tpc = 0;
+ zmw_get_wlan_dev(dev);
+ hpPriv = wd->hpPrivate;
+
if (hpPriv->hwFrequency < 3000)
{
if(wd->BandWidth40)
@@ -2382,11 +2400,12 @@ u8_t zfHpGetMinTxPower(zdev_t* dev)
u8_t zfHpGetMaxTxPower(zdev_t* dev)
{
- zmw_get_wlan_dev(dev);
-
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ struct zsHpPriv* hpPriv;
u8_t tpc = 0;
+ zmw_get_wlan_dev(dev);
+ hpPriv = wd->hpPrivate;
+
if (hpPriv->hwFrequency < 3000)
{
tpc = (hpPriv->tPow2xCck[0]&0x3f);
@@ -2421,11 +2440,13 @@ u32_t zfHpLoadEEPROMFromFW(zdev_t* dev)
void zfHpHeartBeat(zdev_t* dev)
{
- zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ struct zsHpPriv* hpPriv;
u8_t polluted = 0;
u8_t ackTpc;
+ zmw_get_wlan_dev(dev);
+ hpPriv=wd->hpPrivate;
+
/* Workaround : Make OTUS fire more beacon in ad hoc mode in 2.4GHz */
if (hpPriv->ibssBcnEnabled != 0)
{
@@ -4219,8 +4240,10 @@ void zfHpPowerSaveSetMode(zdev_t* dev, u8_t staMode, u8_t psMode, u16_t bcnInter
void zfHpPowerSaveSetState(zdev_t* dev, u8_t psState)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
//DbgPrint("INTO zfHpPowerSaveSetState");
@@ -4279,8 +4302,10 @@ void zfHpPowerSaveSetState(zdev_t* dev, u8_t psState)
void zfHpSetAggPktNum(zdev_t* dev, u32_t num)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
num = (num << 16) | (0xa);
@@ -4310,8 +4335,10 @@ void zfHpSetMPDUDensity(zdev_t* dev, u8_t density)
void zfHpSetSlotTime(zdev_t* dev, u8_t type)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
if (type == 0)
{
@@ -4376,8 +4403,10 @@ void zfHpSetRifs(zdev_t* dev, u8_t ht_enable, u8_t ht2040, u8_t g_mode)
void zfHpBeginSiteSurvey(zdev_t* dev, u8_t status)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
if ( status == 1 )
{ // Connected
@@ -4421,8 +4450,10 @@ void zfHpBeginSiteSurvey(zdev_t* dev, u8_t status)
void zfHpFinishSiteSurvey(zdev_t* dev, u8_t status)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -4527,16 +4558,20 @@ void zfHpSWEncrypt(zdev_t* dev, u8_t enable)
u32_t zfHpCapability(zdev_t* dev)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
return hpPriv->halCapability;
}
void zfHpSetRollCallTable(zdev_t* dev)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
if (hpPriv->camRollCallTable != (u64_t) 0)
{
diff --git a/drivers/staging/otus/hal/hpreg.c b/drivers/staging/otus/hal/hpreg.c
index 3cfeba8620f..d9894fe5f4e 100644
--- a/drivers/staging/otus/hal/hpreg.c
+++ b/drivers/staging/otus/hal/hpreg.c
@@ -1770,8 +1770,10 @@ void zfHpGetRegulationTable(zdev_t* dev, u16_t regionCode, u16_t c_lo, u16_t c_h
REG_DOMAIN rd5GHz, rd2GHz;
const struct cmode *cm;
s16_t next=0,b;
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -2473,9 +2475,10 @@ u8_t zfHpGetRegulatoryDomain(zdev_t* dev)
void zfHpDisableDfsChannel(zdev_t* dev, u8_t disableFlag)
{
- zmw_get_wlan_dev(dev);
+ struct zsHpPriv* hpPriv;
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ zmw_get_wlan_dev(dev);
+ hpPriv=wd->hpPrivate;
hpPriv->disableDfsCh = disableFlag;
return;
}
diff --git a/drivers/staging/otus/hal/hprw.c b/drivers/staging/otus/hal/hprw.c
index db7d4957645..d9fad47d5d5 100644
--- a/drivers/staging/otus/hal/hprw.c
+++ b/drivers/staging/otus/hal/hprw.c
@@ -29,8 +29,10 @@ u16_t zfFlushDelayWrite(zdev_t* dev);
void zfInitCmdQueue(zdev_t* dev)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = (struct zsHpPriv*)(wd->hpPrivate);
+ hpPriv = (struct zsHpPriv*)(wd->hpPrivate);
zmw_declare_for_critical_section();
@@ -48,9 +50,10 @@ void zfInitCmdQueue(zdev_t* dev)
u16_t zfPutCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen, u16_t src, u8_t* buf)
{
u16_t i;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
/* Make sure command length < ZM_MAX_CMD_SIZE */
zm_assert(cmdLen <= ZM_MAX_CMD_SIZE);
@@ -77,9 +80,10 @@ u16_t zfPutCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen, u16_t src, u8_t* buf)
u16_t zfGetCmd(zdev_t* dev, u32_t* cmd, u16_t* cmdLen, u16_t* src, u8_t** buf)
{
u16_t i;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
if (hpPriv->cmdTail == hpPriv->cmdHead)
{
@@ -106,9 +110,10 @@ void zfSendCmdEx(zdev_t* dev)
u16_t ncmdLen = 0;
u16_t cmdFlag = 0;
u16_t i;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -141,8 +146,10 @@ void zfSendCmdEx(zdev_t* dev)
void zfiSendCmdComp(zdev_t* dev)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -158,9 +165,10 @@ u16_t zfIssueCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen, u16_t src, u8_t* buf)
{
u16_t cmdFlag = 0;
u16_t ret;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -214,9 +222,10 @@ void zfIdlRsp(zdev_t* dev, u32_t* rsp, u16_t rspLen)
u16_t i;
s32_t nf;
s32_t noisefloor[4];
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -826,9 +835,10 @@ u16_t zfDelayWriteInternalReg(zdev_t* dev, u32_t addr, u32_t val)
u32_t cmd[(ZM_MAX_CMD_SIZE/4)];
u16_t i;
u16_t ret;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -892,8 +902,10 @@ u16_t zfFlushDelayWrite(zdev_t* dev)
u32_t cmd[(ZM_MAX_CMD_SIZE/4)];
u16_t i;
u16_t ret;
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
diff --git a/drivers/staging/otus/hal/hpusb.c b/drivers/staging/otus/hal/hpusb.c
index 4b76de93fff..ee939005be7 100644
--- a/drivers/staging/otus/hal/hpusb.c
+++ b/drivers/staging/otus/hal/hpusb.c
@@ -64,9 +64,10 @@ void zfAdjustCtrlSetting(zdev_t* dev, u16_t* header, zbuf_t* buf)
u32_t oldPhyCtrl;
u16_t tpc = 0;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
/* mm */
if (header == NULL)
@@ -330,8 +331,10 @@ u16_t zfHpSend(zdev_t* dev, u16_t* header, u16_t headerLen,
u16_t i;
u16_t swlpOffset;
#endif /* #if ZM_SW_LOOP_BACK == 1 */
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zm_msg1_tx(ZM_LV_1, "zfHpSend(), len = ", 12 + headerLen-8 + snapLen + zfwBufGetSize(dev, buf) + 4 + 8);
@@ -576,8 +579,10 @@ void zfiUsbRecv(zdev_t *dev, zbuf_t *buf)
u32_t rxMCS;
u32_t rxBW;
u32_t rxSG;
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
//zm_msg0_rx(ZM_LV_0, "zfiUsbRecv()");
diff --git a/drivers/staging/otus/ioctl.c b/drivers/staging/otus/ioctl.c
index 7a5c1e876b0..ce04218253d 100644
--- a/drivers/staging/otus/ioctl.c
+++ b/drivers/staging/otus/ioctl.c
@@ -25,7 +25,7 @@
/************************************************************************/
#include <linux/module.h>
#include <linux/if_arp.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include "usbdrv.h"
@@ -34,7 +34,7 @@
#define ZD_IOCTL_GETWPAIE (SIOCDEVPRIVATE + 3)
#ifdef ZM_ENABLE_CENC
#define ZM_IOCTL_CENC (SIOCDEVPRIVATE + 4)
-#endif //ZM_ENABLE_CENC
+#endif /* ZM_ENABLE_CENC */
#define ZD_PARAM_ROAMING 0x0001
#define ZD_PARAM_PRIVACY 0x0002
#define ZD_PARAM_WPA 0x0003
@@ -45,7 +45,7 @@
#ifdef ZM_ENABLE_CENC
#define P80211_PACKET_CENCFLAG 0x0001
-#endif //ZM_ENABLE_CENC
+#endif /* ZM_ENABLE_CENC */
#define P80211_PACKET_SETKEY 0x0003
#define ZD_CMD_SET_ENCRYPT_KEY 0x0001
@@ -62,204 +62,190 @@
#include <net/iw_handler.h>
#endif
-extern u16_t zfLnxGetVapId(zdev_t* dev);
+extern u16_t zfLnxGetVapId(zdev_t *dev);
static const u32_t channel_frequency_11A[] =
{
-//Even element for Channel Number, Odd for Frequency
- 36,5180,
- 40,5200,
- 44,5220,
- 48,5240,
- 52,5260,
- 56,5280,
- 60,5300,
- 64,5320,
- 100,5500,
- 104,5520,
- 108,5540,
- 112,5560,
- 116,5580,
- 120,5600,
- 124,5620,
- 128,5640,
- 132,5660,
- 136,5680,
- 140,5700,
-//
- 184,4920,
- 188,4940,
- 192,4960,
- 196,4980,
- 8,5040,
- 12,5060,
- 16,5080,
- 34,5170,
- 38,5190,
- 42,5210,
- 46,5230,
-//
- 149,5745,
- 153,5765,
- 157,5785,
- 161,5805,
- 165,5825
-//
+ /* Even element for Channel Number, Odd for Frequency */
+ 36, 5180,
+ 40, 5200,
+ 44, 5220,
+ 48, 5240,
+ 52, 5260,
+ 56, 5280,
+ 60, 5300,
+ 64, 5320,
+ 100, 5500,
+ 104, 5520,
+ 108, 5540,
+ 112, 5560,
+ 116, 5580,
+ 120, 5600,
+ 124, 5620,
+ 128, 5640,
+ 132, 5660,
+ 136, 5680,
+ 140, 5700,
+ /**/
+ 184, 4920,
+ 188, 4940,
+ 192, 4960,
+ 196, 4980,
+ 8, 5040,
+ 12, 5060,
+ 16, 5080,
+ 34, 5170,
+ 38, 5190,
+ 42, 5210,
+ 46, 5230,
+ /**/
+ 149, 5745,
+ 153, 5765,
+ 157, 5785,
+ 161, 5805,
+ 165, 5825
+ /**/
};
int usbdrv_freq2chan(u32_t freq)
{
- /* 2.4G Hz */
- if (freq > 2400 && freq < 3000)
- {
- return ((freq-2412)/5) + 1;
- }
- else
- {
- u16_t ii;
- u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);
-
- for(ii = 1; ii < num_chan; ii += 2)
- {
- if (channel_frequency_11A[ii] == freq)
- return channel_frequency_11A[ii-1];
- }
- }
-
- return 0;
+ /* 2.4G Hz */
+ if (freq > 2400 && freq < 3000) {
+ return ((freq-2412)/5) + 1;
+ } else {
+ u16_t ii;
+ u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);
+
+ for (ii = 1; ii < num_chan; ii += 2) {
+ if (channel_frequency_11A[ii] == freq)
+ return channel_frequency_11A[ii-1];
+ }
+ }
+
+ return 0;
}
int usbdrv_chan2freq(int chan)
{
- int freq;
-
- /* If channel number is out of range */
- if (chan > 165 || chan <= 0)
- return -1;
-
- /* 2.4G band */
- if (chan >= 1 && chan <= 13)
- {
- freq = (2412 + (chan - 1) * 5);
- return freq;
- }
- else if (chan >= 36 && chan <= 165)
- {
- u16_t ii;
- u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);
-
- for(ii = 0; ii < num_chan; ii += 2)
- {
- if (channel_frequency_11A[ii] == chan)
- return channel_frequency_11A[ii+1];
- }
-
- /* Can't find desired frequency */
- if (ii == num_chan)
- return -1;
- }
-
- /* Can't find deisred frequency */
- return -1;
+ int freq;
+
+ /* If channel number is out of range */
+ if (chan > 165 || chan <= 0)
+ return -1;
+
+ /* 2.4G band */
+ if (chan >= 1 && chan <= 13) {
+ freq = (2412 + (chan - 1) * 5);
+ return freq;
+ } else if (chan >= 36 && chan <= 165) {
+ u16_t ii;
+ u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);
+
+ for (ii = 0; ii < num_chan; ii += 2) {
+ if (channel_frequency_11A[ii] == chan)
+ return channel_frequency_11A[ii+1];
+ }
+
+ /* Can't find desired frequency */
+ if (ii == num_chan)
+ return -1;
+ }
+
+ /* Can't find deisred frequency */
+ return -1;
}
int usbdrv_ioctl_setessid(struct net_device *dev, struct iw_point *erq)
{
-#ifdef ZM_HOSTAPD_SUPPORT
- //struct usbdrv_private *macp = dev->ml_priv;
- char essidbuf[IW_ESSID_MAX_SIZE+1];
- int i;
+ #ifdef ZM_HOSTAPD_SUPPORT
+ /* struct usbdrv_private *macp = dev->ml_priv; */
+ char essidbuf[IW_ESSID_MAX_SIZE+1];
+ int i;
- if(!netif_running(dev))
- return -EINVAL;
+ if (!netif_running(dev))
+ return -EINVAL;
- memset(essidbuf, 0, sizeof(essidbuf));
+ memset(essidbuf, 0, sizeof(essidbuf));
- printk(KERN_ERR "usbdrv_ioctl_setessid\n");
+ printk(KERN_ERR "usbdrv_ioctl_setessid\n");
- //printk("ssidlen=%d\n", erq->length); //for any, it is 1.
- if (erq->flags) {
- if (erq->length > (IW_ESSID_MAX_SIZE+1))
- return -E2BIG;
+ /* printk("ssidlen=%d\n", erq->length); //for any, it is 1. */
+ if (erq->flags) {
+ if (erq->length > (IW_ESSID_MAX_SIZE+1))
+ return -E2BIG;
- if (copy_from_user(essidbuf, erq->pointer, erq->length))
- return -EFAULT;
- }
+ if (copy_from_user(essidbuf, erq->pointer, erq->length))
+ return -EFAULT;
+ }
- //zd_DisasocAll(2);
- //wait_ms(100);
+ /* zd_DisasocAll(2); */
+ /* wait_ms(100); */
- printk(KERN_ERR "essidbuf: ");
+ printk(KERN_ERR "essidbuf: ");
- for(i = 0; i < erq->length; i++)
- {
- printk(KERN_ERR "%02x ", essidbuf[i]);
- }
+ for (i = 0; i < erq->length; i++)
+ printk(KERN_ERR "%02x ", essidbuf[i]);
- printk(KERN_ERR "\n");
+ printk(KERN_ERR "\n");
- essidbuf[erq->length] = '\0';
- //memcpy(macp->wd.ws.ssid, essidbuf, erq->length);
- //macp->wd.ws.ssidLen = strlen(essidbuf)+2;
- //macp->wd.ws.ssid[1] = strlen(essidbuf); // Update ssid length
+ essidbuf[erq->length] = '\0';
+ /* memcpy(macp->wd.ws.ssid, essidbuf, erq->length); */
+ /* macp->wd.ws.ssidLen = strlen(essidbuf)+2; */
+ /* macp->wd.ws.ssid[1] = strlen(essidbuf); Update ssid length */
- zfiWlanSetSSID(dev, essidbuf, erq->length);
-#if 0
- printk(KERN_ERR "macp->wd.ws.ssid: ");
+ zfiWlanSetSSID(dev, essidbuf, erq->length);
+ #if 0
+ printk(KERN_ERR "macp->wd.ws.ssid: ");
- for(i = 0; i < macp->wd.ws.ssidLen; i++)
- {
- printk(KERN_ERR "%02x ", macp->wd.ws.ssid[i]);
- }
+ for (i = 0; i < macp->wd.ws.ssidLen; i++)
+ printk(KERN_ERR "%02x ", macp->wd.ws.ssid[i]);
- printk(KERN_ERR "\n");
-#endif
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
+ printk(KERN_ERR "\n");
+ #endif
-#endif
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
- return 0;
+ #endif
+
+ return 0;
}
int usbdrv_ioctl_getessid(struct net_device *dev, struct iw_point *erq)
{
- //struct usbdrv_private *macp = dev->ml_priv;
- u8_t essidbuf[IW_ESSID_MAX_SIZE+1];
- u8_t len;
- u8_t i;
+ /* struct usbdrv_private *macp = dev->ml_priv; */
+ u8_t essidbuf[IW_ESSID_MAX_SIZE+1];
+ u8_t len;
+ u8_t i;
- //len = macp->wd.ws.ssidLen;
- //memcpy(essidbuf, macp->wd.ws.ssid, macp->wd.ws.ssidLen);
- zfiWlanQuerySSID(dev, essidbuf, &len);
+ /* len = macp->wd.ws.ssidLen; */
+ /* memcpy(essidbuf, macp->wd.ws.ssid, macp->wd.ws.ssidLen); */
+ zfiWlanQuerySSID(dev, essidbuf, &len);
- essidbuf[len] = 0;
+ essidbuf[len] = 0;
- printk(KERN_ERR "ESSID: ");
+ printk(KERN_ERR "ESSID: ");
- for(i = 0; i < len; i++)
- {
- printk(KERN_ERR "%c", essidbuf[i]);
- }
+ for (i = 0; i < len; i++)
+ printk(KERN_ERR "%c", essidbuf[i]);
- printk(KERN_ERR "\n");
+ printk(KERN_ERR "\n");
- erq->flags= 1;
- erq->length = strlen(essidbuf) + 1;
+ erq->flags = 1;
+ erq->length = strlen(essidbuf) + 1;
- if (erq->pointer)
- if (copy_to_user(erq->pointer, essidbuf, erq->length))
- return -EFAULT;
+ if (erq->pointer) {
+ if (copy_to_user(erq->pointer, essidbuf, erq->length))
+ return -EFAULT;
+ }
- return 0;
+ return 0;
}
-
int usbdrv_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
{
-
- return 0;
+ return 0;
}
#if WIRELESS_EXT > 14
@@ -267,462 +253,418 @@ int usbdrv_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
* Encode a WPA or RSN information element as a custom
* element using the hostap format.
*/
-u32 encode_ie(void *buf, u32 bufsize, const u8 *ie, u32 ielen, const u8 *leader, u32 leader_len)
+u32 encode_ie(void *buf, u32 bufsize, const u8 *ie, u32 ielen,
+ const u8 *leader, u32 leader_len)
{
- u8 *p;
- u32 i;
-
- if (bufsize < leader_len)
- return 0;
- p = buf;
- memcpy(p, leader, leader_len);
- bufsize -= leader_len;
- p += leader_len;
- for (i = 0; i < ielen && bufsize > 2; i++)
- p += sprintf(p, "%02x", ie[i]);
- return (i == ielen ? p - (u8 *)buf : 0);
+ u8 *p;
+ u32 i;
+
+ if (bufsize < leader_len)
+ return 0;
+ p = buf;
+ memcpy(p, leader, leader_len);
+ bufsize -= leader_len;
+ p += leader_len;
+ for (i = 0; i < ielen && bufsize > 2; i++)
+ p += sprintf(p, "%02x", ie[i]);
+ return (i == ielen ? p - (u8 *)buf:0);
}
-#endif /* WIRELESS_EXT > 14 */
+#endif /* WIRELESS_EXT > 14 */
-/*------------------------------------------------------------------*/
/*
* Translate scan data returned from the card to a card independent
* format that the Wireless Tools will understand
*/
char *usbdrv_translate_scan(struct net_device *dev,
struct iw_request_info *info, char *current_ev,
- char *end_buf, struct zsBssInfo *list)
+ char *end_buf, struct zsBssInfo *list)
{
- struct iw_event iwe; /* Temporary buffer */
- u16_t capabilities;
- char *current_val; /* For rates */
- char *last_ev;
- int i;
-#if WIRELESS_EXT > 14
- char buf[64*2 + 30];
-#endif
+ struct iw_event iwe; /* Temporary buffer */
+ u16_t capabilities;
+ char *current_val; /* For rates */
+ char *last_ev;
+ int i;
+ #if WIRELESS_EXT > 14
+ char buf[64*2 + 30];
+ #endif
+
+ last_ev = current_ev;
+
+ /* First entry *MUST* be the AP MAC address */
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe, IW_EV_ADDR_LEN);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ /* Other entries will be displayed in the order we give them */
+
+ /* Add the ESSID */
+ iwe.u.data.length = list->ssid[1];
+ if (iwe.u.data.length > 32)
+ iwe.u.data.length = 32;
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.flags = 1;
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, &list->ssid[2]);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ /* Add mode */
+ iwe.cmd = SIOCGIWMODE;
+ capabilities = (list->capability[1] << 8) + list->capability[0];
+ if (capabilities & (0x01 | 0x02)) {
+ if (capabilities & 0x01)
+ iwe.u.mode = IW_MODE_MASTER;
+ else
+ iwe.u.mode = IW_MODE_ADHOC;
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe, IW_EV_UINT_LEN);
+ }
- last_ev = current_ev;
-
-/* First entry *MUST* be the AP MAC address */
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(
- info,
- current_ev,
- end_buf, &iwe, IW_EV_ADDR_LEN);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
-/* Other entries will be displayed in the order we give them */
-
-/* Add the ESSID */
- iwe.u.data.length = list->ssid[1];
- if(iwe.u.data.length > 32)
- iwe.u.data.length = 32;
- iwe.cmd = SIOCGIWESSID;
- iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(
- info,
- current_ev, end_buf, &iwe, &list->ssid[2]);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
-/* Add mode */
- iwe.cmd = SIOCGIWMODE;
- capabilities = (list->capability[1] << 8) + list->capability[0];
- if(capabilities & (0x01 | 0x02))
- {
- if(capabilities & 0x01)
- iwe.u.mode = IW_MODE_MASTER;
- else
- iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(
- info,
- current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
- }
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
-/* Add frequency */
- iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = list->channel;
-/* Channel frequency in KHz */
- if (iwe.u.freq.m > 14)
- {
- if ((184 <= iwe.u.freq.m) && (iwe.u.freq.m<=196))
- iwe.u.freq.m = 4000 + iwe.u.freq.m * 5;
- else
- iwe.u.freq.m = 5000 + iwe.u.freq.m * 5;
- }
- else
- {
- if (iwe.u.freq.m == 14)
- iwe.u.freq.m = 2484;
- else
- iwe.u.freq.m = 2412 + (iwe.u.freq.m - 1) * 5;
- }
- iwe.u.freq.e = 6;
- current_ev = iwe_stream_add_event(
- info,
- current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
-/* Add quality statistics */
- iwe.cmd = IWEVQUAL;
-#if WIRELESS_EXT > 18
- iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
- |IW_QUAL_NOISE_UPDATED;
-#endif
- iwe.u.qual.level = list->signalStrength;
- iwe.u.qual.noise = 0;
- iwe.u.qual.qual = list->signalQuality;
- current_ev = iwe_stream_add_event(
- info,
- current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
-/* Add encryption capability */
-
- iwe.cmd = SIOCGIWENCODE;
- if(capabilities & 0x10)
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- else
- iwe.u.data.flags = IW_ENCODE_DISABLED;
-
- iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(
- info,
- current_ev, end_buf, &iwe, list->ssid);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
-/* Rate : stuffing multiple values in a single event require a bit
- * more of magic */
- current_val = current_ev + IW_EV_LCP_LEN;
-
- iwe.cmd = SIOCGIWRATE;
-/* Those two flags are ignored... */
- iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-
- for(i = 0 ; i < list->supportedRates[1] ; i++)
- {
-/* Bit rate given in 500 kb/s units (+ 0x80) */
- iwe.u.bitrate.value = ((list->supportedRates[i+2] & 0x7f) * 500000);
-/* Add new value to event */
- current_val = iwe_stream_add_value(
- info,
- current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
-
- /* Ran out of buffer */
- if (last_ev == current_val)
- {
- return end_buf;
- }
-
- last_ev = current_val;
- }
-
- for (i = 0 ; i < list->extSupportedRates[1] ; i++)
- {
-/* Bit rate given in 500 kb/s units (+ 0x80) */
- iwe.u.bitrate.value = ((list->extSupportedRates[i+2] & 0x7f) * 500000);
-/* Add new value to event */
- current_val = iwe_stream_add_value(
- info,
- current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
-
- /* Ran out of buffer */
- if (last_ev == current_val)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
- }
-
-/* Check if we added any event */
- if((current_val - current_ev) > IW_EV_LCP_LEN)
- current_ev = current_val;
-#if WIRELESS_EXT > 14
-#define IEEE80211_ELEMID_RSN 0x30
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVCUSTOM;
- snprintf(buf, sizeof(buf), "bcn_int=%d", (list->beaconInterval[1] << 8) + list->beaconInterval[0]);
- iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(
- info,
- current_ev, end_buf, &iwe, buf);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
- if (list->wpaIe[1] != 0)
- {
- static const char rsn_leader[] = "rsn_ie=";
- static const char wpa_leader[] = "wpa_ie=";
-
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVCUSTOM;
- if (list->wpaIe[0] == IEEE80211_ELEMID_RSN)
- iwe.u.data.length = encode_ie(buf, sizeof(buf),
- list->wpaIe, list->wpaIe[1]+2,
- rsn_leader, sizeof(rsn_leader)-1);
- else
- iwe.u.data.length = encode_ie(buf, sizeof(buf),
- list->wpaIe, list->wpaIe[1]+2,
- wpa_leader, sizeof(wpa_leader)-1);
-
- if (iwe.u.data.length != 0)
- current_ev = iwe_stream_add_point(
- info,
- current_ev, end_buf, &iwe, buf);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
- }
- if (list->rsnIe[1] != 0)
- {
- static const char rsn_leader[] = "rsn_ie=";
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVCUSTOM;
-
- if (list->rsnIe[0] == IEEE80211_ELEMID_RSN)
- {
- iwe.u.data.length = encode_ie(buf, sizeof(buf),
- list->rsnIe, list->rsnIe[1]+2,
- rsn_leader, sizeof(rsn_leader)-1);
- if (iwe.u.data.length != 0)
- current_ev = iwe_stream_add_point(
- info,
- current_ev, end_buf, &iwe, buf);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
- }
- }
-#endif
-/* The other data in the scan result are not really
- * interesting, so for now drop it */
- return current_ev;
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ /* Add frequency */
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.m = list->channel;
+ /* Channel frequency in KHz */
+ if (iwe.u.freq.m > 14) {
+ if ((184 <= iwe.u.freq.m) && (iwe.u.freq.m <= 196))
+ iwe.u.freq.m = 4000 + iwe.u.freq.m * 5;
+ else
+ iwe.u.freq.m = 5000 + iwe.u.freq.m * 5;
+ } else {
+ if (iwe.u.freq.m == 14)
+ iwe.u.freq.m = 2484;
+ else
+ iwe.u.freq.m = 2412 + (iwe.u.freq.m - 1) * 5;
+ }
+ iwe.u.freq.e = 6;
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe, IW_EV_FREQ_LEN);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ /* Add quality statistics */
+ iwe.cmd = IWEVQUAL;
+ #if WIRELESS_EXT > 18
+ iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_NOISE_UPDATED;
+ #endif
+ iwe.u.qual.level = list->signalStrength;
+ iwe.u.qual.noise = 0;
+ iwe.u.qual.qual = list->signalQuality;
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe, IW_EV_QUAL_LEN);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ /* Add encryption capability */
+
+ iwe.cmd = SIOCGIWENCODE;
+ if (capabilities & 0x10)
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+
+ iwe.u.data.length = 0;
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, list->ssid);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ /* Rate : stuffing multiple values in a single event require a bit
+ * more of magic
+ */
+ current_val = current_ev + IW_EV_LCP_LEN;
+
+ iwe.cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+
+ for (i = 0 ; i < list->supportedRates[1] ; i++) {
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe.u.bitrate.value = ((list->supportedRates[i+2] & 0x7f)
+ * 500000);
+ /* Add new value to event */
+ current_val = iwe_stream_add_value(info, current_ev,
+ current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+
+ /* Ran out of buffer */
+ if (last_ev == current_val)
+ return end_buf;
+
+ last_ev = current_val;
+ }
+
+ for (i = 0 ; i < list->extSupportedRates[1] ; i++) {
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe.u.bitrate.value = ((list->extSupportedRates[i+2] & 0x7f)
+ * 500000);
+ /* Add new value to event */
+ current_val = iwe_stream_add_value(info, current_ev,
+ current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+
+ /* Ran out of buffer */
+ if (last_ev == current_val)
+ return end_buf;
+
+ last_ev = current_ev;
+ }
+
+ /* Check if we added any event */
+ if ((current_val - current_ev) > IW_EV_LCP_LEN)
+ current_ev = current_val;
+ #if WIRELESS_EXT > 14
+ #define IEEE80211_ELEMID_RSN 0x30
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+ snprintf(buf, sizeof(buf), "bcn_int=%d", (list->beaconInterval[1] << 8)
+ + list->beaconInterval[0]);
+ iwe.u.data.length = strlen(buf);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ if (list->wpaIe[1] != 0) {
+ static const char rsn_leader[] = "rsn_ie=";
+ static const char wpa_leader[] = "wpa_ie=";
+
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+ if (list->wpaIe[0] == IEEE80211_ELEMID_RSN)
+ iwe.u.data.length = encode_ie(buf, sizeof(buf),
+ list->wpaIe, list->wpaIe[1]+2,
+ rsn_leader, sizeof(rsn_leader)-1);
+ else
+ iwe.u.data.length = encode_ie(buf, sizeof(buf),
+ list->wpaIe, list->wpaIe[1]+2,
+ wpa_leader, sizeof(wpa_leader)-1);
+
+ if (iwe.u.data.length != 0)
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+ }
+
+ if (list->rsnIe[1] != 0) {
+ static const char rsn_leader[] = "rsn_ie=";
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+
+ if (list->rsnIe[0] == IEEE80211_ELEMID_RSN) {
+ iwe.u.data.length = encode_ie(buf, sizeof(buf),
+ list->rsnIe, list->rsnIe[1]+2,
+ rsn_leader, sizeof(rsn_leader)-1);
+ if (iwe.u.data.length != 0)
+ current_ev = iwe_stream_add_point(info,
+ current_ev, end_buf, &iwe, buf);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+ }
+ }
+ #endif
+ /* The other data in the scan result are not really
+ * interesting, so for now drop it
+ */
+ return current_ev;
}
int usbdrvwext_giwname(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrq, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrq, char *extra)
{
- //struct usbdrv_private *macp = dev->ml_priv;
+ /* struct usbdrv_private *macp = dev->ml_priv; */
- strcpy(wrq->name, "IEEE 802.11-MIMO");
+ strcpy(wrq->name, "IEEE 802.11-MIMO");
- return 0;
+ return 0;
}
int usbdrvwext_siwfreq(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_freq *freq, char *extra)
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
{
- u32_t FreqKHz;
- struct usbdrv_private *macp = dev->ml_priv;
-
- if(!netif_running(dev))
- return -EINVAL;
-
- if (freq->e > 1)
- return -EINVAL;
-
- if (freq->e == 1)
- {
- FreqKHz = (freq->m / 100000);
-
- if (FreqKHz > 4000000)
- {
- if (FreqKHz > 5825000)
- FreqKHz = 5825000;
- else if (FreqKHz < 4920000)
- FreqKHz = 4920000;
- else if (FreqKHz < 5000000)
- FreqKHz = (((FreqKHz - 4000000) / 5000) * 5000) + 4000000;
- else
- FreqKHz = (((FreqKHz - 5000000) / 5000) * 5000) + 5000000;
- }
- else
- {
- if (FreqKHz > 2484000)
- FreqKHz = 2484000;
- else if (FreqKHz < 2412000)
- FreqKHz = 2412000;
- else
- FreqKHz = (((FreqKHz - 2412000) / 5000) * 5000) + 2412000;
- }
-
- }
- else
- {
- FreqKHz = usbdrv_chan2freq(freq->m);
-
- if (FreqKHz != -1)
- FreqKHz *= 1000;
- else
- FreqKHz = 2412000;
- }
-
- //printk("freq->m: %d, freq->e: %d\n", freq->m, freq->e);
- //printk("FreqKHz: %d\n", FreqKHz);
-
- if (macp->DeviceOpened == 1)
- {
- zfiWlanSetFrequency(dev, FreqKHz, 0); // Immediate
- //u8_t wpaieLen,wpaie[50];
- //zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen);
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
- //if (wpaieLen > 2)
- // zfiWlanSetWpaIe(dev, wpaie, wpaieLen);
- }
-
- return 0;
+ u32_t FreqKHz;
+ struct usbdrv_private *macp = dev->ml_priv;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (freq->e > 1)
+ return -EINVAL;
+
+ if (freq->e == 1) {
+ FreqKHz = (freq->m / 100000);
+
+ if (FreqKHz > 4000000) {
+ if (FreqKHz > 5825000)
+ FreqKHz = 5825000;
+ else if (FreqKHz < 4920000)
+ FreqKHz = 4920000;
+ else if (FreqKHz < 5000000)
+ FreqKHz = (((FreqKHz - 4000000) / 5000) * 5000)
+ + 4000000;
+ else
+ FreqKHz = (((FreqKHz - 5000000) / 5000) * 5000)
+ + 5000000;
+ } else {
+ if (FreqKHz > 2484000)
+ FreqKHz = 2484000;
+ else if (FreqKHz < 2412000)
+ FreqKHz = 2412000;
+ else
+ FreqKHz = (((FreqKHz - 2412000) / 5000) * 5000)
+ + 2412000;
+ }
+ } else {
+ FreqKHz = usbdrv_chan2freq(freq->m);
+
+ if (FreqKHz != -1)
+ FreqKHz *= 1000;
+ else
+ FreqKHz = 2412000;
+ }
+
+ /* printk("freq->m: %d, freq->e: %d\n", freq->m, freq->e); */
+ /* printk("FreqKHz: %d\n", FreqKHz); */
+
+ if (macp->DeviceOpened == 1) {
+ zfiWlanSetFrequency(dev, FreqKHz, 0); /* Immediate */
+ /* u8_t wpaieLen,wpaie[50]; */
+ /* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
+ /* if (wpaieLen > 2) */
+ /* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
+ }
+
+ return 0;
}
int usbdrvwext_giwfreq(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_freq *freq, char *extra)
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
+ struct usbdrv_private *macp = dev->ml_priv;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- freq->m = zfiWlanQueryFrequency(dev);
- freq->e = 3;
+ freq->m = zfiWlanQueryFrequency(dev);
+ freq->e = 3;
- return 0;
+ return 0;
}
int usbdrvwext_siwmode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrq, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrq, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u8_t WlanMode;
-
- if(!netif_running(dev))
- return -EINVAL;
-
- if (macp->DeviceOpened != 1)
- return 0;
-
- switch(wrq->mode)
- {
- case IW_MODE_MASTER:
- WlanMode = ZM_MODE_AP;
- break;
- case IW_MODE_INFRA:
- WlanMode = ZM_MODE_INFRASTRUCTURE;
- break;
- case IW_MODE_ADHOC:
- WlanMode = ZM_MODE_IBSS;
- break;
- default:
- WlanMode = ZM_MODE_IBSS;
- break;
- }
-
- zfiWlanSetWlanMode(dev,WlanMode);
- zfiWlanDisable(dev, 1);
- zfiWlanEnable(dev);
-
- return 0;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u8_t WlanMode;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (macp->DeviceOpened != 1)
+ return 0;
+
+ switch (wrq->mode) {
+ case IW_MODE_MASTER:
+ WlanMode = ZM_MODE_AP;
+ break;
+ case IW_MODE_INFRA:
+ WlanMode = ZM_MODE_INFRASTRUCTURE;
+ break;
+ case IW_MODE_ADHOC:
+ WlanMode = ZM_MODE_IBSS;
+ break;
+ default:
+ WlanMode = ZM_MODE_IBSS;
+ break;
+ }
+
+ zfiWlanSetWlanMode(dev, WlanMode);
+ zfiWlanDisable(dev, 1);
+ zfiWlanEnable(dev);
+
+ return 0;
}
int usbdrvwext_giwmode(struct net_device *dev,
- struct iw_request_info *info,
- __u32 *mode, char *extra)
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
{
- unsigned long irqFlag;
- struct usbdrv_private *macp = dev->ml_priv;
-
- if(!netif_running(dev))
- return -EINVAL;
-
- if (macp->DeviceOpened != 1)
- return 0;
-
- spin_lock_irqsave(&macp->cs_lock, irqFlag);
-
- switch(zfiWlanQueryWlanMode(dev))
- {
- case ZM_MODE_AP:
- *mode = IW_MODE_MASTER;
- break;
- case ZM_MODE_INFRASTRUCTURE:
- *mode = IW_MODE_INFRA;
- break;
- case ZM_MODE_IBSS:
- *mode = IW_MODE_ADHOC;
- break;
- default:
- *mode = IW_MODE_ADHOC;
- break;
- }
-
- spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
-
- return 0;
+ unsigned long irqFlag;
+ struct usbdrv_private *macp = dev->ml_priv;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (macp->DeviceOpened != 1)
+ return 0;
+
+ spin_lock_irqsave(&macp->cs_lock, irqFlag);
+
+ switch (zfiWlanQueryWlanMode(dev)) {
+ case ZM_MODE_AP:
+ *mode = IW_MODE_MASTER;
+ break;
+ case ZM_MODE_INFRASTRUCTURE:
+ *mode = IW_MODE_INFRA;
+ break;
+ case ZM_MODE_IBSS:
+ *mode = IW_MODE_ADHOC;
+ break;
+ default:
+ *mode = IW_MODE_ADHOC;
+ break;
+ }
+
+ spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+
+ return 0;
}
int usbdrvwext_siwsens(struct net_device *dev,
@@ -743,338 +685,341 @@ int usbdrvwext_giwsens(struct net_device *dev,
}
int usbdrvwext_giwrange(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
- struct iw_range *range = (struct iw_range *) extra;
- int i, val;
- //int num_band_a;
- u16_t channels[60];
- u16_t channel_num;
-
- if(!netif_running(dev))
- return -EINVAL;
-
-#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 */
-
- channel_num = zfiWlanQueryAllowChannels(dev, channels);
-
- /* Gurantee reported channel numbers is less or equal to IW_MAX_FREQUENCIES */
- if (channel_num > IW_MAX_FREQUENCIES)
- channel_num = IW_MAX_FREQUENCIES;
-
- val = 0;
-
- for (i = 0; i < channel_num; i++)
- {
- range->freq[val].i = usbdrv_freq2chan(channels[i]);
- range->freq[val].m = channels[i];
- range->freq[val].e = 6;
- val++;
- }
-
- range->num_channels = channel_num;
- range->num_frequency = channel_num;
-
-#if 0
- range->num_channels = 14; // Only 2.4G
-
-/* XXX need to filter against the regulatory domain &| active set */
- val = 0;
- for (i = 1; i <= 14; i++) // B,G Bands
- {
- range->freq[val].i = i;
- if (i == 14)
- range->freq[val].m = 2484000;
- else
- range->freq[val].m = (2412+(i-1)*5)*1000;
- range->freq[val].e = 3;
- val++;
- }
-
- num_band_a = (IW_MAX_FREQUENCIES - val);
-
- for (i = 0; i < num_band_a; i++) // A Bands
- {
- range->freq[val].i = channel_frequency_11A[2 * i];
- range->freq[val].m = channel_frequency_11A[2 * i + 1] * 1000;
- range->freq[val].e = 3;
- val++;
- }
- // MIMO Rate Not Defined Now
- //For 802.11a, there are too more frequency. We can't return them all
- range->num_frequency = val;
-#endif
-
-/* Max of /proc/net/wireless */
- range->max_qual.qual = 100; //?? //92;
- range->max_qual.level = 154; //??
- range->max_qual.noise = 154; //??
- 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 = 4/*NUM_WEPKEYS*/; //??
- range->num_encoding_sizes = 2; //??
+ struct iw_range *range = (struct iw_range *) extra;
+ int i, val;
+ /* int num_band_a; */
+ u16_t channels[60];
+ u16_t channel_num;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ #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 */
+
+ channel_num = zfiWlanQueryAllowChannels(dev, channels);
+
+ /* Gurantee reported channel numbers is less
+ * or equal to IW_MAX_FREQUENCIES
+ */
+ if (channel_num > IW_MAX_FREQUENCIES)
+ channel_num = IW_MAX_FREQUENCIES;
+
+ val = 0;
+
+ for (i = 0; i < channel_num; i++) {
+ range->freq[val].i = usbdrv_freq2chan(channels[i]);
+ range->freq[val].m = channels[i];
+ range->freq[val].e = 6;
+ val++;
+ }
- range->encoding_size[0] = 5; //?? //WEP Key Encoding Size
- range->encoding_size[1] = 13;//??
+ range->num_channels = channel_num;
+ range->num_frequency = channel_num;
-// XXX what about num_bitrates/throughput?
- range->num_bitrates = 0; //??
+ #if 0
+ range->num_channels = 14; /* Only 2.4G */
-/* estimated max throughput */
-// XXX need to cap it if we're running at ~2Mbps..
+ /* XXX need to filter against the regulatory domain &| active set */
+ val = 0;
+ /* B,G Bands */
+ for (i = 1; i <= 14; i++) {
+ range->freq[val].i = i;
+ if (i == 14)
+ range->freq[val].m = 2484000;
+ else
+ range->freq[val].m = (2412+(i-1)*5)*1000;
+ range->freq[val].e = 3;
+ val++;
+ }
- range->throughput = 300000000;
+ num_band_a = (IW_MAX_FREQUENCIES - val);
+ /* A Bands */
+ for (i = 0; i < num_band_a; i++) {
+ range->freq[val].i = channel_frequency_11A[2 * i];
+ range->freq[val].m = channel_frequency_11A[2 * i + 1] * 1000;
+ range->freq[val].e = 3;
+ val++;
+ }
+ /* MIMO Rate Not Defined Now
+ * For 802.11a, there are too more frequency.
+ * We can't return them all.
+ */
+ range->num_frequency = val;
+ #endif
+
+ /* Max of /proc/net/wireless */
+ range->max_qual.qual = 100; /* ?? 92; */
+ range->max_qual.level = 154; /* ?? */
+ range->max_qual.noise = 154; /* ?? */
+ 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 = 4 /* NUM_WEPKEYS ?? */;
+ range->num_encoding_sizes = 2; /* ?? */
+
+ range->encoding_size[0] = 5; /* ?? WEP Key Encoding Size */
+ 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 = 300000000;
- return 0;
+ return 0;
}
int usbdrvwext_siwap(struct net_device *dev, struct iw_request_info *info,
- struct sockaddr *MacAddr, char *extra)
+ struct sockaddr *MacAddr, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
-
- if(!netif_running(dev))
- return -EINVAL;
-
- if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) // AP Mode
- zfiWlanSetMacAddress(dev,(u16_t *)&MacAddr->sa_data[0]);
- else //STA Mode
- zfiWlanSetBssid(dev,&MacAddr->sa_data[0]);
-
- if (macp->DeviceOpened == 1)
- {
- //u8_t wpaieLen,wpaie[80];
- //zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen);
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
- //if (wpaieLen > 2)
- // zfiWlanSetWpaIe(dev, wpaie, wpaieLen);
- }
-
- return 0;
+ struct usbdrv_private *macp = dev->ml_priv;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
+ /* AP Mode */
+ zfiWlanSetMacAddress(dev, (u16_t *)&MacAddr->sa_data[0]);
+ } else {
+ /* STA Mode */
+ zfiWlanSetBssid(dev, &MacAddr->sa_data[0]);
+ }
+
+ if (macp->DeviceOpened == 1) {
+ /* u8_t wpaieLen,wpaie[80]; */
+ /* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
+ /* if (wpaieLen > 2) */
+ /* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
+ }
+
+ return 0;
}
int usbdrvwext_giwap(struct net_device *dev,
- struct iw_request_info *info,
- struct sockaddr *MacAddr, char *extra)
+ struct iw_request_info *info,
+ struct sockaddr *MacAddr, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
-
- if (macp->DeviceOpened != 1)
- return 0;
-
- if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) // AP Mode
- zfiWlanQueryMacAddress(dev, &MacAddr->sa_data[0]);
- else //STA Mode
- {
- if (macp->adapterState == ZM_STATUS_MEDIA_CONNECT)
- {
- zfiWlanQueryBssid(dev, &MacAddr->sa_data[0]);
- }
- else
- {
- u8_t zero_addr[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- memcpy(&MacAddr->sa_data[0], zero_addr, sizeof(zero_addr));
- }
- }
-
- return 0;
+ struct usbdrv_private *macp = dev->ml_priv;
+
+ if (macp->DeviceOpened != 1)
+ return 0;
+
+ if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
+ /* AP Mode */
+ zfiWlanQueryMacAddress(dev, &MacAddr->sa_data[0]);
+ } else {
+ /* STA Mode */
+ if (macp->adapterState == ZM_STATUS_MEDIA_CONNECT) {
+ zfiWlanQueryBssid(dev, &MacAddr->sa_data[0]);
+ } else {
+ u8_t zero_addr[6] = { 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00 };
+ memcpy(&MacAddr->sa_data[0], zero_addr,
+ sizeof(zero_addr));
+ }
+ }
+
+ return 0;
}
int usbdrvwext_iwaplist(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *extra)
{
- //Don't know how to do yet--CWYang(+)
- return 0;
+ /* Don't know how to do yet--CWYang(+) */
+ return 0;
}
int usbdrvwext_siwscan(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *data, char *extra)
+ struct iw_point *data, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
+ struct usbdrv_private *macp = dev->ml_priv;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- printk("CWY - usbdrvwext_siwscan\n");
+ printk(KERN_WARNING "CWY - usbdrvwext_siwscan\n");
- zfiWlanScan(dev);
+ zfiWlanScan(dev);
- return 0;
+ return 0;
}
int usbdrvwext_giwscan(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
- char *current_ev = extra;
- char *end_buf;
- int i;
- //struct zsBssList BssList;
- struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1), GFP_KERNEL);
- //BssList = wd->sta.pBssList;
- //zmw_get_wlan_dev(dev);
-
- if (macp->DeviceOpened != 1)
- return 0;
-
- if (data->length == 0)
- {
- end_buf = extra + IW_SCAN_MAX_DATA;
- }
- else
- {
- end_buf = extra + data->length;
- }
-
- printk("giwscan - Report Scan Results\n");
- //printk("giwscan - BssList Sreucture Len : %d\n", sizeof(BssList));
- //printk("giwscan - BssList Count : %d\n", wd->sta.pBssList->bssCount);
- //printk("giwscan - UpdateBssList Count : %d\n", wd->sta.pUpdateBssList->bssCount);
- zfiWlanQueryBssListV1(dev, pBssList);
- //zfiWlanQueryBssList(dev, &BssList);
-
-/* Read and parse all entries */
- printk("giwscan - pBssList->bssCount : %d\n", pBssList->bssCount);
- //printk("giwscan - BssList.bssCount : %d\n", BssList.bssCount);
-
- for (i = 0; i < pBssList->bssCount; i++)
- {
-/* Translate to WE format this entry */
- //current_ev = usbdrv_translate_scan(dev, info, current_ev,
- // extra + IW_SCAN_MAX_DATA, &pBssList->bssInfo[i]);
- current_ev = usbdrv_translate_scan(dev, info, current_ev,
- end_buf, &pBssList->bssInfo[i]);
-
-#if WIRELESS_EXT > 16
- if (current_ev == end_buf)
- {
- kfree(pBssList);
- data->length = current_ev - extra;
- return -E2BIG;
- }
-#endif
- }
+ struct usbdrv_private *macp = dev->ml_priv;
+ /* struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); */
+ char *current_ev = extra;
+ char *end_buf;
+ int i;
+ /* struct zsBssList BssList; */
+ struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1),
+ GFP_KERNEL);
+ /* BssList = wd->sta.pBssList; */
+ /* zmw_get_wlan_dev(dev); */
+
+ if (macp->DeviceOpened != 1)
+ return 0;
+
+ if (data->length == 0)
+ end_buf = extra + IW_SCAN_MAX_DATA;
+ else
+ end_buf = extra + data->length;
+
+ printk(KERN_WARNING "giwscan - Report Scan Results\n");
+ /* printk("giwscan - BssList Sreucture Len : %d\n", sizeof(BssList));
+ * printk("giwscan - BssList Count : %d\n",
+ * wd->sta.pBssList->bssCount);
+ * printk("giwscan - UpdateBssList Count : %d\n",
+ * wd->sta.pUpdateBssList->bssCount);
+ */
+ zfiWlanQueryBssListV1(dev, pBssList);
+ /* zfiWlanQueryBssList(dev, &BssList); */
+
+ /* Read and parse all entries */
+ printk(KERN_WARNING "giwscan - pBssList->bssCount : %d\n",
+ pBssList->bssCount);
+ /* printk("giwscan - BssList.bssCount : %d\n", BssList.bssCount); */
+
+ for (i = 0; i < pBssList->bssCount; i++) {
+ /* Translate to WE format this entry
+ * current_ev = usbdrv_translate_scan(dev, info, current_ev,
+ * extra + IW_SCAN_MAX_DATA, &pBssList->bssInfo[i]);
+ */
+ current_ev = usbdrv_translate_scan(dev, info, current_ev,
+ end_buf, &pBssList->bssInfo[i]);
+
+ #if WIRELESS_EXT > 16
+ if (current_ev == end_buf) {
+ kfree(pBssList);
+ data->length = current_ev - extra;
+ return -E2BIG;
+ }
+ #endif
+ }
-/* Length of data */
- data->length = (current_ev - extra);
- data->flags = 0; /* todo */
+ /* Length of data */
+ data->length = (current_ev - extra);
+ data->flags = 0; /* todo */
- kfree(pBssList);
+ kfree(pBssList);
- return 0;
+ return 0;
}
int usbdrvwext_siwessid(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *essid, char *extra)
+ struct iw_request_info *info,
+ struct iw_point *essid, char *extra)
{
- char EssidBuf[IW_ESSID_MAX_SIZE+1];
- struct usbdrv_private *macp = dev->ml_priv;
-
- if(!netif_running(dev))
- return -EINVAL;
-
- if (essid->flags == 1)
- {
- if (essid->length > (IW_ESSID_MAX_SIZE+1))
- return -E2BIG;
-
- if (copy_from_user(&EssidBuf, essid->pointer, essid->length))
- return -EFAULT;
-
- EssidBuf[essid->length] = '\0';
- //printk("siwessid - Set Essid : %s\n",EssidBuf);
- //printk("siwessid - Essid Len : %d\n",essid->length);
- //printk("siwessid - Essid Flag : %x\n",essid->flags);
- if (macp->DeviceOpened == 1)
- {
- zfiWlanSetSSID(dev, EssidBuf, strlen(EssidBuf));
- zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev), FALSE);
- zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev));
- //u8_t wpaieLen,wpaie[50];
- //zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen);
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
- //if (wpaieLen > 2)
- // zfiWlanSetWpaIe(dev, wpaie, wpaieLen);
- }
- }
-
- return 0;
+ char EssidBuf[IW_ESSID_MAX_SIZE + 1];
+ struct usbdrv_private *macp = dev->ml_priv;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (essid->flags == 1) {
+ if (essid->length > (IW_ESSID_MAX_SIZE + 1))
+ return -E2BIG;
+
+ if (copy_from_user(&EssidBuf, essid->pointer, essid->length))
+ return -EFAULT;
+
+ EssidBuf[essid->length] = '\0';
+ /* printk("siwessid - Set Essid : %s\n",EssidBuf); */
+ /* printk("siwessid - Essid Len : %d\n",essid->length); */
+ /* printk("siwessid - Essid Flag : %x\n",essid->flags); */
+ if (macp->DeviceOpened == 1) {
+ zfiWlanSetSSID(dev, EssidBuf, strlen(EssidBuf));
+ zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev),
+ FALSE);
+ zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev));
+ /* u8_t wpaieLen,wpaie[50]; */
+ /* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
+ /* if (wpaieLen > 2) */
+ /* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
+ }
+ }
+
+ return 0;
}
int usbdrvwext_giwessid(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *essid, char *extra)
+ struct iw_request_info *info,
+ struct iw_point *essid, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u8_t EssidLen;
- char EssidBuf[IW_ESSID_MAX_SIZE+1];
- int ssid_len;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u8_t EssidLen;
+ char EssidBuf[IW_ESSID_MAX_SIZE + 1];
+ int ssid_len;
- if(!netif_running(dev))
- return -EINVAL;
+ if (!netif_running(dev))
+ return -EINVAL;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);
+ zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);
- /* Convert type from unsigned char to char */
- ssid_len = (int)EssidLen;
+ /* Convert type from unsigned char to char */
+ ssid_len = (int)EssidLen;
- /* Make sure the essid length is not greater than IW_ESSID_MAX_SIZE */
- if (ssid_len > IW_ESSID_MAX_SIZE)
- ssid_len = IW_ESSID_MAX_SIZE;
+ /* Make sure the essid length is not greater than IW_ESSID_MAX_SIZE */
+ if (ssid_len > IW_ESSID_MAX_SIZE)
+ ssid_len = IW_ESSID_MAX_SIZE;
- EssidBuf[ssid_len] = '\0';
+ EssidBuf[ssid_len] = '\0';
- essid->flags = 1;
- essid->length = strlen(EssidBuf);
+ essid->flags = 1;
+ essid->length = strlen(EssidBuf);
- memcpy(extra, EssidBuf, essid->length);
- // wireless.c in Kernel would handle copy_to_user -- line 679
- /*if (essid->pointer)
- {
- if ( copy_to_user(essid->pointer, EssidBuf, essid->length) )
- {
- printk("giwessid - copy_to_user Fail\n");
- return -EFAULT;
- }
- }*/
+ memcpy(extra, EssidBuf, essid->length);
+ /* wireless.c in Kernel would handle copy_to_user -- line 679 */
+ /* if (essid->pointer) {
+ * if (copy_to_user(essid->pointer, EssidBuf, essid->length)) {
+ * printk("giwessid - copy_to_user Fail\n");
+ * return -EFAULT;
+ * }
+ * }
+ */
- return 0;
+ return 0;
}
int usbdrvwext_siwnickn(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *nickname)
{
- //Exist but junk--CWYang(+)
+ /* Exist but junk--CWYang(+) */
return 0;
}
@@ -1082,182 +1027,180 @@ int usbdrvwext_giwnickn(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *nickname)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u8_t EssidLen;
- char EssidBuf[IW_ESSID_MAX_SIZE+1];
+ struct usbdrv_private *macp = dev->ml_priv;
+ u8_t EssidLen;
+ char EssidBuf[IW_ESSID_MAX_SIZE + 1];
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);
- EssidBuf[EssidLen] = 0;
+ zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);
+ EssidBuf[EssidLen] = 0;
- data->flags = 1;
- data->length = strlen(EssidBuf);
+ data->flags = 1;
+ data->length = strlen(EssidBuf);
- memcpy(nickname, EssidBuf, data->length);
+ memcpy(nickname, EssidBuf, data->length);
return 0;
}
int usbdrvwext_siwrate(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frq, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *frq, char *extra)
{
struct usbdrv_private *macp = dev->ml_priv;
- //Array to Define Rate Number that Send to Driver
- u16_t zcIndextoRateBG[16] = {1000, 2000, 5500, 11000, 0, 0, 0, 0, 48000,
- 24000, 12000, 6000, 54000, 36000, 18000, 9000};
- u16_t zcRateToMCS[] = {0xff, 0, 1, 2, 3, 0xb, 0xf, 0xa, 0xe, 0x9, 0xd,
- 0x8, 0xc};
- u8_t i,RateIndex = 4;
- u16_t RateKbps;
-
- //printk("frq->disabled : 0x%x\n",frq->disabled);
- //printk("frq->value : 0x%x\n",frq->value);
-
- RateKbps = frq->value / 1000;
- //printk("RateKbps : %d\n", RateKbps);
- for (i = 0; i < 16; i++)
- {
- if (RateKbps == zcIndextoRateBG[i])
- RateIndex = i;
- }
- if (zcIndextoRateBG[RateIndex] == 0)
- RateIndex = 0xff;
- //printk("RateIndex : %x\n", RateIndex);
- for (i = 0; i < 13; i++)
- if (RateIndex == zcRateToMCS[i])
- break;
- //printk("Index : %x\n", i);
- if (RateKbps == 65000)
- {
- RateIndex = 20;
- printk("RateIndex : %d\n", RateIndex);
- }
- if (macp->DeviceOpened == 1)
- {
- zfiWlanSetTxRate(dev, i);
- //zfiWlanDisable(dev);
- //zfiWlanEnable(dev);
- }
-
- return 0;
+ /* Array to Define Rate Number that Send to Driver */
+ u16_t zcIndextoRateBG[16] = {1000, 2000, 5500, 11000, 0, 0, 0, 0,
+ 48000, 24000, 12000, 6000, 54000, 36000, 18000, 9000};
+ u16_t zcRateToMCS[] = {0xff, 0, 1, 2, 3, 0xb, 0xf, 0xa, 0xe, 0x9, 0xd,
+ 0x8, 0xc};
+ u8_t i, RateIndex = 4;
+ u16_t RateKbps;
+
+ /* printk("frq->disabled : 0x%x\n",frq->disabled); */
+ /* printk("frq->value : 0x%x\n",frq->value); */
+
+ RateKbps = frq->value / 1000;
+ /* printk("RateKbps : %d\n", RateKbps); */
+ for (i = 0; i < 16; i++) {
+ if (RateKbps == zcIndextoRateBG[i])
+ RateIndex = i;
+ }
+
+ if (zcIndextoRateBG[RateIndex] == 0)
+ RateIndex = 0xff;
+ /* printk("RateIndex : %x\n", RateIndex); */
+ for (i = 0; i < 13; i++)
+ if (RateIndex == zcRateToMCS[i])
+ break;
+ /* printk("Index : %x\n", i); */
+ if (RateKbps == 65000) {
+ RateIndex = 20;
+ printk(KERN_WARNING "RateIndex : %d\n", RateIndex);
+ }
+
+ if (macp->DeviceOpened == 1) {
+ zfiWlanSetTxRate(dev, i);
+ /* zfiWlanDisable(dev); */
+ /* zfiWlanEnable(dev); */
+ }
+
+ return 0;
}
int usbdrvwext_giwrate(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frq, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *frq, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
+ struct usbdrv_private *macp = dev->ml_priv;
- if(!netif_running(dev))
- return -EINVAL;
+ if (!netif_running(dev))
+ return -EINVAL;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- frq->fixed = 0;
- frq->disabled = 0;
- frq->value = zfiWlanQueryRxRate(dev) * 1000;
+ frq->fixed = 0;
+ frq->disabled = 0;
+ frq->value = zfiWlanQueryRxRate(dev) * 1000;
- return 0;
+ return 0;
}
int usbdrvwext_siwrts(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rts, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- int val = rts->value;
+ struct usbdrv_private *macp = dev->ml_priv;
+ int val = rts->value;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- if (rts->disabled)
- val = 2347;
+ if (rts->disabled)
+ val = 2347;
- if ((val < 0) || (val > 2347))
- return -EINVAL;
+ if ((val < 0) || (val > 2347))
+ return -EINVAL;
- zfiWlanSetRtsThreshold(dev,val);
+ zfiWlanSetRtsThreshold(dev, val);
- return 0;
+ return 0;
}
int usbdrvwext_giwrts(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rts, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
-
- if(!netif_running(dev))
- return -EINVAL;
+ struct usbdrv_private *macp = dev->ml_priv;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (!netif_running(dev))
+ return -EINVAL;
- rts->value = zfiWlanQueryRtsThreshold(dev);
- rts->disabled = (rts->value >= 2347);
- rts->fixed = 1;
+ if (macp->DeviceOpened != 1)
+ return 0;
- return 0;
+ rts->value = zfiWlanQueryRtsThreshold(dev);
+ rts->disabled = (rts->value >= 2347);
+ rts->fixed = 1;
+ return 0;
}
int usbdrvwext_siwfrag(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frag, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u16_t fragThreshold;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u16_t fragThreshold;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- if (frag->disabled)
- fragThreshold = 0;
- else
- fragThreshold = frag->value;
+ if (frag->disabled)
+ fragThreshold = 0;
+ else
+ fragThreshold = frag->value;
- zfiWlanSetFragThreshold(dev,fragThreshold);
+ zfiWlanSetFragThreshold(dev, fragThreshold);
- return 0;
+ return 0;
}
int usbdrvwext_giwfrag(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frag, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u16 val;
- unsigned long irqFlag;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u16 val;
+ unsigned long irqFlag;
- if(!netif_running(dev))
- return -EINVAL;
+ if (!netif_running(dev))
+ return -EINVAL;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- spin_lock_irqsave(&macp->cs_lock, irqFlag);
+ spin_lock_irqsave(&macp->cs_lock, irqFlag);
- val = zfiWlanQueryFragThreshold(dev);
+ val = zfiWlanQueryFragThreshold(dev);
- frag->value = val;
+ frag->value = val;
- frag->disabled = (val >= 2346);
- frag->fixed = 1;
+ frag->disabled = (val >= 2346);
+ frag->fixed = 1;
- spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+ spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
- return 0;
+ return 0;
}
int usbdrvwext_siwtxpow(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
- //Not support yet--CWYng(+)
+ /* Not support yet--CWYng(+) */
return 0;
}
@@ -1265,7 +1208,7 @@ int usbdrvwext_giwtxpow(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
- //Not support yet--CWYng(+)
+ /* Not support yet--CWYng(+) */
return 0;
}
@@ -1273,7 +1216,7 @@ int usbdrvwext_siwretry(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
- //Do nothing--CWYang(+)
+ /* Do nothing--CWYang(+) */
return 0;
}
@@ -1281,665 +1224,662 @@ int usbdrvwext_giwretry(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
- //Do nothing--CWYang(+)
+ /* Do nothing--CWYang(+) */
return 0;
}
int usbdrvwext_siwencode(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq, char *key)
+ struct iw_request_info *info,
+ struct iw_point *erq, char *key)
{
- struct zsKeyInfo keyInfo;
- int i, WepState = ZM_ENCRYPTION_WEP_DISABLED;
- struct usbdrv_private *macp = dev->ml_priv;
-
- if(!netif_running(dev))
- return -EINVAL;
-
- if ((erq->flags & IW_ENCODE_DISABLED) == 0)
- {
- keyInfo.key = key;
- keyInfo.keyLength = erq->length;
- keyInfo.keyIndex = (erq->flags & IW_ENCODE_INDEX) - 1;
- if (keyInfo.keyIndex >= 4)
- keyInfo.keyIndex = 0;
- keyInfo.flag = ZM_KEY_FLAG_DEFAULT_KEY;
-
- zfiWlanSetKey(dev, keyInfo);
- WepState = ZM_ENCRYPTION_WEP_ENABLED;
- }
- else
- {
- for (i = 1; i < 4; i++)
- zfiWlanRemoveKey(dev, 0, i);
- WepState = ZM_ENCRYPTION_WEP_DISABLED;
- //zfiWlanSetEncryMode(dev, ZM_NO_WEP);
- }
-
- if (macp->DeviceOpened == 1)
- {
- zfiWlanSetWepStatus(dev, WepState);
- zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev), FALSE);
- //zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev));
- //u8_t wpaieLen,wpaie[50];
- //zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen);
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
- //if (wpaieLen > 2)
- // zfiWlanSetWpaIe(dev, wpaie, wpaieLen);
- }
-
- return 0;
+ struct zsKeyInfo keyInfo;
+ int i;
+ int WepState = ZM_ENCRYPTION_WEP_DISABLED;
+ struct usbdrv_private *macp = dev->ml_priv;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if ((erq->flags & IW_ENCODE_DISABLED) == 0) {
+ keyInfo.key = key;
+ keyInfo.keyLength = erq->length;
+ keyInfo.keyIndex = (erq->flags & IW_ENCODE_INDEX) - 1;
+ if (keyInfo.keyIndex >= 4)
+ keyInfo.keyIndex = 0;
+ keyInfo.flag = ZM_KEY_FLAG_DEFAULT_KEY;
+
+ zfiWlanSetKey(dev, keyInfo);
+ WepState = ZM_ENCRYPTION_WEP_ENABLED;
+ } else {
+ for (i = 1; i < 4; i++)
+ zfiWlanRemoveKey(dev, 0, i);
+ WepState = ZM_ENCRYPTION_WEP_DISABLED;
+ /* zfiWlanSetEncryMode(dev, ZM_NO_WEP); */
+ }
+
+ if (macp->DeviceOpened == 1) {
+ zfiWlanSetWepStatus(dev, WepState);
+ zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev), FALSE);
+ /* zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev)); */
+ /* u8_t wpaieLen,wpaie[50]; */
+ /* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
+ /* if (wpaieLen > 2) */
+ /* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
+ }
+
+ return 0;
}
int usbdrvwext_giwencode(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq, char *key)
+ struct iw_request_info *info,
+ struct iw_point *erq, char *key)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u8_t EncryptionMode;
- u8_t keyLen = 0;
-
- if (macp->DeviceOpened != 1)
- return 0;
-
- EncryptionMode = zfiWlanQueryEncryMode(dev);
-
- if (EncryptionMode)
- {
- erq->flags = IW_ENCODE_ENABLED;
- }
- else
- {
- erq->flags = IW_ENCODE_DISABLED;
- }
-
-/* We can't return the key, so set the proper flag and return zero */
- erq->flags |= IW_ENCODE_NOKEY;
- memset(key, 0, 16);
-
-/* Copy the key to the user buffer */
- switch(EncryptionMode)
- {
- case ZM_WEP64:
- keyLen = 5;
- break;
- case ZM_WEP128:
- keyLen = 13;
- break;
- case ZM_WEP256:
- keyLen = 29;
- break;
- case ZM_AES:
- keyLen = 16;
- break;
- case ZM_TKIP:
- keyLen = 32;
- break;
-#ifdef ZM_ENABLE_CENC
- case ZM_CENC:
- keyLen = 32;
- break;
-#endif //ZM_ENABLE_CENC
- case ZM_NO_WEP:
- keyLen = 0;
- break;
- default :
- keyLen = 0;
- printk("Unknown EncryMode\n");
- break;
-
- }
- erq->length = keyLen;
-
- return 0;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u8_t EncryptionMode;
+ u8_t keyLen = 0;
+
+ if (macp->DeviceOpened != 1)
+ return 0;
+
+ EncryptionMode = zfiWlanQueryEncryMode(dev);
+
+ if (EncryptionMode)
+ erq->flags = IW_ENCODE_ENABLED;
+ else
+ erq->flags = IW_ENCODE_DISABLED;
+
+ /* We can't return the key, so set the proper flag and return zero */
+ erq->flags |= IW_ENCODE_NOKEY;
+ memset(key, 0, 16);
+
+ /* Copy the key to the user buffer */
+ switch (EncryptionMode) {
+ case ZM_WEP64:
+ keyLen = 5;
+ break;
+ case ZM_WEP128:
+ keyLen = 13;
+ break;
+ case ZM_WEP256:
+ keyLen = 29;
+ break;
+ case ZM_AES:
+ keyLen = 16;
+ break;
+ case ZM_TKIP:
+ keyLen = 32;
+ break;
+ #ifdef ZM_ENABLE_CENC
+ case ZM_CENC:
+ /* ZM_ENABLE_CENC */
+ keyLen = 32;
+ break;
+ #endif
+ case ZM_NO_WEP:
+ keyLen = 0;
+ break;
+ default:
+ keyLen = 0;
+ printk(KERN_ERR "Unknown EncryMode\n");
+ break;
+ }
+ erq->length = keyLen;
+
+ return 0;
}
int usbdrvwext_siwpower(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frq, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *frq, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u8_t PSMode;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u8_t PSMode;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- if (frq->disabled)
- PSMode = ZM_STA_PS_NONE;
- else
- PSMode = ZM_STA_PS_MAX;
+ if (frq->disabled)
+ PSMode = ZM_STA_PS_NONE;
+ else
+ PSMode = ZM_STA_PS_MAX;
- zfiWlanSetPowerSaveMode(dev,PSMode);
+ zfiWlanSetPowerSaveMode(dev, PSMode);
- return 0;
+ return 0;
}
int usbdrvwext_giwpower(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frq, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *frq, char *extra)
{
- unsigned long irqFlag;
- struct usbdrv_private *macp = dev->ml_priv;
+ unsigned long irqFlag;
+ struct usbdrv_private *macp = dev->ml_priv;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- spin_lock_irqsave(&macp->cs_lock, irqFlag);
+ spin_lock_irqsave(&macp->cs_lock, irqFlag);
- if (zfiWlanQueryPowerSaveMode(dev) == ZM_STA_PS_NONE)
- frq->disabled = 1;
- else
- frq->disabled = 0;
+ if (zfiWlanQueryPowerSaveMode(dev) == ZM_STA_PS_NONE)
+ frq->disabled = 1;
+ else
+ frq->disabled = 0;
- spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+ spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
- return 0;
+ return 0;
}
-//int usbdrvwext_setparam(struct net_device *dev, struct iw_request_info *info,
-// void *w, char *extra)
-//{
-// struct ieee80211vap *vap = dev->ml_priv;
-// struct ieee80211com *ic = vap->iv_ic;
-// struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn;
-// int *i = (int *) extra;
-// int param = i[0]; /* parameter id is 1st */
-// int value = i[1]; /* NB: most values are TYPE_INT */
-// int retv = 0;
-// int j, caps;
-// const struct ieee80211_authenticator *auth;
-// const struct ieee80211_aclator *acl;
-//
-// switch (param) {
-// case IEEE80211_PARAM_AUTHMODE:
-// switch (value) {
-// case IEEE80211_AUTH_WPA: /* WPA */
-// case IEEE80211_AUTH_8021X: /* 802.1x */
-// case IEEE80211_AUTH_OPEN: /* open */
-// case IEEE80211_AUTH_SHARED: /* shared-key */
-// case IEEE80211_AUTH_AUTO: /* auto */
-// auth = ieee80211_authenticator_get(value);
-// if (auth == NULL)
-// return -EINVAL;
-// break;
-// default:
-// return -EINVAL;
-// }
-// switch (value) {
-// case IEEE80211_AUTH_WPA: /* WPA w/ 802.1x */
-// vap->iv_flags |= IEEE80211_F_PRIVACY;
-// value = IEEE80211_AUTH_8021X;
-// break;
-// case IEEE80211_AUTH_OPEN: /* open */
-// vap->iv_flags &= ~(IEEE80211_F_WPA|IEEE80211_F_PRIVACY);
-// break;
-// case IEEE80211_AUTH_SHARED: /* shared-key */
-// case IEEE80211_AUTH_AUTO: /* auto */
-// case IEEE80211_AUTH_8021X: /* 802.1x */
-// vap->iv_flags &= ~IEEE80211_F_WPA;
-// /* both require a key so mark the PRIVACY capability */
-// vap->iv_flags |= IEEE80211_F_PRIVACY;
-// break;
-// }
-// /* NB: authenticator attach/detach happens on state change */
-// vap->iv_bss->ni_authmode = value;
-// /* XXX mixed/mode/usage? */
-// vap->iv_auth = auth;
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_PROTMODE:
-// if (value > IEEE80211_PROT_RTSCTS)
-// return -EINVAL;
-// ic->ic_protmode = value;
-// /* NB: if not operating in 11g this can wait */
-// if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
-// IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_MCASTCIPHER:
-// if ((vap->iv_caps & cipher2cap(value)) == 0 &&
-// !ieee80211_crypto_available(value))
-// return -EINVAL;
-// rsn->rsn_mcastcipher = value;
-// if (vap->iv_flags & IEEE80211_F_WPA)
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_MCASTKEYLEN:
-// if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
-// return -EINVAL;
-// /* XXX no way to verify driver capability */
-// rsn->rsn_mcastkeylen = value;
-// if (vap->iv_flags & IEEE80211_F_WPA)
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_UCASTCIPHERS:
-// /*
-// * Convert cipher set to equivalent capabilities.
-// * NB: this logic intentionally ignores unknown and
-// * unsupported ciphers so folks can specify 0xff or
-// * similar and get all available ciphers.
-// */
-// caps = 0;
-// for (j = 1; j < 32; j++) /* NB: skip WEP */
-// if ((value & (1<<j)) &&
-// ((vap->iv_caps & cipher2cap(j)) ||
-// ieee80211_crypto_available(j)))
-// caps |= 1<<j;
-// if (caps == 0) /* nothing available */
-// return -EINVAL;
-// /* XXX verify ciphers ok for unicast use? */
-// /* XXX disallow if running as it'll have no effect */
-// rsn->rsn_ucastcipherset = caps;
-// if (vap->iv_flags & IEEE80211_F_WPA)
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_UCASTCIPHER:
-// if ((rsn->rsn_ucastcipherset & cipher2cap(value)) == 0)
-// return -EINVAL;
-// rsn->rsn_ucastcipher = value;
-// break;
-// case IEEE80211_PARAM_UCASTKEYLEN:
-// if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
-// return -EINVAL;
-// /* XXX no way to verify driver capability */
-// rsn->rsn_ucastkeylen = value;
-// break;
-// case IEEE80211_PARAM_KEYMGTALGS:
-// /* XXX check */
-// rsn->rsn_keymgmtset = value;
-// if (vap->iv_flags & IEEE80211_F_WPA)
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_RSNCAPS:
-// /* XXX check */
-// rsn->rsn_caps = value;
-// if (vap->iv_flags & IEEE80211_F_WPA)
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_WPA:
-// if (value > 3)
-// return -EINVAL;
-// /* XXX verify ciphers available */
-// vap->iv_flags &= ~IEEE80211_F_WPA;
-// switch (value) {
-// case 1:
-// vap->iv_flags |= IEEE80211_F_WPA1;
-// break;
-// case 2:
-// vap->iv_flags |= IEEE80211_F_WPA2;
-// break;
-// case 3:
-// vap->iv_flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2;
-// break;
-// }
-// retv = ENETRESET; /* XXX? */
-// break;
-// case IEEE80211_PARAM_ROAMING:
-// if (!(IEEE80211_ROAMING_DEVICE <= value &&
-// value <= IEEE80211_ROAMING_MANUAL))
-// return -EINVAL;
-// ic->ic_roaming = value;
-// break;
-// case IEEE80211_PARAM_PRIVACY:
-// if (value) {
-// /* XXX check for key state? */
-// vap->iv_flags |= IEEE80211_F_PRIVACY;
-// } else
-// vap->iv_flags &= ~IEEE80211_F_PRIVACY;
-// break;
-// case IEEE80211_PARAM_DROPUNENCRYPTED:
-// if (value)
-// vap->iv_flags |= IEEE80211_F_DROPUNENC;
-// else
-// vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
-// break;
-// case IEEE80211_PARAM_COUNTERMEASURES:
-// if (value) {
-// if ((vap->iv_flags & IEEE80211_F_WPA) == 0)
-// return -EINVAL;
-// vap->iv_flags |= IEEE80211_F_COUNTERM;
-// } else
-// vap->iv_flags &= ~IEEE80211_F_COUNTERM;
-// break;
-// case IEEE80211_PARAM_DRIVER_CAPS:
-// vap->iv_caps = value; /* NB: for testing */
-// break;
-// case IEEE80211_PARAM_MACCMD:
-// acl = vap->iv_acl;
-// switch (value) {
-// case IEEE80211_MACCMD_POLICY_OPEN:
-// case IEEE80211_MACCMD_POLICY_ALLOW:
-// case IEEE80211_MACCMD_POLICY_DENY:
-// if (acl == NULL) {
-// acl = ieee80211_aclator_get("mac");
-// if (acl == NULL || !acl->iac_attach(vap))
-// return -EINVAL;
-// vap->iv_acl = acl;
-// }
-// acl->iac_setpolicy(vap, value);
-// break;
-// case IEEE80211_MACCMD_FLUSH:
-// if (acl != NULL)
-// acl->iac_flush(vap);
-// /* NB: silently ignore when not in use */
-// break;
-// case IEEE80211_MACCMD_DETACH:
-// if (acl != NULL) {
-// vap->iv_acl = NULL;
-// acl->iac_detach(vap);
-// }
-// break;
-// }
-// break;
-// case IEEE80211_PARAM_WMM:
-// if (ic->ic_caps & IEEE80211_C_WME){
-// if (value) {
-// vap->iv_flags |= IEEE80211_F_WME;
-// vap->iv_ic->ic_flags |= IEEE80211_F_WME; /* XXX needed by ic_reset */
-// }
-// else {
-// vap->iv_flags &= ~IEEE80211_F_WME;
-// vap->iv_ic->ic_flags &= ~IEEE80211_F_WME; /* XXX needed by ic_reset */
-// }
-// retv = ENETRESET; /* Renegotiate for capabilities */
-// }
-// break;
-// case IEEE80211_PARAM_HIDESSID:
-// if (value)
-// vap->iv_flags |= IEEE80211_F_HIDESSID;
-// else
-// vap->iv_flags &= ~IEEE80211_F_HIDESSID;
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_APBRIDGE:
-// if (value == 0)
-// vap->iv_flags |= IEEE80211_F_NOBRIDGE;
-// else
-// vap->iv_flags &= ~IEEE80211_F_NOBRIDGE;
-// break;
-// case IEEE80211_PARAM_INACT:
-// vap->iv_inact_run = value / IEEE80211_INACT_WAIT;
-// break;
-// case IEEE80211_PARAM_INACT_AUTH:
-// vap->iv_inact_auth = value / IEEE80211_INACT_WAIT;
-// break;
-// case IEEE80211_PARAM_INACT_INIT:
-// vap->iv_inact_init = value / IEEE80211_INACT_WAIT;
-// break;
-// case IEEE80211_PARAM_ABOLT:
-// caps = 0;
-// /*
-// * Map abolt settings to capability bits;
-// * this also strips unknown/unwanted bits.
-// */
-// if (value & IEEE80211_ABOLT_TURBO_PRIME)
-// caps |= IEEE80211_ATHC_TURBOP;
-// if (value & IEEE80211_ABOLT_COMPRESSION)
-// caps |= IEEE80211_ATHC_COMP;
-// if (value & IEEE80211_ABOLT_FAST_FRAME)
-// caps |= IEEE80211_ATHC_FF;
-// if (value & IEEE80211_ABOLT_XR)
-// caps |= IEEE80211_ATHC_XR;
-// if (value & IEEE80211_ABOLT_AR)
-// caps |= IEEE80211_ATHC_AR;
-// if (value & IEEE80211_ABOLT_BURST)
-// caps |= IEEE80211_ATHC_BURST;
-// if (value & IEEE80211_ABOLT_WME_ELE)
-// caps |= IEEE80211_ATHC_WME;
-// /* verify requested capabilities are supported */
-// if ((caps & ic->ic_ath_cap) != caps)
-// return -EINVAL;
-// if (vap->iv_ath_cap != caps) {
-// if ((vap->iv_ath_cap ^ caps) & IEEE80211_ATHC_TURBOP) {
-// if (ieee80211_set_turbo(dev, caps & IEEE80211_ATHC_TURBOP))
-// return -EINVAL;
-// ieee80211_scan_flush(ic);
-// }
-// vap->iv_ath_cap = caps;
-// ic->ic_athcapsetup(vap->iv_ic, vap->iv_ath_cap);
-// retv = ENETRESET;
-// }
-// break;
-// case IEEE80211_PARAM_DTIM_PERIOD:
-// if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
-// vap->iv_opmode != IEEE80211_M_IBSS)
-// return -EINVAL;
-// if (IEEE80211_DTIM_MIN <= value &&
-// value <= IEEE80211_DTIM_MAX) {
-// vap->iv_dtim_period = value;
-// retv = ENETRESET; /* requires restart */
-// } else
-// retv = EINVAL;
-// break;
-// case IEEE80211_PARAM_BEACON_INTERVAL:
-// if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
-// vap->iv_opmode != IEEE80211_M_IBSS)
-// return -EINVAL;
-// if (IEEE80211_BINTVAL_MIN <= value &&
-// value <= IEEE80211_BINTVAL_MAX) {
-// ic->ic_lintval = value; /* XXX multi-bss */
-// retv = ENETRESET; /* requires restart */
-// } else
-// retv = EINVAL;
-// break;
-// case IEEE80211_PARAM_DOTH:
-// if (value) {
-// ic->ic_flags |= IEEE80211_F_DOTH;
-// }
-// else
-// ic->ic_flags &= ~IEEE80211_F_DOTH;
-// retv = ENETRESET; /* XXX: need something this drastic? */
-// break;
-// case IEEE80211_PARAM_PWRTARGET:
-// ic->ic_curchanmaxpwr = value;
-// break;
-// case IEEE80211_PARAM_GENREASSOC:
-// IEEE80211_SEND_MGMT(vap->iv_bss, IEEE80211_FC0_SUBTYPE_REASSOC_REQ, 0);
-// break;
-// case IEEE80211_PARAM_COMPRESSION:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_COMP, value);
-// break;
-// case IEEE80211_PARAM_WMM_AGGRMODE:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_WME, value);
-// break;
-// case IEEE80211_PARAM_FF:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_FF, value);
-// break;
-// case IEEE80211_PARAM_TURBO:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_TURBOP, value);
-// if (retv == ENETRESET) {
-// if(ieee80211_set_turbo(dev,value))
-// return -EINVAL;
-// ieee80211_scan_flush(ic);
-// }
-// break;
-// case IEEE80211_PARAM_XR:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_XR, value);
-// break;
-// case IEEE80211_PARAM_BURST:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_BURST, value);
-// break;
-// case IEEE80211_PARAM_AR:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_AR, value);
-// break;
-// case IEEE80211_PARAM_PUREG:
-// if (value)
-// vap->iv_flags |= IEEE80211_F_PUREG;
-// else
-// vap->iv_flags &= ~IEEE80211_F_PUREG;
-// /* NB: reset only if we're operating on an 11g channel */
-// if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
-// IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_WDS:
-// if (value)
-// vap->iv_flags_ext |= IEEE80211_FEXT_WDS;
-// else
-// vap->iv_flags_ext &= ~IEEE80211_FEXT_WDS;
-// break;
-// case IEEE80211_PARAM_BGSCAN:
-// if (value) {
-// if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0)
-// return -EINVAL;
-// vap->iv_flags |= IEEE80211_F_BGSCAN;
-// } else {
-// /* XXX racey? */
-// vap->iv_flags &= ~IEEE80211_F_BGSCAN;
-// ieee80211_cancel_scan(vap); /* anything current */
-// }
-// break;
-// case IEEE80211_PARAM_BGSCAN_IDLE:
-// if (value >= IEEE80211_BGSCAN_IDLE_MIN)
-// vap->iv_bgscanidle = value*HZ/1000;
-// else
-// retv = EINVAL;
-// break;
-// case IEEE80211_PARAM_BGSCAN_INTERVAL:
-// if (value >= IEEE80211_BGSCAN_INTVAL_MIN)
-// vap->iv_bgscanintvl = value*HZ;
-// else
-// retv = EINVAL;
-// break;
-// case IEEE80211_PARAM_MCAST_RATE:
-// /* units are in KILObits per second */
-// if (value >= 256 && value <= 54000)
-// vap->iv_mcast_rate = value;
-// else
-// retv = EINVAL;
-// break;
-// case IEEE80211_PARAM_COVERAGE_CLASS:
-// if (value >= 0 && value <= IEEE80211_COVERAGE_CLASS_MAX) {
-// ic->ic_coverageclass = value;
-// if (IS_UP_AUTO(vap))
-// ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
-// retv = 0;
-// }
-// else
-// retv = EINVAL;
-// break;
-// case IEEE80211_PARAM_COUNTRY_IE:
-// if (value)
-// ic->ic_flags_ext |= IEEE80211_FEXT_COUNTRYIE;
-// else
-// ic->ic_flags_ext &= ~IEEE80211_FEXT_COUNTRYIE;
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_REGCLASS:
-// if (value)
-// ic->ic_flags_ext |= IEEE80211_FEXT_REGCLASS;
-// else
-// ic->ic_flags_ext &= ~IEEE80211_FEXT_REGCLASS;
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_SCANVALID:
-// vap->iv_scanvalid = value*HZ;
-// break;
-// case IEEE80211_PARAM_ROAM_RSSI_11A:
-// vap->iv_roam.rssi11a = value;
-// break;
-// case IEEE80211_PARAM_ROAM_RSSI_11B:
-// vap->iv_roam.rssi11bOnly = value;
-// break;
-// case IEEE80211_PARAM_ROAM_RSSI_11G:
-// vap->iv_roam.rssi11b = value;
-// break;
-// case IEEE80211_PARAM_ROAM_RATE_11A:
-// vap->iv_roam.rate11a = value;
-// break;
-// case IEEE80211_PARAM_ROAM_RATE_11B:
-// vap->iv_roam.rate11bOnly = value;
-// break;
-// case IEEE80211_PARAM_ROAM_RATE_11G:
-// vap->iv_roam.rate11b = value;
-// break;
-// case IEEE80211_PARAM_UAPSDINFO:
-// if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
-// if (ic->ic_caps & IEEE80211_C_UAPSD) {
-// if (value)
-// IEEE80211_VAP_UAPSD_ENABLE(vap);
-// else
-// IEEE80211_VAP_UAPSD_DISABLE(vap);
-// retv = ENETRESET;
-// }
-// }
-// else if (vap->iv_opmode == IEEE80211_M_STA) {
-// vap->iv_uapsdinfo = value;
-// IEEE80211_VAP_UAPSD_ENABLE(vap);
-// retv = ENETRESET;
-// }
-// break;
-// case IEEE80211_PARAM_SLEEP:
-// /* XXX: Forced sleep for testing. Does not actually place the
-// * HW in sleep mode yet. this only makes sense for STAs.
-// */
-// if (value) {
-// /* goto sleep */
-// IEEE80211_VAP_GOTOSLEEP(vap);
-// }
-// else {
-// /* wakeup */
-// IEEE80211_VAP_WAKEUP(vap);
-// }
-// ieee80211_send_nulldata(ieee80211_ref_node(vap->iv_bss));
-// break;
-// case IEEE80211_PARAM_QOSNULL:
-// /* Force a QoS Null for testing. */
-// ieee80211_send_qosnulldata(vap->iv_bss, value);
-// break;
-// case IEEE80211_PARAM_PSPOLL:
-// /* Force a PS-POLL for testing. */
-// ieee80211_send_pspoll(vap->iv_bss);
-// break;
-// case IEEE80211_PARAM_EOSPDROP:
-// if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
-// if (value) IEEE80211_VAP_EOSPDROP_ENABLE(vap);
-// else IEEE80211_VAP_EOSPDROP_DISABLE(vap);
-// }
-// break;
-// case IEEE80211_PARAM_MARKDFS:
-// if (value)
-// ic->ic_flags_ext |= IEEE80211_FEXT_MARKDFS;
-// else
-// ic->ic_flags_ext &= ~IEEE80211_FEXT_MARKDFS;
-// break;
-// case IEEE80211_PARAM_CHANBW:
-// switch (value) {
-// case 0:
-// ic->ic_chanbwflag = 0;
-// break;
-// case 1:
-// ic->ic_chanbwflag = IEEE80211_CHAN_HALF;
-// break;
-// case 2:
-// ic->ic_chanbwflag = IEEE80211_CHAN_QUARTER;
-// break;
-// default:
-// retv = EINVAL;
-// break;
-// }
-// break;
-// case IEEE80211_PARAM_SHORTPREAMBLE:
-// if (value) {
-// ic->ic_caps |= IEEE80211_C_SHPREAMBLE;
-// } else {
-// ic->ic_caps &= ~IEEE80211_C_SHPREAMBLE;
-// }
-// retv = ENETRESET;
-// break;
-// default:
-// retv = EOPNOTSUPP;
-// break;
-// }
-// /* XXX should any of these cause a rescan? */
-// if (retv == ENETRESET)
-// retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0;
-// return -retv;
-//}
+/*int usbdrvwext_setparam(struct net_device *dev, struct iw_request_info *info,
+* void *w, char *extra)
+*{
+* struct ieee80211vap *vap = dev->ml_priv;
+* struct ieee80211com *ic = vap->iv_ic;
+* struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn;
+* int *i = (int *) extra;
+* int param = i[0]; // parameter id is 1st
+* int value = i[1]; // NB: most values are TYPE_INT
+* int retv = 0;
+* int j, caps;
+* const struct ieee80211_authenticator *auth;
+* const struct ieee80211_aclator *acl;
+*
+* switch (param) {
+* case IEEE80211_PARAM_AUTHMODE:
+* switch (value) {
+* case IEEE80211_AUTH_WPA: // WPA
+* case IEEE80211_AUTH_8021X: // 802.1x
+* case IEEE80211_AUTH_OPEN: // open
+* case IEEE80211_AUTH_SHARED: // shared-key
+* case IEEE80211_AUTH_AUTO: // auto
+* auth = ieee80211_authenticator_get(value);
+* if (auth == NULL)
+* return -EINVAL;
+* break;
+* default:
+* return -EINVAL;
+* }
+* switch (value) {
+* case IEEE80211_AUTH_WPA: // WPA w/ 802.1x
+* vap->iv_flags |= IEEE80211_F_PRIVACY;
+* value = IEEE80211_AUTH_8021X;
+* break;
+* case IEEE80211_AUTH_OPEN: // open
+* vap->iv_flags &= ~(IEEE80211_F_WPA | IEEE80211_F_PRIVACY);
+* break;
+* case IEEE80211_AUTH_SHARED: // shared-key
+* case IEEE80211_AUTH_AUTO: // auto
+* case IEEE80211_AUTH_8021X: // 802.1x
+* vap->iv_flags &= ~IEEE80211_F_WPA;
+* // both require a key so mark the PRIVACY capability
+* vap->iv_flags |= IEEE80211_F_PRIVACY;
+* break;
+* }
+* // NB: authenticator attach/detach happens on state change
+* vap->iv_bss->ni_authmode = value;
+* // XXX mixed/mode/usage?
+* vap->iv_auth = auth;
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_PROTMODE:
+* if (value > IEEE80211_PROT_RTSCTS)
+* return -EINVAL;
+* ic->ic_protmode = value;
+* // NB: if not operating in 11g this can wait
+* if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
+* IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_MCASTCIPHER:
+* if ((vap->iv_caps & cipher2cap(value)) == 0 &&
+* !ieee80211_crypto_available(value))
+* return -EINVAL;
+* rsn->rsn_mcastcipher = value;
+* if (vap->iv_flags & IEEE80211_F_WPA)
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_MCASTKEYLEN:
+* if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
+* return -EINVAL;
+* // XXX no way to verify driver capability
+* rsn->rsn_mcastkeylen = value;
+* if (vap->iv_flags & IEEE80211_F_WPA)
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_UCASTCIPHERS:
+*
+* // Convert cipher set to equivalent capabilities.
+* // NB: this logic intentionally ignores unknown and
+* // unsupported ciphers so folks can specify 0xff or
+* // similar and get all available ciphers.
+*
+* caps = 0;
+* for (j = 1; j < 32; j++) // NB: skip WEP
+* if ((value & (1<<j)) &&
+* ((vap->iv_caps & cipher2cap(j)) ||
+* ieee80211_crypto_available(j)))
+* caps |= 1<<j;
+* if (caps == 0) // nothing available
+* return -EINVAL;
+* // XXX verify ciphers ok for unicast use?
+* // XXX disallow if running as it'll have no effect
+* rsn->rsn_ucastcipherset = caps;
+* if (vap->iv_flags & IEEE80211_F_WPA)
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_UCASTCIPHER:
+* if ((rsn->rsn_ucastcipherset & cipher2cap(value)) == 0)
+* return -EINVAL;
+* rsn->rsn_ucastcipher = value;
+* break;
+* case IEEE80211_PARAM_UCASTKEYLEN:
+* if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
+* return -EINVAL;
+* // XXX no way to verify driver capability
+* rsn->rsn_ucastkeylen = value;
+* break;
+* case IEEE80211_PARAM_KEYMGTALGS:
+* // XXX check
+* rsn->rsn_keymgmtset = value;
+* if (vap->iv_flags & IEEE80211_F_WPA)
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_RSNCAPS:
+* // XXX check
+* rsn->rsn_caps = value;
+* if (vap->iv_flags & IEEE80211_F_WPA)
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_WPA:
+* if (value > 3)
+* return -EINVAL;
+* // XXX verify ciphers available
+* vap->iv_flags &= ~IEEE80211_F_WPA;
+* switch (value) {
+* case 1:
+* vap->iv_flags |= IEEE80211_F_WPA1;
+* break;
+* case 2:
+* vap->iv_flags |= IEEE80211_F_WPA2;
+* break;
+* case 3:
+* vap->iv_flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2;
+* break;
+* }
+* retv = ENETRESET; // XXX?
+* break;
+* case IEEE80211_PARAM_ROAMING:
+* if (!(IEEE80211_ROAMING_DEVICE <= value &&
+* value <= IEEE80211_ROAMING_MANUAL))
+* return -EINVAL;
+* ic->ic_roaming = value;
+* break;
+* case IEEE80211_PARAM_PRIVACY:
+* if (value) {
+* // XXX check for key state?
+* vap->iv_flags |= IEEE80211_F_PRIVACY;
+* } else
+* vap->iv_flags &= ~IEEE80211_F_PRIVACY;
+* break;
+* case IEEE80211_PARAM_DROPUNENCRYPTED:
+* if (value)
+* vap->iv_flags |= IEEE80211_F_DROPUNENC;
+* else
+* vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
+* break;
+* case IEEE80211_PARAM_COUNTERMEASURES:
+* if (value) {
+* if ((vap->iv_flags & IEEE80211_F_WPA) == 0)
+* return -EINVAL;
+* vap->iv_flags |= IEEE80211_F_COUNTERM;
+* } else
+* vap->iv_flags &= ~IEEE80211_F_COUNTERM;
+* break;
+* case IEEE80211_PARAM_DRIVER_CAPS:
+* vap->iv_caps = value; // NB: for testing
+* break;
+* case IEEE80211_PARAM_MACCMD:
+* acl = vap->iv_acl;
+* switch (value) {
+* case IEEE80211_MACCMD_POLICY_OPEN:
+* case IEEE80211_MACCMD_POLICY_ALLOW:
+* case IEEE80211_MACCMD_POLICY_DENY:
+* if (acl == NULL) {
+* acl = ieee80211_aclator_get("mac");
+* if (acl == NULL || !acl->iac_attach(vap))
+* return -EINVAL;
+* vap->iv_acl = acl;
+* }
+* acl->iac_setpolicy(vap, value);
+* break;
+* case IEEE80211_MACCMD_FLUSH:
+* if (acl != NULL)
+* acl->iac_flush(vap);
+* // NB: silently ignore when not in use
+* break;
+* case IEEE80211_MACCMD_DETACH:
+* if (acl != NULL) {
+* vap->iv_acl = NULL;
+* acl->iac_detach(vap);
+* }
+* break;
+* }
+* break;
+* case IEEE80211_PARAM_WMM:
+* if (ic->ic_caps & IEEE80211_C_WME){
+* if (value) {
+* vap->iv_flags |= IEEE80211_F_WME;
+* *//* XXX needed by ic_reset *//*
+* vap->iv_ic->ic_flags |= IEEE80211_F_WME;
+* }
+* else {
+* *//* XXX needed by ic_reset *//*
+* vap->iv_flags &= ~IEEE80211_F_WME;
+* vap->iv_ic->ic_flags &= ~IEEE80211_F_WME;
+* }
+* retv = ENETRESET; // Renegotiate for capabilities
+* }
+* break;
+* case IEEE80211_PARAM_HIDESSID:
+* if (value)
+* vap->iv_flags |= IEEE80211_F_HIDESSID;
+* else
+* vap->iv_flags &= ~IEEE80211_F_HIDESSID;
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_APBRIDGE:
+* if (value == 0)
+* vap->iv_flags |= IEEE80211_F_NOBRIDGE;
+* else
+* vap->iv_flags &= ~IEEE80211_F_NOBRIDGE;
+* break;
+* case IEEE80211_PARAM_INACT:
+* vap->iv_inact_run = value / IEEE80211_INACT_WAIT;
+* break;
+* case IEEE80211_PARAM_INACT_AUTH:
+* vap->iv_inact_auth = value / IEEE80211_INACT_WAIT;
+* break;
+* case IEEE80211_PARAM_INACT_INIT:
+* vap->iv_inact_init = value / IEEE80211_INACT_WAIT;
+* break;
+* case IEEE80211_PARAM_ABOLT:
+* caps = 0;
+*
+* // Map abolt settings to capability bits;
+* // this also strips unknown/unwanted bits.
+*
+* if (value & IEEE80211_ABOLT_TURBO_PRIME)
+* caps |= IEEE80211_ATHC_TURBOP;
+* if (value & IEEE80211_ABOLT_COMPRESSION)
+* caps |= IEEE80211_ATHC_COMP;
+* if (value & IEEE80211_ABOLT_FAST_FRAME)
+* caps |= IEEE80211_ATHC_FF;
+* if (value & IEEE80211_ABOLT_XR)
+* caps |= IEEE80211_ATHC_XR;
+* if (value & IEEE80211_ABOLT_AR)
+* caps |= IEEE80211_ATHC_AR;
+* if (value & IEEE80211_ABOLT_BURST)
+* caps |= IEEE80211_ATHC_BURST;
+* if (value & IEEE80211_ABOLT_WME_ELE)
+* caps |= IEEE80211_ATHC_WME;
+* // verify requested capabilities are supported
+* if ((caps & ic->ic_ath_cap) != caps)
+* return -EINVAL;
+* if (vap->iv_ath_cap != caps) {
+* if ((vap->iv_ath_cap ^ caps) & IEEE80211_ATHC_TURBOP) {
+* if (ieee80211_set_turbo(dev,
+* caps & IEEE80211_ATHC_TURBOP))
+* return -EINVAL;
+* ieee80211_scan_flush(ic);
+* }
+* vap->iv_ath_cap = caps;
+* ic->ic_athcapsetup(vap->iv_ic, vap->iv_ath_cap);
+* retv = ENETRESET;
+* }
+* break;
+* case IEEE80211_PARAM_DTIM_PERIOD:
+* if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
+* vap->iv_opmode != IEEE80211_M_IBSS)
+* return -EINVAL;
+* if (IEEE80211_DTIM_MIN <= value &&
+* value <= IEEE80211_DTIM_MAX) {
+* vap->iv_dtim_period = value;
+* retv = ENETRESET; // requires restart
+* } else
+* retv = EINVAL;
+* break;
+* case IEEE80211_PARAM_BEACON_INTERVAL:
+* if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
+* vap->iv_opmode != IEEE80211_M_IBSS)
+* return -EINVAL;
+* if (IEEE80211_BINTVAL_MIN <= value &&
+* value <= IEEE80211_BINTVAL_MAX) {
+* ic->ic_lintval = value; // XXX multi-bss
+* retv = ENETRESET; // requires restart
+* } else
+* retv = EINVAL;
+* break;
+* case IEEE80211_PARAM_DOTH:
+* if (value) {
+* ic->ic_flags |= IEEE80211_F_DOTH;
+* }
+* else
+* ic->ic_flags &= ~IEEE80211_F_DOTH;
+* retv = ENETRESET; // XXX: need something this drastic?
+* break;
+* case IEEE80211_PARAM_PWRTARGET:
+* ic->ic_curchanmaxpwr = value;
+* break;
+* case IEEE80211_PARAM_GENREASSOC:
+* IEEE80211_SEND_MGMT(vap->iv_bss,
+* IEEE80211_FC0_SUBTYPE_REASSOC_REQ, 0);
+* break;
+* case IEEE80211_PARAM_COMPRESSION:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_COMP, value);
+* break;
+* case IEEE80211_PARAM_WMM_AGGRMODE:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_WME, value);
+* break;
+* case IEEE80211_PARAM_FF:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_FF, value);
+* break;
+* case IEEE80211_PARAM_TURBO:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_TURBOP, value);
+* if (retv == ENETRESET) {
+* if(ieee80211_set_turbo(dev,value))
+* return -EINVAL;
+* ieee80211_scan_flush(ic);
+* }
+* break;
+* case IEEE80211_PARAM_XR:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_XR, value);
+* break;
+* case IEEE80211_PARAM_BURST:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_BURST, value);
+* break;
+* case IEEE80211_PARAM_AR:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_AR, value);
+* break;
+* case IEEE80211_PARAM_PUREG:
+* if (value)
+* vap->iv_flags |= IEEE80211_F_PUREG;
+* else
+* vap->iv_flags &= ~IEEE80211_F_PUREG;
+* // NB: reset only if we're operating on an 11g channel
+* if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
+* IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_WDS:
+* if (value)
+* vap->iv_flags_ext |= IEEE80211_FEXT_WDS;
+* else
+* vap->iv_flags_ext &= ~IEEE80211_FEXT_WDS;
+* break;
+* case IEEE80211_PARAM_BGSCAN:
+* if (value) {
+* if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0)
+* return -EINVAL;
+* vap->iv_flags |= IEEE80211_F_BGSCAN;
+* } else {
+* // XXX racey?
+* vap->iv_flags &= ~IEEE80211_F_BGSCAN;
+* ieee80211_cancel_scan(vap); // anything current
+* }
+* break;
+* case IEEE80211_PARAM_BGSCAN_IDLE:
+* if (value >= IEEE80211_BGSCAN_IDLE_MIN)
+* vap->iv_bgscanidle = value*HZ/1000;
+* else
+* retv = EINVAL;
+* break;
+* case IEEE80211_PARAM_BGSCAN_INTERVAL:
+* if (value >= IEEE80211_BGSCAN_INTVAL_MIN)
+* vap->iv_bgscanintvl = value*HZ;
+* else
+* retv = EINVAL;
+* break;
+* case IEEE80211_PARAM_MCAST_RATE:
+* // units are in KILObits per second
+* if (value >= 256 && value <= 54000)
+* vap->iv_mcast_rate = value;
+* else
+* retv = EINVAL;
+* break;
+* case IEEE80211_PARAM_COVERAGE_CLASS:
+* if (value >= 0 && value <= IEEE80211_COVERAGE_CLASS_MAX) {
+* ic->ic_coverageclass = value;
+* if (IS_UP_AUTO(vap))
+* ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
+* retv = 0;
+* }
+* else
+* retv = EINVAL;
+* break;
+* case IEEE80211_PARAM_COUNTRY_IE:
+* if (value)
+* ic->ic_flags_ext |= IEEE80211_FEXT_COUNTRYIE;
+* else
+* ic->ic_flags_ext &= ~IEEE80211_FEXT_COUNTRYIE;
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_REGCLASS:
+* if (value)
+* ic->ic_flags_ext |= IEEE80211_FEXT_REGCLASS;
+* else
+* ic->ic_flags_ext &= ~IEEE80211_FEXT_REGCLASS;
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_SCANVALID:
+* vap->iv_scanvalid = value*HZ;
+* break;
+* case IEEE80211_PARAM_ROAM_RSSI_11A:
+* vap->iv_roam.rssi11a = value;
+* break;
+* case IEEE80211_PARAM_ROAM_RSSI_11B:
+* vap->iv_roam.rssi11bOnly = value;
+* break;
+* case IEEE80211_PARAM_ROAM_RSSI_11G:
+* vap->iv_roam.rssi11b = value;
+* break;
+* case IEEE80211_PARAM_ROAM_RATE_11A:
+* vap->iv_roam.rate11a = value;
+* break;
+* case IEEE80211_PARAM_ROAM_RATE_11B:
+* vap->iv_roam.rate11bOnly = value;
+* break;
+* case IEEE80211_PARAM_ROAM_RATE_11G:
+* vap->iv_roam.rate11b = value;
+* break;
+* case IEEE80211_PARAM_UAPSDINFO:
+* if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
+* if (ic->ic_caps & IEEE80211_C_UAPSD) {
+* if (value)
+* IEEE80211_VAP_UAPSD_ENABLE(vap);
+* else
+* IEEE80211_VAP_UAPSD_DISABLE(vap);
+* retv = ENETRESET;
+* }
+* }
+* else if (vap->iv_opmode == IEEE80211_M_STA) {
+* vap->iv_uapsdinfo = value;
+* IEEE80211_VAP_UAPSD_ENABLE(vap);
+* retv = ENETRESET;
+* }
+* break;
+* case IEEE80211_PARAM_SLEEP:
+* // XXX: Forced sleep for testing. Does not actually place the
+* // HW in sleep mode yet. this only makes sense for STAs.
+*
+* if (value) {
+* // goto sleep
+* IEEE80211_VAP_GOTOSLEEP(vap);
+* }
+* else {
+* // wakeup
+* IEEE80211_VAP_WAKEUP(vap);
+* }
+* ieee80211_send_nulldata(ieee80211_ref_node(vap->iv_bss));
+* break;
+* case IEEE80211_PARAM_QOSNULL:
+* // Force a QoS Null for testing.
+* ieee80211_send_qosnulldata(vap->iv_bss, value);
+* break;
+* case IEEE80211_PARAM_PSPOLL:
+* // Force a PS-POLL for testing.
+* ieee80211_send_pspoll(vap->iv_bss);
+* break;
+* case IEEE80211_PARAM_EOSPDROP:
+* if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
+* if (value) IEEE80211_VAP_EOSPDROP_ENABLE(vap);
+* else IEEE80211_VAP_EOSPDROP_DISABLE(vap);
+* }
+* break;
+* case IEEE80211_PARAM_MARKDFS:
+* if (value)
+* ic->ic_flags_ext |= IEEE80211_FEXT_MARKDFS;
+* else
+* ic->ic_flags_ext &= ~IEEE80211_FEXT_MARKDFS;
+* break;
+* case IEEE80211_PARAM_CHANBW:
+* switch (value) {
+* case 0:
+* ic->ic_chanbwflag = 0;
+* break;
+* case 1:
+* ic->ic_chanbwflag = IEEE80211_CHAN_HALF;
+* break;
+* case 2:
+* ic->ic_chanbwflag = IEEE80211_CHAN_QUARTER;
+* break;
+* default:
+* retv = EINVAL;
+* break;
+* }
+* break;
+* case IEEE80211_PARAM_SHORTPREAMBLE:
+* if (value) {
+* ic->ic_caps |= IEEE80211_C_SHPREAMBLE;
+* } else {
+* ic->ic_caps &= ~IEEE80211_C_SHPREAMBLE;
+* }
+* retv = ENETRESET;
+* break;
+* default:
+* retv = EOPNOTSUPP;
+* break;
+* }
+* // XXX should any of these cause a rescan?
+* if (retv == ENETRESET)
+* retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0;
+* return -retv;
+*}
+*/
int usbdrvwext_setmode(struct net_device *dev, struct iw_request_info *info,
- void *w, char *extra)
+ void *w, char *extra)
{
return 0;
}
@@ -1947,158 +1887,138 @@ int usbdrvwext_setmode(struct net_device *dev, struct iw_request_info *info,
int usbdrvwext_getmode(struct net_device *dev, struct iw_request_info *info,
void *w, char *extra)
{
- //struct usbdrv_private *macp = dev->ml_priv;
+ /* struct usbdrv_private *macp = dev->ml_priv; */
struct iw_point *wri = (struct iw_point *)extra;
char mode[8];
- strcpy(mode,"11g");
- return (copy_to_user(wri->pointer, mode, 6) ? -EFAULT : 0);
+ strcpy(mode, "11g");
+ return copy_to_user(wri->pointer, mode, 6) ? -EFAULT : 0;
}
int zfLnxPrivateIoctl(struct net_device *dev, struct zdap_ioctl* zdreq)
{
- //void* regp = macp->regp;
+ /* void* regp = macp->regp; */
u16_t cmd;
- //u32_t temp;
- u32_t* p;
+ /* u32_t temp; */
+ u32_t *p;
u32_t i;
cmd = zdreq->cmd;
- switch(cmd)
- {
+ switch (cmd) {
case ZM_IOCTL_REG_READ:
zfiDbgReadReg(dev, zdreq->addr);
break;
-
case ZM_IOCTL_REG_WRITE:
zfiDbgWriteReg(dev, zdreq->addr, zdreq->value);
break;
-
case ZM_IOCTL_MEM_READ:
p = (u32_t *) bus_to_virt(zdreq->addr);
- printk(KERN_DEBUG "usbdrv: read memory addr: 0x%08x value: 0x%08x\n", zdreq->addr, *p);
+ printk(KERN_WARNING
+ "usbdrv: read memory addr: 0x%08x value:"
+ " 0x%08x\n", zdreq->addr, *p);
break;
-
case ZM_IOCTL_MEM_WRITE:
p = (u32_t *) bus_to_virt(zdreq->addr);
*p = zdreq->value;
- printk(KERN_DEBUG "usbdrv: write value: 0x%08x to memory addr: 0x%08x\n", zdreq->value, zdreq->addr);
+ printk(KERN_WARNING
+ "usbdrv : write value : 0x%08x to memory addr :"
+ " 0x%08x\n", zdreq->value, zdreq->addr);
break;
-
- case ZM_IOCTL_TALLY :
+ case ZM_IOCTL_TALLY:
zfiWlanShowTally(dev);
if (zdreq->addr)
zfiWlanResetTally(dev);
break;
+ case ZM_IOCTL_TEST:
+ printk(KERN_WARNING
+ "ZM_IOCTL_TEST:len=%d\n", zdreq->addr);
+ /* zfiWlanReadReg(dev, 0x10f400); */
+ /* zfiWlanReadReg(dev, 0x10f404); */
+ printk(KERN_WARNING "IOCTL TEST\n");
+ #if 1
+ /* print packet */
+ for (i = 0; i < zdreq->addr; i++) {
+ if ((i&0x7) == 0)
+ printk(KERN_WARNING "\n");
+ printk(KERN_WARNING "%02X ",
+ (unsigned char)zdreq->data[i]);
+ }
+ printk(KERN_WARNING "\n");
+ #endif
+
+ /* For Test?? 1 to 0 by CWYang(-) */
+ #if 0
+ struct sk_buff *s;
+
+ /* Allocate a skb */
+ s = alloc_skb(2000, GFP_ATOMIC);
- case ZM_IOCTL_TEST :
- printk(KERN_DEBUG "ZM_IOCTL_TEST:len=%d\n", zdreq->addr);
- //zfiWlanReadReg(dev, 0x10f400);
- //zfiWlanReadReg(dev, 0x10f404);
- printk("IOCTL TEST\n");
- #if 1
- //print packet
- for (i=0; i<zdreq->addr; i++)
- {
- if ((i&0x7) == 0)
- {
- printk("\n");
- }
- printk("%02X ", (unsigned char)zdreq->data[i]);
- }
- printk("\n");
- #endif
-
-
- #if 0 //For Test?? 1 to 0 by CWYang(-)
- {
- struct sk_buff* s;
-
- /* Allocate a skb */
- s = alloc_skb(2000, GFP_ATOMIC);
-
- /* Copy data to skb */
- for (i=0; i<zdreq->addr; i++)
- {
- s->data[i] = zdreq->data[i];
- }
- s->len = zdreq->addr;
-
- /* Call zfIdlRecv() */
- zfiRecv80211(dev, s, NULL);
- }
- #endif
-
- break;
-
-
-/****************************** ZDCONFIG ******************************/
- case ZM_IOCTL_FRAG :
- zfiWlanSetFragThreshold(dev, zdreq->addr);
- break;
-
- case ZM_IOCTL_RTS :
- zfiWlanSetRtsThreshold(dev, zdreq->addr);
- break;
-
- case ZM_IOCTL_SCAN :
- zfiWlanScan(dev);
- break;
-
- case ZM_IOCTL_KEY :
- {
- u8_t key[29];
- struct zsKeyInfo keyInfo;
- u32_t i;
-
- for (i=0; i<29; i++)
- {
- key[i] = 0;
- }
-
- for (i=0; i<zdreq->addr; i++)
- {
- key[i] = zdreq->data[i];
- }
-
- printk("key len=%d, key=%02x%02x%02x%02x%02x...\n",
- zdreq->addr, key[0], key[1], key[2], key[3], key[4]);
-
- keyInfo.keyLength = zdreq->addr;
- keyInfo.keyIndex = 0;
- keyInfo.flag = 0;
- keyInfo.key = key;
- zfiWlanSetKey(dev, keyInfo);
- }
- break;
-
- case ZM_IOCTL_RATE :
- zfiWlanSetTxRate(dev, zdreq->addr);
- break;
-
- case ZM_IOCTL_ENCRYPTION_MODE :
- zfiWlanSetEncryMode(dev, zdreq->addr);
-
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
- break;
- //CWYang(+)
- case ZM_IOCTL_SIGNAL_STRENGTH :
- {
- u8_t buffer[2];
- zfiWlanQuerySignalInfo(dev, &buffer[0]);
- printk("Current Signal Strength : %02d\n", buffer[0]);
- }
- break;
- //CWYang(+)
- case ZM_IOCTL_SIGNAL_QUALITY :
- {
- u8_t buffer[2];
- zfiWlanQuerySignalInfo(dev, &buffer[0]);
- printk("Current Signal Quality : %02d\n", buffer[1]);
- }
- break;
+ /* Copy data to skb */
+ for (i = 0; i < zdreq->addr; i++)
+ s->data[i] = zdreq->data[i];
+ s->len = zdreq->addr;
+ /* Call zfIdlRecv() */
+ zfiRecv80211(dev, s, NULL);
+ #endif
+ break;
+ /************************* ZDCONFIG ***************************/
+ case ZM_IOCTL_FRAG:
+ zfiWlanSetFragThreshold(dev, zdreq->addr);
+ break;
+ case ZM_IOCTL_RTS:
+ zfiWlanSetRtsThreshold(dev, zdreq->addr);
+ break;
+ case ZM_IOCTL_SCAN:
+ zfiWlanScan(dev);
+ break;
+ case ZM_IOCTL_KEY: {
+ u8_t key[29];
+ struct zsKeyInfo keyInfo;
+ u32_t i;
+
+ for (i = 0; i < 29; i++)
+ key[i] = 0;
+
+ for (i = 0; i < zdreq->addr; i++)
+ key[i] = zdreq->data[i];
+
+ printk(KERN_WARNING
+ "key len=%d, key=%02x%02x%02x%02x%02x...\n",
+ zdreq->addr, key[0], key[1], key[2], key[3], key[4]);
+
+ keyInfo.keyLength = zdreq->addr;
+ keyInfo.keyIndex = 0;
+ keyInfo.flag = 0;
+ keyInfo.key = key;
+ zfiWlanSetKey(dev, keyInfo);
+ }
+ break;
+ case ZM_IOCTL_RATE:
+ zfiWlanSetTxRate(dev, zdreq->addr);
+ break;
+ case ZM_IOCTL_ENCRYPTION_MODE:
+ zfiWlanSetEncryMode(dev, zdreq->addr);
+
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
+ break;
+ /* CWYang(+) */
+ case ZM_IOCTL_SIGNAL_STRENGTH: {
+ u8_t buffer[2];
+ zfiWlanQuerySignalInfo(dev, &buffer[0]);
+ printk(KERN_WARNING
+ "Current Signal Strength : %02d\n", buffer[0]);
+ }
+ break;
+ /* CWYang(+) */
+ case ZM_IOCTL_SIGNAL_QUALITY: {
+ u8_t buffer[2];
+ zfiWlanQuerySignalInfo(dev, &buffer[0]);
+ printk(KERN_WARNING
+ "Current Signal Quality : %02d\n", buffer[1]);
+ }
+ break;
case ZM_IOCTL_SET_PIBSS_MODE:
if (zdreq->addr == 1)
zfiWlanSetWlanMode(dev, ZM_MODE_PSEUDO);
@@ -2107,11 +2027,9 @@ int zfLnxPrivateIoctl(struct net_device *dev, struct zdap_ioctl* zdreq)
zfiWlanDisable(dev, 0);
zfiWlanEnable(dev);
-
break;
-/****************************** ZDCONFIG ******************************/
-
- default :
+ /********************* ZDCONFIG ***********************/
+ default:
printk(KERN_ERR "usbdrv: error command = %x\n", cmd);
break;
}
@@ -2121,793 +2039,736 @@ int zfLnxPrivateIoctl(struct net_device *dev, struct zdap_ioctl* zdreq)
int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
{
- int ret = 0;
- u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- u8_t mac_addr[80];
- struct zsKeyInfo keyInfo;
- struct usbdrv_private *macp = dev->ml_priv;
- u16_t vapId = 0;
-
- //zmw_get_wlan_dev(dev);
-
- switch(zdparm->cmd)
- {
- case ZD_CMD_SET_ENCRYPT_KEY:
-
- /* Set up key information */
- keyInfo.keyLength = zdparm->u.crypt.key_len;
- keyInfo.keyIndex = zdparm->u.crypt.idx;
- if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) // AP Mode
- keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR;
- else
- keyInfo.flag = 0;
- keyInfo.key = zdparm->u.crypt.key;
- keyInfo.initIv = zdparm->u.crypt.seq;
- keyInfo.macAddr = (u16_t *)zdparm->sta_addr;
-
- /* Identify the MAC address information */
- if (memcmp(zdparm->sta_addr, bc_addr, sizeof(bc_addr)) == 0)
- {
- keyInfo.flag |= ZM_KEY_FLAG_GK;
- }
- else
- {
- keyInfo.flag |= ZM_KEY_FLAG_PK;
- }
-
- if (!strcmp(zdparm->u.crypt.alg, "NONE"))
- {
- //u8_t zero_mac[]={0,0,0,0,0,0};
-
- /* Set key length to zero */
- keyInfo.keyLength = 0;
-
- if (zdparm->sta_addr[0] & 1)//del group key
- {
- //if (macp->cardSetting.WPAIeLen==0)
- //{//802.1x dynamic WEP
- // mDynKeyMode = 0;
- // mKeyFormat[0] = 0;
- // mPrivacyInvoked[0]=FALSE;
- // mCap[0] &= ~CAP_PRIVACY;
- // macp->cardSetting.EncryOnOff[0]=0;
- //}
- //mWpaBcKeyLen = mGkInstalled = 0;
- }
- else
- {
- //if (memcmp(zero_mac,zdparm->sta_addr, 6)==0)
- //{
- // mDynKeyMode=0;
- // mKeyFormat[0]=0;
- // pSetting->DynKeyMode=0;
- // pSetting->EncryMode[0]=0;
- // mDynKeyMode=0;
- //}
- }
-
- printk(KERN_ERR "Set Encryption Type NONE\n");
- return ret;
- }
- else if (!strcmp(zdparm->u.crypt.alg, "TKIP"))
- {
- zfiWlanSetEncryMode(dev, ZM_TKIP);
- //Linux Supplicant will inverse Tx/Rx key
- //So we inverse it back //CWYang(+)
- //zfMemoryCopy(&temp[0], &keyInfo.key[16], 8);
- //zfMemoryCopy(&keyInfo.key[16], keyInfo.key[24], 8);
- //zfMemoryCopy(&keyInfo.key[24], &temp[0], 8);
- //u8_t temp;
- //int k;
- //for (k = 0; k < 8; k++)
- //{
- // temp = keyInfo.key[16 + k];
- // keyInfo.key[16 + k] = keyInfo.key[24 + k];
- // keyInfo.key[24 + k] = temp;
- //}
- //CamEncryType = ZM_TKIP;
- ////if (idx == 0)
- //{// Pairwise key
- // mKeyFormat[0] = CamEncryType;
- // mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_TKIP;
- //}
- }
- else if (!strcmp(zdparm->u.crypt.alg, "CCMP"))
- {
- zfiWlanSetEncryMode(dev, ZM_AES);
- //CamEncryType = ZM_AES;
- ////if (idx == 0)
- //{// Pairwise key
- // mKeyFormat[0] = CamEncryType;
- // mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_AES;
- //}
- }
- else if (!strcmp(zdparm->u.crypt.alg, "WEP"))
- {
- if (keyInfo.keyLength == 5)
- { // WEP 64
- zfiWlanSetEncryMode(dev, ZM_WEP64);
- // CamEncryType = ZM_WEP64;
- // tmpDynKeyMode=DYN_KEY_WEP64;
- }
- else if (keyInfo.keyLength == 13)
- {//keylen=13, WEP 128
- zfiWlanSetEncryMode(dev, ZM_WEP128);
- // CamEncryType = ZM_WEP128;
- // tmpDynKeyMode=DYN_KEY_WEP128;
- }
- else
- {
- zfiWlanSetEncryMode(dev, ZM_WEP256);
- }
-
- // For Dynamic WEP key (Non-WPA Radius), the key ID range: 0-3
- // In WPA/RSN mode, the key ID range: 1-3, usually, a broadcast key.
- // For WEP key setting: we set mDynKeyMode and mKeyFormat in following case:
- // 1. For 802.1x dynamically generated WEP key method.
- // 2. For WPA/RSN mode, but key id == 0. (But this is an impossible case)
- // So, only check case 1.
- //if (macp->cardSetting.WPAIeLen==0)
- //{
- // mKeyFormat[0] = CamEncryType;
- // mDynKeyMode = pSetting->DynKeyMode = tmpDynKeyMode;
- // mPrivacyInvoked[0]=TRUE;
- // mCap[0] |= CAP_PRIVACY;
- // macp->cardSetting.EncryOnOff[0]=1;
- //}
- }
-
- /* DUMP key context */
-//#ifdef WPA_DEBUG
- if (keyInfo.keyLength > 0)
- {
- int ii;
- printk("Otus: Key Context:\n");
- for(ii = 0; ii < keyInfo.keyLength;)
- {
- printk("0x%02x ", keyInfo.key[ii]);
- if((++ii % 16) == 0)
- printk("\n");
- }
- printk("\n");
- }
-//#endif
-
- /* Set encrypt mode */
- //zfiWlanSetEncryMode(dev, CamEncryType);
- vapId = zfLnxGetVapId(dev);
- if (vapId == 0xffff)
- keyInfo.vapId = 0;
- else
- keyInfo.vapId = vapId + 1;
- keyInfo.vapAddr[0] = keyInfo.macAddr[0];
- keyInfo.vapAddr[1] = keyInfo.macAddr[1];
- keyInfo.vapAddr[2] = keyInfo.macAddr[2];
-
- zfiWlanSetKey(dev, keyInfo);
-
- //zfiWlanDisable(dev);
- //zfiWlanEnable(dev);
- break;
-
- case ZD_CMD_SET_MLME:
- printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SET_MLME\n");
-
- /* Translate STA's address */
- sprintf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x", zdparm->sta_addr[0], zdparm->sta_addr[1],
- zdparm->sta_addr[2], zdparm->sta_addr[3], zdparm->sta_addr[4], zdparm->sta_addr[5]);
-
- switch(zdparm->u.mlme.cmd)
- {
- case MLME_STA_DEAUTH:
- printk(" -------Call zfiWlanDeauth, reason:%d\n",zdparm->u.mlme.reason_code);
- if(zfiWlanDeauth(dev, (u16_t*) zdparm->sta_addr, zdparm->u.mlme.reason_code) != 0)
- printk(KERN_ERR "Can't deauthencate STA: %s\n", mac_addr);
- else
- printk(KERN_ERR "Deauthenticate STA: %s with reason code: %d\n", mac_addr, zdparm->u.mlme.reason_code);
- break;
-
- case MLME_STA_DISASSOC:
- printk(" -------Call zfiWlanDeauth, reason:%d\n",zdparm->u.mlme.reason_code);
- if(zfiWlanDeauth(dev, (u16_t*) zdparm->sta_addr, zdparm->u.mlme.reason_code) != 0)
- printk(KERN_ERR "Can't disassociate STA: %s\n", mac_addr);
- else
- printk(KERN_ERR "Disassociate STA: %s with reason code: %d\n", mac_addr, zdparm->u.mlme.reason_code);
- break;
-
- default:
- printk(KERN_ERR "MLME command: 0x%04x not support\n", zdparm->u.mlme.cmd);
- break;
- }
-
- break;
-
- case ZD_CMD_SCAN_REQ:
- printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SCAN_REQ\n");
- break;
-
- case ZD_CMD_SET_GENERIC_ELEMENT:
- printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SET_GENERIC_ELEMENT\n");
-
- /* Copy the WPA IE */
- //zm_msg1_mm(ZM_LV_0, "CWY - wpaie Length : ", zdparm->u.generic_elem.len);
- printk(KERN_ERR "wpaie Length : %d\n", zdparm->u.generic_elem.len);
- if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) // AP Mode
- {
- zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data, zdparm->u.generic_elem.len);
- }
- else
- {
- macp->supLen = zdparm->u.generic_elem.len;
- memcpy(macp->supIe, zdparm->u.generic_elem.data, zdparm->u.generic_elem.len);
- }
- zfiWlanSetWpaSupport(dev, 1);
- //zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data, zdparm->u.generic_elem.len);
- {
- int ii;
- u8_t len = zdparm->u.generic_elem.len;
- u8_t *wpaie = (u8_t *)zdparm->u.generic_elem.data;
-
- printk(KERN_ERR "wd->ap.wpaLen: %d\n", len);
-
- /* DUMP WPA IE */
- for(ii = 0; ii < len;)
- {
- printk(KERN_ERR "0x%02x ", wpaie[ii]);
-
- if((++ii % 16) == 0)
- printk(KERN_ERR "\n");
- }
- printk(KERN_ERR "\n");
- }
-
-// #ifdef ZM_HOSTAPD_SUPPORT
- //if (wd->wlanMode == ZM_MODE_AP)
- //{// Update Beacon FIFO in the next TBTT.
- // memcpy(&mWPAIe, pSetting->WPAIe, pSetting->WPAIeLen);
- // printk(KERN_ERR "Copy WPA IE into mWPAIe\n");
- //}
-// #endif
- break;
-
-// #ifdef ZM_HOSTAPD_SUPPORT
- case ZD_CMD_GET_TSC:
- printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_GET_TSC\n");
- break;
-// #endif
-
- default:
- printk(KERN_ERR "usbdrv_wpa_ioctl default: 0x%04x\n", zdparm->cmd);
- ret = -EINVAL;
- break;
- }
-
- return ret;
+ int ret = 0;
+ u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ u8_t mac_addr[80];
+ struct zsKeyInfo keyInfo;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u16_t vapId = 0;
+
+ /* zmw_get_wlan_dev(dev); */
+
+ switch (zdparm->cmd) {
+ case ZD_CMD_SET_ENCRYPT_KEY:
+ /* Set up key information */
+ keyInfo.keyLength = zdparm->u.crypt.key_len;
+ keyInfo.keyIndex = zdparm->u.crypt.idx;
+ if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
+ /* AP Mode */
+ keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR;
+ } else
+ keyInfo.flag = 0;
+ keyInfo.key = zdparm->u.crypt.key;
+ keyInfo.initIv = zdparm->u.crypt.seq;
+ keyInfo.macAddr = (u16_t *)zdparm->sta_addr;
+
+ /* Identify the MAC address information */
+ if (memcmp(zdparm->sta_addr, bc_addr, sizeof(bc_addr)) == 0)
+ keyInfo.flag |= ZM_KEY_FLAG_GK;
+ else
+ keyInfo.flag |= ZM_KEY_FLAG_PK;
+
+ if (!strcmp(zdparm->u.crypt.alg, "NONE")) {
+ /* u8_t zero_mac[]={0,0,0,0,0,0}; */
+
+ /* Set key length to zero */
+ keyInfo.keyLength = 0;
+
+ /* del group key */
+ if (zdparm->sta_addr[0] & 1) {
+ /* if (macp->cardSetting.WPAIeLen==0)
+ * { 802.1x dynamic WEP
+ * mDynKeyMode = 0;
+ * mKeyFormat[0] = 0;
+ * mPrivacyInvoked[0]=FALSE;
+ * mCap[0] &= ~CAP_PRIVACY;
+ * macp->cardSetting.EncryOnOff[0]=0;
+ * }
+ * mWpaBcKeyLen = mGkInstalled = 0;
+ */
+ } else {
+ /* if (memcmp(zero_mac,zdparm->sta_addr, 6)==0)
+ * {
+ * mDynKeyMode=0;
+ * mKeyFormat[0]=0;
+ * pSetting->DynKeyMode=0;
+ * pSetting->EncryMode[0]=0;
+ * mDynKeyMode=0;
+ * }
+ */
+ }
+
+ printk(KERN_ERR "Set Encryption Type NONE\n");
+ return ret;
+ } else if (!strcmp(zdparm->u.crypt.alg, "TKIP")) {
+ zfiWlanSetEncryMode(dev, ZM_TKIP);
+ /* //Linux Supplicant will inverse Tx/Rx key
+ * //So we inverse it back, CWYang(+)
+ * zfMemoryCopy(&temp[0], &keyInfo.key[16], 8);
+ * zfMemoryCopy(&keyInfo.key[16], keyInfo.key[24], 8);
+ * zfMemoryCopy(&keyInfo.key[24], &temp[0], 8);
+ * u8_t temp;
+ * int k;
+ * for (k = 0; k < 8; k++)
+ * {
+ * temp = keyInfo.key[16 + k];
+ * keyInfo.key[16 + k] = keyInfo.key[24 + k];
+ * keyInfo.key[24 + k] = temp;
+ * }
+ * CamEncryType = ZM_TKIP;
+ * if (idx == 0)
+ * { // Pairwise key
+ * mKeyFormat[0] = CamEncryType;
+ * mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_TKIP;
+ * }
+ */
+ } else if (!strcmp(zdparm->u.crypt.alg, "CCMP")) {
+ zfiWlanSetEncryMode(dev, ZM_AES);
+ /* CamEncryType = ZM_AES;
+ * if (idx == 0)
+ * { // Pairwise key
+ * mKeyFormat[0] = CamEncryType;
+ * mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_AES;
+ * }
+ */
+ } else if (!strcmp(zdparm->u.crypt.alg, "WEP")) {
+ if (keyInfo.keyLength == 5) {
+ /* WEP 64 */
+ zfiWlanSetEncryMode(dev, ZM_WEP64);
+ /* CamEncryType = ZM_WEP64; */
+ /* tmpDynKeyMode=DYN_KEY_WEP64; */
+ } else if (keyInfo.keyLength == 13) {
+ /* keylen=13, WEP 128 */
+ zfiWlanSetEncryMode(dev, ZM_WEP128);
+ /* CamEncryType = ZM_WEP128; */
+ /* tmpDynKeyMode=DYN_KEY_WEP128; */
+ } else {
+ zfiWlanSetEncryMode(dev, ZM_WEP256);
+ }
+
+ /* For Dynamic WEP key (Non-WPA Radius), the key ID range: 0-3
+ * In WPA/RSN mode, the key ID range: 1-3, usually, a broadcast key.
+ * For WEP key setting: we set mDynKeyMode and mKeyFormat in following
+ * case:
+ * 1. For 802.1x dynamically generated WEP key method.
+ * 2. For WPA/RSN mode, but key id == 0.
+ * (But this is an impossible case)
+ * So, only check case 1.
+ * if (macp->cardSetting.WPAIeLen==0)
+ * {
+ * mKeyFormat[0] = CamEncryType;
+ * mDynKeyMode = pSetting->DynKeyMode = tmpDynKeyMode;
+ * mPrivacyInvoked[0]=TRUE;
+ * mCap[0] |= CAP_PRIVACY;
+ * macp->cardSetting.EncryOnOff[0]=1;
+ * }
+ */
+ }
+
+ /* DUMP key context */
+ /* #ifdef WPA_DEBUG */
+ if (keyInfo.keyLength > 0) {
+ int ii;
+ printk(KERN_WARNING
+ "Otus: Key Context:\n");
+ for (ii = 0; ii < keyInfo.keyLength; ) {
+ printk(KERN_WARNING
+ "0x%02x ", keyInfo.key[ii]);
+ if ((++ii % 16) == 0)
+ printk(KERN_WARNING "\n");
+ }
+ printk(KERN_WARNING "\n");
+ }
+ /* #endif */
+
+ /* Set encrypt mode */
+ /* zfiWlanSetEncryMode(dev, CamEncryType); */
+ vapId = zfLnxGetVapId(dev);
+ if (vapId == 0xffff)
+ keyInfo.vapId = 0;
+ else
+ keyInfo.vapId = vapId + 1;
+ keyInfo.vapAddr[0] = keyInfo.macAddr[0];
+ keyInfo.vapAddr[1] = keyInfo.macAddr[1];
+ keyInfo.vapAddr[2] = keyInfo.macAddr[2];
+
+ zfiWlanSetKey(dev, keyInfo);
+
+ /* zfiWlanDisable(dev); */
+ /* zfiWlanEnable(dev); */
+ break;
+ case ZD_CMD_SET_MLME:
+ printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SET_MLME\n");
+
+ /* Translate STA's address */
+ sprintf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x",
+ zdparm->sta_addr[0], zdparm->sta_addr[1],
+ zdparm->sta_addr[2], zdparm->sta_addr[3],
+ zdparm->sta_addr[4], zdparm->sta_addr[5]);
+
+ switch (zdparm->u.mlme.cmd) {
+ case MLME_STA_DEAUTH:
+ printk(KERN_WARNING
+ " -------Call zfiWlanDeauth, reason:%d\n",
+ zdparm->u.mlme.reason_code);
+ if (zfiWlanDeauth(dev, (u16_t *) zdparm->sta_addr,
+ zdparm->u.mlme.reason_code) != 0)
+ printk(KERN_ERR "Can't deauthencate STA: %s\n",
+ mac_addr);
+ else
+ printk(KERN_ERR "Deauthenticate STA: %s"
+ "with reason code: %d\n",
+ mac_addr, zdparm->u.mlme.reason_code);
+ break;
+ case MLME_STA_DISASSOC:
+ printk(KERN_WARNING
+ " -------Call zfiWlanDeauth, reason:%d\n",
+ zdparm->u.mlme.reason_code);
+ if (zfiWlanDeauth(dev, (u16_t *) zdparm->sta_addr,
+ zdparm->u.mlme.reason_code) != 0)
+ printk(KERN_ERR "Can't disassociate STA: %s\n",
+ mac_addr);
+ else
+ printk(KERN_ERR "Disassociate STA: %s"
+ "with reason code: %d\n",
+ mac_addr, zdparm->u.mlme.reason_code);
+ break;
+ default:
+ printk(KERN_ERR "MLME command: 0x%04x not support\n",
+ zdparm->u.mlme.cmd);
+ break;
+ }
+
+ break;
+ case ZD_CMD_SCAN_REQ:
+ printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SCAN_REQ\n");
+ break;
+ case ZD_CMD_SET_GENERIC_ELEMENT:
+ printk(KERN_ERR "usbdrv_wpa_ioctl:"
+ " ZD_CMD_SET_GENERIC_ELEMENT\n");
+
+ /* Copy the WPA IE
+ * zm_msg1_mm(ZM_LV_0, "CWY - wpaie Length : ",
+ * zdparm->u.generic_elem.len);
+ */
+ printk(KERN_ERR "wpaie Length : % d\n",
+ zdparm->u.generic_elem.len);
+ if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
+ /* AP Mode */
+ zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data,
+ zdparm->u.generic_elem.len);
+ } else {
+ macp->supLen = zdparm->u.generic_elem.len;
+ memcpy(macp->supIe, zdparm->u.generic_elem.data,
+ zdparm->u.generic_elem.len);
+ }
+ zfiWlanSetWpaSupport(dev, 1);
+ /* zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data,
+ * zdparm->u.generic_elem.len);
+ */
+ int ii;
+ u8_t len = zdparm->u.generic_elem.len;
+ u8_t *wpaie = (u8_t *)zdparm->u.generic_elem.data;
+
+ printk(KERN_ERR "wd->ap.wpaLen : % d\n", len);
+
+ /* DUMP WPA IE */
+ for(ii = 0; ii < len;) {
+ printk(KERN_ERR "0x%02x ", wpaie[ii]);
+
+ if((++ii % 16) == 0)
+ printk(KERN_ERR "\n");
+ }
+ printk(KERN_ERR "\n");
+
+ /* #ifdef ZM_HOSTAPD_SUPPORT
+ * if (wd->wlanMode == ZM_MODE_AP)
+ * {// Update Beacon FIFO in the next TBTT.
+ * memcpy(&mWPAIe, pSetting->WPAIe, pSetting->WPAIeLen);
+ * printk(KERN_ERR "Copy WPA IE into mWPAIe\n");
+ * }
+ * #endif
+ */
+ break;
+
+ /* #ifdef ZM_HOSTAPD_SUPPORT */
+ case ZD_CMD_GET_TSC:
+ printk(KERN_ERR "usbdrv_wpa_ioctl : ZD_CMD_GET_TSC\n");
+ break;
+ /* #endif */
+
+ default:
+ printk(KERN_ERR "usbdrv_wpa_ioctl default : 0x%04x\n",
+ zdparm->cmd);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
}
#ifdef ZM_ENABLE_CENC
int usbdrv_cenc_ioctl(struct net_device *dev, struct zydas_cenc_param *zdparm)
{
- //struct usbdrv_private *macp = dev->ml_priv;
- struct zsKeyInfo keyInfo;
- u16_t apId;
- u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- int ret = 0;
- int ii;
-
- /* Get the AP Id */
- apId = zfLnxGetVapId(dev);
-
- if (apId == 0xffff)
- {
- apId = 0;
- }
- else
- {
- apId = apId+1;
- }
-
- switch (zdparm->cmd)
- {
- case ZM_CMD_CENC_SETCENC:
- printk(KERN_ERR "ZM_CMD_CENC_SETCENC\n");
- printk(KERN_ERR "length: %d\n", zdparm->len);
- printk(KERN_ERR "policy: %d\n", zdparm->u.info.cenc_policy);
- break;
- case ZM_CMD_CENC_SETKEY:
- //ret = wai_ioctl_setkey(vap, ioctl_msg);
- printk(KERN_ERR "ZM_CMD_CENC_SETKEY\n");
-
- printk(KERN_ERR "MAC address= ");
- for(ii = 0; ii < 6; ii++)
- {
- printk(KERN_ERR "0x%02x ", zdparm->u.crypt.sta_addr[ii]);
- }
- printk(KERN_ERR "\n");
-
- printk(KERN_ERR "Key Index: %d\n", zdparm->u.crypt.keyid);
- printk(KERN_ERR "Encryption key= ");
- for(ii = 0; ii < 16; ii++)
- {
- printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
- }
- printk(KERN_ERR "\n");
-
- printk(KERN_ERR "MIC key= ");
- for(ii = 16; ii < ZM_CENC_KEY_SIZE; ii++)
- {
- printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
- }
- printk(KERN_ERR "\n");
-
- /* Set up key information */
- keyInfo.keyLength = ZM_CENC_KEY_SIZE;
- keyInfo.keyIndex = zdparm->u.crypt.keyid;
- keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR | ZM_KEY_FLAG_CENC;
- keyInfo.key = zdparm->u.crypt.key;
- keyInfo.macAddr = (u16_t *)zdparm->u.crypt.sta_addr;
-
- /* Identify the MAC address information */
- if (memcmp(zdparm->u.crypt.sta_addr, bc_addr, sizeof(bc_addr)) == 0)
- {
- keyInfo.flag |= ZM_KEY_FLAG_GK;
- keyInfo.vapId = apId;
- memcpy(keyInfo.vapAddr, dev->dev_addr, ETH_ALEN);
- }
- else
- {
- keyInfo.flag |= ZM_KEY_FLAG_PK;
- }
-
- zfiWlanSetKey(dev, keyInfo);
-
- break;
- case ZM_CMD_CENC_REKEY:
- //ret = wai_ioctl_rekey(vap, ioctl_msg);
- printk(KERN_ERR "ZM_CMD_CENC_REKEY\n");
- break;
- default:
- ret = -EOPNOTSUPP;
- break;
-
- }
-
- //if (retv == ENETRESET)
- // retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0;
-
- return ret;
-}
-#endif //ZM_ENABLE_CENC
-/////////////////////////////////////////
-int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
-// struct usbdrv_private *macp;
-// void *regp;
- struct zdap_ioctl zdreq;
- struct iwreq *wrq = (struct iwreq *)ifr;
- struct athr_wlan_param zdparm;
- struct usbdrv_private *macp = dev->ml_priv;
+ /* struct usbdrv_private *macp = dev->ml_priv; */
+ struct zsKeyInfo keyInfo;
+ u16_t apId;
+ u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ int ret = 0;
+ int ii;
+
+ /* Get the AP Id */
+ apId = zfLnxGetVapId(dev);
+
+ if (apId == 0xffff) {
+ apId = 0;
+ } else {
+ apId = apId + 1;
+ }
- int err = 0;
- int changed = 0;
+ switch (zdparm->cmd) {
+ case ZM_CMD_CENC_SETCENC:
+ printk(KERN_ERR "ZM_CMD_CENC_SETCENC\n");
+ printk(KERN_ERR "length : % d\n", zdparm->len);
+ printk(KERN_ERR "policy : % d\n", zdparm->u.info.cenc_policy);
+ break;
+ case ZM_CMD_CENC_SETKEY:
+ /* ret = wai_ioctl_setkey(vap, ioctl_msg); */
+ printk(KERN_ERR "ZM_CMD_CENC_SETKEY\n");
+
+ printk(KERN_ERR "MAC address = ");
+ for (ii = 0; ii < 6; ii++) {
+ printk(KERN_ERR "0x%02x ",
+ zdparm->u.crypt.sta_addr[ii]);
+ }
+ printk(KERN_ERR "\n");
-// regp = macp->regp;
+ printk(KERN_ERR "Key Index : % d\n", zdparm->u.crypt.keyid);
+ printk(KERN_ERR "Encryption key = ");
+ for (ii = 0; ii < 16; ii++) {
+ printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
+ }
+ printk(KERN_ERR "\n");
- if(!netif_running(dev))
- return -EINVAL;
+ printk(KERN_ERR "MIC key = ");
+ for(ii = 16; ii < ZM_CENC_KEY_SIZE; ii++) {
+ printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
+ }
+ printk(KERN_ERR "\n");
+
+ /* Set up key information */
+ keyInfo.keyLength = ZM_CENC_KEY_SIZE;
+ keyInfo.keyIndex = zdparm->u.crypt.keyid;
+ keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR | ZM_KEY_FLAG_CENC;
+ keyInfo.key = zdparm->u.crypt.key;
+ keyInfo.macAddr = (u16_t *)zdparm->u.crypt.sta_addr;
+
+ /* Identify the MAC address information */
+ if (memcmp(zdparm->u.crypt.sta_addr, bc_addr,
+ sizeof(bc_addr)) == 0) {
+ keyInfo.flag |= ZM_KEY_FLAG_GK;
+ keyInfo.vapId = apId;
+ memcpy(keyInfo.vapAddr, dev->dev_addr, ETH_ALEN);
+ } else {
+ keyInfo.flag |= ZM_KEY_FLAG_PK;
+ }
- switch (cmd)
- {
- case SIOCGIWNAME:
- strcpy(wrq->u.name, "IEEE 802.11-DS");
- break;
+ zfiWlanSetKey(dev, keyInfo);
- case SIOCGIWAP:
- err = usbdrvwext_giwap(dev, NULL, &wrq->u.ap_addr, NULL);
- break;
+ break;
+ case ZM_CMD_CENC_REKEY:
+ /* ret = wai_ioctl_rekey(vap, ioctl_msg); */
+ printk(KERN_ERR "ZM_CMD_CENC_REKEY\n");
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+ /* if (retv == ENETRESET) */
+ /* retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0; */
- case SIOCSIWAP:
- err = usbdrvwext_siwap(dev, NULL, &wrq->u.ap_addr, NULL);
- break;
+ return ret;
+}
+#endif /* ZM_ENABLE_CENC */
+int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ /* struct usbdrv_private *macp; */
+ /* void *regp; */
+ struct zdap_ioctl zdreq;
+ struct iwreq *wrq = (struct iwreq *)ifr;
+ struct athr_wlan_param zdparm;
+ struct usbdrv_private *macp = dev->ml_priv;
- case SIOCGIWMODE:
- err = usbdrvwext_giwmode(dev, NULL, &wrq->u.mode, NULL);
- break;
+ int err = 0;
+ int changed = 0;
+ /* regp = macp->regp; */
- case SIOCSIWESSID:
- printk(KERN_ERR "CWY - usbdrvwext_siwessid\n");
- //err = usbdrv_ioctl_setessid(dev, &wrq->u.essid);
- err = usbdrvwext_siwessid(dev, NULL, &wrq->u.essid, NULL);
+ if (!netif_running(dev))
+ return -EINVAL;
- if (! err)
- changed = 1;
- break;
+ switch (cmd) {
+ case SIOCGIWNAME:
+ strcpy(wrq->u.name, "IEEE 802.11-DS");
+ break;
+ case SIOCGIWAP:
+ err = usbdrvwext_giwap(dev, NULL, &wrq->u.ap_addr, NULL);
+ break;
+ case SIOCSIWAP:
+ err = usbdrvwext_siwap(dev, NULL, &wrq->u.ap_addr, NULL);
+ break;
+ case SIOCGIWMODE:
+ err = usbdrvwext_giwmode(dev, NULL, &wrq->u.mode, NULL);
+ break;
+ case SIOCSIWESSID:
+ printk(KERN_ERR "CWY - usbdrvwext_siwessid\n");
+ /* err = usbdrv_ioctl_setessid(dev, &wrq->u.essid); */
+ err = usbdrvwext_siwessid(dev, NULL, &wrq->u.essid, NULL);
+ if (!err)
+ changed = 1;
+ break;
+ case SIOCGIWESSID:
+ err = usbdrvwext_giwessid(dev, NULL, &wrq->u.essid, NULL);
+ break;
+ case SIOCSIWRTS:
+ err = usbdrv_ioctl_setrts(dev, &wrq->u.rts);
+ if (! err)
+ changed = 1;
+ break;
+ /* set_auth */
+ case SIOCIWFIRSTPRIV + 0x2: {
+ /* printk("CWY - SIOCIWFIRSTPRIV + 0x2(set_auth)\n"); */
+ if (!capable(CAP_NET_ADMIN)) {
+ err = -EPERM;
+ break;
+ }
+ int val = *((int *) wrq->u.name);
+ if ((val < 0) || (val > 2)) {
+ err = -EINVAL;
+ break;
+ } else {
+ zfiWlanSetAuthenticationMode(dev, val);
- case SIOCGIWESSID:
- err = usbdrvwext_giwessid(dev, NULL, &wrq->u.essid, NULL);
- break;
+ if (macp->DeviceOpened == 1) {
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
+ }
+ err = 0;
+ changed = 1;
+ }
+ }
+ break;
+ /* get_auth */
+ case SIOCIWFIRSTPRIV + 0x3: {
+ int AuthMode = ZM_AUTH_MODE_OPEN;
- case SIOCSIWRTS:
+ /* printk("CWY - SIOCIWFIRSTPRIV + 0x3(get_auth)\n"); */
- err = usbdrv_ioctl_setrts(dev, &wrq->u.rts);
- if (! err)
- changed = 1;
- break;
+ if (wrq->u.data.pointer) {
+ wrq->u.data.flags = 1;
+ AuthMode = zfiWlanQueryAuthenticationMode(dev, 0);
+ if (AuthMode == ZM_AUTH_MODE_OPEN) {
+ wrq->u.data.length = 12;
- case SIOCIWFIRSTPRIV + 0x2: /* set_auth */
- {
- //printk("CWY - SIOCIWFIRSTPRIV + 0x2 (set_auth)\n");
- if (! capable(CAP_NET_ADMIN))
- {
- err = -EPERM;
- break;
- }
- {
- int val = *( (int *) wrq->u.name );
- if ((val < 0) || (val > 2))
- {
- err = -EINVAL;
- break;
+ if (copy_to_user(wrq->u.data.pointer,
+ "open system", 12)) {
+ return -EFAULT;
}
- else
- {
- zfiWlanSetAuthenticationMode(dev, val);
+ } else if (AuthMode == ZM_AUTH_MODE_SHARED_KEY) {
+ wrq->u.data.length = 11;
- if (macp->DeviceOpened == 1)
- {
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
- }
+ if (copy_to_user(wrq->u.data.pointer,
+ "shared key", 11)) {
+ return -EFAULT;
+ }
+ } else if (AuthMode == ZM_AUTH_MODE_AUTO) {
+ wrq->u.data.length = 10;
- err = 0;
- changed = 1;
+ if (copy_to_user(wrq->u.data.pointer,
+ "auto mode", 10)) {
+ return -EFAULT;
}
+ } else {
+ return -EFAULT;
}
}
- break;
-
- case SIOCIWFIRSTPRIV + 0x3: /* get_auth */
- {
- int AuthMode = ZM_AUTH_MODE_OPEN;
-
- //printk("CWY - SIOCIWFIRSTPRIV + 0x3 (get_auth)\n");
+ }
+ break;
+ /* debug command */
+ case ZDAPIOCTL:
+ if (copy_from_user(&zdreq, ifr->ifr_data, sizeof(zdreq))) {
+ printk(KERN_ERR "usbdrv : copy_from_user error\n");
+ return -EFAULT;
+ }
- if (wrq->u.data.pointer)
- {
- wrq->u.data.flags = 1;
+ /* printk(KERN_WARNING
+ * "usbdrv : cmd = % 2x, reg = 0x%04lx,
+ *value = 0x%08lx\n",
+ * zdreq.cmd, zdreq.addr, zdreq.value);
+ */
+ zfLnxPrivateIoctl(dev, &zdreq);
- AuthMode = zfiWlanQueryAuthenticationMode(dev, 0);
- if (AuthMode == ZM_AUTH_MODE_OPEN)
- {
- wrq->u.data.length = 12;
+ err = 0;
+ break;
+ case ZD_IOCTL_WPA:
+ if (copy_from_user(&zdparm, ifr->ifr_data,
+ sizeof(struct athr_wlan_param))) {
+ printk(KERN_ERR "usbdrv : copy_from_user error\n");
+ return -EFAULT;
+ }
- if (copy_to_user(wrq->u.data.pointer, "open system", 12))
+ usbdrv_wpa_ioctl(dev, &zdparm);
+ err = 0;
+ break;
+ case ZD_IOCTL_PARAM: {
+ int *p;
+ int op;
+ int arg;
+
+ /* Point to the name field and retrieve the
+ * op and arg elements.
+ */
+ p = (int *)wrq->u.name;
+ op = *p++;
+ arg = *p;
+
+ if (op == ZD_PARAM_ROAMING) {
+ printk(KERN_ERR
+ "*************ZD_PARAM_ROAMING : % d\n", arg);
+ /* macp->cardSetting.ap_scan=(U8)arg; */
+ }
+ if (op == ZD_PARAM_PRIVACY) {
+ printk(KERN_ERR "ZD_IOCTL_PRIVACY : ");
+
+ /* Turn on the privacy invoke flag */
+ if (arg) {
+ /* mCap[0] |= CAP_PRIVACY; */
+ /* macp->cardSetting.EncryOnOff[0] = 1; */
+ printk(KERN_ERR "enable\n");
+
+ } else {
+ /* mCap[0] &= ~CAP_PRIVACY; */
+ /* macp->cardSetting.EncryOnOff[0] = 0; */
+ printk(KERN_ERR "disable\n");
+ }
+ /* changed=1; */
+ }
+ if (op == ZD_PARAM_WPA) {
+
+ printk(KERN_ERR "ZD_PARAM_WPA : ");
+
+ if (arg) {
+ printk(KERN_ERR "enable\n");
+
+ if (zfiWlanQueryWlanMode(dev) != ZM_MODE_AP) {
+ printk(KERN_ERR "Station Mode\n");
+ /* zfiWlanQueryWpaIe(dev, (u8_t *)
+ &wpaIe, &wpalen); */
+ /* printk("wpaIe : % 2x, % 2x, % 2x\n",
+ wpaIe[21], wpaIe[22], wpaIe[23]); */
+ /* printk("rsnIe : % 2x, % 2x, % 2x\n",
+ wpaIe[17], wpaIe[18], wpaIe[19]); */
+ if ((macp->supIe[21] == 0x50) &&
+ (macp->supIe[22] == 0xf2) &&
+ (macp->supIe[23] == 0x2)) {
+ printk(KERN_ERR
+ "wd->sta.authMode = ZM_AUTH_MODE_WPAPSK\n");
+ /* wd->sta.authMode = ZM_AUTH_MODE_WPAPSK; */
+ /* wd->ws.authMode = ZM_AUTH_MODE_WPAPSK; */
+ zfiWlanSetAuthenticationMode(dev,
+ ZM_AUTH_MODE_WPAPSK);
+ } else if ((macp->supIe[21] == 0x50) &&
+ (macp->supIe[22] == 0xf2) &&
+ (macp->supIe[23] == 0x1)) {
+ printk(KERN_ERR
+ "wd->sta.authMode = ZM_AUTH_MODE_WPA\n");
+ /* wd->sta.authMode = ZM_AUTH_MODE_WPA; */
+ /* wd->ws.authMode = ZM_AUTH_MODE_WPA; */
+ zfiWlanSetAuthenticationMode(dev,
+ ZM_AUTH_MODE_WPA);
+ } else if ((macp->supIe[17] == 0xf) &&
+ (macp->supIe[18] == 0xac) &&
+ (macp->supIe[19] == 0x2))
{
- return -EFAULT;
- }
- }
- else if (AuthMode == ZM_AUTH_MODE_SHARED_KEY)
+ printk(KERN_ERR
+ "wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK\n");
+ /* wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK; */
+ /* wd->ws.authMode = ZM_AUTH_MODE_WPA2PSK; */
+ zfiWlanSetAuthenticationMode(dev,
+ ZM_AUTH_MODE_WPA2PSK);
+ } else if ((macp->supIe[17] == 0xf) &&
+ (macp->supIe[18] == 0xac) &&
+ (macp->supIe[19] == 0x1))
{
- wrq->u.data.length = 11;
-
- if (copy_to_user(wrq->u.data.pointer, "shared key", 11))
- {
- return -EFAULT;
- }
+ printk(KERN_ERR
+ "wd->sta.authMode = ZM_AUTH_MODE_WPA2\n");
+ /* wd->sta.authMode = ZM_AUTH_MODE_WPA2; */
+ /* wd->ws.authMode = ZM_AUTH_MODE_WPA2; */
+ zfiWlanSetAuthenticationMode(dev,
+ ZM_AUTH_MODE_WPA2);
+ }
+ /* WPA or WPAPSK */
+ if ((macp->supIe[21] == 0x50) ||
+ (macp->supIe[22] == 0xf2)) {
+ if (macp->supIe[11] == 0x2) {
+ printk(KERN_ERR
+ "wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
+ /* wd->sta.wepStatus = ZM_ENCRYPTION_TKIP; */
+ /* wd->ws.wepStatus = ZM_ENCRYPTION_TKIP; */
+ zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
+ } else {
+ printk(KERN_ERR
+ "wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
+ /* wd->sta.wepStatus = ZM_ENCRYPTION_AES; */
+ /* wd->ws.wepStatus = ZM_ENCRYPTION_AES; */
+ zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
}
- else if (AuthMode == ZM_AUTH_MODE_AUTO)
- {
- wrq->u.data.length = 10;
-
- if (copy_to_user(wrq->u.data.pointer, "auto mode", 10))
- {
- return -EFAULT;
+ }
+ //WPA2 or WPA2PSK
+ if ((macp->supIe[17] == 0xf) ||
+ (macp->supIe[18] == 0xac)) {
+ if (macp->supIe[13] == 0x2) {
+ printk(KERN_ERR
+ "wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
+ /* wd->sta.wepStatus = ZM_ENCRYPTION_TKIP; */
+ /* wd->ws.wepStatus = ZM_ENCRYPTION_TKIP; */
+ zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
+ } else {
+ printk(KERN_ERR
+ "wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
+ /* wd->sta.wepStatus = ZM_ENCRYPTION_AES; */
+ /* wd->ws.wepStatus = ZM_ENCRYPTION_AES; */
+ zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
}
}
- else
- {
- return -EFAULT;
- }
}
+ zfiWlanSetWpaSupport(dev, 1);
+ } else {
+ /* Reset the WPA related variables */
+ printk(KERN_ERR "disable\n");
+
+ zfiWlanSetWpaSupport(dev, 0);
+ zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_OPEN);
+ zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_WEP_DISABLED);
+
+ /* Now we only set the length in the WPA IE
+ * field to zero.
+ *macp->cardSetting.WPAIe[1] = 0;
+ */
+ }
+ }
+
+ if (op == ZD_PARAM_COUNTERMEASURES) {
+ printk(KERN_ERR
+ "****************ZD_PARAM_COUNTERMEASURES : ");
+
+ if(arg) {
+ /* mCounterMeasureState=1; */
+ printk(KERN_ERR "enable\n");
+ } else {
+ /* mCounterMeasureState=0; */
+ printk(KERN_ERR "disable\n");
+ }
+ }
+ if (op == ZD_PARAM_DROPUNENCRYPTED) {
+ printk(KERN_ERR "ZD_PARAM_DROPUNENCRYPTED : ");
+
+ if(arg) {
+ printk(KERN_ERR "enable\n");
+ } else {
+ printk(KERN_ERR "disable\n");
+ }
+ }
+ if (op == ZD_PARAM_AUTH_ALGS) {
+ printk(KERN_ERR "ZD_PARAM_AUTH_ALGS : ");
+
+ if (arg == 0) {
+ printk(KERN_ERR "OPEN_SYSTEM\n");
+ } else {
+ printk(KERN_ERR "SHARED_KEY\n");
+ }
+ }
+ if (op == ZD_PARAM_WPS_FILTER) {
+ printk(KERN_ERR "ZD_PARAM_WPS_FILTER : ");
+
+ if (arg) {
+ /* mCounterMeasureState=1; */
+ macp->forwardMgmt = 1;
+ printk(KERN_ERR "enable\n");
+ } else {
+ /* mCounterMeasureState=0; */
+ macp->forwardMgmt = 0;
+ printk(KERN_ERR "disable\n");
+ }
+ }
+ }
+ err = 0;
+ break;
+ case ZD_IOCTL_GETWPAIE: {
+ struct ieee80211req_wpaie req_wpaie;
+ u16_t apId, i, j;
+
+ /* Get the AP Id */
+ apId = zfLnxGetVapId(dev);
+
+ if (apId == 0xffff) {
+ apId = 0;
+ } else {
+ apId = apId + 1;
}
+
+ if (copy_from_user(&req_wpaie, ifr->ifr_data,
+ sizeof(struct ieee80211req_wpaie))) {
+ printk(KERN_ERR "usbdrv : copy_from_user error\n");
+ return -EFAULT;
+ }
+
+ for (i = 0; i < ZM_OAL_MAX_STA_SUPPORT; i++) {
+ for (j = 0; j < IEEE80211_ADDR_LEN; j++) {
+ if (macp->stawpaie[i].wpa_macaddr[j] !=
+ req_wpaie.wpa_macaddr[j])
+ break;
+ }
+ if (j == 6)
break;
+ }
+ if (i < ZM_OAL_MAX_STA_SUPPORT) {
+ /* printk("ZD_IOCTL_GETWPAIE - sta index = % d\n", i); */
+ memcpy(req_wpaie.wpa_ie, macp->stawpaie[i].wpa_ie,
+ IEEE80211_MAX_IE_SIZE);
+ }
- case ZDAPIOCTL: //debug command
- if (copy_from_user(&zdreq, ifr->ifr_data, sizeof (zdreq)))
- {
- printk(KERN_ERR "usbdrv: copy_from_user error\n");
- return -EFAULT;
- }
-
- //printk(KERN_DEBUG "usbdrv: cmd=%2x, reg=0x%04lx, value=0x%08lx\n",
- // zdreq.cmd, zdreq.addr, zdreq.value);
-
- zfLnxPrivateIoctl(dev, &zdreq);
-
- err = 0;
- break;
-
- case ZD_IOCTL_WPA:
- if (copy_from_user(&zdparm, ifr->ifr_data, sizeof(struct athr_wlan_param)))
- {
- printk(KERN_ERR "usbdrv: copy_from_user error\n");
- return -EFAULT;
- }
-
- usbdrv_wpa_ioctl(dev, &zdparm);
- err = 0;
- break;
-
- case ZD_IOCTL_PARAM:
- {
- int *p;
- int op;
- int arg;
-
- /* Point to the name field and retrieve the
- * op and arg elements. */
- p = (int *)wrq->u.name;
- op = *p++;
- arg = *p;
-
- if(op == ZD_PARAM_ROAMING)
- {
- printk(KERN_ERR "************* ZD_PARAM_ROAMING: %d\n", arg);
- //macp->cardSetting.ap_scan=(U8)arg;
- }
- if(op == ZD_PARAM_PRIVACY)
- {
- printk(KERN_ERR "ZD_IOCTL_PRIVACY: ");
-
- /* Turn on the privacy invoke flag */
- if(arg)
- {
- // mCap[0] |= CAP_PRIVACY;
- // macp->cardSetting.EncryOnOff[0] = 1;
- printk(KERN_ERR "enable\n");
-
- }
- else
- {
- // mCap[0] &= ~CAP_PRIVACY;
- // macp->cardSetting.EncryOnOff[0] = 0;
- printk(KERN_ERR "disable\n");
- }
- //changed=1;
- }
- if(op == ZD_PARAM_WPA)
- {
- printk(KERN_ERR "ZD_PARAM_WPA: ");
-
- if(arg)
- {
- printk(KERN_ERR "enable\n");
-
- if (zfiWlanQueryWlanMode(dev) != ZM_MODE_AP)
- {
- printk(KERN_ERR "Station Mode\n");
- //zfiWlanQueryWpaIe(dev, (u8_t *)&wpaIe, &wpalen);
- //printk("wpaIe : %2x,%2x,%2x\n", wpaIe[21], wpaIe[22], wpaIe[23]);
- //printk("rsnIe : %2x,%2x,%2x\n", wpaIe[17], wpaIe[18], wpaIe[19]);
- if ((macp->supIe[21] == 0x50) &&
- (macp->supIe[22] == 0xf2) &&
- (macp->supIe[23] == 0x2))
- {
- printk(KERN_ERR "wd->sta.authMode = ZM_AUTH_MODE_WPAPSK\n");
- //wd->sta.authMode = ZM_AUTH_MODE_WPAPSK;
- //wd->ws.authMode = ZM_AUTH_MODE_WPAPSK;
- zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_WPAPSK);
- }
- else if ((macp->supIe[21] == 0x50) &&
- (macp->supIe[22] == 0xf2) &&
- (macp->supIe[23] == 0x1))
- {
- printk(KERN_ERR "wd->sta.authMode = ZM_AUTH_MODE_WPA\n");
- //wd->sta.authMode = ZM_AUTH_MODE_WPA;
- //wd->ws.authMode = ZM_AUTH_MODE_WPA;
- zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_WPA);
- }
- else if ((macp->supIe[17] == 0xf) &&
- (macp->supIe[18] == 0xac) &&
- (macp->supIe[19] == 0x2))
- {
- printk(KERN_ERR "wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK\n");
- //wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK;
- //wd->ws.authMode = ZM_AUTH_MODE_WPA2PSK;
- zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_WPA2PSK);
- }
- else if ((macp->supIe[17] == 0xf) &&
- (macp->supIe[18] == 0xac) &&
- (macp->supIe[19] == 0x1))
- {
- printk(KERN_ERR "wd->sta.authMode = ZM_AUTH_MODE_WPA2\n");
- //wd->sta.authMode = ZM_AUTH_MODE_WPA2;
- //wd->ws.authMode = ZM_AUTH_MODE_WPA2;
- zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_WPA2);
- }
- if ((macp->supIe[21] == 0x50) || (macp->supIe[22] == 0xf2))//WPA or WPAPSK
- {
- if (macp->supIe[11] == 0x2)
- {
- printk(KERN_ERR "wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
- //wd->sta.wepStatus = ZM_ENCRYPTION_TKIP;
- //wd->ws.wepStatus = ZM_ENCRYPTION_TKIP;
- zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
- }
- else
- {
- printk(KERN_ERR "wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
- //wd->sta.wepStatus = ZM_ENCRYPTION_AES;
- //wd->ws.wepStatus = ZM_ENCRYPTION_AES;
- zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
- }
- }
- if ((macp->supIe[17] == 0xf) || (macp->supIe[18] == 0xac)) //WPA2 or WPA2PSK
- {
- if (macp->supIe[13] == 0x2)
- {
- printk(KERN_ERR "wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
- //wd->sta.wepStatus = ZM_ENCRYPTION_TKIP;
- //wd->ws.wepStatus = ZM_ENCRYPTION_TKIP;
- zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
- }
- else
- {
- printk(KERN_ERR "wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
- //wd->sta.wepStatus = ZM_ENCRYPTION_AES;
- //wd->ws.wepStatus = ZM_ENCRYPTION_AES;
- zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
- }
- }
- }
- zfiWlanSetWpaSupport(dev, 1);
- }
- else
- {
- /* Reset the WPA related variables */
- printk(KERN_ERR "disable\n");
-
- zfiWlanSetWpaSupport(dev, 0);
- zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_OPEN);
- zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_WEP_DISABLED);
-
- /* Now we only set the length in the WPA IE
- * field to zero. */
- //macp->cardSetting.WPAIe[1] = 0;
- }
- }
- if(op == ZD_PARAM_COUNTERMEASURES)
- {
- printk(KERN_ERR "================ZD_PARAM_COUNTERMEASURES: ");
-
- if(arg)
- {
- // mCounterMeasureState=1;
- printk(KERN_ERR "enable\n");
- }
- else
- {
- // mCounterMeasureState=0;
- printk(KERN_ERR "disable\n");
- }
- }
- if(op == ZD_PARAM_DROPUNENCRYPTED)
- {
- printk(KERN_ERR "ZD_PARAM_DROPUNENCRYPTED: ");
-
- if(arg)
- {
- printk(KERN_ERR "enable\n");
- }
- else
- {
- printk(KERN_ERR "disable\n");
- }
- }
- if(op == ZD_PARAM_AUTH_ALGS)
- {
- printk(KERN_ERR "ZD_PARAM_AUTH_ALGS: ");
-
- if(arg == 0)
- {
- printk(KERN_ERR "OPEN_SYSTEM\n");
- }
- else
- {
- printk(KERN_ERR "SHARED_KEY\n");
- }
- }
- if(op == ZD_PARAM_WPS_FILTER)
- {
- printk(KERN_ERR "ZD_PARAM_WPS_FILTER: ");
-
- if(arg)
- {
- // mCounterMeasureState=1;
- macp->forwardMgmt = 1;
- printk(KERN_ERR "enable\n");
- }
- else
- {
- // mCounterMeasureState=0;
- macp->forwardMgmt = 0;
- printk(KERN_ERR "disable\n");
- }
- }
- }
- err = 0;
- break;
-
- case ZD_IOCTL_GETWPAIE:
- {
- struct ieee80211req_wpaie req_wpaie;
- u16_t apId, i, j;
-
- /* Get the AP Id */
- apId = zfLnxGetVapId(dev);
-
- if (apId == 0xffff)
- {
- apId = 0;
- }
- else
- {
- apId = apId+1;
- }
-
- if (copy_from_user(&req_wpaie, ifr->ifr_data, sizeof(struct ieee80211req_wpaie))){
- printk(KERN_ERR "usbdrv: copy_from_user error\n");
- return -EFAULT;
- }
-
- for(i = 0; i < ZM_OAL_MAX_STA_SUPPORT; i++)
- {
- for(j = 0; j < IEEE80211_ADDR_LEN; j++)
- {
- if (macp->stawpaie[i].wpa_macaddr[j] != req_wpaie.wpa_macaddr[j])
- break;
- }
- if (j == 6)
- break;
- }
- if (i < ZM_OAL_MAX_STA_SUPPORT)
- {
- //printk("ZD_IOCTL_GETWPAIE - sta index = %d\n", i);
- memcpy(req_wpaie.wpa_ie, macp->stawpaie[i].wpa_ie, IEEE80211_MAX_IE_SIZE);
- }
-
- if (copy_to_user(wrq->u.data.pointer, &req_wpaie, sizeof(struct ieee80211req_wpaie)))
- {
- return -EFAULT;
- }
- }
-
- err = 0;
- break;
-#ifdef ZM_ENABLE_CENC
- case ZM_IOCTL_CENC:
- if (copy_from_user(&macp->zd_wpa_req, ifr->ifr_data, sizeof(struct athr_wlan_param)))
- {
- printk(KERN_ERR "usbdrv: copy_from_user error\n");
- return -EFAULT;
- }
-
- usbdrv_cenc_ioctl(dev, (struct zydas_cenc_param *)&macp->zd_wpa_req);
- err = 0;
- break;
-#endif //ZM_ENABLE_CENC
- default:
- err = -EOPNOTSUPP;
- break;
- }
-
-
- return err;
+ if (copy_to_user(wrq->u.data.pointer, &req_wpaie,
+ sizeof(struct ieee80211req_wpaie))) {
+ return -EFAULT;
+ }
+ }
+
+ err = 0;
+ break;
+ #ifdef ZM_ENABLE_CENC
+ case ZM_IOCTL_CENC:
+ if (copy_from_user(&macp->zd_wpa_req, ifr->ifr_data,
+ sizeof(struct athr_wlan_param))) {
+ printk(KERN_ERR "usbdrv : copy_from_user error\n");
+ return -EFAULT;
+ }
+
+ usbdrv_cenc_ioctl(dev,
+ (struct zydas_cenc_param *)&macp->zd_wpa_req);
+ err = 0;
+ break;
+ #endif /* ZM_ENABLE_CENC */
+ default:
+ err = -EOPNOTSUPP;
+ break;
+ }
+
+ return err;
}
diff --git a/drivers/staging/otus/usbdrv.c b/drivers/staging/otus/usbdrv.c
index dfe07072011..565a839589f 100644
--- a/drivers/staging/otus/usbdrv.c
+++ b/drivers/staging/otus/usbdrv.c
@@ -936,30 +936,26 @@ int zfLnxAllocAllUrbs(struct usbdrv_private *macp)
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i)
{
endpoint = &iface_desc->endpoint[i].desc;
- if ((endpoint->bEndpointAddress & 0x80) &&
- ((endpoint->bmAttributes & 3) == 0x02))
+ if (usb_endpoint_is_bulk_in(endpoint))
{
/* we found a bulk in endpoint */
printk(KERN_ERR "bulk in: wMaxPacketSize = %x\n", le16_to_cpu(endpoint->wMaxPacketSize));
}
- if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
- ((endpoint->bmAttributes & 3) == 0x02))
+ if (usb_endpoint_is_bulk_out(endpoint))
{
/* we found a bulk out endpoint */
printk(KERN_ERR "bulk out: wMaxPacketSize = %x\n", le16_to_cpu(endpoint->wMaxPacketSize));
}
- if ((endpoint->bEndpointAddress & 0x80) &&
- ((endpoint->bmAttributes & 3) == 0x03))
+ if (usb_endpoint_is_int_in(endpoint))
{
/* we found a interrupt in endpoint */
printk(KERN_ERR "interrupt in: wMaxPacketSize = %x\n", le16_to_cpu(endpoint->wMaxPacketSize));
printk(KERN_ERR "interrupt in: int_interval = %d\n", endpoint->bInterval);
}
- if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
- ((endpoint->bmAttributes & 3) == 0x03))
+ if (usb_endpoint_is_int_out(endpoint))
{
/* we found a interrupt out endpoint */
printk(KERN_ERR "interrupt out: wMaxPacketSize = %x\n", le16_to_cpu(endpoint->wMaxPacketSize));
diff --git a/drivers/staging/otus/wwrap.c b/drivers/staging/otus/wwrap.c
index 1bb5f596d6c..4db8f6e75ad 100644
--- a/drivers/staging/otus/wwrap.c
+++ b/drivers/staging/otus/wwrap.c
@@ -350,8 +350,7 @@ void zfLnxUsbDataIn_callback(urb_t *urb)
buf->len = 0;
#endif
- if ((buf->tail + urb->actual_length) > buf->end)
- BUG();
+ BUG_ON((buf->tail + urb->actual_length) > buf->end);
skb_put(buf, urb->actual_length);
@@ -971,8 +970,7 @@ int zfLnxCencSendMsg(struct sock *netlink_sk, u_int8_t *msg, int len)
out:
return ret;
nlmsg_failure: /*NLMSG_PUT ʧ°Ü£¬Ôò³·ÏúÌ×½Ó×Ö»º´æ*/
- if(skb)
- kfree_skb(skb);
+ kfree_skb(skb);
goto out;
#undef COMMTYPE_GROUP
diff --git a/drivers/staging/otus/zdcompat.h b/drivers/staging/otus/zdcompat.h
index 8acf400fbc0..d9a3b2d5ba1 100644
--- a/drivers/staging/otus/zdcompat.h
+++ b/drivers/staging/otus/zdcompat.h
@@ -45,13 +45,6 @@ struct iw_request_info
#endif
#endif
-#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
diff --git a/drivers/staging/p9auth/Kconfig b/drivers/staging/p9auth/Kconfig
new file mode 100644
index 00000000000..d1c66d26202
--- /dev/null
+++ b/drivers/staging/p9auth/Kconfig
@@ -0,0 +1,9 @@
+config PLAN9AUTH
+ tristate "Plan 9 style capability device implementation"
+ default n
+ depends on CRYPTO
+ help
+ This module implements the Plan 9 style capability device.
+
+ To compile this driver as a module, choose
+ M here: the module will be called p9auth.
diff --git a/drivers/staging/p9auth/Makefile b/drivers/staging/p9auth/Makefile
new file mode 100644
index 00000000000..3ebf6ff0eef
--- /dev/null
+++ b/drivers/staging/p9auth/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_PLAN9AUTH) += p9auth.o
diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c
new file mode 100644
index 00000000000..3cac89b26fa
--- /dev/null
+++ b/drivers/staging/p9auth/p9auth.c
@@ -0,0 +1,383 @@
+/*
+ * Plan 9 style capability device implementation for the Linux Kernel
+ *
+ * Copyright 2008, 2009 Ashwin Ganti <ashwin.ganti@gmail.com>
+ *
+ * Released under the GPLv2
+ *
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/highmem.h>
+#include <linux/scatterlist.h>
+#include <linux/sched.h>
+#include <linux/cred.h>
+
+#ifndef CAP_MAJOR
+#define CAP_MAJOR 0
+#endif
+
+#ifndef CAP_NR_DEVS
+#define CAP_NR_DEVS 2 /* caphash and capuse */
+#endif
+
+#ifndef CAP_NODE_SIZE
+#define CAP_NODE_SIZE 20
+#endif
+
+#define MAX_DIGEST_SIZE 20
+
+struct cap_node {
+ char data[CAP_NODE_SIZE];
+ struct list_head list;
+};
+
+struct cap_dev {
+ struct cap_node *head;
+ int node_size;
+ unsigned long size;
+ struct semaphore sem;
+ struct cdev cdev;
+};
+
+static int cap_major = CAP_MAJOR;
+static int cap_minor;
+static int cap_nr_devs = CAP_NR_DEVS;
+static int cap_node_size = CAP_NODE_SIZE;
+
+module_param(cap_major, int, S_IRUGO);
+module_param(cap_minor, int, S_IRUGO);
+module_param(cap_nr_devs, int, S_IRUGO);
+
+MODULE_AUTHOR("Ashwin Ganti");
+MODULE_LICENSE("GPL");
+
+static struct cap_dev *cap_devices;
+
+static void hexdump(unsigned char *buf, unsigned int len)
+{
+ while (len--)
+ printk("%02x", *buf++);
+ printk("\n");
+}
+
+static char *cap_hash(char *plain_text, unsigned int plain_text_size,
+ char *key, unsigned int key_size)
+{
+ struct scatterlist sg;
+ char *result;
+ struct crypto_hash *tfm;
+ struct hash_desc desc;
+ int ret;
+
+ tfm = crypto_alloc_hash("hmac(sha1)", 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(tfm)) {
+ printk(KERN_ERR
+ "failed to load transform for hmac(sha1): %ld\n",
+ PTR_ERR(tfm));
+ return NULL;
+ }
+
+ desc.tfm = tfm;
+ desc.flags = 0;
+
+ result = kzalloc(MAX_DIGEST_SIZE, GFP_KERNEL);
+ if (!result) {
+ printk(KERN_ERR "out of memory!\n");
+ goto out;
+ }
+
+ sg_set_buf(&sg, plain_text, plain_text_size);
+
+ ret = crypto_hash_setkey(tfm, key, key_size);
+ if (ret) {
+ printk(KERN_ERR "setkey() failed ret=%d\n", ret);
+ kfree(result);
+ result = NULL;
+ goto out;
+ }
+
+ ret = crypto_hash_digest(&desc, &sg, plain_text_size, result);
+ if (ret) {
+ printk(KERN_ERR "digest () failed ret=%d\n", ret);
+ kfree(result);
+ result = NULL;
+ goto out;
+ }
+
+ printk(KERN_DEBUG "crypto hash digest size %d\n",
+ crypto_hash_digestsize(tfm));
+ hexdump(result, MAX_DIGEST_SIZE);
+
+out:
+ crypto_free_hash(tfm);
+ return result;
+}
+
+static int cap_trim(struct cap_dev *dev)
+{
+ struct cap_node *tmp;
+ struct list_head *pos, *q;
+ if (dev->head != NULL) {
+ list_for_each_safe(pos, q, &(dev->head->list)) {
+ tmp = list_entry(pos, struct cap_node, list);
+ list_del(pos);
+ kfree(tmp);
+ }
+ }
+ return 0;
+}
+
+static int cap_open(struct inode *inode, struct file *filp)
+{
+ struct cap_dev *dev;
+ dev = container_of(inode->i_cdev, struct cap_dev, cdev);
+ filp->private_data = dev;
+
+ /* trim to 0 the length of the device if open was write-only */
+ if ((filp->f_flags & O_ACCMODE) == O_WRONLY) {
+ if (down_interruptible(&dev->sem))
+ return -ERESTARTSYS;
+ cap_trim(dev);
+ up(&dev->sem);
+ }
+ /* initialise the head if it is NULL */
+ if (dev->head == NULL) {
+ dev->head = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
+ INIT_LIST_HEAD(&(dev->head->list));
+ }
+ return 0;
+}
+
+static int cap_release(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static ssize_t cap_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ struct cap_node *node_ptr, *tmp;
+ struct list_head *pos;
+ struct cap_dev *dev = filp->private_data;
+ ssize_t retval = -ENOMEM;
+ struct cred *new;
+ int len, target_int, source_int, flag = 0;
+ char *user_buf, *user_buf_running, *source_user, *target_user,
+ *rand_str, *hash_str, *result;
+
+ if (down_interruptible(&dev->sem))
+ return -ERESTARTSYS;
+
+ node_ptr = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
+ user_buf = kzalloc(count, GFP_KERNEL);
+
+ if (copy_from_user(user_buf, buf, count)) {
+ retval = -EFAULT;
+ goto out;
+ }
+
+ /*
+ * If the minor number is 0 ( /dev/caphash ) then simply add the
+ * hashed capability supplied by the user to the list of hashes
+ */
+ if (0 == iminor(filp->f_dentry->d_inode)) {
+ printk(KERN_INFO "Capability being written to /dev/caphash : \n");
+ hexdump(user_buf, count);
+ memcpy(node_ptr->data, user_buf, count);
+ list_add(&(node_ptr->list), &(dev->head->list));
+ } else {
+ /*
+ * break the supplied string into tokens with @ as the
+ * delimiter If the string is "user1@user2@randomstring" we
+ * need to split it and hash 'user1@user2' using 'randomstring'
+ * as the key.
+ */
+ user_buf_running = kstrdup(user_buf, GFP_KERNEL);
+ source_user = strsep(&user_buf_running, "@");
+ target_user = strsep(&user_buf_running, "@");
+ rand_str = strsep(&user_buf_running, "@");
+
+ /* hash the string user1@user2 with rand_str as the key */
+ len = strlen(source_user) + strlen(target_user) + 1;
+ hash_str = kzalloc(len, GFP_KERNEL);
+ strcat(hash_str, source_user);
+ strcat(hash_str, "@");
+ strcat(hash_str, target_user);
+
+ printk(KERN_ALERT "the source user is %s \n", source_user);
+ printk(KERN_ALERT "the target user is %s \n", target_user);
+
+ result = cap_hash(hash_str, len, rand_str, strlen(rand_str));
+ if (NULL == result) {
+ retval = -EFAULT;
+ goto out;
+ }
+ memcpy(node_ptr->data, result, CAP_NODE_SIZE);
+ /* Change the process's uid if the hash is present in the
+ * list of hashes
+ */
+ list_for_each(pos, &(cap_devices->head->list)) {
+ /*
+ * Change the user id of the process if the hashes
+ * match
+ */
+ if (0 ==
+ memcmp(result,
+ list_entry(pos, struct cap_node,
+ list)->data,
+ CAP_NODE_SIZE)) {
+ target_int = (unsigned int)
+ simple_strtol(target_user, NULL, 0);
+ source_int = (unsigned int)
+ simple_strtol(source_user, NULL, 0);
+ flag = 1;
+
+ /*
+ * Check whether the process writing to capuse
+ * is actually owned by the source owner
+ */
+ if (source_int != current_uid()) {
+ printk(KERN_ALERT
+ "Process is not owned by the source user of the capability.\n");
+ retval = -EFAULT;
+ goto out;
+ }
+ /*
+ * What all id's need to be changed here? uid,
+ * euid, fsid, savedids ?? Currently I am
+ * changing the effective user id since most of
+ * the authorisation decisions are based on it
+ */
+ new = prepare_creds();
+ if (!new) {
+ retval = -ENOMEM;
+ goto out;
+ }
+ new->uid = (uid_t) target_int;
+ new->euid = (uid_t) target_int;
+ retval = commit_creds(new);
+ if (retval)
+ goto out;
+
+ /*
+ * Remove the capability from the list and
+ * break
+ */
+ tmp = list_entry(pos, struct cap_node, list);
+ list_del(pos);
+ kfree(tmp);
+ break;
+ }
+ }
+ if (0 == flag) {
+ /*
+ * The capability is not present in the list of the
+ * hashes stored, hence return failure
+ */
+ printk(KERN_ALERT
+ "Invalid capabiliy written to /dev/capuse \n");
+ retval = -EFAULT;
+ goto out;
+ }
+ }
+ *f_pos += count;
+ retval = count;
+ /* update the size */
+ if (dev->size < *f_pos)
+ dev->size = *f_pos;
+
+out:
+ up(&dev->sem);
+ return retval;
+}
+
+static const struct file_operations cap_fops = {
+ .owner = THIS_MODULE,
+ .write = cap_write,
+ .open = cap_open,
+ .release = cap_release,
+};
+
+static void cap_cleanup_module(void)
+{
+ int i;
+ dev_t devno = MKDEV(cap_major, cap_minor);
+ if (cap_devices) {
+ for (i = 0; i < cap_nr_devs; i++) {
+ cap_trim(cap_devices + i);
+ cdev_del(&cap_devices[i].cdev);
+ }
+ kfree(cap_devices);
+ }
+ unregister_chrdev_region(devno, cap_nr_devs);
+
+}
+
+static void cap_setup_cdev(struct cap_dev *dev, int index)
+{
+ int err, devno = MKDEV(cap_major, cap_minor + index);
+ cdev_init(&dev->cdev, &cap_fops);
+ dev->cdev.owner = THIS_MODULE;
+ dev->cdev.ops = &cap_fops;
+ err = cdev_add(&dev->cdev, devno, 1);
+ if (err)
+ printk(KERN_NOTICE "Error %d adding cap%d", err, index);
+}
+
+static int cap_init_module(void)
+{
+ int result, i;
+ dev_t dev = 0;
+
+ if (cap_major) {
+ dev = MKDEV(cap_major, cap_minor);
+ result = register_chrdev_region(dev, cap_nr_devs, "cap");
+ } else {
+ result = alloc_chrdev_region(&dev, cap_minor, cap_nr_devs,
+ "cap");
+ cap_major = MAJOR(dev);
+ }
+
+ if (result < 0) {
+ printk(KERN_WARNING "cap: can't get major %d\n",
+ cap_major);
+ return result;
+ }
+
+ cap_devices = kzalloc(cap_nr_devs * sizeof(struct cap_dev),
+ GFP_KERNEL);
+ if (!cap_devices) {
+ result = -ENOMEM;
+ goto fail;
+ }
+
+ /* Initialize each device. */
+ for (i = 0; i < cap_nr_devs; i++) {
+ cap_devices[i].node_size = cap_node_size;
+ init_MUTEX(&cap_devices[i].sem);
+ cap_setup_cdev(&cap_devices[i], i);
+ }
+
+ return 0;
+
+fail:
+ cap_cleanup_module();
+ return result;
+}
+
+module_init(cap_init_module);
+module_exit(cap_cleanup_module);
+
+
diff --git a/drivers/staging/panel/Kconfig b/drivers/staging/panel/Kconfig
index c4b30f2a549..3abe7c9d558 100644
--- a/drivers/staging/panel/Kconfig
+++ b/drivers/staging/panel/Kconfig
@@ -110,7 +110,7 @@ config PANEL_LCD_BWIDTH
---help---
Most LCDs use a standard controller which supports hardware lines of 40
characters, although sometimes only 16, 20 or 24 of them are really wired
- to the terminal. This results in some non-visible but adressable characters,
+ to the terminal. This results in some non-visible but addressable characters,
and is the case for most parallel LCDs. Other LCDs, and some serial ones,
however, use the same line width internally as what is visible. The KS0074
for example, uses 16 characters per line for 16 visible characters per line.
diff --git a/drivers/staging/phison/Kconfig b/drivers/staging/phison/Kconfig
new file mode 100644
index 00000000000..d3c65d315a2
--- /dev/null
+++ b/drivers/staging/phison/Kconfig
@@ -0,0 +1,5 @@
+config IDE_PHISON
+ tristate "PCIE ATA PS5000 IDE support"
+ depends on PCI && ATA && ATA_SFF
+ ---help---
+ This is an experimental driver for PS5000 IDE driver.
diff --git a/drivers/staging/phison/Makefile b/drivers/staging/phison/Makefile
new file mode 100644
index 00000000000..7642a2190e9
--- /dev/null
+++ b/drivers/staging/phison/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_IDE_PHISON) += phison.o
diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c
new file mode 100644
index 00000000000..270ebcb681a
--- /dev/null
+++ b/drivers/staging/phison/phison.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2006 Red Hat <evan_ko@phison.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public License
+ *
+ * [Modify History]
+ * #0001, Evan, 2008.10.22, V0.00, New release.
+ * #0002, Evan, 2008.11.01, V0.90, Test Work In Ubuntu Linux 8.04.
+ * #0003, Evan, 2008.01.08, V0.91, Change Name "PCIE-SSD" to "E-BOX".
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+#include <linux/ata.h>
+
+#define PHISON_DEBUG
+
+#define DRV_NAME "phison_e-box" /* #0003 */
+#define DRV_VERSION "0.91" /* #0003 */
+
+#define PCI_VENDOR_ID_PHISON 0x1987
+#define PCI_DEVICE_ID_PS5000 0x5000
+
+static int phison_pre_reset(struct ata_link *link, unsigned long deadline)
+{
+ int ret;
+ struct ata_port *ap = link->ap;
+
+ ap->cbl = ATA_CBL_NONE;
+ ret = ata_std_prereset(link, deadline);
+ dev_dbg(ap->dev, "phison_pre_reset(), ret = %x\n", ret);
+ return ret;
+}
+
+static struct scsi_host_template phison_sht = {
+ ATA_BMDMA_SHT(DRV_NAME),
+};
+
+static struct ata_port_operations phison_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .prereset = phison_pre_reset,
+};
+
+static int phison_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ int ret;
+ struct ata_port_info info = {
+ .flags = ATA_FLAG_NO_ATAPI,
+
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = ATA_UDMA5,
+
+ .port_ops = &phison_ops,
+ };
+ const struct ata_port_info *ppi[] = { &info, NULL };
+
+ ret = ata_pci_sff_init_one(pdev, ppi, &phison_sht, NULL);
+
+ dev_dbg(&pdev->dev, "phison_init_one(), ret = %x\n", ret);
+
+ return ret;
+}
+
+static struct pci_device_id phison_pci_tbl[] = {
+ { PCI_VENDOR_ID_PHISON, PCI_DEVICE_ID_PS5000, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, phison_pci_tbl);
+
+static struct pci_driver phison_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = phison_pci_tbl,
+ .probe = phison_init_one,
+ .remove = ata_pci_remove_one,
+#ifdef CONFIG_PM /* haven't tested it. */
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
+#endif
+};
+
+static int phison_ide_init(void)
+{
+ return pci_register_driver(&phison_pci_driver);
+}
+
+static void phison_ide_exit(void)
+{
+ pci_unregister_driver(&phison_pci_driver);
+}
+
+module_init(phison_ide_init);
+module_exit(phison_ide_exit);
+
+MODULE_AUTHOR("Evan Ko");
+MODULE_DESCRIPTION("PCIE driver module for PHISON PS5000 E-BOX");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/staging/pohmelfs/Kconfig b/drivers/staging/pohmelfs/Kconfig
new file mode 100644
index 00000000000..58158b8780f
--- /dev/null
+++ b/drivers/staging/pohmelfs/Kconfig
@@ -0,0 +1,28 @@
+config POHMELFS
+ tristate "POHMELFS filesystem support"
+ depends on NET
+ select CONNECTOR
+ select CRYPTO
+ select CRYPTO_BLKCIPHER
+ select CRYPTO_HMAC
+ help
+ POHMELFS stands for Parallel Optimized Host Message Exchange Layered
+ File System. This is a network filesystem which supports coherent
+ caching of data and metadata on clients.
+
+config POHMELFS_DEBUG
+ bool "POHMELFS debugging"
+ depends on POHMELFS
+ default n
+ help
+ Turns on excessive POHMELFS debugging facilities.
+ You usually do not want to slow things down noticeably and get really
+ lots of kernel messages in syslog.
+
+config POHMELFS_CRYPTO
+ bool "POHMELFS crypto support"
+ depends on POHMELFS
+ help
+ This option allows to encrypt and/or protect with strong
+ cryptographic hash all dataflow between server and clients.
+ Each config group can have its own keys.
diff --git a/drivers/staging/pohmelfs/Makefile b/drivers/staging/pohmelfs/Makefile
new file mode 100644
index 00000000000..196561ca26b
--- /dev/null
+++ b/drivers/staging/pohmelfs/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_POHMELFS) += pohmelfs.o
+
+pohmelfs-y := inode.o config.o dir.o net.o path_entry.o trans.o crypto.o lock.o mcache.o
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c
new file mode 100644
index 00000000000..3e67da9ea38
--- /dev/null
+++ b/drivers/staging/pohmelfs/config.c
@@ -0,0 +1,478 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/connector.h>
+#include <linux/crypto.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/in.h>
+
+#include "netfs.h"
+
+/*
+ * Global configuration list.
+ * Each client can be asked to get one of them.
+ *
+ * Allows to provide remote server address (ipv4/v6/whatever), port
+ * and so on via kernel connector.
+ */
+
+static struct cb_id pohmelfs_cn_id = {.idx = POHMELFS_CN_IDX, .val = POHMELFS_CN_VAL};
+static LIST_HEAD(pohmelfs_config_list);
+static DEFINE_MUTEX(pohmelfs_config_lock);
+
+static inline int pohmelfs_config_eql(struct pohmelfs_ctl *sc, struct pohmelfs_ctl *ctl)
+{
+ if (sc->idx == ctl->idx && sc->type == ctl->type &&
+ sc->proto == ctl->proto &&
+ sc->addrlen == ctl->addrlen &&
+ !memcmp(&sc->addr, &ctl->addr, ctl->addrlen))
+ return 1;
+
+ return 0;
+}
+
+static struct pohmelfs_config_group *pohmelfs_find_config_group(unsigned int idx)
+{
+ struct pohmelfs_config_group *g, *group = NULL;
+
+ list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
+ if (g->idx == idx) {
+ group = g;
+ break;
+ }
+ }
+
+ return group;
+}
+
+static struct pohmelfs_config_group *pohmelfs_find_create_config_group(unsigned int idx)
+{
+ struct pohmelfs_config_group *g;
+
+ g = pohmelfs_find_config_group(idx);
+ if (g)
+ return g;
+
+ g = kzalloc(sizeof(struct pohmelfs_config_group), GFP_KERNEL);
+ if (!g)
+ return NULL;
+
+ INIT_LIST_HEAD(&g->config_list);
+ g->idx = idx;
+ g->num_entry = 0;
+
+ list_add_tail(&g->group_entry, &pohmelfs_config_list);
+
+ return g;
+}
+
+int pohmelfs_copy_config(struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config_group *g;
+ struct pohmelfs_config *c, *dst;
+ int err = -ENODEV;
+
+ mutex_lock(&pohmelfs_config_lock);
+
+ g = pohmelfs_find_config_group(psb->idx);
+ if (!g)
+ goto out_unlock;
+
+ /*
+ * Run over all entries in given config group and try to crate and
+ * initialize those, which do not exist in superblock list.
+ * Skip all existing entries.
+ */
+
+ list_for_each_entry(c, &g->config_list, config_entry) {
+ err = 0;
+ list_for_each_entry(dst, &psb->state_list, config_entry) {
+ if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) {
+ err = -EEXIST;
+ break;
+ }
+ }
+
+ if (err)
+ continue;
+
+ dst = kzalloc(sizeof(struct pohmelfs_config), GFP_KERNEL);
+ if (!dst) {
+ err = -ENOMEM;
+ break;
+ }
+
+ memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl));
+
+ list_add_tail(&dst->config_entry, &psb->state_list);
+
+ err = pohmelfs_state_init_one(psb, dst);
+ if (err) {
+ list_del(&dst->config_entry);
+ kfree(dst);
+ }
+
+ err = 0;
+ }
+
+out_unlock:
+ mutex_unlock(&pohmelfs_config_lock);
+
+ return err;
+}
+
+int pohmelfs_copy_crypto(struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config_group *g;
+ int err = -ENOENT;
+
+ mutex_lock(&pohmelfs_config_lock);
+ g = pohmelfs_find_config_group(psb->idx);
+ if (!g)
+ goto err_out_exit;
+
+ if (g->hash_string) {
+ err = -ENOMEM;
+ psb->hash_string = kstrdup(g->hash_string, GFP_KERNEL);
+ if (!psb->hash_string)
+ goto err_out_exit;
+ psb->hash_strlen = g->hash_strlen;
+ }
+
+ if (g->cipher_string) {
+ psb->cipher_string = kstrdup(g->cipher_string, GFP_KERNEL);
+ if (!psb->cipher_string)
+ goto err_out_free_hash_string;
+ psb->cipher_strlen = g->cipher_strlen;
+ }
+
+ if (g->hash_keysize) {
+ psb->hash_key = kmalloc(g->hash_keysize, GFP_KERNEL);
+ if (!psb->hash_key)
+ goto err_out_free_cipher_string;
+ memcpy(psb->hash_key, g->hash_key, g->hash_keysize);
+ psb->hash_keysize = g->hash_keysize;
+ }
+
+ if (g->cipher_keysize) {
+ psb->cipher_key = kmalloc(g->cipher_keysize, GFP_KERNEL);
+ if (!psb->cipher_key)
+ goto err_out_free_hash;
+ memcpy(psb->cipher_key, g->cipher_key, g->cipher_keysize);
+ psb->cipher_keysize = g->cipher_keysize;
+ }
+
+ mutex_unlock(&pohmelfs_config_lock);
+
+ return 0;
+
+err_out_free_hash:
+ kfree(psb->hash_key);
+err_out_free_cipher_string:
+ kfree(psb->cipher_string);
+err_out_free_hash_string:
+ kfree(psb->hash_string);
+err_out_exit:
+ mutex_unlock(&pohmelfs_config_lock);
+ return err;
+}
+
+static int pohmelfs_send_reply(int err, int msg_num, int action, struct cn_msg *msg, struct pohmelfs_ctl *ctl)
+{
+ struct pohmelfs_cn_ack *ack;
+
+ ack = kmalloc(sizeof(struct pohmelfs_cn_ack), GFP_KERNEL);
+ if (!ack)
+ return -ENOMEM;
+
+ memset(ack, 0, sizeof(struct pohmelfs_cn_ack));
+ memcpy(&ack->msg, msg, sizeof(struct cn_msg));
+
+ if (action == POHMELFS_CTLINFO_ACK)
+ memcpy(&ack->ctl, ctl, sizeof(struct pohmelfs_ctl));
+
+ ack->msg.len = sizeof(struct pohmelfs_cn_ack) - sizeof(struct cn_msg);
+ ack->msg.ack = msg->ack + 1;
+ ack->error = err;
+ ack->msg_num = msg_num;
+
+ cn_netlink_send(&ack->msg, 0, GFP_KERNEL);
+ kfree(ack);
+ return 0;
+}
+
+static int pohmelfs_cn_disp(struct cn_msg *msg)
+{
+ struct pohmelfs_config_group *g;
+ struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
+ struct pohmelfs_config *c, *tmp;
+ int err = 0, i = 1;
+
+ if (msg->len != sizeof(struct pohmelfs_ctl))
+ return -EBADMSG;
+
+ mutex_lock(&pohmelfs_config_lock);
+
+ g = pohmelfs_find_config_group(ctl->idx);
+ if (!g) {
+ pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL);
+ goto out_unlock;
+ }
+
+ list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+ struct pohmelfs_ctl *sc = &c->state.ctl;
+ if (pohmelfs_send_reply(err, g->num_entry - i, POHMELFS_CTLINFO_ACK, msg, sc)) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+ i += 1;
+ }
+
+out_unlock:
+ mutex_unlock(&pohmelfs_config_lock);
+ return err;
+}
+
+static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
+{
+ struct pohmelfs_config_group *g;
+ struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
+ struct pohmelfs_config *c, *tmp;
+ int err = 0;
+
+ if (msg->len != sizeof(struct pohmelfs_ctl))
+ return -EBADMSG;
+
+ mutex_lock(&pohmelfs_config_lock);
+
+ g = pohmelfs_find_create_config_group(ctl->idx);
+ if (!g) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+
+ list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+ struct pohmelfs_ctl *sc = &c->state.ctl;
+
+ if (pohmelfs_config_eql(sc, ctl)) {
+ if (action == POHMELFS_FLAGS_ADD) {
+ err = -EEXIST;
+ goto out_unlock;
+ } else if (action == POHMELFS_FLAGS_DEL) {
+ list_del(&c->config_entry);
+ g->num_entry--;
+ kfree(c);
+ goto out_unlock;
+ } else {
+ err = -EEXIST;
+ goto out_unlock;
+ }
+ }
+ }
+ if (action == POHMELFS_FLAGS_DEL) {
+ err = -EBADMSG;
+ goto out_unlock;
+ }
+
+ c = kzalloc(sizeof(struct pohmelfs_config), GFP_KERNEL);
+ if (!c) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+ memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl));
+ g->num_entry++;
+ list_add_tail(&c->config_entry, &g->config_list);
+
+out_unlock:
+ mutex_unlock(&pohmelfs_config_lock);
+ if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
+ err = -ENOMEM;
+
+ return err;
+}
+
+static int pohmelfs_crypto_hash_init(struct pohmelfs_config_group *g, struct pohmelfs_crypto *c)
+{
+ char *algo = (char *)c->data;
+ u8 *key = (u8 *)(algo + c->strlen);
+
+ if (g->hash_string)
+ return -EEXIST;
+
+ g->hash_string = kstrdup(algo, GFP_KERNEL);
+ if (!g->hash_string)
+ return -ENOMEM;
+ g->hash_strlen = c->strlen;
+ g->hash_keysize = c->keysize;
+
+ g->hash_key = kmalloc(c->keysize, GFP_KERNEL);
+ if (!g->hash_key) {
+ kfree(g->hash_string);
+ return -ENOMEM;
+ }
+
+ memcpy(g->hash_key, key, c->keysize);
+
+ return 0;
+}
+
+static int pohmelfs_crypto_cipher_init(struct pohmelfs_config_group *g, struct pohmelfs_crypto *c)
+{
+ char *algo = (char *)c->data;
+ u8 *key = (u8 *)(algo + c->strlen);
+
+ if (g->cipher_string)
+ return -EEXIST;
+
+ g->cipher_string = kstrdup(algo, GFP_KERNEL);
+ if (!g->cipher_string)
+ return -ENOMEM;
+ g->cipher_strlen = c->strlen;
+ g->cipher_keysize = c->keysize;
+
+ g->cipher_key = kmalloc(c->keysize, GFP_KERNEL);
+ if (!g->cipher_key) {
+ kfree(g->cipher_string);
+ return -ENOMEM;
+ }
+
+ memcpy(g->cipher_key, key, c->keysize);
+
+ return 0;
+}
+
+
+static int pohmelfs_cn_crypto(struct cn_msg *msg)
+{
+ struct pohmelfs_crypto *crypto = (struct pohmelfs_crypto *)msg->data;
+ struct pohmelfs_config_group *g;
+ int err = 0;
+
+ dprintk("%s: idx: %u, strlen: %u, type: %u, keysize: %u, algo: %s.\n",
+ __func__, crypto->idx, crypto->strlen, crypto->type,
+ crypto->keysize, (char *)crypto->data);
+
+ mutex_lock(&pohmelfs_config_lock);
+ g = pohmelfs_find_create_config_group(crypto->idx);
+ if (!g) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+
+ switch (crypto->type) {
+ case POHMELFS_CRYPTO_HASH:
+ err = pohmelfs_crypto_hash_init(g, crypto);
+ break;
+ case POHMELFS_CRYPTO_CIPHER:
+ err = pohmelfs_crypto_cipher_init(g, crypto);
+ break;
+ default:
+ err = -ENOTSUPP;
+ break;
+ }
+
+out_unlock:
+ mutex_unlock(&pohmelfs_config_lock);
+ if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
+ err = -ENOMEM;
+
+ return err;
+}
+
+static void pohmelfs_cn_callback(void *data)
+{
+ struct cn_msg *msg = data;
+ int err;
+
+ switch (msg->flags) {
+ case POHMELFS_FLAGS_ADD:
+ err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_ADD);
+ break;
+ case POHMELFS_FLAGS_DEL:
+ err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_DEL);
+ break;
+ case POHMELFS_FLAGS_SHOW:
+ err = pohmelfs_cn_disp(msg);
+ break;
+ case POHMELFS_FLAGS_CRYPTO:
+ err = pohmelfs_cn_crypto(msg);
+ break;
+ default:
+ err = -ENOSYS;
+ break;
+ }
+}
+
+int pohmelfs_config_check(struct pohmelfs_config *config, int idx)
+{
+ struct pohmelfs_ctl *ctl = &config->state.ctl;
+ struct pohmelfs_config *tmp;
+ int err = -ENOENT;
+ struct pohmelfs_ctl *sc;
+ struct pohmelfs_config_group *g;
+
+ mutex_lock(&pohmelfs_config_lock);
+
+ g = pohmelfs_find_config_group(ctl->idx);
+ if (g) {
+ list_for_each_entry(tmp, &g->config_list, config_entry) {
+ sc = &tmp->state.ctl;
+
+ if (pohmelfs_config_eql(sc, ctl)) {
+ err = 0;
+ break;
+ }
+ }
+ }
+
+ mutex_unlock(&pohmelfs_config_lock);
+
+ return err;
+}
+
+int __init pohmelfs_config_init(void)
+{
+ return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", pohmelfs_cn_callback);
+}
+
+void pohmelfs_config_exit(void)
+{
+ struct pohmelfs_config *c, *tmp;
+ struct pohmelfs_config_group *g, *gtmp;
+
+ cn_del_callback(&pohmelfs_cn_id);
+
+ mutex_lock(&pohmelfs_config_lock);
+ list_for_each_entry_safe(g, gtmp, &pohmelfs_config_list, group_entry) {
+ list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+ list_del(&c->config_entry);
+ kfree(c);
+ }
+
+ list_del(&g->group_entry);
+
+ if (g->hash_string)
+ kfree(g->hash_string);
+
+ if (g->cipher_string)
+ kfree(g->cipher_string);
+
+ kfree(g);
+ }
+ mutex_unlock(&pohmelfs_config_lock);
+}
diff --git a/drivers/staging/pohmelfs/crypto.c b/drivers/staging/pohmelfs/crypto.c
new file mode 100644
index 00000000000..31d765de92c
--- /dev/null
+++ b/drivers/staging/pohmelfs/crypto.c
@@ -0,0 +1,880 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/crypto.h>
+#include <linux/highmem.h>
+#include <linux/kthread.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+
+#include "netfs.h"
+
+static struct crypto_hash *pohmelfs_init_hash(struct pohmelfs_sb *psb)
+{
+ int err;
+ struct crypto_hash *hash;
+
+ hash = crypto_alloc_hash(psb->hash_string, 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(hash)) {
+ err = PTR_ERR(hash);
+ dprintk("%s: idx: %u: failed to allocate hash '%s', err: %d.\n",
+ __func__, psb->idx, psb->hash_string, err);
+ goto err_out_exit;
+ }
+
+ psb->crypto_attached_size = crypto_hash_digestsize(hash);
+
+ if (!psb->hash_keysize)
+ return hash;
+
+ err = crypto_hash_setkey(hash, psb->hash_key, psb->hash_keysize);
+ if (err) {
+ dprintk("%s: idx: %u: failed to set key for hash '%s', err: %d.\n",
+ __func__, psb->idx, psb->hash_string, err);
+ goto err_out_free;
+ }
+
+ return hash;
+
+err_out_free:
+ crypto_free_hash(hash);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+static struct crypto_ablkcipher *pohmelfs_init_cipher(struct pohmelfs_sb *psb)
+{
+ int err = -EINVAL;
+ struct crypto_ablkcipher *cipher;
+
+ if (!psb->cipher_keysize)
+ goto err_out_exit;
+
+ cipher = crypto_alloc_ablkcipher(psb->cipher_string, 0, 0);
+ if (IS_ERR(cipher)) {
+ err = PTR_ERR(cipher);
+ dprintk("%s: idx: %u: failed to allocate cipher '%s', err: %d.\n",
+ __func__, psb->idx, psb->cipher_string, err);
+ goto err_out_exit;
+ }
+
+ crypto_ablkcipher_clear_flags(cipher, ~0);
+
+ err = crypto_ablkcipher_setkey(cipher, psb->cipher_key, psb->cipher_keysize);
+ if (err) {
+ dprintk("%s: idx: %u: failed to set key for cipher '%s', err: %d.\n",
+ __func__, psb->idx, psb->cipher_string, err);
+ goto err_out_free;
+ }
+
+ return cipher;
+
+err_out_free:
+ crypto_free_ablkcipher(cipher);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+int pohmelfs_crypto_engine_init(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb)
+{
+ int err;
+
+ e->page_num = 0;
+
+ e->size = PAGE_SIZE;
+ e->data = kmalloc(e->size, GFP_KERNEL);
+ if (!e->data) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+
+ if (psb->hash_string) {
+ e->hash = pohmelfs_init_hash(psb);
+ if (IS_ERR(e->hash)) {
+ err = PTR_ERR(e->hash);
+ e->hash = NULL;
+ goto err_out_free;
+ }
+ }
+
+ if (psb->cipher_string) {
+ e->cipher = pohmelfs_init_cipher(psb);
+ if (IS_ERR(e->cipher)) {
+ err = PTR_ERR(e->cipher);
+ e->cipher = NULL;
+ goto err_out_free_hash;
+ }
+ }
+
+ return 0;
+
+err_out_free_hash:
+ crypto_free_hash(e->hash);
+err_out_free:
+ kfree(e->data);
+err_out_exit:
+ return err;
+}
+
+void pohmelfs_crypto_engine_exit(struct pohmelfs_crypto_engine *e)
+{
+ if (e->hash)
+ crypto_free_hash(e->hash);
+ if (e->cipher)
+ crypto_free_ablkcipher(e->cipher);
+ kfree(e->data);
+}
+
+static void pohmelfs_crypto_complete(struct crypto_async_request *req, int err)
+{
+ struct pohmelfs_crypto_completion *c = req->data;
+
+ if (err == -EINPROGRESS)
+ return;
+
+ dprintk("%s: req: %p, err: %d.\n", __func__, req, err);
+ c->error = err;
+ complete(&c->complete);
+}
+
+static int pohmelfs_crypto_process(struct ablkcipher_request *req,
+ struct scatterlist *sg_dst, struct scatterlist *sg_src,
+ void *iv, int enc, unsigned long timeout)
+{
+ struct pohmelfs_crypto_completion complete;
+ int err;
+
+ init_completion(&complete.complete);
+ complete.error = -EINPROGRESS;
+
+ ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ pohmelfs_crypto_complete, &complete);
+
+ ablkcipher_request_set_crypt(req, sg_src, sg_dst, sg_src->length, iv);
+
+ if (enc)
+ err = crypto_ablkcipher_encrypt(req);
+ else
+ err = crypto_ablkcipher_decrypt(req);
+
+ switch (err) {
+ case -EINPROGRESS:
+ case -EBUSY:
+ err = wait_for_completion_interruptible_timeout(&complete.complete,
+ timeout);
+ if (!err)
+ err = -ETIMEDOUT;
+ else
+ err = complete.error;
+ break;
+ default:
+ break;
+ }
+
+ return err;
+}
+
+int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 cmd_iv,
+ void *data, struct page *page, unsigned int size)
+{
+ int err;
+ struct scatterlist sg;
+
+ if (!e->cipher && !e->hash)
+ return 0;
+
+ dprintk("%s: eng: %p, iv: %llx, data: %p, page: %p/%lu, size: %u.\n",
+ __func__, e, cmd_iv, data, page, (page)?page->index:0, size);
+
+ if (data) {
+ sg_init_one(&sg, data, size);
+ } else {
+ sg_init_table(&sg, 1);
+ sg_set_page(&sg, page, size, 0);
+ }
+
+ if (e->cipher) {
+ struct ablkcipher_request *req = e->data + crypto_hash_digestsize(e->hash);
+ u8 iv[32];
+
+ memset(iv, 0, sizeof(iv));
+ memcpy(iv, &cmd_iv, sizeof(cmd_iv));
+
+ ablkcipher_request_set_tfm(req, e->cipher);
+
+ err = pohmelfs_crypto_process(req, &sg, &sg, iv, 0, e->timeout);
+ if (err)
+ goto err_out_exit;
+ }
+
+ if (e->hash) {
+ struct hash_desc desc;
+ void *dst = e->data + e->size/2;
+
+ desc.tfm = e->hash;
+ desc.flags = 0;
+
+ err = crypto_hash_init(&desc);
+ if (err)
+ goto err_out_exit;
+
+ err = crypto_hash_update(&desc, &sg, size);
+ if (err)
+ goto err_out_exit;
+
+ err = crypto_hash_final(&desc, dst);
+ if (err)
+ goto err_out_exit;
+
+ err = !!memcmp(dst, e->data, crypto_hash_digestsize(e->hash));
+
+ if (err) {
+#ifdef CONFIG_POHMELFS_DEBUG
+ unsigned int i;
+ unsigned char *recv = e->data, *calc = dst;
+
+ dprintk("%s: eng: %p, hash: %p, cipher: %p: iv : %llx, hash mismatch (recv/calc): ",
+ __func__, e, e->hash, e->cipher, cmd_iv);
+ for (i=0; i<crypto_hash_digestsize(e->hash); ++i) {
+#if 0
+ dprintka("%02x ", recv[i]);
+ if (recv[i] != calc[i]) {
+ dprintka("| calc byte: %02x.\n", calc[i]);
+ break;
+ }
+#else
+ dprintka("%02x/%02x ", recv[i], calc[i]);
+#endif
+ }
+ dprintk("\n");
+#endif
+ goto err_out_exit;
+ } else {
+ dprintk("%s: eng: %p, hash: %p, cipher: %p: hashes matched.\n",
+ __func__, e, e->hash, e->cipher);
+ }
+ }
+
+ dprintk("%s: eng: %p, size: %u, hash: %p, cipher: %p: completed.\n",
+ __func__, e, e->size, e->hash, e->cipher);
+
+ return 0;
+
+err_out_exit:
+ dprintk("%s: eng: %p, hash: %p, cipher: %p: err: %d.\n",
+ __func__, e, e->hash, e->cipher, err);
+ return err;
+}
+
+static int pohmelfs_trans_iter(struct netfs_trans *t, struct pohmelfs_crypto_engine *e,
+ int (* iterator) (struct pohmelfs_crypto_engine *e,
+ struct scatterlist *dst,
+ struct scatterlist *src))
+{
+ void *data = t->iovec.iov_base + sizeof(struct netfs_cmd) + t->psb->crypto_attached_size;
+ unsigned int size = t->iovec.iov_len - sizeof(struct netfs_cmd) - t->psb->crypto_attached_size;
+ struct netfs_cmd *cmd = data;
+ unsigned int sz, pages = t->attached_pages, i, csize, cmd_cmd, dpage_idx;
+ struct scatterlist sg_src, sg_dst;
+ int err;
+
+ while (size) {
+ cmd = data;
+ cmd_cmd = __be16_to_cpu(cmd->cmd);
+ csize = __be32_to_cpu(cmd->size);
+ cmd->iv = __cpu_to_be64(e->iv);
+
+ if (cmd_cmd == NETFS_READ_PAGES || cmd_cmd == NETFS_READ_PAGE)
+ csize = __be16_to_cpu(cmd->ext);
+
+ sz = csize + __be16_to_cpu(cmd->cpad) + sizeof(struct netfs_cmd);
+
+ dprintk("%s: size: %u, sz: %u, cmd_size: %u, cmd_cpad: %u.\n",
+ __func__, size, sz, __be32_to_cpu(cmd->size), __be16_to_cpu(cmd->cpad));
+
+ data += sz;
+ size -= sz;
+
+ sg_init_one(&sg_src, cmd->data, sz - sizeof(struct netfs_cmd));
+ sg_init_one(&sg_dst, cmd->data, sz - sizeof(struct netfs_cmd));
+
+ err = iterator(e, &sg_dst, &sg_src);
+ if (err)
+ return err;
+ }
+
+ if (!pages)
+ return 0;
+
+ dpage_idx = 0;
+ for (i=0; i<t->page_num; ++i) {
+ struct page *page = t->pages[i];
+ struct page *dpage = e->pages[dpage_idx];
+
+ if (!page)
+ continue;
+
+ sg_init_table(&sg_src, 1);
+ sg_init_table(&sg_dst, 1);
+ sg_set_page(&sg_src, page, page_private(page), 0);
+ sg_set_page(&sg_dst, dpage, page_private(page), 0);
+
+ err = iterator(e, &sg_dst, &sg_src);
+ if (err)
+ return err;
+
+ pages--;
+ if (!pages)
+ break;
+ dpage_idx++;
+ }
+
+ return 0;
+}
+
+static int pohmelfs_encrypt_iterator(struct pohmelfs_crypto_engine *e,
+ struct scatterlist *sg_dst, struct scatterlist *sg_src)
+{
+ struct ablkcipher_request *req = e->data;
+ u8 iv[32];
+
+ memset(iv, 0, sizeof(iv));
+
+ memcpy(iv, &e->iv, sizeof(e->iv));
+
+ return pohmelfs_crypto_process(req, sg_dst, sg_src, iv, 1, e->timeout);
+}
+
+static int pohmelfs_encrypt(struct pohmelfs_crypto_thread *tc)
+{
+ struct netfs_trans *t = tc->trans;
+ struct pohmelfs_crypto_engine *e = &tc->eng;
+ struct ablkcipher_request *req = e->data;
+
+ memset(req, 0, sizeof(struct ablkcipher_request));
+ ablkcipher_request_set_tfm(req, e->cipher);
+
+ e->iv = pohmelfs_gen_iv(t);
+
+ return pohmelfs_trans_iter(t, e, pohmelfs_encrypt_iterator);
+}
+
+static int pohmelfs_hash_iterator(struct pohmelfs_crypto_engine *e,
+ struct scatterlist *sg_dst, struct scatterlist *sg_src)
+{
+ return crypto_hash_update(e->data, sg_src, sg_src->length);
+}
+
+static int pohmelfs_hash(struct pohmelfs_crypto_thread *tc)
+{
+ struct pohmelfs_crypto_engine *e = &tc->eng;
+ struct hash_desc *desc = e->data;
+ unsigned char *dst = tc->trans->iovec.iov_base + sizeof(struct netfs_cmd);
+ int err;
+
+ desc->tfm = e->hash;
+ desc->flags = 0;
+
+ err = crypto_hash_init(desc);
+ if (err)
+ return err;
+
+ err = pohmelfs_trans_iter(tc->trans, e, pohmelfs_hash_iterator);
+ if (err)
+ return err;
+
+ err = crypto_hash_final(desc, dst);
+ if (err)
+ return err;
+
+ {
+ unsigned int i;
+ dprintk("%s: ", __func__);
+ for (i=0; i<tc->psb->crypto_attached_size; ++i)
+ dprintka("%02x ", dst[i]);
+ dprintka("\n");
+ }
+
+ return 0;
+}
+
+static void pohmelfs_crypto_pages_free(struct pohmelfs_crypto_engine *e)
+{
+ unsigned int i;
+
+ for (i=0; i<e->page_num; ++i)
+ __free_page(e->pages[i]);
+ kfree(e->pages);
+}
+
+static int pohmelfs_crypto_pages_alloc(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb)
+{
+ unsigned int i;
+
+ e->pages = kmalloc(psb->trans_max_pages * sizeof(struct page *), GFP_KERNEL);
+ if (!e->pages)
+ return -ENOMEM;
+
+ for (i=0; i<psb->trans_max_pages; ++i) {
+ e->pages[i] = alloc_page(GFP_KERNEL);
+ if (!e->pages[i])
+ break;
+ }
+
+ e->page_num = i;
+ if (!e->page_num)
+ goto err_out_free;
+
+ return 0;
+
+err_out_free:
+ kfree(e->pages);
+ return -ENOMEM;
+}
+
+static void pohmelfs_sys_crypto_exit_one(struct pohmelfs_crypto_thread *t)
+{
+ struct pohmelfs_sb *psb = t->psb;
+
+ if (t->thread)
+ kthread_stop(t->thread);
+
+ mutex_lock(&psb->crypto_thread_lock);
+ list_del(&t->thread_entry);
+ psb->crypto_thread_num--;
+ mutex_unlock(&psb->crypto_thread_lock);
+
+ pohmelfs_crypto_engine_exit(&t->eng);
+ pohmelfs_crypto_pages_free(&t->eng);
+ kfree(t);
+}
+
+static int pohmelfs_crypto_finish(struct netfs_trans *t, struct pohmelfs_sb *psb, int err)
+{
+ struct netfs_cmd *cmd = t->iovec.iov_base;
+ netfs_convert_cmd(cmd);
+
+ if (likely(!err))
+ err = netfs_trans_finish_send(t, psb);
+
+ t->result = err;
+ netfs_trans_put(t);
+
+ return err;
+}
+
+void pohmelfs_crypto_thread_make_ready(struct pohmelfs_crypto_thread *th)
+{
+ struct pohmelfs_sb *psb = th->psb;
+
+ th->page = NULL;
+ th->trans = NULL;
+
+ mutex_lock(&psb->crypto_thread_lock);
+ list_move_tail(&th->thread_entry, &psb->crypto_ready_list);
+ mutex_unlock(&psb->crypto_thread_lock);
+ wake_up(&psb->wait);
+}
+
+static int pohmelfs_crypto_thread_trans(struct pohmelfs_crypto_thread *t)
+{
+ struct netfs_trans *trans;
+ int err = 0;
+
+ trans = t->trans;
+ trans->eng = NULL;
+
+ if (t->eng.hash) {
+ err = pohmelfs_hash(t);
+ if (err)
+ goto out_complete;
+ }
+
+ if (t->eng.cipher) {
+ err = pohmelfs_encrypt(t);
+ if (err)
+ goto out_complete;
+ trans->eng = &t->eng;
+ }
+
+out_complete:
+ t->page = NULL;
+ t->trans = NULL;
+
+ if (!trans->eng)
+ pohmelfs_crypto_thread_make_ready(t);
+
+ pohmelfs_crypto_finish(trans, t->psb, err);
+ return err;
+}
+
+static int pohmelfs_crypto_thread_page(struct pohmelfs_crypto_thread *t)
+{
+ struct pohmelfs_crypto_engine *e = &t->eng;
+ struct page *page = t->page;
+ int err;
+
+ WARN_ON(!PageChecked(page));
+
+ err = pohmelfs_crypto_process_input_data(e, e->iv, NULL, page, t->size);
+ if (!err)
+ SetPageUptodate(page);
+ else
+ SetPageError(page);
+ unlock_page(page);
+ page_cache_release(page);
+
+ pohmelfs_crypto_thread_make_ready(t);
+
+ return err;
+}
+
+static int pohmelfs_crypto_thread_func(void *data)
+{
+ struct pohmelfs_crypto_thread *t = data;
+
+ while (!kthread_should_stop()) {
+ wait_event_interruptible(t->wait, kthread_should_stop() ||
+ t->trans || t->page);
+
+ if (kthread_should_stop())
+ break;
+
+ if (!t->trans && !t->page)
+ continue;
+
+ dprintk("%s: thread: %p, trans: %p, page: %p.\n",
+ __func__, t, t->trans, t->page);
+
+ if (t->trans)
+ pohmelfs_crypto_thread_trans(t);
+ else if (t->page)
+ pohmelfs_crypto_thread_page(t);
+ }
+
+ return 0;
+}
+
+static void pohmelfs_crypto_flush(struct pohmelfs_sb *psb, struct list_head *head)
+{
+ while (!list_empty(head)) {
+ struct pohmelfs_crypto_thread *t = NULL;
+
+ mutex_lock(&psb->crypto_thread_lock);
+ if (!list_empty(head)) {
+ t = list_first_entry(head, struct pohmelfs_crypto_thread, thread_entry);
+ list_del_init(&t->thread_entry);
+ }
+ mutex_unlock(&psb->crypto_thread_lock);
+
+ if (t)
+ pohmelfs_sys_crypto_exit_one(t);
+ }
+}
+
+static void pohmelfs_sys_crypto_exit(struct pohmelfs_sb *psb)
+{
+ while (!list_empty(&psb->crypto_active_list) || !list_empty(&psb->crypto_ready_list)) {
+ dprintk("%s: crypto_thread_num: %u.\n", __func__, psb->crypto_thread_num);
+ pohmelfs_crypto_flush(psb, &psb->crypto_active_list);
+ pohmelfs_crypto_flush(psb, &psb->crypto_ready_list);
+ }
+}
+
+static int pohmelfs_sys_crypto_init(struct pohmelfs_sb *psb)
+{
+ unsigned int i;
+ struct pohmelfs_crypto_thread *t;
+ struct pohmelfs_config *c;
+ struct netfs_state *st;
+ int err;
+
+ list_for_each_entry(c, &psb->state_list, config_entry) {
+ st = &c->state;
+
+ err = pohmelfs_crypto_engine_init(&st->eng, psb);
+ if (err)
+ goto err_out_exit;
+
+ dprintk("%s: st: %p, eng: %p, hash: %p, cipher: %p.\n",
+ __func__, st, &st->eng, &st->eng.hash, &st->eng.cipher);
+ }
+
+ for (i=0; i<psb->crypto_thread_num; ++i) {
+ err = -ENOMEM;
+ t = kzalloc(sizeof(struct pohmelfs_crypto_thread), GFP_KERNEL);
+ if (!t)
+ goto err_out_free_state_engines;
+
+ init_waitqueue_head(&t->wait);
+
+ t->psb = psb;
+ t->trans = NULL;
+ t->eng.thread = t;
+
+ err = pohmelfs_crypto_engine_init(&t->eng, psb);
+ if (err)
+ goto err_out_free_state_engines;
+
+ err = pohmelfs_crypto_pages_alloc(&t->eng, psb);
+ if (err)
+ goto err_out_free;
+
+ t->thread = kthread_run(pohmelfs_crypto_thread_func, t,
+ "pohmelfs-crypto-%d-%d", psb->idx, i);
+ if (IS_ERR(t->thread)) {
+ err = PTR_ERR(t->thread);
+ t->thread = NULL;
+ goto err_out_free;
+ }
+
+ if (t->eng.cipher)
+ psb->crypto_align_size = crypto_ablkcipher_blocksize(t->eng.cipher);
+
+ mutex_lock(&psb->crypto_thread_lock);
+ list_add_tail(&t->thread_entry, &psb->crypto_ready_list);
+ mutex_unlock(&psb->crypto_thread_lock);
+ }
+
+ psb->crypto_thread_num = i;
+ return 0;
+
+err_out_free:
+ pohmelfs_sys_crypto_exit_one(t);
+err_out_free_state_engines:
+ list_for_each_entry(c, &psb->state_list, config_entry) {
+ st = &c->state;
+ pohmelfs_crypto_engine_exit(&st->eng);
+ }
+err_out_exit:
+ pohmelfs_sys_crypto_exit(psb);
+ return err;
+}
+
+void pohmelfs_crypto_exit(struct pohmelfs_sb *psb)
+{
+ pohmelfs_sys_crypto_exit(psb);
+
+ kfree(psb->hash_string);
+ kfree(psb->cipher_string);
+}
+
+static int pohmelfs_crypt_init_complete(struct page **pages, unsigned int page_num,
+ void *private, int err)
+{
+ struct pohmelfs_sb *psb = private;
+
+ psb->flags = -err;
+ dprintk("%s: err: %d.\n", __func__, err);
+
+ wake_up(&psb->wait);
+
+ return err;
+}
+
+static int pohmelfs_crypto_init_handshake(struct pohmelfs_sb *psb)
+{
+ struct netfs_trans *t;
+ struct netfs_crypto_capabilities *cap;
+ struct netfs_cmd *cmd;
+ char *str;
+ int err = -ENOMEM, size;
+
+ size = sizeof(struct netfs_crypto_capabilities) +
+ psb->cipher_strlen + psb->hash_strlen + 2; /* 0 bytes */
+
+ t = netfs_trans_alloc(psb, size, 0, 0);
+ if (!t)
+ goto err_out_exit;
+
+ t->complete = pohmelfs_crypt_init_complete;
+ t->private = psb;
+
+ cmd = netfs_trans_current(t);
+ cap = (struct netfs_crypto_capabilities *)(cmd + 1);
+ str = (char *)(cap + 1);
+
+ cmd->cmd = NETFS_CAPABILITIES;
+ cmd->id = POHMELFS_CRYPTO_CAPABILITIES;
+ cmd->size = size;
+ cmd->start = 0;
+ cmd->ext = 0;
+ cmd->csize = 0;
+
+ netfs_convert_cmd(cmd);
+ netfs_trans_update(cmd, t, size);
+
+ cap->hash_strlen = psb->hash_strlen;
+ if (cap->hash_strlen) {
+ sprintf(str, "%s", psb->hash_string);
+ str += cap->hash_strlen;
+ }
+
+ cap->cipher_strlen = psb->cipher_strlen;
+ cap->cipher_keysize = psb->cipher_keysize;
+ if (cap->cipher_strlen)
+ sprintf(str, "%s", psb->cipher_string);
+
+ netfs_convert_crypto_capabilities(cap);
+
+ psb->flags = ~0;
+ err = netfs_trans_finish(t, psb);
+ if (err)
+ goto err_out_exit;
+
+ err = wait_event_interruptible_timeout(psb->wait, (psb->flags != ~0),
+ psb->wait_on_page_timeout);
+ if (!err)
+ err = -ETIMEDOUT;
+ else
+ err = -psb->flags;
+
+ if (!err)
+ psb->perform_crypto = 1;
+ psb->flags = 0;
+
+ /*
+ * At this point NETFS_CAPABILITIES response command
+ * should setup superblock in a way, which is acceptible
+ * for both client and server, so if server refuses connection,
+ * it will send error in transaction response.
+ */
+
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+int pohmelfs_crypto_init(struct pohmelfs_sb *psb)
+{
+ int err;
+
+ if (!psb->cipher_string && !psb->hash_string)
+ return 0;
+
+ err = pohmelfs_crypto_init_handshake(psb);
+ if (err)
+ return err;
+
+ err = pohmelfs_sys_crypto_init(psb);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int pohmelfs_crypto_thread_get(struct pohmelfs_sb *psb,
+ int (* action)(struct pohmelfs_crypto_thread *t, void *data), void *data)
+{
+ struct pohmelfs_crypto_thread *t = NULL;
+ int err;
+
+ while (!t) {
+ err = wait_event_interruptible_timeout(psb->wait,
+ !list_empty(&psb->crypto_ready_list),
+ psb->wait_on_page_timeout);
+
+ t = NULL;
+ err = 0;
+ mutex_lock(&psb->crypto_thread_lock);
+ if (!list_empty(&psb->crypto_ready_list)) {
+ t = list_entry(psb->crypto_ready_list.prev,
+ struct pohmelfs_crypto_thread,
+ thread_entry);
+
+ list_move_tail(&t->thread_entry,
+ &psb->crypto_active_list);
+
+ action(t, data);
+ wake_up(&t->wait);
+
+ }
+ mutex_unlock(&psb->crypto_thread_lock);
+ }
+
+ return err;
+}
+
+static int pohmelfs_trans_crypt_action(struct pohmelfs_crypto_thread *t, void *data)
+{
+ struct netfs_trans *trans = data;
+
+ netfs_trans_get(trans);
+ t->trans = trans;
+
+ dprintk("%s: t: %p, gen: %u, thread: %p.\n", __func__, trans, trans->gen, t);
+ return 0;
+}
+
+int pohmelfs_trans_crypt(struct netfs_trans *trans, struct pohmelfs_sb *psb)
+{
+ if ((!psb->hash_string && !psb->cipher_string) || !psb->perform_crypto) {
+ netfs_trans_get(trans);
+ return pohmelfs_crypto_finish(trans, psb, 0);
+ }
+
+ return pohmelfs_crypto_thread_get(psb, pohmelfs_trans_crypt_action, trans);
+}
+
+struct pohmelfs_crypto_input_action_data
+{
+ struct page *page;
+ struct pohmelfs_crypto_engine *e;
+ u64 iv;
+ unsigned int size;
+};
+
+static int pohmelfs_crypt_input_page_action(struct pohmelfs_crypto_thread *t, void *data)
+{
+ struct pohmelfs_crypto_input_action_data *act = data;
+
+ memcpy(t->eng.data, act->e->data, t->psb->crypto_attached_size);
+
+ t->size = act->size;
+ t->eng.iv = act->iv;
+
+ t->page = act->page;
+ return 0;
+}
+
+int pohmelfs_crypto_process_input_page(struct pohmelfs_crypto_engine *e,
+ struct page *page, unsigned int size, u64 iv)
+{
+ struct inode *inode = page->mapping->host;
+ struct pohmelfs_crypto_input_action_data act;
+ int err = -ENOENT;
+
+ act.page = page;
+ act.e = e;
+ act.size = size;
+ act.iv = iv;
+
+ err = pohmelfs_crypto_thread_get(POHMELFS_SB(inode->i_sb),
+ pohmelfs_crypt_input_page_action, &act);
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ SetPageUptodate(page);
+ page_cache_release(page);
+
+ return err;
+}
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c
new file mode 100644
index 00000000000..7a41183a32e
--- /dev/null
+++ b/drivers/staging/pohmelfs/dir.c
@@ -0,0 +1,1093 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/jhash.h>
+#include <linux/namei.h>
+#include <linux/pagemap.h>
+
+#include "netfs.h"
+
+static int pohmelfs_cmp_hash(struct pohmelfs_name *n, u32 hash)
+{
+ if (n->hash > hash)
+ return -1;
+ if (n->hash < hash)
+ return 1;
+
+ return 0;
+}
+
+static struct pohmelfs_name *pohmelfs_search_hash_unprecise(struct pohmelfs_inode *pi, u32 hash)
+{
+ struct rb_node *n = pi->hash_root.rb_node;
+ struct pohmelfs_name *tmp = NULL;
+ int cmp;
+
+ while (n) {
+ tmp = rb_entry(n, struct pohmelfs_name, hash_node);
+
+ cmp = pohmelfs_cmp_hash(tmp, hash);
+ if (cmp < 0)
+ n = n->rb_left;
+ else if (cmp > 0)
+ n = n->rb_right;
+ else
+ break;
+
+ }
+
+ return tmp;
+}
+
+struct pohmelfs_name *pohmelfs_search_hash(struct pohmelfs_inode *pi, u32 hash)
+{
+ struct pohmelfs_name *tmp;
+
+ tmp = pohmelfs_search_hash_unprecise(pi, hash);
+ if (tmp && (tmp->hash == hash))
+ return tmp;
+
+ return NULL;
+}
+
+static void __pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
+{
+ rb_erase(&node->hash_node, &parent->hash_root);
+}
+
+/*
+ * Remove name cache entry from its caches and free it.
+ */
+static void pohmelfs_name_free(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
+{
+ __pohmelfs_name_del(parent, node);
+ list_del(&node->sync_create_entry);
+ kfree(node);
+}
+
+static struct pohmelfs_name *pohmelfs_insert_hash(struct pohmelfs_inode *pi,
+ struct pohmelfs_name *new)
+{
+ struct rb_node **n = &pi->hash_root.rb_node, *parent = NULL;
+ struct pohmelfs_name *ret = NULL, *tmp;
+ int cmp;
+
+ while (*n) {
+ parent = *n;
+
+ tmp = rb_entry(parent, struct pohmelfs_name, hash_node);
+
+ cmp = pohmelfs_cmp_hash(tmp, new->hash);
+ if (cmp < 0)
+ n = &parent->rb_left;
+ else if (cmp > 0)
+ n = &parent->rb_right;
+ else {
+ ret = tmp;
+ break;
+ }
+ }
+
+ if (ret) {
+ printk("%s: exist: parent: %llu, ino: %llu, hash: %x, len: %u, data: '%s', "
+ "new: ino: %llu, hash: %x, len: %u, data: '%s'.\n",
+ __func__, pi->ino,
+ ret->ino, ret->hash, ret->len, ret->data,
+ new->ino, new->hash, new->len, new->data);
+ ret->ino = new->ino;
+ return ret;
+ }
+
+ rb_link_node(&new->hash_node, parent, n);
+ rb_insert_color(&new->hash_node, &pi->hash_root);
+
+ return NULL;
+}
+
+/*
+ * Free name cache for given inode.
+ */
+void pohmelfs_free_names(struct pohmelfs_inode *parent)
+{
+ struct rb_node *rb_node;
+ struct pohmelfs_name *n;
+
+ for (rb_node = rb_first(&parent->hash_root); rb_node;) {
+ n = rb_entry(rb_node, struct pohmelfs_name, hash_node);
+ rb_node = rb_next(rb_node);
+
+ pohmelfs_name_free(parent, n);
+ }
+}
+
+static void pohmelfs_fix_offset(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
+{
+ parent->total_len -= node->len;
+}
+
+/*
+ * Free name cache entry helper.
+ */
+void pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
+{
+ pohmelfs_fix_offset(parent, node);
+ pohmelfs_name_free(parent, node);
+}
+
+/*
+ * Insert new name cache entry into all hash cache.
+ */
+static int pohmelfs_insert_name(struct pohmelfs_inode *parent, struct pohmelfs_name *n)
+{
+ struct pohmelfs_name *name;
+
+ name = pohmelfs_insert_hash(parent, n);
+ if (name)
+ return -EEXIST;
+
+ parent->total_len += n->len;
+ list_add_tail(&n->sync_create_entry, &parent->sync_create_list);
+
+ return 0;
+}
+
+/*
+ * Allocate new name cache entry.
+ */
+static struct pohmelfs_name *pohmelfs_name_alloc(unsigned int len)
+{
+ struct pohmelfs_name *n;
+
+ n = kzalloc(sizeof(struct pohmelfs_name) + len, GFP_KERNEL);
+ if (!n)
+ return NULL;
+
+ INIT_LIST_HEAD(&n->sync_create_entry);
+
+ n->data = (char *)(n+1);
+
+ return n;
+}
+
+/*
+ * Add new name entry into directory's cache.
+ */
+static int pohmelfs_add_dir(struct pohmelfs_sb *psb, struct pohmelfs_inode *parent,
+ struct pohmelfs_inode *npi, struct qstr *str, unsigned int mode, int link)
+{
+ int err = -ENOMEM;
+ struct pohmelfs_name *n;
+
+ n = pohmelfs_name_alloc(str->len + 1);
+ if (!n)
+ goto err_out_exit;
+
+ n->ino = npi->ino;
+ n->mode = mode;
+ n->len = str->len;
+ n->hash = str->hash;
+ sprintf(n->data, "%s", str->name);
+
+ mutex_lock(&parent->offset_lock);
+ err = pohmelfs_insert_name(parent, n);
+ mutex_unlock(&parent->offset_lock);
+
+ if (err) {
+ if (err != -EEXIST)
+ goto err_out_free;
+ kfree(n);
+ }
+
+ return 0;
+
+err_out_free:
+ kfree(n);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Create new inode for given parameters (name, inode info, parent).
+ * This does not create object on the server, it will be synced there during writeback.
+ */
+struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb,
+ struct pohmelfs_inode *parent, struct qstr *str,
+ struct netfs_inode_info *info, int link)
+{
+ struct inode *new = NULL;
+ struct pohmelfs_inode *npi;
+ int err = -EEXIST;
+
+ dprintk("%s: creating inode: parent: %llu, ino: %llu, str: %p.\n",
+ __func__, (parent)?parent->ino:0, info->ino, str);
+
+ err = -ENOMEM;
+ new = iget_locked(psb->sb, info->ino);
+ if (!new)
+ goto err_out_exit;
+
+ npi = POHMELFS_I(new);
+ npi->ino = info->ino;
+ err = 0;
+
+ if (new->i_state & I_NEW) {
+ dprintk("%s: filling VFS inode: %lu/%llu.\n",
+ __func__, new->i_ino, info->ino);
+ pohmelfs_fill_inode(new, info);
+
+ if (S_ISDIR(info->mode)) {
+ struct qstr s;
+
+ s.name = ".";
+ s.len = 1;
+ s.hash = jhash(s.name, s.len, 0);
+
+ err = pohmelfs_add_dir(psb, npi, npi, &s, info->mode, 0);
+ if (err)
+ goto err_out_put;
+
+ s.name = "..";
+ s.len = 2;
+ s.hash = jhash(s.name, s.len, 0);
+
+ err = pohmelfs_add_dir(psb, npi, (parent)?parent:npi, &s,
+ (parent)?parent->vfs_inode.i_mode:npi->vfs_inode.i_mode, 0);
+ if (err)
+ goto err_out_put;
+ }
+ }
+
+ if (str) {
+ if (parent) {
+ err = pohmelfs_add_dir(psb, parent, npi, str, info->mode, link);
+
+ dprintk("%s: %s inserted name: '%s', new_offset: %llu, ino: %llu, parent: %llu.\n",
+ __func__, (err)?"unsuccessfully":"successfully",
+ str->name, parent->total_len, info->ino, parent->ino);
+
+ if (err && err != -EEXIST)
+ goto err_out_put;
+ }
+ }
+
+ if (new->i_state & I_NEW) {
+ if (parent)
+ mark_inode_dirty(&parent->vfs_inode);
+ mark_inode_dirty(new);
+ }
+
+ set_bit(NETFS_INODE_OWNED, &npi->state);
+ npi->lock_type = POHMELFS_WRITE_LOCK;
+ unlock_new_inode(new);
+
+ return npi;
+
+err_out_put:
+ printk("%s: putting inode: %p, npi: %p, error: %d.\n", __func__, new, npi, err);
+ iput(new);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+static int pohmelfs_remote_sync_complete(struct page **pages, unsigned int page_num,
+ void *private, int err)
+{
+ struct pohmelfs_inode *pi = private;
+ struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+
+ dprintk("%s: ino: %llu, err: %d.\n", __func__, pi->ino, err);
+
+ if (err)
+ pi->error = err;
+ wake_up(&psb->wait);
+ pohmelfs_put_inode(pi);
+
+ return err;
+}
+
+/*
+ * Receive directory content from the server.
+ * This should be only done for objects, which were not created locally,
+ * and which were not synced previously.
+ */
+static int pohmelfs_sync_remote_dir(struct pohmelfs_inode *pi)
+{
+ struct inode *inode = &pi->vfs_inode;
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ long ret = msecs_to_jiffies(25000);
+ int err;
+
+ dprintk("%s: dir: %llu, state: %lx: remote_synced: %d.\n",
+ __func__, pi->ino, pi->state, test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state));
+
+ if (test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state))
+ return 0;
+
+ if (!igrab(inode)) {
+ err = -ENOENT;
+ goto err_out_exit;
+ }
+
+ err = pohmelfs_meta_command(pi, NETFS_READDIR, NETFS_TRANS_SINGLE_DST,
+ pohmelfs_remote_sync_complete, pi, 0);
+ if (err)
+ goto err_out_exit;
+
+ pi->error = 0;
+ ret = wait_event_interruptible_timeout(psb->wait,
+ test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state) || pi->error, ret);
+ dprintk("%s: awake dir: %llu, ret: %ld, err: %d.\n", __func__, pi->ino, ret, pi->error);
+ if (ret <= 0) {
+ err = -ETIMEDOUT;
+ goto err_out_exit;
+ }
+
+ if (pi->error)
+ return pi->error;
+
+ return 0;
+
+err_out_exit:
+ clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+
+ return err;
+}
+
+static int pohmelfs_dir_open(struct inode *inode, struct file *file)
+{
+ file->private_data = NULL;
+ return 0;
+}
+
+/*
+ * VFS readdir callback. Syncs directory content from server if needed,
+ * and provides direntry info to the userspace.
+ */
+static int pohmelfs_readdir(struct file *file, void *dirent, filldir_t filldir)
+{
+ struct inode *inode = file->f_path.dentry->d_inode;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ struct pohmelfs_name *n;
+ struct rb_node *rb_node;
+ int err = 0, mode;
+ u64 len;
+
+ dprintk("%s: parent: %llu, fpos: %llu, hash: %08lx.\n",
+ __func__, pi->ino, (u64)file->f_pos,
+ (unsigned long)file->private_data);
+
+ err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK);
+ if (err)
+ return err;
+
+ err = pohmelfs_sync_remote_dir(pi);
+ if (err)
+ return err;
+
+ if (file->private_data && (file->private_data == (void *)(unsigned long)file->f_pos))
+ return 0;
+
+ mutex_lock(&pi->offset_lock);
+ n = pohmelfs_search_hash_unprecise(pi, (unsigned long)file->private_data);
+
+ while (n) {
+ mode = (n->mode >> 12) & 15;
+
+ dprintk("%s: offset: %llu, parent ino: %llu, name: '%s', len: %u, ino: %llu, "
+ "mode: %o/%o, fpos: %llu, hash: %08x.\n",
+ __func__, file->f_pos, pi->ino, n->data, n->len,
+ n->ino, n->mode, mode, file->f_pos, n->hash);
+
+ file->private_data = (void *)n->hash;
+
+ len = n->len;
+ err = filldir(dirent, n->data, n->len, file->f_pos, n->ino, mode);
+
+ if (err < 0) {
+ dprintk("%s: err: %d.\n", __func__, err);
+ err = 0;
+ break;
+ }
+
+ file->f_pos += len;
+
+ rb_node = rb_next(&n->hash_node);
+
+ if (!rb_node || (rb_node == &n->hash_node)) {
+ file->private_data = (void *)(unsigned long)file->f_pos;
+ break;
+ }
+
+ n = rb_entry(rb_node, struct pohmelfs_name, hash_node);
+ }
+ mutex_unlock(&pi->offset_lock);
+
+ return err;
+}
+
+static loff_t pohmelfs_dir_lseek(struct file *file, loff_t offset, int origin)
+{
+ file->f_pos = offset;
+ file->private_data = NULL;
+ return offset;
+}
+
+const struct file_operations pohmelfs_dir_fops = {
+ .open = pohmelfs_dir_open,
+ .read = generic_read_dir,
+ .llseek = pohmelfs_dir_lseek,
+ .readdir = pohmelfs_readdir,
+};
+
+/*
+ * Lookup single object on server.
+ */
+static int pohmelfs_lookup_single(struct pohmelfs_inode *parent,
+ struct qstr *str, u64 ino)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(parent->vfs_inode.i_sb);
+ long ret = msecs_to_jiffies(5000);
+ int err;
+
+ set_bit(NETFS_COMMAND_PENDING, &parent->state);
+ err = pohmelfs_meta_command_data(parent, parent->ino, NETFS_LOOKUP,
+ (char *)str->name, NETFS_TRANS_SINGLE_DST, NULL, NULL, ino);
+ if (err)
+ goto err_out_exit;
+
+ err = 0;
+ ret = wait_event_interruptible_timeout(psb->wait,
+ !test_bit(NETFS_COMMAND_PENDING, &parent->state), ret);
+ if (ret == 0)
+ err = -ETIMEDOUT;
+ else if (signal_pending(current))
+ err = -EINTR;
+
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ clear_bit(NETFS_COMMAND_PENDING, &parent->state);
+
+ printk("%s: failed: parent: %llu, ino: %llu, name: '%s', err: %d.\n",
+ __func__, parent->ino, ino, str->name, err);
+
+ return err;
+}
+
+/*
+ * VFS lookup callback.
+ * We first try to get inode number from local name cache, if we have one,
+ * then inode can be found in inode cache. If there is no inode or no object in
+ * local cache, try to lookup it on server. This only should be done for directories,
+ * which were not created locally, otherwise remote server does not know about dir at all,
+ * so no need to try to know that.
+ */
+struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+{
+ struct pohmelfs_inode *parent = POHMELFS_I(dir);
+ struct pohmelfs_name *n;
+ struct inode *inode = NULL;
+ unsigned long ino = 0;
+ int err, lock_type = POHMELFS_READ_LOCK, need_lock;
+ struct qstr str = dentry->d_name;
+
+ if ((nd->intent.open.flags & O_ACCMODE) > 1)
+ lock_type = POHMELFS_WRITE_LOCK;
+
+ need_lock = pohmelfs_need_lock(parent, lock_type);
+
+ err = pohmelfs_data_lock(parent, 0, ~0, lock_type);
+ if (err)
+ goto out;
+
+ str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+ mutex_lock(&parent->offset_lock);
+ n = pohmelfs_search_hash(parent, str.hash);
+ if (n)
+ ino = n->ino;
+ mutex_unlock(&parent->offset_lock);
+
+ dprintk("%s: 1 ino: %lu, inode: %p, name: '%s', hash: %x, parent_state: %lx.\n",
+ __func__, ino, inode, str.name, str.hash, parent->state);
+
+ if (ino) {
+ inode = ilookup(dir->i_sb, ino);
+ if (inode)
+ goto out;
+ }
+
+ dprintk("%s: dir: %p, dir_ino: %llu, name: '%s', len: %u, dir_state: %lx, ino: %lu.\n",
+ __func__, dir, parent->ino,
+ str.name, str.len, parent->state, ino);
+
+ if (!ino) {
+ if (!need_lock)
+ goto out;
+ }
+
+ err = pohmelfs_lookup_single(parent, &str, ino);
+ if (err)
+ goto out;
+
+ if (!ino) {
+ mutex_lock(&parent->offset_lock);
+ n = pohmelfs_search_hash(parent, str.hash);
+ if (n)
+ ino = n->ino;
+ mutex_unlock(&parent->offset_lock);
+ }
+
+ if (ino) {
+ inode = ilookup(dir->i_sb, ino);
+ printk("%s: second lookup ino: %lu, inode: %p, name: '%s', hash: %x.\n",
+ __func__, ino, inode, str.name, str.hash);
+ if (!inode) {
+ printk("%s: No inode for ino: %lu, name: '%s', hash: %x.\n",
+ __func__, ino, str.name, str.hash);
+ //return NULL;
+ return ERR_PTR(-EACCES);
+ }
+ } else {
+ printk("%s: No inode number : name: '%s', hash: %x.\n",
+ __func__, str.name, str.hash);
+ }
+out:
+ return d_splice_alias(inode, dentry);
+}
+
+/*
+ * Create new object in local cache. Object will be synced to server
+ * during writeback for given inode.
+ */
+struct pohmelfs_inode *pohmelfs_create_entry_local(struct pohmelfs_sb *psb,
+ struct pohmelfs_inode *parent, struct qstr *str, u64 start, int mode)
+{
+ struct pohmelfs_inode *npi;
+ int err = -ENOMEM;
+ struct netfs_inode_info info;
+
+ dprintk("%s: name: '%s', mode: %o, start: %llu.\n",
+ __func__, str->name, mode, start);
+
+ info.mode = mode;
+ info.ino = start;
+
+ if (!start)
+ info.ino = pohmelfs_new_ino(psb);
+
+ info.nlink = S_ISDIR(mode)?2:1;
+ info.uid = current_fsuid();
+ info.gid = current_fsgid();
+ info.size = 0;
+ info.blocksize = 512;
+ info.blocks = 0;
+ info.rdev = 0;
+ info.version = 0;
+
+ npi = pohmelfs_new_inode(psb, parent, str, &info, !!start);
+ if (IS_ERR(npi)) {
+ err = PTR_ERR(npi);
+ goto err_out_unlock;
+ }
+
+ return npi;
+
+err_out_unlock:
+ dprintk("%s: err: %d.\n", __func__, err);
+ return ERR_PTR(err);
+}
+
+/*
+ * Create local object and bind it to dentry.
+ */
+static int pohmelfs_create_entry(struct inode *dir, struct dentry *dentry, u64 start, int mode)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(dir->i_sb);
+ struct pohmelfs_inode *npi, *parent;
+ struct qstr str = dentry->d_name;
+ int err;
+
+ parent = POHMELFS_I(dir);
+
+ err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
+ if (err)
+ return err;
+
+ str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+ npi = pohmelfs_create_entry_local(psb, parent, &str, start, mode);
+ if (IS_ERR(npi))
+ return PTR_ERR(npi);
+
+ d_instantiate(dentry, &npi->vfs_inode);
+
+ dprintk("%s: parent: %llu, inode: %llu, name: '%s', parent_nlink: %d, nlink: %d.\n",
+ __func__, parent->ino, npi->ino, dentry->d_name.name,
+ (signed)dir->i_nlink, (signed)npi->vfs_inode.i_nlink);
+
+ return 0;
+}
+
+/*
+ * VFS create and mkdir callbacks.
+ */
+static int pohmelfs_create(struct inode *dir, struct dentry *dentry, int mode,
+ struct nameidata *nd)
+{
+ return pohmelfs_create_entry(dir, dentry, 0, mode);
+}
+
+static int pohmelfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ int err;
+
+ inode_inc_link_count(dir);
+ err = pohmelfs_create_entry(dir, dentry, 0, mode | S_IFDIR);
+ if (err)
+ inode_dec_link_count(dir);
+
+ return err;
+}
+
+static int pohmelfs_remove_entry(struct inode *dir, struct dentry *dentry)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(dir->i_sb);
+ struct inode *inode = dentry->d_inode;
+ struct pohmelfs_inode *parent = POHMELFS_I(dir), *pi = POHMELFS_I(inode);
+ struct pohmelfs_name *n;
+ int err = -ENOENT;
+ struct qstr str = dentry->d_name;
+
+ err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
+ if (err)
+ return err;
+
+ str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+ dprintk("%s: dir_ino: %llu, inode: %llu, name: '%s', nlink: %d.\n",
+ __func__, parent->ino, pi->ino,
+ str.name, (signed)inode->i_nlink);
+
+ BUG_ON(!inode);
+
+ mutex_lock(&parent->offset_lock);
+ n = pohmelfs_search_hash(parent, str.hash);
+ if (n) {
+ pohmelfs_fix_offset(parent, n);
+ if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state)) {
+ pohmelfs_remove_child(pi, n);
+ }
+ pohmelfs_name_free(parent, n);
+ err = 0;
+ }
+ mutex_unlock(&parent->offset_lock);
+
+ if (!err) {
+ psb->avail_size += inode->i_size;
+
+ pohmelfs_inode_del_inode(psb, pi);
+
+ mark_inode_dirty(dir);
+
+ inode->i_ctime = dir->i_ctime;
+ if (inode->i_nlink)
+ inode_dec_link_count(inode);
+ }
+ dprintk("%s: inode: %p, lock: %ld, unhashed: %d.\n",
+ __func__, pi, inode->i_state & I_LOCK, hlist_unhashed(&inode->i_hash));
+
+ return err;
+}
+
+/*
+ * Unlink and rmdir VFS callbacks.
+ */
+static int pohmelfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+ return pohmelfs_remove_entry(dir, dentry);
+}
+
+static int pohmelfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+ int err;
+ struct inode *inode = dentry->d_inode;
+
+ dprintk("%s: parent: %llu, inode: %llu, name: '%s', parent_nlink: %d, nlink: %d.\n",
+ __func__, POHMELFS_I(dir)->ino, POHMELFS_I(inode)->ino,
+ dentry->d_name.name, (signed)dir->i_nlink, (signed)inode->i_nlink);
+
+ err = pohmelfs_remove_entry(dir, dentry);
+ if (!err) {
+ inode_dec_link_count(dir);
+ inode_dec_link_count(inode);
+ }
+
+ return err;
+}
+
+/*
+ * Link creation is synchronous.
+ * I'm lazy.
+ * Earth is somewhat round.
+ */
+static int pohmelfs_create_link(struct pohmelfs_inode *parent, struct qstr *obj,
+ struct pohmelfs_inode *target, struct qstr *tstr)
+{
+ struct super_block *sb = parent->vfs_inode.i_sb;
+ struct pohmelfs_sb *psb = POHMELFS_SB(sb);
+ struct netfs_cmd *cmd;
+ struct netfs_trans *t;
+ void *data;
+ int err, parent_len, target_len = 0, cur_len, path_size = 0;
+
+ err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
+ if (err)
+ return err;
+
+ err = sb->s_op->write_inode(&parent->vfs_inode, 0);
+ if (err)
+ goto err_out_exit;
+
+ if (tstr)
+ target_len = tstr->len;
+
+ parent_len = pohmelfs_path_length(parent);
+ if (target)
+ target_len += pohmelfs_path_length(target);
+
+ if (parent_len < 0) {
+ err = parent_len;
+ goto err_out_exit;
+ }
+
+ if (target_len < 0) {
+ err = target_len;
+ goto err_out_exit;
+ }
+
+ t = netfs_trans_alloc(psb, parent_len + target_len + obj->len + 2, 0, 0);
+ if (!t) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+ cur_len = netfs_trans_cur_len(t);
+
+ cmd = netfs_trans_current(t);
+ if (IS_ERR(cmd)) {
+ err = PTR_ERR(cmd);
+ goto err_out_free;
+ }
+
+ data = (void *)(cmd + 1);
+ cur_len -= sizeof(struct netfs_cmd);
+
+ err = pohmelfs_construct_path_string(parent, data, parent_len);
+ if (err > 0) {
+ /* Do not place null-byte before the slash */
+ path_size = err - 1;
+ cur_len -= path_size;
+
+ err = snprintf(data + path_size, cur_len, "/%s|", obj->name);
+
+ path_size += err;
+ cur_len -= err;
+
+ cmd->ext = path_size - 1; /* No | symbol */
+
+ if (target) {
+ err = pohmelfs_construct_path_string(target, data + path_size, target_len);
+ if (err > 0) {
+ path_size += err;
+ cur_len -= err;
+ }
+ }
+ }
+
+ if (err < 0)
+ goto err_out_free;
+
+ cmd->start = 0;
+
+ if (!target && tstr) {
+ if (tstr->len > cur_len - 1) {
+ err = -ENAMETOOLONG;
+ goto err_out_free;
+ }
+
+ err = snprintf(data + path_size, cur_len, "%s", tstr->name) + 1; /* 0-byte */
+ path_size += err;
+ cur_len -= err;
+ cmd->start = 1;
+ }
+
+ dprintk("%s: parent: %llu, obj: '%s', target_inode: %llu, target_str: '%s', full: '%s'.\n",
+ __func__, parent->ino, obj->name, (target)?target->ino:0, (tstr)?tstr->name:NULL,
+ (char *)data);
+
+ cmd->cmd = NETFS_LINK;
+ cmd->size = path_size;
+ cmd->id = parent->ino;
+
+ netfs_convert_cmd(cmd);
+
+ netfs_trans_update(cmd, t, path_size);
+
+ err = netfs_trans_finish(t, psb);
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_free:
+ t->result = err;
+ netfs_trans_put(t);
+err_out_exit:
+ return err;
+}
+
+/*
+ * VFS hard and soft link callbacks.
+ */
+static int pohmelfs_link(struct dentry *old_dentry, struct inode *dir,
+ struct dentry *dentry)
+{
+ struct inode *inode = old_dentry->d_inode;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ int err;
+ struct qstr str = dentry->d_name;
+
+ str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+ err = inode->i_sb->s_op->write_inode(inode, 0);
+ if (err)
+ return err;
+
+ err = pohmelfs_create_link(POHMELFS_I(dir), &str, pi, NULL);
+ if (err)
+ return err;
+
+ return pohmelfs_create_entry(dir, dentry, pi->ino, inode->i_mode);
+}
+
+static int pohmelfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+{
+ struct qstr sym_str;
+ struct qstr str = dentry->d_name;
+ struct inode *inode;
+ int err;
+
+ str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+ sym_str.name = symname;
+ sym_str.len = strlen(symname);
+
+ err = pohmelfs_create_link(POHMELFS_I(dir), &str, NULL, &sym_str);
+ if (err)
+ goto err_out_exit;
+
+ err = pohmelfs_create_entry(dir, dentry, 0, S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO);
+ if (err)
+ goto err_out_exit;
+
+ inode = dentry->d_inode;
+
+ err = page_symlink(inode, symname, sym_str.len + 1);
+ if (err)
+ goto err_out_put;
+
+ return 0;
+
+err_out_put:
+ iput(inode);
+err_out_exit:
+ return err;
+}
+
+static int pohmelfs_send_rename(struct pohmelfs_inode *pi, struct pohmelfs_inode *parent,
+ struct qstr *str)
+{
+ int path_len, err, total_len = 0, inode_len, parent_len;
+ char *path;
+ struct netfs_trans *t;
+ struct netfs_cmd *cmd;
+ struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+
+ parent_len = pohmelfs_path_length(parent);
+ inode_len = pohmelfs_path_length(pi);
+
+ if (parent_len < 0 || inode_len < 0)
+ return -EINVAL;
+
+ path_len = parent_len + inode_len + str->len + 3;
+
+ t = netfs_trans_alloc(psb, path_len, 0, 0);
+ if (!t)
+ return -ENOMEM;
+
+ cmd = netfs_trans_current(t);
+ path = (char *)(cmd + 1);
+
+ err = pohmelfs_construct_path_string(pi, path, inode_len);
+ if (err < 0)
+ goto err_out_unlock;
+
+ cmd->ext = err;
+
+ path += err;
+ total_len += err;
+ path_len -= err;
+
+ *path = '|';
+ path++;
+ total_len++;
+ path_len--;
+
+ err = pohmelfs_construct_path_string(parent, path, parent_len);
+ if (err < 0)
+ goto err_out_unlock;
+
+ /*
+ * Do not place a null-byte before the final slash and the name.
+ */
+ err--;
+ path += err;
+ total_len += err;
+ path_len -= err;
+
+ err = snprintf(path, path_len - 1, "/%s", str->name);
+
+ total_len += err + 1; /* 0 symbol */
+ path_len -= err + 1;
+
+ cmd->cmd = NETFS_RENAME;
+ cmd->id = pi->ino;
+ cmd->start = parent->ino;
+ cmd->size = total_len;
+
+ netfs_convert_cmd(cmd);
+
+ netfs_trans_update(cmd, t, total_len);
+
+ return netfs_trans_finish(t, psb);
+
+err_out_unlock:
+ netfs_trans_free(t);
+ return err;
+}
+
+static int pohmelfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ struct inode *inode = old_dentry->d_inode;
+ struct pohmelfs_inode *old_parent, *pi, *new_parent;
+ struct qstr str = new_dentry->d_name;
+ struct pohmelfs_name *n;
+ unsigned int old_hash;
+ int err = -ENOENT;
+
+ pi = POHMELFS_I(inode);
+ old_parent = POHMELFS_I(old_dir);
+
+ if (new_dir) {
+ new_dir->i_sb->s_op->write_inode(new_dir, 0);
+ }
+
+ old_hash = jhash(old_dentry->d_name.name, old_dentry->d_name.len, 0);
+ str.hash = jhash(new_dentry->d_name.name, new_dentry->d_name.len, 0);
+
+ str.len = new_dentry->d_name.len;
+ str.name = new_dentry->d_name.name;
+ str.hash = jhash(new_dentry->d_name.name, new_dentry->d_name.len, 0);
+
+ if (new_dir) {
+ new_parent = POHMELFS_I(new_dir);
+ err = -ENOTEMPTY;
+
+ if (S_ISDIR(inode->i_mode) &&
+ new_parent->total_len <= 3)
+ goto err_out_exit;
+ } else {
+ new_parent = old_parent;
+ }
+
+ dprintk("%s: ino: %llu, parent: %llu, name: '%s' -> parent: %llu, name: '%s', i_size: %llu.\n",
+ __func__, pi->ino, old_parent->ino, old_dentry->d_name.name,
+ new_parent->ino, new_dentry->d_name.name, inode->i_size);
+
+ if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state) &&
+ test_bit(NETFS_INODE_OWNED, &pi->state)) {
+ err = pohmelfs_send_rename(pi, new_parent, &str);
+ if (err)
+ goto err_out_exit;
+ }
+
+ n = pohmelfs_name_alloc(str.len + 1);
+ if (!n)
+ goto err_out_exit;
+
+ mutex_lock(&new_parent->offset_lock);
+ n->ino = pi->ino;
+ n->mode = inode->i_mode;
+ n->len = str.len;
+ n->hash = str.hash;
+ sprintf(n->data, "%s", str.name);
+
+ err = pohmelfs_insert_name(new_parent, n);
+ mutex_unlock(&new_parent->offset_lock);
+
+ if (err)
+ goto err_out_exit;
+
+ mutex_lock(&old_parent->offset_lock);
+ n = pohmelfs_search_hash(old_parent, old_hash);
+ if (n)
+ pohmelfs_name_del(old_parent, n);
+ mutex_unlock(&old_parent->offset_lock);
+
+ mark_inode_dirty(inode);
+ mark_inode_dirty(&new_parent->vfs_inode);
+
+ WARN_ON_ONCE(list_empty(&inode->i_dentry));
+
+ return 0;
+
+err_out_exit:
+
+ clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+
+ mutex_unlock(&inode->i_mutex);
+ return err;
+}
+
+/*
+ * POHMELFS directory inode operations.
+ */
+const struct inode_operations pohmelfs_dir_inode_ops = {
+ .link = pohmelfs_link,
+ .symlink = pohmelfs_symlink,
+ .unlink = pohmelfs_unlink,
+ .mkdir = pohmelfs_mkdir,
+ .rmdir = pohmelfs_rmdir,
+ .create = pohmelfs_create,
+ .lookup = pohmelfs_lookup,
+ .setattr = pohmelfs_setattr,
+ .rename = pohmelfs_rename,
+};
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
new file mode 100644
index 00000000000..5bf16504cd6
--- /dev/null
+++ b/drivers/staging/pohmelfs/inode.c
@@ -0,0 +1,1976 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/backing-dev.h>
+#include <linux/crypto.h>
+#include <linux/fs.h>
+#include <linux/jhash.h>
+#include <linux/hash.h>
+#include <linux/ktime.h>
+#include <linux/mm.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/pagevec.h>
+#include <linux/parser.h>
+#include <linux/swap.h>
+#include <linux/slab.h>
+#include <linux/statfs.h>
+#include <linux/writeback.h>
+#include <linux/quotaops.h>
+
+#include "netfs.h"
+
+#define POHMELFS_MAGIC_NUM 0x504f482e
+
+static struct kmem_cache *pohmelfs_inode_cache;
+
+/*
+ * Removes inode from all trees, drops local name cache and removes all queued
+ * requests for object removal.
+ */
+void pohmelfs_inode_del_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode *pi)
+{
+ mutex_lock(&pi->offset_lock);
+ pohmelfs_free_names(pi);
+ mutex_unlock(&pi->offset_lock);
+
+ dprintk("%s: deleted stuff in ino: %llu.\n", __func__, pi->ino);
+}
+
+/*
+ * Sync inode to server.
+ * Returns zero in success and negative error value otherwise.
+ * It will gather path to root directory into structures containing
+ * creation mode, permissions and names, so that the whole path
+ * to given inode could be created using only single network command.
+ */
+int pohmelfs_write_inode_create(struct inode *inode, struct netfs_trans *trans)
+{
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ int err = -ENOMEM, size;
+ struct netfs_cmd *cmd;
+ void *data;
+ int cur_len = netfs_trans_cur_len(trans);
+
+ if (unlikely(cur_len < 0))
+ return -ETOOSMALL;
+
+ cmd = netfs_trans_current(trans);
+ cur_len -= sizeof(struct netfs_cmd);
+
+ data = (void *)(cmd + 1);
+
+ err = pohmelfs_construct_path_string(pi, data, cur_len);
+ if (err < 0)
+ goto err_out_exit;
+
+ size = err;
+
+ cmd->start = i_size_read(inode);
+ cmd->cmd = NETFS_CREATE;
+ cmd->size = size;
+ cmd->id = pi->ino;
+ cmd->ext = inode->i_mode;
+
+ netfs_convert_cmd(cmd);
+
+ netfs_trans_update(cmd, trans, size);
+
+ return 0;
+
+err_out_exit:
+ printk("%s: completed ino: %llu, err: %d.\n", __func__, pi->ino, err);
+ return err;
+}
+
+static int pohmelfs_write_trans_complete(struct page **pages, unsigned int page_num,
+ void *private, int err)
+{
+ unsigned i;
+
+ dprintk("%s: pages: %lu-%lu, page_num: %u, err: %d.\n",
+ __func__, pages[0]->index, pages[page_num-1]->index,
+ page_num, err);
+
+ for (i = 0; i < page_num; i++) {
+ struct page *page = pages[i];
+
+ if (!page)
+ continue;
+
+ end_page_writeback(page);
+
+ if (err < 0) {
+ SetPageError(page);
+ set_page_dirty(page);
+ }
+
+ unlock_page(page);
+ page_cache_release(page);
+
+ /* dprintk("%s: %3u/%u: page: %p.\n", __func__, i, page_num, page); */
+ }
+ return err;
+}
+
+static int pohmelfs_inode_has_dirty_pages(struct address_space *mapping, pgoff_t index)
+{
+ int ret;
+ struct page *page;
+
+ rcu_read_lock();
+ ret = radix_tree_gang_lookup_tag(&mapping->page_tree,
+ (void **)&page, index, 1, PAGECACHE_TAG_DIRTY);
+ rcu_read_unlock();
+ return ret;
+}
+
+static int pohmelfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
+{
+ struct inode *inode = mapping->host;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ struct backing_dev_info *bdi = mapping->backing_dev_info;
+ int err = 0;
+ int done = 0;
+ int nr_pages;
+ pgoff_t index;
+ pgoff_t end; /* Inclusive */
+ int scanned = 0;
+ int range_whole = 0;
+
+ if (wbc->nonblocking && bdi_write_congested(bdi)) {
+ wbc->encountered_congestion = 1;
+ return 0;
+ }
+
+ if (wbc->range_cyclic) {
+ index = mapping->writeback_index; /* Start from prev offset */
+ end = -1;
+ } else {
+ index = wbc->range_start >> PAGE_CACHE_SHIFT;
+ end = wbc->range_end >> PAGE_CACHE_SHIFT;
+ if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+ range_whole = 1;
+ scanned = 1;
+ }
+retry:
+ while (!done && (index <= end)) {
+ unsigned int i = min(end - index, (pgoff_t)psb->trans_max_pages);
+ int path_len;
+ struct netfs_trans *trans;
+
+ err = pohmelfs_inode_has_dirty_pages(mapping, index);
+ if (!err)
+ break;
+
+ err = pohmelfs_path_length(pi);
+ if (err < 0)
+ break;
+
+ path_len = err;
+
+ if (path_len <= 2) {
+ err = -ENOENT;
+ break;
+ }
+
+ trans = netfs_trans_alloc(psb, path_len, 0, i);
+ if (!trans) {
+ err = -ENOMEM;
+ break;
+ }
+ trans->complete = &pohmelfs_write_trans_complete;
+
+ trans->page_num = nr_pages = find_get_pages_tag(mapping, &index,
+ PAGECACHE_TAG_DIRTY, trans->page_num,
+ trans->pages);
+
+ dprintk("%s: t: %p, nr_pages: %u, end: %lu, index: %lu, max: %u.\n",
+ __func__, trans, nr_pages, end, index, trans->page_num);
+
+ if (!nr_pages)
+ goto err_out_reset;
+
+ err = pohmelfs_write_inode_create(inode, trans);
+ if (err)
+ goto err_out_reset;
+
+ err = 0;
+ scanned = 1;
+
+ for (i = 0; i < trans->page_num; i++) {
+ struct page *page = trans->pages[i];
+
+ lock_page(page);
+
+ if (unlikely(page->mapping != mapping))
+ goto out_continue;
+
+ if (!wbc->range_cyclic && page->index > end) {
+ done = 1;
+ goto out_continue;
+ }
+
+ if (wbc->sync_mode != WB_SYNC_NONE)
+ wait_on_page_writeback(page);
+
+ if (PageWriteback(page) ||
+ !clear_page_dirty_for_io(page)) {
+ dprintk("%s: not clear for io page: %p, writeback: %d.\n",
+ __func__, page, PageWriteback(page));
+ goto out_continue;
+ }
+
+ set_page_writeback(page);
+
+ trans->attached_size += page_private(page);
+ trans->attached_pages++;
+#if 0
+ dprintk("%s: %u/%u added trans: %p, gen: %u, page: %p, [High: %d], size: %lu, idx: %lu.\n",
+ __func__, i, trans->page_num, trans, trans->gen, page,
+ !!PageHighMem(page), page_private(page), page->index);
+#endif
+ wbc->nr_to_write--;
+
+ if (wbc->nr_to_write <= 0)
+ done = 1;
+ if (wbc->nonblocking && bdi_write_congested(bdi)) {
+ wbc->encountered_congestion = 1;
+ done = 1;
+ }
+
+ continue;
+out_continue:
+ unlock_page(page);
+ trans->pages[i] = NULL;
+ }
+
+ err = netfs_trans_finish(trans, psb);
+ if (err)
+ break;
+
+ continue;
+
+err_out_reset:
+ trans->result = err;
+ netfs_trans_reset(trans);
+ netfs_trans_put(trans);
+ break;
+ }
+
+ if (!scanned && !done) {
+ /*
+ * We hit the last page and there is more work to be done: wrap
+ * back to the start of the file
+ */
+ scanned = 1;
+ index = 0;
+ goto retry;
+ }
+
+ if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
+ mapping->writeback_index = index;
+
+ return err;
+}
+
+/*
+ * Inode writeback creation completion callback.
+ * Only invoked for just created inodes, which do not have pages attached,
+ * like dirs and empty files.
+ */
+static int pohmelfs_write_inode_complete(struct page **pages, unsigned int page_num,
+ void *private, int err)
+{
+ struct inode *inode = private;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+
+ if (inode) {
+ if (err) {
+ mark_inode_dirty(inode);
+ clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+ } else {
+ set_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+ }
+
+ pohmelfs_put_inode(pi);
+ }
+
+ return err;
+}
+
+int pohmelfs_write_create_inode(struct pohmelfs_inode *pi)
+{
+ struct netfs_trans *t;
+ struct inode *inode = &pi->vfs_inode;
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ int err;
+
+ if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state))
+ return 0;
+
+ dprintk("%s: started ino: %llu.\n", __func__, pi->ino);
+
+ err = pohmelfs_path_length(pi);
+ if (err < 0)
+ goto err_out_exit;
+
+ t = netfs_trans_alloc(psb, err + 1, 0, 0);
+ if (!t) {
+ err = -ENOMEM;
+ goto err_out_put;
+ }
+ t->complete = pohmelfs_write_inode_complete;
+ t->private = igrab(inode);
+ if (!t->private) {
+ err = -ENOENT;
+ goto err_out_put;
+ }
+
+ err = pohmelfs_write_inode_create(inode, t);
+ if (err)
+ goto err_out_put;
+
+ netfs_trans_finish(t, POHMELFS_SB(inode->i_sb));
+
+ return 0;
+
+err_out_put:
+ t->result = err;
+ netfs_trans_put(t);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Sync all not-yet-created children in given directory to the server.
+ */
+static int pohmelfs_write_inode_create_children(struct inode *inode)
+{
+ struct pohmelfs_inode *parent = POHMELFS_I(inode);
+ struct super_block *sb = inode->i_sb;
+ struct pohmelfs_name *n;
+
+ while (!list_empty(&parent->sync_create_list)) {
+ n = NULL;
+ mutex_lock(&parent->offset_lock);
+ if (!list_empty(&parent->sync_create_list)) {
+ n = list_first_entry(&parent->sync_create_list,
+ struct pohmelfs_name, sync_create_entry);
+ list_del_init(&n->sync_create_entry);
+ }
+ mutex_unlock(&parent->offset_lock);
+
+ if (!n)
+ break;
+
+ inode = ilookup(sb, n->ino);
+
+ dprintk("%s: parent: %llu, ino: %llu, inode: %p.\n",
+ __func__, parent->ino, n->ino, inode);
+
+ if (inode && (inode->i_state & I_DIRTY)) {
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ pohmelfs_write_create_inode(pi);
+ //pohmelfs_meta_command(pi, NETFS_INODE_INFO, 0, NULL, NULL, 0);
+ iput(inode);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Removes given child from given inode on server.
+ */
+int pohmelfs_remove_child(struct pohmelfs_inode *pi, struct pohmelfs_name *n)
+{
+ return pohmelfs_meta_command_data(pi, pi->ino, NETFS_REMOVE, NULL, 0, NULL, NULL, 0);
+}
+
+/*
+ * Writeback for given inode.
+ */
+static int pohmelfs_write_inode(struct inode *inode, int sync)
+{
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+
+ pohmelfs_write_create_inode(pi);
+ pohmelfs_write_inode_create_children(inode);
+
+ return 0;
+}
+
+/*
+ * It is not exported, sorry...
+ */
+static inline wait_queue_head_t *page_waitqueue(struct page *page)
+{
+ const struct zone *zone = page_zone(page);
+
+ return &zone->wait_table[hash_ptr(page, zone->wait_table_bits)];
+}
+
+static int pohmelfs_wait_on_page_locked(struct page *page)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(page->mapping->host->i_sb);
+ long ret = psb->wait_on_page_timeout;
+ DEFINE_WAIT_BIT(wait, &page->flags, PG_locked);
+ int err = 0;
+
+ if (!PageLocked(page))
+ return 0;
+
+ for (;;) {
+ prepare_to_wait(page_waitqueue(page),
+ &wait.wait, TASK_INTERRUPTIBLE);
+
+ dprintk("%s: page: %p, locked: %d, uptodate: %d, error: %d, flags: %lx.\n",
+ __func__, page, PageLocked(page), PageUptodate(page),
+ PageError(page), page->flags);
+
+ if (!PageLocked(page))
+ break;
+
+ if (!signal_pending(current)) {
+ ret = schedule_timeout(ret);
+ if (!ret)
+ break;
+ continue;
+ }
+ ret = -ERESTARTSYS;
+ break;
+ }
+ finish_wait(page_waitqueue(page), &wait.wait);
+
+ if (!ret)
+ err = -ETIMEDOUT;
+
+
+ if (!err)
+ SetPageUptodate(page);
+
+ if (err)
+ printk("%s: page: %p, uptodate: %d, locked: %d, err: %d.\n",
+ __func__, page, PageUptodate(page), PageLocked(page), err);
+
+ return err;
+}
+
+static int pohmelfs_read_page_complete(struct page **pages, unsigned int page_num,
+ void *private, int err)
+{
+ struct page *page = private;
+
+ if (PageChecked(page))
+ return err;
+
+ if (err < 0) {
+ dprintk("%s: page: %p, err: %d.\n", __func__, page, err);
+ SetPageError(page);
+ }
+
+ unlock_page(page);
+
+ return err;
+}
+
+/*
+ * Read a page from remote server.
+ * Function will wait until page is unlocked.
+ */
+static int pohmelfs_readpage(struct file *file, struct page *page)
+{
+ struct inode *inode = page->mapping->host;
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ struct netfs_trans *t;
+ struct netfs_cmd *cmd;
+ int err, path_len;
+ void *data;
+ u64 isize;
+
+ err = pohmelfs_data_lock(pi, page->index << PAGE_CACHE_SHIFT,
+ PAGE_SIZE, POHMELFS_READ_LOCK);
+ if (err)
+ goto err_out_exit;
+
+ isize = i_size_read(inode);
+ if (isize <= page->index << PAGE_CACHE_SHIFT) {
+ SetPageUptodate(page);
+ unlock_page(page);
+ return 0;
+ }
+
+ path_len = pohmelfs_path_length(pi);
+ if (path_len < 0) {
+ err = path_len;
+ goto err_out_exit;
+ }
+
+ t = netfs_trans_alloc(psb, path_len, NETFS_TRANS_SINGLE_DST, 0);
+ if (!t) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+
+ t->complete = pohmelfs_read_page_complete;
+ t->private = page;
+
+ cmd = netfs_trans_current(t);
+ data = (void *)(cmd + 1);
+
+ err = pohmelfs_construct_path_string(pi, data, path_len);
+ if (err < 0)
+ goto err_out_free;
+
+ path_len = err;
+
+ cmd->id = pi->ino;
+ cmd->start = page->index;
+ cmd->start <<= PAGE_CACHE_SHIFT;
+ cmd->size = PAGE_CACHE_SIZE + path_len;
+ cmd->cmd = NETFS_READ_PAGE;
+ cmd->ext = path_len;
+
+ dprintk("%s: path: '%s', page: %p, ino: %llu, start: %llu, size: %lu.\n",
+ __func__, (char *)data, page, pi->ino, cmd->start, PAGE_CACHE_SIZE);
+
+ netfs_convert_cmd(cmd);
+ netfs_trans_update(cmd, t, path_len);
+
+ err = netfs_trans_finish(t, psb);
+ if (err)
+ goto err_out_return;
+
+ return pohmelfs_wait_on_page_locked(page);
+
+err_out_free:
+ t->result = err;
+ netfs_trans_put(t);
+err_out_exit:
+ SetPageError(page);
+ if (PageLocked(page))
+ unlock_page(page);
+err_out_return:
+ printk("%s: page: %p, start: %lu, size: %lu, err: %d.\n",
+ __func__, page, page->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE, err);
+
+ return err;
+}
+
+/*
+ * Write begin/end magic.
+ * Allocates a page and writes inode if it was not synced to server before.
+ */
+static int pohmelfs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+{
+ struct inode *inode = mapping->host;
+ struct page *page;
+ pgoff_t index;
+ unsigned start, end;
+ int err;
+
+ *pagep = NULL;
+
+ index = pos >> PAGE_CACHE_SHIFT;
+ start = pos & (PAGE_CACHE_SIZE - 1);
+ end = start + len;
+
+ page = grab_cache_page(mapping, index);
+#if 0
+ dprintk("%s: page: %p pos: %llu, len: %u, index: %lu, start: %u, end: %u, uptodate: %d.\n",
+ __func__, page, pos, len, index, start, end, PageUptodate(page));
+#endif
+ if (!page) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+
+ while (!PageUptodate(page)) {
+ if (start && test_bit(NETFS_INODE_REMOTE_SYNCED, &POHMELFS_I(inode)->state)) {
+ err = pohmelfs_readpage(file, page);
+ if (err)
+ goto err_out_exit;
+
+ lock_page(page);
+ continue;
+ }
+
+ if (len != PAGE_CACHE_SIZE) {
+ void *kaddr = kmap_atomic(page, KM_USER0);
+
+ memset(kaddr + start, 0, PAGE_CACHE_SIZE - start);
+ flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
+ }
+ SetPageUptodate(page);
+ }
+
+ set_page_private(page, end);
+
+ *pagep = page;
+
+ return 0;
+
+err_out_exit:
+ page_cache_release(page);
+ *pagep = NULL;
+
+ return err;
+}
+
+static int pohmelfs_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ struct inode *inode = mapping->host;
+
+ if (copied != len) {
+ unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+ void *kaddr = kmap_atomic(page, KM_USER0);
+
+ memset(kaddr + from + copied, 0, len - copied);
+ flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
+ }
+
+ SetPageUptodate(page);
+ set_page_dirty(page);
+#if 0
+ dprintk("%s: page: %p [U: %d, D: %d, L: %d], pos: %llu, len: %u, copied: %u.\n",
+ __func__, page,
+ PageUptodate(page), PageDirty(page), PageLocked(page),
+ pos, len, copied);
+#endif
+ flush_dcache_page(page);
+
+ unlock_page(page);
+ page_cache_release(page);
+
+ if (pos + copied > inode->i_size) {
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+
+ psb->avail_size -= pos + copied - inode->i_size;
+
+ i_size_write(inode, pos + copied);
+ }
+
+ return copied;
+}
+
+static int pohmelfs_readpages_trans_complete(struct page **__pages, unsigned int page_num,
+ void *private, int err)
+{
+ struct pohmelfs_inode *pi = private;
+ unsigned int i, num;
+ struct page **pages, *page = (struct page *)__pages;
+ loff_t index = page->index;
+
+ pages = kzalloc(sizeof(void *) * page_num, GFP_NOIO);
+ if (!pages)
+ return -ENOMEM;
+
+ num = find_get_pages_contig(pi->vfs_inode.i_mapping, index, page_num, pages);
+ if (num <= 0) {
+ err = num;
+ goto err_out_free;
+ }
+
+ for (i=0; i<num; ++i) {
+ page = pages[i];
+
+ if (err)
+ printk("%s: %u/%u: page: %p, index: %lu, uptodate: %d, locked: %d, err: %d.\n",
+ __func__, i, num, page, page->index,
+ PageUptodate(page), PageLocked(page), err);
+
+ if (!PageChecked(page)) {
+ if (err < 0)
+ SetPageError(page);
+ unlock_page(page);
+ }
+ page_cache_release(page);
+ page_cache_release(page);
+ }
+
+err_out_free:
+ kfree(pages);
+ return err;
+}
+
+static int pohmelfs_send_readpages(struct pohmelfs_inode *pi, struct page *first, unsigned int num)
+{
+ struct netfs_trans *t;
+ struct netfs_cmd *cmd;
+ struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+ int err, path_len;
+ void *data;
+
+ err = pohmelfs_data_lock(pi, first->index << PAGE_CACHE_SHIFT,
+ num * PAGE_SIZE, POHMELFS_READ_LOCK);
+ if (err)
+ goto err_out_exit;
+
+ path_len = pohmelfs_path_length(pi);
+ if (path_len < 0) {
+ err = path_len;
+ goto err_out_exit;
+ }
+
+ t = netfs_trans_alloc(psb, path_len, NETFS_TRANS_SINGLE_DST, 0);
+ if (!t) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+
+ cmd = netfs_trans_current(t);
+ data = (void *)(cmd + 1);
+
+ t->complete = pohmelfs_readpages_trans_complete;
+ t->private = pi;
+ t->page_num = num;
+ t->pages = (struct page **)first;
+
+ err = pohmelfs_construct_path_string(pi, data, path_len);
+ if (err < 0)
+ goto err_out_put;
+
+ path_len = err;
+
+ cmd->cmd = NETFS_READ_PAGES;
+ cmd->start = first->index;
+ cmd->start <<= PAGE_CACHE_SHIFT;
+ cmd->size = (num << 8 | PAGE_CACHE_SHIFT);
+ cmd->id = pi->ino;
+ cmd->ext = path_len;
+
+ dprintk("%s: t: %p, gen: %u, path: '%s', path_len: %u, "
+ "start: %lu, num: %u.\n",
+ __func__, t, t->gen, (char *)data, path_len,
+ first->index, num);
+
+ netfs_convert_cmd(cmd);
+ netfs_trans_update(cmd, t, path_len);
+
+ return netfs_trans_finish(t, psb);
+
+err_out_put:
+ netfs_trans_free(t);
+err_out_exit:
+ pohmelfs_readpages_trans_complete((struct page **)first, num, pi, err);
+ return err;
+}
+
+#define list_to_page(head) (list_entry((head)->prev, struct page, lru))
+
+static int pohmelfs_readpages(struct file *file, struct address_space *mapping,
+ struct list_head *pages, unsigned nr_pages)
+{
+ unsigned int page_idx, num = 0;
+ struct page *page = NULL, *first = NULL;
+
+ for (page_idx = 0; page_idx < nr_pages; page_idx++) {
+ page = list_to_page(pages);
+
+ prefetchw(&page->flags);
+ list_del(&page->lru);
+
+ if (!add_to_page_cache_lru(page, mapping,
+ page->index, GFP_KERNEL)) {
+
+ if (!num) {
+ num = 1;
+ first = page;
+ continue;
+ }
+
+ dprintk("%s: added to lru page: %p, page_index: %lu, first_index: %lu.\n",
+ __func__, page, page->index, first->index);
+
+ if (unlikely(first->index + num != page->index) || (num > 500)) {
+ pohmelfs_send_readpages(POHMELFS_I(mapping->host),
+ first, num);
+ first = page;
+ num = 0;
+ }
+
+ num++;
+ }
+ }
+ pohmelfs_send_readpages(POHMELFS_I(mapping->host), first, num);
+
+ /*
+ * This will be sync read, so when last page is processed,
+ * all previous are alerady unlocked and ready to be used.
+ */
+ return 0;
+}
+
+/*
+ * Small addres space operations for POHMELFS.
+ */
+const struct address_space_operations pohmelfs_aops = {
+ .readpage = pohmelfs_readpage,
+ .readpages = pohmelfs_readpages,
+ .writepages = pohmelfs_writepages,
+ .write_begin = pohmelfs_write_begin,
+ .write_end = pohmelfs_write_end,
+ .set_page_dirty = __set_page_dirty_nobuffers,
+};
+
+/*
+ * ->detroy_inode() callback. Deletes inode from the caches
+ * and frees private data.
+ */
+static void pohmelfs_destroy_inode(struct inode *inode)
+{
+ struct super_block *sb = inode->i_sb;
+ struct pohmelfs_sb *psb = POHMELFS_SB(sb);
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+
+ //pohmelfs_data_unlock(pi, 0, inode->i_size, POHMELFS_READ_LOCK);
+
+ pohmelfs_inode_del_inode(psb, pi);
+
+ dprintk("%s: pi: %p, inode: %p, ino: %llu.\n",
+ __func__, pi, &pi->vfs_inode, pi->ino);
+ kmem_cache_free(pohmelfs_inode_cache, pi);
+ atomic_long_dec(&psb->total_inodes);
+}
+
+/*
+ * ->alloc_inode() callback. Allocates inode and initilizes private data.
+ */
+static struct inode *pohmelfs_alloc_inode(struct super_block *sb)
+{
+ struct pohmelfs_inode *pi;
+
+ pi = kmem_cache_alloc(pohmelfs_inode_cache, GFP_NOIO);
+ if (!pi)
+ return NULL;
+
+ pi->hash_root = RB_ROOT;
+ mutex_init(&pi->offset_lock);
+
+ INIT_LIST_HEAD(&pi->sync_create_list);
+
+ INIT_LIST_HEAD(&pi->inode_entry);
+
+ pi->lock_type = 0;
+ pi->state = 0;
+ pi->total_len = 0;
+ pi->drop_count = 0;
+
+ dprintk("%s: pi: %p, inode: %p.\n", __func__, pi, &pi->vfs_inode);
+
+ atomic_long_inc(&POHMELFS_SB(sb)->total_inodes);
+
+ return &pi->vfs_inode;
+}
+
+/*
+ * We want fsync() to work on POHMELFS.
+ */
+static int pohmelfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+ struct inode *inode = file->f_mapping->host;
+ struct writeback_control wbc = {
+ .sync_mode = WB_SYNC_ALL,
+ .nr_to_write = 0, /* sys_fsync did this */
+ };
+
+ return sync_inode(inode, &wbc);
+}
+
+ssize_t pohmelfs_write(struct file *file, const char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ struct address_space *mapping = file->f_mapping;
+ struct inode *inode = mapping->host;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
+ struct kiocb kiocb;
+ ssize_t ret;
+ loff_t pos = *ppos;
+
+ init_sync_kiocb(&kiocb, file);
+ kiocb.ki_pos = pos;
+ kiocb.ki_left = len;
+
+ dprintk("%s: len: %zu, pos: %llu.\n", __func__, len, pos);
+
+ mutex_lock(&inode->i_mutex);
+ ret = pohmelfs_data_lock(pi, pos, len, POHMELFS_WRITE_LOCK);
+ if (ret)
+ goto err_out_unlock;
+
+ ret = generic_file_aio_write_nolock(&kiocb, &iov, 1, pos);
+ *ppos = kiocb.ki_pos;
+
+ mutex_unlock(&inode->i_mutex);
+ WARN_ON(ret < 0);
+
+ if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
+ ssize_t err;
+
+ err = sync_page_range(inode, mapping, pos, ret);
+ if (err < 0)
+ ret = err;
+ WARN_ON(ret < 0);
+ }
+
+ return ret;
+
+err_out_unlock:
+ mutex_unlock(&inode->i_mutex);
+ return ret;
+}
+
+const static struct file_operations pohmelfs_file_ops = {
+ .open = generic_file_open,
+ .fsync = pohmelfs_fsync,
+
+ .llseek = generic_file_llseek,
+
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+
+ .mmap = generic_file_mmap,
+
+ .splice_read = generic_file_splice_read,
+ .splice_write = generic_file_splice_write,
+
+ .write = pohmelfs_write,
+ .aio_write = generic_file_aio_write,
+};
+
+const struct inode_operations pohmelfs_symlink_inode_operations = {
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
+};
+
+int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr)
+{
+ int err;
+
+ err = inode_change_ok(inode, attr);
+ if (err) {
+ dprintk("%s: ino: %llu, inode changes are not allowed.\n", __func__, POHMELFS_I(inode)->ino);
+ goto err_out_exit;
+ }
+
+ if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+ (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
+ err = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
+ if (err)
+ goto err_out_exit;
+ }
+
+ err = inode_setattr(inode, attr);
+ if (err) {
+ dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino);
+ goto err_out_exit;
+ }
+
+ dprintk("%s: ino: %llu, mode: %o -> %o, uid: %u -> %u, gid: %u -> %u, size: %llu -> %llu.\n",
+ __func__, POHMELFS_I(inode)->ino, inode->i_mode, attr->ia_mode,
+ inode->i_uid, attr->ia_uid, inode->i_gid, attr->ia_gid, inode->i_size, attr->ia_size);
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+int pohmelfs_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ struct inode *inode = dentry->d_inode;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ int err;
+
+ err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_WRITE_LOCK);
+ if (err)
+ goto err_out_exit;
+
+ err = security_inode_setattr(dentry, attr);
+ if (err)
+ goto err_out_exit;
+
+ err = pohmelfs_setattr_raw(inode, attr);
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+static int pohmelfs_send_xattr_req(struct pohmelfs_inode *pi, u64 id, u64 start,
+ const char *name, const void *value, size_t attrsize, int command)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+ int err, path_len, namelen = strlen(name) + 1; /* 0-byte */
+ struct netfs_trans *t;
+ struct netfs_cmd *cmd;
+ void *data;
+
+ dprintk("%s: id: %llu, start: %llu, name: '%s', attrsize: %zu, cmd: %d.\n",
+ __func__, id, start, name, attrsize, command);
+
+ path_len = pohmelfs_path_length(pi);
+ if (path_len < 0) {
+ err = path_len;
+ goto err_out_exit;
+ }
+
+ t = netfs_trans_alloc(psb, namelen + path_len + attrsize, 0, 0);
+ if (!t) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+
+ cmd = netfs_trans_current(t);
+ data = cmd + 1;
+
+ path_len = pohmelfs_construct_path_string(pi, data, path_len);
+ if (path_len < 0) {
+ err = path_len;
+ goto err_out_put;
+ }
+ data += path_len;
+
+ /*
+ * 'name' is a NUL-terminated string already and
+ * 'namelen' includes 0-byte.
+ */
+ memcpy(data, name, namelen);
+ data += namelen;
+
+ memcpy(data, value, attrsize);
+
+ cmd->cmd = command;
+ cmd->id = id;
+ cmd->start = start;
+ cmd->size = attrsize + namelen + path_len;
+ cmd->ext = path_len;
+ cmd->csize = 0;
+ cmd->cpad = 0;
+
+ netfs_convert_cmd(cmd);
+ netfs_trans_update(cmd, t, namelen + path_len + attrsize);
+
+ return netfs_trans_finish(t, psb);
+
+err_out_put:
+ t->result = err;
+ netfs_trans_put(t);
+err_out_exit:
+ return err;
+}
+
+static int pohmelfs_setxattr(struct dentry *dentry, const char *name,
+ const void *value, size_t attrsize, int flags)
+{
+ struct inode *inode = dentry->d_inode;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+
+ if (!(psb->state_flags & POHMELFS_FLAGS_XATTR))
+ return -EOPNOTSUPP;
+
+ return pohmelfs_send_xattr_req(pi, flags, attrsize, name,
+ value, attrsize, NETFS_XATTR_SET);
+}
+
+static ssize_t pohmelfs_getxattr(struct dentry *dentry, const char *name,
+ void *value, size_t attrsize)
+{
+ struct inode *inode = dentry->d_inode;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ struct pohmelfs_mcache *m;
+ int err;
+ long timeout = psb->mcache_timeout;
+
+ if (!(psb->state_flags & POHMELFS_FLAGS_XATTR))
+ return -EOPNOTSUPP;
+
+ m = pohmelfs_mcache_alloc(psb, 0, attrsize, value);
+ if (IS_ERR(m))
+ return PTR_ERR(m);
+
+ dprintk("%s: ino: %llu, name: '%s', size: %zu.\n",
+ __func__, pi->ino, name, attrsize);
+
+ err = pohmelfs_send_xattr_req(pi, m->gen, attrsize, name, value, 0, NETFS_XATTR_GET);
+ if (err)
+ goto err_out_put;
+
+ do {
+ err = wait_for_completion_timeout(&m->complete, timeout);
+ if (err) {
+ err = m->err;
+ break;
+ }
+
+ /*
+ * This loop is a bit ugly, since it waits until reference counter
+ * hits 1 and then put object here. Main goal is to prevent race with
+ * network thread, when it can start processing given request, i.e.
+ * increase its reference counter but yet not complete it, while
+ * we will exit from ->getxattr() with timeout, and although request
+ * will not be freed (its reference counter was increased by network
+ * thread), data pointer provided by user may be released, so we will
+ * overwrite already freed area in network thread.
+ *
+ * Now after timeout we remove request from the cache, so it can not be
+ * found by network thread, and wait for its reference counter to hit 1,
+ * i.e. if network thread already started to process this request, we wait
+ * it to finish, and then free object locally. If reference counter is
+ * already 1, i.e. request is not used by anyone else, we can free it without
+ * problem.
+ */
+ err = -ETIMEDOUT;
+ timeout = HZ;
+
+ pohmelfs_mcache_remove_locked(psb, m);
+ } while (atomic_read(&m->refcnt) != 1);
+
+ pohmelfs_mcache_put(psb, m);
+
+ dprintk("%s: ino: %llu, err: %d.\n", __func__, pi->ino, err);
+
+ return err;
+
+err_out_put:
+ pohmelfs_mcache_put(psb, m);
+ return err;
+}
+
+static int pohmelfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+{
+ struct inode *inode = dentry->d_inode;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ int err;
+
+ err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK);
+ if (err)
+ return err;
+
+ dprintk("%s: ino: %llu, mode: %o, uid: %u, gid: %u, size: %llu.\n",
+ __func__, pi->ino, inode->i_mode, inode->i_uid,
+ inode->i_gid, inode->i_size);
+
+ generic_fillattr(inode, stat);
+ return 0;
+}
+
+const struct inode_operations pohmelfs_file_inode_operations = {
+ .setattr = pohmelfs_setattr,
+ .getattr = pohmelfs_getattr,
+ .setxattr = pohmelfs_setxattr,
+ .getxattr = pohmelfs_getxattr,
+};
+
+/*
+ * Fill inode data: mode, size, operation callbacks and so on...
+ */
+void pohmelfs_fill_inode(struct inode *inode, struct netfs_inode_info *info)
+{
+ inode->i_mode = info->mode;
+ inode->i_nlink = info->nlink;
+ inode->i_uid = info->uid;
+ inode->i_gid = info->gid;
+ inode->i_blocks = info->blocks;
+ inode->i_rdev = info->rdev;
+ inode->i_size = info->size;
+ inode->i_version = info->version;
+ inode->i_blkbits = ffs(info->blocksize);
+
+ dprintk("%s: inode: %p, num: %lu/%llu inode is regular: %d, dir: %d, link: %d, mode: %o, size: %llu.\n",
+ __func__, inode, inode->i_ino, info->ino,
+ S_ISREG(inode->i_mode), S_ISDIR(inode->i_mode),
+ S_ISLNK(inode->i_mode), inode->i_mode, inode->i_size);
+
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
+
+ /*
+ * i_mapping is a pointer to i_data during inode initialization.
+ */
+ inode->i_data.a_ops = &pohmelfs_aops;
+
+ if (S_ISREG(inode->i_mode)) {
+ inode->i_fop = &pohmelfs_file_ops;
+ inode->i_op = &pohmelfs_file_inode_operations;
+ } else if (S_ISDIR(inode->i_mode)) {
+ inode->i_fop = &pohmelfs_dir_fops;
+ inode->i_op = &pohmelfs_dir_inode_ops;
+ } else if (S_ISLNK(inode->i_mode)) {
+ inode->i_op = &pohmelfs_symlink_inode_operations;
+ inode->i_fop = &pohmelfs_file_ops;
+ } else {
+ inode->i_fop = &generic_ro_fops;
+ }
+}
+
+static void pohmelfs_drop_inode(struct inode *inode)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+
+ spin_lock(&psb->ino_lock);
+ list_del_init(&pi->inode_entry);
+ spin_unlock(&psb->ino_lock);
+
+ generic_drop_inode(inode);
+}
+
+static struct pohmelfs_inode *pohmelfs_get_inode_from_list(struct pohmelfs_sb *psb,
+ struct list_head *head, unsigned int *count)
+{
+ struct pohmelfs_inode *pi = NULL;
+
+ spin_lock(&psb->ino_lock);
+ if (!list_empty(head)) {
+ pi = list_entry(head->next, struct pohmelfs_inode,
+ inode_entry);
+ list_del_init(&pi->inode_entry);
+ *count = pi->drop_count;
+ pi->drop_count = 0;
+ }
+ spin_unlock(&psb->ino_lock);
+
+ return pi;
+}
+
+static void pohmelfs_flush_transactions(struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config *c;
+
+ mutex_lock(&psb->state_lock);
+ list_for_each_entry(c, &psb->state_list, config_entry) {
+ pohmelfs_state_flush_transactions(&c->state);
+ }
+ mutex_unlock(&psb->state_lock);
+}
+
+/*
+ * ->put_super() callback. Invoked before superblock is destroyed,
+ * so it has to clean all private data.
+ */
+static void pohmelfs_put_super(struct super_block *sb)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(sb);
+ struct pohmelfs_inode *pi;
+ unsigned int count;
+ unsigned int in_drop_list = 0;
+ struct inode *inode, *tmp;
+
+ dprintk("%s.\n", __func__);
+
+ /*
+ * Kill pending transactions, which could affect inodes in-flight.
+ */
+ pohmelfs_flush_transactions(psb);
+
+ while ((pi = pohmelfs_get_inode_from_list(psb, &psb->drop_list, &count))) {
+ inode = &pi->vfs_inode;
+
+ dprintk("%s: ino: %llu, pi: %p, inode: %p, count: %u.\n",
+ __func__, pi->ino, pi, inode, count);
+
+ if (atomic_read(&inode->i_count) != count) {
+ printk("%s: ino: %llu, pi: %p, inode: %p, count: %u, i_count: %d.\n",
+ __func__, pi->ino, pi, inode, count,
+ atomic_read(&inode->i_count));
+ count = atomic_read(&inode->i_count);
+ in_drop_list++;
+ }
+
+ while (count--)
+ iput(&pi->vfs_inode);
+ }
+
+ list_for_each_entry_safe(inode, tmp, &sb->s_inodes, i_sb_list) {
+ pi = POHMELFS_I(inode);
+
+ dprintk("%s: ino: %llu, pi: %p, inode: %p, i_count: %u.\n",
+ __func__, pi->ino, pi, inode, atomic_read(&inode->i_count));
+
+ /*
+ * These are special inodes, they were created during
+ * directory reading or lookup, and were not bound to dentry,
+ * so they live here with reference counter being 1 and prevent
+ * umount from succeed since it believes that they are busy.
+ */
+ count = atomic_read(&inode->i_count);
+ if (count) {
+ list_del_init(&inode->i_sb_list);
+ while (count--)
+ iput(&pi->vfs_inode);
+ }
+ }
+
+ psb->trans_scan_timeout = psb->drop_scan_timeout = 0;
+ cancel_rearming_delayed_work(&psb->dwork);
+ cancel_rearming_delayed_work(&psb->drop_dwork);
+ flush_scheduled_work();
+
+ dprintk("%s: stopped workqueues.\n", __func__);
+
+ pohmelfs_crypto_exit(psb);
+ pohmelfs_state_exit(psb);
+
+ kfree(psb);
+ sb->s_fs_info = NULL;
+
+ pohmelfs_ftrans_exit();
+}
+
+static int pohmelfs_remount(struct super_block *sb, int *flags, char *data)
+{
+ *flags |= MS_RDONLY;
+ return 0;
+}
+
+static int pohmelfs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+ struct super_block *sb = dentry->d_sb;
+ struct pohmelfs_sb *psb = POHMELFS_SB(sb);
+
+ /*
+ * There are no filesystem size limits yet.
+ */
+ memset(buf, 0, sizeof(struct kstatfs));
+
+ buf->f_type = POHMELFS_MAGIC_NUM; /* 'POH.' */
+ buf->f_bsize = sb->s_blocksize;
+ buf->f_files = psb->ino;
+ buf->f_namelen = 255;
+ buf->f_files = atomic_long_read(&psb->total_inodes);
+ buf->f_bfree = buf->f_bavail = psb->avail_size >> PAGE_SHIFT;
+ buf->f_blocks = psb->total_size >> PAGE_SHIFT;
+
+ dprintk("%s: total: %llu, avail: %llu, inodes: %llu, bsize: %lu.\n",
+ __func__, psb->total_size, psb->avail_size, buf->f_files, sb->s_blocksize);
+
+ return 0;
+}
+
+static int pohmelfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(vfs->mnt_sb);
+
+ seq_printf(seq, ",idx=%u", psb->idx);
+ seq_printf(seq, ",trans_scan_timeout=%u", jiffies_to_msecs(psb->trans_scan_timeout));
+ seq_printf(seq, ",drop_scan_timeout=%u", jiffies_to_msecs(psb->drop_scan_timeout));
+ seq_printf(seq, ",wait_on_page_timeout=%u", jiffies_to_msecs(psb->wait_on_page_timeout));
+ seq_printf(seq, ",trans_retries=%u", psb->trans_retries);
+ seq_printf(seq, ",crypto_thread_num=%u", psb->crypto_thread_num);
+ seq_printf(seq, ",trans_max_pages=%u", psb->trans_max_pages);
+ seq_printf(seq, ",mcache_timeout=%u", jiffies_to_msecs(psb->mcache_timeout));
+ if (psb->crypto_fail_unsupported)
+ seq_printf(seq, ",crypto_fail_unsupported");
+
+ return 0;
+}
+
+static const struct super_operations pohmelfs_sb_ops = {
+ .alloc_inode = pohmelfs_alloc_inode,
+ .destroy_inode = pohmelfs_destroy_inode,
+ .drop_inode = pohmelfs_drop_inode,
+ .write_inode = pohmelfs_write_inode,
+ .put_super = pohmelfs_put_super,
+ .remount_fs = pohmelfs_remount,
+ .statfs = pohmelfs_statfs,
+ .show_options = pohmelfs_show_options,
+};
+
+enum {
+ pohmelfs_opt_idx,
+ pohmelfs_opt_trans_scan_timeout,
+ pohmelfs_opt_drop_scan_timeout,
+ pohmelfs_opt_wait_on_page_timeout,
+ pohmelfs_opt_trans_retries,
+ pohmelfs_opt_crypto_thread_num,
+ pohmelfs_opt_trans_max_pages,
+ pohmelfs_opt_crypto_fail_unsupported,
+ pohmelfs_opt_mcache_timeout,
+};
+
+static struct match_token pohmelfs_tokens[] = {
+ {pohmelfs_opt_idx, "idx=%u"},
+ {pohmelfs_opt_trans_scan_timeout, "trans_scan_timeout=%u"},
+ {pohmelfs_opt_drop_scan_timeout, "drop_scan_timeout=%u"},
+ {pohmelfs_opt_wait_on_page_timeout, "wait_on_page_timeout=%u"},
+ {pohmelfs_opt_trans_retries, "trans_retries=%u"},
+ {pohmelfs_opt_crypto_thread_num, "crypto_thread_num=%u"},
+ {pohmelfs_opt_trans_max_pages, "trans_max_pages=%u"},
+ {pohmelfs_opt_crypto_fail_unsupported, "crypto_fail_unsupported"},
+ {pohmelfs_opt_mcache_timeout, "mcache_timeout=%u"},
+};
+
+static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb)
+{
+ char *p;
+ substring_t args[MAX_OPT_ARGS];
+ int option, err;
+
+ if (!options)
+ return 0;
+
+ while ((p = strsep(&options, ",")) != NULL) {
+ int token;
+ if (!*p)
+ continue;
+
+ token = match_token(p, pohmelfs_tokens, args);
+
+ err = match_int(&args[0], &option);
+ if (err)
+ return err;
+
+ switch (token) {
+ case pohmelfs_opt_idx:
+ psb->idx = option;
+ break;
+ case pohmelfs_opt_trans_scan_timeout:
+ psb->trans_scan_timeout = msecs_to_jiffies(option);
+ break;
+ case pohmelfs_opt_drop_scan_timeout:
+ psb->drop_scan_timeout = msecs_to_jiffies(option);
+ break;
+ case pohmelfs_opt_wait_on_page_timeout:
+ psb->wait_on_page_timeout = msecs_to_jiffies(option);
+ break;
+ case pohmelfs_opt_mcache_timeout:
+ psb->mcache_timeout = msecs_to_jiffies(option);
+ break;
+ case pohmelfs_opt_trans_retries:
+ psb->trans_retries = option;
+ break;
+ case pohmelfs_opt_crypto_thread_num:
+ psb->crypto_thread_num = option;
+ break;
+ case pohmelfs_opt_trans_max_pages:
+ psb->trans_max_pages = option;
+ break;
+ case pohmelfs_opt_crypto_fail_unsupported:
+ psb->crypto_fail_unsupported = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static void pohmelfs_flush_inode(struct pohmelfs_inode *pi, unsigned int count)
+{
+ struct inode *inode = &pi->vfs_inode;
+
+ dprintk("%s: %p: ino: %llu, owned: %d.\n",
+ __func__, inode, pi->ino, test_bit(NETFS_INODE_OWNED, &pi->state));
+
+ mutex_lock(&inode->i_mutex);
+ if (test_and_clear_bit(NETFS_INODE_OWNED, &pi->state)) {
+ filemap_fdatawrite(inode->i_mapping);
+ inode->i_sb->s_op->write_inode(inode, 0);
+ }
+
+ truncate_inode_pages(inode->i_mapping, 0);
+
+ pohmelfs_data_unlock(pi, 0, ~0, POHMELFS_WRITE_LOCK);
+ mutex_unlock(&inode->i_mutex);
+}
+
+static void pohmelfs_put_inode_count(struct pohmelfs_inode *pi, unsigned int count)
+{
+ dprintk("%s: ino: %llu, pi: %p, inode: %p, count: %u.\n",
+ __func__, pi->ino, pi, &pi->vfs_inode, count);
+
+ if (test_and_clear_bit(NETFS_INODE_NEED_FLUSH, &pi->state))
+ pohmelfs_flush_inode(pi, count);
+
+ while (count--)
+ iput(&pi->vfs_inode);
+}
+
+static void pohmelfs_drop_scan(struct work_struct *work)
+{
+ struct pohmelfs_sb *psb =
+ container_of(work, struct pohmelfs_sb, drop_dwork.work);
+ struct pohmelfs_inode *pi;
+ unsigned int count = 0;
+
+ while ((pi = pohmelfs_get_inode_from_list(psb, &psb->drop_list, &count))) {
+ pohmelfs_put_inode_count(pi, count);
+ }
+ pohmelfs_check_states(psb);
+
+ if (psb->drop_scan_timeout)
+ schedule_delayed_work(&psb->drop_dwork, psb->drop_scan_timeout);
+}
+
+/*
+ * Run through all transactions starting from the oldest,
+ * drop transaction from current state and try to send it
+ * to all remote nodes, which are currently installed.
+ */
+static void pohmelfs_trans_scan_state(struct netfs_state *st)
+{
+ struct rb_node *rb_node;
+ struct netfs_trans_dst *dst;
+ struct pohmelfs_sb *psb = st->psb;
+ unsigned int timeout = psb->trans_scan_timeout;
+ struct netfs_trans *t;
+ int err;
+
+ mutex_lock(&st->trans_lock);
+ for (rb_node = rb_first(&st->trans_root); rb_node; ) {
+ dst = rb_entry(rb_node, struct netfs_trans_dst, state_entry);
+ t = dst->trans;
+
+ if (timeout && time_after(dst->send_time + timeout, jiffies)
+ && dst->retries == 0)
+ break;
+
+ dprintk("%s: t: %p, gen: %u, st: %p, retries: %u, max: %u.\n",
+ __func__, t, t->gen, st, dst->retries, psb->trans_retries);
+ netfs_trans_get(t);
+
+ rb_node = rb_next(rb_node);
+
+ err = -ETIMEDOUT;
+ if (timeout && (++dst->retries < psb->trans_retries)) {
+ err = netfs_trans_resend(t, psb);
+ }
+
+ if (err || (t->flags & NETFS_TRANS_SINGLE_DST)) {
+ if (netfs_trans_remove_nolock(dst, st))
+ netfs_trans_drop_dst_nostate(dst);
+ }
+
+ t->result = err;
+ netfs_trans_put(t);
+ }
+ mutex_unlock(&st->trans_lock);
+}
+
+/*
+ * Walk through all installed network states and resend all
+ * transactions, which are old enough.
+ */
+static void pohmelfs_trans_scan(struct work_struct *work)
+{
+ struct pohmelfs_sb *psb =
+ container_of(work, struct pohmelfs_sb, dwork.work);
+ struct netfs_state *st;
+ struct pohmelfs_config *c;
+
+ mutex_lock(&psb->state_lock);
+ list_for_each_entry(c, &psb->state_list, config_entry) {
+ st = &c->state;
+
+ pohmelfs_trans_scan_state(st);
+ }
+ mutex_unlock(&psb->state_lock);
+
+ /*
+ * If no timeout specified then system is in the middle of umount process,
+ * so no need to reschedule scanning process again.
+ */
+ if (psb->trans_scan_timeout)
+ schedule_delayed_work(&psb->dwork, psb->trans_scan_timeout);
+}
+
+int pohmelfs_meta_command_data(struct pohmelfs_inode *pi, u64 id, unsigned int cmd_op, char *addon,
+ unsigned int flags, netfs_trans_complete_t complete, void *priv, u64 start)
+{
+ struct inode *inode = &pi->vfs_inode;
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ int err = 0, sz;
+ struct netfs_trans *t;
+ int path_len, addon_len = 0;
+ void *data;
+ struct netfs_inode_info *info;
+ struct netfs_cmd *cmd;
+
+ dprintk("%s: ino: %llu, cmd: %u, addon: %p.\n", __func__, pi->ino, cmd_op, addon);
+
+ path_len = pohmelfs_path_length(pi);
+ if (path_len < 0) {
+ err = path_len;
+ goto err_out_exit;
+ }
+
+ if (addon)
+ addon_len = strlen(addon) + 1; /* 0-byte */
+ sz = addon_len;
+
+ if (cmd_op == NETFS_INODE_INFO)
+ sz += sizeof(struct netfs_inode_info);
+
+ t = netfs_trans_alloc(psb, sz + path_len, flags, 0);
+ if (!t) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+ t->complete = complete;
+ t->private = priv;
+
+ cmd = netfs_trans_current(t);
+ data = (void *)(cmd + 1);
+
+ if (cmd_op == NETFS_INODE_INFO) {
+ info = (struct netfs_inode_info *)(cmd + 1);
+ data = (void *)(info + 1);
+
+ /*
+ * We are under i_mutex, can read and change whatever we want...
+ */
+ info->mode = inode->i_mode;
+ info->nlink = inode->i_nlink;
+ info->uid = inode->i_uid;
+ info->gid = inode->i_gid;
+ info->blocks = inode->i_blocks;
+ info->rdev = inode->i_rdev;
+ info->size = inode->i_size;
+ info->version = inode->i_version;
+
+ netfs_convert_inode_info(info);
+ }
+
+ path_len = pohmelfs_construct_path_string(pi, data, path_len);
+ if (path_len < 0)
+ goto err_out_free;
+
+ dprintk("%s: path_len: %d.\n", __func__, path_len);
+
+ if (addon) {
+ path_len--; /* Do not place null-byte before the addon */
+ path_len += sprintf(data + path_len, "/%s", addon) + 1; /* 0 - byte */
+ }
+
+ sz += path_len;
+
+ cmd->cmd = cmd_op;
+ cmd->ext = path_len;
+ cmd->size = sz;
+ cmd->id = id;
+ cmd->start = start;
+
+ netfs_convert_cmd(cmd);
+ netfs_trans_update(cmd, t, sz);
+
+ /*
+ * Note, that it is possible to leak error here: transaction callback will not
+ * be invoked for allocation path failure.
+ */
+ return netfs_trans_finish(t, psb);
+
+err_out_free:
+ netfs_trans_free(t);
+err_out_exit:
+ if (complete)
+ complete(NULL, 0, priv, err);
+ return err;
+}
+
+int pohmelfs_meta_command(struct pohmelfs_inode *pi, unsigned int cmd_op, unsigned int flags,
+ netfs_trans_complete_t complete, void *priv, u64 start)
+{
+ return pohmelfs_meta_command_data(pi, pi->ino, cmd_op, NULL, flags, complete, priv, start);
+}
+
+/*
+ * Send request and wait for POHMELFS root capabilities response,
+ * which will update server's informaion about size of the export,
+ * permissions, number of objects, available size and so on.
+ */
+static int pohmelfs_root_handshake(struct pohmelfs_sb *psb)
+{
+ struct netfs_trans *t;
+ struct netfs_cmd *cmd;
+ int err = -ENOMEM;
+
+ t = netfs_trans_alloc(psb, 0, 0, 0);
+ if (!t)
+ goto err_out_exit;
+
+ cmd = netfs_trans_current(t);
+
+ cmd->cmd = NETFS_CAPABILITIES;
+ cmd->id = POHMELFS_ROOT_CAPABILITIES;
+ cmd->size = 0;
+ cmd->start = 0;
+ cmd->ext = 0;
+ cmd->csize = 0;
+
+ netfs_convert_cmd(cmd);
+ netfs_trans_update(cmd, t, 0);
+
+ err = netfs_trans_finish(t, psb);
+ if (err)
+ goto err_out_exit;
+
+ psb->flags = ~0;
+ err = wait_event_interruptible_timeout(psb->wait,
+ (psb->flags != ~0),
+ psb->wait_on_page_timeout);
+ if (!err) {
+ err = -ETIMEDOUT;
+ } else {
+ err = -psb->flags;
+ }
+
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+/*
+ * Allocate private superblock and create root dir.
+ */
+static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
+{
+ struct pohmelfs_sb *psb;
+ int err = -ENOMEM;
+ struct inode *root;
+ struct pohmelfs_inode *npi;
+ struct qstr str;
+
+ pohmelfs_ftrans_init();
+
+ psb = kzalloc(sizeof(struct pohmelfs_sb), GFP_KERNEL);
+ if (!psb)
+ goto err_out_exit;
+
+ sb->s_fs_info = psb;
+ sb->s_op = &pohmelfs_sb_ops;
+ sb->s_magic = POHMELFS_MAGIC_NUM;
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
+ sb->s_blocksize = PAGE_SIZE;
+
+ psb->sb = sb;
+
+ psb->ino = 2;
+ psb->idx = 0;
+ psb->active_state = NULL;
+ psb->trans_retries = 5;
+ psb->trans_data_size = PAGE_SIZE;
+ psb->drop_scan_timeout = msecs_to_jiffies(1000);
+ psb->trans_scan_timeout = msecs_to_jiffies(5000);
+ psb->wait_on_page_timeout = msecs_to_jiffies(5000);
+ init_waitqueue_head(&psb->wait);
+
+ spin_lock_init(&psb->ino_lock);
+
+ INIT_LIST_HEAD(&psb->drop_list);
+
+ mutex_init(&psb->mcache_lock);
+ psb->mcache_root = RB_ROOT;
+ psb->mcache_timeout = msecs_to_jiffies(5000);
+ atomic_long_set(&psb->mcache_gen, 0);
+
+ psb->trans_max_pages = 100;
+
+ psb->crypto_align_size = 16;
+ psb->crypto_attached_size = 0;
+ psb->hash_strlen = 0;
+ psb->cipher_strlen = 0;
+ psb->perform_crypto = 0;
+ psb->crypto_thread_num = 2;
+ psb->crypto_fail_unsupported = 0;
+ mutex_init(&psb->crypto_thread_lock);
+ INIT_LIST_HEAD(&psb->crypto_ready_list);
+ INIT_LIST_HEAD(&psb->crypto_active_list);
+
+ atomic_set(&psb->trans_gen, 1);
+ atomic_set(&psb->total_inodes, 0);
+
+ mutex_init(&psb->state_lock);
+ INIT_LIST_HEAD(&psb->state_list);
+
+ err = pohmelfs_parse_options((char *) data, psb);
+ if (err)
+ goto err_out_free_sb;
+
+ err = pohmelfs_copy_crypto(psb);
+ if (err)
+ goto err_out_free_sb;
+
+ err = pohmelfs_state_init(psb);
+ if (err)
+ goto err_out_free_strings;
+
+ err = pohmelfs_crypto_init(psb);
+ if (err)
+ goto err_out_state_exit;
+
+ err = pohmelfs_root_handshake(psb);
+ if (err)
+ goto err_out_crypto_exit;
+
+ str.name = "/";
+ str.hash = jhash("/", 1, 0);
+ str.len = 1;
+
+ npi = pohmelfs_create_entry_local(psb, NULL, &str, 0, 0755|S_IFDIR);
+ if (IS_ERR(npi)) {
+ err = PTR_ERR(npi);
+ goto err_out_crypto_exit;
+ }
+
+ root = &npi->vfs_inode;
+
+ sb->s_root = d_alloc_root(root);
+ if (!sb->s_root)
+ goto err_out_put_root;
+
+ INIT_DELAYED_WORK(&psb->drop_dwork, pohmelfs_drop_scan);
+ schedule_delayed_work(&psb->drop_dwork, psb->drop_scan_timeout);
+
+ INIT_DELAYED_WORK(&psb->dwork, pohmelfs_trans_scan);
+ schedule_delayed_work(&psb->dwork, psb->trans_scan_timeout);
+
+ return 0;
+
+err_out_put_root:
+ iput(root);
+err_out_crypto_exit:
+ pohmelfs_crypto_exit(psb);
+err_out_state_exit:
+ pohmelfs_state_exit(psb);
+err_out_free_strings:
+ kfree(psb->cipher_string);
+ kfree(psb->hash_string);
+err_out_free_sb:
+ kfree(psb);
+err_out_exit:
+
+ dprintk("%s: err: %d.\n", __func__, err);
+ return err;
+}
+
+/*
+ * Some VFS magic here...
+ */
+static int pohmelfs_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+{
+ return get_sb_nodev(fs_type, flags, data, pohmelfs_fill_super,
+ mnt);
+}
+
+static struct file_system_type pohmel_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "pohmel",
+ .get_sb = pohmelfs_get_sb,
+ .kill_sb = kill_anon_super,
+};
+
+/*
+ * Cache and module initializations and freeing routings.
+ */
+static void pohmelfs_init_once(void *data)
+{
+ struct pohmelfs_inode *pi = data;
+
+ inode_init_once(&pi->vfs_inode);
+}
+
+static int __init pohmelfs_init_inodecache(void)
+{
+ pohmelfs_inode_cache = kmem_cache_create("pohmelfs_inode_cache",
+ sizeof(struct pohmelfs_inode),
+ 0, (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),
+ pohmelfs_init_once);
+ if (!pohmelfs_inode_cache)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void pohmelfs_destroy_inodecache(void)
+{
+ kmem_cache_destroy(pohmelfs_inode_cache);
+}
+
+static int __init init_pohmel_fs(void)
+{
+ int err;
+
+ err = pohmelfs_config_init();
+ if (err)
+ goto err_out_exit;
+
+ err = pohmelfs_init_inodecache();
+ if (err)
+ goto err_out_config_exit;
+
+ err = pohmelfs_mcache_init();
+ if (err)
+ goto err_out_destroy;
+
+ err = netfs_trans_init();
+ if (err)
+ goto err_out_mcache_exit;
+
+ err = register_filesystem(&pohmel_fs_type);
+ if (err)
+ goto err_out_trans;
+
+ return 0;
+
+err_out_trans:
+ netfs_trans_exit();
+err_out_mcache_exit:
+ pohmelfs_mcache_exit();
+err_out_destroy:
+ pohmelfs_destroy_inodecache();
+err_out_config_exit:
+ pohmelfs_config_exit();
+err_out_exit:
+ return err;
+}
+
+static void __exit exit_pohmel_fs(void)
+{
+ unregister_filesystem(&pohmel_fs_type);
+ pohmelfs_destroy_inodecache();
+ pohmelfs_mcache_exit();
+ pohmelfs_config_exit();
+ netfs_trans_exit();
+}
+
+module_init(init_pohmel_fs);
+module_exit(exit_pohmel_fs);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
+MODULE_DESCRIPTION("Pohmel filesystem");
diff --git a/drivers/staging/pohmelfs/lock.c b/drivers/staging/pohmelfs/lock.c
new file mode 100644
index 00000000000..ad4a18559bd
--- /dev/null
+++ b/drivers/staging/pohmelfs/lock.c
@@ -0,0 +1,182 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/backing-dev.h>
+#include <linux/fs.h>
+#include <linux/fsnotify.h>
+#include <linux/slab.h>
+#include <linux/mempool.h>
+
+#include "netfs.h"
+
+static int pohmelfs_send_lock_trans(struct pohmelfs_inode *pi,
+ u64 id, u64 start, u32 size, int type)
+{
+ struct inode *inode = &pi->vfs_inode;
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ struct netfs_trans *t;
+ struct netfs_cmd *cmd;
+ int path_len, err;
+ void *data;
+ struct netfs_lock *l;
+ int isize = (type & POHMELFS_LOCK_GRAB) ? 0 : sizeof(struct netfs_inode_info);
+
+ err = pohmelfs_path_length(pi);
+ if (err < 0)
+ goto err_out_exit;
+
+ path_len = err;
+
+ err = -ENOMEM;
+ t = netfs_trans_alloc(psb, path_len + sizeof(struct netfs_lock) + isize, 0, 0);
+ if (!t)
+ goto err_out_exit;
+
+ cmd = netfs_trans_current(t);
+ data = cmd + 1;
+
+ err = pohmelfs_construct_path_string(pi, data, path_len);
+ if (err < 0)
+ goto err_out_free;
+ path_len = err;
+
+ l = data + path_len;
+
+ l->start = start;
+ l->size = size;
+ l->type = type;
+ l->ino = pi->ino;
+
+ cmd->cmd = NETFS_LOCK;
+ cmd->start = 0;
+ cmd->id = id;
+ cmd->size = sizeof(struct netfs_lock) + path_len + isize;
+ cmd->ext = path_len;
+ cmd->csize = 0;
+
+ netfs_convert_cmd(cmd);
+ netfs_convert_lock(l);
+
+ if (isize) {
+ struct netfs_inode_info *info = (struct netfs_inode_info *)(l + 1);
+
+ info->mode = inode->i_mode;
+ info->nlink = inode->i_nlink;
+ info->uid = inode->i_uid;
+ info->gid = inode->i_gid;
+ info->blocks = inode->i_blocks;
+ info->rdev = inode->i_rdev;
+ info->size = inode->i_size;
+ info->version = inode->i_version;
+
+ netfs_convert_inode_info(info);
+ }
+
+ netfs_trans_update(cmd, t, path_len + sizeof(struct netfs_lock) + isize);
+
+ return netfs_trans_finish(t, psb);
+
+err_out_free:
+ netfs_trans_free(t);
+err_out_exit:
+ printk("%s: err: %d.\n", __func__, err);
+ return err;
+}
+
+int pohmelfs_data_lock(struct pohmelfs_inode *pi, u64 start, u32 size, int type)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+ struct pohmelfs_mcache *m;
+ int err = -ENOMEM;
+ struct iattr iattr;
+ struct inode *inode = &pi->vfs_inode;
+
+ dprintk("%s: %p: ino: %llu, start: %llu, size: %u, "
+ "type: %d, locked as: %d, owned: %d.\n",
+ __func__, &pi->vfs_inode, pi->ino,
+ start, size, type, pi->lock_type,
+ !!test_bit(NETFS_INODE_OWNED, &pi->state));
+
+ if (!pohmelfs_need_lock(pi, type))
+ return 0;
+
+ m = pohmelfs_mcache_alloc(psb, start, size, NULL);
+ if (IS_ERR(m))
+ return PTR_ERR(m);
+
+ err = pohmelfs_send_lock_trans(pi, m->gen, start, size,
+ type | POHMELFS_LOCK_GRAB);
+ if (err)
+ goto err_out_put;
+
+ err = wait_for_completion_timeout(&m->complete, psb->mcache_timeout);
+ if (err)
+ err = m->err;
+ else
+ err = -ETIMEDOUT;
+
+ if (err) {
+ printk("%s: %p: ino: %llu, mgen: %llu, start: %llu, size: %u, err: %d.\n",
+ __func__, &pi->vfs_inode, pi->ino, m->gen, start, size, err);
+ }
+
+ if (err && (err != -ENOENT))
+ goto err_out_put;
+
+ if (!err) {
+ netfs_convert_inode_info(&m->info);
+
+ iattr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_SIZE | ATTR_ATIME;
+ iattr.ia_mode = m->info.mode;
+ iattr.ia_uid = m->info.uid;
+ iattr.ia_gid = m->info.gid;
+ iattr.ia_size = m->info.size;
+ iattr.ia_atime = CURRENT_TIME;
+
+ dprintk("%s: %p: ino: %llu, mgen: %llu, start: %llu, isize: %llu -> %llu.\n",
+ __func__, &pi->vfs_inode, pi->ino, m->gen, start, inode->i_size, m->info.size);
+
+ err = pohmelfs_setattr_raw(inode, &iattr);
+ if (!err) {
+ struct dentry *dentry = d_find_alias(inode);
+ if (dentry) {
+ fsnotify_change(dentry, iattr.ia_valid);
+ dput(dentry);
+ }
+ }
+ }
+
+ pi->lock_type = type;
+ set_bit(NETFS_INODE_OWNED, &pi->state);
+
+ pohmelfs_mcache_put(psb, m);
+
+ return 0;
+
+err_out_put:
+ pohmelfs_mcache_put(psb, m);
+ return err;
+}
+
+int pohmelfs_data_unlock(struct pohmelfs_inode *pi, u64 start, u32 size, int type)
+{
+ dprintk("%s: %p: ino: %llu, start: %llu, size: %u, type: %d.\n",
+ __func__, &pi->vfs_inode, pi->ino, start, size, type);
+ pi->lock_type = 0;
+ clear_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state);
+ clear_bit(NETFS_INODE_OWNED, &pi->state);
+ return pohmelfs_send_lock_trans(pi, pi->ino, start, size, type);
+}
diff --git a/drivers/staging/pohmelfs/mcache.c b/drivers/staging/pohmelfs/mcache.c
new file mode 100644
index 00000000000..e22665cdd16
--- /dev/null
+++ b/drivers/staging/pohmelfs/mcache.c
@@ -0,0 +1,171 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/mempool.h>
+
+#include "netfs.h"
+
+static struct kmem_cache *pohmelfs_mcache_cache;
+static mempool_t *pohmelfs_mcache_pool;
+
+static inline int pohmelfs_mcache_cmp(u64 gen, u64 new)
+{
+ if (gen < new)
+ return 1;
+ if (gen > new)
+ return -1;
+ return 0;
+}
+
+struct pohmelfs_mcache *pohmelfs_mcache_search(struct pohmelfs_sb *psb, u64 gen)
+{
+ struct rb_root *root = &psb->mcache_root;
+ struct rb_node *n = root->rb_node;
+ struct pohmelfs_mcache *tmp, *ret = NULL;
+ int cmp;
+
+ while (n) {
+ tmp = rb_entry(n, struct pohmelfs_mcache, mcache_entry);
+
+ cmp = pohmelfs_mcache_cmp(tmp->gen, gen);
+ if (cmp < 0)
+ n = n->rb_left;
+ else if (cmp > 0)
+ n = n->rb_right;
+ else {
+ ret = tmp;
+ pohmelfs_mcache_get(ret);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int pohmelfs_mcache_insert(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
+{
+ struct rb_root *root = &psb->mcache_root;
+ struct rb_node **n = &root->rb_node, *parent = NULL;
+ struct pohmelfs_mcache *ret = NULL, *tmp;
+ int cmp;
+
+ while (*n) {
+ parent = *n;
+
+ tmp = rb_entry(parent, struct pohmelfs_mcache, mcache_entry);
+
+ cmp = pohmelfs_mcache_cmp(tmp->gen, m->gen);
+ if (cmp < 0)
+ n = &parent->rb_left;
+ else if (cmp > 0)
+ n = &parent->rb_right;
+ else {
+ ret = tmp;
+ break;
+ }
+ }
+
+ if (ret)
+ return -EEXIST;
+
+ rb_link_node(&m->mcache_entry, parent, n);
+ rb_insert_color(&m->mcache_entry, root);
+
+ return 0;
+}
+
+static int pohmelfs_mcache_remove(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
+{
+ if (m && m->mcache_entry.rb_parent_color) {
+ rb_erase(&m->mcache_entry, &psb->mcache_root);
+ m->mcache_entry.rb_parent_color = 0;
+ return 1;
+ }
+ return 0;
+}
+
+void pohmelfs_mcache_remove_locked(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
+{
+ mutex_lock(&psb->mcache_lock);
+ pohmelfs_mcache_remove(psb, m);
+ mutex_unlock(&psb->mcache_lock);
+}
+
+struct pohmelfs_mcache *pohmelfs_mcache_alloc(struct pohmelfs_sb *psb, u64 start,
+ unsigned int size, void *data)
+{
+ struct pohmelfs_mcache *m;
+ int err = -ENOMEM;
+
+ m = mempool_alloc(pohmelfs_mcache_pool, GFP_KERNEL);
+ if (!m)
+ goto err_out_exit;
+
+ init_completion(&m->complete);
+ m->err = 0;
+ atomic_set(&m->refcnt, 1);
+ m->data = data;
+ m->start = start;
+ m->size = size;
+ m->gen = atomic_long_inc_return(&psb->mcache_gen);
+
+ mutex_lock(&psb->mcache_lock);
+ err = pohmelfs_mcache_insert(psb, m);
+ mutex_unlock(&psb->mcache_lock);
+ if (err)
+ goto err_out_free;
+
+ return m;
+
+err_out_free:
+ mempool_free(m, pohmelfs_mcache_pool);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+void pohmelfs_mcache_free(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
+{
+ pohmelfs_mcache_remove_locked(psb, m);
+
+ mempool_free(m, pohmelfs_mcache_pool);
+}
+
+int __init pohmelfs_mcache_init(void)
+{
+ pohmelfs_mcache_cache = kmem_cache_create("pohmelfs_mcache_cache",
+ sizeof(struct pohmelfs_mcache),
+ 0, (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD), NULL);
+ if (!pohmelfs_mcache_cache)
+ goto err_out_exit;
+
+ pohmelfs_mcache_pool = mempool_create_slab_pool(256, pohmelfs_mcache_cache);
+ if (!pohmelfs_mcache_pool)
+ goto err_out_free;
+
+ return 0;
+
+err_out_free:
+ kmem_cache_destroy(pohmelfs_mcache_cache);
+err_out_exit:
+ return -ENOMEM;
+}
+
+void pohmelfs_mcache_exit(void)
+{
+ mempool_destroy(pohmelfs_mcache_pool);
+ kmem_cache_destroy(pohmelfs_mcache_cache);
+}
diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c
new file mode 100644
index 00000000000..c9b8540c1ef
--- /dev/null
+++ b/drivers/staging/pohmelfs/net.c
@@ -0,0 +1,1247 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/fsnotify.h>
+#include <linux/jhash.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/kthread.h>
+#include <linux/pagemap.h>
+#include <linux/poll.h>
+#include <linux/swap.h>
+#include <linux/syscalls.h>
+#include <linux/vmalloc.h>
+
+#include "netfs.h"
+
+static int pohmelfs_ftrans_size = 10240;
+static u32 *pohmelfs_ftrans;
+
+int pohmelfs_ftrans_init(void)
+{
+ pohmelfs_ftrans = vmalloc(pohmelfs_ftrans_size * 4);
+ if (!pohmelfs_ftrans)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void pohmelfs_ftrans_exit(void)
+{
+ vfree(pohmelfs_ftrans);
+}
+
+void pohmelfs_ftrans_clean(u64 id)
+{
+ if (pohmelfs_ftrans) {
+ u32 i = id & 0xffffffff;
+ int idx = i % pohmelfs_ftrans_size;
+
+ pohmelfs_ftrans[idx] = 0;
+ }
+}
+
+void pohmelfs_ftrans_update(u64 id)
+{
+ if (pohmelfs_ftrans) {
+ u32 i = id & 0xffffffff;
+ int idx = i % pohmelfs_ftrans_size;
+
+ pohmelfs_ftrans[idx] = i;
+ }
+}
+
+int pohmelfs_ftrans_check(u64 id)
+{
+ if (pohmelfs_ftrans) {
+ u32 i = id & 0xffffffff;
+ int idx = i % pohmelfs_ftrans_size;
+
+ return (pohmelfs_ftrans[idx] == i);
+ }
+
+ return -1;
+}
+
+/*
+ * Async machinery lives here.
+ * All commands being sent to server do _not_ require sync reply,
+ * instead, if it is really needed, like readdir or readpage, caller
+ * sleeps waiting for data, which will be placed into provided buffer
+ * and caller will be awakened.
+ *
+ * Every command response can come without some listener. For example
+ * readdir response will add new objects into cache without appropriate
+ * request from userspace. This is used in cache coherency.
+ *
+ * If object is not found for given data, it is discarded.
+ *
+ * All requests are received by dedicated kernel thread.
+ */
+
+/*
+ * Basic network sending/receiving functions.
+ * Blocked mode is used.
+ */
+static int netfs_data_recv(struct netfs_state *st, void *buf, u64 size)
+{
+ struct msghdr msg;
+ struct kvec iov;
+ int err;
+
+ BUG_ON(!size);
+
+ iov.iov_base = buf;
+ iov.iov_len = size;
+
+ msg.msg_iov = (struct iovec *)&iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = MSG_DONTWAIT;
+
+ err = kernel_recvmsg(st->socket, &msg, &iov, 1, iov.iov_len,
+ msg.msg_flags);
+ if (err <= 0) {
+ printk("%s: failed to recv data: size: %llu, err: %d.\n", __func__, size, err);
+ if (err == 0)
+ err = -ECONNRESET;
+ }
+
+ return err;
+}
+
+static int pohmelfs_data_recv(struct netfs_state *st, void *data, unsigned int size)
+{
+ unsigned int revents = 0;
+ unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
+ unsigned int mask = err_mask | POLLIN;
+ int err = 0;
+
+ while (size && !err) {
+ revents = netfs_state_poll(st);
+
+ if (!(revents & mask)) {
+ DEFINE_WAIT(wait);
+
+ for (;;) {
+ prepare_to_wait(&st->thread_wait, &wait, TASK_INTERRUPTIBLE);
+ if (kthread_should_stop())
+ break;
+
+ revents = netfs_state_poll(st);
+
+ if (revents & mask)
+ break;
+
+ if (signal_pending(current))
+ break;
+
+ schedule();
+ continue;
+ }
+ finish_wait(&st->thread_wait, &wait);
+ }
+
+ err = 0;
+ netfs_state_lock(st);
+ if (st->socket && (st->read_socket == st->socket) && (revents & POLLIN)) {
+ err = netfs_data_recv(st, data, size);
+ if (err > 0) {
+ data += err;
+ size -= err;
+ err = 0;
+ } else if (err == 0)
+ err = -ECONNRESET;
+ }
+
+ if (revents & err_mask) {
+ printk("%s: revents: %x, socket: %p, size: %u, err: %d.\n",
+ __func__, revents, st->socket, size, err);
+ err = -ECONNRESET;
+ }
+ netfs_state_unlock(st);
+
+ if (err < 0) {
+ if (netfs_state_trylock_send(st)) {
+ netfs_state_exit(st);
+ err = netfs_state_init(st);
+ if (!err)
+ err = -EAGAIN;
+ netfs_state_unlock_send(st);
+ } else {
+ st->need_reset = 1;
+ }
+ }
+
+ if (kthread_should_stop())
+ err = -ENODEV;
+
+ if (err)
+ printk("%s: socket: %p, read_socket: %p, revents: %x, rev_error: %d, "
+ "should_stop: %d, size: %u, err: %d.\n",
+ __func__, st->socket, st->read_socket,
+ revents, revents & err_mask, kthread_should_stop(), size, err);
+ }
+
+ return err;
+}
+
+int pohmelfs_data_recv_and_check(struct netfs_state *st, void *data, unsigned int size)
+{
+ struct netfs_cmd *cmd = &st->cmd;
+ int err;
+
+ err = pohmelfs_data_recv(st, data, size);
+ if (err)
+ return err;
+
+ return pohmelfs_crypto_process_input_data(&st->eng, cmd->iv, data, NULL, size);
+}
+
+/*
+ * Polling machinery.
+ */
+
+struct netfs_poll_helper
+{
+ poll_table pt;
+ struct netfs_state *st;
+};
+
+static int netfs_queue_wake(wait_queue_t *wait, unsigned mode, int sync, void *key)
+{
+ struct netfs_state *st = container_of(wait, struct netfs_state, wait);
+
+ wake_up(&st->thread_wait);
+ return 1;
+}
+
+static void netfs_queue_func(struct file *file, wait_queue_head_t *whead,
+ poll_table *pt)
+{
+ struct netfs_state *st = container_of(pt, struct netfs_poll_helper, pt)->st;
+
+ st->whead = whead;
+ init_waitqueue_func_entry(&st->wait, netfs_queue_wake);
+ add_wait_queue(whead, &st->wait);
+}
+
+static void netfs_poll_exit(struct netfs_state *st)
+{
+ if (st->whead) {
+ remove_wait_queue(st->whead, &st->wait);
+ st->whead = NULL;
+ }
+}
+
+static int netfs_poll_init(struct netfs_state *st)
+{
+ struct netfs_poll_helper ph;
+
+ ph.st = st;
+ init_poll_funcptr(&ph.pt, &netfs_queue_func);
+
+ st->socket->ops->poll(NULL, st->socket, &ph.pt);
+ return 0;
+}
+
+/*
+ * Get response for readpage command. We search inode and page in its mapping
+ * and copy data into. If it was async request, then we queue page into shared
+ * data and wakeup listener, who will copy it to userspace.
+ *
+ * There is a work in progress of allowing to call copy_to_user() directly from
+ * async receiving kernel thread.
+ */
+static int pohmelfs_read_page_response(struct netfs_state *st)
+{
+ struct pohmelfs_sb *psb = st->psb;
+ struct netfs_cmd *cmd = &st->cmd;
+ struct inode *inode;
+ struct page *page;
+ int err = 0;
+
+ if (cmd->size > PAGE_CACHE_SIZE) {
+ err = -EINVAL;
+ goto err_out_exit;
+ }
+
+ inode = ilookup(st->psb->sb, cmd->id);
+ if (!inode) {
+ printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
+ err = -ENOENT;
+ goto err_out_exit;
+ }
+
+ page = find_get_page(inode->i_mapping, cmd->start >> PAGE_CACHE_SHIFT);
+ if (!page || !PageLocked(page)) {
+ printk("%s: failed to find/lock page: page: %p, id: %llu, start: %llu, index: %llu.\n",
+ __func__, page, cmd->id, cmd->start, cmd->start >> PAGE_CACHE_SHIFT);
+
+ while (cmd->size) {
+ unsigned int sz = min(cmd->size, st->size);
+
+ err = pohmelfs_data_recv(st, st->data, sz);
+ if (err)
+ break;
+
+ cmd->size -= sz;
+ }
+
+ err = -ENODEV;
+ if (page)
+ goto err_out_page_put;
+ goto err_out_put;
+ }
+
+ if (cmd->size) {
+ void *addr;
+
+ addr = kmap(page);
+ err = pohmelfs_data_recv(st, addr, cmd->size);
+ kunmap(page);
+
+ if (err)
+ goto err_out_page_unlock;
+ }
+
+ dprintk("%s: page: %p, start: %llu, size: %u, locked: %d.\n",
+ __func__, page, cmd->start, cmd->size, PageLocked(page));
+
+ SetPageChecked(page);
+ if ((psb->hash_string || psb->cipher_string) && psb->perform_crypto && cmd->size) {
+ err = pohmelfs_crypto_process_input_page(&st->eng, page, cmd->size, cmd->iv);
+ if (err < 0)
+ goto err_out_page_unlock;
+ } else {
+ SetPageUptodate(page);
+ unlock_page(page);
+ page_cache_release(page);
+ }
+
+ pohmelfs_put_inode(POHMELFS_I(inode));
+ wake_up(&st->psb->wait);
+
+ return 0;
+
+err_out_page_unlock:
+ SetPageError(page);
+ unlock_page(page);
+err_out_page_put:
+ page_cache_release(page);
+err_out_put:
+ pohmelfs_put_inode(POHMELFS_I(inode));
+err_out_exit:
+ wake_up(&st->psb->wait);
+ return err;
+}
+
+static int pohmelfs_check_name(struct pohmelfs_inode *parent, struct qstr *str,
+ struct netfs_inode_info *info)
+{
+ struct inode *inode;
+ struct pohmelfs_name *n;
+ int err = 0;
+ u64 ino = 0;
+
+ mutex_lock(&parent->offset_lock);
+ n = pohmelfs_search_hash(parent, str->hash);
+ if (n)
+ ino = n->ino;
+ mutex_unlock(&parent->offset_lock);
+
+ if (!ino)
+ goto out;
+
+ inode = ilookup(parent->vfs_inode.i_sb, ino);
+ if (!inode)
+ goto out;
+
+ dprintk("%s: parent: %llu, inode: %llu.\n", __func__, parent->ino, ino);
+
+ pohmelfs_fill_inode(inode, info);
+ pohmelfs_put_inode(POHMELFS_I(inode));
+ err = -EEXIST;
+out:
+ return err;
+}
+
+/*
+ * Readdir response from server. If special field is set, we wakeup
+ * listener (readdir() call), which will copy data to userspace.
+ */
+static int pohmelfs_readdir_response(struct netfs_state *st)
+{
+ struct inode *inode;
+ struct netfs_cmd *cmd = &st->cmd;
+ struct netfs_inode_info *info;
+ struct pohmelfs_inode *parent = NULL, *npi;
+ int err = 0, last = cmd->ext;
+ struct qstr str;
+
+ if (cmd->size > st->size)
+ return -EINVAL;
+
+ inode = ilookup(st->psb->sb, cmd->id);
+ if (!inode) {
+ printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
+ return -ENOENT;
+ }
+ parent = POHMELFS_I(inode);
+
+ if (!cmd->size && cmd->start) {
+ err = -cmd->start;
+ goto out;
+ }
+
+ if (cmd->size) {
+ char *name;
+
+ err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
+ if (err)
+ goto err_out_put;
+
+ info = (struct netfs_inode_info *)(st->data);
+
+ name = (char *)(info + 1);
+ str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
+ name[str.len] = 0;
+ str.name = name;
+ str.hash = jhash(str.name, str.len, 0);
+
+ netfs_convert_inode_info(info);
+
+ if (parent) {
+ err = pohmelfs_check_name(parent, &str, info);
+ if (err) {
+ if (err == -EEXIST)
+ err = 0;
+ goto out;
+ }
+ }
+
+ info->ino = cmd->start;
+ if (!info->ino)
+ info->ino = pohmelfs_new_ino(st->psb);
+
+ dprintk("%s: parent: %llu, ino: %llu, name: '%s', hash: %x, len: %u, mode: %o.\n",
+ __func__, parent->ino, info->ino, str.name, str.hash, str.len,
+ info->mode);
+
+ npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
+ if (IS_ERR(npi)) {
+ err = PTR_ERR(npi);
+
+ if (err != -EEXIST)
+ goto err_out_put;
+ } else {
+ set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
+ clear_bit(NETFS_INODE_OWNED, &npi->state);
+ }
+ }
+out:
+ if (last) {
+ set_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
+ set_bit(NETFS_INODE_REMOTE_SYNCED, &parent->state);
+ wake_up(&st->psb->wait);
+ }
+ pohmelfs_put_inode(parent);
+
+ return err;
+
+err_out_put:
+ clear_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
+ printk("%s: parent: %llu, ino: %llu, cmd_id: %llu.\n", __func__, parent->ino, cmd->start, cmd->id);
+ pohmelfs_put_inode(parent);
+ wake_up(&st->psb->wait);
+ return err;
+}
+
+/*
+ * Lookup command response.
+ * It searches for inode to be looked at (if it exists) and substitutes
+ * its inode information (size, permission, mode and so on), if inode does
+ * not exist, new one will be created and inserted into caches.
+ */
+static int pohmelfs_lookup_response(struct netfs_state *st)
+{
+ struct inode *inode = NULL;
+ struct netfs_cmd *cmd = &st->cmd;
+ struct netfs_inode_info *info;
+ struct pohmelfs_inode *parent = NULL, *npi;
+ int err = -EINVAL;
+ char *name;
+
+ inode = ilookup(st->psb->sb, cmd->id);
+ if (!inode) {
+ printk("%s: lookup response: id: %llu, start: %llu, size: %u.\n",
+ __func__, cmd->id, cmd->start, cmd->size);
+ err = -ENOENT;
+ goto err_out_exit;
+ }
+ parent = POHMELFS_I(inode);
+
+ if (!cmd->size) {
+ err = -cmd->start;
+ goto err_out_put;
+ }
+
+ if (cmd->size < sizeof(struct netfs_inode_info)) {
+ printk("%s: broken lookup response: id: %llu, start: %llu, size: %u.\n",
+ __func__, cmd->id, cmd->start, cmd->size);
+ err = -EINVAL;
+ goto err_out_put;
+ }
+
+ err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
+ if (err)
+ goto err_out_put;
+
+ info = (struct netfs_inode_info *)(st->data);
+ name = (char *)(info + 1);
+
+ netfs_convert_inode_info(info);
+
+ info->ino = cmd->start;
+ if (!info->ino)
+ info->ino = pohmelfs_new_ino(st->psb);
+
+ dprintk("%s: parent: %llu, ino: %llu, name: '%s', start: %llu.\n",
+ __func__, parent->ino, info->ino, name, cmd->start);
+
+ if (cmd->start)
+ npi = pohmelfs_new_inode(st->psb, parent, NULL, info, 0);
+ else {
+ struct qstr str;
+
+ str.name = name;
+ str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
+ str.hash = jhash(name, str.len, 0);
+
+ npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
+ }
+ if (IS_ERR(npi)) {
+ err = PTR_ERR(npi);
+
+ if (err != -EEXIST)
+ goto err_out_put;
+ } else {
+ set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
+ clear_bit(NETFS_INODE_OWNED, &npi->state);
+ }
+
+ clear_bit(NETFS_COMMAND_PENDING, &parent->state);
+ pohmelfs_put_inode(parent);
+
+ wake_up(&st->psb->wait);
+
+ return 0;
+
+err_out_put:
+ pohmelfs_put_inode(parent);
+err_out_exit:
+ clear_bit(NETFS_COMMAND_PENDING, &parent->state);
+ wake_up(&st->psb->wait);
+ printk("%s: inode: %p, id: %llu, start: %llu, size: %u, err: %d.\n",
+ __func__, inode, cmd->id, cmd->start, cmd->size, err);
+ return err;
+}
+
+/*
+ * Create response, just marks local inode as 'created', so that writeback
+ * for any of its children (or own) would not try to sync it again.
+ */
+static int pohmelfs_create_response(struct netfs_state *st)
+{
+ struct inode *inode;
+ struct netfs_cmd *cmd = &st->cmd;
+ struct pohmelfs_inode *pi;
+
+ inode = ilookup(st->psb->sb, cmd->id);
+ if (!inode) {
+ printk("%s: failed to find inode: id: %llu, start: %llu.\n",
+ __func__, cmd->id, cmd->start);
+ goto err_out_exit;
+ }
+
+ pi = POHMELFS_I(inode);
+
+ /*
+ * To lock or not to lock?
+ * We actually do not care if it races...
+ */
+ if (cmd->start)
+ make_bad_inode(inode);
+ set_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+
+ pohmelfs_put_inode(pi);
+
+ wake_up(&st->psb->wait);
+ return 0;
+
+err_out_exit:
+ wake_up(&st->psb->wait);
+ return -ENOENT;
+}
+
+/*
+ * Object remove response. Just says that remove request has been received.
+ * Used in cache coherency protocol.
+ */
+static int pohmelfs_remove_response(struct netfs_state *st)
+{
+ struct netfs_cmd *cmd = &st->cmd;
+ int err;
+
+ err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
+ if (err)
+ return err;
+
+ dprintk("%s: parent: %llu, path: '%s'.\n", __func__, cmd->id, (char *)st->data);
+
+ return 0;
+}
+
+/*
+ * Transaction reply processing.
+ *
+ * Find transaction based on its generation number, bump its reference counter,
+ * so that none could free it under us, drop from the trees and lists and
+ * drop reference counter. When it hits zero (when all destinations replied
+ * and all timeout handled by async scanning code), completion will be called
+ * and transaction will be freed.
+ */
+static int pohmelfs_transaction_response(struct netfs_state *st)
+{
+ struct netfs_trans_dst *dst;
+ struct netfs_trans *t = NULL;
+ struct netfs_cmd *cmd = &st->cmd;
+ short err = (signed)cmd->ext;
+
+ mutex_lock(&st->trans_lock);
+ dst = netfs_trans_search(st, cmd->start);
+ if (dst) {
+ netfs_trans_remove_nolock(dst, st);
+ t = dst->trans;
+
+ pohmelfs_ftrans_update(cmd->start);
+ }
+ mutex_unlock(&st->trans_lock);
+
+ if (!t) {
+ int check = pohmelfs_ftrans_check(cmd->start);
+ printk("%s: failed to find transaction: start: %llu: id: %llu, size: %u, ext: %u, double: %d.\n",
+ __func__, cmd->start, cmd->id, cmd->size, cmd->ext, check);
+ err = -EINVAL;
+ goto out;
+ }
+
+ t->result = err;
+ netfs_trans_drop_dst_nostate(dst);
+
+out:
+ wake_up(&st->psb->wait);
+ return err;
+}
+
+/*
+ * Inode metadata cache coherency message.
+ */
+static int pohmelfs_page_cache_response(struct netfs_state *st)
+{
+ struct netfs_cmd *cmd = &st->cmd;
+ struct inode *inode;
+
+ dprintk("%s: st: %p, id: %llu, start: %llu, size: %u.\n", __func__, st, cmd->id, cmd->start, cmd->size);
+
+ inode = ilookup(st->psb->sb, cmd->id);
+ if (!inode) {
+ printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
+ return -ENOENT;
+ }
+
+ set_bit(NETFS_INODE_NEED_FLUSH, &POHMELFS_I(inode)->state);
+ pohmelfs_put_inode(POHMELFS_I(inode));
+
+ return 0;
+}
+
+/*
+ * Root capabilities response: export statistics
+ * like used and available size, number of files and dirs,
+ * permissions.
+ */
+static int pohmelfs_root_cap_response(struct netfs_state *st)
+{
+ struct netfs_cmd *cmd = &st->cmd;
+ struct netfs_root_capabilities *cap;
+ struct pohmelfs_sb *psb = st->psb;
+
+ if (cmd->size != sizeof(struct netfs_root_capabilities)) {
+ psb->flags = EPROTO;
+ wake_up(&psb->wait);
+ return -EPROTO;
+ }
+
+ cap = st->data;
+
+ netfs_convert_root_capabilities(cap);
+
+ if (psb->total_size < cap->used + cap->avail)
+ psb->total_size = cap->used + cap->avail;
+ if (cap->avail)
+ psb->avail_size = cap->avail;
+ psb->state_flags = cap->flags;
+
+ if (psb->state_flags & POHMELFS_FLAGS_RO) {
+ psb->sb->s_flags |= MS_RDONLY;
+ printk(KERN_INFO "Mounting POHMELFS (%d) read-only.\n", psb->idx);
+ }
+
+ if (psb->state_flags & POHMELFS_FLAGS_XATTR)
+ printk(KERN_INFO "Mounting POHMELFS (%d) "
+ "with extended attributes support.\n", psb->idx);
+
+ if (atomic_read(&psb->total_inodes) <= 1)
+ atomic_long_set(&psb->total_inodes, cap->nr_files);
+
+ dprintk("%s: total: %llu, avail: %llu, flags: %llx, inodes: %llu.\n",
+ __func__, psb->total_size, psb->avail_size, psb->state_flags, cap->nr_files);
+
+ psb->flags = 0;
+ wake_up(&psb->wait);
+ return 0;
+}
+
+/*
+ * Crypto capabilities of the server, where it says that
+ * it supports or does not requested hash/cipher algorithms.
+ */
+static int pohmelfs_crypto_cap_response(struct netfs_state *st)
+{
+ struct netfs_cmd *cmd = &st->cmd;
+ struct netfs_crypto_capabilities *cap;
+ struct pohmelfs_sb *psb = st->psb;
+ int err = 0;
+
+ if (cmd->size != sizeof(struct netfs_crypto_capabilities)) {
+ psb->flags = EPROTO;
+ wake_up(&psb->wait);
+ return -EPROTO;
+ }
+
+ cap = st->data;
+
+ dprintk("%s: cipher '%s': %s, hash: '%s': %s.\n",
+ __func__,
+ psb->cipher_string, (cap->cipher_strlen)?"SUPPORTED":"NOT SUPPORTED",
+ psb->hash_string, (cap->hash_strlen)?"SUPPORTED":"NOT SUPPORTED");
+
+ if (!cap->hash_strlen) {
+ if (psb->hash_strlen && psb->crypto_fail_unsupported)
+ err = -ENOTSUPP;
+ psb->hash_strlen = 0;
+ kfree(psb->hash_string);
+ psb->hash_string = NULL;
+ }
+
+ if (!cap->cipher_strlen) {
+ if (psb->cipher_strlen && psb->crypto_fail_unsupported)
+ err = -ENOTSUPP;
+ psb->cipher_strlen = 0;
+ kfree(psb->cipher_string);
+ psb->cipher_string = NULL;
+ }
+
+ return err;
+}
+
+/*
+ * Capabilities handshake response.
+ */
+static int pohmelfs_capabilities_response(struct netfs_state *st)
+{
+ struct netfs_cmd *cmd = &st->cmd;
+ int err = 0;
+
+ err = pohmelfs_data_recv(st, st->data, cmd->size);
+ if (err)
+ return err;
+
+ switch (cmd->id) {
+ case POHMELFS_CRYPTO_CAPABILITIES:
+ return pohmelfs_crypto_cap_response(st);
+ case POHMELFS_ROOT_CAPABILITIES:
+ return pohmelfs_root_cap_response(st);
+ default:
+ break;
+ }
+ return -EINVAL;
+}
+
+/*
+ * Receiving extended attribute.
+ * Does not work properly if received size is more than requested one,
+ * it should not happen with current request/reply model though.
+ */
+static int pohmelfs_getxattr_response(struct netfs_state *st)
+{
+ struct pohmelfs_sb *psb = st->psb;
+ struct netfs_cmd *cmd = &st->cmd;
+ struct pohmelfs_mcache *m;
+ short error = (signed short)cmd->ext, err;
+ unsigned int sz, total_size;
+
+ m = pohmelfs_mcache_search(psb, cmd->id);
+
+ dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
+ __func__, cmd->id, (m)?m->gen:0, error);
+
+ if (!m) {
+ printk("%s: failed to find getxattr cache entry: id: %llu.\n", __func__, cmd->id);
+ return -ENOENT;
+ }
+
+ if (cmd->size) {
+ sz = min_t(unsigned int, cmd->size, m->size);
+ err = pohmelfs_data_recv_and_check(st, m->data, sz);
+ if (err) {
+ error = err;
+ goto out;
+ }
+
+ m->size = sz;
+ total_size = cmd->size - sz;
+
+ while (total_size) {
+ sz = min(total_size, st->size);
+
+ err = pohmelfs_data_recv_and_check(st, st->data, sz);
+ if (err) {
+ error = err;
+ break;
+ }
+
+ total_size -= sz;
+ }
+ }
+
+out:
+ m->err = error;
+ complete(&m->complete);
+ pohmelfs_mcache_put(psb, m);
+
+ return error;
+}
+
+int pohmelfs_data_lock_response(struct netfs_state *st)
+{
+ struct pohmelfs_sb *psb = st->psb;
+ struct netfs_cmd *cmd = &st->cmd;
+ struct pohmelfs_mcache *m;
+ short err = (signed short)cmd->ext;
+ u64 id = cmd->id;
+
+ m = pohmelfs_mcache_search(psb, id);
+
+ dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
+ __func__, cmd->id, (m)?m->gen:0, err);
+
+ if (!m) {
+ pohmelfs_data_recv(st, st->data, cmd->size);
+ printk("%s: failed to find data lock response: id: %llu.\n", __func__, cmd->id);
+ return -ENOENT;
+ }
+
+ if (cmd->size)
+ err = pohmelfs_data_recv_and_check(st, &m->info, cmd->size);
+
+ m->err = err;
+ complete(&m->complete);
+ pohmelfs_mcache_put(psb, m);
+
+ return err;
+}
+
+static void __inline__ netfs_state_reset(struct netfs_state *st)
+{
+ netfs_state_lock_send(st);
+ netfs_state_exit(st);
+ netfs_state_init(st);
+ netfs_state_unlock_send(st);
+}
+
+/*
+ * Main receiving function, called from dedicated kernel thread.
+ */
+static int pohmelfs_recv(void *data)
+{
+ int err = -EINTR;
+ struct netfs_state *st = data;
+ struct netfs_cmd *cmd = &st->cmd;
+
+ while (!kthread_should_stop()) {
+ /*
+ * If socket will be reset after this statement, then
+ * pohmelfs_data_recv() will just fail and loop will
+ * start again, so it can be done without any locks.
+ *
+ * st->read_socket is needed to prevents state machine
+ * breaking between this data reading and subsequent one
+ * in protocol specific functions during connection reset.
+ * In case of reset we have to read next command and do
+ * not expect data for old command to magically appear in
+ * new connection.
+ */
+ st->read_socket = st->socket;
+ err = pohmelfs_data_recv(st, cmd, sizeof(struct netfs_cmd));
+ if (err) {
+ msleep(1000);
+ continue;
+ }
+
+ netfs_convert_cmd(cmd);
+
+ dprintk("%s: cmd: %u, id: %llu, start: %llu, size: %u, "
+ "ext: %u, csize: %u, cpad: %u.\n",
+ __func__, cmd->cmd, cmd->id, cmd->start,
+ cmd->size, cmd->ext, cmd->csize, cmd->cpad);
+
+ if (cmd->csize) {
+ struct pohmelfs_crypto_engine *e = &st->eng;
+
+ if (unlikely(cmd->csize > e->size/2)) {
+ netfs_state_reset(st);
+ continue;
+ }
+
+ if (e->hash && unlikely(cmd->csize != st->psb->crypto_attached_size)) {
+ dprintk("%s: cmd: cmd: %u, id: %llu, start: %llu, size: %u, "
+ "csize: %u != digest size %u.\n",
+ __func__, cmd->cmd, cmd->id, cmd->start, cmd->size,
+ cmd->csize, st->psb->crypto_attached_size);
+ netfs_state_reset(st);
+ continue;
+ }
+
+ err = pohmelfs_data_recv(st, e->data, cmd->csize);
+ if (err) {
+ netfs_state_reset(st);
+ continue;
+ }
+
+#ifdef CONFIG_POHMELFS_DEBUG
+ {
+ unsigned int i;
+ unsigned char *hash = e->data;
+
+ dprintk("%s: received hash: ", __func__);
+ for (i=0; i<cmd->csize; ++i) {
+ printk("%02x ", hash[i]);
+ }
+ printk("\n");
+ }
+#endif
+ cmd->size -= cmd->csize;
+ }
+
+ /*
+ * This should catch protocol breakage and random garbage instead of commands.
+ */
+ if (unlikely((cmd->size > st->size) && (cmd->cmd != NETFS_XATTR_GET))) {
+ netfs_state_reset(st);
+ continue;
+ }
+
+ switch (cmd->cmd) {
+ case NETFS_READ_PAGE:
+ err = pohmelfs_read_page_response(st);
+ break;
+ case NETFS_READDIR:
+ err = pohmelfs_readdir_response(st);
+ break;
+ case NETFS_LOOKUP:
+ err = pohmelfs_lookup_response(st);
+ break;
+ case NETFS_CREATE:
+ err = pohmelfs_create_response(st);
+ break;
+ case NETFS_REMOVE:
+ err = pohmelfs_remove_response(st);
+ break;
+ case NETFS_TRANS:
+ err = pohmelfs_transaction_response(st);
+ break;
+ case NETFS_PAGE_CACHE:
+ err = pohmelfs_page_cache_response(st);
+ break;
+ case NETFS_CAPABILITIES:
+ err = pohmelfs_capabilities_response(st);
+ break;
+ case NETFS_LOCK:
+ err = pohmelfs_data_lock_response(st);
+ break;
+ case NETFS_XATTR_GET:
+ err = pohmelfs_getxattr_response(st);
+ break;
+ default:
+ printk("%s: wrong cmd: %u, id: %llu, start: %llu, size: %u, ext: %u.\n",
+ __func__, cmd->cmd, cmd->id, cmd->start, cmd->size, cmd->ext);
+ netfs_state_reset(st);
+ break;
+ }
+ }
+
+ while (!kthread_should_stop())
+ schedule_timeout_uninterruptible(msecs_to_jiffies(10));
+
+ return err;
+}
+
+int netfs_state_init(struct netfs_state *st)
+{
+ int err;
+ struct pohmelfs_ctl *ctl = &st->ctl;
+
+ err = sock_create(ctl->addr.sa_family, ctl->type, ctl->proto, &st->socket);
+ if (err) {
+ printk("%s: failed to create a socket: family: %d, type: %d, proto: %d, err: %d.\n",
+ __func__, ctl->addr.sa_family, ctl->type, ctl->proto, err);
+ goto err_out_exit;
+ }
+
+ st->socket->sk->sk_allocation = GFP_NOIO;
+ st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);
+
+ err = kernel_connect(st->socket, (struct sockaddr *)&ctl->addr, ctl->addrlen, 0);
+ if (err) {
+ printk("%s: failed to connect to server: idx: %u, err: %d.\n",
+ __func__, st->psb->idx, err);
+ goto err_out_release;
+ }
+ st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);
+
+ err = netfs_poll_init(st);
+ if (err)
+ goto err_out_release;
+
+ if (st->socket->ops->family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)&ctl->addr;
+ printk(KERN_INFO "%s: (re)connected to peer %u.%u.%u.%u:%d.\n", __func__,
+ NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+ } else if (st->socket->ops->family == AF_INET6) {
+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&ctl->addr;
+ printk(KERN_INFO "%s: (re)connected to peer "
+ "%pi6:%d",
+ __func__, &sin->sin6_addr, ntohs(sin->sin6_port));
+ }
+
+ return 0;
+
+err_out_release:
+ sock_release(st->socket);
+err_out_exit:
+ st->socket = NULL;
+ return err;
+}
+
+void netfs_state_exit(struct netfs_state *st)
+{
+ if (st->socket) {
+ netfs_poll_exit(st);
+ st->socket->ops->shutdown(st->socket, 2);
+
+ if (st->socket->ops->family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
+ printk("%s: disconnected from peer %u.%u.%u.%u:%d.\n", __func__,
+ NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+ } else if (st->socket->ops->family == AF_INET6) {
+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
+ printk("%s: disconnected from peer "
+ "%pi6:%d",
+ __func__, &sin->sin6_addr, ntohs(sin->sin6_port));
+ }
+
+ sock_release(st->socket);
+ st->socket = NULL;
+ st->read_socket = NULL;
+ st->need_reset = 0;
+ }
+}
+
+int pohmelfs_state_init_one(struct pohmelfs_sb *psb, struct pohmelfs_config *conf)
+{
+ struct netfs_state *st = &conf->state;
+ int err = -ENOMEM;
+
+ mutex_init(&st->__state_lock);
+ mutex_init(&st->__state_send_lock);
+ init_waitqueue_head(&st->thread_wait);
+
+ st->psb = psb;
+ st->trans_root = RB_ROOT;
+ mutex_init(&st->trans_lock);
+
+ st->size = psb->trans_data_size;
+ st->data = kmalloc(st->size, GFP_KERNEL);
+ if (!st->data)
+ goto err_out_exit;
+
+ if (psb->perform_crypto) {
+ err = pohmelfs_crypto_engine_init(&st->eng, psb);
+ if (err)
+ goto err_out_free_data;
+ }
+
+ err = netfs_state_init(st);
+ if (err)
+ goto err_out_free_engine;
+
+ st->thread = kthread_run(pohmelfs_recv, st, "pohmelfs/%u", psb->idx);
+ if (IS_ERR(st->thread)) {
+ err = PTR_ERR(st->thread);
+ goto err_out_netfs_exit;
+ }
+
+ if (!psb->active_state)
+ psb->active_state = conf;
+
+ dprintk("%s: conf: %p, st: %p, socket: %p.\n",
+ __func__, conf, st, st->socket);
+ return 0;
+
+err_out_netfs_exit:
+ netfs_state_exit(st);
+err_out_free_engine:
+ pohmelfs_crypto_engine_exit(&st->eng);
+err_out_free_data:
+ kfree(st->data);
+err_out_exit:
+ return err;
+
+}
+
+void pohmelfs_state_flush_transactions(struct netfs_state *st)
+{
+ struct rb_node *rb_node;
+ struct netfs_trans_dst *dst;
+
+ mutex_lock(&st->trans_lock);
+ for (rb_node = rb_first(&st->trans_root); rb_node; ) {
+ dst = rb_entry(rb_node, struct netfs_trans_dst, state_entry);
+ rb_node = rb_next(rb_node);
+
+ dst->trans->result = -EINVAL;
+ netfs_trans_remove_nolock(dst, st);
+ netfs_trans_drop_dst_nostate(dst);
+ }
+ mutex_unlock(&st->trans_lock);
+}
+
+static void pohmelfs_state_exit_one(struct pohmelfs_config *c)
+{
+ struct netfs_state *st = &c->state;
+
+ dprintk("%s: exiting, st: %p.\n", __func__, st);
+ if (st->thread) {
+ kthread_stop(st->thread);
+ st->thread = NULL;
+ }
+
+ netfs_state_lock_send(st);
+ netfs_state_exit(st);
+ netfs_state_unlock_send(st);
+
+ pohmelfs_state_flush_transactions(st);
+
+ pohmelfs_crypto_engine_exit(&st->eng);
+ kfree(st->data);
+
+ kfree(c);
+}
+
+/*
+ * Initialize network stack. It searches for given ID in global
+ * configuration table, this contains information of the remote server
+ * (address (any supported by socket interface) and port, protocol and so on).
+ */
+int pohmelfs_state_init(struct pohmelfs_sb *psb)
+{
+ int err = -ENOMEM;
+
+ err = pohmelfs_copy_config(psb);
+ if (err) {
+ pohmelfs_state_exit(psb);
+ return err;
+ }
+
+ return 0;
+}
+
+void pohmelfs_state_exit(struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config *c, *tmp;
+
+ list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
+ list_del(&c->config_entry);
+ pohmelfs_state_exit_one(c);
+ }
+}
+
+void pohmelfs_switch_active(struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config *c = psb->active_state;
+
+ if (!list_empty(&psb->state_list)) {
+ if (c->config_entry.next != &psb->state_list) {
+ psb->active_state = list_entry(c->config_entry.next,
+ struct pohmelfs_config, config_entry);
+ } else {
+ psb->active_state = list_entry(psb->state_list.next,
+ struct pohmelfs_config, config_entry);
+ }
+
+ dprintk("%s: empty: %d, active %p -> %p.\n",
+ __func__, list_empty(&psb->state_list), c,
+ psb->active_state);
+ } else
+ psb->active_state = NULL;
+}
+
+void pohmelfs_check_states(struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config *c, *tmp;
+ LIST_HEAD(delete_list);
+
+ mutex_lock(&psb->state_lock);
+ list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
+ if (pohmelfs_config_check(c, psb->idx)) {
+
+ if (psb->active_state == c)
+ pohmelfs_switch_active(psb);
+ list_move(&c->config_entry, &delete_list);
+ }
+ }
+ pohmelfs_copy_config(psb);
+ mutex_unlock(&psb->state_lock);
+
+ list_for_each_entry_safe(c, tmp, &delete_list, config_entry) {
+ list_del(&c->config_entry);
+ pohmelfs_state_exit_one(c);
+ }
+}
diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h
new file mode 100644
index 00000000000..2ff21ae5bb1
--- /dev/null
+++ b/drivers/staging/pohmelfs/netfs.h
@@ -0,0 +1,932 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __NETFS_H
+#define __NETFS_H
+
+#include <linux/types.h>
+#include <linux/connector.h>
+
+#define POHMELFS_CN_IDX 5
+#define POHMELFS_CN_VAL 0
+
+#define POHMELFS_CTLINFO_ACK 1
+#define POHMELFS_NOINFO_ACK 2
+
+
+/*
+ * Network command structure.
+ * Will be extended.
+ */
+struct netfs_cmd
+{
+ __u16 cmd; /* Command number */
+ __u16 csize; /* Attached crypto information size */
+ __u16 cpad; /* Attached padding size */
+ __u16 ext; /* External flags */
+ __u32 size; /* Size of the attached data */
+ __u32 trans; /* Transaction id */
+ __u64 id; /* Object ID to operate on. Used for feedback.*/
+ __u64 start; /* Start of the object. */
+ __u64 iv; /* IV sequence */
+ __u8 data[0];
+};
+
+static inline void netfs_convert_cmd(struct netfs_cmd *cmd)
+{
+ cmd->id = __be64_to_cpu(cmd->id);
+ cmd->start = __be64_to_cpu(cmd->start);
+ cmd->iv = __be64_to_cpu(cmd->iv);
+ cmd->cmd = __be16_to_cpu(cmd->cmd);
+ cmd->ext = __be16_to_cpu(cmd->ext);
+ cmd->csize = __be16_to_cpu(cmd->csize);
+ cmd->cpad = __be16_to_cpu(cmd->cpad);
+ cmd->size = __be32_to_cpu(cmd->size);
+}
+
+#define NETFS_TRANS_SINGLE_DST (1<<0)
+
+enum {
+ NETFS_READDIR = 1, /* Read directory for given inode number */
+ NETFS_READ_PAGE, /* Read data page from the server */
+ NETFS_WRITE_PAGE, /* Write data page to the server */
+ NETFS_CREATE, /* Create directory entry */
+ NETFS_REMOVE, /* Remove directory entry */
+
+ NETFS_LOOKUP, /* Lookup single object */
+ NETFS_LINK, /* Create a link */
+ NETFS_TRANS, /* Transaction */
+ NETFS_OPEN, /* Open intent */
+ NETFS_INODE_INFO, /* Metadata cache coherency synchronization message */
+
+ NETFS_PAGE_CACHE, /* Page cache invalidation message */
+ NETFS_READ_PAGES, /* Read multiple contiguous pages in one go */
+ NETFS_RENAME, /* Rename object */
+ NETFS_CAPABILITIES, /* Capabilities of the client, for example supported crypto */
+ NETFS_LOCK, /* Distributed lock message */
+
+ NETFS_XATTR_SET, /* Set extended attribute */
+ NETFS_XATTR_GET, /* Get extended attribute */
+ NETFS_CMD_MAX
+};
+
+enum {
+ POHMELFS_FLAGS_ADD = 0, /* Network state control message for ADD */
+ POHMELFS_FLAGS_DEL, /* Network state control message for DEL */
+ POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */
+ POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */
+};
+
+/*
+ * Always wanted to copy it from socket headers into public one,
+ * since they are __KERNEL__ protected there.
+ */
+#define _K_SS_MAXSIZE 128
+
+struct saddr
+{
+ unsigned short sa_family;
+ char addr[_K_SS_MAXSIZE];
+};
+
+enum {
+ POHMELFS_CRYPTO_HASH = 0,
+ POHMELFS_CRYPTO_CIPHER,
+};
+
+struct pohmelfs_crypto
+{
+ unsigned int idx; /* Config index */
+ unsigned short strlen; /* Size of the attached crypto string including 0-byte
+ * "cbc(aes)" for example */
+ unsigned short type; /* HMAC, cipher, both */
+ unsigned int keysize; /* Key size */
+ unsigned char data[0]; /* Algorithm string, key and IV */
+};
+
+/*
+ * Configuration command used to create table of different remote servers.
+ */
+struct pohmelfs_ctl
+{
+ unsigned int idx; /* Config index */
+ unsigned int type; /* Socket type */
+ unsigned int proto; /* Socket protocol */
+ unsigned int addrlen; /* Size of the address */
+ unsigned short unused; /* Align structure by 4 bytes */
+ struct saddr addr; /* Remote server address */
+};
+
+/*
+ * Ack for userspace about requested command.
+ */
+struct pohmelfs_cn_ack
+{
+ struct cn_msg msg;
+ int error;
+ int msg_num;
+ int unused[3];
+ struct pohmelfs_ctl ctl;
+};
+
+/*
+ * Inode info structure used to sync with server.
+ * Check what stat() returns.
+ */
+struct netfs_inode_info
+{
+ unsigned int mode;
+ unsigned int nlink;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int blocksize;
+ unsigned int padding;
+ __u64 ino;
+ __u64 blocks;
+ __u64 rdev;
+ __u64 size;
+ __u64 version;
+};
+
+static inline void netfs_convert_inode_info(struct netfs_inode_info *info)
+{
+ info->mode = __cpu_to_be32(info->mode);
+ info->nlink = __cpu_to_be32(info->nlink);
+ info->uid = __cpu_to_be32(info->uid);
+ info->gid = __cpu_to_be32(info->gid);
+ info->blocksize = __cpu_to_be32(info->blocksize);
+ info->blocks = __cpu_to_be64(info->blocks);
+ info->rdev = __cpu_to_be64(info->rdev);
+ info->size = __cpu_to_be64(info->size);
+ info->version = __cpu_to_be64(info->version);
+ info->ino = __cpu_to_be64(info->ino);
+}
+
+/*
+ * Cache state machine.
+ */
+enum {
+ NETFS_COMMAND_PENDING = 0, /* Command is being executed */
+ NETFS_INODE_REMOTE_SYNCED, /* Inode was synced to server */
+ NETFS_INODE_REMOTE_DIR_SYNCED, /* Inode (directory) was synced from the server */
+ NETFS_INODE_OWNED, /* Inode is owned by given host */
+ NETFS_INODE_NEED_FLUSH, /* Inode has to be flushed to the server */
+};
+
+/*
+ * POHMELFS capabilities: information about supported
+ * crypto operations (hash/cipher, modes, key sizes and so on),
+ * root informaion (used/available size, number of objects, permissions)
+ */
+enum pohmelfs_capabilities {
+ POHMELFS_CRYPTO_CAPABILITIES = 0,
+ POHMELFS_ROOT_CAPABILITIES,
+};
+
+/* Read-only mount */
+#define POHMELFS_FLAGS_RO (1<<0)
+/* Extended attributes support on/off */
+#define POHMELFS_FLAGS_XATTR (1<<1)
+
+struct netfs_root_capabilities
+{
+ __u64 nr_files;
+ __u64 used, avail;
+ __u64 flags;
+};
+
+static inline void netfs_convert_root_capabilities(struct netfs_root_capabilities *cap)
+{
+ cap->nr_files = __cpu_to_be64(cap->nr_files);
+ cap->used = __cpu_to_be64(cap->used);
+ cap->avail = __cpu_to_be64(cap->avail);
+ cap->flags = __cpu_to_be64(cap->flags);
+}
+
+struct netfs_crypto_capabilities
+{
+ unsigned short hash_strlen; /* Hash string length, like "hmac(sha1) including 0 byte "*/
+ unsigned short cipher_strlen; /* Cipher string length with the same format */
+ unsigned int cipher_keysize; /* Cipher key size */
+};
+
+static inline void netfs_convert_crypto_capabilities(struct netfs_crypto_capabilities *cap)
+{
+ cap->hash_strlen = __cpu_to_be16(cap->hash_strlen);
+ cap->cipher_strlen = __cpu_to_be16(cap->cipher_strlen);
+ cap->cipher_keysize = __cpu_to_be32(cap->cipher_keysize);
+}
+
+enum pohmelfs_lock_type {
+ POHMELFS_LOCK_GRAB = (1<<15),
+
+ POHMELFS_READ_LOCK = 0,
+ POHMELFS_WRITE_LOCK,
+};
+
+struct netfs_lock
+{
+ __u64 start;
+ __u64 ino;
+ __u32 size;
+ __u32 type;
+};
+
+static inline void netfs_convert_lock(struct netfs_lock *lock)
+{
+ lock->start = __cpu_to_be64(lock->start);
+ lock->ino = __cpu_to_be64(lock->ino);
+ lock->size = __cpu_to_be32(lock->size);
+ lock->type = __cpu_to_be32(lock->type);
+}
+
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+#include <linux/completion.h>
+#include <linux/rbtree.h>
+#include <linux/net.h>
+#include <linux/poll.h>
+
+/*
+ * Private POHMELFS cache of objects in directory.
+ */
+struct pohmelfs_name
+{
+ struct rb_node hash_node;
+
+ struct list_head sync_create_entry;
+
+ u64 ino;
+
+ u32 hash;
+ u32 mode;
+ u32 len;
+
+ char *data;
+};
+
+/*
+ * POHMELFS inode. Main object.
+ */
+struct pohmelfs_inode
+{
+ struct list_head inode_entry; /* Entry in superblock list.
+ * Objects which are not bound to dentry require to be dropped
+ * in ->put_super()
+ */
+ struct rb_root hash_root; /* The same, but indexed by name hash and len */
+ struct mutex offset_lock; /* Protect both above trees */
+
+ struct list_head sync_create_list; /* List of created but not yet synced to the server children */
+
+ unsigned int drop_count;
+
+ int lock_type; /* How this inode is locked: read or write */
+
+ int error; /* Transaction error for given inode */
+
+ long state; /* State machine above */
+
+ u64 ino; /* Inode number */
+ u64 total_len; /* Total length of all children names, used to create offsets */
+
+ struct inode vfs_inode;
+};
+
+struct netfs_trans;
+typedef int (* netfs_trans_complete_t)(struct page **pages, unsigned int page_num,
+ void *private, int err);
+
+struct netfs_state;
+struct pohmelfs_sb;
+
+struct netfs_trans
+{
+ /*
+ * Transaction header and attached contiguous data live here.
+ */
+ struct iovec iovec;
+
+ /*
+ * Pages attached to transaction.
+ */
+ struct page **pages;
+
+ /*
+ * List and protecting lock for transaction destination
+ * network states.
+ */
+ spinlock_t dst_lock;
+ struct list_head dst_list;
+
+ /*
+ * Number of users for given transaction.
+ * For example each network state attached to transaction
+ * via dst_list increases it.
+ */
+ atomic_t refcnt;
+
+ /*
+ * Number of pages attached to given transaction.
+ * Some slots in above page array can be NULL, since
+ * for example page can be under writeback already,
+ * so we skip it in this transaction.
+ */
+ unsigned int page_num;
+
+ /*
+ * Transaction flags: single dst or broadcast and so on.
+ */
+ unsigned int flags;
+
+ /*
+ * Size of the data, which can be placed into
+ * iovec.iov_base area.
+ */
+ unsigned int total_size;
+
+ /*
+ * Number of pages to be sent to remote server.
+ * Usually equal to above page_num, but in case of partial
+ * writeback it can accumulate only pages already completed
+ * previous writeback.
+ */
+ unsigned int attached_pages;
+
+ /*
+ * Attached number of bytes in all above pages.
+ */
+ unsigned int attached_size;
+
+ /*
+ * Unique transacton generation number.
+ * Used as identity in the network state tree of transactions.
+ */
+ unsigned int gen;
+
+ /*
+ * Transaction completion status.
+ */
+ int result;
+
+ /*
+ * Superblock this transaction belongs to
+ */
+ struct pohmelfs_sb *psb;
+
+ /*
+ * Crypto engine, which processed this transaction.
+ * Can be not NULL only if crypto engine holds encrypted pages.
+ */
+ struct pohmelfs_crypto_engine *eng;
+
+ /* Private data */
+ void *private;
+
+ /* Completion callback, invoked just before transaction is destroyed */
+ netfs_trans_complete_t complete;
+};
+
+static inline int netfs_trans_cur_len(struct netfs_trans *t)
+{
+ return (signed)(t->total_size - t->iovec.iov_len);
+}
+
+static inline void *netfs_trans_current(struct netfs_trans *t)
+{
+ return t->iovec.iov_base + t->iovec.iov_len;
+}
+
+struct netfs_trans *netfs_trans_alloc(struct pohmelfs_sb *psb, unsigned int size,
+ unsigned int flags, unsigned int nr);
+void netfs_trans_free(struct netfs_trans *t);
+int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb);
+int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb);
+
+static inline void netfs_trans_reset(struct netfs_trans *t)
+{
+ t->complete = NULL;
+}
+
+struct netfs_trans_dst
+{
+ struct list_head trans_entry;
+ struct rb_node state_entry;
+
+ unsigned long send_time;
+
+ /*
+ * Times this transaction was resent to its old or new,
+ * depending on flags, destinations. When it reaches maximum
+ * allowed number, specified in superblock->trans_retries,
+ * transaction will be freed with ETIMEDOUT error.
+ */
+ unsigned int retries;
+
+ struct netfs_trans *trans;
+ struct netfs_state *state;
+};
+
+struct netfs_trans_dst *netfs_trans_search(struct netfs_state *st, unsigned int gen);
+void netfs_trans_drop_dst(struct netfs_trans_dst *dst);
+void netfs_trans_drop_dst_nostate(struct netfs_trans_dst *dst);
+void netfs_trans_drop_trans(struct netfs_trans *t, struct netfs_state *st);
+void netfs_trans_drop_last(struct netfs_trans *t, struct netfs_state *st);
+int netfs_trans_resend(struct netfs_trans *t, struct pohmelfs_sb *psb);
+int netfs_trans_remove_nolock(struct netfs_trans_dst *dst, struct netfs_state *st);
+
+int netfs_trans_init(void);
+void netfs_trans_exit(void);
+
+struct pohmelfs_crypto_engine
+{
+ u64 iv; /* Crypto IV for current operation */
+ unsigned long timeout; /* Crypto waiting timeout */
+ unsigned int size; /* Size of crypto scratchpad */
+ void *data; /* Temporal crypto scratchpad */
+ /*
+ * Crypto operations performed on objects.
+ */
+ struct crypto_hash *hash;
+ struct crypto_ablkcipher *cipher;
+
+ struct pohmelfs_crypto_thread *thread; /* Crypto thread which hosts this engine */
+
+ struct page **pages;
+ unsigned int page_num;
+};
+
+struct pohmelfs_crypto_thread
+{
+ struct list_head thread_entry;
+
+ struct task_struct *thread;
+ struct pohmelfs_sb *psb;
+
+ struct pohmelfs_crypto_engine eng;
+
+ struct netfs_trans *trans;
+
+ wait_queue_head_t wait;
+ int error;
+
+ unsigned int size;
+ struct page *page;
+};
+
+void pohmelfs_crypto_thread_make_ready(struct pohmelfs_crypto_thread *th);
+
+/*
+ * Network state, attached to one server.
+ */
+struct netfs_state
+{
+ struct mutex __state_lock; /* Can not allow to use the same socket simultaneously */
+ struct mutex __state_send_lock;
+ struct netfs_cmd cmd; /* Cached command */
+ struct netfs_inode_info info; /* Cached inode info */
+
+ void *data; /* Cached some data */
+ unsigned int size; /* Size of that data */
+
+ struct pohmelfs_sb *psb; /* Superblock */
+
+ struct task_struct *thread; /* Async receiving thread */
+
+ /* Waiting/polling machinery */
+ wait_queue_t wait;
+ wait_queue_head_t *whead;
+ wait_queue_head_t thread_wait;
+
+ struct mutex trans_lock;
+ struct rb_root trans_root;
+
+ struct pohmelfs_ctl ctl; /* Remote peer */
+
+ struct socket *socket; /* Socket object */
+ struct socket *read_socket; /* Cached pointer to socket object.
+ * Used to determine if between lock drops socket was changed.
+ * Never used to read data or any kind of access.
+ */
+ /*
+ * Crypto engines to process incoming data.
+ */
+ struct pohmelfs_crypto_engine eng;
+
+ int need_reset;
+};
+
+int netfs_state_init(struct netfs_state *st);
+void netfs_state_exit(struct netfs_state *st);
+
+static inline void netfs_state_lock_send(struct netfs_state *st)
+{
+ mutex_lock(&st->__state_send_lock);
+}
+
+static inline int netfs_state_trylock_send(struct netfs_state *st)
+{
+ return mutex_trylock(&st->__state_send_lock);
+}
+
+static inline void netfs_state_unlock_send(struct netfs_state *st)
+{
+ BUG_ON(!mutex_is_locked(&st->__state_send_lock));
+
+ mutex_unlock(&st->__state_send_lock);
+}
+
+static inline void netfs_state_lock(struct netfs_state *st)
+{
+ mutex_lock(&st->__state_lock);
+}
+
+static inline void netfs_state_unlock(struct netfs_state *st)
+{
+ BUG_ON(!mutex_is_locked(&st->__state_lock));
+
+ mutex_unlock(&st->__state_lock);
+}
+
+static inline unsigned int netfs_state_poll(struct netfs_state *st)
+{
+ unsigned int revents = POLLHUP | POLLERR;
+
+ netfs_state_lock(st);
+ if (st->socket)
+ revents = st->socket->ops->poll(NULL, st->socket, NULL);
+ netfs_state_unlock(st);
+
+ return revents;
+}
+
+struct pohmelfs_config;
+
+struct pohmelfs_sb
+{
+ struct rb_root mcache_root;
+ struct mutex mcache_lock;
+ atomic_long_t mcache_gen;
+ unsigned long mcache_timeout;
+
+ unsigned int idx;
+
+ unsigned int trans_retries;
+
+ atomic_t trans_gen;
+
+ unsigned int crypto_attached_size;
+ unsigned int crypto_align_size;
+
+ unsigned int crypto_fail_unsupported;
+
+ unsigned int crypto_thread_num;
+ struct list_head crypto_active_list, crypto_ready_list;
+ struct mutex crypto_thread_lock;
+
+ unsigned int trans_max_pages;
+ unsigned long trans_data_size;
+ unsigned long trans_timeout;
+
+ unsigned long drop_scan_timeout;
+ unsigned long trans_scan_timeout;
+
+ unsigned long wait_on_page_timeout;
+
+ struct list_head flush_list;
+ struct list_head drop_list;
+ spinlock_t ino_lock;
+ u64 ino;
+
+ /*
+ * Remote nodes POHMELFS connected to.
+ */
+ struct list_head state_list;
+ struct mutex state_lock;
+
+ /*
+ * Currently active state to request data from.
+ */
+ struct pohmelfs_config *active_state;
+
+
+ wait_queue_head_t wait;
+
+ /*
+ * Timed checks: stale transactions, inodes to be freed and so on.
+ */
+ struct delayed_work dwork;
+ struct delayed_work drop_dwork;
+
+ struct super_block *sb;
+
+ /*
+ * Algorithm strings.
+ */
+ char *hash_string;
+ char *cipher_string;
+
+ u8 *hash_key;
+ u8 *cipher_key;
+
+ /*
+ * Algorithm string lengths.
+ */
+ unsigned int hash_strlen;
+ unsigned int cipher_strlen;
+ unsigned int hash_keysize;
+ unsigned int cipher_keysize;
+
+ /*
+ * Controls whether to perfrom crypto processing or not.
+ */
+ int perform_crypto;
+
+ /*
+ * POHMELFS statistics.
+ */
+ u64 total_size;
+ u64 avail_size;
+ atomic_long_t total_inodes;
+
+ /*
+ * Xattr support, read-only and so on.
+ */
+ u64 state_flags;
+
+ /*
+ * Temporary storage to detect changes in the wait queue.
+ */
+ long flags;
+};
+
+static inline void netfs_trans_update(struct netfs_cmd *cmd,
+ struct netfs_trans *t, unsigned int size)
+{
+ unsigned int sz = ALIGN(size, t->psb->crypto_align_size);
+
+ t->iovec.iov_len += sizeof(struct netfs_cmd) + sz;
+ cmd->cpad = __cpu_to_be16(sz - size);
+}
+
+static inline struct pohmelfs_sb *POHMELFS_SB(struct super_block *sb)
+{
+ return sb->s_fs_info;
+}
+
+static inline struct pohmelfs_inode *POHMELFS_I(struct inode *inode)
+{
+ return container_of(inode, struct pohmelfs_inode, vfs_inode);
+}
+
+static inline u64 pohmelfs_new_ino(struct pohmelfs_sb *psb)
+{
+ u64 ino;
+
+ spin_lock(&psb->ino_lock);
+ ino = psb->ino++;
+ spin_unlock(&psb->ino_lock);
+
+ return ino;
+}
+
+static inline void pohmelfs_put_inode(struct pohmelfs_inode *pi)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+
+ spin_lock(&psb->ino_lock);
+ list_move_tail(&pi->inode_entry, &psb->drop_list);
+ pi->drop_count++;
+ spin_unlock(&psb->ino_lock);
+}
+
+struct pohmelfs_config
+{
+ struct list_head config_entry;
+
+ struct netfs_state state;
+};
+
+struct pohmelfs_config_group
+{
+ /*
+ * Entry in the global config group list.
+ */
+ struct list_head group_entry;
+
+ /*
+ * Index of the current group.
+ */
+ unsigned int idx;
+ /*
+ * Number of config_list entries in this group entry.
+ */
+ unsigned int num_entry;
+ /*
+ * Algorithm strings.
+ */
+ char *hash_string;
+ char *cipher_string;
+
+ /*
+ * Algorithm string lengths.
+ */
+ unsigned int hash_strlen;
+ unsigned int cipher_strlen;
+
+ /*
+ * Key and its size.
+ */
+ unsigned int hash_keysize;
+ unsigned int cipher_keysize;
+ u8 *hash_key;
+ u8 *cipher_key;
+
+ /*
+ * List of config entries (network state info) for given idx.
+ */
+ struct list_head config_list;
+};
+
+int __init pohmelfs_config_init(void);
+void pohmelfs_config_exit(void);
+int pohmelfs_copy_config(struct pohmelfs_sb *psb);
+int pohmelfs_copy_crypto(struct pohmelfs_sb *psb);
+int pohmelfs_config_check(struct pohmelfs_config *config, int idx);
+int pohmelfs_state_init_one(struct pohmelfs_sb *psb, struct pohmelfs_config *conf);
+
+extern const struct file_operations pohmelfs_dir_fops;
+extern const struct inode_operations pohmelfs_dir_inode_ops;
+
+int pohmelfs_state_init(struct pohmelfs_sb *psb);
+void pohmelfs_state_exit(struct pohmelfs_sb *psb);
+void pohmelfs_state_flush_transactions(struct netfs_state *st);
+
+void pohmelfs_fill_inode(struct inode *inode, struct netfs_inode_info *info);
+
+void pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *n);
+void pohmelfs_free_names(struct pohmelfs_inode *parent);
+struct pohmelfs_name *pohmelfs_search_hash(struct pohmelfs_inode *pi, u32 hash);
+
+void pohmelfs_inode_del_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode *pi);
+
+struct pohmelfs_inode *pohmelfs_create_entry_local(struct pohmelfs_sb *psb,
+ struct pohmelfs_inode *parent, struct qstr *str, u64 start, int mode);
+
+int pohmelfs_write_create_inode(struct pohmelfs_inode *pi);
+
+int pohmelfs_write_inode_create(struct inode *inode, struct netfs_trans *trans);
+int pohmelfs_remove_child(struct pohmelfs_inode *parent, struct pohmelfs_name *n);
+
+struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb,
+ struct pohmelfs_inode *parent, struct qstr *str,
+ struct netfs_inode_info *info, int link);
+
+int pohmelfs_setattr(struct dentry *dentry, struct iattr *attr);
+int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr);
+
+int pohmelfs_meta_command(struct pohmelfs_inode *pi, unsigned int cmd_op, unsigned int flags,
+ netfs_trans_complete_t complete, void *priv, u64 start);
+int pohmelfs_meta_command_data(struct pohmelfs_inode *pi, u64 id, unsigned int cmd_op, char *addon,
+ unsigned int flags, netfs_trans_complete_t complete, void *priv, u64 start);
+
+void pohmelfs_check_states(struct pohmelfs_sb *psb);
+void pohmelfs_switch_active(struct pohmelfs_sb *psb);
+
+int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len);
+int pohmelfs_path_length(struct pohmelfs_inode *pi);
+
+struct pohmelfs_crypto_completion
+{
+ struct completion complete;
+ int error;
+};
+
+int pohmelfs_trans_crypt(struct netfs_trans *t, struct pohmelfs_sb *psb);
+void pohmelfs_crypto_exit(struct pohmelfs_sb *psb);
+int pohmelfs_crypto_init(struct pohmelfs_sb *psb);
+
+int pohmelfs_crypto_engine_init(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb);
+void pohmelfs_crypto_engine_exit(struct pohmelfs_crypto_engine *e);
+
+int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 iv,
+ void *data, struct page *page, unsigned int size);
+int pohmelfs_crypto_process_input_page(struct pohmelfs_crypto_engine *e,
+ struct page *page, unsigned int size, u64 iv);
+
+static inline u64 pohmelfs_gen_iv(struct netfs_trans *t)
+{
+ u64 iv = t->gen;
+
+ iv <<= 32;
+ iv |= ((unsigned long)t) & 0xffffffff;
+
+ return iv;
+}
+
+int pohmelfs_data_lock(struct pohmelfs_inode *pi, u64 start, u32 size, int type);
+int pohmelfs_data_unlock(struct pohmelfs_inode *pi, u64 start, u32 size, int type);
+int pohmelfs_data_lock_response(struct netfs_state *st);
+
+static inline int pohmelfs_need_lock(struct pohmelfs_inode *pi, int type)
+{
+ if (test_bit(NETFS_INODE_OWNED, &pi->state)) {
+ if (type == pi->lock_type)
+ return 0;
+ if ((type == POHMELFS_READ_LOCK) && (pi->lock_type == POHMELFS_WRITE_LOCK))
+ return 0;
+ }
+
+ if (!test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state))
+ return 0;
+
+ return 1;
+}
+
+int __init pohmelfs_mcache_init(void);
+void pohmelfs_mcache_exit(void);
+
+//#define CONFIG_POHMELFS_DEBUG
+
+#ifdef CONFIG_POHMELFS_DEBUG
+#define dprintka(f, a...) printk(f, ##a)
+#define dprintk(f, a...) printk("%d: " f, task_pid_vnr(current), ##a)
+#else
+#define dprintka(f, a...) do {} while (0)
+#define dprintk(f, a...) do {} while (0)
+#endif
+
+static inline void netfs_trans_get(struct netfs_trans *t)
+{
+ atomic_inc(&t->refcnt);
+}
+
+static inline void netfs_trans_put(struct netfs_trans *t)
+{
+ if (atomic_dec_and_test(&t->refcnt)) {
+ dprintk("%s: t: %p, gen: %u, err: %d.\n",
+ __func__, t, t->gen, t->result);
+ if (t->complete)
+ t->complete(t->pages, t->page_num,
+ t->private, t->result);
+ netfs_trans_free(t);
+ }
+}
+
+struct pohmelfs_mcache
+{
+ struct rb_node mcache_entry;
+ struct completion complete;
+
+ atomic_t refcnt;
+
+ u64 gen;
+
+ void *data;
+ u64 start;
+ u32 size;
+ int err;
+
+ struct netfs_inode_info info;
+};
+
+struct pohmelfs_mcache *pohmelfs_mcache_alloc(struct pohmelfs_sb *psb, u64 start,
+ unsigned int size, void *data);
+void pohmelfs_mcache_free(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m);
+struct pohmelfs_mcache *pohmelfs_mcache_search(struct pohmelfs_sb *psb, u64 gen);
+void pohmelfs_mcache_remove_locked(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m);
+
+static inline void pohmelfs_mcache_get(struct pohmelfs_mcache *m)
+{
+ atomic_inc(&m->refcnt);
+}
+
+static inline void pohmelfs_mcache_put(struct pohmelfs_sb *psb,
+ struct pohmelfs_mcache *m)
+{
+ if (atomic_dec_and_test(&m->refcnt))
+ pohmelfs_mcache_free(psb, m);
+}
+
+int pohmelfs_ftrans_init(void);
+void pohmelfs_ftrans_exit(void);
+void pohmelfs_ftrans_update(u64 id);
+int pohmelfs_ftrans_check(u64 id);
+void pohmelfs_ftrans_clean(u64 id);
+
+#endif /* __KERNEL__*/
+
+#endif /* __NETFS_H */
diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c
new file mode 100644
index 00000000000..3bad888ced1
--- /dev/null
+++ b/drivers/staging/pohmelfs/path_entry.c
@@ -0,0 +1,114 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/ktime.h>
+#include <linux/fs_struct.h>
+#include <linux/pagemap.h>
+#include <linux/writeback.h>
+#include <linux/mount.h>
+#include <linux/mm.h>
+
+#include "netfs.h"
+
+#define UNHASHED_OBSCURE_STRING_SIZE sizeof(" (deleted)")
+
+/*
+ * Create path from root for given inode.
+ * Path is formed as set of stuctures, containing name of the object
+ * and its inode data (mode, permissions and so on).
+ */
+int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len)
+{
+ struct path path;
+ struct dentry *d;
+ char *ptr;
+ int err = 0, strlen, reduce = 0;
+
+ d = d_find_alias(&pi->vfs_inode);
+ if (!d) {
+ printk("%s: no alias, list_empty: %d.\n", __func__, list_empty(&pi->vfs_inode.i_dentry));
+ return -ENOENT;
+ }
+
+ read_lock(&current->fs->lock);
+ path.mnt = mntget(current->fs->root.mnt);
+ read_unlock(&current->fs->lock);
+
+ path.dentry = d;
+
+ if (!IS_ROOT(d) && d_unhashed(d))
+ reduce = 1;
+
+ ptr = d_path(&path, data, len);
+ if (IS_ERR(ptr)) {
+ err = PTR_ERR(ptr);
+ goto out;
+ }
+
+ if (reduce && len >= UNHASHED_OBSCURE_STRING_SIZE) {
+ char *end = data + len - UNHASHED_OBSCURE_STRING_SIZE;
+ *end = '\0';
+ }
+
+ strlen = len - (ptr - (char *)data);
+ memmove(data, ptr, strlen);
+ ptr = data;
+
+ err = strlen;
+
+ dprintk("%s: dname: '%s', len: %u, maxlen: %u, name: '%s', strlen: %d.\n",
+ __func__, d->d_name.name, d->d_name.len, len, ptr, strlen);
+
+out:
+ dput(d);
+ mntput(path.mnt);
+
+ return err;
+}
+
+int pohmelfs_path_length(struct pohmelfs_inode *pi)
+{
+ struct dentry *d, *root, *first;
+ int len = 1; /* Root slash */
+
+ first = d = d_find_alias(&pi->vfs_inode);
+ if (!d) {
+ dprintk("%s: ino: %llu, mode: %o.\n", __func__, pi->ino, pi->vfs_inode.i_mode);
+ return -ENOENT;
+ }
+
+ read_lock(&current->fs->lock);
+ root = dget(current->fs->root.dentry);
+ read_unlock(&current->fs->lock);
+
+ spin_lock(&dcache_lock);
+
+ if (!IS_ROOT(d) && d_unhashed(d))
+ len += UNHASHED_OBSCURE_STRING_SIZE; /* Obscure " (deleted)" string */
+
+ while (d && d != root && !IS_ROOT(d)) {
+ len += d->d_name.len + 1; /* Plus slash */
+ d = d->d_parent;
+ }
+ spin_unlock(&dcache_lock);
+
+ dput(root);
+ dput(first);
+
+ return len + 1; /* Including zero-byte */
+}
diff --git a/drivers/staging/pohmelfs/trans.c b/drivers/staging/pohmelfs/trans.c
new file mode 100644
index 00000000000..bcb59425a21
--- /dev/null
+++ b/drivers/staging/pohmelfs/trans.c
@@ -0,0 +1,715 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/fs.h>
+#include <linux/jhash.h>
+#include <linux/hash.h>
+#include <linux/ktime.h>
+#include <linux/mempool.h>
+#include <linux/mm.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/parser.h>
+#include <linux/poll.h>
+#include <linux/swap.h>
+#include <linux/slab.h>
+#include <linux/statfs.h>
+#include <linux/writeback.h>
+
+#include "netfs.h"
+
+static struct kmem_cache *netfs_trans_dst;
+static mempool_t *netfs_trans_dst_pool;
+
+static void netfs_trans_init_static(struct netfs_trans *t, int num, int size)
+{
+ t->page_num = num;
+ t->total_size = size;
+ atomic_set(&t->refcnt, 1);
+
+ spin_lock_init(&t->dst_lock);
+ INIT_LIST_HEAD(&t->dst_list);
+}
+
+static int netfs_trans_send_pages(struct netfs_trans *t, struct netfs_state *st)
+{
+ int err = 0;
+ unsigned int i, attached_pages = t->attached_pages, ci;
+ struct msghdr msg;
+ struct page **pages = (t->eng)?t->eng->pages:t->pages;
+ struct page *p;
+ unsigned int size;
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = MSG_WAITALL | MSG_MORE;
+
+ ci = 0;
+ for (i=0; i<t->page_num; ++i) {
+ struct page *page = pages[ci];
+ struct netfs_cmd cmd;
+ struct iovec io;
+
+ p = t->pages[i];
+
+ if (!p)
+ continue;
+
+ size = page_private(p);
+
+ io.iov_base = &cmd;
+ io.iov_len = sizeof(struct netfs_cmd);
+
+ cmd.cmd = NETFS_WRITE_PAGE;
+ cmd.ext = 0;
+ cmd.id = 0;
+ cmd.size = size;
+ cmd.start = p->index;
+ cmd.start <<= PAGE_CACHE_SHIFT;
+ cmd.csize = 0;
+ cmd.cpad = 0;
+ cmd.iv = pohmelfs_gen_iv(t);
+
+ netfs_convert_cmd(&cmd);
+
+ msg.msg_iov = &io;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = MSG_WAITALL | MSG_MORE;
+
+ err = kernel_sendmsg(st->socket, &msg, (struct kvec *)msg.msg_iov, 1, sizeof(struct netfs_cmd));
+ if (err <= 0) {
+ printk("%s: %d/%d failed to send transaction header: t: %p, gen: %u, err: %d.\n",
+ __func__, i, t->page_num, t, t->gen, err);
+ if (err == 0)
+ err = -ECONNRESET;
+ goto err_out;
+ }
+
+ msg.msg_flags = MSG_WAITALL|(attached_pages == 1)?0:MSG_MORE;
+
+ err = kernel_sendpage(st->socket, page, 0, size, msg.msg_flags);
+ if (err <= 0) {
+ printk("%s: %d/%d failed to send transaction page: t: %p, gen: %u, size: %u, err: %d.\n",
+ __func__, i, t->page_num, t, t->gen, size, err);
+ if (err == 0)
+ err = -ECONNRESET;
+ goto err_out;
+ }
+
+ dprintk("%s: %d/%d sent t: %p, gen: %u, page: %p/%p, size: %u.\n",
+ __func__, i, t->page_num, t, t->gen, page, p, size);
+
+ err = 0;
+ attached_pages--;
+ if (!attached_pages)
+ break;
+ ci++;
+
+ continue;
+
+err_out:
+ printk("%s: t: %p, gen: %u, err: %d.\n", __func__, t, t->gen, err);
+ netfs_state_exit(st);
+ break;
+ }
+
+ return err;
+}
+
+int netfs_trans_send(struct netfs_trans *t, struct netfs_state *st)
+{
+ int err;
+ struct msghdr msg;
+
+ BUG_ON(!t->iovec.iov_len);
+ BUG_ON(t->iovec.iov_len > 1024*1024*1024);
+
+ netfs_state_lock_send(st);
+ if (!st->socket) {
+ err = netfs_state_init(st);
+ if (err)
+ goto err_out_unlock_return;
+ }
+
+ msg.msg_iov = &t->iovec;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = MSG_WAITALL;
+
+ if (t->attached_pages)
+ msg.msg_flags |= MSG_MORE;
+
+ err = kernel_sendmsg(st->socket, &msg, (struct kvec *)msg.msg_iov, 1, t->iovec.iov_len);
+ if (err <= 0) {
+ printk("%s: failed to send contig transaction: t: %p, gen: %u, size: %zu, err: %d.\n",
+ __func__, t, t->gen, t->iovec.iov_len, err);
+ if (err == 0)
+ err = -ECONNRESET;
+ goto err_out_unlock_return;
+ }
+
+ dprintk("%s: sent %s transaction: t: %p, gen: %u, size: %zu, page_num: %u.\n",
+ __func__, (t->page_num)?"partial":"full",
+ t, t->gen, t->iovec.iov_len, t->page_num);
+
+ err = 0;
+ if (t->attached_pages)
+ err = netfs_trans_send_pages(t, st);
+
+err_out_unlock_return:
+
+ if (st->need_reset) {
+ netfs_state_exit(st);
+ }
+ netfs_state_unlock_send(st);
+
+ dprintk("%s: t: %p, gen: %u, err: %d.\n",
+ __func__, t, t->gen, err);
+
+ t->result = err;
+ return err;
+}
+
+static inline int netfs_trans_cmp(unsigned int gen, unsigned int new)
+{
+ if (gen < new)
+ return 1;
+ if (gen > new)
+ return -1;
+ return 0;
+}
+
+struct netfs_trans_dst *netfs_trans_search(struct netfs_state *st, unsigned int gen)
+{
+ struct rb_root *root = &st->trans_root;
+ struct rb_node *n = root->rb_node;
+ struct netfs_trans_dst *tmp, *ret = NULL;
+ struct netfs_trans *t;
+ int cmp;
+
+ while (n) {
+ tmp = rb_entry(n, struct netfs_trans_dst, state_entry);
+ t = tmp->trans;
+
+ cmp = netfs_trans_cmp(t->gen, gen);
+ if (cmp < 0)
+ n = n->rb_left;
+ else if (cmp > 0)
+ n = n->rb_right;
+ else {
+ ret = tmp;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int netfs_trans_insert(struct netfs_trans_dst *ndst, struct netfs_state *st)
+{
+ struct rb_root *root = &st->trans_root;
+ struct rb_node **n = &root->rb_node, *parent = NULL;
+ struct netfs_trans_dst *ret = NULL, *tmp;
+ struct netfs_trans *t = NULL, *new = ndst->trans;
+ int cmp;
+
+ while (*n) {
+ parent = *n;
+
+ tmp = rb_entry(parent, struct netfs_trans_dst, state_entry);
+ t = tmp->trans;
+
+ cmp = netfs_trans_cmp(t->gen, new->gen);
+ if (cmp < 0)
+ n = &parent->rb_left;
+ else if (cmp > 0)
+ n = &parent->rb_right;
+ else {
+ ret = tmp;
+ break;
+ }
+ }
+
+ if (ret) {
+ printk("%s: exist: old: gen: %u, flags: %x, send_time: %lu, "
+ "new: gen: %u, flags: %x, send_time: %lu.\n",
+ __func__, t->gen, t->flags, ret->send_time,
+ new->gen, new->flags, ndst->send_time);
+ return -EEXIST;
+ }
+
+ rb_link_node(&ndst->state_entry, parent, n);
+ rb_insert_color(&ndst->state_entry, root);
+ ndst->send_time = jiffies;
+
+ return 0;
+}
+
+int netfs_trans_remove_nolock(struct netfs_trans_dst *dst, struct netfs_state *st)
+{
+ if (dst && dst->state_entry.rb_parent_color) {
+ rb_erase(&dst->state_entry, &st->trans_root);
+ dst->state_entry.rb_parent_color = 0;
+ return 1;
+ }
+ return 0;
+}
+
+static int netfs_trans_remove_state(struct netfs_trans_dst *dst)
+{
+ int ret;
+ struct netfs_state *st = dst->state;
+
+ mutex_lock(&st->trans_lock);
+ ret = netfs_trans_remove_nolock(dst, st);
+ mutex_unlock(&st->trans_lock);
+
+ return ret;
+}
+
+/*
+ * Create new destination for given transaction associated with given network state.
+ * Transaction's reference counter is bumped and will be dropped when either
+ * reply is received or when async timeout detection task will fail resending
+ * and drop transaction.
+ */
+static int netfs_trans_push_dst(struct netfs_trans *t, struct netfs_state *st)
+{
+ struct netfs_trans_dst *dst;
+ int err;
+
+ dst = mempool_alloc(netfs_trans_dst_pool, GFP_KERNEL);
+ if (!dst)
+ return -ENOMEM;
+
+ dst->retries = 0;
+ dst->send_time = 0;
+ dst->state = st;
+ dst->trans = t;
+ netfs_trans_get(t);
+
+ mutex_lock(&st->trans_lock);
+ err = netfs_trans_insert(dst, st);
+ mutex_unlock(&st->trans_lock);
+
+ if (err)
+ goto err_out_free;
+
+ spin_lock(&t->dst_lock);
+ list_add_tail(&dst->trans_entry, &t->dst_list);
+ spin_unlock(&t->dst_lock);
+
+ return 0;
+
+err_out_free:
+ t->result = err;
+ netfs_trans_put(t);
+ mempool_free(dst, netfs_trans_dst_pool);
+ return err;
+}
+
+static void netfs_trans_free_dst(struct netfs_trans_dst *dst)
+{
+ netfs_trans_put(dst->trans);
+ mempool_free(dst, netfs_trans_dst_pool);
+}
+
+static void netfs_trans_remove_dst(struct netfs_trans_dst *dst)
+{
+ if (netfs_trans_remove_state(dst))
+ netfs_trans_free_dst(dst);
+}
+
+/*
+ * Drop destination transaction entry when we know it.
+ */
+void netfs_trans_drop_dst(struct netfs_trans_dst *dst)
+{
+ struct netfs_trans *t = dst->trans;
+
+ spin_lock(&t->dst_lock);
+ list_del_init(&dst->trans_entry);
+ spin_unlock(&t->dst_lock);
+
+ netfs_trans_remove_dst(dst);
+}
+
+/*
+ * Drop destination transaction entry when we know it and when we
+ * already removed dst from state tree.
+ */
+void netfs_trans_drop_dst_nostate(struct netfs_trans_dst *dst)
+{
+ struct netfs_trans *t = dst->trans;
+
+ spin_lock(&t->dst_lock);
+ list_del_init(&dst->trans_entry);
+ spin_unlock(&t->dst_lock);
+
+ netfs_trans_free_dst(dst);
+}
+
+/*
+ * This drops destination transaction entry from appropriate network state
+ * tree and drops related reference counter. It is possible that transaction
+ * will be freed here if its reference counter hits zero.
+ * Destination transaction entry will be freed.
+ */
+void netfs_trans_drop_trans(struct netfs_trans *t, struct netfs_state *st)
+{
+ struct netfs_trans_dst *dst, *tmp, *ret = NULL;
+
+ spin_lock(&t->dst_lock);
+ list_for_each_entry_safe(dst, tmp, &t->dst_list, trans_entry) {
+ if (dst->state == st) {
+ ret = dst;
+ list_del(&dst->trans_entry);
+ break;
+ }
+ }
+ spin_unlock(&t->dst_lock);
+
+ if (ret)
+ netfs_trans_remove_dst(ret);
+}
+
+/*
+ * This drops destination transaction entry from appropriate network state
+ * tree and drops related reference counter. It is possible that transaction
+ * will be freed here if its reference counter hits zero.
+ * Destination transaction entry will be freed.
+ */
+void netfs_trans_drop_last(struct netfs_trans *t, struct netfs_state *st)
+{
+ struct netfs_trans_dst *dst, *tmp, *ret;
+
+ spin_lock(&t->dst_lock);
+ ret = list_entry(t->dst_list.prev, struct netfs_trans_dst, trans_entry);
+ if (ret->state != st) {
+ ret = NULL;
+ list_for_each_entry_safe(dst, tmp, &t->dst_list, trans_entry) {
+ if (dst->state == st) {
+ ret = dst;
+ list_del_init(&dst->trans_entry);
+ break;
+ }
+ }
+ } else {
+ list_del(&ret->trans_entry);
+ }
+ spin_unlock(&t->dst_lock);
+
+ if (ret)
+ netfs_trans_remove_dst(ret);
+}
+
+static int netfs_trans_push(struct netfs_trans *t, struct netfs_state *st)
+{
+ int err;
+
+ err = netfs_trans_push_dst(t, st);
+ if (err)
+ return err;
+
+ err = netfs_trans_send(t, st);
+ if (err)
+ goto err_out_free;
+
+ if (t->flags & NETFS_TRANS_SINGLE_DST)
+ pohmelfs_switch_active(st->psb);
+
+ return 0;
+
+err_out_free:
+ t->result = err;
+ netfs_trans_drop_last(t, st);
+
+ return err;
+}
+
+int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config *c;
+ int err = -ENODEV;
+ struct netfs_state *st;
+#if 0
+ dprintk("%s: t: %p, gen: %u, size: %u, page_num: %u, active: %p.\n",
+ __func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state);
+#endif
+ mutex_lock(&psb->state_lock);
+
+ if ((t->flags & NETFS_TRANS_SINGLE_DST) && psb->active_state) {
+ st = &psb->active_state->state;
+
+ err = -EPIPE;
+ if (netfs_state_poll(st) & POLLOUT) {
+ err = netfs_trans_push_dst(t, st);
+ if (!err) {
+ err = netfs_trans_send(t, st);
+ if (err) {
+ netfs_trans_drop_last(t, st);
+ } else {
+ pohmelfs_switch_active(psb);
+ goto out;
+ }
+ }
+ }
+ pohmelfs_switch_active(psb);
+ }
+
+ list_for_each_entry(c, &psb->state_list, config_entry) {
+ st = &c->state;
+
+ err = netfs_trans_push(t, st);
+ if (!err && (t->flags & NETFS_TRANS_SINGLE_DST))
+ break;
+ }
+out:
+ mutex_unlock(&psb->state_lock);
+#if 0
+ dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n",
+ __func__, t, t->gen, t->iovec.iov_len, t->page_num, err);
+#endif
+ if (err)
+ t->result = err;
+ return err;
+}
+
+int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb)
+{
+ int err;
+ struct netfs_cmd *cmd = t->iovec.iov_base;
+
+ t->gen = atomic_inc_return(&psb->trans_gen);
+
+ pohmelfs_ftrans_clean(t->gen);
+
+ cmd->size = t->iovec.iov_len - sizeof(struct netfs_cmd) +
+ t->attached_size + t->attached_pages * sizeof(struct netfs_cmd);
+ cmd->cmd = NETFS_TRANS;
+ cmd->start = t->gen;
+ cmd->id = 0;
+
+ if (psb->perform_crypto) {
+ cmd->ext = psb->crypto_attached_size;
+ cmd->csize = psb->crypto_attached_size;
+ }
+
+ dprintk("%s: t: %u, size: %u, iov_len: %zu, attached_size: %u, attached_pages: %u.\n",
+ __func__, t->gen, cmd->size, t->iovec.iov_len, t->attached_size, t->attached_pages);
+ err = pohmelfs_trans_crypt(t, psb);
+ if (err) {
+ t->result = err;
+ netfs_convert_cmd(cmd);
+ dprintk("%s: trans: %llu, crypto_attached_size: %u, attached_size: %u, attached_pages: %d, trans_size: %u, err: %d.\n",
+ __func__, cmd->start, psb->crypto_attached_size, t->attached_size, t->attached_pages, cmd->size, err);
+ }
+ netfs_trans_put(t);
+ return err;
+}
+
+/*
+ * Resend transaction to remote server(s).
+ * If new servers were added into superblock, we can try to send data
+ * to them too.
+ *
+ * It is called under superblock's state_lock, so we can safely
+ * dereference psb->state_list. Also, transaction's reference counter is
+ * bumped, so it can not go away under us, thus we can safely access all
+ * its members. State is locked.
+ *
+ * This function returns 0 if transaction was successfully sent to at
+ * least one destination target.
+ */
+int netfs_trans_resend(struct netfs_trans *t, struct pohmelfs_sb *psb)
+{
+ struct netfs_trans_dst *dst;
+ struct netfs_state *st;
+ struct pohmelfs_config *c;
+ int err, exist, error = -ENODEV;
+
+ list_for_each_entry(c, &psb->state_list, config_entry) {
+ st = &c->state;
+
+ exist = 0;
+ spin_lock(&t->dst_lock);
+ list_for_each_entry(dst, &t->dst_list, trans_entry) {
+ if (st == dst->state) {
+ exist = 1;
+ break;
+ }
+ }
+ spin_unlock(&t->dst_lock);
+
+ if (exist) {
+ if (!(t->flags & NETFS_TRANS_SINGLE_DST) ||
+ (c->config_entry.next == &psb->state_list)) {
+ dprintk("%s: resending st: %p, t: %p, gen: %u.\n",
+ __func__, st, t, t->gen);
+ err = netfs_trans_send(t, st);
+ if (!err)
+ error = 0;
+ }
+ continue;
+ }
+
+ dprintk("%s: pushing/resending st: %p, t: %p, gen: %u.\n",
+ __func__, st, t, t->gen);
+ err = netfs_trans_push(t, st);
+ if (err)
+ continue;
+ error = 0;
+ if (t->flags & NETFS_TRANS_SINGLE_DST)
+ break;
+ }
+
+ t->result = error;
+ return error;
+}
+
+void *netfs_trans_add(struct netfs_trans *t, unsigned int size)
+{
+ struct iovec *io = &t->iovec;
+ void *ptr;
+
+ if (size > t->total_size) {
+ ptr = ERR_PTR(-EINVAL);
+ goto out;
+ }
+
+ if (io->iov_len + size > t->total_size) {
+ dprintk("%s: too big size t: %p, gen: %u, iov_len: %zu, size: %u, total: %u.\n",
+ __func__, t, t->gen, io->iov_len, size, t->total_size);
+ ptr = ERR_PTR(-E2BIG);
+ goto out;
+ }
+
+ ptr = io->iov_base + io->iov_len;
+ io->iov_len += size;
+
+out:
+ dprintk("%s: t: %p, gen: %u, size: %u, total: %zu.\n",
+ __func__, t, t->gen, size, io->iov_len);
+ return ptr;
+}
+
+void netfs_trans_free(struct netfs_trans *t)
+{
+ if (t->eng)
+ pohmelfs_crypto_thread_make_ready(t->eng->thread);
+ kfree(t);
+}
+
+struct netfs_trans *netfs_trans_alloc(struct pohmelfs_sb *psb, unsigned int size,
+ unsigned int flags, unsigned int nr)
+{
+ struct netfs_trans *t;
+ unsigned int num, cont, pad, size_no_trans;
+ unsigned int crypto_added = 0;
+ struct netfs_cmd *cmd;
+
+ if (psb->perform_crypto)
+ crypto_added = psb->crypto_attached_size;
+
+ /*
+ * |sizeof(struct netfs_trans)|
+ * |sizeof(struct netfs_cmd)| - transaction header
+ * |size| - buffer with requested size
+ * |padding| - crypto padding, zero bytes
+ * |nr * sizeof(struct page *)| - array of page pointers
+ *
+ * Overall size should be less than PAGE_SIZE for guaranteed allocation.
+ */
+
+ cont = size;
+ size = ALIGN(size, psb->crypto_align_size);
+ pad = size - cont;
+
+ size_no_trans = size + sizeof(struct netfs_cmd) * 2 + crypto_added;
+
+ cont = sizeof(struct netfs_trans) + size_no_trans;
+
+ num = (PAGE_SIZE - cont)/sizeof(struct page *);
+
+ if (nr > num)
+ nr = num;
+
+ t = kzalloc(cont + nr*sizeof(struct page *), GFP_NOIO);
+ if (!t)
+ goto err_out_exit;
+
+ t->iovec.iov_base = (void *)(t + 1);
+ t->pages = (struct page **)(t->iovec.iov_base + size_no_trans);
+
+ /*
+ * Reserving space for transaction header.
+ */
+ t->iovec.iov_len = sizeof(struct netfs_cmd) + crypto_added;
+
+ netfs_trans_init_static(t, nr, size_no_trans);
+
+ t->flags = flags;
+ t->psb = psb;
+
+ cmd = (struct netfs_cmd *)t->iovec.iov_base;
+
+ cmd->size = size;
+ cmd->cpad = pad;
+ cmd->csize = crypto_added;
+
+ dprintk("%s: t: %p, gen: %u, size: %u, padding: %u, align_size: %u, flags: %x, "
+ "page_num: %u, base: %p, pages: %p.\n",
+ __func__, t, t->gen, size, pad, psb->crypto_align_size, flags, nr,
+ t->iovec.iov_base, t->pages);
+
+ return t;
+
+err_out_exit:
+ return NULL;
+}
+
+int netfs_trans_init(void)
+{
+ int err = -ENOMEM;
+
+ netfs_trans_dst = kmem_cache_create("netfs_trans_dst", sizeof(struct netfs_trans_dst),
+ 0, 0, NULL);
+ if (!netfs_trans_dst)
+ goto err_out_exit;
+
+ netfs_trans_dst_pool = mempool_create_slab_pool(256, netfs_trans_dst);
+ if (!netfs_trans_dst_pool)
+ goto err_out_free;
+
+ return 0;
+
+err_out_free:
+ kmem_cache_destroy(netfs_trans_dst);
+err_out_exit:
+ return err;
+}
+
+void netfs_trans_exit(void)
+{
+ mempool_destroy(netfs_trans_dst_pool);
+ kmem_cache_destroy(netfs_trans_dst);
+}
diff --git a/drivers/staging/rspiusb/rspiusb.c b/drivers/staging/rspiusb/rspiusb.c
index ca281d6cbd7..ecaffb50311 100644
--- a/drivers/staging/rspiusb/rspiusb.c
+++ b/drivers/staging/rspiusb/rspiusb.c
@@ -781,9 +781,8 @@ static int piusb_probe(struct usb_interface *interface,
dbg("Endpoint[%d]->MaxPacketSize = %d\n", i,
endpoint->wMaxPacketSize);
}
- if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
- USB_ENDPOINT_XFER_BULK) {
- if (endpoint->bEndpointAddress & USB_DIR_IN)
+ if (usb_endpoint_xfer_bulk(endpoint)) {
+ if (usb_endpoint_dir_in(endpoint))
pdx->hEP[i] =
usb_rcvbulkpipe(pdx->udev,
endpoint->bEndpointAddress);
diff --git a/drivers/staging/rt2860/2860_main_dev.c b/drivers/staging/rt2860/2860_main_dev.c
index 08ca81f43cc..ff7f8338073 100644
--- a/drivers/staging/rt2860/2860_main_dev.c
+++ b/drivers/staging/rt2860/2860_main_dev.c
@@ -90,12 +90,10 @@ void init_thread_task(PRTMP_ADAPTER pAd);
static void __exit rt2860_cleanup_module(void);
static int __init rt2860_init_module(void);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#ifdef CONFIG_PM
static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
static int rt2860_resume(struct pci_dev *pci_dev);
#endif // CONFIG_PM //
-#endif
//
@@ -128,22 +126,15 @@ static struct pci_driver rt2860_driver =
name: "rt2860",
id_table: rt2860_pci_tbl,
probe: rt2860_init_one,
-#if LINUX_VERSION_CODE >= 0x20412
remove: __devexit_p(rt2860_remove_one),
-#else
- remove: __devexit(rt2860_remove_one),
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#ifdef CONFIG_PM
suspend: rt2860_suspend,
resume: rt2860_resume,
#endif
-#endif
};
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#ifdef CONFIG_PM
VOID RT2860RejectPendingPackets(
@@ -284,16 +275,11 @@ static int rt2860_resume(
return 0;
}
#endif // CONFIG_PM //
-#endif
static INT __init rt2860_init_module(VOID)
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
return pci_register_driver(&rt2860_driver);
-#else
- return pci_module_init(&rt2860_driver);
-#endif
}
@@ -374,11 +360,7 @@ static VOID __devexit rt2860_remove_one(
}
// Free pre-allocated net_device memory
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
free_netdev(net_dev);
-#else
- kfree(net_dev);
-#endif
}
//
@@ -758,16 +740,13 @@ static void ac0_dma_done_tasklet(unsigned long data)
int print_int_count;
IRQ_HANDLE_TYPE
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
rt2860_interrupt(int irq, void *dev_instance)
-#else
-rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
-#endif
{
struct net_device *net_dev = (struct net_device *) dev_instance;
PRTMP_ADAPTER pAd = net_dev->ml_priv;
INT_SOURCE_CSR_STRUC IntSource;
POS_COOKIE pObj;
+ BOOLEAN bOldValue;
pObj = (POS_COOKIE) pAd->OS_Cookie;
@@ -800,20 +779,19 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
// RT2661 => when ASIC is sleeping, MAC register cannot be read and written.
// RT2860 => when ASIC is sleeping, MAC register can be read and written.
+ bOldValue = pAd->bPCIclkOff;
+ pAd->bPCIclkOff = FALSE;
{
RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear
}
+ pAd->bPCIclkOff = bOldValue;
// Do nothing if Reset in progress
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- return IRQ_HANDLED;
-#else
- return;
-#endif
+ return IRQ_HANDLED;
}
//
@@ -822,8 +800,6 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
// The priority can be adjust by altering processing if statement
//
- pAd->bPCIclkOff = FALSE;
-
// If required spinlock, each interrupt service routine has to acquire
// and release itself.
//
@@ -832,11 +808,8 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
if (IntSource.word == 0xffffffff)
{
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- return IRQ_HANDLED;
-#else
- return;
-#endif
+ printk("snowpin - IntSource.word == 0xffffffff\n");
+ return IRQ_HANDLED;
}
if (IntSource.word & TxCoherent)
@@ -970,10 +943,7 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
}
#endif // CONFIG_STA_SUPPORT //
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
return IRQ_HANDLED;
-#endif
-
}
/*
@@ -1026,11 +996,7 @@ BOOLEAN RT28XXNetDevInit(
ULONG csr_addr;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- print_name = pci_dev ? pci_name(pci_dev) : "rt2860";
-#else
- print_name = pci_dev ? pci_dev->slot_name : "rt2860";
-#endif // LINUX_VERSION_CODE //
+ print_name = pci_dev ? pci_name(pci_dev) : "rt2860";
net_dev->base_addr = 0;
net_dev->irq = 0;
diff --git a/drivers/staging/rt2860/Makefile b/drivers/staging/rt2860/Makefile
index 6162212b588..b9563647846 100644
--- a/drivers/staging/rt2860/Makefile
+++ b/drivers/staging/rt2860/Makefile
@@ -2,7 +2,6 @@ obj-$(CONFIG_RT2860) += rt2860sta.o
# TODO: all of these should be removed
EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
-EXTRA_CFLAGS += -DRT2860
EXTRA_CFLAGS += -DCONFIG_STA_SUPPORT
EXTRA_CFLAGS += -DDBG
EXTRA_CFLAGS += -DDOT11_N_SUPPORT
diff --git a/drivers/staging/rt2860/TODO b/drivers/staging/rt2860/TODO
index 2f70b0faca3..6158dc2a4b6 100644
--- a/drivers/staging/rt2860/TODO
+++ b/drivers/staging/rt2860/TODO
@@ -1,6 +1,6 @@
I'm hesitant to add a TODO file here, as the wireless developers would
really have people help them out on the "clean" rt2860 driver that can
-be found at the rt2860.sf.net site.
+be found at the http://rt2x00.serialmonkey.com/ site.
But, if you wish to clean up this driver instead, here's a short list of
things that need to be done to get it into a more mergable shape:
@@ -8,7 +8,7 @@ things that need to be done to get it into a more mergable shape:
TODO:
- checkpatch.pl clean
- sparse clean
- - port to in-kernel 80211 stack
+ - port to in-kernel 80211 stack and common rt2x00 infrastructure
- remove reading from /etc/ config files
- review by the wireless developer community
diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c
index b67b9eba722..b3f88f52af7 100644
--- a/drivers/staging/rt2860/common/cmm_data.c
+++ b/drivers/staging/rt2860/common/cmm_data.c
@@ -105,9 +105,7 @@ NDIS_STATUS MiniportMMRequest(
PNDIS_PACKET pPacket;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
ULONG FreeNum;
-#ifdef RT2860
unsigned long IrqFlags = 0;
-#endif // RT2860 //
UCHAR IrqState;
UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
@@ -118,10 +116,9 @@ NDIS_STATUS MiniportMMRequest(
// 2860C use Tx Ring
IrqState = pAd->irq_disabled;
-#ifdef RT2860
+
if ((pAd->MACVersion == 0x28600100) && (!IrqState))
RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-#endif // RT2860 //
do
{
@@ -175,17 +172,14 @@ NDIS_STATUS MiniportMMRequest(
} while (FALSE);
-#ifdef RT2860
// 2860C use Tx Ring
if ((pAd->MACVersion == 0x28600100) && (!IrqState))
RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-#endif // RT2860 //
return Status;
}
-#ifdef RT2860
NDIS_STATUS MiniportMMRequestUnlock(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
@@ -253,7 +247,6 @@ NDIS_STATUS MiniportMMRequestUnlock(
return Status;
}
-#endif // RT2860 //
/*
@@ -290,17 +283,14 @@ NDIS_STATUS MlmeHardTransmit(
return NDIS_STATUS_FAILURE;
}
-#ifdef RT2860
if ( pAd->MACVersion == 0x28600100 )
return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
else
-#endif // RT2860 //
return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
}
-#ifdef RT2860
NDIS_STATUS MlmeHardTransmitTxRing(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
@@ -366,7 +356,7 @@ NDIS_STATUS MlmeHardTransmitTxRing(
{
// outgoing frame always wakeup PHY to prevent frame lost
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
- AsicForceWakeup(pAd, TRUE);
+ AsicForceWakeup(pAd, FROM_TX);
}
#endif // CONFIG_STA_SUPPORT //
pFirstTxWI =(PTXWI_STRUC)pSrcBufVA;
@@ -509,7 +499,6 @@ NDIS_STATUS MlmeHardTransmitTxRing(
return NDIS_STATUS_SUCCESS;
}
-#endif // RT2860 //
NDIS_STATUS MlmeHardTransmitMgmtRing(
@@ -541,7 +530,7 @@ NDIS_STATUS MlmeHardTransmitMgmtRing(
{
// outgoing frame always wakeup PHY to prevent frame lost
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
- AsicForceWakeup(pAd, TRUE);
+ AsicForceWakeup(pAd, FROM_TX);
}
#endif // CONFIG_STA_SUPPORT //
@@ -1076,7 +1065,6 @@ VOID RTMPDeQueuePacket(
break;
}
-#ifdef RT2860
FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
#ifdef DBG_DIAGNOSE
@@ -1101,7 +1089,6 @@ VOID RTMPDeQueuePacket(
RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
}
-#endif // RT2860 //
// probe the Queue Head
pQueue = &pAd->TxSwQueue[QueIdx];
@@ -1180,12 +1167,10 @@ VOID RTMPDeQueuePacket(
Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
#endif // CONFIG_STA_SUPPORT //
-#ifdef RT2860
DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
// static rate also need NICUpdateFifoStaCounters() function.
//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
NICUpdateFifoStaCounters(pAd);
-#endif // RT2860 //
}
RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
@@ -1764,7 +1749,6 @@ PQUEUE_HEADER RTMPCheckTxSwQueue(
}
-#ifdef RT2860
BOOLEAN RTMPFreeTXDUponTxDmaDone(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx)
@@ -2309,7 +2293,6 @@ VOID DBGPRINT_RX_RING(
DBGPRINT_RAW(RT_DEBUG_TRACE,(" RxSwReadIdx [%d]=", AC0freeIdx));
DBGPRINT_RAW(RT_DEBUG_TRACE,(" pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
}
-#endif // RT2860 //
/*
========================================================================
@@ -2634,9 +2617,7 @@ MAC_TABLE_ENTRY *MacTableInsertEntry(
pEntry->AuthMode = pAd->StaCfg.AuthMode;
pEntry->WepStatus = pAd->StaCfg.WepStatus;
pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-#ifdef RT2860
AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i);
-#endif // RT2860 //
}
#endif // CONFIG_STA_SUPPORT //
}
@@ -2823,9 +2804,7 @@ VOID MacTableReset(
for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
{
-#ifdef RT2860
RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
-#endif // RT2860 //
if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
{
diff --git a/drivers/staging/rt2860/common/cmm_data_2860.c b/drivers/staging/rt2860/common/cmm_data_2860.c
index 419e50c3fc4..fae741e4bee 100644
--- a/drivers/staging/rt2860/common/cmm_data_2860.c
+++ b/drivers/staging/rt2860/common/cmm_data_2860.c
@@ -634,7 +634,7 @@ VOID RT28xxPciAsicRadioOff(
}
// Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops.
- pAd->bPCIclkOffDisableTx = TRUE;
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
@@ -651,7 +651,7 @@ VOID RT28xxPciAsicRadioOff(
{
DBGPRINT(RT_DEBUG_TRACE, ("TbTTTime = 0x%x , give up this sleep. \n", TbTTTime));
OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
- pAd->bPCIclkOffDisableTx = FALSE;
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
return;
}
else
@@ -688,18 +688,25 @@ VOID RT28xxPciAsicRadioOff(
if (i >= 50)
{
DBGPRINT(RT_DEBUG_TRACE, ("DMA keeps busy. return on RT28xxPciAsicRadioOff ()\n"));
- pAd->bPCIclkOffDisableTx = FALSE;
RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
DmaCfg.field.EnableTxDMA = 1;
RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
+ pAd->CheckDmaBusyCount++;
return;
}
+ else
+ {
+ pAd->CheckDmaBusyCount = 0;
+ }
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
// Set to 1R.
- tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
+ if (pAd->Antenna.field.RxPath > 1)
+ {
+ tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
+ }
// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
@@ -714,8 +721,15 @@ VOID RT28xxPciAsicRadioOff(
AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
}
- // When PCI clock is off, don't want to service interrupt.
- RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
+ if (Level != RTMP_HALT)
+ {
+ // Change Interrupt bitmask.
+ RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
+ }
+ else
+ {
+ NICDisableInterrupt(pAd);
+ }
RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
// Disable MAC Rx
@@ -726,7 +740,8 @@ VOID RT28xxPciAsicRadioOff(
// 2. Send Sleep command
RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
- AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x00); // send POWER-SAVE command to MCU. Timeout unit:40us.
+ // send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power
+ AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1);
// 2-1. Wait command success
// Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task.
brc = AsicCheckCommanOk(pAd, PowerSafeCID);
@@ -734,7 +749,7 @@ VOID RT28xxPciAsicRadioOff(
if (brc == FALSE)
{
// try again
- AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x00); // send POWER-SAVE command to MCU. Timeout unit:40us.
+ AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x01); // send POWER-SAVE command to MCU. Timeout unit:40us.
//RTMPusecDelay(200);
brc = AsicCheckCommanOk(pAd, PowerSafeCID);
}
@@ -759,7 +774,7 @@ VOID RT28xxPciAsicRadioOff(
do
{
RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
- if (DmaCfg.field.RxDMABusy == 0)
+ if ((DmaCfg.field.RxDMABusy == 0) && (DmaCfg.field.TxDMABusy == 0))
break;
RTMPusecDelay(20);
i++;
@@ -767,13 +782,12 @@ VOID RT28xxPciAsicRadioOff(
if (i >= 50)
{
+ pAd->CheckDmaBusyCount++;
DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy. on RT28xxPciAsicRadioOff ()\n"));
}
- // disable DMA Rx.
+ else
{
- RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
- DmaCfg.field.EnableRxDMA = 0;
- RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
+ pAd->CheckDmaBusyCount = 0;
}
if (Level == DOT11POWERSAVE)
@@ -799,7 +813,7 @@ VOID RT28xxPciAsicRadioOff(
if (Level == RTMP_HALT)
{
if ((brc == TRUE) && (i < 50))
- RTMPPCIeLinkCtrlSetting(pAd, 1);
+ RTMPPCIeLinkCtrlSetting(pAd, 0);
}
// 4. Set PCI configuration Space Link Comtrol fields. Only Radio Off needs to call this function
else
@@ -808,7 +822,7 @@ VOID RT28xxPciAsicRadioOff(
RTMPPCIeLinkCtrlSetting(pAd, 3);
}
- pAd->bPCIclkOffDisableTx = FALSE;
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
}
@@ -835,7 +849,8 @@ BOOLEAN RT28xxPciAsicRadioOn(
{
pAd->Mlme.bPsPollTimerRunning = FALSE;
RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
- if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE))
+ if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE)
+ || (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)))
{
DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOn ()\n"));
// 1. Set PCI Link Control in Configuration Space.
@@ -845,15 +860,14 @@ BOOLEAN RT28xxPciAsicRadioOn(
}
pAd->bPCIclkOff = FALSE;
-
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x3a80);
// 2. Send wake up command.
- AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
+ AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
// 2-1. wait command ok.
brv = AsicCheckCommanOk(pAd, PowerWakeCID);
if (brv)
{
- //RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT));
NICEnableInterrupt(pAd);
// 3. Enable Tx DMA.
@@ -893,13 +907,10 @@ BOOLEAN RT28xxPciAsicRadioOn(
VOID RT28xxPciStaAsicForceWakeup(
IN PRTMP_ADAPTER pAd,
- IN BOOLEAN bFromTx)
+ IN UCHAR Level)
{
AUTO_WAKEUP_STRUC AutoWakeupCfg;
- if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
- return;
-
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
{
DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
@@ -907,38 +918,48 @@ VOID RT28xxPciStaAsicForceWakeup(
}
OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
// Support PCIe Advance Power Save
- if (bFromTx == TRUE)
+ if (((Level == FROM_TX) && (pAd->Mlme.bPsPollTimerRunning == TRUE)) ||
+ (Level == RTMP_HALT))
{
pAd->Mlme.bPsPollTimerRunning = FALSE;
RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
- RTMPusecDelay(3000);
+ RTMPusecDelay(5000);
DBGPRINT(RT_DEBUG_TRACE, ("=======AsicForceWakeup===bFromTx\n"));
}
AutoWakeupCfg.word = 0;
RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
- if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE))
- {
- // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
- if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
- && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
- {
- // Must using 40MHz.
- AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
- AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
- }
- else
- {
- // Must using 20MHz.
- AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
- AsicLockChannel(pAd, pAd->CommonCfg.Channel);
- }
- }
+ // If this is called from Halt. ALWAYS force wakeup!!!
+ if (Level == RTMP_HALT)
+ {
+ RT28xxPciAsicRadioOn(pAd, RTMP_HALT);
+ }
+ else
+ {
+ if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE))
+ {
+ // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
+ if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
+ && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ // Must using 40MHz.
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+ }
+ else
+ {
+ // Must using 20MHz.
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ }
+ }
+ }
}
else
{
@@ -1122,6 +1143,7 @@ VOID RT28xxPciMlmeRadioOn(
{
NICResetFromError(pAd);
+ /*
RTMPRingCleanUp(pAd, QID_AC_BK);
RTMPRingCleanUp(pAd, QID_AC_BE);
RTMPRingCleanUp(pAd, QID_AC_VI);
@@ -1129,6 +1151,7 @@ VOID RT28xxPciMlmeRadioOn(
RTMPRingCleanUp(pAd, QID_HCCA);
RTMPRingCleanUp(pAd, QID_MGMT);
RTMPRingCleanUp(pAd, QID_RX);
+ */
// Enable Tx/Rx
RTMPEnableRxTx(pAd);
@@ -1162,6 +1185,12 @@ VOID RT28xxPciMlmeRadioOFF(
WPDMA_GLO_CFG_STRUC GloCfg;
UINT32 i;
+ if (pAd->StaCfg.bRadio == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("-->MlmeRadioOff() return on bRadio == TRUE; \n"));
+ return;
+ }
+
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
return;
@@ -1169,13 +1198,12 @@ VOID RT28xxPciMlmeRadioOFF(
// Set LED
RTMPSetLED(pAd, LED_RADIO_OFF);
- // Set Radio off flag
- RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
BOOLEAN Cancelled;
+
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
{
RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
@@ -1185,6 +1213,15 @@ VOID RT28xxPciMlmeRadioOFF(
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
BOOLEAN Cancelled;
+
+ // Always radio on since the NIC needs to set the MCU command (LED_RADIO_OFF).
+ if ((pAd->OpMode == OPMODE_STA) &&
+ (IDLE_ON(pAd)) &&
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
+ {
+ RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
+ }
+
pAd->Mlme.bPsPollTimerRunning = FALSE;
RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
@@ -1197,9 +1234,26 @@ VOID RT28xxPciMlmeRadioOFF(
//==========================================
// Clean up old bss table
BssTableInit(&pAd->ScanTab);
+
+ RTMPRingCleanUp(pAd, QID_AC_BK);
+ RTMPRingCleanUp(pAd, QID_AC_BE);
+ RTMPRingCleanUp(pAd, QID_AC_VI);
+ RTMPRingCleanUp(pAd, QID_AC_VO);
+ RTMPRingCleanUp(pAd, QID_HCCA);
+ RTMPRingCleanUp(pAd, QID_MGMT);
+ RTMPRingCleanUp(pAd, QID_RX);
+
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
+ {
+ RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 500);
+ return;
+ }
}
#endif // CONFIG_STA_SUPPORT //
+ // Set Radio off flag
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
// Disable Tx/Rx DMA
RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
GloCfg.field.EnableTxDMA = 0;
diff --git a/drivers/staging/rt2860/common/cmm_info.c b/drivers/staging/rt2860/common/cmm_info.c
index dd92ac6eaed..c3e13195e12 100644
--- a/drivers/staging/rt2860/common/cmm_info.c
+++ b/drivers/staging/rt2860/common/cmm_info.c
@@ -814,7 +814,6 @@ INT Show_DescInfo_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
{
-#ifdef RT2860
INT i, QueIdx=0;
PRT28XX_RXD_STRUC pRxD;
PTXD_STRUC pTxD;
@@ -845,7 +844,6 @@ INT Show_DescInfo_Proc(
hex_dump("Rx Descriptor", (char *)pRxD, 16);
printk("pRxD->DDONE = %x\n", pRxD->DDONE);
}
-#endif // RT2860 //
return TRUE;
}
@@ -1803,9 +1801,7 @@ VOID RTMPAddWcidAttributeEntry(
}
// For key index and ext IV bit, so only need to update the position(offset+3).
-#ifdef RT2860
RTMP_IO_WRITE8(pAd, offset+3, IVEIV);
-#endif // RT2860 //
DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
DBGPRINT(RT_DEBUG_TRACE,(" WCIDAttri = 0x%x \n", WCIDAttri));
@@ -2827,9 +2823,7 @@ INT Set_OpMode_Proc(
Value = simple_strtol(arg, 0, 10);
-#ifdef RT2860
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-#endif // RT2860 //
{
DBGPRINT(RT_DEBUG_ERROR, ("Can not switch operate mode on interface up !! \n"));
return FALSE;
diff --git a/drivers/staging/rt2860/common/cmm_sync.c b/drivers/staging/rt2860/common/cmm_sync.c
index 40e4109118e..d29e0b630e2 100644
--- a/drivers/staging/rt2860/common/cmm_sync.c
+++ b/drivers/staging/rt2860/common/cmm_sync.c
@@ -470,7 +470,7 @@ VOID ScanNextChannel(
{
// BBP and RF are not accessible in PS mode, we has to wake them up first
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
- AsicForceWakeup(pAd, TRUE);
+ AsicForceWakeup(pAd, FROM_TX);
// leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
if (pAd->StaCfg.Psm == PWR_SAVE)
diff --git a/drivers/staging/rt2860/common/cmm_wpa.c b/drivers/staging/rt2860/common/cmm_wpa.c
index 81c332ac252..69baf522fa0 100644
--- a/drivers/staging/rt2860/common/cmm_wpa.c
+++ b/drivers/staging/rt2860/common/cmm_wpa.c
@@ -39,8 +39,10 @@
// WPA OUI
UCHAR OUI_WPA_NONE_AKM[4] = {0x00, 0x50, 0xF2, 0x00};
UCHAR OUI_WPA_VERSION[4] = {0x00, 0x50, 0xF2, 0x01};
+UCHAR OUI_WPA_WEP40[4] = {0x00, 0x50, 0xF2, 0x01};
UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02};
UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04};
+UCHAR OUI_WPA_WEP104[4] = {0x00, 0x50, 0xF2, 0x05};
UCHAR OUI_WPA_8021X_AKM[4] = {0x00, 0x50, 0xF2, 0x01};
UCHAR OUI_WPA_PSK_AKM[4] = {0x00, 0x50, 0xF2, 0x02};
// WPA2 OUI
@@ -49,6 +51,7 @@ UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};
UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};
UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01};
UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02};
+UCHAR OUI_WPA2_WEP104[4] = {0x00, 0x0F, 0xAC, 0x05};
// MSA OUI
UCHAR OUI_MSA_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x05}; // Not yet final - IEEE 802.11s-D1.06
UCHAR OUI_MSA_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x06}; // Not yet final - IEEE 802.11s-D1.06
@@ -367,6 +370,24 @@ static VOID RTMPInsertRsnIeCipher(
break;
}
+#ifdef CONFIG_STA_SUPPORT
+ if ((pAd->OpMode == OPMODE_STA) &&
+ (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
+ {
+ UINT GroupCipher = pAd->StaCfg.GroupCipher;
+ switch(GroupCipher)
+ {
+ case Ndis802_11GroupWEP40Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP40, 4);
+ break;
+ case Ndis802_11GroupWEP104Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP104, 4);
+ break;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
// swap for big-endian platform
pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
@@ -427,11 +448,28 @@ static VOID RTMPInsertRsnIeCipher(
break;
}
+#ifdef CONFIG_STA_SUPPORT
+ if ((pAd->OpMode == OPMODE_STA) &&
+ (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
+ {
+ UINT GroupCipher = pAd->StaCfg.GroupCipher;
+ switch(GroupCipher)
+ {
+ case Ndis802_11GroupWEP40Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP40, 4);
+ break;
+ case Ndis802_11GroupWEP104Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP104, 4);
+ break;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
// swap for big-endian platform
pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
}
-
}
/*
diff --git a/drivers/staging/rt2860/common/mlme.c b/drivers/staging/rt2860/common/mlme.c
index 229747095ae..c00f9ab9c46 100644
--- a/drivers/staging/rt2860/common/mlme.c
+++ b/drivers/staging/rt2860/common/mlme.c
@@ -527,7 +527,6 @@ NDIS_STATUS MlmeInit(
#ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
@@ -537,7 +536,6 @@ NDIS_STATUS MlmeInit(
RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE);
}
}
-#endif // RT2860 //
#endif // CONFIG_STA_SUPPORT //
} while (FALSE);
@@ -711,13 +709,11 @@ VOID MlmeHalt(
RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
-#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
}
-#endif // RT2860 //
#ifdef QOS_DLS_SUPPORT
for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
@@ -808,21 +804,34 @@ VOID MlmePeriodicExec(
ULONG TxTotalCnt;
PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
+ //Baron 2008/07/10
+ //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
+ //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
+ //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
+ if(pAd->StaCfg.WepStatus<2)
+ {
+ pAd->StaCfg.WpaSupplicantUP = 0;
+ }
+ else
+ {
+ pAd->StaCfg.WpaSupplicantUP = 1;
+ }
+
#ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
// If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second.
// Move code to here, because following code will return when radio is off
- if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) && (pAd->StaCfg.bHardwareRadio == TRUE) &&
+ if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) &&
+ (pAd->StaCfg.bHardwareRadio == TRUE) &&
+ (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
- (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
- (pAd->bPCIclkOff == FALSE))
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
{
UINT32 data = 0;
// Read GPIO pin2 as Hardware controlled radio state
- RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
+ RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
if (data & 0x04)
{
pAd->StaCfg.bHwRadio = TRUE;
@@ -849,7 +858,6 @@ VOID MlmePeriodicExec(
}
}
}
-#endif // RT2860 //
#endif // CONFIG_STA_SUPPORT //
// Do nothing if the driver is starting halt state.
@@ -860,6 +868,45 @@ VOID MlmePeriodicExec(
fRTMP_ADAPTER_RESET_IN_PROGRESS))))
return;
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if ((pAd->RalinkCounters.LastReceivedByteCount == pAd->RalinkCounters.ReceivedByteCount) && (pAd->StaCfg.bRadio == TRUE))
+ {
+ // If ReceiveByteCount doesn't change, increase SameRxByteCount by 1.
+ pAd->SameRxByteCount++;
+ }
+ else
+ pAd->SameRxByteCount = 0;
+
+ // If after BBP, still not work...need to check to reset PBF&MAC.
+ if (pAd->SameRxByteCount == 702)
+ {
+ pAd->SameRxByteCount = 0;
+ AsicResetPBF(pAd);
+ AsicResetMAC(pAd);
+ }
+
+ // If SameRxByteCount keeps happens for 2 second in infra mode, or for 60 seconds in idle mode.
+ if (((INFRA_ON(pAd)) && (pAd->SameRxByteCount > 20)) || ((IDLE_ON(pAd)) && (pAd->SameRxByteCount > 600)))
+ {
+ if ((pAd->StaCfg.bRadio == TRUE) && (pAd->SameRxByteCount < 700))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("---> SameRxByteCount = %lu !!!!!!!!!!!!!!! \n", pAd->SameRxByteCount));
+ pAd->SameRxByteCount = 700;
+ AsicResetBBP(pAd);
+ }
+ }
+
+ // Update lastReceiveByteCount.
+ pAd->RalinkCounters.LastReceivedByteCount = pAd->RalinkCounters.ReceivedByteCount;
+
+ if ((pAd->CheckDmaBusyCount > 3) && (IDLE_ON(pAd)))
+ {
+ pAd->CheckDmaBusyCount = 0;
+ AsicResetFromDMABusy(pAd);
+ }
+ }
+
RT28XX_MLME_PRE_SANITY_CHECK(pAd);
#ifdef RALINK_ATE
@@ -1022,9 +1069,7 @@ VOID MlmePeriodicExec(
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
-#ifdef RT2860
if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE))
-#endif // RT2860 //
{
// When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
// and sending CTS-to-self over and over.
@@ -1081,6 +1126,19 @@ VOID STAMlmePeriodicExec(
pAd->StaCfg.bBlockAssoc = FALSE;
}
+ //Baron 2008/07/10
+ //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
+ //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
+ //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
+ if(pAd->StaCfg.WepStatus<2)
+ {
+ pAd->StaCfg.WpaSupplicantUP = 0;
+ }
+ else
+ {
+ pAd->StaCfg.WpaSupplicantUP = 1;
+ }
+
if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
{
if (pAd->IndicateMediaState == NdisMediaStateConnected)
@@ -1090,6 +1148,15 @@ VOID STAMlmePeriodicExec(
pAd->PreMediaState = pAd->IndicateMediaState;
}
+ if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) &&
+ (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
+ (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
+ (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
+ (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
+ {
+ RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
+ }
@@ -2781,7 +2848,7 @@ VOID MlmeCheckPsmChange(
if (INFRA_ON(pAd) &&
(PowerMode != Ndis802_11PowerModeCAM) &&
(pAd->StaCfg.Psm == PWR_ACTIVE) &&
- (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
+ RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP))
{
NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
pAd->RalinkCounters.RxCountSinceLastNULL = 0;
@@ -4065,7 +4132,9 @@ VOID BssTableSsidSort(
continue;
// check group cipher
- if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
+ if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
+ (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
+ (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled))
continue;
// check pairwise cipher, skip if none matched
@@ -4084,7 +4153,9 @@ VOID BssTableSsidSort(
continue;
// check group cipher
- if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
+ if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
+ (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
+ (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled))
continue;
// check pairwise cipher, skip if none matched
@@ -4371,8 +4442,10 @@ VOID BssCipherParse(
switch (*pTmp)
{
case 1:
- case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
- pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+ pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
+ break;
+ case 5:
+ pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
break;
case 2:
pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
@@ -4489,8 +4562,10 @@ VOID BssCipherParse(
switch (pCipher->Type)
{
case 1:
- case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
- pBss->WPA2.GroupCipher = Ndis802_11Encryption1Enabled;
+ pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
+ break;
+ case 5:
+ pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
break;
case 2:
pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
@@ -4953,16 +5028,13 @@ BOOLEAN MlmeDequeue(
VOID MlmeRestartStateMachine(
IN PRTMP_ADAPTER pAd)
{
-#ifdef RT2860
MLME_QUEUE_ELEM *Elem = NULL;
-#endif // RT2860 //
#ifdef CONFIG_STA_SUPPORT
BOOLEAN Cancelled;
#endif // CONFIG_STA_SUPPORT //
DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
-#ifdef RT2860
NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
if(pAd->Mlme.bRunning)
{
@@ -4990,7 +5062,6 @@ VOID MlmeRestartStateMachine(
DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
}
}
-#endif // RT2860 //
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
@@ -5039,12 +5110,10 @@ VOID MlmeRestartStateMachine(
}
#endif // CONFIG_STA_SUPPORT //
-#ifdef RT2860
// Remove running state
NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
pAd->Mlme.bRunning = FALSE;
NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-#endif // RT2860 //
}
/*! \brief test if the MLME Queue is empty
@@ -6149,6 +6218,12 @@ VOID AsicAdjustTxPower(
ULONG TxPwr[5];
CHAR Value;
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+ || (pAd->bPCIclkOff == TRUE)
+ || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)
+ || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ return;
+
if (pAd->CommonCfg.BBPCurrentBW == BW_40)
{
if (pAd->CommonCfg.CentralChannel > 14)
@@ -6493,10 +6568,10 @@ VOID AsicForceSleep(
*/
VOID AsicForceWakeup(
IN PRTMP_ADAPTER pAd,
- IN BOOLEAN bFromTx)
+ IN UCHAR Level)
{
DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
- RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
+ RT28XX_STA_FORCE_WAKEUP(pAd, Level);
}
#endif // CONFIG_STA_SUPPORT //
/*
@@ -6710,7 +6785,6 @@ VOID AsicEnableIbssSync(
csr9.field.bTsfTicking = 0;
RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
-#ifdef RT2860
// move BEACON TXD and frame content to on-chip memory
ptr = (PUCHAR)&pAd->BeaconTxWI;
for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
@@ -6728,7 +6802,6 @@ VOID AsicEnableIbssSync(
RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
ptr +=4;
}
-#endif // RT2860 //
// start sending BEACON
csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
@@ -7097,9 +7170,7 @@ VOID AsicAddSharedKeyEntry(
{
ULONG offset; //, csr0;
SHAREDKEY_MODE_STRUC csr1;
-#ifdef RT2860
INT i;
-#endif // RT2860 //
DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
//============================================================================================
@@ -7121,7 +7192,6 @@ VOID AsicAddSharedKeyEntry(
//
// fill key material - key + TX MIC + RX MIC
//
-#ifdef RT2860
offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
{
@@ -7145,7 +7215,6 @@ VOID AsicAddSharedKeyEntry(
RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
}
}
-#endif // RT2860 //
//
@@ -7320,9 +7389,7 @@ VOID AsicAddKeyEntry(
PUCHAR pTxtsc = pCipherKey->TxTsc;
UCHAR CipherAlg = pCipherKey->CipherAlg;
SHAREDKEY_MODE_STRUC csr1;
-#ifdef RT2860
UCHAR i;
-#endif // RT2860 //
DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
//
@@ -7337,7 +7404,6 @@ VOID AsicAddKeyEntry(
// 2.) Set Key to Asic
//
//for (i = 0; i < KeyLen; i++)
-#ifdef RT2860
for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
{
RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
@@ -7363,7 +7429,6 @@ VOID AsicAddKeyEntry(
RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
}
}
-#endif // RT2860 //
//
@@ -7372,7 +7437,6 @@ VOID AsicAddKeyEntry(
//
if (bTxKey)
{
-#ifdef RT2860
offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
//
// Write IV
@@ -7395,7 +7459,6 @@ VOID AsicAddKeyEntry(
{
RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
}
-#endif // RT2860 //
AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
}
@@ -7461,12 +7524,10 @@ VOID AsicAddPairwiseKeyEntry(
// EKEY
offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
-#ifdef RT2860
for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
{
RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
}
-#endif // RT2860 //
for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
{
UINT32 Value;
@@ -7478,22 +7539,18 @@ VOID AsicAddPairwiseKeyEntry(
// MIC KEY
if (pTxMic)
{
-#ifdef RT2860
for (i=0; i<8; i++)
{
RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
}
-#endif // RT2860 //
}
offset += 8;
if (pRxMic)
{
-#ifdef RT2860
for (i=0; i<8; i++)
{
RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
}
-#endif // RT2860 //
}
DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
@@ -7542,11 +7599,9 @@ BOOLEAN AsicSendCommandToMcu(
HOST_CMD_CSR_STRUC H2MCmd;
H2M_MAILBOX_STRUC H2MMailbox;
ULONG i = 0;
-#ifdef RT2860
#ifdef RALINK_ATE
static UINT32 j = 0;
#endif // RALINK_ATE //
-#endif // RT2860 //
do
{
RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
@@ -7558,7 +7613,6 @@ BOOLEAN AsicSendCommandToMcu(
if (i >= 100)
{
-#ifdef RT2860
#ifdef RALINK_ATE
if (pAd->ate.bFWLoading == TRUE)
{
@@ -7583,14 +7637,33 @@ BOOLEAN AsicSendCommandToMcu(
}
else
#endif // RALINK_ATE //
-#endif // RT2860 //
{
+ UINT32 Data;
+
+ // Reset DMA
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+ Data |= 0x2;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+ // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
+ // Reset DMA/CPU ring index
+ RTMPRingCleanUp(pAd, QID_AC_BK);
+ RTMPRingCleanUp(pAd, QID_AC_BE);
+ RTMPRingCleanUp(pAd, QID_AC_VI);
+ RTMPRingCleanUp(pAd, QID_AC_VO);
+ RTMPRingCleanUp(pAd, QID_HCCA);
+ RTMPRingCleanUp(pAd, QID_MGMT);
+ RTMPRingCleanUp(pAd, QID_RX);
+
+ // Clear Reset
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+ Data &= 0xfffffffd;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
}
- return FALSE;
+ //return FALSE;
}
-#ifdef RT2860
#ifdef RALINK_ATE
else if (pAd->ate.bFWLoading == TRUE)
{
@@ -7600,7 +7673,6 @@ BOOLEAN AsicSendCommandToMcu(
j = 0;
}
#endif // RALINK_ATE //
-#endif // RT2860 //
H2MMailbox.field.Owner = 1; // pass ownership to MCU
H2MMailbox.field.CmdToken = Token;
@@ -7619,7 +7691,6 @@ BOOLEAN AsicSendCommandToMcu(
return TRUE;
}
-#ifdef RT2860
BOOLEAN AsicCheckCommanOk(
IN PRTMP_ADAPTER pAd,
IN UCHAR Command)
@@ -7684,7 +7755,6 @@ BOOLEAN AsicCheckCommanOk(
return FALSE;
}
-#endif // RT2860 //
/*
========================================================================
@@ -8096,10 +8166,8 @@ VOID AsicEvaluateRxAnt(
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
#ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
pAd->StaCfg.BBPR3 = BBPR3;
-#endif // RT2860 //
#endif // CONFIG_STA_SUPPORT //
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
)
@@ -8211,9 +8279,7 @@ VOID AsicRxAntEvalTimeout(
BBPR3 |= (0x0);
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-#ifdef RT2860
- pAd->StaCfg.BBPR3 = BBPR3;
-#endif // RT2860 //
+ pAd->StaCfg.BBPR3 = BBPR3;
}
#endif // CONFIG_STA_SUPPORT //
@@ -8439,10 +8505,7 @@ VOID AsicStaBbpTuning(
&& (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
)
&& !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#ifdef RT2860
- && (pAd->bPCIclkOff == FALSE)
-#endif // RT2860 //
- )
+ && (pAd->bPCIclkOff == FALSE))
{
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
R66 = OrigR66Value;
@@ -8518,6 +8581,106 @@ VOID AsicStaBbpTuning(
}
}
+
+VOID AsicResetFromDMABusy(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 Data;
+ BOOLEAN bCtrl = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("---> AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
+
+ // Be sure restore link control value so we can write register.
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+ if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("AsicResetFromDMABusy==>\n"));
+ RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
+ RTMPusecDelay(6000);
+ pAd->bPCIclkOff = FALSE;
+ bCtrl = TRUE;
+ }
+ // Reset DMA
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+ Data |= 0x2;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+ // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
+ // Reset DMA/CPU ring index
+ RTMPRingCleanUp(pAd, QID_AC_BK);
+ RTMPRingCleanUp(pAd, QID_AC_BE);
+ RTMPRingCleanUp(pAd, QID_AC_VI);
+ RTMPRingCleanUp(pAd, QID_AC_VO);
+ RTMPRingCleanUp(pAd, QID_HCCA);
+ RTMPRingCleanUp(pAd, QID_MGMT);
+ RTMPRingCleanUp(pAd, QID_RX);
+
+ // Clear Reset
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+ Data &= 0xfffffffd;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+ // If in Radio off, should call RTMPPCIePowerLinkCtrl again.
+ if ((bCtrl == TRUE) && (pAd->StaCfg.bRadio == FALSE))
+ RTMPPCIeLinkCtrlSetting(pAd, 3);
+
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
+}
+
+VOID AsicResetBBP(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("---> Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
+
+ // After hard-reset BBP, initialize all BBP values.
+ NICRestoreBBPValue(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
+}
+
+VOID AsicResetMAC(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG Data;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("---> AsicResetMAC !!!! \n"));
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+ Data |= 0x4;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+ Data &= 0xfffffffb;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- AsicResetMAC !!!! \n"));
+}
+
+VOID AsicResetPBF(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG Value1, Value2;
+ ULONG Data;
+
+ RTMP_IO_READ32(pAd, TXRXQ_PCNT, &Value1);
+ RTMP_IO_READ32(pAd, PBF_DBG, &Value2);
+
+ Value2 &= 0xff;
+ // sum should be equals to 0xff, which is the total buffer size.
+ if ((Value1 + Value2) < 0xff)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("---> Asic HardReset PBF !!!! \n"));
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+ Data |= 0x8;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+ Data &= 0xfffffff7;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- Asic HardReset PBF !!!! \n"));
+ }
+}
#endif // CONFIG_STA_SUPPORT //
VOID RTMPSetAGCInitValue(
diff --git a/drivers/staging/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c
index 563f2c5bb85..8a00cee3ee9 100644
--- a/drivers/staging/rt2860/common/rtmp_init.c
+++ b/drivers/staging/rt2860/common/rtmp_init.c
@@ -149,9 +149,7 @@ RTMP_REG_PAIR MACRegTable[] = {
{GF20_PROT_CFG, 0x01744004}, // set 19:18 --> Short NAV for MIMO PS
{GF40_PROT_CFG, 0x03F44084},
{MM20_PROT_CFG, 0x01744004},
-#ifdef RT2860
{MM40_PROT_CFG, 0x03F54084},
-#endif // RT2860 //
{TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f*/ /*0x000024bf*/}, //Extension channel backoff.
{TX_RTS_CFG, 0x00092b20},
{EXP_ACK_TIME, 0x002400ca}, // default value
@@ -188,9 +186,7 @@ RTMP_REG_PAIR STAMACRegTable[] = {
#define FIRMWAREIMAGEV1_LENGTH 0x1000
#define FIRMWAREIMAGEV2_LENGTH 0x1000
-#ifdef RT2860
#define FIRMWARE_MINOR_VERSION 2
-#endif // RT2860 //
/*
@@ -248,9 +244,7 @@ NDIS_STATUS RTMPAllocAdapterBlock(
// Init spin locks
NdisAllocateSpinLock(&pAd->MgmtRingLock);
-#ifdef RT2860
NdisAllocateSpinLock(&pAd->RxRingLock);
-#endif // RT2860 //
for (index =0 ; index < NUM_OF_TX_RING; index++)
{
@@ -1555,10 +1549,7 @@ VOID NICInitAsicFromEEPROM(
pAd->LedCntl.word = 0x01;
pAd->Led1 = 0x5555;
pAd->Led2 = 0x2221;
-
-#ifdef RT2860
pAd->Led3 = 0xA9F8;
-#endif // RT2860 //
}
AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8));
@@ -1594,12 +1585,10 @@ VOID NICInitAsicFromEEPROM(
else
{
RTMPSetLED(pAd, LED_RADIO_ON);
-#ifdef RT2860
AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
// 2-1. wait command ok.
AsicCheckCommanOk(pAd, PowerWakeCID);
-#endif // RT2860 //
}
}
#endif // CONFIG_STA_SUPPORT //
@@ -1677,10 +1666,8 @@ NDIS_STATUS NICInitializeAdapter(
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
WPDMA_GLO_CFG_STRUC GloCfg;
-#ifdef RT2860
UINT32 Value;
DELAY_INT_CFG_STRUC IntCfg;
-#endif // RT2860 //
ULONG i =0, j=0;
AC_TXOP_CSR0_STRUC csr0;
@@ -1719,11 +1706,9 @@ retry:
// asic simulation sequence put this ahead before loading firmware.
// pbf hardware reset
-#ifdef RT2860
RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f); // 0x10000 for reset rx, 0x3f resets all 6 tx rings.
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f);
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00);
-#endif // RT2860 //
// Initialze ASIC for TX & Rx operation
if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
@@ -1737,7 +1722,6 @@ retry:
}
-#ifdef RT2860
// Write AC_BK base address register
Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa);
RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value);
@@ -1810,7 +1794,6 @@ retry:
// Write RX_RING_CSR register
Value = RX_RING_SIZE;
RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value);
-#endif // RT2860 //
// WMM parameter
@@ -1829,7 +1812,6 @@ retry:
RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
-#ifdef RT2860
// 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
i = 0;
do
@@ -1848,7 +1830,6 @@ retry:
IntCfg.word = 0;
RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word);
-#endif // RT2860 //
// reset action
@@ -1889,7 +1870,6 @@ NDIS_STATUS NICInitializeAsic(
DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
-#ifdef RT2860
if (bHardReset == TRUE)
{
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
@@ -1914,7 +1894,6 @@ NDIS_STATUS NICInitializeAsic(
}
}
#endif // CONFIG_STA_SUPPORT //
-#endif // RT2860 //
//
@@ -2041,6 +2020,131 @@ NDIS_STATUS NICInitializeAsic(
return NDIS_STATUS_SUCCESS;
}
+
+VOID NICRestoreBBPValue(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR index;
+ UCHAR Value = 0;
+ ULONG Data;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("---> NICRestoreBBPValue !!!!!!!!!!!!!!!!!!!!!!! \n"));
+ // Initialize BBP register to default value (rtmp_init.c)
+ for (index = 0; index < NUM_BBP_REG_PARMS; index++)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[index].Register, BBPRegTable[index].Value);
+ }
+ // copy from (rtmp_init.c)
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
+ }
+
+ // copy from (connect.c LinkUp function)
+ if (INFRA_ON(pAd))
+ {
+ // Change to AP channel
+ if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ // Must using 40MHz.
+ pAd->CommonCfg.BBPCurrentBW = BW_40;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x18);
+ Value |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+ // RX : control channel at lower
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+ Value &= (~0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+ // Record BBPR3 setting, But don't keep R Antenna # information.
+ pAd->StaCfg.BBPR3 = Value;
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+ Data &= 0xfffffffe;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
+ }
+ else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ // Must using 40MHz.
+ pAd->CommonCfg.BBPCurrentBW = BW_40;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x18);
+ Value |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+ Data |= 0x1;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+ Value |= (0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+ // Record BBPR3 setting, But don't keep R Antenna # information.
+ pAd->StaCfg.BBPR3 = Value;
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
+ }
+ else
+ {
+ pAd->CommonCfg.BBPCurrentBW = BW_20;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+ Data &= 0xfffffffe;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+ Value &= (~0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+ // Record BBPR3 setting, But don't keep R Antenna # information.
+ pAd->StaCfg.BBPR3 = Value;
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz LINK UP !!! \n" ));
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- NICRestoreBBPValue !!!!!!!!!!!!!!!!!!!!!!! \n"));
+}
+
/*
========================================================================
@@ -3028,11 +3132,10 @@ VOID UserCfgInit(
pAd->CommonCfg.BBPCurrentBW = BW_20;
pAd->LedCntl.word = 0;
-#ifdef RT2860
pAd->LedIndicatorStregth = 0;
pAd->RLnkCtrlOffset = 0;
pAd->HostLnkCtrlOffset = 0;
-#endif // RT2860 //
+ pAd->CheckDmaBusyCount = 0;
pAd->bAutoTxAgcA = FALSE; // Default is OFF
pAd->bAutoTxAgcG = FALSE; // Default is OFF
@@ -3292,9 +3395,7 @@ VOID UserCfgInit(
pAd->ate.bRxFer = 0;
pAd->ate.bQATxStart = FALSE;
pAd->ate.bQARxStart = FALSE;
-#ifdef RT2860
pAd->ate.bFWLoading = FALSE;
-#endif // RT2860 //
#ifdef RALINK_28xx_QA
//pAd->ate.Repeat = 0;
pAd->ate.TxStatus = 0;
@@ -3304,11 +3405,9 @@ VOID UserCfgInit(
pAd->CommonCfg.bWiFiTest = FALSE;
-#ifdef RT2860
- pAd->bPCIclkOff = FALSE;
-#endif // RT2860 //
-
+ pAd->bPCIclkOff = FALSE;
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
}
diff --git a/drivers/staging/rt2860/common/spectrum.c b/drivers/staging/rt2860/common/spectrum.c
index 0265a6d1df1..b3650ec4656 100644
--- a/drivers/staging/rt2860/common/spectrum.c
+++ b/drivers/staging/rt2860/common/spectrum.c
@@ -1596,7 +1596,7 @@ static VOID PeerMeasureReportAction(
if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
{
- DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
+ DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%zu).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
return;
}
diff --git a/drivers/staging/rt2860/config.mk b/drivers/staging/rt2860/config.mk
index f57d7bbffb2..25bd55a7aab 100644
--- a/drivers/staging/rt2860/config.mk
+++ b/drivers/staging/rt2860/config.mk
@@ -108,10 +108,6 @@ ifeq ($(HAS_EXT_BUILD_CHANNEL_LIST),y)
WFLAGS += -DEXT_BUILD_CHANNEL_LIST
endif
-ifeq ($(CHIPSET),2860)
-WFLAGS +=-DRT2860
-endif
-
ifeq ($(CHIPSET),2870)
WFLAGS +=-DRT2870
endif
diff --git a/drivers/staging/rt2860/oid.h b/drivers/staging/rt2860/oid.h
index f2f91b607c4..5e6ed9f62f9 100644
--- a/drivers/staging/rt2860/oid.h
+++ b/drivers/staging/rt2860/oid.h
@@ -544,6 +544,8 @@ typedef enum _NDIS_802_11_WEP_STATUS
Ndis802_11Encryption3KeyAbsent,
Ndis802_11Encryption4Enabled, // TKIP or AES mix
Ndis802_11Encryption4KeyAbsent,
+ Ndis802_11GroupWEP40Enabled,
+ Ndis802_11GroupWEP104Enabled,
} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
diff --git a/drivers/staging/rt2860/rt2860.h b/drivers/staging/rt2860/rt2860.h
index 01720190662..4fbec906e10 100644
--- a/drivers/staging/rt2860/rt2860.h
+++ b/drivers/staging/rt2860/rt2860.h
@@ -46,18 +46,10 @@
Status = NDIS_STATUS_SUCCESS;
/* function declarations */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#define IRQ_HANDLE_TYPE irqreturn_t
-#else
-#define IRQ_HANDLE_TYPE void
-#endif
IRQ_HANDLE_TYPE
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
rt2860_interrupt(int irq, void *dev_instance);
-#else
-rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-#endif
/* ----------------- Frimware Related MACRO ----------------- */
#define RT28XX_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \
@@ -237,9 +229,7 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
#define RTMP_MSI_DISABLE(_pAd)
#endif // PCI_MSI_SUPPORT //
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
#define SA_SHIRQ IRQF_SHARED
-#endif
#define RT28XX_IRQ_REQUEST(net_dev) \
{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->ml_priv); \
@@ -251,20 +241,12 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
printk("RT2860: request_irq ERROR(%d)\n", retval); \
return retval; } }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#define RT28XX_IRQ_RELEASE(net_dev) \
{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->ml_priv); \
POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
synchronize_irq(_pObj->pci_dev->irq); \
free_irq(_pObj->pci_dev->irq, (net_dev)); \
RTMP_MSI_DISABLE(_pAd); }
-#else
-#define RT28XX_IRQ_RELEASE(net_dev) \
-{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->priv); \
- POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
- free_irq(_pObj->pci_dev->irq, (net_dev)); \
- RTMP_MSI_DISABLE(_pAd); }
-#endif
#define RT28XX_IRQ_INIT(pAd) \
{ pAd->int_enable_reg = ((DELAYINTMASK) | \
@@ -333,8 +315,8 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
reg16 = cpu2le16(Configuration); \
pci_write_config_word(pci_dev, offset, reg16); \
-#define RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx) \
- RT28xxPciStaAsicForceWakeup(pAd, bFromTx);
+#define RT28XX_STA_FORCE_WAKEUP(pAd, Level) \
+ RT28xxPciStaAsicForceWakeup(pAd, Level);
#define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
diff --git a/drivers/staging/rt2860/rt28xx.h b/drivers/staging/rt2860/rt28xx.h
index ff23043e560..e5e6f0a8de6 100644
--- a/drivers/staging/rt2860/rt28xx.h
+++ b/drivers/staging/rt2860/rt28xx.h
@@ -1670,11 +1670,9 @@ typedef struct _HW_WCID_ENTRY { // 8-byte per entry
#define E2PROM_CSR 0x0004
#define IO_CNTL_CSR 0x77d0
-#ifdef RT2860
// 8051 firmware image for RT2860 - base address = 0x4000
#define FIRMWARE_IMAGE_BASE 0x2000
#define MAX_FIRMWARE_IMAGE_SIZE 0x2000 // 8kbyte
-#endif // RT2860 //
// ================================================================
@@ -2029,7 +2027,6 @@ typedef struct PACKED _TXWI_STRUC {
//
// Rx descriptor format, Rx Ring
//
-#ifdef RT2860
#ifdef RT_BIG_ENDIAN
typedef struct PACKED _RXD_STRUC {
// Word 0
@@ -2098,7 +2095,6 @@ typedef struct PACKED _RXD_STRUC {
UINT32 Rsv1:13;
} RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
#endif
-#endif // RT2860 //
//
// RXWI wireless information format, in PBF. invisible in driver.
//
diff --git a/drivers/staging/rt2860/rt_ate.c b/drivers/staging/rt2860/rt_ate.c
index f3316ec0b15..1ed73c9e6b6 100644
--- a/drivers/staging/rt2860/rt_ate.c
+++ b/drivers/staging/rt2860/rt_ate.c
@@ -68,7 +68,6 @@ static int CheckMCSValid(
IN UCHAR Mode,
IN UCHAR Mcs);
-#ifdef RT2860
static VOID ATEWriteTxWI(
IN PRTMP_ADAPTER pAd,
IN PTXWI_STRUC pOutTxWI,
@@ -87,7 +86,6 @@ static VOID ATEWriteTxWI(
IN UCHAR Txopmode,
IN BOOLEAN CfAck,
IN HTTRANSMIT_SETTING *pTransmit);
-#endif // RT2860 //
static VOID SetJapanFilter(
@@ -95,7 +93,6 @@ static VOID SetJapanFilter(
/*=========================end of prototype=========================*/
-#ifdef RT2860
static INT TxDmaBusy(
IN PRTMP_ADAPTER pAd)
{
@@ -153,7 +150,6 @@ static VOID RtmpDmaEnable(
return;
}
-#endif // RT2860 //
static VOID BbpSoftReset(
@@ -488,7 +484,6 @@ static INT ATETxPwrHandler(
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
-#ifdef RT2860
static INT ATECmdHandler(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
@@ -1297,7 +1292,6 @@ static INT ATECmdHandler(
return TRUE;
}
-#endif // RT2860 //
/* */
/* */
/*=======================End of RT2860=======================*/
@@ -2907,7 +2901,6 @@ VOID ATEAsicAdjustTxPower(
None
========================================================================
*/
-#ifdef RT2860
static VOID ATEWriteTxWI(
IN PRTMP_ADAPTER pAd,
IN PTXWI_STRUC pOutTxWI,
@@ -2972,7 +2965,6 @@ static VOID ATEWriteTxWI(
return;
}
-#endif // RT2860 //
/*
========================================================================
@@ -3249,13 +3241,11 @@ VOID RTMPStationStart(
IN PRTMP_ADAPTER pAd)
{
ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStart\n"));
-#ifdef RT2860
- pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+epAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
//
// We did not cancel this timer when entering ATE mode.
//
// RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
-#endif // RT2860 //
ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStart\n"));
}
#endif // CONFIG_STA_SUPPORT //
@@ -3268,7 +3258,6 @@ VOID RTMPStationStart(
This routine should only be used in ATE mode.
==========================================================================
*/
-#ifdef RT2860
static INT ATESetUpFrame(
IN PRTMP_ADAPTER pAd,
IN UINT32 TxIdx)
@@ -3455,7 +3444,6 @@ static INT ATESetUpFrame(
/* */
/* */
/*=======================End of RT2860=======================*/
-#endif // RT2860 //
VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
@@ -4578,9 +4566,7 @@ VOID RtmpDoAte(
{
if (pAdapter->ate.TxCount == 0)
{
-#ifdef RT2860
pAdapter->ate.TxCount = 0xFFFFFFFF;
-#endif // RT2860 //
}
ATEDBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n"));
pAdapter->ate.bQATxStart = TRUE;
@@ -5375,7 +5361,6 @@ TX_START_ERROR:
memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
value = ntohs(value);
-#ifdef RT2860
/* TX_FRAME_COUNT == 0 means tx infinitely */
if (value == 0)
{
@@ -5387,7 +5372,6 @@ TX_START_ERROR:
}
else
-#endif // RT2860 //
{
sprintf((PCHAR)str, "%d", value);
Set_ATE_TX_COUNT_Proc(pAdapter, str);
diff --git a/drivers/staging/rt2860/rt_ate.h b/drivers/staging/rt2860/rt_ate.h
index 48aa70d2f01..38f5c4af546 100644
--- a/drivers/staging/rt2860/rt_ate.h
+++ b/drivers/staging/rt2860/rt_ate.h
@@ -31,12 +31,10 @@
#ifndef UCOS
#define ate_print printk
#define ATEDBGPRINT DBGPRINT
-#ifdef RT2860
#define EEPROM_SIZE 0x200
#ifdef CONFIG_STA_SUPPORT
#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2860STA/e2p.bin"
#endif // CONFIG_STA_SUPPORT //
-#endif // RT2860 //
#else // !UCOS //
#define fATE_LOAD_EEPROM 0x0C43
@@ -69,7 +67,6 @@ do{ int (*org_remote_display)(char *) = NULL; \
#define ATE_ON(_p) (((_p)->ate.Mode) != ATE_STOP)
/* RT2880_iNIC will define "RT2860". */
-#ifdef RT2860
#define ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
{ \
BBP_CSR_CFG_STRUC BbpCsr; \
@@ -131,10 +128,8 @@ do{ int (*org_remote_display)(char *) = NULL; \
ATEDBGPRINT(RT_DEBUG_ERROR, ("BBP write R%d fail\n", _I)); \
} \
}
-#endif // RT2860 //
/* RT2880_iNIC will define RT2860. */
-#ifdef RT2860
#define EEPROM_SIZE 0x200
/* iNIC has its own EEPROM_BIN_FILE_NAME */
#ifndef UCOS
@@ -142,7 +137,6 @@ do{ int (*org_remote_display)(char *) = NULL; \
#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2860STA/e2p.bin"
#endif // CONFIG_STA_SUPPORT //
#endif // !UCOS //
-#endif // RT2860 //
diff --git a/drivers/staging/rt2860/rt_config.h b/drivers/staging/rt2860/rt_config.h
index 7ee7a405b02..a67024fb437 100644
--- a/drivers/staging/rt2860/rt_config.h
+++ b/drivers/staging/rt2860/rt_config.h
@@ -53,9 +53,7 @@
#include "rtmp_def.h"
#include "rt28xx.h"
-#ifdef RT2860
#include "rt2860.h"
-#endif // RT2860 //
#include "oid.h"
diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c
index f14500931ef..f3c128c72a2 100644
--- a/drivers/staging/rt2860/rt_linux.c
+++ b/drivers/staging/rt2860/rt_linux.c
@@ -48,10 +48,8 @@ BUILD_TIMER_FUNCTION(LeapAuthTimeout);
#endif
BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
-#ifdef RT2860
BUILD_TIMER_FUNCTION(PsPollWakeExec);
BUILD_TIMER_FUNCTION(RadioOnExec);
-#endif // RT2860 //
#ifdef QOS_DLS_SUPPORT
BUILD_TIMER_FUNCTION(DlsTimeoutAction);
#endif // QOS_DLS_SUPPORT //
@@ -293,9 +291,7 @@ VOID RTMPFreeAdapter(
NdisFreeSpinLock(&pAd->MgmtRingLock);
-#ifdef RT2860
NdisFreeSpinLock(&pAd->RxRingLock);
-#endif // RT2860 //
for (index =0 ; index < NUM_OF_TX_RING; index++)
{
@@ -854,7 +850,7 @@ void send_monitor_packets(
if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
{
- DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
goto err_free_sk_buff;
}
@@ -1005,35 +1001,14 @@ err_free_sk_buff:
void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
{
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
allow_signal(SIGTERM);
allow_signal(SIGKILL);
current->flags |= PF_NOFREEZE;
-#else
- unsigned long flags;
-
- daemonize();
- reparent_to_init();
- strcpy(current->comm, pThreadName);
-
- siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
- /* Allow interception of SIGKILL only
- * Don't allow other signals to interrupt the transmission */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
- spin_lock_irqsave(&current->sigmask_lock, flags);
- flush_signals(current);
- recalc_sigpending(current);
- spin_unlock_irqrestore(&current->sigmask_lock, flags);
-#endif
-#endif
-
- /* signal that we've started the thread */
+ /* signal that we've started the thread */
complete(pNotify);
-
}
void RTMP_IndicateMediaState(
diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h
index 0fd58f5109f..708923cecaa 100644
--- a/drivers/staging/rt2860/rt_linux.h
+++ b/drivers/staging/rt2860/rt_linux.h
@@ -65,7 +65,6 @@
#include <linux/vmalloc.h>
-#include <linux/wireless.h>
#include <net/iw_handler.h>
// load firmware
@@ -90,28 +89,22 @@ typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_
// add by kathy
#ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
#define STA_PROFILE_PATH "/etc/Wireless/RT2860STA/RT2860STA.dat"
#define STA_RTMP_FIRMWARE_FILE_NAME "/etc/Wireless/RT2860STA/RT2860STA.bin"
#define STA_NIC_DEVICE_NAME "RT2860STA"
-#define STA_DRIVER_VERSION "1.8.0.0"
+#define STA_DRIVER_VERSION "1.8.1.1"
#ifdef MULTIPLE_CARD_SUPPORT
#define CARD_INFO_PATH "/etc/Wireless/RT2860STA/RT2860STACard.dat"
#endif // MULTIPLE_CARD_SUPPORT //
-#endif // RT2860 //
#endif // CONFIG_STA_SUPPORT //
-#ifdef RT2860
#ifndef PCI_DEVICE
#define PCI_DEVICE(vend,dev) \
.vendor = (vend), .device = (dev), \
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
#endif // PCI_DEVICE //
-#endif // RT2860 //
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#define RTMP_TIME_AFTER(a,b) \
(typecheck(unsigned long, (unsigned long)a) && \
@@ -123,11 +116,7 @@ typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_
typecheck(unsigned long, (unsigned long)b) && \
((long)(a) - (long)(b) >= 0))
#define RTMP_TIME_BEFORE(a,b) RTMP_TIME_AFTER_EQ(b,a)
-#else
-#define RTMP_TIME_AFTER(a,b) time_after(a, b)
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#define RT_MOD_INC_USE_COUNT() \
if (!try_module_get(THIS_MODULE)) \
{ \
@@ -136,10 +125,6 @@ typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_
}
#define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE);
-#else
-#define RT_MOD_INC_USE_COUNT() MOD_INC_USE_COUNT;
-#define RT_MOD_DEC_USE_COUNT() MOD_DEC_USE_COUNT;
-#endif
#define OS_HZ HZ
@@ -171,21 +156,12 @@ typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_
#define NDIS_PACKET_TYPE_ALL_MULTICAST 3
#endif // CONFIG_STA_SUPPORT //
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
typedef struct pid * THREAD_PID;
#define THREAD_PID_INIT_VALUE NULL
#define GET_PID(_v) find_get_pid(_v)
#define GET_PID_NUMBER(_v) pid_nr(_v)
#define CHECK_PID_LEGALITY(_pid) if (pid_nr(_pid) >= 0)
#define KILL_THREAD_PID(_A, _B, _C) kill_pid(_A, _B, _C)
-#else
-typedef pid_t THREAD_PID;
-#define THREAD_PID_INIT_VALUE -1
-#define GET_PID(_v) _v
-#define GET_PID_NUMBER(_v) _v
-#define CHECK_PID_LEGALITY(_pid) if (_pid >= 0)
-#define KILL_THREAD_PID(_A, _B, _C) kill_proc(_A, _B, _C)
-#endif
struct os_lock {
spinlock_t lock;
@@ -194,11 +170,9 @@ struct os_lock {
struct os_cookie {
-#ifdef RT2860
struct pci_dev *pci_dev;
struct pci_dev *parent_pci_dev;
dma_addr_t pAd_pa;
-#endif // RT2860 //
struct tasklet_struct rx_done_task;
@@ -209,9 +183,7 @@ struct os_cookie {
struct tasklet_struct ac3_dma_done_task;
struct tasklet_struct hcca_dma_done_task;
struct tasklet_struct tbtt_task;
-#ifdef RT2860
struct tasklet_struct fifo_statistic_full_task;
-#endif // RT2860 //
unsigned long apd_pid; //802.1x daemon pid
@@ -266,7 +238,6 @@ void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int
#define RT2860_PCI_DEVICE_ID 0x0601
-#ifdef RT2860
#define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \
linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir)
@@ -281,7 +252,6 @@ void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int
#define DEV_ALLOC_SKB(_length) \
dev_alloc_skb(_length)
-#endif // RT2860 //
@@ -401,7 +371,6 @@ extern ULONG RTDebugLevel;
spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag)); \
}
-#ifdef RT2860
#if defined(INF_TWINPASS) || defined(INF_DANUBE) || defined(IKANOS_VX_1X0)
//Patch for ASIC turst read/write bug, needs to remove after metel fix
#define RTMP_IO_READ32(_A, _R, _pV) \
@@ -413,6 +382,12 @@ extern ULONG RTDebugLevel;
(*_pV = SWAP32(*((UINT32 *)(_pV)))); \
} \
}
+#define RTMP_IO_FORCE_READ32(_A, _R, _pV) \
+{ \
+ (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \
+ (*_pV = readl((void *)((_A)->CSRBaseAddress + (_R)))); \
+ (*_pV = SWAP32(*((UINT32 *)(_pV)))); \
+}
#define RTMP_IO_READ8(_A, _R, _pV) \
{ \
(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \
@@ -452,6 +427,11 @@ extern ULONG RTDebugLevel;
else \
*_pV = 0; \
}
+#define RTMP_IO_FORCE_READ32(_A, _R, _pV) \
+{ \
+ (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \
+ (*_pV = readl((void *)((_A)->CSRBaseAddress + (_R)))); \
+}
#define RTMP_IO_READ8(_A, _R, _pV) \
{ \
(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \
@@ -492,7 +472,6 @@ extern ULONG RTDebugLevel;
writew((_V), (PUSHORT)((_A)->CSRBaseAddress + (_R))); \
}
#endif
-#endif // RT2860 //
#ifndef wait_event_interruptible_timeout
@@ -544,7 +523,6 @@ typedef void (*TIMER_FUNCTION)(unsigned long);
#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
#define MlmeFreeMemory(_pAd, _pVA) os_free_mem(_pAd, _pVA)
-#ifdef RT2860
#define BUILD_TIMER_FUNCTION(_func) \
void linux_##_func(unsigned long data) \
{ \
@@ -554,7 +532,6 @@ void linux_##_func(unsigned long data) \
if (pTimer->Repeat) \
RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); \
}
-#endif // RT2860 //
@@ -907,7 +884,6 @@ int rt28xx_packet_xmit(struct sk_buff *skb);
void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify);
-#ifdef RT2860
#if !defined(PCI_CAP_ID_EXP)
#define PCI_CAP_ID_EXP 0x10
#endif
@@ -921,6 +897,5 @@ void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify);
#endif
#define PCIBUS_INTEL_VENDOR 0x8086
-#endif // RT2860 //
diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c
index 3873c478f4e..cf17bcdd733 100644
--- a/drivers/staging/rt2860/rt_main_dev.c
+++ b/drivers/staging/rt2860/rt_main_dev.c
@@ -58,11 +58,7 @@ UINT32 CW_MAX_IN_BITS;
char *mac = ""; // default 00:00:00:00:00:00
char *hostname = ""; // default CMPC
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
-MODULE_PARM (mac, "s");
-#else
module_param (mac, charp, 0);
-#endif
MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
@@ -75,9 +71,7 @@ extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
#endif // DOT11_N_SUPPORT //
extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd);
-#ifdef RT2860
extern void init_thread_task(PRTMP_ADAPTER pAd);
-#endif // RT2860 //
// public function prototype
INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
@@ -87,13 +81,6 @@ INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
static int rt28xx_init(IN struct net_device *net_dev);
INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
-#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
-struct net_device *alloc_netdev(
- int sizeof_priv,
- const char *mask,
- void (*setup)(struct net_device *));
-#endif // LINUX_VERSION_CODE //
-
static void CfgInitHook(PRTMP_ADAPTER pAd);
#ifdef CONFIG_STA_SUPPORT
@@ -235,15 +222,13 @@ int rt28xx_close(IN PNET_DEV dev)
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
-#ifdef RT2860
- RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
-#endif // RT2860 //
-
// If dirver doesn't wake up firmware here,
// NICLoadFirmware will hang forever when interface is up again.
- if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
{
- AsicForceWakeup(pAd, TRUE);
+ AsicForceWakeup(pAd, RTMP_HALT);
}
#ifdef QOS_DLS_SUPPORT
@@ -323,9 +308,7 @@ int rt28xx_close(IN PNET_DEV dev)
#endif // WPA_SUPPLICANT_SUPPORT //
MlmeRadioOff(pAd);
-#ifdef RT2860
pAd->bPCIclkOff = FALSE;
-#endif // RT2860 //
}
#endif // CONFIG_STA_SUPPORT //
@@ -359,7 +342,6 @@ int rt28xx_close(IN PNET_DEV dev)
TpcReqTabExit(pAd);
-#ifdef RT2860
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
{
NICDisableInterrupt(pAd);
@@ -375,7 +357,6 @@ int rt28xx_close(IN PNET_DEV dev)
RT28XX_IRQ_RELEASE(net_dev)
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
}
-#endif // RT2860 //
// Free Ring or USB buffers
@@ -439,12 +420,10 @@ static int rt28xx_init(IN struct net_device *net_dev)
// Disable interrupts here which is as soon as possible
// This statement should never be true. We might consider to remove it later
-#ifdef RT2860
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
{
NICDisableInterrupt(pAd);
}
-#endif // RT2860 //
Status = RTMPAllocTxRxRingMemory(pAd);
if (Status != NDIS_STATUS_SUCCESS)
@@ -667,26 +646,6 @@ int rt28xx_open(IN PNET_DEV dev)
#endif // WIRELESS_EXT >= 12 //
#endif // CONFIG_APSTA_MIXED_SUPPORT //
-#ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
- IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
- {
- // If dirver doesn't wake up firmware here,
- // NICLoadFirmware will hang forever when interface is up again.
- // RT2860 PCI
- if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) &&
- OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
- {
- AUTO_WAKEUP_STRUC AutoWakeupCfg;
- AsicForceWakeup(pAd, TRUE);
- AutoWakeupCfg.word = 0;
- RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
- OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
- }
- }
-#endif // RT2860 //
-#endif // CONFIG_STA_SUPPORT //
-
// Init
pObj = (POS_COOKIE)pAd->OS_Cookie;
@@ -753,10 +712,8 @@ int rt28xx_open(IN PNET_DEV dev)
}
#ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
RTMPInitPCIeLinkCtrlValue(pAd);
-#endif // RT2860 //
#endif // CONFIG_STA_SUPPORT //
return (retval);
@@ -808,9 +765,7 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p
dev->stop = MainVirtualIF_close; //rt28xx_close;
dev->priv_flags = INT_MAIN;
dev->do_ioctl = rt28xx_ioctl;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
- dev->validate_addr = NULL;
-#endif
+ dev->validate_addr = NULL;
// find available device name
for (i = 0; i < 8; i++)
{
@@ -821,25 +776,11 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p
#endif // MULTIPLE_CARD_SUPPORT //
sprintf(slot_name, "ra%d", i);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
- device = dev_get_by_name(dev_net(dev), slot_name);
-#else
- device = dev_get_by_name(dev->nd_net, slot_name);
-#endif
-#else
- device = dev_get_by_name(slot_name);
-#endif
- if (device != NULL) dev_put(device);
-#else
- for (device = dev_base; device != NULL; device = device->next)
- {
- if (strncmp(device->name, slot_name, 4) == 0)
- break;
- }
-#endif
- if(device == NULL)
+ device = dev_get_by_name(dev_net(dev), slot_name);
+ if (device != NULL)
+ dev_put(device);
+
+ if (device == NULL)
break;
}
@@ -1252,47 +1193,28 @@ INT __devinit rt28xx_probe(
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) NULL;
INT status;
PVOID handle;
-#ifdef RT2860
struct pci_dev *dev_p = (struct pci_dev *)_dev_p;
-#endif // RT2860 //
#ifdef CONFIG_STA_SUPPORT
DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
#endif // CONFIG_STA_SUPPORT //
-#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
- net_dev = alloc_netdev(sizeof(PRTMP_ADAPTER), "eth%d", ether_setup);
-#else
net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER));
-#endif
if (net_dev == NULL)
{
printk("alloc_netdev failed\n");
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
- module_put(THIS_MODULE);
-#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
-#else
- MOD_DEC_USE_COUNT;
-#endif
goto err_out;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
- SET_MODULE_OWNER(net_dev);
-#endif
-
netif_stop_queue(net_dev);
#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
/* for supporting Network Manager */
/* Set the sysfs physical device reference for the network logical device
* if set prior to registration will cause a symlink during initialization.
*/
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
SET_NETDEV_DEV(net_dev, &(dev_p->dev));
-#endif
#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
// Allocate RTMP_ADAPTER miniport adapter structure
@@ -1313,13 +1235,8 @@ INT __devinit rt28xx_probe(
#endif // CONFIG_STA_SUPPORT //
// Post config
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- if (RT28XXProbePostConfig(_dev_p, pAd, argc) == FALSE)
- goto err_out_unmap;
-#else
if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE)
goto err_out_unmap;
-#endif // LINUX_VERSION_CODE //
#ifdef CONFIG_STA_SUPPORT
pAd->OpMode = OPMODE_STA;
@@ -1362,20 +1279,12 @@ err_out_unmap:
RT28XX_UNMAP();
err_out_free_netdev:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- free_netdev(net_dev);
-#else
- kfree(net_dev);
-#endif
+ free_netdev(net_dev);
err_out:
RT28XX_PUT_DEVICE(dev_p);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- return (LONG)NULL;
-#else
- return -ENODEV; /* probe fail */
-#endif // LINUX_VERSION_CODE //
+ return -ENODEV; /* probe fail */
} /* End of rt28xx_probe */
@@ -1495,40 +1404,6 @@ INT rt28xx_send_packets(
-#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
-struct net_device *alloc_netdev(
- int sizeof_priv,
- const char *mask,
- void (*setup)(struct net_device *))
-{
- struct net_device *dev;
- INT alloc_size;
-
-
- /* ensure 32-byte alignment of the private area */
- alloc_size = sizeof (*dev) + sizeof_priv + 31;
-
- dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL);
- if (dev == NULL)
- {
- DBGPRINT(RT_DEBUG_ERROR,
- ("alloc_netdev: Unable to allocate device memory.\n"));
- return NULL;
- }
-
- memset(dev, 0, alloc_size);
-
- if (sizeof_priv)
- dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
-
- setup(dev);
- strcpy(dev->name, mask);
-
- return dev;
-}
-#endif // LINUX_VERSION_CODE //
-
-
void CfgInitHook(PRTMP_ADAPTER pAd)
{
pAd->bBroadComHT = TRUE;
diff --git a/drivers/staging/rt2860/rt_profile.c b/drivers/staging/rt2860/rt_profile.c
index 326a3cb52b9..62141f37697 100644
--- a/drivers/staging/rt2860/rt_profile.c
+++ b/drivers/staging/rt2860/rt_profile.c
@@ -1451,7 +1451,7 @@ NDIS_STATUS RTMPReadParametersHook(
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
//PSMode
- if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer))
+ if (RTMPGetKeyParameter("PSMode", tmpbuf, 32, buffer))
{
if (pAd->StaCfg.BssType == BSS_INFRA)
{
diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h
index 411954206c2..b904b7886c2 100644
--- a/drivers/staging/rt2860/rtmp.h
+++ b/drivers/staging/rt2860/rtmp.h
@@ -203,9 +203,7 @@ typedef struct _ATE_INFO {
BOOLEAN bRxFer;
BOOLEAN bQATxStart; // Have compiled QA in and use it to ATE tx.
BOOLEAN bQARxStart; // Have compiled QA in and use it to ATE rx.
-#ifdef RT2860
BOOLEAN bFWLoading; // Reload firmware when ATE is done.
-#endif // RT2860 //
UINT32 RxTotalCnt;
UINT32 RxCntPerSec;
@@ -366,6 +364,13 @@ typedef struct _QUEUE_HEADER {
#define RTMP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0)
#define RTMP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F))
+// Macro for power save flag.
+#define RTMP_SET_PSFLAG(_M, _F) ((_M)->PSFlags |= (_F))
+#define RTMP_CLEAR_PSFLAG(_M, _F) ((_M)->PSFlags &= ~(_F))
+#define RTMP_CLEAR_PSFLAGS(_M) ((_M)->PSFlags = 0)
+#define RTMP_TEST_PSFLAG(_M, _F) (((_M)->PSFlags & (_F)) != 0)
+#define RTMP_TEST_PSFLAGS(_M, _F) (((_M)->PSFlags & (_F)) == (_F))
+
#define OPSTATUS_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags |= (_F))
#define OPSTATUS_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F))
#define OPSTATUS_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0)
@@ -478,7 +483,6 @@ typedef struct _QUEUE_HEADER {
//
#define MAX_BUSY_COUNT 100 // Number of retry before failing access BBP & RF indirect register
//
-#ifdef RT2860
#define RTMP_RF_IO_WRITE32(_A, _V) \
{ \
PHY_CSR4_STRUC Value; \
@@ -642,7 +646,6 @@ typedef struct _QUEUE_HEADER {
} \
} \
}
-#endif // RT2860 //
#define MAP_CHANNEL_ID_TO_KHZ(ch, khz) { \
@@ -894,7 +897,6 @@ typedef struct _RTMP_SCATTER_GATHER_LIST {
// Enqueue this frame to MLME engine
// We need to enqueue the whole frame because MLME need to pass data type
// information from 802.11 header
-#ifdef RT2860
#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal) \
{ \
UINT32 High32TSF, Low32TSF; \
@@ -902,7 +904,6 @@ typedef struct _RTMP_SCATTER_GATHER_LIST {
RTMP_IO_READ32(_pAd, TSF_TIMER_DW0, &Low32TSF); \
MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal); \
}
-#endif // RT2860 //
#define NDIS_QUERY_BUFFER(_NdisBuf, _ppVA, _pBufLen) \
NdisQueryBuffer(_NdisBuf, _ppVA, _pBufLen)
@@ -919,9 +920,10 @@ typedef struct _RTMP_SCATTER_GATHER_LIST {
#define STA_PORT_SECURED(_pAd) \
{ \
_pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
- NdisAcquireSpinLock(&_pAd->MacTabLock); \
+ RTMP_SET_PSFLAG(_pAd, fRTMP_PS_CAN_GO_SLEEP); \
+ NdisAcquireSpinLock(&(_pAd)->MacTabLock); \
_pAd->MacTab.Content[BSSID_WCID].PortSecured = _pAd->StaCfg.PortSecured; \
- NdisReleaseSpinLock(&_pAd->MacTabLock); \
+ NdisReleaseSpinLock(&(_pAd)->MacTabLock); \
}
#endif // CONFIG_STA_SUPPORT //
@@ -1000,9 +1002,7 @@ typedef struct _RTMP_REORDERBUF
UCHAR DataOffset;
USHORT Datasize;
ULONG AllocSize;
-#ifdef RT2860
NDIS_PHYSICAL_ADDRESS AllocPa; // TxBuf physical address
-#endif // RT2860 //
} RTMP_REORDERBUF, *PRTMP_REORDERBUF;
//
@@ -1101,6 +1101,7 @@ typedef struct _COUNTER_802_11 {
typedef struct _COUNTER_RALINK {
ULONG TransmittedByteCount; // both successful and failure, used to calculate TX throughput
+ ULONG LastReceivedByteCount;
ULONG ReceivedByteCount; // both CRC okay and CRC error, used to calculate RX throughput
ULONG BeenDisassociatedCount;
ULONG BadCQIAutoRecoveryCount;
@@ -1436,11 +1437,9 @@ typedef struct _MLME_STRUCT {
RALINK_TIMER_STRUCT APSDPeriodicTimer;
RALINK_TIMER_STRUCT LinkDownTimer;
RALINK_TIMER_STRUCT LinkUpTimer;
-#ifdef RT2860
UCHAR bPsPollTimerRunning;
RALINK_TIMER_STRUCT PsPollTimer;
RALINK_TIMER_STRUCT RadioOnOffTimer;
-#endif // RT2860 //
ULONG PeriodicRound;
ULONG OneSecPeriodicRound;
@@ -2228,9 +2227,7 @@ typedef struct _STA_ADMIN_CONFIG {
RT_HT_PHY_INFO DesiredHtPhyInfo;
BOOLEAN bAutoTxRateSwitch;
-#ifdef RT2860
UCHAR BBPR3;
-#endif // RT2860 //
#ifdef EXT_BUILD_CHANNEL_LIST
UCHAR IEEE80211dClientMode;
@@ -2663,7 +2660,6 @@ typedef struct _RTMP_ADAPTER
PNET_DEV net_dev;
ULONG VirtualIfCnt;
-#ifdef RT2860
USHORT LnkCtrlBitMask;
USHORT RLnkCtrlConfiguration;
USHORT RLnkCtrlOffset;
@@ -2671,7 +2667,9 @@ typedef struct _RTMP_ADAPTER
USHORT HostLnkCtrlOffset;
USHORT PCIePowerSaveLevel;
BOOLEAN bPCIclkOff; // flag that indicate if the PICE power status in Configuration SPace..
- BOOLEAN bPCIclkOffDisableTx; //
+ ULONG CheckDmaBusyCount; // Check Interrupt Status Register Count.
+ USHORT ThisTbttNumToNextWakeUp;
+ ULONG SameRxByteCount;
/*****************************************************************************************/
@@ -2688,7 +2686,6 @@ typedef struct _RTMP_ADAPTER
RTMP_DMABUF RxDescRing; // Shared memory for RX descriptors
RTMP_DMABUF TxDescRing[NUM_OF_TX_RING]; // Shared memory for Tx descriptors
RTMP_TX_RING TxRing[NUM_OF_TX_RING]; // AC0~4 + HCCA
-#endif // RT2860 //
NDIS_SPIN_LOCK irq_lock;
@@ -2721,10 +2718,8 @@ typedef struct _RTMP_ADAPTER
/* Rx related parameters */
/*****************************************************************************************/
-#ifdef RT2860
RTMP_RX_RING RxRing;
NDIS_SPIN_LOCK RxRingLock; // Rx Ring spinlock
-#endif // RT2860 //
@@ -2895,6 +2890,7 @@ typedef struct _RTMP_ADAPTER
// flags, see fRTMP_ADAPTER_xxx flags
ULONG Flags; // Represent current device status
+ ULONG PSFlags; // Power Save operation flag.
// current TX sequence #
USHORT Sequence;
@@ -3181,7 +3177,6 @@ typedef struct _TX_BLK_
//------------------------------------------------------------------------------------------
-#ifdef RT2860
//
// Enable & Disable NIC interrupt via writing interrupt mask register
// Since it use ADAPTER structure, it have to be put after structure definition.
@@ -3214,7 +3209,6 @@ __inline VOID NICEnableInterrupt(
//RTMP_IO_WRITE32(pAd, PBF_INT_ENA, 0x00000030); // 1 : enable
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
}
-#endif // RT2860 //
#ifdef RT_BIG_ENDIAN
static inline VOID WriteBackToDescriptor(
@@ -3291,7 +3285,6 @@ static inline VOID RTMPWIEndianChange(
Call this function when read or update descriptor
========================================================================
*/
-#ifdef RT2860
static inline VOID RTMPDescriptorEndianChange(
IN PUCHAR pData,
IN ULONG DescriptorType)
@@ -3301,7 +3294,6 @@ static inline VOID RTMPDescriptorEndianChange(
*((UINT32 *)(pData +12)) = SWAP32(*((UINT32 *)(pData + 12))); // Byte 12~15
*((UINT32 *)(pData + 4)) = SWAP32(*((UINT32 *)(pData + 4))); // Byte 4~7, this must be swapped last
}
-#endif // RT2860 //
/*
========================================================================
@@ -3550,6 +3542,9 @@ NDIS_STATUS NICInitializeAsic(
IN PRTMP_ADAPTER pAd,
IN BOOLEAN bHardReset);
+VOID NICRestoreBBPValue(
+ IN PRTMP_ADAPTER pAd);
+
VOID NICIssueReset(
IN PRTMP_ADAPTER pAd);
@@ -4208,7 +4203,7 @@ VOID AsicForceSleep(
VOID AsicForceWakeup(
IN PRTMP_ADAPTER pAd,
- IN BOOLEAN bFromTx);
+ IN UCHAR Level);
#endif // CONFIG_STA_SUPPORT //
VOID AsicSetBssid(
@@ -4304,11 +4299,9 @@ BOOLEAN AsicSendCommandToMcu(
IN UCHAR Arg0,
IN UCHAR Arg1);
-#ifdef RT2860
BOOLEAN AsicCheckCommanOk(
IN PRTMP_ADAPTER pAd,
IN UCHAR Command);
-#endif // RT2860 //
VOID MacAddrRandomBssid(
IN PRTMP_ADAPTER pAd,
@@ -6978,7 +6971,6 @@ void kill_thread_task(PRTMP_ADAPTER pAd);
void tbtt_tasklet(unsigned long data);
-#ifdef RT2860
//
// Function Prototype in cmm_data_2860.c
//
@@ -7069,7 +7061,7 @@ BOOLEAN RT28xxPciAsicRadioOn(
VOID RT28xxPciStaAsicForceWakeup(
IN PRTMP_ADAPTER pAd,
- IN BOOLEAN bFromTx);
+ IN UCHAR Level);
VOID RT28xxPciStaAsicSleepThenAutoWakeup(
IN PRTMP_ADAPTER pAd,
@@ -7093,7 +7085,6 @@ VOID RT28xxPciMlmeRadioOn(
VOID RT28xxPciMlmeRadioOFF(
IN PRTMP_ADAPTER pAd);
-#endif // RT2860 //
VOID AsicTurnOffRFClk(
IN PRTMP_ADAPTER pAd,
@@ -7132,6 +7123,18 @@ PCHAR RTMPGetRalinkEncryModeStr(
#ifdef CONFIG_STA_SUPPORT
VOID AsicStaBbpTuning(
IN PRTMP_ADAPTER pAd);
+
+VOID AsicResetFromDMABusy(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicResetBBP(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicResetMAC(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicResetPBF(
+ IN PRTMP_ADAPTER pAd);
#endif // CONFIG_STA_SUPPORT //
void RTMP_IndicateMediaState(
diff --git a/drivers/staging/rt2860/rtmp_def.h b/drivers/staging/rt2860/rtmp_def.h
index be982147883..25a53d83a0d 100644
--- a/drivers/staging/rt2860/rtmp_def.h
+++ b/drivers/staging/rt2860/rtmp_def.h
@@ -111,7 +111,6 @@
// Entry number for each DMA descriptor ring
//
-#ifdef RT2860
#define TX_RING_SIZE 64 //64
#define MGMT_RING_SIZE 128
#define RX_RING_SIZE 128 //64
@@ -119,7 +118,6 @@
#define MAX_DMA_DONE_PROCESS TX_RING_SIZE
#define MAX_TX_DONE_PROCESS TX_RING_SIZE //8
#define LOCAL_TXBUF_SIZE 2
-#endif // RT2860 //
#ifdef MULTIPLE_CARD_SUPPORT
@@ -212,6 +210,19 @@
#define fOP_STATUS_WAKEUP_NOW 0x00008000
#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE 0x00020000
+//
+// RTMP_ADAPTER PSFlags : related to advanced power save.
+//
+// Indicate whether driver can go to sleep mode from now. This flag is useful AFTER link up
+#define fRTMP_PS_CAN_GO_SLEEP 0x00000001
+// Indicate whether driver has issue a LinkControl command to PCIe L1
+#define fRTMP_PS_SET_PCI_CLK_OFF_COMMAND 0x00000002
+// Indicate driver should disable kick off hardware to send packets from now.
+#define fRTMP_PS_DISABLE_TX 0x00000004
+// Indicate driver should IMMEDIATELY fo to sleep after receiving AP's beacon in which doesn't indicate unicate nor multicast packets for me
+//. This flag is used ONLY in RTMPHandleRxDoneInterrupt routine.
+#define fRTMP_PS_GO_TO_SLEEP_NOW 0x00000008
+
#ifdef DOT11N_DRAFT3
#define fOP_STATUS_SCAN_2040 0x00040000
#endif // DOT11N_DRAFT3 //
@@ -1514,12 +1525,14 @@
#define MCAST_HTMIX 3
#endif // MCAST_RATE_SPECIFIC //
-// For AsicRadioOff/AsicRadioOn function
-#define DOT11POWERSAVE 0
-#define GUIRADIO_OFF 1
-#define RTMP_HALT 2
-#define GUI_IDLE_POWER_SAVE 3
-// --
+// For AsicRadioOff/AsicRadioOn/AsicForceWakeup function
+// This is to indicate from where to call this function.
+#define DOT11POWERSAVE 0 // TO do .11 power save sleep
+#define GUIRADIO_OFF 1 // To perform Radio OFf command from GUI
+#define RTMP_HALT 2 // Called from Halt handler.
+#define GUI_IDLE_POWER_SAVE 3 // Call to sleep before link up with AP
+#define FROM_TX 4 // Force wake up from Tx packet.
+
// definition for WpaSupport flag
diff --git a/drivers/staging/rt2860/sta/assoc.c b/drivers/staging/rt2860/sta/assoc.c
index 42db753eed7..34f1c1490f4 100644
--- a/drivers/staging/rt2860/sta/assoc.c
+++ b/drivers/staging/rt2860/sta/assoc.c
@@ -473,12 +473,7 @@ VOID MlmeAssocReqAction(
RSNIe = IE_WPA2;
}
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifdef SIOCSIWGENIE
- if (pAd->StaCfg.WpaSupplicantUP != 1)
-#endif // SIOCSIWGENIE //
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
- RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
+ RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
// Check for WPA PMK cache list
if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
@@ -504,17 +499,6 @@ VOID MlmeAssocReqAction(
}
}
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifdef SIOCSIWGENIE
- if (pAd->StaCfg.WpaSupplicantUP == 1)
- {
- MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
- pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
- END_OF_ARGS);
- }
- else
-#endif
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
{
MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1, &RSNIe,
@@ -525,11 +509,6 @@ VOID MlmeAssocReqAction(
FrameLen += tmp;
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifdef SIOCSIWGENIE
- if (pAd->StaCfg.WpaSupplicantUP != 1)
-#endif
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
{
// Append Variable IE
NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
diff --git a/drivers/staging/rt2860/sta/connect.c b/drivers/staging/rt2860/sta/connect.c
index 36f28f8b4aa..d8bcc76688a 100644
--- a/drivers/staging/rt2860/sta/connect.c
+++ b/drivers/staging/rt2860/sta/connect.c
@@ -337,6 +337,10 @@ VOID CntlOidSsidProc(
MLME_DISASSOC_REQ_STRUCT DisassocReq;
ULONG Now;
+ // BBP and RF are not accessible in PS mode, we has to wake them up first
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ AsicForceWakeup(pAd, RTMP_HALT);
+
// Step 1. record the desired user settings to MlmeAux
NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
@@ -1240,6 +1244,13 @@ VOID LinkUp(
UCHAR Value = 0, idx;
MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
+ if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
+ {
+ RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
+ RTMPusecDelay(6000);
+ pAd->bPCIclkOff = FALSE;
+ }
+
pEntry = &pAd->MacTab.Content[BSSID_WCID];
//
@@ -1264,7 +1275,6 @@ VOID LinkUp(
//rt2860b. Don't know why need this
SwitchBetweenWepAndCkip(pAd);
-#ifdef RT2860
// Before power save before link up function, We will force use 1R.
// So after link up, check Rx antenna # again.
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
@@ -1282,7 +1292,6 @@ VOID LinkUp(
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
pAd->StaCfg.BBPR3 = Value;
-#endif // RT2860 //
if (BssType == BSS_ADHOC)
{
@@ -1330,9 +1339,7 @@ VOID LinkUp(
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
Value &= (~0x20);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RT2860
pAd->StaCfg.BBPR3 = Value;
-#endif // RT2860 //
RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
Data &= 0xfffffffe;
@@ -1367,9 +1374,7 @@ VOID LinkUp(
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
Value |= (0x20);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RT2860
pAd->StaCfg.BBPR3 = Value;
-#endif // RT2860 //
if (pAd->MACVersion == 0x28600100)
{
@@ -1400,9 +1405,7 @@ VOID LinkUp(
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
Value &= (~0x20);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RT2860
pAd->StaCfg.BBPR3 = Value;
-#endif // RT2860 //
if (pAd->MACVersion == 0x28600100)
{
@@ -1598,6 +1601,8 @@ VOID LinkUp(
IV = 0;
IV |= (pAd->StaCfg.DefaultKeyId << 30);
AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
+
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
}
// NOTE:
// the decision of using "short slot time" or not may change dynamically due to
@@ -1919,6 +1924,7 @@ VOID LinkUp(
}
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
#ifdef DOT11_N_SUPPORT
#ifdef DOT11N_DRAFT3
@@ -1961,6 +1967,7 @@ VOID LinkDown(
IN BOOLEAN IsReqFromAP)
{
UCHAR i, ByteValue = 0;
+ BOOLEAN Cancelled;
// Do nothing if monitor mode is on
if (MONITOR_ON(pAd))
@@ -1972,6 +1979,12 @@ VOID LinkDown(
return;
#endif // RALINK_ATE //
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
+ RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
+
+ // Not allow go to sleep within linkdown function.
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+
if (pAd->CommonCfg.bWirelessEvent)
{
RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
@@ -1980,7 +1993,6 @@ VOID LinkDown(
DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
-#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
BOOLEAN Cancelled;
@@ -1988,17 +2000,15 @@ VOID LinkDown(
RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
}
- if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
+ RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
{
- AUTO_WAKEUP_STRUC AutoWakeupCfg;
- AsicForceWakeup(pAd, TRUE);
- AutoWakeupCfg.word = 0;
- RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+ AsicForceWakeup(pAd, RTMP_HALT);
OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
}
pAd->bPCIclkOff = FALSE;
-#endif // RT2860 //
if (ADHOC_ON(pAd)) // Adhoc mode link down
{
DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
@@ -2266,6 +2276,9 @@ VOID LinkDown(
RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+ // Allow go to sleep after linkdown steps.
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+
#ifdef WPA_SUPPLICANT_SUPPORT
#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
if (pAd->StaCfg.WpaSupplicantUP) {
@@ -2510,7 +2523,6 @@ VOID AuthParmFill(
==========================================================================
*/
-#ifdef RT2860
VOID ComposePsPoll(
IN PRTMP_ADAPTER pAd)
{
@@ -2534,7 +2546,6 @@ VOID ComposeNullFrame(
COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
}
-#endif // RT2860 //
diff --git a/drivers/staging/rt2860/sta/dls.c b/drivers/staging/rt2860/sta/dls.c
index 78fb28976fd..873cf7f1de9 100644
--- a/drivers/staging/rt2860/sta/dls.c
+++ b/drivers/staging/rt2860/sta/dls.c
@@ -1419,7 +1419,6 @@ BOOLEAN RTMPRcvFrameDLSCheck(
//AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
//AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
// Add Pair-wise key to Asic
-#ifdef RT2860
AsicAddPairwiseKeyEntry(pAd,
pAd->StaCfg.DLSEntry[i].MacAddr,
(UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
@@ -1431,7 +1430,6 @@ BOOLEAN RTMPRcvFrameDLSCheck(
PairwiseKey.CipherAlg,
pEntry);
-#endif // RT2860 //
NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
@@ -1477,7 +1475,6 @@ BOOLEAN RTMPRcvFrameDLSCheck(
//AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
//AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
// Add Pair-wise key to Asic
-#ifdef RT2860
AsicAddPairwiseKeyEntry(pAd,
pAd->StaCfg.DLSEntry[i].MacAddr,
(UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
@@ -1488,7 +1485,6 @@ BOOLEAN RTMPRcvFrameDLSCheck(
0,
PairwiseKey.CipherAlg,
pEntry);
-#endif // RT2860 //
NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
diff --git a/drivers/staging/rt2860/sta/rtmp_data.c b/drivers/staging/rt2860/sta/rtmp_data.c
index 36aff247cd9..c5e76a2da56 100644
--- a/drivers/staging/rt2860/sta/rtmp_data.c
+++ b/drivers/staging/rt2860/sta/rtmp_data.c
@@ -75,7 +75,6 @@ VOID STARxEAPOLFrameIndicate(
if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0)
{
-#ifdef RT2860
MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[BSSID_WCID];
// Set key material and cipherAlg to Asic
@@ -89,7 +88,6 @@ VOID STARxEAPOLFrameIndicate(
pAd->IndicateMediaState = NdisMediaStateConnected;
pAd->ExtraInfo = GENERAL_LINK_UP;
-#endif // RT2860 //
// For Preventing ShardKey Table is cleared by remove key procedure.
pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg;
pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen;
@@ -693,14 +691,12 @@ BOOLEAN STARxDoneInterruptHandle(
break;
}
-#ifdef RT2860
if (RxProcessed++ > MAX_RX_PROCESS_CNT)
{
// need to reschedule rx handle
bReschedule = TRUE;
break;
}
-#endif // RT2860 //
RxProcessed ++; // test
@@ -811,6 +807,13 @@ BOOLEAN STARxDoneInterruptHandle(
}
}
+ // fRTMP_PS_GO_TO_SLEEP_NOW is set if receiving beacon.
+ if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW) && (INFRA_ON(pAd)))
+ {
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
+ AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp);
+ bReschedule = FALSE;
+ }
return bReschedule;
}
@@ -828,7 +831,7 @@ BOOLEAN STARxDoneInterruptHandle(
VOID RTMPHandleTwakeupInterrupt(
IN PRTMP_ADAPTER pAd)
{
- AsicForceWakeup(pAd, FALSE);
+ AsicForceWakeup(pAd, DOT11POWERSAVE);
}
/*
@@ -1220,7 +1223,6 @@ NDIS_STATUS STASendPacket(
========================================================================
*/
-#ifdef RT2860
NDIS_STATUS RTMPFreeTXDRequest(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
@@ -1264,7 +1266,6 @@ NDIS_STATUS RTMPFreeTXDRequest(
return (Status);
}
-#endif // RT2860 //
@@ -1889,7 +1890,8 @@ VOID STA_AMPDU_Frame_Tx(
//
// Kick out Tx
//
- HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+ if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
pAd->RalinkCounters.KickTxCount++;
pAd->RalinkCounters.OneSecTxDoneCount++;
@@ -2019,7 +2021,8 @@ VOID STA_AMSDU_Frame_Tx(
//
// Kick out Tx
//
- HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+ if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
}
#endif // DOT11_N_SUPPORT //
@@ -2139,7 +2142,8 @@ VOID STA_Legacy_Frame_Tx(
//
// Kick out Tx
//
- HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+ if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
}
@@ -2249,7 +2253,8 @@ VOID STA_ARalink_Frame_Tx(
//
// Kick out Tx
//
- HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+ if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
}
@@ -2526,7 +2531,7 @@ NDIS_STATUS STAHardTransmit(
if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
{
DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicForceWakeup At HardTx\n"));
- AsicForceWakeup(pAd, TRUE);
+ AsicForceWakeup(pAd, FROM_TX);
}
// It should not change PSM bit, when APSD turn on.
diff --git a/drivers/staging/rt2860/sta/sync.c b/drivers/staging/rt2860/sta/sync.c
index d196f85395c..148037a79d5 100644
--- a/drivers/staging/rt2860/sta/sync.c
+++ b/drivers/staging/rt2860/sta/sync.c
@@ -228,7 +228,6 @@ VOID MlmeScanReqAction(
// Increase the scan retry counters.
pAd->StaCfg.ScanCnt++;
-#ifdef RT2860
if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
(IDLE_ON(pAd)) &&
(pAd->StaCfg.bRadio == TRUE) &&
@@ -236,7 +235,6 @@ VOID MlmeScanReqAction(
{
RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
}
-#endif // RT2860 //
// first check the parameter sanity
if (MlmeScanReqSanity(pAd,
@@ -349,7 +347,6 @@ VOID MlmeJoinReqAction(
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
-#ifdef RT2860
if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
(IDLE_ON(pAd)) &&
(pAd->StaCfg.bRadio == TRUE) &&
@@ -357,7 +354,6 @@ VOID MlmeJoinReqAction(
{
RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
}
-#endif // RT2860 //
// reset all the timers
RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
@@ -1532,13 +1528,10 @@ VOID PeerBeacon(
// 5. otherwise, put PHY back to sleep to save battery.
if (MessageToMe)
{
-#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
- // Turn clk to 80Mhz.
}
-#endif // RT2860 //
if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
{
@@ -1549,12 +1542,10 @@ VOID PeerBeacon(
}
else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
{
-#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
}
-#endif // RT2860 //
}
else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) ||
(pAd->TxSwQueue[QID_AC_BE].Number != 0) ||
@@ -1568,12 +1559,10 @@ VOID PeerBeacon(
{
// TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
// can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
-#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
}
-#endif // RT2860 //
}
else
{
@@ -1588,7 +1577,10 @@ VOID PeerBeacon(
if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
{
- AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+ // Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode.
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
+ pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp;
+ //AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
}
}
}
diff --git a/drivers/staging/rt2860/sta/wpa.c b/drivers/staging/rt2860/sta/wpa.c
index 774c6567ae5..2609d845fd5 100644
--- a/drivers/staging/rt2860/sta/wpa.c
+++ b/drivers/staging/rt2860/sta/wpa.c
@@ -1384,6 +1384,10 @@ VOID WpaGroupMsg1Action(
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128;
//hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
}
@@ -1760,7 +1764,7 @@ BOOLEAN ParseKeyData(
// Get GTK length - refer to IEEE 802.11i-2004 p.82
GTKLEN = pKDE->Len -6;
- if (GTKLEN < LEN_AES_KEY)
+ if (GTKLEN < MIN_LEN_OF_GTK)
{
DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
return FALSE;
@@ -1786,6 +1790,10 @@ BOOLEAN ParseKeyData(
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128;
return TRUE;
diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c
index 3ea2b2c4ab0..c5452f152a2 100644
--- a/drivers/staging/rt2860/sta_ioctl.c
+++ b/drivers/staging/rt2860/sta_ioctl.c
@@ -49,15 +49,9 @@ extern ULONG RTDebugLevel;
#define GROUP_KEY_NO 4
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E) iwe_stream_add_event(_A, _B, _C, _D, _E)
#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E) iwe_stream_add_point(_A, _B, _C, _D, _E)
#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_A, _B, _C, _D, _E, _F)
-#else
-#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E) iwe_stream_add_event(_B, _C, _D, _E)
-#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E) iwe_stream_add_point(_B, _C, _D, _E)
-#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_B, _C, _D, _E, _F)
-#endif
extern UCHAR CipherWpa2Template[];
extern UCHAR CipherWpaPskTkip[];
@@ -358,6 +352,20 @@ VOID RTMPAddKey(
DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+ if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
+ {
+ if (pAd->StaCfg.bRadio == FALSE)
+ {
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+ return;
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
+ RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
+ RTMPusecDelay(6000);
+ pAd->bPCIclkOff = FALSE;
+ }
+
if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
{
if (pKey->KeyIndex & 0x80000000)
@@ -551,6 +559,8 @@ VOID RTMPAddKey(
}
}
end:
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+ DBGPRINT(RT_DEBUG_INFO, ("<------ RTMPAddKey\n"));
return;
}
@@ -573,9 +583,7 @@ rt_ioctl_giwname(struct net_device *dev,
{
// PRTMP_ADAPTER pAdapter = dev->ml_priv;
-#ifdef RT2860
strncpy(name, "RT2860 Wireless", IFNAMSIZ);
-#endif // RT2860 //
return 0;
}
@@ -670,11 +678,9 @@ int rt_ioctl_siwmode(struct net_device *dev,
case IW_MODE_INFRA:
Set_NetworkType_Proc(pAdapter, "Infra");
break;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
case IW_MODE_MONITOR:
Set_NetworkType_Proc(pAdapter, "Monitor");
break;
-#endif
default:
DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
return -EINVAL;
@@ -715,12 +721,10 @@ int rt_ioctl_giwmode(struct net_device *dev,
*mode = IW_MODE_ADHOC;
else if (INFRA_ON(pAdapter))
*mode = IW_MODE_INFRA;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
else if (MONITOR_ON(pAdapter))
{
*mode = IW_MODE_MONITOR;
}
-#endif
else
*mode = IW_MODE_AUTO;
@@ -1038,6 +1042,15 @@ int rt_ioctl_siwscan(struct net_device *dev,
return -EINVAL;
}
+ if ((pAdapter->OpMode == OPMODE_STA) && (IDLE_ON(pAdapter))
+ && (pAdapter->StaCfg.bRadio == TRUE)
+ && (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
+ {
+ RT28xxPciAsicRadioOn(pAdapter, GUI_IDLE_POWER_SAVE);
+ }
+ // Check if still radio off.
+ else if (pAdapter->bPCIclkOff == TRUE)
+ return 0;
#ifdef WPA_SUPPLICANT_SUPPORT
if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
@@ -1756,7 +1769,7 @@ int rt_ioctl_siwencode(struct net_device *dev,
}
else
/* Don't complain if only change the mode */
- if(!erq->flags & IW_ENCODE_MODE) {
+ if (!(erq->flags & IW_ENCODE_MODE)) {
return -EINVAL;
}
}
@@ -2161,12 +2174,6 @@ rt_private_show(struct net_device *dev, struct iw_request_info *info,
wrq->length = strlen(extra) + 1; // 1: size of '\0'
break;
case RAIO_ON:
- if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
- {
- sprintf(extra, "Scanning\n");
- wrq->length = strlen(extra) + 1; // 1: size of '\0'
- break;
- }
pAd->StaCfg.bSwRadio = TRUE;
//if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
{
@@ -2450,6 +2457,20 @@ void fnSetCipherKey(
IN BOOLEAN bGTK,
IN struct iw_encode_ext *ext)
{
+ RTMP_CLEAR_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
+ if (RTMP_TEST_PSFLAG(pAdapter, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
+ {
+ if (pAdapter->StaCfg.bRadio == FALSE)
+ {
+ RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
+ return;
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
+ RTMPPCIeLinkCtrlValueRestore(pAdapter, RESTORE_HALT);
+ RTMPusecDelay(6000);
+ pAdapter->bPCIclkOff = FALSE;
+ }
+
NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
@@ -2480,6 +2501,8 @@ void fnSetCipherKey(
keyIdx,
pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
&pAdapter->MacTab.Content[BSSID_WCID]);
+
+ RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
}
int rt_ioctl_siwencodeext(struct net_device *dev,
@@ -2544,6 +2567,21 @@ int rt_ioctl_siwencodeext(struct net_device *dev,
NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
+
+ if (pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled ||
+ pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
+ {
+ // Set Group key material to Asic
+ AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, pAdapter->SharedKey[BSS0][keyIdx].Key, NULL, NULL);
+
+ // Update WCID attribute table and IVEIV table for this group key table
+ RTMPAddWcidAttributeEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, NULL);
+
+ STA_PORT_SECURED(pAdapter);
+
+ // Indicate Connected for GUI
+ pAdapter->IndicateMediaState = NdisMediaStateConnected;
+ }
break;
case IW_ENCODE_ALG_TKIP:
DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __func__, keyIdx, ext->key_len));
@@ -4259,7 +4297,23 @@ INT RTMPSetInformation(
}
#ifdef WPA_SUPPLICANT_SUPPORT
- if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
+ if ((pAdapter->StaCfg.WpaSupplicantUP != 0) &&
+ (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
+ {
+ Key = pWepKey->KeyMaterial;
+
+ // Set Group key material to Asic
+ AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
+
+ // Update WCID attribute table and IVEIV table for this group key table
+ RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
+
+ STA_PORT_SECURED(pAdapter);
+
+ // Indicate Connected for GUI
+ pAdapter->IndicateMediaState = NdisMediaStateConnected;
+ }
+ else if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
#endif // WPA_SUPPLICANT_SUPPORT
{
Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
@@ -5265,7 +5319,6 @@ INT RTMPQueryInformation(
case RT_OID_802_11_PRODUCTID:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
-#ifdef RT2860
{
USHORT device_id;
@@ -5275,7 +5328,6 @@ INT RTMPQueryInformation(
DBGPRINT(RT_DEBUG_TRACE, (" pci_dev = NULL\n"));
sprintf(tmp, "%04x %04x\n", NIC_PCI_VENDOR_ID, device_id);
}
-#endif // RT2860 //
wrq->u.data.length = strlen(tmp);
Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
break;
diff --git a/drivers/staging/rt2860/wpa.h b/drivers/staging/rt2860/wpa.h
index 88c7c8bf3fc..0134ae6097c 100644
--- a/drivers/staging/rt2860/wpa.h
+++ b/drivers/staging/rt2860/wpa.h
@@ -90,6 +90,7 @@
#define TKIP_AP_RXMICK_OFFSET (TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK)
#define TKIP_GTK_LENGTH ((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
#define LEN_PTK ((LEN_EAP_KEY)+(LEN_TKIP_KEY))
+#define MIN_LEN_OF_GTK 5
// RSN IE Length definition
#define MAX_LEN_OF_RSNIE 90
diff --git a/drivers/staging/rt2870/2870_main_dev.c b/drivers/staging/rt2870/2870_main_dev.c
index 04c764d95d7..9d59e3167fe 100644
--- a/drivers/staging/rt2870/2870_main_dev.c
+++ b/drivers/staging/rt2870/2870_main_dev.c
@@ -265,7 +265,7 @@ INT MlmeThread(
*/
DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
- pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
+ pObj->MLMEThr_task = NULL;
complete_and_exit (&pAd->mlmeComplete, 0);
return 0;
@@ -373,7 +373,7 @@ INT RTUSBCmdThread(
*/
DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
- pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
+ pObj->RTUSBCmdThr_task = NULL;
complete_and_exit (&pAd->CmdQComplete, 0);
return 0;
@@ -467,7 +467,7 @@ INT TimerQThread(
*/
DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
- pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE;
+ pObj->TimerQThr_task = NULL;
complete_and_exit(&pAd->TimerQComplete, 0);
return 0;
@@ -944,69 +944,46 @@ VOID RT28xxThreadTerminate(
RTUSBCancelPendingIRPs(pAd);
// Terminate Threads
- CHECK_PID_LEGALITY(pObj->TimerQThr_pid)
+ BUG_ON(pObj->TimerQThr_task == NULL);
+ CHECK_PID_LEGALITY(task_pid(pObj->TimerQThr_task))
{
POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
- printk("Terminate the TimerQThr_pid=%d!\n", GET_PID_NUMBER(pObj->TimerQThr_pid));
+ printk(KERN_DEBUG "Terminate the TimerQThr pid=%d!\n",
+ pid_nr(task_pid(pObj->TimerQThr_task)));
mb();
pAd->TimerFunc_kill = 1;
mb();
- ret = KILL_THREAD_PID(pObj->TimerQThr_pid, SIGTERM, 1);
- if (ret)
- {
- printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
- pAd->net_dev->name, GET_PID_NUMBER(pObj->TimerQThr_pid), ret);
- }
- else
- {
- wait_for_completion(&pAd->TimerQComplete);
- pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE;
- }
+ kthread_stop(pObj->TimerQThr_task);
+ pObj->TimerQThr_task = NULL;
}
- CHECK_PID_LEGALITY(pObj->MLMEThr_pid)
+ BUG_ON(pObj->MLMEThr_task == NULL);
+ CHECK_PID_LEGALITY(task_pid(pObj->MLMEThr_task))
{
- printk("Terminate the MLMEThr_pid=%d!\n", GET_PID_NUMBER(pObj->MLMEThr_pid));
+ printk(KERN_DEBUG "Terminate the MLMEThr pid=%d!\n",
+ pid_nr(task_pid(pObj->MLMEThr_task)));
mb();
pAd->mlme_kill = 1;
//RT28XX_MLME_HANDLER(pAd);
mb();
- ret = KILL_THREAD_PID(pObj->MLMEThr_pid, SIGTERM, 1);
- if (ret)
- {
- printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
- pAd->net_dev->name, GET_PID_NUMBER(pObj->MLMEThr_pid), ret);
- }
- else
- {
- //wait_for_completion (&pAd->notify);
- wait_for_completion (&pAd->mlmeComplete);
- pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
- }
+ kthread_stop(pObj->MLMEThr_task);
+ pObj->MLMEThr_task = NULL;
}
- CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)
+ BUG_ON(pObj->RTUSBCmdThr_task == NULL);
+ CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task))
{
- printk("Terminate the RTUSBCmdThr_pid=%d!\n", GET_PID_NUMBER(pObj->RTUSBCmdThr_pid));
+ printk(KERN_DEBUG "Terminate the RTUSBCmdThr pid=%d!\n",
+ pid_nr(task_pid(pObj->RTUSBCmdThr_task)));
mb();
NdisAcquireSpinLock(&pAd->CmdQLock);
pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
NdisReleaseSpinLock(&pAd->CmdQLock);
mb();
//RTUSBCMDUp(pAd);
- ret = KILL_THREAD_PID(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
- if (ret)
- {
- printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
- pAd->net_dev->name, GET_PID_NUMBER(pObj->RTUSBCmdThr_pid), ret);
- }
- else
- {
- //wait_for_completion (&pAd->notify);
- wait_for_completion (&pAd->CmdQComplete);
- pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
- }
+ kthread_stop(pObj->RTUSBCmdThr_task);
+ pObj->RTUSBCmdThr_task = NULL;
}
@@ -1067,7 +1044,7 @@ BOOLEAN RT28XXChipsetCheck(
if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
{
- printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
+ printk(KERN_DEBUG "rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
break;
}
diff --git a/drivers/staging/rt2870/TODO b/drivers/staging/rt2870/TODO
index eae1ac47d3f..2df1bfed9a5 100644
--- a/drivers/staging/rt2870/TODO
+++ b/drivers/staging/rt2870/TODO
@@ -1,7 +1,14 @@
+I'm hesitant to add a TODO file here, as the wireless developers would
+really have people help them out on the "clean" rt2870 driver that can
+be found at the http://rt2x00.serialmonkey.com/ site.
+
+But, if you wish to clean up this driver instead, here's a short list of
+things that need to be done to get it into a more mergable shape:
+
TODO:
- checkpatch.pl clean
- sparse clean
- - port to in-kernel 80211 stack
+ - port to in-kernel 80211 stack and common rt2x00 infrastructure
- remove reading from /etc/ config files
- review by the wireless developer community
diff --git a/drivers/staging/rt2870/common/2870_rtmp_init.c b/drivers/staging/rt2870/common/2870_rtmp_init.c
index 9f5143b3922..cb16d2fcf60 100644
--- a/drivers/staging/rt2870/common/2870_rtmp_init.c
+++ b/drivers/staging/rt2870/common/2870_rtmp_init.c
@@ -727,8 +727,8 @@ NDIS_STATUS AdapterBlockAllocateMemory(
usb_dev = pObj->pUsb_Dev;
- pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
- pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
+ pObj->MLMEThr_task = NULL;
+ pObj->RTUSBCmdThr_task = NULL;
*ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
@@ -765,7 +765,7 @@ NDIS_STATUS CreateThreads(
{
PRTMP_ADAPTER pAd = net_dev->ml_priv;
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
- pid_t pid_number = -1;
+ struct task_struct *tsk;
//init_MUTEX(&(pAd->usbdev_semaphore));
@@ -779,36 +779,39 @@ NDIS_STATUS CreateThreads(
init_completion (&pAd->TimerQComplete);
// Creat MLME Thread
- pObj->MLMEThr_pid= THREAD_PID_INIT_VALUE;
- pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
- if (pid_number < 0)
- {
+ pObj->MLMEThr_task = NULL;
+ tsk = kthread_run(MlmeThread, pAd, pAd->net_dev->name);
+
+ if (IS_ERR(tsk)) {
printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
return NDIS_STATUS_FAILURE;
}
- pObj->MLMEThr_pid = GET_PID(pid_number);
+
+ pObj->MLMEThr_task = tsk;
// Wait for the thread to start
wait_for_completion(&(pAd->mlmeComplete));
// Creat Command Thread
- pObj->RTUSBCmdThr_pid= THREAD_PID_INIT_VALUE;
- pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
- if (pid_number < 0)
+ pObj->RTUSBCmdThr_task = NULL;
+ tsk = kthread_run(RTUSBCmdThread, pAd, pAd->net_dev->name);
+
+ if (IS_ERR(tsk) < 0)
{
printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
return NDIS_STATUS_FAILURE;
}
- pObj->RTUSBCmdThr_pid = GET_PID(pid_number);
+
+ pObj->RTUSBCmdThr_task = tsk;
wait_for_completion(&(pAd->CmdQComplete));
- pObj->TimerQThr_pid= THREAD_PID_INIT_VALUE;
- pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
- if (pid_number < 0)
+ pObj->TimerQThr_task = NULL;
+ tsk = kthread_run(TimerQThread, pAd, pAd->net_dev->name);
+ if (IS_ERR(tsk) < 0)
{
printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
return NDIS_STATUS_FAILURE;
}
- pObj->TimerQThr_pid = GET_PID(pid_number);
+ pObj->TimerQThr_task = tsk;
// Wait for the thread to start
wait_for_completion(&(pAd->TimerQComplete));
diff --git a/drivers/staging/rt2870/common/cmm_data.c b/drivers/staging/rt2870/common/cmm_data.c
index fd809abf6df..f8e0ebd7bca 100644
--- a/drivers/staging/rt2870/common/cmm_data.c
+++ b/drivers/staging/rt2870/common/cmm_data.c
@@ -709,9 +709,6 @@ BOOLEAN RTMP_FillTxBlkInfo(
}
return TRUE;
-
-FillTxBlkErr:
- return FALSE;
}
diff --git a/drivers/staging/rt2870/common/rtmp_init.c b/drivers/staging/rt2870/common/rtmp_init.c
index 870a00da3da..099b6a806f8 100644
--- a/drivers/staging/rt2870/common/rtmp_init.c
+++ b/drivers/staging/rt2870/common/rtmp_init.c
@@ -3655,7 +3655,7 @@ VOID UserCfgInit(
#ifdef RALINK_28xx_QA
//pAd->ate.Repeat = 0;
pAd->ate.TxStatus = 0;
- pAd->ate.AtePid = THREAD_PID_INIT_VALUE;
+ pAd->ate.AtePid = NULL;
#endif // RALINK_28xx_QA //
#endif // RALINK_ATE //
diff --git a/drivers/staging/rt2870/common/rtusb_io.c b/drivers/staging/rt2870/common/rtusb_io.c
index 6db443e9268..afde136a9a0 100644
--- a/drivers/staging/rt2870/common/rtusb_io.c
+++ b/drivers/staging/rt2870/common/rtusb_io.c
@@ -958,7 +958,8 @@ NDIS_STATUS RTUSBEnqueueCmdFromNdis(
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
- CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)
+ BUG_ON(pObj->RTUSBCmdThr_task == NULL);
+ CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task))
return (NDIS_STATUS_RESOURCES);
status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
diff --git a/drivers/staging/rt2870/common/spectrum.c b/drivers/staging/rt2870/common/spectrum.c
index 43782ce9288..74380958eb7 100644
--- a/drivers/staging/rt2870/common/spectrum.c
+++ b/drivers/staging/rt2870/common/spectrum.c
@@ -1595,7 +1595,7 @@ static VOID PeerMeasureReportAction(
if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
{
- DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
+ DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%zu).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
return;
}
diff --git a/drivers/staging/rt2870/rt2870.h b/drivers/staging/rt2870/rt2870.h
index 30af4b57c3d..5dd15aac9ce 100644
--- a/drivers/staging/rt2870/rt2870.h
+++ b/drivers/staging/rt2870/rt2870.h
@@ -86,6 +86,7 @@
#define RT2870_USB_DEVICES \
{ \
{USB_DEVICE(0x148F,0x2770)}, /* Ralink */ \
+ {USB_DEVICE(0x1737,0x0071)}, /* Linksys WUSB600N */ \
{USB_DEVICE(0x148F,0x2870)}, /* Ralink */ \
{USB_DEVICE(0x148F,0x3070)}, /* Ralink */ \
{USB_DEVICE(0x0B05,0x1731)}, /* Asus */ \
@@ -576,14 +577,16 @@ VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs);
#define RTUSBMlmeUp(pAd) \
{ \
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \
- CHECK_PID_LEGALITY(pObj->MLMEThr_pid) \
+ BUG_ON(pObj->MLMEThr_task == NULL); \
+ CHECK_PID_LEGALITY(task_pid(pObj->MLMEThr_task)) \
up(&(pAd->mlme_semaphore)); \
}
#define RTUSBCMDUp(pAd) \
{ \
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \
- CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid) \
+ BUG_ON(pObj->RTUSBCmdThr_task == NULL); \
+ CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task)) \
up(&(pAd->RTUSBCmd_semaphore)); \
}
diff --git a/drivers/staging/rt2870/rt_linux.c b/drivers/staging/rt2870/rt_linux.c
index 992e3d16f9b..e38552c5ccb 100644
--- a/drivers/staging/rt2870/rt_linux.c
+++ b/drivers/staging/rt2870/rt_linux.c
@@ -895,7 +895,7 @@ void send_monitor_packets(
if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
{
- DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
goto err_free_sk_buff;
}
diff --git a/drivers/staging/rt2870/rt_linux.h b/drivers/staging/rt2870/rt_linux.h
index 859f9cef0a1..5a6ee6ad0e5 100644
--- a/drivers/staging/rt2870/rt_linux.h
+++ b/drivers/staging/rt2870/rt_linux.h
@@ -44,6 +44,7 @@
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
+#include <linux/kthread.h>
#include <linux/spinlock.h>
#include <linux/init.h>
@@ -65,7 +66,6 @@
#include <linux/vmalloc.h>
-#include <linux/wireless.h>
#include <net/iw_handler.h>
// load firmware
@@ -166,14 +166,12 @@ typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
typedef struct pid * THREAD_PID;
-#define THREAD_PID_INIT_VALUE NULL
#define GET_PID(_v) find_get_pid(_v)
#define GET_PID_NUMBER(_v) pid_nr(_v)
#define CHECK_PID_LEGALITY(_pid) if (pid_nr(_pid) >= 0)
#define KILL_THREAD_PID(_A, _B, _C) kill_pid(_A, _B, _C)
#else
typedef pid_t THREAD_PID;
-#define THREAD_PID_INIT_VALUE -1
#define GET_PID(_v) _v
#define GET_PID_NUMBER(_v) _v
#define CHECK_PID_LEGALITY(_pid) if (_pid >= 0)
@@ -189,11 +187,11 @@ struct os_lock {
struct os_cookie {
#ifdef RT2870
- struct usb_device *pUsb_Dev;
+ struct usb_device *pUsb_Dev;
- THREAD_PID MLMEThr_pid;
- THREAD_PID RTUSBCmdThr_pid;
- THREAD_PID TimerQThr_pid;
+ struct task_struct *MLMEThr_task;
+ struct task_struct *RTUSBCmdThr_task;
+ struct task_struct *TimerQThr_task;
#endif // RT2870 //
struct tasklet_struct rx_done_task;
diff --git a/drivers/staging/rt2870/sta_ioctl.c b/drivers/staging/rt2870/sta_ioctl.c
index 91f0fab1131..4b432ce4442 100644
--- a/drivers/staging/rt2870/sta_ioctl.c
+++ b/drivers/staging/rt2870/sta_ioctl.c
@@ -1776,7 +1776,7 @@ int rt_ioctl_siwencode(struct net_device *dev,
}
else
/* Don't complain if only change the mode */
- if(!erq->flags & IW_ENCODE_MODE) {
+ if (!(erq->flags & IW_ENCODE_MODE)) {
return -EINVAL;
}
}
diff --git a/drivers/staging/rt3070/2870_main_dev.c b/drivers/staging/rt3070/2870_main_dev.c
new file mode 100644
index 00000000000..401ddb01213
--- /dev/null
+++ b/drivers/staging/rt3070/2870_main_dev.c
@@ -0,0 +1,1627 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_main.c
+
+ Abstract:
+ main initialization routines
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Jan Lee 01-10-2005 modified
+ Sample Jun/01/07 Merge RT2870 and RT2860 drivers.
+*/
+
+#include "rt_config.h"
+
+
+// Following information will be show when you run 'modinfo'
+// *** If you have a solution for the bug in current version of driver, please mail to me.
+// Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. ***
+MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
+MODULE_DESCRIPTION("RT2870 Wireless Lan Linux Driver");
+#ifdef CONFIG_STA_SUPPORT
+MODULE_LICENSE("GPL");
+#ifdef MODULE_VERSION
+MODULE_VERSION(STA_DRIVER_VERSION);
+#endif
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef MULTIPLE_CARD_SUPPORT
+// record whether the card in the card list is used in the card file
+extern UINT8 MC_CardUsed[];
+#endif // MULTIPLE_CARD_SUPPORT //
+
+/* Kernel thread and vars, which handles packets that are completed. Only
+ * packets that have a "complete" function are sent here. This way, the
+ * completion is run out of kernel context, and doesn't block the rest of
+ * the stack. */
+//static int mlme_kill = 0; // Mlme kernel thread
+//static int RTUSBCmd_kill = 0; // Command kernel thread
+//static int TimerFunc_kill = 0; // TimerQ kernel thread
+
+//static wait_queue_head_t timerWaitQ;
+//static wait_queue_t waitQ;
+
+extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
+ IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
+
+
+/* module table */
+struct usb_device_id rtusb_usb_id[] = RT2870_USB_DEVICES;
+INT const rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
+MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
+
+#ifndef PF_NOFREEZE
+#define PF_NOFREEZE 0
+#endif
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+
+/**************************************************************************/
+/**************************************************************************/
+//tested for kernel 2.4 series
+/**************************************************************************/
+/**************************************************************************/
+static void *rtusb_probe(struct usb_device *dev, UINT interface,
+ const struct usb_device_id *id_table);
+static void rtusb_disconnect(struct usb_device *dev, void *ptr);
+
+struct usb_driver rtusb_driver = {
+ name:"rt2870",
+ probe:rtusb_probe,
+ disconnect:rtusb_disconnect,
+ id_table:rtusb_usb_id,
+ };
+
+#else
+
+#ifdef CONFIG_PM
+static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
+static int rt2870_resume(struct usb_interface *intf);
+#endif // CONFIG_PM //
+
+/**************************************************************************/
+/**************************************************************************/
+//tested for kernel 2.6series
+/**************************************************************************/
+/**************************************************************************/
+static int rtusb_probe (struct usb_interface *intf,
+ const struct usb_device_id *id);
+static void rtusb_disconnect(struct usb_interface *intf);
+
+struct usb_driver rtusb_driver = {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ .owner = THIS_MODULE,
+#endif
+ .name="rt2870",
+ .probe=rtusb_probe,
+ .disconnect=rtusb_disconnect,
+ .id_table=rtusb_usb_id,
+
+#ifdef CONFIG_PM
+ suspend: rt2870_suspend,
+ resume: rt2870_resume,
+#endif
+ };
+
+#ifdef CONFIG_PM
+
+VOID RT2860RejectPendingPackets(
+ IN PRTMP_ADAPTER pAd)
+{
+ // clear PS packets
+ // clear TxSw packets
+}
+
+static int rt2870_suspend(
+ struct usb_interface *intf,
+ pm_message_t state)
+{
+ struct net_device *net_dev;
+ PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
+ net_dev = pAd->net_dev;
+ netif_device_detach(net_dev);
+
+ pAd->PM_FlgSuspend = 1;
+ if (netif_running(net_dev)) {
+ RTUSBCancelPendingBulkInIRP(pAd);
+ RTUSBCancelPendingBulkOutIRP(pAd);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
+ return 0;
+}
+
+static int rt2870_resume(
+ struct usb_interface *intf)
+{
+ struct net_device *net_dev;
+ PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
+
+ pAd->PM_FlgSuspend = 0;
+ net_dev = pAd->net_dev;
+ netif_device_attach(net_dev);
+ netif_start_queue(net_dev);
+ netif_carrier_on(net_dev);
+ netif_wake_queue(net_dev);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
+ return 0;
+}
+#endif // CONFIG_PM //
+#endif // LINUX_VERSION_CODE //
+
+
+// Init driver module
+INT __init rtusb_init(void)
+{
+ printk("rtusb init --->\n");
+ return usb_register(&rtusb_driver);
+}
+
+// Deinit driver module
+VOID __exit rtusb_exit(void)
+{
+ usb_deregister(&rtusb_driver);
+ printk("<--- rtusb exit\n");
+}
+
+module_init(rtusb_init);
+module_exit(rtusb_exit);
+
+
+
+
+/*--------------------------------------------------------------------- */
+/* function declarations */
+/*--------------------------------------------------------------------- */
+
+/*
+========================================================================
+Routine Description:
+ MLME kernel thread.
+
+Arguments:
+ *Context the pAd, driver control block pointer
+
+Return Value:
+ 0 close the thread
+
+Note:
+========================================================================
+*/
+INT MlmeThread(
+ IN void *Context)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
+ POS_COOKIE pObj;
+ int status;
+
+ pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+ rtmp_os_thread_init("rt2870MlmeThread", (PVOID)&(pAd->mlmeComplete));
+
+ while (pAd->mlme_kill == 0)
+ {
+ /* lock the device pointers */
+ //down(&(pAd->mlme_semaphore));
+ status = down_interruptible(&(pAd->mlme_semaphore));
+
+ /* lock the device pointers , need to check if required*/
+ //down(&(pAd->usbdev_semaphore));
+
+ if (!pAd->PM_FlgSuspend)
+ MlmeHandler(pAd);
+
+ /* unlock the device pointers */
+ //up(&(pAd->usbdev_semaphore));
+ if (status != 0)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ break;
+ }
+ }
+
+ /* notify the exit routine that we're actually exiting now
+ *
+ * complete()/wait_for_completion() is similar to up()/down(),
+ * except that complete() is safe in the case where the structure
+ * is getting deleted in a parallel mode of execution (i.e. just
+ * after the down() -- that's necessary for the thread-shutdown
+ * case.
+ *
+ * complete_and_exit() goes even further than this -- it is safe in
+ * the case that the thread of the caller is going away (not just
+ * the structure) -- this is necessary for the module-remove case.
+ * This is important in preemption kernels, which transfer the flow
+ * of execution immediately upon a complete().
+ */
+ DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
+
+ pObj->MLMEThr_pid = NULL;
+
+ complete_and_exit (&pAd->mlmeComplete, 0);
+ return 0;
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+ USB command kernel thread.
+
+Arguments:
+ *Context the pAd, driver control block pointer
+
+Return Value:
+ 0 close the thread
+
+Note:
+========================================================================
+*/
+INT RTUSBCmdThread(
+ IN void * Context)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
+ POS_COOKIE pObj;
+ int status;
+
+ pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+ rtmp_os_thread_init("rt2870CmdThread", (PVOID)&(pAd->CmdQComplete));
+
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ pAd->CmdQ.CmdQState = RT2870_THREAD_RUNNING;
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+
+ while (pAd->CmdQ.CmdQState == RT2870_THREAD_RUNNING)
+ {
+ /* lock the device pointers */
+ //down(&(pAd->RTUSBCmd_semaphore));
+ status = down_interruptible(&(pAd->RTUSBCmd_semaphore));
+
+ if (pAd->CmdQ.CmdQState == RT2870_THREAD_STOPED)
+ break;
+
+ if (status != 0)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ break;
+ }
+ /* lock the device pointers , need to check if required*/
+ //down(&(pAd->usbdev_semaphore));
+
+ if (!pAd->PM_FlgSuspend)
+ CMDHandler(pAd);
+
+ /* unlock the device pointers */
+ //up(&(pAd->usbdev_semaphore));
+ }
+
+ if (!pAd->PM_FlgSuspend)
+ { // Clear the CmdQElements.
+ CmdQElmt *pCmdQElmt = NULL;
+
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
+ while(pAd->CmdQ.size)
+ {
+ RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
+ if (pCmdQElmt)
+ {
+ if (pCmdQElmt->CmdFromNdis == TRUE)
+ {
+ if (pCmdQElmt->buffer != NULL)
+ NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
+
+ NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
+ }
+ else
+ {
+ if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
+ NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
+ {
+ NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
+ }
+ }
+ }
+ }
+
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+ }
+ /* notify the exit routine that we're actually exiting now
+ *
+ * complete()/wait_for_completion() is similar to up()/down(),
+ * except that complete() is safe in the case where the structure
+ * is getting deleted in a parallel mode of execution (i.e. just
+ * after the down() -- that's necessary for the thread-shutdown
+ * case.
+ *
+ * complete_and_exit() goes even further than this -- it is safe in
+ * the case that the thread of the caller is going away (not just
+ * the structure) -- this is necessary for the module-remove case.
+ * This is important in preemption kernels, which transfer the flow
+ * of execution immediately upon a complete().
+ */
+ DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
+
+ pObj->RTUSBCmdThr_pid = NULL;
+
+ complete_and_exit (&pAd->CmdQComplete, 0);
+ return 0;
+
+}
+
+
+static void RT2870_TimerQ_Handle(RTMP_ADAPTER *pAd)
+{
+ int status;
+ RALINK_TIMER_STRUCT *pTimer;
+ RT2870_TIMER_ENTRY *pEntry;
+ unsigned long irqFlag;
+
+ while(!pAd->TimerFunc_kill)
+ {
+// printk("waiting for event!\n");
+ pTimer = NULL;
+
+ status = down_interruptible(&(pAd->RTUSBTimer_semaphore));
+
+ if (pAd->TimerQ.status == RT2870_THREAD_STOPED)
+ break;
+
+ // event happened.
+ while(pAd->TimerQ.pQHead)
+ {
+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlag);
+ pEntry = pAd->TimerQ.pQHead;
+ if (pEntry)
+ {
+ pTimer = pEntry->pRaTimer;
+
+ // update pQHead
+ pAd->TimerQ.pQHead = pEntry->pNext;
+ if (pEntry == pAd->TimerQ.pQTail)
+ pAd->TimerQ.pQTail = NULL;
+
+ // return this queue entry to timerQFreeList.
+ pEntry->pNext = pAd->TimerQ.pQPollFreeList;
+ pAd->TimerQ.pQPollFreeList = pEntry;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlag);
+
+ if (pTimer)
+ {
+ if (pTimer->handle != NULL)
+ if (!pAd->PM_FlgSuspend)
+ pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
+ if ((pTimer->Repeat) && (pTimer->State == FALSE))
+ RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
+ }
+ }
+
+ if (status != 0)
+ {
+ pAd->TimerQ.status = RT2870_THREAD_STOPED;
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ break;
+ }
+ }
+}
+
+
+INT TimerQThread(
+ IN OUT PVOID Context)
+{
+ PRTMP_ADAPTER pAd;
+ POS_COOKIE pObj;
+
+ pAd = (PRTMP_ADAPTER)Context;
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ rtmp_os_thread_init("rt2870TimerQHandle", (PVOID)&(pAd->TimerQComplete));
+
+ RT2870_TimerQ_Handle(pAd);
+
+ /* notify the exit routine that we're actually exiting now
+ *
+ * complete()/wait_for_completion() is similar to up()/down(),
+ * except that complete() is safe in the case where the structure
+ * is getting deleted in a parallel mode of execution (i.e. just
+ * after the down() -- that's necessary for the thread-shutdown
+ * case.
+ *
+ * complete_and_exit() goes even further than this -- it is safe in
+ * the case that the thread of the caller is going away (not just
+ * the structure) -- this is necessary for the module-remove case.
+ * This is important in preemption kernels, which transfer the flow
+ * of execution immediately upon a complete().
+ */
+ DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
+
+ pObj->TimerQThr_pid = NULL;
+
+ complete_and_exit(&pAd->TimerQComplete, 0);
+ return 0;
+
+}
+
+
+RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
+ IN RTMP_ADAPTER *pAd,
+ IN RALINK_TIMER_STRUCT *pTimer)
+{
+ RT2870_TIMER_ENTRY *pQNode = NULL, *pQTail;
+ unsigned long irqFlags;
+
+
+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
+ if (pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)
+ {
+ if(pAd->TimerQ.pQPollFreeList)
+ {
+ pQNode = pAd->TimerQ.pQPollFreeList;
+ pAd->TimerQ.pQPollFreeList = pQNode->pNext;
+
+ pQNode->pRaTimer = pTimer;
+ pQNode->pNext = NULL;
+
+ pQTail = pAd->TimerQ.pQTail;
+ if (pAd->TimerQ.pQTail != NULL)
+ pQTail->pNext = pQNode;
+ pAd->TimerQ.pQTail = pQNode;
+ if (pAd->TimerQ.pQHead == NULL)
+ pAd->TimerQ.pQHead = pQNode;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+ if (pQNode)
+ up(&pAd->RTUSBTimer_semaphore);
+ //wake_up(&timerWaitQ);
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+ }
+ return pQNode;
+}
+
+
+BOOLEAN RT2870_TimerQ_Remove(
+ IN RTMP_ADAPTER *pAd,
+ IN RALINK_TIMER_STRUCT *pTimer)
+{
+ RT2870_TIMER_ENTRY *pNode, *pPrev = NULL;
+ unsigned long irqFlags;
+
+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
+ if (pAd->TimerQ.status >= RT2870_THREAD_INITED)
+ {
+ pNode = pAd->TimerQ.pQHead;
+ while (pNode)
+ {
+ if (pNode->pRaTimer == pTimer)
+ break;
+ pPrev = pNode;
+ pNode = pNode->pNext;
+ }
+
+ // Now move it to freeList queue.
+ if (pNode)
+ {
+ if (pNode == pAd->TimerQ.pQHead)
+ pAd->TimerQ.pQHead = pNode->pNext;
+ if (pNode == pAd->TimerQ.pQTail)
+ pAd->TimerQ.pQTail = pPrev;
+ if (pPrev != NULL)
+ pPrev->pNext = pNode->pNext;
+
+ // return this queue entry to timerQFreeList.
+ pNode->pNext = pAd->TimerQ.pQPollFreeList;
+ pAd->TimerQ.pQPollFreeList = pNode;
+ }
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+ return TRUE;
+}
+
+
+void RT2870_TimerQ_Exit(RTMP_ADAPTER *pAd)
+{
+ RT2870_TIMER_ENTRY *pTimerQ;
+ unsigned long irqFlags;
+
+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
+ while (pAd->TimerQ.pQHead)
+ {
+ pTimerQ = pAd->TimerQ.pQHead;
+ pAd->TimerQ.pQHead = pTimerQ->pNext;
+ // remove the timeQ
+ }
+ pAd->TimerQ.pQPollFreeList = NULL;
+ os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
+ pAd->TimerQ.pQTail = NULL;
+ pAd->TimerQ.pQHead = NULL;
+ pAd->TimerQ.status = RT2870_THREAD_STOPED;
+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+}
+
+
+void RT2870_TimerQ_Init(RTMP_ADAPTER *pAd)
+{
+ int i;
+ RT2870_TIMER_ENTRY *pQNode, *pEntry;
+ unsigned long irqFlags;
+
+ NdisAllocateSpinLock(&pAd->TimerQLock);
+
+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
+ NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
+ //InterlockedExchange(&pAd->TimerQ.count, 0);
+
+ /* Initialise the wait q head */
+ //init_waitqueue_head(&timerWaitQ);
+
+ os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RT2870_TIMER_ENTRY) * TIMER_QUEUE_SIZE_MAX);
+ if (pAd->TimerQ.pTimerQPoll)
+ {
+ pEntry = NULL;
+ pQNode = (RT2870_TIMER_ENTRY *)pAd->TimerQ.pTimerQPoll;
+ for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
+ {
+ pQNode->pNext = pEntry;
+ pEntry = pQNode;
+ pQNode++;
+ }
+ pAd->TimerQ.pQPollFreeList = pEntry;
+ pAd->TimerQ.pQHead = NULL;
+ pAd->TimerQ.pQTail = NULL;
+ pAd->TimerQ.status = RT2870_THREAD_INITED;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+}
+
+
+VOID RT2870_WatchDog(IN RTMP_ADAPTER *pAd)
+{
+ PHT_TX_CONTEXT pHTTXContext;
+ int idx;
+ ULONG irqFlags;
+ PURB pUrb;
+ BOOLEAN needDumpSeq = FALSE;
+ UINT32 MACValue;
+
+
+ idx = 0;
+ RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+ if ((MACValue & 0xff) !=0 )
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
+ while((MACValue &0xff) != 0 && (idx++ < 10))
+ {
+ RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+ NdisMSleep(1);
+ }
+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
+ }
+
+//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ idx = 0;
+ if ((MACValue & 0xff00) !=0 )
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
+ while((MACValue &0xff00) != 0 && (idx++ < 10))
+ {
+ RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+ NdisMSleep(1);
+ }
+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ if (pAd->watchDogRxOverFlowCnt >= 2)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
+ if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_BULKIN_RESET |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
+ needDumpSeq = TRUE;
+ }
+ pAd->watchDogRxOverFlowCnt = 0;
+ }
+
+
+ for (idx = 0; idx < NUM_OF_TX_RING; idx++)
+ {
+ pUrb = NULL;
+
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
+ if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
+ {
+ pAd->watchDogTxPendingCnt[idx]++;
+
+ if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
+ (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
+ )
+ {
+ // FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
+ pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
+ if (pHTTXContext->IRPPending)
+ { // Check TxContext.
+ pUrb = pHTTXContext->pUrb;
+ }
+ else if (idx == MGMTPIPEIDX)
+ {
+ PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
+
+ //Check MgmtContext.
+ pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
+ pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
+ pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
+
+ if (pMLMEContext->IRPPending)
+ {
+ ASSERT(pMLMEContext->IRPPending);
+ pUrb = pMLMEContext->pUrb;
+ }
+ else if (pNULLContext->IRPPending)
+ {
+ ASSERT(pNULLContext->IRPPending);
+ pUrb = pNULLContext->pUrb;
+ }
+ else if (pPsPollContext->IRPPending)
+ {
+ ASSERT(pPsPollContext->IRPPending);
+ pUrb = pPsPollContext->pUrb;
+ }
+ }
+
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
+ if (pUrb)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
+ // unlink it now
+ RTUSB_UNLINK_URB(pUrb);
+ // Sleep 200 microseconds to give cancellation time to work
+ RTMPusecDelay(200);
+ needDumpSeq = TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
+ }
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+ }
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+ }
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // For Sigma debug, dump the ba_reordering sequence.
+ if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
+ {
+ USHORT Idx;
+ PBA_REC_ENTRY pBAEntry = NULL;
+ UCHAR count = 0;
+ struct reordering_mpdu *mpdu_blk;
+
+ Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
+
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+ mpdu_blk = pBAEntry->list.next;
+ while (mpdu_blk)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
+ mpdu_blk = mpdu_blk->next;
+ count++;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+}
+
+/*
+========================================================================
+Routine Description:
+ Release allocated resources.
+
+Arguments:
+ *dev Point to the PCI or USB device
+ pAd driver control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+static void _rtusb_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd)
+{
+ struct net_device *net_dev = NULL;
+
+
+ DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
+ dev->bus->bus_name, dev->devpath));
+ if (!pAd)
+ {
+#ifdef MULTIPLE_CARD_SUPPORT
+ if ((pAd->MC_RowID >= 0) && (pAd->MC_RowID <= MAX_NUM_OF_MULTIPLE_CARD))
+ MC_CardUsed[pAd->MC_RowID] = 0; // not clear MAC address
+#endif // MULTIPLE_CARD_SUPPORT //
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ while(MOD_IN_USE > 0)
+ {
+ MOD_DEC_USE_COUNT;
+ }
+#else
+ usb_put_dev(dev);
+#endif // LINUX_VERSION_CODE //
+
+ printk("rtusb_disconnect: pAd == NULL!\n");
+ return;
+ }
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+
+
+
+ // for debug, wait to show some messages to /proc system
+ udelay(1);
+
+
+
+
+ net_dev = pAd->net_dev;
+ if (pAd->net_dev != NULL)
+ {
+ printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev->name);
+ unregister_netdev (pAd->net_dev);
+ }
+ udelay(1);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+#else
+ flush_scheduled_work();
+#endif // LINUX_VERSION_CODE //
+ udelay(1);
+
+ // free net_device memory
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ kfree(net_dev);
+#else
+ free_netdev(net_dev);
+#endif // LINUX_VERSION_CODE //
+
+ // free adapter memory
+ RTMPFreeAdapter(pAd);
+
+ // release a use of the usb device structure
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ while(MOD_IN_USE > 0)
+ {
+ MOD_DEC_USE_COUNT;
+ }
+#else
+ usb_put_dev(dev);
+#endif // LINUX_VERSION_CODE //
+ udelay(1);
+
+ DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Probe RT28XX chipset.
+
+Arguments:
+ *dev Point to the PCI or USB device
+ interface
+ *id_table Point to the PCI or USB device ID
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+static void *rtusb_probe(struct usb_device *dev, UINT interface,
+ const struct usb_device_id *id)
+{
+ PRTMP_ADAPTER pAd;
+ rt28xx_probe((void *)dev, (void *)id, interface, &pAd);
+ return (void *)pAd;
+}
+
+//Disconnect function is called within exit routine
+static void rtusb_disconnect(struct usb_device *dev, void *ptr)
+{
+ _rtusb_disconnect(dev, ((PRTMP_ADAPTER)ptr));
+}
+
+#else /* kernel 2.6 series */
+static int rtusb_probe (struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ PRTMP_ADAPTER pAd;
+ return (int)rt28xx_probe((void *)intf, (void *)id, 0, &pAd);
+}
+
+
+static void rtusb_disconnect(struct usb_interface *intf)
+{
+ struct usb_device *dev = interface_to_usbdev(intf);
+ PRTMP_ADAPTER pAd;
+
+
+ pAd = usb_get_intfdata(intf);
+ usb_set_intfdata(intf, NULL);
+
+ _rtusb_disconnect(dev, pAd);
+}
+#endif // LINUX_VERSION_CODE //
+
+
+/*
+========================================================================
+Routine Description:
+ Close kernel threads.
+
+Arguments:
+ *pAd the raxx interface data pointer
+
+Return Value:
+ NONE
+
+Note:
+========================================================================
+*/
+VOID RT28xxThreadTerminate(
+ IN RTMP_ADAPTER *pAd)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ INT ret;
+
+
+ // Sleep 50 milliseconds so pending io might finish normally
+ RTMPusecDelay(50000);
+
+ // We want to wait until all pending receives and sends to the
+ // device object. We cancel any
+ // irps. Wait until sends and receives have stopped.
+ RTUSBCancelPendingIRPs(pAd);
+
+ // Terminate Threads
+ if (pObj->MLMEThr_pid)
+ {
+ printk("Terminate the MLMEThr_pid=%d!\n", pid_nr(pObj->MLMEThr_pid));
+ mb();
+ pAd->mlme_kill = 1;
+ //RT28XX_MLME_HANDLER(pAd);
+ mb();
+ ret = kill_pid(pObj->MLMEThr_pid, SIGTERM, 1);
+ if (ret)
+ {
+ printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
+ pAd->net_dev->name, pid_nr(pObj->MLMEThr_pid), ret);
+ }
+ else
+ {
+ //wait_for_completion (&pAd->notify);
+ wait_for_completion (&pAd->mlmeComplete);
+ pObj->MLMEThr_pid = NULL;
+ }
+ }
+
+ if (pObj->RTUSBCmdThr_pid >= 0)
+ {
+ printk("Terminate the RTUSBCmdThr_pid=%d!\n", pid_nr(pObj->RTUSBCmdThr_pid));
+ mb();
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+ mb();
+ //RTUSBCMDUp(pAd);
+ ret = kill_pid(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
+ if (ret)
+ {
+ printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
+ pAd->net_dev->name, pid_nr(pObj->RTUSBCmdThr_pid), ret);
+ }
+ else
+ {
+ //wait_for_completion (&pAd->notify);
+ wait_for_completion (&pAd->CmdQComplete);
+ pObj->RTUSBCmdThr_pid = NULL;
+ }
+ }
+ if (pObj->TimerQThr_pid >= 0)
+ {
+ POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+ printk("Terminate the TimerQThr_pid=%d!\n", pid_nr(pObj->TimerQThr_pid));
+ mb();
+ pAd->TimerFunc_kill = 1;
+ mb();
+ ret = kill_pid(pObj->TimerQThr_pid, SIGTERM, 1);
+ if (ret)
+ {
+ printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
+ pAd->net_dev->name, pid_nr(pObj->TimerQThr_pid), ret);
+ }
+ else
+ {
+ printk("wait_for_completion TimerQThr\n");
+ wait_for_completion(&pAd->TimerQComplete);
+ pObj->TimerQThr_pid = NULL;
+ }
+ }
+ // Kill tasklets
+ pAd->mlme_kill = 0;
+ pAd->CmdQ.CmdQState = RT2870_THREAD_UNKNOWN;
+ pAd->TimerFunc_kill = 0;
+}
+
+
+void kill_thread_task(IN PRTMP_ADAPTER pAd)
+{
+ POS_COOKIE pObj;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ tasklet_kill(&pObj->rx_done_task);
+ tasklet_kill(&pObj->mgmt_dma_done_task);
+ tasklet_kill(&pObj->ac0_dma_done_task);
+ tasklet_kill(&pObj->ac1_dma_done_task);
+ tasklet_kill(&pObj->ac2_dma_done_task);
+ tasklet_kill(&pObj->ac3_dma_done_task);
+ tasklet_kill(&pObj->hcca_dma_done_task);
+ tasklet_kill(&pObj->tbtt_task);
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Check the chipset vendor/product ID.
+
+Arguments:
+ _dev_p Point to the PCI or USB device
+
+Return Value:
+ TRUE Check ok
+ FALSE Check fail
+
+Note:
+========================================================================
+*/
+BOOLEAN RT28XXChipsetCheck(
+ IN void *_dev_p)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ struct usb_device *dev_p = (struct usb_device *)_dev_p;
+#else
+ struct usb_interface *intf = (struct usb_interface *)_dev_p;
+ struct usb_device *dev_p = interface_to_usbdev(intf);
+#endif // LINUX_VERSION_CODE //
+ UINT32 i;
+
+
+ for(i=0; i<rtusb_usb_id_len; i++)
+ {
+ if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
+ dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
+ {
+ printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
+ dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
+ break;
+ }
+ }
+
+ if (i == rtusb_usb_id_len)
+ {
+ printk("rt2870: Error! Device Descriptor not matching!\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Init net device structure.
+
+Arguments:
+ _dev_p Point to the PCI or USB device
+ *net_dev Point to the net device
+ *pAd the raxx interface data pointer
+
+Return Value:
+ TRUE Init ok
+ FALSE Init fail
+
+Note:
+========================================================================
+*/
+BOOLEAN RT28XXNetDevInit(
+ IN void *_dev_p,
+ IN struct net_device *net_dev,
+ IN RTMP_ADAPTER *pAd)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ struct usb_device *dev_p = (struct usb_device *)_dev_p;
+#else
+ struct usb_interface *intf = (struct usb_interface *)_dev_p;
+ struct usb_device *dev_p = interface_to_usbdev(intf);
+#endif // LINUX_VERSION_CODE //
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ pAd->config = dev_p->config;
+#else
+ pAd->config = &dev_p->config->desc;
+#endif // LINUX_VERSION_CODE //
+ return TRUE;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Init net device structure.
+
+Arguments:
+ _dev_p Point to the PCI or USB device
+ *pAd the raxx interface data pointer
+
+Return Value:
+ TRUE Config ok
+ FALSE Config fail
+
+Note:
+========================================================================
+*/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+BOOLEAN RT28XXProbePostConfig(
+ IN void *_dev_p,
+ IN RTMP_ADAPTER *pAd,
+ IN INT32 interface)
+{
+ struct usb_device *dev_p = (struct usb_device *)_dev_p;
+ struct usb_interface *intf;
+ struct usb_interface_descriptor *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ ULONG BulkOutIdx;
+ UINT32 i;
+
+
+ /* get the active interface descriptor */
+ intf = &dev_p->actconfig->interface[interface];
+ iface_desc = &intf->altsetting[0];
+
+ /* get # of enpoints */
+ pAd->NumberOfPipes = iface_desc->bNumEndpoints;
+ DBGPRINT(RT_DEBUG_TRACE, ("NumEndpoints=%d\n", iface_desc->bNumEndpoints));
+
+ /* Configure Pipes */
+ endpoint = &iface_desc->endpoint[0];
+ BulkOutIdx = 0;
+
+ for(i=0; i<pAd->NumberOfPipes; i++)
+ {
+ if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) &&
+ ((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
+ {
+ pAd->BulkInEpAddr = endpoint[i].bEndpointAddress;
+ pAd->BulkInMaxPacketSize = endpoint[i].wMaxPacketSize;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("EP address = 0x%2x \n", endpoint[i].bEndpointAddress));
+ }
+ else if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) &&
+ ((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
+ {
+ // There are 6 bulk out EP. EP6 highest priority.
+ // EP1-4 is EDCA. EP5 is HCCA.
+ pAd->BulkOutEpAddr[BulkOutIdx++] = endpoint[i].bEndpointAddress;
+ pAd->BulkOutMaxPacketSize = endpoint[i].wMaxPacketSize;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("EP address = 0x%2x \n", endpoint[i].bEndpointAddress));
+ }
+ }
+
+ if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
+ {
+ printk("Could not find both bulk-in and bulk-out endpoints\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#else
+BOOLEAN RT28XXProbePostConfig(
+ IN void *_dev_p,
+ IN RTMP_ADAPTER *pAd,
+ IN INT32 interface)
+{
+ struct usb_interface *intf = (struct usb_interface *)_dev_p;
+ struct usb_host_interface *iface_desc;
+ ULONG BulkOutIdx;
+ UINT32 i;
+
+
+ /* get the active interface descriptor */
+ iface_desc = intf->cur_altsetting;
+
+ /* get # of enpoints */
+ pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
+
+ /* Configure Pipes */
+ BulkOutIdx = 0;
+
+ for(i=0; i<pAd->NumberOfPipes; i++)
+ {
+ if ((iface_desc->endpoint[i].desc.bmAttributes ==
+ USB_ENDPOINT_XFER_BULK) &&
+ ((iface_desc->endpoint[i].desc.bEndpointAddress &
+ USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
+ {
+ pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress;
+ pAd->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress));
+ }
+ else if ((iface_desc->endpoint[i].desc.bmAttributes ==
+ USB_ENDPOINT_XFER_BULK) &&
+ ((iface_desc->endpoint[i].desc.bEndpointAddress &
+ USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
+ {
+ // there are 6 bulk out EP. EP6 highest priority.
+ // EP1-4 is EDCA. EP5 is HCCA.
+ pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress;
+ pAd->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("EP address = 0x%2x \n", iface_desc->endpoint[i].desc.bEndpointAddress));
+ }
+ }
+
+ if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
+ {
+ printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __FUNCTION__);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#endif // LINUX_VERSION_CODE //
+
+
+/*
+========================================================================
+Routine Description:
+ Disable DMA.
+
+Arguments:
+ *pAd the raxx interface data pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RT28XXDMADisable(
+ IN RTMP_ADAPTER *pAd)
+{
+ // no use
+}
+
+
+
+/*
+========================================================================
+Routine Description:
+ Enable DMA.
+
+Arguments:
+ *pAd the raxx interface data pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RT28XXDMAEnable(
+ IN RTMP_ADAPTER *pAd)
+{
+ WPDMA_GLO_CFG_STRUC GloCfg;
+ USB_DMA_CFG_STRUC UsbCfg;
+ int i = 0;
+
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
+ do
+ {
+ RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+ if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
+ break;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
+ RTMPusecDelay(1000);
+ i++;
+ }while ( i <200);
+
+
+ RTMPusecDelay(50);
+ GloCfg.field.EnTXWriteBackDDONE = 1;
+ GloCfg.field.EnableRxDMA = 1;
+ GloCfg.field.EnableTxDMA = 1;
+ DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
+ RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+
+ UsbCfg.word = 0;
+ UsbCfg.field.phyclear = 0;
+ /* usb version is 1.1,do not use bulk in aggregation */
+ if (pAd->BulkInMaxPacketSize == 512)
+ UsbCfg.field.RxBulkAggEn = 1;
+ /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
+ UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
+ UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
+ UsbCfg.field.RxBulkEn = 1;
+ UsbCfg.field.TxBulkEn = 1;
+
+ RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
+
+}
+
+/*
+========================================================================
+Routine Description:
+ Write Beacon buffer to Asic.
+
+Arguments:
+ *pAd the raxx interface data pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RT28xx_UpdateBeaconToAsic(
+ IN RTMP_ADAPTER *pAd,
+ IN INT apidx,
+ IN ULONG FrameLen,
+ IN ULONG UpdatePos)
+{
+ PUCHAR pBeaconFrame = NULL;
+ UCHAR *ptr;
+ UINT i, padding;
+ BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync;
+ UINT32 longValue;
+// USHORT shortValue;
+ BOOLEAN bBcnReq = FALSE;
+ UCHAR bcn_idx = 0;
+
+
+ if (pBeaconFrame == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
+ return;
+ }
+
+ if (pBeaconSync == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
+ return;
+ }
+
+ //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
+ // ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
+ // )
+ if (bBcnReq == FALSE)
+ {
+ /* when the ra interface is down, do not send its beacon frame */
+ /* clear all zero */
+ for(i=0; i<TXWI_SIZE; i+=4) {
+ RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
+ }
+ pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
+ }
+ else
+ {
+ ptr = (PUCHAR)&pAd->BeaconTxWI;
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(ptr, TYPE_TXWI);
+#endif
+ if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
+ { // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
+ pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
+ NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
+ }
+
+ if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
+ {
+ for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
+ {
+ longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+ RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
+ ptr += 4;
+ }
+ }
+
+ ptr = pBeaconSync->BeaconBuf[bcn_idx];
+ padding = (FrameLen & 0x01);
+ NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
+ FrameLen += padding;
+ for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
+ {
+ if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
+ {
+ NdisMoveMemory(ptr, pBeaconFrame, 2);
+ //shortValue = *ptr + (*(ptr+1)<<8);
+ //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
+ RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
+ }
+ ptr +=2;
+ pBeaconFrame += 2;
+ }
+
+ pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
+
+ // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
+ }
+
+}
+
+
+VOID RT2870_BssBeaconStop(
+ IN RTMP_ADAPTER *pAd)
+{
+ BEACON_SYNC_STRUCT *pBeaconSync;
+ int i, offset;
+ BOOLEAN Cancelled = TRUE;
+
+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
+ if (pBeaconSync && pBeaconSync->EnableBeacon)
+ {
+ INT NumOfBcn;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ NumOfBcn = MAX_MESH_NUM;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
+
+ for(i=0; i<NumOfBcn; i++)
+ {
+ NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+
+ for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
+ RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
+
+ pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+ pBeaconSync->TimIELocationInBeacon[i] = 0;
+ }
+ pBeaconSync->BeaconBitMap = 0;
+ pBeaconSync->DtimBitOn = 0;
+ }
+}
+
+
+VOID RT2870_BssBeaconStart(
+ IN RTMP_ADAPTER *pAd)
+{
+ int apidx;
+ BEACON_SYNC_STRUCT *pBeaconSync;
+// LARGE_INTEGER tsfTime, deltaTime;
+
+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
+ if (pBeaconSync && pBeaconSync->EnableBeacon)
+ {
+ INT NumOfBcn;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ NumOfBcn = MAX_MESH_NUM;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ for(apidx=0; apidx<NumOfBcn; apidx++)
+ {
+ UCHAR CapabilityInfoLocationInBeacon = 0;
+ UCHAR TimIELocationInBeacon = 0;
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
+ pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
+ pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
+ }
+ pBeaconSync->BeaconBitMap = 0;
+ pBeaconSync->DtimBitOn = 0;
+ pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
+
+ pAd->CommonCfg.BeaconAdjust = 0;
+ pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
+ pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
+ printk("RT2870_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain);
+ RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod);
+
+ }
+}
+
+
+VOID RT2870_BssBeaconInit(
+ IN RTMP_ADAPTER *pAd)
+{
+ BEACON_SYNC_STRUCT *pBeaconSync;
+ int i;
+
+ NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
+ if (pAd->CommonCfg.pBeaconSync)
+ {
+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
+ NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
+ for(i=0; i < HW_BEACON_MAX_COUNT; i++)
+ {
+ NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+ pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+ pBeaconSync->TimIELocationInBeacon[i] = 0;
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+ }
+ pBeaconSync->BeaconBitMap = 0;
+
+ //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
+ pBeaconSync->EnableBeacon = TRUE;
+ }
+}
+
+
+VOID RT2870_BssBeaconExit(
+ IN RTMP_ADAPTER *pAd)
+{
+ BEACON_SYNC_STRUCT *pBeaconSync;
+ BOOLEAN Cancelled = TRUE;
+ int i;
+
+ if (pAd->CommonCfg.pBeaconSync)
+ {
+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
+ pBeaconSync->EnableBeacon = FALSE;
+ RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
+ pBeaconSync->BeaconBitMap = 0;
+
+ for(i=0; i<HW_BEACON_MAX_COUNT; i++)
+ {
+ NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+ pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+ pBeaconSync->TimIELocationInBeacon[i] = 0;
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+ }
+
+ NdisFreeMemory(pAd->CommonCfg.pBeaconSync, HW_BEACON_OFFSET * HW_BEACON_MAX_COUNT, 0);
+ pAd->CommonCfg.pBeaconSync = NULL;
+ }
+}
+
+VOID BeaconUpdateExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
+ LARGE_INTEGER tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
+ UINT32 delta, remain, remain_low, remain_high;
+// BOOLEAN positive;
+
+ ReSyncBeaconTime(pAd);
+
+
+
+ RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
+ RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
+
+
+ //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
+ remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
+ remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
+ remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
+ delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
+
+ pAd->CommonCfg.BeaconUpdateTimer.TimerValue = (delta >> 10) + 10;
+
+}
+
diff --git a/drivers/staging/rt3070/Kconfig b/drivers/staging/rt3070/Kconfig
new file mode 100644
index 00000000000..b37fb5d13a4
--- /dev/null
+++ b/drivers/staging/rt3070/Kconfig
@@ -0,0 +1,6 @@
+config RT3070
+ tristate "Ralink 3070 wireless support"
+ depends on USB && X86 && WLAN_80211
+ ---help---
+ This is an experimental driver for the Ralink 3070 wireless chip.
+
diff --git a/drivers/staging/rt3070/Makefile b/drivers/staging/rt3070/Makefile
new file mode 100644
index 00000000000..55980c92925
--- /dev/null
+++ b/drivers/staging/rt3070/Makefile
@@ -0,0 +1,47 @@
+obj-$(CONFIG_RT3070) += rt3070sta.o
+
+# TODO: all of these should be removed
+EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
+EXTRA_CFLAGS += -DRT2870 -DRT30xx -DRT3070
+EXTRA_CFLAGS += -DCONFIG_STA_SUPPORT
+EXTRA_CFLAGS += -DDBG
+EXTRA_CFLAGS += -DDOT11_N_SUPPORT
+EXTRA_CFLAGS += -DWPA_SUPPLICANT_SUPPORT
+EXTRA_CFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT
+
+rt3070sta-objs := \
+ common/md5.o \
+ common/mlme.o \
+ common/rtmp_wep.o \
+ common/action.o \
+ common/cmm_data.o \
+ common/rtmp_init.o \
+ common/rtmp_tkip.o \
+ common/cmm_sync.o \
+ common/eeprom.o \
+ common/cmm_sanity.o \
+ common/cmm_info.o \
+ common/cmm_wpa.o \
+ common/dfs.o \
+ common/spectrum.o \
+ sta/assoc.o \
+ sta/aironet.o \
+ sta/auth.o \
+ sta/auth_rsp.o \
+ sta/sync.o \
+ sta/sanity.o \
+ sta/rtmp_data.o \
+ sta/connect.o \
+ sta/wpa.o \
+ rt_linux.o \
+ rt_profile.o \
+ rt_main_dev.o \
+ sta_ioctl.o \
+ common/ba_action.o \
+ 2870_main_dev.o \
+ common/2870_rtmp_init.o \
+ common/rtusb_io.o \
+ common/rtusb_bulk.o \
+ common/rtusb_data.o \
+ common/cmm_data_2870.o
+
diff --git a/drivers/staging/rt3070/action.h b/drivers/staging/rt3070/action.h
new file mode 100644
index 00000000000..ce3877dce81
--- /dev/null
+++ b/drivers/staging/rt3070/action.h
@@ -0,0 +1,68 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ aironet.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 04-06-15 Initial
+*/
+
+#ifndef __ACTION_H__
+#define __ACTION_H__
+
+typedef struct PACKED __HT_INFO_OCTET
+{
+#ifdef RT_BIG_ENDIAN
+ UCHAR Reserved:5;
+ UCHAR STA_Channel_Width:1;
+ UCHAR Forty_MHz_Intolerant:1;
+ UCHAR Request:1;
+#else
+ UCHAR Request:1;
+ UCHAR Forty_MHz_Intolerant:1;
+ UCHAR STA_Channel_Width:1;
+ UCHAR Reserved:5;
+#endif
+} HT_INFORMATION_OCTET;
+
+
+typedef struct PACKED __FRAME_HT_INFO
+{
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ HT_INFORMATION_OCTET HT_Info;
+} FRAME_HT_INFO, *PFRAME_HT_INFO;
+
+#endif /* __ACTION_H__ */
+
+
diff --git a/drivers/staging/rt3070/aironet.h b/drivers/staging/rt3070/aironet.h
new file mode 100644
index 00000000000..1e07b19b8cd
--- /dev/null
+++ b/drivers/staging/rt3070/aironet.h
@@ -0,0 +1,210 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ aironet.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 04-06-15 Initial
+*/
+
+#ifndef __AIRONET_H__
+#define __AIRONET_H__
+
+// Measurement Type definition
+#define MSRN_TYPE_UNUSED 0
+#define MSRN_TYPE_CHANNEL_LOAD_REQ 1
+#define MSRN_TYPE_NOISE_HIST_REQ 2
+#define MSRN_TYPE_BEACON_REQ 3
+#define MSRN_TYPE_FRAME_REQ 4
+
+// Scan Mode in Beacon Request
+#define MSRN_SCAN_MODE_PASSIVE 0
+#define MSRN_SCAN_MODE_ACTIVE 1
+#define MSRN_SCAN_MODE_BEACON_TABLE 2
+
+// PHY type definition for Aironet beacon report, CCX 2 table 36-9
+#define PHY_FH 1
+#define PHY_DSS 2
+#define PHY_UNUSED 3
+#define PHY_OFDM 4
+#define PHY_HR_DSS 5
+#define PHY_ERP 6
+
+// RPI table in dBm
+#define RPI_0 0 // Power <= -87
+#define RPI_1 1 // -87 < Power <= -82
+#define RPI_2 2 // -82 < Power <= -77
+#define RPI_3 3 // -77 < Power <= -72
+#define RPI_4 4 // -72 < Power <= -67
+#define RPI_5 5 // -67 < Power <= -62
+#define RPI_6 6 // -62 < Power <= -57
+#define RPI_7 7 // -57 < Power
+
+// Cisco Aironet IAPP definetions
+#define AIRONET_IAPP_TYPE 0x32
+#define AIRONET_IAPP_SUBTYPE_REQUEST 0x01
+#define AIRONET_IAPP_SUBTYPE_REPORT 0x81
+
+// Measurement Request detail format
+typedef struct _MEASUREMENT_REQUEST {
+ UCHAR Channel;
+ UCHAR ScanMode; // Use only in beacon request, other requests did not use this field
+ USHORT Duration;
+} MEASUREMENT_REQUEST, *PMEASUREMENT_REQUEST;
+
+// Beacon Measurement Report
+// All these field might change to UCHAR, because we didn't do anything to these report.
+// We copy all these beacons and report to CCX 2 AP.
+typedef struct _BEACON_REPORT {
+ UCHAR Channel;
+ UCHAR Spare;
+ USHORT Duration;
+ UCHAR PhyType; // Definiation is listed above table 36-9
+ UCHAR RxPower;
+ UCHAR BSSID[6];
+ UCHAR ParentTSF[4];
+ UCHAR TargetTSF[8];
+ USHORT BeaconInterval;
+ USHORT CapabilityInfo;
+} BEACON_REPORT, *PBEACON_REPORT;
+
+// Frame Measurement Report (Optional)
+typedef struct _FRAME_REPORT {
+ UCHAR Channel;
+ UCHAR Spare;
+ USHORT Duration;
+ UCHAR TA;
+ UCHAR BSSID[6];
+ UCHAR RSSI;
+ UCHAR Count;
+} FRAME_REPORT, *PFRAME_REPORT;
+
+#pragma pack(1)
+// Channel Load Report
+typedef struct _CHANNEL_LOAD_REPORT {
+ UCHAR Channel;
+ UCHAR Spare;
+ USHORT Duration;
+ UCHAR CCABusy;
+} CHANNEL_LOAD_REPORT, *PCHANNEL_LOAD_REPORT;
+#pragma pack()
+
+// Nosie Histogram Report
+typedef struct _NOISE_HIST_REPORT {
+ UCHAR Channel;
+ UCHAR Spare;
+ USHORT Duration;
+ UCHAR Density[8];
+} NOISE_HIST_REPORT, *PNOISE_HIST_REPORT;
+
+// Radio Management Capability element
+typedef struct _RADIO_MANAGEMENT_CAPABILITY {
+ UCHAR Eid; // TODO: Why the Eid is 1 byte, not normal 2 bytes???
+ UCHAR Length;
+ UCHAR AironetOui[3]; // AIronet OUI (00 40 96)
+ UCHAR Type; // Type / Version
+ USHORT Status; // swap16 required
+} RADIO_MANAGEMENT_CAPABILITY, *PRADIO_MANAGEMENT_CAPABILITY;
+
+// Measurement Mode Bit definition
+typedef struct _MEASUREMENT_MODE {
+ UCHAR Rsvd:4;
+ UCHAR Report:1;
+ UCHAR NotUsed:1;
+ UCHAR Enable:1;
+ UCHAR Parallel:1;
+} MEASUREMENT_MODE, *PMEASUREMENT_MODE;
+
+// Measurement Request element, This is little endian mode
+typedef struct _MEASUREMENT_REQUEST_ELEMENT {
+ USHORT Eid;
+ USHORT Length; // swap16 required
+ USHORT Token; // non-zero unique token
+ UCHAR Mode; // Measurement Mode
+ UCHAR Type; // Measurement type
+} MEASUREMENT_REQUEST_ELEMENT, *PMEASUREMENT_REQUEST_ELEMENT;
+
+// Measurement Report element, This is little endian mode
+typedef struct _MEASUREMENT_REPORT_ELEMENT {
+ USHORT Eid;
+ USHORT Length; // swap16 required
+ USHORT Token; // non-zero unique token
+ UCHAR Mode; // Measurement Mode
+ UCHAR Type; // Measurement type
+} MEASUREMENT_REPORT_ELEMENT, *PMEASUREMENT_REPORT_ELEMENT;
+
+// Cisco Aironet IAPP Frame Header, Network byte order used
+typedef struct _AIRONET_IAPP_HEADER {
+ UCHAR CiscoSnapHeader[8]; // 8 bytes Cisco snap header
+ USHORT Length; // IAPP ID & length, remember to swap16 in LE system
+ UCHAR Type; // IAPP type
+ UCHAR SubType; // IAPP subtype
+ UCHAR DA[6]; // Destination MAC address
+ UCHAR SA[6]; // Source MAC address
+ USHORT Token; // Dialog token, no need to swap16 since it is for yoken usage only
+} AIRONET_IAPP_HEADER, *PAIRONET_IAPP_HEADER;
+
+// Radio Measurement Request frame
+typedef struct _AIRONET_RM_REQUEST_FRAME {
+ AIRONET_IAPP_HEADER IAPP; // Common header
+ UCHAR Delay; // Activation Delay
+ UCHAR Offset; // Measurement offset
+} AIRONET_RM_REQUEST_FRAME, *PAIRONET_RM_REQUEST_FRAME;
+
+// Radio Measurement Report frame
+typedef struct _AIRONET_RM_REPORT_FRAME {
+ AIRONET_IAPP_HEADER IAPP; // Common header
+} AIRONET_RM_REPORT_FRAME, *PAIRONET_RM_REPORT_FRAME;
+
+// Saved element request actions which will saved in StaCfg.
+typedef struct _RM_REQUEST_ACTION {
+ MEASUREMENT_REQUEST_ELEMENT ReqElem; // Saved request element
+ MEASUREMENT_REQUEST Measurement; // Saved measurement within the request element
+} RM_REQUEST_ACTION, *PRM_REQUEST_ACTION;
+
+// CCX administration control
+typedef union _CCX_CONTROL {
+ struct {
+ UINT32 Enable:1; // Enable CCX2
+ UINT32 LeapEnable:1; // Enable LEAP at CCX2
+ UINT32 RMEnable:1; // Radio Measurement Enable
+ UINT32 DCRMEnable:1; // Non serving channel Radio Measurement enable
+ UINT32 QOSEnable:1; // Enable QOS for CCX 2.0 support
+ UINT32 FastRoamEnable:1; // Enable fast roaming
+ UINT32 Rsvd:2; // Not used
+ UINT32 dBmToRoam:8; // the condition to roam when receiving Rssi less than this value. It's negative value.
+ UINT32 TuLimit:16; // Limit for different channel scan
+ } field;
+ UINT32 word;
+} CCX_CONTROL, *PCCX_CONTROL;
+
+#endif // __AIRONET_H__
diff --git a/drivers/staging/rt3070/ap.h b/drivers/staging/rt3070/ap.h
new file mode 100644
index 00000000000..f5ba042e52b
--- /dev/null
+++ b/drivers/staging/rt3070/ap.h
@@ -0,0 +1,557 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ ap.h
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 08-01-2002 created
+ James Tan 09-06-2002 modified (Revise NTCRegTable)
+ John Chang 12-22-2004 modified for RT2561/2661. merge with STA driver
+*/
+#ifndef __AP_H__
+#define __AP_H__
+
+
+
+// ========================= AP RTMP.h ================================
+
+
+
+// =============================================================
+// Function Prototypes
+// =============================================================
+
+// ap_data.c
+
+BOOLEAN APBridgeToWirelessSta(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN UINT DataLen,
+ IN ULONG fromwdsidx);
+
+BOOLEAN APHandleRxDoneInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APSendPackets(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PPNDIS_PACKET ppPacketArray,
+ IN UINT NumberOfPackets);
+
+NDIS_STATUS APSendPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+
+NDIS_STATUS APHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR QueIdx);
+
+VOID APRxEAPOLFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+NDIS_STATUS APCheckRxError(
+ IN PRTMP_ADAPTER pAd,
+ IN PRT28XX_RXD_STRUC pRxD,
+ IN UCHAR Wcid);
+
+BOOLEAN APCheckClass2Class3Error(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN PHEADER_802_11 pHeader);
+
+VOID APHandleRxPsPoll(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN USHORT Aid,
+ IN BOOLEAN isActive);
+
+VOID RTMPDescriptorEndianChange(
+ IN PUCHAR pData,
+ IN ULONG DescriptorType);
+
+VOID RTMPFrameEndianChange(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG Dir,
+ IN BOOLEAN FromRxDoneInt);
+
+// ap_assoc.c
+
+VOID APAssocStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID APPeerAssocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerReassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MbssKickOutStas(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN USHORT Reason);
+
+VOID APMlmeKickOutSta(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pStaAddr,
+ IN UCHAR Wcid,
+ IN USHORT Reason);
+
+VOID APMlmeDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APCls3errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN PHEADER_802_11 pHeader);
+
+
+USHORT APBuildAssociation(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN USHORT CapabilityInfo,
+ IN UCHAR MaxSupportedRateIn500Kbps,
+ IN UCHAR *RSN,
+ IN UCHAR *pRSNLen,
+ IN BOOLEAN bWmmCapable,
+ IN ULONG RalinkIe,
+#ifdef DOT11N_DRAFT3
+ IN EXT_CAP_INFO_ELEMENT ExtCapInfo,
+#endif // DOT11N_DRAFT3 //
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ OUT USHORT *pAid);
+
+/*
+VOID RTMPAddClientSec(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIdx,
+ IN UCHAR KeyIdx,
+ IN UCHAR CipherAlg,
+ IN PUCHAR pKey,
+ IN PUCHAR pTxMic,
+ IN PUCHAR pRxMic,
+ IN MAC_TABLE_ENTRY *pEntry);
+*/
+
+// ap_auth.c
+
+void APAuthStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID APMlmeDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APCls2errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN PHEADER_802_11 pHeader);
+
+// ap_authrsp.c
+
+VOID APAuthRspStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTATE_MACHINE Sm,
+ IN STATE_MACHINE_FUNC Trans[]);
+
+VOID APPeerAuthAtAuthRspIdleAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerAuthSimpleRspGenAndSend(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHdr80211,
+ IN USHORT Alg,
+ IN USHORT Seq,
+ IN USHORT StatusCode);
+
+// ap_connect.c
+
+BOOLEAN BeaconTransmitRequired(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx);
+
+VOID APMakeBssBeacon(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx);
+
+VOID APUpdateBeaconFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx);
+
+VOID APMakeAllBssBeacon(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APUpdateAllBeaconFrame(
+ IN PRTMP_ADAPTER pAd);
+
+
+// ap_sync.c
+
+VOID APSyncStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID APScanTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID APInvalidStateWhenScan(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APScanTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerProbeReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerBeaconAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APMlmeScanReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerBeaconAtScanAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APScanCnclAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ApSiteSurvey(
+ IN PRTMP_ADAPTER pAd);
+
+VOID SupportRate(
+ IN PUCHAR SupRate,
+ IN UCHAR SupRateLen,
+ IN PUCHAR ExtRate,
+ IN UCHAR ExtRateLen,
+ OUT PUCHAR *Rates,
+ OUT PUCHAR RatesLen,
+ OUT PUCHAR pMaxSupportRate);
+
+
+BOOLEAN ApScanRunning(
+ IN PRTMP_ADAPTER pAd);
+
+#ifdef DOT11N_DRAFT3
+VOID APOverlappingBSSScan(
+ IN RTMP_ADAPTER *pAd);
+#endif // DOT11N_DRAFT3 //
+
+// ap_wpa.c
+
+VOID APWpaStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+// ap_mlme.c
+
+VOID APMlmePeriodicExec(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APMlmeSelectTxRateTable(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR *ppTable,
+ IN PUCHAR pTableSize,
+ IN PUCHAR pInitTxRateIdx);
+
+VOID APMlmeSetTxRate(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PRTMP_TX_RATE_SWITCH pTxRate);
+
+VOID APMlmeDynamicTxRateSwitching(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APQuickResponeForRateUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+BOOLEAN APMsgTypeSubst(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 pFrame,
+ OUT INT *Machine,
+ OUT INT *MsgType);
+
+VOID APQuickResponeForRateUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+#ifdef RT2870
+VOID BeaconUpdateExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+#endif // RT2870 //
+
+VOID RTMPSetPiggyBack(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bPiggyBack);
+
+VOID APAsicEvaluateRxAnt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APAsicRxAntEvalTimeout(
+ IN PRTMP_ADAPTER pAd);
+
+// ap.c
+
+VOID APSwitchChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN INT Channel);
+
+NDIS_STATUS APInitialize(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APShutdown(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APStartUp(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APStop(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APCleanupPsQueue(
+ IN PRTMP_ADAPTER pAd,
+ IN PQUEUE_HEADER pQueue);
+
+VOID MacTableReset(
+ IN PRTMP_ADAPTER pAd);
+
+MAC_TABLE_ENTRY *MacTableInsertEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR apidx,
+ IN BOOLEAN CleanAll);
+
+BOOLEAN MacTableDeleteEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT wcid,
+ IN PUCHAR pAddr);
+
+MAC_TABLE_ENTRY *MacTableLookup(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr);
+
+VOID MacTableMaintenance(
+ IN PRTMP_ADAPTER pAd);
+
+UINT32 MacTableAssocStaNumGet(
+ IN PRTMP_ADAPTER pAd);
+
+MAC_TABLE_ENTRY *APSsPsInquiry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ OUT SST *Sst,
+ OUT USHORT *Aid,
+ OUT UCHAR *PsMode,
+ OUT UCHAR *Rate);
+
+BOOLEAN APPsIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN ULONG Wcid,
+ IN UCHAR Psm);
+
+VOID ApLogEvent(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN USHORT Event);
+
+#ifdef DOT11_N_SUPPORT
+VOID APUpdateOperationMode(
+ IN PRTMP_ADAPTER pAd);
+#endif // DOT11_N_SUPPORT //
+
+VOID APUpdateCapabilityAndErpIe(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN ApCheckAccessControlList(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR Apidx);
+
+VOID ApUpdateAccessControlList(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Apidx);
+
+VOID ApEnqueueNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR TxRate,
+ IN UCHAR PID,
+ IN UCHAR apidx,
+ IN BOOLEAN bQosNull,
+ IN BOOLEAN bEOSP,
+ IN UCHAR OldUP);
+
+VOID ApSendFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PVOID pBuffer,
+ IN ULONG Length,
+ IN UCHAR TxRate,
+ IN UCHAR PID);
+
+VOID ApEnqueueAckFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR TxRate,
+ IN UCHAR apidx);
+
+UCHAR APAutoSelectChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN Optimal);
+
+// ap_sanity.c
+
+
+BOOLEAN PeerAssocReqCmmSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN isRessoc,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pListenInterval,
+ OUT PUCHAR pApAddr,
+ OUT UCHAR *pSsidLen,
+ OUT char *Ssid,
+ OUT UCHAR *pRatesLen,
+ OUT UCHAR Rates[],
+ OUT UCHAR *RSN,
+ OUT UCHAR *pRSNLen,
+ OUT BOOLEAN *pbWmmCapable,
+ OUT ULONG *pRalinkIe,
+#ifdef DOT11N_DRAFT3
+ OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo,
+#endif // DOT11N_DRAFT3 //
+ OUT UCHAR *pHtCapabilityLen,
+ OUT HT_CAPABILITY_IE *pHtCapability);
+
+
+BOOLEAN PeerDisassocReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *Reason);
+
+BOOLEAN PeerDeauthReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *Reason);
+
+BOOLEAN APPeerAuthSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr1,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *Alg,
+ OUT USHORT *Seq,
+ OUT USHORT *Status,
+ CHAR *ChlgText);
+
+BOOLEAN APPeerProbeReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT CHAR Ssid[],
+ OUT UCHAR *SsidLen);
+
+BOOLEAN APPeerBeaconAndProbeRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT PUCHAR pBssid,
+ OUT CHAR Ssid[],
+ OUT UCHAR *SsidLen,
+ OUT UCHAR *BssType,
+ OUT USHORT *BeaconPeriod,
+ OUT UCHAR *Channel,
+ OUT LARGE_INTEGER *Timestamp,
+ OUT USHORT *CapabilityInfo,
+ OUT UCHAR Rate[],
+ OUT UCHAR *RateLen,
+ OUT BOOLEAN *ExtendedRateIeExist,
+ OUT UCHAR *Erp);
+
+
+// ================== end of AP RTMP.h ========================
+
+
+#endif // __AP_H__
+
diff --git a/drivers/staging/rt3070/chlist.h b/drivers/staging/rt3070/chlist.h
new file mode 100644
index 00000000000..7151e8668cb
--- /dev/null
+++ b/drivers/staging/rt3070/chlist.h
@@ -0,0 +1,1253 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ chlist.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Fonchi Wu 2007-12-19 created
+*/
+
+#ifndef __CHLIST_H__
+#define __CHLIST_H__
+
+#include "rtmp_type.h"
+#include "rtmp_def.h"
+
+
+#define ODOR 0
+#define IDOR 1
+#define BOTH 2
+
+#define BAND_5G 0
+#define BAND_24G 1
+#define BAND_BOTH 2
+
+typedef struct _CH_DESP {
+ UCHAR FirstChannel;
+ UCHAR NumOfCh;
+ CHAR MaxTxPwr; // dBm
+ UCHAR Geography; // 0:out door, 1:in door, 2:both
+ BOOLEAN DfsReq; // Dfs require, 0: No, 1: yes.
+} CH_DESP, *PCH_DESP;
+
+typedef struct _CH_REGION {
+ UCHAR CountReg[3];
+ UCHAR DfsType; // 0: CE, 1: FCC, 2: JAP, 3:JAP_W53, JAP_W56
+ CH_DESP ChDesp[10];
+} CH_REGION, *PCH_REGION;
+
+static CH_REGION ChRegion[] =
+{
+ { // Antigua and Berbuda
+ "AG",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Argentina
+ "AR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Aruba
+ "AW",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Australia
+ "AU",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Austria
+ "AT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Bahamas
+ "BS",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Barbados
+ "BB",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Bermuda
+ "BM",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Brazil
+ "BR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 24, BOTH, FALSE}, // 5G, ch 100~140
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Belgium
+ "BE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 18, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 18, IDOR, FALSE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // Bulgaria
+ "BG",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Canada
+ "CA",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Cayman IsLands
+ "KY",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Chile
+ "CL",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // China
+ "CN",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Colombia
+ "CO",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Costa Rica
+ "CR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Cyprus
+ "CY",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Czech_Republic
+ "CZ",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // Denmark
+ "DK",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Dominican Republic
+ "DO",
+ CE,
+ {
+ { 1, 0, 20, BOTH, FALSE}, // 2.4 G, ch 0
+ { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Equador
+ "EC",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 100, 11, 27, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // El Salvador
+ "SV",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 30, BOTH, TRUE}, // 5G, ch 52~64
+ { 149, 4, 36, BOTH, TRUE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Finland
+ "FI",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // France
+ "FR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // Germany
+ "DE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Greece
+ "GR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Guam
+ "GU",
+ CE,
+ {
+ { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Guatemala
+ "GT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Haiti
+ "HT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Honduras
+ "HN",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Hong Kong
+ "HK",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Hungary
+ "HU",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // Iceland
+ "IS",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // India
+ "IN",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 149, 4, 24, IDOR, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Indonesia
+ "ID",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Ireland
+ "IE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Israel
+ "IL",
+ CE,
+ {
+ { 1, 3, 20, IDOR, FALSE}, // 2.4 G, ch 1~3
+ { 4, 6, 20, BOTH, FALSE}, // 2.4 G, ch 4~9
+ { 10, 4, 20, IDOR, FALSE}, // 2.4 G, ch 10~13
+ { 0}, // end
+ }
+ },
+
+ { // Italy
+ "IT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Japan
+ "JP",
+ JAP,
+ {
+ { 1, 14, 20, BOTH, FALSE}, // 2.4 G, ch 1~14
+ { 34, 4, 23, IDOR, FALSE}, // 5G, ch 34~46
+ { 0}, // end
+ }
+ },
+
+ { // Jordan
+ "JO",
+ CE,
+ {
+ { 1, 13, 20, IDOR, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 149, 4, 23, IDOR, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Latvia
+ "LV",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Liechtenstein
+ "LI",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Lithuania
+ "LT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Luxemburg
+ "LU",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Malaysia
+ "MY",
+ CE,
+ {
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Malta
+ "MT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Marocco
+ "MA",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48
+ { 0}, // end
+ }
+ },
+
+ { // Mexico
+ "MX",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 5, 30, IDOR, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Netherlands
+ "NL",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // New Zealand
+ "NZ",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 24, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Norway
+ "NO",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Peru
+ "PE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Portugal
+ "PT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Poland
+ "PL",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Romania
+ "RO",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Russia
+ "RU",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 149, 4, 20, IDOR, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Saudi Arabia
+ "SA",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 23, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Serbia_and_Montenegro
+ "CS",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 0}, // end
+ }
+ },
+
+ { // Singapore
+ "SG",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Slovakia
+ "SK",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Slovenia
+ "SI",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // South Africa
+ "ZA",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // South Korea
+ "KR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 8, 20, BOTH, FALSE}, // 5G, ch 100~128
+ { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Spain
+ "ES",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 17, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Sweden
+ "SE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Switzerland
+ "CH",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // Taiwan
+ "TW",
+ CE,
+ {
+ { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // Turkey
+ "TR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // UK
+ "GB",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Ukraine
+ "UA",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 0}, // end
+ }
+ },
+
+ { // United_Arab_Emirates
+ "AE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 0}, // end
+ }
+ },
+
+ { // United_States
+ "US",
+ CE,
+ {
+ { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 36, 4, 17, IDOR, FALSE}, // 5G, ch 52~64
+ { 52, 4, 24, BOTH, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Venezuela
+ "VE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Default
+ "",
+ CE,
+ {
+ { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 36, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
+ { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 20, BOTH, FALSE}, // 5G, ch 100~140
+ { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+};
+
+static inline PCH_REGION GetChRegion(
+ IN PUCHAR CntryCode)
+{
+ INT loop = 0;
+ PCH_REGION pChRegion = NULL;
+
+ while (strcmp(ChRegion[loop].CountReg, "") != 0)
+ {
+ if (strncmp(ChRegion[loop].CountReg, CntryCode, 2) == 0)
+ {
+ pChRegion = &ChRegion[loop];
+ break;
+ }
+ loop++;
+ }
+
+ if (pChRegion == NULL)
+ pChRegion = &ChRegion[loop];
+ return pChRegion;
+}
+
+static inline VOID ChBandCheck(
+ IN UCHAR PhyMode,
+ OUT PUCHAR pChType)
+{
+ switch(PhyMode)
+ {
+ case PHY_11A:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11AN_MIXED:
+#endif // DOT11_N_SUPPORT //
+ *pChType = BAND_5G;
+ break;
+ case PHY_11ABG_MIXED:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11AGN_MIXED:
+ case PHY_11ABGN_MIXED:
+#endif // DOT11_N_SUPPORT //
+ *pChType = BAND_BOTH;
+ break;
+
+ default:
+ *pChType = BAND_24G;
+ break;
+ }
+}
+
+static inline UCHAR FillChList(
+ IN PRTMP_ADAPTER pAd,
+ IN PCH_DESP pChDesp,
+ IN UCHAR Offset,
+ IN UCHAR increment)
+{
+ INT i, j, l;
+ UCHAR channel;
+
+ j = Offset;
+ for (i = 0; i < pChDesp->NumOfCh; i++)
+ {
+ channel = pChDesp->FirstChannel + i * increment;
+ for (l=0; l<MAX_NUM_OF_CHANNELS; l++)
+ {
+ if (channel == pAd->TxPower[l].Channel)
+ {
+ pAd->ChannelList[j].Power = pAd->TxPower[l].Power;
+ pAd->ChannelList[j].Power2 = pAd->TxPower[l].Power2;
+ break;
+ }
+ }
+ if (l == MAX_NUM_OF_CHANNELS)
+ continue;
+
+ pAd->ChannelList[j].Channel = pChDesp->FirstChannel + i * increment;
+ pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr;
+ pAd->ChannelList[j].DfsReq = pChDesp->DfsReq;
+ j++;
+ }
+ pAd->ChannelListNum = j;
+
+ return j;
+}
+
+static inline VOID CreateChList(
+ IN PRTMP_ADAPTER pAd,
+ IN PCH_REGION pChRegion,
+ IN UCHAR Geography)
+{
+ INT i;
+ UCHAR offset = 0;
+ PCH_DESP pChDesp;
+ UCHAR ChType;
+ UCHAR increment;
+
+ if (pChRegion == NULL)
+ return;
+
+ ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
+
+ for (i=0; i<10; i++)
+ {
+ pChDesp = &pChRegion->ChDesp[i];
+ if (pChDesp->FirstChannel == 0)
+ break;
+
+ if (ChType == BAND_5G)
+ {
+ if (pChDesp->FirstChannel <= 14)
+ continue;
+ }
+ else if (ChType == BAND_24G)
+ {
+ if (pChDesp->FirstChannel > 14)
+ continue;
+ }
+
+ if ((pChDesp->Geography == BOTH)
+ || (pChDesp->Geography == Geography))
+ {
+ if (pChDesp->FirstChannel > 14)
+ increment = 4;
+ else
+ increment = 1;
+ offset = FillChList(pAd, pChDesp, offset, increment);
+ }
+ }
+}
+
+static inline VOID BuildChannelListEx(
+ IN PRTMP_ADAPTER pAd)
+{
+ PCH_REGION pChReg;
+
+ pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
+ CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
+}
+
+static inline VOID BuildBeaconChList(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf,
+ OUT PULONG pBufLen)
+{
+ INT i;
+ ULONG TmpLen;
+ PCH_REGION pChRegion;
+ PCH_DESP pChDesp;
+ UCHAR ChType;
+
+ pChRegion = GetChRegion(pAd->CommonCfg.CountryCode);
+
+ if (pChRegion == NULL)
+ return;
+
+ ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
+ *pBufLen = 0;
+
+ for (i=0; i<10; i++)
+ {
+ pChDesp = &pChRegion->ChDesp[i];
+ if (pChDesp->FirstChannel == 0)
+ break;
+
+ if (ChType == BAND_5G)
+ {
+ if (pChDesp->FirstChannel <= 14)
+ continue;
+ }
+ else if (ChType == BAND_24G)
+ {
+ if (pChDesp->FirstChannel > 14)
+ continue;
+ }
+
+ if ((pChDesp->Geography == BOTH)
+ || (pChDesp->Geography == pAd->CommonCfg.Geography))
+ {
+ MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen,
+ 1, &pChDesp->FirstChannel,
+ 1, &pChDesp->NumOfCh,
+ 1, &pChDesp->MaxTxPwr,
+ END_OF_ARGS);
+ *pBufLen += TmpLen;
+ }
+ }
+}
+
+
+#ifdef DOT11_N_SUPPORT
+static inline BOOLEAN IsValidChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel)
+
+{
+ INT i;
+
+ for (i = 0; i < pAd->ChannelListNum; i++)
+ {
+ if (pAd->ChannelList[i].Channel == channel)
+ break;
+ }
+
+ if (i == pAd->ChannelListNum)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+
+static inline UCHAR GetExtCh(
+ IN UCHAR Channel,
+ IN UCHAR Direction)
+{
+ CHAR ExtCh;
+
+ if (Direction == EXTCHA_ABOVE)
+ ExtCh = Channel + 4;
+ else
+ ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0;
+
+ return ExtCh;
+}
+
+
+static inline VOID N_ChannelCheck(
+ IN PRTMP_ADAPTER pAd)
+{
+ //UCHAR ChannelNum = pAd->ChannelListNum;
+ UCHAR Channel = pAd->CommonCfg.Channel;
+
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
+ {
+ if (Channel > 14)
+ {
+ if ((Channel == 36) || (Channel == 44) || (Channel == 52) || (Channel == 60) || (Channel == 100) || (Channel == 108) ||
+ (Channel == 116) || (Channel == 124) || (Channel == 132) || (Channel == 149) || (Channel == 157))
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
+ }
+ else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) ||
+ (Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161))
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
+ }
+ else
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ }
+ }
+ else
+ {
+ do
+ {
+ UCHAR ExtCh;
+ UCHAR Dir = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
+ ExtCh = GetExtCh(Channel, Dir);
+ if (IsValidChannel(pAd, ExtCh))
+ break;
+
+ Dir = (Dir == EXTCHA_ABOVE) ? EXTCHA_BELOW : EXTCHA_ABOVE;
+ ExtCh = GetExtCh(Channel, Dir);
+ if (IsValidChannel(pAd, ExtCh))
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = Dir;
+ break;
+ }
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ } while(FALSE);
+
+ if (Channel == 14)
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ //pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE; // We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT()
+ }
+ }
+ }
+
+
+}
+
+
+static inline VOID N_SetCenCh(
+ IN PRTMP_ADAPTER pAd)
+{
+ if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+ {
+ if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
+ {
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
+ }
+ else
+ {
+ if (pAd->CommonCfg.Channel == 14)
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1;
+ else
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
+ }
+ }
+ else
+ {
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ }
+}
+#endif // DOT11_N_SUPPORT //
+
+
+static inline UINT8 GetCuntryMaxTxPwr(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 channel)
+{
+ int i;
+ for (i = 0; i < pAd->ChannelListNum; i++)
+ {
+ if (pAd->ChannelList[i].Channel == channel)
+ break;
+ }
+
+ if (i == pAd->ChannelListNum)
+ return 0xff;
+ else
+ return pAd->ChannelList[i].MaxTxPwr;
+}
+#endif // __CHLIST_H__
+
diff --git a/drivers/staging/rt3070/common/2870_rtmp_init.c b/drivers/staging/rt3070/common/2870_rtmp_init.c
new file mode 100644
index 00000000000..fdf8dc176a6
--- /dev/null
+++ b/drivers/staging/rt3070/common/2870_rtmp_init.c
@@ -0,0 +1,1762 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ 2870_rtmp_init.c
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 2002-08-01 created
+ John Chang 2004-08-20 RT2561/2661 use scatter-gather scheme
+ Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
+ Sample Lin 2007-05-31 Merge RT2860 and RT2870 drivers.
+*/
+
+#include "../rt_config.h"
+
+
+static void rx_done_tasklet(unsigned long data);
+static void rt2870_hcca_dma_done_tasklet(unsigned long data);
+static void rt2870_ac3_dma_done_tasklet(unsigned long data);
+static void rt2870_ac2_dma_done_tasklet(unsigned long data);
+static void rt2870_ac1_dma_done_tasklet(unsigned long data);
+static void rt2870_ac0_dma_done_tasklet(unsigned long data);
+static void rt2870_mgmt_dma_done_tasklet(unsigned long data);
+static void rt2870_null_frame_complete_tasklet(unsigned long data);
+static void rt2870_rts_frame_complete_tasklet(unsigned long data);
+static void rt2870_pspoll_frame_complete_tasklet(unsigned long data);
+static void rt2870_dataout_complete_tasklet(unsigned long data);
+
+
+/*
+========================================================================
+Routine Description:
+ Initialize receive data structures.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_RESOURCES
+
+Note:
+ Initialize all receive releated private buffer, include those define
+ in RTMP_ADAPTER structure and all private data structures. The mahor
+ work is to allocate buffer for each packet and chain buffer to
+ NDIS packet descriptor.
+========================================================================
+*/
+NDIS_STATUS NICInitRecv(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR i;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
+ pObj = pObj;
+
+ //InterlockedExchange(&pAd->PendingRx, 0);
+ pAd->PendingRx = 0;
+ pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
+ pAd->NextRxBulkInIndex = 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer
+ pAd->NextRxBulkInPosition = 0;
+
+ for (i = 0; i < (RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+
+ //Allocate URB
+ pRxContext->pUrb = RTUSB_ALLOC_URB(0);
+ if (pRxContext->pUrb == NULL)
+ {
+ Status = NDIS_STATUS_RESOURCES;
+ goto out1;
+ }
+
+ // Allocate transfer buffer
+ pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma);
+ if (pRxContext->TransferBuffer == NULL)
+ {
+ Status = NDIS_STATUS_RESOURCES;
+ goto out1;
+ }
+
+ NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
+
+ pRxContext->pAd = pAd;
+ pRxContext->pIrp = NULL;
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pRxContext->Readable = FALSE;
+ //pRxContext->ReorderInUse = FALSE;
+ pRxContext->bRxHandling = FALSE;
+ pRxContext->BulkInOffset = 0;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv\n"));
+ return Status;
+
+out1:
+ for (i = 0; i < (RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+
+ if (NULL != pRxContext->TransferBuffer)
+ {
+ RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
+ pRxContext->TransferBuffer, pRxContext->data_dma);
+ pRxContext->TransferBuffer = NULL;
+ }
+
+ if (NULL != pRxContext->pUrb)
+ {
+ RTUSB_UNLINK_URB(pRxContext->pUrb);
+ RTUSB_FREE_URB(pRxContext->pUrb);
+ pRxContext->pUrb = NULL;
+ }
+ }
+
+ return Status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Initialize transmit data structures.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+NDIS_STATUS NICInitTransmit(
+ IN PRTMP_ADAPTER pAd)
+{
+#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \
+ Context->pUrb = RTUSB_ALLOC_URB(0); \
+ if (Context->pUrb == NULL) { \
+ DBGPRINT(RT_DEBUG_ERROR, msg1); \
+ Status = NDIS_STATUS_RESOURCES; \
+ goto err1; } \
+ \
+ Context->TransferBuffer = \
+ (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \
+ if (Context->TransferBuffer == NULL) { \
+ DBGPRINT(RT_DEBUG_ERROR, msg2); \
+ Status = NDIS_STATUS_RESOURCES; \
+ goto err2; }
+
+#define LM_URB_FREE(pObj, Context, BufferSize) \
+ if (NULL != Context->pUrb) { \
+ RTUSB_UNLINK_URB(Context->pUrb); \
+ RTUSB_FREE_URB(Context->pUrb); \
+ Context->pUrb = NULL; } \
+ if (NULL != Context->TransferBuffer) { \
+ RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
+ Context->TransferBuffer, \
+ Context->data_dma); \
+ Context->TransferBuffer = NULL; }
+
+ UCHAR i, acidx;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ PTX_CONTEXT pNullContext = &(pAd->NullContext);
+ PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
+ PTX_CONTEXT pRTSContext = &(pAd->RTSContext);
+ PTX_CONTEXT pMLMEContext = NULL;
+// PHT_TX_CONTEXT pHTTXContext = NULL;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ PVOID RingBaseVa;
+// RTMP_TX_RING *pTxRing;
+ RTMP_MGMT_RING *pMgmtRing;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
+ pObj = pObj;
+
+ // Init 4 set of Tx parameters
+ for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++)
+ {
+ // Initialize all Transmit releated queues
+ InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
+
+ // Next Local tx ring pointer waiting for buck out
+ pAd->NextBulkOutIndex[acidx] = acidx;
+ pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag
+ //pAd->DataBulkDoneIdx[acidx] = 0;
+ }
+
+ //pAd->NextMLMEIndex = 0;
+ //pAd->PushMgmtIndex = 0;
+ //pAd->PopMgmtIndex = 0;
+ //InterlockedExchange(&pAd->MgmtQueueSize, 0);
+ //InterlockedExchange(&pAd->TxCount, 0);
+
+ //pAd->PrioRingFirstIndex = 0;
+ //pAd->PrioRingTxCnt = 0;
+
+ do
+ {
+ //
+ // TX_RING_SIZE, 4 ACs
+ //
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ for(acidx=0; acidx<4; acidx++)
+#endif // CONFIG_STA_SUPPORT //
+ {
+#if 1 //def DOT11_N_SUPPORT
+ PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
+
+ NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
+ //Allocate URB
+ LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status,
+ ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx),
+ done,
+ ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx),
+ out1);
+
+ NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4);
+ pHTTXContext->pAd = pAd;
+ pHTTXContext->pIrp = NULL;
+ pHTTXContext->IRPPending = FALSE;
+ pHTTXContext->NextBulkOutPosition = 0;
+ pHTTXContext->ENextBulkOutPosition = 0;
+ pHTTXContext->CurWritePosition = 0;
+ pHTTXContext->CurWriteRealPos = 0;
+ pHTTXContext->BulkOutSize = 0;
+ pHTTXContext->BulkOutPipeId = acidx;
+ pHTTXContext->bRingEmpty = TRUE;
+ pHTTXContext->bCopySavePad = FALSE;
+#endif // DOT11_N_SUPPORT //
+ pAd->BulkOutPending[acidx] = FALSE;
+ }
+
+
+ //
+ // MGMT_RING_SIZE
+ //
+ // Allocate MGMT ring descriptor's memory
+ pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
+ RTMPAllocateMemory(&pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
+ if (pAd->MgmtDescRing.AllocVa == NULL)
+ {
+ DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
+ Status = NDIS_STATUS_RESOURCES;
+ goto out1;
+ }
+ NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
+ RingBaseVa = pAd->MgmtDescRing.AllocVa;
+
+ // Initialize MGMT Ring and associated buffer memory
+ pMgmtRing = &pAd->MgmtRing;
+ for (i = 0; i < MGMT_RING_SIZE; i++)
+ {
+ // link the pre-allocated Mgmt buffer to MgmtRing.Cell
+ pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
+ pMgmtRing->Cell[i].AllocVa = RingBaseVa;
+ pMgmtRing->Cell[i].pNdisPacket = NULL;
+ pMgmtRing->Cell[i].pNextNdisPacket = NULL;
+
+ //Allocate URB for MLMEContext
+ pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
+ pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
+ if (pMLMEContext->pUrb == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
+ Status = NDIS_STATUS_RESOURCES;
+ goto out2;
+ }
+ pMLMEContext->pAd = pAd;
+ pMLMEContext->pIrp = NULL;
+ pMLMEContext->TransferBuffer = NULL;
+ pMLMEContext->InUse = FALSE;
+ pMLMEContext->IRPPending = FALSE;
+ pMLMEContext->bWaitingBulkOut = FALSE;
+ pMLMEContext->BulkOutSize = 0;
+ pMLMEContext->SelfIdx = i;
+
+ // Offset to next ring descriptor address
+ RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
+
+ //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
+ pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
+ pAd->MgmtRing.TxCpuIdx = 0;
+ pAd->MgmtRing.TxDmaIdx = 0;
+
+ //
+ // BEACON_RING_SIZE
+ //
+ for(i=0; i<BEACON_RING_SIZE; i++) // 2
+ {
+ PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
+
+
+ NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
+
+ //Allocate URB
+ LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+ ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
+ out2,
+ ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
+ out3);
+
+ pBeaconContext->pAd = pAd;
+ pBeaconContext->pIrp = NULL;
+ pBeaconContext->InUse = FALSE;
+ pBeaconContext->IRPPending = FALSE;
+ }
+
+ //
+ // NullContext
+ //
+ NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
+
+ //Allocate URB
+ LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+ ("<-- ERROR in Alloc TX NullContext urb!! \n"),
+ out3,
+ ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
+ out4);
+
+ pNullContext->pAd = pAd;
+ pNullContext->pIrp = NULL;
+ pNullContext->InUse = FALSE;
+ pNullContext->IRPPending = FALSE;
+
+ //
+ // RTSContext
+ //
+ NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
+
+ //Allocate URB
+ LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+ ("<-- ERROR in Alloc TX RTSContext urb!! \n"),
+ out4,
+ ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
+ out5);
+
+ pRTSContext->pAd = pAd;
+ pRTSContext->pIrp = NULL;
+ pRTSContext->InUse = FALSE;
+ pRTSContext->IRPPending = FALSE;
+
+ //
+ // PsPollContext
+ //
+ //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
+ //Allocate URB
+ LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+ ("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
+ out5,
+ ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
+ out6);
+
+ pPsPollContext->pAd = pAd;
+ pPsPollContext->pIrp = NULL;
+ pPsPollContext->InUse = FALSE;
+ pPsPollContext->IRPPending = FALSE;
+ pPsPollContext->bAggregatible = FALSE;
+ pPsPollContext->LastOne = TRUE;
+
+ } while (FALSE);
+
+
+done:
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit\n"));
+
+ return Status;
+
+ /* --------------------------- ERROR HANDLE --------------------------- */
+out6:
+ LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
+
+out5:
+ LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
+
+out4:
+ LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
+
+out3:
+ for(i=0; i<BEACON_RING_SIZE; i++)
+ {
+ PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
+ if (pBeaconContext)
+ LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
+ }
+
+out2:
+ if (pAd->MgmtDescRing.AllocVa)
+ {
+ pMgmtRing = &pAd->MgmtRing;
+ for(i=0; i<MGMT_RING_SIZE; i++)
+ {
+ pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
+ if (pMLMEContext)
+ LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
+ }
+ NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
+ pAd->MgmtDescRing.AllocVa = NULL;
+ }
+
+out1:
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ for(acidx=0; acidx<4; acidx++)
+#endif // CONFIG_STA_SUPPORT //
+ {
+ PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
+ if (pTxContext)
+ LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
+ }
+
+ // Here we didn't have any pre-allocated memory need to free.
+
+ return Status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Allocate DMA memory blocks for send, receive.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_FAILURE
+ NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+NDIS_STATUS RTMPAllocTxRxRingMemory(
+ IN PRTMP_ADAPTER pAd)
+{
+// COUNTER_802_11 pCounter = &pAd->WlanCounters;
+ NDIS_STATUS Status;
+ INT num;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
+
+
+ do
+ {
+ // Init the CmdQ and CmdQLock
+ NdisAllocateSpinLock(&pAd->CmdQLock);
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ RTUSBInitializeCmdQ(&pAd->CmdQ);
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+
+
+ NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
+ //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
+ NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
+ NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
+ NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
+ NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
+ NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
+ NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
+ NdisAllocateSpinLock(&pAd->BulkInLock);
+
+ for (num = 0; num < NUM_OF_TX_RING; num++)
+ {
+ NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
+ }
+
+#ifdef RALINK_ATE
+ NdisAllocateSpinLock(&pAd->GenericLock);
+#endif // RALINK_ATE //
+
+// NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX
+
+// NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
+// NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
+
+// for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
+// {
+// NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
+// }
+
+ //
+ // Init Mac Table
+ //
+// MacTableInitialize(pAd);
+
+ //
+ // Init send data structures and related parameters
+ //
+ Status = NICInitTransmit(pAd);
+ if (Status != NDIS_STATUS_SUCCESS)
+ break;
+
+ //
+ // Init receive data structures and related parameters
+ //
+ Status = NICInitRecv(pAd);
+ if (Status != NDIS_STATUS_SUCCESS)
+ break;
+
+ pAd->PendingIoCount = 1;
+
+ } while (FALSE);
+
+ NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
+ pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
+
+ if (pAd->FragFrame.pFragPacket == NULL)
+ {
+ Status = NDIS_STATUS_RESOURCES;
+ }
+
+ DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
+ return Status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Calls USB_InterfaceStop and frees memory allocated for the URBs
+ calls NdisMDeregisterDevice and frees the memory
+ allocated in VNetInitialize for the Adapter Object
+
+Arguments:
+ *pAd the raxx interface data pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RTMPFreeTxRxRingMemory(
+ IN PRTMP_ADAPTER pAd)
+{
+#define LM_URB_FREE(pObj, Context, BufferSize) \
+ if (NULL != Context->pUrb) { \
+ RTUSB_UNLINK_URB(Context->pUrb); \
+ RTUSB_FREE_URB(Context->pUrb); \
+ Context->pUrb = NULL; } \
+ if (NULL != Context->TransferBuffer) { \
+ RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
+ Context->TransferBuffer, \
+ Context->data_dma); \
+ Context->TransferBuffer = NULL; }
+
+
+ UINT i, acidx;
+ PTX_CONTEXT pNullContext = &pAd->NullContext;
+ PTX_CONTEXT pPsPollContext = &pAd->PsPollContext;
+ PTX_CONTEXT pRTSContext = &pAd->RTSContext;
+// PHT_TX_CONTEXT pHTTXContext;
+ //PRTMP_REORDERBUF pReorderBuf;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+// RTMP_TX_RING *pTxRing;
+
+ DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
+ pObj = pObj;
+
+ // Free all resources for the RECEIVE buffer queue.
+ for(i=0; i<(RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+ if (pRxContext)
+ LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
+ }
+
+ // Free PsPoll frame resource
+ LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
+
+ // Free NULL frame resource
+ LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
+
+ // Free RTS frame resource
+ LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
+
+
+ // Free beacon frame resource
+ for(i=0; i<BEACON_RING_SIZE; i++)
+ {
+ PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
+ if (pBeaconContext)
+ LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
+ }
+
+
+ // Free mgmt frame resource
+ for(i = 0; i < MGMT_RING_SIZE; i++)
+ {
+ PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
+ //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
+ if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
+ {
+ RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
+ pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
+ pMLMEContext->TransferBuffer = NULL;
+ }
+
+ if (pMLMEContext)
+ {
+ if (NULL != pMLMEContext->pUrb)
+ {
+ RTUSB_UNLINK_URB(pMLMEContext->pUrb);
+ RTUSB_FREE_URB(pMLMEContext->pUrb);
+ pMLMEContext->pUrb = NULL;
+ }
+ }
+ }
+ if (pAd->MgmtDescRing.AllocVa)
+ NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
+
+
+ // Free Tx frame resource
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ for(acidx=0; acidx<4; acidx++)
+#endif // CONFIG_STA_SUPPORT //
+ {
+ PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
+ if (pHTTXContext)
+ LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
+ }
+
+ if (pAd->FragFrame.pFragPacket)
+ RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
+
+ for(i=0; i<6; i++)
+ {
+ NdisFreeSpinLock(&pAd->BulkOutLock[i]);
+ }
+
+ NdisFreeSpinLock(&pAd->BulkInLock);
+ NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
+
+ NdisFreeSpinLock(&pAd->CmdQLock);
+#ifdef RALINK_ATE
+ NdisFreeSpinLock(&pAd->GenericLock);
+#endif // RALINK_ATE //
+ // Clear all pending bulk-out request flags.
+ RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
+
+// NdisFreeSpinLock(&pAd->MacTabLock);
+
+// for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
+// {
+// NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
+// }
+
+ DBGPRINT(RT_DEBUG_ERROR, ("<--- ReleaseAdapter\n"));
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Allocate memory for adapter control block.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_FAILURE
+ NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+NDIS_STATUS AdapterBlockAllocateMemory(
+ IN PVOID handle,
+ OUT PVOID *ppAd)
+{
+ PUSB_DEV usb_dev;
+ POS_COOKIE pObj = (POS_COOKIE) handle;
+
+
+ usb_dev = pObj->pUsb_Dev;
+
+ pObj->MLMEThr_pid = NULL;
+ pObj->RTUSBCmdThr_pid = NULL;
+
+ *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
+
+ if (*ppAd)
+ {
+ NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
+ ((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
+ return (NDIS_STATUS_SUCCESS);
+ }
+ else
+ {
+ return (NDIS_STATUS_FAILURE);
+ }
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Create kernel threads & tasklets.
+
+Arguments:
+ *net_dev Pointer to wireless net device interface
+
+Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_FAILURE
+
+Note:
+========================================================================
+*/
+NDIS_STATUS CreateThreads(
+ IN struct net_device *net_dev)
+{
+ PRTMP_ADAPTER pAd = net_dev->ml_priv;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ pid_t pid_number;
+
+ //init_MUTEX(&(pAd->usbdev_semaphore));
+
+ init_MUTEX_LOCKED(&(pAd->mlme_semaphore));
+ init_completion (&pAd->mlmeComplete);
+
+ init_MUTEX_LOCKED(&(pAd->RTUSBCmd_semaphore));
+ init_completion (&pAd->CmdQComplete);
+
+ init_MUTEX_LOCKED(&(pAd->RTUSBTimer_semaphore));
+ init_completion (&pAd->TimerQComplete);
+
+ // Creat MLME Thread
+ pObj->MLMEThr_pid = NULL;
+ pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
+ if (pid_number < 0)
+ {
+ printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
+ return NDIS_STATUS_FAILURE;
+ }
+ pObj->MLMEThr_pid = find_get_pid(pid_number);
+ // Wait for the thread to start
+ wait_for_completion(&(pAd->mlmeComplete));
+
+ // Creat Command Thread
+ pObj->RTUSBCmdThr_pid = NULL;
+ pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
+ if (pid_number < 0)
+ {
+ printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
+ return NDIS_STATUS_FAILURE;
+ }
+ pObj->RTUSBCmdThr_pid = find_get_pid(pid_number);
+ wait_for_completion(&(pAd->CmdQComplete));
+
+ pObj->TimerQThr_pid = NULL;
+ pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
+ if (pid_number < 0)
+ {
+ printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
+ return NDIS_STATUS_FAILURE;
+ }
+ pObj->TimerQThr_pid = find_get_pid(pid_number);
+ // Wait for the thread to start
+ wait_for_completion(&(pAd->TimerQComplete));
+
+ // Create receive tasklet
+ tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd);
+ tasklet_init(&pObj->mgmt_dma_done_task, rt2870_mgmt_dma_done_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->ac0_dma_done_task, rt2870_ac0_dma_done_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->ac1_dma_done_task, rt2870_ac1_dma_done_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->ac2_dma_done_task, rt2870_ac2_dma_done_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->ac3_dma_done_task, rt2870_ac3_dma_done_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->hcca_dma_done_task, rt2870_hcca_dma_done_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->null_frame_complete_task, rt2870_null_frame_complete_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->rts_frame_complete_task, rt2870_rts_frame_complete_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->pspoll_frame_complete_task, rt2870_pspoll_frame_complete_tasklet, (unsigned long)pAd);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+========================================================================
+Routine Description:
+ As STA's BSSID is a WC too, it uses shared key table.
+ This function write correct unicast TX key to ASIC WCID.
+ And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
+ Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
+ Caller guarantee WEP calls this function when set Txkey, default key index=0~3.
+
+Arguments:
+ pAd Pointer to our adapter
+ pKey Pointer to the where the key stored
+
+Return Value:
+ NDIS_SUCCESS Add key successfully
+
+Note:
+========================================================================
+*/
+VOID RTMPAddBSSIDCipher(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Aid,
+ IN PNDIS_802_11_KEY pKey,
+ IN UCHAR CipherAlg)
+{
+ PUCHAR pTxMic, pRxMic;
+ BOOLEAN bKeyRSC, bAuthenticator; // indicate the receive SC set by KeyRSC value
+// UCHAR CipherAlg;
+ UCHAR i;
+ ULONG WCIDAttri;
+ USHORT offset;
+ UCHAR KeyIdx, IVEIV[8];
+ UINT32 Value;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddBSSIDCipher==> Aid = %d\n",Aid));
+
+ // Bit 29 of Add-key KeyRSC
+ bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
+
+ // Bit 28 of Add-key Authenticator
+ bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
+ KeyIdx = (UCHAR)pKey->KeyIndex&0xff;
+
+ if (KeyIdx > 4)
+ return;
+
+
+ if (pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg == CIPHER_TKIP)
+ { if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ // for WPA-None Tx, Rx MIC is the same
+ pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
+ pRxMic = pTxMic;
+ }
+ else if (bAuthenticator == TRUE)
+ {
+ pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
+ pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
+ }
+ else
+ {
+ pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
+ pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
+ }
+
+ offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x10;
+ for (i=0; i<8; )
+ {
+ Value = *(pTxMic+i);
+ Value += (*(pTxMic+i+1)<<8);
+ Value += (*(pTxMic+i+2)<<16);
+ Value += (*(pTxMic+i+3)<<24);
+ RTUSBWriteMACRegister(pAd, offset+i, Value);
+ i+=4;
+ }
+
+ offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x18;
+ for (i=0; i<8; )
+ {
+ Value = *(pRxMic+i);
+ Value += (*(pRxMic+i+1)<<8);
+ Value += (*(pRxMic+i+2)<<16);
+ Value += (*(pRxMic+i+3)<<24);
+ RTUSBWriteMACRegister(pAd, offset+i, Value);
+ i+=4;
+ }
+
+ // Only Key lenth equal to TKIP key have these
+ NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxMic, pRxMic, 8);
+ NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.TxMic, pTxMic, 8);
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ (" TxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
+ pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],
+ pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+ DBGPRINT(RT_DEBUG_TRACE,
+ (" RxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
+ pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],
+ pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+ }
+
+ // 2. Record Security Key.
+ pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen= (UCHAR)pKey->KeyLength;
+ NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
+
+ // 3. Check RxTsc. And used to init to ASIC IV.
+ if (bKeyRSC == TRUE)
+ NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, &pKey->KeyRSC, 6);
+ else
+ NdisZeroMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, 6);
+
+ // 4. Init TxTsc to one based on WiFi WPA specs
+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[0] = 1;
+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[1] = 0;
+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[2] = 0;
+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[3] = 0;
+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[4] = 0;
+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[5] = 0;
+
+ CipherAlg = pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg;
+
+ offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE);
+ RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial,
+ ((pKey->KeyLength == LEN_TKIP_KEY) ? 16 : (USHORT)pKey->KeyLength));
+
+ offset = SHARED_KEY_TABLE_BASE + (KeyIdx * HW_KEY_ENTRY_SIZE);
+ RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial, (USHORT)pKey->KeyLength);
+
+ offset = PAIRWISE_IVEIV_TABLE_BASE + (Aid * HW_IVEIV_ENTRY_SIZE);
+ NdisZeroMemory(IVEIV, 8);
+
+ // IV/EIV
+ if ((CipherAlg == CIPHER_TKIP) ||
+ (CipherAlg == CIPHER_TKIP_NO_MIC) ||
+ (CipherAlg == CIPHER_AES))
+ {
+ IVEIV[3] = 0x20; // Eiv bit on. keyid always 0 for pairwise key
+ }
+ // default key idx needs to set.
+ // in TKIP/AES KeyIdx = 0 , WEP KeyIdx is default tx key.
+ else
+ {
+ IVEIV[3] |= (KeyIdx<< 6);
+ }
+ RTUSBMultiWrite(pAd, (USHORT) offset, IVEIV, 8);
+
+ // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
+ if ((CipherAlg == CIPHER_TKIP) ||
+ (CipherAlg == CIPHER_TKIP_NO_MIC) ||
+ (CipherAlg == CIPHER_AES))
+ {
+ WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
+ }
+ else
+ WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
+
+ offset = MAC_WCID_ATTRIBUTE_BASE + (Aid* HW_WCID_ATTRI_SIZE);
+ RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
+ RTUSBReadMACRegister(pAd, offset, &Value);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BSSID_WCID : offset = %x, WCIDAttri = %lx\n",
+ offset, WCIDAttri));
+
+ // pAddr
+ // Add Bssid mac address at linkup. not here. check!
+ /*offset = MAC_WCID_BASE + (BSSID_WCID * HW_WCID_ENTRY_SIZE);
+ *for (i=0; i<MAC_ADDR_LEN; i++)
+ {
+ RTMP_IO_WRITE8(pAd, offset+i, pKey->BSSID[i]);
+ }
+ */
+
+ DBGPRINT(RT_DEBUG_ERROR, ("AddBSSIDasWCIDEntry: Alg=%s, KeyLength = %d\n",
+ CipherName[CipherAlg], pKey->KeyLength));
+ DBGPRINT(RT_DEBUG_TRACE, ("Key [idx=%x] [KeyLen = %d]\n",
+ pKey->KeyIndex, pKey->KeyLength));
+ for(i=0; i<pKey->KeyLength; i++)
+ DBGPRINT_RAW(RT_DEBUG_TRACE,(" %x:", pKey->KeyMaterial[i]));
+ DBGPRINT(RT_DEBUG_TRACE,(" \n"));
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+========================================================================
+Routine Description:
+ Get a received packet.
+
+Arguments:
+ pAd device control block
+ pSaveRxD receive descriptor information
+ *pbReschedule need reschedule flag
+ *pRxPending pending received packet flag
+
+Return Value:
+ the recieved packet
+
+Note:
+========================================================================
+*/
+#define RT2870_RXDMALEN_FIELD_SIZE 4
+PNDIS_PACKET GetPacketFromRxRing(
+ IN PRTMP_ADAPTER pAd,
+ OUT PRT28XX_RXD_STRUC pSaveRxD,
+ OUT BOOLEAN *pbReschedule,
+ IN OUT UINT32 *pRxPending)
+{
+ PRX_CONTEXT pRxContext;
+ PNDIS_PACKET pSkb;
+ PUCHAR pData;
+ ULONG ThisFrameLen;
+ ULONG RxBufferLength;
+ PRXWI_STRUC pRxWI;
+
+ pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
+ if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
+ return NULL;
+
+ RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
+ if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC)))
+ {
+ goto label_null;
+ }
+
+ pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
+ // The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)
+ ThisFrameLen = *pData + (*(pData+1)<<8);
+ if (ThisFrameLen == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
+ pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
+ goto label_null;
+ }
+ if ((ThisFrameLen&0x3) != 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
+ pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
+ goto label_null;
+ }
+
+ if ((ThisFrameLen + 8)> RxBufferLength) // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
+ pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition));
+
+ // error frame. finish this loop
+ goto label_null;
+ }
+
+ // skip USB frame length field
+ pData += RT2870_RXDMALEN_FIELD_SIZE;
+ pRxWI = (PRXWI_STRUC)pData;
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(pData, TYPE_RXWI);
+#endif // RT_BIG_ENDIAN //
+ if (pRxWI->MPDUtotalByteCount > ThisFrameLen)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
+ __FUNCTION__, pRxWI->MPDUtotalByteCount, ThisFrameLen));
+ goto label_null;
+ }
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(pData, TYPE_RXWI);
+#endif // RT_BIG_ENDIAN //
+
+ // allocate a rx packet
+ pSkb = dev_alloc_skb(ThisFrameLen);
+ if (pSkb == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__));
+ goto label_null;
+ }
+
+ // copy the rx packet
+ memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
+ RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
+ RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
+
+ // copy RxD
+ *pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen);
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pSaveRxD, TYPE_RXINFO);
+#endif // RT_BIG_ENDIAN //
+
+ // update next packet read position.
+ pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
+
+ return pSkb;
+
+label_null:
+
+ return NULL;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Handle received packets.
+
+Arguments:
+ data - URB information pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+static void rx_done_tasklet(unsigned long data)
+{
+ purbb_t pUrb;
+ PRX_CONTEXT pRxContext;
+ PRTMP_ADAPTER pAd;
+ NTSTATUS Status;
+ unsigned int IrqFlags;
+
+ pUrb = (purbb_t)data;
+ pRxContext = (PRX_CONTEXT)pUrb->context;
+ pAd = pRxContext->pAd;
+ Status = pUrb->status;
+
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pRxContext->BulkInOffset += pUrb->actual_length;
+ //NdisInterlockedDecrement(&pAd->PendingRx);
+ pAd->PendingRx--;
+
+ if (Status == USB_ST_NOERROR)
+ {
+ pAd->BulkInComplete++;
+ pAd->NextRxBulkInPosition = 0;
+ if (pRxContext->BulkInOffset) // As jan's comment, it may bulk-in success but size is zero.
+ {
+ pRxContext->Readable = TRUE;
+ INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
+ }
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ }
+ else // STATUS_OTHER
+ {
+ pAd->BulkInCompleteFail++;
+ // Still read this packet although it may comtain wrong bytes.
+ pRxContext->Readable = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+ // Parsing all packets. because after reset, the index will reset to all zero.
+ if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_BULKIN_RESET |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
+ Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
+ }
+ }
+
+ ASSERT((pRxContext->InUse == pRxContext->IRPPending));
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ // If the driver is in ATE mode and Rx frame is set into here.
+ if (pAd->ContinBulkIn == TRUE)
+ {
+ RTUSBBulkReceive(pAd);
+ }
+ }
+ else
+#endif // RALINK_ATE //
+ RTUSBBulkReceive(pAd);
+
+ return;
+
+}
+
+
+static void rt2870_mgmt_dma_done_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pMLMEContext;
+ int index;
+ PNDIS_PACKET pPacket;
+ purbb_t pUrb;
+ NTSTATUS Status;
+ unsigned long IrqFlags;
+
+
+ pUrb = (purbb_t)data;
+ pMLMEContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pMLMEContext->pAd;
+ Status = pUrb->status;
+ index = pMLMEContext->SelfIdx;
+
+ ASSERT((pAd->MgmtRing.TxDmaIdx == index));
+
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+
+ if (Status != USB_ST_NOERROR)
+ {
+ //Bulk-Out fail status handle
+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
+ // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+ }
+ }
+
+ pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+ RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+ // Reset MLME context flags
+ pMLMEContext->IRPPending = FALSE;
+ pMLMEContext->InUse = FALSE;
+ pMLMEContext->bWaitingBulkOut = FALSE;
+ pMLMEContext->BulkOutSize = 0;
+
+ pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
+ pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
+
+ // Increase MgmtRing Index
+ INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
+ pAd->MgmtRing.TxSwFreeIdx++;
+ RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+ // No-matter success or fail, we free the mgmt packet.
+ if (pPacket)
+ RTMPFreeNdisPacket(pAd, pPacket);
+
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ // do nothing and return directly.
+ }
+ else
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) &&
+ ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG))
+ { // For Mgmt Bulk-Out failed, ignore it now.
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ {
+
+ // Always call Bulk routine, even reset bulk.
+ // The protectioon of rest bulk should be in BulkOut routine
+ if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
+ {
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+ }
+ RTUSBKickBulkOut(pAd);
+ }
+ }
+
+}
+
+
+static void rt2870_hcca_dma_done_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PHT_TX_CONTEXT pHTTXContext;
+ UCHAR BulkOutPipeId = 4;
+ purbb_t pUrb;
+
+
+ pUrb = (purbb_t)data;
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+
+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ // do nothing and return directly.
+ }
+ else
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+ {
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+ /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+ (pHTTXContext->bCurWriting == FALSE))
+ {
+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+ }
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<4);
+ RTUSBKickBulkOut(pAd);
+ }
+ }
+
+
+ return;
+}
+
+
+static void rt2870_ac3_dma_done_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PHT_TX_CONTEXT pHTTXContext;
+ UCHAR BulkOutPipeId = 3;
+ purbb_t pUrb;
+
+
+ pUrb = (purbb_t)data;
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+
+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ // do nothing and return directly.
+ }
+ else
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+ {
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+ /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+ (pHTTXContext->bCurWriting == FALSE))
+ {
+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+ }
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3);
+ RTUSBKickBulkOut(pAd);
+ }
+ }
+
+
+ return;
+}
+
+
+static void rt2870_ac2_dma_done_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PHT_TX_CONTEXT pHTTXContext;
+ UCHAR BulkOutPipeId = 2;
+ purbb_t pUrb;
+
+
+ pUrb = (purbb_t)data;
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+
+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ // do nothing and return directly.
+ }
+ else
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+ {
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+ /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+ (pHTTXContext->bCurWriting == FALSE))
+ {
+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+ }
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2);
+ RTUSBKickBulkOut(pAd);
+ }
+ }
+
+ return;
+}
+
+
+static void rt2870_ac1_dma_done_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PHT_TX_CONTEXT pHTTXContext;
+ UCHAR BulkOutPipeId = 1;
+ purbb_t pUrb;
+
+
+ pUrb = (purbb_t)data;
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+
+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ // do nothing and return directly.
+ }
+ else
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+ {
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+ /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+ (pHTTXContext->bCurWriting == FALSE))
+ {
+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+ }
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1);
+ RTUSBKickBulkOut(pAd);
+ }
+ }
+
+
+ return;
+}
+
+
+static void rt2870_ac0_dma_done_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PHT_TX_CONTEXT pHTTXContext;
+ UCHAR BulkOutPipeId = 0;
+ purbb_t pUrb;
+
+
+ pUrb = (purbb_t)data;
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+
+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ // do nothing and return directly.
+ }
+ else
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+ {
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+ /* ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+ (pHTTXContext->bCurWriting == FALSE))
+ {
+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+ }
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
+ RTUSBKickBulkOut(pAd);
+ }
+ }
+
+
+ return;
+
+}
+
+
+static void rt2870_null_frame_complete_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pNullContext;
+ purbb_t pUrb;
+ NTSTATUS Status;
+ unsigned long irqFlag;
+
+
+ pUrb = (purbb_t)data;
+ pNullContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pNullContext->pAd;
+ Status = pUrb->status;
+
+ // Reset Null frame context flags
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
+ pNullContext->IRPPending = FALSE;
+ pNullContext->InUse = FALSE;
+ pAd->BulkOutPending[0] = FALSE;
+ pAd->watchDogTxPendingCnt[0] = 0;
+
+ if (Status == USB_ST_NOERROR)
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ }
+ else // STATUS_OTHER
+ {
+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status));
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+ }
+ }
+
+ // Always call Bulk routine, even reset bulk.
+ // The protectioon of rest bulk should be in BulkOut routine
+ RTUSBKickBulkOut(pAd);
+
+}
+
+
+static void rt2870_rts_frame_complete_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pRTSContext;
+ purbb_t pUrb;
+ NTSTATUS Status;
+ unsigned long irqFlag;
+
+
+ pUrb = (purbb_t)data;
+ pRTSContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pRTSContext->pAd;
+ Status = pUrb->status;
+
+ // Reset RTS frame context flags
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
+ pRTSContext->IRPPending = FALSE;
+ pRTSContext->InUse = FALSE;
+
+ if (Status == USB_ST_NOERROR)
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ }
+ else // STATUS_OTHER
+ {
+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+ }
+ }
+
+ RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
+ pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
+ RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
+
+ // Always call Bulk routine, even reset bulk.
+ // The protectioon of rest bulk should be in BulkOut routine
+ RTUSBKickBulkOut(pAd);
+
+}
+
+
+static void rt2870_pspoll_frame_complete_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pPsPollContext;
+ purbb_t pUrb;
+ NTSTATUS Status;
+
+
+ pUrb = (purbb_t)data;
+ pPsPollContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pPsPollContext->pAd;
+ Status = pUrb->status;
+
+ // Reset PsPoll context flags
+ pPsPollContext->IRPPending = FALSE;
+ pPsPollContext->InUse = FALSE;
+ pAd->watchDogTxPendingCnt[0] = 0;
+
+ if (Status == USB_ST_NOERROR)
+ {
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ }
+ else // STATUS_OTHER
+ {
+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ }
+
+ RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
+ pAd->BulkOutPending[0] = FALSE;
+ RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
+
+ // Always call Bulk routine, even reset bulk.
+ // The protectioon of rest bulk should be in BulkOut routine
+ RTUSBKickBulkOut(pAd);
+
+}
+
+
+static void rt2870_dataout_complete_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ purbb_t pUrb;
+ POS_COOKIE pObj;
+ PHT_TX_CONTEXT pHTTXContext;
+ UCHAR BulkOutPipeId;
+ NTSTATUS Status;
+ unsigned long IrqFlags;
+
+
+ pUrb = (purbb_t)data;
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ Status = pUrb->status;
+
+ // Store BulkOut PipeId
+ BulkOutPipeId = pHTTXContext->BulkOutPipeId;
+ pAd->BulkOutDataOneSecCount++;
+
+ //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
+ // pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
+
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+ pHTTXContext->IRPPending = FALSE;
+ pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
+
+ if (Status == USB_ST_NOERROR)
+ {
+ pAd->BulkOutComplete++;
+
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+ pAd->Counters8023.GoodTransmits++;
+ //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+ FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
+ //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+
+ }
+ else // STATUS_OTHER
+ {
+ PUCHAR pBuf;
+
+ pAd->BulkOutCompleteOther++;
+
+ pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition];
+
+ if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST |
+ fRTMP_ADAPTER_BULKOUT_RESET)))
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ pAd->bulkResetPipeid = BulkOutPipeId;
+ pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
+ //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
+
+ }
+
+ //
+ // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
+ // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
+ //
+ //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+ if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
+ (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
+ !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
+ {
+ // Indicate There is data avaliable
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+ }
+ //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+ // Always call Bulk routine, even reset bulk.
+ // The protection of rest bulk should be in BulkOut routine
+ RTUSBKickBulkOut(pAd);
+}
+
+/* End of 2870_rtmp_init.c */
diff --git a/drivers/staging/rt3070/common/action.c b/drivers/staging/rt3070/common/action.c
new file mode 100644
index 00000000000..b8ae5363366
--- /dev/null
+++ b/drivers/staging/rt3070/common/action.c
@@ -0,0 +1,1038 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ action.c
+
+ Abstract:
+ Handle association related requests either from WSTA or from local MLME
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan Lee 2006 created for rt2860
+ */
+
+#include "../rt_config.h"
+#include "../action.h"
+
+
+static VOID ReservedAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+/*
+ ==========================================================================
+ Description:
+ association state machine init, including state transition and timer init
+ Parameters:
+ S - pointer to the association state machine
+ Note:
+ The state machine looks like the following
+
+ ASSOC_IDLE
+ MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action
+ MT2_PEER_DISASSOC_REQ peer_disassoc_action
+ MT2_PEER_ASSOC_REQ drop
+ MT2_PEER_REASSOC_REQ drop
+ MT2_CLS3ERR cls3err_action
+ ==========================================================================
+ */
+VOID ActionStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_ACT_STATE, MAX_ACT_MSG, (STATE_MACHINE_FUNC)Drop, ACT_IDLE, ACT_MACHINE_BASE);
+
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, (STATE_MACHINE_FUNC)PeerSpectrumAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, (STATE_MACHINE_FUNC)PeerQOSAction);
+
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)ReservedAction);
+#ifdef QOS_DLS_SUPPORT
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)PeerDLSAction);
+#endif // QOS_DLS_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, (STATE_MACHINE_FUNC)PeerBAAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, (STATE_MACHINE_FUNC)PeerHTAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, (STATE_MACHINE_FUNC)MlmeADDBAAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
+#endif // DOT11_N_SUPPORT //
+
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, (STATE_MACHINE_FUNC)PeerPublicAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, (STATE_MACHINE_FUNC)PeerRMAction);
+
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, (STATE_MACHINE_FUNC)MlmeQOSAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, (STATE_MACHINE_FUNC)MlmeDLSAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, (STATE_MACHINE_FUNC)MlmeInvalidAction);
+}
+
+#ifdef DOT11_N_SUPPORT
+VOID MlmeADDBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ MLME_ADDBA_REQ_STRUCT *pInfo;
+ UCHAR Addr[6];
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG Idx;
+ FRAME_ADDBA_REQ Frame;
+ ULONG FrameLen;
+ BA_ORI_ENTRY *pBAEntry = NULL;
+
+ pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg;
+ NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ));
+
+ if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr))
+ {
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n"));
+ return;
+ }
+ // 1. find entry
+ Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
+ if (Idx == 0)
+ {
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
+ return;
+ }
+ else
+ {
+ pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (ADHOC_ON(pAd))
+ ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+ else
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr);
+
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ Frame.Category = CATEGORY_BA;
+ Frame.Action = ADDBA_REQ;
+ Frame.BaParm.AMSDUSupported = 0;
+ Frame.BaParm.BAPolicy = IMMED_BA;
+ Frame.BaParm.TID = pInfo->TID;
+ Frame.BaParm.BufSize = pInfo->BaBufSize;
+ Frame.Token = pInfo->Token;
+ Frame.TimeOutValue = pInfo->TimeOutValue;
+ Frame.BaStartSeq.field.FragNum = 0;
+ Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
+
+ *(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm));
+ Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
+ Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_ADDBA_REQ), &Frame,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ //MiniportDataMMRequest(pAd, MapUserPriorityToAccessCategory[pInfo->TID], pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ send DELBA and delete BaEntry if any
+ Parametrs:
+ Elem - MLME message MLME_DELBA_REQ_STRUCT
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeDELBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_DELBA_REQ_STRUCT *pInfo;
+ PUCHAR pOutBuffer = NULL;
+ PUCHAR pOutBuffer2 = NULL;
+ NDIS_STATUS NStatus;
+ ULONG Idx;
+ FRAME_DELBA_REQ Frame;
+ ULONG FrameLen;
+ FRAME_BAR FrameBar;
+
+ pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg;
+ // must send back DELBA
+ NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ));
+ DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator));
+
+ if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen))
+ {
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
+ return;
+ }
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
+ return;
+ }
+
+ // SEND BAR (Send BAR to refresh peer reordering buffer.)
+ Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress);
+#endif // CONFIG_STA_SUPPORT //
+
+ FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL funciton.
+ FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; // make sure sequence not clear in DEL funciton.
+ FrameBar.BarControl.TID = pInfo->TID; // make sure sequence not clear in DEL funciton.
+ FrameBar.BarControl.ACKPolicy = IMMED_BA; // make sure sequence not clear in DEL funciton.
+ FrameBar.BarControl.Compressed = 1; // make sure sequence not clear in DEL funciton.
+ FrameBar.BarControl.MTID = 0; // make sure sequence not clear in DEL funciton.
+
+ MakeOutgoingFrame(pOutBuffer2, &FrameLen,
+ sizeof(FRAME_BAR), &FrameBar,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer2);
+ DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
+
+ // SEND DELBA FRAME
+ FrameLen = 0;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (ADHOC_ON(pAd))
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+ else
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ Frame.Category = CATEGORY_BA;
+ Frame.Action = DELBA;
+ Frame.DelbaParm.Initiator = pInfo->Initiator;
+ Frame.DelbaParm.TID = pInfo->TID;
+ Frame.ReasonCode = 39; // Time Out
+ *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm));
+ Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_DELBA_REQ), &Frame,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator));
+ }
+}
+#endif // DOT11_N_SUPPORT //
+
+VOID MlmeQOSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+VOID MlmeDLSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+VOID MlmeInvalidAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ //PUCHAR pOutBuffer = NULL;
+ //Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11
+}
+
+VOID PeerQOSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+#ifdef QOS_DLS_SUPPORT
+VOID PeerDLSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
+
+ switch(Action)
+ {
+ case ACTION_DLS_REQUEST:
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ PeerDlsReqAction(pAd, Elem);
+#endif // CONFIG_STA_SUPPORT //
+ break;
+
+ case ACTION_DLS_RESPONSE:
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ PeerDlsRspAction(pAd, Elem);
+#endif // CONFIG_STA_SUPPORT //
+ break;
+
+ case ACTION_DLS_TEARDOWN:
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ PeerDlsTearDownAction(pAd, Elem);
+#endif // CONFIG_STA_SUPPORT //
+ break;
+ }
+}
+#endif // QOS_DLS_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+VOID PeerBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
+
+ switch(Action)
+ {
+ case ADDBA_REQ:
+ PeerAddBAReqAction(pAd,Elem);
+ break;
+ case ADDBA_RESP:
+ PeerAddBARspAction(pAd,Elem);
+ break;
+ case DELBA:
+ PeerDelBAAction(pAd,Elem);
+ break;
+ }
+}
+
+
+#ifdef DOT11N_DRAFT3
+
+#ifdef CONFIG_STA_SUPPORT
+VOID StaPublicAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Bss2040Coexist)
+{
+ BSS_2040_COEXIST_IE BssCoexist;
+ MLME_SCAN_REQ_STRUCT ScanReq;
+
+ BssCoexist.word = Bss2040Coexist;
+ // AP asks Station to return a 20/40 BSS Coexistence mgmt frame. So we first starts a scan, then send back 20/40 BSS Coexistence mgmt frame
+ if ((BssCoexist.field.InfoReq == 1) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040)))
+ {
+ // Clear record first. After scan , will update those bit and send back to transmiter.
+ pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1;
+ pAd->CommonCfg.BSSCoexist2040.field.Intolerant40 = 0;
+ pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 0;
+ // Fill out stuff for scan request
+ ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+ }
+}
+
+
+/*
+Description : Build Intolerant Channel Rerpot from Trigger event table.
+return : how many bytes copied.
+*/
+ULONG BuildIntolerantChannelRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDest)
+{
+ ULONG FrameLen = 0;
+ ULONG ReadOffset = 0;
+ UCHAR i;
+ UCHAR LastRegClass = 0xff;
+ PUCHAR pLen;
+
+ for ( i = 0;i < MAX_TRIGGER_EVENT;i++)
+ {
+ if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid == TRUE)
+ {
+ if (pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass == LastRegClass)
+ {
+ *(pDest + ReadOffset) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
+ *pLen++;
+ ReadOffset++;
+ FrameLen++;
+ }
+ else
+ {
+ *(pDest + ReadOffset) = IE_2040_BSS_INTOLERANT_REPORT; // IE
+ *(pDest + ReadOffset + 1) = 2; // Len = RegClass byte + channel byte.
+ pLen = pDest + ReadOffset + 1;
+ LastRegClass = pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass;
+ *(pDest + ReadOffset + 2) = LastRegClass; // Len = RegClass byte + channel byte.
+ *(pDest + ReadOffset + 3) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
+ FrameLen += 4;
+ ReadOffset += 4;
+ }
+
+ }
+ }
+ return FrameLen;
+}
+
+
+/*
+Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered.
+*/
+VOID Send2040CoexistAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN BOOLEAN bAddIntolerantCha)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ FRAME_ACTION_HDR Frame;
+ ULONG FrameLen;
+ ULONG IntolerantChaRepLen;
+
+ IntolerantChaRepLen = 0;
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n"));
+ return;
+ }
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->CommonCfg.Bssid);
+ Frame.Category = CATEGORY_PUBLIC;
+ Frame.Action = ACTION_BSS_2040_COEXIST;
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_ACTION_HDR), &Frame,
+ END_OF_ARGS);
+
+ *(pOutBuffer + FrameLen) = pAd->CommonCfg.BSSCoexist2040.word;
+ FrameLen++;
+
+ if (bAddIntolerantCha == TRUE)
+ IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen);
+ DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x ) \n", pAd->CommonCfg.BSSCoexist2040.word));
+
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ After scan, Update 20/40 BSS Coexistence IE and send out.
+ According to 802.11n D3.03 11.14.10
+
+ Parameters:
+ ==========================================================================
+ */
+VOID Update2040CoexistFrameAndNotify(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN BOOLEAN bAddIntolerantCha)
+{
+ BSS_2040_COEXIST_IE OldValue;
+
+ OldValue.word = pAd->CommonCfg.BSSCoexist2040.word;
+ if ((pAd->CommonCfg.TriggerEventTab.EventANo > 0) || (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0))
+ pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 1;
+
+ // Need to check !!!!
+ // How STA will set Intolerant40 if implementation dependent. Now we don't set this bit first.!!!!!
+ // So Only check BSS20WidthReq change.
+ if (OldValue.field.BSS20WidthReq != pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq)
+ {
+ Send2040CoexistAction(pAd, Wcid, bAddIntolerantCha);
+ }
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+BOOLEAN ChannelSwitchSanityCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR NewChannel,
+ IN UCHAR Secondary)
+{
+ UCHAR i;
+
+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return FALSE;
+
+ if ((NewChannel > 7) && (Secondary == 1))
+ return FALSE;
+
+ if ((NewChannel < 5) && (Secondary == 3))
+ return FALSE;
+
+ // 0. Check if new channel is in the channellist.
+ for (i = 0;i < pAd->ChannelListNum;i++)
+ {
+ if (pAd->ChannelList[i].Channel == NewChannel)
+ {
+ break;
+ }
+ }
+
+ if (i == pAd->ChannelListNum)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+VOID ChannelSwitchAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR NewChannel,
+ IN UCHAR Secondary)
+{
+ UCHAR BBPValue = 0;
+ ULONG MACValue;
+
+ DBGPRINT(RT_DEBUG_TRACE,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d) \n", NewChannel, Secondary));
+
+ if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE)
+ return;
+
+ // 1. Switches to BW = 20.
+ if (Secondary == 0)
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue&= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+ pAd->CommonCfg.BBPCurrentBW = BW_20;
+ pAd->CommonCfg.Channel = NewChannel;
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel,FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz !!! \n" ));
+ }
+ // 1. Switches to BW = 40 And Station supports BW = 40.
+ else if (((Secondary == 1) || (Secondary == 3)) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
+ {
+ pAd->CommonCfg.Channel = NewChannel;
+
+ if (Secondary == 1)
+ {
+ // Secondary above.
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
+ MACValue &= 0xfe;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue&= (~0x18);
+ BBPValue|= (0x10);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
+ BBPValue&= (~0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
+ }
+ else
+ {
+ // Secondary below.
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
+ MACValue &= 0xfe;
+ MACValue |= 0x1;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue&= (~0x18);
+ BBPValue|= (0x10);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
+ BBPValue&= (~0x20);
+ BBPValue|= (0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
+ }
+ pAd->CommonCfg.BBPCurrentBW = BW_40;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+ pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 1;
+ }
+}
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+VOID PeerPublicAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+#ifdef DOT11N_DRAFT3
+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
+#endif // DOT11N_DRAFT3 //
+
+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return;
+
+#ifdef DOT11N_DRAFT3
+ switch(Action)
+ {
+ case ACTION_BSS_2040_COEXIST: // Format defined in IEEE 7.4.7a.1 in 11n Draf3.03
+ {
+ //UCHAR BssCoexist;
+ BSS_2040_COEXIST_ELEMENT *pCoexistInfo;
+ BSS_2040_COEXIST_IE *pBssCoexistIe;
+ BSS_2040_INTOLERANT_CH_REPORT *pIntolerantReport = NULL;
+
+ if (Elem->MsgLen <= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT)) )
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem->MsgLen));
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("ACTION - 20/40 BSS Coexistence Management action----> \n"));
+ hex_dump("CoexistenceMgmtFrame", Elem->Msg, Elem->MsgLen);
+
+
+ pCoexistInfo = (BSS_2040_COEXIST_ELEMENT *) &Elem->Msg[LENGTH_802_11+2];
+ //hex_dump("CoexistInfo", (PUCHAR)pCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT));
+ if (Elem->MsgLen >= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT) + sizeof(BSS_2040_INTOLERANT_CH_REPORT)))
+ {
+ pIntolerantReport = (BSS_2040_INTOLERANT_CH_REPORT *)((PUCHAR)pCoexistInfo + sizeof(BSS_2040_COEXIST_ELEMENT));
+ }
+ //hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
+
+ pBssCoexistIe = (BSS_2040_COEXIST_IE *)(&pCoexistInfo->BssCoexistIe);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (INFRA_ON(pAd))
+ {
+ StaPublicAction(pAd, pCoexistInfo);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ }
+ break;
+ }
+
+#endif // DOT11N_DRAFT3 //
+
+}
+
+
+static VOID ReservedAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Category;
+
+ if (Elem->MsgLen <= LENGTH_802_11)
+ {
+ return;
+ }
+
+ Category = Elem->Msg[LENGTH_802_11];
+ DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category));
+ hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
+}
+
+VOID PeerRMAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ return;
+}
+
+#ifdef DOT11_N_SUPPORT
+static VOID respond_ht_information_exchange_action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+ FRAME_HT_INFO HTINFOframe, *pFrame;
+ UCHAR *pAddr;
+
+
+ // 2. Always send back ADDBA Response
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
+ return;
+ }
+
+ // get RA
+ pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
+ pAddr = pFrame->Hdr.Addr2;
+
+ NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO));
+ // 2-1. Prepare ADDBA Response frame.
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (ADHOC_ON(pAd))
+ ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+ else
+ ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ HTINFOframe.Category = CATEGORY_HT;
+ HTINFOframe.Action = HT_INFO_EXCHANGE;
+ HTINFOframe.HT_Info.Request = 0;
+ HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
+ HTINFOframe.HT_Info.STA_Channel_Width = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_HT_INFO), &HTINFOframe,
+ END_OF_ARGS);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+
+#ifdef DOT11N_DRAFT3
+VOID SendNotifyBWActionFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR apidx)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ FRAME_ACTION_HDR Frame;
+ ULONG FrameLen;
+ PUCHAR pAddr1;
+
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n"));
+ return;
+ }
+
+ if (Wcid == MCAST_WCID)
+ pAddr1 = &BROADCAST_ADDR[0];
+ else
+ pAddr1 = pAd->MacTab.Content[Wcid].Addr;
+ ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
+
+ Frame.Category = CATEGORY_HT;
+ Frame.Action = NOTIFY_BW_ACTION;
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_ACTION_HDR), &Frame,
+ END_OF_ARGS);
+
+ *(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
+ FrameLen++;
+
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth));
+
+}
+#endif // DOT11N_DRAFT3 //
+
+
+VOID PeerHTAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
+
+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return;
+
+ switch(Action)
+ {
+ case NOTIFY_BW_ACTION:
+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n"));
+#ifdef CONFIG_STA_SUPPORT
+ if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
+ {
+ // Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
+ // sending BW_Notify Action frame, and cause us to linkup and linkdown.
+ // In legacy mode, don't need to parse HT action frame.
+ DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
+ Elem->Msg[LENGTH_802_11+2] ));
+ break;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ if (Elem->Msg[LENGTH_802_11+2] == 0) // 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
+ pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
+
+ break;
+
+ case SMPS_ACTION:
+ // 7.3.1.25
+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
+ if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
+ {
+ pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
+ }
+ else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
+ {
+ pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
+ }
+ else
+ {
+ pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode));
+ // rt2860c : add something for smps change.
+ break;
+
+ case SETPCO_ACTION:
+ break;
+
+ case MIMO_CHA_MEASURE_ACTION:
+ break;
+
+ case HT_INFO_EXCHANGE:
+ {
+ HT_INFORMATION_OCTET *pHT_info;
+
+ pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
+ // 7.4.8.10
+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
+ if (pHT_info->Request)
+ {
+ respond_ht_information_exchange_action(pAd, Elem);
+ }
+ }
+ break;
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Retry sending ADDBA Reqest.
+
+ IRQL = DISPATCH_LEVEL
+
+ Parametrs:
+ p8023Header: if this is already 802.3 format, p8023Header is NULL
+
+ Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
+ FALSE , then continue indicaterx at this moment.
+ ==========================================================================
+ */
+VOID ORIBATimerTimeout(
+ IN PRTMP_ADAPTER pAd)
+{
+ MAC_TABLE_ENTRY *pEntry;
+ INT i, total;
+// FRAME_BAR FrameBar;
+// ULONG FrameLen;
+// NDIS_STATUS NStatus;
+// PUCHAR pOutBuffer = NULL;
+// USHORT Sequence;
+ UCHAR TID;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ total = pAd->MacTab.Size * NUM_OF_TID;
+
+ for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
+ {
+ if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
+ {
+ pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
+ TID = pAd->BATable.BAOriEntry[i].TID;
+
+ ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
+ }
+ total --;
+ }
+}
+
+
+VOID SendRefreshBAR(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ FRAME_BAR FrameBar;
+ ULONG FrameLen;
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ USHORT Sequence;
+ UCHAR i, TID;
+ USHORT idx;
+ BA_ORI_ENTRY *pBAEntry;
+
+ for (i = 0; i <NUM_OF_TID; i++)
+ {
+ idx = pEntry->BAOriWcidArray[i];
+ if (idx == 0)
+ {
+ continue;
+ }
+ pBAEntry = &pAd->BATable.BAOriEntry[idx];
+
+ if (pBAEntry->ORI_BA_Status == Originator_Done)
+ {
+ TID = pBAEntry->TID;
+
+ ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
+ return;
+ }
+
+ Sequence = pEntry->TxSeq[TID];
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress);
+#endif // CONFIG_STA_SUPPORT //
+
+ FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
+ FrameBar.StartingSeq.field.StartSeq = Sequence; // make sure sequence not clear in DEL funciton.
+ FrameBar.BarControl.TID = TID; // make sure sequence not clear in DEL funciton.
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_BAR), &FrameBar,
+ END_OF_ARGS);
+ //if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))
+ if (1) // Now we always send BAR.
+ {
+ //MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ //MiniportDataMMRequest(pAd, MapUserPriorityToAccessCategory[TID], pOutBuffer, FrameLen);
+ }
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+ }
+}
+#endif // DOT11_N_SUPPORT //
+
+VOID ActHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN PUCHAR Addr1,
+ IN PUCHAR Addr2,
+ IN PUCHAR Addr3)
+{
+ NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+ pHdr80211->FC.Type = BTYPE_MGMT;
+ pHdr80211->FC.SubType = SUBTYPE_ACTION;
+
+ COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
+ COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
+ COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
+}
+
+VOID BarHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PFRAME_BAR pCntlBar,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA)
+{
+// USHORT Duration;
+
+ NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR));
+ pCntlBar->FC.Type = BTYPE_CNTL;
+ pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
+ pCntlBar->BarControl.MTID = 0;
+ pCntlBar->BarControl.Compressed = 1;
+ pCntlBar->BarControl.ACKPolicy = 0;
+
+
+ pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
+
+ COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
+ COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Insert Category and action code into the action frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. category code of the frame.
+ 4. action code of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID InsertActField(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 Category,
+ IN UINT8 ActCode)
+{
+ ULONG TempLen;
+
+ MakeOutgoingFrame( pFrameBuf, &TempLen,
+ 1, &Category,
+ 1, &ActCode,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ return;
+}
diff --git a/drivers/staging/rt3070/common/ba_action.c b/drivers/staging/rt3070/common/ba_action.c
new file mode 100644
index 00000000000..17e1f87d98d
--- /dev/null
+++ b/drivers/staging/rt3070/common/ba_action.c
@@ -0,0 +1,1810 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+
+#ifdef DOT11_N_SUPPORT
+
+#include "../rt_config.h"
+
+
+
+#define BA_ORI_INIT_SEQ (pEntry->TxSeq[TID]) //1 // inital sequence number of BA session
+
+#define ORI_SESSION_MAX_RETRY 8
+#define ORI_BA_SESSION_TIMEOUT (2000) // ms
+#define REC_BA_SESSION_IDLE_TIMEOUT (1000) // ms
+
+#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
+#define MAX_REORDERING_PACKET_TIMEOUT ((3000 * HZ)/1000) // system ticks -- 100 ms
+
+#define RESET_RCV_SEQ (0xFFFF)
+
+static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk);
+
+
+BA_ORI_ENTRY *BATableAllocOriEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT USHORT *Idx);
+
+BA_REC_ENTRY *BATableAllocRecEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT USHORT *Idx);
+
+VOID BAOriSessionSetupTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID BARecSessionIdleTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+
+BUILD_TIMER_FUNCTION(BAOriSessionSetupTimeout);
+BUILD_TIMER_FUNCTION(BARecSessionIdleTimeout);
+
+#define ANNOUNCE_REORDERING_PACKET(_pAd, _mpdu_blk) \
+ Announce_Reordering_Packet(_pAd, _mpdu_blk);
+
+VOID BA_MaxWinSizeReasign(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntryPeer,
+ OUT UCHAR *pWinSize)
+{
+ UCHAR MaxSize;
+
+
+ if (pAd->MACVersion >= RALINK_2883_VERSION) // 3*3
+ {
+ if (pAd->MACVersion >= RALINK_3070_VERSION)
+ {
+ if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
+ MaxSize = 7; // for non-open mode
+ else
+ MaxSize = 13;
+ }
+ else
+ MaxSize = 31;
+ }
+ else if (pAd->MACVersion >= RALINK_2880E_VERSION) // 2880 e
+ {
+ if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
+ MaxSize = 7; // for non-open mode
+ else
+ MaxSize = 13;
+ }
+ else
+ MaxSize = 7;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ba> Win Size = %d, Max Size = %d\n",
+ *pWinSize, MaxSize));
+
+ if ((*pWinSize) > MaxSize)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ba> reassign max win size from %d to %d\n",
+ *pWinSize, MaxSize));
+
+ *pWinSize = MaxSize;
+ }
+}
+
+void Announce_Reordering_Packet(IN PRTMP_ADAPTER pAd,
+ IN struct reordering_mpdu *mpdu)
+{
+ PNDIS_PACKET pPacket;
+
+ pPacket = mpdu->pPacket;
+
+ if (mpdu->bAMSDU)
+ {
+ ASSERT(0);
+ BA_Reorder_AMSDU_Annnounce(pAd, pPacket);
+ }
+ else
+ {
+ //
+ // pass this 802.3 packet to upper layer or forward this packet to WM directly
+ //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket, RTMP_GET_PACKET_IF(pPacket));
+#endif // CONFIG_STA_SUPPORT //
+ }
+}
+
+/*
+ * Insert a reordering mpdu into sorted linked list by sequence no.
+ */
+BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list, struct reordering_mpdu *mpdu)
+{
+
+ struct reordering_mpdu **ppScan = &list->next;
+
+ while (*ppScan != NULL)
+ {
+ if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ))
+ {
+ ppScan = &(*ppScan)->next;
+ }
+ else if ((*ppScan)->Sequence == mpdu->Sequence)
+ {
+ /* give up this duplicated frame */
+ return(FALSE);
+ }
+ else
+ {
+ /* find position */
+ break;
+ }
+ }
+
+ mpdu->next = *ppScan;
+ *ppScan = mpdu;
+ list->qlen++;
+ return TRUE;
+}
+
+
+/*
+ * caller lock critical section if necessary
+ */
+static inline void ba_enqueue(struct reordering_list *list, struct reordering_mpdu *mpdu_blk)
+{
+ list->qlen++;
+ mpdu_blk->next = list->next;
+ list->next = mpdu_blk;
+}
+
+/*
+ * caller lock critical section if necessary
+ */
+static inline struct reordering_mpdu * ba_dequeue(struct reordering_list *list)
+{
+ struct reordering_mpdu *mpdu_blk = NULL;
+
+ ASSERT(list);
+
+ if (list->qlen)
+ {
+ list->qlen--;
+ mpdu_blk = list->next;
+ if (mpdu_blk)
+ {
+ list->next = mpdu_blk->next;
+ mpdu_blk->next = NULL;
+ }
+ }
+ return mpdu_blk;
+}
+
+
+static inline struct reordering_mpdu *ba_reordering_mpdu_dequeue(struct reordering_list *list)
+{
+ return(ba_dequeue(list));
+}
+
+
+static inline struct reordering_mpdu *ba_reordering_mpdu_probe(struct reordering_list *list)
+ {
+ ASSERT(list);
+
+ return(list->next);
+ }
+
+
+/*
+ * free all resource for reordering mechanism
+ */
+void ba_reordering_resource_release(PRTMP_ADAPTER pAd)
+{
+ BA_TABLE *Tab;
+ PBA_REC_ENTRY pBAEntry;
+ struct reordering_mpdu *mpdu_blk;
+ int i;
+
+ Tab = &pAd->BATable;
+
+ /* I. release all pending reordering packet */
+ NdisAcquireSpinLock(&pAd->BATabLock);
+ for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
+ {
+ pBAEntry = &Tab->BARecEntry[i];
+ if (pBAEntry->REC_BA_Status != Recipient_NONE)
+ {
+ while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
+ {
+ ASSERT(mpdu_blk->pPacket);
+ RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket, NDIS_STATUS_FAILURE);
+ ba_mpdu_blk_free(pAd, mpdu_blk);
+ }
+ }
+ }
+ NdisReleaseSpinLock(&pAd->BATabLock);
+
+ ASSERT(pBAEntry->list.qlen == 0);
+ /* II. free memory of reordering mpdu table */
+ NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
+ os_free_mem(pAd, pAd->mpdu_blk_pool.mem);
+ NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
+}
+
+
+
+/*
+ * Allocate all resource for reordering mechanism
+ */
+BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num)
+{
+ int i;
+ PUCHAR mem;
+ struct reordering_mpdu *mpdu_blk;
+ struct reordering_list *freelist;
+
+ /* allocate spinlock */
+ NdisAllocateSpinLock(&pAd->mpdu_blk_pool.lock);
+
+ /* initialize freelist */
+ freelist = &pAd->mpdu_blk_pool.freelist;
+ freelist->next = NULL;
+ freelist->qlen = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Allocate %d memory for BA reordering\n", (UINT32)(num*sizeof(struct reordering_mpdu))));
+
+ /* allocate number of mpdu_blk memory */
+ os_alloc_mem(pAd, (PUCHAR *)&mem, (num*sizeof(struct reordering_mpdu)));
+
+ pAd->mpdu_blk_pool.mem = mem;
+
+ if (mem == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Can't Allocate Memory for BA Reordering\n"));
+ return(FALSE);
+ }
+
+ /* build mpdu_blk free list */
+ for (i=0; i<num; i++)
+ {
+ /* get mpdu_blk */
+ mpdu_blk = (struct reordering_mpdu *) mem;
+ /* initial mpdu_blk */
+ NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
+ /* next mpdu_blk */
+ mem += sizeof(struct reordering_mpdu);
+ /* insert mpdu_blk into freelist */
+ ba_enqueue(freelist, mpdu_blk);
+ }
+
+ return(TRUE);
+}
+
+//static int blk_count=0; // sample take off, no use
+
+static struct reordering_mpdu *ba_mpdu_blk_alloc(PRTMP_ADAPTER pAd)
+{
+ struct reordering_mpdu *mpdu_blk;
+
+ NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
+ mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist);
+ if (mpdu_blk)
+ {
+// blk_count++;
+ /* reset mpdu_blk */
+ NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
+ }
+ NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
+ return mpdu_blk;
+}
+
+static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk)
+{
+ ASSERT(mpdu_blk);
+
+ NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
+// blk_count--;
+ ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk);
+ NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
+}
+
+
+static USHORT ba_indicate_reordering_mpdus_in_order(
+ IN PRTMP_ADAPTER pAd,
+ IN PBA_REC_ENTRY pBAEntry,
+ IN USHORT StartSeq)
+{
+ struct reordering_mpdu *mpdu_blk;
+ USHORT LastIndSeq = RESET_RCV_SEQ;
+
+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+
+ while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
+ {
+ /* find in-order frame */
+ if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ))
+ {
+ break;
+ }
+ /* dequeue in-order frame from reodering list */
+ mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
+ /* pass this frame up */
+ ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
+ /* move to next sequence */
+ StartSeq = mpdu_blk->Sequence;
+ LastIndSeq = StartSeq;
+ /* free mpdu_blk */
+ ba_mpdu_blk_free(pAd, mpdu_blk);
+ }
+
+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+
+ /* update last indicated sequence */
+ return LastIndSeq;
+}
+
+static void ba_indicate_reordering_mpdus_le_seq(
+ IN PRTMP_ADAPTER pAd,
+ IN PBA_REC_ENTRY pBAEntry,
+ IN USHORT Sequence)
+{
+ struct reordering_mpdu *mpdu_blk;
+
+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+ while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
+ {
+ /* find in-order frame */
+ if ((mpdu_blk->Sequence == Sequence) || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ))
+ {
+ /* dequeue in-order frame from reodering list */
+ mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
+ /* pass this frame up */
+ ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
+ /* free mpdu_blk */
+ ba_mpdu_blk_free(pAd, mpdu_blk);
+ }
+ else
+ {
+ break;
+ }
+ }
+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+}
+
+
+static void ba_refresh_reordering_mpdus(
+ IN PRTMP_ADAPTER pAd,
+ PBA_REC_ENTRY pBAEntry)
+{
+ struct reordering_mpdu *mpdu_blk;
+
+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+
+ /* dequeue in-order frame from reodering list */
+ while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
+ {
+ /* pass this frame up */
+ ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
+
+ pBAEntry->LastIndSeq = mpdu_blk->Sequence;
+ ba_mpdu_blk_free(pAd, mpdu_blk);
+
+ /* update last indicated sequence */
+ }
+ ASSERT(pBAEntry->list.qlen == 0);
+ pBAEntry->LastIndSeq = RESET_RCV_SEQ;
+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+}
+
+
+//static
+void ba_flush_reordering_timeout_mpdus(
+ IN PRTMP_ADAPTER pAd,
+ IN PBA_REC_ENTRY pBAEntry,
+ IN ULONG Now32)
+
+{
+ USHORT Sequence;
+
+// if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) &&
+// (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //||
+// (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) &&
+// (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8)))
+ if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT/6)))
+ &&(pBAEntry->list.qlen > 1)
+ )
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
+ (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
+ pBAEntry->LastIndSeq));
+ ba_refresh_reordering_mpdus(pAd, pBAEntry);
+ pBAEntry->LastIndSeqAtTimer = Now32;
+ }
+ else
+ if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
+ && (pBAEntry->list.qlen > 0)
+ )
+ {
+// printk("timeout[%d] (%lx-%lx = %d > %d): %x, ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
+// (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), REORDERING_PACKET_TIMEOUT,
+// pBAEntry->LastIndSeq);
+ //
+ // force LastIndSeq to shift to LastIndSeq+1
+ //
+ Sequence = (pBAEntry->LastIndSeq+1) & MAXSEQ;
+ ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
+ pBAEntry->LastIndSeqAtTimer = Now32;
+ pBAEntry->LastIndSeq = Sequence;
+ //
+ // indicate in-order mpdus
+ //
+ Sequence = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, Sequence);
+ if (Sequence != RESET_RCV_SEQ)
+ {
+ pBAEntry->LastIndSeq = Sequence;
+ }
+
+ //printk("%x, flush one!\n", pBAEntry->LastIndSeq);
+
+ }
+}
+
+
+/*
+ * generate ADDBA request to
+ * set up BA agreement
+ */
+VOID BAOriSessionSetUp(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR TID,
+ IN USHORT TimeOut,
+ IN ULONG DelayTime,
+ IN BOOLEAN isForced)
+
+{
+ //MLME_ADDBA_REQ_STRUCT AddbaReq;
+ BA_ORI_ENTRY *pBAEntry = NULL;
+ USHORT Idx;
+ BOOLEAN Cancelled;
+
+ if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE) && (isForced == FALSE))
+ return;
+
+ // if this entry is limited to use legacy tx mode, it doesn't generate BA.
+ if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT)
+ return;
+
+ if ((pEntry->BADeclineBitmap & (1<<TID)) && (isForced == FALSE))
+ {
+ // try again after 3 secs
+ DelayTime = 3000;
+// printk("DeCline BA from Peer\n");
+// return;
+ }
+
+
+ Idx = pEntry->BAOriWcidArray[TID];
+ if (Idx == 0)
+ {
+ // allocate a BA session
+ pBAEntry = BATableAllocOriEntry(pAd, &Idx);
+ if (pBAEntry == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ADDBA - MlmeADDBAAction() allocate BA session failed \n"));
+ return;
+ }
+ }
+ else
+ {
+ pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+ }
+
+ if (pBAEntry->ORI_BA_Status >= Originator_WaitRes)
+ {
+ return;
+ }
+
+ pEntry->BAOriWcidArray[TID] = Idx;
+
+ // Initialize BA session
+ pBAEntry->ORI_BA_Status = Originator_WaitRes;
+ pBAEntry->Wcid = pEntry->Aid;
+ pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
+ pBAEntry->Sequence = BA_ORI_INIT_SEQ;
+ pBAEntry->Token = 1; // (2008-01-21) Jan Lee recommends it - this token can't be 0
+ pBAEntry->TID = TID;
+ pBAEntry->TimeOutValue = TimeOut;
+ pBAEntry->pAdapter = pAd;
+
+ DBGPRINT(RT_DEBUG_TRACE,("Send AddBA to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d isForced:%d Wcid:%d\n"
+ ,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
+ ,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
+ ,TID,isForced,pEntry->Aid));
+
+ if (!(pEntry->TXBAbitmap & (1<<TID)))
+ {
+ RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE);
+ }
+ else
+ RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
+
+ // set timer to send ADDBA request
+ RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime);
+}
+
+VOID BAOriSessionAdd(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PFRAME_ADDBA_RSP pFrame)
+{
+ BA_ORI_ENTRY *pBAEntry = NULL;
+ BOOLEAN Cancelled;
+ UCHAR TID;
+ USHORT Idx;
+ PUCHAR pOutBuffer2 = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+ FRAME_BAR FrameBar;
+
+ TID = pFrame->BaParm.TID;
+ Idx = pEntry->BAOriWcidArray[TID];
+ pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+
+ // Start fill in parameters.
+ if ((Idx !=0) && (pBAEntry->TID == TID) && (pBAEntry->ORI_BA_Status == Originator_WaitRes))
+ {
+ pBAEntry->BAWinSize = min(pBAEntry->BAWinSize, ((UCHAR)pFrame->BaParm.BufSize));
+ BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize);
+
+ pBAEntry->TimeOutValue = pFrame->TimeOutValue;
+ pBAEntry->ORI_BA_Status = Originator_Done;
+ // reset sequence number
+ pBAEntry->Sequence = BA_ORI_INIT_SEQ;
+ // Set Bitmap flag.
+ pEntry->TXBAbitmap |= (1<<TID);
+ RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
+
+ pBAEntry->ORIBATimer.TimerValue = 0; //pFrame->TimeOutValue;
+
+ DBGPRINT(RT_DEBUG_TRACE,("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n", __FUNCTION__, pEntry->TXBAbitmap,
+ pBAEntry->BAWinSize, pBAEntry->ORIBATimer.TimerValue));
+
+ // SEND BAR ;
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("BA - BAOriSessionAdd() allocate memory failed \n"));
+ return;
+ }
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->CurrentAddress);
+#endif // CONFIG_STA_SUPPORT //
+
+ FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
+ FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence; // make sure sequence not clear in DEL funciton.
+ FrameBar.BarControl.TID = pBAEntry->TID; // make sure sequence not clear in DEL funciton.
+ MakeOutgoingFrame(pOutBuffer2, &FrameLen,
+ sizeof(FRAME_BAR), &FrameBar,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer2);
+
+
+ if (pBAEntry->ORIBATimer.TimerValue)
+ RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue); // in mSec
+ }
+}
+
+BOOLEAN BARecSessionAdd(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PFRAME_ADDBA_REQ pFrame)
+{
+ BA_REC_ENTRY *pBAEntry = NULL;
+ BOOLEAN Status = TRUE;
+ BOOLEAN Cancelled;
+ USHORT Idx;
+ UCHAR TID;
+ UCHAR BAWinSize;
+ //UINT32 Value;
+ //UINT offset;
+
+
+ ASSERT(pEntry);
+
+ // find TID
+ TID = pFrame->BaParm.TID;
+
+ BAWinSize = min(((UCHAR)pFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
+
+ // Intel patch
+ if (BAWinSize == 0)
+ {
+ BAWinSize = 64;
+ }
+
+ Idx = pEntry->BARecWcidArray[TID];
+
+
+ if (Idx == 0)
+ {
+ pBAEntry = BATableAllocRecEntry(pAd, &Idx);
+ }
+ else
+ {
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ // flush all pending reordering mpdus
+ ba_refresh_reordering_mpdus(pAd, pBAEntry);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __FUNCTION__, pAd->BATable.numAsRecipient, Idx,
+ pFrame->BaParm.BufSize, BAWinSize));
+
+ // Start fill in parameters.
+ if (pBAEntry != NULL)
+ {
+ ASSERT(pBAEntry->list.qlen == 0);
+
+ pBAEntry->REC_BA_Status = Recipient_HandleRes;
+ pBAEntry->BAWinSize = BAWinSize;
+ pBAEntry->Wcid = pEntry->Aid;
+ pBAEntry->TID = TID;
+ pBAEntry->TimeOutValue = pFrame->TimeOutValue;
+ pBAEntry->REC_BA_Status = Recipient_Accept;
+ // initial sequence number
+ pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq;
+
+ printk("Start Seq = %08x\n", pFrame->BaStartSeq.field.StartSeq);
+
+ if (pEntry->RXBAbitmap & (1<<TID))
+ {
+ RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
+ }
+ else
+ {
+ RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE);
+ }
+
+ // Set Bitmap flag.
+ pEntry->RXBAbitmap |= (1<<TID);
+ pEntry->BARecWcidArray[TID] = Idx;
+
+ pEntry->BADeclineBitmap &= ~(1<<TID);
+
+ // Set BA session mask in WCID table.
+ RT28XX_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
+
+ DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
+ pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID]));
+ }
+ else
+ {
+ Status = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE,("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n",
+ PRINT_MAC(pEntry->Addr), TID));
+ }
+ return(Status);
+}
+
+
+BA_REC_ENTRY *BATableAllocRecEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT USHORT *Idx)
+{
+ int i;
+ BA_REC_ENTRY *pBAEntry = NULL;
+
+
+ NdisAcquireSpinLock(&pAd->BATabLock);
+
+ if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION)
+ {
+ printk("BA Recipeint Session (%ld) > %d\n", pAd->BATable.numAsRecipient,
+ MAX_BARECI_SESSION);
+ goto done;
+ }
+
+ // reserve idx 0 to identify BAWcidArray[TID] as empty
+ for (i=1; i < MAX_LEN_OF_BA_REC_TABLE; i++)
+ {
+ pBAEntry =&pAd->BATable.BARecEntry[i];
+ if ((pBAEntry->REC_BA_Status == Recipient_NONE))
+ {
+ // get one
+ pAd->BATable.numAsRecipient++;
+ pBAEntry->REC_BA_Status = Recipient_USED;
+ *Idx = i;
+ break;
+ }
+ }
+
+done:
+ NdisReleaseSpinLock(&pAd->BATabLock);
+ return pBAEntry;
+}
+
+BA_ORI_ENTRY *BATableAllocOriEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT USHORT *Idx)
+{
+ int i;
+ BA_ORI_ENTRY *pBAEntry = NULL;
+
+ NdisAcquireSpinLock(&pAd->BATabLock);
+
+ if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE))
+ {
+ goto done;
+ }
+
+ // reserve idx 0 to identify BAWcidArray[TID] as empty
+ for (i=1; i<MAX_LEN_OF_BA_ORI_TABLE; i++)
+ {
+ pBAEntry =&pAd->BATable.BAOriEntry[i];
+ if ((pBAEntry->ORI_BA_Status == Originator_NONE))
+ {
+ // get one
+ pAd->BATable.numAsOriginator++;
+ pBAEntry->ORI_BA_Status = Originator_USED;
+ pBAEntry->pAdapter = pAd;
+ *Idx = i;
+ break;
+ }
+ }
+
+done:
+ NdisReleaseSpinLock(&pAd->BATabLock);
+ return pBAEntry;
+}
+
+
+VOID BATableFreeOriEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Idx)
+{
+ BA_ORI_ENTRY *pBAEntry = NULL;
+ MAC_TABLE_ENTRY *pEntry;
+
+
+ if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
+ return;
+
+ pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+
+ if (pBAEntry->ORI_BA_Status != Originator_NONE)
+ {
+ pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
+ pEntry->BAOriWcidArray[pBAEntry->TID] = 0;
+
+
+ NdisAcquireSpinLock(&pAd->BATabLock);
+ if (pBAEntry->ORI_BA_Status == Originator_Done)
+ {
+ pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) ));
+ DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
+ // Erase Bitmap flag.
+ }
+
+ ASSERT(pAd->BATable.numAsOriginator != 0);
+
+ pAd->BATable.numAsOriginator -= 1;
+
+ pBAEntry->ORI_BA_Status = Originator_NONE;
+ pBAEntry->Token = 0;
+ NdisReleaseSpinLock(&pAd->BATabLock);
+ }
+}
+
+
+VOID BATableFreeRecEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Idx)
+{
+ BA_REC_ENTRY *pBAEntry = NULL;
+ MAC_TABLE_ENTRY *pEntry;
+
+
+ if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE))
+ return;
+
+ pBAEntry =&pAd->BATable.BARecEntry[Idx];
+
+ if (pBAEntry->REC_BA_Status != Recipient_NONE)
+ {
+ pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
+ pEntry->BARecWcidArray[pBAEntry->TID] = 0;
+
+ NdisAcquireSpinLock(&pAd->BATabLock);
+
+ ASSERT(pAd->BATable.numAsRecipient != 0);
+
+ pAd->BATable.numAsRecipient -= 1;
+
+ pBAEntry->REC_BA_Status = Recipient_NONE;
+ NdisReleaseSpinLock(&pAd->BATabLock);
+ }
+}
+
+
+VOID BAOriSessionTearDown(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR TID,
+ IN BOOLEAN bPassive,
+ IN BOOLEAN bForceSend)
+{
+ ULONG Idx = 0;
+ BA_ORI_ENTRY *pBAEntry;
+ BOOLEAN Cancelled;
+
+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+ {
+ return;
+ }
+
+ //
+ // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
+ //
+ Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID];
+ if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
+ {
+ if (bForceSend == TRUE)
+ {
+ // force send specified TID DelBA
+ MLME_DELBA_REQ_STRUCT DelbaReq;
+ MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+ NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
+ NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
+
+ COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
+ DelbaReq.Wcid = Wcid;
+ DelbaReq.TID = TID;
+ DelbaReq.Initiator = ORIGINATOR;
+#if 1
+ Elem->MsgLen = sizeof(DelbaReq);
+ NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
+ MlmeDELBAAction(pAd, Elem);
+ kfree(Elem);
+#else
+ MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
+ RT28XX_MLME_HANDLER(pAd);
+#endif
+ }
+
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
+
+ pBAEntry = &pAd->BATable.BAOriEntry[Idx];
+ DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status));
+ //
+ // Prepare DelBA action frame and send to the peer.
+ //
+ if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done))
+ {
+ MLME_DELBA_REQ_STRUCT DelbaReq;
+ MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+ NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
+ NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
+
+ COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
+ DelbaReq.Wcid = Wcid;
+ DelbaReq.TID = pBAEntry->TID;
+ DelbaReq.Initiator = ORIGINATOR;
+#if 1
+ Elem->MsgLen = sizeof(DelbaReq);
+ NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
+ MlmeDELBAAction(pAd, Elem);
+ kfree(Elem);
+#else
+ MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
+ RT28XX_MLME_HANDLER(pAd);
+#endif
+ }
+ RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
+ BATableFreeOriEntry(pAd, Idx);
+
+ if (bPassive)
+ {
+ //BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE);
+ }
+}
+
+VOID BARecSessionTearDown(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR TID,
+ IN BOOLEAN bPassive)
+{
+ ULONG Idx = 0;
+ BA_REC_ENTRY *pBAEntry;
+
+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+ {
+ return;
+ }
+
+ //
+ // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
+ //
+ Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
+ if (Idx == 0)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
+
+
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status));
+ //
+ // Prepare DelBA action frame and send to the peer.
+ //
+ if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept))
+ {
+ MLME_DELBA_REQ_STRUCT DelbaReq;
+ BOOLEAN Cancelled;
+ MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+ //ULONG offset;
+ //UINT32 VALUE;
+
+ RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
+
+ //
+ // 1. Send DELBA Action Frame
+ //
+ if (bPassive == FALSE)
+ {
+ NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
+ NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
+
+ COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
+ DelbaReq.Wcid = Wcid;
+ DelbaReq.TID = TID;
+ DelbaReq.Initiator = RECIPIENT;
+#if 1
+ Elem->MsgLen = sizeof(DelbaReq);
+ NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
+ MlmeDELBAAction(pAd, Elem);
+ kfree(Elem);
+#else
+ MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
+ RT28XX_MLME_HANDLER(pAd);
+#endif
+ }
+
+
+ //
+ // 2. Free resource of BA session
+ //
+ // flush all pending reordering mpdus
+ ba_refresh_reordering_mpdus(pAd, pBAEntry);
+
+ NdisAcquireSpinLock(&pAd->BATabLock);
+
+ // Erase Bitmap flag.
+ pBAEntry->LastIndSeq = RESET_RCV_SEQ;
+ pBAEntry->BAWinSize = 0;
+ // Erase Bitmap flag at software mactable
+ pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID)));
+ pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;
+
+ RT28XX_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
+
+ NdisReleaseSpinLock(&pAd->BATabLock);
+
+ }
+
+ BATableFreeRecEntry(pAd, Idx);
+}
+
+VOID BASessionTearDownALL(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid)
+{
+ int i;
+
+ for (i=0; i<NUM_OF_TID; i++)
+ {
+ BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE);
+ BARecSessionTearDown(pAd, Wcid, i, FALSE);
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Retry sending ADDBA Reqest.
+
+ IRQL = DISPATCH_LEVEL
+
+ Parametrs:
+ p8023Header: if this is already 802.3 format, p8023Header is NULL
+
+ Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
+ FALSE , then continue indicaterx at this moment.
+ ==========================================================================
+ */
+VOID BAOriSessionSetupTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ BA_ORI_ENTRY *pBAEntry = (BA_ORI_ENTRY *)FunctionContext;
+ MAC_TABLE_ENTRY *pEntry;
+ PRTMP_ADAPTER pAd;
+
+ if (pBAEntry == NULL)
+ return;
+
+ pAd = pBAEntry->pAdapter;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Do nothing if monitor mode is on
+ if (MONITOR_ON(pAd))
+ return;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RALINK_ATE
+ // Nothing to do in ATE mode.
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
+
+ if ((pBAEntry->ORI_BA_Status == Originator_WaitRes) && (pBAEntry->Token < ORI_SESSION_MAX_RETRY))
+ {
+ MLME_ADDBA_REQ_STRUCT AddbaReq;
+
+ NdisZeroMemory(&AddbaReq, sizeof(AddbaReq));
+ COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr);
+ AddbaReq.Wcid = (UCHAR)(pEntry->Aid);
+ AddbaReq.TID = pBAEntry->TID;
+ AddbaReq.BaBufSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
+ AddbaReq.TimeOutValue = 0;
+ AddbaReq.Token = pBAEntry->Token;
+ MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq);
+ RT28XX_MLME_HANDLER(pAd);
+ //DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token));
+
+ DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d Wcid:%d\n"
+ ,pBAEntry->Token
+ ,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
+ ,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
+ ,pBAEntry->TID,pEntry->Aid));
+
+ pBAEntry->Token++;
+ RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
+ }
+ else
+ {
+ BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ Retry sending ADDBA Reqest.
+
+ IRQL = DISPATCH_LEVEL
+
+ Parametrs:
+ p8023Header: if this is already 802.3 format, p8023Header is NULL
+
+ Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
+ FALSE , then continue indicaterx at this moment.
+ ==========================================================================
+ */
+VOID BARecSessionIdleTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+
+ BA_REC_ENTRY *pBAEntry = (BA_REC_ENTRY *)FunctionContext;
+ PRTMP_ADAPTER pAd;
+ ULONG Now32;
+
+ if (pBAEntry == NULL)
+ return;
+
+ if ((pBAEntry->REC_BA_Status == Recipient_Accept))
+ {
+ NdisGetSystemUpTime(&Now32);
+
+ if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer + REC_BA_SESSION_IDLE_TIMEOUT)))
+ {
+ pAd = pBAEntry->pAdapter;
+ // flush all pending reordering mpdus
+ ba_refresh_reordering_mpdus(pAd, pBAEntry);
+ printk("%ld: REC BA session Timeout\n", Now32);
+ }
+ }
+}
+
+
+VOID PeerAddBAReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ // 7.4.4.1
+ //ULONG Idx;
+ UCHAR Status = 1;
+ UCHAR pAddr[6];
+ FRAME_ADDBA_RSP ADDframe;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ PFRAME_ADDBA_REQ pAddreqFrame = NULL;
+ //UCHAR BufSize;
+ ULONG FrameLen;
+ PULONG ptemp;
+ PMAC_TABLE_ENTRY pMacEntry;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __FUNCTION__, Elem->Wcid));
+
+ //hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen);
+
+ //ADDBA Request from unknown peer, ignore this.
+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return;
+
+ pMacEntry = &pAd->MacTab.Content[Elem->Wcid];
+ DBGPRINT(RT_DEBUG_TRACE,("BA - PeerAddBAReqAction----> \n"));
+ ptemp = (PULONG)Elem->Msg;
+ //DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8)));
+
+ if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr))
+ {
+
+ if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry))
+ {
+ pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
+ printk("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid);
+ if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame))
+ Status = 0;
+ else
+ Status = 38; // more parameters have invalid values
+ }
+ else
+ {
+ Status = 37; // the request has been declined.
+ }
+ }
+
+ if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI)
+ ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC);
+
+ pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
+ // 2. Always send back ADDBA Response
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n"));
+ return;
+ }
+
+ NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP));
+ // 2-1. Prepare ADDBA Response frame.
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (ADHOC_ON(pAd))
+ ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+ else
+ ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ ADDframe.Category = CATEGORY_BA;
+ ADDframe.Action = ADDBA_RESP;
+ ADDframe.Token = pAddreqFrame->Token;
+ // What is the Status code?? need to check.
+ ADDframe.StatusCode = Status;
+ ADDframe.BaParm.BAPolicy = IMMED_BA;
+ ADDframe.BaParm.AMSDUSupported = 0;
+ ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID;
+ ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
+ if (ADDframe.BaParm.BufSize == 0)
+ {
+ ADDframe.BaParm.BufSize = 64;
+ }
+ ADDframe.TimeOutValue = 0; //pAddreqFrame->TimeOutValue;
+
+ *(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm));
+ ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode);
+ ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_ADDBA_RSP), &ADDframe,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __FUNCTION__, Elem->Wcid, ADDframe.BaParm.TID,
+ ADDframe.BaParm.BufSize));
+}
+
+
+VOID PeerAddBARspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ //UCHAR Idx, i;
+ //PUCHAR pOutBuffer = NULL;
+ PFRAME_ADDBA_RSP pFrame = NULL;
+ //PBA_ORI_ENTRY pBAEntry;
+
+ //ADDBA Response from unknown peer, ignore this.
+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __FUNCTION__, Elem->Wcid));
+
+ //hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen);
+
+ if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen))
+ {
+ pFrame = (PFRAME_ADDBA_RSP)(&Elem->Msg[0]);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\t StatusCode = %d\n", pFrame->StatusCode));
+ switch (pFrame->StatusCode)
+ {
+ case 0:
+ // I want a BAsession with this peer as an originator.
+ BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pFrame);
+ break;
+ default:
+ // check status == USED ???
+ BAOriSessionTearDown(pAd, Elem->Wcid, pFrame->BaParm.TID, TRUE, FALSE);
+ break;
+ }
+ // Rcv Decline StatusCode
+ if ((pFrame->StatusCode == 37)
+#ifdef CONFIG_STA_SUPPORT
+ || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd) && (pFrame->StatusCode != 0))
+#endif // CONFIG_STA_SUPPORT //
+ )
+ {
+ pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<<pFrame->BaParm.TID;
+ }
+ }
+}
+
+VOID PeerDelBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ //UCHAR Idx;
+ //PUCHAR pOutBuffer = NULL;
+ PFRAME_DELBA_REQ pDelFrame = NULL;
+
+ DBGPRINT(RT_DEBUG_TRACE,("%s ==>\n", __FUNCTION__));
+ //DELBA Request from unknown peer, ignore this.
+ if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen))
+ {
+ pDelFrame = (PFRAME_DELBA_REQ)(&Elem->Msg[0]);
+ if (pDelFrame->DelbaParm.Initiator == ORIGINATOR)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> ORIGINATOR\n"));
+ BARecSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n", pDelFrame->ReasonCode));
+ //hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen);
+ BAOriSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE, FALSE);
+ }
+ }
+}
+
+
+BOOLEAN CntlEnqueueForRecv(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN ULONG MsgLen,
+ IN PFRAME_BA_REQ pMsg)
+{
+ PFRAME_BA_REQ pFrame = pMsg;
+ //PRTMP_REORDERBUF pBuffer;
+ //PRTMP_REORDERBUF pDmaBuf;
+ PBA_REC_ENTRY pBAEntry;
+ //BOOLEAN Result;
+ ULONG Idx;
+ //UCHAR NumRxPkt;
+ UCHAR TID;//, i;
+
+ TID = (UCHAR)pFrame->BARControl.TID;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __FUNCTION__, Wcid, TID));
+ //hex_dump("BAR", (PCHAR) pFrame, MsgLen);
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return FALSE;
+
+ // First check the size, it MUST not exceed the mlme queue size
+ if (MsgLen > MGMT_DMA_BUFFER_SIZE)
+ {
+ DBGPRINT_ERR(("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
+ return FALSE;
+ }
+ else if (MsgLen != sizeof(FRAME_BA_REQ))
+ {
+ DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
+ return FALSE;
+ }
+ else if (MsgLen != sizeof(FRAME_BA_REQ))
+ {
+ DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
+ return FALSE;
+ }
+
+ if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8))
+ {
+ // if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search.
+ Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID, pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq ));
+
+ if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ))
+ {
+ //printk("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq);
+ ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq);
+ pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1);
+ }
+ //ba_refresh_reordering_mpdus(pAd, pBAEntry);
+ return TRUE;
+}
+
+/*
+Description : Send PSMP Action frame If PSMP mode switches.
+*/
+VOID SendPSMPAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR Psmp)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ //ULONG Idx;
+ FRAME_PSMP_ACTION Frame;
+ ULONG FrameLen;
+#ifdef RT30xx
+ UCHAR bbpdata=0;
+ UINT32 macdata;
+#endif // RT30xx //
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
+ return;
+ }
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
+#endif // CONFIG_STA_SUPPORT //
+
+ Frame.Category = CATEGORY_HT;
+ Frame.Action = SMPS_ACTION;
+ switch (Psmp)
+ {
+ case MMPS_ENABLE:
+#ifdef RT30xx
+ if (IS_RT3090(pAd))
+ {
+ // disable MMPS BBP control register
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
+ bbpdata &= ~(0x04); //bit 2
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
+
+ // disable MMPS MAC control register
+ RTMP_IO_READ32(pAd, 0x1210, &macdata);
+ macdata &= ~(0x09); //bit 0, 3
+ RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+ }
+#endif // RT30xx //
+ Frame.Psmp = 0;
+ break;
+ case MMPS_DYNAMIC:
+#ifdef RT30xx
+ if (IS_RT3090(pAd))
+ {
+ // enable MMPS BBP control register
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
+ bbpdata |= 0x04; //bit 2
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
+
+ // enable MMPS MAC control register
+ RTMP_IO_READ32(pAd, 0x1210, &macdata);
+ macdata |= 0x09; //bit 0, 3
+ RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+ }
+#endif // RT30xx //
+ Frame.Psmp = 3;
+ break;
+ case MMPS_STATIC:
+#ifdef RT30xx
+ if (IS_RT3090(pAd))
+ {
+ // enable MMPS BBP control register
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
+ bbpdata |= 0x04; //bit 2
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
+
+ // enable MMPS MAC control register
+ RTMP_IO_READ32(pAd, 0x1210, &macdata);
+ macdata |= 0x09; //bit 0, 3
+ RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+ }
+#endif // RT30xx //
+ Frame.Psmp = 1;
+ break;
+ }
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_PSMP_ACTION), &Frame,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d ) \n", Frame.Psmp));
+}
+
+
+#define RADIO_MEASUREMENT_REQUEST_ACTION 0
+
+typedef struct PACKED
+{
+ UCHAR RegulatoryClass;
+ UCHAR ChannelNumber;
+ USHORT RandomInterval;
+ USHORT MeasurementDuration;
+ UCHAR MeasurementMode;
+ UCHAR BSSID[MAC_ADDR_LEN];
+ UCHAR ReportingCondition;
+ UCHAR Threshold;
+ UCHAR SSIDIE[2]; // 2 byte
+} BEACON_REQUEST;
+
+typedef struct PACKED
+{
+ UCHAR ID;
+ UCHAR Length;
+ UCHAR Token;
+ UCHAR RequestMode;
+ UCHAR Type;
+} MEASUREMENT_REQ;
+
+
+
+
+void convert_reordering_packet_to_preAMSDU_or_802_3_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ PNDIS_PACKET pRxPkt;
+ UCHAR Header802_3[LENGTH_802_3];
+
+ // 1. get 802.3 Header
+ // 2. remove LLC
+ // a. pointer pRxBlk->pData to payload
+ // b. modify pRxBlk->DataSize
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
+#endif // CONFIG_STA_SUPPORT //
+
+ ASSERT(pRxBlk->pRxPacket);
+ pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
+
+ RTPKT_TO_OSPKT(pRxPkt)->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+ RTPKT_TO_OSPKT(pRxPkt)->data = pRxBlk->pData;
+ RTPKT_TO_OSPKT(pRxPkt)->len = pRxBlk->DataSize;
+ RTPKT_TO_OSPKT(pRxPkt)->tail = RTPKT_TO_OSPKT(pRxPkt)->data + RTPKT_TO_OSPKT(pRxPkt)->len;
+
+ //
+ // copy 802.3 header, if necessary
+ //
+ if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+#ifdef LINUX
+ NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
+#endif
+#ifdef UCOS
+ NdisMoveMemory(net_pkt_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
+#endif
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+}
+
+
+#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID) \
+ do \
+ { \
+ if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU)) \
+ { \
+ Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
+ } \
+ else if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_EAP)) \
+ { \
+ Indicate_EAPOL_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
+ } \
+ else \
+ { \
+ Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
+ } \
+ } while (0);
+
+
+
+static VOID ba_enqueue_reordering_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PBA_REC_ENTRY pBAEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ struct reordering_mpdu *mpdu_blk;
+ UINT16 Sequence = (UINT16) pRxBlk->pHeader->Sequence;
+
+ mpdu_blk = ba_mpdu_blk_alloc(pAd);
+ if (mpdu_blk != NULL)
+ {
+ // Write RxD buffer address & allocated buffer length
+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+
+ mpdu_blk->Sequence = Sequence;
+
+ mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU);
+
+ convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd, pRxBlk, FromWhichBSSID);
+
+ STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
+
+ //
+ // it is necessary for reordering packet to record
+ // which BSS it come from
+ //
+ RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
+
+ mpdu_blk->pPacket = pRxBlk->pRxPacket;
+
+ if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk) == FALSE)
+ {
+ // had been already within reordering list
+ // don't indicate
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_SUCCESS);
+ ba_mpdu_blk_free(pAd, mpdu_blk);
+ }
+
+ ASSERT((0<= pBAEntry->list.qlen) && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));
+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("!!! (%d) Can't allocate reordering mpdu blk\n",
+ pBAEntry->list.qlen));
+ /*
+ * flush all pending reordering mpdus
+ * and receving mpdu to upper layer
+ * make tcp/ip to take care reordering mechanism
+ */
+ //ba_refresh_reordering_mpdus(pAd, pBAEntry);
+ ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
+
+ pBAEntry->LastIndSeq = Sequence;
+ INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Indicate this packet to upper layer or put it into reordering buffer
+
+ Parametrs:
+ pRxBlk : carry necessary packet info 802.11 format
+ FromWhichBSSID : the packet received from which BSS
+
+ Return :
+ none
+
+ Note :
+ the packet queued into reordering buffer need to cover to 802.3 format
+ or pre_AMSDU format
+ ==========================================================================
+ */
+
+VOID Indicate_AMPDU_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ USHORT Idx;
+ PBA_REC_ENTRY pBAEntry = NULL;
+ UINT16 Sequence = pRxBlk->pHeader->Sequence;
+ ULONG Now32;
+ UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
+ UCHAR TID = pRxBlk->pRxWI->TID;
+
+
+ if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) && (pRxBlk->DataSize > MAX_RX_PKT_LEN))
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ if (Wcid < MAX_LEN_OF_MAC_TABLE)
+ {
+ Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
+ if (Idx == 0)
+ {
+ /* Rec BA Session had been torn down */
+ INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
+ return;
+ }
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ }
+ else
+ {
+ // impossible !!!
+ ASSERT(0);
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ ASSERT(pBAEntry);
+
+ // update last rx time
+ NdisGetSystemUpTime(&Now32);
+
+ pBAEntry->rcvSeq = Sequence;
+
+
+ ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
+ pBAEntry->LastIndSeqAtTimer = Now32;
+
+ //
+ // Reset Last Indicate Sequence
+ //
+ if (pBAEntry->LastIndSeq == RESET_RCV_SEQ)
+ {
+ ASSERT((pBAEntry->list.qlen == 0) && (pBAEntry->list.next == NULL));
+
+ // reset rcv sequence of BA session
+ pBAEntry->LastIndSeq = Sequence;
+ pBAEntry->LastIndSeqAtTimer = Now32;
+ INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
+ return;
+ }
+
+
+ //
+ // I. Check if in order.
+ //
+ if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
+ {
+ USHORT LastIndSeq;
+
+ pBAEntry->LastIndSeq = Sequence;
+ INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
+ LastIndSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
+ if (LastIndSeq != RESET_RCV_SEQ)
+ {
+ pBAEntry->LastIndSeq = LastIndSeq;
+ }
+ pBAEntry->LastIndSeqAtTimer = Now32;
+ }
+ //
+ // II. Drop Duplicated Packet
+ //
+ else if (Sequence == pBAEntry->LastIndSeq)
+ {
+
+ // drop and release packet
+ pBAEntry->nDropPacket++;
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ }
+ //
+ // III. Drop Old Received Packet
+ //
+ else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
+ {
+
+ // drop and release packet
+ pBAEntry->nDropPacket++;
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ }
+ //
+ // IV. Receive Sequence within Window Size
+ //
+ else if (SEQ_SMALLER(Sequence, (((pBAEntry->LastIndSeq+pBAEntry->BAWinSize+1)) & MAXSEQ), MAXSEQ))
+ {
+ ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
+ }
+ //
+ // V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer
+ //
+ else
+ {
+ LONG WinStartSeq, TmpSeq;
+
+
+ TmpSeq = Sequence - (pBAEntry->BAWinSize) -1;
+ if (TmpSeq < 0)
+ {
+ TmpSeq = (MAXSEQ+1) + TmpSeq;
+ }
+ WinStartSeq = (TmpSeq+1) & MAXSEQ;
+ ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq);
+ pBAEntry->LastIndSeq = WinStartSeq; //TmpSeq;
+
+ pBAEntry->LastIndSeqAtTimer = Now32;
+
+ ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
+
+ TmpSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
+ if (TmpSeq != RESET_RCV_SEQ)
+ {
+ pBAEntry->LastIndSeq = TmpSeq;
+ }
+ }
+}
+
+#endif // DOT11_N_SUPPORT //
+
diff --git a/drivers/staging/rt3070/common/cmm_data.c b/drivers/staging/rt3070/common/cmm_data.c
new file mode 100644
index 00000000000..85f92b9f83d
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_data.c
@@ -0,0 +1,2827 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+*/
+
+#include "../rt_config.h"
+
+#define MAX_TX_IN_TBTT (16)
+
+
+UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+UCHAR SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
+// Add Cisco Aironet SNAP heade for CCX2 support
+UCHAR SNAP_AIRONET[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00};
+UCHAR CKIP_LLC_SNAP[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
+UCHAR EAPOL_LLC_SNAP[]= {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e};
+UCHAR EAPOL[] = {0x88, 0x8e};
+UCHAR TPID[] = {0x81, 0x00}; /* VLAN related */
+
+UCHAR IPX[] = {0x81, 0x37};
+UCHAR APPLE_TALK[] = {0x80, 0xf3};
+UCHAR RateIdToPlcpSignal[12] = {
+ 0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3, /* RATE_11 */ // see BBP spec
+ 11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14, /* RATE_18 */ // see IEEE802.11a-1999 p.14
+ 9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */ }; // see IEEE802.11a-1999 p.14
+
+UCHAR OfdmSignalToRateId[16] = {
+ RATE_54, RATE_54, RATE_54, RATE_54, // OFDM PLCP Signal = 0, 1, 2, 3 respectively
+ RATE_54, RATE_54, RATE_54, RATE_54, // OFDM PLCP Signal = 4, 5, 6, 7 respectively
+ RATE_48, RATE_24, RATE_12, RATE_6, // OFDM PLCP Signal = 8, 9, 10, 11 respectively
+ RATE_54, RATE_36, RATE_18, RATE_9, // OFDM PLCP Signal = 12, 13, 14, 15 respectively
+};
+
+UCHAR OfdmRateToRxwiMCS[12] = {
+ 0, 0, 0, 0,
+ 0, 1, 2, 3, // OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
+ 4, 5, 6, 7, // OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
+};
+UCHAR RxwiMCSToOfdmRate[12] = {
+ RATE_6, RATE_9, RATE_12, RATE_18,
+ RATE_24, RATE_36, RATE_48, RATE_54, // OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
+ 4, 5, 6, 7, // OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
+};
+
+char* MCSToMbps[] = {"1Mbps","2Mbps","5.5Mbps","11Mbps","06Mbps","09Mbps","12Mbps","18Mbps","24Mbps","36Mbps","48Mbps","54Mbps","MM-0","MM-1","MM-2","MM-3","MM-4","MM-5","MM-6","MM-7","MM-8","MM-9","MM-10","MM-11","MM-12","MM-13","MM-14","MM-15","MM-32","ee1","ee2","ee3"};
+
+UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2};
+//UCHAR default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1};
+UCHAR default_sta_aifsn[]={3,7,2,2};
+
+UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO};
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ API for MLME to transmit management frame to AP (BSS Mode)
+ or station (IBSS Mode)
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Pointer to the outgoing 802.11 frame
+ Length Size of outgoing management frame
+
+ Return Value:
+ NDIS_STATUS_FAILURE
+ NDIS_STATUS_PENDING
+ NDIS_STATUS_SUCCESS
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS MiniportMMRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PUCHAR pData,
+ IN UINT Length)
+{
+ PNDIS_PACKET pPacket;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ ULONG FreeNum;
+ UCHAR IrqState;
+ UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
+
+ ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
+
+ QueIdx=3;
+
+ // 2860C use Tx Ring
+
+ IrqState = pAd->irq_disabled;
+
+ do
+ {
+ // Reset is in progress, stop immediately
+ if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
+ !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+ {
+ Status = NDIS_STATUS_FAILURE;
+ break;
+ }
+
+ // Check Free priority queue
+ // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
+
+ // 2860C use Tx Ring
+ if (pAd->MACVersion == 0x28600100)
+ {
+ FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
+ }
+ else
+ {
+ FreeNum = GET_MGMTRING_FREENO(pAd);
+ }
+
+ if ((FreeNum > 0))
+ {
+ // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
+ NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
+ Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
+ break;
+ }
+
+ //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+ //pAd->CommonCfg.MlmeRate = RATE_2;
+
+
+ Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
+ if (Status != NDIS_STATUS_SUCCESS)
+ RTMPFreeNdisPacket(pAd, pPacket);
+ }
+ else
+ {
+ pAd->RalinkCounters.MgmtRingFullCount++;
+ DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
+ QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
+ }
+
+ } while (FALSE);
+
+
+ return Status;
+}
+
+
+
+NDIS_STATUS MlmeDataHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket);
+
+#define MAX_DATAMM_RETRY 3
+/*
+ ========================================================================
+
+ Routine Description:
+ API for MLME to transmit management frame to AP (BSS Mode)
+ or station (IBSS Mode)
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Pointer to the outgoing 802.11 frame
+ Length Size of outgoing management frame
+
+ Return Value:
+ NDIS_STATUS_FAILURE
+ NDIS_STATUS_PENDING
+ NDIS_STATUS_SUCCESS
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS MiniportDataMMRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PUCHAR pData,
+ IN UINT Length)
+{
+ PNDIS_PACKET pPacket;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ ULONG FreeNum;
+ int retry = 0;
+ UCHAR IrqState;
+ UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
+
+ ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
+
+ // 2860C use Tx Ring
+ IrqState = pAd->irq_disabled;
+
+ do
+ {
+ // Reset is in progress, stop immediately
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
+ !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+ {
+ Status = NDIS_STATUS_FAILURE;
+ break;
+ }
+
+ // Check Free priority queue
+ // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
+
+ // 2860C use Tx Ring
+
+ // free Tx(QueIdx) resources
+ FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
+
+ if ((FreeNum > 0))
+ {
+ // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
+ NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
+ Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
+ break;
+ }
+
+ //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+ //pAd->CommonCfg.MlmeRate = RATE_2;
+
+
+ Status = MlmeDataHardTransmit(pAd, QueIdx, pPacket);
+ if (Status != NDIS_STATUS_SUCCESS)
+ RTMPFreeNdisPacket(pAd, pPacket);
+ retry = MAX_DATAMM_RETRY;
+ }
+ else
+ {
+ retry ++;
+
+ printk("retry %d\n", retry);
+ pAd->RalinkCounters.MgmtRingFullCount++;
+
+ if (retry >= MAX_DATAMM_RETRY)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
+ QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
+ }
+ }
+
+ } while (retry < MAX_DATAMM_RETRY);
+
+
+ return Status;
+}
+
+
+
+
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Copy frame from waiting queue into relative ring buffer and set
+ appropriate ASIC register to kick hardware transmit function
+
+ Arguments:
+ pAd Pointer to our adapter
+ pBuffer Pointer to memory of outgoing frame
+ Length Size of outgoing management frame
+
+ Return Value:
+ NDIS_STATUS_FAILURE
+ NDIS_STATUS_PENDING
+ NDIS_STATUS_SUCCESS
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS MlmeHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket)
+{
+ if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+#ifdef CARRIER_DETECTION_SUPPORT
+#endif // CARRIER_DETECTION_SUPPORT //
+ )
+ {
+ return NDIS_STATUS_FAILURE;
+ }
+
+ return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
+
+}
+
+NDIS_STATUS MlmeDataHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket)
+{
+ if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+#ifdef CARRIER_DETECTION_SUPPORT
+#endif // CARRIER_DETECTION_SUPPORT //
+ )
+ {
+ return NDIS_STATUS_FAILURE;
+ }
+
+#ifdef RT2870
+ return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
+#endif // RT2870 //
+}
+
+
+
+
+
+NDIS_STATUS MlmeHardTransmitMgmtRing(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket)
+{
+ PACKET_INFO PacketInfo;
+ PUCHAR pSrcBufVA;
+ UINT SrcBufLen;
+ PHEADER_802_11 pHeader_802_11;
+ BOOLEAN bAckRequired, bInsertTimestamp;
+ UCHAR MlmeRate;
+ PTXWI_STRUC pFirstTxWI;
+ MAC_TABLE_ENTRY *pMacEntry = NULL;
+
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+ // Make sure MGMT ring resource won't be used by other threads
+// sample, for IRQ LOCK -> SEM LOCK
+// IrqState = pAd->irq_disabled;
+// if (!IrqState)
+ RTMP_SEM_LOCK(&pAd->MgmtRingLock);
+
+
+ if (pSrcBufVA == NULL)
+ {
+ // The buffer shouldn't be NULL
+// if (!IrqState)
+ RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
+ return NDIS_STATUS_FAILURE;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // outgoing frame always wakeup PHY to prevent frame lost
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ AsicForceWakeup(pAd, TRUE);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE);
+ pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
+
+ if (pHeader_802_11->Addr1[0] & 0x01)
+ {
+ MlmeRate = pAd->CommonCfg.BasicMlmeRate;
+ }
+ else
+ {
+ MlmeRate = pAd->CommonCfg.MlmeRate;
+ }
+
+ // Verify Mlme rate for a / g bands.
+ if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
+ MlmeRate = RATE_6;
+
+ if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
+ (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
+ {
+ pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
+ if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
+#ifdef DOT11_N_SUPPORT
+ || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ if (pAd->LatchRfRegs.Channel > 14)
+ pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
+ else
+ pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ //
+ // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
+ // Snice it's been set to 0 while on MgtMacHeaderInit
+ // By the way this will cause frame to be send on PWR_SAVE failed.
+ //
+ // pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
+ //
+ // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
+#ifdef CONFIG_STA_SUPPORT
+ // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
+ if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
+ {
+ if ((pAd->StaCfg.Psm == PWR_SAVE) &&
+ (pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
+ pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+ else
+ pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ bInsertTimestamp = FALSE;
+ if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
+ {
+#ifdef CONFIG_STA_SUPPORT
+ //Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue.
+ if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
+ {
+ pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ bAckRequired = FALSE;
+ }
+ else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
+ {
+ //pAd->Sequence++;
+ //pHeader_802_11->Sequence = pAd->Sequence;
+
+ if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
+ {
+ bAckRequired = FALSE;
+ pHeader_802_11->Duration = 0;
+ }
+ else
+ {
+ bAckRequired = TRUE;
+ pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
+ if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
+ {
+ bInsertTimestamp = TRUE;
+ }
+ }
+ }
+
+ pHeader_802_11->Sequence = pAd->Sequence++;
+ if (pAd->Sequence >0xfff)
+ pAd->Sequence = 0;
+
+ // Before radar detection done, mgmt frame can not be sent but probe req
+ // Because we need to use probe req to trigger driver to send probe req in passive scan
+ if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
+// if (!IrqState)
+ RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
+ return (NDIS_STATUS_FAILURE);
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
+#endif
+
+ //
+ // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
+ // should always has only one ohysical buffer, and the whole frame size equals
+ // to the first scatter buffer size
+ //
+
+ // Initialize TX Descriptor
+ // For inter-frame gap, the number is for this frame and next frame
+ // For MLME rate, we will fix as 2Mb to match other vendor's implement
+// pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
+
+// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
+ if (pMacEntry == NULL)
+ {
+ RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
+ 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+ }
+ else
+ {
+ RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
+ bInsertTimestamp, FALSE, bAckRequired, FALSE,
+ 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
+ pMacEntry->MaxHTPhyMode.field.MCS, 0,
+ (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
+ IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
+#endif
+
+ // Now do hardware-depened kick out.
+ HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
+
+ // Make sure to release MGMT ring resource
+// if (!IrqState)
+ RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+/********************************************************************************
+
+ New DeQueue Procedures.
+
+ ********************************************************************************/
+
+#define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \
+ do{ \
+ if (bIntContext == FALSE) \
+ RTMP_IRQ_LOCK((lock), IrqFlags); \
+ }while(0)
+
+#define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \
+ do{ \
+ if (bIntContext == FALSE) \
+ RTMP_IRQ_UNLOCK((lock), IrqFlags); \
+ }while(0)
+
+
+/*
+ ========================================================================
+ Tx Path design algorithm:
+ Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
+ Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
+ Classification Rule=>
+ Multicast: (*addr1 & 0x01) == 0x01
+ Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
+ 11N Rate : If peer support HT
+ (1).AMPDU -- If TXBA is negotiated.
+ (2).AMSDU -- If AMSDU is capable for both peer and ourself.
+ *). AMSDU can embedded in a AMPDU, but now we didn't support it.
+ (3).Normal -- Other packets which send as 11n rate.
+
+ B/G Rate : If peer is b/g only.
+ (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
+ (2).Normal -- Other packets which send as b/g rate.
+ Fragment:
+ The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
+
+ Classified Packet Handle Rule=>
+ Multicast:
+ No ACK, //pTxBlk->bAckRequired = FALSE;
+ No WMM, //pTxBlk->bWMM = FALSE;
+ No piggyback, //pTxBlk->bPiggyBack = FALSE;
+ Force LowRate, //pTxBlk->bForceLowRate = TRUE;
+ Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use
+ the same policy to handle it.
+ Force LowRate, //pTxBlk->bForceLowRate = TRUE;
+
+ 11N Rate :
+ No piggyback, //pTxBlk->bPiggyBack = FALSE;
+
+ (1).AMSDU
+ pTxBlk->bWMM = TRUE;
+ (2).AMPDU
+ pTxBlk->bWMM = TRUE;
+ (3).Normal
+
+ B/G Rate :
+ (1).ARALINK
+
+ (2).Normal
+ ========================================================================
+*/
+static UCHAR TxPktClassification(
+ IN RTMP_ADAPTER *pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ UCHAR TxFrameType = TX_UNKOWN_FRAME;
+ UCHAR Wcid;
+ MAC_TABLE_ENTRY *pMacEntry = NULL;
+#ifdef DOT11_N_SUPPORT
+ BOOLEAN bHTRate = FALSE;
+#endif // DOT11_N_SUPPORT //
+
+ Wcid = RTMP_GET_PACKET_WCID(pPacket);
+ if (Wcid == MCAST_WCID)
+ { // Handle for RA is Broadcast/Multicast Address.
+ return TX_MCAST_FRAME;
+ }
+
+ // Handle for unicast packets
+ pMacEntry = &pAd->MacTab.Content[Wcid];
+ if (RTMP_GET_PACKET_LOWRATE(pPacket))
+ { // It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
+ TxFrameType = TX_LEGACY_FRAME;
+ }
+#ifdef DOT11_N_SUPPORT
+ else if (IS_HT_RATE(pMacEntry))
+ { // it's a 11n capable packet
+
+ // Depends on HTPhyMode to check if the peer support the HTRate transmission.
+ // Currently didn't support A-MSDU embedded in A-MPDU
+ bHTRate = TRUE;
+ if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
+ TxFrameType = TX_LEGACY_FRAME;
+#ifdef UAPSD_AP_SUPPORT
+ else if (RTMP_GET_PACKET_EOSP(pPacket))
+ TxFrameType = TX_LEGACY_FRAME;
+#endif // UAPSD_AP_SUPPORT //
+ else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
+ return TX_AMPDU_FRAME;
+ else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
+ return TX_AMSDU_FRAME;
+ else
+ TxFrameType = TX_LEGACY_FRAME;
+ }
+#endif // DOT11_N_SUPPORT //
+ else
+ { // it's a legacy b/g packet.
+ if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
+ (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
+ (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
+ { // if peer support Ralink Aggregation, we use it.
+ TxFrameType = TX_RALINK_FRAME;
+ }
+ else
+ {
+ TxFrameType = TX_LEGACY_FRAME;
+ }
+ }
+
+ // Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
+ if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
+ TxFrameType = TX_FRAG_FRAME;
+
+ return TxFrameType;
+}
+
+
+BOOLEAN RTMP_FillTxBlkInfo(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk)
+{
+ PACKET_INFO PacketInfo;
+ PNDIS_PACKET pPacket;
+ PMAC_TABLE_ENTRY pMacEntry = NULL;
+
+ pPacket = pTxBlk->pPacket;
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
+
+ pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
+ pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
+ pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
+ pTxBlk->FrameGap = IFS_HTTXOP; // ASIC determine Frame Gap
+
+ if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
+ else
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
+
+ // Default to clear this flag
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
+
+
+ if (pTxBlk->Wcid == MCAST_WCID)
+ {
+ pTxBlk->pMacEntry = NULL;
+ {
+#ifdef MCAST_RATE_SPECIFIC
+ PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
+ if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
+ pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
+ else
+#endif // MCAST_RATE_SPECIFIC //
+ pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
+ }
+
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); // AckRequired = FALSE, when broadcast packet in Adhoc mode.
+ //TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
+ if (RTMP_GET_PACKET_MOREDATA(pPacket))
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
+ }
+
+ }
+ else
+ {
+ pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
+ pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
+
+ pMacEntry = pTxBlk->pMacEntry;
+
+
+ // For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
+ if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
+ else
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
+
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+
+ // If support WMM, enable it.
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
+ CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
+
+// if (pAd->StaCfg.bAutoTxRateSwitch)
+// TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
+ {
+ if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
+ ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
+ { // Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
+ pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
+#ifdef DOT11_N_SUPPORT
+ // Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
+ if (IS_HT_STA(pTxBlk->pMacEntry) &&
+ (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
+ ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
+ {
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
+ }
+#endif // DOT11_N_SUPPORT //
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
+ (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
+ { // Currently piggy-back only support when peer is operate in b/g mode.
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
+ }
+#endif // DOT11_N_SUPPORT //
+
+ if (RTMP_GET_PACKET_MOREDATA(pPacket))
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
+ }
+#ifdef UAPSD_AP_SUPPORT
+ if (RTMP_GET_PACKET_EOSP(pPacket))
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
+ }
+#endif // UAPSD_AP_SUPPORT //
+ }
+ else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
+ }
+
+ pMacEntry->DebugTxCount++;
+ }
+
+ return TRUE;
+
+FillTxBlkErr:
+ return FALSE;
+}
+
+
+BOOLEAN CanDoAggregateTransmit(
+ IN RTMP_ADAPTER *pAd,
+ IN NDIS_PACKET *pPacket,
+ IN TX_BLK *pTxBlk)
+{
+
+ //printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
+
+ if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
+ return FALSE;
+
+ if (RTMP_GET_PACKET_DHCP(pPacket) ||
+ RTMP_GET_PACKET_EAPOL(pPacket) ||
+ RTMP_GET_PACKET_WAI(pPacket))
+ return FALSE;
+
+ if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
+ ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
+ { // For AMSDU, allow the packets with total length < max-amsdu size
+ return FALSE;
+ }
+
+ if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
+ (pTxBlk->TxPacketList.Number == 2))
+ { // For RALINK-Aggregation, allow two frames in one batch.
+ return FALSE;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
+ return TRUE;
+ else
+#endif // CONFIG_STA_SUPPORT //
+ return FALSE;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ To do the enqueue operation and extract the first item of waiting
+ list. If a number of available shared memory segments could meet
+ the request of extracted item, the extracted item will be fragmented
+ into shared memory segments.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pQueue Pointer to Waiting Queue
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPDeQueuePacket(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bIntContext,
+ IN UCHAR QIdx, /* BulkOutPipeId */
+ IN UCHAR Max_Tx_Packets)
+{
+ PQUEUE_ENTRY pEntry = NULL;
+ PNDIS_PACKET pPacket;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ UCHAR Count=0;
+ PQUEUE_HEADER pQueue;
+ ULONG FreeNumber[NUM_OF_TX_RING];
+ UCHAR QueIdx, sQIdx, eQIdx;
+ unsigned long IrqFlags = 0;
+ BOOLEAN hasTxDesc = FALSE;
+ TX_BLK TxBlk;
+ TX_BLK *pTxBlk;
+
+#ifdef DBG_DIAGNOSE
+ BOOLEAN firstRound;
+ RtmpDiagStruct *pDiagStruct = &pAd->DiagStruct;
+#endif
+
+
+ if (QIdx == NUM_OF_TX_RING)
+ {
+ sQIdx = 0;
+//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ eQIdx = 3; // 4 ACs, start from 0.
+#endif // CONFIG_STA_SUPPORT //
+ }
+ else
+ {
+ sQIdx = eQIdx = QIdx;
+ }
+
+ for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
+ {
+ Count=0;
+
+ RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
+
+#ifdef DBG_DIAGNOSE
+ firstRound = ((QueIdx == 0) ? TRUE : FALSE);
+#endif // DBG_DIAGNOSE //
+
+ while (1)
+ {
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
+ fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
+ return;
+ }
+
+ if (Count >= Max_Tx_Packets)
+ break;
+
+ DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+ if (&pAd->TxSwQueue[QueIdx] == NULL)
+ {
+#ifdef DBG_DIAGNOSE
+ if (firstRound == TRUE)
+ pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;
+#endif // DBG_DIAGNOSE //
+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+ break;
+ }
+
+
+ // probe the Queue Head
+ pQueue = &pAd->TxSwQueue[QueIdx];
+ if ((pEntry = pQueue->Head) == NULL)
+ {
+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+ break;
+ }
+
+ pTxBlk = &TxBlk;
+ NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
+ //InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it.
+ pTxBlk->QueIdx = QueIdx;
+
+ pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+
+ // Early check to make sure we have enoguh Tx Resource.
+ hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
+ if (!hasTxDesc)
+ {
+ pAd->PrivateInfo.TxRingFullCnt++;
+
+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+
+ break;
+ }
+
+ pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
+ pEntry = RemoveHeadQueue(pQueue);
+ pTxBlk->TotalFrameNum++;
+ pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
+ pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
+ pTxBlk->pPacket = pPacket;
+ InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
+
+ if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
+ {
+ // Enhance SW Aggregation Mechanism
+ if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
+ {
+ InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+ break;
+ }
+
+ do{
+ if((pEntry = pQueue->Head) == NULL)
+ break;
+
+ // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
+ pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+ FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
+ hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
+ if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
+ break;
+
+ //Remove the packet from the TxSwQueue and insert into pTxBlk
+ pEntry = RemoveHeadQueue(pQueue);
+ ASSERT(pEntry);
+ pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+ pTxBlk->TotalFrameNum++;
+ pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
+ pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
+ InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
+ }while(1);
+
+ if (pTxBlk->TxPacketList.Number == 1)
+ pTxBlk->TxFrameType = TX_LEGACY_FRAME;
+ }
+
+#ifdef RT2870
+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+#endif // RT2870 //
+
+ Count += pTxBlk->TxPacketList.Number;
+
+ // Do HardTransmit now.
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
+
+#ifdef RT2870
+ if (!hasTxDesc)
+ RTUSBKickBulkOut(pAd);
+#endif // RT2870 //
+
+#ifdef BLOCK_NET_IF
+ if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE)
+ && (pAd->TxSwQueue[QueIdx].Number < 1))
+ {
+ releaseNetIf(&pAd->blockQueueTab[QueIdx]);
+ }
+#endif // BLOCK_NET_IF //
+
+ }
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculates the duration which is required to transmit out frames
+ with given size and specified rate.
+
+ Arguments:
+ pAd Pointer to our adapter
+ Rate Transmit rate
+ Size Frame size in units of byte
+
+ Return Value:
+ Duration number in units of usec
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+USHORT RTMPCalcDuration(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Rate,
+ IN ULONG Size)
+{
+ ULONG Duration = 0;
+
+ if (Rate < RATE_FIRST_OFDM_RATE) // CCK
+ {
+ if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
+ Duration = 96; // 72+24 preamble+plcp
+ else
+ Duration = 192; // 144+48 preamble+plcp
+
+ Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
+ if ((Size << 4) % RateIdTo500Kbps[Rate])
+ Duration ++;
+ }
+ else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
+ {
+ Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
+ Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
+ if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
+ Duration += 4;
+ }
+ else //mimo rate
+ {
+ Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
+ }
+
+ return (USHORT)Duration;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculates the duration which is required to transmit out frames
+ with given size and specified rate.
+
+ Arguments:
+ pTxWI Pointer to head of each MPDU to HW.
+ Ack Setting for Ack requirement bit
+ Fragment Setting for Fragment bit
+ RetryMode Setting for retry mode
+ Ifs Setting for IFS gap
+ Rate Setting for transmit rate
+ Service Setting for service
+ Length Frame length
+ TxPreamble Short or Long preamble when using CCK rates
+ QueIdx - 0-3, according to 802.11e/d4.4 June/2003
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ See also : BASmartHardTransmit() !!!
+
+ ========================================================================
+*/
+VOID RTMPWriteTxWI(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXWI_STRUC pOutTxWI,
+ IN BOOLEAN FRAG,
+ IN BOOLEAN CFACK,
+ IN BOOLEAN InsTimestamp,
+ IN BOOLEAN AMPDU,
+ IN BOOLEAN Ack,
+ IN BOOLEAN NSeq, // HW new a sequence.
+ IN UCHAR BASize,
+ IN UCHAR WCID,
+ IN ULONG Length,
+ IN UCHAR PID,
+ IN UCHAR TID,
+ IN UCHAR TxRate,
+ IN UCHAR Txopmode,
+ IN BOOLEAN CfAck,
+ IN HTTRANSMIT_SETTING *pTransmit)
+{
+ PMAC_TABLE_ENTRY pMac = NULL;
+ TXWI_STRUC TxWI;
+ PTXWI_STRUC pTxWI;
+
+ if (WCID < MAX_LEN_OF_MAC_TABLE)
+ pMac = &pAd->MacTab.Content[WCID];
+
+ //
+ // Always use Long preamble before verifiation short preamble functionality works well.
+ // Todo: remove the following line if short preamble functionality works
+ //
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+ NdisZeroMemory(&TxWI, TXWI_SIZE);
+ pTxWI = &TxWI;
+
+ pTxWI->FRAG= FRAG;
+
+ pTxWI->CFACK = CFACK;
+ pTxWI->TS= InsTimestamp;
+ pTxWI->AMPDU = AMPDU;
+ pTxWI->ACK = Ack;
+ pTxWI->txop= Txopmode;
+
+ pTxWI->NSEQ = NSeq;
+ // John tune the performace with Intel Client in 20 MHz performance
+#ifdef DOT11_N_SUPPORT
+ BASize = pAd->CommonCfg.TxBASize;
+
+ if( BASize >7 )
+ BASize =7;
+ pTxWI->BAWinSize = BASize;
+ pTxWI->ShortGI = pTransmit->field.ShortGI;
+ pTxWI->STBC = pTransmit->field.STBC;
+#endif // DOT11_N_SUPPORT //
+
+ pTxWI->WirelessCliID = WCID;
+ pTxWI->MPDUtotalByteCount = Length;
+ pTxWI->PacketId = PID;
+
+ // If CCK or OFDM, BW must be 20
+ pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+#ifdef DOT11N_DRAFT3
+ if (pTxWI->BW)
+ pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
+#endif // DOT11N_DRAFT3 //
+
+ pTxWI->MCS = pTransmit->field.MCS;
+ pTxWI->PHYMODE = pTransmit->field.MODE;
+ pTxWI->CFACK = CfAck;
+
+#ifdef DOT11_N_SUPPORT
+ if (pMac)
+ {
+ if (pAd->CommonCfg.bMIMOPSEnable)
+ {
+ if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
+ {
+ // Dynamic MIMO Power Save Mode
+ pTxWI->MIMOps = 1;
+ }
+ else if (pMac->MmpsMode == MMPS_STATIC)
+ {
+ // Static MIMO Power Save Mode
+ if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
+ {
+ pTxWI->MCS = 7;
+ pTxWI->MIMOps = 0;
+ }
+ }
+ }
+ //pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
+ if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
+ {
+ pTxWI->MpduDensity = 7;
+ }
+ else
+ {
+ pTxWI->MpduDensity = pMac->MpduDensity;
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+ pTxWI->PacketId = pTxWI->MCS;
+ NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
+}
+
+
+VOID RTMPWriteTxWI_Data(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PTXWI_STRUC pTxWI,
+ IN TX_BLK *pTxBlk)
+{
+ HTTRANSMIT_SETTING *pTransmit;
+ PMAC_TABLE_ENTRY pMacEntry;
+#ifdef DOT11_N_SUPPORT
+ UCHAR BASize;
+#endif // DOT11_N_SUPPORT //
+
+
+ ASSERT(pTxWI);
+
+ pTransmit = pTxBlk->pTransmit;
+ pMacEntry = pTxBlk->pMacEntry;
+
+
+ //
+ // Always use Long preamble before verifiation short preamble functionality works well.
+ // Todo: remove the following line if short preamble functionality works
+ //
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+ NdisZeroMemory(pTxWI, TXWI_SIZE);
+
+ pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
+ pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
+ pTxWI->txop = pTxBlk->FrameGap;
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ if (pMacEntry &&
+ (pAd->StaCfg.BssType == BSS_INFRA) &&
+ (pMacEntry->ValidAsDls == TRUE))
+ pTxWI->WirelessCliID = BSSID_WCID;
+ else
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+ pTxWI->WirelessCliID = pTxBlk->Wcid;
+
+ pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+ pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
+
+ // If CCK or OFDM, BW must be 20
+ pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if (pTxWI->BW)
+ pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
+#endif // DOT11N_DRAFT3 //
+ pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
+
+ // John tune the performace with Intel Client in 20 MHz performance
+ BASize = pAd->CommonCfg.TxBASize;
+ if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
+ {
+ UCHAR RABAOriIdx = 0; //The RA's BA Originator table index.
+
+ RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
+ BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
+ }
+
+ pTxWI->TxBF = pTransmit->field.TxBF;
+ pTxWI->BAWinSize = BASize;
+ pTxWI->ShortGI = pTransmit->field.ShortGI;
+ pTxWI->STBC = pTransmit->field.STBC;
+#endif // DOT11_N_SUPPORT //
+
+ pTxWI->MCS = pTransmit->field.MCS;
+ pTxWI->PHYMODE = pTransmit->field.MODE;
+
+#ifdef DOT11_N_SUPPORT
+ if (pMacEntry)
+ {
+ if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
+ {
+ // Dynamic MIMO Power Save Mode
+ pTxWI->MIMOps = 1;
+ }
+ else if (pMacEntry->MmpsMode == MMPS_STATIC)
+ {
+ // Static MIMO Power Save Mode
+ if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
+ {
+ pTxWI->MCS = 7;
+ pTxWI->MIMOps = 0;
+ }
+ }
+
+ if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
+ {
+ pTxWI->MpduDensity = 7;
+ }
+ else
+ {
+ pTxWI->MpduDensity = pMacEntry->MpduDensity;
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+#ifdef DBG_DIAGNOSE
+ if (pTxBlk->QueIdx== 0)
+ {
+ pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
+ pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
+ }
+#endif // DBG_DIAGNOSE //
+
+ // for rate adapation
+ pTxWI->PacketId = pTxWI->MCS;
+#ifdef INF_AMAZON_SE
+/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
+ if( RTMP_GET_PACKET_NOBULKOUT(pTxBlk->pPacket))
+ {
+ if(pTxWI->PHYMODE == MODE_CCK)
+ {
+ pTxWI->PacketId = 6;
+ }
+ }
+#endif // INF_AMAZON_SE //
+}
+
+
+VOID RTMPWriteTxWI_Cache(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PTXWI_STRUC pTxWI,
+ IN TX_BLK *pTxBlk)
+{
+ PHTTRANSMIT_SETTING /*pTxHTPhyMode,*/ pTransmit;
+ PMAC_TABLE_ENTRY pMacEntry;
+
+ //
+ // update TXWI
+ //
+ pMacEntry = pTxBlk->pMacEntry;
+ pTransmit = pTxBlk->pTransmit;
+
+ //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
+ //if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry))
+ //if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch))
+ if (pMacEntry->bAutoTxRateSwitch)
+ {
+ pTxWI->txop = IFS_HTTXOP;
+
+ // If CCK or OFDM, BW must be 20
+ pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+ pTxWI->ShortGI = pTransmit->field.ShortGI;
+ pTxWI->STBC = pTransmit->field.STBC;
+
+ pTxWI->MCS = pTransmit->field.MCS;
+ pTxWI->PHYMODE = pTransmit->field.MODE;
+
+ // set PID for TxRateSwitching
+ pTxWI->PacketId = pTransmit->field.MCS;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
+ pTxWI->MIMOps = 0;
+
+#ifdef DOT11N_DRAFT3
+ if (pTxWI->BW)
+ pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
+#endif // DOT11N_DRAFT3 //
+
+ if (pAd->CommonCfg.bMIMOPSEnable)
+ {
+ // MIMO Power Save Mode
+ if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
+ {
+ // Dynamic MIMO Power Save Mode
+ pTxWI->MIMOps = 1;
+ }
+ else if (pMacEntry->MmpsMode == MMPS_STATIC)
+ {
+ // Static MIMO Power Save Mode
+ if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
+ {
+ pTxWI->MCS = 7;
+ pTxWI->MIMOps = 0;
+ }
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+#ifdef DBG_DIAGNOSE
+ if (pTxBlk->QueIdx== 0)
+ {
+ pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
+ pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
+ }
+#endif // DBG_DIAGNOSE //
+
+ pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculates the duration which is required to transmit out frames
+ with given size and specified rate.
+
+ Arguments:
+ pTxD Pointer to transmit descriptor
+ Ack Setting for Ack requirement bit
+ Fragment Setting for Fragment bit
+ RetryMode Setting for retry mode
+ Ifs Setting for IFS gap
+ Rate Setting for transmit rate
+ Service Setting for service
+ Length Frame length
+ TxPreamble Short or Long preamble when using CCK rates
+ QueIdx - 0-3, according to 802.11e/d4.4 June/2003
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ========================================================================
+*/
+VOID RTMPWriteTxDescriptor(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXD_STRUC pTxD,
+ IN BOOLEAN bWIV,
+ IN UCHAR QueueSEL)
+{
+ //
+ // Always use Long preamble before verifiation short preamble functionality works well.
+ // Todo: remove the following line if short preamble functionality works
+ //
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+
+ pTxD->WIV = (bWIV) ? 1: 0;
+ pTxD->QSEL= (QueueSEL);
+ if (pAd->bGenOneHCCA == TRUE)
+ pTxD->QSEL= FIFO_HCCA;
+ pTxD->DMADONE = 0;
+}
+
+
+// should be called only when -
+// 1. MEADIA_CONNECTED
+// 2. AGGREGATION_IN_USED
+// 3. Fragmentation not in used
+// 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
+BOOLEAN TxFrameIsAggregatible(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pPrevAddr1,
+ IN PUCHAR p8023hdr)
+{
+
+ // can't aggregate EAPOL (802.1x) frame
+ if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
+ return FALSE;
+
+ // can't aggregate multicast/broadcast frame
+ if (p8023hdr[0] & 0x01)
+ return FALSE;
+
+ if (INFRA_ON(pAd)) // must be unicast to AP
+ return TRUE;
+ else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check the MSDU Aggregation policy
+ 1.HT aggregation is A-MSDU
+ 2.legaacy rate aggregation is software aggregation by Ralink.
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN PeerIsAggreOn(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG TxRate,
+ IN PMAC_TABLE_ENTRY pMacEntry)
+{
+ ULONG AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
+
+ if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
+ {
+#ifdef DOT11_N_SUPPORT
+ if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
+ {
+ return TRUE;
+ }
+#endif // DOT11_N_SUPPORT //
+
+#ifdef AGGREGATION_SUPPORT
+ if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
+ { // legacy Ralink Aggregation support
+ return TRUE;
+ }
+#endif // AGGREGATION_SUPPORT //
+ }
+
+ return FALSE;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check and fine the packet waiting in SW queue with highest priority
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ pQueue Pointer to Waiting Queue
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+PQUEUE_HEADER RTMPCheckTxSwQueue(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pQueIdx)
+{
+
+ ULONG Number;
+ // 2004-11-15 to be removed. test aggregation only
+// if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))
+// return NULL;
+
+ Number = pAd->TxSwQueue[QID_AC_BK].Number
+ + pAd->TxSwQueue[QID_AC_BE].Number
+ + pAd->TxSwQueue[QID_AC_VI].Number
+ + pAd->TxSwQueue[QID_AC_VO].Number
+ + pAd->TxSwQueue[QID_HCCA].Number;
+
+ if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
+ {
+ *pQueIdx = QID_AC_VO;
+ return (&pAd->TxSwQueue[QID_AC_VO]);
+ }
+ else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
+ {
+ *pQueIdx = QID_AC_VI;
+ return (&pAd->TxSwQueue[QID_AC_VI]);
+ }
+ else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
+ {
+ *pQueIdx = QID_AC_BE;
+ return (&pAd->TxSwQueue[QID_AC_BE]);
+ }
+ else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
+ {
+ *pQueIdx = QID_AC_BK;
+ return (&pAd->TxSwQueue[QID_AC_BK]);
+ }
+ else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
+ {
+ *pQueIdx = QID_HCCA;
+ return (&pAd->TxSwQueue[QID_HCCA]);
+ }
+
+ // No packet pending in Tx Sw queue
+ *pQueIdx = QID_AC_BK;
+
+ return (NULL);
+}
+
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Suspend MSDU transmission
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPSuspendMsduTransmission(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
+
+
+ //
+ // Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
+ // use Lowbound as R66 value on ScanNextChannel(...)
+ //
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
+
+ // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
+ //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));
+ RTMPSetAGCInitValue(pAd, BW_20);
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+ //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Resume MSDU transmission
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPResumeMsduTransmission(
+ IN PRTMP_ADAPTER pAd)
+{
+// UCHAR IrqState;
+
+ DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
+
+
+ // After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
+ // R66 should not be 0
+ if (pAd->BbpTuning.R66CurrentValue == 0)
+ {
+ pAd->BbpTuning.R66CurrentValue = 0x38;
+ DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"));
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+// sample, for IRQ LOCK to SEM LOCK
+// IrqState = pAd->irq_disabled;
+// if (IrqState)
+// RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+// else
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+}
+
+
+UINT deaggregate_AMSDU_announce(
+ IN PRTMP_ADAPTER pAd,
+ PNDIS_PACKET pPacket,
+ IN PUCHAR pData,
+ IN ULONG DataSize)
+{
+ USHORT PayloadSize;
+ USHORT SubFrameSize;
+ PHEADER_802_3 pAMSDUsubheader;
+ UINT nMSDU;
+ UCHAR Header802_3[14];
+
+ PUCHAR pPayload, pDA, pSA, pRemovedLLCSNAP;
+ PNDIS_PACKET pClonePacket;
+
+
+
+ nMSDU = 0;
+
+ while (DataSize > LENGTH_802_3)
+ {
+
+ nMSDU++;
+
+ //hex_dump("subheader", pData, 64);
+ pAMSDUsubheader = (PHEADER_802_3)pData;
+ //pData += LENGTH_802_3;
+ PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
+ SubFrameSize = PayloadSize + LENGTH_802_3;
+
+
+ if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
+ {
+ break;
+ }
+
+ //printk("%d subframe: Size = %d\n", nMSDU, PayloadSize);
+
+ pPayload = pData + LENGTH_802_3;
+ pDA = pData;
+ pSA = pData + MAC_ADDR_LEN;
+
+ // convert to 802.3 header
+ CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
+
+#ifdef CONFIG_STA_SUPPORT
+ if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
+ {
+ // avoid local heap overflow, use dyanamic allocation
+ MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+ memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
+ Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
+ WpaEAPOLKeyAction(pAd, Elem);
+ kfree(Elem);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pRemovedLLCSNAP)
+ {
+ pPayload -= LENGTH_802_3;
+ PayloadSize += LENGTH_802_3;
+ NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
+ if (pClonePacket)
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+
+ // A-MSDU has padding to multiple of 4 including subframe header.
+ // align SubFrameSize up to multiple of 4
+ SubFrameSize = (SubFrameSize+3)&(~0x3);
+
+
+ if (SubFrameSize > 1528 || SubFrameSize < 32)
+ {
+ break;
+ }
+
+ if (DataSize > SubFrameSize)
+ {
+ pData += SubFrameSize;
+ DataSize -= SubFrameSize;
+ }
+ else
+ {
+ // end of A-MSDU
+ DataSize = 0;
+ }
+ }
+
+ // finally release original rx packet
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+
+ return nMSDU;
+}
+
+
+UINT BA_Reorder_AMSDU_Annnounce(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ PUCHAR pData;
+ USHORT DataSize;
+ UINT nMSDU = 0;
+
+ pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
+ DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
+
+ nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
+
+ return nMSDU;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Look up the MAC address in the MAC table. Return NULL if not found.
+ Return:
+ pEntry - pointer to the MAC entry; NULL is not found
+ ==========================================================================
+*/
+MAC_TABLE_ENTRY *MacTableLookup(
+ IN PRTMP_ADAPTER pAd,
+ PUCHAR pAddr)
+{
+ ULONG HashIdx;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+ HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+ pEntry = pAd->MacTab.Hash[HashIdx];
+
+ while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
+ {
+ if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
+ {
+ break;
+ }
+ else
+ pEntry = pEntry->pNext;
+ }
+
+ return pEntry;
+}
+
+MAC_TABLE_ENTRY *MacTableInsertEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR apidx,
+ IN BOOLEAN CleanAll)
+{
+ UCHAR HashIdx;
+ int i, FirstWcid;
+ MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
+// USHORT offset;
+// ULONG addr;
+
+ // if FULL, return
+ if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
+ return NULL;
+
+ FirstWcid = 1;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ if (pAd->StaCfg.BssType == BSS_INFRA)
+ FirstWcid = 2;
+#endif // CONFIG_STA_SUPPORT //
+
+ // allocate one MAC entry
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) // skip entry#0 so that "entry index == AID" for fast lookup
+ {
+ // pick up the first available vacancy
+ if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
+ (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
+ (pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
+ (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ && (pAd->MacTab.Content[i].ValidAsDls == FALSE)
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+ )
+ {
+ pEntry = &pAd->MacTab.Content[i];
+ if (CleanAll == TRUE)
+ {
+ pEntry->MaxSupportedRate = RATE_11;
+ pEntry->CurrTxRate = RATE_11;
+ NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
+ pEntry->PairwiseKey.KeyLen = 0;
+ pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
+ }
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ if (apidx >= MIN_NET_DEVICE_FOR_DLS)
+ {
+ pEntry->ValidAsCLI = FALSE;
+ pEntry->ValidAsWDS = FALSE;
+ pEntry->ValidAsApCli = FALSE;
+ pEntry->ValidAsMesh = FALSE;
+ pEntry->ValidAsDls = TRUE;
+ pEntry->isCached = FALSE;
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pEntry->ValidAsCLI = TRUE;
+ pEntry->ValidAsWDS = FALSE;
+ pEntry->ValidAsApCli = FALSE;
+ pEntry->ValidAsMesh = FALSE;
+ pEntry->ValidAsDls = FALSE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ pEntry->bIAmBadAtheros = FALSE;
+ pEntry->pAd = pAd;
+ pEntry->CMTimerRunning = FALSE;
+ pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
+ pEntry->RSNIE_Len = 0;
+ NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
+ pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
+
+ if (pEntry->ValidAsMesh)
+ pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
+ else if (pEntry->ValidAsApCli)
+ pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
+ else if (pEntry->ValidAsWDS)
+ pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ else if (pEntry->ValidAsDls)
+ pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_DLS);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+ else
+ pEntry->apidx = apidx;
+
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pEntry->AuthMode = pAd->StaCfg.AuthMode;
+ pEntry->WepStatus = pAd->StaCfg.WepStatus;
+ pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ pEntry->GTKState = REKEY_NEGOTIATING;
+ pEntry->PairwiseKey.KeyLen = 0;
+ pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ if (pEntry->ValidAsDls == TRUE)
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ else
+#endif //QOS_DLS_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+ pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
+ COPY_MAC_ADDR(pEntry->Addr, pAddr);
+ pEntry->Sst = SST_NOT_AUTH;
+ pEntry->AuthState = AS_NOT_AUTH;
+ pEntry->Aid = (USHORT)i; //0;
+ pEntry->CapabilityInfo = 0;
+ pEntry->PsMode = PWR_ACTIVE;
+ pEntry->PsQIdleCount = 0;
+ pEntry->NoDataIdleCount = 0;
+ pEntry->ContinueTxFailCnt = 0;
+ InitializeQueueHeader(&pEntry->PsQueue);
+
+
+ pAd->MacTab.Size ++;
+
+ // Add this entry into ASIC RX WCID search table
+ RT28XX_STA_ENTRY_ADD(pAd, pEntry);
+
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
+ break;
+ }
+ }
+
+ // add this MAC entry into HASH table
+ if (pEntry)
+ {
+ HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+ if (pAd->MacTab.Hash[HashIdx] == NULL)
+ {
+ pAd->MacTab.Hash[HashIdx] = pEntry;
+ }
+ else
+ {
+ pCurrEntry = pAd->MacTab.Hash[HashIdx];
+ while (pCurrEntry->pNext != NULL)
+ pCurrEntry = pCurrEntry->pNext;
+ pCurrEntry->pNext = pEntry;
+ }
+ }
+
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+ return pEntry;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Delete a specified client from MAC table
+ ==========================================================================
+ */
+BOOLEAN MacTableDeleteEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT wcid,
+ IN PUCHAR pAddr)
+{
+ USHORT HashIdx;
+ MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
+ BOOLEAN Cancelled;
+ //USHORT offset; // unused variable
+ //UCHAR j; // unused variable
+
+ if (wcid >= MAX_LEN_OF_MAC_TABLE)
+ return FALSE;
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+
+ HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+ //pEntry = pAd->MacTab.Hash[HashIdx];
+ pEntry = &pAd->MacTab.Content[wcid];
+
+ if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ || pEntry->ValidAsDls
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+ ))
+ {
+ if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
+ {
+
+ // Delete this entry from ASIC on-chip WCID Table
+ RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
+
+#ifdef DOT11_N_SUPPORT
+ // free resources of BA
+ BASessionTearDownALL(pAd, pEntry->Aid);
+#endif // DOT11_N_SUPPORT //
+
+
+ pPrevEntry = NULL;
+ pProbeEntry = pAd->MacTab.Hash[HashIdx];
+ ASSERT(pProbeEntry);
+
+ // update Hash list
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ // not found !!!
+ ASSERT(pProbeEntry != NULL);
+
+ RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
+
+
+ if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
+ {
+ RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
+ pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
+ }
+
+
+ NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
+ pAd->MacTab.Size --;
+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
+ }
+ else
+ {
+ printk("\n%s: Impossible Wcid = %d !!!!!\n", __FUNCTION__, wcid);
+ }
+ }
+
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+ //Reset operating mode when no Sta.
+ if (pAd->MacTab.Size == 0)
+ {
+#ifdef DOT11_N_SUPPORT
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
+#endif // DOT11_N_SUPPORT //
+ //AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
+ RT28XX_UPDATE_PROTECT(pAd); // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+ }
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ This routine reset the entire MAC table. All packets pending in
+ the power-saving queues are freed here.
+ ==========================================================================
+ */
+VOID MacTableReset(
+ IN PRTMP_ADAPTER pAd)
+{
+ int i;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
+ //NdisAcquireSpinLock(&pAd->MacTabLock);
+
+ for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
+ {
+
+#ifdef DOT11_N_SUPPORT
+ // free resources of BA
+ BASessionTearDownALL(pAd, i);
+#endif // DOT11_N_SUPPORT //
+
+ pAd->MacTab.Content[i].ValidAsCLI = FALSE;
+
+
+
+#ifdef RT2870
+ NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
+ RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
+#endif // RT2870 //
+
+ //AsicDelWcidTab(pAd, i);
+ }
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID AssocParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
+ IN PUCHAR pAddr,
+ IN USHORT CapabilityInfo,
+ IN ULONG Timeout,
+ IN USHORT ListenIntv)
+{
+ COPY_MAC_ADDR(AssocReq->Addr, pAddr);
+ // Add mask to support 802.11b mode only
+ AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
+ AssocReq->Timeout = Timeout;
+ AssocReq->ListenIntv = ListenIntv;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID DisassocParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
+ IN PUCHAR pAddr,
+ IN USHORT Reason)
+{
+ COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
+ DisassocReq->Reason = Reason;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check the out going frame, if this is an DHCP or ARP datagram
+ will be duplicate another frame at low data rate transmit.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pPacket Pointer to outgoing Ndis frame
+
+ Return Value:
+ TRUE To be duplicate at Low data rate transmit. (1mb)
+ FALSE Do nothing.
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ MAC header + IP Header + UDP Header
+ 14 Bytes 20 Bytes
+
+ UDP Header
+ 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
+ Source Port
+ 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
+ Destination Port
+
+ port 0x43 means Bootstrap Protocol, server.
+ Port 0x44 means Bootstrap Protocol, client.
+
+ ========================================================================
+*/
+
+BOOLEAN RTMPCheckDHCPFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ PACKET_INFO PacketInfo;
+ ULONG NumberOfBytesRead = 0;
+ ULONG CurrentOffset = 0;
+ PVOID pVirtualAddress = NULL;
+ UINT NdisBufferLength;
+ PUCHAR pSrc;
+ USHORT Protocol;
+ UCHAR ByteOffset36 = 0;
+ UCHAR ByteOffset38 = 0;
+ BOOLEAN ReadFirstParm = TRUE;
+
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
+
+ NumberOfBytesRead += NdisBufferLength;
+ pSrc = (PUCHAR) pVirtualAddress;
+ Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
+
+ //
+ // Check DHCP & BOOTP protocol
+ //
+ while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
+ {
+ if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
+ {
+ CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
+ ByteOffset36 = *(pSrc + CurrentOffset);
+ ReadFirstParm = FALSE;
+ }
+
+ if (NumberOfBytesRead >= 37)
+ {
+ CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
+ ByteOffset38 = *(pSrc + CurrentOffset);
+ //End of Read
+ break;
+ }
+ return FALSE;
+ }
+
+ // Check for DHCP & BOOTP protocol
+ if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
+ {
+ //
+ // 2054 (hex 0806) for ARP datagrams
+ // if this packet is not ARP datagrams, then do nothing
+ // ARP datagrams will also be duplicate at 1mb broadcast frames
+ //
+ if (Protocol != 0x0806 )
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+BOOLEAN RTMPCheckEtherType(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ USHORT TypeLen;
+ UCHAR Byte0, Byte1;
+ PUCHAR pSrcBuf;
+ UINT32 pktLen;
+ UINT16 srcPort, dstPort;
+ BOOLEAN status = TRUE;
+
+
+ pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
+ pktLen = GET_OS_PKT_LEN(pPacket);
+
+ ASSERT(pSrcBuf);
+
+ RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
+
+ // get Ethernet protocol field
+ TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
+
+ pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header.
+
+ if (TypeLen <= 1500)
+ { // 802.3, 802.3 LLC
+ /*
+ DestMAC(6) + SrcMAC(6) + Lenght(2) +
+ DSAP(1) + SSAP(1) + Control(1) +
+ if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
+ => + SNAP (5, OriginationID(3) + etherType(2))
+ */
+ if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
+ {
+ Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
+ RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
+ TypeLen = (USHORT)((Byte0 << 8) + Byte1);
+ pSrcBuf += 8; // Skip this LLC/SNAP header
+ }
+ else
+ {
+ //It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
+ }
+ }
+
+ // If it's a VLAN packet, get the real Type/Length field.
+ if (TypeLen == 0x8100)
+ {
+ /* 0x8100 means VLAN packets */
+
+ /* Dest. MAC Address (6-bytes) +
+ Source MAC Address (6-bytes) +
+ Length/Type = 802.1Q Tag Type (2-byte) +
+ Tag Control Information (2-bytes) +
+ Length / Type (2-bytes) +
+ data payload (0-n bytes) +
+ Pad (0-p bytes) +
+ Frame Check Sequence (4-bytes) */
+
+ RTMP_SET_PACKET_VLAN(pPacket, 1);
+ Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
+ TypeLen = (USHORT)((Byte0 << 8) + Byte1);
+
+ pSrcBuf += 4; // Skip the VLAN Header.
+ }
+
+ switch (TypeLen)
+ {
+ case 0x0800:
+ {
+ ASSERT((pktLen > 34));
+ if (*(pSrcBuf + 9) == 0x11)
+ { // udp packet
+ ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header
+
+ pSrcBuf += 20; // Skip the IP header
+ srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
+ dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
+
+ if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
+ { //It's a BOOTP/DHCP packet
+ RTMP_SET_PACKET_DHCP(pPacket, 1);
+ }
+ }
+ }
+ break;
+ case 0x0806:
+ {
+ //ARP Packet.
+ RTMP_SET_PACKET_DHCP(pPacket, 1);
+ }
+ break;
+ case 0x888e:
+ {
+ // EAPOL Packet.
+ RTMP_SET_PACKET_EAPOL(pPacket, 1);
+ }
+ break;
+ default:
+ status = FALSE;
+ break;
+ }
+
+ return status;
+
+}
+
+
+
+VOID Update_Rssi_Sample(
+ IN PRTMP_ADAPTER pAd,
+ IN RSSI_SAMPLE *pRssi,
+ IN PRXWI_STRUC pRxWI)
+ {
+ CHAR rssi0 = pRxWI->RSSI0;
+ CHAR rssi1 = pRxWI->RSSI1;
+ CHAR rssi2 = pRxWI->RSSI2;
+
+ if (rssi0 != 0)
+ {
+ pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
+ pRssi->AvgRssi0X8 = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
+ pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
+ }
+
+ if (rssi1 != 0)
+ {
+ pRssi->LastRssi1 = ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
+ pRssi->AvgRssi1X8 = (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
+ pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
+ }
+
+ if (rssi2 != 0)
+ {
+ pRssi->LastRssi2 = ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
+ pRssi->AvgRssi2X8 = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
+ pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
+ }
+}
+
+
+
+// Normal legacy Rx packet indication
+VOID Indicate_Legacy_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+ UCHAR Header802_3[LENGTH_802_3];
+
+ // 1. get 802.3 Header
+ // 2. remove LLC
+ // a. pointer pRxBlk->pData to payload
+ // b. modify pRxBlk->DataSize
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
+#endif // CONFIG_STA_SUPPORT //
+
+ if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+
+ STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
+
+#ifdef RT2870
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.bDisableReordering == 0)
+ {
+ PBA_REC_ENTRY pBAEntry;
+ ULONG Now32;
+ UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
+ UCHAR TID = pRxBlk->pRxWI->TID;
+ USHORT Idx;
+
+#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
+
+ if (Wcid < MAX_LEN_OF_MAC_TABLE)
+ {
+ Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
+ if (Idx != 0)
+ {
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ // update last rx time
+ NdisGetSystemUpTime(&Now32);
+ if ((pBAEntry->list.qlen > 0) &&
+ RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
+ )
+ {
+ printk("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU);
+ hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
+ ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
+ }
+ }
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+#endif // RT2870 //
+
+ wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
+
+ //
+ // pass this 802.3 packet to upper layer or forward this packet to WM directly
+ //
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
+#endif // CONFIG_STA_SUPPORT //
+
+}
+
+
+// Normal, AMPDU or AMSDU
+VOID CmmRxnonRalinkFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+#ifdef DOT11_N_SUPPORT
+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
+ {
+ Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+#ifdef DOT11_N_SUPPORT
+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
+ {
+ // handle A-MSDU
+ Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+ }
+ }
+}
+
+
+VOID CmmRxRalinkFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ UCHAR Header802_3[LENGTH_802_3];
+ UINT16 Msdu2Size;
+ UINT16 Payload1Size, Payload2Size;
+ PUCHAR pData2;
+ PNDIS_PACKET pPacket2 = NULL;
+
+
+
+ Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
+
+ if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
+ {
+ /* skip two byte MSDU2 len */
+ pRxBlk->pData += 2;
+ pRxBlk->DataSize -= 2;
+ }
+ else
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ // get 802.3 Header and remove LLC
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
+#endif // CONFIG_STA_SUPPORT //
+
+
+ ASSERT(pRxBlk->pRxPacket);
+
+ // Ralink Aggregation frame
+ pAd->RalinkCounters.OneSecRxAggregationCount ++;
+ Payload1Size = pRxBlk->DataSize - Msdu2Size;
+ Payload2Size = Msdu2Size - LENGTH_802_3;
+
+ pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
+#endif // CONFIG_STA_SUPPORT //
+
+ if (!pPacket2)
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ // update payload size of 1st packet
+ pRxBlk->DataSize = Payload1Size;
+ wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
+#endif // CONFIG_STA_SUPPORT //
+
+ if (pPacket2)
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
+#endif // CONFIG_STA_SUPPORT //
+ }
+}
+
+
+#define RESET_FRAGFRAME(_fragFrame) \
+ { \
+ _fragFrame.RxSize = 0; \
+ _fragFrame.Sequence = 0; \
+ _fragFrame.LastFrag = 0; \
+ _fragFrame.Flags = 0; \
+ }
+
+
+PNDIS_PACKET RTMPDeFragmentDataFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+ UCHAR *pData = pRxBlk->pData;
+ USHORT DataSize = pRxBlk->DataSize;
+ PNDIS_PACKET pRetPacket = NULL;
+ UCHAR *pFragBuffer = NULL;
+ BOOLEAN bReassDone = FALSE;
+ UCHAR HeaderRoom = 0;
+
+
+ ASSERT(pHeader);
+
+ HeaderRoom = pData - (UCHAR *)pHeader;
+
+ // Re-assemble the fragmented packets
+ if (pHeader->Frag == 0) // Frag. Number is 0 : First frag or only one pkt
+ {
+ // the first pkt of fragment, record it.
+ if (pHeader->FC.MoreFrag)
+ {
+ ASSERT(pAd->FragFrame.pFragPacket);
+ pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
+ pAd->FragFrame.RxSize = DataSize + HeaderRoom;
+ NdisMoveMemory(pFragBuffer, pHeader, pAd->FragFrame.RxSize);
+ pAd->FragFrame.Sequence = pHeader->Sequence;
+ pAd->FragFrame.LastFrag = pHeader->Frag; // Should be 0
+ ASSERT(pAd->FragFrame.LastFrag == 0);
+ goto done; // end of processing this frame
+ }
+ }
+ else //Middle & End of fragment
+ {
+ if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
+ (pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
+ {
+ // Fragment is not the same sequence or out of fragment number order
+ // Reset Fragment control blk
+ RESET_FRAGFRAME(pAd->FragFrame);
+ DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
+ goto done; // give up this frame
+ }
+ else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
+ {
+ // Fragment frame is too large, it exeeds the maximum frame size.
+ // Reset Fragment control blk
+ RESET_FRAGFRAME(pAd->FragFrame);
+ DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
+ goto done; // give up this frame
+ }
+
+ //
+ // Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
+ // In this case, we will dropt it.
+ //
+ if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
+ goto done; // give up this frame
+ }
+
+ pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
+
+ // concatenate this fragment into the re-assembly buffer
+ NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
+ pAd->FragFrame.RxSize += DataSize;
+ pAd->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
+
+ // Last fragment
+ if (pHeader->FC.MoreFrag == FALSE)
+ {
+ bReassDone = TRUE;
+ }
+ }
+
+done:
+ // always release rx fragmented packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+
+ // return defragmented packet if packet is reassembled completely
+ // otherwise return NULL
+ if (bReassDone)
+ {
+ PNDIS_PACKET pNewFragPacket;
+
+ // allocate a new packet buffer for fragment
+ pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
+ if (pNewFragPacket)
+ {
+ // update RxBlk
+ pRetPacket = pAd->FragFrame.pFragPacket;
+ pAd->FragFrame.pFragPacket = pNewFragPacket;
+ pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
+ pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
+ pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
+ pRxBlk->pRxPacket = pRetPacket;
+ }
+ else
+ {
+ RESET_FRAGFRAME(pAd->FragFrame);
+ }
+ }
+
+ return pRetPacket;
+}
+
+
+VOID Indicate_AMSDU_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ UINT nMSDU;
+
+ update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
+ RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
+ nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
+}
+
+VOID Indicate_EAPOL_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
+ STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ return;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ if (pEntry == NULL)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+}
+
+#define BCN_TBTT_OFFSET 64 //defer 64 us
+VOID ReSyncBeaconTime(
+ IN PRTMP_ADAPTER pAd)
+{
+
+ UINT32 Offset;
+
+
+ Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
+
+ pAd->TbttTickCount++;
+
+ //
+ // The updated BeaconInterval Value will affect Beacon Interval after two TBTT
+ // beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
+ //
+ if (Offset == (BCN_TBTT_OFFSET-2))
+ {
+ BCN_TIME_CFG_STRUC csr;
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+ csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ; // ASIC register in units of 1/16 TU = 64us
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+ }
+ else
+ {
+ if (Offset == (BCN_TBTT_OFFSET-1))
+ {
+ BCN_TIME_CFG_STRUC csr;
+
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+ csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+ }
+ }
+}
+
diff --git a/drivers/staging/rt3070/common/cmm_data_2870.c b/drivers/staging/rt3070/common/cmm_data_2870.c
new file mode 100644
index 00000000000..b1066aa2bb2
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_data_2870.c
@@ -0,0 +1,980 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+*/
+/*
+ All functions in this file must be USB-depended, or you should out your function
+ in other files.
+
+*/
+#include "../rt_config.h"
+
+
+/*
+ We can do copy the frame into pTxContext when match following conditions.
+ =>
+ =>
+ =>
+*/
+static inline NDIS_STATUS RtmpUSBCanDoWrite(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN HT_TX_CONTEXT *pHTTXContext)
+{
+ NDIS_STATUS canWrite = NDIS_STATUS_RESOURCES;
+
+ if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n"));
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+ }
+ else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE))
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n"));
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+ }
+ else if (pHTTXContext->bCurWriting == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n"));
+ }
+ else
+ {
+ canWrite = NDIS_STATUS_SUCCESS;
+ }
+
+
+ return canWrite;
+}
+
+
+USHORT RtmpUSB_WriteSubTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN BOOLEAN bIsLast,
+ OUT USHORT *FreeNumber)
+{
+
+ // Dummy function. Should be removed in the future.
+ return 0;
+
+}
+
+USHORT RtmpUSB_WriteFragTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR fragNum,
+ OUT USHORT *FreeNumber)
+{
+ HT_TX_CONTEXT *pHTTXContext;
+ USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length.
+ UINT32 fillOffset;
+ TXINFO_STRUC *pTxInfo;
+ TXWI_STRUC *pTxWI;
+ PUCHAR pWirelessPacket = NULL;
+ UCHAR QueIdx;
+ NDIS_STATUS Status;
+ unsigned long IrqFlags;
+ UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
+ BOOLEAN TxQLastRound = FALSE;
+
+ //
+ // get Tx Ring Resource & Dma Buffer address
+ //
+ QueIdx = pTxBlk->QueIdx;
+ pHTTXContext = &pAd->TxContext[QueIdx];
+
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ pHTTXContext = &pAd->TxContext[QueIdx];
+ fillOffset = pHTTXContext->CurWritePosition;
+
+ if(fragNum == 0)
+ {
+ // Check if we have enough space for this bulk-out batch.
+ Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ pHTTXContext->bCurWriting = TRUE;
+
+ // Reserve space for 8 bytes padding.
+ if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
+ {
+ pHTTXContext->ENextBulkOutPosition += 8;
+ pHTTXContext->CurWritePosition += 8;
+ fillOffset += 8;
+ }
+ pTxBlk->Priv = 0;
+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ return(Status);
+ }
+ }
+ else
+ {
+ // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
+ Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ fillOffset += pTxBlk->Priv;
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ return(Status);
+ }
+ }
+
+ NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);
+ pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
+ pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+ pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+ // copy TXWI + WLAN Header + LLC into DMA Header Buffer
+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+ hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+ // Build our URB for USBD
+ DMAHdrLen = TXWI_SIZE + hwHdrLen;
+ USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
+ padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
+ USBDMApktLen += padding;
+
+ pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);
+
+ // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
+
+ if (fragNum == pTxBlk->TotalFragNum)
+ {
+ pTxInfo->USBDMATxburst = 0;
+ if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT)
+ {
+ pTxInfo->SwUseLastRound = 1;
+ TxQLastRound = TRUE;
+ }
+ }
+ else
+ {
+ pTxInfo->USBDMATxburst = 1;
+ }
+
+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
+#endif // RT_BIG_ENDIAN //
+ pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+ pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+
+ // Zero the last padding.
+ pWirelessPacket += pTxBlk->SrcBufLen;
+ NdisZeroMemory(pWirelessPacket, padding + 8);
+
+ if (fragNum == pTxBlk->TotalFragNum)
+ {
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ // Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame.
+ pHTTXContext->CurWritePosition += pTxBlk->Priv;
+ if (TxQLastRound == TRUE)
+ pHTTXContext->CurWritePosition = 8;
+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+
+ // Finally, set bCurWriting as FALSE
+ pHTTXContext->bCurWriting = FALSE;
+
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ // succeed and release the skb buffer
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+ }
+
+
+ return(Status);
+
+}
+
+
+USHORT RtmpUSB_WriteSingleTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN BOOLEAN bIsLast,
+ OUT USHORT *FreeNumber)
+{
+ HT_TX_CONTEXT *pHTTXContext;
+ USHORT hwHdrLen;
+ UINT32 fillOffset;
+ TXINFO_STRUC *pTxInfo;
+ TXWI_STRUC *pTxWI;
+ PUCHAR pWirelessPacket;
+ UCHAR QueIdx;
+ unsigned long IrqFlags;
+ NDIS_STATUS Status;
+ UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
+ BOOLEAN bTxQLastRound = FALSE;
+
+ // For USB, didn't need PCI_MAP_SINGLE()
+ //SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE);
+
+
+ //
+ // get Tx Ring Resource & Dma Buffer address
+ //
+ QueIdx = pTxBlk->QueIdx;
+
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+ pHTTXContext = &pAd->TxContext[QueIdx];
+ fillOffset = pHTTXContext->CurWritePosition;
+
+
+
+ // Check ring full.
+ Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+ if(Status == NDIS_STATUS_SUCCESS)
+ {
+ pHTTXContext->bCurWriting = TRUE;
+
+ pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
+ pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+ // Reserve space for 8 bytes padding.
+ if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
+ {
+ pHTTXContext->ENextBulkOutPosition += 8;
+ pHTTXContext->CurWritePosition += 8;
+ fillOffset += 8;
+ }
+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+ pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+ // copy TXWI + WLAN Header + LLC into DMA Header Buffer
+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+ hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+ // Build our URB for USBD
+ DMAHdrLen = TXWI_SIZE + hwHdrLen;
+ USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
+ padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
+ USBDMApktLen += padding;
+
+ pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
+
+ // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
+ //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
+#endif // CONFIG_STA_SUPPORT //
+
+ if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT)
+ {
+ pTxInfo->SwUseLastRound = 1;
+ bTxQLastRound = TRUE;
+ }
+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
+#endif // RT_BIG_ENDIAN //
+ pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+
+ // We unlock it here to prevent the first 8 bytes maybe over-writed issue.
+ // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext.
+ // 2. An interrupt break our routine and handle bulk-out complete.
+ // 3. In the bulk-out compllete, it need to do another bulk-out,
+ // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
+ // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
+ // 4. Interrupt complete.
+ // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
+ // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
+ // and the packet will wrong.
+ pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+ pWirelessPacket += pTxBlk->SrcBufLen;
+ NdisZeroMemory(pWirelessPacket, padding + 8);
+
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ pHTTXContext->CurWritePosition += pTxBlk->Priv;
+ if (bTxQLastRound)
+ pHTTXContext->CurWritePosition = 8;
+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+ pHTTXContext->bCurWriting = FALSE;
+ }
+
+
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+
+ // succeed and release the skb buffer
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+
+ return(Status);
+
+}
+
+
+USHORT RtmpUSB_WriteMultiTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR frameNum,
+ OUT USHORT *FreeNumber)
+{
+ HT_TX_CONTEXT *pHTTXContext;
+ USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length.
+ UINT32 fillOffset;
+ TXINFO_STRUC *pTxInfo;
+ TXWI_STRUC *pTxWI;
+ PUCHAR pWirelessPacket = NULL;
+ UCHAR QueIdx;
+ NDIS_STATUS Status;
+ unsigned long IrqFlags;
+ //UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
+
+ //
+ // get Tx Ring Resource & Dma Buffer address
+ //
+ QueIdx = pTxBlk->QueIdx;
+ pHTTXContext = &pAd->TxContext[QueIdx];
+
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ if(frameNum == 0)
+ {
+ // Check if we have enough space for this bulk-out batch.
+ Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ pHTTXContext->bCurWriting = TRUE;
+
+ pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
+ pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+
+ // Reserve space for 8 bytes padding.
+ if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
+ {
+
+ pHTTXContext->CurWritePosition += 8;
+ pHTTXContext->ENextBulkOutPosition += 8;
+ }
+ fillOffset = pHTTXContext->CurWritePosition;
+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+ pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+ //
+ // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
+ //
+ if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
+ hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
+ else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
+ hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
+ else
+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+ hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+ // Update the pTxBlk->Priv.
+ pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
+
+ // pTxInfo->USBDMApktLen now just a temp value and will to correct latter.
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
+
+ // Copy it.
+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv);
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
+#endif // RT_BIG_ENDIAN //
+ pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
+ pWirelessPacket += pTxBlk->Priv;
+ }
+ }
+ else
+ { // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
+
+ Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ fillOffset = (pHTTXContext->CurWritePosition + pTxBlk->Priv);
+ pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+ //hwHdrLen = pTxBlk->MpduHeaderLen;
+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen);
+ pWirelessPacket += (pTxBlk->MpduHeaderLen);
+ pTxBlk->Priv += pTxBlk->MpduHeaderLen;
+ }
+ else
+ { // It should not happened now unless we are going to shutdown.
+ DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
+ Status = NDIS_STATUS_FAILURE;
+ }
+ }
+
+
+ // We unlock it here to prevent the first 8 bytes maybe over-write issue.
+ // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext.
+ // 2. An interrupt break our routine and handle bulk-out complete.
+ // 3. In the bulk-out compllete, it need to do another bulk-out,
+ // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
+ // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
+ // 4. Interrupt complete.
+ // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
+ // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
+ // and the packet will wrong.
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
+ goto done;
+ }
+
+ // Copy the frame content into DMA buffer and update the pTxBlk->Priv
+ NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+ pWirelessPacket += pTxBlk->SrcBufLen;
+ pTxBlk->Priv += pTxBlk->SrcBufLen;
+
+done:
+ // Release the skb buffer here
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+
+ return(Status);
+
+}
+
+
+VOID RtmpUSB_FinalWriteTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN USHORT totalMPDUSize,
+ IN USHORT TxIdx)
+{
+ UCHAR QueIdx;
+ HT_TX_CONTEXT *pHTTXContext;
+ UINT32 fillOffset;
+ TXINFO_STRUC *pTxInfo;
+ TXWI_STRUC *pTxWI;
+ UINT32 USBDMApktLen, padding;
+ unsigned long IrqFlags;
+ PUCHAR pWirelessPacket;
+
+ QueIdx = pTxBlk->QueIdx;
+ pHTTXContext = &pAd->TxContext[QueIdx];
+
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ if (pHTTXContext->bCurWriting == TRUE)
+ {
+ fillOffset = pHTTXContext->CurWritePosition;
+ if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
+ && (pHTTXContext->bCopySavePad == TRUE))
+ pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]);
+ else
+ pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]);
+
+ //
+ // Update TxInfo->USBDMApktLen ,
+ // the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding
+ //
+ pTxInfo = (PTXINFO_STRUC)(pWirelessPacket);
+
+ // Calculate the bulk-out padding
+ USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
+ padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
+ USBDMApktLen += padding;
+
+ pTxInfo->USBDMATxPktLen = USBDMApktLen;
+
+ //
+ // Update TXWI->MPDUtotalByteCount ,
+ // the length = 802.11 header + payload_of_all_batch_frames
+ pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE);
+ pTxWI->MPDUtotalByteCount = totalMPDUSize;
+
+ //
+ // Update the pHTTXContext->CurWritePosition
+ //
+ pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
+ if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT)
+ { // Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame.
+ pHTTXContext->CurWritePosition = 8;
+ pTxInfo->SwUseLastRound = 1;
+ }
+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+
+ //
+ // Zero the last padding.
+ //
+ pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]);
+ NdisZeroMemory(pWirelessPacket, padding + 8);
+
+ // Finally, set bCurWriting as FALSE
+ pHTTXContext->bCurWriting = FALSE;
+
+ }
+ else
+ { // It should not happened now unless we are going to shutdown.
+ DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
+ }
+
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+}
+
+
+VOID RtmpUSBDataLastTxIdx(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN USHORT TxIdx)
+{
+ // DO nothing for USB.
+}
+
+
+/*
+ When can do bulk-out:
+ 1. TxSwFreeIdx < TX_RING_SIZE;
+ It means has at least one Ring entity is ready for bulk-out, kick it out.
+ 2. If TxSwFreeIdx == TX_RING_SIZE
+ Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
+
+*/
+VOID RtmpUSBDataKickOut(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR QueIdx)
+{
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+ RTUSBKickBulkOut(pAd);
+
+}
+
+
+/*
+ Must be run in Interrupt context
+ This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
+ */
+int RtmpUSBMgmtKickOut(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pSrcBufVA,
+ IN UINT SrcBufLen)
+{
+ PTXINFO_STRUC pTxInfo;
+ ULONG BulkOutSize;
+ UCHAR padLen;
+ PUCHAR pDest;
+ ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
+ PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
+ unsigned long IrqFlags;
+
+
+ pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);
+
+ // Build our URB for USBD
+ BulkOutSize = SrcBufLen;
+ BulkOutSize = (BulkOutSize + 3) & (~3);
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+
+ BulkOutSize += 4; // Always add 4 extra bytes at every packet.
+
+ // If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.
+ if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
+ BulkOutSize += 4;
+
+ padLen = BulkOutSize - SrcBufLen;
+ ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
+
+ // Now memzero all extra padding bytes.
+ pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
+ skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
+ NdisZeroMemory(pDest, padLen);
+
+ RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+ pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
+ pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));
+
+ // Length in TxInfo should be 8 less than bulkout size.
+ pMLMEContext->BulkOutSize = BulkOutSize;
+ pMLMEContext->InUse = TRUE;
+ pMLMEContext->bWaitingBulkOut = TRUE;
+
+
+ //for debug
+ //hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));
+
+ //pAd->RalinkCounters.KickTxCount++;
+ //pAd->RalinkCounters.OneSecTxDoneCount++;
+
+ //if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
+ // needKickOut = TRUE;
+
+ // Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX
+ pAd->MgmtRing.TxSwFreeIdx--;
+ INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
+
+ RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+ //if (needKickOut)
+ RTUSBKickBulkOut(pAd);
+
+ return 0;
+}
+
+
+VOID RtmpUSBNullFrameKickOut(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN UCHAR *pNullFrame,
+ IN UINT32 frameLen)
+{
+ if (pAd->NullContext.InUse == FALSE)
+ {
+ PTX_CONTEXT pNullContext;
+ PTXINFO_STRUC pTxInfo;
+ PTXWI_STRUC pTxWI;
+ PUCHAR pWirelessPkt;
+
+ pNullContext = &(pAd->NullContext);
+
+ // Set the in use bit
+ pNullContext->InUse = TRUE;
+ pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];
+
+ RTMPZeroMemory(&pWirelessPkt[0], 100);
+ pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0];
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+ pTxInfo->QSEL = FIFO_EDCA;
+ pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE];
+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
+ 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+#endif // RT_BIG_ENDIAN //
+
+ RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)&pWirelessPkt[TXINFO_SIZE + TXWI_SIZE], DIR_WRITE, FALSE);
+#endif // RT_BIG_ENDIAN //
+ pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
+
+ // Fill out frame length information for global Bulk out arbitor
+ //pNullContext->BulkOutSize = TransferBufferLength;
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate]));
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
+
+ // Kick bulk out
+ RTUSBKickBulkOut(pAd);
+ }
+
+}
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+ ========================================================================
+
+ Routine Description:
+ Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
+
+ Arguments:
+ pRxD Pointer to the Rx descriptor
+
+ Return Value:
+ NDIS_STATUS_SUCCESS No err
+ NDIS_STATUS_FAILURE Error
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS RTMPCheckRxError(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHeader,
+ IN PRXWI_STRUC pRxWI,
+ IN PRT28XX_RXD_STRUC pRxINFO)
+{
+ PCIPHER_KEY pWpaKey;
+ INT dBm;
+
+ if (pAd->bPromiscuous == TRUE)
+ return(NDIS_STATUS_SUCCESS);
+ if(pRxINFO == NULL)
+ return(NDIS_STATUS_FAILURE);
+
+ // Phy errors & CRC errors
+ if (pRxINFO->Crc)
+ {
+ // Check RSSI for Noise Hist statistic collection.
+ dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
+ if (dBm <= -87)
+ pAd->StaCfg.RPIDensity[0] += 1;
+ else if (dBm <= -82)
+ pAd->StaCfg.RPIDensity[1] += 1;
+ else if (dBm <= -77)
+ pAd->StaCfg.RPIDensity[2] += 1;
+ else if (dBm <= -72)
+ pAd->StaCfg.RPIDensity[3] += 1;
+ else if (dBm <= -67)
+ pAd->StaCfg.RPIDensity[4] += 1;
+ else if (dBm <= -62)
+ pAd->StaCfg.RPIDensity[5] += 1;
+ else if (dBm <= -57)
+ pAd->StaCfg.RPIDensity[6] += 1;
+ else if (dBm > -57)
+ pAd->StaCfg.RPIDensity[7] += 1;
+
+ return(NDIS_STATUS_FAILURE);
+ }
+
+ // Add Rx size to channel load counter, we should ignore error counts
+ pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14);
+
+ // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
+ if (pHeader->FC.ToDs)
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ // Paul 04-03 for OFDM Rx length issue
+ if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE)
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ // Drop not U2M frames, cant's drop here because we will drop beacon in this case
+ // I am kind of doubting the U2M bit operation
+ // if (pRxD->U2M == 0)
+ // return(NDIS_STATUS_FAILURE);
+
+ // drop decyption fail frame
+ if (pRxINFO->Decrypted && pRxINFO->CipherErr)
+ {
+
+ //
+ // MIC Error
+ //
+ if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss)
+ {
+ pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
+ RTMPReportMicError(pAd, pWpaKey);
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
+ }
+
+ if (pRxINFO->Decrypted &&
+ (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) &&
+ (pHeader->Sequence == pAd->FragFrame.Sequence))
+ {
+ //
+ // Acceptable since the First FragFrame no CipherErr problem.
+ //
+ return(NDIS_STATUS_SUCCESS);
+ }
+
+ return(NDIS_STATUS_FAILURE);
+ }
+
+ return(NDIS_STATUS_SUCCESS);
+}
+
+VOID RT28xxUsbStaAsicForceWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bFromTx)
+{
+ AUTO_WAKEUP_STRUC AutoWakeupCfg;
+
+ AutoWakeupCfg.word = 0;
+ RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+ AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+}
+
+VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT TbttNumToNextWakeUp)
+{
+ AUTO_WAKEUP_STRUC AutoWakeupCfg;
+
+ // we have decided to SLEEP, so at least do it for a BEACON period.
+ if (TbttNumToNextWakeUp == 0)
+ TbttNumToNextWakeUp = 1;
+
+ AutoWakeupCfg.word = 0;
+ RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+ AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
+ AutoWakeupCfg.field.EnableAutoWakeup = 1;
+ AutoWakeupCfg.field.AutoLeadTime = 5;
+ RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+ AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); // send POWER-SAVE command to MCU. Timeout 40us.
+
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
+
+}
+#endif // CONFIG_STA_SUPPORT //
+
+VOID RT28xxUsbMlmeRadioOn(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n"));
+
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+ return;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+ RTMPusecDelay(10000);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ NICResetFromError(pAd);
+
+ // Enable Tx/Rx
+ RTMPEnableRxTx(pAd);
+
+#ifdef RT3070
+ if (IS_RT3071(pAd))
+ {
+ RT30xxReverseRFSleepModeSetup(pAd);
+ }
+#endif // RT3070 //
+
+ // Clear Radio off flag
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ RTUSBBulkReceive(pAd);
+#endif // CONFIG_STA_SUPPORT //
+
+ // Set LED
+ RTMPSetLED(pAd, LED_RADIO_ON);
+}
+
+VOID RT28xxUsbMlmeRadioOFF(
+ IN PRTMP_ADAPTER pAd)
+{
+ WPDMA_GLO_CFG_STRUC GloCfg;
+ UINT32 Value, i;
+
+ DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+ return;
+
+ // Set LED
+ RTMPSetLED(pAd, LED_RADIO_OFF);
+ // Set Radio off flag
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Link down first if any association exists
+ if (INFRA_ON(pAd) || ADHOC_ON(pAd))
+ LinkDown(pAd, FALSE);
+ RTMPusecDelay(10000);
+
+ //==========================================
+ // Clean up old bss table
+ BssTableInit(&pAd->ScanTab);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+ if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+ {
+ // Must using 40MHz.
+ AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
+ }
+ else
+ {
+ // Must using 20MHz.
+ AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
+ }
+
+ // Disable Tx/Rx DMA
+ RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
+ GloCfg.field.EnableTxDMA = 0;
+ GloCfg.field.EnableRxDMA = 0;
+ RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings
+
+ // Waiting for DMA idle
+ i = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+ if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
+ break;
+
+ RTMPusecDelay(1000);
+ }while (i++ < 100);
+
+ // Disable MAC Tx/Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= (0xfffffff3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // MAC_SYS_CTRL => value = 0x0 => 40mA
+ //RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0);
+
+ // PWR_PIN_CFG => value = 0x0 => 40mA
+ //RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0);
+
+ // TX_PIN_CFG => value = 0x0 => 20mA
+ //RTMP_IO_WRITE32(pAd, TX_PIN_CFG, 0);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
+#endif // CONFIG_STA_SUPPORT //
+}
+
diff --git a/drivers/staging/rt3070/common/cmm_info.c b/drivers/staging/rt3070/common/cmm_info.c
new file mode 100644
index 00000000000..54cb1a35f7b
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_info.c
@@ -0,0 +1,3395 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+*/
+
+#include "../rt_config.h"
+
+INT Show_SSID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_WirelessMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_TxBurst_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_TxPreamble_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_TxPower_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_Channel_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_BGProtection_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_RTSThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_FragThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+#ifdef DOT11_N_SUPPORT
+INT Show_HtBw_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtMcs_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtGi_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtOpMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtExtcha_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtMpduDensity_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtBaWinSize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtRdg_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtAmsdu_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtAutoBa_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+#endif // DOT11_N_SUPPORT //
+
+INT Show_CountryRegion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_CountryRegionABand_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_CountryCode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+#ifdef AGGREGATION_SUPPORT
+INT Show_PktAggregate_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+#endif // AGGREGATION_SUPPORT //
+
+#ifdef WMM_SUPPORT
+INT Show_WmmCapable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+#endif // WMM_SUPPORT //
+
+INT Show_IEEE80211H_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+#ifdef CONFIG_STA_SUPPORT
+INT Show_NetworkType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+#endif // CONFIG_STA_SUPPORT //
+
+INT Show_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_EncrypType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_DefaultKeyID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_Key1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_Key2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_Key3_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_Key4_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_WPAPSK_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+static struct {
+ CHAR *name;
+ INT (*show_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
+} *PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC, RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC[] = {
+ {"SSID", Show_SSID_Proc},
+ {"WirelessMode", Show_WirelessMode_Proc},
+ {"TxBurst", Show_TxBurst_Proc},
+ {"TxPreamble", Show_TxPreamble_Proc},
+ {"TxPower", Show_TxPower_Proc},
+ {"Channel", Show_Channel_Proc},
+ {"BGProtection", Show_BGProtection_Proc},
+ {"RTSThreshold", Show_RTSThreshold_Proc},
+ {"FragThreshold", Show_FragThreshold_Proc},
+#ifdef DOT11_N_SUPPORT
+ {"HtBw", Show_HtBw_Proc},
+ {"HtMcs", Show_HtMcs_Proc},
+ {"HtGi", Show_HtGi_Proc},
+ {"HtOpMode", Show_HtOpMode_Proc},
+ {"HtExtcha", Show_HtExtcha_Proc},
+ {"HtMpduDensity", Show_HtMpduDensity_Proc},
+ {"HtBaWinSize", Show_HtBaWinSize_Proc},
+ {"HtRdg", Show_HtRdg_Proc},
+ {"HtAmsdu", Show_HtAmsdu_Proc},
+ {"HtAutoBa", Show_HtAutoBa_Proc},
+#endif // DOT11_N_SUPPORT //
+ {"CountryRegion", Show_CountryRegion_Proc},
+ {"CountryRegionABand", Show_CountryRegionABand_Proc},
+ {"CountryCode", Show_CountryCode_Proc},
+#ifdef AGGREGATION_SUPPORT
+ {"PktAggregate", Show_PktAggregate_Proc},
+#endif
+
+#ifdef WMM_SUPPORT
+ {"WmmCapable", Show_WmmCapable_Proc},
+#endif
+ {"IEEE80211H", Show_IEEE80211H_Proc},
+#ifdef CONFIG_STA_SUPPORT
+ {"NetworkType", Show_NetworkType_Proc},
+#endif // CONFIG_STA_SUPPORT //
+ {"AuthMode", Show_AuthMode_Proc},
+ {"EncrypType", Show_EncrypType_Proc},
+ {"DefaultKeyID", Show_DefaultKeyID_Proc},
+ {"Key1", Show_Key1_Proc},
+ {"Key2", Show_Key2_Proc},
+ {"Key3", Show_Key3_Proc},
+ {"Key4", Show_Key4_Proc},
+ {"WPAPSK", Show_WPAPSK_Proc},
+ {NULL, NULL}
+};
+
+/*
+ ==========================================================================
+ Description:
+ Get Driver version.
+
+ Return:
+ ==========================================================================
+*/
+INT Set_DriverVersion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", STA_DRIVER_VERSION));
+#endif // CONFIG_STA_SUPPORT //
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Country Region.
+ This command will not work, if the field of CountryRegion in eeprom is programmed.
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_CountryRegion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG region;
+
+ region = simple_strtol(arg, 0, 10);
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ return -EOPNOTSUPP;
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+ // Country can be set only when EEPROM not programmed
+ if (pAd->CommonCfg.CountryRegion & 0x80)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameter of CountryRegion in eeprom is programmed \n"));
+ return FALSE;
+ }
+
+ if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND))
+ {
+ pAd->CommonCfg.CountryRegion = (UCHAR) region;
+ }
+ else if (region == REGION_31_BG_BAND)
+ {
+ pAd->CommonCfg.CountryRegion = (UCHAR) region;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameters out of range\n"));
+ return FALSE;
+ }
+
+ // if set country region, driver needs to be reset
+ BuildChannelList(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegion_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegion));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Country Region for A band.
+ This command will not work, if the field of CountryRegion in eeprom is programmed.
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_CountryRegionABand_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG region;
+
+ region = simple_strtol(arg, 0, 10);
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ return -EOPNOTSUPP;
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+ // Country can be set only when EEPROM not programmed
+ if (pAd->CommonCfg.CountryRegionForABand & 0x80)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameter of CountryRegion in eeprom is programmed \n"));
+ return FALSE;
+ }
+
+ if((region >= 0) && (region <= REGION_MAXIMUM_A_BAND))
+ {
+ pAd->CommonCfg.CountryRegionForABand = (UCHAR) region;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameters out of range\n"));
+ return FALSE;
+ }
+
+ // if set country region, driver needs to be reset
+ BuildChannelList(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegionABand_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegionForABand));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Wireless Mode
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_WirelessMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG WirelessMode;
+ INT success = TRUE;
+
+ WirelessMode = simple_strtol(arg, 0, 10);
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ INT MaxPhyMode = PHY_11G;
+
+#ifdef DOT11_N_SUPPORT
+ MaxPhyMode = PHY_11N_5G;
+#endif // DOT11_N_SUPPORT //
+
+ if (WirelessMode <= MaxPhyMode)
+ {
+ RTMPSetPhyMode(pAd, WirelessMode);
+#ifdef DOT11_N_SUPPORT
+ if (WirelessMode >= PHY_11ABGN_MIXED)
+ {
+ pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
+ pAd->CommonCfg.REGBACapability.field.AutoBA = TRUE;
+ }
+ else
+ {
+ pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
+ pAd->CommonCfg.REGBACapability.field.AutoBA = FALSE;
+ }
+#endif // DOT11_N_SUPPORT //
+ // Set AdhocMode rates
+ if (pAd->StaCfg.BssType == BSS_ADHOC)
+ {
+ MlmeUpdateTxRates(pAd, FALSE, 0);
+ MakeIbssBeacon(pAd); // re-build BEACON frame
+ AsicEnableIbssSync(pAd); // copy to on-chip memory
+ }
+ }
+ else
+ {
+ success = FALSE;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // it is needed to set SSID to take effect
+ if (success == TRUE)
+ {
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%ld)\n", WirelessMode));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_WirelessMode_Proc::parameters out of range\n"));
+ }
+
+ return success;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Channel
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Channel_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ INT success = TRUE;
+ UCHAR Channel;
+
+ Channel = (UCHAR) simple_strtol(arg, 0, 10);
+
+ // check if this channel is valid
+ if (ChannelSanity(pAd, Channel) == TRUE)
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pAd->CommonCfg.Channel = Channel;
+
+ if (MONITOR_ON(pAd))
+ {
+#ifdef DOT11_N_SUPPORT
+ N_ChannelCheck(pAd);
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
+ pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+ {
+ N_SetCenCh(pAd);
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+ DBGPRINT(RT_DEBUG_TRACE, ("BW_40, control_channel(%d), CentralChannel(%d) \n",
+ pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAd->CommonCfg.Channel));
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+ success = TRUE;
+ }
+ else
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ success = FALSE;
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+
+ if (success == TRUE)
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Channel_Proc::(Channel=%d)\n", pAd->CommonCfg.Channel));
+
+ return success;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Short Slot Time Enable or Disable
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ShortSlot_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG ShortSlot;
+
+ ShortSlot = simple_strtol(arg, 0, 10);
+
+ if (ShortSlot == 1)
+ pAd->CommonCfg.bUseShortSlotTime = TRUE;
+ else if (ShortSlot == 0)
+ pAd->CommonCfg.bUseShortSlotTime = FALSE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ShortSlot_Proc::(ShortSlot=%d)\n", pAd->CommonCfg.bUseShortSlotTime));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Tx power
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_TxPower_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG TxPower;
+ INT success = FALSE;
+
+ TxPower = (ULONG) simple_strtol(arg, 0, 10);
+ if (TxPower <= 100)
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pAd->CommonCfg.TxPowerDefault = TxPower;
+ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ success = TRUE;
+ }
+ else
+ success = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPower_Proc::(TxPowerPercentage=%ld)\n", pAd->CommonCfg.TxPowerPercentage));
+
+ return success;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set 11B/11G Protection
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_BGProtection_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ switch (simple_strtol(arg, 0, 10))
+ {
+ case 0: //AUTO
+ pAd->CommonCfg.UseBGProtection = 0;
+ break;
+ case 1: //Always On
+ pAd->CommonCfg.UseBGProtection = 1;
+ break;
+ case 2: //Always OFF
+ pAd->CommonCfg.UseBGProtection = 2;
+ break;
+ default: //Invalid argument
+ return FALSE;
+ }
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_BGProtection_Proc::(BGProtection=%ld)\n", pAd->CommonCfg.UseBGProtection));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set TxPreamble
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_TxPreamble_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ RT_802_11_PREAMBLE Preamble;
+
+ Preamble = simple_strtol(arg, 0, 10);
+
+
+ switch (Preamble)
+ {
+ case Rt802_11PreambleShort:
+ pAd->CommonCfg.TxPreamble = Preamble;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
+#endif // CONFIG_STA_SUPPORT //
+ break;
+ case Rt802_11PreambleLong:
+#ifdef CONFIG_STA_SUPPORT
+ case Rt802_11PreambleAuto:
+ // if user wants AUTO, initialize to LONG here, then change according to AP's
+ // capability upon association.
+#endif // CONFIG_STA_SUPPORT //
+ pAd->CommonCfg.TxPreamble = Preamble;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
+#endif // CONFIG_STA_SUPPORT //
+ break;
+ default: //Invalid argument
+ return FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPreamble_Proc::(TxPreamble=%ld)\n", pAd->CommonCfg.TxPreamble));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set RTS Threshold
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_RTSThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ NDIS_802_11_RTS_THRESHOLD RtsThresh;
+
+ RtsThresh = simple_strtol(arg, 0, 10);
+
+ if((RtsThresh > 0) && (RtsThresh <= MAX_RTS_THRESHOLD))
+ pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
+#ifdef CONFIG_STA_SUPPORT
+ else if (RtsThresh == 0)
+ pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
+#endif // CONFIG_STA_SUPPORT //
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_RTSThreshold_Proc::(RTSThreshold=%d)\n", pAd->CommonCfg.RtsThreshold));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Fragment Threshold
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_FragThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
+
+ FragThresh = simple_strtol(arg, 0, 10);
+
+ if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
+ {
+ //Illegal FragThresh so we set it to default
+ pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
+ }
+ else if (FragThresh % 2 == 1)
+ {
+ // The length of each fragment shall always be an even number of octets, except for the last fragment
+ // of an MSDU or MMPDU, which may be either an even or an odd number of octets.
+ pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
+ }
+ else
+ {
+ pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pAd->CommonCfg.FragmentThreshold == MAX_FRAG_THRESHOLD)
+ pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
+ else
+ pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_FragThreshold_Proc::(FragThreshold=%d)\n", pAd->CommonCfg.FragmentThreshold));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set TxBurst
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_TxBurst_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG TxBurst;
+
+ TxBurst = simple_strtol(arg, 0, 10);
+ if (TxBurst == 1)
+ pAd->CommonCfg.bEnableTxBurst = TRUE;
+ else if (TxBurst == 0)
+ pAd->CommonCfg.bEnableTxBurst = FALSE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_TxBurst_Proc::(TxBurst=%d)\n", pAd->CommonCfg.bEnableTxBurst));
+
+ return TRUE;
+}
+
+#ifdef AGGREGATION_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Set TxBurst
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_PktAggregate_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG aggre;
+
+ aggre = simple_strtol(arg, 0, 10);
+
+ if (aggre == 1)
+ pAd->CommonCfg.bAggregationCapable = TRUE;
+ else if (aggre == 0)
+ pAd->CommonCfg.bAggregationCapable = FALSE;
+ else
+ return FALSE; //Invalid argument
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_PktAggregate_Proc::(AGGRE=%d)\n", pAd->CommonCfg.bAggregationCapable));
+
+ return TRUE;
+}
+#endif
+
+/*
+ ==========================================================================
+ Description:
+ Set IEEE80211H.
+ This parameter is 1 when needs radar detection, otherwise 0
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_IEEE80211H_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG ieee80211h;
+
+ ieee80211h = simple_strtol(arg, 0, 10);
+
+ if (ieee80211h == 1)
+ pAd->CommonCfg.bIEEE80211H = TRUE;
+ else if (ieee80211h == 0)
+ pAd->CommonCfg.bIEEE80211H = FALSE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_IEEE80211H_Proc::(IEEE80211H=%d)\n", pAd->CommonCfg.bIEEE80211H));
+
+ return TRUE;
+}
+
+
+#ifdef DBG
+/*
+ ==========================================================================
+ Description:
+ For Debug information
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Debug_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Debug_Proc *******************\n"));
+
+ if(simple_strtol(arg, 0, 10) <= RT_DEBUG_LOUD)
+ RTDebugLevel = simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Debug_Proc(RTDebugLevel = %ld)\n", RTDebugLevel));
+
+ return TRUE;
+}
+#endif
+
+INT Show_DescInfo_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Reset statistics counter
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ arg
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ResetStatCounter_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ //UCHAR i;
+ //MAC_TABLE_ENTRY *pEntry;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==>Set_ResetStatCounter_Proc\n"));
+
+ // add the most up-to-date h/w raw counters into software counters
+ NICUpdateRawCounters(pAd);
+
+ NdisZeroMemory(&pAd->WlanCounters, sizeof(COUNTER_802_11));
+ NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3));
+ NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK));
+
+ return TRUE;
+}
+
+BOOLEAN RTMPCheckStrPrintAble(
+ IN CHAR *pInPutStr,
+ IN UCHAR strLen)
+{
+ UCHAR i=0;
+
+ for (i=0; i<strLen; i++)
+ {
+ if ((pInPutStr[i] < 0x21) ||
+ (pInPutStr[i] > 0x7E))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Remove WPA Key process
+
+ Arguments:
+ pAd Pointer to our adapter
+ pBuf Pointer to the where the key stored
+
+ Return Value:
+ NDIS_SUCCESS Add key successfully
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPSetDesiredRates(
+ IN PRTMP_ADAPTER pAdapter,
+ IN LONG Rates)
+{
+ NDIS_802_11_RATES aryRates;
+
+ memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES));
+ switch (pAdapter->CommonCfg.PhyMode)
+ {
+ case PHY_11A: // A only
+ switch (Rates)
+ {
+ case 6000000: //6M
+ aryRates[0] = 0x0c; // 6M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
+ break;
+ case 9000000: //9M
+ aryRates[0] = 0x12; // 9M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
+ break;
+ case 12000000: //12M
+ aryRates[0] = 0x18; // 12M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
+ break;
+ case 18000000: //18M
+ aryRates[0] = 0x24; // 18M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
+ break;
+ case 24000000: //24M
+ aryRates[0] = 0x30; // 24M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
+ break;
+ case 36000000: //36M
+ aryRates[0] = 0x48; // 36M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
+ break;
+ case 48000000: //48M
+ aryRates[0] = 0x60; // 48M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
+ break;
+ case 54000000: //54M
+ aryRates[0] = 0x6c; // 54M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
+ break;
+ case -1: //Auto
+ default:
+ aryRates[0] = 0x6c; // 54Mbps
+ aryRates[1] = 0x60; // 48Mbps
+ aryRates[2] = 0x48; // 36Mbps
+ aryRates[3] = 0x30; // 24Mbps
+ aryRates[4] = 0x24; // 18M
+ aryRates[5] = 0x18; // 12M
+ aryRates[6] = 0x12; // 9M
+ aryRates[7] = 0x0c; // 6M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ break;
+ }
+ break;
+ case PHY_11BG_MIXED: // B/G Mixed
+ case PHY_11B: // B only
+ case PHY_11ABG_MIXED: // A/B/G Mixed
+ default:
+ switch (Rates)
+ {
+ case 1000000: //1M
+ aryRates[0] = 0x02;
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
+ break;
+ case 2000000: //2M
+ aryRates[0] = 0x04;
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
+ break;
+ case 5000000: //5.5M
+ aryRates[0] = 0x0b; // 5.5M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
+ break;
+ case 11000000: //11M
+ aryRates[0] = 0x16; // 11M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
+ break;
+ case 6000000: //6M
+ aryRates[0] = 0x0c; // 6M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
+ break;
+ case 9000000: //9M
+ aryRates[0] = 0x12; // 9M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
+ break;
+ case 12000000: //12M
+ aryRates[0] = 0x18; // 12M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
+ break;
+ case 18000000: //18M
+ aryRates[0] = 0x24; // 18M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
+ break;
+ case 24000000: //24M
+ aryRates[0] = 0x30; // 24M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
+ break;
+ case 36000000: //36M
+ aryRates[0] = 0x48; // 36M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
+ break;
+ case 48000000: //48M
+ aryRates[0] = 0x60; // 48M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
+ break;
+ case 54000000: //54M
+ aryRates[0] = 0x6c; // 54M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
+ break;
+ case -1: //Auto
+ default:
+ if (pAdapter->CommonCfg.PhyMode == PHY_11B)
+ { //B Only
+ aryRates[0] = 0x16; // 11Mbps
+ aryRates[1] = 0x0b; // 5.5Mbps
+ aryRates[2] = 0x04; // 2Mbps
+ aryRates[3] = 0x02; // 1Mbps
+ }
+ else
+ { //(B/G) Mixed or (A/B/G) Mixed
+ aryRates[0] = 0x6c; // 54Mbps
+ aryRates[1] = 0x60; // 48Mbps
+ aryRates[2] = 0x48; // 36Mbps
+ aryRates[3] = 0x30; // 24Mbps
+ aryRates[4] = 0x16; // 11Mbps
+ aryRates[5] = 0x0b; // 5.5Mbps
+ aryRates[6] = 0x04; // 2Mbps
+ aryRates[7] = 0x02; // 1Mbps
+ }
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ break;
+ }
+ break;
+ }
+
+ NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
+ NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
+ DBGPRINT(RT_DEBUG_TRACE, (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
+ pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
+ pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
+ pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
+ pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
+ // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
+ MlmeUpdateTxRates(pAdapter, FALSE, 0);
+}
+
+NDIS_STATUS RTMPWPARemoveKeyProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PVOID pBuf)
+{
+ PNDIS_802_11_REMOVE_KEY pKey;
+ ULONG KeyIdx;
+ NDIS_STATUS Status = NDIS_STATUS_FAILURE;
+ BOOLEAN bTxKey; // Set the key as transmit key
+ BOOLEAN bPairwise; // Indicate the key is pairwise key
+ BOOLEAN bKeyRSC; // indicate the receive SC set by KeyRSC value.
+ // Otherwise, it will set by the NIC.
+ BOOLEAN bAuthenticator; // indicate key is set by authenticator.
+ INT i;
+
+ DBGPRINT(RT_DEBUG_TRACE,("---> RTMPWPARemoveKeyProc\n"));
+
+ pKey = (PNDIS_802_11_REMOVE_KEY) pBuf;
+ KeyIdx = pKey->KeyIndex & 0xff;
+ // Bit 31 of Add-key, Tx Key
+ bTxKey = (pKey->KeyIndex & 0x80000000) ? TRUE : FALSE;
+ // Bit 30 of Add-key PairwiseKey
+ bPairwise = (pKey->KeyIndex & 0x40000000) ? TRUE : FALSE;
+ // Bit 29 of Add-key KeyRSC
+ bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
+ // Bit 28 of Add-key Authenticator
+ bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
+
+ // 1. If bTx is TRUE, return failure information
+ if (bTxKey == TRUE)
+ return(NDIS_STATUS_INVALID_DATA);
+
+ // 2. Check Pairwise Key
+ if (bPairwise)
+ {
+ // a. If BSSID is broadcast, remove all pairwise keys.
+ // b. If not broadcast, remove the pairwise specified by BSSID
+ for (i = 0; i < SHARE_KEY_NUM; i++)
+ {
+ if (MAC_ADDR_EQUAL(pAd->SharedKey[BSS0][i].BssId, pKey->BSSID))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%d)\n", i));
+ pAd->SharedKey[BSS0][i].KeyLen = 0;
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
+ AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)i);
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+ }
+ }
+ }
+ // 3. Group Key
+ else
+ {
+ // a. If BSSID is broadcast, remove all group keys indexed
+ // b. If BSSID matched, delete the group key indexed.
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%ld)\n", KeyIdx));
+ pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0;
+ pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
+ AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx);
+ Status = NDIS_STATUS_SUCCESS;
+ }
+
+ return (Status);
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+ ========================================================================
+
+ Routine Description:
+ Remove All WPA Keys
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPWPARemoveAllKeys(
+ IN PRTMP_ADAPTER pAd)
+{
+
+ UCHAR i;
+
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
+
+ // For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after
+ // Link up. And it will be replaced if user changed it.
+ if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
+ return;
+
+ // For WPA-None, there is no need to remove it, since WinXP won't set it again after
+ // Link up. And it will be replaced if user changed it.
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ return;
+
+ // set BSSID wcid entry of the Pair-wise Key table as no-security mode
+ AsicRemovePairwiseKeyEntry(pAd, BSS0, BSSID_WCID);
+
+ // set all shared key mode as no-security.
+ for (i = 0; i < SHARE_KEY_NUM; i++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("remove %s key #%d\n", CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i));
+ NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(CIPHER_KEY));
+
+ AsicRemoveSharedKeyEntry(pAd, BSS0, i);
+ }
+
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+ ========================================================================
+ Routine Description:
+ Change NIC PHY mode. Re-association may be necessary. possible settings
+ include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED
+
+ Arguments:
+ pAd - Pointer to our adapter
+ phymode -
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ========================================================================
+*/
+VOID RTMPSetPhyMode(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG phymode)
+{
+ INT i;
+ // the selected phymode must be supported by the RF IC encoded in E2PROM
+
+ pAd->CommonCfg.PhyMode = (UCHAR)phymode;
+
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
+#ifdef EXT_BUILD_CHANNEL_LIST
+ BuildChannelListEx(pAd);
+#else
+ BuildChannelList(pAd);
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+ // sanity check user setting
+ for (i = 0; i < pAd->ChannelListNum; i++)
+ {
+ if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
+ break;
+ }
+
+ if (i == pAd->ChannelListNum)
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pAd->CommonCfg.Channel = FirstChannel(pAd);
+#endif // CONFIG_STA_SUPPORT //
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n", pAd->CommonCfg.Channel));
+ }
+
+ NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
+ NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
+ NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
+ switch (phymode) {
+ case PHY_11B:
+ pAd->CommonCfg.SupRate[0] = 0x82; // 1 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[1] = 0x84; // 2 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[2] = 0x8B; // 5.5 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[3] = 0x96; // 11 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRateLen = 4;
+ pAd->CommonCfg.ExtRateLen = 0;
+ pAd->CommonCfg.DesireRate[0] = 2; // 1 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[1] = 4; // 2 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[2] = 11; // 5.5 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[3] = 22; // 11 mbps, in units of 0.5 Mbps
+ //pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use
+ break;
+
+ case PHY_11G:
+ case PHY_11BG_MIXED:
+ case PHY_11ABG_MIXED:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11N_2_4G:
+ case PHY_11ABGN_MIXED:
+ case PHY_11BGN_MIXED:
+ case PHY_11GN_MIXED:
+#endif // DOT11_N_SUPPORT //
+ pAd->CommonCfg.SupRate[0] = 0x82; // 1 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[1] = 0x84; // 2 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[2] = 0x8B; // 5.5 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[3] = 0x96; // 11 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[4] = 0x12; // 9 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[5] = 0x24; // 18 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[6] = 0x48; // 36 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRateLen = 8;
+ pAd->CommonCfg.ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.ExtRate[1] = 0x18; // 12 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.ExtRate[2] = 0x30; // 24 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.ExtRate[3] = 0x60; // 48 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.ExtRateLen = 4;
+ pAd->CommonCfg.DesireRate[0] = 2; // 1 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[1] = 4; // 2 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[2] = 11; // 5.5 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[3] = 22; // 11 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[4] = 12; // 6 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[5] = 18; // 9 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[6] = 24; // 12 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[7] = 36; // 18 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[8] = 48; // 24 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[9] = 72; // 36 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[10] = 96; // 48 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[11] = 108; // 54 mbps, in units of 0.5 Mbps
+ break;
+
+ case PHY_11A:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11AN_MIXED:
+ case PHY_11AGN_MIXED:
+ case PHY_11N_5G:
+#endif // DOT11_N_SUPPORT //
+ pAd->CommonCfg.SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRateLen = 8;
+ pAd->CommonCfg.ExtRateLen = 0;
+ pAd->CommonCfg.DesireRate[0] = 12; // 6 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[1] = 18; // 9 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[2] = 24; // 12 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[3] = 36; // 18 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[4] = 48; // 24 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[5] = 72; // 36 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[6] = 96; // 48 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[7] = 108; // 54 mbps, in units of 0.5 Mbps
+ //pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use
+ break;
+
+ default:
+ break;
+ }
+
+
+ pAd->CommonCfg.BandState = UNKNOWN_BAND;
+}
+
+
+#ifdef DOT11_N_SUPPORT
+/*
+ ========================================================================
+ Routine Description:
+ Caller ensures we has 802.11n support.
+ Calls at setting HT from AP/STASetinformation
+
+ Arguments:
+ pAd - Pointer to our adapter
+ phymode -
+
+ ========================================================================
+*/
+VOID RTMPSetHT(
+ IN PRTMP_ADAPTER pAd,
+ IN OID_SET_HT_PHYMODE *pHTPhyMode)
+{
+ //ULONG *pmcs;
+ UINT32 Value = 0;
+ UCHAR BBPValue = 0;
+ UCHAR BBP3Value = 0;
+ UCHAR RxStream = pAd->CommonCfg.RxStream;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n",
+ pHTPhyMode->HtMode, pHTPhyMode->ExtOffset,
+ pHTPhyMode->MCS, pHTPhyMode->BW,
+ pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
+
+ // Don't zero supportedHyPhy structure.
+ RTMPZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
+ RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
+ RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset));
+ RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy, sizeof(pAd->CommonCfg.DesiredHtPhy));
+
+ if (pAd->CommonCfg.bRdg)
+ {
+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1;
+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1;
+ }
+ else
+ {
+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0;
+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0;
+ }
+
+ pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3;
+ pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit));
+
+ // Mimo power save, A-MSDU size,
+ pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
+ pAd->CommonCfg.DesiredHtPhy.AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize;
+ pAd->CommonCfg.DesiredHtPhy.MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode;
+ pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+
+ pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
+ pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
+ pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
+ pAd->CommonCfg.DesiredHtPhy.AmsduSize,
+ pAd->CommonCfg.DesiredHtPhy.MimoPs,
+ pAd->CommonCfg.DesiredHtPhy.MpduDensity,
+ pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor));
+
+ if(pHTPhyMode->HtMode == HTMODE_GF)
+ {
+ pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1;
+ pAd->CommonCfg.DesiredHtPhy.GF = 1;
+ }
+ else
+ pAd->CommonCfg.DesiredHtPhy.GF = 0;
+
+ // Decide Rx MCSSet
+ switch (RxStream)
+ {
+ case 1:
+ pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
+ pAd->CommonCfg.HtCapability.MCSSet[1] = 0x00;
+ break;
+
+ case 2:
+ pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
+ pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
+ break;
+
+ case 3: // 3*3
+ pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
+ pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
+ pAd->CommonCfg.HtCapability.MCSSet[2] = 0xff;
+ break;
+ }
+
+ if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40) )
+ {
+ pHTPhyMode->BW = BW_20;
+ pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1;
+ }
+
+ if(pHTPhyMode->BW == BW_40)
+ {
+ pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1; // MCS 32
+ pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1;
+ if (pAd->CommonCfg.Channel <= 14)
+ pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1;
+
+ pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = (pHTPhyMode->ExtOffset == EXTCHA_BELOW)? (EXTCHA_BELOW): EXTCHA_ABOVE;
+ // Set Regsiter for extension channel position.
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value);
+ if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW))
+ {
+ Value |= 0x1;
+ BBP3Value |= (0x20);
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+ }
+ else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE))
+ {
+ Value &= 0xfe;
+ BBP3Value &= (~0x20);
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+ }
+
+ // Turn on BBP 40MHz mode now only as AP .
+ // Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection.
+ if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd)
+ )
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= (~0x18);
+ BBPValue |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value);
+ pAd->CommonCfg.BBPCurrentBW = BW_40;
+ }
+ }
+ else
+ {
+ pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0;
+ pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE;
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ // Turn on BBP 20MHz mode by request here.
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ pAd->CommonCfg.BBPCurrentBW = BW_20;
+ }
+ }
+
+ if(pHTPhyMode->STBC == STBC_USE)
+ {
+ pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1;
+ pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1;
+ pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1;
+ pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1;
+ }
+ else
+ {
+ pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
+ pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
+ }
+
+ if(pHTPhyMode->SHORTGI == GI_400)
+ {
+ pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1;
+ pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1;
+ pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1;
+ pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1;
+ }
+ else
+ {
+ pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0;
+ pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0;
+ pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0;
+ pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0;
+ }
+
+ // We support link adaptation for unsolicit MCS feedback, set to 2.
+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE; //MCSFBK_UNSOLICIT;
+ pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel;
+ // 1, the extension channel above the control channel.
+
+ // EDCA parameters used for AP's own transmission
+ if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
+ {
+ pAd->CommonCfg.APEdcaParm.bValid = TRUE;
+ pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
+ pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
+ pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
+ pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
+
+ pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
+ pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
+ pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
+ pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
+
+ pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6;
+ pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10;
+ pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
+ pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
+
+ pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
+ pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
+ pAd->CommonCfg.APEdcaParm.Txop[2] = 94;
+ pAd->CommonCfg.APEdcaParm.Txop[3] = 47;
+ }
+ AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ RTMPSetIndividualHT(pAd, 0);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Caller ensures we has 802.11n support.
+ Calls at setting HT from AP/STASetinformation
+
+ Arguments:
+ pAd - Pointer to our adapter
+ phymode -
+
+ ========================================================================
+*/
+VOID RTMPSetIndividualHT(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx)
+{
+ PRT_HT_PHY_INFO pDesired_ht_phy = NULL;
+ UCHAR TxStream = pAd->CommonCfg.TxStream;
+ UCHAR DesiredMcs = MCS_AUTO;
+
+ do
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo;
+ DesiredMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
+ //pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE;
+ break;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ } while (FALSE);
+
+ if (pDesired_ht_phy == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
+ return;
+ }
+ RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_HT_PHY_INFO));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs));
+ // Check the validity of MCS
+ if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15)))
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs));
+ DesiredMcs = MCS_7;
+ }
+
+ if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32))
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n"));
+ DesiredMcs = MCS_0;
+ }
+
+ pDesired_ht_phy->bHtEnable = TRUE;
+
+ // Decide desired Tx MCS
+ switch (TxStream)
+ {
+ case 1:
+ if (DesiredMcs == MCS_AUTO)
+ {
+ pDesired_ht_phy->MCSSet[0]= 0xff;
+ pDesired_ht_phy->MCSSet[1]= 0x00;
+ }
+ else if (DesiredMcs <= MCS_7)
+ {
+ pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs;
+ pDesired_ht_phy->MCSSet[1]= 0x00;
+ }
+ break;
+
+ case 2:
+ if (DesiredMcs == MCS_AUTO)
+ {
+ pDesired_ht_phy->MCSSet[0]= 0xff;
+ pDesired_ht_phy->MCSSet[1]= 0xff;
+ }
+ else if (DesiredMcs <= MCS_15)
+ {
+ ULONG mode;
+
+ mode = DesiredMcs / 8;
+ if (mode < 2)
+ pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
+ }
+ break;
+
+ case 3: // 3*3
+ if (DesiredMcs == MCS_AUTO)
+ {
+ /* MCS0 ~ MCS23, 3 bytes */
+ pDesired_ht_phy->MCSSet[0]= 0xff;
+ pDesired_ht_phy->MCSSet[1]= 0xff;
+ pDesired_ht_phy->MCSSet[2]= 0xff;
+ }
+ else if (DesiredMcs <= MCS_23)
+ {
+ ULONG mode;
+
+ mode = DesiredMcs / 8;
+ if (mode < 3)
+ pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
+ }
+ break;
+ }
+
+ if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40)
+ {
+ if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32)
+ pDesired_ht_phy->MCSSet[4] = 0x1;
+ }
+
+ // update HT Rate setting
+ if (pAd->OpMode == OPMODE_STA)
+ MlmeUpdateHtTxRates(pAd, BSS0);
+ else
+ MlmeUpdateHtTxRates(pAd, apidx);
+}
+
+
+/*
+ ========================================================================
+ Routine Description:
+ Update HT IE from our capability.
+
+ Arguments:
+ Send all HT IE in beacon/probe rsp/assoc rsp/action frame.
+
+
+ ========================================================================
+*/
+VOID RTMPUpdateHTIE(
+ IN RT_HT_CAPABILITY *pRtHt,
+ IN UCHAR *pMcsSet,
+ OUT HT_CAPABILITY_IE *pHtCapability,
+ OUT ADD_HT_INFO_IE *pAddHtInfo)
+{
+ RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE));
+ RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE));
+
+ pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth;
+ pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs;
+ pHtCapability->HtCapInfo.GF = pRtHt->GF;
+ pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20;
+ pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40;
+ pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC;
+ pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC;
+ pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize;
+ pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor;
+ pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity;
+
+ pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset ;
+ pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth;
+ pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode;
+ pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent;
+ RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet*/pMcsSet, 4); // rt2860 only support MCS max=32, no need to copy all 16 uchar.
+
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPUpdateHTIE <== \n"));
+}
+#endif // DOT11_N_SUPPORT //
+
+/*
+ ========================================================================
+ Description:
+ Add Client security information into ASIC WCID table and IVEIV table.
+ Return:
+ ========================================================================
+*/
+VOID RTMPAddWcidAttributeEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIdx,
+ IN UCHAR KeyIdx,
+ IN UCHAR CipherAlg,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ UINT32 WCIDAttri = 0;
+ USHORT offset;
+ UCHAR IVEIV = 0;
+ USHORT Wcid = 0;
+
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (BssIdx > BSS0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n", BssIdx));
+ return;
+ }
+
+ // 1. In ADHOC mode, the AID is wcid number. And NO mesh link exists.
+ // 2. In Infra mode, the AID:1 MUST be wcid of infra STA.
+ // the AID:2~ assign to mesh link entry.
+ if (pEntry && ADHOC_ON(pAd))
+ Wcid = pEntry->Aid;
+ else if (pEntry && INFRA_ON(pAd))
+ {
+#ifdef QOS_DLS_SUPPORT
+ if (pEntry->ValidAsDls == TRUE)
+ Wcid = pEntry->Aid;
+ else
+#endif // QOS_DLS_SUPPORT //
+ Wcid = BSSID_WCID;
+ }
+ else
+ Wcid = MCAST_WCID;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ // Update WCID attribute table
+ offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pEntry && pEntry->ValidAsMesh)
+ WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
+#ifdef QOS_DLS_SUPPORT
+ else if ((pEntry) && (pEntry->ValidAsDls) &&
+ ((CipherAlg == CIPHER_TKIP) ||
+ (CipherAlg == CIPHER_TKIP_NO_MIC) ||
+ (CipherAlg == CIPHER_AES) ||
+ (CipherAlg == CIPHER_NONE)))
+ WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
+#endif // QOS_DLS_SUPPORT //
+ else
+ WCIDAttri = (CipherAlg<<1) | SHAREDKEYTABLE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
+
+
+ // Update IV/EIV table
+ offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
+
+ // WPA mode
+ if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) || (CipherAlg == CIPHER_AES))
+ {
+ // Eiv bit on. keyid always is 0 for pairwise key
+ IVEIV = (KeyIdx <<6) | 0x20;
+ }
+ else
+ {
+ // WEP KeyIdx is default tx key.
+ IVEIV = (KeyIdx << 6);
+ }
+
+ // For key index and ext IV bit, so only need to update the position(offset+3).
+#ifdef RT2870
+ RTUSBMultiWrite_OneByte(pAd, offset+3, &IVEIV);
+#endif // RT2870 //
+
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
+ DBGPRINT(RT_DEBUG_TRACE,(" WCIDAttri = 0x%x \n", WCIDAttri));
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ Parse encryption type
+Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+CHAR *GetEncryptType(CHAR enc)
+{
+ if(enc == Ndis802_11WEPDisabled)
+ return "NONE";
+ if(enc == Ndis802_11WEPEnabled)
+ return "WEP";
+ if(enc == Ndis802_11Encryption2Enabled)
+ return "TKIP";
+ if(enc == Ndis802_11Encryption3Enabled)
+ return "AES";
+ if(enc == Ndis802_11Encryption4Enabled)
+ return "TKIPAES";
+ else
+ return "UNKNOW";
+}
+
+CHAR *GetAuthMode(CHAR auth)
+{
+ if(auth == Ndis802_11AuthModeOpen)
+ return "OPEN";
+ if(auth == Ndis802_11AuthModeShared)
+ return "SHARED";
+ if(auth == Ndis802_11AuthModeAutoSwitch)
+ return "AUTOWEP";
+ if(auth == Ndis802_11AuthModeWPA)
+ return "WPA";
+ if(auth == Ndis802_11AuthModeWPAPSK)
+ return "WPAPSK";
+ if(auth == Ndis802_11AuthModeWPANone)
+ return "WPANONE";
+ if(auth == Ndis802_11AuthModeWPA2)
+ return "WPA2";
+ if(auth == Ndis802_11AuthModeWPA2PSK)
+ return "WPA2PSK";
+ if(auth == Ndis802_11AuthModeWPA1WPA2)
+ return "WPA1WPA2";
+ if(auth == Ndis802_11AuthModeWPA1PSKWPA2PSK)
+ return "WPA1PSKWPA2PSK";
+
+ return "UNKNOW";
+}
+
+#if 1 //#ifndef UCOS
+/*
+ ==========================================================================
+ Description:
+ Get site survey results
+ Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) UI needs to wait 4 seconds after issue a site survey command
+ 2.) iwpriv ra0 get_site_survey
+ 3.) UI needs to prepare at least 4096bytes to get the results
+ ==========================================================================
+*/
+#define LINE_LEN (4+33+20+8+10+9+7+3) // Channel+SSID+Bssid+WepStatus+AuthMode+Signal+WiressMode+NetworkType
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+VOID RTMPIoctlGetSiteSurvey(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq)
+{
+ CHAR *msg;
+ INT i=0;
+ INT WaitCnt;
+ INT Status=0;
+ CHAR Ssid[MAX_LEN_OF_SSID +1];
+ INT Rssi = 0, max_len = LINE_LEN;
+ UINT Rssi_Quality = 0;
+ NDIS_802_11_NETWORK_TYPE wireless_mode;
+
+ os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len));
+
+ if (msg == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n"));
+ return;
+ }
+
+ memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len );
+ memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1));
+ sprintf(msg,"%s","\n");
+ sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-8s%-10s%-9s%-7s%-3s\n",
+ "Ch", "SSID", "BSSID", "Enc", "Auth", "Siganl(%)", "W-Mode", " NT");
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ WaitCnt = 0;
+#ifdef CONFIG_STA_SUPPORT
+ pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+ while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
+ OS_WAIT(500);
+#endif // CONFIG_STA_SUPPORT //
+
+ for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
+ {
+ if( pAdapter->ScanTab.BssEntry[i].Channel==0)
+ break;
+
+ if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
+ break;
+
+ //Channel
+ sprintf(msg+strlen(msg),"%-4d", pAdapter->ScanTab.BssEntry[i].Channel);
+ //SSID
+ memcpy(Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
+ Ssid[pAdapter->ScanTab.BssEntry[i].SsidLen] = '\0';
+ sprintf(msg+strlen(msg),"%-33s", Ssid);
+ //BSSID
+ sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x ",
+ pAdapter->ScanTab.BssEntry[i].Bssid[0],
+ pAdapter->ScanTab.BssEntry[i].Bssid[1],
+ pAdapter->ScanTab.BssEntry[i].Bssid[2],
+ pAdapter->ScanTab.BssEntry[i].Bssid[3],
+ pAdapter->ScanTab.BssEntry[i].Bssid[4],
+ pAdapter->ScanTab.BssEntry[i].Bssid[5]);
+ //Encryption Type
+ sprintf(msg+strlen(msg),"%-8s",GetEncryptType(pAdapter->ScanTab.BssEntry[i].WepStatus));
+ //Authentication Mode
+ if (pAdapter->ScanTab.BssEntry[i].WepStatus == Ndis802_11WEPEnabled)
+ sprintf(msg+strlen(msg),"%-10s", "UNKNOW");
+ else
+ sprintf(msg+strlen(msg),"%-10s",GetAuthMode(pAdapter->ScanTab.BssEntry[i].AuthMode));
+ // Rssi
+ Rssi = (INT)pAdapter->ScanTab.BssEntry[i].Rssi;
+ if (Rssi >= -50)
+ Rssi_Quality = 100;
+ else if (Rssi >= -80) // between -50 ~ -80dbm
+ Rssi_Quality = (UINT)(24 + ((Rssi + 80) * 26)/10);
+ else if (Rssi >= -90) // between -80 ~ -90dbm
+ Rssi_Quality = (UINT)(((Rssi + 90) * 26)/10);
+ else // < -84 dbm
+ Rssi_Quality = 0;
+ sprintf(msg+strlen(msg),"%-9d", Rssi_Quality);
+ // Wireless Mode
+ wireless_mode = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
+ if (wireless_mode == Ndis802_11FH ||
+ wireless_mode == Ndis802_11DS)
+ sprintf(msg+strlen(msg),"%-7s", "11b");
+ else if (wireless_mode == Ndis802_11OFDM5)
+ sprintf(msg+strlen(msg),"%-7s", "11a");
+ else if (wireless_mode == Ndis802_11OFDM5_N)
+ sprintf(msg+strlen(msg),"%-7s", "11a/n");
+ else if (wireless_mode == Ndis802_11OFDM24)
+ sprintf(msg+strlen(msg),"%-7s", "11b/g");
+ else if (wireless_mode == Ndis802_11OFDM24_N)
+ sprintf(msg+strlen(msg),"%-7s", "11b/g/n");
+ else
+ sprintf(msg+strlen(msg),"%-7s", "unknow");
+ //Network Type
+ if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_ADHOC)
+ sprintf(msg+strlen(msg),"%-3s", " Ad");
+ else
+ sprintf(msg+strlen(msg),"%-3s", " In");
+
+ sprintf(msg+strlen(msg),"\n");
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+#endif // CONFIG_STA_SUPPORT //
+ wrq->u.data.length = strlen(msg);
+ Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - wrq->u.data.length = %d\n", wrq->u.data.length));
+ os_free_mem(NULL, (PUCHAR)msg);
+}
+
+
+#define MAC_LINE_LEN (14+4+4+10+10+10+6+6) // Addr+aid+psm+datatime+rxbyte+txbyte+current tx rate+last tx rate
+VOID RTMPIoctlGetMacTable(
+ IN PRTMP_ADAPTER pAd,
+ IN struct iwreq *wrq)
+{
+ INT i;
+ RT_802_11_MAC_TABLE MacTab;
+ char *msg;
+
+ MacTab.Num = 0;
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (pAd->MacTab.Content[i].ValidAsCLI && (pAd->MacTab.Content[i].Sst == SST_ASSOC))
+ {
+ COPY_MAC_ADDR(MacTab.Entry[MacTab.Num].Addr, &pAd->MacTab.Content[i].Addr);
+ MacTab.Entry[MacTab.Num].Aid = (UCHAR)pAd->MacTab.Content[i].Aid;
+ MacTab.Entry[MacTab.Num].Psm = pAd->MacTab.Content[i].PsMode;
+#ifdef DOT11_N_SUPPORT
+ MacTab.Entry[MacTab.Num].MimoPs = pAd->MacTab.Content[i].MmpsMode;
+#endif // DOT11_N_SUPPORT //
+
+ // Fill in RSSI per entry
+ MacTab.Entry[MacTab.Num].AvgRssi0 = pAd->MacTab.Content[i].RssiSample.AvgRssi0;
+ MacTab.Entry[MacTab.Num].AvgRssi1 = pAd->MacTab.Content[i].RssiSample.AvgRssi1;
+ MacTab.Entry[MacTab.Num].AvgRssi2 = pAd->MacTab.Content[i].RssiSample.AvgRssi2;
+
+ // the connected time per entry
+ MacTab.Entry[MacTab.Num].ConnectedTime = pAd->MacTab.Content[i].StaConnectTime;
+ MacTab.Entry[MacTab.Num].TxRate.field.MCS = pAd->MacTab.Content[i].HTPhyMode.field.MCS;
+ MacTab.Entry[MacTab.Num].TxRate.field.BW = pAd->MacTab.Content[i].HTPhyMode.field.BW;
+ MacTab.Entry[MacTab.Num].TxRate.field.ShortGI = pAd->MacTab.Content[i].HTPhyMode.field.ShortGI;
+ MacTab.Entry[MacTab.Num].TxRate.field.STBC = pAd->MacTab.Content[i].HTPhyMode.field.STBC;
+ MacTab.Entry[MacTab.Num].TxRate.field.rsv = pAd->MacTab.Content[i].HTPhyMode.field.rsv;
+ MacTab.Entry[MacTab.Num].TxRate.field.MODE = pAd->MacTab.Content[i].HTPhyMode.field.MODE;
+ MacTab.Entry[MacTab.Num].TxRate.word = pAd->MacTab.Content[i].HTPhyMode.word;
+
+ MacTab.Num += 1;
+ }
+ }
+ wrq->u.data.length = sizeof(RT_802_11_MAC_TABLE);
+ if (copy_to_user(wrq->u.data.pointer, &MacTab, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
+ }
+
+ msg = (CHAR *) kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);
+ memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN );
+ sprintf(msg,"%s","\n");
+ sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-10s%-10s%-10s%-6s%-6s\n",
+ "MAC", "AID", "PSM", "LDT", "RxB", "TxB","CTxR", "LTxR");
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+ if (pEntry->ValidAsCLI && (pEntry->Sst == SST_ASSOC))
+ {
+ if((strlen(msg)+MAC_LINE_LEN ) >= (MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN) )
+ break;
+ sprintf(msg+strlen(msg),"%02x%02x%02x%02x%02x%02x ",
+ pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
+ pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
+ sprintf(msg+strlen(msg),"%-4d", (int)pEntry->Aid);
+ sprintf(msg+strlen(msg),"%-4d", (int)pEntry->PsMode);
+ sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.LastDataPacketTime*/); // ToDo
+ sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalRxByteCount*/); // ToDo
+ sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalTxByteCount*/); // ToDo
+ sprintf(msg+strlen(msg),"%-6d",RateIdToMbps[pAd->MacTab.Content[i].CurrTxRate]);
+ sprintf(msg+strlen(msg),"%-6d\n",0/*RateIdToMbps[pAd->MacTab.Content[i].LastTxRate]*/); // ToDo
+ }
+ }
+ // for compatible with old API just do the printk to console
+ //wrq->u.data.length = strlen(msg);
+ //if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s", msg));
+ }
+
+ kfree(msg);
+}
+#endif // UCOS //
+
+#ifdef DOT11_N_SUPPORT
+INT Set_BASetup_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR mac[6], tid;
+ char *token, sepValue[] = ":", DASH = '-';
+ INT i;
+ MAC_TABLE_ENTRY *pEntry;
+
+/*
+ The BASetup inupt string format should be xx:xx:xx:xx:xx:xx-d,
+ =>The six 2 digit hex-decimal number previous are the Mac address,
+ =>The seventh decimal number is the tid value.
+*/
+ //printk("\n%s\n", arg);
+
+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
+ return FALSE;
+
+ token = strchr(arg, DASH);
+ if ((token != NULL) && (strlen(token)>1))
+ {
+ tid = simple_strtol((token+1), 0, 10);
+ if (tid > 15)
+ return FALSE;
+
+ *token = '\0';
+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+ {
+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+ return FALSE;
+ AtoH(token, (PUCHAR)(&mac[i]), 1);
+ }
+ if(i != 6)
+ return FALSE;
+
+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n", mac[0], mac[1],
+ mac[2], mac[3], mac[4], mac[5], tid);
+
+ pEntry = MacTableLookup(pAd, mac);
+
+ if (pEntry) {
+ printk("\nSetup BA Session: Tid = %d\n", tid);
+ BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+
+}
+
+INT Set_BADecline_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG bBADecline;
+
+ bBADecline = simple_strtol(arg, 0, 10);
+
+ if (bBADecline == 0)
+ {
+ pAd->CommonCfg.bBADecline = FALSE;
+ }
+ else if (bBADecline == 1)
+ {
+ pAd->CommonCfg.bBADecline = TRUE;
+ }
+ else
+ {
+ return FALSE; //Invalid argument
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_BADecline_Proc::(BADecline=%d)\n", pAd->CommonCfg.bBADecline));
+
+ return TRUE;
+}
+
+INT Set_BAOriTearDown_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR mac[6], tid;
+ char *token, sepValue[] = ":", DASH = '-';
+ INT i;
+ MAC_TABLE_ENTRY *pEntry;
+
+ //printk("\n%s\n", arg);
+/*
+ The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
+ =>The six 2 digit hex-decimal number previous are the Mac address,
+ =>The seventh decimal number is the tid value.
+*/
+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
+ return FALSE;
+
+ token = strchr(arg, DASH);
+ if ((token != NULL) && (strlen(token)>1))
+ {
+ tid = simple_strtol((token+1), 0, 10);
+ if (tid > NUM_OF_TID)
+ return FALSE;
+
+ *token = '\0';
+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+ {
+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+ return FALSE;
+ AtoH(token, (PUCHAR)(&mac[i]), 1);
+ }
+ if(i != 6)
+ return FALSE;
+
+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
+ mac[2], mac[3], mac[4], mac[5], tid);
+
+ pEntry = MacTableLookup(pAd, mac);
+
+ if (pEntry) {
+ printk("\nTear down Ori BA Session: Tid = %d\n", tid);
+ BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+
+}
+
+INT Set_BARecTearDown_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR mac[6], tid;
+ char *token, sepValue[] = ":", DASH = '-';
+ INT i;
+ MAC_TABLE_ENTRY *pEntry;
+
+ //printk("\n%s\n", arg);
+/*
+ The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
+ =>The six 2 digit hex-decimal number previous are the Mac address,
+ =>The seventh decimal number is the tid value.
+*/
+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
+ return FALSE;
+
+ token = strchr(arg, DASH);
+ if ((token != NULL) && (strlen(token)>1))
+ {
+ tid = simple_strtol((token+1), 0, 10);
+ if (tid > NUM_OF_TID)
+ return FALSE;
+
+ *token = '\0';
+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+ {
+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+ return FALSE;
+ AtoH(token, (PUCHAR)(&mac[i]), 1);
+ }
+ if(i != 6)
+ return FALSE;
+
+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
+ mac[2], mac[3], mac[4], mac[5], tid);
+
+ pEntry = MacTableLookup(pAd, mac);
+
+ if (pEntry) {
+ printk("\nTear down Rec BA Session: Tid = %d\n", tid);
+ BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+
+}
+
+INT Set_HtBw_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG HtBw;
+
+ HtBw = simple_strtol(arg, 0, 10);
+ if (HtBw == BW_40)
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+ else if (HtBw == BW_20)
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBw_Proc::(HtBw=%d)\n", pAd->CommonCfg.RegTransmitSetting.field.BW));
+
+ return TRUE;
+}
+
+INT Set_HtMcs_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG HtMcs, Mcs_tmp;
+#ifdef CONFIG_STA_SUPPORT
+ BOOLEAN bAutoRate = FALSE;
+#endif // CONFIG_STA_SUPPORT //
+
+ Mcs_tmp = simple_strtol(arg, 0, 10);
+
+ if (Mcs_tmp <= 15 || Mcs_tmp == 32)
+ HtMcs = Mcs_tmp;
+ else
+ HtMcs = MCS_AUTO;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = HtMcs;
+ pAd->StaCfg.bAutoTxRateSwitch = (HtMcs == MCS_AUTO) ? TRUE:FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(HtMcs=%d, bAutoTxRateSwitch = %d)\n",
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS, pAd->StaCfg.bAutoTxRateSwitch));
+
+ if ((pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED) ||
+ (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE < MODE_HTMIX))
+ {
+ if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
+ (HtMcs >= 0 && HtMcs <= 3) &&
+ (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_CCK))
+ {
+ RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs] * 1000000));
+ }
+ else if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
+ (HtMcs >= 0 && HtMcs <= 7) &&
+ (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_OFDM))
+ {
+ RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs+4] * 1000000));
+ }
+ else
+ bAutoRate = TRUE;
+
+ if (bAutoRate)
+ {
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ RTMPSetDesiredRates(pAd, -1);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(FixedTxMode=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode));
+ }
+ if (ADHOC_ON(pAd))
+ return TRUE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ SetCommonHT(pAd);
+
+ return TRUE;
+}
+
+INT Set_HtGi_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG HtGi;
+
+ HtGi = simple_strtol(arg, 0, 10);
+
+ if ( HtGi == GI_400)
+ pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
+ else if ( HtGi == GI_800 )
+ pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtGi_Proc::(ShortGI=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.ShortGI));
+
+ return TRUE;
+}
+
+
+INT Set_HtTxBASize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR Size;
+
+ Size = simple_strtol(arg, 0, 10);
+
+ if (Size <=0 || Size >=64)
+ {
+ Size = 8;
+ }
+ pAd->CommonCfg.TxBASize = Size-1;
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_HtTxBASize ::(TxBASize= %d)\n", Size));
+
+ return TRUE;
+}
+
+
+INT Set_HtOpMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if (Value == HTMODE_GF)
+ pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF;
+ else if ( Value == HTMODE_MM )
+ pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtOpMode_Proc::(HtOpMode=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.HTMODE));
+
+ return TRUE;
+
+}
+
+INT Set_HtStbc_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if (Value == STBC_USE)
+ pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
+ else if ( Value == STBC_NONE )
+ pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Stbc_Proc::(HtStbc=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.STBC));
+
+ return TRUE;
+}
+
+INT Set_HtHtc_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->HTCEnable = FALSE;
+ else if ( Value ==1 )
+ pAd->HTCEnable = TRUE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtHtc_Proc::(HtHtc=%d)\n",pAd->HTCEnable));
+
+ return TRUE;
+}
+
+INT Set_HtExtcha_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if (Value == 0)
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
+ else if ( Value ==1 )
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtExtcha_Proc::(HtExtcha=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.EXTCHA));
+
+ return TRUE;
+}
+
+INT Set_HtMpduDensity_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if (Value <=7 && Value >= 0)
+ pAd->CommonCfg.BACapability.field.MpduDensity = Value;
+ else
+ pAd->CommonCfg.BACapability.field.MpduDensity = 4;
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMpduDensity_Proc::(HtMpduDensity=%d)\n",pAd->CommonCfg.BACapability.field.MpduDensity));
+
+ return TRUE;
+}
+
+INT Set_HtBaWinSize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+
+ if (Value >=1 && Value <= 64)
+ {
+ pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
+ pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
+ }
+ else
+ {
+ pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
+ pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
+ }
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBaWinSize_Proc::(HtBaWinSize=%d)\n",pAd->CommonCfg.BACapability.field.RxBAWinLimit));
+
+ return TRUE;
+}
+
+INT Set_HtRdg_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if (Value == 0)
+ pAd->CommonCfg.bRdg = FALSE;
+ else if ( Value ==1 )
+ {
+ pAd->HTCEnable = TRUE;
+ pAd->CommonCfg.bRdg = TRUE;
+ }
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtRdg_Proc::(HtRdg=%d)\n",pAd->CommonCfg.bRdg));
+
+ return TRUE;
+}
+
+INT Set_HtLinkAdapt_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->bLinkAdapt = FALSE;
+ else if ( Value ==1 )
+ {
+ pAd->HTCEnable = TRUE;
+ pAd->bLinkAdapt = TRUE;
+ }
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtLinkAdapt_Proc::(HtLinkAdapt=%d)\n",pAd->bLinkAdapt));
+
+ return TRUE;
+}
+
+INT Set_HtAmsdu_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
+ else if ( Value == 1 )
+ pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAmsdu_Proc::(HtAmsdu=%d)\n",pAd->CommonCfg.BACapability.field.AmsduEnable));
+
+ return TRUE;
+}
+
+INT Set_HtAutoBa_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
+ pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
+ }
+ else if (Value == 1)
+ {
+ pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
+ pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
+ }
+ else
+ return FALSE; //Invalid argument
+
+ pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
+ pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAutoBa_Proc::(HtAutoBa=%d)\n",pAd->CommonCfg.BACapability.field.AutoBA));
+
+ return TRUE;
+
+}
+
+INT Set_HtProtect_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->CommonCfg.bHTProtect = FALSE;
+ else if (Value == 1)
+ pAd->CommonCfg.bHTProtect = TRUE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtProtect_Proc::(HtProtect=%d)\n",pAd->CommonCfg.bHTProtect));
+
+ return TRUE;
+}
+
+INT Set_SendPSMPAction_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR mac[6], mode;
+ char *token, sepValue[] = ":", DASH = '-';
+ INT i;
+ MAC_TABLE_ENTRY *pEntry;
+
+ //printk("\n%s\n", arg);
+/*
+ The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
+ =>The six 2 digit hex-decimal number previous are the Mac address,
+ =>The seventh decimal number is the mode value.
+*/
+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and mode value in decimal format.
+ return FALSE;
+
+ token = strchr(arg, DASH);
+ if ((token != NULL) && (strlen(token)>1))
+ {
+ mode = simple_strtol((token+1), 0, 10);
+ if (mode > MMPS_ENABLE)
+ return FALSE;
+
+ *token = '\0';
+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+ {
+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+ return FALSE;
+ AtoH(token, (PUCHAR)(&mac[i]), 1);
+ }
+ if(i != 6)
+ return FALSE;
+
+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
+ mac[2], mac[3], mac[4], mac[5], mode);
+
+ pEntry = MacTableLookup(pAd, mac);
+
+ if (pEntry) {
+ printk("\nSendPSMPAction MIPS mode = %d\n", mode);
+ SendPSMPAction(pAd, pEntry->Aid, mode);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+
+
+}
+
+INT Set_HtMIMOPSmode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if (Value <=3 && Value >= 0)
+ pAd->CommonCfg.BACapability.field.MMPSmode = Value;
+ else
+ pAd->CommonCfg.BACapability.field.MMPSmode = 3;
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMIMOPSmode_Proc::(MIMOPS mode=%d)\n",pAd->CommonCfg.BACapability.field.MMPSmode));
+
+ return TRUE;
+}
+
+
+INT Set_ForceShortGI_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->WIFItestbed.bShortGI = FALSE;
+ else if (Value == 1)
+ pAd->WIFItestbed.bShortGI = TRUE;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceShortGI_Proc::(ForceShortGI=%d)\n", pAd->WIFItestbed.bShortGI));
+
+ return TRUE;
+}
+
+
+
+INT Set_ForceGF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->WIFItestbed.bGreenField = FALSE;
+ else if (Value == 1)
+ pAd->WIFItestbed.bGreenField = TRUE;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceGF_Proc::(ForceGF=%d)\n", pAd->WIFItestbed.bGreenField));
+
+ return TRUE;
+}
+
+INT Set_HtMimoPs_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->CommonCfg.bMIMOPSEnable = FALSE;
+ else if (Value == 1)
+ pAd->CommonCfg.bMIMOPSEnable = TRUE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMimoPs_Proc::(HtMimoPs=%d)\n",pAd->CommonCfg.bMIMOPSEnable));
+
+ return TRUE;
+}
+#endif // DOT11_N_SUPPORT //
+
+
+#ifdef DOT11_N_SUPPORT
+INT SetCommonHT(
+ IN PRTMP_ADAPTER pAd)
+{
+ OID_SET_HT_PHYMODE SetHT;
+
+ if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
+ return FALSE;
+
+ SetHT.PhyMode = pAd->CommonCfg.PhyMode;
+ SetHT.TransmitNo = ((UCHAR)pAd->Antenna.field.TxPath);
+ SetHT.HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
+ SetHT.ExtOffset = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
+ SetHT.MCS = MCS_AUTO;
+ SetHT.BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW;
+ SetHT.STBC = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.STBC;
+ SetHT.SHORTGI = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
+
+ RTMPSetHT(pAd, &SetHT);
+
+ return TRUE;
+}
+#endif // DOT11_N_SUPPORT //
+
+INT Set_FixedTxMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR fix_tx_mode = FIXED_TXMODE_HT;
+
+ if (strcmp(arg, "OFDM") == 0 || strcmp(arg, "ofdm") == 0)
+ {
+ fix_tx_mode = FIXED_TXMODE_OFDM;
+ }
+ else if (strcmp(arg, "CCK") == 0 || strcmp(arg, "cck") == 0)
+ {
+ fix_tx_mode = FIXED_TXMODE_CCK;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
+#endif // CONFIG_STA_SUPPORT //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_FixedTxMode_Proc::(FixedTxMode=%d)\n", fix_tx_mode));
+
+ return TRUE;
+}
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+INT Set_OpMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+#ifdef RT2870
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+#endif // RT2870 //
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Can not switch operate mode on interface up !! \n"));
+ return FALSE;
+ }
+
+ if (Value == 0)
+ pAd->OpMode = OPMODE_STA;
+ else if (Value == 1)
+ pAd->OpMode = OPMODE_AP;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_OpMode_Proc::(OpMode=%s)\n", pAd->OpMode == 1 ? "AP Mode" : "STA Mode"));
+
+ return TRUE;
+}
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+
+/////////////////////////////////////////////////////////////////////////
+PCHAR RTMPGetRalinkAuthModeStr(
+ IN NDIS_802_11_AUTHENTICATION_MODE authMode)
+{
+ switch(authMode)
+ {
+ case Ndis802_11AuthModeOpen:
+ return "OPEN";
+ default:
+ case Ndis802_11AuthModeWPAPSK:
+ return "WPAPSK";
+ case Ndis802_11AuthModeShared:
+ return "SHARED";
+ case Ndis802_11AuthModeWPA:
+ return "WPA";
+ case Ndis802_11AuthModeWPA2:
+ return "WPA2";
+ case Ndis802_11AuthModeWPA2PSK:
+ return "WPA2PSK";
+ case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+ return "WPAPSKWPA2PSK";
+ case Ndis802_11AuthModeWPA1WPA2:
+ return "WPA1WPA2";
+ }
+}
+
+PCHAR RTMPGetRalinkEncryModeStr(
+ IN USHORT encryMode)
+{
+ switch(encryMode)
+ {
+ default:
+ case Ndis802_11WEPDisabled:
+ return "NONE";
+ case Ndis802_11WEPEnabled:
+ return "WEP";
+ case Ndis802_11Encryption2Enabled:
+ return "TKIP";
+ case Ndis802_11Encryption3Enabled:
+ return "AES";
+ case Ndis802_11Encryption4Enabled:
+ return "TKIPAES";
+ }
+}
+
+INT RTMPShowCfgValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pName,
+ IN PUCHAR pBuf)
+{
+ INT Status = 0;
+
+ for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++)
+ {
+ if (!strcmp(pName, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name))
+ {
+ if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->show_proc(pAd, pBuf))
+ Status = -EINVAL;
+ break; //Exit for loop.
+ }
+ }
+
+ if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name == NULL)
+ {
+ sprintf(pBuf, "\n");
+ for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++)
+ sprintf(pBuf, "%s%s\n", pBuf, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name);
+ }
+
+ return Status;
+}
+
+INT Show_SSID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.Ssid);
+#endif // CONFIG_STA_SUPPORT //
+ return 0;
+}
+
+INT Show_WirelessMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->CommonCfg.PhyMode)
+ {
+ case PHY_11BG_MIXED:
+ sprintf(pBuf, "\t11B/G");
+ break;
+ case PHY_11B:
+ sprintf(pBuf, "\t11B");
+ break;
+ case PHY_11A:
+ sprintf(pBuf, "\t11A");
+ break;
+ case PHY_11ABG_MIXED:
+ sprintf(pBuf, "\t11A/B/G");
+ break;
+ case PHY_11G:
+ sprintf(pBuf, "\t11G");
+ break;
+#ifdef DOT11_N_SUPPORT
+ case PHY_11ABGN_MIXED:
+ sprintf(pBuf, "\t11A/B/G/N");
+ break;
+ case PHY_11N_2_4G:
+ sprintf(pBuf, "\t11N only with 2.4G");
+ break;
+ case PHY_11GN_MIXED:
+ sprintf(pBuf, "\t11G/N");
+ break;
+ case PHY_11AN_MIXED:
+ sprintf(pBuf, "\t11A/N");
+ break;
+ case PHY_11BGN_MIXED:
+ sprintf(pBuf, "\t11B/G/N");
+ break;
+ case PHY_11AGN_MIXED:
+ sprintf(pBuf, "\t11A/G/N");
+ break;
+ case PHY_11N_5G:
+ sprintf(pBuf, "\t11N only with 5G");
+ break;
+#endif // DOT11_N_SUPPORT //
+ default:
+ sprintf(pBuf, "\tUnknow Value(%d)", pAd->CommonCfg.PhyMode);
+ break;
+ }
+ return 0;
+}
+
+
+INT Show_TxBurst_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE");
+ return 0;
+}
+
+INT Show_TxPreamble_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->CommonCfg.TxPreamble)
+ {
+ case Rt802_11PreambleShort:
+ sprintf(pBuf, "\tShort");
+ break;
+ case Rt802_11PreambleLong:
+ sprintf(pBuf, "\tLong");
+ break;
+ case Rt802_11PreambleAuto:
+ sprintf(pBuf, "\tAuto");
+ break;
+ default:
+ sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.TxPreamble);
+ break;
+ }
+
+ return 0;
+}
+
+INT Show_TxPower_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage);
+ return 0;
+}
+
+INT Show_Channel_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel);
+ return 0;
+}
+
+INT Show_BGProtection_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->CommonCfg.UseBGProtection)
+ {
+ case 1: //Always On
+ sprintf(pBuf, "\tON");
+ break;
+ case 2: //Always OFF
+ sprintf(pBuf, "\tOFF");
+ break;
+ case 0: //AUTO
+ sprintf(pBuf, "\tAuto");
+ break;
+ default:
+ sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.UseBGProtection);
+ break;
+ }
+ return 0;
+}
+
+INT Show_RTSThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold);
+ return 0;
+}
+
+INT Show_FragThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold);
+ return 0;
+}
+
+#ifdef DOT11_N_SUPPORT
+INT Show_HtBw_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+ {
+ sprintf(pBuf, "\t40 MHz");
+ }
+ else
+ {
+ sprintf(pBuf, "\t20 MHz");
+ }
+ return 0;
+}
+
+INT Show_HtMcs_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ sprintf(pBuf, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS);
+#endif // CONFIG_STA_SUPPORT //
+ return 0;
+}
+
+INT Show_HtGi_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI)
+ {
+ case GI_400:
+ sprintf(pBuf, "\tGI_400");
+ break;
+ case GI_800:
+ sprintf(pBuf, "\tGI_800");
+ break;
+ default:
+ sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.ShortGI);
+ break;
+ }
+ return 0;
+}
+
+INT Show_HtOpMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE)
+ {
+ case HTMODE_GF:
+ sprintf(pBuf, "\tGF");
+ break;
+ case HTMODE_MM:
+ sprintf(pBuf, "\tMM");
+ break;
+ default:
+ sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.HTMODE);
+ break;
+ }
+ return 0;
+}
+
+INT Show_HtExtcha_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA)
+ {
+ case EXTCHA_BELOW:
+ sprintf(pBuf, "\tBelow");
+ break;
+ case EXTCHA_ABOVE:
+ sprintf(pBuf, "\tAbove");
+ break;
+ default:
+ sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.EXTCHA);
+ break;
+ }
+ return 0;
+}
+
+
+INT Show_HtMpduDensity_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity);
+ return 0;
+}
+
+INT Show_HtBaWinSize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit);
+ return 0;
+}
+
+INT Show_HtRdg_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE");
+ return 0;
+}
+
+INT Show_HtAmsdu_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE");
+ return 0;
+}
+
+INT Show_HtAutoBa_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE");
+ return 0;
+}
+#endif // DOT11_N_SUPPORT //
+
+INT Show_CountryRegion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion);
+ return 0;
+}
+
+INT Show_CountryRegionABand_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand);
+ return 0;
+}
+
+INT Show_CountryCode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode);
+ return 0;
+}
+
+#ifdef AGGREGATION_SUPPORT
+INT Show_PktAggregate_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE");
+ return 0;
+}
+#endif // AGGREGATION_SUPPORT //
+
+#ifdef WMM_SUPPORT
+INT Show_WmmCapable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE");
+#endif // CONFIG_STA_SUPPORT //
+
+ return 0;
+}
+#endif // WMM_SUPPORT //
+
+INT Show_IEEE80211H_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE");
+ return 0;
+}
+
+#ifdef CONFIG_STA_SUPPORT
+INT Show_NetworkType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->StaCfg.BssType)
+ {
+ case BSS_ADHOC:
+ sprintf(pBuf, "\tAdhoc");
+ break;
+ case BSS_INFRA:
+ sprintf(pBuf, "\tInfra");
+ break;
+ case BSS_ANY:
+ sprintf(pBuf, "\tAny");
+ break;
+ case BSS_MONITOR:
+ sprintf(pBuf, "\tMonitor");
+ break;
+ default:
+ sprintf(pBuf, "\tUnknow Value(%d)", pAd->StaCfg.BssType);
+ break;
+ }
+ return 0;
+}
+#endif // CONFIG_STA_SUPPORT //
+
+INT Show_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeOpen;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ AuthMode = pAd->StaCfg.AuthMode;
+#endif // CONFIG_STA_SUPPORT //
+
+ if ((AuthMode >= Ndis802_11AuthModeOpen) &&
+ (AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
+ sprintf(pBuf, "\t%s", RTMPGetRalinkAuthModeStr(AuthMode));
+ else
+ sprintf(pBuf, "\tUnknow Value(%d)", AuthMode);
+
+ return 0;
+}
+
+INT Show_EncrypType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ NDIS_802_11_WEP_STATUS WepStatus = Ndis802_11WEPDisabled;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ WepStatus = pAd->StaCfg.WepStatus;
+#endif // CONFIG_STA_SUPPORT //
+
+ if ((WepStatus >= Ndis802_11WEPEnabled) &&
+ (WepStatus <= Ndis802_11Encryption4KeyAbsent))
+ sprintf(pBuf, "\t%s", RTMPGetRalinkEncryModeStr(WepStatus));
+ else
+ sprintf(pBuf, "\tUnknow Value(%d)", WepStatus);
+
+ return 0;
+}
+
+INT Show_DefaultKeyID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ UCHAR DefaultKeyId = 0;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ DefaultKeyId = pAd->StaCfg.DefaultKeyId;
+#endif // CONFIG_STA_SUPPORT //
+
+ sprintf(pBuf, "\t%d", DefaultKeyId);
+
+ return 0;
+}
+
+INT Show_WepKey_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN INT KeyIdx,
+ OUT PUCHAR pBuf)
+{
+ UCHAR Key[16] = {0}, KeyLength = 0;
+ INT index = BSS0;
+
+ KeyLength = pAd->SharedKey[index][KeyIdx].KeyLen;
+ NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength);
+
+ //check key string is ASCII or not
+ if (RTMPCheckStrPrintAble(Key, KeyLength))
+ sprintf(pBuf, "\t%s", Key);
+ else
+ {
+ int idx;
+ sprintf(pBuf, "\t");
+ for (idx = 0; idx < KeyLength; idx++)
+ sprintf(pBuf+strlen(pBuf), "%02X", Key[idx]);
+ }
+ return 0;
+}
+
+INT Show_Key1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ Show_WepKey_Proc(pAd, 0, pBuf);
+ return 0;
+}
+
+INT Show_Key2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ Show_WepKey_Proc(pAd, 1, pBuf);
+ return 0;
+}
+
+INT Show_Key3_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ Show_WepKey_Proc(pAd, 2, pBuf);
+ return 0;
+}
+
+INT Show_Key4_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ Show_WepKey_Proc(pAd, 3, pBuf);
+ return 0;
+}
+
+INT Show_WPAPSK_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ INT idx;
+ UCHAR PMK[32] = {0};
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ NdisMoveMemory(PMK, pAd->StaCfg.PMK, 32);
+#endif // CONFIG_STA_SUPPORT //
+
+ sprintf(pBuf, "\tPMK = ");
+ for (idx = 0; idx < 32; idx++)
+ sprintf(pBuf+strlen(pBuf), "%02X", PMK[idx]);
+
+ return 0;
+}
+
diff --git a/drivers/staging/rt3070/common/cmm_sanity.c b/drivers/staging/rt3070/common/cmm_sanity.c
new file mode 100644
index 00000000000..6118df8de7b
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_sanity.c
@@ -0,0 +1,1669 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ sanity.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2004-09-01 add WMM support
+*/
+#include "../rt_config.h"
+
+
+extern UCHAR CISCO_OUI[];
+
+extern UCHAR WPA_OUI[];
+extern UCHAR RSN_OUI[];
+extern UCHAR WME_INFO_ELEM[];
+extern UCHAR WME_PARM_ELEM[];
+extern UCHAR Ccx2QosInfo[];
+extern UCHAR RALINK_OUI[];
+extern UCHAR BROADCOM_OUI[];
+extern UCHAR WPS_OUI[];
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN MlmeAddBAReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2)
+{
+ PMLME_ADDBA_REQ_STRUCT pInfo;
+
+ pInfo = (MLME_ADDBA_REQ_STRUCT *)Msg;
+
+ if ((MsgLen != sizeof(MLME_ADDBA_REQ_STRUCT)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - message lenght not correct.\n"));
+ return FALSE;
+ }
+
+ if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
+ return FALSE;
+ }
+
+ /*
+ if ((pInfo->BaBufSize > MAX_RX_REORDERBUF) || (pInfo->BaBufSize < 2))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - Rx Reordering buffer too big or too small\n"));
+ return FALSE;
+ }
+ */
+
+ if ((pInfo->pAddr[0]&0x01) == 0x01)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN MlmeDelBAReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen)
+{
+ MLME_DELBA_REQ_STRUCT *pInfo;
+ pInfo = (MLME_DELBA_REQ_STRUCT *)Msg;
+
+ if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n"));
+ return FALSE;
+ }
+
+ if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
+ return FALSE;
+ }
+
+ if ((pInfo->TID & 0xf0))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
+ return FALSE;
+ }
+
+ if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOLEAN PeerAddBAReqActionSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2)
+{
+ PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
+ PFRAME_ADDBA_REQ pAddFrame;
+ pAddFrame = (PFRAME_ADDBA_REQ)(pMsg);
+ if (MsgLen < (sizeof(FRAME_ADDBA_REQ)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen));
+ return FALSE;
+ }
+ // we support immediate BA.
+ *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
+ pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
+ pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word);
+
+ if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
+ DBGPRINT(RT_DEBUG_ERROR,("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, pAddFrame->BaParm.AMSDUSupported));
+ return FALSE;
+ }
+
+ // we support immediate BA.
+ if (pAddFrame->BaParm.TID &0xfff0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", pAddFrame->BaParm.TID));
+ return FALSE;
+ }
+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+ return TRUE;
+}
+
+BOOLEAN PeerAddBARspActionSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen)
+{
+ //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
+ PFRAME_ADDBA_RSP pAddFrame;
+
+ pAddFrame = (PFRAME_ADDBA_RSP)(pMsg);
+ if (MsgLen < (sizeof(FRAME_ADDBA_RSP)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", MsgLen));
+ return FALSE;
+ }
+ // we support immediate BA.
+ *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
+ pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode);
+ pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
+
+ if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
+ return FALSE;
+ }
+
+ // we support immediate BA.
+ if (pAddFrame->BaParm.TID &0xfff0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", pAddFrame->BaParm.TID));
+ return FALSE;
+ }
+ return TRUE;
+
+}
+
+BOOLEAN PeerDelBAActionSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN VOID *pMsg,
+ IN ULONG MsgLen )
+{
+ //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
+ PFRAME_DELBA_REQ pDelFrame;
+ if (MsgLen != (sizeof(FRAME_DELBA_REQ)))
+ return FALSE;
+
+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return FALSE;
+
+ pDelFrame = (PFRAME_DELBA_REQ)(pMsg);
+
+ *(USHORT *)(&pDelFrame->DelbaParm) = cpu2le16(*(USHORT *)(&pDelFrame->DelbaParm));
+ pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode);
+
+ if (pDelFrame->DelbaParm.TID &0xfff0)
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerBeaconAndProbeRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ IN UCHAR MsgChannel,
+ OUT PUCHAR pAddr2,
+ OUT PUCHAR pBssid,
+ OUT CHAR Ssid[],
+ OUT UCHAR *pSsidLen,
+ OUT UCHAR *pBssType,
+ OUT USHORT *pBeaconPeriod,
+ OUT UCHAR *pChannel,
+ OUT UCHAR *pNewChannel,
+ OUT LARGE_INTEGER *pTimestamp,
+ OUT CF_PARM *pCfParm,
+ OUT USHORT *pAtimWin,
+ OUT USHORT *pCapabilityInfo,
+ OUT UCHAR *pErp,
+ OUT UCHAR *pDtimCount,
+ OUT UCHAR *pDtimPeriod,
+ OUT UCHAR *pBcastFlag,
+ OUT UCHAR *pMessageToMe,
+ OUT UCHAR SupRate[],
+ OUT UCHAR *pSupRateLen,
+ OUT UCHAR ExtRate[],
+ OUT UCHAR *pExtRateLen,
+ OUT UCHAR *pCkipFlag,
+ OUT UCHAR *pAironetCellPowerLimit,
+ OUT PEDCA_PARM pEdcaParm,
+ OUT PQBSS_LOAD_PARM pQbssLoad,
+ OUT PQOS_CAPABILITY_PARM pQosCapability,
+ OUT ULONG *pRalinkIe,
+ OUT UCHAR *pHtCapabilityLen,
+#ifdef CONFIG_STA_SUPPORT
+ OUT UCHAR *pPreNHtCapabilityLen,
+#endif // CONFIG_STA_SUPPORT //
+ OUT HT_CAPABILITY_IE *pHtCapability,
+ OUT UCHAR *AddHtInfoLen,
+ OUT ADD_HT_INFO_IE *AddHtInfo,
+ OUT UCHAR *NewExtChannelOffset, // Ht extension channel offset(above or below)
+ OUT USHORT *LengthVIE,
+ OUT PNDIS_802_11_VARIABLE_IEs pVIE)
+{
+ CHAR *Ptr;
+#ifdef CONFIG_STA_SUPPORT
+ CHAR TimLen;
+#endif // CONFIG_STA_SUPPORT //
+ PFRAME_802_11 pFrame;
+ PEID_STRUCT pEid;
+ UCHAR SubType;
+ UCHAR Sanity;
+ //UCHAR ECWMin, ECWMax;
+ //MAC_CSR9_STRUC Csr9;
+ ULONG Length = 0;
+
+ // For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel
+ // 1. If the AP is 11n enabled, then check the control channel.
+ // 2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!!)
+ UCHAR CtrlChannel = 0;
+
+ // Add for 3 necessary EID field check
+ Sanity = 0;
+
+ *pAtimWin = 0;
+ *pErp = 0;
+ *pDtimCount = 0;
+ *pDtimPeriod = 0;
+ *pBcastFlag = 0;
+ *pMessageToMe = 0;
+ *pExtRateLen = 0;
+ *pCkipFlag = 0; // Default of CkipFlag is 0
+ *pAironetCellPowerLimit = 0xFF; // Default of AironetCellPowerLimit is 0xFF
+ *LengthVIE = 0; // Set the length of VIE to init value 0
+ *pHtCapabilityLen = 0; // Set the length of VIE to init value 0
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->OpMode == OPMODE_STA)
+ *pPreNHtCapabilityLen = 0; // Set the length of VIE to init value 0
+#endif // CONFIG_STA_SUPPORT //
+ *AddHtInfoLen = 0; // Set the length of VIE to init value 0
+ *pRalinkIe = 0;
+ *pNewChannel = 0;
+ *NewExtChannelOffset = 0xff; //Default 0xff means no such IE
+ pCfParm->bValid = FALSE; // default: no IE_CF found
+ pQbssLoad->bValid = FALSE; // default: no IE_QBSS_LOAD found
+ pEdcaParm->bValid = FALSE; // default: no IE_EDCA_PARAMETER found
+ pQosCapability->bValid = FALSE; // default: no IE_QOS_CAPABILITY found
+
+ pFrame = (PFRAME_802_11)Msg;
+
+ // get subtype from header
+ SubType = (UCHAR)pFrame->Hdr.FC.SubType;
+
+ // get Addr2 and BSSID from header
+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+ COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3);
+
+// hex_dump("Beacon", Msg, MsgLen);
+
+ Ptr = pFrame->Octet;
+ Length += LENGTH_802_11;
+
+ // get timestamp from payload and advance the pointer
+ NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
+
+ pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart);
+ pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart);
+
+ Ptr += TIMESTAMP_LEN;
+ Length += TIMESTAMP_LEN;
+
+ // get beacon interval from payload and advance the pointer
+ NdisMoveMemory(pBeaconPeriod, Ptr, 2);
+ Ptr += 2;
+ Length += 2;
+
+ // get capability info from payload and advance the pointer
+ NdisMoveMemory(pCapabilityInfo, Ptr, 2);
+ Ptr += 2;
+ Length += 2;
+
+ if (CAP_IS_ESS_ON(*pCapabilityInfo))
+ *pBssType = BSS_INFRA;
+ else
+ *pBssType = BSS_ADHOC;
+
+ pEid = (PEID_STRUCT) Ptr;
+
+ // get variable fields from payload and advance the pointer
+ while ((Length + 2 + pEid->Len) <= MsgLen)
+ {
+ //
+ // Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow.
+ //
+ if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
+ (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN));
+ break;
+ }
+
+ switch(pEid->Eid)
+ {
+ case IE_SSID:
+ // Already has one SSID EID in this beacon, ignore the second one
+ if (Sanity & 0x1)
+ break;
+ if(pEid->Len <= MAX_LEN_OF_SSID)
+ {
+ NdisMoveMemory(Ssid, pEid->Octet, pEid->Len);
+ *pSsidLen = pEid->Len;
+ Sanity |= 0x1;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
+ return FALSE;
+ }
+ break;
+
+ case IE_SUPP_RATES:
+ if(pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ Sanity |= 0x2;
+ NdisMoveMemory(SupRate, pEid->Octet, pEid->Len);
+ *pSupRateLen = pEid->Len;
+
+ // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
+ // from ScanTab. We should report as is. And filter out unsupported
+ // rates in MlmeAux.
+ // Check against the supported rates
+ // RTMPCheckRates(pAd, SupRate, pSupRateLen);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",pEid->Len));
+ return FALSE;
+ }
+ break;
+
+ case IE_HT_CAP:
+ if (pEid->Len >= SIZE_HT_CAP_IE) //Note: allow extension.!!
+ {
+ NdisMoveMemory(pHtCapability, pEid->Octet, sizeof(HT_CAPABILITY_IE));
+ *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
+
+ *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
+ *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ *pPreNHtCapabilityLen = 0; // Nnow we only support 26 bytes.
+
+ Ptr = (PUCHAR) pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", pEid->Len));
+ }
+
+ break;
+ case IE_ADD_HT:
+ if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
+ {
+ // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
+ // copy first sizeof(ADD_HT_INFO_IE)
+ NdisMoveMemory(AddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
+ *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
+
+ CtrlChannel = AddHtInfo->ControlChan;
+
+ *(USHORT *)(&AddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo2));
+ *(USHORT *)(&AddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo3));
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ Ptr = (PUCHAR) pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
+ }
+
+ break;
+ case IE_SECONDARY_CH_OFFSET:
+ if (pEid->Len == 1)
+ {
+ *NewExtChannelOffset = pEid->Octet[0];
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
+ }
+
+ break;
+ case IE_FH_PARM:
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
+ break;
+
+ case IE_DS_PARM:
+ if(pEid->Len == 1)
+ {
+ *pChannel = *pEid->Octet;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (ChannelSanity(pAd, *pChannel) == 0)
+ {
+
+ return FALSE;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+ Sanity |= 0x4;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",pEid->Len));
+ return FALSE;
+ }
+ break;
+
+ case IE_CF_PARM:
+ if(pEid->Len == 6)
+ {
+ pCfParm->bValid = TRUE;
+ pCfParm->CfpCount = pEid->Octet[0];
+ pCfParm->CfpPeriod = pEid->Octet[1];
+ pCfParm->CfpMaxDuration = pEid->Octet[2] + 256 * pEid->Octet[3];
+ pCfParm->CfpDurRemaining = pEid->Octet[4] + 256 * pEid->Octet[5];
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
+ return FALSE;
+ }
+ break;
+
+ case IE_IBSS_PARM:
+ if(pEid->Len == 2)
+ {
+ NdisMoveMemory(pAtimWin, pEid->Octet, pEid->Len);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
+ return FALSE;
+ }
+ break;
+
+#ifdef CONFIG_STA_SUPPORT
+ case IE_TIM:
+ if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON)
+ {
+ GetTimBit((PUCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe);
+ }
+ break;
+#endif // CONFIG_STA_SUPPORT //
+ case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
+ if(pEid->Len == 3)
+ {
+ *pNewChannel = pEid->Octet[1]; //extract new channel number
+ }
+ break;
+
+ // New for WPA
+ // CCX v2 has the same IE, we need to parse that too
+ // Wifi WMM use the same IE vale, need to parse that too
+ // case IE_WPA:
+ case IE_VENDOR_SPECIFIC:
+ // Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE.
+ // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
+ /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4))
+ {
+ if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30))
+ {
+ {
+ NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
+ *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
+ }
+ }
+ if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26))
+ {
+ {
+ NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
+ *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; // Nnow we only support 26 bytes.
+ }
+ }
+ }
+ */
+ // Check the OUI version, filter out non-standard usage
+ if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7))
+ {
+ //*pRalinkIe = pEid->Octet[3];
+ if (pEid->Octet[3] != 0)
+ *pRalinkIe = pEid->Octet[3];
+ else
+ *pRalinkIe = 0xf0000000; // Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag.
+ }
+#ifdef CONFIG_STA_SUPPORT
+#ifdef DOT11_N_SUPPORT
+ // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
+
+ // Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP,
+ // Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE
+ else if ((*pHtCapabilityLen == 0) && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI, 3) && (pEid->Len >= 4) && (pAd->OpMode == OPMODE_STA))
+ {
+ if ((pEid->Octet[3] == OUI_PREN_HT_CAP) && (pEid->Len >= 30) && (*pHtCapabilityLen == 0))
+ {
+ NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
+ *pPreNHtCapabilityLen = SIZE_HT_CAP_IE;
+ }
+
+ if ((pEid->Octet[3] == OUI_PREN_ADD_HT) && (pEid->Len >= 26))
+ {
+ NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
+ *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+ else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
+ {
+ // Copy to pVIE which will report to microsoft bssid list.
+ Ptr = (PUCHAR) pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ }
+ else if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
+ {
+ PUCHAR ptr;
+ int i;
+
+ // parsing EDCA parameters
+ pEdcaParm->bValid = TRUE;
+ pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
+ pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
+ pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
+ pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
+ pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
+ ptr = &pEid->Octet[8];
+ for (i=0; i<4; i++)
+ {
+ UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
+ pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); // b5 is ACM
+ pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; // b0~3 is AIFSN
+ pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f; // b0~4 is Cwmin
+ pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4; // b5~8 is Cwmax
+ pEdcaParm->Txop[aci] = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
+ ptr += 4; // point to next AC
+ }
+ }
+ else if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) && (pEid->Len == 7))
+ {
+ // parsing EDCA parameters
+ pEdcaParm->bValid = TRUE;
+ pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
+ pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
+ pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
+ pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
+ pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
+
+ // use default EDCA parameter
+ pEdcaParm->bACM[QID_AC_BE] = 0;
+ pEdcaParm->Aifsn[QID_AC_BE] = 3;
+ pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
+ pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
+ pEdcaParm->Txop[QID_AC_BE] = 0;
+
+ pEdcaParm->bACM[QID_AC_BK] = 0;
+ pEdcaParm->Aifsn[QID_AC_BK] = 7;
+ pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
+ pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
+ pEdcaParm->Txop[QID_AC_BK] = 0;
+
+ pEdcaParm->bACM[QID_AC_VI] = 0;
+ pEdcaParm->Aifsn[QID_AC_VI] = 2;
+ pEdcaParm->Cwmin[QID_AC_VI] = CW_MIN_IN_BITS-1;
+ pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
+ pEdcaParm->Txop[QID_AC_VI] = 96; // AC_VI: 96*32us ~= 3ms
+
+ pEdcaParm->bACM[QID_AC_VO] = 0;
+ pEdcaParm->Aifsn[QID_AC_VO] = 2;
+ pEdcaParm->Cwmin[QID_AC_VO] = CW_MIN_IN_BITS-2;
+ pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1;
+ pEdcaParm->Txop[QID_AC_VO] = 48; // AC_VO: 48*32us ~= 1.5ms
+ }
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+ else
+ {
+ }
+
+ break;
+
+ case IE_EXT_SUPP_RATES:
+ if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
+ *pExtRateLen = pEid->Len;
+
+ // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
+ // from ScanTab. We should report as is. And filter out unsupported
+ // rates in MlmeAux.
+ // Check against the supported rates
+ // RTMPCheckRates(pAd, ExtRate, pExtRateLen);
+ }
+ break;
+
+ case IE_ERP:
+ if (pEid->Len == 1)
+ {
+ *pErp = (UCHAR)pEid->Octet[0];
+ }
+ break;
+
+ case IE_AIRONET_CKIP:
+ // 0. Check Aironet IE length, it must be larger or equal to 28
+ // Cisco AP350 used length as 28
+ // Cisco AP12XX used length as 30
+ if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
+ break;
+
+ // 1. Copy CKIP flag byte to buffer for process
+ *pCkipFlag = *(pEid->Octet + 8);
+ break;
+
+ case IE_AP_TX_POWER:
+ // AP Control of Client Transmit Power
+ //0. Check Aironet IE length, it must be 6
+ if (pEid->Len != 0x06)
+ break;
+
+ // Get cell power limit in dBm
+ if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
+ *pAironetCellPowerLimit = *(pEid->Octet + 4);
+ break;
+
+ // WPA2 & 802.11i RSN
+ case IE_RSN:
+ // There is no OUI for version anymore, check the group cipher OUI before copying
+ if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
+ {
+ // Copy to pVIE which will report to microsoft bssid list.
+ Ptr = (PUCHAR) pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ }
+ break;
+#ifdef CONFIG_STA_SUPPORT
+#ifdef EXT_BUILD_CHANNEL_LIST
+ case IE_COUNTRY:
+ Ptr = (PUCHAR) pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ break;
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+ default:
+ break;
+ }
+
+ Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len]
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+ }
+
+ // For some 11a AP. it did not have the channel EID, patch here
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ UCHAR LatchRfChannel = MsgChannel;
+ if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0))
+ {
+ if (CtrlChannel != 0)
+ *pChannel = CtrlChannel;
+ else
+ *pChannel = LatchRfChannel;
+ Sanity |= 0x4;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ if (Sanity != 0x7)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity));
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+
+}
+
+#ifdef DOT11N_DRAFT3
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check for some IE addressed in 802.11n d3.03.
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerBeaconAndProbeRspSanity2(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT UCHAR *RegClass)
+{
+ CHAR *Ptr;
+ PFRAME_802_11 pFrame;
+ PEID_STRUCT pEid;
+ ULONG Length = 0;
+
+ pFrame = (PFRAME_802_11)Msg;
+
+ *RegClass = 0;
+ Ptr = pFrame->Octet;
+ Length += LENGTH_802_11;
+
+ // get timestamp from payload and advance the pointer
+ Ptr += TIMESTAMP_LEN;
+ Length += TIMESTAMP_LEN;
+
+ // get beacon interval from payload and advance the pointer
+ Ptr += 2;
+ Length += 2;
+
+ // get capability info from payload and advance the pointer
+ Ptr += 2;
+ Length += 2;
+
+ pEid = (PEID_STRUCT) Ptr;
+
+ // get variable fields from payload and advance the pointer
+ while ((Length + 2 + pEid->Len) <= MsgLen)
+ {
+ switch(pEid->Eid)
+ {
+ case IE_SUPP_REG_CLASS:
+ if(pEid->Len > 0)
+ {
+ *RegClass = *pEid->Octet;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
+ return FALSE;
+ }
+ break;
+ }
+
+ Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len]
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+ }
+
+ return TRUE;
+
+}
+#endif // DOT11N_DRAFT3 //
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+ */
+BOOLEAN MlmeScanReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT UCHAR *pBssType,
+ OUT CHAR Ssid[],
+ OUT UCHAR *pSsidLen,
+ OUT UCHAR *pScanType)
+{
+ MLME_SCAN_REQ_STRUCT *Info;
+
+ Info = (MLME_SCAN_REQ_STRUCT *)(Msg);
+ *pBssType = Info->BssType;
+ *pSsidLen = Info->SsidLen;
+ NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
+ *pScanType = Info->ScanType;
+
+ if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY)
+ && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE
+#ifdef CONFIG_STA_SUPPORT
+ || *pScanType == SCAN_CISCO_PASSIVE || *pScanType == SCAN_CISCO_ACTIVE
+ || *pScanType == SCAN_CISCO_CHANNEL_LOAD || *pScanType == SCAN_CISCO_NOISE
+#endif // CONFIG_STA_SUPPORT //
+ ))
+ {
+ return TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
+ return FALSE;
+ }
+}
+
+// IRQL = DISPATCH_LEVEL
+UCHAR ChannelSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel)
+{
+ int i;
+
+ for (i = 0; i < pAd->ChannelListNum; i ++)
+ {
+ if (channel == pAd->ChannelList[i].Channel)
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerDeauthSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *pReason)
+{
+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+
+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+ NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerAuthSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr,
+ OUT USHORT *pAlg,
+ OUT USHORT *pSeq,
+ OUT USHORT *pStatus,
+ CHAR *pChlgText)
+{
+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+
+ COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2);
+ NdisMoveMemory(pAlg, &pFrame->Octet[0], 2);
+ NdisMoveMemory(pSeq, &pFrame->Octet[2], 2);
+ NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
+
+ if ((*pAlg == Ndis802_11AuthModeOpen)
+#ifdef LEAP_SUPPORT
+ || (*pAlg == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+ )
+ {
+ if (*pSeq == 1 || *pSeq == 2)
+ {
+ return TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
+ return FALSE;
+ }
+ }
+ else if (*pAlg == Ndis802_11AuthModeShared)
+ {
+ if (*pSeq == 1 || *pSeq == 4)
+ {
+ return TRUE;
+ }
+ else if (*pSeq == 2 || *pSeq == 3)
+ {
+ NdisMoveMemory(pChlgText, &pFrame->Octet[8], CIPHER_TEXT_LEN);
+ return TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
+ return FALSE;
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong algorithm\n"));
+ return FALSE;
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+ */
+BOOLEAN MlmeAuthReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr,
+ OUT ULONG *pTimeout,
+ OUT USHORT *pAlg)
+{
+ MLME_AUTH_REQ_STRUCT *pInfo;
+
+ pInfo = (MLME_AUTH_REQ_STRUCT *)Msg;
+ COPY_MAC_ADDR(pAddr, pInfo->Addr);
+ *pTimeout = pInfo->Timeout;
+ *pAlg = pInfo->Alg;
+
+ if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen)
+#ifdef LEAP_SUPPORT
+ || (*pAlg == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+ ) &&
+ ((*pAddr & 0x01) == 0))
+ {
+ return TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAuthReqSanity fail - wrong algorithm\n"));
+ return FALSE;
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN MlmeAssocReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pApAddr,
+ OUT USHORT *pCapabilityInfo,
+ OUT ULONG *pTimeout,
+ OUT USHORT *pListenIntv)
+{
+ MLME_ASSOC_REQ_STRUCT *pInfo;
+
+ pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg;
+ *pTimeout = pInfo->Timeout; // timeout
+ COPY_MAC_ADDR(pApAddr, pInfo->Addr); // AP address
+ *pCapabilityInfo = pInfo->CapabilityInfo; // capability info
+ *pListenIntv = pInfo->ListenIntv;
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerDisassocSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *pReason)
+{
+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+
+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+ NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
+
+ return TRUE;
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Sanity check NetworkType (11b, 11g or 11a)
+
+ Arguments:
+ pBss - Pointer to BSS table.
+
+ Return Value:
+ Ndis802_11DS .......(11b)
+ Ndis802_11OFDM24....(11g)
+ Ndis802_11OFDM5.....(11a)
+
+ IRQL = DISPATCH_LEVEL
+
+ ========================================================================
+*/
+NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
+ IN PBSS_ENTRY pBss)
+{
+ NDIS_802_11_NETWORK_TYPE NetWorkType;
+ UCHAR rate, i;
+
+ NetWorkType = Ndis802_11DS;
+
+ if (pBss->Channel <= 14)
+ {
+ //
+ // First check support Rate.
+ //
+ for (i = 0; i < pBss->SupRateLen; i++)
+ {
+ rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
+ if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
+ {
+ continue;
+ }
+ else
+ {
+ //
+ // Otherwise (even rate > 108) means Ndis802_11OFDM24
+ //
+ NetWorkType = Ndis802_11OFDM24;
+ break;
+ }
+ }
+
+ //
+ // Second check Extend Rate.
+ //
+ if (NetWorkType != Ndis802_11OFDM24)
+ {
+ for (i = 0; i < pBss->ExtRateLen; i++)
+ {
+ rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
+ if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
+ {
+ continue;
+ }
+ else
+ {
+ //
+ // Otherwise (even rate > 108) means Ndis802_11OFDM24
+ //
+ NetWorkType = Ndis802_11OFDM24;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ NetWorkType = Ndis802_11OFDM5;
+ }
+
+ if (pBss->HtCapabilityLen != 0)
+ {
+ if (NetWorkType == Ndis802_11OFDM5)
+ NetWorkType = Ndis802_11OFDM5_N;
+ else
+ NetWorkType = Ndis802_11OFDM24_N;
+ }
+
+ return NetWorkType;
+}
+
+/*
+ ==========================================================================
+ Description:
+ WPA message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+ */
+BOOLEAN PeerWpaMessageSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN PEAPOL_PACKET pMsg,
+ IN ULONG MsgLen,
+ IN UCHAR MsgType,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ UCHAR mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE];
+ BOOLEAN bReplayDiff = FALSE;
+ BOOLEAN bWPA2 = FALSE;
+ KEY_INFO EapolKeyInfo;
+ UCHAR GroupKeyIndex = 0;
+
+
+ NdisZeroMemory(mic, sizeof(mic));
+ NdisZeroMemory(digest, sizeof(digest));
+ NdisZeroMemory(KEYDATA, sizeof(KEYDATA));
+ NdisZeroMemory((PUCHAR)&EapolKeyInfo, sizeof(EapolKeyInfo));
+
+ NdisMoveMemory((PUCHAR)&EapolKeyInfo, (PUCHAR)&pMsg->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+ *((USHORT *)&EapolKeyInfo) = cpu2le16(*((USHORT *)&EapolKeyInfo));
+
+ // Choose WPA2 or not
+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+ bWPA2 = TRUE;
+
+ // 0. Check MsgType
+ if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("The message type is invalid(%d)! \n", MsgType));
+ return FALSE;
+ }
+
+ // 1. Replay counter check
+ if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1) // For supplicant
+ {
+ // First validate replay counter, only accept message with larger replay counter.
+ // Let equal pass, some AP start with all zero replay counter
+ UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
+
+ NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
+ if ((RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY) != 1) &&
+ (RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
+ {
+ bReplayDiff = TRUE;
+ }
+ }
+ else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) // For authenticator
+ {
+ // check Replay Counter coresponds to MSG from authenticator, otherwise discard
+ if (!NdisEqualMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
+ {
+ bReplayDiff = TRUE;
+ }
+ }
+
+ // Replay Counter different condition
+ if (bReplayDiff)
+ {
+ // send wireless event - for replay counter different
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+ if (MsgType < EAPOL_GROUP_MSG_1)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
+ }
+
+ hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+ hex_dump("Current replay counter ", pEntry->R_Counter, LEN_KEY_DESC_REPLAY);
+ return FALSE;
+ }
+
+ // 2. Verify MIC except Pairwise Msg1
+ if (MsgType != EAPOL_PAIR_MSG_1)
+ {
+ UCHAR rcvd_mic[LEN_KEY_DESC_MIC];
+
+ // Record the received MIC for check later
+ NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+
+ if (pEntry->WepStatus == Ndis802_11Encryption2Enabled) // TKIP
+ {
+ hmac_md5(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, mic);
+ }
+ else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled) // AES
+ {
+ HMAC_SHA1((PUCHAR)pMsg, MsgLen, pEntry->PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
+ }
+
+ if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC))
+ {
+ // send wireless event - for MIC different
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_MIC_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+ if (MsgType < EAPOL_GROUP_MSG_1)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
+ }
+
+ hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC);
+ hex_dump("Desired MIC", mic, LEN_KEY_DESC_MIC);
+
+ return FALSE;
+ }
+ }
+
+ // Extract the context of the Key Data field if it exist
+ // The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is un-encrypted.
+ // The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.
+ if (pMsg->KeyDesc.KeyDataLen[1] > 0)
+ {
+ // Decrypt this field
+ if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
+ {
+ if(pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA, pMsg->KeyDesc.KeyDataLen[1],pMsg->KeyDesc.KeyData);
+ }
+ else
+ {
+ INT i;
+ UCHAR Key[32];
+ // Decrypt TKIP GTK
+ // Construct 32 bytes RC4 Key
+ NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16);
+ NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16);
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
+ //discard first 256 bytes
+ for(i = 0; i < 256; i++)
+ ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
+ // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
+ ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
+ }
+
+ if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
+ GroupKeyIndex = EapolKeyInfo.KeyIndex;
+
+ }
+ else if ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2))
+ {
+ NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
+ }
+ else
+ {
+
+ return TRUE;
+ }
+
+ // Parse Key Data field to
+ // 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2)
+ // 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2
+ // 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2)
+ if (!RTMPParseEapolKeyData(pAd, KEYDATA, pMsg->KeyDesc.KeyDataLen[1], GroupKeyIndex, MsgType, bWPA2, pEntry))
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+
+}
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+BOOLEAN MlmeDlsReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PRT_802_11_DLS *pDLS,
+ OUT PUSHORT pReason)
+{
+ MLME_DLS_REQ_STRUCT *pInfo;
+
+ pInfo = (MLME_DLS_REQ_STRUCT *)Msg;
+
+ *pDLS = pInfo->pDLS;
+ *pReason = pInfo->Reason;
+
+ return TRUE;
+}
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef QOS_DLS_SUPPORT
+BOOLEAN PeerDlsReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pDA,
+ OUT PUCHAR pSA,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pDlsTimeout,
+ OUT UCHAR *pRatesLen,
+ OUT UCHAR Rates[],
+ OUT UCHAR *pHtCapabilityLen,
+ OUT HT_CAPABILITY_IE *pHtCapability)
+{
+ CHAR *Ptr;
+ PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
+ PEID_STRUCT eid_ptr;
+
+ // to prevent caller from using garbage output value
+ *pCapabilityInfo = 0;
+ *pDlsTimeout = 0;
+ *pHtCapabilityLen = 0;
+
+ Ptr = Fr->Octet;
+
+ // offset to destination MAC address (Category and Action field)
+ Ptr += 2;
+
+ // get DA from payload and advance the pointer
+ NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
+ Ptr += MAC_ADDR_LEN;
+
+ // get SA from payload and advance the pointer
+ NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
+ Ptr += MAC_ADDR_LEN;
+
+ // get capability info from payload and advance the pointer
+ NdisMoveMemory(pCapabilityInfo, Ptr, 2);
+ Ptr += 2;
+
+ // get capability info from payload and advance the pointer
+ NdisMoveMemory(pDlsTimeout, Ptr, 2);
+ Ptr += 2;
+
+ // Category and Action field + DA + SA + capability + Timeout
+ eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
+
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_SUPP_RATES:
+ if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
+ {
+ NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
+ DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7]));
+ *pRatesLen = eid_ptr->Len;
+ }
+ else
+ {
+ *pRatesLen = 8;
+ Rates[0] = 0x82;
+ Rates[1] = 0x84;
+ Rates[2] = 0x8b;
+ Rates[3] = 0x96;
+ Rates[4] = 0x12;
+ Rates[5] = 0x24;
+ Rates[6] = 0x48;
+ Rates[7] = 0x6c;
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
+ }
+ break;
+
+ case IE_EXT_SUPP_RATES:
+ if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
+ *pRatesLen = (*pRatesLen) + eid_ptr->Len;
+ }
+ else
+ {
+ NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
+ *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
+ }
+ break;
+
+ case IE_HT_CAP:
+ if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
+ {
+ NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
+
+ *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
+ *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+ *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_HT_CAP\n"));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return TRUE;
+}
+
+BOOLEAN PeerDlsRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pDA,
+ OUT PUCHAR pSA,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pStatus,
+ OUT UCHAR *pRatesLen,
+ OUT UCHAR Rates[],
+ OUT UCHAR *pHtCapabilityLen,
+ OUT HT_CAPABILITY_IE *pHtCapability)
+{
+ CHAR *Ptr;
+ PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
+ PEID_STRUCT eid_ptr;
+
+ // to prevent caller from using garbage output value
+ *pStatus = 0;
+ *pCapabilityInfo = 0;
+ *pHtCapabilityLen = 0;
+
+ Ptr = Fr->Octet;
+
+ // offset to destination MAC address (Category and Action field)
+ Ptr += 2;
+
+ // get status code from payload and advance the pointer
+ NdisMoveMemory(pStatus, Ptr, 2);
+ Ptr += 2;
+
+ // get DA from payload and advance the pointer
+ NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
+ Ptr += MAC_ADDR_LEN;
+
+ // get SA from payload and advance the pointer
+ NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
+ Ptr += MAC_ADDR_LEN;
+
+ if (pStatus == 0)
+ {
+ // get capability info from payload and advance the pointer
+ NdisMoveMemory(pCapabilityInfo, Ptr, 2);
+ Ptr += 2;
+ }
+
+ // Category and Action field + status code + DA + SA + capability
+ eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
+
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_SUPP_RATES:
+ if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
+ {
+ NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
+ DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7]));
+ *pRatesLen = eid_ptr->Len;
+ }
+ else
+ {
+ *pRatesLen = 8;
+ Rates[0] = 0x82;
+ Rates[1] = 0x84;
+ Rates[2] = 0x8b;
+ Rates[3] = 0x96;
+ Rates[4] = 0x12;
+ Rates[5] = 0x24;
+ Rates[6] = 0x48;
+ Rates[7] = 0x6c;
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
+ }
+ break;
+
+ case IE_EXT_SUPP_RATES:
+ if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
+ *pRatesLen = (*pRatesLen) + eid_ptr->Len;
+ }
+ else
+ {
+ NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
+ *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
+ }
+ break;
+
+ case IE_HT_CAP:
+ if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
+ {
+ NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
+
+ *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
+ *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+ *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_HT_CAP\n"));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return TRUE;
+}
+
+BOOLEAN PeerDlsTearDownSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pDA,
+ OUT PUCHAR pSA,
+ OUT USHORT *pReason)
+{
+ CHAR *Ptr;
+ PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
+
+ // to prevent caller from using garbage output value
+ *pReason = 0;
+
+ Ptr = Fr->Octet;
+
+ // offset to destination MAC address (Category and Action field)
+ Ptr += 2;
+
+ // get DA from payload and advance the pointer
+ NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
+ Ptr += MAC_ADDR_LEN;
+
+ // get SA from payload and advance the pointer
+ NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
+ Ptr += MAC_ADDR_LEN;
+
+ // get reason code from payload and advance the pointer
+ NdisMoveMemory(pReason, Ptr, 2);
+ Ptr += 2;
+
+ return TRUE;
+}
+#endif // QOS_DLS_SUPPORT //
+
diff --git a/drivers/staging/rt3070/common/cmm_sync.c b/drivers/staging/rt3070/common/cmm_sync.c
new file mode 100644
index 00000000000..2be7c77a384
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_sync.c
@@ -0,0 +1,711 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ sync.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2004-09-01 modified for rt2561/2661
+*/
+#include "../rt_config.h"
+
+// 2.4 Ghz channel plan index in the TxPower arrays.
+#define BG_BAND_REGION_0_START 0 // 1,2,3,4,5,6,7,8,9,10,11
+#define BG_BAND_REGION_0_SIZE 11
+#define BG_BAND_REGION_1_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13
+#define BG_BAND_REGION_1_SIZE 13
+#define BG_BAND_REGION_2_START 9 // 10,11
+#define BG_BAND_REGION_2_SIZE 2
+#define BG_BAND_REGION_3_START 9 // 10,11,12,13
+#define BG_BAND_REGION_3_SIZE 4
+#define BG_BAND_REGION_4_START 13 // 14
+#define BG_BAND_REGION_4_SIZE 1
+#define BG_BAND_REGION_5_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
+#define BG_BAND_REGION_5_SIZE 14
+#define BG_BAND_REGION_6_START 2 // 3,4,5,6,7,8,9
+#define BG_BAND_REGION_6_SIZE 7
+#define BG_BAND_REGION_7_START 4 // 5,6,7,8,9,10,11,12,13
+#define BG_BAND_REGION_7_SIZE 9
+#define BG_BAND_REGION_31_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
+#define BG_BAND_REGION_31_SIZE 14
+
+// 5 Ghz channel plan index in the TxPower arrays.
+UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_1_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64};
+UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
+UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
+UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
+UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
+UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161};
+
+//BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.
+UCHAR BaSizeArray[4] = {8,16,32,64};
+
+/*
+ ==========================================================================
+ Description:
+ Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
+ and 3) PHY-mode user selected.
+ The outcome is used by driver when doing site survey.
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID BuildChannelList(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR i, j, index=0, num=0;
+ PUCHAR pChannelList = NULL;
+
+ NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER));
+
+ // if not 11a-only mode, channel list starts from 2.4Ghz band
+ if ((pAd->CommonCfg.PhyMode != PHY_11A)
+#ifdef DOT11_N_SUPPORT
+ && (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ switch (pAd->CommonCfg.CountryRegion & 0x7f)
+ {
+ case REGION_0_BG_BAND: // 1 -11
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE);
+ index += BG_BAND_REGION_0_SIZE;
+ break;
+ case REGION_1_BG_BAND: // 1 - 13
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE);
+ index += BG_BAND_REGION_1_SIZE;
+ break;
+ case REGION_2_BG_BAND: // 10 - 11
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE);
+ index += BG_BAND_REGION_2_SIZE;
+ break;
+ case REGION_3_BG_BAND: // 10 - 13
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE);
+ index += BG_BAND_REGION_3_SIZE;
+ break;
+ case REGION_4_BG_BAND: // 14
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE);
+ index += BG_BAND_REGION_4_SIZE;
+ break;
+ case REGION_5_BG_BAND: // 1 - 14
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE);
+ index += BG_BAND_REGION_5_SIZE;
+ break;
+ case REGION_6_BG_BAND: // 3 - 9
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE);
+ index += BG_BAND_REGION_6_SIZE;
+ break;
+ case REGION_7_BG_BAND: // 5 - 13
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_7_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_7_SIZE);
+ index += BG_BAND_REGION_7_SIZE;
+ break;
+ case REGION_31_BG_BAND: // 1 - 14
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_31_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_31_SIZE);
+ index += BG_BAND_REGION_31_SIZE;
+ break;
+ default: // Error. should never happen
+ break;
+ }
+ for (i=0; i<index; i++)
+ pAd->ChannelList[i].MaxTxPwr = 20;
+ }
+
+ if ((pAd->CommonCfg.PhyMode == PHY_11A) || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
+#ifdef DOT11_N_SUPPORT
+ || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
+ || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ switch (pAd->CommonCfg.CountryRegionForABand & 0x7f)
+ {
+ case REGION_0_A_BAND:
+ num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
+ break;
+ case REGION_1_A_BAND:
+ num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
+ break;
+ case REGION_2_A_BAND:
+ num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
+ break;
+ case REGION_3_A_BAND:
+ num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
+ break;
+ case REGION_4_A_BAND:
+ num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
+ break;
+ case REGION_5_A_BAND:
+ num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
+ break;
+ case REGION_6_A_BAND:
+ num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
+ break;
+ case REGION_7_A_BAND:
+ num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
+ break;
+ case REGION_8_A_BAND:
+ num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
+ break;
+ case REGION_9_A_BAND:
+ num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
+ break;
+
+ case REGION_10_A_BAND:
+ num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
+ break;
+
+ case REGION_11_A_BAND:
+ num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
+ break;
+
+ default: // Error. should never happen
+ DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand));
+ break;
+ }
+
+ if (num != 0)
+ {
+ UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+ for (i=0; i<num; i++)
+ {
+ for (j=0; j<MAX_NUM_OF_CHANNELS; j++)
+ {
+ if (pChannelList[i] == pAd->TxPower[j].Channel)
+ NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER));
+ }
+ for (j=0; j<15; j++)
+ {
+ if (pChannelList[i] == RadarCh[j])
+ pAd->ChannelList[index+i].DfsReq = TRUE;
+ }
+ pAd->ChannelList[index+i].MaxTxPwr = 20;
+ }
+ index += num;
+ }
+ }
+
+ pAd->ChannelListNum = index;
+ DBGPRINT(RT_DEBUG_TRACE,("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
+ pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
+#ifdef DBG
+ for (i=0;i<pAd->ChannelListNum;i++)
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2));
+ }
+#endif
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine return the first channel number according to the country
+ code selection and RF IC selection (signal band or dual band). It is called
+ whenever driver need to start a site survey of all supported channels.
+ Return:
+ ch - the first channel number of current country code setting
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+UCHAR FirstChannel(
+ IN PRTMP_ADAPTER pAd)
+{
+ return pAd->ChannelList[0].Channel;
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine returns the next channel number. This routine is called
+ during driver need to start a site survey of all supported channels.
+ Return:
+ next_channel - the next channel number valid in current country code setting.
+ Note:
+ return 0 if no more next channel
+ ==========================================================================
+ */
+UCHAR NextChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel)
+{
+ int i;
+ UCHAR next_channel = 0;
+
+ for (i = 0; i < (pAd->ChannelListNum - 1); i++)
+ if (channel == pAd->ChannelList[i].Channel)
+ {
+ next_channel = pAd->ChannelList[i+1].Channel;
+ break;
+ }
+ return next_channel;
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine is for Cisco Compatible Extensions 2.X
+ Spec31. AP Control of Client Transmit Power
+ Return:
+ None
+ Note:
+ Required by Aironet dBm(mW)
+ 0dBm(1mW), 1dBm(5mW), 13dBm(20mW), 15dBm(30mW),
+ 17dBm(50mw), 20dBm(100mW)
+
+ We supported
+ 3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%),
+ 14dBm(75%), 15dBm(100%)
+
+ The client station's actual transmit power shall be within +/- 5dB of
+ the minimum value or next lower value.
+ ==========================================================================
+ */
+VOID ChangeToCellPowerLimit(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR AironetCellPowerLimit)
+{
+ //valud 0xFF means that hasn't found power limit information
+ //from the AP's Beacon/Probe response.
+ if (AironetCellPowerLimit == 0xFF)
+ return;
+
+ if (AironetCellPowerLimit < 6) //Used Lowest Power Percentage.
+ pAd->CommonCfg.TxPowerPercentage = 6;
+ else if (AironetCellPowerLimit < 9)
+ pAd->CommonCfg.TxPowerPercentage = 10;
+ else if (AironetCellPowerLimit < 12)
+ pAd->CommonCfg.TxPowerPercentage = 25;
+ else if (AironetCellPowerLimit < 14)
+ pAd->CommonCfg.TxPowerPercentage = 50;
+ else if (AironetCellPowerLimit < 15)
+ pAd->CommonCfg.TxPowerPercentage = 75;
+ else
+ pAd->CommonCfg.TxPowerPercentage = 100; //else used maximum
+
+ if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
+ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+
+}
+
+CHAR ConvertToRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi,
+ IN UCHAR RssiNumber)
+{
+ UCHAR RssiOffset, LNAGain;
+
+ // Rssi equals to zero should be an invalid value
+ if (Rssi == 0)
+ return -99;
+
+ LNAGain = GET_LNA_GAIN(pAd);
+ if (pAd->LatchRfRegs.Channel > 14)
+ {
+ if (RssiNumber == 0)
+ RssiOffset = pAd->ARssiOffset0;
+ else if (RssiNumber == 1)
+ RssiOffset = pAd->ARssiOffset1;
+ else
+ RssiOffset = pAd->ARssiOffset2;
+ }
+ else
+ {
+ if (RssiNumber == 0)
+ RssiOffset = pAd->BGRssiOffset0;
+ else if (RssiNumber == 1)
+ RssiOffset = pAd->BGRssiOffset1;
+ else
+ RssiOffset = pAd->BGRssiOffset2;
+ }
+
+ return (-12 - RssiOffset - LNAGain - Rssi);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Scan next channel
+ ==========================================================================
+ */
+VOID ScanNextChannel(
+ IN PRTMP_ADAPTER pAd)
+{
+ HEADER_802_11 Hdr80211;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ UCHAR SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
+#ifdef CONFIG_STA_SUPPORT
+ USHORT Status;
+ PHEADER_802_11 pHdr80211;
+#endif // CONFIG_STA_SUPPORT //
+ UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (MONITOR_ON(pAd))
+ return;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RALINK_ATE
+ // Nothing to do in ATE mode.
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ if (pAd->MlmeAux.Channel == 0)
+ {
+ if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
+#ifdef CONFIG_STA_SUPPORT
+ && (INFRA_ON(pAd)
+ || (pAd->OpMode == OPMODE_AP))
+#endif // CONFIG_STA_SUPPORT //
+ )
+ {
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= (~0x18);
+ BBPValue |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
+ }
+ else
+ {
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ //
+ // To prevent data lost.
+ // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
+ // Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done
+ //
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
+ {
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
+ if (NStatus == NDIS_STATUS_SUCCESS)
+ {
+ pHdr80211 = (PHEADER_802_11) pOutBuffer;
+ MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+ pHdr80211->Duration = 0;
+ pHdr80211->FC.Type = BTYPE_DATA;
+ pHdr80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
+
+ // Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame\n"));
+ MlmeFreeMemory(pAd, pOutBuffer);
+ RTMPusecDelay(5000);
+ }
+ }
+
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+ }
+#ifdef RT2870
+#ifdef CONFIG_STA_SUPPORT
+ else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA))
+ {
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
+ }
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT2870 //
+ else
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // BBP and RF are not accessible in PS mode, we has to wake them up first
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ AsicForceWakeup(pAd, TRUE);
+
+ // leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
+ if (pAd->StaCfg.Psm == PWR_SAVE)
+ MlmeSetPsmBit(pAd, PWR_ACTIVE);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
+ AsicLockChannel(pAd, pAd->MlmeAux.Channel);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pAd->MlmeAux.Channel > 14)
+ {
+ if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
+ {
+ ScanType = SCAN_PASSIVE;
+ ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
+ }
+ }
+
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+ // carrier detection
+ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+ {
+ ScanType = SCAN_PASSIVE;
+ ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
+ }
+#endif // CARRIER_DETECTION_SUPPORT //
+ }
+
+#endif // CONFIG_STA_SUPPORT //
+
+ //Global country domain(ch1-11:active scan, ch12-14 passive scan)
+ if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) && ((pAd->CommonCfg.CountryRegion & 0x7f) == REGION_31_BG_BAND))
+ {
+ ScanType = SCAN_PASSIVE;
+ }
+
+ // We need to shorten active scan time in order for WZC connect issue
+ // Chnage the channel scan time for CISCO stuff based on its IAPP announcement
+ if (ScanType == FAST_SCAN_ACTIVE)
+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
+#ifdef CONFIG_STA_SUPPORT
+ else if (((ScanType == SCAN_CISCO_ACTIVE) ||
+ (ScanType == SCAN_CISCO_PASSIVE) ||
+ (ScanType == SCAN_CISCO_CHANNEL_LOAD) ||
+ (ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA))
+ {
+ if (pAd->StaCfg.CCXScanTime < 25)
+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2);
+ else
+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ else // must be SCAN_PASSIVE or SCAN_ACTIVE
+ {
+ if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
+#ifdef DOT11_N_SUPPORT
+ || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ if (pAd->MlmeAux.Channel > 14)
+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel);
+ else
+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME);
+ }
+ else
+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
+ }
+
+ if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) ||
+ (ScanType == SCAN_CISCO_ACTIVE))
+ {
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ return;
+ }
+
+ // There is no need to send broadcast probe request if active scan is in effect.
+ if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
+ )
+ SsidLen = pAd->MlmeAux.SsidLen;
+ else
+ SsidLen = 0;
+
+ MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &Hdr80211,
+ 1, &SsidIe,
+ 1, &SsidLen,
+ SsidLen, pAd->MlmeAux.Ssid,
+ 1, &SupRateIe,
+ 1, &pAd->CommonCfg.SupRateLen,
+ pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRate,
+ END_OF_ARGS);
+
+ if (pAd->CommonCfg.ExtRateLen)
+ {
+ ULONG Tmp;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &ExtRateIe,
+ 1, &pAd->CommonCfg.ExtRateLen,
+ pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate,
+ END_OF_ARGS);
+ FrameLen += Tmp;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ {
+ ULONG Tmp;
+ UCHAR HtLen;
+ UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+#endif
+ if (pAd->bBroadComHT == TRUE)
+ {
+ HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
+#ifdef RT_BIG_ENDIAN
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &WpaIe,
+ 1, &HtLen,
+ 4, &BROADCOM[0],
+ pAd->MlmeAux.HtCapabilityLen, &HtCapabilityTmp,
+ END_OF_ARGS);
+#else
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &WpaIe,
+ 1, &HtLen,
+ 4, &BROADCOM[0],
+ pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
+ END_OF_ARGS);
+#endif // RT_BIG_ENDIAN //
+ }
+ else
+ {
+ HtLen = pAd->MlmeAux.HtCapabilityLen;
+#ifdef RT_BIG_ENDIAN
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE);
+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &HtCapabilityTmp,
+ END_OF_ARGS);
+#else
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &pAd->CommonCfg.HtCapability,
+ END_OF_ARGS);
+#endif // RT_BIG_ENDIAN //
+ }
+ FrameLen += Tmp;
+
+#ifdef DOT11N_DRAFT3
+ if (pAd->CommonCfg.BACapability.field.b2040CoexistScanSup == 1)
+ {
+ ULONG Tmp;
+ HtLen = 1;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &ExtHtCapIe,
+ 1, &HtLen,
+ 1, &pAd->CommonCfg.BSSCoexist2040.word,
+ END_OF_ARGS);
+
+ FrameLen += Tmp;
+ }
+#endif // DOT11N_DRAFT3 //
+ }
+#endif // DOT11_N_SUPPORT //
+
+
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+
+ // For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
+#endif // CONFIG_STA_SUPPORT //
+
+ }
+}
+
+VOID MgtProbReqMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR SubType,
+ IN UCHAR ToDs,
+ IN PUCHAR pDA,
+ IN PUCHAR pBssid)
+{
+ NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+
+ pHdr80211->FC.Type = BTYPE_MGMT;
+ pHdr80211->FC.SubType = SubType;
+ if (SubType == SUBTYPE_ACK)
+ pHdr80211->FC.Type = BTYPE_CNTL;
+ pHdr80211->FC.ToDs = ToDs;
+ COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
+ COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
+}
+
+
diff --git a/drivers/staging/rt3070/common/cmm_wpa.c b/drivers/staging/rt3070/common/cmm_wpa.c
new file mode 100644
index 00000000000..81c332ac252
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_wpa.c
@@ -0,0 +1,1606 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ wpa.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan Lee 03-07-22 Initial
+ Paul Lin 03-11-28 Modify for supplicant
+*/
+#include "../rt_config.h"
+// WPA OUI
+UCHAR OUI_WPA_NONE_AKM[4] = {0x00, 0x50, 0xF2, 0x00};
+UCHAR OUI_WPA_VERSION[4] = {0x00, 0x50, 0xF2, 0x01};
+UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02};
+UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04};
+UCHAR OUI_WPA_8021X_AKM[4] = {0x00, 0x50, 0xF2, 0x01};
+UCHAR OUI_WPA_PSK_AKM[4] = {0x00, 0x50, 0xF2, 0x02};
+// WPA2 OUI
+UCHAR OUI_WPA2_WEP40[4] = {0x00, 0x0F, 0xAC, 0x01};
+UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};
+UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};
+UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01};
+UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02};
+// MSA OUI
+UCHAR OUI_MSA_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x05}; // Not yet final - IEEE 802.11s-D1.06
+UCHAR OUI_MSA_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x06}; // Not yet final - IEEE 802.11s-D1.06
+
+/*
+ ========================================================================
+
+ Routine Description:
+ The pseudo-random function(PRF) that hashes various inputs to
+ derive a pseudo-random value. To add liveness to the pseudo-random
+ value, a nonce should be one of the inputs.
+
+ It is used to generate PTK, GTK or some specific random value.
+
+ Arguments:
+ UCHAR *key, - the key material for HMAC_SHA1 use
+ INT key_len - the length of key
+ UCHAR *prefix - a prefix label
+ INT prefix_len - the length of the label
+ UCHAR *data - a specific data with variable length
+ INT data_len - the length of a specific data
+ INT len - the output lenght
+
+ Return Value:
+ UCHAR *output - the calculated result
+
+ Note:
+ 802.11i-2004 Annex H.3
+
+ ========================================================================
+*/
+VOID PRF(
+ IN UCHAR *key,
+ IN INT key_len,
+ IN UCHAR *prefix,
+ IN INT prefix_len,
+ IN UCHAR *data,
+ IN INT data_len,
+ OUT UCHAR *output,
+ IN INT len)
+{
+ INT i;
+ UCHAR *input;
+ INT currentindex = 0;
+ INT total_len;
+
+ // Allocate memory for input
+ os_alloc_mem(NULL, (PUCHAR *)&input, 1024);
+
+ if (input == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n"));
+ return;
+ }
+
+ // Generate concatenation input
+ NdisMoveMemory(input, prefix, prefix_len);
+
+ // Concatenate a single octet containing 0
+ input[prefix_len] = 0;
+
+ // Concatenate specific data
+ NdisMoveMemory(&input[prefix_len + 1], data, data_len);
+ total_len = prefix_len + 1 + data_len;
+
+ // Concatenate a single octet containing 0
+ // This octet shall be update later
+ input[total_len] = 0;
+ total_len++;
+
+ // Iterate to calculate the result by hmac-sha-1
+ // Then concatenate to last result
+ for (i = 0; i < (len + 19) / 20; i++)
+ {
+ HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
+ currentindex += 20;
+
+ // update the last octet
+ input[total_len - 1]++;
+ }
+ os_free_mem(NULL, input);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
+ It shall be called by 4-way handshake processing.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ PMK - pointer to PMK
+ ANonce - pointer to ANonce
+ AA - pointer to Authenticator Address
+ SNonce - pointer to SNonce
+ SA - pointer to Supplicant Address
+ len - indicate the length of PTK (octet)
+
+ Return Value:
+ Output pointer to the PTK
+
+ Note:
+ Refer to IEEE 802.11i-2004 8.5.1.2
+
+ ========================================================================
+*/
+VOID WpaCountPTK(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR *PMK,
+ IN UCHAR *ANonce,
+ IN UCHAR *AA,
+ IN UCHAR *SNonce,
+ IN UCHAR *SA,
+ OUT UCHAR *output,
+ IN UINT len)
+{
+ UCHAR concatenation[76];
+ UINT CurrPos = 0;
+ UCHAR temp[32];
+ UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
+ 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
+
+ // initiate the concatenation input
+ NdisZeroMemory(temp, sizeof(temp));
+ NdisZeroMemory(concatenation, 76);
+
+ // Get smaller address
+ if (RTMPCompareMemory(SA, AA, 6) == 1)
+ NdisMoveMemory(concatenation, AA, 6);
+ else
+ NdisMoveMemory(concatenation, SA, 6);
+ CurrPos += 6;
+
+ // Get larger address
+ if (RTMPCompareMemory(SA, AA, 6) == 1)
+ NdisMoveMemory(&concatenation[CurrPos], SA, 6);
+ else
+ NdisMoveMemory(&concatenation[CurrPos], AA, 6);
+
+ // store the larger mac address for backward compatible of
+ // ralink proprietary STA-key issue
+ NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
+ CurrPos += 6;
+
+ // Get smaller Nonce
+ if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
+ NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue
+ else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
+ NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
+ else
+ NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
+ CurrPos += 32;
+
+ // Get larger Nonce
+ if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
+ NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue
+ else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
+ NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
+ else
+ NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
+ CurrPos += 32;
+
+ hex_dump("concatenation=", concatenation, 76);
+
+ // Use PRF to generate PTK
+ PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Generate random number by software.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ macAddr - pointer to local MAC address
+
+ Return Value:
+
+ Note:
+ 802.1ii-2004 Annex H.5
+
+ ========================================================================
+*/
+VOID GenRandom(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR *macAddr,
+ OUT UCHAR *random)
+{
+ INT i, curr;
+ UCHAR local[80], KeyCounter[32];
+ UCHAR result[80];
+ ULONG CurrentTime;
+ UCHAR prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
+
+ // Zero the related information
+ NdisZeroMemory(result, 80);
+ NdisZeroMemory(local, 80);
+ NdisZeroMemory(KeyCounter, 32);
+
+ for (i = 0; i < 32; i++)
+ {
+ // copy the local MAC address
+ COPY_MAC_ADDR(local, macAddr);
+ curr = MAC_ADDR_LEN;
+
+ // concatenate the current time
+ NdisGetSystemUpTime(&CurrentTime);
+ NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
+ curr += sizeof(CurrentTime);
+
+ // concatenate the last result
+ NdisMoveMemory(&local[curr], result, 32);
+ curr += 32;
+
+ // concatenate a variable
+ NdisMoveMemory(&local[curr], &i, 2);
+ curr += 2;
+
+ // calculate the result
+ PRF(KeyCounter, 32, prefix,12, local, curr, result, 32);
+ }
+
+ NdisMoveMemory(random, result, 32);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build cipher suite in RSN-IE.
+ It only shall be called by RTMPMakeRSNIE.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ ElementID - indicate the WPA1 or WPA2
+ WepStatus - indicate the encryption type
+ bMixCipher - a boolean to indicate the pairwise cipher and group
+ cipher are the same or not
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+static VOID RTMPInsertRsnIeCipher(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ElementID,
+ IN UINT WepStatus,
+ IN BOOLEAN bMixCipher,
+ IN UCHAR FlexibleCipher,
+ OUT PUCHAR pRsnIe,
+ OUT UCHAR *rsn_len)
+{
+ UCHAR PairwiseCnt;
+
+ *rsn_len = 0;
+
+ // decide WPA2 or WPA1
+ if (ElementID == Wpa2Ie)
+ {
+ RSNIE2 *pRsnie_cipher = (RSNIE2*)pRsnIe;
+
+ // Assign the verson as 1
+ pRsnie_cipher->version = 1;
+
+ switch (WepStatus)
+ {
+ // TKIP mode
+ case Ndis802_11Encryption2Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
+ pRsnie_cipher->ucount = 1;
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
+ *rsn_len = sizeof(RSNIE2);
+ break;
+
+ // AES mode
+ case Ndis802_11Encryption3Enabled:
+ if (bMixCipher)
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
+ else
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4);
+ pRsnie_cipher->ucount = 1;
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
+ *rsn_len = sizeof(RSNIE2);
+ break;
+
+ // TKIP-AES mix mode
+ case Ndis802_11Encryption4Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
+
+ PairwiseCnt = 1;
+ // Insert WPA2 TKIP as the first pairwise cipher
+ if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher))
+ {
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
+ // Insert WPA2 AES as the secondary pairwise cipher
+ if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher))
+ {
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4);
+ PairwiseCnt = 2;
+ }
+ }
+ else
+ {
+ // Insert WPA2 AES as the first pairwise cipher
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
+ }
+
+ pRsnie_cipher->ucount = PairwiseCnt;
+ *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1));
+ break;
+ }
+
+ // swap for big-endian platform
+ pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
+ pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
+ }
+ else
+ {
+ RSNIE *pRsnie_cipher = (RSNIE*)pRsnIe;
+
+ // Assign OUI and version
+ NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
+ pRsnie_cipher->version = 1;
+
+ switch (WepStatus)
+ {
+ // TKIP mode
+ case Ndis802_11Encryption2Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
+ pRsnie_cipher->ucount = 1;
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
+ *rsn_len = sizeof(RSNIE);
+ break;
+
+ // AES mode
+ case Ndis802_11Encryption3Enabled:
+ if (bMixCipher)
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
+ else
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4);
+ pRsnie_cipher->ucount = 1;
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
+ *rsn_len = sizeof(RSNIE);
+ break;
+
+ // TKIP-AES mix mode
+ case Ndis802_11Encryption4Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
+
+ PairwiseCnt = 1;
+ // Insert WPA TKIP as the first pairwise cipher
+ if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher))
+ {
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
+ // Insert WPA AES as the secondary pairwise cipher
+ if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher))
+ {
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4);
+ PairwiseCnt = 2;
+ }
+ }
+ else
+ {
+ // Insert WPA AES as the first pairwise cipher
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
+ }
+
+ pRsnie_cipher->ucount = PairwiseCnt;
+ *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1));
+ break;
+ }
+
+ // swap for big-endian platform
+ pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
+ pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
+ }
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build AKM suite in RSN-IE.
+ It only shall be called by RTMPMakeRSNIE.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ ElementID - indicate the WPA1 or WPA2
+ AuthMode - indicate the authentication mode
+ apidx - indicate the interface index
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+static VOID RTMPInsertRsnIeAKM(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ElementID,
+ IN UINT AuthMode,
+ IN UCHAR apidx,
+ OUT PUCHAR pRsnIe,
+ OUT UCHAR *rsn_len)
+{
+ RSNIE_AUTH *pRsnie_auth;
+
+ pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len));
+
+ // decide WPA2 or WPA1
+ if (ElementID == Wpa2Ie)
+ {
+ switch (AuthMode)
+ {
+ case Ndis802_11AuthModeWPA2:
+ case Ndis802_11AuthModeWPA1WPA2:
+ pRsnie_auth->acount = 1;
+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
+ break;
+
+ case Ndis802_11AuthModeWPA2PSK:
+ case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+ pRsnie_auth->acount = 1;
+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
+ break;
+ }
+ }
+ else
+ {
+ switch (AuthMode)
+ {
+ case Ndis802_11AuthModeWPA:
+ case Ndis802_11AuthModeWPA1WPA2:
+ pRsnie_auth->acount = 1;
+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4);
+ break;
+
+ case Ndis802_11AuthModeWPAPSK:
+ case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+ pRsnie_auth->acount = 1;
+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4);
+ break;
+
+ case Ndis802_11AuthModeWPANone:
+ pRsnie_auth->acount = 1;
+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4);
+ break;
+ }
+ }
+
+ pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
+
+ (*rsn_len) += sizeof(RSNIE_AUTH); // update current RSNIE length
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build capability in RSN-IE.
+ It only shall be called by RTMPMakeRSNIE.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ ElementID - indicate the WPA1 or WPA2
+ apidx - indicate the interface index
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+static VOID RTMPInsertRsnIeCap(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ElementID,
+ IN UCHAR apidx,
+ OUT PUCHAR pRsnIe,
+ OUT UCHAR *rsn_len)
+{
+ RSN_CAPABILITIES *pRSN_Cap;
+
+ // it could be ignored in WPA1 mode
+ if (ElementID == WpaIe)
+ return;
+
+ pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len));
+
+
+ pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
+
+ (*rsn_len) += sizeof(RSN_CAPABILITIES); // update current RSNIE length
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build RSN IE context. It is not included element-ID and length.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ AuthMode - indicate the authentication mode
+ WepStatus - indicate the encryption type
+ apidx - indicate the interface index
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPMakeRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT AuthMode,
+ IN UINT WepStatus,
+ IN UCHAR apidx)
+{
+ PUCHAR pRsnIe = NULL; // primary RSNIE
+ UCHAR *rsnielen_cur_p = 0; // the length of the primary RSNIE
+ UCHAR *rsnielen_ex_cur_p = 0; // the length of the secondary RSNIE
+ UCHAR PrimaryRsnie;
+ BOOLEAN bMixCipher = FALSE; // indicate the pairwise and group cipher are different
+ UCHAR p_offset;
+ WPA_MIX_PAIR_CIPHER FlexibleCipher = MIX_CIPHER_NOTUSE; // it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode
+
+ rsnielen_cur_p = NULL;
+ rsnielen_ex_cur_p = NULL;
+
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+ {
+ if (AuthMode < Ndis802_11AuthModeWPA)
+ return;
+ }
+ else
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ // Support WPAPSK or WPA2PSK in STA-Infra mode
+ // Support WPANone in STA-Adhoc mode
+ if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
+ (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+ (AuthMode != Ndis802_11AuthModeWPANone)
+ )
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n"));
+
+ // Zero RSNIE context
+ pAd->StaCfg.RSNIE_Len = 0;
+ NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
+
+ // Pointer to RSNIE
+ rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
+ pRsnIe = pAd->StaCfg.RSN_IE;
+
+ bMixCipher = pAd->StaCfg.bMixCipher;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ // indicate primary RSNIE as WPA or WPA2
+ if ((AuthMode == Ndis802_11AuthModeWPA) ||
+ (AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (AuthMode == Ndis802_11AuthModeWPANone) ||
+ (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
+ (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
+ PrimaryRsnie = WpaIe;
+ else
+ PrimaryRsnie = Wpa2Ie;
+
+ {
+ // Build the primary RSNIE
+ // 1. insert cipher suite
+ RTMPInsertRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);
+
+ // 2. insert AKM
+ RTMPInsertRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);
+
+ // 3. insert capability
+ RTMPInsertRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
+ }
+
+ // 4. update the RSNIE length
+ *rsnielen_cur_p = p_offset;
+
+ hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
+
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ Check whether the received frame is EAP frame.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ pEntry - pointer to active entry
+ pData - the received frame
+ DataByteCount - the received frame's length
+ FromWhichBSSID - indicate the interface index
+
+ Return:
+ TRUE - This frame is EAP frame
+ FALSE - otherwise
+ ==========================================================================
+*/
+BOOLEAN RTMPCheckWPAframe(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR pData,
+ IN ULONG DataByteCount,
+ IN UCHAR FromWhichBSSID)
+{
+ ULONG Body_len;
+ BOOLEAN Cancelled;
+
+
+ if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
+ return FALSE;
+
+
+ // Skip LLC header
+ if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
+ // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL
+ NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6))
+ {
+ pData += 6;
+ }
+ // Skip 2-bytes EAPoL type
+ if (NdisEqualMemory(EAPOL, pData, 2))
+ {
+ pData += 2;
+ }
+ else
+ return FALSE;
+
+ switch (*(pData+1))
+ {
+ case EAPPacket:
+ Body_len = (*(pData+2)<<8) | (*(pData+3));
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len));
+ break;
+ case EAPOLStart:
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n"));
+ if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n"));
+ RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
+ pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
+ }
+ break;
+ case EAPOLLogoff:
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
+ break;
+ case EAPOLKey:
+ Body_len = (*(pData+2)<<8) | (*(pData+3));
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len));
+ break;
+ case EAPOLASFAlert:
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
+ break;
+ default:
+ return FALSE;
+
+ }
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ ENCRYPT AES GTK before sending in EAPOL frame.
+ AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function.
+ This function references to RFC 3394 for aes key wrap algorithm.
+ Return:
+ ==========================================================================
+*/
+VOID AES_GTK_KEY_WRAP(
+ IN UCHAR *key,
+ IN UCHAR *plaintext,
+ IN UCHAR p_len,
+ OUT UCHAR *ciphertext)
+{
+ UCHAR A[8], BIN[16], BOUT[16];
+ UCHAR R[512];
+ INT num_blocks = p_len/8; // unit:64bits
+ INT i, j;
+ aes_context aesctx;
+ UCHAR xor;
+
+ rtmp_aes_set_key(&aesctx, key, 128);
+
+ // Init IA
+ for (i = 0; i < 8; i++)
+ A[i] = 0xa6;
+
+ //Input plaintext
+ for (i = 0; i < num_blocks; i++)
+ {
+ for (j = 0 ; j < 8; j++)
+ R[8 * (i + 1) + j] = plaintext[8 * i + j];
+ }
+
+ // Key Mix
+ for (j = 0; j < 6; j++)
+ {
+ for(i = 1; i <= num_blocks; i++)
+ {
+ //phase 1
+ NdisMoveMemory(BIN, A, 8);
+ NdisMoveMemory(&BIN[8], &R[8 * i], 8);
+ rtmp_aes_encrypt(&aesctx, BIN, BOUT);
+
+ NdisMoveMemory(A, &BOUT[0], 8);
+ xor = num_blocks * j + i;
+ A[7] = BOUT[7] ^ xor;
+ NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
+ }
+ }
+
+ // Output ciphertext
+ NdisMoveMemory(ciphertext, A, 8);
+
+ for (i = 1; i <= num_blocks; i++)
+ {
+ for (j = 0 ; j < 8; j++)
+ ciphertext[8 * i + j] = R[8 * i + j];
+ }
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Misc function to decrypt AES body
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+ This function references to RFC 3394 for aes key unwrap algorithm.
+
+ ========================================================================
+*/
+VOID AES_GTK_KEY_UNWRAP(
+ IN UCHAR *key,
+ OUT UCHAR *plaintext,
+ IN UCHAR c_len,
+ IN UCHAR *ciphertext)
+
+{
+ UCHAR A[8], BIN[16], BOUT[16];
+ UCHAR xor;
+ INT i, j;
+ aes_context aesctx;
+ UCHAR *R;
+ INT num_blocks = c_len/8; // unit:64bits
+
+
+ os_alloc_mem(NULL, (PUCHAR *)&R, 512);
+
+ if (R == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
+ return;
+ } /* End of if */
+
+ // Initialize
+ NdisMoveMemory(A, ciphertext, 8);
+ //Input plaintext
+ for(i = 0; i < (c_len-8); i++)
+ {
+ R[ i] = ciphertext[i + 8];
+ }
+
+ rtmp_aes_set_key(&aesctx, key, 128);
+
+ for(j = 5; j >= 0; j--)
+ {
+ for(i = (num_blocks-1); i > 0; i--)
+ {
+ xor = (num_blocks -1 )* j + i;
+ NdisMoveMemory(BIN, A, 8);
+ BIN[7] = A[7] ^ xor;
+ NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
+ rtmp_aes_decrypt(&aesctx, BIN, BOUT);
+ NdisMoveMemory(A, &BOUT[0], 8);
+ NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
+ }
+ }
+
+ // OUTPUT
+ for(i = 0; i < c_len; i++)
+ {
+ plaintext[i] = R[i];
+ }
+
+
+ os_free_mem(NULL, R);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Report the EAP message type
+
+ Arguments:
+ msg - EAPOL_PAIR_MSG_1
+ EAPOL_PAIR_MSG_2
+ EAPOL_PAIR_MSG_3
+ EAPOL_PAIR_MSG_4
+ EAPOL_GROUP_MSG_1
+ EAPOL_GROUP_MSG_2
+
+ Return:
+ message type string
+
+ ==========================================================================
+*/
+CHAR *GetEapolMsgType(CHAR msg)
+{
+ if(msg == EAPOL_PAIR_MSG_1)
+ return "Pairwise Message 1";
+ else if(msg == EAPOL_PAIR_MSG_2)
+ return "Pairwise Message 2";
+ else if(msg == EAPOL_PAIR_MSG_3)
+ return "Pairwise Message 3";
+ else if(msg == EAPOL_PAIR_MSG_4)
+ return "Pairwise Message 4";
+ else if(msg == EAPOL_GROUP_MSG_1)
+ return "Group Message 1";
+ else if(msg == EAPOL_GROUP_MSG_2)
+ return "Group Message 2";
+ else
+ return "Invalid Message";
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check Sanity RSN IE of EAPoL message
+
+ Arguments:
+
+ Return Value:
+
+
+ ========================================================================
+*/
+BOOLEAN RTMPCheckRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN UCHAR DataLen,
+ IN MAC_TABLE_ENTRY *pEntry,
+ OUT UCHAR *Offset)
+{
+ PUCHAR pVIE;
+ UCHAR len;
+ PEID_STRUCT pEid;
+ BOOLEAN result = FALSE;
+
+ pVIE = pData;
+ len = DataLen;
+ *Offset = 0;
+
+ while (len > sizeof(RSNIE2))
+ {
+ pEid = (PEID_STRUCT) pVIE;
+ // WPA RSN IE
+ if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
+ {
+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) &&
+ (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
+ (pEntry->RSNIE_Len == (pEid->Len + 2)))
+ {
+ result = TRUE;
+ }
+
+ *Offset += (pEid->Len + 2);
+ }
+ // WPA2 RSN IE
+ else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
+ {
+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) &&
+ (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
+ (pEntry->RSNIE_Len == (pEid->Len + 2))/* ToDo-AlbertY for mesh*/)
+ {
+ result = TRUE;
+ }
+
+ *Offset += (pEid->Len + 2);
+ }
+ else
+ {
+ break;
+ }
+
+ pVIE += (pEid->Len + 2);
+ len -= (pEid->Len + 2);
+ }
+
+
+ return result;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
+ GTK is encaptulated in KDE format at p.83 802.11i D10
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+ 802.11i D10
+
+ ========================================================================
+*/
+BOOLEAN RTMPParseEapolKeyData(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKeyData,
+ IN UCHAR KeyDataLen,
+ IN UCHAR GroupKeyIndex,
+ IN UCHAR MsgType,
+ IN BOOLEAN bWPA2,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ PKDE_ENCAP pKDE = NULL;
+ PUCHAR pMyKeyData = pKeyData;
+ UCHAR KeyDataLength = KeyDataLen;
+ UCHAR GTKLEN = 0;
+ UCHAR DefaultIdx = 0;
+ UCHAR skip_offset;
+
+ // Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it
+ if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3)
+ {
+ // Check RSN IE whether it is WPA2/WPA2PSK
+ if (!RTMPCheckRSNIE(pAd, pKeyData, KeyDataLen, pEntry, &skip_offset))
+ {
+ // send wireless event - for RSN IE different
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_RSNIE_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+ DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType));
+ hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
+ hex_dump("Desired RSN_IE ", pEntry->RSN_IE, pEntry->RSNIE_Len);
+
+ return FALSE;
+ }
+ else
+ {
+ if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3)
+ {
+ // skip RSN IE
+ pMyKeyData += skip_offset;
+ KeyDataLength -= skip_offset;
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
+ }
+ else
+ return TRUE;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
+
+ // Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2
+ if (bWPA2 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1))
+ {
+ if (KeyDataLength >= 8) // KDE format exclude GTK length
+ {
+ pKDE = (PKDE_ENCAP) pMyKeyData;
+
+
+ DefaultIdx = pKDE->GTKEncap.Kid;
+
+ // Sanity check - KED length
+ if (KeyDataLength < (pKDE->Len + 2))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
+ return FALSE;
+ }
+
+ // Get GTK length - refer to IEEE 802.11i-2004 p.82
+ GTKLEN = pKDE->Len -6;
+ if (GTKLEN < LEN_AES_KEY)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
+ return FALSE;
+ }
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KDE format length is too short \n"));
+ return FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN));
+ // skip it
+ pMyKeyData += 8;
+ KeyDataLength -= 8;
+
+ }
+ else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1)
+ {
+ DefaultIdx = GroupKeyIndex;
+ DBGPRINT(RT_DEBUG_TRACE, ("GTK DefaultKeyID=%d \n", DefaultIdx));
+ }
+
+ // Sanity check - shared key index must be 1 ~ 3
+ if (DefaultIdx < 1 || DefaultIdx > 3)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
+ return FALSE;
+ }
+
+
+#ifdef CONFIG_STA_SUPPORT
+ // Todo
+#endif // CONFIG_STA_SUPPORT //
+
+ return TRUE;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Construct EAPoL message for WPA handshaking
+ Its format is below,
+
+ +--------------------+
+ | Protocol Version | 1 octet
+ +--------------------+
+ | Protocol Type | 1 octet
+ +--------------------+
+ | Body Length | 2 octets
+ +--------------------+
+ | Descriptor Type | 1 octet
+ +--------------------+
+ | Key Information | 2 octets
+ +--------------------+
+ | Key Length | 1 octet
+ +--------------------+
+ | Key Repaly Counter | 8 octets
+ +--------------------+
+ | Key Nonce | 32 octets
+ +--------------------+
+ | Key IV | 16 octets
+ +--------------------+
+ | Key RSC | 8 octets
+ +--------------------+
+ | Key ID or Reserved | 8 octets
+ +--------------------+
+ | Key MIC | 16 octets
+ +--------------------+
+ | Key Data Length | 2 octets
+ +--------------------+
+ | Key Data | n octets
+ +--------------------+
+
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID ConstructEapolMsg(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR AuthMode,
+ IN UCHAR WepStatus,
+ IN UCHAR GroupKeyWepStatus,
+ IN UCHAR MsgType,
+ IN UCHAR DefaultKeyIdx,
+ IN UCHAR *ReplayCounter,
+ IN UCHAR *KeyNonce,
+ IN UCHAR *TxRSC,
+ IN UCHAR *PTK,
+ IN UCHAR *GTK,
+ IN UCHAR *RSNIE,
+ IN UCHAR RSNIE_Len,
+ OUT PEAPOL_PACKET pMsg)
+{
+ BOOLEAN bWPA2 = FALSE;
+
+ // Choose WPA2 or not
+ if ((AuthMode == Ndis802_11AuthModeWPA2) || (AuthMode == Ndis802_11AuthModeWPA2PSK))
+ bWPA2 = TRUE;
+
+ // Init Packet and Fill header
+ pMsg->ProVer = EAPOL_VER;
+ pMsg->ProType = EAPOLKey;
+
+ // Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field
+ pMsg->Body_Len[1] = LEN_EAPOL_KEY_MSG;
+
+ // Fill in EAPoL descriptor
+ if (bWPA2)
+ pMsg->KeyDesc.Type = WPA2_KEY_DESC;
+ else
+ pMsg->KeyDesc.Type = WPA1_KEY_DESC;
+
+ // Fill in Key information, refer to IEEE Std 802.11i-2004 page 78
+ // When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used.
+ pMsg->KeyDesc.KeyInfo.KeyDescVer =
+ (((WepStatus == Ndis802_11Encryption3Enabled) || (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
+
+ // Specify Key Type as Group(0) or Pairwise(1)
+ if (MsgType >= EAPOL_GROUP_MSG_1)
+ pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
+ else
+ pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+ // Specify Key Index, only group_msg1_WPA1
+ if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
+ pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
+
+ if (MsgType == EAPOL_PAIR_MSG_3)
+ pMsg->KeyDesc.KeyInfo.Install = 1;
+
+ if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))
+ pMsg->KeyDesc.KeyInfo.KeyAck = 1;
+
+ if (MsgType != EAPOL_PAIR_MSG_1)
+ pMsg->KeyDesc.KeyInfo.KeyMic = 1;
+
+ if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)))
+ {
+ pMsg->KeyDesc.KeyInfo.Secure = 1;
+ }
+
+ if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
+ {
+ pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
+ }
+
+ // key Information element has done.
+ *(USHORT *)(&pMsg->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo));
+
+ // Fill in Key Length
+ {
+ if (MsgType >= EAPOL_GROUP_MSG_1)
+ {
+ // the length of group key cipher
+ pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : LEN_AES_KEY);
+ }
+ else
+ {
+ // the length of pairwise key cipher
+ pMsg->KeyDesc.KeyLength[1] = ((WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY);
+ }
+ }
+
+ // Fill in replay counter
+ NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Fill Key Nonce field
+ // ANonce : pairwise_msg1 & pairwise_msg3
+ // SNonce : pairwise_msg2
+ // GNonce : group_msg1_wpa1
+ if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
+ NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE);
+
+ // Fill key IV - WPA2 as 0, WPA1 as random
+ if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
+ {
+ // Suggest IV be random number plus some number,
+ NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV);
+ pMsg->KeyDesc.KeyIv[15] += 2;
+ }
+
+ // Fill Key RSC field
+ // It contains the RSC for the GTK being installed.
+ if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
+ {
+ NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
+ }
+
+ // Clear Key MIC field for MIC calculation later
+ NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+
+ ConstructEapolKeyData(pAd,
+ AuthMode,
+ WepStatus,
+ GroupKeyWepStatus,
+ MsgType,
+ DefaultKeyIdx,
+ bWPA2,
+ PTK,
+ GTK,
+ RSNIE,
+ RSNIE_Len,
+ pMsg);
+
+ // Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.
+ if (MsgType != EAPOL_PAIR_MSG_1)
+ {
+ CalculateMIC(pAd, WepStatus, PTK, pMsg);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
+ DBGPRINT(RT_DEBUG_TRACE, (" Body length = %d \n", pMsg->Body_Len[1]));
+ DBGPRINT(RT_DEBUG_TRACE, (" Key length = %d \n", pMsg->KeyDesc.KeyLength[1]));
+
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Construct the Key Data field of EAPoL message
+
+ Arguments:
+ pAd Pointer to our adapter
+ Elem Message body
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID ConstructEapolKeyData(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR AuthMode,
+ IN UCHAR WepStatus,
+ IN UCHAR GroupKeyWepStatus,
+ IN UCHAR MsgType,
+ IN UCHAR DefaultKeyIdx,
+ IN BOOLEAN bWPA2Capable,
+ IN UCHAR *PTK,
+ IN UCHAR *GTK,
+ IN UCHAR *RSNIE,
+ IN UCHAR RSNIE_LEN,
+ OUT PEAPOL_PACKET pMsg)
+{
+ UCHAR *mpool, *Key_Data, *Rc4GTK;
+ UCHAR ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)];
+ UCHAR data_offset;
+
+
+ if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
+ return;
+
+ // allocate memory pool
+ os_alloc_mem(pAd, (PUCHAR *)&mpool, 1500);
+
+ if (mpool == NULL)
+ return;
+
+ /* Rc4GTK Len = 512 */
+ Rc4GTK = (UCHAR *) ROUND_UP(mpool, 4);
+ /* Key_Data Len = 512 */
+ Key_Data = (UCHAR *) ROUND_UP(Rc4GTK + 512, 4);
+
+ NdisZeroMemory(Key_Data, 512);
+ pMsg->KeyDesc.KeyDataLen[1] = 0;
+ data_offset = 0;
+
+ // Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3
+ if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3)))
+ {
+ if (bWPA2Capable)
+ Key_Data[data_offset + 0] = IE_WPA2;
+ else
+ Key_Data[data_offset + 0] = IE_WPA;
+
+ Key_Data[data_offset + 1] = RSNIE_LEN;
+ NdisMoveMemory(&Key_Data[data_offset + 2], RSNIE, RSNIE_LEN);
+ data_offset += (2 + RSNIE_LEN);
+ }
+
+ // Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2
+ if (bWPA2Capable && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
+ {
+ // Key Data Encapsulation (KDE) format - 802.11i-2004 Figure-43w and Table-20h
+ Key_Data[data_offset + 0] = 0xDD;
+
+ if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
+ {
+ Key_Data[data_offset + 1] = 0x16;// 4+2+16(OUI+DataType+DataField)
+ }
+ else
+ {
+ Key_Data[data_offset + 1] = 0x26;// 4+2+32(OUI+DataType+DataField)
+ }
+
+ Key_Data[data_offset + 2] = 0x00;
+ Key_Data[data_offset + 3] = 0x0F;
+ Key_Data[data_offset + 4] = 0xAC;
+ Key_Data[data_offset + 5] = 0x01;
+
+ // GTK KDE format - 802.11i-2004 Figure-43x
+ Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
+ Key_Data[data_offset + 7] = 0x00; // Reserved Byte
+
+ data_offset += 8;
+ }
+
+
+ // Encapsulate GTK and encrypt the key-data field with KEK.
+ // Only for pairwise_msg3_WPA2 and group_msg1
+ if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1))
+ {
+ // Fill in GTK
+ if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
+ {
+ NdisMoveMemory(&Key_Data[data_offset], GTK, LEN_AES_KEY);
+ data_offset += LEN_AES_KEY;
+ }
+ else
+ {
+ NdisMoveMemory(&Key_Data[data_offset], GTK, TKIP_GTK_LENGTH);
+ data_offset += TKIP_GTK_LENGTH;
+ }
+
+ // Still dont know why, but if not append will occur "GTK not include in MSG3"
+ // Patch for compatibility between zero config and funk
+ if (MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
+ {
+ if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
+ {
+ Key_Data[data_offset + 0] = 0xDD;
+ Key_Data[data_offset + 1] = 0;
+ data_offset += 2;
+ }
+ else
+ {
+ Key_Data[data_offset + 0] = 0xDD;
+ Key_Data[data_offset + 1] = 0;
+ Key_Data[data_offset + 2] = 0;
+ Key_Data[data_offset + 3] = 0;
+ Key_Data[data_offset + 4] = 0;
+ Key_Data[data_offset + 5] = 0;
+ data_offset += 6;
+ }
+ }
+
+ // Encrypt the data material in key data field
+ if (WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ AES_GTK_KEY_WRAP(&PTK[16], Key_Data, data_offset, Rc4GTK);
+ // AES wrap function will grow 8 bytes in length
+ data_offset += 8;
+ }
+ else
+ {
+ // PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV)
+ // put TxTsc in Key RSC field
+ pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
+
+ // ekey is the contanetion of IV-field, and PTK[16]->PTK[31]
+ NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, LEN_KEY_DESC_IV);
+ NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &PTK[16], LEN_EAP_EK);
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); //INIT SBOX, KEYLEN+3(IV)
+ pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, data_offset);
+ WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, Key_Data, data_offset);
+ }
+
+ NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
+ }
+ else
+ {
+ NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
+ }
+
+ // set key data length field and total length
+ pMsg->KeyDesc.KeyDataLen[1] = data_offset;
+ pMsg->Body_Len[1] += data_offset;
+
+ os_free_mem(pAd, mpool);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calcaulate MIC. It is used during 4-ways handsharking.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ PeerWepStatus - indicate the encryption type
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID CalculateMIC(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR PeerWepStatus,
+ IN UCHAR *PTK,
+ OUT PEAPOL_PACKET pMsg)
+{
+ UCHAR *OutBuffer;
+ ULONG FrameLen = 0;
+ UCHAR mic[LEN_KEY_DESC_MIC];
+ UCHAR digest[80];
+
+ // allocate memory for MIC calculation
+ os_alloc_mem(pAd, (PUCHAR *)&OutBuffer, 512);
+
+ if (OutBuffer == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n"));
+ return;
+ }
+
+ // make a frame for calculating MIC.
+ MakeOutgoingFrame(OutBuffer, &FrameLen,
+ pMsg->Body_Len[1] + 4, pMsg,
+ END_OF_ARGS);
+
+ NdisZeroMemory(mic, sizeof(mic));
+
+ // Calculate MIC
+ if (PeerWepStatus == Ndis802_11Encryption3Enabled)
+ {
+ HMAC_SHA1(OutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic);
+ }
+
+ // store the calculated MIC
+ NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
+
+ os_free_mem(pAd, OutBuffer);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Some received frames can't decrypt by Asic, so decrypt them by software.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ PeerWepStatus - indicate the encryption type
+
+ Return Value:
+ NDIS_STATUS_SUCCESS - decryption successful
+ NDIS_STATUS_FAILURE - decryption failure
+
+ ========================================================================
+*/
+NDIS_STATUS RTMPSoftDecryptBroadCastData(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher,
+ IN PCIPHER_KEY pShard_key)
+{
+ PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
+
+
+
+ // handle WEP decryption
+ if (GroupCipher == Ndis802_11Encryption1Enabled)
+ {
+ if (RTMPSoftDecryptWEP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, pShard_key))
+ {
+
+ //Minus IV[4] & ICV[4]
+ pRxWI->MPDUtotalByteCount -= 8;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR : Software decrypt WEP data fails.\n"));
+ // give up this frame
+ return NDIS_STATUS_FAILURE;
+ }
+ }
+ // handle TKIP decryption
+ else if (GroupCipher == Ndis802_11Encryption2Enabled)
+ {
+ if (RTMPSoftDecryptTKIP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0, pShard_key))
+ {
+
+ //Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV
+ pRxWI->MPDUtotalByteCount -= 20;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
+ // give up this frame
+ return NDIS_STATUS_FAILURE;
+ }
+ }
+ // handle AES decryption
+ else if (GroupCipher == Ndis802_11Encryption3Enabled)
+ {
+ if (RTMPSoftDecryptAES(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount , pShard_key))
+ {
+
+ //8 bytes MIC, 8 bytes IV/EIV (CCMP Header)
+ pRxWI->MPDUtotalByteCount -= 16;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptAES Failed\n"));
+ // give up this frame
+ return NDIS_STATUS_FAILURE;
+ }
+ }
+ else
+ {
+ // give up this frame
+ return NDIS_STATUS_FAILURE;
+ }
+
+ return NDIS_STATUS_SUCCESS;
+
+}
+
diff --git a/drivers/staging/rt3070/common/dfs.c b/drivers/staging/rt3070/common/dfs.c
new file mode 100644
index 00000000000..28d60145791
--- /dev/null
+++ b/drivers/staging/rt3070/common/dfs.c
@@ -0,0 +1,441 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ ap_dfs.c
+
+ Abstract:
+ Support DFS function.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Fonchi 03-12-2007 created
+*/
+
+#include "../rt_config.h"
+
+typedef struct _RADAR_DURATION_TABLE
+{
+ ULONG RDDurRegion;
+ ULONG RadarSignalDuration;
+ ULONG Tolerance;
+} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
+
+
+static UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
+{
+ {9, 250, 250, 250}, // CE
+ {4, 250, 250, 250}, // FCC
+ {4, 250, 250, 250}, // JAP
+ {15, 250, 250, 250}, // JAP_W53
+ {4, 250, 250, 250} // JAP_W56
+};
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Bbp Radar detection routine
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+
+ ========================================================================
+*/
+VOID BbpRadarDetectionStart(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT8 RadarPeriod;
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x08/*0x80*/);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
+
+ RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
+ (RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
+
+ RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
+ RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
+
+ RadarDetectionStart(pAd, 0, RadarPeriod);
+ return;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Bbp Radar detection routine
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+
+ ========================================================================
+*/
+VOID BbpRadarDetectionStop(
+ IN PRTMP_ADAPTER pAd)
+{
+ RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
+ RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
+
+ RadarDetectionStop(pAd);
+ return;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Radar detection routine
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+
+ ========================================================================
+*/
+VOID RadarDetectionStart(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN CTSProtect,
+ IN UINT8 CTSPeriod)
+{
+ UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f);
+ UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect.
+
+ if (CTSProtect != 0)
+ {
+ switch(pAd->CommonCfg.RadarDetect.RDDurRegion)
+ {
+ case FCC:
+ case JAP_W56:
+ CtsProtect = 0x03;
+ break;
+
+ case CE:
+ case JAP_W53:
+ default:
+ CtsProtect = 0x02;
+ break;
+ }
+ }
+ else
+ CtsProtect = 0x01;
+
+
+ // send start-RD with CTS protection command to MCU
+ // highbyte [7] reserve
+ // highbyte [6:5] 0x: stop Carrier/Radar detection
+ // highbyte [10]: Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection
+ // highbyte [4:0] Radar/carrier detection duration. In 1ms.
+
+ // lowbyte [7:0] Radar/carrier detection period, in 1ms.
+ AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5));
+ //AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0);
+
+ return;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Radar detection routine
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ TRUE Found radar signal
+ FALSE Not found radar signal
+
+ ========================================================================
+*/
+VOID RadarDetectionStop(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n"));
+ AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00); // send start-RD with CTS protection command to MCU
+
+ return;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Radar channel check routine
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ TRUE need to do radar detect
+ FALSE need not to do radar detect
+
+ ========================================================================
+*/
+BOOLEAN RadarChannelCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Ch)
+{
+#if 1
+ INT i;
+ BOOLEAN result = FALSE;
+
+ for (i=0; i<pAd->ChannelListNum; i++)
+ {
+ if (Ch == pAd->ChannelList[i].Channel)
+ {
+ result = pAd->ChannelList[i].DfsReq;
+ break;
+ }
+ }
+
+ return result;
+#else
+ INT i;
+ UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+
+ for (i=0; i<15; i++)
+ {
+ if (Ch == Channel[i])
+ {
+ break;
+ }
+ }
+
+ if (i != 15)
+ return TRUE;
+ else
+ return FALSE;
+#endif
+}
+
+ULONG JapRadarType(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG i;
+ const UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+
+ if (pAd->CommonCfg.RadarDetect.RDDurRegion != JAP)
+ {
+ return pAd->CommonCfg.RadarDetect.RDDurRegion;
+ }
+
+ for (i=0; i<15; i++)
+ {
+ if (pAd->CommonCfg.Channel == Channel[i])
+ {
+ break;
+ }
+ }
+
+ if (i < 4)
+ return JAP_W53;
+ else if (i < 15)
+ return JAP_W56;
+ else
+ return JAP; // W52
+
+}
+
+ULONG RTMPBbpReadRadarDuration(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT8 byteValue = 0;
+ ULONG result;
+
+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue);
+
+ result = 0;
+ switch (byteValue)
+ {
+ case 1: // radar signal detected by pulse mode.
+ case 2: // radar signal detected by width mode.
+ result = RTMPReadRadarDuration(pAd);
+ break;
+
+ case 0: // No radar signal.
+ default:
+
+ result = 0;
+ break;
+ }
+
+ return result;
+}
+
+ULONG RTMPReadRadarDuration(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG result = 0;
+
+#ifdef DFS_SUPPORT
+ UINT8 duration1 = 0, duration2 = 0, duration3 = 0;
+
+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R116, &duration1);
+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R117, &duration2);
+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R118, &duration3);
+ result = (duration1 << 16) + (duration2 << 8) + duration3;
+#endif // DFS_SUPPORT //
+
+ return result;
+
+}
+
+VOID RTMPCleanRadarDuration(
+ IN PRTMP_ADAPTER pAd)
+{
+ return;
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Radar wave detection. The API should be invoke each second.
+
+ Arguments:
+ pAd - Adapter pointer
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID ApRadarDetectPeriodic(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i;
+
+ pAd->CommonCfg.RadarDetect.InServiceMonitorCount++;
+
+ for (i=0; i<pAd->ChannelListNum; i++)
+ {
+ if (pAd->ChannelList[i].RemainingTimeForUse > 0)
+ {
+ pAd->ChannelList[i].RemainingTimeForUse --;
+ if ((pAd->Mlme.PeriodicRound%5) == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
+ }
+ }
+ }
+
+ //radar detect
+ if ((pAd->CommonCfg.Channel > 14)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+ {
+ RadarDetectPeriodic(pAd);
+ }
+
+ return;
+}
+
+// Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()
+// Before switch channel, driver needs doing channel switch announcement.
+VOID RadarDetectPeriodic(
+ IN PRTMP_ADAPTER pAd)
+{
+ // need to check channel availability, after switch channel
+ if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
+ return;
+
+ // channel availability check time is 60sec, use 65 for assurance
+ if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
+ BbpRadarDetectionStop(pAd);
+ AsicEnableBssSync(pAd);
+ pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
+
+
+ return;
+ }
+
+ return;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ change channel moving time for DFS testing.
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 set ChMovTime=[value]
+ ==========================================================================
+*/
+INT Set_ChMovingTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UINT8 Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
+ pAd->CommonCfg.RadarDetect.ChMovingTime));
+
+ return TRUE;
+}
+
+INT Set_LongPulseRadarTh_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UINT8 Value;
+
+ Value = simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
+
+ pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
+ pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
+
+ return TRUE;
+}
+
+
diff --git a/drivers/staging/rt3070/common/eeprom.c b/drivers/staging/rt3070/common/eeprom.c
new file mode 100644
index 00000000000..63e1dc14d15
--- /dev/null
+++ b/drivers/staging/rt3070/common/eeprom.c
@@ -0,0 +1,1498 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ eeprom.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+#include "../rt_config.h"
+
+// IRQL = PASSIVE_LEVEL
+VOID RaiseClock(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 *x)
+{
+ *x = *x | EESK;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
+ RTMPusecDelay(1); // Max frequency = 1MHz in Spec. definition
+}
+
+// IRQL = PASSIVE_LEVEL
+VOID LowerClock(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 *x)
+{
+ *x = *x & ~EESK;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
+ RTMPusecDelay(1);
+}
+
+// IRQL = PASSIVE_LEVEL
+USHORT ShiftInBits(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 x,i;
+ USHORT data=0;
+
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+ x &= ~( EEDO | EEDI);
+
+ for(i=0; i<16; i++)
+ {
+ data = data << 1;
+ RaiseClock(pAd, &x);
+
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ LowerClock(pAd, &x); //prevent read failed
+
+ x &= ~(EEDI);
+ if(x & EEDO)
+ data |= 1;
+ }
+
+ return data;
+}
+
+// IRQL = PASSIVE_LEVEL
+VOID ShiftOutBits(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT data,
+ IN USHORT count)
+{
+ UINT32 x,mask;
+
+ mask = 0x01 << (count - 1);
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+ x &= ~(EEDO | EEDI);
+
+ do
+ {
+ x &= ~EEDI;
+ if(data & mask) x |= EEDI;
+
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+
+ mask = mask >> 1;
+ } while(mask);
+
+ x &= ~EEDI;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+}
+
+// IRQL = PASSIVE_LEVEL
+VOID EEpromCleanup(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 x;
+
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+ x &= ~(EECS | EEDI);
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+}
+
+VOID EWEN(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 x;
+
+ // reset bits and set EECS
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x &= ~(EEDI | EEDO | EESK);
+ x |= EECS;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ // kick a pulse
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+
+ // output the read_opcode and six pulse in that order
+ ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
+ ShiftOutBits(pAd, 0, 6);
+
+ EEpromCleanup(pAd);
+}
+
+VOID EWDS(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 x;
+
+ // reset bits and set EECS
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x &= ~(EEDI | EEDO | EESK);
+ x |= EECS;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ // kick a pulse
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+
+ // output the read_opcode and six pulse in that order
+ ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
+ ShiftOutBits(pAd, 0, 6);
+
+ EEpromCleanup(pAd);
+}
+
+// IRQL = PASSIVE_LEVEL
+USHORT RTMP_EEPROM_READ16(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset)
+{
+ UINT32 x;
+ USHORT data;
+
+ if (pAd->NicConfig2.field.AntDiversity)
+ {
+ pAd->EepromAccess = TRUE;
+ }
+//2008/09/11:KH add to support efuse<--
+//2008/09/11:KH add to support efuse-->
+{
+ Offset /= 2;
+ // reset bits and set EECS
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x &= ~(EEDI | EEDO | EESK);
+ x |= EECS;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ // patch can not access e-Fuse issue
+ if (!IS_RT3090(pAd))
+ {
+ // kick a pulse
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+ }
+
+ // output the read_opcode and register number in that order
+ ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
+ ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
+
+ // Now read the data (16 bits) in from the selected EEPROM word
+ data = ShiftInBits(pAd);
+
+ EEpromCleanup(pAd);
+
+ // Antenna and EEPROM access are both using EESK pin,
+ // Therefor we should avoid accessing EESK at the same time
+ // Then restore antenna after EEPROM access
+ if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
+ {
+ pAd->EepromAccess = FALSE;
+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+ }
+}
+ return data;
+} //ReadEEprom
+
+VOID RTMP_EEPROM_WRITE16(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Data)
+{
+ UINT32 x;
+
+ if (pAd->NicConfig2.field.AntDiversity)
+ {
+ pAd->EepromAccess = TRUE;
+ }
+ //2008/09/11:KH add to support efuse<--
+//2008/09/11:KH add to support efuse-->
+ {
+ Offset /= 2;
+
+ EWEN(pAd);
+
+ // reset bits and set EECS
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x &= ~(EEDI | EEDO | EESK);
+ x |= EECS;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ // patch can not access e-Fuse issue
+ if (!IS_RT3090(pAd))
+ {
+ // kick a pulse
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+ }
+
+ // output the read_opcode ,register number and data in that order
+ ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
+ ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
+ ShiftOutBits(pAd, Data, 16); // 16-bit access
+
+ // read DO status
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+ EEpromCleanup(pAd);
+
+ RTMPusecDelay(10000); //delay for twp(MAX)=10ms
+
+ EWDS(pAd);
+
+ EEpromCleanup(pAd);
+
+ // Antenna and EEPROM access are both using EESK pin,
+ // Therefor we should avoid accessing EESK at the same time
+ // Then restore antenna after EEPROM access
+ if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
+ {
+ pAd->EepromAccess = FALSE;
+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+ }
+}
+}
+
+//2008/09/11:KH add to support efuse<--
+#ifdef RT30xx
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+UCHAR eFuseReadRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ OUT USHORT* pData)
+{
+ EFUSE_CTRL_STRUC eFuseCtrlStruc;
+ int i;
+ USHORT efuseDataOffset;
+ UINT32 data;
+
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+ //Use the eeprom logical address and covert to address to block number
+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+ //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
+ eFuseCtrlStruc.field.EFSROM_MODE = 0;
+
+ //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+ //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+ i = 0;
+ while(i < 100)
+ {
+ //rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+ {
+ break;
+ }
+ RTMPusecDelay(2);
+ i++;
+ }
+
+ //if EFSROM_AOUT is not found in physical address, write 0xffff
+ if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
+ {
+ for(i=0; i<Length/2; i++)
+ *(pData+2*i) = 0xffff;
+ }
+ else
+ {
+ //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
+ efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
+ //data hold 4 bytes data.
+ //In RTMP_IO_READ32 will automatically execute 32-bytes swapping
+ RTMP_IO_READ32(pAd, efuseDataOffset, &data);
+ //Decide the upper 2 bytes or the bottom 2 bytes.
+ // Little-endian S | S Big-endian
+ // addr 3 2 1 0 | 0 1 2 3
+ // Ori-V D C B A | A B C D
+ //After swapping
+ // D C B A | D C B A
+ //Return 2-bytes
+ //The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
+ //For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
+#ifdef RT_BIG_ENDIAN
+ data = data << (8*((Offset & 0x3)^0x2));
+#else
+ data = data >> (8*(Offset & 0x3));
+#endif
+
+ NdisMoveMemory(pData, &data, Length);
+ }
+
+ return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID eFusePhysicalReadRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ OUT USHORT* pData)
+{
+ EFUSE_CTRL_STRUC eFuseCtrlStruc;
+ int i;
+ USHORT efuseDataOffset;
+ UINT32 data;
+
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+ //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
+ //Read in physical view
+ eFuseCtrlStruc.field.EFSROM_MODE = 1;
+
+ //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+ //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+ i = 0;
+ while(i < 100)
+ {
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+ break;
+ RTMPusecDelay(2);
+ i++;
+ }
+
+ //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
+ //Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
+ //The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
+ //Decide which EFUSE_DATA to read
+ //590:F E D C
+ //594:B A 9 8
+ //598:7 6 5 4
+ //59C:3 2 1 0
+ efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
+
+ RTMP_IO_READ32(pAd, efuseDataOffset, &data);
+
+#ifdef RT_BIG_ENDIAN
+ data = data << (8*((Offset & 0x3)^0x2));
+#else
+ data = data >> (8*(Offset & 0x3));
+#endif
+
+ NdisMoveMemory(pData, &data, Length);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID eFuseReadPhysical(
+ IN PRTMP_ADAPTER pAd,
+ IN PUSHORT lpInBuffer,
+ IN ULONG nInBufferSize,
+ OUT PUSHORT lpOutBuffer,
+ IN ULONG nOutBufferSize
+)
+{
+ USHORT* pInBuf = (USHORT*)lpInBuffer;
+ USHORT* pOutBuf = (USHORT*)lpOutBuffer;
+
+ USHORT Offset = pInBuf[0]; //addr
+ USHORT Length = pInBuf[1]; //length
+ int i;
+
+ for(i=0; i<Length; i+=2)
+ {
+ eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS eFuseRead(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUCHAR pData,
+ IN USHORT Length)
+{
+ USHORT* pOutBuf = (USHORT*)pData;
+ NTSTATUS Status = STATUS_SUCCESS;
+ UCHAR EFSROM_AOUT;
+ int i;
+
+ for(i=0; i<Length; i+=2)
+ {
+ EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pOutBuf[i/2]);
+ }
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID eFusePhysicalWriteRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ OUT USHORT* pData)
+{
+ EFUSE_CTRL_STRUC eFuseCtrlStruc;
+ int i;
+ USHORT efuseDataOffset;
+ UINT32 data, eFuseDataBuffer[4];
+
+ //Step0. Write 16-byte of data to EFUSE_DATA0-3 (0x590-0x59C), where EFUSE_DATA0 is the LSB DW, EFUSE_DATA3 is the MSB DW.
+
+ /////////////////////////////////////////////////////////////////
+ //read current values of 16-byte block
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+ //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
+ eFuseCtrlStruc.field.EFSROM_MODE = 1;
+
+ //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+ //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+ i = 0;
+ while(i < 100)
+ {
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+ break;
+ RTMPusecDelay(2);
+ i++;
+ }
+
+ //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
+ efuseDataOffset = EFUSE_DATA3;
+ for(i=0; i< 4; i++)
+ {
+ RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
+ efuseDataOffset -= 4;
+ }
+
+ //Update the value, the offset is multiple of 2, length is 2
+ efuseDataOffset = (Offset & 0xc) >> 2;
+ data = pData[0] & 0xffff;
+ //The offset should be 0x***10 or 0x***00
+ if((Offset % 4) != 0)
+ {
+ eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16);
+ }
+ else
+ {
+ eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data;
+ }
+
+ efuseDataOffset = EFUSE_DATA3;
+ for(i=0; i< 4; i++)
+ {
+ RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
+ efuseDataOffset -= 4;
+ }
+ /////////////////////////////////////////////////////////////////
+
+ //Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+ //Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
+ eFuseCtrlStruc.field.EFSROM_MODE = 3;
+
+ //Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+ //Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
+ i = 0;
+ while(i < 100)
+ {
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+ break;
+
+ RTMPusecDelay(2);
+ i++;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS eFuseWriteRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ IN USHORT* pData)
+{
+ USHORT i;
+ USHORT eFuseData;
+ USHORT LogicalAddress, BlkNum = 0xffff;
+ UCHAR EFSROM_AOUT;
+
+ USHORT addr,tmpaddr, InBuf[3], tmpOffset;
+ USHORT buffer[8];
+ BOOLEAN bWriteSuccess = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData));
+
+ //Step 0. find the entry in the mapping table
+ //The address of EEPROM is 2-bytes alignment.
+ //The last bit is used for alignment, so it must be 0.
+ tmpOffset = Offset & 0xfffe;
+ EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
+
+ if( EFSROM_AOUT == 0x3f)
+ { //find available logical address pointer
+ //the logical address does not exist, find an empty one
+ //from the first address of block 45=16*45=0x2d0 to the last address of block 47
+ //==>48*16-3(reserved)=2FC
+ for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+ {
+ //Retrive the logical block nubmer form each logical address pointer
+ //It will access two logical address pointer each time.
+ eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+ if( (LogicalAddress & 0xff) == 0)
+ {//Not used logical address pointer
+ BlkNum = i-EFUSE_USAGE_MAP_START;
+ break;
+ }
+ else if(( (LogicalAddress >> 8) & 0xff) == 0)
+ {//Not used logical address pointer
+ if (i != EFUSE_USAGE_MAP_END)
+ {
+ BlkNum = i-EFUSE_USAGE_MAP_START+1;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ BlkNum = EFSROM_AOUT;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
+
+ if(BlkNum == 0xffff)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
+ return FALSE;
+ }
+
+ //Step 1. Save data of this block which is pointed by the avaible logical address pointer
+ // read and save the original block data
+ for(i =0; i<8; i++)
+ {
+ addr = BlkNum * 0x10 ;
+
+ InBuf[0] = addr+2*i;
+ InBuf[1] = 2;
+ InBuf[2] = 0x0;
+
+ eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+ buffer[i] = InBuf[2];
+ }
+
+ //Step 2. Update the data in buffer, and write the data to Efuse
+ buffer[ (Offset >> 1) % 8] = pData[0];
+
+ do
+ {
+ //Step 3. Write the data to Efuse
+ if(!bWriteSuccess)
+ {
+ for(i =0; i<8; i++)
+ {
+ addr = BlkNum * 0x10 ;
+
+ InBuf[0] = addr+2*i;
+ InBuf[1] = 2;
+ InBuf[2] = buffer[i];
+
+ eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
+ }
+ }
+ else
+ {
+ addr = BlkNum * 0x10 ;
+
+ InBuf[0] = addr+(Offset % 16);
+ InBuf[1] = 2;
+ InBuf[2] = pData[0];
+
+ eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
+ }
+
+ //Step 4. Write mapping table
+ addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+ tmpaddr = addr;
+
+ if(addr % 2 != 0)
+ addr = addr -1;
+ InBuf[0] = addr;
+ InBuf[1] = 2;
+
+ //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
+ tmpOffset = Offset;
+ tmpOffset >>= 4;
+ tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
+ tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
+
+ // write the logical address
+ if(tmpaddr%2 != 0)
+ InBuf[2] = tmpOffset<<8;
+ else
+ InBuf[2] = tmpOffset;
+
+ eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
+
+ //Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
+ bWriteSuccess = TRUE;
+ for(i =0; i<8; i++)
+ {
+ addr = BlkNum * 0x10 ;
+
+ InBuf[0] = addr+2*i;
+ InBuf[1] = 2;
+ InBuf[2] = 0x0;
+
+ eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+ if(buffer[i] != InBuf[2])
+ {
+ bWriteSuccess = FALSE;
+ break;
+ }
+ }
+
+ //Step 6. invlidate mapping entry and find a free mapping entry if not succeed
+ if (!bWriteSuccess)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum));
+
+ // the offset of current mapping entry
+ addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+ //find a new mapping entry
+ BlkNum = 0xffff;
+ for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+ {
+ eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+ if( (LogicalAddress & 0xff) == 0)
+ {
+ BlkNum = i-EFUSE_USAGE_MAP_START;
+ break;
+ }
+ else if(( (LogicalAddress >> 8) & 0xff) == 0)
+ {
+ if (i != EFUSE_USAGE_MAP_END)
+ {
+ BlkNum = i+1-EFUSE_USAGE_MAP_START;
+ }
+ break;
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum));
+ if(BlkNum == 0xffff)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
+ return FALSE;
+ }
+
+ //invalidate the original mapping entry if new entry is not found
+ tmpaddr = addr;
+
+ if(addr % 2 != 0)
+ addr = addr -1;
+ InBuf[0] = addr;
+ InBuf[1] = 2;
+
+ eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+ // write the logical address
+ if(tmpaddr%2 != 0)
+ {
+ // Invalidate the high byte
+ for (i=8; i<15; i++)
+ {
+ if( ( (InBuf[2] >> i) & 0x01) == 0)
+ {
+ InBuf[2] |= (0x1 <<i);
+ break;
+ }
+ }
+ }
+ else
+ {
+ // invalidate the low byte
+ for (i=0; i<8; i++)
+ {
+ if( ( (InBuf[2] >> i) & 0x01) == 0)
+ {
+ InBuf[2] |= (0x1 <<i);
+ break;
+ }
+ }
+ }
+ eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
+ }
+ }
+ while(!bWriteSuccess);
+
+ return TRUE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID eFuseWritePhysical(
+ IN PRTMP_ADAPTER pAd,
+ PUSHORT lpInBuffer,
+ ULONG nInBufferSize,
+ PUCHAR lpOutBuffer,
+ ULONG nOutBufferSize
+)
+{
+ USHORT* pInBuf = (USHORT*)lpInBuffer;
+ int i;
+ //USHORT* pOutBuf = (USHORT*)ioBuffer;
+
+ USHORT Offset = pInBuf[0]; //addr
+ USHORT Length = pInBuf[1]; //length
+ USHORT* pValueX = &pInBuf[2]; //value ...
+ // Little-endian S | S Big-endian
+ // addr 3 2 1 0 | 0 1 2 3
+ // Ori-V D C B A | A B C D
+ //After swapping
+ // D C B A | D C B A
+ //Both the little and big-endian use the same sequence to write data.
+ //Therefore, we only need swap data when read the data.
+ for(i=0; i<Length; i+=2)
+ {
+ eFusePhysicalWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
+ }
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS eFuseWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData,
+ IN USHORT length)
+{
+ int i;
+
+ USHORT* pValueX = (PUSHORT) pData; //value ...
+ //The input value=3070 will be stored as following
+ // Little-endian S | S Big-endian
+ // addr 1 0 | 0 1
+ // Ori-V 30 70 | 30 70
+ //After swapping
+ // 30 70 | 70 30
+ //Casting
+ // 3070 | 7030 (x)
+ //The swapping should be removed for big-endian
+ for(i=0; i<length; i+=2)
+ {
+ eFuseWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
+ }
+
+ return TRUE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+INT set_eFuseGetFreeBlockCount_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ USHORT i;
+ USHORT LogicalAddress;
+ USHORT efusefreenum=0;
+ if(!pAd->bUseEfuse)
+ return FALSE;
+ for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
+ {
+ eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+ if( (LogicalAddress & 0xff) == 0)
+ {
+ efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
+ break;
+ }
+ else if(( (LogicalAddress >> 8) & 0xff) == 0)
+ {
+ efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i);
+ break;
+ }
+
+ if(i == EFUSE_USAGE_MAP_END)
+ efusefreenum = 0;
+ }
+ printk("efuseFreeNumber is %d\n",efusefreenum);
+ return TRUE;
+}
+INT set_eFusedump_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+USHORT InBuf[3];
+ INT i=0;
+ if(!pAd->bUseEfuse)
+ return FALSE;
+ for(i =0; i<EFUSE_USAGE_MAP_END/2; i++)
+ {
+ InBuf[0] = 2*i;
+ InBuf[1] = 2;
+ InBuf[2] = 0x0;
+
+ eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+ if(i%4==0)
+ printk("\nBlock %x:",i/8);
+ printk("%04x ",InBuf[2]);
+ }
+ return TRUE;
+}
+INT set_eFuseLoadFromBin_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR *src;
+ struct file *srcf;
+ INT retval, orgfsuid, orgfsgid;
+ mm_segment_t orgfs;
+ UCHAR *buffer;
+ UCHAR BinFileSize=0;
+ INT i = 0,j=0,k=1;
+ USHORT *PDATA;
+ USHORT DATA;
+ BinFileSize=strlen("RT30xxEEPROM.bin");
+ src = kmalloc(128, MEM_ALLOC_FLAG);
+ NdisZeroMemory(src, 128);
+
+ if(strlen(arg)>0)
+ {
+
+ NdisMoveMemory(src, arg, strlen(arg));
+ }
+
+ else
+ {
+
+ NdisMoveMemory(src, "RT30xxEEPROM.bin", BinFileSize);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
+ buffer = kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);
+
+ if(buffer == NULL)
+ {
+ kfree(src);
+ return FALSE;
+}
+ PDATA=kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);
+
+ if(PDATA==NULL)
+ {
+ kfree(src);
+
+ kfree(buffer);
+ return FALSE;
+ }
+ /* Don't change to uid 0, let the file be opened as the "normal" user */
+#if 0
+ orgfsuid = current->fsuid;
+ orgfsgid = current->fsgid;
+ current->fsuid=current->fsgid = 0;
+#endif
+ orgfs = get_fs();
+ set_fs(KERNEL_DS);
+
+ if (src && *src)
+ {
+ srcf = filp_open(src, O_RDONLY, 0);
+ if (IS_ERR(srcf))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
+ return FALSE;
+ }
+ else
+ {
+ // The object must have a read method
+ if (srcf->f_op && srcf->f_op->read)
+ {
+ memset(buffer, 0x00, MAX_EEPROM_BIN_FILE_SIZE);
+ while(srcf->f_op->read(srcf, &buffer[i], 1, &srcf->f_pos)==1)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[i]));
+ if((i+1)%8==0)
+ DBGPRINT(RT_DEBUG_TRACE, ("\n"));
+ i++;
+ if(i>=MAX_EEPROM_BIN_FILE_SIZE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld reading %s, The file is too large[1024]\n", -PTR_ERR(srcf),src));
+ kfree(PDATA);
+ kfree(buffer);
+ kfree(src);
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n"));
+ kfree(PDATA);
+ kfree(buffer);
+ kfree(src);
+ return FALSE;
+ }
+ }
+
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n"));
+ kfree(PDATA);
+ kfree(buffer);
+ return FALSE;
+
+ }
+
+
+ retval=filp_close(srcf,NULL);
+
+ if (retval)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
+ }
+ set_fs(orgfs);
+#if 0
+ current->fsuid = orgfsuid;
+ current->fsgid = orgfsgid;
+#endif
+ for(j=0;j<i;j++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[j]));
+ if((j+1)%2==0)
+ PDATA[j/2%8]=((buffer[j]<<8)&0xff00)|(buffer[j-1]&0xff);
+ if(j%16==0)
+ {
+ k=buffer[j];
+ }
+ else
+ {
+ k&=buffer[j];
+ if((j+1)%16==0)
+ {
+
+ DBGPRINT(RT_DEBUG_TRACE, (" result=%02X,blk=%02x\n",k,j/16));
+
+ if(k!=0xff)
+ eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
+ else
+ {
+ if(eFuseReadRegisters(pAd,j, 2,(PUSHORT)&DATA)!=0x3f)
+ eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
+ }
+ /*
+ for(l=0;l<8;l++)
+ printk("%04x ",PDATA[l]);
+ printk("\n");
+ */
+ NdisZeroMemory(PDATA,16);
+
+
+ }
+ }
+
+
+ }
+
+
+ kfree(PDATA);
+ kfree(buffer);
+ kfree(src);
+ return TRUE;
+}
+NTSTATUS eFuseWriteRegistersFromBin(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ IN USHORT* pData)
+{
+ USHORT i;
+ USHORT eFuseData;
+ USHORT LogicalAddress, BlkNum = 0xffff;
+ UCHAR EFSROM_AOUT,Loop=0;
+ EFUSE_CTRL_STRUC eFuseCtrlStruc;
+ USHORT efuseDataOffset;
+ UINT32 data,tempbuffer;
+ USHORT addr,tmpaddr, InBuf[3], tmpOffset;
+ UINT32 buffer[4];
+ BOOLEAN bWriteSuccess = TRUE;
+ BOOLEAN bNotWrite=TRUE;
+ BOOLEAN bAllocateNewBlk=TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin Offset=%x, pData=%04x:%04x:%04x:%04x\n", Offset, *pData,*(pData+1),*(pData+2),*(pData+3)));
+
+ do
+ {
+ //Step 0. find the entry in the mapping table
+ //The address of EEPROM is 2-bytes alignment.
+ //The last bit is used for alignment, so it must be 0.
+ Loop++;
+ tmpOffset = Offset & 0xfffe;
+ EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
+
+ if( EFSROM_AOUT == 0x3f)
+ { //find available logical address pointer
+ //the logical address does not exist, find an empty one
+ //from the first address of block 45=16*45=0x2d0 to the last address of block 47
+ //==>48*16-3(reserved)=2FC
+ bAllocateNewBlk=TRUE;
+ for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+ {
+ //Retrive the logical block nubmer form each logical address pointer
+ //It will access two logical address pointer each time.
+ eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+ if( (LogicalAddress & 0xff) == 0)
+ {//Not used logical address pointer
+ BlkNum = i-EFUSE_USAGE_MAP_START;
+ break;
+ }
+ else if(( (LogicalAddress >> 8) & 0xff) == 0)
+ {//Not used logical address pointer
+ if (i != EFUSE_USAGE_MAP_END)
+ {
+ BlkNum = i-EFUSE_USAGE_MAP_START+1;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ bAllocateNewBlk=FALSE;
+ BlkNum = EFSROM_AOUT;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
+
+ if(BlkNum == 0xffff)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
+ return FALSE;
+ }
+ //Step 1.1.0
+ //If the block is not existing in mapping table, create one
+ //and write down the 16-bytes data to the new block
+ if(bAllocateNewBlk)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n"));
+ efuseDataOffset = EFUSE_DATA3;
+ for(i=0; i< 4; i++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i]));
+ tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
+
+
+ RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer);
+ efuseDataOffset -= 4;
+
+ }
+ /////////////////////////////////////////////////////////////////
+
+ //Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+ eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ;
+
+ //Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
+ eFuseCtrlStruc.field.EFSROM_MODE = 3;
+
+ //Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+
+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+ //Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
+ i = 0;
+ while(i < 100)
+ {
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+ break;
+
+ RTMPusecDelay(2);
+ i++;
+ }
+
+ }
+ else
+ { //Step1.2.
+ //If the same logical number is existing, check if the writting data and the data
+ //saving in this block are the same.
+ /////////////////////////////////////////////////////////////////
+ //read current values of 16-byte block
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ //Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+ //Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
+ eFuseCtrlStruc.field.EFSROM_MODE = 0;
+
+ //Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+ //Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+ i = 0;
+ while(i < 100)
+ {
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+ break;
+ RTMPusecDelay(2);
+ i++;
+ }
+
+ //Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
+ efuseDataOffset = EFUSE_DATA3;
+ for(i=0; i< 4; i++)
+ {
+ RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]);
+ efuseDataOffset -= 4;
+ }
+ //Step1.2.5. Check if the data of efuse and the writing data are the same.
+ for(i =0; i<4; i++)
+ {
+ tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
+ DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer));
+
+ if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i]))
+ bNotWrite&=TRUE;
+ else
+ {
+ bNotWrite&=FALSE;
+ break;
+ }
+ }
+ if(!bNotWrite)
+ {
+ printk("The data is not the same\n");
+
+ for(i =0; i<8; i++)
+ {
+ addr = BlkNum * 0x10 ;
+
+ InBuf[0] = addr+2*i;
+ InBuf[1] = 2;
+ InBuf[2] = pData[i];
+
+ eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
+ }
+
+ }
+ else
+ return TRUE;
+ }
+
+
+
+ //Step 2. Write mapping table
+ addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+ tmpaddr = addr;
+
+ if(addr % 2 != 0)
+ addr = addr -1;
+ InBuf[0] = addr;
+ InBuf[1] = 2;
+
+ //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
+ tmpOffset = Offset;
+ tmpOffset >>= 4;
+ tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
+ tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
+
+ // write the logical address
+ if(tmpaddr%2 != 0)
+ InBuf[2] = tmpOffset<<8;
+ else
+ InBuf[2] = tmpOffset;
+
+ eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
+
+ //Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
+ bWriteSuccess = TRUE;
+ for(i =0; i<8; i++)
+ {
+ addr = BlkNum * 0x10 ;
+
+ InBuf[0] = addr+2*i;
+ InBuf[1] = 2;
+ InBuf[2] = 0x0;
+
+ eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+ DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2]));
+ if(pData[i] != InBuf[2])
+ {
+ bWriteSuccess = FALSE;
+ break;
+ }
+ }
+
+ //Step 4. invlidate mapping entry and find a free mapping entry if not succeed
+
+ if (!bWriteSuccess&&Loop<2)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum));
+
+ // the offset of current mapping entry
+ addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+ //find a new mapping entry
+ BlkNum = 0xffff;
+ for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+ {
+ eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+ if( (LogicalAddress & 0xff) == 0)
+ {
+ BlkNum = i-EFUSE_USAGE_MAP_START;
+ break;
+ }
+ else if(( (LogicalAddress >> 8) & 0xff) == 0)
+ {
+ if (i != EFUSE_USAGE_MAP_END)
+ {
+ BlkNum = i+1-EFUSE_USAGE_MAP_START;
+ }
+ break;
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum));
+ if(BlkNum == 0xffff)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n"));
+ return FALSE;
+ }
+
+ //invalidate the original mapping entry if new entry is not found
+ tmpaddr = addr;
+
+ if(addr % 2 != 0)
+ addr = addr -1;
+ InBuf[0] = addr;
+ InBuf[1] = 2;
+
+ eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+ // write the logical address
+ if(tmpaddr%2 != 0)
+ {
+ // Invalidate the high byte
+ for (i=8; i<15; i++)
+ {
+ if( ( (InBuf[2] >> i) & 0x01) == 0)
+ {
+ InBuf[2] |= (0x1 <<i);
+ break;
+ }
+ }
+ }
+ else
+ {
+ // invalidate the low byte
+ for (i=0; i<8; i++)
+ {
+ if( ( (InBuf[2] >> i) & 0x01) == 0)
+ {
+ InBuf[2] |= (0x1 <<i);
+ break;
+ }
+ }
+ }
+ eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
+ }
+
+ }
+ while(!bWriteSuccess&&Loop<2);
+
+ return TRUE;
+}
+
+#endif // RT30xx //
+//2008/09/11:KH add to support efuse-->
+
diff --git a/drivers/staging/rt3070/common/md5.c b/drivers/staging/rt3070/common/md5.c
new file mode 100644
index 00000000000..774776b4b8c
--- /dev/null
+++ b/drivers/staging/rt3070/common/md5.c
@@ -0,0 +1,1427 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ md5.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ jan 10-28-03 Initial
+ Rita 11-23-04 Modify MD5 and SHA-1
+ Rita 10-14-05 Modify SHA-1 in big-endian platform
+ */
+#include "../rt_config.h"
+
+/**
+ * md5_mac:
+ * @key: pointer to the key used for MAC generation
+ * @key_len: length of the key in bytes
+ * @data: pointer to the data area for which the MAC is generated
+ * @data_len: length of the data in bytes
+ * @mac: pointer to the buffer holding space for the MAC; the buffer should
+ * have space for 128-bit (16 bytes) MD5 hash value
+ *
+ * md5_mac() determines the message authentication code by using secure hash
+ * MD5(key | data | key).
+ */
+void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
+{
+ MD5_CTX context;
+
+ MD5Init(&context);
+ MD5Update(&context, key, key_len);
+ MD5Update(&context, data, data_len);
+ MD5Update(&context, key, key_len);
+ MD5Final(mac, &context);
+}
+
+/**
+ * hmac_md5:
+ * @key: pointer to the key used for MAC generation
+ * @key_len: length of the key in bytes
+ * @data: pointer to the data area for which the MAC is generated
+ * @data_len: length of the data in bytes
+ * @mac: pointer to the buffer holding space for the MAC; the buffer should
+ * have space for 128-bit (16 bytes) MD5 hash value
+ *
+ * hmac_md5() determines the message authentication code using HMAC-MD5.
+ * This implementation is based on the sample code presented in RFC 2104.
+ */
+void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
+{
+ MD5_CTX context;
+ u8 k_ipad[65]; /* inner padding - key XORd with ipad */
+ u8 k_opad[65]; /* outer padding - key XORd with opad */
+ u8 tk[16];
+ int i;
+
+ //assert(key != NULL && data != NULL && mac != NULL);
+
+ /* if key is longer than 64 bytes reset it to key = MD5(key) */
+ if (key_len > 64) {
+ MD5_CTX ttcontext;
+
+ MD5Init(&ttcontext);
+ MD5Update(&ttcontext, key, key_len);
+ MD5Final(tk, &ttcontext);
+ //key=(PUCHAR)ttcontext.buf;
+ key = tk;
+ key_len = 16;
+ }
+
+ /* the HMAC_MD5 transform looks like:
+ *
+ * MD5(K XOR opad, MD5(K XOR ipad, text))
+ *
+ * where K is an n byte key
+ * ipad is the byte 0x36 repeated 64 times
+ * opad is the byte 0x5c repeated 64 times
+ * and text is the data being protected */
+
+ /* start out by storing key in pads */
+ NdisZeroMemory(k_ipad, sizeof(k_ipad));
+ NdisZeroMemory(k_opad, sizeof(k_opad));
+ //assert(key_len < sizeof(k_ipad));
+ NdisMoveMemory(k_ipad, key, key_len);
+ NdisMoveMemory(k_opad, key, key_len);
+
+ /* XOR key with ipad and opad values */
+ for (i = 0; i < 64; i++) {
+ k_ipad[i] ^= 0x36;
+ k_opad[i] ^= 0x5c;
+ }
+
+ /* perform inner MD5 */
+ MD5Init(&context); /* init context for 1st pass */
+ MD5Update(&context, k_ipad, 64); /* start with inner pad */
+ MD5Update(&context, data, data_len); /* then text of datagram */
+ MD5Final(mac, &context); /* finish up 1st pass */
+
+ /* perform outer MD5 */
+ MD5Init(&context); /* init context for 2nd pass */
+ MD5Update(&context, k_opad, 64); /* start with outer pad */
+ MD5Update(&context, mac, 16); /* then results of 1st hash */
+ MD5Final(mac, &context); /* finish up 2nd pass */
+}
+
+#ifndef RT_BIG_ENDIAN
+#define byteReverse(buf, len) /* Nothing */
+#else
+void byteReverse(unsigned char *buf, unsigned longs);
+void byteReverse(unsigned char *buf, unsigned longs)
+{
+ do {
+ *(UINT32 *)buf = SWAP32(*(UINT32 *)buf);
+ buf += 4;
+ } while (--longs);
+}
+#endif
+
+
+/* ========================== MD5 implementation =========================== */
+// four base functions for MD5
+#define MD5_F1(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define MD5_F2(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define MD5_F3(x, y, z) ((x) ^ (y) ^ (z))
+#define MD5_F4(x, y, z) ((y) ^ ((x) | (~z)))
+#define CYCLIC_LEFT_SHIFT(w, s) (((w) << (s)) | ((w) >> (32-(s))))
+
+#define MD5Step(f, w, x, y, z, data, t, s) \
+ ( w += f(x, y, z) + data + t, w = (CYCLIC_LEFT_SHIFT(w, s)) & 0xffffffff, w += x )
+
+
+/*
+ * Function Description:
+ * Initiate MD5 Context satisfied in RFC 1321
+ *
+ * Arguments:
+ * pCtx Pointer to MD5 context
+ *
+ * Return Value:
+ * None
+ */
+VOID MD5Init(MD5_CTX *pCtx)
+{
+ pCtx->Buf[0]=0x67452301;
+ pCtx->Buf[1]=0xefcdab89;
+ pCtx->Buf[2]=0x98badcfe;
+ pCtx->Buf[3]=0x10325476;
+
+ pCtx->LenInBitCount[0]=0;
+ pCtx->LenInBitCount[1]=0;
+}
+
+
+/*
+ * Function Description:
+ * Update MD5 Context, allow of an arrary of octets as the next portion
+ * of the message
+ *
+ * Arguments:
+ * pCtx Pointer to MD5 context
+ * pData Pointer to input data
+ * LenInBytes The length of input data (unit: byte)
+ *
+ * Return Value:
+ * None
+ *
+ * Note:
+ * Called after MD5Init or MD5Update(itself)
+ */
+VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes)
+{
+
+ UINT32 TfTimes;
+ UINT32 temp;
+ unsigned int i;
+
+ temp = pCtx->LenInBitCount[0];
+
+ pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3));
+
+ if (pCtx->LenInBitCount[0] < temp)
+ pCtx->LenInBitCount[1]++; //carry in
+
+ pCtx->LenInBitCount[1] += LenInBytes >> 29;
+
+ // mod 64 bytes
+ temp = (temp >> 3) & 0x3f;
+
+ // process lacks of 64-byte data
+ if (temp)
+ {
+ UCHAR *pAds = (UCHAR *) pCtx->Input + temp;
+
+ if ((temp+LenInBytes) < 64)
+ {
+ NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes);
+ return;
+ }
+
+ NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp);
+ byteReverse(pCtx->Input, 16);
+ MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+
+ pData += 64-temp;
+ LenInBytes -= 64-temp;
+ } // end of if (temp)
+
+
+ TfTimes = (LenInBytes >> 6);
+
+ for (i=TfTimes; i>0; i--)
+ {
+ NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64);
+ byteReverse(pCtx->Input, 16);
+ MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+ pData += 64;
+ LenInBytes -= 64;
+ } // end of for
+
+ // buffering lacks of 64-byte data
+ if(LenInBytes)
+ NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes);
+
+}
+
+
+/*
+ * Function Description:
+ * Append padding bits and length of original message in the tail
+ * The message digest has to be completed in the end
+ *
+ * Arguments:
+ * Digest Output of Digest-Message for MD5
+ * pCtx Pointer to MD5 context
+ *
+ * Return Value:
+ * None
+ *
+ * Note:
+ * Called after MD5Update
+ */
+VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx)
+{
+ UCHAR Remainder;
+ UCHAR PadLenInBytes;
+ UCHAR *pAppend=0;
+ unsigned int i;
+
+ Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f);
+
+ PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder);
+
+ pAppend = (UCHAR *)pCtx->Input + Remainder;
+
+ // padding bits without crossing block(64-byte based) boundary
+ if (Remainder < 56)
+ {
+ *pAppend = 0x80;
+ PadLenInBytes --;
+
+ NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes);
+
+ // add data-length field, from low to high
+ for (i=0; i<4; i++)
+ {
+ pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff);
+ pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff);
+ }
+
+ byteReverse(pCtx->Input, 16);
+ MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+ } // end of if
+
+ // padding bits with crossing block(64-byte based) boundary
+ else
+ {
+ // the first block ===
+ *pAppend = 0x80;
+ PadLenInBytes --;
+
+ NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1));
+ PadLenInBytes -= (64 - Remainder - 1);
+
+ byteReverse(pCtx->Input, 16);
+ MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+
+
+ // the second block ===
+ NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes);
+
+ // add data-length field
+ for (i=0; i<4; i++)
+ {
+ pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff);
+ pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff);
+ }
+
+ byteReverse(pCtx->Input, 16);
+ MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+ } // end of else
+
+
+ NdisMoveMemory((UCHAR *)Digest, (UINT32 *)pCtx->Buf, 16); // output
+ byteReverse((UCHAR *)Digest, 4);
+ NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free
+}
+
+
+/*
+ * Function Description:
+ * The central algorithm of MD5, consists of four rounds and sixteen
+ * steps per round
+ *
+ * Arguments:
+ * Buf Buffers of four states (output: 16 bytes)
+ * Mes Input data (input: 64 bytes)
+ *
+ * Return Value:
+ * None
+ *
+ * Note:
+ * Called by MD5Update or MD5Final
+ */
+VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16])
+{
+ UINT32 Reg[4], Temp;
+ unsigned int i;
+
+ static UCHAR LShiftVal[16] =
+ {
+ 7, 12, 17, 22,
+ 5, 9 , 14, 20,
+ 4, 11, 16, 23,
+ 6, 10, 15, 21,
+ };
+
+
+ // [equal to 4294967296*abs(sin(index))]
+ static UINT32 MD5Table[64] =
+ {
+ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+
+ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+ 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+
+ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
+ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+
+ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+ };
+
+
+ for (i=0; i<4; i++)
+ Reg[i]=Buf[i];
+
+
+ // 64 steps in MD5 algorithm
+ for (i=0; i<16; i++)
+ {
+ MD5Step(MD5_F1, Reg[0], Reg[1], Reg[2], Reg[3], Mes[i],
+ MD5Table[i], LShiftVal[i & 0x3]);
+
+ // one-word right shift
+ Temp = Reg[3];
+ Reg[3] = Reg[2];
+ Reg[2] = Reg[1];
+ Reg[1] = Reg[0];
+ Reg[0] = Temp;
+ }
+ for (i=16; i<32; i++)
+ {
+ MD5Step(MD5_F2, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(5*(i & 0xf)+1) & 0xf],
+ MD5Table[i], LShiftVal[(0x1 << 2)+(i & 0x3)]);
+
+ // one-word right shift
+ Temp = Reg[3];
+ Reg[3] = Reg[2];
+ Reg[2] = Reg[1];
+ Reg[1] = Reg[0];
+ Reg[0] = Temp;
+ }
+ for (i=32; i<48; i++)
+ {
+ MD5Step(MD5_F3, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(3*(i & 0xf)+5) & 0xf],
+ MD5Table[i], LShiftVal[(0x1 << 3)+(i & 0x3)]);
+
+ // one-word right shift
+ Temp = Reg[3];
+ Reg[3] = Reg[2];
+ Reg[2] = Reg[1];
+ Reg[1] = Reg[0];
+ Reg[0] = Temp;
+ }
+ for (i=48; i<64; i++)
+ {
+ MD5Step(MD5_F4, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(7*(i & 0xf)) & 0xf],
+ MD5Table[i], LShiftVal[(0x3 << 2)+(i & 0x3)]);
+
+ // one-word right shift
+ Temp = Reg[3];
+ Reg[3] = Reg[2];
+ Reg[2] = Reg[1];
+ Reg[1] = Reg[0];
+ Reg[0] = Temp;
+ }
+
+
+ // (temporary)output
+ for (i=0; i<4; i++)
+ Buf[i] += Reg[i];
+
+}
+
+
+
+/* ========================= SHA-1 implementation ========================== */
+// four base functions for SHA-1
+#define SHA1_F1(b, c, d) (((b) & (c)) | ((~b) & (d)))
+#define SHA1_F2(b, c, d) ((b) ^ (c) ^ (d))
+#define SHA1_F3(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
+
+
+#define SHA1Step(f, a, b, c, d, e, w, k) \
+ ( e += ( f(b, c, d) + w + k + CYCLIC_LEFT_SHIFT(a, 5)) & 0xffffffff, \
+ b = CYCLIC_LEFT_SHIFT(b, 30) )
+
+//Initiate SHA-1 Context satisfied in RFC 3174
+VOID SHAInit(SHA_CTX *pCtx)
+{
+ pCtx->Buf[0]=0x67452301;
+ pCtx->Buf[1]=0xefcdab89;
+ pCtx->Buf[2]=0x98badcfe;
+ pCtx->Buf[3]=0x10325476;
+ pCtx->Buf[4]=0xc3d2e1f0;
+
+ pCtx->LenInBitCount[0]=0;
+ pCtx->LenInBitCount[1]=0;
+}
+
+/*
+ * Function Description:
+ * Update SHA-1 Context, allow of an arrary of octets as the next
+ * portion of the message
+ *
+ * Arguments:
+ * pCtx Pointer to SHA-1 context
+ * pData Pointer to input data
+ * LenInBytes The length of input data (unit: byte)
+ *
+ * Return Value:
+ * error indicate more than pow(2,64) bits of data
+ *
+ * Note:
+ * Called after SHAInit or SHAUpdate(itself)
+ */
+UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes)
+{
+ UINT32 TfTimes;
+ UINT32 temp1,temp2;
+ unsigned int i;
+ UCHAR err=1;
+
+ temp1 = pCtx->LenInBitCount[0];
+ temp2 = pCtx->LenInBitCount[1];
+
+ pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3));
+ if (pCtx->LenInBitCount[0] < temp1)
+ pCtx->LenInBitCount[1]++; //carry in
+
+
+ pCtx->LenInBitCount[1] = (UINT32) (pCtx->LenInBitCount[1] +(LenInBytes >> 29));
+ if (pCtx->LenInBitCount[1] < temp2)
+ return (err); //check total length of original data
+
+
+ // mod 64 bytes
+ temp1 = (temp1 >> 3) & 0x3f;
+
+ // process lacks of 64-byte data
+ if (temp1)
+ {
+ UCHAR *pAds = (UCHAR *) pCtx->Input + temp1;
+
+ if ((temp1+LenInBytes) < 64)
+ {
+ NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes);
+ return (0);
+ }
+
+ NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp1);
+ byteReverse((UCHAR *)pCtx->Input, 16);
+
+ NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
+ SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+
+ pData += 64-temp1;
+ LenInBytes -= 64-temp1;
+ } // end of if (temp1)
+
+
+ TfTimes = (LenInBytes >> 6);
+
+ for (i=TfTimes; i>0; i--)
+ {
+ NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64);
+ byteReverse((UCHAR *)pCtx->Input, 16);
+
+ NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
+ SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+ pData += 64;
+ LenInBytes -= 64;
+ } // end of for
+
+ // buffering lacks of 64-byte data
+ if(LenInBytes)
+ NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes);
+
+ return (0);
+
+}
+
+// Append padding bits and length of original message in the tail
+// The message digest has to be completed in the end
+VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20])
+{
+ UCHAR Remainder;
+ UCHAR PadLenInBytes;
+ UCHAR *pAppend=0;
+ unsigned int i;
+
+ Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f);
+
+ pAppend = (UCHAR *)pCtx->Input + Remainder;
+
+ PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder);
+
+ // padding bits without crossing block(64-byte based) boundary
+ if (Remainder < 56)
+ {
+ *pAppend = 0x80;
+ PadLenInBytes --;
+
+ NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes);
+
+ // add data-length field, from high to low
+ for (i=0; i<4; i++)
+ {
+ pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff);
+ pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff);
+ }
+
+ byteReverse((UCHAR *)pCtx->Input, 16);
+ NdisZeroMemory((UCHAR *)pCtx->Input + 64, 14);
+ SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+ } // end of if
+
+ // padding bits with crossing block(64-byte based) boundary
+ else
+ {
+ // the first block ===
+ *pAppend = 0x80;
+ PadLenInBytes --;
+
+ NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1));
+ PadLenInBytes -= (64 - Remainder - 1);
+
+ byteReverse((UCHAR *)pCtx->Input, 16);
+ NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
+ SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+
+
+ // the second block ===
+ NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes);
+
+ // add data-length field
+ for (i=0; i<4; i++)
+ {
+ pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff);
+ pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff);
+ }
+
+ byteReverse((UCHAR *)pCtx->Input, 16);
+ NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
+ SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+ } // end of else
+
+
+ //Output, bytereverse
+ for (i=0; i<20; i++)
+ {
+ Digest [i] = (UCHAR)(pCtx->Buf[i>>2] >> 8*(3-(i & 0x3)));
+ }
+
+ NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free
+}
+
+
+// The central algorithm of SHA-1, consists of four rounds and
+// twenty steps per round
+VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20])
+{
+ UINT32 Reg[5],Temp;
+ unsigned int i;
+ UINT32 W[80];
+
+ static UINT32 SHA1Table[4] = { 0x5a827999, 0x6ed9eba1,
+ 0x8f1bbcdc, 0xca62c1d6 };
+
+ Reg[0]=Buf[0];
+ Reg[1]=Buf[1];
+ Reg[2]=Buf[2];
+ Reg[3]=Buf[3];
+ Reg[4]=Buf[4];
+
+ //the first octet of a word is stored in the 0th element, bytereverse
+ for(i = 0; i < 16; i++)
+ {
+ W[i] = (Mes[i] >> 24) & 0xff;
+ W[i] |= (Mes[i] >> 8 ) & 0xff00;
+ W[i] |= (Mes[i] << 8 ) & 0xff0000;
+ W[i] |= (Mes[i] << 24) & 0xff000000;
+ }
+
+
+ for (i = 0; i < 64; i++)
+ W[16+i] = CYCLIC_LEFT_SHIFT(W[i] ^ W[2+i] ^ W[8+i] ^ W[13+i], 1);
+
+
+ // 80 steps in SHA-1 algorithm
+ for (i=0; i<80; i++)
+ {
+ if (i<20)
+ SHA1Step(SHA1_F1, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
+ W[i], SHA1Table[0]);
+
+ else if (i>=20 && i<40)
+ SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
+ W[i], SHA1Table[1]);
+
+ else if (i>=40 && i<60)
+ SHA1Step(SHA1_F3, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
+ W[i], SHA1Table[2]);
+
+ else
+ SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
+ W[i], SHA1Table[3]);
+
+
+ // one-word right shift
+ Temp = Reg[4];
+ Reg[4] = Reg[3];
+ Reg[3] = Reg[2];
+ Reg[2] = Reg[1];
+ Reg[1] = Reg[0];
+ Reg[0] = Temp;
+
+ } // end of for-loop
+
+
+ // (temporary)output
+ for (i=0; i<5; i++)
+ Buf[i] += Reg[i];
+
+}
+
+
+/* ========================= AES En/Decryption ========================== */
+
+/* forward S-box */
+static uint32 FSb[256] =
+{
+ 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
+ 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
+ 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
+ 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
+ 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
+ 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+ 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
+ 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
+ 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
+ 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
+ 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
+ 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+ 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
+ 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
+ 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
+ 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
+ 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
+ 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+ 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
+ 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
+ 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
+ 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
+ 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
+ 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+ 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
+ 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
+ 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
+ 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
+ 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
+ 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+ 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
+ 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
+};
+
+/* forward table */
+#define FT \
+\
+ V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \
+ V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \
+ V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \
+ V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \
+ V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \
+ V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \
+ V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \
+ V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \
+ V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \
+ V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \
+ V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \
+ V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \
+ V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \
+ V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \
+ V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \
+ V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \
+ V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \
+ V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \
+ V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \
+ V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \
+ V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \
+ V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \
+ V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \
+ V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \
+ V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \
+ V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \
+ V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \
+ V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \
+ V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \
+ V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \
+ V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \
+ V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \
+ V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \
+ V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \
+ V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \
+ V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \
+ V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \
+ V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \
+ V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \
+ V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \
+ V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \
+ V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \
+ V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \
+ V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \
+ V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \
+ V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \
+ V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \
+ V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \
+ V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \
+ V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \
+ V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \
+ V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \
+ V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \
+ V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \
+ V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \
+ V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \
+ V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \
+ V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \
+ V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \
+ V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \
+ V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \
+ V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \
+ V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \
+ V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static uint32 FT0[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static uint32 FT1[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static uint32 FT2[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static uint32 FT3[256] = { FT };
+#undef V
+
+#undef FT
+
+/* reverse S-box */
+
+static uint32 RSb[256] =
+{
+ 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
+ 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
+ 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
+ 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
+ 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
+ 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+ 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
+ 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
+ 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
+ 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
+ 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
+ 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+ 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
+ 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
+ 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
+ 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
+ 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
+ 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+ 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
+ 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
+ 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
+ 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
+ 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
+ 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+ 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
+ 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
+ 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
+ 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
+ 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
+ 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
+ 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
+};
+
+/* reverse table */
+
+#define RT \
+\
+ V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \
+ V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \
+ V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \
+ V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \
+ V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \
+ V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \
+ V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \
+ V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \
+ V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \
+ V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \
+ V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \
+ V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \
+ V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \
+ V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \
+ V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \
+ V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \
+ V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \
+ V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \
+ V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \
+ V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \
+ V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \
+ V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \
+ V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \
+ V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \
+ V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \
+ V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \
+ V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \
+ V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \
+ V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \
+ V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \
+ V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \
+ V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \
+ V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \
+ V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \
+ V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \
+ V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \
+ V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \
+ V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \
+ V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \
+ V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \
+ V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \
+ V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \
+ V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \
+ V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \
+ V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \
+ V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \
+ V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \
+ V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \
+ V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \
+ V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \
+ V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \
+ V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \
+ V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \
+ V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \
+ V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \
+ V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \
+ V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \
+ V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \
+ V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \
+ V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \
+ V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \
+ V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \
+ V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \
+ V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static uint32 RT0[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static uint32 RT1[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static uint32 RT2[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static uint32 RT3[256] = { RT };
+#undef V
+
+#undef RT
+
+/* round constants */
+
+static uint32 RCON[10] =
+{
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
+ 0x1B000000, 0x36000000
+};
+
+/* key schedule tables */
+
+static int KT_init = 1;
+
+static uint32 KT0[256];
+static uint32 KT1[256];
+static uint32 KT2[256];
+static uint32 KT3[256];
+
+/* platform-independant 32-bit integer manipulation macros */
+
+#define GET_UINT32(n,b,i) \
+{ \
+ (n) = ( (uint32) (b)[(i) ] << 24 ) \
+ | ( (uint32) (b)[(i) + 1] << 16 ) \
+ | ( (uint32) (b)[(i) + 2] << 8 ) \
+ | ( (uint32) (b)[(i) + 3] ); \
+}
+
+#define PUT_UINT32(n,b,i) \
+{ \
+ (b)[(i) ] = (uint8) ( (n) >> 24 ); \
+ (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \
+ (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \
+ (b)[(i) + 3] = (uint8) ( (n) ); \
+}
+
+/* AES key scheduling routine */
+
+int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits )
+{
+ int i;
+ uint32 *RK, *SK;
+
+ switch( nbits )
+ {
+ case 128: ctx->nr = 10; break;
+ case 192: ctx->nr = 12; break;
+ case 256: ctx->nr = 14; break;
+ default : return( 1 );
+ }
+
+ RK = ctx->erk;
+
+ for( i = 0; i < (nbits >> 5); i++ )
+ {
+ GET_UINT32( RK[i], key, i * 4 );
+ }
+
+ /* setup encryption round keys */
+
+ switch( nbits )
+ {
+ case 128:
+
+ for( i = 0; i < 10; i++, RK += 4 )
+ {
+ RK[4] = RK[0] ^ RCON[i] ^
+ ( FSb[ (uint8) ( RK[3] >> 16 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( RK[3] >> 8 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( RK[3] ) ] << 8 ) ^
+ ( FSb[ (uint8) ( RK[3] >> 24 ) ] );
+
+ RK[5] = RK[1] ^ RK[4];
+ RK[6] = RK[2] ^ RK[5];
+ RK[7] = RK[3] ^ RK[6];
+ }
+ break;
+
+ case 192:
+
+ for( i = 0; i < 8; i++, RK += 6 )
+ {
+ RK[6] = RK[0] ^ RCON[i] ^
+ ( FSb[ (uint8) ( RK[5] >> 16 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( RK[5] >> 8 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( RK[5] ) ] << 8 ) ^
+ ( FSb[ (uint8) ( RK[5] >> 24 ) ] );
+
+ RK[7] = RK[1] ^ RK[6];
+ RK[8] = RK[2] ^ RK[7];
+ RK[9] = RK[3] ^ RK[8];
+ RK[10] = RK[4] ^ RK[9];
+ RK[11] = RK[5] ^ RK[10];
+ }
+ break;
+
+ case 256:
+
+ for( i = 0; i < 7; i++, RK += 8 )
+ {
+ RK[8] = RK[0] ^ RCON[i] ^
+ ( FSb[ (uint8) ( RK[7] >> 16 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( RK[7] >> 8 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( RK[7] ) ] << 8 ) ^
+ ( FSb[ (uint8) ( RK[7] >> 24 ) ] );
+
+ RK[9] = RK[1] ^ RK[8];
+ RK[10] = RK[2] ^ RK[9];
+ RK[11] = RK[3] ^ RK[10];
+
+ RK[12] = RK[4] ^
+ ( FSb[ (uint8) ( RK[11] >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( RK[11] >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( RK[11] >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8) ( RK[11] ) ] );
+
+ RK[13] = RK[5] ^ RK[12];
+ RK[14] = RK[6] ^ RK[13];
+ RK[15] = RK[7] ^ RK[14];
+ }
+ break;
+ }
+
+ /* setup decryption round keys */
+
+ if( KT_init )
+ {
+ for( i = 0; i < 256; i++ )
+ {
+ KT0[i] = RT0[ FSb[i] ];
+ KT1[i] = RT1[ FSb[i] ];
+ KT2[i] = RT2[ FSb[i] ];
+ KT3[i] = RT3[ FSb[i] ];
+ }
+
+ KT_init = 0;
+ }
+
+ SK = ctx->drk;
+
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+
+ for( i = 1; i < ctx->nr; i++ )
+ {
+ RK -= 8;
+
+ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
+ KT1[ (uint8) ( *RK >> 16 ) ] ^
+ KT2[ (uint8) ( *RK >> 8 ) ] ^
+ KT3[ (uint8) ( *RK ) ]; RK++;
+
+ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
+ KT1[ (uint8) ( *RK >> 16 ) ] ^
+ KT2[ (uint8) ( *RK >> 8 ) ] ^
+ KT3[ (uint8) ( *RK ) ]; RK++;
+
+ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
+ KT1[ (uint8) ( *RK >> 16 ) ] ^
+ KT2[ (uint8) ( *RK >> 8 ) ] ^
+ KT3[ (uint8) ( *RK ) ]; RK++;
+
+ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
+ KT1[ (uint8) ( *RK >> 16 ) ] ^
+ KT2[ (uint8) ( *RK >> 8 ) ] ^
+ KT3[ (uint8) ( *RK ) ]; RK++;
+ }
+
+ RK -= 8;
+
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+
+ return( 0 );
+}
+
+/* AES 128-bit block encryption routine */
+
+void rtmp_aes_encrypt(aes_context *ctx, uint8 input[16], uint8 output[16] )
+{
+ uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+ RK = ctx->erk;
+ GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
+ GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
+ GET_UINT32( X2, input, 8 ); X2 ^= RK[2];
+ GET_UINT32( X3, input, 12 ); X3 ^= RK[3];
+
+#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
+{ \
+ RK += 4; \
+ \
+ X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \
+ FT1[ (uint8) ( Y1 >> 16 ) ] ^ \
+ FT2[ (uint8) ( Y2 >> 8 ) ] ^ \
+ FT3[ (uint8) ( Y3 ) ]; \
+ \
+ X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \
+ FT1[ (uint8) ( Y2 >> 16 ) ] ^ \
+ FT2[ (uint8) ( Y3 >> 8 ) ] ^ \
+ FT3[ (uint8) ( Y0 ) ]; \
+ \
+ X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \
+ FT1[ (uint8) ( Y3 >> 16 ) ] ^ \
+ FT2[ (uint8) ( Y0 >> 8 ) ] ^ \
+ FT3[ (uint8) ( Y1 ) ]; \
+ \
+ X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \
+ FT1[ (uint8) ( Y0 >> 16 ) ] ^ \
+ FT2[ (uint8) ( Y1 >> 8 ) ] ^ \
+ FT3[ (uint8) ( Y2 ) ]; \
+}
+
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
+
+ if( ctx->nr > 10 )
+ {
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */
+ }
+
+ if( ctx->nr > 12 )
+ {
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */
+ }
+
+ /* last round */
+
+ RK += 4;
+
+ X0 = RK[0] ^ ( FSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8) ( Y3 ) ] );
+
+ X1 = RK[1] ^ ( FSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8) ( Y0 ) ] );
+
+ X2 = RK[2] ^ ( FSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8) ( Y1 ) ] );
+
+ X3 = RK[3] ^ ( FSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8) ( Y2 ) ] );
+
+ PUT_UINT32( X0, output, 0 );
+ PUT_UINT32( X1, output, 4 );
+ PUT_UINT32( X2, output, 8 );
+ PUT_UINT32( X3, output, 12 );
+}
+
+/* AES 128-bit block decryption routine */
+
+void rtmp_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] )
+{
+ uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+ RK = ctx->drk;
+
+ GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
+ GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
+ GET_UINT32( X2, input, 8 ); X2 ^= RK[2];
+ GET_UINT32( X3, input, 12 ); X3 ^= RK[3];
+
+#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
+{ \
+ RK += 4; \
+ \
+ X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \
+ RT1[ (uint8) ( Y3 >> 16 ) ] ^ \
+ RT2[ (uint8) ( Y2 >> 8 ) ] ^ \
+ RT3[ (uint8) ( Y1 ) ]; \
+ \
+ X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \
+ RT1[ (uint8) ( Y0 >> 16 ) ] ^ \
+ RT2[ (uint8) ( Y3 >> 8 ) ] ^ \
+ RT3[ (uint8) ( Y2 ) ]; \
+ \
+ X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \
+ RT1[ (uint8) ( Y1 >> 16 ) ] ^ \
+ RT2[ (uint8) ( Y0 >> 8 ) ] ^ \
+ RT3[ (uint8) ( Y3 ) ]; \
+ \
+ X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \
+ RT1[ (uint8) ( Y2 >> 16 ) ] ^ \
+ RT2[ (uint8) ( Y1 >> 8 ) ] ^ \
+ RT3[ (uint8) ( Y0 ) ]; \
+}
+
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
+
+ if( ctx->nr > 10 )
+ {
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */
+ }
+
+ if( ctx->nr > 12 )
+ {
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */
+ }
+
+ /* last round */
+
+ RK += 4;
+
+ X0 = RK[0] ^ ( RSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^
+ ( RSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^
+ ( RSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^
+ ( RSb[ (uint8) ( Y1 ) ] );
+
+ X1 = RK[1] ^ ( RSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^
+ ( RSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^
+ ( RSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^
+ ( RSb[ (uint8) ( Y2 ) ] );
+
+ X2 = RK[2] ^ ( RSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^
+ ( RSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^
+ ( RSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^
+ ( RSb[ (uint8) ( Y3 ) ] );
+
+ X3 = RK[3] ^ ( RSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^
+ ( RSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^
+ ( RSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^
+ ( RSb[ (uint8) ( Y0 ) ] );
+
+ PUT_UINT32( X0, output, 0 );
+ PUT_UINT32( X1, output, 4 );
+ PUT_UINT32( X2, output, 8 );
+ PUT_UINT32( X3, output, 12 );
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ SHA1 function
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID HMAC_SHA1(
+ IN UCHAR *text,
+ IN UINT text_len,
+ IN UCHAR *key,
+ IN UINT key_len,
+ IN UCHAR *digest)
+{
+ SHA_CTX context;
+ UCHAR k_ipad[65]; /* inner padding - key XORd with ipad */
+ UCHAR k_opad[65]; /* outer padding - key XORd with opad */
+ INT i;
+
+ // if key is longer than 64 bytes reset it to key=SHA1(key)
+ if (key_len > 64)
+ {
+ SHA_CTX tctx;
+ SHAInit(&tctx);
+ SHAUpdate(&tctx, key, key_len);
+ SHAFinal(&tctx, key);
+ key_len = 20;
+ }
+ NdisZeroMemory(k_ipad, sizeof(k_ipad));
+ NdisZeroMemory(k_opad, sizeof(k_opad));
+ NdisMoveMemory(k_ipad, key, key_len);
+ NdisMoveMemory(k_opad, key, key_len);
+
+ // XOR key with ipad and opad values
+ for (i = 0; i < 64; i++)
+ {
+ k_ipad[i] ^= 0x36;
+ k_opad[i] ^= 0x5c;
+ }
+
+ // perform inner SHA1
+ SHAInit(&context); /* init context for 1st pass */
+ SHAUpdate(&context, k_ipad, 64); /* start with inner pad */
+ SHAUpdate(&context, text, text_len); /* then text of datagram */
+ SHAFinal(&context, digest); /* finish up 1st pass */
+
+ //perform outer SHA1
+ SHAInit(&context); /* init context for 2nd pass */
+ SHAUpdate(&context, k_opad, 64); /* start with outer pad */
+ SHAUpdate(&context, digest, 20); /* then results of 1st hash */
+ SHAFinal(&context, digest); /* finish up 2nd pass */
+
+}
+
+/*
+* F(P, S, c, i) = U1 xor U2 xor ... Uc
+* U1 = PRF(P, S || Int(i))
+* U2 = PRF(P, U1)
+* Uc = PRF(P, Uc-1)
+*/
+
+void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output)
+{
+ unsigned char digest[36], digest1[SHA_DIGEST_LEN];
+ int i, j;
+
+ /* U1 = PRF(P, S || int(i)) */
+ memcpy(digest, ssid, ssidlength);
+ digest[ssidlength] = (unsigned char)((count>>24) & 0xff);
+ digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff);
+ digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff);
+ digest[ssidlength+3] = (unsigned char)(count & 0xff);
+ HMAC_SHA1(digest, ssidlength+4, (unsigned char*) password, (int) strlen(password), digest1); // for WPA update
+
+ /* output = U1 */
+ memcpy(output, digest1, SHA_DIGEST_LEN);
+
+ for (i = 1; i < iterations; i++)
+ {
+ /* Un = PRF(P, Un-1) */
+ HMAC_SHA1(digest1, SHA_DIGEST_LEN, (unsigned char*) password, (int) strlen(password), digest); // for WPA update
+ memcpy(digest1, digest, SHA_DIGEST_LEN);
+
+ /* output = output xor Un */
+ for (j = 0; j < SHA_DIGEST_LEN; j++)
+ {
+ output[j] ^= digest[j];
+ }
+ }
+}
+/*
+* password - ascii string up to 63 characters in length
+* ssid - octet string up to 32 octets
+* ssidlength - length of ssid in octets
+* output must be 40 octets in length and outputs 256 bits of key
+*/
+int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output)
+{
+ if ((strlen(password) > 63) || (ssidlength > 32))
+ return 0;
+
+ F(password, ssid, ssidlength, 4096, 1, output);
+ F(password, ssid, ssidlength, 4096, 2, &output[SHA_DIGEST_LEN]);
+ return 1;
+}
+
+
diff --git a/drivers/staging/rt3070/common/mlme.c b/drivers/staging/rt3070/common/mlme.c
new file mode 100644
index 00000000000..0ffbfa36699
--- /dev/null
+++ b/drivers/staging/rt3070/common/mlme.c
@@ -0,0 +1,9136 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ mlme.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2004-08-25 Modify from RT2500 code base
+ John Chang 2004-09-06 modified for RT2600
+*/
+
+#include "../rt_config.h"
+#include <stdarg.h>
+
+UCHAR CISCO_OUI[] = {0x00, 0x40, 0x96};
+
+UCHAR WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
+UCHAR RSN_OUI[] = {0x00, 0x0f, 0xac};
+UCHAR WAPI_OUI[] = {0x00, 0x14, 0x72};
+UCHAR WME_INFO_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
+UCHAR WME_PARM_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
+UCHAR Ccx2QosInfo[] = {0x00, 0x40, 0x96, 0x04};
+UCHAR RALINK_OUI[] = {0x00, 0x0c, 0x43};
+UCHAR BROADCOM_OUI[] = {0x00, 0x90, 0x4c};
+UCHAR WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
+#ifdef CONFIG_STA_SUPPORT
+#ifdef DOT11_N_SUPPORT
+UCHAR PRE_N_HT_OUI[] = {0x00, 0x90, 0x4c};
+#endif // DOT11_N_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+UCHAR RateSwitchTable[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x11, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x00, 0, 40, 101,
+ 0x01, 0x00, 1, 40, 50,
+ 0x02, 0x00, 2, 35, 45,
+ 0x03, 0x00, 3, 20, 45,
+ 0x04, 0x21, 0, 30, 50,
+ 0x05, 0x21, 1, 20, 50,
+ 0x06, 0x21, 2, 20, 50,
+ 0x07, 0x21, 3, 15, 50,
+ 0x08, 0x21, 4, 15, 30,
+ 0x09, 0x21, 5, 10, 25,
+ 0x0a, 0x21, 6, 8, 25,
+ 0x0b, 0x21, 7, 8, 25,
+ 0x0c, 0x20, 12, 15, 30,
+ 0x0d, 0x20, 13, 8, 20,
+ 0x0e, 0x20, 14, 8, 20,
+ 0x0f, 0x20, 15, 8, 25,
+ 0x10, 0x22, 15, 8, 25,
+ 0x11, 0x00, 0, 0, 0,
+ 0x12, 0x00, 0, 0, 0,
+ 0x13, 0x00, 0, 0, 0,
+ 0x14, 0x00, 0, 0, 0,
+ 0x15, 0x00, 0, 0, 0,
+ 0x16, 0x00, 0, 0, 0,
+ 0x17, 0x00, 0, 0, 0,
+ 0x18, 0x00, 0, 0, 0,
+ 0x19, 0x00, 0, 0, 0,
+ 0x1a, 0x00, 0, 0, 0,
+ 0x1b, 0x00, 0, 0, 0,
+ 0x1c, 0x00, 0, 0, 0,
+ 0x1d, 0x00, 0, 0, 0,
+ 0x1e, 0x00, 0, 0, 0,
+ 0x1f, 0x00, 0, 0, 0,
+};
+
+UCHAR RateSwitchTable11B[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x04, 0x03, 0, 0, 0, // Initial used item after association
+ 0x00, 0x00, 0, 40, 101,
+ 0x01, 0x00, 1, 40, 50,
+ 0x02, 0x00, 2, 35, 45,
+ 0x03, 0x00, 3, 20, 45,
+};
+
+UCHAR RateSwitchTable11BG[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0a, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x00, 0, 40, 101,
+ 0x01, 0x00, 1, 40, 50,
+ 0x02, 0x00, 2, 35, 45,
+ 0x03, 0x00, 3, 20, 45,
+ 0x04, 0x10, 2, 20, 35,
+ 0x05, 0x10, 3, 16, 35,
+ 0x06, 0x10, 4, 10, 25,
+ 0x07, 0x10, 5, 16, 25,
+ 0x08, 0x10, 6, 10, 25,
+ 0x09, 0x10, 7, 10, 13,
+};
+
+UCHAR RateSwitchTable11G[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x08, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x10, 0, 20, 101,
+ 0x01, 0x10, 1, 20, 35,
+ 0x02, 0x10, 2, 20, 35,
+ 0x03, 0x10, 3, 16, 35,
+ 0x04, 0x10, 4, 10, 25,
+ 0x05, 0x10, 5, 16, 25,
+ 0x06, 0x10, 6, 10, 25,
+ 0x07, 0x10, 7, 10, 13,
+};
+
+#ifdef DOT11_N_SUPPORT
+UCHAR RateSwitchTable11N1S[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x09, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30, 101,
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x21, 5, 10, 25,
+ 0x06, 0x21, 6, 8, 14,
+ 0x07, 0x21, 7, 8, 14,
+ 0x08, 0x23, 7, 8, 14,
+};
+
+UCHAR RateSwitchTable11N2S[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0a, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30, 101,
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x20, 12, 15, 30,
+ 0x06, 0x20, 13, 8, 20,
+ 0x07, 0x20, 14, 8, 20,
+ 0x08, 0x20, 15, 8, 25,
+ 0x09, 0x22, 15, 8, 25,
+};
+
+UCHAR RateSwitchTable11N3S[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0a, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30, 101,
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x20, 12, 15, 30,
+ 0x06, 0x20, 13, 8, 20,
+ 0x07, 0x20, 14, 8, 20,
+ 0x08, 0x20, 15, 8, 25,
+ 0x09, 0x22, 15, 8, 25,
+};
+
+UCHAR RateSwitchTable11N2SForABand[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0b, 0x09, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30, 101,
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x21, 5, 15, 30,
+ 0x06, 0x20, 12, 15, 30,
+ 0x07, 0x20, 13, 8, 20,
+ 0x08, 0x20, 14, 8, 20,
+ 0x09, 0x20, 15, 8, 25,
+ 0x0a, 0x22, 15, 8, 25,
+};
+
+UCHAR RateSwitchTable11N3SForABand[] = { // 3*3
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0b, 0x09, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30, 101,
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x21, 5, 15, 30,
+ 0x06, 0x20, 12, 15, 30,
+ 0x07, 0x20, 13, 8, 20,
+ 0x08, 0x20, 14, 8, 20,
+ 0x09, 0x20, 15, 8, 25,
+ 0x0a, 0x22, 15, 8, 25,
+};
+
+UCHAR RateSwitchTable11BGN1S[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0d, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x00, 0, 40, 101,
+ 0x01, 0x00, 1, 40, 50,
+ 0x02, 0x00, 2, 35, 45,
+ 0x03, 0x00, 3, 20, 45,
+ 0x04, 0x21, 0, 30,101, //50
+ 0x05, 0x21, 1, 20, 50,
+ 0x06, 0x21, 2, 20, 50,
+ 0x07, 0x21, 3, 15, 50,
+ 0x08, 0x21, 4, 15, 30,
+ 0x09, 0x21, 5, 10, 25,
+ 0x0a, 0x21, 6, 8, 14,
+ 0x0b, 0x21, 7, 8, 14,
+ 0x0c, 0x23, 7, 8, 14,
+};
+
+UCHAR RateSwitchTable11BGN2S[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0a, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30,101, //50
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x20, 12, 15, 30,
+ 0x06, 0x20, 13, 8, 20,
+ 0x07, 0x20, 14, 8, 20,
+ 0x08, 0x20, 15, 8, 25,
+ 0x09, 0x22, 15, 8, 25,
+};
+
+UCHAR RateSwitchTable11BGN3S[] = { // 3*3
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0a, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30,101, //50
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 20, 50,
+ 0x04, 0x21, 4, 15, 50,
+#if 1
+ 0x05, 0x20, 20, 15, 30,
+ 0x06, 0x20, 21, 8, 20,
+ 0x07, 0x20, 22, 8, 20,
+ 0x08, 0x20, 23, 8, 25,
+ 0x09, 0x22, 23, 8, 25,
+#else // for RT2860 2*3 test
+ 0x05, 0x20, 12, 15, 30,
+ 0x06, 0x20, 13, 8, 20,
+ 0x07, 0x20, 14, 8, 20,
+ 0x08, 0x20, 15, 8, 25,
+ 0x09, 0x22, 15, 8, 25,
+#endif
+};
+
+UCHAR RateSwitchTable11BGN2SForABand[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0b, 0x09, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30,101, //50
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x21, 5, 15, 30,
+ 0x06, 0x20, 12, 15, 30,
+ 0x07, 0x20, 13, 8, 20,
+ 0x08, 0x20, 14, 8, 20,
+ 0x09, 0x20, 15, 8, 25,
+ 0x0a, 0x22, 15, 8, 25,
+};
+
+UCHAR RateSwitchTable11BGN3SForABand[] = { // 3*3
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0c, 0x09, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30,101, //50
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x21, 5, 15, 30,
+ 0x06, 0x21, 12, 15, 30,
+ 0x07, 0x20, 20, 15, 30,
+ 0x08, 0x20, 21, 8, 20,
+ 0x09, 0x20, 22, 8, 20,
+ 0x0a, 0x20, 23, 8, 25,
+ 0x0b, 0x22, 23, 8, 25,
+};
+#endif // DOT11_N_SUPPORT //
+
+PUCHAR ReasonString[] = {
+ /* 0 */ "Reserved",
+ /* 1 */ "Unspecified Reason",
+ /* 2 */ "Previous Auth no longer valid",
+ /* 3 */ "STA is leaving / has left",
+ /* 4 */ "DIS-ASSOC due to inactivity",
+ /* 5 */ "AP unable to hanle all associations",
+ /* 6 */ "class 2 error",
+ /* 7 */ "class 3 error",
+ /* 8 */ "STA is leaving / has left",
+ /* 9 */ "require auth before assoc/re-assoc",
+ /* 10 */ "Reserved",
+ /* 11 */ "Reserved",
+ /* 12 */ "Reserved",
+ /* 13 */ "invalid IE",
+ /* 14 */ "MIC error",
+ /* 15 */ "4-way handshake timeout",
+ /* 16 */ "2-way (group key) handshake timeout",
+ /* 17 */ "4-way handshake IE diff among AssosReq/Rsp/Beacon",
+ /* 18 */
+};
+
+extern UCHAR OfdmRateToRxwiMCS[];
+// since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
+// otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate
+ULONG BasicRateMask[12] = {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */,
+ 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
+ 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
+
+UCHAR MULTICAST_ADDR[MAC_ADDR_LEN] = {0x1, 0x00, 0x00, 0x00, 0x00, 0x00};
+UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+// e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
+// this value, then it's quaranteed capable of operating in 36 mbps TX rate in
+// clean environment.
+// TxRate: 1 2 5.5 11 6 9 12 18 24 36 48 54 72 100
+CHAR RssiSafeLevelForTxRate[] ={ -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
+
+UCHAR RateIdToMbps[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};
+USHORT RateIdTo500Kbps[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};
+
+UCHAR SsidIe = IE_SSID;
+UCHAR SupRateIe = IE_SUPP_RATES;
+UCHAR ExtRateIe = IE_EXT_SUPP_RATES;
+#ifdef DOT11_N_SUPPORT
+UCHAR HtCapIe = IE_HT_CAP;
+UCHAR AddHtInfoIe = IE_ADD_HT;
+UCHAR NewExtChanIe = IE_SECONDARY_CH_OFFSET;
+#ifdef DOT11N_DRAFT3
+UCHAR ExtHtCapIe = IE_EXT_CAPABILITY;
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+UCHAR ErpIe = IE_ERP;
+UCHAR DsIe = IE_DS_PARM;
+UCHAR TimIe = IE_TIM;
+UCHAR WpaIe = IE_WPA;
+UCHAR Wpa2Ie = IE_WPA2;
+UCHAR IbssIe = IE_IBSS_PARM;
+UCHAR Ccx2Ie = IE_CCX_V2;
+UCHAR WapiIe = IE_WAPI;
+
+extern UCHAR WPA_OUI[];
+
+UCHAR SES_OUI[] = {0x00, 0x90, 0x4c};
+
+UCHAR ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+// Reset the RFIC setting to new series
+RTMP_RF_REGS RF2850RegTable[] = {
+// ch R1 R2 R3(TX0~4=0) R4
+ {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
+ {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
+ {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
+ {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
+ {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
+ {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
+ {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
+ {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
+ {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
+ {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
+ {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
+ {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
+ {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
+ {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
+
+ // 802.11 UNI / HyperLan 2
+ {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
+ {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
+ {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
+ {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
+ {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
+ {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
+ {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
+ {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
+ {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
+ {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
+ {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
+ {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
+
+ // 802.11 HyperLan 2
+ {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
+
+ // 2008.04.30 modified
+ // The system team has AN to improve the EVM value
+ // for channel 102 to 108 for the RT2850/RT2750 dual band solution.
+ {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
+ {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
+ {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
+
+ {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
+ {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
+ {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
+ {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
+ {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
+ {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
+ {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
+ {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
+ {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
+ {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
+ {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
+ {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
+
+ // 802.11 UNII
+ {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
+ {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
+ {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
+ {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
+ {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
+ {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
+ {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
+
+ // Japan
+ {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
+ {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
+ {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
+ {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
+ {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
+ {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
+ {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
+
+ // still lack of MMAC(Japan) ch 34,38,42,46
+};
+UCHAR NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
+
+FREQUENCY_ITEM FreqItems3020[] =
+{
+ /**************************************************/
+ // ISM : 2.4 to 2.483 GHz //
+ /**************************************************/
+ // 11g
+ /**************************************************/
+ //-CH---N-------R---K-----------
+ {1, 241, 2, 2},
+ {2, 241, 2, 7},
+ {3, 242, 2, 2},
+ {4, 242, 2, 7},
+ {5, 243, 2, 2},
+ {6, 243, 2, 7},
+ {7, 244, 2, 2},
+ {8, 244, 2, 7},
+ {9, 245, 2, 2},
+ {10, 245, 2, 7},
+ {11, 246, 2, 2},
+ {12, 246, 2, 7},
+ {13, 247, 2, 2},
+ {14, 248, 2, 4},
+};
+//2008/07/10:KH Modified to share this variable
+UCHAR NUM_OF_3020_CHNL=(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
+
+/*
+ ==========================================================================
+ Description:
+ initialize the MLME task and its data structure (queue, spinlock,
+ timer, state machines).
+
+ IRQL = PASSIVE_LEVEL
+
+ Return:
+ always return NDIS_STATUS_SUCCESS
+
+ ==========================================================================
+*/
+NDIS_STATUS MlmeInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n"));
+
+ do
+ {
+ Status = MlmeQueueInit(&pAd->Mlme.Queue);
+ if(Status != NDIS_STATUS_SUCCESS)
+ break;
+
+ pAd->Mlme.bRunning = FALSE;
+ NdisAllocateSpinLock(&pAd->Mlme.TaskLock);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ BssTableInit(&pAd->ScanTab);
+
+ // init STA state machines
+ AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, pAd->Mlme.AssocFunc);
+ AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc);
+ AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc);
+ SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc);
+ WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc);
+ AironetStateMachineInit(pAd, &pAd->Mlme.AironetMachine, pAd->Mlme.AironetFunc);
+
+#ifdef QOS_DLS_SUPPORT
+ DlsStateMachineInit(pAd, &pAd->Mlme.DlsMachine, pAd->Mlme.DlsFunc);
+#endif // QOS_DLS_SUPPORT //
+
+
+ // Since we are using switch/case to implement it, the init is different from the above
+ // state machine init
+ MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+ ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc);
+
+ // Init mlme periodic timer
+ RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
+
+ // Set mlme periodic timer
+ RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
+
+ // software-based RX Antenna diversity
+ RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ } while (FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
+
+ return Status;
+}
+
+/*
+ ==========================================================================
+ Description:
+ main loop of the MLME
+ Pre:
+ Mlme has to be initialized, and there are something inside the queue
+ Note:
+ This function is invoked from MPSetInformation and MPReceive;
+ This task guarantee only one MlmeHandler will run.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeHandler(
+ IN PRTMP_ADAPTER pAd)
+{
+ MLME_QUEUE_ELEM *Elem = NULL;
+
+ // Only accept MLME and Frame from peer side, no other (control/data) frame should
+ // get into this state machine
+
+ NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
+ if(pAd->Mlme.bRunning)
+ {
+ NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+ return;
+ }
+ else
+ {
+ pAd->Mlme.bRunning = TRUE;
+ }
+ NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+
+ while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd->Mlme.Queue.Num));
+ break;
+ }
+
+#ifdef RALINK_ATE
+ if(ATE_ON(pAd))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now in MlmeHandler\n"));
+ break;
+ }
+#endif // RALINK_ATE //
+
+ //From message type, determine which state machine I should drive
+ if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
+ {
+#ifdef RT2870
+ if (Elem->MsgType == MT2_RESET_CONF)
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n"));
+ MlmeRestartStateMachine(pAd);
+ Elem->Occupied = FALSE;
+ Elem->MsgLen = 0;
+ continue;
+ }
+#endif // RT2870 //
+
+ // if dequeue success
+ switch (Elem->Machine)
+ {
+ // STA state machines
+#ifdef CONFIG_STA_SUPPORT
+ case ASSOC_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem);
+ break;
+ case AUTH_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, Elem);
+ break;
+ case AUTH_RSP_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, Elem);
+ break;
+ case SYNC_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, Elem);
+ break;
+ case MLME_CNTL_STATE_MACHINE:
+ MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem);
+ break;
+ case WPA_PSK_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
+ break;
+#ifdef LEAP_SUPPORT
+ case LEAP_STATE_MACHINE:
+ LeapMachinePerformAction(pAd, &pAd->Mlme.LeapMachine, Elem);
+ break;
+#endif
+ case AIRONET_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.AironetMachine, Elem);
+ break;
+
+#ifdef QOS_DLS_SUPPORT
+ case DLS_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.DlsMachine, Elem);
+ break;
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+ case ACTION_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem);
+ break;
+
+
+
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem->Machine));
+ break;
+ } // end of switch
+
+ // free MLME element
+ Elem->Occupied = FALSE;
+ Elem->MsgLen = 0;
+
+ }
+ else {
+ DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
+ }
+ }
+
+ NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
+ pAd->Mlme.bRunning = FALSE;
+ NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Destructor of MLME (Destroy queue, state machine, spin lock and timer)
+ Parameters:
+ Adapter - NIC Adapter pointer
+ Post:
+ The MLME task will no longer work properly
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeHalt(
+ IN PRTMP_ADAPTER pAd)
+{
+ BOOLEAN Cancelled;
+#ifdef RT3070
+ UINT32 TxPinCfg = 0x00050F0F;
+#endif // RT3070 //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
+
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ // disable BEACON generation and other BEACON related hardware timers
+ AsicDisableSync(pAd);
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+#ifdef QOS_DLS_SUPPORT
+ UCHAR i;
+#endif // QOS_DLS_SUPPORT //
+ // Cancel pending timers
+ RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
+
+#ifdef QOS_DLS_SUPPORT
+ for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
+ }
+#endif // QOS_DLS_SUPPORT //
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer, &Cancelled);
+
+
+
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ // Set LED
+ RTMPSetLED(pAd, LED_HALT);
+ RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
+#ifdef RT2870
+ {
+ LED_CFG_STRUC LedCfg;
+ RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
+ LedCfg.field.LedPolar = 0;
+ LedCfg.field.RLedMode = 0;
+ LedCfg.field.GLedMode = 0;
+ LedCfg.field.YLedMode = 0;
+ RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
+ }
+#endif // RT2870 //
+#ifdef RT3070
+ //
+ // Turn off LNA_PE
+ //
+ if (IS_RT3070(pAd) || IS_RT3071(pAd))
+ {
+ TxPinCfg &= 0xFFFFF0F0;
+ RTUSBWriteMACRegister(pAd, TX_PIN_CFG, TxPinCfg);
+ }
+#endif // RT3070 //
+ }
+
+ RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled
+
+ MlmeQueueDestroy(&pAd->Mlme.Queue);
+ NdisFreeSpinLock(&pAd->Mlme.TaskLock);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n"));
+}
+
+VOID MlmeResetRalinkCounters(
+ IN PRTMP_ADAPTER pAd)
+{
+ pAd->RalinkCounters.LastOneSecRxOkDataCnt = pAd->RalinkCounters.OneSecRxOkDataCnt;
+ // clear all OneSecxxx counters.
+ pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
+ pAd->RalinkCounters.OneSecFalseCCACnt = 0;
+ pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
+ pAd->RalinkCounters.OneSecRxOkCnt = 0;
+ pAd->RalinkCounters.OneSecTxFailCount = 0;
+ pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
+ pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
+ pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
+
+ // TODO: for debug only. to be removed
+ pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
+ pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
+ pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
+ pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0;
+ pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0;
+ pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0;
+ pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0;
+ pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0;
+ pAd->RalinkCounters.OneSecTxDoneCount = 0;
+ pAd->RalinkCounters.OneSecRxCount = 0;
+ pAd->RalinkCounters.OneSecTxAggregationCount = 0;
+ pAd->RalinkCounters.OneSecRxAggregationCount = 0;
+
+ return;
+}
+
+unsigned long rx_AMSDU;
+unsigned long rx_Total;
+
+/*
+ ==========================================================================
+ Description:
+ This routine is executed periodically to -
+ 1. Decide if it's a right time to turn on PwrMgmt bit of all
+ outgoiing frames
+ 2. Calculate ChannelQuality based on statistics of the last
+ period, so that TX rate won't toggling very frequently between a
+ successful TX and a failed TX.
+ 3. If the calculated ChannelQuality indicated current connection not
+ healthy, then a ROAMing attempt is tried here.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+#define ADHOC_BEACON_LOST_TIME (8*OS_HZ) // 8 sec
+VOID MlmePeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ ULONG TxTotalCnt;
+ PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_RADIO_MEASUREMENT |
+ fRTMP_ADAPTER_RESET_IN_PROGRESS))))
+ return;
+
+ RT28XX_MLME_PRE_SANITY_CHECK(pAd);
+
+#ifdef RALINK_ATE
+ /* Do not show RSSI until "Normal 1 second Mlme PeriodicExec". */
+ if (ATE_ON(pAd))
+ {
+ if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE != (MLME_TASK_EXEC_MULTIPLE - 1))
+ {
+ pAd->Mlme.PeriodicRound ++;
+ return;
+ }
+ }
+#endif // RALINK_ATE //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Do nothing if monitor mode is on
+ if (MONITOR_ON(pAd))
+ return;
+
+ if (pAd->Mlme.PeriodicRound & 0x1)
+ {
+ // This is the fix for wifi 11n extension channel overlapping test case. for 2860D
+ if (((pAd->MACVersion & 0xffff) == 0x0101) &&
+ (STA_TGN_WIFI_ON(pAd)) &&
+ (pAd->CommonCfg.IOTestParm.bToggle == FALSE))
+
+ {
+ RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
+ pAd->CommonCfg.IOTestParm.bToggle = TRUE;
+ }
+ else if ((STA_TGN_WIFI_ON(pAd)) &&
+ ((pAd->MACVersion & 0xffff) == 0x0101))
+ {
+ RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
+ pAd->CommonCfg.IOTestParm.bToggle = FALSE;
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ pAd->bUpdateBcnCntDone = FALSE;
+
+// RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
+ pAd->Mlme.PeriodicRound ++;
+
+#ifdef RT2870
+ // execute every 100ms, update the Tx FIFO Cnt for update Tx Rate.
+ NICUpdateFifoStaCounters(pAd);
+#endif // RT2870 //
+ // execute every 500ms
+ if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
+ {
+#ifdef CONFIG_STA_SUPPORT
+ // perform dynamic tx rate switching based on past TX history
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+ )
+ && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
+ MlmeDynamicTxRateSwitching(pAd);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ // Normal 1 second Mlme PeriodicExec.
+ if (pAd->Mlme.PeriodicRound %MLME_TASK_EXEC_MULTIPLE == 0)
+ {
+ pAd->Mlme.OneSecPeriodicRound ++;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ /* request from Baron : move this routine from later to here */
+ /* for showing Rx error count in ATE RXFRAME */
+ NICUpdateRawCounters(pAd);
+ if (pAd->ate.bRxFer == 1)
+ {
+ pAd->ate.RxTotalCnt += pAd->ate.RxCntPerSec;
+ ate_print(KERN_EMERG "MlmePeriodicExec: Rx packet cnt = %d/%d\n", pAd->ate.RxCntPerSec, pAd->ate.RxTotalCnt);
+ pAd->ate.RxCntPerSec = 0;
+
+ if (pAd->ate.RxAntennaSel == 0)
+ ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi0=%d, AvgRssi1=%d, AvgRssi2=%d\n\n",
+ pAd->ate.AvgRssi0, pAd->ate.AvgRssi1, pAd->ate.AvgRssi2);
+ else
+ ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi=%d\n\n", pAd->ate.AvgRssi0);
+ }
+ MlmeResetRalinkCounters(pAd);
+ return;
+ }
+#endif // RALINK_ATE //
+
+
+ if (rx_Total)
+ {
+
+ // reset counters
+ rx_AMSDU = 0;
+ rx_Total = 0;
+ }
+
+ //ORIBATimerTimeout(pAd);
+
+ // Media status changed, report to NDIS
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE))
+ {
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ RTMP_IndicateMediaState(pAd);
+
+ }
+ else
+ {
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ }
+ }
+
+ NdisGetSystemUpTime(&pAd->Mlme.Now32);
+
+ // add the most up-to-date h/w raw counters into software variable, so that
+ // the dynamic tuning mechanism below are based on most up-to-date information
+ NICUpdateRawCounters(pAd);
+
+#ifdef RT2870
+ RT2870_WatchDog(pAd);
+#endif // RT2870 //
+
+#ifdef DOT11_N_SUPPORT
+ // Need statistics after read counter. So put after NICUpdateRawCounters
+ ORIBATimerTimeout(pAd);
+#endif // DOT11_N_SUPPORT //
+
+ // The time period for checking antenna is according to traffic
+ {
+ if (pAd->Mlme.bEnableAutoAntennaCheck)
+ {
+ TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
+
+ // dynamic adjust antenna evaluation period according to the traffic
+ if (TxTotalCnt > 50)
+ {
+ if (pAd->Mlme.OneSecPeriodicRound % 10 == 0)
+ {
+ AsicEvaluateRxAnt(pAd);
+ }
+ }
+ else
+ {
+ if (pAd->Mlme.OneSecPeriodicRound % 3 == 0)
+ {
+ AsicEvaluateRxAnt(pAd);
+ }
+ }
+ }
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ STAMlmePeriodicExec(pAd);
+#endif // CONFIG_STA_SUPPORT //
+
+ MlmeResetRalinkCounters(pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ {
+ // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
+ // and sending CTS-to-self over and over.
+ // Software Patch Solution:
+ // 1. Polling debug state register 0x10F4 every one second.
+ // 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
+ // 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
+
+ UINT32 MacReg = 0;
+
+ RTMP_IO_READ32(pAd, 0x10F4, &MacReg);
+ if (((MacReg & 0x20000000) && (MacReg & 0x80)) || ((MacReg & 0x20000000) && (MacReg & 0x20)))
+ {
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
+ RTMPusecDelay(1);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
+
+ DBGPRINT(RT_DEBUG_WARN,("Warning, MAC specific condition occurs \n"));
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ RT28XX_MLME_HANDLER(pAd);
+ }
+
+
+ pAd->bUpdateBcnCntDone = FALSE;
+}
+
+#ifdef CONFIG_STA_SUPPORT
+VOID STAMlmePeriodicExec(
+ PRTMP_ADAPTER pAd)
+{
+ ULONG TxTotalCnt;
+ int i;
+
+//
+// We return here in ATE mode, because the statistics
+// that ATE needs are not collected via this routine.
+//
+#ifdef RALINK_ATE
+ // It is supposed that we will never reach here in ATE mode.
+ ASSERT(!(ATE_ON(pAd)));
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ // WPA MIC error should block association attempt for 60 seconds
+ if (pAd->StaCfg.bBlockAssoc && (pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ) < pAd->Mlme.Now32))
+ pAd->StaCfg.bBlockAssoc = FALSE;
+ }
+
+ if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
+ {
+ if (pAd->IndicateMediaState == NdisMediaStateConnected)
+ {
+ RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+ pAd->PreMediaState = pAd->IndicateMediaState;
+ }
+
+
+
+
+ AsicStaBbpTuning(pAd);
+
+ TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
+
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ // update channel quality for Roaming and UI LinkQuality display
+ MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32);
+ }
+
+ // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
+ // Radio is currently in noisy environment
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ AsicAdjustTxPower(pAd);
+
+ if (INFRA_ON(pAd))
+ {
+#ifdef QOS_DLS_SUPPORT
+ // Check DLS time out, then tear down those session
+ RTMPCheckDLSTimeOut(pAd);
+#endif // QOS_DLS_SUPPORT //
+
+ // Is PSM bit consistent with user power management policy?
+ // This is the only place that will set PSM bit ON.
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
+
+ pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
+
+ if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
+ ((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600)))
+ {
+ RTMPSetAGCInitValue(pAd, BW_20);
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
+ }
+
+ //if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
+ // (pAd->RalinkCounters.OneSecTxRetryOkCount == 0))
+ {
+ if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
+ {
+ // When APSD is enabled, the period changes as 20 sec
+ if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+ }
+ else
+ {
+ // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
+ if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
+ {
+ if (pAd->CommonCfg.bWmmCapable)
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+ else
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
+ }
+ }
+ }
+
+ if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
+ pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
+ pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime;
+
+ // Lost AP, send disconnect & link down event
+ LinkDown(pAd, FALSE);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP)
+ {
+ union iwreq_data wrqu;
+ //send disassociate event to wpa_supplicant
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+ // RTMPPatchMacBbpBug(pAd);
+ MlmeAutoReconnectLastSSID(pAd);
+ }
+ else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
+ {
+ pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
+ MlmeAutoReconnectLastSSID(pAd);
+ }
+
+ // Add auto seamless roaming
+ if (pAd->StaCfg.bFastRoaming)
+ {
+ SHORT dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), (CHAR)dBmToRoam));
+
+ if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam)
+ {
+ MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32);
+ }
+ }
+ }
+ else if (ADHOC_ON(pAd))
+ {
+ //radar detect
+ if ((pAd->CommonCfg.Channel > 14)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+ {
+ RadarDetectPeriodic(pAd);
+ }
+
+ // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
+ // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
+ // join later.
+ if ((pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) &&
+ OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ MLME_START_REQ_STRUCT StartReq;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
+ LinkDown(pAd, FALSE);
+
+ StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
+ }
+
+ for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
+
+ if (pEntry->ValidAsCLI == FALSE)
+ continue;
+
+ if (pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32)
+ MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+ }
+ }
+ else // no INFRA nor ADHOC connection
+ {
+
+ if (pAd->StaCfg.bScanReqIsFromWebUI &&
+ ((pAd->StaCfg.LastScanTime + 30 * OS_HZ) > pAd->Mlme.Now32))
+ goto SKIP_AUTO_SCAN_CONN;
+ else
+ pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
+
+ if ((pAd->StaCfg.bAutoReconnect == TRUE)
+ && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
+ && (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
+ {
+ if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
+ {
+ MLME_SCAN_REQ_STRUCT ScanReq;
+
+ if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
+ ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+ // Reset Missed scan number
+ pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
+ }
+ else if (pAd->StaCfg.BssType == BSS_ADHOC) // Quit the forever scan when in a very clean room
+ MlmeAutoReconnectLastSSID(pAd);
+ }
+ else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+ {
+ if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0)
+ {
+ MlmeAutoScan(pAd);
+ pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
+ }
+ else
+ {
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+ {
+ if ((pAd->Mlme.OneSecPeriodicRound % 5) == 1)
+ MlmeAutoReconnectLastSSID(pAd);
+ }
+ else
+#endif // CARRIER_DETECTION_SUPPORT //
+ MlmeAutoReconnectLastSSID(pAd);
+ }
+ }
+ }
+ }
+
+SKIP_AUTO_SCAN_CONN:
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE))
+ {
+ pAd->MacTab.fAnyBASession = TRUE;
+ AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE, FALSE);
+ }
+ else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE))
+ {
+ pAd->MacTab.fAnyBASession = FALSE;
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
+ }
+#endif // DOT11_N_SUPPORT //
+
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040))
+ TriEventCounterMaintenance(pAd);
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+ return;
+}
+
+// Link down report
+VOID LinkDownExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeAutoScan(
+ IN PRTMP_ADAPTER pAd)
+{
+ // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+ if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
+ MlmeEnqueue(pAd,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_BSSID_LIST_SCAN,
+ 0,
+ NULL);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeAutoReconnectLastSSID(
+ IN PRTMP_ADAPTER pAd)
+{
+
+
+ // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+ if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
+ (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
+ {
+ NDIS_802_11_SSID OidSsid;
+ OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
+ NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen));
+ MlmeEnqueue(pAd,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_SSID,
+ sizeof(NDIS_802_11_SSID),
+ &OidSsid);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+ ==========================================================================
+ Validate SSID for connection try and rescan purpose
+ Valid SSID will have visible chars only.
+ The valid length is from 0 to 32.
+ IRQL = DISPATCH_LEVEL
+ ==========================================================================
+ */
+BOOLEAN MlmeValidateSSID(
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen)
+{
+ int index;
+
+ if (SsidLen > MAX_LEN_OF_SSID)
+ return (FALSE);
+
+ // Check each character value
+ for (index = 0; index < SsidLen; index++)
+ {
+ if (pSsid[index] < 0x20)
+ return (FALSE);
+ }
+
+ // All checked
+ return (TRUE);
+}
+
+VOID MlmeSelectTxRateTable(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR *ppTable,
+ IN PUCHAR pTableSize,
+ IN PUCHAR pInitTxRateIdx)
+{
+ do
+ {
+ // decide the rate table for tuning
+ if (pAd->CommonCfg.TxRateTableSize > 0)
+ {
+ *ppTable = RateSwitchTable;
+ *pTableSize = RateSwitchTable[0];
+ *pInitTxRateIdx = RateSwitchTable[1];
+
+ break;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
+ {
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
+ (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+ ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
+ {// 11N 1S Adhoc
+ *ppTable = RateSwitchTable11N1S;
+ *pTableSize = RateSwitchTable11N1S[0];
+ *pInitTxRateIdx = RateSwitchTable11N1S[1];
+
+ }
+ else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
+ (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+ (pEntry->HTCapability.MCSSet[1] == 0xff) &&
+ (pAd->Antenna.field.TxPath == 2))
+ {// 11N 2S Adhoc
+ if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ *ppTable = RateSwitchTable11N2S;
+ *pTableSize = RateSwitchTable11N2S[0];
+ *pInitTxRateIdx = RateSwitchTable11N2S[1];
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11N2SForABand;
+ *pTableSize = RateSwitchTable11N2SForABand[0];
+ *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+ }
+
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ if ((pEntry->RateLen == 4)
+#ifdef DOT11_N_SUPPORT
+ && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ *ppTable = RateSwitchTable11B;
+ *pTableSize = RateSwitchTable11B[0];
+ *pInitTxRateIdx = RateSwitchTable11B[1];
+
+ }
+ else if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ *ppTable = RateSwitchTable11BG;
+ *pTableSize = RateSwitchTable11BG[0];
+ *pInitTxRateIdx = RateSwitchTable11BG[1];
+
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11G;
+ *pTableSize = RateSwitchTable11G[0];
+ *pInitTxRateIdx = RateSwitchTable11G[1];
+
+ }
+ break;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+ //if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
+ // ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
+ if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+ ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
+ {// 11BGN 1S AP
+ *ppTable = RateSwitchTable11BGN1S;
+ *pTableSize = RateSwitchTable11BGN1S[0];
+ *pInitTxRateIdx = RateSwitchTable11BGN1S[1];
+
+ break;
+ }
+
+ //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
+ // (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
+ if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+ (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
+ {// 11BGN 2S AP
+ if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ *ppTable = RateSwitchTable11BGN2S;
+ *pTableSize = RateSwitchTable11BGN2S[0];
+ *pInitTxRateIdx = RateSwitchTable11BGN2S[1];
+
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11BGN2SForABand;
+ *pTableSize = RateSwitchTable11BGN2SForABand[0];
+ *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1];
+
+ }
+ break;
+ }
+
+ //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
+ if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
+ {// 11N 1S AP
+ *ppTable = RateSwitchTable11N1S;
+ *pTableSize = RateSwitchTable11N1S[0];
+ *pInitTxRateIdx = RateSwitchTable11N1S[1];
+
+ break;
+ }
+
+ //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
+ if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
+ {// 11N 2S AP
+ if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ *ppTable = RateSwitchTable11N2S;
+ *pTableSize = RateSwitchTable11N2S[0];
+ *pInitTxRateIdx = RateSwitchTable11N2S[1];
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11N2SForABand;
+ *pTableSize = RateSwitchTable11N2SForABand[0];
+ *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+ }
+
+ break;
+ }
+#endif // DOT11_N_SUPPORT //
+ //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+ if ((pEntry->RateLen == 4)
+#ifdef DOT11_N_SUPPORT
+//Iverson mark for Adhoc b mode,sta will use rate 54 Mbps when connect with sta b/g/n mode
+// && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif // DOT11_N_SUPPORT //
+ )
+ {// B only AP
+ *ppTable = RateSwitchTable11B;
+ *pTableSize = RateSwitchTable11B[0];
+ *pInitTxRateIdx = RateSwitchTable11B[1];
+
+ break;
+ }
+
+ //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+ if ((pEntry->RateLen > 8)
+#ifdef DOT11_N_SUPPORT
+ && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif // DOT11_N_SUPPORT //
+ )
+ {// B/G mixed AP
+ *ppTable = RateSwitchTable11BG;
+ *pTableSize = RateSwitchTable11BG[0];
+ *pInitTxRateIdx = RateSwitchTable11BG[1];
+
+ break;
+ }
+
+ //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+ if ((pEntry->RateLen == 8)
+#ifdef DOT11_N_SUPPORT
+ && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif // DOT11_N_SUPPORT //
+ )
+ {// G only AP
+ *ppTable = RateSwitchTable11G;
+ *pTableSize = RateSwitchTable11G[0];
+ *pInitTxRateIdx = RateSwitchTable11G[1];
+
+ break;
+ }
+#ifdef DOT11_N_SUPPORT
+#endif // DOT11_N_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+#ifdef DOT11_N_SUPPORT
+ //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+ if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))
+#endif // DOT11_N_SUPPORT //
+ { // Legacy mode
+ if (pAd->CommonCfg.MaxTxRate <= RATE_11)
+ {
+ *ppTable = RateSwitchTable11B;
+ *pTableSize = RateSwitchTable11B[0];
+ *pInitTxRateIdx = RateSwitchTable11B[1];
+ }
+ else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))
+ {
+ *ppTable = RateSwitchTable11G;
+ *pTableSize = RateSwitchTable11G[0];
+ *pInitTxRateIdx = RateSwitchTable11G[1];
+
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11BG;
+ *pTableSize = RateSwitchTable11BG[0];
+ *pInitTxRateIdx = RateSwitchTable11BG[1];
+ }
+ break;
+ }
+#ifdef DOT11_N_SUPPORT
+ if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ if (pAd->CommonCfg.TxStream == 1)
+ {
+ *ppTable = RateSwitchTable11N1S;
+ *pTableSize = RateSwitchTable11N1S[0];
+ *pInitTxRateIdx = RateSwitchTable11N1S[1];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11N2S;
+ *pTableSize = RateSwitchTable11N2S[0];
+ *pInitTxRateIdx = RateSwitchTable11N2S[1];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
+ }
+ }
+ else
+ {
+ if (pAd->CommonCfg.TxStream == 1)
+ {
+ *ppTable = RateSwitchTable11N1S;
+ *pTableSize = RateSwitchTable11N1S[0];
+ *pInitTxRateIdx = RateSwitchTable11N1S[1];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11N2SForABand;
+ *pTableSize = RateSwitchTable11N2SForABand[0];
+ *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
+ pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
+ }
+#endif // CONFIG_STA_SUPPORT //
+ } while(FALSE);
+}
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ This routine checks if there're other APs out there capable for
+ roaming. Caller should call this routine only when Link up in INFRA mode
+ and channel quality is below CQI_GOOD_THRESHOLD.
+
+ IRQL = DISPATCH_LEVEL
+
+ Output:
+ ==========================================================================
+ */
+VOID MlmeCheckForRoaming(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now32)
+{
+ USHORT i;
+ BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
+ BSS_ENTRY *pBss;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
+ // put all roaming candidates into RoamTab, and sort in RSSI order
+ BssTableInit(pRoamTab);
+ for (i = 0; i < pAd->ScanTab.BssNr; i++)
+ {
+ pBss = &pAd->ScanTab.BssEntry[i];
+
+ if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32)
+ continue; // AP disappear
+ if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
+ continue; // RSSI too weak. forget it.
+ if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
+ continue; // skip current AP
+ if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
+ continue; // only AP with stronger RSSI is eligible for roaming
+
+ // AP passing all above rules is put into roaming candidate table
+ NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
+ pRoamTab->BssNr += 1;
+ }
+
+ if (pRoamTab->BssNr > 0)
+ {
+ // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+ if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+ {
+ pAd->RalinkCounters.PoorCQIRoamingCount ++;
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine checks if there're other APs out there capable for
+ roaming. Caller should call this routine only when link up in INFRA mode
+ and channel quality is below CQI_GOOD_THRESHOLD.
+
+ IRQL = DISPATCH_LEVEL
+
+ Output:
+ ==========================================================================
+ */
+VOID MlmeCheckForFastRoaming(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now)
+{
+ USHORT i;
+ BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
+ BSS_ENTRY *pBss;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
+ // put all roaming candidates into RoamTab, and sort in RSSI order
+ BssTableInit(pRoamTab);
+ for (i = 0; i < pAd->ScanTab.BssNr; i++)
+ {
+ pBss = &pAd->ScanTab.BssEntry[i];
+
+ if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
+ continue; // RSSI too weak. forget it.
+ if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
+ continue; // skip current AP
+ if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
+ continue; // skip different SSID
+ if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
+ continue; // skip AP without better RSSI
+
+ DBGPRINT(RT_DEBUG_TRACE, ("LastRssi0 = %d, pBss->Rssi = %d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), pBss->Rssi));
+ // AP passing all above rules is put into roaming candidate table
+ NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
+ pRoamTab->BssNr += 1;
+ }
+
+ if (pRoamTab->BssNr > 0)
+ {
+ // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+ if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+ {
+ pAd->RalinkCounters.PoorCQIRoamingCount ++;
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+ }
+ // Maybe site survey required
+ else
+ {
+ if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now)
+ {
+ // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
+ pAd->StaCfg.ScanCnt = 2;
+ pAd->StaCfg.LastScanTime = Now;
+ MlmeAutoScan(pAd);
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine calculates TxPER, RxPER of the past N-sec period. And
+ according to the calculation result, ChannelQuality is calculated here
+ to decide if current AP is still doing the job.
+
+ If ChannelQuality is not good, a ROAMing attempt may be tried later.
+ Output:
+ StaCfg.ChannelQuality - 0..100
+
+ IRQL = DISPATCH_LEVEL
+
+ NOTE: This routine decide channle quality based on RX CRC error ratio.
+ Caller should make sure a function call to NICUpdateRawCounters(pAd)
+ is performed right before this routine, so that this routine can decide
+ channel quality based on the most up-to-date information
+ ==========================================================================
+ */
+VOID MlmeCalculateChannelQuality(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now32)
+{
+ ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
+ ULONG RxCnt, RxPER;
+ UCHAR NorRssi;
+ CHAR MaxRssi;
+ ULONG BeaconLostTime = BEACON_LOST_TIME;
+
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+ // longer beacon lost time when carrier detection enabled
+ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+ {
+ BeaconLostTime = BEACON_LOST_TIME + BEACON_LOST_TIME/2;
+ }
+#endif // CARRIER_DETECTION_SUPPORT //
+
+ MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
+
+ //
+ // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
+ //
+ TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount;
+ TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount;
+ if (TxCnt < 5)
+ {
+ TxPER = 0;
+ TxPRR = 0;
+ }
+ else
+ {
+ TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt;
+ TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt;
+ }
+
+ //
+ // calculate RX PER - don't take RxPER into consideration if too few sample
+ //
+ RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt;
+ if (RxCnt < 5)
+ RxPER = 0;
+ else
+ RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt;
+
+ //
+ // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
+ //
+ if (INFRA_ON(pAd) &&
+ (pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic
+ (pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
+ pAd->Mlme.ChannelQuality = 0;
+ }
+ else
+ {
+ // Normalize Rssi
+ if (MaxRssi > -40)
+ NorRssi = 100;
+ else if (MaxRssi < -90)
+ NorRssi = 0;
+ else
+ NorRssi = (MaxRssi + 90) * 2;
+
+ // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
+ pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi +
+ TX_WEIGHTING * (100 - TxPRR) +
+ RX_WEIGHTING* (100 - RxPER)) / 100;
+ if (pAd->Mlme.ChannelQuality >= 100)
+ pAd->Mlme.ChannelQuality = 100;
+ }
+
+}
+
+VOID MlmeSetTxRate(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PRTMP_TX_RATE_SWITCH pTxRate)
+{
+ UCHAR MaxMode = MODE_OFDM;
+
+#ifdef DOT11_N_SUPPORT
+ MaxMode = MODE_HTGREENFIELD;
+
+ if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
+ pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
+ else
+#endif // DOT11_N_SUPPORT //
+ pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
+
+ if (pTxRate->CurrMCS < MCS_AUTO)
+ pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
+
+ if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
+ pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
+
+ if (ADHOC_ON(pAd))
+ {
+ // If peer adhoc is b-only mode, we can't send 11g rate.
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+ pEntry->HTPhyMode.field.STBC = STBC_NONE;
+
+ //
+ // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
+ //
+ pEntry->HTPhyMode.field.MODE = pTxRate->Mode;
+ pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+
+ // Patch speed error in status page
+ pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
+ }
+ else
+ {
+ if (pTxRate->Mode <= MaxMode)
+ pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
+
+#ifdef DOT11_N_SUPPORT
+ if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
+ else
+#endif // DOT11_N_SUPPORT //
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+
+#ifdef DOT11_N_SUPPORT
+ // Reexam each bandwidth's SGI support.
+ if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)
+ {
+ if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+ if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+ }
+
+ // Turn RTS/CTS rate to 6Mbps.
+ if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
+ {
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ if (pAd->MacTab.fAnyBASession)
+ {
+ AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
+ else
+ {
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
+ }
+ else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
+ {
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ if (pAd->MacTab.fAnyBASession)
+ {
+ AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
+ else
+ {
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
+ }
+ else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
+ {
+ AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+
+ }
+ else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
+ {
+ AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
+#endif // DOT11_N_SUPPORT //
+
+ pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC;
+ pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
+ pAd->WIFItestbed.bGreenField)
+ pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
+#endif // DOT11_N_SUPPORT //
+ }
+
+ pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine calculates the acumulated TxPER of eaxh TxRate. And
+ according to the calculation result, change CommonCfg.TxRate which
+ is the stable TX Rate we expect the Radio situation could sustained.
+
+ CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
+ Output:
+ CommonCfg.TxRate -
+
+ IRQL = DISPATCH_LEVEL
+
+ NOTE:
+ call this routine every second
+ ==========================================================================
+ */
+VOID MlmeDynamicTxRateSwitching(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
+ ULONG i, AccuTxTotalCnt = 0, TxTotalCnt;
+ ULONG TxErrorRatio = 0;
+ BOOLEAN bTxRateChanged, bUpgradeQuality = FALSE;
+ PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+ UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
+ CHAR Rssi, RssiOffset = 0;
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+ ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
+ MAC_TABLE_ENTRY *pEntry;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ return;
+ }
+#endif // RALINK_ATE //
+
+ //
+ // walk through MAC table, see if need to change AP's TX rate toward each entry
+ //
+ for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ pEntry = &pAd->MacTab.Content[i];
+
+ // check if this entry need to switch rate automatically
+ if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
+ continue;
+
+ if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
+ {
+ Rssi = RTMPMaxRssi(pAd,
+ pAd->StaCfg.RssiSample.AvgRssi0,
+ pAd->StaCfg.RssiSample.AvgRssi1,
+ pAd->StaCfg.RssiSample.AvgRssi2);
+
+ // Update statistic counter
+ RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+ RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
+ pAd->bUpdateBcnCntDone = TRUE;
+ TxRetransmit = StaTx1.field.TxRetransmit;
+ TxSuccess = StaTx1.field.TxSuccess;
+ TxFailCount = TxStaCnt0.field.TxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
+ pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
+ pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
+ pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
+ pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
+ pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
+
+ // if no traffic in the past 1-sec period, don't change TX rate,
+ // but clear all bad history. because the bad history may affect the next
+ // Chariot throughput test
+ AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+ }
+ else
+ {
+ if (INFRA_ON(pAd) && (i == 1))
+ Rssi = RTMPMaxRssi(pAd,
+ pAd->StaCfg.RssiSample.AvgRssi0,
+ pAd->StaCfg.RssiSample.AvgRssi1,
+ pAd->StaCfg.RssiSample.AvgRssi2);
+ else
+ Rssi = RTMPMaxRssi(pAd,
+ pEntry->RssiSample.AvgRssi0,
+ pEntry->RssiSample.AvgRssi1,
+ pEntry->RssiSample.AvgRssi2);
+
+ TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
+ pEntry->OneSecTxRetryOkCount +
+ pEntry->OneSecTxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
+ }
+
+ CurrRateIdx = pEntry->CurrTxRateIndex;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
+
+ if (CurrRateIdx >= TableSize)
+ {
+ CurrRateIdx = TableSize - 1;
+ }
+
+ // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
+ // So need to sync here.
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
+ if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
+ //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+ )
+ {
+
+ // Need to sync Real Tx rate and our record.
+ // Then return for next DRS.
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5];
+ pEntry->CurrTxRateIndex = InitTxRateIdx;
+ MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
+
+ // reset all OneSecTx counters
+ RESET_ONE_SEC_TX_CNT(pEntry);
+ continue;
+ }
+
+ // decide the next upgrade rate and downgrade rate, if any
+ if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
+ {
+ UpRateIdx = CurrRateIdx + 1;
+ DownRateIdx = CurrRateIdx -1;
+ }
+ else if (CurrRateIdx == 0)
+ {
+ UpRateIdx = CurrRateIdx + 1;
+ DownRateIdx = CurrRateIdx;
+ }
+ else if (CurrRateIdx == (TableSize - 1))
+ {
+ UpRateIdx = CurrRateIdx;
+ DownRateIdx = CurrRateIdx - 1;
+ }
+
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
+
+#ifdef DOT11_N_SUPPORT
+ if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
+ {
+ TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
+ TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ TrainUp = pCurrTxRate->TrainUp;
+ TrainDown = pCurrTxRate->TrainDown;
+ }
+
+ //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
+
+ //
+ // Keep the last time TxRateChangeAction status.
+ //
+ pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
+
+
+
+ //
+ // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
+ // (criteria copied from RT2500 for Netopia case)
+ //
+ if (TxTotalCnt <= 15)
+ {
+ CHAR idx = 0;
+ UCHAR TxRateIdx;
+ //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
+ UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0;
+ UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
+ UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
+
+ // check the existence and index of each needed MCS
+ while (idx < pTable[0])
+ {
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
+
+ if (pCurrTxRate->CurrMCS == MCS_0)
+ {
+ MCS0 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_1)
+ {
+ MCS1 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_2)
+ {
+ MCS2 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_3)
+ {
+ MCS3 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_4)
+ {
+ MCS4 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_5)
+ {
+ MCS5 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_6)
+ {
+ MCS6 = idx;
+ }
+ //else if (pCurrTxRate->CurrMCS == MCS_7)
+ else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) // prevent the highest MCS using short GI when 1T and low throughput
+ {
+ MCS7 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_12)
+ {
+ MCS12 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_13)
+ {
+ MCS13 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_14)
+ {
+ MCS14 = idx;
+ }
+ else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800))
+ {
+ MCS15 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
+ {
+ MCS20 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_21)
+ {
+ MCS21 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_22)
+ {
+ MCS22 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_23)
+ {
+ MCS23 = idx;
+ }
+ idx ++;
+ }
+
+ if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ if (pAd->NicConfig2.field.ExternalLNAForG)
+ {
+ RssiOffset = 2;
+ }
+ else
+ {
+ RssiOffset = 5;
+ }
+ }
+ else
+ {
+ if (pAd->NicConfig2.field.ExternalLNAForA)
+ {
+ RssiOffset = 5;
+ }
+ else
+ {
+ RssiOffset = 8;
+ }
+ }
+#ifdef DOT11_N_SUPPORT
+ /*if (MCS15)*/
+ if ((pTable == RateSwitchTable11BGN3S) ||
+ (pTable == RateSwitchTable11N3S) ||
+ (pTable == RateSwitchTable))
+ {// N mode with 3 stream // 3*3
+ if (MCS23 && (Rssi >= -70))
+ TxRateIdx = MCS15;
+ else if (MCS22 && (Rssi >= -72))
+ TxRateIdx = MCS14;
+ else if (MCS21 && (Rssi >= -76))
+ TxRateIdx = MCS13;
+ else if (MCS20 && (Rssi >= -78))
+ TxRateIdx = MCS12;
+ else if (MCS4 && (Rssi >= -82))
+ TxRateIdx = MCS4;
+ else if (MCS3 && (Rssi >= -84))
+ TxRateIdx = MCS3;
+ else if (MCS2 && (Rssi >= -86))
+ TxRateIdx = MCS2;
+ else if (MCS1 && (Rssi >= -88))
+ TxRateIdx = MCS1;
+ else
+ TxRateIdx = MCS0;
+ }
+// else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable))
+ else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
+ {// N mode with 2 stream
+ if (MCS15 && (Rssi >= (-70+RssiOffset)))
+ TxRateIdx = MCS15;
+ else if (MCS14 && (Rssi >= (-72+RssiOffset)))
+ TxRateIdx = MCS14;
+ else if (MCS13 && (Rssi >= (-76+RssiOffset)))
+ TxRateIdx = MCS13;
+ else if (MCS12 && (Rssi >= (-78+RssiOffset)))
+ TxRateIdx = MCS12;
+ else if (MCS4 && (Rssi >= (-82+RssiOffset)))
+ TxRateIdx = MCS4;
+ else if (MCS3 && (Rssi >= (-84+RssiOffset)))
+ TxRateIdx = MCS3;
+ else if (MCS2 && (Rssi >= (-86+RssiOffset)))
+ TxRateIdx = MCS2;
+ else if (MCS1 && (Rssi >= (-88+RssiOffset)))
+ TxRateIdx = MCS1;
+ else
+ TxRateIdx = MCS0;
+ }
+ else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S))
+ {// N mode with 1 stream
+ if (MCS7 && (Rssi > (-72+RssiOffset)))
+ TxRateIdx = MCS7;
+ else if (MCS6 && (Rssi > (-74+RssiOffset)))
+ TxRateIdx = MCS6;
+ else if (MCS5 && (Rssi > (-77+RssiOffset)))
+ TxRateIdx = MCS5;
+ else if (MCS4 && (Rssi > (-79+RssiOffset)))
+ TxRateIdx = MCS4;
+ else if (MCS3 && (Rssi > (-81+RssiOffset)))
+ TxRateIdx = MCS3;
+ else if (MCS2 && (Rssi > (-83+RssiOffset)))
+ TxRateIdx = MCS2;
+ else if (MCS1 && (Rssi > (-86+RssiOffset)))
+ TxRateIdx = MCS1;
+ else
+ TxRateIdx = MCS0;
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {// Legacy mode
+ if (MCS7 && (Rssi > -70))
+ TxRateIdx = MCS7;
+ else if (MCS6 && (Rssi > -74))
+ TxRateIdx = MCS6;
+ else if (MCS5 && (Rssi > -78))
+ TxRateIdx = MCS5;
+ else if (MCS4 && (Rssi > -82))
+ TxRateIdx = MCS4;
+ else if (MCS4 == 0) // for B-only mode
+ TxRateIdx = MCS3;
+ else if (MCS3 && (Rssi > -85))
+ TxRateIdx = MCS3;
+ else if (MCS2 && (Rssi > -87))
+ TxRateIdx = MCS2;
+ else if (MCS1 && (Rssi > -90))
+ TxRateIdx = MCS1;
+ else
+ TxRateIdx = MCS0;
+ }
+
+ // if (TxRateIdx != pAd->CommonCfg.TxRateIndex)
+ {
+ pEntry->CurrTxRateIndex = TxRateIdx;
+ pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
+ MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+ }
+
+ NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+ NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+ pEntry->fLastSecAccordingRSSI = TRUE;
+ // reset all OneSecTx counters
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+ continue;
+ }
+
+ if (pEntry->fLastSecAccordingRSSI == TRUE)
+ {
+ pEntry->fLastSecAccordingRSSI = FALSE;
+ pEntry->LastSecTxRateChangeAction = 0;
+ // reset all OneSecTx counters
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+ continue;
+ }
+
+ do
+ {
+ BOOLEAN bTrainUpDown = FALSE;
+
+ pEntry->CurrTxRateStableTime ++;
+
+ // downgrade TX quality if PER >= Rate-Down threshold
+ if (TxErrorRatio >= TrainDown)
+ {
+ bTrainUpDown = TRUE;
+ pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+ }
+ // upgrade TX quality if PER <= Rate-Up threshold
+ else if (TxErrorRatio <= TrainUp)
+ {
+ bTrainUpDown = TRUE;
+ bUpgradeQuality = TRUE;
+ if (pEntry->TxQuality[CurrRateIdx])
+ pEntry->TxQuality[CurrRateIdx] --; // quality very good in CurrRate
+
+ if (pEntry->TxRateUpPenalty)
+ pEntry->TxRateUpPenalty --;
+ else if (pEntry->TxQuality[UpRateIdx])
+ pEntry->TxQuality[UpRateIdx] --; // may improve next UP rate's quality
+ }
+
+ pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
+
+ if (bTrainUpDown)
+ {
+ // perform DRS - consider TxRate Down first, then rate up.
+ if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND))
+ {
+ pEntry->CurrTxRateIndex = DownRateIdx;
+ }
+ else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0))
+ {
+ pEntry->CurrTxRateIndex = UpRateIdx;
+ }
+ }
+ } while (FALSE);
+
+ // if rate-up happen, clear all bad history of all TX rates
+ if (pEntry->CurrTxRateIndex > CurrRateIdx)
+ {
+ pEntry->CurrTxRateStableTime = 0;
+ pEntry->TxRateUpPenalty = 0;
+ pEntry->LastSecTxRateChangeAction = 1; // rate UP
+ NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+ NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+
+ //
+ // For TxRate fast train up
+ //
+ if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
+ {
+ RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
+
+ pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
+ }
+ bTxRateChanged = TRUE;
+ }
+ // if rate-down happen, only clear DownRate's bad history
+ else if (pEntry->CurrTxRateIndex < CurrRateIdx)
+ {
+ pEntry->CurrTxRateStableTime = 0;
+ pEntry->TxRateUpPenalty = 0; // no penalty
+ pEntry->LastSecTxRateChangeAction = 2; // rate DOWN
+ pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
+ pEntry->PER[pEntry->CurrTxRateIndex] = 0;
+
+ //
+ // For TxRate fast train down
+ //
+ if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
+ {
+ RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
+
+ pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
+ }
+ bTxRateChanged = TRUE;
+ }
+ else
+ {
+ pEntry->LastSecTxRateChangeAction = 0; // rate no change
+ bTxRateChanged = FALSE;
+ }
+
+ pEntry->LastTxOkCount = TxSuccess;
+
+ // reset all OneSecTx counters
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+ pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
+ if (bTxRateChanged && pNextTxRate)
+ {
+ MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+ }
+ }
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Station side, Auto TxRate faster train up timer call back function.
+
+ Arguments:
+ SystemSpecific1 - Not used.
+ FunctionContext - Pointer to our Adapter context.
+ SystemSpecific2 - Not used.
+ SystemSpecific3 - Not used.
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID StaQuickResponeForRateUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
+ UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
+ ULONG TxTotalCnt;
+ ULONG TxErrorRatio = 0;
+ BOOLEAN bTxRateChanged; //, bUpgradeQuality = FALSE;
+ PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+ UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+ CHAR Rssi, ratio;
+ ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
+ MAC_TABLE_ENTRY *pEntry;
+ ULONG i;
+
+ pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
+
+ //
+ // walk through MAC table, see if need to change AP's TX rate toward each entry
+ //
+ for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ pEntry = &pAd->MacTab.Content[i];
+
+ // check if this entry need to switch rate automatically
+ if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
+ continue;
+
+ if (INFRA_ON(pAd) && (i == 1))
+ Rssi = RTMPMaxRssi(pAd,
+ pAd->StaCfg.RssiSample.AvgRssi0,
+ pAd->StaCfg.RssiSample.AvgRssi1,
+ pAd->StaCfg.RssiSample.AvgRssi2);
+ else
+ Rssi = RTMPMaxRssi(pAd,
+ pEntry->RssiSample.AvgRssi0,
+ pEntry->RssiSample.AvgRssi1,
+ pEntry->RssiSample.AvgRssi2);
+
+ CurrRateIdx = pAd->CommonCfg.TxRateIndex;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
+
+ // decide the next upgrade rate and downgrade rate, if any
+ if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
+ {
+ UpRateIdx = CurrRateIdx + 1;
+ DownRateIdx = CurrRateIdx -1;
+ }
+ else if (CurrRateIdx == 0)
+ {
+ UpRateIdx = CurrRateIdx + 1;
+ DownRateIdx = CurrRateIdx;
+ }
+ else if (CurrRateIdx == (TableSize - 1))
+ {
+ UpRateIdx = CurrRateIdx;
+ DownRateIdx = CurrRateIdx - 1;
+ }
+
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
+
+#ifdef DOT11_N_SUPPORT
+ if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
+ {
+ TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
+ TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ TrainUp = pCurrTxRate->TrainUp;
+ TrainDown = pCurrTxRate->TrainDown;
+ }
+
+ if (pAd->MacTab.Size == 1)
+ {
+ // Update statistic counter
+ RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+ RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
+
+ TxRetransmit = StaTx1.field.TxRetransmit;
+ TxSuccess = StaTx1.field.TxSuccess;
+ TxFailCount = TxStaCnt0.field.TxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
+ pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
+ pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
+ pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
+ pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
+ pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+ }
+ else
+ {
+ TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
+ pEntry->OneSecTxRetryOkCount +
+ pEntry->OneSecTxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
+ }
+
+
+ //
+ // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
+ // (criteria copied from RT2500 for Netopia case)
+ //
+ if (TxTotalCnt <= 12)
+ {
+ NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+ NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+
+ if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
+ {
+ pAd->CommonCfg.TxRateIndex = DownRateIdx;
+ pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+ }
+ else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
+ {
+ pAd->CommonCfg.TxRateIndex = UpRateIdx;
+ }
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
+ return;
+ }
+
+ do
+ {
+ ULONG OneSecTxNoRetryOKRationCount;
+
+ if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
+ ratio = 5;
+ else
+ ratio = 4;
+
+ // downgrade TX quality if PER >= Rate-Down threshold
+ if (TxErrorRatio >= TrainDown)
+ {
+ pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+ }
+
+ pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
+
+ OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
+
+ // perform DRS - consider TxRate Down first, then rate up.
+ if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
+ {
+ if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
+ {
+ pAd->CommonCfg.TxRateIndex = DownRateIdx;
+ pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+
+ }
+
+ }
+ else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
+ {
+ if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown))
+ {
+
+ }
+ else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
+ {
+ pAd->CommonCfg.TxRateIndex = UpRateIdx;
+ }
+ }
+ }while (FALSE);
+
+ // if rate-up happen, clear all bad history of all TX rates
+ if (pAd->CommonCfg.TxRateIndex > CurrRateIdx)
+ {
+ pAd->DrsCounters.TxRateUpPenalty = 0;
+ NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+ NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+ bTxRateChanged = TRUE;
+ }
+ // if rate-down happen, only clear DownRate's bad history
+ else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex));
+
+ pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty
+ pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
+ pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
+ bTxRateChanged = TRUE;
+ }
+ else
+ {
+ bTxRateChanged = FALSE;
+ }
+
+ pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5];
+ if (bTxRateChanged && pNextTxRate)
+ {
+ MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine is executed periodically inside MlmePeriodicExec() after
+ association with an AP.
+ It checks if StaCfg.Psm is consistent with user policy (recorded in
+ StaCfg.WindowsPowerMode). If not, enforce user policy. However,
+ there're some conditions to consider:
+ 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
+ the time when Mibss==TRUE
+ 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
+ if outgoing traffic available in TxRing or MgmtRing.
+ Output:
+ 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeCheckPsmChange(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now32)
+{
+ ULONG PowerMode;
+
+ // condition -
+ // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
+ // 2. user wants either MAX_PSP or FAST_PSP
+ // 3. but current psm is not in PWR_SAVE
+ // 4. CNTL state machine is not doing SCANning
+ // 5. no TX SUCCESS event for the past 1-sec period
+#ifdef NDIS51_MINIPORT
+ if (pAd->StaCfg.WindowsPowerProfile == NdisPowerProfileBattery)
+ PowerMode = pAd->StaCfg.WindowsBatteryPowerMode;
+ else
+#endif
+ PowerMode = pAd->StaCfg.WindowsPowerMode;
+
+ if (INFRA_ON(pAd) &&
+ (PowerMode != Ndis802_11PowerModeCAM) &&
+ (pAd->StaCfg.Psm == PWR_ACTIVE) &&
+// (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) /*&&
+ (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
+ (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/)
+ {
+ // add by johnli, use Rx OK data count per second to calculate throughput
+ // If Ttraffic is too high ( > 400 Rx per second), don't go to sleep mode. If tx rate is low, use low criteria
+ // Mode=CCK/MCS=3 => 11 Mbps, Mode=OFDM/MCS=3 => 18 Mbps
+ if (((pAd->StaCfg.HTPhyMode.field.MCS <= 3) &&
+/* Iverson mark
+ (pAd->StaCfg.HTPhyMode.field.MODE <= MODE_OFDM) &&
+*/
+ (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)100)) ||
+ ((pAd->StaCfg.HTPhyMode.field.MCS > 3) &&
+/* Iverson mark
+ (pAd->StaCfg.HTPhyMode.field.MODE > MODE_OFDM) &&
+*/
+ (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)400)))
+ {
+ // Get this time
+ NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
+ pAd->RalinkCounters.RxCountSinceLastNULL = 0;
+ MlmeSetPsmBit(pAd, PWR_SAVE);
+ if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
+ {
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
+ }
+ else
+ {
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+ }
+ }
+ }
+}
+
+// IRQL = PASSIVE_LEVEL
+// IRQL = DISPATCH_LEVEL
+VOID MlmeSetPsmBit(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT psm)
+{
+ AUTO_RSP_CFG_STRUC csr4;
+
+ pAd->StaCfg.Psm = psm;
+ RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
+ csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
+ RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeSetTxPreamble(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT TxPreamble)
+{
+ AUTO_RSP_CFG_STRUC csr4;
+
+ //
+ // Always use Long preamble before verifiation short preamble functionality works well.
+ // Todo: remove the following line if short preamble functionality works
+ //
+ //TxPreamble = Rt802_11PreambleLong;
+
+ RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
+ if (TxPreamble == Rt802_11PreambleLong)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+ csr4.field.AutoResponderPreamble = 0;
+ }
+ else
+ {
+ // NOTE: 1Mbps should always use long preamble
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+ csr4.field.AutoResponderPreamble = 1;
+ }
+
+ RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Update basic rate bitmap
+ ==========================================================================
+ */
+
+VOID UpdateBasicRateBitmap(
+ IN PRTMP_ADAPTER pAdapter)
+{
+ INT i, j;
+ /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
+ UCHAR rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
+ UCHAR *sup_p = pAdapter->CommonCfg.SupRate;
+ UCHAR *ext_p = pAdapter->CommonCfg.ExtRate;
+ ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap;
+
+
+ /* if A mode, always use fix BasicRateBitMap */
+ //if (pAdapter->CommonCfg.Channel == PHY_11A)
+ if (pAdapter->CommonCfg.Channel > 14)
+ pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
+ /* End of if */
+
+ if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
+ {
+ /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
+ return;
+ } /* End of if */
+
+ for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ sup_p[i] &= 0x7f;
+ ext_p[i] &= 0x7f;
+ } /* End of for */
+
+ for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ if (bitmap & (1 << i))
+ {
+ for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
+ {
+ if (sup_p[j] == rate[i])
+ sup_p[j] |= 0x80;
+ /* End of if */
+ } /* End of for */
+
+ for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
+ {
+ if (ext_p[j] == rate[i])
+ ext_p[j] |= 0x80;
+ /* End of if */
+ } /* End of for */
+ } /* End of if */
+ } /* End of for */
+} /* End of UpdateBasicRateBitmap */
+
+// IRQL = PASSIVE_LEVEL
+// IRQL = DISPATCH_LEVEL
+// bLinkUp is to identify the inital link speed.
+// TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
+VOID MlmeUpdateTxRates(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bLinkUp,
+ IN UCHAR apidx)
+{
+ int i, num;
+ UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
+ UCHAR MinSupport = RATE_54;
+ ULONG BasicRateBitmap = 0;
+ UCHAR CurrBasicRate = RATE_1;
+ UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
+ PHTTRANSMIT_SETTING pHtPhy = NULL;
+ PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
+ PHTTRANSMIT_SETTING pMinHtPhy = NULL;
+ BOOLEAN *auto_rate_cur_p;
+ UCHAR HtMcs = MCS_AUTO;
+
+ // find max desired rate
+ UpdateBasicRateBitmap(pAd);
+
+ num = 0;
+ auto_rate_cur_p = NULL;
+ for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ switch (pAd->CommonCfg.DesireRate[i] & 0x7f)
+ {
+ case 2: Rate = RATE_1; num++; break;
+ case 4: Rate = RATE_2; num++; break;
+ case 11: Rate = RATE_5_5; num++; break;
+ case 22: Rate = RATE_11; num++; break;
+ case 12: Rate = RATE_6; num++; break;
+ case 18: Rate = RATE_9; num++; break;
+ case 24: Rate = RATE_12; num++; break;
+ case 36: Rate = RATE_18; num++; break;
+ case 48: Rate = RATE_24; num++; break;
+ case 72: Rate = RATE_36; num++; break;
+ case 96: Rate = RATE_48; num++; break;
+ case 108: Rate = RATE_54; num++; break;
+ //default: Rate = RATE_1; break;
+ }
+ if (MaxDesire < Rate) MaxDesire = Rate;
+ }
+
+//===========================================================================
+//===========================================================================
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pHtPhy = &pAd->StaCfg.HTPhyMode;
+ pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
+ pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
+
+ auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
+ HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
+
+ if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
+ (pAd->CommonCfg.PhyMode == PHY_11B) &&
+ (MaxDesire > RATE_11))
+ {
+ MaxDesire = RATE_11;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ pAd->CommonCfg.MaxDesiredRate = MaxDesire;
+ pMinHtPhy->word = 0;
+ pMaxHtPhy->word = 0;
+ pHtPhy->word = 0;
+
+ // Auto rate switching is enabled only if more than one DESIRED RATES are
+ // specified; otherwise disabled
+ if (num <= 1)
+ {
+ //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+ //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
+ *auto_rate_cur_p = FALSE;
+ }
+ else
+ {
+ //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+ //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
+ *auto_rate_cur_p = TRUE;
+ }
+
+#if 1
+ if (HtMcs != MCS_AUTO)
+ {
+ //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+ //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
+ *auto_rate_cur_p = FALSE;
+ }
+ else
+ {
+ //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+ //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
+ *auto_rate_cur_p = TRUE;
+ }
+#endif
+
+#ifdef CONFIG_STA_SUPPORT
+ if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
+ {
+ pSupRate = &pAd->StaActive.SupRate[0];
+ pExtRate = &pAd->StaActive.ExtRate[0];
+ SupRateLen = pAd->StaActive.SupRateLen;
+ ExtRateLen = pAd->StaActive.ExtRateLen;
+ }
+ else
+#endif // CONFIG_STA_SUPPORT //
+ {
+ pSupRate = &pAd->CommonCfg.SupRate[0];
+ pExtRate = &pAd->CommonCfg.ExtRate[0];
+ SupRateLen = pAd->CommonCfg.SupRateLen;
+ ExtRateLen = pAd->CommonCfg.ExtRateLen;
+ }
+
+ // find max supported rate
+ for (i=0; i<SupRateLen; i++)
+ {
+ switch (pSupRate[i] & 0x7f)
+ {
+ case 2: Rate = RATE_1; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
+ case 4: Rate = RATE_2; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
+ case 11: Rate = RATE_5_5; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
+ case 22: Rate = RATE_11; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
+ case 12: Rate = RATE_6; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
+ case 18: Rate = RATE_9; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
+ case 24: Rate = RATE_12; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
+ case 36: Rate = RATE_18; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
+ case 48: Rate = RATE_24; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
+ case 72: Rate = RATE_36; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
+ case 96: Rate = RATE_48; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
+ case 108: Rate = RATE_54; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
+ default: Rate = RATE_1; break;
+ }
+ if (MaxSupport < Rate) MaxSupport = Rate;
+
+ if (MinSupport > Rate) MinSupport = Rate;
+ }
+
+ for (i=0; i<ExtRateLen; i++)
+ {
+ switch (pExtRate[i] & 0x7f)
+ {
+ case 2: Rate = RATE_1; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
+ case 4: Rate = RATE_2; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
+ case 11: Rate = RATE_5_5; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
+ case 22: Rate = RATE_11; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
+ case 12: Rate = RATE_6; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
+ case 18: Rate = RATE_9; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
+ case 24: Rate = RATE_12; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
+ case 36: Rate = RATE_18; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
+ case 48: Rate = RATE_24; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
+ case 72: Rate = RATE_36; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
+ case 96: Rate = RATE_48; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
+ case 108: Rate = RATE_54; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
+ default: Rate = RATE_1; break;
+ }
+ if (MaxSupport < Rate) MaxSupport = Rate;
+
+ if (MinSupport > Rate) MinSupport = Rate;
+ }
+
+ RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
+
+ // calculate the exptected ACK rate for each TX rate. This info is used to caculate
+ // the DURATION field of outgoing uniicast DATA/MGMT frame
+ for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ if (BasicRateBitmap & (0x01 << i))
+ CurrBasicRate = (UCHAR)i;
+ pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
+ // max tx rate = min {max desire rate, max supported rate}
+ if (MaxSupport < MaxDesire)
+ pAd->CommonCfg.MaxTxRate = MaxSupport;
+ else
+ pAd->CommonCfg.MaxTxRate = MaxDesire;
+
+ pAd->CommonCfg.MinTxRate = MinSupport;
+ // 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success
+ // ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending
+ // on average RSSI
+ // 1. RSSI >= -70db, start at 54 Mbps (short distance)
+ // 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance)
+ // 3. -75 > RSSI, start at 11 Mbps (long distance)
+ //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)/* &&
+ // OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)*/)
+ if (*auto_rate_cur_p)
+ {
+ short dbm = 0;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
+#endif // CONFIG_STA_SUPPORT //
+ if (bLinkUp == TRUE)
+ pAd->CommonCfg.TxRate = RATE_24;
+ else
+ pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
+
+ if (dbm < -75)
+ pAd->CommonCfg.TxRate = RATE_11;
+ else if (dbm < -70)
+ pAd->CommonCfg.TxRate = RATE_24;
+
+ // should never exceed MaxTxRate (consider 11B-only mode)
+ if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
+ pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
+
+ pAd->CommonCfg.TxRateIndex = 0;
+ }
+ else
+ {
+ pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
+ pHtPhy->field.MCS = (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;
+ pHtPhy->field.MODE = (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
+
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC = pHtPhy->field.STBC;
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = pHtPhy->field.ShortGI;
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS = pHtPhy->field.MCS;
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE = pHtPhy->field.MODE;
+ }
+
+ if (pAd->CommonCfg.TxRate <= RATE_11)
+ {
+ pMaxHtPhy->field.MODE = MODE_CCK;
+ pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
+ pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
+ }
+ else
+ {
+ pMaxHtPhy->field.MODE = MODE_OFDM;
+ pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
+ if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54))
+ {pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];}
+ else
+ {pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;}
+ }
+
+ pHtPhy->word = (pMaxHtPhy->word);
+ if (bLinkUp && (pAd->OpMode == OPMODE_STA))
+ {
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
+ pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word;
+ pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word;
+ }
+ else
+ {
+ switch (pAd->CommonCfg.PhyMode)
+ {
+ case PHY_11BG_MIXED:
+ case PHY_11B:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11BGN_MIXED:
+#endif // DOT11_N_SUPPORT //
+ pAd->CommonCfg.MlmeRate = RATE_1;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
+
+//#ifdef WIFI_TEST
+ pAd->CommonCfg.RtsRate = RATE_11;
+//#else
+// pAd->CommonCfg.RtsRate = RATE_1;
+//#endif
+ break;
+ case PHY_11G:
+ case PHY_11A:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11AGN_MIXED:
+ case PHY_11GN_MIXED:
+ case PHY_11N_2_4G:
+ case PHY_11AN_MIXED:
+ case PHY_11N_5G:
+#endif // DOT11_N_SUPPORT //
+ pAd->CommonCfg.MlmeRate = RATE_6;
+ pAd->CommonCfg.RtsRate = RATE_6;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ break;
+ case PHY_11ABG_MIXED:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11ABGN_MIXED:
+#endif // DOT11_N_SUPPORT //
+ if (pAd->CommonCfg.Channel <= 14)
+ {
+ pAd->CommonCfg.MlmeRate = RATE_1;
+ pAd->CommonCfg.RtsRate = RATE_1;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
+ }
+ else
+ {
+ pAd->CommonCfg.MlmeRate = RATE_6;
+ pAd->CommonCfg.RtsRate = RATE_6;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ }
+ break;
+ default: // error
+ pAd->CommonCfg.MlmeRate = RATE_6;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ pAd->CommonCfg.RtsRate = RATE_1;
+ break;
+ }
+ //
+ // Keep Basic Mlme Rate.
+ //
+ pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word;
+ if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
+ pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24];
+ else
+ pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1;
+ pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
+ RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate],
+ /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p));
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
+ RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
+ pAd->CommonCfg.MlmeTransmit.word, pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word ));
+}
+
+#ifdef DOT11_N_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ This function update HT Rate setting.
+ Input Wcid value is valid for 2 case :
+ 1. it's used for Station in infra mode that copy AP rate to Mactable.
+ 2. OR Station in adhoc mode to copy peer's HT rate to Mactable.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeUpdateHtTxRates(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx)
+{
+ UCHAR StbcMcs; //j, StbcMcs, bitmask;
+ CHAR i; // 3*3
+ RT_HT_CAPABILITY *pRtHtCap = NULL;
+ RT_HT_PHY_INFO *pActiveHtPhy = NULL;
+ ULONG BasicMCS;
+ UCHAR j, bitmask;
+ PRT_HT_PHY_INFO pDesireHtPhy = NULL;
+ PHTTRANSMIT_SETTING pHtPhy = NULL;
+ PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
+ PHTTRANSMIT_SETTING pMinHtPhy = NULL;
+ BOOLEAN *auto_rate_cur_p;
+
+ DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
+
+ auto_rate_cur_p = NULL;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
+ pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
+ pHtPhy = &pAd->StaCfg.HTPhyMode;
+ pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
+ pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
+
+ auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
+ {
+ if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
+ return;
+
+ pRtHtCap = &pAd->StaActive.SupportedHtPhy;
+ pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
+ StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
+ BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16);
+ if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
+ pMaxHtPhy->field.STBC = STBC_USE;
+ else
+ pMaxHtPhy->field.STBC = STBC_NONE;
+ }
+ else
+#endif // CONFIG_STA_SUPPORT //
+ {
+ if (pDesireHtPhy->bHtEnable == FALSE)
+ return;
+
+ pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
+ StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
+ BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16);
+ if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
+ pMaxHtPhy->field.STBC = STBC_USE;
+ else
+ pMaxHtPhy->field.STBC = STBC_NONE;
+ }
+
+ // Decide MAX ht rate.
+ if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+ pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
+ else
+ pMaxHtPhy->field.MODE = MODE_HTMIX;
+
+ if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth))
+ pMaxHtPhy->field.BW = BW_40;
+ else
+ pMaxHtPhy->field.BW = BW_20;
+
+ if (pMaxHtPhy->field.BW == BW_20)
+ pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20);
+ else
+ pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
+
+ for (i=23; i>=0; i--) // 3*3
+ {
+ j = i/8;
+ bitmask = (1<<(i-(j*8)));
+
+ if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
+ {
+ pMaxHtPhy->field.MCS = i;
+ break;
+ }
+
+ if (i==0)
+ break;
+ }
+
+ // Copy MIN ht rate. rt2860???
+ pMinHtPhy->field.BW = BW_20;
+ pMinHtPhy->field.MCS = 0;
+ pMinHtPhy->field.STBC = 0;
+ pMinHtPhy->field.ShortGI = 0;
+ //If STA assigns fixed rate. update to fixed here.
+#ifdef CONFIG_STA_SUPPORT
+ if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
+ {
+ if (pDesireHtPhy->MCSSet[4] != 0)
+ {
+ pMaxHtPhy->field.MCS = 32;
+ pMinHtPhy->field.MCS = 32;
+ DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
+ }
+
+ for (i=23; (CHAR)i >= 0; i--) // 3*3
+ {
+ j = i/8;
+ bitmask = (1<<(i-(j*8)));
+ if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
+ {
+ pMaxHtPhy->field.MCS = i;
+ pMinHtPhy->field.MCS = i;
+ break;
+ }
+ if (i==0)
+ break;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+ // Decide ht rate
+ pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
+ pHtPhy->field.BW = pMaxHtPhy->field.BW;
+ pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
+ pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
+ pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
+
+ // use default now. rt2860
+ if (pDesireHtPhy->MCSSet[0] != 0xff)
+ *auto_rate_cur_p = FALSE;
+ else
+ *auto_rate_cur_p = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize ));
+ DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS,
+ pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE));
+ DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
+}
+#endif // DOT11_N_SUPPORT //
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeRadioOff(
+ IN PRTMP_ADAPTER pAd)
+{
+ RT28XX_MLME_RADIO_OFF(pAd);
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeRadioOn(
+ IN PRTMP_ADAPTER pAd)
+{
+ RT28XX_MLME_RADIO_ON(pAd);
+}
+
+// ===========================================================================================
+// bss_table.c
+// ===========================================================================================
+
+
+/*! \brief initialize BSS table
+ * \param p_tab pointer to the table
+ * \return none
+ * \pre
+ * \post
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ */
+VOID BssTableInit(
+ IN BSS_TABLE *Tab)
+{
+ int i;
+
+ Tab->BssNr = 0;
+ Tab->BssOverlapNr = 0;
+ for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
+ {
+ NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
+ Tab->BssEntry[i].Rssi = -127; // initial the rssi as a minimum value
+ }
+}
+
+#ifdef DOT11_N_SUPPORT
+VOID BATableInit(
+ IN PRTMP_ADAPTER pAd,
+ IN BA_TABLE *Tab)
+{
+ int i;
+
+ Tab->numAsOriginator = 0;
+ Tab->numAsRecipient = 0;
+ NdisAllocateSpinLock(&pAd->BATabLock);
+ for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
+ {
+ Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
+ NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
+ }
+ for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
+ {
+ Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
+ }
+}
+#endif // DOT11_N_SUPPORT //
+
+/*! \brief search the BSS table by SSID
+ * \param p_tab pointer to the bss table
+ * \param ssid SSID string
+ * \return index of the table, BSS_NOT_FOUND if not in the table
+ * \pre
+ * \post
+ * \note search by sequential search
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+ULONG BssTableSearch(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN UCHAR Channel)
+{
+ UCHAR i;
+
+ for (i = 0; i < Tab->BssNr; i++)
+ {
+ //
+ // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
+ // We should distinguish this case.
+ //
+ if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+ ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+ MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))
+ {
+ return i;
+ }
+ }
+ return (ULONG)BSS_NOT_FOUND;
+}
+
+ULONG BssSsidTableSearch(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN UCHAR Channel)
+{
+ UCHAR i;
+
+ for (i = 0; i < Tab->BssNr; i++)
+ {
+ //
+ // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
+ // We should distinguish this case.
+ //
+ if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+ ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+ MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
+ SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
+ {
+ return i;
+ }
+ }
+ return (ULONG)BSS_NOT_FOUND;
+}
+
+ULONG BssTableSearchWithSSID(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR Bssid,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN UCHAR Channel)
+{
+ UCHAR i;
+
+ for (i = 0; i < Tab->BssNr; i++)
+ {
+ if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+ ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+ MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
+ (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) ||
+ (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
+ (NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen))))
+ {
+ return i;
+ }
+ }
+ return (ULONG)BSS_NOT_FOUND;
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID BssTableDeleteEntry(
+ IN OUT BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN UCHAR Channel)
+{
+ UCHAR i, j;
+
+ for (i = 0; i < Tab->BssNr; i++)
+ {
+ if ((Tab->BssEntry[i].Channel == Channel) &&
+ (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)))
+ {
+ for (j = i; j < Tab->BssNr - 1; j++)
+ {
+ NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY));
+ }
+ NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY));
+ Tab->BssNr -= 1;
+ return;
+ }
+ }
+}
+
+#ifdef DOT11_N_SUPPORT
+/*
+ ========================================================================
+ Routine Description:
+ Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
+
+ Arguments:
+ // IRQL = DISPATCH_LEVEL
+ ========================================================================
+*/
+VOID BATableDeleteORIEntry(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN BA_ORI_ENTRY *pBAORIEntry)
+{
+
+ if (pBAORIEntry->ORI_BA_Status != Originator_NONE)
+ {
+ NdisAcquireSpinLock(&pAd->BATabLock);
+ if (pBAORIEntry->ORI_BA_Status == Originator_Done)
+ {
+ pAd->BATable.numAsOriginator -= 1;
+ DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
+ // Erase Bitmap flag.
+ }
+ pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) )); // If STA mode, erase flag here
+ pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0; // If STA mode, erase flag here
+ pBAORIEntry->ORI_BA_Status = Originator_NONE;
+ pBAORIEntry->Token = 1;
+ // Not clear Sequence here.
+ NdisReleaseSpinLock(&pAd->BATabLock);
+ }
+}
+#endif // DOT11_N_SUPPORT //
+
+/*! \brief
+ * \param
+ * \return
+ * \pre
+ * \post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+VOID BssEntrySet(
+ IN PRTMP_ADAPTER pAd,
+ OUT BSS_ENTRY *pBss,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN USHORT BeaconPeriod,
+ IN PCF_PARM pCfParm,
+ IN USHORT AtimWin,
+ IN USHORT CapabilityInfo,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR AddHtInfoLen,
+ IN UCHAR NewExtChanOffset,
+ IN UCHAR Channel,
+ IN CHAR Rssi,
+ IN LARGE_INTEGER TimeStamp,
+ IN UCHAR CkipFlag,
+ IN PEDCA_PARM pEdcaParm,
+ IN PQOS_CAPABILITY_PARM pQosCapability,
+ IN PQBSS_LOAD_PARM pQbssLoad,
+ IN USHORT LengthVIE,
+ IN PNDIS_802_11_VARIABLE_IEs pVIE)
+{
+ COPY_MAC_ADDR(pBss->Bssid, pBssid);
+ // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
+ pBss->Hidden = 1;
+ if (SsidLen > 0)
+ {
+ // For hidden SSID AP, it might send beacon with SSID len equal to 0
+ // Or send beacon /probe response with SSID len matching real SSID length,
+ // but SSID is all zero. such as "00-00-00-00" with length 4.
+ // We have to prevent this case overwrite correct table
+ if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0)
+ {
+ NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
+ pBss->SsidLen = SsidLen;
+ pBss->Hidden = 0;
+ }
+ }
+ else
+ pBss->SsidLen = 0;
+ pBss->BssType = BssType;
+ pBss->BeaconPeriod = BeaconPeriod;
+ if (BssType == BSS_INFRA)
+ {
+ if (pCfParm->bValid)
+ {
+ pBss->CfpCount = pCfParm->CfpCount;
+ pBss->CfpPeriod = pCfParm->CfpPeriod;
+ pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
+ pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
+ }
+ }
+ else
+ {
+ pBss->AtimWin = AtimWin;
+ }
+
+ pBss->CapabilityInfo = CapabilityInfo;
+ // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
+ // Combine with AuthMode, they will decide the connection methods.
+ pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
+ ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
+ if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
+ NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
+ else
+ NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
+ pBss->SupRateLen = SupRateLen;
+ ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
+ NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
+ NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
+ NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
+ pBss->NewExtChanOffset = NewExtChanOffset;
+ pBss->ExtRateLen = ExtRateLen;
+ pBss->Channel = Channel;
+ pBss->CentralChannel = Channel;
+ pBss->Rssi = Rssi;
+ // Update CkipFlag. if not exists, the value is 0x0
+ pBss->CkipFlag = CkipFlag;
+
+ // New for microsoft Fixed IEs
+ NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
+ pBss->FixIEs.BeaconInterval = BeaconPeriod;
+ pBss->FixIEs.Capabilities = CapabilityInfo;
+
+ // New for microsoft Variable IEs
+ if (LengthVIE != 0)
+ {
+ pBss->VarIELen = LengthVIE;
+ NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
+ }
+ else
+ {
+ pBss->VarIELen = 0;
+ }
+
+ pBss->AddHtInfoLen = 0;
+ pBss->HtCapabilityLen = 0;
+#ifdef DOT11_N_SUPPORT
+ if (HtCapabilityLen> 0)
+ {
+ pBss->HtCapabilityLen = HtCapabilityLen;
+ NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
+ if (AddHtInfoLen > 0)
+ {
+ pBss->AddHtInfoLen = AddHtInfoLen;
+ NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
+
+ if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
+ {
+ pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
+ }
+ else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
+ {
+ pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
+ }
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+ BssCipherParse(pBss);
+
+ // new for QOS
+ if (pEdcaParm)
+ NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+ else
+ pBss->EdcaParm.bValid = FALSE;
+ if (pQosCapability)
+ NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM));
+ else
+ pBss->QosCapability.bValid = FALSE;
+ if (pQbssLoad)
+ NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM));
+ else
+ pBss->QbssLoad.bValid = FALSE;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ PEID_STRUCT pEid;
+ USHORT Length = 0;
+
+
+ NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
+ NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
+#ifdef EXT_BUILD_CHANNEL_LIST
+ NdisZeroMemory(&pBss->CountryString[0], 3);
+ pBss->bHasCountryIE = FALSE;
+#endif // EXT_BUILD_CHANNEL_LIST //
+ pEid = (PEID_STRUCT) pVIE;
+ while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
+ {
+ switch(pEid->Eid)
+ {
+ case IE_WPA:
+ if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
+ {
+ if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
+ {
+ pBss->WpaIE.IELen = 0;
+ break;
+ }
+ pBss->WpaIE.IELen = pEid->Len + 2;
+ NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
+ }
+ break;
+ case IE_RSN:
+ if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
+ {
+ if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
+ {
+ pBss->RsnIE.IELen = 0;
+ break;
+ }
+ pBss->RsnIE.IELen = pEid->Len + 2;
+ NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
+ }
+ break;
+#ifdef EXT_BUILD_CHANNEL_LIST
+ case IE_COUNTRY:
+ NdisMoveMemory(&pBss->CountryString[0], pEid->Octet, 3);
+ pBss->bHasCountryIE = TRUE;
+ break;
+#endif // EXT_BUILD_CHANNEL_LIST //
+ }
+ Length = Length + 2 + (USHORT)pEid->Len; // Eid[1] + Len[1]+ content[Len]
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+}
+
+/*!
+ * \brief insert an entry into the bss table
+ * \param p_tab The BSS table
+ * \param Bssid BSSID
+ * \param ssid SSID
+ * \param ssid_len Length of SSID
+ * \param bss_type
+ * \param beacon_period
+ * \param timestamp
+ * \param p_cf
+ * \param atim_win
+ * \param cap
+ * \param rates
+ * \param rates_len
+ * \param channel_idx
+ * \return none
+ * \pre
+ * \post
+ * \note If SSID is identical, the old entry will be replaced by the new one
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+ULONG BssTableSetEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN USHORT BeaconPeriod,
+ IN CF_PARM *CfParm,
+ IN USHORT AtimWin,
+ IN USHORT CapabilityInfo,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR AddHtInfoLen,
+ IN UCHAR NewExtChanOffset,
+ IN UCHAR ChannelNo,
+ IN CHAR Rssi,
+ IN LARGE_INTEGER TimeStamp,
+ IN UCHAR CkipFlag,
+ IN PEDCA_PARM pEdcaParm,
+ IN PQOS_CAPABILITY_PARM pQosCapability,
+ IN PQBSS_LOAD_PARM pQbssLoad,
+ IN USHORT LengthVIE,
+ IN PNDIS_802_11_VARIABLE_IEs pVIE)
+{
+ ULONG Idx;
+
+ Idx = BssTableSearchWithSSID(Tab, pBssid, Ssid, SsidLen, ChannelNo);
+ if (Idx == BSS_NOT_FOUND)
+ {
+ if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
+ {
+ //
+ // It may happen when BSS Table was full.
+ // The desired AP will not be added into BSS Table
+ // In this case, if we found the desired AP then overwrite BSS Table.
+ //
+ if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
+ SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
+ {
+ Idx = Tab->BssOverlapNr;
+ BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
+ CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
+ NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
+ Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
+ }
+ return Idx;
+ }
+ else
+ {
+ return BSS_NOT_FOUND;
+ }
+ }
+ Idx = Tab->BssNr;
+ BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
+ CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
+ NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
+ Tab->BssNr++;
+ }
+ else
+ {
+ /* avoid Hidden SSID form beacon to overwirite correct SSID from probe response */
+ if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) ||
+ (NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen)))
+ {
+ BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
+ CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
+ NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
+ }
+ }
+
+ return Idx;
+}
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+VOID TriEventInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR i;
+
+ for (i = 0;i < MAX_TRIGGER_EVENT;i++)
+ pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
+
+ pAd->CommonCfg.TriggerEventTab.EventANo = 0;
+ pAd->CommonCfg.TriggerEventTab.EventBCountDown = 0;
+}
+
+ULONG TriEventTableSetEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT TRIGGER_EVENT_TAB *Tab,
+ IN PUCHAR pBssid,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR RegClass,
+ IN UCHAR ChannelNo)
+{
+ // Event A
+ if (HtCapabilityLen == 0)
+ {
+ if (Tab->EventANo < MAX_TRIGGER_EVENT)
+ {
+ RTMPMoveMemory(Tab->EventA[Tab->EventANo].BSSID, pBssid, 6);
+ Tab->EventA[Tab->EventANo].bValid = TRUE;
+ Tab->EventA[Tab->EventANo].Channel = ChannelNo;
+ Tab->EventA[Tab->EventANo].CDCounter = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
+ if (RegClass != 0)
+ {
+ // Beacon has Regulatory class IE. So use beacon's
+ Tab->EventA[Tab->EventANo].RegClass = RegClass;
+ }
+ else
+ {
+ // Use Station's Regulatory class instead.
+ if (pAd->StaActive.SupportedHtPhy.bHtEnable == TRUE)
+ {
+ if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
+ {
+ Tab->EventA[Tab->EventANo].RegClass = 32;
+ }
+ else if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
+ Tab->EventA[Tab->EventANo].RegClass = 33;
+ }
+ else
+ Tab->EventA[Tab->EventANo].RegClass = ??;
+
+ }
+
+ Tab->EventANo ++;
+ }
+ }
+ else if (pHtCapability->HtCapInfo.Intolerant40)
+ {
+ Tab->EventBCountDown = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
+ }
+
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Trigger Event table Maintainence called once every second.
+
+ Arguments:
+ // IRQL = DISPATCH_LEVEL
+ ========================================================================
+*/
+VOID TriEventCounterMaintenance(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR i;
+ BOOLEAN bNotify = FALSE;
+ for (i = 0;i < MAX_TRIGGER_EVENT;i++)
+ {
+ if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid && (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter > 0))
+ {
+ pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter--;
+ if (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter == 0)
+ {
+ pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
+ pAd->CommonCfg.TriggerEventTab.EventANo --;
+ // Need to send 20/40 Coexistence Notify frame if has status change.
+ bNotify = TRUE;
+ }
+ }
+ }
+ if (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0)
+ {
+ pAd->CommonCfg.TriggerEventTab.EventBCountDown--;
+ if (pAd->CommonCfg.TriggerEventTab.EventBCountDown == 0)
+ bNotify = TRUE;
+ }
+
+ if (bNotify == TRUE)
+ Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
+}
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+// IRQL = DISPATCH_LEVEL
+VOID BssTableSsidSort(
+ IN PRTMP_ADAPTER pAd,
+ OUT BSS_TABLE *OutTab,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen)
+{
+ INT i;
+ BssTableInit(OutTab);
+
+ for (i = 0; i < pAd->ScanTab.BssNr; i++)
+ {
+ BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i];
+ BOOLEAN bIsHiddenApIncluded = FALSE;
+
+ if (((pAd->CommonCfg.bIEEE80211H == 1) &&
+ (pAd->MlmeAux.Channel > 14) &&
+ RadarChannelCheck(pAd, pInBss->Channel))
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+ || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+#endif // CARRIER_DETECTION_SUPPORT //
+ )
+ {
+ if (pInBss->Hidden)
+ bIsHiddenApIncluded = TRUE;
+ }
+
+ if ((pInBss->BssType == pAd->StaCfg.BssType) &&
+ (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
+ {
+ BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
+
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ // If no Country IE exists no Connection will be established when IEEE80211dClientMode is strict.
+ if ((pAd->StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict) &&
+ (pInBss->bHasCountryIE == FALSE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict, but this AP doesn't have country IE.\n"));
+ continue;
+ }
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+#ifdef DOT11_N_SUPPORT
+ // 2.4G/5G N only mode
+ if ((pInBss->HtCapabilityLen == 0) &&
+ ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
+ continue;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // New for WPA2
+ // Check the Authmode first
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
+ if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
+ // None matched
+ continue;
+
+ // Check cipher suite, AP must have more secured cipher than station setting
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ // If it's not mixed mode, we should only let BSS pass with the same encryption
+ if (pInBss->WPA.bMixMode == FALSE)
+ if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
+ continue;
+
+ // check group cipher
+ if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
+ continue;
+
+ // check pairwise cipher, skip if none matched
+ // If profile set to AES, let it pass without question.
+ // If profile set to TKIP, we must find one mateched
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
+ continue;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ // If it's not mixed mode, we should only let BSS pass with the same encryption
+ if (pInBss->WPA2.bMixMode == FALSE)
+ if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
+ continue;
+
+ // check group cipher
+ if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
+ continue;
+
+ // check pairwise cipher, skip if none matched
+ // If profile set to AES, let it pass without question.
+ // If profile set to TKIP, we must find one mateched
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
+ continue;
+ }
+ }
+ // Bss Type matched, SSID matched.
+ // We will check wepstatus for qualification Bss
+ else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
+ //
+ // For the SESv2 case, we will not qualify WepStatus.
+ //
+ if (!pInBss->bSES)
+ continue;
+ }
+
+ // Since the AP is using hidden SSID, and we are trying to connect to ANY
+ // It definitely will fail. So, skip it.
+ // CCX also require not even try to connect it!!
+ if (SsidLen == 0)
+ continue;
+
+#ifdef DOT11_N_SUPPORT
+ // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
+ // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
+ if ((pInBss->CentralChannel != pInBss->Channel) &&
+ (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
+ {
+ if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ SetCommonHT(pAd);
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+ }
+ else
+ {
+ if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20)
+ {
+ SetCommonHT(pAd);
+ }
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // copy matching BSS from InTab to OutTab
+ NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
+
+ OutTab->BssNr++;
+ }
+ else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
+ {
+ BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
+
+
+#ifdef DOT11_N_SUPPORT
+ // 2.4G/5G N only mode
+ if ((pInBss->HtCapabilityLen == 0) &&
+ ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
+ continue;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // New for WPA2
+ // Check the Authmode first
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
+ if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
+ // None matched
+ continue;
+
+ // Check cipher suite, AP must have more secured cipher than station setting
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ // If it's not mixed mode, we should only let BSS pass with the same encryption
+ if (pInBss->WPA.bMixMode == FALSE)
+ if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
+ continue;
+
+ // check group cipher
+ if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
+ continue;
+
+ // check pairwise cipher, skip if none matched
+ // If profile set to AES, let it pass without question.
+ // If profile set to TKIP, we must find one mateched
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
+ continue;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ // If it's not mixed mode, we should only let BSS pass with the same encryption
+ if (pInBss->WPA2.bMixMode == FALSE)
+ if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
+ continue;
+
+ // check group cipher
+ if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
+ continue;
+
+ // check pairwise cipher, skip if none matched
+ // If profile set to AES, let it pass without question.
+ // If profile set to TKIP, we must find one mateched
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
+ continue;
+ }
+ }
+ // Bss Type matched, SSID matched.
+ // We will check wepstatus for qualification Bss
+ else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
+ continue;
+
+#ifdef DOT11_N_SUPPORT
+ // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
+ // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
+ if ((pInBss->CentralChannel != pInBss->Channel) &&
+ (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
+ {
+ if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ SetCommonHT(pAd);
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // copy matching BSS from InTab to OutTab
+ NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
+
+ OutTab->BssNr++;
+ }
+
+ if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
+ break;
+ }
+
+ BssTableSortByRssi(OutTab);
+}
+
+
+// IRQL = DISPATCH_LEVEL
+VOID BssTableSortByRssi(
+ IN OUT BSS_TABLE *OutTab)
+{
+ INT i, j;
+ BSS_ENTRY TmpBss;
+
+ for (i = 0; i < OutTab->BssNr - 1; i++)
+ {
+ for (j = i+1; j < OutTab->BssNr; j++)
+ {
+ if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
+ {
+ NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
+ NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
+ NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
+ }
+ }
+ }
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+VOID BssCipherParse(
+ IN OUT PBSS_ENTRY pBss)
+{
+ PEID_STRUCT pEid;
+ PUCHAR pTmp;
+ PRSN_IE_HEADER_STRUCT pRsnHeader;
+ PCIPHER_SUITE_STRUCT pCipher;
+ PAKM_SUITE_STRUCT pAKM;
+ USHORT Count;
+ INT Length;
+ NDIS_802_11_ENCRYPTION_STATUS TmpCipher;
+
+ //
+ // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
+ //
+ if (pBss->Privacy)
+ {
+ pBss->WepStatus = Ndis802_11WEPEnabled;
+ }
+ else
+ {
+ pBss->WepStatus = Ndis802_11WEPDisabled;
+ }
+ // Set default to disable & open authentication before parsing variable IE
+ pBss->AuthMode = Ndis802_11AuthModeOpen;
+ pBss->AuthModeAux = Ndis802_11AuthModeOpen;
+
+ // Init WPA setting
+ pBss->WPA.PairCipher = Ndis802_11WEPDisabled;
+ pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
+ pBss->WPA.GroupCipher = Ndis802_11WEPDisabled;
+ pBss->WPA.RsnCapability = 0;
+ pBss->WPA.bMixMode = FALSE;
+
+ // Init WPA2 setting
+ pBss->WPA2.PairCipher = Ndis802_11WEPDisabled;
+ pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
+ pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled;
+ pBss->WPA2.RsnCapability = 0;
+ pBss->WPA2.bMixMode = FALSE;
+
+
+ Length = (INT) pBss->VarIELen;
+
+ while (Length > 0)
+ {
+ // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
+ pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
+ pEid = (PEID_STRUCT) pTmp;
+ switch (pEid->Eid)
+ {
+ case IE_WPA:
+ //Parse Cisco IE_WPA (LEAP, CCKM, etc.)
+ if ( NdisEqualMemory((pTmp+8), CISCO_OUI, 3))
+ {
+ pTmp += 11;
+ switch (*pTmp)
+ {
+ case 1:
+ case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+ pBss->WepStatus = Ndis802_11Encryption1Enabled;
+ pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
+ pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ pBss->WepStatus = Ndis802_11Encryption2Enabled;
+ pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
+ pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 4:
+ pBss->WepStatus = Ndis802_11Encryption3Enabled;
+ pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
+ pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+ break;
+ default:
+ break;
+ }
+
+ // if Cisco IE_WPA, break
+ break;
+ }
+ else if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
+ {
+ pBss->bSES = TRUE;
+ break;
+ }
+ else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
+ {
+ // if unsupported vendor specific IE
+ break;
+ }
+ // Skip OUI, version, and multicast suite
+ // This part should be improved in the future when AP supported multiple cipher suite.
+ // For now, it's OK since almost all APs have fixed cipher suite supported.
+ // pTmp = (PUCHAR) pEid->Octet;
+ pTmp += 11;
+
+ // Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
+ // Value Meaning
+ // 0 None
+ // 1 WEP-40
+ // 2 Tkip
+ // 3 WRAP
+ // 4 AES
+ // 5 WEP-104
+ // Parse group cipher
+ switch (*pTmp)
+ {
+ case 1:
+ case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+ pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
+ break;
+ }
+ // number of unicast suite
+ pTmp += 1;
+
+ // skip all unicast cipher suites
+ //Count = *(PUSHORT) pTmp;
+ Count = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
+
+ // Parsing all unicast cipher suite
+ while (Count > 0)
+ {
+ // Skip OUI
+ pTmp += 3;
+ TmpCipher = Ndis802_11WEPDisabled;
+ switch (*pTmp)
+ {
+ case 1:
+ case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+ TmpCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ TmpCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ TmpCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
+ break;
+ }
+ if (TmpCipher > pBss->WPA.PairCipher)
+ {
+ // Move the lower cipher suite to PairCipherAux
+ pBss->WPA.PairCipherAux = pBss->WPA.PairCipher;
+ pBss->WPA.PairCipher = TmpCipher;
+ }
+ else
+ {
+ pBss->WPA.PairCipherAux = TmpCipher;
+ }
+ pTmp++;
+ Count--;
+ }
+
+ // 4. get AKM suite counts
+ //Count = *(PUSHORT) pTmp;
+ Count = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
+ pTmp += 3;
+
+ switch (*pTmp)
+ {
+ case 1:
+ // Set AP support WPA mode
+ if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+ pBss->AuthMode = Ndis802_11AuthModeWPA;
+ else
+ pBss->AuthModeAux = Ndis802_11AuthModeWPA;
+ break;
+ case 2:
+ // Set AP support WPA mode
+ if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+ pBss->AuthMode = Ndis802_11AuthModeWPAPSK;
+ else
+ pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK;
+ break;
+ default:
+ break;
+ }
+ pTmp += 1;
+
+ // Fixed for WPA-None
+ if (pBss->BssType == BSS_ADHOC)
+ {
+ pBss->AuthMode = Ndis802_11AuthModeWPANone;
+ pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
+ pBss->WepStatus = pBss->WPA.GroupCipher;
+ if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
+ pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
+ }
+ else
+ pBss->WepStatus = pBss->WPA.PairCipher;
+
+ // Check the Pair & Group, if different, turn on mixed mode flag
+ if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
+ pBss->WPA.bMixMode = TRUE;
+
+ break;
+
+ case IE_RSN:
+ pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
+
+ // 0. Version must be 1
+ if (le2cpu16(pRsnHeader->Version) != 1)
+ break;
+ pTmp += sizeof(RSN_IE_HEADER_STRUCT);
+
+ // 1. Check group cipher
+ pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
+ if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
+ break;
+
+ // Parse group cipher
+ switch (pCipher->Type)
+ {
+ case 1:
+ case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+ pBss->WPA2.GroupCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
+ break;
+ }
+ // set to correct offset for next parsing
+ pTmp += sizeof(CIPHER_SUITE_STRUCT);
+
+ // 2. Get pairwise cipher counts
+ //Count = *(PUSHORT) pTmp;
+ Count = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
+
+ // 3. Get pairwise cipher
+ // Parsing all unicast cipher suite
+ while (Count > 0)
+ {
+ // Skip OUI
+ pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
+ TmpCipher = Ndis802_11WEPDisabled;
+ switch (pCipher->Type)
+ {
+ case 1:
+ case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+ TmpCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ TmpCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ TmpCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
+ break;
+ }
+ if (TmpCipher > pBss->WPA2.PairCipher)
+ {
+ // Move the lower cipher suite to PairCipherAux
+ pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
+ pBss->WPA2.PairCipher = TmpCipher;
+ }
+ else
+ {
+ pBss->WPA2.PairCipherAux = TmpCipher;
+ }
+ pTmp += sizeof(CIPHER_SUITE_STRUCT);
+ Count--;
+ }
+
+ // 4. get AKM suite counts
+ //Count = *(PUSHORT) pTmp;
+ Count = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
+
+ // 5. Get AKM ciphers
+ pAKM = (PAKM_SUITE_STRUCT) pTmp;
+ if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
+ break;
+
+ switch (pAKM->Type)
+ {
+ case 1:
+ // Set AP support WPA mode
+ if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+ pBss->AuthMode = Ndis802_11AuthModeWPA2;
+ else
+ pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
+ break;
+ case 2:
+ // Set AP support WPA mode
+ if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+ pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
+ else
+ pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
+ break;
+ default:
+ break;
+ }
+ pTmp += (Count * sizeof(AKM_SUITE_STRUCT));
+
+ // Fixed for WPA-None
+ if (pBss->BssType == BSS_ADHOC)
+ {
+ pBss->AuthMode = Ndis802_11AuthModeWPANone;
+ pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
+ pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
+ pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
+ pBss->WepStatus = pBss->WPA.GroupCipher;
+ if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
+ pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
+ }
+ pBss->WepStatus = pBss->WPA2.PairCipher;
+
+ // 6. Get RSN capability
+ //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
+ pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
+
+ // Check the Pair & Group, if different, turn on mixed mode flag
+ if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
+ pBss->WPA2.bMixMode = TRUE;
+
+ break;
+ default:
+ break;
+ }
+ Length -= (pEid->Len + 2);
+ }
+}
+
+// ===========================================================================================
+// mac_table.c
+// ===========================================================================================
+
+/*! \brief generates a random mac address value for IBSS BSSID
+ * \param Addr the bssid location
+ * \return none
+ * \pre
+ * \post
+ */
+VOID MacAddrRandomBssid(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pAddr)
+{
+ INT i;
+
+ for (i = 0; i < MAC_ADDR_LEN; i++)
+ {
+ pAddr[i] = RandomByte(pAd);
+ }
+
+ pAddr[0] = (pAddr[0] & 0xfe) | 0x02; // the first 2 bits must be 01xxxxxxxx
+}
+
+/*! \brief init the management mac frame header
+ * \param p_hdr mac header
+ * \param subtype subtype of the frame
+ * \param p_ds destination address, don't care if it is a broadcast address
+ * \return none
+ * \pre the station has the following information in the pAd->StaCfg
+ * - bssid
+ * - station address
+ * \post
+ * \note this function initializes the following field
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ */
+VOID MgtMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR SubType,
+ IN UCHAR ToDs,
+ IN PUCHAR pDA,
+ IN PUCHAR pBssid)
+{
+ NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+
+ pHdr80211->FC.Type = BTYPE_MGMT;
+ pHdr80211->FC.SubType = SubType;
+// if (SubType == SUBTYPE_ACK) // sample, no use, it will conflict with ACTION frame sub type
+// pHdr80211->FC.Type = BTYPE_CNTL;
+ pHdr80211->FC.ToDs = ToDs;
+ COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
+#endif // CONFIG_STA_SUPPORT //
+ COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
+}
+
+// ===========================================================================================
+// mem_mgmt.c
+// ===========================================================================================
+
+/*!***************************************************************************
+ * This routine build an outgoing frame, and fill all information specified
+ * in argument list to the frame body. The actual frame size is the summation
+ * of all arguments.
+ * input params:
+ * Buffer - pointer to a pre-allocated memory segment
+ * args - a list of <int arg_size, arg> pairs.
+ * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
+ * function will FAIL!!!
+ * return:
+ * Size of the buffer
+ * usage:
+ * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ****************************************************************************/
+ULONG MakeOutgoingFrame(
+ OUT CHAR *Buffer,
+ OUT ULONG *FrameLen, ...)
+{
+ CHAR *p;
+ int leng;
+ ULONG TotLeng;
+ va_list Args;
+
+ // calculates the total length
+ TotLeng = 0;
+ va_start(Args, FrameLen);
+ do
+ {
+ leng = va_arg(Args, int);
+ if (leng == END_OF_ARGS)
+ {
+ break;
+ }
+ p = va_arg(Args, PVOID);
+ NdisMoveMemory(&Buffer[TotLeng], p, leng);
+ TotLeng = TotLeng + leng;
+ } while(TRUE);
+
+ va_end(Args); /* clean up */
+ *FrameLen = TotLeng;
+ return TotLeng;
+}
+
+// ===========================================================================================
+// mlme_queue.c
+// ===========================================================================================
+
+/*! \brief Initialize The MLME Queue, used by MLME Functions
+ * \param *Queue The MLME Queue
+ * \return Always Return NDIS_STATE_SUCCESS in this implementation
+ * \pre
+ * \post
+ * \note Because this is done only once (at the init stage), no need to be locked
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+NDIS_STATUS MlmeQueueInit(
+ IN MLME_QUEUE *Queue)
+{
+ INT i;
+
+ NdisAllocateSpinLock(&Queue->Lock);
+
+ Queue->Num = 0;
+ Queue->Head = 0;
+ Queue->Tail = 0;
+
+ for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++)
+ {
+ Queue->Entry[i].Occupied = FALSE;
+ Queue->Entry[i].MsgLen = 0;
+ NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
+ * \param *Queue The MLME Queue
+ * \param Machine The State Machine Id
+ * \param MsgType The Message Type
+ * \param MsgLen The Message length
+ * \param *Msg The message pointer
+ * \return TRUE if enqueue is successful, FALSE if the queue is full
+ * \pre
+ * \post
+ * \note The message has to be initialized
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeEnqueue(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Machine,
+ IN ULONG MsgType,
+ IN ULONG MsgLen,
+ IN VOID *Msg)
+{
+ INT Tail;
+ MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return FALSE;
+
+ // First check the size, it MUST not exceed the mlme queue size
+ if (MsgLen > MGMT_DMA_BUFFER_SIZE)
+ {
+ DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
+ return FALSE;
+ }
+
+ if (MlmeQueueFull(Queue))
+ {
+ return FALSE;
+ }
+
+ NdisAcquireSpinLock(&(Queue->Lock));
+ Tail = Queue->Tail;
+ Queue->Tail++;
+ Queue->Num++;
+ if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
+ {
+ Queue->Tail = 0;
+ }
+
+ Queue->Entry[Tail].Wcid = RESERVED_WCID;
+ Queue->Entry[Tail].Occupied = TRUE;
+ Queue->Entry[Tail].Machine = Machine;
+ Queue->Entry[Tail].MsgType = MsgType;
+ Queue->Entry[Tail].MsgLen = MsgLen;
+
+ if (Msg != NULL)
+ {
+ NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
+ }
+
+ NdisReleaseSpinLock(&(Queue->Lock));
+ return TRUE;
+}
+
+/*! \brief This function is used when Recv gets a MLME message
+ * \param *Queue The MLME Queue
+ * \param TimeStampHigh The upper 32 bit of timestamp
+ * \param TimeStampLow The lower 32 bit of timestamp
+ * \param Rssi The receiving RSSI strength
+ * \param MsgLen The length of the message
+ * \param *Msg The message pointer
+ * \return TRUE if everything ok, FALSE otherwise (like Queue Full)
+ * \pre
+ * \post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeEnqueueForRecv(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN ULONG TimeStampHigh,
+ IN ULONG TimeStampLow,
+ IN UCHAR Rssi0,
+ IN UCHAR Rssi1,
+ IN UCHAR Rssi2,
+ IN ULONG MsgLen,
+ IN VOID *Msg,
+ IN UCHAR Signal)
+{
+ INT Tail, Machine;
+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+ INT MsgType;
+ MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
+
+#ifdef RALINK_ATE
+ /* Nothing to do in ATE mode */
+ if(ATE_ON(pAd))
+ return FALSE;
+#endif // RALINK_ATE //
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
+ return FALSE;
+ }
+
+ // First check the size, it MUST not exceed the mlme queue size
+ if (MsgLen > MGMT_DMA_BUFFER_SIZE)
+ {
+ DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
+ return FALSE;
+ }
+
+ if (MlmeQueueFull(Queue))
+ {
+ return FALSE;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
+ {
+ DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
+ return FALSE;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // OK, we got all the informations, it is time to put things into queue
+ NdisAcquireSpinLock(&(Queue->Lock));
+ Tail = Queue->Tail;
+ Queue->Tail++;
+ Queue->Num++;
+ if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
+ {
+ Queue->Tail = 0;
+ }
+ Queue->Entry[Tail].Occupied = TRUE;
+ Queue->Entry[Tail].Machine = Machine;
+ Queue->Entry[Tail].MsgType = MsgType;
+ Queue->Entry[Tail].MsgLen = MsgLen;
+ Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
+ Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
+ Queue->Entry[Tail].Rssi0 = Rssi0;
+ Queue->Entry[Tail].Rssi1 = Rssi1;
+ Queue->Entry[Tail].Rssi2 = Rssi2;
+ Queue->Entry[Tail].Signal = Signal;
+ Queue->Entry[Tail].Wcid = (UCHAR)Wcid;
+
+ Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
+
+ if (Msg != NULL)
+ {
+ NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
+ }
+
+ NdisReleaseSpinLock(&(Queue->Lock));
+
+ RT28XX_MLME_HANDLER(pAd);
+
+ return TRUE;
+}
+
+
+/*! \brief Dequeue a message from the MLME Queue
+ * \param *Queue The MLME Queue
+ * \param *Elem The message dequeued from MLME Queue
+ * \return TRUE if the Elem contains something, FALSE otherwise
+ * \pre
+ * \post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeDequeue(
+ IN MLME_QUEUE *Queue,
+ OUT MLME_QUEUE_ELEM **Elem)
+{
+ NdisAcquireSpinLock(&(Queue->Lock));
+ *Elem = &(Queue->Entry[Queue->Head]);
+ Queue->Num--;
+ Queue->Head++;
+ if (Queue->Head == MAX_LEN_OF_MLME_QUEUE)
+ {
+ Queue->Head = 0;
+ }
+ NdisReleaseSpinLock(&(Queue->Lock));
+ return TRUE;
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeRestartStateMachine(
+ IN PRTMP_ADAPTER pAd)
+{
+#ifdef CONFIG_STA_SUPPORT
+ BOOLEAN Cancelled;
+#endif // CONFIG_STA_SUPPORT //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+#ifdef QOS_DLS_SUPPORT
+ UCHAR i;
+#endif // QOS_DLS_SUPPORT //
+ // Cancel all timer events
+ // Be careful to cancel new added timer
+ RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
+
+#ifdef QOS_DLS_SUPPORT
+ for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
+ }
+#endif // QOS_DLS_SUPPORT //
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Change back to original channel in case of doing scan
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+ // Resume MSDU which is turned off durning scan
+ RTMPResumeMsduTransmission(pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Set all state machines back IDLE
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
+#ifdef QOS_DLS_SUPPORT
+ pAd->Mlme.DlsMachine.CurrState = DLS_IDLE;
+#endif // QOS_DLS_SUPPORT //
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+}
+
+/*! \brief test if the MLME Queue is empty
+ * \param *Queue The MLME Queue
+ * \return TRUE if the Queue is empty, FALSE otherwise
+ * \pre
+ * \post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeQueueEmpty(
+ IN MLME_QUEUE *Queue)
+{
+ BOOLEAN Ans;
+
+ NdisAcquireSpinLock(&(Queue->Lock));
+ Ans = (Queue->Num == 0);
+ NdisReleaseSpinLock(&(Queue->Lock));
+
+ return Ans;
+}
+
+/*! \brief test if the MLME Queue is full
+ * \param *Queue The MLME Queue
+ * \return TRUE if the Queue is empty, FALSE otherwise
+ * \pre
+ * \post
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeQueueFull(
+ IN MLME_QUEUE *Queue)
+{
+ BOOLEAN Ans;
+
+ NdisAcquireSpinLock(&(Queue->Lock));
+ Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied);
+ NdisReleaseSpinLock(&(Queue->Lock));
+
+ return Ans;
+}
+
+/*! \brief The destructor of MLME Queue
+ * \param
+ * \return
+ * \pre
+ * \post
+ * \note Clear Mlme Queue, Set Queue->Num to Zero.
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+VOID MlmeQueueDestroy(
+ IN MLME_QUEUE *pQueue)
+{
+ NdisAcquireSpinLock(&(pQueue->Lock));
+ pQueue->Num = 0;
+ pQueue->Head = 0;
+ pQueue->Tail = 0;
+ NdisReleaseSpinLock(&(pQueue->Lock));
+ NdisFreeSpinLock(&(pQueue->Lock));
+}
+
+/*! \brief To substitute the message type if the message is coming from external
+ * \param pFrame The frame received
+ * \param *Machine The state machine
+ * \param *MsgType the message type for the state machine
+ * \return TRUE if the substitution is successful, FALSE otherwise
+ * \pre
+ * \post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+#ifdef CONFIG_STA_SUPPORT
+BOOLEAN MsgTypeSubst(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 pFrame,
+ OUT INT *Machine,
+ OUT INT *MsgType)
+{
+ USHORT Seq;
+ UCHAR EAPType;
+ PUCHAR pData;
+
+ // Pointer to start of data frames including SNAP header
+ pData = (PUCHAR) pFrame + LENGTH_802_11;
+
+ // The only data type will pass to this function is EAPOL frame
+ if (pFrame->Hdr.FC.Type == BTYPE_DATA)
+ {
+ if (NdisEqualMemory(SNAP_AIRONET, pData, LENGTH_802_1_H))
+ {
+ // Cisco Aironet SNAP header
+ *Machine = AIRONET_STATE_MACHINE;
+ *MsgType = MT2_AIRONET_MSG;
+ return (TRUE);
+ }
+#ifdef LEAP_SUPPORT
+ if ( pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP ) //LEAP
+ {
+ // LEAP frames
+ *Machine = LEAP_STATE_MACHINE;
+ EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
+ return (LeapMsgTypeSubst(EAPType, MsgType));
+ }
+ else
+#endif // LEAP_SUPPORT //
+ {
+ *Machine = WPA_PSK_STATE_MACHINE;
+ EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
+ return(WpaMsgTypeSubst(EAPType, MsgType));
+ }
+ }
+
+ switch (pFrame->Hdr.FC.SubType)
+ {
+ case SUBTYPE_ASSOC_REQ:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_ASSOC_REQ;
+ break;
+ case SUBTYPE_ASSOC_RSP:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_ASSOC_RSP;
+ break;
+ case SUBTYPE_REASSOC_REQ:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_REASSOC_REQ;
+ break;
+ case SUBTYPE_REASSOC_RSP:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_REASSOC_RSP;
+ break;
+ case SUBTYPE_PROBE_REQ:
+ *Machine = SYNC_STATE_MACHINE;
+ *MsgType = MT2_PEER_PROBE_REQ;
+ break;
+ case SUBTYPE_PROBE_RSP:
+ *Machine = SYNC_STATE_MACHINE;
+ *MsgType = MT2_PEER_PROBE_RSP;
+ break;
+ case SUBTYPE_BEACON:
+ *Machine = SYNC_STATE_MACHINE;
+ *MsgType = MT2_PEER_BEACON;
+ break;
+ case SUBTYPE_ATIM:
+ *Machine = SYNC_STATE_MACHINE;
+ *MsgType = MT2_PEER_ATIM;
+ break;
+ case SUBTYPE_DISASSOC:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_DISASSOC_REQ;
+ break;
+ case SUBTYPE_AUTH:
+ // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
+ NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
+ if (Seq == 1 || Seq == 3)
+ {
+ *Machine = AUTH_RSP_STATE_MACHINE;
+ *MsgType = MT2_PEER_AUTH_ODD;
+ }
+ else if (Seq == 2 || Seq == 4)
+ {
+ *Machine = AUTH_STATE_MACHINE;
+ *MsgType = MT2_PEER_AUTH_EVEN;
+ }
+ else
+ {
+ return FALSE;
+ }
+ break;
+ case SUBTYPE_DEAUTH:
+ *Machine = AUTH_RSP_STATE_MACHINE;
+ *MsgType = MT2_PEER_DEAUTH;
+ break;
+ case SUBTYPE_ACTION:
+ *Machine = ACTION_STATE_MACHINE;
+ // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
+ if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
+ {
+ *MsgType = MT2_ACT_INVALID;
+ }
+ else
+ {
+ *MsgType = (pFrame->Octet[0]&0x7F);
+ }
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+
+ return TRUE;
+}
+#endif // CONFIG_STA_SUPPORT //
+
+// ===========================================================================================
+// state_machine.c
+// ===========================================================================================
+
+/*! \brief Initialize the state machine.
+ * \param *S pointer to the state machine
+ * \param Trans State machine transition function
+ * \param StNr number of states
+ * \param MsgNr number of messages
+ * \param DefFunc default function, when there is invalid state/message combination
+ * \param InitState initial state of the state machine
+ * \param Base StateMachine base, internal use only
+ * \pre p_sm should be a legal pointer
+ * \post
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+VOID StateMachineInit(
+ IN STATE_MACHINE *S,
+ IN STATE_MACHINE_FUNC Trans[],
+ IN ULONG StNr,
+ IN ULONG MsgNr,
+ IN STATE_MACHINE_FUNC DefFunc,
+ IN ULONG InitState,
+ IN ULONG Base)
+{
+ ULONG i, j;
+
+ // set number of states and messages
+ S->NrState = StNr;
+ S->NrMsg = MsgNr;
+ S->Base = Base;
+
+ S->TransFunc = Trans;
+
+ // init all state transition to default function
+ for (i = 0; i < StNr; i++)
+ {
+ for (j = 0; j < MsgNr; j++)
+ {
+ S->TransFunc[i * MsgNr + j] = DefFunc;
+ }
+ }
+
+ // set the starting state
+ S->CurrState = InitState;
+}
+
+/*! \brief This function fills in the function pointer into the cell in the state machine
+ * \param *S pointer to the state machine
+ * \param St state
+ * \param Msg incoming message
+ * \param f the function to be executed when (state, message) combination occurs at the state machine
+ * \pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state
+ * \post
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+VOID StateMachineSetAction(
+ IN STATE_MACHINE *S,
+ IN ULONG St,
+ IN ULONG Msg,
+ IN STATE_MACHINE_FUNC Func)
+{
+ ULONG MsgIdx;
+
+ MsgIdx = Msg - S->Base;
+
+ if (St < S->NrState && MsgIdx < S->NrMsg)
+ {
+ // boundary checking before setting the action
+ S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
+ }
+}
+
+/*! \brief This function does the state transition
+ * \param *Adapter the NIC adapter pointer
+ * \param *S the state machine
+ * \param *Elem the message to be executed
+ * \return None
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+VOID StateMachinePerformAction(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem);
+}
+
+/*
+ ==========================================================================
+ Description:
+ The drop function, when machine executes this, the message is simply
+ ignored. This function does nothing, the message is freed in
+ StateMachinePerformAction()
+ ==========================================================================
+ */
+VOID Drop(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+// ===========================================================================================
+// lfsr.c
+// ===========================================================================================
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+VOID LfsrInit(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Seed)
+{
+ if (Seed == 0)
+ pAd->Mlme.ShiftReg = 1;
+ else
+ pAd->Mlme.ShiftReg = Seed;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+UCHAR RandomByte(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG i;
+ UCHAR R, Result;
+
+ R = 0;
+
+ if (pAd->Mlme.ShiftReg == 0)
+ NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg);
+
+ for (i = 0; i < 8; i++)
+ {
+ if (pAd->Mlme.ShiftReg & 0x00000001)
+ {
+ pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
+ Result = 1;
+ }
+ else
+ {
+ pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
+ Result = 0;
+ }
+ R = (R << 1) | Result;
+ }
+
+ return R;
+}
+
+VOID AsicUpdateAutoFallBackTable(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pRateTable)
+{
+ UCHAR i;
+ HT_FBK_CFG0_STRUC HtCfg0;
+ HT_FBK_CFG1_STRUC HtCfg1;
+ LG_FBK_CFG0_STRUC LgCfg0;
+ LG_FBK_CFG1_STRUC LgCfg1;
+ PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate;
+
+ // set to initial value
+ HtCfg0.word = 0x65432100;
+ HtCfg1.word = 0xedcba988;
+ LgCfg0.word = 0xedcba988;
+ LgCfg1.word = 0x00002100;
+
+ pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
+ for (i = 1; i < *((PUCHAR) pRateTable); i++)
+ {
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
+ switch (pCurrTxRate->Mode)
+ {
+ case 0: //CCK
+ break;
+ case 1: //OFDM
+ {
+ switch(pCurrTxRate->CurrMCS)
+ {
+ case 0:
+ LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 1:
+ LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 2:
+ LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 3:
+ LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 4:
+ LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 5:
+ LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 6:
+ LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 7:
+ LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ }
+ }
+ break;
+#ifdef DOT11_N_SUPPORT
+ case 2: //HT-MIX
+ case 3: //HT-GF
+ {
+ if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
+ {
+ switch(pCurrTxRate->CurrMCS)
+ {
+ case 0:
+ HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
+ break;
+ case 1:
+ HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
+ break;
+ case 2:
+ HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
+ break;
+ case 3:
+ HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
+ break;
+ case 4:
+ HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
+ break;
+ case 5:
+ HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
+ break;
+ case 6:
+ HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
+ break;
+ case 7:
+ HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
+ break;
+ case 8:
+ HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
+ break;
+ case 9:
+ HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
+ break;
+ case 10:
+ HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
+ break;
+ case 11:
+ HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
+ break;
+ case 12:
+ HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
+ break;
+ case 13:
+ HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
+ break;
+ case 14:
+ HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
+ break;
+ case 15:
+ HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
+ }
+ }
+ }
+ break;
+#endif // DOT11_N_SUPPORT //
+ }
+
+ pNextTxRate = pCurrTxRate;
+ }
+
+ RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
+ RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
+ RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
+ RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set MAC register value according operation mode.
+ OperationMode AND bNonGFExist are for MM and GF Proteciton.
+ If MM or GF mask is not set, those passing argument doesn't not take effect.
+
+ Operation mode meaning:
+ = 0 : Pure HT, no preotection.
+ = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
+ = 0x10: No Transmission in 40M is protected.
+ = 0x11: Transmission in both 40M and 20M shall be protected
+ if (bNonGFExist)
+ we should choose not to use GF. But still set correct ASIC registers.
+ ========================================================================
+*/
+VOID AsicUpdateProtect(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT OperationMode,
+ IN UCHAR SetMask,
+ IN BOOLEAN bDisableBGProtect,
+ IN BOOLEAN bNonGFExist)
+{
+ PROT_CFG_STRUC ProtCfg, ProtCfg4;
+ UINT32 Protect[6];
+ USHORT offset;
+ UCHAR i;
+ UINT32 MacReg = 0;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+#ifdef DOT11_N_SUPPORT
+ if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
+ {
+ return;
+ }
+
+ if (pAd->BATable.numAsOriginator)
+ {
+ //
+ // enable the RTS/CTS to avoid channel collision
+ //
+ SetMask = ALLN_SETPROTECT;
+ OperationMode = 8;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // Config ASIC RTS threshold register
+ RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
+ MacReg &= 0xFF0000FF;
+
+ // If the user want disable RtsThreshold and enbale Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
+ if ((
+#ifdef DOT11_N_SUPPORT
+ (pAd->CommonCfg.BACapability.field.AmsduEnable) ||
+#endif // DOT11_N_SUPPORT //
+ (pAd->CommonCfg.bAggregationCapable == TRUE))
+ && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
+ {
+ MacReg |= (0x1000 << 8);
+ }
+ else
+ {
+ MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
+ }
+
+ RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
+
+ // Initial common protection settings
+ RTMPZeroMemory(Protect, sizeof(Protect));
+ ProtCfg4.word = 0;
+ ProtCfg.word = 0;
+ ProtCfg.field.TxopAllowGF40 = 1;
+ ProtCfg.field.TxopAllowGF20 = 1;
+ ProtCfg.field.TxopAllowMM40 = 1;
+ ProtCfg.field.TxopAllowMM20 = 1;
+ ProtCfg.field.TxopAllowOfdm = 1;
+ ProtCfg.field.TxopAllowCck = 1;
+ ProtCfg.field.RTSThEn = 1;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+
+ // update PHY mode and rate
+ if (pAd->CommonCfg.Channel > 14)
+ ProtCfg.field.ProtectRate = 0x4000;
+ ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
+
+ // Handle legacy(B/G) protection
+ if (bDisableBGProtect)
+ {
+ //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
+ ProtCfg.field.ProtectCtrl = 0;
+ Protect[0] = ProtCfg.word;
+ Protect[1] = ProtCfg.word;
+ }
+ else
+ {
+ //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
+ ProtCfg.field.ProtectCtrl = 0; // CCK do not need to be protected
+ Protect[0] = ProtCfg.word;
+ ProtCfg.field.ProtectCtrl = ASIC_CTS; // OFDM needs using CCK to protect
+ Protect[1] = ProtCfg.word;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // Decide HT frame protection.
+ if ((SetMask & ALLN_SETPROTECT) != 0)
+ {
+ switch(OperationMode)
+ {
+ case 0x0:
+ // NO PROTECT
+ // 1.All STAs in the BSS are 20/40 MHz HT
+ // 2. in ai 20/40MHz BSS
+ // 3. all STAs are 20MHz in a 20MHz BSS
+ // Pure HT. no protection.
+
+ // MM20_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 010111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
+ Protect[2] = 0x01744004;
+
+ // MM40_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 111111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
+ Protect[3] = 0x03f44084;
+
+ // CF20_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 010111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
+ Protect[4] = 0x01744004;
+
+ // CF40_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 111111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
+ Protect[5] = 0x03f44084;
+
+ if (bNonGFExist)
+ {
+ // PROT_NAV(19:18) -- 01 (Short NAV protectiion)
+ // PROT_CTRL(17:16) -- 01 (RTS/CTS)
+ Protect[4] = 0x01754004;
+ Protect[5] = 0x03f54084;
+ }
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+ break;
+
+ case 1:
+ // This is "HT non-member protection mode."
+ // If there may be non-HT STAs my BSS
+ ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
+ ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+ {
+ ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
+ ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
+ }
+ //Assign Protection method for 20&40 MHz packets
+ ProtCfg.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+ ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+ Protect[2] = ProtCfg.word;
+ Protect[3] = ProtCfg4.word;
+ Protect[4] = ProtCfg.word;
+ Protect[5] = ProtCfg4.word;
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+ break;
+
+ case 2:
+ // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
+ ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
+ ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
+
+ //Assign Protection method for 40MHz packets
+ ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+ Protect[2] = ProtCfg.word;
+ Protect[3] = ProtCfg4.word;
+ if (bNonGFExist)
+ {
+ ProtCfg.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+ }
+ Protect[4] = ProtCfg.word;
+ Protect[5] = ProtCfg4.word;
+
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+ break;
+
+ case 3:
+ // HT mixed mode. PROTECT ALL!
+ // Assign Rate
+ ProtCfg.word = 0x01744004; //duplicaet legacy 24M. BW set 1.
+ ProtCfg4.word = 0x03f44084;
+ // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+ {
+ ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
+ ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
+ }
+ //Assign Protection method for 20&40 MHz packets
+ ProtCfg.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+ ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+ Protect[2] = ProtCfg.word;
+ Protect[3] = ProtCfg4.word;
+ Protect[4] = ProtCfg.word;
+ Protect[5] = ProtCfg4.word;
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+ break;
+
+ case 8:
+ Protect[2] = 0x01754004;
+ Protect[3] = 0x03f54084;
+ Protect[4] = 0x01754004;
+ Protect[5] = 0x03f54084;
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+ break;
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+ offset = CCK_PROT_CFG;
+ for (i = 0;i < 6;i++)
+ {
+ if ((SetMask & (1<< i)))
+ {
+ RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
+ }
+ }
+}
+
+
+#ifdef RT30xx
+/*
+ ========================================================================
+
+ Routine Description: Write RT30xx RF register through MAC
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RT30xxWriteRFRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR RegID,
+ IN UCHAR Value)
+{
+ RF_CSR_CFG_STRUC rfcsr;
+ UINT i = 0;
+
+ do
+ {
+ RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+ if (!rfcsr.field.RF_CSR_KICK)
+ break;
+ i++;
+ }
+ while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+ if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ rfcsr.field.RF_CSR_WR = 1;
+ rfcsr.field.RF_CSR_KICK = 1;
+ rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
+ rfcsr.field.RF_CSR_DATA = Value;
+
+ RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
+
+ return STATUS_SUCCESS;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description: Read RT30xx RF register through MAC
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RT30xxReadRFRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR RegID,
+ IN PUCHAR pValue)
+{
+ RF_CSR_CFG_STRUC rfcsr;
+ UINT i=0, k=0;
+
+ for (i=0; i<MAX_BUSY_COUNT; i++)
+ {
+ RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+ if (rfcsr.field.RF_CSR_KICK == BUSY)
+ {
+ continue;
+ }
+ rfcsr.word = 0;
+ rfcsr.field.RF_CSR_WR = 0;
+ rfcsr.field.RF_CSR_KICK = 1;
+ rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
+ RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
+ for (k=0; k<MAX_BUSY_COUNT; k++)
+ {
+ RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+ if (rfcsr.field.RF_CSR_KICK == IDLE)
+ break;
+ }
+ if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
+ (rfcsr.field.TESTCSR_RFACC_REGNUM == RegID))
+ {
+ *pValue = (UCHAR)rfcsr.field.RF_CSR_DATA;
+ break;
+ }
+ }
+ if (rfcsr.field.RF_CSR_KICK == BUSY)
+ {
+ DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", RegID, rfcsr.word,i,k));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ return STATUS_SUCCESS;
+}
+#endif // RT30xx //
+
+#ifdef RT30xx
+// add by johnli, RF power sequence setup
+/*
+ ==========================================================================
+ Description:
+
+ Load RF normal operation-mode setup
+
+ ==========================================================================
+ */
+VOID RT30xxLoadRFNormalModeSetup(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR RFValue;
+
+ // RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
+ RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+ RFValue = (RFValue & (~0x0C)) | 0x31;
+ RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+ // TX_LO2_en, RF R15 register Bit 3 to 0
+ RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
+ RFValue &= (~0x08);
+ RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
+
+ // TX_LO1_en, RF R17 register Bit 3 to 0
+ RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
+ RFValue &= (~0x08);
+ // to fix rx long range issue
+ if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
+ {
+ RFValue |= 0x20;
+ }
+ RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
+
+ // RX_LO1_en, RF R20 register Bit 3 to 0
+ RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
+ RFValue &= (~0x08);
+ RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
+
+ // RX_LO2_en, RF R21 register Bit 3 to 0
+ RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+ RFValue &= (~0x08);
+ RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+
+ // LDORF_VC, RF R27 register Bit 2 to 0
+ RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+ if ((pAd->MACVersion & 0xffff) < 0x0211)
+ RFValue = (RFValue & (~0x77)) | 0x3;
+ else
+ RFValue = (RFValue & (~0x77));
+ RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+ /* end johnli */
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ Load RF sleep-mode setup
+
+ ==========================================================================
+ */
+VOID RT30xxLoadRFSleepModeSetup(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR RFValue;
+ UINT32 MACValue;
+
+ // RF_BLOCK_en. RF R1 register Bit 0 to 0
+ RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+ RFValue &= (~0x01);
+ RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+ // VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
+ RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+ RFValue &= (~0x30);
+ RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+ // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
+ RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
+ RFValue &= (~0x0E);
+ RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
+
+ // RX_CTB_en, RF R21 register Bit 7 to 0
+ RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+ RFValue &= (~0x80);
+ RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+
+ // LDORF_VC, RF R27 register Bit 0, Bit 1 & Bit 2 to 1
+ RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+ RFValue |= 0x77;
+ RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+
+ RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+ MACValue |= 0x1D000000;
+ RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ Reverse RF sleep-mode setup
+
+ ==========================================================================
+ */
+VOID RT30xxReverseRFSleepModeSetup(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR RFValue;
+ UINT32 MACValue;
+
+ // RF_BLOCK_en, RF R1 register Bit 0 to 1
+ RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+ RFValue |= 0x01;
+ RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+ // VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
+ RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+ RFValue |= 0x30;
+ RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+ // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
+ RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
+ RFValue |= 0x0E;
+ RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
+
+ // RX_CTB_en, RF R21 register Bit 7 to 1
+ RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+ RFValue |= 0x80;
+ RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+
+ // LDORF_VC, RF R27 register Bit 2 to 0
+ RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+ if ((pAd->MACVersion & 0xffff) < 0x0211)
+ RFValue = (RFValue & (~0x77)) | 0x3;
+ else
+ RFValue = (RFValue & (~0x77));
+ RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+
+ // RT3071 version E has fixed this issue
+ if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
+ {
+ // patch tx EVM issue temporarily
+ RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+ MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
+ RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+ }
+ else
+ {
+ RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+ MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
+ RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+ }
+}
+// end johnli
+#endif // RT30xx //
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel,
+ IN BOOLEAN bScan)
+{
+ ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
+ CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
+ UCHAR index;
+ UINT32 Value = 0; //BbpReg, Value;
+ RTMP_RF_REGS *RFRegTable;
+
+ // Search Tx power value
+#if 1
+ // We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
+ // in ChannelList, so use TxPower array instead.
+ //
+ for (index = 0; index < MAX_NUM_OF_CHANNELS; index++)
+ {
+ if (Channel == pAd->TxPower[index].Channel)
+ {
+ TxPwer = pAd->TxPower[index].Power;
+ TxPwer2 = pAd->TxPower[index].Power2;
+ break;
+ }
+ }
+#else
+ for (index = 0; index < pAd->ChannelListNum; index++)
+ {
+ if (Channel == pAd->ChannelList[index].Channel)
+ {
+ TxPwer = pAd->ChannelList[index].Power;
+ TxPwer2 = pAd->ChannelList[index].Power2;
+ break;
+ }
+ }
+#endif
+
+ if (index == MAX_NUM_OF_CHANNELS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
+ }
+
+#ifdef RT30xx
+ // The RF programming sequence is difference between 3xxx and 2xxx
+ if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) ||
+ (pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022)))
+ {
+ /* modify by WY for Read RF Reg. error */
+ UCHAR RFValue;
+
+ for (index = 0; index < NUM_OF_3020_CHNL; index++)
+ {
+ if (Channel == FreqItems3020[index].Channel)
+ {
+ // Programming channel parameters
+ RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
+ RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
+ RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
+ RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
+ RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
+
+ // Set Tx0 Power
+ RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
+ RFValue = (RFValue & 0xE0) | TxPwer;
+ RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
+
+ // Set Tx1 Power
+ RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
+ RFValue = (RFValue & 0xE0) | TxPwer2;
+ RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
+
+ // Tx/Rx Stream setting
+ RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+ //if (IS_RT3090(pAd))
+ // RFValue |= 0x01; // Enable RF block.
+ RFValue &= 0x03; //clear bit[7~2]
+ if (pAd->Antenna.field.TxPath == 1)
+ RFValue |= 0xA0;
+ else if (pAd->Antenna.field.TxPath == 2)
+ RFValue |= 0x80;
+ if (pAd->Antenna.field.RxPath == 1)
+ RFValue |= 0x50;
+ else if (pAd->Antenna.field.RxPath == 2)
+ RFValue |= 0x40;
+ RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+ // Set RF offset
+ RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
+ RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
+ RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
+
+ // Set BW
+ if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
+ {
+ RFValue = pAd->Mlme.CaliBW40RfR24;
+ //DISABLE_11N_CHECK(pAd);
+ }
+ else
+ {
+ RFValue = pAd->Mlme.CaliBW20RfR24;
+ }
+ RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
+ RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
+
+ // Enable RF tuning
+ RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+ RFValue = RFValue | 0x1;
+ RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+ // latch channel for future usage.
+ pAd->LatchRfRegs.Channel = Channel;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
+ Channel,
+ pAd->RfIcType,
+ TxPwer,
+ TxPwer2,
+ pAd->Antenna.field.TxPath,
+ FreqItems3020[index].N,
+ FreqItems3020[index].K,
+ FreqItems3020[index].R));
+
+ break;
+ }
+ }
+ }
+ else
+#endif // RT30xx //
+
+ {
+ RFRegTable = RF2850RegTable;
+
+ switch (pAd->RfIcType)
+ {
+ case RFIC_2820:
+ case RFIC_2850:
+ case RFIC_2720:
+ case RFIC_2750:
+
+ for (index = 0; index < NUM_OF_2850_CHNL; index++)
+ {
+ if (Channel == RFRegTable[index].Channel)
+ {
+ R2 = RFRegTable[index].R2;
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
+ }
+
+ if (pAd->Antenna.field.RxPath == 2)
+ {
+ R2 |= 0x40; // write 1 to off Rxpath.
+ }
+ else if (pAd->Antenna.field.RxPath == 1)
+ {
+ R2 |= 0x20040; // write 1 to off RxPath
+ }
+
+ if (Channel > 14)
+ {
+ // initialize R3, R4
+ R3 = (RFRegTable[index].R3 & 0xffffc1ff);
+ R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
+
+ // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
+ // R3
+ if ((TxPwer >= -7) && (TxPwer < 0))
+ {
+ TxPwer = (7+TxPwer);
+ TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+ R3 |= (TxPwer << 10);
+ DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
+ }
+ else
+ {
+ TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+ R3 |= (TxPwer << 10) | (1 << 9);
+ }
+
+ // R4
+ if ((TxPwer2 >= -7) && (TxPwer2 < 0))
+ {
+ TxPwer2 = (7+TxPwer2);
+ TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+ R4 |= (TxPwer2 << 7);
+ DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
+ }
+ else
+ {
+ TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+ R4 |= (TxPwer2 << 7) | (1 << 6);
+ }
+ }
+ else
+ {
+ R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
+ R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
+ }
+
+ // Based on BBP current mode before changing RF channel.
+ if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
+ {
+ R4 |=0x200000;
+ }
+
+ // Update variables
+ pAd->LatchRfRegs.Channel = Channel;
+ pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
+ pAd->LatchRfRegs.R2 = R2;
+ pAd->LatchRfRegs.R3 = R3;
+ pAd->LatchRfRegs.R4 = R4;
+
+ // Set RF value 1's set R3[bit2] = [0]
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+ RTMPusecDelay(200);
+
+ // Set RF value 2's set R3[bit2] = [1]
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+ RTMPusecDelay(200);
+
+ // Set RF value 3's set R3[bit2] = [0]
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Change BBP setting during siwtch from a->g, g->a
+ if (Channel <= 14)
+ {
+ ULONG TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue.
+ //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+
+ // Rx High power VGA offset for LNA select
+ if (pAd->NicConfig2.field.ExternalLNAForG)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
+ }
+ else
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
+ }
+
+ // 5G band selection PIN, bit1 and bit2 are complement
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+ Value &= (~0x6);
+ Value |= (0x04);
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+ // Turn off unused PA or LNA when only 1T or 1R
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFFFF3;
+ }
+ if (pAd->Antenna.field.RxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFF3FF;
+ }
+
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+ }
+ else
+ {
+ ULONG TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue.
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
+
+ // Rx High power VGA offset for LNA select
+ if (pAd->NicConfig2.field.ExternalLNAForA)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
+ }
+ else
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
+ }
+
+ // 5G band selection PIN, bit1 and bit2 are complement
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+ Value &= (~0x6);
+ Value |= (0x02);
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+ // Turn off unused PA or LNA when only 1T or 1R
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFFFF3;
+ }
+ if (pAd->Antenna.field.RxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFF3FF;
+ }
+
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+ }
+
+ // R66 should be set according to Channel and use 20MHz when scanning
+ //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
+ if (bScan)
+ RTMPSetAGCInitValue(pAd, BW_20);
+ else
+ RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
+
+ //
+ // On 11A, We should delay and wait RF/BBP to be stable
+ // and the appropriate time should be 1000 micro seconds
+ // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
+ //
+ RTMPusecDelay(1000);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
+ Channel,
+ pAd->RfIcType,
+ (R3 & 0x00003e00) >> 9,
+ (R4 & 0x000007c0) >> 6,
+ pAd->Antenna.field.TxPath,
+ pAd->LatchRfRegs.R1,
+ pAd->LatchRfRegs.R2,
+ pAd->LatchRfRegs.R3,
+ pAd->LatchRfRegs.R4));
+}
+
+/*
+ ==========================================================================
+ Description:
+ This function is required for 2421 only, and should not be used during
+ site survey. It's only required after NIC decided to stay at a channel
+ for a longer period.
+ When this function is called, it's always after AsicSwitchChannel().
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicLockChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicAntennaSelect(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+ if (pAd->Mlme.OneSecPeriodicRound % 2 == 1)
+ {
+ // patch for AsicSetRxAnt failed
+ pAd->RxAnt.EvaluatePeriod = 0;
+
+ // check every 2 second. If rcv-beacon less than 5 in the past 2 second, then AvgRSSI is no longer a
+ // valid indication of the distance between this AP and its clients.
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ SHORT realavgrssi1;
+
+ // if no traffic then reset average rssi to trigger evaluation
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->StaCfg.NumOfAvgRssiSample < 5)
+ {
+ pAd->RxAnt.Pair1LastAvgRssi = (-99);
+ pAd->RxAnt.Pair2LastAvgRssi = (-99);
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no traffic/beacon, reset RSSI\n"));
+ }
+
+ pAd->StaCfg.NumOfAvgRssiSample = 0;
+#endif // CONFIG_STA_SUPPORT //
+ realavgrssi1 = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3);
+
+ DBGPRINT(RT_DEBUG_TRACE,("Ant-realrssi0(%d), Lastrssi0(%d), EvaluateStableCnt=%d\n", realavgrssi1, pAd->RxAnt.Pair1LastAvgRssi, pAd->RxAnt.EvaluateStableCnt));
+
+ // if the difference between two rssi is larger or less than 5, then evaluate the other antenna
+ if ((pAd->RxAnt.EvaluateStableCnt < 2) || (realavgrssi1 > (pAd->RxAnt.Pair1LastAvgRssi + 5)) || (realavgrssi1 < (pAd->RxAnt.Pair1LastAvgRssi - 5)))
+ {
+ pAd->RxAnt.Pair1LastAvgRssi = realavgrssi1;
+ AsicEvaluateRxAnt(pAd);
+ }
+ }
+ else
+ {
+ // if not connected, always switch antenna to try to connect
+ UCHAR temp;
+
+ temp = pAd->RxAnt.Pair1PrimaryRxAnt;
+ pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
+ pAd->RxAnt.Pair1SecondaryRxAnt = temp;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no connect, switch to another one to try connection\n"));
+
+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+ }
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Antenna miscellaneous setting.
+
+ Arguments:
+ pAd Pointer to our adapter
+ BandState Indicate current Band State.
+
+ Return Value:
+ None
+
+ IRQL <= DISPATCH_LEVEL
+
+ Note:
+ 1.) Frame End type control
+ only valid for G only (RF_2527 & RF_2529)
+ 0: means DPDT, set BBP R4 bit 5 to 1
+ 1: means SPDT, set BBP R4 bit 5 to 0
+
+
+ ========================================================================
+*/
+VOID AsicAntennaSetting(
+ IN PRTMP_ADAPTER pAd,
+ IN ABGBAND_STATE BandState)
+{
+}
+
+VOID AsicRfTuningExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+}
+
+/*
+ ==========================================================================
+ Description:
+ Gives CCK TX rate 2 more dB TX power.
+ This routine works only in LINK UP in INFRASTRUCTURE mode.
+
+ calculate desired Tx power in RF R3.Tx0~5, should consider -
+ 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
+ 1. TxPowerPercentage
+ 2. auto calibration based on TSSI feedback
+ 3. extra 2 db for CCK
+ 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
+
+ NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
+ it should be called AFTER MlmeDynamicTxRatSwitching()
+ ==========================================================================
+ */
+VOID AsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i, j;
+ CHAR DeltaPwr = 0;
+ BOOLEAN bAutoTxAgc = FALSE;
+ UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
+ UCHAR BbpR1 = 0, BbpR49 = 0, idx;
+ PCHAR pTxAgcCompensate;
+ ULONG TxPwr[5];
+ CHAR Value;
+
+
+
+ if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+ {
+ if (pAd->CommonCfg.CentralChannel > 14)
+ {
+ TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
+ TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
+ TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
+ TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
+ TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
+ }
+ else
+ {
+ TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
+ TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
+ TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
+ TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
+ TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
+ }
+ }
+ else
+ {
+ if (pAd->CommonCfg.Channel > 14)
+ {
+ TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
+ TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
+ TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
+ TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
+ TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
+ }
+ else
+ {
+ TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
+ TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
+ TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
+ TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
+ TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
+ }
+ }
+
+ // TX power compensation for temperature variation based on TSSI. try every 4 second
+ if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
+ {
+ if (pAd->CommonCfg.Channel <= 14)
+ {
+ /* bg channel */
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ TssiRef = pAd->TssiRefG;
+ pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
+ pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
+ TxAgcStep = pAd->TxAgcStepG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ }
+ else
+ {
+ /* a channel */
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ TssiRef = pAd->TssiRefA;
+ pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
+ pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
+ TxAgcStep = pAd->TxAgcStepA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ }
+
+ if (bAutoTxAgc)
+ {
+ /* BbpR1 is unsigned char */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
+
+ /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
+ /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
+ /* step value is defined in pAd->TxAgcStepG for tx power value */
+
+ /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
+ /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
+ above value are examined in mass factory production */
+ /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
+
+ /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
+ /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
+ /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
+
+ if (BbpR49 > pTssiMinusBoundary[1])
+ {
+ // Reading is larger than the reference value
+ // check for how large we need to decrease the Tx power
+ for (idx = 1; idx < 5; idx++)
+ {
+ if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
+ break;
+ }
+ // The index is the step we should decrease, idx = 0 means there is nothing to compensate
+// if (R3 > (ULONG) (TxAgcStep * (idx-1)))
+ *pTxAgcCompensate = -(TxAgcStep * (idx-1));
+// else
+// *pTxAgcCompensate = -((UCHAR)R3);
+
+ DeltaPwr += (*pTxAgcCompensate);
+ DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
+ BbpR49, TssiRef, TxAgcStep, idx-1));
+ }
+ else if (BbpR49 < pTssiPlusBoundary[1])
+ {
+ // Reading is smaller than the reference value
+ // check for how large we need to increase the Tx power
+ for (idx = 1; idx < 5; idx++)
+ {
+ if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
+ break;
+ }
+ // The index is the step we should increase, idx = 0 means there is nothing to compensate
+ *pTxAgcCompensate = TxAgcStep * (idx-1);
+ DeltaPwr += (*pTxAgcCompensate);
+ DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+ BbpR49, TssiRef, TxAgcStep, idx-1));
+ }
+ else
+ {
+ *pTxAgcCompensate = 0;
+ DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+ BbpR49, TssiRef, TxAgcStep, 0));
+ }
+ }
+ }
+ else
+ {
+ if (pAd->CommonCfg.Channel <= 14)
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ }
+ else
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ }
+
+ if (bAutoTxAgc)
+ DeltaPwr += (*pTxAgcCompensate);
+ }
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
+ BbpR1 &= 0xFC;
+
+#ifdef SINGLE_SKU
+ // Handle regulatory max tx power constrain
+ do
+ {
+ UCHAR TxPwrInEEPROM = 0xFF, CountryTxPwr = 0xFF, criterion;
+ UCHAR AdjustMaxTxPwr[40];
+
+ if (pAd->CommonCfg.Channel > 14) // 5G band
+ TxPwrInEEPROM = ((pAd->CommonCfg.DefineMaxTxPwr & 0xFF00) >> 8);
+ else // 2.4G band
+ TxPwrInEEPROM = (pAd->CommonCfg.DefineMaxTxPwr & 0x00FF);
+ CountryTxPwr = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
+
+ // error handling, range check
+ if ((TxPwrInEEPROM > 0x50) || (CountryTxPwr > 0x50))
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("AsicAdjustTxPower - Invalid max tx power (=0x%02x), CountryTxPwr=%d\n", TxPwrInEEPROM, CountryTxPwr));
+ break;
+ }
+
+ criterion = *((PUCHAR)TxPwr + 2) & 0xF; // FAE use OFDM 6M as criterion
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (criterion=%d, TxPwrInEEPROM=%d, CountryTxPwr=%d)\n", criterion, TxPwrInEEPROM, CountryTxPwr));
+
+ // Adjust max tx power according to the relationship of tx power in E2PROM
+ for (i=0; i<5; i++)
+ {
+ // CCK will have 4dBm larger than OFDM
+ // Therefore, we should separate to parse the tx power field
+ if (i == 0)
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
+
+ if (j < 4)
+ {
+ // CCK will have 4dBm larger than OFDM
+ AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion) + 4;
+ }
+ else
+ {
+ AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
+ }
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
+ }
+ }
+ else
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
+
+ AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
+ }
+ }
+ }
+
+ // Adjust tx power according to the relationship
+ for (i=0; i<5; i++)
+ {
+ if (TxPwr[i] != 0xffffffff)
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
+
+ // The system tx power is larger than the regulatory, the power should be restrain
+ if (AdjustMaxTxPwr[i*8+j] > CountryTxPwr)
+ {
+ // decrease to zero and don't need to take care BBPR1
+ if ((Value - (AdjustMaxTxPwr[i*8+j] - CountryTxPwr)) > 0)
+ Value -= (AdjustMaxTxPwr[i*8+j] - CountryTxPwr);
+ else
+ Value = 0;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
+ }
+ else
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d, no change)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
+
+ TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
+ }
+ }
+ }
+ } while (FALSE);
+#endif // SINGLE_SKU //
+
+ /* calculate delta power based on the percentage specified from UI */
+ // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
+ // We lower TX power here according to the percentage specified from UI
+ if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
+ ;
+ else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
+ ;
+ else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1;
+ {
+ DeltaPwr -= 1;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3;
+ {
+ DeltaPwr -= 3;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6;
+ {
+ BbpR1 |= 0x01;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9;
+ {
+ BbpR1 |= 0x01;
+ DeltaPwr -= 3;
+ }
+ else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12;
+ {
+ BbpR1 |= 0x02;
+ }
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
+
+ /* reset different new tx power for different TX rate */
+ for(i=0; i<5; i++)
+ {
+ if (TxPwr[i] != 0xffffffff)
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
+
+ if ((Value + DeltaPwr) < 0)
+ {
+ Value = 0; /* min */
+ }
+ else if ((Value + DeltaPwr) > 0xF)
+ {
+ Value = 0xF; /* max */
+ }
+ else
+ {
+ Value += DeltaPwr; /* temperature compensation */
+ }
+
+ /* fill new value to CSR offset */
+ TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
+ }
+
+ /* write tx power value to CSR */
+ /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
+ TX power for OFDM 6M/9M
+ TX power for CCK5.5M/11M
+ TX power for CCK1M/2M */
+ /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
+ }
+ }
+
+
+}
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
+ automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
+ the wakeup timer timeout. Driver has to issue a separate command to wake
+ PHY up.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSleepThenAutoWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT TbttNumToNextWakeUp)
+{
+ RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
+}
+
+/*
+ ==========================================================================
+ Description:
+ AsicForceWakeup() is used whenever manual wakeup is required
+ AsicForceSleep() should only be used when not in INFRA BSS. When
+ in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
+ ==========================================================================
+ */
+VOID AsicForceSleep(
+ IN PRTMP_ADAPTER pAd)
+{
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
+ expired.
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+ ==========================================================================
+ */
+VOID AsicForceWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bFromTx)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
+ RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
+}
+#endif // CONFIG_STA_SUPPORT //
+/*
+ ==========================================================================
+ Description:
+ Set My BSSID
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSetBssid(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pBssid)
+{
+ ULONG Addr4;
+ DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
+ pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
+
+ Addr4 = (ULONG)(pBssid[0]) |
+ (ULONG)(pBssid[1] << 8) |
+ (ULONG)(pBssid[2] << 16) |
+ (ULONG)(pBssid[3] << 24);
+ RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
+
+ Addr4 = 0;
+ // always one BSSID in STA mode
+ Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
+
+ RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
+}
+
+VOID AsicSetMcastWC(
+ IN PRTMP_ADAPTER pAd)
+{
+ MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
+ USHORT offset;
+
+ pEntry->Sst = SST_ASSOC;
+ pEntry->Aid = MCAST_WCID; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
+ pEntry->PsMode = PWR_ACTIVE;
+ pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
+ offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicDelWcidTab(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid)
+{
+ ULONG Addr0 = 0x0, Addr1 = 0x0;
+ ULONG offset;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
+ offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
+ RTMP_IO_WRITE32(pAd, offset, Addr0);
+ offset += 4;
+ RTMP_IO_WRITE32(pAd, offset, Addr1);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicEnableRDG(
+ IN PRTMP_ADAPTER pAd)
+{
+ TX_LINK_CFG_STRUC TxLinkCfg;
+ UINT32 Data = 0;
+
+ RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+ TxLinkCfg.field.TxRDGEn = 1;
+ RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+ Data &= 0xFFFFFF00;
+ Data |= 0x80;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+ //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicDisableRDG(
+ IN PRTMP_ADAPTER pAd)
+{
+ TX_LINK_CFG_STRUC TxLinkCfg;
+ UINT32 Data = 0;
+
+
+ RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+ TxLinkCfg.field.TxRDGEn = 0;
+ RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+
+ Data &= 0xFFFFFF00;
+ //Data |= 0x20;
+#ifndef WIFI_TEST
+ //if ( pAd->CommonCfg.bEnableTxBurst )
+ // Data |= 0x60; // for performance issue not set the TXOP to 0
+#endif
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
+#ifdef DOT11_N_SUPPORT
+ && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
+ if (pAd->CommonCfg.bEnableTxBurst)
+ Data |= 0x20;
+ }
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicDisableSync(
+ IN PRTMP_ADAPTER pAd)
+{
+ BCN_TIME_CFG_STRUC csr;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
+
+ // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
+ // that NIC will never wakes up because TSF stops and no more
+ // TBTT interrupts
+ pAd->TbttTickCount = 0;
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+ csr.field.bBeaconGen = 0;
+ csr.field.bTBTTEnable = 0;
+ csr.field.TsfSyncMode = 0;
+ csr.field.bTsfTicking = 0;
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicEnableBssSync(
+ IN PRTMP_ADAPTER pAd)
+{
+ BCN_TIME_CFG_STRUC csr;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
+
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+// RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000);
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
+ csr.field.bTsfTicking = 1;
+ csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
+ csr.field.bBeaconGen = 0; // do NOT generate BEACON
+ csr.field.bTBTTEnable = 1;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Note:
+ BEACON frame in shared memory should be built ok before this routine
+ can be called. Otherwise, a garbage frame maybe transmitted out every
+ Beacon period.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicEnableIbssSync(
+ IN PRTMP_ADAPTER pAd)
+{
+ BCN_TIME_CFG_STRUC csr9;
+ PUCHAR ptr;
+ UINT i;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
+
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
+ csr9.field.bBeaconGen = 0;
+ csr9.field.bTBTTEnable = 0;
+ csr9.field.bTsfTicking = 0;
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+
+
+#ifdef RT2870
+ // move BEACON TXD and frame content to on-chip memory
+ ptr = (PUCHAR)&pAd->BeaconTxWI;
+ for (i=0; i<TXWI_SIZE; i+=2) // 16-byte TXWI field
+ {
+ //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+ //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
+ RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
+ ptr += 2;
+ }
+
+ // start right after the 16-byte TXWI field
+ ptr = pAd->BeaconBuf;
+ for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
+ {
+ //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+ //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
+ RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
+ ptr +=2;
+ }
+#endif // RT2870 //
+
+ //
+ // For Wi-Fi faily generated beacons between participating stations.
+ // Set TBTT phase adaptive adjustment step to 8us (default 16us)
+ // don't change settings 2006-5- by Jerry
+ //RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010);
+
+ // start sending BEACON
+ csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
+ csr9.field.bTsfTicking = 1;
+ csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
+ csr9.field.bTBTTEnable = 1;
+ csr9.field.bBeaconGen = 1;
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSetEdcaParm(
+ IN PRTMP_ADAPTER pAd,
+ IN PEDCA_PARM pEdcaParm)
+{
+ EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
+ AC_TXOP_CSR0_STRUC csr0;
+ AC_TXOP_CSR1_STRUC csr1;
+ AIFSN_CSR_STRUC AifsnCsr;
+ CWMIN_CSR_STRUC CwminCsr;
+ CWMAX_CSR_STRUC CwmaxCsr;
+ int i;
+
+ Ac0Cfg.word = 0;
+ Ac1Cfg.word = 0;
+ Ac2Cfg.word = 0;
+ Ac3Cfg.word = 0;
+ if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
+ CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
+ }
+
+ //========================================================
+ // MAC Register has a copy .
+ //========================================================
+//#ifndef WIFI_TEST
+ if( pAd->CommonCfg.bEnableTxBurst )
+ {
+ // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
+ Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
+ }
+ else
+ Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
+//#else
+// Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
+//#endif
+ Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
+ Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
+ Ac0Cfg.field.Aifsn = 2;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
+
+ Ac1Cfg.field.AcTxop = 0; // QID_AC_BK
+ Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
+ Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
+ Ac1Cfg.field.Aifsn = 2;
+ RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
+
+ if (pAd->CommonCfg.PhyMode == PHY_11B)
+ {
+ Ac2Cfg.field.AcTxop = 192; // AC_VI: 192*32us ~= 6ms
+ Ac3Cfg.field.AcTxop = 96; // AC_VO: 96*32us ~= 3ms
+ }
+ else
+ {
+ Ac2Cfg.field.AcTxop = 96; // AC_VI: 96*32us ~= 3ms
+ Ac3Cfg.field.AcTxop = 48; // AC_VO: 48*32us ~= 1.5ms
+ }
+ Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
+ Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
+ Ac2Cfg.field.Aifsn = 2;
+ RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
+ Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
+ Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
+ Ac3Cfg.field.Aifsn = 2;
+ RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
+
+ //========================================================
+ // DMA Register has a copy too.
+ //========================================================
+ csr0.field.Ac0Txop = 0; // QID_AC_BE
+ csr0.field.Ac1Txop = 0; // QID_AC_BK
+ RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+ if (pAd->CommonCfg.PhyMode == PHY_11B)
+ {
+ csr1.field.Ac2Txop = 192; // AC_VI: 192*32us ~= 6ms
+ csr1.field.Ac3Txop = 96; // AC_VO: 96*32us ~= 3ms
+ }
+ else
+ {
+ csr1.field.Ac2Txop = 96; // AC_VI: 96*32us ~= 3ms
+ csr1.field.Ac3Txop = 48; // AC_VO: 48*32us ~= 1.5ms
+ }
+ RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
+
+ CwminCsr.word = 0;
+ CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
+ CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
+ CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
+ CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
+ RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+
+ CwmaxCsr.word = 0;
+ CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
+ CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
+ CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
+ CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
+ RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+
+ RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
+
+ NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
+ }
+ else
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
+ //========================================================
+ // MAC Register has a copy.
+ //========================================================
+ //
+ // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
+ // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
+ //
+ //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
+
+ Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
+ Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
+ Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
+ Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
+
+ Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
+ Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
+ Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
+ Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
+
+ Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
+ Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
+ Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
+ Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI];
+#ifdef INF_AMAZON_SE
+#endif // INF_AMAZON_SE //
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Tuning for Wi-Fi WMM S06
+ if (pAd->CommonCfg.bWiFiTest &&
+ pEdcaParm->Aifsn[QID_AC_VI] == 10)
+ Ac2Cfg.field.Aifsn -= 1;
+
+ // Tuning for TGn Wi-Fi 5.2.32
+ // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
+ if (STA_TGN_WIFI_ON(pAd) &&
+ pEdcaParm->Aifsn[QID_AC_VI] == 10)
+ {
+ Ac0Cfg.field.Aifsn = 3;
+ Ac2Cfg.field.AcTxop = 5;
+ }
+
+#ifdef RT30xx
+ if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
+ {
+ // Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
+ Ac2Cfg.field.Aifsn = 5;
+ }
+#endif // RT30xx //
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
+ Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
+ Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
+ Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
+
+//#ifdef WIFI_TEST
+ if (pAd->CommonCfg.bWiFiTest)
+ {
+ if (Ac3Cfg.field.AcTxop == 102)
+ {
+ Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
+ Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
+ Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
+ Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];
+ Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
+ } /* End of if */
+ }
+//#endif // WIFI_TEST //
+
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
+ RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
+ RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
+ RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
+
+
+ //========================================================
+ // DMA Register has a copy too.
+ //========================================================
+ csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
+ csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
+ RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+
+ csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
+ csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
+ RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
+
+ CwminCsr.word = 0;
+ CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
+ CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
+ CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
+#endif // CONFIG_STA_SUPPORT //
+ RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+
+ CwmaxCsr.word = 0;
+ CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
+ CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
+ CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
+ CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
+ RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+
+ AifsnCsr.word = 0;
+ AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
+ AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
+ AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
+#ifdef INF_AMAZON_SE
+#endif // INF_AMAZON_SE //
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Tuning for Wi-Fi WMM S06
+ if (pAd->CommonCfg.bWiFiTest &&
+ pEdcaParm->Aifsn[QID_AC_VI] == 10)
+ AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
+
+ // Tuning for TGn Wi-Fi 5.2.32
+ // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
+ if (STA_TGN_WIFI_ON(pAd) &&
+ pEdcaParm->Aifsn[QID_AC_VI] == 10)
+ {
+ AifsnCsr.field.Aifsn0 = 3;
+ AifsnCsr.field.Aifsn2 = 7;
+ }
+
+ if (INFRA_ON(pAd))
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
+#ifdef RT30xx
+ if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
+ {
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
+ }
+#endif // RT30xx //
+#endif // CONFIG_STA_SUPPORT //
+ RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
+
+ NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+ if (!ADHOC_ON(pAd))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount));
+ DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n",
+ pEdcaParm->Aifsn[0],
+ pEdcaParm->Cwmin[0],
+ pEdcaParm->Cwmax[0],
+ pEdcaParm->Txop[0]<<5,
+ pEdcaParm->bACM[0]));
+ DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n",
+ pEdcaParm->Aifsn[1],
+ pEdcaParm->Cwmin[1],
+ pEdcaParm->Cwmax[1],
+ pEdcaParm->Txop[1]<<5,
+ pEdcaParm->bACM[1]));
+ DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n",
+ pEdcaParm->Aifsn[2],
+ pEdcaParm->Cwmin[2],
+ pEdcaParm->Cwmax[2],
+ pEdcaParm->Txop[2]<<5,
+ pEdcaParm->bACM[2]));
+ DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n",
+ pEdcaParm->Aifsn[3],
+ pEdcaParm->Cwmin[3],
+ pEdcaParm->Cwmax[3],
+ pEdcaParm->Txop[3]<<5,
+ pEdcaParm->bACM[3]));
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSetSlotTime(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bUseShortSlotTime)
+{
+ ULONG SlotTime;
+ UINT32 RegValue = 0;
+
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->CommonCfg.Channel > 14)
+ bUseShortSlotTime = TRUE;
+#endif // CONFIG_STA_SUPPORT //
+
+ if (bUseShortSlotTime)
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+ else
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+
+ SlotTime = (bUseShortSlotTime)? 9 : 20;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // force using short SLOT time for FAE to demo performance when TxBurst is ON
+ if (pAd->CommonCfg.bEnableTxBurst)
+ SlotTime = 9;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ //
+ // For some reasons, always set it to short slot time.
+ //
+ // ToDo: Should consider capability with 11B
+ //
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pAd->StaCfg.BssType == BSS_ADHOC)
+ SlotTime = 20;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
+ RegValue = RegValue & 0xFFFFFF00;
+
+ RegValue |= SlotTime;
+
+ RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
+}
+
+/*
+ ========================================================================
+ Description:
+ Add Shared key information into ASIC.
+ Update shared key, TxMic and RxMic to Asic Shared key table
+ Update its cipherAlg to Asic Shared key Mode.
+
+ Return:
+ ========================================================================
+*/
+VOID AsicAddSharedKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx,
+ IN UCHAR CipherAlg,
+ IN PUCHAR pKey,
+ IN PUCHAR pTxMic,
+ IN PUCHAR pRxMic)
+{
+ ULONG offset; //, csr0;
+ SHAREDKEY_MODE_STRUC csr1;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
+//============================================================================================
+
+ DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
+ DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
+ if (pRxMic)
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+ }
+ if (pTxMic)
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+ }
+//============================================================================================
+ //
+ // fill key material - key + TX MIC + RX MIC
+ //
+
+#ifdef RT2870
+{
+ offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
+ RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
+
+ offset += MAX_LEN_OF_SHARE_KEY;
+ if (pTxMic)
+ {
+ RTUSBMultiWrite(pAd, offset, pTxMic, 8);
+ }
+
+ offset += 8;
+ if (pRxMic)
+ {
+ RTUSBMultiWrite(pAd, offset, pRxMic, 8);
+ }
+}
+#endif // RT2870 //
+
+ //
+ // Update cipher algorithm. WSTA always use BSS0
+ //
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
+ DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
+ if ((BssIndex%2) == 0)
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss0Key0CipherAlg = CipherAlg;
+ else if (KeyIdx == 1)
+ csr1.field.Bss0Key1CipherAlg = CipherAlg;
+ else if (KeyIdx == 2)
+ csr1.field.Bss0Key2CipherAlg = CipherAlg;
+ else
+ csr1.field.Bss0Key3CipherAlg = CipherAlg;
+ }
+ else
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss1Key0CipherAlg = CipherAlg;
+ else if (KeyIdx == 1)
+ csr1.field.Bss1Key1CipherAlg = CipherAlg;
+ else if (KeyIdx == 2)
+ csr1.field.Bss1Key2CipherAlg = CipherAlg;
+ else
+ csr1.field.Bss1Key3CipherAlg = CipherAlg;
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
+
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID AsicRemoveSharedKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx)
+{
+ //ULONG SecCsr0;
+ SHAREDKEY_MODE_STRUC csr1;
+
+ DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
+
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
+ if ((BssIndex%2) == 0)
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss0Key0CipherAlg = 0;
+ else if (KeyIdx == 1)
+ csr1.field.Bss0Key1CipherAlg = 0;
+ else if (KeyIdx == 2)
+ csr1.field.Bss0Key2CipherAlg = 0;
+ else
+ csr1.field.Bss0Key3CipherAlg = 0;
+ }
+ else
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss1Key0CipherAlg = 0;
+ else if (KeyIdx == 1)
+ csr1.field.Bss1Key1CipherAlg = 0;
+ else if (KeyIdx == 2)
+ csr1.field.Bss1Key2CipherAlg = 0;
+ else
+ csr1.field.Bss1Key3CipherAlg = 0;
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
+ ASSERT(BssIndex < 4);
+ ASSERT(KeyIdx < 4);
+
+}
+
+
+VOID AsicUpdateWCIDAttribute(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN UCHAR BssIndex,
+ IN UCHAR CipherAlg,
+ IN BOOLEAN bUsePairewiseKeyTable)
+{
+ ULONG WCIDAttri = 0, offset;
+
+ //
+ // Update WCID attribute.
+ // Only TxKey could update WCID attribute.
+ //
+ offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
+ WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
+ RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
+}
+
+VOID AsicUpdateWCIDIVEIV(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN ULONG uIV,
+ IN ULONG uEIV)
+{
+ ULONG offset;
+
+ offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
+
+ RTMP_IO_WRITE32(pAd, offset, uIV);
+ RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
+}
+
+VOID AsicUpdateRxWCIDTable(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN PUCHAR pAddr)
+{
+ ULONG offset;
+ ULONG Addr;
+
+ offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
+ Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
+ RTMP_IO_WRITE32(pAd, offset, Addr);
+ Addr = pAddr[4] + (pAddr[5] << 8);
+ RTMP_IO_WRITE32(pAd, offset + 4, Addr);
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set Cipher Key, Cipher algorithm, IV/EIV to Asic
+
+ Arguments:
+ pAd Pointer to our adapter
+ WCID WCID Entry number.
+ BssIndex BSSID index, station or none multiple BSSID support
+ this value should be 0.
+ KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
+ pCipherKey Pointer to Cipher Key.
+ bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
+ otherwise PairewiseKey table
+ bTxKey This is the transmit key if enabled.
+
+ Return Value:
+ None
+
+ Note:
+ This routine will set the relative key stuff to Asic including WCID attribute,
+ Cipher Key, Cipher algorithm and IV/EIV.
+
+ IV/EIV will be update if this CipherKey is the transmission key because
+ ASIC will base on IV's KeyID value to select Cipher Key.
+
+ If bTxKey sets to FALSE, this is not the TX key, but it could be
+ RX key
+
+ For AP mode bTxKey must be always set to TRUE.
+ ========================================================================
+*/
+VOID AsicAddKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx,
+ IN PCIPHER_KEY pCipherKey,
+ IN BOOLEAN bUsePairewiseKeyTable,
+ IN BOOLEAN bTxKey)
+{
+ ULONG offset;
+// ULONG WCIDAttri = 0;
+ UCHAR IV4 = 0;
+ PUCHAR pKey = pCipherKey->Key;
+// ULONG KeyLen = pCipherKey->KeyLen;
+ PUCHAR pTxMic = pCipherKey->TxMic;
+ PUCHAR pRxMic = pCipherKey->RxMic;
+ PUCHAR pTxtsc = pCipherKey->TxTsc;
+ UCHAR CipherAlg = pCipherKey->CipherAlg;
+ SHAREDKEY_MODE_STRUC csr1;
+
+// ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
+ //
+ // 1.) decide key table offset
+ //
+ if (bUsePairewiseKeyTable)
+ offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
+ else
+ offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
+
+ //
+ // 2.) Set Key to Asic
+ //
+ //for (i = 0; i < KeyLen; i++)
+
+#ifdef RT2870
+ RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
+ offset += MAX_LEN_OF_PEER_KEY;
+
+ //
+ // 3.) Set MIC key if available
+ //
+ if (pTxMic)
+ {
+ RTUSBMultiWrite(pAd, offset, pTxMic, 8);
+ }
+ offset += LEN_TKIP_TXMICK;
+
+ if (pRxMic)
+ {
+ RTUSBMultiWrite(pAd, offset, pRxMic, 8);
+ }
+#endif // RT2870 //
+
+ //
+ // 4.) Modify IV/EIV if needs
+ // This will force Asic to use this key ID by setting IV.
+ //
+ if (bTxKey)
+ {
+
+#ifdef RT2870
+ UINT32 tmpVal;
+
+ //
+ // Write IV
+ //
+ IV4 = (KeyIdx << 6);
+ if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
+ IV4 |= 0x20; // turn on extension bit means EIV existence
+
+ tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24);
+ RTMP_IO_WRITE32(pAd, offset, tmpVal);
+
+ //
+ // Write EIV
+ //
+ offset += 4;
+ RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]);
+#endif // RT2870 //
+ AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
+ }
+
+ if (!bUsePairewiseKeyTable)
+ {
+ //
+ // Only update the shared key security mode
+ //
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
+ if ((BssIndex % 2) == 0)
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss0Key0CipherAlg = CipherAlg;
+ else if (KeyIdx == 1)
+ csr1.field.Bss0Key1CipherAlg = CipherAlg;
+ else if (KeyIdx == 2)
+ csr1.field.Bss0Key2CipherAlg = CipherAlg;
+ else
+ csr1.field.Bss0Key3CipherAlg = CipherAlg;
+ }
+ else
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss1Key0CipherAlg = CipherAlg;
+ else if (KeyIdx == 1)
+ csr1.field.Bss1Key1CipherAlg = CipherAlg;
+ else if (KeyIdx == 2)
+ csr1.field.Bss1Key2CipherAlg = CipherAlg;
+ else
+ csr1.field.Bss1Key3CipherAlg = CipherAlg;
+ }
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
+}
+
+
+/*
+ ========================================================================
+ Description:
+ Add Pair-wise key material into ASIC.
+ Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
+
+ Return:
+ ========================================================================
+*/
+VOID AsicAddPairwiseKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR WCID,
+ IN CIPHER_KEY *pCipherKey)
+{
+ INT i;
+ ULONG offset;
+ PUCHAR pKey = pCipherKey->Key;
+ PUCHAR pTxMic = pCipherKey->TxMic;
+ PUCHAR pRxMic = pCipherKey->RxMic;
+#ifdef DBG
+ UCHAR CipherAlg = pCipherKey->CipherAlg;
+#endif // DBG //
+
+ // EKEY
+ offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
+#ifdef RT2870
+ RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
+#endif // RT2870 //
+ for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
+ {
+ UINT32 Value;
+ RTMP_IO_READ32(pAd, offset + i, &Value);
+ }
+
+ offset += MAX_LEN_OF_PEER_KEY;
+
+ // MIC KEY
+ if (pTxMic)
+ {
+#ifdef RT2870
+ RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
+#endif // RT2870 //
+ }
+ offset += 8;
+ if (pRxMic)
+ {
+#ifdef RT2870
+ RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
+#endif // RT2870 //
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
+ DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
+ if (pRxMic)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+ }
+ if (pTxMic)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+ }
+}
+/*
+ ========================================================================
+ Description:
+ Remove Pair-wise key material from ASIC.
+
+ Return:
+ ========================================================================
+*/
+VOID AsicRemovePairwiseKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIdx,
+ IN UCHAR Wcid)
+{
+ ULONG WCIDAttri;
+ USHORT offset;
+
+ // re-set the entry's WCID attribute as OPEN-NONE.
+ offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
+ WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
+ RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
+}
+
+BOOLEAN AsicSendCommandToMcu(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Command,
+ IN UCHAR Token,
+ IN UCHAR Arg0,
+ IN UCHAR Arg1)
+{
+ HOST_CMD_CSR_STRUC H2MCmd;
+ H2M_MAILBOX_STRUC H2MMailbox;
+ ULONG i = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
+ if (H2MMailbox.field.Owner == 0)
+ break;
+
+ RTMPusecDelay(2);
+ } while(i++ < 100);
+
+ if (i >= 100)
+ {
+ {
+ DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
+ }
+ return FALSE;
+ }
+
+
+ H2MMailbox.field.Owner = 1; // pass ownership to MCU
+ H2MMailbox.field.CmdToken = Token;
+ H2MMailbox.field.HighByte = Arg1;
+ H2MMailbox.field.LowByte = Arg0;
+ RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
+
+ H2MCmd.word = 0;
+ H2MCmd.field.HostCommand = Command;
+ RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
+
+ if (Command != 0x80)
+ {
+ }
+
+ return TRUE;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Verify the support rate for different PHY type
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ ========================================================================
+*/
+VOID RTMPCheckRates(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT UCHAR SupRate[],
+ IN OUT UCHAR *SupRateLen)
+{
+ UCHAR RateIdx, i, j;
+ UCHAR NewRate[12], NewRateLen;
+
+ NewRateLen = 0;
+
+ if (pAd->CommonCfg.PhyMode == PHY_11B)
+ RateIdx = 4;
+ else
+ RateIdx = 12;
+
+ // Check for support rates exclude basic rate bit
+ for (i = 0; i < *SupRateLen; i++)
+ for (j = 0; j < RateIdx; j++)
+ if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
+ NewRate[NewRateLen++] = SupRate[i];
+
+ *SupRateLen = NewRateLen;
+ NdisMoveMemory(SupRate, NewRate, NewRateLen);
+}
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef DOT11_N_SUPPORT
+BOOLEAN RTMPCheckChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR CentralChannel,
+ IN UCHAR Channel)
+{
+ UCHAR k;
+ UCHAR UpperChannel = 0, LowerChannel = 0;
+ UCHAR NoEffectChannelinList = 0;
+
+ // Find upper and lower channel according to 40MHz current operation.
+ if (CentralChannel < Channel)
+ {
+ UpperChannel = Channel;
+ if (CentralChannel > 2)
+ LowerChannel = CentralChannel - 2;
+ else
+ return FALSE;
+ }
+ else if (CentralChannel > Channel)
+ {
+ UpperChannel = CentralChannel + 2;
+ LowerChannel = Channel;
+ }
+
+ for (k = 0;k < pAd->ChannelListNum;k++)
+ {
+ if (pAd->ChannelList[k].Channel == UpperChannel)
+ {
+ NoEffectChannelinList ++;
+ }
+ if (pAd->ChannelList[k].Channel == LowerChannel)
+ {
+ NoEffectChannelinList ++;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList));
+ if (NoEffectChannelinList == 2)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Verify the support rate for HT phy type
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability. (AP Mode)
+
+ IRQL = PASSIVE_LEVEL
+
+ ========================================================================
+*/
+BOOLEAN RTMPCheckHt(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN ADD_HT_INFO_IE *pAddHtInfo)
+{
+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return FALSE;
+
+ // If use AMSDU, set flag.
+ if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable)
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_AMSDU_INUSED);
+ // Save Peer Capability
+ if (pHtCapability->HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI20_CAPABLE);
+ if (pHtCapability->HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI40_CAPABLE);
+ if (pHtCapability->HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (pHtCapability->HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
+ {
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RDG_CAPABLE);
+ }
+
+ if (Wcid < MAX_LEN_OF_MAC_TABLE)
+ {
+ pAd->MacTab.Content[Wcid].MpduDensity = pHtCapability->HtCapParm.MpduDensity;
+ }
+
+ // Will check ChannelWidth for MCSSet[4] below
+ pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1;
+ switch (pAd->CommonCfg.RxStream)
+ {
+ case 1:
+ pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+ pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
+ pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
+ pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+ break;
+ case 2:
+ pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+ pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
+ pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
+ pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+ break;
+ case 3:
+ pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+ pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
+ pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
+ pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+ break;
+ }
+
+ pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.ChannelWidth;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
+ pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth, pAddHtInfo->AddHtInfo.RecomWidth, pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
+ pAd->NicConfig2.field.BW40MAvailForA, pAd->NicConfig2.field.BW40MAvailForG, pAd->CommonCfg.PhyMode));
+
+ pAd->MlmeAux.HtCapability.HtCapInfo.GF = pHtCapability->HtCapInfo.GF &pAd->CommonCfg.DesiredHtPhy.GF;
+
+ // Send Assoc Req with my HT capability.
+ pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize = pAd->CommonCfg.DesiredHtPhy.AmsduSize;
+ pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs = pAd->CommonCfg.DesiredHtPhy.MimoPs;
+ pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20);
+ pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40);
+ pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC = (pAd->CommonCfg.DesiredHtPhy.TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC);
+ pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC = (pAd->CommonCfg.DesiredHtPhy.RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC);
+ pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
+ pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
+ pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
+ pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
+ if (pAd->CommonCfg.bRdg)
+ {
+ pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport = pHtCapability->ExtHtCapInfo.RDGSupport;
+ pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
+ }
+
+ if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
+ pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0; // BW20 can't transmit MCS32
+
+ COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability);
+ return TRUE;
+}
+#endif // DOT11_N_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Verify the support rate for different PHY type
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ ========================================================================
+*/
+VOID RTMPUpdateMlmeRate(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR MinimumRate;
+ UCHAR ProperMlmeRate; //= RATE_54;
+ UCHAR i, j, RateIdx = 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
+ BOOLEAN bMatch = FALSE;
+
+ switch (pAd->CommonCfg.PhyMode)
+ {
+ case PHY_11B:
+ ProperMlmeRate = RATE_11;
+ MinimumRate = RATE_1;
+ break;
+ case PHY_11BG_MIXED:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11ABGN_MIXED:
+ case PHY_11BGN_MIXED:
+#endif // DOT11_N_SUPPORT //
+ if ((pAd->MlmeAux.SupRateLen == 4) &&
+ (pAd->MlmeAux.ExtRateLen == 0))
+ // B only AP
+ ProperMlmeRate = RATE_11;
+ else
+ ProperMlmeRate = RATE_24;
+
+ if (pAd->MlmeAux.Channel <= 14)
+ MinimumRate = RATE_1;
+ else
+ MinimumRate = RATE_6;
+ break;
+ case PHY_11A:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11N_2_4G: // rt2860 need to check mlmerate for 802.11n
+ case PHY_11GN_MIXED:
+ case PHY_11AGN_MIXED:
+ case PHY_11AN_MIXED:
+ case PHY_11N_5G:
+#endif // DOT11_N_SUPPORT //
+ ProperMlmeRate = RATE_24;
+ MinimumRate = RATE_6;
+ break;
+ case PHY_11ABG_MIXED:
+ ProperMlmeRate = RATE_24;
+ if (pAd->MlmeAux.Channel <= 14)
+ MinimumRate = RATE_1;
+ else
+ MinimumRate = RATE_6;
+ break;
+ default: // error
+ ProperMlmeRate = RATE_1;
+ MinimumRate = RATE_1;
+ break;
+ }
+
+ for (i = 0; i < pAd->MlmeAux.SupRateLen; i++)
+ {
+ for (j = 0; j < RateIdx; j++)
+ {
+ if ((pAd->MlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
+ {
+ if (j == ProperMlmeRate)
+ {
+ bMatch = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (bMatch)
+ break;
+ }
+
+ if (bMatch == FALSE)
+ {
+ for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++)
+ {
+ for (j = 0; j < RateIdx; j++)
+ {
+ if ((pAd->MlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j])
+ {
+ if (j == ProperMlmeRate)
+ {
+ bMatch = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (bMatch)
+ break;
+ }
+ }
+
+ if (bMatch == FALSE)
+ {
+ ProperMlmeRate = MinimumRate;
+ }
+
+ pAd->CommonCfg.MlmeRate = MinimumRate;
+ pAd->CommonCfg.RtsRate = ProperMlmeRate;
+ if (pAd->CommonCfg.MlmeRate >= RATE_6)
+ {
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
+ pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ }
+ else
+ {
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
+ pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_CCK;
+ pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = pAd->CommonCfg.MlmeRate;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateMlmeRate ==> MlmeTransmit = 0x%x \n" , pAd->CommonCfg.MlmeTransmit.word));
+}
+
+CHAR RTMPMaxRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi0,
+ IN CHAR Rssi1,
+ IN CHAR Rssi2)
+{
+ CHAR larger = -127;
+
+ if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0))
+ {
+ larger = Rssi0;
+ }
+
+ if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0))
+ {
+ larger = max(Rssi0, Rssi1);
+ }
+
+ if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0))
+ {
+ larger = max(larger, Rssi2);
+ }
+
+ if (larger == -127)
+ larger = 0;
+
+ return larger;
+}
+
+
+// Antenna divesity use GPIO3 and EESK pin for control
+// Antenna and EEPROM access are both using EESK pin,
+// Therefor we should avoid accessing EESK at the same time
+// Then restore antenna after EEPROM access
+VOID AsicSetRxAnt(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Ant)
+{
+#ifdef RT30xx
+ UINT32 Value;
+ UINT32 x;
+
+ if ((pAd->EepromAccess) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ return;
+ }
+
+ // the antenna selection is through firmware and MAC register(GPIO3)
+ if (Ant == 0)
+ {
+ // Main antenna
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x |= (EESK);
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
+ Value &= ~(0x0808);
+ RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
+ }
+ else
+ {
+ // Aux antenna
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x &= ~(EESK);
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
+ Value &= ~(0x0808);
+ Value |= 0x08;
+ RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
+ }
+#endif // RT30xx //
+}
+
+
+/*
+ ========================================================================
+ Routine Description:
+ Periodic evaluate antenna link status
+
+ Arguments:
+ pAd - Adapter pointer
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID AsicEvaluateRxAnt(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR BBPR3 = 0;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_NIC_NOT_EXIST |
+ fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
+ OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+#ifdef RT30xx
+ || (pAd->EepromAccess)
+#endif // RT30xx //
+ )
+ return;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ //if (pAd->StaCfg.Psm == PWR_SAVE)
+ // return;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove
+ // one is antenna diversity:there is only one antenna can rx and tx
+ // the other is failed antenna remove:two physical antenna can rx and tx
+ if (pAd->NicConfig2.field.AntDiversity)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n",
+ pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
+
+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt);
+
+ pAd->RxAnt.EvaluatePeriod = 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
+ pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE;
+ pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
+
+ // a one-shot timer to end the evalution
+ // dynamic adjust antenna evaluation period according to the traffic
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100);
+ else
+ RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
+ }
+ else
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->StaCfg.Psm == PWR_SAVE)
+ return;
+#endif // CONFIG_STA_SUPPORT //
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
+ BBPR3 &= (~0x18);
+ if(pAd->Antenna.field.RxPath == 3)
+ {
+ BBPR3 |= (0x10);
+ }
+ else if(pAd->Antenna.field.RxPath == 2)
+ {
+ BBPR3 |= (0x8);
+ }
+ else if(pAd->Antenna.field.RxPath == 1)
+ {
+ BBPR3 |= (0x0);
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+ )
+ {
+ ULONG TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
+
+ // dynamic adjust antenna evaluation period according to the traffic
+ if (TxTotalCnt > 50)
+ {
+ RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
+ pAd->Mlme.bLowThroughput = FALSE;
+ }
+ else
+ {
+ RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
+ pAd->Mlme.bLowThroughput = TRUE;
+ }
+ }
+ }
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ After evaluation, check antenna link status
+
+ Arguments:
+ pAd - Adapter pointer
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID AsicRxAntEvalTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+#ifdef CONFIG_STA_SUPPORT
+ UCHAR BBPR3 = 0;
+ CHAR larger = -127, rssi0, rssi1, rssi2;
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_NIC_NOT_EXIST) ||
+ OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+#ifdef RT30xx
+ || (pAd->EepromAccess)
+#endif // RT30xx //
+ )
+ return;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ //if (pAd->StaCfg.Psm == PWR_SAVE)
+ // return;
+
+ if (pAd->NicConfig2.field.AntDiversity)
+ {
+ if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt]))
+ {
+ UCHAR temp;
+
+ //
+ // select PrimaryRxAntPair
+ // Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair.
+ // Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt
+ //
+ temp = pAd->RxAnt.Pair1PrimaryRxAnt;
+ pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
+ pAd->RxAnt.Pair1SecondaryRxAnt = temp;
+
+ pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3);
+ pAd->RxAnt.EvaluateStableCnt = 0;
+ }
+ else
+ {
+ // if the evaluated antenna is not better than original, switch back to original antenna
+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+ pAd->RxAnt.EvaluateStableCnt ++;
+ }
+
+ pAd->RxAnt.EvaluatePeriod = 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
+
+ DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n",
+ pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate));
+ }
+ else
+ {
+ if (pAd->StaCfg.Psm == PWR_SAVE)
+ return;
+
+ // if the traffic is low, use average rssi as the criteria
+ if (pAd->Mlme.bLowThroughput == TRUE)
+ {
+ rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
+ rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
+ rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
+ }
+ else
+ {
+ rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
+ rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
+ rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
+ }
+
+ if(pAd->Antenna.field.RxPath == 3)
+ {
+ larger = max(rssi0, rssi1);
+
+ if (larger > (rssi2 + 20))
+ pAd->Mlme.RealRxPath = 2;
+ else
+ pAd->Mlme.RealRxPath = 3;
+ }
+ else if(pAd->Antenna.field.RxPath == 2)
+ {
+ if (rssi0 > (rssi1 + 20))
+ pAd->Mlme.RealRxPath = 1;
+ else
+ pAd->Mlme.RealRxPath = 2;
+ }
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
+ BBPR3 &= (~0x18);
+ if(pAd->Mlme.RealRxPath == 3)
+ {
+ BBPR3 |= (0x10);
+ }
+ else if(pAd->Mlme.RealRxPath == 2)
+ {
+ BBPR3 |= (0x8);
+ }
+ else if(pAd->Mlme.RealRxPath == 1)
+ {
+ BBPR3 |= (0x0);
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
+ }
+ }
+
+#endif // CONFIG_STA_SUPPORT //
+
+}
+
+
+
+VOID APSDPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ return;
+
+ pAd->CommonCfg.TriggerTimerCount++;
+
+// Driver should not send trigger frame, it should be send by application layer
+/*
+ if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable
+ && (pAd->CommonCfg.bNeedSendTriggerFrame ||
+ (((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO))))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n"));
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+ pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
+ pAd->CommonCfg.TriggerTimerCount = 0;
+ pAd->CommonCfg.bInServicePeriod = TRUE;
+ }*/
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Set/reset MAC registers according to bPiggyBack parameter
+
+ Arguments:
+ pAd - Adapter pointer
+ bPiggyBack - Enable / Disable Piggy-Back
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID RTMPSetPiggyBack(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bPiggyBack)
+{
+ TX_LINK_CFG_STRUC TxLinkCfg;
+
+ RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+
+ TxLinkCfg.field.TxCFAckEn = bPiggyBack;
+ RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ check if this entry need to switch rate automatically
+
+ Arguments:
+ pAd
+ pEntry
+
+ Return Value:
+ TURE
+ FALSE
+
+ ========================================================================
+*/
+BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry)
+{
+ BOOLEAN result = TRUE;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // only associated STA counts
+ if (pEntry && (pEntry->ValidAsCLI) && (pEntry->Sst == SST_ASSOC))
+ {
+ result = pAd->StaCfg.bAutoTxRateSwitch;
+ }
+ else
+ result = FALSE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+ return result;
+}
+
+
+BOOLEAN RTMPAutoRateSwitchCheck(
+ IN PRTMP_ADAPTER pAd)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pAd->StaCfg.bAutoTxRateSwitch)
+ return TRUE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ return FALSE;
+}
+
+
+/*
+ ========================================================================
+ Routine Description:
+ check if this entry need to fix tx legacy rate
+
+ Arguments:
+ pAd
+ pEntry
+
+ Return Value:
+ TURE
+ FALSE
+
+ ========================================================================
+*/
+UCHAR RTMPStaFixedTxMode(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry)
+{
+ UCHAR tx_mode = FIXED_TXMODE_HT;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ return tx_mode;
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
+
+ Arguments:
+ pAd
+ pEntry
+
+ Return Value:
+ TURE
+ FALSE
+
+ ========================================================================
+*/
+VOID RTMPUpdateLegacyTxSetting(
+ UCHAR fixed_tx_mode,
+ PMAC_TABLE_ENTRY pEntry)
+{
+ HTTRANSMIT_SETTING TransmitSetting;
+
+ if (fixed_tx_mode == FIXED_TXMODE_HT)
+ return;
+
+ TransmitSetting.word = 0;
+
+ TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE;
+ TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS;
+
+ if (fixed_tx_mode == FIXED_TXMODE_CCK)
+ {
+ TransmitSetting.field.MODE = MODE_CCK;
+ // CCK mode allow MCS 0~3
+ if (TransmitSetting.field.MCS > MCS_3)
+ TransmitSetting.field.MCS = MCS_3;
+ }
+ else
+ {
+ TransmitSetting.field.MODE = MODE_OFDM;
+ // OFDM mode allow MCS 0~7
+ if (TransmitSetting.field.MCS > MCS_7)
+ TransmitSetting.field.MCS = MCS_7;
+ }
+
+ if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE)
+ {
+ pEntry->HTPhyMode.word = TransmitSetting.word;
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
+ pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE), pEntry->HTPhyMode.field.MCS));
+ }
+}
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ dynamic tune BBP R66 to find a balance between sensibility and
+ noise isolation
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicStaBbpTuning(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR OrigR66Value = 0, R66;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
+ CHAR Rssi;
+
+ // 2860C did not support Fase CCA, therefore can't tune
+ if (pAd->MACVersion == 0x28600100)
+ return;
+
+ //
+ // work as a STA
+ //
+ if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) // no R66 tuning when SCANNING
+ return;
+
+ if ((pAd->OpMode == OPMODE_STA)
+ && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+ )
+ && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ )
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
+ R66 = OrigR66Value;
+
+ if (pAd->Antenna.field.RxPath > 1)
+ Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
+ else
+ Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
+
+ if (pAd->LatchRfRegs.Channel <= 14)
+ { //BG band
+#ifdef RT30xx
+ // RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
+ // Otherwise, it will have some throughput side effect when low RSSI
+ if (IS_RT30xx(pAd))
+ {
+ if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
+ {
+ R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20;
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ else
+ {
+ R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ }
+ else
+#endif // RT30xx //
+ {
+ if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
+ {
+ R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10;
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ else
+ {
+ R66 = 0x2E + GET_LNA_GAIN(pAd);
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ }
+
+ }
+ else
+ { //A band
+ if (pAd->CommonCfg.BBPCurrentBW == BW_20)
+ {
+ if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
+ {
+ R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ else
+ {
+ R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3;
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ }
+ else
+ {
+ if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
+ {
+ R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ else
+ {
+ R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3;
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ }
+ }
+
+
+ }
+}
+#endif // CONFIG_STA_SUPPORT //
+
+VOID RTMPSetAGCInitValue(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BandWidth)
+{
+ UCHAR R66 = 0x30;
+
+ if (pAd->LatchRfRegs.Channel <= 14)
+ { // BG band
+ R66 = 0x2E + GET_LNA_GAIN(pAd);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ else
+ { //A band
+ if (BandWidth == BW_20)
+ {
+ R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+#ifdef DOT11_N_SUPPORT
+ else
+ {
+ R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+#endif // DOT11_N_SUPPORT //
+ }
+
+}
+
+VOID AsicTurnOffRFClk(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+ // RF R2 bit 18 = 0
+ UINT32 R1 = 0, R2 = 0, R3 = 0;
+ UCHAR index;
+ RTMP_RF_REGS *RFRegTable;
+
+#ifdef RT30xx
+ // The RF programming sequence is difference between 3xxx and 2xxx
+ if (IS_RT3090(pAd))
+ {
+ RT30xxLoadRFSleepModeSetup(pAd); // add by johnli, RF power sequence setup, load RF sleep-mode setup
+ }
+ else
+ {
+#endif // RT30xx //
+ RFRegTable = RF2850RegTable;
+
+ switch (pAd->RfIcType)
+ {
+ case RFIC_2820:
+ case RFIC_2850:
+ case RFIC_2720:
+ case RFIC_2750:
+
+ for (index = 0; index < NUM_OF_2850_CHNL; index++)
+ {
+ if (Channel == RFRegTable[index].Channel)
+ {
+ R1 = RFRegTable[index].R1 & 0xffffdfff;
+ R2 = RFRegTable[index].R2 & 0xfffbffff;
+ R3 = RFRegTable[index].R3 & 0xfff3ffff;
+
+ RTMP_RF_IO_WRITE32(pAd, R1);
+ RTMP_RF_IO_WRITE32(pAd, R2);
+
+ // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
+ // Set RF R2 bit18=0, R3 bit[18:19]=0
+ //if (pAd->StaCfg.bRadio == FALSE)
+ if (1)
+ {
+ RTMP_RF_IO_WRITE32(pAd, R3);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
+ Channel, pAd->RfIcType, R2, R3));
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
+ Channel, pAd->RfIcType, R2));
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+#ifdef RT30xx
+ }
+#endif // RT30xx //
+
+}
+
+
+VOID AsicTurnOnRFClk(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+ // RF R2 bit 18 = 0
+ UINT32 R1 = 0, R2 = 0, R3 = 0;
+ UCHAR index;
+ RTMP_RF_REGS *RFRegTable;
+
+#ifdef RT30xx
+ // The RF programming sequence is difference between 3xxx and 2xxx
+ if (IS_RT3090(pAd))
+ {
+ }
+ else
+ {
+#endif // RT30xx //
+ RFRegTable = RF2850RegTable;
+
+ switch (pAd->RfIcType)
+ {
+ case RFIC_2820:
+ case RFIC_2850:
+ case RFIC_2720:
+ case RFIC_2750:
+
+ for (index = 0; index < NUM_OF_2850_CHNL; index++)
+ {
+ if (Channel == RFRegTable[index].Channel)
+ {
+ R3 = pAd->LatchRfRegs.R3;
+ R3 &= 0xfff3ffff;
+ R3 |= 0x00080000;
+ RTMP_RF_IO_WRITE32(pAd, R3);
+
+ R1 = RFRegTable[index].R1;
+ RTMP_RF_IO_WRITE32(pAd, R1);
+
+ R2 = RFRegTable[index].R2;
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
+ }
+
+ if (pAd->Antenna.field.RxPath == 2)
+ {
+ R2 |= 0x40; // write 1 to off Rxpath.
+ }
+ else if (pAd->Antenna.field.RxPath == 1)
+ {
+ R2 |= 0x20040; // write 1 to off RxPath
+ }
+ RTMP_RF_IO_WRITE32(pAd, R2);
+
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+#ifdef RT30xx
+ }
+#endif // RT30xx //
+
+}
+
diff --git a/drivers/staging/rt3070/common/netif_block.c b/drivers/staging/rt3070/common/netif_block.c
new file mode 100644
index 00000000000..4773c11bedd
--- /dev/null
+++ b/drivers/staging/rt3070/common/netif_block.c
@@ -0,0 +1,136 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#include "../rt_config.h"
+#include "netif_block.h"
+
+static NETIF_ENTRY freeNetIfEntryPool[FREE_NETIF_POOL_SIZE];
+static LIST_HEADER freeNetIfEntryList;
+
+void initblockQueueTab(
+ IN PRTMP_ADAPTER pAd)
+{
+ int i;
+
+ initList(&freeNetIfEntryList);
+ for (i = 0; i < FREE_NETIF_POOL_SIZE; i++)
+ insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)&freeNetIfEntryPool[i]);
+
+ for (i=0; i < NUM_OF_TX_RING; i++)
+ initList(&pAd->blockQueueTab[i].NetIfList);
+
+ return;
+}
+
+BOOLEAN blockNetIf(
+ IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
+ IN PNET_DEV pNetDev)
+{
+ PNETIF_ENTRY pNetIfEntry = NULL;
+
+ if ((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(&freeNetIfEntryList)) != NULL)
+ {
+ netif_stop_queue(pNetDev);
+ pNetIfEntry->pNetDev = pNetDev;
+ insertTailList(&pBlockQueueEntry->NetIfList, (PLIST_ENTRY)pNetIfEntry);
+
+ pBlockQueueEntry->SwTxQueueBlockFlag = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("netif_stop_queue(%s)\n", pNetDev->name));
+ }
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+VOID releaseNetIf(
+ IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry)
+{
+ PNETIF_ENTRY pNetIfEntry = NULL;
+ PLIST_HEADER pNetIfList = &pBlockQueueEntry->NetIfList;
+
+ while((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(pNetIfList)) != NULL)
+ {
+ PNET_DEV pNetDev = pNetIfEntry->pNetDev;
+ netif_wake_queue(pNetDev);
+ insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)pNetIfEntry);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("netif_wake_queue(%s)\n", pNetDev->name));
+ }
+ pBlockQueueEntry->SwTxQueueBlockFlag = FALSE;
+ return;
+}
+
+
+VOID StopNetIfQueue(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket)
+{
+ PNET_DEV NetDev = NULL;
+ UCHAR IfIdx = 0;
+ BOOLEAN valid = FALSE;
+
+#ifdef WDS_SUPPORT
+ if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_WDS)
+ {
+ IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_WDS) % MAX_WDS_ENTRY;
+ NetDev = pAd->WdsTab.WdsEntry[IfIdx].dev;
+ }
+ else
+#endif // WDS_SUPPORT //
+ {
+#ifdef MBSS_SUPPORT
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_MBSSID) % MAX_MBSSID_NUM;
+ NetDev = pAd->ApCfg.MBSSID[IfIdx].MSSIDDev;
+ }
+ else
+ {
+ IfIdx = MAIN_MBSSID;
+ NetDev = pAd->net_dev;
+ }
+#else
+ IfIdx = MAIN_MBSSID;
+ NetDev = pAd->net_dev;
+#endif
+ }
+
+ // WMM support 4 software queues.
+ // One software queue full doesn't mean device have no capbility to transmit packet.
+ // So disable block Net-If queue function while WMM enable.
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ valid = (pAd->CommonCfg.bWmmCapable == TRUE) ? FALSE : TRUE;
+#endif // CONFIG_STA_SUPPORT //
+
+ if (valid)
+ blockNetIf(&pAd->blockQueueTab[QueIdx], NetDev);
+ return;
+}
+
diff --git a/drivers/staging/rt3070/common/rtmp_init.c b/drivers/staging/rt3070/common/rtmp_init.c
new file mode 100644
index 00000000000..4503f6c6d95
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtmp_init.c
@@ -0,0 +1,4197 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_init.c
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 2002-08-01 created
+ John Chang 2004-08-20 RT2561/2661 use scatter-gather scheme
+ Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
+*/
+#include "../rt_config.h"
+#include "../firmware.h"
+
+//#define BIN_IN_FILE /* use *.bin firmware */
+
+UCHAR BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
+ULONG BIT32[] = {0x00000001, 0x00000002, 0x00000004, 0x00000008,
+ 0x00000010, 0x00000020, 0x00000040, 0x00000080,
+ 0x00000100, 0x00000200, 0x00000400, 0x00000800,
+ 0x00001000, 0x00002000, 0x00004000, 0x00008000,
+ 0x00010000, 0x00020000, 0x00040000, 0x00080000,
+ 0x00100000, 0x00200000, 0x00400000, 0x00800000,
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000};
+
+char* CipherName[] = {"none","wep64","wep128","TKIP","AES","CKIP64","CKIP128"};
+
+const unsigned short ccitt_16Table[] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+ 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+ 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+ 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+ 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+ 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+ 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+ 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+ 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+ 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+ 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+ 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+ 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+ 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+ 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+ 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+ 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+ 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+ 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+ 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+ 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+ 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+ 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+};
+#define ByteCRC16(v, crc) \
+ (unsigned short)((crc << 8) ^ ccitt_16Table[((crc >> 8) ^ (v)) & 255])
+
+unsigned char BitReverse(unsigned char x)
+{
+ int i;
+ unsigned char Temp=0;
+ for(i=0; ; i++)
+ {
+ if(x & 0x80) Temp |= 0x80;
+ if(i==7) break;
+ x <<= 1;
+ Temp >>= 1;
+ }
+ return Temp;
+}
+
+//
+// BBP register initialization set
+//
+REG_PAIR BBPRegTable[] = {
+ {BBP_R65, 0x2C}, // fix rssi issue
+ {BBP_R66, 0x38}, // Also set this default value to pAd->BbpTuning.R66CurrentValue at initial
+ {BBP_R69, 0x12},
+ {BBP_R70, 0xa}, // BBP_R70 will change to 0x8 in ApStartUp and LinkUp for rt2860C, otherwise value is 0xa
+ {BBP_R73, 0x10},
+ {BBP_R81, 0x37},
+ {BBP_R82, 0x62},
+ {BBP_R83, 0x6A},
+ {BBP_R84, 0x99}, // 0x19 is for rt2860E and after. This is for extension channel overlapping IOT. 0x99 is for rt2860D and before
+ {BBP_R86, 0x00}, // middle range issue, Rory @2008-01-28
+ {BBP_R91, 0x04}, // middle range issue, Rory @2008-01-28
+ {BBP_R92, 0x00}, // middle range issue, Rory @2008-01-28
+ {BBP_R103, 0x00}, // near range high-power issue, requested from Gary @2008-0528
+ {BBP_R105, 0x05}, // 0x05 is for rt2860E to turn on FEQ control. It is safe for rt2860D and before, because Bit 7:2 are reserved in rt2860D and before.
+};
+#define NUM_BBP_REG_PARMS (sizeof(BBPRegTable) / sizeof(REG_PAIR))
+
+//
+// RF register initialization set
+//
+#ifdef RT30xx
+REG_PAIR RT30xx_RFRegTable[] = {
+ {RF_R04, 0x40},
+ {RF_R05, 0x03},
+ {RF_R06, 0x02},
+ {RF_R07, 0x70},
+ {RF_R09, 0x0F},
+ {RF_R10, 0x41},
+ {RF_R11, 0x21},
+ {RF_R12, 0x7B},
+ {RF_R14, 0x90},
+ {RF_R15, 0x58},
+ {RF_R16, 0xB3},
+ {RF_R17, 0x92},
+ {RF_R18, 0x2C},
+ {RF_R19, 0x02},
+ {RF_R20, 0xBA},
+ {RF_R21, 0xDB},
+ {RF_R24, 0x16},
+ {RF_R25, 0x01},
+ {RF_R29, 0x1F},
+};
+#define NUM_RF_REG_PARMS (sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR))
+#endif // RT30xx //
+
+//
+// ASIC register initialization sets
+//
+
+RTMP_REG_PAIR MACRegTable[] = {
+#if defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x200)
+ {BCN_OFFSET0, 0xf8f0e8e0}, /* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */
+ {BCN_OFFSET1, 0x6f77d0c8}, /* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */
+#elif defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x100)
+ {BCN_OFFSET0, 0xece8e4e0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
+ {BCN_OFFSET1, 0xfcf8f4f0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
+#else
+ #error You must re-calculate new value for BCN_OFFSET0 & BCN_OFFSET1 in MACRegTable[]!!!
+#endif // HW_BEACON_OFFSET //
+
+ {LEGACY_BASIC_RATE, 0x0000013f}, // Basic rate set bitmap
+ {HT_BASIC_RATE, 0x00008003}, // Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI.
+ {MAC_SYS_CTRL, 0x00}, // 0x1004, , default Disable RX
+ {RX_FILTR_CFG, 0x17f97}, //0x1400 , RX filter control,
+ {BKOFF_SLOT_CFG, 0x209}, // default set short slot time, CC_DELAY_TIME should be 2
+ //{TX_SW_CFG0, 0x40a06}, // Gary,2006-08-23
+ {TX_SW_CFG0, 0x0}, // Gary,2008-05-21 for CWC test
+ {TX_SW_CFG1, 0x80606}, // Gary,2006-08-23
+ {TX_LINK_CFG, 0x1020}, // Gary,2006-08-23
+ {TX_TIMEOUT_CFG, 0x000a2090},
+ {MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000}, // 0x3018, MAX frame length. Max PSDU = 16kbytes.
+ {LED_CFG, 0x7f031e46}, // Gary, 2006-08-23
+
+//#ifdef CONFIG_STA_SUPPORT
+// {WMM_AIFSN_CFG, 0x00002273},
+// {WMM_CWMIN_CFG, 0x00002344},
+// {WMM_CWMAX_CFG, 0x000034aa},
+//#endif // CONFIG_STA_SUPPORT //
+#ifdef INF_AMAZON_SE
+ {PBF_MAX_PCNT, 0x1F3F6F6F}, //iverson modify for usb issue, 2008/09/19
+ // 6F + 6F < total page count FE
+ // so that RX doesn't occupy TX's buffer space when WMM congestion.
+#else
+ {PBF_MAX_PCNT, 0x1F3FBF9F}, //0x1F3f7f9f}, //Jan, 2006/04/20
+#endif // INF_AMAZON_SE //
+ //{TX_RTY_CFG, 0x6bb80408}, // Jan, 2006/11/16
+ {TX_RTY_CFG, 0x47d01f0f}, // Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03
+ {AUTO_RSP_CFG, 0x00000013}, // Initial Auto_Responder, because QA will turn off Auto-Responder
+ {CCK_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
+ {OFDM_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
+//PS packets use Tx1Q (for HCCA) when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef RT2870
+#ifdef CONFIG_STA_SUPPORT
+ {PBF_CFG, 0xf40006}, // Only enable Queue 2
+#endif // CONFIG_STA_SUPPORT //
+ {MM40_PROT_CFG, 0x3F44084}, // Initial Auto_Responder, because QA will turn off Auto-Responder
+ {WPDMA_GLO_CFG, 0x00000030},
+#endif // RT2870 //
+ {GF20_PROT_CFG, 0x01744004}, // set 19:18 --> Short NAV for MIMO PS
+ {GF40_PROT_CFG, 0x03F44084},
+ {MM20_PROT_CFG, 0x01744004},
+ {TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f*/ /*0x000024bf*/}, //Extension channel backoff.
+ {TX_RTS_CFG, 0x00092b20},
+//#ifdef WIFI_TEST
+ {EXP_ACK_TIME, 0x002400ca}, // default value
+//#else
+// {EXP_ACK_TIME, 0x005400ca}, // suggested by Gray @ 20070323 for 11n intel-sta throughput
+//#endif // end - WIFI_TEST //
+ {TXOP_HLDR_ET, 0x00000002},
+
+ /* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us
+ is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0
+ and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping
+ will always lost. So we change the SIFS of CCK from 10us to 16us. */
+ {XIFS_TIME_CFG, 0x33a41010},
+ {PWR_PIN_CFG, 0x00000003}, // patch for 2880-E
+};
+
+
+#ifdef CONFIG_STA_SUPPORT
+RTMP_REG_PAIR STAMACRegTable[] = {
+ {WMM_AIFSN_CFG, 0x00002273},
+ {WMM_CWMIN_CFG, 0x00002344},
+ {WMM_CWMAX_CFG, 0x000034aa},
+};
+#endif // CONFIG_STA_SUPPORT //
+
+#define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR))
+#ifdef CONFIG_STA_SUPPORT
+#define NUM_STA_MAC_REG_PARMS (sizeof(STAMACRegTable) / sizeof(RTMP_REG_PAIR))
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RT2870
+//
+// RT2870 Firmware Spec only used 1 oct for version expression
+//
+#define FIRMWARE_MINOR_VERSION 7
+
+#endif // RT2870 //
+
+// New 8k byte firmware size for RT3071/RT3072
+#define FIRMWAREIMAGE_MAX_LENGTH 0x2000
+#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(UCHAR))
+#define FIRMWARE_MAJOR_VERSION 0
+
+#define FIRMWAREIMAGEV1_LENGTH 0x1000
+#define FIRMWAREIMAGEV2_LENGTH 0x1000
+
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Allocate RTMP_ADAPTER data block and do some initialization
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_FAILURE
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS RTMPAllocAdapterBlock(
+ IN PVOID handle,
+ OUT PRTMP_ADAPTER *ppAdapter)
+{
+ PRTMP_ADAPTER pAd;
+ NDIS_STATUS Status;
+ INT index;
+ UCHAR *pBeaconBuf = NULL;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocAdapterBlock\n"));
+
+ *ppAdapter = NULL;
+
+ do
+ {
+ // Allocate RTMP_ADAPTER memory block
+ pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG);
+ if (pBeaconBuf == NULL)
+ {
+ Status = NDIS_STATUS_FAILURE;
+ DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n"));
+ break;
+ }
+
+ Status = AdapterBlockAllocateMemory(handle, (PVOID *)&pAd);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("Failed to allocate memory - ADAPTER\n"));
+ break;
+ }
+ pAd->BeaconBuf = pBeaconBuf;
+ printk("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER));
+
+
+ // Init spin locks
+ NdisAllocateSpinLock(&pAd->MgmtRingLock);
+
+ for (index =0 ; index < NUM_OF_TX_RING; index++)
+ {
+ NdisAllocateSpinLock(&pAd->TxSwQueueLock[index]);
+ NdisAllocateSpinLock(&pAd->DeQueueLock[index]);
+ pAd->DeQueueRunning[index] = FALSE;
+ }
+
+ NdisAllocateSpinLock(&pAd->irq_lock);
+
+ } while (FALSE);
+
+ if ((Status != NDIS_STATUS_SUCCESS) && (pBeaconBuf))
+ kfree(pBeaconBuf);
+
+ *ppAdapter = pAd;
+
+ DBGPRINT_S(Status, ("<-- RTMPAllocAdapterBlock, Status=%x\n", Status));
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Read initial Tx power per MCS and BW from EEPROM
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPReadTxPwrPerRate(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG data, Adata, Gdata;
+ USHORT i, value, value2;
+ INT Apwrdelta, Gpwrdelta;
+ UCHAR t1,t2,t3,t4;
+ BOOLEAN bValid, bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE;
+
+ //
+ // Get power delta for 20MHz and 40MHz.
+ //
+ DBGPRINT(RT_DEBUG_TRACE, ("Txpower per Rate\n"));
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, value2);
+ Apwrdelta = 0;
+ Gpwrdelta = 0;
+
+ if ((value2 & 0xff) != 0xff)
+ {
+ if ((value2 & 0x80))
+ Gpwrdelta = (value2&0xf);
+
+ if ((value2 & 0x40))
+ bGpwrdeltaMinus = FALSE;
+ else
+ bGpwrdeltaMinus = TRUE;
+ }
+ if ((value2 & 0xff00) != 0xff00)
+ {
+ if ((value2 & 0x8000))
+ Apwrdelta = ((value2&0xf00)>>8);
+
+ if ((value2 & 0x4000))
+ bApwrdeltaMinus = FALSE;
+ else
+ bApwrdeltaMinus = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta));
+
+ //
+ // Get Txpower per MCS for 20MHz in 2.4G.
+ //
+ for (i=0; i<5; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4, value);
+ data = value;
+ if (bApwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Apwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Apwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Apwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Apwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Apwrdelta)
+ t1 = (value&0xf)-(Apwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Apwrdelta)
+ t2 = ((value&0xf0)>>4)-(Apwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Apwrdelta)
+ t3 = ((value&0xf00)>>8)-(Apwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Apwrdelta)
+ t4 = ((value&0xf000)>>12)-(Apwrdelta);
+ else
+ t4 = 0;
+ }
+ Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+ if (bGpwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Gpwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Gpwrdelta)
+ t1 = (value&0xf)-(Gpwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Gpwrdelta)
+ t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Gpwrdelta)
+ t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Gpwrdelta)
+ t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+ else
+ t4 = 0;
+ }
+ Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4 + 2, value);
+ if (bApwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Apwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Apwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Apwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Apwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Apwrdelta)
+ t1 = (value&0xf)-(Apwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Apwrdelta)
+ t2 = ((value&0xf0)>>4)-(Apwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Apwrdelta)
+ t3 = ((value&0xf00)>>8)-(Apwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Apwrdelta)
+ t4 = ((value&0xf000)>>12)-(Apwrdelta);
+ else
+ t4 = 0;
+ }
+ Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+ if (bGpwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Gpwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Gpwrdelta)
+ t1 = (value&0xf)-(Gpwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Gpwrdelta)
+ t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Gpwrdelta)
+ t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Gpwrdelta)
+ t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+ else
+ t4 = 0;
+ }
+ Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+ data |= (value<<16);
+
+ pAd->Tx20MPwrCfgABand[i] = pAd->Tx40MPwrCfgABand[i] = Adata;
+ pAd->Tx20MPwrCfgGBand[i] = pAd->Tx40MPwrCfgGBand[i] = Gdata;
+
+ if (data != 0xffffffff)
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, data);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 2.4G band-%lx, Adata = %lx, Gdata = %lx \n", data, Adata, Gdata));
+ }
+
+ //
+ // Check this block is valid for 40MHz in 2.4G. If invalid, use parameter for 20MHz in 2.4G
+ //
+ bValid = TRUE;
+ for (i=0; i<6; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + 2 + i*2, value);
+ if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
+ {
+ bValid = FALSE;
+ break;
+ }
+ }
+
+ //
+ // Get Txpower per MCS for 40MHz in 2.4G.
+ //
+ if (bValid)
+ {
+ for (i=0; i<4; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4, value);
+ if (bGpwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Gpwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Gpwrdelta)
+ t1 = (value&0xf)-(Gpwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Gpwrdelta)
+ t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Gpwrdelta)
+ t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Gpwrdelta)
+ t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+ else
+ t4 = 0;
+ }
+ Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4 + 2, value);
+ if (bGpwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Gpwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Gpwrdelta)
+ t1 = (value&0xf)-(Gpwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Gpwrdelta)
+ t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Gpwrdelta)
+ t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Gpwrdelta)
+ t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+ else
+ t4 = 0;
+ }
+ Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+
+ if (i == 0)
+ pAd->Tx40MPwrCfgGBand[i+1] = (pAd->Tx40MPwrCfgGBand[i+1] & 0x0000FFFF) | (Gdata & 0xFFFF0000);
+ else
+ pAd->Tx40MPwrCfgGBand[i+1] = Gdata;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 2.4G band, Gdata = %lx \n", Gdata));
+ }
+ }
+
+ //
+ // Check this block is valid for 20MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
+ //
+ bValid = TRUE;
+ for (i=0; i<8; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + 2 + i*2, value);
+ if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
+ {
+ bValid = FALSE;
+ break;
+ }
+ }
+
+ //
+ // Get Txpower per MCS for 20MHz in 5G.
+ //
+ if (bValid)
+ {
+ for (i=0; i<5; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4, value);
+ if (bApwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Apwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Apwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Apwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Apwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Apwrdelta)
+ t1 = (value&0xf)-(Apwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Apwrdelta)
+ t2 = ((value&0xf0)>>4)-(Apwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Apwrdelta)
+ t3 = ((value&0xf00)>>8)-(Apwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Apwrdelta)
+ t4 = ((value&0xf000)>>12)-(Apwrdelta);
+ else
+ t4 = 0;
+ }
+ Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4 + 2, value);
+ if (bApwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Apwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Apwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Apwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Apwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Apwrdelta)
+ t1 = (value&0xf)-(Apwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Apwrdelta)
+ t2 = ((value&0xf0)>>4)-(Apwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Apwrdelta)
+ t3 = ((value&0xf00)>>8)-(Apwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Apwrdelta)
+ t4 = ((value&0xf000)>>12)-(Apwrdelta);
+ else
+ t4 = 0;
+ }
+ Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+
+ if (i == 0)
+ pAd->Tx20MPwrCfgABand[i] = (pAd->Tx20MPwrCfgABand[i] & 0x0000FFFF) | (Adata & 0xFFFF0000);
+ else
+ pAd->Tx20MPwrCfgABand[i] = Adata;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 5GHz band, Adata = %lx \n", Adata));
+ }
+ }
+
+ //
+ // Check this block is valid for 40MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
+ //
+ bValid = TRUE;
+ for (i=0; i<6; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + 2 + i*2, value);
+ if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
+ {
+ bValid = FALSE;
+ break;
+ }
+ }
+
+ //
+ // Get Txpower per MCS for 40MHz in 5G.
+ //
+ if (bValid)
+ {
+ for (i=0; i<4; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4, value);
+ if (bApwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Apwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Apwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Apwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Apwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Apwrdelta)
+ t1 = (value&0xf)-(Apwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Apwrdelta)
+ t2 = ((value&0xf0)>>4)-(Apwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Apwrdelta)
+ t3 = ((value&0xf00)>>8)-(Apwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Apwrdelta)
+ t4 = ((value&0xf000)>>12)-(Apwrdelta);
+ else
+ t4 = 0;
+ }
+ Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4 + 2, value);
+ if (bApwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Apwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Apwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Apwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Apwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Apwrdelta)
+ t1 = (value&0xf)-(Apwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Apwrdelta)
+ t2 = ((value&0xf0)>>4)-(Apwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Apwrdelta)
+ t3 = ((value&0xf00)>>8)-(Apwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Apwrdelta)
+ t4 = ((value&0xf000)>>12)-(Apwrdelta);
+ else
+ t4 = 0;
+ }
+ Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+
+ if (i == 0)
+ pAd->Tx40MPwrCfgABand[i+1] = (pAd->Tx40MPwrCfgABand[i+1] & 0x0000FFFF) | (Adata & 0xFFFF0000);
+ else
+ pAd->Tx40MPwrCfgABand[i+1] = Adata;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 5GHz band, Adata = %lx \n", Adata));
+ }
+ }
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Read initial channel power parameters from EEPROM
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPReadChannelPwr(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR i, choffset;
+ EEPROM_TX_PWR_STRUC Power;
+ EEPROM_TX_PWR_STRUC Power2;
+
+ // Read Tx power value for all channels
+ // Value from 1 - 0x7f. Default value is 24.
+ // Power value : 2.4G 0x00 (0) ~ 0x1F (31)
+ // : 5.5G 0xF9 (-7) ~ 0x0F (15)
+
+ // 0. 11b/g, ch1 - ch 14
+ for (i = 0; i < 7; i++)
+ {
+// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2);
+// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2, Power.word);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2, Power2.word);
+ pAd->TxPower[i * 2].Channel = i * 2 + 1;
+ pAd->TxPower[i * 2 + 1].Channel = i * 2 + 2;
+
+ if ((Power.field.Byte0 > 31) || (Power.field.Byte0 < 0))
+ pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER;
+ else
+ pAd->TxPower[i * 2].Power = Power.field.Byte0;
+
+ if ((Power.field.Byte1 > 31) || (Power.field.Byte1 < 0))
+ pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER;
+ else
+ pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1;
+
+ if ((Power2.field.Byte0 > 31) || (Power2.field.Byte0 < 0))
+ pAd->TxPower[i * 2].Power2 = DEFAULT_RF_TX_POWER;
+ else
+ pAd->TxPower[i * 2].Power2 = Power2.field.Byte0;
+
+ if ((Power2.field.Byte1 > 31) || (Power2.field.Byte1 < 0))
+ pAd->TxPower[i * 2 + 1].Power2 = DEFAULT_RF_TX_POWER;
+ else
+ pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1;
+ }
+
+ // 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz)
+ // 1.1 Fill up channel
+ choffset = 14;
+ for (i = 0; i < 4; i++)
+ {
+ pAd->TxPower[3 * i + choffset + 0].Channel = 36 + i * 8 + 0;
+ pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
+
+ pAd->TxPower[3 * i + choffset + 1].Channel = 36 + i * 8 + 2;
+ pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
+
+ pAd->TxPower[3 * i + choffset + 2].Channel = 36 + i * 8 + 4;
+ pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
+ }
+
+ // 1.2 Fill up power
+ for (i = 0; i < 6; i++)
+ {
+// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2);
+// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2, Power.word);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2, Power2.word);
+
+ if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
+ pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
+
+ if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
+ pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
+
+ if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
+ pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
+
+ if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
+ pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
+ }
+
+ // 2. HipperLAN 2 100, 102 ,104; 108, 110, 112; 116, 118, 120; 124, 126, 128; 132, 134, 136; 140 (including central frequency in BW 40MHz)
+ // 2.1 Fill up channel
+ choffset = 14 + 12;
+ for (i = 0; i < 5; i++)
+ {
+ pAd->TxPower[3 * i + choffset + 0].Channel = 100 + i * 8 + 0;
+ pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
+
+ pAd->TxPower[3 * i + choffset + 1].Channel = 100 + i * 8 + 2;
+ pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
+
+ pAd->TxPower[3 * i + choffset + 2].Channel = 100 + i * 8 + 4;
+ pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
+ }
+ pAd->TxPower[3 * 5 + choffset + 0].Channel = 140;
+ pAd->TxPower[3 * 5 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * 5 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
+
+ // 2.2 Fill up power
+ for (i = 0; i < 8; i++)
+ {
+// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2);
+// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
+
+ if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
+ pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
+
+ if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
+ pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
+
+ if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
+ pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
+
+ if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
+ pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
+ }
+
+ // 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165 (including central frequency in BW 40MHz)
+ // 3.1 Fill up channel
+ choffset = 14 + 12 + 16;
+ for (i = 0; i < 2; i++)
+ {
+ pAd->TxPower[3 * i + choffset + 0].Channel = 149 + i * 8 + 0;
+ pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
+
+ pAd->TxPower[3 * i + choffset + 1].Channel = 149 + i * 8 + 2;
+ pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
+
+ pAd->TxPower[3 * i + choffset + 2].Channel = 149 + i * 8 + 4;
+ pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
+ }
+ pAd->TxPower[3 * 2 + choffset + 0].Channel = 165;
+ pAd->TxPower[3 * 2 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * 2 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
+
+ // 3.2 Fill up power
+ for (i = 0; i < 4; i++)
+ {
+// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2);
+// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
+
+ if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
+ pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
+
+ if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
+ pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
+
+ if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
+ pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
+
+ if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
+ pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
+ }
+
+ // 4. Print and Debug
+ choffset = 14 + 12 + 16 + 7;
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Read the following from the registry
+ 1. All the parameters
+ 2. NetworkAddres
+
+ Arguments:
+ Adapter Pointer to our adapter
+ WrapperConfigurationContext For use by NdisOpenConfiguration
+
+ Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_FAILURE
+ NDIS_STATUS_RESOURCES
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS NICReadRegParameters(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_HANDLE WrapperConfigurationContext
+ )
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status));
+ return Status;
+}
+
+
+#ifdef RT30xx
+/*
+ ========================================================================
+
+ Routine Description:
+ For RF filter calibration purpose
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ ========================================================================
+*/
+VOID RTMPFilterCalibration(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR R55x = 0, value, FilterTarget = 0x1E, BBPValue=0;
+ UINT loop = 0, count = 0, loopcnt = 0, ReTry = 0;
+ UCHAR RF_R24_Value = 0;
+
+ // Give bbp filter initial value
+ pAd->Mlme.CaliBW20RfR24 = 0x1F;
+ pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40
+
+ do
+ {
+ if (loop == 1) //BandWidth = 40 MHz
+ {
+ // Write 0x27 to RF_R24 to program filter
+ RF_R24_Value = 0x27;
+ RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+ if (IS_RT3090(pAd))
+ FilterTarget = 0x15;
+ else
+ FilterTarget = 0x19;
+
+ // when calibrate BW40, BBP mask must set to BW40.
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue&= (~0x18);
+ BBPValue|= (0x10);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+ // set to BW40
+ RT30xxReadRFRegister(pAd, RF_R31, &value);
+ value |= 0x20;
+ RT30xxWriteRFRegister(pAd, RF_R31, value);
+ }
+ else //BandWidth = 20 MHz
+ {
+ // Write 0x07 to RF_R24 to program filter
+ RF_R24_Value = 0x07;
+ RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+ if (IS_RT3090(pAd))
+ FilterTarget = 0x13;
+ else
+ FilterTarget = 0x16;
+
+ // set to BW20
+ RT30xxReadRFRegister(pAd, RF_R31, &value);
+ value &= (~0x20);
+ RT30xxWriteRFRegister(pAd, RF_R31, value);
+ }
+
+ // Write 0x01 to RF_R22 to enable baseband loopback mode
+ RT30xxReadRFRegister(pAd, RF_R22, &value);
+ value |= 0x01;
+ RT30xxWriteRFRegister(pAd, RF_R22, value);
+
+ // Write 0x00 to BBP_R24 to set power & frequency of passband test tone
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
+
+ do
+ {
+ // Write 0x90 to BBP_R25 to transmit test tone
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
+
+ RTMPusecDelay(1000);
+ // Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
+ R55x = value & 0xFF;
+
+ } while ((ReTry++ < 100) && (R55x == 0));
+
+ // Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
+
+ while(TRUE)
+ {
+ // Write 0x90 to BBP_R25 to transmit test tone
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
+
+ //We need to wait for calibration
+ RTMPusecDelay(1000);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
+ value &= 0xFF;
+ if ((R55x - value) < FilterTarget)
+ {
+ RF_R24_Value ++;
+ }
+ else if ((R55x - value) == FilterTarget)
+ {
+ RF_R24_Value ++;
+ count ++;
+ }
+ else
+ {
+ break;
+ }
+
+ // prevent infinite loop cause driver hang.
+ if (loopcnt++ > 100)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
+ break;
+ }
+
+ // Write RF_R24 to program filter
+ RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+ }
+
+ if (count > 0)
+ {
+ RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
+ }
+
+ // Store for future usage
+ if (loopcnt < 100)
+ {
+ if (loop++ == 0)
+ {
+ //BandWidth = 20 MHz
+ pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
+ }
+ else
+ {
+ //BandWidth = 40 MHz
+ pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
+ break;
+ }
+ }
+ else
+ break;
+
+ RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+
+ // reset count
+ count = 0;
+ } while(TRUE);
+
+ //
+ // Set back to initial state
+ //
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
+
+ RT30xxReadRFRegister(pAd, RF_R22, &value);
+ value &= ~(0x01);
+ RT30xxWriteRFRegister(pAd, RF_R22, value);
+
+ // set BBP back to BW20
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue&= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
+}
+#endif // RT30xx //
+
+
+#ifdef RT3070
+VOID NICInitRT30xxRFRegisters(IN PRTMP_ADAPTER pAd)
+{
+ INT i;
+ // Driver must read EEPROM to get RfIcType before initial RF registers
+ // Initialize RF register to default value
+ if (IS_RT3070(pAd) || IS_RT3071(pAd))
+ {
+ // Init RF calibration
+ // Driver should toggle RF R30 bit7 before init RF registers
+ UINT32 RfReg = 0;
+ UINT32 data;
+
+ RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
+ RfReg |= 0x80;
+ RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
+ RTMPusecDelay(1000);
+ RfReg &= 0x7F;
+ RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
+
+ // Initialize RF register to default value
+ for (i = 0; i < NUM_RF_REG_PARMS; i++)
+ {
+ RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
+ }
+
+ // add by johnli
+ if (IS_RT3070(pAd))
+ {
+ // Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate
+ RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
+ data = ((data & 0xF0FFFFFF) | 0x0D000000);
+ RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
+ }
+ else if (IS_RT3071(pAd))
+ {
+ // Driver should set RF R6 bit6 on before init RF registers
+ RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
+ RfReg |= 0x40;
+ RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
+
+ // init R31
+ RT30xxWriteRFRegister(pAd, RF_R31, 0x14);
+
+ // RT3071 version E has fixed this issue
+ if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
+ {
+ // patch tx EVM issue temporarily
+ RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
+ data = ((data & 0xE0FFFFFF) | 0x0D000000);
+ RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
+ }
+ else
+ {
+ RTMP_IO_READ32(pAd, LDO_CFG0, &data);
+ data = ((data & 0xE0FFFFFF) | 0x01000000);
+ RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
+ }
+
+ // patch LNA_PE_G1 failed issue
+ RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data);
+ data &= ~(0x20);
+ RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data);
+ }
+
+ //For RF filter Calibration
+ RTMPFilterCalibration(pAd);
+
+ // Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
+ if ((pAd->MACVersion & 0xffff) < 0x0211)
+ RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
+
+ // set led open drain enable
+ RTUSBReadMACRegister(pAd, OPT_14, &data);
+ data |= 0x01;
+ RTUSBWriteMACRegister(pAd, OPT_14, data);
+
+ if (IS_RT3071(pAd))
+ {
+ // add by johnli, RF power sequence setup, load RF normal operation-mode setup
+ RT30xxLoadRFNormalModeSetup(pAd);
+ }
+ }
+
+}
+#endif // RT3070 //
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Read initial parameters from EEPROM
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID NICReadEEPROMParameters(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR mac_addr)
+{
+ UINT32 data = 0;
+ USHORT i, value, value2;
+ UCHAR TmpPhy;
+ EEPROM_TX_PWR_STRUC Power;
+ EEPROM_VERSION_STRUC Version;
+ EEPROM_ANTENNA_STRUC Antenna;
+ EEPROM_NIC_CONFIG2_STRUC NicConfig2;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n"));
+
+ // Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
+ DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data));
+
+ if((data & 0x30) == 0)
+ pAd->EEPROMAddressNum = 6; // 93C46
+ else if((data & 0x30) == 0x10)
+ pAd->EEPROMAddressNum = 8; // 93C66
+ else
+ pAd->EEPROMAddressNum = 8; // 93C86
+ DBGPRINT(RT_DEBUG_TRACE, ("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum ));
+
+ // RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize
+ // MAC address registers according to E2PROM setting
+ if (mac_addr == NULL ||
+ strlen(mac_addr) != 17 ||
+ mac_addr[2] != ':' || mac_addr[5] != ':' || mac_addr[8] != ':' ||
+ mac_addr[11] != ':' || mac_addr[14] != ':')
+ {
+ USHORT Addr01,Addr23,Addr45 ;
+
+ RT28xx_EEPROM_READ16(pAd, 0x04, Addr01);
+ RT28xx_EEPROM_READ16(pAd, 0x06, Addr23);
+ RT28xx_EEPROM_READ16(pAd, 0x08, Addr45);
+
+ pAd->PermanentAddress[0] = (UCHAR)(Addr01 & 0xff);
+ pAd->PermanentAddress[1] = (UCHAR)(Addr01 >> 8);
+ pAd->PermanentAddress[2] = (UCHAR)(Addr23 & 0xff);
+ pAd->PermanentAddress[3] = (UCHAR)(Addr23 >> 8);
+ pAd->PermanentAddress[4] = (UCHAR)(Addr45 & 0xff);
+ pAd->PermanentAddress[5] = (UCHAR)(Addr45 >> 8);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from E2PROM \n"));
+ }
+ else
+ {
+ INT j;
+ PUCHAR macptr;
+
+ macptr = mac_addr;
+
+ for (j=0; j<MAC_ADDR_LEN; j++)
+ {
+ AtoH(macptr, &pAd->PermanentAddress[j], 1);
+ macptr=macptr+3;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from module parameter \n"));
+ }
+
+
+ {
+ //more conveninet to test mbssid, so ap's bssid &0xf1
+ if (pAd->PermanentAddress[0] == 0xff)
+ pAd->PermanentAddress[0] = RandomByte(pAd)&0xf8;
+
+ //if (pAd->PermanentAddress[5] == 0xff)
+ // pAd->PermanentAddress[5] = RandomByte(pAd)&0xf8;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pAd->PermanentAddress[0], pAd->PermanentAddress[1],
+ pAd->PermanentAddress[2], pAd->PermanentAddress[3],
+ pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
+ if (pAd->bLocalAdminMAC == FALSE)
+ {
+ MAC_DW0_STRUC csr2;
+ MAC_DW1_STRUC csr3;
+ COPY_MAC_ADDR(pAd->CurrentAddress, pAd->PermanentAddress);
+ csr2.field.Byte0 = pAd->CurrentAddress[0];
+ csr2.field.Byte1 = pAd->CurrentAddress[1];
+ csr2.field.Byte2 = pAd->CurrentAddress[2];
+ csr2.field.Byte3 = pAd->CurrentAddress[3];
+ RTMP_IO_WRITE32(pAd, MAC_ADDR_DW0, csr2.word);
+ csr3.word = 0;
+ csr3.field.Byte4 = pAd->CurrentAddress[4];
+ csr3.field.Byte5 = pAd->CurrentAddress[5];
+ csr3.field.U2MeMask = 0xff;
+ RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word);
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pAd->PermanentAddress[0], pAd->PermanentAddress[1],
+ pAd->PermanentAddress[2], pAd->PermanentAddress[3],
+ pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
+ }
+ }
+
+ // if not return early. cause fail at emulation.
+ // Init the channel number for TX channel power
+ RTMPReadChannelPwr(pAd);
+
+ // if E2PROM version mismatch with driver's expectation, then skip
+ // all subsequent E2RPOM retieval and set a system error bit to notify GUI
+ RT28xx_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET, Version.word);
+ pAd->EepromVersion = Version.field.Version + Version.field.FaeReleaseNumber * 256;
+ DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: Version = %d, FAE release #%d\n", Version.field.Version, Version.field.FaeReleaseNumber));
+
+ if (Version.field.Version > VALID_EEPROM_VERSION)
+ {
+ DBGPRINT_ERR(("E2PROM: WRONG VERSION 0x%x, should be %d\n",Version.field.Version, VALID_EEPROM_VERSION));
+ /*pAd->SystemErrorBitmap |= 0x00000001;
+
+ // hard-code default value when no proper E2PROM installed
+ pAd->bAutoTxAgcA = FALSE;
+ pAd->bAutoTxAgcG = FALSE;
+
+ // Default the channel power
+ for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
+ pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
+
+ // Default the channel power
+ for (i = 0; i < MAX_NUM_OF_11JCHANNELS; i++)
+ pAd->TxPower11J[i].Power = DEFAULT_RF_TX_POWER;
+
+ for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
+ pAd->EEPROMDefaultValue[i] = 0xffff;
+ return; */
+ }
+
+ // Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd
+ RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value);
+ pAd->EEPROMDefaultValue[0] = value;
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value);
+ pAd->EEPROMDefaultValue[1] = value;
+
+ RT28xx_EEPROM_READ16(pAd, 0x38, value); // Country Region
+ pAd->EEPROMDefaultValue[2] = value;
+
+ for(i = 0; i < 8; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i*2, value);
+ pAd->EEPROMDefaultValue[i+3] = value;
+ }
+
+ // We have to parse NIC configuration 0 at here.
+ // If TSSI did not have preloaded value, it should reset the TxAutoAgc to false
+ // Therefore, we have to read TxAutoAgc control beforehand.
+ // Read Tx AGC control bit
+ Antenna.word = pAd->EEPROMDefaultValue[0];
+ if (Antenna.word == 0xFFFF)
+ {
+#ifdef RT30xx
+ if(IS_RT3090(pAd))
+ {
+ Antenna.word = 0;
+ Antenna.field.RfIcType = RFIC_3020;
+ Antenna.field.TxPath = 1;
+ Antenna.field.RxPath = 1;
+ }
+ else
+ {
+#endif // RT30xx //
+ Antenna.word = 0;
+ Antenna.field.RfIcType = RFIC_2820;
+ Antenna.field.TxPath = 1;
+ Antenna.field.RxPath = 2;
+ DBGPRINT(RT_DEBUG_WARN, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
+#ifdef RT30xx
+ }
+#endif // RT30xx //
+ }
+
+ // Choose the desired Tx&Rx stream.
+ if ((pAd->CommonCfg.TxStream == 0) || (pAd->CommonCfg.TxStream > Antenna.field.TxPath))
+ pAd->CommonCfg.TxStream = Antenna.field.TxPath;
+
+ if ((pAd->CommonCfg.RxStream == 0) || (pAd->CommonCfg.RxStream > Antenna.field.RxPath))
+ {
+ pAd->CommonCfg.RxStream = Antenna.field.RxPath;
+
+ if ((pAd->MACVersion < RALINK_2883_VERSION) &&
+ (pAd->CommonCfg.RxStream > 2))
+ {
+ // only 2 Rx streams for RT2860 series
+ pAd->CommonCfg.RxStream = 2;
+ }
+ }
+
+ // 3*3
+ // read value from EEPROM and set them to CSR174 ~ 177 in chain0 ~ chain2
+ // yet implement
+ for(i=0; i<3; i++)
+ {
+ }
+
+ NicConfig2.word = pAd->EEPROMDefaultValue[1];
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if ((NicConfig2.word & 0x00ff) == 0xff)
+ {
+ NicConfig2.word &= 0xff00;
+ }
+
+ if ((NicConfig2.word >> 8) == 0xff)
+ {
+ NicConfig2.word &= 0x00ff;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ if (NicConfig2.field.DynamicTxAgcControl == 1)
+ pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
+ else
+ pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n", Antenna.field.RxPath, Antenna.field.TxPath));
+
+ // Save the antenna for future use
+ pAd->Antenna.word = Antenna.word;
+
+ //
+ // Reset PhyMode if we don't support 802.11a
+ // Only RFIC_2850 & RFIC_2750 support 802.11a
+ //
+ if ((Antenna.field.RfIcType != RFIC_2850) && (Antenna.field.RfIcType != RFIC_2750))
+ {
+ if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) ||
+ (pAd->CommonCfg.PhyMode == PHY_11A))
+ pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;
+#ifdef DOT11_N_SUPPORT
+ else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) ||
+ (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) ||
+ (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) ||
+ (pAd->CommonCfg.PhyMode == PHY_11N_5G))
+ pAd->CommonCfg.PhyMode = PHY_11BGN_MIXED;
+#endif // DOT11_N_SUPPORT //
+ }
+
+ // Read TSSI reference and TSSI boundary for temperature compensation. This is ugly
+ // 0. 11b/g
+ {
+ /* these are tempature reference value (0x00 ~ 0xFE)
+ ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
+ TssiPlusBoundaryG [4] [3] [2] [1] [0] (smaller) +
+ TssiMinusBoundaryG[0] [1] [2] [3] [4] (larger) */
+ RT28xx_EEPROM_READ16(pAd, 0x6E, Power.word);
+ pAd->TssiMinusBoundaryG[4] = Power.field.Byte0;
+ pAd->TssiMinusBoundaryG[3] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0x70, Power.word);
+ pAd->TssiMinusBoundaryG[2] = Power.field.Byte0;
+ pAd->TssiMinusBoundaryG[1] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0x72, Power.word);
+ pAd->TssiRefG = Power.field.Byte0; /* reference value [0] */
+ pAd->TssiPlusBoundaryG[1] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0x74, Power.word);
+ pAd->TssiPlusBoundaryG[2] = Power.field.Byte0;
+ pAd->TssiPlusBoundaryG[3] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0x76, Power.word);
+ pAd->TssiPlusBoundaryG[4] = Power.field.Byte0;
+ pAd->TxAgcStepG = Power.field.Byte1;
+ pAd->TxAgcCompensateG = 0;
+ pAd->TssiMinusBoundaryG[0] = pAd->TssiRefG;
+ pAd->TssiPlusBoundaryG[0] = pAd->TssiRefG;
+
+ // Disable TxAgc if the based value is not right
+ if (pAd->TssiRefG == 0xff)
+ pAd->bAutoTxAgcG = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE,("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
+ pAd->TssiMinusBoundaryG[4], pAd->TssiMinusBoundaryG[3], pAd->TssiMinusBoundaryG[2], pAd->TssiMinusBoundaryG[1],
+ pAd->TssiRefG,
+ pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2], pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4],
+ pAd->TxAgcStepG, pAd->bAutoTxAgcG));
+ }
+ // 1. 11a
+ {
+ RT28xx_EEPROM_READ16(pAd, 0xD4, Power.word);
+ pAd->TssiMinusBoundaryA[4] = Power.field.Byte0;
+ pAd->TssiMinusBoundaryA[3] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0xD6, Power.word);
+ pAd->TssiMinusBoundaryA[2] = Power.field.Byte0;
+ pAd->TssiMinusBoundaryA[1] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0xD8, Power.word);
+ pAd->TssiRefA = Power.field.Byte0;
+ pAd->TssiPlusBoundaryA[1] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0xDA, Power.word);
+ pAd->TssiPlusBoundaryA[2] = Power.field.Byte0;
+ pAd->TssiPlusBoundaryA[3] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0xDC, Power.word);
+ pAd->TssiPlusBoundaryA[4] = Power.field.Byte0;
+ pAd->TxAgcStepA = Power.field.Byte1;
+ pAd->TxAgcCompensateA = 0;
+ pAd->TssiMinusBoundaryA[0] = pAd->TssiRefA;
+ pAd->TssiPlusBoundaryA[0] = pAd->TssiRefA;
+
+ // Disable TxAgc if the based value is not right
+ if (pAd->TssiRefA == 0xff)
+ pAd->bAutoTxAgcA = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE,("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
+ pAd->TssiMinusBoundaryA[4], pAd->TssiMinusBoundaryA[3], pAd->TssiMinusBoundaryA[2], pAd->TssiMinusBoundaryA[1],
+ pAd->TssiRefA,
+ pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2], pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4],
+ pAd->TxAgcStepA, pAd->bAutoTxAgcA));
+ }
+ pAd->BbpRssiToDbmDelta = 0x0;
+
+ // Read frequency offset setting for RF
+ RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, value);
+ if ((value & 0x00FF) != 0x00FF)
+ pAd->RfFreqOffset = (ULONG) (value & 0x00FF);
+ else
+ pAd->RfFreqOffset = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset));
+
+ //CountryRegion byte offset (38h)
+ value = pAd->EEPROMDefaultValue[2] >> 8; // 2.4G band
+ value2 = pAd->EEPROMDefaultValue[2] & 0x00FF; // 5G band
+
+ if ((value <= REGION_MAXIMUM_BG_BAND) && (value2 <= REGION_MAXIMUM_A_BAND))
+ {
+ pAd->CommonCfg.CountryRegion = ((UCHAR) value) | 0x80;
+ pAd->CommonCfg.CountryRegionForABand = ((UCHAR) value2) | 0x80;
+ TmpPhy = pAd->CommonCfg.PhyMode;
+ pAd->CommonCfg.PhyMode = 0xff;
+ RTMPSetPhyMode(pAd, TmpPhy);
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+ }
+
+ //
+ // Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch.
+ // The valid value are (-10 ~ 10)
+ //
+ RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, value);
+ pAd->BGRssiOffset0 = value & 0x00ff;
+ pAd->BGRssiOffset1 = (value >> 8);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET+2, value);
+ pAd->BGRssiOffset2 = value & 0x00ff;
+ pAd->ALNAGain1 = (value >> 8);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value);
+ pAd->BLNAGain = value & 0x00ff;
+ pAd->ALNAGain0 = (value >> 8);
+
+ // Validate 11b/g RSSI_0 offset.
+ if ((pAd->BGRssiOffset0 < -10) || (pAd->BGRssiOffset0 > 10))
+ pAd->BGRssiOffset0 = 0;
+
+ // Validate 11b/g RSSI_1 offset.
+ if ((pAd->BGRssiOffset1 < -10) || (pAd->BGRssiOffset1 > 10))
+ pAd->BGRssiOffset1 = 0;
+
+ // Validate 11b/g RSSI_2 offset.
+ if ((pAd->BGRssiOffset2 < -10) || (pAd->BGRssiOffset2 > 10))
+ pAd->BGRssiOffset2 = 0;
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value);
+ pAd->ARssiOffset0 = value & 0x00ff;
+ pAd->ARssiOffset1 = (value >> 8);
+ RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET+2), value);
+ pAd->ARssiOffset2 = value & 0x00ff;
+ pAd->ALNAGain2 = (value >> 8);
+
+ if (((UCHAR)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00))
+ pAd->ALNAGain1 = pAd->ALNAGain0;
+ if (((UCHAR)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00))
+ pAd->ALNAGain2 = pAd->ALNAGain0;
+
+ // Validate 11a RSSI_0 offset.
+ if ((pAd->ARssiOffset0 < -10) || (pAd->ARssiOffset0 > 10))
+ pAd->ARssiOffset0 = 0;
+
+ // Validate 11a RSSI_1 offset.
+ if ((pAd->ARssiOffset1 < -10) || (pAd->ARssiOffset1 > 10))
+ pAd->ARssiOffset1 = 0;
+
+ //Validate 11a RSSI_2 offset.
+ if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10))
+ pAd->ARssiOffset2 = 0;
+
+ //
+ // Get LED Setting.
+ //
+ RT28xx_EEPROM_READ16(pAd, 0x3a, value);
+ pAd->LedCntl.word = (value&0xff00) >> 8;
+ RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value);
+ pAd->Led1 = value;
+ RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value);
+ pAd->Led2 = value;
+ RT28xx_EEPROM_READ16(pAd, EEPROM_LED3_OFFSET, value);
+ pAd->Led3 = value;
+
+ RTMPReadTxPwrPerRate(pAd);
+
+#ifdef SINGLE_SKU
+ //pAd->CommonCfg.DefineMaxTxPwr = RTMP_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR, pAd->CommonCfg.DefineMaxTxPwr);
+#endif // SINGLE_SKU //
+#ifdef RT30xx
+ if (IS_RT30xx(pAd))
+ {
+ eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
+ pAd->EFuseTag = (value & 0xff);
+ }
+#endif // RT30xx //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set default value from EEPROM
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID NICInitAsicFromEEPROM(
+ IN PRTMP_ADAPTER pAd)
+{
+#ifdef CONFIG_STA_SUPPORT
+ UINT32 data = 0;
+ UCHAR BBPR1 = 0;
+#endif // CONFIG_STA_SUPPORT //
+ USHORT i;
+ EEPROM_ANTENNA_STRUC Antenna;
+ EEPROM_NIC_CONFIG2_STRUC NicConfig2;
+ UCHAR BBPR3 = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n"));
+ for(i = 3; i < NUM_EEPROM_BBP_PARMS; i++)
+ {
+ UCHAR BbpRegIdx, BbpValue;
+
+ if ((pAd->EEPROMDefaultValue[i] != 0xFFFF) && (pAd->EEPROMDefaultValue[i] != 0))
+ {
+ BbpRegIdx = (UCHAR)(pAd->EEPROMDefaultValue[i] >> 8);
+ BbpValue = (UCHAR)(pAd->EEPROMDefaultValue[i] & 0xff);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BbpRegIdx, BbpValue);
+ }
+ }
+
+ Antenna.word = pAd->EEPROMDefaultValue[0];
+ if (Antenna.word == 0xFFFF)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
+ BUG_ON(Antenna.word == 0xFFFF);
+ }
+ pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath;
+ pAd->RfIcType = (UCHAR) Antenna.field.RfIcType;
+
+ DBGPRINT(RT_DEBUG_WARN, ("pAd->RfIcType = %d, RealRxPath=%d, TxPath = %d\n", pAd->RfIcType, pAd->Mlme.RealRxPath,Antenna.field.TxPath));
+
+ // Save the antenna for future use
+ pAd->Antenna.word = Antenna.word;
+
+ NicConfig2.word = pAd->EEPROMDefaultValue[1];
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if ((NicConfig2.word & 0x00ff) == 0xff)
+ {
+ NicConfig2.word &= 0xff00;
+ }
+
+ if ((NicConfig2.word >> 8) == 0xff)
+ {
+ NicConfig2.word &= 0x00ff;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Save the antenna for future use
+ pAd->NicConfig2.word = NicConfig2.word;
+
+ // set default antenna as main
+ if (pAd->RfIcType == RFIC_3020)
+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+
+ //
+ // Send LED Setting to MCU.
+ //
+ if (pAd->LedCntl.word == 0xFF)
+ {
+ pAd->LedCntl.word = 0x01;
+ pAd->Led1 = 0x5555;
+ pAd->Led2 = 0x2221;
+
+#ifdef RT2870
+ pAd->Led3 = 0x5627;
+#endif // RT2870 //
+ }
+
+ AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8));
+ AsicSendCommandToMcu(pAd, 0x53, 0xff, (UCHAR)pAd->Led2, (UCHAR)(pAd->Led2 >> 8));
+ AsicSendCommandToMcu(pAd, 0x54, 0xff, (UCHAR)pAd->Led3, (UCHAR)(pAd->Led3 >> 8));
+ pAd->LedIndicatorStregth = 0xFF;
+ RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, before link up
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Read Hardware controlled Radio state enable bit
+ if (NicConfig2.field.HardwareRadioControl == 1)
+ {
+ pAd->StaCfg.bHardwareRadio = TRUE;
+
+ // Read GPIO pin2 as Hardware controlled radio state
+ RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
+ if ((data & 0x04) == 0)
+ {
+ pAd->StaCfg.bHwRadio = FALSE;
+ pAd->StaCfg.bRadio = FALSE;
+// RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+ }
+ }
+ else
+ pAd->StaCfg.bHardwareRadio = FALSE;
+
+ if (pAd->StaCfg.bRadio == FALSE)
+ {
+ RTMPSetLED(pAd, LED_RADIO_OFF);
+ }
+ else
+ {
+ RTMPSetLED(pAd, LED_RADIO_ON);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Turn off patching for cardbus controller
+ if (NicConfig2.field.CardbusAcceleration == 1)
+ {
+// pAd->bTest1 = TRUE;
+ }
+
+ if (NicConfig2.field.DynamicTxAgcControl == 1)
+ pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
+ else
+ pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
+ //
+ // Since BBP has been progamed, to make sure BBP setting will be
+ // upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND!!
+ //
+ pAd->CommonCfg.BandState = UNKNOWN_BAND;
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
+ BBPR3 &= (~0x18);
+ if(pAd->Antenna.field.RxPath == 3)
+ {
+ BBPR3 |= (0x10);
+ }
+ else if(pAd->Antenna.field.RxPath == 2)
+ {
+ BBPR3 |= (0x8);
+ }
+ else if(pAd->Antenna.field.RxPath == 1)
+ {
+ BBPR3 |= (0x0);
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Handle the difference when 1T
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
+ if(pAd->Antenna.field.TxPath == 1)
+ {
+ BBPR1 &= (~0x18);
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n", pAd->CommonCfg.bHardwareRadio, pAd->CommonCfg.bHardwareRadio));
+ }
+#endif // CONFIG_STA_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("TxPath = %d, RxPath = %d, RFIC=%d, Polar+LED mode=%x\n", pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath, pAd->RfIcType, pAd->LedCntl.word));
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Initialize NIC hardware
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS NICInitializeAdapter(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bHardReset)
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ WPDMA_GLO_CFG_STRUC GloCfg;
+// INT_MASK_CSR_STRUC IntMask;
+ ULONG i =0, j=0;
+ AC_TXOP_CSR0_STRUC csr0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n"));
+
+ // 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
+retry:
+ i = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+ if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
+ break;
+
+ RTMPusecDelay(1000);
+ i++;
+ }while ( i<100);
+ DBGPRINT(RT_DEBUG_TRACE, ("<== DMA offset 0x208 = 0x%x\n", GloCfg.word));
+ GloCfg.word &= 0xff0;
+ GloCfg.field.EnTXWriteBackDDONE =1;
+ RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+
+ // Record HW Beacon offset
+ pAd->BeaconOffset[0] = HW_BEACON_BASE0;
+ pAd->BeaconOffset[1] = HW_BEACON_BASE1;
+ pAd->BeaconOffset[2] = HW_BEACON_BASE2;
+ pAd->BeaconOffset[3] = HW_BEACON_BASE3;
+ pAd->BeaconOffset[4] = HW_BEACON_BASE4;
+ pAd->BeaconOffset[5] = HW_BEACON_BASE5;
+ pAd->BeaconOffset[6] = HW_BEACON_BASE6;
+ pAd->BeaconOffset[7] = HW_BEACON_BASE7;
+
+ //
+ // write all shared Ring's base address into ASIC
+ //
+
+ // asic simulation sequence put this ahead before loading firmware.
+ // pbf hardware reset
+
+ // Initialze ASIC for TX & Rx operation
+ if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
+ {
+ if (j++ == 0)
+ {
+ NICLoadFirmware(pAd);
+ goto retry;
+ }
+ return NDIS_STATUS_FAILURE;
+ }
+
+
+
+
+ // WMM parameter
+ csr0.word = 0;
+ RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+ if (pAd->CommonCfg.PhyMode == PHY_11B)
+ {
+ csr0.field.Ac0Txop = 192; // AC_VI: 192*32us ~= 6ms
+ csr0.field.Ac1Txop = 96; // AC_VO: 96*32us ~= 3ms
+ }
+ else
+ {
+ csr0.field.Ac0Txop = 96; // AC_VI: 96*32us ~= 3ms
+ csr0.field.Ac1Txop = 48; // AC_VO: 48*32us ~= 1.5ms
+ }
+ RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
+
+
+
+
+ // reset action
+ // Load firmware
+ // Status = NICLoadFirmware(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAdapter\n"));
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Initialize ASIC
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS NICInitializeAsic(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bHardReset)
+{
+ ULONG Index = 0;
+ UCHAR R0 = 0xff;
+ UINT32 MacCsr12 = 0, Counter = 0;
+#ifdef RT2870
+ UINT32 MacCsr0 = 0;
+ NTSTATUS Status;
+ UCHAR Value = 0xff;
+#endif // RT2870 //
+#ifdef RT30xx
+ UINT32 eFuseCtrl;
+#endif // RT30xx //
+ USHORT KeyIdx;
+ INT i,apidx;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
+
+
+#ifdef RT2870
+ //
+ // Make sure MAC gets ready after NICLoadFirmware().
+ //
+ Index = 0;
+
+ //To avoid hang-on issue when interface up in kernel 2.4,
+ //we use a local variable "MacCsr0" instead of using "pAd->MACVersion" directly.
+ do
+ {
+ RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
+
+ if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
+ break;
+
+ RTMPusecDelay(10);
+ } while (Index++ < 100);
+
+ pAd->MACVersion = MacCsr0;
+ DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
+ // turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue.
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacCsr12);
+ MacCsr12 &= (~0x2000);
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacCsr12);
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
+ RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0);
+ Status = RTUSBVenderReset(pAd);
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+
+ // Initialize MAC register to default value
+ for(Index=0; Index<NUM_MAC_REG_PARMS; Index++)
+ {
+#ifdef RT3070
+ if ((MACRegTable[Index].Register == TX_SW_CFG0) && (IS_RT3070(pAd) || IS_RT3071(pAd)))
+ {
+ MACRegTable[Index].Value = 0x00000400;
+ }
+#endif // RT3070 //
+ RTMP_IO_WRITE32(pAd, (USHORT)MACRegTable[Index].Register, MACRegTable[Index].Value);
+ }
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++)
+ {
+ RTMP_IO_WRITE32(pAd, (USHORT)STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT2870 //
+
+#ifdef RT30xx
+ // Initialize RT3070 serial MAc registers which is different from RT2870 serial
+ if (IS_RT3090(pAd))
+ {
+ RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
+
+ // RT3071 version E has fixed this issue
+ if ((pAd->MACVersion & 0xffff) < 0x0211)
+ {
+ if (pAd->NicConfig2.field.DACTestBit == 1)
+ {
+ RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically
+ }
+ else
+ {
+ RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F); // To fix throughput drop drastically
+ }
+ }
+ else
+ {
+ RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0);
+ }
+ }
+ else if (IS_RT3070(pAd))
+ {
+ RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
+ RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically
+ }
+#endif // RT30xx //
+
+ //
+ // Before program BBP, we need to wait BBP/RF get wake up.
+ //
+ Index = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12);
+
+ if ((MacCsr12 & 0x03) == 0) // if BB.RF is stable
+ break;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Check MAC_STATUS_CFG = Busy = %x\n", MacCsr12));
+ RTMPusecDelay(1000);
+ } while (Index++ < 100);
+
+ // The commands to firmware should be after these commands, these commands will init firmware
+ // PCI and USB are not the same because PCI driver needs to wait for PCI bus ready
+ RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0); // initialize BBP R/W access agent
+ RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
+ RTMPusecDelay(1000);
+
+ // Read BBP register, make sure BBP is up and running before write new data
+ Index = 0;
+ do
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &R0);
+ DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", R0));
+ } while ((++Index < 20) && ((R0 == 0xff) || (R0 == 0x00)));
+ //ASSERT(Index < 20); //this will cause BSOD on Check-build driver
+
+ if ((R0 == 0xff) || (R0 == 0x00))
+ return NDIS_STATUS_FAILURE;
+
+ // Initialize BBP register to default value
+ for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value);
+ }
+
+ // for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.
+ // RT3090 should not program BBP R84 to 0x19, otherwise TX will block.
+ if (((pAd->MACVersion&0xffff) != 0x0101) && (!IS_RT30xx(pAd)))
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
+
+// add by johnli, RF power sequence setup
+#ifdef RT30xx
+ if (IS_RT30xx(pAd))
+ { //update for RT3070/71/72/90/91/92.
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33);
+ }
+
+ if (IS_RT3090(pAd))
+ {
+ UCHAR bbpreg=0;
+
+ // enable DC filter
+ if ((pAd->MACVersion & 0xffff) >= 0x0211)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
+ }
+
+ // improve power consumption
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg);
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ // turn off tx DAC_1
+ bbpreg = (bbpreg | 0x20);
+ }
+
+ if (pAd->Antenna.field.RxPath == 1)
+ {
+ // turn off tx ADC_1
+ bbpreg &= (~0x2);
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg);
+
+ // improve power consumption in RT3071 Ver.E
+ if ((pAd->MACVersion & 0xffff) >= 0x0211)
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
+ bbpreg &= (~0x3);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
+ }
+ }
+#endif // RT30xx //
+// end johnli
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
+ }
+
+ if (pAd->MACVersion >= RALINK_2880E_VERSION && pAd->MACVersion < RALINK_3070_VERSION) // 3*3
+ {
+ // enlarge MAX_LEN_CFG
+ UINT32 csr;
+ RTMP_IO_READ32(pAd, MAX_LEN_CFG, &csr);
+ csr &= 0xFFF;
+ csr |= 0x2000;
+ RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
+ }
+
+#ifdef RT2870
+{
+ UCHAR MAC_Value[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0,0};
+
+ //Initialize WCID table
+ Value = 0xff;
+ for(Index =0 ;Index < 254;Index++)
+ {
+ RTUSBMultiWrite(pAd, (USHORT)(MAC_WCID_BASE + Index * 8), MAC_Value, 8);
+ }
+}
+#endif // RT2870 //
+
+ // Add radio off control
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pAd->StaCfg.bRadio == FALSE)
+ {
+// RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set Radio Off\n"));
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Clear raw counters
+ RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
+ RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
+ RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
+ RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
+ RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
+ RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
+
+ // ASIC will keep garbage value after boot
+ // Clear all seared key table when initial
+ // This routine can be ignored in radio-ON/OFF operation.
+ if (bHardReset)
+ {
+ for (KeyIdx = 0; KeyIdx < 4; KeyIdx++)
+ {
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4*KeyIdx, 0);
+ }
+
+ // Clear all pairwise key table when initial
+ for (KeyIdx = 0; KeyIdx < 256; KeyIdx++)
+ {
+ RTMP_IO_WRITE32(pAd, MAC_WCID_ATTRIBUTE_BASE + (KeyIdx * HW_WCID_ATTRI_SIZE), 1);
+ }
+ }
+
+ // assert HOST ready bit
+// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); // 2004-09-14 asked by Mark
+// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4);
+
+ // It isn't necessary to clear this space when not hard reset.
+ if (bHardReset == TRUE)
+ {
+ // clear all on-chip BEACON frame space
+ for (apidx = 0; apidx < HW_BEACON_MAX_COUNT; apidx++)
+ {
+ for (i = 0; i < HW_BEACON_OFFSET>>2; i+=4)
+ RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[apidx] + i, 0x00);
+ }
+ }
+#ifdef RT2870
+ AsicDisableSync(pAd);
+ // Clear raw counters
+ RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
+ RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
+ RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
+ RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
+ RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
+ RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
+ // Default PCI clock cycle per ms is different as default setting, which is based on PCI.
+ RTMP_IO_READ32(pAd, USB_CYC_CFG, &Counter);
+ Counter&=0xffffff00;
+ Counter|=0x000001e;
+ RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter);
+#endif // RT2870 //
+#ifdef RT30xx
+ pAd->bUseEfuse=FALSE;
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
+ pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
+ if(pAd->bUseEfuse)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse\n"));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
+
+ }
+#endif // RT30xx //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT.
+ if ((pAd->MACVersion&0xffff) != 0x0101)
+ RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x583f);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAsic\n"));
+ return NDIS_STATUS_SUCCESS;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Reset NIC Asics
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+ Reset NIC to initial state AS IS system boot up time.
+
+ ========================================================================
+*/
+VOID NICIssueReset(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 Value = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n"));
+
+ // Abort Tx, prevent ASIC from writing to Host memory
+ //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x001f0000);
+
+ // Disable Rx, register value supposed will remain after reset
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= (0xfffffff3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Issue reset and clear from reset state
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x03); // 2004-09-17 change from 0x01
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICIssueReset\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check ASIC registers and find any reason the system might hang
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ ========================================================================
+*/
+BOOLEAN NICCheckForHang(
+ IN PRTMP_ADAPTER pAd)
+{
+ return (FALSE);
+}
+
+VOID NICUpdateFifoStaCounters(
+ IN PRTMP_ADAPTER pAd)
+{
+ TX_STA_FIFO_STRUC StaFifo;
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR i = 0;
+ UCHAR pid = 0, wcid = 0;
+ CHAR reTry;
+ UCHAR succMCS;
+
+#ifdef RALINK_ATE
+ /* Nothing to do in ATE mode */
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ do
+ {
+ RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
+
+ if (StaFifo.field.bValid == 0)
+ break;
+
+ wcid = (UCHAR)StaFifo.field.wcid;
+
+
+ /* ignore NoACK and MGMT frame use 0xFF as WCID */
+ if ((StaFifo.field.TxAckRequired == 0) || (wcid >= MAX_LEN_OF_MAC_TABLE))
+ {
+ i++;
+ continue;
+ }
+
+ /* PID store Tx MCS Rate */
+ pid = (UCHAR)StaFifo.field.PidType;
+
+ pEntry = &pAd->MacTab.Content[wcid];
+
+ pEntry->DebugFIFOCount++;
+
+#ifdef DOT11_N_SUPPORT
+ if (StaFifo.field.TxBF) // 3*3
+ pEntry->TxBFCount++;
+#endif // DOT11_N_SUPPORT //
+
+#ifdef UAPSD_AP_SUPPORT
+ UAPSD_SP_AUE_Handle(pAd, pEntry, StaFifo.field.TxSuccess);
+#endif // UAPSD_AP_SUPPORT //
+
+ if (!StaFifo.field.TxSuccess)
+ {
+ pEntry->FIFOCount++;
+ pEntry->OneSecTxFailCount++;
+
+ if (pEntry->FIFOCount >= 1)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("#"));
+#ifdef DOT11_N_SUPPORT
+ pEntry->NoBADataCountDown = 64;
+#endif // DOT11_N_SUPPORT //
+
+ if(pEntry->PsMode == PWR_ACTIVE)
+ {
+#ifdef DOT11_N_SUPPORT
+ int tid;
+ for (tid=0; tid<NUM_OF_TID; tid++)
+ {
+ BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, FALSE);
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // Update the continuous transmission counter except PS mode
+ pEntry->ContinueTxFailCnt++;
+ }
+ else
+ {
+ // Clear the FIFOCount when sta in Power Save mode. Basically we assume
+ // this tx error happened due to sta just go to sleep.
+ pEntry->FIFOCount = 0;
+ pEntry->ContinueTxFailCnt = 0;
+ }
+ //pEntry->FIFOCount = 0;
+ }
+ //pEntry->bSendBAR = TRUE;
+ }
+ else
+ {
+#ifdef DOT11_N_SUPPORT
+ if ((pEntry->PsMode != PWR_SAVE) && (pEntry->NoBADataCountDown > 0))
+ {
+ pEntry->NoBADataCountDown--;
+ if (pEntry->NoBADataCountDown==0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("@\n"));
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+ pEntry->FIFOCount = 0;
+ pEntry->OneSecTxNoRetryOkCount++;
+ // update NoDataIdleCount when sucessful send packet to STA.
+ pEntry->NoDataIdleCount = 0;
+ pEntry->ContinueTxFailCnt = 0;
+ }
+
+ succMCS = StaFifo.field.SuccessRate & 0x7F;
+
+ reTry = pid - succMCS;
+
+ if (StaFifo.field.TxSuccess)
+ {
+ pEntry->TXMCSExpected[pid]++;
+ if (pid == succMCS)
+ {
+ pEntry->TXMCSSuccessful[pid]++;
+ }
+ else
+ {
+ pEntry->TXMCSAutoFallBack[pid][succMCS]++;
+ }
+ }
+ else
+ {
+ pEntry->TXMCSFailed[pid]++;
+ }
+
+ if (reTry > 0)
+ {
+ if ((pid >= 12) && succMCS <=7)
+ {
+ reTry -= 4;
+ }
+ pEntry->OneSecTxRetryOkCount += reTry;
+ }
+
+ i++;
+ // ASIC store 16 stack
+ } while ( i < (2*TX_RING_SIZE) );
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Read statistical counters from hardware registers and record them
+ in software variables for later on query
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ ========================================================================
+*/
+VOID NICUpdateRawCounters(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 OldValue;//, Value2;
+ //ULONG PageSum, OneSecTransmitCount;
+ //ULONG TxErrorRatio, Retry, Fail;
+ RX_STA_CNT0_STRUC RxStaCnt0;
+ RX_STA_CNT1_STRUC RxStaCnt1;
+ RX_STA_CNT2_STRUC RxStaCnt2;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT2_STRUC StaTx2;
+ TX_AGG_CNT_STRUC TxAggCnt;
+ TX_AGG_CNT0_STRUC TxAggCnt0;
+ TX_AGG_CNT1_STRUC TxAggCnt1;
+ TX_AGG_CNT2_STRUC TxAggCnt2;
+ TX_AGG_CNT3_STRUC TxAggCnt3;
+ TX_AGG_CNT4_STRUC TxAggCnt4;
+ TX_AGG_CNT5_STRUC TxAggCnt5;
+ TX_AGG_CNT6_STRUC TxAggCnt6;
+ TX_AGG_CNT7_STRUC TxAggCnt7;
+
+ RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word);
+ RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word);
+
+ {
+ RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word);
+ // Update RX PLCP error counter
+ pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr;
+ // Update False CCA counter
+ pAd->RalinkCounters.OneSecFalseCCACnt += RxStaCnt1.field.FalseCca;
+ }
+
+ // Update FCS counters
+ OldValue= pAd->WlanCounters.FCSErrorCount.u.LowPart;
+ pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr); // >> 7);
+ if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue)
+ pAd->WlanCounters.FCSErrorCount.u.HighPart++;
+
+ // Add FCS error count to private counters
+ pAd->RalinkCounters.OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
+ OldValue = pAd->RalinkCounters.RealFcsErrCount.u.LowPart;
+ pAd->RalinkCounters.RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
+ if (pAd->RalinkCounters.RealFcsErrCount.u.LowPart < OldValue)
+ pAd->RalinkCounters.RealFcsErrCount.u.HighPart++;
+
+ // Update Duplicate Rcv check
+ pAd->RalinkCounters.DuplicateRcv += RxStaCnt2.field.RxDupliCount;
+ pAd->WlanCounters.FrameDuplicateCount.u.LowPart += RxStaCnt2.field.RxDupliCount;
+ // Update RX Overflow counter
+ pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount);
+
+ //pAd->RalinkCounters.RxCount = 0;
+#ifdef RT2870
+ if (pAd->RalinkCounters.RxCount != pAd->watchDogRxCnt)
+ {
+ pAd->watchDogRxCnt = pAd->RalinkCounters.RxCount;
+ pAd->watchDogRxOverFlowCnt = 0;
+ }
+ else
+ {
+ if (RxStaCnt2.field.RxFifoOverflowCount)
+ pAd->watchDogRxOverFlowCnt++;
+ else
+ pAd->watchDogRxOverFlowCnt = 0;
+ }
+#endif // RT2870 //
+
+
+ //if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) ||
+ // (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1)))
+ if (!pAd->bUpdateBcnCntDone)
+ {
+ // Update BEACON sent count
+ RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+ RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
+ RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
+ pAd->RalinkCounters.OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount;
+ pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
+ pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
+ pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
+ pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
+ pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
+ pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
+ }
+
+ //if (pAd->bStaFifoTest == TRUE)
+ {
+ RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT1, &TxAggCnt1.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT2, &TxAggCnt2.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT3, &TxAggCnt3.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT4, &TxAggCnt4.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word);
+ pAd->RalinkCounters.TxAggCount += TxAggCnt.field.AggTxCount;
+ pAd->RalinkCounters.TxNonAggCount += TxAggCnt.field.NonAggTxCount;
+ pAd->RalinkCounters.TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count;
+ pAd->RalinkCounters.TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count;
+
+ pAd->RalinkCounters.TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count;
+ pAd->RalinkCounters.TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count;
+ pAd->RalinkCounters.TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count;
+ pAd->RalinkCounters.TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count;
+
+ pAd->RalinkCounters.TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count;
+ pAd->RalinkCounters.TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count;
+ pAd->RalinkCounters.TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count;
+ pAd->RalinkCounters.TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count;
+
+ pAd->RalinkCounters.TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count;
+ pAd->RalinkCounters.TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count;
+ pAd->RalinkCounters.TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count;
+ pAd->RalinkCounters.TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count;
+
+ pAd->RalinkCounters.TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count;
+ pAd->RalinkCounters.TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count;
+
+ // Calculate the transmitted A-MPDU count
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count;
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count / 2);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count / 4);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count / 8);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count / 16);
+ }
+
+#ifdef DBG_DIAGNOSE
+ {
+ RtmpDiagStruct *pDiag;
+ COUNTER_RALINK *pRalinkCounters;
+ UCHAR ArrayCurIdx, i;
+
+ pDiag = &pAd->DiagStruct;
+ pRalinkCounters = &pAd->RalinkCounters;
+ ArrayCurIdx = pDiag->ArrayCurIdx;
+
+ if (pDiag->inited == 0)
+ {
+ NdisZeroMemory(pDiag, sizeof(struct _RtmpDiagStrcut_));
+ pDiag->ArrayStartIdx = pDiag->ArrayCurIdx = 0;
+ pDiag->inited = 1;
+ }
+ else
+ {
+ // Tx
+ pDiag->TxFailCnt[ArrayCurIdx] = TxStaCnt0.field.TxFailCount;
+ pDiag->TxAggCnt[ArrayCurIdx] = TxAggCnt.field.AggTxCount;
+ pDiag->TxNonAggCnt[ArrayCurIdx] = TxAggCnt.field.NonAggTxCount;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][0] = TxAggCnt0.field.AggSize1Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][1] = TxAggCnt0.field.AggSize2Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][2] = TxAggCnt1.field.AggSize3Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][3] = TxAggCnt1.field.AggSize4Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][4] = TxAggCnt2.field.AggSize5Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][5] = TxAggCnt2.field.AggSize6Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][6] = TxAggCnt3.field.AggSize7Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][7] = TxAggCnt3.field.AggSize8Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][8] = TxAggCnt4.field.AggSize9Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][9] = TxAggCnt4.field.AggSize10Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][10] = TxAggCnt5.field.AggSize11Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][11] = TxAggCnt5.field.AggSize12Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][12] = TxAggCnt6.field.AggSize13Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][13] = TxAggCnt6.field.AggSize14Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][14] = TxAggCnt7.field.AggSize15Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][15] = TxAggCnt7.field.AggSize16Count;
+
+ pDiag->RxCrcErrCnt[ArrayCurIdx] = RxStaCnt0.field.CrcErr;
+
+ INC_RING_INDEX(pDiag->ArrayCurIdx, DIAGNOSE_TIME);
+ ArrayCurIdx = pDiag->ArrayCurIdx;
+ for (i =0; i < 9; i++)
+ {
+ pDiag->TxDescCnt[ArrayCurIdx][i]= 0;
+ pDiag->TxSWQueCnt[ArrayCurIdx][i] =0;
+ pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
+ pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
+ }
+ pDiag->TxDataCnt[ArrayCurIdx] = 0;
+ pDiag->TxFailCnt[ArrayCurIdx] = 0;
+ pDiag->RxDataCnt[ArrayCurIdx] = 0;
+ pDiag->RxCrcErrCnt[ArrayCurIdx] = 0;
+// for (i = 9; i < 16; i++)
+ for (i = 9; i < 24; i++) // 3*3
+ {
+ pDiag->TxDescCnt[ArrayCurIdx][i] = 0;
+ pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
+ pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
+}
+
+ if (pDiag->ArrayCurIdx == pDiag->ArrayStartIdx)
+ INC_RING_INDEX(pDiag->ArrayStartIdx, DIAGNOSE_TIME);
+ }
+
+ }
+#endif // DBG_DIAGNOSE //
+
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Reset NIC from error
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+ Reset NIC from error state
+
+ ========================================================================
+*/
+VOID NICResetFromError(
+ IN PRTMP_ADAPTER pAd)
+{
+ // Reset BBP (according to alex, reset ASIC will force reset BBP
+ // Therefore, skip the reset BBP
+ // RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x2);
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
+ // Remove ASIC from reset state
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+
+ NICInitializeAdapter(pAd, FALSE);
+ NICInitAsicFromEEPROM(pAd);
+
+ // Switch to current channel, since during reset process, the connection should remains on.
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ erase 8051 firmware image in MAC ASIC
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ IRQL = PASSIVE_LEVEL
+
+ ========================================================================
+*/
+VOID NICEraseFirmware(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG i;
+
+ for(i=0; i<MAX_FIRMWARE_IMAGE_SIZE; i+=4)
+ RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
+
+}/* End of NICEraseFirmware */
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Load 8051 firmware RT2561.BIN file into MAC ASIC
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ NDIS_STATUS_SUCCESS firmware image load ok
+ NDIS_STATUS_FAILURE image not found
+
+ IRQL = PASSIVE_LEVEL
+
+ ========================================================================
+*/
+NDIS_STATUS NICLoadFirmware(
+ IN PRTMP_ADAPTER pAd)
+{
+#ifdef BIN_IN_FILE
+#define NICLF_DEFAULT_USE() \
+ flg_default_firm_use = TRUE; \
+ printk("%s - Use default firmware!\n", __FUNCTION__);
+
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ PUCHAR src;
+ struct file *srcf;
+ INT retval, orgfsuid, orgfsgid, i;
+ mm_segment_t orgfs;
+ PUCHAR pFirmwareImage;
+ UINT FileLength = 0;
+ UINT32 MacReg;
+ ULONG Index;
+ ULONG firm;
+ BOOLEAN flg_default_firm_use = FALSE;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("===> %s\n", __FUNCTION__));
+
+ /* init */
+ pFirmwareImage = NULL;
+ src = RTMP_FIRMWARE_FILE_NAME;
+
+ /* save uid and gid used for filesystem access.
+ set user and group to 0 (root) */
+ orgfsuid = current->fsuid;
+ orgfsgid = current->fsgid;
+ current->fsuid = current->fsgid = 0;
+ orgfs = get_fs();
+ set_fs(KERNEL_DS);
+
+ pAd->FirmwareVersion = (FIRMWARE_MAJOR_VERSION << 8) + \
+ FIRMWARE_MINOR_VERSION;
+
+
+ /* allocate firmware buffer */
+ pFirmwareImage = kmalloc(MAX_FIRMWARE_IMAGE_SIZE, MEM_ALLOC_FLAG);
+ if (pFirmwareImage == NULL)
+ {
+ /* allocate fail, use default firmware array in firmware.h */
+ printk("%s - Allocate memory fail!\n", __FUNCTION__);
+ NICLF_DEFAULT_USE();
+ }
+ else
+ {
+ /* allocate ok! zero the firmware buffer */
+ memset(pFirmwareImage, 0x00, MAX_FIRMWARE_IMAGE_SIZE);
+ } /* End of if */
+
+
+ /* if ok, read firmware file from *.bin file */
+ if (flg_default_firm_use == FALSE)
+ {
+ do
+ {
+ /* open the bin file */
+ srcf = filp_open(src, O_RDONLY, 0);
+
+ if (IS_ERR(srcf))
+ {
+ printk("%s - Error %ld opening %s\n",
+ __FUNCTION__, -PTR_ERR(srcf), src);
+ NICLF_DEFAULT_USE();
+ break;
+ } /* End of if */
+
+ /* the object must have a read method */
+ if ((srcf->f_op == NULL) || (srcf->f_op->read == NULL))
+ {
+ printk("%s - %s does not have a write method\n", __FUNCTION__, src);
+ NICLF_DEFAULT_USE();
+ break;
+ } /* End of if */
+
+ /* read the firmware from the file *.bin */
+ FileLength = srcf->f_op->read(srcf,
+ pFirmwareImage,
+ MAX_FIRMWARE_IMAGE_SIZE,
+ &srcf->f_pos);
+
+ if (FileLength != MAX_FIRMWARE_IMAGE_SIZE)
+ {
+ printk("%s: error file length (=%d) in RT2860AP.BIN\n",
+ __FUNCTION__, FileLength);
+ NICLF_DEFAULT_USE();
+ break;
+ }
+ else
+ {
+ PUCHAR ptr = pFirmwareImage;
+ USHORT crc = 0xffff;
+
+
+ /* calculate firmware CRC */
+ for(i=0; i<(MAX_FIRMWARE_IMAGE_SIZE-2); i++, ptr++)
+ crc = ByteCRC16(BitReverse(*ptr), crc);
+ /* End of for */
+
+ if ((pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2] != \
+ (UCHAR)BitReverse((UCHAR)(crc>>8))) ||
+ (pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1] != \
+ (UCHAR)BitReverse((UCHAR)crc)))
+ {
+ /* CRC fail */
+ printk("%s: CRC = 0x%02x 0x%02x "
+ "error, should be 0x%02x 0x%02x\n",
+ __FUNCTION__,
+ pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2],
+ pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1],
+ (UCHAR)(crc>>8), (UCHAR)(crc));
+ NICLF_DEFAULT_USE();
+ break;
+ }
+ else
+ {
+ /* firmware is ok */
+ pAd->FirmwareVersion = \
+ (pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4] << 8) +
+ pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3];
+
+ /* check if firmware version of the file is too old */
+ if ((pAd->FirmwareVersion) < \
+ ((FIRMWARE_MAJOR_VERSION << 8) +
+ FIRMWARE_MINOR_VERSION))
+ {
+ printk("%s: firmware version too old!\n", __FUNCTION__);
+ NICLF_DEFAULT_USE();
+ break;
+ } /* End of if */
+ } /* End of if */
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("NICLoadFirmware: CRC ok, ver=%d.%d\n",
+ pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4],
+ pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3]));
+ } /* End of if (FileLength == MAX_FIRMWARE_IMAGE_SIZE) */
+ break;
+ } while(TRUE);
+
+ /* close firmware file */
+ if (IS_ERR(srcf))
+ ;
+ else
+ {
+ retval = filp_close(srcf, NULL);
+ if (retval)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("--> Error %d closing %s\n", -retval, src));
+ } /* End of if */
+ } /* End of if */
+ } /* End of if */
+
+
+ /* write firmware to ASIC */
+ if (flg_default_firm_use == TRUE)
+ {
+ /* use default fimeware, free allocated buffer */
+ if (pFirmwareImage != NULL)
+ kfree(pFirmwareImage);
+ /* End of if */
+
+ /* use default *.bin array */
+ pFirmwareImage = FirmwareImage;
+ FileLength = sizeof(FirmwareImage);
+ } /* End of if */
+
+ /* enable Host program ram write selection */
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x10000);
+
+ for(i=0; i<FileLength; i+=4)
+ {
+ firm = pFirmwareImage[i] +
+ (pFirmwareImage[i+3] << 24) +
+ (pFirmwareImage[i+2] << 16) +
+ (pFirmwareImage[i+1] << 8);
+
+ RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, firm);
+ } /* End of for */
+
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00000);
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00001);
+
+ /* initialize BBP R/W access agent */
+ RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);
+ RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
+
+ if (flg_default_firm_use == FALSE)
+ {
+ /* use file firmware, free allocated buffer */
+ if (pFirmwareImage != NULL)
+ kfree(pFirmwareImage);
+ /* End of if */
+ } /* End of if */
+
+ set_fs(orgfs);
+ current->fsuid = orgfsuid;
+ current->fsgid = orgfsgid;
+#else
+
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ PUCHAR pFirmwareImage;
+ ULONG FileLength, Index;
+ //ULONG firm;
+ UINT32 MacReg = 0;
+ UINT32 Version = (pAd->MACVersion >> 16);
+
+ pFirmwareImage = FirmwareImage;
+ FileLength = sizeof(FirmwareImage);
+
+ // New 8k byte firmware size for RT3071/RT3072
+ //printk("Usb Chip\n");
+ if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_MAX_LENGTH)
+ //The firmware image consists of two parts. One is the origianl and the other is the new.
+ //Use Second Part
+ {
+#ifdef RT2870
+ if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070))
+ { // Use Firmware V2.
+ //printk("KH:Use New Version,part2\n");
+ pFirmwareImage = (PUCHAR)&FirmwareImage[FIRMWAREIMAGEV1_LENGTH];
+ FileLength = FIRMWAREIMAGEV2_LENGTH;
+ }
+ else
+ {
+ //printk("KH:Use New Version,part1\n");
+ pFirmwareImage = FirmwareImage;
+ FileLength = FIRMWAREIMAGEV1_LENGTH;
+ }
+#endif // RT2870 //
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n"));
+ Status = NDIS_STATUS_FAILURE;
+ }
+
+ RT28XX_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
+
+#endif
+
+ /* check if MCU is ready */
+ Index = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
+
+ if (MacReg & 0x80)
+ break;
+
+ RTMPusecDelay(1000);
+ } while (Index++ < 1000);
+
+ if (Index >= 1000)
+ {
+ Status = NDIS_STATUS_FAILURE;
+ DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n"));
+ } /* End of if */
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("<=== %s (status=%d)\n", __FUNCTION__, Status));
+ return Status;
+} /* End of NICLoadFirmware */
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Load Tx rate switching parameters
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ NDIS_STATUS_SUCCESS firmware image load ok
+ NDIS_STATUS_FAILURE image not found
+
+ IRQL = PASSIVE_LEVEL
+
+ Rate Table Format:
+ 1. (B0: Valid Item number) (B1:Initial item from zero)
+ 2. Item Number(Dec) Mode(Hex) Current MCS(Dec) TrainUp(Dec) TrainDown(Dec)
+
+ ========================================================================
+*/
+NDIS_STATUS NICLoadRateSwitchingParams(
+ IN PRTMP_ADAPTER pAd)
+{
+ return NDIS_STATUS_SUCCESS;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ if pSrc1 all zero with length Length, return 0.
+ If not all zero, return 1
+
+ Arguments:
+ pSrc1
+
+ Return Value:
+ 1: not all zero
+ 0: all zero
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+ULONG RTMPNotAllZero(
+ IN PVOID pSrc1,
+ IN ULONG Length)
+{
+ PUCHAR pMem1;
+ ULONG Index = 0;
+
+ pMem1 = (PUCHAR) pSrc1;
+
+ for (Index = 0; Index < Length; Index++)
+ {
+ if (pMem1[Index] != 0x0)
+ {
+ break;
+ }
+ }
+
+ if (Index == Length)
+ {
+ return (0);
+ }
+ else
+ {
+ return (1);
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Compare two memory block
+
+ Arguments:
+ pSrc1 Pointer to first memory address
+ pSrc2 Pointer to second memory address
+
+ Return Value:
+ 0: memory is equal
+ 1: pSrc1 memory is larger
+ 2: pSrc2 memory is larger
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+ULONG RTMPCompareMemory(
+ IN PVOID pSrc1,
+ IN PVOID pSrc2,
+ IN ULONG Length)
+{
+ PUCHAR pMem1;
+ PUCHAR pMem2;
+ ULONG Index = 0;
+
+ pMem1 = (PUCHAR) pSrc1;
+ pMem2 = (PUCHAR) pSrc2;
+
+ for (Index = 0; Index < Length; Index++)
+ {
+ if (pMem1[Index] > pMem2[Index])
+ return (1);
+ else if (pMem1[Index] < pMem2[Index])
+ return (2);
+ }
+
+ // Equal
+ return (0);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Zero out memory block
+
+ Arguments:
+ pSrc1 Pointer to memory address
+ Length Size
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPZeroMemory(
+ IN PVOID pSrc,
+ IN ULONG Length)
+{
+ PUCHAR pMem;
+ ULONG Index = 0;
+
+ pMem = (PUCHAR) pSrc;
+
+ for (Index = 0; Index < Length; Index++)
+ {
+ pMem[Index] = 0x00;
+ }
+}
+
+VOID RTMPFillMemory(
+ IN PVOID pSrc,
+ IN ULONG Length,
+ IN UCHAR Fill)
+{
+ PUCHAR pMem;
+ ULONG Index = 0;
+
+ pMem = (PUCHAR) pSrc;
+
+ for (Index = 0; Index < Length; Index++)
+ {
+ pMem[Index] = Fill;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Copy data from memory block 1 to memory block 2
+
+ Arguments:
+ pDest Pointer to destination memory address
+ pSrc Pointer to source memory address
+ Length Copy size
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPMoveMemory(
+ OUT PVOID pDest,
+ IN PVOID pSrc,
+ IN ULONG Length)
+{
+ PUCHAR pMem1;
+ PUCHAR pMem2;
+ UINT Index;
+
+ ASSERT((Length==0) || (pDest && pSrc));
+
+ pMem1 = (PUCHAR) pDest;
+ pMem2 = (PUCHAR) pSrc;
+
+ for (Index = 0; Index < Length; Index++)
+ {
+ pMem1[Index] = pMem2[Index];
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Initialize port configuration structure
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID UserCfgInit(
+ IN PRTMP_ADAPTER pAd)
+{
+// EDCA_PARM DefaultEdcaParm;
+ UINT key_index, bss_index;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n"));
+
+ //
+ // part I. intialize common configuration
+ //
+#ifdef RT2870
+ pAd->BulkOutReq = 0;
+
+ pAd->BulkOutComplete = 0;
+ pAd->BulkOutCompleteOther = 0;
+ pAd->BulkOutCompleteCancel = 0;
+ pAd->BulkInReq = 0;
+ pAd->BulkInComplete = 0;
+ pAd->BulkInCompleteFail = 0;
+
+ //pAd->QuickTimerP = 100;
+ //pAd->TurnAggrBulkInCount = 0;
+ pAd->bUsbTxBulkAggre = 0;
+
+ // init as unsed value to ensure driver will set to MCU once.
+ pAd->LedIndicatorStregth = 0xFF;
+
+ pAd->CommonCfg.MaxPktOneTxBulk = 2;
+ pAd->CommonCfg.TxBulkFactor = 1;
+ pAd->CommonCfg.RxBulkFactor =1;
+
+ pAd->CommonCfg.TxPower = 100; //mW
+
+ NdisZeroMemory(&pAd->CommonCfg.IOTestParm, sizeof(pAd->CommonCfg.IOTestParm));
+#endif // RT2870 //
+
+ for(key_index=0; key_index<SHARE_KEY_NUM; key_index++)
+ {
+ for(bss_index = 0; bss_index < MAX_MBSSID_NUM; bss_index++)
+ {
+ pAd->SharedKey[bss_index][key_index].KeyLen = 0;
+ pAd->SharedKey[bss_index][key_index].CipherAlg = CIPHER_NONE;
+ } /* End of for */
+ } /* End of for */
+
+ pAd->EepromAccess = FALSE;
+
+ pAd->Antenna.word = 0;
+ pAd->CommonCfg.BBPCurrentBW = BW_20;
+
+ pAd->LedCntl.word = 0;
+
+ pAd->bAutoTxAgcA = FALSE; // Default is OFF
+ pAd->bAutoTxAgcG = FALSE; // Default is OFF
+ pAd->RfIcType = RFIC_2820;
+
+ // Init timer for reset complete event
+ pAd->CommonCfg.CentralChannel = 1;
+ pAd->bForcePrintTX = FALSE;
+ pAd->bForcePrintRX = FALSE;
+ pAd->bStaFifoTest = FALSE;
+ pAd->bProtectionTest = FALSE;
+ pAd->bHCCATest = FALSE;
+ pAd->bGenOneHCCA = FALSE;
+ pAd->CommonCfg.Dsifs = 10; // in units of usec
+ pAd->CommonCfg.TxPower = 100; //mW
+ pAd->CommonCfg.TxPowerPercentage = 0xffffffff; // AUTO
+ pAd->CommonCfg.TxPowerDefault = 0xffffffff; // AUTO
+ pAd->CommonCfg.TxPreamble = Rt802_11PreambleAuto; // use Long preamble on TX by defaut
+ pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
+ pAd->CommonCfg.RtsThreshold = 2347;
+ pAd->CommonCfg.FragmentThreshold = 2346;
+ pAd->CommonCfg.UseBGProtection = 0; // 0: AUTO
+ pAd->CommonCfg.bEnableTxBurst = TRUE; //0;
+ pAd->CommonCfg.PhyMode = 0xff; // unknown
+ pAd->CommonCfg.BandState = UNKNOWN_BAND;
+ pAd->CommonCfg.RadarDetect.CSPeriod = 10;
+ pAd->CommonCfg.RadarDetect.CSCount = 0;
+ pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
+ pAd->CommonCfg.RadarDetect.ChMovingTime = 65;
+ pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3;
+ pAd->CommonCfg.bAPSDCapable = FALSE;
+ pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
+ pAd->CommonCfg.TriggerTimerCount = 0;
+ pAd->CommonCfg.bAPSDForcePowerSave = FALSE;
+ pAd->CommonCfg.bCountryFlag = FALSE;
+ pAd->CommonCfg.TxStream = 0;
+ pAd->CommonCfg.RxStream = 0;
+
+ NdisZeroMemory(&pAd->BeaconTxWI, sizeof(pAd->BeaconTxWI));
+
+#ifdef DOT11_N_SUPPORT
+ NdisZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
+ pAd->HTCEnable = FALSE;
+ pAd->bBroadComHT = FALSE;
+ pAd->CommonCfg.bRdg = FALSE;
+
+#ifdef DOT11N_DRAFT3
+ pAd->CommonCfg.Dot11OBssScanPassiveDwell = dot11OBSSScanPassiveDwell; // Unit : TU. 5~1000
+ pAd->CommonCfg.Dot11OBssScanActiveDwell = dot11OBSSScanActiveDwell; // Unit : TU. 10~1000
+ pAd->CommonCfg.Dot11BssWidthTriggerScanInt = dot11BSSWidthTriggerScanInterval; // Unit : Second
+ pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = dot11OBSSScanPassiveTotalPerChannel; // Unit : TU. 200~10000
+ pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = dot11OBSSScanActiveTotalPerChannel; // Unit : TU. 20~10000
+ pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = dot11BSSWidthChannelTransactionDelayFactor;
+ pAd->CommonCfg.Dot11OBssScanActivityThre = dot11BSSScanActivityThreshold; // Unit : percentage
+ pAd->CommonCfg.Dot11BssWidthChanTranDelay = (pAd->CommonCfg.Dot11BssWidthTriggerScanInt * pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor);
+#endif // DOT11N_DRAFT3 //
+
+ NdisZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
+ pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
+ pAd->CommonCfg.BACapability.field.MpduDensity = 0;
+ pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
+ pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; //32;
+ pAd->CommonCfg.BACapability.field.TxBAWinLimit = 64; //32;
+ DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit. BACapability = 0x%x\n", pAd->CommonCfg.BACapability.word));
+
+ pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
+ BATableInit(pAd, &pAd->BATable);
+
+ pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1;
+ pAd->CommonCfg.bHTProtect = 1;
+ pAd->CommonCfg.bMIMOPSEnable = TRUE;
+ pAd->CommonCfg.bBADecline = FALSE;
+ pAd->CommonCfg.bDisableReordering = FALSE;
+
+ pAd->CommonCfg.TxBASize = 7;
+
+ pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
+#endif // DOT11_N_SUPPORT //
+
+ //pAd->CommonCfg.HTPhyMode.field.BW = BW_20;
+ //pAd->CommonCfg.HTPhyMode.field.MCS = MCS_AUTO;
+ //pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800;
+ //pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE;
+ pAd->CommonCfg.TxRate = RATE_6;
+
+ pAd->CommonCfg.MlmeTransmit.field.MCS = MCS_RATE_6;
+ pAd->CommonCfg.MlmeTransmit.field.BW = BW_20;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+
+ pAd->CommonCfg.BeaconPeriod = 100; // in mSec
+
+ //
+ // part II. intialize STA specific configuration
+ //
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_DIRECT);
+ RX_FILTER_CLEAR_FLAG(pAd, fRX_FILTER_ACCEPT_MULTICAST);
+ RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_BROADCAST);
+ RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_ALL_MULTICAST);
+
+ pAd->StaCfg.Psm = PWR_ACTIVE;
+
+ pAd->StaCfg.OrigWepStatus = Ndis802_11EncryptionDisabled;
+ pAd->StaCfg.PairCipher = Ndis802_11EncryptionDisabled;
+ pAd->StaCfg.GroupCipher = Ndis802_11EncryptionDisabled;
+ pAd->StaCfg.bMixCipher = FALSE;
+ pAd->StaCfg.DefaultKeyId = 0;
+
+ // 802.1x port control
+ pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ pAd->StaCfg.LastMicErrorTime = 0;
+ pAd->StaCfg.MicErrCnt = 0;
+ pAd->StaCfg.bBlockAssoc = FALSE;
+ pAd->StaCfg.WpaState = SS_NOTUSE;
+
+ pAd->CommonCfg.NdisRadioStateOff = FALSE; // New to support microsoft disable radio with OID command
+
+ pAd->StaCfg.RssiTrigger = 0;
+ NdisZeroMemory(&pAd->StaCfg.RssiSample, sizeof(RSSI_SAMPLE));
+ pAd->StaCfg.RssiTriggerMode = RSSI_TRIGGERED_UPON_BELOW_THRESHOLD;
+ pAd->StaCfg.AtimWin = 0;
+ pAd->StaCfg.DefaultListenCount = 3;//default listen count;
+ pAd->StaCfg.BssType = BSS_INFRA; // BSS_INFRA or BSS_ADHOC or BSS_MONITOR
+ pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
+
+ pAd->StaCfg.bAutoTxRateSwitch = TRUE;
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ }
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ pAd->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+
+ // global variables mXXXX used in MAC protocol state machines
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
+
+ // PHY specification
+ pAd->CommonCfg.PhyMode = PHY_11BG_MIXED; // default PHY mode
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); // CCK use LONG preamble
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // user desired power mode
+ pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
+ pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
+ pAd->StaCfg.bWindowsACCAMEnable = FALSE;
+
+#ifdef LEAP_SUPPORT
+ // CCX v1.0 releated init value
+ RTMPInitTimer(pAd, &pAd->StaCfg.LeapAuthTimer, GET_TIMER_FUNCTION(LeapAuthTimeout), pAd, FALSE);
+ pAd->StaCfg.LeapAuthMode = CISCO_AuthModeLEAPNone;
+ pAd->StaCfg.bCkipOn = FALSE;
+#endif // LEAP_SUPPORT //
+
+ RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer, GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec), pAd, FALSE);
+ pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
+
+ // Patch for Ndtest
+ pAd->StaCfg.ScanCnt = 0;
+
+ // CCX 2.0 control flag init
+ pAd->StaCfg.CCXEnable = FALSE;
+ pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
+ pAd->StaCfg.CCXQosECWMin = 4;
+ pAd->StaCfg.CCXQosECWMax = 10;
+
+ pAd->StaCfg.bHwRadio = TRUE; // Default Hardware Radio status is On
+ pAd->StaCfg.bSwRadio = TRUE; // Default Software Radio status is On
+ pAd->StaCfg.bRadio = TRUE; // bHwRadio && bSwRadio
+ pAd->StaCfg.bHardwareRadio = FALSE; // Default is OFF
+ pAd->StaCfg.bShowHiddenSSID = FALSE; // Default no show
+
+ // Nitro mode control
+ pAd->StaCfg.bAutoReconnect = TRUE;
+
+ // Save the init time as last scan time, the system should do scan after 2 seconds.
+ // This patch is for driver wake up from standby mode, system will do scan right away.
+ pAd->StaCfg.LastScanTime = 0;
+ NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1);
+ sprintf(pAd->nickname, "%s", STA_NIC_DEVICE_NAME);
+ RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer, GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc), pAd, FALSE);
+#ifdef WPA_SUPPLICANT_SUPPORT
+ pAd->StaCfg.IEEE8021X = FALSE;
+ pAd->StaCfg.IEEE8021x_required_keys = FALSE;
+ pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Default for extra information is not valid
+ pAd->ExtraInfo = EXTRA_INFO_CLEAR;
+
+ // Default Config change flag
+ pAd->bConfigChanged = FALSE;
+
+ //
+ // part III. AP configurations
+ //
+
+
+ //
+ // part IV. others
+ //
+ // dynamic BBP R66:sensibity tuning to overcome background noise
+ pAd->BbpTuning.bEnable = TRUE;
+ pAd->BbpTuning.FalseCcaLowerThreshold = 100;
+ pAd->BbpTuning.FalseCcaUpperThreshold = 512;
+ pAd->BbpTuning.R66Delta = 4;
+ pAd->Mlme.bEnableAutoAntennaCheck = TRUE;
+
+ //
+ // Also initial R66CurrentValue, RTUSBResumeMsduTransmission might use this value.
+ // if not initial this value, the default value will be 0.
+ //
+ pAd->BbpTuning.R66CurrentValue = 0x38;
+
+ pAd->Bbp94 = BBPR94_DEFAULT;
+ pAd->BbpForCCK = FALSE;
+
+ // Default is FALSE for test bit 1
+ //pAd->bTest1 = FALSE;
+
+ // initialize MAC table and allocate spin lock
+ NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
+ InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
+ NdisAllocateSpinLock(&pAd->MacTabLock);
+
+ //RTMPInitTimer(pAd, &pAd->RECBATimer, RECBATimerTimeout, pAd, TRUE);
+ //RTMPSetTimer(&pAd->RECBATimer, REORDER_EXEC_INTV);
+
+#ifdef RALINK_ATE
+ NdisZeroMemory(&pAd->ate, sizeof(ATE_INFO));
+ pAd->ate.Mode = ATE_STOP;
+ pAd->ate.TxCount = 200;/* to exceed TX_RING_SIZE ... */
+ pAd->ate.TxLength = 1024;
+ pAd->ate.TxWI.ShortGI = 0;// LONG GI : 800 ns
+ pAd->ate.TxWI.PHYMODE = MODE_CCK;
+ pAd->ate.TxWI.MCS = 3;
+ pAd->ate.TxWI.BW = BW_20;
+ pAd->ate.Channel = 1;
+ pAd->ate.QID = QID_AC_BE;
+ pAd->ate.Addr1[0] = 0x00;
+ pAd->ate.Addr1[1] = 0x11;
+ pAd->ate.Addr1[2] = 0x22;
+ pAd->ate.Addr1[3] = 0xAA;
+ pAd->ate.Addr1[4] = 0xBB;
+ pAd->ate.Addr1[5] = 0xCC;
+ NdisMoveMemory(pAd->ate.Addr2, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
+ NdisMoveMemory(pAd->ate.Addr3, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
+ pAd->ate.bRxFer = 0;
+ pAd->ate.bQATxStart = FALSE;
+ pAd->ate.bQARxStart = FALSE;
+#ifdef RALINK_28xx_QA
+ //pAd->ate.Repeat = 0;
+ pAd->ate.TxStatus = 0;
+ pAd->ate.AtePid = 0;
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+
+ pAd->CommonCfg.bWiFiTest = FALSE;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
+}
+
+// IRQL = PASSIVE_LEVEL
+UCHAR BtoH(char ch)
+{
+ if (ch >= '0' && ch <= '9') return (ch - '0'); // Handle numerals
+ if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA); // Handle capitol hex digits
+ if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 0xA); // Handle small hex digits
+ return(255);
+}
+
+//
+// FUNCTION: AtoH(char *, UCHAR *, int)
+//
+// PURPOSE: Converts ascii string to network order hex
+//
+// PARAMETERS:
+// src - pointer to input ascii string
+// dest - pointer to output hex
+// destlen - size of dest
+//
+// COMMENTS:
+//
+// 2 ascii bytes make a hex byte so must put 1st ascii byte of pair
+// into upper nibble and 2nd ascii byte of pair into lower nibble.
+//
+// IRQL = PASSIVE_LEVEL
+
+void AtoH(char * src, UCHAR * dest, int destlen)
+{
+ char * srcptr;
+ PUCHAR destTemp;
+
+ srcptr = src;
+ destTemp = (PUCHAR) dest;
+
+ while(destlen--)
+ {
+ *destTemp = BtoH(*srcptr++) << 4; // Put 1st ascii byte in upper nibble.
+ *destTemp += BtoH(*srcptr++); // Add 2nd ascii byte to above.
+ destTemp++;
+ }
+}
+
+VOID RTMPPatchMacBbpBug(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG Index;
+
+ // Initialize BBP register to default value
+ for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, (UCHAR)BBPRegTable[Index].Value);
+ }
+
+ // Initialize RF register to default value
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+ // Re-init BBP register from EEPROM value
+ NICInitAsicFromEEPROM(pAd);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init timer objects
+
+ Arguments:
+ pAd Pointer to our adapter
+ pTimer Timer structure
+ pTimerFunc Function to execute when timer expired
+ Repeat Ture for period timer
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPInitTimer(
+ IN PRTMP_ADAPTER pAd,
+ IN PRALINK_TIMER_STRUCT pTimer,
+ IN PVOID pTimerFunc,
+ IN PVOID pData,
+ IN BOOLEAN Repeat)
+{
+ //
+ // Set Valid to TRUE for later used.
+ // It will crash if we cancel a timer or set a timer
+ // that we haven't initialize before.
+ //
+ pTimer->Valid = TRUE;
+
+ pTimer->PeriodicType = Repeat;
+ pTimer->State = FALSE;
+ pTimer->cookie = (ULONG) pData;
+
+#ifdef RT2870
+ pTimer->pAd = pAd;
+#endif // RT2870 //
+
+ RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (PVOID) pTimer);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init timer objects
+
+ Arguments:
+ pTimer Timer structure
+ Value Timer value in milliseconds
+
+ Return Value:
+ None
+
+ Note:
+ To use this routine, must call RTMPInitTimer before.
+
+ ========================================================================
+*/
+VOID RTMPSetTimer(
+ IN PRALINK_TIMER_STRUCT pTimer,
+ IN ULONG Value)
+{
+ if (pTimer->Valid)
+ {
+ pTimer->TimerValue = Value;
+ pTimer->State = FALSE;
+ if (pTimer->PeriodicType == TRUE)
+ {
+ pTimer->Repeat = TRUE;
+ RTMP_SetPeriodicTimer(&pTimer->TimerObj, Value);
+ }
+ else
+ {
+ pTimer->Repeat = FALSE;
+ RTMP_OS_Add_Timer(&pTimer->TimerObj, Value);
+ }
+ }
+ else
+ {
+ DBGPRINT_ERR(("RTMPSetTimer failed, Timer hasn't been initialize!\n"));
+ }
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init timer objects
+
+ Arguments:
+ pTimer Timer structure
+ Value Timer value in milliseconds
+
+ Return Value:
+ None
+
+ Note:
+ To use this routine, must call RTMPInitTimer before.
+
+ ========================================================================
+*/
+VOID RTMPModTimer(
+ IN PRALINK_TIMER_STRUCT pTimer,
+ IN ULONG Value)
+{
+ BOOLEAN Cancel;
+
+ if (pTimer->Valid)
+ {
+ pTimer->TimerValue = Value;
+ pTimer->State = FALSE;
+ if (pTimer->PeriodicType == TRUE)
+ {
+ RTMPCancelTimer(pTimer, &Cancel);
+ RTMPSetTimer(pTimer, Value);
+ }
+ else
+ {
+ RTMP_OS_Mod_Timer(&pTimer->TimerObj, Value);
+ }
+ }
+ else
+ {
+ DBGPRINT_ERR(("RTMPModTimer failed, Timer hasn't been initialize!\n"));
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Cancel timer objects
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ 1.) To use this routine, must call RTMPInitTimer before.
+ 2.) Reset NIC to initial state AS IS system boot up time.
+
+ ========================================================================
+*/
+VOID RTMPCancelTimer(
+ IN PRALINK_TIMER_STRUCT pTimer,
+ OUT BOOLEAN *pCancelled)
+{
+ if (pTimer->Valid)
+ {
+ if (pTimer->State == FALSE)
+ pTimer->Repeat = FALSE;
+ RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled);
+
+ if (*pCancelled == TRUE)
+ pTimer->State = TRUE;
+
+#ifdef RT2870
+ // We need to go-through the TimerQ to findout this timer handler and remove it if
+ // it's still waiting for execution.
+
+ RT2870_TimerQ_Remove(pTimer->pAd, pTimer);
+#endif // RT2870 //
+ }
+ else
+ {
+ //
+ // NdisMCancelTimer just canced the timer and not mean release the timer.
+ // And don't set the "Valid" to False. So that we can use this timer again.
+ //
+ DBGPRINT_ERR(("RTMPCancelTimer failed, Timer hasn't been initialize!\n"));
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set LED Status
+
+ Arguments:
+ pAd Pointer to our adapter
+ Status LED Status
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPSetLED(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Status)
+{
+ //ULONG data;
+ UCHAR HighByte = 0;
+ UCHAR LowByte;
+
+// In ATE mode of RT2860 AP/STA, we have erased 8051 firmware.
+// So LED mode is not supported when ATE is running.
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ LowByte = pAd->LedCntl.field.LedMode&0x7f;
+ switch (Status)
+ {
+ case LED_LINK_DOWN:
+ HighByte = 0x20;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ pAd->LedIndicatorStregth = 0;
+ break;
+ case LED_LINK_UP:
+ if (pAd->CommonCfg.Channel > 14)
+ HighByte = 0xa0;
+ else
+ HighByte = 0x60;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ break;
+ case LED_RADIO_ON:
+ HighByte = 0x20;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ break;
+ case LED_HALT:
+ LowByte = 0; // Driver sets MAC register and MAC controls LED
+ case LED_RADIO_OFF:
+ HighByte = 0;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ break;
+ case LED_WPS:
+ HighByte = 0x10;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ break;
+ case LED_ON_SITE_SURVEY:
+ HighByte = 0x08;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ break;
+ case LED_POWER_UP:
+ HighByte = 0x04;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_WARN, ("RTMPSetLED::Unknown Status %d\n", Status));
+ break;
+ }
+
+ //
+ // Keep LED status for LED SiteSurvey mode.
+ // After SiteSurvey, we will set the LED mode to previous status.
+ //
+ if ((Status != LED_ON_SITE_SURVEY) && (Status != LED_POWER_UP))
+ pAd->LedStatus = Status;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetLED::Mode=%d,HighByte=0x%02x,LowByte=0x%02x\n", pAd->LedCntl.field.LedMode, HighByte, LowByte));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set LED Signal Stregth
+
+ Arguments:
+ pAd Pointer to our adapter
+ Dbm Signal Stregth
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+ Can be run on any IRQL level.
+
+ According to Microsoft Zero Config Wireless Signal Stregth definition as belows.
+ <= -90 No Signal
+ <= -81 Very Low
+ <= -71 Low
+ <= -67 Good
+ <= -57 Very Good
+ > -57 Excellent
+ ========================================================================
+*/
+VOID RTMPSetSignalLED(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_802_11_RSSI Dbm)
+{
+ UCHAR nLed = 0;
+
+ //
+ // if not Signal Stregth, then do nothing.
+ //
+ if (pAd->LedCntl.field.LedMode != LED_MODE_SIGNAL_STREGTH)
+ {
+ return;
+ }
+
+ if (Dbm <= -90)
+ nLed = 0;
+ else if (Dbm <= -81)
+ nLed = 1;
+ else if (Dbm <= -71)
+ nLed = 3;
+ else if (Dbm <= -67)
+ nLed = 7;
+ else if (Dbm <= -57)
+ nLed = 15;
+ else
+ nLed = 31;
+
+ //
+ // Update Signal Stregth to firmware if changed.
+ //
+ if (pAd->LedIndicatorStregth != nLed)
+ {
+ AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, pAd->LedCntl.field.Polarity);
+ pAd->LedIndicatorStregth = nLed;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Enable RX
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL <= DISPATCH_LEVEL
+
+ Note:
+ Before Enable RX, make sure you have enabled Interrupt.
+ ========================================================================
+*/
+VOID RTMPEnableRxTx(
+ IN PRTMP_ADAPTER pAd)
+{
+// WPDMA_GLO_CFG_STRUC GloCfg;
+// ULONG i = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n"));
+
+ // Enable Rx DMA.
+ RT28XXDMAEnable(pAd);
+
+ // enable RX of MAC block
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ UINT32 rx_filter_flag = APNORMAL;
+
+
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); // enable RX of DMA block
+ }
+ else
+ {
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
+ }
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
+ DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n"));
+}
+
+
diff --git a/drivers/staging/rt3070/common/rtmp_tkip.c b/drivers/staging/rt3070/common/rtmp_tkip.c
new file mode 100644
index 00000000000..bf8986e8367
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtmp_tkip.c
@@ -0,0 +1,1613 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_tkip.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Wu 02-25-02 Initial
+*/
+
+#include "../rt_config.h"
+
+// 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) )
+
+UINT Tkip_Sbox_Lower[256] =
+{
+ 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
+ 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
+ 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
+ 0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B,
+ 0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F,
+ 0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F,
+ 0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5,
+ 0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F,
+ 0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB,
+ 0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97,
+ 0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED,
+ 0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A,
+ 0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94,
+ 0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3,
+ 0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04,
+ 0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D,
+ 0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39,
+ 0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95,
+ 0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83,
+ 0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76,
+ 0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4,
+ 0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B,
+ 0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0,
+ 0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18,
+ 0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51,
+ 0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85,
+ 0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12,
+ 0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9,
+ 0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7,
+ 0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A,
+ 0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8,
+ 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
+};
+
+UINT Tkip_Sbox_Upper[256] =
+{
+ 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
+ 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
+ 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
+ 0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B,
+ 0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83,
+ 0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A,
+ 0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F,
+ 0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA,
+ 0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B,
+ 0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13,
+ 0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6,
+ 0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85,
+ 0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11,
+ 0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B,
+ 0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1,
+ 0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF,
+ 0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E,
+ 0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6,
+ 0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B,
+ 0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD,
+ 0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8,
+ 0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2,
+ 0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49,
+ 0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10,
+ 0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97,
+ 0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F,
+ 0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C,
+ 0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27,
+ 0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33,
+ 0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5,
+ 0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0,
+ 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
+};
+
+/*****************************/
+/******** SBOX Table *********/
+/*****************************/
+
+UCHAR SboxTable[256] =
+{
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+VOID xor_32(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out);
+
+VOID xor_128(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out);
+
+VOID next_key(
+ IN PUCHAR key,
+ IN INT round);
+
+VOID byte_sub(
+ IN PUCHAR in,
+ OUT PUCHAR out);
+
+VOID shift_row(
+ IN PUCHAR in,
+ OUT PUCHAR out);
+
+VOID mix_column(
+ IN PUCHAR in,
+ OUT PUCHAR out);
+
+UCHAR RTMPCkipSbox(
+ IN UCHAR a);
+//
+// Expanded IV for TKIP function.
+//
+typedef struct PACKED _IV_CONTROL_
+{
+ union PACKED
+ {
+ struct PACKED
+ {
+ UCHAR rc0;
+ UCHAR rc1;
+ UCHAR rc2;
+
+ union PACKED
+ {
+ struct PACKED
+ {
+#ifdef RT_BIG_ENDIAN
+ UCHAR KeyID:2;
+ UCHAR ExtIV:1;
+ UCHAR Rsvd:5;
+#else
+ UCHAR Rsvd:5;
+ UCHAR ExtIV:1;
+ UCHAR KeyID:2;
+#endif
+ } field;
+ UCHAR Byte;
+ } CONTROL;
+ } field;
+
+ ULONG word;
+ } IV16;
+
+ ULONG IV32;
+} TKIP_IV, *PTKIP_IV;
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Convert from UCHAR[] to ULONG in a portable way
+
+ Arguments:
+ pMICKey pointer to MIC Key
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+ULONG RTMPTkipGetUInt32(
+ IN PUCHAR pMICKey)
+{
+ ULONG res = 0;
+ INT i;
+
+ for (i = 0; i < 4; i++)
+ {
+ res |= (*pMICKey++) << (8 * i);
+ }
+
+ return res;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Convert from ULONG to UCHAR[] in a portable way
+
+ Arguments:
+ pDst pointer to destination for convert ULONG to UCHAR[]
+ val the value for convert
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPTkipPutUInt32(
+ IN OUT PUCHAR pDst,
+ IN ULONG val)
+{
+ INT i;
+
+ for(i = 0; i < 4; i++)
+ {
+ *pDst++ = (UCHAR) (val & 0xff);
+ val >>= 8;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set the MIC Key.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pMICKey pointer to MIC Key
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPTkipSetMICKey(
+ IN PTKIP_KEY_INFO pTkip,
+ IN PUCHAR pMICKey)
+{
+ // Set the key
+ pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
+ pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
+ // and reset the message
+ pTkip->L = pTkip->K0;
+ pTkip->R = pTkip->K1;
+ pTkip->nBytesInM = 0;
+ pTkip->M = 0;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculate the MIC Value.
+
+ Arguments:
+ pAd Pointer to our adapter
+ uChar Append this uChar
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPTkipAppendByte(
+ IN PTKIP_KEY_INFO pTkip,
+ IN UCHAR uChar)
+{
+ // Append the byte to our word-sized buffer
+ pTkip->M |= (uChar << (8* pTkip->nBytesInM));
+ pTkip->nBytesInM++;
+ // Process the word if it is full.
+ if( pTkip->nBytesInM >= 4 )
+ {
+ pTkip->L ^= pTkip->M;
+ pTkip->R ^= ROL32( pTkip->L, 17 );
+ pTkip->L += pTkip->R;
+ pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8);
+ pTkip->L += pTkip->R;
+ pTkip->R ^= ROL32( pTkip->L, 3 );
+ pTkip->L += pTkip->R;
+ pTkip->R ^= ROR32( pTkip->L, 2 );
+ pTkip->L += pTkip->R;
+ // Clear the buffer
+ pTkip->M = 0;
+ pTkip->nBytesInM = 0;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculate the MIC Value.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pSrc Pointer to source data for Calculate MIC Value
+ Len Indicate the length of the source data
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPTkipAppend(
+ IN PTKIP_KEY_INFO pTkip,
+ IN PUCHAR pSrc,
+ IN UINT nBytes)
+{
+ // This is simple
+ while(nBytes > 0)
+ {
+ RTMPTkipAppendByte(pTkip, *pSrc++);
+ nBytes--;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get the MIC Value.
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ the MIC Value is store in pAd->PrivateInfo.MIC
+ ========================================================================
+*/
+VOID RTMPTkipGetMIC(
+ IN PTKIP_KEY_INFO pTkip)
+{
+ // Append the minimum padding
+ RTMPTkipAppendByte(pTkip, 0x5a );
+ RTMPTkipAppendByte(pTkip, 0 );
+ RTMPTkipAppendByte(pTkip, 0 );
+ RTMPTkipAppendByte(pTkip, 0 );
+ RTMPTkipAppendByte(pTkip, 0 );
+ // and then zeroes until the length is a multiple of 4
+ while( pTkip->nBytesInM != 0 )
+ {
+ RTMPTkipAppendByte(pTkip, 0 );
+ }
+ // The appendByte function has already computed the result.
+ RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
+ RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init Tkip function.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
+ KeyId TK Key ID
+ pTA Pointer to transmitter address
+ pMICKey pointer to MIC Key
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPInitTkipEngine(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKey,
+ IN UCHAR KeyId,
+ IN PUCHAR pTA,
+ IN PUCHAR pMICKey,
+ IN PUCHAR pTSC,
+ OUT PULONG pIV16,
+ OUT PULONG pIV32)
+{
+ TKIP_IV tkipIv;
+
+ // Prepare 8 bytes TKIP encapsulation for MPDU
+ NdisZeroMemory(&tkipIv, sizeof(TKIP_IV));
+ tkipIv.IV16.field.rc0 = *(pTSC + 1);
+ tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
+ tkipIv.IV16.field.rc2 = *pTSC;
+ tkipIv.IV16.field.CONTROL.field.ExtIV = 1; // 0: non-extended IV, 1: an extended IV
+ tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
+// tkipIv.IV32 = *(PULONG)(pTSC + 2);
+ NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); // Copy IV
+
+ *pIV16 = tkipIv.IV16.word;
+ *pIV32 = tkipIv.IV32;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init MIC Value calculation function which include set MIC key &
+ calculate first 16 bytes (DA + SA + priority + 0)
+
+ Arguments:
+ pAd Pointer to our adapter
+ pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
+ pDA Pointer to DA address
+ pSA Pointer to SA address
+ pMICKey pointer to MIC Key
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPInitMICEngine(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKey,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN UCHAR UserPriority,
+ IN PUCHAR pMICKey)
+{
+ ULONG Priority = UserPriority;
+
+ // Init MIC value calculation
+ RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
+ // DA
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
+ // SA
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
+ // Priority + 3 bytes of 0
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Compare MIC value of received MSDU
+
+ Arguments:
+ pAd Pointer to our adapter
+ pSrc Pointer to the received Plain text data
+ pDA Pointer to DA address
+ pSA Pointer to SA address
+ pMICKey pointer to MIC Key
+ Len the length of the received plain text data exclude MIC value
+
+ Return Value:
+ TRUE MIC value matched
+ FALSE MIC value mismatched
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN RTMPTkipCompareMICValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pSrc,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN PUCHAR pMICKey,
+ IN UCHAR UserPriority,
+ IN UINT Len)
+{
+ UCHAR OldMic[8];
+ ULONG Priority = UserPriority;
+
+ // Init MIC value calculation
+ RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
+ // DA
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
+ // SA
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
+ // Priority + 3 bytes of 0
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
+
+ // Calculate MIC value from plain text data
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
+
+ // Get MIC valude from received frame
+ NdisMoveMemory(OldMic, pSrc + Len, 8);
+
+ // Get MIC value from decrypted plain data
+ RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
+
+ // Move MIC value from MSDU, this steps should move to data path.
+ // Since the MIC value might cross MPDUs.
+ if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); //MIC error.
+
+
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Compare MIC value of received MSDU
+
+ Arguments:
+ pAd Pointer to our adapter
+ pLLC LLC header
+ pSrc Pointer to the received Plain text data
+ pDA Pointer to DA address
+ pSA Pointer to SA address
+ pMICKey pointer to MIC Key
+ Len the length of the received plain text data exclude MIC value
+
+ Return Value:
+ TRUE MIC value matched
+ FALSE MIC value mismatched
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN RTMPTkipCompareMICValueWithLLC(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pLLC,
+ IN PUCHAR pSrc,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN PUCHAR pMICKey,
+ IN UINT Len)
+{
+ UCHAR OldMic[8];
+ ULONG Priority = 0;
+
+ // Init MIC value calculation
+ RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
+ // DA
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
+ // SA
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
+ // Priority + 3 bytes of 0
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
+
+ // Start with LLC header
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8);
+
+ // Calculate MIC value from plain text data
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
+
+ // Get MIC valude from received frame
+ NdisMoveMemory(OldMic, pSrc + Len, 8);
+
+ // Get MIC value from decrypted plain data
+ RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
+
+ // Move MIC value from MSDU, this steps should move to data path.
+ // Since the MIC value might cross MPDUs.
+ if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n")); //MIC error.
+
+
+ return (FALSE);
+ }
+ return (TRUE);
+}
+/*
+ ========================================================================
+
+ Routine Description:
+ Copy frame from waiting queue into relative ring buffer and set
+ appropriate ASIC register to kick hardware transmit function
+
+ Arguments:
+ pAd Pointer to our adapter
+ PNDIS_PACKET Pointer to Ndis Packet for MIC calculation
+ pEncap Pointer to LLC encap data
+ LenEncap Total encap length, might be 0 which indicates no encap
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPCalculateMICValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pEncap,
+ IN PCIPHER_KEY pKey,
+ IN UCHAR apidx)
+{
+ PACKET_INFO PacketInfo;
+ PUCHAR pSrcBufVA;
+ UINT SrcBufLen;
+ PUCHAR pSrc;
+ UCHAR UserPriority;
+ UCHAR vlan_offset = 0;
+
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+ UserPriority = RTMP_GET_PACKET_UP(pPacket);
+ pSrc = pSrcBufVA;
+
+ // determine if this is a vlan packet
+ if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
+ vlan_offset = 4;
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+ {
+ RTMPInitMICEngine(
+ pAd,
+ pKey->Key,
+ pSrc,
+ pSrc + 6,
+ UserPriority,
+ pKey->TxMic);
+ }
+
+
+ if (pEncap != NULL)
+ {
+ // LLC encapsulation
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
+ // Protocol Type
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, 2);
+ }
+ SrcBufLen -= (14 + vlan_offset);
+ pSrc += (14 + vlan_offset);
+ do
+ {
+ if (SrcBufLen > 0)
+ {
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
+ }
+
+ break; // No need handle next packet
+
+ } while (TRUE); // End of copying payload
+
+ // Compute the final MIC Value
+ RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
+}
+
+
+/************************************************************/
+/* tkip_sbox() */
+/* Returns a 16 bit value from a 64K entry table. The Table */
+/* is synthesized from two 256 entry byte wide tables. */
+/************************************************************/
+
+UINT tkip_sbox(UINT index)
+{
+ UINT index_low;
+ UINT index_high;
+ UINT left, right;
+
+ index_low = (index % 256);
+ index_high = ((index >> 8) % 256);
+
+ left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
+ right = Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
+
+ return (left ^ right);
+}
+
+UINT rotr1(UINT a)
+{
+ unsigned int b;
+
+ if ((a & 0x01) == 0x01)
+ {
+ b = (a >> 1) | 0x8000;
+ }
+ else
+ {
+ b = (a >> 1) & 0x7fff;
+ }
+ b = b % 65536;
+ return b;
+}
+
+VOID RTMPTkipMixKey(
+ UCHAR *key,
+ UCHAR *ta,
+ ULONG pnl, /* Least significant 16 bits of PN */
+ ULONG pnh, /* Most significant 32 bits of PN */
+ UCHAR *rc4key,
+ UINT *p1k)
+{
+
+ UINT tsc0;
+ UINT tsc1;
+ UINT tsc2;
+
+ UINT ppk0;
+ UINT ppk1;
+ UINT ppk2;
+ UINT ppk3;
+ UINT ppk4;
+ UINT ppk5;
+
+ INT i;
+ INT j;
+
+ tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
+ tsc1 = (unsigned int)(pnh % 65536);
+ tsc2 = (unsigned int)(pnl % 65536); /* lsb */
+
+ /* Phase 1, step 1 */
+ p1k[0] = tsc1;
+ p1k[1] = tsc0;
+ p1k[2] = (UINT)(ta[0] + (ta[1]*256));
+ p1k[3] = (UINT)(ta[2] + (ta[3]*256));
+ p1k[4] = (UINT)(ta[4] + (ta[5]*256));
+
+ /* Phase 1, step 2 */
+ for (i=0; i<8; i++)
+ {
+ j = 2*(i & 1);
+ p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*key[1+j]) + key[j])) % 65536 )) % 65536;
+ p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*key[5+j]) + key[4+j])) % 65536 )) % 65536;
+ p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*key[9+j]) + key[8+j])) % 65536 )) % 65536;
+ p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*key[13+j]) + key[12+j])) % 65536 )) % 65536;
+ p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*key[1+j]) + key[j]))) % 65536 )) % 65536;
+ p1k[4] = (p1k[4] + i) % 65536;
+ }
+
+ /* Phase 2, Step 1 */
+ ppk0 = p1k[0];
+ ppk1 = p1k[1];
+ ppk2 = p1k[2];
+ ppk3 = p1k[3];
+ ppk4 = p1k[4];
+ ppk5 = (p1k[4] + tsc2) % 65536;
+
+ /* Phase2, Step 2 */
+ ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*key[1]) + key[0])) % 65536);
+ ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*key[3]) + key[2])) % 65536);
+ ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*key[5]) + key[4])) % 65536);
+ ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*key[7]) + key[6])) % 65536);
+ ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*key[9]) + key[8])) % 65536);
+ ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*key[11]) + key[10])) % 65536);
+
+ ppk0 = ppk0 + rotr1(ppk5 ^ ((256*key[13]) + key[12]));
+ ppk1 = ppk1 + rotr1(ppk0 ^ ((256*key[15]) + key[14]));
+ ppk2 = ppk2 + rotr1(ppk1);
+ ppk3 = ppk3 + rotr1(ppk2);
+ ppk4 = ppk4 + rotr1(ppk3);
+ ppk5 = ppk5 + rotr1(ppk4);
+
+ /* Phase 2, Step 3 */
+ /* Phase 2, Step 3 */
+
+ tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
+ tsc1 = (unsigned int)(pnh % 65536);
+ tsc2 = (unsigned int)(pnl % 65536); /* lsb */
+
+ rc4key[0] = (tsc2 >> 8) % 256;
+ rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
+ rc4key[2] = tsc2 % 256;
+ rc4key[3] = ((ppk5 ^ ((256*key[1]) + key[0])) >> 1) % 256;
+
+ rc4key[4] = ppk0 % 256;
+ rc4key[5] = (ppk0 >> 8) % 256;
+
+ rc4key[6] = ppk1 % 256;
+ rc4key[7] = (ppk1 >> 8) % 256;
+
+ rc4key[8] = ppk2 % 256;
+ rc4key[9] = (ppk2 >> 8) % 256;
+
+ rc4key[10] = ppk3 % 256;
+ rc4key[11] = (ppk3 >> 8) % 256;
+
+ rc4key[12] = ppk4 % 256;
+ rc4key[13] = (ppk4 >> 8) % 256;
+
+ rc4key[14] = ppk5 % 256;
+ rc4key[15] = (ppk5 >> 8) % 256;
+}
+
+
+/************************************************/
+/* construct_mic_header1() */
+/* Builds the first MIC header block from */
+/* header fields. */
+/************************************************/
+
+void construct_mic_header1(
+ unsigned char *mic_header1,
+ int header_length,
+ unsigned char *mpdu)
+{
+ mic_header1[0] = (unsigned char)((header_length - 2) / 256);
+ mic_header1[1] = (unsigned char)((header_length - 2) % 256);
+ mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
+ mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
+ mic_header1[4] = mpdu[4]; /* A1 */
+ mic_header1[5] = mpdu[5];
+ mic_header1[6] = mpdu[6];
+ mic_header1[7] = mpdu[7];
+ mic_header1[8] = mpdu[8];
+ mic_header1[9] = mpdu[9];
+ mic_header1[10] = mpdu[10]; /* A2 */
+ mic_header1[11] = mpdu[11];
+ mic_header1[12] = mpdu[12];
+ mic_header1[13] = mpdu[13];
+ mic_header1[14] = mpdu[14];
+ mic_header1[15] = mpdu[15];
+}
+
+/************************************************/
+/* construct_mic_header2() */
+/* Builds the last MIC header block from */
+/* header fields. */
+/************************************************/
+
+void construct_mic_header2(
+ unsigned char *mic_header2,
+ unsigned char *mpdu,
+ int a4_exists,
+ int qc_exists)
+{
+ int i;
+
+ for (i = 0; i<16; i++) mic_header2[i]=0x00;
+
+ mic_header2[0] = mpdu[16]; /* A3 */
+ mic_header2[1] = mpdu[17];
+ mic_header2[2] = mpdu[18];
+ mic_header2[3] = mpdu[19];
+ mic_header2[4] = mpdu[20];
+ mic_header2[5] = mpdu[21];
+
+ // In Sequence Control field, mute sequence numer bits (12-bit)
+ mic_header2[6] = mpdu[22] & 0x0f; /* SC */
+ mic_header2[7] = 0x00; /* mpdu[23]; */
+
+ if ((!qc_exists) & a4_exists)
+ {
+ for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
+
+ }
+
+ if (qc_exists && (!a4_exists))
+ {
+ mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
+ mic_header2[9] = mpdu[25] & 0x00;
+ }
+
+ if (qc_exists && a4_exists)
+ {
+ for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
+
+ mic_header2[14] = mpdu[30] & 0x0f;
+ mic_header2[15] = mpdu[31] & 0x00;
+ }
+}
+
+
+/************************************************/
+/* construct_mic_iv() */
+/* Builds the MIC IV from header fields and PN */
+/************************************************/
+
+void construct_mic_iv(
+ unsigned char *mic_iv,
+ int qc_exists,
+ int a4_exists,
+ unsigned char *mpdu,
+ unsigned int payload_length,
+ unsigned char *pn_vector)
+{
+ int i;
+
+ mic_iv[0] = 0x59;
+ if (qc_exists && a4_exists)
+ mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
+ if (qc_exists && !a4_exists)
+ mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
+ if (!qc_exists)
+ mic_iv[1] = 0x00;
+ for (i = 2; i < 8; i++)
+ mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
+#ifdef CONSISTENT_PN_ORDER
+ for (i = 8; i < 14; i++)
+ mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */
+#else
+ for (i = 8; i < 14; i++)
+ mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
+#endif
+ i = (payload_length / 256);
+ i = (payload_length % 256);
+ mic_iv[14] = (unsigned char) (payload_length / 256);
+ mic_iv[15] = (unsigned char) (payload_length % 256);
+
+}
+
+
+
+/************************************/
+/* bitwise_xor() */
+/* A 128 bit, bitwise exclusive or */
+/************************************/
+
+void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
+{
+ int i;
+ for (i=0; i<16; i++)
+ {
+ out[i] = ina[i] ^ inb[i];
+ }
+}
+
+
+void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
+{
+ int round;
+ int i;
+ unsigned char intermediatea[16];
+ unsigned char intermediateb[16];
+ unsigned char round_key[16];
+
+ for(i=0; i<16; i++) round_key[i] = key[i];
+
+ for (round = 0; round < 11; round++)
+ {
+ if (round == 0)
+ {
+ xor_128(round_key, data, ciphertext);
+ next_key(round_key, round);
+ }
+ else if (round == 10)
+ {
+ byte_sub(ciphertext, intermediatea);
+ shift_row(intermediatea, intermediateb);
+ xor_128(intermediateb, round_key, ciphertext);
+ }
+ else /* 1 - 9 */
+ {
+ byte_sub(ciphertext, intermediatea);
+ shift_row(intermediatea, intermediateb);
+ mix_column(&intermediateb[0], &intermediatea[0]);
+ mix_column(&intermediateb[4], &intermediatea[4]);
+ mix_column(&intermediateb[8], &intermediatea[8]);
+ mix_column(&intermediateb[12], &intermediatea[12]);
+ xor_128(intermediatea, round_key, ciphertext);
+ next_key(round_key, round);
+ }
+ }
+
+}
+
+void construct_ctr_preload(
+ unsigned char *ctr_preload,
+ int a4_exists,
+ int qc_exists,
+ unsigned char *mpdu,
+ unsigned char *pn_vector,
+ int c)
+{
+
+ int i = 0;
+ for (i=0; i<16; i++) ctr_preload[i] = 0x00;
+ i = 0;
+
+ ctr_preload[0] = 0x01; /* flag */
+ if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
+ if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f;
+
+ for (i = 2; i < 8; i++)
+ ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
+#ifdef CONSISTENT_PN_ORDER
+ for (i = 8; i < 14; i++)
+ ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */
+#else
+ for (i = 8; i < 14; i++)
+ ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
+#endif
+ ctr_preload[14] = (unsigned char) (c / 256); // Ctr
+ ctr_preload[15] = (unsigned char) (c % 256);
+
+}
+
+
+//
+// TRUE: Success!
+// FALSE: Decrypt Error!
+//
+BOOLEAN RTMPSoftDecryptTKIP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN UCHAR UserPriority,
+ IN PCIPHER_KEY pWpaKey)
+{
+ UCHAR KeyID;
+ UINT HeaderLen;
+ UCHAR fc0;
+ UCHAR fc1;
+ USHORT fc;
+ UINT frame_type;
+ UINT frame_subtype;
+ UINT from_ds;
+ UINT to_ds;
+ INT a4_exists;
+ INT qc_exists;
+ USHORT duration;
+ USHORT seq_control;
+ USHORT qos_control;
+ UCHAR TA[MAC_ADDR_LEN];
+ UCHAR DA[MAC_ADDR_LEN];
+ UCHAR SA[MAC_ADDR_LEN];
+ UCHAR RC4Key[16];
+ UINT p1k[5]; //for mix_key;
+ ULONG pnl;/* Least significant 16 bits of PN */
+ ULONG pnh;/* Most significant 32 bits of PN */
+ UINT num_blocks;
+ UINT payload_remainder;
+ ARCFOURCONTEXT ArcFourContext;
+ UINT crc32 = 0;
+ UINT trailfcs = 0;
+ UCHAR MIC[8];
+ UCHAR TrailMIC[8];
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+
+ fc0 = *pData;
+ fc1 = *(pData + 1);
+
+ fc = *((PUSHORT)pData);
+
+ frame_type = ((fc0 >> 2) & 0x03);
+ frame_subtype = ((fc0 >> 4) & 0x0f);
+
+ from_ds = (fc1 & 0x2) >> 1;
+ to_ds = (fc1 & 0x1);
+
+ a4_exists = (from_ds & to_ds);
+ qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
+ (frame_subtype == 0x09) || /* Likely to change. */
+ (frame_subtype == 0x0a) ||
+ (frame_subtype == 0x0b)
+ );
+
+ HeaderLen = 24;
+ if (a4_exists)
+ HeaderLen += 6;
+
+ KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
+ KeyID = KeyID >> 6;
+
+ if (pWpaKey[KeyID].KeyLen == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n", KeyID));
+ return FALSE;
+ }
+
+ duration = *((PUSHORT)(pData+2));
+
+ seq_control = *((PUSHORT)(pData+22));
+
+ if (qc_exists)
+ {
+ if (a4_exists)
+ {
+ qos_control = *((PUSHORT)(pData+30));
+ }
+ else
+ {
+ qos_control = *((PUSHORT)(pData+24));
+ }
+ }
+
+ if (to_ds == 0 && from_ds == 1)
+ {
+ NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
+ NdisMoveMemory(SA, pData+16, MAC_ADDR_LEN);
+ NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); //BSSID
+ }
+ else if (to_ds == 0 && from_ds == 0 )
+ {
+ NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
+ NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
+ NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
+ }
+ else if (to_ds == 1 && from_ds == 0)
+ {
+ NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
+ NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
+ NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
+ }
+ else if (to_ds == 1 && from_ds == 1)
+ {
+ NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
+ NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
+ NdisMoveMemory(SA, pData+22, MAC_ADDR_LEN);
+ }
+
+ num_blocks = (DataByteCnt - 16) / 16;
+ payload_remainder = (DataByteCnt - 16) % 16;
+
+ pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
+ pnh = *((PULONG)(pData + HeaderLen + 4));
+ pnh = cpu2le32(pnh);
+ RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
+
+ ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
+
+ ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen, pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
+ NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
+ crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4); //Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS).
+ crc32 ^= 0xffffffff; /* complement */
+
+ if(crc32 != cpu2le32(trailfcs))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n")); //ICV error.
+
+ return (FALSE);
+ }
+
+ NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
+ RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority, pWpaKey[KeyID].RxMic);
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 12);
+ RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
+ NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
+
+ if (!NdisEqualMemory(MIC, TrailMIC, 8))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); //MIC error.
+ //RTMPReportMicError(pAd, &pWpaKey[KeyID]); // marked by AlbertY @ 20060630
+ return (FALSE);
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+ //DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!!\n");
+ return TRUE;
+}
+
+
+
+
+BOOLEAN RTMPSoftDecryptAES(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN PCIPHER_KEY pWpaKey)
+{
+ UCHAR KeyID;
+ UINT HeaderLen;
+ UCHAR PN[6];
+ UINT payload_len;
+ UINT num_blocks;
+ UINT payload_remainder;
+ USHORT fc;
+ UCHAR fc0;
+ UCHAR fc1;
+ UINT frame_type;
+ UINT frame_subtype;
+ UINT from_ds;
+ UINT to_ds;
+ INT a4_exists;
+ INT qc_exists;
+ UCHAR aes_out[16];
+ int payload_index;
+ UINT i;
+ UCHAR ctr_preload[16];
+ UCHAR chain_buffer[16];
+ UCHAR padded_buffer[16];
+ UCHAR mic_iv[16];
+ UCHAR mic_header1[16];
+ UCHAR mic_header2[16];
+ UCHAR MIC[8];
+ UCHAR TrailMIC[8];
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+
+ fc0 = *pData;
+ fc1 = *(pData + 1);
+
+ fc = *((PUSHORT)pData);
+
+ frame_type = ((fc0 >> 2) & 0x03);
+ frame_subtype = ((fc0 >> 4) & 0x0f);
+
+ from_ds = (fc1 & 0x2) >> 1;
+ to_ds = (fc1 & 0x1);
+
+ a4_exists = (from_ds & to_ds);
+ qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
+ (frame_subtype == 0x09) || /* Likely to change. */
+ (frame_subtype == 0x0a) ||
+ (frame_subtype == 0x0b)
+ );
+
+ HeaderLen = 24;
+ if (a4_exists)
+ HeaderLen += 6;
+
+ KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
+ KeyID = KeyID >> 6;
+
+ if (pWpaKey[KeyID].KeyLen == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", KeyID));
+ return FALSE;
+ }
+
+ PN[0] = *(pData+ HeaderLen);
+ PN[1] = *(pData+ HeaderLen + 1);
+ PN[2] = *(pData+ HeaderLen + 4);
+ PN[3] = *(pData+ HeaderLen + 5);
+ PN[4] = *(pData+ HeaderLen + 6);
+ PN[5] = *(pData+ HeaderLen + 7);
+
+ payload_len = DataByteCnt - HeaderLen - 8 - 8; // 8 bytes for CCMP header , 8 bytes for MIC
+ payload_remainder = (payload_len) % 16;
+ num_blocks = (payload_len) / 16;
+
+
+
+ // Find start of payload
+ payload_index = HeaderLen + 8; //IV+EIV
+
+ for (i=0; i< num_blocks; i++)
+ {
+ construct_ctr_preload(ctr_preload,
+ a4_exists,
+ qc_exists,
+ pData,
+ PN,
+ i+1 );
+
+ aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+ bitwise_xor(aes_out, pData + payload_index, chain_buffer);
+ NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
+ payload_index += 16;
+ }
+
+ //
+ // If there is a short final block, then pad it
+ // encrypt it and copy the unpadded part back
+ //
+ if (payload_remainder > 0)
+ {
+ construct_ctr_preload(ctr_preload,
+ a4_exists,
+ qc_exists,
+ pData,
+ PN,
+ num_blocks + 1);
+
+ NdisZeroMemory(padded_buffer, 16);
+ NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
+
+ aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+ NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder);
+ payload_index += payload_remainder;
+ }
+
+ //
+ // Descrypt the MIC
+ //
+ construct_ctr_preload(ctr_preload,
+ a4_exists,
+ qc_exists,
+ pData,
+ PN,
+ 0);
+ NdisZeroMemory(padded_buffer, 16);
+ NdisMoveMemory(padded_buffer, pData + payload_index, 8);
+
+ aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+
+ NdisMoveMemory(TrailMIC, chain_buffer, 8);
+
+ //
+ // Calculate MIC
+ //
+
+ //Force the protected frame bit on
+ *(pData + 1) = *(pData + 1) | 0x40;
+
+ // Find start of payload
+ // Because the CCMP header has been removed
+ payload_index = HeaderLen;
+
+ construct_mic_iv(
+ mic_iv,
+ qc_exists,
+ a4_exists,
+ pData,
+ payload_len,
+ PN);
+
+ construct_mic_header1(
+ mic_header1,
+ HeaderLen,
+ pData);
+
+ construct_mic_header2(
+ mic_header2,
+ pData,
+ a4_exists,
+ qc_exists);
+
+ aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
+ bitwise_xor(aes_out, mic_header1, chain_buffer);
+ aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+ bitwise_xor(aes_out, mic_header2, chain_buffer);
+ aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+
+ // iterate through each 16 byte payload block
+ for (i = 0; i < num_blocks; i++)
+ {
+ bitwise_xor(aes_out, pData + payload_index, chain_buffer);
+ payload_index += 16;
+ aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+ }
+
+ // Add on the final payload block if it needs padding
+ if (payload_remainder > 0)
+ {
+ NdisZeroMemory(padded_buffer, 16);
+ NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
+
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+ aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+ }
+
+ // aes_out contains padded mic, discard most significant
+ // 8 bytes to generate 64 bit MIC
+ for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i];
+
+ if (!NdisEqualMemory(MIC, TrailMIC, 8))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); //MIC error.
+ return FALSE;
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+
+ return TRUE;
+}
+
+/****************************************/
+/* aes128k128d() */
+/* Performs a 128 bit AES encrypt with */
+/* 128 bit data. */
+/****************************************/
+VOID xor_128(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out)
+{
+ INT i;
+
+ for (i=0;i<16; i++)
+ {
+ out[i] = a[i] ^ b[i];
+ }
+}
+
+VOID next_key(
+ IN PUCHAR key,
+ IN INT round)
+{
+ UCHAR rcon;
+ UCHAR sbox_key[4];
+ UCHAR rcon_table[12] =
+ {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+ 0x1b, 0x36, 0x36, 0x36
+ };
+
+ sbox_key[0] = RTMPCkipSbox(key[13]);
+ sbox_key[1] = RTMPCkipSbox(key[14]);
+ sbox_key[2] = RTMPCkipSbox(key[15]);
+ sbox_key[3] = RTMPCkipSbox(key[12]);
+
+ rcon = rcon_table[round];
+
+ xor_32(&key[0], sbox_key, &key[0]);
+ key[0] = key[0] ^ rcon;
+
+ xor_32(&key[4], &key[0], &key[4]);
+ xor_32(&key[8], &key[4], &key[8]);
+ xor_32(&key[12], &key[8], &key[12]);
+}
+
+VOID xor_32(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out)
+{
+ INT i;
+
+ for (i=0;i<4; i++)
+ {
+ out[i] = a[i] ^ b[i];
+ }
+}
+
+VOID byte_sub(
+ IN PUCHAR in,
+ OUT PUCHAR out)
+{
+ INT i;
+
+ for (i=0; i< 16; i++)
+ {
+ out[i] = RTMPCkipSbox(in[i]);
+ }
+}
+
+UCHAR RTMPCkipSbox(
+ IN UCHAR a)
+{
+ return SboxTable[(int)a];
+}
+
+VOID shift_row(
+ IN PUCHAR in,
+ OUT PUCHAR out)
+{
+ out[0] = in[0];
+ out[1] = in[5];
+ out[2] = in[10];
+ out[3] = in[15];
+ out[4] = in[4];
+ out[5] = in[9];
+ out[6] = in[14];
+ out[7] = in[3];
+ out[8] = in[8];
+ out[9] = in[13];
+ out[10] = in[2];
+ out[11] = in[7];
+ out[12] = in[12];
+ out[13] = in[1];
+ out[14] = in[6];
+ out[15] = in[11];
+}
+
+VOID mix_column(
+ IN PUCHAR in,
+ OUT PUCHAR out)
+{
+ INT i;
+ UCHAR add1b[4];
+ UCHAR add1bf7[4];
+ UCHAR rotl[4];
+ UCHAR swap_halfs[4];
+ UCHAR andf7[4];
+ UCHAR rotr[4];
+ UCHAR temp[4];
+ UCHAR tempb[4];
+
+ for (i=0 ; i<4; i++)
+ {
+ if ((in[i] & 0x80)== 0x80)
+ add1b[i] = 0x1b;
+ else
+ add1b[i] = 0x00;
+ }
+
+ swap_halfs[0] = in[2]; /* Swap halfs */
+ swap_halfs[1] = in[3];
+ swap_halfs[2] = in[0];
+ swap_halfs[3] = in[1];
+
+ rotl[0] = in[3]; /* Rotate left 8 bits */
+ rotl[1] = in[0];
+ rotl[2] = in[1];
+ rotl[3] = in[2];
+
+ andf7[0] = in[0] & 0x7f;
+ andf7[1] = in[1] & 0x7f;
+ andf7[2] = in[2] & 0x7f;
+ andf7[3] = in[3] & 0x7f;
+
+ for (i = 3; i>0; i--) /* logical shift left 1 bit */
+ {
+ andf7[i] = andf7[i] << 1;
+ if ((andf7[i-1] & 0x80) == 0x80)
+ {
+ andf7[i] = (andf7[i] | 0x01);
+ }
+ }
+ andf7[0] = andf7[0] << 1;
+ andf7[0] = andf7[0] & 0xfe;
+
+ xor_32(add1b, andf7, add1bf7);
+
+ xor_32(in, add1bf7, rotr);
+
+ temp[0] = rotr[0]; /* Rotate right 8 bits */
+ rotr[0] = rotr[1];
+ rotr[1] = rotr[2];
+ rotr[2] = rotr[3];
+ rotr[3] = temp[0];
+
+ xor_32(add1bf7, rotr, temp);
+ xor_32(swap_halfs, rotl,tempb);
+ xor_32(temp, tempb, out);
+}
+
diff --git a/drivers/staging/rt3070/common/rtmp_wep.c b/drivers/staging/rt3070/common/rtmp_wep.c
new file mode 100644
index 00000000000..f5f0a3bb17e
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtmp_wep.c
@@ -0,0 +1,508 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_wep.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Wu 10-28-02 Initial
+*/
+
+#include "../rt_config.h"
+
+UINT FCSTAB_32[256] =
+{
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/*
+UCHAR WEPKEY[] = {
+ //IV
+ 0x00, 0x11, 0x22,
+ //WEP KEY
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
+ };
+ */
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init WEP function.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pKey Pointer to the WEP KEY
+ KeyId WEP Key ID
+ KeyLen the length of WEP KEY
+ pDest Pointer to the destination which Encryption data will store in.
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPInitWepEngine(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKey,
+ IN UCHAR KeyId,
+ IN UCHAR KeyLen,
+ IN OUT PUCHAR pDest)
+{
+ UINT i;
+ UCHAR WEPKEY[] = {
+ //IV
+ 0x00, 0x11, 0x22,
+ //WEP KEY
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
+ };
+
+ pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
+
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10) && (pAd->OpMode == OPMODE_STA))
+ {
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, pKey, KeyLen); //INIT SBOX, KEYLEN+3(IV)
+ NdisMoveMemory(pDest, pKey, 3); //Append Init Vector
+ }
+ else
+#endif // CONFIG_STA_SUPPORT //
+ {
+ NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
+
+ for(i = 0; i < 3; i++)
+ WEPKEY[i] = RandomByte(pAd); //Call mlme RandomByte() function.
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3); //INIT SBOX, KEYLEN+3(IV)
+
+ NdisMoveMemory(pDest, WEPKEY, 3); //Append Init Vector
+ }
+ *(pDest+3) = (KeyId << 6); //Append KEYID
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Encrypt transimitted data
+
+ Arguments:
+ pAd Pointer to our adapter
+ pSrc Pointer to the transimitted source data that will be encrypt
+ pDest Pointer to the destination where entryption data will be store in.
+ Len Indicate the length of the source data
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPEncryptData(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pSrc,
+ IN PUCHAR pDest,
+ IN UINT Len)
+{
+ pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
+ ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Decrypt received WEP data
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ pSrc Pointer to the received data
+ Len the length of the received data
+
+ Return Value:
+ TRUE Decrypt WEP data success
+ FALSE Decrypt WEP data failed
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN RTMPSoftDecryptWEP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN PCIPHER_KEY pGroupKey)
+{
+ UINT trailfcs;
+ UINT crc32;
+ UCHAR KeyIdx;
+ UCHAR WEPKEY[] = {
+ //IV
+ 0x00, 0x11, 0x22,
+ //WEP KEY
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
+ };
+ UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11;
+ ULONG payload_len = DataByteCnt - LENGTH_802_11;
+
+ NdisMoveMemory(WEPKEY, pPayload, 3); //Get WEP IV
+
+ KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
+ if (pGroupKey[KeyIdx].KeyLen == 0)
+ return (FALSE);
+
+ NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, pGroupKey[KeyIdx].KeyLen);
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, pGroupKey[KeyIdx].KeyLen + 3);
+ ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, payload_len - 4);
+ NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
+ crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8); //Skip last 4 bytes(FCS).
+ crc32 ^= 0xffffffff; /* complement */
+
+ if(crc32 != cpu2le32(trailfcs))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n")); //CRC error.
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ The Stream Cipher Encryption Algorithm "ARCFOUR" initialize
+
+ Arguments:
+ Ctx Pointer to ARCFOUR CONTEXT (SBOX)
+ pKey Pointer to the WEP KEY
+ KeyLen Indicate the length fo the WEP KEY
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID ARCFOUR_INIT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pKey,
+ IN UINT KeyLen)
+{
+ UCHAR t, u;
+ UINT keyindex;
+ UINT stateindex;
+ PUCHAR state;
+ UINT counter;
+
+ state = Ctx->STATE;
+ Ctx->X = 0;
+ Ctx->Y = 0;
+ for (counter = 0; counter < 256; counter++)
+ state[counter] = (UCHAR)counter;
+ keyindex = 0;
+ stateindex = 0;
+ for (counter = 0; counter < 256; counter++)
+ {
+ t = state[counter];
+ stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
+ u = state[stateindex];
+ state[stateindex] = t;
+ state[counter] = u;
+ if (++keyindex >= KeyLen)
+ keyindex = 0;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get bytes from ARCFOUR CONTEXT (S-BOX)
+
+ Arguments:
+ Ctx Pointer to ARCFOUR CONTEXT (SBOX)
+
+ Return Value:
+ UCHAR - the value of the ARCFOUR CONTEXT (S-BOX)
+
+ Note:
+
+ ========================================================================
+*/
+UCHAR ARCFOUR_BYTE(
+ IN PARCFOURCONTEXT Ctx)
+{
+ UINT x;
+ UINT y;
+ UCHAR sx, sy;
+ PUCHAR state;
+
+ state = Ctx->STATE;
+ x = (Ctx->X + 1) & 0xff;
+ sx = state[x];
+ y = (sx + Ctx->Y) & 0xff;
+ sy = state[y];
+ Ctx->X = x;
+ Ctx->Y = y;
+ state[y] = sx;
+ state[x] = sy;
+
+ return(state[(sx + sy) & 0xff]);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ The Stream Cipher Decryption Algorithm
+
+ Arguments:
+ Ctx Pointer to ARCFOUR CONTEXT (SBOX)
+ pDest Pointer to the Destination
+ pSrc Pointer to the Source data
+ Len Indicate the length of the Source data
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID ARCFOUR_DECRYPT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pDest,
+ IN PUCHAR pSrc,
+ IN UINT Len)
+{
+ UINT i;
+
+ for (i = 0; i < Len; i++)
+ pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ The Stream Cipher Encryption Algorithm
+
+ Arguments:
+ Ctx Pointer to ARCFOUR CONTEXT (SBOX)
+ pDest Pointer to the Destination
+ pSrc Pointer to the Source data
+ Len Indicate the length of the Source dta
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID ARCFOUR_ENCRYPT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pDest,
+ IN PUCHAR pSrc,
+ IN UINT Len)
+{
+ UINT i;
+
+ for (i = 0; i < Len; i++)
+ pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt GTK.
+
+ Arguments:
+ Ctx Pointer to ARCFOUR CONTEXT (SBOX)
+ pDest Pointer to the Destination
+ pSrc Pointer to the Source data
+ Len Indicate the length of the Source dta
+
+
+ ========================================================================
+*/
+
+VOID WPAARCFOUR_ENCRYPT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pDest,
+ IN PUCHAR pSrc,
+ IN UINT Len)
+{
+ UINT i;
+ //discard first 256 bytes
+ for (i = 0; i < 256; i++)
+ ARCFOUR_BYTE(Ctx);
+
+ for (i = 0; i < Len; i++)
+ pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculate a new FCS given the current FCS and the new data.
+
+ Arguments:
+ Fcs the original FCS value
+ Cp pointer to the data which will be calculate the FCS
+ Len the length of the data
+
+ Return Value:
+ UINT - FCS 32 bits
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+UINT RTMP_CALC_FCS32(
+ IN UINT Fcs,
+ IN PUCHAR Cp,
+ IN INT Len)
+{
+ while (Len--)
+ Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
+
+ return (Fcs);
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get last FCS and encrypt it to the destination
+
+ Arguments:
+ pDest Pointer to the Destination
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPSetICV(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDest)
+{
+ pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff; /* complement */
+ pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
+
+ ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);
+}
+
diff --git a/drivers/staging/rt3070/common/rtusb_bulk.c b/drivers/staging/rt3070/common/rtusb_bulk.c
new file mode 100644
index 00000000000..1a05703520f
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtusb_bulk.c
@@ -0,0 +1,1382 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtusb_bulk.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 06-25-2004 created
+
+*/
+
+#include "../rt_config.h"
+// Match total 6 bulkout endpoint to corresponding queue.
+UCHAR EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT};
+
+//static BOOLEAN SingleBulkOut = FALSE;
+
+void RTUSB_FILL_BULK_URB (struct urb *pUrb,
+ struct usb_device *pUsb_Dev,
+ unsigned int bulkpipe,
+ void *pTransferBuf,
+ int BufSize,
+ usb_complete_t Complete,
+ void *pContext)
+{
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, (usb_complete_t)Complete, pContext);
+#else
+ FILL_BULK_URB(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);
+#endif
+
+}
+
+VOID RTUSBInitTxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PTX_CONTEXT pTxContext,
+ IN UCHAR BulkOutPipeId,
+ IN usb_complete_t Func)
+{
+ PURB pUrb;
+ PUCHAR pSrc = NULL;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ pUrb = pTxContext->pUrb;
+ ASSERT(pUrb);
+
+ // Store BulkOut PipeId
+ pTxContext->BulkOutPipeId = BulkOutPipeId;
+
+ if (pTxContext->bAggregatible)
+ {
+ pSrc = &pTxContext->TransferBuffer->Aggregation[2];
+ }
+ else
+ {
+ pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket;
+ }
+
+
+ //Initialize a tx bulk urb
+ RTUSB_FILL_BULK_URB(pUrb,
+ pObj->pUsb_Dev,
+ usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
+ pSrc,
+ pTxContext->BulkOutSize,
+ Func,
+ pTxContext);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ if (pTxContext->bAggregatible)
+ pUrb->transfer_dma = (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
+ else
+ pUrb->transfer_dma = pTxContext->data_dma;
+
+ pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+#endif
+
+}
+
+VOID RTUSBInitHTTxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PHT_TX_CONTEXT pTxContext,
+ IN UCHAR BulkOutPipeId,
+ IN ULONG BulkOutSize,
+ IN usb_complete_t Func)
+{
+ PURB pUrb;
+ PUCHAR pSrc = NULL;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ pUrb = pTxContext->pUrb;
+ ASSERT(pUrb);
+
+ // Store BulkOut PipeId
+ pTxContext->BulkOutPipeId = BulkOutPipeId;
+
+ pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
+
+
+ //Initialize a tx bulk urb
+ RTUSB_FILL_BULK_URB(pUrb,
+ pObj->pUsb_Dev,
+ usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
+ pSrc,
+ BulkOutSize,
+ Func,
+ pTxContext);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ pUrb->transfer_dma = (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
+ pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+#endif
+
+}
+
+VOID RTUSBInitRxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PRX_CONTEXT pRxContext)
+{
+ PURB pUrb;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ ULONG RX_bulk_size;
+
+
+ pUrb = pRxContext->pUrb;
+ ASSERT(pUrb);
+
+ if ( pAd->BulkInMaxPacketSize == 64)
+ RX_bulk_size = 4096;
+ else
+ RX_bulk_size = MAX_RXBULK_SIZE;
+
+ //Initialize a rx bulk urb
+ RTUSB_FILL_BULK_URB(pUrb,
+ pObj->pUsb_Dev,
+ usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
+ &(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]),
+ RX_bulk_size - (pAd->NextRxBulkInPosition),
+ (usb_complete_t)RTUSBBulkRxComplete,
+ (void *)pRxContext);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition;
+ pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+#endif
+
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+
+#define BULK_OUT_LOCK(pLock, IrqFlags) \
+ if(1 /*!(in_interrupt() & 0xffff0000)*/) \
+ RTMP_IRQ_LOCK((pLock), IrqFlags);
+
+#define BULK_OUT_UNLOCK(pLock, IrqFlags) \
+ if(1 /*!(in_interrupt() & 0xffff0000)*/) \
+ RTMP_IRQ_UNLOCK((pLock), IrqFlags);
+
+
+VOID RTUSBBulkOutDataPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BulkOutPipeId,
+ IN UCHAR Index)
+{
+
+ PHT_TX_CONTEXT pHTTXContext;
+ PURB pUrb;
+ int ret = 0;
+ PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL;
+ PTXWI_STRUC pTxWI;
+ ULONG TmpBulkEndPos, ThisBulkSize;
+ unsigned long IrqFlags = 0, IrqFlags2 = 0;
+ PUCHAR pWirelessPkt, pAppendant;
+ BOOLEAN bTxQLastRound = FALSE;
+ UCHAR allzero[4]= {0x0,0x0,0x0,0x0};
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
+ {
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ return;
+ }
+ pAd->BulkOutPending[BulkOutPipeId] = TRUE;
+
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+ )
+ {
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ return;
+ }
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+
+ pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
+
+ BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+ if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
+ || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
+ {
+ BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+
+ // Clear Data flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
+ RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ return;
+ }
+
+ // Clear Data flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
+ RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+
+ //DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(),
+ // pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition,
+ // pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
+ pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
+ ThisBulkSize = 0;
+ TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
+ pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
+
+ if ((pHTTXContext->bCopySavePad == TRUE))
+ {
+ if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n",
+ pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
+ ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
+ }
+ NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8);
+ pHTTXContext->bCopySavePad = FALSE;
+ if (pAd->bForcePrintTX == TRUE)
+ DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition));
+ }
+
+ do
+ {
+ pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos];
+ pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
+
+ if (pAd->bForcePrintTX == TRUE)
+ DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU));
+
+ // add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items
+ //if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0))
+ if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK))
+ {
+#ifdef INF_AMAZON_SE
+ /*Iverson Add for AMAZON USB (RT2070 && RT3070) to pass WMM A2-T4 ~ A2-T10*/
+ if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
+ {
+ /*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate*/
+ if(pTxWI->PacketId == 6)
+ {
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ else if (BulkOutPipeId == 1)
+ {
+ /*BK No Limit BulkOut size .*/
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x1000) == 0x1000) && (BulkOutPipeId == 0) ))
+ {
+ /*BE Limit BulkOut size to about 4k bytes.*/
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x1c00) == 0x1c00) && (BulkOutPipeId == 2) ))
+ {
+ /*VI Limit BulkOut size to about 7k bytes.*/
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x2500) == 0x2500) && (BulkOutPipeId == 3) ))
+ {
+ /*VO Limit BulkOut size to about 9k bytes.*/
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ }
+ else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
+ {
+ /* Limit BulkOut size to about 4k bytes.*/
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+#else
+ if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
+ {
+ // Limit BulkOut size to about 4k bytes.
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+#endif // INF_AMAZON_SE //
+
+ else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
+ {
+ // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
+ // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ }
+ // end Iverson
+ else
+ {
+#ifdef INF_AMAZON_SE
+//#ifdef DOT11_N_SUPPORT
+// if(((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000) || ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)))
+// {
+// /* AMAZON_SE: BG mode Disable BulkOut Aggregate, N mode BulkOut Aggregaet size 24K */
+// pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+// break;
+// }
+// else
+//#endif // DOT11_N_SUPPORT //
+// {
+ if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && (pTxWI->AMPDU == 0))
+ {
+ if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0)) ||
+ (ThisBulkSize != 0))
+ {
+ /* AMAZON_SE: RT2070 Disable BulkOut Aggregate when WMM for USB issue */
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ }
+/*
+ else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
+ {
+ // Limit BulkOut size to about 24k bytes.
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ }
+*/
+#endif // INF_AMAZON_SE //
+
+ if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
+ { // Limit BulkOut size to about 24k bytes.
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+
+ else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
+ { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
+ // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ }
+
+ if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
+ {
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pTxInfo->QSEL != FIFO_EDCA)
+ {
+ printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __FUNCTION__, pTxInfo->QSEL);
+ printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
+ hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ if (pTxInfo->USBDMATxPktLen <= 8)
+ {
+ BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+ DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
+ pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n",
+ pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
+ ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
+ }
+ pAd->bForcePrintTX = TRUE;
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
+ return;
+ }
+
+ // Increase Total transmit byte counter
+ pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount;
+ pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount;
+
+ pLastTxInfo = pTxInfo;
+
+ // Make sure we use EDCA QUEUE.
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pTxInfo->QSEL = FIFO_EDCA; //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#endif // CONFIG_STA_SUPPORT //
+ ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
+ TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
+
+ if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
+ pTxInfo->USBDMANextVLD = 1;
+
+ if (pTxInfo->SwUseLastRound == 1)
+ {
+ if (pHTTXContext->CurWritePosition == 8)
+ pTxInfo->USBDMANextVLD = 0;
+ pTxInfo->SwUseLastRound = 0;
+
+ bTxQLastRound = TRUE;
+ pHTTXContext->ENextBulkOutPosition = 8;
+
+ #ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
+ RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+ #endif // RT_BIG_ENDIAN //
+
+ break;
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
+ RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+#endif // RT_BIG_ENDIAN //
+
+ }while (TRUE);
+
+ // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
+ if (pLastTxInfo)
+ {
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+ pLastTxInfo->USBDMANextVLD = 0;
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+ }
+
+ /*
+ We need to copy SavedPad when following condition matched!
+ 1. Not the last round of the TxQueue and
+ 2. any match of following cases:
+ (1). The End Position of this bulk out is reach to the Currenct Write position and
+ the TxInfo and related header already write to the CurWritePosition.
+ =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
+
+ (2). The EndPosition of the bulk out is not reach to the Current Write Position.
+ =>(ENextBulkOutPosition != CurWritePosition)
+ */
+ if ((bTxQLastRound == FALSE) &&
+ (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
+ (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
+ )
+ {
+ NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
+ pHTTXContext->bCopySavePad = TRUE;
+ if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
+ {
+ PUCHAR pBuf = &pHTTXContext->SavedPad[0];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
+ pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
+ pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
+
+ pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7]));
+ }
+ //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
+ }
+
+ if (pAd->bForcePrintTX == TRUE)
+ DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
+ //DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound));
+
+ // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
+ pAppendant = &pWirelessPkt[TmpBulkEndPos];
+ NdisZeroMemory(pAppendant, 8);
+ ThisBulkSize += 4;
+ pHTTXContext->LastOne = TRUE;
+ if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
+ ThisBulkSize += 4;
+ pHTTXContext->BulkOutSize = ThisBulkSize;
+
+ pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
+ BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+
+ // Init Tx context descriptor
+ RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
+
+ pUrb = pHTTXContext->pUrb;
+ if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+ pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+ return;
+ }
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pHTTXContext->IRPPending = TRUE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutReq++;
+
+}
+
+
+VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+ PHT_TX_CONTEXT pHTTXContext;
+ PRTMP_ADAPTER pAd;
+ POS_COOKIE pObj;
+ UCHAR BulkOutPipeId;
+
+
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ // Store BulkOut PipeId
+ BulkOutPipeId = pHTTXContext->BulkOutPipeId;
+ pAd->BulkOutDataOneSecCount++;
+
+ switch (BulkOutPipeId)
+ {
+ case 0:
+ pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->ac0_dma_done_task);
+ break;
+ case 1:
+ pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->ac1_dma_done_task);
+ break;
+ case 2:
+ pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->ac2_dma_done_task);
+ break;
+ case 3:
+ pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->ac3_dma_done_task);
+ break;
+ case 4:
+ pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->hcca_dma_done_task);
+ break;
+ }
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note: NULL frame use BulkOutPipeId = 0
+
+ ========================================================================
+*/
+VOID RTUSBBulkOutNullFrame(
+ IN PRTMP_ADAPTER pAd)
+{
+ PTX_CONTEXT pNullContext = &(pAd->NullContext);
+ PURB pUrb;
+ int ret = 0;
+ unsigned long IrqFlags;
+
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+ if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+ return;
+ }
+ pAd->BulkOutPending[0] = TRUE;
+ pAd->watchDogTxPendingCnt[0] = 1;
+ pNullContext->IRPPending = TRUE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+
+ // Increase Total transmit byte counter
+ pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
+
+
+ // Clear Null frame bulk flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
+
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pNullContext->TransferBuffer, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+
+ // Init Tx context descriptor
+ RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
+
+ pUrb = pNullContext->pUrb;
+ if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ {
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+ pAd->BulkOutPending[0] = FALSE;
+ pAd->watchDogTxPendingCnt[0] = 0;
+ pNullContext->IRPPending = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+
+ DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
+ return;
+ }
+
+}
+
+// NULL frame use BulkOutPipeId = 0
+VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pNullContext;
+ NTSTATUS Status;
+ POS_COOKIE pObj;
+
+
+ pNullContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pNullContext->pAd;
+ Status = pUrb->status;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ pObj->null_frame_complete_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->null_frame_complete_task);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note: MLME use BulkOutPipeId = 0
+
+ ========================================================================
+*/
+VOID RTUSBBulkOutMLMEPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ PTX_CONTEXT pMLMEContext;
+ PURB pUrb;
+ int ret = 0;
+ unsigned long IrqFlags;
+
+ pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
+ pUrb = pMLMEContext->pUrb;
+
+ if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
+ (pMLMEContext->InUse == FALSE) ||
+ (pMLMEContext->bWaitingBulkOut == FALSE))
+ {
+
+
+ // Clear MLME bulk flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+
+ return;
+ }
+
+
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+ if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+ return;
+ }
+
+ pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
+ pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
+ pMLMEContext->IRPPending = TRUE;
+ pMLMEContext->bWaitingBulkOut = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+ // Increase Total transmit byte counter
+ pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
+
+ // Clear MLME bulk flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pMLMEContext->TransferBuffer, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+
+ // Init Tx context descriptor
+ RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
+ pUrb->transfer_dma = 0;
+ pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
+#endif
+
+ pUrb = pMLMEContext->pUrb;
+ if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+ pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
+ pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
+ pMLMEContext->IRPPending = FALSE;
+ pMLMEContext->bWaitingBulkOut = TRUE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+ return;
+ }
+
+ //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
+// printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
+}
+
+
+VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+ PTX_CONTEXT pMLMEContext;
+ PRTMP_ADAPTER pAd;
+ NTSTATUS Status;
+ POS_COOKIE pObj;
+ int index;
+
+ //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
+ pMLMEContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pMLMEContext->pAd;
+ pObj = (POS_COOKIE)pAd->OS_Cookie;
+ Status = pUrb->status;
+ index = pMLMEContext->SelfIdx;
+
+ pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note: PsPoll use BulkOutPipeId = 0
+
+ ========================================================================
+*/
+VOID RTUSBBulkOutPsPoll(
+ IN PRTMP_ADAPTER pAd)
+{
+ PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
+ PURB pUrb;
+ int ret = 0;
+ unsigned long IrqFlags;
+
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+ if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+ return;
+ }
+ pAd->BulkOutPending[0] = TRUE;
+ pAd->watchDogTxPendingCnt[0] = 1;
+ pPsPollContext->IRPPending = TRUE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+
+
+ // Clear PS-Poll bulk flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
+
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pPsPollContext->TransferBuffer, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+
+ // Init Tx context descriptor
+ RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
+
+ pUrb = pPsPollContext->pUrb;
+ if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ {
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+ pAd->BulkOutPending[0] = FALSE;
+ pAd->watchDogTxPendingCnt[0] = 0;
+ pPsPollContext->IRPPending = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+
+ DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
+ return;
+ }
+
+}
+
+// PS-Poll frame use BulkOutPipeId = 0
+VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pPsPollContext;
+ NTSTATUS Status;
+ POS_COOKIE pObj;
+
+
+ pPsPollContext= (PTX_CONTEXT)pUrb->context;
+ pAd = pPsPollContext->pAd;
+ Status = pUrb->status;
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
+
+}
+
+VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
+{
+ PRX_CONTEXT pRxContext;
+ PURB pUrb;
+ int ret = 0;
+ unsigned long IrqFlags;
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
+ if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ return;
+ }
+ pRxContext->InUse = TRUE;
+ pRxContext->IRPPending = TRUE;
+ pAd->PendingRx++;
+ pAd->BulkInReq++;
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+ // Init Rx context descriptor
+ NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
+ RTUSBInitRxDesc(pAd, pRxContext);
+
+ pUrb = pRxContext->pUrb;
+ if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ { // fail
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pAd->PendingRx--;
+ pAd->BulkInReq--;
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
+ }
+ else
+ { // success
+ ASSERT((pRxContext->InUse == pRxContext->IRPPending));
+ //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
+ }
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ USB_RxPacket initializes a URB and uses the Rx IRP to submit it
+ to USB. It checks if an Rx Descriptor is available and passes the
+ the coresponding buffer to be filled. If no descriptor is available
+ fails the request. When setting the completion routine we pass our
+ Adapter Object as Context.
+
+ Arguments:
+
+ Return Value:
+ TRUE found matched tuple cache
+ FALSE no matched found
+
+ Note:
+
+ ========================================================================
+*/
+#define fRTMP_ADAPTER_NEED_STOP_RX \
+ (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
+ fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
+ fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
+
+#define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \
+ (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
+ fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
+ fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
+
+VOID RTUSBBulkReceive(
+ IN PRTMP_ADAPTER pAd)
+{
+ PRX_CONTEXT pRxContext;
+ unsigned long IrqFlags;
+
+
+ /* sanity check */
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
+ return;
+
+ while(1)
+ {
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
+ if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
+ (pRxContext->bRxHandling == FALSE))
+ {
+ pRxContext->bRxHandling = TRUE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+ // read RxContext, Since not
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ STARxDoneInterruptHandle(pAd, TRUE);
+#endif // CONFIG_STA_SUPPORT //
+
+ // Finish to handle this bulkIn buffer.
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext->BulkInOffset = 0;
+ pRxContext->Readable = FALSE;
+ pRxContext->bRxHandling = FALSE;
+ pAd->ReadPosition = 0;
+ pAd->TransferBufferLength = 0;
+ INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ break;
+ }
+ }
+
+ if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
+ DoBulkIn(pAd);
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ This routine process Rx Irp and call rx complete function.
+
+ Arguments:
+ DeviceObject Pointer to the device object for next lower
+ device. DeviceObject passed in here belongs to
+ the next lower driver in the stack because we
+ were invoked via IoCallDriver in USB_RxPacket
+ AND it is not OUR device object
+ Irp Ptr to completed IRP
+ Context Ptr to our Adapter object (context specified
+ in IoSetCompletionRoutine
+
+ Return Value:
+ Always returns STATUS_MORE_PROCESSING_REQUIRED
+
+ Note:
+ Always returns STATUS_MORE_PROCESSING_REQUIRED
+ ========================================================================
+*/
+VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+ // use a receive tasklet to handle received packets;
+ // or sometimes hardware IRQ will be disabled here, so we can not
+ // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
+ PRX_CONTEXT pRxContext;
+ PRTMP_ADAPTER pAd;
+ POS_COOKIE pObj;
+
+
+ pRxContext = (PRX_CONTEXT)pUrb->context;
+ pAd = pRxContext->pAd;
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ pObj->rx_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->rx_done_task);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBKickBulkOut(
+ IN PRTMP_ADAPTER pAd)
+{
+ // BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
+ if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
+#ifdef RALINK_ATE
+ && !(ATE_ON(pAd))
+#endif // RALINK_ATE //
+ )
+ {
+ // 2. PS-Poll frame is next
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
+ {
+ RTUSBBulkOutPsPoll(pAd);
+ }
+
+ // 5. Mlme frame is next
+ else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
+ (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
+ {
+ RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
+ }
+
+ // 6. Data frame normal is next
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
+ {
+ if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ ))
+ {
+ RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
+ }
+ }
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
+ {
+ if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ ))
+ {
+ RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
+ }
+ }
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
+ {
+ if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ ))
+ {
+ RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
+ }
+ }
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
+ {
+ if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ ))
+ {
+ RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
+ }
+ }
+ //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_5))
+ {
+ if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ ))
+ {
+ }
+ }
+
+ // 7. Null frame is the last
+ else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
+ {
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ {
+ RTUSBBulkOutNullFrame(pAd);
+ }
+ }
+
+ // 8. No data avaliable
+ else
+ {
+
+ }
+ }
+#ifdef RALINK_ATE
+ /* If the mode is in ATE mode. */
+ else if((ATE_ON(pAd)) &&
+ !RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX))// PETER : watch out !
+ {
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE))
+ {
+ ATE_RTUSBBulkOutDataPacket(pAd, 0);
+ }
+ }
+#endif // RALINK_ATE //
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Call from Reset action after BulkOut failed.
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBCleanUpDataBulkOutQueue(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR Idx;
+ PHT_TX_CONTEXT pTxContext;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
+
+ for (Idx = 0; Idx < 4; Idx++)
+ {
+ pTxContext = &pAd->TxContext[Idx];
+
+ pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
+ pTxContext->LastOne = FALSE;
+ NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
+ pAd->BulkOutPending[Idx] = FALSE;
+ NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBCleanUpMLMEBulkOutQueue(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBCancelPendingIRPs(
+ IN PRTMP_ADAPTER pAd)
+{
+ RTUSBCancelPendingBulkInIRP(pAd);
+ RTUSBCancelPendingBulkOutIRP(pAd);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBCancelPendingBulkInIRP(
+ IN PRTMP_ADAPTER pAd)
+{
+ PRX_CONTEXT pRxContext;
+ UINT i;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
+ for ( i = 0; i < (RX_RING_SIZE); i++)
+ {
+ pRxContext = &(pAd->RxContext[i]);
+ if(pRxContext->IRPPending == TRUE)
+ {
+ RTUSB_UNLINK_URB(pRxContext->pUrb);
+ pRxContext->IRPPending = FALSE;
+ pRxContext->InUse = FALSE;
+ //NdisInterlockedDecrement(&pAd->PendingRx);
+ //pAd->PendingRx--;
+ }
+ }
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBCancelPendingBulkOutIRP(
+ IN PRTMP_ADAPTER pAd)
+{
+ PHT_TX_CONTEXT pHTTXContext;
+ PTX_CONTEXT pMLMEContext;
+ PTX_CONTEXT pBeaconContext;
+ PTX_CONTEXT pNullContext;
+ PTX_CONTEXT pPsPollContext;
+ PTX_CONTEXT pRTSContext;
+ UINT i, Idx;
+// unsigned int IrqFlags;
+// NDIS_SPIN_LOCK *pLock;
+// BOOLEAN *pPending;
+
+
+// pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
+// pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
+
+ for (Idx = 0; Idx < 4; Idx++)
+ {
+ pHTTXContext = &(pAd->TxContext[Idx]);
+
+ if (pHTTXContext->IRPPending == TRUE)
+ {
+
+ // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
+ // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
+ // when the last IRP on the list has been cancelled; that's how we exit this loop
+ //
+
+ RTUSB_UNLINK_URB(pHTTXContext->pUrb);
+
+ // Sleep 200 microseconds to give cancellation time to work
+ RTMPusecDelay(200);
+ }
+
+#ifdef RALINK_ATE
+ pHTTXContext->bCopySavePad = 0;
+ pHTTXContext->CurWritePosition = 0;
+ pHTTXContext->CurWriteRealPos = 0;
+ pHTTXContext->bCurWriting = FALSE;
+ pHTTXContext->NextBulkOutPosition = 0;
+ pHTTXContext->ENextBulkOutPosition = 0;
+#endif // RALINK_ATE //
+ pAd->BulkOutPending[Idx] = FALSE;
+ }
+
+ //RTMP_IRQ_LOCK(pLock, IrqFlags);
+ for (i = 0; i < MGMT_RING_SIZE; i++)
+ {
+ pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
+ if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
+ {
+
+ // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
+ // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
+ // when the last IRP on the list has been cancelled; that's how we exit this loop
+ //
+
+ RTUSB_UNLINK_URB(pMLMEContext->pUrb);
+ pMLMEContext->IRPPending = FALSE;
+
+ // Sleep 200 microsecs to give cancellation time to work
+ RTMPusecDelay(200);
+ }
+ }
+ pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
+ //RTMP_IRQ_UNLOCK(pLock, IrqFlags);
+
+
+ for (i = 0; i < BEACON_RING_SIZE; i++)
+ {
+ pBeaconContext = &(pAd->BeaconContext[i]);
+
+ if(pBeaconContext->IRPPending == TRUE)
+ {
+
+ // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
+ // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
+ // when the last IRP on the list has been cancelled; that's how we exit this loop
+ //
+
+ RTUSB_UNLINK_URB(pBeaconContext->pUrb);
+
+ // Sleep 200 microsecs to give cancellation time to work
+ RTMPusecDelay(200);
+ }
+ }
+
+ pNullContext = &(pAd->NullContext);
+ if (pNullContext->IRPPending == TRUE)
+ RTUSB_UNLINK_URB(pNullContext->pUrb);
+
+ pRTSContext = &(pAd->RTSContext);
+ if (pRTSContext->IRPPending == TRUE)
+ RTUSB_UNLINK_URB(pRTSContext->pUrb);
+
+ pPsPollContext = &(pAd->PsPollContext);
+ if (pPsPollContext->IRPPending == TRUE)
+ RTUSB_UNLINK_URB(pPsPollContext->pUrb);
+
+ for (Idx = 0; Idx < 4; Idx++)
+ {
+ NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
+ pAd->BulkOutPending[Idx] = FALSE;
+ NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
+ }
+}
+
diff --git a/drivers/staging/rt3070/common/rtusb_data.c b/drivers/staging/rt3070/common/rtusb_data.c
new file mode 100644
index 00000000000..521309a2ae5
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtusb_data.c
@@ -0,0 +1,218 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtusb_data.c
+
+ Abstract:
+ Ralink USB driver Tx/Rx functions.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan 03-25-2006 created
+
+*/
+#include "../rt_config.h"
+
+extern UCHAR Phy11BGNextRateUpward[]; // defined in mlme.c
+extern UCHAR EpToQueue[];
+
+
+VOID REPORT_AMSDU_FRAMES_TO_LLC(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataSize)
+{
+ PNDIS_PACKET pPacket;
+ UINT nMSDU;
+ struct sk_buff *pSkb;
+
+ nMSDU = 0;
+ /* allocate a rx packet */
+ pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE);
+ pPacket = (PNDIS_PACKET)OSPKT_TO_RTPKT(pSkb);
+ if (pSkb)
+ {
+
+ /* convert 802.11 to 802.3 packet */
+ pSkb->dev = get_netdev_from_bssid(pAd, BSS0);
+ RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+ deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("Can't allocate skb\n"));
+ }
+}
+
+NDIS_STATUS RTUSBFreeDescriptorRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BulkOutPipeId,
+ IN UINT32 NumberRequired)
+{
+// UCHAR FreeNumber = 0;
+// UINT Index;
+ NDIS_STATUS Status = NDIS_STATUS_FAILURE;
+ unsigned long IrqFlags;
+ HT_TX_CONTEXT *pHTTXContext;
+
+
+ pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+ if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition) && ((pHTTXContext->CurWritePosition + NumberRequired + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition))
+ {
+
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+ }
+ else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < (NumberRequired + LOCAL_TXBUF_SIZE)))
+ {
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+ }
+ else if (pHTTXContext->bCurWriting == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n", BulkOutPipeId, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+ }
+ else
+ {
+ Status = NDIS_STATUS_SUCCESS;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+
+ return (Status);
+}
+
+
+NDIS_STATUS RTUSBFreeDescriptorRelease(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR BulkOutPipeId)
+{
+ unsigned long IrqFlags;
+ HT_TX_CONTEXT *pHTTXContext;
+
+ pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+ pHTTXContext->bCurWriting = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+ return (NDIS_STATUS_SUCCESS);
+}
+
+
+BOOLEAN RTUSBNeedQueueBackForAgg(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR BulkOutPipeId)
+{
+ unsigned long IrqFlags;
+ HT_TX_CONTEXT *pHTTXContext;
+ BOOLEAN needQueBack = FALSE;
+
+ pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+ if ((pHTTXContext->IRPPending == TRUE) /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */)
+ {
+ if ((pHTTXContext->CurWritePosition < pHTTXContext->ENextBulkOutPosition) &&
+ (((pHTTXContext->ENextBulkOutPosition+MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT) || (pHTTXContext->CurWritePosition > MAX_AGGREGATION_SIZE)))
+ {
+ needQueBack = TRUE;
+ }
+ else if ((pHTTXContext->CurWritePosition > pHTTXContext->ENextBulkOutPosition) &&
+ ((pHTTXContext->ENextBulkOutPosition + MAX_AGGREGATION_SIZE) < pHTTXContext->CurWritePosition))
+ {
+ needQueBack = TRUE;
+ }
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+ return needQueBack;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBRejectPendingPackets(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR Index;
+ PQUEUE_ENTRY pEntry;
+ PNDIS_PACKET pPacket;
+ PQUEUE_HEADER pQueue;
+
+
+ for (Index = 0; Index < 4; Index++)
+ {
+ NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]);
+ while (pAd->TxSwQueue[Index].Head != NULL)
+ {
+ pQueue = (PQUEUE_HEADER) &(pAd->TxSwQueue[Index]);
+ pEntry = RemoveHeadQueue(pQueue);
+ pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+ NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]);
+
+ }
+
+}
+
+VOID RTMPWriteTxInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXINFO_STRUC pTxInfo,
+ IN USHORT USBDMApktLen,
+ IN BOOLEAN bWiv,
+ IN UCHAR QueueSel,
+ IN UCHAR NextValid,
+ IN UCHAR TxBurst)
+{
+ pTxInfo->USBDMATxPktLen = USBDMApktLen;
+ pTxInfo->QSEL = QueueSel;
+ if (QueueSel != FIFO_EDCA)
+ DBGPRINT(RT_DEBUG_TRACE, ("====> QueueSel != FIFO_EDCA<============\n"));
+ pTxInfo->USBDMANextVLD = FALSE; //NextValid; // Need to check with Jan about this.
+ pTxInfo->USBDMATxburst = TxBurst;
+ pTxInfo->WIV = bWiv;
+ pTxInfo->SwUseLastRound = 0;
+ pTxInfo->rsv = 0;
+ pTxInfo->rsv2 = 0;
+}
+
diff --git a/drivers/staging/rt3070/common/rtusb_io.c b/drivers/staging/rt3070/common/rtusb_io.c
new file mode 100644
index 00000000000..a6a52e3445f
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtusb_io.c
@@ -0,0 +1,1908 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtusb_io.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 06-25-2004 created
+*/
+
+#include "../rt_config.h"
+
+
+/*
+ ========================================================================
+
+ Routine Description: NIC initialization complete
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+
+NTSTATUS RTUSBFirmwareRun(
+ IN PRTMP_ADAPTER pAd)
+{
+ NTSTATUS Status;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x01,
+ 0x8,
+ 0,
+ NULL,
+ 0);
+
+ return Status;
+}
+
+
+
+/*
+ ========================================================================
+
+ Routine Description: Write Firmware to NIC.
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBFirmwareWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pFwImage,
+ IN ULONG FwLen)
+{
+ UINT32 MacReg;
+ NTSTATUS Status;
+// ULONG i;
+ USHORT writeLen;
+
+ Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg);
+
+
+ writeLen = FwLen;
+ RTUSBMultiWrite(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen);
+
+ Status = RTUSBWriteMACRegister(pAd, 0x7014, 0xffffffff);
+ Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff);
+ Status = RTUSBFirmwareRun(pAd);
+
+ RTMPusecDelay(10000);
+ RTUSBWriteMACRegister(pAd,H2M_MAILBOX_CSR,0);
+ AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00);//reset rf by MCU supported by new firmware
+
+ return Status;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description: Get current firmware operation mode (Return Value)
+
+ Arguments:
+
+ Return Value:
+ 0 or 1 = Downloaded by host driver
+ others = Driver doesn't download firmware
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBFirmwareOpmode(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUINT32 pValue)
+{
+ NTSTATUS Status;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
+ DEVICE_VENDOR_REQUEST_IN,
+ 0x1,
+ 0x11,
+ 0,
+ pValue,
+ 4);
+ return Status;
+}
+NTSTATUS RTUSBVenderReset(
+ IN PRTMP_ADAPTER pAd)
+{
+ NTSTATUS Status;
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("-->RTUSBVenderReset\n"));
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x01,
+ 0x1,
+ 0,
+ NULL,
+ 0);
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("<--RTUSBVenderReset\n"));
+ return Status;
+}
+/*
+ ========================================================================
+
+ Routine Description: Read various length data from RT2573
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBMultiRead(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUCHAR pData,
+ IN USHORT length)
+{
+ NTSTATUS Status;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
+ DEVICE_VENDOR_REQUEST_IN,
+ 0x7,
+ 0,
+ Offset,
+ pData,
+ length);
+
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description: Write various length data to RT2573
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBMultiWrite_OneByte(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData)
+{
+ NTSTATUS Status;
+
+ // TODO: In 2870, use this funciton carefully cause it's not stable.
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x6,
+ 0,
+ Offset,
+ pData,
+ 1);
+
+ return Status;
+}
+
+NTSTATUS RTUSBMultiWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData,
+ IN USHORT length)
+{
+ NTSTATUS Status;
+
+
+ USHORT index = 0,Value;
+ PUCHAR pSrc = pData;
+ USHORT resude = 0;
+
+ resude = length % 2;
+ length += resude;
+ do
+ {
+ Value =(USHORT)( *pSrc | (*(pSrc + 1) << 8));
+ Status = RTUSBSingleWrite(pAd,Offset + index,Value);
+ index +=2;
+ length -= 2;
+ pSrc = pSrc + 2;
+ }while(length > 0);
+
+ return Status;
+}
+
+
+NTSTATUS RTUSBSingleWrite(
+ IN RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ IN USHORT Value)
+{
+ NTSTATUS Status;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x2,
+ Value,
+ Offset,
+ NULL,
+ 0);
+
+ return Status;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description: Read 32-bit MAC register
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBReadMACRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUINT32 pValue)
+{
+ NTSTATUS Status;
+ UINT32 localVal;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
+ DEVICE_VENDOR_REQUEST_IN,
+ 0x7,
+ 0,
+ Offset,
+ &localVal,
+ 4);
+
+ *pValue = le2cpu32(localVal);
+
+
+ if (Status < 0)
+ *pValue = 0xffffffff;
+
+ return Status;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description: Write 32-bit MAC register
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBWriteMACRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN UINT32 Value)
+{
+ NTSTATUS Status;
+ UINT32 localVal;
+
+ localVal = Value;
+
+ Status = RTUSBSingleWrite(pAd, Offset, (USHORT)(localVal & 0xffff));
+ Status = RTUSBSingleWrite(pAd, Offset + 2, (USHORT)((localVal & 0xffff0000) >> 16));
+
+ return Status;
+}
+
+
+
+#if 1
+/*
+ ========================================================================
+
+ Routine Description: Read 8-bit BBP register
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBReadBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN PUCHAR pValue)
+{
+ BBP_CSR_CFG_STRUC BbpCsr;
+ UINT i = 0;
+ NTSTATUS status;
+
+ // Verify the busy condition
+ do
+ {
+ status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
+ if(status >= 0)
+ {
+ if (!(BbpCsr.field.Busy == BUSY))
+ break;
+ }
+ printk("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n", i);
+ i++;
+ }
+ while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+ if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ //
+ // Read failed then Return Default value.
+ //
+ *pValue = pAd->BbpWriteLatch[Id];
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ // Prepare for write material
+ BbpCsr.word = 0;
+ BbpCsr.field.fRead = 1;
+ BbpCsr.field.Busy = 1;
+ BbpCsr.field.RegNum = Id;
+ RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
+
+ i = 0;
+ // Verify the busy condition
+ do
+ {
+ status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
+ if (status >= 0)
+ {
+ if (!(BbpCsr.field.Busy == BUSY))
+ {
+ *pValue = (UCHAR)BbpCsr.field.Value;
+ break;
+ }
+ }
+ printk("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n", i);
+ i++;
+ }
+ while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+ if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ //
+ // Read failed then Return Default value.
+ //
+ *pValue = pAd->BbpWriteLatch[Id];
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ return STATUS_SUCCESS;
+}
+#else
+/*
+ ========================================================================
+
+ Routine Description: Read 8-bit BBP register via firmware
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBReadBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN PUCHAR pValue)
+{
+ BBP_CSR_CFG_STRUC BbpCsr;
+ int i, k;
+ for (i=0; i<MAX_BUSY_COUNT; i++)
+ {
+ RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+ if (BbpCsr.field.Busy == BUSY)
+ {
+ continue;
+ }
+ BbpCsr.word = 0;
+ BbpCsr.field.fRead = 1;
+ BbpCsr.field.BBP_RW_MODE = 1;
+ BbpCsr.field.Busy = 1;
+ BbpCsr.field.RegNum = Id;
+ RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, BbpCsr.word);
+ AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
+ for (k=0; k<MAX_BUSY_COUNT; k++)
+ {
+ RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+ if (BbpCsr.field.Busy == IDLE)
+ break;
+ }
+ if ((BbpCsr.field.Busy == IDLE) &&
+ (BbpCsr.field.RegNum == Id))
+ {
+ *pValue = (UCHAR)BbpCsr.field.Value;
+ break;
+ }
+ }
+ if (BbpCsr.field.Busy == BUSY)
+ {
+ DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", Id, BbpCsr.word));
+ *pValue = pAd->BbpWriteLatch[Id];
+ return STATUS_UNSUCCESSFUL;
+ }
+ return STATUS_SUCCESS;
+}
+#endif
+
+#if 1
+/*
+ ========================================================================
+
+ Routine Description: Write 8-bit BBP register
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBWriteBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN UCHAR Value)
+{
+ BBP_CSR_CFG_STRUC BbpCsr;
+ UINT i = 0;
+ NTSTATUS status;
+ // Verify the busy condition
+ do
+ {
+ status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
+ if (status >= 0)
+ {
+ if (!(BbpCsr.field.Busy == BUSY))
+ break;
+ }
+ printk("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i);
+ i++;
+ }
+ while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+ if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ // Prepare for write material
+ BbpCsr.word = 0;
+ BbpCsr.field.fRead = 0;
+ BbpCsr.field.Value = Value;
+ BbpCsr.field.Busy = 1;
+ BbpCsr.field.RegNum = Id;
+ RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
+
+ pAd->BbpWriteLatch[Id] = Value;
+
+ return STATUS_SUCCESS;
+}
+#else
+/*
+ ========================================================================
+
+ Routine Description: Write 8-bit BBP register via firmware
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+
+NTSTATUS RTUSBWriteBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN UCHAR Value)
+
+{
+ BBP_CSR_CFG_STRUC BbpCsr;
+ int BusyCnt;
+ for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)
+ {
+ RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+ if (BbpCsr.field.Busy == BUSY)
+ continue;
+ BbpCsr.word = 0;
+ BbpCsr.field.fRead = 0;
+ BbpCsr.field.BBP_RW_MODE = 1;
+ BbpCsr.field.Busy = 1;
+ BbpCsr.field.Value = Value;
+ BbpCsr.field.RegNum = Id;
+ RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
+ AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
+ pAd->BbpWriteLatch[Id] = Value;
+ break;
+ }
+ if (BusyCnt == MAX_BUSY_COUNT)
+ {
+ DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", Id, BbpCsr.word));
+ return STATUS_UNSUCCESSFUL;
+ }
+ return STATUS_SUCCESS;
+}
+#endif
+/*
+ ========================================================================
+
+ Routine Description: Write RF register through MAC
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBWriteRFRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 Value)
+{
+ PHY_CSR4_STRUC PhyCsr4;
+ UINT i = 0;
+ NTSTATUS status;
+
+ NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC));
+ do
+ {
+ status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word);
+ if (status >= 0)
+ {
+ if (!(PhyCsr4.field.Busy))
+ break;
+ }
+ printk("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i);
+ i++;
+ }
+ while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+ if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value);
+
+ return STATUS_SUCCESS;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBReadEEPROM(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUCHAR pData,
+ IN USHORT length)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+#ifdef RT30xx
+ if(pAd->bUseEfuse)
+ {
+ Status =eFuseRead(pAd, Offset, pData, length);
+ }
+ else
+#endif // RT30xx //
+ {
+ Status = RTUSB_VendorRequest(
+ pAd,
+ (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
+ DEVICE_VENDOR_REQUEST_IN,
+ 0x9,
+ 0,
+ Offset,
+ pData,
+ length);
+ }
+
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBWriteEEPROM(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData,
+ IN USHORT length)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+#ifdef RT30xx
+ if(pAd->bUseEfuse)
+ {
+ Status = eFuseWrite(pAd, Offset, pData, length);
+ }
+ else
+#endif // RT30xx //
+ {
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x8,
+ 0,
+ Offset,
+ pData,
+ length);
+ }
+
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBPutToSleep(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 value;
+
+ // Timeout 0x40 x 50us
+ value = (SLEEPCID<<16)+(OWNERMCU<<24)+ (0x40<<8)+1;
+ RTUSBWriteMACRegister(pAd, 0x7010, value);
+ RTUSBWriteMACRegister(pAd, 0x404, 0x30);
+ //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value));
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBWakeUp(
+ IN PRTMP_ADAPTER pAd)
+{
+ NTSTATUS Status;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x01,
+ 0x09,
+ 0,
+ NULL,
+ 0);
+
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBInitializeCmdQ(
+ IN PCmdQ cmdq)
+{
+ cmdq->head = NULL;
+ cmdq->tail = NULL;
+ cmdq->size = 0;
+ cmdq->CmdQState = RT2870_THREAD_INITED;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS RTUSBEnqueueCmdFromNdis(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_OID Oid,
+ IN BOOLEAN SetInformation,
+ IN PVOID pInformationBuffer,
+ IN UINT32 InformationBufferLength)
+{
+ NDIS_STATUS status;
+ PCmdQElmt cmdqelmt = NULL;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+
+ if (pObj->RTUSBCmdThr_pid < 0)
+ return (NDIS_STATUS_RESOURCES);
+
+ status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
+ if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
+ return (NDIS_STATUS_RESOURCES);
+
+ cmdqelmt->buffer = NULL;
+ if (pInformationBuffer != NULL)
+ {
+ status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
+ if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
+ {
+ kfree(cmdqelmt);
+ return (NDIS_STATUS_RESOURCES);
+ }
+ else
+ {
+ NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
+ cmdqelmt->bufferlength = InformationBufferLength;
+ }
+ }
+ else
+ cmdqelmt->bufferlength = 0;
+
+ cmdqelmt->command = Oid;
+ cmdqelmt->CmdFromNdis = TRUE;
+ if (SetInformation == TRUE)
+ cmdqelmt->SetOperation = TRUE;
+ else
+ cmdqelmt->SetOperation = FALSE;
+
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
+ {
+ EnqueueCmd((&pAd->CmdQ), cmdqelmt);
+ status = NDIS_STATUS_SUCCESS;
+ }
+ else
+ {
+ status = NDIS_STATUS_FAILURE;
+ }
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+
+ if (status == NDIS_STATUS_FAILURE)
+ {
+ if (cmdqelmt->buffer)
+ NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
+ NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+ }
+ else
+ RTUSBCMDUp(pAd);
+
+
+ return(NDIS_STATUS_SUCCESS);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS RTUSBEnqueueInternalCmd(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_OID Oid,
+ IN PVOID pInformationBuffer,
+ IN UINT32 InformationBufferLength)
+{
+ NDIS_STATUS status;
+ PCmdQElmt cmdqelmt = NULL;
+
+
+ status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
+ if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
+ return (NDIS_STATUS_RESOURCES);
+ NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt));
+
+ if(InformationBufferLength > 0)
+ {
+ status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
+ if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
+ {
+ NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+ return (NDIS_STATUS_RESOURCES);
+ }
+ else
+ {
+ NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
+ cmdqelmt->bufferlength = InformationBufferLength;
+ }
+ }
+ else
+ {
+ cmdqelmt->buffer = NULL;
+ cmdqelmt->bufferlength = 0;
+ }
+
+ cmdqelmt->command = Oid;
+ cmdqelmt->CmdFromNdis = FALSE;
+
+ if (cmdqelmt != NULL)
+ {
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
+ {
+ EnqueueCmd((&pAd->CmdQ), cmdqelmt);
+ status = NDIS_STATUS_SUCCESS;
+ }
+ else
+ {
+ status = NDIS_STATUS_FAILURE;
+ }
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+
+ if (status == NDIS_STATUS_FAILURE)
+ {
+ if (cmdqelmt->buffer)
+ NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
+ NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+ }
+ else
+ RTUSBCMDUp(pAd);
+ }
+ return(NDIS_STATUS_SUCCESS);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBDequeueCmd(
+ IN PCmdQ cmdq,
+ OUT PCmdQElmt *pcmdqelmt)
+{
+ *pcmdqelmt = cmdq->head;
+
+ if (*pcmdqelmt != NULL)
+ {
+ cmdq->head = cmdq->head->next;
+ cmdq->size--;
+ if (cmdq->size == 0)
+ cmdq->tail = NULL;
+ }
+}
+
+/*
+ ========================================================================
+ usb_control_msg - Builds a control urb, sends it off and waits for completion
+ @dev: pointer to the usb device to send the message to
+ @pipe: endpoint "pipe" to send the message to
+ @request: USB message request value
+ @requesttype: USB message request type value
+ @value: USB message value
+ @index: USB message index value
+ @data: pointer to the data to send
+ @size: length in bytes of the data to send
+ @timeout: time in jiffies to wait for the message to complete before
+ timing out (if 0 the wait is forever)
+ Context: !in_interrupt ()
+
+ This function sends a simple control message to a specified endpoint
+ and waits for the message to complete, or timeout.
+ If successful, it returns the number of bytes transferred, otherwise a negative error number.
+
+ Don't use this function from within an interrupt context, like a
+ bottom half handler. If you need an asynchronous message, or need to send
+ a message from within interrupt context, use usb_submit_urb()
+ If a thread in your driver uses this call, make sure your disconnect()
+ method can wait for it to complete. Since you don't have a handle on
+ the URB used, you can't cancel the request.
+
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSB_VendorRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 TransferFlags,
+ IN UCHAR RequestType,
+ IN UCHAR Request,
+ IN USHORT Value,
+ IN USHORT Index,
+ IN PVOID TransferBuffer,
+ IN UINT32 TransferBufferLength)
+{
+ int ret;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n"));
+ return -1;
+ }
+ else if (in_interrupt())
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",Request,Value,Index));
+
+ return -1;
+ }
+ else
+ {
+#define MAX_RETRY_COUNT 10
+
+ int retryCount = 0;
+ void *tmpBuf = TransferBuffer;
+
+ // Acquire Control token
+#ifdef INF_AMAZON_SE
+ ret = down_interruptible(&(pAd->UsbVendorReq_semaphore));
+ if (pAd->UsbVendorReqBuf)
+ {
+ ASSERT(TransferBufferLength <MAX_PARAM_BUFFER_SIZE);
+
+ tmpBuf = (void *)pAd->UsbVendorReqBuf;
+ NdisZeroMemory(pAd->UsbVendorReqBuf, TransferBufferLength);
+
+ if (RequestType == DEVICE_VENDOR_REQUEST_OUT)
+ NdisMoveMemory(tmpBuf, TransferBuffer, TransferBufferLength);
+ }
+#endif // INF_AMAZON_SE //
+ do {
+ if( RequestType == DEVICE_VENDOR_REQUEST_OUT)
+ ret=usb_control_msg(pObj->pUsb_Dev, usb_sndctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
+ else if(RequestType == DEVICE_VENDOR_REQUEST_IN)
+ ret=usb_control_msg(pObj->pUsb_Dev, usb_rcvctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n"));
+ ret = -1;
+ }
+
+ retryCount++;
+ if (ret < 0) {
+ printk("#\n");
+ RTMPusecDelay(5000);
+ }
+ } while((ret < 0) && (retryCount < MAX_RETRY_COUNT));
+
+#ifdef INF_AMAZON_SE
+ if ((pAd->UsbVendorReqBuf) && (RequestType == DEVICE_VENDOR_REQUEST_IN))
+ NdisMoveMemory(TransferBuffer, tmpBuf, TransferBufferLength);
+ up(&(pAd->UsbVendorReq_semaphore));
+#endif // INF_AMAZON_SE //
+
+ if (ret < 0) {
+// DBGPRINT(RT_DEBUG_ERROR, ("USBVendorRequest failed ret=%d \n",ret));
+ DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n",
+ ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index));
+ if (Request == 0x2)
+ DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value));
+
+ if ((TransferBuffer!= NULL) && (TransferBufferLength > 0))
+ hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength);
+ }
+ }
+ return ret;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT
+ synchronously. Callers of this function must be running at
+ PASSIVE LEVEL.
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSB_ResetDevice(
+ IN PRTMP_ADAPTER pAd)
+{
+ NTSTATUS Status = TRUE;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n"));
+ //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
+ return Status;
+}
+
+VOID CMDHandler(
+ IN PRTMP_ADAPTER pAd)
+{
+ PCmdQElmt cmdqelmt;
+ PUCHAR pData;
+ NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
+// ULONG Now = 0;
+ NTSTATUS ntStatus;
+// unsigned long IrqFlags;
+
+ while (pAd->CmdQ.size > 0)
+ {
+ NdisStatus = NDIS_STATUS_SUCCESS;
+
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt);
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+
+ if (cmdqelmt == NULL)
+ break;
+
+ pData = cmdqelmt->buffer;
+
+ if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
+ {
+ switch (cmdqelmt->command)
+ {
+ case CMDTHREAD_CHECK_GPIO:
+ {
+#ifdef CONFIG_STA_SUPPORT
+ UINT32 data;
+#endif // CONFIG_STA_SUPPORT //
+#ifdef RALINK_ATE
+ if(ATE_ON(pAd))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+ break;
+ }
+#endif // RALINK_ATE //
+
+#ifdef CONFIG_STA_SUPPORT
+
+
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Read GPIO pin2 as Hardware controlled radio state
+
+ RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data);
+
+ if (data & 0x04)
+ {
+ pAd->StaCfg.bHwRadio = TRUE;
+ }
+ else
+ {
+ pAd->StaCfg.bHwRadio = FALSE;
+ }
+
+ if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
+ {
+ pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
+ if(pAd->StaCfg.bRadio == TRUE)
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n"));
+
+ MlmeRadioOn(pAd);
+ // Update extra information
+ pAd->ExtraInfo = EXTRA_INFO_CLEAR;
+ }
+ else
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n"));
+
+ MlmeRadioOff(pAd);
+ // Update extra information
+ pAd->ExtraInfo = HW_RADIO_OFF;
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ break;
+
+#ifdef CONFIG_STA_SUPPORT
+ case CMDTHREAD_QKERIODIC_EXECUT:
+ {
+ StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL);
+ }
+ break;
+#endif // CONFIG_STA_SUPPORT //
+
+ case CMDTHREAD_RESET_BULK_OUT:
+ {
+ UINT32 MACValue;
+ UCHAR Index;
+ int ret=0;
+ PHT_TX_CONTEXT pHTTXContext;
+// RTMP_TX_RING *pTxRing;
+ unsigned long IrqFlags;
+#ifdef RALINK_ATE
+ PTX_CONTEXT pNullContext = &(pAd->NullContext);
+#endif // RALINK_ATE //
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid));
+ // All transfers must be aborted or cancelled before attempting to reset the pipe.
+ //RTUSBCancelPendingBulkOutIRP(pAd);
+ // Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007
+ Index = 0;
+ do
+ {
+ RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue);
+ if ((MACValue & 0xf00000/*0x800000*/) == 0)
+ break;
+ Index++;
+ RTMPusecDelay(10000);
+ }while(Index < 100);
+ MACValue = 0;
+ RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
+ // To prevent Read Register error, we 2nd check the validity.
+ if ((MACValue & 0xc00000) == 0)
+ RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
+ // To prevent Read Register error, we 3rd check the validity.
+ if ((MACValue & 0xc00000) == 0)
+ RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
+ MACValue |= 0x80000;
+ RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
+
+ // Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
+ RTMPusecDelay(1000);
+
+ MACValue &= (~0x80000);
+ RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
+
+ // Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
+ //RTMPusecDelay(5000);
+
+ if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)
+ {
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
+ {
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+ }
+ RTUSBKickBulkOut(pAd);
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n"));
+ }
+ else
+ {
+ pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]);
+ //NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
+ RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+ if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE)
+ {
+ pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE;
+ pHTTXContext->IRPPending = TRUE;
+ pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1;
+
+ // no matter what, clean the flag
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+
+ //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
+ RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+/*-----------------------------------------------------------------------------------------------*/
+#ifdef RALINK_ATE
+ if(ATE_ON(pAd))
+ {
+ pNullContext->IRPPending = TRUE;
+ //
+ // If driver is still in ATE TXFRAME mode,
+ // keep on transmitting ATE frames.
+ //
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("pAd->ate.Mode == %d\npAd->ContinBulkOut == %d\npAd->BulkOutRemained == %d\n", pAd->ate.Mode, pAd->ContinBulkOut, atomic_read(&pAd->BulkOutRemained)));
+ if((pAd->ate.Mode == ATE_TXFRAME) && ((pAd->ContinBulkOut == TRUE) || (atomic_read(&pAd->BulkOutRemained) > 0)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("After CMDTHREAD_RESET_BULK_OUT, continue to bulk out frames !\n"));
+
+ // Init Tx context descriptor
+ RTUSBInitTxDesc(pAd, pNullContext, 0/* pAd->bulkResetPipeid */, (usb_complete_t)ATE_RTUSBBulkOutDataPacketComplete);
+
+ if((ret = RTUSB_SUBMIT_URB(pNullContext->pUrb))!=0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
+ }
+
+ pAd->BulkOutReq++;
+ }
+ }
+ else
+#endif // RALINK_ATE //
+/*-----------------------------------------------------------------------------------------------*/
+ {
+ RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
+
+ if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0)
+ {
+ RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+ pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE;
+ pHTTXContext->IRPPending = FALSE;
+ pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0;
+ RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+
+ DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n", ret));
+ }
+ else
+ {
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
+ pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition,
+ pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, pAd->BulkOutPending[pAd->bulkResetPipeid]));
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
+ pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pHTTXContext->pUrb->status));
+
+ }
+ }
+ }
+ else
+ {
+ //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
+ //RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pAd->bulkResetPipeid));
+ if (pAd->bulkResetPipeid == 0)
+ {
+ UCHAR pendingContext = 0;
+ PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]);
+ PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
+ PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext);
+ PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext);
+
+ if (pHTTXContext->IRPPending)
+ pendingContext |= 1;
+ else if (pMLMEContext->IRPPending)
+ pendingContext |= 2;
+ else if (pNULLContext->IRPPending)
+ pendingContext |= 4;
+ else if (pPsPollContext->IRPPending)
+ pendingContext |= 8;
+ else
+ pendingContext = 0;
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext));
+ }
+
+ // no matter what, clean the flag
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+
+ RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid));
+ }
+
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ //RTUSBKickBulkOut(pAd);
+ }
+
+ }
+ /*
+ // Don't cancel BULKIN.
+ while ((atomic_read(&pAd->PendingRx) > 0) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ if (atomic_read(&pAd->PendingRx) > 0)
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
+ RTUSBCancelPendingBulkInIRP(pAd);
+ }
+ RTMPusecDelay(100000);
+ }
+
+ if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
+ {
+ UCHAR i;
+ RTUSBRxPacket(pAd);
+ pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
+ pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer
+ for (i = 0; i < (RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+
+ pRxContext->pAd = pAd;
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pRxContext->Readable = FALSE;
+ pRxContext->ReorderInUse = FALSE;
+
+ }
+ RTUSBBulkReceive(pAd);
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
+ }*/
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
+ break;
+
+ case CMDTHREAD_RESET_BULK_IN:
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));
+
+ // All transfers must be aborted or cancelled before attempting to reset the pipe.
+ {
+ UINT32 MACValue;
+/*-----------------------------------------------------------------------------------------------*/
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("ATE : BulkIn IRP Pending!!!\n"));
+ ATE_RTUSBCancelPendingBulkInIRP(pAd);
+ RTMPusecDelay(100000);
+ pAd->PendingRx = 0;
+ }
+ }
+ else
+#endif // RALINK_ATE //
+/*-----------------------------------------------------------------------------------------------*/
+ {
+ //while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n"));
+ RTUSBCancelPendingBulkInIRP(pAd);
+ RTMPusecDelay(100000);
+ pAd->PendingRx = 0;
+ }
+ }
+
+ // Wait 10ms before reading register.
+ RTMPusecDelay(10000);
+ ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue);
+
+ if ((NT_SUCCESS(ntStatus) == TRUE) &&
+ (!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))))
+ {
+ UCHAR i;
+
+ if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ break;
+ pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset;
+ DBGPRINT(RT_DEBUG_TRACE, ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n",
+ pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail));
+ for (i = 0; i < RX_RING_SIZE; i++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n"
+ , i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable));
+ }
+ /*
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));
+
+ pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
+ pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer
+ for (i = 0; i < (RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+
+ pRxContext->pAd = pAd;
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pRxContext->Readable = FALSE;
+ pRxContext->ReorderInUse = FALSE;
+
+ }*/
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
+ for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++)
+ {
+ //RTUSBBulkReceive(pAd);
+ PRX_CONTEXT pRxContext;
+ PURB pUrb;
+ int ret = 0;
+ unsigned long IrqFlags;
+
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
+ if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ break;
+ }
+ pRxContext->InUse = TRUE;
+ pRxContext->IRPPending = TRUE;
+ pAd->PendingRx++;
+ pAd->BulkInReq++;
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+ // Init Rx context descriptor
+ RTUSBInitRxDesc(pAd, pRxContext);
+ pUrb = pRxContext->pUrb;
+ if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ { // fail
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pAd->PendingRx--;
+ pAd->BulkInReq--;
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->status));
+ }
+ else
+ { // success
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->status));
+ ASSERT((pRxContext->InUse == pRxContext->IRPPending));
+ }
+ }
+
+ }
+ else
+ {
+ // Card must be removed
+ if (NT_SUCCESS(ntStatus) != TRUE)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
+ }
+ else
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags));
+ }
+ }
+ }
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
+ break;
+
+ case CMDTHREAD_SET_ASIC_WCID:
+ {
+ RT_SET_ASIC_WCID SetAsicWcid;
+ USHORT offset;
+ UINT32 MACValue, MACRValue = 0;
+ SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData));
+
+ if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
+ return;
+
+ offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid));
+ MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[3]<<24)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[2]<<16)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[1]<<8)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[0]);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue));
+ RTUSBWriteMACRegister(pAd, offset, MACValue);
+ // Read bitmask
+ RTUSBReadMACRegister(pAd, offset+4, &MACRValue);
+ if ( SetAsicWcid.DeleteTid != 0xffffffff)
+ MACRValue &= (~SetAsicWcid.DeleteTid);
+ if (SetAsicWcid.SetTid != 0xffffffff)
+ MACRValue |= (SetAsicWcid.SetTid);
+ MACRValue &= 0xffff0000;
+
+ MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4];
+ MACValue |= MACRValue;
+ RTUSBWriteMACRegister(pAd, offset+4, MACValue);
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
+ }
+ break;
+
+ case CMDTHREAD_SET_ASIC_WCID_CIPHER:
+ {
+#ifdef CONFIG_STA_SUPPORT
+ RT_SET_ASIC_WCID_ATTRI SetAsicWcidAttri;
+ USHORT offset;
+ UINT32 MACRValue = 0;
+ SHAREDKEY_MODE_STRUC csr1;
+ SetAsicWcidAttri = *((PRT_SET_ASIC_WCID_ATTRI)(pData));
+
+ if (SetAsicWcidAttri.WCID >= MAX_LEN_OF_MAC_TABLE)
+ return;
+
+ offset = MAC_WCID_ATTRIBUTE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_WCID_ATTRI_SIZE;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n", SetAsicWcidAttri.WCID, SetAsicWcidAttri.Cipher));
+ // Read bitmask
+ RTUSBReadMACRegister(pAd, offset, &MACRValue);
+ MACRValue = 0;
+ MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
+
+ RTUSBWriteMACRegister(pAd, offset, MACRValue);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
+
+ offset = PAIRWISE_IVEIV_TABLE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_IVEIV_ENTRY_SIZE;
+ MACRValue = 0;
+ if ( (SetAsicWcidAttri.Cipher <= CIPHER_WEP128))
+ MACRValue |= ( pAd->StaCfg.DefaultKeyId << 30);
+ else
+ MACRValue |= (0x20000000);
+ RTUSBWriteMACRegister(pAd, offset, MACRValue);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
+
+ //
+ // Update cipher algorithm. WSTA always use BSS0
+ //
+ // for adhoc mode only ,because wep status slow than add key, when use zero config
+ if (pAd->StaCfg.BssType == BSS_ADHOC )
+ {
+ offset = MAC_WCID_ATTRIBUTE_BASE;
+
+ RTUSBReadMACRegister(pAd, offset, &MACRValue);
+ MACRValue &= (~0xe);
+ MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
+
+ RTUSBWriteMACRegister(pAd, offset, MACRValue);
+
+ //Update group key cipher,,because wep status slow than add key, when use zero config
+ RTUSBReadMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), &csr1.word);
+
+ csr1.field.Bss0Key0CipherAlg = SetAsicWcidAttri.Cipher;
+ csr1.field.Bss0Key1CipherAlg = SetAsicWcidAttri.Cipher;
+
+ RTUSBWriteMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), csr1.word);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ break;
+
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
+ case RT_CMD_SET_KEY_TABLE: //General call for AsicAddPairwiseKeyEntry()
+ {
+ RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
+ KeyInfo = *((PRT_ADD_PAIRWISE_KEY_ENTRY)(pData));
+ AsicAddPairwiseKeyEntry(pAd,
+ KeyInfo.MacAddr,
+ (UCHAR)KeyInfo.MacTabMatchWCID,
+ &KeyInfo.CipherKey);
+ }
+ break;
+ case RT_CMD_SET_RX_WCID_TABLE: //General call for RTMPAddWcidAttributeEntry()
+ {
+ PMAC_TABLE_ENTRY pEntry;
+ UCHAR KeyIdx;
+ UCHAR CipherAlg;
+ UCHAR ApIdx;
+
+ pEntry = (PMAC_TABLE_ENTRY)(pData);
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ KeyIdx = 0;
+ CipherAlg = pEntry->PairwiseKey.CipherAlg;
+ ApIdx = BSS0;
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+
+ RTMPAddWcidAttributeEntry(
+ pAd,
+ ApIdx,
+ KeyIdx,
+ CipherAlg,
+ pEntry);
+ }
+ break;
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
+
+ case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
+ {
+ MAC_TABLE_ENTRY *pEntry;
+ pEntry = (MAC_TABLE_ENTRY *)pData;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)pEntry->Aid);
+ if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && (pEntry->WepStatus == Ndis802_11Encryption1Enabled))
+ {
+ UINT32 uIV = 0;
+ PUCHAR ptr;
+
+ ptr = (PUCHAR) &uIV;
+ *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
+ AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
+ AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
+ }
+ else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ UINT32 uIV = 0;
+ PUCHAR ptr;
+
+ ptr = (PUCHAR) &uIV;
+ *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
+ AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
+ AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
+ }
+ else
+ {
+ //
+ // Other case, disable engine.
+ // Don't worry WPA key, we will add WPA Key after 4-Way handshaking.
+ //
+ USHORT offset;
+ offset = MAC_WCID_ATTRIBUTE_BASE + (pEntry->Aid * HW_WCID_ATTRI_SIZE);
+ // RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0
+ RTUSBWriteMACRegister(pAd, offset, 0);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
+ printk("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid,
+ pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
+ }
+ break;
+
+// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+ case CMDTHREAD_UPDATE_PROTECT:
+ {
+ AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
+ }
+ break;
+// end johnli
+
+ case OID_802_11_ADD_WEP:
+ {
+#ifdef CONFIG_STA_SUPPORT
+ UINT i;
+ UINT32 KeyIdx;
+ PNDIS_802_11_WEP pWepKey;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP \n"));
+
+ pWepKey = (PNDIS_802_11_WEP)pData;
+ KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
+
+ // it is a shared key
+ if ((KeyIdx >= 4) || ((pWepKey->KeyLength != 5) && (pWepKey->KeyLength != 13)))
+ {
+ NdisStatus = NDIS_STATUS_INVALID_DATA;
+ DBGPRINT(RT_DEBUG_ERROR, ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
+ }
+ else
+ {
+ UCHAR CipherAlg;
+ pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
+ NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
+ CipherAlg = (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 5)? CIPHER_WEP64 : CIPHER_WEP128;
+
+ //
+ // Change the WEP cipher to CKIP cipher if CKIP KP on.
+ // Funk UI or Meetinghouse UI will add ckip key from this path.
+ //
+
+ if (pAd->OpMode == OPMODE_STA)
+ {
+ pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
+ pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = pAd->SharedKey[BSS0][KeyIdx].KeyLen;
+ }
+ pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
+ if (pWepKey->KeyIndex & 0x80000000)
+ {
+ // Default key for tx (shared key)
+ UCHAR IVEIV[8];
+ UINT32 WCIDAttri, Value;
+ USHORT offset, offset2;
+ NdisZeroMemory(IVEIV, 8);
+ pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+ // Add BSSID to WCTable. because this is Tx wep key.
+ // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
+ WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
+
+ offset = MAC_WCID_ATTRIBUTE_BASE + (BSSID_WCID* HW_WCID_ATTRI_SIZE);
+ RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
+ // 1. IV/EIV
+ // Specify key index to find shared key.
+ IVEIV[3] = (UCHAR)(KeyIdx<< 6); //WEP Eiv bit off. groupkey index is not 0
+ offset = PAIRWISE_IVEIV_TABLE_BASE + (BSS0Mcast_WCID * HW_IVEIV_ENTRY_SIZE);
+ offset2 = PAIRWISE_IVEIV_TABLE_BASE + (BSSID_WCID* HW_IVEIV_ENTRY_SIZE);
+ for (i=0; i<8;)
+ {
+ Value = IVEIV[i];
+ Value += (IVEIV[i+1]<<8);
+ Value += (IVEIV[i+2]<<16);
+ Value += (IVEIV[i+3]<<24);
+ RTUSBWriteMACRegister(pAd, offset+i, Value);
+ RTUSBWriteMACRegister(pAd, offset2+i, Value);
+ i+=4;
+ }
+
+ // 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0
+ WCIDAttri = (pAd->SharedKey[BSS0][KeyIdx].CipherAlg<<1)|SHAREDKEYTABLE;
+ offset = MAC_WCID_ATTRIBUTE_BASE + (BSS0Mcast_WCID* HW_WCID_ATTRI_SIZE);
+ DBGPRINT(RT_DEBUG_TRACE, ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n", offset, WCIDAttri));
+ RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
+
+ }
+ AsicAddSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx, CipherAlg, pWepKey->KeyMaterial, NULL, NULL);
+ DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", KeyIdx, pWepKey->KeyLength));
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ break;
+
+ case CMDTHREAD_802_11_COUNTER_MEASURE:
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command));
+ break;
+ }
+ }
+
+ if (cmdqelmt->CmdFromNdis == TRUE)
+ {
+ if (cmdqelmt->buffer != NULL)
+ NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
+
+ NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+ }
+ else
+ {
+ if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0))
+ NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
+ {
+ NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+ }
+ }
+ } /* end of while */
+}
+
diff --git a/drivers/staging/rt3070/common/spectrum.c b/drivers/staging/rt3070/common/spectrum.c
new file mode 100644
index 00000000000..da57b1202d6
--- /dev/null
+++ b/drivers/staging/rt3070/common/spectrum.c
@@ -0,0 +1,1876 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ action.c
+
+ Abstract:
+ Handle association related requests either from WSTA or from local MLME
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ Fonchi Wu 2008 created for 802.11h
+ */
+
+#include "../rt_config.h"
+#include "../action.h"
+
+VOID MeasureReqTabInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
+
+ pAd->CommonCfg.pMeasureReqTab = kmalloc(sizeof(MEASURE_REQ_TAB), GFP_ATOMIC);
+ if (pAd->CommonCfg.pMeasureReqTab)
+ NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab, sizeof(MEASURE_REQ_TAB));
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", __FUNCTION__));
+
+ return;
+}
+
+VOID MeasureReqTabExit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NdisFreeSpinLock(pAd->CommonCfg.MeasureReqTabLock);
+
+ if (pAd->CommonCfg.pMeasureReqTab)
+ kfree(pAd->CommonCfg.pMeasureReqTab);
+ pAd->CommonCfg.pMeasureReqTab = NULL;
+
+ return;
+}
+
+static PMEASURE_REQ_ENTRY MeasureReqLookUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ UINT HashIdx;
+ PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
+ PMEASURE_REQ_ENTRY pEntry = NULL;
+ PMEASURE_REQ_ENTRY pPrevEntry = NULL;
+
+ if (pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
+
+ HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
+ pEntry = pTab->Hash[HashIdx];
+
+ while (pEntry)
+ {
+ if (pEntry->DialogToken == DialogToken)
+ break;
+ else
+ {
+ pPrevEntry = pEntry;
+ pEntry = pEntry->pNext;
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
+
+ return pEntry;
+}
+
+static PMEASURE_REQ_ENTRY MeasureReqInsert(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ INT i;
+ ULONG HashIdx;
+ PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
+ PMEASURE_REQ_ENTRY pEntry = NULL, pCurrEntry;
+ ULONG Now;
+
+ if(pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ pEntry = MeasureReqLookUp(pAd, DialogToken);
+ if (pEntry == NULL)
+ {
+ RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
+ for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++)
+ {
+ NdisGetSystemUpTime(&Now);
+ pEntry = &pTab->Content[i];
+
+ if ((pEntry->Valid == TRUE)
+ && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + MQ_REQ_AGE_OUT)))
+ {
+ PMEASURE_REQ_ENTRY pPrevEntry = NULL;
+ ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+ PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+ // update Hash list
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
+ pTab->Size--;
+
+ break;
+ }
+
+ if (pEntry->Valid == FALSE)
+ break;
+ }
+
+ if (i < MAX_MEASURE_REQ_TAB_SIZE)
+ {
+ NdisGetSystemUpTime(&Now);
+ pEntry->lastTime = Now;
+ pEntry->Valid = TRUE;
+ pEntry->DialogToken = DialogToken;
+ pTab->Size++;
+ }
+ else
+ {
+ pEntry = NULL;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab tab full.\n", __FUNCTION__));
+ }
+
+ // add this Neighbor entry into HASH table
+ if (pEntry)
+ {
+ HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
+ if (pTab->Hash[HashIdx] == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry;
+ }
+ else
+ {
+ pCurrEntry = pTab->Hash[HashIdx];
+ while (pCurrEntry->pNext != NULL)
+ pCurrEntry = pCurrEntry->pNext;
+ pCurrEntry->pNext = pEntry;
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
+ }
+
+ return pEntry;
+}
+
+static VOID MeasureReqDelete(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
+ PMEASURE_REQ_ENTRY pEntry = NULL;
+
+ if(pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
+ return;
+ }
+
+ // if empty, return
+ if (pTab->Size == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n"));
+ return;
+ }
+
+ pEntry = MeasureReqLookUp(pAd, DialogToken);
+ if (pEntry != NULL)
+ {
+ PMEASURE_REQ_ENTRY pPrevEntry = NULL;
+ ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+ PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+ RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
+ // update Hash list
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
+ pTab->Size--;
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
+ }
+
+ return;
+}
+
+VOID TpcReqTabInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock);
+
+ pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(TPC_REQ_TAB), GFP_ATOMIC);
+ if (pAd->CommonCfg.pTpcReqTab)
+ NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(TPC_REQ_TAB));
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", __FUNCTION__));
+
+ return;
+}
+
+VOID TpcReqTabExit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NdisFreeSpinLock(pAd->CommonCfg.TpcReqTabLock);
+
+ if (pAd->CommonCfg.pTpcReqTab)
+ kfree(pAd->CommonCfg.pTpcReqTab);
+ pAd->CommonCfg.pTpcReqTab = NULL;
+
+ return;
+}
+
+static PTPC_REQ_ENTRY TpcReqLookUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ UINT HashIdx;
+ PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
+ PTPC_REQ_ENTRY pEntry = NULL;
+ PTPC_REQ_ENTRY pPrevEntry = NULL;
+
+ if (pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
+
+ HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
+ pEntry = pTab->Hash[HashIdx];
+
+ while (pEntry)
+ {
+ if (pEntry->DialogToken == DialogToken)
+ break;
+ else
+ {
+ pPrevEntry = pEntry;
+ pEntry = pEntry->pNext;
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
+
+ return pEntry;
+}
+
+
+static PTPC_REQ_ENTRY TpcReqInsert(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ INT i;
+ ULONG HashIdx;
+ PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
+ PTPC_REQ_ENTRY pEntry = NULL, pCurrEntry;
+ ULONG Now;
+
+ if(pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ pEntry = TpcReqLookUp(pAd, DialogToken);
+ if (pEntry == NULL)
+ {
+ RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
+ for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++)
+ {
+ NdisGetSystemUpTime(&Now);
+ pEntry = &pTab->Content[i];
+
+ if ((pEntry->Valid == TRUE)
+ && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + TPC_REQ_AGE_OUT)))
+ {
+ PTPC_REQ_ENTRY pPrevEntry = NULL;
+ ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+ PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+ // update Hash list
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
+ pTab->Size--;
+
+ break;
+ }
+
+ if (pEntry->Valid == FALSE)
+ break;
+ }
+
+ if (i < MAX_TPC_REQ_TAB_SIZE)
+ {
+ NdisGetSystemUpTime(&Now);
+ pEntry->lastTime = Now;
+ pEntry->Valid = TRUE;
+ pEntry->DialogToken = DialogToken;
+ pTab->Size++;
+ }
+ else
+ {
+ pEntry = NULL;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab tab full.\n", __FUNCTION__));
+ }
+
+ // add this Neighbor entry into HASH table
+ if (pEntry)
+ {
+ HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
+ if (pTab->Hash[HashIdx] == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry;
+ }
+ else
+ {
+ pCurrEntry = pTab->Hash[HashIdx];
+ while (pCurrEntry->pNext != NULL)
+ pCurrEntry = pCurrEntry->pNext;
+ pCurrEntry->pNext = pEntry;
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
+ }
+
+ return pEntry;
+}
+
+static VOID TpcReqDelete(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
+ PTPC_REQ_ENTRY pEntry = NULL;
+
+ if(pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
+ return;
+ }
+
+ // if empty, return
+ if (pTab->Size == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n"));
+ return;
+ }
+
+ pEntry = TpcReqLookUp(pAd, DialogToken);
+ if (pEntry != NULL)
+ {
+ PTPC_REQ_ENTRY pPrevEntry = NULL;
+ ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+ PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+ RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
+ // update Hash list
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
+ pTab->Size--;
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Get Current TimeS tamp.
+
+ Parametrs:
+
+ Return : Current Time Stamp.
+ ==========================================================================
+ */
+static UINT64 GetCurrentTimeStamp(
+ IN PRTMP_ADAPTER pAd)
+{
+ // get current time stamp.
+ return 0;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Get Current Transmit Power.
+
+ Parametrs:
+
+ Return : Current Time Stamp.
+ ==========================================================================
+ */
+static UINT8 GetCurTxPwr(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 Wcid)
+{
+ return 16; /* 16 dBm */
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert Dialog Token into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. Dialog token.
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID InsertDialogToken(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 DialogToken)
+{
+ ULONG TempLen;
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &DialogToken,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert TPC Request IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+
+ Return : None.
+ ==========================================================================
+ */
+ static VOID InsertTpcReqIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen)
+{
+ ULONG TempLen;
+ ULONG Len = 0;
+ UINT8 ElementID = IE_TPC_REQUEST;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert TPC Report IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. Transmit Power.
+ 4. Link Margin.
+
+ Return : None.
+ ==========================================================================
+ */
+ static VOID InsertTpcReportIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 TxPwr,
+ IN UINT8 LinkMargin)
+{
+ ULONG TempLen;
+ ULONG Len = sizeof(TPC_REPORT_INFO);
+ UINT8 ElementID = IE_TPC_REPORT;
+ TPC_REPORT_INFO TpcReportIE;
+
+ TpcReportIE.TxPwr = TxPwr;
+ TpcReportIE.LinkMargin = LinkMargin;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ Len, &TpcReportIE,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert Channel Switch Announcement IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. channel switch announcement mode.
+ 4. new selected channel.
+ 5. channel switch announcement count.
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID InsertChSwAnnIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 ChSwMode,
+ IN UINT8 NewChannel,
+ IN UINT8 ChSwCnt)
+{
+ ULONG TempLen;
+ ULONG Len = sizeof(CH_SW_ANN_INFO);
+ UINT8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
+ CH_SW_ANN_INFO ChSwAnnIE;
+
+ ChSwAnnIE.ChSwMode = ChSwMode;
+ ChSwAnnIE.Channel = NewChannel;
+ ChSwAnnIE.ChSwCnt = ChSwCnt;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ Len, &ChSwAnnIE,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert Measure Request IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. Measure Token.
+ 4. Measure Request Mode.
+ 5. Measure Request Type.
+ 6. Measure Channel.
+ 7. Measure Start time.
+ 8. Measure Duration.
+
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID InsertMeasureReqIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN PMEASURE_REQ_INFO pMeasureReqIE)
+{
+ ULONG TempLen;
+ UINT8 Len = sizeof(MEASURE_REQ_INFO);
+ UINT8 ElementID = IE_MEASUREMENT_REQUEST;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ Len, pMeasureReqIE,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert Measure Report IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. Measure Token.
+ 4. Measure Request Mode.
+ 5. Measure Request Type.
+ 6. Length of Report Infomation
+ 7. Pointer of Report Infomation Buffer.
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID InsertMeasureReportIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN PMEASURE_REPORT_INFO pMeasureReportIE,
+ IN UINT8 ReportLnfoLen,
+ IN PUINT8 pReportInfo)
+{
+ ULONG TempLen;
+ ULONG Len;
+ UINT8 ElementID = IE_MEASUREMENT_REPORT;
+
+ Len = sizeof(MEASURE_REPORT_INFO) + ReportLnfoLen;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ Len, pMeasureReportIE,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ if ((ReportLnfoLen > 0) && (pReportInfo != NULL))
+ {
+ MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen,
+ ReportLnfoLen, pReportInfo,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+ }
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Measurement request action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueMeasurementReq(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 MeasureToken,
+ IN UINT8 MeasureReqMode,
+ IN UINT8 MeasureReqType,
+ IN UINT8 MeasureCh,
+ IN UINT16 MeasureDuration)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+ HEADER_802_11 ActHdr;
+ MEASURE_REQ_INFO MeasureReqIE;
+ UINT8 RmReqDailogToken = RandomByte(pAd);
+ UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);
+
+ // build action frame header.
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRQ);
+
+ // fill Dialog Token
+ InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, MeasureToken);
+
+ // prepare Measurement IE.
+ NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO));
+ MeasureReqIE.Token = RmReqDailogToken;
+ MeasureReqIE.ReqMode.word = MeasureReqMode;
+ MeasureReqIE.ReqType = MeasureReqType;
+ MeasureReqIE.MeasureReq.ChNum = MeasureCh;
+ MeasureReqIE.MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
+ MeasureReqIE.MeasureReq.MeasureDuration = cpu2le16(MeasureDuration);
+ InsertMeasureReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureReqIE);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Measurement report action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueMeasurementRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 DialogToken,
+ IN UINT8 MeasureToken,
+ IN UINT8 MeasureReqMode,
+ IN UINT8 MeasureReqType,
+ IN UINT8 ReportInfoLen,
+ IN PUINT8 pReportInfo)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+ HEADER_802_11 ActHdr;
+ MEASURE_REPORT_INFO MeasureRepIE;
+
+ // build action frame header.
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRP);
+
+ // fill Dialog Token
+ InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
+
+ // prepare Measurement IE.
+ NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO));
+ MeasureRepIE.Token = MeasureToken;
+ MeasureRepIE.ReportMode.word = MeasureReqMode;
+ MeasureRepIE.ReportType = MeasureReqType;
+ InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare TPC Request action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueTPCReq(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UCHAR DialogToken)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+
+ HEADER_802_11 ActHdr;
+
+ // build action frame header.
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRQ);
+
+ // fill Dialog Token
+ InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
+
+ // Insert TPC Request IE.
+ InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare TPC Report action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueTPCRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 DialogToken,
+ IN UINT8 TxPwr,
+ IN UINT8 LinkMargin)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+
+ HEADER_802_11 ActHdr;
+
+ // build action frame header.
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRP);
+
+ // fill Dialog Token
+ InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
+
+ // Insert TPC Request IE.
+ InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr, LinkMargin);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Channel Switch Announcement action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+ 2. Channel switch announcement mode.
+ 2. a New selected channel.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueChSwAnn(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 ChSwMode,
+ IN UINT8 NewCh)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+
+ HEADER_802_11 ActHdr;
+
+ // build action frame header.
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
+
+ InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode, NewCh, 0);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+static BOOLEAN DfsRequirementCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 Channel)
+{
+ BOOLEAN Result = FALSE;
+ INT i;
+
+ do
+ {
+ // check DFS procedure is running.
+ // make sure DFS procedure won't start twice.
+ if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+ {
+ Result = FALSE;
+ break;
+ }
+
+ // check the new channel carried from Channel Switch Announcemnet is valid.
+ for (i=0; i<pAd->ChannelListNum; i++)
+ {
+ if ((Channel == pAd->ChannelList[i].Channel)
+ &&(pAd->ChannelList[i].RemainingTimeForUse == 0))
+ {
+ // found radar signal in the channel. the channel can't use at least for 30 minutes.
+ pAd->ChannelList[i].RemainingTimeForUse = 1800;//30 min = 1800 sec
+ Result = TRUE;
+ break;
+ }
+ }
+ } while(FALSE);
+
+ return Result;
+}
+
+VOID NotifyChSwAnnToPeerAPs(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pRA,
+ IN PUCHAR pTA,
+ IN UINT8 ChSwMode,
+ IN UINT8 Channel)
+{
+#ifdef WDS_SUPPORT
+ if (!((pRA[0] & 0xff) == 0xff)) // is pRA a broadcase address.
+ {
+ INT i;
+ // info neighbor APs that Radar signal found throgh WDS link.
+ for (i = 0; i < MAX_WDS_ENTRY; i++)
+ {
+ if (ValidWdsEntry(pAd, i))
+ {
+ PUCHAR pDA = pAd->WdsTab.WdsEntry[i].PeerWdsAddr;
+
+ // DA equal to SA. have no necessary orignal AP which found Radar signal.
+ if (MAC_ADDR_EQUAL(pTA, pDA))
+ continue;
+
+ // send Channel Switch Action frame to info Neighbro APs.
+ EnqueueChSwAnn(pAd, pDA, ChSwMode, Channel);
+ }
+ }
+ }
+#endif // WDS_SUPPORT //
+}
+
+static VOID StartDFSProcedure(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel,
+ IN UINT8 ChSwMode)
+{
+ // start DFS procedure
+ pAd->CommonCfg.Channel = Channel;
+#ifdef DOT11_N_SUPPORT
+ N_ChannelCheck(pAd);
+#endif // DOT11_N_SUPPORT //
+ pAd->CommonCfg.RadarDetect.RDMode = RD_SWITCHING_MODE;
+ pAd->CommonCfg.RadarDetect.CSCount = 0;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Channel Switch Announcement action frame sanity check.
+
+ Parametrs:
+ 1. MLME message containing the received frame
+ 2. message length.
+ 3. Channel switch announcement infomation buffer.
+
+
+ Return : None.
+ ==========================================================================
+ */
+
+/*
+ Channel Switch Announcement IE.
+ +----+-----+-----------+------------+-----------+
+ | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt |
+ +----+-----+-----------+------------+-----------+
+ 1 1 1 1 1
+*/
+static BOOLEAN PeerChSwAnnSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PCH_SW_ANN_INFO pChSwAnnInfo)
+{
+ PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+ PUCHAR pFramePtr = Fr->Octet;
+ BOOLEAN result = FALSE;
+ PEID_STRUCT eid_ptr;
+
+ // skip 802.11 header.
+ MsgLen -= sizeof(HEADER_802_11);
+
+ // skip category and action code.
+ pFramePtr += 2;
+ MsgLen -= 2;
+
+ if (pChSwAnnInfo == NULL)
+ return result;
+
+ eid_ptr = (PEID_STRUCT)pFramePtr;
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
+ NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet, 1);
+ NdisMoveMemory(&pChSwAnnInfo->Channel, eid_ptr->Octet + 1, 1);
+ NdisMoveMemory(&pChSwAnnInfo->ChSwCnt, eid_ptr->Octet + 2, 1);
+
+ result = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return result;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Measurement request action frame sanity check.
+
+ Parametrs:
+ 1. MLME message containing the received frame
+ 2. message length.
+ 3. Measurement request infomation buffer.
+
+ Return : None.
+ ==========================================================================
+ */
+static BOOLEAN PeerMeasureReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUINT8 pDialogToken,
+ OUT PMEASURE_REQ_INFO pMeasureReqInfo)
+{
+ PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+ PUCHAR pFramePtr = Fr->Octet;
+ BOOLEAN result = FALSE;
+ PEID_STRUCT eid_ptr;
+ PUCHAR ptr;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+
+ // skip 802.11 header.
+ MsgLen -= sizeof(HEADER_802_11);
+
+ // skip category and action code.
+ pFramePtr += 2;
+ MsgLen -= 2;
+
+ if (pMeasureReqInfo == NULL)
+ return result;
+
+ NdisMoveMemory(pDialogToken, pFramePtr, 1);
+ pFramePtr += 1;
+ MsgLen -= 1;
+
+ eid_ptr = (PEID_STRUCT)pFramePtr;
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_MEASUREMENT_REQUEST:
+ NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1);
+ NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1);
+ NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1);
+ ptr = eid_ptr->Octet + 3;
+ NdisMoveMemory(&pMeasureReqInfo->MeasureReq.ChNum, ptr, 1);
+ NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
+ pMeasureReqInfo->MeasureReq.MeasureStartTime = SWAP64(MeasureStartTime);
+ NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
+ pMeasureReqInfo->MeasureReq.MeasureDuration = SWAP16(MeasureDuration);
+
+ result = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return result;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Measurement report action frame sanity check.
+
+ Parametrs:
+ 1. MLME message containing the received frame
+ 2. message length.
+ 3. Measurement report infomation buffer.
+ 4. basic report infomation buffer.
+
+ Return : None.
+ ==========================================================================
+ */
+
+/*
+ Measurement Report IE.
+ +----+-----+-------+-------------+--------------+----------------+
+ | ID | Len | Token | Report Mode | Measure Type | Measure Report |
+ +----+-----+-------+-------------+--------------+----------------+
+ 1 1 1 1 1 variable
+
+ Basic Report.
+ +--------+------------+----------+-----+
+ | Ch Num | Start Time | Duration | Map |
+ +--------+------------+----------+-----+
+ 1 8 2 1
+
+ Map Field Bit Format.
+ +-----+---------------+---------------------+-------+------------+----------+
+ | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved |
+ +-----+---------------+---------------------+-------+------------+----------+
+ 0 1 2 3 4 5-7
+*/
+static BOOLEAN PeerMeasureReportSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUINT8 pDialogToken,
+ OUT PMEASURE_REPORT_INFO pMeasureReportInfo,
+ OUT PUINT8 pReportBuf)
+{
+ PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+ PUCHAR pFramePtr = Fr->Octet;
+ BOOLEAN result = FALSE;
+ PEID_STRUCT eid_ptr;
+ PUCHAR ptr;
+
+ // skip 802.11 header.
+ MsgLen -= sizeof(HEADER_802_11);
+
+ // skip category and action code.
+ pFramePtr += 2;
+ MsgLen -= 2;
+
+ if (pMeasureReportInfo == NULL)
+ return result;
+
+ NdisMoveMemory(pDialogToken, pFramePtr, 1);
+ pFramePtr += 1;
+ MsgLen -= 1;
+
+ eid_ptr = (PEID_STRUCT)pFramePtr;
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_MEASUREMENT_REPORT:
+ NdisMoveMemory(&pMeasureReportInfo->Token, eid_ptr->Octet, 1);
+ NdisMoveMemory(&pMeasureReportInfo->ReportMode, eid_ptr->Octet + 1, 1);
+ NdisMoveMemory(&pMeasureReportInfo->ReportType, eid_ptr->Octet + 2, 1);
+ if (pMeasureReportInfo->ReportType == RM_BASIC)
+ {
+ PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf;
+ ptr = eid_ptr->Octet + 3;
+ NdisMoveMemory(&pReport->ChNum, ptr, 1);
+ NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
+ NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
+ NdisMoveMemory(&pReport->Map, ptr + 11, 1);
+
+ }
+ else if (pMeasureReportInfo->ReportType == RM_CCA)
+ {
+ PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf;
+ ptr = eid_ptr->Octet + 3;
+ NdisMoveMemory(&pReport->ChNum, ptr, 1);
+ NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
+ NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
+ NdisMoveMemory(&pReport->CCA_Busy_Fraction, ptr + 11, 1);
+
+ }
+ else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM)
+ {
+ PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf;
+ ptr = eid_ptr->Octet + 3;
+ NdisMoveMemory(&pReport->ChNum, ptr, 1);
+ NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
+ NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
+ NdisMoveMemory(&pReport->RPI_Density, ptr + 11, 8);
+ }
+ result = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return result;
+}
+
+/*
+ ==========================================================================
+ Description:
+ TPC Request action frame sanity check.
+
+ Parametrs:
+ 1. MLME message containing the received frame
+ 2. message length.
+ 3. Dialog Token.
+
+ Return : None.
+ ==========================================================================
+ */
+static BOOLEAN PeerTpcReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUINT8 pDialogToken)
+{
+ PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+ PUCHAR pFramePtr = Fr->Octet;
+ BOOLEAN result = FALSE;
+ PEID_STRUCT eid_ptr;
+
+ MsgLen -= sizeof(HEADER_802_11);
+
+ // skip category and action code.
+ pFramePtr += 2;
+ MsgLen -= 2;
+
+ if (pDialogToken == NULL)
+ return result;
+
+ NdisMoveMemory(pDialogToken, pFramePtr, 1);
+ pFramePtr += 1;
+ MsgLen -= 1;
+
+ eid_ptr = (PEID_STRUCT)pFramePtr;
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_TPC_REQUEST:
+ result = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return result;
+}
+
+/*
+ ==========================================================================
+ Description:
+ TPC Report action frame sanity check.
+
+ Parametrs:
+ 1. MLME message containing the received frame
+ 2. message length.
+ 3. Dialog Token.
+ 4. TPC Report IE.
+
+ Return : None.
+ ==========================================================================
+ */
+static BOOLEAN PeerTpcRepSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUINT8 pDialogToken,
+ OUT PTPC_REPORT_INFO pTpcRepInfo)
+{
+ PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+ PUCHAR pFramePtr = Fr->Octet;
+ BOOLEAN result = FALSE;
+ PEID_STRUCT eid_ptr;
+
+ MsgLen -= sizeof(HEADER_802_11);
+
+ // skip category and action code.
+ pFramePtr += 2;
+ MsgLen -= 2;
+
+ if (pDialogToken == NULL)
+ return result;
+
+ NdisMoveMemory(pDialogToken, pFramePtr, 1);
+ pFramePtr += 1;
+ MsgLen -= 1;
+
+ eid_ptr = (PEID_STRUCT)pFramePtr;
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_TPC_REPORT:
+ NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1);
+ NdisMoveMemory(&pTpcRepInfo->LinkMargin, eid_ptr->Octet + 1, 1);
+ result = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return result;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Channel Switch Announcement action frame handler.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID PeerChSwAnnAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ CH_SW_ANN_INFO ChSwAnnInfo;
+ PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
+#ifdef CONFIG_STA_SUPPORT
+ UCHAR index = 0, Channel = 0, NewChannel = 0;
+ ULONG Bssidx = 0;
+#endif // CONFIG_STA_SUPPORT //
+
+ NdisZeroMemory(&ChSwAnnInfo, sizeof(CH_SW_ANN_INFO));
+ if (! PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Invalid Channel Switch Action Frame.\n"));
+ return;
+ }
+
+
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->OpMode == OPMODE_STA)
+ {
+ Bssidx = BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3, pAd->CommonCfg.Channel);
+ if (Bssidx == BSS_NOT_FOUND)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerChSwAnnAction - Bssidx is not found\n"));
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\n****Bssidx is %d, Channel = %d\n", index, pAd->ScanTab.BssEntry[Bssidx].Channel));
+ hex_dump("SSID",pAd->ScanTab.BssEntry[Bssidx].Bssid ,6);
+
+ Channel = pAd->CommonCfg.Channel;
+ NewChannel = ChSwAnnInfo.Channel;
+
+ if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
+ {
+ // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
+ // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
+ AsicSwitchChannel(pAd, 1, FALSE);
+ AsicLockChannel(pAd, 1);
+ LinkDown(pAd, FALSE);
+ MlmeQueueInit(&pAd->Mlme.Queue);
+ BssTableInit(&pAd->ScanTab);
+ RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
+
+ // channel sanity check
+ for (index = 0 ; index < pAd->ChannelListNum; index++)
+ {
+ if (pAd->ChannelList[index].Channel == NewChannel)
+ {
+ pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
+ pAd->CommonCfg.Channel = NewChannel;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ DBGPRINT(RT_DEBUG_TRACE, ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
+ break;
+ }
+ }
+
+ if (index >= pAd->ChannelListNum)
+ {
+ DBGPRINT_ERR(("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ return;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Measurement Request action frame handler.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID PeerMeasureReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
+ UINT8 DialogToken;
+ MEASURE_REQ_INFO MeasureReqInfo;
+ MEASURE_REPORT_MODE ReportMode;
+
+ if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo))
+ {
+ ReportMode.word = 0;
+ ReportMode.field.Incapable = 1;
+ EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken, MeasureReqInfo.Token, ReportMode.word, MeasureReqInfo.ReqType, 0, NULL);
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Measurement Report action frame handler.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID PeerMeasureReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MEASURE_REPORT_INFO MeasureReportInfo;
+ PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
+ UINT8 DialogToken;
+ PUINT8 pMeasureReportInfo;
+
+// if (pAd->CommonCfg.bIEEE80211H != TRUE)
+// return;
+
+ if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __FUNCTION__, sizeof(MEASURE_RPI_REPORT)));
+ return;
+ }
+
+ NdisZeroMemory(&MeasureReportInfo, sizeof(MEASURE_REPORT_INFO));
+ NdisZeroMemory(pMeasureReportInfo, sizeof(MEASURE_RPI_REPORT));
+ if (PeerMeasureReportSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo, pMeasureReportInfo))
+ {
+ do {
+ PMEASURE_REQ_ENTRY pEntry = NULL;
+
+ // Not a autonomous measure report.
+ // check the dialog token field. drop it if the dialog token doesn't match.
+ if ((DialogToken != 0)
+ && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL))
+ break;
+
+ if (pEntry != NULL)
+ MeasureReqDelete(pAd, pEntry->DialogToken);
+
+ if (MeasureReportInfo.ReportType == RM_BASIC)
+ {
+ PMEASURE_BASIC_REPORT pBasicReport = (PMEASURE_BASIC_REPORT)pMeasureReportInfo;
+ if ((pBasicReport->Map.field.Radar)
+ && (DfsRequirementCheck(pAd, pBasicReport->ChNum) == TRUE))
+ {
+ NotifyChSwAnnToPeerAPs(pAd, pFr->Hdr.Addr1, pFr->Hdr.Addr2, 1, pBasicReport->ChNum);
+ StartDFSProcedure(pAd, pBasicReport->ChNum, 1);
+ }
+ }
+ } while (FALSE);
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("Invalid Measurement Report Frame.\n"));
+
+ kfree(pMeasureReportInfo);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ TPC Request action frame handler.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID PeerTpcReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
+ PUCHAR pFramePtr = pFr->Octet;
+ UINT8 DialogToken;
+ UINT8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid);
+ UINT8 LinkMargin = 0;
+ CHAR RealRssi;
+
+ // link margin: Ratio of the received signal power to the minimum desired by the station (STA). The
+ // STA may incorporate rate information and channel conditions, including interference, into its computation
+ // of link margin.
+
+ RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
+ ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
+ ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+
+ // skip Category and action code.
+ pFramePtr += 2;
+
+ // Dialog token.
+ NdisMoveMemory(&DialogToken, pFramePtr, 1);
+
+ LinkMargin = (RealRssi / MIN_RCV_PWR);
+ if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken))
+ EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr, LinkMargin);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ TPC Report action frame handler.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID PeerTpcRepAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UINT8 DialogToken;
+ TPC_REPORT_INFO TpcRepInfo;
+ PTPC_REQ_ENTRY pEntry = NULL;
+
+ NdisZeroMemory(&TpcRepInfo, sizeof(TPC_REPORT_INFO));
+ if (PeerTpcRepSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo))
+ {
+ if ((pEntry = TpcReqLookUp(pAd, DialogToken)) != NULL)
+ {
+ TpcReqDelete(pAd, pEntry->DialogToken);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
+ __FUNCTION__, DialogToken, TpcRepInfo.TxPwr, TpcRepInfo.LinkMargin));
+ }
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Spectrun action frames Handler such as channel switch annoucement,
+ measurement report, measurement request actions frames.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+VOID PeerSpectrumAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+
+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
+
+ if (pAd->CommonCfg.bIEEE80211H != TRUE)
+ return;
+
+ switch(Action)
+ {
+ case SPEC_MRQ:
+ // current rt2860 unable do such measure specified in Measurement Request.
+ // reject all measurement request.
+ PeerMeasureReqAction(pAd, Elem);
+ break;
+
+ case SPEC_MRP:
+ PeerMeasureReportAction(pAd, Elem);
+ break;
+
+ case SPEC_TPCRQ:
+ PeerTpcReqAction(pAd, Elem);
+ break;
+
+ case SPEC_TPCRP:
+ PeerTpcRepAction(pAd, Elem);
+ break;
+
+ case SPEC_CHANNEL_SWITCH:
+{
+#ifdef DOT11N_DRAFT3
+ SEC_CHA_OFFSET_IE Secondary;
+ CHA_SWITCH_ANNOUNCE_IE ChannelSwitch;
+
+ // 802.11h only has Channel Switch Announcement IE.
+ RTMPMoveMemory(&ChannelSwitch, &Elem->Msg[LENGTH_802_11+4], sizeof (CHA_SWITCH_ANNOUNCE_IE));
+
+ // 802.11n D3.03 adds secondary channel offset element in the end.
+ if (Elem->MsgLen == (LENGTH_802_11 + 2 + sizeof (CHA_SWITCH_ANNOUNCE_IE) + sizeof (SEC_CHA_OFFSET_IE)))
+ {
+ RTMPMoveMemory(&Secondary, &Elem->Msg[LENGTH_802_11+9], sizeof (SEC_CHA_OFFSET_IE));
+ }
+ else
+ {
+ Secondary.SecondaryChannelOffset = 0;
+ }
+
+ if ((Elem->Msg[LENGTH_802_11+2] == IE_CHANNEL_SWITCH_ANNOUNCEMENT) && (Elem->Msg[LENGTH_802_11+3] == 3))
+ {
+ ChannelSwitchAction(pAd, Elem->Wcid, ChannelSwitch.NewChannel, Secondary.SecondaryChannelOffset);
+ }
+#endif // DOT11N_DRAFT3 //
+}
+ PeerChSwAnnAction(pAd, Elem);
+ break;
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ Parametrs:
+
+ Return : None.
+ ==========================================================================
+ */
+INT Set_MeasureReq_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UINT Aid = 1;
+ UINT ArgIdx;
+ PUCHAR thisChar;
+
+ MEASURE_REQ_MODE MeasureReqMode;
+ UINT8 MeasureReqToken = RandomByte(pAd);
+ UINT8 MeasureReqType = RM_BASIC;
+ UINT8 MeasureCh = 1;
+
+ ArgIdx = 1;
+ while ((thisChar = strsep((char **)&arg, "-")) != NULL)
+ {
+ switch(ArgIdx)
+ {
+ case 1: // Aid.
+ Aid = simple_strtol(thisChar, 0, 16);
+ break;
+
+ case 2: // Measurement Request Type.
+ MeasureReqType = simple_strtol(thisChar, 0, 16);
+ if (MeasureReqType > 3)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __FUNCTION__, MeasureReqType));
+ return TRUE;
+ }
+ break;
+
+ case 3: // Measurement channel.
+ MeasureCh = simple_strtol(thisChar, 0, 16);
+ break;
+ }
+ ArgIdx++;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __FUNCTION__, Aid, MeasureReqType, MeasureCh));
+ if (!VALID_WCID(Aid))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
+ return TRUE;
+ }
+
+ MeasureReqMode.word = 0;
+ MeasureReqMode.field.Enable = 1;
+
+ MeasureReqInsert(pAd, MeasureReqToken);
+
+ EnqueueMeasurementReq(pAd, pAd->MacTab.Content[Aid].Addr,
+ MeasureReqToken, MeasureReqMode.word, MeasureReqType, MeasureCh, 2000);
+
+ return TRUE;
+}
+
+INT Set_TpcReq_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UINT Aid;
+
+ UINT8 TpcReqToken = RandomByte(pAd);
+
+ Aid = simple_strtol(arg, 0, 16);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __FUNCTION__, Aid));
+ if (!VALID_WCID(Aid))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
+ return TRUE;
+ }
+
+ TpcReqInsert(pAd, TpcReqToken);
+
+ EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken);
+
+ return TRUE;
+}
+
diff --git a/drivers/staging/rt3070/dfs.h b/drivers/staging/rt3070/dfs.h
new file mode 100644
index 00000000000..752a6352d9d
--- /dev/null
+++ b/drivers/staging/rt3070/dfs.h
@@ -0,0 +1,100 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ dfs.h
+
+ Abstract:
+ Support DFS function.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Fonchi 03-12-2007 created
+*/
+
+#define RADAR_PULSE 1
+#define RADAR_WIDTH 2
+
+#define WIDTH_RD_IDLE 0
+#define WIDTH_RD_CHECK 1
+
+
+VOID BbpRadarDetectionStart(
+ IN PRTMP_ADAPTER pAd);
+
+VOID BbpRadarDetectionStop(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RadarDetectionStart(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN CTS_Protect,
+ IN UINT8 CTSPeriod);
+
+VOID RadarDetectionStop(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RadarDetectPeriodic(
+ IN PRTMP_ADAPTER pAd);
+
+
+BOOLEAN RadarChannelCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Ch);
+
+ULONG JapRadarType(
+ IN PRTMP_ADAPTER pAd);
+
+ULONG RTMPBbpReadRadarDuration(
+ IN PRTMP_ADAPTER pAd);
+
+ULONG RTMPReadRadarDuration(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPCleanRadarDuration(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPPrepareRDCTSFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN ULONG Duration,
+ IN UCHAR RTSRate,
+ IN ULONG CTSBaseAddr,
+ IN UCHAR FrameGap);
+
+VOID RTMPPrepareRadarDetectParams(
+ IN PRTMP_ADAPTER pAd);
+
+
+INT Set_ChMovingTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_LongPulseRadarTh_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+
diff --git a/drivers/staging/rt3070/firmware.h b/drivers/staging/rt3070/firmware.h
new file mode 100644
index 00000000000..b07783ed8dd
--- /dev/null
+++ b/drivers/staging/rt3070/firmware.h
@@ -0,0 +1,558 @@
+/*
+ Copyright (c) 2007, Ralink Technology Corporation
+ All rights reserved.
+
+ Redistribution. Redistribution and use in binary form, without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions must reproduce the above copyright notice and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+ * Neither the name of Ralink Technology Corporation nor the names of its
+ suppliers may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+ * No reverse engineering, decompilation, or disassembly of this software
+ is permitted.
+
+ Limited patent license. Ralink Technology Corporation grants a world-wide,
+ royalty-free, non-exclusive license under patents it now or hereafter
+ owns or controls to make, have made, use, import, offer to sell and
+ sell ("Utilize") this software, but solely to the extent that any
+ such patent is necessary to Utilize the software alone, or in
+ combination with an operating system licensed under an approved Open
+ Source license as listed by the Open Source Initiative at
+ http://opensource.org/licenses. The patent license shall not apply to
+ any other combinations which include this software. No hardware per
+ se is licensed hereunder.
+
+ DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+*/
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+
+
+UCHAR FirmwareImage [] = {
+0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02,
+0x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02,
+0x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
+0xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
+0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
+0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
+0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
+0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
+0x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10,
+0xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d,
+0x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73,
+0x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf,
+0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
+0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22,
+0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11,
+0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03,
+0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04,
+0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57,
+0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef,
+0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
+0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47,
+0x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90,
+0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03,
+0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2, 0x04, 0x22, 0x90, 0x70,
+0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56,
+0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
+0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70,
+0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b,
+0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
+0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0,
+0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54,
+0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5,
+0x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80,
+0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10,
+0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74,
+0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70,
+0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90,
+0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90,
+0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2,
+0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f,
+0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2,
+0x4c, 0xe5, 0x44, 0x12, 0x0a, 0x9d, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13,
+0x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85,
+0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13,
+0x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5,
+0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43,
+0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06,
+0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f,
+0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5,
+0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e,
+0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5,
+0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b,
+0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54,
+0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0,
+0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0,
+0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12,
+0x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04,
+0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff,
+0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5,
+0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5,
+0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05,
+0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30,
+0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03,
+0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30,
+0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2,
+0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64,
+0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5,
+0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5,
+0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c,
+0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26,
+0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01,
+0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
+0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80,
+0x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f,
+0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80,
+0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c,
+0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04,
+0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01,
+0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0,
+0x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92,
+0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2,
+0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29,
+0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23,
+0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07,
+0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0,
+0x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02,
+0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5,
+0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5,
+0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e,
+0x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5,
+0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
+0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46,
+0x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38,
+0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20,
+0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2,
+0x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
+0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90,
+0x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5,
+0x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47,
+0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f,
+0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51,
+0x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75,
+0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04,
+0x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f,
+0x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73,
+0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70,
+0x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02,
+0x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90,
+0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96,
+0xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0,
+0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75,
+0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62,
+0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62,
+0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2,
+0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d,
+0x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52,
+0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44,
+0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74,
+0x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0,
+0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17,
+0x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60,
+0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff,
+0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e,
+0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22,
+0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10,
+0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10,
+0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90,
+0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90,
+0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01,
+0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 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, 0x0c, 0x94, 0x3f,
+0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02,
+0x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02,
+0x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
+0xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
+0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
+0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
+0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
+0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
+0x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10,
+0xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d,
+0x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73,
+0x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf,
+0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
+0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22,
+0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11,
+0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03,
+0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04,
+0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57,
+0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef,
+0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
+0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47,
+0x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90,
+0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03,
+0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2, 0x04, 0x22, 0x90, 0x70,
+0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56,
+0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
+0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70,
+0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b,
+0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
+0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0,
+0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54,
+0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5,
+0x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80,
+0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10,
+0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74,
+0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70,
+0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90,
+0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90,
+0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2,
+0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f,
+0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2,
+0x4c, 0xe5, 0x44, 0x12, 0x0a, 0xb6, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13,
+0x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85,
+0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13,
+0x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5,
+0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43,
+0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06,
+0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f,
+0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5,
+0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e,
+0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5,
+0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b,
+0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54,
+0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0,
+0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0,
+0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12,
+0x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04,
+0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff,
+0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5,
+0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5,
+0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05,
+0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30,
+0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03,
+0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30,
+0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2,
+0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64,
+0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5,
+0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5,
+0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c,
+0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26,
+0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01,
+0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
+0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80,
+0x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f,
+0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80,
+0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c,
+0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04,
+0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01,
+0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0,
+0x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92,
+0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2,
+0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29,
+0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23,
+0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07,
+0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0,
+0x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02,
+0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5,
+0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5,
+0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e,
+0x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5,
+0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
+0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46,
+0x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38,
+0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20,
+0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2,
+0x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
+0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90,
+0x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5,
+0x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47,
+0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f,
+0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51,
+0x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75,
+0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04,
+0x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f,
+0x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73,
+0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70,
+0x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02,
+0x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90,
+0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96,
+0xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0,
+0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75,
+0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62,
+0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62,
+0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2,
+0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d,
+0x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52,
+0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44,
+0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74,
+0x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0,
+0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17,
+0x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60,
+0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff,
+0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e,
+0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22,
+0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10,
+0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10,
+0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90,
+0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90,
+0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01,
+0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 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, 0x02, 0x9b, 0xc0, } ;
diff --git a/drivers/staging/rt3070/leap.h b/drivers/staging/rt3070/leap.h
new file mode 100644
index 00000000000..6818c1ff4d7
--- /dev/null
+++ b/drivers/staging/rt3070/leap.h
@@ -0,0 +1,215 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ leap.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+#ifndef __LEAP_H__
+#define __LEAP_H__
+
+// Messages for Associate state machine
+#define LEAP_MACHINE_BASE 30
+
+#define LEAP_MSG_REQUEST_IDENTITY 31
+#define LEAP_MSG_REQUEST_LEAP 32
+#define LEAP_MSG_SUCCESS 33
+#define LEAP_MSG_FAILED 34
+#define LEAP_MSG_RESPONSE_LEAP 35
+#define LEAP_MSG_EAPOLKEY 36
+#define LEAP_MSG_UNKNOWN 37
+#define LEAP_MSG 38
+//! assoc state-machine states
+#define LEAP_IDLE 0
+#define LEAP_WAIT_IDENTITY_REQUEST 1
+#define LEAP_WAIT_CHANLLENGE_REQUEST 2
+#define LEAP_WAIT_SUCCESS 3
+#define LEAP_WAIT_CHANLLENGE_RESPONSE 4
+#define LEAP_WAIT_EAPOLKEY 5
+
+#define LEAP_REASON_INVALID_AUTH 0x01
+#define LEAP_REASON_AUTH_TIMEOUT 0x02
+#define LEAP_REASON_CHALLENGE_FROM_AP_FAILED 0x03
+#define LEAP_REASON_CHALLENGE_TO_AP_FAILED 0x04
+
+#define CISCO_AuthModeLEAP 0x80
+#define CISCO_AuthModeLEAPNone 0x00
+#define LEAP_AUTH_TIMEOUT 30000
+#define LEAP_CHALLENGE_RESPONSE_LENGTH 24
+#define LEAP_CHALLENGE_REQUEST_LENGTH 8
+
+typedef struct _LEAP_EAPOL_HEADER_ {
+ UCHAR Version;
+ UCHAR Type;
+ UCHAR Length[2];
+} LEAP_EAPOL_HEADER, *PLEAP_EAPOL_HEADER;
+
+typedef struct _LEAP_EAPOL_PACKET_ {
+ UCHAR Code;
+ UCHAR Identifier;
+ UCHAR Length[2];
+ UCHAR Type;
+} LEAP_EAPOL_PACKET, *PLEAP_EAPOL_PACKET;
+
+typedef struct _LEAP_EAP_CONTENTS_ {
+ UCHAR Version;
+ UCHAR Reserved;
+ UCHAR Length;
+} LEAP_EAP_CONTENTS, *PLEAP_EAP_CONTENTS;
+
+/*** EAPOL key ***/
+typedef struct _EAPOL_KEY_HEADER_ {
+ UCHAR Type;
+ UCHAR Length[2];
+ UCHAR Counter[8];
+ UCHAR IV[16];
+ UCHAR Index;
+ UCHAR Signature[16];
+} EAPOL_KEY_HEADER, *PEAPOL_KEY_HEADER;
+
+BOOLEAN LeapMsgTypeSubst(
+ IN UCHAR EAPType,
+ OUT ULONG *MsgType);
+
+VOID LeapMachinePerformAction(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID LeapMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR wep,
+ IN PUCHAR pAddr3);
+
+VOID LeapStartAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID LeapIdentityAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID LeapPeerChallengeAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID HashPwd(
+ IN PUCHAR pwd,
+ IN INT pwdlen,
+ OUT PUCHAR hash);
+
+VOID PeerChallengeResponse(
+ IN PUCHAR szChallenge,
+ IN PUCHAR smbPasswd,
+ OUT PUCHAR szResponse);
+
+VOID ParityKey(
+ OUT PUCHAR szOut,
+ IN PUCHAR szIn);
+
+VOID DesKey(
+ OUT ULONG k[16][2],
+ IN PUCHAR key,
+ IN INT decrypt);
+
+VOID Des(
+ IN ULONG ks[16][2],
+ OUT UCHAR block[8]);
+
+VOID DesEncrypt(
+ IN PUCHAR szClear,
+ IN PUCHAR szKey,
+ OUT PUCHAR szOut);
+
+VOID LeapNetworkChallengeAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID LeapNetworkChallengeResponse(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID HashpwdHash(
+ IN PUCHAR hash,
+ IN PUCHAR hashhash);
+
+VOID ProcessSessionKey(
+ OUT PUCHAR SessionKey,
+ IN PUCHAR hash2,
+ IN PUCHAR ChallengeToRadius,
+ IN PUCHAR ChallengeResponseFromRadius,
+ IN PUCHAR ChallengeFromRadius,
+ IN PUCHAR ChallengeResponseToRadius);
+
+VOID LeapEapolKeyAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID RogueApTableInit(
+ IN ROGUEAP_TABLE *Tab);
+
+ULONG RogueApTableSearch(
+ IN ROGUEAP_TABLE *Tab,
+ IN PUCHAR pAddr);
+
+VOID RogueApEntrySet(
+ IN PRTMP_ADAPTER pAd,
+ OUT ROGUEAP_ENTRY *pRogueAp,
+ IN PUCHAR pAddr,
+ IN UCHAR FaileCode);
+
+ULONG RogueApTableSetEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT ROGUEAP_TABLE *Tab,
+ IN PUCHAR pAddr,
+ IN UCHAR FaileCode);
+
+VOID RogueApTableDeleteEntry(
+ IN OUT ROGUEAP_TABLE *Tab,
+ IN PUCHAR pAddr);
+
+VOID LeapAuthTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID LeapSendRogueAPReport(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN CCKMAssocRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen);
+
+#endif // __LEAP_H__
diff --git a/drivers/staging/rt3070/link_list.h b/drivers/staging/rt3070/link_list.h
new file mode 100644
index 00000000000..f6521133fd5
--- /dev/null
+++ b/drivers/staging/rt3070/link_list.h
@@ -0,0 +1,134 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#ifndef __LINK_LIST_H__
+#define __LINK_LIST_H__
+
+typedef struct _LIST_ENTRY
+{
+ struct _LIST_ENTRY *pNext;
+} LIST_ENTRY, *PLIST_ENTRY;
+
+typedef struct _LIST_HEADR
+{
+ PLIST_ENTRY pHead;
+ PLIST_ENTRY pTail;
+ UCHAR size;
+} LIST_HEADER, *PLIST_HEADER;
+
+static inline VOID initList(
+ IN PLIST_HEADER pList)
+{
+ pList->pHead = pList->pTail = NULL;
+ pList->size = 0;
+ return;
+}
+
+static inline VOID insertTailList(
+ IN PLIST_HEADER pList,
+ IN PLIST_ENTRY pEntry)
+{
+ pEntry->pNext = NULL;
+ if (pList->pTail)
+ pList->pTail->pNext = pEntry;
+ else
+ pList->pHead = pEntry;
+ pList->pTail = pEntry;
+ pList->size++;
+
+ return;
+}
+
+static inline PLIST_ENTRY removeHeadList(
+ IN PLIST_HEADER pList)
+{
+ PLIST_ENTRY pNext;
+ PLIST_ENTRY pEntry;
+
+ pEntry = pList->pHead;
+ if (pList->pHead != NULL)
+ {
+ pNext = pList->pHead->pNext;
+ pList->pHead = pNext;
+ if (pNext == NULL)
+ pList->pTail = NULL;
+ pList->size--;
+ }
+ return pEntry;
+}
+
+static inline int getListSize(
+ IN PLIST_HEADER pList)
+{
+ return pList->size;
+}
+
+static inline PLIST_ENTRY delEntryList(
+ IN PLIST_HEADER pList,
+ IN PLIST_ENTRY pEntry)
+{
+ PLIST_ENTRY pCurEntry;
+ PLIST_ENTRY pPrvEntry;
+
+ if(pList->pHead == NULL)
+ return NULL;
+
+ if(pEntry == pList->pHead)
+ {
+ pCurEntry = pList->pHead;
+ pList->pHead = pCurEntry->pNext;
+
+ if(pList->pHead == NULL)
+ pList->pTail = NULL;
+
+ pList->size--;
+ return pCurEntry;
+ }
+
+ pPrvEntry = pList->pHead;
+ pCurEntry = pPrvEntry->pNext;
+ while(pCurEntry != NULL)
+ {
+ if (pEntry == pCurEntry)
+ {
+ pPrvEntry->pNext = pCurEntry->pNext;
+
+ if(pEntry == pList->pTail)
+ pList->pTail = pPrvEntry;
+
+ pList->size--;
+ break;
+ }
+ pPrvEntry = pCurEntry;
+ pCurEntry = pPrvEntry->pNext;
+ }
+
+ return pCurEntry;
+}
+
+#endif // ___LINK_LIST_H__ //
+
diff --git a/drivers/staging/rt3070/md4.h b/drivers/staging/rt3070/md4.h
new file mode 100644
index 00000000000..f1e5b526350
--- /dev/null
+++ b/drivers/staging/rt3070/md4.h
@@ -0,0 +1,42 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#ifndef __MD4_H__
+#define __MD4_H__
+
+/* MD4 context. */
+typedef struct _MD4_CTX_ {
+ ULONG state[4]; /* state (ABCD) */
+ ULONG count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ UCHAR buffer[64]; /* input buffer */
+} MD4_CTX;
+
+VOID MD4Init (MD4_CTX *);
+VOID MD4Update (MD4_CTX *, PUCHAR, UINT);
+VOID MD4Final (UCHAR [16], MD4_CTX *);
+
+#endif //__MD4_H__ \ No newline at end of file
diff --git a/drivers/staging/rt3070/md5.h b/drivers/staging/rt3070/md5.h
new file mode 100644
index 00000000000..d85db12170d
--- /dev/null
+++ b/drivers/staging/rt3070/md5.h
@@ -0,0 +1,107 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ md5.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ jan 10-28-03 Initial
+ Rita 11-23-04 Modify MD5 and SHA-1
+*/
+
+#ifndef uint8
+#define uint8 unsigned char
+#endif
+
+#ifndef uint32
+#define uint32 unsigned long int
+#endif
+
+
+#ifndef __MD5_H__
+#define __MD5_H__
+
+#define MD5_MAC_LEN 16
+
+typedef struct _MD5_CTX {
+ UINT32 Buf[4]; // buffers of four states
+ UCHAR Input[64]; // input message
+ UINT32 LenInBitCount[2]; // length counter for input message, 0 up to 64 bits
+} MD5_CTX;
+
+VOID MD5Init(MD5_CTX *pCtx);
+VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes);
+VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx);
+VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16]);
+
+void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac);
+void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac);
+
+//
+// SHA context
+//
+typedef struct _SHA_CTX
+{
+ UINT32 Buf[5]; // buffers of five states
+ UCHAR Input[80]; // input message
+ UINT32 LenInBitCount[2]; // length counter for input message, 0 up to 64 bits
+
+} SHA_CTX;
+
+VOID SHAInit(SHA_CTX *pCtx);
+UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes);
+VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20]);
+VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20]);
+
+#define SHA_DIGEST_LEN 20
+#endif // __MD5_H__
+
+/******************************************************************************/
+#ifndef _AES_H
+#define _AES_H
+
+typedef struct
+{
+ uint32 erk[64]; /* encryption round keys */
+ uint32 drk[64]; /* decryption round keys */
+ int nr; /* number of rounds */
+}
+aes_context;
+
+int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits );
+void rtmp_aes_encrypt( aes_context *ctx, uint8 input[16], uint8 output[16] );
+void rtmp_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] );
+
+void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output);
+int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output);
+
+#endif /* aes.h */
+
diff --git a/drivers/staging/rt3070/mlme.h b/drivers/staging/rt3070/mlme.h
new file mode 100644
index 00000000000..b0035e1fa8e
--- /dev/null
+++ b/drivers/staging/rt3070/mlme.h
@@ -0,0 +1,1468 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ mlme.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2003-08-28 Created
+ John Chang 2004-09-06 modified for RT2600
+
+*/
+#ifndef __MLME_H__
+#define __MLME_H__
+
+//extern UCHAR BROADCAST_ADDR[];
+
+// maximum supported capability information -
+// ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot
+#define SUPPORTED_CAPABILITY_INFO 0x0533
+
+#define END_OF_ARGS -1
+#define LFSR_MASK 0x80000057
+#define MLME_TASK_EXEC_INTV 100/*200*/ //
+#define LEAD_TIME 5
+#define MLME_TASK_EXEC_MULTIPLE 10 /*5*/ // MLME_TASK_EXEC_MULTIPLE * MLME_TASK_EXEC_INTV = 1 sec
+#define REORDER_EXEC_INTV 100 // 0.1 sec
+//#define TBTT_PRELOAD_TIME 384 // usec. LomgPreamble + 24-byte at 1Mbps
+
+// The definition of Radar detection duration region
+#define CE 0
+#define FCC 1
+#define JAP 2
+#define JAP_W53 3
+#define JAP_W56 4
+#define MAX_RD_REGION 5
+
+#ifdef NDIS51_MINIPORT
+#define BEACON_LOST_TIME 4000 // 2048 msec = 2 sec
+#else
+#define BEACON_LOST_TIME 4 * OS_HZ // 2048 msec = 2 sec
+#endif
+
+#define DLS_TIMEOUT 1200 // unit: msec
+#define AUTH_TIMEOUT 300 // unit: msec
+#define ASSOC_TIMEOUT 300 // unit: msec
+#define JOIN_TIMEOUT 2 * OS_HZ // unit: msec
+#define SHORT_CHANNEL_TIME 90 // unit: msec
+#define MIN_CHANNEL_TIME 110 // unit: msec, for dual band scan
+#define MAX_CHANNEL_TIME 140 // unit: msec, for single band scan
+#define FAST_ACTIVE_SCAN_TIME 30 // Active scan waiting for probe response time
+#define CW_MIN_IN_BITS 4 // actual CwMin = 2^CW_MIN_IN_BITS - 1
+
+
+#ifdef CONFIG_STA_SUPPORT
+#ifndef CONFIG_AP_SUPPORT
+#define CW_MAX_IN_BITS 10 // actual CwMax = 2^CW_MAX_IN_BITS - 1
+#endif
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+extern UINT32 CW_MAX_IN_BITS;
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+// Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720).
+// SHould not refer to this constant anymore
+//#define RSSI_TO_DBM_OFFSET 120 // for RT2530 RSSI-115 = dBm
+#define RSSI_FOR_MID_TX_POWER -55 // -55 db is considered mid-distance
+#define RSSI_FOR_LOW_TX_POWER -45 // -45 db is considered very short distance and
+ // eligible to use a lower TX power
+#define RSSI_FOR_LOWEST_TX_POWER -30
+//#define MID_TX_POWER_DELTA 0 // 0 db from full TX power upon mid-distance to AP
+#define LOW_TX_POWER_DELTA 6 // -3 db from full TX power upon very short distance. 1 grade is 0.5 db
+#define LOWEST_TX_POWER_DELTA 16 // -8 db from full TX power upon shortest distance. 1 grade is 0.5 db
+
+#define RSSI_TRIGGERED_UPON_BELOW_THRESHOLD 0
+#define RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD 1
+#define RSSI_THRESHOLD_FOR_ROAMING 25
+#define RSSI_DELTA 5
+
+// Channel Quality Indication
+#define CQI_IS_GOOD(cqi) ((cqi) >= 50)
+//#define CQI_IS_FAIR(cqi) (((cqi) >= 20) && ((cqi) < 50))
+#define CQI_IS_POOR(cqi) (cqi < 50) //(((cqi) >= 5) && ((cqi) < 20))
+#define CQI_IS_BAD(cqi) (cqi < 5)
+#define CQI_IS_DEAD(cqi) (cqi == 0)
+
+// weighting factor to calculate Channel quality, total should be 100%
+#define RSSI_WEIGHTING 50
+#define TX_WEIGHTING 30
+#define RX_WEIGHTING 20
+
+//#define PEER_KEY_NOT_USED 0
+//#define PEER_KEY_64_BIT 64
+//#define PEER_KEY_128_BIT 128
+
+//#define PEER_KEY_64BIT_LEN 8
+//#define PEER_KEY_128BIT_LEN 16
+
+#define BSS_NOT_FOUND 0xFFFFFFFF
+
+
+#ifdef CONFIG_STA_SUPPORT
+#define MAX_LEN_OF_MLME_QUEUE 40 //10
+#endif // CONFIG_STA_SUPPORT //
+
+#define SCAN_PASSIVE 18 // scan with no probe request, only wait beacon and probe response
+#define SCAN_ACTIVE 19 // scan with probe request, and wait beacon and probe response
+#define SCAN_CISCO_PASSIVE 20 // Single channel passive scan
+#define SCAN_CISCO_ACTIVE 21 // Single channel active scan
+#define SCAN_CISCO_NOISE 22 // Single channel passive scan for noise histogram collection
+#define SCAN_CISCO_CHANNEL_LOAD 23 // Single channel passive scan for channel load collection
+#define FAST_SCAN_ACTIVE 24 // scan with probe request, and wait beacon and probe response
+
+#ifdef DOT11N_DRAFT3
+#define SCAN_2040_BSS_COEXIST 26
+#endif // DOT11N_DRAFT3 //
+
+//#define BSS_TABLE_EMPTY(x) ((x).BssNr == 0)
+#define MAC_ADDR_IS_GROUP(Addr) (((Addr[0]) & 0x01))
+#define MAC_ADDR_HASH(Addr) (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
+#define MAC_ADDR_HASH_INDEX(Addr) (MAC_ADDR_HASH(Addr) % HASH_TABLE_SIZE)
+#define TID_MAC_HASH(Addr,TID) (TID^Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
+#define TID_MAC_HASH_INDEX(Addr,TID) (TID_MAC_HASH(Addr,TID) % HASH_TABLE_SIZE)
+
+// LED Control
+// assoiation ON. one LED ON. another blinking when TX, OFF when idle
+// no association, both LED off
+#define ASIC_LED_ACT_ON(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00031e46)
+#define ASIC_LED_ACT_OFF(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00001e46)
+
+// bit definition of the 2-byte pBEACON->Capability field
+#define CAP_IS_ESS_ON(x) (((x) & 0x0001) != 0)
+#define CAP_IS_IBSS_ON(x) (((x) & 0x0002) != 0)
+#define CAP_IS_CF_POLLABLE_ON(x) (((x) & 0x0004) != 0)
+#define CAP_IS_CF_POLL_REQ_ON(x) (((x) & 0x0008) != 0)
+#define CAP_IS_PRIVACY_ON(x) (((x) & 0x0010) != 0)
+#define CAP_IS_SHORT_PREAMBLE_ON(x) (((x) & 0x0020) != 0)
+#define CAP_IS_PBCC_ON(x) (((x) & 0x0040) != 0)
+#define CAP_IS_AGILITY_ON(x) (((x) & 0x0080) != 0)
+#define CAP_IS_SPECTRUM_MGMT(x) (((x) & 0x0100) != 0) // 802.11e d9
+#define CAP_IS_QOS(x) (((x) & 0x0200) != 0) // 802.11e d9
+#define CAP_IS_SHORT_SLOT(x) (((x) & 0x0400) != 0)
+#define CAP_IS_APSD(x) (((x) & 0x0800) != 0) // 802.11e d9
+#define CAP_IS_IMMED_BA(x) (((x) & 0x1000) != 0) // 802.11e d9
+#define CAP_IS_DSSS_OFDM(x) (((x) & 0x2000) != 0)
+#define CAP_IS_DELAY_BA(x) (((x) & 0x4000) != 0) // 802.11e d9
+
+#define CAP_GENERATE(ess,ibss,priv,s_pre,s_slot,spectrum) (((ess) ? 0x0001 : 0x0000) | ((ibss) ? 0x0002 : 0x0000) | ((priv) ? 0x0010 : 0x0000) | ((s_pre) ? 0x0020 : 0x0000) | ((s_slot) ? 0x0400 : 0x0000) | ((spectrum) ? 0x0100 : 0x0000))
+
+//#define STA_QOS_CAPABILITY 0 // 1-byte. see 802.11e d9.0 for bit definition
+
+#define ERP_IS_NON_ERP_PRESENT(x) (((x) & 0x01) != 0) // 802.11g
+#define ERP_IS_USE_PROTECTION(x) (((x) & 0x02) != 0) // 802.11g
+#define ERP_IS_USE_BARKER_PREAMBLE(x) (((x) & 0x04) != 0) // 802.11g
+
+#define DRS_TX_QUALITY_WORST_BOUND 8// 3 // just test by gary
+#define DRS_PENALTY 8
+
+#define BA_NOTUSE 2
+//BA Policy subfiled value in ADDBA frame
+#define IMMED_BA 1
+#define DELAY_BA 0
+
+// BA Initiator subfield in DELBA frame
+#define ORIGINATOR 1
+#define RECIPIENT 0
+
+// ADDBA Status Code
+#define ADDBA_RESULTCODE_SUCCESS 0
+#define ADDBA_RESULTCODE_REFUSED 37
+#define ADDBA_RESULTCODE_INVALID_PARAMETERS 38
+
+// DELBA Reason Code
+#define DELBA_REASONCODE_QSTA_LEAVING 36
+#define DELBA_REASONCODE_END_BA 37
+#define DELBA_REASONCODE_UNKNOWN_BA 38
+#define DELBA_REASONCODE_TIMEOUT 39
+
+// reset all OneSecTx counters
+#define RESET_ONE_SEC_TX_CNT(__pEntry) \
+if (((__pEntry)) != NULL) \
+{ \
+ (__pEntry)->OneSecTxRetryOkCount = 0; \
+ (__pEntry)->OneSecTxFailCount = 0; \
+ (__pEntry)->OneSecTxNoRetryOkCount = 0; \
+}
+
+//
+// 802.11 frame formats
+//
+// HT Capability INFO field in HT Cap IE .
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT LSIGTxopProSup:1;
+ USHORT Forty_Mhz_Intolerant:1;
+ USHORT PSMP:1;
+ USHORT CCKmodein40:1;
+ USHORT AMsduSize:1;
+ USHORT DelayedBA:1; //rt2860c not support
+ USHORT RxSTBC:2;
+ USHORT TxSTBC:1;
+ USHORT ShortGIfor40:1; //for40MHz
+ USHORT ShortGIfor20:1;
+ USHORT GF:1; //green field
+ USHORT MimoPs:2;//momi power safe
+ USHORT ChannelWidth:1;
+ USHORT AdvCoding:1;
+#else
+ USHORT AdvCoding:1;
+ USHORT ChannelWidth:1;
+ USHORT MimoPs:2;//momi power safe
+ USHORT GF:1; //green field
+ USHORT ShortGIfor20:1;
+ USHORT ShortGIfor40:1; //for40MHz
+ USHORT TxSTBC:1;
+ USHORT RxSTBC:2;
+ USHORT DelayedBA:1; //rt2860c not support
+ USHORT AMsduSize:1; // only support as zero
+ USHORT CCKmodein40:1;
+ USHORT PSMP:1;
+ USHORT Forty_Mhz_Intolerant:1;
+ USHORT LSIGTxopProSup:1;
+#endif /* !RT_BIG_ENDIAN */
+} HT_CAP_INFO, *PHT_CAP_INFO;
+
+// HT Capability INFO field in HT Cap IE .
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ UCHAR rsv:3;//momi power safe
+ UCHAR MpduDensity:3;
+ UCHAR MaxRAmpduFactor:2;
+#else
+ UCHAR MaxRAmpduFactor:2;
+ UCHAR MpduDensity:3;
+ UCHAR rsv:3;//momi power safe
+#endif /* !RT_BIG_ENDIAN */
+} HT_CAP_PARM, *PHT_CAP_PARM;
+
+// HT Capability INFO field in HT Cap IE .
+typedef struct PACKED {
+ UCHAR MCSSet[10];
+ UCHAR SupRate[2]; // unit : 1Mbps
+#ifdef RT_BIG_ENDIAN
+ UCHAR rsv:3;
+ UCHAR MpduDensity:1;
+ UCHAR TxStream:2;
+ UCHAR TxRxNotEqual:1;
+ UCHAR TxMCSSetDefined:1;
+#else
+ UCHAR TxMCSSetDefined:1;
+ UCHAR TxRxNotEqual:1;
+ UCHAR TxStream:2;
+ UCHAR MpduDensity:1;
+ UCHAR rsv:3;
+#endif // RT_BIG_ENDIAN //
+ UCHAR rsv3[3];
+} HT_MCS_SET, *PHT_MCS_SET;
+
+// HT Capability INFO field in HT Cap IE .
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT rsv2:4;
+ USHORT RDGSupport:1; //reverse Direction Grant support
+ USHORT PlusHTC:1; //+HTC control field support
+ USHORT MCSFeedback:2; //0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback, 1:rsv.
+ USHORT rsv:5;//momi power safe
+ USHORT TranTime:2;
+ USHORT Pco:1;
+#else
+ USHORT Pco:1;
+ USHORT TranTime:2;
+ USHORT rsv:5;//momi power safe
+ USHORT MCSFeedback:2; //0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback, 1:rsv.
+ USHORT PlusHTC:1; //+HTC control field support
+ USHORT RDGSupport:1; //reverse Direction Grant support
+ USHORT rsv2:4;
+#endif /* RT_BIG_ENDIAN */
+} EXT_HT_CAP_INFO, *PEXT_HT_CAP_INFO;
+
+// HT Beamforming field in HT Cap IE .
+typedef struct PACKED _HT_BF_CAP{
+#ifdef RT_BIG_ENDIAN
+ ULONG rsv:3;
+ ULONG ChanEstimation:2;
+ ULONG CSIRowBFSup:2;
+ ULONG ComSteerBFAntSup:2;
+ ULONG NoComSteerBFAntSup:2;
+ ULONG CSIBFAntSup:2;
+ ULONG MinGrouping:2;
+ ULONG ExpComBF:2;
+ ULONG ExpNoComBF:2;
+ ULONG ExpCSIFbk:2;
+ ULONG ExpComSteerCapable:1;
+ ULONG ExpNoComSteerCapable:1;
+ ULONG ExpCSICapable:1;
+ ULONG Calibration:2;
+ ULONG ImpTxBFCapable:1;
+ ULONG TxNDPCapable:1;
+ ULONG RxNDPCapable:1;
+ ULONG TxSoundCapable:1;
+ ULONG RxSoundCapable:1;
+ ULONG TxBFRecCapable:1;
+#else
+ ULONG TxBFRecCapable:1;
+ ULONG RxSoundCapable:1;
+ ULONG TxSoundCapable:1;
+ ULONG RxNDPCapable:1;
+ ULONG TxNDPCapable:1;
+ ULONG ImpTxBFCapable:1;
+ ULONG Calibration:2;
+ ULONG ExpCSICapable:1;
+ ULONG ExpNoComSteerCapable:1;
+ ULONG ExpComSteerCapable:1;
+ ULONG ExpCSIFbk:2;
+ ULONG ExpNoComBF:2;
+ ULONG ExpComBF:2;
+ ULONG MinGrouping:2;
+ ULONG CSIBFAntSup:2;
+ ULONG NoComSteerBFAntSup:2;
+ ULONG ComSteerBFAntSup:2;
+ ULONG CSIRowBFSup:2;
+ ULONG ChanEstimation:2;
+ ULONG rsv:3;
+#endif // RT_BIG_ENDIAN //
+} HT_BF_CAP, *PHT_BF_CAP;
+
+// HT antenna selection field in HT Cap IE .
+typedef struct PACKED _HT_AS_CAP{
+#ifdef RT_BIG_ENDIAN
+ UCHAR rsv:1;
+ UCHAR TxSoundPPDU:1;
+ UCHAR RxASel:1;
+ UCHAR AntIndFbk:1;
+ UCHAR ExpCSIFbk:1;
+ UCHAR AntIndFbkTxASEL:1;
+ UCHAR ExpCSIFbkTxASEL:1;
+ UCHAR AntSelect:1;
+#else
+ UCHAR AntSelect:1;
+ UCHAR ExpCSIFbkTxASEL:1;
+ UCHAR AntIndFbkTxASEL:1;
+ UCHAR ExpCSIFbk:1;
+ UCHAR AntIndFbk:1;
+ UCHAR RxASel:1;
+ UCHAR TxSoundPPDU:1;
+ UCHAR rsv:1;
+#endif // RT_BIG_ENDIAN //
+} HT_AS_CAP, *PHT_AS_CAP;
+
+// Draft 1.0 set IE length 26, but is extensible..
+#define SIZE_HT_CAP_IE 26
+// The structure for HT Capability IE.
+typedef struct PACKED _HT_CAPABILITY_IE{
+ HT_CAP_INFO HtCapInfo;
+ HT_CAP_PARM HtCapParm;
+// HT_MCS_SET HtMCSSet;
+ UCHAR MCSSet[16];
+ EXT_HT_CAP_INFO ExtHtCapInfo;
+ HT_BF_CAP TxBFCap; // beamforming cap. rt2860c not support beamforming.
+ HT_AS_CAP ASCap; //antenna selection.
+} HT_CAPABILITY_IE, *PHT_CAPABILITY_IE;
+
+
+// 802.11n draft3 related structure definitions.
+// 7.3.2.60
+#define dot11OBSSScanPassiveDwell 20 // in TU. min amount of time that the STA continously scans each channel when performing an active OBSS scan.
+#define dot11OBSSScanActiveDwell 10 // in TU.min amount of time that the STA continously scans each channel when performing an passive OBSS scan.
+#define dot11BSSWidthTriggerScanInterval 300 // in sec. max interval between scan operations to be performed to detect BSS channel width trigger events.
+#define dot11OBSSScanPassiveTotalPerChannel 200 // in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan.
+#define dot11OBSSScanActiveTotalPerChannel 20 //in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan
+#define dot11BSSWidthChannelTransactionDelayFactor 5 // min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maxima
+ // interval between overlapping BSS scan operations.
+#define dot11BSSScanActivityThreshold 25 // in %%, max total time that a STA may be active on the medium during a period of
+ // (dot11BSSWidthChannelTransactionDelayFactor * dot11BSSWidthTriggerScanInterval) seconds without
+ // being obligated to perform OBSS Scan operations. default is 25(== 0.25%)
+
+typedef struct PACKED _OVERLAP_BSS_SCAN_IE{
+ USHORT ScanPassiveDwell;
+ USHORT ScanActiveDwell;
+ USHORT TriggerScanInt; // Trigger scan interval
+ USHORT PassiveTalPerChannel; // passive total per channel
+ USHORT ActiveTalPerChannel; // active total per channel
+ USHORT DelayFactor; // BSS width channel transition delay factor
+ USHORT ScanActThre; // Scan Activity threshold
+}OVERLAP_BSS_SCAN_IE, *POVERLAP_BSS_SCAN_IE;
+
+
+// 7.3.2.56. 20/40 Coexistence element used in Element ID = 72 = IE_2040_BSS_COEXIST
+typedef union PACKED _BSS_2040_COEXIST_IE{
+ struct PACKED {
+ #ifdef RT_BIG_ENDIAN
+ UCHAR rsv:5;
+ UCHAR BSS20WidthReq:1;
+ UCHAR Intolerant40:1;
+ UCHAR InfoReq:1;
+ #else
+ UCHAR InfoReq:1;
+ UCHAR Intolerant40:1; // Inter-BSS. set 1 when prohibits a receiving BSS from operating as a 20/40 Mhz BSS.
+ UCHAR BSS20WidthReq:1; // Intra-BSS set 1 when prohibits a receiving AP from operating its BSS as a 20/40MHz BSS.
+ UCHAR rsv:5;
+#endif // RT_BIG_ENDIAN //
+ } field;
+ UCHAR word;
+} BSS_2040_COEXIST_IE, *PBSS_2040_COEXIST_IE;
+
+
+typedef struct _TRIGGER_EVENTA{
+ BOOLEAN bValid;
+ UCHAR BSSID[6];
+ UCHAR RegClass; // Regulatory Class
+ USHORT Channel;
+ ULONG CDCounter; // Maintain a seperate count down counter for each Event A.
+} TRIGGER_EVENTA, *PTRIGGER_EVENTA;
+
+// 20/40 trigger event table
+// If one Event A delete or created, or if Event B is detected or not detected, STA should send 2040BSSCoexistence to AP.
+#define MAX_TRIGGER_EVENT 64
+typedef struct _TRIGGER_EVENT_TAB{
+ UCHAR EventANo;
+ TRIGGER_EVENTA EventA[MAX_TRIGGER_EVENT];
+ ULONG EventBCountDown; // Count down counter for Event B.
+} TRIGGER_EVENT_TAB, *PTRIGGER_EVENT_TAB;
+
+// 7.3.27 20/40 Bss Coexistence Mgmt capability used in extended capabilities information IE( ID = 127 = IE_EXT_CAPABILITY).
+// This is the first octet and was defined in 802.11n D3.03 and 802.11yD9.0
+typedef struct PACKED _EXT_CAP_INFO_ELEMENT{
+#ifdef RT_BIG_ENDIAN
+ UCHAR rsv2:5;
+ UCHAR ExtendChannelSwitch:1;
+ UCHAR rsv:1;
+ UCHAR BssCoexistMgmtSupport:1;
+#else
+ UCHAR BssCoexistMgmtSupport:1;
+ UCHAR rsv:1;
+ UCHAR ExtendChannelSwitch:1;
+ UCHAR rsv2:5;
+#endif // RT_BIG_ENDIAN //
+}EXT_CAP_INFO_ELEMENT, *PEXT_CAP_INFO_ELEMENT;
+
+
+// 802.11n 7.3.2.61
+typedef struct PACKED _BSS_2040_COEXIST_ELEMENT{
+ UCHAR ElementID; // ID = IE_2040_BSS_COEXIST = 72
+ UCHAR Len;
+ BSS_2040_COEXIST_IE BssCoexistIe;
+}BSS_2040_COEXIST_ELEMENT, *PBSS_2040_COEXIST_ELEMENT;
+
+
+//802.11n 7.3.2.59
+typedef struct PACKED _BSS_2040_INTOLERANT_CH_REPORT{
+ UCHAR ElementID; // ID = IE_2040_BSS_INTOLERANT_REPORT = 73
+ UCHAR Len;
+ UCHAR RegulatoryClass;
+ UCHAR ChList[0];
+}BSS_2040_INTOLERANT_CH_REPORT, *PBSS_2040_INTOLERANT_CH_REPORT;
+
+
+// The structure for channel switch annoucement IE. This is in 802.11n D3.03
+typedef struct PACKED _CHA_SWITCH_ANNOUNCE_IE{
+ UCHAR SwitchMode; //channel switch mode
+ UCHAR NewChannel; //
+ UCHAR SwitchCount; //
+} CHA_SWITCH_ANNOUNCE_IE, *PCHA_SWITCH_ANNOUNCE_IE;
+
+
+// The structure for channel switch annoucement IE. This is in 802.11n D3.03
+typedef struct PACKED _SEC_CHA_OFFSET_IE{
+ UCHAR SecondaryChannelOffset; // 1: Secondary above, 3: Secondary below, 0: no Secondary
+} SEC_CHA_OFFSET_IE, *PSEC_CHA_OFFSET_IE;
+
+
+// This structure is extracted from struct RT_HT_CAPABILITY
+typedef struct {
+ BOOLEAN bHtEnable; // If we should use ht rate.
+ BOOLEAN bPreNHt; // If we should use ht rate.
+ //Substract from HT Capability IE
+ UCHAR MCSSet[16]; //only supoort MCS=0-15,32 ,
+} RT_HT_PHY_INFO, *PRT_HT_PHY_INFO;
+
+//This structure substracts ralink supports from all 802.11n-related features.
+//Features not listed here but contained in 802.11n spec are not supported in rt2860.
+typedef struct {
+#ifdef RT_BIG_ENDIAN
+ USHORT rsv:5;
+ USHORT AmsduSize:1; // Max receiving A-MSDU size
+ USHORT AmsduEnable:1; // Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
+ USHORT RxSTBC:2; // 2 bits
+ USHORT TxSTBC:1;
+ USHORT ShortGIfor40:1; //for40MHz
+ USHORT ShortGIfor20:1;
+ USHORT GF:1; //green field
+ USHORT MimoPs:2;//mimo power safe MMPS_
+ USHORT ChannelWidth:1;
+#else
+ USHORT ChannelWidth:1;
+ USHORT MimoPs:2;//mimo power safe MMPS_
+ USHORT GF:1; //green field
+ USHORT ShortGIfor20:1;
+ USHORT ShortGIfor40:1; //for40MHz
+ USHORT TxSTBC:1;
+ USHORT RxSTBC:2; // 2 bits
+ USHORT AmsduEnable:1; // Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
+ USHORT AmsduSize:1; // Max receiving A-MSDU size
+ USHORT rsv:5;
+#endif
+
+ //Substract from Addiont HT INFO IE
+#ifdef RT_BIG_ENDIAN
+ UCHAR RecomWidth:1;
+ UCHAR ExtChanOffset:2; // Please not the difference with following UCHAR NewExtChannelOffset; from 802.11n
+ UCHAR MpduDensity:3;
+ UCHAR MaxRAmpduFactor:2;
+#else
+ UCHAR MaxRAmpduFactor:2;
+ UCHAR MpduDensity:3;
+ UCHAR ExtChanOffset:2; // Please not the difference with following UCHAR NewExtChannelOffset; from 802.11n
+ UCHAR RecomWidth:1;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+ USHORT rsv2:11;
+ USHORT OBSS_NonHTExist:1;
+ USHORT rsv3:1;
+ USHORT NonGfPresent:1;
+ USHORT OperaionMode:2;
+#else
+ USHORT OperaionMode:2;
+ USHORT NonGfPresent:1;
+ USHORT rsv3:1;
+ USHORT OBSS_NonHTExist:1;
+ USHORT rsv2:11;
+#endif
+
+ // New Extension Channel Offset IE
+ UCHAR NewExtChannelOffset;
+ // Extension Capability IE = 127
+ UCHAR BSSCoexist2040;
+} RT_HT_CAPABILITY, *PRT_HT_CAPABILITY;
+
+// field in Addtional HT Information IE .
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ UCHAR SerInterGranu:3;
+ UCHAR S_PSMPSup:1;
+ UCHAR RifsMode:1;
+ UCHAR RecomWidth:1;
+ UCHAR ExtChanOffset:2;
+#else
+ UCHAR ExtChanOffset:2;
+ UCHAR RecomWidth:1;
+ UCHAR RifsMode:1;
+ UCHAR S_PSMPSup:1; //Indicate support for scheduled PSMP
+ UCHAR SerInterGranu:3; //service interval granularity
+#endif
+} ADD_HTINFO, *PADD_HTINFO;
+
+typedef struct PACKED{
+#ifdef RT_BIG_ENDIAN
+ USHORT rsv2:11;
+ USHORT OBSS_NonHTExist:1;
+ USHORT rsv:1;
+ USHORT NonGfPresent:1;
+ USHORT OperaionMode:2;
+#else
+ USHORT OperaionMode:2;
+ USHORT NonGfPresent:1;
+ USHORT rsv:1;
+ USHORT OBSS_NonHTExist:1;
+ USHORT rsv2:11;
+#endif
+} ADD_HTINFO2, *PADD_HTINFO2;
+
+
+// TODO: Need sync with spec about the definition of StbcMcs. In Draft 3.03, it's reserved.
+typedef struct PACKED{
+#ifdef RT_BIG_ENDIAN
+ USHORT rsv:4;
+ USHORT PcoPhase:1;
+ USHORT PcoActive:1;
+ USHORT LsigTxopProt:1;
+ USHORT STBCBeacon:1;
+ USHORT DualCTSProtect:1;
+ USHORT DualBeacon:1;
+ USHORT StbcMcs:6;
+#else
+ USHORT StbcMcs:6;
+ USHORT DualBeacon:1;
+ USHORT DualCTSProtect:1;
+ USHORT STBCBeacon:1;
+ USHORT LsigTxopProt:1; // L-SIG TXOP protection full support
+ USHORT PcoActive:1;
+ USHORT PcoPhase:1;
+ USHORT rsv:4;
+#endif // RT_BIG_ENDIAN //
+} ADD_HTINFO3, *PADD_HTINFO3;
+
+#define SIZE_ADD_HT_INFO_IE 22
+typedef struct PACKED{
+ UCHAR ControlChan;
+ ADD_HTINFO AddHtInfo;
+ ADD_HTINFO2 AddHtInfo2;
+ ADD_HTINFO3 AddHtInfo3;
+ UCHAR MCSSet[16]; // Basic MCS set
+} ADD_HT_INFO_IE, *PADD_HT_INFO_IE;
+
+typedef struct PACKED{
+ UCHAR NewExtChanOffset;
+} NEW_EXT_CHAN_IE, *PNEW_EXT_CHAN_IE;
+
+
+// 4-byte HTC field. maybe included in any frame except non-QOS data frame. The Order bit must set 1.
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ UINT32 RDG:1; //RDG / More PPDU
+ UINT32 ACConstraint:1; //feedback request
+ UINT32 rsv:5; //calibration sequence
+ UINT32 ZLFAnnouce:1; // ZLF announcement
+ UINT32 CSISTEERING:2; //CSI/ STEERING
+ UINT32 FBKReq:2; //feedback request
+ UINT32 CalSeq:2; //calibration sequence
+ UINT32 CalPos:2; // calibration position
+ UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
+ UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB.
+ UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
+ UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback
+ UINT32 TRQ:1; //sounding request
+ UINT32 MA:1; //management action payload exist in (QoS Null+HTC)
+#else
+ UINT32 MA:1; //management action payload exist in (QoS Null+HTC)
+ UINT32 TRQ:1; //sounding request
+ UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback
+ UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
+ UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB.
+ UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
+ UINT32 CalPos:2; // calibration position
+ UINT32 CalSeq:2; //calibration sequence
+ UINT32 FBKReq:2; //feedback request
+ UINT32 CSISTEERING:2; //CSI/ STEERING
+ UINT32 ZLFAnnouce:1; // ZLF announcement
+ UINT32 rsv:5; //calibration sequence
+ UINT32 ACConstraint:1; //feedback request
+ UINT32 RDG:1; //RDG / More PPDU
+#endif /* !RT_BIG_ENDIAN */
+} HT_CONTROL, *PHT_CONTROL;
+
+// 2-byte QOS CONTROL field
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT Txop_QueueSize:8;
+ USHORT AMsduPresent:1;
+ USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA
+ USHORT EOSP:1;
+ USHORT TID:4;
+#else
+ USHORT TID:4;
+ USHORT EOSP:1;
+ USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA
+ USHORT AMsduPresent:1;
+ USHORT Txop_QueueSize:8;
+#endif /* !RT_BIG_ENDIAN */
+} QOS_CONTROL, *PQOS_CONTROL;
+
+// 2-byte Frame control field
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT Order:1; // Strict order expected
+ USHORT Wep:1; // Wep data
+ USHORT MoreData:1; // More data bit
+ USHORT PwrMgmt:1; // Power management bit
+ USHORT Retry:1; // Retry status bit
+ USHORT MoreFrag:1; // More fragment bit
+ USHORT FrDs:1; // From DS indication
+ USHORT ToDs:1; // To DS indication
+ USHORT SubType:4; // MSDU subtype
+ USHORT Type:2; // MSDU type
+ USHORT Ver:2; // Protocol version
+#else
+ USHORT Ver:2; // Protocol version
+ USHORT Type:2; // MSDU type
+ USHORT SubType:4; // MSDU subtype
+ USHORT ToDs:1; // To DS indication
+ USHORT FrDs:1; // From DS indication
+ USHORT MoreFrag:1; // More fragment bit
+ USHORT Retry:1; // Retry status bit
+ USHORT PwrMgmt:1; // Power management bit
+ USHORT MoreData:1; // More data bit
+ USHORT Wep:1; // Wep data
+ USHORT Order:1; // Strict order expected
+#endif /* !RT_BIG_ENDIAN */
+} FRAME_CONTROL, *PFRAME_CONTROL;
+
+typedef struct PACKED _HEADER_802_11 {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ UCHAR Addr3[MAC_ADDR_LEN];
+#ifdef RT_BIG_ENDIAN
+ USHORT Sequence:12;
+ USHORT Frag:4;
+#else
+ USHORT Frag:4;
+ USHORT Sequence:12;
+#endif /* !RT_BIG_ENDIAN */
+ UCHAR Octet[0];
+} HEADER_802_11, *PHEADER_802_11;
+
+typedef struct PACKED _FRAME_802_11 {
+ HEADER_802_11 Hdr;
+ UCHAR Octet[1];
+} FRAME_802_11, *PFRAME_802_11;
+
+// QoSNull embedding of management action. When HT Control MA field set to 1.
+typedef struct PACKED _MA_BODY {
+ UCHAR Category;
+ UCHAR Action;
+ UCHAR Octet[1];
+} MA_BODY, *PMA_BODY;
+
+typedef struct PACKED _HEADER_802_3 {
+ UCHAR DAAddr1[MAC_ADDR_LEN];
+ UCHAR SAAddr2[MAC_ADDR_LEN];
+ UCHAR Octet[2];
+} HEADER_802_3, *PHEADER_802_3;
+////Block ACK related format
+// 2-byte BA Parameter field in DELBA frames to terminate an already set up bA
+typedef struct PACKED{
+#ifdef RT_BIG_ENDIAN
+ USHORT TID:4; // value of TC os TS
+ USHORT Initiator:1; // 1: originator 0:recipient
+ USHORT Rsv:11; // always set to 0
+#else
+ USHORT Rsv:11; // always set to 0
+ USHORT Initiator:1; // 1: originator 0:recipient
+ USHORT TID:4; // value of TC os TS
+#endif /* !RT_BIG_ENDIAN */
+} DELBA_PARM, *PDELBA_PARM;
+
+// 2-byte BA Parameter Set field in ADDBA frames to signal parm for setting up a BA
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT BufSize:10; // number of buffe of size 2304 octetsr
+ USHORT TID:4; // value of TC os TS
+ USHORT BAPolicy:1; // 1: immediately BA 0:delayed BA
+ USHORT AMSDUSupported:1; // 0: not permitted 1: permitted
+#else
+ USHORT AMSDUSupported:1; // 0: not permitted 1: permitted
+ USHORT BAPolicy:1; // 1: immediately BA 0:delayed BA
+ USHORT TID:4; // value of TC os TS
+ USHORT BufSize:10; // number of buffe of size 2304 octetsr
+#endif /* !RT_BIG_ENDIAN */
+} BA_PARM, *PBA_PARM;
+
+// 2-byte BA Starting Seq CONTROL field
+typedef union PACKED {
+ struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT StartSeq:12; // sequence number of the 1st MSDU for which this BAR is sent
+ USHORT FragNum:4; // always set to 0
+#else
+ USHORT FragNum:4; // always set to 0
+ USHORT StartSeq:12; // sequence number of the 1st MSDU for which this BAR is sent
+#endif /* RT_BIG_ENDIAN */
+ } field;
+ USHORT word;
+} BASEQ_CONTROL, *PBASEQ_CONTROL;
+
+//BAControl and BARControl are the same
+// 2-byte BA CONTROL field in BA frame
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT TID:4;
+ USHORT Rsv:9;
+ USHORT Compressed:1;
+ USHORT MTID:1; //EWC V1.24
+ USHORT ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK 1:No ACK
+#else
+ USHORT ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK 1:No ACK
+ USHORT MTID:1; //EWC V1.24
+ USHORT Compressed:1;
+ USHORT Rsv:9;
+ USHORT TID:4;
+#endif /* !RT_BIG_ENDIAN */
+} BA_CONTROL, *PBA_CONTROL;
+
+// 2-byte BAR CONTROL field in BAR frame
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT TID:4;
+ USHORT Rsv1:9;
+ USHORT Compressed:1;
+ USHORT MTID:1; //if this bit1, use FRAME_MTBA_REQ, if 0, use FRAME_BA_REQ
+ USHORT ACKPolicy:1;
+#else
+ USHORT ACKPolicy:1; // 0:normal ack, 1:no ack.
+ USHORT MTID:1; //if this bit1, use FRAME_MTBA_REQ, if 0, use FRAME_BA_REQ
+ USHORT Compressed:1;
+ USHORT Rsv1:9;
+ USHORT TID:4;
+#endif /* !RT_BIG_ENDIAN */
+} BAR_CONTROL, *PBAR_CONTROL;
+
+// BARControl in MTBAR frame
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT NumTID:4;
+ USHORT Rsv1:9;
+ USHORT Compressed:1;
+ USHORT MTID:1;
+ USHORT ACKPolicy:1;
+#else
+ USHORT ACKPolicy:1;
+ USHORT MTID:1;
+ USHORT Compressed:1;
+ USHORT Rsv1:9;
+ USHORT NumTID:4;
+#endif /* !RT_BIG_ENDIAN */
+} MTBAR_CONTROL, *PMTBAR_CONTROL;
+
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT TID:4;
+ USHORT Rsv1:12;
+#else
+ USHORT Rsv1:12;
+ USHORT TID:4;
+#endif /* !RT_BIG_ENDIAN */
+} PER_TID_INFO, *PPER_TID_INFO;
+
+typedef struct {
+ PER_TID_INFO PerTID;
+ BASEQ_CONTROL BAStartingSeq;
+} EACH_TID, *PEACH_TID;
+
+
+typedef struct PACKED _PSPOLL_FRAME {
+ FRAME_CONTROL FC;
+ USHORT Aid;
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR Ta[MAC_ADDR_LEN];
+} PSPOLL_FRAME, *PPSPOLL_FRAME;
+
+typedef struct PACKED _RTS_FRAME {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+}RTS_FRAME, *PRTS_FRAME;
+
+// BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap.
+typedef struct PACKED _FRAME_BA_REQ {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ BAR_CONTROL BARControl;
+ BASEQ_CONTROL BAStartingSeq;
+} FRAME_BA_REQ, *PFRAME_BA_REQ;
+
+typedef struct PACKED _FRAME_MTBA_REQ {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ MTBAR_CONTROL MTBARControl;
+ PER_TID_INFO PerTIDInfo;
+ BASEQ_CONTROL BAStartingSeq;
+} FRAME_MTBA_REQ, *PFRAME_MTBA_REQ;
+
+// Compressed format is mandantory in HT STA
+typedef struct PACKED _FRAME_MTBA {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ BA_CONTROL BAControl;
+ BASEQ_CONTROL BAStartingSeq;
+ UCHAR BitMap[8];
+} FRAME_MTBA, *PFRAME_MTBA;
+
+typedef struct PACKED _FRAME_PSMP_ACTION {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ UCHAR Psmp; // 7.3.1.25
+} FRAME_PSMP_ACTION, *PFRAME_PSMP_ACTION;
+
+typedef struct PACKED _FRAME_ACTION_HDR {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+} FRAME_ACTION_HDR, *PFRAME_ACTION_HDR;
+
+//Action Frame
+//Action Frame Category:Spectrum, Action:Channel Switch. 7.3.2.20
+typedef struct PACKED _CHAN_SWITCH_ANNOUNCE {
+ UCHAR ElementID; // ID = IE_CHANNEL_SWITCH_ANNOUNCEMENT = 37
+ UCHAR Len;
+ CHA_SWITCH_ANNOUNCE_IE CSAnnounceIe;
+} CHAN_SWITCH_ANNOUNCE, *PCHAN_SWITCH_ANNOUNCE;
+
+
+//802.11n : 7.3.2.20a
+typedef struct PACKED _SECOND_CHAN_OFFSET {
+ UCHAR ElementID; // ID = IE_SECONDARY_CH_OFFSET = 62
+ UCHAR Len;
+ SEC_CHA_OFFSET_IE SecChOffsetIe;
+} SECOND_CHAN_OFFSET, *PSECOND_CHAN_OFFSET;
+
+
+typedef struct PACKED _FRAME_SPETRUM_CS {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ CHAN_SWITCH_ANNOUNCE CSAnnounce;
+ SECOND_CHAN_OFFSET SecondChannel;
+} FRAME_SPETRUM_CS, *PFRAME_SPETRUM_CS;
+
+
+typedef struct PACKED _FRAME_ADDBA_REQ {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ UCHAR Token; // 1
+ BA_PARM BaParm; // 2 - 10
+ USHORT TimeOutValue; // 0 - 0
+ BASEQ_CONTROL BaStartSeq; // 0-0
+} FRAME_ADDBA_REQ, *PFRAME_ADDBA_REQ;
+
+typedef struct PACKED _FRAME_ADDBA_RSP {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ UCHAR Token;
+ USHORT StatusCode;
+ BA_PARM BaParm; //0 - 2
+ USHORT TimeOutValue;
+} FRAME_ADDBA_RSP, *PFRAME_ADDBA_RSP;
+
+typedef struct PACKED _FRAME_DELBA_REQ {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ DELBA_PARM DelbaParm;
+ USHORT ReasonCode;
+} FRAME_DELBA_REQ, *PFRAME_DELBA_REQ;
+
+
+//7.2.1.7
+typedef struct PACKED _FRAME_BAR {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ BAR_CONTROL BarControl;
+ BASEQ_CONTROL StartingSeq;
+} FRAME_BAR, *PFRAME_BAR;
+
+//7.2.1.7
+typedef struct PACKED _FRAME_BA {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ BAR_CONTROL BarControl;
+ BASEQ_CONTROL StartingSeq;
+ UCHAR bitmask[8];
+} FRAME_BA, *PFRAME_BA;
+
+
+// Radio Measuement Request Frame Format
+typedef struct PACKED _FRAME_RM_REQ_ACTION {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ UCHAR Token;
+ USHORT Repetition;
+ UCHAR data[0];
+} FRAME_RM_REQ_ACTION, *PFRAME_RM_REQ_ACTION;
+
+typedef struct PACKED {
+ UCHAR ID;
+ UCHAR Length;
+ UCHAR ChannelSwitchMode;
+ UCHAR NewRegClass;
+ UCHAR NewChannelNum;
+ UCHAR ChannelSwitchCount;
+} HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE, *PHT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE;
+
+
+//
+// _Limit must be the 2**n - 1
+// _SEQ1 , _SEQ2 must be within 0 ~ _Limit
+//
+#define SEQ_STEPONE(_SEQ1, _SEQ2, _Limit) ((_SEQ1 == ((_SEQ2+1) & _Limit)))
+#define SEQ_SMALLER(_SEQ1, _SEQ2, _Limit) (((_SEQ1-_SEQ2) & ((_Limit+1)>>1)))
+#define SEQ_LARGER(_SEQ1, _SEQ2, _Limit) ((_SEQ1 != _SEQ2) && !(((_SEQ1-_SEQ2) & ((_Limit+1)>>1))))
+#define SEQ_WITHIN_WIN(_SEQ1, _SEQ2, _WIN, _Limit) (SEQ_LARGER(_SEQ1, _SEQ2, _Limit) && \
+ SEQ_SMALLER(_SEQ1, ((_SEQ2+_WIN+1)&_Limit), _Limit))
+
+//
+// Contention-free parameter (without ID and Length)
+//
+typedef struct PACKED {
+ BOOLEAN bValid; // 1: variable contains valid value
+ UCHAR CfpCount;
+ UCHAR CfpPeriod;
+ USHORT CfpMaxDuration;
+ USHORT CfpDurRemaining;
+} CF_PARM, *PCF_PARM;
+
+typedef struct _CIPHER_SUITE {
+ NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher 1, this one has more secured cipher suite
+ NDIS_802_11_ENCRYPTION_STATUS PairCipherAux; // Unicast cipher 2 if AP announce two unicast cipher suite
+ NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Group cipher
+ USHORT RsnCapability; // RSN capability from beacon
+ BOOLEAN bMixMode; // Indicate Pair & Group cipher might be different
+} CIPHER_SUITE, *PCIPHER_SUITE;
+
+// EDCA configuration from AP's BEACON/ProbeRsp
+typedef struct {
+ BOOLEAN bValid; // 1: variable contains valid value
+ BOOLEAN bAdd; // 1: variable contains valid value
+ BOOLEAN bQAck;
+ BOOLEAN bQueueRequest;
+ BOOLEAN bTxopRequest;
+ BOOLEAN bAPSDCapable;
+// BOOLEAN bMoreDataAck;
+ UCHAR EdcaUpdateCount;
+ UCHAR Aifsn[4]; // 0:AC_BK, 1:AC_BE, 2:AC_VI, 3:AC_VO
+ UCHAR Cwmin[4];
+ UCHAR Cwmax[4];
+ USHORT Txop[4]; // in unit of 32-us
+ BOOLEAN bACM[4]; // 1: Admission Control of AC_BK is mandattory
+} EDCA_PARM, *PEDCA_PARM;
+
+// QBSS LOAD information from QAP's BEACON/ProbeRsp
+typedef struct {
+ BOOLEAN bValid; // 1: variable contains valid value
+ USHORT StaNum;
+ UCHAR ChannelUtilization;
+ USHORT RemainingAdmissionControl; // in unit of 32-us
+} QBSS_LOAD_PARM, *PQBSS_LOAD_PARM;
+
+// QBSS Info field in QSTA's assoc req
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ UCHAR Rsv2:1;
+ UCHAR MaxSPLength:2;
+ UCHAR Rsv1:1;
+ UCHAR UAPSD_AC_BE:1;
+ UCHAR UAPSD_AC_BK:1;
+ UCHAR UAPSD_AC_VI:1;
+ UCHAR UAPSD_AC_VO:1;
+#else
+ UCHAR UAPSD_AC_VO:1;
+ UCHAR UAPSD_AC_VI:1;
+ UCHAR UAPSD_AC_BK:1;
+ UCHAR UAPSD_AC_BE:1;
+ UCHAR Rsv1:1;
+ UCHAR MaxSPLength:2;
+ UCHAR Rsv2:1;
+#endif /* !RT_BIG_ENDIAN */
+} QBSS_STA_INFO_PARM, *PQBSS_STA_INFO_PARM;
+
+// QBSS Info field in QAP's Beacon/ProbeRsp
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ UCHAR UAPSD:1;
+ UCHAR Rsv:3;
+ UCHAR ParamSetCount:4;
+#else
+ UCHAR ParamSetCount:4;
+ UCHAR Rsv:3;
+ UCHAR UAPSD:1;
+#endif /* !RT_BIG_ENDIAN */
+} QBSS_AP_INFO_PARM, *PQBSS_AP_INFO_PARM;
+
+// QOS Capability reported in QAP's BEACON/ProbeRsp
+// QOS Capability sent out in QSTA's AssociateReq/ReAssociateReq
+typedef struct {
+ BOOLEAN bValid; // 1: variable contains valid value
+ BOOLEAN bQAck;
+ BOOLEAN bQueueRequest;
+ BOOLEAN bTxopRequest;
+// BOOLEAN bMoreDataAck;
+ UCHAR EdcaUpdateCount;
+} QOS_CAPABILITY_PARM, *PQOS_CAPABILITY_PARM;
+
+#ifdef CONFIG_STA_SUPPORT
+typedef struct {
+ UCHAR IELen;
+ UCHAR IE[MAX_CUSTOM_LEN];
+} WPA_IE_;
+#endif // CONFIG_STA_SUPPORT //
+
+
+typedef struct {
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR Channel;
+ UCHAR CentralChannel; //Store the wide-band central channel for 40MHz. .used in 40MHz AP. Or this is the same as Channel.
+ UCHAR BssType;
+ USHORT AtimWin;
+ USHORT BeaconPeriod;
+
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen;
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR ExtRateLen;
+ HT_CAPABILITY_IE HtCapability;
+ UCHAR HtCapabilityLen;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR AddHtInfoLen;
+ UCHAR NewExtChanOffset;
+ CHAR Rssi;
+ UCHAR Privacy; // Indicate security function ON/OFF. Don't mess up with auth mode.
+ UCHAR Hidden;
+
+ USHORT DtimPeriod;
+ USHORT CapabilityInfo;
+
+ USHORT CfpCount;
+ USHORT CfpPeriod;
+ USHORT CfpMaxDuration;
+ USHORT CfpDurRemaining;
+ UCHAR SsidLen;
+ CHAR Ssid[MAX_LEN_OF_SSID];
+
+ ULONG LastBeaconRxTime; // OS's timestamp
+
+ BOOLEAN bSES;
+
+ // New for WPA2
+ CIPHER_SUITE WPA; // AP announced WPA cipher suite
+ CIPHER_SUITE WPA2; // AP announced WPA2 cipher suite
+
+ // New for microsoft WPA support
+ NDIS_802_11_FIXED_IEs FixIEs;
+ NDIS_802_11_AUTHENTICATION_MODE AuthModeAux; // Addition mode for WPA2 / WPA capable AP
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode;
+ NDIS_802_11_WEP_STATUS WepStatus; // Unicast Encryption Algorithm extract from VAR_IE
+ USHORT VarIELen; // Length of next VIE include EID & Length
+ UCHAR VarIEs[MAX_VIE_LEN];
+
+ // CCX Ckip information
+ UCHAR CkipFlag;
+
+ // CCX 2 TSF
+ UCHAR PTSF[4]; // Parent TSF
+ UCHAR TTSF[8]; // Target TSF
+
+ // 802.11e d9, and WMM
+ EDCA_PARM EdcaParm;
+ QOS_CAPABILITY_PARM QosCapability;
+ QBSS_LOAD_PARM QbssLoad;
+#ifdef CONFIG_STA_SUPPORT
+ WPA_IE_ WpaIE;
+ WPA_IE_ RsnIE;
+#ifdef EXT_BUILD_CHANNEL_LIST
+ UCHAR CountryString[3];
+ BOOLEAN bHasCountryIE;
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+} BSS_ENTRY, *PBSS_ENTRY;
+
+typedef struct {
+ UCHAR BssNr;
+ UCHAR BssOverlapNr;
+ BSS_ENTRY BssEntry[MAX_LEN_OF_BSS_TABLE];
+} BSS_TABLE, *PBSS_TABLE;
+
+
+typedef struct _MLME_QUEUE_ELEM {
+ ULONG Machine;
+ ULONG MsgType;
+ ULONG MsgLen;
+ UCHAR Msg[MGMT_DMA_BUFFER_SIZE];
+ LARGE_INTEGER TimeStamp;
+ UCHAR Rssi0;
+ UCHAR Rssi1;
+ UCHAR Rssi2;
+ UCHAR Signal;
+ UCHAR Channel;
+ UCHAR Wcid;
+ BOOLEAN Occupied;
+#ifdef MLME_EX
+ USHORT Idx;
+#endif // MLME_EX //
+} MLME_QUEUE_ELEM, *PMLME_QUEUE_ELEM;
+
+typedef struct _MLME_QUEUE {
+ ULONG Num;
+ ULONG Head;
+ ULONG Tail;
+ NDIS_SPIN_LOCK Lock;
+ MLME_QUEUE_ELEM Entry[MAX_LEN_OF_MLME_QUEUE];
+} MLME_QUEUE, *PMLME_QUEUE;
+
+typedef VOID (*STATE_MACHINE_FUNC)(VOID *Adaptor, MLME_QUEUE_ELEM *Elem);
+
+typedef struct _STATE_MACHINE {
+ ULONG Base;
+ ULONG NrState;
+ ULONG NrMsg;
+ ULONG CurrState;
+ STATE_MACHINE_FUNC *TransFunc;
+} STATE_MACHINE, *PSTATE_MACHINE;
+
+
+// MLME AUX data structure that hold temporarliy settings during a connection attempt.
+// Once this attemp succeeds, all settings will be copy to pAd->StaActive.
+// A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of
+// several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely
+// separate this under-trial settings away from pAd->StaActive so that once
+// this new attempt failed, driver can auto-recover back to the active settings.
+typedef struct _MLME_AUX {
+ UCHAR BssType;
+ UCHAR Ssid[MAX_LEN_OF_SSID];
+ UCHAR SsidLen;
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR AutoReconnectSsid[MAX_LEN_OF_SSID];
+ UCHAR AutoReconnectSsidLen;
+ USHORT Alg;
+ UCHAR ScanType;
+ UCHAR Channel;
+ UCHAR CentralChannel;
+ USHORT Aid;
+ USHORT CapabilityInfo;
+ USHORT BeaconPeriod;
+ USHORT CfpMaxDuration;
+ USHORT CfpPeriod;
+ USHORT AtimWin;
+
+ // Copy supported rate from desired AP's beacon. We are trying to match
+ // AP's supported and extended rate settings.
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen;
+ UCHAR ExtRateLen;
+ HT_CAPABILITY_IE HtCapability;
+ UCHAR HtCapabilityLen;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR NewExtChannelOffset;
+ //RT_HT_CAPABILITY SupportedHtPhy;
+
+ // new for QOS
+ QOS_CAPABILITY_PARM APQosCapability; // QOS capability of the current associated AP
+ EDCA_PARM APEdcaParm; // EDCA parameters of the current associated AP
+ QBSS_LOAD_PARM APQbssLoad; // QBSS load of the current associated AP
+
+ // new to keep Ralink specific feature
+ ULONG APRalinkIe;
+
+ BSS_TABLE SsidBssTab; // AP list for the same SSID
+ BSS_TABLE RoamTab; // AP list eligible for roaming
+ ULONG BssIdx;
+ ULONG RoamIdx;
+
+ BOOLEAN CurrReqIsFromNdis;
+
+ RALINK_TIMER_STRUCT BeaconTimer, ScanTimer;
+ RALINK_TIMER_STRUCT AuthTimer;
+ RALINK_TIMER_STRUCT AssocTimer, ReassocTimer, DisassocTimer;
+} MLME_AUX, *PMLME_AUX;
+
+typedef struct _MLME_ADDBA_REQ_STRUCT{
+ UCHAR Wcid; //
+ UCHAR pAddr[MAC_ADDR_LEN];
+ UCHAR BaBufSize;
+ USHORT TimeOutValue;
+ UCHAR TID;
+ UCHAR Token;
+ USHORT BaStartSeq;
+} MLME_ADDBA_REQ_STRUCT, *PMLME_ADDBA_REQ_STRUCT;
+
+
+typedef struct _MLME_DELBA_REQ_STRUCT{
+ UCHAR Wcid; //
+ UCHAR Addr[MAC_ADDR_LEN];
+ UCHAR TID;
+ UCHAR Initiator;
+} MLME_DELBA_REQ_STRUCT, *PMLME_DELBA_REQ_STRUCT;
+
+// assoc struct is equal to reassoc
+typedef struct _MLME_ASSOC_REQ_STRUCT{
+ UCHAR Addr[MAC_ADDR_LEN];
+ USHORT CapabilityInfo;
+ USHORT ListenIntv;
+ ULONG Timeout;
+} MLME_ASSOC_REQ_STRUCT, *PMLME_ASSOC_REQ_STRUCT, MLME_REASSOC_REQ_STRUCT, *PMLME_REASSOC_REQ_STRUCT;
+
+typedef struct _MLME_DISASSOC_REQ_STRUCT{
+ UCHAR Addr[MAC_ADDR_LEN];
+ USHORT Reason;
+} MLME_DISASSOC_REQ_STRUCT, *PMLME_DISASSOC_REQ_STRUCT;
+
+typedef struct _MLME_AUTH_REQ_STRUCT {
+ UCHAR Addr[MAC_ADDR_LEN];
+ USHORT Alg;
+ ULONG Timeout;
+} MLME_AUTH_REQ_STRUCT, *PMLME_AUTH_REQ_STRUCT;
+
+typedef struct _MLME_DEAUTH_REQ_STRUCT {
+ UCHAR Addr[MAC_ADDR_LEN];
+ USHORT Reason;
+} MLME_DEAUTH_REQ_STRUCT, *PMLME_DEAUTH_REQ_STRUCT;
+
+typedef struct {
+ ULONG BssIdx;
+} MLME_JOIN_REQ_STRUCT;
+
+typedef struct _MLME_SCAN_REQ_STRUCT {
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR BssType;
+ UCHAR ScanType;
+ UCHAR SsidLen;
+ CHAR Ssid[MAX_LEN_OF_SSID];
+} MLME_SCAN_REQ_STRUCT, *PMLME_SCAN_REQ_STRUCT;
+
+typedef struct _MLME_START_REQ_STRUCT {
+ CHAR Ssid[MAX_LEN_OF_SSID];
+ UCHAR SsidLen;
+} MLME_START_REQ_STRUCT, *PMLME_START_REQ_STRUCT;
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+// structure for DLS
+typedef struct _RT_802_11_DLS {
+ USHORT TimeOut; // Use to time out while slience, unit: second , set by UI
+ USHORT CountDownTimer; // Use to time out while slience,unit: second , used by driver only
+ NDIS_802_11_MAC_ADDRESS MacAddr; // set by UI
+ UCHAR Status; // 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
+ BOOLEAN Valid; // 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
+ RALINK_TIMER_STRUCT Timer; // Use to time out while handshake
+ USHORT Sequence;
+ USHORT MacTabMatchWCID; // ASIC
+ BOOLEAN bHTCap;
+ PVOID pAd;
+} RT_802_11_DLS, *PRT_802_11_DLS;
+
+typedef struct _MLME_DLS_REQ_STRUCT {
+ PRT_802_11_DLS pDLS;
+ USHORT Reason;
+} MLME_DLS_REQ_STRUCT, *PMLME_DLS_REQ_STRUCT;
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+typedef struct PACKED {
+ UCHAR Eid;
+ UCHAR Len;
+ CHAR Octet[1];
+} EID_STRUCT,*PEID_STRUCT, BEACON_EID_STRUCT, *PBEACON_EID_STRUCT;
+
+typedef struct PACKED _RTMP_TX_RATE_SWITCH
+{
+ UCHAR ItemNo;
+#ifdef RT_BIG_ENDIAN
+ UCHAR Rsv2:2;
+ UCHAR Mode:2;
+ UCHAR Rsv1:1;
+ UCHAR BW:1;
+ UCHAR ShortGI:1;
+ UCHAR STBC:1;
+#else
+ UCHAR STBC:1;
+ UCHAR ShortGI:1;
+ UCHAR BW:1;
+ UCHAR Rsv1:1;
+ UCHAR Mode:2;
+ UCHAR Rsv2:2;
+#endif
+ UCHAR CurrMCS;
+ UCHAR TrainUp;
+ UCHAR TrainDown;
+} RRTMP_TX_RATE_SWITCH, *PRTMP_TX_RATE_SWITCH;
+
+// ========================== AP mlme.h ===============================
+#define TBTT_PRELOAD_TIME 384 // usec. LomgPreamble + 24-byte at 1Mbps
+#define DEFAULT_DTIM_PERIOD 1
+
+// weighting factor to calculate Channel quality, total should be 100%
+//#define RSSI_WEIGHTING 0
+//#define TX_WEIGHTING 40
+//#define RX_WEIGHTING 60
+
+#define MAC_TABLE_AGEOUT_TIME 300 // unit: sec
+#define MAC_TABLE_ASSOC_TIMEOUT 5 // unit: sec
+#define MAC_TABLE_FULL(Tab) ((Tab).size == MAX_LEN_OF_MAC_TABLE)
+
+// AP shall drop the sta if contine Tx fail count reach it.
+#define MAC_ENTRY_LIFE_CHECK_CNT 20 // packet cnt.
+
+// Value domain of pMacEntry->Sst
+typedef enum _Sst {
+ SST_NOT_AUTH, // 0: equivalent to IEEE 802.11/1999 state 1
+ SST_AUTH, // 1: equivalent to IEEE 802.11/1999 state 2
+ SST_ASSOC // 2: equivalent to IEEE 802.11/1999 state 3
+} SST;
+
+// value domain of pMacEntry->AuthState
+typedef enum _AuthState {
+ AS_NOT_AUTH,
+ AS_AUTH_OPEN, // STA has been authenticated using OPEN SYSTEM
+ AS_AUTH_KEY, // STA has been authenticated using SHARED KEY
+ AS_AUTHENTICATING // STA is waiting for AUTH seq#3 using SHARED KEY
+} AUTH_STATE;
+
+//for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
+typedef enum _ApWpaState {
+ AS_NOTUSE, // 0
+ AS_DISCONNECT, // 1
+ AS_DISCONNECTED, // 2
+ AS_INITIALIZE, // 3
+ AS_AUTHENTICATION, // 4
+ AS_AUTHENTICATION2, // 5
+ AS_INITPMK, // 6
+ AS_INITPSK, // 7
+ AS_PTKSTART, // 8
+ AS_PTKINIT_NEGOTIATING, // 9
+ AS_PTKINITDONE, // 10
+ AS_UPDATEKEYS, // 11
+ AS_INTEGRITY_FAILURE, // 12
+ AS_KEYUPDATE, // 13
+} AP_WPA_STATE;
+
+// for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
+typedef enum _GTKState {
+ REKEY_NEGOTIATING,
+ REKEY_ESTABLISHED,
+ KEYERROR,
+} GTK_STATE;
+
+// for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
+typedef enum _WpaGTKState {
+ SETKEYS,
+ SETKEYS_DONE,
+} WPA_GTK_STATE;
+// ====================== end of AP mlme.h ============================
+
+
+#endif // MLME_H__
diff --git a/drivers/staging/rt3070/netif_block.h b/drivers/staging/rt3070/netif_block.h
new file mode 100644
index 00000000000..6e5151c4109
--- /dev/null
+++ b/drivers/staging/rt3070/netif_block.h
@@ -0,0 +1,58 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#ifndef __NET_IF_BLOCK_H__
+#define __NET_IF_BLOCK_H__
+
+//#include <linux/device.h>
+#include "link_list.h"
+#include "rtmp.h"
+
+#define FREE_NETIF_POOL_SIZE 32
+
+typedef struct _NETIF_ENTRY
+{
+ struct _NETIF_ENTRY *pNext;
+ PNET_DEV pNetDev;
+} NETIF_ENTRY, *PNETIF_ENTRY;
+
+void initblockQueueTab(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN blockNetIf(
+ IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
+ IN PNET_DEV pNetDev);
+
+VOID releaseNetIf(
+ IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry);
+
+VOID StopNetIfQueue(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket);
+#endif // __NET_IF_BLOCK_H__
+
diff --git a/drivers/staging/rt3070/oid.h b/drivers/staging/rt3070/oid.h
new file mode 100644
index 00000000000..f78bf0a5f14
--- /dev/null
+++ b/drivers/staging/rt3070/oid.h
@@ -0,0 +1,1142 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ oid.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+#ifndef _OID_H_
+#define _OID_H_
+
+//#include <linux/wireless.h>
+
+
+#define TRUE 1
+#define FALSE 0
+//
+// IEEE 802.11 Structures and definitions
+//
+#define MAX_TX_POWER_LEVEL 100 /* mW */
+#define MAX_RSSI_TRIGGER -10 /* dBm */
+#define MIN_RSSI_TRIGGER -200 /* dBm */
+#define MAX_FRAG_THRESHOLD 2346 /* byte count */
+#define MIN_FRAG_THRESHOLD 256 /* byte count */
+#define MAX_RTS_THRESHOLD 2347 /* byte count */
+
+// new types for Media Specific Indications
+// Extension channel offset
+#define EXTCHA_NONE 0
+#define EXTCHA_ABOVE 0x1
+#define EXTCHA_BELOW 0x3
+
+// BW
+#define BAND_WIDTH_20 0
+#define BAND_WIDTH_40 1
+#define BAND_WIDTH_BOTH 2
+#define BAND_WIDTH_10 3 // 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
+// SHORTGI
+#define GAP_INTERVAL_400 1 // only support in HT mode
+#define GAP_INTERVAL_800 0
+#define GAP_INTERVAL_BOTH 2
+
+#define NdisMediaStateConnected 1
+#define NdisMediaStateDisconnected 0
+
+#define NDIS_802_11_LENGTH_SSID 32
+#define NDIS_802_11_LENGTH_RATES 8
+#define NDIS_802_11_LENGTH_RATES_EX 16
+#define MAC_ADDR_LENGTH 6
+#define MAX_NUM_OF_CHS 49 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc
+#define MAX_NUMBER_OF_EVENT 10 // entry # in EVENT table
+#define MAX_NUMBER_OF_MAC 32 // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
+#define MAX_NUMBER_OF_ACL 64
+#define MAX_LENGTH_OF_SUPPORT_RATES 12 // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
+#define MAX_NUMBER_OF_DLS_ENTRY 4
+
+
+
+#ifndef UNDER_CE
+// OID definition, since NDIS 5.0 didn't define these, we need to define for our own
+//#if _WIN32_WINNT<=0x0500
+
+#define OID_GEN_MACHINE_NAME 0x0001021A
+
+#ifdef RALINK_ATE
+#define RT_QUERY_ATE_TXDONE_COUNT 0x0401
+#endif // RALINK_ATE //
+#define RT_QUERY_SIGNAL_CONTEXT 0x0402
+#define RT_SET_IAPP_PID 0x0404
+#define RT_SET_APD_PID 0x0405
+#define RT_SET_DEL_MAC_ENTRY 0x0406
+
+//
+// IEEE 802.11 OIDs
+//
+#define OID_GET_SET_TOGGLE 0x8000
+
+#define OID_802_11_NETWORK_TYPES_SUPPORTED 0x0103
+#define OID_802_11_NETWORK_TYPE_IN_USE 0x0104
+#define OID_802_11_RSSI_TRIGGER 0x0107
+#define RT_OID_802_11_RSSI 0x0108 //rt2860 only , kathy
+#define RT_OID_802_11_RSSI_1 0x0109 //rt2860 only , kathy
+#define RT_OID_802_11_RSSI_2 0x010A //rt2860 only , kathy
+#define OID_802_11_NUMBER_OF_ANTENNAS 0x010B
+#define OID_802_11_RX_ANTENNA_SELECTED 0x010C
+#define OID_802_11_TX_ANTENNA_SELECTED 0x010D
+#define OID_802_11_SUPPORTED_RATES 0x010E
+#define OID_802_11_ADD_WEP 0x0112
+#define OID_802_11_REMOVE_WEP 0x0113
+#define OID_802_11_DISASSOCIATE 0x0114
+#define OID_802_11_PRIVACY_FILTER 0x0118
+#define OID_802_11_ASSOCIATION_INFORMATION 0x011E
+#define OID_802_11_TEST 0x011F
+#define RT_OID_802_11_COUNTRY_REGION 0x0507
+#define OID_802_11_BSSID_LIST_SCAN 0x0508
+#define OID_802_11_SSID 0x0509
+#define OID_802_11_BSSID 0x050A
+#define RT_OID_802_11_RADIO 0x050B
+#define RT_OID_802_11_PHY_MODE 0x050C
+#define RT_OID_802_11_STA_CONFIG 0x050D
+#define OID_802_11_DESIRED_RATES 0x050E
+#define RT_OID_802_11_PREAMBLE 0x050F
+#define OID_802_11_WEP_STATUS 0x0510
+#define OID_802_11_AUTHENTICATION_MODE 0x0511
+#define OID_802_11_INFRASTRUCTURE_MODE 0x0512
+#define RT_OID_802_11_RESET_COUNTERS 0x0513
+#define OID_802_11_RTS_THRESHOLD 0x0514
+#define OID_802_11_FRAGMENTATION_THRESHOLD 0x0515
+#define OID_802_11_POWER_MODE 0x0516
+#define OID_802_11_TX_POWER_LEVEL 0x0517
+#define RT_OID_802_11_ADD_WPA 0x0518
+#define OID_802_11_REMOVE_KEY 0x0519
+#define OID_802_11_ADD_KEY 0x0520
+#define OID_802_11_CONFIGURATION 0x0521
+#define OID_802_11_TX_PACKET_BURST 0x0522
+#define RT_OID_802_11_QUERY_NOISE_LEVEL 0x0523
+#define RT_OID_802_11_EXTRA_INFO 0x0524
+#ifdef DBG
+#define RT_OID_802_11_HARDWARE_REGISTER 0x0525
+#endif
+#define OID_802_11_ENCRYPTION_STATUS OID_802_11_WEP_STATUS
+#define OID_802_11_DEAUTHENTICATION 0x0526
+#define OID_802_11_DROP_UNENCRYPTED 0x0527
+#define OID_802_11_MIC_FAILURE_REPORT_FRAME 0x0528
+
+// For 802.1x daemin using to require current driver configuration
+#define OID_802_11_RADIUS_QUERY_SETTING 0x0540
+
+#define RT_OID_DEVICE_NAME 0x0607
+#define RT_OID_VERSION_INFO 0x0608
+#define OID_802_11_BSSID_LIST 0x0609
+#define OID_802_3_CURRENT_ADDRESS 0x060A
+#define OID_GEN_MEDIA_CONNECT_STATUS 0x060B
+#define RT_OID_802_11_QUERY_LINK_STATUS 0x060C
+#define OID_802_11_RSSI 0x060D
+#define OID_802_11_STATISTICS 0x060E
+#define OID_GEN_RCV_OK 0x060F
+#define OID_GEN_RCV_NO_BUFFER 0x0610
+#define RT_OID_802_11_QUERY_EEPROM_VERSION 0x0611
+#define RT_OID_802_11_QUERY_FIRMWARE_VERSION 0x0612
+#define RT_OID_802_11_QUERY_LAST_RX_RATE 0x0613
+#define RT_OID_802_11_TX_POWER_LEVEL_1 0x0614
+#define RT_OID_802_11_QUERY_PIDVID 0x0615
+//for WPA_SUPPLICANT_SUPPORT
+#define OID_SET_COUNTERMEASURES 0x0616
+#define OID_802_11_SET_IEEE8021X 0x0617
+#define OID_802_11_SET_IEEE8021X_REQUIRE_KEY 0x0618
+#define OID_802_11_PMKID 0x0620
+#define RT_OID_WPA_SUPPLICANT_SUPPORT 0x0621
+#define RT_OID_WE_VERSION_COMPILED 0x0622
+#define RT_OID_NEW_DRIVER 0x0623
+
+
+//rt2860 , kathy
+#define RT_OID_802_11_SNR_0 0x0630
+#define RT_OID_802_11_SNR_1 0x0631
+#define RT_OID_802_11_QUERY_LAST_TX_RATE 0x0632
+#define RT_OID_802_11_QUERY_HT_PHYMODE 0x0633
+#define RT_OID_802_11_SET_HT_PHYMODE 0x0634
+#define OID_802_11_RELOAD_DEFAULTS 0x0635
+#define RT_OID_802_11_QUERY_APSD_SETTING 0x0636
+#define RT_OID_802_11_SET_APSD_SETTING 0x0637
+#define RT_OID_802_11_QUERY_APSD_PSM 0x0638
+#define RT_OID_802_11_SET_APSD_PSM 0x0639
+#define RT_OID_802_11_QUERY_DLS 0x063A
+#define RT_OID_802_11_SET_DLS 0x063B
+#define RT_OID_802_11_QUERY_DLS_PARAM 0x063C
+#define RT_OID_802_11_SET_DLS_PARAM 0x063D
+#define RT_OID_802_11_QUERY_WMM 0x063E
+#define RT_OID_802_11_SET_WMM 0x063F
+#define RT_OID_802_11_QUERY_IMME_BA_CAP 0x0640
+#define RT_OID_802_11_SET_IMME_BA_CAP 0x0641
+#define RT_OID_802_11_QUERY_BATABLE 0x0642
+#define RT_OID_802_11_ADD_IMME_BA 0x0643
+#define RT_OID_802_11_TEAR_IMME_BA 0x0644
+#define RT_OID_DRIVER_DEVICE_NAME 0x0645
+#define RT_OID_802_11_QUERY_DAT_HT_PHYMODE 0x0646
+#define RT_OID_QUERY_MULTIPLE_CARD_SUPPORT 0x0647
+
+// Ralink defined OIDs
+// Dennis Lee move to platform specific
+
+#define RT_OID_802_11_BSSID (OID_GET_SET_TOGGLE | OID_802_11_BSSID)
+#define RT_OID_802_11_SSID (OID_GET_SET_TOGGLE | OID_802_11_SSID)
+#define RT_OID_802_11_INFRASTRUCTURE_MODE (OID_GET_SET_TOGGLE | OID_802_11_INFRASTRUCTURE_MODE)
+#define RT_OID_802_11_ADD_WEP (OID_GET_SET_TOGGLE | OID_802_11_ADD_WEP)
+#define RT_OID_802_11_ADD_KEY (OID_GET_SET_TOGGLE | OID_802_11_ADD_KEY)
+#define RT_OID_802_11_REMOVE_WEP (OID_GET_SET_TOGGLE | OID_802_11_REMOVE_WEP)
+#define RT_OID_802_11_REMOVE_KEY (OID_GET_SET_TOGGLE | OID_802_11_REMOVE_KEY)
+#define RT_OID_802_11_DISASSOCIATE (OID_GET_SET_TOGGLE | OID_802_11_DISASSOCIATE)
+#define RT_OID_802_11_AUTHENTICATION_MODE (OID_GET_SET_TOGGLE | OID_802_11_AUTHENTICATION_MODE)
+#define RT_OID_802_11_PRIVACY_FILTER (OID_GET_SET_TOGGLE | OID_802_11_PRIVACY_FILTER)
+#define RT_OID_802_11_BSSID_LIST_SCAN (OID_GET_SET_TOGGLE | OID_802_11_BSSID_LIST_SCAN)
+#define RT_OID_802_11_WEP_STATUS (OID_GET_SET_TOGGLE | OID_802_11_WEP_STATUS)
+#define RT_OID_802_11_RELOAD_DEFAULTS (OID_GET_SET_TOGGLE | OID_802_11_RELOAD_DEFAULTS)
+#define RT_OID_802_11_NETWORK_TYPE_IN_USE (OID_GET_SET_TOGGLE | OID_802_11_NETWORK_TYPE_IN_USE)
+#define RT_OID_802_11_TX_POWER_LEVEL (OID_GET_SET_TOGGLE | OID_802_11_TX_POWER_LEVEL)
+#define RT_OID_802_11_RSSI_TRIGGER (OID_GET_SET_TOGGLE | OID_802_11_RSSI_TRIGGER)
+#define RT_OID_802_11_FRAGMENTATION_THRESHOLD (OID_GET_SET_TOGGLE | OID_802_11_FRAGMENTATION_THRESHOLD)
+#define RT_OID_802_11_RTS_THRESHOLD (OID_GET_SET_TOGGLE | OID_802_11_RTS_THRESHOLD)
+#define RT_OID_802_11_RX_ANTENNA_SELECTED (OID_GET_SET_TOGGLE | OID_802_11_RX_ANTENNA_SELECTED)
+#define RT_OID_802_11_TX_ANTENNA_SELECTED (OID_GET_SET_TOGGLE | OID_802_11_TX_ANTENNA_SELECTED)
+#define RT_OID_802_11_SUPPORTED_RATES (OID_GET_SET_TOGGLE | OID_802_11_SUPPORTED_RATES)
+#define RT_OID_802_11_DESIRED_RATES (OID_GET_SET_TOGGLE | OID_802_11_DESIRED_RATES)
+#define RT_OID_802_11_CONFIGURATION (OID_GET_SET_TOGGLE | OID_802_11_CONFIGURATION)
+#define RT_OID_802_11_POWER_MODE (OID_GET_SET_TOGGLE | OID_802_11_POWER_MODE)
+
+
+
+typedef enum _NDIS_802_11_STATUS_TYPE
+{
+ Ndis802_11StatusType_Authentication,
+ Ndis802_11StatusType_MediaStreamMode,
+ Ndis802_11StatusType_PMKID_CandidateList,
+ Ndis802_11StatusTypeMax // not a real type, defined as an upper bound
+} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE;
+
+typedef UCHAR NDIS_802_11_MAC_ADDRESS[6];
+
+typedef struct _NDIS_802_11_STATUS_INDICATION
+{
+ NDIS_802_11_STATUS_TYPE StatusType;
+} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION;
+
+// mask for authentication/integrity fields
+#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f
+
+#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01
+#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02
+#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06
+#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E
+
+typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST
+{
+ ULONG Length; // Length of structure
+ NDIS_802_11_MAC_ADDRESS Bssid;
+ ULONG Flags;
+} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST;
+
+//Added new types for PMKID Candidate lists.
+typedef struct _PMKID_CANDIDATE {
+ NDIS_802_11_MAC_ADDRESS BSSID;
+ ULONG Flags;
+} PMKID_CANDIDATE, *PPMKID_CANDIDATE;
+
+typedef struct _NDIS_802_11_PMKID_CANDIDATE_LIST
+{
+ ULONG Version; // Version of the structure
+ ULONG NumCandidates; // No. of pmkid candidates
+ PMKID_CANDIDATE CandidateList[1];
+} NDIS_802_11_PMKID_CANDIDATE_LIST, *PNDIS_802_11_PMKID_CANDIDATE_LIST;
+
+//Flags for PMKID Candidate list structure
+#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01
+
+// Added new types for OFDM 5G and 2.4G
+typedef enum _NDIS_802_11_NETWORK_TYPE
+{
+ Ndis802_11FH,
+ Ndis802_11DS,
+ Ndis802_11OFDM5,
+ Ndis802_11OFDM5_N,
+ Ndis802_11OFDM24,
+ Ndis802_11OFDM24_N,
+ Ndis802_11Automode,
+ Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound
+} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE;
+
+typedef struct _NDIS_802_11_NETWORK_TYPE_LIST
+{
+ UINT NumberOfItems; // in list below, at least 1
+ NDIS_802_11_NETWORK_TYPE NetworkType [1];
+} NDIS_802_11_NETWORK_TYPE_LIST, *PNDIS_802_11_NETWORK_TYPE_LIST;
+
+typedef enum _NDIS_802_11_POWER_MODE
+{
+ Ndis802_11PowerModeCAM,
+ Ndis802_11PowerModeMAX_PSP,
+ Ndis802_11PowerModeFast_PSP,
+ Ndis802_11PowerModeLegacy_PSP,
+ Ndis802_11PowerModeMax // not a real mode, defined as an upper bound
+} NDIS_802_11_POWER_MODE, *PNDIS_802_11_POWER_MODE;
+
+typedef ULONG NDIS_802_11_TX_POWER_LEVEL; // in milliwatts
+
+//
+// Received Signal Strength Indication
+//
+typedef LONG NDIS_802_11_RSSI; // in dBm
+
+typedef struct _NDIS_802_11_CONFIGURATION_FH
+{
+ ULONG Length; // Length of structure
+ ULONG HopPattern; // As defined by 802.11, MSB set
+ ULONG HopSet; // to one if non-802.11
+ ULONG DwellTime; // units are Kusec
+} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH;
+
+typedef struct _NDIS_802_11_CONFIGURATION
+{
+ ULONG Length; // Length of structure
+ ULONG BeaconPeriod; // units are Kusec
+ ULONG ATIMWindow; // units are Kusec
+ ULONG DSConfig; // Frequency, units are kHz
+ NDIS_802_11_CONFIGURATION_FH FHConfig;
+} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION;
+
+typedef struct _NDIS_802_11_STATISTICS
+{
+ ULONG Length; // Length of structure
+ LARGE_INTEGER TransmittedFragmentCount;
+ LARGE_INTEGER MulticastTransmittedFrameCount;
+ LARGE_INTEGER FailedCount;
+ LARGE_INTEGER RetryCount;
+ LARGE_INTEGER MultipleRetryCount;
+ LARGE_INTEGER RTSSuccessCount;
+ LARGE_INTEGER RTSFailureCount;
+ LARGE_INTEGER ACKFailureCount;
+ LARGE_INTEGER FrameDuplicateCount;
+ LARGE_INTEGER ReceivedFragmentCount;
+ LARGE_INTEGER MulticastReceivedFrameCount;
+ LARGE_INTEGER FCSErrorCount;
+ LARGE_INTEGER TKIPLocalMICFailures;
+ LARGE_INTEGER TKIPRemoteMICErrors;
+ LARGE_INTEGER TKIPICVErrors;
+ LARGE_INTEGER TKIPCounterMeasuresInvoked;
+ LARGE_INTEGER TKIPReplays;
+ LARGE_INTEGER CCMPFormatErrors;
+ LARGE_INTEGER CCMPReplays;
+ LARGE_INTEGER CCMPDecryptErrors;
+ LARGE_INTEGER FourWayHandshakeFailures;
+} NDIS_802_11_STATISTICS, *PNDIS_802_11_STATISTICS;
+
+typedef ULONG NDIS_802_11_KEY_INDEX;
+typedef ULONGLONG NDIS_802_11_KEY_RSC;
+
+#define MAX_RADIUS_SRV_NUM 2 // 802.1x failover number
+
+typedef struct PACKED _RADIUS_SRV_INFO {
+ UINT32 radius_ip;
+ UINT32 radius_port;
+ UCHAR radius_key[64];
+ UCHAR radius_key_len;
+} RADIUS_SRV_INFO, *PRADIUS_SRV_INFO;
+
+typedef struct PACKED _RADIUS_KEY_INFO
+{
+ UCHAR radius_srv_num;
+ RADIUS_SRV_INFO radius_srv_info[MAX_RADIUS_SRV_NUM];
+ UCHAR ieee8021xWEP; // dynamic WEP
+ UCHAR key_index;
+ UCHAR key_length; // length of key in bytes
+ UCHAR key_material[13];
+} RADIUS_KEY_INFO, *PRADIUS_KEY_INFO;
+
+// It's used by 802.1x daemon to require relative configuration
+typedef struct PACKED _RADIUS_CONF
+{
+ UINT32 Length; // Length of this structure
+ UCHAR mbss_num; // indicate multiple BSS number
+ UINT32 own_ip_addr;
+ UINT32 retry_interval;
+ UINT32 session_timeout_interval;
+ UCHAR EAPifname[IFNAMSIZ];
+ UCHAR EAPifname_len;
+ UCHAR PreAuthifname[IFNAMSIZ];
+ UCHAR PreAuthifname_len;
+ RADIUS_KEY_INFO RadiusInfo[8/*MAX_MBSSID_NUM*/];
+} RADIUS_CONF, *PRADIUS_CONF;
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+// Key mapping keys require a BSSID
+typedef struct _NDIS_802_11_KEY
+{
+ UINT Length; // Length of this structure
+ UINT KeyIndex;
+ UINT KeyLength; // length of key in bytes
+ NDIS_802_11_MAC_ADDRESS BSSID;
+ NDIS_802_11_KEY_RSC KeyRSC;
+ UCHAR KeyMaterial[1]; // variable length depending on above field
+} NDIS_802_11_KEY, *PNDIS_802_11_KEY;
+#endif // CONFIG_STA_SUPPORT //
+
+typedef struct _NDIS_802_11_REMOVE_KEY
+{
+ UINT Length; // Length of this structure
+ UINT KeyIndex;
+ NDIS_802_11_MAC_ADDRESS BSSID;
+} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY;
+
+typedef struct _NDIS_802_11_WEP
+{
+ UINT Length; // Length of this structure
+ UINT KeyIndex; // 0 is the per-client key, 1-N are the
+ // global keys
+ UINT KeyLength; // length of key in bytes
+ UCHAR KeyMaterial[1];// variable length depending on above field
+} NDIS_802_11_WEP, *PNDIS_802_11_WEP;
+
+
+typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE
+{
+ Ndis802_11IBSS,
+ Ndis802_11Infrastructure,
+ Ndis802_11AutoUnknown,
+ Ndis802_11Monitor,
+ Ndis802_11InfrastructureMax // Not a real value, defined as upper bound
+} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE;
+
+// Add new authentication modes
+typedef enum _NDIS_802_11_AUTHENTICATION_MODE
+{
+ Ndis802_11AuthModeOpen,
+ Ndis802_11AuthModeShared,
+ Ndis802_11AuthModeAutoSwitch,
+ Ndis802_11AuthModeWPA,
+ Ndis802_11AuthModeWPAPSK,
+ Ndis802_11AuthModeWPANone,
+ Ndis802_11AuthModeWPA2,
+ Ndis802_11AuthModeWPA2PSK,
+ Ndis802_11AuthModeWPA1WPA2,
+ Ndis802_11AuthModeWPA1PSKWPA2PSK,
+ Ndis802_11AuthModeMax // Not a real mode, defined as upper bound
+} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE;
+
+typedef UCHAR NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; // Set of 8 data rates
+typedef UCHAR NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; // Set of 16 data rates
+
+typedef struct PACKED _NDIS_802_11_SSID
+{
+ UINT SsidLength; // length of SSID field below, in bytes;
+ // this can be zero.
+ UCHAR Ssid[NDIS_802_11_LENGTH_SSID]; // SSID information field
+} NDIS_802_11_SSID, *PNDIS_802_11_SSID;
+
+
+typedef struct PACKED _NDIS_WLAN_BSSID
+{
+ ULONG Length; // Length of this structure
+ NDIS_802_11_MAC_ADDRESS MacAddress; // BSSID
+ UCHAR Reserved[2];
+ NDIS_802_11_SSID Ssid; // SSID
+ ULONG Privacy; // WEP encryption requirement
+ NDIS_802_11_RSSI Rssi; // receive signal strength in dBm
+ NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
+ NDIS_802_11_CONFIGURATION Configuration;
+ NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
+ NDIS_802_11_RATES SupportedRates;
+} NDIS_WLAN_BSSID, *PNDIS_WLAN_BSSID;
+
+typedef struct PACKED _NDIS_802_11_BSSID_LIST
+{
+ UINT NumberOfItems; // in list below, at least 1
+ NDIS_WLAN_BSSID Bssid[1];
+} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST;
+
+// Added Capabilities, IELength and IEs for each BSSID
+typedef struct PACKED _NDIS_WLAN_BSSID_EX
+{
+ ULONG Length; // Length of this structure
+ NDIS_802_11_MAC_ADDRESS MacAddress; // BSSID
+ UCHAR Reserved[2];
+ NDIS_802_11_SSID Ssid; // SSID
+ UINT Privacy; // WEP encryption requirement
+ NDIS_802_11_RSSI Rssi; // receive signal
+ // strength in dBm
+ NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
+ NDIS_802_11_CONFIGURATION Configuration;
+ NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
+ NDIS_802_11_RATES_EX SupportedRates;
+ ULONG IELength;
+ UCHAR IEs[1];
+} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX;
+
+typedef struct PACKED _NDIS_802_11_BSSID_LIST_EX
+{
+ UINT NumberOfItems; // in list below, at least 1
+ NDIS_WLAN_BSSID_EX Bssid[1];
+} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX;
+
+typedef struct PACKED _NDIS_802_11_FIXED_IEs
+{
+ UCHAR Timestamp[8];
+ USHORT BeaconInterval;
+ USHORT Capabilities;
+} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs;
+
+typedef struct _NDIS_802_11_VARIABLE_IEs
+{
+ UCHAR ElementID;
+ UCHAR Length; // Number of bytes in data field
+ UCHAR data[1];
+} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs;
+
+typedef ULONG NDIS_802_11_FRAGMENTATION_THRESHOLD;
+
+typedef ULONG NDIS_802_11_RTS_THRESHOLD;
+
+typedef ULONG NDIS_802_11_ANTENNA;
+
+typedef enum _NDIS_802_11_PRIVACY_FILTER
+{
+ Ndis802_11PrivFilterAcceptAll,
+ Ndis802_11PrivFilter8021xWEP
+} NDIS_802_11_PRIVACY_FILTER, *PNDIS_802_11_PRIVACY_FILTER;
+
+// Added new encryption types
+// Also aliased typedef to new name
+typedef enum _NDIS_802_11_WEP_STATUS
+{
+ Ndis802_11WEPEnabled,
+ Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
+ Ndis802_11WEPDisabled,
+ Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
+ Ndis802_11WEPKeyAbsent,
+ Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
+ Ndis802_11WEPNotSupported,
+ Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
+ Ndis802_11Encryption2Enabled,
+ Ndis802_11Encryption2KeyAbsent,
+ Ndis802_11Encryption3Enabled,
+ Ndis802_11Encryption3KeyAbsent,
+ Ndis802_11Encryption4Enabled, // TKIP or AES mix
+ Ndis802_11Encryption4KeyAbsent,
+} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
+ NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
+
+typedef enum _NDIS_802_11_RELOAD_DEFAULTS
+{
+ Ndis802_11ReloadWEPKeys
+} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS;
+
+#define NDIS_802_11_AI_REQFI_CAPABILITIES 1
+#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2
+#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4
+
+#define NDIS_802_11_AI_RESFI_CAPABILITIES 1
+#define NDIS_802_11_AI_RESFI_STATUSCODE 2
+#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4
+
+typedef struct _NDIS_802_11_AI_REQFI
+{
+ USHORT Capabilities;
+ USHORT ListenInterval;
+ NDIS_802_11_MAC_ADDRESS CurrentAPAddress;
+} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
+
+typedef struct _NDIS_802_11_AI_RESFI
+{
+ USHORT Capabilities;
+ USHORT StatusCode;
+ USHORT AssociationId;
+} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
+
+typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
+{
+ ULONG Length;
+ USHORT AvailableRequestFixedIEs;
+ NDIS_802_11_AI_REQFI RequestFixedIEs;
+ ULONG RequestIELength;
+ ULONG OffsetRequestIEs;
+ USHORT AvailableResponseFixedIEs;
+ NDIS_802_11_AI_RESFI ResponseFixedIEs;
+ ULONG ResponseIELength;
+ ULONG OffsetResponseIEs;
+} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION;
+
+typedef struct _NDIS_802_11_AUTHENTICATION_EVENT
+{
+ NDIS_802_11_STATUS_INDICATION Status;
+ NDIS_802_11_AUTHENTICATION_REQUEST Request[1];
+} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT;
+
+/*
+typedef struct _NDIS_802_11_TEST
+{
+ ULONG Length;
+ ULONG Type;
+ union
+ {
+ NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent;
+ NDIS_802_11_RSSI RssiTrigger;
+ };
+} NDIS_802_11_TEST, *PNDIS_802_11_TEST;
+ */
+
+// 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE
+typedef enum _NDIS_802_11_MEDIA_STREAM_MODE
+{
+ Ndis802_11MediaStreamOff,
+ Ndis802_11MediaStreamOn,
+} NDIS_802_11_MEDIA_STREAM_MODE, *PNDIS_802_11_MEDIA_STREAM_MODE;
+
+// PMKID Structures
+typedef UCHAR NDIS_802_11_PMKID_VALUE[16];
+
+#ifdef CONFIG_STA_SUPPORT
+typedef struct _BSSID_INFO
+{
+ NDIS_802_11_MAC_ADDRESS BSSID;
+ NDIS_802_11_PMKID_VALUE PMKID;
+} BSSID_INFO, *PBSSID_INFO;
+
+typedef struct _NDIS_802_11_PMKID
+{
+ UINT Length;
+ UINT BSSIDInfoCount;
+ BSSID_INFO BSSIDInfo[1];
+} NDIS_802_11_PMKID, *PNDIS_802_11_PMKID;
+#endif // CONFIG_STA_SUPPORT //
+
+
+typedef struct _NDIS_802_11_AUTHENTICATION_ENCRYPTION
+{
+ NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported;
+ NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported;
+} NDIS_802_11_AUTHENTICATION_ENCRYPTION, *PNDIS_802_11_AUTHENTICATION_ENCRYPTION;
+
+typedef struct _NDIS_802_11_CAPABILITY
+{
+ ULONG Length;
+ ULONG Version;
+ ULONG NoOfPMKIDs;
+ ULONG NoOfAuthEncryptPairsSupported;
+ NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1];
+} NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY;
+
+//#endif //of WIN 2k
+#endif //UNDER_CE
+
+#if WIRELESS_EXT <= 11
+#ifndef SIOCDEVPRIVATE
+#define SIOCDEVPRIVATE 0x8BE0
+#endif
+#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
+#endif
+
+#ifdef CONFIG_STA_SUPPORT
+#define RT_PRIV_IOCTL_EXT (SIOCIWFIRSTPRIV + 0x01) // Sync. with AP for wsc upnp daemon
+#define RTPRIV_IOCTL_SET (SIOCIWFIRSTPRIV + 0x02)
+
+#ifdef DBG
+#define RTPRIV_IOCTL_BBP (SIOCIWFIRSTPRIV + 0x03)
+#define RTPRIV_IOCTL_MAC (SIOCIWFIRSTPRIV + 0x05)
+#define RTPRIV_IOCTL_RF (SIOCIWFIRSTPRIV + 0x13)
+#define RTPRIV_IOCTL_E2P (SIOCIWFIRSTPRIV + 0x07)
+#endif
+
+#ifdef RALINK_ATE
+#ifdef RALINK_28xx_QA
+#define RTPRIV_IOCTL_ATE (SIOCIWFIRSTPRIV + 0x08)
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+#define RTPRIV_IOCTL_STATISTICS (SIOCIWFIRSTPRIV + 0x09)
+#define RTPRIV_IOCTL_ADD_PMKID_CACHE (SIOCIWFIRSTPRIV + 0x0A)
+#define RTPRIV_IOCTL_RADIUS_DATA (SIOCIWFIRSTPRIV + 0x0C)
+#define RTPRIV_IOCTL_GSITESURVEY (SIOCIWFIRSTPRIV + 0x0D)
+#define RT_PRIV_IOCTL (SIOCIWFIRSTPRIV + 0x0E) // Sync. with RT61 (for wpa_supplicant)
+#define RTPRIV_IOCTL_GET_MAC_TABLE (SIOCIWFIRSTPRIV + 0x0F)
+
+#define RTPRIV_IOCTL_SHOW (SIOCIWFIRSTPRIV + 0x11)
+enum {
+ SHOW_CONN_STATUS = 4,
+ SHOW_DRVIER_VERION = 5,
+ SHOW_BA_INFO = 6,
+ SHOW_DESC_INFO = 7,
+#ifdef RT2870
+ SHOW_RXBULK_INFO = 8,
+ SHOW_TXBULK_INFO = 9,
+#endif // RT2870 //
+ RAIO_OFF = 10,
+ RAIO_ON = 11,
+#ifdef QOS_DLS_SUPPORT
+ SHOW_DLS_ENTRY_INFO = 19,
+#endif // QOS_DLS_SUPPORT //
+ SHOW_CFG_VALUE = 20,
+};
+
+
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+#ifdef SNMP_SUPPORT
+//SNMP ieee 802dot11, kathy , 2008_0220
+// dot11res(3)
+#define RT_OID_802_11_MANUFACTUREROUI 0x0700
+#define RT_OID_802_11_MANUFACTURERNAME 0x0701
+#define RT_OID_802_11_RESOURCETYPEIDNAME 0x0702
+
+// dot11smt(1)
+#define RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED 0x0703
+#define RT_OID_802_11_POWERMANAGEMENTMODE 0x0704
+#define OID_802_11_WEPDEFAULTKEYVALUE 0x0705 // read , write
+#define OID_802_11_WEPDEFAULTKEYID 0x0706
+#define RT_OID_802_11_WEPKEYMAPPINGLENGTH 0x0707
+#define OID_802_11_SHORTRETRYLIMIT 0x0708
+#define OID_802_11_LONGRETRYLIMIT 0x0709
+#define RT_OID_802_11_PRODUCTID 0x0710
+#define RT_OID_802_11_MANUFACTUREID 0x0711
+
+// //dot11Phy(4)
+#define OID_802_11_CURRENTCHANNEL 0x0712
+
+//dot11mac
+#define RT_OID_802_11_MAC_ADDRESS 0x0713
+#endif // SNMP_SUPPORT //
+
+#define OID_802_11_BUILD_CHANNEL_EX 0x0714
+#define OID_802_11_GET_CH_LIST 0x0715
+#define OID_802_11_GET_COUNTRY_CODE 0x0716
+#define OID_802_11_GET_CHANNEL_GEOGRAPHY 0x0717
+
+//#define RT_OID_802_11_STATISTICS (OID_GET_SET_TOGGLE | OID_802_11_STATISTICS)
+
+#ifdef CONFIG_STA_SUPPORT
+#define RT_OID_WSC_SET_PASSPHRASE 0x0740 // passphrase for wpa(2)-psk
+#define RT_OID_WSC_DRIVER_AUTO_CONNECT 0x0741
+#define RT_OID_WSC_QUERY_DEFAULT_PROFILE 0x0742
+#define RT_OID_WSC_SET_CONN_BY_PROFILE_INDEX 0x0743
+#define RT_OID_WSC_SET_ACTION 0x0744
+#define RT_OID_WSC_SET_SSID 0x0745
+#define RT_OID_WSC_SET_PIN_CODE 0x0746
+#define RT_OID_WSC_SET_MODE 0x0747 // PIN or PBC
+#define RT_OID_WSC_SET_CONF_MODE 0x0748 // Enrollee or Registrar
+#define RT_OID_WSC_SET_PROFILE 0x0749
+#endif // CONFIG_STA_SUPPORT //
+#define RT_OID_802_11_WSC_QUERY_PROFILE 0x0750
+// for consistency with RT61
+#define RT_OID_WSC_QUERY_STATUS 0x0751
+#define RT_OID_WSC_PIN_CODE 0x0752
+#define RT_OID_WSC_UUID 0x0753
+#define RT_OID_WSC_SET_SELECTED_REGISTRAR 0x0754
+#define RT_OID_WSC_EAPMSG 0x0755
+#define RT_OID_WSC_MANUFACTURER 0x0756
+#define RT_OID_WSC_MODEL_NAME 0x0757
+#define RT_OID_WSC_MODEL_NO 0x0758
+#define RT_OID_WSC_SERIAL_NO 0x0759
+#define RT_OID_WSC_MAC_ADDRESS 0x0760
+
+#ifdef LLTD_SUPPORT
+// for consistency with RT61
+#define RT_OID_GET_PHY_MODE 0x761
+#endif // LLTD_SUPPORT //
+
+#ifdef NINTENDO_AP
+//#define RT_OID_NINTENDO 0x0D010770
+#define RT_OID_802_11_NINTENDO_GET_TABLE 0x0771 //((RT_OID_NINTENDO + 0x01) & 0xffff)
+#define RT_OID_802_11_NINTENDO_SET_TABLE 0x0772 //((RT_OID_NINTENDO + 0x02) & 0xffff)
+#define RT_OID_802_11_NINTENDO_CAPABLE 0x0773 //((RT_OID_NINTENDO + 0x03) & 0xffff)
+#endif // NINTENDO_AP //
+
+//Add Paul Chen for Accton
+//#define RT_OID_TX_POWER_LEVEL 0xFF020010
+//#define RT_OID_SET_TX_POWER_LEVEL (OID_GET_SET_TOGGLE | RT_OID_TX_POWER_LEVEL)
+
+// New for MeetingHouse Api support
+#define OID_MH_802_1X_SUPPORTED 0xFFEDC100
+
+// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition!!!
+typedef union _HTTRANSMIT_SETTING {
+#ifdef RT_BIG_ENDIAN
+ struct {
+ USHORT MODE:2; // Use definition MODE_xxx.
+// USHORT rsv:3;
+ USHORT TxBF:1;
+ USHORT rsv:2;
+ USHORT STBC:2; //SPACE
+ USHORT ShortGI:1;
+ USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
+ USHORT MCS:7; // MCS
+ } field;
+#else
+ struct {
+ USHORT MCS:7; // MCS
+ USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
+ USHORT ShortGI:1;
+ USHORT STBC:2; //SPACE
+// USHORT rsv:3;
+ USHORT rsv:2;
+ USHORT TxBF:1;
+ USHORT MODE:2; // Use definition MODE_xxx.
+ } field;
+#endif
+ USHORT word;
+ } HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING;
+
+typedef enum _RT_802_11_PREAMBLE {
+ Rt802_11PreambleLong,
+ Rt802_11PreambleShort,
+ Rt802_11PreambleAuto
+} RT_802_11_PREAMBLE, *PRT_802_11_PREAMBLE;
+
+// Only for STA, need to sync with AP
+// 2005-03-08 match current RaConfig.
+typedef enum _RT_802_11_PHY_MODE {
+ PHY_11BG_MIXED = 0,
+ PHY_11B,
+ PHY_11A,
+ PHY_11ABG_MIXED,
+ PHY_11G,
+#ifdef DOT11_N_SUPPORT
+ PHY_11ABGN_MIXED, // both band 5
+ PHY_11N_2_4G, // 11n-only with 2.4G band 6
+ PHY_11GN_MIXED, // 2.4G band 7
+ PHY_11AN_MIXED, // 5G band 8
+ PHY_11BGN_MIXED, // if check 802.11b. 9
+ PHY_11AGN_MIXED, // if check 802.11b. 10
+ PHY_11N_5G, // 11n-only with 5G band 11
+#endif // DOT11_N_SUPPORT //
+} RT_802_11_PHY_MODE;
+
+// put all proprietery for-query objects here to reduce # of Query_OID
+typedef struct _RT_802_11_LINK_STATUS {
+ ULONG CurrTxRate; // in units of 0.5Mbps
+ ULONG ChannelQuality; // 0..100 %
+ ULONG TxByteCount; // both ok and fail
+ ULONG RxByteCount; // both ok and fail
+ ULONG CentralChannel; // 40MHz central channel number
+} RT_802_11_LINK_STATUS, *PRT_802_11_LINK_STATUS;
+
+typedef struct _RT_802_11_EVENT_LOG {
+ LARGE_INTEGER SystemTime; // timestammp via NdisGetCurrentSystemTime()
+ UCHAR Addr[MAC_ADDR_LENGTH];
+ USHORT Event; // EVENT_xxx
+} RT_802_11_EVENT_LOG, *PRT_802_11_EVENT_LOG;
+
+typedef struct _RT_802_11_EVENT_TABLE {
+ ULONG Num;
+ ULONG Rsv; // to align Log[] at LARGE_INEGER boundary
+ RT_802_11_EVENT_LOG Log[MAX_NUMBER_OF_EVENT];
+} RT_802_11_EVENT_TABLE, PRT_802_11_EVENT_TABLE;
+
+// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition!!!
+typedef union _MACHTTRANSMIT_SETTING {
+ struct {
+ USHORT MCS:7; // MCS
+ USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
+ USHORT ShortGI:1;
+ USHORT STBC:2; //SPACE
+ USHORT rsv:3;
+ USHORT MODE:2; // Use definition MODE_xxx.
+ } field;
+ USHORT word;
+ } MACHTTRANSMIT_SETTING, *PMACHTTRANSMIT_SETTING;
+
+typedef struct _RT_802_11_MAC_ENTRY {
+ UCHAR Addr[MAC_ADDR_LENGTH];
+ UCHAR Aid;
+ UCHAR Psm; // 0:PWR_ACTIVE, 1:PWR_SAVE
+ UCHAR MimoPs; // 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled
+ CHAR AvgRssi0;
+ CHAR AvgRssi1;
+ CHAR AvgRssi2;
+ UINT32 ConnectedTime;
+ MACHTTRANSMIT_SETTING TxRate;
+} RT_802_11_MAC_ENTRY, *PRT_802_11_MAC_ENTRY;
+
+typedef struct _RT_802_11_MAC_TABLE {
+ ULONG Num;
+ RT_802_11_MAC_ENTRY Entry[MAX_NUMBER_OF_MAC];
+} RT_802_11_MAC_TABLE, *PRT_802_11_MAC_TABLE;
+
+// structure for query/set hardware register - MAC, BBP, RF register
+typedef struct _RT_802_11_HARDWARE_REGISTER {
+ ULONG HardwareType; // 0:MAC, 1:BBP, 2:RF register, 3:EEPROM
+ ULONG Offset; // Q/S register offset addr
+ ULONG Data; // R/W data buffer
+} RT_802_11_HARDWARE_REGISTER, *PRT_802_11_HARDWARE_REGISTER;
+
+// structure to tune BBP R17 "RX AGC VGC init"
+//typedef struct _RT_802_11_RX_AGC_VGC_TUNING {
+// UCHAR FalseCcaLowerThreshold; // 0-255, def 10
+// UCHAR FalseCcaUpperThreshold; // 0-255, def 100
+// UCHAR VgcDelta; // R17 +-= VgcDelta whenever flase CCA over UpprThreshold
+// // or lower than LowerThresholdupper threshold
+// UCHAR VgcUpperBound; // max value of R17
+//} RT_802_11_RX_AGC_VGC_TUNING, *PRT_802_11_RX_AGC_VGC_TUNING;
+
+typedef struct _RT_802_11_AP_CONFIG {
+ ULONG EnableTxBurst; // 0-disable, 1-enable
+ ULONG EnableTurboRate; // 0-disable, 1-enable 72/100mbps turbo rate
+ ULONG IsolateInterStaTraffic; // 0-disable, 1-enable isolation
+ ULONG HideSsid; // 0-disable, 1-enable hiding
+ ULONG UseBGProtection; // 0-AUTO, 1-always ON, 2-always OFF
+ ULONG UseShortSlotTime; // 0-no use, 1-use 9-us short slot time
+ ULONG Rsv1; // must be 0
+ ULONG SystemErrorBitmap; // ignore upon SET, return system error upon QUERY
+} RT_802_11_AP_CONFIG, *PRT_802_11_AP_CONFIG;
+
+// structure to query/set STA_CONFIG
+typedef struct _RT_802_11_STA_CONFIG {
+ ULONG EnableTxBurst; // 0-disable, 1-enable
+ ULONG EnableTurboRate; // 0-disable, 1-enable 72/100mbps turbo rate
+ ULONG UseBGProtection; // 0-AUTO, 1-always ON, 2-always OFF
+ ULONG UseShortSlotTime; // 0-no use, 1-use 9-us short slot time when applicable
+ ULONG AdhocMode; // 0-11b rates only (WIFI spec), 1 - b/g mixed, 2 - g only
+ ULONG HwRadioStatus; // 0-OFF, 1-ON, default is 1, Read-Only
+ ULONG Rsv1; // must be 0
+ ULONG SystemErrorBitmap; // ignore upon SET, return system error upon QUERY
+} RT_802_11_STA_CONFIG, *PRT_802_11_STA_CONFIG;
+
+//
+// For OID Query or Set about BA structure
+//
+typedef struct _OID_BACAP_STRUC {
+ UCHAR RxBAWinLimit;
+ UCHAR TxBAWinLimit;
+ UCHAR Policy; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid
+ UCHAR MpduDensity; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid
+ UCHAR AmsduEnable; //Enable AMSDU transmisstion
+ UCHAR AmsduSize; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
+ UCHAR MMPSmode; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
+ BOOLEAN AutoBA; // Auto BA will automatically
+} OID_BACAP_STRUC, *POID_BACAP_STRUC;
+
+typedef struct _RT_802_11_ACL_ENTRY {
+ UCHAR Addr[MAC_ADDR_LENGTH];
+ USHORT Rsv;
+} RT_802_11_ACL_ENTRY, *PRT_802_11_ACL_ENTRY;
+
+typedef struct PACKED _RT_802_11_ACL {
+ ULONG Policy; // 0-disable, 1-positive list, 2-negative list
+ ULONG Num;
+ RT_802_11_ACL_ENTRY Entry[MAX_NUMBER_OF_ACL];
+} RT_802_11_ACL, *PRT_802_11_ACL;
+
+typedef struct _RT_802_11_WDS {
+ ULONG Num;
+ NDIS_802_11_MAC_ADDRESS Entry[24/*MAX_NUM_OF_WDS_LINK*/];
+ ULONG KeyLength;
+ UCHAR KeyMaterial[32];
+} RT_802_11_WDS, *PRT_802_11_WDS;
+
+typedef struct _RT_802_11_TX_RATES_ {
+ UCHAR SupRateLen;
+ UCHAR SupRate[MAX_LENGTH_OF_SUPPORT_RATES];
+ UCHAR ExtRateLen;
+ UCHAR ExtRate[MAX_LENGTH_OF_SUPPORT_RATES];
+} RT_802_11_TX_RATES, *PRT_802_11_TX_RATES;
+
+
+// Definition of extra information code
+#define GENERAL_LINK_UP 0x0 // Link is Up
+#define GENERAL_LINK_DOWN 0x1 // Link is Down
+#define HW_RADIO_OFF 0x2 // Hardware radio off
+#define SW_RADIO_OFF 0x3 // Software radio off
+#define AUTH_FAIL 0x4 // Open authentication fail
+#define AUTH_FAIL_KEYS 0x5 // Shared authentication fail
+#define ASSOC_FAIL 0x6 // Association failed
+#define EAP_MIC_FAILURE 0x7 // Deauthencation because MIC failure
+#define EAP_4WAY_TIMEOUT 0x8 // Deauthencation on 4-way handshake timeout
+#define EAP_GROUP_KEY_TIMEOUT 0x9 // Deauthencation on group key handshake timeout
+#define EAP_SUCCESS 0xa // EAP succeed
+#define DETECT_RADAR_SIGNAL 0xb // Radar signal occur in current channel
+#define EXTRA_INFO_MAX 0xb // Indicate Last OID
+
+#define EXTRA_INFO_CLEAR 0xffffffff
+
+// This is OID setting structure. So only GF or MM as Mode. This is valid when our wirelss mode has 802.11n in use.
+typedef struct {
+ RT_802_11_PHY_MODE PhyMode; //
+ UCHAR TransmitNo;
+ UCHAR HtMode; //HTMODE_GF or HTMODE_MM
+ UCHAR ExtOffset; //extension channel above or below
+ UCHAR MCS;
+ UCHAR BW;
+ UCHAR STBC;
+ UCHAR SHORTGI;
+ UCHAR rsv;
+} OID_SET_HT_PHYMODE, *POID_SET_HT_PHYMODE;
+
+#ifdef NINTENDO_AP
+#define NINTENDO_MAX_ENTRY 16
+#define NINTENDO_SSID_NAME_LN 8
+#define NINTENDO_SSID_NAME "NWCUSBAP"
+#define NINTENDO_PROBE_REQ_FLAG_MASK 0x03
+#define NINTENDO_PROBE_REQ_ON 0x01
+#define NINTENDO_PROBE_REQ_SIGNAL 0x02
+#define NINTENDO_PROBE_RSP_ON 0x01
+#define NINTENDO_SSID_NICKNAME_LN 20
+
+#define NINTENDO_WEPKEY_LN 13
+
+typedef struct _NINTENDO_SSID
+{
+ UCHAR NINTENDOFixChar[NINTENDO_SSID_NAME_LN];
+ UCHAR zero1;
+ UCHAR registe;
+ UCHAR ID;
+ UCHAR zero2;
+ UCHAR NICKname[NINTENDO_SSID_NICKNAME_LN];
+} RT_NINTENDO_SSID, *PRT_NINTENDO_SSID;
+
+typedef struct _NINTENDO_ENTRY
+{
+ UCHAR NICKname[NINTENDO_SSID_NICKNAME_LN];
+ UCHAR DS_Addr[ETH_LENGTH_OF_ADDRESS];
+ UCHAR registe;
+ UCHAR UserSpaceAck;
+} RT_NINTENDO_ENTRY, *PRT_NINTENDO_ENTRY;
+
+//RTPRIV_IOCTL_NINTENDO_GET_TABLE
+//RTPRIV_IOCTL_NINTENDO_SET_TABLE
+typedef struct _NINTENDO_TABLE
+{
+ UINT number;
+ RT_NINTENDO_ENTRY entry[NINTENDO_MAX_ENTRY];
+} RT_NINTENDO_TABLE, *PRT_NINTENDO_TABLE;
+
+//RTPRIV_IOCTL_NINTENDO_SEED_WEPKEY
+typedef struct _NINTENDO_SEED_WEPKEY
+{
+ UCHAR seed[NINTENDO_SSID_NICKNAME_LN];
+ UCHAR wepkey[16];//use 13 for 104 bits wep key
+} RT_NINTENDO_SEED_WEPKEY, *PRT_NINTENDO_SEED_WEPKEY;
+#endif // NINTENDO_AP //
+
+#ifdef LLTD_SUPPORT
+typedef struct _RT_LLTD_ASSOICATION_ENTRY {
+ UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
+ unsigned short MOR; // maximum operational rate
+ UCHAR phyMode;
+} RT_LLTD_ASSOICATION_ENTRY, *PRT_LLTD_ASSOICATION_ENTRY;
+
+typedef struct _RT_LLTD_ASSOICATION_TABLE {
+ unsigned int Num;
+ RT_LLTD_ASSOICATION_ENTRY Entry[MAX_NUMBER_OF_MAC];
+} RT_LLTD_ASSOICATION_TABLE, *PRT_LLTD_ASSOICATION_TABLE;
+#endif // LLTD_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+//rt2860, kathy 2007-0118
+// structure for DLS
+typedef struct _RT_802_11_DLS_UI {
+ USHORT TimeOut; // unit: second , set by UI
+ USHORT CountDownTimer; // unit: second , used by driver only
+ NDIS_802_11_MAC_ADDRESS MacAddr; // set by UI
+ UCHAR Status; // 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
+ BOOLEAN Valid; // 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
+} RT_802_11_DLS_UI, *PRT_802_11_DLS_UI;
+
+typedef struct _RT_802_11_DLS_INFO {
+ RT_802_11_DLS_UI Entry[MAX_NUMBER_OF_DLS_ENTRY];
+ UCHAR num;
+} RT_802_11_DLS_INFO, *PRT_802_11_DLS_INFO;
+
+typedef enum _RT_802_11_DLS_MODE {
+ DLS_NONE,
+ DLS_WAIT_KEY,
+ DLS_FINISH
+} RT_802_11_DLS_MODE;
+#endif // QOS_DLS_SUPPORT //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+#define RT_ASSOC_EVENT_FLAG 0x0101
+#define RT_DISASSOC_EVENT_FLAG 0x0102
+#define RT_REQIE_EVENT_FLAG 0x0103
+#define RT_RESPIE_EVENT_FLAG 0x0104
+#define RT_ASSOCINFO_EVENT_FLAG 0x0105
+#define RT_PMKIDCAND_FLAG 0x0106
+#define RT_INTERFACE_DOWN 0x0107
+#define RT_INTERFACE_UP 0x0108
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+
+#define MAX_CUSTOM_LEN 128
+
+#ifdef CONFIG_STA_SUPPORT
+typedef enum _RT_802_11_D_CLIENT_MODE
+{
+ Rt802_11_D_None,
+ Rt802_11_D_Flexible,
+ Rt802_11_D_Strict,
+} RT_802_11_D_CLIENT_MODE, *PRT_802_11_D_CLIENT_MODE;
+#endif // CONFIG_STA_SUPPORT //
+
+typedef struct _RT_CHANNEL_LIST_INFO
+{
+ UCHAR ChannelList[MAX_NUM_OF_CHS]; // list all supported channels for site survey
+ UCHAR ChannelListNum; // number of channel in ChannelList[]
+} RT_CHANNEL_LIST_INFO, *PRT_CHANNEL_LIST_INFO;
+
+// WSC configured credential
+typedef struct _WSC_CREDENTIAL
+{
+ NDIS_802_11_SSID SSID; // mandatory
+ USHORT AuthType; // mandatory, 1: open, 2: wpa-psk, 4: shared, 8:wpa, 0x10: wpa2, 0x20: wpa2-psk
+ USHORT EncrType; // mandatory, 1: none, 2: wep, 4: tkip, 8: aes
+ UCHAR Key[64]; // mandatory, Maximum 64 byte
+ USHORT KeyLength;
+ UCHAR MacAddr[6]; // mandatory, AP MAC address
+ UCHAR KeyIndex; // optional, default is 1
+ UCHAR Rsvd[3]; // Make alignment
+} WSC_CREDENTIAL, *PWSC_CREDENTIAL;
+
+// WSC configured profiles
+typedef struct _WSC_PROFILE
+{
+ UINT ProfileCnt;
+ WSC_CREDENTIAL Profile[8]; // Support up to 8 profiles
+} WSC_PROFILE, *PWSC_PROFILE;
+
+
+
+#endif // _OID_H_
+
diff --git a/drivers/staging/rt3070/rt2870.h b/drivers/staging/rt3070/rt2870.h
new file mode 100644
index 00000000000..d32a2bf1d04
--- /dev/null
+++ b/drivers/staging/rt3070/rt2870.h
@@ -0,0 +1,756 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#ifndef __RT2870_H__
+#define __RT2870_H__
+
+//usb header files
+#include <linux/usb.h>
+
+/* rtmp_def.h */
+//
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define BULKAGGRE_ZISE 100
+#define RT28XX_DRVDATA_SET(_a) usb_set_intfdata(_a, pAd);
+#define RT28XX_PUT_DEVICE usb_put_dev
+#define RTUSB_ALLOC_URB(iso) usb_alloc_urb(iso, GFP_ATOMIC)
+#define RTUSB_SUBMIT_URB(pUrb) usb_submit_urb(pUrb, GFP_ATOMIC)
+#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr) usb_buffer_alloc(pUsb_Dev, BufSize, GFP_ATOMIC, pDma_addr)
+#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr) usb_buffer_free(pUsb_Dev, BufSize, pTransferBuf, Dma_addr)
+#else
+#define BULKAGGRE_ZISE 60
+#define RT28XX_DRVDATA_SET(_a)
+#define RT28XX_PUT_DEVICE(dev_p)
+#define RTUSB_ALLOC_URB(iso) usb_alloc_urb(iso)
+#define RTUSB_SUBMIT_URB(pUrb) usb_submit_urb(pUrb)
+#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr) kmalloc(BufSize, GFP_ATOMIC)
+#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr) kfree(pTransferBuf)
+#endif
+
+#define RXBULKAGGRE_ZISE 12
+#define MAX_TXBULK_LIMIT (LOCAL_TXBUF_SIZE*(BULKAGGRE_ZISE-1))
+#define MAX_TXBULK_SIZE (LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE)
+#define MAX_RXBULK_SIZE (LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE)
+#define MAX_MLME_HANDLER_MEMORY 20
+#define BUFFER_SIZE 2400 //2048
+#define TX_RING 0xa
+#define PRIO_RING 0xc
+
+
+// Flags for Bulkflags control for bulk out data
+//
+#define fRTUSB_BULK_OUT_DATA_NULL 0x00000001
+#define fRTUSB_BULK_OUT_RTS 0x00000002
+#define fRTUSB_BULK_OUT_MLME 0x00000004
+
+#define fRTUSB_BULK_OUT_DATA_NORMAL 0x00010000
+#define fRTUSB_BULK_OUT_DATA_NORMAL_2 0x00020000
+#define fRTUSB_BULK_OUT_DATA_NORMAL_3 0x00040000
+#define fRTUSB_BULK_OUT_DATA_NORMAL_4 0x00080000
+#define fRTUSB_BULK_OUT_DATA_NORMAL_5 0x00100000
+
+#define fRTUSB_BULK_OUT_PSPOLL 0x00000020
+#define fRTUSB_BULK_OUT_DATA_FRAG 0x00000040
+#define fRTUSB_BULK_OUT_DATA_FRAG_2 0x00000080
+#define fRTUSB_BULK_OUT_DATA_FRAG_3 0x00000100
+#define fRTUSB_BULK_OUT_DATA_FRAG_4 0x00000200
+
+#ifdef RALINK_ATE
+#define fRTUSB_BULK_OUT_DATA_ATE 0x00100000
+#endif // RALINK_ATE //
+
+#define RT2870_USB_DEVICES \
+{ \
+ {USB_DEVICE(0x148F,0x2770)}, /* Ralink */ \
+ {USB_DEVICE(0x148F,0x2870)}, /* Ralink */ \
+ {USB_DEVICE(0x148F,0x3070)}, /* Ralink 3070 */ \
+ {USB_DEVICE(0x148F,0x3071)}, /* Ralink 3071 */ \
+ {USB_DEVICE(0x148F,0x3072)}, /* Ralink 3072 */ \
+ {USB_DEVICE(0x0B05,0x1731)}, /* Asus */ \
+ {USB_DEVICE(0x0B05,0x1732)}, /* Asus */ \
+ {USB_DEVICE(0x0B05,0x1742)}, /* Asus */ \
+ {USB_DEVICE(0x0DF6,0x0017)}, /* Sitecom */ \
+ {USB_DEVICE(0x0DF6,0x002B)}, /* Sitecom */ \
+ {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ \
+ {USB_DEVICE(0x0DF6,0x003E)}, /* Sitecom 3070 */ \
+ {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ \
+ {USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom 2770 */ \
+ {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ \
+ {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ \
+ {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ \
+ {USB_DEVICE(0x2019,0xAB25)}, /* Planex Communications, Inc. RT3070 */ \
+ {USB_DEVICE(0x07D1,0x3C09)}, /* D-Link */ \
+ {USB_DEVICE(0x07D1,0x3C11)}, /* D-Link */ \
+ {USB_DEVICE(0x2001,0x3C09)}, /* D-Link */ \
+ {USB_DEVICE(0x2001,0x3C0A)}, /* D-Link 3072*/ \
+ {USB_DEVICE(0x14B2,0x3C07)}, /* AL */ \
+ {USB_DEVICE(0x14B2,0x3C12)}, /* AL 3070 */ \
+ {USB_DEVICE(0x050D,0x8053)}, /* Belkin */ \
+ {USB_DEVICE(0x14B2,0x3C23)}, /* Airlink */ \
+ {USB_DEVICE(0x14B2,0x3C27)}, /* Airlink */ \
+ {USB_DEVICE(0x07AA,0x002F)}, /* Corega */ \
+ {USB_DEVICE(0x07AA,0x003C)}, /* Corega */ \
+ {USB_DEVICE(0x07AA,0x003F)}, /* Corega */ \
+ {USB_DEVICE(0x18C5,0x0012)}, /* Corega 3070 */ \
+ {USB_DEVICE(0x1044,0x800B)}, /* Gigabyte */ \
+ {USB_DEVICE(0x1044,0x800D)}, /* Gigabyte GN-WB32L 3070 */ \
+ {USB_DEVICE(0x15A9,0x0006)}, /* Sparklan */ \
+ {USB_DEVICE(0x083A,0xB522)}, /* SMC */ \
+ {USB_DEVICE(0x083A,0xA618)}, /* SMC */ \
+ {USB_DEVICE(0x083A,0x8522)}, /* Arcadyan */ \
+ {USB_DEVICE(0x083A,0x7512)}, /* Arcadyan 2770 */ \
+ {USB_DEVICE(0x083A,0x7522)}, /* Arcadyan */ \
+ {USB_DEVICE(0x083A,0x7511)}, /* Arcadyan 3070 */ \
+ {USB_DEVICE(0x0CDE,0x0022)}, /* ZCOM */ \
+ {USB_DEVICE(0x0586,0x3416)}, /* Zyxel */ \
+ {USB_DEVICE(0x0CDE,0x0025)}, /* Zyxel */ \
+ {USB_DEVICE(0x1740,0x9701)}, /* EnGenius */ \
+ {USB_DEVICE(0x1740,0x9702)}, /* EnGenius */ \
+ {USB_DEVICE(0x1740,0x9703)}, /* EnGenius 3070 */ \
+ {USB_DEVICE(0x0471,0x200f)}, /* Philips */ \
+ {USB_DEVICE(0x14B2,0x3C25)}, /* Draytek */ \
+ {USB_DEVICE(0x13D3,0x3247)}, /* AzureWave */ \
+ {USB_DEVICE(0x13D3,0x3273)}, /* AzureWave 3070*/ \
+ {USB_DEVICE(0x083A,0x6618)}, /* Accton */ \
+ {USB_DEVICE(0x15c5,0x0008)}, /* Amit */ \
+ {USB_DEVICE(0x0E66,0x0001)}, /* Hawking */ \
+ {USB_DEVICE(0x0E66,0x0003)}, /* Hawking */ \
+ {USB_DEVICE(0x129B,0x1828)}, /* Siemens */ \
+ {USB_DEVICE(0x157E,0x300E)}, /* U-Media */ \
+ {USB_DEVICE(0x050d,0x805c)}, \
+ {USB_DEVICE(0x1482,0x3C09)}, /* Abocom*/ \
+ {USB_DEVICE(0x14B2,0x3C09)}, /* Alpha */ \
+ {USB_DEVICE(0x04E8,0x2018)}, /* samsung */ \
+ {USB_DEVICE(0x07B8,0x3070)}, /* AboCom 3070 */ \
+ {USB_DEVICE(0x07B8,0x3071)}, /* AboCom 3071 */ \
+ {USB_DEVICE(0x07B8,0x3072)}, /* Abocom 3072 */ \
+ {USB_DEVICE(0x7392,0x7711)}, /* Edimax 3070 */ \
+ {USB_DEVICE(0x5A57,0x0280)}, /* Zinwell */ \
+ {USB_DEVICE(0x5A57,0x0282)}, /* Zinwell */ \
+ {USB_DEVICE(0x1A32,0x0304)}, /* Quanta 3070 */ \
+ {USB_DEVICE(0x0789,0x0162)}, /* Logitec 2870 */ \
+ {USB_DEVICE(0x0789,0x0163)}, /* Logitec 2870 */ \
+ {USB_DEVICE(0x0789,0x0164)}, /* Logitec 2870 */ \
+ {USB_DEVICE(0x1EDA,0x2310)}, /* AirTies 3070 */ \
+ { }/* Terminating entry */ \
+}
+
+#define FREE_HTTX_RING(_p, _b, _t) \
+{ \
+ if ((_t)->ENextBulkOutPosition == (_t)->CurWritePosition) \
+ { \
+ (_t)->bRingEmpty = TRUE; \
+ } \
+ /*NdisInterlockedDecrement(&(_p)->TxCount); */\
+}
+
+//
+// RXINFO appends at the end of each rx packet.
+//
+#ifdef RT_BIG_ENDIAN
+typedef struct PACKED _RXINFO_STRUC {
+ UINT32 PlcpSignal:12;
+ UINT32 LastAMSDU:1;
+ UINT32 CipherAlg:1;
+ UINT32 PlcpRssil:1;
+ UINT32 Decrypted:1;
+ UINT32 AMPDU:1; // To be moved
+ UINT32 L2PAD:1;
+ UINT32 RSSI:1;
+ UINT32 HTC:1;
+ UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header.
+ UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
+ UINT32 Crc:1; // 1: CRC error
+ UINT32 MyBss:1; // 1: this frame belongs to the same BSSID
+ UINT32 Bcast:1; // 1: this is a broadcast frame
+ UINT32 Mcast:1; // 1: this is a multicast frame
+ UINT32 U2M:1; // 1: this RX frame is unicast to me
+ UINT32 FRAG:1;
+ UINT32 NULLDATA:1;
+ UINT32 DATA:1;
+ UINT32 BA:1;
+} RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
+#else
+typedef struct PACKED _RXINFO_STRUC {
+ UINT32 BA:1;
+ UINT32 DATA:1;
+ UINT32 NULLDATA:1;
+ UINT32 FRAG:1;
+ UINT32 U2M:1; // 1: this RX frame is unicast to me
+ UINT32 Mcast:1; // 1: this is a multicast frame
+ UINT32 Bcast:1; // 1: this is a broadcast frame
+ UINT32 MyBss:1; // 1: this frame belongs to the same BSSID
+ UINT32 Crc:1; // 1: CRC error
+ UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
+ UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header.
+ UINT32 HTC:1;
+ UINT32 RSSI:1;
+ UINT32 L2PAD:1;
+ UINT32 AMPDU:1; // To be moved
+ UINT32 Decrypted:1;
+ UINT32 PlcpRssil:1;
+ UINT32 CipherAlg:1;
+ UINT32 LastAMSDU:1;
+ UINT32 PlcpSignal:12;
+} RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
+#endif
+
+
+//
+// TXINFO
+//
+#ifdef RT_BIG_ENDIAN
+typedef struct _TXINFO_STRUC {
+ // Word 0
+ UINT32 USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint
+ UINT32 USBDMANextVLD:1; //used ONLY in USB bulk Aggregation, NextValid
+ UINT32 rsv2:2; // Software use.
+ UINT32 SwUseLastRound:1; // Software use.
+ UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+ UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
+ UINT32 rsv:8;
+ UINT32 USBDMATxPktLen:16; //used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame.
+} TXINFO_STRUC, *PTXINFO_STRUC;
+#else
+typedef struct _TXINFO_STRUC {
+ // Word 0
+ UINT32 USBDMATxPktLen:16; //used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame.
+ UINT32 rsv:8;
+ UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
+ UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+ UINT32 SwUseLastRound:1; // Software use.
+ UINT32 rsv2:2; // Software use.
+ UINT32 USBDMANextVLD:1; //used ONLY in USB bulk Aggregation, NextValid
+ UINT32 USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint
+} TXINFO_STRUC, *PTXINFO_STRUC;
+#endif
+
+#define TXINFO_SIZE 4
+#define RXINFO_SIZE 4
+#define TXPADDING_SIZE 11
+
+//
+// Management ring buffer format
+//
+typedef struct _MGMT_STRUC {
+ BOOLEAN Valid;
+ PUCHAR pBuffer;
+ ULONG Length;
+} MGMT_STRUC, *PMGMT_STRUC;
+
+
+/* ----------------- EEPROM Related MACRO ----------------- */
+#ifdef RT30xx
+#define RT28xx_EEPROM_READ16(pAd, offset, var) \
+ do { \
+ RTUSBReadEEPROM(pAd, offset, (PUCHAR)&(var), 2); \
+ if(!pAd->bUseEfuse) \
+ var = le2cpu16(var); \
+ }while(0)
+
+#define RT28xx_EEPROM_WRITE16(pAd, offset, var) \
+ do{ \
+ USHORT _tmpVar=var; \
+ if(!pAd->bUseEfuse) \
+ _tmpVar = cpu2le16(var); \
+ RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(_tmpVar), 2); \
+ }while(0)
+#endif // RT30xx //
+#ifndef RT30xx
+#define RT28xx_EEPROM_READ16(pAd, offset, var) \
+ do { \
+ RTUSBReadEEPROM(pAd, offset, (PUCHAR)&(var), 2); \
+ var = le2cpu16(var); \
+ }while(0)
+
+#define RT28xx_EEPROM_WRITE16(pAd, offset, var) \
+ do{ \
+ USHORT _tmpVar=var; \
+ _tmpVar = cpu2le16(var); \
+ RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(_tmpVar), 2); \
+ }while(0)
+#endif // RT30xx //
+
+/* ----------------- TASK/THREAD Related MACRO ----------------- */
+#define RT28XX_TASK_THREAD_INIT(pAd, Status) \
+ Status = CreateThreads(net_dev);
+
+
+/* ----------------- Frimware Related MACRO ----------------- */
+#define RT28XX_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \
+ RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen)
+
+/* ----------------- TX Related MACRO ----------------- */
+#define RT28XX_START_DEQUEUE(pAd, QueIdx, irqFlags) \
+ { \
+ RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
+ if (pAd->DeQueueRunning[QueIdx]) \
+ { \
+ RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
+ printk("DeQueueRunning[%d]= TRUE!\n", QueIdx); \
+ continue; \
+ } \
+ else \
+ { \
+ pAd->DeQueueRunning[QueIdx] = TRUE; \
+ RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
+ } \
+ }
+#define RT28XX_STOP_DEQUEUE(pAd, QueIdx, irqFlags) \
+ do{ \
+ RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
+ pAd->DeQueueRunning[QueIdx] = FALSE; \
+ RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
+ }while(0)
+
+
+#define RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
+ (RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS)
+
+#define RT28XX_RELEASE_DESC_RESOURCE(pAd, QueIdx) \
+ do{}while(0)
+
+#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType) \
+ ((_TxFrameType == TX_RALINK_FRAME) && (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx)))
+
+
+
+#define fRTMP_ADAPTER_NEED_STOP_TX \
+ (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
+ fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \
+ fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
+
+
+#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \
+ RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
+
+#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \
+ RtmpUSB_WriteSingleTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)
+
+#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
+ RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
+
+#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \
+ RtmpUSB_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)
+
+#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) \
+ RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)
+
+#define HAL_LastTxIdx(pAd, QueIdx,TxIdx) \
+ /*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx)*/
+
+#define HAL_KickOutTx(pAd, pTxBlk, QueIdx) \
+ RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx)
+
+
+#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen) \
+ RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)
+
+#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \
+ RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen)
+
+#define RTMP_PKT_TAIL_PADDING 11 // 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding)
+
+extern UCHAR EpToQueue[6];
+
+
+#ifdef RT2870
+#define GET_TXRING_FREENO(_pAd, _QueIdx) (_QueIdx) //(_pAd->TxRing[_QueIdx].TxSwFreeIdx)
+#define GET_MGMTRING_FREENO(_pAd) (_pAd->MgmtRing.TxSwFreeIdx)
+#endif // RT2870 //
+
+
+/* ----------------- RX Related MACRO ----------------- */
+//#define RT28XX_RX_ERROR_CHECK RTMPCheckRxWI
+
+#define RT28XX_RV_ALL_BUF_END(bBulkReceive) \
+ /* We return STATUS_MORE_PROCESSING_REQUIRED so that the completion */ \
+ /* routine (IofCompleteRequest) will stop working on the irp. */ \
+ if (bBulkReceive == TRUE) RTUSBBulkReceive(pAd);
+
+
+/* ----------------- ASIC Related MACRO ----------------- */
+// reset MAC of a station entry to 0xFFFFFFFFFFFF
+#define RT28XX_STA_ENTRY_MAC_RESET(pAd, Wcid) \
+ { RT_SET_ASIC_WCID SetAsicWcid; \
+ SetAsicWcid.WCID = Wcid; \
+ SetAsicWcid.SetTid = 0xffffffff; \
+ SetAsicWcid.DeleteTid = 0xffffffff; \
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID, \
+ &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); }
+
+// add this entry into ASIC RX WCID search table
+#define RT28XX_STA_ENTRY_ADD(pAd, pEntry) \
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY, \
+ pEntry, sizeof(MAC_TABLE_ENTRY));
+
+// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+// Set MAC register value according operation mode
+#define RT28XX_UPDATE_PROTECT(pAd) \
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0);
+// end johnli
+
+// remove Pair-wise key material from ASIC
+// yet implement
+#define RT28XX_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)
+
+// add Client security information into ASIC WCID table and IVEIV table
+#define RT28XX_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry) \
+ { RT28XX_STA_ENTRY_MAC_RESET(pAd, pEntry->Aid); \
+ if (pEntry->Aid >= 1) { \
+ RT_SET_ASIC_WCID_ATTRI SetAsicWcidAttri; \
+ SetAsicWcidAttri.WCID = pEntry->Aid; \
+ if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && \
+ (pEntry->WepStatus == Ndis802_11Encryption1Enabled)) \
+ { \
+ SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \
+ } \
+ else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone) \
+ { \
+ SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \
+ } \
+ else SetAsicWcidAttri.Cipher = 0; \
+ DBGPRINT(RT_DEBUG_TRACE, ("aid cipher = %ld\n",SetAsicWcidAttri.Cipher)); \
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID_CIPHER, \
+ &SetAsicWcidAttri, sizeof(RT_SET_ASIC_WCID_ATTRI)); } }
+
+// Insert the BA bitmap to ASIC for the Wcid entry
+#define RT28XX_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \
+ do{ \
+ RT_SET_ASIC_WCID SetAsicWcid; \
+ SetAsicWcid.WCID = (_Aid); \
+ SetAsicWcid.SetTid = (0x10000<<(_TID)); \
+ SetAsicWcid.DeleteTid = 0xffffffff; \
+ RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \
+ }while(0)
+
+// Remove the BA bitmap from ASIC for the Wcid entry
+#define RT28XX_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \
+ do{ \
+ RT_SET_ASIC_WCID SetAsicWcid; \
+ SetAsicWcid.WCID = (_Wcid); \
+ SetAsicWcid.SetTid = (0xffffffff); \
+ SetAsicWcid.DeleteTid = (0x10000<<(_TID) ); \
+ RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \
+ }while(0)
+
+
+/* ----------------- PCI/USB Related MACRO ----------------- */
+#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p) \
+ ((POS_COOKIE)handle)->pUsb_Dev = dev_p;
+
+// no use
+#define RT28XX_UNMAP()
+#define RT28XX_IRQ_REQUEST(net_dev)
+#define RT28XX_IRQ_RELEASE(net_dev)
+#define RT28XX_IRQ_INIT(pAd)
+#define RT28XX_IRQ_ENABLE(pAd)
+
+
+/* ----------------- MLME Related MACRO ----------------- */
+#define RT28XX_MLME_HANDLER(pAd) RTUSBMlmeUp(pAd)
+
+#define RT28XX_MLME_PRE_SANITY_CHECK(pAd) \
+ { if ((pAd->CommonCfg.bHardwareRadio == TRUE) && \
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && \
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) { \
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } }
+
+#define RT28XX_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \
+ { RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0); \
+ RTUSBMlmeUp(pAd); }
+
+#define RT28XX_MLME_RESET_STATE_MACHINE(pAd) \
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL); \
+ RTUSBMlmeUp(pAd);
+
+#define RT28XX_HANDLE_COUNTER_MEASURE(_pAd, _pEntry) \
+ { RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(MAC_TABLE_ENTRY)); \
+ RTUSBMlmeUp(_pAd); \
+ }
+
+
+/* ----------------- Power Save Related MACRO ----------------- */
+#define RT28XX_PS_POLL_ENQUEUE(pAd) \
+ { RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); \
+ RTUSBKickBulkOut(pAd); }
+
+#define RT28xx_CHIP_NAME "RT2870"
+#define USB_CYC_CFG 0x02a4
+#define NT_SUCCESS(status) (((status) > 0) ? (1):(0))
+#define InterlockedIncrement atomic_inc
+#define NdisInterlockedIncrement atomic_inc
+#define InterlockedDecrement atomic_dec
+#define NdisInterlockedDecrement atomic_dec
+#define InterlockedExchange atomic_set
+//#define NdisMSendComplete RTMP_SendComplete
+#define NdisMCancelTimer RTMPCancelTimer
+#define NdisAllocMemory(_ptr, _size, _flag) \
+ do{_ptr = kmalloc((_size),(_flag));}while(0)
+#define NdisFreeMemory(a, b, c) kfree((a))
+#define NdisMSleep RTMPusecDelay /* unit: microsecond */
+
+
+#define USBD_TRANSFER_DIRECTION_OUT 0
+#define USBD_TRANSFER_DIRECTION_IN 0
+#define USBD_SHORT_TRANSFER_OK 0
+#define PURB purbb_t
+
+#define RTUSB_FREE_URB(pUrb) usb_free_urb(pUrb)
+
+//#undef MlmeAllocateMemory
+//#undef MlmeFreeMemory
+
+typedef struct usb_device * PUSB_DEV;
+
+/* MACRO for linux usb */
+typedef struct urb *purbb_t;
+typedef struct usb_ctrlrequest devctrlrequest;
+#define PIRP PVOID
+#define PMDL PVOID
+#define NDIS_OID UINT
+#ifndef USB_ST_NOERROR
+#define USB_ST_NOERROR 0
+#endif
+
+// vendor-specific control operations
+#define CONTROL_TIMEOUT_JIFFIES ( (100 * HZ) / 1000)
+#define UNLINK_TIMEOUT_MS 3
+
+/* unlink urb */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7)
+#define RTUSB_UNLINK_URB(pUrb) usb_kill_urb(pUrb)
+#else
+#define RTUSB_UNLINK_URB(pUrb) usb_unlink_urb(pUrb)
+#endif
+
+// Prototypes of completion funuc.
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define RTUSBBulkOutDataPacketComplete(purb, pt_regs) RTUSBBulkOutDataPacketComplete(purb)
+#define RTUSBBulkOutMLMEPacketComplete(pUrb, pt_regs) RTUSBBulkOutMLMEPacketComplete(pUrb)
+#define RTUSBBulkOutNullFrameComplete(pUrb, pt_regs) RTUSBBulkOutNullFrameComplete(pUrb)
+#define RTUSBBulkOutRTSFrameComplete(pUrb, pt_regs) RTUSBBulkOutRTSFrameComplete(pUrb)
+#define RTUSBBulkOutPsPollComplete(pUrb, pt_regs) RTUSBBulkOutPsPollComplete(pUrb)
+#define RTUSBBulkRxComplete(pUrb, pt_regs) RTUSBBulkRxComplete(pUrb)
+#endif
+
+
+VOID RTUSBBulkOutDataPacketComplete(purbb_t purb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+
+
+#define RTUSBMlmeUp(pAd) \
+{ \
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \
+ if(pObj->MLMEThr_pid>0) \
+ up(&(pAd->mlme_semaphore)); \
+}
+
+#define RTUSBCMDUp(pAd) \
+{ \
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \
+ if(pObj->RTUSBCmdThr_pid>0) \
+ up(&(pAd->RTUSBCmd_semaphore)); \
+}
+
+
+static inline NDIS_STATUS RTMPAllocateMemory(
+ OUT PVOID *ptr,
+ IN size_t size)
+{
+ *ptr = kmalloc(size, GFP_ATOMIC);
+ if(*ptr)
+ return NDIS_STATUS_SUCCESS;
+ else
+ return NDIS_STATUS_RESOURCES;
+}
+
+/* rtmp.h */
+#define BEACON_RING_SIZE 2
+#define DEVICE_VENDOR_REQUEST_OUT 0x40
+#define DEVICE_VENDOR_REQUEST_IN 0xc0
+#define INTERFACE_VENDOR_REQUEST_OUT 0x41
+#define INTERFACE_VENDOR_REQUEST_IN 0xc1
+#define MGMTPIPEIDX 0 // EP6 is highest priority
+
+#define BULKOUT_MGMT_RESET_FLAG 0x80
+
+#define RTUSB_SET_BULK_FLAG(_M, _F) ((_M)->BulkFlags |= (_F))
+#define RTUSB_CLEAR_BULK_FLAG(_M, _F) ((_M)->BulkFlags &= ~(_F))
+#define RTUSB_TEST_BULK_FLAG(_M, _F) (((_M)->BulkFlags & (_F)) != 0)
+
+#define EnqueueCmd(cmdq, cmdqelmt) \
+{ \
+ if (cmdq->size == 0) \
+ cmdq->head = cmdqelmt; \
+ else \
+ cmdq->tail->next = cmdqelmt; \
+ cmdq->tail = cmdqelmt; \
+ cmdqelmt->next = NULL; \
+ cmdq->size++; \
+}
+
+typedef struct _RT_SET_ASIC_WCID {
+ ULONG WCID; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
+ ULONG SetTid; // time-based: seconds, packet-based: kilo-packets
+ ULONG DeleteTid; // time-based: seconds, packet-based: kilo-packets
+} RT_SET_ASIC_WCID,*PRT_SET_ASIC_WCID;
+
+typedef struct _RT_SET_ASIC_WCID_ATTRI {
+ ULONG WCID; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
+ ULONG Cipher; // ASIC Cipher definition
+ UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
+} RT_SET_ASIC_WCID_ATTRI,*PRT_SET_ASIC_WCID_ATTRI;
+
+typedef struct _MLME_MEMORY_STRUCT {
+ PVOID AllocVa; //Pointer to the base virtual address of the allocated memory
+ struct _MLME_MEMORY_STRUCT *Next; //Pointer to the next virtual address of the allocated memory
+} MLME_MEMORY_STRUCT, *PMLME_MEMORY_STRUCT;
+
+typedef struct _MLME_MEMORY_HANDLER {
+ BOOLEAN MemRunning; //The flag of the Mlme memory handler's status
+ UINT MemoryCount; //Total nonpaged system-space memory not size
+ UINT InUseCount; //Nonpaged system-space memory in used counts
+ UINT UnUseCount; //Nonpaged system-space memory available counts
+ INT PendingCount; //Nonpaged system-space memory for free counts
+ PMLME_MEMORY_STRUCT pInUseHead; //Pointer to the first nonpaed memory not used
+ PMLME_MEMORY_STRUCT pInUseTail; //Pointer to the last nonpaged memory not used
+ PMLME_MEMORY_STRUCT pUnUseHead; //Pointer to the first nonpaged memory in used
+ PMLME_MEMORY_STRUCT pUnUseTail; //Pointer to the last nonpaged memory in used
+ PULONG MemFreePending[MAX_MLME_HANDLER_MEMORY]; //an array to keep pending free-memory's pointer (32bits)
+} MLME_MEMORY_HANDLER, *PMLME_MEMORY_HANDLER;
+
+typedef struct _CmdQElmt {
+ UINT command;
+ PVOID buffer;
+ ULONG bufferlength;
+ BOOLEAN CmdFromNdis;
+ BOOLEAN SetOperation;
+ struct _CmdQElmt *next;
+} CmdQElmt, *PCmdQElmt;
+
+typedef struct _CmdQ {
+ UINT size;
+ CmdQElmt *head;
+ CmdQElmt *tail;
+ UINT32 CmdQState;
+}CmdQ, *PCmdQ;
+
+//
+// For WPA SUPPLICANT: WIRELESS EXT support wireless events: v14 or newer
+//
+#if WIRELESS_EXT >= 14
+//#define WPA_SUPPLICANT_SUPPORT 1
+#endif
+
+/* oid.h */
+// Cipher suite type for mixed mode group cipher, P802.11i-2004
+typedef enum _RT_802_11_CIPHER_SUITE_TYPE {
+ Cipher_Type_NONE,
+ Cipher_Type_WEP40,
+ Cipher_Type_TKIP,
+ Cipher_Type_RSVD,
+ Cipher_Type_CCMP,
+ Cipher_Type_WEP104
+} RT_802_11_CIPHER_SUITE_TYPE, *PRT_802_11_CIPHER_SUITE_TYPE;
+
+//CMDTHREAD_MULTI_READ_MAC
+//CMDTHREAD_MULTI_WRITE_MAC
+//CMDTHREAD_VENDOR_EEPROM_READ
+//CMDTHREAD_VENDOR_EEPROM_WRITE
+typedef struct _CMDHandler_TLV {
+ USHORT Offset;
+ USHORT Length;
+ UCHAR DataFirst;
+} CMDHandler_TLV, *PCMDHandler_TLV;
+
+// New for MeetingHouse Api support
+#define CMDTHREAD_VENDOR_RESET 0x0D730101 // cmd
+#define CMDTHREAD_VENDOR_UNPLUG 0x0D730102 // cmd
+#define CMDTHREAD_VENDOR_SWITCH_FUNCTION 0x0D730103 // cmd
+#define CMDTHREAD_MULTI_WRITE_MAC 0x0D730107 // cmd
+#define CMDTHREAD_MULTI_READ_MAC 0x0D730108 // cmd
+#define CMDTHREAD_VENDOR_EEPROM_WRITE 0x0D73010A // cmd
+#define CMDTHREAD_VENDOR_EEPROM_READ 0x0D73010B // cmd
+#define CMDTHREAD_VENDOR_ENTER_TESTMODE 0x0D73010C // cmd
+#define CMDTHREAD_VENDOR_EXIT_TESTMODE 0x0D73010D // cmd
+#define CMDTHREAD_VENDOR_WRITE_BBP 0x0D730119 // cmd
+#define CMDTHREAD_VENDOR_READ_BBP 0x0D730118 // cmd
+#define CMDTHREAD_VENDOR_WRITE_RF 0x0D73011A // cmd
+#define CMDTHREAD_VENDOR_FLIP_IQ 0x0D73011D // cmd
+#define CMDTHREAD_RESET_BULK_OUT 0x0D730210 // cmd
+#define CMDTHREAD_RESET_BULK_IN 0x0D730211 // cmd
+#define CMDTHREAD_SET_PSM_BIT_SAVE 0x0D730212 // cmd
+#define CMDTHREAD_SET_RADIO 0x0D730214 // cmd
+#define CMDTHREAD_UPDATE_TX_RATE 0x0D730216 // cmd
+#define CMDTHREAD_802_11_ADD_KEY_WEP 0x0D730218 // cmd
+#define CMDTHREAD_RESET_FROM_ERROR 0x0D73021A // cmd
+#define CMDTHREAD_LINK_DOWN 0x0D73021B // cmd
+#define CMDTHREAD_RESET_FROM_NDIS 0x0D73021C // cmd
+#define CMDTHREAD_CHECK_GPIO 0x0D730215 // cmd
+#define CMDTHREAD_FORCE_WAKE_UP 0x0D730222 // cmd
+#define CMDTHREAD_SET_BW 0x0D730225 // cmd
+#define CMDTHREAD_SET_ASIC_WCID 0x0D730226 // cmd
+#define CMDTHREAD_SET_ASIC_WCID_CIPHER 0x0D730227 // cmd
+#define CMDTHREAD_QKERIODIC_EXECUT 0x0D73023D // cmd
+#define RT_CMD_SET_KEY_TABLE 0x0D730228 // cmd
+#define RT_CMD_SET_RX_WCID_TABLE 0x0D730229 // cmd
+#define CMDTHREAD_SET_CLIENT_MAC_ENTRY 0x0D73023E // cmd
+#define CMDTHREAD_802_11_QUERY_HARDWARE_REGISTER 0x0D710105 // cmd
+#define CMDTHREAD_802_11_SET_PHY_MODE 0x0D79010C // cmd
+#define CMDTHREAD_802_11_SET_STA_CONFIG 0x0D790111 // cmd
+#define CMDTHREAD_802_11_SET_PREAMBLE 0x0D790101 // cmd
+#define CMDTHREAD_802_11_COUNTER_MEASURE 0x0D790102 // cmd
+// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+#define CMDTHREAD_UPDATE_PROTECT 0x0D790103 // cmd
+// end johnli
+
+#define WPA1AKMBIT 0x01
+#define WPA2AKMBIT 0x02
+#define WPA1PSKAKMBIT 0x04
+#define WPA2PSKAKMBIT 0x08
+#define TKIPBIT 0x01
+#define CCMPBIT 0x02
+
+
+#define RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx) \
+ RT28xxUsbStaAsicForceWakeup(pAd, bFromTx);
+
+#define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
+ RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+
+#define RT28XX_MLME_RADIO_ON(pAd) \
+ RT28xxUsbMlmeRadioOn(pAd);
+
+#define RT28XX_MLME_RADIO_OFF(pAd) \
+ RT28xxUsbMlmeRadioOFF(pAd);
+
+#endif //__RT2870_H__
diff --git a/drivers/staging/rt3070/rt28xx.h b/drivers/staging/rt3070/rt28xx.h
new file mode 100644
index 00000000000..b637c4ee609
--- /dev/null
+++ b/drivers/staging/rt3070/rt28xx.h
@@ -0,0 +1,2725 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rt28xx.h
+
+ Abstract:
+ RT28xx ASIC related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan Lee Jan-3-2006 created for RT2860c
+*/
+
+#ifndef __RT28XX_H__
+#define __RT28XX_H__
+
+
+//
+// PCI registers - base address 0x0000
+//
+#define PCI_CFG 0x0000
+#define PCI_EECTRL 0x0004
+#define PCI_MCUCTRL 0x0008
+
+#define OPT_14 0x114
+
+typedef int NTSTATUS;
+#define RETRY_LIMIT 10
+#define STATUS_SUCCESS 0x00
+#define STATUS_UNSUCCESSFUL 0x01
+
+//
+// SCH/DMA registers - base address 0x0200
+//
+// INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit
+//
+#define DMA_CSR0 0x200
+#define INT_SOURCE_CSR 0x200
+#ifdef RT_BIG_ENDIAN
+typedef union _INT_SOURCE_CSR_STRUC {
+ struct {
+ UINT32 :14;
+ UINT32 TxCoherent:1;
+ UINT32 RxCoherent:1;
+ UINT32 GPTimer:1;
+ UINT32 AutoWakeup:1;//bit14
+ UINT32 TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
+ UINT32 PreTBTT:1;
+ UINT32 TBTTInt:1;
+ UINT32 RxTxCoherent:1;
+ UINT32 MCUCommandINT:1;
+ UINT32 MgmtDmaDone:1;
+ UINT32 HccaDmaDone:1;
+ UINT32 Ac3DmaDone:1;
+ UINT32 Ac2DmaDone:1;
+ UINT32 Ac1DmaDone:1;
+ UINT32 Ac0DmaDone:1;
+ UINT32 RxDone:1;
+ UINT32 TxDelayINT:1; //delayed interrupt, not interrupt until several int or time limit hit
+ UINT32 RxDelayINT:1; //dealyed interrupt
+ } field;
+ UINT32 word;
+} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
+#else
+typedef union _INT_SOURCE_CSR_STRUC {
+ struct {
+ UINT32 RxDelayINT:1;
+ UINT32 TxDelayINT:1;
+ UINT32 RxDone:1;
+ UINT32 Ac0DmaDone:1;//4
+ UINT32 Ac1DmaDone:1;
+ UINT32 Ac2DmaDone:1;
+ UINT32 Ac3DmaDone:1;
+ UINT32 HccaDmaDone:1; // bit7
+ UINT32 MgmtDmaDone:1;
+ UINT32 MCUCommandINT:1;//bit 9
+ UINT32 RxTxCoherent:1;
+ UINT32 TBTTInt:1;
+ UINT32 PreTBTT:1;
+ UINT32 TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
+ UINT32 AutoWakeup:1;//bit14
+ UINT32 GPTimer:1;
+ UINT32 RxCoherent:1;//bit16
+ UINT32 TxCoherent:1;
+ UINT32 :14;
+ } field;
+ UINT32 word;
+} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
+#endif
+
+//
+// INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF
+//
+#define INT_MASK_CSR 0x204
+#ifdef RT_BIG_ENDIAN
+typedef union _INT_MASK_CSR_STRUC {
+ struct {
+ UINT32 TxCoherent:1;
+ UINT32 RxCoherent:1;
+ UINT32 :20;
+ UINT32 MCUCommandINT:1;
+ UINT32 MgmtDmaDone:1;
+ UINT32 HccaDmaDone:1;
+ UINT32 Ac3DmaDone:1;
+ UINT32 Ac2DmaDone:1;
+ UINT32 Ac1DmaDone:1;
+ UINT32 Ac0DmaDone:1;
+ UINT32 RxDone:1;
+ UINT32 TxDelay:1;
+ UINT32 RXDelay_INT_MSK:1;
+ } field;
+ UINT32 word;
+}INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
+#else
+typedef union _INT_MASK_CSR_STRUC {
+ struct {
+ UINT32 RXDelay_INT_MSK:1;
+ UINT32 TxDelay:1;
+ UINT32 RxDone:1;
+ UINT32 Ac0DmaDone:1;
+ UINT32 Ac1DmaDone:1;
+ UINT32 Ac2DmaDone:1;
+ UINT32 Ac3DmaDone:1;
+ UINT32 HccaDmaDone:1;
+ UINT32 MgmtDmaDone:1;
+ UINT32 MCUCommandINT:1;
+ UINT32 :20;
+ UINT32 RxCoherent:1;
+ UINT32 TxCoherent:1;
+ } field;
+ UINT32 word;
+} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
+#endif
+#define WPDMA_GLO_CFG 0x208
+#ifdef RT_BIG_ENDIAN
+typedef union _WPDMA_GLO_CFG_STRUC {
+ struct {
+ UINT32 HDR_SEG_LEN:16;
+ UINT32 RXHdrScater:8;
+ UINT32 BigEndian:1;
+ UINT32 EnTXWriteBackDDONE:1;
+ UINT32 WPDMABurstSIZE:2;
+ UINT32 RxDMABusy:1;
+ UINT32 EnableRxDMA:1;
+ UINT32 TxDMABusy:1;
+ UINT32 EnableTxDMA:1;
+ } field;
+ UINT32 word;
+}WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
+#else
+typedef union _WPDMA_GLO_CFG_STRUC {
+ struct {
+ UINT32 EnableTxDMA:1;
+ UINT32 TxDMABusy:1;
+ UINT32 EnableRxDMA:1;
+ UINT32 RxDMABusy:1;
+ UINT32 WPDMABurstSIZE:2;
+ UINT32 EnTXWriteBackDDONE:1;
+ UINT32 BigEndian:1;
+ UINT32 RXHdrScater:8;
+ UINT32 HDR_SEG_LEN:16;
+ } field;
+ UINT32 word;
+} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
+#endif
+#define WPDMA_RST_IDX 0x20c
+#ifdef RT_BIG_ENDIAN
+typedef union _WPDMA_RST_IDX_STRUC {
+ struct {
+ UINT32 :15;
+ UINT32 RST_DRX_IDX0:1;
+ UINT32 rsv:10;
+ UINT32 RST_DTX_IDX5:1;
+ UINT32 RST_DTX_IDX4:1;
+ UINT32 RST_DTX_IDX3:1;
+ UINT32 RST_DTX_IDX2:1;
+ UINT32 RST_DTX_IDX1:1;
+ UINT32 RST_DTX_IDX0:1;
+ } field;
+ UINT32 word;
+}WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
+#else
+typedef union _WPDMA_RST_IDX_STRUC {
+ struct {
+ UINT32 RST_DTX_IDX0:1;
+ UINT32 RST_DTX_IDX1:1;
+ UINT32 RST_DTX_IDX2:1;
+ UINT32 RST_DTX_IDX3:1;
+ UINT32 RST_DTX_IDX4:1;
+ UINT32 RST_DTX_IDX5:1;
+ UINT32 rsv:10;
+ UINT32 RST_DRX_IDX0:1;
+ UINT32 :15;
+ } field;
+ UINT32 word;
+} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
+#endif
+#define DELAY_INT_CFG 0x0210
+#ifdef RT_BIG_ENDIAN
+typedef union _DELAY_INT_CFG_STRUC {
+ struct {
+ UINT32 TXDLY_INT_EN:1;
+ UINT32 TXMAX_PINT:7;
+ UINT32 TXMAX_PTIME:8;
+ UINT32 RXDLY_INT_EN:1;
+ UINT32 RXMAX_PINT:7;
+ UINT32 RXMAX_PTIME:8;
+ } field;
+ UINT32 word;
+}DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
+#else
+typedef union _DELAY_INT_CFG_STRUC {
+ struct {
+ UINT32 RXMAX_PTIME:8;
+ UINT32 RXMAX_PINT:7;
+ UINT32 RXDLY_INT_EN:1;
+ UINT32 TXMAX_PTIME:8;
+ UINT32 TXMAX_PINT:7;
+ UINT32 TXDLY_INT_EN:1;
+ } field;
+ UINT32 word;
+} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
+#endif
+#define WMM_AIFSN_CFG 0x0214
+#ifdef RT_BIG_ENDIAN
+typedef union _AIFSN_CSR_STRUC {
+ struct {
+ UINT32 Rsv:16;
+ UINT32 Aifsn3:4; // for AC_VO
+ UINT32 Aifsn2:4; // for AC_VI
+ UINT32 Aifsn1:4; // for AC_BK
+ UINT32 Aifsn0:4; // for AC_BE
+ } field;
+ UINT32 word;
+} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
+#else
+typedef union _AIFSN_CSR_STRUC {
+ struct {
+ UINT32 Aifsn0:4; // for AC_BE
+ UINT32 Aifsn1:4; // for AC_BK
+ UINT32 Aifsn2:4; // for AC_VI
+ UINT32 Aifsn3:4; // for AC_VO
+ UINT32 Rsv:16;
+ } field;
+ UINT32 word;
+} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
+#endif
+//
+// CWMIN_CSR: CWmin for each EDCA AC
+//
+#define WMM_CWMIN_CFG 0x0218
+#ifdef RT_BIG_ENDIAN
+typedef union _CWMIN_CSR_STRUC {
+ struct {
+ UINT32 Rsv:16;
+ UINT32 Cwmin3:4; // for AC_VO
+ UINT32 Cwmin2:4; // for AC_VI
+ UINT32 Cwmin1:4; // for AC_BK
+ UINT32 Cwmin0:4; // for AC_BE
+ } field;
+ UINT32 word;
+} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
+#else
+typedef union _CWMIN_CSR_STRUC {
+ struct {
+ UINT32 Cwmin0:4; // for AC_BE
+ UINT32 Cwmin1:4; // for AC_BK
+ UINT32 Cwmin2:4; // for AC_VI
+ UINT32 Cwmin3:4; // for AC_VO
+ UINT32 Rsv:16;
+ } field;
+ UINT32 word;
+} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
+#endif
+
+//
+// CWMAX_CSR: CWmin for each EDCA AC
+//
+#define WMM_CWMAX_CFG 0x021c
+#ifdef RT_BIG_ENDIAN
+typedef union _CWMAX_CSR_STRUC {
+ struct {
+ UINT32 Rsv:16;
+ UINT32 Cwmax3:4; // for AC_VO
+ UINT32 Cwmax2:4; // for AC_VI
+ UINT32 Cwmax1:4; // for AC_BK
+ UINT32 Cwmax0:4; // for AC_BE
+ } field;
+ UINT32 word;
+} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
+#else
+typedef union _CWMAX_CSR_STRUC {
+ struct {
+ UINT32 Cwmax0:4; // for AC_BE
+ UINT32 Cwmax1:4; // for AC_BK
+ UINT32 Cwmax2:4; // for AC_VI
+ UINT32 Cwmax3:4; // for AC_VO
+ UINT32 Rsv:16;
+ } field;
+ UINT32 word;
+} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
+#endif
+
+
+//
+// AC_TXOP_CSR0: AC_BK/AC_BE TXOP register
+//
+#define WMM_TXOP0_CFG 0x0220
+#ifdef RT_BIG_ENDIAN
+typedef union _AC_TXOP_CSR0_STRUC {
+ struct {
+ USHORT Ac1Txop; // for AC_BE, in unit of 32us
+ USHORT Ac0Txop; // for AC_BK, in unit of 32us
+ } field;
+ UINT32 word;
+} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
+#else
+typedef union _AC_TXOP_CSR0_STRUC {
+ struct {
+ USHORT Ac0Txop; // for AC_BK, in unit of 32us
+ USHORT Ac1Txop; // for AC_BE, in unit of 32us
+ } field;
+ UINT32 word;
+} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
+#endif
+
+//
+// AC_TXOP_CSR1: AC_VO/AC_VI TXOP register
+//
+#define WMM_TXOP1_CFG 0x0224
+#ifdef RT_BIG_ENDIAN
+typedef union _AC_TXOP_CSR1_STRUC {
+ struct {
+ USHORT Ac3Txop; // for AC_VO, in unit of 32us
+ USHORT Ac2Txop; // for AC_VI, in unit of 32us
+ } field;
+ UINT32 word;
+} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
+#else
+typedef union _AC_TXOP_CSR1_STRUC {
+ struct {
+ USHORT Ac2Txop; // for AC_VI, in unit of 32us
+ USHORT Ac3Txop; // for AC_VO, in unit of 32us
+ } field;
+ UINT32 word;
+} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
+#endif
+#define RINGREG_DIFF 0x10
+#define GPIO_CTRL_CFG 0x0228 //MAC_CSR13
+#define MCU_CMD_CFG 0x022c
+#define TX_BASE_PTR0 0x0230 //AC_BK base address
+#define TX_MAX_CNT0 0x0234
+#define TX_CTX_IDX0 0x0238
+#define TX_DTX_IDX0 0x023c
+#define TX_BASE_PTR1 0x0240 //AC_BE base address
+#define TX_MAX_CNT1 0x0244
+#define TX_CTX_IDX1 0x0248
+#define TX_DTX_IDX1 0x024c
+#define TX_BASE_PTR2 0x0250 //AC_VI base address
+#define TX_MAX_CNT2 0x0254
+#define TX_CTX_IDX2 0x0258
+#define TX_DTX_IDX2 0x025c
+#define TX_BASE_PTR3 0x0260 //AC_VO base address
+#define TX_MAX_CNT3 0x0264
+#define TX_CTX_IDX3 0x0268
+#define TX_DTX_IDX3 0x026c
+#define TX_BASE_PTR4 0x0270 //HCCA base address
+#define TX_MAX_CNT4 0x0274
+#define TX_CTX_IDX4 0x0278
+#define TX_DTX_IDX4 0x027c
+#define TX_BASE_PTR5 0x0280 //MGMT base address
+#define TX_MAX_CNT5 0x0284
+#define TX_CTX_IDX5 0x0288
+#define TX_DTX_IDX5 0x028c
+#define TX_MGMTMAX_CNT TX_MAX_CNT5
+#define TX_MGMTCTX_IDX TX_CTX_IDX5
+#define TX_MGMTDTX_IDX TX_DTX_IDX5
+#define RX_BASE_PTR 0x0290 //RX base address
+#define RX_MAX_CNT 0x0294
+#define RX_CRX_IDX 0x0298
+#define RX_DRX_IDX 0x029c
+#define USB_DMA_CFG 0x02a0
+#ifdef RT_BIG_ENDIAN
+typedef union _USB_DMA_CFG_STRUC {
+ struct {
+ UINT32 TxBusy:1; //USB DMA TX FSM busy . debug only
+ UINT32 RxBusy:1; //USB DMA RX FSM busy . debug only
+ UINT32 EpoutValid:6; //OUT endpoint data valid. debug only
+ UINT32 TxBulkEn:1; //Enable USB DMA Tx
+ UINT32 RxBulkEn:1; //Enable USB DMA Rx
+ UINT32 RxBulkAggEn:1; //Enable Rx Bulk Aggregation
+ UINT32 TxopHalt:1; //Halt TXOP count down when TX buffer is full.
+ UINT32 TxClear:1; //Clear USB DMA TX path
+ UINT32 rsv:2;
+ UINT32 phyclear:1; //phy watch dog enable. write 1
+ UINT32 RxBulkAggLmt:8; //Rx Bulk Aggregation Limit in unit of 1024 bytes
+ UINT32 RxBulkAggTOut:8; //Rx Bulk Aggregation TimeOut in unit of 33ns
+ } field;
+ UINT32 word;
+} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
+#else
+typedef union _USB_DMA_CFG_STRUC {
+ struct {
+ UINT32 RxBulkAggTOut:8; //Rx Bulk Aggregation TimeOut in unit of 33ns
+ UINT32 RxBulkAggLmt:8; //Rx Bulk Aggregation Limit in unit of 256 bytes
+ UINT32 phyclear:1; //phy watch dog enable. write 1
+ UINT32 rsv:2;
+ UINT32 TxClear:1; //Clear USB DMA TX path
+ UINT32 TxopHalt:1; //Halt TXOP count down when TX buffer is full.
+ UINT32 RxBulkAggEn:1; //Enable Rx Bulk Aggregation
+ UINT32 RxBulkEn:1; //Enable USB DMA Rx
+ UINT32 TxBulkEn:1; //Enable USB DMA Tx
+ UINT32 EpoutValid:6; //OUT endpoint data valid
+ UINT32 RxBusy:1; //USB DMA RX FSM busy
+ UINT32 TxBusy:1; //USB DMA TX FSM busy
+ } field;
+ UINT32 word;
+} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
+#endif
+
+//
+// 3 PBF registers
+//
+//
+// Most are for debug. Driver doesn't touch PBF register.
+#define PBF_SYS_CTRL 0x0400
+#define PBF_CFG 0x0408
+#define PBF_MAX_PCNT 0x040C
+#define PBF_CTRL 0x0410
+#define PBF_INT_STA 0x0414
+#define PBF_INT_ENA 0x0418
+#define TXRXQ_PCNT 0x0438
+#define PBF_DBG 0x043c
+#define PBF_CAP_CTRL 0x0440
+
+
+// eFuse registers
+#define EFUSE_CTRL 0x0580
+#define EFUSE_DATA0 0x0590
+#define EFUSE_DATA1 0x0594
+#define EFUSE_DATA2 0x0598
+#define EFUSE_DATA3 0x059c
+#define EFUSE_USAGE_MAP_START 0x2d0
+#define EFUSE_USAGE_MAP_END 0x2fc
+#define EFUSE_TAG 0x2fe
+#define EFUSE_USAGE_MAP_SIZE 45
+
+#ifdef RT_BIG_ENDIAN
+typedef union _EFUSE_CTRL_STRUC {
+ struct {
+ UINT32 SEL_EFUSE:1;
+ UINT32 EFSROM_KICK:1;
+ UINT32 RESERVED:4;
+ UINT32 EFSROM_AIN:10;
+ UINT32 EFSROM_LDO_ON_TIME:2;
+ UINT32 EFSROM_LDO_OFF_TIME:6;
+ UINT32 EFSROM_MODE:2;
+ UINT32 EFSROM_AOUT:6;
+ } field;
+ UINT32 word;
+} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
+#else
+typedef union _EFUSE_CTRL_STRUC {
+ struct {
+ UINT32 EFSROM_AOUT:6;
+ UINT32 EFSROM_MODE:2;
+ UINT32 EFSROM_LDO_OFF_TIME:6;
+ UINT32 EFSROM_LDO_ON_TIME:2;
+ UINT32 EFSROM_AIN:10;
+ UINT32 RESERVED:4;
+ UINT32 EFSROM_KICK:1;
+ UINT32 SEL_EFUSE:1;
+ } field;
+ UINT32 word;
+} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
+#endif // RT_BIG_ENDIAN //
+
+#define LDO_CFG0 0x05d4
+#define GPIO_SWITCH 0x05dc
+
+//
+// 4 MAC registers
+//
+//
+// 4.1 MAC SYSTEM configuration registers (offset:0x1000)
+//
+#define MAC_CSR0 0x1000
+#ifdef RT_BIG_ENDIAN
+typedef union _ASIC_VER_ID_STRUC {
+ struct {
+ USHORT ASICVer; // version : 2860
+ USHORT ASICRev; // reversion : 0
+ } field;
+ UINT32 word;
+} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
+#else
+typedef union _ASIC_VER_ID_STRUC {
+ struct {
+ USHORT ASICRev; // reversion : 0
+ USHORT ASICVer; // version : 2860
+ } field;
+ UINT32 word;
+} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
+#endif
+#define MAC_SYS_CTRL 0x1004 //MAC_CSR1
+#define MAC_ADDR_DW0 0x1008 // MAC ADDR DW0
+#define MAC_ADDR_DW1 0x100c // MAC ADDR DW1
+//
+// MAC_CSR2: STA MAC register 0
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _MAC_DW0_STRUC {
+ struct {
+ UCHAR Byte3; // MAC address byte 3
+ UCHAR Byte2; // MAC address byte 2
+ UCHAR Byte1; // MAC address byte 1
+ UCHAR Byte0; // MAC address byte 0
+ } field;
+ UINT32 word;
+} MAC_DW0_STRUC, *PMAC_DW0_STRUC;
+#else
+typedef union _MAC_DW0_STRUC {
+ struct {
+ UCHAR Byte0; // MAC address byte 0
+ UCHAR Byte1; // MAC address byte 1
+ UCHAR Byte2; // MAC address byte 2
+ UCHAR Byte3; // MAC address byte 3
+ } field;
+ UINT32 word;
+} MAC_DW0_STRUC, *PMAC_DW0_STRUC;
+#endif
+
+//
+// MAC_CSR3: STA MAC register 1
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _MAC_DW1_STRUC {
+ struct {
+ UCHAR Rsvd1;
+ UCHAR U2MeMask;
+ UCHAR Byte5; // MAC address byte 5
+ UCHAR Byte4; // MAC address byte 4
+ } field;
+ UINT32 word;
+} MAC_DW1_STRUC, *PMAC_DW1_STRUC;
+#else
+typedef union _MAC_DW1_STRUC {
+ struct {
+ UCHAR Byte4; // MAC address byte 4
+ UCHAR Byte5; // MAC address byte 5
+ UCHAR U2MeMask;
+ UCHAR Rsvd1;
+ } field;
+ UINT32 word;
+} MAC_DW1_STRUC, *PMAC_DW1_STRUC;
+#endif
+
+#define MAC_BSSID_DW0 0x1010 // MAC BSSID DW0
+#define MAC_BSSID_DW1 0x1014 // MAC BSSID DW1
+
+//
+// MAC_CSR5: BSSID register 1
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _MAC_CSR5_STRUC {
+ struct {
+ USHORT Rsvd:11;
+ USHORT MBssBcnNum:3;
+ USHORT BssIdMode:2; // 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID
+ UCHAR Byte5; // BSSID byte 5
+ UCHAR Byte4; // BSSID byte 4
+ } field;
+ UINT32 word;
+} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
+#else
+typedef union _MAC_CSR5_STRUC {
+ struct {
+ UCHAR Byte4; // BSSID byte 4
+ UCHAR Byte5; // BSSID byte 5
+ USHORT BssIdMask:2; // 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID
+ USHORT MBssBcnNum:3;
+ USHORT Rsvd:11;
+ } field;
+ UINT32 word;
+} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
+#endif
+
+#define MAX_LEN_CFG 0x1018 // rt2860b max 16k bytes. bit12:13 Maximum PSDU length (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16
+#define BBP_CSR_CFG 0x101c //
+//
+// BBP_CSR_CFG: BBP serial control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _BBP_CSR_CFG_STRUC {
+ struct {
+ UINT32 :12;
+ UINT32 BBP_RW_MODE:1; // 0: use serial mode 1:parallel
+ UINT32 BBP_PAR_DUR:1; // 0: 4 MAC clock cycles 1: 8 MAC clock cycles
+ UINT32 Busy:1; // 1: ASIC is busy execute BBP programming.
+ UINT32 fRead:1; // 0: Write BBP, 1: Read BBP
+ UINT32 RegNum:8; // Selected BBP register
+ UINT32 Value:8; // Register value to program into BBP
+ } field;
+ UINT32 word;
+} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
+#else
+typedef union _BBP_CSR_CFG_STRUC {
+ struct {
+ UINT32 Value:8; // Register value to program into BBP
+ UINT32 RegNum:8; // Selected BBP register
+ UINT32 fRead:1; // 0: Write BBP, 1: Read BBP
+ UINT32 Busy:1; // 1: ASIC is busy execute BBP programming.
+ UINT32 BBP_PAR_DUR:1; // 0: 4 MAC clock cycles 1: 8 MAC clock cycles
+ UINT32 BBP_RW_MODE:1; // 0: use serial mode 1:parallel
+ UINT32 :12;
+ } field;
+ UINT32 word;
+} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
+#endif
+#define RF_CSR_CFG0 0x1020
+//
+// RF_CSR_CFG: RF control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _RF_CSR_CFG0_STRUC {
+ struct {
+ UINT32 Busy:1; // 0: idle 1: 8busy
+ UINT32 Sel:1; // 0:RF_LE0 activate 1:RF_LE1 activate
+ UINT32 StandbyMode:1; // 0: high when stand by 1: low when standby
+ UINT32 bitwidth:5; // Selected BBP register
+ UINT32 RegIdAndContent:24; // Register value to program into BBP
+ } field;
+ UINT32 word;
+} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
+#else
+typedef union _RF_CSR_CFG0_STRUC {
+ struct {
+ UINT32 RegIdAndContent:24; // Register value to program into BBP
+ UINT32 bitwidth:5; // Selected BBP register
+ UINT32 StandbyMode:1; // 0: high when stand by 1: low when standby
+ UINT32 Sel:1; // 0:RF_LE0 activate 1:RF_LE1 activate
+ UINT32 Busy:1; // 0: idle 1: 8busy
+ } field;
+ UINT32 word;
+} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
+#endif
+#define RF_CSR_CFG1 0x1024
+#ifdef RT_BIG_ENDIAN
+typedef union _RF_CSR_CFG1_STRUC {
+ struct {
+ UINT32 rsv:7; // 0: idle 1: 8busy
+ UINT32 RFGap:5; // Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec)
+ UINT32 RegIdAndContent:24; // Register value to program into BBP
+ } field;
+ UINT32 word;
+} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
+#else
+typedef union _RF_CSR_CFG1_STRUC {
+ struct {
+ UINT32 RegIdAndContent:24; // Register value to program into BBP
+ UINT32 RFGap:5; // Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec)
+ UINT32 rsv:7; // 0: idle 1: 8busy
+ } field;
+ UINT32 word;
+} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
+#endif
+#define RF_CSR_CFG2 0x1028 //
+#ifdef RT_BIG_ENDIAN
+typedef union _RF_CSR_CFG2_STRUC {
+ struct {
+ UINT32 rsv:8; // 0: idle 1: 8busy
+ UINT32 RegIdAndContent:24; // Register value to program into BBP
+ } field;
+ UINT32 word;
+} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
+#else
+typedef union _RF_CSR_CFG2_STRUC {
+ struct {
+ UINT32 RegIdAndContent:24; // Register value to program into BBP
+ UINT32 rsv:8; // 0: idle 1: 8busy
+ } field;
+ UINT32 word;
+} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
+#endif
+#define LED_CFG 0x102c // MAC_CSR14
+#ifdef RT_BIG_ENDIAN
+typedef union _LED_CFG_STRUC {
+ struct {
+ UINT32 :1;
+ UINT32 LedPolar:1; // Led Polarity. 0: active low1: active high
+ UINT32 YLedMode:2; // yellow Led Mode
+ UINT32 GLedMode:2; // green Led Mode
+ UINT32 RLedMode:2; // red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on
+ UINT32 rsv:2;
+ UINT32 SlowBlinkPeriod:6; // slow blinking period. unit:1ms
+ UINT32 OffPeriod:8; // blinking off period unit 1ms
+ UINT32 OnPeriod:8; // blinking on period unit 1ms
+ } field;
+ UINT32 word;
+} LED_CFG_STRUC, *PLED_CFG_STRUC;
+#else
+typedef union _LED_CFG_STRUC {
+ struct {
+ UINT32 OnPeriod:8; // blinking on period unit 1ms
+ UINT32 OffPeriod:8; // blinking off period unit 1ms
+ UINT32 SlowBlinkPeriod:6; // slow blinking period. unit:1ms
+ UINT32 rsv:2;
+ UINT32 RLedMode:2; // red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on
+ UINT32 GLedMode:2; // green Led Mode
+ UINT32 YLedMode:2; // yellow Led Mode
+ UINT32 LedPolar:1; // Led Polarity. 0: active low1: active high
+ UINT32 :1;
+ } field;
+ UINT32 word;
+} LED_CFG_STRUC, *PLED_CFG_STRUC;
+#endif
+//
+// 4.2 MAC TIMING configuration registers (offset:0x1100)
+//
+#define XIFS_TIME_CFG 0x1100 // MAC_CSR8 MAC_CSR9
+#ifdef RT_BIG_ENDIAN
+typedef union _IFS_SLOT_CFG_STRUC {
+ struct {
+ UINT32 rsv:2;
+ UINT32 BBRxendEnable:1; // reference RXEND signal to begin XIFS defer
+ UINT32 EIFS:9; // unit 1us
+ UINT32 OfdmXifsTime:4; //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
+ UINT32 OfdmSifsTime:8; // unit 1us. Applied after OFDM RX/TX
+ UINT32 CckmSifsTime:8; // unit 1us. Applied after CCK RX/TX
+ } field;
+ UINT32 word;
+} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
+#else
+typedef union _IFS_SLOT_CFG_STRUC {
+ struct {
+ UINT32 CckmSifsTime:8; // unit 1us. Applied after CCK RX/TX
+ UINT32 OfdmSifsTime:8; // unit 1us. Applied after OFDM RX/TX
+ UINT32 OfdmXifsTime:4; //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
+ UINT32 EIFS:9; // unit 1us
+ UINT32 BBRxendEnable:1; // reference RXEND signal to begin XIFS defer
+ UINT32 rsv:2;
+ } field;
+ UINT32 word;
+} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
+#endif
+
+#define BKOFF_SLOT_CFG 0x1104 // mac_csr9 last 8 bits
+#define NAV_TIME_CFG 0x1108 // NAV (MAC_CSR15)
+#define CH_TIME_CFG 0x110C // Count as channel busy
+#define PBF_LIFE_TIMER 0x1110 //TX/RX MPDU timestamp timer (free run)Unit: 1us
+#define BCN_TIME_CFG 0x1114 // TXRX_CSR9
+
+#define BCN_OFFSET0 0x042C
+#define BCN_OFFSET1 0x0430
+
+//
+// BCN_TIME_CFG : Synchronization control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _BCN_TIME_CFG_STRUC {
+ struct {
+ UINT32 TxTimestampCompensate:8;
+ UINT32 :3;
+ UINT32 bBeaconGen:1; // Enable beacon generator
+ UINT32 bTBTTEnable:1;
+ UINT32 TsfSyncMode:2; // Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
+ UINT32 bTsfTicking:1; // Enable TSF auto counting
+ UINT32 BeaconInterval:16; // in unit of 1/16 TU
+ } field;
+ UINT32 word;
+} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
+#else
+typedef union _BCN_TIME_CFG_STRUC {
+ struct {
+ UINT32 BeaconInterval:16; // in unit of 1/16 TU
+ UINT32 bTsfTicking:1; // Enable TSF auto counting
+ UINT32 TsfSyncMode:2; // Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
+ UINT32 bTBTTEnable:1;
+ UINT32 bBeaconGen:1; // Enable beacon generator
+ UINT32 :3;
+ UINT32 TxTimestampCompensate:8;
+ } field;
+ UINT32 word;
+} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
+#endif
+#define TBTT_SYNC_CFG 0x1118 // txrx_csr10
+#define TSF_TIMER_DW0 0x111C // Local TSF timer lsb 32 bits. Read-only
+#define TSF_TIMER_DW1 0x1120 // msb 32 bits. Read-only.
+#define TBTT_TIMER 0x1124 // TImer remains till next TBTT. Read-only. TXRX_CSR14
+#define INT_TIMER_CFG 0x1128 //
+#define INT_TIMER_EN 0x112c // GP-timer and pre-tbtt Int enable
+#define CH_IDLE_STA 0x1130 // channel idle time
+#define CH_BUSY_STA 0x1134 // channle busy time
+//
+// 4.2 MAC POWER configuration registers (offset:0x1200)
+//
+#define MAC_STATUS_CFG 0x1200 // old MAC_CSR12
+#define PWR_PIN_CFG 0x1204 // old MAC_CSR12
+#define AUTO_WAKEUP_CFG 0x1208 // old MAC_CSR10
+//
+// AUTO_WAKEUP_CFG: Manual power control / status register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _AUTO_WAKEUP_STRUC {
+ struct {
+ UINT32 :16;
+ UINT32 EnableAutoWakeup:1; // 0:sleep, 1:awake
+ UINT32 NumofSleepingTbtt:7; // ForceWake has high privilege than PutToSleep when both set
+ UINT32 AutoLeadTime:8;
+ } field;
+ UINT32 word;
+} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
+#else
+typedef union _AUTO_WAKEUP_STRUC {
+ struct {
+ UINT32 AutoLeadTime:8;
+ UINT32 NumofSleepingTbtt:7; // ForceWake has high privilege than PutToSleep when both set
+ UINT32 EnableAutoWakeup:1; // 0:sleep, 1:awake
+ UINT32 :16;
+ } field;
+ UINT32 word;
+} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
+#endif
+//
+// 4.3 MAC TX configuration registers (offset:0x1300)
+//
+
+#define EDCA_AC0_CFG 0x1300 //AC_TXOP_CSR0 0x3474
+#define EDCA_AC1_CFG 0x1304
+#define EDCA_AC2_CFG 0x1308
+#define EDCA_AC3_CFG 0x130c
+#ifdef RT_BIG_ENDIAN
+typedef union _EDCA_AC_CFG_STRUC {
+ struct {
+ UINT32 :12; //
+ UINT32 Cwmax:4; //unit power of 2
+ UINT32 Cwmin:4; //
+ UINT32 Aifsn:4; // # of slot time
+ UINT32 AcTxop:8; // in unit of 32us
+ } field;
+ UINT32 word;
+} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
+#else
+typedef union _EDCA_AC_CFG_STRUC {
+ struct {
+ UINT32 AcTxop:8; // in unit of 32us
+ UINT32 Aifsn:4; // # of slot time
+ UINT32 Cwmin:4; //
+ UINT32 Cwmax:4; //unit power of 2
+ UINT32 :12; //
+ } field;
+ UINT32 word;
+} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
+#endif
+
+#define EDCA_TID_AC_MAP 0x1310
+#define TX_PWR_CFG_0 0x1314
+#define TX_PWR_CFG_1 0x1318
+#define TX_PWR_CFG_2 0x131C
+#define TX_PWR_CFG_3 0x1320
+#define TX_PWR_CFG_4 0x1324
+#define TX_PIN_CFG 0x1328
+#define TX_BAND_CFG 0x132c // 0x1 use upper 20MHz. 0 juse lower 20MHz
+#define TX_SW_CFG0 0x1330
+#define TX_SW_CFG1 0x1334
+#define TX_SW_CFG2 0x1338
+#define TXOP_THRES_CFG 0x133c
+#define TXOP_CTRL_CFG 0x1340
+#define TX_RTS_CFG 0x1344
+
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_RTS_CFG_STRUC {
+ struct {
+ UINT32 rsv:7;
+ UINT32 RtsFbkEn:1; // enable rts rate fallback
+ UINT32 RtsThres:16; // unit:byte
+ UINT32 AutoRtsRetryLimit:8;
+ } field;
+ UINT32 word;
+} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
+#else
+typedef union _TX_RTS_CFG_STRUC {
+ struct {
+ UINT32 AutoRtsRetryLimit:8;
+ UINT32 RtsThres:16; // unit:byte
+ UINT32 RtsFbkEn:1; // enable rts rate fallback
+ UINT32 rsv:7; // 1: HT non-STBC control frame enable
+ } field;
+ UINT32 word;
+} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
+#endif
+#define TX_TIMEOUT_CFG 0x1348
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_TIMEOUT_CFG_STRUC {
+ struct {
+ UINT32 rsv2:8;
+ UINT32 TxopTimeout:8; //TXOP timeout value for TXOP truncation. It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
+ UINT32 RxAckTimeout:8; // unit:slot. Used for TX precedure
+ UINT32 MpduLifeTime:4; // expiration time = 2^(9+MPDU LIFE TIME) us
+ UINT32 rsv:4;
+ } field;
+ UINT32 word;
+} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
+#else
+typedef union _TX_TIMEOUT_CFG_STRUC {
+ struct {
+ UINT32 rsv:4;
+ UINT32 MpduLifeTime:4; // expiration time = 2^(9+MPDU LIFE TIME) us
+ UINT32 RxAckTimeout:8; // unit:slot. Used for TX precedure
+ UINT32 TxopTimeout:8; //TXOP timeout value for TXOP truncation. It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
+ UINT32 rsv2:8; // 1: HT non-STBC control frame enable
+ } field;
+ UINT32 word;
+} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
+#endif
+#define TX_RTY_CFG 0x134c
+#ifdef RT_BIG_ENDIAN
+typedef union PACKED _TX_RTY_CFG_STRUC {
+ struct {
+ UINT32 rsv:1;
+ UINT32 TxautoFBEnable:1; // Tx retry PHY rate auto fallback enable
+ UINT32 AggRtyMode:1; // Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
+ UINT32 NonAggRtyMode:1; // Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
+ UINT32 LongRtyThre:12; // Long retry threshoold
+ UINT32 LongRtyLimit:8; //long retry limit
+ UINT32 ShortRtyLimit:8; // short retry limit
+
+ } field;
+ UINT32 word;
+} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
+#else
+typedef union PACKED _TX_RTY_CFG_STRUC {
+ struct {
+ UINT32 ShortRtyLimit:8; // short retry limit
+ UINT32 LongRtyLimit:8; //long retry limit
+ UINT32 LongRtyThre:12; // Long retry threshoold
+ UINT32 NonAggRtyMode:1; // Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
+ UINT32 AggRtyMode:1; // Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
+ UINT32 TxautoFBEnable:1; // Tx retry PHY rate auto fallback enable
+ UINT32 rsv:1; // 1: HT non-STBC control frame enable
+ } field;
+ UINT32 word;
+} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
+#endif
+#define TX_LINK_CFG 0x1350
+#ifdef RT_BIG_ENDIAN
+typedef union PACKED _TX_LINK_CFG_STRUC {
+ struct PACKED {
+ UINT32 RemotMFS:8; //remote MCS feedback sequence number
+ UINT32 RemotMFB:8; // remote MCS feedback
+ UINT32 rsv:3; //
+ UINT32 TxCFAckEn:1; // Piggyback CF-ACK enable
+ UINT32 TxRDGEn:1; // RDG TX enable
+ UINT32 TxMRQEn:1; // MCS request TX enable
+ UINT32 RemoteUMFSEnable:1; // remote unsolicit MFB enable. 0: not apply remote remote unsolicit (MFS=7)
+ UINT32 MFBEnable:1; // TX apply remote MFB 1:enable
+ UINT32 RemoteMFBLifeTime:8; //remote MFB life time. unit : 32us
+ } field;
+ UINT32 word;
+} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
+#else
+typedef union PACKED _TX_LINK_CFG_STRUC {
+ struct PACKED {
+ UINT32 RemoteMFBLifeTime:8; //remote MFB life time. unit : 32us
+ UINT32 MFBEnable:1; // TX apply remote MFB 1:enable
+ UINT32 RemoteUMFSEnable:1; // remote unsolicit MFB enable. 0: not apply remote remote unsolicit (MFS=7)
+ UINT32 TxMRQEn:1; // MCS request TX enable
+ UINT32 TxRDGEn:1; // RDG TX enable
+ UINT32 TxCFAckEn:1; // Piggyback CF-ACK enable
+ UINT32 rsv:3; //
+ UINT32 RemotMFB:8; // remote MCS feedback
+ UINT32 RemotMFS:8; //remote MCS feedback sequence number
+ } field;
+ UINT32 word;
+} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
+#endif
+#define HT_FBK_CFG0 0x1354
+#ifdef RT_BIG_ENDIAN
+typedef union PACKED _HT_FBK_CFG0_STRUC {
+ struct {
+ UINT32 HTMCS7FBK:4;
+ UINT32 HTMCS6FBK:4;
+ UINT32 HTMCS5FBK:4;
+ UINT32 HTMCS4FBK:4;
+ UINT32 HTMCS3FBK:4;
+ UINT32 HTMCS2FBK:4;
+ UINT32 HTMCS1FBK:4;
+ UINT32 HTMCS0FBK:4;
+ } field;
+ UINT32 word;
+} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
+#else
+typedef union PACKED _HT_FBK_CFG0_STRUC {
+ struct {
+ UINT32 HTMCS0FBK:4;
+ UINT32 HTMCS1FBK:4;
+ UINT32 HTMCS2FBK:4;
+ UINT32 HTMCS3FBK:4;
+ UINT32 HTMCS4FBK:4;
+ UINT32 HTMCS5FBK:4;
+ UINT32 HTMCS6FBK:4;
+ UINT32 HTMCS7FBK:4;
+ } field;
+ UINT32 word;
+} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
+#endif
+#define HT_FBK_CFG1 0x1358
+#ifdef RT_BIG_ENDIAN
+typedef union _HT_FBK_CFG1_STRUC {
+ struct {
+ UINT32 HTMCS15FBK:4;
+ UINT32 HTMCS14FBK:4;
+ UINT32 HTMCS13FBK:4;
+ UINT32 HTMCS12FBK:4;
+ UINT32 HTMCS11FBK:4;
+ UINT32 HTMCS10FBK:4;
+ UINT32 HTMCS9FBK:4;
+ UINT32 HTMCS8FBK:4;
+ } field;
+ UINT32 word;
+} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
+#else
+typedef union _HT_FBK_CFG1_STRUC {
+ struct {
+ UINT32 HTMCS8FBK:4;
+ UINT32 HTMCS9FBK:4;
+ UINT32 HTMCS10FBK:4;
+ UINT32 HTMCS11FBK:4;
+ UINT32 HTMCS12FBK:4;
+ UINT32 HTMCS13FBK:4;
+ UINT32 HTMCS14FBK:4;
+ UINT32 HTMCS15FBK:4;
+ } field;
+ UINT32 word;
+} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
+#endif
+#define LG_FBK_CFG0 0x135c
+#ifdef RT_BIG_ENDIAN
+typedef union _LG_FBK_CFG0_STRUC {
+ struct {
+ UINT32 OFDMMCS7FBK:4; //initial value is 6
+ UINT32 OFDMMCS6FBK:4; //initial value is 5
+ UINT32 OFDMMCS5FBK:4; //initial value is 4
+ UINT32 OFDMMCS4FBK:4; //initial value is 3
+ UINT32 OFDMMCS3FBK:4; //initial value is 2
+ UINT32 OFDMMCS2FBK:4; //initial value is 1
+ UINT32 OFDMMCS1FBK:4; //initial value is 0
+ UINT32 OFDMMCS0FBK:4; //initial value is 0
+ } field;
+ UINT32 word;
+} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
+#else
+typedef union _LG_FBK_CFG0_STRUC {
+ struct {
+ UINT32 OFDMMCS0FBK:4; //initial value is 0
+ UINT32 OFDMMCS1FBK:4; //initial value is 0
+ UINT32 OFDMMCS2FBK:4; //initial value is 1
+ UINT32 OFDMMCS3FBK:4; //initial value is 2
+ UINT32 OFDMMCS4FBK:4; //initial value is 3
+ UINT32 OFDMMCS5FBK:4; //initial value is 4
+ UINT32 OFDMMCS6FBK:4; //initial value is 5
+ UINT32 OFDMMCS7FBK:4; //initial value is 6
+ } field;
+ UINT32 word;
+} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
+#endif
+#define LG_FBK_CFG1 0x1360
+#ifdef RT_BIG_ENDIAN
+typedef union _LG_FBK_CFG1_STRUC {
+ struct {
+ UINT32 rsv:16;
+ UINT32 CCKMCS3FBK:4; //initial value is 2
+ UINT32 CCKMCS2FBK:4; //initial value is 1
+ UINT32 CCKMCS1FBK:4; //initial value is 0
+ UINT32 CCKMCS0FBK:4; //initial value is 0
+ } field;
+ UINT32 word;
+} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
+#else
+typedef union _LG_FBK_CFG1_STRUC {
+ struct {
+ UINT32 CCKMCS0FBK:4; //initial value is 0
+ UINT32 CCKMCS1FBK:4; //initial value is 0
+ UINT32 CCKMCS2FBK:4; //initial value is 1
+ UINT32 CCKMCS3FBK:4; //initial value is 2
+ UINT32 rsv:16;
+ } field;
+ UINT32 word;
+} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
+#endif
+
+//=======================================================
+//================ Protection Paramater================================
+//=======================================================
+#define CCK_PROT_CFG 0x1364 //CCK Protection
+#define ASIC_SHORTNAV 1
+#define ASIC_LONGNAV 2
+#define ASIC_RTS 1
+#define ASIC_CTS 2
+#ifdef RT_BIG_ENDIAN
+typedef union _PROT_CFG_STRUC {
+ struct {
+ UINT32 rsv:5;
+ UINT32 RTSThEn:1; //RTS threshold enable on CCK TX
+ UINT32 TxopAllowGF40:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowGF20:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowMM40:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowMM20:1; //CCK TXOP allowance. 0:disallow.
+ UINT32 TxopAllowOfdm:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowCck:1; //CCK TXOP allowance.0:disallow.
+ UINT32 ProtectNav:2; //TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect, 2:LongNAVProtect, 3:rsv
+ UINT32 ProtectCtrl:2; //Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
+ UINT32 ProtectRate:16; //Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
+ } field;
+ UINT32 word;
+} PROT_CFG_STRUC, *PPROT_CFG_STRUC;
+#else
+typedef union _PROT_CFG_STRUC {
+ struct {
+ UINT32 ProtectRate:16; //Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
+ UINT32 ProtectCtrl:2; //Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
+ UINT32 ProtectNav:2; //TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect, 2:LongNAVProtect, 3:rsv
+ UINT32 TxopAllowCck:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowOfdm:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowMM20:1; //CCK TXOP allowance. 0:disallow.
+ UINT32 TxopAllowMM40:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowGF20:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowGF40:1; //CCK TXOP allowance.0:disallow.
+ UINT32 RTSThEn:1; //RTS threshold enable on CCK TX
+ UINT32 rsv:5;
+ } field;
+ UINT32 word;
+} PROT_CFG_STRUC, *PPROT_CFG_STRUC;
+#endif
+
+#define OFDM_PROT_CFG 0x1368 //OFDM Protection
+#define MM20_PROT_CFG 0x136C //MM20 Protection
+#define MM40_PROT_CFG 0x1370 //MM40 Protection
+#define GF20_PROT_CFG 0x1374 //GF20 Protection
+#define GF40_PROT_CFG 0x1378 //GR40 Protection
+#define EXP_CTS_TIME 0x137C //
+#define EXP_ACK_TIME 0x1380 //
+
+//
+// 4.4 MAC RX configuration registers (offset:0x1400)
+//
+#define RX_FILTR_CFG 0x1400 //TXRX_CSR0
+#define AUTO_RSP_CFG 0x1404 //TXRX_CSR4
+//
+// TXRX_CSR4: Auto-Responder/
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _AUTO_RSP_CFG_STRUC {
+ struct {
+ UINT32 :24;
+ UINT32 AckCtsPsmBit:1; // Power bit value in conrtrol frame
+ UINT32 DualCTSEn:1; // Power bit value in conrtrol frame
+ UINT32 rsv:1; // Power bit value in conrtrol frame
+ UINT32 AutoResponderPreamble:1; // 0:long, 1:short preamble
+ UINT32 CTS40MRef:1; // Response CTS 40MHz duplicate mode
+ UINT32 CTS40MMode:1; // Response CTS 40MHz duplicate mode
+ UINT32 BACAckPolicyEnable:1; // 0:long, 1:short preamble
+ UINT32 AutoResponderEnable:1;
+ } field;
+ UINT32 word;
+} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
+#else
+typedef union _AUTO_RSP_CFG_STRUC {
+ struct {
+ UINT32 AutoResponderEnable:1;
+ UINT32 BACAckPolicyEnable:1; // 0:long, 1:short preamble
+ UINT32 CTS40MMode:1; // Response CTS 40MHz duplicate mode
+ UINT32 CTS40MRef:1; // Response CTS 40MHz duplicate mode
+ UINT32 AutoResponderPreamble:1; // 0:long, 1:short preamble
+ UINT32 rsv:1; // Power bit value in conrtrol frame
+ UINT32 DualCTSEn:1; // Power bit value in conrtrol frame
+ UINT32 AckCtsPsmBit:1; // Power bit value in conrtrol frame
+ UINT32 :24;
+ } field;
+ UINT32 word;
+} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
+#endif
+
+#define LEGACY_BASIC_RATE 0x1408 // TXRX_CSR5 0x3054
+#define HT_BASIC_RATE 0x140c
+#define HT_CTRL_CFG 0x1410
+#define SIFS_COST_CFG 0x1414
+#define RX_PARSER_CFG 0x1418 //Set NAV for all received frames
+
+//
+// 4.5 MAC Security configuration (offset:0x1500)
+//
+#define TX_SEC_CNT0 0x1500 //
+#define RX_SEC_CNT0 0x1504 //
+#define CCMP_FC_MUTE 0x1508 //
+//
+// 4.6 HCCA/PSMP (offset:0x1600)
+//
+#define TXOP_HLDR_ADDR0 0x1600
+#define TXOP_HLDR_ADDR1 0x1604
+#define TXOP_HLDR_ET 0x1608
+#define QOS_CFPOLL_RA_DW0 0x160c
+#define QOS_CFPOLL_A1_DW1 0x1610
+#define QOS_CFPOLL_QC 0x1614
+//
+// 4.7 MAC Statistis registers (offset:0x1700)
+//
+#define RX_STA_CNT0 0x1700 //
+#define RX_STA_CNT1 0x1704 //
+#define RX_STA_CNT2 0x1708 //
+
+//
+// RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _RX_STA_CNT0_STRUC {
+ struct {
+ USHORT PhyErr;
+ USHORT CrcErr;
+ } field;
+ UINT32 word;
+} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
+#else
+typedef union _RX_STA_CNT0_STRUC {
+ struct {
+ USHORT CrcErr;
+ USHORT PhyErr;
+ } field;
+ UINT32 word;
+} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
+#endif
+
+//
+// RX_STA_CNT1_STRUC: RX False CCA count & RX LONG frame count
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _RX_STA_CNT1_STRUC {
+ struct {
+ USHORT PlcpErr;
+ USHORT FalseCca;
+ } field;
+ UINT32 word;
+} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
+#else
+typedef union _RX_STA_CNT1_STRUC {
+ struct {
+ USHORT FalseCca;
+ USHORT PlcpErr;
+ } field;
+ UINT32 word;
+} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
+#endif
+
+//
+// RX_STA_CNT2_STRUC:
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _RX_STA_CNT2_STRUC {
+ struct {
+ USHORT RxFifoOverflowCount;
+ USHORT RxDupliCount;
+ } field;
+ UINT32 word;
+} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
+#else
+typedef union _RX_STA_CNT2_STRUC {
+ struct {
+ USHORT RxDupliCount;
+ USHORT RxFifoOverflowCount;
+ } field;
+ UINT32 word;
+} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
+#endif
+#define TX_STA_CNT0 0x170C //
+//
+// STA_CSR3: TX Beacon count
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_STA_CNT0_STRUC {
+ struct {
+ USHORT TxBeaconCount;
+ USHORT TxFailCount;
+ } field;
+ UINT32 word;
+} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
+#else
+typedef union _TX_STA_CNT0_STRUC {
+ struct {
+ USHORT TxFailCount;
+ USHORT TxBeaconCount;
+ } field;
+ UINT32 word;
+} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
+#endif
+#define TX_STA_CNT1 0x1710 //
+//
+// TX_STA_CNT1: TX tx count
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_STA_CNT1_STRUC {
+ struct {
+ USHORT TxRetransmit;
+ USHORT TxSuccess;
+ } field;
+ UINT32 word;
+} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
+#else
+typedef union _TX_STA_CNT1_STRUC {
+ struct {
+ USHORT TxSuccess;
+ USHORT TxRetransmit;
+ } field;
+ UINT32 word;
+} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
+#endif
+#define TX_STA_CNT2 0x1714 //
+//
+// TX_STA_CNT2: TX tx count
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_STA_CNT2_STRUC {
+ struct {
+ USHORT TxUnderFlowCount;
+ USHORT TxZeroLenCount;
+ } field;
+ UINT32 word;
+} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
+#else
+typedef union _TX_STA_CNT2_STRUC {
+ struct {
+ USHORT TxZeroLenCount;
+ USHORT TxUnderFlowCount;
+ } field;
+ UINT32 word;
+} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
+#endif
+#define TX_STA_FIFO 0x1718 //
+//
+// TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union PACKED _TX_STA_FIFO_STRUC {
+ struct {
+ UINT32 Reserve:2;
+ UINT32 TxBF:1; // 3*3
+ UINT32 SuccessRate:13; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+// UINT32 SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+ UINT32 wcid:8; //wireless client index
+ UINT32 TxAckRequired:1; // ack required
+ UINT32 TxAggre:1; // Tx is aggregated
+ UINT32 TxSuccess:1; // Tx success. whether success or not
+ UINT32 PidType:4;
+ UINT32 bValid:1; // 1:This register contains a valid TX result
+ } field;
+ UINT32 word;
+} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
+#else
+typedef union PACKED _TX_STA_FIFO_STRUC {
+ struct {
+ UINT32 bValid:1; // 1:This register contains a valid TX result
+ UINT32 PidType:4;
+ UINT32 TxSuccess:1; // Tx No retry success
+ UINT32 TxAggre:1; // Tx Retry Success
+ UINT32 TxAckRequired:1; // Tx fail
+ UINT32 wcid:8; //wireless client index
+// UINT32 SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+ UINT32 SuccessRate:13; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+ UINT32 TxBF:1;
+ UINT32 Reserve:2;
+ } field;
+ UINT32 word;
+} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT 0x171c
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT_STRUC {
+ struct {
+ USHORT AggTxCount;
+ USHORT NonAggTxCount;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
+#else
+typedef union _TX_AGG_CNT_STRUC {
+ struct {
+ USHORT NonAggTxCount;
+ USHORT AggTxCount;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT0 0x1720
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT0_STRUC {
+ struct {
+ USHORT AggSize2Count;
+ USHORT AggSize1Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
+#else
+typedef union _TX_AGG_CNT0_STRUC {
+ struct {
+ USHORT AggSize1Count;
+ USHORT AggSize2Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT1 0x1724
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT1_STRUC {
+ struct {
+ USHORT AggSize4Count;
+ USHORT AggSize3Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
+#else
+typedef union _TX_AGG_CNT1_STRUC {
+ struct {
+ USHORT AggSize3Count;
+ USHORT AggSize4Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
+#endif
+#define TX_AGG_CNT2 0x1728
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT2_STRUC {
+ struct {
+ USHORT AggSize6Count;
+ USHORT AggSize5Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
+#else
+typedef union _TX_AGG_CNT2_STRUC {
+ struct {
+ USHORT AggSize5Count;
+ USHORT AggSize6Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT3 0x172c
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT3_STRUC {
+ struct {
+ USHORT AggSize8Count;
+ USHORT AggSize7Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
+#else
+typedef union _TX_AGG_CNT3_STRUC {
+ struct {
+ USHORT AggSize7Count;
+ USHORT AggSize8Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT4 0x1730
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT4_STRUC {
+ struct {
+ USHORT AggSize10Count;
+ USHORT AggSize9Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
+#else
+typedef union _TX_AGG_CNT4_STRUC {
+ struct {
+ USHORT AggSize9Count;
+ USHORT AggSize10Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
+#endif
+#define TX_AGG_CNT5 0x1734
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT5_STRUC {
+ struct {
+ USHORT AggSize12Count;
+ USHORT AggSize11Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
+#else
+typedef union _TX_AGG_CNT5_STRUC {
+ struct {
+ USHORT AggSize11Count;
+ USHORT AggSize12Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
+#endif
+#define TX_AGG_CNT6 0x1738
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT6_STRUC {
+ struct {
+ USHORT AggSize14Count;
+ USHORT AggSize13Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
+#else
+typedef union _TX_AGG_CNT6_STRUC {
+ struct {
+ USHORT AggSize13Count;
+ USHORT AggSize14Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
+#endif
+#define TX_AGG_CNT7 0x173c
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT7_STRUC {
+ struct {
+ USHORT AggSize16Count;
+ USHORT AggSize15Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
+#else
+typedef union _TX_AGG_CNT7_STRUC {
+ struct {
+ USHORT AggSize15Count;
+ USHORT AggSize16Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
+#endif
+#define MPDU_DENSITY_CNT 0x1740
+#ifdef RT_BIG_ENDIAN
+typedef union _MPDU_DEN_CNT_STRUC {
+ struct {
+ USHORT RXZeroDelCount; //RX zero length delimiter count
+ USHORT TXZeroDelCount; //TX zero length delimiter count
+ } field;
+ UINT32 word;
+} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
+#else
+typedef union _MPDU_DEN_CNT_STRUC {
+ struct {
+ USHORT TXZeroDelCount; //TX zero length delimiter count
+ USHORT RXZeroDelCount; //RX zero length delimiter count
+ } field;
+ UINT32 word;
+} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
+#endif
+//
+// TXRX control registers - base address 0x3000
+//
+// rt2860b UNKNOWN reg use R/O Reg Addr 0x77d0 first..
+#define TXRX_CSR1 0x77d0
+
+//
+// Security key table memory, base address = 0x1000
+//
+#define MAC_WCID_BASE 0x1800 //8-bytes(use only 6-bytes) * 256 entry =
+#define HW_WCID_ENTRY_SIZE 8
+#define PAIRWISE_KEY_TABLE_BASE 0x4000 // 32-byte * 256-entry = -byte
+#define HW_KEY_ENTRY_SIZE 0x20
+#define PAIRWISE_IVEIV_TABLE_BASE 0x6000 // 8-byte * 256-entry = -byte
+#define MAC_IVEIV_TABLE_BASE 0x6000 // 8-byte * 256-entry = -byte
+#define HW_IVEIV_ENTRY_SIZE 8
+#define MAC_WCID_ATTRIBUTE_BASE 0x6800 // 4-byte * 256-entry = -byte
+#define HW_WCID_ATTRI_SIZE 4
+#define WCID_RESERVED 0x6bfc
+#define SHARED_KEY_TABLE_BASE 0x6c00 // 32-byte * 16-entry = 512-byte
+#define SHARED_KEY_MODE_BASE 0x7000 // 32-byte * 16-entry = 512-byte
+#define HW_SHARED_KEY_MODE_SIZE 4
+#define SHAREDKEYTABLE 0
+#define PAIRWISEKEYTABLE 1
+
+
+#ifdef RT_BIG_ENDIAN
+typedef union _SHAREDKEY_MODE_STRUC {
+ struct {
+ UINT32 :1;
+ UINT32 Bss1Key3CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key0CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key3CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key0CipherAlg:3;
+ } field;
+ UINT32 word;
+} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
+#else
+typedef union _SHAREDKEY_MODE_STRUC {
+ struct {
+ UINT32 Bss0Key0CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key3CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key0CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key3CipherAlg:3;
+ UINT32 :1;
+ } field;
+ UINT32 word;
+} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
+#endif
+// 64-entry for pairwise key table
+typedef struct _HW_WCID_ENTRY { // 8-byte per entry
+ UCHAR Address[6];
+ UCHAR Rsv[2];
+} HW_WCID_ENTRY, PHW_WCID_ENTRY;
+
+
+
+//
+// Other on-chip shared memory space, base = 0x2000
+//
+
+// CIS space - base address = 0x2000
+#define HW_CIS_BASE 0x2000
+
+// Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function.
+#define HW_CS_CTS_BASE 0x7700
+// DFS CTS frame base address. It's where mac stores CTS frame for DFS.
+#define HW_DFS_CTS_BASE 0x7780
+#define HW_CTS_FRAME_SIZE 0x80
+
+// 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes
+// to save debugging settings
+#define HW_DEBUG_SETTING_BASE 0x77f0 // 0x77f0~0x77ff total 16 bytes
+#define HW_DEBUG_SETTING_BASE2 0x7770 // 0x77f0~0x77ff total 16 bytes
+
+// In order to support maximum 8 MBSS and its maximum length is 512 for each beacon
+// Three section discontinue memory segments will be used.
+// 1. The original region for BCN 0~3
+// 2. Extract memory from FCE table for BCN 4~5
+// 3. Extract memory from Pair-wise key table for BCN 6~7
+// It occupied those memory of wcid 238~253 for BCN 6
+// and wcid 222~237 for BCN 7
+#define HW_BEACON_MAX_SIZE 0x1000 /* unit: byte */
+#define HW_BEACON_BASE0 0x7800
+#define HW_BEACON_BASE1 0x7A00
+#define HW_BEACON_BASE2 0x7C00
+#define HW_BEACON_BASE3 0x7E00
+#define HW_BEACON_BASE4 0x7200
+#define HW_BEACON_BASE5 0x7400
+#define HW_BEACON_BASE6 0x5DC0
+#define HW_BEACON_BASE7 0x5BC0
+
+#define HW_BEACON_MAX_COUNT 8
+#define HW_BEACON_OFFSET 0x0200
+#define HW_BEACON_CONTENT_LEN (HW_BEACON_OFFSET - TXWI_SIZE)
+
+// HOST-MCU shared memory - base address = 0x2100
+#define HOST_CMD_CSR 0x404
+#define H2M_MAILBOX_CSR 0x7010
+#define H2M_MAILBOX_CID 0x7014
+#define H2M_MAILBOX_STATUS 0x701c
+#define H2M_INT_SRC 0x7024
+#define H2M_BBP_AGENT 0x7028
+#define M2H_CMD_DONE_CSR 0x000c
+#define MCU_TXOP_ARRAY_BASE 0x000c // TODO: to be provided by Albert
+#define MCU_TXOP_ENTRY_SIZE 32 // TODO: to be provided by Albert
+#define MAX_NUM_OF_TXOP_ENTRY 16 // TODO: must be same with 8051 firmware
+#define MCU_MBOX_VERSION 0x01 // TODO: to be confirmed by Albert
+#define MCU_MBOX_VERSION_OFFSET 5 // TODO: to be provided by Albert
+
+//
+// Host DMA registers - base address 0x200 . TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT,
+//
+//
+// DMA RING DESCRIPTOR
+//
+#define E2PROM_CSR 0x0004
+#define IO_CNTL_CSR 0x77d0
+
+#ifdef RT2870
+// 8051 firmware image for usb - use last-half base address = 0x3000
+#define FIRMWARE_IMAGE_BASE 0x3000
+#define MAX_FIRMWARE_IMAGE_SIZE 0x1000 // 4kbyte
+#endif // RT2870 //
+
+// TODO: ????? old RT2560 registers. to keep them or remove them?
+//#define MCAST0 0x0178 // multicast filter register 0
+//#define MCAST1 0x017c // multicast filter register 1
+
+
+// ================================================================
+// Tx / Rx / Mgmt ring descriptor definition
+// ================================================================
+
+// the following PID values are used to mark outgoing frame type in TXD->PID so that
+// proper TX statistics can be collected based on these categories
+// b3-2 of PID field -
+#define PID_MGMT 0x05
+#define PID_BEACON 0x0c
+#define PID_DATA_NORMALUCAST 0x02
+#define PID_DATA_AMPDU 0x04
+#define PID_DATA_NO_ACK 0x08
+#define PID_DATA_NOT_NORM_ACK 0x03
+// value domain of pTxD->HostQId (4-bit: 0~15)
+#define QID_AC_BK 1 // meet ACI definition in 802.11e
+#define QID_AC_BE 0 // meet ACI definition in 802.11e
+#define QID_AC_VI 2
+#define QID_AC_VO 3
+#define QID_HCCA 4
+#define NUM_OF_TX_RING 5
+#define QID_MGMT 13
+#define QID_RX 14
+#define QID_OTHER 15
+
+
+// ------------------------------------------------------
+// BBP & RF definition
+// ------------------------------------------------------
+#define BUSY 1
+#define IDLE 0
+
+#define RF_R00 0
+#define RF_R01 1
+#define RF_R02 2
+#define RF_R03 3
+#define RF_R04 4
+#define RF_R05 5
+#define RF_R06 6
+#define RF_R07 7
+#define RF_R08 8
+#define RF_R09 9
+#define RF_R10 10
+#define RF_R11 11
+#define RF_R12 12
+#define RF_R13 13
+#define RF_R14 14
+#define RF_R15 15
+#define RF_R16 16
+#define RF_R17 17
+#define RF_R18 18
+#define RF_R19 19
+#define RF_R20 20
+#define RF_R21 21
+#define RF_R22 22
+#define RF_R23 23
+#define RF_R24 24
+#define RF_R25 25
+#define RF_R26 26
+#define RF_R27 27
+#define RF_R28 28
+#define RF_R29 29
+#define RF_R30 30
+#define RF_R31 31
+
+#define BBP_R0 0 // version
+#define BBP_R1 1 // TSSI
+#define BBP_R2 2 // TX configure
+#define BBP_R3 3
+#define BBP_R4 4
+#define BBP_R5 5
+#define BBP_R6 6
+#define BBP_R14 14 // RX configure
+#define BBP_R16 16
+#define BBP_R17 17 // RX sensibility
+#define BBP_R18 18
+#define BBP_R21 21
+#define BBP_R22 22
+#define BBP_R24 24
+#define BBP_R25 25
+#define BBP_R31 31
+#define BBP_R49 49 //TSSI
+#define BBP_R50 50
+#define BBP_R51 51
+#define BBP_R52 52
+#define BBP_R55 55
+#define BBP_R62 62 // Rx SQ0 Threshold HIGH
+#define BBP_R63 63
+#define BBP_R64 64
+#define BBP_R65 65
+#define BBP_R66 66
+#define BBP_R67 67
+#define BBP_R68 68
+#define BBP_R69 69
+#define BBP_R70 70 // Rx AGC SQ CCK Xcorr threshold
+#define BBP_R73 73
+#define BBP_R75 75
+#define BBP_R77 77
+#define BBP_R79 79
+#define BBP_R80 80
+#define BBP_R81 81
+#define BBP_R82 82
+#define BBP_R83 83
+#define BBP_R84 84
+#define BBP_R86 86
+#define BBP_R91 91
+#define BBP_R92 92
+#define BBP_R94 94 // Tx Gain Control
+#define BBP_R103 103
+#define BBP_R105 105
+#define BBP_R113 113
+#define BBP_R114 114
+#define BBP_R115 115
+#define BBP_R116 116
+#define BBP_R117 117
+#define BBP_R118 118
+#define BBP_R119 119
+#define BBP_R120 120
+#define BBP_R121 121
+#define BBP_R122 122
+#define BBP_R123 123
+#ifdef RT30xx
+#define BBP_R138 138 // add by johnli, RF power sequence setup, ADC dynamic on/off control
+#endif // RT30xx //
+
+
+#define BBPR94_DEFAULT 0x06 // Add 1 value will gain 1db
+
+//#define PHY_TR_SWITCH_TIME 5 // usec
+
+//#define BBP_R17_LOW_SENSIBILITY 0x50
+//#define BBP_R17_MID_SENSIBILITY 0x41
+//#define BBP_R17_DYNAMIC_UP_BOUND 0x40
+#define RSSI_FOR_VERY_LOW_SENSIBILITY -35
+#define RSSI_FOR_LOW_SENSIBILITY -58
+#define RSSI_FOR_MID_LOW_SENSIBILITY -80
+#define RSSI_FOR_MID_SENSIBILITY -90
+
+//-------------------------------------------------------------------------
+// EEPROM definition
+//-------------------------------------------------------------------------
+#define EEDO 0x08
+#define EEDI 0x04
+#define EECS 0x02
+#define EESK 0x01
+#define EERL 0x80
+
+#define EEPROM_WRITE_OPCODE 0x05
+#define EEPROM_READ_OPCODE 0x06
+#define EEPROM_EWDS_OPCODE 0x10
+#define EEPROM_EWEN_OPCODE 0x13
+
+#define NUM_EEPROM_BBP_PARMS 19 // Include NIC Config 0, 1, CR, TX ALC step, BBPs
+#define NUM_EEPROM_TX_G_PARMS 7
+#define EEPROM_NIC1_OFFSET 0x34 // The address is from NIC config 0, not BBP register ID
+#define EEPROM_NIC2_OFFSET 0x36 // The address is from NIC config 0, not BBP register ID
+#define EEPROM_BBP_BASE_OFFSET 0xf0 // The address is from NIC config 0, not BBP register ID
+#define EEPROM_G_TX_PWR_OFFSET 0x52
+#define EEPROM_G_TX2_PWR_OFFSET 0x60
+#define EEPROM_LED1_OFFSET 0x3c
+#define EEPROM_LED2_OFFSET 0x3e
+#define EEPROM_LED3_OFFSET 0x40
+#define EEPROM_LNA_OFFSET 0x44
+#define EEPROM_RSSI_BG_OFFSET 0x46
+#define EEPROM_RSSI_A_OFFSET 0x4a
+#define EEPROM_DEFINE_MAX_TXPWR 0x4e
+#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G 0xde // 20MHZ 2.4G tx power.
+#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G 0xee // 40MHZ 2.4G tx power.
+#define EEPROM_TXPOWER_BYRATE_20MHZ_5G 0xfa // 20MHZ 5G tx power.
+#define EEPROM_TXPOWER_BYRATE_40MHZ_5G 0x10a // 40MHZ 5G tx power.
+#define EEPROM_A_TX_PWR_OFFSET 0x78
+#define EEPROM_A_TX2_PWR_OFFSET 0xa6
+//#define EEPROM_Japan_TX_PWR_OFFSET 0x90 // 802.11j
+//#define EEPROM_Japan_TX2_PWR_OFFSET 0xbe
+//#define EEPROM_TSSI_REF_OFFSET 0x54
+//#define EEPROM_TSSI_DELTA_OFFSET 0x24
+//#define EEPROM_CCK_TX_PWR_OFFSET 0x62
+//#define EEPROM_CALIBRATE_OFFSET 0x7c
+#define EEPROM_VERSION_OFFSET 0x02
+#define EEPROM_FREQ_OFFSET 0x3a
+#define EEPROM_TXPOWER_BYRATE 0xde // 20MHZ power.
+#define EEPROM_TXPOWER_DELTA 0x50 // 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ.
+#define VALID_EEPROM_VERSION 1
+
+// PairKeyMode definition
+#define PKMODE_NONE 0
+#define PKMODE_WEP64 1
+#define PKMODE_WEP128 2
+#define PKMODE_TKIP 3
+#define PKMODE_AES 4
+#define PKMODE_CKIP64 5
+#define PKMODE_CKIP128 6
+#define PKMODE_TKIP_NO_MIC 7 // MIC appended by driver: not a valid value in hardware key table
+
+// =================================================================================
+// WCID format
+// =================================================================================
+//7.1 WCID ENTRY format : 8bytes
+typedef struct _WCID_ENTRY_STRUC {
+ UCHAR RXBABitmap7; // bit0 for TID8, bit7 for TID 15
+ UCHAR RXBABitmap0; // bit0 for TID0, bit7 for TID 7
+ UCHAR MAC[6]; // 0 for shared key table. 1 for pairwise key table
+} WCID_ENTRY_STRUC, *PWCID_ENTRY_STRUC;
+
+//8.1.1 SECURITY KEY format : 8DW
+// 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table
+typedef struct _HW_KEY_ENTRY { // 32-byte per entry
+ UCHAR Key[16];
+ UCHAR TxMic[8];
+ UCHAR RxMic[8];
+} HW_KEY_ENTRY, *PHW_KEY_ENTRY;
+
+//8.1.2 IV/EIV format : 2DW
+
+//8.1.3 RX attribute entry format : 1DW
+#ifdef RT_BIG_ENDIAN
+typedef struct _MAC_ATTRIBUTE_STRUC {
+ UINT32 rsv:22;
+ UINT32 RXWIUDF:3;
+ UINT32 BSSIDIdx:3; //multipleBSS index for the WCID
+ UINT32 PairKeyMode:3;
+ UINT32 KeyTab:1; // 0 for shared key table. 1 for pairwise key table
+} MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
+#else
+typedef struct _MAC_ATTRIBUTE_STRUC {
+ UINT32 KeyTab:1; // 0 for shared key table. 1 for pairwise key table
+ UINT32 PairKeyMode:3;
+ UINT32 BSSIDIdx:3; //multipleBSS index for the WCID
+ UINT32 RXWIUDF:3;
+ UINT32 rsv:22;
+} MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
+#endif
+
+
+// =================================================================================
+// TX / RX ring descriptor format
+// =================================================================================
+
+// the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO.
+// MAC block use this TXINFO to control the transmission behavior of this frame.
+#define FIFO_MGMT 0
+#define FIFO_HCCA 1
+#define FIFO_EDCA 2
+
+//
+// TX descriptor format, Tx ring, Mgmt Ring
+//
+#ifdef RT_BIG_ENDIAN
+typedef struct PACKED _TXD_STRUC {
+ // Word 0
+ UINT32 SDPtr0;
+ // Word 1
+ UINT32 DMADONE:1;
+ UINT32 LastSec0:1;
+ UINT32 SDLen0:14;
+ UINT32 Burst:1;
+ UINT32 LastSec1:1;
+ UINT32 SDLen1:14;
+ // Word 2
+ UINT32 SDPtr1;
+ // Word 3
+ UINT32 ICO:1;
+ UINT32 UCO:1;
+ UINT32 TCO:1;
+ UINT32 rsv:2;
+ UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+ UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
+ UINT32 rsv2:24;
+} TXD_STRUC, *PTXD_STRUC;
+#else
+typedef struct PACKED _TXD_STRUC {
+ // Word 0
+ UINT32 SDPtr0;
+ // Word 1
+ UINT32 SDLen1:14;
+ UINT32 LastSec1:1;
+ UINT32 Burst:1;
+ UINT32 SDLen0:14;
+ UINT32 LastSec0:1;
+ UINT32 DMADONE:1;
+ //Word2
+ UINT32 SDPtr1;
+ //Word3
+ UINT32 rsv2:24;
+ UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
+ UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+ UINT32 rsv:2;
+ UINT32 TCO:1; //
+ UINT32 UCO:1; //
+ UINT32 ICO:1; //
+} TXD_STRUC, *PTXD_STRUC;
+#endif
+
+
+//
+// TXD Wireless Information format for Tx ring and Mgmt Ring
+//
+//txop : for txop mode
+// 0:txop for the MPDU frame will be handles by ASIC by register
+// 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS
+#ifdef RT_BIG_ENDIAN
+typedef struct PACKED _TXWI_STRUC {
+ // Word 0
+ UINT32 PHYMODE:2;
+ UINT32 TxBF:1; // 3*3
+ UINT32 rsv2:1;
+// UINT32 rsv2:2;
+ UINT32 Ifs:1; //
+ UINT32 STBC:2; //channel bandwidth 20MHz or 40 MHz
+ UINT32 ShortGI:1;
+ UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
+ UINT32 MCS:7;
+
+ UINT32 rsv:6;
+ UINT32 txop:2; //tx back off mode 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
+ UINT32 MpduDensity:3;
+ UINT32 AMPDU:1;
+
+ UINT32 TS:1;
+ UINT32 CFACK:1;
+ UINT32 MIMOps:1; // the remote peer is in dynamic MIMO-PS mode
+ UINT32 FRAG:1; // 1 to inform TKIP engine this is a fragment.
+ // Word 1
+ UINT32 PacketId:4;
+ UINT32 MPDUtotalByteCount:12;
+ UINT32 WirelessCliID:8;
+ UINT32 BAWinSize:6;
+ UINT32 NSEQ:1;
+ UINT32 ACK:1;
+ // Word 2
+ UINT32 IV;
+ // Word 3
+ UINT32 EIV;
+} TXWI_STRUC, *PTXWI_STRUC;
+#else
+typedef struct PACKED _TXWI_STRUC {
+ // Word 0
+ UINT32 FRAG:1; // 1 to inform TKIP engine this is a fragment.
+ UINT32 MIMOps:1; // the remote peer is in dynamic MIMO-PS mode
+ UINT32 CFACK:1;
+ UINT32 TS:1;
+
+ UINT32 AMPDU:1;
+ UINT32 MpduDensity:3;
+ UINT32 txop:2; //FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
+ UINT32 rsv:6;
+
+ UINT32 MCS:7;
+ UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
+ UINT32 ShortGI:1;
+ UINT32 STBC:2; // 1: STBC support MCS =0-7, 2,3 : RESERVE
+ UINT32 Ifs:1; //
+// UINT32 rsv2:2; //channel bandwidth 20MHz or 40 MHz
+ UINT32 rsv2:1;
+ UINT32 TxBF:1; // 3*3
+ UINT32 PHYMODE:2;
+ // Word 1
+ UINT32 ACK:1;
+ UINT32 NSEQ:1;
+ UINT32 BAWinSize:6;
+ UINT32 WirelessCliID:8;
+ UINT32 MPDUtotalByteCount:12;
+ UINT32 PacketId:4;
+ //Word2
+ UINT32 IV;
+ //Word3
+ UINT32 EIV;
+} TXWI_STRUC, *PTXWI_STRUC;
+#endif
+//
+// Rx descriptor format, Rx Ring
+//
+//
+// RXWI wireless information format, in PBF. invisible in driver.
+//
+#ifdef RT_BIG_ENDIAN
+typedef struct PACKED _RXWI_STRUC {
+ // Word 0
+ UINT32 TID:4;
+ UINT32 MPDUtotalByteCount:12;
+ UINT32 UDF:3;
+ UINT32 BSSID:3;
+ UINT32 KeyIndex:2;
+ UINT32 WirelessCliID:8;
+ // Word 1
+ UINT32 PHYMODE:2; // 1: this RX frame is unicast to me
+ UINT32 rsv:3;
+ UINT32 STBC:2;
+ UINT32 ShortGI:1;
+ UINT32 BW:1;
+ UINT32 MCS:7;
+ UINT32 SEQUENCE:12;
+ UINT32 FRAG:4;
+ // Word 2
+ UINT32 rsv1:8;
+ UINT32 RSSI2:8;
+ UINT32 RSSI1:8;
+ UINT32 RSSI0:8;
+ // Word 3
+ UINT32 rsv2:16;
+ UINT32 SNR1:8;
+ UINT32 SNR0:8;
+} RXWI_STRUC, *PRXWI_STRUC;
+#else
+typedef struct PACKED _RXWI_STRUC {
+ // Word 0
+ UINT32 WirelessCliID:8;
+ UINT32 KeyIndex:2;
+ UINT32 BSSID:3;
+ UINT32 UDF:3;
+ UINT32 MPDUtotalByteCount:12;
+ UINT32 TID:4;
+ // Word 1
+ UINT32 FRAG:4;
+ UINT32 SEQUENCE:12;
+ UINT32 MCS:7;
+ UINT32 BW:1;
+ UINT32 ShortGI:1;
+ UINT32 STBC:2;
+ UINT32 rsv:3;
+ UINT32 PHYMODE:2; // 1: this RX frame is unicast to me
+ //Word2
+ UINT32 RSSI0:8;
+ UINT32 RSSI1:8;
+ UINT32 RSSI2:8;
+ UINT32 rsv1:8;
+ //Word3
+ UINT32 SNR0:8;
+ UINT32 SNR1:8;
+ UINT32 rsv2:16;
+} RXWI_STRUC, *PRXWI_STRUC;
+#endif
+
+
+// =================================================================================
+// HOST-MCU communication data structure
+// =================================================================================
+
+//
+// H2M_MAILBOX_CSR: Host-to-MCU Mailbox
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _H2M_MAILBOX_STRUC {
+ struct {
+ UINT32 Owner:8;
+ UINT32 CmdToken:8; // 0xff tells MCU not to report CmdDoneInt after excuting the command
+ UINT32 HighByte:8;
+ UINT32 LowByte:8;
+ } field;
+ UINT32 word;
+} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
+#else
+typedef union _H2M_MAILBOX_STRUC {
+ struct {
+ UINT32 LowByte:8;
+ UINT32 HighByte:8;
+ UINT32 CmdToken:8;
+ UINT32 Owner:8;
+ } field;
+ UINT32 word;
+} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
+#endif
+
+//
+// M2H_CMD_DONE_CSR: MCU-to-Host command complete indication
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _M2H_CMD_DONE_STRUC {
+ struct {
+ UINT32 CmdToken3;
+ UINT32 CmdToken2;
+ UINT32 CmdToken1;
+ UINT32 CmdToken0;
+ } field;
+ UINT32 word;
+} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
+#else
+typedef union _M2H_CMD_DONE_STRUC {
+ struct {
+ UINT32 CmdToken0;
+ UINT32 CmdToken1;
+ UINT32 CmdToken2;
+ UINT32 CmdToken3;
+ } field;
+ UINT32 word;
+} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
+#endif
+
+
+
+//
+// MCU_LEDCS: MCU LED Control Setting.
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _MCU_LEDCS_STRUC {
+ struct {
+ UCHAR Polarity:1;
+ UCHAR LedMode:7;
+ } field;
+ UCHAR word;
+} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
+#else
+typedef union _MCU_LEDCS_STRUC {
+ struct {
+ UCHAR LedMode:7;
+ UCHAR Polarity:1;
+ } field;
+ UCHAR word;
+} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
+#endif
+// =================================================================================
+// Register format
+// =================================================================================
+
+
+
+//NAV_TIME_CFG :NAV
+#ifdef RT_BIG_ENDIAN
+typedef union _NAV_TIME_CFG_STRUC {
+ struct {
+ USHORT rsv:6;
+ USHORT ZeroSifs:1; // Applied zero SIFS timer after OFDM RX 0: disable
+ USHORT Eifs:9; // in unit of 1-us
+ UCHAR SlotTime; // in unit of 1-us
+ UCHAR Sifs; // in unit of 1-us
+ } field;
+ UINT32 word;
+} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
+#else
+typedef union _NAV_TIME_CFG_STRUC {
+ struct {
+ UCHAR Sifs; // in unit of 1-us
+ UCHAR SlotTime; // in unit of 1-us
+ USHORT Eifs:9; // in unit of 1-us
+ USHORT ZeroSifs:1; // Applied zero SIFS timer after OFDM RX 0: disable
+ USHORT rsv:6;
+ } field;
+ UINT32 word;
+} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
+#endif
+
+
+
+
+
+//
+// RX_FILTR_CFG: /RX configuration register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union RX_FILTR_CFG_STRUC {
+ struct {
+ UINT32 :15;
+ UINT32 DropRsvCntlType:1;
+
+ UINT32 DropBAR:1; //
+ UINT32 DropBA:1; //
+ UINT32 DropPsPoll:1; // Drop Ps-Poll
+ UINT32 DropRts:1; // Drop Ps-Poll
+
+ UINT32 DropCts:1; // Drop Ps-Poll
+ UINT32 DropAck:1; // Drop Ps-Poll
+ UINT32 DropCFEnd:1; // Drop Ps-Poll
+ UINT32 DropCFEndAck:1; // Drop Ps-Poll
+
+ UINT32 DropDuplicate:1; // Drop duplicate frame
+ UINT32 DropBcast:1; // Drop broadcast frames
+ UINT32 DropMcast:1; // Drop multicast frames
+ UINT32 DropVerErr:1; // Drop version error frame
+
+ UINT32 DropNotMyBSSID:1; // Drop fram ToDs bit is true
+ UINT32 DropNotToMe:1; // Drop not to me unicast frame
+ UINT32 DropPhyErr:1; // Drop physical error
+ UINT32 DropCRCErr:1; // Drop CRC error
+ } field;
+ UINT32 word;
+} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
+#else
+typedef union _RX_FILTR_CFG_STRUC {
+ struct {
+ UINT32 DropCRCErr:1; // Drop CRC error
+ UINT32 DropPhyErr:1; // Drop physical error
+ UINT32 DropNotToMe:1; // Drop not to me unicast frame
+ UINT32 DropNotMyBSSID:1; // Drop fram ToDs bit is true
+
+ UINT32 DropVerErr:1; // Drop version error frame
+ UINT32 DropMcast:1; // Drop multicast frames
+ UINT32 DropBcast:1; // Drop broadcast frames
+ UINT32 DropDuplicate:1; // Drop duplicate frame
+
+ UINT32 DropCFEndAck:1; // Drop Ps-Poll
+ UINT32 DropCFEnd:1; // Drop Ps-Poll
+ UINT32 DropAck:1; // Drop Ps-Poll
+ UINT32 DropCts:1; // Drop Ps-Poll
+
+ UINT32 DropRts:1; // Drop Ps-Poll
+ UINT32 DropPsPoll:1; // Drop Ps-Poll
+ UINT32 DropBA:1; //
+ UINT32 DropBAR:1; //
+
+ UINT32 DropRsvCntlType:1;
+ UINT32 :15;
+ } field;
+ UINT32 word;
+} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
+#endif
+
+
+
+
+//
+// PHY_CSR4: RF serial control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _PHY_CSR4_STRUC {
+ struct {
+ UINT32 Busy:1; // 1: ASIC is busy execute RF programming.
+ UINT32 PLL_LD:1; // RF PLL_LD status
+ UINT32 IFSelect:1; // 1: select IF to program, 0: select RF to program
+ UINT32 NumberOfBits:5; // Number of bits used in RFRegValue (I:20, RFMD:22)
+ UINT32 RFRegValue:24; // Register value (include register id) serial out to RF/IF chip.
+ } field;
+ UINT32 word;
+} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
+#else
+typedef union _PHY_CSR4_STRUC {
+ struct {
+ UINT32 RFRegValue:24; // Register value (include register id) serial out to RF/IF chip.
+ UINT32 NumberOfBits:5; // Number of bits used in RFRegValue (I:20, RFMD:22)
+ UINT32 IFSelect:1; // 1: select IF to program, 0: select RF to program
+ UINT32 PLL_LD:1; // RF PLL_LD status
+ UINT32 Busy:1; // 1: ASIC is busy execute RF programming.
+ } field;
+ UINT32 word;
+} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
+#endif
+
+
+//
+// SEC_CSR5: shared key table security mode register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _SEC_CSR5_STRUC {
+ struct {
+ UINT32 :1;
+ UINT32 Bss3Key3CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key0CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key3CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key0CipherAlg:3;
+ } field;
+ UINT32 word;
+} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
+#else
+typedef union _SEC_CSR5_STRUC {
+ struct {
+ UINT32 Bss2Key0CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key3CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key0CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key3CipherAlg:3;
+ UINT32 :1;
+ } field;
+ UINT32 word;
+} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
+#endif
+
+
+//
+// HOST_CMD_CSR: For HOST to interrupt embedded processor
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _HOST_CMD_CSR_STRUC {
+ struct {
+ UINT32 Rsv:24;
+ UINT32 HostCommand:8;
+ } field;
+ UINT32 word;
+} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
+#else
+typedef union _HOST_CMD_CSR_STRUC {
+ struct {
+ UINT32 HostCommand:8;
+ UINT32 Rsv:24;
+ } field;
+ UINT32 word;
+} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
+#endif
+
+
+//
+// AIFSN_CSR: AIFSN for each EDCA AC
+//
+
+
+
+//
+// E2PROM_CSR: EEPROM control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _E2PROM_CSR_STRUC {
+ struct {
+ UINT32 Rsvd:25;
+ UINT32 LoadStatus:1; // 1:loading, 0:done
+ UINT32 Type:1; // 1: 93C46, 0:93C66
+ UINT32 EepromDO:1;
+ UINT32 EepromDI:1;
+ UINT32 EepromCS:1;
+ UINT32 EepromSK:1;
+ UINT32 Reload:1; // Reload EEPROM content, write one to reload, self-cleared.
+ } field;
+ UINT32 word;
+} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
+#else
+typedef union _E2PROM_CSR_STRUC {
+ struct {
+ UINT32 Reload:1; // Reload EEPROM content, write one to reload, self-cleared.
+ UINT32 EepromSK:1;
+ UINT32 EepromCS:1;
+ UINT32 EepromDI:1;
+ UINT32 EepromDO:1;
+ UINT32 Type:1; // 1: 93C46, 0:93C66
+ UINT32 LoadStatus:1; // 1:loading, 0:done
+ UINT32 Rsvd:25;
+ } field;
+ UINT32 word;
+} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
+#endif
+
+
+// -------------------------------------------------------------------
+// E2PROM data layout
+// -------------------------------------------------------------------
+
+//
+// EEPROM antenna select format
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_ANTENNA_STRUC {
+ struct {
+ USHORT Rsv:4;
+ USHORT RfIcType:4; // see E2PROM document
+ USHORT TxPath:4; // 1: 1T, 2: 2T
+ USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R
+ } field;
+ USHORT word;
+} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
+#else
+typedef union _EEPROM_ANTENNA_STRUC {
+ struct {
+ USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R
+ USHORT TxPath:4; // 1: 1T, 2: 2T
+ USHORT RfIcType:4; // see E2PROM document
+ USHORT Rsv:4;
+ } field;
+ USHORT word;
+} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_NIC_CINFIG2_STRUC {
+ struct {
+ USHORT DACTestBit:1; // control if driver should patch the DAC issue
+ USHORT Rsv2:3; // must be 0
+ USHORT AntDiversity:1; // Antenna diversity
+ USHORT Rsv1:1; // must be 0
+ USHORT BW40MAvailForA:1; // 0:enable, 1:disable
+ USHORT BW40MAvailForG:1; // 0:enable, 1:disable
+ USHORT EnableWPSPBC:1; // WPS PBC Control bit
+ USHORT BW40MSidebandForA:1;
+ USHORT BW40MSidebandForG:1;
+ USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable
+ USHORT ExternalLNAForA:1; // external LNA enable for 5G
+ USHORT ExternalLNAForG:1; // external LNA enable for 2.4G
+ USHORT DynamicTxAgcControl:1; //
+ USHORT HardwareRadioControl:1; // Whether RF is controlled by driver or HW. 1:enable hw control, 0:disable
+ } field;
+ USHORT word;
+} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
+#else
+typedef union _EEPROM_NIC_CINFIG2_STRUC {
+ struct {
+ USHORT HardwareRadioControl:1; // 1:enable, 0:disable
+ USHORT DynamicTxAgcControl:1; //
+ USHORT ExternalLNAForG:1; //
+ USHORT ExternalLNAForA:1; // external LNA enable for 2.4G
+ USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable
+ USHORT BW40MSidebandForG:1;
+ USHORT BW40MSidebandForA:1;
+ USHORT EnableWPSPBC:1; // WPS PBC Control bit
+ USHORT BW40MAvailForG:1; // 0:enable, 1:disable
+ USHORT BW40MAvailForA:1; // 0:enable, 1:disable
+ USHORT Rsv1:1; // must be 0
+ USHORT AntDiversity:1; // Antenna diversity
+ USHORT Rsv2:3; // must be 0
+ USHORT DACTestBit:1; // control if driver should patch the DAC issue
+ } field;
+ USHORT word;
+} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
+#endif
+
+//
+// TX_PWR Value valid range 0xFA(-6) ~ 0x24(36)
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_TX_PWR_STRUC {
+ struct {
+ CHAR Byte1; // High Byte
+ CHAR Byte0; // Low Byte
+ } field;
+ USHORT word;
+} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
+#else
+typedef union _EEPROM_TX_PWR_STRUC {
+ struct {
+ CHAR Byte0; // Low Byte
+ CHAR Byte1; // High Byte
+ } field;
+ USHORT word;
+} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_VERSION_STRUC {
+ struct {
+ UCHAR Version; // High Byte
+ UCHAR FaeReleaseNumber; // Low Byte
+ } field;
+ USHORT word;
+} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
+#else
+typedef union _EEPROM_VERSION_STRUC {
+ struct {
+ UCHAR FaeReleaseNumber; // Low Byte
+ UCHAR Version; // High Byte
+ } field;
+ USHORT word;
+} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_LED_STRUC {
+ struct {
+ USHORT Rsvd:3; // Reserved
+ USHORT LedMode:5; // Led mode.
+ USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting.
+ USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting.
+ USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting.
+ USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting.
+ USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting.
+ USHORT PolarityACT:1; // Polarity ACT setting.
+ USHORT PolarityRDY_A:1; // Polarity RDY_A setting.
+ USHORT PolarityRDY_G:1; // Polarity RDY_G setting.
+ } field;
+ USHORT word;
+} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
+#else
+typedef union _EEPROM_LED_STRUC {
+ struct {
+ USHORT PolarityRDY_G:1; // Polarity RDY_G setting.
+ USHORT PolarityRDY_A:1; // Polarity RDY_A setting.
+ USHORT PolarityACT:1; // Polarity ACT setting.
+ USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting.
+ USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting.
+ USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting.
+ USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting.
+ USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting.
+ USHORT LedMode:5; // Led mode.
+ USHORT Rsvd:3; // Reserved
+ } field;
+ USHORT word;
+} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_TXPOWER_DELTA_STRUC {
+ struct {
+ UCHAR TxPowerEnable:1;// Enable
+ UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value
+ UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4)
+ } field;
+ UCHAR value;
+} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
+#else
+typedef union _EEPROM_TXPOWER_DELTA_STRUC {
+ struct {
+ UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4)
+ UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value
+ UCHAR TxPowerEnable:1;// Enable
+ } field;
+ UCHAR value;
+} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
+#endif
+
+//
+// QOS_CSR0: TXOP holder address0 register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _QOS_CSR0_STRUC {
+ struct {
+ UCHAR Byte3; // MAC address byte 3
+ UCHAR Byte2; // MAC address byte 2
+ UCHAR Byte1; // MAC address byte 1
+ UCHAR Byte0; // MAC address byte 0
+ } field;
+ UINT32 word;
+} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
+#else
+typedef union _QOS_CSR0_STRUC {
+ struct {
+ UCHAR Byte0; // MAC address byte 0
+ UCHAR Byte1; // MAC address byte 1
+ UCHAR Byte2; // MAC address byte 2
+ UCHAR Byte3; // MAC address byte 3
+ } field;
+ UINT32 word;
+} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
+#endif
+
+//
+// QOS_CSR1: TXOP holder address1 register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _QOS_CSR1_STRUC {
+ struct {
+ UCHAR Rsvd1;
+ UCHAR Rsvd0;
+ UCHAR Byte5; // MAC address byte 5
+ UCHAR Byte4; // MAC address byte 4
+ } field;
+ UINT32 word;
+} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
+#else
+typedef union _QOS_CSR1_STRUC {
+ struct {
+ UCHAR Byte4; // MAC address byte 4
+ UCHAR Byte5; // MAC address byte 5
+ UCHAR Rsvd0;
+ UCHAR Rsvd1;
+ } field;
+ UINT32 word;
+} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
+#endif
+
+#define RF_CSR_CFG 0x500
+#ifdef RT_BIG_ENDIAN
+typedef union _RF_CSR_CFG_STRUC {
+ struct {
+ UINT Rsvd1:14; // Reserved
+ UINT RF_CSR_KICK:1; // kick RF register read/write
+ UINT RF_CSR_WR:1; // 0: read 1: write
+ UINT Rsvd2:3; // Reserved
+ UINT TESTCSR_RFACC_REGNUM:5; // RF register ID
+ UINT RF_CSR_DATA:8; // DATA
+ } field;
+ UINT word;
+} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
+#else
+typedef union _RF_CSR_CFG_STRUC {
+ struct {
+ UINT RF_CSR_DATA:8; // DATA
+ UINT TESTCSR_RFACC_REGNUM:5; // RF register ID
+ UINT Rsvd2:3; // Reserved
+ UINT RF_CSR_WR:1; // 0: read 1: write
+ UINT RF_CSR_KICK:1; // kick RF register read/write
+ UINT Rsvd1:14; // Reserved
+ } field;
+ UINT word;
+} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
+#endif
+
+#endif // __RT28XX_H__
diff --git a/drivers/staging/rt3070/rt_ate.c b/drivers/staging/rt3070/rt_ate.c
new file mode 100644
index 00000000000..9238d960121
--- /dev/null
+++ b/drivers/staging/rt3070/rt_ate.c
@@ -0,0 +1,6506 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#include "rt_config.h"
+
+#ifdef UCOS
+INT IoctlResponse(PUCHAR payload, PUCHAR msg, INT len);
+#endif // UCOS //
+
+#define ATE_BBP_REG_NUM 168
+UCHAR restore_BBP[ATE_BBP_REG_NUM]={0};
+
+#ifdef RALINK_ATE
+UCHAR TemplateFrame[24] = {0x08/* Data type */,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xAA,0xBB,0x12,0x34,0x56,0x00,0x11,0x22,0xAA,0xBB,0xCC,0x00,0x00}; // 802.11 MAC Header, Type:Data, Length:24bytes
+extern RTMP_RF_REGS RF2850RegTable[];
+extern UCHAR NUM_OF_2850_CHNL;
+
+#ifdef RT2870
+extern UCHAR EpToQueue[];
+extern VOID RTUSBRejectPendingPackets( IN PRTMP_ADAPTER pAd);
+#endif // RT2870 //
+
+#ifdef RT30xx
+//2008/07/10:KH adds to support 3070 ATE<--
+extern FREQUENCY_ITEM FreqItems3020[];
+extern UCHAR NUM_OF_3020_CHNL;
+//2008/07/10:KH adds to support 3070 ATE-->
+#endif // RT30xx //
+
+#ifdef UCOS
+extern INT ConsoleResponse(IN PUCHAR buff);
+extern int (*remote_display)(char *);
+#endif // UCOS //
+
+static CHAR CCKRateTable[] = {0, 1, 2, 3, 8, 9, 10, 11, -1}; /* CCK Mode. */
+static CHAR OFDMRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, -1}; /* OFDM Mode. */
+static CHAR HTMIXRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}; /* HT Mix Mode. */
+
+static INT TxDmaBusy(
+ IN PRTMP_ADAPTER pAd);
+
+static INT RxDmaBusy(
+ IN PRTMP_ADAPTER pAd);
+
+static VOID RtmpDmaEnable(
+ IN PRTMP_ADAPTER pAd,
+ IN INT Enable);
+
+static VOID BbpSoftReset(
+ IN PRTMP_ADAPTER pAd);
+
+static VOID RtmpRfIoWrite(
+ IN PRTMP_ADAPTER pAd);
+
+static INT ATESetUpFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 TxIdx);
+
+static INT ATETxPwrHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN char index);
+
+static INT ATECmdHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+static int CheckMCSValid(
+ IN UCHAR Mode,
+ IN UCHAR Mcs);
+
+
+#ifdef RT2870
+static VOID ATEWriteTxInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXINFO_STRUC pTxInfo,
+ IN USHORT USBDMApktLen,
+ IN BOOLEAN bWiv,
+ IN UCHAR QueueSel,
+ IN UCHAR NextValid,
+ IN UCHAR TxBurst);
+
+static VOID ATEWriteTxWI(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXWI_STRUC pTxWI,
+ IN BOOLEAN FRAG,
+ IN BOOLEAN InsTimestamp,
+ IN BOOLEAN AMPDU,
+ IN BOOLEAN Ack,
+ IN BOOLEAN NSeq, // HW new a sequence.
+ IN UCHAR BASize,
+ IN UCHAR WCID,
+ IN ULONG Length,
+ IN UCHAR PID,
+ IN UCHAR MIMOps,
+ IN UCHAR Txopmode,
+ IN BOOLEAN CfAck,
+ IN HTTRANSMIT_SETTING Transmit);
+
+#endif // RT2870 //
+
+static VOID SetJapanFilter(
+ IN PRTMP_ADAPTER pAd);
+
+/*=========================end of prototype=========================*/
+
+
+#ifdef RT2870
+static INT TxDmaBusy(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT result;
+ USB_DMA_CFG_STRUC UsbCfg;
+
+ RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
+ if (UsbCfg.field.TxBusy)
+ result = 1;
+ else
+ result = 0;
+
+ return result;
+}
+
+static INT RxDmaBusy(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT result;
+ USB_DMA_CFG_STRUC UsbCfg;
+
+ RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
+ if (UsbCfg.field.RxBusy)
+ result = 1;
+ else
+ result = 0;
+
+ return result;
+}
+
+static VOID RtmpDmaEnable(
+ IN PRTMP_ADAPTER pAd,
+ IN INT Enable)
+{
+ BOOLEAN value;
+ ULONG WaitCnt;
+ USB_DMA_CFG_STRUC UsbCfg;
+
+ value = Enable > 0 ? 1 : 0;
+
+ // check DMA is in busy mode.
+ WaitCnt = 0;
+ while (TxDmaBusy(pAd) || RxDmaBusy(pAd))
+ {
+ RTMPusecDelay(10);
+ if (WaitCnt++ > 100)
+ break;
+ }
+
+ //Why not to clear USB DMA TX path first ???
+ RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
+ UsbCfg.field.TxBulkEn = value;
+ UsbCfg.field.RxBulkEn = value;
+ RTMP_IO_WRITE32(pAd, USB_DMA_CFG, UsbCfg.word); // abort all TX rings
+ RTMPusecDelay(5000);
+
+ return;
+}
+#endif // RT2870 //
+
+static VOID BbpSoftReset(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR BbpData = 0;
+
+ // Soft reset, set BBP R21 bit0=1->0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
+ BbpData |= 0x00000001; //set bit0=1
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
+
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
+ BbpData &= ~(0x00000001); //set bit0=0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
+
+ return;
+}
+
+static VOID RtmpRfIoWrite(
+ IN PRTMP_ADAPTER pAd)
+{
+ // Set RF value 1's set R3[bit2] = [0]
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+ RTMPusecDelay(200);
+
+ // Set RF value 2's set R3[bit2] = [1]
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+ RTMPusecDelay(200);
+
+ // Set RF value 3's set R3[bit2] = [0]
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+ return;
+}
+
+static int CheckMCSValid(
+ UCHAR Mode,
+ UCHAR Mcs)
+{
+ int i;
+ PCHAR pRateTab;
+
+ switch(Mode)
+ {
+ case 0:
+ pRateTab = CCKRateTable;
+ break;
+ case 1:
+ pRateTab = OFDMRateTable;
+ break;
+ case 2:
+ case 3:
+ pRateTab = HTMIXRateTable;
+ break;
+ default:
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("unrecognizable Tx Mode %d\n", Mode));
+ return -1;
+ break;
+ }
+
+ i = 0;
+ while(pRateTab[i] != -1)
+ {
+ if (pRateTab[i] == Mcs)
+ return 0;
+ i++;
+ }
+
+ return -1;
+}
+
+#if 1
+static INT ATETxPwrHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN char index)
+{
+ ULONG R;
+ CHAR TxPower;
+ UCHAR Bbp94 = 0;
+ BOOLEAN bPowerReduce = FALSE;
+#ifdef RT30xx
+ UCHAR RFValue;
+#endif // RT30xx //
+#ifdef RALINK_28xx_QA
+ if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
+ {
+ /* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
+ ** are not synchronized.
+ */
+/*
+ pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
+ pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
+*/
+ return 0;
+ }
+ else
+#endif // RALINK_28xx_QA //
+ {
+ TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
+
+ if (pAd->ate.Channel <= 14)
+ {
+ if (TxPower > 31)
+ {
+ //
+ // R3, R4 can't large than 31 (0x24), 31 ~ 36 used by BBP 94
+ //
+ R = 31;
+ if (TxPower <= 36)
+ Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
+ }
+ else if (TxPower < 0)
+ {
+ //
+ // R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
+ //
+ R = 0;
+ if (TxPower >= -6)
+ Bbp94 = BBPR94_DEFAULT + TxPower;
+ }
+ else
+ {
+ // 0 ~ 31
+ R = (ULONG) TxPower;
+ Bbp94 = BBPR94_DEFAULT;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
+ }
+ else// 5.5 GHz
+ {
+ if (TxPower > 15)
+ {
+ //
+ // R3, R4 can't large than 15 (0x0F)
+ //
+ R = 15;
+ }
+ else if (TxPower < 0)
+ {
+ //
+ // R3, R4 can't less than 0
+ //
+ // -1 ~ -7
+ ASSERT((TxPower >= -7));
+ R = (ULONG)(TxPower + 7);
+ bPowerReduce = TRUE;
+ }
+ else
+ {
+ // 0 ~ 15
+ R = (ULONG) TxPower;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%lu)\n", __FUNCTION__, TxPower, R));
+ }
+//2008/09/10:KH adds to support 3070 ATE TX Power tunning real time<--
+#ifdef RT30xx
+ if(IS_RT30xx(pAd))
+ {
+ // Set Tx Power
+
+ RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue);
+ RFValue = (RFValue & 0xE0) | TxPower;
+ RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)RFValue);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("3070 or 2070:%s (TxPower=%d, RFValue=%x)\n", __FUNCTION__, TxPower, RFValue));
+
+ }
+ else
+#endif // RT30xx //
+ {
+ if (pAd->ate.Channel <= 14)
+ {
+ if (index == 0)
+ {
+ R = R << 9; // shift TX power control to correct RF(R3) register bit position
+ R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+ pAd->LatchRfRegs.R3 = R;
+ }
+ else
+ {
+ R = R << 6; // shift TX power control to correct RF(R4) register bit position
+ R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+ pAd->LatchRfRegs.R4 = R;
+ }
+ }
+ else// 5.5GHz
+ {
+ if (bPowerReduce == FALSE)
+ {
+ if (index == 0)
+ {
+ R = (R << 10) | (1 << 9); // shift TX power control to correct RF(R3) register bit position
+ R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+ pAd->LatchRfRegs.R3 = R;
+ }
+ else
+ {
+ R = (R << 7) | (1 << 6); // shift TX power control to correct RF(R4) register bit position
+ R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+ pAd->LatchRfRegs.R4 = R;
+ }
+ }
+ else
+ {
+ if (index == 0)
+ {
+ R = (R << 10); // shift TX power control to correct RF(R3) register bit position
+ R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+
+ /* Clear bit 9 of R3 to reduce 7dB. */
+ pAd->LatchRfRegs.R3 = (R & (~(1 << 9)));
+ }
+ else
+ {
+ R = (R << 7); // shift TX power control to correct RF(R4) register bit position
+ R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+
+ /* Clear bit 6 of R4 to reduce 7dB. */
+ pAd->LatchRfRegs.R4 = (R & (~(1 << 6)));
+ }
+ }
+ }
+ RtmpRfIoWrite(pAd);
+ }
+//2008/09/10:KH adds to support 3070 ATE TX Power tunning real time-->
+
+ return 0;
+ }
+}
+#else// 1 //
+static INT ATETxPwrHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN char index)
+{
+ ULONG R;
+ CHAR TxPower;
+ UCHAR Bbp94 = 0;
+
+#ifdef RALINK_28xx_QA
+ if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
+ {
+ // TODO: how to get current TxPower0/1 from pAd->LatchRfRegs ?
+ /* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
+ ** are not synchronized.
+ */
+/*
+ pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
+ pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
+*/
+ return 0;
+ }
+ else
+#endif // RALINK_28xx_QA //
+ {
+ TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
+
+ if (TxPower > 31)
+ {
+ //
+ // R3, R4 can't large than 36 (0x24), 31 ~ 36 used by BBP 94
+ //
+ R = 31;
+ if (TxPower <= 36)
+ Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
+ }
+ else if (TxPower < 0)
+ {
+ //
+ // R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
+ //
+ R = 0;
+ if (TxPower >= -6)
+ Bbp94 = BBPR94_DEFAULT + TxPower;
+ }
+ else
+ {
+ // 0 ~ 31
+ R = (ULONG) TxPower;
+ Bbp94 = BBPR94_DEFAULT;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R3=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
+
+ if (pAd->ate.Channel <= 14)
+ {
+ if (index == 0)
+ {
+ R = R << 9; // shift TX power control to correct RF(R3) register bit position
+ R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+ pAd->LatchRfRegs.R3 = R;
+ }
+ else
+ {
+ R = R << 6; // shift TX power control to correct RF(R4) register bit position
+ R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+ pAd->LatchRfRegs.R4 = R;
+ }
+ }
+ else
+ {
+ if (index == 0)
+ {
+ R = (R << 10) | (1 << 9); // shift TX power control to correct RF(R3) register bit position
+ R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+ pAd->LatchRfRegs.R3 = R;
+ }
+ else
+ {
+ R = (R << 7) | (1 << 6); // shift TX power control to correct RF(R4) register bit position
+ R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+ pAd->LatchRfRegs.R4 = R;
+ }
+ }
+
+ RtmpRfIoWrite(pAd);
+
+ return 0;
+ }
+}
+#endif // 1 //
+/*
+ ==========================================================================
+ Description:
+ Set ATE operation mode to
+ 0. ATESTART = Start ATE Mode
+ 1. ATESTOP = Stop ATE Mode
+ 2. TXCONT = Continuous Transmit
+ 3. TXCARR = Transmit Carrier
+ 4. TXFRAME = Transmit Frames
+ 5. RXFRAME = Receive Frames
+#ifdef RALINK_28xx_QA
+ 6. TXSTOP = Stop Any Type of Transmition
+ 7. RXSTOP = Stop Receiving Frames
+#endif // RALINK_28xx_QA //
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+/* */
+/* */
+/*=======================End of RT2860=======================*/
+
+
+/*======================Start of RT2870======================*/
+/* */
+/* */
+
+#ifdef RT2870
+static INT ATECmdHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UINT32 Value;
+ UCHAR BbpData;
+ UINT32 MacData;
+ UINT i=0, atemode;
+ //NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ //PUCHAR pDest;
+ UINT32 temp;
+ ULONG IrqFlags;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("===> ATECmdHandler()\n"));
+ ATEAsicSwitchChannel(pAd);
+ /* AsicLockChannel() is empty function so far in fact */
+ AsicLockChannel(pAd, pAd->ate.Channel);
+
+ RTMPusecDelay(5000);
+
+ // Default value in BBP R22 is 0x0.
+ BbpData = 0;
+
+ /* Enter ATE mode and set Tx/Rx Idle */
+ if (!strcmp(arg, "ATESTART"))
+ {
+#ifdef CONFIG_STA_SUPPORT
+ BOOLEAN Cancelled;
+#endif // CONFIG_STA_SUPPORT //
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: ATESTART\n"));
+
+ netif_stop_queue(pAd->net_dev);
+
+ atemode = pAd->ate.Mode;
+ pAd->ate.Mode = ATE_START;
+// pAd->ate.TxDoneCount = pAd->ate.TxCount;
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Disable auto responder
+ RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &temp);
+ temp = temp & 0xFFFFFFFE;
+ RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, temp);
+
+ // read MAC_SYS_CTRL and backup MAC_SYS_CTRL value.
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+ // clean bit4 to stop continuous Tx production test.
+ MacData &= 0xFFFFFFEF;
+ // Stop continuous TX production test.
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);//disable or cancel pending irp first ???
+
+ if (atemode & ATE_TXCARR
+#ifdef RT30xx
+ || atemode & ATE_TXCONT
+#endif // RT30xx //
+)
+ {
+#ifdef RT30xx
+ //Hardware Reset BBP
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+ temp = temp |0x00000002;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+ temp = temp & ~(0x00000002);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+ //Restore All BBP Value
+ for(i=0;i<ATE_BBP_REG_NUM;i++)
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,i,restore_BBP[i]);
+#endif // RT30xx //
+
+ // No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ }
+ else if (atemode & ATE_TXCARRSUPP)
+ {
+#ifdef RT30xx
+ //Hardware Reset BBP
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+ temp = temp |0x00000002;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+ temp = temp & ~(0x00000002);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+ //Restore All BBP Value
+ for(i=0;i<ATE_BBP_REG_NUM;i++)
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,i,restore_BBP[i]);
+#endif // RT30xx //
+
+ // No Cont. TX set BBP R22 bit7=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= ~(1 << 7); //set bit7=0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+ // No Carrier Suppression set BBP R24 bit0=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
+ BbpData &= 0xFFFFFFFE; //clear bit0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
+ }
+ // We should free some resource which allocate when ATE_TXFRAME , ATE_STOP, and ATE_TXCONT.
+ // TODO:Should we free some resource which was allocated when LoopBack and ATE_STOP ?
+ else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
+ {
+ if (atemode & ATE_TXCONT)
+ {
+ // Not Cont. TX anymore, so set BBP R22 bit7=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= ~(1 << 7); //set bit7=0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ }
+ // Abort Tx, Rx DMA.
+ RtmpDmaEnable(pAd, 0);
+
+ {
+ // It seems nothing to free,
+ // because we didn't allocate any resource when we entered ATE_TXFRAME mode latestly.
+ }
+
+ // Start Tx, RX DMA
+ RtmpDmaEnable(pAd, 1);
+ }
+
+ RTUSBRejectPendingPackets(pAd);
+ RTUSBCleanUpDataBulkOutQueue(pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+ //
+ // It will be called in MlmeSuspend().
+ //
+ // Cancel pending timers
+ RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
+#endif // CONFIG_STA_SUPPORT //
+
+ //RTUSBCleanUpMLMEWaitQueue(pAd); /* not used in RT28xx */
+ RTUSBCleanUpMLMEBulkOutQueue(pAd);
+
+ // Sometimes kernel will hang on, so we avoid calling MlmeSuspend().
+// MlmeSuspend(pAd, TRUE);
+ //RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
+
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+
+ // Disable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Make sure there are no pending bulk in/out IRPs before we go on.
+/*=========================================================================*/
+ /* pAd->PendingRx is not of type atomic_t anymore in 28xx */
+// while ((atomic_read(&pAd->PendingRx) > 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ while ((pAd->PendingRx > 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ {
+#if 1
+ ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+ NdisInterlockedDecrement(&pAd->PendingRx);
+#endif
+ /* delay 0.5 seconds */
+ RTMPusecDelay(500000);
+ pAd->PendingRx = 0;
+ }
+ /* peter : why don't we have to get BulkOutLock first ? */
+ while (((pAd->BulkOutPending[0] == TRUE) ||
+ (pAd->BulkOutPending[1] == TRUE) ||
+ (pAd->BulkOutPending[2] == TRUE) ||
+ (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ {
+ do
+ {
+ /* pAd->BulkOutPending[y] will be set to FALSE in RTUSBCancelPendingBulkOutIRP(pAd) */
+ RTUSBCancelPendingBulkOutIRP(pAd);
+ } while (FALSE);
+
+ /* we have enough time delay in RTUSBCancelPendingBulkOutIRP(pAd)
+ ** so this is not necessary
+ */
+// RTMPusecDelay(500000);
+ }
+
+ /* pAd->PendingRx is not of type atomic_t anymore in 28xx */
+// ASSERT(atomic_read(&pAd->PendingRx) == 0);
+ ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+
+ // reset Rx statistics.
+ pAd->ate.LastSNR0 = 0;
+ pAd->ate.LastSNR1 = 0;
+ pAd->ate.LastRssi0 = 0;
+ pAd->ate.LastRssi1 = 0;
+ pAd->ate.LastRssi2 = 0;
+ pAd->ate.AvgRssi0 = 0;
+ pAd->ate.AvgRssi1 = 0;
+ pAd->ate.AvgRssi2 = 0;
+ pAd->ate.AvgRssi0X8 = 0;
+ pAd->ate.AvgRssi1X8 = 0;
+ pAd->ate.AvgRssi2X8 = 0;
+ pAd->ate.NumOfAvgRssiSample = 0;
+
+#ifdef RALINK_28xx_QA
+ // Tx frame
+ pAd->ate.bQATxStart = FALSE;
+ pAd->ate.bQARxStart = FALSE;
+ pAd->ate.seq = 0;
+
+ // counters
+ pAd->ate.U2M = 0;
+ pAd->ate.OtherData = 0;
+ pAd->ate.Beacon = 0;
+ pAd->ate.OtherCount = 0;
+ pAd->ate.TxAc0 = 0;
+ pAd->ate.TxAc1 = 0;
+ pAd->ate.TxAc2 = 0;
+ pAd->ate.TxAc3 = 0;
+ pAd->ate.TxHCCA = 0;
+ pAd->ate.TxMgmt = 0;
+ pAd->ate.RSSI0 = 0;
+ pAd->ate.RSSI1 = 0;
+ pAd->ate.RSSI2 = 0;
+ pAd->ate.SNR0 = 0;
+ pAd->ate.SNR1 = 0;
+
+ // control
+ pAd->ate.TxDoneCount = 0;
+ pAd->ate.TxStatus = 0; // task Tx status // 0 --> task is idle, 1 --> task is running
+#endif // RALINK_28xx_QA //
+
+ // Soft reset BBP.
+ BbpSoftReset(pAd);
+
+
+#ifdef CONFIG_STA_SUPPORT
+ AsicDisableSync(pAd);
+
+ /*
+ ** If we skip "LinkDown()", we should disable protection
+ ** to prevent from sending out RTS or CTS-to-self.
+ */
+ ATEDisableAsicProtect(pAd);
+ RTMPStationStop(pAd);
+#endif // CONFIG_STA_SUPPORT //
+
+ // Default value in BBP R22 is 0x0.
+ BbpData = 0;
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+
+ // Clean bit4 to stop continuous Tx production test.
+ MacData &= 0xFFFFFFEF;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+ //Clean ATE Bulk in/out counter and continue setup
+ InterlockedExchange(&pAd->BulkOutRemained, 0);
+
+ /* NdisAcquireSpinLock()/NdisReleaseSpinLock() need only one argument in RT28xx */
+ NdisAcquireSpinLock(&pAd->GenericLock);
+ pAd->ContinBulkOut = FALSE;
+ pAd->ContinBulkIn = FALSE;
+ NdisReleaseSpinLock(&pAd->GenericLock);
+
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+ }
+ else if (!strcmp(arg, "ATESTOP"))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE : ATESTOP ===>\n"));
+
+ // Default value in BBP R22 is 0x0.
+ BbpData = 0;
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);//0820
+ // Clean bit4 to stop continuous Tx production test.
+ MacData &= 0xFFFFFFEF;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); // recover the MAC_SYS_CTRL register back.
+
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ /*
+ ** Abort Tx, RX DMA.
+ ** Q : How to do the following I/O if Tx, Rx DMA is aborted ?
+ ** Ans : Bulk endpoints are aborted, while the control endpoint is not.
+ */
+ RtmpDmaEnable(pAd, 0);
+
+ // Disable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ /* Make sure there are no pending bulk in/out IRPs before we go on. */
+/*=========================================================================*/
+// while ((atomic_read(&pAd->PendingRx) > 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ while (pAd->PendingRx > 0)
+ {
+#if 1
+ ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+// NdisInterlockedDecrement(&pAd->PendingRx);
+ pAd->PendingRx--;
+#endif
+ RTMPusecDelay(500000);
+ }
+
+ while (((pAd->BulkOutPending[0] == TRUE) ||
+ (pAd->BulkOutPending[1] == TRUE) ||
+ (pAd->BulkOutPending[2] == TRUE) ||
+ (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ {
+ do
+ {
+ RTUSBCancelPendingBulkOutIRP(pAd);
+ } while (FALSE);
+
+ RTMPusecDelay(500000);
+ }
+
+// ASSERT(atomic_read(&pAd->PendingRx) == 0);
+ ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+/* Reset Rx RING */
+/*=========================================================================*/
+// InterlockedExchange(&pAd->PendingRx, 0);
+ pAd->PendingRx = 0;
+ pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
+ pAd->NextRxBulkInIndex = RX_RING_SIZE - 1; // Rx Bulk pointer
+ pAd->NextRxBulkInPosition = 0;
+ for (i = 0; i < (RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+ NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
+ /* peter : why don't we have to get BulkInLock first ? */
+ pRxContext->pAd = pAd;
+ pRxContext->pIrp = NULL;
+ /* peter debug ++ */
+ pRxContext->BulkInOffset = 0;
+ pRxContext->bRxHandling = FALSE;
+ /* peter debug -- */
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pRxContext->Readable = FALSE;
+// pRxContext->ReorderInUse = FALSE;
+// pRxContext->ReadPosOffset = 0;
+ }
+
+/*=========================================================================*/
+/* Reset Tx RING */
+/*=========================================================================*/
+ do
+ {
+ RTUSBCancelPendingBulkOutIRP(pAd);
+ } while (FALSE);
+
+/*=========================================================================*/
+ // Enable auto responder.
+ RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &temp);
+ temp = temp | (0x01);
+ RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, temp);
+
+/*================================================*/
+ AsicEnableBssSync(pAd);
+
+ /* Soft reset BBP.*/
+ /* In 2870 chipset, ATE_BBP_IO_READ8_BY_REG_ID() == RTMP_BBP_IO_READ8_BY_REG_ID() */
+ /* Both rt2870ap and rt2870sta use BbpSoftReset(pAd) to do BBP soft reset */
+ BbpSoftReset(pAd);
+/*================================================*/
+ {
+#ifdef CONFIG_STA_SUPPORT
+ // Set all state machines back IDLE
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
+#endif // CONFIG_STA_SUPPORT //
+
+ //
+ // ===> refer to MlmeRestartStateMachine().
+ // When we entered ATE_START mode, PeriodicTimer was not cancelled.
+ // So we don't have to set it here.
+ //
+ //RTMPSetTimer(pAd, &pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
+
+ ASSERT(pAd->CommonCfg.Channel != 0);
+
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+
+#ifdef CONFIG_STA_SUPPORT
+ RTMPStationStart(pAd);
+#endif // CONFIG_STA_SUPPORT //
+ }
+//
+// These two steps have been done when entering ATE_STOP mode.
+//
+ // Clean ATE Bulk in/out counter and continue setup.
+ InterlockedExchange(&pAd->BulkOutRemained, 0);
+ NdisAcquireSpinLock(&pAd->GenericLock);
+ pAd->ContinBulkOut = FALSE;
+ pAd->ContinBulkIn = FALSE;
+ NdisReleaseSpinLock(&pAd->GenericLock);
+
+ /* Wait 50ms to prevent next URB to bulkout during HW reset. */
+ /* todo : remove this if not necessary */
+ NdisMSleep(50000);
+
+ pAd->ate.Mode = ATE_STOP;
+
+ // Enable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value |= (1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+/*=========================================================================*/
+ /* restore RX_FILTR_CFG */
+#ifdef CONFIG_STA_SUPPORT
+ /* restore RX_FILTR_CFG in order that QA maybe set it to 0x3 */
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL);
+#endif // CONFIG_STA_SUPPORT //
+/*=========================================================================*/
+
+ // Enable Tx, RX DMA.
+ RtmpDmaEnable(pAd, 1);
+
+ // Enable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value |= (1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Wait 10ms to wait all of the bulk-in URBs to complete.
+ /* todo : remove this if not necessary */
+ NdisMSleep(10000);
+
+ // Everything is ready to start normal Tx/Rx.
+ RTUSBBulkReceive(pAd);
+ netif_start_queue(pAd->net_dev);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATE : ATESTOP \n"));
+ }
+ else if (!strcmp(arg, "TXCARR")) // Tx Carrier
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCARR\n"));
+ pAd->ate.Mode |= ATE_TXCARR;
+
+#ifdef RT30xx
+ for(i=0;i<ATE_BBP_REG_NUM;i++)
+ restore_BBP[i]=0;
+ //Record All BBP Value
+ for(i=0;i<ATE_BBP_REG_NUM;i++)
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd,i,&restore_BBP[i]);
+#endif // RT30xx //
+
+ // Disable Rx
+ // May be we need not to do this, because these have been done in ATE_START mode ???
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // QA has done the following steps if it is used.
+ if (pAd->ate.bQATxStart == FALSE)
+ {
+ // Soft reset BBP.
+ BbpSoftReset(pAd);
+
+ // Carrier Test set BBP R22 bit7=1, bit6=1, bit[5~0]=0x01
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
+ BbpData |= 0x000000C1; //set bit7=1, bit6=1, bit[5~0]=0x01
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+ // set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value = Value | 0x00000010;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+ }
+ }
+ else if (!strcmp(arg, "TXCONT")) // Tx Continue
+ {
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ /* set MAC_SYS_CTRL(0x1004) bit4(Continuous Tx Production Test)
+ and bit2(MAC TX enable) back to zero. */
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+ MacData &= 0xFFFFFFEB;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+ // set BBP R22 bit7=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= 0xFFFFFF7F; //set bit7=0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ }
+
+ /* for TxCont mode.
+ ** Step 1: Send 50 packets first then wait for a moment.
+ ** Step 2: Send more 50 packet then start continue mode.
+ */
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCONT\n"));
+
+#ifdef RT30xx
+ for(i=0;i<ATE_BBP_REG_NUM;i++)
+ restore_BBP[i]=0;
+ //Record All BBP Value
+ for(i=0;i<ATE_BBP_REG_NUM;i++)
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd,i,&restore_BBP[i]);
+#endif // RT30xx //
+
+ // Step 1: send 50 packets first.
+ pAd->ate.Mode |= ATE_TXCONT;
+ pAd->ate.TxCount = 50;
+ pAd->ate.TxDoneCount = 0;
+
+ // Soft reset BBP.
+ BbpSoftReset(pAd);
+
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+
+
+ /* Only needed if we have to send some normal frames. */
+ SetJapanFilter(pAd);
+
+ // Setup frame format.
+ ATESetUpFrame(pAd, 0);
+
+ // Enable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value |= (1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Start Tx, RX DMA.
+ RtmpDmaEnable(pAd, 1);
+
+ InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
+
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ pAd->ate.TxStatus = 1;
+ //pAd->ate.Repeat = 0;
+ }
+#endif // RALINK_28xx_QA //
+
+ NdisAcquireSpinLock(&pAd->GenericLock);//0820
+ pAd->ContinBulkOut = FALSE;
+ NdisReleaseSpinLock(&pAd->GenericLock);
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+
+ // Kick bulk out
+ RTUSBKickBulkOut(pAd);
+
+ /* To make sure all the 50 frames have been bulk out before executing step 2 */
+ while (atomic_read(&pAd->BulkOutRemained) > 0)
+ {
+ RTMPusecDelay(5000);
+ }
+
+ // Step 2: send more 50 packets then start continue mode.
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+
+ // Cont. TX set BBP R22 bit7=1
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData |= 0x00000080; //set bit7=1
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+ pAd->ate.TxCount = 50;
+ pAd->ate.TxDoneCount = 0;
+
+ SetJapanFilter(pAd);
+
+ // Setup frame format.
+ ATESetUpFrame(pAd, 0);
+
+ // Enable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value |= (1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+
+ // Start Tx, RX DMA.
+ RtmpDmaEnable(pAd, 1);
+
+ InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
+
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ pAd->ate.TxStatus = 1;
+ //pAd->ate.Repeat = 0;
+ }
+#endif // RALINK_28xx_QA //
+
+ NdisAcquireSpinLock(&pAd->GenericLock);//0820
+ pAd->ContinBulkOut = FALSE;
+ NdisReleaseSpinLock(&pAd->GenericLock);
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+ // Kick bulk out
+ RTUSBKickBulkOut(pAd);
+
+#if 1
+ RTMPusecDelay(500);
+#else
+ while (atomic_read(&pAd->BulkOutRemained) > 0)
+ {
+ RTMPusecDelay(5000);
+ }
+#endif // 1 //
+
+ // Set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1.
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+ MacData |= 0x00000010;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+ }
+ else if (!strcmp(arg, "TXFRAME")) // Tx Frames
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXFRAME(Count=0x%08x)\n", pAd->ate.TxCount));
+ pAd->ate.Mode |= ATE_TXFRAME;
+
+ // Soft reset BBP.
+ BbpSoftReset(pAd);
+
+ // Default value in BBP R22 is 0x0.
+ BbpData = 0;
+
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+
+ // Clean bit4 to stop continuous Tx production test.
+ MacData &= 0xFFFFFFEF;
+
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+#ifdef RALINK_28xx_QA
+ // add this for LoopBack mode
+ if (pAd->ate.bQARxStart == FALSE)
+ {
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+ }
+
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ pAd->ate.TxStatus = 1;
+ //pAd->ate.Repeat = 0;
+ }
+#else
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+#endif // RALINK_28xx_QA //
+
+ // Enable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value |= (1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ SetJapanFilter(pAd);
+
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+
+ pAd->ate.TxDoneCount = 0;
+
+ // Setup frame format
+ ATESetUpFrame(pAd, 0);
+
+ // Start Tx, RX DMA.
+ RtmpDmaEnable(pAd, 1);
+
+ // Check count is continuous or not yet.
+ //
+ // Due to the type mismatch between "pAd->BulkOutRemained"(atomic_t) and "pAd->ate.TxCount"(UINT32)
+ //
+ if (pAd->ate.TxCount == 0)
+ {
+ InterlockedExchange(&pAd->BulkOutRemained, 0);
+ }
+ else
+ {
+ InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
+ }
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("bulk out count = %d\n", atomic_read(&pAd->BulkOutRemained)));
+ ASSERT((atomic_read(&pAd->BulkOutRemained) >= 0));
+
+ if (atomic_read(&pAd->BulkOutRemained) == 0)
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Send packet countinuously\n"));
+
+ /* In 28xx, NdisAcquireSpinLock() == spin_lock_bh() */
+ /* NdisAcquireSpinLock only need one argument in 28xx. */
+ NdisAcquireSpinLock(&pAd->GenericLock);
+ pAd->ContinBulkOut = TRUE;
+ NdisReleaseSpinLock(&pAd->GenericLock);
+
+ /* In 28xx, BULK_OUT_LOCK() == spin_lock_irqsave() */
+ BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags);// peter : NdisAcquireSpinLock ==> BULK_OUT_LOCK
+ pAd->BulkOutPending[0] = FALSE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);// peter : NdisAcquireSpinLock ==> BULK_OUT_LOCK
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Send packets depend on counter\n"));
+
+ NdisAcquireSpinLock(&pAd->GenericLock);
+ pAd->ContinBulkOut = FALSE;
+ NdisReleaseSpinLock(&pAd->GenericLock);
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+ pAd->BulkOutPending[0] = FALSE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+ }
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+
+ // Kick bulk out
+ RTUSBKickBulkOut(pAd);
+ }
+#ifdef RALINK_28xx_QA
+ else if (!strcmp(arg, "TXSTOP")) //Enter ATE mode and set Tx/Rx Idle
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXSTOP\n"));
+
+ atemode = pAd->ate.Mode;
+ pAd->ate.Mode &= ATE_TXSTOP;
+ pAd->ate.bQATxStart = FALSE;
+// pAd->ate.TxDoneCount = pAd->ate.TxCount;
+
+/*=========================================================================*/
+ if (atemode & ATE_TXCARR)
+ {
+ // No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ }
+ else if (atemode & ATE_TXCARRSUPP)
+ {
+ // No Cont. TX set BBP R22 bit7=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= ~(1 << 7); //set bit7=0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+ // No Carrier Suppression set BBP R24 bit0=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
+ BbpData &= 0xFFFFFFFE; //clear bit0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
+ }
+ else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
+ {
+ if (atemode & ATE_TXCONT)
+ {
+ // No Cont. TX set BBP R22 bit7=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= ~(1 << 7); //set bit7=0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ }
+ }
+
+/*=========================================================================*/
+ RTUSBRejectPendingPackets(pAd);
+ RTUSBCleanUpDataBulkOutQueue(pAd);
+
+ /* not used in RT28xx */
+ //RTUSBCleanUpMLMEWaitQueue(pAd);
+ /* empty function so far */
+ RTUSBCleanUpMLMEBulkOutQueue(pAd);
+/*=========================================================================*/
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+/*=========================================================================*/
+
+ /* In 28xx, pAd->PendingRx is not of type atomic_t anymore */
+// while ((atomic_read(&pAd->PendingRx) > 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ /* peter todo : BulkInLock */
+ while (pAd->PendingRx > 0)
+ {
+#if 1
+ ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+// NdisInterlockedDecrement(&pAd->PendingRx);
+ pAd->PendingRx--;
+#endif
+ RTMPusecDelay(500000);
+ }
+
+ while (((pAd->BulkOutPending[0] == TRUE) ||
+ (pAd->BulkOutPending[1] == TRUE) ||
+ (pAd->BulkOutPending[2] == TRUE) ||
+ (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ {
+ do
+ {
+ RTUSBCancelPendingBulkOutIRP(pAd);
+ } while (FALSE);
+
+ RTMPusecDelay(500000);
+ }
+
+ ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+ // Enable Tx, Rx DMA.
+ RtmpDmaEnable(pAd, 1);
+
+ /* task Tx status : 0 --> task is idle, 1 --> task is running */
+ pAd->ate.TxStatus = 0;
+
+ // Soft reset BBP.
+ BbpSoftReset(pAd);
+
+ // Disable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+ MacData &= (0xfffffffb);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+ //Clean ATE Bulk in/out counter and continue setup
+ InterlockedExchange(&pAd->BulkOutRemained, 0);
+
+ pAd->ContinBulkOut = FALSE;
+ }
+ else if (!strcmp(arg, "RXSTOP"))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXSTOP\n"));
+ atemode = pAd->ate.Mode;
+
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ pAd->ate.Mode &= ATE_RXSTOP;
+ pAd->ate.bQARxStart = FALSE;
+// pAd->ate.TxDoneCount = pAd->ate.TxCount;
+
+/*=========================================================================*/
+ RTUSBRejectPendingPackets(pAd);
+ RTUSBCleanUpDataBulkOutQueue(pAd);
+
+ /* not used in RT28xx */
+ //RTUSBCleanUpMLMEWaitQueue(pAd);
+ RTUSBCleanUpMLMEBulkOutQueue(pAd);
+/*=========================================================================*/
+
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+/*=========================================================================*/
+// while ((atomic_read(&pAd->PendingRx) > 0))
+ while (pAd->PendingRx > 0)
+ {
+#if 1
+ ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+// NdisInterlockedDecrement(&pAd->PendingRx);
+ pAd->PendingRx--;
+#endif
+ RTMPusecDelay(500000);
+ }
+
+ while (((pAd->BulkOutPending[0] == TRUE) ||
+ (pAd->BulkOutPending[1] == TRUE) ||
+ (pAd->BulkOutPending[2] == TRUE) ||
+ (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ {
+ do
+ {
+ RTUSBCancelPendingBulkOutIRP(pAd);
+ } while (FALSE);
+
+ RTMPusecDelay(500000);
+ }
+
+ ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+
+ // Soft reset BBP.
+ BbpSoftReset(pAd);
+ pAd->ContinBulkIn = FALSE;
+ }
+#endif // RALINK_28xx_QA //
+ else if (!strcmp(arg, "RXFRAME")) // Rx Frames
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXFRAME\n"));
+
+ // Disable Rx of MAC block
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Default value in BBP R22 is 0x0.
+ BbpData = 0;
+
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+ // Clean bit4 to stop continuous Tx production test.
+ MacData &= 0xFFFFFFEF;
+
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+ pAd->ate.Mode |= ATE_RXFRAME;
+
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+
+ // Disable TX of MAC block
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Reset Rx RING.
+ for ( i = 0; i < (RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pRxContext->Readable = FALSE;
+
+ //
+ // Get the urb from kernel back to driver.
+ //
+ RTUSB_UNLINK_URB(pRxContext->pUrb);
+
+ /* Sleep 200 microsecs to give cancellation time to work. */
+ NdisMSleep(200);
+ pAd->BulkInReq = 0;
+
+// InterlockedExchange(&pAd->PendingRx, 0);
+ pAd->PendingRx = 0;
+ pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
+ pAd->NextRxBulkInIndex = RX_RING_SIZE - 1; // Rx Bulk pointer
+ pAd->NextRxBulkInPosition = 0;
+ }
+
+ // read to clear counters
+ RTUSBReadMACRegister(pAd, RX_STA_CNT0, &temp); //RX PHY & RX CRC count
+ RTUSBReadMACRegister(pAd, RX_STA_CNT1, &temp); //RX PLCP error count & CCA false alarm count
+ RTUSBReadMACRegister(pAd, RX_STA_CNT2, &temp); //RX FIFO overflow frame count & RX duplicated filtered frame count
+
+ pAd->ContinBulkIn = TRUE;
+
+ // Enable Tx, RX DMA.
+ RtmpDmaEnable(pAd, 1);
+
+ // Enable RX of MAC block
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value |= (1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Kick bulk in
+ RTUSBBulkReceive(pAd);
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: Invalid arg!\n"));
+ return FALSE;
+ }
+ RTMPusecDelay(5000);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATECmdHandler()\n"));
+
+ return TRUE;
+}
+#endif // RT2870 //
+
+INT Set_ATE_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ if (ATECmdHandler(pAd, arg))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Success\n"));
+
+
+ return TRUE;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Failed\n"));
+ return FALSE;
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE ADDR1=DA for TxFrame(AP : To DS = 0 ; From DS = 1)
+ or
+ Set ATE ADDR3=DA for TxFrame(STA : To DS = 1 ; From DS = 0)
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_DA_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR *value;
+ INT i;
+
+ if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
+ return FALSE;
+
+ for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+ {
+ if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ return FALSE; //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+ AtoH(value, &pAd->ate.Addr3[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ if(i != 6)
+ return FALSE; //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_DA_Proc (DA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr3[0],
+ pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]));
+#endif // CONFIG_STA_SUPPORT //
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_DA_Proc Success\n"));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE ADDR3=SA for TxFrame(AP : To DS = 0 ; From DS = 1)
+ or
+ Set ATE ADDR2=SA for TxFrame(STA : To DS = 1 ; From DS = 0)
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_SA_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR *value;
+ INT i;
+
+ if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
+ return FALSE;
+
+ for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+ {
+ if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ return FALSE; //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+ AtoH(value, &pAd->ate.Addr2[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ if(i != 6)
+ return FALSE; //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_SA_Proc (SA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr2[0],
+ pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]));
+#endif // CONFIG_STA_SUPPORT //
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_SA_Proc Success\n"));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE ADDR2=BSSID for TxFrame(AP : To DS = 0 ; From DS = 1)
+ or
+ Set ATE ADDR1=BSSID for TxFrame(STA : To DS = 1 ; From DS = 0)
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_BSSID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR *value;
+ INT i;
+
+ if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
+ return FALSE;
+
+ for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+ {
+ if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ return FALSE; //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+ AtoH(value, &pAd->ate.Addr1[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ if(i != 6)
+ return FALSE; //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_BSSID_Proc (BSSID = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr1[0],
+ pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]));
+#endif // CONFIG_STA_SUPPORT //
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_BSSID_Proc Success\n"));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx Channel
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_CHANNEL_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR channel;
+
+ channel = simple_strtol(arg, 0, 10);
+
+ if ((channel < 1) || (channel > 216))// to allow A band channel : ((channel < 1) || (channel > 14))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_CHANNEL_Proc::Out of range, it should be in range of 1~14.\n"));
+ return FALSE;
+ }
+ pAd->ate.Channel = channel;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_CHANNEL_Proc (ATE Channel = %d)\n", pAd->ate.Channel));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_CHANNEL_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx Power0
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_POWER0_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR TxPower;
+
+ TxPower = simple_strtol(arg, 0, 10);
+
+ if (pAd->ate.Channel <= 14)
+ {
+ if ((TxPower > 31) || (TxPower < 0))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
+ return FALSE;
+ }
+ }
+ else// 5.5GHz
+ {
+ if ((TxPower > 15) || (TxPower < -7))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
+ return FALSE;
+ }
+ }
+
+ pAd->ate.TxPower0 = TxPower;
+ ATETxPwrHandler(pAd, 0);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER0_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx Power1
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_POWER1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR TxPower;
+
+ TxPower = simple_strtol(arg, 0, 10);
+
+ if (pAd->ate.Channel <= 14)
+ {
+ if ((TxPower > 31) || (TxPower < 0))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
+ return FALSE;
+ }
+ }
+ else
+ {
+ if ((TxPower > 15) || (TxPower < -7))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
+ return FALSE;
+ }
+ }
+
+ pAd->ate.TxPower1 = TxPower;
+ ATETxPwrHandler(pAd, 1);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER1_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx Antenna
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_Antenna_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR value;
+
+ value = simple_strtol(arg, 0, 10);
+
+ if ((value > 2) || (value < 0))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_Antenna_Proc::Out of range (Value=%d)\n", value));
+ return FALSE;
+ }
+
+ pAd->ate.TxAntennaSel = value;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_Antenna_Proc (Antenna = %d)\n", pAd->ate.TxAntennaSel));
+ ATEDBGPRINT(RT_DEBUG_TRACE,("Ralink: Set_ATE_TX_Antenna_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Rx Antenna
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_RX_Antenna_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR value;
+
+ value = simple_strtol(arg, 0, 10);
+
+ if ((value > 3) || (value < 0))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_RX_Antenna_Proc::Out of range (Value=%d)\n", value));
+ return FALSE;
+ }
+
+ pAd->ate.RxAntennaSel = value;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_Antenna_Proc (Antenna = %d)\n", pAd->ate.RxAntennaSel));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_Antenna_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE RF frequence offset
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_FREQOFFSET_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR RFFreqOffset;
+ ULONG R4;
+
+ RFFreqOffset = simple_strtol(arg, 0, 10);
+#ifndef RT30xx
+ if(RFFreqOffset >= 64)
+#endif // RT30xx //
+#ifdef RT30xx
+//2008/08/06: KH modified the limit of offset value from 65 to 95(0x5F)
+ if(RFFreqOffset >= 95)
+#endif // RT30xx //
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_FREQOFFSET_Proc::Out of range, it should be in range of 0~63.\n"));
+ return FALSE;
+ }
+
+ pAd->ate.RFFreqOffset = RFFreqOffset;
+#ifdef RT30xx
+ if(IS_RT30xx(pAd))
+ {
+ // Set RF offset
+ UCHAR RFValue;
+ RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue);
+ //2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
+ RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset;
+ RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
+ }
+ else
+#endif // RT30xx //
+ {
+
+ R4 = pAd->ate.RFFreqOffset << 15; // shift TX power control to correct RF register bit position
+ R4 |= (pAd->LatchRfRegs.R4 & ((~0x001f8000)));
+ pAd->LatchRfRegs.R4 = R4;
+
+ RtmpRfIoWrite(pAd);
+ }
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_FREQOFFSET_Proc (RFFreqOffset = %d)\n", pAd->ate.RFFreqOffset));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_FREQOFFSET_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE RF BW
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_BW_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ int i;
+ UCHAR value = 0;
+ UCHAR BBPCurrentBW;
+
+ BBPCurrentBW = simple_strtol(arg, 0, 10);
+
+ if(BBPCurrentBW == 0)
+ pAd->ate.TxWI.BW = BW_20;
+ else
+ pAd->ate.TxWI.BW = BW_40;
+
+ if(pAd->ate.TxWI.BW == BW_20)
+ {
+ if(pAd->ate.Channel <= 14)
+ {
+ for (i=0; i<5; i++)
+ {
+ if (pAd->Tx20MPwrCfgGBand[i] != 0xffffffff)
+ {
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgGBand[i]);
+ RTMPusecDelay(5000);
+ }
+ }
+ }
+ else
+ {
+ for (i=0; i<5; i++)
+ {
+ if (pAd->Tx20MPwrCfgABand[i] != 0xffffffff)
+ {
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgABand[i]);
+ RTMPusecDelay(5000);
+ }
+ }
+ }
+
+ //Set BBP R4 bit[4:3]=0:0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
+ value &= (~0x18);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+
+ //Set BBP R66=0x3C
+ value = 0x3C;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
+ //Set BBP R68=0x0B
+ //to improve Rx sensitivity.
+ value = 0x0B;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
+ //Set BBP R69=0x16
+ value = 0x16;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
+ //Set BBP R70=0x08
+ value = 0x08;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
+ //Set BBP R73=0x11
+ value = 0x11;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
+
+ // If Channel=14, Bandwidth=20M and Mode=CCK, Set BBP R4 bit5=1
+ // (Japan filter coefficients)
+ // This segment of code will only works when ATETXMODE and ATECHANNEL
+ // were set to MODE_CCK and 14 respectively before ATETXBW is set to 0.
+ //=====================================================================
+ if (pAd->ate.Channel == 14)
+ {
+ int TxMode = pAd->ate.TxWI.PHYMODE;
+ if (TxMode == MODE_CCK)
+ {
+ // when Channel==14 && Mode==CCK && BandWidth==20M, BBP R4 bit5=1
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
+ value |= 0x20; //set bit5=1
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+ }
+ }
+
+ //=====================================================================
+ // If bandwidth != 40M, RF Reg4 bit 21 = 0.
+#ifdef RT30xx
+ // Set BW
+ if(IS_RT30xx(pAd))
+ RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW20RfR24);
+ else
+#endif // RT30xx //
+ {
+ pAd->LatchRfRegs.R4 &= ~0x00200000;
+ RtmpRfIoWrite(pAd);
+ }
+
+ }
+ else if(pAd->ate.TxWI.BW == BW_40)
+ {
+ if(pAd->ate.Channel <= 14)
+ {
+ for (i=0; i<5; i++)
+ {
+ if (pAd->Tx40MPwrCfgGBand[i] != 0xffffffff)
+ {
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgGBand[i]);
+ RTMPusecDelay(5000);
+ }
+ }
+ }
+ else
+ {
+ for (i=0; i<5; i++)
+ {
+ if (pAd->Tx40MPwrCfgABand[i] != 0xffffffff)
+ {
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgABand[i]);
+ RTMPusecDelay(5000);
+ }
+ }
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->ate.TxWI.PHYMODE >= MODE_HTMIX) && (pAd->ate.TxWI.MCS == 7))
+ {
+ value = 0x28;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R67, value);
+ }
+#endif // DOT11_N_SUPPORT //
+ }
+
+ //Set BBP R4 bit[4:3]=1:0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
+ value &= (~0x18);
+ value |= 0x10;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+
+ //Set BBP R66=0x3C
+ value = 0x3C;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
+ //Set BBP R68=0x0C
+ //to improve Rx sensitivity.
+ value = 0x0C;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
+ //Set BBP R69=0x1A
+ value = 0x1A;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
+ //Set BBP R70=0x0A
+ value = 0x0A;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
+ //Set BBP R73=0x16
+ value = 0x16;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
+
+ // If bandwidth = 40M, set RF Reg4 bit 21 = 1.
+#ifdef RT30xx
+ // Set BW
+ if(IS_RT30xx(pAd))
+ RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW40RfR24);
+ else
+#endif // RT30xx //
+ {
+ pAd->LatchRfRegs.R4 |= 0x00200000;
+ RtmpRfIoWrite(pAd);
+ }
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_BW_Proc (BBPCurrentBW = %d)\n", pAd->ate.TxWI.BW));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_BW_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx frame length
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_LENGTH_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ pAd->ate.TxLength = simple_strtol(arg, 0, 10);
+
+ if((pAd->ate.TxLength < 24) || (pAd->ate.TxLength > (MAX_FRAME_SIZE - 34/* == 2312 */)))
+ {
+ pAd->ate.TxLength = (MAX_FRAME_SIZE - 34/* == 2312 */);
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_LENGTH_Proc::Out of range, it should be in range of 24~%d.\n", (MAX_FRAME_SIZE - 34/* == 2312 */)));
+ return FALSE;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_LENGTH_Proc (TxLength = %d)\n", pAd->ate.TxLength));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_LENGTH_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx frame count
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_COUNT_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ pAd->ate.TxCount = simple_strtol(arg, 0, 10);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_COUNT_Proc (TxCount = %d)\n", pAd->ate.TxCount));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_COUNT_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx frame MCS
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_MCS_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR MCS;
+ int result;
+
+ MCS = simple_strtol(arg, 0, 10);
+ result = CheckMCSValid(pAd->ate.TxWI.PHYMODE, MCS);
+
+ if (result != -1)
+ {
+ pAd->ate.TxWI.MCS = (UCHAR)MCS;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MCS_Proc::Out of range, refer to rate table.\n"));
+ return FALSE;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MCS_Proc (MCS = %d)\n", pAd->ate.TxWI.MCS));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MCS_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx frame Mode
+ 0: MODE_CCK
+ 1: MODE_OFDM
+ 2: MODE_HTMIX
+ 3: MODE_HTGREENFIELD
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_MODE_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ pAd->ate.TxWI.PHYMODE = simple_strtol(arg, 0, 10);
+
+ if(pAd->ate.TxWI.PHYMODE > 3)
+ {
+ pAd->ate.TxWI.PHYMODE = 0;
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MODE_Proc::Out of range. it should be in range of 0~3\n"));
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("0: CCK, 1: OFDM, 2: HT_MIX, 3: HT_GREEN_FIELD.\n"));
+ return FALSE;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MODE_Proc (TxMode = %d)\n", pAd->ate.TxWI.PHYMODE));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MODE_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx frame GI
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_GI_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ pAd->ate.TxWI.ShortGI = simple_strtol(arg, 0, 10);
+
+ if(pAd->ate.TxWI.ShortGI > 1)
+ {
+ pAd->ate.TxWI.ShortGI = 0;
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_GI_Proc::Out of range\n"));
+ return FALSE;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_GI_Proc (GI = %d)\n", pAd->ate.TxWI.ShortGI));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_GI_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+INT Set_ATE_RX_FER_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ pAd->ate.bRxFer = simple_strtol(arg, 0, 10);
+
+ if (pAd->ate.bRxFer == 1)
+ {
+ pAd->ate.RxCntPerSec = 0;
+ pAd->ate.RxTotalCnt = 0;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_FER_Proc (bRxFer = %d)\n", pAd->ate.bRxFer));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_FER_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+INT Set_ATE_Read_RF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support RT30xx ATE<--
+ if(IS_RT30xx(pAd))
+ {
+ /* modify by WY for Read RF Reg. error */
+ UCHAR RFValue;
+ INT index=0;
+ for (index = 0; index < 32; index++)
+ {
+ RT30xxReadRFRegister(pAd, index, (PUCHAR)&RFValue);
+ printk("R%d=%d\n",index,RFValue);
+ }
+ }
+ else
+//2008/07/10:KH add to support RT30xx ATE-->
+#endif // RT30xx //
+ {
+ ate_print(KERN_EMERG "R1 = %lx\n", pAd->LatchRfRegs.R1);
+ ate_print(KERN_EMERG "R2 = %lx\n", pAd->LatchRfRegs.R2);
+ ate_print(KERN_EMERG "R3 = %lx\n", pAd->LatchRfRegs.R3);
+ ate_print(KERN_EMERG "R4 = %lx\n", pAd->LatchRfRegs.R4);
+ }
+ return TRUE;
+}
+
+INT Set_ATE_Write_RF1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+ if(IS_RT30xx(pAd))
+ {
+ printk("Warning!! RT30xx Don't Support\n");
+ return FALSE;
+
+ }
+ else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+ {
+ UINT32 value = simple_strtol(arg, 0, 16);
+
+ pAd->LatchRfRegs.R1 = value;
+ RtmpRfIoWrite(pAd);
+ }
+ return TRUE;
+
+}
+
+INT Set_ATE_Write_RF2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+ if(IS_RT30xx(pAd))
+ {
+ printk("Warning!! RT30xx Don't Support\n");
+ return FALSE;
+
+ }
+ else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+ {
+ UINT32 value = simple_strtol(arg, 0, 16);
+
+ pAd->LatchRfRegs.R2 = value;
+ RtmpRfIoWrite(pAd);
+ }
+ return TRUE;
+}
+
+INT Set_ATE_Write_RF3_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+ if(IS_RT30xx(pAd))
+ {
+ printk("Warning!! RT30xx Don't Support\n");
+ return FALSE;
+
+ }
+ else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+ {
+ UINT32 value = simple_strtol(arg, 0, 16);
+
+ pAd->LatchRfRegs.R3 = value;
+ RtmpRfIoWrite(pAd);
+ }
+ return TRUE;
+}
+
+INT Set_ATE_Write_RF4_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+ if(IS_RT30xx(pAd))
+ {
+ printk("Warning!! RT30xx Don't Support\n");
+ return FALSE;
+
+ }
+ else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+ {
+ UINT32 value = simple_strtol(arg, 0, 16);
+
+ pAd->LatchRfRegs.R4 = value;
+ RtmpRfIoWrite(pAd);
+ }
+ return TRUE;
+}
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+INT SET_ATE_3070RF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR *this_char;
+ CHAR *value;
+ UINT32 Reg,RFValue;
+ if(IS_RT30xx(pAd))
+ {
+ printk("SET_ATE_3070RF_Proc=%s\n",arg);
+ this_char =arg;
+ if ((value = strchr(this_char, ':')) != NULL)
+ *value++ = 0;
+ Reg= simple_strtol(this_char, 0, 16);
+ RFValue= simple_strtol(value, 0, 16);
+ printk("RF Reg[%d]=%d\n",Reg,RFValue);
+ RT30xxWriteRFRegister(pAd, Reg,RFValue);
+ }
+ else
+ printk("Warning!! Only 3070 Support\n");
+ return TRUE;
+}
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+/*
+ ==========================================================================
+ Description:
+ Load and Write EEPROM from a binary file prepared in advance.
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+#ifndef UCOS
+INT Set_ATE_Load_E2P_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ BOOLEAN ret = FALSE;
+ PUCHAR src = EEPROM_BIN_FILE_NAME;
+ struct file *srcf;
+ INT32 retval, orgfsuid, orgfsgid;
+ mm_segment_t orgfs;
+ USHORT WriteEEPROM[(EEPROM_SIZE/2)];
+ UINT32 FileLength = 0;
+ UINT32 value = simple_strtol(arg, 0, 10);
+
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("===> %s (value=%d)\n\n", __FUNCTION__, value));
+
+ if (value > 0)
+ {
+ /* zero the e2p buffer */
+ NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
+
+ /* save uid and gid used for filesystem access.
+ ** set user and group to 0 (root)
+ */
+ orgfsuid = current->fsuid;
+ orgfsgid = current->fsgid;
+ /* as root */
+ current->fsuid = current->fsgid = 0;
+ orgfs = get_fs();
+ set_fs(KERNEL_DS);
+
+ do
+ {
+ /* open the bin file */
+ srcf = filp_open(src, O_RDONLY, 0);
+
+ if (IS_ERR(srcf))
+ {
+ ate_print("%s - Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(srcf), src);
+ break;
+ }
+
+ /* the object must have a read method */
+ if ((srcf->f_op == NULL) || (srcf->f_op->read == NULL))
+ {
+ ate_print("%s - %s does not have a read method\n", __FUNCTION__, src);
+ break;
+ }
+
+ /* read the firmware from the file *.bin */
+ FileLength = srcf->f_op->read(srcf,
+ (PUCHAR)WriteEEPROM,
+ EEPROM_SIZE,
+ &srcf->f_pos);
+
+ if (FileLength != EEPROM_SIZE)
+ {
+ ate_print("%s: error file length (=%d) in e2p.bin\n",
+ __FUNCTION__, FileLength);
+ break;
+ }
+ else
+ {
+ /* write the content of .bin file to EEPROM */
+ rt_ee_write_all(pAd, WriteEEPROM);
+ ret = TRUE;
+ }
+ break;
+ } while(TRUE);
+
+ /* close firmware file */
+ if (IS_ERR(srcf))
+ {
+ ;
+ }
+ else
+ {
+ retval = filp_close(srcf, NULL);
+ if (retval)
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src));
+
+ }
+ }
+
+ /* restore */
+ set_fs(orgfs);
+ current->fsuid = orgfsuid;
+ current->fsgid = orgfsgid;
+ }
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("<=== %s (ret=%d)\n", __FUNCTION__, ret));
+
+ return ret;
+
+}
+#else
+INT Set_ATE_Load_E2P_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ USHORT WriteEEPROM[(EEPROM_SIZE/2)];
+ struct iwreq *wrq = (struct iwreq *)arg;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("===> %s (wrq->u.data.length = %d)\n\n", __FUNCTION__, wrq->u.data.length));
+
+ if (wrq->u.data.length != EEPROM_SIZE)
+ {
+ ate_print("%s: error length (=%d) from host\n",
+ __FUNCTION__, wrq->u.data.length);
+ return FALSE;
+ }
+ else/* (wrq->u.data.length == EEPROM_SIZE) */
+ {
+ /* zero the e2p buffer */
+ NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
+
+ /* fill the local buffer */
+ NdisMoveMemory((PUCHAR)WriteEEPROM, wrq->u.data.pointer, wrq->u.data.length);
+
+ do
+ {
+ /* write the content of .bin file to EEPROM */
+ rt_ee_write_all(pAd, WriteEEPROM);
+
+ } while(FALSE);
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== %s\n", __FUNCTION__));
+
+ return TRUE;
+
+}
+#endif // !UCOS //
+
+INT Set_ATE_Read_E2P_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ USHORT buffer[EEPROM_SIZE/2];
+ USHORT *p;
+ int i;
+
+ rt_ee_read_all(pAd, (USHORT *)buffer);
+ p = buffer;
+ for (i = 0; i < (EEPROM_SIZE/2); i++)
+ {
+ ate_print("%4.4x ", *p);
+ if (((i+1) % 16) == 0)
+ ate_print("\n");
+ p++;
+ }
+ return TRUE;
+}
+
+INT Set_ATE_Show_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ate_print("Mode=%d\n", pAd->ate.Mode);
+ ate_print("TxPower0=%d\n", pAd->ate.TxPower0);
+ ate_print("TxPower1=%d\n", pAd->ate.TxPower1);
+ ate_print("TxAntennaSel=%d\n", pAd->ate.TxAntennaSel);
+ ate_print("RxAntennaSel=%d\n", pAd->ate.RxAntennaSel);
+ ate_print("BBPCurrentBW=%d\n", pAd->ate.TxWI.BW);
+ ate_print("GI=%d\n", pAd->ate.TxWI.ShortGI);
+ ate_print("MCS=%d\n", pAd->ate.TxWI.MCS);
+ ate_print("TxMode=%d\n", pAd->ate.TxWI.PHYMODE);
+ ate_print("Addr1=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pAd->ate.Addr1[0], pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]);
+ ate_print("Addr2=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pAd->ate.Addr2[0], pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]);
+ ate_print("Addr3=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pAd->ate.Addr3[0], pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]);
+ ate_print("Channel=%d\n", pAd->ate.Channel);
+ ate_print("TxLength=%d\n", pAd->ate.TxLength);
+ ate_print("TxCount=%u\n", pAd->ate.TxCount);
+ ate_print("RFFreqOffset=%d\n", pAd->ate.RFFreqOffset);
+ ate_print(KERN_EMERG "Set_ATE_Show_Proc Success\n");
+ return TRUE;
+}
+
+INT Set_ATE_Help_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ate_print("ATE=ATESTART, ATESTOP, TXCONT, TXCARR, TXFRAME, RXFRAME\n");
+ ate_print("ATEDA\n");
+ ate_print("ATESA\n");
+ ate_print("ATEBSSID\n");
+ ate_print("ATECHANNEL, range:0~14(unless A band !)\n");
+ ate_print("ATETXPOW0, set power level of antenna 1.\n");
+ ate_print("ATETXPOW1, set power level of antenna 2.\n");
+ ate_print("ATETXANT, set TX antenna. 0:all, 1:antenna one, 2:antenna two.\n");
+ ate_print("ATERXANT, set RX antenna.0:all, 1:antenna one, 2:antenna two, 3:antenna three.\n");
+ ate_print("ATETXFREQOFFSET, set frequency offset, range 0~63\n");
+ ate_print("ATETXBW, set BandWidth, 0:20MHz, 1:40MHz.\n");
+ ate_print("ATETXLEN, set Frame length, range 24~%d\n", (MAX_FRAME_SIZE - 34/* == 2312 */));
+ ate_print("ATETXCNT, set how many frame going to transmit.\n");
+ ate_print("ATETXMCS, set MCS, reference to rate table.\n");
+ ate_print("ATETXMODE, set Mode 0:CCK, 1:OFDM, 2:HT-Mix, 3:GreenField, reference to rate table.\n");
+ ate_print("ATETXGI, set GI interval, 0:Long, 1:Short\n");
+ ate_print("ATERXFER, 0:disable Rx Frame error rate. 1:enable Rx Frame error rate.\n");
+ ate_print("ATERRF, show all RF registers.\n");
+ ate_print("ATEWRF1, set RF1 register.\n");
+ ate_print("ATEWRF2, set RF2 register.\n");
+ ate_print("ATEWRF3, set RF3 register.\n");
+ ate_print("ATEWRF4, set RF4 register.\n");
+ ate_print("ATELDE2P, load EEPROM from .bin file.\n");
+ ate_print("ATERE2P, display all EEPROM content.\n");
+ ate_print("ATESHOW, display all parameters of ATE.\n");
+ ate_print("ATEHELP, online help.\n");
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ AsicSwitchChannel() dedicated for ATE.
+
+ ==========================================================================
+*/
+VOID ATEAsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0, Value = 0;
+ CHAR TxPwer = 0, TxPwer2 = 0;
+ UCHAR index, BbpValue = 0, R66 = 0x30;
+ RTMP_RF_REGS *RFRegTable;
+ UCHAR Channel;
+
+#ifdef RALINK_28xx_QA
+ if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
+ {
+ if (pAd->ate.Channel != pAd->LatchRfRegs.Channel)
+ {
+ pAd->ate.Channel = pAd->LatchRfRegs.Channel;
+ }
+ return;
+ }
+ else
+#endif // RALINK_28xx_QA //
+ Channel = pAd->ate.Channel;
+
+ // Select antenna
+ AsicAntennaSelect(pAd, Channel);
+
+ // fill Tx power value
+ TxPwer = pAd->ate.TxPower0;
+ TxPwer2 = pAd->ate.TxPower1;
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+
+ // The RF programming sequence is difference between 3xxx and 2xxx
+ // The 3070 is 1T1R. Therefore, we don't need to set the number of Tx/Rx path and the only job is to set the parameters of channels.
+ if (IS_RT30xx(pAd) && ((pAd->RfIcType == RFIC_3020) ||
+(pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022) ||
+(pAd->RfIcType == RFIC_2020)))
+ {
+ /* modify by WY for Read RF Reg. error */
+ UCHAR RFValue;
+
+ for (index = 0; index < NUM_OF_3020_CHNL; index++)
+ {
+ if (Channel == FreqItems3020[index].Channel)
+ {
+ // Programming channel parameters
+ RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
+ RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
+
+ RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RFValue);
+ RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
+ RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RFValue);
+
+ // Set Tx Power
+ RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue);
+ RFValue = (RFValue & 0xE0) | TxPwer;
+ RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)RFValue);
+
+ // Set RF offset
+ RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue);
+ //2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
+ RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset;
+ RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
+
+ // Set BW
+ if (pAd->ate.TxWI.BW == BW_40)
+ {
+ RFValue = pAd->Mlme.CaliBW40RfR24;
+ //DISABLE_11N_CHECK(pAd);
+ }
+ else
+ {
+ RFValue = pAd->Mlme.CaliBW20RfR24;
+ }
+ RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR)RFValue);
+
+ // Enable RF tuning
+ RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)&RFValue);
+ RFValue = RFValue | 0x1;
+ RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue);
+
+ // latch channel for future usage.
+ pAd->LatchRfRegs.Channel = Channel;
+
+ break;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
+ Channel,
+ pAd->RfIcType,
+ TxPwer,
+ TxPwer2,
+ pAd->Antenna.field.TxPath,
+ FreqItems3020[index].N,
+ FreqItems3020[index].K,
+ FreqItems3020[index].R));
+ }
+ else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+{
+ RFRegTable = RF2850RegTable;
+
+ switch (pAd->RfIcType)
+ {
+ /* But only 2850 and 2750 support 5.5GHz band... */
+ case RFIC_2820:
+ case RFIC_2850:
+ case RFIC_2720:
+ case RFIC_2750:
+
+ for (index = 0; index < NUM_OF_2850_CHNL; index++)
+ {
+ if (Channel == RFRegTable[index].Channel)
+ {
+ R2 = RFRegTable[index].R2;
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
+ }
+
+ if (pAd->Antenna.field.RxPath == 2)
+ {
+ switch (pAd->ate.RxAntennaSel)
+ {
+ case 1:
+ R2 |= 0x20040;
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ BbpValue |= 0x00;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ case 2:
+ R2 |= 0x10040;
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ BbpValue |= 0x01;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ default:
+ R2 |= 0x40;
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ /* Only enable two Antenna to receive. */
+ BbpValue |= 0x08;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ }
+ }
+ else if (pAd->Antenna.field.RxPath == 1)
+ {
+ R2 |= 0x20040; // write 1 to off RxPath
+ }
+
+ if (pAd->Antenna.field.TxPath == 2)
+ {
+ if (pAd->ate.TxAntennaSel == 1)
+ {
+ R2 |= 0x4000; // If TX Antenna select is 1 , bit 14 = 1; Disable Ant 2
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
+ BbpValue &= 0xE7; //11100111B
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
+ }
+ else if (pAd->ate.TxAntennaSel == 2)
+ {
+ R2 |= 0x8000; // If TX Antenna select is 2 , bit 15 = 1; Disable Ant 1
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
+ BbpValue &= 0xE7;
+ BbpValue |= 0x08;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
+ }
+ else
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
+ BbpValue &= 0xE7;
+ BbpValue |= 0x10;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
+ }
+ }
+ if (pAd->Antenna.field.RxPath == 3)
+ {
+ switch (pAd->ate.RxAntennaSel)
+ {
+ case 1:
+ R2 |= 0x20040;
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ BbpValue |= 0x00;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ case 2:
+ R2 |= 0x10040;
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ BbpValue |= 0x01;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ case 3:
+ R2 |= 0x30000;
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ BbpValue |= 0x02;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ default:
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ BbpValue |= 0x10;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ }
+ }
+
+ if (Channel > 14)
+ {
+ // initialize R3, R4
+ R3 = (RFRegTable[index].R3 & 0xffffc1ff);
+ R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15);
+
+ // According the Rory's suggestion to solve the middle range issue.
+ // 5.5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
+ // R3
+ if ((TxPwer >= -7) && (TxPwer < 0))
+ {
+ TxPwer = (7+TxPwer);
+ TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+ R3 |= (TxPwer << 10);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer=%d \n", TxPwer));
+ }
+ else
+ {
+ TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+ R3 |= (TxPwer << 10) | (1 << 9);
+ }
+
+ // R4
+ if ((TxPwer2 >= -7) && (TxPwer2 < 0))
+ {
+ TxPwer2 = (7+TxPwer2);
+ TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+ R4 |= (TxPwer2 << 7);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
+ }
+ else
+ {
+ TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+ R4 |= (TxPwer2 << 7) | (1 << 6);
+ }
+ }
+ else
+ {
+ R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
+ R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15) | (TxPwer2 <<6);// Set freq offset & TxPwr1
+ }
+
+ // Based on BBP current mode before changing RF channel.
+ if (pAd->ate.TxWI.BW == BW_40)
+ {
+ R4 |=0x200000;
+ }
+
+ // Update variables
+ pAd->LatchRfRegs.Channel = Channel;
+ pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
+ pAd->LatchRfRegs.R2 = R2;
+ pAd->LatchRfRegs.R3 = R3;
+ pAd->LatchRfRegs.R4 = R4;
+
+ RtmpRfIoWrite(pAd);
+
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+ // Change BBP setting during switch from a->g, g->a
+ if (Channel <= 14)
+ {
+ ULONG TxPinCfg = 0x00050F0A;// 2007.10.09 by Brian : 0x0005050A ==> 0x00050F0A
+
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+
+ /* For 1T/2R chip only... */
+ if (pAd->NicConfig2.field.ExternalLNAForG)
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+ }
+ else
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
+ }
+
+ // According the Rory's suggestion to solve the middle range issue.
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
+ ASSERT((BbpValue == 0x00));
+ if ((BbpValue != 0x00))
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
+ }
+
+ // 5.5GHz band selection PIN, bit1 and bit2 are complement
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+ Value &= (~0x6);
+ Value |= (0x04);
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+ // Turn off unused PA or LNA when only 1T or 1R.
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFFFF3;
+ }
+ if (pAd->Antenna.field.RxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFF3FF;
+ }
+
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+ }
+ else
+ {
+ ULONG TxPinCfg = 0x00050F05;//2007.10.09 by Brian : 0x00050505 ==> 0x00050F05
+
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
+
+ // According the Rory's suggestion to solve the middle range issue.
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
+ ASSERT((BbpValue == 0x00));
+ if ((BbpValue != 0x00))
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
+ }
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R91, &BbpValue);
+ ASSERT((BbpValue == 0x04));
+
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R92, &BbpValue);
+ ASSERT((BbpValue == 0x00));
+
+ // 5.5GHz band selection PIN, bit1 and bit2 are complement
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+ Value &= (~0x6);
+ Value |= (0x02);
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+ // Turn off unused PA or LNA when only 1T or 1R.
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFFFF3;
+ }
+ if (pAd->Antenna.field.RxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFF3FF;
+ }
+
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+ }
+
+ // R66 should be set according to Channel and use 20MHz when scanning
+ if (Channel <= 14)
+ {
+ // BG band
+ R66 = 0x2E + GET_LNA_GAIN(pAd);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ else
+ {
+ // 5.5 GHz band
+ if (pAd->ate.TxWI.BW == BW_20)
+ {
+ R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ else
+ {
+ R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+
+ //
+ // On 11A, We should delay and wait RF/BBP to be stable
+ // and the appropriate time should be 1000 micro seconds
+ // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
+ //
+ RTMPusecDelay(1000);
+
+ if (Channel > 14)
+ {
+ // When 5.5GHz band the LSB of TxPwr will be used to reduced 7dB or not.
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
+ Channel,
+ pAd->RfIcType,
+ pAd->Antenna.field.TxPath,
+ pAd->LatchRfRegs.R1,
+ pAd->LatchRfRegs.R2,
+ pAd->LatchRfRegs.R3,
+ pAd->LatchRfRegs.R4));
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%u, Pwr1=%u, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
+ Channel,
+ pAd->RfIcType,
+ (R3 & 0x00003e00) >> 9,
+ (R4 & 0x000007c0) >> 6,
+ pAd->Antenna.field.TxPath,
+ pAd->LatchRfRegs.R1,
+ pAd->LatchRfRegs.R2,
+ pAd->LatchRfRegs.R3,
+ pAd->LatchRfRegs.R4));
+ }
+}
+
+//
+// In fact, no one will call this routine so far !
+//
+/*
+ ==========================================================================
+ Description:
+ Gives CCK TX rate 2 more dB TX power.
+ This routine works only in ATE mode.
+
+ calculate desired Tx power in RF R3.Tx0~5, should consider -
+ 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
+ 1. TxPowerPercentage
+ 2. auto calibration based on TSSI feedback
+ 3. extra 2 db for CCK
+ 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
+
+ NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
+ it should be called AFTER MlmeDynamicTxRateSwitching()
+ ==========================================================================
+ */
+VOID ATEAsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i, j;
+ CHAR DeltaPwr = 0;
+ BOOLEAN bAutoTxAgc = FALSE;
+ UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
+ UCHAR BbpR49 = 0, idx;
+ PCHAR pTxAgcCompensate;
+ ULONG TxPwr[5];
+ CHAR Value;
+
+ /* no one calls this procedure so far */
+ if (pAd->ate.TxWI.BW == BW_40)
+ {
+ if (pAd->ate.Channel > 14)
+ {
+ TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
+ TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
+ TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
+ TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
+ TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
+ }
+ else
+ {
+ TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
+ TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
+ TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
+ TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
+ TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
+ }
+ }
+ else
+ {
+ if (pAd->ate.Channel > 14)
+ {
+ TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
+ TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
+ TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
+ TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
+ TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
+ }
+ else
+ {
+ TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
+ TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
+ TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
+ TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
+ TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
+ }
+ }
+
+ // TX power compensation for temperature variation based on TSSI.
+ // Do it per 4 seconds.
+ if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
+ {
+ if (pAd->ate.Channel <= 14)
+ {
+ /* bg channel */
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ TssiRef = pAd->TssiRefG;
+ pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
+ pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
+ TxAgcStep = pAd->TxAgcStepG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ }
+ else
+ {
+ /* a channel */
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ TssiRef = pAd->TssiRefA;
+ pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
+ pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
+ TxAgcStep = pAd->TxAgcStepA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ }
+
+ if (bAutoTxAgc)
+ {
+ /* BbpR49 is unsigned char */
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
+
+ /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
+ /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
+ /* step value is defined in pAd->TxAgcStepG for tx power value */
+
+ /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
+ /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
+ above value are examined in mass factory production */
+ /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
+
+ /* plus is 0x10 ~ 0x40, minus is 0x60 ~ 0x90 */
+ /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
+ /* if value is 0x65, tx power will be -= TxAgcStep*(2-1) */
+
+ if (BbpR49 > pTssiMinusBoundary[1])
+ {
+ // Reading is larger than the reference value.
+ // Check for how large we need to decrease the Tx power.
+ for (idx = 1; idx < 5; idx++)
+ {
+ if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
+ break;
+ }
+ // The index is the step we should decrease, idx = 0 means there is nothing to compensate
+// if (R3 > (ULONG) (TxAgcStep * (idx-1)))
+ *pTxAgcCompensate = -(TxAgcStep * (idx-1));
+// else
+// *pTxAgcCompensate = -((UCHAR)R3);
+
+ DeltaPwr += (*pTxAgcCompensate);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
+ BbpR49, TssiRef, TxAgcStep, idx-1));
+ }
+ else if (BbpR49 < pTssiPlusBoundary[1])
+ {
+ // Reading is smaller than the reference value
+ // check for how large we need to increase the Tx power
+ for (idx = 1; idx < 5; idx++)
+ {
+ if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
+ break;
+ }
+ // The index is the step we should increase, idx = 0 means there is nothing to compensate
+ *pTxAgcCompensate = TxAgcStep * (idx-1);
+ DeltaPwr += (*pTxAgcCompensate);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+ BbpR49, TssiRef, TxAgcStep, idx-1));
+ }
+ else
+ {
+ *pTxAgcCompensate = 0;
+ ATEDBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+ BbpR49, TssiRef, TxAgcStep, 0));
+ }
+ }
+ }
+ else
+ {
+ if (pAd->ate.Channel <= 14)
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ }
+ else
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ }
+
+ if (bAutoTxAgc)
+ DeltaPwr += (*pTxAgcCompensate);
+ }
+
+ /* calculate delta power based on the percentage specified from UI */
+ // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
+ // We lower TX power here according to the percentage specified from UI
+ if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
+ ;
+ else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
+ ;
+ else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW
+ {
+ DeltaPwr -= 1;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW
+ {
+ DeltaPwr -= 3;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW
+ {
+ DeltaPwr -= 6;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW
+ {
+ DeltaPwr -= 9;
+ }
+ else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW
+ {
+ DeltaPwr -= 12;
+ }
+
+ /* reset different new tx power for different TX rate */
+ for(i=0; i<5; i++)
+ {
+ if (TxPwr[i] != 0xffffffff)
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
+
+ if ((Value + DeltaPwr) < 0)
+ {
+ Value = 0; /* min */
+ }
+ else if ((Value + DeltaPwr) > 0xF)
+ {
+ Value = 0xF; /* max */
+ }
+ else
+ {
+ Value += DeltaPwr; /* temperature compensation */
+ }
+
+ /* fill new value to CSR offset */
+ TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
+ }
+
+ /* write tx power value to CSR */
+ /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
+ TX power for OFDM 6M/9M
+ TX power for CCK5.5M/11M
+ TX power for CCK1M/2M */
+ /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
+
+
+ }
+ }
+
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Write TxWI for ATE mode.
+
+ Return Value:
+ None
+ ========================================================================
+*/
+
+#ifdef RT2870
+static VOID ATEWriteTxWI(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXWI_STRUC pTxWI,
+ IN BOOLEAN FRAG,
+ IN BOOLEAN InsTimestamp,
+ IN BOOLEAN AMPDU,
+ IN BOOLEAN Ack,
+ IN BOOLEAN NSeq, // HW new a sequence.
+ IN UCHAR BASize,
+ IN UCHAR WCID,
+ IN ULONG Length,
+ IN UCHAR PID,
+ IN UCHAR MIMOps,
+ IN UCHAR Txopmode,
+ IN BOOLEAN CfAck,
+ IN HTTRANSMIT_SETTING Transmit)
+{
+ //
+ // Always use Long preamble before verifiation short preamble functionality works well.
+ // Todo: remove the following line if short preamble functionality works
+ //
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+ pTxWI->FRAG= FRAG;
+ pTxWI->TS= InsTimestamp;
+ pTxWI->AMPDU = AMPDU;
+
+ pTxWI->MIMOps = PWR_ACTIVE;
+ pTxWI->MpduDensity = 4;
+ pTxWI->ACK = Ack;
+ pTxWI->txop = Txopmode;
+ pTxWI->NSEQ = NSeq;
+ pTxWI->BAWinSize = BASize;
+
+ pTxWI->WirelessCliID = WCID;
+ pTxWI->MPDUtotalByteCount = Length;
+ pTxWI->PacketId = PID;
+
+ pTxWI->BW = Transmit.field.BW;
+ pTxWI->ShortGI = Transmit.field.ShortGI;
+ pTxWI->STBC= Transmit.field.STBC;
+
+ pTxWI->MCS = Transmit.field.MCS;
+ pTxWI->PHYMODE= Transmit.field.MODE;
+
+#ifdef DOT11_N_SUPPORT
+ //
+ // MMPS is 802.11n features. Because TxWI->MCS > 7 must be HT mode,
+ // so need not check if it's HT rate.
+ //
+ if ((MIMOps == MMPS_STATIC) && (pTxWI->MCS > 7))
+ pTxWI->MCS = 7;
+
+ if ((MIMOps == MMPS_DYNAMIC) && (pTxWI->MCS > 7)) // SMPS protect 2 spatial.
+ pTxWI->MIMOps = 1;
+#endif // DOT11_N_SUPPORT //
+
+ pTxWI->CFACK = CfAck;
+
+ return;
+}
+#endif // RT2870 //
+/*
+ ========================================================================
+
+ Routine Description:
+ Disable protection for ATE.
+ ========================================================================
+*/
+VOID ATEDisableAsicProtect(
+ IN PRTMP_ADAPTER pAd)
+{
+ PROT_CFG_STRUC ProtCfg, ProtCfg4;
+ UINT32 Protect[6];
+ USHORT offset;
+ UCHAR i;
+ UINT32 MacReg = 0;
+
+ // Config ASIC RTS threshold register
+ RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
+ MacReg &= 0xFF0000FF;
+ MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
+ RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
+
+ // Initial common protection settings
+ RTMPZeroMemory(Protect, sizeof(Protect));
+ ProtCfg4.word = 0;
+ ProtCfg.word = 0;
+ ProtCfg.field.TxopAllowGF40 = 1;
+ ProtCfg.field.TxopAllowGF20 = 1;
+ ProtCfg.field.TxopAllowMM40 = 1;
+ ProtCfg.field.TxopAllowMM20 = 1;
+ ProtCfg.field.TxopAllowOfdm = 1;
+ ProtCfg.field.TxopAllowCck = 1;
+ ProtCfg.field.RTSThEn = 1;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+
+ // Handle legacy(B/G) protection
+ ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
+ ProtCfg.field.ProtectCtrl = 0;
+ Protect[0] = ProtCfg.word;
+ Protect[1] = ProtCfg.word;
+
+ // NO PROTECT
+ // 1.All STAs in the BSS are 20/40 MHz HT
+ // 2. in ai 20/40MHz BSS
+ // 3. all STAs are 20MHz in a 20MHz BSS
+ // Pure HT. no protection.
+
+ // MM20_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 010111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
+ Protect[2] = 0x01744004;
+
+ // MM40_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 111111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
+ Protect[3] = 0x03f44084;
+
+ // CF20_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 010111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
+ Protect[4] = 0x01744004;
+
+ // CF40_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 111111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
+ Protect[5] = 0x03f44084;
+
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+
+ offset = CCK_PROT_CFG;
+ for (i = 0;i < 6;i++)
+ RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
+
+}
+
+#ifdef RT2870
+/*
+ ========================================================================
+ Routine Description:
+ Write TxInfo for ATE mode.
+
+ Return Value:
+ None
+ ========================================================================
+*/
+static VOID ATEWriteTxInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXINFO_STRUC pTxInfo,
+ IN USHORT USBDMApktLen,
+ IN BOOLEAN bWiv,
+ IN UCHAR QueueSel,
+ IN UCHAR NextValid,
+ IN UCHAR TxBurst)
+{
+ pTxInfo->USBDMATxPktLen = USBDMApktLen;
+ pTxInfo->QSEL = QueueSel;
+
+ if (QueueSel != FIFO_EDCA)
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("=======> QueueSel != FIFO_EDCA<=======\n"));
+
+ pTxInfo->USBDMANextVLD = NextValid;
+ pTxInfo->USBDMATxburst = TxBurst;
+ pTxInfo->WIV = bWiv;
+ pTxInfo->SwUseLastRound = 0;
+ pTxInfo->rsv = 0;
+ pTxInfo->rsv2 = 0;
+
+ return;
+}
+#endif // RT2870 //
+
+/* There are two ways to convert Rssi */
+#if 1
+//
+// The way used with GET_LNA_GAIN().
+//
+CHAR ATEConvertToRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi,
+ IN UCHAR RssiNumber)
+{
+ UCHAR RssiOffset, LNAGain;
+
+ // Rssi equals to zero should be an invalid value
+ if (Rssi == 0)
+ return -99;
+
+ LNAGain = GET_LNA_GAIN(pAd);
+ if (pAd->LatchRfRegs.Channel > 14)
+ {
+ if (RssiNumber == 0)
+ RssiOffset = pAd->ARssiOffset0;
+ else if (RssiNumber == 1)
+ RssiOffset = pAd->ARssiOffset1;
+ else
+ RssiOffset = pAd->ARssiOffset2;
+ }
+ else
+ {
+ if (RssiNumber == 0)
+ RssiOffset = pAd->BGRssiOffset0;
+ else if (RssiNumber == 1)
+ RssiOffset = pAd->BGRssiOffset1;
+ else
+ RssiOffset = pAd->BGRssiOffset2;
+ }
+
+ return (-12 - RssiOffset - LNAGain - Rssi);
+}
+#else
+//
+// The way originally used in ATE of rt2860ap.
+//
+CHAR ATEConvertToRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi,
+ IN UCHAR RssiNumber)
+{
+ UCHAR RssiOffset, LNAGain;
+
+ // Rssi equals to zero should be an invalid value
+ if (Rssi == 0)
+ return -99;
+
+ if (pAd->LatchRfRegs.Channel > 14)
+ {
+ LNAGain = pAd->ALNAGain;
+ if (RssiNumber == 0)
+ RssiOffset = pAd->ARssiOffset0;
+ else if (RssiNumber == 1)
+ RssiOffset = pAd->ARssiOffset1;
+ else
+ RssiOffset = pAd->ARssiOffset2;
+ }
+ else
+ {
+ LNAGain = pAd->BLNAGain;
+ if (RssiNumber == 0)
+ RssiOffset = pAd->BGRssiOffset0;
+ else if (RssiNumber == 1)
+ RssiOffset = pAd->BGRssiOffset1;
+ else
+ RssiOffset = pAd->BGRssiOffset2;
+ }
+
+ return (-32 - RssiOffset + LNAGain - Rssi);
+}
+#endif /* end of #if 1 */
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set Japan filter coefficients if needed.
+ Note:
+ This routine should only be called when
+ entering TXFRAME mode or TXCONT mode.
+
+ ========================================================================
+*/
+static VOID SetJapanFilter(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR BbpData = 0;
+
+ //
+ // If Channel=14 and Bandwidth=20M and Mode=CCK, set BBP R4 bit5=1
+ // (Japan Tx filter coefficients)when (TXFRAME or TXCONT).
+ //
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpData);
+
+ if ((pAd->ate.TxWI.PHYMODE == MODE_CCK) && (pAd->ate.Channel == 14) && (pAd->ate.TxWI.BW == BW_20))
+ {
+ BbpData |= 0x20; // turn on
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("SetJapanFilter!!!\n"));
+ }
+ else
+ {
+ BbpData &= 0xdf; // turn off
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ClearJapanFilter!!!\n"));
+ }
+
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData);
+}
+
+VOID ATESampleRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN PRXWI_STRUC pRxWI)
+{
+ /* There are two ways to collect RSSI. */
+#if 1
+ //pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
+ if (pRxWI->RSSI0 != 0)
+ {
+ pAd->ate.LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
+ pAd->ate.AvgRssi0X8 = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
+ pAd->ate.AvgRssi0 = pAd->ate.AvgRssi0X8 >> 3;
+ }
+ if (pRxWI->RSSI1 != 0)
+ {
+ pAd->ate.LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
+ pAd->ate.AvgRssi1X8 = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
+ pAd->ate.AvgRssi1 = pAd->ate.AvgRssi1X8 >> 3;
+ }
+ if (pRxWI->RSSI2 != 0)
+ {
+ pAd->ate.LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
+ pAd->ate.AvgRssi2X8 = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
+ pAd->ate.AvgRssi2 = pAd->ate.AvgRssi2X8 >> 3;
+ }
+
+ pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);// CHAR ==> UCHAR ?
+ pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);// CHAR ==> UCHAR ?
+
+ pAd->ate.NumOfAvgRssiSample ++;
+#else
+ pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);
+ pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);
+ pAd->ate.RxCntPerSec++;
+ pAd->ate.LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
+ pAd->ate.LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
+ pAd->ate.LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
+ pAd->ate.AvgRssi0X8 = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
+ pAd->ate.AvgRssi0 = pAd->ate.AvgRssi0X8 >> 3;
+ pAd->ate.AvgRssi1X8 = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
+ pAd->ate.AvgRssi1 = pAd->ate.AvgRssi1X8 >> 3;
+ pAd->ate.AvgRssi2X8 = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
+ pAd->ate.AvgRssi2 = pAd->ate.AvgRssi2X8 >> 3;
+ pAd->ate.NumOfAvgRssiSample ++;
+#endif
+}
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPStationStop(
+ IN PRTMP_ADAPTER pAd)
+{
+// BOOLEAN Cancelled;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStop\n"));
+
+ // For rx statistics, we need to keep this timer running.
+// RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStop\n"));
+}
+
+VOID RTMPStationStart(
+ IN PRTMP_ADAPTER pAd)
+{
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStart\n"));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStart\n"));
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+ ==========================================================================
+ Description:
+ Setup Frame format.
+ NOTE:
+ This routine should only be used in ATE mode.
+ ==========================================================================
+ */
+
+#ifdef RT2870
+/*======================Start of RT2870======================*/
+/* */
+/* */
+static INT ATESetUpFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 TxIdx)
+{
+ UINT j;
+ PTX_CONTEXT pNullContext;
+ PUCHAR pDest;
+ HTTRANSMIT_SETTING TxHTPhyMode;
+ PTXWI_STRUC pTxWI;
+ PTXINFO_STRUC pTxInfo;
+ UINT32 TransferBufferLength, OrgBufferLength = 0;
+ UCHAR padLen = 0;
+#ifdef RALINK_28xx_QA
+ PHEADER_802_11 pHeader80211 = NULL;
+#endif // RALINK_28xx_QA //
+
+ if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ return -1;
+ }
+
+ /* We always use QID_AC_BE and FIFO_EDCA in ATE mode. */
+
+ pNullContext = &(pAd->NullContext);
+ ASSERT(pNullContext != NULL);
+
+ if (pNullContext->InUse == FALSE)
+ {
+ // Set the in use bit
+ pNullContext->InUse = TRUE;
+ NdisZeroMemory(&(pAd->NullFrame), sizeof(HEADER_802_11));
+
+ // Fill 802.11 header.
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ pHeader80211 = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen);
+// pDest = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen);
+// pHeader80211 = (PHEADER_802_11)pDest;
+ }
+ else
+#endif // RALINK_28xx_QA //
+ {
+ // Fill 802.11 header.
+ NdisMoveMemory(&(pAd->NullFrame), TemplateFrame, sizeof(HEADER_802_11));
+ }
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)&(pAd->NullFrame), DIR_READ, FALSE);
+#endif // RT_BIG_ENDIAN //
+
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ /* modify sequence number.... */
+ if (pAd->ate.TxDoneCount == 0)
+ {
+ pAd->ate.seq = pHeader80211->Sequence;
+ }
+ else
+ {
+ pHeader80211->Sequence = ++pAd->ate.seq;
+ }
+ /* We already got all the addr. fields from QA GUI. */
+ }
+ else
+#endif // RALINK_28xx_QA //
+ {
+ COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->ate.Addr1);
+ COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->ate.Addr2);
+ COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->ate.Addr3);
+ }
+
+ RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], TX_BUFFER_NORMSIZE);//???
+ pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
+
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ // Avoid to exceed the range of WirelessPacket[].
+ ASSERT(pAd->ate.TxInfo.USBDMATxPktLen <= (MAX_FRAME_SIZE - 34/* == 2312 */));
+ NdisMoveMemory(pTxInfo, &(pAd->ate.TxInfo), sizeof(pAd->ate.TxInfo));
+ }
+ else
+#endif // RALINK_28xx_QA //
+ {
+ // Avoid to exceed the range of WirelessPacket[].
+ ASSERT(pAd->ate.TxLength <= (MAX_FRAME_SIZE - 34/* == 2312 */));
+
+ // pTxInfo->USBDMATxPktLen will be updated to include padding later.
+ ATEWriteTxInfo(pAd, pTxInfo, (USHORT)(TXWI_SIZE + pAd->ate.TxLength), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+ pTxInfo->QSEL = FIFO_EDCA;
+ }
+
+ pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
+
+ // Fill TxWI.
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
+ TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
+ TxHTPhyMode.field.STBC = pAd->ate.TxWI.STBC;
+ TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
+ TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
+ ATEWriteTxWI(pAd, pTxWI, pAd->ate.TxWI.FRAG, pAd->ate.TxWI.TS, pAd->ate.TxWI.AMPDU, pAd->ate.TxWI.ACK, pAd->ate.TxWI.NSEQ,
+ pAd->ate.TxWI.BAWinSize, BSSID_WCID, pAd->ate.TxWI.MPDUtotalByteCount/* include 802.11 header */, pAd->ate.TxWI.PacketId, 0, pAd->ate.TxWI.txop/*IFS_HTTXOP*/, pAd->ate.TxWI.CFACK/*FALSE*/, TxHTPhyMode);
+ }
+ else
+ {
+ TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
+ TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
+ TxHTPhyMode.field.STBC = 0;
+ TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
+ TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
+
+ ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE/* No ack required. */, FALSE, 0, BSSID_WCID, pAd->ate.TxLength,
+ 0, 0, IFS_HTTXOP, FALSE, TxHTPhyMode);// "MMPS_STATIC" instead of "MMPS_DYNAMIC" ???
+ }
+
+ RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
+
+ pDest = &(pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE+sizeof(HEADER_802_11)]);
+
+ // Prepare frame payload
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ // copy pattern
+ if ((pAd->ate.PLen != 0))
+ {
+ for (j = 0; j < pAd->ate.DLen; j+=pAd->ate.PLen)
+ {
+ RTMPMoveMemory(pDest, pAd->ate.Pattern, pAd->ate.PLen);
+ pDest += pAd->ate.PLen;
+ }
+ }
+ TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxWI.MPDUtotalByteCount;
+ }
+ else
+#endif // RALINK_28xx_QA //
+ {
+ for (j = 0; j < (pAd->ate.TxLength - sizeof(HEADER_802_11)); j++)
+ {
+ *pDest = 0xA5;
+ pDest += 1;
+ }
+ TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxLength;
+ }
+
+#if 1
+ OrgBufferLength = TransferBufferLength;
+ TransferBufferLength = (TransferBufferLength + 3) & (~3);
+
+ // Always add 4 extra bytes at every packet.
+ padLen = TransferBufferLength - OrgBufferLength + 4;/* 4 == last packet padding */
+ ASSERT((padLen <= (RTMP_PKT_TAIL_PADDING - 4/* 4 == MaxBulkOutsize alignment padding */)));
+
+ /* Now memzero all extra padding bytes. */
+ NdisZeroMemory(pDest, padLen);
+ pDest += padLen;
+#else
+ if ((TransferBufferLength % 4) == 1)
+ {
+ NdisZeroMemory(pDest, 7);
+ pDest += 7;
+ TransferBufferLength += 3;
+ }
+ else if ((TransferBufferLength % 4) == 2)
+ {
+ NdisZeroMemory(pDest, 6);
+ pDest += 6;
+ TransferBufferLength += 2;
+ }
+ else if ((TransferBufferLength % 4) == 3)
+ {
+ NdisZeroMemory(pDest, 5);
+ pDest += 5;
+ TransferBufferLength += 1;
+ }
+#endif // 1 //
+
+ // Update pTxInfo->USBDMATxPktLen to include padding.
+ pTxInfo->USBDMATxPktLen = TransferBufferLength - TXINFO_SIZE;
+
+ TransferBufferLength += 4;
+
+ // If TransferBufferLength is multiple of 64, add extra 4 bytes again.
+ if ((TransferBufferLength % pAd->BulkOutMaxPacketSize) == 0)
+ {
+ NdisZeroMemory(pDest, 4);
+ TransferBufferLength += 4;
+ }
+
+ // Fill out frame length information for global Bulk out arbitor
+ pAd->NullContext.BulkOutSize = TransferBufferLength;
+ }
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+ RTMPFrameEndianChange(pAd, (((PUCHAR)pTxInfo)+TXWI_SIZE+TXINFO_SIZE), DIR_WRITE, FALSE);
+ RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+ return 0;
+}
+
+VOID ATE_RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pNullContext;
+ UCHAR BulkOutPipeId;
+ NTSTATUS Status;
+ unsigned long IrqFlags;
+ ULONG OldValue;
+
+ pNullContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pNullContext->pAd;
+
+
+ // Reset Null frame context flags
+ pNullContext->IRPPending = FALSE;
+ pNullContext->InUse = FALSE;
+ Status = pUrb->status;
+
+ // Store BulkOut PipeId
+ BulkOutPipeId = pNullContext->BulkOutPipeId;
+ pAd->BulkOutDataOneSecCount++;
+
+ if (Status == USB_ST_NOERROR)
+ {
+#ifdef RALINK_28xx_QA
+ if ((ATE_ON(pAd)) && (pAd->ate.bQATxStart == TRUE))
+ {
+ if (pAd->ate.QID == BulkOutPipeId)
+ {
+ // Let Rx can have a chance to break in during Tx process,
+ // especially for loopback mode in QA ATE.
+ // To trade off between tx performance and loopback mode integrity.
+ /* Q : Now Rx is handled by tasklet, do we still need this delay ? */
+ /* Ans : Even tasklet is used, Rx/Tx < 1 if we do not delay for a while right here. */
+ RTMPusecDelay(500);
+ pAd->ate.TxDoneCount++;
+ pAd->RalinkCounters.KickTxCount++;
+ ASSERT(pAd->ate.QID == 0);
+ pAd->ate.TxAc0++;
+ }
+ }
+#endif // RALINK_28xx_QA //
+ pAd->BulkOutComplete++;
+
+ pAd->Counters8023.GoodTransmits++;
+
+ /* Don't worry about the queue is empty or not. This function will check itself. */
+ RTMPDeQueuePacket(pAd, TRUE, BulkOutPipeId, MAX_TX_PROCESS);
+
+ /* In 28xx, SendTxWaitQueue ==> TxSwQueue */
+/*
+ if (pAd->SendTxWaitQueue[BulkOutPipeId].Number > 0)
+ {
+ RTMPDeQueuePacket(pAd, BulkOutPipeId);
+ }
+*/
+ }
+ else // STATUS_OTHER
+ {
+ pAd->BulkOutCompleteOther++;
+
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("BulkOutDataPacket Failed STATUS_OTHER = 0x%x . \n", Status));
+ ATEDBGPRINT(RT_DEBUG_ERROR, (">>BulkOutReq=0x%lx, BulkOutComplete=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete));
+
+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ /* In 28xx, RT_OID_USB_RESET_BULK_OUT ==> CMDTHREAD_RESET_BULK_OUT */
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ // Check
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+ pAd->bulkResetPipeid = BulkOutPipeId;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ return;
+ }
+ }
+
+
+
+ if (atomic_read(&pAd->BulkOutRemained) > 0)
+ {
+ atomic_dec(&pAd->BulkOutRemained);
+ }
+
+ // 1st - Transmit Success
+ OldValue = pAd->WlanCounters.TransmittedFragmentCount.u.LowPart;
+ pAd->WlanCounters.TransmittedFragmentCount.u.LowPart++;
+
+ if (pAd->WlanCounters.TransmittedFragmentCount.u.LowPart < OldValue)
+ {
+ pAd->WlanCounters.TransmittedFragmentCount.u.HighPart++;
+ }
+
+ if(((pAd->ContinBulkOut == TRUE ) ||(atomic_read(&pAd->BulkOutRemained) > 0)) && (pAd->ate.Mode & ATE_TXFRAME))
+ {
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+ }
+ else
+ {
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+#ifdef RALINK_28xx_QA
+ pAd->ate.TxStatus = 0;
+#endif // RALINK_28xx_QA //
+ }
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+ // Always call Bulk routine, even reset bulk.
+ // The protection of rest bulk should be in BulkOut routine.
+ RTUSBKickBulkOut(pAd);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID ATE_RTUSBBulkOutDataPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BulkOutPipeId)
+{
+ PTX_CONTEXT pNullContext = &(pAd->NullContext);
+ PURB pUrb;
+ int ret = 0;
+ unsigned long IrqFlags;
+
+
+ ASSERT(BulkOutPipeId == 0);
+
+ /* Build up the frame first. */
+// ATESetUpFrame(pAd, 0);
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+ if (pAd->BulkOutPending[BulkOutPipeId] == TRUE)
+ {
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ return;
+ }
+
+ pAd->BulkOutPending[BulkOutPipeId] = TRUE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+ // Increase Total transmit byte counter
+ pAd->RalinkCounters.OneSecTransmittedByteCount += pNullContext->BulkOutSize;
+ pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
+
+ // Clear ATE frame bulk out flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+
+ // Init Tx context descriptor
+ pNullContext->IRPPending = TRUE;
+ RTUSBInitTxDesc(pAd, pNullContext, BulkOutPipeId, (usb_complete_t)ATE_RTUSBBulkOutDataPacketComplete);
+ pUrb = pNullContext->pUrb;
+
+ if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
+ return;
+ }
+
+ pAd->BulkOutReq++;
+ return;
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID ATE_RTUSBCancelPendingBulkInIRP(
+ IN PRTMP_ADAPTER pAd)
+{
+ PRX_CONTEXT pRxContext;
+ UINT i;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("--->ATE_RTUSBCancelPendingBulkInIRP\n"));
+#if 1
+ for ( i = 0; i < (RX_RING_SIZE); i++)
+ {
+ pRxContext = &(pAd->RxContext[i]);
+ if(pRxContext->IRPPending == TRUE)
+ {
+ RTUSB_UNLINK_URB(pRxContext->pUrb);
+ pRxContext->IRPPending = FALSE;
+ pRxContext->InUse = FALSE;
+ //NdisInterlockedDecrement(&pAd->PendingRx);
+ //pAd->PendingRx--;
+ }
+ }
+#else
+ for ( i = 0; i < (RX_RING_SIZE); i++)
+ {
+ pRxContext = &(pAd->RxContext[i]);
+ if(atomic_read(&pRxContext->IrpLock) == IRPLOCK_CANCELABLE)
+ {
+ RTUSB_UNLINK_URB(pRxContext->pUrb);
+ }
+ InterlockedExchange(&pRxContext->IrpLock, IRPLOCK_CANCE_START);
+ }
+#endif // 1 //
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("<---ATE_RTUSBCancelPendingBulkInIRP\n"));
+ return;
+}
+#endif // RT2870 //
+
+VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
+{
+ USHORT i;
+ USHORT value;
+
+ for (i = 0 ; i < EEPROM_SIZE/2 ; )
+ {
+ /* "value" is expecially for some compilers... */
+ RT28xx_EEPROM_READ16(pAd, i*2, value);
+ Data[i] = value;
+ i++;
+ }
+}
+
+VOID rt_ee_write_all(PRTMP_ADAPTER pAd, USHORT *Data)
+{
+ USHORT i;
+ USHORT value;
+
+ for (i = 0 ; i < EEPROM_SIZE/2 ; )
+ {
+ /* "value" is expecially for some compilers... */
+ value = Data[i];
+ RT28xx_EEPROM_WRITE16(pAd, i*2, value);
+ i ++;
+ }
+}
+#ifdef RALINK_28xx_QA
+VOID ATE_QA_Statistics(
+ IN PRTMP_ADAPTER pAd,
+ IN PRXWI_STRUC pRxWI,
+ IN PRT28XX_RXD_STRUC pRxD,
+ IN PHEADER_802_11 pHeader)
+{
+ // update counter first
+ if (pHeader != NULL)
+ {
+ if (pHeader->FC.Type == BTYPE_DATA)
+ {
+ if (pRxD->U2M)
+ pAd->ate.U2M++;
+ else
+ pAd->ate.OtherData++;
+ }
+ else if (pHeader->FC.Type == BTYPE_MGMT)
+ {
+ if (pHeader->FC.SubType == SUBTYPE_BEACON)
+ pAd->ate.Beacon++;
+ else
+ pAd->ate.OtherCount++;
+ }
+ else if (pHeader->FC.Type == BTYPE_CNTL)
+ {
+ pAd->ate.OtherCount++;
+ }
+ }
+ pAd->ate.RSSI0 = pRxWI->RSSI0;
+ pAd->ate.RSSI1 = pRxWI->RSSI1;
+ pAd->ate.RSSI2 = pRxWI->RSSI2;
+ pAd->ate.SNR0 = pRxWI->SNR0;
+ pAd->ate.SNR1 = pRxWI->SNR1;
+}
+
+/* command id with Cmd Type == 0x0008(for 28xx)/0x0005(for iNIC) */
+#define RACFG_CMD_RF_WRITE_ALL 0x0000
+#define RACFG_CMD_E2PROM_READ16 0x0001
+#define RACFG_CMD_E2PROM_WRITE16 0x0002
+#define RACFG_CMD_E2PROM_READ_ALL 0x0003
+#define RACFG_CMD_E2PROM_WRITE_ALL 0x0004
+#define RACFG_CMD_IO_READ 0x0005
+#define RACFG_CMD_IO_WRITE 0x0006
+#define RACFG_CMD_IO_READ_BULK 0x0007
+#define RACFG_CMD_BBP_READ8 0x0008
+#define RACFG_CMD_BBP_WRITE8 0x0009
+#define RACFG_CMD_BBP_READ_ALL 0x000a
+#define RACFG_CMD_GET_COUNTER 0x000b
+#define RACFG_CMD_CLEAR_COUNTER 0x000c
+
+#define RACFG_CMD_RSV1 0x000d
+#define RACFG_CMD_RSV2 0x000e
+#define RACFG_CMD_RSV3 0x000f
+
+#define RACFG_CMD_TX_START 0x0010
+#define RACFG_CMD_GET_TX_STATUS 0x0011
+#define RACFG_CMD_TX_STOP 0x0012
+#define RACFG_CMD_RX_START 0x0013
+#define RACFG_CMD_RX_STOP 0x0014
+#define RACFG_CMD_GET_NOISE_LEVEL 0x0015
+
+#define RACFG_CMD_ATE_START 0x0080
+#define RACFG_CMD_ATE_STOP 0x0081
+
+#define RACFG_CMD_ATE_START_TX_CARRIER 0x0100
+#define RACFG_CMD_ATE_START_TX_CONT 0x0101
+#define RACFG_CMD_ATE_START_TX_FRAME 0x0102
+#define RACFG_CMD_ATE_SET_BW 0x0103
+#define RACFG_CMD_ATE_SET_TX_POWER0 0x0104
+#define RACFG_CMD_ATE_SET_TX_POWER1 0x0105
+#define RACFG_CMD_ATE_SET_FREQ_OFFSET 0x0106
+#define RACFG_CMD_ATE_GET_STATISTICS 0x0107
+#define RACFG_CMD_ATE_RESET_COUNTER 0x0108
+#define RACFG_CMD_ATE_SEL_TX_ANTENNA 0x0109
+#define RACFG_CMD_ATE_SEL_RX_ANTENNA 0x010a
+#define RACFG_CMD_ATE_SET_PREAMBLE 0x010b
+#define RACFG_CMD_ATE_SET_CHANNEL 0x010c
+#define RACFG_CMD_ATE_SET_ADDR1 0x010d
+#define RACFG_CMD_ATE_SET_ADDR2 0x010e
+#define RACFG_CMD_ATE_SET_ADDR3 0x010f
+#define RACFG_CMD_ATE_SET_RATE 0x0110
+#define RACFG_CMD_ATE_SET_TX_FRAME_LEN 0x0111
+#define RACFG_CMD_ATE_SET_TX_FRAME_COUNT 0x0112
+#define RACFG_CMD_ATE_START_RX_FRAME 0x0113
+#define RACFG_CMD_ATE_E2PROM_READ_BULK 0x0114
+#define RACFG_CMD_ATE_E2PROM_WRITE_BULK 0x0115
+#define RACFG_CMD_ATE_IO_WRITE_BULK 0x0116
+#define RACFG_CMD_ATE_BBP_READ_BULK 0x0117
+#define RACFG_CMD_ATE_BBP_WRITE_BULK 0x0118
+#define RACFG_CMD_ATE_RF_READ_BULK 0x0119
+#define RACFG_CMD_ATE_RF_WRITE_BULK 0x011a
+
+
+
+#define A2Hex(_X, _p) \
+{ \
+ UCHAR *p; \
+ _X = 0; \
+ p = _p; \
+ while (((*p >= 'a') && (*p <= 'f')) || ((*p >= 'A') && (*p <= 'F')) || ((*p >= '0') && (*p <= '9'))) \
+ { \
+ if ((*p >= 'a') && (*p <= 'f')) \
+ _X = _X * 16 + *p - 87; \
+ else if ((*p >= 'A') && (*p <= 'F')) \
+ _X = _X * 16 + *p - 55; \
+ else if ((*p >= '0') && (*p <= '9')) \
+ _X = _X * 16 + *p - 48; \
+ p++; \
+ } \
+}
+
+
+static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
+static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
+static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len);
+
+#ifdef UCOS
+int ate_copy_to_user(
+ IN PUCHAR payload,
+ IN PUCHAR msg,
+ IN INT len)
+{
+ memmove(payload, msg, len);
+ return 0;
+}
+
+#undef copy_to_user
+#define copy_to_user(x,y,z) ate_copy_to_user((PUCHAR)x, (PUCHAR)y, z)
+#endif // UCOS //
+
+#define LEN_OF_ARG 16
+
+VOID RtmpDoAte(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq)
+{
+ unsigned short Command_Id;
+ struct ate_racfghdr *pRaCfg;
+ INT Status = NDIS_STATUS_SUCCESS;
+
+
+
+ if((pRaCfg = kmalloc(sizeof(struct ate_racfghdr), GFP_KERNEL)) == NULL)
+ {
+ Status = -EINVAL;
+ return;
+ }
+
+ NdisZeroMemory(pRaCfg, sizeof(struct ate_racfghdr));
+
+ if (copy_from_user((PUCHAR)pRaCfg, wrq->u.data.pointer, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ kfree(pRaCfg);
+ return;
+ }
+
+
+ Command_Id = ntohs(pRaCfg->command_id);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("\n%s: Command_Id = 0x%04x !\n", __FUNCTION__, Command_Id));
+
+ switch (Command_Id)
+ {
+ // We will get this command when QA starts.
+ case RACFG_CMD_ATE_START:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START\n"));
+
+ // prepare feedback as soon as we can to avoid QA timeout.
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_ATE_START\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START is done !\n"));
+ }
+ Set_ATE_Proc(pAdapter, "ATESTART");
+ }
+ break;
+
+ // We will get this command either QA is closed or ated is killed by user.
+ case RACFG_CMD_ATE_STOP:
+ {
+#ifndef UCOS
+ INT32 ret;
+#endif // !UCOS //
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_STOP\n"));
+
+ // Distinguish this command came from QA(via ated)
+ // or ate daemon according to the existence of pid in payload.
+ // No need to prepare feedback if this cmd came directly from ate daemon.
+ pRaCfg->length = ntohs(pRaCfg->length);
+
+ if (pRaCfg->length == sizeof(pAdapter->ate.AtePid))
+ {
+ // This command came from QA.
+ // Get the pid of ATE daemon.
+ memcpy((UCHAR *)&pAdapter->ate.AtePid,
+ (&pRaCfg->data[0]) - 2/* == &(pRaCfg->status) */,
+ sizeof(pAdapter->ate.AtePid));
+
+ // prepare feedback as soon as we can to avoid QA timeout.
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_STOP\n"));
+ Status = -EFAULT;
+ }
+
+ //
+ // kill ATE daemon when leaving ATE mode.
+ // We must kill ATE daemon first before setting ATESTOP,
+ // or Microsoft will report sth. wrong.
+#ifndef UCOS
+ ret = kill_proc(pAdapter->ate.AtePid, SIGTERM, 1);
+ if (ret)
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("%s: unable to signal thread\n", pAdapter->net_dev->name));
+ }
+#endif // !UCOS //
+ }
+
+#ifdef UCOS
+ // Roger add to avoid error message after close QA
+ if (pAdapter->CSRBaseAddress == RT2860_CSR_ADDR)
+ {
+
+ // prepare feedback as soon as we can to avoid QA timeout.
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_AP_START\n"));
+ Status = -EFAULT;
+ }
+ }
+#endif // UCOS //
+
+ // AP might have in ATE_STOP mode due to cmd from QA.
+ if (ATE_ON(pAdapter))
+ {
+ // Someone has killed ate daemon while QA GUI is still open.
+ Set_ATE_Proc(pAdapter, "ATESTOP");
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_AP_START is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_RF_WRITE_ALL:
+ {
+ UINT32 R1, R2, R3, R4;
+ USHORT channel;
+
+ memcpy(&R1, pRaCfg->data-2, 4);
+ memcpy(&R2, pRaCfg->data+2, 4);
+ memcpy(&R3, pRaCfg->data+6, 4);
+ memcpy(&R4, pRaCfg->data+10, 4);
+ memcpy(&channel, pRaCfg->data+14, 2);
+
+ pAdapter->LatchRfRegs.R1 = ntohl(R1);
+ pAdapter->LatchRfRegs.R2 = ntohl(R2);
+ pAdapter->LatchRfRegs.R3 = ntohl(R3);
+ pAdapter->LatchRfRegs.R4 = ntohl(R4);
+ pAdapter->LatchRfRegs.Channel = ntohs(channel);
+
+ RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R3);
+ RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R4);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RF_WRITE_ALL\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RF_WRITE_ALL is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_E2PROM_READ16:
+ {
+ USHORT offset, value, tmp;
+
+ offset = ntohs(pRaCfg->status);
+ /* "tmp" is expecially for some compilers... */
+ RT28xx_EEPROM_READ16(pAdapter, offset, tmp);
+ value = tmp;
+ value = htons(value);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("EEPROM Read offset = 0x%04x, value = 0x%04x\n", offset, value));
+
+ // prepare feedback
+ pRaCfg->length = htons(4);
+ pRaCfg->status = htons(0);
+ memcpy(pRaCfg->data, &value, 2);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("sizeof(struct ate_racfghdr) = %d\n", sizeof(struct ate_racfghdr)));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ16\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ16 is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_E2PROM_WRITE16:
+ {
+ USHORT offset, value;
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&value, pRaCfg->data, 2);
+ value = ntohs(value);
+ RT28xx_EEPROM_WRITE16(pAdapter, offset, value);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE16\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_WRITE16 is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_E2PROM_READ_ALL:
+ {
+ USHORT buffer[EEPROM_SIZE/2];
+
+ rt_ee_read_all(pAdapter,(USHORT *)buffer);
+ memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer, EEPROM_SIZE);
+
+ // prepare feedback
+ pRaCfg->length = htons(2+EEPROM_SIZE);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ_ALL\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ_ALL is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_E2PROM_WRITE_ALL:
+ {
+ USHORT buffer[EEPROM_SIZE/2];
+
+ NdisZeroMemory((UCHAR *)buffer, EEPROM_SIZE);
+ memcpy_exs(pAdapter, (UCHAR *)buffer, (UCHAR *)&pRaCfg->status, EEPROM_SIZE);
+ rt_ee_write_all(pAdapter,(USHORT *)buffer);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE_ALL\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_E2PROM_WRITE_ALL is done !\n"));
+ }
+
+ }
+ break;
+
+ case RACFG_CMD_IO_READ:
+ {
+ UINT32 offset;
+ UINT32 value;
+
+ memcpy(&offset, &pRaCfg->status, 4);
+ offset = ntohl(offset);
+
+ // We do not need the base address.
+ // So just extract the offset out.
+ offset &= 0x0000FFFF;
+ RTMP_IO_READ32(pAdapter, offset, &value);
+ value = htonl(value);
+
+ // prepare feedback
+ pRaCfg->length = htons(6);
+ pRaCfg->status = htons(0);
+ memcpy(pRaCfg->data, &value, 4);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_IO_WRITE:
+ {
+ UINT32 offset, value;
+
+ memcpy(&offset, pRaCfg->data-2, 4);
+ memcpy(&value, pRaCfg->data+2, 4);
+
+ offset = ntohl(offset);
+
+ // We do not need the base address.
+ // So just extract out the offset.
+ offset &= 0x0000FFFF;
+ value = ntohl(value);
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_IO_WRITE: offset = %x, value = %x\n", offset, value));
+ RTMP_IO_WRITE32(pAdapter, offset, value);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_WRITE\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_WRITE is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_IO_READ_BULK:
+ {
+ UINT32 offset;
+ USHORT len;
+
+ memcpy(&offset, &pRaCfg->status, 4);
+ offset = ntohl(offset);
+
+ // We do not need the base address.
+ // So just extract the offset.
+ offset &= 0x0000FFFF;
+ memcpy(&len, pRaCfg->data+2, 2);
+ len = ntohs(len);
+
+ if (len > 371)
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("len is too large, make it smaller\n"));
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(1);
+ break;
+ }
+
+ RTMP_IO_READ_BULK(pAdapter, pRaCfg->data, (UCHAR *)offset, len*4);// unit in four bytes
+
+ // prepare feedback
+ pRaCfg->length = htons(2+len*4);// unit in four bytes
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ_BULK is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_BBP_READ8:
+ {
+ USHORT offset;
+ UCHAR value;
+
+ value = 0;
+ offset = ntohs(pRaCfg->status);
+
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value);
+ }
+ else
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value);
+ }
+ // prepare feedback
+ pRaCfg->length = htons(3);
+ pRaCfg->status = htons(0);
+ pRaCfg->data[0] = value;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("BBP value = %x\n", value));
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ8\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ8 is done !\n"));
+ }
+ }
+ break;
+ case RACFG_CMD_BBP_WRITE8:
+ {
+ USHORT offset;
+ UCHAR value;
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&value, pRaCfg->data, 1);
+
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value);
+ }
+ else
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value);
+ }
+
+ if ((offset == BBP_R1) || (offset == BBP_R3))
+ {
+ SyncTxRxConfig(pAdapter, offset, value);
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_WRITE8\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_WRITE8 is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_BBP_READ_ALL:
+ {
+ USHORT j;
+
+ for (j = 0; j < 137; j++)
+ {
+ pRaCfg->data[j] = 0;
+
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j]);
+ }
+ else
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j]);
+ }
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2+137);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ_ALL\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ_ALL is done !\n"));
+ }
+ }
+
+ break;
+
+ case RACFG_CMD_ATE_E2PROM_READ_BULK:
+ {
+ USHORT offset;
+ USHORT len;
+ USHORT buffer[EEPROM_SIZE/2];
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = ntohs(len);
+
+ rt_ee_read_all(pAdapter,(USHORT *)buffer);
+ if (offset + len <= EEPROM_SIZE)
+ memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer+offset, len);
+ else
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("exceed EEPROM size\n"));
+
+ // prepare feedback
+ pRaCfg->length = htons(2+len);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_READ_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_E2PROM_READ_BULK is done !\n"));
+ }
+
+ }
+ break;
+
+ case RACFG_CMD_ATE_E2PROM_WRITE_BULK:
+ {
+ USHORT offset;
+ USHORT len;
+ USHORT buffer[EEPROM_SIZE/2];
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = ntohs(len);
+
+ rt_ee_read_all(pAdapter,(USHORT *)buffer);
+ memcpy_exs(pAdapter, (UCHAR *)buffer + offset, (UCHAR *)pRaCfg->data + 2, len);
+ rt_ee_write_all(pAdapter,(USHORT *)buffer);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_WRITE_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_E2PROM_WRITE_BULK is done !\n"));
+ }
+
+ }
+ break;
+
+ case RACFG_CMD_ATE_IO_WRITE_BULK:
+ {
+ UINT32 offset, i, value;
+ USHORT len;
+
+ memcpy(&offset, &pRaCfg->status, 4);
+ offset = ntohl(offset);
+ memcpy(&len, pRaCfg->data+2, 2);
+ len = ntohs(len);
+
+ for (i = 0; i < len; i += 4)
+ {
+ memcpy_exl(pAdapter, (UCHAR *)&value, pRaCfg->data+4+i, 4);
+ printk("Write %x %x\n", offset + i, value);
+ RTMP_IO_WRITE32(pAdapter, (offset +i) & 0xffff, value);
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_IO_WRITE_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_IO_WRITE_BULK is done !\n"));
+ }
+
+ }
+ break;
+
+ case RACFG_CMD_ATE_BBP_READ_BULK:
+ {
+ USHORT offset;
+ USHORT len;
+ USHORT j;
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = ntohs(len);
+
+
+ for (j = offset; j < (offset+len); j++)
+ {
+ pRaCfg->data[j - offset] = 0;
+
+ if (pAdapter->ate.Mode == ATE_STOP)
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]);
+ }
+ else
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]);
+ }
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2+len);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_READ_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_READ_BULK is done !\n"));
+ }
+
+ }
+ break;
+
+ case RACFG_CMD_ATE_BBP_WRITE_BULK:
+ {
+ USHORT offset;
+ USHORT len;
+ USHORT j;
+ UCHAR *value;
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = ntohs(len);
+
+ for (j = offset; j < (offset+len); j++)
+ {
+ value = pRaCfg->data + 2 + (j - offset);
+ if (pAdapter->ate.Mode == ATE_STOP)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j, *value);
+ }
+ else
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j, *value);
+ }
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_WRITE_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_WRITE_BULK is done !\n"));
+ }
+ }
+ break;
+
+#ifdef CONFIG_RALINK_RT3052
+ case RACFG_CMD_ATE_RF_READ_BULK:
+ {
+ USHORT offset;
+ USHORT len;
+ USHORT j;
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = ntohs(len);
+
+ for (j = offset; j < (offset+len); j++)
+ {
+ pRaCfg->data[j - offset] = 0;
+ RT30xxReadRFRegister(pAdapter, j, &pRaCfg->data[j - offset]);
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2+len);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_READ_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_READ_BULK is done !\n"));
+ }
+
+ }
+ break;
+
+ case RACFG_CMD_ATE_RF_WRITE_BULK:
+ {
+ USHORT offset;
+ USHORT len;
+ USHORT j;
+ UCHAR *value;
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = ntohs(len);
+
+ for (j = offset; j < (offset+len); j++)
+ {
+ value = pRaCfg->data + 2 + (j - offset);
+ RT30xxWriteRFRegister(pAdapter, j, *value);
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_WRITE_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_WRITE_BULK is done !\n"));
+ }
+
+ }
+ break;
+#endif
+
+
+ case RACFG_CMD_GET_NOISE_LEVEL:
+ {
+ UCHAR channel;
+ INT32 buffer[3][10];/* 3 : RxPath ; 10 : no. of per rssi samples */
+
+ channel = (ntohs(pRaCfg->status) & 0x00FF);
+ CalNoiseLevel(pAdapter, channel, buffer);
+ memcpy_exl(pAdapter, (UCHAR *)pRaCfg->data, (UCHAR *)&(buffer[0][0]), (sizeof(INT32)*3*10));
+
+ // prepare feedback
+ pRaCfg->length = htons(2 + (sizeof(INT32)*3*10));
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_NOISE_LEVEL\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_NOISE_LEVEL is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_GET_COUNTER:
+ {
+ memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.U2M, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->ate.OtherData, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->ate.Beacon, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->ate.OtherCount, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->ate.TxAc0, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->ate.TxAc1, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->ate.TxAc2, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->ate.TxAc3, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->ate.TxHCCA, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->ate.TxMgmt, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&pAdapter->ate.RSSI0, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&pAdapter->ate.RSSI1, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&pAdapter->ate.RSSI2, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[52], (UCHAR *)&pAdapter->ate.SNR0, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[56], (UCHAR *)&pAdapter->ate.SNR1, 4);
+
+ pRaCfg->length = htons(2+60);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_COUNTER\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_COUNTER is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_CLEAR_COUNTER:
+ {
+ pAdapter->ate.U2M = 0;
+ pAdapter->ate.OtherData = 0;
+ pAdapter->ate.Beacon = 0;
+ pAdapter->ate.OtherCount = 0;
+ pAdapter->ate.TxAc0 = 0;
+ pAdapter->ate.TxAc1 = 0;
+ pAdapter->ate.TxAc2 = 0;
+ pAdapter->ate.TxAc3 = 0;
+ pAdapter->ate.TxHCCA = 0;
+ pAdapter->ate.TxMgmt = 0;
+ pAdapter->ate.TxDoneCount = 0;
+
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_CLEAR_COUNTER\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_CLEAR_COUNTER is done !\n"));
+ }
+ }
+
+ break;
+
+ case RACFG_CMD_TX_START:
+ {
+ USHORT *p;
+ USHORT err = 1;
+ UCHAR Bbp22Value = 0, Bbp24Value = 0;
+
+ if ((pAdapter->ate.TxStatus != 0) && (pAdapter->ate.Mode & ATE_TXFRAME))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("Ate Tx is already running, to run next Tx, you must stop it first\n"));
+ err = 2;
+ goto TX_START_ERROR;
+ }
+ else if ((pAdapter->ate.TxStatus != 0) && !(pAdapter->ate.Mode & ATE_TXFRAME))
+ {
+ int i = 0;
+
+ while ((i++ < 10) && (pAdapter->ate.TxStatus != 0))
+ {
+ RTMPusecDelay(5000);
+ }
+
+ // force it to stop
+ pAdapter->ate.TxStatus = 0;
+ pAdapter->ate.TxDoneCount = 0;
+ //pAdapter->ate.Repeat = 0;
+ pAdapter->ate.bQATxStart = FALSE;
+ }
+
+ // If pRaCfg->length == 0, this "RACFG_CMD_TX_START" is for Carrier test or Carrier Suppression.
+ if (ntohs(pRaCfg->length) != 0)
+ {
+ // Get frame info
+#ifdef RT2870
+ NdisMoveMemory(&pAdapter->ate.TxInfo, pRaCfg->data - 2, 4);
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR) &pAdapter->ate.TxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+#endif // RT2870 //
+
+ NdisMoveMemory(&pAdapter->ate.TxWI, pRaCfg->data + 2, 16);
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange((PUCHAR)&pAdapter->ate.TxWI, TYPE_TXWI);
+#endif // RT_BIG_ENDIAN //
+
+ NdisMoveMemory(&pAdapter->ate.TxCount, pRaCfg->data + 18, 4);
+ pAdapter->ate.TxCount = ntohl(pAdapter->ate.TxCount);
+
+ p = (USHORT *)(&pRaCfg->data[22]);
+ //p = pRaCfg->data + 22;
+ // always use QID_AC_BE
+ pAdapter->ate.QID = 0;
+ p = (USHORT *)(&pRaCfg->data[24]);
+ //p = pRaCfg->data + 24;
+ pAdapter->ate.HLen = ntohs(*p);
+
+ if (pAdapter->ate.HLen > 32)
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.HLen > 32\n"));
+ err = 3;
+ goto TX_START_ERROR;
+ }
+
+ NdisMoveMemory(&pAdapter->ate.Header, pRaCfg->data + 26, pAdapter->ate.HLen);
+
+
+ pAdapter->ate.PLen = ntohs(pRaCfg->length) - (pAdapter->ate.HLen + 28);
+
+ if (pAdapter->ate.PLen > 32)
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.PLen > 32\n"));
+ err = 4;
+ goto TX_START_ERROR;
+ }
+
+ NdisMoveMemory(&pAdapter->ate.Pattern, pRaCfg->data + 26 + pAdapter->ate.HLen, pAdapter->ate.PLen);
+ pAdapter->ate.DLen = pAdapter->ate.TxWI.MPDUtotalByteCount - pAdapter->ate.HLen;
+ }
+
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R22, &Bbp22Value);
+
+ switch (Bbp22Value)
+ {
+ case BBP22_TXFRAME:
+ {
+ if (pAdapter->ate.TxCount == 0)
+ {
+ }
+ ATEDBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n"));
+ pAdapter->ate.bQATxStart = TRUE;
+ Set_ATE_Proc(pAdapter, "TXFRAME");
+ }
+ break;
+
+ case BBP22_TXCONT_OR_CARRSUPP:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("BBP22_TXCONT_OR_CARRSUPP\n"));
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, 24, &Bbp24Value);
+
+ switch (Bbp24Value)
+ {
+ case BBP24_TXCONT:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCONT\n"));
+ pAdapter->ate.bQATxStart = TRUE;
+ Set_ATE_Proc(pAdapter, "TXCONT");
+ }
+ break;
+
+ case BBP24_CARRSUPP:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARRSUPP\n"));
+ pAdapter->ate.bQATxStart = TRUE;
+ pAdapter->ate.Mode |= ATE_TXCARRSUPP;
+ }
+ break;
+
+ default:
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
+ }
+ break;
+ }
+ }
+ break;
+
+ case BBP22_TXCARR:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARR\n"));
+ pAdapter->ate.bQATxStart = TRUE;
+ Set_ATE_Proc(pAdapter, "TXCARR");
+ }
+ break;
+
+ default:
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
+ }
+ break;
+ }
+
+ if (pAdapter->ate.bQATxStart == TRUE)
+ {
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() was failed in case RACFG_CMD_TX_START\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_START is done !\n"));
+ }
+ break;
+ }
+
+TX_START_ERROR:
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(err);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_TX_START\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("feedback of TX_START_ERROR is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_GET_TX_STATUS:
+ {
+ UINT32 count;
+
+ // prepare feedback
+ pRaCfg->length = htons(6);
+ pRaCfg->status = htons(0);
+ count = htonl(pAdapter->ate.TxDoneCount);
+ NdisMoveMemory(pRaCfg->data, &count, 4);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_TX_STATUS\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_TX_STATUS is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_TX_STOP:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_TX_STOP\n"));
+
+ Set_ATE_Proc(pAdapter, "TXSTOP");
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_TX_STOP\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_STOP is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_RX_START:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
+
+ pAdapter->ate.bQARxStart = TRUE;
+ Set_ATE_Proc(pAdapter, "RXFRAME");
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_RX_STOP:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_STOP\n"));
+
+ Set_ATE_Proc(pAdapter, "RXSTOP");
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_STOP\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_STOP is done !\n"));
+ }
+ }
+ break;
+
+ /* The following cases are for new ATE GUI(not QA). */
+ /*==================================================*/
+ case RACFG_CMD_ATE_START_TX_CARRIER:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CARRIER\n"));
+
+ Set_ATE_Proc(pAdapter, "TXCARR");
+
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_CARRIER\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CARRIER is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_START_TX_CONT:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CONT\n"));
+
+ Set_ATE_Proc(pAdapter, "TXCONT");
+
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_CONT\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CONT is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_START_TX_FRAME:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_FRAME\n"));
+
+ Set_ATE_Proc(pAdapter, "TXFRAME");
+
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_FRAME\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_FRAME is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_BW:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_BW\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+
+ Set_ATE_TX_BW_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_BW\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_BW is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_TX_POWER0:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER0\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_POWER0_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER0\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER0 is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_TX_POWER1:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER1\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_POWER1_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER1\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER1 is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_FREQ_OFFSET:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_FREQOFFSET_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_FREQ_OFFSET is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_GET_STATISTICS:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_GET_STATISTICS\n"));
+
+ memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.TxDoneCount, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->WlanCounters.RetryCount.u.LowPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->WlanCounters.FailedCount.u.LowPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->WlanCounters.RTSSuccessCount.u.LowPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->WlanCounters.RTSFailureCount.u.LowPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->WlanCounters.FCSErrorCount.u.LowPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->Counters8023.RxNoBuffer, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->RalinkCounters.OneSecFalseCCACnt, 4);
+
+ if (pAdapter->ate.RxAntennaSel == 0)
+ {
+ INT32 RSSI0 = 0;
+ INT32 RSSI1 = 0;
+ INT32 RSSI2 = 0;
+
+ RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
+ RSSI1 = (INT32)(pAdapter->ate.LastRssi1 - pAdapter->BbpRssiToDbmDelta);
+ RSSI2 = (INT32)(pAdapter->ate.LastRssi2 - pAdapter->BbpRssiToDbmDelta);
+ memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&RSSI1, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&RSSI2, 4);
+ pRaCfg->length = htons(2+52);
+ }
+ else
+ {
+ INT32 RSSI0 = 0;
+
+ RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
+ memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
+ pRaCfg->length = htons(2+44);
+ }
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_GET_STATISTICS\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_GET_STATISTICS is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_RESET_COUNTER:
+ {
+ SHORT value = 1;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_RESET_COUNTER\n"));
+
+ sprintf((PCHAR)str, "%d", value);
+ Set_ResetStatCounter_Proc(pAdapter, str);
+
+ pAdapter->ate.TxDoneCount = 0;
+
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RESET_COUNTER\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RESET_COUNTER is done !\n"));
+ }
+ }
+
+ break;
+
+ case RACFG_CMD_ATE_SEL_TX_ANTENNA:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_Antenna_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_TX_ANTENNA is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SEL_RX_ANTENNA:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_RX_Antenna_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_RX_ANTENNA is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_PREAMBLE:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_PREAMBLE\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_MODE_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_PREAMBLE\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_PREAMBLE is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_CHANNEL:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_CHANNEL\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_CHANNEL_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_CHANNEL\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_CHANNEL is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_ADDR1:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR1\n"));
+
+ // Addr is an array of UCHAR,
+ // so no need to perform endian swap.
+ memcpy(pAdapter->ate.Addr1, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR1\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR1 is done !\n (ADDR1 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr1[0],
+ pAdapter->ate.Addr1[1], pAdapter->ate.Addr1[2], pAdapter->ate.Addr1[3], pAdapter->ate.Addr1[4], pAdapter->ate.Addr1[5]));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_ADDR2:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR2\n"));
+
+ // Addr is an array of UCHAR,
+ // so no need to perform endian swap.
+ memcpy(pAdapter->ate.Addr2, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR2\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR2 is done !\n (ADDR2 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr2[0],
+ pAdapter->ate.Addr2[1], pAdapter->ate.Addr2[2], pAdapter->ate.Addr2[3], pAdapter->ate.Addr2[4], pAdapter->ate.Addr2[5]));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_ADDR3:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR3\n"));
+
+ // Addr is an array of UCHAR,
+ // so no need to perform endian swap.
+ memcpy(pAdapter->ate.Addr3, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR3\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR3 is done !\n (ADDR3 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr3[0],
+ pAdapter->ate.Addr3[1], pAdapter->ate.Addr3[2], pAdapter->ate.Addr3[3], pAdapter->ate.Addr3[4], pAdapter->ate.Addr3[5]));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_RATE:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_RATE\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_MCS_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_RATE\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_RATE is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_TX_FRAME_LEN:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_LENGTH_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_LEN is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_TX_FRAME_COUNT:
+ {
+ USHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ {
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_COUNT_Proc(pAdapter, str);
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_COUNT is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_START_RX_FRAME:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
+
+ Set_ATE_Proc(pAdapter, "RXFRAME");
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ ASSERT(pRaCfg != NULL);
+ if (pRaCfg != NULL)
+ {
+ kfree(pRaCfg);
+ }
+ return;
+}
+
+VOID BubbleSort(INT32 n, INT32 a[])
+{
+ INT32 k, j, temp;
+
+ for (k = n-1; k>0; k--)
+ {
+ for (j = 0; j<k; j++)
+ {
+ if(a[j] > a[j+1])
+ {
+ temp = a[j];
+ a[j]=a[j+1];
+ a[j+1]=temp;
+ }
+ }
+ }
+}
+
+VOID CalNoiseLevel(PRTMP_ADAPTER pAd, UCHAR channel, INT32 RSSI[3][10])
+{
+ INT32 RSSI0, RSSI1, RSSI2;
+ CHAR Rssi0Offset, Rssi1Offset, Rssi2Offset;
+ UCHAR BbpR50Rssi0 = 0, BbpR51Rssi1 = 0, BbpR52Rssi2 = 0;
+ UCHAR Org_BBP66value = 0, Org_BBP69value = 0, Org_BBP70value = 0, data = 0;
+ USHORT LNA_Gain = 0;
+ INT32 j = 0;
+ UCHAR Org_Channel = pAd->ate.Channel;
+ USHORT GainValue = 0, OffsetValue = 0;
+
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &Org_BBP66value);
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R69, &Org_BBP69value);
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R70, &Org_BBP70value);
+
+ //**********************************************************************
+ // Read the value of LNA gain and Rssi offset
+ //**********************************************************************
+ RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, GainValue);
+
+ // for Noise Level
+ if (channel <= 14)
+ {
+ LNA_Gain = GainValue & 0x00FF;
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, OffsetValue);
+ Rssi0Offset = OffsetValue & 0x00FF;
+ Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
+ RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_BG_OFFSET + 2)/* 0x48 */, OffsetValue);
+ Rssi2Offset = OffsetValue & 0x00FF;
+ }
+ else
+ {
+ LNA_Gain = (GainValue & 0xFF00) >> 8;
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, OffsetValue);
+ Rssi0Offset = OffsetValue & 0x00FF;
+ Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
+ RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2)/* 0x4C */, OffsetValue);
+ Rssi2Offset = OffsetValue & 0x00FF;
+ }
+ //**********************************************************************
+ {
+ pAd->ate.Channel = channel;
+ ATEAsicSwitchChannel(pAd);
+ mdelay(5);
+
+ data = 0x10;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, data);
+ data = 0x40;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, data);
+ data = 0x40;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, data);
+ mdelay(5);
+
+ // Start Rx
+ pAd->ate.bQARxStart = TRUE;
+ Set_ATE_Proc(pAd, "RXFRAME");
+
+ mdelay(5);
+
+ for (j = 0; j < 10; j++)
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R50, &BbpR50Rssi0);
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R51, &BbpR51Rssi1);
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R52, &BbpR52Rssi2);
+
+ mdelay(10);
+
+ // Calculate RSSI 0
+ if (BbpR50Rssi0 == 0)
+ {
+ RSSI0 = -100;
+ }
+ else
+ {
+ RSSI0 = (INT32)(-12 - BbpR50Rssi0 - LNA_Gain - Rssi0Offset);
+ }
+ RSSI[0][j] = RSSI0;
+
+ if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
+ {
+ // Calculate RSSI 1
+ if (BbpR51Rssi1 == 0)
+ {
+ RSSI1 = -100;
+ }
+ else
+ {
+ RSSI1 = (INT32)(-12 - BbpR51Rssi1 - LNA_Gain - Rssi1Offset);
+ }
+ RSSI[1][j] = RSSI1;
+ }
+
+ if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
+ {
+ // Calculate RSSI 2
+ if (BbpR52Rssi2 == 0)
+ RSSI2 = -100;
+ else
+ RSSI2 = (INT32)(-12 - BbpR52Rssi2 - LNA_Gain - Rssi2Offset);
+
+ RSSI[2][j] = RSSI2;
+ }
+ }
+
+ // Stop Rx
+ Set_ATE_Proc(pAd, "RXSTOP");
+
+ mdelay(5);
+
+ BubbleSort(10, RSSI[0]); // 1R
+
+ if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
+ {
+ BubbleSort(10, RSSI[1]);
+ }
+
+ if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
+ {
+ BubbleSort(10, RSSI[2]);
+ }
+
+ }
+
+ pAd->ate.Channel = Org_Channel;
+ ATEAsicSwitchChannel(pAd);
+
+ // Restore original value
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, Org_BBP66value);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, Org_BBP69value);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, Org_BBP70value);
+
+ return;
+}
+
+BOOLEAN SyncTxRxConfig(PRTMP_ADAPTER pAd, USHORT offset, UCHAR value)
+{
+ UCHAR tmp = 0, bbp_data = 0;
+
+ if (ATE_ON(pAd))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
+ }
+ else
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
+ }
+
+ /* confirm again */
+ ASSERT(bbp_data == value);
+
+ switch(offset)
+ {
+ case BBP_R1:
+ /* Need to sync. tx configuration with legacy ATE. */
+ tmp = (bbp_data & ((1 << 4) | (1 << 3))/* 0x18 */) >> 3;
+ switch(tmp)
+ {
+ /* The BBP R1 bit[4:3] = 2 :: Both DACs will be used by QA. */
+ case 2:
+ /* All */
+ pAd->ate.TxAntennaSel = 0;
+ break;
+ /* The BBP R1 bit[4:3] = 0 :: DAC 0 will be used by QA. */
+ case 0:
+ /* Antenna one */
+ pAd->ate.TxAntennaSel = 1;
+ break;
+ /* The BBP R1 bit[4:3] = 1 :: DAC 1 will be used by QA. */
+ case 1:
+ /* Antenna two */
+ pAd->ate.TxAntennaSel = 2;
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s -- Sth. wrong! : return FALSE; \n", __FUNCTION__));
+ return FALSE;
+ }
+ break;/* case BBP_R1 */
+
+ case BBP_R3:
+ /* Need to sync. rx configuration with legacy ATE. */
+ tmp = (bbp_data & ((1 << 1) | (1 << 0))/* 0x03 */);
+ switch(tmp)
+ {
+ /* The BBP R3 bit[1:0] = 3 :: All ADCs will be used by QA. */
+ case 3:
+ /* All */
+ pAd->ate.RxAntennaSel = 0;
+ break;
+ /* The BBP R3 bit[1:0] = 0 :: ADC 0 will be used by QA, */
+ /* unless the BBP R3 bit[4:3] = 2 */
+ case 0:
+ /* Antenna one */
+ pAd->ate.RxAntennaSel = 1;
+ tmp = ((bbp_data & ((1 << 4) | (1 << 3))/* 0x03 */) >> 3);
+ if (tmp == 2)// 3R
+ {
+ /* Default : All ADCs will be used by QA */
+ pAd->ate.RxAntennaSel = 0;
+ }
+ break;
+ /* The BBP R3 bit[1:0] = 1 :: ADC 1 will be used by QA. */
+ case 1:
+ /* Antenna two */
+ pAd->ate.RxAntennaSel = 2;
+ break;
+ /* The BBP R3 bit[1:0] = 2 :: ADC 2 will be used by QA. */
+ case 2:
+ /* Antenna three */
+ pAd->ate.RxAntennaSel = 3;
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_ERROR, ("%s -- Impossible! : return FALSE; \n", __FUNCTION__));
+ return FALSE;
+ }
+ break;/* case BBP_R3 */
+
+ default:
+ DBGPRINT(RT_DEBUG_ERROR, ("%s -- Sth. wrong! : return FALSE; \n", __FUNCTION__));
+ return FALSE;
+
+ }
+ return TRUE;
+}
+
+static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
+{
+ ULONG i, Value = 0;
+ ULONG *pDst, *pSrc;
+ UCHAR *p8;
+
+ p8 = src;
+ pDst = (ULONG *) dst;
+ pSrc = (ULONG *) src;
+
+ for (i = 0 ; i < (len/4); i++)
+ {
+ /* For alignment issue, we need a variable "Value". */
+ memmove(&Value, pSrc, 4);
+ Value = htonl(Value);
+ memmove(pDst, &Value, 4);
+ pDst++;
+ pSrc++;
+ }
+ if ((len % 4) != 0)
+ {
+ /* wish that it will never reach here */
+ memmove(&Value, pSrc, (len % 4));
+ Value = htonl(Value);
+ memmove(pDst, &Value, (len % 4));
+ }
+}
+
+static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
+{
+ ULONG i;
+ UCHAR *pDst, *pSrc;
+
+ pDst = dst;
+ pSrc = src;
+
+ for (i = 0; i < (len/2); i++)
+ {
+ memmove(pDst, pSrc, 2);
+ *((USHORT *)pDst) = htons(*((USHORT *)pDst));
+ pDst+=2;
+ pSrc+=2;
+ }
+
+ if ((len % 2) != 0)
+ {
+ memmove(pDst, pSrc, 1);
+ }
+}
+
+static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len)
+{
+ UINT32 i, Value;
+ UINT32 *pDst, *pSrc;
+
+ pDst = (UINT32 *) dst;
+ pSrc = (UINT32 *) src;
+
+ for (i = 0 ; i < (len/4); i++)
+ {
+ RTMP_IO_READ32(pAd, (ULONG)pSrc, &Value);
+ Value = htonl(Value);
+ memmove(pDst, &Value, 4);
+ pDst++;
+ pSrc++;
+ }
+ return;
+}
+
+INT Set_TxStop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ATEDBGPRINT(RT_DEBUG_TRACE,("Set_TxStop_Proc\n"));
+
+ if (Set_ATE_Proc(pAd, "TXSTOP"))
+ {
+ return TRUE;
+}
+ else
+ {
+ return FALSE;
+ }
+}
+
+INT Set_RxStop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ATEDBGPRINT(RT_DEBUG_TRACE,("Set_RxStop_Proc\n"));
+
+ if (Set_ATE_Proc(pAd, "RXSTOP"))
+ {
+ return TRUE;
+}
+ else
+ {
+ return FALSE;
+ }
+}
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
diff --git a/drivers/staging/rt3070/rt_ate.h b/drivers/staging/rt3070/rt_ate.h
new file mode 100644
index 00000000000..829ebb5f723
--- /dev/null
+++ b/drivers/staging/rt3070/rt_ate.h
@@ -0,0 +1,294 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#ifndef __ATE_H__
+#define __ATE_H__
+
+#ifndef UCOS
+#define ate_print printk
+#define ATEDBGPRINT DBGPRINT
+
+#ifdef RT2870
+#define EEPROM_SIZE 0x400
+#ifdef CONFIG_STA_SUPPORT
+#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2870STA/e2p.bin"
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT2870 //
+#else // !UCOS //
+#define fATE_LOAD_EEPROM 0x0C43
+#ifdef CONFIG_PRINTK
+extern INT ConsoleResponse(IN PUCHAR buff);
+extern int (*remote_display)(char *);
+extern void puts (const char *s);
+
+/* specificly defined to redirect and show ate-related messages to host. */
+/* Try to define ate_print as a macro. */
+#define ate_print(fmt, args...) \
+do{ int (*org_remote_display)(char *) = NULL; \
+ org_remote_display = remote_display;\
+ /* Save original "remote_display" */\
+ remote_display = (int (*)(char *))ConsoleResponse; \
+ printk(fmt, ## args); \
+ /* Restore the remote_display function pointer */ \
+ remote_display = org_remote_display; }while(0)
+
+#define ATEDBGPRINT(Level, Fmt) \
+{ \
+ if ((Level) <= RTDebugLevel) \
+ { \
+ ate_print Fmt; \
+ } \
+}
+#endif // CONFIG_PRINTK //
+#endif // !UCOS //
+
+#define ATE_ON(_p) (((_p)->ate.Mode) != ATE_STOP)
+
+/* RT2880_iNIC will define "RT2860". */
+
+/* RT2880_iNIC will define RT2860. */
+
+#ifdef RT2870
+#define EEPROM_SIZE 0x400
+#ifdef CONFIG_STA_SUPPORT
+#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2870STA/e2p.bin"
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT2870 //
+
+#ifdef RT2870
+#define ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)
+#define ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)
+
+#define BULK_OUT_LOCK(pLock, IrqFlags) \
+ if(1 /*!(in_interrupt() & 0xffff0000)*/) \
+ RTMP_IRQ_LOCK((pLock), IrqFlags);
+
+#define BULK_OUT_UNLOCK(pLock, IrqFlags) \
+ if(1 /*!(in_interrupt() & 0xffff0000)*/) \
+ RTMP_IRQ_UNLOCK((pLock), IrqFlags);
+
+// Prototypes of completion funuc.
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define ATE_RTUSBBulkOutDataPacketComplete(purb, pt_regs) ATE_RTUSBBulkOutDataPacketComplete(purb)
+#endif
+
+VOID ATE_RTUSBBulkOutDataPacketComplete(
+ IN purbb_t purb,
+ OUT struct pt_regs *pt_regs);
+
+VOID ATE_RTUSBBulkOutDataPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BulkOutPipeId);
+
+VOID ATE_RTUSBCancelPendingBulkInIRP(
+ IN PRTMP_ADAPTER pAd);
+#endif // RT2870 //
+
+#ifdef RT30xx
+#define ATE_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)
+#define ATE_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)
+#endif // RT30xx //
+
+
+VOID rt_ee_read_all(
+ IN PRTMP_ADAPTER pAd,
+ OUT USHORT *Data);
+
+
+VOID rt_ee_write_all(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT *Data);
+
+INT Set_ATE_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_DA_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_SA_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_BSSID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_CHANNEL_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_POWER0_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_POWER1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_Antenna_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_RX_Antenna_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_FREQOFFSET_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_BW_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_LENGTH_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_COUNT_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_MCS_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_MODE_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_GI_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+
+INT Set_ATE_RX_FER_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Read_RF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Write_RF1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Write_RF2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Write_RF3_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Write_RF4_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Load_E2P_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Read_E2P_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Show_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Help_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+#ifdef RALINK_ATE
+#ifdef RALINK_28xx_QA
+VOID ATE_QA_Statistics(
+ IN PRTMP_ADAPTER pAd,
+ IN PRXWI_STRUC pRxWI,
+ IN PRT28XX_RXD_STRUC p28xxRxD,
+ IN PHEADER_802_11 pHeader);
+
+VOID RtmpDoAte(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq);
+
+VOID BubbleSort(
+ IN INT32 n,
+ IN INT32 a[]);
+
+VOID CalNoiseLevel(
+ IN PRTMP_ADAPTER pAdapter,
+ IN UCHAR channel,
+ OUT INT32 buffer[3][10]);
+
+BOOLEAN SyncTxRxConfig(
+ IN PRTMP_ADAPTER pAdapter,
+ IN USHORT offset,
+ IN UCHAR value);
+
+INT Set_TxStop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_RxStop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+VOID ATEAsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ATEAsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ATEDisableAsicProtect(
+ IN PRTMP_ADAPTER pAd);
+
+CHAR ATEConvertToRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi,
+ IN UCHAR RssiNumber);
+
+VOID ATESampleRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN PRXWI_STRUC pRxWI);
+
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPStationStop(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPStationStart(
+ IN PRTMP_ADAPTER pAd);
+#endif // CONFIG_STA_SUPPORT //
+#endif // __ATE_H__ //
diff --git a/drivers/staging/rt3070/rt_config.h b/drivers/staging/rt3070/rt_config.h
new file mode 100644
index 00000000000..9e06417f63d
--- /dev/null
+++ b/drivers/staging/rt3070/rt_config.h
@@ -0,0 +1,121 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rt_config.h
+
+ Abstract:
+ Central header file to maintain all include files for all NDIS
+ miniport driver routines.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 08-01-2002 created
+
+*/
+#ifndef __RT_CONFIG_H__
+#define __RT_CONFIG_H__
+
+#include "rtmp_type.h"
+#ifdef UCOS
+#include "includes.h"
+#include <stdio.h>
+#include "rt_ucos.h"
+#endif
+
+#ifdef LINUX
+#include "rt_linux.h"
+#endif
+#include "rtmp_def.h"
+#include "rt28xx.h"
+
+
+#ifdef RT2870
+#include "rt2870.h"
+#endif // RT2870 //
+
+#include "oid.h"
+#include "mlme.h"
+#include "wpa.h"
+#include "md5.h"
+#include "rtmp.h"
+#include "ap.h"
+#include "dfs.h"
+#include "chlist.h"
+#include "spectrum.h"
+#ifdef MLME_EX
+#include "mlme_ex_def.h"
+#include "mlme_ex.h"
+#endif // MLME_EX //
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+#ifdef LEAP_SUPPORT
+#include "leap.h"
+#endif // LEAP_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef BLOCK_NET_IF
+#include "netif_block.h"
+#endif // BLOCK_NET_IF //
+
+#ifdef IGMP_SNOOP_SUPPORT
+#include "igmp_snoop.h"
+#endif // IGMP_SNOOP_SUPPORT //
+
+#ifdef RALINK_ATE
+#include "rt_ate.h"
+#endif // RALINK_ATE //
+
+
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifndef WPA_SUPPLICANT_SUPPORT
+#error "Build for being controlled by NetworkManager or wext, please set HAS_WPA_SUPPLICANT=y and HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y"
+#endif // WPA_SUPPLICANT_SUPPORT //
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef IKANOS_VX_1X0
+#include "vr_ikans.h"
+#endif // IKANOS_VX_1X0 //
+
+#endif // __RT_CONFIG_H__
+
diff --git a/drivers/staging/rt3070/rt_linux.c b/drivers/staging/rt3070/rt_linux.c
new file mode 100644
index 00000000000..bf3385365da
--- /dev/null
+++ b/drivers/staging/rt3070/rt_linux.c
@@ -0,0 +1,1063 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#include "rt_config.h"
+
+ULONG RTDebugLevel = RT_DEBUG_ERROR;
+
+BUILD_TIMER_FUNCTION(MlmePeriodicExec);
+//BUILD_TIMER_FUNCTION(MlmeRssiReportExec);
+BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+BUILD_TIMER_FUNCTION(APSDPeriodicExec);
+BUILD_TIMER_FUNCTION(AsicRfTuningExec);
+#ifdef RT2870
+BUILD_TIMER_FUNCTION(BeaconUpdateExec);
+#endif // RT2870 //
+
+
+#ifdef CONFIG_STA_SUPPORT
+BUILD_TIMER_FUNCTION(BeaconTimeout);
+BUILD_TIMER_FUNCTION(ScanTimeout);
+BUILD_TIMER_FUNCTION(AuthTimeout);
+BUILD_TIMER_FUNCTION(AssocTimeout);
+BUILD_TIMER_FUNCTION(ReassocTimeout);
+BUILD_TIMER_FUNCTION(DisassocTimeout);
+BUILD_TIMER_FUNCTION(LinkDownExec);
+#ifdef LEAP_SUPPORT
+BUILD_TIMER_FUNCTION(LeapAuthTimeout);
+#endif
+BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
+BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
+#ifdef QOS_DLS_SUPPORT
+BUILD_TIMER_FUNCTION(DlsTimeoutAction);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+
+// for wireless system event message
+char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
+ // system status event
+ "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
+ "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
+ "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
+ "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
+ "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
+ "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
+ "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
+ "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
+ "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
+ "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
+ "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
+ "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
+ "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
+ "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
+ "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
+ "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
+ "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
+ "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
+ "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
+ };
+
+// for wireless IDS_spoof_attack event message
+char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
+ "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
+ "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
+ "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
+ "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
+ "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
+ "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
+ "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
+ "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
+ "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
+ "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
+ };
+
+// for wireless IDS_flooding_attack event message
+char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
+ "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
+ "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
+ "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
+ "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
+ "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
+ "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
+ "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
+ };
+
+
+/* timeout -- ms */
+VOID RTMP_SetPeriodicTimer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN unsigned long timeout)
+{
+ timeout = ((timeout*HZ) / 1000);
+ pTimer->expires = jiffies + timeout;
+ add_timer(pTimer);
+}
+
+/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
+VOID RTMP_OS_Init_Timer(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN TIMER_FUNCTION function,
+ IN PVOID data)
+{
+ init_timer(pTimer);
+ pTimer->data = (unsigned long)data;
+ pTimer->function = function;
+}
+
+
+VOID RTMP_OS_Add_Timer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN unsigned long timeout)
+{
+ if (timer_pending(pTimer))
+ return;
+
+ timeout = ((timeout*HZ) / 1000);
+ pTimer->expires = jiffies + timeout;
+ add_timer(pTimer);
+}
+
+VOID RTMP_OS_Mod_Timer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN unsigned long timeout)
+{
+ timeout = ((timeout*HZ) / 1000);
+ mod_timer(pTimer, jiffies + timeout);
+}
+
+VOID RTMP_OS_Del_Timer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ OUT BOOLEAN *pCancelled)
+{
+ if (timer_pending(pTimer))
+ {
+ *pCancelled = del_timer_sync(pTimer);
+ }
+ else
+ {
+ *pCancelled = TRUE;
+ }
+
+}
+
+VOID RTMP_OS_Release_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PQUEUE_ENTRY pEntry)
+{
+ //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
+}
+
+// Unify all delay routine by using udelay
+VOID RTMPusecDelay(
+ IN ULONG usec)
+{
+ ULONG i;
+
+ for (i = 0; i < (usec / 50); i++)
+ udelay(50);
+
+ if (usec % 50)
+ udelay(usec % 50);
+}
+
+void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
+{
+ time->u.LowPart = jiffies;
+}
+
+// pAd MUST allow to be NULL
+NDIS_STATUS os_alloc_mem(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR *mem,
+ IN ULONG size)
+{
+ *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
+ if (*mem)
+ return (NDIS_STATUS_SUCCESS);
+ else
+ return (NDIS_STATUS_FAILURE);
+}
+
+// pAd MUST allow to be NULL
+NDIS_STATUS os_free_mem(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR mem)
+{
+
+ ASSERT(mem);
+ kfree(mem);
+ return (NDIS_STATUS_SUCCESS);
+}
+
+
+PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length)
+{
+ struct sk_buff *pkt;
+
+ pkt = dev_alloc_skb(Length);
+
+ if (pkt == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
+ }
+
+ if (pkt)
+ {
+ RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
+ }
+
+ return (PNDIS_PACKET) pkt;
+}
+
+
+PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress)
+{
+ struct sk_buff *pkt;
+
+ pkt = dev_alloc_skb(Length);
+
+ if (pkt == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
+ }
+
+ if (pkt)
+ {
+ RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
+ *VirtualAddress = (PVOID) pkt->data;
+ }
+ else
+ {
+ *VirtualAddress = (PVOID) NULL;
+ }
+
+ return (PNDIS_PACKET) pkt;
+}
+
+
+VOID build_tx_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pFrame,
+ IN ULONG FrameLen)
+{
+
+ struct sk_buff *pTxPkt;
+
+ ASSERT(pPacket);
+ pTxPkt = RTPKT_TO_OSPKT(pPacket);
+
+ NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
+}
+
+VOID RTMPFreeAdapter(
+ IN PRTMP_ADAPTER pAd)
+{
+ POS_COOKIE os_cookie;
+ int index;
+
+ os_cookie=(POS_COOKIE)pAd->OS_Cookie;
+
+ kfree(pAd->BeaconBuf);
+
+
+ NdisFreeSpinLock(&pAd->MgmtRingLock);
+
+
+ for (index =0 ; index < NUM_OF_TX_RING; index++)
+ {
+ NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
+ NdisFreeSpinLock(&pAd->DeQueueLock[index]);
+ pAd->DeQueueRunning[index] = FALSE;
+ }
+
+ NdisFreeSpinLock(&pAd->irq_lock);
+
+
+ vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
+ kfree(os_cookie);
+}
+
+BOOLEAN OS_Need_Clone_Packet(void)
+{
+ return (FALSE);
+}
+
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
+ must have only one NDIS BUFFER
+ return - byte copied. 0 means can't create NDIS PACKET
+ NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
+
+ Arguments:
+ pAd Pointer to our adapter
+ pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
+ *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
+
+ Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_FAILURE
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS RTMPCloneNdisPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN pInsAMSDUHdr,
+ IN PNDIS_PACKET pInPacket,
+ OUT PNDIS_PACKET *ppOutPacket)
+{
+
+ struct sk_buff *pkt;
+
+ ASSERT(pInPacket);
+ ASSERT(ppOutPacket);
+
+ // 1. Allocate a packet
+ pkt = dev_alloc_skb(2048);
+
+ if (pkt == NULL)
+ {
+ return NDIS_STATUS_FAILURE;
+ }
+
+ skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
+ NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
+ *ppOutPacket = OSPKT_TO_RTPKT(pkt);
+
+
+ RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
+
+ printk("###Clone###\n");
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+// the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
+NDIS_STATUS RTMPAllocateNdisPacket(
+ IN PRTMP_ADAPTER pAd,
+ OUT PNDIS_PACKET *ppPacket,
+ IN PUCHAR pHeader,
+ IN UINT HeaderLen,
+ IN PUCHAR pData,
+ IN UINT DataLen)
+{
+ PNDIS_PACKET pPacket;
+ ASSERT(pData);
+ ASSERT(DataLen);
+
+ // 1. Allocate a packet
+ pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
+ if (pPacket == NULL)
+ {
+ *ppPacket = NULL;
+#ifdef DEBUG
+ printk("RTMPAllocateNdisPacket Fail\n\n");
+#endif
+ return NDIS_STATUS_FAILURE;
+ }
+
+ // 2. clone the frame content
+ if (HeaderLen > 0)
+ NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
+ if (DataLen > 0)
+ NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
+
+ // 3. update length of packet
+ skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
+
+ RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+// printk("%s : pPacket = %p, len = %d\n", __FUNCTION__, pPacket, GET_OS_PKT_LEN(pPacket));
+ *ppPacket = pPacket;
+ return NDIS_STATUS_SUCCESS;
+}
+
+/*
+ ========================================================================
+ Description:
+ This routine frees a miniport internally allocated NDIS_PACKET and its
+ corresponding NDIS_BUFFER and allocated memory.
+ ========================================================================
+*/
+VOID RTMPFreeNdisPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
+}
+
+
+// IRQL = DISPATCH_LEVEL
+// NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
+// scatter gather buffer
+NDIS_STATUS Sniff2BytesFromNdisBuffer(
+ IN PNDIS_BUFFER pFirstBuffer,
+ IN UCHAR DesiredOffset,
+ OUT PUCHAR pByte0,
+ OUT PUCHAR pByte1)
+{
+ *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
+ *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+void RTMP_QueryPacketInfo(
+ IN PNDIS_PACKET pPacket,
+ OUT PACKET_INFO *pPacketInfo,
+ OUT PUCHAR *pSrcBufVA,
+ OUT UINT *pSrcBufLen)
+{
+ pPacketInfo->BufferCount = 1;
+ pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
+ pPacketInfo->PhysicalBufferCount = 1;
+ pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
+
+ *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
+ *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
+}
+
+void RTMP_QueryNextPacketInfo(
+ IN PNDIS_PACKET *ppPacket,
+ OUT PACKET_INFO *pPacketInfo,
+ OUT PUCHAR *pSrcBufVA,
+ OUT UINT *pSrcBufLen)
+{
+ PNDIS_PACKET pPacket = NULL;
+
+ if (*ppPacket)
+ pPacket = GET_OS_PKT_NEXT(*ppPacket);
+
+ if (pPacket)
+ {
+ pPacketInfo->BufferCount = 1;
+ pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
+ pPacketInfo->PhysicalBufferCount = 1;
+ pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
+
+ *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
+ *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
+ *ppPacket = GET_OS_PKT_NEXT(pPacket);
+ }
+ else
+ {
+ pPacketInfo->BufferCount = 0;
+ pPacketInfo->pFirstBuffer = NULL;
+ pPacketInfo->PhysicalBufferCount = 0;
+ pPacketInfo->TotalPacketLength = 0;
+
+ *pSrcBufVA = NULL;
+ *pSrcBufLen = 0;
+ *ppPacket = NULL;
+ }
+}
+
+// not yet support MBSS
+PNET_DEV get_netdev_from_bssid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR FromWhichBSSID)
+{
+ PNET_DEV dev_p = NULL;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ dev_p = pAd->net_dev;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ ASSERT(dev_p);
+ return dev_p; /* return one of MBSS */
+}
+
+PNDIS_PACKET DuplicatePacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR FromWhichBSSID)
+{
+ struct sk_buff *skb;
+ PNDIS_PACKET pRetPacket = NULL;
+ USHORT DataSize;
+ UCHAR *pData;
+
+ DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
+ pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
+
+
+ skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
+ if (skb)
+ {
+ skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+ pRetPacket = OSPKT_TO_RTPKT(skb);
+ }
+
+ return pRetPacket;
+
+}
+
+PNDIS_PACKET duplicate_pkt(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN ULONG DataSize,
+ IN UCHAR FromWhichBSSID)
+{
+ struct sk_buff *skb;
+ PNDIS_PACKET pPacket = NULL;
+
+
+ if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
+ {
+ skb_reserve(skb, 2);
+ NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
+ skb_put(skb, HdrLen);
+ NdisMoveMemory(skb->tail, pData, DataSize);
+ skb_put(skb, DataSize);
+ skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+ pPacket = OSPKT_TO_RTPKT(skb);
+ }
+
+ return pPacket;
+}
+
+
+#define TKIP_TX_MIC_SIZE 8
+PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ struct sk_buff *skb, *newskb;
+
+
+ skb = RTPKT_TO_OSPKT(pPacket);
+ if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
+ {
+ // alloc a new skb and copy the packet
+ newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
+ dev_kfree_skb_any(skb);
+ if (newskb == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
+ return NULL;
+ }
+ skb = newskb;
+ }
+
+ return OSPKT_TO_RTPKT(skb);
+}
+
+
+
+
+PNDIS_PACKET ClonePacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pData,
+ IN ULONG DataSize)
+{
+ struct sk_buff *pRxPkt;
+ struct sk_buff *pClonedPkt;
+
+ ASSERT(pPacket);
+ pRxPkt = RTPKT_TO_OSPKT(pPacket);
+
+ // clone the packet
+ pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
+
+ if (pClonedPkt)
+ {
+ // set the correct dataptr and data len
+ pClonedPkt->dev = pRxPkt->dev;
+ pClonedPkt->data = pData;
+ pClonedPkt->len = DataSize;
+ pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
+ ASSERT(DataSize < 1530);
+ }
+ return pClonedPkt;
+}
+
+//
+// change OS packet DataPtr and DataLen
+//
+void update_os_packet_info(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ struct sk_buff *pOSPkt;
+
+ ASSERT(pRxBlk->pRxPacket);
+ pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
+
+ pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+ pOSPkt->data = pRxBlk->pData;
+ pOSPkt->len = pRxBlk->DataSize;
+ pOSPkt->tail = pOSPkt->data + pOSPkt->len;
+}
+
+
+void wlan_802_11_to_802_3_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN PUCHAR pHeader802_3,
+ IN UCHAR FromWhichBSSID)
+{
+ struct sk_buff *pOSPkt;
+
+ ASSERT(pRxBlk->pRxPacket);
+ ASSERT(pHeader802_3);
+
+ pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
+
+ pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+ pOSPkt->data = pRxBlk->pData;
+ pOSPkt->len = pRxBlk->DataSize;
+ pOSPkt->tail = pOSPkt->data + pOSPkt->len;
+
+ //
+ // copy 802.3 header
+ //
+ //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+
+
+void announce_802_3_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+
+ struct sk_buff *pRxPkt;
+
+ ASSERT(pPacket);
+
+ pRxPkt = RTPKT_TO_OSPKT(pPacket);
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ /* Push up the protocol stack */
+#ifdef IKANOS_VX_1X0
+ IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
+#else
+ pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
+
+//#ifdef CONFIG_5VT_ENHANCE
+// *(int*)(pRxPkt->cb) = BRIDGE_TAG;
+//#endif
+ netif_rx(pRxPkt);
+#endif // IKANOS_VX_1X0 //
+}
+
+
+PRTMP_SCATTER_GATHER_LIST
+rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
+{
+ sg->NumberOfElements = 1;
+ sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
+ sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
+ return (sg);
+}
+
+void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
+{
+ unsigned char *pt;
+ int x;
+
+ if (RTDebugLevel < RT_DEBUG_TRACE)
+ return;
+
+ pt = pSrcBufVA;
+ printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
+ for (x=0; x<SrcBufLen; x++)
+ {
+ if (x % 16 == 0)
+ printk("0x%04x : ", x);
+ printk("%02x ", ((unsigned char)pt[x]));
+ if (x%16 == 15) printk("\n");
+ }
+ printk("\n");
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Send log message through wireless event
+
+ Support standard iw_event with IWEVCUSTOM. It is used below.
+
+ iwreq_data.data.flags is used to store event_flag that is defined by user.
+ iwreq_data.data.length is the length of the event log.
+
+ The format of the event log is composed of the entry's MAC address and
+ the desired log message (refer to pWirelessEventText).
+
+ ex: 11:22:33:44:55:66 has associated successfully
+
+ p.s. The requirement of Wireless Extension is v15 or newer.
+
+ ========================================================================
+*/
+VOID RTMPSendWirelessEvent(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Event_flag,
+ IN PUCHAR pAddr,
+ IN UCHAR BssIdx,
+ IN CHAR Rssi)
+{
+#if WIRELESS_EXT >= 15
+
+ union iwreq_data wrqu;
+ PUCHAR pBuf = NULL, pBufPtr = NULL;
+ USHORT event, type, BufLen;
+ UCHAR event_table_len = 0;
+
+ type = Event_flag & 0xFF00;
+ event = Event_flag & 0x00FF;
+
+ switch (type)
+ {
+ case IW_SYS_EVENT_FLAG_START:
+ event_table_len = IW_SYS_EVENT_TYPE_NUM;
+ break;
+
+ case IW_SPOOF_EVENT_FLAG_START:
+ event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
+ break;
+
+ case IW_FLOOD_EVENT_FLAG_START:
+ event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
+ break;
+ }
+
+ if (event_table_len == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __FUNCTION__, type));
+ return;
+ }
+
+ if (event >= event_table_len)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __FUNCTION__, event));
+ return;
+ }
+
+ //Allocate memory and copy the msg.
+ if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
+ {
+ //Prepare the payload
+ memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
+
+ pBufPtr = pBuf;
+
+ if (pAddr)
+ pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
+ else if (BssIdx < MAX_MBSSID_NUM)
+ pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
+ else
+ pBufPtr += sprintf(pBufPtr, "(RT2860) ");
+
+ if (type == IW_SYS_EVENT_FLAG_START)
+ pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
+ else if (type == IW_SPOOF_EVENT_FLAG_START)
+ pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
+ else if (type == IW_FLOOD_EVENT_FLAG_START)
+ pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
+ else
+ pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
+
+ pBufPtr[pBufPtr - pBuf] = '\0';
+ BufLen = pBufPtr - pBuf;
+
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = Event_flag;
+ wrqu.data.length = BufLen;
+
+ //send wireless event
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
+
+ //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __FUNCTION__, pBuf));
+
+ kfree(pBuf);
+ }
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __FUNCTION__));
+#else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __FUNCTION__));
+#endif /* WIRELESS_EXT >= 15 */
+}
+
+
+#ifdef CONFIG_STA_SUPPORT
+void send_monitor_packets(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+ struct sk_buff *pOSPkt;
+ wlan_ng_prism2_header *ph;
+ int rate_index = 0;
+ USHORT header_len = 0;
+ UCHAR temp_header[40] = {0};
+
+ u_int32_t ralinkrate[256] = {2,4,11,22, 12,18,24,36,48,72,96, 108, 109, 110, 111, 112, 13, 26, 39, 52,78,104, 117, 130, 26, 52, 78,104, 156, 208, 234, 260, 27, 54,81,108,162, 216, 243, 270, // Last 38
+ 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115, 130, 144, 29, 59,87,115, 173, 230,260, 288, 30, 60,90,120,180,240,270,300,60,120,180,240,360,480,540,600, 0,1,2,3,4,5,6,7,8,9,10,
+ 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80};
+
+
+ ASSERT(pRxBlk->pRxPacket);
+ if (pRxBlk->DataSize < 10)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __FUNCTION__, pRxBlk->DataSize));
+ goto err_free_sk_buff;
+ }
+
+ if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __FUNCTION__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
+ goto err_free_sk_buff;
+ }
+
+ pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
+ pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
+ if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
+ {
+ pRxBlk->DataSize -= LENGTH_802_11;
+ if ((pRxBlk->pHeader->FC.ToDs == 1) &&
+ (pRxBlk->pHeader->FC.FrDs == 1))
+ header_len = LENGTH_802_11_WITH_ADDR4;
+ else
+ header_len = LENGTH_802_11;
+
+ // QOS
+ if (pRxBlk->pHeader->FC.SubType & 0x08)
+ {
+ header_len += 2;
+ // Data skip QOS contorl field
+ pRxBlk->DataSize -=2;
+ }
+
+ // Order bit: A-Ralink or HTC+
+ if (pRxBlk->pHeader->FC.Order)
+ {
+ header_len += 4;
+ // Data skip HTC contorl field
+ pRxBlk->DataSize -= 4;
+ }
+
+ // Copy Header
+ if (header_len <= 40)
+ NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
+
+ // skip HW padding
+ if (pRxBlk->RxD.L2PAD)
+ pRxBlk->pData += (header_len + 2);
+ else
+ pRxBlk->pData += header_len;
+ } //end if
+
+
+ if (pRxBlk->DataSize < pOSPkt->len) {
+ skb_trim(pOSPkt,pRxBlk->DataSize);
+ } else {
+ skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
+ } //end if
+
+ if ((pRxBlk->pData - pOSPkt->data) > 0) {
+ skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
+ skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
+ } //end if
+
+ if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
+ if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __FUNCTION__));
+ goto err_free_sk_buff;
+ } //end if
+ } //end if
+
+ if (header_len > 0)
+ NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
+
+ ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
+ NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
+
+ ph->msgcode = DIDmsg_lnxind_wlansniffrm;
+ ph->msglen = sizeof(wlan_ng_prism2_header);
+ strcpy(ph->devname, pAd->net_dev->name);
+
+ ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
+ ph->hosttime.status = 0;
+ ph->hosttime.len = 4;
+ ph->hosttime.data = jiffies;
+
+ ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
+ ph->mactime.status = 0;
+ ph->mactime.len = 0;
+ ph->mactime.data = 0;
+
+ ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
+ ph->istx.status = 0;
+ ph->istx.len = 0;
+ ph->istx.data = 0;
+
+ ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
+ ph->channel.status = 0;
+ ph->channel.len = 4;
+
+ ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
+
+ ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
+ ph->rssi.status = 0;
+ ph->rssi.len = 4;
+ ph->rssi.data = (u_int32_t)RTMPMaxRssi(pAd, ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2));;
+
+ ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
+ ph->signal.status = 0;
+ ph->signal.len = 4;
+ ph->signal.data = 0; //rssi + noise;
+
+ ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
+ ph->noise.status = 0;
+ ph->noise.len = 4;
+ ph->noise.data = 0;
+
+#ifdef DOT11_N_SUPPORT
+ if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
+ {
+ rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
+ rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
+ else
+ rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
+ if (rate_index < 0)
+ rate_index = 0;
+ if (rate_index > 255)
+ rate_index = 255;
+
+ ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
+ ph->rate.status = 0;
+ ph->rate.len = 4;
+ ph->rate.data = ralinkrate[rate_index];
+
+ ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
+ ph->frmlen.status = 0;
+ ph->frmlen.len = 4;
+ ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
+
+
+ pOSPkt->pkt_type = PACKET_OTHERHOST;
+ pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
+ pOSPkt->ip_summed = CHECKSUM_NONE;
+ netif_rx(pOSPkt);
+
+ return;
+
+err_free_sk_buff:
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
+{
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
+
+ allow_signal(SIGTERM);
+ allow_signal(SIGKILL);
+ current->flags |= PF_NOFREEZE;
+#else
+ unsigned long flags;
+
+ daemonize();
+ reparent_to_init();
+ strcpy(current->comm, pThreadName);
+
+ siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
+
+ /* Allow interception of SIGKILL only
+ * Don't allow other signals to interrupt the transmission */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
+ spin_lock_irqsave(&current->sigmask_lock, flags);
+ flush_signals(current);
+ recalc_sigpending(current);
+ spin_unlock_irqrestore(&current->sigmask_lock, flags);
+#endif
+#endif
+
+ /* signal that we've started the thread */
+ complete(pNotify);
+
+}
+
+void RTMP_IndicateMediaState(
+ IN PRTMP_ADAPTER pAd)
+{
+ if (pAd->CommonCfg.bWirelessEvent)
+ {
+ if (pAd->IndicateMediaState == NdisMediaStateConnected)
+ {
+ RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+ else
+ {
+ RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+ }
+}
+
diff --git a/drivers/staging/rt3070/rt_linux.h b/drivers/staging/rt3070/rt_linux.h
new file mode 100644
index 00000000000..0540d02da79
--- /dev/null
+++ b/drivers/staging/rt3070/rt_linux.h
@@ -0,0 +1,887 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+/***********************************************************************/
+/* */
+/* Program: rt_linux.c */
+/* Created: 4/21/2006 1:17:38 PM */
+/* Author: Wu Xi-Kun */
+/* Comments: `description` */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* History: */
+/* Revision 1.1 4/21/2006 1:17:38 PM xsikun */
+/* Initial revision */
+/* */
+/***********************************************************************/
+
+#include "rtmp_type.h"
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/wireless.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/if_arp.h>
+#include <linux/ctype.h>
+#include <linux/vmalloc.h>
+
+
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+
+// load firmware
+#define __KERNEL_SYSCALLS__
+#include <linux/unistd.h>
+#include <asm/uaccess.h>
+
+
+#define MEM_ALLOC_FLAG (GFP_ATOMIC) //(GFP_DMA | GFP_ATOMIC)
+
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+
+//#define CONFIG_CKIP_SUPPORT
+
+#undef __inline
+#define __inline static inline
+
+typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_dev);
+
+// add by kathy
+
+#ifdef CONFIG_STA_SUPPORT
+
+#ifdef RT2870
+#define STA_PROFILE_PATH "/etc/Wireless/RT2870STA/RT2870STA.dat"
+#define STA_RT2870_IMAGE_FILE_NAME "/etc/Wireless/RT2870STA/rt2870.bin"
+#define STA_NIC_DEVICE_NAME "RT2870STA"
+#define STA_DRIVER_VERSION "2.0.1.0"
+#ifdef MULTIPLE_CARD_SUPPORT
+#define CARD_INFO_PATH "/etc/Wireless/RT2870STA/RT2870STACard.dat"
+#endif // MULTIPLE_CARD_SUPPORT //
+#endif // RT2870 //
+
+#endif // CONFIG_STA_SUPPORT //
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+
+#define RTMP_TIME_AFTER(a,b) \
+ (typecheck(unsigned long, (unsigned long)a) && \
+ typecheck(unsigned long, (unsigned long)b) && \
+ ((long)(b) - (long)(a) < 0))
+
+#define RTMP_TIME_AFTER_EQ(a,b) \
+ (typecheck(unsigned long, (unsigned long)a) && \
+ typecheck(unsigned long, (unsigned long)b) && \
+ ((long)(a) - (long)(b) >= 0))
+#define RTMP_TIME_BEFORE(a,b) RTMP_TIME_AFTER_EQ(b,a)
+#else
+#define RTMP_TIME_AFTER(a,b) time_after(a, b)
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define RT_MOD_INC_USE_COUNT() \
+ if (!try_module_get(THIS_MODULE)) \
+ { \
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot reserve module\n", __FUNCTION__)); \
+ return -1; \
+ }
+
+#define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE);
+#else
+#define RT_MOD_INC_USE_COUNT() MOD_INC_USE_COUNT;
+#define RT_MOD_DEC_USE_COUNT() MOD_DEC_USE_COUNT;
+#endif
+
+#define OS_HZ HZ
+
+#define ETH_LENGTH_OF_ADDRESS 6
+
+#define IN
+#define OUT
+
+#define NDIS_STATUS INT
+#define NDIS_STATUS_SUCCESS 0x00
+#define NDIS_STATUS_FAILURE 0x01
+#define NDIS_STATUS_INVALID_DATA 0x02
+#define NDIS_STATUS_RESOURCES 0x03
+
+#define MIN_NET_DEVICE_FOR_AID 0x00 //0x00~0x3f
+#define MIN_NET_DEVICE_FOR_MBSSID 0x00 //0x00,0x10,0x20,0x30
+#define MIN_NET_DEVICE_FOR_WDS 0x10 //0x40,0x50,0x60,0x70
+#define MIN_NET_DEVICE_FOR_APCLI 0x20
+#define MIN_NET_DEVICE_FOR_MESH 0x30
+#ifdef CONFIG_STA_SUPPORT
+#define MIN_NET_DEVICE_FOR_DLS 0x40
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef CONFIG_STA_SUPPORT
+#define NDIS_PACKET_TYPE_DIRECTED 0
+#define NDIS_PACKET_TYPE_MULTICAST 1
+#define NDIS_PACKET_TYPE_BROADCAST 2
+#define NDIS_PACKET_TYPE_ALL_MULTICAST 3
+#endif // CONFIG_STA_SUPPORT //
+
+struct os_lock {
+ spinlock_t lock;
+ unsigned long flags;
+};
+
+
+struct os_cookie {
+
+#ifdef RT2870
+ struct usb_device *pUsb_Dev;
+
+ struct pid * MLMEThr_pid;
+ struct pid * RTUSBCmdThr_pid;
+ struct pid * TimerQThr_pid;
+#endif // RT2870 //
+
+ struct tasklet_struct rx_done_task;
+ struct tasklet_struct mgmt_dma_done_task;
+ struct tasklet_struct ac0_dma_done_task;
+ struct tasklet_struct ac1_dma_done_task;
+ struct tasklet_struct ac2_dma_done_task;
+ struct tasklet_struct ac3_dma_done_task;
+ struct tasklet_struct hcca_dma_done_task;
+ struct tasklet_struct tbtt_task;
+#ifdef RT2870
+ struct tasklet_struct null_frame_complete_task;
+ struct tasklet_struct rts_frame_complete_task;
+ struct tasklet_struct pspoll_frame_complete_task;
+#endif // RT2870 //
+
+
+ unsigned long apd_pid; //802.1x daemon pid
+ INT ioctl_if_type;
+ INT ioctl_if;
+};
+
+typedef struct _VIRTUAL_ADAPTER
+{
+ struct net_device *RtmpDev;
+ struct net_device *VirtualDev;
+} VIRTUAL_ADAPTER, PVIRTUAL_ADAPTER;
+
+#undef ASSERT
+#define ASSERT(x) \
+{ \
+ if (!(x)) \
+ { \
+ printk(KERN_WARNING __FILE__ ":%d assert " #x "failed\n", __LINE__); \
+ } \
+}
+
+typedef struct os_cookie * POS_COOKIE;
+typedef struct pci_dev * PPCI_DEV;
+typedef struct net_device * PNET_DEV;
+typedef void * PNDIS_PACKET;
+typedef char NDIS_PACKET;
+typedef PNDIS_PACKET * PPNDIS_PACKET;
+typedef dma_addr_t NDIS_PHYSICAL_ADDRESS;
+typedef dma_addr_t * PNDIS_PHYSICAL_ADDRESS;
+//typedef struct timer_list RALINK_TIMER_STRUCT;
+//typedef struct timer_list * PRALINK_TIMER_STRUCT;
+//typedef struct os_lock NDIS_SPIN_LOCK;
+typedef spinlock_t NDIS_SPIN_LOCK;
+typedef struct timer_list NDIS_MINIPORT_TIMER;
+typedef void * NDIS_HANDLE;
+typedef char * PNDIS_BUFFER;
+
+
+
+void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen);
+
+dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction);
+void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction);
+
+
+////////////////////////////////////////
+// MOVE TO rtmp.h ?
+/////////////////////////////////////////
+#define PKTSRC_NDIS 0x7f
+#define PKTSRC_DRIVER 0x0f
+#define PRINT_MAC(addr) \
+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
+
+
+#define RT2860_PCI_DEVICE_ID 0x0601
+
+#ifdef RT2870
+#define PCI_MAP_SINGLE(_handle, _ptr, _size, _dir) (ULONG)0
+
+#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir)
+#endif // RT2870 //
+
+
+#define BEACON_FRAME_DMA_CACHE_WBACK(_ptr, _size) \
+ dma_cache_wback(_ptr, _size)
+
+
+//////////////////////////////////////////
+//
+//////////////////////////////////////////
+
+
+#define NdisMIndicateStatus(_w, _x, _y, _z)
+
+
+typedef struct timer_list RTMP_OS_TIMER;
+
+#ifdef RT2870
+/* ----------------- Timer Related MARCO ---------------*/
+// In RT2870, we have a lot of timer functions and will read/write register, it's
+// not allowed in Linux USB sub-system to do it ( because of sleep issue when submit
+// to ctrl pipe). So we need a wrapper function to take care it.
+
+typedef VOID (*RT2870_TIMER_HANDLE)(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+#endif // RT2870 //
+
+
+typedef struct _RALINK_TIMER_STRUCT {
+ RTMP_OS_TIMER TimerObj; // Ndis Timer object
+ BOOLEAN Valid; // Set to True when call RTMPInitTimer
+ BOOLEAN State; // True if timer cancelled
+ BOOLEAN PeriodicType; // True if timer is periodic timer
+ BOOLEAN Repeat; // True if periodic timer
+ ULONG TimerValue; // Timer value in milliseconds
+ ULONG cookie; // os specific object
+#ifdef RT2870
+ RT2870_TIMER_HANDLE handle;
+ void *pAd;
+#endif // RT2870 //
+} RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT;
+
+
+#ifdef RT2870
+
+typedef enum _RT2870_KERNEL_THREAD_STATUS_
+{
+ RT2870_THREAD_UNKNOWN = 0,
+ RT2870_THREAD_INITED = 1,
+ RT2870_THREAD_RUNNING = 2,
+ RT2870_THREAD_STOPED = 4,
+}RT2870_KERNEL_THREAD_STATUS;
+
+#define RT2870_THREAD_CAN_DO_INSERT (RT2870_THREAD_INITED |RT2870_THREAD_RUNNING)
+
+typedef struct _RT2870_TIMER_ENTRY_
+{
+ RALINK_TIMER_STRUCT *pRaTimer;
+ struct _RT2870_TIMER_ENTRY_ *pNext;
+}RT2870_TIMER_ENTRY;
+
+
+#define TIMER_QUEUE_SIZE_MAX 128
+typedef struct _RT2870_TIMER_QUEUE_
+{
+ unsigned int status;
+ //wait_queue_head_t timerWaitQ;
+ //atomic_t count;
+ UCHAR *pTimerQPoll;
+ RT2870_TIMER_ENTRY *pQPollFreeList;
+ RT2870_TIMER_ENTRY *pQHead;
+ RT2870_TIMER_ENTRY *pQTail;
+}RT2870_TIMER_QUEUE;
+#endif // RT2870 //
+
+
+//#define DBG 1
+
+//
+// MACRO for debugging information
+//
+
+#ifdef DBG
+extern ULONG RTDebugLevel;
+
+#define DBGPRINT_RAW(Level, Fmt) \
+{ \
+ if (Level <= RTDebugLevel) \
+ { \
+ printk Fmt; \
+ } \
+}
+
+#define DBGPRINT(Level, Fmt) DBGPRINT_RAW(Level, Fmt)
+
+
+#define DBGPRINT_ERR(Fmt) \
+{ \
+ printk("ERROR!!! "); \
+ printk Fmt; \
+}
+
+#define DBGPRINT_S(Status, Fmt) \
+{ \
+ printk Fmt; \
+}
+
+
+#else
+#define DBGPRINT(Level, Fmt)
+#define DBGPRINT_RAW(Level, Fmt)
+#define DBGPRINT_S(Status, Fmt)
+#define DBGPRINT_ERR(Fmt)
+#endif
+
+
+//
+// spin_lock enhanced for Nested spin lock
+//
+#define NdisAllocateSpinLock(__lock) \
+{ \
+ spin_lock_init((spinlock_t *)(__lock)); \
+}
+
+#define NdisFreeSpinLock(lock) \
+{ \
+}
+
+
+#define RTMP_SEM_LOCK(__lock) \
+{ \
+ spin_lock_bh((spinlock_t *)(__lock)); \
+}
+
+#define RTMP_SEM_UNLOCK(__lock) \
+{ \
+ spin_unlock_bh((spinlock_t *)(__lock)); \
+}
+
+// sample, use semaphore lock to replace IRQ lock, 2007/11/15
+#define RTMP_IRQ_LOCK(__lock, __irqflags) \
+{ \
+ __irqflags = 0; \
+ spin_lock_bh((spinlock_t *)(__lock)); \
+ pAd->irq_disabled |= 1; \
+}
+
+#define RTMP_IRQ_UNLOCK(__lock, __irqflag) \
+{ \
+ pAd->irq_disabled &= 0; \
+ spin_unlock_bh((spinlock_t *)(__lock)); \
+}
+
+#define RTMP_INT_LOCK(__lock, __irqflags) \
+{ \
+ spin_lock_irqsave((spinlock_t *)__lock, __irqflags); \
+}
+
+#define RTMP_INT_UNLOCK(__lock, __irqflag) \
+{ \
+ spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag)); \
+}
+
+#ifdef RT2870
+#define RTMP_IO_READ32(_A, _R, _pV) \
+ RTUSBReadMACRegister(_A, _R, _pV)
+
+#define RTMP_IO_READ8(_A, _R, _pV) \
+{ \
+}
+
+#define RTMP_IO_WRITE32(_A, _R, _V) \
+ RTUSBWriteMACRegister(_A, _R, _V)
+
+
+#define RTMP_IO_WRITE8(_A, _R, _V) \
+{ \
+ USHORT _Val = _V; \
+ RTUSBSingleWrite(_A, _R, _Val); \
+}
+
+
+#define RTMP_IO_WRITE16(_A, _R, _V) \
+{ \
+ RTUSBSingleWrite(_A, _R, _V); \
+}
+#endif // RT2870 //
+
+#ifndef wait_event_interruptible_timeout
+#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; \
+ } \
+ current->state = TASK_RUNNING; \
+ remove_wait_queue(&wq, &__wait); \
+} while (0)
+
+#define wait_event_interruptible_timeout(wq, condition, timeout) \
+({ \
+ long __ret = timeout; \
+ if (!(condition)) \
+ __wait_event_interruptible_timeout(wq, condition, __ret); \
+ __ret; \
+})
+#endif
+#define ONE_TICK 1
+#define OS_WAIT(_time) \
+{ int _i; \
+ long _loop = ((_time)/(1000/OS_HZ)) > 0 ? ((_time)/(1000/OS_HZ)) : 1;\
+ wait_queue_head_t _wait; \
+ init_waitqueue_head(&_wait); \
+ for (_i=0; _i<(_loop); _i++) \
+ wait_event_interruptible_timeout(_wait, 0, ONE_TICK); }
+
+
+/* Modified by Wu Xi-Kun 4/21/2006 */
+typedef void (*TIMER_FUNCTION)(unsigned long);
+
+#define COPY_MAC_ADDR(Addr1, Addr2) memcpy((Addr1), (Addr2), MAC_ADDR_LEN)
+
+#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
+#define MlmeFreeMemory(_pAd, _pVA) os_free_mem(_pAd, _pVA)
+
+
+#ifdef RT2870
+#define BUILD_TIMER_FUNCTION(_func) \
+void linux_##_func(unsigned long data) \
+{ \
+ PRALINK_TIMER_STRUCT _pTimer = (PRALINK_TIMER_STRUCT)data; \
+ RT2870_TIMER_ENTRY *_pQNode; \
+ RTMP_ADAPTER *_pAd; \
+ \
+ _pTimer->handle = _func; \
+ _pAd = (RTMP_ADAPTER *)_pTimer->pAd; \
+ _pQNode = RT2870_TimerQ_Insert(_pAd, _pTimer); \
+ if ((_pQNode == NULL) && (_pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)) \
+ RTMP_OS_Add_Timer(&_pTimer->TimerObj, HZ); \
+}
+#endif // RT2870 //
+
+
+#define DECLARE_TIMER_FUNCTION(_func) \
+void linux_##_func(unsigned long data)
+
+#define GET_TIMER_FUNCTION(_func) \
+ linux_##_func
+
+DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
+DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
+DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
+DECLARE_TIMER_FUNCTION(AsicRfTuningExec);
+#ifdef RT2870
+DECLARE_TIMER_FUNCTION(BeaconUpdateExec);
+#endif // RT2870 //
+
+
+#ifdef CONFIG_STA_SUPPORT
+DECLARE_TIMER_FUNCTION(BeaconTimeout);
+DECLARE_TIMER_FUNCTION(ScanTimeout);
+DECLARE_TIMER_FUNCTION(AuthTimeout);
+DECLARE_TIMER_FUNCTION(AssocTimeout);
+DECLARE_TIMER_FUNCTION(ReassocTimeout);
+DECLARE_TIMER_FUNCTION(DisassocTimeout);
+DECLARE_TIMER_FUNCTION(LinkDownExec);
+#ifdef LEAP_SUPPORT
+DECLARE_TIMER_FUNCTION(LeapAuthTimeout);
+#endif
+DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
+DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
+DECLARE_TIMER_FUNCTION(PsPollWakeExec);
+DECLARE_TIMER_FUNCTION(RadioOnExec);
+
+#ifdef QOS_DLS_SUPPORT
+DECLARE_TIMER_FUNCTION(DlsTimeoutAction);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+
+
+
+void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time);
+
+
+/*
+ * packet helper
+ * - convert internal rt packet to os packet or
+ * os packet to rt packet
+ */
+#define RTPKT_TO_OSPKT(_p) ((struct sk_buff *)(_p))
+#define OSPKT_TO_RTPKT(_p) ((PNDIS_PACKET)(_p))
+
+#define GET_OS_PKT_DATAPTR(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->data)
+
+#define GET_OS_PKT_LEN(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->len)
+
+#define GET_OS_PKT_DATATAIL(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->tail)
+
+#define GET_OS_PKT_HEAD(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->head)
+
+#define GET_OS_PKT_END(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->end)
+
+#define GET_OS_PKT_NETDEV(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->dev)
+
+#define GET_OS_PKT_TYPE(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt))
+
+#define GET_OS_PKT_NEXT(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->next)
+
+
+#define OS_NTOHS(_Val) \
+ (ntohs(_Val))
+#define OS_HTONS(_Val) \
+ (htons(_Val))
+#define OS_NTOHL(_Val) \
+ (ntohl(_Val))
+#define OS_HTONL(_Val) \
+ (htonl(_Val))
+
+/* statistics counter */
+#define STATS_INC_RX_PACKETS(_pAd, _dev)
+#define STATS_INC_TX_PACKETS(_pAd, _dev)
+
+#define STATS_INC_RX_BYTESS(_pAd, _dev, len)
+#define STATS_INC_TX_BYTESS(_pAd, _dev, len)
+
+#define STATS_INC_RX_ERRORS(_pAd, _dev)
+#define STATS_INC_TX_ERRORS(_pAd, _dev)
+
+#define STATS_INC_RX_DROPPED(_pAd, _dev)
+#define STATS_INC_TX_DROPPED(_pAd, _dev)
+
+
+#define CB_OFF 10
+
+
+// check DDK NDIS_PACKET data structure and find out only MiniportReservedEx[0..7] can be used by our driver without
+// ambiguity. Fields after pPacket->MiniportReservedEx[8] may be used by other wrapper layer thus crashes the driver
+//
+//#define RTMP_GET_PACKET_MR(_p) (RTPKT_TO_OSPKT(_p))
+
+// User Priority
+#define RTMP_SET_PACKET_UP(_p, _prio) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0] = _prio)
+#define RTMP_GET_PACKET_UP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0])
+
+// Fragment #
+#define RTMP_SET_PACKET_FRAGMENTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1] = _num)
+#define RTMP_GET_PACKET_FRAGMENTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1])
+
+// 0x0 ~0x7f: TX to AP's own BSS which has the specified AID. if AID>127, set bit 7 in RTMP_SET_PACKET_EMACTAB too.
+//(this value also as MAC(on-chip WCID) table index)
+// 0x80~0xff: TX to a WDS link. b0~6: WDS index
+#define RTMP_SET_PACKET_WCID(_p, _wdsidx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2] = _wdsidx)
+#define RTMP_GET_PACKET_WCID(_p) ((UCHAR)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2]))
+
+// 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet
+#define RTMP_SET_PACKET_SOURCE(_p, _pktsrc) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3] = _pktsrc)
+#define RTMP_GET_PACKET_SOURCE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3])
+
+// RTS/CTS-to-self protection method
+#define RTMP_SET_PACKET_RTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4] = _num)
+#define RTMP_GET_PACKET_RTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4])
+// see RTMP_S(G)ET_PACKET_EMACTAB
+
+// TX rate index
+#define RTMP_SET_PACKET_TXRATE(_p, _rate) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5] = _rate)
+#define RTMP_GET_PACKET_TXRATE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5])
+
+// From which Interface
+#define RTMP_SET_PACKET_IF(_p, _ifdx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6] = _ifdx)
+#define RTMP_GET_PACKET_IF(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6])
+#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss) RTMP_SET_PACKET_IF((_p), (_bss))
+#define RTMP_SET_PACKET_NET_DEVICE_WDS(_p, _bss) RTMP_SET_PACKET_IF((_p), ((_bss) + MIN_NET_DEVICE_FOR_WDS))
+#define RTMP_SET_PACKET_NET_DEVICE_APCLI(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_APCLI))
+#define RTMP_SET_PACKET_NET_DEVICE_MESH(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_MESH))
+#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p) RTMP_GET_PACKET_IF((_p))
+#define RTMP_GET_PACKET_NET_DEVICE(_p) RTMP_GET_PACKET_IF((_p))
+
+#define RTMP_SET_PACKET_MOREDATA(_p, _morebit) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7] = _morebit)
+#define RTMP_GET_PACKET_MOREDATA(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7])
+
+//#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss) (RTPKT_TO_OSPKT(_p)->cb[8] = _bss)
+//#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p) (RTPKT_TO_OSPKT(_p)->cb[8])
+
+//
+// Sepcific Pakcet Type definition
+//
+#define RTMP_PACKET_SPECIFIC_CB_OFFSET 11
+
+#define RTMP_PACKET_SPECIFIC_DHCP 0x01
+#define RTMP_PACKET_SPECIFIC_EAPOL 0x02
+#define RTMP_PACKET_SPECIFIC_IPV4 0x04
+#define RTMP_PACKET_SPECIFIC_WAI 0x08
+#define RTMP_PACKET_SPECIFIC_VLAN 0x10
+#define RTMP_PACKET_SPECIFIC_LLCSNAP 0x20
+
+//Specific
+#define RTMP_SET_PACKET_SPECIFIC(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg)
+
+//DHCP
+#define RTMP_SET_PACKET_DHCP(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_DHCP); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_DHCP); \
+ }while(0)
+#define RTMP_GET_PACKET_DHCP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_DHCP)
+
+//EAPOL
+#define RTMP_SET_PACKET_EAPOL(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_EAPOL); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_EAPOL); \
+ }while(0)
+#define RTMP_GET_PACKET_EAPOL(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_EAPOL)
+
+//WAI
+#define RTMP_SET_PACKET_WAI(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_WAI); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_WAI); \
+ }while(0)
+#define RTMP_GET_PACKET_WAI(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_WAI)
+
+#define RTMP_GET_PACKET_LOWRATE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & (RTMP_PACKET_SPECIFIC_EAPOL | RTMP_PACKET_SPECIFIC_DHCP | RTMP_PACKET_SPECIFIC_WAI))
+
+//VLAN
+#define RTMP_SET_PACKET_VLAN(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_VLAN); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_VLAN); \
+ }while(0)
+#define RTMP_GET_PACKET_VLAN(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_VLAN)
+
+//LLC/SNAP
+#define RTMP_SET_PACKET_LLCSNAP(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_LLCSNAP); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_LLCSNAP); \
+ }while(0)
+
+#define RTMP_GET_PACKET_LLCSNAP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_LLCSNAP)
+
+// IP
+#define RTMP_SET_PACKET_IPV4(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_IPV4); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_IPV4); \
+ }while(0)
+
+#define RTMP_GET_PACKET_IPV4(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_IPV4)
+
+// If this flag is set, it indicates that this EAPoL frame MUST be clear.
+#define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12] = _flg)
+#define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12])
+
+#define RTMP_SET_PACKET_5VT(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg)
+#define RTMP_GET_PACKET_5VT(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22])
+
+
+#ifdef INF_AMAZON_SE
+/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
+#define RTMP_SET_PACKET_NOBULKOUT(_p, _morebit) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+23] = _morebit)
+#define RTMP_GET_PACKET_NOBULKOUT(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+23])
+#endif // INF_AMAZON_SE //
+
+
+
+#ifdef CONFIG_5VT_ENHANCE
+#define BRIDGE_TAG 0x35564252 // depends on 5VT define in br_input.c
+#endif
+
+
+#define NDIS_SET_PACKET_STATUS(_p, _status)
+
+
+#define GET_SG_LIST_FROM_PACKET(_p, _sc) \
+ rt_get_sg_list_from_packet(_p, _sc)
+
+#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)
+#define NdisZeroMemory(Destination, Length) memset(Destination, 0, Length)
+#define NdisFillMemory(Destination, Length, Fill) memset(Destination, Fill, Length)
+#define NdisEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length))
+#define RTMPEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length))
+
+
+#define RTMP_INC_REF(_A) 0
+#define RTMP_DEC_REF(_A) 0
+#define RTMP_GET_REF(_A) 0
+
+
+
+/*
+ * ULONG
+ * RTMP_GetPhysicalAddressLow(
+ * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);
+ */
+#define RTMP_GetPhysicalAddressLow(PhysicalAddress) (PhysicalAddress)
+
+/*
+ * ULONG
+ * RTMP_GetPhysicalAddressHigh(
+ * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);
+ */
+#define RTMP_GetPhysicalAddressHigh(PhysicalAddress) (0)
+
+/*
+ * VOID
+ * RTMP_SetPhysicalAddressLow(
+ * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
+ * IN ULONG Value);
+ */
+#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value) \
+ PhysicalAddress = Value;
+
+/*
+ * VOID
+ * RTMP_SetPhysicalAddressHigh(
+ * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
+ * IN ULONG Value);
+ */
+#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value)
+
+
+//CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
+#define QUEUE_ENTRY_TO_PACKET(pEntry) \
+ (PNDIS_PACKET)(pEntry)
+
+#define PACKET_TO_QUEUE_ENTRY(pPacket) \
+ (PQUEUE_ENTRY)(pPacket)
+
+
+#ifndef CONTAINING_RECORD
+#define CONTAINING_RECORD(address, type, field) \
+((type *)((PCHAR)(address) - offsetof(type, field)))
+#endif
+
+
+#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status) \
+{ \
+ RTMPFreeNdisPacket(_pAd, _pPacket); \
+}
+
+
+#define SWITCH_PhyAB(_pAA, _pBB) \
+{ \
+ ULONG AABasePaHigh; \
+ ULONG AABasePaLow; \
+ ULONG BBBasePaHigh; \
+ ULONG BBBasePaLow; \
+ BBBasePaHigh = RTMP_GetPhysicalAddressHigh(_pBB); \
+ BBBasePaLow = RTMP_GetPhysicalAddressLow(_pBB); \
+ AABasePaHigh = RTMP_GetPhysicalAddressHigh(_pAA); \
+ AABasePaLow = RTMP_GetPhysicalAddressLow(_pAA); \
+ RTMP_SetPhysicalAddressHigh(_pAA, BBBasePaHigh); \
+ RTMP_SetPhysicalAddressLow(_pAA, BBBasePaLow); \
+ RTMP_SetPhysicalAddressHigh(_pBB, AABasePaHigh); \
+ RTMP_SetPhysicalAddressLow(_pBB, AABasePaLow); \
+}
+
+
+#define NdisWriteErrorLogEntry(_a, _b, _c, _d)
+#define NdisMAllocateMapRegisters(_a, _b, _c, _d, _e) NDIS_STATUS_SUCCESS
+
+
+#define NdisAcquireSpinLock RTMP_SEM_LOCK
+#define NdisReleaseSpinLock RTMP_SEM_UNLOCK
+
+static inline void NdisGetSystemUpTime(ULONG *time)
+{
+ *time = jiffies;
+}
+
+//pPacket = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
+#define QUEUE_ENTRY_TO_PKT(pEntry) \
+ ((PNDIS_PACKET) (pEntry))
+
+int rt28xx_packet_xmit(struct sk_buff *skb);
+
+
+
+void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify);
+
+
+
diff --git a/drivers/staging/rt3070/rt_main_dev.c b/drivers/staging/rt3070/rt_main_dev.c
new file mode 100644
index 00000000000..c000646286e
--- /dev/null
+++ b/drivers/staging/rt3070/rt_main_dev.c
@@ -0,0 +1,1800 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rt_main_dev.c
+
+ Abstract:
+ Create and register network interface.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Sample Mar/21/07 Merge RT2870 and RT2860 drivers.
+*/
+
+#include "rt_config.h"
+
+#define FORTY_MHZ_INTOLERANT_INTERVAL (60*1000) // 1 min
+
+#ifdef MULTIPLE_CARD_SUPPORT
+// record whether the card in the card list is used in the card file
+UINT8 MC_CardUsed[MAX_NUM_OF_MULTIPLE_CARD];
+// record used card mac address in the card list
+static UINT8 MC_CardMac[MAX_NUM_OF_MULTIPLE_CARD][6];
+#endif // MULTIPLE_CARD_SUPPORT //
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+UINT32 CW_MAX_IN_BITS;
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+/*---------------------------------------------------------------------*/
+/* Private Variables Used */
+/*---------------------------------------------------------------------*/
+//static RALINK_TIMER_STRUCT PeriodicTimer;
+
+char *mac = ""; // default 00:00:00:00:00:00
+char *hostname = ""; // default CMPC
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
+MODULE_PARM (mac, "s");
+#else
+module_param (mac, charp, 0);
+#endif
+MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
+
+
+/*---------------------------------------------------------------------*/
+/* Prototypes of Functions Used */
+/*---------------------------------------------------------------------*/
+#ifdef DOT11_N_SUPPORT
+extern BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
+extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
+#endif // DOT11_N_SUPPORT //
+extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd);
+
+
+// public function prototype
+INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
+ IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
+
+// private function prototype
+static int rt28xx_init(IN struct net_device *net_dev);
+INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
+
+#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
+struct net_device *alloc_netdev(
+ int sizeof_priv,
+ const char *mask,
+ void (*setup)(struct net_device *));
+#endif // LINUX_VERSION_CODE //
+
+static void CfgInitHook(PRTMP_ADAPTER pAd);
+//static BOOLEAN RT28XXAvailRANameAssign(IN CHAR *name_p);
+
+#ifdef CONFIG_STA_SUPPORT
+extern const struct iw_handler_def rt28xx_iw_handler_def;
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+extern const struct iw_handler_def rt28xx_ap_iw_handler_def;
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+#if WIRELESS_EXT >= 12
+// This function will be called when query /proc
+struct iw_statistics *rt28xx_get_wireless_stats(
+ IN struct net_device *net_dev);
+#endif
+
+struct net_device_stats *RT28xx_get_ether_stats(
+ IN struct net_device *net_dev);
+
+/*
+========================================================================
+Routine Description:
+ Close raxx interface.
+
+Arguments:
+ *net_dev the raxx interface pointer
+
+Return Value:
+ 0 Open OK
+ otherwise Open Fail
+
+Note:
+ 1. if open fail, kernel will not call the close function.
+ 2. Free memory for
+ (1) Mlme Memory Handler: MlmeHalt()
+ (2) TX & RX: RTMPFreeTxRxRingMemory()
+ (3) BA Reordering: ba_reordering_resource_release()
+========================================================================
+*/
+int MainVirtualIF_close(IN struct net_device *net_dev)
+{
+ RTMP_ADAPTER *pAd = net_dev->ml_priv;
+
+ // Sanity check for pAd
+ if (pAd == NULL)
+ return 0; // close ok
+
+ netif_carrier_off(pAd->net_dev);
+ netif_stop_queue(pAd->net_dev);
+
+
+
+ VIRTUAL_IF_DOWN(pAd);
+
+ RT_MOD_DEC_USE_COUNT();
+
+ return 0; // close ok
+}
+
+/*
+========================================================================
+Routine Description:
+ Open raxx interface.
+
+Arguments:
+ *net_dev the raxx interface pointer
+
+Return Value:
+ 0 Open OK
+ otherwise Open Fail
+
+Note:
+ 1. if open fail, kernel will not call the close function.
+ 2. Free memory for
+ (1) Mlme Memory Handler: MlmeHalt()
+ (2) TX & RX: RTMPFreeTxRxRingMemory()
+ (3) BA Reordering: ba_reordering_resource_release()
+========================================================================
+*/
+int MainVirtualIF_open(IN struct net_device *net_dev)
+{
+ RTMP_ADAPTER *pAd = net_dev->ml_priv;
+
+ // Sanity check for pAd
+ if (pAd == NULL)
+ return 0; // close ok
+
+ if (VIRTUAL_IF_UP(pAd) != 0)
+ return -1;
+
+ // increase MODULE use count
+ RT_MOD_INC_USE_COUNT();
+
+ netif_start_queue(net_dev);
+ netif_carrier_on(net_dev);
+ netif_wake_queue(net_dev);
+
+ return 0;
+}
+
+/*
+========================================================================
+Routine Description:
+ Close raxx interface.
+
+Arguments:
+ *net_dev the raxx interface pointer
+
+Return Value:
+ 0 Open OK
+ otherwise Open Fail
+
+Note:
+ 1. if open fail, kernel will not call the close function.
+ 2. Free memory for
+ (1) Mlme Memory Handler: MlmeHalt()
+ (2) TX & RX: RTMPFreeTxRxRingMemory()
+ (3) BA Reordering: ba_reordering_resource_release()
+========================================================================
+*/
+int rt28xx_close(IN PNET_DEV dev)
+{
+ struct net_device * net_dev = (struct net_device *)dev;
+ RTMP_ADAPTER *pAd = net_dev->ml_priv;
+ BOOLEAN Cancelled = FALSE;
+ UINT32 i = 0;
+#ifdef RT2870
+ DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
+ DECLARE_WAITQUEUE(wait, current);
+
+ //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
+#endif // RT2870 //
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
+
+ // Sanity check for pAd
+ if (pAd == NULL)
+ return 0; // close ok
+
+
+#ifdef WDS_SUPPORT
+ WdsDown(pAd);
+#endif // WDS_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+
+ // If dirver doesn't wake up firmware here,
+ // NICLoadFirmware will hang forever when interface is up again.
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ {
+ AsicForceWakeup(pAd, TRUE);
+ }
+
+#ifdef QOS_DLS_SUPPORT
+ // send DLS-TEAR_DOWN message,
+ if (pAd->CommonCfg.bDLSCapable)
+ {
+ UCHAR i;
+
+ // tear down local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ }
+ }
+
+ // tear down peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ }
+ }
+ RT28XX_MLME_HANDLER(pAd);
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ if (INFRA_ON(pAd) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ MLME_DISASSOC_REQ_STRUCT DisReq;
+ MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+ COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid);
+ DisReq.Reason = REASON_DEAUTH_STA_LEAVING;
+
+ MsgElem->Machine = ASSOC_STATE_MACHINE;
+ MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
+ MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
+ NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
+
+ // Prevent to connect AP again in STAMlmePeriodicExec
+ pAd->MlmeAux.AutoReconnectSsidLen= 32;
+ NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
+ MlmeDisassocReqAction(pAd, MsgElem);
+ kfree(MsgElem);
+
+ RTMPusecDelay(1000);
+ }
+
+#ifdef RT2870
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
+#endif // RT2870 //
+
+#ifdef CCX_SUPPORT
+ RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &Cancelled);
+#endif
+
+ RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ // send wireless event to wpa_supplicant for infroming interface down.
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_INTERFACE_DOWN;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ MlmeRadioOff(pAd);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+
+ for (i = 0 ; i < NUM_OF_TX_RING; i++)
+ {
+ while (pAd->DeQueueRunning[i] == TRUE)
+ {
+ printk("Waiting for TxQueue[%d] done..........\n", i);
+ RTMPusecDelay(1000);
+ }
+ }
+
+#ifdef RT2870
+ // ensure there are no more active urbs.
+ add_wait_queue (&unlink_wakeup, &wait);
+ pAd->wait = &unlink_wakeup;
+
+ // maybe wait for deletions to finish.
+ i = 0;
+ //while((i < 25) && atomic_read(&pAd->PendingRx) > 0)
+ while(i < 25)
+ {
+ unsigned long IrqFlags;
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ if (pAd->PendingRx == 0)
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ break;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
+ msleep(UNLINK_TIMEOUT_MS); //Time in millisecond
+#else
+ RTMPusecDelay(UNLINK_TIMEOUT_MS*1000); //Time in microsecond
+#endif
+ i++;
+ }
+ pAd->wait = NULL;
+ remove_wait_queue (&unlink_wakeup, &wait);
+#endif // RT2870 //
+
+ //RTUSBCleanUpMLMEWaitQueue(pAd); /*not used in RT28xx*/
+
+
+#ifdef RT2870
+ // We need clear timerQ related structure before exits of the timer thread.
+ RT2870_TimerQ_Exit(pAd);
+ // Close kernel threads or tasklets
+ RT28xxThreadTerminate(pAd);
+#endif // RT2870 //
+
+ // Stop Mlme state machine
+ MlmeHalt(pAd);
+
+ // Close kernel threads or tasklets
+ kill_thread_task(pAd);
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ MacTableReset(pAd);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+ MeasureReqTabExit(pAd);
+ TpcReqTabExit(pAd);
+
+
+
+
+ // Free Ring or USB buffers
+ RTMPFreeTxRxRingMemory(pAd);
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+
+#ifdef DOT11_N_SUPPORT
+ // Free BA reorder resource
+ ba_reordering_resource_release(pAd);
+#endif // DOT11_N_SUPPORT //
+
+#ifdef RT2870
+#ifdef INF_AMAZON_SE
+ if (pAd->UsbVendorReqBuf)
+ os_free_mem(pAd, pAd->UsbVendorReqBuf);
+#endif // INF_AMAZON_SE //
+#endif // RT2870 //
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
+
+ return 0; // close ok
+} /* End of rt28xx_close */
+
+static int rt28xx_init(IN struct net_device *net_dev)
+{
+ PRTMP_ADAPTER pAd = net_dev->ml_priv;
+ UINT index;
+ UCHAR TmpPhy;
+// ULONG Value=0;
+ NDIS_STATUS Status;
+// OID_SET_HT_PHYMODE SetHT;
+// WPDMA_GLO_CFG_STRUC GloCfg;
+ UINT32 MacCsr0 = 0;
+ UINT32 MacValue = 0;
+
+#ifdef RT2870
+#ifdef INF_AMAZON_SE
+ init_MUTEX(&(pAd->UsbVendorReq_semaphore));
+ os_alloc_mem(pAd, (PUCHAR)&pAd->UsbVendorReqBuf, MAX_PARAM_BUFFER_SIZE - 1);
+ if (pAd->UsbVendorReqBuf == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Allocate vendor request temp buffer failed!\n"));
+ goto err0;
+ }
+#endif // INF_AMAZON_SE //
+#endif // RT2870 //
+
+#ifdef DOT11_N_SUPPORT
+ // Allocate BA Reordering memory
+ ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
+#endif // DOT11_N_SUPPORT //
+
+ // Make sure MAC gets ready.
+ index = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
+ pAd->MACVersion = MacCsr0;
+
+ if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
+ break;
+
+ RTMPusecDelay(10);
+ } while (index++ < 100);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
+/*Iverson patch PCIE L1 issue */
+
+ // Disable DMA
+ RT28XXDMADisable(pAd);
+
+
+ // Load 8051 firmware
+ Status = NICLoadFirmware(pAd);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
+ goto err1;
+ }
+
+ NICLoadRateSwitchingParams(pAd);
+
+ // Disable interrupts here which is as soon as possible
+ // This statement should never be true. We might consider to remove it later
+
+ Status = RTMPAllocTxRxRingMemory(pAd);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status));
+ goto err1;
+ }
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
+
+ // initialize MLME
+ //
+
+ Status = MlmeInit(pAd);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status));
+ goto err2;
+ }
+
+ // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default
+ //
+ UserCfgInit(pAd);
+
+#ifdef RT2870
+ // We need init timerQ related structure before create the timer thread.
+ RT2870_TimerQ_Init(pAd);
+#endif // RT2870 //
+
+ RT28XX_TASK_THREAD_INIT(pAd, Status);
+ if (Status != NDIS_STATUS_SUCCESS)
+ goto err1;
+
+// COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr);
+// pAd->bForcePrintTX = TRUE;
+
+ CfgInitHook(pAd);
+
+
+#ifdef BLOCK_NET_IF
+ initblockQueueTab(pAd);
+#endif // BLOCK_NET_IF //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ NdisAllocateSpinLock(&pAd->MacTabLock);
+#endif // CONFIG_STA_SUPPORT //
+
+ MeasureReqTabInit(pAd);
+ TpcReqTabInit(pAd);
+
+ //
+ // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset
+ //
+ Status = NICInitializeAdapter(pAd, TRUE);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status));
+ if (Status != NDIS_STATUS_SUCCESS)
+ goto err3;
+ }
+
+ // Read parameters from Config File
+ Status = RTMPReadParametersHook(pAd);
+
+ printk("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status));
+ goto err4;
+ }
+
+#ifdef RT2870
+ pAd->CommonCfg.bMultipleIRP = FALSE;
+
+ if (pAd->CommonCfg.bMultipleIRP)
+ pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE;
+ else
+ pAd->CommonCfg.NumOfBulkInIRP = 1;
+#endif // RT2870 //
+
+
+ //Init Ba Capability parameters.
+// RT28XX_BA_INIT(pAd);
+#ifdef DOT11_N_SUPPORT
+ pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+ pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
+ pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
+ pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
+ // UPdata to HT IE
+ pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
+ pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
+ pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+#endif // DOT11_N_SUPPORT //
+
+ // after reading Registry, we now know if in AP mode or STA mode
+
+ // Load 8051 firmware; crash when FW image not existent
+ // Status = NICLoadFirmware(pAd);
+ // if (Status != NDIS_STATUS_SUCCESS)
+ // break;
+
+ printk("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
+
+ // We should read EEPROM for all cases. rt2860b
+ NICReadEEPROMParameters(pAd, mac);
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ printk("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
+
+ NICInitAsicFromEEPROM(pAd); //rt2860b
+
+ // Set PHY to appropriate mode
+ TmpPhy = pAd->CommonCfg.PhyMode;
+ pAd->CommonCfg.PhyMode = 0xff;
+ RTMPSetPhyMode(pAd, TmpPhy);
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+
+ // No valid channels.
+ if (pAd->ChannelListNum == 0)
+ {
+ printk("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n");
+ goto err4;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ printk("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0],
+ pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2],
+ pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]);
+#endif // DOT11_N_SUPPORT //
+
+#ifdef RT30xx
+ //Init RT30xx RFRegisters after read RFIC type from EEPROM
+ NICInitRT30xxRFRegisters(pAd);
+#endif // RT30xx //
+
+// APInitialize(pAd);
+
+#ifdef IKANOS_VX_1X0
+ VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress);
+#endif // IKANOS_VX_1X0 //
+
+ //
+ // Initialize RF register to default value
+ //
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+ if (pAd && (Status != NDIS_STATUS_SUCCESS))
+ {
+ //
+ // Undo everything if it failed
+ //
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+// NdisMDeregisterInterrupt(&pAd->Interrupt);
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
+ }
+// RTMPFreeAdapter(pAd); // we will free it in disconnect()
+ }
+ else if (pAd)
+ {
+ // Microsoft HCT require driver send a disconnect event after driver initialization.
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+// pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
+
+
+#ifdef RT2870
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
+
+ //
+ // Support multiple BulkIn IRP,
+ // the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.
+ //
+ for(index=0; index<pAd->CommonCfg.NumOfBulkInIRP; index++)
+ {
+ RTUSBBulkReceive(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
+ }
+#endif // RT2870 //
+ }// end of else
+
+
+ DBGPRINT_S(Status, ("<==== RTMPInitialize, Status=%x\n", Status));
+
+ return TRUE;
+
+
+err4:
+err3:
+ MlmeHalt(pAd);
+err2:
+ RTMPFreeTxRxRingMemory(pAd);
+// RTMPFreeAdapter(pAd);
+err1:
+
+#ifdef DOT11_N_SUPPORT
+ os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool
+#endif // DOT11_N_SUPPORT //
+ RT28XX_IRQ_RELEASE(net_dev);
+
+ // shall not set priv to NULL here because the priv didn't been free yet.
+ //net_dev->ml_priv = 0;
+#ifdef INF_AMAZON_SE
+err0:
+#endif // INF_AMAZON_SE //
+ printk("!!! %s Initialized fail !!!\n", RT28xx_CHIP_NAME);
+ return FALSE;
+} /* End of rt28xx_init */
+
+
+/*
+========================================================================
+Routine Description:
+ Open raxx interface.
+
+Arguments:
+ *net_dev the raxx interface pointer
+
+Return Value:
+ 0 Open OK
+ otherwise Open Fail
+
+Note:
+========================================================================
+*/
+int rt28xx_open(IN PNET_DEV dev)
+{
+ struct net_device * net_dev = (struct net_device *)dev;
+ PRTMP_ADAPTER pAd = net_dev->ml_priv;
+ int retval = 0;
+ POS_COOKIE pObj;
+
+
+ // Sanity check for pAd
+ if (pAd == NULL)
+ {
+ /* if 1st open fail, pAd will be free;
+ So the net_dev->ml_priv will be NULL in 2rd open */
+ return -1;
+ }
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ CW_MAX_IN_BITS = 6;
+ }
+ else if (pAd->OpMode == OPMODE_STA)
+ {
+ CW_MAX_IN_BITS = 10;
+ }
+
+#if WIRELESS_EXT >= 12
+ if (net_dev->ml_priv_flags == INT_MAIN)
+ {
+ if (pAd->OpMode == OPMODE_AP)
+ net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def;
+ else if (pAd->OpMode == OPMODE_STA)
+ net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def;
+ }
+#endif // WIRELESS_EXT >= 12 //
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ // Init
+ pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+ // reset Adapter flags
+ RTMP_CLEAR_FLAGS(pAd);
+
+ // Request interrupt service routine for PCI device
+ // register the interrupt routine with the os
+ RT28XX_IRQ_REQUEST(net_dev);
+
+
+ // Init BssTab & ChannelInfo tabbles for auto channel select.
+
+
+ // Chip & other init
+ if (rt28xx_init(net_dev) == FALSE)
+ goto err;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ NdisZeroMemory(pAd->StaCfg.dev_name, 16);
+ NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name));
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Set up the Mac address
+ NdisMoveMemory(net_dev->dev_addr, (void *) pAd->CurrentAddress, 6);
+
+ // Init IRQ parameters
+ RT28XX_IRQ_INIT(pAd);
+
+ // Various AP function init
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ // send wireless event to wpa_supplicant for infroming interface down.
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_INTERFACE_UP;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Enable Interrupt
+ RT28XX_IRQ_ENABLE(pAd);
+
+ // Now Enable RxTx
+ RTMPEnableRxTx(pAd);
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
+
+ {
+ UINT32 reg = 0;
+ RTMP_IO_READ32(pAd, 0x1300, &reg); // clear garbage interrupts
+ printk("0x1300 = %08x\n", reg);
+ }
+
+ {
+// u32 reg;
+// u8 byte;
+// u16 tmp;
+
+// RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg);
+
+// tmp = 0x0805;
+// reg = (reg & 0xffff0000) | tmp;
+// RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg);
+
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ return (retval);
+
+err:
+ return (-1);
+} /* End of rt28xx_open */
+
+
+/* Must not be called for mdev and apdev */
+static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd)
+{
+ NDIS_STATUS Status;
+ INT i=0;
+ CHAR slot_name[IFNAMSIZ];
+ struct net_device *device;
+
+
+ //ether_setup(dev);
+ dev->hard_start_xmit = rt28xx_send_packets;
+
+#ifdef IKANOS_VX_1X0
+ dev->hard_start_xmit = IKANOS_DataFramesTx;
+#endif // IKANOS_VX_1X0 //
+
+// dev->set_multicast_list = ieee80211_set_multicast_list;
+// dev->change_mtu = ieee80211_change_mtu;
+#ifdef CONFIG_STA_SUPPORT
+#if WIRELESS_EXT >= 12
+ if (pAd->OpMode == OPMODE_STA)
+ {
+ dev->wireless_handlers = &rt28xx_iw_handler_def;
+ }
+#endif //WIRELESS_EXT >= 12
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+#if WIRELESS_EXT >= 12
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ dev->wireless_handlers = &rt28xx_ap_iw_handler_def;
+ }
+#endif //WIRELESS_EXT >= 12
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+#if WIRELESS_EXT < 21
+ dev->get_wireless_stats = rt28xx_get_wireless_stats;
+#endif
+ dev->get_stats = RT28xx_get_ether_stats;
+ dev->open = MainVirtualIF_open; //rt28xx_open;
+ dev->stop = MainVirtualIF_close; //rt28xx_close;
+// dev->uninit = ieee80211_if_reinit;
+// dev->destructor = ieee80211_if_free;
+ dev->priv_flags = INT_MAIN;
+ dev->do_ioctl = rt28xx_ioctl;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+ dev->validate_addr = NULL;
+#endif
+ // find available device name
+ for (i = 0; i < 8; i++)
+ {
+#ifdef MULTIPLE_CARD_SUPPORT
+ if (pAd->MC_RowID >= 0)
+ sprintf(slot_name, "ra%02d_%d", pAd->MC_RowID, i);
+ else
+#endif // MULTIPLE_CARD_SUPPORT //
+ sprintf(slot_name, "ra%d", i);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+ device = dev_get_by_name(dev_net(dev), slot_name);
+#else
+ device = dev_get_by_name(dev->nd_net, slot_name);
+#endif
+#else
+ device = dev_get_by_name(slot_name);
+#endif
+ if (device != NULL) dev_put(device);
+#else
+ for (device = dev_base; device != NULL; device = device->next)
+ {
+ if (strncmp(device->name, slot_name, 4) == 0)
+ break;
+ }
+#endif
+ if(device == NULL)
+ break;
+ }
+
+ if(i == 8)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("No available slot name\n"));
+ Status = NDIS_STATUS_FAILURE;
+ }
+ else
+ {
+#ifdef MULTIPLE_CARD_SUPPORT
+ if (pAd->MC_RowID >= 0)
+ sprintf(dev->name, "ra%02d_%d", pAd->MC_RowID, i);
+ else
+#endif // MULTIPLE_CARD_SUPPORT //
+ sprintf(dev->name, "ra%d", i);
+ Status = NDIS_STATUS_SUCCESS;
+ }
+
+ return Status;
+
+}
+
+
+#ifdef MULTIPLE_CARD_SUPPORT
+/*
+========================================================================
+Routine Description:
+ Get card profile path.
+
+Arguments:
+ pAd
+
+Return Value:
+ TRUE - Find a card profile
+ FALSE - use default profile
+
+Note:
+========================================================================
+*/
+extern INT RTMPGetKeyParameter(
+ IN PCHAR key,
+ OUT PCHAR dest,
+ IN INT destsize,
+ IN PCHAR buffer);
+
+BOOLEAN RTMP_CardInfoRead(
+ IN PRTMP_ADAPTER pAd)
+{
+#define MC_SELECT_CARDID 0 /* use CARD ID (0 ~ 31) to identify different cards */
+#define MC_SELECT_MAC 1 /* use CARD MAC to identify different cards */
+#define MC_SELECT_CARDTYPE 2 /* use CARD type (abgn or bgn) to identify different cards */
+
+#define LETTER_CASE_TRANSLATE(txt_p, card_id) \
+ { UINT32 _len; char _char; \
+ for(_len=0; _len<strlen(card_id); _len++) { \
+ _char = *(txt_p + _len); \
+ if (('A' <= _char) && (_char <= 'Z')) \
+ *(txt_p+_len) = 'a'+(_char-'A'); \
+ } }
+
+ struct file *srcf;
+ INT retval, orgfsuid, orgfsgid;
+ mm_segment_t orgfs;
+ CHAR *buffer, *tmpbuf, card_id_buf[30], RFIC_word[30];
+ BOOLEAN flg_match_ok = FALSE;
+ INT32 card_select_method;
+ INT32 card_free_id, card_nouse_id, card_same_mac_id, card_match_id;
+ EEPROM_ANTENNA_STRUC antenna;
+ USHORT addr01, addr23, addr45;
+ UINT8 mac[6];
+ UINT32 data, card_index;
+ UCHAR *start_ptr;
+
+
+ // init
+ buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ if (buffer == NULL)
+ return FALSE;
+
+ tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ if(tmpbuf == NULL)
+ {
+ kfree(buffer);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ orgfsuid = current->fsuid;
+ orgfsgid = current->fsgid;
+ current->fsuid = current->fsgid = 0;
+ orgfs = get_fs();
+ set_fs(KERNEL_DS);
+
+ // get RF IC type
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
+
+ if ((data & 0x30) == 0)
+ pAd->EEPROMAddressNum = 6; // 93C46
+ else if ((data & 0x30) == 0x10)
+ pAd->EEPROMAddressNum = 8; // 93C66
+ else
+ pAd->EEPROMAddressNum = 8; // 93C86
+
+ //antenna.word = RTMP_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, antenna.word);
+
+ if ((antenna.field.RfIcType == RFIC_2850) ||
+ (antenna.field.RfIcType == RFIC_2750))
+ {
+ /* ABGN card */
+ strcpy(RFIC_word, "abgn");
+ }
+ else
+ {
+ /* BGN card */
+ strcpy(RFIC_word, "bgn");
+ }
+
+ // get MAC address
+ //addr01 = RTMP_EEPROM_READ16(pAd, 0x04);
+ //addr23 = RTMP_EEPROM_READ16(pAd, 0x06);
+ //addr45 = RTMP_EEPROM_READ16(pAd, 0x08);
+ RT28xx_EEPROM_READ16(pAd, 0x04, addr01);
+ RT28xx_EEPROM_READ16(pAd, 0x06, addr23);
+ RT28xx_EEPROM_READ16(pAd, 0x08, addr45);
+
+ mac[0] = (UCHAR)(addr01 & 0xff);
+ mac[1] = (UCHAR)(addr01 >> 8);
+ mac[2] = (UCHAR)(addr23 & 0xff);
+ mac[3] = (UCHAR)(addr23 >> 8);
+ mac[4] = (UCHAR)(addr45 & 0xff);
+ mac[5] = (UCHAR)(addr45 >> 8);
+
+ // open card information file
+ srcf = filp_open(CARD_INFO_PATH, O_RDONLY, 0);
+ if (IS_ERR(srcf))
+ {
+ /* card information file does not exist */
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("--> Error %ld opening %s\n", -PTR_ERR(srcf), CARD_INFO_PATH));
+ return FALSE;
+ }
+
+ if (srcf->f_op && srcf->f_op->read)
+ {
+ /* card information file exists so reading the card information */
+ memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
+ retval = srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
+ if (retval < 0)
+ {
+ /* read fail */
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("--> Read %s error %d\n", CARD_INFO_PATH, -retval));
+ }
+ else
+ {
+ /* get card selection method */
+ memset(tmpbuf, 0x00, MAX_PARAM_BUFFER_SIZE);
+ card_select_method = MC_SELECT_CARDTYPE; // default
+
+ if (RTMPGetKeyParameter("SELECT", tmpbuf, 256, buffer))
+ {
+ if (strcmp(tmpbuf, "CARDID") == 0)
+ card_select_method = MC_SELECT_CARDID;
+ else if (strcmp(tmpbuf, "MAC") == 0)
+ card_select_method = MC_SELECT_MAC;
+ else if (strcmp(tmpbuf, "CARDTYPE") == 0)
+ card_select_method = MC_SELECT_CARDTYPE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("MC> Card Selection = %d\n", card_select_method));
+
+ // init
+ card_free_id = -1;
+ card_nouse_id = -1;
+ card_same_mac_id = -1;
+ card_match_id = -1;
+
+ // search current card information records
+ for(card_index=0;
+ card_index<MAX_NUM_OF_MULTIPLE_CARD;
+ card_index++)
+ {
+ if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
+ (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
+ {
+ // MAC is all-0 so the entry is available
+ MC_CardUsed[card_index] = 0;
+
+ if (card_free_id < 0)
+ card_free_id = card_index; // 1st free entry
+ }
+ else
+ {
+ if (memcmp(MC_CardMac[card_index], mac, 6) == 0)
+ {
+ // we find the entry with same MAC
+ if (card_same_mac_id < 0)
+ card_same_mac_id = card_index; // 1st same entry
+ }
+ else
+ {
+ // MAC is not all-0 but used flag == 0
+ if ((MC_CardUsed[card_index] == 0) &&
+ (card_nouse_id < 0))
+ {
+ card_nouse_id = card_index; // 1st available entry
+ }
+ }
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("MC> Free = %d, Same = %d, NOUSE = %d\n",
+ card_free_id, card_same_mac_id, card_nouse_id));
+
+ if ((card_same_mac_id >= 0) &&
+ ((card_select_method == MC_SELECT_CARDID) ||
+ (card_select_method == MC_SELECT_CARDTYPE)))
+ {
+ // same MAC entry is found
+ card_match_id = card_same_mac_id;
+
+ if (card_select_method == MC_SELECT_CARDTYPE)
+ {
+ // for CARDTYPE
+ sprintf(card_id_buf, "%02dCARDTYPE%s",
+ card_match_id, RFIC_word);
+
+ if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
+ {
+ // we found the card ID
+ LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
+ }
+ }
+ }
+ else
+ {
+ // the card is 1st plug-in, try to find the match card profile
+ switch(card_select_method)
+ {
+ case MC_SELECT_CARDID: // CARDID
+ default:
+ if (card_free_id >= 0)
+ card_match_id = card_free_id;
+ else
+ card_match_id = card_nouse_id;
+ break;
+
+ case MC_SELECT_MAC: // MAC
+ sprintf(card_id_buf, "MAC%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2],
+ mac[3], mac[4], mac[5]);
+
+ /* try to find the key word in the card file */
+ if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
+ {
+ LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
+
+ /* get the row ID (2 ASCII characters) */
+ start_ptr -= 2;
+ card_id_buf[0] = *(start_ptr);
+ card_id_buf[1] = *(start_ptr+1);
+ card_id_buf[2] = 0x00;
+
+ card_match_id = simple_strtol(card_id_buf, 0, 10);
+ }
+ break;
+
+ case MC_SELECT_CARDTYPE: // CARDTYPE
+ card_nouse_id = -1;
+
+ for(card_index=0;
+ card_index<MAX_NUM_OF_MULTIPLE_CARD;
+ card_index++)
+ {
+ sprintf(card_id_buf, "%02dCARDTYPE%s",
+ card_index, RFIC_word);
+
+ if ((start_ptr=rtstrstruncasecmp(buffer,
+ card_id_buf)) != NULL)
+ {
+ LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
+
+ if (MC_CardUsed[card_index] == 0)
+ {
+ /* current the card profile is not used */
+ if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
+ (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
+ {
+ // find it and no previous card use it
+ card_match_id = card_index;
+ break;
+ }
+ else
+ {
+ // ever a card use it
+ if (card_nouse_id < 0)
+ card_nouse_id = card_index;
+ }
+ }
+ }
+ }
+
+ // if not find a free one, use the available one
+ if (card_match_id < 0)
+ card_match_id = card_nouse_id;
+ break;
+ }
+ }
+
+ if (card_match_id >= 0)
+ {
+ // make up search keyword
+ switch(card_select_method)
+ {
+ case MC_SELECT_CARDID: // CARDID
+ sprintf(card_id_buf, "%02dCARDID", card_match_id);
+ break;
+
+ case MC_SELECT_MAC: // MAC
+ sprintf(card_id_buf,
+ "%02dmac%02x:%02x:%02x:%02x:%02x:%02x",
+ card_match_id,
+ mac[0], mac[1], mac[2],
+ mac[3], mac[4], mac[5]);
+ break;
+
+ case MC_SELECT_CARDTYPE: // CARDTYPE
+ default:
+ sprintf(card_id_buf, "%02dcardtype%s",
+ card_match_id, RFIC_word);
+ break;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Search Keyword = %s\n", card_id_buf));
+
+ // read card file path
+ if (RTMPGetKeyParameter(card_id_buf, tmpbuf, 256, buffer))
+ {
+ if (strlen(tmpbuf) < sizeof(pAd->MC_FileName))
+ {
+ // backup card information
+ pAd->MC_RowID = card_match_id; /* base 0 */
+ MC_CardUsed[card_match_id] = 1;
+ memcpy(MC_CardMac[card_match_id], mac, sizeof(mac));
+
+ // backup card file path
+ NdisMoveMemory(pAd->MC_FileName, tmpbuf , strlen(tmpbuf));
+ pAd->MC_FileName[strlen(tmpbuf)] = '\0';
+ flg_match_ok = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("Card Profile Name = %s\n", pAd->MC_FileName));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("Card Profile Name length too large!\n"));
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("Can not find search key word in card.dat!\n"));
+ }
+
+ if ((flg_match_ok != TRUE) &&
+ (card_match_id < MAX_NUM_OF_MULTIPLE_CARD))
+ {
+ MC_CardUsed[card_match_id] = 0;
+ memset(MC_CardMac[card_match_id], 0, sizeof(mac));
+ }
+ } // if (card_match_id >= 0)
+ }
+ }
+
+ // close file
+ retval = filp_close(srcf, NULL);
+ set_fs(orgfs);
+ current->fsuid = orgfsuid;
+ current->fsgid = orgfsgid;
+ kfree(buffer);
+ kfree(tmpbuf);
+ return flg_match_ok;
+}
+#endif // MULTIPLE_CARD_SUPPORT //
+
+
+/*
+========================================================================
+Routine Description:
+ Probe RT28XX chipset.
+
+Arguments:
+ _dev_p Point to the PCI or USB device
+ _dev_id_p Point to the PCI or USB device ID
+
+Return Value:
+ 0 Probe OK
+ -ENODEV Probe Fail
+
+Note:
+========================================================================
+*/
+INT __devinit rt28xx_probe(
+ IN void *_dev_p,
+ IN void *_dev_id_p,
+ IN UINT argc,
+ OUT PRTMP_ADAPTER *ppAd)
+{
+ struct net_device *net_dev;
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) NULL;
+ INT status;
+ PVOID handle;
+#ifdef RT2870
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ struct usb_device *dev_p = (struct usb_device *)_dev_p;
+#else
+ struct usb_interface *intf = (struct usb_interface *)_dev_p;
+ struct usb_device *dev_p = interface_to_usbdev(intf);
+
+ dev_p = usb_get_dev(dev_p);
+#endif // LINUX_VERSION_CODE //
+#endif // RT2870 //
+
+
+#ifdef CONFIG_STA_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
+#endif // CONFIG_STA_SUPPORT //
+
+ // Check chipset vendor/product ID
+// if (RT28XXChipsetCheck(_dev_p) == FALSE)
+// goto err_out;
+
+#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
+ net_dev = alloc_netdev(sizeof(PRTMP_ADAPTER), "eth%d", ether_setup);
+#else
+ net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER));
+#endif
+ if (net_dev == NULL)
+ {
+ printk("alloc_netdev failed\n");
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ module_put(THIS_MODULE);
+#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+#else
+ MOD_DEC_USE_COUNT;
+#endif
+ goto err_out;
+ }
+
+// sample
+// if (rt_ieee80211_if_setup(net_dev) != NDIS_STATUS_SUCCESS)
+// goto err_out;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ SET_MODULE_OWNER(net_dev);
+#endif
+
+ netif_stop_queue(net_dev);
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+/* for supporting Network Manager */
+/* Set the sysfs physical device reference for the network logical device
+ * if set prior to registration will cause a symlink during initialization.
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ SET_NETDEV_DEV(net_dev, &(dev_p->dev));
+#endif
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+ // Allocate RTMP_ADAPTER miniport adapter structure
+ handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
+ RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p);
+
+ status = RTMPAllocAdapterBlock(handle, &pAd);
+ if (status != NDIS_STATUS_SUCCESS)
+ goto err_out_free_netdev;
+
+ net_dev->ml_priv = (PVOID)pAd;
+ pAd->net_dev = net_dev; // must be before RT28XXNetDevInit()
+
+ RT28XXNetDevInit(_dev_p, net_dev, pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+ pAd->StaCfg.OriDevType = net_dev->type;
+#endif // CONFIG_STA_SUPPORT //
+
+ // Find and assign a free interface name, raxx
+// RT28XXAvailRANameAssign(net_dev->name);
+
+ // Post config
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ if (RT28XXProbePostConfig(_dev_p, pAd, argc) == FALSE)
+ goto err_out_unmap;
+#else
+ if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE)
+ goto err_out_unmap;
+#endif // LINUX_VERSION_CODE //
+
+#ifdef CONFIG_STA_SUPPORT
+ pAd->OpMode = OPMODE_STA;
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef MULTIPLE_CARD_SUPPORT
+ // find its profile path
+ pAd->MC_RowID = -1; // use default profile path
+ RTMP_CardInfoRead(pAd);
+
+ if (pAd->MC_RowID == -1)
+#ifdef CONFIG_STA_SUPPORT
+ strcpy(pAd->MC_FileName, STA_PROFILE_PATH);
+#endif // CONFIG_STA_SUPPORT //
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("MC> ROW = %d, PATH = %s\n", pAd->MC_RowID, pAd->MC_FileName));
+#endif // MULTIPLE_CARD_SUPPORT //
+
+ // sample move
+ if (rt_ieee80211_if_setup(net_dev, pAd) != NDIS_STATUS_SUCCESS)
+ goto err_out_unmap;
+
+ // Register this device
+ status = register_netdev(net_dev);
+ if (status)
+ goto err_out_unmap;
+
+ // Set driver data
+ RT28XX_DRVDATA_SET(_dev_p);
+
+
+
+ *ppAd = pAd;
+ return 0; // probe ok
+
+
+ /* --------------------------- ERROR HANDLE --------------------------- */
+err_out_unmap:
+ RTMPFreeAdapter(pAd);
+ RT28XX_UNMAP();
+
+err_out_free_netdev:
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ free_netdev(net_dev);
+#else
+ kfree(net_dev);
+#endif
+
+err_out:
+ RT28XX_PUT_DEVICE(dev_p);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ return (LONG)NULL;
+#else
+ return -ENODEV; /* probe fail */
+#endif // LINUX_VERSION_CODE //
+} /* End of rt28xx_probe */
+
+
+/*
+========================================================================
+Routine Description:
+ The entry point for Linux kernel sent packet to our driver.
+
+Arguments:
+ sk_buff *skb the pointer refer to a sk_buffer.
+
+Return Value:
+ 0
+
+Note:
+ This function is the entry point of Tx Path for Os delivery packet to
+ our driver. You only can put OS-depened & STA/AP common handle procedures
+ in here.
+========================================================================
+*/
+int rt28xx_packet_xmit(struct sk_buff *skb)
+{
+ struct net_device *net_dev = skb->dev;
+ PRTMP_ADAPTER pAd = net_dev->ml_priv;
+ int status = 0;
+ PNDIS_PACKET pPacket = (PNDIS_PACKET) skb;
+
+ /* RT2870STA does this in RTMPSendPackets() */
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES);
+ return 0;
+ }
+#endif // RALINK_ATE //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Drop send request since we are in monitor mode
+ if (MONITOR_ON(pAd))
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ goto done;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // EapolStart size is 18
+ if (skb->len < 14)
+ {
+ //printk("bad packet size: %d\n", pkt->len);
+ hex_dump("bad packet", skb->data, skb->len);
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ goto done;
+ }
+
+ RTMP_SET_PACKET_5VT(pPacket, 0);
+// MiniportMMRequest(pAd, pkt->data, pkt->len);
+#ifdef CONFIG_5VT_ENHANCE
+ if (*(int*)(skb->cb) == BRIDGE_TAG) {
+ RTMP_SET_PACKET_5VT(pPacket, 1);
+ }
+#endif
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+
+ STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
+ }
+
+#endif // CONFIG_STA_SUPPORT //
+
+ status = 0;
+done:
+
+ return status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Send a packet to WLAN.
+
+Arguments:
+ skb_p points to our adapter
+ dev_p which WLAN network interface
+
+Return Value:
+ 0: transmit successfully
+ otherwise: transmit fail
+
+Note:
+========================================================================
+*/
+INT rt28xx_send_packets(
+ IN struct sk_buff *skb_p,
+ IN struct net_device *net_dev)
+{
+ RTMP_ADAPTER *pAd = net_dev->ml_priv;
+
+ if (!(net_dev->flags & IFF_UP))
+ {
+ RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE);
+ return 0;
+ }
+
+ NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15);
+ RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
+
+ return rt28xx_packet_xmit(skb_p);
+} /* End of MBSS_VirtualIF_PacketSend */
+
+
+
+
+#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
+//static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)) //sample
+struct net_device *alloc_netdev(
+ int sizeof_priv,
+ const char *mask,
+ void (*setup)(struct net_device *))
+{
+ struct net_device *dev;
+ INT alloc_size;
+
+
+ /* ensure 32-byte alignment of the private area */
+ alloc_size = sizeof (*dev) + sizeof_priv + 31;
+
+ dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL);
+ if (dev == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("alloc_netdev: Unable to allocate device memory.\n"));
+ return NULL;
+ }
+
+ memset(dev, 0, alloc_size);
+
+ if (sizeof_priv)
+ dev->ml_priv = (void *) (((long)(dev + 1) + 31) & ~31);
+
+ setup(dev);
+ strcpy(dev->name, mask);
+
+ return dev;
+}
+#endif // LINUX_VERSION_CODE //
+
+
+void CfgInitHook(PRTMP_ADAPTER pAd)
+{
+ pAd->bBroadComHT = TRUE;
+} /* End of CfgInitHook */
+
+
+#if WIRELESS_EXT >= 12
+// This function will be called when query /proc
+struct iw_statistics *rt28xx_get_wireless_stats(
+ IN struct net_device *net_dev)
+{
+ PRTMP_ADAPTER pAd = net_dev->ml_priv;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
+
+ pAd->iw_stats.status = 0; // Status - device dependent for now
+
+ // link quality
+ pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10);
+ if(pAd->iw_stats.qual.qual > 100)
+ pAd->iw_stats.qual.qual = 100;
+
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->OpMode == OPMODE_STA)
+ pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
+#endif // CONFIG_STA_SUPPORT //
+
+ pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm)
+
+ pAd->iw_stats.qual.noise += 256 - 143;
+ pAd->iw_stats.qual.updated = 1; // Flags to know if updated
+#ifdef IW_QUAL_DBM
+ pAd->iw_stats.qual.updated |= IW_QUAL_DBM; // Level + Noise are dBm
+#endif // IW_QUAL_DBM //
+
+ pAd->iw_stats.discard.nwid = 0; // Rx : Wrong nwid/essid
+ pAd->iw_stats.miss.beacon = 0; // Missed beacons/superframe
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
+ return &pAd->iw_stats;
+} /* End of rt28xx_get_wireless_stats */
+#endif // WIRELESS_EXT //
+
+
+
+void tbtt_tasklet(unsigned long data)
+{
+#define MAX_TX_IN_TBTT (16)
+
+}
+
+INT rt28xx_ioctl(
+ IN struct net_device *net_dev,
+ IN OUT struct ifreq *rq,
+ IN INT cmd)
+{
+ VIRTUAL_ADAPTER *pVirtualAd = NULL;
+ RTMP_ADAPTER *pAd = NULL;
+ INT ret = 0;
+
+ if (net_dev->priv_flags == INT_MAIN)
+ {
+ pAd = net_dev->ml_priv;
+ }
+ else
+ {
+ pVirtualAd = net_dev->ml_priv;
+ pAd = pVirtualAd->RtmpDev->ml_priv;
+ }
+
+ if (pAd == NULL)
+ {
+ /* if 1st open fail, pAd will be free;
+ So the net_dev->ml_priv will be NULL in 2rd open */
+ return -ENETDOWN;
+ }
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ ret = rt28xx_sta_ioctl(net_dev, rq, cmd);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ return ret;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ return ethernet statistics counter
+
+ Arguments:
+ net_dev Pointer to net_device
+
+ Return Value:
+ net_device_stats*
+
+ Note:
+
+ ========================================================================
+*/
+struct net_device_stats *RT28xx_get_ether_stats(
+ IN struct net_device *net_dev)
+{
+ RTMP_ADAPTER *pAd = NULL;
+
+ if (net_dev)
+ pAd = net_dev->ml_priv;
+
+ if (pAd)
+ {
+
+ pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
+ pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
+
+ pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
+ pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
+
+ pAd->stats.rx_errors = pAd->Counters8023.RxErrors;
+ pAd->stats.tx_errors = pAd->Counters8023.TxErrors;
+
+ pAd->stats.rx_dropped = 0;
+ pAd->stats.tx_dropped = 0;
+
+ pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart; // multicast packets received
+ pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions; // Collision packets
+
+ pAd->stats.rx_length_errors = 0;
+ pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer; // receiver ring buff overflow
+ pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error
+ pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors; // recv'd frame alignment error
+ pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer; // recv'r fifo overrun
+ pAd->stats.rx_missed_errors = 0; // receiver missed packet
+
+ // detailed tx_errors
+ pAd->stats.tx_aborted_errors = 0;
+ pAd->stats.tx_carrier_errors = 0;
+ pAd->stats.tx_fifo_errors = 0;
+ pAd->stats.tx_heartbeat_errors = 0;
+ pAd->stats.tx_window_errors = 0;
+
+ // for cslip etc
+ pAd->stats.rx_compressed = 0;
+ pAd->stats.tx_compressed = 0;
+
+ return &pAd->stats;
+ }
+ else
+ return NULL;
+}
+
diff --git a/drivers/staging/rt3070/rt_profile.c b/drivers/staging/rt3070/rt_profile.c
new file mode 100644
index 00000000000..6eda27e6b8d
--- /dev/null
+++ b/drivers/staging/rt3070/rt_profile.c
@@ -0,0 +1,2041 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#include "rt_config.h"
+
+#ifdef DOT11_N_SUPPORT
+static void HTParametersHook(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR *pValueStr,
+ IN CHAR *pInput);
+#endif // DOT11_N_SUPPORT //
+
+#define ETH_MAC_ADDR_STR_LEN 17 // in format of xx:xx:xx:xx:xx:xx
+
+// We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed.
+BOOLEAN rtstrmactohex(char *s1, char *s2)
+{
+ int i = 0;
+ char *ptokS = s1, *ptokE = s1;
+
+ if (strlen(s1) != ETH_MAC_ADDR_STR_LEN)
+ return FALSE;
+
+ while((*ptokS) != '\0')
+ {
+ if((ptokE = strchr(ptokS, ':')) != NULL)
+ *ptokE++ = '\0';
+ if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1))))
+ break; // fail
+ AtoH(ptokS, &s2[i++], 1);
+ ptokS = ptokE;
+ if (i == 6)
+ break; // parsing finished
+ }
+
+ return ( i == 6 ? TRUE : FALSE);
+
+}
+
+
+// we assume the s1 and s2 both are strings.
+BOOLEAN rtstrcasecmp(char *s1, char *s2)
+{
+ char *p1 = s1, *p2 = s2;
+
+ if (strlen(s1) != strlen(s2))
+ return FALSE;
+
+ while(*p1 != '\0')
+ {
+ if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20))
+ return FALSE;
+ p1++;
+ p2++;
+ }
+
+ return TRUE;
+}
+
+// we assume the s1 (buffer) and s2 (key) both are strings.
+char * rtstrstruncasecmp(char * s1, char * s2)
+{
+ INT l1, l2, i;
+ char temp1, temp2;
+
+ l2 = strlen(s2);
+ if (!l2)
+ return (char *) s1;
+
+ l1 = strlen(s1);
+
+ while (l1 >= l2)
+ {
+ l1--;
+
+ for(i=0; i<l2; i++)
+ {
+ temp1 = *(s1+i);
+ temp2 = *(s2+i);
+
+ if (('a' <= temp1) && (temp1 <= 'z'))
+ temp1 = 'A'+(temp1-'a');
+ if (('a' <= temp2) && (temp2 <= 'z'))
+ temp2 = 'A'+(temp2-'a');
+
+ if (temp1 != temp2)
+ break;
+ }
+
+ if (i == l2)
+ return (char *) s1;
+
+ s1++;
+ }
+
+ return NULL; // not found
+}
+
+//add by kathy
+
+ /**
+ * strstr - Find the first substring in a %NUL terminated string
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ */
+char * rtstrstr(const char * s1,const char * s2)
+{
+ INT l1, l2;
+
+ l2 = strlen(s2);
+ if (!l2)
+ return (char *) s1;
+
+ l1 = strlen(s1);
+
+ while (l1 >= l2)
+ {
+ l1--;
+ if (!memcmp(s1,s2,l2))
+ return (char *) s1;
+ s1++;
+ }
+
+ return NULL;
+}
+
+/**
+ * rstrtok - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ * * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture.
+ */
+char * __rstrtok;
+char * rstrtok(char * s,const char * ct)
+{
+ char *sbegin, *send;
+
+ sbegin = s ? s : __rstrtok;
+ if (!sbegin)
+ {
+ return NULL;
+ }
+
+ sbegin += strspn(sbegin,ct);
+ if (*sbegin == '\0')
+ {
+ __rstrtok = NULL;
+ return( NULL );
+ }
+
+ send = strpbrk( sbegin, ct);
+ if (send && *send != '\0')
+ *send++ = '\0';
+
+ __rstrtok = send;
+
+ return (sbegin);
+}
+
+/**
+ * delimitcnt - return the count of a given delimiter in a given string.
+ * @s: The string to be searched.
+ * @ct: The delimiter to search for.
+ * Notice : We suppose the delimiter is a single-char string(for example : ";").
+ */
+INT delimitcnt(char * s,const char * ct)
+{
+ INT count = 0;
+ /* point to the beginning of the line */
+ const char *token = s;
+
+ for ( ;; )
+ {
+ token = strpbrk(token, ct); /* search for delimiters */
+
+ if ( token == NULL )
+ {
+ /* advanced to the terminating null character */
+ break;
+ }
+ /* skip the delimiter */
+ ++token;
+
+ /*
+ * Print the found text: use len with %.*s to specify field width.
+ */
+
+ /* accumulate delimiter count */
+ ++count;
+ }
+ return count;
+}
+
+/*
+ * converts the Internet host address from the standard numbers-and-dots notation
+ * into binary data.
+ * returns nonzero if the address is valid, zero if not.
+ */
+int rtinet_aton(const char *cp, unsigned int *addr)
+{
+ unsigned int val;
+ int base, n;
+ char c;
+ unsigned int parts[4];
+ unsigned int *pp = parts;
+
+ for (;;)
+ {
+ /*
+ * Collect number up to ``.''.
+ * Values are specified as for C:
+ * 0x=hex, 0=octal, other=decimal.
+ */
+ val = 0;
+ base = 10;
+ if (*cp == '0')
+ {
+ if (*++cp == 'x' || *cp == 'X')
+ base = 16, cp++;
+ else
+ base = 8;
+ }
+ while ((c = *cp) != '\0')
+ {
+ if (isdigit((unsigned char) c))
+ {
+ val = (val * base) + (c - '0');
+ cp++;
+ continue;
+ }
+ if (base == 16 && isxdigit((unsigned char) c))
+ {
+ val = (val << 4) +
+ (c + 10 - (islower((unsigned char) c) ? 'a' : 'A'));
+ cp++;
+ continue;
+ }
+ break;
+ }
+ if (*cp == '.')
+ {
+ /*
+ * Internet format: a.b.c.d a.b.c (with c treated as 16-bits)
+ * a.b (with b treated as 24 bits)
+ */
+ if (pp >= parts + 3 || val > 0xff)
+ return 0;
+ *pp++ = val, cp++;
+ }
+ else
+ break;
+ }
+
+ /*
+ * Check for trailing junk.
+ */
+ while (*cp)
+ if (!isspace((unsigned char) *cp++))
+ return 0;
+
+ /*
+ * Concoct the address according to the number of parts specified.
+ */
+ n = pp - parts + 1;
+ switch (n)
+ {
+
+ case 1: /* a -- 32 bits */
+ break;
+
+ case 2: /* a.b -- 8.24 bits */
+ if (val > 0xffffff)
+ return 0;
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff)
+ return 0;
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff)
+ return 0;
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+
+ *addr = htonl(val);
+ return 1;
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Find key section for Get key parameter.
+
+ Arguments:
+ buffer Pointer to the buffer to start find the key section
+ section the key of the secion to be find
+
+ Return Value:
+ NULL Fail
+ Others Success
+ ========================================================================
+*/
+PUCHAR RTMPFindSection(
+ IN PCHAR buffer)
+{
+ CHAR temp_buf[32];
+ PUCHAR ptr;
+
+ strcpy(temp_buf, "Default");
+
+ if((ptr = rtstrstr(buffer, temp_buf)) != NULL)
+ return (ptr+strlen("\n"));
+ else
+ return NULL;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get key parameter.
+
+ Arguments:
+ key Pointer to key string
+ dest Pointer to destination
+ destsize The datasize of the destination
+ buffer Pointer to the buffer to start find the key
+
+ Return Value:
+ TRUE Success
+ FALSE Fail
+
+ Note:
+ This routine get the value with the matched key (case case-sensitive)
+ ========================================================================
+*/
+INT RTMPGetKeyParameter(
+ IN PCHAR key,
+ OUT PCHAR dest,
+ IN INT destsize,
+ IN PCHAR buffer)
+{
+ UCHAR *temp_buf1 = NULL;
+ UCHAR *temp_buf2 = NULL;
+ CHAR *start_ptr;
+ CHAR *end_ptr;
+ CHAR *ptr;
+ CHAR *offset = 0;
+ INT len;
+
+ //temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
+
+ if(temp_buf1 == NULL)
+ return (FALSE);
+
+ //temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
+ if(temp_buf2 == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ return (FALSE);
+ }
+
+ //find section
+ if((offset = RTMPFindSection(buffer)) == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ strcpy(temp_buf1, "\n");
+ strcat(temp_buf1, key);
+ strcat(temp_buf1, "=");
+
+ //search key
+ if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ start_ptr+=strlen("\n");
+ if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
+ end_ptr=start_ptr+strlen(start_ptr);
+
+ if (end_ptr<start_ptr)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+ temp_buf2[end_ptr-start_ptr]='\0';
+ len = strlen(temp_buf2);
+ strcpy(temp_buf1, temp_buf2);
+ if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ strcpy(temp_buf2, start_ptr+1);
+ ptr = temp_buf2;
+ //trim space or tab
+ while(*ptr != 0x00)
+ {
+ if( (*ptr == ' ') || (*ptr == '\t') )
+ ptr++;
+ else
+ break;
+ }
+
+ len = strlen(ptr);
+ memset(dest, 0x00, destsize);
+ strncpy(dest, ptr, len >= destsize ? destsize: len);
+
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return TRUE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get key parameter.
+
+ Arguments:
+ key Pointer to key string
+ dest Pointer to destination
+ destsize The datasize of the destination
+ buffer Pointer to the buffer to start find the key
+
+ Return Value:
+ TRUE Success
+ FALSE Fail
+
+ Note:
+ This routine get the value with the matched key (case case-sensitive).
+ It is called for parsing SSID and any key string.
+ ========================================================================
+*/
+INT RTMPGetCriticalParameter(
+ IN PCHAR key,
+ OUT PCHAR dest,
+ IN INT destsize,
+ IN PCHAR buffer)
+{
+ UCHAR *temp_buf1 = NULL;
+ UCHAR *temp_buf2 = NULL;
+ CHAR *start_ptr;
+ CHAR *end_ptr;
+ CHAR *ptr;
+ CHAR *offset = 0;
+ INT len;
+
+ //temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
+
+ if(temp_buf1 == NULL)
+ return (FALSE);
+
+ //temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
+ if(temp_buf2 == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ return (FALSE);
+ }
+
+ //find section
+ if((offset = RTMPFindSection(buffer)) == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ strcpy(temp_buf1, "\n");
+ strcat(temp_buf1, key);
+ strcat(temp_buf1, "=");
+
+ //search key
+ if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ start_ptr+=strlen("\n");
+ if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
+ end_ptr=start_ptr+strlen(start_ptr);
+
+ if (end_ptr<start_ptr)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+ temp_buf2[end_ptr-start_ptr]='\0';
+ len = strlen(temp_buf2);
+ strcpy(temp_buf1, temp_buf2);
+ if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ strcpy(temp_buf2, start_ptr+1);
+ ptr = temp_buf2;
+
+ //trim tab
+ /* We cannot trim space(' ') for SSID and key string. */
+ while(*ptr != 0x00)
+ {
+ //if( (*ptr == ' ') || (*ptr == '\t') )
+ if( (*ptr == '\t') )
+ ptr++;
+ else
+ break;
+ }
+
+ len = strlen(ptr);
+ memset(dest, 0x00, destsize);
+ strncpy(dest, ptr, len >= destsize ? destsize: len);
+
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return TRUE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get multiple key parameter.
+
+ Arguments:
+ key Pointer to key string
+ dest Pointer to destination
+ destsize The datasize of the destination
+ buffer Pointer to the buffer to start find the key
+
+ Return Value:
+ TRUE Success
+ FALSE Fail
+
+ Note:
+ This routine get the value with the matched key (case case-sensitive)
+ ========================================================================
+*/
+INT RTMPGetKeyParameterWithOffset(
+ IN PCHAR key,
+ OUT PCHAR dest,
+ OUT USHORT *end_offset,
+ IN INT destsize,
+ IN PCHAR buffer,
+ IN BOOLEAN bTrimSpace)
+{
+ UCHAR *temp_buf1 = NULL;
+ UCHAR *temp_buf2 = NULL;
+ CHAR *start_ptr;
+ CHAR *end_ptr;
+ CHAR *ptr;
+ CHAR *offset = 0;
+ INT len;
+
+ if (*end_offset >= MAX_INI_BUFFER_SIZE)
+ return (FALSE);
+
+ os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
+
+ if(temp_buf1 == NULL)
+ return (FALSE);
+
+ os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
+ if(temp_buf2 == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ return (FALSE);
+ }
+
+ //find section
+ if(*end_offset == 0)
+ {
+ if ((offset = RTMPFindSection(buffer)) == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+ }
+ else
+ offset = buffer + (*end_offset);
+
+ strcpy(temp_buf1, "\n");
+ strcat(temp_buf1, key);
+ strcat(temp_buf1, "=");
+
+ //search key
+ if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ start_ptr+=strlen("\n");
+ if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
+ end_ptr=start_ptr+strlen(start_ptr);
+
+ if (end_ptr<start_ptr)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ *end_offset = end_ptr - buffer;
+
+ NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+ temp_buf2[end_ptr-start_ptr]='\0';
+ len = strlen(temp_buf2);
+ strcpy(temp_buf1, temp_buf2);
+ if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ strcpy(temp_buf2, start_ptr+1);
+ ptr = temp_buf2;
+ //trim space or tab
+ while(*ptr != 0x00)
+ {
+ if((bTrimSpace && (*ptr == ' ')) || (*ptr == '\t') )
+ ptr++;
+ else
+ break;
+ }
+
+ len = strlen(ptr);
+ memset(dest, 0x00, destsize);
+ strncpy(dest, ptr, len >= destsize ? destsize: len);
+
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return TRUE;
+}
+
+
+static int rtmp_parse_key_buffer_from_file(IN PRTMP_ADAPTER pAd,IN char *buffer,IN ULONG KeyType,IN INT BSSIdx,IN INT KeyIdx)
+{
+ PUCHAR keybuff;
+ INT i = BSSIdx, idx = KeyIdx;
+ ULONG KeyLen;
+ UCHAR CipherAlg = CIPHER_WEP64;
+
+ keybuff = buffer;
+ KeyLen = strlen(keybuff);
+
+ if (KeyType == 1)
+ {//Ascii
+ if( (KeyLen == 5) || (KeyLen == 13))
+ {
+ pAd->SharedKey[i][idx].KeyLen = KeyLen;
+ NdisMoveMemory(pAd->SharedKey[i][idx].Key, keybuff, KeyLen);
+ if (KeyLen == 5)
+ CipherAlg = CIPHER_WEP64;
+ else
+ CipherAlg = CIPHER_WEP128;
+ pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
+ return 1;
+ }
+ else
+ {//Invalid key length
+ DBGPRINT(RT_DEBUG_ERROR, ("Key%dStr is Invalid key length! KeyLen = %ld!\n", idx+1, KeyLen));
+ return 0;
+ }
+ }
+ else
+ {//Hex type
+ if( (KeyLen == 10) || (KeyLen == 26))
+ {
+ pAd->SharedKey[i][idx].KeyLen = KeyLen / 2;
+ AtoH(keybuff, pAd->SharedKey[i][idx].Key, KeyLen / 2);
+ if (KeyLen == 10)
+ CipherAlg = CIPHER_WEP64;
+ else
+ CipherAlg = CIPHER_WEP128;
+ pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
+ return 1;
+ }
+ else
+ {//Invalid key length
+ DBGPRINT(RT_DEBUG_ERROR, ("I/F(ra%d) Key%dStr is Invalid key length! KeyLen = %ld!\n", i, idx+1, KeyLen));
+ return 0;
+ }
+ }
+}
+static void rtmp_read_key_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
+{
+ char tok_str[16];
+ PUCHAR macptr;
+ INT i = 0, idx;
+ ULONG KeyType[MAX_MBSSID_NUM];
+ ULONG KeyIdx;
+
+ NdisZeroMemory(KeyType, MAX_MBSSID_NUM);
+
+ //DefaultKeyID
+ if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer))
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ KeyIdx = simple_strtol(tmpbuf, 0, 10);
+ if((KeyIdx >= 1 ) && (KeyIdx <= 4))
+ pAd->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1);
+ else
+ pAd->StaCfg.DefaultKeyId = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyID(0~3)=%d\n", pAd->StaCfg.DefaultKeyId));
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+
+ for (idx = 0; idx < 4; idx++)
+ {
+ sprintf(tok_str, "Key%dType", idx + 1);
+ //Key1Type
+ if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ KeyType[i] = simple_strtol(macptr, 0, 10);
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ sprintf(tok_str, "Key%dStr", idx + 1);
+ if (RTMPGetCriticalParameter(tok_str, tmpbuf, 128, buffer))
+ {
+ rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ }
+}
+
+
+#ifdef CONFIG_STA_SUPPORT
+static void rtmp_read_sta_wmm_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
+{
+ PUCHAR macptr;
+ INT i=0;
+ BOOLEAN bWmmEnable = FALSE;
+
+ //WmmCapable
+ if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+ {
+ pAd->CommonCfg.bWmmCapable = TRUE;
+ bWmmEnable = TRUE;
+ }
+ else //Disable
+ {
+ pAd->CommonCfg.bWmmCapable = FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable));
+ }
+
+#ifdef QOS_DLS_SUPPORT
+ //DLSCapable
+ if(RTMPGetKeyParameter("DLSCapable", tmpbuf, 32, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+ {
+ pAd->CommonCfg.bDLSCapable = TRUE;
+ }
+ else //Disable
+ {
+ pAd->CommonCfg.bDLSCapable = FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("bDLSCapable=%d\n", pAd->CommonCfg.bDLSCapable));
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ //AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO
+ if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i]));
+ }
+ }
+
+ if (bWmmEnable)
+ {
+ //APSDCapable
+ if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+ pAd->CommonCfg.bAPSDCapable = TRUE;
+ else
+ pAd->CommonCfg.bAPSDCapable = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable));
+ }
+
+ //APSDAC for AC_BE, AC_BK, AC_VI, AC_VO
+ if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer))
+ {
+ BOOLEAN apsd_ac[4];
+
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d %d\n", i, apsd_ac[i]));
+ }
+
+ pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0];
+ pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1];
+ pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2];
+ pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3];
+ }
+ }
+
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+NDIS_STATUS RTMPReadParametersHook(
+ IN PRTMP_ADAPTER pAd)
+{
+ PUCHAR src = NULL;
+ struct file *srcf;
+ INT retval, orgfsuid, orgfsgid;
+ mm_segment_t orgfs;
+ CHAR *buffer;
+ CHAR *tmpbuf;
+ ULONG RtsThresh;
+ ULONG FragThresh;
+#ifdef CONFIG_STA_SUPPORT
+ UCHAR keyMaterial[40];
+#endif // CONFIG_STA_SUPPORT //
+
+
+ PUCHAR macptr;
+ INT i = 0;
+
+ buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ if(buffer == NULL)
+ return NDIS_STATUS_FAILURE;
+
+ tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ if(tmpbuf == NULL)
+ {
+ kfree(buffer);
+ return NDIS_STATUS_FAILURE;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ src = STA_PROFILE_PATH;
+#endif // CONFIG_STA_SUPPORT //
+#ifdef MULTIPLE_CARD_SUPPORT
+ src = pAd->MC_FileName;
+#endif // MULTIPLE_CARD_SUPPORT //
+
+ // Save uid and gid used for filesystem access.
+ // Set user and group to 0 (root)
+#if 0
+ orgfsuid = current->fsuid;
+ orgfsgid = current->fsgid;
+ current->fsuid=current->fsgid = 0;
+#endif
+ orgfs = get_fs();
+ set_fs(KERNEL_DS);
+
+ if (src && *src)
+ {
+ srcf = filp_open(src, O_RDONLY, 0);
+ if (IS_ERR(srcf))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
+ }
+ else
+ {
+ // The object must have a read method
+ if (srcf->f_op && srcf->f_op->read)
+ {
+ memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
+ retval=srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
+ if (retval < 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> Read %s error %d\n", src, -retval));
+ }
+ else
+ {
+ // set file parameter to portcfg
+ //CountryRegion
+ if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, buffer))
+ {
+ pAd->CommonCfg.CountryRegion = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion));
+ }
+ //CountryRegionABand
+ if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, buffer))
+ {
+ pAd->CommonCfg.CountryRegionForABand= (UCHAR) simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand));
+ }
+ //CountryCode
+ if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, buffer))
+ {
+ NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2);
+#ifdef CONFIG_STA_SUPPORT
+#ifdef EXT_BUILD_CHANNEL_LIST
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ NdisMoveMemory(pAd->StaCfg.StaOriCountryCode, tmpbuf , 2);
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+ if (strlen(pAd->CommonCfg.CountryCode) != 0)
+ {
+ pAd->CommonCfg.bCountryFlag = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode));
+ }
+ //ChannelGeography
+ if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, buffer))
+ {
+ UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+ if (Geography <= BOTH)
+ {
+ pAd->CommonCfg.Geography = Geography;
+ pAd->CommonCfg.CountryCode[2] =
+ (pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O');
+#ifdef CONFIG_STA_SUPPORT
+#ifdef EXT_BUILD_CHANNEL_LIST
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pAd->StaCfg.StaOriGeography = pAd->CommonCfg.Geography;
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography));
+ }
+ }
+ else
+ {
+ pAd->CommonCfg.Geography = BOTH;
+ pAd->CommonCfg.CountryCode[2] = ' ';
+ }
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ //SSID
+ if (RTMPGetCriticalParameter("SSID", tmpbuf, 256, buffer))
+ {
+ if (strlen(tmpbuf) <= 32)
+ {
+ pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf);
+ NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID);
+ NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen);
+ pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
+ NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID);
+ NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen);
+ pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
+ NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID);
+ NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __FUNCTION__, tmpbuf));
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ //NetworkType
+ if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, buffer))
+ {
+ pAd->bConfigChanged = TRUE;
+ if (strcmp(tmpbuf, "Adhoc") == 0)
+ pAd->StaCfg.BssType = BSS_ADHOC;
+ else //Default Infrastructure mode
+ pAd->StaCfg.BssType = BSS_INFRA;
+ // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
+ pAd->StaCfg.WpaState = SS_NOTUSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __FUNCTION__, pAd->StaCfg.BssType));
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+ //Channel
+ if(RTMPGetKeyParameter("Channel", tmpbuf, 10, buffer))
+ {
+ pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel));
+ }
+ //WirelessMode
+ if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, buffer))
+ {
+ int value = 0, maxPhyMode = PHY_11G;
+
+#ifdef DOT11_N_SUPPORT
+ maxPhyMode = PHY_11N_5G;
+#endif // DOT11_N_SUPPORT //
+
+ value = simple_strtol(tmpbuf, 0, 10);
+
+ if (value <= maxPhyMode)
+ {
+ pAd->CommonCfg.PhyMode = value;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
+ }
+ //BasicRate
+ if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, buffer))
+ {
+ pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap));
+ }
+ //BeaconPeriod
+ if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, buffer))
+ {
+ pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod));
+ }
+ //TxPower
+ if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, buffer))
+ {
+ pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10);
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage;
+#endif // CONFIG_STA_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage));
+ }
+ //BGProtection
+ if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, buffer))
+ {
+ switch (simple_strtol(tmpbuf, 0, 10))
+ {
+ case 1: //Always On
+ pAd->CommonCfg.UseBGProtection = 1;
+ break;
+ case 2: //Always OFF
+ pAd->CommonCfg.UseBGProtection = 2;
+ break;
+ case 0: //AUTO
+ default:
+ pAd->CommonCfg.UseBGProtection = 0;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection));
+ }
+ //OLBCDetection
+ if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, buffer))
+ {
+ switch (simple_strtol(tmpbuf, 0, 10))
+ {
+ case 1: //disable OLBC Detection
+ pAd->CommonCfg.DisableOLBCDetect = 1;
+ break;
+ case 0: //enable OLBC Detection
+ pAd->CommonCfg.DisableOLBCDetect = 0;
+ break;
+ default:
+ pAd->CommonCfg.DisableOLBCDetect= 0;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect));
+ }
+ //TxPreamble
+ if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, buffer))
+ {
+ switch (simple_strtol(tmpbuf, 0, 10))
+ {
+ case Rt802_11PreambleShort:
+ pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort;
+ break;
+ case Rt802_11PreambleLong:
+ default:
+ pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble));
+ }
+ //RTSThreshold
+ if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, buffer))
+ {
+ RtsThresh = simple_strtol(tmpbuf, 0, 10);
+ if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) )
+ pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
+ else
+ pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold));
+ }
+ //FragThreshold
+ if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, buffer))
+ {
+ FragThresh = simple_strtol(tmpbuf, 0, 10);
+ pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
+
+ if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
+ { //illegal FragThresh so we set it to default
+ pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
+ pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
+ }
+ else if (FragThresh % 2 == 1)
+ {
+ // The length of each fragment shall always be an even number of octets, except for the last fragment
+ // of an MSDU or MMPDU, which may be either an even or an odd number of octets.
+ pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
+ }
+ else
+ {
+ pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
+ }
+ //pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
+ DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold));
+ }
+ //TxBurst
+ if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, buffer))
+ {
+//#ifdef WIFI_TEST
+// pAd->CommonCfg.bEnableTxBurst = FALSE;
+//#else
+ if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+ pAd->CommonCfg.bEnableTxBurst = TRUE;
+ else //Disable
+ pAd->CommonCfg.bEnableTxBurst = FALSE;
+//#endif
+ DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst));
+ }
+
+#ifdef AGGREGATION_SUPPORT
+ //PktAggregate
+ if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+ pAd->CommonCfg.bAggregationCapable = TRUE;
+ else //Disable
+ pAd->CommonCfg.bAggregationCapable = FALSE;
+#ifdef PIGGYBACK_SUPPORT
+ pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
+#endif // PIGGYBACK_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable));
+ }
+#else
+ pAd->CommonCfg.bAggregationCapable = FALSE;
+ pAd->CommonCfg.bPiggyBackCapable = FALSE;
+#endif // AGGREGATION_SUPPORT //
+
+ // WmmCapable
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, buffer);
+#endif // CONFIG_STA_SUPPORT //
+
+ //ShortSlot
+ if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+ pAd->CommonCfg.bUseShortSlotTime = TRUE;
+ else //Disable
+ pAd->CommonCfg.bUseShortSlotTime = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
+ }
+ //IEEE80211H
+ if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, buffer))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if(simple_strtol(macptr, 0, 10) != 0) //Enable
+ pAd->CommonCfg.bIEEE80211H = TRUE;
+ else //Disable
+ pAd->CommonCfg.bIEEE80211H = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H));
+ }
+ }
+ //CSPeriod
+ if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0)
+ pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10);
+ else
+ pAd->CommonCfg.RadarDetect.CSPeriod = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod));
+ }
+
+ //RDRegion
+ if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, buffer))
+ {
+ if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W53;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
+ }
+ else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W56;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+ }
+ else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
+ }
+ else if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = FCC;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
+ }
+ else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+ }
+ else
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pAd->CommonCfg.RadarDetect.RDDurRegion));
+ }
+ else
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+ }
+
+ //WirelessEvent
+ if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, buffer))
+ {
+#if WIRELESS_EXT >= 15
+ if(simple_strtol(tmpbuf, 0, 10) != 0)
+ pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10);
+ else
+ pAd->CommonCfg.bWirelessEvent = 0; // disable
+#else
+ pAd->CommonCfg.bWirelessEvent = 0; // disable
+#endif
+ DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent));
+ }
+ if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0)
+ pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10);
+ else
+ pAd->CommonCfg.bWiFiTest = 0; // disable
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest));
+ }
+ //AuthMode
+ if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, buffer))
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
+ else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+ else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
+ else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
+ else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
+ else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ else
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ //EncrypType
+ if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, buffer))
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0))
+ pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled;
+ else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0))
+ pAd->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
+ else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0))
+ pAd->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
+ else
+ pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+
+ // Update all wepstatus related
+ pAd->StaCfg.PairCipher = pAd->StaCfg.WepStatus;
+ pAd->StaCfg.GroupCipher = pAd->StaCfg.WepStatus;
+ pAd->StaCfg.OrigWepStatus = pAd->StaCfg.WepStatus;
+ pAd->StaCfg.bMixCipher = FALSE;
+
+ //RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if(RTMPGetCriticalParameter("WPAPSK", tmpbuf, 512, buffer))
+ {
+ int err=0;
+
+ tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input
+
+ if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
+ (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+ (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
+ )
+ {
+ err = 1;
+ }
+ else if ((strlen(tmpbuf) >= 8) && (strlen(tmpbuf) < 64))
+ {
+ PasswordHash((char *)tmpbuf, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, keyMaterial);
+ NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
+
+ }
+ else if (strlen(tmpbuf) == 64)
+ {
+ AtoH(tmpbuf, keyMaterial, 32);
+ NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
+ }
+ else
+ {
+ err = 1;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s::(WPAPSK key-string required 8 ~ 64 characters!)\n", __FUNCTION__));
+ }
+
+ if (err == 0)
+ {
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ // Start STA supplicant state machine
+ pAd->StaCfg.WpaState = SS_START;
+ }
+ else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ /*
+ NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
+
+ // Decide its ChiperAlg
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+ else
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
+ */
+ pAd->StaCfg.WpaState = SS_NOTUSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __FUNCTION__, tmpbuf));
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ //DefaultKeyID, KeyType, KeyStr
+ rtmp_read_key_parms_from_file(pAd, tmpbuf, buffer);
+
+
+ //HSCounter
+ /*if(RTMPGetKeyParameter("HSCounter", tmpbuf, 10, buffer))
+ {
+ switch (simple_strtol(tmpbuf, 0, 10))
+ {
+ case 1: //Enable
+ pAd->CommonCfg.bEnableHSCounter = TRUE;
+ break;
+ case 0: //Disable
+ default:
+ pAd->CommonCfg.bEnableHSCounter = FALSE;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, "HSCounter=%d\n", pAd->CommonCfg.bEnableHSCounter);
+ }*/
+
+#ifdef DOT11_N_SUPPORT
+ HTParametersHook(pAd, tmpbuf, buffer);
+#endif // DOT11_N_SUPPORT //
+
+
+#ifdef CARRIER_DETECTION_SUPPORT
+ //CarrierDetect
+ if(RTMPGetKeyParameter("CarrierDetect", tmpbuf, 128, buffer))
+ {
+ if ((strncmp(tmpbuf, "0", 1) == 0))
+ pAd->CommonCfg.CarrierDetect.Enable = FALSE;
+ else if ((strncmp(tmpbuf, "1", 1) == 0))
+ pAd->CommonCfg.CarrierDetect.Enable = TRUE;
+ else
+ pAd->CommonCfg.CarrierDetect.Enable = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CarrierDetect.Enable=%d\n", pAd->CommonCfg.CarrierDetect.Enable));
+ }
+ else
+ pAd->CommonCfg.CarrierDetect.Enable = FALSE;
+#endif // CARRIER_DETECTION_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ //PSMode
+ if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer))
+ {
+ if (pAd->StaCfg.BssType == BSS_INFRA)
+ {
+ if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0))
+ {
+ // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+ // to exclude certain situations.
+ // MlmeSetPsm(pAd, PWR_SAVE);
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+ if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
+ pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
+ pAd->StaCfg.DefaultListenCount = 5;
+ }
+ else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0)
+ || (strcmp(tmpbuf, "FAST_PSP") == 0))
+ {
+ // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+ // to exclude certain situations.
+ // MlmeSetPsmBit(pAd, PWR_SAVE);
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+ if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
+ pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
+ pAd->StaCfg.DefaultListenCount = 3;
+ }
+ else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0)
+ || (strcmp(tmpbuf, "LEGACY_PSP") == 0))
+ {
+ // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+ // to exclude certain situations.
+ // MlmeSetPsmBit(pAd, PWR_SAVE);
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+ if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
+ pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
+ pAd->StaCfg.DefaultListenCount = 3;
+ }
+ else
+ { //Default Ndis802_11PowerModeCAM
+ // clear PSM bit immediately
+ MlmeSetPsmBit(pAd, PWR_ACTIVE);
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+ if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
+ pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
+ }
+ }
+ // FastRoaming
+ if (RTMPGetKeyParameter("FastRoaming", tmpbuf, 32, buffer))
+ {
+ if (simple_strtol(tmpbuf, 0, 10) == 0)
+ pAd->StaCfg.bFastRoaming = FALSE;
+ else
+ pAd->StaCfg.bFastRoaming = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("FastRoaming=%d\n", pAd->StaCfg.bFastRoaming));
+ }
+ // RoamThreshold
+ if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, buffer))
+ {
+ long lInfo = simple_strtol(tmpbuf, 0, 10);
+
+ if (lInfo > 90 || lInfo < 60)
+ pAd->StaCfg.dBmToRoam = -70;
+ else
+ pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d dBm\n", pAd->StaCfg.dBmToRoam));
+ }
+
+ if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) == 0)
+ pAd->StaCfg.bTGnWifiTest = FALSE;
+ else
+ pAd->StaCfg.bTGnWifiTest = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef RT30xx
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if(RTMPGetKeyParameter("AntDiversity", tmpbuf, 10, buffer))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if(simple_strtol(macptr, 0, 10) != 0) //Enable
+ pAd->CommonCfg.bRxAntDiversity = TRUE;
+ else //Disable
+ pAd->CommonCfg.bRxAntDiversity = FALSE;
+
+ DBGPRINT(RT_DEBUG_ERROR, ("AntDiversity=%d\n", pAd->CommonCfg.bRxAntDiversity));
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT30xx //
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> %s does not have a write method\n", src));
+ }
+
+ retval=filp_close(srcf,NULL);
+
+ if (retval)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
+ }
+ }
+ }
+
+ set_fs(orgfs);
+#if 0
+ current->fsuid = orgfsuid;
+ current->fsgid = orgfsgid;
+#endif
+
+ kfree(buffer);
+ kfree(tmpbuf);
+
+ return (NDIS_STATUS_SUCCESS);
+}
+
+#ifdef DOT11_N_SUPPORT
+static void HTParametersHook(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR *pValueStr,
+ IN CHAR *pInput)
+{
+
+ INT Value;
+
+ if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.bHTProtect = FALSE;
+ }
+ else
+ {
+ pAd->CommonCfg.bHTProtect = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+ if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.bMIMOPSEnable = FALSE;
+ }
+ else
+ {
+ pAd->CommonCfg.bMIMOPSEnable = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+
+ if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value > MMPS_ENABLE)
+ {
+ pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
+ }
+ else
+ {
+ //TODO: add mimo power saving mechanism
+ pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
+ //pAd->CommonCfg.BACapability.field.MMPSmode = Value;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode = %d\n", Value));
+ }
+
+ if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.bBADecline = FALSE;
+ }
+ else
+ {
+ pAd->CommonCfg.bBADecline = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+
+ if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.bDisableReordering = FALSE;
+ }
+ else
+ {
+ pAd->CommonCfg.bDisableReordering = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+ if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
+ pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
+ }
+ else
+ {
+ pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
+ pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
+ }
+ pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
+ pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+ // Tx_+HTC frame
+ if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->HTCEnable = FALSE;
+ }
+ else
+ {
+ pAd->HTCEnable = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+ // Enable HT Link Adaptation Control
+ if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->bLinkAdapt = FALSE;
+ }
+ else
+ {
+ pAd->HTCEnable = TRUE;
+ pAd->bLinkAdapt = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
+ }
+
+ // Reverse Direction Mechanism
+ if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.bRdg = FALSE;
+ }
+ else
+ {
+ pAd->HTCEnable = TRUE;
+ pAd->CommonCfg.bRdg = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
+ }
+
+
+
+
+ // Tx A-MSUD ?
+ if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
+ }
+ else
+ {
+ pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+ // MPDU Density
+ if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value <=7 && Value >= 0)
+ {
+ pAd->CommonCfg.BACapability.field.MpduDensity = Value;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", Value));
+ }
+ else
+ {
+ pAd->CommonCfg.BACapability.field.MpduDensity = 4;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4));
+ }
+ }
+
+ // Max Rx BA Window Size
+ if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+
+ if (Value >=1 && Value <= 64)
+ {
+ pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
+ pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", Value));
+ }
+ else
+ {
+ pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
+ pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n"));
+ }
+
+ }
+
+ // Guard Interval
+ if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+
+ if (Value == GI_400)
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
+ }
+ else
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" ));
+ }
+
+ // HT Operation Mode : Mixed Mode , Green Field
+ if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+
+ if (Value == HTMODE_GF)
+ {
+
+ pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF;
+ }
+ else
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" ));
+ }
+
+ // Fixed Tx mode : CCK, OFDM
+ if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput))
+ {
+ UCHAR fix_tx_mode;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ fix_tx_mode = FIXED_TXMODE_HT;
+
+ if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0)
+ {
+ fix_tx_mode = FIXED_TXMODE_OFDM;
+ }
+ else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0)
+ {
+ fix_tx_mode = FIXED_TXMODE_CCK;
+ }
+ else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0)
+ {
+ fix_tx_mode = FIXED_TXMODE_HT;
+ }
+ else
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ // 1 : CCK
+ // 2 : OFDM
+ // otherwise : HT
+ if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM)
+ fix_tx_mode = Value;
+ else
+ fix_tx_mode = FIXED_TXMODE_HT;
+ }
+
+ pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
+ DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode));
+
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+
+ // Channel Width
+ if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+
+ if (Value == BW_40)
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+ }
+ else
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ }
+
+#ifdef MCAST_RATE_SPECIFIC
+ pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW;
+#endif // MCAST_RATE_SPECIFIC //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" ));
+ }
+
+ if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+
+ if (Value == 0)
+ {
+
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
+ }
+ else
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" ));
+ }
+
+ // MSC
+ if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput))
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+
+// if ((Value >= 0 && Value <= 15) || (Value == 32))
+ if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3
+ {
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = Value;
+ pAd->StaCfg.bAutoTxRateSwitch = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS));
+ }
+ else
+ {
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ pAd->StaCfg.bAutoTxRateSwitch = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n"));
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ // STBC
+ if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == STBC_USE)
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
+ }
+ else
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC));
+ }
+
+ // 40_Mhz_Intolerant
+ if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE;
+ }
+ else
+ {
+ pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant));
+ }
+ //HT_TxStream
+ if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput))
+ {
+ switch (simple_strtol(pValueStr, 0, 10))
+ {
+ case 1:
+ pAd->CommonCfg.TxStream = 1;
+ break;
+ case 2:
+ pAd->CommonCfg.TxStream = 2;
+ break;
+ case 3: // 3*3
+ default:
+ pAd->CommonCfg.TxStream = 3;
+
+ if (pAd->MACVersion < RALINK_2883_VERSION)
+ pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream));
+ }
+ //HT_RxStream
+ if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput))
+ {
+ switch (simple_strtol(pValueStr, 0, 10))
+ {
+ case 1:
+ pAd->CommonCfg.RxStream = 1;
+ break;
+ case 2:
+ pAd->CommonCfg.RxStream = 2;
+ break;
+ case 3:
+ default:
+ pAd->CommonCfg.RxStream = 3;
+
+ if (pAd->MACVersion < RALINK_2883_VERSION)
+ pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream));
+ }
+
+}
+#endif // DOT11_N_SUPPORT //
+
diff --git a/drivers/staging/rt3070/rtmp.h b/drivers/staging/rt3070/rtmp.h
new file mode 100644
index 00000000000..d80d74ffbc8
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp.h
@@ -0,0 +1,7728 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp.h
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 2002-08-01 created
+ James Tan 2002-09-06 modified (Revise NTCRegTable)
+ John Chang 2004-09-06 modified for RT2600
+*/
+#ifndef __RTMP_H__
+#define __RTMP_H__
+
+#include "link_list.h"
+#include "spectrum_def.h"
+
+#ifdef MLME_EX
+#include "mlme_ex_def.h"
+#endif // MLME_EX //
+
+#ifdef CONFIG_STA_SUPPORT
+#include "aironet.h"
+#endif // CONFIG_STA_SUPPORT //
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+
+
+
+
+
+//#define DBG 1
+
+//#define DBG_DIAGNOSE 1
+
+#if defined(CONFIG_AP_SUPPORT) && defined(CONFIG_STA_SUPPORT)
+#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd) if(_pAd->OpMode == OPMODE_AP)
+#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd) if(_pAd->OpMode == OPMODE_STA)
+#else
+#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd)
+#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd)
+#endif
+
+#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++)
+#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--)
+#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt)
+
+#ifdef RT2870
+////////////////////////////////////////////////////////////////////////////
+// The TX_BUFFER structure forms the transmitted USB packet to the device
+////////////////////////////////////////////////////////////////////////////
+typedef struct __TX_BUFFER{
+ union {
+ UCHAR WirelessPacket[TX_BUFFER_NORMSIZE];
+ HEADER_802_11 NullFrame;
+ PSPOLL_FRAME PsPollPacket;
+ RTS_FRAME RTSFrame;
+ }field;
+ UCHAR Aggregation[4]; //Buffer for save Aggregation size.
+} TX_BUFFER, *PTX_BUFFER;
+
+typedef struct __HTTX_BUFFER{
+ union {
+ UCHAR WirelessPacket[MAX_TXBULK_SIZE];
+ HEADER_802_11 NullFrame;
+ PSPOLL_FRAME PsPollPacket;
+ RTS_FRAME RTSFrame;
+ }field;
+ UCHAR Aggregation[4]; //Buffer for save Aggregation size.
+} HTTX_BUFFER, *PHTTX_BUFFER;
+
+
+// used to track driver-generated write irps
+typedef struct _TX_CONTEXT
+{
+ PVOID pAd; //Initialized in MiniportInitialize
+ PURB pUrb; //Initialized in MiniportInitialize
+ PIRP pIrp; //used to cancel pending bulk out.
+ //Initialized in MiniportInitialize
+ PTX_BUFFER TransferBuffer; //Initialized in MiniportInitialize
+ ULONG BulkOutSize;
+ UCHAR BulkOutPipeId;
+ UCHAR SelfIdx;
+ BOOLEAN InUse;
+ BOOLEAN bWaitingBulkOut; // at least one packet is in this TxContext, ready for making IRP anytime.
+ BOOLEAN bFullForBulkOut; // all tx buffer are full , so waiting for tx bulkout.
+ BOOLEAN IRPPending;
+ BOOLEAN LastOne;
+ BOOLEAN bAggregatible;
+ UCHAR Header_802_3[LENGTH_802_3];
+ UCHAR Rsv[2];
+ ULONG DataOffset;
+ UINT TxRate;
+ dma_addr_t data_dma; // urb dma on linux
+
+} TX_CONTEXT, *PTX_CONTEXT, **PPTX_CONTEXT;
+
+
+// used to track driver-generated write irps
+typedef struct _HT_TX_CONTEXT
+{
+ PVOID pAd; //Initialized in MiniportInitialize
+ PURB pUrb; //Initialized in MiniportInitialize
+ PIRP pIrp; //used to cancel pending bulk out.
+ //Initialized in MiniportInitialize
+ PHTTX_BUFFER TransferBuffer; //Initialized in MiniportInitialize
+ ULONG BulkOutSize; // Indicate the total bulk-out size in bytes in one bulk-transmission
+ UCHAR BulkOutPipeId;
+ BOOLEAN IRPPending;
+ BOOLEAN LastOne;
+ BOOLEAN bCurWriting;
+ BOOLEAN bRingEmpty;
+ BOOLEAN bCopySavePad;
+ UCHAR SavedPad[8];
+ UCHAR Header_802_3[LENGTH_802_3];
+ ULONG CurWritePosition; // Indicate the buffer offset which packet will be inserted start from.
+ ULONG CurWriteRealPos; // Indicate the buffer offset which packet now are writing to.
+ ULONG NextBulkOutPosition; // Indicate the buffer start offset of a bulk-transmission
+ ULONG ENextBulkOutPosition; // Indicate the buffer end offset of a bulk-transmission
+ UINT TxRate;
+ dma_addr_t data_dma; // urb dma on linux
+} HT_TX_CONTEXT, *PHT_TX_CONTEXT, **PPHT_TX_CONTEXT;
+
+
+//
+// Structure to keep track of receive packets and buffers to indicate
+// receive data to the protocol.
+//
+typedef struct _RX_CONTEXT
+{
+ PUCHAR TransferBuffer;
+ PVOID pAd;
+ PIRP pIrp;//used to cancel pending bulk in.
+ PURB pUrb;
+ //These 2 Boolean shouldn't both be 1 at the same time.
+ ULONG BulkInOffset; // number of packets waiting for reordering .
+// BOOLEAN ReorderInUse; // At least one packet in this buffer are in reordering buffer and wait for receive indication
+ BOOLEAN bRxHandling; // Notify this packet is being process now.
+ BOOLEAN InUse; // USB Hardware Occupied. Wait for USB HW to put packet.
+ BOOLEAN Readable; // Receive Complete back. OK for driver to indicate receiving packet.
+ BOOLEAN IRPPending; // TODO: To be removed
+ atomic_t IrpLock;
+ NDIS_SPIN_LOCK RxContextLock;
+ dma_addr_t data_dma; // urb dma on linux
+} RX_CONTEXT, *PRX_CONTEXT;
+#endif // RT2870 //
+
+
+//
+// NDIS Version definitions
+//
+#ifdef NDIS50_MINIPORT
+#define RTMP_NDIS_MAJOR_VERSION 5
+#define RTMP_NDIS_MINOR_VERSION 0
+#endif
+
+#ifdef NDIS51_MINIPORT
+#define RTMP_NDIS_MAJOR_VERSION 5
+#define RTMP_NDIS_MINOR_VERSION 1
+#endif
+
+extern char NIC_VENDOR_DESC[];
+extern int NIC_VENDOR_DESC_LEN;
+
+extern unsigned char SNAP_AIRONET[];
+extern unsigned char CipherSuiteCiscoCCKM[];
+extern unsigned char CipherSuiteCiscoCCKMLen;
+extern unsigned char CipherSuiteCiscoCCKM24[];
+extern unsigned char CipherSuiteCiscoCCKM24Len;
+extern unsigned char CipherSuiteCCXTkip[];
+extern unsigned char CipherSuiteCCXTkipLen;
+extern unsigned char CISCO_OUI[];
+extern UCHAR BaSizeArray[4];
+
+extern UCHAR BROADCAST_ADDR[MAC_ADDR_LEN];
+extern UCHAR MULTICAST_ADDR[MAC_ADDR_LEN];
+extern UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN];
+extern ULONG BIT32[32];
+extern UCHAR BIT8[8];
+extern char* CipherName[];
+extern char* MCSToMbps[];
+extern UCHAR RxwiMCSToOfdmRate[12];
+extern UCHAR SNAP_802_1H[6];
+extern UCHAR SNAP_BRIDGE_TUNNEL[6];
+extern UCHAR SNAP_AIRONET[8];
+extern UCHAR CKIP_LLC_SNAP[8];
+extern UCHAR EAPOL_LLC_SNAP[8];
+extern UCHAR EAPOL[2];
+extern UCHAR IPX[2];
+extern UCHAR APPLE_TALK[2];
+extern UCHAR RateIdToPlcpSignal[12]; // see IEEE802.11a-1999 p.14
+extern UCHAR OfdmRateToRxwiMCS[];
+extern UCHAR OfdmSignalToRateId[16] ;
+extern UCHAR default_cwmin[4];
+extern UCHAR default_cwmax[4];
+extern UCHAR default_sta_aifsn[4];
+extern UCHAR MapUserPriorityToAccessCategory[8];
+
+extern USHORT RateUpPER[];
+extern USHORT RateDownPER[];
+extern UCHAR Phy11BNextRateDownward[];
+extern UCHAR Phy11BNextRateUpward[];
+extern UCHAR Phy11BGNextRateDownward[];
+extern UCHAR Phy11BGNextRateUpward[];
+extern UCHAR Phy11ANextRateDownward[];
+extern UCHAR Phy11ANextRateUpward[];
+extern CHAR RssiSafeLevelForTxRate[];
+extern UCHAR RateIdToMbps[];
+extern USHORT RateIdTo500Kbps[];
+
+extern UCHAR CipherSuiteWpaNoneTkip[];
+extern UCHAR CipherSuiteWpaNoneTkipLen;
+
+extern UCHAR CipherSuiteWpaNoneAes[];
+extern UCHAR CipherSuiteWpaNoneAesLen;
+
+extern UCHAR SsidIe;
+extern UCHAR SupRateIe;
+extern UCHAR ExtRateIe;
+
+#ifdef DOT11_N_SUPPORT
+extern UCHAR HtCapIe;
+extern UCHAR AddHtInfoIe;
+extern UCHAR NewExtChanIe;
+#ifdef DOT11N_DRAFT3
+extern UCHAR ExtHtCapIe;
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+extern UCHAR ErpIe;
+extern UCHAR DsIe;
+extern UCHAR TimIe;
+extern UCHAR WpaIe;
+extern UCHAR Wpa2Ie;
+extern UCHAR IbssIe;
+extern UCHAR Ccx2Ie;
+extern UCHAR WapiIe;
+
+extern UCHAR WPA_OUI[];
+extern UCHAR RSN_OUI[];
+extern UCHAR WAPI_OUI[];
+extern UCHAR WME_INFO_ELEM[];
+extern UCHAR WME_PARM_ELEM[];
+extern UCHAR Ccx2QosInfo[];
+extern UCHAR Ccx2IeInfo[];
+extern UCHAR RALINK_OUI[];
+extern UCHAR PowerConstraintIE[];
+
+
+extern UCHAR RateSwitchTable[];
+extern UCHAR RateSwitchTable11B[];
+extern UCHAR RateSwitchTable11G[];
+extern UCHAR RateSwitchTable11BG[];
+
+#ifdef DOT11_N_SUPPORT
+extern UCHAR RateSwitchTable11BGN1S[];
+extern UCHAR RateSwitchTable11BGN2S[];
+extern UCHAR RateSwitchTable11BGN2SForABand[];
+extern UCHAR RateSwitchTable11N1S[];
+extern UCHAR RateSwitchTable11N2S[];
+extern UCHAR RateSwitchTable11N2SForABand[];
+
+#ifdef CONFIG_STA_SUPPORT
+extern UCHAR PRE_N_HT_OUI[];
+#endif // CONFIG_STA_SUPPORT //
+#endif // DOT11_N_SUPPORT //
+
+#define MAXSEQ (0xFFF)
+
+#ifdef RALINK_ATE
+typedef struct _ATE_INFO {
+ UCHAR Mode;
+ CHAR TxPower0;
+ CHAR TxPower1;
+ CHAR TxAntennaSel;
+ CHAR RxAntennaSel;
+ TXWI_STRUC TxWI; // TXWI
+ USHORT QID;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ UCHAR Addr3[MAC_ADDR_LEN];
+ UCHAR Channel;
+ UINT32 TxLength;
+ UINT32 TxCount;
+ UINT32 TxDoneCount; // Tx DMA Done
+ UINT32 RFFreqOffset;
+ BOOLEAN bRxFer;
+ BOOLEAN bQATxStart; // Have compiled QA in and use it to ATE tx.
+ BOOLEAN bQARxStart; // Have compiled QA in and use it to ATE rx.
+ UINT32 RxTotalCnt;
+ UINT32 RxCntPerSec;
+
+ CHAR LastSNR0; // last received SNR
+ CHAR LastSNR1; // last received SNR for 2nd antenna
+ CHAR LastRssi0; // last received RSSI
+ CHAR LastRssi1; // last received RSSI for 2nd antenna
+ CHAR LastRssi2; // last received RSSI for 3rd antenna
+ CHAR AvgRssi0; // last 8 frames' average RSSI
+ CHAR AvgRssi1; // last 8 frames' average RSSI
+ CHAR AvgRssi2; // last 8 frames' average RSSI
+ SHORT AvgRssi0X8; // sum of last 8 frames' RSSI
+ SHORT AvgRssi1X8; // sum of last 8 frames' RSSI
+ SHORT AvgRssi2X8; // sum of last 8 frames' RSSI
+
+ UINT32 NumOfAvgRssiSample;
+
+#ifdef RALINK_28xx_QA
+ // Tx frame
+#ifdef RT2870
+ /* not used in RT2860 */
+ TXINFO_STRUC TxInfo; // TxInfo
+#endif // RT2870 //
+ USHORT HLen; // Header Length
+ USHORT PLen; // Pattern Length
+ UCHAR Header[32]; // Header buffer
+ UCHAR Pattern[32]; // Pattern buffer
+ USHORT DLen; // Data Length
+ USHORT seq;
+ UINT32 CID;
+ pid_t AtePid;
+ // counters
+ UINT32 U2M;
+ UINT32 OtherData;
+ UINT32 Beacon;
+ UINT32 OtherCount;
+ UINT32 TxAc0;
+ UINT32 TxAc1;
+ UINT32 TxAc2;
+ UINT32 TxAc3;
+ UINT32 TxHCCA;
+ UINT32 TxMgmt;
+ UINT32 RSSI0;
+ UINT32 RSSI1;
+ UINT32 RSSI2;
+ UINT32 SNR0;
+ UINT32 SNR1;
+ // control
+ //UINT32 Repeat; // Tx Cpu count
+ UCHAR TxStatus; // task Tx status // 0 --> task is idle, 1 --> task is running
+#endif // RALINK_28xx_QA //
+} ATE_INFO, *PATE_INFO;
+
+#ifdef RALINK_28xx_QA
+struct ate_racfghdr {
+ UINT32 magic_no;
+ USHORT command_type;
+ USHORT command_id;
+ USHORT length;
+ USHORT sequence;
+ USHORT status;
+ UCHAR data[2046];
+} __attribute__((packed));
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+#ifdef DOT11_N_SUPPORT
+struct reordering_mpdu
+{
+ struct reordering_mpdu *next;
+ PNDIS_PACKET pPacket; /* coverted to 802.3 frame */
+ int Sequence; /* sequence number of MPDU */
+ BOOLEAN bAMSDU;
+};
+
+struct reordering_list
+{
+ struct reordering_mpdu *next;
+ int qlen;
+};
+
+struct reordering_mpdu_pool
+{
+ PVOID mem;
+ NDIS_SPIN_LOCK lock;
+ struct reordering_list freelist;
+};
+#endif // DOT11_N_SUPPORT //
+
+typedef struct _RSSI_SAMPLE {
+ CHAR LastRssi0; // last received RSSI
+ CHAR LastRssi1; // last received RSSI
+ CHAR LastRssi2; // last received RSSI
+ CHAR AvgRssi0;
+ CHAR AvgRssi1;
+ CHAR AvgRssi2;
+ SHORT AvgRssi0X8;
+ SHORT AvgRssi1X8;
+ SHORT AvgRssi2X8;
+} RSSI_SAMPLE;
+
+//
+// Queue structure and macros
+//
+typedef struct _QUEUE_ENTRY {
+ struct _QUEUE_ENTRY *Next;
+} QUEUE_ENTRY, *PQUEUE_ENTRY;
+
+// Queue structure
+typedef struct _QUEUE_HEADER {
+ PQUEUE_ENTRY Head;
+ PQUEUE_ENTRY Tail;
+ ULONG Number;
+} QUEUE_HEADER, *PQUEUE_HEADER;
+
+#define InitializeQueueHeader(QueueHeader) \
+{ \
+ (QueueHeader)->Head = (QueueHeader)->Tail = NULL; \
+ (QueueHeader)->Number = 0; \
+}
+
+#define RemoveHeadQueue(QueueHeader) \
+(QueueHeader)->Head; \
+{ \
+ PQUEUE_ENTRY pNext; \
+ if ((QueueHeader)->Head != NULL) \
+ { \
+ pNext = (QueueHeader)->Head->Next; \
+ (QueueHeader)->Head = pNext; \
+ if (pNext == NULL) \
+ (QueueHeader)->Tail = NULL; \
+ (QueueHeader)->Number--; \
+ } \
+}
+
+#define InsertHeadQueue(QueueHeader, QueueEntry) \
+{ \
+ ((PQUEUE_ENTRY)QueueEntry)->Next = (QueueHeader)->Head; \
+ (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \
+ if ((QueueHeader)->Tail == NULL) \
+ (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \
+ (QueueHeader)->Number++; \
+}
+
+#define InsertTailQueue(QueueHeader, QueueEntry) \
+{ \
+ ((PQUEUE_ENTRY)QueueEntry)->Next = NULL; \
+ if ((QueueHeader)->Tail) \
+ (QueueHeader)->Tail->Next = (PQUEUE_ENTRY)(QueueEntry); \
+ else \
+ (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \
+ (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \
+ (QueueHeader)->Number++; \
+}
+
+//
+// Macros for flag and ref count operations
+//
+#define RTMP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F))
+#define RTMP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F))
+#define RTMP_CLEAR_FLAGS(_M) ((_M)->Flags = 0)
+#define RTMP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0)
+#define RTMP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F))
+
+#define OPSTATUS_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags |= (_F))
+#define OPSTATUS_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F))
+#define OPSTATUS_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0)
+
+#define CLIENT_STATUS_SET_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags |= (_F))
+#define CLIENT_STATUS_CLEAR_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags &= ~(_F))
+#define CLIENT_STATUS_TEST_FLAG(_pEntry,_F) (((_pEntry)->ClientStatusFlags & (_F)) != 0)
+
+#define RX_FILTER_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter |= (_F))
+#define RX_FILTER_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter &= ~(_F))
+#define RX_FILTER_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.PacketFilter & (_F)) != 0)
+
+#ifdef CONFIG_STA_SUPPORT
+#define STA_NO_SECURITY_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
+#define STA_WEP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
+#define STA_TKIP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
+#define STA_AES_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+
+#define STA_TGN_WIFI_ON(_p) (_p->StaCfg.bTGnWifiTest == TRUE)
+#endif // CONFIG_STA_SUPPORT //
+
+#define CKIP_KP_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x10) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
+#define CKIP_CMIC_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x08) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
+
+
+#define INC_RING_INDEX(_idx, _RingSize) \
+{ \
+ (_idx) = (_idx+1) % (_RingSize); \
+}
+
+// We will have a cost down version which mac version is 0x3090xxxx
+#define IS_RT3090(_pAd) ((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (((_pAd)->MACVersion & 0xffff0000) == 0x30900000))
+
+#define IS_RT3070(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30700000)
+#define IS_RT3071(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30710000)
+#define IS_RT2070(_pAd) (((_pAd)->RfIcType == RFIC_2020) || ((_pAd)->EFuseTag == 0x27))
+
+#define IS_RT30xx(_pAd) (((_pAd)->MACVersion & 0xfff00000) == 0x30700000)
+
+#define RING_PACKET_INIT(_TxRing, _idx) \
+{ \
+ _TxRing->Cell[_idx].pNdisPacket = NULL; \
+ _TxRing->Cell[_idx].pNextNdisPacket = NULL; \
+}
+
+#define TXDT_INIT(_TxD) \
+{ \
+ NdisZeroMemory(_TxD, TXD_SIZE); \
+ _TxD->DMADONE = 1; \
+}
+
+//Set last data segment
+#define RING_SET_LASTDS(_TxD, _IsSD0) \
+{ \
+ if (_IsSD0) {_TxD->LastSec0 = 1;} \
+ else {_TxD->LastSec1 = 1;} \
+}
+
+// Increase TxTsc value for next transmission
+// TODO:
+// When i==6, means TSC has done one full cycle, do re-keying stuff follow specs
+// Should send a special event microsoft defined to request re-key
+#define INC_TX_TSC(_tsc) \
+{ \
+ int i=0; \
+ while (++_tsc[i] == 0x0) \
+ { \
+ i++; \
+ if (i == 6) \
+ break; \
+ } \
+}
+
+#ifdef DOT11_N_SUPPORT
+// StaActive.SupportedHtPhy.MCSSet is copied from AP beacon. Don't need to update here.
+#define COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
+{ \
+ _pAd->StaActive.SupportedHtPhy.ChannelWidth = _pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth; \
+ _pAd->StaActive.SupportedHtPhy.MimoPs = _pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs; \
+ _pAd->StaActive.SupportedHtPhy.GF = _pAd->MlmeAux.HtCapability.HtCapInfo.GF; \
+ _pAd->StaActive.SupportedHtPhy.ShortGIfor20 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20; \
+ _pAd->StaActive.SupportedHtPhy.ShortGIfor40 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40; \
+ _pAd->StaActive.SupportedHtPhy.TxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC; \
+ _pAd->StaActive.SupportedHtPhy.RxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC; \
+ _pAd->StaActive.SupportedHtPhy.ExtChanOffset = _pAd->MlmeAux.AddHtInfo.AddHtInfo.ExtChanOffset; \
+ _pAd->StaActive.SupportedHtPhy.RecomWidth = _pAd->MlmeAux.AddHtInfo.AddHtInfo.RecomWidth; \
+ _pAd->StaActive.SupportedHtPhy.OperaionMode = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode; \
+ _pAd->StaActive.SupportedHtPhy.NonGfPresent = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent; \
+ NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(UCHAR) * 16);\
+}
+
+#define COPY_AP_HTSETTINGS_FROM_BEACON(_pAd, _pHtCapability) \
+{ \
+ _pAd->MacTab.Content[BSSID_WCID].AMsduSize = (UCHAR)(_pHtCapability->HtCapInfo.AMsduSize); \
+ _pAd->MacTab.Content[BSSID_WCID].MmpsMode= (UCHAR)(_pHtCapability->HtCapInfo.MimoPs); \
+ _pAd->MacTab.Content[BSSID_WCID].MaxRAmpduFactor = (UCHAR)(_pHtCapability->HtCapParm.MaxRAmpduFactor); \
+}
+#endif // DOT11_N_SUPPORT //
+
+//
+// MACRO for 32-bit PCI register read / write
+//
+// Usage : RTMP_IO_READ32(
+// PRTMP_ADAPTER pAd,
+// ULONG Register_Offset,
+// PULONG pValue)
+//
+// RTMP_IO_WRITE32(
+// PRTMP_ADAPTER pAd,
+// ULONG Register_Offset,
+// ULONG Value)
+//
+
+//
+// BBP & RF are using indirect access. Before write any value into it.
+// We have to make sure there is no outstanding command pending via checking busy bit.
+//
+#define MAX_BUSY_COUNT 100 // Number of retry before failing access BBP & RF indirect register
+//
+
+#ifdef RT2870
+#define RTMP_RF_IO_WRITE32(_A, _V) RTUSBWriteRFRegister(_A, _V)
+#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV)
+#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V)
+
+#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V)
+#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV)
+#endif // RT2870 //
+
+#ifdef RT30xx
+#define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RT30xxReadRFRegister(_A, _I, _pV)
+#define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RT30xxWriteRFRegister(_A, _I, _V)
+#endif // RT30xx //
+
+#define MAP_CHANNEL_ID_TO_KHZ(ch, khz) { \
+ switch (ch) \
+ { \
+ case 1: khz = 2412000; break; \
+ case 2: khz = 2417000; break; \
+ case 3: khz = 2422000; break; \
+ case 4: khz = 2427000; break; \
+ case 5: khz = 2432000; break; \
+ case 6: khz = 2437000; break; \
+ case 7: khz = 2442000; break; \
+ case 8: khz = 2447000; break; \
+ case 9: khz = 2452000; break; \
+ case 10: khz = 2457000; break; \
+ case 11: khz = 2462000; break; \
+ case 12: khz = 2467000; break; \
+ case 13: khz = 2472000; break; \
+ case 14: khz = 2484000; break; \
+ case 36: /* UNII */ khz = 5180000; break; \
+ case 40: /* UNII */ khz = 5200000; break; \
+ case 44: /* UNII */ khz = 5220000; break; \
+ case 48: /* UNII */ khz = 5240000; break; \
+ case 52: /* UNII */ khz = 5260000; break; \
+ case 56: /* UNII */ khz = 5280000; break; \
+ case 60: /* UNII */ khz = 5300000; break; \
+ case 64: /* UNII */ khz = 5320000; break; \
+ case 149: /* UNII */ khz = 5745000; break; \
+ case 153: /* UNII */ khz = 5765000; break; \
+ case 157: /* UNII */ khz = 5785000; break; \
+ case 161: /* UNII */ khz = 5805000; break; \
+ case 165: /* UNII */ khz = 5825000; break; \
+ case 100: /* HiperLAN2 */ khz = 5500000; break; \
+ case 104: /* HiperLAN2 */ khz = 5520000; break; \
+ case 108: /* HiperLAN2 */ khz = 5540000; break; \
+ case 112: /* HiperLAN2 */ khz = 5560000; break; \
+ case 116: /* HiperLAN2 */ khz = 5580000; break; \
+ case 120: /* HiperLAN2 */ khz = 5600000; break; \
+ case 124: /* HiperLAN2 */ khz = 5620000; break; \
+ case 128: /* HiperLAN2 */ khz = 5640000; break; \
+ case 132: /* HiperLAN2 */ khz = 5660000; break; \
+ case 136: /* HiperLAN2 */ khz = 5680000; break; \
+ case 140: /* HiperLAN2 */ khz = 5700000; break; \
+ case 34: /* Japan MMAC */ khz = 5170000; break; \
+ case 38: /* Japan MMAC */ khz = 5190000; break; \
+ case 42: /* Japan MMAC */ khz = 5210000; break; \
+ case 46: /* Japan MMAC */ khz = 5230000; break; \
+ case 184: /* Japan */ khz = 4920000; break; \
+ case 188: /* Japan */ khz = 4940000; break; \
+ case 192: /* Japan */ khz = 4960000; break; \
+ case 196: /* Japan */ khz = 4980000; break; \
+ case 208: /* Japan, means J08 */ khz = 5040000; break; \
+ case 212: /* Japan, means J12 */ khz = 5060000; break; \
+ case 216: /* Japan, means J16 */ khz = 5080000; break; \
+ default: khz = 2412000; break; \
+ } \
+ }
+
+#define MAP_KHZ_TO_CHANNEL_ID(khz, ch) { \
+ switch (khz) \
+ { \
+ case 2412000: ch = 1; break; \
+ case 2417000: ch = 2; break; \
+ case 2422000: ch = 3; break; \
+ case 2427000: ch = 4; break; \
+ case 2432000: ch = 5; break; \
+ case 2437000: ch = 6; break; \
+ case 2442000: ch = 7; break; \
+ case 2447000: ch = 8; break; \
+ case 2452000: ch = 9; break; \
+ case 2457000: ch = 10; break; \
+ case 2462000: ch = 11; break; \
+ case 2467000: ch = 12; break; \
+ case 2472000: ch = 13; break; \
+ case 2484000: ch = 14; break; \
+ case 5180000: ch = 36; /* UNII */ break; \
+ case 5200000: ch = 40; /* UNII */ break; \
+ case 5220000: ch = 44; /* UNII */ break; \
+ case 5240000: ch = 48; /* UNII */ break; \
+ case 5260000: ch = 52; /* UNII */ break; \
+ case 5280000: ch = 56; /* UNII */ break; \
+ case 5300000: ch = 60; /* UNII */ break; \
+ case 5320000: ch = 64; /* UNII */ break; \
+ case 5745000: ch = 149; /* UNII */ break; \
+ case 5765000: ch = 153; /* UNII */ break; \
+ case 5785000: ch = 157; /* UNII */ break; \
+ case 5805000: ch = 161; /* UNII */ break; \
+ case 5825000: ch = 165; /* UNII */ break; \
+ case 5500000: ch = 100; /* HiperLAN2 */ break; \
+ case 5520000: ch = 104; /* HiperLAN2 */ break; \
+ case 5540000: ch = 108; /* HiperLAN2 */ break; \
+ case 5560000: ch = 112; /* HiperLAN2 */ break; \
+ case 5580000: ch = 116; /* HiperLAN2 */ break; \
+ case 5600000: ch = 120; /* HiperLAN2 */ break; \
+ case 5620000: ch = 124; /* HiperLAN2 */ break; \
+ case 5640000: ch = 128; /* HiperLAN2 */ break; \
+ case 5660000: ch = 132; /* HiperLAN2 */ break; \
+ case 5680000: ch = 136; /* HiperLAN2 */ break; \
+ case 5700000: ch = 140; /* HiperLAN2 */ break; \
+ case 5170000: ch = 34; /* Japan MMAC */ break; \
+ case 5190000: ch = 38; /* Japan MMAC */ break; \
+ case 5210000: ch = 42; /* Japan MMAC */ break; \
+ case 5230000: ch = 46; /* Japan MMAC */ break; \
+ case 4920000: ch = 184; /* Japan */ break; \
+ case 4940000: ch = 188; /* Japan */ break; \
+ case 4960000: ch = 192; /* Japan */ break; \
+ case 4980000: ch = 196; /* Japan */ break; \
+ case 5040000: ch = 208; /* Japan, means J08 */ break; \
+ case 5060000: ch = 212; /* Japan, means J12 */ break; \
+ case 5080000: ch = 216; /* Japan, means J16 */ break; \
+ default: ch = 1; break; \
+ } \
+ }
+
+//
+// Common fragment list structure - Identical to the scatter gather frag list structure
+//
+//#define RTMP_SCATTER_GATHER_ELEMENT SCATTER_GATHER_ELEMENT
+//#define PRTMP_SCATTER_GATHER_ELEMENT PSCATTER_GATHER_ELEMENT
+#define NIC_MAX_PHYS_BUF_COUNT 8
+
+typedef struct _RTMP_SCATTER_GATHER_ELEMENT {
+ PVOID Address;
+ ULONG Length;
+ PULONG Reserved;
+} RTMP_SCATTER_GATHER_ELEMENT, *PRTMP_SCATTER_GATHER_ELEMENT;
+
+
+typedef struct _RTMP_SCATTER_GATHER_LIST {
+ ULONG NumberOfElements;
+ PULONG Reserved;
+ RTMP_SCATTER_GATHER_ELEMENT Elements[NIC_MAX_PHYS_BUF_COUNT];
+} RTMP_SCATTER_GATHER_LIST, *PRTMP_SCATTER_GATHER_LIST;
+
+//
+// Some utility macros
+//
+#ifndef min
+#define min(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
+#endif
+
+#ifndef max
+#define max(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
+#endif
+
+#define GET_LNA_GAIN(_pAd) ((_pAd->LatchRfRegs.Channel <= 14) ? (_pAd->BLNAGain) : ((_pAd->LatchRfRegs.Channel <= 64) ? (_pAd->ALNAGain0) : ((_pAd->LatchRfRegs.Channel <= 128) ? (_pAd->ALNAGain1) : (_pAd->ALNAGain2))))
+
+#define INC_COUNTER64(Val) (Val.QuadPart++)
+
+#define INFRA_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_INFRA_ON))
+#define ADHOC_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_ADHOC_ON))
+#define MONITOR_ON(_p) (((_p)->StaCfg.BssType) == BSS_MONITOR)
+#define IDLE_ON(_p) (!INFRA_ON(_p) && !ADHOC_ON(_p))
+
+// Check LEAP & CCKM flags
+#define LEAP_ON(_p) (((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP)
+#define LEAP_CCKM_ON(_p) ((((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) && ((_p)->StaCfg.LeapAuthInfo.CCKM == TRUE))
+
+// if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required
+#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap) \
+{ \
+ if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500) \
+ { \
+ _pExtraLlcSnapEncap = SNAP_802_1H; \
+ if (NdisEqualMemory(IPX, _pBufVA + 12, 2) || \
+ NdisEqualMemory(APPLE_TALK, _pBufVA + 12, 2)) \
+ { \
+ _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \
+ } \
+ } \
+ else \
+ { \
+ _pExtraLlcSnapEncap = NULL; \
+ } \
+}
+
+// New Define for new Tx Path.
+#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(_pBufVA, _pExtraLlcSnapEncap) \
+{ \
+ if (((*(_pBufVA) << 8) + *(_pBufVA + 1)) > 1500) \
+ { \
+ _pExtraLlcSnapEncap = SNAP_802_1H; \
+ if (NdisEqualMemory(IPX, _pBufVA, 2) || \
+ NdisEqualMemory(APPLE_TALK, _pBufVA, 2)) \
+ { \
+ _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \
+ } \
+ } \
+ else \
+ { \
+ _pExtraLlcSnapEncap = NULL; \
+ } \
+}
+
+
+#define MAKE_802_3_HEADER(_p, _pMac1, _pMac2, _pType) \
+{ \
+ NdisMoveMemory(_p, _pMac1, MAC_ADDR_LEN); \
+ NdisMoveMemory((_p + MAC_ADDR_LEN), _pMac2, MAC_ADDR_LEN); \
+ NdisMoveMemory((_p + MAC_ADDR_LEN * 2), _pType, LENGTH_802_3_TYPE); \
+}
+
+// if pData has no LLC/SNAP (neither RFC1042 nor Bridge tunnel), keep it that way.
+// else if the received frame is LLC/SNAP-encaped IPX or APPLETALK, preserve the LLC/SNAP field
+// else remove the LLC/SNAP field from the result Ethernet frame
+// Patch for WHQL only, which did not turn on Netbios but use IPX within its payload
+// Note:
+// _pData & _DataSize may be altered (remove 8-byte LLC/SNAP) by this MACRO
+// _pRemovedLLCSNAP: pointer to removed LLC/SNAP; NULL is not removed
+#define CONVERT_TO_802_3(_p8023hdr, _pDA, _pSA, _pData, _DataSize, _pRemovedLLCSNAP) \
+{ \
+ char LLC_Len[2]; \
+ \
+ _pRemovedLLCSNAP = NULL; \
+ if (NdisEqualMemory(SNAP_802_1H, _pData, 6) || \
+ NdisEqualMemory(SNAP_BRIDGE_TUNNEL, _pData, 6)) \
+ { \
+ PUCHAR pProto = _pData + 6; \
+ \
+ if ((NdisEqualMemory(IPX, pProto, 2) || NdisEqualMemory(APPLE_TALK, pProto, 2)) && \
+ NdisEqualMemory(SNAP_802_1H, _pData, 6)) \
+ { \
+ LLC_Len[0] = (UCHAR)(_DataSize / 256); \
+ LLC_Len[1] = (UCHAR)(_DataSize % 256); \
+ MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \
+ } \
+ else \
+ { \
+ MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, pProto); \
+ _pRemovedLLCSNAP = _pData; \
+ _DataSize -= LENGTH_802_1_H; \
+ _pData += LENGTH_802_1_H; \
+ } \
+ } \
+ else \
+ { \
+ LLC_Len[0] = (UCHAR)(_DataSize / 256); \
+ LLC_Len[1] = (UCHAR)(_DataSize % 256); \
+ MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \
+ } \
+}
+
+#define SWITCH_AB( _pAA, _pBB) \
+{ \
+ PVOID pCC; \
+ pCC = _pBB; \
+ _pBB = _pAA; \
+ _pAA = pCC; \
+}
+
+// Enqueue this frame to MLME engine
+// We need to enqueue the whole frame because MLME need to pass data type
+// information from 802.11 header
+#ifdef RT2870
+#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal) \
+{ \
+ UINT32 High32TSF=0, Low32TSF=0; \
+ MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal); \
+}
+#endif // RT2870 //
+
+#ifdef RT30xx
+//Need to collect each ant's rssi concurrently
+//rssi1 is report to pair2 Ant and rss2 is reprot to pair1 Ant when 4 Ant
+#define COLLECT_RX_ANTENNA_AVERAGE_RSSI(_pAd, _rssi1, _rssi2) \
+{ \
+ SHORT AvgRssi; \
+ UCHAR UsedAnt; \
+ if (_pAd->RxAnt.EvaluatePeriod == 0) \
+ { \
+ UsedAnt = _pAd->RxAnt.Pair1PrimaryRxAnt; \
+ AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \
+ if (AvgRssi < 0) \
+ AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \
+ else \
+ AvgRssi = _rssi1 << 3; \
+ _pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \
+ } \
+ else \
+ { \
+ UsedAnt = _pAd->RxAnt.Pair1SecondaryRxAnt; \
+ AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \
+ if ((AvgRssi < 0) && (_pAd->RxAnt.FirstPktArrivedWhenEvaluate)) \
+ AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \
+ else \
+ { \
+ _pAd->RxAnt.FirstPktArrivedWhenEvaluate = TRUE; \
+ AvgRssi = _rssi1 << 3; \
+ } \
+ _pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \
+ _pAd->RxAnt.RcvPktNumWhenEvaluate++; \
+ } \
+}
+#endif // RT30xx //
+
+
+#define NDIS_QUERY_BUFFER(_NdisBuf, _ppVA, _pBufLen) \
+ NdisQueryBuffer(_NdisBuf, _ppVA, _pBufLen)
+
+#define MAC_ADDR_EQUAL(pAddr1,pAddr2) RTMPEqualMemory((PVOID)(pAddr1), (PVOID)(pAddr2), MAC_ADDR_LEN)
+#define SSID_EQUAL(ssid1, len1, ssid2, len2) ((len1==len2) && (RTMPEqualMemory(ssid1, ssid2, len1)))
+
+//
+// Check if it is Japan W53(ch52,56,60,64) channel.
+//
+#define JapanChannelCheck(channel) ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64))
+
+#ifdef CONFIG_STA_SUPPORT
+#define STA_PORT_SECURED(_pAd) \
+{ \
+ _pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
+ NdisAcquireSpinLock(&_pAd->MacTabLock); \
+ _pAd->MacTab.Content[BSSID_WCID].PortSecured = _pAd->StaCfg.PortSecured; \
+ NdisReleaseSpinLock(&_pAd->MacTabLock); \
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+//
+// Register set pair for initialzation register set definition
+//
+typedef struct _RTMP_REG_PAIR
+{
+ ULONG Register;
+ ULONG Value;
+} RTMP_REG_PAIR, *PRTMP_REG_PAIR;
+
+typedef struct _REG_PAIR
+{
+ UCHAR Register;
+ UCHAR Value;
+} REG_PAIR, *PREG_PAIR;
+
+//
+// Register set pair for initialzation register set definition
+//
+typedef struct _RTMP_RF_REGS
+{
+ UCHAR Channel;
+ ULONG R1;
+ ULONG R2;
+ ULONG R3;
+ ULONG R4;
+} RTMP_RF_REGS, *PRTMP_RF_REGS;
+
+typedef struct _FREQUENCY_ITEM {
+ UCHAR Channel;
+ UCHAR N;
+ UCHAR R;
+ UCHAR K;
+} FREQUENCY_ITEM, *PFREQUENCY_ITEM;
+
+//
+// Data buffer for DMA operation, the buffer must be contiguous physical memory
+// Both DMA to / from CPU use the same structure.
+//
+typedef struct _RTMP_DMABUF
+{
+ ULONG AllocSize;
+ PVOID AllocVa; // TxBuf virtual address
+ NDIS_PHYSICAL_ADDRESS AllocPa; // TxBuf physical address
+} RTMP_DMABUF, *PRTMP_DMABUF;
+
+
+typedef union _HEADER_802_11_SEQ{
+#ifdef RT_BIG_ENDIAN
+ struct {
+ USHORT Sequence:12;
+ USHORT Frag:4;
+ } field;
+#else
+ struct {
+ USHORT Frag:4;
+ USHORT Sequence:12;
+ } field;
+#endif
+ USHORT value;
+} HEADER_802_11_SEQ, *PHEADER_802_11_SEQ;
+
+//
+// Data buffer for DMA operation, the buffer must be contiguous physical memory
+// Both DMA to / from CPU use the same structure.
+//
+typedef struct _RTMP_REORDERBUF
+{
+ BOOLEAN IsFull;
+ PVOID AllocVa; // TxBuf virtual address
+ UCHAR Header802_3[14];
+ HEADER_802_11_SEQ Sequence; //support compressed bitmap BA, so no consider fragment in BA
+ UCHAR DataOffset;
+ USHORT Datasize;
+ ULONG AllocSize;
+#ifdef RT2870
+ PUCHAR AllocPa;
+#endif // RT2870 //
+} RTMP_REORDERBUF, *PRTMP_REORDERBUF;
+
+//
+// Control block (Descriptor) for all ring descriptor DMA operation, buffer must be
+// contiguous physical memory. NDIS_PACKET stored the binding Rx packet descriptor
+// which won't be released, driver has to wait until upper layer return the packet
+// before giveing up this rx ring descriptor to ASIC. NDIS_BUFFER is assocaited pair
+// to describe the packet buffer. For Tx, NDIS_PACKET stored the tx packet descriptor
+// which driver should ACK upper layer when the tx is physically done or failed.
+//
+typedef struct _RTMP_DMACB
+{
+ ULONG AllocSize; // Control block size
+ PVOID AllocVa; // Control block virtual address
+ NDIS_PHYSICAL_ADDRESS AllocPa; // Control block physical address
+ PNDIS_PACKET pNdisPacket;
+ PNDIS_PACKET pNextNdisPacket;
+
+ RTMP_DMABUF DmaBuf; // Associated DMA buffer structure
+} RTMP_DMACB, *PRTMP_DMACB;
+
+typedef struct _RTMP_TX_BUF
+{
+ PQUEUE_ENTRY Next;
+ UCHAR Index;
+ ULONG AllocSize; // Control block size
+ PVOID AllocVa; // Control block virtual address
+ NDIS_PHYSICAL_ADDRESS AllocPa; // Control block physical address
+} RTMP_TXBUF, *PRTMP_TXBUF;
+
+typedef struct _RTMP_RX_BUF
+{
+ BOOLEAN InUse;
+ ULONG ByBaRecIndex;
+ RTMP_REORDERBUF MAP_RXBuf[MAX_RX_REORDERBUF];
+} RTMP_RXBUF, *PRTMP_RXBUF;
+typedef struct _RTMP_TX_RING
+{
+ RTMP_DMACB Cell[TX_RING_SIZE];
+ UINT32 TxCpuIdx;
+ UINT32 TxDmaIdx;
+ UINT32 TxSwFreeIdx; // software next free tx index
+} RTMP_TX_RING, *PRTMP_TX_RING;
+
+typedef struct _RTMP_RX_RING
+{
+ RTMP_DMACB Cell[RX_RING_SIZE];
+ UINT32 RxCpuIdx;
+ UINT32 RxDmaIdx;
+ INT32 RxSwReadIdx; // software next read index
+} RTMP_RX_RING, *PRTMP_RX_RING;
+
+typedef struct _RTMP_MGMT_RING
+{
+ RTMP_DMACB Cell[MGMT_RING_SIZE];
+ UINT32 TxCpuIdx;
+ UINT32 TxDmaIdx;
+ UINT32 TxSwFreeIdx; // software next free tx index
+} RTMP_MGMT_RING, *PRTMP_MGMT_RING;
+
+//
+// Statistic counter structure
+//
+typedef struct _COUNTER_802_3
+{
+ // General Stats
+ ULONG GoodTransmits;
+ ULONG GoodReceives;
+ ULONG TxErrors;
+ ULONG RxErrors;
+ ULONG RxNoBuffer;
+
+ // Ethernet Stats
+ ULONG RcvAlignmentErrors;
+ ULONG OneCollision;
+ ULONG MoreCollisions;
+
+} COUNTER_802_3, *PCOUNTER_802_3;
+
+typedef struct _COUNTER_802_11 {
+ ULONG Length;
+ LARGE_INTEGER LastTransmittedFragmentCount;
+ LARGE_INTEGER TransmittedFragmentCount;
+ LARGE_INTEGER MulticastTransmittedFrameCount;
+ LARGE_INTEGER FailedCount;
+ LARGE_INTEGER RetryCount;
+ LARGE_INTEGER MultipleRetryCount;
+ LARGE_INTEGER RTSSuccessCount;
+ LARGE_INTEGER RTSFailureCount;
+ LARGE_INTEGER ACKFailureCount;
+ LARGE_INTEGER FrameDuplicateCount;
+ LARGE_INTEGER ReceivedFragmentCount;
+ LARGE_INTEGER MulticastReceivedFrameCount;
+ LARGE_INTEGER FCSErrorCount;
+} COUNTER_802_11, *PCOUNTER_802_11;
+
+typedef struct _COUNTER_RALINK {
+ ULONG TransmittedByteCount; // both successful and failure, used to calculate TX throughput
+ ULONG ReceivedByteCount; // both CRC okay and CRC error, used to calculate RX throughput
+ ULONG BeenDisassociatedCount;
+ ULONG BadCQIAutoRecoveryCount;
+ ULONG PoorCQIRoamingCount;
+ ULONG MgmtRingFullCount;
+ ULONG RxCountSinceLastNULL;
+ ULONG RxCount;
+ ULONG RxRingErrCount;
+ ULONG KickTxCount;
+ ULONG TxRingErrCount;
+ LARGE_INTEGER RealFcsErrCount;
+ ULONG PendingNdisPacketCount;
+
+ ULONG OneSecOsTxCount[NUM_OF_TX_RING];
+ ULONG OneSecDmaDoneCount[NUM_OF_TX_RING];
+ UINT32 OneSecTxDoneCount;
+ ULONG OneSecRxCount;
+ UINT32 OneSecTxAggregationCount;
+ UINT32 OneSecRxAggregationCount;
+
+ UINT32 OneSecFrameDuplicateCount;
+
+#ifdef RT2870
+ ULONG OneSecTransmittedByteCount; // both successful and failure, used to calculate TX throughput
+#endif // RT2870 //
+
+ UINT32 OneSecTxNoRetryOkCount;
+ UINT32 OneSecTxRetryOkCount;
+ UINT32 OneSecTxFailCount;
+ UINT32 OneSecFalseCCACnt; // CCA error count, for debug purpose, might move to global counter
+ UINT32 OneSecRxOkCnt; // RX without error
+ UINT32 OneSecRxOkDataCnt; // unicast-to-me DATA frame count
+ UINT32 OneSecRxFcsErrCnt; // CRC error
+ UINT32 OneSecBeaconSentCnt;
+ UINT32 LastOneSecTotalTxCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
+ UINT32 LastOneSecRxOkDataCnt; // OneSecRxOkDataCnt
+ ULONG DuplicateRcv;
+ ULONG TxAggCount;
+ ULONG TxNonAggCount;
+ ULONG TxAgg1MPDUCount;
+ ULONG TxAgg2MPDUCount;
+ ULONG TxAgg3MPDUCount;
+ ULONG TxAgg4MPDUCount;
+ ULONG TxAgg5MPDUCount;
+ ULONG TxAgg6MPDUCount;
+ ULONG TxAgg7MPDUCount;
+ ULONG TxAgg8MPDUCount;
+ ULONG TxAgg9MPDUCount;
+ ULONG TxAgg10MPDUCount;
+ ULONG TxAgg11MPDUCount;
+ ULONG TxAgg12MPDUCount;
+ ULONG TxAgg13MPDUCount;
+ ULONG TxAgg14MPDUCount;
+ ULONG TxAgg15MPDUCount;
+ ULONG TxAgg16MPDUCount;
+
+ LARGE_INTEGER TransmittedOctetsInAMSDU;
+ LARGE_INTEGER TransmittedAMSDUCount;
+ LARGE_INTEGER ReceivedOctesInAMSDUCount;
+ LARGE_INTEGER ReceivedAMSDUCount;
+ LARGE_INTEGER TransmittedAMPDUCount;
+ LARGE_INTEGER TransmittedMPDUsInAMPDUCount;
+ LARGE_INTEGER TransmittedOctetsInAMPDUCount;
+ LARGE_INTEGER MPDUInReceivedAMPDUCount;
+} COUNTER_RALINK, *PCOUNTER_RALINK;
+
+typedef struct _PID_COUNTER {
+ ULONG TxAckRequiredCount; // CRC error
+ ULONG TxAggreCount;
+ ULONG TxSuccessCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
+ ULONG LastSuccessRate;
+} PID_COUNTER, *PPID_COUNTER;
+
+typedef struct _COUNTER_DRS {
+ // to record the each TX rate's quality. 0 is best, the bigger the worse.
+ USHORT TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
+ UCHAR PER[MAX_STEP_OF_TX_RATE_SWITCH];
+ UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
+ ULONG CurrTxRateStableTime; // # of second in current TX rate
+ BOOLEAN fNoisyEnvironment;
+ BOOLEAN fLastSecAccordingRSSI;
+ UCHAR LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
+ UCHAR LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
+ ULONG LastTxOkCount;
+} COUNTER_DRS, *PCOUNTER_DRS;
+
+//
+// Arcfour Structure Added by PaulWu
+//
+typedef struct _ARCFOUR
+{
+ UINT X;
+ UINT Y;
+ UCHAR STATE[256];
+} ARCFOURCONTEXT, *PARCFOURCONTEXT;
+
+// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI too. just copy to TXWI.
+typedef struct _RECEIVE_SETTING {
+#ifdef RT_BIG_ENDIAN
+ USHORT MIMO:1;
+ USHORT OFDM:1;
+ USHORT rsv:3;
+ USHORT STBC:2; //SPACE
+ USHORT ShortGI:1;
+ USHORT Mode:2; //channel bandwidth 20MHz or 40 MHz
+ USHORT NumOfRX:2; // MIMO. WE HAVE 3R
+#else
+ USHORT NumOfRX:2; // MIMO. WE HAVE 3R
+ USHORT Mode:2; //channel bandwidth 20MHz or 40 MHz
+ USHORT ShortGI:1;
+ USHORT STBC:2; //SPACE
+ USHORT rsv:3;
+ USHORT OFDM:1;
+ USHORT MIMO:1;
+#endif
+ } RECEIVE_SETTING, *PRECEIVE_SETTING;
+
+// Shared key data structure
+typedef struct _WEP_KEY {
+ UCHAR KeyLen; // Key length for each key, 0: entry is invalid
+ UCHAR Key[MAX_LEN_OF_KEY]; // right now we implement 4 keys, 128 bits max
+} WEP_KEY, *PWEP_KEY;
+
+typedef struct _CIPHER_KEY {
+ UCHAR Key[16]; // right now we implement 4 keys, 128 bits max
+ UCHAR RxMic[8]; // make alignment
+ UCHAR TxMic[8];
+ UCHAR TxTsc[6]; // 48bit TSC value
+ UCHAR RxTsc[6]; // 48bit TSC value
+ UCHAR CipherAlg; // 0-none, 1:WEP64, 2:WEP128, 3:TKIP, 4:AES, 5:CKIP64, 6:CKIP128
+ UCHAR KeyLen;
+#ifdef CONFIG_STA_SUPPORT
+ UCHAR BssId[6];
+#endif // CONFIG_STA_SUPPORT //
+ // Key length for each key, 0: entry is invalid
+ UCHAR Type; // Indicate Pairwise/Group when reporting MIC error
+} CIPHER_KEY, *PCIPHER_KEY;
+
+typedef struct _BBP_TUNING_STRUCT {
+ BOOLEAN Enable;
+ UCHAR FalseCcaCountUpperBound; // 100 per sec
+ UCHAR FalseCcaCountLowerBound; // 10 per sec
+ UCHAR R17LowerBound; // specified in E2PROM
+ UCHAR R17UpperBound; // 0x68 according to David Tung
+ UCHAR CurrentR17Value;
+} BBP_TUNING, *PBBP_TUNING;
+
+typedef struct _SOFT_RX_ANT_DIVERSITY_STRUCT {
+ UCHAR EvaluatePeriod; // 0:not evalute status, 1: evaluate status, 2: switching status
+ UCHAR EvaluateStableCnt;
+ UCHAR Pair1PrimaryRxAnt; // 0:Ant-E1, 1:Ant-E2
+ UCHAR Pair1SecondaryRxAnt; // 0:Ant-E1, 1:Ant-E2
+ UCHAR Pair2PrimaryRxAnt; // 0:Ant-E3, 1:Ant-E4
+ UCHAR Pair2SecondaryRxAnt; // 0:Ant-E3, 1:Ant-E4
+ SHORT Pair1AvgRssi[2]; // AvgRssi[0]:E1, AvgRssi[1]:E2
+ SHORT Pair2AvgRssi[2]; // AvgRssi[0]:E3, AvgRssi[1]:E4
+ SHORT Pair1LastAvgRssi; //
+ SHORT Pair2LastAvgRssi; //
+ ULONG RcvPktNumWhenEvaluate;
+ BOOLEAN FirstPktArrivedWhenEvaluate;
+ RALINK_TIMER_STRUCT RxAntDiversityTimer;
+} SOFT_RX_ANT_DIVERSITY, *PSOFT_RX_ANT_DIVERSITY;
+
+typedef struct _LEAP_AUTH_INFO {
+ BOOLEAN Enabled; //Ture: Enable LEAP Authentication
+ BOOLEAN CCKM; //Ture: Use Fast Reauthentication with CCKM
+ UCHAR Reserve[2];
+ UCHAR UserName[256]; //LEAP, User name
+ ULONG UserNameLen;
+ UCHAR Password[256]; //LEAP, User Password
+ ULONG PasswordLen;
+} LEAP_AUTH_INFO, *PLEAP_AUTH_INFO;
+
+typedef struct {
+ UCHAR Addr[MAC_ADDR_LEN];
+ UCHAR ErrorCode[2]; //00 01-Invalid authentication type
+ //00 02-Authentication timeout
+ //00 03-Challenge from AP failed
+ //00 04-Challenge to AP failed
+ BOOLEAN Reported;
+} ROGUEAP_ENTRY, *PROGUEAP_ENTRY;
+
+typedef struct {
+ UCHAR RogueApNr;
+ ROGUEAP_ENTRY RogueApEntry[MAX_LEN_OF_BSS_TABLE];
+} ROGUEAP_TABLE, *PROGUEAP_TABLE;
+
+typedef struct {
+ BOOLEAN Enable;
+ UCHAR Delta;
+ BOOLEAN PlusSign;
+} CCK_TX_POWER_CALIBRATE, *PCCK_TX_POWER_CALIBRATE;
+
+//
+// Receive Tuple Cache Format
+//
+typedef struct _TUPLE_CACHE {
+ BOOLEAN Valid;
+ UCHAR MacAddress[MAC_ADDR_LEN];
+ USHORT Sequence;
+ USHORT Frag;
+} TUPLE_CACHE, *PTUPLE_CACHE;
+
+//
+// Fragment Frame structure
+//
+typedef struct _FRAGMENT_FRAME {
+ PNDIS_PACKET pFragPacket;
+ ULONG RxSize;
+ USHORT Sequence;
+ USHORT LastFrag;
+ ULONG Flags; // Some extra frame information. bit 0: LLC presented
+} FRAGMENT_FRAME, *PFRAGMENT_FRAME;
+
+
+//
+// Packet information for NdisQueryPacket
+//
+typedef struct _PACKET_INFO {
+ UINT PhysicalBufferCount; // Physical breaks of buffer descripor chained
+ UINT BufferCount ; // Number of Buffer descriptor chained
+ UINT TotalPacketLength ; // Self explained
+ PNDIS_BUFFER pFirstBuffer; // Pointer to first buffer descriptor
+} PACKET_INFO, *PPACKET_INFO;
+
+//
+// Tkip Key structure which RC4 key & MIC calculation
+//
+typedef struct _TKIP_KEY_INFO {
+ UINT nBytesInM; // # bytes in M for MICKEY
+ ULONG IV16;
+ ULONG IV32;
+ ULONG K0; // for MICKEY Low
+ ULONG K1; // for MICKEY Hig
+ ULONG L; // Current state for MICKEY
+ ULONG R; // Current state for MICKEY
+ ULONG M; // Message accumulator for MICKEY
+ UCHAR RC4KEY[16];
+ UCHAR MIC[8];
+} TKIP_KEY_INFO, *PTKIP_KEY_INFO;
+
+//
+// Private / Misc data, counters for driver internal use
+//
+typedef struct __PRIVATE_STRUC {
+ UINT SystemResetCnt; // System reset counter
+ UINT TxRingFullCnt; // Tx ring full occurrance number
+ UINT PhyRxErrCnt; // PHY Rx error count, for debug purpose, might move to global counter
+ // Variables for WEP encryption / decryption in rtmp_wep.c
+ UINT FCSCRC32;
+ ARCFOURCONTEXT WEPCONTEXT;
+ // Tkip stuff
+ TKIP_KEY_INFO Tx;
+ TKIP_KEY_INFO Rx;
+} PRIVATE_STRUC, *PPRIVATE_STRUC;
+
+// structure to tune BBP R66 (BBP TUNING)
+typedef struct _BBP_R66_TUNING {
+ BOOLEAN bEnable;
+ USHORT FalseCcaLowerThreshold; // default 100
+ USHORT FalseCcaUpperThreshold; // default 512
+ UCHAR R66Delta;
+ UCHAR R66CurrentValue;
+ BOOLEAN R66LowerUpperSelect; //Before LinkUp, Used LowerBound or UpperBound as R66 value.
+} BBP_R66_TUNING, *PBBP_R66_TUNING;
+
+// structure to store channel TX power
+typedef struct _CHANNEL_TX_POWER {
+ USHORT RemainingTimeForUse; //unit: sec
+ UCHAR Channel;
+#ifdef DOT11N_DRAFT3
+ BOOLEAN bEffectedChannel; // For BW 40 operating in 2.4GHz , the "effected channel" is the channel that is covered in 40Mhz.
+#endif // DOT11N_DRAFT3 //
+ CHAR Power;
+ CHAR Power2;
+ UCHAR MaxTxPwr;
+ UCHAR DfsReq;
+} CHANNEL_TX_POWER, *PCHANNEL_TX_POWER;
+
+// structure to store 802.11j channel TX power
+typedef struct _CHANNEL_11J_TX_POWER {
+ UCHAR Channel;
+ UCHAR BW; // BW_10 or BW_20
+ CHAR Power;
+ CHAR Power2;
+ USHORT RemainingTimeForUse; //unit: sec
+} CHANNEL_11J_TX_POWER, *PCHANNEL_11J_TX_POWER;
+
+typedef enum _ABGBAND_STATE_ {
+ UNKNOWN_BAND,
+ BG_BAND,
+ A_BAND,
+} ABGBAND_STATE;
+
+typedef struct _MLME_STRUCT {
+#ifdef CONFIG_STA_SUPPORT
+ // STA state machines
+ STATE_MACHINE CntlMachine;
+ STATE_MACHINE AssocMachine;
+ STATE_MACHINE AuthMachine;
+ STATE_MACHINE AuthRspMachine;
+ STATE_MACHINE SyncMachine;
+ STATE_MACHINE WpaPskMachine;
+ STATE_MACHINE LeapMachine;
+ STATE_MACHINE AironetMachine;
+ STATE_MACHINE_FUNC AssocFunc[ASSOC_FUNC_SIZE];
+ STATE_MACHINE_FUNC AuthFunc[AUTH_FUNC_SIZE];
+ STATE_MACHINE_FUNC AuthRspFunc[AUTH_RSP_FUNC_SIZE];
+ STATE_MACHINE_FUNC SyncFunc[SYNC_FUNC_SIZE];
+ STATE_MACHINE_FUNC WpaPskFunc[WPA_PSK_FUNC_SIZE];
+ STATE_MACHINE_FUNC AironetFunc[AIRONET_FUNC_SIZE];
+#endif // CONFIG_STA_SUPPORT //
+ STATE_MACHINE_FUNC ActFunc[ACT_FUNC_SIZE];
+ // Action
+ STATE_MACHINE ActMachine;
+
+
+#ifdef QOS_DLS_SUPPORT
+ STATE_MACHINE DlsMachine;
+ STATE_MACHINE_FUNC DlsFunc[DLS_FUNC_SIZE];
+#endif // QOS_DLS_SUPPORT //
+
+
+
+
+ ULONG ChannelQuality; // 0..100, Channel Quality Indication for Roaming
+ ULONG Now32; // latch the value of NdisGetSystemUpTime()
+ ULONG LastSendNULLpsmTime;
+
+ BOOLEAN bRunning;
+ NDIS_SPIN_LOCK TaskLock;
+ MLME_QUEUE Queue;
+
+ UINT ShiftReg;
+
+ RALINK_TIMER_STRUCT PeriodicTimer;
+ RALINK_TIMER_STRUCT APSDPeriodicTimer;
+ RALINK_TIMER_STRUCT LinkDownTimer;
+ RALINK_TIMER_STRUCT LinkUpTimer;
+ ULONG PeriodicRound;
+ ULONG OneSecPeriodicRound;
+
+ UCHAR RealRxPath;
+ BOOLEAN bLowThroughput;
+ BOOLEAN bEnableAutoAntennaCheck;
+ RALINK_TIMER_STRUCT RxAntEvalTimer;
+
+#ifdef RT30xx
+ UCHAR CaliBW40RfR24;
+ UCHAR CaliBW20RfR24;
+#endif // RT30xx //
+
+} MLME_STRUCT, *PMLME_STRUCT;
+
+// structure for radar detection and channel switch
+typedef struct _RADAR_DETECT_STRUCT {
+ //BOOLEAN IEEE80211H; // 0: disable, 1: enable IEEE802.11h
+ UCHAR CSCount; //Channel switch counter
+ UCHAR CSPeriod; //Channel switch period (beacon count)
+ UCHAR RDCount; //Radar detection counter
+ UCHAR RDMode; //Radar Detection mode
+ UCHAR RDDurRegion; //Radar detection duration region
+ UCHAR BBPR16;
+ UCHAR BBPR17;
+ UCHAR BBPR18;
+ UCHAR BBPR21;
+ UCHAR BBPR22;
+ UCHAR BBPR64;
+ ULONG InServiceMonitorCount; // unit: sec
+ UINT8 DfsSessionTime;
+ BOOLEAN bFastDfs;
+ UINT8 ChMovingTime;
+ UINT8 LongPulseRadarTh;
+} RADAR_DETECT_STRUCT, *PRADAR_DETECT_STRUCT;
+
+#ifdef CARRIER_DETECTION_SUPPORT
+typedef enum CD_STATE_n
+{
+ CD_NORMAL,
+ CD_SILENCE,
+ CD_MAX_STATE
+} CD_STATE;
+
+typedef struct CARRIER_DETECTION_s
+{
+ BOOLEAN Enable;
+ UINT8 CDSessionTime;
+ UINT8 CDPeriod;
+ CD_STATE CD_State;
+} CARRIER_DETECTION, *PCARRIER_DETECTION;
+#endif // CARRIER_DETECTION_SUPPORT //
+
+typedef enum _REC_BLOCKACK_STATUS
+{
+ Recipient_NONE=0,
+ Recipient_USED,
+ Recipient_HandleRes,
+ Recipient_Accept
+} REC_BLOCKACK_STATUS, *PREC_BLOCKACK_STATUS;
+
+typedef enum _ORI_BLOCKACK_STATUS
+{
+ Originator_NONE=0,
+ Originator_USED,
+ Originator_WaitRes,
+ Originator_Done
+} ORI_BLOCKACK_STATUS, *PORI_BLOCKACK_STATUS;
+
+#ifdef DOT11_N_SUPPORT
+typedef struct _BA_ORI_ENTRY{
+ UCHAR Wcid;
+ UCHAR TID;
+ UCHAR BAWinSize;
+ UCHAR Token;
+// Sequence is to fill every outgoing QoS DATA frame's sequence field in 802.11 header.
+ USHORT Sequence;
+ USHORT TimeOutValue;
+ ORI_BLOCKACK_STATUS ORI_BA_Status;
+ RALINK_TIMER_STRUCT ORIBATimer;
+ PVOID pAdapter;
+} BA_ORI_ENTRY, *PBA_ORI_ENTRY;
+
+typedef struct _BA_REC_ENTRY {
+ UCHAR Wcid;
+ UCHAR TID;
+ UCHAR BAWinSize; // 7.3.1.14. each buffer is capable of holding a max AMSDU or MSDU.
+ //UCHAR NumOfRxPkt;
+ //UCHAR Curindidx; // the head in the RX reordering buffer
+ USHORT LastIndSeq;
+// USHORT LastIndSeqAtTimer;
+ USHORT TimeOutValue;
+ RALINK_TIMER_STRUCT RECBATimer;
+ ULONG LastIndSeqAtTimer;
+ ULONG nDropPacket;
+ ULONG rcvSeq;
+ REC_BLOCKACK_STATUS REC_BA_Status;
+// UCHAR RxBufIdxUsed;
+ // corresponding virtual address for RX reordering packet storage.
+ //RTMP_REORDERDMABUF MAP_RXBuf[MAX_RX_REORDERBUF];
+ NDIS_SPIN_LOCK RxReRingLock; // Rx Ring spinlock
+// struct _BA_REC_ENTRY *pNext;
+ PVOID pAdapter;
+ struct reordering_list list;
+} BA_REC_ENTRY, *PBA_REC_ENTRY;
+
+
+typedef struct {
+ ULONG numAsRecipient; // I am recipient of numAsRecipient clients. These client are in the BARecEntry[]
+ ULONG numAsOriginator; // I am originator of numAsOriginator clients. These clients are in the BAOriEntry[]
+ BA_ORI_ENTRY BAOriEntry[MAX_LEN_OF_BA_ORI_TABLE];
+ BA_REC_ENTRY BARecEntry[MAX_LEN_OF_BA_REC_TABLE];
+} BA_TABLE, *PBA_TABLE;
+
+//For QureyBATableOID use;
+typedef struct PACKED _OID_BA_REC_ENTRY{
+ UCHAR MACAddr[MAC_ADDR_LEN];
+ UCHAR BaBitmap; // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize
+ UCHAR rsv;
+ UCHAR BufSize[8];
+ REC_BLOCKACK_STATUS REC_BA_Status[8];
+} OID_BA_REC_ENTRY, *POID_BA_REC_ENTRY;
+
+//For QureyBATableOID use;
+typedef struct PACKED _OID_BA_ORI_ENTRY{
+ UCHAR MACAddr[MAC_ADDR_LEN];
+ UCHAR BaBitmap; // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize, read ORI_BA_Status[TID] for status
+ UCHAR rsv;
+ UCHAR BufSize[8];
+ ORI_BLOCKACK_STATUS ORI_BA_Status[8];
+} OID_BA_ORI_ENTRY, *POID_BA_ORI_ENTRY;
+
+typedef struct _QUERYBA_TABLE{
+ OID_BA_ORI_ENTRY BAOriEntry[32];
+ OID_BA_REC_ENTRY BARecEntry[32];
+ UCHAR OriNum;// Number of below BAOriEntry
+ UCHAR RecNum;// Number of below BARecEntry
+} QUERYBA_TABLE, *PQUERYBA_TABLE;
+
+typedef union _BACAP_STRUC {
+#ifdef RT_BIG_ENDIAN
+ struct {
+ UINT32 :4;
+ UINT32 b2040CoexistScanSup:1; //As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz.
+ UINT32 bHtAdhoc:1; // adhoc can use ht rate.
+ UINT32 MMPSmode:2; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
+ UINT32 AmsduSize:1; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
+ UINT32 AmsduEnable:1; //Enable AMSDU transmisstion
+ UINT32 MpduDensity:3;
+ UINT32 Policy:2; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use
+ UINT32 AutoBA:1; // automatically BA
+ UINT32 TxBAWinLimit:8;
+ UINT32 RxBAWinLimit:8;
+ } field;
+#else
+ struct {
+ UINT32 RxBAWinLimit:8;
+ UINT32 TxBAWinLimit:8;
+ UINT32 AutoBA:1; // automatically BA
+ UINT32 Policy:2; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use
+ UINT32 MpduDensity:3;
+ UINT32 AmsduEnable:1; //Enable AMSDU transmisstion
+ UINT32 AmsduSize:1; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
+ UINT32 MMPSmode:2; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
+ UINT32 bHtAdhoc:1; // adhoc can use ht rate.
+ UINT32 b2040CoexistScanSup:1; //As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz.
+ UINT32 :4;
+ } field;
+#endif
+ UINT32 word;
+} BACAP_STRUC, *PBACAP_STRUC;
+#endif // DOT11_N_SUPPORT //
+
+//This structure is for all 802.11n card InterOptibilityTest action. Reset all Num every n second. (Details see MLMEPeriodic)
+typedef struct _IOT_STRUC {
+ UCHAR Threshold[2];
+ UCHAR ReorderTimeOutNum[MAX_LEN_OF_BA_REC_TABLE]; // compare with threshold[0]
+ UCHAR RefreshNum[MAX_LEN_OF_BA_REC_TABLE]; // compare with threshold[1]
+ ULONG OneSecInWindowCount;
+ ULONG OneSecFrameDuplicateCount;
+ ULONG OneSecOutWindowCount;
+ UCHAR DelOriAct;
+ UCHAR DelRecAct;
+ UCHAR RTSShortProt;
+ UCHAR RTSLongProt;
+ BOOLEAN bRTSLongProtOn;
+#ifdef CONFIG_STA_SUPPORT
+ BOOLEAN bLastAtheros;
+ BOOLEAN bCurrentAtheros;
+ BOOLEAN bNowAtherosBurstOn;
+ BOOLEAN bNextDisableRxBA;
+ BOOLEAN bToggle;
+#endif // CONFIG_STA_SUPPORT //
+} IOT_STRUC, *PIOT_STRUC;
+
+// This is the registry setting for 802.11n transmit setting. Used in advanced page.
+typedef union _REG_TRANSMIT_SETTING {
+#ifdef RT_BIG_ENDIAN
+ struct {
+ UINT32 rsv:13;
+ UINT32 EXTCHA:2;
+ UINT32 HTMODE:1;
+ UINT32 TRANSNO:2;
+ UINT32 STBC:1; //SPACE
+ UINT32 ShortGI:1;
+ UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
+ UINT32 TxBF:1; // 3*3
+ UINT32 rsv0:10;
+ //UINT32 MCS:7; // MCS
+ //UINT32 PhyMode:4;
+ } field;
+#else
+ struct {
+ //UINT32 PhyMode:4;
+ //UINT32 MCS:7; // MCS
+ UINT32 rsv0:10;
+ UINT32 TxBF:1;
+ UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
+ UINT32 ShortGI:1;
+ UINT32 STBC:1; //SPACE
+ UINT32 TRANSNO:2;
+ UINT32 HTMODE:1;
+ UINT32 EXTCHA:2;
+ UINT32 rsv:13;
+ } field;
+#endif
+ UINT32 word;
+} REG_TRANSMIT_SETTING, *PREG_TRANSMIT_SETTING;
+
+typedef union _DESIRED_TRANSMIT_SETTING {
+#ifdef RT_BIG_ENDIAN
+ struct {
+ USHORT rsv:3;
+ USHORT FixedTxMode:2; // If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
+ USHORT PhyMode:4;
+ USHORT MCS:7; // MCS
+ } field;
+#else
+ struct {
+ USHORT MCS:7; // MCS
+ USHORT PhyMode:4;
+ USHORT FixedTxMode:2; // If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
+ USHORT rsv:3;
+ } field;
+#endif
+ USHORT word;
+ } DESIRED_TRANSMIT_SETTING, *PDESIRED_TRANSMIT_SETTING;
+
+typedef struct {
+ BOOLEAN IsRecipient;
+ UCHAR MACAddr[MAC_ADDR_LEN];
+ UCHAR TID;
+ UCHAR nMSDU;
+ USHORT TimeOut;
+ BOOLEAN bAllTid; // If True, delete all TID for BA sessions with this MACaddr.
+} OID_ADD_BA_ENTRY, *POID_ADD_BA_ENTRY;
+
+//
+// Multiple SSID structure
+//
+#define WLAN_MAX_NUM_OF_TIM ((MAX_LEN_OF_MAC_TABLE >> 3) + 1) /* /8 + 1 */
+#define WLAN_CT_TIM_BCMC_OFFSET 0 /* unit: 32B */
+
+/* clear bcmc TIM bit */
+#define WLAN_MR_TIM_BCMC_CLEAR(apidx) \
+ pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] &= ~BIT8[0];
+
+/* set bcmc TIM bit */
+#define WLAN_MR_TIM_BCMC_SET(apidx) \
+ pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] |= BIT8[0];
+
+/* clear a station PS TIM bit */
+#define WLAN_MR_TIM_BIT_CLEAR(ad_p, apidx, wcid) \
+ { UCHAR tim_offset = wcid >> 3; \
+ UCHAR bit_offset = wcid & 0x7; \
+ ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] &= (~BIT8[bit_offset]); }
+
+/* set a station PS TIM bit */
+#define WLAN_MR_TIM_BIT_SET(ad_p, apidx, wcid) \
+ { UCHAR tim_offset = wcid >> 3; \
+ UCHAR bit_offset = wcid & 0x7; \
+ ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] |= BIT8[bit_offset]; }
+
+#ifdef RT2870
+#define BEACON_BITMAP_MASK 0xff
+typedef struct _BEACON_SYNC_STRUCT_
+{
+ UCHAR BeaconBuf[HW_BEACON_MAX_COUNT][HW_BEACON_OFFSET];
+ UCHAR BeaconTxWI[HW_BEACON_MAX_COUNT][TXWI_SIZE];
+ ULONG TimIELocationInBeacon[HW_BEACON_MAX_COUNT];
+ ULONG CapabilityInfoLocationInBeacon[HW_BEACON_MAX_COUNT];
+ BOOLEAN EnableBeacon; // trigger to enable beacon transmission.
+ UCHAR BeaconBitMap; // NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change.
+ UCHAR DtimBitOn; // NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change.
+}BEACON_SYNC_STRUCT;
+#endif // RT2870 //
+
+typedef struct _MULTISSID_STRUCT {
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR SsidLen;
+ CHAR Ssid[MAX_LEN_OF_SSID];
+ USHORT CapabilityInfo;
+
+ PNET_DEV MSSIDDev;
+
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode;
+ NDIS_802_11_WEP_STATUS WepStatus;
+ NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
+ WPA_MIX_PAIR_CIPHER WpaMixPairCipher;
+
+ ULONG TxCount;
+ ULONG RxCount;
+ ULONG ReceivedByteCount;
+ ULONG TransmittedByteCount;
+ ULONG RxErrorCount;
+ ULONG RxDropCount;
+
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
+ RT_HT_PHY_INFO DesiredHtPhyInfo;
+ DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting. this is for reading registry setting only. not useful.
+ BOOLEAN bAutoTxRateSwitch;
+
+ //CIPHER_KEY SharedKey[SHARE_KEY_NUM]; // ref pAd->SharedKey[BSS][4]
+ UCHAR DefaultKeyId;
+
+ UCHAR TxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11, ...
+ UCHAR DesiredRates[MAX_LEN_OF_SUPPORTED_RATES];// OID_802_11_DESIRED_RATES
+ UCHAR DesiredRatesIndex;
+ UCHAR MaxTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
+
+// ULONG TimBitmap; // bit0 for broadcast, 1 for AID1, 2 for AID2, ...so on
+// ULONG TimBitmap2; // b0 for AID32, b1 for AID33, ... and so on
+ UCHAR TimBitmaps[WLAN_MAX_NUM_OF_TIM];
+
+ // WPA
+ UCHAR GMK[32];
+ UCHAR PMK[32];
+ UCHAR GTK[32];
+ BOOLEAN IEEE8021X;
+ BOOLEAN PreAuth;
+ UCHAR GNonce[32];
+ UCHAR PortSecured;
+ NDIS_802_11_PRIVACY_FILTER PrivacyFilter;
+ UCHAR BANClass3Data;
+ ULONG IsolateInterStaTraffic;
+
+ UCHAR RSNIE_Len[2];
+ UCHAR RSN_IE[2][MAX_LEN_OF_RSNIE];
+
+
+ UCHAR TimIELocationInBeacon;
+ UCHAR CapabilityInfoLocationInBeacon;
+ // outgoing BEACON frame buffer and corresponding TXWI
+ // PTXWI_STRUC BeaconTxWI; //
+ CHAR BeaconBuf[MAX_BEACON_SIZE]; // NOTE: BeaconBuf should be 4-byte aligned
+
+ BOOLEAN bHideSsid;
+ UINT16 StationKeepAliveTime; // unit: second
+
+ USHORT VLAN_VID;
+ USHORT VLAN_Priority;
+
+ RT_802_11_ACL AccessControlList;
+
+ // EDCA Qos
+ BOOLEAN bWmmCapable; // 0:disable WMM, 1:enable WMM
+ BOOLEAN bDLSCapable; // 0:disable DLS, 1:enable DLS
+
+ UCHAR DlsPTK[64]; // Due to windows dirver count on meetinghouse to handle 4-way shake
+
+ // For 802.1x daemon setting per BSS
+ UCHAR radius_srv_num;
+ RADIUS_SRV_INFO radius_srv_info[MAX_RADIUS_SRV_NUM];
+
+#ifdef RTL865X_SOC
+ unsigned int mylinkid;
+#endif
+
+
+ UINT32 RcvdConflictSsidCount;
+ UINT32 RcvdSpoofedAssocRespCount;
+ UINT32 RcvdSpoofedReassocRespCount;
+ UINT32 RcvdSpoofedProbeRespCount;
+ UINT32 RcvdSpoofedBeaconCount;
+ UINT32 RcvdSpoofedDisassocCount;
+ UINT32 RcvdSpoofedAuthCount;
+ UINT32 RcvdSpoofedDeauthCount;
+ UINT32 RcvdSpoofedUnknownMgmtCount;
+ UINT32 RcvdReplayAttackCount;
+
+ CHAR RssiOfRcvdConflictSsid;
+ CHAR RssiOfRcvdSpoofedAssocResp;
+ CHAR RssiOfRcvdSpoofedReassocResp;
+ CHAR RssiOfRcvdSpoofedProbeResp;
+ CHAR RssiOfRcvdSpoofedBeacon;
+ CHAR RssiOfRcvdSpoofedDisassoc;
+ CHAR RssiOfRcvdSpoofedAuth;
+ CHAR RssiOfRcvdSpoofedDeauth;
+ CHAR RssiOfRcvdSpoofedUnknownMgmt;
+ CHAR RssiOfRcvdReplayAttack;
+
+ BOOLEAN bBcnSntReq;
+ UCHAR BcnBufIdx;
+} MULTISSID_STRUCT, *PMULTISSID_STRUCT;
+
+
+
+#ifdef DOT11N_DRAFT3
+typedef enum _BSS2040COEXIST_FLAG{
+ BSS_2040_COEXIST_DISABLE = 0,
+ BSS_2040_COEXIST_TIMER_FIRED = 1,
+ BSS_2040_COEXIST_INFO_SYNC = 2,
+ BSS_2040_COEXIST_INFO_NOTIFY = 4,
+}BSS2040COEXIST_FLAG;
+#endif // DOT11N_DRAFT3 //
+
+// configuration common to OPMODE_AP as well as OPMODE_STA
+typedef struct _COMMON_CONFIG {
+
+ BOOLEAN bCountryFlag;
+ UCHAR CountryCode[3];
+ UCHAR Geography;
+ UCHAR CountryRegion; // Enum of country region, 0:FCC, 1:IC, 2:ETSI, 3:SPAIN, 4:France, 5:MKK, 6:MKK1, 7:Israel
+ UCHAR CountryRegionForABand; // Enum of country region for A band
+ UCHAR PhyMode; // PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED
+ USHORT Dsifs; // in units of usec
+ ULONG PacketFilter; // Packet filter for receiving
+
+ CHAR Ssid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
+ UCHAR SsidLen; // the actual ssid length in used
+ UCHAR LastSsidLen; // the actual ssid length in used
+ CHAR LastSsid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
+ UCHAR LastBssid[MAC_ADDR_LEN];
+
+ UCHAR Bssid[MAC_ADDR_LEN];
+ USHORT BeaconPeriod;
+ UCHAR Channel;
+ UCHAR CentralChannel; // Central Channel when using 40MHz is indicating. not real channel.
+
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen;
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR ExtRateLen;
+ UCHAR DesireRate[MAX_LEN_OF_SUPPORTED_RATES]; // OID_802_11_DESIRED_RATES
+ UCHAR MaxDesiredRate;
+ UCHAR ExpectedACKRate[MAX_LEN_OF_SUPPORTED_RATES];
+
+ ULONG BasicRateBitmap; // backup basic ratebitmap
+
+ BOOLEAN bAPSDCapable;
+ BOOLEAN bInServicePeriod;
+ BOOLEAN bAPSDAC_BE;
+ BOOLEAN bAPSDAC_BK;
+ BOOLEAN bAPSDAC_VI;
+ BOOLEAN bAPSDAC_VO;
+ BOOLEAN bNeedSendTriggerFrame;
+ BOOLEAN bAPSDForcePowerSave; // Force power save mode, should only use in APSD-STAUT
+ ULONG TriggerTimerCount;
+ UCHAR MaxSPLength;
+ UCHAR BBPCurrentBW; // BW_10, BW_20, BW_40
+ // move to MULTISSID_STRUCT for MBSS
+ //HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
+ REG_TRANSMIT_SETTING RegTransmitSetting; //registry transmit setting. this is for reading registry setting only. not useful.
+ //UCHAR FixedTxMode; // Fixed Tx Mode (CCK, OFDM), for HT fixed tx mode (GF, MIX) , refer to RegTransmitSetting.field.HTMode
+ UCHAR TxRate; // Same value to fill in TXD. TxRate is 6-bit
+ UCHAR MaxTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
+ UCHAR TxRateIndex; // Tx rate index in RateSwitchTable
+ UCHAR TxRateTableSize; // Valid Tx rate table size in RateSwitchTable
+ //BOOLEAN bAutoTxRateSwitch;
+ UCHAR MinTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
+ UCHAR RtsRate; // RATE_xxx
+ HTTRANSMIT_SETTING MlmeTransmit; // MGMT frame PHY rate setting when operatin at Ht rate.
+ UCHAR MlmeRate; // RATE_xxx, used to send MLME frames
+ UCHAR BasicMlmeRate; // Default Rate for sending MLME frames
+
+ USHORT RtsThreshold; // in unit of BYTE
+ USHORT FragmentThreshold; // in unit of BYTE
+
+ UCHAR TxPower; // in unit of mW
+ ULONG TxPowerPercentage; // 0~100 %
+ ULONG TxPowerDefault; // keep for TxPowerPercentage
+
+#ifdef DOT11_N_SUPPORT
+ BACAP_STRUC BACapability; // NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0
+ BACAP_STRUC REGBACapability; // NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0
+#endif // DOT11_N_SUPPORT //
+ IOT_STRUC IOTestParm; // 802.11n InterOpbility Test Parameter;
+ ULONG TxPreamble; // Rt802_11PreambleLong, Rt802_11PreambleShort, Rt802_11PreambleAuto
+ BOOLEAN bUseZeroToDisableFragment; // Microsoft use 0 as disable
+ ULONG UseBGProtection; // 0: auto, 1: always use, 2: always not use
+ BOOLEAN bUseShortSlotTime; // 0: disable, 1 - use short slot (9us)
+ BOOLEAN bEnableTxBurst; // 1: enble TX PACKET BURST, 0: disable TX PACKET BURST
+ BOOLEAN bAggregationCapable; // 1: enable TX aggregation when the peer supports it
+ BOOLEAN bPiggyBackCapable; // 1: enable TX piggy-back according MAC's version
+ BOOLEAN bIEEE80211H; // 1: enable IEEE802.11h spec.
+ ULONG DisableOLBCDetect; // 0: enable OLBC detect; 1 disable OLBC detect
+
+#ifdef DOT11_N_SUPPORT
+ BOOLEAN bRdg;
+#endif // DOT11_N_SUPPORT //
+ BOOLEAN bWmmCapable; // 0:disable WMM, 1:enable WMM
+ QOS_CAPABILITY_PARM APQosCapability; // QOS capability of the current associated AP
+ EDCA_PARM APEdcaParm; // EDCA parameters of the current associated AP
+ QBSS_LOAD_PARM APQbssLoad; // QBSS load of the current associated AP
+ UCHAR AckPolicy[4]; // ACK policy of the specified AC. see ACK_xxx
+#ifdef CONFIG_STA_SUPPORT
+ BOOLEAN bDLSCapable; // 0:disable DLS, 1:enable DLS
+#endif // CONFIG_STA_SUPPORT //
+ // a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
+ // BOOLEAN control, either ON or OFF. These flags should always be accessed via
+ // OPSTATUS_TEST_FLAG(), OPSTATUS_SET_FLAG(), OP_STATUS_CLEAR_FLAG() macros.
+ // see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition
+ ULONG OpStatusFlags;
+
+ BOOLEAN NdisRadioStateOff; //For HCT 12.0, set this flag to TRUE instead of called MlmeRadioOff.
+ ABGBAND_STATE BandState; // For setting BBP used on B/G or A mode.
+ BOOLEAN bRxAntDiversity; // 0:disable, 1:enable Software Rx Antenna Diversity.
+
+ // IEEE802.11H--DFS.
+ RADAR_DETECT_STRUCT RadarDetect;
+
+#ifdef CARRIER_DETECTION_SUPPORT
+ CARRIER_DETECTION CarrierDetect;
+#endif // CARRIER_DETECTION_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+ // HT
+ UCHAR BASize; // USer desired BAWindowSize. Should not exceed our max capability
+ //RT_HT_CAPABILITY SupportedHtPhy;
+ RT_HT_CAPABILITY DesiredHtPhy;
+ HT_CAPABILITY_IE HtCapability;
+ ADD_HT_INFO_IE AddHTInfo; // Useful as AP.
+ //This IE is used with channel switch announcement element when changing to a new 40MHz.
+ //This IE is included in channel switch ammouncement frames 7.4.1.5, beacons, probe Rsp.
+ NEW_EXT_CHAN_IE NewExtChanOffset; //7.3.2.20A, 1 if extension channel is above the control channel, 3 if below, 0 if not present
+
+#ifdef DOT11N_DRAFT3
+ UCHAR Bss2040CoexistFlag; // bit 0: bBssCoexistTimerRunning, bit 1: NeedSyncAddHtInfo.
+ RALINK_TIMER_STRUCT Bss2040CoexistTimer;
+
+ //This IE is used for 20/40 BSS Coexistence.
+ BSS_2040_COEXIST_IE BSS2040CoexistInfo;
+ // ====== 11n D3.0 =======================>
+ USHORT Dot11OBssScanPassiveDwell; // Unit : TU. 5~1000
+ USHORT Dot11OBssScanActiveDwell; // Unit : TU. 10~1000
+ USHORT Dot11BssWidthTriggerScanInt; // Unit : Second
+ USHORT Dot11OBssScanPassiveTotalPerChannel; // Unit : TU. 200~10000
+ USHORT Dot11OBssScanActiveTotalPerChannel; // Unit : TU. 20~10000
+ USHORT Dot11BssWidthChanTranDelayFactor;
+ USHORT Dot11OBssScanActivityThre; // Unit : percentage
+
+ ULONG Dot11BssWidthChanTranDelay; // multiple of (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
+ ULONG CountDownCtr; // CountDown Counter from (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
+
+ NDIS_SPIN_LOCK TriggerEventTabLock;
+ BSS_2040_COEXIST_IE LastBSSCoexist2040;
+ BSS_2040_COEXIST_IE BSSCoexist2040;
+ TRIGGER_EVENT_TAB TriggerEventTab;
+ UCHAR ChannelListIdx;
+ // <====== 11n D3.0 =======================
+ BOOLEAN bOverlapScanning;
+#endif // DOT11N_DRAFT3 //
+
+ BOOLEAN bHTProtect;
+ BOOLEAN bMIMOPSEnable;
+ BOOLEAN bBADecline;
+ BOOLEAN bDisableReordering;
+ BOOLEAN bForty_Mhz_Intolerant;
+ BOOLEAN bExtChannelSwitchAnnouncement;
+ BOOLEAN bRcvBSSWidthTriggerEvents;
+ ULONG LastRcvBSSWidthTriggerEventsTime;
+
+ UCHAR TxBASize;
+#endif // DOT11_N_SUPPORT //
+
+ // Enable wireless event
+ BOOLEAN bWirelessEvent;
+ BOOLEAN bWiFiTest; // Enable this parameter for WiFi test
+
+ // Tx & Rx Stream number selection
+ UCHAR TxStream;
+ UCHAR RxStream;
+
+ // transmit phy mode, trasmit rate for Multicast.
+#ifdef MCAST_RATE_SPECIFIC
+ UCHAR McastTransmitMcs;
+ UCHAR McastTransmitPhyMode;
+#endif // MCAST_RATE_SPECIFIC //
+
+ BOOLEAN bHardwareRadio; // Hardware controlled Radio enabled
+
+#ifdef RT2870
+ BOOLEAN bMultipleIRP; // Multiple Bulk IN flag
+ UCHAR NumOfBulkInIRP; // if bMultipleIRP == TRUE, NumOfBulkInIRP will be 4 otherwise be 1
+ RT_HT_CAPABILITY SupportedHtPhy;
+ ULONG MaxPktOneTxBulk;
+ UCHAR TxBulkFactor;
+ UCHAR RxBulkFactor;
+
+ BEACON_SYNC_STRUCT *pBeaconSync;
+ RALINK_TIMER_STRUCT BeaconUpdateTimer;
+ UINT32 BeaconAdjust;
+ UINT32 BeaconFactor;
+ UINT32 BeaconRemain;
+#endif // RT2870 //
+
+
+ NDIS_SPIN_LOCK MeasureReqTabLock;
+ PMEASURE_REQ_TAB pMeasureReqTab;
+
+ NDIS_SPIN_LOCK TpcReqTabLock;
+ PTPC_REQ_TAB pTpcReqTab;
+
+ // transmit phy mode, trasmit rate for Multicast.
+#ifdef MCAST_RATE_SPECIFIC
+ HTTRANSMIT_SETTING MCastPhyMode;
+#endif // MCAST_RATE_SPECIFIC //
+
+#ifdef SINGLE_SKU
+ UINT16 DefineMaxTxPwr;
+#endif // SINGLE_SKU //
+
+
+} COMMON_CONFIG, *PCOMMON_CONFIG;
+
+
+#ifdef CONFIG_STA_SUPPORT
+/* Modified by Wu Xi-Kun 4/21/2006 */
+// STA configuration and status
+typedef struct _STA_ADMIN_CONFIG {
+ // GROUP 1 -
+ // User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
+ // the user intended configuration, but not necessary fully equal to the final
+ // settings in ACTIVE BSS after negotiation/compromize with the BSS holder (either
+ // AP or IBSS holder).
+ // Once initialized, user configuration can only be changed via OID_xxx
+ UCHAR BssType; // BSS_INFRA or BSS_ADHOC
+ USHORT AtimWin; // used when starting a new IBSS
+
+ // GROUP 2 -
+ // User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
+ // the user intended configuration, and should be always applied to the final
+ // settings in ACTIVE BSS without compromising with the BSS holder.
+ // Once initialized, user configuration can only be changed via OID_xxx
+ UCHAR RssiTrigger;
+ UCHAR RssiTriggerMode; // RSSI_TRIGGERED_UPON_BELOW_THRESHOLD or RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD
+ USHORT DefaultListenCount; // default listen count;
+ ULONG WindowsPowerMode; // Power mode for AC power
+ ULONG WindowsBatteryPowerMode; // Power mode for battery if exists
+ BOOLEAN bWindowsACCAMEnable; // Enable CAM power mode when AC on
+ BOOLEAN bAutoReconnect; // Set to TRUE when setting OID_802_11_SSID with no matching BSSID
+ ULONG WindowsPowerProfile; // Windows power profile, for NDIS5.1 PnP
+
+ // MIB:ieee802dot11.dot11smt(1).dot11StationConfigTable(1)
+ USHORT Psm; // power management mode (PWR_ACTIVE|PWR_SAVE)
+ USHORT DisassocReason;
+ UCHAR DisassocSta[MAC_ADDR_LEN];
+ USHORT DeauthReason;
+ UCHAR DeauthSta[MAC_ADDR_LEN];
+ USHORT AuthFailReason;
+ UCHAR AuthFailSta[MAC_ADDR_LEN];
+
+ NDIS_802_11_PRIVACY_FILTER PrivacyFilter; // PrivacyFilter enum for 802.1X
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
+ NDIS_802_11_WEP_STATUS WepStatus;
+ NDIS_802_11_WEP_STATUS OrigWepStatus; // Original wep status set from OID
+
+ // Add to support different cipher suite for WPA2/WPA mode
+ NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Multicast cipher suite
+ NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher suite
+ BOOLEAN bMixCipher; // Indicate current Pair & Group use different cipher suites
+ USHORT RsnCapability;
+
+ NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
+
+ UCHAR PMK[32]; // WPA PSK mode PMK
+ UCHAR PTK[64]; // WPA PSK mode PTK
+ UCHAR GTK[32]; // GTK from authenticator
+ BSSID_INFO SavedPMK[PMKID_NO];
+ UINT SavedPMKNum; // Saved PMKID number
+
+ UCHAR DefaultKeyId;
+
+
+ // WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED
+ UCHAR PortSecured;
+
+ // For WPA countermeasures
+ ULONG LastMicErrorTime; // record last MIC error time
+ ULONG MicErrCnt; // Should be 0, 1, 2, then reset to zero (after disassoiciation).
+ BOOLEAN bBlockAssoc; // Block associate attempt for 60 seconds after counter measure occurred.
+ // For WPA-PSK supplicant state
+ WPA_STATE WpaState; // Default is SS_NOTUSE and handled by microsoft 802.1x
+ UCHAR ReplayCounter[8];
+ UCHAR ANonce[32]; // ANonce for WPA-PSK from aurhenticator
+ UCHAR SNonce[32]; // SNonce for WPA-PSK
+
+ UCHAR LastSNR0; // last received BEACON's SNR
+ UCHAR LastSNR1; // last received BEACON's SNR for 2nd antenna
+ RSSI_SAMPLE RssiSample;
+ ULONG NumOfAvgRssiSample;
+
+ ULONG LastBeaconRxTime; // OS's timestamp of the last BEACON RX time
+ ULONG Last11bBeaconRxTime; // OS's timestamp of the last 11B BEACON RX time
+ ULONG Last11gBeaconRxTime; // OS's timestamp of the last 11G BEACON RX time
+ ULONG Last20NBeaconRxTime; // OS's timestamp of the last 20MHz N BEACON RX time
+
+ ULONG LastScanTime; // Record last scan time for issue BSSID_SCAN_LIST
+ ULONG ScanCnt; // Scan counts since most recent SSID, BSSID, SCAN OID request
+ BOOLEAN bSwRadio; // Software controlled Radio On/Off, TRUE: On
+ BOOLEAN bHwRadio; // Hardware controlled Radio On/Off, TRUE: On
+ BOOLEAN bRadio; // Radio state, And of Sw & Hw radio state
+ BOOLEAN bHardwareRadio; // Hardware controlled Radio enabled
+ BOOLEAN bShowHiddenSSID; // Show all known SSID in SSID list get operation
+
+ //BOOLEAN AdhocBOnlyJoined; // Indicate Adhoc B Join.
+ //BOOLEAN AdhocBGJoined; // Indicate Adhoc B/G Join.
+ //BOOLEAN Adhoc20NJoined; // Indicate Adhoc 20MHz N Join.
+
+ // New for WPA, windows want us to to keep association information and
+ // Fixed IEs from last association response
+ NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo;
+ USHORT ReqVarIELen; // Length of next VIE include EID & Length
+ UCHAR ReqVarIEs[MAX_VIE_LEN]; // The content saved here should be little-endian format.
+ USHORT ResVarIELen; // Length of next VIE include EID & Length
+ UCHAR ResVarIEs[MAX_VIE_LEN];
+
+ UCHAR RSNIE_Len;
+ UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; // The content saved here should be little-endian format.
+
+ // New variables used for CCX 1.0
+ BOOLEAN bCkipOn;
+ BOOLEAN bCkipCmicOn;
+ UCHAR CkipFlag;
+ UCHAR GIV[3]; //for CCX iv
+ UCHAR RxSEQ[4];
+ UCHAR TxSEQ[4];
+ UCHAR CKIPMIC[4];
+ UCHAR LeapAuthMode;
+ LEAP_AUTH_INFO LeapAuthInfo;
+ UCHAR HashPwd[16];
+ UCHAR NetworkChallenge[8];
+ UCHAR NetworkChallengeResponse[24];
+ UCHAR PeerChallenge[8];
+
+ UCHAR PeerChallengeResponse[24];
+ UCHAR SessionKey[16]; //Network session keys (NSK)
+ RALINK_TIMER_STRUCT LeapAuthTimer;
+ ROGUEAP_TABLE RogueApTab; //Cisco CCX1 Rogue AP Detection
+
+ // New control flags for CCX
+ CCX_CONTROL CCXControl; // Master administration state
+ BOOLEAN CCXEnable; // Actual CCX state
+ UCHAR CCXScanChannel; // Selected channel for CCX beacon request
+ USHORT CCXScanTime; // Time out to wait for beacon and probe response
+ UCHAR CCXReqType; // Current processing CCX request type
+ BSS_TABLE CCXBssTab; // BSS Table
+ UCHAR FrameReportBuf[2048]; // Buffer for creating frame report
+ USHORT FrameReportLen; // Current Frame report length
+ ULONG CLBusyBytes; // Save the total bytes received durning channel load scan time
+ USHORT RPIDensity[8]; // Array for RPI density collection
+ // Start address of each BSS table within FrameReportBuf
+ // It's important to update the RxPower of the corresponding Bss
+ USHORT BssReportOffset[MAX_LEN_OF_BSS_TABLE];
+ USHORT BeaconToken; // Token for beacon report
+ ULONG LastBssIndex; // Most current reported Bss index
+ RM_REQUEST_ACTION MeasurementRequest[16]; // Saved measurement request
+ UCHAR RMReqCnt; // Number of measurement request saved.
+ UCHAR CurrentRMReqIdx; // Number of measurement request saved.
+ BOOLEAN ParallelReq; // Parallel measurement, only one request performed,
+ // It must be the same channel with maximum duration
+ USHORT ParallelDuration; // Maximum duration for parallel measurement
+ UCHAR ParallelChannel; // Only one channel with parallel measurement
+ USHORT IAPPToken; // IAPP dialog token
+ UCHAR CCXQosECWMin; // Cisco QOS ECWMin for AC 0
+ UCHAR CCXQosECWMax; // Cisco QOS ECWMax for AC 0
+ // Hack for channel load and noise histogram parameters
+ UCHAR NHFactor; // Parameter for Noise histogram
+ UCHAR CLFactor; // Parameter for channel load
+
+ UCHAR KRK[16]; //Key Refresh Key.
+ UCHAR BTK[32]; //Base Transient Key
+ BOOLEAN CCKMLinkUpFlag;
+ ULONG CCKMRN; //(Re)Association request number.
+ LARGE_INTEGER CCKMBeaconAtJoinTimeStamp; //TSF timer for Re-assocaite to the new AP
+ UCHAR AironetCellPowerLimit; //in dBm
+ UCHAR AironetIPAddress[4]; //eg. 192.168.1.1
+ BOOLEAN CCXAdjacentAPReportFlag; //flag for determining report Assoc Lost time
+ CHAR CCXAdjacentAPSsid[MAX_LEN_OF_SSID]; //Adjacent AP's SSID report
+ UCHAR CCXAdjacentAPSsidLen; // the actual ssid length in used
+ UCHAR CCXAdjacentAPBssid[MAC_ADDR_LEN]; //Adjacent AP's BSSID report
+ USHORT CCXAdjacentAPChannel;
+ ULONG CCXAdjacentAPLinkDownTime; //for Spec S32.
+
+ RALINK_TIMER_STRUCT StaQuickResponeForRateUpTimer;
+ BOOLEAN StaQuickResponeForRateUpTimerRunning;
+
+ UCHAR DtimCount; // 0.. DtimPeriod-1
+ UCHAR DtimPeriod; // default = 3
+
+#ifdef QOS_DLS_SUPPORT
+ RT_802_11_DLS DLSEntry[MAX_NUM_OF_DLS_ENTRY];
+ UCHAR DlsReplayCounter[8];
+#endif // QOS_DLS_SUPPORT //
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // This is only for WHQL test.
+ BOOLEAN WhqlTest;
+ ////////////////////////////////////////////////////////////////////////////////////////
+
+ RALINK_TIMER_STRUCT WpaDisassocAndBlockAssocTimer;
+ // Fast Roaming
+ BOOLEAN bFastRoaming; // 0:disable fast roaming, 1:enable fast roaming
+ CHAR dBmToRoam; // the condition to roam when receiving Rssi less than this value. It's negative value.
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ BOOLEAN IEEE8021X;
+ BOOLEAN IEEE8021x_required_keys;
+ CIPHER_KEY DesireSharedKey[4]; // Record user desired WEP keys
+ UCHAR DesireSharedKeyId;
+
+ // 0: driver ignores wpa_supplicant
+ // 1: wpa_supplicant initiates scanning and AP selection
+ // 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters
+ UCHAR WpaSupplicantUP;
+ UCHAR WpaSupplicantScanCount;
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ CHAR dev_name[16];
+ USHORT OriDevType;
+
+ BOOLEAN bTGnWifiTest;
+ BOOLEAN bScanReqIsFromWebUI;
+
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
+ DESIRED_TRANSMIT_SETTING DesiredTransmitSetting;
+ RT_HT_PHY_INFO DesiredHtPhyInfo;
+ BOOLEAN bAutoTxRateSwitch;
+
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ UCHAR IEEE80211dClientMode;
+ UCHAR StaOriCountryCode[3];
+ UCHAR StaOriGeography;
+#endif // EXT_BUILD_CHANNEL_LIST //
+} STA_ADMIN_CONFIG, *PSTA_ADMIN_CONFIG;
+
+// This data structure keep the current active BSS/IBSS's configuration that this STA
+// had agreed upon joining the network. Which means these parameters are usually decided
+// by the BSS/IBSS creator instead of user configuration. Data in this data structurre
+// is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE.
+// Normally, after SCAN or failed roaming attempts, we need to recover back to
+// the current active settings.
+typedef struct _STA_ACTIVE_CONFIG {
+ USHORT Aid;
+ USHORT AtimWin; // in kusec; IBSS parameter set element
+ USHORT CapabilityInfo;
+ USHORT CfpMaxDuration;
+ USHORT CfpPeriod;
+
+ // Copy supported rate from desired AP's beacon. We are trying to match
+ // AP's supported and extended rate settings.
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen;
+ UCHAR ExtRateLen;
+ // Copy supported ht from desired AP's beacon. We are trying to match
+ RT_HT_PHY_INFO SupportedPhyInfo;
+ RT_HT_CAPABILITY SupportedHtPhy;
+} STA_ACTIVE_CONFIG, *PSTA_ACTIVE_CONFIG;
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RT2870
+typedef struct RT_ADD_PAIRWISE_KEY_ENTRY {
+ NDIS_802_11_MAC_ADDRESS MacAddr;
+ USHORT MacTabMatchWCID; // ASIC
+ CIPHER_KEY CipherKey;
+} RT_ADD_PAIRWISE_KEY_ENTRY,*PRT_ADD_PAIRWISE_KEY_ENTRY;
+#endif // RT2870 //
+
+// ----------- start of AP --------------------------
+// AUTH-RSP State Machine Aux data structure
+typedef struct _AP_MLME_AUX {
+ UCHAR Addr[MAC_ADDR_LEN];
+ USHORT Alg;
+ CHAR Challenge[CIPHER_TEXT_LEN];
+} AP_MLME_AUX, *PAP_MLME_AUX;
+
+// structure to define WPA Group Key Rekey Interval
+typedef struct PACKED _RT_802_11_WPA_REKEY {
+ ULONG ReKeyMethod; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
+ ULONG ReKeyInterval; // time-based: seconds, packet-based: kilo-packets
+} RT_WPA_REKEY,*PRT_WPA_REKEY, RT_802_11_WPA_REKEY, *PRT_802_11_WPA_REKEY;
+
+typedef struct _MAC_TABLE_ENTRY {
+ //Choose 1 from ValidAsWDS and ValidAsCLI to validize.
+ BOOLEAN ValidAsCLI; // Sta mode, set this TRUE after Linkup,too.
+ BOOLEAN ValidAsWDS; // This is WDS Entry. only for AP mode.
+ BOOLEAN ValidAsApCli; //This is a AP-Client entry, only for AP mode which enable AP-Client functions.
+ BOOLEAN ValidAsMesh;
+ BOOLEAN ValidAsDls; // This is DLS Entry. only for STA mode.
+ BOOLEAN isCached;
+ BOOLEAN bIAmBadAtheros;
+
+ UCHAR EnqueueEapolStartTimerRunning; // Enqueue EAPoL-Start for triggering EAP SM
+ //jan for wpa
+ // record which entry revoke MIC Failure , if it leaves the BSS itself, AP won't update aMICFailTime MIB
+ UCHAR CMTimerRunning;
+ UCHAR apidx; // MBSS number
+ UCHAR RSNIE_Len;
+ UCHAR RSN_IE[MAX_LEN_OF_RSNIE];
+ UCHAR ANonce[LEN_KEY_DESC_NONCE];
+ UCHAR R_Counter[LEN_KEY_DESC_REPLAY];
+ UCHAR PTK[64];
+ UCHAR ReTryCounter;
+ RALINK_TIMER_STRUCT RetryTimer;
+ RALINK_TIMER_STRUCT EnqueueStartForPSKTimer; // A timer which enqueue EAPoL-Start for triggering PSK SM
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
+ NDIS_802_11_WEP_STATUS WepStatus;
+ AP_WPA_STATE WpaState;
+ GTK_STATE GTKState;
+ USHORT PortSecured;
+ NDIS_802_11_PRIVACY_FILTER PrivacyFilter; // PrivacyFilter enum for 802.1X
+ CIPHER_KEY PairwiseKey;
+ PVOID pAd;
+ INT PMKID_CacheIdx;
+ UCHAR PMKID[LEN_PMKID];
+
+
+ UCHAR Addr[MAC_ADDR_LEN];
+ UCHAR PsMode;
+ SST Sst;
+ AUTH_STATE AuthState; // for SHARED KEY authentication state machine used only
+ BOOLEAN IsReassocSta; // Indicate whether this is a reassociation procedure
+ USHORT Aid;
+ USHORT CapabilityInfo;
+ UCHAR LastRssi;
+ ULONG NoDataIdleCount;
+ UINT16 StationKeepAliveCount; // unit: second
+ ULONG PsQIdleCount;
+ QUEUE_HEADER PsQueue;
+
+ UINT32 StaConnectTime; // the live time of this station since associated with AP
+
+
+#ifdef DOT11_N_SUPPORT
+ BOOLEAN bSendBAR;
+ USHORT NoBADataCountDown;
+
+ UINT32 CachedBuf[16]; // UINT (4 bytes) for alignment
+ UINT TxBFCount; // 3*3
+#endif // DOT11_N_SUPPORT //
+ UINT FIFOCount;
+ UINT DebugFIFOCount;
+ UINT DebugTxCount;
+ BOOLEAN bDlsInit;
+
+
+//====================================================
+//WDS entry needs these
+// rt2860 add this. if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab
+ UINT MatchWDSTabIdx;
+ UCHAR MaxSupportedRate;
+ UCHAR CurrTxRate;
+ UCHAR CurrTxRateIndex;
+ // to record the each TX rate's quality. 0 is best, the bigger the worse.
+ USHORT TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
+// USHORT OneSecTxOkCount;
+ UINT32 OneSecTxNoRetryOkCount;
+ UINT32 OneSecTxRetryOkCount;
+ UINT32 OneSecTxFailCount;
+ UINT32 ContinueTxFailCnt;
+ UINT32 CurrTxRateStableTime; // # of second in current TX rate
+ UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
+//====================================================
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ UINT MatchDlsEntryIdx; // indicate the index in pAd->StaCfg.DLSEntry
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+ BOOLEAN fNoisyEnvironment;
+ BOOLEAN fLastSecAccordingRSSI;
+ UCHAR LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
+ CHAR LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
+ ULONG LastTxOkCount;
+ UCHAR PER[MAX_STEP_OF_TX_RATE_SWITCH];
+
+ // a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
+ // BOOLEAN control, either ON or OFF. These flags should always be accessed via
+ // CLIENT_STATUS_TEST_FLAG(), CLIENT_STATUS_SET_FLAG(), CLIENT_STATUS_CLEAR_FLAG() macros.
+ // see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition. fCLIENT_STATUS_AMSDU_INUSED
+ ULONG ClientStatusFlags;
+
+ // TODO: Shall we move that to DOT11_N_SUPPORT???
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
+
+#ifdef DOT11_N_SUPPORT
+ // HT EWC MIMO-N used parameters
+ USHORT RXBAbitmap; // fill to on-chip RXWI_BA_BITMASK in 8.1.3RX attribute entry format
+ USHORT TXBAbitmap; // This bitmap as originator, only keep in software used to mark AMPDU bit in TXWI
+ USHORT TXAutoBAbitmap;
+ USHORT BADeclineBitmap;
+ USHORT BARecWcidArray[NUM_OF_TID]; // The mapping wcid of recipient session. if RXBAbitmap bit is masked
+ USHORT BAOriWcidArray[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
+ USHORT BAOriSequence[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
+
+ // 802.11n features.
+ UCHAR MpduDensity;
+ UCHAR MaxRAmpduFactor;
+ UCHAR AMsduSize;
+ UCHAR MmpsMode; // MIMO power save more.
+
+ HT_CAPABILITY_IE HTCapability;
+
+#ifdef DOT11N_DRAFT3
+ UCHAR BSS2040CoexistenceMgmtSupport;
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+ BOOLEAN bAutoTxRateSwitch;
+
+ UCHAR RateLen;
+ struct _MAC_TABLE_ENTRY *pNext;
+ USHORT TxSeq[NUM_OF_TID];
+ USHORT NonQosDataSeq;
+
+ RSSI_SAMPLE RssiSample;
+
+ UINT32 TXMCSExpected[16];
+ UINT32 TXMCSSuccessful[16];
+ UINT32 TXMCSFailed[16];
+ UINT32 TXMCSAutoFallBack[16][16];
+
+#ifdef CONFIG_STA_SUPPORT
+ ULONG LastBeaconRxTime;
+#endif // CONFIG_STA_SUPPORT //
+} MAC_TABLE_ENTRY, *PMAC_TABLE_ENTRY;
+
+typedef struct _MAC_TABLE {
+ USHORT Size;
+ MAC_TABLE_ENTRY *Hash[HASH_TABLE_SIZE];
+ MAC_TABLE_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
+ QUEUE_HEADER McastPsQueue;
+ ULONG PsQIdleCount;
+ BOOLEAN fAnyStationInPsm;
+ BOOLEAN fAnyStationBadAtheros; // Check if any Station is atheros 802.11n Chip. We need to use RTS/CTS with Atheros 802,.11n chip.
+ BOOLEAN fAnyTxOPForceDisable; // Check if it is necessary to disable BE TxOP
+ BOOLEAN fAllStationAsRalink; // Check if all stations are ralink-chipset
+#ifdef DOT11_N_SUPPORT
+ BOOLEAN fAnyStationIsLegacy; // Check if I use legacy rate to transmit to my BSS Station/
+ BOOLEAN fAnyStationNonGF; // Check if any Station can't support GF.
+ BOOLEAN fAnyStation20Only; // Check if any Station can't support GF.
+ BOOLEAN fAnyStationMIMOPSDynamic; // Check if any Station is MIMO Dynamic
+ BOOLEAN fAnyBASession; // Check if there is BA session. Force turn on RTS/CTS
+#endif // DOT11_N_SUPPORT //
+} MAC_TABLE, *PMAC_TABLE;
+
+#ifdef DOT11_N_SUPPORT
+#define IS_HT_STA(_pMacEntry) \
+ (_pMacEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX)
+
+#define IS_HT_RATE(_pMacEntry) \
+ (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
+
+#define PEER_IS_HT_RATE(_pMacEntry) \
+ (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
+#endif // DOT11_N_SUPPORT //
+
+typedef struct _WDS_ENTRY {
+ BOOLEAN Valid;
+ UCHAR Addr[MAC_ADDR_LEN];
+ ULONG NoDataIdleCount;
+ struct _WDS_ENTRY *pNext;
+} WDS_ENTRY, *PWDS_ENTRY;
+
+typedef struct _WDS_TABLE_ENTRY {
+ USHORT Size;
+ UCHAR WdsAddr[MAC_ADDR_LEN];
+ WDS_ENTRY *Hash[HASH_TABLE_SIZE];
+ WDS_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
+ UCHAR MaxSupportedRate;
+ UCHAR CurrTxRate;
+ USHORT TxQuality[MAX_LEN_OF_SUPPORTED_RATES];
+ USHORT OneSecTxOkCount;
+ USHORT OneSecTxRetryOkCount;
+ USHORT OneSecTxFailCount;
+ ULONG CurrTxRateStableTime; // # of second in current TX rate
+ UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
+} WDS_TABLE_ENTRY, *PWDS_TABLE_ENTRY;
+
+typedef struct _RT_802_11_WDS_ENTRY {
+ PNET_DEV dev;
+ UCHAR Valid;
+ UCHAR PhyMode;
+ UCHAR PeerWdsAddr[MAC_ADDR_LEN];
+ UCHAR MacTabMatchWCID; // ASIC
+ NDIS_802_11_WEP_STATUS WepStatus;
+ UCHAR KeyIdx;
+ CIPHER_KEY WdsKey;
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
+ RT_HT_PHY_INFO DesiredHtPhyInfo;
+ BOOLEAN bAutoTxRateSwitch;
+ DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting.
+} RT_802_11_WDS_ENTRY, *PRT_802_11_WDS_ENTRY;
+
+typedef struct _WDS_TABLE {
+ UCHAR Mode;
+ ULONG Size;
+ RT_802_11_WDS_ENTRY WdsEntry[MAX_WDS_ENTRY];
+} WDS_TABLE, *PWDS_TABLE;
+
+typedef struct _APCLI_STRUCT {
+ PNET_DEV dev;
+#ifdef RTL865X_SOC
+ unsigned int mylinkid;
+#endif
+ BOOLEAN Enable; // Set it as 1 if the apcli interface was configured to "1" or by iwpriv cmd "ApCliEnable"
+ BOOLEAN Valid; // Set it as 1 if the apcli interface associated success to remote AP.
+ UCHAR MacTabWCID; //WCID value, which point to the entry of ASIC Mac table.
+ UCHAR SsidLen;
+ CHAR Ssid[MAX_LEN_OF_SSID];
+
+ UCHAR CfgSsidLen;
+ CHAR CfgSsid[MAX_LEN_OF_SSID];
+ UCHAR CfgApCliBssid[ETH_LENGTH_OF_ADDRESS];
+ UCHAR CurrentAddress[ETH_LENGTH_OF_ADDRESS];
+
+ ULONG ApCliRcvBeaconTime;
+
+ ULONG CtrlCurrState;
+ ULONG SyncCurrState;
+ ULONG AuthCurrState;
+ ULONG AssocCurrState;
+ ULONG WpaPskCurrState;
+
+ USHORT AuthReqCnt;
+ USHORT AssocReqCnt;
+
+ ULONG ClientStatusFlags;
+ UCHAR MpduDensity;
+
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
+ NDIS_802_11_WEP_STATUS WepStatus;
+
+ // Add to support different cipher suite for WPA2/WPA mode
+ NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Multicast cipher suite
+ NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher suite
+ BOOLEAN bMixCipher; // Indicate current Pair & Group use different cipher suites
+ USHORT RsnCapability;
+
+ UCHAR PSK[100]; // reserve PSK key material
+ UCHAR PSKLen;
+ UCHAR PMK[32]; // WPA PSK mode PMK
+ //UCHAR PTK[64]; // WPA PSK mode PTK
+ UCHAR GTK[32]; // GTK from authenticator
+
+ //CIPHER_KEY PairwiseKey;
+ CIPHER_KEY SharedKey[SHARE_KEY_NUM];
+ UCHAR DefaultKeyId;
+
+ // WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED
+ //UCHAR PortSecured;
+
+ // store RSN_IE built by driver
+ UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; // The content saved here should be convert to little-endian format.
+ UCHAR RSNIE_Len;
+
+ // For WPA countermeasures
+ ULONG LastMicErrorTime; // record last MIC error time
+ //ULONG MicErrCnt; // Should be 0, 1, 2, then reset to zero (after disassoiciation).
+ BOOLEAN bBlockAssoc; // Block associate attempt for 60 seconds after counter measure occurred.
+
+ // For WPA-PSK supplicant state
+ //WPA_STATE WpaState; // Default is SS_NOTUSE
+ //UCHAR ReplayCounter[8];
+ //UCHAR ANonce[32]; // ANonce for WPA-PSK from authenticator
+ UCHAR SNonce[32]; // SNonce for WPA-PSK
+ UCHAR GNonce[32]; // GNonce for WPA-PSK from authenticator
+
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
+ RT_HT_PHY_INFO DesiredHtPhyInfo;
+ BOOLEAN bAutoTxRateSwitch;
+ DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting.
+} APCLI_STRUCT, *PAPCLI_STRUCT;
+
+// ----------- end of AP ----------------------------
+
+#ifdef BLOCK_NET_IF
+typedef struct _BLOCK_QUEUE_ENTRY
+{
+ BOOLEAN SwTxQueueBlockFlag;
+ LIST_HEADER NetIfList;
+} BLOCK_QUEUE_ENTRY, *PBLOCK_QUEUE_ENTRY;
+#endif // BLOCK_NET_IF //
+
+
+struct wificonf
+{
+ BOOLEAN bShortGI;
+ BOOLEAN bGreenField;
+};
+
+
+
+
+typedef struct _INF_PCI_CONFIG
+{
+ PUCHAR CSRBaseAddress; // PCI MMIO Base Address, all access will use
+}INF_PCI_CONFIG;
+
+typedef struct _INF_USB_CONFIG
+{
+ UINT BulkInEpAddr; // bulk-in endpoint address
+ UINT BulkOutEpAddr[6]; // bulk-out endpoint address
+
+}INF_USB_CONFIG;
+
+#ifdef IKANOS_VX_1X0
+ typedef void (*IkanosWlanTxCbFuncP)(void *, void *);
+
+ struct IKANOS_TX_INFO
+ {
+ struct net_device *netdev;
+ IkanosWlanTxCbFuncP *fp;
+ };
+#endif // IKANOS_VX_1X0 //
+
+#ifdef NINTENDO_AP
+typedef struct _NINDO_CTRL_BLOCK {
+
+ RT_NINTENDO_TABLE DS_TABLE;
+
+#ifdef CHIP25XX
+ spinlock_t NINTENDO_TABLE_Lock;
+#else
+ NDIS_SPIN_LOCK NINTENDO_TABLE_Lock;
+#endif // CHIP25XX //
+
+ UCHAR NINTENDO_UP_BUFFER[512];
+ UCHAR Local_KeyIdx;
+ CIPHER_KEY Local_SharedKey;
+ UCHAR Local_bHideSsid;
+ UCHAR Local_AuthMode;
+ UCHAR Local_WepStatus;
+ USHORT Local_CapabilityInfo;
+} NINDO_CTRL_BLOCK;
+#endif // NINTENDO_AP //
+
+
+#ifdef DBG_DIAGNOSE
+#define DIAGNOSE_TIME 10 // 10 sec
+typedef struct _RtmpDiagStrcut_
+{ // Diagnosis Related element
+ unsigned char inited;
+ unsigned char qIdx;
+ unsigned char ArrayStartIdx;
+ unsigned char ArrayCurIdx;
+ // Tx Related Count
+ USHORT TxDataCnt[DIAGNOSE_TIME];
+ USHORT TxFailCnt[DIAGNOSE_TIME];
+// USHORT TxDescCnt[DIAGNOSE_TIME][16]; // TxDesc queue length in scale of 0~14, >=15
+ USHORT TxDescCnt[DIAGNOSE_TIME][24]; // 3*3 // TxDesc queue length in scale of 0~14, >=15
+// USHORT TxMcsCnt[DIAGNOSE_TIME][16]; // TxDate MCS Count in range from 0 to 15, step in 1.
+ USHORT TxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
+ USHORT TxSWQueCnt[DIAGNOSE_TIME][9]; // TxSwQueue length in scale of 0, 1, 2, 3, 4, 5, 6, 7, >=8
+
+ USHORT TxAggCnt[DIAGNOSE_TIME];
+ USHORT TxNonAggCnt[DIAGNOSE_TIME];
+// USHORT TxAMPDUCnt[DIAGNOSE_TIME][16]; // 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1.
+ USHORT TxAMPDUCnt[DIAGNOSE_TIME][24]; // 3*3 // 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1.
+ USHORT TxRalinkCnt[DIAGNOSE_TIME]; // TxRalink Aggregation Count in 1 sec scale.
+ USHORT TxAMSDUCnt[DIAGNOSE_TIME]; // TxAMSUD Aggregation Count in 1 sec scale.
+
+ // Rx Related Count
+ USHORT RxDataCnt[DIAGNOSE_TIME]; // Rx Total Data count.
+ USHORT RxCrcErrCnt[DIAGNOSE_TIME];
+// USHORT RxMcsCnt[DIAGNOSE_TIME][16]; // Rx MCS Count in range from 0 to 15, step in 1.
+ USHORT RxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
+}RtmpDiagStruct;
+#endif // DBG_DIAGNOSE //
+
+
+//
+// The miniport adapter structure
+//
+typedef struct _RTMP_ADAPTER
+{
+ PVOID OS_Cookie; // save specific structure relative to OS
+ PNET_DEV net_dev;
+ ULONG VirtualIfCnt;
+
+
+
+ NDIS_SPIN_LOCK irq_lock;
+ UCHAR irq_disabled;
+
+#ifdef RT2870
+/*****************************************************************************************/
+/* USB related parameters */
+/*****************************************************************************************/
+ struct usb_config_descriptor *config;
+ UINT BulkInEpAddr; // bulk-in endpoint address
+ UINT BulkOutEpAddr[6]; // bulk-out endpoint address
+
+ UINT NumberOfPipes;
+ USHORT BulkOutMaxPacketSize;
+ USHORT BulkInMaxPacketSize;
+
+ //======Control Flags
+ LONG PendingIoCount;
+ ULONG BulkFlags;
+ BOOLEAN bUsbTxBulkAggre; // Flags for bulk out data priority
+
+
+ //======Timer Thread
+ RT2870_TIMER_QUEUE TimerQ;
+ NDIS_SPIN_LOCK TimerQLock;
+
+
+ //======Cmd Thread
+ CmdQ CmdQ;
+ NDIS_SPIN_LOCK CmdQLock; // CmdQLock spinlock
+
+ BOOLEAN TimerFunc_kill;
+ BOOLEAN mlme_kill;
+
+
+ //======Semaphores (event)
+ struct semaphore mlme_semaphore; /* to sleep thread on */
+ struct semaphore RTUSBCmd_semaphore; /* to sleep thread on */
+ struct semaphore RTUSBTimer_semaphore;
+#ifdef INF_AMAZON_SE
+ struct semaphore UsbVendorReq_semaphore;
+ PVOID UsbVendorReqBuf;
+#endif // INF_AMAZON_SE //
+ struct completion TimerQComplete;
+ struct completion mlmeComplete;
+ struct completion CmdQComplete;
+ wait_queue_head_t *wait;
+
+ //======Lock for 2870 ATE
+#ifdef RALINK_ATE
+ NDIS_SPIN_LOCK GenericLock; // ATE Tx/Rx generic spinlock
+#endif // RALINK_ATE //
+
+#endif // RT2870 //
+
+
+/*****************************************************************************************/
+ /* Both PCI/USB related parameters */
+/*****************************************************************************************/
+
+
+/*****************************************************************************************/
+/* Tx related parameters */
+/*****************************************************************************************/
+ BOOLEAN DeQueueRunning[NUM_OF_TX_RING]; // for ensuring RTUSBDeQueuePacket get call once
+ NDIS_SPIN_LOCK DeQueueLock[NUM_OF_TX_RING];
+
+#ifdef RT2870
+ // Data related context and AC specified, 4 AC supported
+ NDIS_SPIN_LOCK BulkOutLock[6]; // BulkOut spinlock for 4 ACs
+ NDIS_SPIN_LOCK MLMEBulkOutLock; // MLME BulkOut lock
+
+ HT_TX_CONTEXT TxContext[NUM_OF_TX_RING];
+ NDIS_SPIN_LOCK TxContextQueueLock[NUM_OF_TX_RING]; // TxContextQueue spinlock
+
+ // 4 sets of Bulk Out index and pending flag
+ UCHAR NextBulkOutIndex[4]; // only used for 4 EDCA bulkout pipe
+
+ BOOLEAN BulkOutPending[6]; // used for total 6 bulkout pipe
+ UCHAR bulkResetPipeid;
+ BOOLEAN MgmtBulkPending;
+ ULONG bulkResetReq[6];
+#endif // RT2870 //
+
+ // resource for software backlog queues
+ QUEUE_HEADER TxSwQueue[NUM_OF_TX_RING]; // 4 AC + 1 HCCA
+ NDIS_SPIN_LOCK TxSwQueueLock[NUM_OF_TX_RING]; // TxSwQueue spinlock
+
+ RTMP_DMABUF MgmtDescRing; // Shared memory for MGMT descriptors
+ RTMP_MGMT_RING MgmtRing;
+ NDIS_SPIN_LOCK MgmtRingLock; // Prio Ring spinlock
+
+
+/*****************************************************************************************/
+/* Rx related parameters */
+/*****************************************************************************************/
+
+
+#ifdef RT2870
+ RX_CONTEXT RxContext[RX_RING_SIZE]; // 1 for redundant multiple IRP bulk in.
+ NDIS_SPIN_LOCK BulkInLock; // BulkIn spinlock for 4 ACs
+ UCHAR PendingRx; // The Maxima pending Rx value should be RX_RING_SIZE.
+ UCHAR NextRxBulkInIndex; // Indicate the current RxContext Index which hold by Host controller.
+ UCHAR NextRxBulkInReadIndex; // Indicate the current RxContext Index which driver can read & process it.
+ ULONG NextRxBulkInPosition; // Want to contatenate 2 URB buffer while 1st is bulkin failed URB. This Position is 1st URB TransferLength.
+ ULONG TransferBufferLength; // current length of the packet buffer
+ ULONG ReadPosition; // current read position in a packet buffer
+#endif // RT2870 //
+
+
+/*****************************************************************************************/
+/* ASIC related parameters */
+/*****************************************************************************************/
+ UINT32 MACVersion; // MAC version. Record rt2860C(0x28600100) or rt2860D (0x28600101)..
+
+ // ---------------------------
+ // E2PROM
+ // ---------------------------
+ ULONG EepromVersion; // byte 0: version, byte 1: revision, byte 2~3: unused
+ UCHAR EEPROMAddressNum; // 93c46=6 93c66=8
+ USHORT EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS];
+ BOOLEAN EepromAccess;
+ UCHAR EFuseTag;
+ ULONG FirmwareVersion; // byte 0: Minor version, byte 1: Major version, otherwise unused.
+
+ // ---------------------------
+ // BBP Control
+ // ---------------------------
+ UCHAR BbpWriteLatch[140]; // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID
+ UCHAR BbpRssiToDbmDelta;
+ BBP_R66_TUNING BbpTuning;
+
+ // ----------------------------
+ // RFIC control
+ // ----------------------------
+ UCHAR RfIcType; // RFIC_xxx
+ ULONG RfFreqOffset; // Frequency offset for channel switching
+ RTMP_RF_REGS LatchRfRegs; // latch th latest RF programming value since RF IC doesn't support READ
+
+ EEPROM_ANTENNA_STRUC Antenna; // Since ANtenna definition is different for a & g. We need to save it for future reference.
+ EEPROM_NIC_CONFIG2_STRUC NicConfig2;
+
+ // This soft Rx Antenna Diversity mechanism is used only when user set
+ // RX Antenna = DIVERSITY ON
+ SOFT_RX_ANT_DIVERSITY RxAnt;
+
+ UCHAR RFProgSeq;
+ CHANNEL_TX_POWER TxPower[MAX_NUM_OF_CHANNELS]; // Store Tx power value for all channels.
+ CHANNEL_TX_POWER ChannelList[MAX_NUM_OF_CHANNELS]; // list all supported channels for site survey
+ CHANNEL_11J_TX_POWER TxPower11J[MAX_NUM_OF_11JCHANNELS]; // 802.11j channel and bw
+ CHANNEL_11J_TX_POWER ChannelList11J[MAX_NUM_OF_11JCHANNELS]; // list all supported channels for site survey
+
+ UCHAR ChannelListNum; // number of channel in ChannelList[]
+ UCHAR Bbp94;
+ BOOLEAN BbpForCCK;
+ ULONG Tx20MPwrCfgABand[5];
+ ULONG Tx20MPwrCfgGBand[5];
+ ULONG Tx40MPwrCfgABand[5];
+ ULONG Tx40MPwrCfgGBand[5];
+
+ BOOLEAN bAutoTxAgcA; // Enable driver auto Tx Agc control
+ UCHAR TssiRefA; // Store Tssi reference value as 25 temperature.
+ UCHAR TssiPlusBoundaryA[5]; // Tssi boundary for increase Tx power to compensate.
+ UCHAR TssiMinusBoundaryA[5]; // Tssi boundary for decrease Tx power to compensate.
+ UCHAR TxAgcStepA; // Store Tx TSSI delta increment / decrement value
+ CHAR TxAgcCompensateA; // Store the compensation (TxAgcStep * (idx-1))
+
+ BOOLEAN bAutoTxAgcG; // Enable driver auto Tx Agc control
+ UCHAR TssiRefG; // Store Tssi reference value as 25 temperature.
+ UCHAR TssiPlusBoundaryG[5]; // Tssi boundary for increase Tx power to compensate.
+ UCHAR TssiMinusBoundaryG[5]; // Tssi boundary for decrease Tx power to compensate.
+ UCHAR TxAgcStepG; // Store Tx TSSI delta increment / decrement value
+ CHAR TxAgcCompensateG; // Store the compensation (TxAgcStep * (idx-1))
+
+ //+++For RT2870, the parameteres is start from BGRssiOffset1 ~ BGRssiOffset3
+ CHAR BGRssiOffset0; // Store B/G RSSI#0 Offset value on EEPROM 0x46h
+ CHAR BGRssiOffset1; // Store B/G RSSI#1 Offset value
+ CHAR BGRssiOffset2; // Store B/G RSSI#2 Offset value
+ //---
+
+ //+++For RT2870, the parameteres is start from ARssiOffset1 ~ ARssiOffset3
+ CHAR ARssiOffset0; // Store A RSSI#0 Offset value on EEPROM 0x4Ah
+ CHAR ARssiOffset1; // Store A RSSI#1 Offset value
+ CHAR ARssiOffset2; // Store A RSSI#2 Offset value
+ //---
+
+ CHAR BLNAGain; // Store B/G external LNA#0 value on EEPROM 0x44h
+ CHAR ALNAGain0; // Store A external LNA#0 value for ch36~64
+ CHAR ALNAGain1; // Store A external LNA#1 value for ch100~128
+ CHAR ALNAGain2; // Store A external LNA#2 value for ch132~165
+
+ // ----------------------------
+ // LED control
+ // ----------------------------
+ MCU_LEDCS_STRUC LedCntl;
+ USHORT Led1; // read from EEPROM 0x3c
+ USHORT Led2; // EEPROM 0x3e
+ USHORT Led3; // EEPROM 0x40
+ UCHAR LedIndicatorStregth;
+ UCHAR RssiSingalstrengthOffet;
+ BOOLEAN bLedOnScanning;
+ UCHAR LedStatus;
+
+/*****************************************************************************************/
+/* 802.11 related parameters */
+/*****************************************************************************************/
+ // outgoing BEACON frame buffer and corresponding TXD
+ TXWI_STRUC BeaconTxWI;
+ PUCHAR BeaconBuf;
+ USHORT BeaconOffset[HW_BEACON_MAX_COUNT];
+
+ // pre-build PS-POLL and NULL frame upon link up. for efficiency purpose.
+ PSPOLL_FRAME PsPollFrame;
+ HEADER_802_11 NullFrame;
+
+#ifdef RT2870
+ TX_CONTEXT BeaconContext[BEACON_RING_SIZE];
+ TX_CONTEXT NullContext;
+ TX_CONTEXT PsPollContext;
+ TX_CONTEXT RTSContext;
+#endif // RT2870 //
+
+
+
+//=========AP===========
+
+
+//=======STA===========
+#ifdef CONFIG_STA_SUPPORT
+/* Modified by Wu Xi-Kun 4/21/2006 */
+ // -----------------------------------------------
+ // STA specific configuration & operation status
+ // used only when pAd->OpMode == OPMODE_STA
+ // -----------------------------------------------
+ STA_ADMIN_CONFIG StaCfg; // user desired settings
+ STA_ACTIVE_CONFIG StaActive; // valid only when ADHOC_ON(pAd) || INFRA_ON(pAd)
+ CHAR nickname[IW_ESSID_MAX_SIZE+1]; // nickname, only used in the iwconfig i/f
+ NDIS_MEDIA_STATE PreMediaState;
+#endif // CONFIG_STA_SUPPORT //
+
+//=======Common===========
+ // OP mode: either AP or STA
+ UCHAR OpMode; // OPMODE_STA, OPMODE_AP
+
+ NDIS_MEDIA_STATE IndicateMediaState; // Base on Indication state, default is NdisMediaStateDisConnected
+
+
+ // MAT related parameters
+
+ // configuration: read from Registry & E2PROM
+ BOOLEAN bLocalAdminMAC; // Use user changed MAC
+ UCHAR PermanentAddress[MAC_ADDR_LEN]; // Factory default MAC address
+ UCHAR CurrentAddress[MAC_ADDR_LEN]; // User changed MAC address
+
+ // ------------------------------------------------------
+ // common configuration to both OPMODE_STA and OPMODE_AP
+ // ------------------------------------------------------
+ COMMON_CONFIG CommonCfg;
+ MLME_STRUCT Mlme;
+
+ // AP needs those vaiables for site survey feature.
+ MLME_AUX MlmeAux; // temporary settings used during MLME state machine
+ BSS_TABLE ScanTab; // store the latest SCAN result
+
+ //About MacTab, the sta driver will use #0 and #1 for multicast and AP.
+ MAC_TABLE MacTab; // ASIC on-chip WCID entry table. At TX, ASIC always use key according to this on-chip table.
+ NDIS_SPIN_LOCK MacTabLock;
+
+#ifdef DOT11_N_SUPPORT
+ BA_TABLE BATable;
+#endif // DOT11_N_SUPPORT //
+ NDIS_SPIN_LOCK BATabLock;
+ RALINK_TIMER_STRUCT RECBATimer;
+
+ // encryption/decryption KEY tables
+ CIPHER_KEY SharedKey[MAX_MBSSID_NUM][4]; // STA always use SharedKey[BSS0][0..3]
+
+ // RX re-assembly buffer for fragmentation
+ FRAGMENT_FRAME FragFrame; // Frame storage for fragment frame
+
+ // various Counters
+ COUNTER_802_3 Counters8023; // 802.3 counters
+ COUNTER_802_11 WlanCounters; // 802.11 MIB counters
+ COUNTER_RALINK RalinkCounters; // Ralink propriety counters
+ COUNTER_DRS DrsCounters; // counters for Dynamic TX Rate Switching
+ PRIVATE_STRUC PrivateInfo; // Private information & counters
+
+ // flags, see fRTMP_ADAPTER_xxx flags
+ ULONG Flags; // Represent current device status
+
+ // current TX sequence #
+ USHORT Sequence;
+
+#ifdef UNDER_CE
+ NDIS_HANDLE hGiISR;
+#endif
+
+
+ // Control disconnect / connect event generation
+ //+++Didn't used anymore
+ ULONG LinkDownTime;
+ //---
+ ULONG LastRxRate;
+ ULONG LastTxRate;
+ //+++Used only for Station
+ BOOLEAN bConfigChanged; // Config Change flag for the same SSID setting
+ //---
+
+ ULONG ExtraInfo; // Extra information for displaying status
+ ULONG SystemErrorBitmap; // b0: E2PROM version error
+
+ //+++Didn't used anymore
+ ULONG MacIcVersion; // MAC/BBP serial interface issue solved after ver.D
+ //---
+
+ // ---------------------------
+ // System event log
+ // ---------------------------
+ RT_802_11_EVENT_TABLE EventTab;
+
+
+ BOOLEAN HTCEnable;
+
+ /*****************************************************************************************/
+ /* Statistic related parameters */
+ /*****************************************************************************************/
+#ifdef RT2870
+ ULONG BulkOutDataOneSecCount;
+ ULONG BulkInDataOneSecCount;
+ ULONG BulkLastOneSecCount; // BulkOutDataOneSecCount + BulkInDataOneSecCount
+ ULONG watchDogRxCnt;
+ ULONG watchDogRxOverFlowCnt;
+ ULONG watchDogTxPendingCnt[NUM_OF_TX_RING];
+#endif // RT2870 //
+
+ BOOLEAN bUpdateBcnCntDone;
+ ULONG watchDogMacDeadlock; // prevent MAC/BBP into deadlock condition
+ // ----------------------------
+ // DEBUG paramerts
+ // ----------------------------
+ //ULONG DebugSetting[4];
+ BOOLEAN bBanAllBaSetup;
+ BOOLEAN bPromiscuous;
+
+ // ----------------------------
+ // rt2860c emulation-use Parameters
+ // ----------------------------
+ ULONG rtsaccu[30];
+ ULONG ctsaccu[30];
+ ULONG cfendaccu[30];
+ ULONG bacontent[16];
+ ULONG rxint[RX_RING_SIZE+1];
+ UCHAR rcvba[60];
+ BOOLEAN bLinkAdapt;
+ BOOLEAN bForcePrintTX;
+ BOOLEAN bForcePrintRX;
+ BOOLEAN bDisablescanning; //defined in RT2870 USB
+ BOOLEAN bStaFifoTest;
+ BOOLEAN bProtectionTest;
+ BOOLEAN bHCCATest;
+ BOOLEAN bGenOneHCCA;
+ BOOLEAN bBroadComHT;
+ //+++Following add from RT2870 USB.
+ ULONG BulkOutReq;
+ ULONG BulkOutComplete;
+ ULONG BulkOutCompleteOther;
+ ULONG BulkOutCompleteCancel; // seems not use now?
+ ULONG BulkInReq;
+ ULONG BulkInComplete;
+ ULONG BulkInCompleteFail;
+ //---
+
+ struct wificonf WIFItestbed;
+
+#ifdef RALINK_ATE
+ ATE_INFO ate;
+#ifdef RT2870
+ BOOLEAN ContinBulkOut; //ATE bulk out control
+ BOOLEAN ContinBulkIn; //ATE bulk in control
+ atomic_t BulkOutRemained;
+ atomic_t BulkInRemained;
+#endif // RT2870 //
+#endif // RALINK_ATE //
+
+#ifdef DOT11_N_SUPPORT
+ struct reordering_mpdu_pool mpdu_blk_pool;
+#endif // DOT11_N_SUPPORT //
+
+ ULONG OneSecondnonBEpackets; // record non BE packets per second
+
+#if WIRELESS_EXT >= 12
+ struct iw_statistics iw_stats;
+#endif
+
+ struct net_device_stats stats;
+
+#ifdef BLOCK_NET_IF
+ BLOCK_QUEUE_ENTRY blockQueueTab[NUM_OF_TX_RING];
+#endif // BLOCK_NET_IF //
+
+
+
+#ifdef MULTIPLE_CARD_SUPPORT
+ INT32 MC_RowID;
+ UCHAR MC_FileName[256];
+#endif // MULTIPLE_CARD_SUPPORT //
+
+ ULONG TbttTickCount;
+#ifdef PCI_MSI_SUPPORT
+ BOOLEAN HaveMsi;
+#endif // PCI_MSI_SUPPORT //
+
+
+ UCHAR is_on;
+
+#define TIME_BASE (1000000/OS_HZ)
+#define TIME_ONE_SECOND (1000000/TIME_BASE)
+ UCHAR flg_be_adjust;
+ ULONG be_adjust_last_time;
+
+#ifdef NINTENDO_AP
+ NINDO_CTRL_BLOCK nindo_ctrl_block;
+#endif // NINTENDO_AP //
+
+
+#ifdef IKANOS_VX_1X0
+ struct IKANOS_TX_INFO IkanosTxInfo;
+ struct IKANOS_TX_INFO IkanosRxInfo[MAX_MBSSID_NUM + MAX_WDS_ENTRY + MAX_APCLI_NUM + MAX_MESH_NUM];
+#endif // IKANOS_VX_1X0 //
+
+
+#ifdef DBG_DIAGNOSE
+ RtmpDiagStruct DiagStruct;
+#endif // DBG_DIAGNOSE //
+
+
+ UINT8 PM_FlgSuspend;
+
+#ifdef RT30xx
+//======efuse
+ BOOLEAN bUseEfuse;
+ BOOLEAN bEEPROMFile;
+#endif // RT30xx //
+
+} RTMP_ADAPTER, *PRTMP_ADAPTER;
+
+//
+// Cisco IAPP format
+//
+typedef struct _CISCO_IAPP_CONTENT_
+{
+ USHORT Length; //IAPP Length
+ UCHAR MessageType; //IAPP type
+ UCHAR FunctionCode; //IAPP function type
+ UCHAR DestinaionMAC[MAC_ADDR_LEN];
+ UCHAR SourceMAC[MAC_ADDR_LEN];
+ USHORT Tag; //Tag(element IE) - Adjacent AP report
+ USHORT TagLength; //Length of element not including 4 byte header
+ UCHAR OUI[4]; //0x00, 0x40, 0x96, 0x00
+ UCHAR PreviousAP[MAC_ADDR_LEN]; //MAC Address of access point
+ USHORT Channel;
+ USHORT SsidLen;
+ UCHAR Ssid[MAX_LEN_OF_SSID];
+ USHORT Seconds; //Seconds that the client has been disassociated.
+} CISCO_IAPP_CONTENT, *PCISCO_IAPP_CONTENT;
+
+#define DELAYINTMASK 0x0003fffb
+#define INTMASK 0x0003fffb
+#define IndMask 0x0003fffc
+#define RxINT 0x00000005 // Delayed Rx or indivi rx
+#define TxDataInt 0x000000fa // Delayed Tx or indivi tx
+#define TxMgmtInt 0x00000102 // Delayed Tx or indivi tx
+#define TxCoherent 0x00020000 // tx coherent
+#define RxCoherent 0x00010000 // rx coherent
+#define McuCommand 0x00000200 // mcu
+#define PreTBTTInt 0x00001000 // Pre-TBTT interrupt
+#define TBTTInt 0x00000800 // TBTT interrupt
+#define GPTimeOutInt 0x00008000 // GPtimeout interrupt
+#define AutoWakeupInt 0x00004000 // AutoWakeupInt interrupt
+#define FifoStaFullInt 0x00002000 // fifo statistics full interrupt
+
+
+typedef struct _RX_BLK_
+{
+// RXD_STRUC RxD; // sample
+ RT28XX_RXD_STRUC RxD;
+ PRXWI_STRUC pRxWI;
+ PHEADER_802_11 pHeader;
+ PNDIS_PACKET pRxPacket;
+ UCHAR *pData;
+ USHORT DataSize;
+ USHORT Flags;
+ UCHAR UserPriority; // for calculate TKIP MIC using
+} RX_BLK;
+
+
+#define RX_BLK_SET_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags |= _flag)
+#define RX_BLK_TEST_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags & _flag)
+#define RX_BLK_CLEAR_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags &= ~(_flag))
+
+
+#define fRX_WDS 0x0001
+#define fRX_AMSDU 0x0002
+#define fRX_ARALINK 0x0004
+#define fRX_HTC 0x0008
+#define fRX_PAD 0x0010
+#define fRX_AMPDU 0x0020
+#define fRX_QOS 0x0040
+#define fRX_INFRA 0x0080
+#define fRX_EAP 0x0100
+#define fRX_MESH 0x0200
+#define fRX_APCLI 0x0400
+#define fRX_DLS 0x0800
+#define fRX_WPI 0x1000
+
+#define LENGTH_AMSDU_SUBFRAMEHEAD 14
+#define LENGTH_ARALINK_SUBFRAMEHEAD 14
+#define LENGTH_ARALINK_HEADER_FIELD 2
+
+#define TX_UNKOWN_FRAME 0x00
+#define TX_MCAST_FRAME 0x01
+#define TX_LEGACY_FRAME 0x02
+#define TX_AMPDU_FRAME 0x04
+#define TX_AMSDU_FRAME 0x08
+#define TX_RALINK_FRAME 0x10
+#define TX_FRAG_FRAME 0x20
+
+
+// Currently the sizeof(TX_BLK) is 148 bytes.
+typedef struct _TX_BLK_
+{
+ UCHAR QueIdx;
+ UCHAR TxFrameType; // Indicate the Transmission type of the all frames in one batch
+ UCHAR TotalFrameNum; // Total frame number want to send-out in one batch
+ USHORT TotalFragNum; // Total frame fragments required in one batch
+ USHORT TotalFrameLen; // Total length of all frames want to send-out in one batch
+
+ QUEUE_HEADER TxPacketList;
+ MAC_TABLE_ENTRY *pMacEntry; // NULL: packet with 802.11 RA field is multicast/broadcast address
+ HTTRANSMIT_SETTING *pTransmit;
+
+ // Following structure used for the characteristics of a specific packet.
+ PNDIS_PACKET pPacket;
+ PUCHAR pSrcBufHeader; // Reference to the head of sk_buff->data
+ PUCHAR pSrcBufData; // Reference to the sk_buff->data, will changed depends on hanlding progresss
+ UINT SrcBufLen; // Length of packet payload which not including Layer 2 header
+ PUCHAR pExtraLlcSnapEncap; // NULL means no extra LLC/SNAP is required
+ UCHAR HeaderBuf[80]; // TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP
+ UCHAR MpduHeaderLen; // 802.11 header length NOT including the padding
+ UCHAR HdrPadLen; // recording Header Padding Length;
+ UCHAR apidx; // The interface associated to this packet
+ UCHAR Wcid; // The MAC entry associated to this packet
+ UCHAR UserPriority; // priority class of packet
+ UCHAR FrameGap; // what kind of IFS this packet use
+ UCHAR MpduReqNum; // number of fragments of this frame
+ UCHAR TxRate; // TODO: Obsoleted? Should change to MCS?
+ UCHAR CipherAlg; // cipher alogrithm
+ PCIPHER_KEY pKey;
+
+
+
+ USHORT Flags; //See following definitions for detail.
+
+ //YOU SHOULD NOT TOUCH IT! Following parameters are used for hardware-depended layer.
+ ULONG Priv; // Hardware specific value saved in here.
+} TX_BLK, *PTX_BLK;
+
+
+#define fTX_bRtsRequired 0x0001 // Indicate if need send RTS frame for protection. Not used in RT2860/RT2870.
+#define fTX_bAckRequired 0x0002 // the packet need ack response
+#define fTX_bPiggyBack 0x0004 // Legacy device use Piggback or not
+#define fTX_bHTRate 0x0008 // allow to use HT rate
+//#define fTX_bForceLowRate 0x0010 // force to use Low Rate
+#define fTX_bForceNonQoS 0x0010 // force to transmit frame without WMM-QoS in HT mode
+#define fTX_bAllowFrag 0x0020 // allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment
+#define fTX_bMoreData 0x0040 // there are more data packets in PowerSave Queue
+#define fTX_bWMM 0x0080 // QOS Data
+
+#define fTX_bClearEAPFrame 0x0100
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+#define TX_BLK_ASSIGN_FLAG(_pTxBlk, _flag, value) \
+ do { \
+ if (value) \
+ (_pTxBlk->Flags |= _flag) \
+ else \
+ (_pTxBlk->Flags &= ~(_flag)) \
+ }while(0)
+
+#define TX_BLK_SET_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags |= _flag)
+#define TX_BLK_TEST_FLAG(_pTxBlk, _flag) (((_pTxBlk->Flags & _flag) == _flag) ? 1 : 0)
+#define TX_BLK_CLEAR_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags &= ~(_flag))
+
+
+
+
+
+//------------------------------------------------------------------------------------------
+
+
+
+#ifdef RT_BIG_ENDIAN
+static inline VOID WriteBackToDescriptor(
+ IN PUCHAR Dest,
+ IN PUCHAR Src,
+ IN BOOLEAN DoEncrypt,
+ IN ULONG DescriptorType)
+{
+ UINT32 *p1, *p2;
+
+ p1 = ((UINT32 *)Dest);
+ p2 = ((UINT32 *)Src);
+
+ *p1 = *p2;
+ *(p1+2) = *(p2+2);
+ *(p1+3) = *(p2+3);
+ *(p1+1) = *(p2+1); // Word 1; this must be written back last
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Endian conversion of Tx/Rx descriptor .
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Pointer to Tx/Rx descriptor
+ DescriptorType Direction of the frame
+
+ Return Value:
+ None
+
+ Note:
+ Call this function when read or update descriptor
+ ========================================================================
+*/
+static inline VOID RTMPWIEndianChange(
+ IN PUCHAR pData,
+ IN ULONG DescriptorType)
+{
+ int size;
+ int i;
+
+ size = ((DescriptorType == TYPE_TXWI) ? TXWI_SIZE : RXWI_SIZE);
+
+ if(DescriptorType == TYPE_TXWI)
+ {
+ *((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData))); // Byte 0~3
+ *((UINT32 *)(pData + 4)) = SWAP32(*((UINT32 *)(pData+4))); // Byte 4~7
+ }
+ else
+ {
+ for(i=0; i < size/4 ; i++)
+ *(((UINT32 *)pData) +i) = SWAP32(*(((UINT32 *)pData)+i));
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Endian conversion of Tx/Rx descriptor .
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Pointer to Tx/Rx descriptor
+ DescriptorType Direction of the frame
+
+ Return Value:
+ None
+
+ Note:
+ Call this function when read or update descriptor
+ ========================================================================
+*/
+
+#ifdef RT2870
+static inline VOID RTMPDescriptorEndianChange(
+ IN PUCHAR pData,
+ IN ULONG DescriptorType)
+{
+ *((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData)));
+}
+#endif // RT2870 //
+/*
+ ========================================================================
+
+ Routine Description:
+ Endian conversion of all kinds of 802.11 frames .
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Pointer to the 802.11 frame structure
+ Dir Direction of the frame
+ FromRxDoneInt Caller is from RxDone interrupt
+
+ Return Value:
+ None
+
+ Note:
+ Call this function when read or update buffer data
+ ========================================================================
+*/
+static inline VOID RTMPFrameEndianChange(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG Dir,
+ IN BOOLEAN FromRxDoneInt)
+{
+ PHEADER_802_11 pFrame;
+ PUCHAR pMacHdr;
+
+ // swab 16 bit fields - Frame Control field
+ if(Dir == DIR_READ)
+ {
+ *(USHORT *)pData = SWAP16(*(USHORT *)pData);
+ }
+
+ pFrame = (PHEADER_802_11) pData;
+ pMacHdr = (PUCHAR) pFrame;
+
+ // swab 16 bit fields - Duration/ID field
+ *(USHORT *)(pMacHdr + 2) = SWAP16(*(USHORT *)(pMacHdr + 2));
+
+ // swab 16 bit fields - Sequence Control field
+ *(USHORT *)(pMacHdr + 22) = SWAP16(*(USHORT *)(pMacHdr + 22));
+
+ if(pFrame->FC.Type == BTYPE_MGMT)
+ {
+ switch(pFrame->FC.SubType)
+ {
+ case SUBTYPE_ASSOC_REQ:
+ case SUBTYPE_REASSOC_REQ:
+ // swab 16 bit fields - CapabilityInfo field
+ pMacHdr += sizeof(HEADER_802_11);
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+ // swab 16 bit fields - Listen Interval field
+ pMacHdr += 2;
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+ break;
+
+ case SUBTYPE_ASSOC_RSP:
+ case SUBTYPE_REASSOC_RSP:
+ // swab 16 bit fields - CapabilityInfo field
+ pMacHdr += sizeof(HEADER_802_11);
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+ // swab 16 bit fields - Status Code field
+ pMacHdr += 2;
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+ // swab 16 bit fields - AID field
+ pMacHdr += 2;
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+ break;
+
+ case SUBTYPE_AUTH:
+ // If from APHandleRxDoneInterrupt routine, it is still a encrypt format.
+ // The convertion is delayed to RTMPHandleDecryptionDoneInterrupt.
+ if(!FromRxDoneInt && pFrame->FC.Wep == 1)
+ break;
+ else
+ {
+ // swab 16 bit fields - Auth Alg No. field
+ pMacHdr += sizeof(HEADER_802_11);
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+ // swab 16 bit fields - Auth Seq No. field
+ pMacHdr += 2;
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+ // swab 16 bit fields - Status Code field
+ pMacHdr += 2;
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+ }
+ break;
+
+ case SUBTYPE_BEACON:
+ case SUBTYPE_PROBE_RSP:
+ // swab 16 bit fields - BeaconInterval field
+ pMacHdr += (sizeof(HEADER_802_11) + TIMESTAMP_LEN);
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+ // swab 16 bit fields - CapabilityInfo field
+ pMacHdr += sizeof(USHORT);
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+ break;
+
+ case SUBTYPE_DEAUTH:
+ case SUBTYPE_DISASSOC:
+ // swab 16 bit fields - Reason code field
+ pMacHdr += sizeof(HEADER_802_11);
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+ break;
+ }
+ }
+ else if( pFrame->FC.Type == BTYPE_DATA )
+ {
+ }
+ else if(pFrame->FC.Type == BTYPE_CNTL)
+ {
+ switch(pFrame->FC.SubType)
+ {
+ case SUBTYPE_BLOCK_ACK_REQ:
+ {
+ PFRAME_BA_REQ pBAReq = (PFRAME_BA_REQ)pFrame;
+ *(USHORT *)(&pBAReq->BARControl) = SWAP16(*(USHORT *)(&pBAReq->BARControl));
+ pBAReq->BAStartingSeq.word = SWAP16(pBAReq->BAStartingSeq.word);
+ }
+ break;
+ case SUBTYPE_BLOCK_ACK:
+ // For Block Ack packet, the HT_CONTROL field is in the same offset with Addr3
+ *(UINT32 *)(&pFrame->Addr3[0]) = SWAP32(*(UINT32 *)(&pFrame->Addr3[0]));
+ break;
+
+ case SUBTYPE_ACK:
+ //For ACK packet, the HT_CONTROL field is in the same offset with Addr2
+ *(UINT32 *)(&pFrame->Addr2[0])= SWAP32(*(UINT32 *)(&pFrame->Addr2[0]));
+ break;
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("Invalid Frame Type!!!\n"));
+ }
+
+ // swab 16 bit fields - Frame Control
+ if(Dir == DIR_WRITE)
+ {
+ *(USHORT *)pData = SWAP16(*(USHORT *)pData);
+ }
+}
+#endif // RT_BIG_ENDIAN //
+
+
+static inline VOID ConvertMulticastIP2MAC(
+ IN PUCHAR pIpAddr,
+ IN PUCHAR *ppMacAddr,
+ IN UINT16 ProtoType)
+{
+ if (pIpAddr == NULL)
+ return;
+
+ if (ppMacAddr == NULL || *ppMacAddr == NULL)
+ return;
+
+ switch (ProtoType)
+ {
+ case ETH_P_IPV6:
+// memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
+ *(*ppMacAddr) = 0x33;
+ *(*ppMacAddr + 1) = 0x33;
+ *(*ppMacAddr + 2) = pIpAddr[12];
+ *(*ppMacAddr + 3) = pIpAddr[13];
+ *(*ppMacAddr + 4) = pIpAddr[14];
+ *(*ppMacAddr + 5) = pIpAddr[15];
+ break;
+
+ case ETH_P_IP:
+ default:
+// memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
+ *(*ppMacAddr) = 0x01;
+ *(*ppMacAddr + 1) = 0x00;
+ *(*ppMacAddr + 2) = 0x5e;
+ *(*ppMacAddr + 3) = pIpAddr[1] & 0x7f;
+ *(*ppMacAddr + 4) = pIpAddr[2];
+ *(*ppMacAddr + 5) = pIpAddr[3];
+ break;
+ }
+
+ return;
+}
+
+BOOLEAN RTMPCheckForHang(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+VOID RTMPHalt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+//
+// Private routines in rtmp_init.c
+//
+NDIS_STATUS RTMPAllocAdapterBlock(
+ IN PVOID handle,
+ OUT PRTMP_ADAPTER *ppAdapter
+ );
+
+NDIS_STATUS RTMPAllocTxRxRingMemory(
+ IN PRTMP_ADAPTER pAd
+ );
+
+NDIS_STATUS RTMPFindAdapter(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_HANDLE WrapperConfigurationContext
+ );
+
+NDIS_STATUS RTMPReadParametersHook(
+ IN PRTMP_ADAPTER pAd
+ );
+
+VOID RTMPFreeAdapter(
+ IN PRTMP_ADAPTER pAd
+ );
+
+NDIS_STATUS NICReadRegParameters(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_HANDLE WrapperConfigurationContext
+ );
+
+#ifdef RT30xx
+VOID NICInitRT30xxRFRegisters(
+ IN PRTMP_ADAPTER pAd);
+#endif // RT30xx //
+
+VOID NICReadEEPROMParameters(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR mac_addr);
+
+VOID NICInitAsicFromEEPROM(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NICInitTxRxRingAndBacklogQueue(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS NICInitializeAdapter(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bHardReset);
+
+NDIS_STATUS NICInitializeAsic(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bHardReset);
+
+VOID NICIssueReset(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPRingCleanUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR RingType);
+
+VOID RxTest(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS DbgSendPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+VOID UserCfgInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NICResetFromError(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NICEraseFirmware(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS NICLoadFirmware(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS NICLoadRateSwitchingParams(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN NICCheckForHang(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NICUpdateFifoStaCounters(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NICUpdateRawCounters(
+ IN PRTMP_ADAPTER pAd);
+
+ULONG RTMPNotAllZero(
+ IN PVOID pSrc1,
+ IN ULONG Length);
+
+VOID RTMPZeroMemory(
+ IN PVOID pSrc,
+ IN ULONG Length);
+
+ULONG RTMPCompareMemory(
+ IN PVOID pSrc1,
+ IN PVOID pSrc2,
+ IN ULONG Length);
+
+VOID RTMPMoveMemory(
+ OUT PVOID pDest,
+ IN PVOID pSrc,
+ IN ULONG Length);
+
+VOID AtoH(
+ char *src,
+ UCHAR *dest,
+ int destlen);
+
+UCHAR BtoH(
+ char ch);
+
+VOID RTMPPatchMacBbpBug(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPPatchCardBus(
+ IN PRTMP_ADAPTER pAdapter);
+
+VOID RTMPPatchRalinkCardBus(
+ IN PRTMP_ADAPTER pAdapter,
+ IN ULONG Bus);
+
+ULONG RTMPReadCBConfig(
+ IN ULONG Bus,
+ IN ULONG Slot,
+ IN ULONG Func,
+ IN ULONG Offset);
+
+VOID RTMPWriteCBConfig(
+ IN ULONG Bus,
+ IN ULONG Slot,
+ IN ULONG Func,
+ IN ULONG Offset,
+ IN ULONG Value);
+
+VOID RTMPInitTimer(
+ IN PRTMP_ADAPTER pAd,
+ IN PRALINK_TIMER_STRUCT pTimer,
+ IN PVOID pTimerFunc,
+ IN PVOID pData,
+ IN BOOLEAN Repeat);
+
+VOID RTMPSetTimer(
+ IN PRALINK_TIMER_STRUCT pTimer,
+ IN ULONG Value);
+
+
+VOID RTMPModTimer(
+ IN PRALINK_TIMER_STRUCT pTimer,
+ IN ULONG Value);
+
+VOID RTMPCancelTimer(
+ IN PRALINK_TIMER_STRUCT pTimer,
+ OUT BOOLEAN *pCancelled);
+
+VOID RTMPSetLED(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Status);
+
+VOID RTMPSetSignalLED(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_802_11_RSSI Dbm);
+
+VOID RTMPEnableRxTx(
+ IN PRTMP_ADAPTER pAd);
+
+//
+// prototype in action.c
+//
+VOID ActionStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID MlmeADDBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeDELBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeDLSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeInvalidAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeQOSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef DOT11_N_SUPPORT
+VOID PeerAddBAReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAddBARspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDelBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+#endif // DOT11_N_SUPPORT //
+
+VOID SendPSMPAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR Psmp);
+
+
+#ifdef DOT11N_DRAFT3
+VOID SendBSS2040CoexistMgmtAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR apidx,
+ IN UCHAR InfoReq);
+
+VOID SendNotifyBWActionFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR apidx);
+
+BOOLEAN ChannelSwitchSanityCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR NewChannel,
+ IN UCHAR Secondary);
+
+VOID ChannelSwitchAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR Channel,
+ IN UCHAR Secondary);
+
+ULONG BuildIntolerantChannelRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDest);
+
+VOID Update2040CoexistFrameAndNotify(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN BOOLEAN bAddIntolerantCha);
+
+VOID Send2040CoexistAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN BOOLEAN bAddIntolerantCha);
+#endif // DOT11N_DRAFT3 //
+
+VOID PeerRMAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerPublicAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef CONFIG_STA_SUPPORT
+VOID StaPublicAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Bss2040Coexist);
+#endif // CONFIG_STA_SUPPORT //
+
+
+VOID PeerBSSTranAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef DOT11_N_SUPPORT
+VOID PeerHTAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+#endif // DOT11_N_SUPPORT //
+
+VOID PeerQOSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef QOS_DLS_SUPPORT
+VOID PeerDLSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+#endif // QOS_DLS_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+VOID DlsParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
+ IN PRT_802_11_DLS pDls,
+ IN USHORT reason);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+VOID RECBATimerTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID ORIBATimerTimeout(
+ IN PRTMP_ADAPTER pAd);
+
+VOID SendRefreshBAR(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+#endif // DOT11_N_SUPPORT //
+
+VOID ActHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN PUCHAR Addr1,
+ IN PUCHAR Addr2,
+ IN PUCHAR Addr3);
+
+VOID BarHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PFRAME_BAR pCntlBar,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA);
+
+VOID InsertActField(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 Category,
+ IN UINT8 ActCode);
+
+BOOLEAN QosBADataParse(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bAMSDU,
+ IN PUCHAR p8023Header,
+ IN UCHAR WCID,
+ IN UCHAR TID,
+ IN USHORT Sequence,
+ IN UCHAR DataOffset,
+ IN USHORT Datasize,
+ IN UINT CurRxIndex);
+
+#ifdef DOT11_N_SUPPORT
+BOOLEAN CntlEnqueueForRecv(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN ULONG MsgLen,
+ IN PFRAME_BA_REQ pMsg);
+
+VOID BaAutoManSwitch(
+ IN PRTMP_ADAPTER pAd);
+#endif // DOT11_N_SUPPORT //
+
+VOID HTIOTCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BatRecIdx);
+
+//
+// Private routines in rtmp_data.c
+//
+BOOLEAN RTMPHandleRxDoneInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPHandleTxDoneInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
+ IN PRTMP_ADAPTER pAd,
+ IN INT_SOURCE_CSR_STRUC TxRingBitmap);
+
+VOID RTMPHandleMgmtRingDmaDoneInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPHandleTBTTInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPHandlePreTBTTInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+void RTMPHandleTwakeupInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPHandleRxCoherentInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN TxFrameIsAggregatible(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pPrevAddr1,
+ IN PUCHAR p8023hdr);
+
+BOOLEAN PeerIsAggreOn(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG TxRate,
+ IN PMAC_TABLE_ENTRY pMacEntry);
+
+NDIS_STATUS Sniff2BytesFromNdisBuffer(
+ IN PNDIS_BUFFER pFirstBuffer,
+ IN UCHAR DesiredOffset,
+ OUT PUCHAR pByte0,
+ OUT PUCHAR pByte1);
+
+NDIS_STATUS STASendPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+VOID STASendPackets(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PPNDIS_PACKET ppPacketArray,
+ IN UINT NumberOfPackets);
+
+VOID RTMPDeQueuePacket(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bIntContext,
+ IN UCHAR QueIdx,
+ IN UCHAR Max_Tx_Packets);
+
+NDIS_STATUS RTMPHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR QueIdx,
+ OUT PULONG pFreeTXDLeft);
+
+NDIS_STATUS STAHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR QueIdx);
+
+VOID STARxEAPOLFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+NDIS_STATUS RTMPFreeTXDRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR RingType,
+ IN UCHAR NumberRequired,
+ IN PUCHAR FreeNumberIs);
+
+NDIS_STATUS MlmeHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket);
+
+NDIS_STATUS MlmeHardTransmitMgmtRing(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket);
+
+NDIS_STATUS MlmeHardTransmitTxRing(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket);
+
+USHORT RTMPCalcDuration(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Rate,
+ IN ULONG Size);
+
+VOID RTMPWriteTxWI(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXWI_STRUC pTxWI,
+ IN BOOLEAN FRAG,
+ IN BOOLEAN CFACK,
+ IN BOOLEAN InsTimestamp,
+ IN BOOLEAN AMPDU,
+ IN BOOLEAN Ack,
+ IN BOOLEAN NSeq, // HW new a sequence.
+ IN UCHAR BASize,
+ IN UCHAR WCID,
+ IN ULONG Length,
+ IN UCHAR PID,
+ IN UCHAR TID,
+ IN UCHAR TxRate,
+ IN UCHAR Txopmode,
+ IN BOOLEAN CfAck,
+ IN HTTRANSMIT_SETTING *pTransmit);
+
+
+VOID RTMPWriteTxWI_Data(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PTXWI_STRUC pTxWI,
+ IN TX_BLK *pTxBlk);
+
+
+VOID RTMPWriteTxWI_Cache(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PTXWI_STRUC pTxWI,
+ IN TX_BLK *pTxBlk);
+
+VOID RTMPWriteTxDescriptor(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXD_STRUC pTxD,
+ IN BOOLEAN bWIV,
+ IN UCHAR QSEL);
+
+VOID RTMPSuspendMsduTransmission(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPResumeMsduTransmission(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS MiniportMMRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PUCHAR pData,
+ IN UINT Length);
+
+NDIS_STATUS MiniportDataMMRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PUCHAR pData,
+ IN UINT Length);
+
+VOID RTMPSendNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull);
+
+VOID RTMPSendDisassociationFrame(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPSendRTSFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN unsigned int NextMpduSize,
+ IN UCHAR TxRate,
+ IN UCHAR RTSRate,
+ IN USHORT AckDuration,
+ IN UCHAR QueIdx,
+ IN UCHAR FrameGap);
+
+
+NDIS_STATUS RTMPApplyPacketFilter(
+ IN PRTMP_ADAPTER pAd,
+ IN PRT28XX_RXD_STRUC pRxD,
+ IN PHEADER_802_11 pHeader);
+
+PQUEUE_HEADER RTMPCheckTxSwQueue(
+ IN PRTMP_ADAPTER pAd,
+ OUT UCHAR *QueIdx);
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPReportMicError(
+ IN PRTMP_ADAPTER pAd,
+ IN PCIPHER_KEY pWpaKey);
+
+VOID WpaMicFailureReportFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID WpaDisassocApAndBlockAssoc(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+#endif // CONFIG_STA_SUPPORT //
+
+NDIS_STATUS RTMPCloneNdisPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN pInsAMSDUHdr,
+ IN PNDIS_PACKET pInPacket,
+ OUT PNDIS_PACKET *ppOutPacket);
+
+NDIS_STATUS RTMPAllocateNdisPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET *pPacket,
+ IN PUCHAR pHeader,
+ IN UINT HeaderLen,
+ IN PUCHAR pData,
+ IN UINT DataLen);
+
+VOID RTMPFreeNdisPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+BOOLEAN RTMPFreeTXDUponTxDmaDone(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx);
+
+BOOLEAN RTMPCheckDHCPFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+
+BOOLEAN RTMPCheckEtherType(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+
+VOID RTMPCckBbpTuning(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT TxRate);
+
+//
+// Private routines in rtmp_wep.c
+//
+VOID RTMPInitWepEngine(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKey,
+ IN UCHAR KeyId,
+ IN UCHAR KeyLen,
+ IN PUCHAR pDest);
+
+VOID RTMPEncryptData(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pSrc,
+ IN PUCHAR pDest,
+ IN UINT Len);
+
+BOOLEAN RTMPDecryptData(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR pSrc,
+ IN UINT Len,
+ IN UINT idx);
+
+BOOLEAN RTMPSoftDecryptWEP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN PCIPHER_KEY pGroupKey);
+
+VOID RTMPSetICV(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDest);
+
+VOID ARCFOUR_INIT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pKey,
+ IN UINT KeyLen);
+
+UCHAR ARCFOUR_BYTE(
+ IN PARCFOURCONTEXT Ctx);
+
+VOID ARCFOUR_DECRYPT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pDest,
+ IN PUCHAR pSrc,
+ IN UINT Len);
+
+VOID ARCFOUR_ENCRYPT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pDest,
+ IN PUCHAR pSrc,
+ IN UINT Len);
+
+VOID WPAARCFOUR_ENCRYPT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pDest,
+ IN PUCHAR pSrc,
+ IN UINT Len);
+
+UINT RTMP_CALC_FCS32(
+ IN UINT Fcs,
+ IN PUCHAR Cp,
+ IN INT Len);
+
+//
+// MLME routines
+//
+
+// Asic/RF/BBP related functions
+
+VOID AsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicUpdateProtect(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT OperaionMode,
+ IN UCHAR SetMask,
+ IN BOOLEAN bDisableBGProtect,
+ IN BOOLEAN bNonGFExist);
+
+VOID AsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel,
+ IN BOOLEAN bScan);
+
+VOID AsicLockChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel) ;
+
+VOID AsicAntennaSelect(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel);
+
+VOID AsicAntennaSetting(
+ IN PRTMP_ADAPTER pAd,
+ IN ABGBAND_STATE BandState);
+
+VOID AsicRfTuningExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+#ifdef CONFIG_STA_SUPPORT
+VOID AsicSleepThenAutoWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT TbttNumToNextWakeUp);
+
+VOID AsicForceSleep(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicForceWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bFromTx);
+#endif // CONFIG_STA_SUPPORT //
+
+VOID AsicSetBssid(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pBssid);
+
+VOID AsicSetMcastWC(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicDelWcidTab(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid);
+
+VOID AsicEnableRDG(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicDisableRDG(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicDisableSync(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicEnableBssSync(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicEnableIbssSync(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicSetEdcaParm(
+ IN PRTMP_ADAPTER pAd,
+ IN PEDCA_PARM pEdcaParm);
+
+VOID AsicSetSlotTime(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bUseShortSlotTime);
+
+VOID AsicAddSharedKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx,
+ IN UCHAR CipherAlg,
+ IN PUCHAR pKey,
+ IN PUCHAR pTxMic,
+ IN PUCHAR pRxMic);
+
+VOID AsicRemoveSharedKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx);
+
+VOID AsicUpdateWCIDAttribute(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN UCHAR BssIndex,
+ IN UCHAR CipherAlg,
+ IN BOOLEAN bUsePairewiseKeyTable);
+
+VOID AsicUpdateWCIDIVEIV(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN ULONG uIV,
+ IN ULONG uEIV);
+
+VOID AsicUpdateRxWCIDTable(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN PUCHAR pAddr);
+
+VOID AsicAddKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx,
+ IN PCIPHER_KEY pCipherKey,
+ IN BOOLEAN bUsePairewiseKeyTable,
+ IN BOOLEAN bTxKey);
+
+VOID AsicAddPairwiseKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR WCID,
+ IN CIPHER_KEY *pCipherKey);
+
+VOID AsicRemovePairwiseKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIdx,
+ IN UCHAR Wcid);
+
+BOOLEAN AsicSendCommandToMcu(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Command,
+ IN UCHAR Token,
+ IN UCHAR Arg0,
+ IN UCHAR Arg1);
+
+
+VOID MacAddrRandomBssid(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pAddr);
+
+VOID MgtMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR SubType,
+ IN UCHAR ToDs,
+ IN PUCHAR pDA,
+ IN PUCHAR pBssid);
+
+VOID MlmeRadioOff(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeRadioOn(
+ IN PRTMP_ADAPTER pAd);
+
+
+VOID BssTableInit(
+ IN BSS_TABLE *Tab);
+
+#ifdef DOT11_N_SUPPORT
+VOID BATableInit(
+ IN PRTMP_ADAPTER pAd,
+ IN BA_TABLE *Tab);
+#endif // DOT11_N_SUPPORT //
+
+ULONG BssTableSearch(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN UCHAR Channel);
+
+ULONG BssSsidTableSearch(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN UCHAR Channel);
+
+ULONG BssTableSearchWithSSID(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR Bssid,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN UCHAR Channel);
+
+VOID BssTableDeleteEntry(
+ IN OUT PBSS_TABLE pTab,
+ IN PUCHAR pBssid,
+ IN UCHAR Channel);
+
+#ifdef DOT11_N_SUPPORT
+VOID BATableDeleteORIEntry(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN BA_ORI_ENTRY *pBAORIEntry);
+
+VOID BATableDeleteRECEntry(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN BA_REC_ENTRY *pBARECEntry);
+
+VOID BATableTearORIEntry(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR TID,
+ IN UCHAR Wcid,
+ IN BOOLEAN bForceDelete,
+ IN BOOLEAN ALL);
+
+VOID BATableTearRECEntry(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR TID,
+ IN UCHAR WCID,
+ IN BOOLEAN ALL);
+#endif // DOT11_N_SUPPORT //
+
+VOID BssEntrySet(
+ IN PRTMP_ADAPTER pAd,
+ OUT PBSS_ENTRY pBss,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN USHORT BeaconPeriod,
+ IN PCF_PARM CfParm,
+ IN USHORT AtimWin,
+ IN USHORT CapabilityInfo,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR AddHtInfoLen,
+ IN UCHAR NewExtChanOffset,
+ IN UCHAR Channel,
+ IN CHAR Rssi,
+ IN LARGE_INTEGER TimeStamp,
+ IN UCHAR CkipFlag,
+ IN PEDCA_PARM pEdcaParm,
+ IN PQOS_CAPABILITY_PARM pQosCapability,
+ IN PQBSS_LOAD_PARM pQbssLoad,
+ IN USHORT LengthVIE,
+ IN PNDIS_802_11_VARIABLE_IEs pVIE);
+
+ULONG BssTableSetEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT PBSS_TABLE pTab,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN USHORT BeaconPeriod,
+ IN CF_PARM *CfParm,
+ IN USHORT AtimWin,
+ IN USHORT CapabilityInfo,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR AddHtInfoLen,
+ IN UCHAR NewExtChanOffset,
+ IN UCHAR Channel,
+ IN CHAR Rssi,
+ IN LARGE_INTEGER TimeStamp,
+ IN UCHAR CkipFlag,
+ IN PEDCA_PARM pEdcaParm,
+ IN PQOS_CAPABILITY_PARM pQosCapability,
+ IN PQBSS_LOAD_PARM pQbssLoad,
+ IN USHORT LengthVIE,
+ IN PNDIS_802_11_VARIABLE_IEs pVIE);
+
+#ifdef DOT11_N_SUPPORT
+VOID BATableInsertEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Aid,
+ IN USHORT TimeOutValue,
+ IN USHORT StartingSeq,
+ IN UCHAR TID,
+ IN UCHAR BAWinSize,
+ IN UCHAR OriginatorStatus,
+ IN BOOLEAN IsRecipient);
+
+#ifdef DOT11N_DRAFT3
+VOID Bss2040CoexistTimeOut(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+
+VOID TriEventInit(
+ IN PRTMP_ADAPTER pAd);
+
+ULONG TriEventTableSetEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT TRIGGER_EVENT_TAB *Tab,
+ IN PUCHAR pBssid,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR RegClass,
+ IN UCHAR ChannelNo);
+
+VOID TriEventCounterMaintenance(
+ IN PRTMP_ADAPTER pAd);
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+VOID BssTableSsidSort(
+ IN PRTMP_ADAPTER pAd,
+ OUT BSS_TABLE *OutTab,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen);
+
+VOID BssTableSortByRssi(
+ IN OUT BSS_TABLE *OutTab);
+
+VOID BssCipherParse(
+ IN OUT PBSS_ENTRY pBss);
+
+NDIS_STATUS MlmeQueueInit(
+ IN MLME_QUEUE *Queue);
+
+VOID MlmeQueueDestroy(
+ IN MLME_QUEUE *Queue);
+
+BOOLEAN MlmeEnqueue(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Machine,
+ IN ULONG MsgType,
+ IN ULONG MsgLen,
+ IN VOID *Msg);
+
+BOOLEAN MlmeEnqueueForRecv(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN ULONG TimeStampHigh,
+ IN ULONG TimeStampLow,
+ IN UCHAR Rssi0,
+ IN UCHAR Rssi1,
+ IN UCHAR Rssi2,
+ IN ULONG MsgLen,
+ IN PVOID Msg,
+ IN UCHAR Signal);
+
+
+BOOLEAN MlmeDequeue(
+ IN MLME_QUEUE *Queue,
+ OUT MLME_QUEUE_ELEM **Elem);
+
+VOID MlmeRestartStateMachine(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN MlmeQueueEmpty(
+ IN MLME_QUEUE *Queue);
+
+BOOLEAN MlmeQueueFull(
+ IN MLME_QUEUE *Queue);
+
+BOOLEAN MsgTypeSubst(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 pFrame,
+ OUT INT *Machine,
+ OUT INT *MsgType);
+
+VOID StateMachineInit(
+ IN STATE_MACHINE *Sm,
+ IN STATE_MACHINE_FUNC Trans[],
+ IN ULONG StNr,
+ IN ULONG MsgNr,
+ IN STATE_MACHINE_FUNC DefFunc,
+ IN ULONG InitState,
+ IN ULONG Base);
+
+VOID StateMachineSetAction(
+ IN STATE_MACHINE *S,
+ IN ULONG St,
+ ULONG Msg,
+ IN STATE_MACHINE_FUNC F);
+
+VOID StateMachinePerformAction(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID Drop(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID AssocStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID ReassocTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID AssocTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID DisassocTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+//----------------------------------------------
+VOID MlmeDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeAssocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeReassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAssocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerReassocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDisassocAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID DisassocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID AssocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ReassocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID Cls3errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr);
+
+VOID SwitchBetweenWepAndCkip(
+ IN PRTMP_ADAPTER pAd);
+
+VOID InvalidStateWhenAssoc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenReassoc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenDisassociate(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef RT2870
+VOID MlmeCntlConfirm(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG MsgType,
+ IN USHORT Msg);
+#endif // RT2870 //
+
+VOID ComposePsPoll(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ComposeNullFrame(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AssocPostProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr2,
+ IN USHORT CapabilityInfo,
+ IN USHORT Aid,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN PEDCA_PARM pEdcaParm,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ IN ADD_HT_INFO_IE *pAddHtInfo);
+
+VOID AuthStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTATE_MACHINE sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID AuthTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID MlmeAuthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAuthRspAtSeq2Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAuthRspAtSeq4Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID AuthTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID Cls2errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr);
+
+VOID MlmeDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenAuth(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+//=============================================
+
+VOID AuthRspStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTATE_MACHINE Sm,
+ IN STATE_MACHINE_FUNC Trans[]);
+
+VOID PeerDeauthAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAuthSimpleRspGenAndSend(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHdr80211,
+ IN USHORT Alg,
+ IN USHORT Seq,
+ IN USHORT Reason,
+ IN USHORT Status);
+
+//
+// Private routines in dls.c
+//
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+void DlsStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID MlmeDlsReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDlsReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDlsRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeDlsTearDownAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDlsTearDownAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID RTMPCheckDLSTimeOut(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN RTMPRcvFrameDLSCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHeader,
+ IN ULONG Len,
+ IN PRT28XX_RXD_STRUC pRxD);
+
+INT RTMPCheckDLSFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA);
+
+VOID RTMPSendDLSTearDownFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA);
+
+NDIS_STATUS RTMPSendSTAKeyRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA);
+
+NDIS_STATUS RTMPSendSTAKeyHandShake(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA);
+
+VOID DlsTimeoutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+BOOLEAN MlmeDlsReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PRT_802_11_DLS *pDLS,
+ OUT PUSHORT pReason);
+
+INT Set_DlsEntryInfo_Display_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UINT DlsEntryIdx);
+
+BOOLEAN MacTableDeleteDlsEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT wcid,
+ IN PUCHAR pAddr);
+
+MAC_TABLE_ENTRY *DlsEntryTableLookup(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount);
+
+MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR wcid,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount);
+
+INT Set_DlsAddEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_DlsTearDownEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef QOS_DLS_SUPPORT
+BOOLEAN PeerDlsReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pDA,
+ OUT PUCHAR pSA,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pDlsTimeout,
+ OUT UCHAR *pRatesLen,
+ OUT UCHAR Rates[],
+ OUT UCHAR *pHtCapabilityLen,
+ OUT HT_CAPABILITY_IE *pHtCapability);
+
+BOOLEAN PeerDlsRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pDA,
+ OUT PUCHAR pSA,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pStatus,
+ OUT UCHAR *pRatesLen,
+ OUT UCHAR Rates[],
+ OUT UCHAR *pHtCapabilityLen,
+ OUT HT_CAPABILITY_IE *pHtCapability);
+
+BOOLEAN PeerDlsTearDownSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pDA,
+ OUT PUCHAR pSA,
+ OUT USHORT *pReason);
+#endif // QOS_DLS_SUPPORT //
+
+//========================================
+
+VOID SyncStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID BeaconTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID ScanTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID MlmeScanReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenScan(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenJoin(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenStart(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBeacon(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID EnqueueProbeRequest(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN ScanRunning(
+ IN PRTMP_ADAPTER pAd);
+//=========================================
+
+VOID MlmeCntlInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID MlmeCntlMachinePerformAction(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlIdleProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlOidScanProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlOidSsidProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM * Elem);
+
+VOID CntlOidRTBssidProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM * Elem);
+
+VOID CntlMlmeRoamingProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM * Elem);
+
+VOID CntlWaitDisassocProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitJoinProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitReassocProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitStartProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitAuthProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitAuthProc2(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitAssocProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef QOS_DLS_SUPPORT
+VOID CntlOidDLSSetupProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+#endif // QOS_DLS_SUPPORT //
+
+VOID LinkUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssType);
+
+VOID LinkDown(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN IsReqFromAP);
+
+VOID IterateOnBssTab(
+ IN PRTMP_ADAPTER pAd);
+
+VOID IterateOnBssTab2(
+ IN PRTMP_ADAPTER pAd);;
+
+VOID JoinParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
+ IN ULONG BssIdx);
+
+VOID AssocParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
+ IN PUCHAR pAddr,
+ IN USHORT CapabilityInfo,
+ IN ULONG Timeout,
+ IN USHORT ListenIntv);
+
+VOID ScanParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN UCHAR ScanType);
+
+VOID DisassocParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
+ IN PUCHAR pAddr,
+ IN USHORT Reason);
+
+VOID StartParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_START_REQ_STRUCT *StartReq,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen);
+
+VOID AuthParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
+ IN PUCHAR pAddr,
+ IN USHORT Alg);
+
+VOID EnqueuePsPoll(
+ IN PRTMP_ADAPTER pAd);
+
+VOID EnqueueBeaconFrame(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeJoinReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeScanReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeStartReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ScanTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID BeaconTimeoutAtJoinAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBeaconAtScanAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBeaconAtJoinAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBeacon(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerProbeReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ScanNextChannel(
+ IN PRTMP_ADAPTER pAd);
+
+ULONG MakeIbssBeacon(
+ IN PRTMP_ADAPTER pAd);
+
+VOID CCXAdjacentAPReport(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN MlmeScanReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT UCHAR *BssType,
+ OUT CHAR ssid[],
+ OUT UCHAR *SsidLen,
+ OUT UCHAR *ScanType);
+
+BOOLEAN PeerBeaconAndProbeRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ IN UCHAR MsgChannel,
+ OUT PUCHAR pAddr2,
+ OUT PUCHAR pBssid,
+ OUT CHAR Ssid[],
+ OUT UCHAR *pSsidLen,
+ OUT UCHAR *pBssType,
+ OUT USHORT *pBeaconPeriod,
+ OUT UCHAR *pChannel,
+ OUT UCHAR *pNewChannel,
+ OUT LARGE_INTEGER *pTimestamp,
+ OUT CF_PARM *pCfParm,
+ OUT USHORT *pAtimWin,
+ OUT USHORT *pCapabilityInfo,
+ OUT UCHAR *pErp,
+ OUT UCHAR *pDtimCount,
+ OUT UCHAR *pDtimPeriod,
+ OUT UCHAR *pBcastFlag,
+ OUT UCHAR *pMessageToMe,
+ OUT UCHAR SupRate[],
+ OUT UCHAR *pSupRateLen,
+ OUT UCHAR ExtRate[],
+ OUT UCHAR *pExtRateLen,
+ OUT UCHAR *pCkipFlag,
+ OUT UCHAR *pAironetCellPowerLimit,
+ OUT PEDCA_PARM pEdcaParm,
+ OUT PQBSS_LOAD_PARM pQbssLoad,
+ OUT PQOS_CAPABILITY_PARM pQosCapability,
+ OUT ULONG *pRalinkIe,
+ OUT UCHAR *pHtCapabilityLen,
+#ifdef CONFIG_STA_SUPPORT
+ OUT UCHAR *pPreNHtCapabilityLen,
+#endif // CONFIG_STA_SUPPORT //
+ OUT HT_CAPABILITY_IE *pHtCapability,
+ OUT UCHAR *AddHtInfoLen,
+ OUT ADD_HT_INFO_IE *AddHtInfo,
+ OUT UCHAR *NewExtChannel,
+ OUT USHORT *LengthVIE,
+ OUT PNDIS_802_11_VARIABLE_IEs pVIE);
+
+BOOLEAN PeerAddBAReqActionSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2);
+
+BOOLEAN PeerAddBARspActionSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen);
+
+BOOLEAN PeerDelBAActionSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN VOID *pMsg,
+ IN ULONG MsgLen);
+
+BOOLEAN MlmeAssocReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pApAddr,
+ OUT USHORT *CapabilityInfo,
+ OUT ULONG *Timeout,
+ OUT USHORT *ListenIntv);
+
+BOOLEAN MlmeAuthReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr,
+ OUT ULONG *Timeout,
+ OUT USHORT *Alg);
+
+BOOLEAN MlmeStartReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT CHAR Ssid[],
+ OUT UCHAR *Ssidlen);
+
+BOOLEAN PeerAuthSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr,
+ OUT USHORT *Alg,
+ OUT USHORT *Seq,
+ OUT USHORT *Status,
+ OUT CHAR ChlgText[]);
+
+BOOLEAN PeerAssocRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pStatus,
+ OUT USHORT *pAid,
+ OUT UCHAR SupRate[],
+ OUT UCHAR *pSupRateLen,
+ OUT UCHAR ExtRate[],
+ OUT UCHAR *pExtRateLen,
+ OUT HT_CAPABILITY_IE *pHtCapability,
+ OUT ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ OUT UCHAR *pHtCapabilityLen,
+ OUT UCHAR *pAddHtInfoLen,
+ OUT UCHAR *pNewExtChannelOffset,
+ OUT PEDCA_PARM pEdcaParm,
+ OUT UCHAR *pCkipFlag);
+
+BOOLEAN PeerDisassocSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *Reason);
+
+BOOLEAN PeerWpaMessageSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN PEAPOL_PACKET pMsg,
+ IN ULONG MsgLen,
+ IN UCHAR MsgType,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+BOOLEAN PeerDeauthSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *Reason);
+
+BOOLEAN PeerProbeReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT CHAR Ssid[],
+ OUT UCHAR *pSsidLen);
+
+BOOLEAN GetTimBit(
+ IN CHAR *Ptr,
+ IN USHORT Aid,
+ OUT UCHAR *TimLen,
+ OUT UCHAR *BcastFlag,
+ OUT UCHAR *DtimCount,
+ OUT UCHAR *DtimPeriod,
+ OUT UCHAR *MessageToMe);
+
+UCHAR ChannelSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel);
+
+NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
+ IN PBSS_ENTRY pBss);
+
+BOOLEAN MlmeDelBAReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen);
+
+BOOLEAN MlmeAddBAReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2);
+
+ULONG MakeOutgoingFrame(
+ OUT CHAR *Buffer,
+ OUT ULONG *Length, ...);
+
+VOID LfsrInit(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Seed);
+
+UCHAR RandomByte(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicUpdateAutoFallBackTable(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pTxRate);
+
+VOID MlmePeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID LinkDownExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID LinkUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID STAMlmePeriodicExec(
+ PRTMP_ADAPTER pAd);
+
+VOID MlmeAutoScan(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeAutoReconnectLastSSID(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN MlmeValidateSSID(
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen);
+
+VOID MlmeCheckForRoaming(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now32);
+
+VOID MlmeCheckForFastRoaming(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now);
+
+VOID MlmeDynamicTxRateSwitching(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeSetTxRate(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PRTMP_TX_RATE_SWITCH pTxRate);
+
+VOID MlmeSelectTxRateTable(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR *ppTable,
+ IN PUCHAR pTableSize,
+ IN PUCHAR pInitTxRateIdx);
+
+VOID MlmeCalculateChannelQuality(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now);
+
+VOID MlmeCheckPsmChange(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now32);
+
+VOID MlmeSetPsmBit(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT psm);
+
+VOID MlmeSetTxPreamble(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT TxPreamble);
+
+VOID UpdateBasicRateBitmap(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeUpdateTxRates(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bLinkUp,
+ IN UCHAR apidx);
+
+#ifdef DOT11_N_SUPPORT
+VOID MlmeUpdateHtTxRates(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx);
+#endif // DOT11_N_SUPPORT //
+
+VOID RTMPCheckRates(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT UCHAR SupRate[],
+ IN OUT UCHAR *SupRateLen);
+
+#ifdef CONFIG_STA_SUPPORT
+BOOLEAN RTMPCheckChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR CentralChannel,
+ IN UCHAR Channel);
+#endif // CONFIG_STA_SUPPORT //
+
+BOOLEAN RTMPCheckHt(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN OUT HT_CAPABILITY_IE *pHtCapability,
+ IN OUT ADD_HT_INFO_IE *pAddHtInfo);
+
+VOID StaQuickResponeForRateUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID AsicBbpTuning1(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicBbpTuning2(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPUpdateMlmeRate(
+ IN PRTMP_ADAPTER pAd);
+
+CHAR RTMPMaxRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi0,
+ IN CHAR Rssi1,
+ IN CHAR Rssi2);
+
+VOID AsicSetRxAnt(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Ant);
+
+VOID AsicEvaluateRxAnt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicRxAntEvalTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID APSDPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry);
+
+UCHAR RTMPStaFixedTxMode(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry);
+
+VOID RTMPUpdateLegacyTxSetting(
+ UCHAR fixed_tx_mode,
+ PMAC_TABLE_ENTRY pEntry);
+
+BOOLEAN RTMPAutoRateSwitchCheck(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS MlmeInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeHandler(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeHalt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeResetRalinkCounters(
+ IN PRTMP_ADAPTER pAd);
+
+VOID BuildChannelList(
+ IN PRTMP_ADAPTER pAd);
+
+UCHAR FirstChannel(
+ IN PRTMP_ADAPTER pAd);
+
+UCHAR NextChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel);
+
+VOID ChangeToCellPowerLimit(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR AironetCellPowerLimit);
+
+VOID RaiseClock(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 *x);
+
+VOID LowerClock(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 *x);
+
+USHORT ShiftInBits(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ShiftOutBits(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT data,
+ IN USHORT count);
+
+VOID EEpromCleanup(
+ IN PRTMP_ADAPTER pAd);
+
+VOID EWDS(
+ IN PRTMP_ADAPTER pAd);
+
+VOID EWEN(
+ IN PRTMP_ADAPTER pAd);
+
+USHORT RTMP_EEPROM_READ16(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset);
+
+VOID RTMP_EEPROM_WRITE16(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Data);
+
+//
+// Prototypes of function definition in rtmp_tkip.c
+//
+VOID RTMPInitTkipEngine(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pTKey,
+ IN UCHAR KeyId,
+ IN PUCHAR pTA,
+ IN PUCHAR pMICKey,
+ IN PUCHAR pTSC,
+ OUT PULONG pIV16,
+ OUT PULONG pIV32);
+
+VOID RTMPInitMICEngine(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKey,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN UCHAR UserPriority,
+ IN PUCHAR pMICKey);
+
+BOOLEAN RTMPTkipCompareMICValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pSrc,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN PUCHAR pMICKey,
+ IN UCHAR UserPriority,
+ IN UINT Len);
+
+VOID RTMPCalculateMICValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pEncap,
+ IN PCIPHER_KEY pKey,
+ IN UCHAR apidx);
+
+BOOLEAN RTMPTkipCompareMICValueWithLLC(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pLLC,
+ IN PUCHAR pSrc,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN PUCHAR pMICKey,
+ IN UINT Len);
+
+VOID RTMPTkipAppendByte(
+ IN PTKIP_KEY_INFO pTkip,
+ IN UCHAR uChar);
+
+VOID RTMPTkipAppend(
+ IN PTKIP_KEY_INFO pTkip,
+ IN PUCHAR pSrc,
+ IN UINT nBytes);
+
+VOID RTMPTkipGetMIC(
+ IN PTKIP_KEY_INFO pTkip);
+
+BOOLEAN RTMPSoftDecryptTKIP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN UCHAR UserPriority,
+ IN PCIPHER_KEY pWpaKey);
+
+BOOLEAN RTMPSoftDecryptAES(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN PCIPHER_KEY pWpaKey);
+
+//
+// Prototypes of function definition in cmm_info.c
+//
+NDIS_STATUS RTMPWPARemoveKeyProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PVOID pBuf);
+
+VOID RTMPWPARemoveAllKeys(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN RTMPCheckStrPrintAble(
+ IN CHAR *pInPutStr,
+ IN UCHAR strLen);
+
+VOID RTMPSetPhyMode(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG phymode);
+
+VOID RTMPUpdateHTIE(
+ IN RT_HT_CAPABILITY *pRtHt,
+ IN UCHAR *pMcsSet,
+ OUT HT_CAPABILITY_IE *pHtCapability,
+ OUT ADD_HT_INFO_IE *pAddHtInfo);
+
+VOID RTMPAddWcidAttributeEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIdx,
+ IN UCHAR KeyIdx,
+ IN UCHAR CipherAlg,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+CHAR *GetEncryptType(
+ CHAR enc);
+
+CHAR *GetAuthMode(
+ CHAR auth);
+
+VOID RTMPIoctlGetSiteSurvey(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq);
+
+VOID RTMPIoctlGetMacTable(
+ IN PRTMP_ADAPTER pAd,
+ IN struct iwreq *wrq);
+
+VOID RTMPIndicateWPA2Status(
+ IN PRTMP_ADAPTER pAdapter);
+
+VOID RTMPOPModeSwitching(
+ IN PRTMP_ADAPTER pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPAddBSSIDCipher(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Aid,
+ IN PNDIS_802_11_KEY pKey,
+ IN UCHAR CipherAlg);
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+VOID RTMPSetHT(
+ IN PRTMP_ADAPTER pAd,
+ IN OID_SET_HT_PHYMODE *pHTPhyMode);
+
+VOID RTMPSetIndividualHT(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx);
+#endif // DOT11_N_SUPPORT //
+
+VOID RTMPSendWirelessEvent(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Event_flag,
+ IN PUCHAR pAddr,
+ IN UCHAR BssIdx,
+ IN CHAR Rssi);
+
+VOID NICUpdateCntlCounters(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHeader,
+ IN UCHAR SubType,
+ IN PRXWI_STRUC pRxWI);
+//
+// prototype in wpa.c
+//
+BOOLEAN WpaMsgTypeSubst(
+ IN UCHAR EAPType,
+ OUT INT *MsgType);
+
+VOID WpaPskStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID WpaEAPOLKeyAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID WpaPairMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID WpaPairMsg3Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID WpaGroupMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID WpaMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR wep,
+ IN PUCHAR pAddr1);
+
+VOID Wpa2PairMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID Wpa2PairMsg3Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+BOOLEAN ParseKeyData(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKeyData,
+ IN UCHAR KeyDataLen,
+ IN UCHAR bPairewise);
+
+VOID RTMPToWirelessSta(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN UINT DataLen,
+ IN BOOLEAN is4wayFrame);
+
+VOID HMAC_SHA1(
+ IN UCHAR *text,
+ IN UINT text_len,
+ IN UCHAR *key,
+ IN UINT key_len,
+ IN UCHAR *digest);
+
+VOID PRF(
+ IN UCHAR *key,
+ IN INT key_len,
+ IN UCHAR *prefix,
+ IN INT prefix_len,
+ IN UCHAR *data,
+ IN INT data_len,
+ OUT UCHAR *output,
+ IN INT len);
+
+VOID CCKMPRF(
+ IN UCHAR *key,
+ IN INT key_len,
+ IN UCHAR *data,
+ IN INT data_len,
+ OUT UCHAR *output,
+ IN INT len);
+
+VOID WpaCountPTK(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR *PMK,
+ IN UCHAR *ANonce,
+ IN UCHAR *AA,
+ IN UCHAR *SNonce,
+ IN UCHAR *SA,
+ OUT UCHAR *output,
+ IN UINT len);
+
+VOID GenRandom(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR *macAddr,
+ OUT UCHAR *random);
+
+//
+// prototype in aironet.c
+//
+VOID AironetStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID AironetMsgAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID AironetRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ChannelLoadRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID NoiseHistRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID BeaconRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID AironetReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ChannelLoadReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID NoiseHistReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID AironetFinalReportAction(
+ IN PRTMP_ADAPTER pAd);
+
+VOID BeaconReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID AironetAddBeaconReport(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Index,
+ IN PMLME_QUEUE_ELEM pElem);
+
+VOID AironetCreateBeaconReportFromBssTable(
+ IN PRTMP_ADAPTER pAd);
+
+VOID DBGPRINT_TX_RING(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx);
+
+VOID DBGPRINT_RX_RING(
+ IN PRTMP_ADAPTER pAd);
+
+CHAR ConvertToRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi,
+ IN UCHAR RssiNumber);
+
+
+#ifdef DOT11N_DRAFT3
+VOID BuildEffectedChannelList(
+ IN PRTMP_ADAPTER pAd);
+#endif // DOT11N_DRAFT3 //
+
+
+VOID APAsicEvaluateRxAnt(
+ IN PRTMP_ADAPTER pAd);
+
+
+VOID APAsicRxAntEvalTimeout(
+ IN PRTMP_ADAPTER pAd);
+
+//
+// function prototype in cmm_wpa.c
+//
+BOOLEAN RTMPCheckWPAframe(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR pData,
+ IN ULONG DataByteCount,
+ IN UCHAR FromWhichBSSID);
+
+VOID AES_GTK_KEY_UNWRAP(
+ IN UCHAR *key,
+ OUT UCHAR *plaintext,
+ IN UCHAR c_len,
+ IN UCHAR *ciphertext);
+
+BOOLEAN RTMPCheckRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN UCHAR DataLen,
+ IN MAC_TABLE_ENTRY *pEntry,
+ OUT UCHAR *Offset);
+
+BOOLEAN RTMPParseEapolKeyData(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKeyData,
+ IN UCHAR KeyDataLen,
+ IN UCHAR GroupKeyIndex,
+ IN UCHAR MsgType,
+ IN BOOLEAN bWPA2,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID ConstructEapolMsg(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR PeerAuthMode,
+ IN UCHAR PeerWepStatus,
+ IN UCHAR MyGroupKeyWepStatus,
+ IN UCHAR MsgType,
+ IN UCHAR DefaultKeyIdx,
+ IN UCHAR *ReplayCounter,
+ IN UCHAR *KeyNonce,
+ IN UCHAR *TxRSC,
+ IN UCHAR *PTK,
+ IN UCHAR *GTK,
+ IN UCHAR *RSNIE,
+ IN UCHAR RSNIE_Len,
+ OUT PEAPOL_PACKET pMsg);
+
+VOID CalculateMIC(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR PeerWepStatus,
+ IN UCHAR *PTK,
+ OUT PEAPOL_PACKET pMsg);
+
+NDIS_STATUS RTMPSoftDecryptBroadCastData(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher,
+ IN PCIPHER_KEY pShard_key);
+
+VOID ConstructEapolKeyData(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR PeerAuthMode,
+ IN UCHAR PeerWepStatus,
+ IN UCHAR GroupKeyWepStatus,
+ IN UCHAR MsgType,
+ IN UCHAR DefaultKeyIdx,
+ IN BOOLEAN bWPA2Capable,
+ IN UCHAR *PTK,
+ IN UCHAR *GTK,
+ IN UCHAR *RSNIE,
+ IN UCHAR RSNIE_LEN,
+ OUT PEAPOL_PACKET pMsg);
+
+VOID RTMPMakeRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT AuthMode,
+ IN UINT WepStatus,
+ IN UCHAR apidx);
+
+//
+// function prototype in ap_wpa.c
+//
+
+BOOLEAN APWpaMsgTypeSubst(
+ IN UCHAR EAPType,
+ OUT INT *MsgType) ;
+
+MAC_TABLE_ENTRY *PACInquiry(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid);
+
+BOOLEAN RTMPCheckMcast(
+ IN PRTMP_ADAPTER pAd,
+ IN PEID_STRUCT eid_ptr,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+BOOLEAN RTMPCheckUcast(
+ IN PRTMP_ADAPTER pAd,
+ IN PEID_STRUCT eid_ptr,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+BOOLEAN RTMPCheckAUTH(
+ IN PRTMP_ADAPTER pAd,
+ IN PEID_STRUCT eid_ptr,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID WPAStart4WayHS(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN ULONG TimeInterval);
+
+VOID WPAStart2WayGroupHS(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID APWpaEAPPacketAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APWpaEAPOLStartAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APWpaEAPOLLogoffAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APWpaEAPOLKeyAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APWpaEAPOLASFAlertAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID HandleCounterMeasure(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID PeerPairMsg2Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerPairMsg4Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CMTimerExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID WPARetryExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID EnqueueStartForPSKExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID RTMPHandleSTAKey(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerGroupMsg2Action(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN VOID *Msg,
+ IN UINT MsgLen);
+
+VOID PairDisAssocAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN USHORT Reason);
+
+VOID MlmeDeAuthAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN USHORT Reason);
+
+VOID GREKEYPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID CountGTK(
+ IN UCHAR *PMK,
+ IN UCHAR *GNonce,
+ IN UCHAR *AA,
+ OUT UCHAR *output,
+ IN UINT len);
+
+VOID GetSmall(
+ IN PVOID pSrc1,
+ IN PVOID pSrc2,
+ OUT PUCHAR out,
+ IN ULONG Length);
+
+VOID GetLarge(
+ IN PVOID pSrc1,
+ IN PVOID pSrc2,
+ OUT PUCHAR out,
+ IN ULONG Length);
+
+VOID APGenRandom(
+ IN PRTMP_ADAPTER pAd,
+ OUT UCHAR *random);
+
+VOID AES_GTK_KEY_WRAP(
+ IN UCHAR *key,
+ IN UCHAR *plaintext,
+ IN UCHAR p_len,
+ OUT UCHAR *ciphertext);
+
+VOID WpaSend(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR pPacket,
+ IN ULONG Len);
+
+VOID APToWirelessSta(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN UINT DataLen,
+ IN BOOLEAN bClearFrame);
+
+VOID RTMPAddPMKIDCache(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN PUCHAR pAddr,
+ IN UCHAR *PMKID,
+ IN UCHAR *PMK);
+
+INT RTMPSearchPMKIDCache(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN PUCHAR pAddr);
+
+VOID RTMPDeletePMKIDCache(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN INT idx);
+
+VOID RTMPMaintainPMKIDCache(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPSendTriggerFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PVOID pBuffer,
+ IN ULONG Length,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull);
+
+#ifdef RT30xx
+VOID RTMPFilterCalibration(
+ IN PRTMP_ADAPTER pAd);
+#endif // RT30xx //
+
+
+//typedef void (*TIMER_FUNCTION)(unsigned long);
+
+
+/* timeout -- ms */
+VOID RTMP_SetPeriodicTimer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN unsigned long timeout);
+
+VOID RTMP_OS_Init_Timer(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN TIMER_FUNCTION function,
+ IN PVOID data);
+
+VOID RTMP_OS_Add_Timer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN unsigned long timeout);
+
+VOID RTMP_OS_Mod_Timer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN unsigned long timeout);
+
+
+VOID RTMP_OS_Del_Timer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ OUT BOOLEAN *pCancelled);
+
+
+VOID RTMP_OS_Release_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PQUEUE_ENTRY pEntry);
+
+VOID RTMPusecDelay(
+ IN ULONG usec);
+
+NDIS_STATUS os_alloc_mem(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR *mem,
+ IN ULONG size);
+
+NDIS_STATUS os_free_mem(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR mem);
+
+
+void RTMP_AllocateSharedMemory(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress,
+ OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+VOID RTMPFreeTxRxRingMemory(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS AdapterBlockAllocateMemory(
+ IN PVOID handle,
+ OUT PVOID *ppAd);
+
+void RTMP_AllocateTxDescMemory(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT Index,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress,
+ OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+void RTMP_AllocateFirstTxBuffer(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT Index,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress,
+ OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+void RTMP_AllocateMgmtDescMemory(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress,
+ OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+void RTMP_AllocateRxDescMemory(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress,
+ OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress,
+ OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress);
+
+PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length);
+
+void RTMP_QueryPacketInfo(
+ IN PNDIS_PACKET pPacket,
+ OUT PACKET_INFO *pPacketInfo,
+ OUT PUCHAR *pSrcBufVA,
+ OUT UINT *pSrcBufLen);
+
+void RTMP_QueryNextPacketInfo(
+ IN PNDIS_PACKET *ppPacket,
+ OUT PACKET_INFO *pPacketInfo,
+ OUT PUCHAR *pSrcBufVA,
+ OUT UINT *pSrcBufLen);
+
+
+BOOLEAN RTMP_FillTxBlkInfo(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk);
+
+
+PRTMP_SCATTER_GATHER_LIST
+rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg);
+
+
+ void announce_802_3_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+
+UINT BA_Reorder_AMSDU_Annnounce(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+
+UINT Handle_AMSDU_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataSize,
+ IN UCHAR FromWhichBSSID);
+
+
+void convert_802_11_to_802_3_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR p8023hdr,
+ IN PUCHAR pData,
+ IN ULONG DataSize,
+ IN UCHAR FromWhichBSSID);
+
+
+PNET_DEV get_netdev_from_bssid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR FromWhichBSSID);
+
+
+PNDIS_PACKET duplicate_pkt(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN ULONG DataSize,
+ IN UCHAR FromWhichBSSID);
+
+
+PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pOldPkt);
+
+PNDIS_PACKET duplicate_pkt_with_VLAN(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN ULONG DataSize,
+ IN UCHAR FromWhichBSSID);
+
+PNDIS_PACKET duplicate_pkt_with_WPI(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UINT32 ext_head_len,
+ IN UINT32 ext_tail_len);
+
+UCHAR VLAN_8023_Header_Copy(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ OUT PUCHAR pData,
+ IN UCHAR FromWhichBSSID);
+
+#ifdef DOT11_N_SUPPORT
+void ba_flush_reordering_timeout_mpdus(
+ IN PRTMP_ADAPTER pAd,
+ IN PBA_REC_ENTRY pBAEntry,
+ IN ULONG Now32);
+
+
+VOID BAOriSessionSetUp(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR TID,
+ IN USHORT TimeOut,
+ IN ULONG DelayTime,
+ IN BOOLEAN isForced);
+
+VOID BASessionTearDownALL(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid);
+#endif // DOT11_N_SUPPORT //
+
+BOOLEAN OS_Need_Clone_Packet(void);
+
+
+VOID build_tx_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pFrame,
+ IN ULONG FrameLen);
+
+
+VOID BAOriSessionTearDown(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR TID,
+ IN BOOLEAN bPassive,
+ IN BOOLEAN bForceSend);
+
+VOID BARecSessionTearDown(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR TID,
+ IN BOOLEAN bPassive);
+
+BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
+void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
+
+ULONG AutoChBssInsertEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR ChannelNo,
+ IN CHAR Rssi);
+
+void AutoChBssTableInit(
+ IN PRTMP_ADAPTER pAd);
+
+void ChannelInfoInit(
+ IN PRTMP_ADAPTER pAd);
+
+void AutoChBssTableDestroy(
+ IN PRTMP_ADAPTER pAd);
+
+void ChannelInfoDestroy(
+ IN PRTMP_ADAPTER pAd);
+
+UCHAR New_ApAutoSelectChannel(
+ IN PRTMP_ADAPTER pAd);
+
+
+#ifdef NINTENDO_AP
+VOID InitNINTENDO_TABLE(
+ IN PRTMP_ADAPTER pAd);
+
+UCHAR CheckNINTENDO_TABLE(
+ IN PRTMP_ADAPTER pAd,
+ PCHAR pDS_Ssid,
+ UCHAR DS_SsidLen,
+ PUCHAR pDS_Addr);
+
+UCHAR DelNINTENDO_ENTRY(
+ IN PRTMP_ADAPTER pAd,
+ UCHAR * pDS_Addr);
+
+VOID RTMPIoctlNintendoCapable(
+ IN PRTMP_ADAPTER pAd,
+ IN struct iwreq *wrq);
+
+VOID RTMPIoctlNintendoGetTable(
+ IN PRTMP_ADAPTER pAd,
+ IN struct iwreq *wrq);
+
+VOID RTMPIoctlNintendoSetTable(
+ IN PRTMP_ADAPTER pAd,
+ IN struct iwreq *wrq);
+
+#endif // NINTENDO_AP //
+
+BOOLEAN rtstrmactohex(
+ IN char *s1,
+ IN char *s2);
+
+BOOLEAN rtstrcasecmp(
+ IN char *s1,
+ IN char *s2);
+
+char *rtstrstruncasecmp(
+ IN char *s1,
+ IN char *s2);
+
+char *rtstrstr(
+ IN const char * s1,
+ IN const char * s2);
+
+char *rstrtok(
+ IN char * s,
+ IN const char * ct);
+
+int rtinet_aton(
+ const char *cp,
+ unsigned int *addr);
+
+////////// common ioctl functions //////////
+INT Set_DriverVersion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_CountryRegion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_CountryRegionABand_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_WirelessMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_Channel_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ShortSlot_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_TxPower_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_BGProtection_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_TxPreamble_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_RTSThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_FragThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_TxBurst_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+#ifdef AGGREGATION_SUPPORT
+INT Set_PktAggregate_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif
+
+INT Set_IEEE80211H_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+#ifdef DBG
+INT Set_Debug_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif
+
+INT Show_DescInfo_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ResetStatCounter_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+#ifdef DOT11_N_SUPPORT
+INT Set_BASetup_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_BADecline_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_BAOriTearDown_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_BARecTearDown_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtBw_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtMcs_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtGi_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtOpMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtStbc_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtHtc_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtExtcha_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtMpduDensity_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtBaWinSize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtRdg_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtLinkAdapt_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtAmsdu_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtAutoBa_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtProtect_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtMimoPs_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+
+INT Set_ForceShortGI_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ForceGF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT SetCommonHT(
+ IN PRTMP_ADAPTER pAd);
+
+INT Set_SendPSMPAction_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtMIMOPSmode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+
+INT Set_HtTxBASize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif // DOT11_N_SUPPORT //
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+//Dls , kathy
+VOID RTMPSendDLSTearDownFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA);
+
+#ifdef DOT11_N_SUPPORT
+//Block ACK
+VOID QueryBATABLE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PQUERYBA_TABLE pBAT);
+#endif // DOT11_N_SUPPORT //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+INT WpaCheckEapCode(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pFrame,
+ IN USHORT FrameLen,
+ IN USHORT OffSet);
+
+VOID WpaSendMicFailureToWpaSupplicant(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bUnicast);
+
+VOID SendAssocIEsToWpaSupplicant(
+ IN PRTMP_ADAPTER pAd);
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+int wext_notify_event_assoc(
+ IN RTMP_ADAPTER *pAd);
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+#ifdef DOT11_N_SUPPORT
+VOID Handle_BSS_Width_Trigger_Events(
+ IN PRTMP_ADAPTER pAd);
+
+void build_ext_channel_switch_ie(
+ IN PRTMP_ADAPTER pAd,
+ IN HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE *pIE);
+#endif // DOT11_N_SUPPORT //
+
+
+BOOLEAN APRxDoneInterruptHandle(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN STARxDoneInterruptHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN argc);
+
+#ifdef DOT11_N_SUPPORT
+// AMPDU packet indication
+VOID Indicate_AMPDU_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+// AMSDU packet indication
+VOID Indicate_AMSDU_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+#endif // DOT11_N_SUPPORT //
+
+// Normal legacy Rx packet indication
+VOID Indicate_Legacy_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+VOID Indicate_EAPOL_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+void update_os_packet_info(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+void wlan_802_11_to_802_3_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN PUCHAR pHeader802_3,
+ IN UCHAR FromWhichBSSID);
+
+UINT deaggregate_AMSDU_announce(
+ IN PRTMP_ADAPTER pAd,
+ PNDIS_PACKET pPacket,
+ IN PUCHAR pData,
+ IN ULONG DataSize);
+
+
+#ifdef CONFIG_STA_SUPPORT
+// remove LLC and get 802_3 Header
+#define RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(_pRxBlk, _pHeader802_3) \
+{ \
+ PUCHAR _pRemovedLLCSNAP = NULL, _pDA, _pSA; \
+ \
+ if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_MESH)) \
+ { \
+ _pDA = _pRxBlk->pHeader->Addr3; \
+ _pSA = (PUCHAR)_pRxBlk->pHeader + sizeof(HEADER_802_11); \
+ } \
+ else \
+ { \
+ if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_INFRA)) \
+ { \
+ _pDA = _pRxBlk->pHeader->Addr1; \
+ if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_DLS)) \
+ _pSA = _pRxBlk->pHeader->Addr2; \
+ else \
+ _pSA = _pRxBlk->pHeader->Addr3; \
+ } \
+ else \
+ { \
+ _pDA = _pRxBlk->pHeader->Addr1; \
+ _pSA = _pRxBlk->pHeader->Addr2; \
+ } \
+ } \
+ \
+ CONVERT_TO_802_3(_pHeader802_3, _pDA, _pSA, _pRxBlk->pData, \
+ _pRxBlk->DataSize, _pRemovedLLCSNAP); \
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+BOOLEAN APFowardWirelessStaToWirelessSta(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN ULONG FromWhichBSSID);
+
+VOID Announce_or_Forward_802_3_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR FromWhichBSSID);
+
+VOID Sta_Announce_or_Forward_802_3_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR FromWhichBSSID);
+
+
+#ifdef CONFIG_STA_SUPPORT
+#define ANNOUNCE_OR_FORWARD_802_3_PACKET(_pAd, _pPacket, _FromWhichBSS)\
+ Sta_Announce_or_Forward_802_3_Packet(_pAd, _pPacket, _FromWhichBSS);
+ //announce_802_3_packet(_pAd, _pPacket);
+#endif // CONFIG_STA_SUPPORT //
+
+
+PNDIS_PACKET DuplicatePacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR FromWhichBSSID);
+
+
+PNDIS_PACKET ClonePacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pData,
+ IN ULONG DataSize);
+
+
+// Normal, AMPDU or AMSDU
+VOID CmmRxnonRalinkFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+VOID CmmRxRalinkFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+VOID Update_Rssi_Sample(
+ IN PRTMP_ADAPTER pAd,
+ IN RSSI_SAMPLE *pRssi,
+ IN PRXWI_STRUC pRxWI);
+
+PNDIS_PACKET GetPacketFromRxRing(
+ IN PRTMP_ADAPTER pAd,
+ OUT PRT28XX_RXD_STRUC pSaveRxD,
+ OUT BOOLEAN *pbReschedule,
+ IN OUT UINT32 *pRxPending);
+
+PNDIS_PACKET RTMPDeFragmentDataFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk);
+
+////////////////////////////////////////
+
+
+
+
+
+#ifdef SNMP_SUPPORT
+//for snmp , kathy
+typedef struct _DefaultKeyIdxValue
+{
+ UCHAR KeyIdx;
+ UCHAR Value[16];
+} DefaultKeyIdxValue, *PDefaultKeyIdxValue;
+#endif
+
+
+#ifdef CONFIG_STA_SUPPORT
+enum {
+ DIDmsg_lnxind_wlansniffrm = 0x00000044,
+ DIDmsg_lnxind_wlansniffrm_hosttime = 0x00010044,
+ DIDmsg_lnxind_wlansniffrm_mactime = 0x00020044,
+ DIDmsg_lnxind_wlansniffrm_channel = 0x00030044,
+ DIDmsg_lnxind_wlansniffrm_rssi = 0x00040044,
+ DIDmsg_lnxind_wlansniffrm_sq = 0x00050044,
+ DIDmsg_lnxind_wlansniffrm_signal = 0x00060044,
+ DIDmsg_lnxind_wlansniffrm_noise = 0x00070044,
+ DIDmsg_lnxind_wlansniffrm_rate = 0x00080044,
+ DIDmsg_lnxind_wlansniffrm_istx = 0x00090044,
+ DIDmsg_lnxind_wlansniffrm_frmlen = 0x000A0044
+};
+enum {
+ P80211ENUM_msgitem_status_no_value = 0x00
+};
+enum {
+ P80211ENUM_truth_false = 0x00,
+ P80211ENUM_truth_true = 0x01
+};
+
+/* Definition from madwifi */
+typedef struct {
+ UINT32 did;
+ UINT16 status;
+ UINT16 len;
+ UINT32 data;
+} p80211item_uint32_t;
+
+typedef struct {
+ UINT32 msgcode;
+ UINT32 msglen;
+#define WLAN_DEVNAMELEN_MAX 16
+ 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_ng_prism2_header;
+
+/* The radio capture header precedes the 802.11 header. */
+typedef struct PACKED _ieee80211_radiotap_header {
+ UINT8 it_version; /* Version 0. Only increases
+ * for drastic changes,
+ * introduction of compatible
+ * new fields does not count.
+ */
+ UINT8 it_pad;
+ UINT16 it_len; /* length of the whole
+ * header in bytes, including
+ * it_version, it_pad,
+ * it_len, and data fields.
+ */
+ UINT32 it_present; /* A bitmap telling which
+ * fields are present. Set bit 31
+ * (0x80000000) to extend the
+ * bitmap by another 32 bits.
+ * Additional extensions are made
+ * by setting bit 31.
+ */
+}ieee80211_radiotap_header ;
+
+enum ieee80211_radiotap_type {
+ IEEE80211_RADIOTAP_TSFT = 0,
+ IEEE80211_RADIOTAP_FLAGS = 1,
+ IEEE80211_RADIOTAP_RATE = 2,
+ IEEE80211_RADIOTAP_CHANNEL = 3,
+ IEEE80211_RADIOTAP_FHSS = 4,
+ IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
+ IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
+ IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
+ IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
+ IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
+ IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
+ IEEE80211_RADIOTAP_ANTENNA = 11,
+ IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
+ IEEE80211_RADIOTAP_DB_ANTNOISE = 13
+};
+
+#define WLAN_RADIOTAP_PRESENT ( \
+ (1 << IEEE80211_RADIOTAP_TSFT) | \
+ (1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
+ 0)
+
+typedef struct _wlan_radiotap_header {
+ ieee80211_radiotap_header wt_ihdr;
+ INT64 wt_tsft;
+ UINT8 wt_flags;
+ UINT8 wt_rate;
+} wlan_radiotap_header;
+/* Definition from madwifi */
+
+void send_monitor_packets(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk);
+
+#if WIRELESS_EXT >= 12
+// This function will be called when query /proc
+struct iw_statistics *rt28xx_get_wireless_stats(
+ IN struct net_device *net_dev);
+#endif
+
+VOID RTMPSetDesiredRates(
+ IN PRTMP_ADAPTER pAdapter,
+ IN LONG Rates);
+#endif // CONFIG_STA_SUPPORT //
+
+INT Set_FixedTxMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+INT Set_OpMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+static inline char* GetPhyMode(
+ int Mode)
+{
+ switch(Mode)
+ {
+ case MODE_CCK:
+ return "CCK";
+
+ case MODE_OFDM:
+ return "OFDM";
+#ifdef DOT11_N_SUPPORT
+ case MODE_HTMIX:
+ return "HTMIX";
+
+ case MODE_HTGREENFIELD:
+ return "GREEN";
+#endif // DOT11_N_SUPPORT //
+ default:
+ return "N/A";
+ }
+}
+
+
+static inline char* GetBW(
+ int BW)
+{
+ switch(BW)
+ {
+ case BW_10:
+ return "10M";
+
+ case BW_20:
+ return "20M";
+#ifdef DOT11_N_SUPPORT
+ case BW_40:
+ return "40M";
+#endif // DOT11_N_SUPPORT //
+ default:
+ return "N/A";
+ }
+}
+
+
+VOID RT28xxThreadTerminate(
+ IN RTMP_ADAPTER *pAd);
+
+BOOLEAN RT28XXChipsetCheck(
+ IN void *_dev_p);
+
+BOOLEAN RT28XXNetDevInit(
+ IN void *_dev_p,
+ IN struct net_device *net_dev,
+ IN RTMP_ADAPTER *pAd);
+
+BOOLEAN RT28XXProbePostConfig(
+ IN void *_dev_p,
+ IN RTMP_ADAPTER *pAd,
+ IN INT32 argc);
+
+VOID RT28XXDMADisable(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RT28XXDMAEnable(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RT28xx_UpdateBeaconToAsic(
+ IN RTMP_ADAPTER * pAd,
+ IN INT apidx,
+ IN ULONG BeaconLen,
+ IN ULONG UpdatePos);
+
+INT rt28xx_ioctl(
+ IN struct net_device *net_dev,
+ IN OUT struct ifreq *rq,
+ IN INT cmd);
+
+
+#ifdef CONFIG_STA_SUPPORT
+INT rt28xx_sta_ioctl(
+ IN struct net_device *net_dev,
+ IN OUT struct ifreq *rq,
+ IN INT cmd);
+#endif // CONFIG_STA_SUPPORT //
+
+BOOLEAN RT28XXSecurityKeyAdd(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG apidx,
+ IN ULONG KeyIdx,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+////////////////////////////////////////
+PNDIS_PACKET GetPacketFromRxRing(
+ IN PRTMP_ADAPTER pAd,
+ OUT PRT28XX_RXD_STRUC pSaveRxD,
+ OUT BOOLEAN *pbReschedule,
+ IN OUT UINT32 *pRxPending);
+
+
+void kill_thread_task(PRTMP_ADAPTER pAd);
+
+void tbtt_tasklet(unsigned long data);
+
+
+VOID AsicTurnOffRFClk(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel);
+
+VOID AsicTurnOnRFClk(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel);
+
+#ifdef RT30xx
+NTSTATUS RT30xxWriteRFRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR RegID,
+ IN UCHAR Value);
+
+NTSTATUS RT30xxReadRFRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR RegID,
+ IN PUCHAR pValue);
+
+//2008/09/11:KH add to support efuse<--
+UCHAR eFuseReadRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ OUT USHORT* pData);
+
+VOID eFuseReadPhysical(
+ IN PRTMP_ADAPTER pAd,
+ IN PUSHORT lpInBuffer,
+ IN ULONG nInBufferSize,
+ OUT PUSHORT lpOutBuffer,
+ IN ULONG nOutBufferSize
+);
+
+NTSTATUS eFuseRead(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUCHAR pData,
+ IN USHORT Length);
+
+VOID eFusePhysicalWriteRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ OUT USHORT* pData);
+
+NTSTATUS eFuseWriteRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ IN USHORT* pData);
+
+VOID eFuseWritePhysical(
+ IN PRTMP_ADAPTER pAd,
+ PUSHORT lpInBuffer,
+ ULONG nInBufferSize,
+ PUCHAR lpOutBuffer,
+ ULONG nOutBufferSize
+);
+
+NTSTATUS eFuseWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData,
+ IN USHORT length);
+
+INT set_eFuseGetFreeBlockCount_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT set_eFusedump_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT set_eFuseLoadFromBin_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+NTSTATUS eFuseWriteRegistersFromBin(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ IN USHORT* pData);
+
+VOID eFusePhysicalReadRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ OUT USHORT* pData);
+
+NDIS_STATUS NICLoadEEPROM(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN bNeedLoadEEPROM(
+ IN PRTMP_ADAPTER pAd);
+//2008/09/11:KH add to support efuse-->
+#endif // RT30xx //
+
+#ifdef RT30xx
+// add by johnli, RF power sequence setup
+VOID RT30xxLoadRFNormalModeSetup(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RT30xxLoadRFSleepModeSetup(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RT30xxReverseRFSleepModeSetup(
+ IN PRTMP_ADAPTER pAd);
+// end johnli
+#endif // RT30xx //
+
+#ifdef RT2870
+//
+// Function Prototype in rtusb_bulk.c
+//
+VOID RTUSBInitTxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PTX_CONTEXT pTxContext,
+ IN UCHAR BulkOutPipeId,
+ IN usb_complete_t Func);
+
+VOID RTUSBInitHTTxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PHT_TX_CONTEXT pTxContext,
+ IN UCHAR BulkOutPipeId,
+ IN ULONG BulkOutSize,
+ IN usb_complete_t Func);
+
+VOID RTUSBInitRxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PRX_CONTEXT pRxContext);
+
+VOID RTUSBCleanUpDataBulkOutQueue(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBCancelPendingBulkOutIRP(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBBulkOutDataPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BulkOutPipeId,
+ IN UCHAR Index);
+
+VOID RTUSBBulkOutNullFrame(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBBulkOutRTSFrame(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBCancelPendingBulkInIRP(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBCancelPendingIRPs(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBBulkOutMLMEPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID RTUSBBulkOutPsPoll(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBCleanUpMLMEBulkOutQueue(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBKickBulkOut(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBBulkReceive(
+ IN PRTMP_ADAPTER pAd);
+
+VOID DoBulkIn(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RTUSBInitRxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PRX_CONTEXT pRxContext);
+
+VOID RTUSBBulkRxHandle(
+ IN unsigned long data);
+
+//
+// Function Prototype in rtusb_io.c
+//
+NTSTATUS RTUSBMultiRead(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUCHAR pData,
+ IN USHORT length);
+
+NTSTATUS RTUSBMultiWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData,
+ IN USHORT length);
+
+NTSTATUS RTUSBMultiWrite_OneByte(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData);
+
+NTSTATUS RTUSBReadBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN PUCHAR pValue);
+
+NTSTATUS RTUSBWriteBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN UCHAR Value);
+
+NTSTATUS RTUSBWriteRFRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 Value);
+
+NTSTATUS RTUSB_VendorRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 TransferFlags,
+ IN UCHAR ReservedBits,
+ IN UCHAR Request,
+ IN USHORT Value,
+ IN USHORT Index,
+ IN PVOID TransferBuffer,
+ IN UINT32 TransferBufferLength);
+
+NTSTATUS RTUSBReadEEPROM(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUCHAR pData,
+ IN USHORT length);
+
+NTSTATUS RTUSBWriteEEPROM(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData,
+ IN USHORT length);
+
+VOID RTUSBPutToSleep(
+ IN PRTMP_ADAPTER pAd);
+
+NTSTATUS RTUSBWakeUp(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBInitializeCmdQ(
+ IN PCmdQ cmdq);
+
+NDIS_STATUS RTUSBEnqueueCmdFromNdis(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_OID Oid,
+ IN BOOLEAN SetInformation,
+ IN PVOID pInformationBuffer,
+ IN UINT32 InformationBufferLength);
+
+NDIS_STATUS RTUSBEnqueueInternalCmd(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_OID Oid,
+ IN PVOID pInformationBuffer,
+ IN UINT32 InformationBufferLength);
+
+VOID RTUSBDequeueCmd(
+ IN PCmdQ cmdq,
+ OUT PCmdQElmt *pcmdqelmt);
+
+INT RTUSBCmdThread(
+ IN OUT PVOID Context);
+
+INT TimerQThread(
+ IN OUT PVOID Context);
+
+RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
+ IN RTMP_ADAPTER *pAd,
+ IN RALINK_TIMER_STRUCT *pTimer);
+
+BOOLEAN RT2870_TimerQ_Remove(
+ IN RTMP_ADAPTER *pAd,
+ IN RALINK_TIMER_STRUCT *pTimer);
+
+void RT2870_TimerQ_Exit(
+ IN RTMP_ADAPTER *pAd);
+
+void RT2870_TimerQ_Init(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RT2870_BssBeaconExit(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RT2870_BssBeaconStop(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RT2870_BssBeaconStart(
+ IN RTMP_ADAPTER * pAd);
+
+VOID RT2870_BssBeaconInit(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RT2870_WatchDog(
+ IN RTMP_ADAPTER *pAd);
+
+NTSTATUS RTUSBWriteMACRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN UINT32 Value);
+
+NTSTATUS RTUSBReadMACRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUINT32 pValue);
+
+NTSTATUS RTUSBSingleWrite(
+ IN RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ IN USHORT Value);
+
+NTSTATUS RTUSBFirmwareRun(
+ IN PRTMP_ADAPTER pAd);
+
+NTSTATUS RTUSBFirmwareWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pFwImage,
+ IN ULONG FwLen);
+
+NTSTATUS RTUSBFirmwareOpmode(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUINT32 pValue);
+
+NTSTATUS RTUSBVenderReset(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS RTUSBSetHardWareRegister(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PVOID pBuf);
+
+NDIS_STATUS RTUSBQueryHardWareRegister(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PVOID pBuf);
+
+VOID CMDHandler(
+ IN PRTMP_ADAPTER pAd);
+
+
+NDIS_STATUS CreateThreads(
+ IN struct net_device *net_dev );
+
+
+VOID MacTableInitialize(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeSetPsm(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT psm);
+
+NDIS_STATUS RTMPWPAAddKeyProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PVOID pBuf);
+
+VOID AsicRxAntEvalAction(
+ IN PRTMP_ADAPTER pAd);
+
+void append_pkt(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN ULONG DataSize,
+ OUT PNDIS_PACKET *ppPacket);
+
+UINT deaggregate_AMSDU_announce(
+ IN PRTMP_ADAPTER pAd,
+ PNDIS_PACKET pPacket,
+ IN PUCHAR pData,
+ IN ULONG DataSize);
+
+NDIS_STATUS RTMPCheckRxError(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHeader,
+ IN PRXWI_STRUC pRxWI,
+ IN PRT28XX_RXD_STRUC pRxINFO);
+
+
+VOID RTUSBMlmeHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN PMGMT_STRUC pMgmt);
+
+INT MlmeThread(
+ IN PVOID Context);
+
+//
+// Function Prototype in rtusb_data.c
+//
+NDIS_STATUS RTUSBFreeDescriptorRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BulkOutPipeId,
+ IN UINT32 NumberRequired);
+
+
+BOOLEAN RTUSBNeedQueueBackForAgg(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR BulkOutPipeId);
+
+
+VOID RTMPWriteTxInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXINFO_STRUC pTxInfo,
+ IN USHORT USBDMApktLen,
+ IN BOOLEAN bWiv,
+ IN UCHAR QueueSel,
+ IN UCHAR NextValid,
+ IN UCHAR TxBurst);
+
+//
+// Function Prototype in cmm_data_2870.c
+//
+USHORT RtmpUSB_WriteSubTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN BOOLEAN bIsLast,
+ OUT USHORT *FreeNumber);
+
+USHORT RtmpUSB_WriteSingleTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN BOOLEAN bIsLast,
+ OUT USHORT *FreeNumber);
+
+USHORT RtmpUSB_WriteFragTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR fragNum,
+ OUT USHORT *FreeNumber);
+
+USHORT RtmpUSB_WriteMultiTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR frameNum,
+ OUT USHORT *FreeNumber);
+
+VOID RtmpUSB_FinalWriteTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN USHORT totalMPDUSize,
+ IN USHORT TxIdx);
+
+VOID RtmpUSBDataLastTxIdx(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN USHORT TxIdx);
+
+VOID RtmpUSBDataKickOut(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR QueIdx);
+
+
+int RtmpUSBMgmtKickOut(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pSrcBufVA,
+ IN UINT SrcBufLen);
+
+VOID RtmpUSBNullFrameKickOut(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN UCHAR *pNullFrame,
+ IN UINT32 frameLen);
+
+VOID RT28xxUsbStaAsicForceWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bFromTx);
+
+VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT TbttNumToNextWakeUp);
+
+VOID RT28xxUsbMlmeRadioOn(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RT28xxUsbMlmeRadioOFF(
+ IN PRTMP_ADAPTER pAd);
+#endif // RT2870 //
+
+////////////////////////////////////////
+
+VOID QBSS_LoadInit(
+ IN RTMP_ADAPTER *pAd);
+
+UINT32 QBSS_LoadElementAppend(
+ IN RTMP_ADAPTER *pAd,
+ OUT UINT8 *buf_p);
+
+VOID QBSS_LoadUpdate(
+ IN RTMP_ADAPTER *pAd);
+
+///////////////////////////////////////
+INT RTMPShowCfgValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pName,
+ IN PUCHAR pBuf);
+
+PCHAR RTMPGetRalinkAuthModeStr(
+ IN NDIS_802_11_AUTHENTICATION_MODE authMode);
+
+PCHAR RTMPGetRalinkEncryModeStr(
+ IN USHORT encryMode);
+//////////////////////////////////////
+
+#ifdef CONFIG_STA_SUPPORT
+VOID AsicStaBbpTuning(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN StaAddMacTableEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN UCHAR MaxSupportedRateIn500Kbps,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ IN USHORT CapabilityInfo);
+#endif // CONFIG_STA_SUPPORT //
+
+void RTMP_IndicateMediaState(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ReSyncBeaconTime(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPSetAGCInitValue(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BandWidth);
+
+int rt28xx_close(IN PNET_DEV dev);
+int rt28xx_open(IN PNET_DEV dev);
+
+__inline INT VIRTUAL_IF_UP(PRTMP_ADAPTER pAd)
+{
+extern VOID MeshMakeBeacon(IN PRTMP_ADAPTER pAd, IN UCHAR idx);
+extern VOID MeshUpdateBeaconFrame(IN PRTMP_ADAPTER pAd, IN UCHAR idx);
+
+ if (VIRTUAL_IF_NUM(pAd) == 0)
+ {
+ if (rt28xx_open(pAd->net_dev) != 0)
+ return -1;
+ }
+ else
+ {
+ }
+ VIRTUAL_IF_INC(pAd);
+ return 0;
+}
+
+__inline VOID VIRTUAL_IF_DOWN(PRTMP_ADAPTER pAd)
+{
+ VIRTUAL_IF_DEC(pAd);
+ if (VIRTUAL_IF_NUM(pAd) == 0)
+ rt28xx_close(pAd->net_dev);
+ return;
+}
+
+
+#endif // __RTMP_H__
+
diff --git a/drivers/staging/rt3070/rtmp_ckipmic.h b/drivers/staging/rt3070/rtmp_ckipmic.h
new file mode 100644
index 00000000000..a3d949a39d3
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp_ckipmic.h
@@ -0,0 +1,113 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_ckipmic.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+#ifndef __RTMP_CKIPMIC_H__
+#define __RTMP_CKIPMIC_H__
+
+typedef struct _MIC_CONTEXT {
+ /* --- MMH context */
+ UCHAR CK[16]; /* the key */
+ UCHAR coefficient[16]; /* current aes counter mode coefficients */
+ ULONGLONG accum; /* accumulated mic, reduced to u32 in final() */
+ UINT position; /* current position (byte offset) in message */
+ UCHAR part[4]; /* for conversion of message to u32 for mmh */
+} MIC_CONTEXT, *PMIC_CONTEXT;
+
+VOID CKIP_key_permute(
+ OUT UCHAR *PK, /* output permuted key */
+ IN UCHAR *CK, /* input CKIP key */
+ IN UCHAR toDsFromDs, /* input toDs/FromDs bits */
+ IN UCHAR *piv); /* input pointer to IV */
+
+VOID RTMPCkipMicInit(
+ IN PMIC_CONTEXT pContext,
+ IN PUCHAR CK);
+
+VOID RTMPMicUpdate(
+ IN PMIC_CONTEXT pContext,
+ IN PUCHAR pOctets,
+ IN INT len);
+
+ULONG RTMPMicGetCoefficient(
+ IN PMIC_CONTEXT pContext);
+
+VOID xor_128(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out);
+
+UCHAR RTMPCkipSbox(
+ IN UCHAR a);
+
+VOID xor_32(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out);
+
+VOID next_key(
+ IN PUCHAR key,
+ IN INT round);
+
+VOID byte_sub(
+ IN PUCHAR in,
+ OUT PUCHAR out);
+
+VOID shift_row(
+ IN PUCHAR in,
+ OUT PUCHAR out);
+
+VOID mix_column(
+ IN PUCHAR in,
+ OUT PUCHAR out);
+
+VOID RTMPAesEncrypt(
+ IN PUCHAR key,
+ IN PUCHAR data,
+ IN PUCHAR ciphertext);
+
+VOID RTMPMicFinal(
+ IN PMIC_CONTEXT pContext,
+ OUT UCHAR digest[4]);
+
+VOID RTMPCkipInsertCMIC(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pMIC,
+ IN PUCHAR p80211hdr,
+ IN PNDIS_PACKET pPacket,
+ IN PCIPHER_KEY pKey,
+ IN PUCHAR mic_snap);
+
+#endif //__RTMP_CKIPMIC_H__
diff --git a/drivers/staging/rt3070/rtmp_def.h b/drivers/staging/rt3070/rtmp_def.h
new file mode 100644
index 00000000000..2599f7c836e
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp_def.h
@@ -0,0 +1,1559 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_def.h
+
+ Abstract:
+ Miniport related definition header
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 08-01-2002 created
+ John Chang 08-05-2003 add definition for 11g & other drafts
+*/
+#ifndef __RTMP_DEF_H__
+#define __RTMP_DEF_H__
+
+#include "oid.h"
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+//
+// Debug information verbosity: lower values indicate higher urgency
+//
+#define RT_DEBUG_OFF 0
+#define RT_DEBUG_ERROR 1
+#define RT_DEBUG_WARN 2
+#define RT_DEBUG_TRACE 3
+#define RT_DEBUG_INFO 4
+#define RT_DEBUG_LOUD 5
+
+#define NIC_TAG ((ULONG)'0682')
+#define NIC_DBG_STRING ("**RT28xx**")
+
+#ifdef SNMP_SUPPORT
+// for snmp
+// to get manufacturer OUI, kathy, 2008_0220
+#define ManufacturerOUI_LEN 3
+#define ManufacturerNAME ("Ralink Technology Company.")
+#define ResourceTypeIdName ("Ralink_ID")
+#endif
+
+
+//#define PACKED
+
+#define RALINK_2883_VERSION ((UINT32)0x28830300)
+#define RALINK_2880E_VERSION ((UINT32)0x28720200)
+#define RALINK_3070_VERSION ((UINT32)0x30700200)
+
+//
+// NDIS version in use by the NIC driver.
+// The high byte is the major version. The low byte is the minor version.
+//
+#ifdef NDIS51_MINIPORT
+#define NIC_DRIVER_VERSION 0x0501
+#else
+#define NIC_DRIVER_VERSION 0x0500
+#endif
+
+//
+// NDIS media type, current is ethernet, change if native wireless supported
+//
+#define NIC_MEDIA_TYPE NdisMedium802_3
+#define NIC_PCI_HDR_LENGTH 0xe2
+#define NIC_MAX_PACKET_SIZE 2304
+#define NIC_HEADER_SIZE 14
+#define MAX_MAP_REGISTERS_NEEDED 32
+#define MIN_MAP_REGISTERS_NEEDED 2 //Todo: should consider fragment issue.
+
+//
+// interface type, we use PCI
+//
+#define NIC_INTERFACE_TYPE NdisInterfacePci
+#define NIC_INTERRUPT_MODE NdisInterruptLevelSensitive
+
+//
+// buffer size passed in NdisMQueryAdapterResources
+// We should only need three adapter resources (IO, interrupt and memory),
+// Some devices get extra resources, so have room for 10 resources
+// UF_SIZE (sizeof(NDIS_RESOURCE_LIST) + (10*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)))
+
+
+#define NIC_RESOURCE_B//
+// IO space length
+//
+#define NIC_MAP_IOSPACE_LENGTH sizeof(CSR_STRUC)
+
+#define MAX_RX_PKT_LEN 1520
+
+//
+// Entry number for each DMA descriptor ring
+//
+
+
+#ifdef RT2870
+#define TX_RING_SIZE 8 // 1
+#define PRIO_RING_SIZE 8
+#define MGMT_RING_SIZE 32 // PRIO_RING_SIZE
+#define RX_RING_SIZE 8
+#define MAX_TX_PROCESS 4
+#define LOCAL_TXBUF_SIZE 2048
+#endif // RT2870 //
+
+#ifdef MULTIPLE_CARD_SUPPORT
+// MC: Multple Cards
+#define MAX_NUM_OF_MULTIPLE_CARD 32
+#endif // MULTIPLE_CARD_SUPPORT //
+
+#define MAX_RX_PROCESS 128 //64 //32
+#define NUM_OF_LOCAL_TXBUF 2
+#define TXD_SIZE 16
+#define TXWI_SIZE 16
+#define RXD_SIZE 16
+#define RXWI_SIZE 16
+// TXINFO_SIZE + TXWI_SIZE + 802.11 Header Size + AMSDU sub frame header
+#define TX_DMA_1ST_BUFFER_SIZE 96 // only the 1st physical buffer is pre-allocated
+#define MGMT_DMA_BUFFER_SIZE 1536 //2048
+#define RX_BUFFER_AGGRESIZE 3840 //3904 //3968 //4096 //2048 //4096
+#define RX_BUFFER_NORMSIZE 3840 //3904 //3968 //4096 //2048 //4096
+#define TX_BUFFER_NORMSIZE RX_BUFFER_NORMSIZE
+#define MAX_FRAME_SIZE 2346 // Maximum 802.11 frame size
+#define MAX_AGGREGATION_SIZE 3840 //3904 //3968 //4096
+#define MAX_NUM_OF_TUPLE_CACHE 2
+#define MAX_MCAST_LIST_SIZE 32
+#define MAX_LEN_OF_VENDOR_DESC 64
+//#define MAX_SIZE_OF_MCAST_PSQ (NUM_OF_LOCAL_TXBUF >> 2) // AP won't spend more than 1/4 of total buffers on M/BCAST PSQ
+#define MAX_SIZE_OF_MCAST_PSQ 32
+
+#define MAX_RX_PROCESS_CNT (RX_RING_SIZE)
+
+
+#define MAX_PACKETS_IN_QUEUE (512) //(512) // to pass WMM A5-WPAPSK
+#define MAX_PACKETS_IN_MCAST_PS_QUEUE 32
+#define MAX_PACKETS_IN_PS_QUEUE 128 //32
+#define WMM_NUM_OF_AC 4 /* AC0, AC1, AC2, and AC3 */
+
+
+//2008/09/11:KH add to support efuse<--
+#define MAX_EEPROM_BIN_FILE_SIZE 1024
+//2008/09/11:KH add to support efuse-->
+
+// RxFilter
+#define STANORMAL 0x17f97
+#define APNORMAL 0x15f97
+//
+// RTMP_ADAPTER flags
+//
+#define fRTMP_ADAPTER_MAP_REGISTER 0x00000001
+#define fRTMP_ADAPTER_INTERRUPT_IN_USE 0x00000002
+#define fRTMP_ADAPTER_HARDWARE_ERROR 0x00000004
+#define fRTMP_ADAPTER_SCATTER_GATHER 0x00000008
+#define fRTMP_ADAPTER_SEND_PACKET_ERROR 0x00000010
+#define fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS 0x00000020
+#define fRTMP_ADAPTER_HALT_IN_PROGRESS 0x00000040
+#define fRTMP_ADAPTER_RESET_IN_PROGRESS 0x00000080
+#define fRTMP_ADAPTER_NIC_NOT_EXIST 0x00000100
+#define fRTMP_ADAPTER_TX_RING_ALLOCATED 0x00000200
+#define fRTMP_ADAPTER_REMOVE_IN_PROGRESS 0x00000400
+#define fRTMP_ADAPTER_MIMORATE_INUSED 0x00000800
+#define fRTMP_ADAPTER_RX_RING_ALLOCATED 0x00001000
+#define fRTMP_ADAPTER_INTERRUPT_ACTIVE 0x00002000
+#define fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS 0x00004000
+#define fRTMP_ADAPTER_REASSOC_IN_PROGRESS 0x00008000
+#define fRTMP_ADAPTER_MEDIA_STATE_PENDING 0x00010000
+#define fRTMP_ADAPTER_RADIO_OFF 0x00020000
+#define fRTMP_ADAPTER_BULKOUT_RESET 0x00040000
+#define fRTMP_ADAPTER_BULKIN_RESET 0x00080000
+#define fRTMP_ADAPTER_RDG_ACTIVE 0x00100000
+#define fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE 0x00200000
+#define fRTMP_ADAPTER_SCAN_2040 0x04000000
+#define fRTMP_ADAPTER_RADIO_MEASUREMENT 0x08000000
+
+#define fRTMP_ADAPTER_START_UP 0x10000000 //Devive already initialized and enabled Tx/Rx.
+#define fRTMP_ADAPTER_MEDIA_STATE_CHANGE 0x20000000
+#define fRTMP_ADAPTER_IDLE_RADIO_OFF 0x40000000
+
+// Lock bit for accessing different ring buffers
+//#define fRTMP_ADAPTER_TX_RING_BUSY 0x80000000
+//#define fRTMP_ADAPTER_MGMT_RING_BUSY 0x40000000
+//#define fRTMP_ADAPTER_ATIM_RING_BUSY 0x20000000
+//#define fRTMP_ADAPTER_RX_RING_BUSY 0x10000000
+
+// Lock bit for accessing different queue
+//#define fRTMP_ADAPTER_TX_QUEUE_BUSY 0x08000000
+//#define fRTMP_ADAPTER_MGMT_QUEUE_BUSY 0x04000000
+
+//
+// STA operation status flags
+//
+#define fOP_STATUS_INFRA_ON 0x00000001
+#define fOP_STATUS_ADHOC_ON 0x00000002
+#define fOP_STATUS_BG_PROTECTION_INUSED 0x00000004
+#define fOP_STATUS_SHORT_SLOT_INUSED 0x00000008
+#define fOP_STATUS_SHORT_PREAMBLE_INUSED 0x00000010
+#define fOP_STATUS_RECEIVE_DTIM 0x00000020
+//#define fOP_STATUS_TX_RATE_SWITCH_ENABLED 0x00000040
+#define fOP_STATUS_MEDIA_STATE_CONNECTED 0x00000080
+#define fOP_STATUS_WMM_INUSED 0x00000100
+#define fOP_STATUS_AGGREGATION_INUSED 0x00000200
+#define fOP_STATUS_DOZE 0x00000400 // debug purpose
+#define fOP_STATUS_PIGGYBACK_INUSED 0x00000800 // piggy-back, and aggregation
+#define fOP_STATUS_APSD_INUSED 0x00001000
+#define fOP_STATUS_TX_AMSDU_INUSED 0x00002000
+#define fOP_STATUS_MAX_RETRY_ENABLED 0x00004000
+#define fOP_STATUS_WAKEUP_NOW 0x00008000
+#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE 0x00020000
+
+#ifdef DOT11N_DRAFT3
+#define fOP_STATUS_SCAN_2040 0x00040000
+#endif // DOT11N_DRAFT3 //
+
+#define CCKSETPROTECT 0x1
+#define OFDMSETPROTECT 0x2
+#define MM20SETPROTECT 0x4
+#define MM40SETPROTECT 0x8
+#define GF20SETPROTECT 0x10
+#define GR40SETPROTECT 0x20
+#define ALLN_SETPROTECT (GR40SETPROTECT | GF20SETPROTECT | MM40SETPROTECT | MM20SETPROTECT)
+
+//
+// AP's client table operation status flags
+//
+#define fCLIENT_STATUS_WMM_CAPABLE 0x00000001 // CLIENT can parse QOS DATA frame
+#define fCLIENT_STATUS_AGGREGATION_CAPABLE 0x00000002 // CLIENT can receive Ralink's proprietary TX aggregation frame
+#define fCLIENT_STATUS_PIGGYBACK_CAPABLE 0x00000004 // CLIENT support piggy-back
+#define fCLIENT_STATUS_AMSDU_INUSED 0x00000008
+#define fCLIENT_STATUS_SGI20_CAPABLE 0x00000010
+#define fCLIENT_STATUS_SGI40_CAPABLE 0x00000020
+#define fCLIENT_STATUS_TxSTBC_CAPABLE 0x00000040
+#define fCLIENT_STATUS_RxSTBC_CAPABLE 0x00000080
+#define fCLIENT_STATUS_HTC_CAPABLE 0x00000100
+#define fCLIENT_STATUS_RDG_CAPABLE 0x00000200
+#define fCLIENT_STATUS_MCSFEEDBACK_CAPABLE 0x00000400
+#define fCLIENT_STATUS_APSD_CAPABLE 0x00000800 /* UAPSD STATION */
+
+#ifdef DOT11N_DRAFT3
+#define fCLIENT_STATUS_BSSCOEXIST_CAPABLE 0x00001000
+#endif // DOT11N_DRAFT3 //
+
+#define fCLIENT_STATUS_RALINK_CHIPSET 0x00100000
+//
+// STA configuration flags
+//
+//#define fSTA_CFG_ENABLE_TX_BURST 0x00000001
+
+// 802.11n Operating Mode Definition. 0-3 also used in ASICUPdateProtect switch case
+#define HT_NO_PROTECT 0
+#define HT_LEGACY_PROTECT 1
+#define HT_40_PROTECT 2
+#define HT_2040_PROTECT 3
+#define HT_RTSCTS_6M 7
+//following is our own definition in order to turn on our ASIC protection register in INFRASTRUCTURE.
+#define HT_ATHEROS 8
+#define HT_FORCERTSCTS 9 // Force turn on RTS/CTS first. then go to evaluate if this force RTS is necessary.
+
+//
+// RX Packet Filter control flags. Apply on pAd->PacketFilter
+//
+#define fRX_FILTER_ACCEPT_DIRECT NDIS_PACKET_TYPE_DIRECTED
+#define fRX_FILTER_ACCEPT_MULTICAST NDIS_PACKET_TYPE_MULTICAST
+#define fRX_FILTER_ACCEPT_BROADCAST NDIS_PACKET_TYPE_BROADCAST
+#define fRX_FILTER_ACCEPT_ALL_MULTICAST NDIS_PACKET_TYPE_ALL_MULTICAST
+
+//
+// Error code section
+//
+// NDIS_ERROR_CODE_ADAPTER_NOT_FOUND
+#define ERRLOG_READ_PCI_SLOT_FAILED 0x00000101L
+#define ERRLOG_WRITE_PCI_SLOT_FAILED 0x00000102L
+#define ERRLOG_VENDOR_DEVICE_NOMATCH 0x00000103L
+
+// NDIS_ERROR_CODE_ADAPTER_DISABLED
+#define ERRLOG_BUS_MASTER_DISABLED 0x00000201L
+
+// NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION
+#define ERRLOG_INVALID_SPEED_DUPLEX 0x00000301L
+#define ERRLOG_SET_SECONDARY_FAILED 0x00000302L
+
+// NDIS_ERROR_CODE_OUT_OF_RESOURCES
+#define ERRLOG_OUT_OF_MEMORY 0x00000401L
+#define ERRLOG_OUT_OF_SHARED_MEMORY 0x00000402L
+#define ERRLOG_OUT_OF_MAP_REGISTERS 0x00000403L
+#define ERRLOG_OUT_OF_BUFFER_POOL 0x00000404L
+#define ERRLOG_OUT_OF_NDIS_BUFFER 0x00000405L
+#define ERRLOG_OUT_OF_PACKET_POOL 0x00000406L
+#define ERRLOG_OUT_OF_NDIS_PACKET 0x00000407L
+#define ERRLOG_OUT_OF_LOOKASIDE_MEMORY 0x00000408L
+
+// NDIS_ERROR_CODE_HARDWARE_FAILURE
+#define ERRLOG_SELFTEST_FAILED 0x00000501L
+#define ERRLOG_INITIALIZE_ADAPTER 0x00000502L
+#define ERRLOG_REMOVE_MINIPORT 0x00000503L
+
+// NDIS_ERROR_CODE_RESOURCE_CONFLICT
+#define ERRLOG_MAP_IO_SPACE 0x00000601L
+#define ERRLOG_QUERY_ADAPTER_RESOURCES 0x00000602L
+#define ERRLOG_NO_IO_RESOURCE 0x00000603L
+#define ERRLOG_NO_INTERRUPT_RESOURCE 0x00000604L
+#define ERRLOG_NO_MEMORY_RESOURCE 0x00000605L
+
+
+// WDS definition
+#define MAX_WDS_ENTRY 4
+#define WDS_PAIRWISE_KEY_OFFSET 60 // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
+
+#define WDS_DISABLE_MODE 0
+#define WDS_RESTRICT_MODE 1
+#define WDS_BRIDGE_MODE 2
+#define WDS_REPEATER_MODE 3
+#define WDS_LAZY_MODE 4
+
+
+#define MAX_MESH_NUM 0
+
+#define MAX_APCLI_NUM 0
+
+#define MAX_MBSSID_NUM 1
+#ifdef MBSS_SUPPORT
+#undef MAX_MBSSID_NUM
+#define MAX_MBSSID_NUM (8 - MAX_MESH_NUM - MAX_APCLI_NUM)
+#endif // MBSS_SUPPORT //
+
+/* sanity check for apidx */
+#define MBSS_MR_APIDX_SANITY_CHECK(apidx) \
+ { if (apidx > MAX_MBSSID_NUM) { \
+ printk("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __FUNCTION__, apidx); \
+ apidx = MAIN_MBSSID; } }
+
+#define VALID_WCID(_wcid) ((_wcid) > 0 && (_wcid) < MAX_LEN_OF_MAC_TABLE )
+
+#define MAIN_MBSSID 0
+#define FIRST_MBSSID 1
+
+
+#define MAX_BEACON_SIZE 512
+// If the MAX_MBSSID_NUM is larger than 6,
+// it shall reserve some WCID space(wcid 222~253) for beacon frames.
+// - these wcid 238~253 are reserved for beacon#6(ra6).
+// - these wcid 222~237 are reserved for beacon#7(ra7).
+#if defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 8)
+#define HW_RESERVED_WCID 222
+#elif defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 7)
+#define HW_RESERVED_WCID 238
+#else
+#define HW_RESERVED_WCID 255
+#endif
+
+// Then dedicate wcid of DFS and Carrier-Sense.
+#define DFS_CTS_WCID (HW_RESERVED_WCID - 1)
+#define CS_CTS_WCID (HW_RESERVED_WCID - 2)
+#define LAST_SPECIFIC_WCID (HW_RESERVED_WCID - 2)
+
+// If MAX_MBSSID_NUM is 8, the maximum available wcid for the associated STA is 211.
+// If MAX_MBSSID_NUM is 7, the maximum available wcid for the associated STA is 228.
+#define MAX_AVAILABLE_CLIENT_WCID (LAST_SPECIFIC_WCID - MAX_MBSSID_NUM - 1)
+
+// TX need WCID to find Cipher Key
+// these wcid 212 ~ 219 are reserved for bc/mc packets if MAX_MBSSID_NUM is 8.
+#define GET_GroupKey_WCID(__wcid, __bssidx) \
+ { \
+ __wcid = LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM) + __bssidx; \
+ }
+
+#define IsGroupKeyWCID(__wcid) (((__wcid) < LAST_SPECIFIC_WCID) && ((__wcid) >= (LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM))))
+
+
+// definition to support multiple BSSID
+#define BSS0 0
+#define BSS1 1
+#define BSS2 2
+#define BSS3 3
+#define BSS4 4
+#define BSS5 5
+#define BSS6 6
+#define BSS7 7
+
+
+//============================================================
+// Length definitions
+#define PEER_KEY_NO 2
+#define MAC_ADDR_LEN 6
+#define TIMESTAMP_LEN 8
+#define MAX_LEN_OF_SUPPORTED_RATES MAX_LENGTH_OF_SUPPORT_RATES // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
+#define MAX_LEN_OF_KEY 32 // 32 octets == 256 bits, Redefine for WPA
+#define MAX_NUM_OF_CHANNELS MAX_NUM_OF_CHS // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
+#define MAX_NUM_OF_11JCHANNELS 20 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
+#define MAX_LEN_OF_SSID 32
+#define CIPHER_TEXT_LEN 128
+#define HASH_TABLE_SIZE 256
+#define MAX_VIE_LEN 1024 // New for WPA cipher suite variable IE sizes.
+#define MAX_SUPPORT_MCS 32
+
+//============================================================
+// ASIC WCID Table definition.
+//============================================================
+#define BSSID_WCID 1 // in infra mode, always put bssid with this WCID
+#define MCAST_WCID 0x0
+#define BSS0Mcast_WCID 0x0
+#define BSS1Mcast_WCID 0xf8
+#define BSS2Mcast_WCID 0xf9
+#define BSS3Mcast_WCID 0xfa
+#define BSS4Mcast_WCID 0xfb
+#define BSS5Mcast_WCID 0xfc
+#define BSS6Mcast_WCID 0xfd
+#define BSS7Mcast_WCID 0xfe
+#define RESERVED_WCID 0xff
+
+#define MAX_NUM_OF_ACL_LIST MAX_NUMBER_OF_ACL
+
+#define MAX_LEN_OF_MAC_TABLE MAX_NUMBER_OF_MAC // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
+
+#if MAX_LEN_OF_MAC_TABLE>MAX_AVAILABLE_CLIENT_WCID
+#error MAX_LEN_OF_MAC_TABLE can not be larger than MAX_AVAILABLE_CLIENT_WCID!!!!
+#endif
+
+#define MAX_NUM_OF_WDS_LINK_PERBSSID 3
+#define MAX_NUM_OF_WDS_LINK (MAX_NUM_OF_WDS_LINK_PERBSSID*MAX_MBSSID_NUM)
+#define MAX_NUM_OF_EVENT MAX_NUMBER_OF_EVENT
+#define WDS_LINK_START_WCID (MAX_LEN_OF_MAC_TABLE-1)
+
+#define NUM_OF_TID 8
+#define MAX_AID_BA 4
+#define MAX_LEN_OF_BA_REC_TABLE ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)// (NUM_OF_TID*MAX_AID_BA + 32) //Block ACK recipient
+#define MAX_LEN_OF_BA_ORI_TABLE ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)// (NUM_OF_TID*MAX_AID_BA + 32) // Block ACK originator
+#define MAX_LEN_OF_BSS_TABLE 64
+#define MAX_REORDERING_MPDU_NUM 512
+
+// key related definitions
+#define SHARE_KEY_NUM 4
+#define MAX_LEN_OF_SHARE_KEY 16 // byte count
+#define MAX_LEN_OF_PEER_KEY 16 // byte count
+#define PAIRWISE_KEY_NUM 64 // in MAC ASIC pairwise key table
+#define GROUP_KEY_NUM 4
+#define PMK_LEN 32
+#define WDS_PAIRWISE_KEY_OFFSET 60 // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
+#define PMKID_NO 4 // Number of PMKID saved supported
+#define MAX_LEN_OF_MLME_BUFFER 2048
+
+// power status related definitions
+#define PWR_ACTIVE 0
+#define PWR_SAVE 1
+#define PWR_MMPS 2 //MIMO power save
+//#define PWR_UNKNOWN 2
+
+// Auth and Assoc mode related definitions
+#define AUTH_MODE_OPEN 0x00
+#define AUTH_MODE_KEY 0x01
+//#define AUTH_MODE_AUTO_SWITCH 0x03
+//#define AUTH_MODE_DEAUTH 0x04
+//#define AUTH_MODE_UPLAYER 0x05 // reserved for 802.11i use
+
+// BSS Type definitions
+#define BSS_ADHOC 0 // = Ndis802_11IBSS
+#define BSS_INFRA 1 // = Ndis802_11Infrastructure
+#define BSS_ANY 2 // = Ndis802_11AutoUnknown
+#define BSS_MONITOR 3 // = Ndis802_11Monitor
+
+
+// Reason code definitions
+#define REASON_RESERVED 0
+#define REASON_UNSPECIFY 1
+#define REASON_NO_LONGER_VALID 2
+#define REASON_DEAUTH_STA_LEAVING 3
+#define REASON_DISASSOC_INACTIVE 4
+#define REASON_DISASSPC_AP_UNABLE 5
+#define REASON_CLS2ERR 6
+#define REASON_CLS3ERR 7
+#define REASON_DISASSOC_STA_LEAVING 8
+#define REASON_STA_REQ_ASSOC_NOT_AUTH 9
+#define REASON_INVALID_IE 13
+#define REASON_MIC_FAILURE 14
+#define REASON_4_WAY_TIMEOUT 15
+#define REASON_GROUP_KEY_HS_TIMEOUT 16
+#define REASON_IE_DIFFERENT 17
+#define REASON_MCIPHER_NOT_VALID 18
+#define REASON_UCIPHER_NOT_VALID 19
+#define REASON_AKMP_NOT_VALID 20
+#define REASON_UNSUPPORT_RSNE_VER 21
+#define REASON_INVALID_RSNE_CAP 22
+#define REASON_8021X_AUTH_FAIL 23
+#define REASON_CIPHER_SUITE_REJECTED 24
+#define REASON_DECLINED 37
+
+#define REASON_QOS_UNSPECIFY 32
+#define REASON_QOS_LACK_BANDWIDTH 33
+#define REASON_POOR_CHANNEL_CONDITION 34
+#define REASON_QOS_OUTSIDE_TXOP_LIMITION 35
+#define REASON_QOS_QSTA_LEAVING_QBSS 36
+#define REASON_QOS_UNWANTED_MECHANISM 37
+#define REASON_QOS_MECH_SETUP_REQUIRED 38
+#define REASON_QOS_REQUEST_TIMEOUT 39
+#define REASON_QOS_CIPHER_NOT_SUPPORT 45
+
+// Status code definitions
+#define MLME_SUCCESS 0
+#define MLME_UNSPECIFY_FAIL 1
+#define MLME_CANNOT_SUPPORT_CAP 10
+#define MLME_REASSOC_DENY_ASSOC_EXIST 11
+#define MLME_ASSOC_DENY_OUT_SCOPE 12
+#define MLME_ALG_NOT_SUPPORT 13
+#define MLME_SEQ_NR_OUT_OF_SEQUENCE 14
+#define MLME_REJ_CHALLENGE_FAILURE 15
+#define MLME_REJ_TIMEOUT 16
+#define MLME_ASSOC_REJ_UNABLE_HANDLE_STA 17
+#define MLME_ASSOC_REJ_DATA_RATE 18
+
+#define MLME_ASSOC_REJ_NO_EXT_RATE 22
+#define MLME_ASSOC_REJ_NO_EXT_RATE_PBCC 23
+#define MLME_ASSOC_REJ_NO_CCK_OFDM 24
+
+#define MLME_QOS_UNSPECIFY 32
+#define MLME_REQUEST_DECLINED 37
+#define MLME_REQUEST_WITH_INVALID_PARAM 38
+#define MLME_DLS_NOT_ALLOW_IN_QBSS 48
+#define MLME_DEST_STA_NOT_IN_QBSS 49
+#define MLME_DEST_STA_IS_NOT_A_QSTA 50
+
+#define MLME_INVALID_FORMAT 0x51
+#define MLME_FAIL_NO_RESOURCE 0x52
+#define MLME_STATE_MACHINE_REJECT 0x53
+#define MLME_MAC_TABLE_FAIL 0x54
+
+// IE code
+#define IE_SSID 0
+#define IE_SUPP_RATES 1
+#define IE_FH_PARM 2
+#define IE_DS_PARM 3
+#define IE_CF_PARM 4
+#define IE_TIM 5
+#define IE_IBSS_PARM 6
+#define IE_COUNTRY 7 // 802.11d
+#define IE_802_11D_REQUEST 10 // 802.11d
+#define IE_QBSS_LOAD 11 // 802.11e d9
+#define IE_EDCA_PARAMETER 12 // 802.11e d9
+#define IE_TSPEC 13 // 802.11e d9
+#define IE_TCLAS 14 // 802.11e d9
+#define IE_SCHEDULE 15 // 802.11e d9
+#define IE_CHALLENGE_TEXT 16
+#define IE_POWER_CONSTRAINT 32 // 802.11h d3.3
+#define IE_POWER_CAPABILITY 33 // 802.11h d3.3
+#define IE_TPC_REQUEST 34 // 802.11h d3.3
+#define IE_TPC_REPORT 35 // 802.11h d3.3
+#define IE_SUPP_CHANNELS 36 // 802.11h d3.3
+#define IE_CHANNEL_SWITCH_ANNOUNCEMENT 37 // 802.11h d3.3
+#define IE_MEASUREMENT_REQUEST 38 // 802.11h d3.3
+#define IE_MEASUREMENT_REPORT 39 // 802.11h d3.3
+#define IE_QUIET 40 // 802.11h d3.3
+#define IE_IBSS_DFS 41 // 802.11h d3.3
+#define IE_ERP 42 // 802.11g
+#define IE_TS_DELAY 43 // 802.11e d9
+#define IE_TCLAS_PROCESSING 44 // 802.11e d9
+#define IE_QOS_CAPABILITY 46 // 802.11e d6
+#define IE_HT_CAP 45 // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
+#define IE_AP_CHANNEL_REPORT 51 // 802.11k d6
+#define IE_HT_CAP2 52 // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
+#define IE_RSN 48 // 802.11i d3.0
+#define IE_WPA2 48 // WPA2
+#define IE_EXT_SUPP_RATES 50 // 802.11g
+#define IE_SUPP_REG_CLASS 59 // 802.11y. Supported regulatory classes.
+#define IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT 60 // 802.11n
+#define IE_ADD_HT 61 // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
+#define IE_ADD_HT2 53 // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
+
+
+// For 802.11n D3.03
+//#define IE_NEW_EXT_CHA_OFFSET 62 // 802.11n d1. New extension channel offset elemet
+#define IE_SECONDARY_CH_OFFSET 62 // 802.11n D3.03 Secondary Channel Offset element
+#define IE_WAPI 68 // WAPI information element
+#define IE_2040_BSS_COEXIST 72 // 802.11n D3.0.3
+#define IE_2040_BSS_INTOLERANT_REPORT 73 // 802.11n D3.03
+#define IE_OVERLAPBSS_SCAN_PARM 74 // 802.11n D3.03
+#define IE_EXT_CAPABILITY 127 // 802.11n D3.03
+
+
+#define IE_WPA 221 // WPA
+#define IE_VENDOR_SPECIFIC 221 // Wifi WMM (WME)
+
+#define OUI_BROADCOM_HT 51 //
+#define OUI_BROADCOM_HTADD 52 //
+#define OUI_PREN_HT_CAP 51 //
+#define OUI_PREN_ADD_HT 52 //
+
+// CCX information
+#define IE_AIRONET_CKIP 133 // CCX1.0 ID 85H for CKIP
+#define IE_AP_TX_POWER 150 // CCX 2.0 for AP transmit power
+#define IE_MEASUREMENT_CAPABILITY 221 // CCX 2.0
+#define IE_CCX_V2 221
+#define IE_AIRONET_IPADDRESS 149 // CCX ID 95H for IP Address
+#define IE_AIRONET_CCKMREASSOC 156 // CCX ID 9CH for CCKM Reassociation Request element
+#define CKIP_NEGOTIATION_LENGTH 30
+#define AIRONET_IPADDRESS_LENGTH 10
+#define AIRONET_CCKMREASSOC_LENGTH 24
+
+// ========================================================
+// MLME state machine definition
+// ========================================================
+
+// STA MLME state mahcines
+#define ASSOC_STATE_MACHINE 1
+#define AUTH_STATE_MACHINE 2
+#define AUTH_RSP_STATE_MACHINE 3
+#define SYNC_STATE_MACHINE 4
+#define MLME_CNTL_STATE_MACHINE 5
+#define WPA_PSK_STATE_MACHINE 6
+#define LEAP_STATE_MACHINE 7
+#define AIRONET_STATE_MACHINE 8
+#define ACTION_STATE_MACHINE 9
+
+// AP MLME state machines
+#define AP_ASSOC_STATE_MACHINE 11
+#define AP_AUTH_STATE_MACHINE 12
+#define AP_AUTH_RSP_STATE_MACHINE 13
+#define AP_SYNC_STATE_MACHINE 14
+#define AP_CNTL_STATE_MACHINE 15
+#define AP_WPA_STATE_MACHINE 16
+
+#define WSC_STATE_MACHINE 17
+#define WSC_UPNP_STATE_MACHINE 18
+
+
+
+#ifdef QOS_DLS_SUPPORT
+#define DLS_STATE_MACHINE 26
+#endif // QOS_DLS_SUPPORT //
+
+//
+// STA's CONTROL/CONNECT state machine: states, events, total function #
+//
+#define CNTL_IDLE 0
+#define CNTL_WAIT_DISASSOC 1
+#define CNTL_WAIT_JOIN 2
+#define CNTL_WAIT_REASSOC 3
+#define CNTL_WAIT_START 4
+#define CNTL_WAIT_AUTH 5
+#define CNTL_WAIT_ASSOC 6
+#define CNTL_WAIT_AUTH2 7
+#define CNTL_WAIT_OID_LIST_SCAN 8
+#define CNTL_WAIT_OID_DISASSOC 9
+#ifdef RT2870
+#define CNTL_WAIT_SCAN_FOR_CONNECT 10
+#endif // RT2870 //
+
+#define MT2_ASSOC_CONF 34
+#define MT2_AUTH_CONF 35
+#define MT2_DEAUTH_CONF 36
+#define MT2_DISASSOC_CONF 37
+#define MT2_REASSOC_CONF 38
+#define MT2_PWR_MGMT_CONF 39
+#define MT2_JOIN_CONF 40
+#define MT2_SCAN_CONF 41
+#define MT2_START_CONF 42
+#define MT2_GET_CONF 43
+#define MT2_SET_CONF 44
+#define MT2_RESET_CONF 45
+#define MT2_MLME_ROAMING_REQ 52
+
+#define CNTL_FUNC_SIZE 1
+
+//
+// STA's ASSOC state machine: states, events, total function #
+//
+#define ASSOC_IDLE 0
+#define ASSOC_WAIT_RSP 1
+#define REASSOC_WAIT_RSP 2
+#define DISASSOC_WAIT_RSP 3
+#define MAX_ASSOC_STATE 4
+
+#define ASSOC_MACHINE_BASE 0
+#define MT2_MLME_ASSOC_REQ 0
+#define MT2_MLME_REASSOC_REQ 1
+#define MT2_MLME_DISASSOC_REQ 2
+#define MT2_PEER_DISASSOC_REQ 3
+#define MT2_PEER_ASSOC_REQ 4
+#define MT2_PEER_ASSOC_RSP 5
+#define MT2_PEER_REASSOC_REQ 6
+#define MT2_PEER_REASSOC_RSP 7
+#define MT2_DISASSOC_TIMEOUT 8
+#define MT2_ASSOC_TIMEOUT 9
+#define MT2_REASSOC_TIMEOUT 10
+#define MAX_ASSOC_MSG 11
+
+#define ASSOC_FUNC_SIZE (MAX_ASSOC_STATE * MAX_ASSOC_MSG)
+
+//
+// ACT state machine: states, events, total function #
+//
+#define ACT_IDLE 0
+#define MAX_ACT_STATE 1
+
+#define ACT_MACHINE_BASE 0
+
+//Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please don'es modify it by your self.
+//Category
+#define MT2_PEER_SPECTRUM_CATE 0
+#define MT2_PEER_QOS_CATE 1
+#define MT2_PEER_DLS_CATE 2
+#define MT2_PEER_BA_CATE 3
+#define MT2_PEER_PUBLIC_CATE 4
+#define MT2_PEER_RM_CATE 5
+#define MT2_PEER_HT_CATE 7 // 7.4.7
+#define MAX_PEER_CATE_MSG 7
+#define MT2_MLME_ADD_BA_CATE 8
+#define MT2_MLME_ORI_DELBA_CATE 9
+#define MT2_MLME_REC_DELBA_CATE 10
+#define MT2_MLME_QOS_CATE 11
+#define MT2_MLME_DLS_CATE 12
+#define MT2_ACT_INVALID 13
+#define MAX_ACT_MSG 14
+
+//Category field
+#define CATEGORY_SPECTRUM 0
+#define CATEGORY_QOS 1
+#define CATEGORY_DLS 2
+#define CATEGORY_BA 3
+#define CATEGORY_PUBLIC 4
+#define CATEGORY_RM 5
+#define CATEGORY_HT 7
+
+
+// DLS Action frame definition
+#define ACTION_DLS_REQUEST 0
+#define ACTION_DLS_RESPONSE 1
+#define ACTION_DLS_TEARDOWN 2
+
+//Spectrum Action field value 802.11h 7.4.1
+#define SPEC_MRQ 0 // Request
+#define SPEC_MRP 1 //Report
+#define SPEC_TPCRQ 2
+#define SPEC_TPCRP 3
+#define SPEC_CHANNEL_SWITCH 4
+
+
+//BA Action field value
+#define ADDBA_REQ 0
+#define ADDBA_RESP 1
+#define DELBA 2
+
+//Public's Action field value in Public Category. Some in 802.11y and some in 11n
+#define ACTION_BSS_2040_COEXIST 0 // 11n
+#define ACTION_DSE_ENABLEMENT 1 // 11y D9.0
+#define ACTION_DSE_DEENABLEMENT 2 // 11y D9.0
+#define ACTION_DSE_REG_LOCATION_ANNOUNCE 3 // 11y D9.0
+#define ACTION_EXT_CH_SWITCH_ANNOUNCE 4 // 11y D9.0
+#define ACTION_DSE_MEASUREMENT_REQ 5 // 11y D9.0
+#define ACTION_DSE_MEASUREMENT_REPORT 6 // 11y D9.0
+#define ACTION_MEASUREMENT_PILOT_ACTION 7 // 11y D9.0
+#define ACTION_DSE_POWER_CONSTRAINT 8 // 11y D9.0
+
+
+//HT Action field value
+#define NOTIFY_BW_ACTION 0
+#define SMPS_ACTION 1
+#define PSMP_ACTION 2
+#define SETPCO_ACTION 3
+#define MIMO_CHA_MEASURE_ACTION 4
+#define MIMO_N_BEACONFORM 5
+#define MIMO_BEACONFORM 6
+#define ANTENNA_SELECT 7
+#define HT_INFO_EXCHANGE 8
+
+#define ACT_FUNC_SIZE (MAX_ACT_STATE * MAX_ACT_MSG)
+//
+// STA's AUTHENTICATION state machine: states, evvents, total function #
+//
+#define AUTH_REQ_IDLE 0
+#define AUTH_WAIT_SEQ2 1
+#define AUTH_WAIT_SEQ4 2
+#define MAX_AUTH_STATE 3
+
+#define AUTH_MACHINE_BASE 0
+#define MT2_MLME_AUTH_REQ 0
+#define MT2_PEER_AUTH_EVEN 1
+#define MT2_AUTH_TIMEOUT 2
+#define MAX_AUTH_MSG 3
+
+#define AUTH_FUNC_SIZE (MAX_AUTH_STATE * MAX_AUTH_MSG)
+
+//
+// STA's AUTH_RSP state machine: states, events, total function #
+//
+#define AUTH_RSP_IDLE 0
+#define AUTH_RSP_WAIT_CHAL 1
+#define MAX_AUTH_RSP_STATE 2
+
+#define AUTH_RSP_MACHINE_BASE 0
+#define MT2_AUTH_CHALLENGE_TIMEOUT 0
+#define MT2_PEER_AUTH_ODD 1
+#define MT2_PEER_DEAUTH 2
+#define MAX_AUTH_RSP_MSG 3
+
+#define AUTH_RSP_FUNC_SIZE (MAX_AUTH_RSP_STATE * MAX_AUTH_RSP_MSG)
+
+//
+// STA's SYNC state machine: states, events, total function #
+//
+#define SYNC_IDLE 0 // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
+#define JOIN_WAIT_BEACON 1
+#define SCAN_LISTEN 2
+#define MAX_SYNC_STATE 3
+
+#define SYNC_MACHINE_BASE 0
+#define MT2_MLME_SCAN_REQ 0
+#define MT2_MLME_JOIN_REQ 1
+#define MT2_MLME_START_REQ 2
+#define MT2_PEER_BEACON 3
+#define MT2_PEER_PROBE_RSP 4
+#define MT2_PEER_ATIM 5
+#define MT2_SCAN_TIMEOUT 6
+#define MT2_BEACON_TIMEOUT 7
+#define MT2_ATIM_TIMEOUT 8
+#define MT2_PEER_PROBE_REQ 9
+#define MAX_SYNC_MSG 10
+
+#define SYNC_FUNC_SIZE (MAX_SYNC_STATE * MAX_SYNC_MSG)
+
+//Messages for the DLS state machine
+#define DLS_IDLE 0
+#define MAX_DLS_STATE 1
+
+#define DLS_MACHINE_BASE 0
+#define MT2_MLME_DLS_REQ 0
+#define MT2_PEER_DLS_REQ 1
+#define MT2_PEER_DLS_RSP 2
+#define MT2_MLME_DLS_TEAR_DOWN 3
+#define MT2_PEER_DLS_TEAR_DOWN 4
+#define MAX_DLS_MSG 5
+
+#define DLS_FUNC_SIZE (MAX_DLS_STATE * MAX_DLS_MSG)
+
+//
+// STA's WPA-PSK State machine: states, events, total function #
+//
+#define WPA_PSK_IDLE 0
+#define MAX_WPA_PSK_STATE 1
+
+#define WPA_MACHINE_BASE 0
+#define MT2_EAPPacket 0
+#define MT2_EAPOLStart 1
+#define MT2_EAPOLLogoff 2
+#define MT2_EAPOLKey 3
+#define MT2_EAPOLASFAlert 4
+#define MAX_WPA_PSK_MSG 5
+
+#define WPA_PSK_FUNC_SIZE (MAX_WPA_PSK_STATE * MAX_WPA_PSK_MSG)
+
+//
+// STA's CISCO-AIRONET State machine: states, events, total function #
+//
+#define AIRONET_IDLE 0
+#define AIRONET_SCANNING 1
+#define MAX_AIRONET_STATE 2
+
+#define AIRONET_MACHINE_BASE 0
+#define MT2_AIRONET_MSG 0
+#define MT2_AIRONET_SCAN_REQ 1
+#define MT2_AIRONET_SCAN_DONE 2
+#define MAX_AIRONET_MSG 3
+
+#define AIRONET_FUNC_SIZE (MAX_AIRONET_STATE * MAX_AIRONET_MSG)
+
+//
+// WSC State machine: states, events, total function #
+//
+
+//
+// AP's CONTROL/CONNECT state machine: states, events, total function #
+//
+#define AP_CNTL_FUNC_SIZE 1
+
+//
+// AP's ASSOC state machine: states, events, total function #
+//
+#define AP_ASSOC_IDLE 0
+#define AP_MAX_ASSOC_STATE 1
+
+#define AP_ASSOC_MACHINE_BASE 0
+#define APMT2_MLME_DISASSOC_REQ 0
+#define APMT2_PEER_DISASSOC_REQ 1
+#define APMT2_PEER_ASSOC_REQ 2
+#define APMT2_PEER_REASSOC_REQ 3
+#define APMT2_CLS3ERR 4
+#define AP_MAX_ASSOC_MSG 5
+
+#define AP_ASSOC_FUNC_SIZE (AP_MAX_ASSOC_STATE * AP_MAX_ASSOC_MSG)
+
+//
+// AP's AUTHENTICATION state machine: states, events, total function #
+//
+#define AP_AUTH_REQ_IDLE 0
+#define AP_MAX_AUTH_STATE 1
+
+#define AP_AUTH_MACHINE_BASE 0
+#define APMT2_MLME_DEAUTH_REQ 0
+#define APMT2_CLS2ERR 1
+#define AP_MAX_AUTH_MSG 2
+
+#define AP_AUTH_FUNC_SIZE (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG)
+
+//
+// AP's AUTH-RSP state machine: states, events, total function #
+//
+#define AP_AUTH_RSP_IDLE 0
+#define AP_MAX_AUTH_RSP_STATE 1
+
+#define AP_AUTH_RSP_MACHINE_BASE 0
+#define APMT2_AUTH_CHALLENGE_TIMEOUT 0
+#define APMT2_PEER_AUTH_ODD 1
+#define APMT2_PEER_DEAUTH 2
+#define AP_MAX_AUTH_RSP_MSG 3
+
+#define AP_AUTH_RSP_FUNC_SIZE (AP_MAX_AUTH_RSP_STATE * AP_MAX_AUTH_RSP_MSG)
+
+//
+// AP's SYNC state machine: states, events, total function #
+//
+#define AP_SYNC_IDLE 0
+#define AP_SCAN_LISTEN 1
+#define AP_MAX_SYNC_STATE 2
+
+#define AP_SYNC_MACHINE_BASE 0
+#define APMT2_PEER_PROBE_REQ 0
+#define APMT2_PEER_BEACON 1
+#define APMT2_MLME_SCAN_REQ 2
+#define APMT2_PEER_PROBE_RSP 3
+#define APMT2_SCAN_TIMEOUT 4
+#define APMT2_MLME_SCAN_CNCL 5
+#define AP_MAX_SYNC_MSG 6
+
+#define AP_SYNC_FUNC_SIZE (AP_MAX_SYNC_STATE * AP_MAX_SYNC_MSG)
+
+//
+// AP's WPA state machine: states, events, total function #
+//
+#define AP_WPA_PTK 0
+#define AP_MAX_WPA_PTK_STATE 1
+
+#define AP_WPA_MACHINE_BASE 0
+#define APMT2_EAPPacket 0
+#define APMT2_EAPOLStart 1
+#define APMT2_EAPOLLogoff 2
+#define APMT2_EAPOLKey 3
+#define APMT2_EAPOLASFAlert 4
+#define AP_MAX_WPA_MSG 5
+
+#define AP_WPA_FUNC_SIZE (AP_MAX_WPA_PTK_STATE * AP_MAX_WPA_MSG)
+
+
+
+// =============================================================================
+
+// value domain of 802.11 header FC.Tyte, which is b3..b2 of the 1st-byte of MAC header
+#define BTYPE_MGMT 0
+#define BTYPE_CNTL 1
+#define BTYPE_DATA 2
+
+// value domain of 802.11 MGMT frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
+#define SUBTYPE_ASSOC_REQ 0
+#define SUBTYPE_ASSOC_RSP 1
+#define SUBTYPE_REASSOC_REQ 2
+#define SUBTYPE_REASSOC_RSP 3
+#define SUBTYPE_PROBE_REQ 4
+#define SUBTYPE_PROBE_RSP 5
+#define SUBTYPE_BEACON 8
+#define SUBTYPE_ATIM 9
+#define SUBTYPE_DISASSOC 10
+#define SUBTYPE_AUTH 11
+#define SUBTYPE_DEAUTH 12
+#define SUBTYPE_ACTION 13
+#define SUBTYPE_ACTION_NO_ACK 14
+
+// value domain of 802.11 CNTL frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
+#define SUBTYPE_WRAPPER 7
+#define SUBTYPE_BLOCK_ACK_REQ 8
+#define SUBTYPE_BLOCK_ACK 9
+#define SUBTYPE_PS_POLL 10
+#define SUBTYPE_RTS 11
+#define SUBTYPE_CTS 12
+#define SUBTYPE_ACK 13
+#define SUBTYPE_CFEND 14
+#define SUBTYPE_CFEND_CFACK 15
+
+// value domain of 802.11 DATA frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
+#define SUBTYPE_DATA 0
+#define SUBTYPE_DATA_CFACK 1
+#define SUBTYPE_DATA_CFPOLL 2
+#define SUBTYPE_DATA_CFACK_CFPOLL 3
+#define SUBTYPE_NULL_FUNC 4
+#define SUBTYPE_CFACK 5
+#define SUBTYPE_CFPOLL 6
+#define SUBTYPE_CFACK_CFPOLL 7
+#define SUBTYPE_QDATA 8
+#define SUBTYPE_QDATA_CFACK 9
+#define SUBTYPE_QDATA_CFPOLL 10
+#define SUBTYPE_QDATA_CFACK_CFPOLL 11
+#define SUBTYPE_QOS_NULL 12
+#define SUBTYPE_QOS_CFACK 13
+#define SUBTYPE_QOS_CFPOLL 14
+#define SUBTYPE_QOS_CFACK_CFPOLL 15
+
+// ACK policy of QOS Control field bit 6:5
+#define NORMAL_ACK 0x00 // b6:5 = 00
+#define NO_ACK 0x20 // b6:5 = 01
+#define NO_EXPLICIT_ACK 0x40 // b6:5 = 10
+#define BLOCK_ACK 0x60 // b6:5 = 11
+
+//
+// rtmp_data.c use these definition
+//
+#define LENGTH_802_11 24
+#define LENGTH_802_11_AND_H 30
+#define LENGTH_802_11_CRC_H 34
+#define LENGTH_802_11_CRC 28
+#define LENGTH_802_11_WITH_ADDR4 30
+#define LENGTH_802_3 14
+#define LENGTH_802_3_TYPE 2
+#define LENGTH_802_1_H 8
+#define LENGTH_EAPOL_H 4
+#define LENGTH_WMMQOS_H 2
+#define LENGTH_CRC 4
+#define MAX_SEQ_NUMBER 0x0fff
+#define LENGTH_802_3_NO_TYPE 12
+#define LENGTH_802_1Q 4 /* VLAN related */
+
+// STA_CSR4.field.TxResult
+#define TX_RESULT_SUCCESS 0
+#define TX_RESULT_ZERO_LENGTH 1
+#define TX_RESULT_UNDER_RUN 2
+#define TX_RESULT_OHY_ERROR 4
+#define TX_RESULT_RETRY_FAIL 6
+
+// All PHY rate summary in TXD
+// Preamble MODE in TxD
+#define MODE_CCK 0
+#define MODE_OFDM 1
+#ifdef DOT11_N_SUPPORT
+#define MODE_HTMIX 2
+#define MODE_HTGREENFIELD 3
+#endif // DOT11_N_SUPPORT //
+// MCS for CCK. BW.SGI.STBC are reserved
+#define MCS_LONGP_RATE_1 0 // long preamble CCK 1Mbps
+#define MCS_LONGP_RATE_2 1 // long preamble CCK 1Mbps
+#define MCS_LONGP_RATE_5_5 2
+#define MCS_LONGP_RATE_11 3
+#define MCS_SHORTP_RATE_1 4 // long preamble CCK 1Mbps. short is forbidden in 1Mbps
+#define MCS_SHORTP_RATE_2 5 // short preamble CCK 2Mbps
+#define MCS_SHORTP_RATE_5_5 6
+#define MCS_SHORTP_RATE_11 7
+// To send duplicate legacy OFDM. set BW=BW_40. SGI.STBC are reserved
+#define MCS_RATE_6 0 // legacy OFDM
+#define MCS_RATE_9 1 // OFDM
+#define MCS_RATE_12 2 // OFDM
+#define MCS_RATE_18 3 // OFDM
+#define MCS_RATE_24 4 // OFDM
+#define MCS_RATE_36 5 // OFDM
+#define MCS_RATE_48 6 // OFDM
+#define MCS_RATE_54 7 // OFDM
+// HT
+#define MCS_0 0 // 1S
+#define MCS_1 1
+#define MCS_2 2
+#define MCS_3 3
+#define MCS_4 4
+#define MCS_5 5
+#define MCS_6 6
+#define MCS_7 7
+#define MCS_8 8 // 2S
+#define MCS_9 9
+#define MCS_10 10
+#define MCS_11 11
+#define MCS_12 12
+#define MCS_13 13
+#define MCS_14 14
+#define MCS_15 15
+#define MCS_16 16 // 3*3
+#define MCS_17 17
+#define MCS_18 18
+#define MCS_19 19
+#define MCS_20 20
+#define MCS_21 21
+#define MCS_22 22
+#define MCS_23 23
+#define MCS_32 32
+#define MCS_AUTO 33
+
+#ifdef DOT11_N_SUPPORT
+// OID_HTPHYMODE
+// MODE
+#define HTMODE_MM 0
+#define HTMODE_GF 1
+#endif // DOT11_N_SUPPORT //
+
+// Fixed Tx MODE - HT, CCK or OFDM
+#define FIXED_TXMODE_HT 0
+#define FIXED_TXMODE_CCK 1
+#define FIXED_TXMODE_OFDM 2
+// BW
+#define BW_20 BAND_WIDTH_20
+#define BW_40 BAND_WIDTH_40
+#define BW_BOTH BAND_WIDTH_BOTH
+#define BW_10 BAND_WIDTH_10 // 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
+
+#ifdef DOT11_N_SUPPORT
+// SHORTGI
+#define GI_400 GAP_INTERVAL_400 // only support in HT mode
+#define GI_BOTH GAP_INTERVAL_BOTH
+#endif // DOT11_N_SUPPORT //
+#define GI_800 GAP_INTERVAL_800
+// STBC
+#define STBC_NONE 0
+#ifdef DOT11_N_SUPPORT
+#define STBC_USE 1 // limited use in rt2860b phy
+#define RXSTBC_ONE 1 // rx support of one spatial stream
+#define RXSTBC_TWO 2 // rx support of 1 and 2 spatial stream
+#define RXSTBC_THR 3 // rx support of 1~3 spatial stream
+// MCS FEEDBACK
+#define MCSFBK_NONE 0 // not support mcs feedback /
+#define MCSFBK_RSV 1 // reserved
+#define MCSFBK_UNSOLICIT 2 // only support unsolict mcs feedback
+#define MCSFBK_MRQ 3 // response to both MRQ and unsolict mcs feedback
+
+// MIMO power safe
+#define MMPS_STATIC 0
+#define MMPS_DYNAMIC 1
+#define MMPS_RSV 2
+#define MMPS_ENABLE 3
+
+
+// A-MSDU size
+#define AMSDU_0 0
+#define AMSDU_1 1
+
+#endif // DOT11_N_SUPPORT //
+
+// MCS use 7 bits
+#define TXRATEMIMO 0x80
+#define TXRATEMCS 0x7F
+#define TXRATEOFDM 0x7F
+#define RATE_1 0
+#define RATE_2 1
+#define RATE_5_5 2
+#define RATE_11 3
+#define RATE_6 4 // OFDM
+#define RATE_9 5 // OFDM
+#define RATE_12 6 // OFDM
+#define RATE_18 7 // OFDM
+#define RATE_24 8 // OFDM
+#define RATE_36 9 // OFDM
+#define RATE_48 10 // OFDM
+#define RATE_54 11 // OFDM
+#define RATE_FIRST_OFDM_RATE RATE_6
+#define RATE_LAST_OFDM_RATE RATE_54
+#define RATE_6_5 12 // HT mix
+#define RATE_13 13 // HT mix
+#define RATE_19_5 14 // HT mix
+#define RATE_26 15 // HT mix
+#define RATE_39 16 // HT mix
+#define RATE_52 17 // HT mix
+#define RATE_58_5 18 // HT mix
+#define RATE_65 19 // HT mix
+#define RATE_78 20 // HT mix
+#define RATE_104 21 // HT mix
+#define RATE_117 22 // HT mix
+#define RATE_130 23 // HT mix
+//#define RATE_AUTO_SWITCH 255 // for StaCfg.FixedTxRate only
+#define HTRATE_0 12
+#define RATE_FIRST_MM_RATE HTRATE_0
+#define RATE_FIRST_HT_RATE HTRATE_0
+#define RATE_LAST_HT_RATE HTRATE_0
+
+// pTxWI->txop
+#define IFS_HTTXOP 0 // The txop will be handles by ASIC.
+#define IFS_PIFS 1
+#define IFS_SIFS 2
+#define IFS_BACKOFF 3
+
+// pTxD->RetryMode
+#define LONG_RETRY 1
+#define SHORT_RETRY 0
+
+// Country Region definition
+#define REGION_MINIMUM_BG_BAND 0
+#define REGION_0_BG_BAND 0 // 1-11
+#define REGION_1_BG_BAND 1 // 1-13
+#define REGION_2_BG_BAND 2 // 10-11
+#define REGION_3_BG_BAND 3 // 10-13
+#define REGION_4_BG_BAND 4 // 14
+#define REGION_5_BG_BAND 5 // 1-14
+#define REGION_6_BG_BAND 6 // 3-9
+#define REGION_7_BG_BAND 7 // 5-13
+#define REGION_31_BG_BAND 31 // 5-13
+#define REGION_MAXIMUM_BG_BAND 7
+
+#define REGION_MINIMUM_A_BAND 0
+#define REGION_0_A_BAND 0 // 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165
+#define REGION_1_A_BAND 1 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
+#define REGION_2_A_BAND 2 // 36, 40, 44, 48, 52, 56, 60, 64
+#define REGION_3_A_BAND 3 // 52, 56, 60, 64, 149, 153, 157, 161
+#define REGION_4_A_BAND 4 // 149, 153, 157, 161, 165
+#define REGION_5_A_BAND 5 // 149, 153, 157, 161
+#define REGION_6_A_BAND 6 // 36, 40, 44, 48
+#define REGION_7_A_BAND 7 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165
+#define REGION_8_A_BAND 8 // 52, 56, 60, 64
+#define REGION_9_A_BAND 9 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165
+#define REGION_10_A_BAND 10 // 36, 40, 44, 48, 149, 153, 157, 161, 165
+#define REGION_11_A_BAND 11 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161
+#define REGION_MAXIMUM_A_BAND 11
+
+// pTxD->CipherAlg
+#define CIPHER_NONE 0
+#define CIPHER_WEP64 1
+#define CIPHER_WEP128 2
+#define CIPHER_TKIP 3
+#define CIPHER_AES 4
+#define CIPHER_CKIP64 5
+#define CIPHER_CKIP128 6
+#define CIPHER_TKIP_NO_MIC 7 // MIC appended by driver: not a valid value in hardware key table
+#define CIPHER_SMS4 8
+
+// value domain of pAd->RfIcType
+#define RFIC_2820 1 // 2.4G 2T3R
+#define RFIC_2850 2 // 2.4G/5G 2T3R
+#define RFIC_2720 3 // 2.4G 1T2R
+#define RFIC_2750 4 // 2.4G/5G 1T2R
+#define RFIC_3020 5 // 2.4G 1T1R
+#define RFIC_2020 6 // 2.4G B/G
+#define RFIC_3021 7 // 2.4G 1T2R
+#define RFIC_3022 8 // 2.4G 2T2R
+
+// LED Status.
+#define LED_LINK_DOWN 0
+#define LED_LINK_UP 1
+#define LED_RADIO_OFF 2
+#define LED_RADIO_ON 3
+#define LED_HALT 4
+#define LED_WPS 5
+#define LED_ON_SITE_SURVEY 6
+#define LED_POWER_UP 7
+
+// value domain of pAd->LedCntl.LedMode and E2PROM
+#define LED_MODE_DEFAULT 0
+#define LED_MODE_TWO_LED 1
+#define LED_MODE_SIGNAL_STREGTH 8 // EEPROM define =8
+
+// RC4 init value, used fro WEP & TKIP
+#define PPPINITFCS32 0xffffffff /* Initial FCS value */
+
+// value domain of pAd->StaCfg.PortSecured. 802.1X controlled port definition
+#define WPA_802_1X_PORT_SECURED 1
+#define WPA_802_1X_PORT_NOT_SECURED 2
+
+#define PAIRWISE_KEY 1
+#define GROUP_KEY 2
+
+//definition of DRS
+#define MAX_STEP_OF_TX_RATE_SWITCH 32
+
+
+// pre-allocated free NDIS PACKET/BUFFER poll for internal usage
+#define MAX_NUM_OF_FREE_NDIS_PACKET 128
+
+//Block ACK
+#define MAX_TX_REORDERBUF 64
+#define MAX_RX_REORDERBUF 64
+#define DEFAULT_TX_TIMEOUT 30
+#define DEFAULT_RX_TIMEOUT 30
+
+// definition of Recipient or Originator
+#define I_RECIPIENT TRUE
+#define I_ORIGINATOR FALSE
+
+#define DEFAULT_BBP_TX_POWER 0
+#define DEFAULT_RF_TX_POWER 5
+
+#define MAX_INI_BUFFER_SIZE 4096
+#define MAX_PARAM_BUFFER_SIZE (2048) // enough for ACL (18*64)
+ //18 : the length of Mac address acceptable format "01:02:03:04:05:06;")
+ //64 : MAX_NUM_OF_ACL_LIST
+// definition of pAd->OpMode
+#define OPMODE_STA 0
+#define OPMODE_AP 1
+//#define OPMODE_L3_BRG 2 // as AP and STA at the same time
+
+#ifdef RT_BIG_ENDIAN
+#define DIR_READ 0
+#define DIR_WRITE 1
+#define TYPE_TXD 0
+#define TYPE_RXD 1
+#define TYPE_TXINFO 0
+#define TYPE_RXINFO 1
+#define TYPE_TXWI 0
+#define TYPE_RXWI 1
+#endif
+
+// ========================= AP rtmp_def.h ===========================
+// value domain for pAd->EventTab.Log[].Event
+#define EVENT_RESET_ACCESS_POINT 0 // Log = "hh:mm:ss Restart Access Point"
+#define EVENT_ASSOCIATED 1 // Log = "hh:mm:ss STA 00:01:02:03:04:05 associated"
+#define EVENT_DISASSOCIATED 2 // Log = "hh:mm:ss STA 00:01:02:03:04:05 left this BSS"
+#define EVENT_AGED_OUT 3 // Log = "hh:mm:ss STA 00:01:02:03:04:05 was aged-out and removed from this BSS"
+#define EVENT_COUNTER_M 4
+#define EVENT_INVALID_PSK 5
+#define EVENT_MAX_EVENT_TYPE 6
+// ==== end of AP rtmp_def.h ============
+
+// definition RSSI Number
+#define RSSI_0 0
+#define RSSI_1 1
+#define RSSI_2 2
+
+// definition of radar detection
+#define RD_NORMAL_MODE 0 // Not found radar signal
+#define RD_SWITCHING_MODE 1 // Found radar signal, and doing channel switch
+#define RD_SILENCE_MODE 2 // After channel switch, need to be silence a while to ensure radar not found
+
+//Driver defined cid for mapping status and command.
+#define SLEEPCID 0x11
+#define WAKECID 0x22
+#define QUERYPOWERCID 0x33
+#define OWNERMCU 0x1
+#define OWNERCPU 0x0
+
+// MBSSID definition
+#define ENTRY_NOT_FOUND 0xFF
+
+
+/* After Linux 2.6.9,
+ * VLAN module use Private (from user) interface flags (netdevice->priv_flags).
+ * #define IFF_802_1Q_VLAN 0x1 -- 802.1Q VLAN device. in if.h
+ * ref to ip_sabotage_out() [ out->priv_flags & IFF_802_1Q_VLAN ] in br_netfilter.c
+ *
+ * For this reason, we MUST use EVEN value in priv_flags
+ */
+#define INT_MAIN 0x0100
+#define INT_MBSSID 0x0200
+#define INT_WDS 0x0300
+#define INT_APCLI 0x0400
+#define INT_MESH 0x0500
+
+// Use bitmap to allow coexist of ATE_TXFRAME and ATE_RXFRAME(i.e.,to support LoopBack mode)
+#ifdef RALINK_ATE
+#define ATE_START 0x00 // Start ATE
+#define ATE_STOP 0x80 // Stop ATE
+#define ATE_TXCONT 0x05 // Continuous Transmit
+#define ATE_TXCARR 0x09 // Transmit Carrier
+#define ATE_TXCARRSUPP 0x11 // Transmit Carrier Suppression
+#define ATE_TXFRAME 0x01 // Transmit Frames
+#define ATE_RXFRAME 0x02 // Receive Frames
+#ifdef RALINK_28xx_QA
+#define ATE_TXSTOP 0xe2 // Stop Transmition(i.e., TXCONT, TXCARR, TXCARRSUPP, and TXFRAME)
+#define ATE_RXSTOP 0xfd // Stop receiving Frames
+#define BBP22_TXFRAME 0x00 // Transmit Frames
+#define BBP22_TXCONT_OR_CARRSUPP 0x80 // Continuous Transmit or Carrier Suppression
+#define BBP22_TXCARR 0xc1 // Transmit Carrier
+#define BBP24_TXCONT 0x00 // Continuous Transmit
+#define BBP24_CARRSUPP 0x01 // Carrier Suppression
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+// WEP Key TYPE
+#define WEP_HEXADECIMAL_TYPE 0
+#define WEP_ASCII_TYPE 1
+
+
+
+// WIRELESS EVENTS definition
+/* Max number of char in custom event, refer to wireless_tools.28/wireless.20.h */
+#define IW_CUSTOM_MAX_LEN 255 /* In bytes */
+
+// For system event - start
+#define IW_SYS_EVENT_FLAG_START 0x0200
+#define IW_ASSOC_EVENT_FLAG 0x0200
+#define IW_DISASSOC_EVENT_FLAG 0x0201
+#define IW_DEAUTH_EVENT_FLAG 0x0202
+#define IW_AGEOUT_EVENT_FLAG 0x0203
+#define IW_COUNTER_MEASURES_EVENT_FLAG 0x0204
+#define IW_REPLAY_COUNTER_DIFF_EVENT_FLAG 0x0205
+#define IW_RSNIE_DIFF_EVENT_FLAG 0x0206
+#define IW_MIC_DIFF_EVENT_FLAG 0x0207
+#define IW_ICV_ERROR_EVENT_FLAG 0x0208
+#define IW_MIC_ERROR_EVENT_FLAG 0x0209
+#define IW_GROUP_HS_TIMEOUT_EVENT_FLAG 0x020A
+#define IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG 0x020B
+#define IW_RSNIE_SANITY_FAIL_EVENT_FLAG 0x020C
+#define IW_SET_KEY_DONE_WPA1_EVENT_FLAG 0x020D
+#define IW_SET_KEY_DONE_WPA2_EVENT_FLAG 0x020E
+#define IW_STA_LINKUP_EVENT_FLAG 0x020F
+#define IW_STA_LINKDOWN_EVENT_FLAG 0x0210
+#define IW_SCAN_COMPLETED_EVENT_FLAG 0x0211
+#define IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG 0x0212
+// if add new system event flag, please upadte the IW_SYS_EVENT_FLAG_END
+#define IW_SYS_EVENT_FLAG_END 0x0212
+#define IW_SYS_EVENT_TYPE_NUM (IW_SYS_EVENT_FLAG_END - IW_SYS_EVENT_FLAG_START + 1)
+// For system event - end
+
+// For spoof attack event - start
+#define IW_SPOOF_EVENT_FLAG_START 0x0300
+#define IW_CONFLICT_SSID_EVENT_FLAG 0x0300
+#define IW_SPOOF_ASSOC_RESP_EVENT_FLAG 0x0301
+#define IW_SPOOF_REASSOC_RESP_EVENT_FLAG 0x0302
+#define IW_SPOOF_PROBE_RESP_EVENT_FLAG 0x0303
+#define IW_SPOOF_BEACON_EVENT_FLAG 0x0304
+#define IW_SPOOF_DISASSOC_EVENT_FLAG 0x0305
+#define IW_SPOOF_AUTH_EVENT_FLAG 0x0306
+#define IW_SPOOF_DEAUTH_EVENT_FLAG 0x0307
+#define IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG 0x0308
+#define IW_REPLAY_ATTACK_EVENT_FLAG 0x0309
+// if add new spoof attack event flag, please upadte the IW_SPOOF_EVENT_FLAG_END
+#define IW_SPOOF_EVENT_FLAG_END 0x0309
+#define IW_SPOOF_EVENT_TYPE_NUM (IW_SPOOF_EVENT_FLAG_END - IW_SPOOF_EVENT_FLAG_START + 1)
+// For spoof attack event - end
+
+// For flooding attack event - start
+#define IW_FLOOD_EVENT_FLAG_START 0x0400
+#define IW_FLOOD_AUTH_EVENT_FLAG 0x0400
+#define IW_FLOOD_ASSOC_REQ_EVENT_FLAG 0x0401
+#define IW_FLOOD_REASSOC_REQ_EVENT_FLAG 0x0402
+#define IW_FLOOD_PROBE_REQ_EVENT_FLAG 0x0403
+#define IW_FLOOD_DISASSOC_EVENT_FLAG 0x0404
+#define IW_FLOOD_DEAUTH_EVENT_FLAG 0x0405
+#define IW_FLOOD_EAP_REQ_EVENT_FLAG 0x0406
+// if add new flooding attack event flag, please upadte the IW_FLOOD_EVENT_FLAG_END
+#define IW_FLOOD_EVENT_FLAG_END 0x0406
+#define IW_FLOOD_EVENT_TYPE_NUM (IW_FLOOD_EVENT_FLAG_END - IW_FLOOD_EVENT_FLAG_START + 1)
+// For flooding attack - end
+
+// End - WIRELESS EVENTS definition
+
+#ifdef CONFIG_STA_SUPPORT
+// definition for DLS, kathy
+#define MAX_NUM_OF_INIT_DLS_ENTRY 1
+#define MAX_NUM_OF_DLS_ENTRY MAX_NUMBER_OF_DLS_ENTRY
+
+//Block ACK , rt2860, kathy
+#define MAX_TX_REORDERBUF 64
+#define MAX_RX_REORDERBUF 64
+#define DEFAULT_TX_TIMEOUT 30
+#define DEFAULT_RX_TIMEOUT 30
+#ifndef CONFIG_AP_SUPPORT
+#define MAX_BARECI_SESSION 8
+#endif
+
+#ifndef IW_ESSID_MAX_SIZE
+/* Maximum size of the ESSID and pAd->nickname strings */
+#define IW_ESSID_MAX_SIZE 32
+#endif
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef MCAST_RATE_SPECIFIC
+#define MCAST_DISABLE 0
+#define MCAST_CCK 1
+#define MCAST_OFDM 2
+#define MCAST_HTMIX 3
+#endif // MCAST_RATE_SPECIFIC //
+
+// For AsicRadioOff/AsicRadioOn function
+#define DOT11POWERSAVE 0
+#define GUIRADIO_OFF 1
+#define RTMP_HALT 2
+#define GUI_IDLE_POWER_SAVE 3
+// --
+
+
+// definition for WpaSupport flag
+#define WPA_SUPPLICANT_DISABLE 0
+#define WPA_SUPPLICANT_ENABLE 1
+#define WPA_SUPPLICANT_ENABLE_WITH_WEB_UI 2
+
+// Endian byte swapping codes
+#define SWAP16(x) \
+ ((UINT16)( \
+ (((UINT16)(x) & (UINT16) 0x00ffU) << 8) | \
+ (((UINT16)(x) & (UINT16) 0xff00U) >> 8) ))
+
+#define SWAP32(x) \
+ ((UINT32)( \
+ (((UINT32)(x) & (UINT32) 0x000000ffUL) << 24) | \
+ (((UINT32)(x) & (UINT32) 0x0000ff00UL) << 8) | \
+ (((UINT32)(x) & (UINT32) 0x00ff0000UL) >> 8) | \
+ (((UINT32)(x) & (UINT32) 0xff000000UL) >> 24) ))
+
+#define SWAP64(x) \
+ ((UINT64)( \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x00000000000000ffULL) << 56) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x000000000000ff00ULL) << 40) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x0000000000ff0000ULL) << 24) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x00000000ff000000ULL) << 8) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x000000ff00000000ULL) >> 8) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x0000ff0000000000ULL) >> 24) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x00ff000000000000ULL) >> 40) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0xff00000000000000ULL) >> 56) ))
+
+#ifdef RT_BIG_ENDIAN
+
+#define cpu2le64(x) SWAP64((x))
+#define le2cpu64(x) SWAP64((x))
+#define cpu2le32(x) SWAP32((x))
+#define le2cpu32(x) SWAP32((x))
+#define cpu2le16(x) SWAP16((x))
+#define le2cpu16(x) SWAP16((x))
+#define cpu2be64(x) ((UINT64)(x))
+#define be2cpu64(x) ((UINT64)(x))
+#define cpu2be32(x) ((UINT32)(x))
+#define be2cpu32(x) ((UINT32)(x))
+#define cpu2be16(x) ((UINT16)(x))
+#define be2cpu16(x) ((UINT16)(x))
+
+#else // Little_Endian
+
+#define cpu2le64(x) ((UINT64)(x))
+#define le2cpu64(x) ((UINT64)(x))
+#define cpu2le32(x) ((UINT32)(x))
+#define le2cpu32(x) ((UINT32)(x))
+#define cpu2le16(x) ((UINT16)(x))
+#define le2cpu16(x) ((UINT16)(x))
+#define cpu2be64(x) SWAP64((x))
+#define be2cpu64(x) SWAP64((x))
+#define cpu2be32(x) SWAP32((x))
+#define be2cpu32(x) SWAP32((x))
+#define cpu2be16(x) SWAP16((x))
+#define be2cpu16(x) SWAP16((x))
+
+#endif // RT_BIG_ENDIAN
+
+#endif // __RTMP_DEF_H__
+
+
diff --git a/drivers/staging/rt3070/rtmp_type.h b/drivers/staging/rt3070/rtmp_type.h
new file mode 100644
index 00000000000..4e4b168b9e9
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp_type.h
@@ -0,0 +1,95 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_type.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 1-2-2004
+*/
+#ifndef __RTMP_TYPE_H__
+#define __RTMP_TYPE_H__
+
+
+#define PACKED __attribute__ ((packed))
+
+// Put platform dependent declaration here
+// For example, linux type definition
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef unsigned int UINT32;
+typedef unsigned long long UINT64;
+typedef int INT32;
+typedef long long INT64;
+
+typedef unsigned char * PUINT8;
+typedef unsigned short * PUINT16;
+typedef unsigned int * PUINT32;
+typedef unsigned long long * PUINT64;
+typedef int * PINT32;
+typedef long long * PINT64;
+
+typedef signed char CHAR;
+typedef signed short SHORT;
+typedef signed int INT;
+typedef signed long LONG;
+typedef signed long long LONGLONG;
+
+
+typedef unsigned char UCHAR;
+typedef unsigned short USHORT;
+typedef unsigned int UINT;
+typedef unsigned long ULONG;
+typedef unsigned long long ULONGLONG;
+
+typedef unsigned char BOOLEAN;
+typedef void VOID;
+
+typedef VOID * PVOID;
+typedef CHAR * PCHAR;
+typedef UCHAR * PUCHAR;
+typedef USHORT * PUSHORT;
+typedef LONG * PLONG;
+typedef ULONG * PULONG;
+typedef UINT * PUINT;
+
+typedef unsigned int NDIS_MEDIA_STATE;
+
+typedef union _LARGE_INTEGER {
+ struct {
+ UINT LowPart;
+ INT32 HighPart;
+ } u;
+ INT64 QuadPart;
+} LARGE_INTEGER;
+
+#endif // __RTMP_TYPE_H__
+
diff --git a/drivers/staging/rt3070/spectrum.h b/drivers/staging/rt3070/spectrum.h
new file mode 100644
index 00000000000..94cfa5b174f
--- /dev/null
+++ b/drivers/staging/rt3070/spectrum.h
@@ -0,0 +1,322 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#ifndef __SPECTRUM_H__
+#define __SPECTRUM_H__
+
+#include "rtmp_type.h"
+#include "spectrum_def.h"
+
+typedef struct PACKED _TPC_REPORT_INFO
+{
+ UINT8 TxPwr;
+ UINT8 LinkMargin;
+} TPC_REPORT_INFO, *PTPC_REPORT_INFO;
+
+typedef struct PACKED _CH_SW_ANN_INFO
+{
+ UINT8 ChSwMode;
+ UINT8 Channel;
+ UINT8 ChSwCnt;
+} CH_SW_ANN_INFO, *PCH_SW_ANN_INFO;
+
+typedef union PACKED _MEASURE_REQ_MODE
+{
+#ifdef RT_BIG_ENDIAN
+ struct PACKED
+ {
+ UINT8 Rev1:4;
+ UINT8 Report:1;
+ UINT8 Request:1;
+ UINT8 Enable:1;
+ UINT8 Rev0:1;
+ } field;
+#else
+ struct PACKED
+ {
+ UINT8 Rev0:1;
+ UINT8 Enable:1;
+ UINT8 Request:1;
+ UINT8 Report:1;
+ UINT8 Rev1:4;
+ } field;
+#endif // RT_BIG_ENDIAN //
+ UINT8 word;
+} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE;
+
+typedef struct PACKED _MEASURE_REQ
+{
+ UINT8 ChNum;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+} MEASURE_REQ, *PMEASURE_REQ;
+
+typedef struct PACKED _MEASURE_REQ_INFO
+{
+ UINT8 Token;
+ MEASURE_REQ_MODE ReqMode;
+ UINT8 ReqType;
+ MEASURE_REQ MeasureReq;
+} MEASURE_REQ_INFO, *PMEASURE_REQ_INFO;
+
+typedef union PACKED _MEASURE_BASIC_REPORT_MAP
+{
+#ifdef RT_BIG_ENDIAN
+ struct PACKED
+ {
+ UINT8 Rev:3;
+ UINT8 Unmeasure:1;
+ UINT8 Radar:1;
+ UINT8 UnidentifiedSignal:1;
+ UINT8 OfdmPreamble:1;
+ UINT8 BSS:1;
+ } field;
+#else
+ struct PACKED
+ {
+ UINT8 BSS:1;
+ UINT8 OfdmPreamble:1;
+ UINT8 UnidentifiedSignal:1;
+ UINT8 Radar:1;
+ UINT8 Unmeasure:1;
+ UINT8 Rev:3;
+ } field;
+#endif // RT_BIG_ENDIAN //
+ UINT8 word;
+} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP;
+
+typedef struct PACKED _MEASURE_BASIC_REPORT
+{
+ UINT8 ChNum;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+ MEASURE_BASIC_REPORT_MAP Map;
+} MEASURE_BASIC_REPORT, *PMEASURE_BASIC_REPORT;
+
+typedef struct PACKED _MEASURE_CCA_REPORT
+{
+ UINT8 ChNum;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+ UINT8 CCA_Busy_Fraction;
+} MEASURE_CCA_REPORT, *PMEASURE_CCA_REPORT;
+
+typedef struct PACKED _MEASURE_RPI_REPORT
+{
+ UINT8 ChNum;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+ UINT8 RPI_Density[8];
+} MEASURE_RPI_REPORT, *PMEASURE_RPI_REPORT;
+
+typedef union PACKED _MEASURE_REPORT_MODE
+{
+ struct PACKED
+ {
+#ifdef RT_BIG_ENDIAN
+ UINT8 Rev:5;
+ UINT8 Refused:1;
+ UINT8 Incapable:1;
+ UINT8 Late:1;
+#else
+ UINT8 Late:1;
+ UINT8 Incapable:1;
+ UINT8 Refused:1;
+ UINT8 Rev:5;
+#endif // RT_BIG_ENDIAN //
+ } field;
+ UINT8 word;
+} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE;
+
+typedef struct PACKED _MEASURE_REPORT_INFO
+{
+ UINT8 Token;
+ MEASURE_REPORT_MODE ReportMode;
+ UINT8 ReportType;
+ UINT8 Octect[0];
+} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO;
+
+typedef struct PACKED _QUIET_INFO
+{
+ UINT8 QuietCnt;
+ UINT8 QuietPeriod;
+ UINT8 QuietDuration;
+ UINT8 QuietOffset;
+} QUIET_INFO, *PQUIET_INFO;
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Measurement request action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueMeasurementReq(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 MeasureToken,
+ IN UINT8 MeasureReqMode,
+ IN UINT8 MeasureReqType,
+ IN UINT8 MeasureCh,
+ IN UINT16 MeasureDuration);
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Measurement report action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueMeasurementRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 DialogToken,
+ IN UINT8 MeasureToken,
+ IN UINT8 MeasureReqMode,
+ IN UINT8 MeasureReqType,
+ IN UINT8 ReportInfoLen,
+ IN PUINT8 pReportInfo);
+
+/*
+ ==========================================================================
+ Description:
+ Prepare TPC Request action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueTPCReq(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UCHAR DialogToken);
+
+/*
+ ==========================================================================
+ Description:
+ Prepare TPC Report action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueTPCRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 DialogToken,
+ IN UINT8 TxPwr,
+ IN UINT8 LinkMargin);
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Channel Switch Announcement action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+ 2. Channel switch announcement mode.
+ 2. a New selected channel.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueChSwAnn(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 ChSwMode,
+ IN UINT8 NewCh);
+
+/*
+ ==========================================================================
+ Description:
+ Spectrun action frames Handler such as channel switch annoucement,
+ measurement report, measurement request actions frames.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+VOID PeerSpectrumAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+/*
+ ==========================================================================
+ Description:
+
+ Parametrs:
+
+ Return : None.
+ ==========================================================================
+ */
+INT Set_MeasureReq_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_TpcReq_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+VOID MeasureReqTabInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MeasureReqTabExit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID TpcReqTabInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID TpcReqTabExit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NotifyChSwAnnToPeerAPs(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pRA,
+ IN PUCHAR pTA,
+ IN UINT8 ChSwMode,
+ IN UINT8 Channel);
+#endif // __SPECTRUM_H__ //
+
diff --git a/drivers/staging/rt3070/spectrum_def.h b/drivers/staging/rt3070/spectrum_def.h
new file mode 100644
index 00000000000..4ca4817bba0
--- /dev/null
+++ b/drivers/staging/rt3070/spectrum_def.h
@@ -0,0 +1,95 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ spectrum_def.h
+
+ Abstract:
+ Handle association related requests either from WSTA or from local MLME
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ Fonchi Wu 2008 created for 802.11h
+ */
+
+#ifndef __SPECTRUM_DEF_H__
+#define __SPECTRUM_DEF_H__
+
+#define MAX_MEASURE_REQ_TAB_SIZE 3
+#define MAX_HASH_MEASURE_REQ_TAB_SIZE MAX_MEASURE_REQ_TAB_SIZE
+
+#define MAX_TPC_REQ_TAB_SIZE 3
+#define MAX_HASH_TPC_REQ_TAB_SIZE MAX_TPC_REQ_TAB_SIZE
+
+#define MIN_RCV_PWR 100 /* Negative value ((dBm) */
+
+#define RM_TPC_REQ 0
+#define RM_MEASURE_REQ 1
+
+#define RM_BASIC 0
+#define RM_CCA 1
+#define RM_RPI_HISTOGRAM 2
+
+#define TPC_REQ_AGE_OUT 500 /* ms */
+#define MQ_REQ_AGE_OUT 500 /* ms */
+
+#define TPC_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) % MAX_HASH_TPC_REQ_TAB_SIZE)
+#define MQ_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) % MAX_MEASURE_REQ_TAB_SIZE)
+
+typedef struct _MEASURE_REQ_ENTRY
+{
+ struct _MEASURE_REQ_ENTRY *pNext;
+ ULONG lastTime;
+ BOOLEAN Valid;
+ UINT8 DialogToken;
+ UINT8 MeasureDialogToken[3]; // 0:basic measure, 1: CCA measure, 2: RPI_Histogram measure.
+} MEASURE_REQ_ENTRY, *PMEASURE_REQ_ENTRY;
+
+typedef struct _MEASURE_REQ_TAB
+{
+ UCHAR Size;
+ PMEASURE_REQ_ENTRY Hash[MAX_HASH_MEASURE_REQ_TAB_SIZE];
+ MEASURE_REQ_ENTRY Content[MAX_MEASURE_REQ_TAB_SIZE];
+} MEASURE_REQ_TAB, *PMEASURE_REQ_TAB;
+
+typedef struct _TPC_REQ_ENTRY
+{
+ struct _TPC_REQ_ENTRY *pNext;
+ ULONG lastTime;
+ BOOLEAN Valid;
+ UINT8 DialogToken;
+} TPC_REQ_ENTRY, *PTPC_REQ_ENTRY;
+
+typedef struct _TPC_REQ_TAB
+{
+ UCHAR Size;
+ PTPC_REQ_ENTRY Hash[MAX_HASH_TPC_REQ_TAB_SIZE];
+ TPC_REQ_ENTRY Content[MAX_TPC_REQ_TAB_SIZE];
+} TPC_REQ_TAB, *PTPC_REQ_TAB;
+
+#endif // __SPECTRUM_DEF_H__ //
+
diff --git a/drivers/staging/rt3070/sta/aironet.c b/drivers/staging/rt3070/sta/aironet.c
new file mode 100644
index 00000000000..4af4a190618
--- /dev/null
+++ b/drivers/staging/rt3070/sta/aironet.c
@@ -0,0 +1,1312 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ aironet.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 04-06-15 Initial
+*/
+#include "../rt_config.h"
+
+/*
+ ==========================================================================
+ Description:
+ association state machine init, including state transition and timer init
+ Parameters:
+ S - pointer to the association state machine
+ ==========================================================================
+ */
+VOID AironetStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(S, Trans, MAX_AIRONET_STATE, MAX_AIRONET_MSG, (STATE_MACHINE_FUNC)Drop, AIRONET_IDLE, AIRONET_MACHINE_BASE);
+ StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_MSG, (STATE_MACHINE_FUNC)AironetMsgAction);
+ StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_SCAN_REQ, (STATE_MACHINE_FUNC)AironetRequestAction);
+ StateMachineSetAction(S, AIRONET_SCANNING, MT2_AIRONET_SCAN_DONE, (STATE_MACHINE_FUNC)AironetReportAction);
+}
+
+/*
+ ==========================================================================
+ Description:
+ This is state machine function.
+ When receiving EAPOL packets which is for 802.1x key management.
+ Use both in WPA, and WPAPSK case.
+ In this function, further dispatch to different functions according to the received packet. 3 categories are :
+ 1. normal 4-way pairwisekey and 2-way groupkey handshake
+ 2. MIC error (Countermeasures attack) report packet from STA.
+ 3. Request for pairwise/group key update from STA
+ Return:
+ ==========================================================================
+*/
+VOID AironetMsgAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Length;
+ UCHAR Index, i;
+ PUCHAR pData;
+ PAIRONET_RM_REQUEST_FRAME pRMReq;
+ PRM_REQUEST_ACTION pReqElem;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> AironetMsgAction\n"));
+
+ // 0. Get Aironet IAPP header first
+ pRMReq = (PAIRONET_RM_REQUEST_FRAME) &Elem->Msg[LENGTH_802_11];
+ pData = (PUCHAR) &Elem->Msg[LENGTH_802_11];
+
+ // 1. Change endian format form network to little endian
+ Length = be2cpu16(pRMReq->IAPP.Length);
+
+ // 2.0 Sanity check, this should only happen when CCX 2.0 support is enabled
+ if (pAd->StaCfg.CCXEnable != TRUE)
+ return;
+
+ // 2.1 Radio measurement must be on
+ if (pAd->StaCfg.CCXControl.field.RMEnable != 1)
+ return;
+
+ // 2.2. Debug print all bit information
+ DBGPRINT(RT_DEBUG_TRACE, ("IAPP ID & Length %d\n", Length));
+ DBGPRINT(RT_DEBUG_TRACE, ("IAPP Type %x\n", pRMReq->IAPP.Type));
+ DBGPRINT(RT_DEBUG_TRACE, ("IAPP SubType %x\n", pRMReq->IAPP.SubType));
+ DBGPRINT(RT_DEBUG_TRACE, ("IAPP Dialog Token %x\n", pRMReq->IAPP.Token));
+ DBGPRINT(RT_DEBUG_TRACE, ("IAPP Activation Delay %x\n", pRMReq->Delay));
+ DBGPRINT(RT_DEBUG_TRACE, ("IAPP Measurement Offset %x\n", pRMReq->Offset));
+
+ // 3. Check IAPP frame type, it must be 0x32 for Cisco Aironet extension
+ if (pRMReq->IAPP.Type != AIRONET_IAPP_TYPE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP type for Cisco Aironet extension\n"));
+ return;
+ }
+
+ // 4. Check IAPP frame subtype, it must be 0x01 for Cisco Aironet extension request.
+ // Since we are acting as client only, we will disregards reply subtype.
+ if (pRMReq->IAPP.SubType != AIRONET_IAPP_SUBTYPE_REQUEST)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP subtype for Cisco Aironet extension\n"));
+ return;
+ }
+
+ // 5. Verify Destination MAC and Source MAC, both should be all zeros.
+ if (! MAC_ADDR_EQUAL(pRMReq->IAPP.DA, ZERO_MAC_ADDR))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP DA for Cisco Aironet extension, it's not Zero\n"));
+ return;
+ }
+
+ if (! MAC_ADDR_EQUAL(pRMReq->IAPP.SA, ZERO_MAC_ADDR))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP SA for Cisco Aironet extension, it's not Zero\n"));
+ return;
+ }
+
+ // 6. Reinit all report related fields
+ NdisZeroMemory(pAd->StaCfg.FrameReportBuf, 2048);
+ NdisZeroMemory(pAd->StaCfg.BssReportOffset, sizeof(USHORT) * MAX_LEN_OF_BSS_TABLE);
+ NdisZeroMemory(pAd->StaCfg.MeasurementRequest, sizeof(RM_REQUEST_ACTION) * 4);
+
+ // 7. Point to the start of first element report element
+ pAd->StaCfg.FrameReportLen = LENGTH_802_11 + sizeof(AIRONET_IAPP_HEADER);
+ DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));
+ pAd->StaCfg.LastBssIndex = 0xff;
+ pAd->StaCfg.RMReqCnt = 0;
+ pAd->StaCfg.ParallelReq = FALSE;
+ pAd->StaCfg.ParallelDuration = 0;
+ pAd->StaCfg.ParallelChannel = 0;
+ pAd->StaCfg.IAPPToken = pRMReq->IAPP.Token;
+ pAd->StaCfg.CurrentRMReqIdx = 0;
+ pAd->StaCfg.CLBusyBytes = 0;
+ // Reset the statistics
+ for (i = 0; i < 8; i++)
+ pAd->StaCfg.RPIDensity[i] = 0;
+
+ Index = 0;
+
+ // 8. Save dialog token for report
+ pAd->StaCfg.IAPPToken = pRMReq->IAPP.Token;
+
+ // Save Activation delay & measurement offset, Not really needed
+
+ // 9. Point to the first request element
+ pData += sizeof(AIRONET_RM_REQUEST_FRAME);
+ // Length should exclude the CISCO Aironet SNAP header
+ Length -= (sizeof(AIRONET_RM_REQUEST_FRAME) - LENGTH_802_1_H);
+
+ // 10. Start Parsing the Measurement elements.
+ // Be careful about multiple MR elements within one frames.
+ while (Length > 0)
+ {
+ pReqElem = (PRM_REQUEST_ACTION) pData;
+ switch (pReqElem->ReqElem.Eid)
+ {
+ case IE_MEASUREMENT_REQUEST:
+ // From the example, it seems we only need to support one request in one frame
+ // There is no multiple request in one frame.
+ // Besides, looks like we need to take care the measurement request only.
+ // The measurement request is always 4 bytes.
+
+ // Start parsing this type of request.
+ // 0. Eid is IE_MEASUREMENT_REQUEST
+ // 1. Length didn't include Eid and Length field, it always be 8.
+ // 2. Measurement Token, we nned to save it for the corresponding report.
+ // 3. Measurement Mode, Although there are definitions, but we din't see value other than
+ // 0 from test specs examples.
+ // 4. Measurement Type, this is what we need to do.
+ switch (pReqElem->ReqElem.Type)
+ {
+ case MSRN_TYPE_CHANNEL_LOAD_REQ:
+ case MSRN_TYPE_NOISE_HIST_REQ:
+ case MSRN_TYPE_BEACON_REQ:
+ // Check the Enable non-serving channel measurement control
+ if (pAd->StaCfg.CCXControl.field.DCRMEnable == 0)
+ {
+ // Check channel before enqueue the action
+ if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
+ break;
+ }
+ else
+ {
+ // If off channel measurement, check the TU duration limit
+ if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
+ if (pReqElem->Measurement.Duration > pAd->StaCfg.CCXControl.field.TuLimit)
+ break;
+ }
+
+ // Save requests and execute actions later
+ NdisMoveMemory(&pAd->StaCfg.MeasurementRequest[Index], pReqElem, sizeof(RM_REQUEST_ACTION));
+ Index += 1;
+ break;
+
+ case MSRN_TYPE_FRAME_REQ:
+ // Since it's option, we will support later
+ // FrameRequestAction(pAd, pData);
+ break;
+
+ default:
+ break;
+ }
+
+ // Point to next Measurement request
+ pData += sizeof(RM_REQUEST_ACTION);
+ Length -= sizeof(RM_REQUEST_ACTION);
+ break;
+
+ // We accept request only, all others are dropped
+ case IE_MEASUREMENT_REPORT:
+ case IE_AP_TX_POWER:
+ case IE_MEASUREMENT_CAPABILITY:
+ default:
+ return;
+ }
+ }
+
+ // 11. Update some flags and index
+ pAd->StaCfg.RMReqCnt = Index;
+
+ if (Index)
+ {
+ MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- AironetMsgAction\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID AironetRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PRM_REQUEST_ACTION pReq;
+
+ // 1. Point to next request element
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
+
+ // 2. Parse measurement type and call appropriate functions
+ if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
+ // Channel Load measurement request
+ ChannelLoadRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
+ // Noise Histogram measurement request
+ NoiseHistRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
+ // Beacon measurement request
+ BeaconRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else
+ // Unknown. Do nothing and return, this should never happen
+ return;
+
+ // 3. Peek into the next request, if it's parallel, we will update the scan time to the largest one
+ if ((pAd->StaCfg.CurrentRMReqIdx + 1) < pAd->StaCfg.RMReqCnt)
+ {
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx + 1];
+ // Check for parallel bit
+ if ((pReq->ReqElem.Mode & 0x01) && (pReq->Measurement.Channel == pAd->StaCfg.CCXScanChannel))
+ {
+ // Update parallel mode request information
+ pAd->StaCfg.ParallelReq = TRUE;
+ pAd->StaCfg.CCXScanTime = ((pReq->Measurement.Duration > pAd->StaCfg.CCXScanTime) ?
+ (pReq->Measurement.Duration) : (pAd->StaCfg.CCXScanTime));
+ }
+ }
+
+ // 4. Call RT28XX_MLME_HANDLER to execute the request mlme commands, Scan request is the only one used
+ RT28XX_MLME_HANDLER(pAd);
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Prepare channel load report action, special scan operation added
+ to support
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Start from element ID
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID ChannelLoadRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ PRM_REQUEST_ACTION pReq;
+ MLME_SCAN_REQ_STRUCT ScanReq;
+ UCHAR ZeroSsid[32];
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ PHEADER_802_11 pNullFrame;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction ----->\n"));
+
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
+ NdisZeroMemory(ZeroSsid, 32);
+
+ // Prepare for special scan request
+ // The scan definition is different with our Active, Passive scan definition.
+ // For CCX2, Active means send out probe request with broadcast BSSID.
+ // Passive means no probe request sent, only listen to the beacons.
+ // The channel scanned is fixed as specified, no need to scan all channels.
+ // The scan wait time is specified in the request too.
+ // Passive scan Mode
+
+ // Control state machine is not idle, reject the request
+ if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
+ return;
+
+ // Fill out stuff for scan request
+ ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_CHANNEL_LOAD);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+
+ // Reset some internal control flags to make sure this scan works.
+ BssTableInit(&pAd->StaCfg.CCXBssTab);
+ pAd->StaCfg.ScanCnt = 0;
+ pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
+ pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
+
+ // If it's non serving channel scan, send out a null frame with PSM bit on.
+ if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+ {
+ // Use MLME enqueue method
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ pNullFrame = (PHEADER_802_11) pOutBuffer;;
+ // Make the power save Null frame with PSM bit on
+ MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+ pNullFrame->Duration = 0;
+ pNullFrame->FC.Type = BTYPE_DATA;
+ pNullFrame->FC.PwrMgmt = PWR_SAVE;
+
+ // Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
+ RTMPusecDelay(5000);
+ }
+
+ pAd->StaCfg.CCXReqType = MSRN_TYPE_CHANNEL_LOAD_REQ;
+ pAd->StaCfg.CLBusyBytes = 0;
+ // Enable Rx with promiscuous reception
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
+
+ // Set channel load measurement flag
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
+
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Prepare noise histogram report action, special scan operation added
+ to support
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Start from element ID
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID NoiseHistRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ PRM_REQUEST_ACTION pReq;
+ MLME_SCAN_REQ_STRUCT ScanReq;
+ UCHAR ZeroSsid[32], i;
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ PHEADER_802_11 pNullFrame;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction ----->\n"));
+
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
+ NdisZeroMemory(ZeroSsid, 32);
+
+ // Prepare for special scan request
+ // The scan definition is different with our Active, Passive scan definition.
+ // For CCX2, Active means send out probe request with broadcast BSSID.
+ // Passive means no probe request sent, only listen to the beacons.
+ // The channel scanned is fixed as specified, no need to scan all channels.
+ // The scan wait time is specified in the request too.
+ // Passive scan Mode
+
+ // Control state machine is not idle, reject the request
+ if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
+ return;
+
+ // Fill out stuff for scan request
+ ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_NOISE);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+
+ // Reset some internal control flags to make sure this scan works.
+ BssTableInit(&pAd->StaCfg.CCXBssTab);
+ pAd->StaCfg.ScanCnt = 0;
+ pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
+ pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
+ pAd->StaCfg.CCXReqType = MSRN_TYPE_NOISE_HIST_REQ;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
+
+ // If it's non serving channel scan, send out a null frame with PSM bit on.
+ if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+ {
+ // Use MLME enqueue method
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ pNullFrame = (PHEADER_802_11) pOutBuffer;
+ // Make the power save Null frame with PSM bit on
+ MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+ pNullFrame->Duration = 0;
+ pNullFrame->FC.Type = BTYPE_DATA;
+ pNullFrame->FC.PwrMgmt = PWR_SAVE;
+
+ // Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
+ RTMPusecDelay(5000);
+ }
+
+ // Reset the statistics
+ for (i = 0; i < 8; i++)
+ pAd->StaCfg.RPIDensity[i] = 0;
+
+ // Enable Rx with promiscuous reception
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
+
+ // Set channel load measurement flag
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
+
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Prepare Beacon report action, special scan operation added
+ to support
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Start from element ID
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID BeaconRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ PRM_REQUEST_ACTION pReq;
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ PHEADER_802_11 pNullFrame;
+ MLME_SCAN_REQ_STRUCT ScanReq;
+ UCHAR ZeroSsid[32];
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction ----->\n"));
+
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
+ NdisZeroMemory(ZeroSsid, 32);
+
+ // Prepare for special scan request
+ // The scan definition is different with our Active, Passive scan definition.
+ // For CCX2, Active means send out probe request with broadcast BSSID.
+ // Passive means no probe request sent, only listen to the beacons.
+ // The channel scanned is fixed as specified, no need to scan all channels.
+ // The scan wait time is specified in the request too.
+ if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_PASSIVE)
+ {
+ // Passive scan Mode
+ DBGPRINT(RT_DEBUG_TRACE, ("Passive Scan Mode!\n"));
+
+ // Control state machine is not idle, reject the request
+ if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
+ return;
+
+ // Fill out stuff for scan request
+ ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_PASSIVE);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+
+ // Reset some internal control flags to make sure this scan works.
+ BssTableInit(&pAd->StaCfg.CCXBssTab);
+ pAd->StaCfg.ScanCnt = 0;
+ pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
+ pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
+ pAd->StaCfg.CCXReqType = MSRN_TYPE_BEACON_REQ;
+ DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
+
+ // If it's non serving channel scan, send out a null frame with PSM bit on.
+ if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+ {
+ // Use MLME enqueue method
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ pNullFrame = (PHEADER_802_11) pOutBuffer;
+ // Make the power save Null frame with PSM bit on
+ MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+ pNullFrame->Duration = 0;
+ pNullFrame->FC.Type = BTYPE_DATA;
+ pNullFrame->FC.PwrMgmt = PWR_SAVE;
+
+ // Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
+ RTMPusecDelay(5000);
+ }
+
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+ }
+ else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_ACTIVE)
+ {
+ // Active scan Mode
+ DBGPRINT(RT_DEBUG_TRACE, ("Active Scan Mode!\n"));
+
+ // Control state machine is not idle, reject the request
+ if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ return;
+
+ // Fill out stuff for scan request
+ ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_ACTIVE);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+
+ // Reset some internal control flags to make sure this scan works.
+ BssTableInit(&pAd->StaCfg.CCXBssTab);
+ pAd->StaCfg.ScanCnt = 0;
+ pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
+ pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
+ pAd->StaCfg.CCXReqType = MSRN_TYPE_BEACON_REQ;
+ DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
+
+ // If it's non serving channel scan, send out a null frame with PSM bit on.
+ if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+ {
+ // Use MLME enqueue method
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ pNullFrame = (PHEADER_802_11) pOutBuffer;
+ // Make the power save Null frame with PSM bit on
+ MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+ pNullFrame->Duration = 0;
+ pNullFrame->FC.Type = BTYPE_DATA;
+ pNullFrame->FC.PwrMgmt = PWR_SAVE;
+
+ // Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
+ RTMPusecDelay(5000);
+ }
+
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+ }
+ else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_BEACON_TABLE)
+ {
+ // Beacon report Mode, report all the APS in current bss table
+ DBGPRINT(RT_DEBUG_TRACE, ("Beacon Report Mode!\n"));
+
+ // Copy current BSS table to CCX table, we can omit this step later on.
+ NdisMoveMemory(&pAd->StaCfg.CCXBssTab, &pAd->ScanTab, sizeof(BSS_TABLE));
+
+ // Create beacon report from Bss table
+ AironetCreateBeaconReportFromBssTable(pAd);
+
+ // Set state to scanning
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+
+ // Enqueue report request
+ // Cisco scan request is finished, prepare beacon report
+ MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
+ }
+ else
+ {
+ // Wrong scan Mode
+ DBGPRINT(RT_DEBUG_TRACE, ("Wrong Scan Mode!\n"));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID AironetReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PRM_REQUEST_ACTION pReq;
+ ULONG Now32;
+
+ NdisGetSystemUpTime(&Now32);
+ pAd->StaCfg.LastBeaconRxTime = Now32;
+
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction ----->\n"));
+
+ // 1. Parse measurement type and call appropriate functions
+ if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
+ // Channel Load measurement request
+ ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
+ // Noise Histogram measurement request
+ NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
+ // Beacon measurement request
+ BeaconReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else
+ // Unknown. Do nothing and return
+ ;
+
+ // 2. Point to the correct index of action element, start from 0
+ pAd->StaCfg.CurrentRMReqIdx++;
+
+ // 3. Check for parallel actions
+ if (pAd->StaCfg.ParallelReq == TRUE)
+ {
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
+
+ // Process next action right away
+ if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
+ // Channel Load measurement request
+ ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
+ // Noise Histogram measurement request
+ NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+
+ pAd->StaCfg.ParallelReq = FALSE;
+ pAd->StaCfg.CurrentRMReqIdx++;
+ }
+
+ if (pAd->StaCfg.CurrentRMReqIdx >= pAd->StaCfg.RMReqCnt)
+ {
+ // 4. There is no more unprocessed measurement request, go for transmit this report
+ AironetFinalReportAction(pAd);
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
+ }
+ else
+ {
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
+
+ if (pReq->Measurement.Channel != pAd->CommonCfg.Channel)
+ {
+ RTMPusecDelay(100000);
+ }
+
+ // 5. There are more requests to be measure
+ MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID AironetFinalReportAction(
+ IN PRTMP_ADAPTER pAd)
+{
+ PUCHAR pDest;
+ PAIRONET_IAPP_HEADER pIAPP;
+ PHEADER_802_11 pHeader;
+ UCHAR AckRate = RATE_2;
+ USHORT AckDuration = 0;
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction ----->\n"));
+
+ // 0. Set up the frame pointer, Frame was inited at the end of message action
+ pDest = &pAd->StaCfg.FrameReportBuf[LENGTH_802_11];
+
+ // 1. Update report IAPP fields
+ pIAPP = (PAIRONET_IAPP_HEADER) pDest;
+
+ // 2. Copy Cisco SNAP header
+ NdisMoveMemory(pIAPP->CiscoSnapHeader, SNAP_AIRONET, LENGTH_802_1_H);
+
+ // 3. network order for this 16bit length
+ pIAPP->Length = cpu2be16(pAd->StaCfg.FrameReportLen - LENGTH_802_11 - LENGTH_802_1_H);
+
+ // 3.1 sanity check the report length, ignore it if there is nothing to report
+ if (be2cpu16(pIAPP->Length) <= 18)
+ return;
+
+ // 4. Type must be 0x32
+ pIAPP->Type = AIRONET_IAPP_TYPE;
+
+ // 5. SubType for report must be 0x81
+ pIAPP->SubType = AIRONET_IAPP_SUBTYPE_REPORT;
+
+ // 6. DA is not used and must be zero, although the whole frame was cleared at the start of function
+ // We will do it again here. We can use BSSID instead
+ COPY_MAC_ADDR(pIAPP->DA, pAd->CommonCfg.Bssid);
+
+ // 7. SA is the client reporting which must be our MAC
+ COPY_MAC_ADDR(pIAPP->SA, pAd->CurrentAddress);
+
+ // 8. Copy the saved dialog token
+ pIAPP->Token = pAd->StaCfg.IAPPToken;
+
+ // 9. Make the Report frame 802.11 header
+ // Reuse function in wpa.c
+ pHeader = (PHEADER_802_11) pAd->StaCfg.FrameReportBuf;
+ pAd->Sequence ++;
+ WpaMacHeaderInit(pAd, pHeader, 0, pAd->CommonCfg.Bssid);
+
+ // ACK size is 14 include CRC, and its rate is based on real time information
+ AckRate = pAd->CommonCfg.ExpectedACKRate[pAd->CommonCfg.MlmeRate];
+ AckDuration = RTMPCalcDuration(pAd, AckRate, 14);
+ pHeader->Duration = pAd->CommonCfg.Dsifs + AckDuration;
+
+ // Use MLME enqueue method
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ // 10. Prepare report frame with dynamic outbuffer. Just simply copy everything.
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ pAd->StaCfg.FrameReportLen, pAd->StaCfg.FrameReportBuf,
+ END_OF_ARGS);
+
+ // 11. Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID ChannelLoadReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ PMEASUREMENT_REPORT_ELEMENT pReport;
+ PCHANNEL_LOAD_REPORT pLoad;
+ PUCHAR pDest;
+ UCHAR CCABusyFraction;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction ----->\n"));
+
+ // Disable Rx with promiscuous reception, make it back to normal
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
+
+ // 0. Setup pointer for processing beacon & probe response
+ pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
+ pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
+
+ // 1. Fill Measurement report element field.
+ pReport->Eid = IE_MEASUREMENT_REPORT;
+ // Fixed Length at 9, not include Eid and length fields
+ pReport->Length = 9;
+ pReport->Token = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
+ pReport->Mode = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
+ pReport->Type = MSRN_TYPE_CHANNEL_LOAD_REQ;
+
+ // 2. Fill channel report measurement data
+ pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
+ pLoad = (PCHANNEL_LOAD_REPORT) pDest;
+ pLoad->Channel = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel;
+ pLoad->Spare = 0;
+ pLoad->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration;
+
+ // 3. Calculate the CCA Busy Fraction
+ // (Bytes + ACK size) * 8 / Tx speed * 255 / 1000 / measurement duration, use 24 us Tx speed
+ // = (Bytes + ACK) / 12 / duration
+ // 9 is the good value for pAd->StaCfg.CLFactor
+ // CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 9 / pLoad->Duration);
+ CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / pAd->StaCfg.CLFactor / pLoad->Duration);
+ if (CCABusyFraction < 10)
+ CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 3 / pLoad->Duration) + 1;
+
+ pLoad->CCABusy = CCABusyFraction;
+ DBGPRINT(RT_DEBUG_TRACE, ("CLBusyByte %ld, Duration %d, Result, %d\n", pAd->StaCfg.CLBusyBytes, pLoad->Duration, CCABusyFraction));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
+ pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(CHANNEL_LOAD_REPORT));
+ DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
+
+ // 4. Clear channel load measurement flag
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
+
+ // 5. reset to idle state
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID NoiseHistReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ PMEASUREMENT_REPORT_ELEMENT pReport;
+ PNOISE_HIST_REPORT pNoise;
+ PUCHAR pDest;
+ UCHAR i,NoiseCnt;
+ USHORT TotalRPICnt, TotalRPISum;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction ----->\n"));
+
+ // 0. Disable Rx with promiscuous reception, make it back to normal
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
+ // 1. Setup pointer for processing beacon & probe response
+ pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
+ pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
+
+ // 2. Fill Measurement report element field.
+ pReport->Eid = IE_MEASUREMENT_REPORT;
+ // Fixed Length at 16, not include Eid and length fields
+ pReport->Length = 16;
+ pReport->Token = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
+ pReport->Mode = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
+ pReport->Type = MSRN_TYPE_NOISE_HIST_REQ;
+
+ // 3. Fill noise histogram report measurement data
+ pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
+ pNoise = (PNOISE_HIST_REPORT) pDest;
+ pNoise->Channel = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel;
+ pNoise->Spare = 0;
+ pNoise->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration;
+ // 4. Fill Noise histogram, the total RPI counts should be 0.4 * TU
+ // We estimate 4000 normal packets received durning 10 seconds test.
+ // Adjust it if required.
+ // 3 is a good value for pAd->StaCfg.NHFactor
+ // TotalRPICnt = pNoise->Duration * 3 / 10;
+ TotalRPICnt = pNoise->Duration * pAd->StaCfg.NHFactor / 10;
+ TotalRPISum = 0;
+
+ for (i = 0; i < 8; i++)
+ {
+ TotalRPISum += pAd->StaCfg.RPIDensity[i];
+ DBGPRINT(RT_DEBUG_TRACE, ("RPI %d Conuts %d\n", i, pAd->StaCfg.RPIDensity[i]));
+ }
+
+ // Double check if the counter is larger than our expectation.
+ // We will replace it with the total number plus a fraction.
+ if (TotalRPISum > TotalRPICnt)
+ TotalRPICnt = TotalRPISum + pNoise->Duration / 20;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Total RPI Conuts %d\n", TotalRPICnt));
+
+ // 5. Initialize noise count for the total summation of 0xff
+ NoiseCnt = 0;
+ for (i = 1; i < 8; i++)
+ {
+ pNoise->Density[i] = (UCHAR) (pAd->StaCfg.RPIDensity[i] * 255 / TotalRPICnt);
+ if ((pNoise->Density[i] == 0) && (pAd->StaCfg.RPIDensity[i] != 0))
+ pNoise->Density[i]++;
+ NoiseCnt += pNoise->Density[i];
+ DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[%d] = 0x%02x\n", i, pNoise->Density[i]));
+ }
+
+ // 6. RPI[0] represents the rest of counts
+ pNoise->Density[0] = 0xff - NoiseCnt;
+ DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[0] = 0x%02x\n", pNoise->Density[0]));
+
+ pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(NOISE_HIST_REPORT));
+
+ // 7. Clear channel load measurement flag
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
+
+ // 8. reset to idle state
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Prepare Beacon report action,
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID BeaconReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction ----->\n"));
+
+ // Looks like we don't have anything thing need to do here.
+ // All measurement report already finished in AddBeaconReport
+ // The length is in the FrameReportLen
+
+ // reset Beacon index for next beacon request
+ pAd->StaCfg.LastBssIndex = 0xff;
+
+ // reset to idle state
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+ Index Current BSSID in CCXBsstab entry index
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID AironetAddBeaconReport(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Index,
+ IN PMLME_QUEUE_ELEM pElem)
+{
+ PVOID pMsg;
+ PUCHAR pSrc, pDest;
+ UCHAR ReqIdx;
+ ULONG MsgLen;
+ USHORT Length;
+ PFRAME_802_11 pFrame;
+ PMEASUREMENT_REPORT_ELEMENT pReport;
+ PEID_STRUCT pEid;
+ PBEACON_REPORT pBeaconReport;
+ PBSS_ENTRY pBss;
+
+ // 0. Setup pointer for processing beacon & probe response
+ pMsg = pElem->Msg;
+ MsgLen = pElem->MsgLen;
+ pFrame = (PFRAME_802_11) pMsg;
+ pSrc = pFrame->Octet; // Start from AP TSF
+ pBss = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index];
+ ReqIdx = pAd->StaCfg.CurrentRMReqIdx;
+
+ // 1 Check the Index, if we already create this entry, only update the average RSSI
+ if ((Index <= pAd->StaCfg.LastBssIndex) && (pAd->StaCfg.LastBssIndex != 0xff))
+ {
+ pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.BssReportOffset[Index]];
+ // Point to bss report information
+ pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
+ pBeaconReport = (PBEACON_REPORT) pDest;
+
+ // Update Rx power, in dBm
+ // Get the original RSSI readback from BBP
+ pBeaconReport->RxPower += pAd->BbpRssiToDbmDelta;
+ // Average the Rssi reading
+ pBeaconReport->RxPower = (pBeaconReport->RxPower + pBss->Rssi) / 2;
+ // Get to dBm format
+ pBeaconReport->RxPower -= pAd->BbpRssiToDbmDelta;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ",
+ pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
+ pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
+ DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld] Rssi %d, Avg Rssi %d\n", Index, (pBss->Rssi - pAd->BbpRssiToDbmDelta), pBeaconReport->RxPower - 256));
+ DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.BssReportOffset[Index]));
+
+ // Update other information here
+
+ // Done
+ return;
+ }
+
+ // 2. Update reported Index
+ pAd->StaCfg.LastBssIndex = Index;
+
+ // 3. Setup the buffer address for copying this BSSID into reporting frame
+ // The offset should start after 802.11 header and report frame header.
+ pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
+
+ // 4. Save the start offset of each Bss in report frame
+ pAd->StaCfg.BssReportOffset[Index] = pAd->StaCfg.FrameReportLen;
+
+ // 5. Fill Measurement report fields
+ pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
+ pReport->Eid = IE_MEASUREMENT_REPORT;
+ pReport->Length = 0;
+ pReport->Token = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token;
+ pReport->Mode = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode;
+ pReport->Type = MSRN_TYPE_BEACON_REQ;
+ Length = sizeof(MEASUREMENT_REPORT_ELEMENT);
+ pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
+
+ // 6. Start thebeacon report format
+ pBeaconReport = (PBEACON_REPORT) pDest;
+ pDest += sizeof(BEACON_REPORT);
+ Length += sizeof(BEACON_REPORT);
+
+ // 7. Copy Channel number
+ pBeaconReport->Channel = pBss->Channel;
+ pBeaconReport->Spare = 0;
+ pBeaconReport->Duration = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration;
+ pBeaconReport->PhyType = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS);
+ // 8. Rx power, in dBm
+ pBeaconReport->RxPower = pBss->Rssi - pAd->BbpRssiToDbmDelta;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ",
+ pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
+ pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
+ DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld], Rssi %d\n", Index, pBeaconReport->RxPower - 256));
+ DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.FrameReportLen));
+
+ pBeaconReport->BeaconInterval = pBss->BeaconPeriod;
+ COPY_MAC_ADDR(pBeaconReport->BSSID, pFrame->Hdr.Addr3);
+ NdisMoveMemory(pBeaconReport->ParentTSF, pSrc, 4);
+ NdisMoveMemory(pBeaconReport->TargetTSF, &pElem->TimeStamp.u.LowPart, 4);
+ NdisMoveMemory(&pBeaconReport->TargetTSF[4], &pElem->TimeStamp.u.HighPart, 4);
+
+ // 9. Skip the beacon frame and offset to start of capabilityinfo since we already processed capabilityinfo
+ pSrc += (TIMESTAMP_LEN + 2);
+ pBeaconReport->CapabilityInfo = *(USHORT *)pSrc;
+
+ // 10. Point to start of element ID
+ pSrc += 2;
+ pEid = (PEID_STRUCT) pSrc;
+
+ // 11. Start process all variable Eid oayload and add the appropriate to the frame report
+ while (((PUCHAR) pEid + pEid->Len + 1) < ((PUCHAR) pFrame + MsgLen))
+ {
+ // Only limited EID are required to report for CCX 2. It includes SSID, Supported rate,
+ // FH paramenter set, DS parameter set, CF parameter set, IBSS parameter set,
+ // TIM (report first 4 bytes only, radio measurement capability
+ switch (pEid->Eid)
+ {
+ case IE_SSID:
+ case IE_SUPP_RATES:
+ case IE_FH_PARM:
+ case IE_DS_PARM:
+ case IE_CF_PARM:
+ case IE_IBSS_PARM:
+ NdisMoveMemory(pDest, pEid, pEid->Len + 2);
+ pDest += (pEid->Len + 2);
+ Length += (pEid->Len + 2);
+ break;
+
+ case IE_MEASUREMENT_CAPABILITY:
+ // Since this IE is duplicated with WPA security IE, we has to do sanity check before
+ // recognize it.
+ // 1. It also has fixed 6 bytes IE length.
+ if (pEid->Len != 6)
+ break;
+ // 2. Check the Cisco Aironet OUI
+ if (NdisEqualMemory(CISCO_OUI, (pSrc + 2), 3))
+ {
+ // Matched, this is what we want
+ NdisMoveMemory(pDest, pEid, pEid->Len + 2);
+ pDest += (pEid->Len + 2);
+ Length += (pEid->Len + 2);
+ }
+ break;
+
+ case IE_TIM:
+ if (pEid->Len > 4)
+ {
+ // May truncate and report the first 4 bytes only, with the eid & len, total should be 6
+ NdisMoveMemory(pDest, pEid, 6);
+ pDest += 6;
+ Length += 6;
+ }
+ else
+ {
+ NdisMoveMemory(pDest, pEid, pEid->Len + 2);
+ pDest += (pEid->Len + 2);
+ Length += (pEid->Len + 2);
+ }
+ break;
+
+ default:
+ break;
+ }
+ // 12. Move to next element ID
+ pSrc += (2 + pEid->Len);
+ pEid = (PEID_STRUCT) pSrc;
+ }
+
+ // 13. Update the length in the header, not include EID and length
+ pReport->Length = Length - 4;
+
+ // 14. Update the frame report buffer data length
+ pAd->StaCfg.FrameReportLen += Length;
+ DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+ Index Current BSSID in CCXBsstab entry index
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID AironetCreateBeaconReportFromBssTable(
+ IN PRTMP_ADAPTER pAd)
+{
+ PMEASUREMENT_REPORT_ELEMENT pReport;
+ PBEACON_REPORT pBeaconReport;
+ UCHAR Index, ReqIdx;
+ USHORT Length;
+ PUCHAR pDest;
+ PBSS_ENTRY pBss;
+
+ // 0. setup base pointer
+ ReqIdx = pAd->StaCfg.CurrentRMReqIdx;
+
+ for (Index = 0; Index < pAd->StaCfg.CCXBssTab.BssNr; Index++)
+ {
+ // 1. Setup the buffer address for copying this BSSID into reporting frame
+ // The offset should start after 802.11 header and report frame header.
+ pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
+ pBss = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index];
+ Length = 0;
+
+ // 2. Fill Measurement report fields
+ pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
+ pReport->Eid = IE_MEASUREMENT_REPORT;
+ pReport->Length = 0;
+ pReport->Token = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token;
+ pReport->Mode = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode;
+ pReport->Type = MSRN_TYPE_BEACON_REQ;
+ Length = sizeof(MEASUREMENT_REPORT_ELEMENT);
+ pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
+
+ // 3. Start the beacon report format
+ pBeaconReport = (PBEACON_REPORT) pDest;
+ pDest += sizeof(BEACON_REPORT);
+ Length += sizeof(BEACON_REPORT);
+
+ // 4. Copy Channel number
+ pBeaconReport->Channel = pBss->Channel;
+ pBeaconReport->Spare = 0;
+ pBeaconReport->Duration = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration;
+ pBeaconReport->PhyType = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS);
+ pBeaconReport->RxPower = pBss->Rssi - pAd->BbpRssiToDbmDelta;
+ pBeaconReport->BeaconInterval = pBss->BeaconPeriod;
+ pBeaconReport->CapabilityInfo = pBss->CapabilityInfo;
+ COPY_MAC_ADDR(pBeaconReport->BSSID, pBss->Bssid);
+ NdisMoveMemory(pBeaconReport->ParentTSF, pBss->PTSF, 4);
+ NdisMoveMemory(pBeaconReport->TargetTSF, pBss->TTSF, 8);
+
+ // 5. Create SSID
+ *pDest++ = 0x00;
+ *pDest++ = pBss->SsidLen;
+ NdisMoveMemory(pDest, pBss->Ssid, pBss->SsidLen);
+ pDest += pBss->SsidLen;
+ Length += (2 + pBss->SsidLen);
+
+ // 6. Create SupportRates
+ *pDest++ = 0x01;
+ *pDest++ = pBss->SupRateLen;
+ NdisMoveMemory(pDest, pBss->SupRate, pBss->SupRateLen);
+ pDest += pBss->SupRateLen;
+ Length += (2 + pBss->SupRateLen);
+
+ // 7. DS Parameter
+ *pDest++ = 0x03;
+ *pDest++ = 1;
+ *pDest++ = pBss->Channel;
+ Length += 3;
+
+ // 8. IBSS parameter if presents
+ if (pBss->BssType == BSS_ADHOC)
+ {
+ *pDest++ = 0x06;
+ *pDest++ = 2;
+ *(PUSHORT) pDest = pBss->AtimWin;
+ pDest += 2;
+ Length += 4;
+ }
+
+ // 9. Update length field, not include EID and length
+ pReport->Length = Length - 4;
+
+ // 10. Update total frame size
+ pAd->StaCfg.FrameReportLen += Length;
+ }
+}
diff --git a/drivers/staging/rt3070/sta/assoc.c b/drivers/staging/rt3070/sta/assoc.c
new file mode 100644
index 00000000000..5c33a895bf7
--- /dev/null
+++ b/drivers/staging/rt3070/sta/assoc.c
@@ -0,0 +1,2060 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ assoc.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John 2004-9-3 porting from RT2500
+*/
+#include "../rt_config.h"
+
+UCHAR CipherWpaTemplate[] = {
+ 0xdd, // WPA IE
+ 0x16, // Length
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x50, 0xf2, 0x02, // Multicast
+ 0x01, 0x00, // Number of unicast
+ 0x00, 0x50, 0xf2, 0x02, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x50, 0xf2, 0x01 // authentication
+ };
+
+UCHAR CipherWpa2Template[] = {
+ 0x30, // RSN IE
+ 0x14, // Length
+ 0x01, 0x00, // Version
+ 0x00, 0x0f, 0xac, 0x02, // group cipher, TKIP
+ 0x01, 0x00, // number of pairwise
+ 0x00, 0x0f, 0xac, 0x02, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x0f, 0xac, 0x02, // authentication
+ 0x00, 0x00, // RSN capability
+ };
+
+UCHAR Ccx2IeInfo[] = { 0x00, 0x40, 0x96, 0x03, 0x02};
+
+/*
+ ==========================================================================
+ Description:
+ association state machine init, including state transition and timer init
+ Parameters:
+ S - pointer to the association state machine
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+VOID AssocStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(S, Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG, (STATE_MACHINE_FUNC)Drop, ASSOC_IDLE, ASSOC_MACHINE_BASE);
+
+ // first column
+ StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)MlmeAssocReqAction);
+ StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)MlmeReassocReqAction);
+ StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)MlmeDisassocReqAction);
+ StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
+
+ // second column
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
+ //
+ // Patch 3Com AP MOde:3CRWE454G72
+ // We send Assoc request frame to this AP, it always send Reassoc Rsp not Associate Rsp.
+ //
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT, (STATE_MACHINE_FUNC)AssocTimeoutAction);
+
+ // third column
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
+ //
+ // Patch, AP doesn't send Reassociate Rsp frame to Station.
+ //
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT, (STATE_MACHINE_FUNC)ReassocTimeoutAction);
+
+ // fourth column
+ StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
+ StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
+ StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
+ StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
+ StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT, (STATE_MACHINE_FUNC)DisassocTimeoutAction);
+
+ // initialize the timer
+ RTMPInitTimer(pAd, &pAd->MlmeAux.AssocTimer, GET_TIMER_FUNCTION(AssocTimeout), pAd, FALSE);
+ RTMPInitTimer(pAd, &pAd->MlmeAux.ReassocTimer, GET_TIMER_FUNCTION(ReassocTimeout), pAd, FALSE);
+ RTMPInitTimer(pAd, &pAd->MlmeAux.DisassocTimer, GET_TIMER_FUNCTION(DisassocTimeout), pAd, FALSE);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Association timeout procedure. After association timeout, this function
+ will be called and it will put a message into the MLME queue
+ Parameters:
+ Standard timer parameters
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AssocTimeout(IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return;
+
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Reassociation timeout procedure. After reassociation timeout, this
+ function will be called and put a message into the MLME queue
+ Parameters:
+ Standard timer parameters
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID ReassocTimeout(IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return;
+
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Disassociation timeout procedure. After disassociation timeout, this
+ function will be called and put a message into the MLME queue
+ Parameters:
+ Standard timer parameters
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID DisassocTimeout(IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return;
+
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+}
+
+/*
+ ==========================================================================
+ Description:
+ mlme assoc req handling procedure
+ Parameters:
+ Adapter - Adapter pointer
+ Elem - MLME Queue Element
+ Pre:
+ the station has been authenticated and the following information is stored in the config
+ -# SSID
+ -# supported rates and their length
+ -# listen interval (Adapter->StaCfg.default_listen_count)
+ -# Transmit power (Adapter->StaCfg.tx_power)
+ Post :
+ -# An association request frame is generated and sent to the air
+ -# Association timer starts
+ -# Association state -> ASSOC_WAIT_RSP
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeAssocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR ApAddr[6];
+ HEADER_802_11 AssocHdr;
+ UCHAR Ccx2Len = 5;
+ UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
+ USHORT ListenIntv;
+ ULONG Timeout;
+ USHORT CapabilityInfo;
+ BOOLEAN TimerCancelled;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ ULONG tmp;
+ USHORT VarIesOffset;
+ UCHAR CkipFlag;
+ UCHAR CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
+ UCHAR AironetCkipIe = IE_AIRONET_CKIP;
+ UCHAR AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
+ UCHAR AironetIPAddressIE = IE_AIRONET_IPADDRESS;
+ UCHAR AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
+ UCHAR AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
+ USHORT Status;
+
+ // Block all authentication request durning WPA block period
+ if (pAd->StaCfg.bBlockAssoc == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block Assoc request durning WPA block period!\n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+ }
+ // check sanity first
+ else if (MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
+ {
+ RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
+ COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
+
+ // Get an unused nonpaged memory
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() allocate memory failed \n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+ return;
+ }
+
+ // Add by James 03/06/27
+ pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+ // Association don't need to report MAC address
+ pAd->StaCfg.AssocInfo.AvailableRequestFixedIEs =
+ NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_LISTENINTERVAL;
+ pAd->StaCfg.AssocInfo.RequestFixedIEs.Capabilities = CapabilityInfo;
+ pAd->StaCfg.AssocInfo.RequestFixedIEs.ListenInterval = ListenIntv;
+ // Only reassociate need this
+ //COPY_MAC_ADDR(pAd->StaCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, ApAddr);
+ pAd->StaCfg.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+
+ NdisZeroMemory(pAd->StaCfg.ReqVarIEs, MAX_VIE_LEN);
+ // First add SSID
+ VarIesOffset = 0;
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SsidIe, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SsidLen, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+ VarIesOffset += pAd->MlmeAux.SsidLen;
+
+ // Second add Supported rates
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SupRateIe, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SupRateLen, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen);
+ VarIesOffset += pAd->MlmeAux.SupRateLen;
+ // End Add by James
+
+ if ((pAd->CommonCfg.Channel > 14) &&
+ (pAd->CommonCfg.bIEEE80211H == TRUE))
+ CapabilityInfo |= 0x0100;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send ASSOC request...\n"));
+ MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr);
+
+ // Build basic frame first
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &AssocHdr,
+ 2, &CapabilityInfo,
+ 2, &ListenIntv,
+ 1, &SsidIe,
+ 1, &pAd->MlmeAux.SsidLen,
+ pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
+ 1, &SupRateIe,
+ 1, &pAd->MlmeAux.SupRateLen,
+ pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
+ END_OF_ARGS);
+
+ if (pAd->MlmeAux.ExtRateLen != 0)
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &ExtRateIe,
+ 1, &pAd->MlmeAux.ExtRateLen,
+ pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // HT
+ if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ ULONG TmpLen;
+ UCHAR HtLen;
+ UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+ if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
+ {
+ HtLen = SIZE_HT_CAP_IE + 4;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &HtLen,
+ 4, &BROADCOM[0],
+ pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
+ END_OF_ARGS);
+ }
+ else
+ {
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+#endif
+
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &pAd->MlmeAux.HtCapabilityLen,
+ pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
+ END_OF_ARGS);
+#else
+ NdisZeroMemory(&HtCapabilityTmp, sizeof(HT_CAPABILITY_IE));
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, pAd->MlmeAux.HtCapabilityLen);
+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &pAd->MlmeAux.HtCapabilityLen,
+ pAd->MlmeAux.HtCapabilityLen,&HtCapabilityTmp,
+ END_OF_ARGS);
+#endif
+ }
+ FrameLen += TmpLen;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
+ // Case I: (Aggregation + Piggy-Back)
+ // 1. user enable aggregation, AND
+ // 2. Mac support piggy-back
+ // 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
+ // Case II: (Aggregation)
+ // 1. user enable aggregation, AND
+ // 2. AP annouces it's AGGREGATION-capable in BEACON
+ if (pAd->CommonCfg.bAggregationCapable)
+ {
+ if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+ else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+ }
+ else
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, 0x00, 0x00, 0x00};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+ if (pAd->MlmeAux.APEdcaParm.bValid)
+ {
+ if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
+ {
+ QBSS_STA_INFO_PARM QosInfo;
+
+ NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
+ QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
+ QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
+ QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
+ QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
+ QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
+ WmeIe[8] |= *(PUCHAR)&QosInfo;
+ }
+ else
+ {
+ // The Parameter Set Count is set to ¡§0¡¨ in the association request frames
+ // WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f);
+ }
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 9, &WmeIe[0],
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ //
+ // Let WPA(#221) Element ID on the end of this association frame.
+ // Otherwise some AP will fail on parsing Element ID and set status fail on Assoc Rsp.
+ // For example: Put Vendor Specific IE on the front of WPA IE.
+ // This happens on AP (Model No:Linksys WRK54G)
+ //
+ if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
+ )
+ )
+ {
+ UCHAR RSNIe = IE_WPA;
+
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
+ {
+ RSNIe = IE_WPA2;
+ }
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifdef SIOCSIWGENIE
+ if (pAd->StaCfg.WpaSupplicantUP != 1)
+#endif // SIOCSIWGENIE //
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
+
+ // Check for WPA PMK cache list
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
+ {
+ INT idx;
+ BOOLEAN FoundPMK = FALSE;
+ // Search chched PMKID, append it if existed
+ for (idx = 0; idx < PMKID_NO; idx++)
+ {
+ if (NdisEqualMemory(ApAddr, &pAd->StaCfg.SavedPMK[idx].BSSID, 6))
+ {
+ FoundPMK = TRUE;
+ break;
+ }
+ }
+
+ if (FoundPMK)
+ {
+ // Set PMK number
+ *(PUSHORT) &pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len] = 1;
+ NdisMoveMemory(&pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len + 2], &pAd->StaCfg.SavedPMK[idx].PMKID, 16);
+ pAd->StaCfg.RSNIE_Len += 18;
+ }
+ }
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifdef SIOCSIWGENIE
+ if (pAd->StaCfg.WpaSupplicantUP == 1)
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
+ END_OF_ARGS);
+ }
+ else
+#endif
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &RSNIe,
+ 1, &pAd->StaCfg.RSNIE_Len,
+ pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
+ END_OF_ARGS);
+ }
+
+ FrameLen += tmp;
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifdef SIOCSIWGENIE
+ if (pAd->StaCfg.WpaSupplicantUP != 1)
+#endif
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ {
+ // Append Variable IE
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->StaCfg.RSNIE_Len, 1);
+ VarIesOffset += 1;
+ }
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
+ VarIesOffset += pAd->StaCfg.RSNIE_Len;
+
+ // Set Variable IEs Length
+ pAd->StaCfg.ReqVarIELen = VarIesOffset;
+ }
+
+ // We have update that at PeerBeaconAtJoinRequest()
+ CkipFlag = pAd->StaCfg.CkipFlag;
+ if (CkipFlag != 0)
+ {
+ NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
+ CkipNegotiationBuffer[2] = 0x66;
+ // Make it try KP & MIC, since we have to follow the result from AssocRsp
+ CkipNegotiationBuffer[8] = 0x18;
+ CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
+ CkipFlag = 0x18;
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &AironetCkipIe,
+ 1, &AironetCkipLen,
+ AironetCkipLen, CkipNegotiationBuffer,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ // Add CCX v2 request if CCX2 admin state is on
+ if (pAd->StaCfg.CCXControl.field.Enable == 1)
+ {
+
+ //
+ // Add AironetIPAddressIE for Cisco CCX 2.X
+ // Add CCX Version
+ //
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &AironetIPAddressIE,
+ 1, &AironetIPAddressLen,
+ AironetIPAddressLen, AironetIPAddressBuffer,
+ 1, &Ccx2Ie,
+ 1, &Ccx2Len,
+ Ccx2Len, Ccx2IeInfo,
+ END_OF_ARGS);
+ FrameLen += tmp;
+
+ //
+ // Add CipherSuite CCKM or LeapTkip if setting.
+ //
+#ifdef LEAP_SUPPORT
+ if (LEAP_CCKM_ON(pAd))
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ CipherSuiteCiscoCCKMLen, CipherSuiteCiscoCCKM,
+ END_OF_ARGS);
+ FrameLen += tmp;
+
+ // Third add RSN
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, CipherSuiteCiscoCCKM, CipherSuiteCiscoCCKMLen); //Save CipherSuite
+ VarIesOffset += CipherSuiteCiscoCCKMLen;
+ }
+ else if ((pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP) && (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled))
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ CipherSuiteCCXTkipLen, CipherSuiteCCXTkip,
+ END_OF_ARGS);
+ FrameLen += tmp;
+
+ // Third add RSN
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, CipherSuiteCCXTkip, CipherSuiteCCXTkipLen);
+ VarIesOffset += CipherSuiteCCXTkipLen;
+ }
+#endif // LEAP_SUPPORT //
+
+ // Add by James 03/06/27
+ // Set Variable IEs Length
+ pAd->StaCfg.ReqVarIELen = VarIesOffset;
+ pAd->StaCfg.AssocInfo.RequestIELength = VarIesOffset;
+
+ // OffsetResponseIEs follow ReqVarIE
+ pAd->StaCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->StaCfg.ReqVarIELen;
+ // End Add by James
+ }
+
+
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ RTMPSetTimer(&pAd->MlmeAux.AssocTimer, Timeout);
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() sanity check failed. BUG!!!!!! \n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_INVALID_FORMAT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+ }
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ mlme reassoc req handling procedure
+ Parameters:
+ Elem -
+ Pre:
+ -# SSID (Adapter->StaCfg.ssid[])
+ -# BSSID (AP address, Adapter->StaCfg.bssid)
+ -# Supported rates (Adapter->StaCfg.supported_rates[])
+ -# Supported rates length (Adapter->StaCfg.supported_rates_len)
+ -# Tx power (Adapter->StaCfg.tx_power)
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeReassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR ApAddr[6];
+ HEADER_802_11 ReassocHdr;
+ UCHAR Ccx2Len = 5;
+ UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
+ USHORT CapabilityInfo, ListenIntv;
+ ULONG Timeout;
+ ULONG FrameLen = 0;
+ BOOLEAN TimerCancelled;
+ NDIS_STATUS NStatus;
+ ULONG tmp;
+ PUCHAR pOutBuffer = NULL;
+//CCX 2.X
+#ifdef LEAP_SUPPORT
+ UCHAR CkipFlag;
+ UCHAR CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
+ UCHAR AironetCkipIe = IE_AIRONET_CKIP;
+ UCHAR AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
+ UCHAR AironetIPAddressIE = IE_AIRONET_IPADDRESS;
+ UCHAR AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
+ UCHAR AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
+ UCHAR AironetCCKMReassocIE = IE_AIRONET_CCKMREASSOC;
+ UCHAR AironetCCKMReassocLen = AIRONET_CCKMREASSOC_LENGTH;
+ UCHAR AironetCCKMReassocBuffer[AIRONET_CCKMREASSOC_LENGTH];
+ UCHAR AironetOUI[] = {0x00, 0x40, 0x96, 0x00};
+ UCHAR MICMN[16];
+ UCHAR CalcMicBuffer[80];
+ ULONG CalcMicBufferLen = 0;
+#endif // LEAP_SUPPORT //
+ USHORT Status;
+
+ // Block all authentication request durning WPA block period
+ if (pAd->StaCfg.bBlockAssoc == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block ReAssoc request durning WPA block period!\n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+ }
+ // the parameters are the same as the association
+ else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
+ {
+ RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() allocate memory failed \n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+ return;
+ }
+
+ COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
+
+ // make frame, use bssid as the AP address??
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send RE-ASSOC request...\n"));
+ MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0, ApAddr, ApAddr);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &ReassocHdr,
+ 2, &CapabilityInfo,
+ 2, &ListenIntv,
+ MAC_ADDR_LEN, ApAddr,
+ 1, &SsidIe,
+ 1, &pAd->MlmeAux.SsidLen,
+ pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
+ 1, &SupRateIe,
+ 1, &pAd->MlmeAux.SupRateLen,
+ pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
+ END_OF_ARGS);
+
+ if (pAd->MlmeAux.ExtRateLen != 0)
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &ExtRateIe,
+ 1, &pAd->MlmeAux.ExtRateLen,
+ pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ if (pAd->MlmeAux.APEdcaParm.bValid)
+ {
+ if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
+ {
+ QBSS_STA_INFO_PARM QosInfo;
+
+ NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
+ QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
+ QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
+ QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
+ QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
+ QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
+ WmeIe[8] |= *(PUCHAR)&QosInfo;
+ }
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 9, &WmeIe[0],
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // HT
+ if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ ULONG TmpLen;
+ UCHAR HtLen;
+ UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+ if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
+ {
+ HtLen = SIZE_HT_CAP_IE + 4;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &HtLen,
+ 4, &BROADCOM[0],
+ pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
+ END_OF_ARGS);
+ }
+ else
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &pAd->MlmeAux.HtCapabilityLen,
+ pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
+ END_OF_ARGS);
+ }
+ FrameLen += TmpLen;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
+ // Case I: (Aggregation + Piggy-Back)
+ // 1. user enable aggregation, AND
+ // 2. Mac support piggy-back
+ // 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
+ // Case II: (Aggregation)
+ // 1. user enable aggregation, AND
+ // 2. AP annouces it's AGGREGATION-capable in BEACON
+ if (pAd->CommonCfg.bAggregationCapable)
+ {
+ if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+ else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+ }
+ else
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x04, 0x00, 0x00, 0x00};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+#ifdef LEAP_SUPPORT
+ if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
+ {
+ CkipFlag = pAd->StaCfg.CkipFlag; // We have update that at PeerBeaconAtJoinRequest()
+ if (CkipFlag != 0)
+ {
+ NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
+ CkipNegotiationBuffer[2] = 0x66;
+ // Make it try KP & MIC, since we have to follow the result from AssocRsp
+ CkipNegotiationBuffer[8] = 0x18;
+ CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &AironetCkipIe,
+ 1, &AironetCkipLen,
+ AironetCkipLen, CkipNegotiationBuffer,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &AironetIPAddressIE,
+ 1, &AironetIPAddressLen,
+ AironetIPAddressLen, AironetIPAddressBuffer,
+ END_OF_ARGS);
+ FrameLen += tmp;
+
+ //
+ // The RN is incremented before each reassociation request.
+ //
+ pAd->StaCfg.CCKMRN++;
+ //
+ // Calculate MIC = hmac-md5(krk, STA-ID|BSSID|RSNIE|TSF|RN);
+ //
+ COPY_MAC_ADDR(CalcMicBuffer, pAd->CurrentAddress);
+ CalcMicBufferLen = MAC_ADDR_LEN;
+ COPY_MAC_ADDR(CalcMicBuffer + CalcMicBufferLen, pAd->MlmeAux.Bssid);
+ CalcMicBufferLen += MAC_ADDR_LEN;
+ NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, CipherSuiteCiscoCCKM, CipherSuiteCiscoCCKMLen);
+ CalcMicBufferLen += CipherSuiteCiscoCCKMLen;
+ NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, (PUCHAR) &pAd->StaCfg.CCKMBeaconAtJoinTimeStamp, sizeof(pAd->StaCfg.CCKMBeaconAtJoinTimeStamp));
+ CalcMicBufferLen += sizeof(pAd->StaCfg.CCKMBeaconAtJoinTimeStamp);
+ NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, (PUCHAR)&pAd->StaCfg.CCKMRN, sizeof(pAd->StaCfg.CCKMRN));
+ CalcMicBufferLen += sizeof(pAd->StaCfg.CCKMRN);
+ hmac_md5(pAd->StaCfg.KRK, LEN_EAP_MICK, CalcMicBuffer, CalcMicBufferLen, MICMN);
+
+ //
+ // fill up CCKM reassociation request element
+ //
+ NdisMoveMemory(AironetCCKMReassocBuffer, AironetOUI, 4);
+ NdisMoveMemory(AironetCCKMReassocBuffer + 4, (PUCHAR)&pAd->StaCfg.CCKMBeaconAtJoinTimeStamp, 8);
+ NdisMoveMemory(AironetCCKMReassocBuffer + 12, (PUCHAR) &pAd->StaCfg.CCKMRN, 4);
+ NdisMoveMemory(AironetCCKMReassocBuffer +16, MICMN, 8);
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &AironetCCKMReassocIE,
+ 1, &AironetCCKMReassocLen,
+ AironetCCKMReassocLen, AironetCCKMReassocBuffer,
+ END_OF_ARGS);
+ FrameLen += tmp;
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ CipherSuiteCiscoCCKMLen,CipherSuiteCiscoCCKM,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+#endif // LEAP_SUPPORT //
+
+ // Add CCX v2 request if CCX2 admin state is on
+ if (pAd->StaCfg.CCXControl.field.Enable == 1)
+ {
+ //
+ // Add CCX Version
+ //
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &Ccx2Ie,
+ 1, &Ccx2Len,
+ Ccx2Len, Ccx2IeInfo,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ RTMPSetTimer(&pAd->MlmeAux.ReassocTimer, Timeout); /* in mSec */
+ pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() sanity check failed. BUG!!!! \n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_INVALID_FORMAT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ Upper layer issues disassoc request
+ Parameters:
+ Elem -
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PMLME_DISASSOC_REQ_STRUCT pDisassocReq;
+ HEADER_802_11 DisassocHdr;
+ PHEADER_802_11 pDisassocHdr;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ NDIS_STATUS NStatus;
+ BOOLEAN TimerCancelled;
+ ULONG Timeout = 0;
+ USHORT Status;
+
+#ifdef QOS_DLS_SUPPORT
+ // send DLS-TEAR_DOWN message,
+ if (pAd->CommonCfg.bDLSCapable)
+ {
+ UCHAR i;
+
+ // tear down local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ }
+ }
+
+ // tear down peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ }
+ }
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ // skip sanity check
+ pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT)(Elem->Msg);
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - MlmeDisassocReqAction() allocate memory failed\n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
+ return;
+ }
+
+
+
+ RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &TimerCancelled);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send DISASSOC request[BSSID::%02x:%02x:%02x:%02x:%02x:%02x (Reason=%d)\n",
+ pDisassocReq->Addr[0], pDisassocReq->Addr[1], pDisassocReq->Addr[2],
+ pDisassocReq->Addr[3], pDisassocReq->Addr[4], pDisassocReq->Addr[5], pDisassocReq->Reason));
+ MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr); // patch peap ttls switching issue
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11),&DisassocHdr,
+ 2, &pDisassocReq->Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+
+ // To patch Instance and Buffalo(N) AP
+ // Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
+ // Therefore, we send both of them.
+ pDisassocHdr = (PHEADER_802_11)pOutBuffer;
+ pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ pAd->StaCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING;
+ COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pDisassocReq->Addr);
+
+ RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout); /* in mSec */
+ pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP;
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+ {
+ union iwreq_data wrqu;
+ //send disassociate event to wpa_supplicant
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ peer sends assoc rsp back
+ Parameters:
+ Elme - MLME message containing the received frame
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerAssocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT CapabilityInfo, Status, Aid;
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
+ UCHAR Addr2[MAC_ADDR_LEN];
+ BOOLEAN TimerCancelled;
+ UCHAR CkipFlag;
+ EDCA_PARM EdcaParm;
+ HT_CAPABILITY_IE HtCapability;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR HtCapabilityLen;
+ UCHAR AddHtInfoLen;
+ UCHAR NewExtChannelOffset = 0xff;
+
+ if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
+ &HtCapability,&AddHtInfo, &HtCapabilityLen,&AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
+ {
+ // The frame is for me ?
+ if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status));
+#ifdef DOT11_N_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():MacTable [%d].AMsduSize = %d. ClientStatusFlags = 0x%lx \n",Elem->Wcid, pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+#endif // DOT11_N_SUPPORT //
+ RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
+ if(Status == MLME_SUCCESS)
+ {
+ UCHAR MaxSupportedRateIn500Kbps = 0;
+ UCHAR idx;
+
+ // supported rates array may not be sorted. sort it and find the maximum rate
+ for (idx=0; idx<SupRateLen; idx++)
+ {
+ if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
+ MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
+ }
+
+ for (idx=0; idx<ExtRateLen; idx++)
+ {
+ if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
+ MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
+ }
+ // go to procedure listed on page 376
+ AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
+ &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
+
+ StaAddMacTableEntry(pAd, &pAd->MacTab.Content[BSSID_WCID], MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo);
+
+ pAd->StaCfg.CkipFlag = CkipFlag;
+ if (CkipFlag & 0x18)
+ {
+ NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
+ NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
+ NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
+ pAd->StaCfg.GIV[0] = RandomByte(pAd);
+ pAd->StaCfg.GIV[1] = RandomByte(pAd);
+ pAd->StaCfg.GIV[2] = RandomByte(pAd);
+ pAd->StaCfg.bCkipOn = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
+ }
+ }
+ else
+ {
+ // Faile on Association, we need to check the status code
+ // Is that a Rogue AP?
+#ifdef LEAP_SUPPORT
+ if ((pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP) && (Status == MLME_ALG_NOT_SUPPORT))
+ { //Possibly Rogue AP
+ RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, pAd->MlmeAux.Bssid, LEAP_REASON_INVALID_AUTH);
+ }
+#endif // LEAP_SUPPORT //
+ }
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerAssocRspAction() sanity check fail\n"));
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ peer sends reassoc rsp
+ Parametrs:
+ Elem - MLME message cntaining the received frame
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerReassocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT CapabilityInfo;
+ USHORT Status;
+ USHORT Aid;
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
+ UCHAR Addr2[MAC_ADDR_LEN];
+ UCHAR CkipFlag;
+ BOOLEAN TimerCancelled;
+ EDCA_PARM EdcaParm;
+ HT_CAPABILITY_IE HtCapability;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR HtCapabilityLen;
+ UCHAR AddHtInfoLen;
+ UCHAR NewExtChannelOffset = 0xff;
+
+ if(PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
+ &HtCapability, &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
+ {
+ if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) // The frame is for me ?
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - receive REASSOC_RSP to me (status=%d)\n", Status));
+ RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
+
+ if(Status == MLME_SUCCESS)
+ {
+ // go to procedure listed on page 376
+ AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
+ &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+ {
+ union iwreq_data wrqu;
+
+ SendAssocIEsToWpaSupplicant(pAd);
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ wext_notify_event_assoc(pAd);
+
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+ }
+
+ //
+ // Cisco Leap CCKM supported Re-association.
+ //
+#ifdef LEAP_SUPPORT
+ if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
+ {
+ if (CCKMAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen) == TRUE)
+ {
+ pAd->StaCfg.CkipFlag = CkipFlag;
+ if (CkipFlag & 0x18)
+ {
+ NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
+ NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
+ NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
+ pAd->StaCfg.GIV[0] = RandomByte(pAd);
+ pAd->StaCfg.GIV[1] = RandomByte(pAd);
+ pAd->StaCfg.GIV[2] = RandomByte(pAd);
+ pAd->StaCfg.bCkipOn = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
+ }
+
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - CCKMAssocRspSanity() sanity check fail\n"));
+ }
+ }
+ else
+#endif // LEAP_SUPPORT //
+ {
+ // CkipFlag is no use for reassociate
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+ }
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerReassocRspAction() sanity check fail\n"));
+ }
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ procedures on IEEE 802.11/1999 p.376
+ Parametrs:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AssocPostProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr2,
+ IN USHORT CapabilityInfo,
+ IN USHORT Aid,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN PEDCA_PARM pEdcaParm,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ IN ADD_HT_INFO_IE *pAddHtInfo) // AP might use this additional ht info IE
+{
+ ULONG Idx;
+
+ pAd->MlmeAux.BssType = BSS_INFRA;
+ COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAddr2);
+ pAd->MlmeAux.Aid = Aid;
+ pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
+#ifdef DOT11_N_SUPPORT
+ // Some HT AP might lost WMM IE. We add WMM ourselves. beacuase HT requires QoS on.
+ if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE))
+ {
+ pEdcaParm->bValid = TRUE;
+ pEdcaParm->Aifsn[0] = 3;
+ pEdcaParm->Aifsn[1] = 7;
+ pEdcaParm->Aifsn[2] = 2;
+ pEdcaParm->Aifsn[3] = 2;
+
+ pEdcaParm->Cwmin[0] = 4;
+ pEdcaParm->Cwmin[1] = 4;
+ pEdcaParm->Cwmin[2] = 3;
+ pEdcaParm->Cwmin[3] = 2;
+
+ pEdcaParm->Cwmax[0] = 10;
+ pEdcaParm->Cwmax[1] = 10;
+ pEdcaParm->Cwmax[2] = 4;
+ pEdcaParm->Cwmax[3] = 3;
+
+ pEdcaParm->Txop[0] = 0;
+ pEdcaParm->Txop[1] = 0;
+ pEdcaParm->Txop[2] = 96;
+ pEdcaParm->Txop[3] = 48;
+
+ }
+#endif // DOT11_N_SUPPORT //
+
+ NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+
+ // filter out un-supported rates
+ pAd->MlmeAux.SupRateLen = SupRateLen;
+ NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
+ RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
+
+ // filter out un-supported rates
+ pAd->MlmeAux.ExtRateLen = ExtRateLen;
+ NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
+ RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
+
+#ifdef DOT11_N_SUPPORT
+ if (HtCapabilityLen > 0)
+ {
+ RTMPCheckHt(pAd, BSSID_WCID, pHtCapability, pAddHtInfo);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> AP.AMsduSize = %d. ClientStatusFlags = 0x%lx \n", pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> (Mmps=%d, AmsduSize=%d, )\n",
+ pAd->MacTab.Content[BSSID_WCID].MmpsMode, pAd->MacTab.Content[BSSID_WCID].AMsduSize));
+#endif // DOT11_N_SUPPORT //
+
+ // Set New WPA information
+ Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel);
+ if (Idx == BSS_NOT_FOUND)
+ {
+ DBGPRINT_ERR(("ASSOC - Can't find BSS after receiving Assoc response\n"));
+ }
+ else
+ {
+ // Init variable
+ pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = 0;
+ NdisZeroMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, MAX_LEN_OF_RSNIE);
+
+ // Store appropriate RSN_IE for WPA SM negotiation later
+ if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAd->ScanTab.BssEntry[Idx].VarIELen != 0))
+ {
+ PUCHAR pVIE;
+ USHORT len;
+ PEID_STRUCT pEid;
+
+ pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs;
+ len = pAd->ScanTab.BssEntry[Idx].VarIELen;
+
+ while (len > 0)
+ {
+ pEid = (PEID_STRUCT) pVIE;
+ // For WPA/WPAPSK
+ if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
+ && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
+ pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
+ DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA SM negotiation \n"));
+ }
+ // For WPA2/WPA2PSK
+ else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
+ && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
+ pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
+ DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA2 SM negotiation \n"));
+ }
+
+ pVIE += (pEid->Len + 2);
+ len -= (pEid->Len + 2);
+ }
+ }
+
+ if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> no RSN_IE \n"));
+ }
+ else
+ {
+ hex_dump("RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ left part of IEEE 802.11/1999 p.374
+ Parameters:
+ Elem - MLME message containing the received frame
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerDisassocAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ USHORT Reason;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction()\n"));
+ if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() Reason = %d\n", Reason));
+ if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, Addr2))
+ {
+
+ if (pAd->CommonCfg.bWirelessEvent)
+ {
+ RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+
+
+#ifdef LEAP_SUPPORT
+ if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+ {
+ // Cisco_LEAP has start a timer
+ // We should cancel it if using LEAP
+ RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &TimerCancelled);
+ //Check is it mach the LEAP Authentication failed as possible a Rogue AP
+ //on it's PortSecured not equal to WPA_802_1X_PORT_SECURED while process the Association.
+ if ((pAd->Mlme.LeapMachine.CurrState != LEAP_IDLE) && (pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
+ {
+ RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_AUTH_TIMEOUT);
+ }
+ }
+#endif // LEAP_SUPPORT //
+ //
+ // Get Current System time and Turn on AdjacentAPReport
+ //
+ NdisGetSystemUpTime(&pAd->StaCfg.CCXAdjacentAPLinkDownTime);
+ pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
+ LinkDown(pAd, TRUE);
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+ {
+ union iwreq_data wrqu;
+ //send disassociate event to wpa_supplicant
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() sanity check fail\n"));
+ }
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ what the state machine will do after assoc timeout
+ Parameters:
+ Elme -
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AssocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - AssocTimeoutAction\n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_REJ_TIMEOUT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ what the state machine will do after reassoc timeout
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID ReassocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - ReassocTimeoutAction\n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_REJ_TIMEOUT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ what the state machine will do after disassoc timeout
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID DisassocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - DisassocTimeoutAction\n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
+}
+
+VOID InvalidStateWhenAssoc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenAssoc(state=%ld), reset ASSOC state machine\n",
+ pAd->Mlme.AssocMachine.CurrState));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+}
+
+VOID InvalidStateWhenReassoc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenReassoc(state=%ld), reset ASSOC state machine\n",
+ pAd->Mlme.AssocMachine.CurrState));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+}
+
+VOID InvalidStateWhenDisassociate(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenDisassoc(state=%ld), reset ASSOC state machine\n",
+ pAd->Mlme.AssocMachine.CurrState));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ right part of IEEE 802.11/1999 page 374
+ Note:
+ This event should never cause ASSOC state machine perform state
+ transition, and has no relationship with CNTL machine. So we separate
+ this routine as a service outside of ASSOC state transition table.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID Cls3errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr)
+{
+ HEADER_802_11 DisassocHdr;
+ PHEADER_802_11 pDisassocHdr;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ NDIS_STATUS NStatus;
+ USHORT Reason = REASON_CLS3ERR;
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Class 3 Error, Send DISASSOC frame\n"));
+ MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, pAd->CommonCfg.Bssid); // patch peap ttls switching issue
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11),&DisassocHdr,
+ 2, &Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+
+ // To patch Instance and Buffalo(N) AP
+ // Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
+ // Therefore, we send both of them.
+ pDisassocHdr = (PHEADER_802_11)pOutBuffer;
+ pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ pAd->StaCfg.DisassocReason = REASON_CLS3ERR;
+ COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr);
+}
+
+ /*
+ ==========================================================================
+ Description:
+ Switch between WEP and CKIP upon new association up.
+ Parameters:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID SwitchBetweenWepAndCkip(
+ IN PRTMP_ADAPTER pAd)
+{
+ int i;
+ SHAREDKEY_MODE_STRUC csr1;
+
+ // if KP is required. change the CipherAlg in hardware shard key table from WEP
+ // to CKIP. else remain as WEP
+ if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10))
+ {
+ // modify hardware key table so that MAC use correct algorithm to decrypt RX
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
+ if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP64)
+ csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP64;
+ else if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP128)
+ csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP128;
+
+ if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP64)
+ csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP64;
+ else if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP128)
+ csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP128;
+
+ if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP64)
+ csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP64;
+ else if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP128)
+ csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP128;
+
+ if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP64)
+ csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP64;
+ else if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP128)
+ csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP128;
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
+
+ // modify software key table so that driver can specify correct algorithm in TXD upon TX
+ for (i=0; i<SHARE_KEY_NUM; i++)
+ {
+ if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP64)
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP64;
+ else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP128)
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP128;
+ }
+ }
+
+ // else if KP NOT inused. change the CipherAlg in hardware shard key table from CKIP
+ // to WEP.
+ else
+ {
+ // modify hardware key table so that MAC use correct algorithm to decrypt RX
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
+ if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP64)
+ csr1.field.Bss0Key0CipherAlg = CIPHER_WEP64;
+ else if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP128)
+ csr1.field.Bss0Key0CipherAlg = CIPHER_WEP128;
+
+ if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP64)
+ csr1.field.Bss0Key1CipherAlg = CIPHER_WEP64;
+ else if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP128)
+ csr1.field.Bss0Key1CipherAlg = CIPHER_WEP128;
+
+ if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP64)
+ csr1.field.Bss0Key2CipherAlg = CIPHER_WEP64;
+ else if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP128)
+ csr1.field.Bss0Key2CipherAlg = CIPHER_WEP128;
+
+ if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP64)
+ csr1.field.Bss0Key3CipherAlg = CIPHER_WEP64;
+ else if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP128)
+ csr1.field.Bss0Key3CipherAlg = CIPHER_WEP128;
+
+ // modify software key table so that driver can specify correct algorithm in TXD upon TX
+ for (i=0; i<SHARE_KEY_NUM; i++)
+ {
+ if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP64)
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP64;
+ else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP128)
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP128;
+ }
+
+ //
+ // On WPA-NONE, must update CipherAlg.
+ // Because the OID_802_11_WEP_STATUS was been set after OID_802_11_ADD_KEY
+ // and CipherAlg will be CIPHER_NONE by Windows ZeroConfig.
+ // So we need to update CipherAlg after connect.
+ //
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ for (i = 0; i < SHARE_KEY_NUM; i++)
+ {
+ if (pAd->SharedKey[BSS0][i].KeyLen != 0)
+ {
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
+ {
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_TKIP;
+ }
+ else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_AES;
+ }
+ }
+ else
+ {
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
+ }
+ }
+
+ csr1.field.Bss0Key0CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+ csr1.field.Bss0Key1CipherAlg = pAd->SharedKey[BSS0][1].CipherAlg;
+ csr1.field.Bss0Key2CipherAlg = pAd->SharedKey[BSS0][2].CipherAlg;
+ csr1.field.Bss0Key3CipherAlg = pAd->SharedKey[BSS0][3].CipherAlg;
+ }
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
+ }
+}
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+VOID SendAssocIEsToWpaSupplicant(
+ IN PRTMP_ADAPTER pAd)
+{
+ union iwreq_data wrqu;
+ unsigned char custom[IW_CUSTOM_MAX] = {0};
+
+ if ((pAd->StaCfg.ReqVarIELen + 17) <= IW_CUSTOM_MAX)
+ {
+ sprintf(custom, "ASSOCINFO_ReqIEs=");
+ NdisMoveMemory(custom+17, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.length = pAd->StaCfg.ReqVarIELen + 17;
+ wrqu.data.flags = RT_REQIE_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
+
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_ASSOCINFO_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen + 17 > MAX_CUSTOM_LEN\n"));
+
+ return;
+}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+int wext_notify_event_assoc(
+ IN RTMP_ADAPTER *pAd)
+{
+ union iwreq_data wrqu;
+ char custom[IW_CUSTOM_MAX] = {0};
+
+#if WIRELESS_EXT > 17
+ if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX)
+ {
+ wrqu.data.length = pAd->StaCfg.ReqVarIELen;
+ memcpy(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
+ wireless_send_event(pAd->net_dev, IWEVASSOCREQIE, &wrqu, custom);
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n"));
+#else
+ if (((pAd->StaCfg.ReqVarIELen*2) + 17) <= IW_CUSTOM_MAX)
+ {
+ UCHAR idx;
+ wrqu.data.length = (pAd->StaCfg.ReqVarIELen*2) + 17;
+ sprintf(custom, "ASSOCINFO(ReqIEs=");
+ for (idx=0; idx<pAd->StaCfg.ReqVarIELen; idx++)
+ sprintf(custom, "%s%02x", custom, pAd->StaCfg.ReqVarIEs[idx]);
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("(pAd->StaCfg.ReqVarIELen*2) + 17 > MAX_CUSTOM_LEN\n"));
+#endif
+
+ return 0;
+
+}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+
+BOOLEAN StaAddMacTableEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN UCHAR MaxSupportedRateIn500Kbps,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ IN USHORT CapabilityInfo)
+{
+ UCHAR MaxSupportedRate = RATE_11;
+
+ if (ADHOC_ON(pAd))
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+
+ switch (MaxSupportedRateIn500Kbps)
+ {
+ case 108: MaxSupportedRate = RATE_54; break;
+ case 96: MaxSupportedRate = RATE_48; break;
+ case 72: MaxSupportedRate = RATE_36; break;
+ case 48: MaxSupportedRate = RATE_24; break;
+ case 36: MaxSupportedRate = RATE_18; break;
+ case 24: MaxSupportedRate = RATE_12; break;
+ case 18: MaxSupportedRate = RATE_9; break;
+ case 12: MaxSupportedRate = RATE_6; break;
+ case 22: MaxSupportedRate = RATE_11; break;
+ case 11: MaxSupportedRate = RATE_5_5; break;
+ case 4: MaxSupportedRate = RATE_2; break;
+ case 2: MaxSupportedRate = RATE_1; break;
+ default: MaxSupportedRate = RATE_11; break;
+ }
+
+ if ((pAd->CommonCfg.PhyMode == PHY_11G) && (MaxSupportedRate < RATE_FIRST_OFDM_RATE))
+ return FALSE;
+
+#ifdef DOT11_N_SUPPORT
+ // 11n only
+ if (((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))&& (HtCapabilityLen == 0))
+ return FALSE;
+#endif // DOT11_N_SUPPORT //
+
+ if (!pEntry)
+ return FALSE;
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ if (pEntry)
+ {
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ if ((MaxSupportedRate < RATE_FIRST_OFDM_RATE) ||
+ (pAd->CommonCfg.PhyMode == PHY_11B))
+ {
+ pEntry->RateLen = 4;
+ if (MaxSupportedRate >= RATE_FIRST_OFDM_RATE)
+ MaxSupportedRate = RATE_11;
+ }
+ else
+ pEntry->RateLen = 12;
+
+ pEntry->MaxHTPhyMode.word = 0;
+ pEntry->MinHTPhyMode.word = 0;
+ pEntry->HTPhyMode.word = 0;
+ pEntry->MaxSupportedRate = MaxSupportedRate;
+ if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->HTPhyMode.field.MODE = MODE_CCK;
+ pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->HTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ }
+ pEntry->CapabilityInfo = CapabilityInfo;
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // If this Entry supports 802.11n, upgrade to HT rate.
+ if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ UCHAR j, bitmask; //k,bitmask;
+ CHAR i;
+
+ if (ADHOC_ON(pAd))
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ if ((pHtCapability->HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pAd->MacTab.fAnyStationNonGF = TRUE;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+ }
+
+ if ((pHtCapability->HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+ {
+ pEntry->MaxHTPhyMode.field.BW= BW_40;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pHtCapability->HtCapInfo.ShortGIfor40));
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(pHtCapability->HtCapInfo.ShortGIfor20));
+ pAd->MacTab.fAnyStation20Only = TRUE;
+ }
+
+ // 3*3
+ if (pAd->MACVersion >= RALINK_2883_VERSION && pAd->MACVersion < RALINK_3070_VERSION)
+ pEntry->MaxHTPhyMode.field.TxBF = pAd->CommonCfg.RegTransmitSetting.field.TxBF;
+
+ // find max fixed rate
+ for (i=23; i>=0; i--) // 3*3
+ {
+ j = i/8;
+ bitmask = (1<<(i-(j*8)));
+ if ((pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j] & bitmask) && (pHtCapability->MCSSet[j] & bitmask))
+ {
+ pEntry->MaxHTPhyMode.field.MCS = i;
+ break;
+ }
+ if (i==0)
+ break;
+ }
+
+
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
+ {
+ // Fix MCS as HT Duplicated Mode
+ pEntry->MaxHTPhyMode.field.BW = 1;
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pEntry->MaxHTPhyMode.field.STBC = 0;
+ pEntry->MaxHTPhyMode.field.ShortGI = 0;
+ pEntry->MaxHTPhyMode.field.MCS = 32;
+ }
+ else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
+ {
+ // STA supports fixed MCS
+ pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ }
+ }
+
+ pEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+ pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity;
+ pEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor;
+ pEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs;
+ pEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize;
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+ if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED);
+ if (pHtCapability->HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (pHtCapability->HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (pHtCapability->HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (pHtCapability->HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (pHtCapability->ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+ }
+ else
+ {
+ pAd->MacTab.fAnyStationIsLegacy = TRUE;
+ }
+
+ NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE));
+#endif // DOT11_N_SUPPORT //
+
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+ pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+
+ // Set asic auto fall back
+ if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+ {
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
+ pEntry->bAutoTxRateSwitch = TRUE;
+ }
+ else
+ {
+ pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ pEntry->bAutoTxRateSwitch = FALSE;
+
+ // If the legacy mode is set, overwrite the transmit setting of this entry.
+ RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+ }
+
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ pEntry->Sst = SST_ASSOC;
+ pEntry->AuthState = AS_AUTH_OPEN;
+ pEntry->AuthMode = pAd->StaCfg.AuthMode;
+ pEntry->WepStatus = pAd->StaCfg.WepStatus;
+
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP)
+ {
+ union iwreq_data wrqu;
+
+ SendAssocIEsToWpaSupplicant(pAd);
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ wext_notify_event_assoc(pAd);
+
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ return TRUE;
+}
+
+
diff --git a/drivers/staging/rt3070/sta/auth.c b/drivers/staging/rt3070/sta/auth.c
new file mode 100644
index 00000000000..032b5df058b
--- /dev/null
+++ b/drivers/staging/rt3070/sta/auth.c
@@ -0,0 +1,475 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ auth.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John 2004-9-3 porting from RT2500
+*/
+#include "../rt_config.h"
+
+/*
+ ==========================================================================
+ Description:
+ authenticate state machine init, including state transition and timer init
+ Parameters:
+ Sm - pointer to the auth state machine
+ Note:
+ The state machine looks like this
+
+ AUTH_REQ_IDLE AUTH_WAIT_SEQ2 AUTH_WAIT_SEQ4
+ MT2_MLME_AUTH_REQ mlme_auth_req_action invalid_state_when_auth invalid_state_when_auth
+ MT2_PEER_AUTH_EVEN drop peer_auth_even_at_seq2_action peer_auth_even_at_seq4_action
+ MT2_AUTH_TIMEOUT Drop auth_timeout_action auth_timeout_action
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+
+void AuthStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(Sm, Trans, MAX_AUTH_STATE, MAX_AUTH_MSG, (STATE_MACHINE_FUNC)Drop, AUTH_REQ_IDLE, AUTH_MACHINE_BASE);
+
+ // the first column
+ StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)MlmeAuthReqAction);
+
+ // the second column
+ StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAuth);
+ StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)PeerAuthRspAtSeq2Action);
+ StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)AuthTimeoutAction);
+
+ // the third column
+ StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAuth);
+ StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)PeerAuthRspAtSeq4Action);
+ StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)AuthTimeoutAction);
+
+ RTMPInitTimer(pAd, &pAd->MlmeAux.AuthTimer, GET_TIMER_FUNCTION(AuthTimeout), pAd, FALSE);
+}
+
+/*
+ ==========================================================================
+ Description:
+ function to be executed at timer thread when auth timer expires
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AuthTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ DBGPRINT(RT_DEBUG_TRACE,("AUTH - AuthTimeout\n"));
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return;
+
+ // send a de-auth to reset AP's state machine (Patch AP-Dir635)
+ if (pAd->Mlme.AuthMachine.CurrState == AUTH_WAIT_SEQ2)
+ Cls2errAction(pAd, pAd->MlmeAux.Bssid);
+
+
+ MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_AUTH_TIMEOUT, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+}
+
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeAuthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr[6];
+ USHORT Alg, Seq, Status;
+ ULONG Timeout;
+ HEADER_802_11 AuthHdr;
+ BOOLEAN TimerCancelled;
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+
+ // Block all authentication request durning WPA block period
+ if (pAd->StaCfg.bBlockAssoc == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Block Auth request durning WPA block period!\n"));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+ }
+ else if(MlmeAuthReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr, &Timeout, &Alg))
+ {
+ // reset timer
+ RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
+ COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr);
+ pAd->MlmeAux.Alg = Alg;
+ Seq = 1;
+ Status = MLME_SUCCESS;
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeAuthReqAction(Alg:%d) allocate memory failed\n", Alg));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#1 (Alg=%d)...\n", Alg));
+ MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr, pAd->MlmeAux.Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11),&AuthHdr,
+ 2, &Alg,
+ 2, &Seq,
+ 2, &Status,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ RTMPSetTimer(&pAd->MlmeAux.AuthTimer, Timeout);
+ pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2;
+ }
+ else
+ {
+ DBGPRINT_ERR(("AUTH - MlmeAuthReqAction() sanity check failed\n"));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_INVALID_FORMAT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerAuthRspAtSeq2Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ USHORT Seq, Status, RemoteStatus, Alg;
+ UCHAR ChlgText[CIPHER_TEXT_LEN];
+ UCHAR CyperChlgText[CIPHER_TEXT_LEN + 8 + 8];
+ UCHAR Element[2];
+ HEADER_802_11 AuthHdr;
+ BOOLEAN TimerCancelled;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ USHORT Status2;
+
+ if (PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText))
+ {
+ if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", Alg, Status));
+ RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
+
+ if (Status == MLME_SUCCESS)
+ {
+ // Authentication Mode "LEAP" has allow for CCX 1.X
+ if ((pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen)
+#ifdef LEAP_SUPPORT
+ || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+ )
+ {
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+#ifdef LEAP_SUPPORT
+ pAd->Mlme.LeapMachine.CurrState = LEAP_IDLE;
+#endif // LEAP_SUPPORT //
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+ }
+ else
+ {
+ // 2. shared key, need to be challenged
+ Seq++;
+ RemoteStatus = MLME_SUCCESS;
+
+ // Get an unused nonpaged memory
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n"));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status2 = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status2);
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#3...\n"));
+ MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2, pAd->MlmeAux.Bssid);
+ AuthHdr.FC.Wep = 1;
+ // Encrypt challenge text & auth information
+ RTMPInitWepEngine(
+ pAd,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen,
+ CyperChlgText);
+
+ Alg = cpu2le16(*(USHORT *)&Alg);
+ Seq = cpu2le16(*(USHORT *)&Seq);
+ RemoteStatus= cpu2le16(*(USHORT *)&RemoteStatus);
+
+ RTMPEncryptData(pAd, (PUCHAR) &Alg, CyperChlgText + 4, 2);
+ RTMPEncryptData(pAd, (PUCHAR) &Seq, CyperChlgText + 6, 2);
+ RTMPEncryptData(pAd, (PUCHAR) &RemoteStatus, CyperChlgText + 8, 2);
+ Element[0] = 16;
+ Element[1] = 128;
+ RTMPEncryptData(pAd, Element, CyperChlgText + 10, 2);
+ RTMPEncryptData(pAd, ChlgText, CyperChlgText + 12, 128);
+ RTMPSetICV(pAd, CyperChlgText + 140);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &AuthHdr,
+ CIPHER_TEXT_LEN + 16, CyperChlgText,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ RTMPSetTimer(&pAd->MlmeAux.AuthTimer, AUTH_TIMEOUT);
+ pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ4;
+ }
+ }
+ else
+ {
+#ifdef LEAP_SUPPORT
+ if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+ {
+ //Invalid Authentication possible rogue AP
+ //Add this Ap to Rogue AP.
+ RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_INVALID_AUTH);
+ }
+#endif // LEAP_SUPPORT //
+ pAd->StaCfg.AuthFailReason = Status;
+ COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+ }
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthSanity() sanity check fail\n"));
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerAuthRspAtSeq4Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ USHORT Alg, Seq, Status;
+ CHAR ChlgText[CIPHER_TEXT_LEN];
+ BOOLEAN TimerCancelled;
+
+ if(PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText))
+ {
+ if(MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 4)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#4 to me\n"));
+ RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
+
+ if (Status != MLME_SUCCESS)
+ {
+ pAd->StaCfg.AuthFailReason = Status;
+ COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
+ }
+
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n"));
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_DEAUTH_REQ_STRUCT *pInfo;
+ HEADER_802_11 DeauthHdr;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ USHORT Status;
+
+ pInfo = (MLME_DEAUTH_REQ_STRUCT *)Elem->Msg;
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeDeauthReqAction() allocate memory fail\n"));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
+ return;
+ }
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send DE-AUTH request (Reason=%d)...\n", pInfo->Reason));
+ MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, pAd->MlmeAux.Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11),&DeauthHdr,
+ 2, &pInfo->Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ pAd->StaCfg.DeauthReason = pInfo->Reason;
+ COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pInfo->Addr);
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
+
+ // send wireless event - for deauthentication
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AuthTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeoutAction\n"));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_REJ_TIMEOUT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID InvalidStateWhenAuth(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - InvalidStateWhenAuth (state=%ld), reset AUTH state machine\n", pAd->Mlme.AuthMachine.CurrState));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Some STA/AP
+ Note:
+ This action should never trigger AUTH state transition, therefore we
+ separate it from AUTH state machine, and make it as a standalone service
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID Cls2errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr)
+{
+ HEADER_802_11 DeauthHdr;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ USHORT Reason = REASON_CLS2ERR;
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Class 2 error, Send DEAUTH frame...\n"));
+ MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAddr, pAd->MlmeAux.Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11),&DeauthHdr,
+ 2, &Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ pAd->StaCfg.DeauthReason = Reason;
+ COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr);
+}
+
+
diff --git a/drivers/staging/rt3070/sta/auth_rsp.c b/drivers/staging/rt3070/sta/auth_rsp.c
new file mode 100644
index 00000000000..f7aa4b99cf5
--- /dev/null
+++ b/drivers/staging/rt3070/sta/auth_rsp.c
@@ -0,0 +1,167 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ auth_rsp.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John 2004-10-1 copy from RT2560
+*/
+#include "../rt_config.h"
+
+/*
+ ==========================================================================
+ Description:
+ authentication state machine init procedure
+ Parameters:
+ Sm - the state machine
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+VOID AuthRspStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTATE_MACHINE Sm,
+ IN STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(Sm, Trans, MAX_AUTH_RSP_STATE, MAX_AUTH_RSP_MSG, (STATE_MACHINE_FUNC)Drop, AUTH_RSP_IDLE, AUTH_RSP_MACHINE_BASE);
+
+ // column 1
+ StateMachineSetAction(Sm, AUTH_RSP_IDLE, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
+
+ // column 2
+ StateMachineSetAction(Sm, AUTH_RSP_WAIT_CHAL, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
+
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID PeerAuthSimpleRspGenAndSend(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHdr80211,
+ IN USHORT Alg,
+ IN USHORT Seq,
+ IN USHORT Reason,
+ IN USHORT Status)
+{
+ HEADER_802_11 AuthHdr;
+ ULONG FrameLen = 0;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+
+ if (Reason != MLME_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Peer AUTH fail...\n"));
+ return;
+ }
+
+ //Get an unused nonpaged memory
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Send AUTH response (seq#2)...\n"));
+ MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, pHdr80211->Addr2, pAd->MlmeAux.Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &AuthHdr,
+ 2, &Alg,
+ 2, &Seq,
+ 2, &Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID PeerDeauthAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PMLME_QUEUE_ELEM Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ USHORT Reason;
+
+ if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
+ {
+ if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n", Reason));
+
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+
+ // send wireless event - for deauthentication
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+ LinkDown(pAd, TRUE);
+
+ // Authentication Mode Cisco_LEAP has start a timer
+ // We should cancel it if using LEAP
+#ifdef LEAP_SUPPORT
+ if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+ {
+ RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &TimerCancelled);
+ //Check is it mach the LEAP Authentication failed as possible a Rogue AP
+ //on it's PortSecured not equal to WPA_802_1X_PORT_SECURED while process the Authenticaton.
+ if ((pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED) && (pAd->Mlme.LeapMachine.CurrState != LEAP_IDLE))
+ {
+ RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_AUTH_TIMEOUT);
+ }
+ }
+#endif // LEAP_SUPPORT //
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - PeerDeauthAction() sanity check fail\n"));
+ }
+}
+
diff --git a/drivers/staging/rt3070/sta/connect.c b/drivers/staging/rt3070/sta/connect.c
new file mode 100644
index 00000000000..152c0bd0f82
--- /dev/null
+++ b/drivers/staging/rt3070/sta/connect.c
@@ -0,0 +1,2857 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ connect.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John 2004-08-08 Major modification from RT2560
+*/
+#include "../rt_config.h"
+
+UCHAR CipherSuiteWpaNoneTkip[] = {
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x50, 0xf2, 0x02, // Multicast
+ 0x01, 0x00, // Number of unicast
+ 0x00, 0x50, 0xf2, 0x02, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x50, 0xf2, 0x00 // authentication
+ };
+UCHAR CipherSuiteWpaNoneTkipLen = (sizeof(CipherSuiteWpaNoneTkip) / sizeof(UCHAR));
+
+UCHAR CipherSuiteWpaNoneAes[] = {
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x50, 0xf2, 0x04, // Multicast
+ 0x01, 0x00, // Number of unicast
+ 0x00, 0x50, 0xf2, 0x04, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x50, 0xf2, 0x00 // authentication
+ };
+UCHAR CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(UCHAR));
+
+// The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS,
+// or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS
+// All settings successfuly negotiated furing MLME state machines become final settings
+// and are copied to pAd->StaActive
+#define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
+{ \
+ (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen; \
+ NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
+ COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid); \
+ (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel; \
+ (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel; \
+ (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid; \
+ (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin; \
+ (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo; \
+ (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod; \
+ (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration; \
+ (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod; \
+ (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen; \
+ NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
+ (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen; \
+ NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
+ NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));\
+ NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));\
+ NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));\
+ COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid); \
+ (_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid; \
+ (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
+ COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
+ (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+*/
+VOID MlmeCntlInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ // Control state machine differs from other state machines, the interface
+ // follows the standard interface
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID MlmeCntlMachinePerformAction(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ switch(pAd->Mlme.CntlMachine.CurrState)
+ {
+ case CNTL_IDLE:
+ {
+ CntlIdleProc(pAd, Elem);
+ }
+ break;
+ case CNTL_WAIT_DISASSOC:
+ CntlWaitDisassocProc(pAd, Elem);
+ break;
+ case CNTL_WAIT_JOIN:
+ CntlWaitJoinProc(pAd, Elem);
+ break;
+
+ // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
+ // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
+ // Therefore not protected by NDIS's "only one outstanding OID request"
+ // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
+ // Current approach is to block new SET request at RTMPSetInformation()
+ // when CntlMachine.CurrState is not CNTL_IDLE
+ case CNTL_WAIT_REASSOC:
+ CntlWaitReassocProc(pAd, Elem);
+ break;
+
+ case CNTL_WAIT_START:
+ CntlWaitStartProc(pAd, Elem);
+ break;
+ case CNTL_WAIT_AUTH:
+ CntlWaitAuthProc(pAd, Elem);
+ break;
+ case CNTL_WAIT_AUTH2:
+ CntlWaitAuthProc2(pAd, Elem);
+ break;
+ case CNTL_WAIT_ASSOC:
+ CntlWaitAssocProc(pAd, Elem);
+ break;
+
+ case CNTL_WAIT_OID_LIST_SCAN:
+ if(Elem->MsgType == MT2_SCAN_CONF)
+ {
+ // Resume TxRing after SCANING complete. We hope the out-of-service time
+ // won't be too long to let upper layer time-out the waiting frames
+ RTMPResumeMsduTransmission(pAd);
+ if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
+ {
+ // Cisco scan request is finished, prepare beacon report
+ MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
+ }
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+
+ //
+ // Set LED status to previous status.
+ //
+ if (pAd->bLedOnScanning)
+ {
+ pAd->bLedOnScanning = FALSE;
+ RTMPSetLED(pAd, pAd->LedStatus);
+ }
+#ifdef DOT11N_DRAFT3
+ // AP sent a 2040Coexistence mgmt frame, then station perform a scan, and then send back the respone.
+ if (pAd->CommonCfg.BSSCoexist2040.field.InfoReq == 1)
+ {
+ Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
+ }
+#endif // DOT11N_DRAFT3 //
+ }
+ break;
+
+ case CNTL_WAIT_OID_DISASSOC:
+ if (Elem->MsgType == MT2_DISASSOC_CONF)
+ {
+ LinkDown(pAd, FALSE);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ }
+ break;
+#ifdef RT2870
+ //
+ // This state is for that we want to connect to an AP but
+ // it didn't find on BSS List table. So we need to scan the air first,
+ // after that we can try to connect to the desired AP if available.
+ //
+ case CNTL_WAIT_SCAN_FOR_CONNECT:
+ if(Elem->MsgType == MT2_SCAN_CONF)
+ {
+ // Resume TxRing after SCANING complete. We hope the out-of-service time
+ // won't be too long to let upper layer time-out the waiting frames
+ RTMPResumeMsduTransmission(pAd);
+#ifdef CCX_SUPPORT
+ if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
+ {
+ // Cisco scan request is finished, prepare beacon report
+ MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
+ }
+#endif // CCX_SUPPORT //
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+
+ //
+ // Check if we can connect to.
+ //
+ BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+ if (pAd->MlmeAux.SsidBssTab.BssNr > 0)
+ {
+ MlmeAutoReconnectLastSSID(pAd);
+ }
+ }
+ break;
+#endif // RT2870 //
+ default:
+ DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
+ break;
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlIdleProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_DISASSOC_REQ_STRUCT DisassocReq;
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+ return;
+
+ switch(Elem->MsgType)
+ {
+ case OID_802_11_SSID:
+ CntlOidSsidProc(pAd, Elem);
+ break;
+
+ case OID_802_11_BSSID:
+ CntlOidRTBssidProc(pAd,Elem);
+ break;
+
+ case OID_802_11_BSSID_LIST_SCAN:
+ CntlOidScanProc(pAd,Elem);
+ break;
+
+ case OID_802_11_DISASSOCIATE:
+#ifdef RALINK_ATE
+ if(ATE_ON(pAd))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+ break;
+ }
+#endif // RALINK_ATE //
+ DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ // Set the AutoReconnectSsid to prevent it reconnect to old SSID
+ // Since calling this indicate user don't want to connect to that SSID anymore.
+ pAd->MlmeAux.AutoReconnectSsidLen= 32;
+ NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+ }
+ break;
+
+ case MT2_MLME_ROAMING_REQ:
+ CntlMlmeRoamingProc(pAd, Elem);
+ break;
+
+ case OID_802_11_MIC_FAILURE_REPORT_FRAME:
+ WpaMicFailureReportFrame(pAd, Elem);
+ break;
+
+#ifdef QOS_DLS_SUPPORT
+ case RT_OID_802_11_SET_DLS_PARAM:
+ CntlOidDLSSetupProc(pAd, Elem);
+ break;
+#endif // QOS_DLS_SUPPORT //
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
+ break;
+ }
+}
+
+VOID CntlOidScanProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_SCAN_REQ_STRUCT ScanReq;
+ ULONG BssIdx = BSS_NOT_FOUND;
+ BSS_ENTRY CurrBss;
+
+#ifdef RALINK_ATE
+/* Disable scanning when ATE is running. */
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+
+ // record current BSS if network is connected.
+ // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
+ if (BssIdx != BSS_NOT_FOUND)
+ {
+ NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
+ }
+ }
+
+ // clean up previous SCAN result, add current BSS back to table if any
+ BssTableInit(&pAd->ScanTab);
+ if (BssIdx != BSS_NOT_FOUND)
+ {
+ // DDK Note: If the NIC is associated with a particular BSSID and SSID
+ // that are not contained in the list of BSSIDs generated by this scan, the
+ // BSSID description of the currently associated BSSID and SSID should be
+ // appended to the list of BSSIDs in the NIC's database.
+ // To ensure this, we append this BSS as the first entry in SCAN result
+ NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
+ pAd->ScanTab.BssNr = 1;
+ }
+
+ ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
+ sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Before calling this routine, user desired SSID should already been
+ recorded in CommonCfg.Ssid[]
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlOidSsidProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM * Elem)
+{
+ PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
+ MLME_DISASSOC_REQ_STRUCT DisassocReq;
+ ULONG Now;
+
+ // Step 1. record the desired user settings to MlmeAux
+ NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
+ pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
+ NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+ pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
+
+
+ //
+ // Update Reconnect Ssid, that user desired to connect.
+ //
+ NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+ pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
+
+ // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
+ // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
+ BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
+ pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
+ NdisGetSystemUpTime(&Now);
+
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
+ (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
+ NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
+ MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
+ {
+ // Case 1. already connected with an AP who has the desired SSID
+ // with highest RSSI
+
+ // Add checking Mode "LEAP" for CCX 1.0
+ if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+#ifdef LEAP_SUPPORT
+ || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+ ) &&
+ (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ {
+ // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
+ // connection process
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
+ DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+ sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+ }
+ else if (pAd->bConfigChanged == TRUE)
+ {
+ // case 1.2 Important Config has changed, we have to reconnect to the same AP
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
+ DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+ sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+ }
+ else
+ {
+ // case 1.3. already connected to the SSID with highest RSSI.
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
+ //
+ // (HCT 12.1) 1c_wlan_mediaevents required
+ // media connect events are indicated when associating with the same AP
+ //
+ if (INFRA_ON(pAd))
+ {
+ //
+ // Since MediaState already is NdisMediaStateConnected
+ // We just indicate the connect event again to meet the WHQL required.
+ //
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
+ }
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ }
+ }
+ else if (INFRA_ON(pAd))
+ {
+ //
+ // For RT61
+ // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
+ // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
+ // But media status is connected, so the SSID not report correctly.
+ //
+ if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
+ {
+ //
+ // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
+ //
+ pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
+ }
+ // case 2. active INFRA association existent
+ // roaming is done within miniport driver, nothing to do with configuration
+ // utility. so upon a new SET(OID_802_11_SSID) is received, we just
+ // disassociate with the current associated AP,
+ // then perform a new association with this new SSID, no matter the
+ // new/old SSID are the same or not.
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
+ DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+ sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+ }
+ else
+ {
+ if (ADHOC_ON(pAd))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
+ LinkDown(pAd, FALSE);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
+ }
+
+ if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
+ (pAd->StaCfg.bAutoReconnect == TRUE) &&
+ (pAd->MlmeAux.BssType == BSS_INFRA) &&
+ (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
+ )
+ {
+ MLME_SCAN_REQ_STRUCT ScanReq;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
+ ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+ // Reset Missed scan number
+ pAd->StaCfg.LastScanTime = Now;
+ }
+ else
+ {
+ pAd->MlmeAux.BssIdx = 0;
+ IterateOnBssTab(pAd);
+ }
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlOidRTBssidProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM * Elem)
+{
+ ULONG BssIdx;
+ PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
+ MLME_DISASSOC_REQ_STRUCT DisassocReq;
+ MLME_JOIN_REQ_STRUCT JoinReq;
+
+#ifdef RALINK_ATE
+/* No need to perform this routine when ATE is running. */
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ // record user desired settings
+ COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
+ pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
+
+ //
+ // Update Reconnect Ssid, that user desired to connect.
+ //
+ NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
+ pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
+ NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+
+ // find the desired BSS in the latest SCAN result table
+ BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
+ if (BssIdx == BSS_NOT_FOUND)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ return;
+ }
+
+ // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
+ // Because we need this entry to become the JOIN target in later on SYNC state machine
+ pAd->MlmeAux.BssIdx = 0;
+ pAd->MlmeAux.SsidBssTab.BssNr = 1;
+ NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
+
+ //pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
+ //NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
+
+ // Add SSID into MlmeAux for site surey joining hidden SSID
+ //pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
+ //NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen);
+
+ // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
+ // we just follow normal procedure. The reason of user doing this may because he/she changed
+ // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
+ // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
+ // checking, we'll disassociate then re-do normal association with this AP at the new channel.
+ // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
+ // connection when setting the same BSSID.
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
+ MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
+ {
+ // already connected to the same BSSID, go back to idle state directly
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ }
+ else
+ {
+ if (INFRA_ON(pAd))
+ {
+ // disassoc from current AP first
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
+ DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+ sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+ }
+ else
+ {
+ if (ADHOC_ON(pAd))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
+ LinkDown(pAd, FALSE);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+ DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
+ }
+
+ // Change the wepstatus to original wepstatus
+ pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
+ pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
+ pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
+
+ // Check cipher suite, AP must have more secured cipher than station setting
+ // Set the Pairwise and Group cipher to match the intended AP setting
+ // We can only connect to AP with less secured cipher setting
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
+
+ if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
+ pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
+ else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
+ pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
+ else // There is no PairCipher Aux, downgrade our capability to TKIP
+ pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
+
+ if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
+ pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
+ else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
+ pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
+ else // There is no PairCipher Aux, downgrade our capability to TKIP
+ pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+
+ // RSN capability
+ pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
+ }
+
+ // Set Mix cipher flag
+ pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
+ if (pAd->StaCfg.bMixCipher == TRUE)
+ {
+ // If mix cipher, re-build RSNIE
+ RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
+ }
+ // No active association, join the BSS immediately
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
+ pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
+
+ JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
+ }
+ }
+}
+
+// Roaming is the only external request triggering CNTL state machine
+// despite of other "SET OID" operation. All "SET OID" related oerations
+// happen in sequence, because no other SET OID will be sent to this device
+// until the the previous SET operation is complete (successful o failed).
+// So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
+// or been corrupted by other "SET OID"?
+//
+// IRQL = DISPATCH_LEVEL
+VOID CntlMlmeRoamingProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ // TODO:
+ // AP in different channel may show lower RSSI than actual value??
+ // should we add a weighting factor to compensate it?
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
+
+ NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
+ pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
+
+ BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
+ pAd->MlmeAux.BssIdx = 0;
+ IterateOnBssTab(pAd);
+}
+
+#ifdef QOS_DLS_SUPPORT
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlOidDLSSetupProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PRT_802_11_DLS pDLS = (PRT_802_11_DLS)Elem->Msg;
+ MLME_DLS_REQ_STRUCT MlmeDlsReq;
+ INT i;
+ USHORT reason = REASON_UNSPECIFY;
+
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n",
+ pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5],
+ pDLS->Valid, pDLS->Status, pDLS->TimeOut, pDLS->CountDownTimer));
+
+ if (!pAd->CommonCfg.bDLSCapable)
+ return;
+
+ // DLS will not be supported when Adhoc mode
+ if (INFRA_ON(pAd))
+ {
+ for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
+ (pDLS->TimeOut == pAd->StaCfg.DLSEntry[i].TimeOut) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ // 1. Same setting, just drop it
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - setting unchanged\n"));
+ break;
+ }
+ else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
+ MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ // 2. Disable DLS link case, just tear down DLS link
+ reason = REASON_QOS_UNWANTED_MECHANISM;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - start tear down procedure\n"));
+ break;
+ }
+ else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && !pAd->StaCfg.DLSEntry[i].Valid)
+ {
+ // 3. Enable case, start DLS setup procedure
+ NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
+
+ //Update countdown timer
+ pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS setup case\n"));
+ break;
+ }
+ else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
+ (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && !MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ // 4. update mac case, tear down old DLS and setup new DLS
+ reason = REASON_QOS_UNWANTED_MECHANISM;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS tear down and restart case\n"));
+ break;
+ }
+ else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
+ MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr) && (pAd->StaCfg.DLSEntry[i].TimeOut != pDLS->TimeOut))
+ {
+ // 5. update timeout case, start DLS setup procedure (no tear down)
+ pAd->StaCfg.DLSEntry[i].TimeOut = pDLS->TimeOut;
+ //Update countdown timer
+ pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS update timeout case\n"));
+ break;
+ }
+ else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
+ (pAd->StaCfg.DLSEntry[i].Status != DLS_FINISH) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ // 6. re-setup case, start DLS setup procedure (no tear down)
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS retry setup procedure\n"));
+ break;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN,("CNTL - DLS not changed in entry - %d - Valid=%d, Status=%d, TimeOut=%d\n",
+ i, pAd->StaCfg.DLSEntry[i].Valid, pAd->StaCfg.DLSEntry[i].Status, pAd->StaCfg.DLSEntry[i].TimeOut));
+ }
+ }
+ }
+}
+#endif // QOS_DLS_SUPPORT //
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitDisassocProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_START_REQ_STRUCT StartReq;
+
+ if (Elem->MsgType == MT2_DISASSOC_CONF)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
+
+ if (pAd->CommonCfg.bWirelessEvent)
+ {
+ RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+
+ LinkDown(pAd, FALSE);
+
+ // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
+ if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
+ StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
+ }
+ // case 2. try each matched BSS
+ else
+ {
+ pAd->MlmeAux.BssIdx = 0;
+
+ IterateOnBssTab(pAd);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitJoinProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Reason;
+ MLME_AUTH_REQ_STRUCT AuthReq;
+
+ if (Elem->MsgType == MT2_JOIN_CONF)
+ {
+ NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
+ if (Reason == MLME_SUCCESS)
+ {
+ // 1. joined an IBSS, we are pretty much done here
+ if (pAd->MlmeAux.BssType == BSS_ADHOC)
+ {
+ //
+ // 5G bands rules of Japan:
+ // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
+ //
+ if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
+ RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
+ )
+ {
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
+ return;
+ }
+
+ LinkUp(pAd, BSS_ADHOC);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
+ pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
+ pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
+
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ pAd->ExtraInfo = GENERAL_LINK_UP;
+ }
+ // 2. joined a new INFRA network, start from authentication
+ else
+ {
+#ifdef LEAP_SUPPORT
+ // Add AuthMode "LEAP" for CCX 1.X
+ if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+ {
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
+ }
+ else
+#endif // LEAP_SUPPORT //
+ {
+ // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
+ {
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
+ }
+ else
+ {
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
+ }
+ }
+ MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
+ sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
+ }
+ }
+ else
+ {
+ // 3. failed, try next BSS
+ pAd->MlmeAux.BssIdx++;
+ IterateOnBssTab(pAd);
+ }
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitStartProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Result;
+
+ if (Elem->MsgType == MT2_START_CONF)
+ {
+ NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
+ if (Result == MLME_SUCCESS)
+ {
+ //
+ // 5G bands rules of Japan:
+ // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
+ //
+ if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
+ RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
+ )
+ {
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
+ return;
+ }
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ {
+ N_ChannelCheck(pAd);
+ SetCommonHT(pAd);
+ NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
+ RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
+ pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
+ NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
+ NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
+ COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
+
+ if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
+ {
+ pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
+ }
+ else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
+ {
+ pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
+ }
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+ }
+ LinkUp(pAd, BSS_ADHOC);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ // Before send beacon, driver need do radar detection
+ if ((pAd->CommonCfg.Channel > 14 )
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+ {
+ pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
+ pAd->CommonCfg.RadarDetect.RDCount = 0;
+#ifdef DFS_SUPPORT
+ BbpRadarDetectionStart(pAd);
+#endif // DFS_SUPPORT //
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
+ pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
+ pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitAuthProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Reason;
+ MLME_ASSOC_REQ_STRUCT AssocReq;
+ MLME_AUTH_REQ_STRUCT AuthReq;
+
+ if (Elem->MsgType == MT2_AUTH_CONF)
+ {
+ NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
+ if (Reason == MLME_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
+ AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
+ ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
+
+#ifdef LEAP_SUPPORT
+ //
+ // Cisco Leap CCKM supported Re-association.
+ //
+ if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
+ {
+ //if CCKM is turn on , that's mean Fast Reauthentication
+ //Use CCKM Reassociation instead of normal association for Fast Roaming.
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
+ sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
+ }
+ else
+#endif // LEAP_SUPPORT //
+ {
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
+ sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
+ }
+ }
+ else
+ {
+ // This fail may because of the AP already keep us in its MAC table without
+ // ageing-out. The previous authentication attempt must have let it remove us.
+ // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
+#ifdef LEAP_SUPPORT
+ //Add AuthMode "LEAP" for CCX 1.X
+ if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+ {
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
+ }
+ else
+#endif // LEAP_SUPPORT //
+ {
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
+ {
+ // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
+ }
+ else
+ {
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
+ }
+ }
+ MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
+ sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitAuthProc2(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Reason;
+ MLME_ASSOC_REQ_STRUCT AssocReq;
+ MLME_AUTH_REQ_STRUCT AuthReq;
+
+ if (Elem->MsgType == MT2_AUTH_CONF)
+ {
+ NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
+ if (Reason == MLME_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
+ AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
+ ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
+ sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
+ }
+ else
+ {
+#ifdef LEAP_SUPPORT
+ // Process LEAP first, since it use different control variable
+ // We don't want to affect other poven operation
+ if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+ {
+ // LEAP Auth not success, try next BSS
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ pAd->MlmeAux.BssIdx++;
+ IterateOnBssTab(pAd);
+ }
+ else
+#endif // LEAP_SUPPORT //
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
+ (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
+ MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
+ sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
+ }
+ else
+ {
+ // not success, try next BSS
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
+ pAd->MlmeAux.BssIdx++;
+ IterateOnBssTab(pAd);
+ }
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitAssocProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Reason;
+
+ if (Elem->MsgType == MT2_ASSOC_CONF)
+ {
+ NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
+ if (Reason == MLME_SUCCESS)
+ {
+ LinkUp(pAd, BSS_INFRA);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
+
+ if (pAd->CommonCfg.bWirelessEvent)
+ {
+ RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+ }
+ else
+ {
+ // not success, try next BSS
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
+ pAd->MlmeAux.BssIdx++;
+ IterateOnBssTab(pAd);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitReassocProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Result;
+
+ if (Elem->MsgType == MT2_REASSOC_CONF)
+ {
+ NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
+ if (Result == MLME_SUCCESS)
+ {
+ //
+ // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
+ //
+ LinkUp(pAd, BSS_INFRA);
+
+ // send wireless event - for association
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+
+#ifdef LEAP_SUPPORT
+ if (LEAP_CCKM_ON(pAd))
+ {
+ STA_PORT_SECURED(pAd);
+ pAd->StaCfg.WpaState = SS_FINISH;
+ }
+#endif // LEAP_SUPPORT //
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
+ }
+ else
+ {
+ // reassoc failed, try to pick next BSS in the BSS Table
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
+ pAd->MlmeAux.RoamIdx++;
+ IterateOnBssTab2(pAd);
+ }
+ }
+}
+
+
+VOID AdhocTurnOnQos(
+ IN PRTMP_ADAPTER pAd)
+{
+#define AC0_DEF_TXOP 0
+#define AC1_DEF_TXOP 0
+#define AC2_DEF_TXOP 94
+#define AC3_DEF_TXOP 47
+
+ // Turn on QOs if use HT rate.
+ if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
+ {
+ pAd->CommonCfg.APEdcaParm.bValid = TRUE;
+ pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
+ pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
+ pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
+ pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
+
+ pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
+ pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
+ pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
+ pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
+
+ pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
+ pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
+ pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
+ pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
+
+ pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
+ pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
+ pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
+ pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
+ }
+ AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID LinkUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssType)
+{
+ ULONG Now;
+ UINT32 Data;
+ BOOLEAN Cancelled;
+ UCHAR Value = 0, idx;
+ MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
+
+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
+
+ //
+ // ASSOC - DisassocTimeoutAction
+ // CNTL - Dis-associate successful
+ // !!! LINK DOWN !!!
+ // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
+ //
+ // To prevent DisassocTimeoutAction to call Link down after we link up,
+ // cancel the DisassocTimer no matter what it start or not.
+ //
+ RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
+
+ COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
+
+#ifdef DOT11_N_SUPPORT
+ COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
+#endif // DOT11_N_SUPPORT //
+ // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
+ // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
+ // to examine if cipher algorithm switching is required.
+ //rt2860b. Don't know why need this
+ SwitchBetweenWepAndCkip(pAd);
+
+
+ if (BssType == BSS_ADHOC)
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
+ {
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
+ }
+ else if ((pAd->CommonCfg.Channel > 2) &&
+ (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
+ {
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
+ }
+#endif // DOT11_N_SUPPORT //
+
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+ // No carrier detection when adhoc
+ // CarrierDetectionStop(pAd);
+ pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL;
+#endif // CARRIER_DETECTION_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ AdhocTurnOnQos(pAd);
+#endif // DOT11_N_SUPPORT //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
+ }
+ else
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
+ }
+
+ // 3*3
+ // reset Tx beamforming bit
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x01);
+ Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+#ifdef DOT11_N_SUPPORT
+ // Change to AP channel
+ if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ // Must using 40MHz.
+ pAd->CommonCfg.BBPCurrentBW = BW_40;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x18);
+ Value |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+ // RX : control channel at lower
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+ Value &= (~0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+ Data &= 0xfffffffe;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
+ }
+ else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ // Must using 40MHz.
+ pAd->CommonCfg.BBPCurrentBW = BW_40;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x18);
+ Value |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+ Data |= 0x1;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+ Value |= (0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ pAd->CommonCfg.BBPCurrentBW = BW_20;
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+ Data &= 0xfffffffe;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+ Value &= (~0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
+ }
+
+ RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
+ //
+ // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
+ //
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
+ BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
+
+#ifdef DOT11_N_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
+#endif // DOT11_N_SUPPORT //
+
+ AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
+
+ AsicSetSlotTime(pAd, TRUE);
+ AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
+
+ // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
+ AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
+ {
+ // Update HT protectionfor based on AP's operating mode.
+ if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
+ {
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
+ }
+ else
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
+ }
+#endif // DOT11_N_SUPPORT //
+
+ NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
+
+ NdisGetSystemUpTime(&Now);
+ pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
+
+ if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
+ CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
+ {
+ MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
+ }
+
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+
+ if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
+ {
+#ifdef DFS_SUPPORT
+ RadarDetectionStop(pAd);
+#endif // DFS_SUPPORT //
+ }
+ pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
+
+ if (BssType == BSS_ADHOC)
+ {
+ MakeIbssBeacon(pAd);
+ if ((pAd->CommonCfg.Channel > 14)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+ {
+ ; //Do nothing
+ }
+ else
+ {
+ AsicEnableIbssSync(pAd);
+ }
+
+ // In ad hoc mode, use MAC table from index 1.
+ // p.s ASIC use all 0xff as termination of WCID table search.To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here.
+ RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
+ RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
+
+ // If WEP is enabled, add key material and cipherAlg into Asic
+ // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
+
+ if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
+ {
+ PUCHAR Key;
+ UCHAR CipherAlg;
+
+ for (idx=0; idx < SHARE_KEY_NUM; idx++)
+ {
+ CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
+ Key = pAd->SharedKey[BSS0][idx].Key;
+
+ if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
+ {
+ // Set key material and cipherAlg to Asic
+ AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
+
+ if (idx == pAd->StaCfg.DefaultKeyId)
+ {
+ // Update WCID attribute table and IVEIV table for this group key table
+ RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
+ }
+ }
+
+
+ }
+ }
+ // If WPANone is enabled, add key material and cipherAlg into Asic
+ // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
+ else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ pAd->StaCfg.DefaultKeyId = 0; // always be zero
+
+ NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
+
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ {
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
+ }
+
+ // Decide its ChiperAlg
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+ }
+
+ // Set key material and cipherAlg to Asic
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pAd->SharedKey[BSS0][0].Key,
+ pAd->SharedKey[BSS0][0].TxMic,
+ pAd->SharedKey[BSS0][0].RxMic);
+
+ // Update WCID attribute table and IVEIV table for this group key table
+ RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
+
+ }
+
+ }
+ else // BSS_INFRA
+ {
+ // Check the new SSID with last SSID
+ while (Cancelled == TRUE)
+ {
+ if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
+ {
+ if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
+ {
+ // Link to the old one no linkdown is required.
+ break;
+ }
+ }
+ // Send link down event before set to link up
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+ DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
+ break;
+ }
+
+ //
+ // On WPA mode, Remove All Keys if not connect to the last BSSID
+ // Key will be set after 4-way handshake.
+ //
+ if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
+ {
+ ULONG IV;
+
+ // Remove all WPA keys
+ RTMPWPARemoveAllKeys(pAd);
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+
+ // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
+ // If IV related values are too large in GroupMsg2, AP would ignore this message.
+ IV = 0;
+ IV |= (pAd->StaCfg.DefaultKeyId << 30);
+ AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
+ }
+ // NOTE:
+ // the decision of using "short slot time" or not may change dynamically due to
+ // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
+
+ // NOTE:
+ // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
+ // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
+
+ ComposePsPoll(pAd);
+ ComposeNullFrame(pAd);
+
+ AsicEnableBssSync(pAd);
+
+ // Add BSSID to WCID search table
+ AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ // add this BSSID entry into HASH table
+ {
+ UCHAR HashIdx;
+
+ //pEntry = &pAd->MacTab.Content[BSSID_WCID];
+ HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
+ if (pAd->MacTab.Hash[HashIdx] == NULL)
+ {
+ pAd->MacTab.Hash[HashIdx] = pEntry;
+ }
+ else
+ {
+ pCurrEntry = pAd->MacTab.Hash[HashIdx];
+ while (pCurrEntry->pNext != NULL)
+ pCurrEntry = pCurrEntry->pNext;
+ pCurrEntry->pNext = pEntry;
+ }
+ }
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+
+ // If WEP is enabled, add paiewise and shared key
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (((pAd->StaCfg.WpaSupplicantUP)&&
+ (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
+ (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
+ ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
+ (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
+#else
+ if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ PUCHAR Key;
+ UCHAR CipherAlg;
+
+ for (idx=0; idx < SHARE_KEY_NUM; idx++)
+ {
+ CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
+ Key = pAd->SharedKey[BSS0][idx].Key;
+
+ if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
+ {
+ // Set key material and cipherAlg to Asic
+ AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
+
+ if (idx == pAd->StaCfg.DefaultKeyId)
+ {
+ // Assign group key info
+ RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
+
+ // Assign pairwise key info
+ RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
+ }
+ }
+ }
+ }
+
+ // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
+ // should wait until at least 2 active nodes in this BSSID.
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+
+ // For GUI ++
+ if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
+ {
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ pAd->ExtraInfo = GENERAL_LINK_UP;
+ RTMP_IndicateMediaState(pAd);
+ }
+ // --
+
+ // Add BSSID in my MAC Table.
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
+ pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
+ pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
+ pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
+ pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
+ pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
+ pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
+ pAd->MacTab.Content[BSSID_WCID].AuthMode = pAd->StaCfg.AuthMode;
+ pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
+ pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+
+ MlmeUpdateTxRates(pAd, TRUE, BSS0);
+#ifdef DOT11_N_SUPPORT
+ MlmeUpdateHtTxRates(pAd, BSS0);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
+#endif // DOT11_N_SUPPORT //
+
+ //
+ // Report Adjacent AP report.
+ //
+#ifdef LEAP_SUPPORT
+ CCXAdjacentAPReport(pAd);
+#endif // LEAP_SUPPORT //
+
+ if (pAd->CommonCfg.bAggregationCapable)
+ {
+ if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
+ {
+
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+ RTMPSetPiggyBack(pAd, TRUE);
+ DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
+ }
+ else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+ }
+ }
+
+ if (pAd->MlmeAux.APRalinkIe != 0x0)
+ {
+#ifdef DOT11_N_SUPPORT
+ if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
+ {
+ AsicEnableRDG(pAd);
+ }
+#endif // DOT11_N_SUPPORT //
+ OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
+ }
+ else
+ {
+ OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
+ CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
+ }
+ }
+
+#ifdef DOT11_N_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n", pAd->CommonCfg.BACapability.word, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+#endif // DOT11_N_SUPPORT //
+
+ // Set LED
+ RTMPSetLED(pAd, LED_LINK_UP);
+
+ pAd->Mlme.PeriodicRound = 0;
+ pAd->Mlme.OneSecPeriodicRound = 0;
+ pAd->bConfigChanged = FALSE; // Reset config flag
+ pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
+
+ // Set asic auto fall back
+ {
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+
+ MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
+ AsicUpdateAutoFallBackTable(pAd, pTable);
+ }
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
+ pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
+ if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
+ {
+ pEntry->bAutoTxRateSwitch = FALSE;
+#ifdef DOT11_N_SUPPORT
+ if (pEntry->HTPhyMode.field.MCS == 32)
+ pEntry->HTPhyMode.field.ShortGI = GI_800;
+
+ if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
+ pEntry->HTPhyMode.field.STBC = STBC_NONE;
+#endif // DOT11_N_SUPPORT //
+ // If the legacy mode is set, overwrite the transmit setting of this entry.
+ if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
+ RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+ }
+ else
+ pEntry->bAutoTxRateSwitch = TRUE;
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+ // Let Link Status Page display first initial rate.
+ pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
+ // Select DAC according to HT or Legacy
+ if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
+ Value &= (~0x18);
+ if (pAd->Antenna.field.TxPath == 2)
+ {
+ Value |= 0x10;
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
+ }
+ else
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
+ Value &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
+ {
+ }
+ else if (pEntry->MaxRAmpduFactor == 0)
+ {
+ // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
+ // Because our Init value is 1 at MACRegTable.
+ RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // Patch for Marvel AP to gain high throughput
+ // Need to set as following,
+ // 1. Set txop in register-EDCA_AC0_CFG as 0x60
+ // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
+ // 3. PBF_MAX_PCNT as 0x1F3FBF9F
+ // 4. kick per two packets when dequeue
+ //
+ // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
+ //
+ // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
+#ifdef DOT11_N_SUPPORT
+// if ((!IS_RT30xx(pAd)) &&
+ if (!((pAd->CommonCfg.RxStream == 1)&&(pAd->CommonCfg.TxStream == 1)) &&
+ (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
+ || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))))
+ {
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+ Data &= 0xFFFFFF00;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+ RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
+ DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ if (pAd->CommonCfg.bEnableTxBurst)
+ {
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+ Data &= 0xFFFFFF00;
+ Data |= 0x60;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+ pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
+
+ RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
+ DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
+ }
+ else
+ {
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+ Data &= 0xFFFFFF00;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+ RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
+ DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // Re-check to turn on TX burst or not.
+ if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
+ {
+ pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
+ if (pAd->CommonCfg.bEnableTxBurst)
+ {
+ UINT32 MACValue = 0;
+ // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
+ // I didn't change PBF_MAX_PCNT setting.
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
+ MACValue &= 0xFFFFFF00;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
+ pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
+ }
+ }
+ else
+ {
+ pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
+ COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
+ // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
+ // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
+ // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
+
+ if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
+ {
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+ }
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ pEntry->PortSecured = pAd->StaCfg.PortSecured;
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+ //
+ // Patch Atheros AP TX will breakdown issue.
+ // AP Model: DLink DWL-8200AP
+ //
+ if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
+ {
+ RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
+ }
+ else
+ {
+ RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
+ }
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
+ BuildEffectedChannelList(pAd);
+ }
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+}
+
+/*
+ ==========================================================================
+
+ Routine Description:
+ Disconnect current BSSID
+
+ Arguments:
+ pAd - Pointer to our adapter
+ IsReqFromAP - Request from AP
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ We need more information to know it's this requst from AP.
+ If yes! we need to do extra handling, for example, remove the WPA key.
+ Otherwise on 4-way handshaking will faied, since the WPA key didn't be
+ remove while auto reconnect.
+ Disconnect request from AP, it means we will start afresh 4-way handshaking
+ on WPA mode.
+
+ ==========================================================================
+*/
+VOID LinkDown(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN IsReqFromAP)
+{
+ UCHAR i, ByteValue = 0;
+
+ // Do nothing if monitor mode is on
+ if (MONITOR_ON(pAd))
+ return;
+
+#ifdef RALINK_ATE
+ // Nothing to do in ATE mode.
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ if (pAd->CommonCfg.bWirelessEvent)
+ {
+ RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+
+ if (ADHOC_ON(pAd)) // Adhoc mode link down
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
+
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+ BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
+ }
+ else // Infra structure mode
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
+
+#ifdef QOS_DLS_SUPPORT
+ // DLS tear down frame must be sent before link down
+ // send DLS-TEAR_DOWN message
+ if (pAd->CommonCfg.bDLSCapable)
+ {
+ // tear down local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+
+ // tear down peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+
+ // Saved last SSID for linkup comparison
+ pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
+ NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
+ COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
+ if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
+ {
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+ DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
+ pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
+ }
+ else
+ {
+ //
+ // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
+ // Otherwise lost beacon or receive De-Authentication from AP,
+ // then we should delete BSSID from BssTable.
+ // If we don't delete from entry, roaming will fail.
+ //
+ BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
+ }
+
+ // restore back to -
+ // 1. long slot (20 us) or short slot (9 us) time
+ // 2. turn on/off RTS/CTS and/or CTS-to-self protection
+ // 3. short preamble
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
+
+ if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
+ {
+ //
+ // Record current AP's information.
+ // for later used reporting Adjacent AP report.
+ //
+ pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
+ pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
+ NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
+ COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
+ }
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ // Country IE of the AP will be evaluated and will be used.
+ if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
+ {
+ NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
+ pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
+ BuildChannelListEx(pAd);
+ }
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+ }
+
+ for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
+ MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
+ }
+
+ pAd->StaCfg.CCXQosECWMin = 4;
+ pAd->StaCfg.CCXQosECWMax = 10;
+
+ AsicSetSlotTime(pAd, TRUE); //FALSE);
+ AsicSetEdcaParm(pAd, NULL);
+
+ // Set LED
+ RTMPSetLED(pAd, LED_LINK_DOWN);
+ pAd->LedIndicatorStregth = 0xF0;
+ RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
+
+ AsicDisableSync(pAd);
+
+ pAd->Mlme.PeriodicRound = 0;
+ pAd->Mlme.OneSecPeriodicRound = 0;
+
+ if (pAd->StaCfg.BssType == BSS_INFRA)
+ {
+ // Remove StaCfg Information after link down
+ NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
+ NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
+ pAd->CommonCfg.SsidLen = 0;
+ }
+#ifdef DOT11_N_SUPPORT
+ NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
+ NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
+ pAd->MlmeAux.HtCapabilityLen = 0;
+ pAd->MlmeAux.NewExtChannelOffset = 0xff;
+#endif // DOT11_N_SUPPORT //
+
+ // Reset WPA-PSK state. Only reset when supplicant enabled
+ if (pAd->StaCfg.WpaState != SS_NOTUSE)
+ {
+ pAd->StaCfg.WpaState = SS_START;
+ // Clear Replay counter
+ NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
+
+#ifdef QOS_DLS_SUPPORT
+ if (pAd->CommonCfg.bDLSCapable)
+ NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8);
+#endif // QOS_DLS_SUPPORT //
+ }
+
+
+ //
+ // if link down come from AP, we need to remove all WPA keys on WPA mode.
+ // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
+ //
+ if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
+ {
+ // Remove all WPA keys
+ RTMPWPARemoveAllKeys(pAd);
+ }
+
+ // 802.1x port control
+#ifdef WPA_SUPPLICANT_SUPPORT
+ // Prevent clear PortSecured here with static WEP
+ // NetworkManger set security policy first then set SSID to connect AP.
+ if (pAd->StaCfg.WpaSupplicantUP &&
+ (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
+ (pAd->StaCfg.IEEE8021X == FALSE))
+ {
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ }
+ else
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ }
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+ pAd->StaCfg.MicErrCnt = 0;
+
+ // Turn off Ckip control flag
+ pAd->StaCfg.bCkipOn = FALSE;
+ pAd->StaCfg.CCXEnable = FALSE;
+
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ // Update extra information to link is up
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+
+ //pAd->StaCfg.AdhocBOnlyJoined = FALSE;
+ //pAd->StaCfg.AdhocBGJoined = FALSE;
+ //pAd->StaCfg.Adhoc20NJoined = FALSE;
+ pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+
+ // Reset the Current AP's IP address
+ NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
+#ifdef RT2870
+ pAd->bUsbTxBulkAggre = FALSE;
+#endif // RT2870 //
+
+ // Clean association information
+ NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
+ pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+ pAd->StaCfg.ReqVarIELen = 0;
+ pAd->StaCfg.ResVarIELen = 0;
+
+ //
+ // Reset RSSI value after link down
+ //
+ pAd->StaCfg.RssiSample.AvgRssi0 = 0;
+ pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
+ pAd->StaCfg.RssiSample.AvgRssi1 = 0;
+ pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
+ pAd->StaCfg.RssiSample.AvgRssi2 = 0;
+ pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
+
+ // Restore MlmeRate
+ pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
+ pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
+
+#ifdef DOT11_N_SUPPORT
+ //
+ // After Link down, reset piggy-back setting in ASIC. Disable RDG.
+ //
+ if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+ {
+ pAd->CommonCfg.BBPCurrentBW = BW_20;
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
+ ByteValue &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
+ }
+#endif // DOT11_N_SUPPORT //
+ // Reset DAC
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
+ ByteValue &= (~0x18);
+ if (pAd->Antenna.field.TxPath == 2)
+ {
+ ByteValue |= 0x10;
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
+
+ RTMPSetPiggyBack(pAd,FALSE);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
+
+#ifdef DOT11_N_SUPPORT
+ pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
+#endif // DOT11_N_SUPPORT //
+
+ // Restore all settings in the following.
+ AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
+ AsicDisableRDG(pAd);
+ pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
+ pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
+ pAd->CommonCfg.BSSCoexist2040.word = 0;
+ TriEventInit(pAd);
+ for (i = 0; i < (pAd->ChannelListNum - 1); i++)
+ {
+ pAd->ChannelList[i].bEffectedChannel = FALSE;
+ }
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+ RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP) {
+ union iwreq_data wrqu;
+ //send disassociate event to wpa_supplicant
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+#ifdef RT30xx
+ if (IS_RT3090(pAd))
+ {
+ UINT32 macdata;
+ // disable MMPS BBP control register
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &ByteValue);
+ ByteValue &= ~(0x04); //bit 2
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, ByteValue);
+
+ // disable MMPS MAC control register
+ RTMP_IO_READ32(pAd, 0x1210, &macdata);
+ macdata &= ~(0x09); //bit 0, 3
+ RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+ }
+#endif // RT30xx //
+
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID IterateOnBssTab(
+ IN PRTMP_ADAPTER pAd)
+{
+ MLME_START_REQ_STRUCT StartReq;
+ MLME_JOIN_REQ_STRUCT JoinReq;
+ ULONG BssIdx;
+
+ // Change the wepstatus to original wepstatus
+ pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
+ pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
+ pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
+
+ BssIdx = pAd->MlmeAux.BssIdx;
+ if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
+ {
+ // Check cipher suite, AP must have more secured cipher than station setting
+ // Set the Pairwise and Group cipher to match the intended AP setting
+ // We can only connect to AP with less secured cipher setting
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
+
+ if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
+ pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
+ else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
+ pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
+ else // There is no PairCipher Aux, downgrade our capability to TKIP
+ pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
+
+ if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
+ pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
+ else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
+ pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
+ else // There is no PairCipher Aux, downgrade our capability to TKIP
+ pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+
+ // RSN capability
+ pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
+ }
+
+ // Set Mix cipher flag
+ pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
+ if (pAd->StaCfg.bMixCipher == TRUE)
+ {
+ // If mix cipher, re-build RSNIE
+ RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
+ JoinParmFill(pAd, &JoinReq, BssIdx);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
+ &JoinReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
+ }
+ else if (pAd->StaCfg.BssType == BSS_ADHOC)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
+ StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
+ }
+ else // no more BSS
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ }
+}
+
+// for re-association only
+// IRQL = DISPATCH_LEVEL
+VOID IterateOnBssTab2(
+ IN PRTMP_ADAPTER pAd)
+{
+ MLME_REASSOC_REQ_STRUCT ReassocReq;
+ ULONG BssIdx;
+ BSS_ENTRY *pBss;
+
+ BssIdx = pAd->MlmeAux.RoamIdx;
+ pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
+
+ if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
+
+ AsicSwitchChannel(pAd, pBss->Channel, FALSE);
+ AsicLockChannel(pAd, pBss->Channel);
+
+ // reassociate message has the same structure as associate message
+ AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
+ ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
+ sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
+ }
+ else // no more BSS
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID JoinParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
+ IN ULONG BssIdx)
+{
+ JoinReq->BssIdx = BssIdx;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID ScanParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN UCHAR ScanType)
+{
+ NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
+ ScanReq->SsidLen = SsidLen;
+ NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
+ ScanReq->BssType = BssType;
+ ScanReq->ScanType = ScanType;
+}
+
+#ifdef QOS_DLS_SUPPORT
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID DlsParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
+ IN PRT_802_11_DLS pDls,
+ IN USHORT reason)
+{
+ pDlsReq->pDLS = pDls;
+ pDlsReq->Reason = reason;
+}
+#endif // QOS_DLS_SUPPORT //
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID StartParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_START_REQ_STRUCT *StartReq,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen)
+{
+ ASSERT(SsidLen <= MAX_LEN_OF_SSID);
+ NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
+ StartReq->SsidLen = SsidLen;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID AuthParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
+ IN PUCHAR pAddr,
+ IN USHORT Alg)
+{
+ COPY_MAC_ADDR(AuthReq->Addr, pAddr);
+ AuthReq->Alg = Alg;
+ AuthReq->Timeout = AUTH_TIMEOUT;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+
+
+#ifdef RT2870
+
+VOID MlmeCntlConfirm(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG MsgType,
+ IN USHORT Msg)
+{
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
+}
+
+VOID ComposePsPoll(
+ IN PRTMP_ADAPTER pAd)
+{
+ PTXINFO_STRUC pTxInfo;
+ PTXWI_STRUC pTxWI;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
+ NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
+
+ pAd->PsPollFrame.FC.PwrMgmt = 0;
+ pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
+ pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
+ pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
+ COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
+ COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
+
+ RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
+ pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+ pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
+ 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+ RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
+ // Append 4 extra zero bytes.
+ pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID ComposeNullFrame(
+ IN PRTMP_ADAPTER pAd)
+{
+ PTXINFO_STRUC pTxInfo;
+ PTXWI_STRUC pTxWI;
+
+ NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
+ pAd->NullFrame.FC.Type = BTYPE_DATA;
+ pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
+ pAd->NullFrame.FC.ToDs = 1;
+ COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
+ COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
+ RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
+ pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+ pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
+ 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+ RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
+ pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
+}
+#endif // RT2870 //
+
+
+/*
+ ==========================================================================
+ Description:
+ Pre-build a BEACON frame in the shared memory
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+ULONG MakeIbssBeacon(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR DsLen = 1, IbssLen = 2;
+ UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
+ HEADER_802_11 BcnHdr;
+ USHORT CapabilityInfo;
+ LARGE_INTEGER FakeTimestamp;
+ ULONG FrameLen = 0;
+ PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
+ CHAR *pBeaconFrame = pAd->BeaconBuf;
+ BOOLEAN Privacy;
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen = 0;
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR ExtRateLen = 0;
+ UCHAR RSNIe = IE_WPA;
+
+ if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
+ {
+ SupRate[0] = 0x82; // 1 mbps
+ SupRate[1] = 0x84; // 2 mbps
+ SupRate[2] = 0x8b; // 5.5 mbps
+ SupRate[3] = 0x96; // 11 mbps
+ SupRateLen = 4;
+ ExtRateLen = 0;
+ }
+ else if (pAd->CommonCfg.Channel > 14)
+ {
+ SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
+ SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
+ SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
+ SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
+ SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
+ SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
+ SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
+ SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
+ SupRateLen = 8;
+ ExtRateLen = 0;
+
+ //
+ // Also Update MlmeRate & RtsRate for G only & A only
+ //
+ pAd->CommonCfg.MlmeRate = RATE_6;
+ pAd->CommonCfg.RtsRate = RATE_6;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
+ pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ }
+ else
+ {
+ SupRate[0] = 0x82; // 1 mbps
+ SupRate[1] = 0x84; // 2 mbps
+ SupRate[2] = 0x8b; // 5.5 mbps
+ SupRate[3] = 0x96; // 11 mbps
+ SupRateLen = 4;
+
+ ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
+ ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
+ ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
+ ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
+ ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
+ ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
+ ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
+ ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
+ ExtRateLen = 8;
+ }
+
+ pAd->StaActive.SupRateLen = SupRateLen;
+ NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
+ pAd->StaActive.ExtRateLen = ExtRateLen;
+ NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
+
+ // compose IBSS beacon frame
+ MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
+ Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
+ CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
+
+ MakeOutgoingFrame(pBeaconFrame, &FrameLen,
+ sizeof(HEADER_802_11), &BcnHdr,
+ TIMESTAMP_LEN, &FakeTimestamp,
+ 2, &pAd->CommonCfg.BeaconPeriod,
+ 2, &CapabilityInfo,
+ 1, &SsidIe,
+ 1, &pAd->CommonCfg.SsidLen,
+ pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
+ 1, &SupRateIe,
+ 1, &SupRateLen,
+ SupRateLen, SupRate,
+ 1, &DsIe,
+ 1, &DsLen,
+ 1, &pAd->CommonCfg.Channel,
+ 1, &IbssIe,
+ 1, &IbssLen,
+ 2, &pAd->StaActive.AtimWin,
+ END_OF_ARGS);
+
+ // add ERP_IE and EXT_RAE IE of in 802.11g
+ if (ExtRateLen)
+ {
+ ULONG tmp;
+
+ MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
+ 3, LocalErpIe,
+ 1, &ExtRateIe,
+ 1, &ExtRateLen,
+ ExtRateLen, ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ // If adhoc secruity is set for WPA-None, append the cipher suite IE
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ ULONG tmp;
+ RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
+
+ MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
+ 1, &RSNIe,
+ 1, &pAd->StaCfg.RSNIE_Len,
+ pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ ULONG TmpLen;
+ UCHAR HtLen, HtLen1;
+
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+ ADD_HT_INFO_IE addHTInfoTmp;
+ USHORT b2lTmp, b2lTmp2;
+#endif
+
+ // add HT Capability IE
+ HtLen = sizeof(pAd->CommonCfg.HtCapability);
+ HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &pAd->CommonCfg.HtCapability,
+ 1, &AddHtInfoIe,
+ 1, &HtLen1,
+ HtLen1, &pAd->CommonCfg.AddHTInfo,
+ END_OF_ARGS);
+#else
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+ NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
+ *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
+ *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
+
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &HtCapabilityTmp,
+ 1, &AddHtInfoIe,
+ 1, &HtLen1,
+ HtLen1, &addHTInfoTmp,
+ END_OF_ARGS);
+#endif
+ FrameLen += TmpLen;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ //beacon use reserved WCID 0xff
+ if (pAd->CommonCfg.Channel > 14)
+ {
+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
+ PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
+ }
+ else
+ {
+ // Set to use 1Mbps for Adhoc beacon.
+ HTTRANSMIT_SETTING Transmit;
+ Transmit.word = 0;
+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
+ PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
+ RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+#endif
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
+ FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));
+ return FrameLen;
+}
+
+
diff --git a/drivers/staging/rt3070/sta/dls.c b/drivers/staging/rt3070/sta/dls.c
new file mode 100644
index 00000000000..8bcd4132934
--- /dev/null
+++ b/drivers/staging/rt3070/sta/dls.c
@@ -0,0 +1,2170 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ dls.c
+
+ Abstract:
+ Handle WMM-DLS state machine
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Rory Chen 02-14-2006
+ Arvin Tai 06-03-2008 Modified for RT28xx
+ */
+
+#include "../rt_config.h"
+
+/*
+ ==========================================================================
+ Description:
+ dls state machine init, including state transition and timer init
+ Parameters:
+ Sm - pointer to the dls state machine
+ Note:
+ The state machine looks like this
+
+ DLS_IDLE
+ MT2_MLME_DLS_REQUEST MlmeDlsReqAction
+ MT2_PEER_DLS_REQUEST PeerDlsReqAction
+ MT2_PEER_DLS_RESPONSE PeerDlsRspAction
+ MT2_MLME_DLS_TEARDOWN MlmeTearDownAction
+ MT2_PEER_DLS_TEARDOWN PeerTearDownAction
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+void DlsStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ UCHAR i;
+
+ StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans, MAX_DLS_STATE, MAX_DLS_MSG, (STATE_MACHINE_FUNC)Drop, DLS_IDLE, DLS_MACHINE_BASE);
+
+ // the first column
+ StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_REQ, (STATE_MACHINE_FUNC)MlmeDlsReqAction);
+ StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_REQ, (STATE_MACHINE_FUNC)PeerDlsReqAction);
+ StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_RSP, (STATE_MACHINE_FUNC)PeerDlsRspAction);
+ StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)MlmeDlsTearDownAction);
+ StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)PeerDlsTearDownAction);
+
+ for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ pAd->StaCfg.DLSEntry[i].pAd = pAd;
+ RTMPInitTimer(pAd, &pAd->StaCfg.DLSEntry[i].Timer, GET_TIMER_FUNCTION(DlsTimeoutAction), pAd, FALSE);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeDlsReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ HEADER_802_11 DlsReqHdr;
+ PRT_802_11_DLS pDLS = NULL;
+ UCHAR Category = CATEGORY_DLS;
+ UCHAR Action = ACTION_DLS_REQUEST;
+ ULONG tmp;
+ USHORT reason;
+ ULONG Timeout;
+ BOOLEAN TimerCancelled;
+
+ if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &reason))
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsReqAction() \n"));
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsReqAction() allocate memory failed \n"));
+ return;
+ }
+
+ ActHeaderInit(pAd, &DlsReqHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+
+ // Build basic frame first
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DlsReqHdr,
+ 1, &Category,
+ 1, &Action,
+ 6, &pDLS->MacAddr,
+ 6, pAd->CurrentAddress,
+ 2, &pAd->StaActive.CapabilityInfo,
+ 2, &pDLS->TimeOut,
+ 1, &SupRateIe,
+ 1, &pAd->MlmeAux.SupRateLen,
+ pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
+ END_OF_ARGS);
+
+ if (pAd->MlmeAux.ExtRateLen != 0)
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &ExtRateIe,
+ 1, &pAd->MlmeAux.ExtRateLen,
+ pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ UCHAR HtLen;
+
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+#endif
+
+ // add HT Capability IE
+ HtLen = sizeof(HT_CAPABILITY_IE);
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &pAd->CommonCfg.HtCapability,
+ END_OF_ARGS);
+#else
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &HtCapabilityTmp,
+ END_OF_ARGS);
+#endif
+ FrameLen = FrameLen + tmp;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
+ Timeout = DLS_TIMEOUT;
+ RTMPSetTimer(&pDLS->Timer, Timeout);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerDlsReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ USHORT StatusCode = MLME_SUCCESS;
+ HEADER_802_11 DlsRspHdr;
+ UCHAR Category = CATEGORY_DLS;
+ UCHAR Action = ACTION_DLS_RESPONSE;
+ ULONG tmp;
+ USHORT CapabilityInfo;
+ UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
+ USHORT DLSTimeOut;
+ SHORT i;
+ ULONG Timeout;
+ BOOLEAN TimerCancelled;
+ PRT_802_11_DLS pDLS = NULL;
+ UCHAR MaxSupportedRateIn500Kbps = 0;
+ UCHAR SupportedRatesLen;
+ UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR HtCapabilityLen;
+ HT_CAPABILITY_IE HtCapability;
+
+ if (!PeerDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &DLSTimeOut,
+ &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
+ return;
+
+ // supported rates array may not be sorted. sort it and find the maximum rate
+ for (i = 0; i < SupportedRatesLen; i++)
+ {
+ if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
+ MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() from %02x:%02x:%02x:%02x:%02x:%02x\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() allocate memory failed \n"));
+ return;
+ }
+
+ if (!INFRA_ON(pAd))
+ {
+ StatusCode = MLME_REQUEST_DECLINED;
+ }
+ else if (!pAd->CommonCfg.bWmmCapable)
+ {
+ StatusCode = MLME_DEST_STA_IS_NOT_A_QSTA;
+ }
+ else if (!pAd->CommonCfg.bDLSCapable)
+ {
+ StatusCode = MLME_REQUEST_DECLINED;
+ }
+ else
+ {
+ // find table to update parameters
+ for (i = (MAX_NUM_OF_DLS_ENTRY-1); i >= 0; i--)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
+ else
+ {
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+ }
+
+ pAd->StaCfg.DLSEntry[i].Sequence = 0;
+ pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
+ pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
+ if (HtCapabilityLen != 0)
+ pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
+ else
+ pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
+ pDLS = &pAd->StaCfg.DLSEntry[i];
+ break;
+ }
+ }
+
+ // can not find in table, create a new one
+ if (i < 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() can not find same entry \n"));
+ for (i=(MAX_NUM_OF_DLS_ENTRY - 1); i >= MAX_NUM_OF_INIT_DLS_ENTRY; i--)
+ {
+ if (!pAd->StaCfg.DLSEntry[i].Valid)
+ {
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR MaxSupportedRate = RATE_11;
+
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
+ }
+ else
+ {
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+ }
+
+ pAd->StaCfg.DLSEntry[i].Sequence = 0;
+ pAd->StaCfg.DLSEntry[i].Valid = TRUE;
+ pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
+ pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
+ NdisMoveMemory(pAd->StaCfg.DLSEntry[i].MacAddr, SA, MAC_ADDR_LEN);
+ if (HtCapabilityLen != 0)
+ pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
+ else
+ pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
+ pDLS = &pAd->StaCfg.DLSEntry[i];
+ pEntry = MacTableInsertDlsEntry(pAd, SA, i);
+
+ switch (MaxSupportedRateIn500Kbps)
+ {
+ case 108: MaxSupportedRate = RATE_54; break;
+ case 96: MaxSupportedRate = RATE_48; break;
+ case 72: MaxSupportedRate = RATE_36; break;
+ case 48: MaxSupportedRate = RATE_24; break;
+ case 36: MaxSupportedRate = RATE_18; break;
+ case 24: MaxSupportedRate = RATE_12; break;
+ case 18: MaxSupportedRate = RATE_9; break;
+ case 12: MaxSupportedRate = RATE_6; break;
+ case 22: MaxSupportedRate = RATE_11; break;
+ case 11: MaxSupportedRate = RATE_5_5; break;
+ case 4: MaxSupportedRate = RATE_2; break;
+ case 2: MaxSupportedRate = RATE_1; break;
+ default: MaxSupportedRate = RATE_11; break;
+ }
+
+ pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
+
+ if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->HTPhyMode.field.MODE = MODE_CCK;
+ pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->HTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ }
+
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MinHTPhyMode.field.BW = BW_20;
+
+#ifdef DOT11_N_SUPPORT
+ pEntry->HTCapability.MCSSet[0] = 0;
+ pEntry->HTCapability.MCSSet[1] = 0;
+
+ // If this Entry supports 802.11n, upgrade to HT rate.
+ if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ UCHAR j, bitmask; //k,bitmask;
+ CHAR ii;
+
+ if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pAd->MacTab.fAnyStationNonGF = TRUE;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+ }
+
+ if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+ {
+ pEntry->MaxHTPhyMode.field.BW= BW_40;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
+ pAd->MacTab.fAnyStation20Only = TRUE;
+ }
+
+ // find max fixed rate
+ for (ii=15; ii>=0; ii--)
+ {
+ j = ii/8;
+ bitmask = (1<<(ii-(j*8)));
+ if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
+ {
+ pEntry->MaxHTPhyMode.field.MCS = ii;
+ break;
+ }
+ if (ii==0)
+ break;
+ }
+
+
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+
+ printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS);
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
+ {
+ // Fix MCS as HT Duplicated Mode
+ pEntry->MaxHTPhyMode.field.BW = 1;
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pEntry->MaxHTPhyMode.field.STBC = 0;
+ pEntry->MaxHTPhyMode.field.ShortGI = 0;
+ pEntry->MaxHTPhyMode.field.MCS = 32;
+ }
+ else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
+ {
+ // STA supports fixed MCS
+ pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ }
+ }
+
+ pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+ pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
+ pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
+ pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
+ pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+ if (HtCapability.HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (HtCapability.HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (HtCapability.HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (HtCapability.HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (HtCapability.ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+ NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
+ }
+#endif // DOT11_N_SUPPORT //
+
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+ pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+
+ if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+ {
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
+ pEntry->bAutoTxRateSwitch = TRUE;
+ }
+ else
+ {
+ pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ pEntry->bAutoTxRateSwitch = FALSE;
+
+ RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+ }
+ pEntry->RateLen = SupportedRatesLen;
+
+ break;
+ }
+ }
+ }
+ StatusCode = MLME_SUCCESS;
+
+ // can not find in table, create a new one
+ if (i < 0)
+ {
+ StatusCode = MLME_QOS_UNSPECIFY;
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() DLSEntry table full(only can support %d DLS session) \n", MAX_NUM_OF_DLS_ENTRY - MAX_NUM_OF_INIT_DLS_ENTRY));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() use entry(%d) %02x:%02x:%02x:%02x:%02x:%02x\n",
+ i, SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+ }
+ }
+
+ ActHeaderInit(pAd, &DlsRspHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+
+ // Build basic frame first
+ if (StatusCode == MLME_SUCCESS)
+ {
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DlsRspHdr,
+ 1, &Category,
+ 1, &Action,
+ 2, &StatusCode,
+ 6, SA,
+ 6, pAd->CurrentAddress,
+ 2, &pAd->StaActive.CapabilityInfo,
+ 1, &SupRateIe,
+ 1, &pAd->MlmeAux.SupRateLen,
+ pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
+ END_OF_ARGS);
+
+ if (pAd->MlmeAux.ExtRateLen != 0)
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &ExtRateIe,
+ 1, &pAd->MlmeAux.ExtRateLen,
+ pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ UCHAR HtLen;
+
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+#endif
+
+ // add HT Capability IE
+ HtLen = sizeof(HT_CAPABILITY_IE);
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &pAd->CommonCfg.HtCapability,
+ END_OF_ARGS);
+#else
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &HtCapabilityTmp,
+ END_OF_ARGS);
+#endif
+ FrameLen = FrameLen + tmp;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ if (pDLS && (pDLS->Status != DLS_FINISH))
+ {
+ RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
+ Timeout = DLS_TIMEOUT;
+ RTMPSetTimer(&pDLS->Timer, Timeout);
+ }
+ }
+ else
+ {
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DlsRspHdr,
+ 1, &Category,
+ 1, &Action,
+ 2, &StatusCode,
+ 6, SA,
+ 6, pAd->CurrentAddress,
+ END_OF_ARGS);
+ }
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerDlsRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT CapabilityInfo;
+ UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
+ USHORT StatusCode;
+ SHORT i;
+ BOOLEAN TimerCancelled;
+ UCHAR MaxSupportedRateIn500Kbps = 0;
+ UCHAR SupportedRatesLen;
+ UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR HtCapabilityLen;
+ HT_CAPABILITY_IE HtCapability;
+
+ if (!pAd->CommonCfg.bDLSCapable)
+ return;
+
+ if (!INFRA_ON(pAd))
+ return;
+
+ if (!PeerDlsRspSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode,
+ &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
+ return;
+
+ // supported rates array may not be sorted. sort it and find the maximum rate
+ for (i=0; i<SupportedRatesLen; i++)
+ {
+ if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
+ MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x with StatusCode=%d, CapabilityInfo=0x%x\n",
+ SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode, CapabilityInfo));
+
+ for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ if (StatusCode == MLME_SUCCESS)
+ {
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR MaxSupportedRate = RATE_11;
+
+ pEntry = MacTableInsertDlsEntry(pAd, SA, i);
+
+ switch (MaxSupportedRateIn500Kbps)
+ {
+ case 108: MaxSupportedRate = RATE_54; break;
+ case 96: MaxSupportedRate = RATE_48; break;
+ case 72: MaxSupportedRate = RATE_36; break;
+ case 48: MaxSupportedRate = RATE_24; break;
+ case 36: MaxSupportedRate = RATE_18; break;
+ case 24: MaxSupportedRate = RATE_12; break;
+ case 18: MaxSupportedRate = RATE_9; break;
+ case 12: MaxSupportedRate = RATE_6; break;
+ case 22: MaxSupportedRate = RATE_11; break;
+ case 11: MaxSupportedRate = RATE_5_5; break;
+ case 4: MaxSupportedRate = RATE_2; break;
+ case 2: MaxSupportedRate = RATE_1; break;
+ default: MaxSupportedRate = RATE_11; break;
+ }
+
+ pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
+
+ if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->HTPhyMode.field.MODE = MODE_CCK;
+ pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->HTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ }
+
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MinHTPhyMode.field.BW = BW_20;
+
+#ifdef DOT11_N_SUPPORT
+ pEntry->HTCapability.MCSSet[0] = 0;
+ pEntry->HTCapability.MCSSet[1] = 0;
+
+ // If this Entry supports 802.11n, upgrade to HT rate.
+ if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ UCHAR j, bitmask; //k,bitmask;
+ CHAR ii;
+
+ if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pAd->MacTab.fAnyStationNonGF = TRUE;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+ }
+
+ if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+ {
+ pEntry->MaxHTPhyMode.field.BW= BW_40;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
+ pAd->MacTab.fAnyStation20Only = TRUE;
+ }
+
+ // find max fixed rate
+ for (ii=15; ii>=0; ii--)
+ {
+ j = ii/8;
+ bitmask = (1<<(ii-(j*8)));
+ if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
+ {
+ pEntry->MaxHTPhyMode.field.MCS = ii;
+ break;
+ }
+ if (ii==0)
+ break;
+ }
+
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
+ {
+ // Fix MCS as HT Duplicated Mode
+ pEntry->MaxHTPhyMode.field.BW = 1;
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pEntry->MaxHTPhyMode.field.STBC = 0;
+ pEntry->MaxHTPhyMode.field.ShortGI = 0;
+ pEntry->MaxHTPhyMode.field.MCS = 32;
+ }
+ else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
+ {
+ // STA supports fixed MCS
+ pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ }
+ }
+
+ pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+ pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
+ pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
+ pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
+ pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+ if (HtCapability.HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (HtCapability.HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (HtCapability.HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (HtCapability.HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (HtCapability.ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+ NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
+ }
+#endif // DOT11_N_SUPPORT //
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+ pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+
+ if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+ {
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
+ pEntry->bAutoTxRateSwitch = TRUE;
+ }
+ else
+ {
+ pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ pEntry->bAutoTxRateSwitch = FALSE;
+
+ RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+ }
+ pEntry->RateLen = SupportedRatesLen;
+
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ // If support WPA or WPA2, start STAKey hand shake,
+ // If failed hand shake, just tear down peer DLS
+ if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
+ {
+ MLME_DLS_REQ_STRUCT MlmeDlsReq;
+ USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
+
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
+ }
+ else
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
+ }
+ }
+ else
+ {
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+ }
+
+ //initialize seq no for DLS frames.
+ pAd->StaCfg.DLSEntry[i].Sequence = 0;
+ if (HtCapabilityLen != 0)
+ pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
+ else
+ pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
+ }
+ else
+ {
+ // DLS setup procedure failed.
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
+ }
+ }
+ }
+
+ if (i >= MAX_NUM_OF_INIT_DLS_ENTRY)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() update timeout value \n"));
+ for (i=(MAX_NUM_OF_DLS_ENTRY-1); i>=MAX_NUM_OF_INIT_DLS_ENTRY; i--)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ if (StatusCode == MLME_SUCCESS)
+ {
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR MaxSupportedRate = RATE_11;
+
+ pEntry = MacTableInsertDlsEntry(pAd, SA, i);
+
+ switch (MaxSupportedRateIn500Kbps)
+ {
+ case 108: MaxSupportedRate = RATE_54; break;
+ case 96: MaxSupportedRate = RATE_48; break;
+ case 72: MaxSupportedRate = RATE_36; break;
+ case 48: MaxSupportedRate = RATE_24; break;
+ case 36: MaxSupportedRate = RATE_18; break;
+ case 24: MaxSupportedRate = RATE_12; break;
+ case 18: MaxSupportedRate = RATE_9; break;
+ case 12: MaxSupportedRate = RATE_6; break;
+ case 22: MaxSupportedRate = RATE_11; break;
+ case 11: MaxSupportedRate = RATE_5_5; break;
+ case 4: MaxSupportedRate = RATE_2; break;
+ case 2: MaxSupportedRate = RATE_1; break;
+ default: MaxSupportedRate = RATE_11; break;
+ }
+
+ pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
+
+ if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->HTPhyMode.field.MODE = MODE_CCK;
+ pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->HTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ }
+
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MinHTPhyMode.field.BW = BW_20;
+
+#ifdef DOT11_N_SUPPORT
+ pEntry->HTCapability.MCSSet[0] = 0;
+ pEntry->HTCapability.MCSSet[1] = 0;
+
+ // If this Entry supports 802.11n, upgrade to HT rate.
+ if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ UCHAR j, bitmask; //k,bitmask;
+ CHAR ii;
+
+ if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pAd->MacTab.fAnyStationNonGF = TRUE;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+ }
+
+ if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+ {
+ pEntry->MaxHTPhyMode.field.BW= BW_40;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
+ pAd->MacTab.fAnyStation20Only = TRUE;
+ }
+
+ // find max fixed rate
+ for (ii=15; ii>=0; ii--)
+ {
+ j = ii/8;
+ bitmask = (1<<(ii-(j*8)));
+ if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
+ {
+ pEntry->MaxHTPhyMode.field.MCS = ii;
+ break;
+ }
+ if (ii==0)
+ break;
+ }
+
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+ printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS);
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
+ {
+ // Fix MCS as HT Duplicated Mode
+ pEntry->MaxHTPhyMode.field.BW = 1;
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pEntry->MaxHTPhyMode.field.STBC = 0;
+ pEntry->MaxHTPhyMode.field.ShortGI = 0;
+ pEntry->MaxHTPhyMode.field.MCS = 32;
+ }
+ else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
+ {
+ // STA supports fixed MCS
+ pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ }
+ }
+
+ pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+ pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
+ pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
+ pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
+ pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+ if (HtCapability.HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (HtCapability.HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (HtCapability.HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (HtCapability.HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (HtCapability.ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+ NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
+ }
+#endif // DOT11_N_SUPPORT //
+
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+ pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+
+ if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+ {
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
+ pEntry->bAutoTxRateSwitch = TRUE;
+ }
+ else
+ {
+ pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ pEntry->bAutoTxRateSwitch = FALSE;
+
+ RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+ }
+ pEntry->RateLen = SupportedRatesLen;
+
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ // If support WPA or WPA2, start STAKey hand shake,
+ // If failed hand shake, just tear down peer DLS
+ if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
+ {
+ MLME_DLS_REQ_STRUCT MlmeDlsReq;
+ USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
+
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
+ }
+ else
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
+ }
+ }
+ else
+ {
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+ }
+ pAd->StaCfg.DLSEntry[i].Sequence = 0;
+ if (HtCapabilityLen != 0)
+ pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
+ else
+ pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
+ }
+ else
+ {
+ // DLS setup procedure failed.
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
+ }
+ }
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeDlsTearDownAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ UCHAR Category = CATEGORY_DLS;
+ UCHAR Action = ACTION_DLS_TEARDOWN;
+ USHORT ReasonCode = REASON_QOS_UNSPECIFY;
+ HEADER_802_11 DlsTearDownHdr;
+ PRT_802_11_DLS pDLS;
+ BOOLEAN TimerCancelled;
+ UCHAR i;
+
+ if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &ReasonCode))
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", ReasonCode));
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsTearDownAction() allocate memory failed \n"));
+ return;
+ }
+
+ ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+
+ // Build basic frame first
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DlsTearDownHdr,
+ 1, &Category,
+ 1, &Action,
+ 6, &pDLS->MacAddr,
+ 6, pAd->CurrentAddress,
+ 2, &ReasonCode,
+ END_OF_ARGS);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
+
+ // Remove key in local dls table entry
+ for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+
+ // clear peer dls table entry
+ for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerDlsTearDownAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
+ USHORT ReasonCode;
+ UINT i;
+ BOOLEAN TimerCancelled;
+
+ if (!pAd->CommonCfg.bDLSCapable)
+ return;
+
+ if (!INFRA_ON(pAd))
+ return;
+
+ if (!PeerDlsTearDownSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &ReasonCode))
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsTearDownAction() from %02x:%02x:%02x:%02x:%02x:%02x with ReasonCode=%d\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], ReasonCode));
+
+ // clear local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
+ //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
+ MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+
+ // clear peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
+ //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
+ MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID RTMPCheckDLSTimeOut(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG i;
+ MLME_DLS_REQ_STRUCT MlmeDlsReq;
+ USHORT reason = REASON_QOS_UNSPECIFY;
+
+ if (! pAd->CommonCfg.bDLSCapable)
+ return;
+
+ if (! INFRA_ON(pAd))
+ return;
+
+ // If timeout value is equaled to zero, it means always not be timeout.
+
+ // update local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+ && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
+ {
+ pAd->StaCfg.DLSEntry[i].CountDownTimer --;
+
+ if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
+ {
+ reason = REASON_QOS_REQUEST_TIMEOUT;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ }
+ }
+ }
+
+ // update peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+ && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
+ {
+ pAd->StaCfg.DLSEntry[i].CountDownTimer --;
+
+ if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
+ {
+ reason = REASON_QOS_REQUEST_TIMEOUT;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ }
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN RTMPRcvFrameDLSCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHeader,
+ IN ULONG Len,
+ IN PRT28XX_RXD_STRUC pRxD)
+{
+ ULONG i;
+ BOOLEAN bFindEntry = FALSE;
+ BOOLEAN bSTAKeyFrame = FALSE;
+ PEAPOL_PACKET pEap;
+ PUCHAR pProto, pAddr = NULL;
+ PUCHAR pSTAKey = NULL;
+ UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
+ UCHAR Mic[16], OldMic[16];
+ UCHAR digest[80];
+ UCHAR DlsPTK[80];
+ UCHAR temp[64];
+ BOOLEAN TimerCancelled;
+ CIPHER_KEY PairwiseKey;
+
+
+ if (! pAd->CommonCfg.bDLSCapable)
+ return bSTAKeyFrame;
+
+ if (! INFRA_ON(pAd))
+ return bSTAKeyFrame;
+
+ if (! (pHeader->FC.SubType & 0x08))
+ return bSTAKeyFrame;
+
+ if (Len < LENGTH_802_11 + 6 + 2 + 2)
+ return bSTAKeyFrame;
+
+ pProto = (PUCHAR)pHeader + LENGTH_802_11 + 2 + 6; // QOS Control field , 0xAA 0xAA 0xAA 0x00 0x00 0x00
+ pAddr = pHeader->Addr2;
+
+ // L2PAD bit on will pad 2 bytes at LLC
+ if (pRxD->L2PAD)
+ {
+ pProto += 2;
+ }
+
+ if (RTMPEqualMemory(EAPOL, pProto, 2) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
+ {
+ pEap = (PEAPOL_PACKET) (pProto + 2);
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff Len=%ld, DataLen=%d, KeyMic=%d, Install=%d, KeyAck=%d, Secure=%d, EKD_DL=%d, Error=%d, Request=%d\n", Len,
+ (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16),
+ pEap->KeyDesc.KeyInfo.KeyMic,
+ pEap->KeyDesc.KeyInfo.Install,
+ pEap->KeyDesc.KeyInfo.KeyAck,
+ pEap->KeyDesc.KeyInfo.Secure,
+ pEap->KeyDesc.KeyInfo.EKD_DL,
+ pEap->KeyDesc.KeyInfo.Error,
+ pEap->KeyDesc.KeyInfo.Request));
+
+ if ((Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16)) && pEap->KeyDesc.KeyInfo.KeyMic
+ && pEap->KeyDesc.KeyInfo.Install && pEap->KeyDesc.KeyInfo.KeyAck && pEap->KeyDesc.KeyInfo.Secure
+ && pEap->KeyDesc.KeyInfo.EKD_DL && !pEap->KeyDesc.KeyInfo.Error && !pEap->KeyDesc.KeyInfo.Request)
+ {
+ // First validate replay counter, only accept message with larger replay counter
+ // Let equal pass, some AP start with all zero replay counter
+ NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
+ if ((RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
+ (RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
+ return bSTAKeyFrame;
+
+ //RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+ RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter (%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
+ pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
+ pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
+ pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
+
+ // put these code segment to get the replay counter
+ if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
+ return bSTAKeyFrame;
+
+ // Check MIC value
+ // Save the MIC and replace with zero
+ // use proprietary PTK
+ NdisZeroMemory(temp, 64);
+ NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
+ WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
+
+ NdisMoveMemory(OldMic, pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ NdisZeroMemory(pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ HMAC_SHA1((PUCHAR) pEap, pEap->Body_Len[1] + 4, DlsPTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, Mic);
+ }
+
+ if (!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in Msg1 of STAKey handshake! \n"));
+ return bSTAKeyFrame;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in Msg1 of STAKey handshake! \n"));
+#if 1
+ if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0C)
+ && (pEap->KeyDesc.KeyData[4] == 0x43) && (pEap->KeyDesc.KeyData[5] == 0x02))
+ {
+ pAddr = pEap->KeyDesc.KeyData + 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
+ pSTAKey = pEap->KeyDesc.KeyData + 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%ld, KeyDataLen=%d\n",
+ pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
+
+ bSTAKeyFrame = TRUE;
+ }
+#else
+ if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0F)
+ && (pEap->KeyDesc.KeyData[4] == 0xAC) && (pEap->KeyDesc.KeyData[5] == 0x02))
+ {
+ pAddr = pEap->KeyDesc.KeyData + 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
+ pSTAKey = pEap->KeyDesc.KeyData + 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%d, KeyDataLen=%d\n",
+ pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
+
+ bSTAKeyFrame = TRUE;
+ }
+#endif
+
+ }
+ else if (Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE))
+ {
+ RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter 2(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
+ pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
+ pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
+ pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
+
+ }
+ }
+
+ // If timeout value is equaled to zero, it means always not be timeout.
+ // update local dls table entry
+ for (i= 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ if (bSTAKeyFrame)
+ {
+ PMAC_TABLE_ENTRY pEntry;
+
+ // STAKey frame, add pairwise key table
+ pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+
+ PairwiseKey.KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
+ NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
+ NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
+
+ PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
+
+ pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
+ //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
+ //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
+ // Add Pair-wise key to Asic
+#ifdef RT2870
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
+ {
+ RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
+ COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
+ KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
+ NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY));
+ RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
+ }
+ {
+ PMAC_TABLE_ENTRY pDLSEntry;
+ pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
+ pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
+ RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
+ }
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
+#endif // RT2870 //
+ NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
+
+ RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
+ }
+ else
+ {
+ // Data frame, update timeout value
+ if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+ {
+ pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
+ //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
+ }
+ }
+
+ bFindEntry = TRUE;
+ }
+ }
+
+ // update peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ if (bSTAKeyFrame)
+ {
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ // STAKey frame, add pairwise key table, and send STAkey Msg-2
+ pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+
+ PairwiseKey.KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
+ NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
+ NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
+
+ PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
+
+ pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
+ //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
+ //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
+ // Add Pair-wise key to Asic
+#ifdef RT2870
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
+ {
+ RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
+ COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
+ KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
+ NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY));
+ RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
+ }
+ {
+ PMAC_TABLE_ENTRY pDLSEntry;
+ pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
+ pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
+ RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
+ }
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
+#endif // RT2870 //
+ NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
+
+ // If support WPA or WPA2, start STAKey hand shake,
+ // If failed hand shake, just tear down peer DLS
+ if (RTMPSendSTAKeyHandShake(pAd, pAddr) != NDIS_STATUS_SUCCESS)
+ {
+ MLME_DLS_REQ_STRUCT MlmeDlsReq;
+ USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
+
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
+ }
+ }
+ else
+ {
+ // Data frame, update timeout value
+ if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+ {
+ pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
+ }
+ }
+
+ bFindEntry = TRUE;
+ }
+ }
+
+
+ return bSTAKeyFrame;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check if the frame can be sent through DLS direct link interface
+
+ Arguments:
+ pAd Pointer to adapter
+
+ Return Value:
+ DLS entry index
+
+ Note:
+
+ ========================================================================
+*/
+INT RTMPCheckDLSFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA)
+{
+ INT rval = -1;
+ INT i;
+
+ if (!pAd->CommonCfg.bDLSCapable)
+ return rval;
+
+ if (!INFRA_ON(pAd))
+ return rval;
+
+ do{
+ // check local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
+ MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ rval = i;
+ break;
+ }
+ }
+
+ // check peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
+ MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ rval = i;
+ break;
+ }
+ }
+ } while (FALSE);
+
+ return rval;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID RTMPSendDLSTearDownFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ HEADER_802_11 DlsTearDownHdr;
+ ULONG FrameLen = 0;
+ USHORT Reason = REASON_QOS_QSTA_LEAVING_QBSS;
+ UCHAR Category = CATEGORY_DLS;
+ UCHAR Action = ACTION_DLS_TEARDOWN;
+ UCHAR i = 0;
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n"));
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
+ return;
+ }
+
+ ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DlsTearDownHdr,
+ 1, &Category,
+ 1, &Action,
+ 6, pDA,
+ 6, pAd->CurrentAddress,
+ 2, &Reason,
+ END_OF_ARGS);
+
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ // Remove key in local dls table entry
+ for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+ && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+
+ // Remove key in peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+ && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i));
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+NDIS_STATUS RTMPSendSTAKeyRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA)
+{
+ UCHAR Header802_3[14];
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ EAPOL_PACKET Packet;
+ UCHAR Mic[16];
+ UCHAR digest[80];
+ PUCHAR pOutBuffer = NULL;
+ PNDIS_PACKET pNdisPacket;
+ UCHAR temp[64];
+ UCHAR DlsPTK[80];
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyRequest() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
+
+ pAd->Sequence ++;
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero message body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE andPeer MAC address
+
+ // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ Packet.KeyDesc.Type = WPA1_KEY_DESC;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ Packet.KeyDesc.Type = WPA2_KEY_DESC;
+ }
+
+ // Key descriptor version
+ Packet.KeyDesc.KeyInfo.KeyDescVer =
+ (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
+
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+ Packet.KeyDesc.KeyInfo.Secure = 1;
+ Packet.KeyDesc.KeyInfo.Request = 1;
+
+ Packet.KeyDesc.KeyDataLen[1] = 12;
+
+ // use our own OUI to distinguish proprietary with standard.
+ Packet.KeyDesc.KeyData[0] = 0xDD;
+ Packet.KeyDesc.KeyData[1] = 0x0A;
+ Packet.KeyDesc.KeyData[2] = 0x00;
+ Packet.KeyDesc.KeyData[3] = 0x0C;
+ Packet.KeyDesc.KeyData[4] = 0x43;
+ Packet.KeyDesc.KeyData[5] = 0x03;
+ NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
+
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Allocate buffer for transmitting message
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return NStatus;
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // use proprietary PTK
+ NdisZeroMemory(temp, 64);
+ NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
+ WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
+
+ // calculate MIC
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ NdisZeroMemory(digest, sizeof(digest));
+ HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ NdisZeroMemory(Mic, sizeof(Mic));
+ hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+ }
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(Header802_3), Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
+ if (NStatus == NDIS_STATUS_SUCCESS)
+ {
+ RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
+ STASendPacket(pAd, pNdisPacket);
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ }
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
+
+ return NStatus;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+NDIS_STATUS RTMPSendSTAKeyHandShake(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA)
+{
+ UCHAR Header802_3[14];
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ EAPOL_PACKET Packet;
+ UCHAR Mic[16];
+ UCHAR digest[80];
+ PUCHAR pOutBuffer = NULL;
+ PNDIS_PACKET pNdisPacket;
+ UCHAR temp[64];
+ UCHAR DlsPTK[80]; // Due to dirver can not get PTK, use proprietary PTK
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyHandShake() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
+
+ pAd->Sequence ++;
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero message body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE and Peer MAC address
+
+ // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ Packet.KeyDesc.Type = WPA1_KEY_DESC;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ Packet.KeyDesc.Type = WPA2_KEY_DESC;
+ }
+
+ // Key descriptor version
+ Packet.KeyDesc.KeyInfo.KeyDescVer =
+ (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
+
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+ Packet.KeyDesc.KeyInfo.Secure = 1;
+
+ Packet.KeyDesc.KeyDataLen[1] = 12;
+
+ // use our own OUI to distinguish proprietary with standard.
+ Packet.KeyDesc.KeyData[0] = 0xDD;
+ Packet.KeyDesc.KeyData[1] = 0x0A;
+ Packet.KeyDesc.KeyData[2] = 0x00;
+ Packet.KeyDesc.KeyData[3] = 0x0C;
+ Packet.KeyDesc.KeyData[4] = 0x43;
+ Packet.KeyDesc.KeyData[5] = 0x03;
+ NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
+
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Allocate buffer for transmitting message
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return NStatus;
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // use proprietary PTK
+ NdisZeroMemory(temp, 64);
+ NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
+ WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
+
+ // calculate MIC
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ NdisZeroMemory(digest, sizeof(digest));
+ HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ NdisZeroMemory(Mic, sizeof(Mic));
+ hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+ }
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(Header802_3), Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
+ if (NStatus == NDIS_STATUS_SUCCESS)
+ {
+ RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
+ STASendPacket(pAd, pNdisPacket);
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ }
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
+
+ return NStatus;
+}
+
+VOID DlsTimeoutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ MLME_DLS_REQ_STRUCT MlmeDlsReq;
+ USHORT reason;
+ PRT_802_11_DLS pDLS = (PRT_802_11_DLS)FunctionContext;
+ PRTMP_ADAPTER pAd = pDLS->pAd;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+ pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5]));
+
+ if ((pDLS) && (pDLS->Valid))
+ {
+ reason = REASON_QOS_REQUEST_TIMEOUT;
+ pDLS->Valid = FALSE;
+ pDLS->Status = DLS_NONE;
+ DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+}
+
+/*
+================================================================
+Description : because DLS and CLI share the same WCID table in ASIC.
+Mesh entry also insert to pAd->MacTab.content[]. Such is marked as ValidAsDls = TRUE.
+Also fills the pairwise key.
+Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
+from index MAX_AID_BA.
+================================================================
+*/
+MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UINT DlsEntryIdx)
+{
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n"));
+ // if FULL, return
+ if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
+ return NULL;
+
+ do
+ {
+ if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL)
+ break;
+
+ // allocate one MAC entry
+ pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE);
+ if (pEntry)
+ {
+ pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = pEntry->Aid;
+ pEntry->MatchDlsEntryIdx = DlsEntryIdx;
+ pEntry->AuthMode = pAd->StaCfg.AuthMode;
+ pEntry->WepStatus = pAd->StaCfg.WepStatus;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size));
+
+ // If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
+ if ((pEntry->ValidAsDls) && (pEntry->WepStatus == Ndis802_11WEPEnabled))
+ {
+ UCHAR KeyIdx = 0;
+ UCHAR CipherAlg = 0;
+
+ KeyIdx = pAd->StaCfg.DefaultKeyId;
+
+ CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
+
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ pEntry);
+ }
+
+ break;
+ }
+ } while(FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n"));
+
+ return pEntry;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Delete all Mesh Entry in pAd->MacTab
+ ==========================================================================
+ */
+BOOLEAN MacTableDeleteDlsEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT wcid,
+ IN PUCHAR pAddr)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n"));
+
+ if (!VALID_WCID(wcid))
+ return FALSE;
+
+ MacTableDeleteEntry(pAd, wcid, pAddr);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n"));
+
+ return TRUE;
+}
+
+MAC_TABLE_ENTRY *DlsEntryTableLookup(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount)
+{
+ ULONG HashIdx;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+ RTMP_SEM_LOCK(&pAd->MacTabLock);
+ HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+ pEntry = pAd->MacTab.Hash[HashIdx];
+
+ while (pEntry)
+ {
+ if ((pEntry->ValidAsDls == TRUE)
+ && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
+ {
+ if(bResetIdelCount)
+ pEntry->NoDataIdleCount = 0;
+ break;
+ }
+ else
+ pEntry = pEntry->pNext;
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->MacTabLock);
+ return pEntry;
+}
+
+MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR wcid,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount)
+{
+ ULONG DLsIndex;
+ PMAC_TABLE_ENTRY pCurEntry = NULL;
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ if (!VALID_WCID(wcid))
+ return NULL;
+
+ RTMP_SEM_LOCK(&pAd->MacTabLock);
+
+ do
+ {
+ pCurEntry = &pAd->MacTab.Content[wcid];
+
+ DLsIndex = 0xff;
+ if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE))
+ {
+ DLsIndex = pCurEntry->MatchDlsEntryIdx;
+ }
+
+ if (DLsIndex == 0xff)
+ break;
+
+ if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
+ {
+ if(bResetIdelCount)
+ pCurEntry->NoDataIdleCount = 0;
+ pEntry = pCurEntry;
+ break;
+ }
+ } while(FALSE);
+
+ RTMP_SEM_UNLOCK(&pAd->MacTabLock);
+
+ return pEntry;
+}
+
+INT Set_DlsEntryInfo_Display_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ INT i;
+
+ printk("\n%-19s%-8s\n", "MAC", "TIMEOUT\n");
+ for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ printk("%02x:%02x:%02x:%02x:%02x:%02x ",
+ pAd->StaCfg.DLSEntry[i].MacAddr[0], pAd->StaCfg.DLSEntry[i].MacAddr[1], pAd->StaCfg.DLSEntry[i].MacAddr[2],
+ pAd->StaCfg.DLSEntry[i].MacAddr[3], pAd->StaCfg.DLSEntry[i].MacAddr[4], pAd->StaCfg.DLSEntry[i].MacAddr[5]);
+ printk("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut);
+ }
+ }
+
+ return TRUE;
+}
+
+INT Set_DlsAddEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR mac[MAC_ADDR_LEN];
+ USHORT Timeout;
+ char *token, sepValue[] = ":", DASH = '-';
+ INT i;
+ RT_802_11_DLS Dls;
+
+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
+ return FALSE;
+
+ token = strchr(arg, DASH);
+ if ((token != NULL) && (strlen(token)>1))
+ {
+ Timeout = simple_strtol((token+1), 0, 10);
+
+ *token = '\0';
+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+ {
+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+ return FALSE;
+ AtoH(token, (PUCHAR)(&mac[i]), 1);
+ }
+ if(i != 6)
+ return FALSE;
+
+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1],
+ mac[2], mac[3], mac[4], mac[5], (int)Timeout);
+
+ NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
+ Dls.TimeOut = Timeout;
+ COPY_MAC_ADDR(Dls.MacAddr, mac);
+ Dls.Valid = 1;
+
+ MlmeEnqueue(pAd,
+ MLME_CNTL_STATE_MACHINE,
+ RT_OID_802_11_SET_DLS_PARAM,
+ sizeof(RT_802_11_DLS),
+ &Dls);
+
+ return TRUE;
+ }
+
+ return FALSE;
+
+}
+
+INT Set_DlsTearDownEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR macAddr[MAC_ADDR_LEN];
+ CHAR *value;
+ INT i;
+ RT_802_11_DLS Dls;
+
+ if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
+ return FALSE;
+
+ for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"))
+ {
+ if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ return FALSE; //Invalid
+
+ AtoH(value, &macAddr[i++], 2);
+ }
+
+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1],
+ macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
+
+ NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
+ COPY_MAC_ADDR(Dls.MacAddr, macAddr);
+ Dls.Valid = 0;
+
+ MlmeEnqueue(pAd,
+ MLME_CNTL_STATE_MACHINE,
+ RT_OID_802_11_SET_DLS_PARAM,
+ sizeof(RT_802_11_DLS),
+ &Dls);
+
+ return TRUE;
+}
+
diff --git a/drivers/staging/rt3070/sta/rtmp_data.c b/drivers/staging/rt3070/sta/rtmp_data.c
new file mode 100644
index 00000000000..b0f259b35c7
--- /dev/null
+++ b/drivers/staging/rt3070/sta/rtmp_data.c
@@ -0,0 +1,2637 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_data.c
+
+ Abstract:
+ Data path subroutines
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Aug/17/04 major modification for RT2561/2661
+ Jan Lee Mar/17/06 major modification for RT2860 New Ring Design
+*/
+#include "../rt_config.h"
+
+
+
+VOID STARxEAPOLFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
+ PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
+ UCHAR *pTmpBuf;
+
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP)
+ {
+ // All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon)
+ // TBD : process fragmented EAPol frames
+ {
+ // In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable
+ if ( pAd->StaCfg.IEEE8021X == TRUE &&
+ (EAP_CODE_SUCCESS == WpaCheckEapCode(pAd, pRxBlk->pData, pRxBlk->DataSize, LENGTH_802_1_H)))
+ {
+ PUCHAR Key;
+ UCHAR CipherAlg;
+ int idx = 0;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("Receive EAP-SUCCESS Packet\n"));
+ //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAd);
+
+ if (pAd->StaCfg.IEEE8021x_required_keys == FALSE)
+ {
+ idx = pAd->StaCfg.DesireSharedKeyId;
+ CipherAlg = pAd->StaCfg.DesireSharedKey[idx].CipherAlg;
+ Key = pAd->StaCfg.DesireSharedKey[idx].Key;
+
+ if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0)
+ {
+#ifdef RT2870
+ union
+ {
+ char buf[sizeof(NDIS_802_11_WEP)+MAX_LEN_OF_KEY- 1];
+ NDIS_802_11_WEP keyinfo;
+ } WepKey;
+ int len;
+
+
+ NdisZeroMemory(&WepKey, sizeof(WepKey));
+ len =pAd->StaCfg.DesireSharedKey[idx].KeyLen;
+
+ NdisMoveMemory(WepKey.keyinfo.KeyMaterial,
+ pAd->StaCfg.DesireSharedKey[idx].Key,
+ pAd->StaCfg.DesireSharedKey[idx].KeyLen);
+
+ WepKey.keyinfo.KeyIndex = 0x80000000 + idx;
+ WepKey.keyinfo.KeyLength = len;
+ pAd->SharedKey[BSS0][idx].KeyLen =(UCHAR) (len <= 5 ? 5 : 13);
+
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ pAd->ExtraInfo = GENERAL_LINK_UP;
+ // need to enqueue cmd to thread
+ RTUSBEnqueueCmdFromNdis(pAd, OID_802_11_ADD_WEP, TRUE, &WepKey, sizeof(WepKey.keyinfo) + len - 1);
+#endif // RT2870 //
+ // For Preventing ShardKey Table is cleared by remove key procedure.
+ pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg;
+ pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen;
+ NdisMoveMemory(pAd->SharedKey[BSS0][idx].Key,
+ pAd->StaCfg.DesireSharedKey[idx].Key,
+ pAd->StaCfg.DesireSharedKey[idx].KeyLen);
+ }
+ }
+ }
+
+ Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+ return;
+ }
+ }
+ else
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ // Special DATA frame that has to pass to MLME
+ // 1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process
+ // 2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process
+ {
+ pTmpBuf = pRxBlk->pData - LENGTH_802_11;
+ NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
+ REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! report EAPOL/AIRONET DATA to MLME (len=%d) !!!\n", pRxBlk->DataSize));
+ }
+ }
+
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+
+}
+
+VOID STARxDataFrameAnnounce(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+
+ // non-EAP frame
+ if (!RTMPCheckWPAframe(pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID))
+ {
+
+ {
+ // drop all non-EAP DATA frame before
+ // this client's Port-Access-Control is secured
+ if (pRxBlk->pHeader->FC.Wep)
+ {
+ // unsupported cipher suite
+ if (pAd->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+ }
+ else
+ {
+ // encryption in-use but receive a non-EAPOL clear text frame, drop it
+ if ((pAd->StaCfg.WepStatus != Ndis802_11EncryptionDisabled) &&
+ (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+ }
+ }
+ RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
+ if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK))
+ {
+ // Normal legacy, AMPDU or AMSDU
+ CmmRxnonRalinkFrameIndicate(pAd, pRxBlk, FromWhichBSSID);
+
+ }
+ else
+ {
+ // ARALINK
+ CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ }
+#ifdef QOS_DLS_SUPPORT
+ RX_BLK_CLEAR_FLAG(pRxBlk, fRX_DLS);
+#endif // QOS_DLS_SUPPORT //
+ }
+ else
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
+#ifdef DOT11_N_SUPPORT
+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
+ {
+ Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ // Determin the destination of the EAP frame
+ // to WPA state machine or upper layer
+ STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ }
+ }
+}
+
+
+// For TKIP frame, calculate the MIC value
+BOOLEAN STACheckTkipMICValue(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk)
+{
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ UCHAR *pData = pRxBlk->pData;
+ USHORT DataSize = pRxBlk->DataSize;
+ UCHAR UserPriority = pRxBlk->UserPriority;
+ PCIPHER_KEY pWpaKey;
+ UCHAR *pDA, *pSA;
+
+ pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];
+
+ pDA = pHeader->Addr1;
+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA))
+ {
+ pSA = pHeader->Addr3;
+ }
+ else
+ {
+ pSA = pHeader->Addr2;
+ }
+
+ if (RTMPTkipCompareMICValue(pAd,
+ pData,
+ pDA,
+ pSA,
+ pWpaKey->RxMic,
+ UserPriority,
+ DataSize) == FALSE)
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error 2\n"));
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP)
+ {
+ WpaSendMicFailureToWpaSupplicant(pAd, (pWpaKey->Type == PAIRWISEKEY) ? TRUE : FALSE);
+ }
+ else
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ RTMPReportMicError(pAd, pWpaKey);
+ }
+
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+//
+// All Rx routines use RX_BLK structure to hande rx events
+// It is very important to build pRxBlk attributes
+// 1. pHeader pointer to 802.11 Header
+// 2. pData pointer to payload including LLC (just skip Header)
+// 3. set payload size including LLC to DataSize
+// 4. set some flags with RX_BLK_SET_FLAG()
+//
+VOID STAHandleRxDataFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+ PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
+ PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+ BOOLEAN bFragment = FALSE;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ UCHAR FromWhichBSSID = BSS0;
+ UCHAR UserPriority = 0;
+
+ {
+ // before LINK UP, all DATA frames are rejected
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+#ifdef QOS_DLS_SUPPORT
+ //if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
+ if (RTMPRcvFrameDLSCheck(pAd, pHeader, pRxWI->MPDUtotalByteCount, pRxD))
+ {
+ return;
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ // Drop not my BSS frames
+ if (pRxD->MyBss == 0)
+ {
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+ }
+
+ pAd->RalinkCounters.RxCountSinceLastNULL++;
+ if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && (pHeader->FC.SubType & 0x08))
+ {
+ UCHAR *pData;
+ DBGPRINT(RT_DEBUG_TRACE,("bAPSDCapable\n"));
+
+ // Qos bit 4
+ pData = (PUCHAR)pHeader + LENGTH_802_11;
+ if ((*pData >> 4) & 0x01)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
+ pAd->CommonCfg.bInServicePeriod = FALSE;
+
+ // Force driver to fall into sleep mode when rcv EOSP frame
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ {
+ USHORT TbttNumToNextWakeUp;
+ USHORT NextDtim = pAd->StaCfg.DtimPeriod;
+ ULONG Now;
+
+ NdisGetSystemUpTime(&Now);
+ NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod;
+
+ TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
+ TbttNumToNextWakeUp = NextDtim;
+
+ MlmeSetPsmBit(pAd, PWR_SAVE);
+ // if WMM-APSD is failed, try to disable following line
+ AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+ }
+ }
+
+ if ((pHeader->FC.MoreData) && (pAd->CommonCfg.bInServicePeriod))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("Sending another trigger frame when More Data bit is set to 1\n"));
+ }
+ }
+
+ // Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame
+ if ((pHeader->FC.SubType & 0x04)) // bit 2 : no DATA
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ // Drop not my BSS frame (we can not only check the MyBss bit in RxD)
+#ifdef QOS_DLS_SUPPORT
+ if (!pAd->CommonCfg.bDLSCapable)
+ {
+#endif // QOS_DLS_SUPPORT //
+ if (INFRA_ON(pAd))
+ {
+ // Infrastructure mode, check address 2 for BSSID
+ if (!RTMPEqualMemory(&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6))
+ {
+ // Receive frame not my BSSID
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+ }
+ else // Ad-Hoc mode or Not associated
+ {
+ // Ad-Hoc mode, check address 3 for BSSID
+ if (!RTMPEqualMemory(&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6))
+ {
+ // Receive frame not my BSSID
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+ }
+#ifdef QOS_DLS_SUPPORT
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ //
+ // find pEntry
+ //
+ if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE)
+ {
+ pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
+ }
+ else
+ {
+ // 1. release packet if infra mode
+ // 2. new a pEntry if ad-hoc mode
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ // infra or ad-hoc
+ if (INFRA_ON(pAd))
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);
+#ifdef QOS_DLS_SUPPORT
+ if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
+ RX_BLK_SET_FLAG(pRxBlk, fRX_DLS);
+ else
+#endif // QOS_DLS_SUPPORT //
+ ASSERT(pRxWI->WirelessCliID == BSSID_WCID);
+ }
+
+ // check Atheros Client
+ if ((pEntry->bIAmBadAtheros == FALSE) && (pRxD->AMPDU == 1) && (pHeader->FC.Retry ))
+ {
+ pEntry->bIAmBadAtheros = TRUE;
+ pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;
+ pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;
+ if (!STA_AES_ON(pAd))
+ {
+ AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE, FALSE);
+ }
+ }
+ }
+
+ pRxBlk->pData = (UCHAR *)pHeader;
+
+ //
+ // update RxBlk->pData, DataSize
+ // 802.11 Header, QOS, HTC, Hw Padding
+ //
+
+ // 1. skip 802.11 HEADER
+ {
+ pRxBlk->pData += LENGTH_802_11;
+ pRxBlk->DataSize -= LENGTH_802_11;
+ }
+
+ // 2. QOS
+ if (pHeader->FC.SubType & 0x08)
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
+ UserPriority = *(pRxBlk->pData) & 0x0f;
+ // bit 7 in QoS Control field signals the HT A-MSDU format
+ if ((*pRxBlk->pData) & 0x80)
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
+ }
+
+ // skip QOS contorl field
+ pRxBlk->pData += 2;
+ pRxBlk->DataSize -=2;
+ }
+ pRxBlk->UserPriority = UserPriority;
+
+ // 3. Order bit: A-Ralink or HTC+
+ if (pHeader->FC.Order)
+ {
+#ifdef AGGREGATION_SUPPORT
+ if ((pRxWI->PHYMODE <= MODE_OFDM) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
+ }
+ else
+#endif
+ {
+#ifdef DOT11_N_SUPPORT
+ RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
+ // skip HTC contorl field
+ pRxBlk->pData += 4;
+ pRxBlk->DataSize -= 4;
+#endif // DOT11_N_SUPPORT //
+ }
+ }
+
+ // 4. skip HW padding
+ if (pRxD->L2PAD)
+ {
+ // just move pData pointer
+ // because DataSize excluding HW padding
+ RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
+ pRxBlk->pData += 2;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if (pRxD->BA)
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
+ }
+#endif // DOT11_N_SUPPORT //
+
+
+ //
+ // Case I Process Broadcast & Multicast data frame
+ //
+ if (pRxD->Bcast || pRxD->Mcast)
+ {
+ INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
+
+ // Drop Mcast/Bcast frame with fragment bit on
+ if (pHeader->FC.MoreFrag)
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ // Filter out Bcast frame which AP relayed for us
+ if (pHeader->FC.FrDs && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress))
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+ return;
+ }
+ else if (pRxD->U2M)
+ {
+ pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
+
+
+#ifdef QOS_DLS_SUPPORT
+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_DLS))
+ {
+ MAC_TABLE_ENTRY *pDlsEntry = NULL;
+
+ pDlsEntry = DlsEntryTableLookupByWcid(pAd, pRxWI->WirelessCliID, pHeader->Addr2, TRUE);
+ if(pDlsEntry)
+ Update_Rssi_Sample(pAd, &pDlsEntry->RssiSample, pRxWI);
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+ if (ADHOC_ON(pAd))
+ {
+ pEntry = MacTableLookup(pAd, pHeader->Addr2);
+ if (pEntry)
+ Update_Rssi_Sample(pAd, &pEntry->RssiSample, pRxWI);
+ }
+
+
+ Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
+
+ pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
+ pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
+
+ pAd->RalinkCounters.OneSecRxOkDataCnt++;
+
+
+ if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0)))
+ {
+ // re-assemble the fragmented packets
+ // return complete frame (pRxPacket) or NULL
+ bFragment = TRUE;
+ pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
+ }
+
+ if (pRxPacket)
+ {
+ pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
+
+ // process complete frame
+ if (bFragment && (pRxD->Decrypted) && (pEntry->WepStatus == Ndis802_11Encryption2Enabled))
+ {
+ // Minus MIC length
+ pRxBlk->DataSize -= 8;
+
+ // For TKIP frame, calculate the MIC value
+ if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) == FALSE)
+ {
+ return;
+ }
+ }
+
+ STARxDataFrameAnnounce(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ return;
+ }
+ else
+ {
+ // just return
+ // because RTMPDeFragmentDataFrame() will release rx packet,
+ // if packet is fragmented
+ return;
+ }
+ }
+
+ ASSERT(0);
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+}
+
+VOID STAHandleRxMgmtFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+ PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
+ PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+
+ do
+ {
+
+ // We should collect RSSI not only U2M data but also my beacon
+ if ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))
+ && (pAd->RxAnt.EvaluatePeriod == 0))
+ {
+ Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
+
+ pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
+ pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
+ }
+
+#ifdef RT30xx
+ // collect rssi information for antenna diversity
+ if (pAd->NicConfig2.field.AntDiversity)
+ {
+ if ((pRxD->U2M) || ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))))
+ {
+ COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAd, ConvertToRssi(pAd, (UCHAR)pRxWI->RSSI0, RSSI_0), 0); //Note: RSSI2 not used on RT73
+ pAd->StaCfg.NumOfAvgRssiSample ++;
+ }
+ }
+#endif // RT30xx //
+
+ // First check the size, it MUST not exceed the mlme queue size
+ if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE)
+ {
+ DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount));
+ break;
+ }
+
+ REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader, pRxWI->MPDUtotalByteCount,
+ pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
+ } while (FALSE);
+
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
+}
+
+VOID STAHandleRxControlFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+#ifdef DOT11_N_SUPPORT
+ PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
+#endif // DOT11_N_SUPPORT //
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+
+ switch (pHeader->FC.SubType)
+ {
+ case SUBTYPE_BLOCK_ACK_REQ:
+#ifdef DOT11_N_SUPPORT
+ {
+ CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID, (pRxWI->MPDUtotalByteCount), (PFRAME_BA_REQ)pHeader);
+ }
+ break;
+#endif // DOT11_N_SUPPORT //
+ case SUBTYPE_BLOCK_ACK:
+ case SUBTYPE_ACK:
+ default:
+ break;
+ }
+
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process RxDone interrupt, running in DPC level
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ This routine has to maintain Rx ring read pointer.
+ Need to consider QOS DATA format when converting to 802.3
+ ========================================================================
+*/
+BOOLEAN STARxDoneInterruptHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN argc)
+{
+ NDIS_STATUS Status;
+ UINT32 RxProcessed, RxPending;
+ BOOLEAN bReschedule = FALSE;
+ RT28XX_RXD_STRUC *pRxD;
+ UCHAR *pData;
+ PRXWI_STRUC pRxWI;
+ PNDIS_PACKET pRxPacket;
+ PHEADER_802_11 pHeader;
+ RX_BLK RxCell;
+
+ RxProcessed = RxPending = 0;
+
+ // process whole rx ring
+ while (1)
+ {
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST) ||
+ !RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_START_UP))
+ {
+ break;
+ }
+
+
+ RxProcessed ++; // test
+
+ // 1. allocate a new data packet into rx ring to replace received packet
+ // then processing the received packet
+ // 2. the callee must take charge of release of packet
+ // 3. As far as driver is concerned ,
+ // the rx packet must
+ // a. be indicated to upper layer or
+ // b. be released if it is discarded
+ pRxPacket = GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule, &RxPending);
+ if (pRxPacket == NULL)
+ {
+ // no more packet to process
+ break;
+ }
+
+ // get rx ring descriptor
+ pRxD = &(RxCell.RxD);
+ // get rx data buffer
+ pData = GET_OS_PKT_DATAPTR(pRxPacket);
+ pRxWI = (PRXWI_STRUC) pData;
+ pHeader = (PHEADER_802_11) (pData+RXWI_SIZE) ;
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, TRUE);
+ RTMPWIEndianChange((PUCHAR)pRxWI, TYPE_RXWI);
+#endif
+
+ // build RxCell
+ RxCell.pRxWI = pRxWI;
+ RxCell.pHeader = pHeader;
+ RxCell.pRxPacket = pRxPacket;
+ RxCell.pData = (UCHAR *) pHeader;
+ RxCell.DataSize = pRxWI->MPDUtotalByteCount;
+ RxCell.Flags = 0;
+
+ // Increase Total receive byte counter after real data received no mater any error or not
+ pAd->RalinkCounters.ReceivedByteCount += pRxWI->MPDUtotalByteCount;
+ pAd->RalinkCounters.RxCount ++;
+
+ INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
+
+ if (pRxWI->MPDUtotalByteCount < 14)
+ Status = NDIS_STATUS_FAILURE;
+
+ if (MONITOR_ON(pAd))
+ {
+ send_monitor_packets(pAd, &RxCell);
+ break;
+ }
+ /* RT2870 invokes STARxDoneInterruptHandle() in rtusb_bulk.c */
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ pAd->ate.RxCntPerSec++;
+ ATESampleRssi(pAd, pRxWI);
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQARxStart == TRUE)
+ {
+ /* (*pRxD) has been swapped in GetPacketFromRxRing() */
+ ATE_QA_Statistics(pAd, pRxWI, pRxD, pHeader);
+ }
+#endif // RALINK_28xx_QA //
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
+ continue;
+ }
+#endif // RALINK_ATE //
+
+ // Check for all RxD errors
+ Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);
+
+ // Handle the received frame
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ switch (pHeader->FC.Type)
+ {
+ // CASE I, receive a DATA frame
+ case BTYPE_DATA:
+ {
+ // process DATA frame
+ STAHandleRxDataFrame(pAd, &RxCell);
+ }
+ break;
+ // CASE II, receive a MGMT frame
+ case BTYPE_MGMT:
+ {
+ STAHandleRxMgmtFrame(pAd, &RxCell);
+ }
+ break;
+ // CASE III. receive a CNTL frame
+ case BTYPE_CNTL:
+ {
+ STAHandleRxControlFrame(pAd, &RxCell);
+ }
+ break;
+ // discard other type
+ default:
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ break;
+ }
+ }
+ else
+ {
+ pAd->Counters8023.RxErrors++;
+ // discard this frame
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ }
+ }
+
+ return bReschedule;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Arguments:
+ pAd Pointer to our adapter
+
+ IRQL = DISPATCH_LEVEL
+
+ ========================================================================
+*/
+VOID RTMPHandleTwakeupInterrupt(
+ IN PRTMP_ADAPTER pAd)
+{
+ AsicForceWakeup(pAd, FALSE);
+}
+
+/*
+========================================================================
+Routine Description:
+ Early checking and OS-depened parsing for Tx packet send to our STA driver.
+
+Arguments:
+ NDIS_HANDLE MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd.
+ PPNDIS_PACKET ppPacketArray The packet array need to do transmission.
+ UINT NumberOfPackets Number of packet in packet array.
+
+Return Value:
+ NONE
+
+Note:
+ This function do early checking and classification for send-out packet.
+ You only can put OS-depened & STA related code in here.
+========================================================================
+*/
+VOID STASendPackets(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PPNDIS_PACKET ppPacketArray,
+ IN UINT NumberOfPackets)
+{
+ UINT Index;
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) MiniportAdapterContext;
+ PNDIS_PACKET pPacket;
+ BOOLEAN allowToSend = FALSE;
+
+
+ for (Index = 0; Index < NumberOfPackets; Index++)
+ {
+ pPacket = ppPacketArray[Index];
+
+ do
+ {
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+ {
+ // Drop send request since hardware is in reset state
+ break;
+ }
+ else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd))
+ {
+ // Drop send request since there are no physical connection yet
+ break;
+ }
+ else
+ {
+ // Record that orignal packet source is from NDIS layer,so that
+ // later on driver knows how to release this NDIS PACKET
+#ifdef QOS_DLS_SUPPORT
+ MAC_TABLE_ENTRY *pEntry;
+ PUCHAR pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
+
+ pEntry = MacTableLookup(pAd, pSrcBufVA);
+ if (pEntry && (pEntry->ValidAsDls == TRUE))
+ {
+ RTMP_SET_PACKET_WCID(pPacket, pEntry->Aid);
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+ RTMP_SET_PACKET_WCID(pPacket, 0); // this field is useless when in STA mode
+ RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+ NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING);
+ pAd->RalinkCounters.PendingNdisPacketCount++;
+
+ allowToSend = TRUE;
+ }
+ } while(FALSE);
+
+ if (allowToSend == TRUE)
+ STASendPacket(pAd, pPacket);
+ else
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+
+ // Dequeue outgoing frames from TxSwQueue[] and process it
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+ This routine is used to do packet parsing and classification for Tx packet
+ to STA device, and it will en-queue packets to our TxSwQueue depends on AC
+ class.
+
+Arguments:
+ pAd Pointer to our adapter
+ pPacket Pointer to send packet
+
+Return Value:
+ NDIS_STATUS_SUCCESS If succes to queue the packet into TxSwQueue.
+ NDIS_STATUS_FAILURE If failed to do en-queue.
+
+Note:
+ You only can put OS-indepened & STA related code in here.
+========================================================================
+*/
+NDIS_STATUS STASendPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ PACKET_INFO PacketInfo;
+ PUCHAR pSrcBufVA;
+ UINT SrcBufLen;
+ UINT AllowFragSize;
+ UCHAR NumberOfFrag;
+// UCHAR RTSRequired;
+ UCHAR QueIdx, UserPriority;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ unsigned int IrqFlags;
+ UCHAR FlgIsIP = 0;
+ UCHAR Rate;
+
+ // Prepare packet information structure for buffer descriptor
+ // chained within a single NDIS packet.
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+ if (pSrcBufVA == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> pSrcBufVA == NULL !!!SrcBufLen=%x\n",SrcBufLen));
+ // Resourece is low, system did not allocate virtual address
+ // return NDIS_STATUS_FAILURE directly to upper layer
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+
+
+ if (SrcBufLen < 14)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> Ndis Packet buffer error !!!\n"));
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return (NDIS_STATUS_FAILURE);
+ }
+
+ // In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry.
+ // Note multicast packets in adhoc also use BSSID_WCID index.
+ {
+ if(INFRA_ON(pAd))
+ {
+#ifdef QOS_DLS_SUPPORT
+ USHORT tmpWcid;
+
+ tmpWcid = RTMP_GET_PACKET_WCID(pPacket);
+ if (VALID_WCID(tmpWcid) &&
+ (pAd->MacTab.Content[tmpWcid].ValidAsDls== TRUE))
+ {
+ pEntry = &pAd->MacTab.Content[tmpWcid];
+ Rate = pAd->MacTab.Content[tmpWcid].CurrTxRate;
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+ {
+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
+ RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
+ Rate = pAd->CommonCfg.TxRate;
+ }
+ }
+ else if (ADHOC_ON(pAd))
+ {
+ if (*pSrcBufVA & 0x01)
+ {
+ RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID);
+ pEntry = &pAd->MacTab.Content[MCAST_WCID];
+ }
+ else
+ {
+ pEntry = MacTableLookup(pAd, pSrcBufVA);
+ }
+ Rate = pAd->CommonCfg.TxRate;
+ }
+ }
+
+ if (!pEntry)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("STASendPacket->Cannot find pEntry(%2x:%2x:%2x:%2x:%2x:%2x) in MacTab!\n", PRINT_MAC(pSrcBufVA)));
+ // Resourece is low, system did not allocate virtual address
+ // return NDIS_STATUS_FAILURE directly to upper layer
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ if (ADHOC_ON(pAd)
+ )
+ {
+ RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid);
+ }
+
+ //
+ // Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags.
+ // Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL).
+ RTMPCheckEtherType(pAd, pPacket);
+
+
+
+ //
+ // WPA 802.1x secured port control - drop all non-802.1x frame before port secured
+ //
+ if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+#ifdef WPA_SUPPLICANT_SUPPORT
+ || (pAd->StaCfg.IEEE8021X == TRUE)
+#endif // WPA_SUPPLICANT_SUPPORT //
+#ifdef LEAP_SUPPORT
+ || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+ )
+ && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAd->StaCfg.MicErrCnt >= 2))
+ && (RTMP_GET_PACKET_EAPOL(pPacket)== FALSE)
+ )
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("STASendPacket --> Drop packet before port secured !!!\n"));
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+
+ return (NDIS_STATUS_FAILURE);
+ }
+
+
+ // STEP 1. Decide number of fragments required to deliver this MSDU.
+ // The estimation here is not very accurate because difficult to
+ // take encryption overhead into consideration here. The result
+ // "NumberOfFrag" is then just used to pre-check if enough free
+ // TXD are available to hold this MSDU.
+
+
+ if (*pSrcBufVA & 0x01) // fragmentation not allowed on multicast & broadcast
+ NumberOfFrag = 1;
+ else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))
+ NumberOfFrag = 1; // Aggregation overwhelms fragmentation
+ else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED))
+ NumberOfFrag = 1; // Aggregation overwhelms fragmentation
+#ifdef DOT11_N_SUPPORT
+ else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX) || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
+ NumberOfFrag = 1; // MIMO RATE overwhelms fragmentation
+#endif // DOT11_N_SUPPORT //
+ else
+ {
+ // The calculated "NumberOfFrag" is a rough estimation because of various
+ // encryption/encapsulation overhead not taken into consideration. This number is just
+ // used to make sure enough free TXD are available before fragmentation takes place.
+ // In case the actual required number of fragments of an NDIS packet
+ // excceeds "NumberOfFrag"caculated here and not enough free TXD available, the
+ // last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of
+ // resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should
+ // rarely happen and the penalty is just like a TX RETRY fail. Affordable.
+
+ AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
+ NumberOfFrag = ((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;
+ // To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size
+ if (((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)
+ {
+ NumberOfFrag--;
+ }
+ }
+
+ // Save fragment number to Ndis packet reserved field
+ RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);
+
+
+ // STEP 2. Check the requirement of RTS:
+ // If multiple fragment required, RTS is required only for the first fragment
+ // if the fragment size large than RTS threshold
+ // For RT28xx, Let ASIC send RTS/CTS
+ RTMP_SET_PACKET_RTS(pPacket, 0);
+ RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);
+
+ //
+ // STEP 3. Traffic classification. outcome = <UserPriority, QueIdx>
+ //
+ UserPriority = 0;
+ QueIdx = QID_AC_BE;
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
+ CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
+ {
+ USHORT Protocol;
+ UCHAR LlcSnapLen = 0, Byte0, Byte1;
+ do
+ {
+ // get Ethernet protocol field
+ Protocol = (USHORT)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
+ if (Protocol <= 1500)
+ {
+ // get Ethernet protocol field from LLC/SNAP
+ if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + 6, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
+ break;
+
+ Protocol = (USHORT)((Byte0 << 8) + Byte1);
+ LlcSnapLen = 8;
+ }
+
+ // always AC_BE for non-IP packet
+ if (Protocol != 0x0800)
+ break;
+
+ // get IP header
+ if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
+ break;
+
+ // return AC_BE if packet is not IPv4
+ if ((Byte0 & 0xf0) != 0x40)
+ break;
+
+ FlgIsIP = 1;
+ UserPriority = (Byte1 & 0xe0) >> 5;
+ QueIdx = MapUserPriorityToAccessCategory[UserPriority];
+
+ // TODO: have to check ACM bit. apply TSPEC if ACM is ON
+ // TODO: downgrade UP & QueIdx before passing ACM
+ if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx])
+ {
+ UserPriority = 0;
+ QueIdx = QID_AC_BE;
+ }
+ } while (FALSE);
+ }
+
+ RTMP_SET_PACKET_UP(pPacket, UserPriority);
+
+
+
+ // Make sure SendTxWait queue resource won't be used by other threads
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+ if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE)
+ {
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+#ifdef BLOCK_NET_IF
+ StopNetIfQueue(pAd, QueIdx, pPacket);
+#endif // BLOCK_NET_IF //
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+
+ return NDIS_STATUS_FAILURE;
+ }
+ else
+ {
+ InsertTailQueue(&pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
+ }
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE)&&
+ IS_HT_STA(pEntry))
+ {
+ //PMAC_TABLE_ENTRY pMacEntry = &pAd->MacTab.Content[BSSID_WCID];
+ if (((pEntry->TXBAbitmap & (1<<UserPriority)) == 0) &&
+ ((pEntry->BADeclineBitmap & (1<<UserPriority)) == 0) &&
+ (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
+ // For IOT compatibility, if
+ // 1. It is Ralink chip or
+ // 2. It is OPEN or AES mode,
+ // then BA session can be bulit.
+ && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0) ||
+ (pEntry->WepStatus == Ndis802_11WEPDisabled || pEntry->WepStatus == Ndis802_11Encryption3Enabled))
+ )
+ {
+ BAOriSessionSetUp(pAd, pEntry, 0, 0, 10, FALSE);
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+ pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++; // TODO: for debug only. to be removed
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ This subroutine will scan through releative ring descriptor to find
+ out avaliable free ring descriptor and compare with request size.
+
+ Arguments:
+ pAd Pointer to our adapter
+ QueIdx Selected TX Ring
+
+ Return Value:
+ NDIS_STATUS_FAILURE Not enough free descriptor
+ NDIS_STATUS_SUCCESS Enough free descriptor
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+
+#ifdef RT2870
+/*
+ Actually, this function used to check if the TxHardware Queue still has frame need to send.
+ If no frame need to send, go to sleep, else, still wake up.
+*/
+NDIS_STATUS RTMPFreeTXDRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN UCHAR NumberRequired,
+ IN PUCHAR FreeNumberIs)
+{
+ //ULONG FreeNumber = 0;
+ NDIS_STATUS Status = NDIS_STATUS_FAILURE;
+ unsigned long IrqFlags;
+ HT_TX_CONTEXT *pHTTXContext;
+
+ switch (QueIdx)
+ {
+ case QID_AC_BK:
+ case QID_AC_BE:
+ case QID_AC_VI:
+ case QID_AC_VO:
+ case QID_HCCA:
+ {
+ pHTTXContext = &pAd->TxContext[QueIdx];
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+ if ((pHTTXContext->CurWritePosition != pHTTXContext->ENextBulkOutPosition) ||
+ (pHTTXContext->IRPPending == TRUE))
+ {
+ Status = NDIS_STATUS_FAILURE;
+ }
+ else
+ {
+ Status = NDIS_STATUS_SUCCESS;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+ }
+ break;
+
+ case QID_MGMT:
+ if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE)
+ Status = NDIS_STATUS_FAILURE;
+ else
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
+ break;
+ }
+
+ return (Status);
+
+}
+#endif // RT2870 //
+
+
+VOID RTMPSendDisassociationFrame(
+ IN PRTMP_ADAPTER pAd)
+{
+}
+
+VOID RTMPSendNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull)
+{
+ UCHAR NullFrame[48];
+ ULONG Length;
+ PHEADER_802_11 pHeader_802_11;
+
+
+#ifdef RALINK_ATE
+ if(ATE_ON(pAd))
+ {
+ return;
+ }
+#endif // RALINK_ATE //
+
+ // WPA 802.1x secured port control
+ if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+#ifdef WPA_SUPPLICANT_SUPPORT
+ || (pAd->StaCfg.IEEE8021X == TRUE)
+#endif
+ ) &&
+ (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ {
+ return;
+ }
+
+ NdisZeroMemory(NullFrame, 48);
+ Length = sizeof(HEADER_802_11);
+
+ pHeader_802_11 = (PHEADER_802_11) NullFrame;
+
+ pHeader_802_11->FC.Type = BTYPE_DATA;
+ pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC;
+ pHeader_802_11->FC.ToDs = 1;
+ COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
+ COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
+
+ if (pAd->CommonCfg.bAPSDForcePowerSave)
+ {
+ pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+ }
+ else
+ {
+ pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE) ? 1: 0;
+ }
+ pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
+
+ pAd->Sequence++;
+ pHeader_802_11->Sequence = pAd->Sequence;
+
+ // Prepare QosNull function frame
+ if (bQosNull)
+ {
+ pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL;
+
+ // copy QOS control bytes
+ NullFrame[Length] = 0;
+ NullFrame[Length+1] = 0;
+ Length += 2;// if pad with 2 bytes for alignment, APSD will fail
+ }
+
+ HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length);
+
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID RTMPSendRTSFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN unsigned int NextMpduSize,
+ IN UCHAR TxRate,
+ IN UCHAR RTSRate,
+ IN USHORT AckDuration,
+ IN UCHAR QueIdx,
+ IN UCHAR FrameGap)
+{
+}
+
+
+
+// --------------------------------------------------------
+// FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM
+// Find the WPA key, either Group or Pairwise Key
+// LEAP + TKIP also use WPA key.
+// --------------------------------------------------------
+// Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst
+// In Cisco CCX 2.0 Leap Authentication
+// WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey
+// Instead of the SharedKey, SharedKey Length may be Zero.
+VOID STAFindCipherAlgorithm(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+ NDIS_802_11_ENCRYPTION_STATUS Cipher; // To indicate cipher used for this packet
+ UCHAR CipherAlg = CIPHER_NONE; // cipher alogrithm
+ UCHAR KeyIdx = 0xff;
+ PUCHAR pSrcBufVA;
+ PCIPHER_KEY pKey = NULL;
+
+ pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket);
+
+ {
+ // Select Cipher
+ if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
+ Cipher = pAd->StaCfg.GroupCipher; // Cipher for Multicast or Broadcast
+ else
+ Cipher = pAd->StaCfg.PairCipher; // Cipher for Unicast
+
+ if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
+ {
+ ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <= CIPHER_CKIP128);
+
+ // 4-way handshaking frame must be clear
+ if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame)) && (pAd->SharedKey[BSS0][0].CipherAlg) &&
+ (pAd->SharedKey[BSS0][0].KeyLen))
+ {
+ CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+ KeyIdx = 0;
+ }
+ }
+ else if (Cipher == Ndis802_11Encryption1Enabled)
+ {
+#ifdef LEAP_SUPPORT
+ if (pAd->StaCfg.CkipFlag & 0x10) // Cisco CKIP KP is on
+ {
+ if (LEAP_CCKM_ON(pAd))
+ {
+ if (((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))))
+ KeyIdx = 1;
+ else
+ KeyIdx = 0;
+ }
+ else
+ KeyIdx = pAd->StaCfg.DefaultKeyId;
+ }
+ else if (pAd->StaCfg.CkipFlag & 0x08) // only CKIP CMIC
+ KeyIdx = pAd->StaCfg.DefaultKeyId;
+ else if (LEAP_CCKM_ON(pAd))
+ {
+ if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
+ KeyIdx = 1;
+ else
+ KeyIdx = 0;
+ }
+ else // standard WEP64 or WEP128
+#endif // LEAP_SUPPORT //
+ KeyIdx = pAd->StaCfg.DefaultKeyId;
+ }
+ else if ((Cipher == Ndis802_11Encryption2Enabled) ||
+ (Cipher == Ndis802_11Encryption3Enabled))
+ {
+ if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) // multicast
+ KeyIdx = pAd->StaCfg.DefaultKeyId;
+ else if (pAd->SharedKey[BSS0][0].KeyLen)
+ KeyIdx = 0;
+ else
+ KeyIdx = pAd->StaCfg.DefaultKeyId;
+ }
+
+ if (KeyIdx == 0xff)
+ CipherAlg = CIPHER_NONE;
+ else if ((Cipher == Ndis802_11EncryptionDisabled) || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
+ CipherAlg = CIPHER_NONE;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ else if ( pAd->StaCfg.WpaSupplicantUP &&
+ (Cipher == Ndis802_11Encryption1Enabled) &&
+ (pAd->StaCfg.IEEE8021X == TRUE) &&
+ (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ CipherAlg = CIPHER_NONE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ else
+ {
+ //Header_802_11.FC.Wep = 1;
+ CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
+ pKey = &pAd->SharedKey[BSS0][KeyIdx];
+ }
+ }
+
+ pTxBlk->CipherAlg = CipherAlg;
+ pTxBlk->pKey = pKey;
+}
+
+
+VOID STABuildCommon802_11Header(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+
+ HEADER_802_11 *pHeader_802_11;
+#ifdef QOS_DLS_SUPPORT
+ BOOLEAN bDLSFrame = FALSE;
+ INT DlsEntryIndex = 0;
+#endif // QOS_DLS_SUPPORT //
+
+ //
+ // MAKE A COMMON 802.11 HEADER
+ //
+
+ // normal wlan header size : 24 octets
+ pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
+
+ pHeader_802_11 = (HEADER_802_11 *) &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+
+ NdisZeroMemory(pHeader_802_11, sizeof(HEADER_802_11));
+
+ pHeader_802_11->FC.FrDs = 0;
+ pHeader_802_11->FC.Type = BTYPE_DATA;
+ pHeader_802_11->FC.SubType = ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : SUBTYPE_DATA);
+
+#ifdef QOS_DLS_SUPPORT
+ if (INFRA_ON(pAd))
+ {
+ // Check if the frame can be sent through DLS direct link interface
+ // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
+ DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
+ if (DlsEntryIndex >= 0)
+ bDLSFrame = TRUE;
+ else
+ bDLSFrame = FALSE;
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ if (pTxBlk->pMacEntry)
+ {
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS))
+ {
+ pHeader_802_11->Sequence = pTxBlk->pMacEntry->NonQosDataSeq;
+ pTxBlk->pMacEntry->NonQosDataSeq = (pTxBlk->pMacEntry->NonQosDataSeq+1) & MAXSEQ;
+ }
+ else
+ {
+#ifdef QOS_DLS_SUPPORT
+ if (bDLSFrame)
+ {
+ pHeader_802_11->Sequence = pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence;
+ pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence = (pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence+1) & MAXSEQ;
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+ {
+ pHeader_802_11->Sequence = pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority];
+ pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = (pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
+ }
+ }
+ }
+ else
+ {
+ pHeader_802_11->Sequence = pAd->Sequence;
+ pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; // next sequence
+ }
+
+ pHeader_802_11->Frag = 0;
+
+ pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
+
+ {
+ if (INFRA_ON(pAd))
+ {
+#ifdef QOS_DLS_SUPPORT
+ if (bDLSFrame)
+ {
+ COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
+ COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
+ pHeader_802_11->FC.ToDs = 0;
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+ {
+ COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
+ COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHeader_802_11->Addr3, pTxBlk->pSrcBufHeader);
+ pHeader_802_11->FC.ToDs = 1;
+ }
+ }
+ else if (ADHOC_ON(pAd))
+ {
+ COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
+ COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
+ pHeader_802_11->FC.ToDs = 0;
+ }
+ }
+
+ if (pTxBlk->CipherAlg != CIPHER_NONE)
+ pHeader_802_11->FC.Wep = 1;
+
+ // -----------------------------------------------------------------
+ // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
+ // -----------------------------------------------------------------
+ if (pAd->CommonCfg.bAPSDForcePowerSave)
+ pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+ else
+ pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
+}
+
+#ifdef DOT11_N_SUPPORT
+VOID STABuildCache802_11Header(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR *pHeader)
+{
+ MAC_TABLE_ENTRY *pMacEntry;
+ PHEADER_802_11 pHeader80211;
+
+ pHeader80211 = (PHEADER_802_11)pHeader;
+ pMacEntry = pTxBlk->pMacEntry;
+
+ //
+ // Update the cached 802.11 HEADER
+ //
+
+ // normal wlan header size : 24 octets
+ pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
+
+ // More Bit
+ pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
+
+ // Sequence
+ pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority];
+ pMacEntry->TxSeq[pTxBlk->UserPriority] = (pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
+
+ {
+ // Check if the frame can be sent through DLS direct link interface
+ // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
+#ifdef QOS_DLS_SUPPORT
+ BOOLEAN bDLSFrame = FALSE;
+ INT DlsEntryIndex = 0;
+
+ DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
+ if (DlsEntryIndex >= 0)
+ bDLSFrame = TRUE;
+ else
+ bDLSFrame = FALSE;
+#endif // QOS_DLS_SUPPORT //
+
+ // The addr3 of normal packet send from DS is Dest Mac address.
+#ifdef QOS_DLS_SUPPORT
+ if (bDLSFrame)
+ {
+ COPY_MAC_ADDR(pHeader80211->Addr1, pTxBlk->pSrcBufHeader);
+ COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
+ pHeader80211->FC.ToDs = 0;
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+ if (ADHOC_ON(pAd))
+ COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
+ else
+ COPY_MAC_ADDR(pHeader80211->Addr3, pTxBlk->pSrcBufHeader);
+ }
+
+ // -----------------------------------------------------------------
+ // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
+ // -----------------------------------------------------------------
+ if (pAd->CommonCfg.bAPSDForcePowerSave)
+ pHeader80211->FC.PwrMgmt = PWR_SAVE;
+ else
+ pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
+}
+#endif // DOT11_N_SUPPORT //
+
+static inline PUCHAR STA_Build_ARalink_Frame_Header(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk)
+{
+ PUCHAR pHeaderBufPtr;
+ HEADER_802_11 *pHeader_802_11;
+ PNDIS_PACKET pNextPacket;
+ UINT32 nextBufLen;
+ PQUEUE_ENTRY pQEntry;
+
+ STAFindCipherAlgorithm(pAd, pTxBlk);
+ STABuildCommon802_11Header(pAd, pTxBlk);
+
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+ pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+ // steal "order" bit to mark "aggregation"
+ pHeader_802_11->FC.Order = 1;
+
+ // skip common header
+ pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
+ {
+ //
+ // build QOS Control bytes
+ //
+ *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+
+ *(pHeaderBufPtr+1) = 0;
+ pHeaderBufPtr +=2;
+ pTxBlk->MpduHeaderLen += 2;
+ }
+
+ // padding at front of LLC header. LLC header should at 4-bytes aligment.
+ pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+ pHeaderBufPtr = (PCHAR)ROUND_UP(pHeaderBufPtr, 4);
+ pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+ // For RA Aggregation,
+ // put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format
+ pQEntry = pTxBlk->TxPacketList.Head;
+ pNextPacket = QUEUE_ENTRY_TO_PKT(pQEntry);
+ nextBufLen = GET_OS_PKT_LEN(pNextPacket);
+ if (RTMP_GET_PACKET_VLAN(pNextPacket))
+ nextBufLen -= LENGTH_802_1Q;
+
+ *pHeaderBufPtr = (UCHAR)nextBufLen & 0xff;
+ *(pHeaderBufPtr+1) = (UCHAR)(nextBufLen >> 8);
+
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen += 2;
+
+ return pHeaderBufPtr;
+
+}
+
+#ifdef DOT11_N_SUPPORT
+static inline PUCHAR STA_Build_AMSDU_Frame_Header(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk)
+{
+ PUCHAR pHeaderBufPtr;//, pSaveBufPtr;
+ HEADER_802_11 *pHeader_802_11;
+
+
+ STAFindCipherAlgorithm(pAd, pTxBlk);
+ STABuildCommon802_11Header(pAd, pTxBlk);
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+ pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+ // skip common header
+ pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+ //
+ // build QOS Control bytes
+ //
+ *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+
+ //
+ // A-MSDU packet
+ //
+ *pHeaderBufPtr |= 0x80;
+
+ *(pHeaderBufPtr+1) = 0;
+ pHeaderBufPtr +=2;
+ pTxBlk->MpduHeaderLen += 2;
+
+ //pSaveBufPtr = pHeaderBufPtr;
+
+ //
+ // padding at front of LLC header
+ // LLC header should locate at 4-octets aligment
+ //
+ // @@@ MpduHeaderLen excluding padding @@@
+ //
+ pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+ pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+ pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+ return pHeaderBufPtr;
+
+}
+
+
+VOID STA_AMPDU_Frame_Tx(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+ HEADER_802_11 *pHeader_802_11;
+ PUCHAR pHeaderBufPtr;
+ USHORT FreeNumber;
+ MAC_TABLE_ENTRY *pMacEntry;
+ BOOLEAN bVLANPkt;
+ PQUEUE_ENTRY pQEntry;
+
+ ASSERT(pTxBlk);
+
+ while(pTxBlk->TxPacketList.Head)
+ {
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if ( RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ continue;
+ }
+
+ bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+ pMacEntry = pTxBlk->pMacEntry;
+ if (pMacEntry->isCached)
+ {
+ // NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]!!!!
+ NdisMoveMemory((PUCHAR)&pTxBlk->HeaderBuf[TXINFO_SIZE], (PUCHAR)&pMacEntry->CachedBuf[0], TXWI_SIZE + sizeof(HEADER_802_11));
+ pHeaderBufPtr = (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
+ STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
+ }
+ else
+ {
+ STAFindCipherAlgorithm(pAd, pTxBlk);
+ STABuildCommon802_11Header(pAd, pTxBlk);
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+ }
+
+
+ pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+ // skip common header
+ pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+ //
+ // build QOS Control bytes
+ //
+ *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+ *(pHeaderBufPtr+1) = 0;
+ pHeaderBufPtr +=2;
+ pTxBlk->MpduHeaderLen += 2;
+
+ //
+ // build HTC+
+ // HTC control filed following QoS field
+ //
+ if ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_RDG_CAPABLE))
+ {
+ if (pMacEntry->isCached == FALSE)
+ {
+ // mark HTC bit
+ pHeader_802_11->FC.Order = 1;
+
+ NdisZeroMemory(pHeaderBufPtr, 4);
+ *(pHeaderBufPtr+3) |= 0x80;
+ }
+ pHeaderBufPtr += 4;
+ pTxBlk->MpduHeaderLen += 4;
+ }
+
+ //pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE;
+ ASSERT(pTxBlk->MpduHeaderLen >= 24);
+
+ // skip 802.3 header
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+ pTxBlk->SrcBufLen -= LENGTH_802_3;
+
+ // skip vlan tag
+ if (bVLANPkt)
+ {
+ pTxBlk->pSrcBufData += LENGTH_802_1Q;
+ pTxBlk->SrcBufLen -= LENGTH_802_1Q;
+ }
+
+ //
+ // padding at front of LLC header
+ // LLC header should locate at 4-octets aligment
+ //
+ // @@@ MpduHeaderLen excluding padding @@@
+ //
+ pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+ pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+ pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+ {
+
+ //
+ // Insert LLC-SNAP encapsulation - 8 octets
+ //
+ EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
+ if (pTxBlk->pExtraLlcSnapEncap)
+ {
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+ pHeaderBufPtr += 6;
+ // get 2 octets (TypeofLen)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+ }
+
+ }
+
+ if (pMacEntry->isCached)
+ {
+ RTMPWriteTxWI_Cache(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+ }
+ else
+ {
+ RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+ NdisZeroMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), sizeof(pMacEntry->CachedBuf));
+ NdisMoveMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (pHeaderBufPtr - (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE])));
+ pMacEntry->isCached = TRUE;
+ }
+
+ // calculate Transmitted AMPDU count and ByteCount
+ {
+ pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.LowPart ++;
+ pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.QuadPart += pTxBlk->SrcBufLen;
+ }
+
+ //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
+
+ HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
+
+ //
+ // Kick out Tx
+ //
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+ }
+
+}
+
+
+VOID STA_AMSDU_Frame_Tx(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+ PUCHAR pHeaderBufPtr;
+ USHORT FreeNumber;
+ USHORT subFramePayloadLen = 0; // AMSDU Subframe length without AMSDU-Header / Padding.
+ USHORT totalMPDUSize=0;
+ UCHAR *subFrameHeader;
+ UCHAR padding = 0;
+ USHORT FirstTx = 0, LastTxIdx = 0;
+ BOOLEAN bVLANPkt;
+ int frameNum = 0;
+ PQUEUE_ENTRY pQEntry;
+
+
+ ASSERT(pTxBlk);
+
+ ASSERT((pTxBlk->TxPacketList.Number > 1));
+
+ while(pTxBlk->TxPacketList.Head)
+ {
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ continue;
+ }
+
+ bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+ // skip 802.3 header
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+ pTxBlk->SrcBufLen -= LENGTH_802_3;
+
+ // skip vlan tag
+ if (bVLANPkt)
+ {
+ pTxBlk->pSrcBufData += LENGTH_802_1Q;
+ pTxBlk->SrcBufLen -= LENGTH_802_1Q;
+ }
+
+ if (frameNum == 0)
+ {
+ pHeaderBufPtr = STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);
+
+ // NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled.
+ RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+ }
+ else
+ {
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
+ padding = ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen, 4) - (LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen);
+ NdisZeroMemory(pHeaderBufPtr, padding + LENGTH_AMSDU_SUBFRAMEHEAD);
+ pHeaderBufPtr += padding;
+ pTxBlk->MpduHeaderLen = padding;
+ }
+
+ //
+ // A-MSDU subframe
+ // DA(6)+SA(6)+Length(2) + LLC/SNAP Encap
+ //
+ subFrameHeader = pHeaderBufPtr;
+ subFramePayloadLen = pTxBlk->SrcBufLen;
+
+ NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);
+
+
+ pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD;
+ pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD;
+
+
+ //
+ // Insert LLC-SNAP encapsulation - 8 octets
+ //
+ EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
+
+ subFramePayloadLen = pTxBlk->SrcBufLen;
+
+ if (pTxBlk->pExtraLlcSnapEncap)
+ {
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+ pHeaderBufPtr += 6;
+ // get 2 octets (TypeofLen)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+ subFramePayloadLen += LENGTH_802_1_H;
+ }
+
+ // update subFrame Length field
+ subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8;
+ subFrameHeader[13] = subFramePayloadLen & 0xFF;
+
+ totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+
+ if (frameNum ==0)
+ FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+ else
+ LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+
+ frameNum++;
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+ // calculate Transmitted AMSDU Count and ByteCount
+ {
+ pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart ++;
+ pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart += totalMPDUSize;
+ }
+
+ }
+
+ HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
+ HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
+
+ //
+ // Kick out Tx
+ //
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+}
+#endif // DOT11_N_SUPPORT //
+
+VOID STA_Legacy_Frame_Tx(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+ HEADER_802_11 *pHeader_802_11;
+ PUCHAR pHeaderBufPtr;
+ USHORT FreeNumber;
+ BOOLEAN bVLANPkt;
+ PQUEUE_ENTRY pQEntry;
+
+ ASSERT(pTxBlk);
+
+
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ if (pTxBlk->TxFrameType == TX_MCAST_FRAME)
+ {
+ INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);
+ }
+
+ if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket))
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired);
+ else
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired);
+
+ bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+ if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate)
+ pTxBlk->TxRate = pAd->CommonCfg.MinTxRate;
+
+ STAFindCipherAlgorithm(pAd, pTxBlk);
+ STABuildCommon802_11Header(pAd, pTxBlk);
+
+
+ // skip 802.3 header
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+ pTxBlk->SrcBufLen -= LENGTH_802_3;
+
+ // skip vlan tag
+ if (bVLANPkt)
+ {
+ pTxBlk->pSrcBufData += LENGTH_802_1Q;
+ pTxBlk->SrcBufLen -= LENGTH_802_1Q;
+ }
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+ pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+ // skip common header
+ pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
+ {
+ //
+ // build QOS Control bytes
+ //
+ *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+ *(pHeaderBufPtr+1) = 0;
+ pHeaderBufPtr +=2;
+ pTxBlk->MpduHeaderLen += 2;
+ }
+
+ // The remaining content of MPDU header should locate at 4-octets aligment
+ pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+ pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+ pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+ {
+
+ //
+ // Insert LLC-SNAP encapsulation - 8 octets
+ //
+ //
+ // if original Ethernet frame contains no LLC/SNAP,
+ // then an extra LLC/SNAP encap is required
+ //
+ EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
+ if (pTxBlk->pExtraLlcSnapEncap)
+ {
+ UCHAR vlan_size;
+
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+ pHeaderBufPtr += 6;
+ // skip vlan tag
+ vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
+ // get 2 octets (TypeofLen)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+ }
+
+ }
+
+ //
+ // prepare for TXWI
+ // use Wcid as Key Index
+ //
+
+ RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+ //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
+
+ HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+ //
+ // Kick out Tx
+ //
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+}
+
+
+VOID STA_ARalink_Frame_Tx(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+ PUCHAR pHeaderBufPtr;
+ USHORT FreeNumber;
+ USHORT totalMPDUSize=0;
+ USHORT FirstTx, LastTxIdx;
+ int frameNum = 0;
+ BOOLEAN bVLANPkt;
+ PQUEUE_ENTRY pQEntry;
+
+
+ ASSERT(pTxBlk);
+
+ ASSERT((pTxBlk->TxPacketList.Number== 2));
+
+
+ FirstTx = LastTxIdx = 0; // Is it ok init they as 0?
+ while(pTxBlk->TxPacketList.Head)
+ {
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+
+ if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ continue;
+ }
+
+ bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+ // skip 802.3 header
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+ pTxBlk->SrcBufLen -= LENGTH_802_3;
+
+ // skip vlan tag
+ if (bVLANPkt)
+ {
+ pTxBlk->pSrcBufData += LENGTH_802_1Q;
+ pTxBlk->SrcBufLen -= LENGTH_802_1Q;
+ }
+
+ if (frameNum == 0)
+ { // For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header
+
+ pHeaderBufPtr = STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
+
+ // It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount
+ // will be updated after final frame was handled.
+ RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+
+ //
+ // Insert LLC-SNAP encapsulation - 8 octets
+ //
+ EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
+
+ if (pTxBlk->pExtraLlcSnapEncap)
+ {
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+ pHeaderBufPtr += 6;
+ // get 2 octets (TypeofLen)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+ }
+ }
+ else
+ { // For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0.
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
+ pTxBlk->MpduHeaderLen = 0;
+
+ // A-Ralink sub-sequent frame header is the same as 802.3 header.
+ // DA(6)+SA(6)+FrameType(2)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader, 12);
+ pHeaderBufPtr += 12;
+ // get 2 octets (TypeofLen)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD;
+ }
+
+ totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+
+ //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
+ if (frameNum ==0)
+ FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+ else
+ LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+
+ frameNum++;
+
+ pAd->RalinkCounters.OneSecTxAggregationCount++;
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+ }
+
+ HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
+ HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
+
+ //
+ // Kick out Tx
+ //
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+
+}
+
+
+VOID STA_Fragment_Frame_Tx(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk)
+{
+ HEADER_802_11 *pHeader_802_11;
+ PUCHAR pHeaderBufPtr;
+ USHORT FreeNumber;
+ UCHAR fragNum = 0;
+ PACKET_INFO PacketInfo;
+ USHORT EncryptionOverhead = 0;
+ UINT32 FreeMpduSize, SrcRemainingBytes;
+ USHORT AckDuration;
+ UINT NextMpduSize;
+ BOOLEAN bVLANPkt;
+ PQUEUE_ENTRY pQEntry;
+
+
+ ASSERT(pTxBlk);
+
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag));
+ bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+ STAFindCipherAlgorithm(pAd, pTxBlk);
+ STABuildCommon802_11Header(pAd, pTxBlk);
+
+ if (pTxBlk->CipherAlg == CIPHER_TKIP)
+ {
+ pTxBlk->pPacket = duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
+ if (pTxBlk->pPacket == NULL)
+ return;
+ RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
+ }
+
+ // skip 802.3 header
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+ pTxBlk->SrcBufLen -= LENGTH_802_3;
+
+
+ // skip vlan tag
+ if (bVLANPkt)
+ {
+ pTxBlk->pSrcBufData += LENGTH_802_1Q;
+ pTxBlk->SrcBufLen -= LENGTH_802_1Q;
+ }
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+ pHeader_802_11 = (HEADER_802_11 *)pHeaderBufPtr;
+
+
+ // skip common header
+ pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
+ {
+ //
+ // build QOS Control bytes
+ //
+ *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+
+ *(pHeaderBufPtr+1) = 0;
+ pHeaderBufPtr +=2;
+ pTxBlk->MpduHeaderLen += 2;
+ }
+
+ //
+ // padding at front of LLC header
+ // LLC header should locate at 4-octets aligment
+ //
+ pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+ pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+ pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+
+
+ //
+ // Insert LLC-SNAP encapsulation - 8 octets
+ //
+ //
+ // if original Ethernet frame contains no LLC/SNAP,
+ // then an extra LLC/SNAP encap is required
+ //
+ EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
+ if (pTxBlk->pExtraLlcSnapEncap)
+ {
+ UCHAR vlan_size;
+
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+ pHeaderBufPtr += 6;
+ // skip vlan tag
+ vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
+ // get 2 octets (TypeofLen)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+ }
+
+
+ // If TKIP is used and fragmentation is required. Driver has to
+ // append TKIP MIC at tail of the scatter buffer
+ // MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC
+ if (pTxBlk->CipherAlg == CIPHER_TKIP)
+ {
+
+ // NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust
+ // to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress.
+ NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen, &pAd->PrivateInfo.Tx.MIC[0], 8);
+ //skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8);
+ pTxBlk->SrcBufLen += 8;
+ pTxBlk->TotalFrameLen += 8;
+ pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
+ }
+
+ //
+ // calcuate the overhead bytes that encryption algorithm may add. This
+ // affects the calculate of "duration" field
+ //
+ if ((pTxBlk->CipherAlg == CIPHER_WEP64) || (pTxBlk->CipherAlg == CIPHER_WEP128))
+ EncryptionOverhead = 8; //WEP: IV[4] + ICV[4];
+ else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC)
+ EncryptionOverhead = 12;//TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength
+ else if (pTxBlk->CipherAlg == CIPHER_TKIP)
+ EncryptionOverhead = 20;//TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8]
+ else if (pTxBlk->CipherAlg == CIPHER_AES)
+ EncryptionOverhead = 16; // AES: IV[4] + EIV[4] + MIC[8]
+ else
+ EncryptionOverhead = 0;
+
+ // decide how much time an ACK/CTS frame will consume in the air
+ AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 14);
+
+ // Init the total payload length of this frame.
+ SrcRemainingBytes = pTxBlk->SrcBufLen;
+
+ pTxBlk->TotalFragNum = 0xff;
+
+ do {
+
+ FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC;
+
+ FreeMpduSize -= pTxBlk->MpduHeaderLen;
+
+ if (SrcRemainingBytes <= FreeMpduSize)
+ { // this is the last or only fragment
+
+ pTxBlk->SrcBufLen = SrcRemainingBytes;
+
+ pHeader_802_11->FC.MoreFrag = 0;
+ pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + AckDuration;
+
+ // Indicate the lower layer that this's the last fragment.
+ pTxBlk->TotalFragNum = fragNum;
+ }
+ else
+ { // more fragment is required
+
+ pTxBlk->SrcBufLen = FreeMpduSize;
+
+ NextMpduSize = min(((UINT)SrcRemainingBytes - pTxBlk->SrcBufLen), ((UINT)pAd->CommonCfg.FragmentThreshold));
+ pHeader_802_11->FC.MoreFrag = 1;
+ pHeader_802_11->Duration = (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) + RTMPCalcDuration(pAd, pTxBlk->TxRate, NextMpduSize + EncryptionOverhead);
+ }
+
+ if (fragNum == 0)
+ pTxBlk->FrameGap = IFS_HTTXOP;
+ else
+ pTxBlk->FrameGap = IFS_SIFS;
+
+ RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+ HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber);
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+ // Update the frame number, remaining size of the NDIS packet payload.
+
+ // space for 802.11 header.
+ if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
+ pTxBlk->MpduHeaderLen -= LENGTH_802_1_H;
+
+ fragNum++;
+ SrcRemainingBytes -= pTxBlk->SrcBufLen;
+ pTxBlk->pSrcBufData += pTxBlk->SrcBufLen;
+
+ pHeader_802_11->Frag++; // increase Frag #
+
+ }while(SrcRemainingBytes > 0);
+
+ //
+ // Kick out Tx
+ //
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+}
+
+
+#define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status) \
+ while(_pTxBlk->TxPacketList.Head) \
+ { \
+ _pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList); \
+ RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status); \
+ }
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Copy frame from waiting queue into relative ring buffer and set
+ appropriate ASIC register to kick hardware encryption before really
+ sent out to air.
+
+ Arguments:
+ pAd Pointer to our adapter
+ PNDIS_PACKET Pointer to outgoing Ndis frame
+ NumberOfFrag Number of fragment required
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS STAHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR QueIdx)
+{
+ NDIS_PACKET *pPacket;
+ PQUEUE_ENTRY pQEntry;
+
+ // ---------------------------------------------
+ // STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION.
+ // ---------------------------------------------
+ //
+ ASSERT(pTxBlk->TxPacketList.Number);
+ if (pTxBlk->TxPacketList.Head == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pTxBlk->TotalFrameNum == %ld!\n", pTxBlk->TxPacketList.Number));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head);
+
+ // ------------------------------------------------------------------
+ // STEP 1. WAKE UP PHY
+ // outgoing frame always wakeup PHY to prevent frame lost and
+ // turn off PSM bit to improve performance
+ // ------------------------------------------------------------------
+ // not to change PSM bit, just send this frame out?
+ if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicForceWakeup At HardTx\n"));
+ AsicForceWakeup(pAd, TRUE);
+ }
+
+ // It should not change PSM bit, when APSD turn on.
+ if ((!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
+ || (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
+ || (RTMP_GET_PACKET_WAI(pTxBlk->pPacket)))
+ {
+ if ((pAd->StaCfg.Psm == PWR_SAVE) &&
+ (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP))
+ MlmeSetPsmBit(pAd, PWR_ACTIVE);
+ }
+
+ switch (pTxBlk->TxFrameType)
+ {
+#ifdef DOT11_N_SUPPORT
+ case TX_AMPDU_FRAME:
+ STA_AMPDU_Frame_Tx(pAd, pTxBlk);
+ break;
+ case TX_AMSDU_FRAME:
+ STA_AMSDU_Frame_Tx(pAd, pTxBlk);
+ break;
+#endif // DOT11_N_SUPPORT //
+ case TX_LEGACY_FRAME:
+ STA_Legacy_Frame_Tx(pAd, pTxBlk);
+ break;
+ case TX_MCAST_FRAME:
+ STA_Legacy_Frame_Tx(pAd, pTxBlk);
+ break;
+ case TX_RALINK_FRAME:
+ STA_ARalink_Frame_Tx(pAd, pTxBlk);
+ break;
+ case TX_FRAG_FRAME:
+ STA_Fragment_Frame_Tx(pAd, pTxBlk);
+ break;
+ default:
+ {
+ // It should not happened!
+ DBGPRINT(RT_DEBUG_ERROR, ("Send a pacekt was not classified!! It should not happen!\n"));
+ while(pTxBlk->TxPacketList.Number)
+ {
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if (pPacket)
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+ }
+ break;
+ }
+
+ return (NDIS_STATUS_SUCCESS);
+
+}
+
+ULONG HashBytesPolynomial(UCHAR *value, unsigned int len)
+{
+ unsigned char *word = value;
+ unsigned int ret = 0;
+ unsigned int i;
+
+ for(i=0; i < len; i++)
+ {
+ int mod = i % 32;
+ ret ^=(unsigned int) (word[i]) << mod;
+ ret ^=(unsigned int) (word[i]) >> (32 - mod);
+ }
+ return ret;
+}
+
+VOID Sta_Announce_or_Forward_802_3_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR FromWhichBSSID)
+{
+ if (TRUE
+ )
+ {
+ announce_802_3_packet(pAd, pPacket);
+ }
+ else
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+}
+
diff --git a/drivers/staging/rt3070/sta/sanity.c b/drivers/staging/rt3070/sta/sanity.c
new file mode 100644
index 00000000000..239872464be
--- /dev/null
+++ b/drivers/staging/rt3070/sta/sanity.c
@@ -0,0 +1,420 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ sanity.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2004-09-01 add WMM support
+*/
+#include "../rt_config.h"
+
+extern UCHAR CISCO_OUI[];
+
+extern UCHAR WPA_OUI[];
+extern UCHAR RSN_OUI[];
+extern UCHAR WME_INFO_ELEM[];
+extern UCHAR WME_PARM_ELEM[];
+extern UCHAR Ccx2QosInfo[];
+extern UCHAR RALINK_OUI[];
+extern UCHAR BROADCOM_OUI[];
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+ */
+BOOLEAN MlmeStartReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT CHAR Ssid[],
+ OUT UCHAR *pSsidLen)
+{
+ MLME_START_REQ_STRUCT *Info;
+
+ Info = (MLME_START_REQ_STRUCT *)(Msg);
+
+ if (Info->SsidLen > MAX_LEN_OF_SSID)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqSanity fail - wrong SSID length\n"));
+ return FALSE;
+ }
+
+ *pSsidLen = Info->SsidLen;
+ NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerAssocRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pStatus,
+ OUT USHORT *pAid,
+ OUT UCHAR SupRate[],
+ OUT UCHAR *pSupRateLen,
+ OUT UCHAR ExtRate[],
+ OUT UCHAR *pExtRateLen,
+ OUT HT_CAPABILITY_IE *pHtCapability,
+ OUT ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ OUT UCHAR *pHtCapabilityLen,
+ OUT UCHAR *pAddHtInfoLen,
+ OUT UCHAR *pNewExtChannelOffset,
+ OUT PEDCA_PARM pEdcaParm,
+ OUT UCHAR *pCkipFlag)
+{
+ CHAR IeType, *Ptr;
+ PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
+ PEID_STRUCT pEid;
+ ULONG Length = 0;
+
+ *pNewExtChannelOffset = 0xff;
+ *pHtCapabilityLen = 0;
+ *pAddHtInfoLen = 0;
+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+ Ptr = pFrame->Octet;
+ Length += LENGTH_802_11;
+
+ NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2);
+ Length += 2;
+ NdisMoveMemory(pStatus, &pFrame->Octet[2], 2);
+ Length += 2;
+ *pCkipFlag = 0;
+ *pExtRateLen = 0;
+ pEdcaParm->bValid = FALSE;
+
+ if (*pStatus != MLME_SUCCESS)
+ return TRUE;
+
+ NdisMoveMemory(pAid, &pFrame->Octet[4], 2);
+ Length += 2;
+
+ // Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform
+ *pAid = (*pAid) & 0x3fff; // AID is low 14-bit
+
+ // -- get supported rates from payload and advance the pointer
+ IeType = pFrame->Octet[6];
+ *pSupRateLen = pFrame->Octet[7];
+ if ((IeType != IE_SUPP_RATES) || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity fail - wrong SupportedRates IE\n"));
+ return FALSE;
+ }
+ else
+ NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen);
+
+ Length = Length + 2 + *pSupRateLen;
+
+ // many AP implement proprietary IEs in non-standard order, we'd better
+ // tolerate mis-ordered IEs to get best compatibility
+ pEid = (PEID_STRUCT) &pFrame->Octet[8 + (*pSupRateLen)];
+
+ // get variable fields from payload and advance the pointer
+ while ((Length + 2 + pEid->Len) <= MsgLen)
+ {
+ switch (pEid->Eid)
+ {
+ case IE_EXT_SUPP_RATES:
+ if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
+ *pExtRateLen = pEid->Len;
+ }
+ break;
+
+ case IE_HT_CAP:
+ case IE_HT_CAP2:
+ if (pEid->Len >= SIZE_HT_CAP_IE) //Note: allow extension.!!
+ {
+ NdisMoveMemory(pHtCapability, pEid->Octet, SIZE_HT_CAP_IE);
+
+ *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
+ *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+
+ *pHtCapabilityLen = SIZE_HT_CAP_IE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_HT_CAP. \n"));
+ }
+
+ break;
+#ifdef DOT11_N_SUPPORT
+ case IE_ADD_HT:
+ case IE_ADD_HT2:
+ if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
+ {
+ // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
+ // copy first sizeof(ADD_HT_INFO_IE)
+ NdisMoveMemory(pAddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
+
+ *(USHORT *)(&pAddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo2));
+ *(USHORT *)(&pAddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo3));
+
+ *pAddHtInfoLen = SIZE_ADD_HT_INFO_IE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_ADD_HT. \n"));
+ }
+
+ break;
+ case IE_SECONDARY_CH_OFFSET:
+ if (pEid->Len == 1)
+ {
+ *pNewExtChannelOffset = pEid->Octet[0];
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
+ }
+#endif // DOT11_N_SUPPORT //
+ break;
+ case IE_AIRONET_CKIP:
+ // 0. Check Aironet IE length, it must be larger or equal to 28
+ // Cisco's AP VxWork version(will not be supported) used this IE length as 28
+ // Cisco's AP IOS version used this IE length as 30
+ if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
+ break;
+
+ // 1. Copy CKIP flag byte to buffer for process
+ *pCkipFlag = *(pEid->Octet + 8);
+ break;
+
+ case IE_AIRONET_IPADDRESS:
+ if (pEid->Len != 0x0A)
+ break;
+
+ // Get Cisco Aironet IP information
+ if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
+ NdisMoveMemory(pAd->StaCfg.AironetIPAddress, pEid->Octet + 4, 4);
+ break;
+
+ // CCX2, WMM use the same IE value
+ // case IE_CCX_V2:
+ case IE_VENDOR_SPECIFIC:
+ // handle WME PARAMTER ELEMENT
+ if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
+ {
+ PUCHAR ptr;
+ int i;
+
+ // parsing EDCA parameters
+ pEdcaParm->bValid = TRUE;
+ pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
+ pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
+ pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
+ //pEdcaParm->bMoreDataAck = FALSE; // pEid->Octet[0] & 0x80;
+ pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
+ pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
+ ptr = &pEid->Octet[8];
+ for (i=0; i<4; i++)
+ {
+ UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
+ pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); // b5 is ACM
+ pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; // b0~3 is AIFSN
+ pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f; // b0~4 is Cwmin
+ pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4; // b5~8 is Cwmax
+ pEdcaParm->Txop[aci] = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
+ ptr += 4; // point to next AC
+ }
+ }
+
+ // handle CCX IE
+ else
+ {
+ // 0. Check the size and CCX admin control
+ if (pAd->StaCfg.CCXControl.field.Enable == 0)
+ break;
+ if (pEid->Len != 5)
+ break;
+
+ // Turn CCX2 if matched
+ if (NdisEqualMemory(pEid->Octet, Ccx2IeInfo, 5) == 1)
+ pAd->StaCfg.CCXEnable = TRUE;
+ break;
+ }
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid->Eid));
+ break;
+ }
+
+ Length = Length + 2 + pEid->Len;
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+ }
+
+ // Force CCX2 enable to TRUE for those AP didn't replay CCX v2 IE, we still force it to be on
+ if (pAd->StaCfg.CCXControl.field.Enable == 1)
+ pAd->StaCfg.CCXEnable = TRUE;
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerProbeReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT CHAR Ssid[],
+ OUT UCHAR *pSsidLen)
+{
+ UCHAR Idx;
+ UCHAR RateLen;
+ CHAR IeType;
+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+
+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+
+ if ((pFrame->Octet[0] != IE_SSID) || (pFrame->Octet[1] > MAX_LEN_OF_SSID))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",pFrame->Octet[0],pFrame->Octet[1]));
+ return FALSE;
+ }
+
+ *pSsidLen = pFrame->Octet[1];
+ NdisMoveMemory(Ssid, &pFrame->Octet[2], *pSsidLen);
+
+ Idx = *pSsidLen + 2;
+
+ // -- get supported rates from payload and advance the pointer
+ IeType = pFrame->Octet[Idx];
+ RateLen = pFrame->Octet[Idx + 1];
+ if (IeType != IE_SUPP_RATES)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",pFrame->Octet[Idx],pFrame->Octet[Idx+1]));
+ return FALSE;
+ }
+ else
+ {
+ if ((pAd->CommonCfg.PhyMode == PHY_11G) && (RateLen < 8))
+ return (FALSE);
+ }
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN GetTimBit(
+ IN CHAR *Ptr,
+ IN USHORT Aid,
+ OUT UCHAR *TimLen,
+ OUT UCHAR *BcastFlag,
+ OUT UCHAR *DtimCount,
+ OUT UCHAR *DtimPeriod,
+ OUT UCHAR *MessageToMe)
+{
+ UCHAR BitCntl, N1, N2, MyByte, MyBit;
+ CHAR *IdxPtr;
+
+ IdxPtr = Ptr;
+
+ IdxPtr ++;
+ *TimLen = *IdxPtr;
+
+ // get DTIM Count from TIM element
+ IdxPtr ++;
+ *DtimCount = *IdxPtr;
+
+ // get DTIM Period from TIM element
+ IdxPtr++;
+ *DtimPeriod = *IdxPtr;
+
+ // get Bitmap Control from TIM element
+ IdxPtr++;
+ BitCntl = *IdxPtr;
+
+ if ((*DtimCount == 0) && (BitCntl & 0x01))
+ *BcastFlag = TRUE;
+ else
+ *BcastFlag = FALSE;
+
+ // Parse Partial Virtual Bitmap from TIM element
+ N1 = BitCntl & 0xfe; // N1 is the first bitmap byte#
+ N2 = *TimLen - 4 + N1; // N2 is the last bitmap byte#
+
+ if ((Aid < (N1 << 3)) || (Aid >= ((N2 + 1) << 3)))
+ *MessageToMe = FALSE;
+ else
+ {
+ MyByte = (Aid >> 3) - N1; // my byte position in the bitmap byte-stream
+ MyBit = Aid % 16 - ((MyByte & 0x01)? 8:0);
+
+ IdxPtr += (MyByte + 1);
+
+ //if (*IdxPtr)
+ // DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr));
+
+ if (*IdxPtr & (0x01 << MyBit))
+ *MessageToMe = TRUE;
+ else
+ *MessageToMe = FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/drivers/staging/rt3070/sta/sync.c b/drivers/staging/rt3070/sta/sync.c
new file mode 100644
index 00000000000..2b5b3b07661
--- /dev/null
+++ b/drivers/staging/rt3070/sta/sync.c
@@ -0,0 +1,1755 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ sync.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2004-09-01 modified for rt2561/2661
+ Jan Lee 2006-08-01 modified for rt2860 for 802.11n
+*/
+#include "../rt_config.h"
+
+#define ADHOC_ENTRY_BEACON_LOST_TIME (2*OS_HZ) // 2 sec
+
+/*
+ ==========================================================================
+ Description:
+ The sync state machine,
+ Parameters:
+ Sm - pointer to the state machine
+ Note:
+ the state machine looks like the following
+
+ ==========================================================================
+ */
+VOID SyncStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE);
+
+ // column 1
+ StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction);
+ StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction);
+ StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)MlmeStartReqAction);
+ StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon);
+ StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction);
+
+ //column 2
+ StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
+ StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
+ StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
+ StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtJoinAction);
+ StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, (STATE_MACHINE_FUNC)BeaconTimeoutAtJoinAction);
+
+ // column 3
+ StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
+ StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
+ StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
+ StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
+ StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
+ StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction);
+
+ // timer init
+ RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
+ RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Beacon timeout handler, executed in timer thread
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID BeaconTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ DBGPRINT(RT_DEBUG_TRACE,("SYNC - BeaconTimeout\n"));
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
+ return;
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
+ )
+ {
+ UCHAR BBPValue = 0;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= (~0x18);
+ BBPValue |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
+ }
+#endif // DOT11_N_SUPPORT //
+
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Scan timeout handler, executed in timer thread
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID ScanTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
+ return;
+
+ if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL))
+ {
+ RT28XX_MLME_HANDLER(pAd);
+ }
+ else
+ {
+ // To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
+ pAd->MlmeAux.Channel = 0;
+ ScanNextChannel(pAd);
+ if (pAd->CommonCfg.bWirelessEvent)
+ {
+ RTMPSendWirelessEvent(pAd, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME SCAN req state machine procedure
+ ==========================================================================
+ */
+VOID MlmeScanReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
+ BOOLEAN TimerCancelled;
+ ULONG Now;
+ USHORT Status;
+ PHEADER_802_11 pHdr80211;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+
+ // Check the total scan tries for one single OID command
+ // If this is the CCX 2.0 Case, skip that!
+ if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeScanReqAction before Startup\n"));
+ return;
+ }
+
+ // Increase the scan retry counters.
+ pAd->StaCfg.ScanCnt++;
+
+
+ // first check the parameter sanity
+ if (MlmeScanReqSanity(pAd,
+ Elem->Msg,
+ Elem->MsgLen,
+ &BssType,
+ Ssid,
+ &SsidLen,
+ &ScanType))
+ {
+
+ // Check for channel load and noise hist request
+ // Suspend MSDU only at scan request, not the last two mentioned
+ if ((ScanType == SCAN_CISCO_NOISE) || (ScanType == SCAN_CISCO_CHANNEL_LOAD))
+ {
+ if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+ RTMPSuspendMsduTransmission(pAd); // Suspend MSDU transmission here
+ }
+ else
+ {
+ // Suspend MSDU transmission here
+ RTMPSuspendMsduTransmission(pAd);
+ }
+
+ //
+ // To prevent data lost.
+ // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
+ // And should send an NULL data with turned PSM bit off to AP, when scan progress done
+ //
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
+ {
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
+ if (NStatus == NDIS_STATUS_SUCCESS)
+ {
+ pHdr80211 = (PHEADER_802_11) pOutBuffer;
+ MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+ pHdr80211->Duration = 0;
+ pHdr80211->FC.Type = BTYPE_DATA;
+ pHdr80211->FC.PwrMgmt = PWR_SAVE;
+
+ // Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
+ MlmeFreeMemory(pAd, pOutBuffer);
+ RTMPusecDelay(5000);
+ }
+ }
+
+ NdisGetSystemUpTime(&Now);
+ pAd->StaCfg.LastScanTime = Now;
+ // reset all the timers
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
+
+ // record desired BSS parameters
+ pAd->MlmeAux.BssType = BssType;
+ pAd->MlmeAux.ScanType = ScanType;
+ pAd->MlmeAux.SsidLen = SsidLen;
+ NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
+
+ // start from the first channel
+ pAd->MlmeAux.Channel = FirstChannel(pAd);
+
+ // Change the scan channel when dealing with CCX beacon report
+ if ((ScanType == SCAN_CISCO_PASSIVE) || (ScanType == SCAN_CISCO_ACTIVE) ||
+ (ScanType == SCAN_CISCO_CHANNEL_LOAD) || (ScanType == SCAN_CISCO_NOISE))
+ pAd->MlmeAux.Channel = pAd->StaCfg.CCXScanChannel;
+
+ // Let BBP register at 20MHz to do scan
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
+ ScanNextChannel(pAd);
+ }
+ else
+ {
+ DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_INVALID_FORMAT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME JOIN req state machine procedure
+ ==========================================================================
+ */
+VOID MlmeJoinReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR BBPValue = 0;
+ BSS_ENTRY *pBss;
+ BOOLEAN TimerCancelled;
+ HEADER_802_11 Hdr80211;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ PUCHAR pOutBuffer = NULL;
+ PUCHAR pSupRate = NULL;
+ UCHAR SupRateLen;
+ PUCHAR pExtRate = NULL;
+ UCHAR ExtRateLen;
+ UCHAR ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
+ UCHAR ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR);
+ MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
+
+
+ // reset all the timers
+ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
+
+ pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
+
+ // record the desired SSID & BSSID we're waiting for
+ COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
+
+ // If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
+ if (pBss->Hidden == 0)
+ {
+ NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
+ pAd->MlmeAux.SsidLen = pBss->SsidLen;
+ }
+
+ pAd->MlmeAux.BssType = pBss->BssType;
+ pAd->MlmeAux.Channel = pBss->Channel;
+ pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ // Country IE of the AP will be evaluated and will be used.
+ if ((pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None) &&
+ (pBss->bHasCountryIE == TRUE))
+ {
+ NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pBss->CountryString[0], 2);
+ if (pBss->CountryString[2] == 'I')
+ pAd->CommonCfg.Geography = IDOR;
+ else if (pBss->CountryString[2] == 'O')
+ pAd->CommonCfg.Geography = ODOR;
+ else
+ pAd->CommonCfg.Geography = BOTH;
+ BuildChannelListEx(pAd);
+ }
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+ // Let BBP register at 20MHz to do scan
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
+
+ // switch channel and waiting for beacon timer
+ AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->MlmeAux.Channel);
+ RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT);
+
+ do
+ {
+ if (((pAd->CommonCfg.bIEEE80211H == 1) &&
+ (pAd->MlmeAux.Channel > 14) &&
+ RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+ || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+#endif // CARRIER_DETECTION_SUPPORT //
+ )
+ {
+ //
+ // We can't send any Probe request frame to meet 802.11h.
+ //
+ if (pBss->Hidden == 0)
+ break;
+ }
+
+ //
+ // send probe request
+ //
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus == NDIS_STATUS_SUCCESS)
+ {
+ if (pAd->MlmeAux.Channel <= 14)
+ {
+ pSupRate = pAd->CommonCfg.SupRate;
+ SupRateLen = pAd->CommonCfg.SupRateLen;
+ pExtRate = pAd->CommonCfg.ExtRate;
+ ExtRateLen = pAd->CommonCfg.ExtRateLen;
+ }
+ else
+ {
+ //
+ // Overwrite Support Rate, CCK rate are not allowed
+ //
+ pSupRate = ASupRate;
+ SupRateLen = ASupRateLen;
+ ExtRateLen = 0;
+ }
+
+ if (pAd->MlmeAux.BssType == BSS_INFRA)
+ MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, pAd->MlmeAux.Bssid);
+ else
+ MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &Hdr80211,
+ 1, &SsidIe,
+ 1, &pAd->MlmeAux.SsidLen,
+ pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
+ 1, &SupRateIe,
+ 1, &SupRateLen,
+ SupRateLen, pSupRate,
+ END_OF_ARGS);
+
+ if (ExtRateLen)
+ {
+ ULONG Tmp;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &ExtRateIe,
+ 1, &ExtRateLen,
+ ExtRateLen, pExtRate,
+ END_OF_ARGS);
+ FrameLen += Tmp;
+ }
+
+
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+ } while (FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
+
+ pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME START Request state machine procedure, starting an IBSS
+ ==========================================================================
+ */
+VOID MlmeStartReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen;
+ BOOLEAN TimerCancelled;
+
+ // New for WPA security suites
+ UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
+ NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
+ LARGE_INTEGER TimeStamp;
+ BOOLEAN Privacy;
+ USHORT Status;
+
+ // Init Variable IE structure
+ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+ pVIE->Length = 0;
+ TimeStamp.u.LowPart = 0;
+ TimeStamp.u.HighPart = 0;
+
+ if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, Ssid, &SsidLen))
+ {
+ // reset all the timers
+ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
+
+ //
+ // Start a new IBSS. All IBSS parameters are decided now....
+ //
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
+ pAd->MlmeAux.BssType = BSS_ADHOC;
+ NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
+ pAd->MlmeAux.SsidLen = SsidLen;
+
+ // generate a radom number as BSSID
+ MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
+
+ Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
+ pAd->MlmeAux.CapabilityInfo = CAP_GENERATE(0,1,Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 1, 0);
+ pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod;
+ pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin;
+ pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
+
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel;
+
+ pAd->MlmeAux.SupRateLen= pAd->CommonCfg.SupRateLen;
+ NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
+ RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
+ pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
+ NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
+ RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ {
+ RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy, &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0], &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
+ pAd->MlmeAux.HtCapabilityLen = sizeof(HT_CAPABILITY_IE);
+ // Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ pAd->MlmeAux.HtCapabilityLen = 0;
+ pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+ }
+ // temporarily not support QOS in IBSS
+ NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
+ NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
+ NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
+
+ AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->MlmeAux.Channel);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
+ pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
+
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
+ }
+ else
+ {
+ DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_INVALID_FORMAT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ peer sends beacon back when scanning
+ ==========================================================================
+ */
+VOID PeerBeaconAtScanAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
+ UCHAR Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
+ SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
+ CF_PARM CfParm;
+ USHORT BeaconPeriod, AtimWin, CapabilityInfo;
+ PFRAME_802_11 pFrame;
+ LARGE_INTEGER TimeStamp;
+ UCHAR Erp;
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen, ExtRateLen;
+ USHORT LenVIE;
+ UCHAR CkipFlag;
+ UCHAR AironetCellPowerLimit;
+ EDCA_PARM EdcaParm;
+ QBSS_LOAD_PARM QbssLoad;
+ QOS_CAPABILITY_PARM QosCapability;
+ ULONG RalinkIe;
+ UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
+ NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
+ HT_CAPABILITY_IE HtCapability;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
+ UCHAR AddHtInfoLen;
+ UCHAR NewExtChannelOffset = 0xff;
+
+
+ // NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00);
+ pFrame = (PFRAME_802_11) Elem->Msg;
+ // Init Variable IE structure
+ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+ pVIE->Length = 0;
+#ifdef DOT11_N_SUPPORT
+ RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
+ RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
+#endif // DOT11_N_SUPPORT //
+
+ if (PeerBeaconAndProbeRspSanity(pAd,
+ Elem->Msg,
+ Elem->MsgLen,
+ Elem->Channel,
+ Addr2,
+ Bssid,
+ Ssid,
+ &SsidLen,
+ &BssType,
+ &BeaconPeriod,
+ &Channel,
+ &NewChannel,
+ &TimeStamp,
+ &CfParm,
+ &AtimWin,
+ &CapabilityInfo,
+ &Erp,
+ &DtimCount,
+ &DtimPeriod,
+ &BcastFlag,
+ &MessageToMe,
+ SupRate,
+ &SupRateLen,
+ ExtRate,
+ &ExtRateLen,
+ &CkipFlag,
+ &AironetCellPowerLimit,
+ &EdcaParm,
+ &QbssLoad,
+ &QosCapability,
+ &RalinkIe,
+ &HtCapabilityLen,
+ &PreNHtCapabilityLen,
+ &HtCapability,
+ &AddHtInfoLen,
+ &AddHtInfo,
+ &NewExtChannelOffset,
+ &LenVIE,
+ pVIE))
+ {
+ ULONG Idx;
+ CHAR Rssi = 0;
+
+ Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
+ if (Idx != BSS_NOT_FOUND)
+ Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
+
+ Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+
+
+#ifdef DOT11_N_SUPPORT
+ if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
+ HtCapabilityLen = SIZE_HT_CAP_IE;
+#endif // DOT11_N_SUPPORT //
+ if ((pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) && (Channel == pAd->StaCfg.CCXScanChannel))
+ {
+ Idx = BssTableSetEntry(pAd, &pAd->StaCfg.CCXBssTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
+ &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen,ExtRate, ExtRateLen, &HtCapability,
+ &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
+ &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
+ if (Idx != BSS_NOT_FOUND)
+ {
+ NdisMoveMemory(pAd->StaCfg.CCXBssTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
+ NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
+ NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
+ if (pAd->StaCfg.CCXReqType == MSRN_TYPE_BEACON_REQ)
+ AironetAddBeaconReport(pAd, Idx, Elem);
+ }
+ }
+ else
+ {
+ Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
+ &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
+ &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
+ &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if (pAd->ChannelList[pAd->CommonCfg.ChannelListIdx].bEffectedChannel == TRUE)
+ {
+ UCHAR RegClass;
+ PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &RegClass);
+ TriEventTableSetEntry(pAd, &pAd->CommonCfg.TriggerEventTab, Bssid, &HtCapability, HtCapabilityLen, RegClass, Channel);
+ }
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+ if (Idx != BSS_NOT_FOUND)
+ {
+ NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
+ NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
+ NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
+ }
+ }
+ }
+ // sanity check fail, ignored
+}
+
+/*
+ ==========================================================================
+ Description:
+ When waiting joining the (I)BSS, beacon received from external
+ ==========================================================================
+ */
+VOID PeerBeaconAtJoinAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
+ UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
+ DtimCount, DtimPeriod, BcastFlag, NewChannel;
+ LARGE_INTEGER TimeStamp;
+ USHORT BeaconPeriod, AtimWin, CapabilityInfo;
+ CF_PARM Cf;
+ BOOLEAN TimerCancelled;
+ UCHAR Erp;
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen, ExtRateLen;
+ UCHAR CkipFlag;
+ USHORT LenVIE;
+ UCHAR AironetCellPowerLimit;
+ EDCA_PARM EdcaParm;
+ QBSS_LOAD_PARM QbssLoad;
+ QOS_CAPABILITY_PARM QosCapability;
+ USHORT Status;
+ UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
+ NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
+ ULONG RalinkIe;
+ ULONG Idx;
+ HT_CAPABILITY_IE HtCapability;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
+ UCHAR AddHtInfoLen;
+ UCHAR NewExtChannelOffset = 0xff;
+#ifdef DOT11_N_SUPPORT
+ UCHAR CentralChannel;
+#endif // DOT11_N_SUPPORT //
+
+ // Init Variable IE structure
+ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+ pVIE->Length = 0;
+ RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
+ RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
+
+
+ if (PeerBeaconAndProbeRspSanity(pAd,
+ Elem->Msg,
+ Elem->MsgLen,
+ Elem->Channel,
+ Addr2,
+ Bssid,
+ Ssid,
+ &SsidLen,
+ &BssType,
+ &BeaconPeriod,
+ &Channel,
+ &NewChannel,
+ &TimeStamp,
+ &Cf,
+ &AtimWin,
+ &CapabilityInfo,
+ &Erp,
+ &DtimCount,
+ &DtimPeriod,
+ &BcastFlag,
+ &MessageToMe,
+ SupRate,
+ &SupRateLen,
+ ExtRate,
+ &ExtRateLen,
+ &CkipFlag,
+ &AironetCellPowerLimit,
+ &EdcaParm,
+ &QbssLoad,
+ &QosCapability,
+ &RalinkIe,
+ &HtCapabilityLen,
+ &PreNHtCapabilityLen,
+ &HtCapability,
+ &AddHtInfoLen,
+ &AddHtInfo,
+ &NewExtChannelOffset,
+ &LenVIE,
+ pVIE))
+ {
+ // Disqualify 11b only adhoc when we are in 11g only adhoc mode
+ if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12))
+ return;
+
+ // BEACON from desired BSS/IBSS found. We should be able to decide most
+ // BSS parameters here.
+ // Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
+ // Do we need to receover back all parameters belonging to previous BSS?
+ // A. Should be not. There's no back-door recover to previous AP. It still need
+ // a new JOIN-AUTH-ASSOC sequence.
+ if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel));
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
+
+ // Update RSSI to prevent No signal display when cards first initialized
+ pAd->StaCfg.RssiSample.LastRssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
+ pAd->StaCfg.RssiSample.LastRssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
+ pAd->StaCfg.RssiSample.LastRssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
+ pAd->StaCfg.RssiSample.AvgRssi0 = pAd->StaCfg.RssiSample.LastRssi0;
+ pAd->StaCfg.RssiSample.AvgRssi0X8 = pAd->StaCfg.RssiSample.AvgRssi0 << 3;
+ pAd->StaCfg.RssiSample.AvgRssi1 = pAd->StaCfg.RssiSample.LastRssi1;
+ pAd->StaCfg.RssiSample.AvgRssi1X8 = pAd->StaCfg.RssiSample.AvgRssi1 << 3;
+ pAd->StaCfg.RssiSample.AvgRssi2 = pAd->StaCfg.RssiSample.LastRssi2;
+ pAd->StaCfg.RssiSample.AvgRssi2X8 = pAd->StaCfg.RssiSample.AvgRssi2 << 3;
+
+ //
+ // We need to check if SSID only set to any, then we can record the current SSID.
+ // Otherwise will cause hidden SSID association failed.
+ //
+ if (pAd->MlmeAux.SsidLen == 0)
+ {
+ NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
+ pAd->MlmeAux.SsidLen = SsidLen;
+ }
+ else
+ {
+ Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel);
+
+ if (Idx != BSS_NOT_FOUND)
+ {
+ //
+ // Multiple SSID case, used correct CapabilityInfo
+ //
+ CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
+ }
+ }
+ NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
+ pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
+ pAd->MlmeAux.BssType = BssType;
+ pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
+ pAd->MlmeAux.Channel = Channel;
+ pAd->MlmeAux.AtimWin = AtimWin;
+ pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod;
+ pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
+ pAd->MlmeAux.APRalinkIe = RalinkIe;
+
+ // Copy AP's supported rate to MlmeAux for creating assoication request
+ // Also filter out not supported rate
+ pAd->MlmeAux.SupRateLen = SupRateLen;
+ NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
+ RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
+ pAd->MlmeAux.ExtRateLen = ExtRateLen;
+ NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
+ RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
+
+ NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16);
+#ifdef DOT11_N_SUPPORT
+ pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
+ pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
+
+ // filter out un-supported ht rates
+ if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
+ RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE);
+
+ // StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
+ NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
+ pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
+ pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
+ pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
+ if (PreNHtCapabilityLen > 0)
+ pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE;
+ RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, &AddHtInfo);
+ // Copy AP Parameter to StaActive. This is also in LinkUp.
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
+ pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, HtCapability.HtCapInfo.ChannelWidth));
+
+ if (AddHtInfoLen > 0)
+ {
+ CentralChannel = AddHtInfo.ControlChan;
+ // Check again the Bandwidth capability of this AP.
+ if ((AddHtInfo.ControlChan > 2)&& (AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ CentralChannel = AddHtInfo.ControlChan - 2;
+ }
+ else if ((AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ CentralChannel = AddHtInfo.ControlChan + 2;
+ }
+
+ // Check Error .
+ if (pAd->MlmeAux.CentralChannel != CentralChannel)
+ DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, AddHtInfo.ControlChan, pAd->MlmeAux.CentralChannel));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, AddHtInfo.ControlChan));
+
+ }
+
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ // To prevent error, let legacy AP must have same CentralChannel and Channel.
+ if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0))
+ pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel;
+
+ pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+ RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
+ RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
+ }
+
+ RTMPUpdateMlmeRate(pAd);
+
+ // copy QOS related information
+ if ((pAd->CommonCfg.bWmmCapable)
+#ifdef DOT11_N_SUPPORT
+ || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM));
+ NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
+ NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
+ }
+ else
+ {
+ NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
+ NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
+ NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
+ pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
+
+#ifdef LEAP_SUPPORT
+ // Update CkipFlag
+ pAd->StaCfg.CkipFlag = CkipFlag;
+
+ // Keep TimeStamp for Re-Association used.
+ if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
+ pAd->StaCfg.CCKMBeaconAtJoinTimeStamp = TimeStamp;
+#endif // LEAP_SUPPORT //
+
+ if (AironetCellPowerLimit != 0xFF)
+ {
+ //We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
+ ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
+ }
+ else //Used the default TX Power Percentage.
+ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
+ }
+ // not to me BEACON, ignored
+ }
+ // sanity check fail, ignore this frame
+}
+
+/*
+ ==========================================================================
+ Description:
+ receive BEACON from peer
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerBeacon(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
+ CHAR Ssid[MAX_LEN_OF_SSID];
+ CF_PARM CfParm;
+ UCHAR SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0;
+ UCHAR DtimCount=0, DtimPeriod=0, BcastFlag=0;
+ USHORT CapabilityInfo, AtimWin, BeaconPeriod;
+ LARGE_INTEGER TimeStamp;
+ USHORT TbttNumToNextWakeUp;
+ UCHAR Erp;
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen, ExtRateLen;
+ UCHAR CkipFlag;
+ USHORT LenVIE;
+ UCHAR AironetCellPowerLimit;
+ EDCA_PARM EdcaParm;
+ QBSS_LOAD_PARM QbssLoad;
+ QOS_CAPABILITY_PARM QosCapability;
+ ULONG RalinkIe;
+ // New for WPA security suites
+ UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
+ NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
+ HT_CAPABILITY_IE HtCapability;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR HtCapabilityLen, PreNHtCapabilityLen;
+ UCHAR AddHtInfoLen;
+ UCHAR NewExtChannelOffset = 0xff;
+
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ return;
+ }
+#endif // RALINK_ATE //
+
+ if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
+ ))
+ return;
+
+ // Init Variable IE structure
+ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+ pVIE->Length = 0;
+ RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
+ RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
+
+ if (PeerBeaconAndProbeRspSanity(pAd,
+ Elem->Msg,
+ Elem->MsgLen,
+ Elem->Channel,
+ Addr2,
+ Bssid,
+ Ssid,
+ &SsidLen,
+ &BssType,
+ &BeaconPeriod,
+ &Channel,
+ &NewChannel,
+ &TimeStamp,
+ &CfParm,
+ &AtimWin,
+ &CapabilityInfo,
+ &Erp,
+ &DtimCount,
+ &DtimPeriod,
+ &BcastFlag,
+ &MessageToMe,
+ SupRate,
+ &SupRateLen,
+ ExtRate,
+ &ExtRateLen,
+ &CkipFlag,
+ &AironetCellPowerLimit,
+ &EdcaParm,
+ &QbssLoad,
+ &QosCapability,
+ &RalinkIe,
+ &HtCapabilityLen,
+ &PreNHtCapabilityLen,
+ &HtCapability,
+ &AddHtInfoLen,
+ &AddHtInfo,
+ &NewExtChannelOffset,
+ &LenVIE,
+ pVIE))
+ {
+ BOOLEAN is_my_bssid, is_my_ssid;
+ ULONG Bssidx, Now;
+ BSS_ENTRY *pBss;
+ CHAR RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+
+ is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE;
+ is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE;
+
+
+ // ignore BEACON not for my SSID
+ if ((! is_my_ssid) && (! is_my_bssid))
+ return;
+
+ // It means STA waits disassoc completely from this AP, ignores this beacon.
+ if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
+ return;
+
+#ifdef DOT11_N_SUPPORT
+ // Copy Control channel for this BSSID.
+ if (AddHtInfoLen != 0)
+ Channel = AddHtInfo.ControlChan;
+
+ if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
+ HtCapabilityLen = SIZE_HT_CAP_IE;
+#endif // DOT11_N_SUPPORT //
+
+ //
+ // Housekeeping "SsidBssTab" table for later-on ROAMing usage.
+ //
+ Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
+ if (Bssidx == BSS_NOT_FOUND)
+ {
+ // discover new AP of this network, create BSS entry
+ Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
+ &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,
+ &HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel,
+ RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability,
+ &QbssLoad, LenVIE, pVIE);
+ if (Bssidx == BSS_NOT_FOUND) // return if BSS table full
+ return;
+
+ NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4);
+ NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
+ NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
+
+
+
+ }
+
+ if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
+ {
+ // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
+ // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
+ AsicSwitchChannel(pAd, 1, FALSE);
+ AsicLockChannel(pAd, 1);
+ LinkDown(pAd, FALSE);
+ MlmeQueueInit(&pAd->Mlme.Queue);
+ BssTableInit(&pAd->ScanTab);
+ RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
+
+ // channel sanity check
+ for (index = 0 ; index < pAd->ChannelListNum; index++)
+ {
+ if (pAd->ChannelList[index].Channel == NewChannel)
+ {
+ pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
+ pAd->CommonCfg.Channel = NewChannel;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
+ break;
+ }
+ }
+
+ if (index >= pAd->ChannelListNum)
+ {
+ DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
+ }
+ }
+
+ // if the ssid matched & bssid unmatched, we should select the bssid with large value.
+ // This might happened when two STA start at the same time
+ if ((! is_my_bssid) && ADHOC_ON(pAd))
+ {
+ INT i;
+
+ // Add the safeguard against the mismatch of adhoc wep status
+ if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Not matched wep status %d %d\n", pAd->StaCfg.WepStatus, pAd->ScanTab.BssEntry[Bssidx].WepStatus));
+ DBGPRINT(RT_DEBUG_TRACE, ("bssid=%s\n", pAd->ScanTab.BssEntry[Bssidx].Bssid));
+ return;
+ }
+
+ // collapse into the ADHOC network which has bigger BSSID value.
+ for (i = 0; i < 6; i++)
+ {
+ if (Bssid[i] > pAd->CommonCfg.Bssid[i])
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
+ AsicDisableSync(pAd);
+ COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid);
+ AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
+ MakeIbssBeacon(pAd); // re-build BEACON frame
+ AsicEnableIbssSync(pAd); // copy BEACON frame to on-chip memory
+ is_my_bssid = TRUE;
+ break;
+ }
+ else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
+ break;
+ }
+ }
+
+
+ NdisGetSystemUpTime(&Now);
+ pBss = &pAd->ScanTab.BssEntry[Bssidx];
+ pBss->Rssi = RealRssi; // lastest RSSI
+ pBss->LastBeaconRxTime = Now; // last RX timestamp
+
+ //
+ // BEACON from my BSSID - either IBSS or INFRA network
+ //
+ if (is_my_bssid)
+ {
+ RXWI_STRUC RxWI;
+
+ pAd->StaCfg.DtimCount = DtimCount;
+ pAd->StaCfg.DtimPeriod = DtimPeriod;
+ pAd->StaCfg.LastBeaconRxTime = Now;
+
+
+ RxWI.RSSI0 = Elem->Rssi0;
+ RxWI.RSSI1 = Elem->Rssi1;
+ RxWI.RSSI2 = Elem->Rssi2;
+
+ Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
+ if (AironetCellPowerLimit != 0xFF)
+ {
+ //
+ // We get the Cisco (ccx) "TxPower Limit" required
+ // Changed to appropriate TxPower Limit for Ciso Compatible Extensions
+ //
+ ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
+ }
+ else
+ {
+ //
+ // AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
+ // Used the default TX Power Percentage, that set from UI.
+ //
+ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+ }
+
+ if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo)))
+ {
+ UCHAR MaxSupportedRateIn500Kbps = 0;
+ UCHAR idx;
+ MAC_TABLE_ENTRY *pEntry;
+
+ // supported rates array may not be sorted. sort it and find the maximum rate
+ for (idx=0; idx<SupRateLen; idx++)
+ {
+ if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
+ MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
+ }
+
+ for (idx=0; idx<ExtRateLen; idx++)
+ {
+ if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
+ MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
+ }
+
+ // look up the existing table
+ pEntry = MacTableLookup(pAd, Addr2);
+
+ // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
+ // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
+ if ((ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) ||
+ (pEntry && ((pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME) < Now)))
+ {
+ if (pEntry == NULL)
+ // Another adhoc joining, add to our MAC table.
+ pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
+
+ if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo) == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n"));
+ return;
+ }
+
+ if (pEntry &&
+ (Elem->Wcid == RESERVED_WCID))
+ {
+ idx = pAd->StaCfg.DefaultKeyId;
+ RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
+ }
+ }
+
+ if (pEntry && pEntry->ValidAsCLI)
+ pEntry->LastBeaconRxTime = Now;
+
+ // At least another peer in this IBSS, declare MediaState as CONNECTED
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_UP;
+ AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
+
+ // 2003/03/12 - john
+ // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
+ // "site survey" result should always include the current connected network.
+ //
+ Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
+ if (Bssidx == BSS_NOT_FOUND)
+ {
+ Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
+ &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
+ &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
+ &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
+ }
+ }
+
+ if (INFRA_ON(pAd))
+ {
+ BOOLEAN bUseShortSlot, bUseBGProtection;
+
+ // decide to use/change to -
+ // 1. long slot (20 us) or short slot (9 us) time
+ // 2. turn on/off RTS/CTS and/or CTS-to-self protection
+ // 3. short preamble
+
+ //bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
+ bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo);
+ if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
+ AsicSetSlotTime(pAd, bUseShortSlot);
+
+ bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || // always use
+ ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp));
+
+ if (pAd->CommonCfg.Channel > 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
+ bUseBGProtection = FALSE;
+
+ if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+ {
+ if (bUseBGProtection)
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
+ }
+ else
+ {
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
+ }
+
+ DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection));
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // check Ht protection mode. and adhere to the Non-GF device indication by AP.
+ if ((AddHtInfoLen != 0) &&
+ ((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) ||
+ (AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent)))
+ {
+ pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent;
+ pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode;
+ if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
+ {
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
+ }
+ else
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode));
+ }
+#endif // DOT11_N_SUPPORT //
+
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) &&
+ ERP_IS_USE_BARKER_PREAMBLE(Erp))
+ {
+ MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n"));
+ }
+
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
+ (EdcaParm.bValid == TRUE) &&
+ (EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
+ pAd->CommonCfg.APEdcaParm.EdcaUpdateCount,
+ EdcaParm.EdcaUpdateCount));
+ AsicSetEdcaParm(pAd, &EdcaParm);
+ }
+
+ // copy QOS related information
+ NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
+ NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
+ }
+
+ // only INFRASTRUCTURE mode support power-saving feature
+ if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave))
+ {
+ UCHAR FreeNumber;
+ // 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
+ // 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
+ // 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
+ // 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
+ // 5. otherwise, put PHY back to sleep to save battery.
+ if (MessageToMe)
+ {
+ if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
+ pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
+ {
+ pAd->CommonCfg.bNeedSendTriggerFrame = TRUE;
+ }
+ else
+ RT28XX_PS_POLL_ENQUEUE(pAd);
+ }
+ else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
+ {
+ }
+ else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) ||
+ (pAd->TxSwQueue[QID_AC_BE].Number != 0) ||
+ (pAd->TxSwQueue[QID_AC_VI].Number != 0) ||
+ (pAd->TxSwQueue[QID_AC_VO].Number != 0) ||
+ (RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
+ (RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
+ (RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
+ (RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
+ (RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS))
+ {
+ // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
+ // can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
+ }
+ else
+ {
+ USHORT NextDtim = DtimCount;
+
+ if (NextDtim == 0)
+ NextDtim = DtimPeriod;
+
+ TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
+ TbttNumToNextWakeUp = NextDtim;
+
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ {
+ AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+ }
+ }
+ }
+ }
+ // not my BSSID, ignore it
+ }
+ // sanity check fail, ignore this frame
+}
+
+/*
+ ==========================================================================
+ Description:
+ Receive PROBE REQ from remote peer when operating in IBSS mode
+ ==========================================================================
+ */
+VOID PeerProbeReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ CHAR Ssid[MAX_LEN_OF_SSID];
+ UCHAR SsidLen;
+#ifdef DOT11_N_SUPPORT
+ UCHAR HtLen, AddHtLen, NewExtLen;
+#endif // DOT11_N_SUPPORT //
+ HEADER_802_11 ProbeRspHdr;
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ LARGE_INTEGER FakeTimestamp;
+ UCHAR DsLen = 1, IbssLen = 2;
+ UCHAR LocalErpIe[3] = {IE_ERP, 1, 0};
+ BOOLEAN Privacy;
+ USHORT CapabilityInfo;
+ UCHAR RSNIe = IE_WPA;
+
+ if (! ADHOC_ON(pAd))
+ return;
+
+ if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
+ {
+ if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
+ {
+ // allocate and send out ProbeRsp frame
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ //pAd->StaCfg.AtimWin = 0; // ??????
+
+ Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
+ CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &ProbeRspHdr,
+ TIMESTAMP_LEN, &FakeTimestamp,
+ 2, &pAd->CommonCfg.BeaconPeriod,
+ 2, &CapabilityInfo,
+ 1, &SsidIe,
+ 1, &pAd->CommonCfg.SsidLen,
+ pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
+ 1, &SupRateIe,
+ 1, &pAd->StaActive.SupRateLen,
+ pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
+ 1, &DsIe,
+ 1, &DsLen,
+ 1, &pAd->CommonCfg.Channel,
+ 1, &IbssIe,
+ 1, &IbssLen,
+ 2, &pAd->StaActive.AtimWin,
+ END_OF_ARGS);
+
+ if (pAd->StaActive.ExtRateLen)
+ {
+ ULONG tmp;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 3, LocalErpIe,
+ 1, &ExtRateIe,
+ 1, &pAd->StaActive.ExtRateLen,
+ pAd->StaActive.ExtRateLen, &pAd->StaActive.ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ // If adhoc secruity is set for WPA-None, append the cipher suite IE
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ ULONG tmp;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &RSNIe,
+ 1, &pAd->StaCfg.RSNIE_Len,
+ pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ {
+ ULONG TmpLen;
+ UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+ HtLen = sizeof(pAd->CommonCfg.HtCapability);
+ AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
+ NewExtLen = 1;
+ //New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
+ if (pAd->bBroadComHT == TRUE)
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 4, &BROADCOM[0],
+ pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
+ END_OF_ARGS);
+ }
+ else
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability,
+ 1, &AddHtInfoIe,
+ 1, &AddHtLen,
+ sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo,
+ 1, &NewExtChanIe,
+ 1, &NewExtLen,
+ sizeof(NEW_EXT_CHAN_IE), &pAd->CommonCfg.NewExtChanOffset,
+ END_OF_ARGS);
+ }
+ FrameLen += TmpLen;
+ }
+#endif // DOT11_N_SUPPORT //
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+ }
+}
+
+VOID BeaconTimeoutAtJoinAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_REJ_TIMEOUT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Scan timeout procedure. basically add channel index by 1 and rescan
+ ==========================================================================
+ */
+VOID ScanTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
+
+ // Only one channel scanned for CISCO beacon request
+ if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
+ (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
+ (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
+ (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
+ pAd->MlmeAux.Channel = 0;
+
+ // this routine will stop if pAd->MlmeAux.Channel == 0
+ ScanNextChannel(pAd);
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+VOID InvalidStateWhenScan(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+VOID InvalidStateWhenJoin(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+VOID InvalidStateWhenStart(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID EnqueuePsPoll(
+ IN PRTMP_ADAPTER pAd)
+{
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ return;
+ }
+#endif // RALINK_ATE //
+
+
+ if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
+ pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
+ MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+VOID EnqueueProbeRequest(
+ IN PRTMP_ADAPTER pAd)
+{
+ NDIS_STATUS NState;
+ PUCHAR pOutBuffer;
+ ULONG FrameLen = 0;
+ HEADER_802_11 Hdr80211;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
+
+ NState = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NState == NDIS_STATUS_SUCCESS)
+ {
+ MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
+
+ // this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &Hdr80211,
+ 1, &SsidIe,
+ 1, &pAd->CommonCfg.SsidLen,
+ pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
+ 1, &SupRateIe,
+ 1, &pAd->StaActive.SupRateLen,
+ pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+
+}
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+VOID BuildEffectedChannelList(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR EChannel[11];
+ UCHAR i, j, k;
+ UCHAR UpperChannel = 0, LowerChannel = 0;
+
+ RTMPZeroMemory(EChannel, 11);
+ i = 0;
+ // Find upper channel and lower channel.
+ if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
+ {
+ UpperChannel = pAd->CommonCfg.Channel;
+ LowerChannel = pAd->CommonCfg.CentralChannel;
+ }
+ else if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
+ {
+ UpperChannel = pAd->CommonCfg.CentralChannel;
+ LowerChannel = pAd->CommonCfg.Channel;
+ }
+ else
+ {
+ return;
+ }
+
+ // Record channels that is below lower channel..
+ if (LowerChannel > 1)
+ {
+ EChannel[0] = LowerChannel - 1;
+ i = 1;
+ if (LowerChannel > 2)
+ {
+ EChannel[1] = LowerChannel - 2;
+ i = 2;
+ if (LowerChannel > 3)
+ {
+ EChannel[2] = LowerChannel - 3;
+ i = 3;
+ }
+ }
+ }
+ // Record channels that is between lower channel and upper channel.
+ for (k = LowerChannel;k < UpperChannel;k++)
+ {
+ EChannel[i] = k;
+ i++;
+ }
+ // Record channels that is above upper channel..
+ if (LowerChannel < 11)
+ {
+ EChannel[i] = UpperChannel + 1;
+ i++;
+ if (LowerChannel < 10)
+ {
+ EChannel[i] = LowerChannel + 2;
+ i++;
+ if (LowerChannel < 9)
+ {
+ EChannel[i] = LowerChannel + 3;
+ i++;
+ }
+ }
+ }
+ //
+ for (j = 0;j < i;j++)
+ {
+ for (k = 0;k < pAd->ChannelListNum;k++)
+ {
+ if (pAd->ChannelList[k].Channel == EChannel[j])
+ {
+ pAd->ChannelList[k].bEffectedChannel = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE,(" EffectedChannel( =%d)\n", EChannel[j]));
+ break;
+ }
+ }
+ }
+}
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+BOOLEAN ScanRunning(
+ IN PRTMP_ADAPTER pAd)
+{
+ return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;
+}
+
diff --git a/drivers/staging/rt3070/sta/wpa.c b/drivers/staging/rt3070/sta/wpa.c
new file mode 100644
index 00000000000..63d08306bf6
--- /dev/null
+++ b/drivers/staging/rt3070/sta/wpa.c
@@ -0,0 +1,2099 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ wpa.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan Lee 03-07-22 Initial
+ Paul Lin 03-11-28 Modify for supplicant
+*/
+#include "../rt_config.h"
+
+#define WPARSNIE 0xdd
+#define WPA2RSNIE 0x30
+
+//extern UCHAR BIT8[];
+UCHAR CipherWpaPskTkip[] = {
+ 0xDD, 0x16, // RSN IE
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x50, 0xf2, 0x02, // Multicast
+ 0x01, 0x00, // Number of unicast
+ 0x00, 0x50, 0xf2, 0x02, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x50, 0xf2, 0x02 // authentication
+ };
+UCHAR CipherWpaPskTkipLen = (sizeof(CipherWpaPskTkip) / sizeof(UCHAR));
+
+UCHAR CipherWpaPskAes[] = {
+ 0xDD, 0x16, // RSN IE
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x50, 0xf2, 0x04, // Multicast
+ 0x01, 0x00, // Number of unicast
+ 0x00, 0x50, 0xf2, 0x04, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x50, 0xf2, 0x02 // authentication
+ };
+UCHAR CipherWpaPskAesLen = (sizeof(CipherWpaPskAes) / sizeof(UCHAR));
+
+UCHAR CipherSuiteCiscoCCKM[] = {
+ 0xDD, 0x16, // RSN IE
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x40, 0x96, 0x01, // Multicast
+ 0x01, 0x00, // Number of uicast
+ 0x00, 0x40, 0x96, 0x01, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x40, 0x96, 0x00 // Authentication
+ };
+UCHAR CipherSuiteCiscoCCKMLen = (sizeof(CipherSuiteCiscoCCKM) / sizeof(UCHAR));
+
+UCHAR CipherSuiteCiscoCCKM24[] = {
+ 0xDD, 0x18, // RSN IE
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x40, 0x96, 0x01, // Multicast
+ 0x01, 0x00, // Number of uicast
+ 0x00, 0x40, 0x96, 0x01, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x40, 0x96, 0x00,
+ 0x28, 0x00// Authentication
+ };
+
+UCHAR CipherSuiteCiscoCCKM24Len = (sizeof(CipherSuiteCiscoCCKM24) / sizeof(UCHAR));
+
+UCHAR CipherSuiteCCXTkip[] = {
+ 0xDD, 0x16, // RSN IE
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x50, 0xf2, 0x02, // Multicast
+ 0x01, 0x00, // Number of unicast
+ 0x00, 0x50, 0xf2, 0x02, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x50, 0xf2, 0x01 // authentication
+ };
+UCHAR CipherSuiteCCXTkipLen = (sizeof(CipherSuiteCCXTkip) / sizeof(UCHAR));
+
+UCHAR CCX_LLC_HDR[] = {0xAA, 0xAA, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
+UCHAR LLC_NORMAL[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
+
+UCHAR EAPOL_FRAME[] = {0x88, 0x8E};
+
+BOOLEAN CheckRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN UCHAR DataLen,
+ OUT UCHAR *Offset);
+
+void inc_byte_array(UCHAR *counter, int len);
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Classify WPA EAP message type
+
+ Arguments:
+ EAPType Value of EAP message type
+ MsgType Internal Message definition for MLME state machine
+
+ Return Value:
+ TRUE Found appropriate message type
+ FALSE No appropriate message type
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ All these constants are defined in wpa.h
+ For supplicant, there is only EAPOL Key message avaliable
+
+ ========================================================================
+*/
+BOOLEAN WpaMsgTypeSubst(
+ IN UCHAR EAPType,
+ OUT INT *MsgType)
+{
+ switch (EAPType)
+ {
+ case EAPPacket:
+ *MsgType = MT2_EAPPacket;
+ break;
+ case EAPOLStart:
+ *MsgType = MT2_EAPOLStart;
+ break;
+ case EAPOLLogoff:
+ *MsgType = MT2_EAPOLLogoff;
+ break;
+ case EAPOLKey:
+ *MsgType = MT2_EAPOLKey;
+ break;
+ case EAPOLASFAlert:
+ *MsgType = MT2_EAPOLASFAlert;
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ association state machine init, including state transition and timer init
+ Parameters:
+ S - pointer to the association state machine
+ ==========================================================================
+ */
+VOID WpaPskStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(S, Trans, MAX_WPA_PSK_STATE, MAX_WPA_PSK_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PSK_IDLE, WPA_MACHINE_BASE);
+ StateMachineSetAction(S, WPA_PSK_IDLE, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction);
+}
+
+/*
+ ==========================================================================
+ Description:
+ This is state machine function.
+ When receiving EAPOL packets which is for 802.1x key management.
+ Use both in WPA, and WPAPSK case.
+ In this function, further dispatch to different functions according to the received packet. 3 categories are :
+ 1. normal 4-way pairwisekey and 2-way groupkey handshake
+ 2. MIC error (Countermeasures attack) report packet from STA.
+ 3. Request for pairwise/group key update from STA
+ Return:
+ ==========================================================================
+*/
+VOID WpaEAPOLKeyAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ INT MsgType = EAPOL_MSG_INVALID;
+ PKEY_DESCRIPTER pKeyDesc;
+ PHEADER_802_11 pHeader; //red
+ UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
+ UCHAR EapolVr;
+ KEY_INFO peerKeyInfo;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaEAPOLKeyAction\n"));
+
+ // Get 802.11 header first
+ pHeader = (PHEADER_802_11) Elem->Msg;
+
+ // Get EAPoL-Key Descriptor
+ pKeyDesc = (PKEY_DESCRIPTER) &Elem->Msg[(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H)];
+
+ NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+ NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pKeyDesc->KeyInfo, sizeof(KEY_INFO));
+
+ *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo));
+
+
+ // 1. Check EAPOL frame version and type
+ EapolVr = (UCHAR) Elem->Msg[LENGTH_802_11+LENGTH_802_1_H];
+
+ if (((EapolVr != EAPOL_VER) && (EapolVr != EAPOL_VER2)) || ((pKeyDesc->Type != WPA1_KEY_DESC) && (pKeyDesc->Type != WPA2_KEY_DESC)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n"));
+ return;
+ }
+
+ // First validate replay counter, only accept message with larger replay counter
+ // Let equal pass, some AP start with all zero replay counter
+ NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
+
+ if((RTMPCompareMemory(pKeyDesc->ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
+ (RTMPCompareMemory(pKeyDesc->ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, (" ReplayCounter not match \n"));
+ return;
+ }
+
+ // Process WPA2PSK frame
+ if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+ {
+ if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
+ (peerKeyInfo.EKD_DL == 0) &&
+ (peerKeyInfo.KeyAck == 1) &&
+ (peerKeyInfo.KeyMic == 0) &&
+ (peerKeyInfo.Secure == 0) &&
+ (peerKeyInfo.Error == 0) &&
+ (peerKeyInfo.Request == 0))
+ {
+ MsgType = EAPOL_PAIR_MSG_1;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
+ } else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
+ (peerKeyInfo.EKD_DL == 1) &&
+ (peerKeyInfo.KeyAck == 1) &&
+ (peerKeyInfo.KeyMic == 1) &&
+ (peerKeyInfo.Secure == 1) &&
+ (peerKeyInfo.Error == 0) &&
+ (peerKeyInfo.Request == 0))
+ {
+ MsgType = EAPOL_PAIR_MSG_3;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
+ } else if((peerKeyInfo.KeyType == GROUPKEY) &&
+ (peerKeyInfo.EKD_DL == 1) &&
+ (peerKeyInfo.KeyAck == 1) &&
+ (peerKeyInfo.KeyMic == 1) &&
+ (peerKeyInfo.Secure == 1) &&
+ (peerKeyInfo.Error == 0) &&
+ (peerKeyInfo.Request == 0))
+ {
+ MsgType = EAPOL_GROUP_MSG_1;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
+ }
+
+ // We will assume link is up (assoc suceess and port not secured).
+ // All state has to be able to process message from previous state
+ switch(pAd->StaCfg.WpaState)
+ {
+ case SS_START:
+ if(MsgType == EAPOL_PAIR_MSG_1)
+ {
+ Wpa2PairMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+ }
+ break;
+
+ case SS_WAIT_MSG_3:
+ if(MsgType == EAPOL_PAIR_MSG_1)
+ {
+ Wpa2PairMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+ }
+ else if(MsgType == EAPOL_PAIR_MSG_3)
+ {
+ Wpa2PairMsg3Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_GROUP;
+ }
+ break;
+
+ case SS_WAIT_GROUP: // When doing group key exchange
+ case SS_FINISH: // This happened when update group key
+ if(MsgType == EAPOL_PAIR_MSG_1)
+ {
+ // Reset port secured variable
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ Wpa2PairMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+ }
+ else if(MsgType == EAPOL_PAIR_MSG_3)
+ {
+ // Reset port secured variable
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ Wpa2PairMsg3Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_GROUP;
+ }
+ else if(MsgType == EAPOL_GROUP_MSG_1)
+ {
+ WpaGroupMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_FINISH;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ // Process WPAPSK Frame
+ // Classify message Type, either pairwise message 1, 3, or group message 1 for supplicant
+ else if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
+ {
+ if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
+ (peerKeyInfo.KeyIndex == 0) &&
+ (peerKeyInfo.KeyAck == 1) &&
+ (peerKeyInfo.KeyMic == 0) &&
+ (peerKeyInfo.Secure == 0) &&
+ (peerKeyInfo.Error == 0) &&
+ (peerKeyInfo.Request == 0))
+ {
+ MsgType = EAPOL_PAIR_MSG_1;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
+ }
+ else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
+ (peerKeyInfo.KeyIndex == 0) &&
+ (peerKeyInfo.KeyAck == 1) &&
+ (peerKeyInfo.KeyMic == 1) &&
+ (peerKeyInfo.Secure == 0) &&
+ (peerKeyInfo.Error == 0) &&
+ (peerKeyInfo.Request == 0))
+ {
+ MsgType = EAPOL_PAIR_MSG_3;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
+ }
+ else if((peerKeyInfo.KeyType == GROUPKEY) &&
+ (peerKeyInfo.KeyIndex != 0) &&
+ (peerKeyInfo.KeyAck == 1) &&
+ (peerKeyInfo.KeyMic == 1) &&
+ (peerKeyInfo.Secure == 1) &&
+ (peerKeyInfo.Error == 0) &&
+ (peerKeyInfo.Request == 0))
+ {
+ MsgType = EAPOL_GROUP_MSG_1;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
+ }
+
+ // We will assume link is up (assoc suceess and port not secured).
+ // All state has to be able to process message from previous state
+ switch(pAd->StaCfg.WpaState)
+ {
+ case SS_START:
+ if(MsgType == EAPOL_PAIR_MSG_1)
+ {
+ WpaPairMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+ }
+ break;
+
+ case SS_WAIT_MSG_3:
+ if(MsgType == EAPOL_PAIR_MSG_1)
+ {
+ WpaPairMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+ }
+ else if(MsgType == EAPOL_PAIR_MSG_3)
+ {
+ WpaPairMsg3Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_GROUP;
+ }
+ break;
+
+ case SS_WAIT_GROUP: // When doing group key exchange
+ case SS_FINISH: // This happened when update group key
+ if(MsgType == EAPOL_PAIR_MSG_1)
+ {
+ WpaPairMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+ // Reset port secured variable
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ }
+ else if(MsgType == EAPOL_PAIR_MSG_3)
+ {
+ WpaPairMsg3Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_GROUP;
+ // Reset port secured variable
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ }
+ else if(MsgType == EAPOL_GROUP_MSG_1)
+ {
+ WpaGroupMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_FINISH;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaEAPOLKeyAction\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process Pairwise key 4-way handshaking
+
+ Arguments:
+ pAd Pointer to our adapter
+ Elem Message body
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID WpaPairMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PHEADER_802_11 pHeader;
+ UCHAR *mpool, *PTK, *digest;
+ PUCHAR pOutBuffer = NULL;
+ UCHAR Header802_3[14];
+ ULONG FrameLen = 0;
+ PEAPOL_PACKET pMsg1;
+ EAPOL_PACKET Packet;
+ UCHAR Mic[16];
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action ----->\n"));
+
+ // allocate memory pool
+ os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
+
+ if (mpool == NULL)
+ return;
+
+ // PTK Len = 80.
+ PTK = (UCHAR *) ROUND_UP(mpool, 4);
+ // digest Len = 80.
+ digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
+
+ pHeader = (PHEADER_802_11) Elem->Msg;
+
+ // Process message 1 from authenticator
+ pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+ // 1. Save Replay counter, it will use to verify message 3 and construct message 2
+ NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // 2. Save ANonce
+ NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
+
+ // Generate random SNonce
+ GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
+
+ // Calc PTK(ANonce, SNonce)
+ WpaCountPTK(pAd,
+ pAd->StaCfg.PMK,
+ pAd->StaCfg.ANonce,
+ pAd->CommonCfg.Bssid,
+ pAd->StaCfg.SNonce,
+ pAd->CurrentAddress,
+ PTK,
+ LEN_PTK);
+
+ // Save key to PTK entry
+ NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
+
+ // init 802.3 header and Fill Packet
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero Message 2 body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ //
+ // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
+ //
+ Packet.KeyDesc.Type = WPA1_KEY_DESC;
+ // 1. Key descriptor version and appropriate RSN IE
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
+ }
+ else // TKIP
+ {
+ Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
+ }
+
+ // fill in Data Material and its length
+ Packet.KeyDesc.KeyData[0] = IE_WPA;
+ Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
+ Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
+ NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
+
+ // Update packet length after decide Key data payload
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
+
+ // Update Key length
+ Packet.KeyDesc.KeyLength[0] = pMsg1->KeyDesc.KeyLength[0];
+ Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
+ // 2. Key Type PeerKey
+ Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+ // 3. KeyMic field presented
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+
+ //Convert to little-endian format.
+ *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+
+ // 4. Fill SNonce
+ NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
+
+ // 5. Key Replay Count
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Send EAPOL(0, 1, 0, 0, 0, P, 0, SNonce, MIC, RSN_IE)
+ // Out buffer for transmitting message 2
+ MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
+ if(pOutBuffer == NULL)
+ {
+ os_free_mem(pAd, mpool);
+ return;
+ }
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // 6. Prepare and Fill MIC value
+ NdisZeroMemory(Mic, sizeof(Mic));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ { // AES
+
+ HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ { // TKIP
+ hmac_md5(PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ }
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+ //hex_dump("MIC", Mic, LEN_KEY_DESC_MIC);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ LENGTH_802_3, &Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+
+ // 5. Copy frame to Tx ring and send Msg 2 to authenticator
+ RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
+
+ MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+ os_free_mem(pAd, (PUCHAR)mpool);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action <-----\n"));
+}
+
+VOID Wpa2PairMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PHEADER_802_11 pHeader;
+ UCHAR *mpool, *PTK, *digest;
+ PUCHAR pOutBuffer = NULL;
+ UCHAR Header802_3[14];
+ ULONG FrameLen = 0;
+ PEAPOL_PACKET pMsg1;
+ EAPOL_PACKET Packet;
+ UCHAR Mic[16];
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action ----->\n"));
+
+ // allocate memory pool
+ os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
+
+ if (mpool == NULL)
+ return;
+
+ // PTK Len = 80.
+ PTK = (UCHAR *) ROUND_UP(mpool, 4);
+ // digest Len = 80.
+ digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
+
+ pHeader = (PHEADER_802_11) Elem->Msg;
+
+ // Process message 1 from authenticator
+ pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+ // 1. Save Replay counter, it will use to verify message 3 and construct message 2
+ NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // 2. Save ANonce
+ NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
+
+ // Generate random SNonce
+ GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
+
+ if(pMsg1->KeyDesc.KeyDataLen[1] > 0 )
+ {
+ // cached PMKID
+ }
+
+ // Calc PTK(ANonce, SNonce)
+ WpaCountPTK(pAd,
+ pAd->StaCfg.PMK,
+ pAd->StaCfg.ANonce,
+ pAd->CommonCfg.Bssid,
+ pAd->StaCfg.SNonce,
+ pAd->CurrentAddress,
+ PTK,
+ LEN_PTK);
+
+ // Save key to PTK entry
+ NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
+
+ // init 802.3 header and Fill Packet
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero message 2 body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ //
+ // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
+ //
+ Packet.KeyDesc.Type = WPA2_KEY_DESC;
+
+ // 1. Key descriptor version and appropriate RSN IE
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
+ }
+ else // TKIP
+ {
+ Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
+ }
+
+ // fill in Data Material and its length
+ Packet.KeyDesc.KeyData[0] = IE_WPA2;
+ Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
+ Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
+ NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
+
+ // Update packet length after decide Key data payload
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
+
+ // 2. Key Type PeerKey
+ Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+ // 3. KeyMic field presented
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+
+ // Update Key Length
+ Packet.KeyDesc.KeyLength[0] = 0;
+ Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
+
+ // 4. Fill SNonce
+ NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
+
+ // 5. Key Replay Count
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Convert to little-endian format.
+ *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+ // Send EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
+ // Out buffer for transmitting message 2
+ MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
+ if(pOutBuffer == NULL)
+ {
+ os_free_mem(pAd, mpool);
+ return;
+ }
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // 6. Prepare and Fill MIC value
+ NdisZeroMemory(Mic, sizeof(Mic));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ }
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+
+ // Make Transmitting frame
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ LENGTH_802_3, &Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+
+ // 5. Copy frame to Tx ring
+ RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+ os_free_mem(pAd, mpool);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action <-----\n"));
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process Pairwise key 4-way handshaking
+
+ Arguments:
+ pAd Pointer to our adapter
+ Elem Message body
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID WpaPairMsg3Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ PHEADER_802_11 pHeader;
+ PUCHAR pOutBuffer = NULL;
+ UCHAR Header802_3[14];
+ ULONG FrameLen = 0;
+ EAPOL_PACKET Packet;
+ PEAPOL_PACKET pMsg3;
+ UCHAR Mic[16], OldMic[16];
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ UCHAR skip_offset;
+ KEY_INFO peerKeyInfo;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action ----->\n"));
+
+ // Record 802.11 header & the received EAPOL packet Msg3
+ pHeader = (PHEADER_802_11) Elem->Msg;
+ pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+ NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+ NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+ *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
+
+
+ // 1. Verify cipher type match
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
+ {
+ return;
+ }
+ else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
+ {
+ return;
+ }
+
+ // Verify RSN IE
+ //if (!RTMPEqualMemory(pMsg3->KeyDesc.KeyData, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len))
+ if (!CheckRSNIE(pAd, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1], &skip_offset))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in Msg 3 of WPA1 4-way handshake!! \n"));
+ hex_dump("The original RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
+ hex_dump("The received RSN_IE", pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
+ return;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("RSN_IE VALID in Msg 3 of WPA1 4-way handshake!! \n"));
+
+
+ // 2. Check MIC value
+ // Save the MIC and replace with zero
+ NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ UCHAR digest[80];
+
+ HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else // TKIP
+ {
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
+ }
+
+ if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
+ return;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
+
+ // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
+ if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
+ return;
+
+ // Update new replay counter
+ NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // 4. Double check ANonce
+ if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
+ return;
+
+ // init 802.3 header and Fill Packet
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero Message 4 body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
+
+ //
+ // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
+ //
+ Packet.KeyDesc.Type = WPA1_KEY_DESC;
+
+ // Key descriptor version and appropriate RSN IE
+ Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
+
+ // Update Key Length
+ Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
+ Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
+
+ // Key Type PeerKey
+ Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+ // KeyMic field presented
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+
+ // In Msg3, KeyInfo.secure =0 if Group Key HS to come. 1 if no group key HS
+ // Station sends Msg4 KeyInfo.secure should be the same as that in Msg.3
+ Packet.KeyDesc.KeyInfo.Secure= peerKeyInfo.Secure;
+
+ // Convert to little-endian format.
+ *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+ // Key Replay count
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Out buffer for transmitting message 4
+ MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
+ if(pOutBuffer == NULL)
+ return;
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // Prepare and Fill MIC value
+ NdisZeroMemory(Mic, sizeof(Mic));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ UCHAR digest[80];
+
+ HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ }
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+ // Update PTK
+ // Prepare pair-wise key information into shared key table
+ NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+
+ // Decide its ChiperAlg
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+ else
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
+
+ // Update these related information to MAC_TABLE_ENTRY
+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
+ NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+ NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+ pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+
+ // Update pairwise key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pAd->SharedKey[BSS0][0].Key,
+ pAd->SharedKey[BSS0][0].TxMic,
+ pAd->SharedKey[BSS0][0].RxMic);
+
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pEntry);
+
+ // Make transmitting frame
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ LENGTH_802_3, &Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+
+ // Copy frame to Tx ring and Send Message 4 to authenticator
+ RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
+
+ MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action <-----\n"));
+}
+
+VOID Wpa2PairMsg3Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ PHEADER_802_11 pHeader;
+ PUCHAR pOutBuffer = NULL;
+ UCHAR Header802_3[14];
+ ULONG FrameLen = 0;
+ EAPOL_PACKET Packet;
+ PEAPOL_PACKET pMsg3;
+ UCHAR Mic[16], OldMic[16];
+ UCHAR *mpool, *KEYDATA, *digest;
+ UCHAR Key[32];
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ KEY_INFO peerKeyInfo;
+
+ // allocate memory
+ os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
+
+ if(mpool == NULL)
+ return;
+
+ // KEYDATA Len = 512.
+ KEYDATA = (UCHAR *) ROUND_UP(mpool, 4);
+ // digest Len = 80.
+ digest = (UCHAR *) ROUND_UP(KEYDATA + 512, 4);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg3Action ----->\n"));
+
+ pHeader = (PHEADER_802_11) Elem->Msg;
+
+ // Process message 3 frame.
+ pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+ NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+ NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+ *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
+
+ // 1. Verify cipher type match
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer!= 2))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+ else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // 2. Check MIC value
+ // Save the MIC and replace with zero
+ NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
+ }
+
+ if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
+
+ // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
+ if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // Update new replay counter
+ NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // 4. Double check ANonce
+ if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // Obtain GTK
+ // 5. Decrypt GTK from Key Data
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("EKD = %d\n", peerKeyInfo.EKD_DL));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // Decrypt AES GTK
+ AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pMsg3->KeyDesc.KeyDataLen[1],pMsg3->KeyDesc.KeyData);
+ }
+ else // TKIP
+ {
+ INT i;
+ // Decrypt TKIP GTK
+ // Construct 32 bytes RC4 Key
+ NdisMoveMemory(Key, pMsg3->KeyDesc.KeyIv, 16);
+ NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
+ //discard first 256 bytes
+ for(i = 0; i < 256; i++)
+ ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
+ // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
+ ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
+ }
+
+ if (!ParseKeyData(pAd, KEYDATA, pMsg3->KeyDesc.KeyDataLen[1], 1))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // Update GTK to ASIC
+ // Update group key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
+
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ NULL);
+
+ // init 802.3 header and Fill Packet
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero message 4 body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
+
+ //
+ // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
+ //
+ Packet.KeyDesc.Type = WPA2_KEY_DESC;
+
+ // Key descriptor version and appropriate RSN IE
+ Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
+
+ // Update Key Length
+ Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
+ Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
+
+ // Key Type PeerKey
+ Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+ // KeyMic field presented
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+ Packet.KeyDesc.KeyInfo.Secure = 1;
+
+ // Convert to little-endian format.
+ *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+ // Key Replay count
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Out buffer for transmitting message 4
+ MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
+ if(pOutBuffer == NULL)
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // Prepare and Fill MIC value
+ NdisZeroMemory(Mic, sizeof(Mic));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ }
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+ // Update PTK
+ // Prepare pair-wise key information into shared key table
+ NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+
+ // Decide its ChiperAlg
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+ else
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
+
+ // Update these related information to MAC_TABLE_ENTRY
+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
+ NdisMoveMemory(&pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+ NdisMoveMemory(&pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+ NdisMoveMemory(&pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+ pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+
+ // Update pairwise key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pAd->SharedKey[BSS0][0].Key,
+ pAd->SharedKey[BSS0][0].TxMic,
+ pAd->SharedKey[BSS0][0].RxMic);
+
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pEntry);
+
+ // Make Transmitting frame
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ LENGTH_802_3, &Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+
+ // Copy frame to Tx ring and Send Message 4 to authenticator
+ RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
+
+ // set 802.1x port control
+ //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAd);
+
+ // Indicate Connected for GUI
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+
+ MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+ os_free_mem(pAd, (PUCHAR)mpool);
+
+
+ // send wireless event - for set key done WPA2
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, BSS0, 0);
+
+ DBGPRINT(RT_DEBUG_ERROR, ("Wpa2PairMsg3Action <-----\n"));
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process Group key 2-way handshaking
+
+ Arguments:
+ pAd Pointer to our adapter
+ Elem Message body
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID WpaGroupMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ PUCHAR pOutBuffer = NULL;
+ UCHAR Header802_3[14];
+ ULONG FrameLen = 0;
+ EAPOL_PACKET Packet;
+ PEAPOL_PACKET pGroup;
+ UCHAR *mpool, *digest, *KEYDATA;
+ UCHAR Mic[16], OldMic[16];
+ UCHAR GTK[32], Key[32];
+ KEY_INFO peerKeyInfo;
+
+ // allocate memory
+ os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
+
+ if(mpool == NULL)
+ return;
+
+ // digest Len = 80.
+ digest = (UCHAR *) ROUND_UP(mpool, 4);
+ // KEYDATA Len = 512.
+ KEYDATA = (UCHAR *) ROUND_UP(digest + 80, 4);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action ----->\n"));
+
+ // Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8)
+ pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+ NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+ NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pGroup->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+ *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
+
+ // 0. Check cipher type match
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+ else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // 1. Verify Replay counter
+ // Check Replay Counter, it has to be larger than last one. No need to be exact one larger
+ if(RTMPCompareMemory(pGroup->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // Update new replay counter
+ NdisMoveMemory(pAd->StaCfg.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // 2. Verify MIC is valid
+ // Save the MIC and replace with zero
+ NdisMoveMemory(OldMic, pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ NdisZeroMemory(pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ { // AES
+ HMAC_SHA1((PUCHAR) pGroup, pGroup->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ { // TKIP
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pGroup, pGroup->Body_Len[1] + 4, Mic);
+ }
+
+ if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
+ MlmeFreeMemory(pAd, (PUCHAR)mpool);
+ return;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
+
+
+ // 3. Decrypt GTK from Key Data
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // Decrypt AES GTK
+ AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pGroup->KeyDesc.KeyDataLen[1], pGroup->KeyDesc.KeyData);
+ }
+ else // TKIP
+ {
+ INT i;
+
+ // Decrypt TKIP GTK
+ // Construct 32 bytes RC4 Key
+ NdisMoveMemory(Key, pGroup->KeyDesc.KeyIv, 16);
+ NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
+ //discard first 256 bytes
+ for(i = 0; i < 256; i++)
+ ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
+ // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
+ ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pGroup->KeyDesc.KeyData, pGroup->KeyDesc.KeyDataLen[1]);
+ }
+
+ // Process decrypted key data material
+ // Parse keyData to handle KDE format for WPA2PSK
+ if (peerKeyInfo.EKD_DL)
+ {
+ if (!ParseKeyData(pAd, KEYDATA, pGroup->KeyDesc.KeyDataLen[1], 0))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+ }
+ else // WPAPSK
+ {
+ // set key material, TxMic and RxMic for WPAPSK
+ NdisMoveMemory(GTK, KEYDATA, 32);
+ NdisMoveMemory(pAd->StaCfg.GTK, GTK, 32);
+ pAd->StaCfg.DefaultKeyId = peerKeyInfo.KeyIndex;
+
+ // Prepare pair-wise key information into shared key table
+ NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, GTK, LEN_TKIP_EK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &GTK[16], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &GTK[24], LEN_TKIP_TXMICK);
+
+ // Update Shared Key CipherAlg
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
+ if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+
+ //hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
+ }
+
+ // Update group key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
+
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ NULL);
+
+ // set 802.1x port control
+ //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAd);
+
+ // Indicate Connected for GUI
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+
+ // init header and Fill Packet
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero Group message 1 body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
+
+ //
+ // Group Message 2 as EAPOL-Key(1,0,0,0,G,0,0,MIC,0)
+ //
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+ {
+ Packet.KeyDesc.Type = WPA2_KEY_DESC;
+ }
+ else
+ {
+ Packet.KeyDesc.Type = WPA1_KEY_DESC;
+ }
+
+ // Key descriptor version and appropriate RSN IE
+ Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
+
+ // Update Key Length
+ Packet.KeyDesc.KeyLength[0] = pGroup->KeyDesc.KeyLength[0];
+ Packet.KeyDesc.KeyLength[1] = pGroup->KeyDesc.KeyLength[1];
+
+ // Key Index as G-Msg 1
+ if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
+ Packet.KeyDesc.KeyInfo.KeyIndex = peerKeyInfo.KeyIndex;
+
+ // Key Type Group key
+ Packet.KeyDesc.KeyInfo.KeyType = GROUPKEY;
+
+ // KeyMic field presented
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+
+ // Secure bit
+ Packet.KeyDesc.KeyInfo.Secure = 1;
+
+ // Convert to little-endian format.
+ *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+ // Key Replay count
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Out buffer for transmitting group message 2
+ MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
+ if(pOutBuffer == NULL)
+ {
+ MlmeFreeMemory(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // Prepare and Fill MIC value
+ NdisZeroMemory(Mic, sizeof(Mic));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ }
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ LENGTH_802_3, &Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+
+ // 5. Copy frame to Tx ring and prepare for encryption
+ RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
+
+ // 6 Free allocated memory
+ MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+ os_free_mem(pAd, (PUCHAR)mpool);
+
+ // send wireless event - for set key done WPA2
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init WPA MAC header
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID WpaMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR wep,
+ IN PUCHAR pAddr1)
+{
+ NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+ pHdr80211->FC.Type = BTYPE_DATA;
+ pHdr80211->FC.ToDs = 1;
+ if (wep == 1)
+ pHdr80211->FC.Wep = 1;
+
+ // Addr1: BSSID, Addr2: SA, Addr3: DA
+ COPY_MAC_ADDR(pHdr80211->Addr1, pAddr1);
+ COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHdr80211->Addr3, pAd->CommonCfg.Bssid);
+ pHdr80211->Sequence = pAd->Sequence;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Copy frame from waiting queue into relative ring buffer and set
+ appropriate ASIC register to kick hardware encryption before really
+ sent out to air.
+
+ Arguments:
+ pAd Pointer to our adapter
+ PNDIS_PACKET Pointer to outgoing Ndis frame
+ NumberOfFrag Number of fragment required
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPToWirelessSta(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN UINT DataLen,
+ IN BOOLEAN is4wayFrame)
+
+{
+ NDIS_STATUS Status;
+ PNDIS_PACKET pPacket;
+ UCHAR Index;
+
+ do
+ {
+ // 1. build a NDIS packet and call RTMPSendPacket();
+ // be careful about how/when to release this internal allocated NDIS PACKET buffer
+ Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen);
+ if (Status != NDIS_STATUS_SUCCESS)
+ break;
+
+ if (is4wayFrame)
+ RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
+ else
+ RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
+
+ // 2. send out the packet
+ Status = STASendPacket(pAd, pPacket);
+ if(Status == NDIS_STATUS_SUCCESS)
+ {
+ // Dequeue one frame from TxSwQueue0..3 queue and process it
+ // There are three place calling dequeue for TX ring.
+ // 1. Here, right after queueing the frame.
+ // 2. At the end of TxRingTxDone service routine.
+ // 3. Upon NDIS call RTMPSendPackets
+ if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
+ {
+ for(Index = 0; Index < 5; Index ++)
+ if(pAd->TxSwQueue[Index].Number > 0)
+ RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS);
+ }
+ }
+ } while(FALSE);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check Sanity RSN IE form AP
+
+ Arguments:
+
+ Return Value:
+
+
+ ========================================================================
+*/
+BOOLEAN CheckRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN UCHAR DataLen,
+ OUT UCHAR *Offset)
+{
+ PUCHAR pVIE;
+ UCHAR len;
+ PEID_STRUCT pEid;
+ BOOLEAN result = FALSE;
+
+ pVIE = pData;
+ len = DataLen;
+ *Offset = 0;
+
+ while (len > sizeof(RSNIE2))
+ {
+ pEid = (PEID_STRUCT) pVIE;
+ // WPA RSN IE
+ if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
+ {
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) &&
+ (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
+ (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA/WPAPSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
+ result = TRUE;
+ }
+
+ *Offset += (pEid->Len + 2);
+ }
+ // WPA2 RSN IE
+ else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
+ {
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) &&
+ (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
+ (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
+ result = TRUE;
+ }
+
+ *Offset += (pEid->Len + 2);
+ }
+ else
+ {
+ break;
+ }
+
+ pVIE += (pEid->Len + 2);
+ len -= (pEid->Len + 2);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> skip_offset(%d) \n", *Offset));
+
+ return result;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
+ GTK is encaptulated in KDE format at p.83 802.11i D10
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+ 802.11i D10
+
+ ========================================================================
+*/
+BOOLEAN ParseKeyData(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKeyData,
+ IN UCHAR KeyDataLen,
+ IN UCHAR bPairewise)
+{
+ PKDE_ENCAP pKDE = NULL;
+ PUCHAR pMyKeyData = pKeyData;
+ UCHAR KeyDataLength = KeyDataLen;
+ UCHAR GTKLEN;
+ UCHAR skip_offset;
+
+ // Verify The RSN IE contained in Pairewise-Msg 3 and skip it
+ if (bPairewise)
+ {
+ // Check RSN IE whether it is WPA2/WPA2PSK
+ if (!CheckRSNIE(pAd, pKeyData, KeyDataLen, &skip_offset))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE mismatched \n"));
+ hex_dump("Get KEYDATA :", pKeyData, KeyDataLen);
+ return FALSE;
+ }
+ else
+ {
+ // skip RSN IE
+ pMyKeyData += skip_offset;
+ KeyDataLength -= skip_offset;
+
+ //DBGPRINT(RT_DEBUG_TRACE, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("ParseKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
+
+ // Parse EKD format
+ if (KeyDataLength >= 8)
+ {
+ pKDE = (PKDE_ENCAP) pMyKeyData;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KeyDataLength is too short \n"));
+ return FALSE;
+ }
+
+
+ // Sanity check - shared key index should not be 0
+ if (pKDE->GTKEncap.Kid == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index zero \n"));
+ return FALSE;
+ }
+
+ // Sanity check - KED length
+ if (KeyDataLength < (pKDE->Len + 2))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
+ return FALSE;
+ }
+
+ // Get GTK length - refer to IEEE 802.11i-2004 p.82
+ GTKLEN = pKDE->Len -6;
+
+ if (GTKLEN < LEN_AES_KEY)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
+ return FALSE;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("GTK Key with KDE formet got index=%d, len=%d \n", pKDE->GTKEncap.Kid, GTKLEN));
+
+ // Update GTK
+ // set key material, TxMic and RxMic for WPAPSK
+ NdisMoveMemory(pAd->StaCfg.GTK, pKDE->GTKEncap.GTK, 32);
+ pAd->StaCfg.DefaultKeyId = pKDE->GTKEncap.Kid;
+
+ // Update shared key table
+ NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKDE->GTKEncap.GTK, LEN_TKIP_EK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &pKDE->GTKEncap.GTK[16], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &pKDE->GTKEncap.GTK[24], LEN_TKIP_TXMICK);
+
+ // Update Shared Key CipherAlg
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
+ if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+
+ return TRUE;
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Cisco CCKM PRF function
+
+ Arguments:
+ key Cisco Base Transient Key (BTK)
+ key_len The key length of the BTK
+ data Ruquest Number(RN) + BSSID
+ data_len The length of the data
+ output Store for PTK(Pairwise transient keys)
+ len The length of the output
+ Return Value:
+ None
+
+ Note:
+ 802.1i Annex F.9
+
+ ========================================================================
+*/
+VOID CCKMPRF(
+ IN UCHAR *key,
+ IN INT key_len,
+ IN UCHAR *data,
+ IN INT data_len,
+ OUT UCHAR *output,
+ IN INT len)
+{
+ INT i;
+ UCHAR input[1024];
+ INT currentindex = 0;
+ INT total_len;
+
+ NdisMoveMemory(input, data, data_len);
+ total_len = data_len;
+ input[total_len] = 0;
+ total_len++;
+ for (i = 0; i < (len + 19) / 20; i++)
+ {
+ HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
+ currentindex += 20;
+ input[total_len - 1]++;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process MIC error indication and record MIC error timer.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pWpaKey Pointer to the WPA key structure
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPReportMicError(
+ IN PRTMP_ADAPTER pAd,
+ IN PCIPHER_KEY pWpaKey)
+{
+ ULONG Now;
+ UCHAR unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1:0);
+
+ // Record Last MIC error time and count
+ Now = jiffies;
+ if (pAd->StaCfg.MicErrCnt == 0)
+ {
+ pAd->StaCfg.MicErrCnt++;
+ pAd->StaCfg.LastMicErrorTime = Now;
+ NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
+ }
+ else if (pAd->StaCfg.MicErrCnt == 1)
+ {
+ if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now)
+ {
+ // Update Last MIC error time, this did not violate two MIC errors within 60 seconds
+ pAd->StaCfg.LastMicErrorTime = Now;
+ }
+ else
+ {
+
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+ pAd->StaCfg.LastMicErrorTime = Now;
+ // Violate MIC error counts, MIC countermeasures kicks in
+ pAd->StaCfg.MicErrCnt++;
+ // We shall block all reception
+ // We shall clean all Tx ring and disassoicate from AP after next EAPOL frame
+ //
+ // No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets
+ // if pAd->StaCfg.MicErrCnt greater than 2.
+ //
+ // RTMPRingCleanUp(pAd, QID_AC_BK);
+ // RTMPRingCleanUp(pAd, QID_AC_BE);
+ // RTMPRingCleanUp(pAd, QID_AC_VI);
+ // RTMPRingCleanUp(pAd, QID_AC_VO);
+ // RTMPRingCleanUp(pAd, QID_HCCA);
+ }
+ }
+ else
+ {
+ // MIC error count >= 2
+ // This should not happen
+ ;
+ }
+ MlmeEnqueue(pAd,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_MIC_FAILURE_REPORT_FRAME,
+ 1,
+ &unicastKey);
+
+ if (pAd->StaCfg.MicErrCnt == 2)
+ {
+ RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100);
+ }
+}
+
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#define LENGTH_EAP_H 4
+// If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)).
+INT WpaCheckEapCode(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pFrame,
+ IN USHORT FrameLen,
+ IN USHORT OffSet)
+{
+
+ PUCHAR pData;
+ INT result = 0;
+
+ if( FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H )
+ return result;
+
+ pData = pFrame + OffSet; // skip offset bytes
+
+ if(*(pData+1) == EAPPacket) // 802.1x header - Packet Type
+ {
+ result = *(pData+4); // EAP header - Code
+ }
+
+ return result;
+}
+
+VOID WpaSendMicFailureToWpaSupplicant(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bUnicast)
+{
+ union iwreq_data wrqu;
+ char custom[IW_CUSTOM_MAX] = {0};
+
+ sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
+ if (bUnicast)
+ sprintf(custom, "%s unicast", custom);
+ wrqu.data.length = strlen(custom);
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
+
+ return;
+}
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+VOID WpaMicFailureReportFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PUCHAR pOutBuffer = NULL;
+ UCHAR Header802_3[14];
+ ULONG FrameLen = 0;
+ EAPOL_PACKET Packet;
+ UCHAR Mic[16];
+ BOOLEAN bUnicast;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));
+
+ bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE);
+ pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);
+
+ // init 802.3 header and Fill Packet
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+
+ Packet.KeyDesc.Type = WPA1_KEY_DESC;
+
+ // Request field presented
+ Packet.KeyDesc.KeyInfo.Request = 1;
+
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
+ }
+ else // TKIP
+ {
+ Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
+ }
+
+ Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);
+
+ // KeyMic field presented
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+
+ // Error field presented
+ Packet.KeyDesc.KeyInfo.Error = 1;
+
+ // Update packet length after decide Key data payload
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;
+
+ // Key Replay Count
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
+ inc_byte_array(pAd->StaCfg.ReplayCounter, 8);
+
+ // Convert to little-endian format.
+ *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+
+ MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
+ if(pOutBuffer == NULL)
+ {
+ return;
+ }
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // Prepare and Fill MIC value
+ NdisZeroMemory(Mic, sizeof(Mic));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ { // AES
+ UCHAR digest[20] = {0};
+ HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ { // TKIP
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ }
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ LENGTH_802_3, &Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // opy frame to Tx ring and send MIC failure report frame to authenticator
+ RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
+
+ MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
+}
+
+/** from wpa_supplicant
+ * inc_byte_array - Increment arbitrary length byte array by one
+ * @counter: Pointer to byte array
+ * @len: Length of the counter in bytes
+ *
+ * This function increments the last byte of the counter by one and continues
+ * rolling over to more significant bytes if the byte was incremented from
+ * 0xff to 0x00.
+ */
+void inc_byte_array(UCHAR *counter, int len)
+{
+ int pos = len - 1;
+ while (pos >= 0) {
+ counter[pos]++;
+ if (counter[pos] != 0)
+ break;
+ pos--;
+ }
+}
+
+VOID WpaDisassocApAndBlockAssoc(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext;
+ MLME_DISASSOC_REQ_STRUCT DisassocReq;
+
+ // disassoc from current AP first
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n"));
+ DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_MIC_FAILURE);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+ pAd->StaCfg.bBlockAssoc = TRUE;
+}
+
diff --git a/drivers/staging/rt3070/sta_ioctl.c b/drivers/staging/rt3070/sta_ioctl.c
new file mode 100644
index 00000000000..079454835a4
--- /dev/null
+++ b/drivers/staging/rt3070/sta_ioctl.c
@@ -0,0 +1,7203 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ sta_ioctl.c
+
+ Abstract:
+ IOCTL related subroutines
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Rory Chen 01-03-2003 created
+ Rory Chen 02-14-2005 modify to support RT61
+*/
+
+#include "rt_config.h"
+
+#ifdef DBG
+extern ULONG RTDebugLevel;
+#endif
+
+#define NR_WEP_KEYS 4
+#define WEP_SMALL_KEY_LEN (40/8)
+#define WEP_LARGE_KEY_LEN (104/8)
+
+#define GROUP_KEY_NO 4
+
+extern UCHAR CipherWpa2Template[];
+extern UCHAR CipherWpaPskTkip[];
+extern UCHAR CipherWpaPskTkipLen;
+
+typedef struct PACKED _RT_VERSION_INFO{
+ UCHAR DriverVersionW;
+ UCHAR DriverVersionX;
+ UCHAR DriverVersionY;
+ UCHAR DriverVersionZ;
+ UINT DriverBuildYear;
+ UINT DriverBuildMonth;
+ UINT DriverBuildDay;
+} RT_VERSION_INFO, *PRT_VERSION_INFO;
+
+struct iw_priv_args privtab[] = {
+{ RTPRIV_IOCTL_SET,
+ IW_PRIV_TYPE_CHAR | 1024, 0,
+ "set"},
+
+{ RTPRIV_IOCTL_SHOW, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+ ""},
+{ RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+ ""},
+/* --- sub-ioctls definitions --- */
+ { SHOW_CONN_STATUS,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
+ { SHOW_DRVIER_VERION,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
+ { SHOW_BA_INFO,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
+ { SHOW_DESC_INFO,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
+ { RAIO_OFF,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
+ { RAIO_ON,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
+#ifdef QOS_DLS_SUPPORT
+ { SHOW_DLS_ENTRY_INFO,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "dlsentryinfo" },
+#endif // QOS_DLS_SUPPORT //
+ { SHOW_CFG_VALUE,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
+/* --- sub-ioctls relations --- */
+
+#ifdef DBG
+{ RTPRIV_IOCTL_BBP,
+ IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+ "bbp"},
+{ RTPRIV_IOCTL_MAC,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
+ "mac"},
+#ifdef RT30xx
+{ RTPRIV_IOCTL_RF,
+ IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+ "rf"},
+#endif // RT30xx //
+{ RTPRIV_IOCTL_E2P,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
+ "e2p"},
+#endif /* DBG */
+
+{ RTPRIV_IOCTL_STATISTICS,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+ "stat"},
+{ RTPRIV_IOCTL_GSITESURVEY,
+ 0, IW_PRIV_TYPE_CHAR | 1024,
+ "get_site_survey"},
+
+
+};
+
+INT Set_SSID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+#ifdef WMM_SUPPORT
+INT Set_WmmCapable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif
+
+INT Set_NetworkType_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_EncrypType_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_DefaultKeyID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_Key1_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_Key2_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_Key3_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_Key4_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_WPAPSK_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+
+INT Set_PSMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+INT Set_Wpa_Support(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef DBG
+
+VOID RTMPIoctlMAC(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq);
+
+VOID RTMPIoctlE2PROM(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq);
+
+#ifdef RT30xx
+VOID RTMPIoctlRF(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq);
+#endif // RT30xx //
+#endif // DBG //
+
+
+NDIS_STATUS RTMPWPANoneAddKeyProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PVOID pBuf);
+
+INT Set_FragTest_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+#ifdef DOT11_N_SUPPORT
+INT Set_TGnWifiTest_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif // DOT11_N_SUPPORT //
+
+INT Set_LongRetryLimit_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_ShortRetryLimit_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+INT Set_Ieee80211dClientMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+#ifdef CARRIER_DETECTION_SUPPORT
+INT Set_CarrierDetect_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif // CARRIER_DETECTION_SUPPORT //
+
+static struct {
+ CHAR *name;
+ INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
+} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
+ {"DriverVersion", Set_DriverVersion_Proc},
+ {"CountryRegion", Set_CountryRegion_Proc},
+ {"CountryRegionABand", Set_CountryRegionABand_Proc},
+ {"SSID", Set_SSID_Proc},
+ {"WirelessMode", Set_WirelessMode_Proc},
+ {"TxBurst", Set_TxBurst_Proc},
+ {"TxPreamble", Set_TxPreamble_Proc},
+ {"TxPower", Set_TxPower_Proc},
+ {"Channel", Set_Channel_Proc},
+ {"BGProtection", Set_BGProtection_Proc},
+ {"RTSThreshold", Set_RTSThreshold_Proc},
+ {"FragThreshold", Set_FragThreshold_Proc},
+#ifdef DOT11_N_SUPPORT
+ {"HtBw", Set_HtBw_Proc},
+ {"HtMcs", Set_HtMcs_Proc},
+ {"HtGi", Set_HtGi_Proc},
+ {"HtOpMode", Set_HtOpMode_Proc},
+ {"HtExtcha", Set_HtExtcha_Proc},
+ {"HtMpduDensity", Set_HtMpduDensity_Proc},
+ {"HtBaWinSize", Set_HtBaWinSize_Proc},
+ {"HtRdg", Set_HtRdg_Proc},
+ {"HtAmsdu", Set_HtAmsdu_Proc},
+ {"HtAutoBa", Set_HtAutoBa_Proc},
+ {"HtBaDecline", Set_BADecline_Proc},
+ {"HtProtect", Set_HtProtect_Proc},
+ {"HtMimoPs", Set_HtMimoPs_Proc},
+#endif // DOT11_N_SUPPORT //
+
+#ifdef AGGREGATION_SUPPORT
+ {"PktAggregate", Set_PktAggregate_Proc},
+#endif
+
+#ifdef WMM_SUPPORT
+ {"WmmCapable", Set_WmmCapable_Proc},
+#endif
+ {"IEEE80211H", Set_IEEE80211H_Proc},
+ {"NetworkType", Set_NetworkType_Proc},
+ {"AuthMode", Set_AuthMode_Proc},
+ {"EncrypType", Set_EncrypType_Proc},
+ {"DefaultKeyID", Set_DefaultKeyID_Proc},
+ {"Key1", Set_Key1_Proc},
+ {"Key2", Set_Key2_Proc},
+ {"Key3", Set_Key3_Proc},
+ {"Key4", Set_Key4_Proc},
+ {"WPAPSK", Set_WPAPSK_Proc},
+ {"ResetCounter", Set_ResetStatCounter_Proc},
+ {"PSMode", Set_PSMode_Proc},
+#ifdef DBG
+ {"Debug", Set_Debug_Proc},
+#endif
+
+#ifdef RALINK_ATE
+ {"ATE", Set_ATE_Proc},
+ {"ATEDA", Set_ATE_DA_Proc},
+ {"ATESA", Set_ATE_SA_Proc},
+ {"ATEBSSID", Set_ATE_BSSID_Proc},
+ {"ATECHANNEL", Set_ATE_CHANNEL_Proc},
+ {"ATETXPOW0", Set_ATE_TX_POWER0_Proc},
+ {"ATETXPOW1", Set_ATE_TX_POWER1_Proc},
+ {"ATETXANT", Set_ATE_TX_Antenna_Proc},
+ {"ATERXANT", Set_ATE_RX_Antenna_Proc},
+ {"ATETXFREQOFFSET", Set_ATE_TX_FREQOFFSET_Proc},
+ {"ATETXBW", Set_ATE_TX_BW_Proc},
+ {"ATETXLEN", Set_ATE_TX_LENGTH_Proc},
+ {"ATETXCNT", Set_ATE_TX_COUNT_Proc},
+ {"ATETXMCS", Set_ATE_TX_MCS_Proc},
+ {"ATETXMODE", Set_ATE_TX_MODE_Proc},
+ {"ATETXGI", Set_ATE_TX_GI_Proc},
+ {"ATERXFER", Set_ATE_RX_FER_Proc},
+ {"ATERRF", Set_ATE_Read_RF_Proc},
+ {"ATEWRF1", Set_ATE_Write_RF1_Proc},
+ {"ATEWRF2", Set_ATE_Write_RF2_Proc},
+ {"ATEWRF3", Set_ATE_Write_RF3_Proc},
+ {"ATEWRF4", Set_ATE_Write_RF4_Proc},
+ {"ATELDE2P", Set_ATE_Load_E2P_Proc},
+ {"ATERE2P", Set_ATE_Read_E2P_Proc},
+ {"ATESHOW", Set_ATE_Show_Proc},
+ {"ATEHELP", Set_ATE_Help_Proc},
+
+#ifdef RALINK_28xx_QA
+ {"TxStop", Set_TxStop_Proc},
+ {"RxStop", Set_RxStop_Proc},
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ {"WpaSupport", Set_Wpa_Support},
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+
+
+ {"FixedTxMode", Set_FixedTxMode_Proc},
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+ {"OpMode", Set_OpMode_Proc},
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+#ifdef DOT11_N_SUPPORT
+ {"TGnWifiTest", Set_TGnWifiTest_Proc},
+ {"ForceGF", Set_ForceGF_Proc},
+#endif // DOT11_N_SUPPORT //
+#ifdef QOS_DLS_SUPPORT
+ {"DlsAddEntry", Set_DlsAddEntry_Proc},
+ {"DlsTearDownEntry", Set_DlsTearDownEntry_Proc},
+#endif // QOS_DLS_SUPPORT //
+ {"LongRetry", Set_LongRetryLimit_Proc},
+ {"ShortRetry", Set_ShortRetryLimit_Proc},
+#ifdef EXT_BUILD_CHANNEL_LIST
+ {"11dClientMode", Set_Ieee80211dClientMode_Proc},
+#endif // EXT_BUILD_CHANNEL_LIST //
+#ifdef CARRIER_DETECTION_SUPPORT
+ {"CarrierDetect", Set_CarrierDetect_Proc},
+#endif // CARRIER_DETECTION_SUPPORT //
+//2008/09/11:KH add to support efuse<--
+#ifdef RT30xx
+ {"efuseFreeNumber", set_eFuseGetFreeBlockCount_Proc},
+ {"efuseDump", set_eFusedump_Proc},
+ {"efuseLoadFromBin", set_eFuseLoadFromBin_Proc},
+#endif // RT30xx //
+//2008/09/11:KH add to support efuse-->
+ {NULL,}
+};
+
+
+VOID RTMPAddKey(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_802_11_KEY pKey)
+{
+ ULONG KeyIdx;
+ MAC_TABLE_ENTRY *pEntry;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
+
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ if (pKey->KeyIndex & 0x80000000)
+ {
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ NdisZeroMemory(pAd->StaCfg.PMK, 32);
+ NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
+ goto end;
+ }
+ // Update PTK
+ NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ {
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+ }
+ else
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+ }
+
+ // Decide its ChiperAlg
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+ else
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
+
+ // Update these related information to MAC_TABLE_ENTRY
+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
+ NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
+ NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
+ NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
+ pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+
+ // Update pairwise key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pAd->SharedKey[BSS0][0].Key,
+ pAd->SharedKey[BSS0][0].TxMic,
+ pAd->SharedKey[BSS0][0].RxMic);
+
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pEntry);
+
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
+ {
+ // set 802.1x port control
+ //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAd);
+
+ // Indicate Connected for GUI
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ }
+ }
+ else
+ {
+ // Update GTK
+ pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
+ NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+ {
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+ }
+ else
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+ }
+
+ // Update Shared Key CipherAlg
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
+ if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+
+ // Update group key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
+
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ NULL);
+
+ // set 802.1x port control
+ //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAd);
+
+ // Indicate Connected for GUI
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ }
+ }
+ else // dynamic WEP from wpa_supplicant
+ {
+ UCHAR CipherAlg;
+ PUCHAR Key;
+
+ if(pKey->KeyLength == 32)
+ goto end;
+
+ KeyIdx = pKey->KeyIndex & 0x0fffffff;
+
+ if (KeyIdx < 4)
+ {
+ // it is a default shared key, for Pairwise key setting
+ if (pKey->KeyIndex & 0x80000000)
+ {
+ pEntry = MacTableLookup(pAd, pKey->BSSID);
+
+ if (pEntry)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
+
+ // set key material and key length
+ pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
+ NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
+
+ // set Cipher type
+ if (pKey->KeyLength == 5)
+ pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
+ else
+ pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
+
+ // Add Pair-wise key to Asic
+ AsicAddPairwiseKeyEntry(
+ pAd,
+ pEntry->Addr,
+ (UCHAR)pEntry->Aid,
+ &pEntry->PairwiseKey);
+
+ // update WCID attribute table and IVEIV table for this entry
+ RTMPAddWcidAttributeEntry(
+ pAd,
+ BSS0,
+ KeyIdx, // The value may be not zero
+ pEntry->PairwiseKey.CipherAlg,
+ pEntry);
+
+ }
+ }
+ else
+ {
+ // Default key for tx (shared key)
+ pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+
+ // set key material and key length
+ pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
+ NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
+
+ // Set Ciper type
+ if (pKey->KeyLength == 5)
+ pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
+ else
+ pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
+
+ CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
+ Key = pAd->SharedKey[BSS0][KeyIdx].Key;
+
+ // Set Group key material to Asic
+ AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
+
+ // Update WCID attribute table and IVEIV table for this group key table
+ RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
+
+ }
+ }
+ }
+end:
+ return;
+}
+
+char * rtstrchr(const char * s, int c)
+{
+ for(; *s != (char) c; ++s)
+ if (*s == '\0')
+ return NULL;
+ return (char *) s;
+}
+
+/*
+This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
+*/
+
+int
+rt_ioctl_giwname(struct net_device *dev,
+ struct iw_request_info *info,
+ char *name, char *extra)
+{
+// PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+#ifdef RT2870
+ strncpy(name, "RT2870 Wireless", IFNAMSIZ);
+#endif // RT2870 //
+ return 0;
+}
+
+int rt_ioctl_siwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ int chan = -1;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+
+ if (freq->e > 1)
+ return -EINVAL;
+
+ if((freq->e == 0) && (freq->m <= 1000))
+ chan = freq->m; // Setting by channel number
+ else
+ MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
+
+ if (ChannelSanity(pAdapter, chan) == TRUE)
+ {
+ pAdapter->CommonCfg.Channel = chan;
+ DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
+ }
+ else
+ return -EINVAL;
+
+ return 0;
+}
+int rt_ioctl_giwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ VIRTUAL_ADAPTER *pVirtualAd = NULL;
+ PRTMP_ADAPTER pAdapter;
+ UCHAR ch;
+ ULONG m;
+
+ if (dev->priv_flags == INT_MAIN)
+ {
+ pAdapter = dev->ml_priv;
+ }
+ else
+ {
+ pVirtualAd = dev->ml_priv;
+ pAdapter = pVirtualAd->RtmpDev->ml_priv;
+ }
+
+ if (pAdapter == NULL)
+ {
+ /* if 1st open fail, pAd will be free;
+ So the net_dev->ml_priv will be NULL in 2rd open */
+ return -ENETDOWN;
+ }
+
+ ch = pAdapter->CommonCfg.Channel;
+
+ DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq %d\n", ch));
+
+ MAP_CHANNEL_ID_TO_KHZ(ch, m);
+ freq->m = m * 100;
+ freq->e = 1;
+ return 0;
+}
+
+int rt_ioctl_siwmode(struct net_device *dev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ switch (*mode)
+ {
+ case IW_MODE_ADHOC:
+ Set_NetworkType_Proc(pAdapter, "Adhoc");
+ break;
+ case IW_MODE_INFRA:
+ Set_NetworkType_Proc(pAdapter, "Infra");
+ break;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
+ case IW_MODE_MONITOR:
+ Set_NetworkType_Proc(pAdapter, "Monitor");
+ break;
+#endif
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
+ return -EINVAL;
+ }
+
+ // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
+ pAdapter->StaCfg.WpaState = SS_NOTUSE;
+
+ return 0;
+}
+
+int rt_ioctl_giwmode(struct net_device *dev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ if (ADHOC_ON(pAdapter))
+ *mode = IW_MODE_ADHOC;
+ else if (INFRA_ON(pAdapter))
+ *mode = IW_MODE_INFRA;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
+ else if (MONITOR_ON(pAdapter))
+ {
+ *mode = IW_MODE_MONITOR;
+ }
+#endif
+ else
+ *mode = IW_MODE_AUTO;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
+ return 0;
+}
+
+int rt_ioctl_siwsens(struct net_device *dev,
+ struct iw_request_info *info,
+ char *name, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ return 0;
+}
+
+int rt_ioctl_giwsens(struct net_device *dev,
+ struct iw_request_info *info,
+ char *name, char *extra)
+{
+ return 0;
+}
+
+int rt_ioctl_giwrange(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ struct iw_range *range = (struct iw_range *) extra;
+ u16 val;
+ int i;
+
+ DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
+ data->length = sizeof(struct iw_range);
+ memset(range, 0, sizeof(struct iw_range));
+
+ range->txpower_capa = IW_TXPOW_DBM;
+
+ if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
+ {
+ range->min_pmp = 1 * 1024;
+ range->max_pmp = 65535 * 1024;
+ range->min_pmt = 1 * 1024;
+ range->max_pmt = 1000 * 1024;
+ range->pmp_flags = IW_POWER_PERIOD;
+ range->pmt_flags = IW_POWER_TIMEOUT;
+ range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
+ IW_POWER_UNICAST_R | IW_POWER_ALL_R;
+ }
+
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = 14;
+
+ range->retry_capa = IW_RETRY_LIMIT;
+ range->retry_flags = IW_RETRY_LIMIT;
+ range->min_retry = 0;
+ range->max_retry = 255;
+
+ range->num_channels = pAdapter->ChannelListNum;
+
+ val = 0;
+ for (i = 1; i <= range->num_channels; i++)
+ {
+ u32 m;
+ range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
+ MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
+ range->freq[val].m = m * 100; /* HZ */
+
+ range->freq[val].e = 1;
+ val++;
+ if (val == IW_MAX_FREQUENCIES)
+ break;
+ }
+ range->num_frequency = val;
+
+ range->max_qual.qual = 100; /* what is correct max? This was not
+ * documented exactly. At least
+ * 69 has been observed. */
+ range->max_qual.level = 0; /* dB */
+ range->max_qual.noise = 0; /* dB */
+
+ /* What would be suitable values for "average/typical" qual? */
+ range->avg_qual.qual = 20;
+ range->avg_qual.level = -60;
+ range->avg_qual.noise = -95;
+ range->sensitivity = 3;
+
+ range->max_encoding_tokens = NR_WEP_KEYS;
+ range->num_encoding_sizes = 2;
+ range->encoding_size[0] = 5;
+ range->encoding_size[1] = 13;
+
+ range->min_rts = 0;
+ range->max_rts = 2347;
+ range->min_frag = 256;
+ range->max_frag = 2346;
+
+#if WIRELESS_EXT > 17
+ /* IW_ENC_CAPA_* bit field */
+ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+#endif
+
+ return 0;
+}
+
+int rt_ioctl_siwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ NDIS_802_11_MAC_ADDRESS Bssid;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ {
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+ }
+
+ // tell CNTL state machine to call NdisMSetInformationComplete() after completing
+ // this request, because this request is initiated by NDIS.
+ pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
+ // Prevent to connect AP again in STAMlmePeriodicExec
+ pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
+
+ memset(Bssid, 0, MAC_ADDR_LEN);
+ memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_BSSID,
+ sizeof(NDIS_802_11_MAC_ADDRESS),
+ (VOID *)&Bssid);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
+ Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
+
+ return 0;
+}
+
+int rt_ioctl_giwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
+ {
+ ap_addr->sa_family = ARPHRD_ETHER;
+ memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
+ }
+#ifdef WPA_SUPPLICANT_SUPPORT
+ // Add for RT2870
+ else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+ {
+ ap_addr->sa_family = ARPHRD_ETHER;
+ memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
+ }
+#endif // WPA_SUPPLICANT_SUPPORT //
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
+ return -ENOTCONN;
+ }
+
+ return 0;
+}
+
+/*
+ * Units are in db above the noise floor. That means the
+ * rssi values reported in the tx/rx descriptors in the
+ * driver are the SNR expressed in db.
+ *
+ * If you assume that the noise floor is -95, which is an
+ * excellent assumption 99.5 % of the time, then you can
+ * derive the absolute signal level (i.e. -95 + rssi).
+ * There are some other slight factors to take into account
+ * depending on whether the rssi measurement is from 11b,
+ * 11g, or 11a. These differences are at most 2db and
+ * can be documented.
+ *
+ * NB: various calculations are based on the orinoco/wavelan
+ * drivers for compatibility
+ */
+static void set_quality(PRTMP_ADAPTER pAdapter,
+ struct iw_quality *iq,
+ signed char rssi)
+{
+ __u8 ChannelQuality;
+
+ // Normalize Rssi
+ if (rssi >= -50)
+ ChannelQuality = 100;
+ else if (rssi >= -80) // between -50 ~ -80dbm
+ ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
+ else if (rssi >= -90) // between -80 ~ -90dbm
+ ChannelQuality = (__u8)((rssi + 90) * 26)/10;
+ else
+ ChannelQuality = 0;
+
+ iq->qual = (__u8)ChannelQuality;
+
+ iq->level = (__u8)(rssi);
+ iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]); // noise level (dBm)
+ iq->noise += 256 - 143;
+ iq->updated = pAdapter->iw_stats.qual.updated;
+}
+
+int rt_ioctl_iwaplist(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ struct sockaddr addr[IW_MAX_AP];
+ struct iw_quality qual[IW_MAX_AP];
+ int i;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ data->length = 0;
+ return 0;
+ //return -ENETDOWN;
+ }
+
+ for (i = 0; i <IW_MAX_AP ; i++)
+ {
+ if (i >= pAdapter->ScanTab.BssNr)
+ break;
+ addr[i].sa_family = ARPHRD_ETHER;
+ memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
+ set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
+ }
+ data->length = i;
+ memcpy(extra, &addr, i*sizeof(addr[0]));
+ data->flags = 1; /* signal quality present (sort of) */
+ memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
+
+ return 0;
+}
+
+#ifdef SIOCGIWSCAN
+int rt_ioctl_siwscan(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ ULONG Now;
+ int Status = NDIS_STATUS_SUCCESS;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (MONITOR_ON(pAdapter))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
+ return -EINVAL;
+ }
+
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
+ {
+ pAdapter->StaCfg.WpaSupplicantScanCount++;
+ }
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+ if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ return 0;
+ do{
+ Now = jiffies;
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
+ (pAdapter->StaCfg.WpaSupplicantScanCount > 3))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+ }
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
+ ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+ (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
+ (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+ }
+
+ if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ {
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+ }
+
+ // tell CNTL state machine to call NdisMSetInformationComplete() after completing
+ // this request, because this request is initiated by NDIS.
+ pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
+ // Reset allowed scan retries
+ pAdapter->StaCfg.ScanCnt = 0;
+ pAdapter->StaCfg.LastScanTime = Now;
+
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_BSSID_LIST_SCAN,
+ 0,
+ NULL);
+
+ Status = NDIS_STATUS_SUCCESS;
+ RT28XX_MLME_HANDLER(pAdapter);
+ }while(0);
+ return 0;
+}
+
+int rt_ioctl_giwscan(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ int i=0;
+ char *current_ev = extra, *previous_ev = extra;
+ char *end_buf;
+ char *current_val, custom[MAX_CUSTOM_LEN] = {0};
+#ifndef IWEVGENIE
+ char idx;
+#endif // IWEVGENIE //
+ struct iw_event iwe;
+
+ if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ {
+ /*
+ * Still scanning, indicate the caller should try again.
+ */
+ return -EAGAIN;
+ }
+
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
+ {
+ pAdapter->StaCfg.WpaSupplicantScanCount = 0;
+ }
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ if (pAdapter->ScanTab.BssNr == 0)
+ {
+ data->length = 0;
+ return 0;
+ }
+
+#if WIRELESS_EXT >= 17
+ if (data->length > 0)
+ end_buf = extra + data->length;
+ else
+ end_buf = extra + IW_SCAN_MAX_DATA;
+#else
+ end_buf = extra + IW_SCAN_MAX_DATA;
+#endif
+
+ for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
+ {
+ if (current_ev >= end_buf)
+ {
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+ }
+
+ //MAC address
+ //================================
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
+
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ /*
+ Protocol:
+ it will show scanned AP's WirelessMode .
+ it might be
+ 802.11a
+ 802.11a/n
+ 802.11g/n
+ 802.11b/g/n
+ 802.11g
+ 802.11b/g
+ */
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWNAME;
+
+
+ {
+ PBSS_ENTRY pBssEntry=&pAdapter->ScanTab.BssEntry[i];
+ BOOLEAN isGonly=FALSE;
+ int rateCnt=0;
+
+ if (pBssEntry->Channel>14)
+ {
+ if (pBssEntry->HtCapabilityLen!=0)
+ strcpy(iwe.u.name,"802.11a/n");
+ else
+ strcpy(iwe.u.name,"802.11a");
+ }
+ else
+ {
+ /*
+ if one of non B mode rate is set supported rate . it mean G only.
+ */
+ for (rateCnt=0;rateCnt<pBssEntry->SupRateLen;rateCnt++)
+ {
+ /*
+ 6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only.
+ */
+ if (pBssEntry->SupRate[rateCnt]==140 || pBssEntry->SupRate[rateCnt]==146 || pBssEntry->SupRate[rateCnt]>=152)
+ isGonly=TRUE;
+ }
+
+ for (rateCnt=0;rateCnt<pBssEntry->ExtRateLen;rateCnt++)
+ {
+ if (pBssEntry->ExtRate[rateCnt]==140 || pBssEntry->ExtRate[rateCnt]==146 || pBssEntry->ExtRate[rateCnt]>=152)
+ isGonly=TRUE;
+ }
+
+
+ if (pBssEntry->HtCapabilityLen!=0)
+ {
+ if (isGonly==TRUE)
+ strcpy(iwe.u.name,"802.11g/n");
+ else
+ strcpy(iwe.u.name,"802.11b/g/n");
+ }
+ else
+ {
+ if (isGonly==TRUE)
+ strcpy(iwe.u.name,"802.11g");
+ else
+ {
+ if (pBssEntry->SupRateLen==4 && pBssEntry->ExtRateLen==0)
+ strcpy(iwe.u.name,"802.11b");
+ else
+ strcpy(iwe.u.name,"802.11b/g");
+ }
+ }
+ }
+ }
+
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ //ESSID
+ //================================
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
+ iwe.u.data.flags = 1;
+
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ //Network Type
+ //================================
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWMODE;
+ if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
+ {
+ iwe.u.mode = IW_MODE_ADHOC;
+ }
+ else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
+ {
+ iwe.u.mode = IW_MODE_INFRA;
+ }
+ else
+ {
+ iwe.u.mode = IW_MODE_AUTO;
+ }
+ iwe.len = IW_EV_UINT_LEN;
+
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ //Channel and Frequency
+ //================================
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWFREQ;
+ if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
+ iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
+ else
+ iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
+ iwe.u.freq.e = 0;
+ iwe.u.freq.i = 0;
+
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ //Add quality statistics
+ //================================
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVQUAL;
+ iwe.u.qual.level = 0;
+ iwe.u.qual.noise = 0;
+ set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ //Encyption key
+ //================================
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWENCODE;
+ if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
+ iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,&iwe, (char *)pAdapter->SharedKey[BSS0][(iwe.u.data.flags & IW_ENCODE_INDEX)-1].Key);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ //Bit Rate
+ //================================
+ if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
+ {
+ UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWRATE;
+ current_val = current_ev + IW_EV_LCP_LEN;
+ if (tmpRate == 0x82)
+ iwe.u.bitrate.value = 1 * 1000000;
+ else if (tmpRate == 0x84)
+ iwe.u.bitrate.value = 2 * 1000000;
+ else if (tmpRate == 0x8B)
+ iwe.u.bitrate.value = 5.5 * 1000000;
+ else if (tmpRate == 0x96)
+ iwe.u.bitrate.value = 11 * 1000000;
+ else
+ iwe.u.bitrate.value = (tmpRate/2) * 1000000;
+
+ iwe.u.bitrate.disabled = 0;
+ current_val = iwe_stream_add_value(info, current_ev,
+ current_val, end_buf, &iwe,
+ IW_EV_PARAM_LEN);
+
+ if((current_val-current_ev)>IW_EV_LCP_LEN)
+ current_ev = current_val;
+ else
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+ }
+
+#ifdef IWEVGENIE
+ //WPA IE
+ if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
+ {
+ memset(&iwe, 0, sizeof(iwe));
+ memset(&custom[0], 0, MAX_CUSTOM_LEN);
+ memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
+ pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+ }
+
+ //WPA2 IE
+ if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
+ {
+ memset(&iwe, 0, sizeof(iwe));
+ memset(&custom[0], 0, MAX_CUSTOM_LEN);
+ memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
+ pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+ }
+#else
+ //WPA IE
+ //================================
+ if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
+ {
+ NdisZeroMemory(&iwe, sizeof(iwe));
+ memset(&custom[0], 0, MAX_CUSTOM_LEN);
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen * 2) + 7;
+ NdisMoveMemory(custom, "wpa_ie=", 7);
+ for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].WpaIE.IELen; idx++)
+ sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].WpaIE.IE[idx]);
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+ }
+
+ //WPA2 IE
+ if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
+ {
+ NdisZeroMemory(&iwe, sizeof(iwe));
+ memset(&custom[0], 0, MAX_CUSTOM_LEN);
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen * 2) + 7;
+ NdisMoveMemory(custom, "rsn_ie=", 7);
+ for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].RsnIE.IELen; idx++)
+ sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].RsnIE.IE[idx]);
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+ }
+#endif // IWEVGENIE //
+ }
+
+ data->length = current_ev - extra;
+ pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+ DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
+ return 0;
+}
+#endif
+
+int rt_ioctl_siwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *essid)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (data->flags)
+ {
+ PCHAR pSsidString = NULL;
+
+ // Includes null character.
+ if (data->length > (IW_ESSID_MAX_SIZE + 1))
+ return -E2BIG;
+
+ pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
+ if (pSsidString)
+ {
+ NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
+ NdisMoveMemory(pSsidString, essid, data->length);
+ if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
+ return -EINVAL;
+ }
+ else
+ return -ENOMEM;
+ }
+ else
+ {
+ // ANY ssid
+ if (Set_SSID_Proc(pAdapter, "") == FALSE)
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int rt_ioctl_giwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *essid)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ data->flags = 1;
+ if (MONITOR_ON(pAdapter))
+ {
+ data->length = 0;
+ return 0;
+ }
+
+ if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
+ data->length = pAdapter->CommonCfg.SsidLen;
+ memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
+ }
+#ifdef RT2870
+#ifdef WPA_SUPPLICANT_SUPPORT
+ // Add for RT2870
+ else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+ {
+ data->length = pAdapter->CommonCfg.SsidLen;
+ memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
+ }
+#endif // WPA_SUPPLICANT_SUPPORT //
+#endif // RT2870 //
+ else
+ {//the ANY ssid was specified
+ data->length = 0;
+ DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
+ }
+
+ return 0;
+
+}
+
+int rt_ioctl_siwnickn(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *nickname)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (data->length > IW_ESSID_MAX_SIZE)
+ return -EINVAL;
+
+ memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
+ memcpy(pAdapter->nickname, nickname, data->length);
+
+
+ return 0;
+}
+
+int rt_ioctl_giwnickn(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *nickname)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ if (data->length > strlen(pAdapter->nickname) + 1)
+ data->length = strlen(pAdapter->nickname) + 1;
+ if (data->length > 0) {
+ memcpy(nickname, pAdapter->nickname, data->length-1);
+ nickname[data->length-1] = '\0';
+ }
+ return 0;
+}
+
+int rt_ioctl_siwrts(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ u16 val;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (rts->disabled)
+ val = MAX_RTS_THRESHOLD;
+ else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
+ return -EINVAL;
+ else if (rts->value == 0)
+ val = MAX_RTS_THRESHOLD;
+ else
+ val = rts->value;
+
+ if (val != pAdapter->CommonCfg.RtsThreshold)
+ pAdapter->CommonCfg.RtsThreshold = val;
+
+ return 0;
+}
+
+int rt_ioctl_giwrts(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ rts->value = pAdapter->CommonCfg.RtsThreshold;
+ rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
+ rts->fixed = 1;
+
+ return 0;
+}
+
+int rt_ioctl_siwfrag(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ u16 val;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (frag->disabled)
+ val = MAX_FRAG_THRESHOLD;
+ else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD)
+ val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
+ else if (frag->value == 0)
+ val = MAX_FRAG_THRESHOLD;
+ else
+ return -EINVAL;
+
+ pAdapter->CommonCfg.FragmentThreshold = val;
+ return 0;
+}
+
+int rt_ioctl_giwfrag(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ frag->value = pAdapter->CommonCfg.FragmentThreshold;
+ frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
+ frag->fixed = 1;
+
+ return 0;
+}
+
+#define MAX_WEP_KEY_SIZE 13
+#define MIN_WEP_KEY_SIZE 5
+int rt_ioctl_siwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if ((erq->length == 0) &&
+ (erq->flags & IW_ENCODE_DISABLED))
+ {
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+ goto done;
+ }
+ else if (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN)
+ {
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ if (erq->flags & IW_ENCODE_RESTRICTED)
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+ else
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+ }
+
+ if (erq->length > 0)
+ {
+ int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
+ /* Check the size of the key */
+ if (erq->length > MAX_WEP_KEY_SIZE)
+ {
+ return -EINVAL;
+ }
+ /* Check key index */
+ if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
+ {
+ DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
+ keyIdx, pAdapter->StaCfg.DefaultKeyId));
+
+ //Using default key
+ keyIdx = pAdapter->StaCfg.DefaultKeyId;
+ }
+ else
+ {
+ pAdapter->StaCfg.DefaultKeyId=keyIdx;
+ }
+
+ NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
+
+ if (erq->length == MAX_WEP_KEY_SIZE)
+ {
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
+ }
+ else if (erq->length == MIN_WEP_KEY_SIZE)
+ {
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
+ }
+ else
+ /* Disable the key */
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
+
+ /* Check if the key is not marked as invalid */
+ if(!(erq->flags & IW_ENCODE_NOKEY))
+ {
+ /* Copy the key in the driver */
+ NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
+ }
+ }
+ else
+ {
+ /* Do we want to just set the transmit key index ? */
+ int index = (erq->flags & IW_ENCODE_INDEX) - 1;
+ if ((index >= 0) && (index < 4))
+ {
+ pAdapter->StaCfg.DefaultKeyId = index;
+ }
+ else
+ /* Don't complain if only change the mode */
+ if(!erq->flags & IW_ENCODE_MODE)
+ {
+ return -EINVAL;
+ }
+ }
+
+done:
+ DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
+ DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
+ DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
+ DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
+ return 0;
+}
+
+int
+rt_ioctl_giwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *key)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ int kid;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ kid = erq->flags & IW_ENCODE_INDEX;
+ DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
+
+ if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
+ {
+ erq->length = 0;
+ erq->flags = IW_ENCODE_DISABLED;
+ }
+ else if ((kid > 0) && (kid <=4))
+ {
+ // copy wep key
+ erq->flags = kid ; /* NB: base 1 */
+ if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
+ erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
+ memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
+ //if ((kid == pAdapter->PortCfg.DefaultKeyId))
+ //erq->flags |= IW_ENCODE_ENABLED; /* XXX */
+ if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
+ erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
+ else
+ erq->flags |= IW_ENCODE_OPEN; /* XXX */
+
+ }
+ else if (kid == 0)
+ {
+ if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
+ erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
+ else
+ erq->flags |= IW_ENCODE_OPEN; /* XXX */
+ erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
+ memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
+ // copy default key ID
+ if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
+ erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
+ else
+ erq->flags |= IW_ENCODE_OPEN; /* XXX */
+ erq->flags = pAdapter->StaCfg.DefaultKeyId + 1; /* NB: base 1 */
+ erq->flags |= IW_ENCODE_ENABLED; /* XXX */
+ }
+
+ return 0;
+
+}
+
+static int
+rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
+ void *w, char *extra)
+{
+ VIRTUAL_ADAPTER *pVirtualAd = NULL;
+ PRTMP_ADAPTER pAdapter;
+ POS_COOKIE pObj;
+ char *this_char = extra;
+ char *value;
+ int Status=0;
+
+ if (dev->priv_flags == INT_MAIN)
+ {
+ pAdapter = dev->ml_priv;
+ }
+ else
+ {
+ pVirtualAd = dev->ml_priv;
+ pAdapter = pVirtualAd->RtmpDev->ml_priv;
+ }
+ pObj = (POS_COOKIE) pAdapter->OS_Cookie;
+
+ if (pAdapter == NULL)
+ {
+ /* if 1st open fail, pAd will be free;
+ So the net_dev->ml_priv will be NULL in 2rd open */
+ return -ENETDOWN;
+ }
+
+ {
+ pObj->ioctl_if_type = INT_MAIN;
+ pObj->ioctl_if = MAIN_MBSSID;
+ }
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (!*this_char)
+ return -EINVAL;
+
+ if ((value = rtstrchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value)
+ return -EINVAL;
+
+ // reject setting nothing besides ANY ssid(ssidLen=0)
+ if (!*value && (strcmp(this_char, "SSID") != 0))
+ return -EINVAL;
+
+ for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
+ {
+ if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
+ {
+ if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
+ { //FALSE:Set private failed then return Invalid argument
+ Status = -EINVAL;
+ }
+ break; //Exit for loop.
+ }
+ }
+
+ if(PRTMP_PRIVATE_SET_PROC->name == NULL)
+ { //Not found argument
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
+ }
+
+ return Status;
+}
+
+
+static int
+rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
+ struct iw_point *wrq, char *extra)
+{
+ INT Status = 0;
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+
+ if (extra == NULL)
+ {
+ wrq->length = 0;
+ return -EIO;
+ }
+
+ memset(extra, 0x00, IW_PRIV_SIZE_MASK);
+ sprintf(extra, "\n\n");
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->ate.TxDoneCount);
+ //sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->ate.TxDoneCount);
+ }
+ else
+#endif // RALINK_ATE //
+ {
+ sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
+ sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
+ }
+ sprintf(extra+strlen(extra), "Tx success after retry = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
+ sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
+ sprintf(extra+strlen(extra), "RTS Success Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
+ sprintf(extra+strlen(extra), "RTS Fail Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
+
+ sprintf(extra+strlen(extra), "Rx success = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
+ sprintf(extra+strlen(extra), "Rx with CRC = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
+ sprintf(extra+strlen(extra), "Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
+ sprintf(extra+strlen(extra), "Rx duplicate frame = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
+
+ sprintf(extra+strlen(extra), "False CCA (one second) = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ if (pAd->ate.RxAntennaSel == 0)
+ {
+ sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
+ sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta));
+ sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta));
+ }
+ else
+ {
+ sprintf(extra+strlen(extra), "RSSI = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
+ }
+ }
+ else
+#endif // RALINK_ATE //
+ {
+ sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
+ sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
+ sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
+ }
+#ifdef WPA_SUPPLICANT_SUPPORT
+ sprintf(extra+strlen(extra), "WpaSupplicantUP = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
+
+ return Status;
+}
+
+#ifdef DOT11_N_SUPPORT
+void getBaInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pOutBuf)
+{
+ INT i, j;
+ BA_ORI_ENTRY *pOriBAEntry;
+ BA_REC_ENTRY *pRecBAEntry;
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+ if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
+ || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
+ {
+ sprintf(pOutBuf, "%s\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
+ pOutBuf,
+ pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
+ pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
+
+ sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
+ for (j=0; j < NUM_OF_TID; j++)
+ {
+ if (pEntry->BARecWcidArray[j] != 0)
+ {
+ pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
+ sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", pOutBuf, j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
+ }
+ }
+ sprintf(pOutBuf, "%s\n", pOutBuf);
+
+ sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
+ for (j=0; j < NUM_OF_TID; j++)
+ {
+ if (pEntry->BAOriWcidArray[j] != 0)
+ {
+ pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
+ sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", pOutBuf, j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
+ }
+ }
+ sprintf(pOutBuf, "%s\n\n", pOutBuf);
+ }
+ if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
+ break;
+ }
+
+ return;
+}
+#endif // DOT11_N_SUPPORT //
+
+static int
+rt_private_show(struct net_device *dev, struct iw_request_info *info,
+ struct iw_point *wrq, char *extra)
+{
+ INT Status = 0;
+ VIRTUAL_ADAPTER *pVirtualAd = NULL;
+ PRTMP_ADAPTER pAd;
+ POS_COOKIE pObj;
+ u32 subcmd = wrq->flags;
+
+ if (dev->priv_flags == INT_MAIN)
+ pAd = dev->ml_priv;
+ else
+ {
+ pVirtualAd = dev->ml_priv;
+ pAd = pVirtualAd->RtmpDev->ml_priv;
+ }
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ if (pAd == NULL)
+ {
+ /* if 1st open fail, pAd will be free;
+ So the net_dev->ml_priv will be NULL in 2rd open */
+ return -ENETDOWN;
+ }
+
+ if (extra == NULL)
+ {
+ wrq->length = 0;
+ return -EIO;
+ }
+ memset(extra, 0x00, IW_PRIV_SIZE_MASK);
+
+ {
+ pObj->ioctl_if_type = INT_MAIN;
+ pObj->ioctl_if = MAIN_MBSSID;
+ }
+
+ switch(subcmd)
+ {
+
+ case SHOW_CONN_STATUS:
+ if (MONITOR_ON(pAd))
+ {
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
+ pAd->CommonCfg.RegTransmitSetting.field.BW)
+ sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
+ else
+#endif // DOT11_N_SUPPORT //
+ sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
+ }
+ else
+ {
+ if (pAd->IndicateMediaState == NdisMediaStateConnected)
+ {
+ if (INFRA_ON(pAd))
+ {
+ sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
+ pAd->CommonCfg.Ssid,
+ pAd->CommonCfg.Bssid[0],
+ pAd->CommonCfg.Bssid[1],
+ pAd->CommonCfg.Bssid[2],
+ pAd->CommonCfg.Bssid[3],
+ pAd->CommonCfg.Bssid[4],
+ pAd->CommonCfg.Bssid[5]);
+ DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
+ }
+ else if (ADHOC_ON(pAd))
+ sprintf(extra, "Connected\n");
+ }
+ else
+ {
+ sprintf(extra, "Disconnected\n");
+ DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
+ }
+ }
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+ case SHOW_DRVIER_VERION:
+ sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+#ifdef DOT11_N_SUPPORT
+ case SHOW_BA_INFO:
+ getBaInfo(pAd, extra);
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+#endif // DOT11_N_SUPPORT //
+ case SHOW_DESC_INFO:
+ {
+ Show_DescInfo_Proc(pAd, NULL);
+ wrq->length = 0; // 1: size of '\0'
+ }
+ break;
+ case RAIO_OFF:
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ {
+ sprintf(extra, "Scanning\n");
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+ }
+ pAd->StaCfg.bSwRadio = FALSE;
+ if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
+ {
+ pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
+ if (pAd->StaCfg.bRadio == FALSE)
+ {
+ MlmeRadioOff(pAd);
+ // Update extra information
+ pAd->ExtraInfo = SW_RADIO_OFF;
+ }
+ }
+ sprintf(extra, "Radio Off\n");
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+ case RAIO_ON:
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ {
+ sprintf(extra, "Scanning\n");
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+ }
+ pAd->StaCfg.bSwRadio = TRUE;
+ //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
+ {
+ pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
+ if (pAd->StaCfg.bRadio == TRUE)
+ {
+ MlmeRadioOn(pAd);
+ // Update extra information
+ pAd->ExtraInfo = EXTRA_INFO_CLEAR;
+ }
+ }
+ sprintf(extra, "Radio On\n");
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+
+
+#ifdef QOS_DLS_SUPPORT
+ case SHOW_DLS_ENTRY_INFO:
+ {
+ Set_DlsEntryInfo_Display_Proc(pAd, NULL);
+ wrq->length = 0; // 1: size of '\0'
+ }
+ break;
+#endif // QOS_DLS_SUPPORT //
+
+ case SHOW_CFG_VALUE:
+ {
+ Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
+ if (Status == 0)
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ }
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __FUNCTION__, subcmd));
+ break;
+ }
+
+ return Status;
+}
+
+#ifdef SIOCSIWMLME
+int rt_ioctl_siwmlme(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+ struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
+ MLME_QUEUE_ELEM MsgElem;
+ MLME_DISASSOC_REQ_STRUCT DisAssocReq;
+ MLME_DEAUTH_REQ_STRUCT DeAuthReq;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));
+
+ if (pMlme == NULL)
+ return -EINVAL;
+
+ switch(pMlme->cmd)
+ {
+#ifdef IW_MLME_DEAUTH
+ case IW_MLME_DEAUTH:
+ DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __FUNCTION__));
+ COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
+ DeAuthReq.Reason = pMlme->reason_code;
+ MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
+ NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
+ MlmeDeauthReqAction(pAd, &MsgElem);
+ if (INFRA_ON(pAd))
+ {
+ LinkDown(pAd, FALSE);
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ }
+ break;
+#endif // IW_MLME_DEAUTH //
+#ifdef IW_MLME_DISASSOC
+ case IW_MLME_DISASSOC:
+ DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __FUNCTION__));
+ COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
+ DisAssocReq.Reason = pMlme->reason_code;
+
+ MsgElem.Machine = ASSOC_STATE_MACHINE;
+ MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
+ MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
+ NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
+ MlmeDisassocReqAction(pAd, &MsgElem);
+ break;
+#endif // IW_MLME_DISASSOC //
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __FUNCTION__));
+ break;
+ }
+
+ return 0;
+}
+#endif // SIOCSIWMLME //
+
+#if WIRELESS_EXT > 17
+int rt_ioctl_siwauth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ struct iw_param *param = &wrqu->param;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ if (param->value == IW_AUTH_WPA_VERSION_WPA)
+ {
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
+ if (pAdapter->StaCfg.BssType == BSS_ADHOC)
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
+ }
+ else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_CIPHER_PAIRWISE:
+ if (param->value == IW_AUTH_CIPHER_NONE)
+ {
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
+ }
+ else if (param->value == IW_AUTH_CIPHER_WEP40 ||
+ param->value == IW_AUTH_CIPHER_WEP104)
+ {
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ pAdapter->StaCfg.IEEE8021X = FALSE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ }
+ else if (param->value == IW_AUTH_CIPHER_TKIP)
+ {
+ pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+ }
+ else if (param->value == IW_AUTH_CIPHER_CCMP)
+ {
+ pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_CIPHER_GROUP:
+ if (param->value == IW_AUTH_CIPHER_NONE)
+ {
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
+ }
+ else if (param->value == IW_AUTH_CIPHER_WEP40 ||
+ param->value == IW_AUTH_CIPHER_WEP104)
+ {
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
+ }
+ else if (param->value == IW_AUTH_CIPHER_TKIP)
+ {
+ pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
+ }
+ else if (param->value == IW_AUTH_CIPHER_CCMP)
+ {
+ pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_KEY_MGMT:
+ if (param->value == IW_AUTH_KEY_MGMT_802_1X)
+ {
+ if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
+ {
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ pAdapter->StaCfg.IEEE8021X = FALSE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ }
+ else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+ {
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ pAdapter->StaCfg.IEEE8021X = FALSE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ }
+#ifdef WPA_SUPPLICANT_SUPPORT
+ else
+ // WEP 1x
+ pAdapter->StaCfg.IEEE8021X = TRUE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ }
+ else if (param->value == 0)
+ {
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ break;
+ case IW_AUTH_PRIVACY_INVOKED:
+ /*if (param->value == 0)
+ {
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
+ }*/
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_DROP_UNENCRYPTED:
+ if (param->value != 0)
+ pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ else
+ {
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_80211_AUTH_ALG:
+ if (param->value & IW_AUTH_ALG_SHARED_KEY)
+ {
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+ }
+ else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
+ {
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+ }
+ else
+ return -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_WPA_ENABLED:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __FUNCTION__, param->value));
+ break;
+ default:
+ return -EOPNOTSUPP;
+}
+
+ return 0;
+}
+
+int rt_ioctl_giwauth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ struct iw_param *param = &wrqu->param;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_DROP_UNENCRYPTED:
+ param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
+ return 0;
+}
+
+void fnSetCipherKey(
+ IN PRTMP_ADAPTER pAdapter,
+ IN INT keyIdx,
+ IN UCHAR CipherAlg,
+ IN BOOLEAN bGTK,
+ IN struct iw_encode_ext *ext)
+{
+ NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
+ NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+ NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
+
+ // Update group key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAdapter,
+ BSS0,
+ keyIdx,
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
+ pAdapter->SharedKey[BSS0][keyIdx].Key,
+ pAdapter->SharedKey[BSS0][keyIdx].TxMic,
+ pAdapter->SharedKey[BSS0][keyIdx].RxMic);
+
+ if (bGTK)
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAdapter,
+ BSS0,
+ keyIdx,
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
+ NULL);
+ else
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAdapter,
+ BSS0,
+ keyIdx,
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
+ &pAdapter->MacTab.Content[BSSID_WCID]);
+}
+
+int rt_ioctl_siwencodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+ {
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int keyIdx, alg = ext->alg;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (encoding->flags & IW_ENCODE_DISABLED)
+ {
+ keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
+ // set BSSID wcid entry of the Pair-wise Key table as no-security mode
+ AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
+ AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
+ NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __FUNCTION__, encoding->flags));
+ }
+ else
+ {
+ // Get Key Index and convet to our own defined key index
+ keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
+ if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
+ return -EINVAL;
+
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+ {
+ pAdapter->StaCfg.DefaultKeyId = keyIdx;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __FUNCTION__, pAdapter->StaCfg.DefaultKeyId));
+ }
+
+ switch (alg) {
+ case IW_ENCODE_ALG_NONE:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __FUNCTION__));
+ break;
+ case IW_ENCODE_ALG_WEP:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __FUNCTION__, ext->key_len, keyIdx));
+ if (ext->key_len == MAX_WEP_KEY_SIZE)
+ {
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
+ }
+ else if (ext->key_len == MIN_WEP_KEY_SIZE)
+ {
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
+ }
+ else
+ return -EINVAL;
+
+ NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
+ NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
+ break;
+ case IW_ENCODE_ALG_TKIP:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __FUNCTION__, keyIdx, ext->key_len));
+ if (ext->key_len == 32)
+ {
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+ {
+ fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
+ {
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ }
+ }
+ else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+ {
+ fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
+
+ // set 802.1x port control
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ }
+ }
+ else
+ return -EINVAL;
+ break;
+ case IW_ENCODE_ALG_CCMP:
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+ {
+ fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ }
+ else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+ {
+ fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
+
+ // set 802.1x port control
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+int
+rt_ioctl_giwencodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+ PCHAR pKey = NULL;
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int idx, max_key_len;
+
+ DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
+
+ max_key_len = encoding->length - sizeof(*ext);
+ if (max_key_len < 0)
+ return -EINVAL;
+
+ idx = encoding->flags & IW_ENCODE_INDEX;
+ if (idx)
+ {
+ if (idx < 1 || idx > 4)
+ return -EINVAL;
+ idx--;
+
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
+ {
+ if (idx != pAd->StaCfg.DefaultKeyId)
+ {
+ ext->key_len = 0;
+ return 0;
+ }
+ }
+ }
+ else
+ idx = pAd->StaCfg.DefaultKeyId;
+
+ encoding->flags = idx + 1;
+ memset(ext, 0, sizeof(*ext));
+
+ ext->key_len = 0;
+ switch(pAd->StaCfg.WepStatus) {
+ case Ndis802_11WEPDisabled:
+ ext->alg = IW_ENCODE_ALG_NONE;
+ encoding->flags |= IW_ENCODE_DISABLED;
+ break;
+ case Ndis802_11WEPEnabled:
+ ext->alg = IW_ENCODE_ALG_WEP;
+ if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
+ return -E2BIG;
+ else
+ {
+ ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
+ pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
+ }
+ break;
+ case Ndis802_11Encryption2Enabled:
+ case Ndis802_11Encryption3Enabled:
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
+ ext->alg = IW_ENCODE_ALG_TKIP;
+ else
+ ext->alg = IW_ENCODE_ALG_CCMP;
+
+ if (max_key_len < 32)
+ return -E2BIG;
+ else
+ {
+ ext->key_len = 32;
+ pKey = &pAd->StaCfg.PMK[0];
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (ext->key_len && pKey)
+ {
+ encoding->flags |= IW_ENCODE_ENABLED;
+ memcpy(ext->key, pKey, ext->key_len);
+ }
+
+ return 0;
+}
+
+#ifdef SIOCSIWGENIE
+int rt_ioctl_siwgenie(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+
+ if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
+ (wrqu->data.length && extra == NULL))
+ return -EINVAL;
+
+ if (wrqu->data.length)
+ {
+ pAd->StaCfg.RSNIE_Len = wrqu->data.length;
+ NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
+ }
+ else
+ {
+ pAd->StaCfg.RSNIE_Len = 0;
+ NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
+ }
+
+ return 0;
+}
+#endif // SIOCSIWGENIE //
+
+int rt_ioctl_giwgenie(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+
+ if ((pAd->StaCfg.RSNIE_Len == 0) ||
+ (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
+ {
+ wrqu->data.length = 0;
+ return 0;
+ }
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifdef SIOCSIWGENIE
+ if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
+ {
+ if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
+ return -E2BIG;
+
+ wrqu->data.length = pAd->StaCfg.RSNIE_Len;
+ memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
+ }
+ else
+#endif // SIOCSIWGENIE //
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ {
+ UCHAR RSNIe = IE_WPA;
+
+ if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
+ return -E2BIG;
+ wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
+
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
+ RSNIe = IE_RSN;
+
+ extra[0] = (char)RSNIe;
+ extra[1] = pAd->StaCfg.RSNIE_Len;
+ memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
+ }
+
+ return 0;
+}
+
+int rt_ioctl_siwpmksa(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+ struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
+ INT CachedIdx = 0, idx = 0;
+
+ if (pPmksa == NULL)
+ return -EINVAL;
+
+ DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
+ switch(pPmksa->cmd)
+ {
+ case IW_PMKSA_FLUSH:
+ NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
+ DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
+ break;
+ case IW_PMKSA_REMOVE:
+ for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
+ {
+ // compare the BSSID
+ if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
+ {
+ NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
+ NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
+ for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
+ {
+ NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
+ NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
+ }
+ pAd->StaCfg.SavedPMKNum--;
+ break;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
+ break;
+ case IW_PMKSA_ADD:
+ for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
+ {
+ // compare the BSSID
+ if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
+ break;
+ }
+
+ // Found, replace it
+ if (CachedIdx < PMKID_NO)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
+ NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
+ NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
+ pAd->StaCfg.SavedPMKNum++;
+ }
+ // Not found, replace the last one
+ else
+ {
+ // Randomly replace one
+ CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
+ DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
+ NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
+ NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
+ break;
+ }
+
+ return 0;
+}
+#endif // #if WIRELESS_EXT > 17
+
+#ifdef DBG
+static int
+rt_private_ioctl_bbp(struct net_device *dev, struct iw_request_info *info,
+ struct iw_point *wrq, char *extra)
+ {
+ CHAR *this_char;
+ CHAR *value = NULL;
+ UCHAR regBBP = 0;
+// CHAR arg[255]={0};
+ UINT32 bbpId;
+ UINT32 bbpValue;
+ BOOLEAN bIsPrintAllBBP = FALSE;
+ INT Status = 0;
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+
+ memset(extra, 0x00, IW_PRIV_SIZE_MASK);
+
+ if (wrq->length > 1) //No parameters.
+ {
+ sprintf(extra, "\n");
+
+ //Parsing Read or Write
+ this_char = wrq->pointer;
+ DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s\n", this_char));
+ if (!*this_char)
+ goto next;
+
+ if ((value = rtstrchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value || !*value)
+ { //Read
+ DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s, value=%s\n", this_char, value));
+ if (sscanf(this_char, "%d", &(bbpId)) == 1)
+ {
+#ifndef RT30xx
+ if (bbpId <= 136)
+#endif // RT30xx //
+#ifdef RT30xx
+ if (bbpId <= 138) // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
+#endif // RT30xx //
+ {
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ }
+ else
+#endif // RALINK_ATE //
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ }
+ sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
+ }
+ else
+ {//Invalid parametes, so default printk all bbp
+ bIsPrintAllBBP = TRUE;
+ goto next;
+ }
+ }
+ else
+ { //Invalid parametes, so default printk all bbp
+ bIsPrintAllBBP = TRUE;
+ goto next;
+ }
+ }
+ else
+ { //Write
+ if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%x", &(bbpValue)) == 1))
+ {
+#ifndef RT30xx
+ if (bbpId <= 136)
+#endif // RT30xx //
+#ifdef RT30xx
+ if (bbpId <= 138) // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
+#endif // RT30xx //
+ {
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
+ //Read it back for showing
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ }
+ else
+#endif // RALINK_ATE //
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
+ //Read it back for showing
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ }
+ sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
+ }
+ else
+ {//Invalid parametes, so default printk all bbp
+ bIsPrintAllBBP = TRUE;
+ goto next;
+ }
+ }
+ else
+ { //Invalid parametes, so default printk all bbp
+ bIsPrintAllBBP = TRUE;
+ goto next;
+ }
+ }
+ }
+ else
+ bIsPrintAllBBP = TRUE;
+
+next:
+ if (bIsPrintAllBBP)
+ {
+ memset(extra, 0x00, IW_PRIV_SIZE_MASK);
+ sprintf(extra, "\n");
+#ifndef RT30xx
+ for (bbpId = 0; bbpId <= 136; bbpId++)
+#endif // RT30xx //
+#ifdef RT30xx
+ for (bbpId = 0; bbpId <= 138; bbpId++) // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
+#endif // RT30xx //
+ {
+ if (strlen(extra) >= (IW_PRIV_SIZE_MASK - 10))
+ break;
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ }
+ else
+#endif // RALINK_ATE //
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+/*
+ sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X ", bbpId, bbpId*2, regBBP);
+ if (bbpId%5 == 4)
+ sprintf(extra+strlen(extra), "\n");
+*/
+ sprintf(extra+strlen(extra), "%03d = %02X\n", bbpId, regBBP); // edit by johnli, change display format
+ }
+
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ DBGPRINT(RT_DEBUG_TRACE, ("wrq->length = %d\n", wrq->length));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==rt_private_ioctl_bbp\n\n"));
+
+ return Status;
+}
+#endif // DBG //
+
+int rt_ioctl_siwrate(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+ UINT32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
+ /* rate = -1 => auto rate
+ rate = X, fixed = 1 => (fixed rate X)
+ */
+ if (rate == -1)
+ {
+ //Auto Rate
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ pAd->StaCfg.bAutoTxRateSwitch = TRUE;
+ if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
+ (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
+ RTMPSetDesiredRates(pAd, -1);
+
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+ }
+ else
+ {
+ if (fixed)
+ {
+ pAd->StaCfg.bAutoTxRateSwitch = FALSE;
+ if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
+ (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
+ RTMPSetDesiredRates(pAd, rate);
+ else
+ {
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
+ }
+ else
+ {
+ // TODO: rate = X, fixed = 0 => (rates <= X)
+ return -EOPNOTSUPP;
+ }
+ }
+
+ return 0;
+}
+
+int rt_ioctl_giwrate(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+ int rate_index = 0, rate_count = 0;
+ HTTRANSMIT_SETTING ht_setting;
+ __s32 ralinkrate[] =
+ {2, 4, 11, 22, // CCK
+ 12, 18, 24, 36, 48, 72, 96, 108, // OFDM
+ 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
+ 39, 78, 117, 156, 234, 312, 351, 390, // 20MHz, 800ns GI, MCS: 16 ~ 23
+ 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
+ 81, 162, 243, 324, 486, 648, 729, 810, // 40MHz, 800ns GI, MCS: 16 ~ 23
+ 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
+ 43, 87, 130, 173, 260, 317, 390, 433, // 20MHz, 400ns GI, MCS: 16 ~ 23
+ 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
+ 90, 180, 270, 360, 540, 720, 810, 900}; // 40MHz, 400ns GI, MCS: 16 ~ 23
+
+ rate_count = sizeof(ralinkrate)/sizeof(__s32);
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
+ (INFRA_ON(pAd)) &&
+ ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
+ ht_setting.word = pAd->StaCfg.HTPhyMode.word;
+ else
+ ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
+
+#ifdef DOT11_N_SUPPORT
+ if (ht_setting.field.MODE >= MODE_HTMIX)
+ {
+// rate_index = 12 + ((UCHAR)ht_setting.field.BW *16) + ((UCHAR)ht_setting.field.ShortGI *32) + ((UCHAR)ht_setting.field.MCS);
+ rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ if (ht_setting.field.MODE == MODE_OFDM)
+ rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
+ else if (ht_setting.field.MODE == MODE_CCK)
+ rate_index = (UCHAR)(ht_setting.field.MCS);
+
+ if (rate_index < 0)
+ rate_index = 0;
+
+ if (rate_index > rate_count)
+ rate_index = rate_count;
+
+ wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
+ wrqu->bitrate.disabled = 0;
+
+ return 0;
+}
+
+static const iw_handler rt_handler[] =
+{
+ (iw_handler) NULL, /* SIOCSIWCOMMIT */
+ (iw_handler) rt_ioctl_giwname, /* SIOCGIWNAME */
+ (iw_handler) NULL, /* SIOCSIWNWID */
+ (iw_handler) NULL, /* SIOCGIWNWID */
+ (iw_handler) rt_ioctl_siwfreq, /* SIOCSIWFREQ */
+ (iw_handler) rt_ioctl_giwfreq, /* SIOCGIWFREQ */
+ (iw_handler) rt_ioctl_siwmode, /* SIOCSIWMODE */
+ (iw_handler) rt_ioctl_giwmode, /* SIOCGIWMODE */
+ (iw_handler) NULL, /* SIOCSIWSENS */
+ (iw_handler) NULL, /* SIOCGIWSENS */
+ (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
+ (iw_handler) rt_ioctl_giwrange, /* SIOCGIWRANGE */
+ (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
+ (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
+ (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
+ (iw_handler) rt28xx_get_wireless_stats /* kernel code */, /* SIOCGIWSTATS */
+ (iw_handler) NULL, /* SIOCSIWSPY */
+ (iw_handler) NULL, /* SIOCGIWSPY */
+ (iw_handler) NULL, /* SIOCSIWTHRSPY */
+ (iw_handler) NULL, /* SIOCGIWTHRSPY */
+ (iw_handler) rt_ioctl_siwap, /* SIOCSIWAP */
+ (iw_handler) rt_ioctl_giwap, /* SIOCGIWAP */
+#ifdef SIOCSIWMLME
+ (iw_handler) rt_ioctl_siwmlme, /* SIOCSIWMLME */
+#else
+ (iw_handler) NULL, /* SIOCSIWMLME */
+#endif // SIOCSIWMLME //
+ (iw_handler) rt_ioctl_iwaplist, /* SIOCGIWAPLIST */
+#ifdef SIOCGIWSCAN
+ (iw_handler) rt_ioctl_siwscan, /* SIOCSIWSCAN */
+ (iw_handler) rt_ioctl_giwscan, /* SIOCGIWSCAN */
+#else
+ (iw_handler) NULL, /* SIOCSIWSCAN */
+ (iw_handler) NULL, /* SIOCGIWSCAN */
+#endif /* SIOCGIWSCAN */
+ (iw_handler) rt_ioctl_siwessid, /* SIOCSIWESSID */
+ (iw_handler) rt_ioctl_giwessid, /* SIOCGIWESSID */
+ (iw_handler) rt_ioctl_siwnickn, /* SIOCSIWNICKN */
+ (iw_handler) rt_ioctl_giwnickn, /* SIOCGIWNICKN */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) rt_ioctl_siwrate, /* SIOCSIWRATE */
+ (iw_handler) rt_ioctl_giwrate, /* SIOCGIWRATE */
+ (iw_handler) rt_ioctl_siwrts, /* SIOCSIWRTS */
+ (iw_handler) rt_ioctl_giwrts, /* SIOCGIWRTS */
+ (iw_handler) rt_ioctl_siwfrag, /* SIOCSIWFRAG */
+ (iw_handler) rt_ioctl_giwfrag, /* SIOCGIWFRAG */
+ (iw_handler) NULL, /* SIOCSIWTXPOW */
+ (iw_handler) NULL, /* SIOCGIWTXPOW */
+ (iw_handler) NULL, /* SIOCSIWRETRY */
+ (iw_handler) NULL, /* SIOCGIWRETRY */
+ (iw_handler) rt_ioctl_siwencode, /* SIOCSIWENCODE */
+ (iw_handler) rt_ioctl_giwencode, /* SIOCGIWENCODE */
+ (iw_handler) NULL, /* SIOCSIWPOWER */
+ (iw_handler) NULL, /* SIOCGIWPOWER */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+#if WIRELESS_EXT > 17
+ (iw_handler) rt_ioctl_siwgenie, /* SIOCSIWGENIE */
+ (iw_handler) rt_ioctl_giwgenie, /* SIOCGIWGENIE */
+ (iw_handler) rt_ioctl_siwauth, /* SIOCSIWAUTH */
+ (iw_handler) rt_ioctl_giwauth, /* SIOCGIWAUTH */
+ (iw_handler) rt_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
+ (iw_handler) rt_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
+ (iw_handler) rt_ioctl_siwpmksa, /* SIOCSIWPMKSA */
+#endif
+};
+
+static const iw_handler rt_priv_handlers[] = {
+ (iw_handler) NULL, /* + 0x00 */
+ (iw_handler) NULL, /* + 0x01 */
+#ifndef CONFIG_AP_SUPPORT
+ (iw_handler) rt_ioctl_setparam, /* + 0x02 */
+#else
+ (iw_handler) NULL, /* + 0x02 */
+#endif // CONFIG_AP_SUPPORT //
+#ifdef DBG
+ (iw_handler) rt_private_ioctl_bbp, /* + 0x03 */
+#else
+ (iw_handler) NULL, /* + 0x03 */
+#endif
+ (iw_handler) NULL, /* + 0x04 */
+ (iw_handler) NULL, /* + 0x05 */
+ (iw_handler) NULL, /* + 0x06 */
+ (iw_handler) NULL, /* + 0x07 */
+ (iw_handler) NULL, /* + 0x08 */
+ (iw_handler) rt_private_get_statistics, /* + 0x09 */
+ (iw_handler) NULL, /* + 0x0A */
+ (iw_handler) NULL, /* + 0x0B */
+ (iw_handler) NULL, /* + 0x0C */
+ (iw_handler) NULL, /* + 0x0D */
+ (iw_handler) NULL, /* + 0x0E */
+ (iw_handler) NULL, /* + 0x0F */
+ (iw_handler) NULL, /* + 0x10 */
+ (iw_handler) rt_private_show, /* + 0x11 */
+ (iw_handler) NULL, /* + 0x12 */
+ (iw_handler) NULL, /* + 0x13 */
+ (iw_handler) NULL, /* + 0x15 */
+ (iw_handler) NULL, /* + 0x17 */
+ (iw_handler) NULL, /* + 0x18 */
+};
+
+const struct iw_handler_def rt28xx_iw_handler_def =
+{
+#define N(a) (sizeof (a) / sizeof (a[0]))
+ .standard = (iw_handler *) rt_handler,
+ .num_standard = sizeof(rt_handler) / sizeof(iw_handler),
+ .private = (iw_handler *) rt_priv_handlers,
+ .num_private = N(rt_priv_handlers),
+ .private_args = (struct iw_priv_args *) privtab,
+ .num_private_args = N(privtab),
+#if IW_HANDLER_VERSION >= 7
+ .get_wireless_stats = rt28xx_get_wireless_stats,
+#endif
+};
+
+INT RTMPSetInformation(
+ IN PRTMP_ADAPTER pAdapter,
+ IN OUT struct ifreq *rq,
+ IN INT cmd)
+{
+ struct iwreq *wrq = (struct iwreq *) rq;
+ NDIS_802_11_SSID Ssid;
+ NDIS_802_11_MAC_ADDRESS Bssid;
+ RT_802_11_PHY_MODE PhyMode;
+ RT_802_11_STA_CONFIG StaConfig;
+ NDIS_802_11_RATES aryRates;
+ RT_802_11_PREAMBLE Preamble;
+ NDIS_802_11_WEP_STATUS WepStatus;
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeMax;
+ NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
+ NDIS_802_11_RTS_THRESHOLD RtsThresh;
+ NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
+ NDIS_802_11_POWER_MODE PowerMode;
+ PNDIS_802_11_KEY pKey = NULL;
+ PNDIS_802_11_WEP pWepKey =NULL;
+ PNDIS_802_11_REMOVE_KEY pRemoveKey = NULL;
+ NDIS_802_11_CONFIGURATION Config, *pConfig = NULL;
+ NDIS_802_11_NETWORK_TYPE NetType;
+ ULONG Now;
+ UINT KeyIdx = 0;
+ INT Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G;
+ ULONG PowerTemp;
+ BOOLEAN RadioState;
+ BOOLEAN StateMachineTouched = FALSE;
+#ifdef DOT11_N_SUPPORT
+ OID_SET_HT_PHYMODE HT_PhyMode; //11n ,kathy
+#endif // DOT11_N_SUPPORT //
+#ifdef WPA_SUPPLICANT_SUPPORT
+ PNDIS_802_11_PMKID pPmkId = NULL;
+ BOOLEAN IEEE8021xState = FALSE;
+ BOOLEAN IEEE8021x_required_keys = FALSE;
+ UCHAR wpa_supplicant_enable = 0;
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef SNMP_SUPPORT
+ TX_RTY_CFG_STRUC tx_rty_cfg;
+ ULONG ShortRetryLimit, LongRetryLimit;
+ UCHAR ctmp;
+#endif // SNMP_SUPPORT //
+
+
+#ifdef DOT11_N_SUPPORT
+ MaxPhyMode = PHY_11N_5G;
+#endif // DOT11_N_SUPPORT //
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(), 0x%08x\n", cmd&0x7FFF));
+ switch(cmd & 0x7FFF) {
+ case RT_OID_802_11_COUNTRY_REGION:
+ if (wrq->u.data.length < sizeof(UCHAR))
+ Status = -EINVAL;
+ // Only avaliable when EEPROM not programming
+ else if (!(pAdapter->CommonCfg.CountryRegion & 0x80) && !(pAdapter->CommonCfg.CountryRegionForABand & 0x80))
+ {
+ ULONG Country;
+ UCHAR TmpPhy;
+
+ Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
+ pAdapter->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
+ pAdapter->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
+ TmpPhy = pAdapter->CommonCfg.PhyMode;
+ pAdapter->CommonCfg.PhyMode = 0xff;
+ // Build all corresponding channel information
+ RTMPSetPhyMode(pAdapter, TmpPhy);
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAdapter);
+#endif // DOT11_N_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d B/G:%d)\n", pAdapter->CommonCfg.CountryRegionForABand,
+ pAdapter->CommonCfg.CountryRegion));
+ }
+ break;
+ case OID_802_11_BSSID_LIST_SCAN:
+ #ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+ break;
+ }
+#endif // RALINK_ATE //
+ Now = jiffies;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAdapter->RalinkCounters.LastOneSecTotalTxCount));
+
+ if (MONITOR_ON(pAdapter))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
+ break;
+ }
+
+ //Benson add 20080527, when radio off, sta don't need to scan
+ if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
+ break;
+
+ if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
+ pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+ }
+
+ if (pAdapter->RalinkCounters.LastOneSecTotalTxCount > 100)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
+ Status = NDIS_STATUS_SUCCESS;
+ pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
+ break;
+ }
+
+ if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
+ ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+ (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+ (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
+ (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
+ Status = NDIS_STATUS_SUCCESS;
+ pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
+ break;
+ }
+
+
+ if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ {
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+ }
+
+ // tell CNTL state machine to call NdisMSetInformationComplete() after completing
+ // this request, because this request is initiated by NDIS.
+ pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
+ // Reset allowed scan retries
+ pAdapter->StaCfg.ScanCnt = 0;
+ pAdapter->StaCfg.LastScanTime = Now;
+
+ pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+ RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_BSSID_LIST_SCAN,
+ 0,
+ NULL);
+
+ Status = NDIS_STATUS_SUCCESS;
+ StateMachineTouched = TRUE;
+ break;
+ case OID_802_11_SSID:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_SSID))
+ Status = -EINVAL;
+ else
+ {
+ PCHAR pSsidString = NULL;
+ Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
+ if (Ssid.SsidLength > MAX_LEN_OF_SSID)
+ Status = -EINVAL;
+ else
+ {
+ if (Ssid.SsidLength == 0)
+ {
+ Set_SSID_Proc(pAdapter, "");
+ }
+ else
+ {
+ pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
+ if (pSsidString)
+ {
+ NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
+ NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
+ Set_SSID_Proc(pAdapter, pSsidString);
+ kfree(pSsidString);
+ }
+ else
+ Status = -ENOMEM;
+ }
+ }
+ }
+ break;
+ case OID_802_11_BSSID:
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+ break;
+ }
+#endif // RALINK_ATE //
+ if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length);
+
+ // tell CNTL state machine to call NdisMSetInformationComplete() after completing
+ // this request, because this request is initiated by NDIS.
+ pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
+
+ // Prevent to connect AP again in STAMlmePeriodicExec
+ pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
+
+ // Reset allowed scan retries
+ pAdapter->StaCfg.ScanCnt = 0;
+
+ if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ {
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+ }
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_BSSID,
+ sizeof(NDIS_802_11_MAC_ADDRESS),
+ (VOID *)&Bssid);
+ Status = NDIS_STATUS_SUCCESS;
+ StateMachineTouched = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
+ Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
+ }
+ break;
+ case RT_OID_802_11_RADIO:
+ if (wrq->u.data.length != sizeof(BOOLEAN))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState));
+ if (pAdapter->StaCfg.bSwRadio != RadioState)
+ {
+ pAdapter->StaCfg.bSwRadio = RadioState;
+ if (pAdapter->StaCfg.bRadio != (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio))
+ {
+ pAdapter->StaCfg.bRadio = (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio);
+ if (pAdapter->StaCfg.bRadio == TRUE)
+ {
+ MlmeRadioOn(pAdapter);
+ // Update extra information
+ pAdapter->ExtraInfo = EXTRA_INFO_CLEAR;
+ }
+ else
+ {
+ MlmeRadioOff(pAdapter);
+ // Update extra information
+ pAdapter->ExtraInfo = SW_RADIO_OFF;
+ }
+ }
+ }
+ }
+ break;
+ case RT_OID_802_11_PHY_MODE:
+ if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length);
+ if (PhyMode <= MaxPhyMode)
+ {
+ RTMPSetPhyMode(pAdapter, PhyMode);
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAdapter);
+#endif // DOT11_N_SUPPORT //
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode));
+ }
+ break;
+ case RT_OID_802_11_STA_CONFIG:
+ if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
+ pAdapter->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
+ pAdapter->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
+ pAdapter->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
+ if ((pAdapter->CommonCfg.PhyMode != StaConfig.AdhocMode) &&
+ (StaConfig.AdhocMode <= MaxPhyMode))
+ {
+ // allow dynamic change of "USE OFDM rate or not" in ADHOC mode
+ // if setting changed, need to reset current TX rate as well as BEACON frame format
+ pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
+ if (pAdapter->StaCfg.BssType == BSS_ADHOC)
+ {
+ RTMPSetPhyMode(pAdapter, PhyMode);
+ MlmeUpdateTxRates(pAdapter, FALSE, 0);
+ MakeIbssBeacon(pAdapter); // re-build BEACON frame
+ AsicEnableIbssSync(pAdapter); // copy to on-chip memory
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
+ pAdapter->CommonCfg.bEnableTxBurst,
+ pAdapter->CommonCfg.UseBGProtection,
+ pAdapter->CommonCfg.bUseShortSlotTime));
+ }
+ break;
+ case OID_802_11_DESIRED_RATES:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_RATES))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length);
+ NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
+ NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
+ pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
+ pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
+ pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
+ pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
+ // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
+ MlmeUpdateTxRates(pAdapter, FALSE, 0);
+ }
+ break;
+ case RT_OID_802_11_PREAMBLE:
+ if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length);
+ if (Preamble == Rt802_11PreambleShort)
+ {
+ pAdapter->CommonCfg.TxPreamble = Preamble;
+ MlmeSetTxPreamble(pAdapter, Rt802_11PreambleShort);
+ }
+ else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto))
+ {
+ // if user wants AUTO, initialize to LONG here, then change according to AP's
+ // capability upon association.
+ pAdapter->CommonCfg.TxPreamble = Preamble;
+ MlmeSetTxPreamble(pAdapter, Rt802_11PreambleLong);
+ }
+ else
+ {
+ Status = -EINVAL;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble));
+ }
+ break;
+ case OID_802_11_WEP_STATUS:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length);
+ // Since TKIP, AES, WEP are all supported. It should not have any invalid setting
+ if (WepStatus <= Ndis802_11Encryption3KeyAbsent)
+ {
+ if (pAdapter->StaCfg.WepStatus != WepStatus)
+ {
+ // Config has changed
+ pAdapter->bConfigChanged = TRUE;
+ }
+ pAdapter->StaCfg.WepStatus = WepStatus;
+ pAdapter->StaCfg.OrigWepStatus = WepStatus;
+ pAdapter->StaCfg.PairCipher = WepStatus;
+ pAdapter->StaCfg.GroupCipher = WepStatus;
+ }
+ else
+ {
+ Status = -EINVAL;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
+ }
+ break;
+ case OID_802_11_AUTHENTICATION_MODE:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length);
+ if (AuthMode > Ndis802_11AuthModeMax)
+ {
+ Status = -EINVAL;
+ break;
+ }
+ else
+ {
+ if (pAdapter->StaCfg.AuthMode != AuthMode)
+ {
+ // Config has changed
+ pAdapter->bConfigChanged = TRUE;
+ }
+ pAdapter->StaCfg.AuthMode = AuthMode;
+ }
+ pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAdapter->StaCfg.AuthMode));
+ }
+ break;
+ case OID_802_11_INFRASTRUCTURE_MODE:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length);
+
+ if (BssType == Ndis802_11IBSS)
+ Set_NetworkType_Proc(pAdapter, "Adhoc");
+ else if (BssType == Ndis802_11Infrastructure)
+ Set_NetworkType_Proc(pAdapter, "Infra");
+ else if (BssType == Ndis802_11Monitor)
+ Set_NetworkType_Proc(pAdapter, "Monitor");
+ else
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n"));
+ }
+ }
+ break;
+ case OID_802_11_REMOVE_WEP:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n"));
+ if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX))
+ {
+ Status = -EINVAL;
+ }
+ else
+ {
+ KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer;
+
+ if (KeyIdx & 0x80000000)
+ {
+ // Should never set default bit when remove key
+ Status = -EINVAL;
+ }
+ else
+ {
+ KeyIdx = KeyIdx & 0x0fffffff;
+ if (KeyIdx >= 4){
+ Status = -EINVAL;
+ }
+ else
+ {
+ pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
+ pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
+ AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
+ }
+ }
+ }
+ break;
+ case RT_OID_802_11_RESET_COUNTERS:
+ NdisZeroMemory(&pAdapter->WlanCounters, sizeof(COUNTER_802_11));
+ NdisZeroMemory(&pAdapter->Counters8023, sizeof(COUNTER_802_3));
+ NdisZeroMemory(&pAdapter->RalinkCounters, sizeof(COUNTER_RALINK));
+ pAdapter->Counters8023.RxNoBuffer = 0;
+ pAdapter->Counters8023.GoodReceives = 0;
+ pAdapter->Counters8023.RxNoBuffer = 0;
+#ifdef RT2870
+ pAdapter->BulkOutComplete = 0;
+ pAdapter->BulkOutCompleteOther= 0;
+ pAdapter->BulkOutCompleteCancel = 0;
+ pAdapter->BulkOutReq = 0;
+ pAdapter->BulkInReq= 0;
+ pAdapter->BulkInComplete = 0;
+ pAdapter->BulkInCompleteFail = 0;
+#endif // RT2870 //
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n"));
+ break;
+ case OID_802_11_RTS_THRESHOLD:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length);
+ if (RtsThresh > MAX_RTS_THRESHOLD)
+ Status = -EINVAL;
+ else
+ pAdapter->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh));
+ break;
+ case OID_802_11_FRAGMENTATION_THRESHOLD:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length);
+ pAdapter->CommonCfg.bUseZeroToDisableFragment = FALSE;
+ if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
+ {
+ if (FragThresh == 0)
+ {
+ pAdapter->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
+ pAdapter->CommonCfg.bUseZeroToDisableFragment = TRUE;
+ }
+ else
+ Status = -EINVAL;
+ }
+ else
+ pAdapter->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh));
+ break;
+ case OID_802_11_POWER_MODE:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length);
+ if (PowerMode == Ndis802_11PowerModeCAM)
+ Set_PSMode_Proc(pAdapter, "CAM");
+ else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
+ Set_PSMode_Proc(pAdapter, "Max_PSP");
+ else if (PowerMode == Ndis802_11PowerModeFast_PSP)
+ Set_PSMode_Proc(pAdapter, "Fast_PSP");
+ else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
+ Set_PSMode_Proc(pAdapter, "Legacy_PSP");
+ else
+ Status = -EINVAL;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode));
+ break;
+ case RT_OID_802_11_TX_POWER_LEVEL_1:
+ if (wrq->u.data.length < sizeof(ULONG))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length);
+ if (PowerTemp > 100)
+ PowerTemp = 0xffffffff; // AUTO
+ pAdapter->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
+ pAdapter->CommonCfg.TxPowerPercentage = pAdapter->CommonCfg.TxPowerDefault;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
+ }
+ break;
+ case OID_802_11_NETWORK_TYPE_IN_USE:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length);
+
+ if (NetType == Ndis802_11DS)
+ RTMPSetPhyMode(pAdapter, PHY_11B);
+ else if (NetType == Ndis802_11OFDM24)
+ RTMPSetPhyMode(pAdapter, PHY_11BG_MIXED);
+ else if (NetType == Ndis802_11OFDM5)
+ RTMPSetPhyMode(pAdapter, PHY_11A);
+ else
+ Status = -EINVAL;
+#ifdef DOT11_N_SUPPORT
+ if (Status == NDIS_STATUS_SUCCESS)
+ SetCommonHT(pAdapter);
+#endif // DOT11_N_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType));
+ }
+ break;
+ // For WPA PSK PMK key
+ case RT_OID_802_11_ADD_WPA:
+ pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+ if(pKey == NULL)
+ {
+ Status = -ENOMEM;
+ break;
+ }
+
+ Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
+ if (pKey->Length != wrq->u.data.length)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n"));
+ }
+ else
+ {
+ if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
+ (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+ (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) )
+ {
+ Status = -EOPNOTSUPP;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n"));
+ }
+ else if ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+ (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) ) // Only for WPA PSK mode
+ {
+ NdisMoveMemory(pAdapter->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
+ // Use RaConfig as PSK agent.
+ // Start STA supplicant state machine
+ if (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
+ pAdapter->StaCfg.WpaState = SS_START;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
+ }
+ else
+ {
+ pAdapter->StaCfg.WpaState = SS_NOTUSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
+ }
+ }
+ kfree(pKey);
+ break;
+ case OID_802_11_REMOVE_KEY:
+ pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+ if(pRemoveKey == NULL)
+ {
+ Status = -ENOMEM;
+ break;
+ }
+
+ Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length);
+ if (pRemoveKey->Length != wrq->u.data.length)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n"));
+ }
+ else
+ {
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ RTMPWPARemoveKeyProc(pAdapter, pRemoveKey);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
+ }
+ else
+ {
+ KeyIdx = pRemoveKey->KeyIndex;
+
+ if (KeyIdx & 0x80000000)
+ {
+ // Should never set default bit when remove key
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n"));
+ }
+ else
+ {
+ KeyIdx = KeyIdx & 0x0fffffff;
+ if (KeyIdx > 3)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx));
+ }
+ else
+ {
+ pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
+ pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
+ AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
+ }
+ }
+ }
+ }
+ kfree(pRemoveKey);
+ break;
+ // New for WPA
+ case OID_802_11_ADD_KEY:
+ pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+ if(pKey == NULL)
+ {
+ Status = -ENOMEM;
+ break;
+ }
+ Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
+ if (pKey->Length != wrq->u.data.length)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
+ }
+ else
+ {
+ RTMPAddKey(pAdapter, pKey);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
+ }
+ kfree(pKey);
+ break;
+ case OID_802_11_CONFIGURATION:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&Config, wrq->u.data.pointer, wrq->u.data.length);
+ pConfig = &Config;
+
+ if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400))
+ pAdapter->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
+
+ pAdapter->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
+ MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAdapter->CommonCfg.Channel);
+ //
+ // Save the channel on MlmeAux for CntlOidRTBssidProc used.
+ //
+ pAdapter->MlmeAux.Channel = pAdapter->CommonCfg.Channel;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
+ pConfig->BeaconPeriod, pConfig->ATIMWindow, pAdapter->CommonCfg.Channel));
+ // Config has changed
+ pAdapter->bConfigChanged = TRUE;
+ }
+ break;
+#ifdef DOT11_N_SUPPORT
+ case RT_OID_802_11_SET_HT_PHYMODE:
+ if (wrq->u.data.length != sizeof(OID_SET_HT_PHYMODE))
+ Status = -EINVAL;
+ else
+ {
+ POID_SET_HT_PHYMODE pHTPhyMode = &HT_PhyMode;
+
+ Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode (PhyMode = %d,TransmitNo = %d, HtMode = %d, ExtOffset = %d , MCS = %d, BW = %d, STBC = %d, SHORTGI = %d) \n",
+ pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset,
+ pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
+ if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ RTMPSetHT(pAdapter, pHTPhyMode);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
+ pAdapter->StaCfg.HTPhyMode.field.MCS, pAdapter->StaCfg.HTPhyMode.field.BW, pAdapter->StaCfg.HTPhyMode.field.ShortGI,
+ pAdapter->StaCfg.HTPhyMode.field.STBC));
+ break;
+#endif // DOT11_N_SUPPORT //
+ case RT_OID_802_11_SET_APSD_SETTING:
+ if (wrq->u.data.length != sizeof(ULONG))
+ Status = -EINVAL;
+ else
+ {
+ ULONG apsd ;
+ Status = copy_from_user(&apsd, wrq->u.data.pointer, wrq->u.data.length);
+
+ /*-------------------------------------------------------------------
+ |B31~B7 | B6~B5 | B4 | B3 | B2 | B1 | B0 |
+ ---------------------------------------------------------------------
+ | Rsvd | Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD Capable |
+ ---------------------------------------------------------------------*/
+ pAdapter->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE : FALSE;
+ pAdapter->CommonCfg.bAPSDAC_BE = ((apsd & 0x00000002) >> 1) ? TRUE : FALSE;
+ pAdapter->CommonCfg.bAPSDAC_BK = ((apsd & 0x00000004) >> 2) ? TRUE : FALSE;
+ pAdapter->CommonCfg.bAPSDAC_VI = ((apsd & 0x00000008) >> 3) ? TRUE : FALSE;
+ pAdapter->CommonCfg.bAPSDAC_VO = ((apsd & 0x00000010) >> 4) ? TRUE : FALSE;
+ pAdapter->CommonCfg.MaxSPLength = (UCHAR)((apsd & 0x00000060) >> 5);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_SETTING (apsd=0x%lx, APSDCap=%d, [BE,BK,VI,VO]=[%d/%d/%d/%d], MaxSPLen=%d)\n", apsd, pAdapter->CommonCfg.bAPSDCapable,
+ pAdapter->CommonCfg.bAPSDAC_BE, pAdapter->CommonCfg.bAPSDAC_BK, pAdapter->CommonCfg.bAPSDAC_VI, pAdapter->CommonCfg.bAPSDAC_VO, pAdapter->CommonCfg.MaxSPLength));
+ }
+ break;
+
+ case RT_OID_802_11_SET_APSD_PSM:
+ if (wrq->u.data.length != sizeof(ULONG))
+ Status = -EINVAL;
+ else
+ {
+ // Driver needs to notify AP when PSM changes
+ Status = copy_from_user(&pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
+ if (pAdapter->CommonCfg.bAPSDForcePowerSave != pAdapter->StaCfg.Psm)
+ {
+ MlmeSetPsmBit(pAdapter, pAdapter->CommonCfg.bAPSDForcePowerSave);
+ RTMPSendNullFrame(pAdapter, pAdapter->CommonCfg.TxRate, TRUE);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
+ }
+ break;
+#ifdef QOS_DLS_SUPPORT
+ case RT_OID_802_11_SET_DLS:
+ if (wrq->u.data.length != sizeof(ULONG))
+ Status = -EINVAL;
+ else
+ {
+ BOOLEAN oldvalue = pAdapter->CommonCfg.bDLSCapable;
+ Status = copy_from_user(&pAdapter->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length);
+ if (oldvalue && !pAdapter->CommonCfg.bDLSCapable)
+ {
+ int i;
+ // tear down local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+
+ // tear down peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAdapter->CommonCfg.bDLSCapable));
+ }
+ break;
+
+ case RT_OID_802_11_SET_DLS_PARAM:
+ if (wrq->u.data.length != sizeof(RT_802_11_DLS_UI))
+ Status = -EINVAL;
+ else
+ {
+ RT_802_11_DLS Dls;
+
+ NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
+ RTMPMoveMemory(&Dls, wrq->u.data.pointer, sizeof(RT_802_11_DLS_UI));
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ RT_OID_802_11_SET_DLS_PARAM,
+ sizeof(RT_802_11_DLS),
+ &Dls);
+ DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS_PARAM \n"));
+ }
+ break;
+#endif // QOS_DLS_SUPPORT //
+ case RT_OID_802_11_SET_WMM:
+ if (wrq->u.data.length != sizeof(BOOLEAN))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&pAdapter->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d) \n", pAdapter->CommonCfg.bWmmCapable));
+ }
+ break;
+
+ case OID_802_11_DISASSOCIATE:
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+ break;
+ }
+#endif // RALINK_ATE //
+ //
+ // Set NdisRadioStateOff to TRUE, instead of called MlmeRadioOff.
+ // Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be 0
+ // when query OID_802_11_BSSID_LIST.
+ //
+ // TRUE: NumberOfItems will set to 0.
+ // FALSE: NumberOfItems no change.
+ //
+ pAdapter->CommonCfg.NdisRadioStateOff = TRUE;
+ // Set to immediately send the media disconnect event
+ pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE \n"));
+
+ if (INFRA_ON(pAdapter))
+ {
+ if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ {
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+ }
+
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_DISASSOCIATE,
+ 0,
+ NULL);
+
+ StateMachineTouched = TRUE;
+ }
+ break;
+
+#ifdef DOT11_N_SUPPORT
+ case RT_OID_802_11_SET_IMME_BA_CAP:
+ if (wrq->u.data.length != sizeof(OID_BACAP_STRUC))
+ Status = -EINVAL;
+ else
+ {
+ OID_BACAP_STRUC Orde ;
+ Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length);
+ if (Orde.Policy > BA_NOTUSE)
+ {
+ Status = NDIS_STATUS_INVALID_DATA;
+ }
+ else if (Orde.Policy == BA_NOTUSE)
+ {
+ pAdapter->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
+ pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
+ pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
+ pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
+ pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
+ pAdapter->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
+ pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
+ // UPdata to HT IE
+ pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
+ pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
+ pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
+ }
+ else
+ {
+ pAdapter->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
+ pAdapter->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
+ pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
+ pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
+ pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
+ pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
+ pAdapter->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
+ pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
+
+ // UPdata to HT IE
+ pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
+ pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
+ pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
+
+ if (pAdapter->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
+ pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
+
+ }
+
+ pAdapter->CommonCfg.REGBACapability.word = pAdapter->CommonCfg.BACapability.word;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAdapter->CommonCfg.BACapability.field.Policy,
+ pAdapter->CommonCfg.BACapability.field.RxBAWinLimit,pAdapter->CommonCfg.BACapability.field.TxBAWinLimit, pAdapter->CommonCfg.BACapability.field.AutoBA));
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAdapter->CommonCfg.DesiredHtPhy.MimoPs, pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable,
+ pAdapter->CommonCfg.DesiredHtPhy.AmsduSize, pAdapter->CommonCfg.DesiredHtPhy.MpduDensity));
+ }
+
+ break;
+ case RT_OID_802_11_ADD_IMME_BA:
+ DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n"));
+ if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
+ Status = -EINVAL;
+ else
+ {
+ UCHAR index;
+ OID_ADD_BA_ENTRY BA;
+ MAC_TABLE_ENTRY *pEntry;
+
+ Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length);
+ if (BA.TID > 15)
+ {
+ Status = NDIS_STATUS_INVALID_DATA;
+ break;
+ }
+ else
+ {
+ //BATableInsertEntry
+ //As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID.
+ index = BA.TID;
+ // in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too
+ pEntry = MacTableLookup(pAdapter, BA.MACAddr);
+ if (!pEntry)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5]));
+ break;
+ }
+ if (BA.IsRecipient == FALSE)
+ {
+ if (pEntry->bIAmBadAtheros == TRUE)
+ pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
+
+ BAOriSessionSetUp(pAdapter, pEntry, index, 0, 100, TRUE);
+ }
+ else
+ {
+ //BATableInsertEntry(pAdapter, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n",
+ BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2]
+ , BA.MACAddr[4], BA.MACAddr[5]));
+ }
+ }
+ break;
+
+ case RT_OID_802_11_TEAR_IMME_BA:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n"));
+ if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
+ Status = -EINVAL;
+ else
+ {
+ POID_ADD_BA_ENTRY pBA;
+ MAC_TABLE_ENTRY *pEntry;
+
+ pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+
+ if (pBA == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n"));
+ Status = NDIS_STATUS_FAILURE;
+ }
+ else
+ {
+ Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid));
+
+ if (!pBA->bAllTid && (pBA->TID > NUM_OF_TID))
+ {
+ Status = NDIS_STATUS_INVALID_DATA;
+ break;
+ }
+
+ if (pBA->IsRecipient == FALSE)
+ {
+ pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
+ DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
+ if (pEntry)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
+ BAOriSessionTearDown(pAdapter, pEntry->Aid, pBA->TID, FALSE, TRUE);
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
+ }
+ else
+ {
+ pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
+ if (pEntry)
+ {
+ BARecSessionTearDown( pAdapter, (UCHAR)pEntry->Aid, pBA->TID, TRUE);
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
+ }
+ kfree(pBA);
+ }
+ }
+ break;
+#endif // DOT11_N_SUPPORT //
+
+ // For WPA_SUPPLICANT to set static wep key
+ case OID_802_11_ADD_WEP:
+ pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+
+ if(pWepKey == NULL)
+ {
+ Status = -ENOMEM;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n"));
+ break;
+ }
+ Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length);
+ if (Status)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n"));
+ }
+ else
+ {
+ KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
+ // KeyIdx must be 0 ~ 3
+ if (KeyIdx > 4)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n"));
+ }
+ else
+ {
+ UCHAR CipherAlg = 0;
+ PUCHAR Key;
+
+ // set key material and key length
+ NdisZeroMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, 16);
+ pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
+ NdisMoveMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
+
+ switch(pWepKey->KeyLength)
+ {
+ case 5:
+ CipherAlg = CIPHER_WEP64;
+ break;
+ case 13:
+ CipherAlg = CIPHER_WEP128;
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n"));
+ Status = -EINVAL;
+ break;
+ }
+ pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
+
+ // Default key for tx (shared key)
+ if (pWepKey->KeyIndex & 0x80000000)
+ {
+#ifdef WPA_SUPPLICANT_SUPPORT
+ // set key material and key length
+ NdisZeroMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
+ pAdapter->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
+ NdisMoveMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
+ pAdapter->StaCfg.DesireSharedKeyId = KeyIdx;
+ pAdapter->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+ }
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
+#endif // WPA_SUPPLICANT_SUPPORT
+ {
+ Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
+
+ // Set key material and cipherAlg to Asic
+ AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
+
+ if (pWepKey->KeyIndex & 0x80000000)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.Content[BSSID_WCID];
+ // Assign group key info
+ RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
+ // Assign pairwise key info
+ RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, pEntry);
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP (id=0x%x, Len=%d-byte), %s\n", pWepKey->KeyIndex, pWepKey->KeyLength, (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED) ? "Port Secured":"Port NOT Secured"));
+ }
+ }
+ kfree(pWepKey);
+ break;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ case OID_SET_COUNTERMEASURES:
+ if (wrq->u.data.length != sizeof(int))
+ Status = -EINVAL;
+ else
+ {
+ int enabled = 0;
+ Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
+ if (enabled == 1)
+ pAdapter->StaCfg.bBlockAssoc = TRUE;
+ else
+ // WPA MIC error should block association attempt for 60 seconds
+ pAdapter->StaCfg.bBlockAssoc = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAdapter->StaCfg.bBlockAssoc ? "TRUE":"FALSE"));
+ }
+ break;
+ case RT_OID_WPA_SUPPLICANT_SUPPORT:
+ if (wrq->u.data.length != sizeof(UCHAR))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length);
+ pAdapter->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
+ }
+ break;
+ case OID_802_11_DEAUTHENTICATION:
+ if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
+ Status = -EINVAL;
+ else
+ {
+ MLME_DEAUTH_REQ_STRUCT *pInfo;
+ MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+ pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
+ Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
+ MlmeDeauthReqAction(pAdapter, MsgElem);
+ kfree(MsgElem);
+
+ if (INFRA_ON(pAdapter))
+ {
+ LinkDown(pAdapter, FALSE);
+ pAdapter->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
+ }
+ break;
+ case OID_802_11_DROP_UNENCRYPTED:
+ if (wrq->u.data.length != sizeof(int))
+ Status = -EINVAL;
+ else
+ {
+ int enabled = 0;
+ Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
+ if (enabled == 1)
+ pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ else
+ pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ NdisAcquireSpinLock(&pAdapter->MacTabLock);
+ pAdapter->MacTab.Content[BSSID_WCID].PortSecured = pAdapter->StaCfg.PortSecured;
+ NdisReleaseSpinLock(&pAdapter->MacTabLock);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
+ }
+ break;
+ case OID_802_11_SET_IEEE8021X:
+ if (wrq->u.data.length != sizeof(BOOLEAN))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
+ pAdapter->StaCfg.IEEE8021X = IEEE8021xState;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState));
+ }
+ break;
+ case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
+ if (wrq->u.data.length != sizeof(BOOLEAN))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
+ pAdapter->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys));
+ }
+ break;
+ case OID_802_11_PMKID:
+ pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+
+ if(pPmkId == NULL) {
+ Status = -ENOMEM;
+ break;
+ }
+ Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length);
+
+ // check the PMKID information
+ if (pPmkId->BSSIDInfoCount == 0)
+ NdisZeroMemory(pAdapter->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
+ else
+ {
+ PBSSID_INFO pBssIdInfo;
+ UINT BssIdx;
+ UINT CachedIdx;
+
+ for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++)
+ {
+ // point to the indexed BSSID_INFO structure
+ pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO));
+ // Find the entry in the saved data base.
+ for (CachedIdx = 0; CachedIdx < pAdapter->StaCfg.SavedPMKNum; CachedIdx++)
+ {
+ // compare the BSSID
+ if (NdisEqualMemory(pBssIdInfo->BSSID, pAdapter->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS)))
+ break;
+ }
+
+ // Found, replace it
+ if (CachedIdx < PMKID_NO)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
+ NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
+ pAdapter->StaCfg.SavedPMKNum++;
+ }
+ // Not found, replace the last one
+ else
+ {
+ // Randomly replace one
+ CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO);
+ DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
+ NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
+ }
+ }
+ }
+ if(pPmkId)
+ kfree(pPmkId);
+ break;
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+
+
+#ifdef SNMP_SUPPORT
+ case OID_802_11_SHORTRETRYLIMIT:
+ if (wrq->u.data.length != sizeof(ULONG))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&ShortRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
+ RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (tx_rty_cfg.field.ShortRetryLimit=%d, ShortRetryLimit=%ld)\n", tx_rty_cfg.field.ShortRtyLimit, ShortRetryLimit));
+ }
+ break;
+
+ case OID_802_11_LONGRETRYLIMIT:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT \n"));
+ if (wrq->u.data.length != sizeof(ULONG))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&LongRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
+ RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (tx_rty_cfg.field.LongRetryLimit= %d,LongRetryLimit=%ld)\n", tx_rty_cfg.field.LongRtyLimit, LongRetryLimit));
+ }
+ break;
+
+ case OID_802_11_WEPDEFAULTKEYVALUE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n"));
+ pKey = kmalloc(wrq->u.data.length, GFP_KERNEL);
+ Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
+ //pKey = &WepKey;
+
+ if ( pKey->Length != wrq->u.data.length)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n"));
+ }
+ KeyIdx = pKey->KeyIndex & 0x0fffffff;
+ DBGPRINT(RT_DEBUG_TRACE,("pKey->KeyIndex =%d, pKey->KeyLength=%d\n", pKey->KeyIndex, pKey->KeyLength));
+
+ // it is a shared key
+ if (KeyIdx > 4)
+ Status = -EINVAL;
+ else
+ {
+ pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
+ NdisMoveMemory(&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
+ if (pKey->KeyIndex & 0x80000000)
+ {
+ // Default key for tx (shared key)
+ pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+ }
+ //RestartAPIsRequired = TRUE;
+ }
+ break;
+
+
+ case OID_802_11_WEPDEFAULTKEYID:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYID \n"));
+
+ if (wrq->u.data.length != sizeof(UCHAR))
+ Status = -EINVAL;
+ else
+ Status = copy_from_user(&pAdapter->StaCfg.DefaultKeyId, wrq->u.data.pointer, wrq->u.data.length);
+
+ break;
+
+
+ case OID_802_11_CURRENTCHANNEL:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CURRENTCHANNEL \n"));
+ if (wrq->u.data.length != sizeof(UCHAR))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&ctmp, wrq->u.data.pointer, wrq->u.data.length);
+ sprintf(&ctmp,"%d", ctmp);
+ Set_Channel_Proc(pAdapter, &ctmp);
+ }
+ break;
+#endif
+
+
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
+ Status = -EOPNOTSUPP;
+ break;
+ }
+
+
+ return Status;
+}
+
+INT RTMPQueryInformation(
+ IN PRTMP_ADAPTER pAdapter,
+ IN OUT struct ifreq *rq,
+ IN INT cmd)
+{
+ struct iwreq *wrq = (struct iwreq *) rq;
+ NDIS_802_11_BSSID_LIST_EX *pBssidList = NULL;
+ PNDIS_WLAN_BSSID_EX pBss;
+ NDIS_802_11_SSID Ssid;
+ NDIS_802_11_CONFIGURATION *pConfiguration = NULL;
+ RT_802_11_LINK_STATUS *pLinkStatus = NULL;
+ RT_802_11_STA_CONFIG *pStaConfig = NULL;
+ NDIS_802_11_STATISTICS *pStatistics = NULL;
+ NDIS_802_11_RTS_THRESHOLD RtsThresh;
+ NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
+ NDIS_802_11_POWER_MODE PowerMode;
+ NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
+ RT_802_11_PREAMBLE PreamType;
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode;
+ NDIS_802_11_WEP_STATUS WepStatus;
+ NDIS_MEDIA_STATE MediaState;
+ ULONG BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0;
+ USHORT BssLen = 0;
+ PUCHAR pBuf = NULL, pPtr;
+ INT Status = NDIS_STATUS_SUCCESS;
+ UINT we_version_compiled;
+ UCHAR i, Padding = 0;
+ BOOLEAN RadioState;
+ UCHAR driverVersion[8];
+ OID_SET_HT_PHYMODE *pHTPhyMode = NULL;
+
+
+#ifdef SNMP_SUPPORT
+ //for snmp, kathy
+ DefaultKeyIdxValue *pKeyIdxValue;
+ INT valueLen;
+ TX_RTY_CFG_STRUC tx_rty_cfg;
+ ULONG ShortRetryLimit, LongRetryLimit;
+ UCHAR tmp[64];
+#endif //SNMP
+
+ switch(cmd)
+ {
+ case RT_OID_DEVICE_NAME:
+ wrq->u.data.length = sizeof(STA_NIC_DEVICE_NAME);
+ Status = copy_to_user(wrq->u.data.pointer, STA_NIC_DEVICE_NAME, wrq->u.data.length);
+ break;
+ case RT_OID_VERSION_INFO:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n"));
+ wrq->u.data.length = 8*sizeof(UCHAR);
+ sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
+ driverVersion[7] = '\0';
+ if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+#ifdef RALINK_ATE
+ case RT_QUERY_ATE_TXDONE_COUNT:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_QUERY_ATE_TXDONE_COUNT \n"));
+ wrq->u.data.length = sizeof(UINT32);
+ if (copy_to_user(wrq->u.data.pointer, &pAdapter->ate.TxDoneCount, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+#endif // RALINK_ATE //
+ case OID_802_11_BSSID_LIST:
+ if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ {
+ /*
+ * Still scanning, indicate the caller should try again.
+ */
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
+ return -EAGAIN;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAdapter->ScanTab.BssNr));
+ pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+ // Claculate total buffer size required
+ BssBufSize = sizeof(ULONG);
+
+ for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
+ {
+ // Align pointer to 4 bytes boundary.
+ //Padding = 4 - (pAdapter->ScanTab.BssEntry[i].VarIELen & 0x0003);
+ //if (Padding == 4)
+ // Padding = 0;
+ BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
+ }
+
+ // For safety issue, we add 256 bytes just in case
+ BssBufSize += 256;
+ // Allocate the same size as passed from higher layer
+ pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG);
+ if(pBuf == NULL)
+ {
+ Status = -ENOMEM;
+ break;
+ }
+ // Init 802_11_BSSID_LIST_EX structure
+ NdisZeroMemory(pBuf, BssBufSize);
+ pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
+ pBssidList->NumberOfItems = pAdapter->ScanTab.BssNr;
+
+ // Calculate total buffer length
+ BssLen = 4; // Consist of NumberOfItems
+ // Point to start of NDIS_WLAN_BSSID_EX
+ // pPtr = pBuf + sizeof(ULONG);
+ pPtr = (PUCHAR) &pBssidList->Bssid[0];
+ for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
+ {
+ pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
+ NdisMoveMemory(&pBss->MacAddress, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
+ if ((pAdapter->ScanTab.BssEntry[i].Hidden == 1) && (pAdapter->StaCfg.bShowHiddenSSID == FALSE))
+ {
+ //
+ // We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation
+ // and then failed to send EAPOl farame.
+ //
+ if ((pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAdapter->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
+ {
+ pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
+ NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
+ }
+ else
+ pBss->Ssid.SsidLength = 0;
+ }
+ else
+ {
+ pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
+ NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
+ }
+ pBss->Privacy = pAdapter->ScanTab.BssEntry[i].Privacy;
+ pBss->Rssi = pAdapter->ScanTab.BssEntry[i].Rssi - pAdapter->BbpRssiToDbmDelta;
+ pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
+ pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
+ pBss->Configuration.BeaconPeriod = pAdapter->ScanTab.BssEntry[i].BeaconPeriod;
+ pBss->Configuration.ATIMWindow = pAdapter->ScanTab.BssEntry[i].AtimWin;
+
+ MAP_CHANNEL_ID_TO_KHZ(pAdapter->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
+
+ if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_INFRA)
+ pBss->InfrastructureMode = Ndis802_11Infrastructure;
+ else
+ pBss->InfrastructureMode = Ndis802_11IBSS;
+
+ NdisMoveMemory(pBss->SupportedRates, pAdapter->ScanTab.BssEntry[i].SupRate, pAdapter->ScanTab.BssEntry[i].SupRateLen);
+ NdisMoveMemory(pBss->SupportedRates + pAdapter->ScanTab.BssEntry[i].SupRateLen,
+ pAdapter->ScanTab.BssEntry[i].ExtRate,
+ pAdapter->ScanTab.BssEntry[i].ExtRateLen);
+
+ if (pAdapter->ScanTab.BssEntry[i].VarIELen == 0)
+ {
+ pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
+ NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
+ pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
+ }
+ else
+ {
+ pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen);
+ pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
+ NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
+ NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAdapter->ScanTab.BssEntry[i].VarIEs, pAdapter->ScanTab.BssEntry[i].VarIELen);
+ pPtr += pAdapter->ScanTab.BssEntry[i].VarIELen;
+ }
+ pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
+
+#if WIRELESS_EXT < 17
+ if ((BssLen + pBss->Length) < wrq->u.data.length)
+ BssLen += pBss->Length;
+ else
+ {
+ pBssidList->NumberOfItems = i;
+ break;
+ }
+#else
+ BssLen += pBss->Length;
+#endif
+ }
+
+#if WIRELESS_EXT < 17
+ wrq->u.data.length = BssLen;
+#else
+ if (BssLen > wrq->u.data.length)
+ {
+ kfree(pBssidList);
+ return -E2BIG;
+ }
+ else
+ wrq->u.data.length = BssLen;
+#endif
+ Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
+ kfree(pBssidList);
+ break;
+ case OID_802_3_CURRENT_ADDRESS:
+ wrq->u.data.length = MAC_ADDR_LEN;
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
+ break;
+ case OID_GEN_MEDIA_CONNECT_STATUS:
+ if (pAdapter->IndicateMediaState == NdisMediaStateConnected)
+ MediaState = NdisMediaStateConnected;
+ else
+ MediaState = NdisMediaStateDisconnected;
+
+ wrq->u.data.length = sizeof(NDIS_MEDIA_STATE);
+ Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length);
+ break;
+ case OID_802_11_BSSID:
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+ Status = NDIS_STATUS_RESOURCES;
+ break;
+ }
+#endif // RALINK_ATE //
+ if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
+ {
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS));
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
+ Status = -ENOTCONN;
+ }
+ break;
+ case OID_802_11_SSID:
+ NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
+ NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
+ Ssid.SsidLength = pAdapter->CommonCfg.SsidLen;
+ memcpy(Ssid.Ssid, pAdapter->CommonCfg.Ssid, Ssid.SsidLength);
+ wrq->u.data.length = sizeof(NDIS_802_11_SSID);
+ Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
+ break;
+ case RT_OID_802_11_QUERY_LINK_STATUS:
+ pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG);
+ if (pLinkStatus)
+ {
+ pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAdapter->CommonCfg.TxRate]; // unit : 500 kbps
+ pLinkStatus->ChannelQuality = pAdapter->Mlme.ChannelQuality;
+ pLinkStatus->RxByteCount = pAdapter->RalinkCounters.ReceivedByteCount;
+ pLinkStatus->TxByteCount = pAdapter->RalinkCounters.TransmittedByteCount;
+ pLinkStatus->CentralChannel = pAdapter->CommonCfg.CentralChannel;
+ wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS);
+ Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length);
+ kfree(pLinkStatus);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n"));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n"));
+ Status = -EFAULT;
+ }
+ break;
+ case OID_802_11_CONFIGURATION:
+ pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG);
+ if (pConfiguration)
+ {
+ pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION);
+ pConfiguration->BeaconPeriod = pAdapter->CommonCfg.BeaconPeriod;
+ pConfiguration->ATIMWindow = pAdapter->StaActive.AtimWin;
+ MAP_CHANNEL_ID_TO_KHZ(pAdapter->CommonCfg.Channel, pConfiguration->DSConfig);
+ wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION);
+ Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n",
+ pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAdapter->CommonCfg.Channel));
+ kfree(pConfiguration);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n"));
+ Status = -EFAULT;
+ }
+ break;
+ case RT_OID_802_11_SNR_0:
+ if ((pAdapter->StaCfg.LastSNR0 > 0))
+ {
+ ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR0) * 3) / 16 ;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo));
+ }
+ else
+ Status = -EFAULT;
+ break;
+ case RT_OID_802_11_SNR_1:
+ if ((pAdapter->Antenna.field.RxPath > 1) &&
+ (pAdapter->StaCfg.LastSNR1 > 0))
+ {
+ ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR1) * 3) / 16 ;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo));
+ }
+ else
+ Status = -EFAULT;
+ DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAdapter->StaCfg.LastSNR1=%d)\n",pAdapter->StaCfg.LastSNR1));
+ break;
+ case OID_802_11_RSSI_TRIGGER:
+ ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0 - pAdapter->BbpRssiToDbmDelta;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo));
+ break;
+ case OID_802_11_RSSI:
+ case RT_OID_802_11_RSSI:
+ ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_RSSI_1:
+ ulInfo = pAdapter->StaCfg.RssiSample.LastRssi1;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_RSSI_2:
+ ulInfo = pAdapter->StaCfg.RssiSample.LastRssi2;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+ case OID_802_11_STATISTICS:
+ pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG);
+ if (pStatistics)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n"));
+ // add the most up-to-date h/w raw counters into software counters
+ NICUpdateRawCounters(pAdapter);
+
+ // Sanity check for calculation of sucessful count
+ if (pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart < pAdapter->WlanCounters.RetryCount.QuadPart)
+ pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
+
+ pStatistics->TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart;
+ pStatistics->MulticastTransmittedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
+ pStatistics->FailedCount.QuadPart = pAdapter->WlanCounters.FailedCount.QuadPart;
+ pStatistics->RetryCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
+ pStatistics->MultipleRetryCount.QuadPart = pAdapter->WlanCounters.MultipleRetryCount.QuadPart;
+ pStatistics->RTSSuccessCount.QuadPart = pAdapter->WlanCounters.RTSSuccessCount.QuadPart;
+ pStatistics->RTSFailureCount.QuadPart = pAdapter->WlanCounters.RTSFailureCount.QuadPart;
+ pStatistics->ACKFailureCount.QuadPart = pAdapter->WlanCounters.ACKFailureCount.QuadPart;
+ pStatistics->FrameDuplicateCount.QuadPart = pAdapter->WlanCounters.FrameDuplicateCount.QuadPart;
+ pStatistics->ReceivedFragmentCount.QuadPart = pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart;
+ pStatistics->MulticastReceivedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastReceivedFrameCount.QuadPart;
+#ifdef DBG
+ pStatistics->FCSErrorCount = pAdapter->RalinkCounters.RealFcsErrCount;
+#else
+ pStatistics->FCSErrorCount.QuadPart = pAdapter->WlanCounters.FCSErrorCount.QuadPart;
+ pStatistics->FrameDuplicateCount.u.LowPart = pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart / 100;
+#endif
+ wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS);
+ Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length);
+ kfree(pStatistics);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n"));
+ Status = -EFAULT;
+ }
+ break;
+ case OID_GEN_RCV_OK:
+ ulInfo = pAdapter->Counters8023.GoodReceives;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+ case OID_GEN_RCV_NO_BUFFER:
+ ulInfo = pAdapter->Counters8023.RxNoBuffer;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_PHY_MODE:
+ ulInfo = (ULONG)pAdapter->CommonCfg.PhyMode;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%ld)\n", ulInfo));
+ break;
+ case RT_OID_802_11_STA_CONFIG:
+ pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG);
+ if (pStaConfig)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n"));
+ pStaConfig->EnableTxBurst = pAdapter->CommonCfg.bEnableTxBurst;
+ pStaConfig->EnableTurboRate = 0;
+ pStaConfig->UseBGProtection = pAdapter->CommonCfg.UseBGProtection;
+ pStaConfig->UseShortSlotTime = pAdapter->CommonCfg.bUseShortSlotTime;
+ //pStaConfig->AdhocMode = pAdapter->StaCfg.AdhocMode;
+ pStaConfig->HwRadioStatus = (pAdapter->StaCfg.bHwRadio == TRUE) ? 1 : 0;
+ pStaConfig->Rsv1 = 0;
+ pStaConfig->SystemErrorBitmap = pAdapter->SystemErrorBitmap;
+ wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG);
+ Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length);
+ kfree(pStaConfig);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
+ Status = -EFAULT;
+ }
+ break;
+ case OID_802_11_RTS_THRESHOLD:
+ RtsThresh = pAdapter->CommonCfg.RtsThreshold;
+ wrq->u.data.length = sizeof(RtsThresh);
+ Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh));
+ break;
+ case OID_802_11_FRAGMENTATION_THRESHOLD:
+ FragThresh = pAdapter->CommonCfg.FragmentThreshold;
+ if (pAdapter->CommonCfg.bUseZeroToDisableFragment == TRUE)
+ FragThresh = 0;
+ wrq->u.data.length = sizeof(FragThresh);
+ Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh));
+ break;
+ case OID_802_11_POWER_MODE:
+ PowerMode = pAdapter->StaCfg.WindowsPowerMode;
+ wrq->u.data.length = sizeof(PowerMode);
+ Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode));
+ break;
+ case RT_OID_802_11_RADIO:
+ RadioState = (BOOLEAN) pAdapter->StaCfg.bSwRadio;
+ wrq->u.data.length = sizeof(RadioState);
+ Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState));
+ break;
+ case OID_802_11_INFRASTRUCTURE_MODE:
+ if (pAdapter->StaCfg.BssType == BSS_ADHOC)
+ BssType = Ndis802_11IBSS;
+ else if (pAdapter->StaCfg.BssType == BSS_INFRA)
+ BssType = Ndis802_11Infrastructure;
+ else if (pAdapter->StaCfg.BssType == BSS_MONITOR)
+ BssType = Ndis802_11Monitor;
+ else
+ BssType = Ndis802_11AutoUnknown;
+
+ wrq->u.data.length = sizeof(BssType);
+ Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType));
+ break;
+ case RT_OID_802_11_PREAMBLE:
+ PreamType = pAdapter->CommonCfg.TxPreamble;
+ wrq->u.data.length = sizeof(PreamType);
+ Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType));
+ break;
+ case OID_802_11_AUTHENTICATION_MODE:
+ AuthMode = pAdapter->StaCfg.AuthMode;
+ wrq->u.data.length = sizeof(AuthMode);
+ Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode));
+ break;
+ case OID_802_11_WEP_STATUS:
+ WepStatus = pAdapter->StaCfg.WepStatus;
+ wrq->u.data.length = sizeof(WepStatus);
+ Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus));
+ break;
+ case OID_802_11_TX_POWER_LEVEL:
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPower, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAdapter->CommonCfg.TxPower));
+ break;
+ case RT_OID_802_11_TX_POWER_LEVEL_1:
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPowerPercentage, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
+ break;
+ case OID_802_11_NETWORK_TYPES_SUPPORTED:
+ if ((pAdapter->RfIcType == RFIC_2850) || (pAdapter->RfIcType == RFIC_2750))
+ {
+ NetworkTypeList[0] = 3; // NumberOfItems = 3
+ NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
+ NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
+ NetworkTypeList[3] = Ndis802_11OFDM5; // NetworkType[3] = 11a
+ wrq->u.data.length = 16;
+ Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
+ }
+ else
+ {
+ NetworkTypeList[0] = 2; // NumberOfItems = 2
+ NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
+ NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
+ wrq->u.data.length = 12;
+ Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n"));
+ break;
+ case OID_802_11_NETWORK_TYPE_IN_USE:
+ wrq->u.data.length = sizeof(ULONG);
+ if (pAdapter->CommonCfg.PhyMode == PHY_11A)
+ ulInfo = Ndis802_11OFDM5;
+ else if ((pAdapter->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAdapter->CommonCfg.PhyMode == PHY_11G))
+ ulInfo = Ndis802_11OFDM24;
+ else
+ ulInfo = Ndis802_11DS;
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_QUERY_LAST_RX_RATE:
+ ulInfo = (ULONG)pAdapter->LastRxRate;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo));
+ break;
+ case RT_OID_802_11_QUERY_LAST_TX_RATE:
+ //ulInfo = (ULONG)pAdapter->LastTxRate;
+ ulInfo = (ULONG)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo));
+ break;
+ case RT_OID_802_11_QUERY_EEPROM_VERSION:
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->EepromVersion, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_QUERY_FIRMWARE_VERSION:
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->FirmwareVersion, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_QUERY_NOISE_LEVEL:
+ wrq->u.data.length = sizeof(UCHAR);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->BbpWriteLatch[66], wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAdapter->BbpWriteLatch[66]));
+ break;
+ case RT_OID_802_11_EXTRA_INFO:
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->ExtraInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAdapter->ExtraInfo));
+ break;
+ case RT_OID_WE_VERSION_COMPILED:
+ wrq->u.data.length = sizeof(UINT);
+ we_version_compiled = WIRELESS_EXT;
+ Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_QUERY_APSD_SETTING:
+ apsd = (pAdapter->CommonCfg.bAPSDCapable | (pAdapter->CommonCfg.bAPSDAC_BE << 1) | (pAdapter->CommonCfg.bAPSDAC_BK << 2)
+ | (pAdapter->CommonCfg.bAPSDAC_VI << 3) | (pAdapter->CommonCfg.bAPSDAC_VO << 4) | (pAdapter->CommonCfg.MaxSPLength << 5));
+
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_SETTING (=0x%lx,APSDCap=%d,AC_BE=%d,AC_BK=%d,AC_VI=%d,AC_VO=%d,MAXSPLen=%d)\n",
+ apsd,pAdapter->CommonCfg.bAPSDCapable,pAdapter->CommonCfg.bAPSDAC_BE,pAdapter->CommonCfg.bAPSDAC_BK,pAdapter->CommonCfg.bAPSDAC_VI,pAdapter->CommonCfg.bAPSDAC_VO,pAdapter->CommonCfg.MaxSPLength));
+ break;
+ case RT_OID_802_11_QUERY_APSD_PSM:
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
+ break;
+ case RT_OID_802_11_QUERY_WMM:
+ wrq->u.data.length = sizeof(BOOLEAN);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bWmmCapable, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n", pAdapter->CommonCfg.bWmmCapable));
+ break;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ case RT_OID_NEW_DRIVER:
+ {
+ UCHAR enabled = 1;
+ wrq->u.data.length = sizeof(UCHAR);
+ Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled));
+ }
+ break;
+ case RT_OID_WPA_SUPPLICANT_SUPPORT:
+ wrq->u.data.length = sizeof(UCHAR);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.WpaSupplicantUP, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
+ break;
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ case RT_OID_DRIVER_DEVICE_NAME:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n"));
+ wrq->u.data.length = 16;
+ if (copy_to_user(wrq->u.data.pointer, pAdapter->StaCfg.dev_name, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+ case RT_OID_802_11_QUERY_HT_PHYMODE:
+ pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
+ if (pHTPhyMode)
+ {
+ pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
+ pHTPhyMode->HtMode = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
+ pHTPhyMode->BW = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
+ pHTPhyMode->MCS= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
+ pHTPhyMode->SHORTGI= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
+ pHTPhyMode->STBC= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
+
+ pHTPhyMode->ExtOffset = ((pAdapter->CommonCfg.CentralChannel < pAdapter->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE));
+ wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
+ if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
+ pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
+ Status = -EFAULT;
+ }
+ break;
+ case RT_OID_802_11_COUNTRY_REGION:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n"));
+ wrq->u.data.length = sizeof(ulInfo);
+ ulInfo = pAdapter->CommonCfg.CountryRegionForABand;
+ ulInfo = (ulInfo << 8)|(pAdapter->CommonCfg.CountryRegion);
+ if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+ case RT_OID_802_11_QUERY_DAT_HT_PHYMODE:
+ pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
+ if (pHTPhyMode)
+ {
+ pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
+ pHTPhyMode->HtMode = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.HTMODE;
+ pHTPhyMode->BW = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.BW;
+ pHTPhyMode->MCS= (UCHAR)pAdapter->StaCfg.DesiredTransmitSetting.field.MCS;
+ pHTPhyMode->SHORTGI= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.ShortGI;
+ pHTPhyMode->STBC= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.STBC;
+
+ wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
+ if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
+ pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
+ Status = -EFAULT;
+ }
+ break;
+ case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT:
+ wrq->u.data.length = sizeof(UCHAR);
+ i = 0;
+#ifdef MULTIPLE_CARD_SUPPORT
+ i = 1;
+#endif // MULTIPLE_CARD_SUPPORT //
+ if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i));
+ break;
+#ifdef SNMP_SUPPORT
+ case RT_OID_802_11_MAC_ADDRESS:
+ wrq->u.data.length = MAC_ADDR_LEN;
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_MANUFACTUREROUI:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREROUI \n"));
+ wrq->u.data.length = ManufacturerOUI_LEN;
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_MANUFACTURERNAME:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTURERNAME \n"));
+ wrq->u.data.length = strlen(ManufacturerNAME);
+ Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_RESOURCETYPEIDNAME:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_RESOURCETYPEIDNAME \n"));
+ wrq->u.data.length = strlen(ResourceTypeIdName);
+ Status = copy_to_user(wrq->u.data.pointer, ResourceTypeIdName, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED \n"));
+ ulInfo = 1; // 1 is support wep else 2 is not support.
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_POWERMANAGEMENTMODE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n"));
+ if (pAdapter->StaCfg.Psm == PSMP_ACTION)
+ ulInfo = 1; // 1 is power active else 2 is power save.
+ else
+ ulInfo = 2;
+
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+
+ case OID_802_11_WEPDEFAULTKEYVALUE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE \n"));
+ //KeyIdxValue.KeyIdx = pAd->PortCfg.MBSSID[pAd->IoctlIF].DefaultKeyId;
+ pKeyIdxValue = wrq->u.data.pointer;
+ DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx));
+ valueLen = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
+ NdisMoveMemory(pKeyIdxValue->Value,
+ &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key,
+ valueLen);
+ pKeyIdxValue->Value[valueLen]='\0';
+
+ wrq->u.data.length = sizeof(DefaultKeyIdxValue);
+
+ Status = copy_to_user(wrq->u.data.pointer, pKeyIdxValue, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE,("DefaultKeyId = %d, total len = %d, str len=%d, KeyValue= %02x %02x %02x %02x \n", pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
+ pAdapter->SharedKey[BSS0][0].Key[0],
+ pAdapter->SharedKey[BSS0][1].Key[0],
+ pAdapter->SharedKey[BSS0][2].Key[0],
+ pAdapter->SharedKey[BSS0][3].Key[0]));
+ break;
+
+ case OID_802_11_WEPDEFAULTKEYID:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPDEFAULTKEYID \n"));
+ wrq->u.data.length = sizeof(UCHAR);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAdapter->StaCfg.DefaultKeyId));
+ break;
+
+ case RT_OID_802_11_WEPKEYMAPPINGLENGTH:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPKEYMAPPINGLENGTH \n"));
+ wrq->u.data.length = sizeof(UCHAR);
+ Status = copy_to_user(wrq->u.data.pointer,
+ &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
+ wrq->u.data.length);
+ break;
+
+ case OID_802_11_SHORTRETRYLIMIT:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT \n"));
+ wrq->u.data.length = sizeof(ULONG);
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ ShortRetryLimit = tx_rty_cfg.field.ShortRtyLimit;
+ DBGPRINT(RT_DEBUG_TRACE, ("ShortRetryLimit =%ld, tx_rty_cfg.field.ShortRetryLimit=%d\n", ShortRetryLimit, tx_rty_cfg.field.ShortRtyLimit));
+ Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length);
+ break;
+
+ case OID_802_11_LONGRETRYLIMIT:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT \n"));
+ wrq->u.data.length = sizeof(ULONG);
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ LongRetryLimit = tx_rty_cfg.field.LongRtyLimit;
+ DBGPRINT(RT_DEBUG_TRACE, ("LongRetryLimit =%ld, tx_rty_cfg.field.LongRtyLimit=%d\n", LongRetryLimit, tx_rty_cfg.field.LongRtyLimit));
+ Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_PRODUCTID:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
+
+#ifdef RT2870
+ sprintf(tmp, "%04x %04x\n", ((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idVendor ,((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idProduct);
+
+#endif // RT2870 //
+ wrq->u.data.length = strlen(tmp);
+ Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_MANUFACTUREID:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREID \n"));
+ wrq->u.data.length = strlen(ManufacturerNAME);
+ Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
+ break;
+
+ case OID_802_11_CURRENTCHANNEL:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CURRENTCHANNEL \n"));
+ wrq->u.data.length = sizeof(UCHAR);
+ DBGPRINT(RT_DEBUG_TRACE, ("sizeof UCHAR=%d, channel=%d \n", sizeof(UCHAR), pAdapter->CommonCfg.Channel));
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Channel, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+ break;
+#endif //SNMP_SUPPORT
+
+ case OID_802_11_BUILD_CHANNEL_EX:
+ {
+ UCHAR value;
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n"));
+ wrq->u.data.length = sizeof(UCHAR);
+#ifdef EXT_BUILD_CHANNEL_LIST
+ DBGPRINT(RT_DEBUG_TRACE, ("Support EXT_BUILD_CHANNEL_LIST.\n"));
+ value = 1;
+#else
+ DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
+ value = 0;
+#endif // EXT_BUILD_CHANNEL_LIST //
+ Status = copy_to_user(wrq->u.data.pointer, &value, 1);
+ DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+ }
+ break;
+
+ case OID_802_11_GET_CH_LIST:
+ {
+ PRT_CHANNEL_LIST_INFO pChListBuf;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n"));
+ if (pAdapter->ChannelListNum == 0)
+ {
+ wrq->u.data.length = 0;
+ break;
+ }
+
+ pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG);
+ if (pChListBuf == NULL)
+ {
+ wrq->u.data.length = 0;
+ break;
+ }
+
+ pChListBuf->ChannelListNum = pAdapter->ChannelListNum;
+ for (i = 0; i < pChListBuf->ChannelListNum; i++)
+ pChListBuf->ChannelList[i] = pAdapter->ChannelList[i].Channel;
+
+ wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO);
+ Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO));
+ DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+
+ if (pChListBuf)
+ kfree(pChListBuf);
+ }
+ break;
+
+ case OID_802_11_GET_COUNTRY_CODE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n"));
+ wrq->u.data.length = 2;
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.CountryCode, 2);
+ DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+ break;
+
+ case OID_802_11_GET_CHANNEL_GEOGRAPHY:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n"));
+ wrq->u.data.length = 1;
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Geography, 1);
+ DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+ break;
+
+
+#ifdef QOS_DLS_SUPPORT
+ case RT_OID_802_11_QUERY_DLS:
+ wrq->u.data.length = sizeof(BOOLEAN);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bDLSCapable, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAdapter->CommonCfg.bDLSCapable));
+ break;
+
+ case RT_OID_802_11_QUERY_DLS_PARAM:
+ {
+ PRT_802_11_DLS_INFO pDlsInfo = kmalloc(sizeof(RT_802_11_DLS_INFO), GFP_ATOMIC);
+ if (pDlsInfo == NULL)
+ break;
+
+ for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ RTMPMoveMemory(&pDlsInfo->Entry[i], &pAdapter->StaCfg.DLSEntry[i], sizeof(RT_802_11_DLS_UI));
+ }
+
+ pDlsInfo->num = MAX_NUM_OF_DLS_ENTRY;
+ wrq->u.data.length = sizeof(RT_802_11_DLS_INFO);
+ Status = copy_to_user(wrq->u.data.pointer, pDlsInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS_PARAM\n"));
+
+ if (pDlsInfo)
+ kfree(pDlsInfo);
+ }
+ break;
+#endif // QOS_DLS_SUPPORT //
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd));
+ Status = -EOPNOTSUPP;
+ break;
+ }
+ return Status;
+}
+
+INT rt28xx_sta_ioctl(
+ IN struct net_device *net_dev,
+ IN OUT struct ifreq *rq,
+ IN INT cmd)
+{
+ POS_COOKIE pObj;
+ VIRTUAL_ADAPTER *pVirtualAd = NULL;
+ RTMP_ADAPTER *pAd = NULL;
+ struct iwreq *wrq = (struct iwreq *) rq;
+ BOOLEAN StateMachineTouched = FALSE;
+ INT Status = NDIS_STATUS_SUCCESS;
+ USHORT subcmd;
+
+ if (net_dev->priv_flags == INT_MAIN)
+ {
+ pAd = net_dev->ml_priv;
+ }
+ else
+ {
+ pVirtualAd = net_dev->ml_priv;
+ pAd = pVirtualAd->RtmpDev->ml_priv;
+ }
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ if (pAd == NULL)
+ {
+ /* if 1st open fail, pAd will be free;
+ So the net_dev->ml_priv will be NULL in 2rd open */
+ return -ENETDOWN;
+ }
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+ if (wrq->u.data.pointer == NULL)
+ {
+ return Status;
+ }
+
+ if (strstr(wrq->u.data.pointer, "OpMode") == NULL)
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+ }
+
+ { // determine this ioctl command is comming from which interface.
+ pObj->ioctl_if_type = INT_MAIN;
+ pObj->ioctl_if = MAIN_MBSSID;
+ }
+
+ switch(cmd)
+ {
+#ifdef RALINK_ATE
+#ifdef RALINK_28xx_QA
+ case RTPRIV_IOCTL_ATE:
+ {
+ RtmpDoAte(pAd, wrq);
+ }
+ break;
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+ case SIOCGIFHWADDR:
+ DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
+ memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
+ break;
+ case SIOCGIWNAME:
+ {
+ char *name=&wrq->u.name[0];
+ rt_ioctl_giwname(net_dev, NULL, name, NULL);
+ break;
+ }
+ case SIOCGIWESSID: //Get ESSID
+ {
+ struct iw_point *essid=&wrq->u.essid;
+ rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
+ break;
+ }
+ case SIOCSIWESSID: //Set ESSID
+ {
+ struct iw_point *essid=&wrq->u.essid;
+ rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
+ break;
+ }
+ case SIOCSIWNWID: // set network id (the cell)
+ case SIOCGIWNWID: // get network id
+ Status = -EOPNOTSUPP;
+ break;
+ case SIOCSIWFREQ: //set channel/frequency (Hz)
+ {
+ struct iw_freq *freq=&wrq->u.freq;
+ rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
+ break;
+ }
+ case SIOCGIWFREQ: // get channel/frequency (Hz)
+ {
+ struct iw_freq *freq=&wrq->u.freq;
+ rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
+ break;
+ }
+ case SIOCSIWNICKN: //set node name/nickname
+ {
+ struct iw_point *data=&wrq->u.data;
+ rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
+ break;
+ }
+ case SIOCGIWNICKN: //get node name/nickname
+ {
+ struct iw_point *data=&wrq->u.data;
+ rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
+ break;
+ }
+ case SIOCGIWRATE: //get default bit rate (bps)
+ rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
+ break;
+ case SIOCSIWRATE: //set default bit rate (bps)
+ rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
+ break;
+ case SIOCGIWRTS: // get RTS/CTS threshold (bytes)
+ {
+ struct iw_param *rts=&wrq->u.rts;
+ rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
+ break;
+ }
+ case SIOCSIWRTS: //set RTS/CTS threshold (bytes)
+ {
+ struct iw_param *rts=&wrq->u.rts;
+ rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
+ break;
+ }
+ case SIOCGIWFRAG: //get fragmentation thr (bytes)
+ {
+ struct iw_param *frag=&wrq->u.frag;
+ rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
+ break;
+ }
+ case SIOCSIWFRAG: //set fragmentation thr (bytes)
+ {
+ struct iw_param *frag=&wrq->u.frag;
+ rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
+ break;
+ }
+ case SIOCGIWENCODE: //get encoding token & mode
+ {
+ struct iw_point *erq=&wrq->u.encoding;
+ if(erq->pointer)
+ rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
+ break;
+ }
+ case SIOCSIWENCODE: //set encoding token & mode
+ {
+ struct iw_point *erq=&wrq->u.encoding;
+ if(erq->pointer)
+ rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
+ break;
+ }
+ case SIOCGIWAP: //get access point MAC addresses
+ {
+ struct sockaddr *ap_addr=&wrq->u.ap_addr;
+ rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
+ break;
+ }
+ case SIOCSIWAP: //set access point MAC addresses
+ {
+ struct sockaddr *ap_addr=&wrq->u.ap_addr;
+ rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
+ break;
+ }
+ case SIOCGIWMODE: //get operation mode
+ {
+ __u32 *mode=&wrq->u.mode;
+ rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
+ break;
+ }
+ case SIOCSIWMODE: //set operation mode
+ {
+ __u32 *mode=&wrq->u.mode;
+ rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
+ break;
+ }
+ case SIOCGIWSENS: //get sensitivity (dBm)
+ case SIOCSIWSENS: //set sensitivity (dBm)
+ case SIOCGIWPOWER: //get Power Management settings
+ case SIOCSIWPOWER: //set Power Management settings
+ case SIOCGIWTXPOW: //get transmit power (dBm)
+ case SIOCSIWTXPOW: //set transmit power (dBm)
+ case SIOCGIWRANGE: //Get range of parameters
+ case SIOCGIWRETRY: //get retry limits and lifetime
+ case SIOCSIWRETRY: //set retry limits and lifetime
+ Status = -EOPNOTSUPP;
+ break;
+ case RT_PRIV_IOCTL:
+ case RT_PRIV_IOCTL_EXT:
+ subcmd = wrq->u.data.flags;
+ if( subcmd & OID_GET_SET_TOGGLE)
+ Status = RTMPSetInformation(pAd, rq, subcmd);
+ else
+ Status = RTMPQueryInformation(pAd, rq, subcmd);
+ break;
+ case SIOCGIWPRIV:
+ if (wrq->u.data.pointer)
+ {
+ if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
+ break;
+ wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
+ if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
+ Status = -EFAULT;
+ }
+ break;
+ case RTPRIV_IOCTL_SET:
+ if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
+ break;
+ rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
+ break;
+ case RTPRIV_IOCTL_GSITESURVEY:
+ RTMPIoctlGetSiteSurvey(pAd, wrq);
+ break;
+#ifdef DBG
+ case RTPRIV_IOCTL_MAC:
+ RTMPIoctlMAC(pAd, wrq);
+ break;
+ case RTPRIV_IOCTL_E2P:
+ RTMPIoctlE2PROM(pAd, wrq);
+ break;
+#ifdef RT30xx
+ case RTPRIV_IOCTL_RF:
+ RTMPIoctlRF(pAd, wrq);
+ break;
+#endif // RT30xx //
+#endif // DBG //
+ case SIOCETHTOOL:
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
+ Status = -EOPNOTSUPP;
+ break;
+ }
+
+ if(StateMachineTouched) // Upper layer sent a MLME-related operations
+ RT28XX_MLME_HANDLER(pAd);
+
+ return Status;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set SSID
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_SSID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ NDIS_802_11_SSID Ssid, *pSsid=NULL;
+ BOOLEAN StateMachineTouched = FALSE;
+ int success = TRUE;
+
+ if( strlen(arg) <= MAX_LEN_OF_SSID)
+ {
+ NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
+ if (strlen(arg) != 0)
+ {
+ NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
+ Ssid.SsidLength = strlen(arg);
+ }
+ else //ANY ssid
+ {
+ Ssid.SsidLength = 0;
+ memcpy(Ssid.Ssid, "", 0);
+ pAdapter->StaCfg.BssType = BSS_INFRA;
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+ pAdapter->StaCfg.WepStatus = Ndis802_11EncryptionDisabled;
+ }
+ pSsid = &Ssid;
+
+ if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ {
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+ }
+
+ pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
+ pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+ pAdapter->bConfigChanged = TRUE;
+
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_SSID,
+ sizeof(NDIS_802_11_SSID),
+ (VOID *)pSsid);
+
+ StateMachineTouched = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
+ }
+ else
+ success = FALSE;
+
+ if (StateMachineTouched) // Upper layer sent a MLME-related operations
+ RT28XX_MLME_HANDLER(pAdapter);
+
+ return success;
+}
+
+#ifdef WMM_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Set WmmCapable Enable or Disable
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_WmmCapable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ BOOLEAN bWmmCapable;
+
+ bWmmCapable = simple_strtol(arg, 0, 10);
+
+ if ((bWmmCapable == 1)
+#ifdef RT2870
+ && (pAd->NumberOfPipes >= 5)
+#endif // RT2870 //
+ )
+ pAd->CommonCfg.bWmmCapable = TRUE;
+ else if (bWmmCapable == 0)
+ pAd->CommonCfg.bWmmCapable = FALSE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
+ pAd->CommonCfg.bWmmCapable));
+
+ return TRUE;
+}
+#endif // WMM_SUPPORT //
+
+/*
+ ==========================================================================
+ Description:
+ Set Network Type(Infrastructure/Adhoc mode)
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_NetworkType_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ UINT32 Value = 0;
+
+ if (strcmp(arg, "Adhoc") == 0)
+ {
+ if (pAdapter->StaCfg.BssType != BSS_ADHOC)
+ {
+ // Config has changed
+ pAdapter->bConfigChanged = TRUE;
+ if (MONITOR_ON(pAdapter))
+ {
+ RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
+ RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
+ Value &= (~0x80);
+ RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
+ OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
+ pAdapter->StaCfg.bAutoReconnect = TRUE;
+ LinkDown(pAdapter, FALSE);
+ }
+ if (INFRA_ON(pAdapter))
+ {
+ //BOOLEAN Cancelled;
+ // Set the AutoReconnectSsid to prevent it reconnect to old SSID
+ // Since calling this indicate user don't want to connect to that SSID anymore.
+ pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
+ NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
+
+ LinkDown(pAdapter, FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
+ }
+ }
+ pAdapter->StaCfg.BssType = BSS_ADHOC;
+ pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
+ DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
+ }
+ else if (strcmp(arg, "Infra") == 0)
+ {
+ if (pAdapter->StaCfg.BssType != BSS_INFRA)
+ {
+ // Config has changed
+ pAdapter->bConfigChanged = TRUE;
+ if (MONITOR_ON(pAdapter))
+ {
+ RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
+ RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
+ Value &= (~0x80);
+ RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
+ OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
+ pAdapter->StaCfg.bAutoReconnect = TRUE;
+ LinkDown(pAdapter, FALSE);
+ }
+ if (ADHOC_ON(pAdapter))
+ {
+ // Set the AutoReconnectSsid to prevent it reconnect to old SSID
+ // Since calling this indicate user don't want to connect to that SSID anymore.
+ pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
+ NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
+
+ LinkDown(pAdapter, FALSE);
+ }
+ }
+ pAdapter->StaCfg.BssType = BSS_INFRA;
+ pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
+ DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
+
+ pAdapter->StaCfg.BssType = BSS_INFRA;
+ }
+ else if (strcmp(arg, "Monitor") == 0)
+ {
+ UCHAR bbpValue = 0;
+ BCN_TIME_CFG_STRUC csr;
+ OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
+ OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
+ OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
+ // disable all periodic state machine
+ pAdapter->StaCfg.bAutoReconnect = FALSE;
+ // reset all mlme state machine
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
+ if (pAdapter->CommonCfg.CentralChannel == 0)
+ {
+#ifdef DOT11_N_SUPPORT
+ if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
+ pAdapter->CommonCfg.CentralChannel = 36;
+ else
+#endif // DOT11_N_SUPPORT //
+ pAdapter->CommonCfg.CentralChannel = 6;
+ }
+#ifdef DOT11_N_SUPPORT
+ else
+ N_ChannelCheck(pAdapter);
+#endif // DOT11_N_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+ if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
+ pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
+ pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
+ {
+ // 40MHz ,control channel at lower
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
+ bbpValue &= (~0x18);
+ bbpValue |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
+ pAdapter->CommonCfg.BBPCurrentBW = BW_40;
+ // RX : control channel at lower
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
+ bbpValue &= (~0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
+
+ RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
+ Value &= 0xfffffffe;
+ RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
+ pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
+ AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
+ DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
+ pAdapter->CommonCfg.Channel,
+ pAdapter->CommonCfg.CentralChannel));
+ }
+ else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
+ pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
+ pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
+ {
+ // 40MHz ,control channel at upper
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
+ bbpValue &= (~0x18);
+ bbpValue |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
+ pAdapter->CommonCfg.BBPCurrentBW = BW_40;
+ RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
+ Value |= 0x1;
+ RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
+ bbpValue |= (0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
+ pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
+ AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
+ DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
+ pAdapter->CommonCfg.Channel,
+ pAdapter->CommonCfg.CentralChannel));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ // 20MHz
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
+ bbpValue &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
+ pAdapter->CommonCfg.BBPCurrentBW = BW_20;
+ AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
+ DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
+ }
+ // Enable Rx with promiscuous reception
+ RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
+ // ASIC supporsts sniffer function with replacing RSSI with timestamp.
+ //RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
+ //Value |= (0x80);
+ //RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
+ // disable sync
+ RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
+ csr.field.bBeaconGen = 0;
+ csr.field.bTBTTEnable = 0;
+ csr.field.TsfSyncMode = 0;
+ RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
+
+ pAdapter->StaCfg.BssType = BSS_MONITOR;
+ pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
+ DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
+ }
+
+ // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
+ pAdapter->StaCfg.WpaState = SS_NOTUSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Authentication mode
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
+ else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+ else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+ else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
+ else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
+ else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
+ else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ else
+ return FALSE;
+
+ pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Encryption Type
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_EncrypType_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
+ {
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
+ }
+ else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
+ {
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
+ }
+ else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
+ {
+ if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
+ pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
+ }
+ else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
+ {
+ if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
+ pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
+ }
+ else
+ return FALSE;
+
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Default Key ID
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_DefaultKeyID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ ULONG KeyIdx;
+
+ KeyIdx = simple_strtol(arg, 0, 10);
+ if((KeyIdx >= 1 ) && (KeyIdx <= 4))
+ pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY1
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Key1_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ int KeyLen;
+ int i;
+ UCHAR CipherAlg=CIPHER_WEP64;
+
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ KeyLen = strlen(arg);
+
+ switch (KeyLen)
+ {
+ case 5: //wep 40 Ascii type
+ pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
+ break;
+ case 10: //wep 40 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
+ break;
+ case 13: //wep 104 Ascii type
+ pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
+ break;
+ case 26: //wep 104 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
+ break;
+ default: //Invalid argument
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
+ return FALSE;
+ }
+
+ pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
+
+ // Set keys (into ASIC)
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ ; // not support
+ else // Old WEP stuff
+ {
+ AsicAddSharedKeyEntry(pAdapter,
+ 0,
+ 0,
+ pAdapter->SharedKey[BSS0][0].CipherAlg,
+ pAdapter->SharedKey[BSS0][0].Key,
+ NULL,
+ NULL);
+ }
+
+ return TRUE;
+}
+/*
+ ==========================================================================
+
+ Description:
+ Set WEP KEY2
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Key2_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ int KeyLen;
+ int i;
+ UCHAR CipherAlg=CIPHER_WEP64;
+
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ KeyLen = strlen(arg);
+
+ switch (KeyLen)
+ {
+ case 5: //wep 40 Ascii type
+ pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
+ break;
+ case 10: //wep 40 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
+ break;
+ case 13: //wep 104 Ascii type
+ pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
+ break;
+ case 26: //wep 104 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
+ break;
+ default: //Invalid argument
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
+ return FALSE;
+ }
+ pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
+
+ // Set keys (into ASIC)
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ ; // not support
+ else // Old WEP stuff
+ {
+ AsicAddSharedKeyEntry(pAdapter,
+ 0,
+ 1,
+ pAdapter->SharedKey[BSS0][1].CipherAlg,
+ pAdapter->SharedKey[BSS0][1].Key,
+ NULL,
+ NULL);
+ }
+
+ return TRUE;
+}
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY3
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Key3_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ int KeyLen;
+ int i;
+ UCHAR CipherAlg=CIPHER_WEP64;
+
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ KeyLen = strlen(arg);
+
+ switch (KeyLen)
+ {
+ case 5: //wep 40 Ascii type
+ pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
+ break;
+ case 10: //wep 40 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
+ break;
+ case 13: //wep 104 Ascii type
+ pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
+ break;
+ case 26: //wep 104 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
+ break;
+ default: //Invalid argument
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
+ return FALSE;
+ }
+ pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
+
+ // Set keys (into ASIC)
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ ; // not support
+ else // Old WEP stuff
+ {
+ AsicAddSharedKeyEntry(pAdapter,
+ 0,
+ 2,
+ pAdapter->SharedKey[BSS0][2].CipherAlg,
+ pAdapter->SharedKey[BSS0][2].Key,
+ NULL,
+ NULL);
+ }
+
+ return TRUE;
+}
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY4
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Key4_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ int KeyLen;
+ int i;
+ UCHAR CipherAlg=CIPHER_WEP64;
+
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ KeyLen = strlen(arg);
+
+ switch (KeyLen)
+ {
+ case 5: //wep 40 Ascii type
+ pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
+ break;
+ case 10: //wep 40 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
+ break;
+ case 13: //wep 104 Ascii type
+ pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
+ break;
+ case 26: //wep 104 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
+ break;
+ default: //Invalid argument
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
+ return FALSE;
+ }
+ pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
+
+ // Set keys (into ASIC)
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ ; // not support
+ else // Old WEP stuff
+ {
+ AsicAddSharedKeyEntry(pAdapter,
+ 0,
+ 3,
+ pAdapter->SharedKey[BSS0][3].CipherAlg,
+ pAdapter->SharedKey[BSS0][3].Key,
+ NULL,
+ NULL);
+ }
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set WPA PSK key
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_WPAPSK_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ UCHAR keyMaterial[40];
+
+ if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
+ (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+ (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
+ )
+ return TRUE; // do nothing
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
+
+ NdisZeroMemory(keyMaterial, 40);
+
+ if ((strlen(arg) < 8) || (strlen(arg) > 64))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
+ return FALSE;
+ }
+
+ if (strlen(arg) == 64)
+ {
+ AtoH(arg, keyMaterial, 32);
+ NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
+
+ }
+ else
+ {
+ PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
+ NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
+ }
+
+
+
+ if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
+ pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ pAdapter->StaCfg.WpaState = SS_NOTUSE;
+ }
+ else
+ {
+ // Start STA supplicant state machine
+ pAdapter->StaCfg.WpaState = SS_START;
+ }
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Power Saving mode
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_PSMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ if (pAdapter->StaCfg.BssType == BSS_INFRA)
+ {
+ if ((strcmp(arg, "Max_PSP") == 0) ||
+ (strcmp(arg, "max_psp") == 0) ||
+ (strcmp(arg, "MAX_PSP") == 0))
+ {
+ // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+ // to exclude certain situations.
+ if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
+ pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
+ OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
+ pAdapter->StaCfg.DefaultListenCount = 5;
+
+ }
+ else if ((strcmp(arg, "Fast_PSP") == 0) ||
+ (strcmp(arg, "fast_psp") == 0) ||
+ (strcmp(arg, "FAST_PSP") == 0))
+ {
+ // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+ // to exclude certain situations.
+ OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
+ if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
+ pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
+ pAdapter->StaCfg.DefaultListenCount = 3;
+ }
+ else if ((strcmp(arg, "Legacy_PSP") == 0) ||
+ (strcmp(arg, "legacy_psp") == 0) ||
+ (strcmp(arg, "LEGACY_PSP") == 0))
+ {
+ // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+ // to exclude certain situations.
+ OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
+ if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
+ pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
+ pAdapter->StaCfg.DefaultListenCount = 3;
+ }
+ else
+ {
+ //Default Ndis802_11PowerModeCAM
+ // clear PSM bit immediately
+ MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
+ OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
+ if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
+ pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
+ }
+ else
+ return FALSE;
+
+
+ return TRUE;
+}
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Set WpaSupport flag.
+ Value:
+ 0: Driver ignore wpa_supplicant.
+ 1: wpa_supplicant initiates scanning and AP selection.
+ 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Wpa_Support(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+ if ( simple_strtol(arg, 0, 10) == 0)
+ pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
+ else if ( simple_strtol(arg, 0, 10) == 1)
+ pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
+ else if ( simple_strtol(arg, 0, 10) == 2)
+ pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
+ else
+ pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
+
+ return TRUE;
+}
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef DBG
+/*
+ ==========================================================================
+ Description:
+ Read / Write MAC
+ Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 mac 0 ==> read MAC where Addr=0x0
+ 2.) iwpriv ra0 mac 0=12 ==> write MAC where Addr=0x0, value=12
+ ==========================================================================
+*/
+VOID RTMPIoctlMAC(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq)
+{
+ CHAR *this_char;
+ CHAR *value;
+ INT j = 0, k = 0;
+ CHAR msg[1024];
+ CHAR arg[255];
+ ULONG macAddr = 0;
+ UCHAR temp[16], temp2[16];
+ UINT32 macValue = 0;
+ INT Status;
+ BOOLEAN bIsPrintAllMAC = FALSE;
+
+
+ memset(msg, 0x00, 1024);
+ if (wrq->u.data.length > 1) //No parameters.
+ {
+ Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
+ sprintf(msg, "\n");
+
+ //Parsing Read or Write
+ this_char = arg;
+ if (!*this_char)
+ goto next;
+
+ if ((value = rtstrchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value || !*value)
+ { //Read
+ // Sanity check
+ if(strlen(this_char) > 4)
+ goto next;
+
+ j = strlen(this_char);
+ while(j-- > 0)
+ {
+ if(this_char[j] > 'f' || this_char[j] < '0')
+ return;
+ }
+
+ // Mac Addr
+ k = j = strlen(this_char);
+ while(j-- > 0)
+ {
+ this_char[4-k+j] = this_char[j];
+ }
+
+ while(k < 4)
+ this_char[3-k++]='0';
+ this_char[4]='\0';
+
+ if(strlen(this_char) == 4)
+ {
+ AtoH(this_char, temp, 2);
+ macAddr = *temp*256 + temp[1];
+ if (macAddr < 0xFFFF)
+ {
+ RTMP_IO_READ32(pAdapter, macAddr, &macValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue));
+ sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr , macValue);
+ }
+ else
+ {//Invalid parametes, so default printk all mac
+ bIsPrintAllMAC = TRUE;
+ goto next;
+ }
+ }
+ }
+ else
+ { //Write
+ memcpy(&temp2, value, strlen(value));
+ temp2[strlen(value)] = '\0';
+
+ // Sanity check
+ if((strlen(this_char) > 4) || strlen(temp2) > 8)
+ goto next;
+
+ j = strlen(this_char);
+ while(j-- > 0)
+ {
+ if(this_char[j] > 'f' || this_char[j] < '0')
+ return;
+ }
+
+ j = strlen(temp2);
+ while(j-- > 0)
+ {
+ if(temp2[j] > 'f' || temp2[j] < '0')
+ return;
+ }
+
+ //MAC Addr
+ k = j = strlen(this_char);
+ while(j-- > 0)
+ {
+ this_char[4-k+j] = this_char[j];
+ }
+
+ while(k < 4)
+ this_char[3-k++]='0';
+ this_char[4]='\0';
+
+ //MAC value
+ k = j = strlen(temp2);
+ while(j-- > 0)
+ {
+ temp2[8-k+j] = temp2[j];
+ }
+
+ while(k < 8)
+ temp2[7-k++]='0';
+ temp2[8]='\0';
+
+ {
+ AtoH(this_char, temp, 2);
+ macAddr = *temp*256 + temp[1];
+
+ AtoH(temp2, temp, 4);
+ macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3];
+
+ // debug mode
+ if (macAddr == (HW_DEBUG_SETTING_BASE + 4))
+ {
+ // 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
+ if (macValue & 0x000000ff)
+ {
+ pAdapter->BbpTuning.bEnable = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n"));
+ }
+ else
+ {
+ UCHAR R66;
+ pAdapter->BbpTuning.bEnable = FALSE;
+ R66 = 0x26 + GET_LNA_GAIN(pAdapter);
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
+ }
+ else
+#endif // RALINK_ATE //
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
+ DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
+ }
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue));
+
+ RTMP_IO_WRITE32(pAdapter, macAddr, macValue);
+ sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr, macValue);
+ }
+ }
+ }
+ else
+ bIsPrintAllMAC = TRUE;
+next:
+ if (bIsPrintAllMAC)
+ {
+ struct file *file_w;
+ PCHAR fileName = "MacDump.txt";
+ mm_segment_t orig_fs;
+
+ orig_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ // open file
+ file_w = filp_open(fileName, O_WRONLY|O_CREAT, 0);
+ if (IS_ERR(file_w))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(file_w), fileName));
+ }
+ else
+ {
+ if (file_w->f_op && file_w->f_op->write)
+ {
+ file_w->f_pos = 0;
+ macAddr = 0x1000;
+
+ while (macAddr <= 0x1800)
+ {
+ RTMP_IO_READ32(pAdapter, macAddr, &macValue);
+ sprintf(msg, "%08lx = %08X\n", macAddr, macValue);
+
+ // write data to file
+ file_w->f_op->write(file_w, msg, strlen(msg), &file_w->f_pos);
+
+ printk("%s", msg);
+ macAddr += 4;
+ }
+ sprintf(msg, "\nDump all MAC values to %s\n", fileName);
+ }
+ filp_close(file_w, NULL);
+ }
+ set_fs(orig_fs);
+ }
+ if(strlen(msg) == 1)
+ sprintf(msg+strlen(msg), "===>Error command format!");
+
+ // Copy the information into the user buffer
+ wrq->u.data.length = strlen(msg);
+ Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n"));
+}
+
+/*
+ ==========================================================================
+ Description:
+ Read / Write E2PROM
+ Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 e2p 0 ==> read E2PROM where Addr=0x0
+ 2.) iwpriv ra0 e2p 0=1234 ==> write E2PROM where Addr=0x0, value=1234
+ ==========================================================================
+*/
+VOID RTMPIoctlE2PROM(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq)
+{
+ CHAR *this_char;
+ CHAR *value;
+ INT j = 0, k = 0;
+ CHAR msg[1024];
+ CHAR arg[255];
+ USHORT eepAddr = 0;
+ UCHAR temp[16], temp2[16];
+ USHORT eepValue;
+ int Status;
+ BOOLEAN bIsPrintAllE2P = FALSE;
+
+
+ memset(msg, 0x00, 1024);
+ if (wrq->u.data.length > 1) //No parameters.
+ {
+ Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
+ sprintf(msg, "\n");
+
+ //Parsing Read or Write
+ this_char = arg;
+
+
+ if (!*this_char)
+ goto next;
+
+ if ((value = rtstrchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value || !*value)
+ { //Read
+
+ // Sanity check
+ if(strlen(this_char) > 4)
+ goto next;
+
+ j = strlen(this_char);
+ while(j-- > 0)
+ {
+ if(this_char[j] > 'f' || this_char[j] < '0')
+ return;
+ }
+
+ // E2PROM addr
+ k = j = strlen(this_char);
+ while(j-- > 0)
+ {
+ this_char[4-k+j] = this_char[j];
+ }
+
+ while(k < 4)
+ this_char[3-k++]='0';
+ this_char[4]='\0';
+
+ if(strlen(this_char) == 4)
+ {
+ AtoH(this_char, temp, 2);
+ eepAddr = *temp*256 + temp[1];
+ if (eepAddr < 0xFFFF)
+ {
+ RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
+ sprintf(msg+strlen(msg), "[0x%04X]:0x%04X ", eepAddr , eepValue);
+ }
+ else
+ {//Invalid parametes, so default printk all bbp
+ bIsPrintAllE2P = TRUE;
+ goto next;
+ }
+ }
+ }
+ else
+ { //Write
+ memcpy(&temp2, value, strlen(value));
+ temp2[strlen(value)] = '\0';
+
+ // Sanity check
+ if((strlen(this_char) > 4) || strlen(temp2) > 8)
+ goto next;
+
+ j = strlen(this_char);
+ while(j-- > 0)
+ {
+ if(this_char[j] > 'f' || this_char[j] < '0')
+ return;
+ }
+ j = strlen(temp2);
+ while(j-- > 0)
+ {
+ if(temp2[j] > 'f' || temp2[j] < '0')
+ return;
+ }
+
+ //MAC Addr
+ k = j = strlen(this_char);
+ while(j-- > 0)
+ {
+ this_char[4-k+j] = this_char[j];
+ }
+
+ while(k < 4)
+ this_char[3-k++]='0';
+ this_char[4]='\0';
+
+ //MAC value
+ k = j = strlen(temp2);
+ while(j-- > 0)
+ {
+ temp2[4-k+j] = temp2[j];
+ }
+
+ while(k < 4)
+ temp2[3-k++]='0';
+ temp2[4]='\0';
+
+ AtoH(this_char, temp, 2);
+ eepAddr = *temp*256 + temp[1];
+
+ AtoH(temp2, temp, 2);
+ eepValue = *temp*256 + temp[1];
+
+ RT28xx_EEPROM_WRITE16(pAdapter, eepAddr, eepValue);
+ sprintf(msg+strlen(msg), "[0x%02X]:%02X ", eepAddr, eepValue);
+ }
+ }
+ else
+ bIsPrintAllE2P = TRUE;
+next:
+ if (bIsPrintAllE2P)
+ {
+ struct file *file_w;
+ PCHAR fileName = "EEPROMDump.txt";
+ mm_segment_t orig_fs;
+
+ orig_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ // open file
+ file_w = filp_open(fileName, O_WRONLY|O_CREAT, 0);
+ if (IS_ERR(file_w))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(file_w), fileName));
+ }
+ else
+ {
+ if (file_w->f_op && file_w->f_op->write)
+ {
+ file_w->f_pos = 0;
+ eepAddr = 0x00;
+
+ while (eepAddr <= 0xFE)
+ {
+ RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
+ sprintf(msg, "%08x = %04x\n", eepAddr , eepValue);
+
+ // write data to file
+ file_w->f_op->write(file_w, msg, strlen(msg), &file_w->f_pos);
+
+ printk("%s", msg);
+ eepAddr += 2;
+ }
+ sprintf(msg, "\nDump all EEPROM values to %s\n", fileName);
+ }
+ filp_close(file_w, NULL);
+ }
+ set_fs(orig_fs);
+ }
+ if(strlen(msg) == 1)
+ sprintf(msg+strlen(msg), "===>Error command format!");
+
+
+ // Copy the information into the user buffer
+ wrq->u.data.length = strlen(msg);
+ Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
+}
+#ifdef RT30xx
+/*
+ ==========================================================================
+ Description:
+ Read / Write RF register
+Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 rf ==> read all RF registers
+ 2.) iwpriv ra0 rf 1 ==> read RF where RegID=1
+ 3.) iwpriv ra0 rf 1=10 ==> write RF R1=0x10
+ ==========================================================================
+*/
+VOID RTMPIoctlRF(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq)
+{
+ CHAR *this_char;
+ CHAR *value;
+ UCHAR regRF = 0;
+ CHAR msg[2048];
+ CHAR arg[255];
+ INT rfId;
+ LONG rfValue;
+ int Status;
+ BOOLEAN bIsPrintAllRF = FALSE;
+
+
+ memset(msg, 0x00, 2048);
+ if (wrq->u.data.length > 1) //No parameters.
+ {
+ Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
+ sprintf(msg, "\n");
+
+ //Parsing Read or Write
+ this_char = arg;
+ if (!*this_char)
+ goto next;
+
+ if ((value = strchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value || !*value)
+ { //Read
+ if (sscanf(this_char, "%d", &(rfId)) == 1)
+ {
+ if (rfId <= 31)
+ {
+ // In RT2860 ATE mode, we do not load 8051 firmware.
+ //We must access RF directly.
+ // For RT2870 ATE mode, ATE_RF_IO_WRITE8(/READ8)_BY_REG_ID are redefined.
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
+ }
+ else
+#endif // RALINK_ATE //
+ // according to Andy, Gary, David require.
+ // the command rf shall read rf register directly for dubug.
+ // BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ RT30xxReadRFRegister(pAdapter, rfId, &regRF);
+
+ sprintf(msg+strlen(msg), "R%02d[0x%02x]:%02X ", rfId, rfId*2, regRF);
+ }
+ else
+ {//Invalid parametes, so default printk all RF
+ bIsPrintAllRF = TRUE;
+ goto next;
+ }
+ }
+ else
+ { //Invalid parametes, so default printk all RF
+ bIsPrintAllRF = TRUE;
+ goto next;
+ }
+ }
+ else
+ { //Write
+ if ((sscanf(this_char, "%d", &(rfId)) == 1) && (sscanf(value, "%lx", &(rfValue)) == 1))
+ {
+ if (rfId <= 31)
+ {
+ // In RT2860 ATE mode, we do not load 8051 firmware.
+ // We should access RF registers directly.
+ // For RT2870 ATE mode, ATE_RF_IO_WRITE8/READ8_BY_REG_ID are redefined.
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
+ ATE_RF_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)rfId,(UCHAR) rfValue);
+ //Read it back for showing
+ ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
+ sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X\n", rfId, rfId*2, regRF);
+ }
+ else
+#endif // RALINK_ATE //
+ {
+ // according to Andy, Gary, David require.
+ // the command RF shall read/write RF register directly for dubug.
+ //BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ //BBP_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)bbpId,(UCHAR) bbpValue);
+ RT30xxReadRFRegister(pAdapter, rfId, &regRF);
+ RT30xxWriteRFRegister(pAdapter, (UCHAR)rfId,(UCHAR) rfValue);
+ //Read it back for showing
+ //BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ RT30xxReadRFRegister(pAdapter, rfId, &regRF);
+ sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X\n", rfId, rfId*2, regRF);
+ }
+ }
+ else
+ {//Invalid parametes, so default printk all RF
+ bIsPrintAllRF = TRUE;
+ }
+ }
+ else
+ { //Invalid parametes, so default printk all RF
+ bIsPrintAllRF = TRUE;
+ }
+ }
+ }
+ else
+ bIsPrintAllRF = TRUE;
+next:
+ if (bIsPrintAllRF)
+ {
+ memset(msg, 0x00, 2048);
+ sprintf(msg, "\n");
+ for (rfId = 0; rfId <= 31; rfId++)
+ {
+ // In RT2860 ATE mode, we do not load 8051 firmware.
+ // We should access RF registers directly.
+ // For RT2870 ATE mode, ATE_RF_IO_WRITE8/READ8_BY_REG_ID are redefined.
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
+ }
+ else
+#endif // RALINK_ATE //
+
+ // according to Andy, Gary, David require.
+ // the command RF shall read/write RF register directly for dubug.
+ RT30xxReadRFRegister(pAdapter, rfId, &regRF);
+ sprintf(msg+strlen(msg), "%03d = %02X\n", rfId, regRF);
+ }
+ // Copy the information into the user buffer
+ DBGPRINT(RT_DEBUG_TRACE, ("strlen(msg)=%d\n", (UINT32)strlen(msg)));
+ wrq->u.data.length = strlen(msg);
+ if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
+ }
+ }
+ else
+ {
+ if(strlen(msg) == 1)
+ sprintf(msg+strlen(msg), "===>Error command format!");
+
+ DBGPRINT(RT_DEBUG_TRACE, ("copy to user [msg=%s]\n", msg));
+ // Copy the information into the user buffer
+ DBGPRINT(RT_DEBUG_TRACE, ("strlen(msg) =%d\n", (UINT32)strlen(msg)));
+
+ // Copy the information into the user buffer
+ wrq->u.data.length = strlen(msg);
+ Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlRF\n\n"));
+}
+#endif // RT30xx //
+#endif // DBG //
+
+
+
+
+INT Set_TGnWifiTest_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ if (simple_strtol(arg, 0, 10) == 0)
+ pAd->StaCfg.bTGnWifiTest = FALSE;
+ else
+ pAd->StaCfg.bTGnWifiTest = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
+ return TRUE;
+}
+
+INT Set_LongRetryLimit_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ TX_RTY_CFG_STRUC tx_rty_cfg;
+ UCHAR LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
+
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
+ RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
+ return TRUE;
+}
+
+INT Set_ShortRetryLimit_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ TX_RTY_CFG_STRUC tx_rty_cfg;
+ UCHAR ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
+
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
+ RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
+ return TRUE;
+}
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+INT Set_Ieee80211dClientMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ if (simple_strtol(arg, 0, 10) == 0)
+ pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
+ else if (simple_strtol(arg, 0, 10) == 1)
+ pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Flexible;
+ else if (simple_strtol(arg, 0, 10) == 2)
+ pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Strict;
+ else
+ return FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Ieee802dMode_Proc::(IEEEE0211dMode=%d)\n", pAdapter->StaCfg.IEEE80211dClientMode));
+ return TRUE;
+}
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+#ifdef CARRIER_DETECTION_SUPPORT
+INT Set_CarrierDetect_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ if (simple_strtol(arg, 0, 10) == 0)
+ pAd->CommonCfg.CarrierDetect.Enable = FALSE;
+ else
+ pAd->CommonCfg.CarrierDetect.Enable = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF Set_CarrierDetect_Proc::(CarrierDetect.Enable=%d)\n", pAd->CommonCfg.CarrierDetect.Enable));
+ return TRUE;
+}
+#endif // CARRIER_DETECTION_SUPPORT //
+
diff --git a/drivers/staging/rt3070/wpa.h b/drivers/staging/rt3070/wpa.h
new file mode 100644
index 00000000000..88c7c8bf3fc
--- /dev/null
+++ b/drivers/staging/rt3070/wpa.h
@@ -0,0 +1,356 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ wpa.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+
+#ifndef __WPA_H__
+#define __WPA_H__
+
+// EAPOL Key descripter frame format related length
+#define LEN_KEY_DESC_NONCE 32
+#define LEN_KEY_DESC_IV 16
+#define LEN_KEY_DESC_RSC 8
+#define LEN_KEY_DESC_ID 8
+#define LEN_KEY_DESC_REPLAY 8
+#define LEN_KEY_DESC_MIC 16
+
+// The length is the EAPoL-Key frame except key data field.
+// Please refer to 802.11i-2004 ,Figure 43u in p.78
+#define LEN_EAPOL_KEY_MSG (sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE)
+
+// EAP Code Type.
+#define EAP_CODE_REQUEST 1
+#define EAP_CODE_RESPONSE 2
+#define EAP_CODE_SUCCESS 3
+#define EAP_CODE_FAILURE 4
+
+// EAPOL frame Protocol Version
+#define EAPOL_VER 1
+#define EAPOL_VER2 2
+
+// EAPOL-KEY Descriptor Type
+#define WPA1_KEY_DESC 0xfe
+#define WPA2_KEY_DESC 0x02
+
+// Key Descriptor Version of Key Information
+#define DESC_TYPE_TKIP 1
+#define DESC_TYPE_AES 2
+#define DESC_TYPE_MESH 3
+
+#define LEN_MSG1_2WAY 0x7f
+#define MAX_LEN_OF_EAP_HS 256
+
+#define LEN_MASTER_KEY 32
+
+// EAPOL EK, MK
+#define LEN_EAP_EK 16
+#define LEN_EAP_MICK 16
+#define LEN_EAP_KEY ((LEN_EAP_EK)+(LEN_EAP_MICK))
+// TKIP key related
+#define LEN_PMKID 16
+#define LEN_TKIP_EK 16
+#define LEN_TKIP_RXMICK 8
+#define LEN_TKIP_TXMICK 8
+#define LEN_AES_EK 16
+#define LEN_AES_KEY LEN_AES_EK
+#define LEN_TKIP_KEY ((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
+#define TKIP_AP_TXMICK_OFFSET ((LEN_EAP_KEY)+(LEN_TKIP_EK))
+#define TKIP_AP_RXMICK_OFFSET (TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK)
+#define TKIP_GTK_LENGTH ((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
+#define LEN_PTK ((LEN_EAP_KEY)+(LEN_TKIP_KEY))
+
+// RSN IE Length definition
+#define MAX_LEN_OF_RSNIE 90
+#define MIN_LEN_OF_RSNIE 8
+
+//EAP Packet Type
+#define EAPPacket 0
+#define EAPOLStart 1
+#define EAPOLLogoff 2
+#define EAPOLKey 3
+#define EAPOLASFAlert 4
+#define EAPTtypeMax 5
+
+#define EAPOL_MSG_INVALID 0
+#define EAPOL_PAIR_MSG_1 1
+#define EAPOL_PAIR_MSG_2 2
+#define EAPOL_PAIR_MSG_3 3
+#define EAPOL_PAIR_MSG_4 4
+#define EAPOL_GROUP_MSG_1 5
+#define EAPOL_GROUP_MSG_2 6
+
+#define PAIRWISEKEY 1
+#define GROUPKEY 0
+
+// Retry timer counter initial value
+#define PEER_MSG1_RETRY_TIMER_CTR 0
+#define PEER_MSG3_RETRY_TIMER_CTR 10
+#define GROUP_MSG1_RETRY_TIMER_CTR 20
+
+
+#define EAPOL_START_DISABLE 0
+#define EAPOL_START_PSK 1
+#define EAPOL_START_1X 2
+
+#define MIX_CIPHER_WPA_TKIP_ON(x) (((x) & 0x08) != 0)
+#define MIX_CIPHER_WPA_AES_ON(x) (((x) & 0x04) != 0)
+#define MIX_CIPHER_WPA2_TKIP_ON(x) (((x) & 0x02) != 0)
+#define MIX_CIPHER_WPA2_AES_ON(x) (((x) & 0x01) != 0)
+
+#define ROUND_UP(__x, __y) \
+ (((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1)))
+
+#define ADD_ONE_To_64BIT_VAR(_V) \
+{ \
+ UCHAR cnt = LEN_KEY_DESC_REPLAY; \
+ do \
+ { \
+ cnt--; \
+ _V[cnt]++; \
+ if (cnt == 0) \
+ break; \
+ }while (_V[cnt] == 0); \
+}
+
+#define IS_WPA_CAPABILITY(a) (((a) >= Ndis802_11AuthModeWPA) && ((a) <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
+
+// EAPOL Key Information definition within Key descriptor format
+typedef struct PACKED _KEY_INFO
+{
+#ifdef RT_BIG_ENDIAN
+ UCHAR KeyAck:1;
+ UCHAR Install:1;
+ UCHAR KeyIndex:2;
+ UCHAR KeyType:1;
+ UCHAR KeyDescVer:3;
+ UCHAR Rsvd:3;
+ UCHAR EKD_DL:1; // EKD for AP; DL for STA
+ UCHAR Request:1;
+ UCHAR Error:1;
+ UCHAR Secure:1;
+ UCHAR KeyMic:1;
+#else
+ UCHAR KeyMic:1;
+ UCHAR Secure:1;
+ UCHAR Error:1;
+ UCHAR Request:1;
+ UCHAR EKD_DL:1; // EKD for AP; DL for STA
+ UCHAR Rsvd:3;
+ UCHAR KeyDescVer:3;
+ UCHAR KeyType:1;
+ UCHAR KeyIndex:2;
+ UCHAR Install:1;
+ UCHAR KeyAck:1;
+#endif
+} KEY_INFO, *PKEY_INFO;
+
+// EAPOL Key descriptor format
+typedef struct PACKED _KEY_DESCRIPTER
+{
+ UCHAR Type;
+ KEY_INFO KeyInfo;
+ UCHAR KeyLength[2];
+ UCHAR ReplayCounter[LEN_KEY_DESC_REPLAY];
+ UCHAR KeyNonce[LEN_KEY_DESC_NONCE];
+ UCHAR KeyIv[LEN_KEY_DESC_IV];
+ UCHAR KeyRsc[LEN_KEY_DESC_RSC];
+ UCHAR KeyId[LEN_KEY_DESC_ID];
+ UCHAR KeyMic[LEN_KEY_DESC_MIC];
+ UCHAR KeyDataLen[2];
+ UCHAR KeyData[MAX_LEN_OF_RSNIE];
+} KEY_DESCRIPTER, *PKEY_DESCRIPTER;
+
+typedef struct PACKED _EAPOL_PACKET
+{
+ UCHAR ProVer;
+ UCHAR ProType;
+ UCHAR Body_Len[2];
+ KEY_DESCRIPTER KeyDesc;
+} EAPOL_PACKET, *PEAPOL_PACKET;
+
+//802.11i D10 page 83
+typedef struct PACKED _GTK_ENCAP
+{
+#ifndef RT_BIG_ENDIAN
+ UCHAR Kid:2;
+ UCHAR tx:1;
+ UCHAR rsv:5;
+ UCHAR rsv1;
+#else
+ UCHAR rsv:5;
+ UCHAR tx:1;
+ UCHAR Kid:2;
+ UCHAR rsv1;
+#endif
+ UCHAR GTK[TKIP_GTK_LENGTH];
+} GTK_ENCAP, *PGTK_ENCAP;
+
+typedef struct PACKED _KDE_ENCAP
+{
+ UCHAR Type;
+ UCHAR Len;
+ UCHAR OUI[3];
+ UCHAR DataType;
+ GTK_ENCAP GTKEncap;
+} KDE_ENCAP, *PKDE_ENCAP;
+
+// For WPA1
+typedef struct PACKED _RSNIE {
+ UCHAR oui[4];
+ USHORT version;
+ UCHAR mcast[4];
+ USHORT ucount;
+ struct PACKED {
+ UCHAR oui[4];
+ }ucast[1];
+} RSNIE, *PRSNIE;
+
+// For WPA2
+typedef struct PACKED _RSNIE2 {
+ USHORT version;
+ UCHAR mcast[4];
+ USHORT ucount;
+ struct PACKED {
+ UCHAR oui[4];
+ }ucast[1];
+} RSNIE2, *PRSNIE2;
+
+// AKM Suite
+typedef struct PACKED _RSNIE_AUTH {
+ USHORT acount;
+ struct PACKED {
+ UCHAR oui[4];
+ }auth[1];
+} RSNIE_AUTH,*PRSNIE_AUTH;
+
+typedef union PACKED _RSN_CAPABILITIES {
+ struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT Rsvd:10;
+ USHORT GTKSA_R_Counter:2;
+ USHORT PTKSA_R_Counter:2;
+ USHORT No_Pairwise:1;
+ USHORT PreAuth:1;
+#else
+ USHORT PreAuth:1;
+ USHORT No_Pairwise:1;
+ USHORT PTKSA_R_Counter:2;
+ USHORT GTKSA_R_Counter:2;
+ USHORT Rsvd:10;
+#endif
+ } field;
+ USHORT word;
+} RSN_CAPABILITIES, *PRSN_CAPABILITIES;
+
+typedef struct PACKED _EAP_HDR {
+ UCHAR ProVer;
+ UCHAR ProType;
+ UCHAR Body_Len[2];
+ UCHAR code;
+ UCHAR identifier;
+ UCHAR length[2]; // including code and identifier, followed by length-2 octets of data
+} EAP_HDR, *PEAP_HDR;
+
+// For supplicant state machine states. 802.11i Draft 4.1, p. 97
+// We simplified it
+typedef enum _WpaState
+{
+ SS_NOTUSE, // 0
+ SS_START, // 1
+ SS_WAIT_MSG_3, // 2
+ SS_WAIT_GROUP, // 3
+ SS_FINISH, // 4
+ SS_KEYUPDATE, // 5
+} WPA_STATE;
+
+//
+// The definition of the cipher combination
+//
+// bit3 bit2 bit1 bit0
+// +------------+------------+
+// | WPA | WPA2 |
+// +------+-----+------+-----+
+// | TKIP | AES | TKIP | AES |
+// | 0 | 1 | 1 | 0 | -> 0x06
+// | 0 | 1 | 1 | 1 | -> 0x07
+// | 1 | 0 | 0 | 1 | -> 0x09
+// | 1 | 0 | 1 | 1 | -> 0x0B
+// | 1 | 1 | 0 | 1 | -> 0x0D
+// | 1 | 1 | 1 | 0 | -> 0x0E
+// | 1 | 1 | 1 | 1 | -> 0x0F
+// +------+-----+------+-----+
+//
+typedef enum _WpaMixPairCipher
+{
+ MIX_CIPHER_NOTUSE = 0x00,
+ WPA_NONE_WPA2_TKIPAES = 0x03, // WPA2-TKIPAES
+ WPA_AES_WPA2_TKIP = 0x06,
+ WPA_AES_WPA2_TKIPAES = 0x07,
+ WPA_TKIP_WPA2_AES = 0x09,
+ WPA_TKIP_WPA2_TKIPAES = 0x0B,
+ WPA_TKIPAES_WPA2_NONE = 0x0C, // WPA-TKIPAES
+ WPA_TKIPAES_WPA2_AES = 0x0D,
+ WPA_TKIPAES_WPA2_TKIP = 0x0E,
+ WPA_TKIPAES_WPA2_TKIPAES = 0x0F,
+} WPA_MIX_PAIR_CIPHER;
+
+typedef struct PACKED _RSN_IE_HEADER_STRUCT {
+ UCHAR Eid;
+ UCHAR Length;
+ USHORT Version; // Little endian format
+} RSN_IE_HEADER_STRUCT, *PRSN_IE_HEADER_STRUCT;
+
+// Cipher suite selector types
+typedef struct PACKED _CIPHER_SUITE_STRUCT {
+ UCHAR Oui[3];
+ UCHAR Type;
+} CIPHER_SUITE_STRUCT, *PCIPHER_SUITE_STRUCT;
+
+// Authentication and Key Management suite selector
+typedef struct PACKED _AKM_SUITE_STRUCT {
+ UCHAR Oui[3];
+ UCHAR Type;
+} AKM_SUITE_STRUCT, *PAKM_SUITE_STRUCT;
+
+// RSN capability
+typedef struct PACKED _RSN_CAPABILITY {
+ USHORT Rsv:10;
+ USHORT GTKSAReplayCnt:2;
+ USHORT PTKSAReplayCnt:2;
+ USHORT NoPairwise:1;
+ USHORT PreAuth:1;
+} RSN_CAPABILITY, *PRSN_CAPABILITY;
+
+#endif
diff --git a/drivers/staging/rtl8187se/dot11d.h b/drivers/staging/rtl8187se/dot11d.h
index 49f53fe52af..2417da99529 100644
--- a/drivers/staging/rtl8187se/dot11d.h
+++ b/drivers/staging/rtl8187se/dot11d.h
@@ -1,101 +1,101 @@
-#ifndef __INC_DOT11D_H
-#define __INC_DOT11D_H
-
-#include "ieee80211.h"
-
-//#define ENABLE_DOT11D
-
-//#define DOT11D_MAX_CHNL_NUM 83
-
-typedef struct _CHNL_TXPOWER_TRIPLE {
- u8 FirstChnl;
- u8 NumChnls;
- u8 MaxTxPowerInDbm;
-}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
-
-typedef enum _DOT11D_STATE {
- DOT11D_STATE_NONE = 0,
- DOT11D_STATE_LEARNED,
- DOT11D_STATE_DONE,
-}DOT11D_STATE;
-
-typedef struct _RT_DOT11D_INFO {
- //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
-
- bool bEnabled; // dot11MultiDomainCapabilityEnabled
-
- u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
- u8 CountryIeBuf[MAX_IE_LEN];
- u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
- u8 CountryIeWatchdog;
-
- u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
- //u8 ChnlListLen; // #Bytes valid in ChnlList[].
- //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
- u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
-
- DOT11D_STATE State;
-}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
-#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
-
-#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
-
-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-
-#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
- (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
- FALSE : \
- (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
-
-#define CIE_WATCHDOG_TH 1
-#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
-#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
-
-#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
-
-
-void
-Dot11d_Init(
- struct ieee80211_device *dev
- );
-
-void
-Dot11d_Reset(
- struct ieee80211_device *dev
- );
-
-void
-Dot11d_UpdateCountryIe(
- struct ieee80211_device *dev,
- u8 * pTaddr,
- u16 CoutryIeLen,
- u8 * pCoutryIe
- );
-
-u8
-DOT11D_GetMaxTxPwrInDbm(
- struct ieee80211_device *dev,
- u8 Channel
- );
-
-void
-DOT11D_ScanComplete(
- struct ieee80211_device * dev
- );
-
-int IsLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-);
-
-int ToLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-);
-
-#endif // #ifndef __INC_DOT11D_H
+#ifndef __INC_DOT11D_H
+#define __INC_DOT11D_H
+
+#include "ieee80211.h"
+
+//#define ENABLE_DOT11D
+
+//#define DOT11D_MAX_CHNL_NUM 83
+
+typedef struct _CHNL_TXPOWER_TRIPLE {
+ u8 FirstChnl;
+ u8 NumChnls;
+ u8 MaxTxPowerInDbm;
+}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
+
+typedef enum _DOT11D_STATE {
+ DOT11D_STATE_NONE = 0,
+ DOT11D_STATE_LEARNED,
+ DOT11D_STATE_DONE,
+}DOT11D_STATE;
+
+typedef struct _RT_DOT11D_INFO {
+ //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
+
+ bool bEnabled; // dot11MultiDomainCapabilityEnabled
+
+ u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
+ u8 CountryIeBuf[MAX_IE_LEN];
+ u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
+ u8 CountryIeWatchdog;
+
+ u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
+ //u8 ChnlListLen; // #Bytes valid in ChnlList[].
+ //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
+ u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
+
+ DOT11D_STATE State;
+}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
+#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
+#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
+#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
+
+#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
+#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
+
+#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+
+#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
+ (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
+ FALSE : \
+ (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
+
+#define CIE_WATCHDOG_TH 1
+#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
+#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
+#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
+
+#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
+
+
+void
+Dot11d_Init(
+ struct ieee80211_device *dev
+ );
+
+void
+Dot11d_Reset(
+ struct ieee80211_device *dev
+ );
+
+void
+Dot11d_UpdateCountryIe(
+ struct ieee80211_device *dev,
+ u8 * pTaddr,
+ u16 CoutryIeLen,
+ u8 * pCoutryIe
+ );
+
+u8
+DOT11D_GetMaxTxPwrInDbm(
+ struct ieee80211_device *dev,
+ u8 Channel
+ );
+
+void
+DOT11D_ScanComplete(
+ struct ieee80211_device * dev
+ );
+
+int IsLegalChannel(
+ struct ieee80211_device * dev,
+ u8 channel
+);
+
+int ToLegalChannel(
+ struct ieee80211_device * dev,
+ u8 channel
+);
+
+#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.c b/drivers/staging/rtl8187se/ieee80211/dot11d.c
index 5d8b752fc0f..54bcdcf1d33 100644
--- a/drivers/staging/rtl8187se/ieee80211/dot11d.c
+++ b/drivers/staging/rtl8187se/ieee80211/dot11d.c
@@ -1,246 +1,246 @@
-#ifdef ENABLE_DOT11D
-//-----------------------------------------------------------------------------
-// File:
-// Dot11d.c
-//
-// Description:
-// Implement 802.11d.
-//
-//-----------------------------------------------------------------------------
-
-#include "dot11d.h"
-
-void
-Dot11d_Init(struct ieee80211_device *ieee)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
-
- pDot11dInfo->bEnabled = 0;
-
- pDot11dInfo->State = DOT11D_STATE_NONE;
- pDot11dInfo->CountryIeLen = 0;
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- RESET_CIE_WATCHDOG(ieee);
-
- printk("Dot11d_Init()\n");
-}
-
-//
-// Description:
-// Reset to the state as we are just entering a regulatory domain.
-//
-void
-Dot11d_Reset(struct ieee80211_device *ieee)
-{
- u32 i;
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
-
- // Clear old channel map
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- // Set new channel map
- for (i=1; i<=11; i++) {
- (pDot11dInfo->channel_map)[i] = 1;
- }
- for (i=12; i<=14; i++) {
- (pDot11dInfo->channel_map)[i] = 2;
- }
-
- pDot11dInfo->State = DOT11D_STATE_NONE;
- pDot11dInfo->CountryIeLen = 0;
- RESET_CIE_WATCHDOG(ieee);
-
- //printk("Dot11d_Reset()\n");
-}
-
-//
-// Description:
-// Update country IE from Beacon or Probe Resopnse
-// and configure PHY for operation in the regulatory domain.
-//
-// TODO:
-// Configure Tx power.
-//
-// Assumption:
-// 1. IS_DOT11D_ENABLE() is TRUE.
-// 2. Input IE is an valid one.
-//
-void
-Dot11d_UpdateCountryIe(
- struct ieee80211_device *dev,
- u8 * pTaddr,
- u16 CoutryIeLen,
- u8 * pCoutryIe
- )
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 i, j, NumTriples, MaxChnlNum;
- PCHNL_TXPOWER_TRIPLE pTriple;
-
- if((CoutryIeLen - 3)%3 != 0)
- {
- printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
- Dot11d_Reset(dev);
- return;
- }
-
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- MaxChnlNum = 0;
- NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
- pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
- for(i = 0; i < NumTriples; i++)
- {
- if(MaxChnlNum >= pTriple->FirstChnl)
- { // It is not in a monotonically increasing order, so stop processing.
- printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
- Dot11d_Reset(dev);
- return;
- }
- if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
- { // It is not a valid set of channel id, so stop processing.
- printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
- Dot11d_Reset(dev);
- return;
- }
-
- for(j = 0 ; j < pTriple->NumChnls; j++)
- {
- pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
- pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
- MaxChnlNum = pTriple->FirstChnl + j;
- }
-
- pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
- }
-#if 1
- //printk("Dot11d_UpdateCountryIe(): Channel List:\n");
- printk("Channel List:");
- for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
- if(pDot11dInfo->channel_map[i] > 0)
- printk(" %d", i);
- printk("\n");
-#endif
-
- UPDATE_CIE_SRC(dev, pTaddr);
-
- pDot11dInfo->CountryIeLen = CoutryIeLen;
- memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
- pDot11dInfo->State = DOT11D_STATE_LEARNED;
-}
-
-void dump_chnl_map(u8 * channel_map)
-{
- int i;
- printk("Channel List:");
- for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
- if(channel_map[i] > 0)
- printk(" %d(%d)", i, channel_map[i]);
- printk("\n");
-}
-
-u8
-DOT11D_GetMaxTxPwrInDbm(
- struct ieee80211_device *dev,
- u8 Channel
- )
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 MaxTxPwrInDbm = 255;
-
- if(MAX_CHANNEL_NUMBER < Channel)
- {
- printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
- return MaxTxPwrInDbm;
- }
- if(pDot11dInfo->channel_map[Channel])
- {
- MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
- }
-
- return MaxTxPwrInDbm;
-}
-
-
-void
-DOT11D_ScanComplete(
- struct ieee80211_device * dev
- )
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-
- switch(pDot11dInfo->State)
- {
- case DOT11D_STATE_LEARNED:
- pDot11dInfo->State = DOT11D_STATE_DONE;
- break;
-
- case DOT11D_STATE_DONE:
- if( GET_CIE_WATCHDOG(dev) == 0 )
- { // Reset country IE if previous one is gone.
- Dot11d_Reset(dev);
- }
- break;
- case DOT11D_STATE_NONE:
- break;
- }
-}
-
-int IsLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-
- if(MAX_CHANNEL_NUMBER < channel)
- {
- printk("IsLegalChannel(): Invalid Channel\n");
- return 0;
- }
- if(pDot11dInfo->channel_map[channel] > 0)
- return 1;
- return 0;
-}
-
-int ToLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 default_chn = 0;
- u32 i = 0;
-
- for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
- {
- if(pDot11dInfo->channel_map[i] > 0)
- {
- default_chn = i;
- break;
- }
- }
-
- if(MAX_CHANNEL_NUMBER < channel)
- {
- printk("IsLegalChannel(): Invalid Channel\n");
- return default_chn;
- }
-
- if(pDot11dInfo->channel_map[channel] > 0)
- return channel;
-
- return default_chn;
-}
-
-#if 0
-EXPORT_SYMBOL(Dot11d_Init);
-EXPORT_SYMBOL(Dot11d_Reset);
-EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
-EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
-EXPORT_SYMBOL(DOT11D_ScanComplete);
-EXPORT_SYMBOL(IsLegalChannel);
-EXPORT_SYMBOL(ToLegalChannel);
-#endif
-#endif
+#ifdef ENABLE_DOT11D
+//-----------------------------------------------------------------------------
+// File:
+// Dot11d.c
+//
+// Description:
+// Implement 802.11d.
+//
+//-----------------------------------------------------------------------------
+
+#include "dot11d.h"
+
+void
+Dot11d_Init(struct ieee80211_device *ieee)
+{
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
+
+ pDot11dInfo->bEnabled = 0;
+
+ pDot11dInfo->State = DOT11D_STATE_NONE;
+ pDot11dInfo->CountryIeLen = 0;
+ memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
+ memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
+ RESET_CIE_WATCHDOG(ieee);
+
+ printk("Dot11d_Init()\n");
+}
+
+//
+// Description:
+// Reset to the state as we are just entering a regulatory domain.
+//
+void
+Dot11d_Reset(struct ieee80211_device *ieee)
+{
+ u32 i;
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
+
+ // Clear old channel map
+ memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
+ memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
+ // Set new channel map
+ for (i=1; i<=11; i++) {
+ (pDot11dInfo->channel_map)[i] = 1;
+ }
+ for (i=12; i<=14; i++) {
+ (pDot11dInfo->channel_map)[i] = 2;
+ }
+
+ pDot11dInfo->State = DOT11D_STATE_NONE;
+ pDot11dInfo->CountryIeLen = 0;
+ RESET_CIE_WATCHDOG(ieee);
+
+ //printk("Dot11d_Reset()\n");
+}
+
+//
+// Description:
+// Update country IE from Beacon or Probe Resopnse
+// and configure PHY for operation in the regulatory domain.
+//
+// TODO:
+// Configure Tx power.
+//
+// Assumption:
+// 1. IS_DOT11D_ENABLE() is TRUE.
+// 2. Input IE is an valid one.
+//
+void
+Dot11d_UpdateCountryIe(
+ struct ieee80211_device *dev,
+ u8 * pTaddr,
+ u16 CoutryIeLen,
+ u8 * pCoutryIe
+ )
+{
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+ u8 i, j, NumTriples, MaxChnlNum;
+ PCHNL_TXPOWER_TRIPLE pTriple;
+
+ if((CoutryIeLen - 3)%3 != 0)
+ {
+ printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
+ Dot11d_Reset(dev);
+ return;
+ }
+
+ memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
+ memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
+ MaxChnlNum = 0;
+ NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
+ pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
+ for(i = 0; i < NumTriples; i++)
+ {
+ if(MaxChnlNum >= pTriple->FirstChnl)
+ { // It is not in a monotonically increasing order, so stop processing.
+ printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
+ Dot11d_Reset(dev);
+ return;
+ }
+ if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
+ { // It is not a valid set of channel id, so stop processing.
+ printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
+ Dot11d_Reset(dev);
+ return;
+ }
+
+ for(j = 0 ; j < pTriple->NumChnls; j++)
+ {
+ pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
+ pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
+ MaxChnlNum = pTriple->FirstChnl + j;
+ }
+
+ pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
+ }
+#if 1
+ //printk("Dot11d_UpdateCountryIe(): Channel List:\n");
+ printk("Channel List:");
+ for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
+ if(pDot11dInfo->channel_map[i] > 0)
+ printk(" %d", i);
+ printk("\n");
+#endif
+
+ UPDATE_CIE_SRC(dev, pTaddr);
+
+ pDot11dInfo->CountryIeLen = CoutryIeLen;
+ memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
+ pDot11dInfo->State = DOT11D_STATE_LEARNED;
+}
+
+void dump_chnl_map(u8 * channel_map)
+{
+ int i;
+ printk("Channel List:");
+ for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
+ if(channel_map[i] > 0)
+ printk(" %d(%d)", i, channel_map[i]);
+ printk("\n");
+}
+
+u8
+DOT11D_GetMaxTxPwrInDbm(
+ struct ieee80211_device *dev,
+ u8 Channel
+ )
+{
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+ u8 MaxTxPwrInDbm = 255;
+
+ if(MAX_CHANNEL_NUMBER < Channel)
+ {
+ printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
+ return MaxTxPwrInDbm;
+ }
+ if(pDot11dInfo->channel_map[Channel])
+ {
+ MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
+ }
+
+ return MaxTxPwrInDbm;
+}
+
+
+void
+DOT11D_ScanComplete(
+ struct ieee80211_device * dev
+ )
+{
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+
+ switch(pDot11dInfo->State)
+ {
+ case DOT11D_STATE_LEARNED:
+ pDot11dInfo->State = DOT11D_STATE_DONE;
+ break;
+
+ case DOT11D_STATE_DONE:
+ if( GET_CIE_WATCHDOG(dev) == 0 )
+ { // Reset country IE if previous one is gone.
+ Dot11d_Reset(dev);
+ }
+ break;
+ case DOT11D_STATE_NONE:
+ break;
+ }
+}
+
+int IsLegalChannel(
+ struct ieee80211_device * dev,
+ u8 channel
+)
+{
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+
+ if(MAX_CHANNEL_NUMBER < channel)
+ {
+ printk("IsLegalChannel(): Invalid Channel\n");
+ return 0;
+ }
+ if(pDot11dInfo->channel_map[channel] > 0)
+ return 1;
+ return 0;
+}
+
+int ToLegalChannel(
+ struct ieee80211_device * dev,
+ u8 channel
+)
+{
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+ u8 default_chn = 0;
+ u32 i = 0;
+
+ for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
+ {
+ if(pDot11dInfo->channel_map[i] > 0)
+ {
+ default_chn = i;
+ break;
+ }
+ }
+
+ if(MAX_CHANNEL_NUMBER < channel)
+ {
+ printk("IsLegalChannel(): Invalid Channel\n");
+ return default_chn;
+ }
+
+ if(pDot11dInfo->channel_map[channel] > 0)
+ return channel;
+
+ return default_chn;
+}
+
+#if 0
+EXPORT_SYMBOL(Dot11d_Init);
+EXPORT_SYMBOL(Dot11d_Reset);
+EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
+EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
+EXPORT_SYMBOL(DOT11D_ScanComplete);
+EXPORT_SYMBOL(IsLegalChannel);
+EXPORT_SYMBOL(ToLegalChannel);
+#endif
+#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.h b/drivers/staging/rtl8187se/ieee80211/dot11d.h
index 64bcf15bd21..82576b519cc 100644
--- a/drivers/staging/rtl8187se/ieee80211/dot11d.h
+++ b/drivers/staging/rtl8187se/ieee80211/dot11d.h
@@ -1,102 +1,102 @@
-#ifndef __INC_DOT11D_H
-#define __INC_DOT11D_H
-
-#include "ieee80211.h"
-
-//#define ENABLE_DOT11D
-
-//#define DOT11D_MAX_CHNL_NUM 83
-
-typedef struct _CHNL_TXPOWER_TRIPLE {
- u8 FirstChnl;
- u8 NumChnls;
- u8 MaxTxPowerInDbm;
-}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
-
-typedef enum _DOT11D_STATE {
- DOT11D_STATE_NONE = 0,
- DOT11D_STATE_LEARNED,
- DOT11D_STATE_DONE,
-}DOT11D_STATE;
-
-typedef struct _RT_DOT11D_INFO {
- //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
-
- bool bEnabled; // dot11MultiDomainCapabilityEnabled
-
- u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
- u8 CountryIeBuf[MAX_IE_LEN];
- u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
- u8 CountryIeWatchdog;
-
- u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
- //u8 ChnlListLen; // #Bytes valid in ChnlList[].
- //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
- u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
-
- DOT11D_STATE State;
-}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
-#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
-
-#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
-
-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-
-#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
- (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
- FALSE : \
- (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
-
-#define CIE_WATCHDOG_TH 1
-#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
-#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
-
-#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
-
-
-void
-Dot11d_Init(
- struct ieee80211_device *dev
- );
-
-void
-Dot11d_Reset(
- struct ieee80211_device *dev
- );
-
-void
-Dot11d_UpdateCountryIe(
- struct ieee80211_device *dev,
- u8 * pTaddr,
- u16 CoutryIeLen,
- u8 * pCoutryIe
- );
-
-u8
-DOT11D_GetMaxTxPwrInDbm(
- struct ieee80211_device *dev,
- u8 Channel
- );
-
-void
-DOT11D_ScanComplete(
- struct ieee80211_device * dev
- );
-
-int IsLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-);
-
-int ToLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-);
-
-void dump_chnl_map(u8 * channel_map);
-#endif // #ifndef __INC_DOT11D_H
+#ifndef __INC_DOT11D_H
+#define __INC_DOT11D_H
+
+#include "ieee80211.h"
+
+//#define ENABLE_DOT11D
+
+//#define DOT11D_MAX_CHNL_NUM 83
+
+typedef struct _CHNL_TXPOWER_TRIPLE {
+ u8 FirstChnl;
+ u8 NumChnls;
+ u8 MaxTxPowerInDbm;
+}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
+
+typedef enum _DOT11D_STATE {
+ DOT11D_STATE_NONE = 0,
+ DOT11D_STATE_LEARNED,
+ DOT11D_STATE_DONE,
+}DOT11D_STATE;
+
+typedef struct _RT_DOT11D_INFO {
+ //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
+
+ bool bEnabled; // dot11MultiDomainCapabilityEnabled
+
+ u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
+ u8 CountryIeBuf[MAX_IE_LEN];
+ u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
+ u8 CountryIeWatchdog;
+
+ u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
+ //u8 ChnlListLen; // #Bytes valid in ChnlList[].
+ //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
+ u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
+
+ DOT11D_STATE State;
+}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
+#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
+#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
+#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
+
+#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
+#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
+
+#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+
+#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
+ (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
+ FALSE : \
+ (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
+
+#define CIE_WATCHDOG_TH 1
+#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
+#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
+#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
+
+#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
+
+
+void
+Dot11d_Init(
+ struct ieee80211_device *dev
+ );
+
+void
+Dot11d_Reset(
+ struct ieee80211_device *dev
+ );
+
+void
+Dot11d_UpdateCountryIe(
+ struct ieee80211_device *dev,
+ u8 * pTaddr,
+ u16 CoutryIeLen,
+ u8 * pCoutryIe
+ );
+
+u8
+DOT11D_GetMaxTxPwrInDbm(
+ struct ieee80211_device *dev,
+ u8 Channel
+ );
+
+void
+DOT11D_ScanComplete(
+ struct ieee80211_device * dev
+ );
+
+int IsLegalChannel(
+ struct ieee80211_device * dev,
+ u8 channel
+);
+
+int ToLegalChannel(
+ struct ieee80211_device * dev,
+ u8 channel
+);
+
+void dump_chnl_map(u8 * channel_map);
+#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
index 6aad61e7804..d1295e56fd4 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
@@ -842,14 +842,14 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
{
- printk("return error out, len:%d\n", len);
+ printk("return error out, len:%zu\n", len);
return -EINVAL;
}
if (len)
{
if (len != ie[1]+2){
- printk("len:%d, ie:%d\n", len, ie[1]);
+ printk("len:%zu, ie:%d\n", len, ie[1]);
return -EINVAL;
}
buf = kmalloc(len, GFP_KERNEL);
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index ff1f23f99f2..6ecd12de429 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -3161,7 +3161,7 @@ void rtl8180_prepare_beacon(struct net_device *dev)
return ;
}
- //while(! *tail & (1<<31)){
+ //while(! (*tail & (1<<31))){
*tail= 0; // zeroes header
*tail = *tail| (1<<29) ; //fist segment of the packet
diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c
index 742dc11fcac..93b5a7bb255 100644
--- a/drivers/staging/rtl8187se/r8180_dm.c
+++ b/drivers/staging/rtl8187se/r8180_dm.c
@@ -1,1725 +1,1725 @@
-//#include "r8180.h"
-#include "r8180_dm.h"
-#include "r8180_hw.h"
-#include "r8180_93cx6.h"
-//{by amy 080312
-
-//
-// Description:
-// Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
-//
-//+by amy 080312
-#define RATE_ADAPTIVE_TIMER_PERIOD 300
-
-bool CheckHighPower(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
-
- if(!priv->bRegHighPowerMechanism)
- {
- return false;
- }
-
- if(ieee->state == IEEE80211_LINKED_SCANNING)
- {
- return false;
- }
-
- return true;
-}
-
-//
-// Description:
-// Update Tx power level if necessary.
-// See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
-//
-// Note:
-// The reason why we udpate Tx power level here instead of DoRxHighPower()
-// is the number of IO to change Tx power is much more than chane TR switch
-// and they are related to OFDM and MAC registers.
-// So, we don't want to update it so frequently in per-Rx packet base.
-//
-void
-DoTxHighPower(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 HiPwrUpperTh = 0;
- u16 HiPwrLowerTh = 0;
- u8 RSSIHiPwrUpperTh;
- u8 RSSIHiPwrLowerTh;
- u8 u1bTmp;
- char OfdmTxPwrIdx, CckTxPwrIdx;
-
- //printk("----> DoTxHighPower()\n");
-
- HiPwrUpperTh = priv->RegHiPwrUpperTh;
- HiPwrLowerTh = priv->RegHiPwrLowerTh;
-
- HiPwrUpperTh = HiPwrUpperTh * 10;
- HiPwrLowerTh = HiPwrLowerTh * 10;
- RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh;
- RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh;
-
- //lzm add 080826
- OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
- CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
-
- // printk("DoTxHighPower() - UndecoratedSmoothedSS:%d, CurCCKRSSI = %d , bCurCCKPkt= %d \n", priv->UndecoratedSmoothedSS, priv->CurCCKRSSI, priv->bCurCCKPkt );
-
- if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
- (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
- {
- // Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah
-
- // printk("=====>DoTxHighPower() - High Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrUpperTh );
- priv->bToUpdateTxPwr = true;
- u1bTmp= read_nic_byte(dev, CCK_TXAGC);
-
- // If it never enter High Power.
- if( CckTxPwrIdx == u1bTmp)
- {
- u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
- write_nic_byte(dev, CCK_TXAGC, u1bTmp);
-
- u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
- u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
- write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
- }
-
- }
- else if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
- (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))
- {
- // printk("DoTxHighPower() - lower Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrLowerTh );
- if(priv->bToUpdateTxPwr)
- {
- priv->bToUpdateTxPwr = false;
- //SD3 required.
- u1bTmp= read_nic_byte(dev, CCK_TXAGC);
- if(u1bTmp < CckTxPwrIdx)
- {
- //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
- //write_nic_byte(dev, CCK_TXAGC, u1bTmp);
- write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);
- }
-
- u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
- if(u1bTmp < OfdmTxPwrIdx)
- {
- //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
- //write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
- write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
- }
- }
- }
-
- //printk("<---- DoTxHighPower()\n");
-}
-
-
-//
-// Description:
-// Callback function of UpdateTxPowerWorkItem.
-// Because of some event happend, e.g. CCX TPC, High Power Mechanism,
-// We update Tx power of current channel again.
-//
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-void rtl8180_tx_pw_wq (struct work_struct *work)
-{
-// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
-// struct ieee80211_device * ieee = (struct ieee80211_device*)
-// container_of(work, struct ieee80211_device, watch_dog_wq);
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);
- struct net_device *dev = ieee->dev;
-#else
-void rtl8180_tx_pw_wq(struct net_device *dev)
-{
- // struct r8180_priv *priv = ieee80211_priv(dev);
-#endif
-
-// printk("----> UpdateTxPowerWorkItemCallback()\n");
-
- DoTxHighPower(dev);
-
-// printk("<---- UpdateTxPowerWorkItemCallback()\n");
-}
-
-
-//
-// Description:
-// Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise.
-//
-bool
-CheckDig(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
-
- if(!priv->bDigMechanism)
- return false;
-
- if(ieee->state != IEEE80211_LINKED)
- return false;
-
- //if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
- if((priv->ieee80211->rate/5) < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
- return false;
- return true;
-}
-//
-// Description:
-// Implementation of DIG for Zebra and Zebra2.
-//
-void
-DIG_Zebra(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 CCKFalseAlarm, OFDMFalseAlarm;
- u16 OfdmFA1, OfdmFA2;
- int InitialGainStep = 7; // The number of initial gain stages.
- int LowestGainStage = 4; // The capable lowest stage of performing dig workitem.
- u32 AwakePeriodIn2Sec=0;
-
- //printk("---------> DIG_Zebra()\n");
-
- CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
- OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
- OfdmFA1 = 0x15;
- OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
-
-// printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
-// printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
-
- // The number of initial gain steps is different, by Bruce, 2007-04-13.
- if (priv->InitialGain == 0 ) //autoDIG
- { // Advised from SD3 DZ
- priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm)
- }
- //if(pHalData->VersionID != VERSION_8187B_B)
- { // Advised from SD3 DZ
- OfdmFA1 = 0x20;
- }
-
-#if 1 //lzm reserved 080826
- AwakePeriodIn2Sec = (2000-priv ->DozePeriodInPast2Sec);
- //printk("&&& DozePeriod=%d AwakePeriod=%d\n", priv->DozePeriodInPast2Sec, AwakePeriodIn2Sec);
- priv ->DozePeriodInPast2Sec=0;
-
- if(AwakePeriodIn2Sec)
- {
- //RT_TRACE(COMP_DIG, DBG_TRACE, ("DIG: AwakePeriodIn2Sec(%d) - FATh(0x%X , 0x%X) ->",AwakePeriodIn2Sec, OfdmFA1, OfdmFA2));
- // adjuest DIG threshold.
- OfdmFA1 = (u16)((OfdmFA1*AwakePeriodIn2Sec) / 2000) ;
- OfdmFA2 = (u16)((OfdmFA2*AwakePeriodIn2Sec) / 2000) ;
- //RT_TRACE(COMP_DIG, DBG_TRACE, ("( 0x%X , 0x%X)\n", OfdmFA1, OfdmFA2));
- }
- else
- {
- ;//RT_TRACE(COMP_DIG, DBG_WARNING, ("ERROR!! AwakePeriodIn2Sec should not be ZERO!!\n"));
- }
-#endif
-
- InitialGainStep = 8;
- LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.
-
- if (OFDMFalseAlarm > OfdmFA1)
- {
- if (OFDMFalseAlarm > OfdmFA2)
- {
- priv->DIG_NumberFallbackVote++;
- if (priv->DIG_NumberFallbackVote >1)
- {
- //serious OFDM False Alarm, need fallback
- if (priv->InitialGain < InitialGainStep)
- {
- priv->InitialGainBackUp= priv->InitialGain;
-
- priv->InitialGain = (priv->InitialGain + 1);
-// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
-// printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);
- UpdateInitialGain(dev);
- }
- priv->DIG_NumberFallbackVote = 0;
- priv->DIG_NumberUpgradeVote=0;
- }
- }
- else
- {
- if (priv->DIG_NumberFallbackVote)
- priv->DIG_NumberFallbackVote--;
- }
- priv->DIG_NumberUpgradeVote=0;
- }
- else
- {
- if (priv->DIG_NumberFallbackVote)
- priv->DIG_NumberFallbackVote--;
- priv->DIG_NumberUpgradeVote++;
-
- if (priv->DIG_NumberUpgradeVote>9)
- {
- if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)
- {
- priv->InitialGainBackUp= priv->InitialGain;
-
- priv->InitialGain = (priv->InitialGain - 1);
-// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
-// printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);
- UpdateInitialGain(dev);
- }
- priv->DIG_NumberFallbackVote = 0;
- priv->DIG_NumberUpgradeVote=0;
- }
- }
-
-// printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
- //printk("<--------- DIG_Zebra()\n");
-}
-
-//
-// Description:
-// Dispatch DIG implementation according to RF.
-//
-void
-DynamicInitGain(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- switch(priv->rf_chip)
- {
- case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01.
- case RF_ZEBRA4:
- DIG_Zebra( dev );
- break;
-
- default:
- printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
- break;
- }
-}
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-void rtl8180_hw_dig_wq (struct work_struct *work)
-{
-// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
-// struct ieee80211_device * ieee = (struct ieee80211_device*)
-// container_of(work, struct ieee80211_device, watch_dog_wq);
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
- struct net_device *dev = ieee->dev;
-#else
-void rtl8180_hw_dig_wq(struct net_device *dev)
-{
-
-#endif
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- // Read CCK and OFDM False Alarm.
- priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
-
-
- // Adjust Initial Gain dynamically.
- DynamicInitGain(dev);
-
-}
-
-int
-IncludedInSupportedRates(
- struct r8180_priv *priv,
- u8 TxRate )
-{
- u8 rate_len;
- u8 rate_ex_len;
- u8 RateMask = 0x7F;
- u8 idx;
- unsigned short Found = 0;
- u8 NaiveTxRate = TxRate&RateMask;
-
- rate_len = priv->ieee80211->current_network.rates_len;
- rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
- for( idx=0; idx< rate_len; idx++ )
- {
- if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate )
- {
- Found = 1;
- goto found_rate;
- }
- }
- for( idx=0; idx< rate_ex_len; idx++ )
- {
- if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate )
- {
- Found = 1;
- goto found_rate;
- }
- }
- return Found;
- found_rate:
- return Found;
-}
-
-//
-// Description:
-// Get the Tx rate one degree up form the input rate in the supported rates.
-// Return the upgrade rate if it is successed, otherwise return the input rate.
-// By Bruce, 2007-06-05.
-//
-u8
-GetUpgradeTxRate(
- struct net_device *dev,
- u8 rate
- )
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 UpRate;
-
- // Upgrade 1 degree.
- switch(rate)
- {
- case 108: // Up to 54Mbps.
- UpRate = 108;
- break;
-
- case 96: // Up to 54Mbps.
- UpRate = 108;
- break;
-
- case 72: // Up to 48Mbps.
- UpRate = 96;
- break;
-
- case 48: // Up to 36Mbps.
- UpRate = 72;
- break;
-
- case 36: // Up to 24Mbps.
- UpRate = 48;
- break;
-
- case 22: // Up to 18Mbps.
- UpRate = 36;
- break;
-
- case 11: // Up to 11Mbps.
- UpRate = 22;
- break;
-
- case 4: // Up to 5.5Mbps.
- UpRate = 11;
- break;
-
- case 2: // Up to 2Mbps.
- UpRate = 4;
- break;
-
- default:
- printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
- return rate;
- }
- // Check if the rate is valid.
- if(IncludedInSupportedRates(priv, UpRate))
- {
-// printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
- return UpRate;
- }
- else
- {
- //printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
- return rate;
- }
- return rate;
-}
-//
-// Description:
-// Get the Tx rate one degree down form the input rate in the supported rates.
-// Return the degrade rate if it is successed, otherwise return the input rate.
-// By Bruce, 2007-06-05.
-//
-u8
-GetDegradeTxRate(
- struct net_device *dev,
- u8 rate
- )
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 DownRate;
-
- // Upgrade 1 degree.
- switch(rate)
- {
- case 108: // Down to 48Mbps.
- DownRate = 96;
- break;
-
- case 96: // Down to 36Mbps.
- DownRate = 72;
- break;
-
- case 72: // Down to 24Mbps.
- DownRate = 48;
- break;
-
- case 48: // Down to 18Mbps.
- DownRate = 36;
- break;
-
- case 36: // Down to 11Mbps.
- DownRate = 22;
- break;
-
- case 22: // Down to 5.5Mbps.
- DownRate = 11;
- break;
-
- case 11: // Down to 2Mbps.
- DownRate = 4;
- break;
-
- case 4: // Down to 1Mbps.
- DownRate = 2;
- break;
-
- case 2: // Down to 1Mbps.
- DownRate = 2;
- break;
-
- default:
- printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
- return rate;
- }
- // Check if the rate is valid.
- if(IncludedInSupportedRates(priv, DownRate))
- {
-// printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
- return DownRate;
- }
- else
- {
- //printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
- return rate;
- }
- return rate;
-}
-//
-// Helper function to determine if specified data rate is
-// CCK rate.
-// 2005.01.25, by rcnjko.
-//
-bool
-MgntIsCckRate(
- u16 rate
- )
-{
- bool bReturn = false;
-
- if((rate <= 22) && (rate != 12) && (rate != 18))
- {
- bReturn = true;
- }
-
- return bReturn;
-}
-#ifdef CONFIG_RTL818X_S
-//
-// Description:
-// Tx Power tracking mechanism routine on 87SE.
-// Created by Roger, 2007.12.11.
-//
-void
-TxPwrTracking87SE(
- struct net_device *dev
-)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u8 tmpu1Byte, CurrentThermal, Idx;
- char CckTxPwrIdx, OfdmTxPwrIdx;
- //u32 u4bRfReg;
-
- tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
- CurrentThermal = (tmpu1Byte & 0xf0)>>4; //[ 7:4]: thermal meter indication.
- CurrentThermal = (CurrentThermal>0x0c)? 0x0c:CurrentThermal;//lzm add 080826
-
- //printk("TxPwrTracking87SE(): CurrentThermal(%d)\n", CurrentThermal);
-
- if( CurrentThermal != priv->ThermalMeter)
- {
-// printk("TxPwrTracking87SE(): Thermal meter changed!!!\n");
-
- // Update Tx Power level on each channel.
- for(Idx = 1; Idx<15; Idx++)
- {
- CckTxPwrIdx = priv->chtxpwr[Idx];
- OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];
-
- if( CurrentThermal > priv->ThermalMeter )
- { // higher thermal meter.
- CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
- OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
-
- if(CckTxPwrIdx >35)
- CckTxPwrIdx = 35; // Force TxPower to maximal index.
- if(OfdmTxPwrIdx >35)
- OfdmTxPwrIdx = 35;
- }
- else
- { // lower thermal meter.
- CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
- OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
-
- if(CckTxPwrIdx <0)
- CckTxPwrIdx = 0;
- if(OfdmTxPwrIdx <0)
- OfdmTxPwrIdx = 0;
- }
-
- // Update TxPower level on CCK and OFDM resp.
- priv->chtxpwr[Idx] = CckTxPwrIdx;
- priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
- }
-
- // Update TxPower level immediately.
- rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
- }
- priv->ThermalMeter = CurrentThermal;
-}
-void
-StaRateAdaptive87SE(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- unsigned long CurrTxokCnt;
- u16 CurrRetryCnt;
- u16 CurrRetryRate;
- //u16 i,idx;
- unsigned long CurrRxokCnt;
- bool bTryUp = false;
- bool bTryDown = false;
- u8 TryUpTh = 1;
- u8 TryDownTh = 2;
- u32 TxThroughput;
- long CurrSignalStrength;
- bool bUpdateInitialGain = false;
- u8 u1bOfdm=0, u1bCck = 0;
- char OfdmTxPwrIdx, CckTxPwrIdx;
-
- priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
-
-
- CurrRetryCnt = priv->CurrRetryCnt;
- CurrTxokCnt = priv->NumTxOkTotal - priv->LastTxokCnt;
- CurrRxokCnt = priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt;
- CurrSignalStrength = priv->Stats_RecvSignalPower;
- TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes);
- priv->LastTxOKBytes = priv->NumTxOkBytesTotal;
- priv->CurrentOperaRate = priv->ieee80211->rate/5;
- //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);
- //2 Compute retry ratio.
- if (CurrTxokCnt>0)
- {
- CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
- }
- else
- { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
- CurrRetryRate = (u16)(CurrRetryCnt*100/1);
- }
-
-
- //
- // Added by Roger, 2007.01.02.
- // For debug information.
- //
- //printk("\n(1) pHalData->LastRetryRate: %d \n",priv->LastRetryRate);
- //printk("(2) RetryCnt = %d \n", CurrRetryCnt);
- //printk("(3) TxokCnt = %d \n", CurrTxokCnt);
- //printk("(4) CurrRetryRate = %d \n", CurrRetryRate);
- //printk("(5) CurrSignalStrength = %d \n",CurrSignalStrength);
- //printk("(6) TxThroughput is %d\n",TxThroughput);
- //printk("priv->NumTxOkBytesTotal is %d\n",priv->NumTxOkBytesTotal);
-
- priv->LastRetryCnt = priv->CurrRetryCnt;
- priv->LastTxokCnt = priv->NumTxOkTotal;
- priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;
- priv->CurrRetryCnt = 0;
-
- //2No Tx packets, return to init_rate or not?
- if (CurrRetryRate==0 && CurrTxokCnt == 0)
- {
- //
- //After 9 (30*300ms) seconds in this condition, we try to raise rate.
- //
- priv->TryupingCountNoData++;
-
-// printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);
- //[TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00
- if (priv->TryupingCountNoData>30)
- {
- priv->TryupingCountNoData = 0;
- priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
- // Reset Fail Record
- priv->LastFailTxRate = 0;
- priv->LastFailTxRateSS = -200;
- priv->FailTxRateCount = 0;
- }
- goto SetInitialGain;
- }
- else
- {
- priv->TryupingCountNoData=0; //Reset trying up times.
- }
-
-
- //
- // For Netgear case, I comment out the following signal strength estimation,
- // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
- // 2007.04.09, by Roger.
- //
-
- //
- // Restructure rate adaptive as the following main stages:
- // (1) Add retry threshold in 54M upgrading condition with signal strength.
- // (2) Add the mechanism to degrade to CCK rate according to signal strength
- // and retry rate.
- // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
- // situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
- // (4) Add the mehanism of trying to upgrade tx rate.
- // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
- // By Bruce, 2007-06-05.
- //
- //
-
- // 11Mbps or 36Mbps
- // Check more times in these rate(key rates).
- //
- if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
- {
- TryUpTh += 9;
- }
- //
- // Let these rates down more difficult.
- //
- if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
- {
- TryDownTh += 1;
- }
-
- //1 Adjust Rate.
- if (priv->bTryuping == true)
- {
- //2 For Test Upgrading mechanism
- // Note:
- // Sometimes the throughput is upon on the capability bwtween the AP and NIC,
- // thus the low data rate does not improve the performance.
- // We randomly upgrade the data rate and check if the retry rate is improved.
-
- // Upgrading rate did not improve the retry rate, fallback to the original rate.
- if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
- {
- //Not necessary raising rate, fall back rate.
- bTryDown = true;
- //printk("case1-1: Not necessary raising rate, fall back rate....\n");
- //printk("case1-1: pMgntInfo->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",
- // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);
- }
- else
- {
- priv->bTryuping = false;
- }
- }
- else if (CurrSignalStrength > -47 && (CurrRetryRate < 50))
- {
- //2For High Power
- //
- // Added by Roger, 2007.04.09.
- // Return to highest data rate, if signal strength is good enough.
- // SignalStrength threshold(-50dbm) is for RTL8186.
- // Revise SignalStrength threshold to -51dbm.
- //
- // Also need to check retry rate for safety, by Bruce, 2007-06-05.
- if(priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate )
- {
- bTryUp = true;
- // Upgrade Tx Rate directly.
- priv->TryupingCount += TryUpTh;
- }
-// printk("case2: StaRateAdaptive87SE: Power(%d) is high enough!!. \n", CurrSignalStrength);
-
- }
- else if(CurrTxokCnt > 9 && CurrTxokCnt< 100 && CurrRetryRate >= 600)
- {
- //2 For Serious Retry
- //
- // Traffic is not busy but our Tx retry is serious.
- //
- bTryDown = true;
- // Let Rate Mechanism to degrade tx rate directly.
- priv->TryDownCountLowData += TryDownTh;
-// printk("case3: RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);
- }
- else if ( priv->CurrentOperaRate == 108 )
- {
- //2For 54Mbps
- // Air Link
- if ( (CurrRetryRate>26)&&(priv->LastRetryRate>25))
-// if ( (CurrRetryRate>40)&&(priv->LastRetryRate>39))
- {
- //Down to rate 48Mbps.
- bTryDown = true;
- }
- // Cable Link
- else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
-// else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
- {
- //Down to rate 48Mbps.
- bTryDown = true;
- }
-
- if(bTryDown && (CurrSignalStrength < -75)) //cable link
- {
- priv->TryDownCountLowData += TryDownTh;
- }
- //printk("case4---54M \n");
-
- }
- else if ( priv->CurrentOperaRate == 96 )
- {
- //2For 48Mbps
- //Air Link
- if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
-// if ( ((CurrRetryRate>65) && (priv->LastRetryRate>64)))
-
- {
- //Down to rate 36Mbps.
- bTryDown = true;
- }
- //Cable Link
- else if ( ((CurrRetryRate>21) && (priv->LastRetryRate>20)) && (CurrSignalStrength > -74))
- {
- //Down to rate 36Mbps.
- bTryDown = true;
- }
- else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
-// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
- {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- }
- else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)
-// else if ( (CurrRetryRate<28) && (priv->LastRetryRate<8) )
- {
- bTryUp = true;
- }
-
- if(bTryDown && (CurrSignalStrength < -75))
- {
- priv->TryDownCountLowData += TryDownTh;
- }
- //printk("case5---48M \n");
- }
- else if ( priv->CurrentOperaRate == 72 )
- {
- //2For 36Mbps
- if ( (CurrRetryRate>43) && (priv->LastRetryRate>41))
-// if ( (CurrRetryRate>60) && (priv->LastRetryRate>59))
- {
- //Down to rate 24Mbps.
- bTryDown = true;
- }
- else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
-// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
- {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- }
- else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16)) //TO DO: need to consider (RSSI)
-// else if ( (CurrRetryRate<35) && (priv->LastRetryRate<36))
- {
- bTryUp = true;
- }
-
- if(bTryDown && (CurrSignalStrength < -80))
- {
- priv->TryDownCountLowData += TryDownTh;
- }
- //printk("case6---36M \n");
- }
- else if ( priv->CurrentOperaRate == 48 )
- {
- //2For 24Mbps
- // Air Link
- if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
-// if ( ((CurrRetryRate>83) && (priv->LastRetryRate>82)))
- {
- //Down to rate 18Mbps.
- bTryDown = true;
- }
- //Cable Link
- else if ( ((CurrRetryRate>33) && (priv->LastRetryRate>32)) && (CurrSignalStrength > -82) )
-// else if ( ((CurrRetryRate>50) && (priv->LastRetryRate>49)) && (CurrSignalStrength > -82) )
- {
- //Down to rate 18Mbps.
- bTryDown = true;
- }
- else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
-// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
-
- {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- }
- else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)
-// else if ( (CurrRetryRate<40) && (priv->LastRetryRate<41))
- {
- bTryUp = true;
- }
-
- if(bTryDown && (CurrSignalStrength < -82))
- {
- priv->TryDownCountLowData += TryDownTh;
- }
- //printk("case7---24M \n");
- }
- else if ( priv->CurrentOperaRate == 36 )
- {
- //2For 18Mbps
- // original (109, 109)
- //[TRC Dell Lab] (90, 91), Isaiah 2008-02-18 23:24
- // (85, 86), Isaiah 2008-02-18 24:00
- if ( ((CurrRetryRate>85) && (priv->LastRetryRate>86)))
-// if ( ((CurrRetryRate>115) && (priv->LastRetryRate>116)))
- {
- //Down to rate 11Mbps.
- bTryDown = true;
- }
- //[TRC Dell Lab] Isaiah 2008-02-18 23:24
- else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
-// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
- {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- }
- else if ( (CurrRetryRate<22) && (priv->LastRetryRate<23)) //TO DO: need to consider (RSSI)
-// else if ( (CurrRetryRate<42) && (priv->LastRetryRate<43))
- {
- bTryUp = true;
- }
- //printk("case8---18M \n");
- }
- else if ( priv->CurrentOperaRate == 22 )
- {
- //2For 11Mbps
- if (CurrRetryRate>95)
-// if (CurrRetryRate>155)
- {
- bTryDown = true;
- }
- else if ( (CurrRetryRate<29) && (priv->LastRetryRate <30) )//TO DO: need to consider (RSSI)
-// else if ( (CurrRetryRate<49) && (priv->LastRetryRate <50) )
- {
- bTryUp = true;
- }
- //printk("case9---11M \n");
- }
- else if ( priv->CurrentOperaRate == 11 )
- {
- //2For 5.5Mbps
- if (CurrRetryRate>149)
-// if (CurrRetryRate>189)
- {
- bTryDown = true;
- }
- else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
-// else if ( (CurrRetryRate<80) && (priv->LastRetryRate < 85))
-
- {
- bTryUp = true;
- }
- //printk("case10---5.5M \n");
- }
- else if ( priv->CurrentOperaRate == 4 )
- {
- //2For 2 Mbps
- if((CurrRetryRate>99) && (priv->LastRetryRate>99))
-// if((CurrRetryRate>199) && (priv->LastRetryRate>199))
- {
- bTryDown = true;
- }
- else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
-// else if ( (CurrRetryRate < 85) && (priv->LastRetryRate < 90))
- {
- bTryUp = true;
- }
- //printk("case11---2M \n");
- }
- else if ( priv->CurrentOperaRate == 2 )
- {
- //2For 1 Mbps
- if( (CurrRetryRate<70) && (priv->LastRetryRate<75))
-// if( (CurrRetryRate<90) && (priv->LastRetryRate<95))
- {
- bTryUp = true;
- }
- //printk("case12---1M \n");
- }
-
- if(bTryUp && bTryDown)
- printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
-
- //1 Test Upgrading Tx Rate
- // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
- // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
- if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
- && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2)
- {
- if(jiffies% (CurrRetryRate + 101) == 0)
- {
- bTryUp = true;
- priv->bTryuping = true;
- //printk("StaRateAdaptive87SE(): Randomly try upgrading...\n");
- }
- }
-
- //1 Rate Mechanism
- if(bTryUp)
- {
- priv->TryupingCount++;
- priv->TryDownCountLowData = 0;
-
- {
-// printk("UP: pHalData->TryupingCount = %d\n", priv->TryupingCount);
-// printk("UP: TryUpTh(%d)+ (FailTxRateCount(%d))^2 =%d\n",
-// TryUpTh, priv->FailTxRateCount, (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount) );
-// printk("UP: pHalData->bTryuping=%d\n", priv->bTryuping);
-
- }
-
- //
- // Check more times if we need to upgrade indeed.
- // Because the largest value of pHalData->TryupingCount is 0xFFFF and
- // the largest value of pHalData->FailTxRateCount is 0x14,
- // this condition will be satisfied at most every 2 min.
- //
-
- if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
- (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
- {
- priv->TryupingCount = 0;
- //
- // When transfering from CCK to OFDM, DIG is an important issue.
- //
- if(priv->CurrentOperaRate == 22)
- bUpdateInitialGain = true;
-
- // The difference in throughput between 48Mbps and 36Mbps is 8M.
- // So, we must be carefully in this rate scale. Isaiah 2008-02-15.
- //
- if( ((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&
- (priv->FailTxRateCount > 2) )
- priv->RateAdaptivePeriod= (RATE_ADAPTIVE_TIMER_PERIOD/2);
-
- // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.
- // (2)If the signal strength is increased, it may be able to upgrade.
-
- priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
-// printk("StaRateAdaptive87SE(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
-
- //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
- if(priv->CurrentOperaRate ==36)
- {
- priv->bUpdateARFR=true;
- write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
-// printk("UP: ARFR=0xF8F\n");
- }
- else if(priv->bUpdateARFR)
- {
- priv->bUpdateARFR=false;
- write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
-// printk("UP: ARFR=0xFFF\n");
- }
-
- // Update Fail Tx rate and count.
- if(priv->LastFailTxRate != priv->CurrentOperaRate)
- {
- priv->LastFailTxRate = priv->CurrentOperaRate;
- priv->FailTxRateCount = 0;
- priv->LastFailTxRateSS = -200; // Set lowest power.
- }
- }
- }
- else
- {
- if(priv->TryupingCount > 0)
- priv->TryupingCount --;
- }
-
- if(bTryDown)
- {
- priv->TryDownCountLowData++;
- priv->TryupingCount = 0;
- {
-// printk("DN: pHalData->TryDownCountLowData = %d\n",priv->TryDownCountLowData);
-// printk("DN: TryDownTh =%d\n", TryDownTh);
-// printk("DN: pHalData->bTryuping=%d\n", priv->bTryuping);
- }
-
- //Check if Tx rate can be degraded or Test trying upgrading should fallback.
- if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
- {
- priv->TryDownCountLowData = 0;
- priv->bTryuping = false;
- // Update fail information.
- if(priv->LastFailTxRate == priv->CurrentOperaRate)
- {
- priv->FailTxRateCount ++;
- // Record the Tx fail rate signal strength.
- if(CurrSignalStrength > priv->LastFailTxRateSS)
- {
- priv->LastFailTxRateSS = CurrSignalStrength;
- }
- }
- else
- {
- priv->LastFailTxRate = priv->CurrentOperaRate;
- priv->FailTxRateCount = 1;
- priv->LastFailTxRateSS = CurrSignalStrength;
- }
- priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
-
- // Reduce chariot training time at weak signal strength situation. SD3 ED demand.
- //[TRC Dell Lab] Revise Signal Threshold from -75 to -80 , Isaiah 2008-02-18 20:00
- if( (CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72 ))
- {
- priv->CurrentOperaRate = 72;
-// printk("DN: weak signal strength (%d), degrade to 36Mbps\n", CurrSignalStrength);
- }
-
- //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
- if(priv->CurrentOperaRate ==36)
- {
- priv->bUpdateARFR=true;
- write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
-// printk("DN: ARFR=0xF8F\n");
- }
- else if(priv->bUpdateARFR)
- {
- priv->bUpdateARFR=false;
- write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
-// printk("DN: ARFR=0xFFF\n");
- }
-
- //
- // When it is CCK rate, it may need to update initial gain to receive lower power packets.
- //
- if(MgntIsCckRate(priv->CurrentOperaRate))
- {
- bUpdateInitialGain = true;
- }
-// printk("StaRateAdaptive87SE(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
- }
- }
- else
- {
- if(priv->TryDownCountLowData > 0)
- priv->TryDownCountLowData --;
- }
-
- // Keep the Tx fail rate count to equal to 0x15 at most.
- // Reduce the fail count at least to 10 sec if tx rate is tending stable.
- if(priv->FailTxRateCount >= 0x15 ||
- (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))
- {
- priv->FailTxRateCount --;
- }
-
-
- OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
- CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
-
- //[TRC Dell Lab] Mac0x9e increase 2 level in 36M~18M situation, Isaiah 2008-02-18 24:00
- if((priv->CurrentOperaRate < 96) &&(priv->CurrentOperaRate > 22))
- {
- u1bCck = read_nic_byte(dev, CCK_TXAGC);
- u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
-
- // case 1: Never enter High power
- if(u1bCck == CckTxPwrIdx )
- {
- if(u1bOfdm != (OfdmTxPwrIdx+2) )
- {
- priv->bEnhanceTxPwr= true;
- u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
- write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
-// printk("Enhance OFDM_TXAGC : +++++ u1bOfdm= 0x%x\n", u1bOfdm);
- }
- }
- // case 2: enter high power
- else if(u1bCck < CckTxPwrIdx)
- {
- if(!priv->bEnhanceTxPwr)
- {
- priv->bEnhanceTxPwr= true;
- u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
- write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
- //RT_TRACE(COMP_RATE, DBG_TRACE, ("Enhance OFDM_TXAGC(2) : +++++ u1bOfdm= 0x%x\n", u1bOfdm));
- }
- }
- }
- else if(priv->bEnhanceTxPwr) //54/48/11/5.5/2/1
- {
- u1bCck = read_nic_byte(dev, CCK_TXAGC);
- u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
-
- // case 1: Never enter High power
- if(u1bCck == CckTxPwrIdx )
- {
- priv->bEnhanceTxPwr= false;
- write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
- //printk("Recover OFDM_TXAGC : ===== u1bOfdm= 0x%x\n", OfdmTxPwrIdx);
- }
- // case 2: enter high power
- else if(u1bCck < CckTxPwrIdx)
- {
- priv->bEnhanceTxPwr= false;
- u1bOfdm = ((u1bOfdm-2) > 0) ? (u1bOfdm-2): 0;
- write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
- //RT_TRACE(COMP_RATE, DBG_TRACE, ("Recover OFDM_TXAGC(2): ===== u1bOfdm= 0x%x\n", u1bOfdm));
-
- }
- }
-
- //
- // We need update initial gain when we set tx rate "from OFDM to CCK" or
- // "from CCK to OFDM".
- //
-SetInitialGain:
- if(bUpdateInitialGain)
- {
- if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK
- {
- if(priv->InitialGain > priv->RegBModeGainStage)
- {
- priv->InitialGainBackUp= priv->InitialGain;
-
- if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.
- {
- //SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26.
- priv->InitialGain = priv->RegBModeGainStage;
- }
- else if(priv->InitialGain > priv->RegBModeGainStage + 1)
- {
- priv->InitialGain -= 2;
- }
- else
- {
- priv->InitialGain --;
- }
- printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
- UpdateInitialGain(dev);
- }
- }
- else // OFDM
- {
- if(priv->InitialGain < 4)
- {
- priv->InitialGainBackUp= priv->InitialGain;
-
- priv->InitialGain ++;
- printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
- UpdateInitialGain(dev);
- }
- }
- }
-
- //Record the related info
- priv->LastRetryRate = CurrRetryRate;
- priv->LastTxThroughput = TxThroughput;
- priv->ieee80211->rate = priv->CurrentOperaRate * 5;
-}
-
-#endif
-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
-void rtl8180_rate_adapter(struct work_struct * work)
-{
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);
- struct net_device *dev = ieee->dev;
-#else
-void rtl8180_rate_adapter(struct net_device *dev)
-{
-
-#endif
- //struct r8180_priv *priv = ieee80211_priv(dev);
-// DMESG("---->rtl8180_rate_adapter");
- StaRateAdaptive87SE(dev);
-// DMESG("<----rtl8180_rate_adapter");
-}
-void timer_rate_adaptive(unsigned long data)
-{
- struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
- //DMESG("---->timer_rate_adaptive()\n");
- if(!priv->up)
- {
-// DMESG("<----timer_rate_adaptive():driver is not up!\n");
- return;
- }
- if((priv->ieee80211->iw_mode != IW_MODE_MASTER)
- && (priv->ieee80211->state == IEEE80211_LINKED) &&
- (priv->ForcedDataRate == 0) )
- {
-// DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
-#ifdef CONFIG_RTL818X_S
- queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
-// StaRateAdaptive87SE((struct net_device *)data);
-#endif
- }
- priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
- add_timer(&priv->rateadapter_timer);
- //DMESG("<----timer_rate_adaptive()\n");
-}
-//by amy 080312}
-void
-SwAntennaDiversityRxOk8185(
- struct net_device *dev,
- u8 SignalStrength
- )
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-// printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
-
- priv->AdRxOkCnt++;
-
- if( priv->AdRxSignalStrength != -1)
- {
- priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
- }
- else
- { // Initialization case.
- priv->AdRxSignalStrength = SignalStrength;
- }
-//{+by amy 080312
- if( priv->LastRxPktAntenna ) //Main antenna.
- priv->AdMainAntennaRxOkCnt++;
- else // Aux antenna.
- priv->AdAuxAntennaRxOkCnt++;
-//+by amy 080312
-// printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
-}
-//
-// Description:
-// Change Antenna Switch.
-//
-bool
-SetAntenna8185(
- struct net_device *dev,
- u8 u1bAntennaIndex
- )
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bAntennaSwitched = false;
-
-// printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
-
- switch(u1bAntennaIndex)
- {
- case 0:
- switch(priv->rf_chip)
- {
- case RF_ZEBRA2:
- case RF_ZEBRA4:
-#ifdef CONFIG_RTL8185B
-#ifdef CONFIG_RTL818X_S
- // Mac register, main antenna
- write_nic_byte(dev, ANTSEL, 0x03);
- //base band
- write_phy_cck(dev,0x11, 0x9b); // Config CCK RX antenna.
- write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
-
-#else
- // Mac register, main antenna
- write_nic_byte(dev, ANTSEL, 0x03);
- //base band
- write_phy_cck(dev, 0x10, 0x9b); // Config CCK RX antenna.
- write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
-#endif
-#endif
-
- bAntennaSwitched = true;
- break;
-
- default:
- printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
- break;
- }
- break;
-
- case 1:
- switch(priv->rf_chip)
- {
- case RF_ZEBRA2:
- case RF_ZEBRA4:
-#ifdef CONFIG_RTL8185B
-#ifdef CONFIG_RTL818X_S
- // Mac register, aux antenna
- write_nic_byte(dev, ANTSEL, 0x00);
- //base band
- write_phy_cck(dev, 0x11, 0xbb); // Config CCK RX antenna.
- write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
-#else
- // Mac register, aux antenna
- write_nic_byte(dev, ANTSEL, 0x00);
- //base band
- write_phy_cck(dev, 0x10, 0xbb); // Config CCK RX antenna.
- write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
-#endif
-#endif
-
- bAntennaSwitched = true;
- break;
-
- default:
- printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
- break;
- }
- break;
-
- default:
- printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
- break;
- }
-
- if(bAntennaSwitched)
- {
- priv->CurrAntennaIndex = u1bAntennaIndex;
- }
-
-// printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
-
- return bAntennaSwitched;
-}
-//
-// Description:
-// Toggle Antenna switch.
-//
-bool
-SwitchAntenna(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- bool bResult;
-
- if(priv->CurrAntennaIndex == 0)
- {
-#if 0//lzm del 080826
-//by amy 080312
-#ifdef CONFIG_RTL818X_S
- if(priv->bSwAntennaDiverity)
- bResult = SetAntennaConfig87SE(dev, 1, true);
- else
-#endif
-#endif
- bResult = SetAntenna8185(dev, 1);
-//by amy 080312
-// printk("SwitchAntenna(): switching to antenna 1 ......\n");
-// bResult = SetAntenna8185(dev, 1);//-by amy 080312
- }
- else
- {
-#if 0//lzm del 080826
-//by amy 080312
-#ifdef CONFIG_RTL818X_S
- if(priv->bSwAntennaDiverity)
- bResult = SetAntennaConfig87SE(dev, 0, true);
- else
-#endif
-#endif
- bResult = SetAntenna8185(dev, 0);
-//by amy 080312
-// printk("SwitchAntenna(): switching to antenna 0 ......\n");
-// bResult = SetAntenna8185(dev, 0);//-by amy 080312
- }
-
- return bResult;
-}
-//
-// Description:
-// Engine of SW Antenna Diversity mechanism.
-// Since 8187 has no Tx part information,
-// this implementation is only dependend on Rx part information.
-//
-// 2006.04.17, by rcnjko.
-//
-void
-SwAntennaDiversity(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bSwCheckSS=false;
-// printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);
-// printk("AdTickCount is %d\n",priv->AdTickCount);
-//by amy 080312
- if(bSwCheckSS)
- {
- priv->AdTickCount++;
-
- printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n",
- priv->AdTickCount, priv->AdCheckPeriod);
- printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n",
- priv->AdRxSignalStrength, priv->AdRxSsThreshold);
- }
-// priv->AdTickCount++;//-by amy 080312
-
- // Case 1. No Link.
- if(priv->ieee80211->state != IEEE80211_LINKED)
- {
- // printk("SwAntennaDiversity(): Case 1. No Link.\n");
-
- priv->bAdSwitchedChecking = false;
- // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..
- SwitchAntenna(dev);
- }
- // Case 2. Linked but no packet received.
- else if(priv->AdRxOkCnt == 0)
- {
- // printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
-
- priv->bAdSwitchedChecking = false;
- SwitchAntenna(dev);
- }
- // Case 3. Evaluate last antenna switch action and undo it if necessary.
- else if(priv->bAdSwitchedChecking == true)
- {
- // printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
-
- priv->bAdSwitchedChecking = false;
-
- // Adjust Rx signal strength threashold.
- priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
-
- priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
- priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
- if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched)
- { // Rx signal strength is not improved after we swtiched antenna. => Swich back.
-// printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %d, LastRxSs: %d\n",
-// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
-//by amy 080312
- // Increase Antenna Diversity checking period due to bad decision.
- priv->AdCheckPeriod *= 2;
-//by amy 080312
- // Increase Antenna Diversity checking period.
- if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
- priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
-
- // Wrong deceision => switch back.
- SwitchAntenna(dev);
- }
- else
- { // Rx Signal Strength is improved.
-// printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %d, LastRxSs: %d\n",
-// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
-
- // Reset Antenna Diversity checking period to its min value.
- priv->AdCheckPeriod = priv->AdMinCheckPeriod;
- }
-
-// printk("SwAntennaDiversity(): AdRxSsThreshold: %d, AdCheckPeriod: %d\n",
-// priv->AdRxSsThreshold, priv->AdCheckPeriod);
- }
- // Case 4. Evaluate if we shall switch antenna now.
- // Cause Table Speed is very fast in TRC Dell Lab, we check it every time.
- else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312
- {
-// printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
-
- priv->AdTickCount = 0;
-
- //
- // <Roger_Notes> We evaluate RxOk counts for each antenna first and than
- // evaluate signal strength.
- // The following operation can overcome the disability of CCA on both two antennas
- // When signal strength was extremely low or high.
- // 2008.01.30.
- //
-
- //
- // Evaluate RxOk count from each antenna if we shall switch default antenna now.
- // Added by Roger, 2008.02.21.
-//{by amy 080312
- if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt)
- && (priv->CurrAntennaIndex == 0))
- { // We set Main antenna as default but RxOk count was less than Aux ones.
-
- // printk("SwAntennaDiversity(): Main antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
- // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
-
- // Switch to Aux antenna.
- SwitchAntenna(dev);
- priv->bHWAdSwitched = true;
- }
- else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt)
- && (priv->CurrAntennaIndex == 1))
- { // We set Aux antenna as default but RxOk count was less than Main ones.
-
- // printk("SwAntennaDiversity(): Aux antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
- // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
-
- // Switch to Main antenna.
- SwitchAntenna(dev);
- priv->bHWAdSwitched = true;
- }
- else
- {// Default antenna is better.
-
- // printk("SwAntennaDiversity(): Default antenna is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
- // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
-
- // Still need to check current signal strength.
- priv->bHWAdSwitched = false;
- }
- //
- // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
- // didn't changed by HW evaluation.
- // 2008.02.27.
- //
- // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
- // For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
- // but AdRxSignalStrength is less than main.
- // Our guess is that main antenna have lower throughput and get many change
- // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
- //
- if( (!priv->bHWAdSwitched) && (bSwCheckSS))
- {
-//by amy 080312}
- // Evaluate Rx signal strength if we shall switch antenna now.
- if(priv->AdRxSignalStrength < priv->AdRxSsThreshold)
- { // Rx signal strength is weak => Switch Antenna.
-// printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %d, RxSsThreshold: %d\n",
-// priv->AdRxSignalStrength, priv->AdRxSsThreshold);
-
- priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
- priv->bAdSwitchedChecking = true;
-
- SwitchAntenna(dev);
- }
- else
- { // Rx signal strength is OK.
-// printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %d, RxSsThreshold: %d\n",
-// priv->AdRxSignalStrength, priv->AdRxSsThreshold);
-
- priv->bAdSwitchedChecking = false;
- // Increase Rx signal strength threashold if necessary.
- if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold
- priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit.
- {
- priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
- priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
- priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312
- }
-
- // Reduce Antenna Diversity checking period if possible.
- if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
- {
- priv->AdCheckPeriod /= 2;
- }
- }
- }
- }
-//by amy 080312
- // Reset antenna diversity Rx related statistics.
- priv->AdRxOkCnt = 0;
- priv->AdMainAntennaRxOkCnt = 0;
- priv->AdAuxAntennaRxOkCnt = 0;
-//by amy 080312
-
-// priv->AdRxOkCnt = 0;//-by amy 080312
-
-// printk("-SwAntennaDiversity()\n");
-}
-
-//
-// Description:
-// Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise.
-//
-bool
-CheckTxPwrTracking( struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- if(!priv->bTxPowerTrack)
- {
- return false;
- }
-
-//lzm reserved 080826
- //if(priv->bScanInProgress)
- //{
- // return false;
- //}
-
- //if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah
- if(priv->bToUpdateTxPwr)
- {
- return false;
- }
-
- return true;
-}
-
-
-//
-// Description:
-// Timer callback function of SW Antenna Diversity.
-//
-void
-SwAntennaDiversityTimerCallback(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- RT_RF_POWER_STATE rtState;
-
- //printk("+SwAntennaDiversityTimerCallback()\n");
-
- //
- // We do NOT need to switch antenna while RF is off.
- // 2007.05.09, added by Roger.
- //
- rtState = priv->eRFPowerState;
- do{
- if (rtState == eRfOff)
- {
-// printk("SwAntennaDiversityTimer - RF is OFF.\n");
- break;
- }
- else if (rtState == eRfSleep)
- {
- // Don't access BB/RF under Disable PLL situation.
- //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
- break;
- }
- SwAntennaDiversity(dev);
-
- }while(false);
-
- if(priv->up)
- {
- priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
- add_timer(&priv->SwAntennaDiversityTimer);
- }
-
- //printk("-SwAntennaDiversityTimerCallback()\n");
-}
-
+//#include "r8180.h"
+#include "r8180_dm.h"
+#include "r8180_hw.h"
+#include "r8180_93cx6.h"
+//{by amy 080312
+
+//
+// Description:
+// Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
+//
+//+by amy 080312
+#define RATE_ADAPTIVE_TIMER_PERIOD 300
+
+bool CheckHighPower(struct net_device *dev)
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device *ieee = priv->ieee80211;
+
+ if(!priv->bRegHighPowerMechanism)
+ {
+ return false;
+ }
+
+ if(ieee->state == IEEE80211_LINKED_SCANNING)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+//
+// Description:
+// Update Tx power level if necessary.
+// See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
+//
+// Note:
+// The reason why we udpate Tx power level here instead of DoRxHighPower()
+// is the number of IO to change Tx power is much more than chane TR switch
+// and they are related to OFDM and MAC registers.
+// So, we don't want to update it so frequently in per-Rx packet base.
+//
+void
+DoTxHighPower(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+ u16 HiPwrUpperTh = 0;
+ u16 HiPwrLowerTh = 0;
+ u8 RSSIHiPwrUpperTh;
+ u8 RSSIHiPwrLowerTh;
+ u8 u1bTmp;
+ char OfdmTxPwrIdx, CckTxPwrIdx;
+
+ //printk("----> DoTxHighPower()\n");
+
+ HiPwrUpperTh = priv->RegHiPwrUpperTh;
+ HiPwrLowerTh = priv->RegHiPwrLowerTh;
+
+ HiPwrUpperTh = HiPwrUpperTh * 10;
+ HiPwrLowerTh = HiPwrLowerTh * 10;
+ RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh;
+ RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh;
+
+ //lzm add 080826
+ OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
+ CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
+
+ // printk("DoTxHighPower() - UndecoratedSmoothedSS:%d, CurCCKRSSI = %d , bCurCCKPkt= %d \n", priv->UndecoratedSmoothedSS, priv->CurCCKRSSI, priv->bCurCCKPkt );
+
+ if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
+ (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
+ {
+ // Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah
+
+ // printk("=====>DoTxHighPower() - High Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrUpperTh );
+ priv->bToUpdateTxPwr = true;
+ u1bTmp= read_nic_byte(dev, CCK_TXAGC);
+
+ // If it never enter High Power.
+ if( CckTxPwrIdx == u1bTmp)
+ {
+ u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
+ write_nic_byte(dev, CCK_TXAGC, u1bTmp);
+
+ u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
+ u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
+ write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
+ }
+
+ }
+ else if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
+ (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))
+ {
+ // printk("DoTxHighPower() - lower Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrLowerTh );
+ if(priv->bToUpdateTxPwr)
+ {
+ priv->bToUpdateTxPwr = false;
+ //SD3 required.
+ u1bTmp= read_nic_byte(dev, CCK_TXAGC);
+ if(u1bTmp < CckTxPwrIdx)
+ {
+ //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
+ //write_nic_byte(dev, CCK_TXAGC, u1bTmp);
+ write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);
+ }
+
+ u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
+ if(u1bTmp < OfdmTxPwrIdx)
+ {
+ //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
+ //write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
+ write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
+ }
+ }
+ }
+
+ //printk("<---- DoTxHighPower()\n");
+}
+
+
+//
+// Description:
+// Callback function of UpdateTxPowerWorkItem.
+// Because of some event happend, e.g. CCX TPC, High Power Mechanism,
+// We update Tx power of current channel again.
+//
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_tx_pw_wq (struct work_struct *work)
+{
+// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
+// struct ieee80211_device * ieee = (struct ieee80211_device*)
+// container_of(work, struct ieee80211_device, watch_dog_wq);
+ struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+ struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);
+ struct net_device *dev = ieee->dev;
+#else
+void rtl8180_tx_pw_wq(struct net_device *dev)
+{
+ // struct r8180_priv *priv = ieee80211_priv(dev);
+#endif
+
+// printk("----> UpdateTxPowerWorkItemCallback()\n");
+
+ DoTxHighPower(dev);
+
+// printk("<---- UpdateTxPowerWorkItemCallback()\n");
+}
+
+
+//
+// Description:
+// Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise.
+//
+bool
+CheckDig(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device *ieee = priv->ieee80211;
+
+ if(!priv->bDigMechanism)
+ return false;
+
+ if(ieee->state != IEEE80211_LINKED)
+ return false;
+
+ //if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
+ if((priv->ieee80211->rate/5) < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
+ return false;
+ return true;
+}
+//
+// Description:
+// Implementation of DIG for Zebra and Zebra2.
+//
+void
+DIG_Zebra(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+ u16 CCKFalseAlarm, OFDMFalseAlarm;
+ u16 OfdmFA1, OfdmFA2;
+ int InitialGainStep = 7; // The number of initial gain stages.
+ int LowestGainStage = 4; // The capable lowest stage of performing dig workitem.
+ u32 AwakePeriodIn2Sec=0;
+
+ //printk("---------> DIG_Zebra()\n");
+
+ CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
+ OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
+ OfdmFA1 = 0x15;
+ OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
+
+// printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
+// printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
+
+ // The number of initial gain steps is different, by Bruce, 2007-04-13.
+ if (priv->InitialGain == 0 ) //autoDIG
+ { // Advised from SD3 DZ
+ priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm)
+ }
+ //if(pHalData->VersionID != VERSION_8187B_B)
+ { // Advised from SD3 DZ
+ OfdmFA1 = 0x20;
+ }
+
+#if 1 //lzm reserved 080826
+ AwakePeriodIn2Sec = (2000-priv ->DozePeriodInPast2Sec);
+ //printk("&&& DozePeriod=%d AwakePeriod=%d\n", priv->DozePeriodInPast2Sec, AwakePeriodIn2Sec);
+ priv ->DozePeriodInPast2Sec=0;
+
+ if(AwakePeriodIn2Sec)
+ {
+ //RT_TRACE(COMP_DIG, DBG_TRACE, ("DIG: AwakePeriodIn2Sec(%d) - FATh(0x%X , 0x%X) ->",AwakePeriodIn2Sec, OfdmFA1, OfdmFA2));
+ // adjuest DIG threshold.
+ OfdmFA1 = (u16)((OfdmFA1*AwakePeriodIn2Sec) / 2000) ;
+ OfdmFA2 = (u16)((OfdmFA2*AwakePeriodIn2Sec) / 2000) ;
+ //RT_TRACE(COMP_DIG, DBG_TRACE, ("( 0x%X , 0x%X)\n", OfdmFA1, OfdmFA2));
+ }
+ else
+ {
+ ;//RT_TRACE(COMP_DIG, DBG_WARNING, ("ERROR!! AwakePeriodIn2Sec should not be ZERO!!\n"));
+ }
+#endif
+
+ InitialGainStep = 8;
+ LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.
+
+ if (OFDMFalseAlarm > OfdmFA1)
+ {
+ if (OFDMFalseAlarm > OfdmFA2)
+ {
+ priv->DIG_NumberFallbackVote++;
+ if (priv->DIG_NumberFallbackVote >1)
+ {
+ //serious OFDM False Alarm, need fallback
+ if (priv->InitialGain < InitialGainStep)
+ {
+ priv->InitialGainBackUp= priv->InitialGain;
+
+ priv->InitialGain = (priv->InitialGain + 1);
+// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
+// printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);
+ UpdateInitialGain(dev);
+ }
+ priv->DIG_NumberFallbackVote = 0;
+ priv->DIG_NumberUpgradeVote=0;
+ }
+ }
+ else
+ {
+ if (priv->DIG_NumberFallbackVote)
+ priv->DIG_NumberFallbackVote--;
+ }
+ priv->DIG_NumberUpgradeVote=0;
+ }
+ else
+ {
+ if (priv->DIG_NumberFallbackVote)
+ priv->DIG_NumberFallbackVote--;
+ priv->DIG_NumberUpgradeVote++;
+
+ if (priv->DIG_NumberUpgradeVote>9)
+ {
+ if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)
+ {
+ priv->InitialGainBackUp= priv->InitialGain;
+
+ priv->InitialGain = (priv->InitialGain - 1);
+// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
+// printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);
+ UpdateInitialGain(dev);
+ }
+ priv->DIG_NumberFallbackVote = 0;
+ priv->DIG_NumberUpgradeVote=0;
+ }
+ }
+
+// printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
+ //printk("<--------- DIG_Zebra()\n");
+}
+
+//
+// Description:
+// Dispatch DIG implementation according to RF.
+//
+void
+DynamicInitGain(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+
+ switch(priv->rf_chip)
+ {
+ case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01.
+ case RF_ZEBRA4:
+ DIG_Zebra( dev );
+ break;
+
+ default:
+ printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
+ break;
+ }
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_hw_dig_wq (struct work_struct *work)
+{
+// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
+// struct ieee80211_device * ieee = (struct ieee80211_device*)
+// container_of(work, struct ieee80211_device, watch_dog_wq);
+ struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+ struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
+ struct net_device *dev = ieee->dev;
+#else
+void rtl8180_hw_dig_wq(struct net_device *dev)
+{
+
+#endif
+ struct r8180_priv *priv = ieee80211_priv(dev);
+
+ // Read CCK and OFDM False Alarm.
+ priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
+
+
+ // Adjust Initial Gain dynamically.
+ DynamicInitGain(dev);
+
+}
+
+int
+IncludedInSupportedRates(
+ struct r8180_priv *priv,
+ u8 TxRate )
+{
+ u8 rate_len;
+ u8 rate_ex_len;
+ u8 RateMask = 0x7F;
+ u8 idx;
+ unsigned short Found = 0;
+ u8 NaiveTxRate = TxRate&RateMask;
+
+ rate_len = priv->ieee80211->current_network.rates_len;
+ rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
+ for( idx=0; idx< rate_len; idx++ )
+ {
+ if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate )
+ {
+ Found = 1;
+ goto found_rate;
+ }
+ }
+ for( idx=0; idx< rate_ex_len; idx++ )
+ {
+ if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate )
+ {
+ Found = 1;
+ goto found_rate;
+ }
+ }
+ return Found;
+ found_rate:
+ return Found;
+}
+
+//
+// Description:
+// Get the Tx rate one degree up form the input rate in the supported rates.
+// Return the upgrade rate if it is successed, otherwise return the input rate.
+// By Bruce, 2007-06-05.
+//
+u8
+GetUpgradeTxRate(
+ struct net_device *dev,
+ u8 rate
+ )
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+ u8 UpRate;
+
+ // Upgrade 1 degree.
+ switch(rate)
+ {
+ case 108: // Up to 54Mbps.
+ UpRate = 108;
+ break;
+
+ case 96: // Up to 54Mbps.
+ UpRate = 108;
+ break;
+
+ case 72: // Up to 48Mbps.
+ UpRate = 96;
+ break;
+
+ case 48: // Up to 36Mbps.
+ UpRate = 72;
+ break;
+
+ case 36: // Up to 24Mbps.
+ UpRate = 48;
+ break;
+
+ case 22: // Up to 18Mbps.
+ UpRate = 36;
+ break;
+
+ case 11: // Up to 11Mbps.
+ UpRate = 22;
+ break;
+
+ case 4: // Up to 5.5Mbps.
+ UpRate = 11;
+ break;
+
+ case 2: // Up to 2Mbps.
+ UpRate = 4;
+ break;
+
+ default:
+ printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
+ return rate;
+ }
+ // Check if the rate is valid.
+ if(IncludedInSupportedRates(priv, UpRate))
+ {
+// printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
+ return UpRate;
+ }
+ else
+ {
+ //printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
+ return rate;
+ }
+ return rate;
+}
+//
+// Description:
+// Get the Tx rate one degree down form the input rate in the supported rates.
+// Return the degrade rate if it is successed, otherwise return the input rate.
+// By Bruce, 2007-06-05.
+//
+u8
+GetDegradeTxRate(
+ struct net_device *dev,
+ u8 rate
+ )
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+ u8 DownRate;
+
+ // Upgrade 1 degree.
+ switch(rate)
+ {
+ case 108: // Down to 48Mbps.
+ DownRate = 96;
+ break;
+
+ case 96: // Down to 36Mbps.
+ DownRate = 72;
+ break;
+
+ case 72: // Down to 24Mbps.
+ DownRate = 48;
+ break;
+
+ case 48: // Down to 18Mbps.
+ DownRate = 36;
+ break;
+
+ case 36: // Down to 11Mbps.
+ DownRate = 22;
+ break;
+
+ case 22: // Down to 5.5Mbps.
+ DownRate = 11;
+ break;
+
+ case 11: // Down to 2Mbps.
+ DownRate = 4;
+ break;
+
+ case 4: // Down to 1Mbps.
+ DownRate = 2;
+ break;
+
+ case 2: // Down to 1Mbps.
+ DownRate = 2;
+ break;
+
+ default:
+ printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
+ return rate;
+ }
+ // Check if the rate is valid.
+ if(IncludedInSupportedRates(priv, DownRate))
+ {
+// printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
+ return DownRate;
+ }
+ else
+ {
+ //printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
+ return rate;
+ }
+ return rate;
+}
+//
+// Helper function to determine if specified data rate is
+// CCK rate.
+// 2005.01.25, by rcnjko.
+//
+bool
+MgntIsCckRate(
+ u16 rate
+ )
+{
+ bool bReturn = false;
+
+ if((rate <= 22) && (rate != 12) && (rate != 18))
+ {
+ bReturn = true;
+ }
+
+ return bReturn;
+}
+#ifdef CONFIG_RTL818X_S
+//
+// Description:
+// Tx Power tracking mechanism routine on 87SE.
+// Created by Roger, 2007.12.11.
+//
+void
+TxPwrTracking87SE(
+ struct net_device *dev
+)
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+ u8 tmpu1Byte, CurrentThermal, Idx;
+ char CckTxPwrIdx, OfdmTxPwrIdx;
+ //u32 u4bRfReg;
+
+ tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
+ CurrentThermal = (tmpu1Byte & 0xf0)>>4; //[ 7:4]: thermal meter indication.
+ CurrentThermal = (CurrentThermal>0x0c)? 0x0c:CurrentThermal;//lzm add 080826
+
+ //printk("TxPwrTracking87SE(): CurrentThermal(%d)\n", CurrentThermal);
+
+ if( CurrentThermal != priv->ThermalMeter)
+ {
+// printk("TxPwrTracking87SE(): Thermal meter changed!!!\n");
+
+ // Update Tx Power level on each channel.
+ for(Idx = 1; Idx<15; Idx++)
+ {
+ CckTxPwrIdx = priv->chtxpwr[Idx];
+ OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];
+
+ if( CurrentThermal > priv->ThermalMeter )
+ { // higher thermal meter.
+ CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
+ OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
+
+ if(CckTxPwrIdx >35)
+ CckTxPwrIdx = 35; // Force TxPower to maximal index.
+ if(OfdmTxPwrIdx >35)
+ OfdmTxPwrIdx = 35;
+ }
+ else
+ { // lower thermal meter.
+ CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
+ OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
+
+ if(CckTxPwrIdx <0)
+ CckTxPwrIdx = 0;
+ if(OfdmTxPwrIdx <0)
+ OfdmTxPwrIdx = 0;
+ }
+
+ // Update TxPower level on CCK and OFDM resp.
+ priv->chtxpwr[Idx] = CckTxPwrIdx;
+ priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
+ }
+
+ // Update TxPower level immediately.
+ rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
+ }
+ priv->ThermalMeter = CurrentThermal;
+}
+void
+StaRateAdaptive87SE(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+ unsigned long CurrTxokCnt;
+ u16 CurrRetryCnt;
+ u16 CurrRetryRate;
+ //u16 i,idx;
+ unsigned long CurrRxokCnt;
+ bool bTryUp = false;
+ bool bTryDown = false;
+ u8 TryUpTh = 1;
+ u8 TryDownTh = 2;
+ u32 TxThroughput;
+ long CurrSignalStrength;
+ bool bUpdateInitialGain = false;
+ u8 u1bOfdm=0, u1bCck = 0;
+ char OfdmTxPwrIdx, CckTxPwrIdx;
+
+ priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
+
+
+ CurrRetryCnt = priv->CurrRetryCnt;
+ CurrTxokCnt = priv->NumTxOkTotal - priv->LastTxokCnt;
+ CurrRxokCnt = priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt;
+ CurrSignalStrength = priv->Stats_RecvSignalPower;
+ TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes);
+ priv->LastTxOKBytes = priv->NumTxOkBytesTotal;
+ priv->CurrentOperaRate = priv->ieee80211->rate/5;
+ //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);
+ //2 Compute retry ratio.
+ if (CurrTxokCnt>0)
+ {
+ CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
+ }
+ else
+ { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
+ CurrRetryRate = (u16)(CurrRetryCnt*100/1);
+ }
+
+
+ //
+ // Added by Roger, 2007.01.02.
+ // For debug information.
+ //
+ //printk("\n(1) pHalData->LastRetryRate: %d \n",priv->LastRetryRate);
+ //printk("(2) RetryCnt = %d \n", CurrRetryCnt);
+ //printk("(3) TxokCnt = %d \n", CurrTxokCnt);
+ //printk("(4) CurrRetryRate = %d \n", CurrRetryRate);
+ //printk("(5) CurrSignalStrength = %d \n",CurrSignalStrength);
+ //printk("(6) TxThroughput is %d\n",TxThroughput);
+ //printk("priv->NumTxOkBytesTotal is %d\n",priv->NumTxOkBytesTotal);
+
+ priv->LastRetryCnt = priv->CurrRetryCnt;
+ priv->LastTxokCnt = priv->NumTxOkTotal;
+ priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;
+ priv->CurrRetryCnt = 0;
+
+ //2No Tx packets, return to init_rate or not?
+ if (CurrRetryRate==0 && CurrTxokCnt == 0)
+ {
+ //
+ //After 9 (30*300ms) seconds in this condition, we try to raise rate.
+ //
+ priv->TryupingCountNoData++;
+
+// printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);
+ //[TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00
+ if (priv->TryupingCountNoData>30)
+ {
+ priv->TryupingCountNoData = 0;
+ priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
+ // Reset Fail Record
+ priv->LastFailTxRate = 0;
+ priv->LastFailTxRateSS = -200;
+ priv->FailTxRateCount = 0;
+ }
+ goto SetInitialGain;
+ }
+ else
+ {
+ priv->TryupingCountNoData=0; //Reset trying up times.
+ }
+
+
+ //
+ // For Netgear case, I comment out the following signal strength estimation,
+ // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
+ // 2007.04.09, by Roger.
+ //
+
+ //
+ // Restructure rate adaptive as the following main stages:
+ // (1) Add retry threshold in 54M upgrading condition with signal strength.
+ // (2) Add the mechanism to degrade to CCK rate according to signal strength
+ // and retry rate.
+ // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
+ // situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
+ // (4) Add the mehanism of trying to upgrade tx rate.
+ // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
+ // By Bruce, 2007-06-05.
+ //
+ //
+
+ // 11Mbps or 36Mbps
+ // Check more times in these rate(key rates).
+ //
+ if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
+ {
+ TryUpTh += 9;
+ }
+ //
+ // Let these rates down more difficult.
+ //
+ if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
+ {
+ TryDownTh += 1;
+ }
+
+ //1 Adjust Rate.
+ if (priv->bTryuping == true)
+ {
+ //2 For Test Upgrading mechanism
+ // Note:
+ // Sometimes the throughput is upon on the capability bwtween the AP and NIC,
+ // thus the low data rate does not improve the performance.
+ // We randomly upgrade the data rate and check if the retry rate is improved.
+
+ // Upgrading rate did not improve the retry rate, fallback to the original rate.
+ if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
+ {
+ //Not necessary raising rate, fall back rate.
+ bTryDown = true;
+ //printk("case1-1: Not necessary raising rate, fall back rate....\n");
+ //printk("case1-1: pMgntInfo->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",
+ // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);
+ }
+ else
+ {
+ priv->bTryuping = false;
+ }
+ }
+ else if (CurrSignalStrength > -47 && (CurrRetryRate < 50))
+ {
+ //2For High Power
+ //
+ // Added by Roger, 2007.04.09.
+ // Return to highest data rate, if signal strength is good enough.
+ // SignalStrength threshold(-50dbm) is for RTL8186.
+ // Revise SignalStrength threshold to -51dbm.
+ //
+ // Also need to check retry rate for safety, by Bruce, 2007-06-05.
+ if(priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate )
+ {
+ bTryUp = true;
+ // Upgrade Tx Rate directly.
+ priv->TryupingCount += TryUpTh;
+ }
+// printk("case2: StaRateAdaptive87SE: Power(%d) is high enough!!. \n", CurrSignalStrength);
+
+ }
+ else if(CurrTxokCnt > 9 && CurrTxokCnt< 100 && CurrRetryRate >= 600)
+ {
+ //2 For Serious Retry
+ //
+ // Traffic is not busy but our Tx retry is serious.
+ //
+ bTryDown = true;
+ // Let Rate Mechanism to degrade tx rate directly.
+ priv->TryDownCountLowData += TryDownTh;
+// printk("case3: RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);
+ }
+ else if ( priv->CurrentOperaRate == 108 )
+ {
+ //2For 54Mbps
+ // Air Link
+ if ( (CurrRetryRate>26)&&(priv->LastRetryRate>25))
+// if ( (CurrRetryRate>40)&&(priv->LastRetryRate>39))
+ {
+ //Down to rate 48Mbps.
+ bTryDown = true;
+ }
+ // Cable Link
+ else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
+// else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
+ {
+ //Down to rate 48Mbps.
+ bTryDown = true;
+ }
+
+ if(bTryDown && (CurrSignalStrength < -75)) //cable link
+ {
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ //printk("case4---54M \n");
+
+ }
+ else if ( priv->CurrentOperaRate == 96 )
+ {
+ //2For 48Mbps
+ //Air Link
+ if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
+// if ( ((CurrRetryRate>65) && (priv->LastRetryRate>64)))
+
+ {
+ //Down to rate 36Mbps.
+ bTryDown = true;
+ }
+ //Cable Link
+ else if ( ((CurrRetryRate>21) && (priv->LastRetryRate>20)) && (CurrSignalStrength > -74))
+ {
+ //Down to rate 36Mbps.
+ bTryDown = true;
+ }
+ else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
+// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
+ {
+ bTryDown = true;
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)
+// else if ( (CurrRetryRate<28) && (priv->LastRetryRate<8) )
+ {
+ bTryUp = true;
+ }
+
+ if(bTryDown && (CurrSignalStrength < -75))
+ {
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ //printk("case5---48M \n");
+ }
+ else if ( priv->CurrentOperaRate == 72 )
+ {
+ //2For 36Mbps
+ if ( (CurrRetryRate>43) && (priv->LastRetryRate>41))
+// if ( (CurrRetryRate>60) && (priv->LastRetryRate>59))
+ {
+ //Down to rate 24Mbps.
+ bTryDown = true;
+ }
+ else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
+// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
+ {
+ bTryDown = true;
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16)) //TO DO: need to consider (RSSI)
+// else if ( (CurrRetryRate<35) && (priv->LastRetryRate<36))
+ {
+ bTryUp = true;
+ }
+
+ if(bTryDown && (CurrSignalStrength < -80))
+ {
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ //printk("case6---36M \n");
+ }
+ else if ( priv->CurrentOperaRate == 48 )
+ {
+ //2For 24Mbps
+ // Air Link
+ if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
+// if ( ((CurrRetryRate>83) && (priv->LastRetryRate>82)))
+ {
+ //Down to rate 18Mbps.
+ bTryDown = true;
+ }
+ //Cable Link
+ else if ( ((CurrRetryRate>33) && (priv->LastRetryRate>32)) && (CurrSignalStrength > -82) )
+// else if ( ((CurrRetryRate>50) && (priv->LastRetryRate>49)) && (CurrSignalStrength > -82) )
+ {
+ //Down to rate 18Mbps.
+ bTryDown = true;
+ }
+ else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
+// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
+
+ {
+ bTryDown = true;
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)
+// else if ( (CurrRetryRate<40) && (priv->LastRetryRate<41))
+ {
+ bTryUp = true;
+ }
+
+ if(bTryDown && (CurrSignalStrength < -82))
+ {
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ //printk("case7---24M \n");
+ }
+ else if ( priv->CurrentOperaRate == 36 )
+ {
+ //2For 18Mbps
+ // original (109, 109)
+ //[TRC Dell Lab] (90, 91), Isaiah 2008-02-18 23:24
+ // (85, 86), Isaiah 2008-02-18 24:00
+ if ( ((CurrRetryRate>85) && (priv->LastRetryRate>86)))
+// if ( ((CurrRetryRate>115) && (priv->LastRetryRate>116)))
+ {
+ //Down to rate 11Mbps.
+ bTryDown = true;
+ }
+ //[TRC Dell Lab] Isaiah 2008-02-18 23:24
+ else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
+// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
+ {
+ bTryDown = true;
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ else if ( (CurrRetryRate<22) && (priv->LastRetryRate<23)) //TO DO: need to consider (RSSI)
+// else if ( (CurrRetryRate<42) && (priv->LastRetryRate<43))
+ {
+ bTryUp = true;
+ }
+ //printk("case8---18M \n");
+ }
+ else if ( priv->CurrentOperaRate == 22 )
+ {
+ //2For 11Mbps
+ if (CurrRetryRate>95)
+// if (CurrRetryRate>155)
+ {
+ bTryDown = true;
+ }
+ else if ( (CurrRetryRate<29) && (priv->LastRetryRate <30) )//TO DO: need to consider (RSSI)
+// else if ( (CurrRetryRate<49) && (priv->LastRetryRate <50) )
+ {
+ bTryUp = true;
+ }
+ //printk("case9---11M \n");
+ }
+ else if ( priv->CurrentOperaRate == 11 )
+ {
+ //2For 5.5Mbps
+ if (CurrRetryRate>149)
+// if (CurrRetryRate>189)
+ {
+ bTryDown = true;
+ }
+ else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
+// else if ( (CurrRetryRate<80) && (priv->LastRetryRate < 85))
+
+ {
+ bTryUp = true;
+ }
+ //printk("case10---5.5M \n");
+ }
+ else if ( priv->CurrentOperaRate == 4 )
+ {
+ //2For 2 Mbps
+ if((CurrRetryRate>99) && (priv->LastRetryRate>99))
+// if((CurrRetryRate>199) && (priv->LastRetryRate>199))
+ {
+ bTryDown = true;
+ }
+ else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
+// else if ( (CurrRetryRate < 85) && (priv->LastRetryRate < 90))
+ {
+ bTryUp = true;
+ }
+ //printk("case11---2M \n");
+ }
+ else if ( priv->CurrentOperaRate == 2 )
+ {
+ //2For 1 Mbps
+ if( (CurrRetryRate<70) && (priv->LastRetryRate<75))
+// if( (CurrRetryRate<90) && (priv->LastRetryRate<95))
+ {
+ bTryUp = true;
+ }
+ //printk("case12---1M \n");
+ }
+
+ if(bTryUp && bTryDown)
+ printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
+
+ //1 Test Upgrading Tx Rate
+ // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
+ // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
+ if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
+ && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2)
+ {
+ if(jiffies% (CurrRetryRate + 101) == 0)
+ {
+ bTryUp = true;
+ priv->bTryuping = true;
+ //printk("StaRateAdaptive87SE(): Randomly try upgrading...\n");
+ }
+ }
+
+ //1 Rate Mechanism
+ if(bTryUp)
+ {
+ priv->TryupingCount++;
+ priv->TryDownCountLowData = 0;
+
+ {
+// printk("UP: pHalData->TryupingCount = %d\n", priv->TryupingCount);
+// printk("UP: TryUpTh(%d)+ (FailTxRateCount(%d))^2 =%d\n",
+// TryUpTh, priv->FailTxRateCount, (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount) );
+// printk("UP: pHalData->bTryuping=%d\n", priv->bTryuping);
+
+ }
+
+ //
+ // Check more times if we need to upgrade indeed.
+ // Because the largest value of pHalData->TryupingCount is 0xFFFF and
+ // the largest value of pHalData->FailTxRateCount is 0x14,
+ // this condition will be satisfied at most every 2 min.
+ //
+
+ if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
+ (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
+ {
+ priv->TryupingCount = 0;
+ //
+ // When transfering from CCK to OFDM, DIG is an important issue.
+ //
+ if(priv->CurrentOperaRate == 22)
+ bUpdateInitialGain = true;
+
+ // The difference in throughput between 48Mbps and 36Mbps is 8M.
+ // So, we must be carefully in this rate scale. Isaiah 2008-02-15.
+ //
+ if( ((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&
+ (priv->FailTxRateCount > 2) )
+ priv->RateAdaptivePeriod= (RATE_ADAPTIVE_TIMER_PERIOD/2);
+
+ // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.
+ // (2)If the signal strength is increased, it may be able to upgrade.
+
+ priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
+// printk("StaRateAdaptive87SE(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
+
+ //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
+ if(priv->CurrentOperaRate ==36)
+ {
+ priv->bUpdateARFR=true;
+ write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
+// printk("UP: ARFR=0xF8F\n");
+ }
+ else if(priv->bUpdateARFR)
+ {
+ priv->bUpdateARFR=false;
+ write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
+// printk("UP: ARFR=0xFFF\n");
+ }
+
+ // Update Fail Tx rate and count.
+ if(priv->LastFailTxRate != priv->CurrentOperaRate)
+ {
+ priv->LastFailTxRate = priv->CurrentOperaRate;
+ priv->FailTxRateCount = 0;
+ priv->LastFailTxRateSS = -200; // Set lowest power.
+ }
+ }
+ }
+ else
+ {
+ if(priv->TryupingCount > 0)
+ priv->TryupingCount --;
+ }
+
+ if(bTryDown)
+ {
+ priv->TryDownCountLowData++;
+ priv->TryupingCount = 0;
+ {
+// printk("DN: pHalData->TryDownCountLowData = %d\n",priv->TryDownCountLowData);
+// printk("DN: TryDownTh =%d\n", TryDownTh);
+// printk("DN: pHalData->bTryuping=%d\n", priv->bTryuping);
+ }
+
+ //Check if Tx rate can be degraded or Test trying upgrading should fallback.
+ if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
+ {
+ priv->TryDownCountLowData = 0;
+ priv->bTryuping = false;
+ // Update fail information.
+ if(priv->LastFailTxRate == priv->CurrentOperaRate)
+ {
+ priv->FailTxRateCount ++;
+ // Record the Tx fail rate signal strength.
+ if(CurrSignalStrength > priv->LastFailTxRateSS)
+ {
+ priv->LastFailTxRateSS = CurrSignalStrength;
+ }
+ }
+ else
+ {
+ priv->LastFailTxRate = priv->CurrentOperaRate;
+ priv->FailTxRateCount = 1;
+ priv->LastFailTxRateSS = CurrSignalStrength;
+ }
+ priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
+
+ // Reduce chariot training time at weak signal strength situation. SD3 ED demand.
+ //[TRC Dell Lab] Revise Signal Threshold from -75 to -80 , Isaiah 2008-02-18 20:00
+ if( (CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72 ))
+ {
+ priv->CurrentOperaRate = 72;
+// printk("DN: weak signal strength (%d), degrade to 36Mbps\n", CurrSignalStrength);
+ }
+
+ //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
+ if(priv->CurrentOperaRate ==36)
+ {
+ priv->bUpdateARFR=true;
+ write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
+// printk("DN: ARFR=0xF8F\n");
+ }
+ else if(priv->bUpdateARFR)
+ {
+ priv->bUpdateARFR=false;
+ write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
+// printk("DN: ARFR=0xFFF\n");
+ }
+
+ //
+ // When it is CCK rate, it may need to update initial gain to receive lower power packets.
+ //
+ if(MgntIsCckRate(priv->CurrentOperaRate))
+ {
+ bUpdateInitialGain = true;
+ }
+// printk("StaRateAdaptive87SE(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
+ }
+ }
+ else
+ {
+ if(priv->TryDownCountLowData > 0)
+ priv->TryDownCountLowData --;
+ }
+
+ // Keep the Tx fail rate count to equal to 0x15 at most.
+ // Reduce the fail count at least to 10 sec if tx rate is tending stable.
+ if(priv->FailTxRateCount >= 0x15 ||
+ (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))
+ {
+ priv->FailTxRateCount --;
+ }
+
+
+ OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
+ CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
+
+ //[TRC Dell Lab] Mac0x9e increase 2 level in 36M~18M situation, Isaiah 2008-02-18 24:00
+ if((priv->CurrentOperaRate < 96) &&(priv->CurrentOperaRate > 22))
+ {
+ u1bCck = read_nic_byte(dev, CCK_TXAGC);
+ u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
+
+ // case 1: Never enter High power
+ if(u1bCck == CckTxPwrIdx )
+ {
+ if(u1bOfdm != (OfdmTxPwrIdx+2) )
+ {
+ priv->bEnhanceTxPwr= true;
+ u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
+ write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
+// printk("Enhance OFDM_TXAGC : +++++ u1bOfdm= 0x%x\n", u1bOfdm);
+ }
+ }
+ // case 2: enter high power
+ else if(u1bCck < CckTxPwrIdx)
+ {
+ if(!priv->bEnhanceTxPwr)
+ {
+ priv->bEnhanceTxPwr= true;
+ u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
+ write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
+ //RT_TRACE(COMP_RATE, DBG_TRACE, ("Enhance OFDM_TXAGC(2) : +++++ u1bOfdm= 0x%x\n", u1bOfdm));
+ }
+ }
+ }
+ else if(priv->bEnhanceTxPwr) //54/48/11/5.5/2/1
+ {
+ u1bCck = read_nic_byte(dev, CCK_TXAGC);
+ u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
+
+ // case 1: Never enter High power
+ if(u1bCck == CckTxPwrIdx )
+ {
+ priv->bEnhanceTxPwr= false;
+ write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
+ //printk("Recover OFDM_TXAGC : ===== u1bOfdm= 0x%x\n", OfdmTxPwrIdx);
+ }
+ // case 2: enter high power
+ else if(u1bCck < CckTxPwrIdx)
+ {
+ priv->bEnhanceTxPwr= false;
+ u1bOfdm = ((u1bOfdm-2) > 0) ? (u1bOfdm-2): 0;
+ write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
+ //RT_TRACE(COMP_RATE, DBG_TRACE, ("Recover OFDM_TXAGC(2): ===== u1bOfdm= 0x%x\n", u1bOfdm));
+
+ }
+ }
+
+ //
+ // We need update initial gain when we set tx rate "from OFDM to CCK" or
+ // "from CCK to OFDM".
+ //
+SetInitialGain:
+ if(bUpdateInitialGain)
+ {
+ if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK
+ {
+ if(priv->InitialGain > priv->RegBModeGainStage)
+ {
+ priv->InitialGainBackUp= priv->InitialGain;
+
+ if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.
+ {
+ //SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26.
+ priv->InitialGain = priv->RegBModeGainStage;
+ }
+ else if(priv->InitialGain > priv->RegBModeGainStage + 1)
+ {
+ priv->InitialGain -= 2;
+ }
+ else
+ {
+ priv->InitialGain --;
+ }
+ printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
+ UpdateInitialGain(dev);
+ }
+ }
+ else // OFDM
+ {
+ if(priv->InitialGain < 4)
+ {
+ priv->InitialGainBackUp= priv->InitialGain;
+
+ priv->InitialGain ++;
+ printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
+ UpdateInitialGain(dev);
+ }
+ }
+ }
+
+ //Record the related info
+ priv->LastRetryRate = CurrRetryRate;
+ priv->LastTxThroughput = TxThroughput;
+ priv->ieee80211->rate = priv->CurrentOperaRate * 5;
+}
+
+#endif
+#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
+void rtl8180_rate_adapter(struct work_struct * work)
+{
+ struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+ struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);
+ struct net_device *dev = ieee->dev;
+#else
+void rtl8180_rate_adapter(struct net_device *dev)
+{
+
+#endif
+ //struct r8180_priv *priv = ieee80211_priv(dev);
+// DMESG("---->rtl8180_rate_adapter");
+ StaRateAdaptive87SE(dev);
+// DMESG("<----rtl8180_rate_adapter");
+}
+void timer_rate_adaptive(unsigned long data)
+{
+ struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
+ //DMESG("---->timer_rate_adaptive()\n");
+ if(!priv->up)
+ {
+// DMESG("<----timer_rate_adaptive():driver is not up!\n");
+ return;
+ }
+ if((priv->ieee80211->iw_mode != IW_MODE_MASTER)
+ && (priv->ieee80211->state == IEEE80211_LINKED) &&
+ (priv->ForcedDataRate == 0) )
+ {
+// DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
+#ifdef CONFIG_RTL818X_S
+ queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
+// StaRateAdaptive87SE((struct net_device *)data);
+#endif
+ }
+ priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
+ add_timer(&priv->rateadapter_timer);
+ //DMESG("<----timer_rate_adaptive()\n");
+}
+//by amy 080312}
+void
+SwAntennaDiversityRxOk8185(
+ struct net_device *dev,
+ u8 SignalStrength
+ )
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+
+// printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
+
+ priv->AdRxOkCnt++;
+
+ if( priv->AdRxSignalStrength != -1)
+ {
+ priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
+ }
+ else
+ { // Initialization case.
+ priv->AdRxSignalStrength = SignalStrength;
+ }
+//{+by amy 080312
+ if( priv->LastRxPktAntenna ) //Main antenna.
+ priv->AdMainAntennaRxOkCnt++;
+ else // Aux antenna.
+ priv->AdAuxAntennaRxOkCnt++;
+//+by amy 080312
+// printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
+}
+//
+// Description:
+// Change Antenna Switch.
+//
+bool
+SetAntenna8185(
+ struct net_device *dev,
+ u8 u1bAntennaIndex
+ )
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+ bool bAntennaSwitched = false;
+
+// printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
+
+ switch(u1bAntennaIndex)
+ {
+ case 0:
+ switch(priv->rf_chip)
+ {
+ case RF_ZEBRA2:
+ case RF_ZEBRA4:
+#ifdef CONFIG_RTL8185B
+#ifdef CONFIG_RTL818X_S
+ // Mac register, main antenna
+ write_nic_byte(dev, ANTSEL, 0x03);
+ //base band
+ write_phy_cck(dev,0x11, 0x9b); // Config CCK RX antenna.
+ write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
+
+#else
+ // Mac register, main antenna
+ write_nic_byte(dev, ANTSEL, 0x03);
+ //base band
+ write_phy_cck(dev, 0x10, 0x9b); // Config CCK RX antenna.
+ write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
+#endif
+#endif
+
+ bAntennaSwitched = true;
+ break;
+
+ default:
+ printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
+ break;
+ }
+ break;
+
+ case 1:
+ switch(priv->rf_chip)
+ {
+ case RF_ZEBRA2:
+ case RF_ZEBRA4:
+#ifdef CONFIG_RTL8185B
+#ifdef CONFIG_RTL818X_S
+ // Mac register, aux antenna
+ write_nic_byte(dev, ANTSEL, 0x00);
+ //base band
+ write_phy_cck(dev, 0x11, 0xbb); // Config CCK RX antenna.
+ write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
+#else
+ // Mac register, aux antenna
+ write_nic_byte(dev, ANTSEL, 0x00);
+ //base band
+ write_phy_cck(dev, 0x10, 0xbb); // Config CCK RX antenna.
+ write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
+#endif
+#endif
+
+ bAntennaSwitched = true;
+ break;
+
+ default:
+ printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
+ break;
+ }
+ break;
+
+ default:
+ printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
+ break;
+ }
+
+ if(bAntennaSwitched)
+ {
+ priv->CurrAntennaIndex = u1bAntennaIndex;
+ }
+
+// printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
+
+ return bAntennaSwitched;
+}
+//
+// Description:
+// Toggle Antenna switch.
+//
+bool
+SwitchAntenna(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+
+ bool bResult;
+
+ if(priv->CurrAntennaIndex == 0)
+ {
+#if 0//lzm del 080826
+//by amy 080312
+#ifdef CONFIG_RTL818X_S
+ if(priv->bSwAntennaDiverity)
+ bResult = SetAntennaConfig87SE(dev, 1, true);
+ else
+#endif
+#endif
+ bResult = SetAntenna8185(dev, 1);
+//by amy 080312
+// printk("SwitchAntenna(): switching to antenna 1 ......\n");
+// bResult = SetAntenna8185(dev, 1);//-by amy 080312
+ }
+ else
+ {
+#if 0//lzm del 080826
+//by amy 080312
+#ifdef CONFIG_RTL818X_S
+ if(priv->bSwAntennaDiverity)
+ bResult = SetAntennaConfig87SE(dev, 0, true);
+ else
+#endif
+#endif
+ bResult = SetAntenna8185(dev, 0);
+//by amy 080312
+// printk("SwitchAntenna(): switching to antenna 0 ......\n");
+// bResult = SetAntenna8185(dev, 0);//-by amy 080312
+ }
+
+ return bResult;
+}
+//
+// Description:
+// Engine of SW Antenna Diversity mechanism.
+// Since 8187 has no Tx part information,
+// this implementation is only dependend on Rx part information.
+//
+// 2006.04.17, by rcnjko.
+//
+void
+SwAntennaDiversity(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+ bool bSwCheckSS=false;
+// printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);
+// printk("AdTickCount is %d\n",priv->AdTickCount);
+//by amy 080312
+ if(bSwCheckSS)
+ {
+ priv->AdTickCount++;
+
+ printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n",
+ priv->AdTickCount, priv->AdCheckPeriod);
+ printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n",
+ priv->AdRxSignalStrength, priv->AdRxSsThreshold);
+ }
+// priv->AdTickCount++;//-by amy 080312
+
+ // Case 1. No Link.
+ if(priv->ieee80211->state != IEEE80211_LINKED)
+ {
+ // printk("SwAntennaDiversity(): Case 1. No Link.\n");
+
+ priv->bAdSwitchedChecking = false;
+ // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..
+ SwitchAntenna(dev);
+ }
+ // Case 2. Linked but no packet received.
+ else if(priv->AdRxOkCnt == 0)
+ {
+ // printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
+
+ priv->bAdSwitchedChecking = false;
+ SwitchAntenna(dev);
+ }
+ // Case 3. Evaluate last antenna switch action and undo it if necessary.
+ else if(priv->bAdSwitchedChecking == true)
+ {
+ // printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
+
+ priv->bAdSwitchedChecking = false;
+
+ // Adjust Rx signal strength threashold.
+ priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
+
+ priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
+ priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
+ if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched)
+ { // Rx signal strength is not improved after we swtiched antenna. => Swich back.
+// printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %d, LastRxSs: %d\n",
+// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
+//by amy 080312
+ // Increase Antenna Diversity checking period due to bad decision.
+ priv->AdCheckPeriod *= 2;
+//by amy 080312
+ // Increase Antenna Diversity checking period.
+ if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
+ priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
+
+ // Wrong deceision => switch back.
+ SwitchAntenna(dev);
+ }
+ else
+ { // Rx Signal Strength is improved.
+// printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %d, LastRxSs: %d\n",
+// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
+
+ // Reset Antenna Diversity checking period to its min value.
+ priv->AdCheckPeriod = priv->AdMinCheckPeriod;
+ }
+
+// printk("SwAntennaDiversity(): AdRxSsThreshold: %d, AdCheckPeriod: %d\n",
+// priv->AdRxSsThreshold, priv->AdCheckPeriod);
+ }
+ // Case 4. Evaluate if we shall switch antenna now.
+ // Cause Table Speed is very fast in TRC Dell Lab, we check it every time.
+ else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312
+ {
+// printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
+
+ priv->AdTickCount = 0;
+
+ //
+ // <Roger_Notes> We evaluate RxOk counts for each antenna first and than
+ // evaluate signal strength.
+ // The following operation can overcome the disability of CCA on both two antennas
+ // When signal strength was extremely low or high.
+ // 2008.01.30.
+ //
+
+ //
+ // Evaluate RxOk count from each antenna if we shall switch default antenna now.
+ // Added by Roger, 2008.02.21.
+//{by amy 080312
+ if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt)
+ && (priv->CurrAntennaIndex == 0))
+ { // We set Main antenna as default but RxOk count was less than Aux ones.
+
+ // printk("SwAntennaDiversity(): Main antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
+ // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
+
+ // Switch to Aux antenna.
+ SwitchAntenna(dev);
+ priv->bHWAdSwitched = true;
+ }
+ else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt)
+ && (priv->CurrAntennaIndex == 1))
+ { // We set Aux antenna as default but RxOk count was less than Main ones.
+
+ // printk("SwAntennaDiversity(): Aux antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
+ // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
+
+ // Switch to Main antenna.
+ SwitchAntenna(dev);
+ priv->bHWAdSwitched = true;
+ }
+ else
+ {// Default antenna is better.
+
+ // printk("SwAntennaDiversity(): Default antenna is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
+ // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
+
+ // Still need to check current signal strength.
+ priv->bHWAdSwitched = false;
+ }
+ //
+ // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
+ // didn't changed by HW evaluation.
+ // 2008.02.27.
+ //
+ // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
+ // For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
+ // but AdRxSignalStrength is less than main.
+ // Our guess is that main antenna have lower throughput and get many change
+ // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
+ //
+ if( (!priv->bHWAdSwitched) && (bSwCheckSS))
+ {
+//by amy 080312}
+ // Evaluate Rx signal strength if we shall switch antenna now.
+ if(priv->AdRxSignalStrength < priv->AdRxSsThreshold)
+ { // Rx signal strength is weak => Switch Antenna.
+// printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %d, RxSsThreshold: %d\n",
+// priv->AdRxSignalStrength, priv->AdRxSsThreshold);
+
+ priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
+ priv->bAdSwitchedChecking = true;
+
+ SwitchAntenna(dev);
+ }
+ else
+ { // Rx signal strength is OK.
+// printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %d, RxSsThreshold: %d\n",
+// priv->AdRxSignalStrength, priv->AdRxSsThreshold);
+
+ priv->bAdSwitchedChecking = false;
+ // Increase Rx signal strength threashold if necessary.
+ if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold
+ priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit.
+ {
+ priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
+ priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
+ priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312
+ }
+
+ // Reduce Antenna Diversity checking period if possible.
+ if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
+ {
+ priv->AdCheckPeriod /= 2;
+ }
+ }
+ }
+ }
+//by amy 080312
+ // Reset antenna diversity Rx related statistics.
+ priv->AdRxOkCnt = 0;
+ priv->AdMainAntennaRxOkCnt = 0;
+ priv->AdAuxAntennaRxOkCnt = 0;
+//by amy 080312
+
+// priv->AdRxOkCnt = 0;//-by amy 080312
+
+// printk("-SwAntennaDiversity()\n");
+}
+
+//
+// Description:
+// Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise.
+//
+bool
+CheckTxPwrTracking( struct net_device *dev)
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+
+ if(!priv->bTxPowerTrack)
+ {
+ return false;
+ }
+
+//lzm reserved 080826
+ //if(priv->bScanInProgress)
+ //{
+ // return false;
+ //}
+
+ //if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah
+ if(priv->bToUpdateTxPwr)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+//
+// Description:
+// Timer callback function of SW Antenna Diversity.
+//
+void
+SwAntennaDiversityTimerCallback(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+ RT_RF_POWER_STATE rtState;
+
+ //printk("+SwAntennaDiversityTimerCallback()\n");
+
+ //
+ // We do NOT need to switch antenna while RF is off.
+ // 2007.05.09, added by Roger.
+ //
+ rtState = priv->eRFPowerState;
+ do{
+ if (rtState == eRfOff)
+ {
+// printk("SwAntennaDiversityTimer - RF is OFF.\n");
+ break;
+ }
+ else if (rtState == eRfSleep)
+ {
+ // Don't access BB/RF under Disable PLL situation.
+ //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
+ break;
+ }
+ SwAntennaDiversity(dev);
+
+ }while(false);
+
+ if(priv->up)
+ {
+ priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
+ add_timer(&priv->SwAntennaDiversityTimer);
+ }
+
+ //printk("-SwAntennaDiversityTimerCallback()\n");
+}
+
diff --git a/drivers/staging/rtl8187se/r8180_dm.h b/drivers/staging/rtl8187se/r8180_dm.h
index 3de92f040f9..b2736c8e521 100644
--- a/drivers/staging/rtl8187se/r8180_dm.h
+++ b/drivers/staging/rtl8187se/r8180_dm.h
@@ -1,41 +1,41 @@
-#ifndef R8180_DM_H
-#define R8180_DM_H
-
-#include "r8180.h"
-//#include "r8180_hw.h"
-//#include "r8180_93cx6.h"
-void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
-bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex);
-bool SwitchAntenna( struct net_device *dev);
-void SwAntennaDiversity(struct net_device *dev );
-void SwAntennaDiversityTimerCallback(struct net_device *dev);
-bool CheckDig(struct net_device *dev);
-bool CheckHighPower(struct net_device *dev);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-void rtl8180_hw_dig_wq (struct work_struct *work);
-#else
-void rtl8180_hw_dig_wq(struct net_device *dev);
-#endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-void rtl8180_tx_pw_wq (struct work_struct *work);
-#else
-void rtl8180_tx_pw_wq(struct net_device *dev);
-#endif
-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
-void rtl8180_rate_adapter(struct work_struct * work);
-
-#else
-void rtl8180_rate_adapter(struct net_device *dev);
-
-#endif
-void TxPwrTracking87SE(struct net_device *dev);
-bool CheckTxPwrTracking(struct net_device *dev);
-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
-void rtl8180_rate_adapter(struct work_struct * work);
-#else
-void rtl8180_rate_adapter(struct net_device *dev);
-#endif
-void timer_rate_adaptive(unsigned long data);
-
-
-#endif
+#ifndef R8180_DM_H
+#define R8180_DM_H
+
+#include "r8180.h"
+//#include "r8180_hw.h"
+//#include "r8180_93cx6.h"
+void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
+bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex);
+bool SwitchAntenna( struct net_device *dev);
+void SwAntennaDiversity(struct net_device *dev );
+void SwAntennaDiversityTimerCallback(struct net_device *dev);
+bool CheckDig(struct net_device *dev);
+bool CheckHighPower(struct net_device *dev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_hw_dig_wq (struct work_struct *work);
+#else
+void rtl8180_hw_dig_wq(struct net_device *dev);
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_tx_pw_wq (struct work_struct *work);
+#else
+void rtl8180_tx_pw_wq(struct net_device *dev);
+#endif
+#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
+void rtl8180_rate_adapter(struct work_struct * work);
+
+#else
+void rtl8180_rate_adapter(struct net_device *dev);
+
+#endif
+void TxPwrTracking87SE(struct net_device *dev);
+bool CheckTxPwrTracking(struct net_device *dev);
+#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
+void rtl8180_rate_adapter(struct work_struct * work);
+#else
+void rtl8180_rate_adapter(struct net_device *dev);
+#endif
+void timer_rate_adaptive(unsigned long data);
+
+
+#endif
diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c
index 8b3901d87f8..979ba0b5f33 100644
--- a/drivers/staging/rtl8187se/r8180_wx.c
+++ b/drivers/staging/rtl8187se/r8180_wx.c
@@ -1274,8 +1274,8 @@ static int r8180_wx_set_enc_ext(struct net_device *dev,
}
static int r8180_wx_set_auth(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *data, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
//printk("====>%s()\n", __func__);
struct r8180_priv *priv = ieee80211_priv(dev);
@@ -1285,7 +1285,7 @@ static int r8180_wx_set_auth(struct net_device *dev,
return 0;
down(&priv->wx_sem);
- ret = ieee80211_wx_set_auth(priv->ieee80211, info, data, extra);
+ ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
up(&priv->wx_sem);
return ret;
}
@@ -1312,8 +1312,8 @@ static int r8180_wx_set_mlme(struct net_device *dev,
return ret;
}
static int r8180_wx_set_gen_ie(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
// printk("====>%s(), len:%d\n", __func__, data->length);
int ret=0;
@@ -1325,7 +1325,7 @@ static int r8180_wx_set_gen_ie(struct net_device *dev,
down(&priv->wx_sem);
#if 1
- ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->length);
+ ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
#endif
up(&priv->wx_sem);
//printk("<======%s(), ret:%d\n", __func__, ret);
diff --git a/drivers/staging/serqt_usb/Kconfig b/drivers/staging/serqt_usb/Kconfig
new file mode 100644
index 00000000000..cc1af5df40d
--- /dev/null
+++ b/drivers/staging/serqt_usb/Kconfig
@@ -0,0 +1,9 @@
+config USB_SERIAL_QUATECH_ESU100
+ tristate "USB Quatech ESU-100 8 Port Serial Driver"
+ depends on USB_SERIAL
+ help
+ Say Y here if you want to use the Quatech ESU-100 8 port usb to
+ serial adapter.
+
+ To compile this driver as a module, choose M here: the
+ module will be called serqt_usb.
diff --git a/drivers/staging/serqt_usb/Makefile b/drivers/staging/serqt_usb/Makefile
new file mode 100644
index 00000000000..4fd1da275e8
--- /dev/null
+++ b/drivers/staging/serqt_usb/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_SERIAL_QUATECH_ESU100) += serqt_usb.o
diff --git a/drivers/staging/serqt_usb/TODO b/drivers/staging/serqt_usb/TODO
new file mode 100644
index 00000000000..34ecca8992d
--- /dev/null
+++ b/drivers/staging/serqt_usb/TODO
@@ -0,0 +1,8 @@
+Things to do for this driver to get merged into the main portion of the
+kernel:
+ - checkpatch cleanups
+ - sparse clean
+ - port to the usb-serial layer instead of doing it all on its
+ own.
+
+Send patches to Greg Kroah-Hartman <greg@kroah.com>
diff --git a/drivers/staging/serqt_usb/serqt_usb.c b/drivers/staging/serqt_usb/serqt_usb.c
new file mode 100644
index 00000000000..234f332fc82
--- /dev/null
+++ b/drivers/staging/serqt_usb/serqt_usb.c
@@ -0,0 +1,2656 @@
+/*
+ * This code was developed for the Quatech USB line for linux, it used
+ * much of the code developed by Greg Kroah-Hartman for USB serial devices
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/uaccess.h>
+
+/* Use our own dbg macro */
+/* #define DEBUG_ON */
+/* #undef dbg */
+#ifdef DEBUG_ON
+#define mydbg(const...) printk(const)
+#else
+#define mydbg(const...)
+#endif
+
+/* parity check flag */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+#define SERIAL_TTY_MAJOR 0 /* Nice legal number now */
+#define SERIAL_TTY_MINORS 255 /* loads of devices :) */
+#define MAX_NUM_PORTS 8 /* The maximum number of ports one device can grab at once */
+#define PREFUFF_LEVEL_CONSERVATIVE 128
+#define ATC_DISABLED 0x00
+
+#define RR_BITS 0x03 /* for clearing clock bits */
+#define DUPMODE_BITS 0xc0
+
+#define RS232_MODE 0x00
+#define RTSCTS_TO_CONNECTOR 0x40
+#define CLKS_X4 0x02
+
+#define LOOPMODE_BITS 0x41 /* LOOP1 = b6, LOOP0 = b0 (PORT B) */
+#define ALL_LOOPBACK 0x01
+#define MODEM_CTRL 0x40
+
+#define THISCHAR data[i]
+#define NEXTCHAR data[i + 1]
+#define THIRDCHAR data[i + 2]
+#define FOURTHCHAR data[i + 3]
+
+/*
+ * Useful defintions for port A, Port B and Port C
+ */
+#define FULLPWRBIT 0x00000080
+#define NEXT_BOARD_POWER_BIT 0x00000004
+
+#define SERIAL_LSR_OE 0x02
+#define SERIAL_LSR_PE 0x04
+#define SERIAL_LSR_FE 0x08
+#define SERIAL_LSR_BI 0x10
+
+#define SERIAL_LSR_TEMT 0x40
+
+#define DIV_LATCH_LS 0x00
+#define XMT_HOLD_REGISTER 0x00
+#define XVR_BUFFER_REGISTER 0x00
+#define DIV_LATCH_MS 0x01
+#define FIFO_CONTROL_REGISTER 0x02
+#define LINE_CONTROL_REGISTER 0x03
+#define MODEM_CONTROL_REGISTER 0x04
+#define LINE_STATUS_REGISTER 0x05
+#define MODEM_STATUS_REGISTER 0x06
+
+#define SERIAL_MCR_DTR 0x01
+#define SERIAL_MCR_RTS 0x02
+#define SERIAL_MCR_LOOP 0x10
+
+#define SERIAL_MSR_CTS 0x10
+#define SERIAL_MSR_CD 0x80
+#define SERIAL_MSR_RI 0x40
+#define SERIAL_MSR_DSR 0x20
+#define SERIAL_MSR_MASK 0xf0
+
+#define SERIAL_8_DATA 0x03
+#define SERIAL_7_DATA 0x02
+#define SERIAL_6_DATA 0x01
+#define SERIAL_5_DATA 0x00
+
+#define SERIAL_ODD_PARITY 0X08
+#define SERIAL_EVEN_PARITY 0X18
+#define SERIAL_TWO_STOPB 0x04
+#define SERIAL_ONE_STOPB 0x00
+
+#define MAX_BAUD_RATE 460800
+#define MAX_BAUD_REMAINDER 4608
+
+#define QT_SET_GET_DEVICE 0xc2
+#define QT_OPEN_CLOSE_CHANNEL 0xca
+#define QT_GET_SET_PREBUF_TRIG_LVL 0xcc
+#define QT_SET_ATF 0xcd
+#define QT_GET_SET_REGISTER 0xc0
+#define QT_GET_SET_UART 0xc1
+#define QT_HW_FLOW_CONTROL_MASK 0xc5
+#define QT_SW_FLOW_CONTROL_MASK 0xc6
+#define QT_SW_FLOW_CONTROL_DISABLE 0xc7
+#define QT_BREAK_CONTROL 0xc8
+
+#define SERIALQT_PCI_IOC_MAGIC 'k'
+#define SERIALQT_WRITE_QOPR _IOW(SERIALQT_PCI_IOC_MAGIC, 0, int)
+#define SERIALQT_WRITE_QMCR _IOW(SERIALQT_PCI_IOC_MAGIC, 1, int)
+#define SERIALQT_GET_NUMOF_UNITS _IOR(SERIALQT_PCI_IOC_MAGIC, 2, void *)
+#define SERIALQT_GET_THIS_UNIT _IOR(SERIALQT_PCI_IOC_MAGIC, 3, void *)
+#define SERIALQT_READ_QOPR _IOR(SERIALQT_PCI_IOC_MAGIC, 4, int)
+#define SERIALQT_READ_QMCR _IOR(SERIALQT_PCI_IOC_MAGIC, 5, int)
+#define SERIALQT_IS422_EXTENDED _IOR(SERIALQT_PCI_IOC_MAGIC, 6, int) /* returns successful if 422 extended */
+
+#define USBD_TRANSFER_DIRECTION_IN 0xc0
+#define USBD_TRANSFER_DIRECTION_OUT 0x40
+
+#define ATC_DISABLED 0x00
+#define ATC_RTS_ENABLED 0x02
+#define ATC_DTR_ENABLED 0x01
+
+#define RR_BITS 0x03 /* for clearing clock bits */
+#define DUPMODE_BITS 0xc0
+
+#define FULL_DUPLEX 0x00
+#define HALF_DUPLEX_RTS 0x40
+#define HALF_DUPLEX_DTR 0x80
+
+#define QMCR_FULL_DUPLEX 0x00
+#define QMCR_HALF_DUPLEX_RTS 0x02
+#define QMCR_HALF_DUPLEX_DTR 0x01
+#define QMCR_HALF_DUPLEX_MASK 0x03
+#define QMCR_CONNECTOR_MASK 0x1C
+
+#define QMCR_RX_EN_MASK 0x20
+
+#define QMCR_ALL_LOOPBACK 0x10
+#define QMCR_MODEM_CONTROL 0X00
+
+#define SERIALQT_IOC_MAXNR 6
+
+struct usb_serial_port {
+ struct usb_serial *serial; /* pointer back to the owner of this port */
+ struct tty_struct *tty; /* the coresponding tty for this port */
+ unsigned char number;
+ char active; /* someone has this device open */
+
+ unsigned char *interrupt_in_buffer;
+ struct urb *interrupt_in_urb;
+ __u8 interrupt_in_endpointAddress;
+
+ unsigned char *bulk_in_buffer;
+ unsigned char *xfer_to_tty_buffer;
+ struct urb *read_urb;
+ __u8 bulk_in_endpointAddress;
+
+ unsigned char *bulk_out_buffer;
+ int bulk_out_size;
+ struct urb *write_urb;
+ __u8 bulk_out_endpointAddress;
+
+ wait_queue_head_t write_wait;
+ wait_queue_head_t wait;
+ struct work_struct work;
+
+ int open_count; /* number of times this port has been opened */
+ struct semaphore sem; /* locks this structure */
+
+ __u8 shadowLCR; /* last LCR value received */
+ __u8 shadowMCR; /* last MCR value received */
+ __u8 shadowMSR; /* last MSR value received */
+ __u8 shadowLSR; /* last LSR value received */
+ int RxHolding;
+ char closePending;
+ int ReadBulkStopped;
+
+ void *private; /* data private to the specific port */
+};
+
+struct identity {
+ int index;
+ int n_identity;
+};
+
+struct usb_serial {
+ struct usb_device *dev;
+ struct usb_interface *interface; /* the interface for this device */
+ struct tty_driver *tty_driver; /* the tty_driver for this device */
+ unsigned char minor; /* the starting minor number for this device */
+ unsigned char num_ports; /* the number of ports this device has */
+ char num_interrupt_in; /* number of interrupt in endpoints we have */
+ char num_bulk_in; /* number of bulk in endpoints we have */
+ char num_bulk_out; /* number of bulk out endpoints we have */
+ unsigned char num_OpenCount; /* the number of ports this device has */
+
+ __u16 vendor; /* vendor id of this device */
+ __u16 product; /* product id of this device */
+ struct usb_serial_port port[MAX_NUM_PORTS];
+
+ void *private; /* data private to the specific driver */
+};
+
+static inline int port_paranoia_check(struct usb_serial_port *port,
+ const char *function)
+{
+ if (!port) {
+ dbg("%s - port == NULL", function);
+ return -1;
+ }
+ if (!port->serial) {
+ dbg("%s - port->serial == NULL\n", function);
+ return -1;
+ }
+ if (!port->tty) {
+ dbg("%s - port->tty == NULL\n", function);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Inline functions to check the sanity of a pointer that is passed to us */
+static inline int serial_paranoia_check(struct usb_serial *serial,
+ const char *function)
+{
+ if (!serial) {
+ dbg("%s - serial == NULL\n", function);
+ return -1;
+ }
+
+ return 0;
+}
+
+static inline struct usb_serial *get_usb_serial(struct usb_serial_port *port,
+ const char *function)
+{
+ /* if no port was specified, or it fails a paranoia check */
+ if (!port ||
+ port_paranoia_check(port, function) ||
+ serial_paranoia_check(port->serial, function)) {
+ /* then say that we dont have a valid usb_serial thing, which will
+ * end up genrating -ENODEV return values */
+ return NULL;
+ }
+
+ return port->serial;
+}
+
+struct qt_get_device_data {
+ __u8 porta;
+ __u8 portb;
+ __u8 portc;
+};
+
+struct qt_open_channel_data {
+ __u8 line_status;
+ __u8 modem_status;
+};
+
+static void ProcessLineStatus(struct usb_serial_port *port,
+ unsigned char line_status);
+static void ProcessModemStatus(struct usb_serial_port *port,
+ unsigned char modem_status);
+static void ProcessRxChar(struct usb_serial_port *port, unsigned char Data);
+static struct usb_serial *get_free_serial(int num_ports, int *minor);
+
+static int serqt_probe(struct usb_interface *interface,
+ const struct usb_device_id *id);
+
+static void serqt_usb_disconnect(struct usb_interface *interface);
+static int box_set_device(struct usb_serial *serial,
+ struct qt_get_device_data *pDeviceData);
+static int box_get_device(struct usb_serial *serial,
+ struct qt_get_device_data *pDeviceData);
+static int serial_open(struct tty_struct *tty, struct file *filp);
+static void serial_close(struct tty_struct *tty, struct file *filp);
+static int serial_write_room(struct tty_struct *tty);
+static int serial_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg);
+static void serial_set_termios(struct tty_struct *tty, struct ktermios *old);
+static int serial_write(struct tty_struct *tty, const unsigned char *buf,
+ int count);
+
+static void serial_throttle(struct tty_struct *tty);
+static void serial_unthrottle(struct tty_struct *tty);
+static int serial_break(struct tty_struct *tty, int break_state);
+static int serial_chars_in_buffer(struct tty_struct *tty);
+
+static int qt_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
+static int BoxSetPrebufferLevel(struct usb_serial *serial);
+
+static int BoxSetATC(struct usb_serial *serial, __u16 n_Mode);
+static int BoxSetUart(struct usb_serial *serial, unsigned short Uart_Number,
+ unsigned short default_divisor,
+ unsigned char default_LCR);
+
+static int BoxOPenCloseChannel(struct usb_serial *serial, __u16 Uart_Number,
+ __u16 OpenClose,
+ struct qt_open_channel_data *pDeviceData);
+static void qt_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp);
+static int BoxGetRegister(struct usb_serial *serial, unsigned short Uart_Number,
+ unsigned short Register_Num, __u8 *pValue);
+static int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number,
+ unsigned short Register_Num, unsigned short Value);
+static void qt_write_bulk_callback(struct urb *urb);
+static int qt_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count);
+static void port_softint(struct work_struct *work);
+static int qt_write_room(struct usb_serial_port *port);
+static int qt_chars_in_buffer(struct usb_serial_port *port);
+static int qt_ioctl(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *file, unsigned int cmd, unsigned long arg);
+static void qt_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port,
+ struct ktermios *old_termios);
+static int BoxSetHW_FlowCtrl(struct usb_serial *serial, unsigned int index,
+ int bSet);
+static int BoxDisable_SW_FlowCtrl(struct usb_serial *serial, __u16 index);
+static int EmulateWriteQMCR_Reg(int index, unsigned uc_value);
+static int EmulateReadQMCR_Reg(int index, unsigned *uc_value);
+static struct usb_serial *find_the_box(unsigned int index);
+static int ioctl_serial_usb(struct inode *innod, struct file *filp, unsigned int cmd,
+ unsigned long arg);
+
+static int BoxSetSW_FlowCtrl(struct usb_serial *serial, __u16 Uart,
+ unsigned char stop_char, unsigned char start_char);
+static void qt_read_bulk_callback(struct urb *urb);
+
+static void port_sofrint(void *private);
+
+static void return_serial(struct usb_serial *serial);
+
+static int serial_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
+static int serial_tiocmget(struct tty_struct *tty, struct file *file);
+
+static int qt_tiocmset(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *file, unsigned int value);
+
+static int qt_tiocmget(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *file);
+
+/* Version Information */
+#define DRIVER_VERSION "v2.14"
+#define DRIVER_AUTHOR "Tim Gobeli, Quatech, Inc"
+#define DRIVER_DESC "Quatech USB to Serial Driver"
+
+#define USB_VENDOR_ID_QUATECH 0x061d /* Quatech VID */
+#define DEVICE_ID_QUATECH_RS232_SINGLE_PORT 0xC020 /* SSU100 */
+#define DEVICE_ID_QUATECH_RS422_SINGLE_PORT 0xC030 /* SSU200 */
+#define DEVICE_ID_QUATECH_RS232_DUAL_PORT 0xC040 /* DSU100 */
+#define DEVICE_ID_QUATECH_RS422_DUAL_PORT 0xC050 /* DSU200 */
+#define DEVICE_ID_QUATECH_RS232_FOUR_PORT 0xC060 /* QSU100 */
+#define DEVICE_ID_QUATECH_RS422_FOUR_PORT 0xC070 /* QSU200 */
+#define DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A 0xC080 /* ESU100A */
+#define DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B 0xC081 /* ESU100B */
+#define DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A 0xC0A0 /* ESU200A */
+#define DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B 0xC0A1 /* ESU200B */
+#define DEVICE_ID_QUATECH_RS232_16_PORT_A 0xC090 /* HSU100A */
+#define DEVICE_ID_QUATECH_RS232_16_PORT_B 0xC091 /* HSU100B */
+#define DEVICE_ID_QUATECH_RS232_16_PORT_C 0xC092 /* HSU100C */
+#define DEVICE_ID_QUATECH_RS232_16_PORT_D 0xC093 /* HSU100D */
+#define DEVICE_ID_QUATECH_RS422_16_PORT_A 0xC0B0 /* HSU200A */
+#define DEVICE_ID_QUATECH_RS422_16_PORT_B 0xC0B1 /* HSU200B */
+#define DEVICE_ID_QUATECH_RS422_16_PORT_C 0xC0B2 /* HSU200C */
+#define DEVICE_ID_QUATECH_RS422_16_PORT_D 0xC0B3 /* HSU200D */
+
+/* table of Quatech devices */
+static struct usb_device_id serqt_table[] = {
+ {USB_DEVICE
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_SINGLE_PORT)},
+ {USB_DEVICE
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_SINGLE_PORT)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_DUAL_PORT)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_DUAL_PORT)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_FOUR_PORT)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_FOUR_PORT)},
+ {USB_DEVICE
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A)},
+ {USB_DEVICE
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B)},
+ {USB_DEVICE
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A)},
+ {USB_DEVICE
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_A)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_B)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_C)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_D)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_A)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_B)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_C)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_D)},
+ {} /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, serqt_table);
+
+static int major_number;
+static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */
+
+/* table of Quatech 422devices */
+static unsigned int serqt_422_table[] = {
+ DEVICE_ID_QUATECH_RS422_SINGLE_PORT,
+ DEVICE_ID_QUATECH_RS422_DUAL_PORT,
+ DEVICE_ID_QUATECH_RS422_FOUR_PORT,
+ DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A,
+ DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B,
+ DEVICE_ID_QUATECH_RS422_16_PORT_A,
+ DEVICE_ID_QUATECH_RS422_16_PORT_B,
+ DEVICE_ID_QUATECH_RS422_16_PORT_C,
+ DEVICE_ID_QUATECH_RS422_16_PORT_D,
+ 0 /* terminate with zero */
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver serqt_usb_driver = {
+ .name = "quatech-usb-serial",
+ .probe = serqt_probe,
+ .disconnect = serqt_usb_disconnect,
+ .id_table = serqt_table,
+};
+
+static struct ktermios *serial_termios[SERIAL_TTY_MINORS];
+static struct ktermios *serial_termios_locked[SERIAL_TTY_MINORS];
+
+static const struct tty_operations serial_ops = {
+ .open = serial_open,
+ .close = serial_close,
+ .write = serial_write,
+ .write_room = serial_write_room,
+ .ioctl = serial_ioctl,
+ .set_termios = serial_set_termios,
+ .throttle = serial_throttle,
+ .unthrottle = serial_unthrottle,
+ .break_ctl = serial_break,
+ .chars_in_buffer = serial_chars_in_buffer,
+ .tiocmset = serial_tiocmset,
+ .tiocmget = serial_tiocmget,
+};
+
+static struct tty_driver serial_tty_driver = {
+ .magic = TTY_DRIVER_MAGIC,
+ .driver_name = "Quatech usb-serial",
+ .name = "ttyQT_USB",
+ .major = SERIAL_TTY_MAJOR,
+ .minor_start = 0,
+ .num = SERIAL_TTY_MINORS,
+ .type = TTY_DRIVER_TYPE_SERIAL,
+ .subtype = SERIAL_TYPE_NORMAL,
+ .flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV,
+
+ .termios = serial_termios,
+ .termios_locked = serial_termios_locked,
+ .init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL,
+
+ .init_termios.c_iflag = ICRNL | IXON,
+ .init_termios.c_oflag = OPOST,
+
+ .init_termios.c_lflag =
+ ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN,
+};
+
+/* fops for parent device */
+static const struct file_operations serialqt_usb_fops = {
+ .ioctl = ioctl_serial_usb,
+};
+
+ /**
+ * serqt_probe
+ *
+ * Called by the usb core when a new device is connected that it thinks
+ * this driver might be interested in.
+ *
+ */
+static int serqt_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct usb_device *dev = interface_to_usbdev(interface);
+ struct usb_serial *serial = NULL;
+ struct usb_serial_port *port;
+ struct usb_endpoint_descriptor *endpoint;
+ struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
+ struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];
+ struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];
+ int minor;
+ int buffer_size;
+ int i;
+ struct usb_host_interface *iface_desc;
+ int num_interrupt_in = 0;
+ int num_bulk_in = 0;
+ int num_bulk_out = 0;
+ int num_ports;
+ struct qt_get_device_data DeviceData;
+ int status;
+
+ mydbg("In %s\n", __func__);
+
+ /* let's find the endpoints needed */
+ /* check out the endpoints */
+ iface_desc = interface->cur_altsetting;;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ if ((endpoint->bEndpointAddress & 0x80) &&
+ ((endpoint->bmAttributes & 3) == 0x02)) {
+ /* we found a bulk in endpoint */
+ mydbg("found bulk in");
+ bulk_in_endpoint[num_bulk_in] = endpoint;
+ ++num_bulk_in;
+ }
+
+ if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
+ ((endpoint->bmAttributes & 3) == 0x02)) {
+ /* we found a bulk out endpoint */
+ mydbg("found bulk out\n");
+ bulk_out_endpoint[num_bulk_out] = endpoint;
+ ++num_bulk_out;
+ }
+
+ if ((endpoint->bEndpointAddress & 0x80) &&
+ ((endpoint->bmAttributes & 3) == 0x03)) {
+ /* we found a interrupt in endpoint */
+ mydbg("found interrupt in\n");
+ interrupt_in_endpoint[num_interrupt_in] = endpoint;
+ ++num_interrupt_in;
+ }
+ }
+
+ /* found all that we need */
+ dev_info(&interface->dev, "Quatech converter detected\n");
+ num_ports = num_bulk_out;
+ if (num_ports == 0) {
+ err("Quatech device with no bulk out, not allowed.");
+ return -ENODEV;
+
+ }
+
+ serial = get_free_serial(num_ports, &minor);
+ if (serial == NULL) {
+ err("No more free serial devices");
+ return -ENODEV;
+ }
+
+ serial->dev = dev;
+ serial->interface = interface;
+ serial->minor = minor;
+ serial->num_ports = num_ports;
+ serial->num_bulk_in = num_bulk_in;
+ serial->num_bulk_out = num_bulk_out;
+ serial->num_interrupt_in = num_interrupt_in;
+ serial->vendor = dev->descriptor.idVendor;
+ serial->product = dev->descriptor.idProduct;
+
+ /* set up the endpoint information */
+ for (i = 0; i < num_bulk_in; ++i) {
+ endpoint = bulk_in_endpoint[i];
+ port = &serial->port[i];
+ port->read_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!port->read_urb) {
+ err("No free urbs available");
+ goto probe_error;
+ }
+ buffer_size = endpoint->wMaxPacketSize;
+ port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
+ port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
+ port->xfer_to_tty_buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!port->bulk_in_buffer) {
+ err("Couldn't allocate bulk_in_buffer");
+ goto probe_error;
+ }
+ usb_fill_bulk_urb(port->read_urb, dev,
+ usb_rcvbulkpipe(dev,
+ endpoint->bEndpointAddress),
+ port->bulk_in_buffer, buffer_size,
+ qt_read_bulk_callback, port);
+ }
+
+ for (i = 0; i < num_bulk_out; ++i) {
+ endpoint = bulk_out_endpoint[i];
+ port = &serial->port[i];
+ port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!port->write_urb) {
+ err("No free urbs available");
+ goto probe_error;
+ }
+ buffer_size = endpoint->wMaxPacketSize;
+ port->bulk_out_size = buffer_size;
+ port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
+ port->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!port->bulk_out_buffer) {
+ err("Couldn't allocate bulk_out_buffer");
+ goto probe_error;
+ }
+ usb_fill_bulk_urb(port->write_urb, dev,
+ usb_sndbulkpipe(dev,
+ endpoint->bEndpointAddress),
+ port->bulk_out_buffer, buffer_size,
+ qt_write_bulk_callback, port);
+
+ }
+
+ /* For us numb of bulkin or out = number of ports */
+ mydbg("%s - setting up %d port structures for this device\n",
+ __func__, num_bulk_in);
+ for (i = 0; i < num_bulk_in; ++i) {
+ port = &serial->port[i];
+ port->number = i + serial->minor;
+ port->serial = serial;
+
+ INIT_WORK(&port->work, port_softint);
+
+ init_MUTEX(&port->sem);
+
+ }
+ status = box_get_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_get_device failed");
+ goto probe_error;
+ }
+
+ mydbg(__FILE__ "DeviceData.portb = 0x%x", DeviceData.portb);
+
+ DeviceData.portb &= ~FULLPWRBIT;
+ mydbg(__FILE__ "Changing DeviceData.portb to 0x%x", DeviceData.portb);
+
+ status = box_set_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_set_device failed\n");
+ goto probe_error;
+ }
+
+ /* initialize the devfs nodes for this device and let the user know what ports we are bound to */
+ for (i = 0; i < serial->num_ports; ++i) {
+ dev_info(&interface->dev,
+ "Converter now attached to ttyUSB%d (or usb/tts/%d for devfs)",
+ serial->port[i].number, serial->port[i].number);
+ }
+
+ /* usb_serial_console_init (debug, minor); */
+
+ /***********TAG add start next board here ****/
+ status = box_get_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_get_device failed");
+ goto probe_error;
+ }
+ /*
+ * and before we power up lets initialiaze parnent device stuff here before
+ * we set thmem via any other method such as the property pages
+ */
+ switch (serial->product) {
+ case DEVICE_ID_QUATECH_RS232_SINGLE_PORT:
+ case DEVICE_ID_QUATECH_RS232_DUAL_PORT:
+ case DEVICE_ID_QUATECH_RS232_FOUR_PORT:
+ case DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A:
+ case DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B:
+ case DEVICE_ID_QUATECH_RS232_16_PORT_A:
+ case DEVICE_ID_QUATECH_RS232_16_PORT_B:
+ case DEVICE_ID_QUATECH_RS232_16_PORT_C:
+ case DEVICE_ID_QUATECH_RS232_16_PORT_D:
+ DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
+ DeviceData.porta |= CLKS_X4;
+ DeviceData.portb &= ~(LOOPMODE_BITS);
+ DeviceData.portb |= RS232_MODE;
+ break;
+
+ case DEVICE_ID_QUATECH_RS422_SINGLE_PORT:
+ case DEVICE_ID_QUATECH_RS422_DUAL_PORT:
+ case DEVICE_ID_QUATECH_RS422_FOUR_PORT:
+ case DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A:
+ case DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B:
+ case DEVICE_ID_QUATECH_RS422_16_PORT_A:
+ case DEVICE_ID_QUATECH_RS422_16_PORT_B:
+ case DEVICE_ID_QUATECH_RS422_16_PORT_C:
+ case DEVICE_ID_QUATECH_RS422_16_PORT_D:
+ DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
+ DeviceData.porta |= CLKS_X4;
+ DeviceData.portb &= ~(LOOPMODE_BITS);
+ DeviceData.portb |= ALL_LOOPBACK;
+ break;
+ default:
+ DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
+ DeviceData.porta |= CLKS_X4;
+ DeviceData.portb &= ~(LOOPMODE_BITS);
+ DeviceData.portb |= RS232_MODE;
+ break;
+
+ }
+ status = BoxSetPrebufferLevel(serial); /* sets to default vaue */
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetPrebufferLevel failed\n");
+ goto probe_error;
+ }
+
+ status = BoxSetATC(serial, ATC_DISABLED);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetATC failed\n");
+ goto probe_error;
+ }
+ /**********************************************************/
+ mydbg(__FILE__ "DeviceData.portb = 0x%x", DeviceData.portb);
+
+ DeviceData.portb |= NEXT_BOARD_POWER_BIT;
+ mydbg(__FILE__ "Changing DeviceData.portb to 0x%x", DeviceData.portb);
+
+ status = box_set_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_set_device failed\n");
+ goto probe_error;
+ }
+
+ mydbg("Exit Success %s\n", __func__);
+
+ usb_set_intfdata(interface, serial);
+ return 0;
+
+probe_error:
+
+ for (i = 0; i < num_bulk_in; ++i) {
+ port = &serial->port[i];
+ usb_free_urb(port->read_urb);
+ kfree(port->bulk_in_buffer);
+ }
+ for (i = 0; i < num_bulk_out; ++i) {
+ port = &serial->port[i];
+ usb_free_urb(port->write_urb);
+ kfree(port->bulk_out_buffer);
+ kfree(port->xfer_to_tty_buffer);
+ }
+ for (i = 0; i < num_interrupt_in; ++i) {
+ port = &serial->port[i];
+ usb_free_urb(port->interrupt_in_urb);
+ kfree(port->interrupt_in_buffer);
+ }
+
+ /* return the minor range that this device had */
+ return_serial(serial);
+ mydbg("Exit fail %s\n", __func__);
+
+ /* free up any memory that we allocated */
+ kfree(serial);
+ return -EIO;
+}
+
+/*
+ * returns the serial_table array pointers that are taken
+ * up in consecutive positions for each port to a common usb_serial structure
+ * back to NULL
+ */
+static void return_serial(struct usb_serial *serial)
+{
+ int i;
+
+ mydbg("%s\n", __func__);
+
+ if (serial == NULL)
+ return;
+
+ for (i = 0; i < serial->num_ports; ++i)
+ serial_table[serial->minor + i] = NULL;
+
+ return;
+}
+
+/*
+ * Finds the first locatio int the serial_table array where it can fit
+ * num_ports number of consecutive points to a common usb_serial
+ * structure,allocates a stucture points to it in all the structures, and
+ * returns the index to the first location in the array in the "minor"
+ * variable.
+ */
+static struct usb_serial *get_free_serial(int num_ports, int *minor)
+{
+ struct usb_serial *serial = NULL;
+ int i, j;
+ int good_spot;
+
+ mydbg("%s %d\n", __func__, num_ports);
+
+ *minor = 0;
+ for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
+ if (serial_table[i])
+ continue;
+
+ good_spot = 1;
+ /*
+ * find a spot in the array where you can fit consecutive
+ * positions to put the pointers to the usb_serail allocated
+ * structure for all the minor numbers (ie. ports)
+ */
+ for (j = 1; j <= num_ports - 1; ++j)
+ if (serial_table[i + j])
+ good_spot = 0;
+ if (good_spot == 0)
+ continue;
+
+ serial = kmalloc(sizeof(struct usb_serial), GFP_KERNEL);
+ if (!serial) {
+ err("%s - Out of memory", __func__);
+ return NULL;
+ }
+ memset(serial, 0, sizeof(struct usb_serial));
+ serial_table[i] = serial;
+ *minor = i;
+ mydbg("%s - minor base = %d\n", __func__, *minor);
+
+ /*
+ * copy in the pointer into the array starting a the *minor
+ * position minor is the index into the array.
+ */
+ for (i = *minor + 1;
+ (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i)
+ serial_table[i] = serial;
+ return serial;
+ }
+ return NULL;
+}
+
+static int flip_that(struct tty_struct *tty, __u16 index,
+ struct usb_serial *serial)
+{
+ tty_flip_buffer_push(tty);
+ tty_schedule_flip(tty);
+ return 0;
+}
+
+/* Handles processing and moving data to the tty layer */
+static void port_sofrint(void *private)
+{
+ struct usb_serial_port *port = private;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ struct tty_struct *tty = port->tty;
+ unsigned char *data = port->read_urb->transfer_buffer;
+ unsigned int index;
+ struct urb *urb = port->read_urb;
+ unsigned int RxCount = urb->actual_length;
+ int i, result;
+ int flag, flag_data;
+
+ /* index = MINOR(port->tty->device) - serial->minor; */
+ index = tty->index - serial->minor;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+ mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+ if (port_paranoia_check(port, __func__) != 0) {
+ mydbg("%s - port_paranoia_check, exiting\n", __func__);
+ port->ReadBulkStopped = 1;
+ return;
+ }
+
+ if (!serial) {
+ mydbg("%s - bad serial pointer, exiting\n", __func__);
+ return;
+ }
+ if (port->closePending == 1) {
+ /* Were closing , stop reading */
+ mydbg("%s - (port->closepending == 1\n", __func__);
+ port->ReadBulkStopped = 1;
+ return;
+ }
+
+ /*
+ * RxHolding is asserted by throttle, if we assert it, we're not
+ * receiving any more characters and let the box handle the flow
+ * control
+ */
+ if (port->RxHolding == 1) {
+ port->ReadBulkStopped = 1;
+ return;
+ }
+
+ if (urb->status) {
+ port->ReadBulkStopped = 1;
+
+ mydbg("%s - nonzero read bulk status received: %d\n",
+ __func__, urb->status);
+ return;
+ }
+
+ tty = port->tty;
+ mydbg("%s - port %d, tty =0x%p\n", __func__, port->number, tty);
+
+ if (tty && RxCount) {
+ flag_data = 0;
+ for (i = 0; i < RxCount; ++i) {
+ /* Look ahead code here */
+ if ((i <= (RxCount - 3)) && (THISCHAR == 0x1b)
+ && (NEXTCHAR == 0x1b)) {
+ flag = 0;
+ switch (THIRDCHAR) {
+ case 0x00:
+ /* Line status change 4th byte must follow */
+ if (i > (RxCount - 4)) {
+ mydbg("Illegal escape sequences in received data\n");
+ break;
+ }
+ ProcessLineStatus(port, FOURTHCHAR);
+ i += 3;
+ flag = 1;
+ break;
+
+ case 0x01:
+ /* Modem status status change 4th byte must follow */
+ mydbg("Modem status status. \n");
+ if (i > (RxCount - 4)) {
+ mydbg
+ ("Illegal escape sequences in received data\n");
+ break;
+ }
+ ProcessModemStatus(port, FOURTHCHAR);
+ i += 3;
+ flag = 1;
+ break;
+ case 0xff:
+ mydbg("No status sequence. \n");
+
+ ProcessRxChar(port, THISCHAR);
+ ProcessRxChar(port, NEXTCHAR);
+ i += 2;
+ break;
+ }
+ if (flag == 1)
+ continue;
+ }
+
+ if (tty && urb->actual_length) {
+ tty_buffer_request_room(tty, 1);
+ tty_insert_flip_string(tty, (data + i), 1);
+ }
+
+ }
+ tty_flip_buffer_push(tty);
+ }
+
+ /* Continue trying to always read */
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ qt_read_bulk_callback, port);
+ result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+ if (result)
+ mydbg("%s - failed resubmitting read urb, error %d",
+ __func__, result);
+ else {
+ if (tty && RxCount)
+ flip_that(tty, index, serial);
+ }
+
+ return;
+
+}
+
+static void qt_read_bulk_callback(struct urb *urb)
+{
+
+ struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+
+ if (urb->status) {
+ port->ReadBulkStopped = 1;
+ mydbg("%s - nonzero write bulk status received: %d\n",
+ __func__, urb->status);
+ return;
+ }
+
+ port_sofrint((void *)port);
+ schedule_work(&port->work);
+}
+
+static void ProcessRxChar(struct usb_serial_port *port, unsigned char Data)
+{
+ struct tty_struct *tty;
+ struct urb *urb = port->read_urb;
+ tty = port->tty;
+ /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
+
+ if (tty && urb->actual_length) {
+ tty_buffer_request_room(tty, 1);
+ tty_insert_flip_string(tty, &Data, 1);
+ /* tty_flip_buffer_push(tty); */
+ }
+
+ return;
+}
+
+static void ProcessLineStatus(struct usb_serial_port *port,
+ unsigned char line_status)
+{
+
+ port->shadowLSR =
+ line_status & (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE |
+ SERIAL_LSR_BI);
+ return;
+}
+
+static void ProcessModemStatus(struct usb_serial_port *port,
+ unsigned char modem_status)
+{
+
+ port->shadowMSR = modem_status;
+ wake_up_interruptible(&port->wait);
+ return;
+}
+
+static void serqt_usb_disconnect(struct usb_interface *interface)
+{
+ struct usb_serial *serial = usb_get_intfdata(interface);
+ /* struct device *dev = &interface->dev; */
+ struct usb_serial_port *port;
+ int i;
+
+ mydbg("%s\n", __func__);
+ if (serial) {
+
+ serial->dev = NULL;
+
+ for (i = 0; i < serial->num_ports; ++i)
+ serial->port[i].open_count = 0;
+
+ for (i = 0; i < serial->num_bulk_in; ++i) {
+ port = &serial->port[i];
+ usb_unlink_urb(port->read_urb);
+ usb_free_urb(port->read_urb);
+ kfree(port->bulk_in_buffer);
+ }
+ for (i = 0; i < serial->num_bulk_out; ++i) {
+ port = &serial->port[i];
+ usb_unlink_urb(port->write_urb);
+ usb_free_urb(port->write_urb);
+ kfree(port->bulk_out_buffer);
+ }
+ for (i = 0; i < serial->num_interrupt_in; ++i) {
+ port = &serial->port[i];
+ usb_unlink_urb(port->interrupt_in_urb);
+ usb_free_urb(port->interrupt_in_urb);
+ kfree(port->interrupt_in_buffer);
+ }
+
+ /* return the minor range that this device had */
+ return_serial(serial);
+
+ /* free up any memory that we allocated */
+ kfree(serial);
+
+ } else {
+ dev_info(&interface->dev, "device disconnected");
+ }
+
+}
+
+static struct usb_serial *get_serial_by_minor(unsigned int minor)
+{
+ return serial_table[minor];
+}
+
+/*****************************************************************************
+ * Driver tty interface functions
+ *****************************************************************************/
+static int serial_open(struct tty_struct *tty, struct file *filp)
+{
+ struct usb_serial *serial;
+ struct usb_serial_port *port;
+ unsigned int portNumber;
+ int retval = 0;
+
+ mydbg("%s\n", __func__);
+
+ /* initialize the pointer incase something fails */
+ tty->driver_data = NULL;
+
+ /* get the serial object associated with this tty pointer */
+ /* serial = get_serial_by_minor (MINOR(tty->device)); */
+
+ /* get the serial object associated with this tty pointer */
+ serial = get_serial_by_minor(tty->index);
+
+ if (serial_paranoia_check(serial, __func__))
+ return -ENODEV;
+
+ /* set up our port structure making the tty driver remember our port object, and us it */
+ portNumber = tty->index - serial->minor;
+ port = &serial->port[portNumber];
+ tty->driver_data = port;
+
+ down(&port->sem);
+ port->tty = tty;
+
+ ++port->open_count;
+ if (port->open_count == 1) {
+ port->closePending = 0;
+ mydbg("%s port->closepending = 0\n", __func__);
+
+ port->RxHolding = 0;
+ mydbg("%s port->RxHolding = 0\n", __func__);
+
+ retval = qt_open(tty, port, filp);
+ }
+
+ if (retval)
+ port->open_count = 0;
+ mydbg("%s returning port->closePending = %d\n", __func__,
+ port->closePending);
+
+ up(&port->sem);
+ return retval;
+}
+
+/*****************************************************************************
+ *device's specific driver functions
+ *****************************************************************************/
+static int qt_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
+{
+ struct usb_serial *serial = port->serial;
+ int result = 0;
+ unsigned int index;
+ struct qt_get_device_data DeviceData;
+ struct qt_open_channel_data ChannelData;
+ unsigned short default_divisor = 0x30; /* gives 9600 baud rate */
+ unsigned char default_LCR = SERIAL_8_DATA; /* 8, none , 1 */
+ int status = 0;
+
+ if (port_paranoia_check(port, __func__))
+ return -ENODEV;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ index = tty->index - serial->minor;
+
+ status = box_get_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_get_device failed\n");
+ return status;
+ }
+ serial->num_OpenCount++;
+ mydbg("%s serial->num_OpenCount = %d\n", __func__,
+ serial->num_OpenCount);
+ /* Open uart channel */
+
+ /* Port specific setups */
+ status = BoxOPenCloseChannel(serial, index, 1, &ChannelData);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxOPenCloseChannel failed\n");
+ return status;
+ }
+ mydbg(__FILE__ "BoxOPenCloseChannel completed.\n");
+
+ port->shadowLSR = ChannelData.line_status &
+ (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE | SERIAL_LSR_BI);
+
+ port->shadowMSR = ChannelData.modem_status &
+ (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_CD);
+
+ /* Set Baud rate to default and turn off (default)flow control here */
+ status = BoxSetUart(serial, index, default_divisor, default_LCR);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetUart failed\n");
+ return status;
+ }
+ mydbg(__FILE__ "BoxSetUart completed.\n");
+
+ /* Put this here to make it responsive to stty and defauls set by the tty layer */
+ qt_set_termios(tty, port, NULL);
+
+ /* Initialize the wait que head */
+ init_waitqueue_head(&(port->wait));
+
+ /* if we have a bulk endpoint, start reading from it */
+ if (serial->num_bulk_in) {
+ /* Start reading from the device */
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->
+ bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ qt_read_bulk_callback, port);
+
+ port->ReadBulkStopped = 0;
+
+ result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+
+ if (result) {
+ err("%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
+ port->ReadBulkStopped = 1;
+ }
+
+ }
+
+ return result;
+}
+
+static void serial_close(struct tty_struct *tty, struct file *filp)
+{
+ struct usb_serial_port *port =
+ tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+
+ if (!serial)
+ return;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ /* if disconnect beat us to the punch here, there's nothing to do */
+ if (tty->driver_data) {
+ if (!port->open_count) {
+ mydbg("%s - port not opened\n", __func__);
+ goto exit;
+ }
+
+ --port->open_count;
+ if (port->open_count <= 0) {
+ port->closePending = 1;
+ mydbg("%s - port->closePending = 1\n", __func__);
+
+ if (serial->dev) {
+ qt_close(tty, port, filp);
+ port->open_count = 0;
+ }
+ }
+
+ }
+
+exit:
+ up(&port->sem);
+
+ mydbg("%s - %d return\n", __func__, port->number);
+
+}
+
+static void qt_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
+{
+ unsigned long jift = jiffies + 10 * HZ;
+ u8 lsr, mcr;
+ struct usb_serial *serial = port->serial;
+ int status;
+ unsigned int index;
+
+ struct qt_open_channel_data ChannelData;
+ status = 0;
+ lsr = 0;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+ index = tty->index - serial->minor;
+
+ /* shutdown any bulk reads that might be going on */
+ if (serial->num_bulk_out)
+ usb_unlink_urb(port->write_urb);
+ if (serial->num_bulk_in)
+ usb_unlink_urb(port->read_urb);
+
+ /* wait up to 30 seconds for transmitter to empty */
+ do {
+ status = BoxGetRegister(serial, index, LINE_STATUS_REGISTER, &lsr);
+ if (status < 0) {
+ mydbg(__FILE__ "box_get_device failed\n");
+ break;
+ }
+
+ if ((lsr & SERIAL_LSR_TEMT)
+ && (port->ReadBulkStopped == 1))
+ break;
+ schedule();
+
+ }
+ while (jiffies <= jift);
+
+ if (jiffies > jift)
+ mydbg("%s - port %d timout of checking transmitter empty\n",
+ __func__, port->number);
+ else
+ mydbg("%s - port %d checking transmitter empty succeded\n",
+ __func__, port->number);
+
+ status =
+ BoxGetRegister(serial, index, MODEM_CONTROL_REGISTER,
+ &mcr);
+ mydbg(__FILE__ "BoxGetRegister MCR = 0x%x.\n", mcr);
+
+ if (status >= 0) {
+ mcr &= ~(SERIAL_MCR_DTR | SERIAL_MCR_RTS);
+ /* status = BoxSetRegister(serial, index, MODEM_CONTROL_REGISTER, mcr); */
+ }
+
+ /* Close uart channel */
+ status = BoxOPenCloseChannel(serial, index, 0, &ChannelData);
+ if (status < 0)
+ mydbg("%s - port %d BoxOPenCloseChannel failed.\n",
+ __func__, port->number);
+
+ serial->num_OpenCount--;
+
+}
+
+static int serial_write(struct tty_struct *tty, const unsigned char *buf,
+ int count)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct usb_serial *serial;
+ int retval = -EINVAL;
+ unsigned int index;
+
+ serial = get_usb_serial(port, __func__);
+ if (serial == NULL)
+ return -ENODEV;
+ /* This can happen if we get disconnected a */
+ if (port->open_count == 0)
+ return -ENODEV;
+ index = tty->index - serial->minor;
+
+ mydbg("%s - port %d, %d byte(s)\n", __func__, port->number, count);
+ mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+ if (!port->open_count) {
+ mydbg("%s - port not opened\n", __func__);
+ goto exit;
+ }
+
+ retval = qt_write(tty, port, buf, count);
+
+exit:
+ return retval;
+}
+
+static int qt_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
+{
+ int result;
+ unsigned int index;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+
+ if (serial == NULL)
+ return -ENODEV;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (count == 0) {
+ mydbg("%s - write request of 0 bytes\n", __func__);
+ return 0;
+ }
+
+ index = tty->index - serial->minor;
+ /* only do something if we have a bulk out endpoint */
+ if (serial->num_bulk_out) {
+ if (port->write_urb->status == -EINPROGRESS) {
+ mydbg("%s - already writing\n", __func__);
+ return 0;
+ }
+
+ count =
+ (count > port->bulk_out_size) ? port->bulk_out_size : count;
+ memcpy(port->write_urb->transfer_buffer, buf, count);
+
+ /* usb_serial_debug_data(__FILE__, __func__, count, port->write_urb->transfer_buffer); */
+
+ /* set up our urb */
+
+ usb_fill_bulk_urb(port->write_urb, serial->dev,
+ usb_sndbulkpipe(serial->dev,
+ port->
+ bulk_out_endpointAddress),
+ port->write_urb->transfer_buffer, count,
+ qt_write_bulk_callback, port);
+
+ /* send the data out the bulk port */
+ result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+ if (result)
+ mydbg("%s - failed submitting write urb, error %d\n",
+ __func__, result);
+ else
+ result = count;
+
+ return result;
+ }
+
+ /* no bulk out, so return 0 bytes written */
+ return 0;
+}
+
+static void qt_write_bulk_callback(struct urb *urb)
+{
+ struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!serial) {
+ mydbg("%s - bad serial pointer, exiting\n", __func__);
+ return;
+ }
+
+ if (urb->status) {
+ mydbg("%s - nonzero write bulk status received: %d\n",
+ __func__, urb->status);
+ return;
+ }
+ port_softint(&port->work);
+ schedule_work(&port->work);
+
+ return;
+}
+
+static void port_softint(struct work_struct *work)
+{
+ struct usb_serial_port *port =
+ container_of(work, struct usb_serial_port, work);
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ struct tty_struct *tty;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!serial)
+ return;
+
+ tty = port->tty;
+ if (!tty)
+ return;
+#if 0
+ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
+ && tty->ldisc.write_wakeup) {
+ mydbg("%s - write wakeup call.\n", __func__);
+ (tty->ldisc.write_wakeup) (tty);
+ }
+#endif
+
+ wake_up_interruptible(&tty->write_wait);
+}
+static int serial_write_room(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ int retval = -EINVAL;
+
+ if (!serial)
+ return -ENODEV;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ retval = qt_write_room(port);
+
+exit:
+ up(&port->sem);
+ return retval;
+}
+static int qt_write_room(struct usb_serial_port *port)
+{
+ struct usb_serial *serial = port->serial;
+ int room = 0;
+ if (port->closePending == 1) {
+ mydbg("%s - port->closePending == 1\n", __func__);
+ return -ENODEV;
+ }
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (serial->num_bulk_out) {
+ if (port->write_urb->status != -EINPROGRESS)
+ room = port->bulk_out_size;
+ }
+
+ mydbg("%s - returns %d\n", __func__, room);
+ return room;
+}
+static int serial_chars_in_buffer(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ int retval = -EINVAL;
+
+ if (!serial)
+ return -ENODEV;
+
+ down(&port->sem);
+
+ mydbg("%s = port %d\n", __func__, port->number);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ retval = qt_chars_in_buffer(port);
+
+exit:
+ up(&port->sem);
+ return retval;
+}
+
+static int qt_chars_in_buffer(struct usb_serial_port *port)
+{
+ struct usb_serial *serial = port->serial;
+ int chars = 0;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (serial->num_bulk_out) {
+ if (port->write_urb->status == -EINPROGRESS)
+ chars = port->write_urb->transfer_buffer_length;
+ }
+
+ mydbg("%s - returns %d\n", __func__, chars);
+ return chars;
+}
+
+static int serial_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear)
+{
+
+ struct usb_serial_port *port = tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ int retval = -ENODEV;
+ unsigned int index;
+ mydbg("In %s \n", __func__);
+
+ if (!serial)
+ return -ENODEV;
+
+ index = tty->index - serial->minor;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d \n", __func__, port->number);
+ mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ retval = qt_tiocmset(tty, port, file, set);
+
+exit:
+ up(&port->sem);
+ return retval;
+}
+
+static int qt_tiocmset(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *file, unsigned int value)
+{
+
+ u8 mcr;
+ int status;
+ unsigned int index;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+
+ if (serial == NULL)
+ return -ENODEV;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ /**************************************************************************************/
+ /** TIOCMGET
+ */
+ index = tty->index - serial->minor;
+ status =
+ BoxGetRegister(port->serial, index, MODEM_CONTROL_REGISTER,
+ &mcr);
+ if (status < 0)
+ return -ESPIPE;
+
+ /*
+ * Turn off the RTS and DTR and loopbcck and then only turn on what was
+ * asked for
+ */
+ mcr &= ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR | SERIAL_MCR_LOOP);
+ if (value & TIOCM_RTS)
+ mcr |= SERIAL_MCR_RTS;
+ if (value & TIOCM_DTR)
+ mcr |= SERIAL_MCR_DTR;
+ if (value & TIOCM_LOOP)
+ mcr |= SERIAL_MCR_LOOP;
+
+ status =
+ BoxSetRegister(port->serial, index, MODEM_CONTROL_REGISTER,
+ mcr);
+ if (status < 0)
+ return -ESPIPE;
+ else
+ return 0;
+}
+
+static int serial_tiocmget(struct tty_struct *tty, struct file *file)
+{
+
+ struct usb_serial_port *port = tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ int retval = -ENODEV;
+ unsigned int index;
+ mydbg("In %s \n", __func__);
+
+ if (!serial)
+ return -ENODEV;
+
+ index = tty->index - serial->minor;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+ mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ retval = qt_tiocmget(tty, port, file);
+
+exit:
+ up(&port->sem);
+ return retval;
+}
+
+static int qt_tiocmget(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *file)
+{
+
+ u8 mcr;
+ u8 msr;
+ unsigned int result = 0;
+ int status;
+ unsigned int index;
+
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ if (serial == NULL)
+ return -ENODEV;
+
+ mydbg("%s - port %d, tty =0x%p\n", __func__, port->number, tty);
+
+ /**************************************************************************************/
+ /** TIOCMGET
+ */
+ index = tty->index - serial->minor;
+ status =
+ BoxGetRegister(port->serial, index, MODEM_CONTROL_REGISTER,
+ &mcr);
+ if (status >= 0) {
+ status =
+ BoxGetRegister(port->serial, index,
+ MODEM_STATUS_REGISTER, &msr);
+
+ }
+
+ if (status >= 0) {
+ result = ((mcr & SERIAL_MCR_DTR) ? TIOCM_DTR : 0)
+ /* DTR IS SET */
+ | ((mcr & SERIAL_MCR_RTS) ? TIOCM_RTS : 0)
+ /* RTS IS SET */
+ | ((msr & SERIAL_MSR_CTS) ? TIOCM_CTS : 0)
+ /* CTS is set */
+ | ((msr & SERIAL_MSR_CD) ? TIOCM_CAR : 0)
+ /* Carrier detect is set */
+ | ((msr & SERIAL_MSR_RI) ? TIOCM_RI : 0)
+ /* Ring indicator set */
+ | ((msr & SERIAL_MSR_DSR) ? TIOCM_DSR : 0);
+ /* DSR is set */
+ return result;
+
+ } else
+ return -ESPIPE;
+}
+
+static int serial_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+
+ struct usb_serial_port *port = tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ int retval = -ENODEV;
+ unsigned int index;
+ mydbg("In %s \n", __func__);
+
+ if (!serial)
+ return -ENODEV;
+
+ index = tty->index - serial->minor;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d, cmd 0x%.4x\n", __func__, port->number, cmd);
+ mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ retval = qt_ioctl(tty, port, file, cmd, arg);
+
+exit:
+ up(&port->sem);
+ return retval;
+}
+static int qt_ioctl(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *file, unsigned int cmd, unsigned long arg)
+{
+ __u8 mcr;
+ __u8 msr;
+ unsigned short prev_msr;
+ unsigned int value, result = 0;
+ int status;
+ unsigned int index;
+
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ if (serial == NULL)
+ return -ENODEV;
+
+ mydbg("%s - port %d, tty =0x%p\n", __func__, port->number, tty);
+
+ /* TIOCMGET */
+ index = tty->index - serial->minor;
+
+ if (cmd == TIOCMIWAIT) {
+ DECLARE_WAITQUEUE(wait, current);
+ prev_msr = port->shadowMSR & SERIAL_MSR_MASK;
+ while (1) {
+ add_wait_queue(&port->wait, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ remove_wait_queue(&port->wait, &wait);
+ /* see if a signal woke us up */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ msr = port->shadowMSR & SERIAL_MSR_MASK;
+ if (msr == prev_msr)
+ return -EIO; /* no change error */
+
+ if ((arg & TIOCM_RNG
+ && ((prev_msr & SERIAL_MSR_RI) ==
+ (msr & SERIAL_MSR_RI)))
+ || (arg & TIOCM_DSR
+ && ((prev_msr & SERIAL_MSR_DSR) ==
+ (msr & SERIAL_MSR_DSR)))
+ || (arg & TIOCM_CD
+ && ((prev_msr & SERIAL_MSR_CD) ==
+ (msr & SERIAL_MSR_CD)))
+ || (arg & TIOCM_CTS
+ && ((prev_msr & SERIAL_MSR_CTS) ==
+ (msr & SERIAL_MSR_CTS)))) {
+ return 0;
+ }
+
+ }
+
+ }
+ mydbg("%s -No ioctl for that one. port = %d\n", __func__,
+ port->number);
+
+ return -ENOIOCTLCMD;
+}
+
+static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
+{
+ struct usb_serial_port *port =
+ tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+
+ if (!serial)
+ return;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ /* pass on to the driver specific version of this function if it is available */
+ qt_set_termios(tty, port, old);
+
+exit:
+ up(&port->sem);
+}
+
+static void qt_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port,
+ struct ktermios *old_termios)
+{
+ unsigned int cflag;
+ int baud, divisor, remainder;
+ unsigned char new_LCR = 0;
+ int status;
+ struct usb_serial *serial;
+ __u16 index;
+ __u16 tmp, tmp2;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ tmp = port->tty->index;
+ mydbg("%s - MINOR(port->tty->index) = %d\n", __func__, tmp);
+
+ serial = port->serial;
+ tmp2 = serial->minor;
+ mydbg("%s - serial->minor = %d\n", __func__, tmp2);
+
+ index = port->tty->index - serial->minor;
+
+ cflag = tty->termios->c_cflag;
+
+ mydbg("%s - 3\n", __func__);
+
+ switch (cflag) {
+ case CS5:
+ new_LCR |= SERIAL_5_DATA;
+ break;
+ case CS6:
+ new_LCR |= SERIAL_6_DATA;
+ break;
+ case CS7:
+ new_LCR |= SERIAL_7_DATA;
+ break;
+ default:
+ case CS8:
+ new_LCR |= SERIAL_8_DATA;
+ break;
+ }
+
+ /* Parity stuff */
+ if (cflag & PARENB) {
+ if (cflag & PARODD)
+ new_LCR |= SERIAL_ODD_PARITY;
+ else
+ new_LCR |= SERIAL_EVEN_PARITY;
+ }
+ if (cflag & CSTOPB)
+ new_LCR |= SERIAL_TWO_STOPB;
+ else
+ new_LCR |= SERIAL_TWO_STOPB;
+
+ mydbg("%s - 4\n", __func__);
+ /* Thats the LCR stuff, go ahead and set it */
+ baud = tty_get_baud_rate(tty);
+ if (!baud)
+ /* pick a default, any default... */
+ baud = 9600;
+
+ mydbg("%s - got baud = %d\n", __func__, baud);
+
+ divisor = MAX_BAUD_RATE / baud;
+ remainder = MAX_BAUD_RATE % baud;
+ /* Round to nearest divisor */
+ if (((remainder * 2) >= baud) && (baud != 110))
+ divisor++;
+
+ /*
+ * Set Baud rate to default and turn off (default)flow control here
+ */
+ status = BoxSetUart(serial, index, (unsigned short)divisor, new_LCR);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetUart failed\n");
+ return;
+ }
+
+ /* Now determine flow control */
+ if (cflag & CRTSCTS) {
+ mydbg("%s - Enabling HW flow control port %d\n", __func__,
+ port->number);
+
+ /* Enable RTS/CTS flow control */
+ status = BoxSetHW_FlowCtrl(serial, index, 1);
+
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetHW_FlowCtrl failed\n");
+ return;
+ }
+ } else {
+ /* Disable RTS/CTS flow control */
+ mydbg("%s - disabling HW flow control port %d\n", __func__,
+ port->number);
+
+ status = BoxSetHW_FlowCtrl(serial, index, 0);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetHW_FlowCtrl failed\n");
+ return;
+ }
+
+ }
+
+ /* if we are implementing XON/XOFF, set the start and stop character in
+ * the device */
+ if (I_IXOFF(tty) || I_IXON(tty)) {
+ unsigned char stop_char = STOP_CHAR(tty);
+ unsigned char start_char = START_CHAR(tty);
+ status =
+ BoxSetSW_FlowCtrl(serial, index, stop_char,
+ start_char);
+ if (status < 0)
+ mydbg(__FILE__ "BoxSetSW_FlowCtrl (enabled) failed\n");
+
+ } else {
+ /* disable SW flow control */
+ status = BoxDisable_SW_FlowCtrl(serial, index);
+ if (status < 0)
+ mydbg(__FILE__ "BoxSetSW_FlowCtrl (diabling) failed\n");
+
+ }
+ tty->termios->c_cflag &= ~CMSPAR;
+ /* FIXME: Error cases should be returning the actual bits changed only */
+}
+
+/****************************************************************************
+* BoxGetRegister
+* issuse a GET_REGISTER vendor-spcific request on the default control pipe
+* If successful, fills in the pValue with the register value asked for
+****************************************************************************/
+static int BoxGetRegister(struct usb_serial *serial, unsigned short Uart_Number,
+ unsigned short Register_Num, __u8 *pValue)
+{
+ int result;
+ __u16 current_length;
+
+ current_length = sizeof(struct qt_get_device_data);
+
+ result =
+ usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ QT_GET_SET_REGISTER, 0xC0, Register_Num,
+ Uart_Number, (void *)pValue, sizeof(*pValue), 300);
+
+ return result;
+}
+
+/****************************************************************************
+* BoxSetRegister
+* issuse a GET_REGISTER vendor-spcific request on the default control pipe
+* If successful, fills in the pValue with the register value asked for
+****************************************************************************/
+static int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number,
+ unsigned short Register_Num, unsigned short Value)
+{
+ int result;
+ unsigned short RegAndByte;
+
+ RegAndByte = Value;
+ RegAndByte = RegAndByte << 8;
+ RegAndByte = RegAndByte + Register_Num;
+
+/*
+ result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_GET_SET_REGISTER, 0xC0, Register_Num,
+ Uart_Number, NULL, 0, 300);
+*/
+
+ result =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_GET_SET_REGISTER, 0x40, RegAndByte, Uart_Number,
+ NULL, 0, 300);
+
+ return result;
+}
+
+/**
+ * box_get_device
+ * Issue a GET_DEVICE vendor-specific request on the default control pipe If
+ * successful, fills in the qt_get_device_data structure pointed to by
+ * device_data, otherwise return a negative error number of the problem.
+ */
+static int box_get_device(struct usb_serial *serial,
+ struct qt_get_device_data *device_data)
+{
+ int result;
+ __u16 current_length;
+ unsigned char *transfer_buffer;
+
+ current_length = sizeof(struct qt_get_device_data);
+ transfer_buffer = kmalloc(current_length, GFP_KERNEL);
+ if (!transfer_buffer)
+ return -ENOMEM;
+
+ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ QT_SET_GET_DEVICE, 0xc0, 0, 0,
+ transfer_buffer, current_length, 300);
+ if (result > 0)
+ memcpy(device_data, transfer_buffer, current_length);
+ kfree(transfer_buffer);
+
+ return result;
+}
+
+/**
+ * box_set_device
+ * Issue a SET_DEVICE vendor-specific request on the default control pipe If
+ * successful returns the number of bytes written, otherwise it returns a
+ * negative error number of the problem.
+ */
+static int box_set_device(struct usb_serial *serial,
+ struct qt_get_device_data *device_data)
+{
+ int result;
+ __u16 length;
+ __u16 PortSettings;
+
+ PortSettings = ((__u16) (device_data->portb));
+ PortSettings = (PortSettings << 8);
+ PortSettings += ((__u16) (device_data->porta));
+
+ length = sizeof(struct qt_get_device_data);
+ mydbg("%s - PortSettings = 0x%x\n", __func__, PortSettings);
+
+ result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_SET_GET_DEVICE, 0x40, PortSettings,
+ 0, NULL, 0, 300);
+ return result;
+}
+
+/****************************************************************************
+ * BoxOPenCloseChannel
+ * This funciotn notifies the device that the device driver wishes to open a particular UART channel. its
+ * purpose is to allow the device driver and the device to synchronize state information.
+ * OpenClose = 1 for open , 0 for close
+ ****************************************************************************/
+static int BoxOPenCloseChannel(struct usb_serial *serial, __u16 Uart_Number,
+ __u16 OpenClose,
+ struct qt_open_channel_data *pDeviceData)
+{
+ int result;
+ __u16 length;
+ __u8 Direcion;
+ unsigned int pipe;
+ length = sizeof(struct qt_open_channel_data);
+
+ /* if opening... */
+ if (OpenClose == 1) {
+ Direcion = USBD_TRANSFER_DIRECTION_IN;
+ pipe = usb_rcvctrlpipe(serial->dev, 0);
+ result =
+ usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
+ Direcion, OpenClose, Uart_Number,
+ pDeviceData, length, 300);
+
+ } else {
+ Direcion = USBD_TRANSFER_DIRECTION_OUT;
+ pipe = usb_sndctrlpipe(serial->dev, 0);
+ result =
+ usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
+ Direcion, OpenClose, Uart_Number, NULL, 0,
+ 300);
+
+ }
+
+ return result;
+}
+
+/****************************************************************************
+ * BoxSetPrebufferLevel
+ TELLS BOX WHEN TO ASSERT FLOW CONTROL
+ ****************************************************************************/
+static int BoxSetPrebufferLevel(struct usb_serial *serial)
+{
+ int result;
+ __u16 buffer_length;
+
+ buffer_length = PREFUFF_LEVEL_CONSERVATIVE;
+ result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_GET_SET_PREBUF_TRIG_LVL, 0x40,
+ buffer_length, 0, NULL, 0, 300);
+ return result;
+}
+
+/****************************************************************************
+ * BoxSetATC
+ TELLS BOX WHEN TO ASSERT automatic transmitter control
+ ****************************************************************************/
+static int BoxSetATC(struct usb_serial *serial, __u16 n_Mode)
+{
+ int result;
+ __u16 buffer_length;
+
+ buffer_length = PREFUFF_LEVEL_CONSERVATIVE;
+
+ result =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_SET_ATF, 0x40, n_Mode, 0, NULL, 0, 300);
+
+ return result;
+}
+
+/****************************************************************************
+* BoxSetUart
+* issuse a SET_UART vendor-spcific request on the default control pipe
+* If successful sets baud rate divisor and LCR value
+****************************************************************************/
+static int BoxSetUart(struct usb_serial *serial, unsigned short Uart_Number,
+ unsigned short default_divisor, unsigned char default_LCR)
+{
+ int result;
+ unsigned short UartNumandLCR;
+
+ UartNumandLCR = (default_LCR << 8) + Uart_Number;
+
+ result =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_GET_SET_UART, 0x40, default_divisor,
+ UartNumandLCR, NULL, 0, 300);
+
+ return result;
+}
+
+static int BoxSetHW_FlowCtrl(struct usb_serial *serial, unsigned int index,
+ int bSet)
+{
+ __u8 mcr = 0;
+ __u8 msr = 0, MOUT_Value = 0;
+ struct usb_serial_port *port;
+ unsigned int status;
+
+ port = serial->port;
+
+ if (bSet == 1) {
+ /* flow control, box will clear RTS line to prevent remote */
+ mcr = SERIAL_MCR_RTS;
+ } /* device from xmitting more chars */
+ else {
+ /* no flow control to remote device */
+ mcr = 0;
+
+ }
+ MOUT_Value = mcr << 8;
+
+ if (bSet == 1) {
+ /* flow control, box will inhibit xmit data if CTS line is
+ * asserted */
+ msr = SERIAL_MSR_CTS;
+ } else {
+ /* Box will not inhimbe xmit data due to CTS line */
+ msr = 0;
+ }
+ MOUT_Value |= msr;
+
+ status =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_HW_FLOW_CONTROL_MASK, 0x40, MOUT_Value,
+ index, NULL, 0, 300);
+ return status;
+
+}
+
+static int BoxSetSW_FlowCtrl(struct usb_serial *serial, __u16 index,
+ unsigned char stop_char, unsigned char start_char)
+{
+ __u16 nSWflowout;
+ int result;
+
+ nSWflowout = start_char << 8;
+ nSWflowout = (unsigned short)stop_char;
+
+ result =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_SW_FLOW_CONTROL_MASK, 0x40, nSWflowout,
+ index, NULL, 0, 300);
+ return result;
+
+}
+static int BoxDisable_SW_FlowCtrl(struct usb_serial *serial, __u16 index)
+{
+ int result;
+
+ result =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_SW_FLOW_CONTROL_DISABLE, 0x40, 0, index,
+ NULL, 0, 300);
+ return result;
+
+}
+
+static void serial_throttle(struct tty_struct *tty)
+{
+ struct usb_serial_port *port =
+ tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!serial)
+ return;
+
+ down(&port->sem);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+ /* shut down any bulk reads that may be going on */
+/* usb_unlink_urb (port->read_urb); */
+ /* pass on to the driver specific version of this function */
+ port->RxHolding = 1;
+ mydbg("%s - port->RxHolding = 1\n", __func__);
+
+exit:
+ up(&port->sem);
+ return;
+}
+
+static void serial_unthrottle(struct tty_struct *tty)
+{
+ struct usb_serial_port *port =
+ tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ unsigned int result;
+
+ if (!serial)
+ return;
+ down(&port->sem);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ if (port->RxHolding == 1) {
+ mydbg("%s -port->RxHolding == 1\n", __func__);
+
+ port->RxHolding = 0;
+ mydbg("%s - port->RxHolding = 0\n", __func__);
+
+ /* if we have a bulk endpoint, start it up */
+ if ((serial->num_bulk_in) && (port->ReadBulkStopped == 1)) {
+ /* Start reading from the device */
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->
+ bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->
+ transfer_buffer_length,
+ qt_read_bulk_callback, port);
+ result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+ if (result)
+ err("%s - failed restarting read urb, error %d",
+ __func__, result);
+ }
+ }
+exit:
+ up(&port->sem);
+ return;
+
+}
+
+static int serial_break(struct tty_struct *tty, int break_state)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ u16 index, onoff;
+ unsigned int result;
+
+ index = tty->index - serial->minor;
+ if (!serial)
+ return -ENODEV;
+
+ if (break_state == -1)
+ onoff = 1;
+ else
+ onoff = 0;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ result =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_BREAK_CONTROL, 0x40, onoff, index,
+ NULL, 0, 300);
+
+exit:
+ up(&port->sem);
+ return 0;
+}
+
+static int ioctl_serial_usb(struct inode *innod, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+
+ unsigned err;
+ unsigned ucOPR_NewValue, uc_Value;
+ int *p_Num_of_adapters, counts, index, *p_QMCR_Value;
+ struct identity *p_Identity_of;
+ struct identity Identity_of;
+ struct usb_serial *lastserial, *serial;
+
+ mydbg(KERN_DEBUG "ioctl_serial_usb cmd =\n");
+ if (_IOC_TYPE(cmd) != SERIALQT_PCI_IOC_MAGIC)
+ return -ENOTTY;
+ if (_IOC_NR(cmd) > SERIALQT_IOC_MAXNR)
+ return -ENOTTY;
+ mydbg(KERN_DEBUG "ioctl_serial_usb cmd = 0x%x\n", cmd);
+ err = 0;
+ switch (cmd) {
+
+ case SERIALQT_WRITE_QMCR:
+ err = -ENOTTY;
+ index = arg >> 16;
+ counts = 0;
+
+ ucOPR_NewValue = arg;
+
+ err = EmulateWriteQMCR_Reg(index, ucOPR_NewValue);
+ break;
+
+ case SERIALQT_READ_QMCR:
+ err = -ENOTTY;
+ p_QMCR_Value = (int *)arg;
+ index = arg >> 16;
+ counts = 0;
+
+ err = EmulateReadQMCR_Reg(index, &uc_Value);
+ if (err == 0)
+ err = put_user(uc_Value, p_QMCR_Value);
+ break;
+
+ case SERIALQT_GET_NUMOF_UNITS:
+ p_Num_of_adapters = (int *)arg;
+ counts = 0; /* Initialize counts to zero */
+ /* struct usb_serial *lastserial = serial_table[0], *serial; */
+ lastserial = serial_table[0];
+
+ mydbg(KERN_DEBUG "SERIALQT_GET_NUMOF_UNITS \n");
+ /* if first pointer is nonull, we at least have one box */
+ if (lastserial)
+ counts = 1; /* we at least have one box */
+
+ for (index = 1; index < SERIAL_TTY_MINORS; index++) {
+ serial = serial_table[index];
+ if (serial) {
+ if (serial != lastserial) {
+ /* we had a change in the array, hence
+ * another box is there */
+ lastserial = serial;
+ counts++;
+ }
+ } else
+ break;
+ }
+
+ mydbg(KERN_DEBUG "ioctl_serial_usb writting counts = %d",
+ counts);
+
+ err = put_user(counts, p_Num_of_adapters);
+
+ break;
+ case SERIALQT_GET_THIS_UNIT:
+ counts = 0;
+ p_Identity_of = (struct identity *)arg;
+ /* copy user structure to local variable */
+ get_user(Identity_of.index, &p_Identity_of->index);
+ mydbg(KERN_DEBUG "SERIALQT_GET_THIS_UNIT Identity_of.index\n");
+ mydbg(KERN_DEBUG
+ "SERIALQT_GET_THIS_UNIT Identity_of.index= 0x%x\n",
+ Identity_of.index);
+
+ err = -ENOTTY;
+ serial = find_the_box(Identity_of.index);
+ if (serial) {
+ err =
+ put_user(serial->product,
+ &p_Identity_of->n_identity);
+
+ }
+ break;
+
+ case SERIALQT_IS422_EXTENDED:
+ err = -ENOTTY;
+ mydbg(KERN_DEBUG "SERIALQT_IS422_EXTENDED \n");
+ index = arg >> 16;
+
+ counts = 0;
+
+ mydbg(KERN_DEBUG
+ "SERIALQT_IS422_EXTENDED, looking Identity_of.indext = 0x%x\n",
+ index);
+ serial = find_the_box(index);
+ if (serial) {
+ mydbg("%s index = 0x%x, serial = 0x%p\n", __func__,
+ index, serial);
+ for (counts = 0; serqt_422_table[counts] != 0; counts++) {
+
+ mydbg
+ ("%s serial->product = = 0x%x, serqt_422_table[counts] = 0x%x\n",
+ __func__, serial->product,
+ serqt_422_table[counts]);
+ if (serial->product == serqt_422_table[counts]) {
+ err = 0;
+
+ mydbg
+ ("%s found match for 422extended\n",
+ __func__);
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ err = -ENOTTY;
+ }
+
+ mydbg("%s returning err = 0x%x\n", __func__, err);
+ return err;
+}
+
+static struct usb_serial *find_the_box(unsigned int index)
+{
+ struct usb_serial *lastserial, *foundserial, *serial;
+ int counts = 0, index2;
+ lastserial = serial_table[0];
+ foundserial = NULL;
+ for (index2 = 0; index2 < SERIAL_TTY_MINORS; index2++) {
+ serial = serial_table[index2];
+
+ mydbg("%s index = 0x%x, index2 = 0x%x, serial = 0x%p\n",
+ __func__, index, index2, serial);
+
+ if (serial) {
+ /* first see if this is the unit we'er looking for */
+ mydbg
+ ("%s inside if(serial) counts = 0x%x , index = 0x%x\n",
+ __func__, counts, index);
+ if (counts == index) {
+ /* we found the one we're looking for, copythe
+ * product Id to user */
+ mydbg("%s we found the one we're looking for serial = 0x%p\n",
+ __func__, serial);
+ foundserial = serial;
+ break;
+ }
+
+ if (serial != lastserial) {
+ /* when we have a change in the pointer */
+ lastserial = serial;
+ counts++;
+ }
+ } else
+ break; /* no matches */
+ }
+
+ mydbg("%s returning foundserial = 0x%p\n", __func__, foundserial);
+ return foundserial;
+}
+
+static int EmulateWriteQMCR_Reg(int index, unsigned uc_value)
+{
+
+ __u16 ATC_Mode = 0;
+ struct usb_serial *serial;
+ int status;
+ struct qt_get_device_data DeviceData;
+ unsigned uc_temp = 0;
+ mydbg("Inside %s, uc_value = 0x%x\n", __func__, uc_value);
+
+ DeviceData.porta = 0;
+ DeviceData.portb = 0;
+ serial = find_the_box(index);
+ /* Determine Duplex mode */
+ if (!(serial))
+ return -ENOTTY;
+ status = box_get_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_set_device failed\n");
+ return status;
+ }
+
+ uc_temp = uc_value & QMCR_HALF_DUPLEX_MASK;
+ switch (uc_temp) {
+ case QMCR_FULL_DUPLEX:
+ DeviceData.porta &= ~DUPMODE_BITS;
+ DeviceData.porta |= FULL_DUPLEX;
+ ATC_Mode = ATC_DISABLED;
+ break;
+ case QMCR_HALF_DUPLEX_RTS:
+ DeviceData.porta &= ~DUPMODE_BITS;
+ DeviceData.porta |= HALF_DUPLEX_RTS;
+ ATC_Mode = ATC_RTS_ENABLED;
+ break;
+ case QMCR_HALF_DUPLEX_DTR:
+ DeviceData.porta &= ~DUPMODE_BITS;
+ DeviceData.porta |= HALF_DUPLEX_DTR;
+ ATC_Mode = ATC_DTR_ENABLED;
+ break;
+ default:
+ break;
+ }
+
+ uc_temp = uc_value & QMCR_CONNECTOR_MASK;
+ switch (uc_temp) {
+ case QMCR_MODEM_CONTROL:
+ DeviceData.portb &= ~LOOPMODE_BITS; /* reset connection bits */
+ DeviceData.portb |= MODEM_CTRL;
+ break;
+ case QMCR_ALL_LOOPBACK:
+ DeviceData.portb &= ~LOOPMODE_BITS; /* reset connection bits */
+ DeviceData.portb |= ALL_LOOPBACK;
+ break;
+ }
+
+ mydbg(__FILE__ "Calling box_set_device with failed\n");
+ status = box_set_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_set_device failed\n");
+ return status;
+ }
+
+ /* This bit (otherwise unused) i'll used to detect whether ATC is
+ * selected */
+ if (uc_value & QMCR_RX_EN_MASK) {
+
+ mydbg(__FILE__
+ "calling BoxsetATC with DeviceData.porta = 0x%x and DeviceData.portb = 0x%x\n",
+ DeviceData.porta, DeviceData.portb);
+ status = BoxSetATC(serial, ATC_Mode);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetATC failed\n");
+ return status;
+ }
+ } else {
+
+ mydbg(__FILE__
+ "calling BoxsetATC with DeviceData.porta = 0x%x and DeviceData.portb = 0x%x\n",
+ DeviceData.porta, DeviceData.portb);
+ status = BoxSetATC(serial, ATC_DISABLED);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetATC failed\n");
+ return status;
+ }
+ }
+
+ return 0;
+
+}
+
+static int EmulateReadQMCR_Reg(int index, unsigned *uc_value)
+{
+ struct usb_serial *serial;
+ int status;
+ struct qt_get_device_data DeviceData;
+ __u8 uc_temp;
+
+ *uc_value = 0;
+
+ serial = find_the_box(index);
+ if (!(serial))
+ return -ENOTTY;
+
+ status = box_get_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_get_device failed\n");
+ return status;
+ }
+ uc_temp = DeviceData.porta & DUPMODE_BITS;
+ switch (uc_temp) {
+ case FULL_DUPLEX:
+ *uc_value |= QMCR_FULL_DUPLEX;
+ break;
+ case HALF_DUPLEX_RTS:
+ *uc_value |= QMCR_HALF_DUPLEX_RTS;
+ break;
+ case HALF_DUPLEX_DTR:
+ *uc_value |= QMCR_HALF_DUPLEX_DTR;
+ break;
+ default:
+ break;
+ }
+
+ /* I use this for ATC control se */
+ uc_temp = DeviceData.portb & LOOPMODE_BITS;
+
+ switch (uc_temp) {
+ case ALL_LOOPBACK:
+ *uc_value |= QMCR_ALL_LOOPBACK;
+ break;
+ case MODEM_CTRL:
+ *uc_value |= QMCR_MODEM_CONTROL;
+ break;
+ default:
+ break;
+
+ }
+ return 0;
+
+}
+
+static int __init serqt_usb_init(void)
+{
+ int i, result;
+ int status = 0;
+
+ mydbg("%s\n", __func__);
+ tty_set_operations(&serial_tty_driver, &serial_ops);
+ result = tty_register_driver(&serial_tty_driver);
+ if (result) {
+ mydbg("tty_register_driver failed error = 0x%x", result);
+ return result;
+ }
+
+ /* Initalize our global data */
+ for (i = 0; i < SERIAL_TTY_MINORS; ++i)
+ serial_table[i] = NULL;
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&serqt_usb_driver);
+ if (result < 0) {
+ err("usb_register failed for the " __FILE__
+ " driver. Error number %d", result);
+ return result;
+ }
+ status = 0; /* Dynamic assignment of major number */
+ major_number =
+ register_chrdev(status, "SerialQT_USB", &serialqt_usb_fops);
+ if (major_number < 0) {
+ mydbg(KERN_DEBUG "No devices found \n\n");
+ return -EBUSY;
+ } else
+ mydbg(KERN_DEBUG "SerQT_USB major number assignment = %d \n\n",
+ major_number);
+
+ printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION);
+ return 0;
+}
+
+static void __exit serqt_usb_exit(void)
+{
+ /* deregister this driver with the USB subsystem */
+ usb_deregister(&serqt_usb_driver);
+ tty_unregister_driver(&serial_tty_driver);
+ unregister_chrdev(major_number, "SerialQT_USB");
+}
+
+module_init(serqt_usb_init);
+module_exit(serqt_usb_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/slicoss/gbdownload.h b/drivers/staging/slicoss/gbdownload.h
deleted file mode 100644
index 794432bd1d7..00000000000
--- a/drivers/staging/slicoss/gbdownload.h
+++ /dev/null
@@ -1,8215 +0,0 @@
-#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
deleted file mode 100644
index 4fa5a4c23e5..00000000000
--- a/drivers/staging/slicoss/gbrcvucode.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 519e00797d4..00000000000
--- a/drivers/staging/slicoss/oasisdbgdownload.h
+++ /dev/null
@@ -1,6850 +0,0 @@
-#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
deleted file mode 100644
index 6438c23d754..00000000000
--- a/drivers/staging/slicoss/oasisdownload.h
+++ /dev/null
@@ -1,6848 +0,0 @@
-#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
deleted file mode 100644
index 5b3531f04cb..00000000000
--- a/drivers/staging/slicoss/oasisrcvucode.h
+++ /dev/null
@@ -1,205 +0,0 @@
-#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
index a8ea59d7ea1..ccf7625b8bb 100644
--- a/drivers/staging/slicoss/slic.h
+++ b/drivers/staging/slicoss/slic.h
@@ -46,30 +46,10 @@
#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,
-};
-
#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,
-};
-
#define GB_RCVUCODE_VERS_STRING "1.2"
#define GB_RCVUCODE_VERS_DATE "2006/03/27 15:12:15"
static u32 OasisRcvUCodeLen = 512;
@@ -201,17 +181,6 @@ struct slic_cmdqueue {
#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 {
@@ -367,30 +336,6 @@ struct sliccard {
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];
@@ -516,8 +461,6 @@ struct adapter {
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;
@@ -570,25 +513,6 @@ struct adapter {
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) \
{ \
@@ -605,11 +529,11 @@ struct slic_crash_info {
#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result) \
{ \
- _Result = TRUE; \
+ _Result = true; \
if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB)) \
- _Result = FALSE; \
+ _Result = false; \
if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4]))) \
- _Result = FALSE; \
+ _Result = false; \
}
#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
@@ -622,8 +546,8 @@ struct slic_crash_info {
#define SLIC_GET_ADDR_HIGH(_addr) (u32)0
#endif
-#define FLUSH TRUE
-#define DONT_FLUSH FALSE
+#define FLUSH true
+#define DONT_FLUSH false
#define SIOCSLICDUMPCARD (SIOCDEVPRIVATE+9)
#define SIOCSLICSETINTAGG (SIOCDEVPRIVATE+10)
diff --git a/drivers/staging/slicoss/slic_os.h b/drivers/staging/slicoss/slic_os.h
deleted file mode 100644
index 46c678440d2..00000000000
--- a/drivers/staging/slicoss/slic_os.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/**************************************************************************
- *
- * 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
deleted file mode 100644
index ae05e043d07..00000000000
--- a/drivers/staging/slicoss/slicbuild.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/**************************************************************************
- *
- * 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
deleted file mode 100644
index c54e44fb1f6..00000000000
--- a/drivers/staging/slicoss/slicdbg.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/**************************************************************************
- *
- * 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
deleted file mode 100644
index 92a9b44bcad..00000000000
--- a/drivers/staging/slicoss/slicdump.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- *
- * 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
index d03e90b0675..6275d452967 100644
--- a/drivers/staging/slicoss/slichw.h
+++ b/drivers/staging/slicoss/slichw.h
@@ -41,300 +41,286 @@
#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
+#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
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];
+ u8 pad1[6];
+ u16 pad2;
+ u32 pad3;
+ u32 pad4;
+ u32 buffer;
+ u32 length;
+ u32 status;
+ u32 pad5;
+ u16 pad6;
+ u8 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;
+struct slic_hddr_wds {
+ union {
+ struct {
+ u32 frame_status;
+ u32 frame_status_b;
+ u32 time_stamp;
+ u32 checksum;
+ } hdrs_14port;
+ struct {
+ u32 frame_status;
+ u16 ByteCnt;
+ u16 TpChksum;
+ u16 CtxHash;
+ u16 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
+#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;
+ 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;
+ u32 hosthandle;
+ u32 RSVD;
+ u8 command;
+ u8 flags;
+ union {
+ u16 rsv1;
+ u16 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];
-
+ u32 hosthandle;
+ u32 pad0;
+ u32 pad1;
+ u32 status;
+ u32 pad2[4];
};
struct slic_regs {
- u32 slic_reset; /* Reset Register */
+ u32 slic_reset; /* Reset Register */
u32 pad0;
- u32 slic_icr; /* Interrupt Control Register */
+ u32 slic_icr; /* Interrupt Control Register */
u32 pad2;
#define SLIC_ICR 0x0008
- u32 slic_isp; /* Interrupt status pointer */
+ u32 slic_isp; /* Interrupt status pointer */
u32 pad1;
#define SLIC_ISP 0x0010
- u32 slic_isr; /* Interrupt status */
+ u32 slic_isr; /* Interrupt status */
u32 pad3;
#define SLIC_ISR 0x0018
- u32 slic_hbar; /* Header buffer address reg */
- u32 pad4;
+ 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;
+ 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.*/
+ 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
@@ -343,13 +329,13 @@ struct slic_regs {
#define SLIC_CBAR_LEN_MSK 0x0000001F
#define SLIC_CBAR_ALIGN 0x00000020
- u32 slic_wcs; /* write control store*/
+ 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;
+ 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.*/
@@ -357,215 +343,214 @@ struct slic_regs {
#define SLIC_RBAR_CNT_MSK 0x000000FF
#define SLIC_RBAR_SIZE 32
- u32 slic_stats; /* read statistics (UPR) */
- u32 pad8;
+ u32 slic_stats; /* read statistics (UPR) */
+ u32 pad8;
#define SLIC_RSTAT 0x0040
- u32 slic_rlsr; /* read link status */
- u32 pad9;
+ u32 slic_rlsr; /* read link status */
+ u32 pad9;
#define SLIC_LSTAT 0x0048
- u32 slic_wmcfg; /* Write Mac Config */
- u32 pad10;
+ u32 slic_wmcfg; /* Write Mac Config */
+ u32 pad10;
#define SLIC_WMCFG 0x0050
- u32 slic_wphy; /* Write phy register */
- u32 pad11;
+ u32 slic_wphy; /* Write phy register */
+ u32 pad11;
#define SLIC_WPHY 0x0058
- u32 slic_rcbar; /*Rcv Cmd buf addr reg*/
- u32 pad12;
+ u32 slic_rcbar; /* Rcv Cmd buf addr reg */
+ u32 pad12;
#define SLIC_RCBAR 0x0060
- u32 slic_rconfig; /* Read SLIC Config*/
- u32 pad13;
+ u32 slic_rconfig; /* Read SLIC Config*/
+ u32 pad13;
#define SLIC_RCONFIG 0x0068
- u32 slic_intagg; /* Interrupt aggregation time*/
- u32 pad14;
+ u32 slic_intagg; /* Interrupt aggregation time */
+ u32 pad14;
#define SLIC_INTAGG 0x0070
- u32 slic_wxcfg; /* Write XMIT config reg*/
- u32 pad16;
+ u32 slic_wxcfg; /* Write XMIT config reg*/
+ u32 pad16;
#define SLIC_WXCFG 0x0078
- u32 slic_wrcfg; /* Write RCV config reg*/
- u32 pad17;
+ u32 slic_wrcfg; /* Write RCV config reg*/
+ u32 pad17;
#define SLIC_WRCFG 0x0080
- u32 slic_wraddral; /* Write rcv addr a low*/
- u32 pad18;
+ u32 slic_wraddral; /* Write rcv addr a low*/
+ u32 pad18;
#define SLIC_WRADDRAL 0x0088
- u32 slic_wraddrah; /* Write rcv addr a high*/
- u32 pad19;
+ u32 slic_wraddrah; /* Write rcv addr a high*/
+ u32 pad19;
#define SLIC_WRADDRAH 0x0090
- u32 slic_wraddrbl; /* Write rcv addr b low*/
- u32 pad20;
+ u32 slic_wraddrbl; /* Write rcv addr b low*/
+ u32 pad20;
#define SLIC_WRADDRBL 0x0098
- u32 slic_wraddrbh; /* Write rcv addr b high*/
+ u32 slic_wraddrbh; /* Write rcv addr b high*/
u32 pad21;
#define SLIC_WRADDRBH 0x00a0
- u32 slic_mcastlow; /* Low bits of mcast mask*/
+ u32 slic_mcastlow; /* Low bits of mcast mask*/
u32 pad22;
#define SLIC_MCASTLOW 0x00a8
- u32 slic_mcasthigh; /* High bits of mcast mask*/
+ u32 slic_mcasthigh; /* High bits of mcast mask*/
u32 pad23;
#define SLIC_MCASTHIGH 0x00b0
- u32 slic_ping; /* Ping the card*/
- u32 pad24;
+ u32 slic_ping; /* Ping the card*/
+ u32 pad24;
#define SLIC_PING 0x00b8
- u32 slic_dump_cmd; /* Dump command */
- u32 pad25;
+ u32 slic_dump_cmd; /* Dump command */
+ u32 pad25;
#define SLIC_DUMP_CMD 0x00c0
- u32 slic_dump_data; /* Dump data pointer */
- u32 pad26;
+ 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;
+ u32 pad27;
#define SLIC_PCISTATUS 0x00d0
- u32 slic_wrhostid; /* Write hostid field */
+ 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;
+ u32 pad29;
#define SLIC_LOW_POWER 0x00e0
u32 slic_quiesce; /* force slic into quiescent state
- before soft reset */
- u32 pad30;
+ before soft reset */
+ u32 pad30;
#define SLIC_QUIESCE 0x00e8
- u32 slic_reset_iface; /* reset interface queues */
- u32 pad31;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ u32 slic_wrvlanid; /* Write VlanId field */
+ u32 pad40;
#define SLIC_WRVLANID 0x0138
- u32 slic_read_xf_info; /* Read Transformer info */
- u32 pad41;
+ 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;
+ u32 slic_write_xf_info; /* Write Transformer info */
+ u32 pad42;
#define SLIC_WRITE_XF_INFO 0x0148
- u32 RSVD1; /* TOE Only */
- u32 pad43;
+ u32 RSVD1; /* TOE Only */
+ u32 pad43;
- u32 RSVD2; /* TOE Only */
- u32 pad44;
+ u32 RSVD2; /* TOE Only */
+ u32 pad44;
- u32 RSVD3; /* TOE Only */
- u32 pad45;
+ u32 RSVD3; /* TOE Only */
+ u32 pad45;
- u32 RSVD4; /* TOE Only */
- u32 pad46;
+ u32 RSVD4; /* TOE Only */
+ u32 pad46;
u32 slic_ticks_per_sec; /* Write card ticks per second */
- u32 pad47;
+ 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,
+ 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];
+ u32 patternlength;
+ u8 pattern[SLIC_PM_PATTERNSIZE];
+ u8 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];
+ 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;
+ 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
+ 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;
+ 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 {
@@ -612,136 +597,135 @@ struct rcv_statsgb {
};
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;
+ 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
+#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];
+ u8 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
+#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];
+ u8 assembly[6];
+ u8 revision[2];
+ u8 serial[14];
+ u8 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];
+ u8 commodity;
+ u8 assembly[4];
+ u8 revision[2];
+ u8 supplier[2];
+ u8 date[2];
+ u8 sequence[3];
+ u8 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];
+ u8 part[8];
+ u8 supplier[5];
+ u8 date[3];
+ u8 sequence[4];
+ u8 pad[7];
};
struct vendor3_fru {
- unsigned char assembly[6];
- unsigned char revision[2];
- unsigned char serial[14];
- unsigned char pad[3];
+ u8 assembly[6];
+ u8 revision[2];
+ u8 serial[14];
+ u8 pad[3];
};
struct vendor4_fru {
- unsigned char number[8];
- unsigned char part[8];
- unsigned char version[8];
- unsigned char pad[3];
+ u8 number[8];
+ u8 part[8];
+ u8 version[8];
+ u8 pad[3];
};
union oemfru {
- struct vendor1_fru vendor1_fru;
- struct vendor2_fru vendor2_fru;
- struct vendor3_fru vendor3_fru;
- struct vendor4_fru vendor4_fru;
+ 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
-*/
+ * 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
+ u16 Id; /* 00 EEPROM/FLASH Magic code 'A5A5'*/
+ u16 EecodeSize; /* 01 Size of EEPROM Codes (bytes * 4)*/
+ u16 FlashSize; /* 02 Flash size */
+ u16 EepromSize; /* 03 EEPROM Size */
+ u16 VendorId; /* 04 Vendor ID */
+ u16 DeviceId; /* 05 Device ID */
+ u8 RevisionId; /* 06 Revision ID */
+ u8 ClassCode[3]; /* 07 Class Code */
+ u8 DbgIntPin; /* 08 Debug Interrupt pin */
+ u8 NetIntPin0; /* Network Interrupt Pin */
+ u8 MinGrant; /* 09 Minimum grant */
+ u8 MaxLat; /* Maximum Latency */
+ u16 PciStatus; /* 10 PCI Status */
+ u16 SubSysVId; /* 11 Subsystem Vendor Id */
+ u16 SubSysId; /* 12 Subsystem ID */
+ u16 DbgDevId; /* 13 Debug Device Id */
+ u16 DramRomFn; /* 14 Dram/Rom function */
+ u16 DSize2Pci; /* 15 DRAM size to PCI (bytes * 64K) */
+ u16 RSize2Pci; /* 16 ROM extension size to PCI (bytes * 4k) */
+ u8 NetIntPin1; /* 17 Network Interface Pin 1
(simba/leone only) */
- unsigned char NetIntPin2; /*Network Interface Pin 2 (simba/leone only)*/
+ u8 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) */
+ u8 NetIntPin3; /* 18 Network Interface Pin 3 (simba only) */
+ u8 FreeTime; /* FreeTime setting (leone/mojave only) */
} u1;
- unsigned char TBIctl; /* 10-bit interface control (Mojave only) */
- ushort DramSize; /* 19 DRAM size (bytes * 64k) */
+ u8 TBIctl; /* 10-bit interface control (Mojave only) */
+ u16 DramSize; /* 19 DRAM size (bytes * 64k) */
union {
struct {
/* Mac Interface Specific portions */
@@ -750,67 +734,64 @@ struct slic_eeprom {
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 */
+ u16 DeviceId2; /* Device ID for 2nd PCI function */
+ u8 IntPin2; /* Interrupt pin for 2nd PCI function */
+ u8 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
+ u16 CfgByte6; /* Config Byte 6 */
+ u16 PMECapab; /* Power Mgment capabilities */
+ u16 NwClkCtrls; /* NetworkClockControls */
+ u8 FruFormat; /* Alacritech FRU format type */
+ struct atk_fru AtkFru; /* Alacritech FRU information */
+ u8 OemFruFormat; /* optional OEM FRU format type */
+ union oemfru OemFru; /* optional OEM FRU information */
+ u8 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 */
+ u16 Id; /* 00 EEPROM/FLASH Magic code 'A5A5' */
+ u16 EecodeSize; /* 01 Size of EEPROM Codes (bytes * 4)*/
+ u16 FlashConfig0; /* 02 Flash Config for SPI device 0 */
+ u16 FlashConfig1; /* 03 Flash Config for SPI device 1 */
+ u16 VendorId; /* 04 Vendor ID */
+ u16 DeviceId; /* 05 Device ID (function 0) */
+ u8 RevisionId; /* 06 Revision ID */
+ u8 ClassCode[3]; /* 07 Class Code for PCI function 0 */
+ u8 IntPin1; /* 08 Interrupt pin for PCI function 1*/
+ u8 ClassCode2[3]; /* 09 Class Code for PCI function 1 */
+ u8 IntPin2; /* 10 Interrupt pin for PCI function 2*/
+ u8 IntPin0; /* Interrupt pin for PCI function 0*/
+ u8 MinGrant; /* 11 Minimum grant */
+ u8 MaxLat; /* Maximum Latency */
+ u16 SubSysVId; /* 12 Subsystem Vendor Id */
+ u16 SubSysId; /* 13 Subsystem ID */
+ u16 FlashSize; /* 14 Flash size (bytes / 4K) */
+ u16 DSize2Pci; /* 15 DRAM size to PCI (bytes / 64K) */
+ u16 RSize2Pci; /* 16 Flash (ROM extension) size to PCI
+ (bytes / 4K) */
+ u16 DeviceId1; /* 17 Device Id (function 1) */
+ u16 DeviceId2; /* 18 Device Id (function 2) */
+ u16 CfgByte6; /* 19 Device Status Config Bytes 6-7 */
+ u16 PMECapab; /* 20 Power Mgment capabilities */
+ u8 MSICapab; /* 21 MSI capabilities */
+ u8 ClockDivider; /* Clock divider */
+ u16 PciStatusLow; /* 22 PCI Status bits 15:0 */
+ u16 PciStatusHigh; /* 23 PCI Status bits 31:16 */
+ u16 DramConfigLow; /* 24 DRAM Configuration bits 15:0 */
+ u16 DramConfigHigh; /* 25 DRAM Configuration bits 31:16 */
+ u16 DramSize; /* 26 DRAM size (bytes / 64K) */
+ u16 GpioTbiCtl; /* 27 GPIO/TBI controls for functions 1/0 */
+ u16 EepromSize; /* 28 EEPROM Size */
struct slic_config_mac MacInfo[2]; /* 29 MAC addresses (2 ports) */
- unsigned char FruFormat; /* 35 Alacritech FRU format type */
+ u8 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
+ u8 OemFruFormat; /* optional OEM FRU format type */
+ union oemfru OemFru; /* optional OEM FRU information */
+ u8 Pad[4]; /* Pad to 128 bytes - includes 2 checksum bytes
* (if OEM FRU info exists) and two unusable
* bytes at the end
*/
@@ -819,24 +800,25 @@ struct oslic_eeprom {
#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().
-*/
+/*
+ * 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) */
+ u16 DramSize; /* DRAM size (bytes / 64K) */
struct slic_config_mac MacInfo[SLIC_NBR_MACS]; /* MAC addresses */
- unsigned char FruFormat; /* Alacritech FRU format type */
+ u8 FruFormat; /* Alacritech FRU format type */
struct atk_fru AtkFru; /* Alacritech FRU information */
- unsigned char OemFruFormat; /* optional OEM FRU format type */
+ u8 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;
+ struct vendor1_fru vendor1_fru;
+ struct vendor2_fru vendor2_fru;
+ struct vendor3_fru vendor3_fru;
+ struct vendor4_fru vendor4_fru;
} OemFru;
};
diff --git a/drivers/staging/slicoss/slicinc.h b/drivers/staging/slicoss/slicinc.h
deleted file mode 100644
index 71288c4f7be..00000000000
--- a/drivers/staging/slicoss/slicinc.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/**************************************************************************
- *
- * 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
index bf7da8f898a..94815634847 100644
--- a/drivers/staging/slicoss/slicoss.c
+++ b/drivers/staging/slicoss/slicoss.c
@@ -55,19 +55,10 @@
*/
-#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
@@ -102,20 +93,73 @@
#include <asm/unaligned.h>
#include <linux/ethtool.h>
-#define SLIC_ETHTOOL_SUPPORT 1
-
#include <linux/uaccess.h>
-#include "slicinc.h"
-
-#if SLIC_DUMP_ENABLED
-#include "slicdump.h"
-#endif
+#include "slichw.h"
+#include "slic.h"
+
+static struct net_device_stats *slic_get_stats(struct net_device *dev);
+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 int slic_mac_set_address(struct net_device *dev, void *ptr);
+static void slic_link_event_handler(struct adapter *adapter);
+static void slic_upr_request_complete(struct adapter *adapter, u32 isr);
+static int slic_rspqueue_init(struct adapter *adapter);
+static void slic_rspqueue_free(struct adapter *adapter);
+static struct slic_rspbuf *slic_rspqueue_getnext(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_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_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 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_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 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_assert_fail(void);
+static ushort slic_eeprom_cksum(char *m, int len);
+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 void slic_mcast_set_list(struct net_device *dev);
-#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";
+ "and Storage Accelerator (Non-Accelerated)";
static char *slic_proc_version = "2.0.351 2006/07/14 12:26:00";
static char *slic_product_name = "SLIC Technology(tm) Server "\
@@ -129,8 +173,6 @@ 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;
@@ -164,6 +206,21 @@ static struct pci_device_id slic_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, slic_pci_tbl);
+#ifdef ASSERT
+#undef ASSERT
+#endif
+
+#ifndef ASSERT
+#define ASSERT(a) do { \
+ if (!(a)) { \
+ printk(KERN_ERR "slicoss ASSERT() Failure: function %s" \
+ "line %d\n", __func__, __LINE__); \
+ slic_assert_fail(); \
+ } \
+} while (0)
+#endif
+
+
#define SLIC_GET_SLIC_HANDLE(_adapter, _pslic_handle) \
{ \
spin_lock_irqsave(&_adapter->handle_lock.lock, \
@@ -195,17 +252,16 @@ 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)
+static inline void slic_reg32_write(void __iomem *reg, u32 value, bool 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)
+static inline void slic_reg64_write(struct adapter *adapter, void __iomem *reg,
+ u32 value, void __iomem *regh, u32 paddrh,
+ bool flush)
{
spin_lock_irqsave(&adapter->bit64reglock.lock,
adapter->bit64reglock.flags);
@@ -223,43 +279,12 @@ static inline void slic_reg64_write(struct adapter *adapter,
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,
@@ -268,9 +293,7 @@ static void slic_init_adapter(struct net_device *netdev,
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;
@@ -310,19 +333,11 @@ static void slic_init_adapter(struct net_device *netdev,
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));
@@ -335,7 +350,7 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
{
static int cards_found;
static int did_version;
- int err;
+ int err = -ENODEV;
struct net_device *netdev;
struct adapter *adapter;
void __iomem *memmapped_ioaddr = NULL;
@@ -344,54 +359,36 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
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);
+ printk(KERN_DEBUG "%s\n", slic_banner);
+ printk(KERN_DEBUG "%s\n", 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");
+ err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64));
+ if (err) {
+ err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32));
+ if (err)
+ goto err_out_disable_pci;
}
- 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;
- }
+ if (err)
+ goto err_out_disable_pci;
- 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);
@@ -403,24 +400,15 @@ static int __devinit slic_entry_probe(struct pci_dev *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 = (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;
+ dev_err(&pcidev->dev, "cannot remap MMIO region %lx @ %lx\n",
+ mmio_len, mmio_start);
+ goto err_out_free_netdev;
}
- 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();
@@ -430,7 +418,7 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
status = slic_card_locate(adapter);
if (status) {
- DBG_ERROR("%s cannot locate card\n", __func__);
+ dev_err(&pcidev->dev, "cannot locate card\n");
goto err_out_free_mmio_region;
}
@@ -441,22 +429,13 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
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);
+ dev_err(&pcidev->dev, "FAILED status[%x]\n", status);
} else {
slic_adapter_set_hwaddr(adapter);
}
@@ -468,9 +447,7 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
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);
@@ -478,35 +455,25 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err) {
- DBG_ERROR("Cannot register net device, aborting.\n");
+ dev_err(&pcidev->dev, "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_free_netdev:
+ free_netdev(netdev);
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;
+err_out_disable_pci:
+ pci_disable_device(pcidev);
+ return err;
}
static int slic_entry_open(struct net_device *dev)
@@ -518,16 +485,6 @@ static int slic_entry_open(struct net_device *dev)
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);
@@ -554,29 +511,14 @@ static int slic_entry_open(struct net_device *dev)
}
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;
}
@@ -591,22 +533,15 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
struct mcast_address *mcaddr, *mlist;
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);
/* free multicast addresses */
mlist = adapter->mcastaddrs;
@@ -620,10 +555,6 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
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) {
@@ -638,10 +569,8 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
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)
@@ -653,75 +582,35 @@ static int slic_entry_halt(struct net_device *dev)
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);
+ netif_stop_queue(adapter->netdev);
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);
+ slic_reg32_write(&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);
+ slic_reg32_write(&slic_regs->slic_reset_iface, 0, FLUSH);
#endif
/*
- * Reset the adapter's rsp, cmd, and rcv queues
+ * Reset the adapter's cmd 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);
-
+ if (!card->adapters_activated)
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;
@@ -729,69 +618,27 @@ static int slic_entry_halt(struct net_device *dev)
static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
+ struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ struct ethtool_cmd edata;
+ struct ethtool_cmd ecmd;
+ u32 data[7];
+ u32 intagg;
+
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 = netdev_priv(dev);
- 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
+ if (copy_from_user(data, rq->ifr_data, 28))
+ return -EFAULT;
+ intagg = data[0];
+ dev_err(&dev->dev, "%s: set interrupt aggregation to %d\n",
+ __func__, intagg);
+ slic_intagg_set(adapter, intagg);
+ return 0;
#ifdef SLIC_TRACE_DUMP_ENABLED
case SIOCSLICTRACEDUMP:
{
- ulong data[7];
- ulong value;
-
+ u32 value;
DBG_IOCTL("slic_ioctl SIOCSLIC_TRACE_DUMP\n");
if (copy_from_user(data, rq->ifr_data, 28)) {
@@ -824,104 +671,76 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
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)))
+ ASSERT(adapter);
+ if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd)))
+ return -EFAULT;
+
+ if (ecmd.cmd == ETHTOOL_GSET) {
+ edata.supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_Autoneg | SUPPORTED_MII);
+ edata.port = PORT_MII;
+ edata.transceiver = XCVR_INTERNAL;
+ edata.phy_address = 0;
+ if (adapter->linkspeed == LINK_100MB)
+ edata.speed = SPEED_100;
+ else if (adapter->linkspeed == LINK_10MB)
+ edata.speed = SPEED_10;
+ else
+ edata.speed = 0;
+
+ if (adapter->linkduplex == LINK_FULLD)
+ edata.duplex = DUPLEX_FULL;
+ else
+ edata.duplex = DUPLEX_HALF;
+
+ edata.autoneg = AUTONEG_ENABLE;
+ edata.maxtxpkt = 1;
+ edata.maxrxpkt = 1;
+ if (copy_to_user(rq->ifr_data, &edata, sizeof(edata)))
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;
+ } else if (ecmd.cmd == ETHTOOL_SSET) {
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
- 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->linkspeed == LINK_100MB)
+ edata.speed = SPEED_100;
+ else if (adapter->linkspeed == LINK_10MB)
+ edata.speed = SPEED_10;
+ else
+ edata.speed = 0;
- if (adapter->linkduplex == LINK_FULLD)
- data.duplex = DUPLEX_FULL;
+ if (adapter->linkduplex == LINK_FULLD)
+ edata.duplex = DUPLEX_FULL;
+ else
+ edata.duplex = DUPLEX_HALF;
+
+ edata.autoneg = AUTONEG_ENABLE;
+ edata.maxtxpkt = 1;
+ edata.maxrxpkt = 1;
+ if ((ecmd.speed != edata.speed) ||
+ (ecmd.duplex != edata.duplex)) {
+ u32 speed;
+ u32 duplex;
+
+ if (ecmd.speed == SPEED_10)
+ speed = 0;
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);
- }
+ speed = PCR_SPEED_100;
+ if (ecmd.duplex == DUPLEX_FULL)
+ duplex = PCR_DUPLEX_FULL;
+ else
+ duplex = 0;
+ slic_link_config(adapter, speed, duplex);
+ slic_link_event_handler(adapter);
}
- return 0;
}
-#endif
+ return 0;
default:
-/* DBG_MSG("slicoss: %s UNSUPPORTED[%x]\n", __func__, cmd); */
return -EOPNOTSUPP;
}
}
@@ -970,11 +789,6 @@ static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
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;
@@ -1015,14 +829,13 @@ static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
}
#endif
if (hcmd->paddrh == 0) {
- WRITE_REG(adapter->slic_regs->slic_cbar,
- (hcmd->paddrl | hcmd->cmdsize), DONT_FLUSH);
+ slic_reg32_write(&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);
+ slic_reg64_write(adapter, &adapter->slic_regs->slic_cbar64,
+ (hcmd->paddrl | hcmd->cmdsize),
+ &adapter->slic_regs->slic_addr_upper,
+ hcmd->paddrh, DONT_FLUSH);
}
xmit_done:
return 0;
@@ -1036,29 +849,29 @@ static void slic_xmit_fail(struct adapter *adapter,
void *cmd, u32 skbtype, u32 status)
{
if (adapter->xmitq_full)
- slic_if_stop_queue(adapter);
+ netif_stop_queue(adapter->netdev);
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);
+ dev_err(&adapter->netdev->dev,
+ "reject xmit skb[%p: %x] linkstate[%s] "
+ "adapter[%s:%d] card[%s:%d]\n",
+ 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);
+ dev_err(&adapter->netdev->dev,
+ "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);
+ dev_err(&adapter->netdev->dev,
+ "xmit_start skb[%p] type[%x] No host commands "
+ "available\n", skb, skb->pkt_type);
break;
default:
ASSERT(0);
@@ -1183,11 +996,6 @@ static void slic_rcv_handler(struct adapter *adapter)
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;
}
@@ -1242,12 +1050,6 @@ static void slic_xmit_complete(struct adapter *adapter)
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);
@@ -1267,7 +1069,8 @@ static irqreturn_t slic_interrupt(int irq, void *dev_id)
u32 isr;
if ((adapter->pshmem) && (adapter->pshmem->isr)) {
- WRITE_REG(adapter->slic_regs->slic_icr, ICR_INT_MASK, FLUSH);
+ slic_reg32_write(&adapter->slic_regs->slic_icr,
+ ICR_INT_MASK, FLUSH);
isr = adapter->isrcopy = adapter->pshmem->isr;
adapter->pshmem->isr = 0;
adapter->num_isrs++;
@@ -1299,29 +1102,18 @@ static irqreturn_t slic_interrupt(int irq, void *dev_id)
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);
+ dev_err(&dev->dev,
+ "isr & ISR_ERR [%x] "
+ "ISR_XDROP \n", isr);
} else {
- DBG_ERROR
- ("isr & ISR_ERR [%x]\n",
- isr);
+ dev_err(&dev->dev,
+ "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);
}
@@ -1359,7 +1151,7 @@ static irqreturn_t slic_interrupt(int irq, void *dev_id)
adapter->isrcopy = 0;
adapter->all_reg_writes += 2;
adapter->isr_reg_writes++;
- WRITE_REG(adapter->slic_regs->slic_isr, 0, FLUSH);
+ slic_reg32_write(&adapter->slic_regs->slic_isr, 0, FLUSH);
} else {
adapter->false_interrupts++;
}
@@ -1389,11 +1181,6 @@ static void slic_link_event_handler(struct adapter *adapter)
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),
@@ -1411,46 +1198,29 @@ static void slic_link_event_handler(struct adapter *adapter)
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);
@@ -1470,7 +1240,6 @@ static struct net_device_stats *slic_get_stats(struct net_device *dev)
stats->rx_length_errors = 0;
return &adapter->stats;
}
-#endif
/*
* Allocate a mcast_address structure to hold the multicast address.
@@ -1491,7 +1260,7 @@ static int slic_mcast_add_list(struct adapter *adapter, char *address)
}
/* Doesn't already exist. Allocate a structure to hold it */
- mcaddr = kmalloc(sizeof(struct mcast_address), GFP_ATOMIC);
+ mcaddr = kmalloc(sizeof(struct mcast_address), GFP_KERNEL);
if (mcaddr == NULL)
return 1;
@@ -1608,8 +1377,6 @@ static void slic_mcast_set_list(struct net_device *dev)
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) {
@@ -1623,9 +1390,7 @@ static void slic_mcast_set_list(struct net_device *dev)
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);
+ slic_config_set(adapter, true);
} else {
if (status == STATUS_SUCCESS)
slic_mcast_set_mask(adapter);
@@ -1637,36 +1402,23 @@ 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); */
+ slic_reg32_write(&slic_regs->slic_mcastlow, 0xFFFFFFFF, FLUSH);
+ slic_reg32_write(&slic_regs->slic_mcasthigh, 0xFFFFFFFF,
+ FLUSH);
} 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);
+ slic_reg32_write(&slic_regs->slic_mcastlow,
+ (u32)(adapter->mcastmask & 0xFFFFFFFF), FLUSH);
+ slic_reg32_write(&slic_regs->slic_mcasthigh,
+ (u32)((adapter->mcastmask >> 32) & 0xFFFFFFFF), FLUSH);
}
}
@@ -1680,53 +1432,11 @@ static void slic_timer_ping(ulong dev)
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);
+ adapter->pingtimer.expires = jiffies + (PING_TIMER_INTERVAL * HZ);
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
*
@@ -1742,14 +1452,11 @@ static int slic_if_init(struct adapter *adapter)
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");
+ dev_err(&dev->dev, "%s: adapter->state != ADAPT_DOWN\n",
+ __func__);
return -EIO;
}
ASSERT(adapter->linkstate == LINK_DOWN);
@@ -1757,54 +1464,35 @@ static int slic_if_init(struct adapter *adapter)
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) {
+ if (dev->flags & IFF_BROADCAST)
adapter->macopts |= MAC_BCAST;
- DBG_MSG("BCAST ");
- }
- if (dev->flags & IFF_PROMISC) {
+ if (dev->flags & IFF_PROMISC)
adapter->macopts |= MAC_PROMISC;
- DBG_MSG("PROMISC ");
- }
- if (dev->flags & IFF_ALLMULTI) {
+ if (dev->flags & IFF_ALLMULTI)
adapter->macopts |= MAC_ALLMCAST;
- DBG_MSG("ALL_MCAST ");
- }
- if (dev->flags & IFF_MULTICAST) {
+ 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);
+ dev_err(&dev->dev,
+ "%s: slic_adapter_allocresources FAILED %x\n",
+ __func__, 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);
+ slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
mdelay(1);
if (!adapter->isp_initialized) {
@@ -1814,13 +1502,13 @@ static int slic_if_init(struct adapter *adapter)
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);
+ slic_reg32_write(&slic_regs->slic_addr_upper,
+ SLIC_GET_ADDR_HIGH(&pshmem->isr), DONT_FLUSH);
+ slic_reg32_write(&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);
+ slic_reg32_write(&slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+ slic_reg32_write(&slic_regs->slic_isp, (u32)&pshmem->isr, FLUSH);
#else
Stop Compilations
#endif
@@ -1833,66 +1521,44 @@ static int slic_if_init(struct adapter *adapter)
if (!card->loadtimerset) {
init_timer(&card->loadtimer);
card->loadtimer.expires =
- jiffies + SLIC_SECS_TO_JIFFS(SLIC_LOADTIMER_PERIOD);
+ jiffies + (SLIC_LOADTIMER_PERIOD * HZ);
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);
+ jiffies + (PING_TIMER_INTERVAL * HZ);
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);
+ slic_reg32_write(&slic_regs->slic_isr, 0, FLUSH);
+ slic_reg32_write(&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)
@@ -1900,13 +1566,6 @@ 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);
@@ -1919,16 +1578,12 @@ static int slic_adapter_allocresources(struct adapter *adapter)
slic_global.driver_lock.flags);
if (retval) {
- DBG_ERROR("slicoss: request_irq (%s) FAILED [%x]\n",
- adapter->netdev->name, retval);
+ dev_err(&adapter->netdev->dev,
+ "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;
}
@@ -1939,22 +1594,17 @@ static void slic_config_pci(struct pci_dev *pcidev)
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);
+ if (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;
@@ -1967,7 +1617,6 @@ static void slic_adapter_freeresources(struct adapter *adapter)
adapter->rcv_broadcasts = 0;
adapter->rcv_multicasts = 0;
adapter->rcv_unicasts = 0;
- DBG_MSG("slicoss: %s EXIT\n", __func__);
}
/*
@@ -1979,21 +1628,15 @@ static void slic_adapter_freeresources(struct adapter *adapter)
static void slic_link_config(struct adapter *adapter,
u32 linkspeed, u32 linkduplex)
{
+ u32 __iomem *wphy;
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);
+ if (adapter->state != ADAPT_UP)
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));
@@ -2003,6 +1646,8 @@ static void slic_link_config(struct adapter *adapter,
if (linkduplex > LINK_AUTOD)
linkduplex = LINK_AUTOD;
+ wphy = &adapter->slic_regs->slic_wphy;
+
if ((linkspeed == LINK_AUTOSPEED) || (linkspeed == LINK_1000MB)) {
if (adapter->flags & ADAPT_FLAGS_FIBERMEDIA) {
/* We've got a fiber gigabit interface, and register
@@ -2013,8 +1658,7 @@ static void slic_link_config(struct adapter *adapter,
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);
+ slic_reg32_write(wphy, phy_advreg, FLUSH);
if (linkspeed == LINK_AUTOSPEED) {
/* reset phy, enable auto-neg */
@@ -2022,14 +1666,12 @@ static void slic_link_config(struct adapter *adapter,
(MIICR_REG_PCR |
(PCR_RESET | PCR_AUTONEG |
PCR_AUTONEG_RST));
- WRITE_REG(adapter->slic_regs->slic_wphy,
- phy_config, FLUSH);
+ slic_reg32_write(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);
+ slic_reg32_write(wphy, phy_config, FLUSH);
/* wait, Marvell says 1 sec,
try to get away with 10 ms */
mdelay(10);
@@ -2040,8 +1682,7 @@ static void slic_link_config(struct adapter *adapter,
(MIICR_REG_PCR |
(PCR_RESET | PCR_SPEED_1000 |
PCR_DUPLEX_FULL));
- WRITE_REG(adapter->slic_regs->slic_wphy,
- phy_config, FLUSH);
+ slic_reg32_write(wphy, phy_config, FLUSH);
}
} else { /* copper gigabit */
@@ -2065,35 +1706,30 @@ static void slic_link_config(struct adapter *adapter,
phy_advreg |= PAR_ASYMPAUSE;
/* required by the Cicada PHY */
phy_advreg |= PAR_802_3;
- WRITE_REG(adapter->slic_regs->slic_wphy, phy_advreg,
- FLUSH);
+ slic_reg32_write(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);
+ slic_reg32_write(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);
+ slic_reg32_write(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);
+ slic_reg32_write(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);
+ slic_reg32_write(wphy, phy_config, FLUSH);
}
}
} else {
@@ -2111,13 +1747,12 @@ static void slic_link_config(struct adapter *adapter,
/* 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);
+ slic_reg32_write(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);
+ slic_reg32_write(wphy, phy_config, FLUSH);
/* wait, Marvell says 1 sec, try to get away with 10 ms */
mdelay(10);
@@ -2128,43 +1763,17 @@ static void slic_link_config(struct adapter *adapter,
soft reset phy, powerup */
phy_config =
(MIICR_REG_PCR | (PCR_RESET | speed | duplex));
- WRITE_REG(adapter->slic_regs->slic_wphy, phy_config,
- FLUSH);
+ slic_reg32_write(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);
+ slic_reg32_write(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);
@@ -2173,7 +1782,6 @@ static void slic_card_cleanup(struct sliccard *card)
slic_debug_card_destroy(card);
kfree(card);
- DBG_MSG("slicoss: %s EXIT\n", __func__);
}
static int slic_card_download_gbrcv(struct adapter *adapter)
@@ -2183,15 +1791,16 @@ static int slic_card_download_gbrcv(struct adapter *adapter)
int ret;
__iomem struct slic_regs *slic_regs = adapter->slic_regs;
u32 codeaddr;
- unsigned char *instruction = NULL;
+ u32 instruction;
+ int index = 0;
u32 rcvucodelen = 0;
switch (adapter->devid) {
case SLIC_2GB_DEVICE_ID:
- file = "oasis_rcv.bin";
+ file = "slicoss/oasisrcvucode.sys";
break;
case SLIC_1GB_DEVICE_ID:
- file = "gb_rcv.bin";
+ file = "slicoss/gbrcvucode.sys";
break;
default:
ASSERT(0);
@@ -2200,12 +1809,13 @@ static int slic_card_download_gbrcv(struct adapter *adapter)
ret = request_firmware(&fw, file, &adapter->pcidev->dev);
if (ret) {
- printk(KERN_ERR "SLICOSS: Failed to load firmware %s\n", file);
+ dev_err(&adapter->pcidev->dev,
+ "SLICOSS: Failed to load firmware %s\n", file);
return ret;
}
- instruction = (unsigned char *)fw->data;
- rcvucodelen = fw->size;
+ rcvucodelen = *(u32 *)(fw->data + index);
+ index += 4;
switch (adapter->devid) {
case SLIC_2GB_DEVICE_ID:
if (rcvucodelen != OasisRcvUCodeLen)
@@ -2219,29 +1829,28 @@ static int slic_card_download_gbrcv(struct adapter *adapter)
ASSERT(0);
break;
}
-
/* start download */
- WRITE_REG(slic_regs->slic_rcv_wcs, SLIC_RCVWCS_BEGIN, FLUSH);
-
+ slic_reg32_write(&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);
+ slic_reg32_write(&slic_regs->slic_rcv_wcs, codeaddr, FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
/* write out the instruction data low addr */
- WRITE_REG(slic_regs->slic_rcv_wcs,
- (u32) *(u32 *) instruction, FLUSH);
- instruction += 4;
+ slic_reg32_write(&slic_regs->slic_rcv_wcs, instruction, FLUSH);
+ instruction = *(u8 *)(fw->data + index);
+ index++;
/* write out the instruction data high addr */
- WRITE_REG(slic_regs->slic_rcv_wcs, (u32) *instruction,
- FLUSH);
- instruction += 1;
+ slic_reg32_write(&slic_regs->slic_rcv_wcs, (u8)instruction,
+ FLUSH);
}
/* download finished */
release_firmware(fw);
- WRITE_REG(slic_regs->slic_rcv_wcs, SLIC_RCVWCS_FINISH, FLUSH);
+ slic_reg32_write(&slic_regs->slic_rcv_wcs, SLIC_RCVWCS_FINISH, FLUSH);
return 0;
}
@@ -2254,41 +1863,21 @@ static int slic_card_download(struct adapter *adapter)
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 instruction;
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()); */
+ int ucode_start, index = 0;
switch (adapter->devid) {
case SLIC_2GB_DEVICE_ID:
-/* DBG_MSG ("slicoss: %s devid==SLIC_2GB_DEVICE_ID sections[%x]\n",
- __func__, (uint) ONumSections); */
- file = "slic_oasis.bin";
- numsects = ONumSections;
- for (i = 0; i < numsects; i++) {
- sectsize[i] = OSectionSize[i];
- sectstart[i] = OSectionStart[i];
- }
+ file = "slicoss/oasisdownload.sys";
break;
case SLIC_1GB_DEVICE_ID:
-/* DBG_MSG ("slicoss: %s devid==SLIC_1GB_DEVICE_ID sections[%x]\n",
- __func__, (uint) MNumSections); */
- file = "slic_mojave.bin";
- numsects = MNumSections;
- for (i = 0; i < numsects; i++) {
- sectsize[i] = MSectionSize[i];
- sectstart[i] = MSectionStart[i];
- }
+ file = "slicoss/gbdownload.sys";
break;
default:
ASSERT(0);
@@ -2296,131 +1885,84 @@ static int slic_card_download(struct adapter *adapter)
}
ret = request_firmware(&fw, file, &adapter->pcidev->dev);
if (ret) {
- printk(KERN_ERR "SLICOSS: Failed to load firmware %s\n", file);
+ dev_err(&adapter->pcidev->dev,
+ "SLICOSS: Failed to load firmware %s\n", file);
return ret;
}
-
+ numsects = *(u32 *)(fw->data + index);
+ index += 4;
ASSERT(numsects <= 3);
-
+ for (i = 0; i < numsects; i++) {
+ sectsize[i] = *(u32 *)(fw->data + index);
+ index += 4;
+ }
+ for (i = 0; i < numsects; i++) {
+ sectstart[i] = *(u32 *)(fw->data + index);
+ index += 4;
+ }
+ ucode_start = index;
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
for (section = 0; section < numsects; section++) {
- switch (adapter->devid) {
- case SLIC_2GB_DEVICE_ID:
- instruction = (u32 *)(fw->data + (SECTION_SIZE *
- section));
- baseaddress = sectstart[section];
- thissectionsize = sectsize[section] >> 3;
- lastinstruct =
- (u32 *)(fw->data + (SECTION_SIZE * section) +
- sectsize[section] - 8);
- break;
- case SLIC_1GB_DEVICE_ID:
- instruction = (u32 *)(fw->data + (SECTION_SIZE *
- section));
- baseaddress = sectstart[section];
- thissectionsize = sectsize[section] >> 3;
- lastinstruct =
- (u32 *)(fw->data + (SECTION_SIZE * 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);
+ slic_reg32_write(&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
+ slic_reg32_write(&slic_regs->slic_wcs, instruction, FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
+
/* 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
+ slic_reg32_write(&slic_regs->slic_wcs, instruction, FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
}
}
-
+ index = ucode_start;
for (section = 0; section < numsects; section++) {
- switch (adapter->devid) {
- case SLIC_2GB_DEVICE_ID:
- instruction = (u32 *)fw->data + (SECTION_SIZE *
- section);
- break;
- case SLIC_1GB_DEVICE_ID:
- instruction = (u32 *)fw->data + (SECTION_SIZE *
- section);
- break;
- default:
- ASSERT(0);
- break;
- }
-
+ instruction = *(u32 *)(fw->data + index);
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);
+ slic_reg32_write(&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
+ slic_reg32_write(&slic_regs->slic_wcs, instruction,
+ FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
/* 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
+ slic_reg32_write(&slic_regs->slic_wcs, instruction,
+ FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
+
/* Check SRAM location zero. If it is non-zero. Abort.*/
- failure = readl((u32 __iomem *)&slic_regs->slic_reset);
+/* 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);
release_firmware(fw);
return -EIO;
- }
+ }*/
}
}
-/* DBG_MSG ("slicoss: Compare done\n");*/
release_firmware(fw);
/* Everything OK, kick off the card */
mdelay(10);
- WRITE_REG(slic_regs->slic_wcs, SLIC_WCS_START, FLUSH);
+ slic_reg32_write(&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;
}
@@ -2428,19 +1970,10 @@ 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])) {
@@ -2451,15 +1984,11 @@ static void slic_adapter_set_hwaddr(struct adapter *adapter)
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);
+ slic_reg32_write(&adapter->slic_regs->slic_intagg, value, FLUSH);
adapter->card->loadlevel_current = value;
}
@@ -2485,10 +2014,6 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
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);
@@ -2496,9 +2021,9 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
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);
+ dev_err(&adapter->pcidev->dev,
+ "download failed bus %d slot %d\n",
+ adapter->busnumber, adapter->slotnumber);
return status;
}
@@ -2510,33 +2035,24 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
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);
+ dev_err(&adapter->pcidev->dev,
+ "eeprom read failed to get memory "
+ "bus %d slot %d\n", adapter->busnumber,
+ adapter->slotnumber);
return -ENOMEM;
} else {
memset(peeprom, 0, sizeof(struct slic_eeprom));
}
- WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+ slic_reg32_write(&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);
+ slic_reg32_write(&slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+ slic_reg32_write(&slic_regs->slic_isp,
+ SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
spin_unlock_irqrestore(&adapter->bit64reglock.lock,
adapter->bit64reglock.flags);
@@ -2544,41 +2060,33 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
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_reg64_write(adapter,
+ &slic_regs->slic_isp, 0,
+ &slic_regs->slic_addr_upper,
+ 0, FLUSH);
+ slic_reg32_write(&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);
+ slic_reg32_write(&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);
+ dev_err(&adapter->pcidev->dev,
+ "%d config data fetch timed out!\n",
+ adapter->port);
+ slic_reg64_write(adapter,
+ &slic_regs->slic_isp, 0,
+ &slic_regs->slic_addr_upper,
+ 0, FLUSH);
return -EINVAL;
}
}
@@ -2614,7 +2122,7 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
break;
}
- card->config.EepromValid = FALSE;
+ card->config.EepromValid = false;
/* see if the EEPROM is valid by checking it's checksum */
if ((eecodesize <= MAX_EECODE_SIZE) &&
@@ -2633,7 +2141,7 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
we wouldn't need this shit
*/
if (ee_chksum == calc_chksum)
- card->config.EepromValid = TRUE;
+ card->config.EepromValid = true;
}
/* copy in the DRAM size */
card->config.DramSize = dramsize;
@@ -2643,8 +2151,6 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
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;
@@ -2654,20 +2160,14 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
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");
+ slic_reg64_write(adapter, &slic_regs->slic_isp, 0,
+ &slic_regs->slic_addr_upper,
+ 0, FLUSH);
+ dev_err(&adapter->pcidev->dev,
+ "unsupported CONFIGURATION EEPROM invalid\n");
return -EINVAL;
}
@@ -2675,74 +2175,26 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
}
if (slic_card_download_gbrcv(adapter)) {
- DBG_ERROR("%s unable to download GB receive microcode\n",
- __func__);
+ dev_err(&adapter->pcidev->dev,
+ "unable to download GB receive microcode\n");
return -EINVAL;
}
- if (slic_global.dynamic_intagg) {
- DBG_MSG
- ("Dynamic Interrupt Aggregation[ENABLED]: slic%d \
- SET intagg to %d\n",
- card->cardnum, 0);
+ if (slic_global.dynamic_intagg)
slic_intagg_set(adapter, 0);
- } else {
+ 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;
}
@@ -2756,10 +2208,6 @@ static u32 slic_card_locate(struct adapter *adapter)
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;
@@ -2775,11 +2223,9 @@ static u32 slic_card_locate(struct adapter *adapter)
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) {
@@ -2789,17 +2235,6 @@ static u32 slic_card_locate(struct adapter *adapter)
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;
@@ -2812,23 +2247,11 @@ static u32 slic_card_locate(struct adapter *adapter)
}
}
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;
@@ -2861,14 +2284,9 @@ static u32 slic_card_locate(struct adapter *adapter)
}
if (!physcard) {
/* no structure allocated for this physical card yet */
- physcard = kzalloc(sizeof(struct physcard), GFP_ATOMIC);
+ physcard = kzalloc(sizeof(struct physcard), GFP_KERNEL);
ASSERT(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;
@@ -2881,8 +2299,6 @@ static u32 slic_card_locate(struct adapter *adapter)
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;
}
@@ -2890,16 +2306,12 @@ static u32 slic_card_locate(struct adapter *adapter)
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);
+ slic_reg32_write(&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);
+ slic_reg32_write(&adapter->slic_regs->slic_reset, SLIC_RESET_MAGIC,
+ FLUSH);
mdelay(1);
}
@@ -2909,10 +2321,6 @@ static void slic_config_set(struct adapter *adapter, bool linkchange)
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);
@@ -2928,9 +2336,7 @@ static void slic_config_set(struct adapter *adapter, bool linkchange)
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);
+ slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
/* Setup rcvcfg last */
value = (RcrReset | /* Reset, if linkchange */
@@ -2943,9 +2349,7 @@ static void slic_config_set(struct adapter *adapter, bool linkchange)
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);
+ slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
/* Setup rcvcfg last */
value = (RcrReset | /* Reset, if linkchange */
@@ -2962,8 +2366,7 @@ static void slic_config_set(struct adapter *adapter, bool linkchange)
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);
+ slic_reg32_write(&slic_regs->slic_wrcfg, value, FLUSH);
}
/*
@@ -2979,18 +2382,18 @@ static void slic_config_clear(struct adapter *adapter)
value = (GXCR_RESET | /* Always reset */
GXCR_PAUSEEN); /* Enable pause */
- WRITE_REG(slic_regs->slic_wxcfg, value, FLUSH);
+ slic_reg32_write(&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);
+ slic_reg32_write(&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);
+ slic_reg32_write(&slic_regs->slic_wphy, phy_config, FLUSH);
}
static void slic_config_get(struct adapter *adapter, u32 config,
@@ -3012,18 +2415,14 @@ static void slic_mac_address_config(struct adapter *adapter)
value = *(u32 *) &adapter->currmacaddr[2];
value = ntohl(value);
- WRITE_REG(slic_regs->slic_wraddral, value, FLUSH);
- WRITE_REG(slic_regs->slic_wraddrbl, value, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wraddral, value, FLUSH);
+ slic_reg32_write(&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);
+ slic_reg32_write(&slic_regs->slic_wraddrah, value2, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wraddrbh, value2, FLUSH);
/* Write our multicast mask out to the card. This is done */
/* here in addition to the slic_mcast_addr_set routine */
@@ -3058,7 +2457,7 @@ static void slic_mac_config(struct adapter *adapter)
}
/* write mac config */
- WRITE_REG(slic_regs->slic_wmcfg, value, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wmcfg, value, FLUSH);
/* setup mac addresses */
slic_mac_address_config(adapter);
@@ -3072,18 +2471,15 @@ static bool slic_mac_filter(struct adapter *adapter,
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 (opts & MAC_PROMISC)
+ return true;
if ((*dhost4 == 0xFFFFFFFF) && (*dhost2 == 0xFFFF)) {
if (opts & MAC_BCAST) {
adapter->rcv_broadcasts++;
- return TRUE;
+ return true;
} else {
- return FALSE;
+ return false;
}
}
@@ -3091,7 +2487,7 @@ static bool slic_mac_filter(struct adapter *adapter,
if (opts & MAC_ALLMCAST) {
adapter->rcv_multicasts++;
adapter->stats.multicast++;
- return TRUE;
+ return true;
}
if (opts & MAC_MCAST) {
struct mcast_address *mcaddr = adapter->mcastaddrs;
@@ -3103,20 +2499,20 @@ static bool slic_mac_filter(struct adapter *adapter,
if (equaladdr) {
adapter->rcv_multicasts++;
adapter->stats.multicast++;
- return TRUE;
+ return true;
}
mcaddr = mcaddr->next;
}
- return FALSE;
+ return false;
} else {
- return FALSE;
+ return false;
}
}
if (opts & MAC_DIRECTED) {
adapter->rcv_unicasts++;
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
@@ -3125,80 +2521,28 @@ 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);
+ 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 = netdev_priv((struct net_device *)dev);
- 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 __iomem *intagg;
u32 load = card->events;
u32 level = 0;
+ intagg = &adapter->slic_regs->slic_intagg;
+
if ((adapter) && (adapter->state == ADAPT_UP) &&
(card->state == CARD_UP) && (slic_global.dynamic_intagg)) {
if (adapter->devid == SLIC_1GB_DEVICE_ID) {
@@ -3220,8 +2564,7 @@ static void slic_timer_load_check(ulong cardaddr)
}
if (card->loadlevel_current != level) {
card->loadlevel_current = level;
- WRITE_REG(adapter->slic_regs->slic_intagg,
- level, FLUSH);
+ slic_reg32_write(intagg, level, FLUSH);
}
} else {
if (load > SLIC_LOAD_5)
@@ -3238,14 +2581,12 @@ static void slic_timer_load_check(ulong cardaddr)
level = SLIC_INTAGG_0;
if (card->loadlevel_current != level) {
card->loadlevel_current = level;
- WRITE_REG(adapter->slic_regs->slic_intagg,
- level, FLUSH);
+ slic_reg32_write(intagg, level, FLUSH);
}
}
}
card->events = 0;
- card->loadtimer.expires =
- jiffies + SLIC_SECS_TO_JIFFS(SLIC_LOADTIMER_PERIOD);
+ card->loadtimer.expires = jiffies + (SLIC_LOADTIMER_PERIOD * HZ);
add_timer(&card->loadtimer);
}
@@ -3256,7 +2597,8 @@ static void slic_assert_fail(void)
cpuid = smp_processor_id();
curr_pid = current->pid;
- DBG_ERROR("%s CPU # %d ---- PID # %d\n", __func__, cpuid, curr_pid);
+ printk(KERN_ERR "%s CPU # %d ---- PID # %d\n",
+ __func__, cpuid, curr_pid);
}
static int slic_upr_queue_request(struct adapter *adapter,
@@ -3269,11 +2611,9 @@ static int slic_upr_queue_request(struct adapter *adapter,
struct slic_upr *uprqueue;
upr = kmalloc(sizeof(struct slic_upr), GFP_ATOMIC);
- if (!upr) {
- DBG_MSG("%s COULD NOT ALLOCATE UPR MEM\n", __func__);
-
+ if (!upr)
return -ENOMEM;
- }
+
upr->adapter = adapter->port;
upr->upr_request = upr_request;
upr->upr_data = upr_data;
@@ -3322,10 +2662,6 @@ 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) {
@@ -3341,38 +2677,19 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
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);
+ dev_err(&adapter->netdev->dev,
+ "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);
@@ -3431,7 +2748,6 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
old->rcv_drops_gb);
}
memcpy(old, newstats, sizeof(struct slic_stats));
-#endif
break;
}
case SLIC_UPR_RLSR:
@@ -3454,11 +2770,6 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
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);
}
@@ -3487,74 +2798,29 @@ static void slic_upr_start(struct adapter *adapter)
switch (upr->upr_request) {
case SLIC_UPR_STATS:
if (upr->upr_data_h == 0) {
- WRITE_REG(slic_regs->slic_stats, upr->upr_data, FLUSH);
+ slic_reg32_write(&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);
+ slic_reg64_write(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);
+ slic_reg64_write(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);
+ slic_reg64_write(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);
+ slic_reg32_write(&slic_regs->slic_ping, 1, FLUSH);
break;
default:
ASSERT(0);
@@ -3568,10 +2834,6 @@ static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
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;
@@ -3599,50 +2861,33 @@ static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
|| (adapter->devid == SLIC_2GB_DEVICE_ID));
linkup = linkstatus & GIG_LINKUP ? LINK_UP : LINK_DOWN;
- if (linkstatus & GIG_SPEED_1000) {
+ 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) {
+ else if (linkstatus & GIG_SPEED_100)
linkspeed = LINK_100MB;
- DBG_MSG("slicoss: %s (%s) GIGABIT Speed==100MB ", __func__,
- adapter->netdev->name);
- } else {
+ else
linkspeed = LINK_10MB;
- DBG_MSG("slicoss: %s (%s) GIGABIT Speed==10MB ", __func__,
- adapter->netdev->name);
- }
- if (linkstatus & GIG_FULLDUPLEX) {
+
+ if (linkstatus & GIG_FULLDUPLEX)
linkduplex = LINK_FULLD;
- DBG_MSG(" Duplex == FULL\n");
- } else {
+ 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);
+ if ((adapter->linkstate == LINK_DOWN) && (linkup == LINK_DOWN))
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);
+ (adapter->linkduplex == linkduplex))
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;
}
@@ -3652,30 +2897,10 @@ static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
if (adapter->linkstate != LINK_UP) {
/* setup the mac */
- DBG_MSG("%s call slic_config_set\n", __func__);
- slic_config_set(adapter, TRUE);
+ 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;
+ netif_start_queue(adapter->netdev);
}
-#endif
}
/*
@@ -3787,20 +3012,18 @@ static int slic_rspqueue_init(struct adapter *adapter)
__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]);
+ 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");
+ dev_err(&adapter->pcidev->dev,
+ "pci_alloc_consistent failed\n");
slic_rspqueue_free(adapter);
return STATUS_FAILURE;
}
@@ -3811,47 +3034,21 @@ static int slic_rspqueue_init(struct adapter *adapter)
(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);
+ slic_reg32_write(&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);
+ slic_reg64_write(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;
}
@@ -3860,14 +3057,8 @@ 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]);
}
@@ -3900,11 +3091,9 @@ static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter)
#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);
+ slic_reg64_write(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 *)
@@ -3932,12 +3121,8 @@ 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],
@@ -3972,7 +3157,6 @@ 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));
@@ -3994,7 +3178,6 @@ static int slic_cmdq_init(struct adapter *adapter)
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;
}
@@ -4003,8 +3186,6 @@ 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) {
@@ -4030,7 +3211,6 @@ static void slic_cmdq_reset(struct adapter *adapter)
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,
@@ -4042,11 +3222,8 @@ static void slic_cmdq_reset(struct adapter *adapter)
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;
@@ -4065,14 +3242,14 @@ static void slic_cmdq_reset(struct adapter *adapter)
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);
+ dev_err(&adapter->netdev->dev,
+ "free_count %d != all count %d\n",
+ 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)
@@ -4090,8 +3267,6 @@ static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page)
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);
@@ -4117,7 +3292,7 @@ static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page)
cmd->pslic_handle = pslic_handle;
cmd->cmd64.hosthandle = pslic_handle->token.handle_token;
- cmd->busy = FALSE;
+ cmd->busy = false;
cmd->paddrl = phys_addrl;
cmd->paddrh = phys_addrh;
cmd->next_all = prev;
@@ -4133,13 +3308,11 @@ static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page)
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);
}
@@ -4184,7 +3357,6 @@ static void slic_cmdq_getdone(struct adapter *adapter)
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;
@@ -4201,9 +3373,7 @@ static void slic_cmdq_putdone_irq(struct adapter *adapter,
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))
@@ -4216,7 +3386,6 @@ 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;
@@ -4233,25 +3402,6 @@ static int slic_rcvqueue_init(struct adapter *adapter)
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;
}
@@ -4290,8 +3440,8 @@ static struct sk_buff *slic_rcvqueue_getnext(struct adapter *adapter)
skb = NULL;
}
} else {
- DBG_ERROR("RcvQ Empty!! adapter[%p] rcvq[%p] count[%x]\n",
- adapter, rcvq, rcvq->count);
+ dev_err(&adapter->netdev->dev,
+ "RcvQ Empty!! rcvq[%p] count[%x]\n", rcvq, rcvq->count);
skb = NULL;
}
while (rcvq->count < SLIC_RCVQ_FILLTHRESH) {
@@ -4311,6 +3461,7 @@ static int slic_rcvqueue_fill(struct adapter *adapter)
u32 paddrh;
struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
int i = 0;
+ struct device *dev = &adapter->netdev->dev;
while (i < SLIC_RCVQ_FILLENTRIES) {
struct slic_rcvbuf *rcvbuf;
@@ -4333,44 +3484,45 @@ retry_rcvqfill:
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");
+ dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
+ __func__);
+ dev_err(dev, "skb[%p] PROBLEM\n", skb);
+ dev_err(dev, " skbdata[%p]\n", skb->data);
+ dev_err(dev, " skblen[%x]\n", skb->len);
+ dev_err(dev, " paddr[%p]\n", paddr);
+ dev_err(dev, " paddrl[%x]\n", paddrl);
+ dev_err(dev, " paddrh[%x]\n", paddrh);
+ dev_err(dev, " rcvq->head[%p]\n", rcvq->head);
+ dev_err(dev, " rcvq->tail[%p]\n", rcvq->tail);
+ dev_err(dev, " rcvq->count[%x]\n", rcvq->count);
+ dev_err(dev, "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);
+ dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
+ __func__);
+ dev_err(dev, "skb[%p] PROBLEM\n", skb);
+ dev_err(dev, " skbdata[%p]\n", skb->data);
+ dev_err(dev, " skblen[%x]\n", skb->len);
+ dev_err(dev, " paddr[%p]\n", paddr);
+ dev_err(dev, " paddrl[%x]\n", paddrl);
+ dev_err(dev, " paddrh[%x]\n", paddrh);
+ dev_err(dev, " rcvq->head[%p]\n", rcvq->head);
+ dev_err(dev, " rcvq->tail[%p]\n", rcvq->tail);
+ dev_err(dev, " rcvq->count[%x]\n", rcvq->count);
+ dev_err(dev, "GIVE TO CARD ANYWAY\n");
}
#endif
if (paddrh == 0) {
- WRITE_REG(adapter->slic_regs->slic_hbar,
- (u32) paddrl, DONT_FLUSH);
+ slic_reg32_write(&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);
+ slic_reg64_write(adapter,
+ &adapter->slic_regs->slic_hbar64,
+ paddrl,
+ &adapter->slic_regs->slic_addr_upper,
+ paddrh, DONT_FLUSH);
}
if (rcvq->head)
rcvq->tail->next = skb;
@@ -4380,10 +3532,9 @@ retry_rcvqfill:
rcvq->count++;
i++;
} else {
- DBG_ERROR
- ("%s slic_rcvqueue_fill could only get [%d] "
- "skbuffs\n",
- adapter->netdev->name, i);
+ dev_err(&adapter->netdev->dev,
+ "slic_rcvqueue_fill could only get [%d] skbuffs\n",
+ i);
break;
}
}
@@ -4397,6 +3548,7 @@ static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb)
u32 paddrl;
u32 paddrh;
struct slic_rcvbuf *rcvbuf = (struct slic_rcvbuf *)skb->head;
+ struct device *dev;
ASSERT(skb->len == SLIC_RCVBUF_HEADSIZE);
@@ -4409,26 +3561,26 @@ static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb)
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);
+ dev = &adapter->netdev->dev;
+ dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
+ __func__);
+ dev_err(dev, "skb[%p] PROBLEM\n", skb);
+ dev_err(dev, " skbdata[%p]\n", skb->data);
+ dev_err(dev, " skblen[%x]\n", skb->len);
+ dev_err(dev, " paddr[%p]\n", paddr);
+ dev_err(dev, " paddrl[%x]\n", paddrl);
+ dev_err(dev, " paddrh[%x]\n", paddrh);
+ dev_err(dev, " rcvq->head[%p]\n", rcvq->head);
+ dev_err(dev, " rcvq->tail[%p]\n", rcvq->tail);
+ dev_err(dev, " rcvq->count[%x]\n", rcvq->count);
}
if (paddrh == 0) {
- WRITE_REG(adapter->slic_regs->slic_hbar, (u32) paddrl,
- DONT_FLUSH);
+ slic_reg32_write(&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);
+ slic_reg64_write(adapter, &adapter->slic_regs->slic_hbar64,
+ paddrl, &adapter->slic_regs->slic_addr_upper,
+ paddrh, DONT_FLUSH);
}
if (rcvq->head)
rcvq->tail->next = skb;
@@ -4449,7 +3601,7 @@ static int slic_debug_card_show(struct seq_file *seq, void *v)
unsigned char *oemfru = (unsigned char *)(&card->config.OemFru);
#endif
- seq_printf(seq, "driver_version : %s", slic_proc_version);
+ seq_printf(seq, "driver_version : %s\n", 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);
@@ -4882,1030 +4034,6 @@ static void slic_debug_cleanup(void)
}
}
-/*=============================================================================
- =============================================================================
- === ===
- === 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 ***************/
/******************************************************************************/
@@ -5915,46 +4043,25 @@ static struct pci_driver slic_driver = {
.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);
+ printk(KERN_DEBUG KBUILD_MODNAME ": 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;
+ return pci_register_driver(&slic_driver);
}
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);
diff --git a/drivers/staging/stlc45xx/Kconfig b/drivers/staging/stlc45xx/Kconfig
new file mode 100644
index 00000000000..8d3f46f190e
--- /dev/null
+++ b/drivers/staging/stlc45xx/Kconfig
@@ -0,0 +1,8 @@
+config STLC45XX
+ tristate "stlc4550/4560 support"
+ depends on MAC80211 && WLAN_80211 && SPI_MASTER
+ ---help---
+ This is a driver for stlc4550 and stlc4560 chipsets.
+
+ To compile this driver as a module, choose M here: the module will be
+ called stlc45xx. If unsure, say N.
diff --git a/drivers/staging/stlc45xx/Makefile b/drivers/staging/stlc45xx/Makefile
new file mode 100644
index 00000000000..7ee32903055
--- /dev/null
+++ b/drivers/staging/stlc45xx/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_STLC45XX) += stlc45xx.o
diff --git a/drivers/staging/stlc45xx/stlc45xx.c b/drivers/staging/stlc45xx/stlc45xx.c
new file mode 100644
index 00000000000..3eced5520c5
--- /dev/null
+++ b/drivers/staging/stlc45xx/stlc45xx.c
@@ -0,0 +1,2606 @@
+/*
+ * This file is part of stlc45xx
+ *
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "stlc45xx.h"
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+#include <linux/etherdevice.h>
+#include <linux/gpio.h>
+#include <linux/moduleparam.h>
+
+#include "stlc45xx_lmac.h"
+
+/*
+ * gpios should be handled in board files and provided via platform data,
+ * but because it's currently impossible for stlc45xx to have a header file
+ * in include/linux, let's use module paramaters for now
+ */
+static int stlc45xx_gpio_power = 97;
+module_param(stlc45xx_gpio_power, int, 0444);
+MODULE_PARM_DESC(stlc45xx_gpio_power, "stlc45xx gpio number for power line");
+
+static int stlc45xx_gpio_irq = 87;
+module_param(stlc45xx_gpio_irq, int, 0444);
+MODULE_PARM_DESC(stlc45xx_gpio_irq, "stlc45xx gpio number for irq line");
+
+static const u8 default_cal_channels[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x09,
+ 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10,
+ 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xe0, 0x00, 0xe0, 0x00,
+ 0xe0, 0x00, 0xe0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0,
+ 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42,
+ 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+ 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9,
+ 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00,
+ 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+ 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0,
+ 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+ 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d,
+ 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+ 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17,
+ 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+ 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00,
+ 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x71, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8,
+ 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0,
+ 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6,
+ 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00,
+ 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+ 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0,
+ 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+ 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca,
+ 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4,
+ 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+ 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21,
+ 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00,
+ 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00,
+ 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+ 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0,
+ 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
+ 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0,
+ 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+ 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0,
+ 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+ 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37,
+ 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc,
+ 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+ 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b,
+ 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+ 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00,
+ 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00,
+ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0,
+ 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+ 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a,
+ 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x09, 0x00, 0x00, 0xc9, 0xff,
+ 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10,
+ 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab,
+ 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb,
+ 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+ 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33,
+ 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+ 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00,
+ 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00,
+ 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+ 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0,
+ 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7,
+ 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17,
+ 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+ 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d,
+ 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00,
+ 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0,
+ 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42,
+ 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+ 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01,
+ 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00,
+ 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+ 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0,
+ 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+ 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0,
+ 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21,
+ 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17,
+ 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+ 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+ 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0,
+ 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x09, 0x00, 0x00, 0xc9,
+ 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
+ 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01,
+ 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00,
+ 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+ 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0,
+ 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+ 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb,
+ 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b,
+ 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+ 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21,
+ 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+ 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0,
+ 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+ 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0,
+ 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x8a, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00,
+ 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0,
+ 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0,
+ 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+ 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22,
+ 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33,
+ 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+ 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b,
+ 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+ 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+ 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0,
+ 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0,
+ 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0,
+ 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+ 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d,
+ 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x09, 0x00, 0x00,
+ 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10,
+ 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54,
+ 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42,
+ 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+ 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33,
+ 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+ 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+ 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0,
+ 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+ 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0,
+ 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+ 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17,
+ 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+ 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c,
+ 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x94, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00,
+ 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0,
+ 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42,
+ 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+ 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+ 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0,
+ 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+ 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0,
+ 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4,
+ 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+ 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21,
+ 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d,
+ 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00,
+ 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+ 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0,
+ 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x09, 0x00,
+ 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
+ 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+ 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0,
+ 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+ 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0,
+ 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc,
+ 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+ 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b,
+ 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+ 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54,
+ 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00,
+ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+ 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0,
+ 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+ 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06,
+ 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x9e, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff,
+ 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10,
+ 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0,
+ 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb,
+ 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+ 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33,
+ 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+ 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79,
+ 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00,
+ 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+ 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0,
+ 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9,
+ 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0,
+ 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+ 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d,
+ 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00 };
+
+static const u8 default_cal_rssi[] = {
+ 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72,
+ 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00,
+ 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a,
+ 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe,
+ 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00,
+ 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01,
+ 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a,
+ 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+static void stlc45xx_tx_edcf(struct stlc45xx *stlc);
+static void stlc45xx_tx_setup(struct stlc45xx *stlc);
+static void stlc45xx_tx_scan(struct stlc45xx *stlc);
+static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable);
+static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave);
+static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave);
+
+static ssize_t stlc45xx_sysfs_show_cal_rssi(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct stlc45xx *stlc = dev_get_drvdata(dev);
+ ssize_t len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ len = PAGE_SIZE;
+
+ mutex_lock(&stlc->mutex);
+
+ if (stlc->cal_rssi)
+ hex_dump_to_buffer(stlc->cal_rssi, RSSI_CAL_ARRAY_LEN, 16,
+ 2, buf, len, 0);
+ mutex_unlock(&stlc->mutex);
+
+ len = strlen(buf);
+
+ return len;
+}
+
+static ssize_t stlc45xx_sysfs_store_cal_rssi(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct stlc45xx *stlc = dev_get_drvdata(dev);
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ if (count != RSSI_CAL_ARRAY_LEN) {
+ stlc45xx_error("invalid cal_rssi length: %zu", count);
+ count = 0;
+ goto out_unlock;
+ }
+
+ kfree(stlc->cal_rssi);
+
+ stlc->cal_rssi = kmemdup(buf, RSSI_CAL_ARRAY_LEN, GFP_KERNEL);
+
+ if (!stlc->cal_rssi) {
+ stlc45xx_error("failed to allocate memory for cal_rssi");
+ count = 0;
+ goto out_unlock;
+ }
+
+ out_unlock:
+ mutex_unlock(&stlc->mutex);
+
+ return count;
+}
+
+static ssize_t stlc45xx_sysfs_show_cal_channels(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct stlc45xx *stlc = dev_get_drvdata(dev);
+ ssize_t len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ len = PAGE_SIZE;
+
+ mutex_lock(&stlc->mutex);
+
+ if (stlc->cal_channels)
+ hex_dump_to_buffer(stlc->cal_channels, CHANNEL_CAL_ARRAY_LEN,
+ 16, 2, buf, len, 0);
+
+ mutex_unlock(&stlc->mutex);
+
+ len = strlen(buf);
+
+ return len;
+}
+
+static ssize_t stlc45xx_sysfs_store_cal_channels(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct stlc45xx *stlc = dev_get_drvdata(dev);
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ if (count != CHANNEL_CAL_ARRAY_LEN) {
+ stlc45xx_error("invalid cal_channels size: %zu ", count);
+ count = 0;
+ goto out_unlock;
+ }
+
+ kfree(stlc->cal_channels);
+
+ stlc->cal_channels = kmemdup(buf, count, GFP_KERNEL);
+
+ if (!stlc->cal_channels) {
+ stlc45xx_error("failed to allocate memory for cal_channels");
+ count = 0;
+ goto out_unlock;
+ }
+
+out_unlock:
+ mutex_unlock(&stlc->mutex);
+
+ return count;
+}
+
+static ssize_t stlc45xx_sysfs_show_tx_buf(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct stlc45xx *stlc = dev_get_drvdata(dev);
+ struct txbuffer *entry;
+ ssize_t len = 0;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ list_for_each_entry(entry, &stlc->tx_sent, tx_list) {
+ len += sprintf(buf + len, "0x%x: 0x%x-0x%x\n",
+ entry->handle, entry->start,
+ entry->end);
+ }
+
+ mutex_unlock(&stlc->mutex);
+
+ return len;
+}
+
+static DEVICE_ATTR(cal_rssi, S_IRUGO | S_IWUSR,
+ stlc45xx_sysfs_show_cal_rssi,
+ stlc45xx_sysfs_store_cal_rssi);
+static DEVICE_ATTR(cal_channels, S_IRUGO | S_IWUSR,
+ stlc45xx_sysfs_show_cal_channels,
+ stlc45xx_sysfs_store_cal_channels);
+static DEVICE_ATTR(tx_buf, S_IRUGO, stlc45xx_sysfs_show_tx_buf, NULL);
+
+static void stlc45xx_spi_read(struct stlc45xx *stlc, unsigned long addr,
+ void *buf, size_t len)
+{
+ struct spi_transfer t[2];
+ struct spi_message m;
+
+ /* We first push the address */
+ addr = (addr << 8) | ADDR_READ_BIT_15;
+
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
+
+ t[0].tx_buf = &addr;
+ t[0].len = 2;
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].rx_buf = buf;
+ t[1].len = len;
+ spi_message_add_tail(&t[1], &m);
+
+ spi_sync(stlc->spi, &m);
+}
+
+
+static void stlc45xx_spi_write(struct stlc45xx *stlc, unsigned long addr,
+ void *buf, size_t len)
+{
+ struct spi_transfer t[3];
+ struct spi_message m;
+ u16 last_word;
+
+ /* We first push the address */
+ addr = addr << 8;
+
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
+
+ t[0].tx_buf = &addr;
+ t[0].len = 2;
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].tx_buf = buf;
+ t[1].len = len;
+ spi_message_add_tail(&t[1], &m);
+
+ if (len % 2) {
+ last_word = ((u8 *)buf)[len - 1];
+
+ t[2].tx_buf = &last_word;
+ t[2].len = 2;
+ spi_message_add_tail(&t[2], &m);
+ }
+
+ spi_sync(stlc->spi, &m);
+}
+
+static u16 stlc45xx_read16(struct stlc45xx *stlc, unsigned long addr)
+{
+ u16 val;
+
+ stlc45xx_spi_read(stlc, addr, &val, sizeof(val));
+
+ return val;
+}
+
+static u32 stlc45xx_read32(struct stlc45xx *stlc, unsigned long addr)
+{
+ u32 val;
+
+ stlc45xx_spi_read(stlc, addr, &val, sizeof(val));
+
+ return val;
+}
+
+static void stlc45xx_write16(struct stlc45xx *stlc, unsigned long addr, u16 val)
+{
+ stlc45xx_spi_write(stlc, addr, &val, sizeof(val));
+}
+
+static void stlc45xx_write32(struct stlc45xx *stlc, unsigned long addr, u32 val)
+{
+ stlc45xx_spi_write(stlc, addr, &val, sizeof(val));
+}
+
+struct stlc45xx_spi_reg {
+ u16 address;
+ u16 length;
+ char *name;
+};
+
+/* caller must hold tx_lock */
+static void stlc45xx_txbuffer_dump(struct stlc45xx *stlc)
+{
+ struct txbuffer *txbuffer;
+ char *buf, *pos;
+ int buf_len, l, count;
+
+ if (!(DEBUG_LEVEL & DEBUG_TXBUFFER))
+ return;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+ buf_len = 500;
+ buf = kmalloc(buf_len, GFP_ATOMIC);
+ if (!buf)
+ return;
+
+ pos = buf;
+ count = 0;
+
+ list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) {
+ l = snprintf(pos, buf_len, "0x%x-0x%x,",
+ txbuffer->start, txbuffer->end);
+ /* drop the null byte */
+ pos += l;
+ buf_len -= l;
+ count++;
+ }
+
+ if (count == 0)
+ *pos = '\0';
+ else
+ *--pos = '\0';
+
+ stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: in buffer %d regions: %s",
+ count, buf);
+
+ kfree(buf);
+}
+
+/* caller must hold tx_lock */
+static int stlc45xx_txbuffer_find(struct stlc45xx *stlc, size_t len)
+{
+ struct txbuffer *txbuffer;
+ int pos;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+ pos = FIRMWARE_TXBUFFER_START;
+
+ if (list_empty(&stlc->txbuffer))
+ goto out;
+
+ /*
+ * the entries in txbuffer must be in the same order as they are in
+ * the real buffer
+ */
+ list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) {
+ if (pos + len < txbuffer->start)
+ break;
+ pos = ALIGN(txbuffer->end + 1, 4);
+ }
+
+ if (pos + len > FIRMWARE_TXBUFFER_END)
+ /* not enough room */
+ pos = -1;
+
+ stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: find %zu B: 0x%x", len, pos);
+
+out:
+ return pos;
+}
+
+static int stlc45xx_txbuffer_add(struct stlc45xx *stlc,
+ struct txbuffer *txbuffer)
+{
+ struct txbuffer *r, *prev = NULL;
+
+ if (list_empty(&stlc->txbuffer)) {
+ list_add(&txbuffer->buffer_list, &stlc->txbuffer);
+ return 0;
+ }
+
+ r = list_first_entry(&stlc->txbuffer, struct txbuffer, buffer_list);
+
+ if (txbuffer->start < r->start) {
+ /* add to the beginning of the list */
+ list_add(&txbuffer->buffer_list, &stlc->txbuffer);
+ return 0;
+ }
+
+ prev = NULL;
+ list_for_each_entry(r, &stlc->txbuffer, buffer_list) {
+ /* skip first entry, we checked for that above */
+ if (!prev) {
+ prev = r;
+ continue;
+ }
+
+ /* double-check overlaps */
+ WARN_ON_ONCE(txbuffer->start >= r->start &&
+ txbuffer->start <= r->end);
+ WARN_ON_ONCE(txbuffer->end >= r->start &&
+ txbuffer->end <= r->end);
+
+ if (prev->end < txbuffer->start &&
+ txbuffer->end < r->start) {
+ /* insert at this spot */
+ list_add_tail(&txbuffer->buffer_list, &r->buffer_list);
+ return 0;
+ }
+
+ prev = r;
+ }
+
+ /* not found */
+ list_add_tail(&txbuffer->buffer_list, &stlc->txbuffer);
+
+ return 0;
+
+}
+
+/* caller must hold tx_lock */
+static struct txbuffer *stlc45xx_txbuffer_alloc(struct stlc45xx *stlc,
+ size_t frame_len)
+{
+ struct txbuffer *entry = NULL;
+ size_t len;
+ int pos;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+ len = FIRMWARE_TXBUFFER_HEADER + frame_len + FIRMWARE_TXBUFFER_TRAILER;
+ pos = stlc45xx_txbuffer_find(stlc, len);
+
+ if (pos < 0)
+ return NULL;
+
+ WARN_ON_ONCE(pos + len > FIRMWARE_TXBUFFER_END);
+ WARN_ON_ONCE(pos < FIRMWARE_TXBUFFER_START);
+
+ entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+ entry->start = pos;
+ entry->frame_start = pos + FIRMWARE_TXBUFFER_HEADER;
+ entry->end = entry->start + len - 1;
+
+ stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: allocated 0x%x-0x%x",
+ entry->start, entry->end);
+
+ stlc45xx_txbuffer_add(stlc, entry);
+
+ stlc45xx_txbuffer_dump(stlc);
+
+ return entry;
+}
+
+/* caller must hold tx_lock */
+static void stlc45xx_txbuffer_free(struct stlc45xx *stlc,
+ struct txbuffer *txbuffer)
+{
+ stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+ stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: freed 0x%x-0x%x",
+ txbuffer->start, txbuffer->end);
+
+ list_del(&txbuffer->buffer_list);
+ kfree(txbuffer);
+}
+
+
+static int stlc45xx_wait_bit(struct stlc45xx *stlc, u16 reg, u32 mask,
+ u32 expected)
+{
+ int i;
+ char buffer[4];
+
+ for (i = 0; i < 2000; i++) {
+ stlc45xx_spi_read(stlc, reg, buffer, sizeof(buffer));
+ if (((*(u32 *)buffer) & mask) == expected)
+ return 1;
+ msleep(1);
+ }
+
+ return 0;
+}
+
+static int stlc45xx_request_firmware(struct stlc45xx *stlc)
+{
+ const struct firmware *fw;
+ int ret;
+
+ /* FIXME: should driver use it's own struct device? */
+ ret = request_firmware(&fw, "3826.arm", &stlc->spi->dev);
+
+ if (ret < 0) {
+ stlc45xx_error("request_firmware() failed: %d", ret);
+ return ret;
+ }
+
+ if (fw->size % 4) {
+ stlc45xx_error("firmware size is not multiple of 32bit: %zu",
+ fw->size);
+ return -EILSEQ; /* Illegal byte sequence */;
+ }
+
+ if (fw->size < 1000) {
+ stlc45xx_error("firmware is too small: %zu", fw->size);
+ return -EILSEQ;
+ }
+
+ stlc->fw = kmemdup(fw->data, fw->size, GFP_KERNEL);
+ if (!stlc->fw) {
+ stlc45xx_error("could not allocate memory for firmware");
+ return -ENOMEM;
+ }
+
+ stlc->fw_len = fw->size;
+
+ release_firmware(fw);
+
+ return 0;
+}
+
+static int stlc45xx_upload_firmware(struct stlc45xx *stlc)
+{
+ struct s_dma_regs dma_regs;
+ unsigned long fw_len, fw_addr;
+ long _fw_len;
+ int ret;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ if (!stlc->fw) {
+ ret = stlc45xx_request_firmware(stlc);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* stop the device */
+ stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
+ SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET
+ | SPI_CTRL_STAT_START_HALTED);
+
+ msleep(TARGET_BOOT_SLEEP);
+
+ stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
+ SPI_CTRL_STAT_HOST_OVERRIDE
+ | SPI_CTRL_STAT_START_HALTED);
+
+ msleep(TARGET_BOOT_SLEEP);
+
+ fw_addr = FIRMWARE_ADDRESS;
+ fw_len = stlc->fw_len;
+
+ while (fw_len > 0) {
+ _fw_len = (fw_len > SPI_MAX_PACKET_SIZE)
+ ? SPI_MAX_PACKET_SIZE : fw_len;
+ dma_regs.cmd = SPI_DMA_WRITE_CTRL_ENABLE;
+ dma_regs.len = cpu_to_le16(_fw_len);
+ dma_regs.addr = cpu_to_le32(fw_addr);
+
+ fw_len -= _fw_len;
+ fw_addr += _fw_len;
+
+ stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_CTRL, dma_regs.cmd);
+
+ if (stlc45xx_wait_bit(stlc, SPI_ADRS_DMA_WRITE_CTRL,
+ HOST_ALLOWED, HOST_ALLOWED) == 0) {
+ stlc45xx_error("fw_upload not allowed to DMA write");
+ return -EAGAIN;
+ }
+
+ stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_LEN, dma_regs.len);
+ stlc45xx_write32(stlc, SPI_ADRS_DMA_WRITE_BASE, dma_regs.addr);
+
+ stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, stlc->fw, _fw_len);
+
+ /* FIXME: I think this doesn't work if firmware is large,
+ * this loop goes to second round. fw->data is not
+ * increased at all! */
+ }
+
+ BUG_ON(fw_len != 0);
+
+ /* enable host interrupts */
+ stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN, SPI_HOST_INTS_DEFAULT);
+
+ /* boot the device */
+ stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
+ SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET
+ | SPI_CTRL_STAT_RAM_BOOT);
+
+ msleep(TARGET_BOOT_SLEEP);
+
+ stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
+ SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT);
+ msleep(TARGET_BOOT_SLEEP);
+
+ return 0;
+}
+
+/* caller must hold tx_lock */
+static void stlc45xx_check_txsent(struct stlc45xx *stlc)
+{
+ struct txbuffer *entry, *n;
+
+ list_for_each_entry_safe(entry, n, &stlc->tx_sent, tx_list) {
+ if (time_after(jiffies, entry->lifetime)) {
+ if (net_ratelimit())
+ stlc45xx_warning("frame 0x%x lifetime exceeded",
+ entry->start);
+ list_del(&entry->tx_list);
+ skb_pull(entry->skb, entry->header_len);
+ ieee80211_tx_status(stlc->hw, entry->skb);
+ stlc45xx_txbuffer_free(stlc, entry);
+ }
+ }
+}
+
+static void stlc45xx_power_off(struct stlc45xx *stlc)
+{
+ disable_irq(gpio_to_irq(stlc45xx_gpio_irq));
+ gpio_set_value(stlc45xx_gpio_power, 0);
+}
+
+static void stlc45xx_power_on(struct stlc45xx *stlc)
+{
+ gpio_set_value(stlc45xx_gpio_power, 1);
+ enable_irq(gpio_to_irq(stlc45xx_gpio_irq));
+
+ /*
+ * need to wait a while before device can be accessed, the length
+ * is just a guess
+ */
+ msleep(10);
+}
+
+/* caller must hold tx_lock */
+static void stlc45xx_flush_queues(struct stlc45xx *stlc)
+{
+ struct txbuffer *entry;
+
+ while (!list_empty(&stlc->tx_sent)) {
+ entry = list_first_entry(&stlc->tx_sent,
+ struct txbuffer, tx_list);
+ list_del(&entry->tx_list);
+ dev_kfree_skb(entry->skb);
+ stlc45xx_txbuffer_free(stlc, entry);
+ }
+
+ WARN_ON(!list_empty(&stlc->tx_sent));
+
+ while (!list_empty(&stlc->tx_pending)) {
+ entry = list_first_entry(&stlc->tx_pending,
+ struct txbuffer, tx_list);
+ list_del(&entry->tx_list);
+ dev_kfree_skb(entry->skb);
+ stlc45xx_txbuffer_free(stlc, entry);
+ }
+
+ WARN_ON(!list_empty(&stlc->tx_pending));
+ WARN_ON(!list_empty(&stlc->txbuffer));
+}
+
+static void stlc45xx_work_reset(struct work_struct *work)
+{
+ struct stlc45xx *stlc = container_of(work, struct stlc45xx,
+ work_reset);
+
+ mutex_lock(&stlc->mutex);
+
+ if (stlc->fw_state != FW_STATE_RESET)
+ goto out;
+
+ stlc45xx_power_off(stlc);
+
+ mutex_unlock(&stlc->mutex);
+
+ /* wait that all work_structs have finished, we can't hold
+ * stlc->mutex to avoid deadlock */
+ cancel_work_sync(&stlc->work);
+
+ /* FIXME: find out good value to wait for chip power down */
+ msleep(100);
+
+ mutex_lock(&stlc->mutex);
+
+ /* FIXME: we should gracefully handle if the state has changed
+ * after re-acquiring mutex */
+ WARN_ON(stlc->fw_state != FW_STATE_RESET);
+
+ spin_lock_bh(&stlc->tx_lock);
+ stlc45xx_flush_queues(stlc);
+ spin_unlock_bh(&stlc->tx_lock);
+
+ stlc->fw_state = FW_STATE_RESETTING;
+
+ stlc45xx_power_on(stlc);
+ stlc45xx_upload_firmware(stlc);
+
+out:
+ mutex_unlock(&stlc->mutex);
+}
+
+/* caller must hold mutex */
+static void stlc45xx_reset(struct stlc45xx *stlc)
+{
+ stlc45xx_warning("resetting firmware");
+ stlc->fw_state = FW_STATE_RESET;
+ ieee80211_stop_queues(stlc->hw);
+ queue_work(stlc->hw->workqueue, &stlc->work_reset);
+}
+
+static void stlc45xx_work_tx_timeout(struct work_struct *work)
+{
+ struct stlc45xx *stlc = container_of(work, struct stlc45xx,
+ work_tx_timeout.work);
+
+ stlc45xx_warning("tx timeout");
+
+ mutex_lock(&stlc->mutex);
+
+ if (stlc->fw_state != FW_STATE_READY)
+ goto out;
+
+ stlc45xx_reset(stlc);
+
+out:
+ mutex_unlock(&stlc->mutex);
+}
+
+static void stlc45xx_int_ack(struct stlc45xx *stlc, u32 val)
+{
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_ACK, val);
+}
+
+static void stlc45xx_wakeup(struct stlc45xx *stlc)
+{
+ unsigned long timeout;
+ u32 ints;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ /* wake the chip */
+ stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_WAKEUP);
+
+ /* And wait for the READY interrupt */
+ timeout = jiffies + HZ;
+
+ ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+ while (!(ints & SPI_HOST_INT_READY)) {
+ if (time_after(jiffies, timeout))
+ goto out;
+ ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+ }
+
+ stlc45xx_int_ack(stlc, SPI_HOST_INT_READY);
+
+out:
+ return;
+}
+
+static void stlc45xx_sleep(struct stlc45xx *stlc)
+{
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_SLEEP);
+}
+
+static void stlc45xx_int_ready(struct stlc45xx *stlc)
+{
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN,
+ SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE);
+
+ switch (stlc->fw_state) {
+ case FW_STATE_BOOTING:
+ stlc->fw_state = FW_STATE_READY;
+ complete(&stlc->fw_comp);
+ break;
+ case FW_STATE_RESETTING:
+ stlc->fw_state = FW_STATE_READY;
+
+ stlc45xx_tx_scan(stlc);
+ stlc45xx_tx_setup(stlc);
+ stlc45xx_tx_edcf(stlc);
+
+ ieee80211_wake_queues(stlc->hw);
+ break;
+ default:
+ break;
+ }
+}
+
+static int stlc45xx_rx_txack(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info;
+ struct s_lm_control *control;
+ struct s_lmo_tx *tx;
+ struct txbuffer *entry;
+ int found = 0;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ control = (struct s_lm_control *) skb->data;
+ tx = (struct s_lmo_tx *) (control + 1);
+
+ if (list_empty(&stlc->tx_sent)) {
+ if (net_ratelimit())
+ stlc45xx_warning("no frames waiting for "
+ "acknowledgement");
+ return -1;
+ }
+
+ list_for_each_entry(entry, &stlc->tx_sent, tx_list) {
+ if (control->handle == entry->handle) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ if (net_ratelimit())
+ stlc45xx_warning("couldn't find frame for tx ack 0x%x",
+ control->handle);
+ return -1;
+ }
+
+ stlc45xx_debug(DEBUG_TX, "TX ACK 0x%x", entry->handle);
+
+ if (entry->status_needed) {
+ info = IEEE80211_SKB_CB(entry->skb);
+
+ if (!(tx->flags & LM_TX_FAILED)) {
+ /* frame was acked */
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ info->status.ack_signal = tx->rcpi / 2 - 110;
+ }
+
+ skb_pull(entry->skb, entry->header_len);
+
+ ieee80211_tx_status(stlc->hw, entry->skb);
+ }
+
+ list_del(&entry->tx_list);
+
+ stlc45xx_check_txsent(stlc);
+ if (list_empty(&stlc->tx_sent))
+ /* there are no pending frames, we can stop the tx timeout
+ * timer */
+ cancel_delayed_work(&stlc->work_tx_timeout);
+
+ spin_lock_bh(&stlc->tx_lock);
+
+ stlc45xx_txbuffer_free(stlc, entry);
+
+ if (stlc->tx_queue_stopped &&
+ stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) != -1) {
+ stlc45xx_debug(DEBUG_QUEUE, "room in tx buffer, waking queues");
+ ieee80211_wake_queues(stlc->hw);
+ stlc->tx_queue_stopped = 0;
+ }
+
+ spin_unlock_bh(&stlc->tx_lock);
+
+ return 0;
+}
+
+static int stlc45xx_rx_control(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+ struct s_lm_control *control;
+ int ret = 0;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ control = (struct s_lm_control *) skb->data;
+
+ switch (control->oid) {
+ case LM_OID_TX:
+ ret = stlc45xx_rx_txack(stlc, skb);
+ break;
+ case LM_OID_SETUP:
+ case LM_OID_SCAN:
+ case LM_OID_TRAP:
+ case LM_OID_EDCF:
+ case LM_OID_KEYCACHE:
+ case LM_OID_PSM:
+ case LM_OID_STATS:
+ case LM_OID_LED:
+ default:
+ stlc45xx_warning("unhandled rx control oid %d\n",
+ control->oid);
+ break;
+ }
+
+ dev_kfree_skb(skb);
+
+ return ret;
+}
+
+/* copied from mac80211 */
+static void stlc45xx_parse_elems(u8 *start, size_t len,
+ struct stlc45xx_ie_tim **tim,
+ size_t *tim_len)
+{
+ size_t left = len;
+ u8 *pos = start;
+
+ while (left >= 2) {
+ u8 id, elen;
+
+ id = *pos++;
+ elen = *pos++;
+ left -= 2;
+
+ if (elen > left)
+ return;
+
+ switch (id) {
+ case WLAN_EID_TIM:
+ *tim = (struct stlc45xx_ie_tim *) pos;
+ *tim_len = elen;
+ break;
+ default:
+ break;
+ }
+
+ left -= elen;
+ pos += elen;
+ }
+}
+
+/*
+ * mac80211 doesn't have support for asking frames with PS-Poll, so let's
+ * implement in the driver for now. We have to add support to mac80211
+ * later.
+ */
+static int stlc45xx_check_more_data(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+ struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
+ struct ieee80211_hdr *hdr;
+ size_t len;
+ u16 fc;
+
+ hdr = (void *) skb->data + sizeof(*data);
+ len = skb->len - sizeof(*data);
+
+ /* minimum frame length is the null frame length 24 bytes */
+ if (len < 24) {
+ stlc45xx_warning("invalid frame length when checking for "
+ "more data");
+ return -EINVAL;
+ }
+
+ fc = le16_to_cpu(hdr->frame_control);
+ if (!(fc & IEEE80211_FCTL_FROMDS))
+ /* this is not from DS */
+ return 0;
+
+ if (compare_ether_addr(hdr->addr1, stlc->mac_addr) != 0)
+ /* the frame was not for us */
+ return 0;
+
+ if (!(fc & IEEE80211_FCTL_MOREDATA)) {
+ /* AP has no more frames buffered for us */
+ stlc45xx_debug(DEBUG_PSM, "all buffered frames retrieved");
+ stlc->pspolling = false;
+ return 0;
+ }
+
+ /* MOREDATA bit is set, let's ask for a new frame from the AP */
+ stlc45xx_tx_pspoll(stlc, stlc->psm);
+
+ return 0;
+}
+
+/*
+ * mac80211 cannot read TIM from beacons, so let's add a hack to the
+ * driver. We have to add support to mac80211 later.
+ */
+static int stlc45xx_rx_data_beacon(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+ struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
+ size_t len = skb->len, tim_len = 0, baselen, pvbmap_len;
+ struct ieee80211_mgmt *mgmt;
+ struct stlc45xx_ie_tim *tim = NULL;
+ int bmap_offset, index, aid_bit;
+
+ mgmt = (void *) skb->data + sizeof(*data);
+
+ baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
+ if (baselen > len) {
+ stlc45xx_warning("invalid baselen in beacon");
+ return -EINVAL;
+ }
+
+ stlc45xx_parse_elems(mgmt->u.beacon.variable, len - baselen, &tim,
+ &tim_len);
+
+ if (!tim) {
+ stlc45xx_warning("didn't find tim from a beacon");
+ return -EINVAL;
+ }
+
+ bmap_offset = tim->bmap_control & 0xfe;
+ index = stlc->aid / 8 - bmap_offset;
+
+ pvbmap_len = tim_len - 3;
+ if (index > pvbmap_len)
+ return -EINVAL;
+
+ aid_bit = !!(tim->pvbmap[index] & (1 << stlc->aid % 8));
+
+ stlc45xx_debug(DEBUG_PSM, "fc 0x%x duration %d seq %d dtim %u "
+ "bmap_control 0x%x aid_bit %d",
+ mgmt->frame_control, mgmt->duration, mgmt->seq_ctrl >> 4,
+ tim->dtim_count, tim->bmap_control, aid_bit);
+
+ if (!aid_bit)
+ return 0;
+
+ stlc->pspolling = true;
+ stlc45xx_tx_pspoll(stlc, stlc->psm);
+
+ return 0;
+}
+
+static int stlc45xx_rx_data(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+ struct ieee80211_rx_status status;
+ struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
+ int align = 0;
+ u8 *p, align_len;
+ u16 len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ if (stlc->psm) {
+ if (data->flags & LM_IN_BEACON)
+ stlc45xx_rx_data_beacon(stlc, skb);
+ else if (stlc->pspolling && (data->flags & LM_IN_DATA))
+ stlc45xx_check_more_data(stlc, skb);
+ }
+
+ memset(&status, 0, sizeof(status));
+
+ status.freq = data->frequency;
+ status.signal = data->rcpi / 2 - 110;
+
+ /* let's assume that maximum rcpi value is 140 (= 35 dBm) */
+ status.qual = data->rcpi * 100 / 140;
+
+ status.band = IEEE80211_BAND_2GHZ;
+
+ /*
+ * FIXME: this gives warning from __ieee80211_rx()
+ *
+ * status.rate_idx = data->rate;
+ */
+
+ len = data->length;
+
+ if (data->flags & LM_FLAG_ALIGN)
+ align = 1;
+
+ skb_pull(skb, sizeof(*data));
+
+ if (align) {
+ p = skb->data;
+ align_len = *p;
+ skb_pull(skb, align_len);
+ }
+
+ skb_trim(skb, len);
+
+ stlc45xx_debug(DEBUG_RX, "rx data 0x%p %d B", skb->data, skb->len);
+ stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
+
+ ieee80211_rx(stlc->hw, skb, &status);
+
+ return 0;
+}
+
+
+
+static int stlc45xx_rx(struct stlc45xx *stlc)
+{
+ struct s_lm_control *control;
+ struct sk_buff *skb;
+ int ret;
+ u16 len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ stlc45xx_wakeup(stlc);
+
+ /* dummy read to flush SPI DMA controller bug */
+ stlc45xx_read16(stlc, SPI_ADRS_GEN_PURP_1);
+
+ len = stlc45xx_read16(stlc, SPI_ADRS_DMA_DATA);
+
+ if (len == 0) {
+ stlc45xx_warning("rx request of zero bytes");
+ return 0;
+ }
+
+ skb = dev_alloc_skb(len);
+ if (!skb) {
+ stlc45xx_warning("could not alloc skb");
+ return 0;
+ }
+
+ stlc45xx_spi_read(stlc, SPI_ADRS_DMA_DATA, skb_put(skb, len), len);
+
+ stlc45xx_sleep(stlc);
+
+ stlc45xx_debug(DEBUG_RX, "rx frame 0x%p %d B", skb->data, skb->len);
+ stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
+
+ control = (struct s_lm_control *) skb->data;
+
+ if (control->flags & LM_FLAG_CONTROL)
+ ret = stlc45xx_rx_control(stlc, skb);
+ else
+ ret = stlc45xx_rx_data(stlc, skb);
+
+ return ret;
+}
+
+
+static irqreturn_t stlc45xx_interrupt(int irq, void *config)
+{
+ struct spi_device *spi = config;
+ struct stlc45xx *stlc = dev_get_drvdata(&spi->dev);
+
+ stlc45xx_debug(DEBUG_IRQ, "IRQ");
+
+ queue_work(stlc->hw->workqueue, &stlc->work);
+
+ return IRQ_HANDLED;
+}
+
+static int stlc45xx_tx_frame(struct stlc45xx *stlc, u32 address,
+ void *buf, size_t len)
+{
+ struct s_dma_regs dma_regs;
+ unsigned long timeout;
+ int ret = 0;
+ u32 ints;
+
+ stlc->tx_frames++;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ stlc45xx_debug(DEBUG_TX, "tx frame 0x%p %zu B", buf, len);
+ stlc45xx_dump(DEBUG_TX_CONTENT, buf, len);
+
+ stlc45xx_wakeup(stlc);
+
+ dma_regs.cmd = SPI_DMA_WRITE_CTRL_ENABLE;
+ dma_regs.len = cpu_to_le16(len);
+ dma_regs.addr = cpu_to_le32(address);
+
+ stlc45xx_spi_write(stlc, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs,
+ sizeof(dma_regs));
+
+ stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, buf, len);
+
+ timeout = jiffies + 2 * HZ;
+ ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+ while (!(ints & SPI_HOST_INT_WR_READY)) {
+ if (time_after(jiffies, timeout)) {
+ stlc45xx_warning("WR_READY timeout");
+ ret = -1;
+ goto out;
+ }
+ ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+ }
+
+ stlc45xx_int_ack(stlc, SPI_HOST_INT_WR_READY);
+
+ stlc45xx_sleep(stlc);
+
+out:
+ return ret;
+}
+
+static int stlc45xx_wq_tx(struct stlc45xx *stlc)
+{
+ struct txbuffer *entry;
+ int ret = 0;
+
+ spin_lock_bh(&stlc->tx_lock);
+
+ while (!list_empty(&stlc->tx_pending)) {
+ entry = list_entry(stlc->tx_pending.next,
+ struct txbuffer, tx_list);
+
+ list_del_init(&entry->tx_list);
+
+ spin_unlock_bh(&stlc->tx_lock);
+
+ ret = stlc45xx_tx_frame(stlc, entry->frame_start,
+ entry->skb->data, entry->skb->len);
+
+ spin_lock_bh(&stlc->tx_lock);
+
+ if (ret < 0) {
+ /* frame transfer to firmware buffer failed */
+ /* FIXME: report this to mac80211 */
+ dev_kfree_skb(entry->skb);
+ stlc45xx_txbuffer_free(stlc, entry);
+ goto out;
+ }
+
+ list_add(&entry->tx_list, &stlc->tx_sent);
+ queue_delayed_work(stlc->hw->workqueue,
+ &stlc->work_tx_timeout,
+ msecs_to_jiffies(TX_TIMEOUT));
+ }
+
+out:
+ spin_unlock_bh(&stlc->tx_lock);
+ return ret;
+}
+
+static void stlc45xx_work(struct work_struct *work)
+{
+ struct stlc45xx *stlc = container_of(work, struct stlc45xx, work);
+ u32 ints;
+ int ret;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ if (stlc->fw_state == FW_STATE_OFF &&
+ stlc->fw_state == FW_STATE_RESET)
+ goto out;
+
+ ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+ stlc45xx_debug(DEBUG_BH, "begin host_ints 0x%08x", ints);
+
+ if (ints & SPI_HOST_INT_READY) {
+ stlc45xx_int_ready(stlc);
+ stlc45xx_int_ack(stlc, SPI_HOST_INT_READY);
+ }
+
+ if (stlc->fw_state != FW_STATE_READY)
+ goto out;
+
+ if (ints & SPI_HOST_INT_UPDATE) {
+ stlc45xx_int_ack(stlc, SPI_HOST_INT_UPDATE);
+ ret = stlc45xx_rx(stlc);
+ if (ret < 0) {
+ stlc45xx_reset(stlc);
+ goto out;
+ }
+ }
+ if (ints & SPI_HOST_INT_SW_UPDATE) {
+ stlc45xx_int_ack(stlc, SPI_HOST_INT_SW_UPDATE);
+ ret = stlc45xx_rx(stlc);
+ if (ret < 0) {
+ stlc45xx_reset(stlc);
+ goto out;
+ }
+ }
+
+ ret = stlc45xx_wq_tx(stlc);
+ if (ret < 0) {
+ stlc45xx_reset(stlc);
+ goto out;
+ }
+
+ ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+ stlc45xx_debug(DEBUG_BH, "end host_ints 0x%08x", ints);
+
+out:
+ mutex_unlock(&stlc->mutex);
+}
+
+static void stlc45xx_tx_edcf(struct stlc45xx *stlc)
+{
+ struct s_lm_control *control;
+ struct s_lmo_edcf *edcf;
+ size_t len, edcf_len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ edcf_len = sizeof(*edcf);
+ len = sizeof(*control) + edcf_len;
+ control = kzalloc(len, GFP_KERNEL);
+ edcf = (struct s_lmo_edcf *) (control + 1);
+
+ control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
+ control->length = edcf_len;
+ control->oid = LM_OID_EDCF;
+
+ edcf->slottime = 0x14;
+ edcf->sifs = 10;
+ edcf->eofpad = 6;
+ edcf->maxburst = 1500;
+
+ edcf->queues[0].aifs = 2;
+ edcf->queues[0].pad0 = 1;
+ edcf->queues[0].cwmin = 3;
+ edcf->queues[0].cwmax = 7;
+ edcf->queues[0].txop = 47;
+ edcf->queues[1].aifs = 2;
+ edcf->queues[1].pad0 = 0;
+ edcf->queues[1].cwmin = 7;
+ edcf->queues[1].cwmax = 15;
+ edcf->queues[1].txop = 94;
+ edcf->queues[2].aifs = 3;
+ edcf->queues[2].pad0 = 0;
+ edcf->queues[2].cwmin = 15;
+ edcf->queues[2].cwmax = 1023;
+ edcf->queues[2].txop = 0;
+ edcf->queues[3].aifs = 7;
+ edcf->queues[3].pad0 = 0;
+ edcf->queues[3].cwmin = 15;
+ edcf->queues[3].cwmax = 1023;
+ edcf->queues[3].txop = 0;
+ edcf->queues[4].aifs = 13;
+ edcf->queues[4].pad0 = 99;
+ edcf->queues[4].cwmin = 3437;
+ edcf->queues[4].cwmax = 512;
+ edcf->queues[4].txop = 12;
+ edcf->queues[5].aifs = 142;
+ edcf->queues[5].pad0 = 109;
+ edcf->queues[5].cwmin = 8756;
+ edcf->queues[5].cwmax = 6;
+ edcf->queues[5].txop = 0;
+ edcf->queues[6].aifs = 4;
+ edcf->queues[6].pad0 = 0;
+ edcf->queues[6].cwmin = 0;
+ edcf->queues[6].cwmax = 58705;
+ edcf->queues[6].txop = 25716;
+ edcf->queues[7].aifs = 0;
+ edcf->queues[7].pad0 = 0;
+ edcf->queues[7].cwmin = 0;
+ edcf->queues[7].cwmax = 0;
+ edcf->queues[7].txop = 0;
+
+ stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
+
+ kfree(control);
+}
+
+static void stlc45xx_tx_setup(struct stlc45xx *stlc)
+{
+ struct s_lm_control *control;
+ struct s_lmo_setup *setup;
+ size_t len, setup_len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ setup_len = sizeof(*setup);
+ len = sizeof(*control) + setup_len;
+ control = kzalloc(len, GFP_KERNEL);
+ setup = (struct s_lmo_setup *) (control + 1);
+
+ control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
+ control->length = setup_len;
+ control->oid = LM_OID_SETUP;
+
+ setup->flags = LM_SETUP_INFRA;
+ setup->antenna = 2;
+ setup->rx_align = 0;
+ setup->rx_buffer = FIRMWARE_RXBUFFER_START;
+ setup->rx_mtu = FIRMWARE_MTU;
+ setup->frontend = 5;
+ setup->timeout = 0;
+ setup->truncate = 48896;
+ setup->bratemask = 0xffffffff;
+ setup->ref_clock = 644245094;
+ setup->lpf_bandwidth = 65535;
+ setup->osc_start_delay = 65535;
+
+ memcpy(setup->macaddr, stlc->mac_addr, ETH_ALEN);
+ memcpy(setup->bssid, stlc->bssid, ETH_ALEN);
+
+ stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
+
+ kfree(control);
+}
+
+static void stlc45xx_tx_scan(struct stlc45xx *stlc)
+{
+ struct s_lm_control *control;
+ struct s_lmo_scan *scan;
+ size_t len, scan_len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ scan_len = sizeof(*scan);
+ len = sizeof(*control) + scan_len;
+ control = kzalloc(len, GFP_KERNEL);
+ scan = (struct s_lmo_scan *) (control + 1);
+
+ control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
+ control->length = scan_len;
+ control->oid = LM_OID_SCAN;
+
+ scan->flags = LM_SCAN_EXIT;
+ scan->bratemask = 0x15f;
+ scan->aloft[0] = 3;
+ scan->aloft[1] = 3;
+ scan->aloft[2] = 1;
+ scan->aloft[3] = 0;
+ scan->aloft[4] = 0;
+ scan->aloft[5] = 0;
+ scan->aloft[6] = 0;
+ scan->aloft[7] = 0;
+
+ memcpy(&scan->rssical, &stlc->cal_rssi[(stlc->channel - 1) *
+ RSSI_CAL_LEN],
+ RSSI_CAL_LEN);
+ memcpy(&scan->channel, &stlc->cal_channels[(stlc->channel - 1) *
+ CHANNEL_CAL_LEN],
+ CHANNEL_CAL_LEN);
+
+ stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
+
+ kfree(control);
+}
+
+/*
+ * caller must hold mutex
+ */
+static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave)
+{
+ struct ieee80211_hdr *pspoll;
+ int payload_len, padding, i;
+ struct s_lm_data_out *data;
+ struct txbuffer *entry;
+ DECLARE_MAC_BUF(mac);
+ struct sk_buff *skb;
+ char *payload;
+ u16 fc;
+
+ skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 16);
+ if (!skb) {
+ stlc45xx_warning("failed to allocate pspoll frame");
+ return -ENOMEM;
+ }
+ skb_reserve(skb, stlc->hw->extra_tx_headroom);
+
+ pspoll = (struct ieee80211_hdr *) skb_put(skb, 16);
+ memset(pspoll, 0, 16);
+ fc = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL;
+ if (powersave)
+ fc |= IEEE80211_FCTL_PM;
+ pspoll->frame_control = cpu_to_le16(fc);
+ pspoll->duration_id = cpu_to_le16(stlc->aid);
+
+ /* aid in PS-Poll has its two MSBs each set to 1 */
+ pspoll->duration_id |= cpu_to_le16(1 << 15) | cpu_to_le16(1 << 14);
+
+ memcpy(pspoll->addr1, stlc->bssid, ETH_ALEN);
+ memcpy(pspoll->addr2, stlc->mac_addr, ETH_ALEN);
+
+ stlc45xx_debug(DEBUG_PSM, "sending PS-Poll frame to %s (powersave %d, "
+ "fc 0x%x, aid %d)", print_mac(mac, pspoll->addr1),
+ powersave, fc, stlc->aid);
+
+ spin_lock_bh(&stlc->tx_lock);
+
+ entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
+
+ spin_unlock_bh(&stlc->tx_lock);
+
+ if (!entry) {
+ /*
+ * The queue should be stopped before the firmware buffer
+ * is full, so firmware buffer should always have enough
+ * space.
+ *
+ * But I'm too lazy and omit it for now.
+ */
+ if (net_ratelimit())
+ stlc45xx_warning("firmware tx buffer full is full "
+ "for null frame");
+ return -ENOSPC;
+ }
+
+ payload = skb->data;
+ payload_len = skb->len;
+ padding = (int) (skb->data - sizeof(*data)) & 3;
+ entry->header_len = sizeof(*data) + padding;
+
+ entry->skb = skb;
+ entry->status_needed = false;
+ entry->handle = (u32) skb;
+ entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
+
+ stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
+ "padding %d header_len %d)",
+ entry->handle, payload, payload_len, padding,
+ entry->header_len);
+ stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
+
+ data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
+
+ memset(data, 0, entry->header_len);
+
+ if (padding)
+ data->flags = LM_FLAG_ALIGN;
+
+ data->flags = LM_OUT_BURST;
+ data->length = payload_len;
+ data->handle = entry->handle;
+ data->aid = 1;
+ data->rts_retries = 7;
+ data->retries = 7;
+ data->aloft_ctrl = 0;
+ data->crypt_offset = 58;
+ data->keytype = 0;
+ data->keylen = 0;
+ data->queue = LM_QUEUE_DATA3;
+ data->backlog = 32;
+ data->antenna = 2;
+ data->cts = 3;
+ data->power = 127;
+
+ for (i = 0; i < 8; i++)
+ data->aloft[i] = 0;
+
+ /*
+ * check if there's enough space in tx buffer
+ *
+ * FIXME: ignored for now
+ */
+
+ stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len);
+
+ list_add(&entry->tx_list, &stlc->tx_sent);
+
+ return 0;
+}
+
+/*
+ * caller must hold mutex
+ *
+ * shamelessly stolen from mac80211/ieee80211_send_nullfunc
+ */
+static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave)
+{
+ struct ieee80211_hdr *nullfunc;
+ int payload_len, padding, i;
+ struct s_lm_data_out *data;
+ struct txbuffer *entry;
+ DECLARE_MAC_BUF(mac);
+ struct sk_buff *skb;
+ char *payload;
+ u16 fc;
+
+ skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 24);
+ if (!skb) {
+ stlc45xx_warning("failed to allocate buffer for null frame\n");
+ return -ENOMEM;
+ }
+ skb_reserve(skb, stlc->hw->extra_tx_headroom);
+
+ nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
+ memset(nullfunc, 0, 24);
+ fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
+ IEEE80211_FCTL_TODS;
+
+ if (powersave)
+ fc |= IEEE80211_FCTL_PM;
+
+ nullfunc->frame_control = cpu_to_le16(fc);
+ memcpy(nullfunc->addr1, stlc->bssid, ETH_ALEN);
+ memcpy(nullfunc->addr2, stlc->mac_addr, ETH_ALEN);
+ memcpy(nullfunc->addr3, stlc->bssid, ETH_ALEN);
+
+ stlc45xx_debug(DEBUG_PSM, "sending Null frame to %s (powersave %d, "
+ "fc 0x%x)",
+ print_mac(mac, nullfunc->addr1), powersave, fc);
+
+ spin_lock_bh(&stlc->tx_lock);
+
+ entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
+
+ spin_unlock_bh(&stlc->tx_lock);
+
+ if (!entry) {
+ /*
+ * The queue should be stopped before the firmware buffer
+ * is full, so firmware buffer should always have enough
+ * space.
+ *
+ * But I'm too lazy and omit it for now.
+ */
+ if (net_ratelimit())
+ stlc45xx_warning("firmware tx buffer full is full "
+ "for null frame");
+ return -ENOSPC;
+ }
+
+ payload = skb->data;
+ payload_len = skb->len;
+ padding = (int) (skb->data - sizeof(*data)) & 3;
+ entry->header_len = sizeof(*data) + padding;
+
+ entry->skb = skb;
+ entry->status_needed = false;
+ entry->handle = (u32) skb;
+ entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
+
+ stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
+ "padding %d header_len %d)",
+ entry->handle, payload, payload_len, padding,
+ entry->header_len);
+ stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
+
+ data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
+
+ memset(data, 0, entry->header_len);
+
+ if (padding)
+ data->flags = LM_FLAG_ALIGN;
+
+ data->flags = LM_OUT_BURST;
+ data->length = payload_len;
+ data->handle = entry->handle;
+ data->aid = 1;
+ data->rts_retries = 7;
+ data->retries = 7;
+ data->aloft_ctrl = 0;
+ data->crypt_offset = 58;
+ data->keytype = 0;
+ data->keylen = 0;
+ data->queue = LM_QUEUE_DATA3;
+ data->backlog = 32;
+ data->antenna = 2;
+ data->cts = 3;
+ data->power = 127;
+
+ for (i = 0; i < 8; i++)
+ data->aloft[i] = 0;
+
+ /*
+ * check if there's enough space in tx buffer
+ *
+ * FIXME: ignored for now
+ */
+
+ stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len);
+
+ list_add(&entry->tx_list, &stlc->tx_sent);
+
+ return 0;
+}
+
+/* caller must hold mutex */
+static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable)
+{
+ struct s_lm_control *control;
+ struct s_lmo_psm *psm;
+ size_t len, psm_len;
+
+ WARN_ON(!stlc->associated);
+ WARN_ON(stlc->aid < 1);
+ WARN_ON(stlc->aid > 2007);
+
+ psm_len = sizeof(*psm);
+ len = sizeof(*control) + psm_len;
+ control = kzalloc(len, GFP_KERNEL);
+ psm = (struct s_lmo_psm *) (control + 1);
+
+ control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
+ control->length = psm_len;
+ control->oid = LM_OID_PSM;
+
+ if (enable)
+ psm->flags |= LM_PSM;
+
+ psm->aid = stlc->aid;
+
+ psm->beacon_rcpi_skip_max = 60;
+
+ psm->intervals[0].interval = 1;
+ psm->intervals[0].periods = 1;
+ psm->intervals[1].interval = 1;
+ psm->intervals[1].periods = 1;
+ psm->intervals[2].interval = 1;
+ psm->intervals[2].periods = 1;
+ psm->intervals[3].interval = 1;
+ psm->intervals[3].periods = 1;
+
+ psm->nr = 0;
+ psm->exclude[0] = 0;
+
+ stlc45xx_debug(DEBUG_PSM, "sending LM_OID_PSM (aid %d, interval %d)",
+ psm->aid, psm->intervals[0].interval);
+
+ stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
+
+ kfree(control);
+}
+
+static int stlc45xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct stlc45xx *stlc = hw->priv;
+ struct ieee80211_tx_info *info;
+ struct ieee80211_rate *rate;
+ int payload_len, padding, i;
+ struct s_lm_data_out *data;
+ struct txbuffer *entry;
+ char *payload;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ spin_lock_bh(&stlc->tx_lock);
+
+ entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
+ if (!entry) {
+ /* the queue should be stopped before the firmware buffer
+ * is full, so firmware buffer should always have enough
+ * space */
+ if (net_ratelimit())
+ stlc45xx_warning("firmware buffer full");
+ spin_unlock_bh(&stlc->tx_lock);
+ return NETDEV_TX_BUSY;
+ }
+
+ info = IEEE80211_SKB_CB(skb);
+
+ payload = skb->data;
+ payload_len = skb->len;
+ padding = (int) (skb->data - sizeof(*data)) & 3;
+ entry->header_len = sizeof(*data) + padding;
+
+ entry->skb = skb;
+ entry->status_needed = true;
+ entry->handle = (u32) skb;
+ entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
+
+ stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
+ "padding %d header_len %d)",
+ entry->handle, payload, payload_len, padding,
+ entry->header_len);
+ stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
+
+ data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
+
+ memset(data, 0, entry->header_len);
+
+ if (padding)
+ data->flags = LM_FLAG_ALIGN;
+
+ data->flags = LM_OUT_BURST;
+ data->length = payload_len;
+ data->handle = entry->handle;
+ data->aid = 1;
+ data->rts_retries = 7;
+ data->retries = 7;
+ data->aloft_ctrl = 0;
+ data->crypt_offset = 58;
+ data->keytype = 0;
+ data->keylen = 0;
+ data->queue = 2;
+ data->backlog = 32;
+ data->antenna = 2;
+ data->cts = 3;
+ data->power = 127;
+
+ for (i = 0; i < 8; i++) {
+ rate = ieee80211_get_tx_rate(stlc->hw, info);
+ data->aloft[i] = rate->hw_value;
+ }
+
+ list_add_tail(&entry->tx_list, &stlc->tx_pending);
+
+ /* check if there's enough space in tx buffer */
+ if (stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) == -1) {
+ stlc45xx_debug(DEBUG_QUEUE, "tx buffer full, stopping queues");
+ stlc->tx_queue_stopped = 1;
+ ieee80211_stop_queues(stlc->hw);
+ }
+
+ queue_work(stlc->hw->workqueue, &stlc->work);
+
+ spin_unlock_bh(&stlc->tx_lock);
+
+ return NETDEV_TX_OK;
+}
+
+static int stlc45xx_op_start(struct ieee80211_hw *hw)
+{
+ struct stlc45xx *stlc = hw->priv;
+ unsigned long timeout;
+ int ret = 0;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ stlc->fw_state = FW_STATE_BOOTING;
+ stlc->channel = 1;
+
+ stlc45xx_power_on(stlc);
+
+ ret = stlc45xx_upload_firmware(stlc);
+ if (ret < 0) {
+ stlc45xx_power_off(stlc);
+ goto out_unlock;
+ }
+
+ stlc->tx_queue_stopped = 0;
+
+ mutex_unlock(&stlc->mutex);
+
+ timeout = msecs_to_jiffies(2000);
+ timeout = wait_for_completion_interruptible_timeout(&stlc->fw_comp,
+ timeout);
+ if (!timeout) {
+ stlc45xx_error("firmware boot failed");
+ stlc45xx_power_off(stlc);
+ ret = -1;
+ goto out;
+ }
+
+ stlc45xx_debug(DEBUG_BOOT, "firmware booted");
+
+ /* FIXME: should we take mutex just after wait_for_completion()? */
+ mutex_lock(&stlc->mutex);
+
+ WARN_ON(stlc->fw_state != FW_STATE_READY);
+
+out_unlock:
+ mutex_unlock(&stlc->mutex);
+
+out:
+ return ret;
+}
+
+static void stlc45xx_op_stop(struct ieee80211_hw *hw)
+{
+ struct stlc45xx *stlc = hw->priv;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ WARN_ON(stlc->fw_state != FW_STATE_READY);
+
+ stlc45xx_power_off(stlc);
+
+ /* FIXME: make sure that all work_structs have completed */
+
+ spin_lock_bh(&stlc->tx_lock);
+ stlc45xx_flush_queues(stlc);
+ spin_unlock_bh(&stlc->tx_lock);
+
+ stlc->fw_state = FW_STATE_OFF;
+
+ mutex_unlock(&stlc->mutex);
+}
+
+static int stlc45xx_op_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct stlc45xx *stlc = hw->priv;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ switch (conf->type) {
+ case NL80211_IFTYPE_STATION:
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ memcpy(stlc->mac_addr, conf->mac_addr, ETH_ALEN);
+
+ return 0;
+}
+
+static void stlc45xx_op_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+}
+
+static int stlc45xx_op_config_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_if_conf *conf)
+{
+ struct stlc45xx *stlc = hw->priv;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ memcpy(stlc->bssid, conf->bssid, ETH_ALEN);
+ stlc45xx_tx_setup(stlc);
+
+ mutex_unlock(&stlc->mutex);
+
+ return 0;
+}
+
+static int stlc45xx_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct stlc45xx *stlc = hw->priv;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ stlc->channel = hw->conf.channel->hw_value;
+ stlc45xx_tx_scan(stlc);
+ stlc45xx_tx_setup(stlc);
+ stlc45xx_tx_edcf(stlc);
+
+ if ((hw->conf.flags & IEEE80211_CONF_PS) != stlc->psm) {
+ stlc->psm = hw->conf.flags & IEEE80211_CONF_PS;
+ if (stlc->associated) {
+ stlc45xx_tx_psm(stlc, stlc->psm);
+ stlc45xx_tx_nullfunc(stlc, stlc->psm);
+ }
+ }
+
+ mutex_unlock(&stlc->mutex);
+
+ return 0;
+}
+
+static void stlc45xx_op_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count,
+ struct dev_addr_list *mc_list)
+{
+ *total_flags = 0;
+}
+
+static void stlc45xx_op_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u32 changed)
+{
+ struct stlc45xx *stlc = hw->priv;
+
+ if (changed & BSS_CHANGED_ASSOC) {
+ stlc->associated = info->assoc;
+ if (info->assoc)
+ stlc->aid = info->aid;
+ else
+ stlc->aid = -1;
+
+ if (stlc->psm) {
+ stlc45xx_tx_psm(stlc, stlc->psm);
+ stlc45xx_tx_nullfunc(stlc, stlc->psm);
+ }
+ }
+}
+
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_rate stlc45xx_rates[] = {
+ { .bitrate = 10, .hw_value = 0, .hw_value_short = 0, },
+ { .bitrate = 20, .hw_value = 1, .hw_value_short = 1, },
+ { .bitrate = 55, .hw_value = 2, .hw_value_short = 2, },
+ { .bitrate = 110, .hw_value = 3, .hw_value_short = 3, },
+ { .bitrate = 60, .hw_value = 4, .hw_value_short = 4, },
+ { .bitrate = 90, .hw_value = 5, .hw_value_short = 5, },
+ { .bitrate = 120, .hw_value = 6, .hw_value_short = 6, },
+ { .bitrate = 180, .hw_value = 7, .hw_value_short = 7, },
+ { .bitrate = 240, .hw_value = 8, .hw_value_short = 8, },
+ { .bitrate = 360, .hw_value = 9, .hw_value_short = 9, },
+ { .bitrate = 480, .hw_value = 10, .hw_value_short = 10, },
+ { .bitrate = 540, .hw_value = 11, .hw_value_short = 11, },
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_channel stlc45xx_channels[] = {
+ { .hw_value = 1, .center_freq = 2412},
+ { .hw_value = 2, .center_freq = 2417},
+ { .hw_value = 3, .center_freq = 2422},
+ { .hw_value = 4, .center_freq = 2427},
+ { .hw_value = 5, .center_freq = 2432},
+ { .hw_value = 6, .center_freq = 2437},
+ { .hw_value = 7, .center_freq = 2442},
+ { .hw_value = 8, .center_freq = 2447},
+ { .hw_value = 9, .center_freq = 2452},
+ { .hw_value = 10, .center_freq = 2457},
+ { .hw_value = 11, .center_freq = 2462},
+ { .hw_value = 12, .center_freq = 2467},
+ { .hw_value = 13, .center_freq = 2472},
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_supported_band stlc45xx_band_2ghz = {
+ .channels = stlc45xx_channels,
+ .n_channels = ARRAY_SIZE(stlc45xx_channels),
+ .bitrates = stlc45xx_rates,
+ .n_bitrates = ARRAY_SIZE(stlc45xx_rates),
+};
+
+static const struct ieee80211_ops stlc45xx_ops = {
+ .start = stlc45xx_op_start,
+ .stop = stlc45xx_op_stop,
+ .add_interface = stlc45xx_op_add_interface,
+ .remove_interface = stlc45xx_op_remove_interface,
+ .config = stlc45xx_op_config,
+ .config_interface = stlc45xx_op_config_interface,
+ .configure_filter = stlc45xx_op_configure_filter,
+ .tx = stlc45xx_op_tx,
+ .bss_info_changed = stlc45xx_op_bss_info_changed,
+};
+
+static int stlc45xx_register_mac80211(struct stlc45xx *stlc)
+{
+ /* FIXME: SET_IEEE80211_PERM_ADDR() requires default_mac_addr
+ to be non-const for some strange reason */
+ static u8 default_mac_addr[ETH_ALEN] = {
+ 0x00, 0x02, 0xee, 0xc0, 0xff, 0xee
+ };
+ int ret;
+
+ SET_IEEE80211_PERM_ADDR(stlc->hw, default_mac_addr);
+
+ ret = ieee80211_register_hw(stlc->hw);
+ if (ret) {
+ stlc45xx_error("unable to register mac80211 hw: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void stlc45xx_device_release(struct device *dev)
+{
+
+}
+
+static struct platform_device stlc45xx_device = {
+ .name = "stlc45xx",
+ .id = -1,
+
+ /* device model insists to have a release function */
+ .dev = {
+ .release = stlc45xx_device_release,
+ },
+};
+
+static int __devinit stlc45xx_probe(struct spi_device *spi)
+{
+ struct stlc45xx *stlc;
+ struct ieee80211_hw *hw;
+ int ret;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ /* mac80211 alloc */
+ hw = ieee80211_alloc_hw(sizeof(*stlc), &stlc45xx_ops);
+ if (!hw) {
+ stlc45xx_error("could not alloc ieee80211_hw");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* mac80211 clears hw->priv */
+ stlc = hw->priv;
+
+ stlc->hw = hw;
+ dev_set_drvdata(&spi->dev, stlc);
+ stlc->spi = spi;
+
+ spi->bits_per_word = 16;
+ spi->max_speed_hz = 24000000;
+
+ ret = spi_setup(spi);
+ if (ret < 0)
+ stlc45xx_error("spi_setup failed");
+
+ ret = gpio_request(stlc45xx_gpio_power, "stlc45xx power");
+ if (ret < 0) {
+ stlc45xx_error("power GPIO request failed: %d", ret);
+ return ret;
+ }
+
+ ret = gpio_request(stlc45xx_gpio_irq, "stlc45xx irq");
+ if (ret < 0) {
+ stlc45xx_error("irq GPIO request failed: %d", ret);
+ goto out;
+ }
+
+ gpio_direction_output(stlc45xx_gpio_power, 0);
+ gpio_direction_input(stlc45xx_gpio_irq);
+
+ ret = request_irq(gpio_to_irq(stlc45xx_gpio_irq),
+ stlc45xx_interrupt, IRQF_DISABLED, "stlc45xx",
+ stlc->spi);
+ if (ret < 0)
+ /* FIXME: handle the error */
+ stlc45xx_error("request_irq() failed");
+
+ set_irq_type(gpio_to_irq(stlc45xx_gpio_irq),
+ IRQ_TYPE_EDGE_RISING);
+
+ disable_irq(gpio_to_irq(stlc45xx_gpio_irq));
+
+ ret = platform_device_register(&stlc45xx_device);
+ if (ret) {
+ stlc45xx_error("Couldn't register wlan_omap device.");
+ return ret;
+ }
+ dev_set_drvdata(&stlc45xx_device.dev, stlc);
+
+ INIT_WORK(&stlc->work, stlc45xx_work);
+ INIT_WORK(&stlc->work_reset, stlc45xx_work_reset);
+ INIT_DELAYED_WORK(&stlc->work_tx_timeout, stlc45xx_work_tx_timeout);
+ mutex_init(&stlc->mutex);
+ init_completion(&stlc->fw_comp);
+ spin_lock_init(&stlc->tx_lock);
+ INIT_LIST_HEAD(&stlc->txbuffer);
+ INIT_LIST_HEAD(&stlc->tx_pending);
+ INIT_LIST_HEAD(&stlc->tx_sent);
+
+ hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_NOISE_DBM;
+ /* four bytes for padding */
+ hw->extra_tx_headroom = sizeof(struct s_lm_data_out) + 4;
+
+ /* unit us */
+ hw->channel_change_time = 1000;
+
+ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &stlc45xx_band_2ghz;
+
+ SET_IEEE80211_DEV(hw, &spi->dev);
+
+ BUILD_BUG_ON(sizeof(default_cal_rssi) != RSSI_CAL_ARRAY_LEN);
+ BUILD_BUG_ON(sizeof(default_cal_channels) != CHANNEL_CAL_ARRAY_LEN);
+
+ stlc->cal_rssi = kmemdup(default_cal_rssi, RSSI_CAL_ARRAY_LEN,
+ GFP_KERNEL);
+ stlc->cal_channels = kmemdup(default_cal_channels,
+ CHANNEL_CAL_ARRAY_LEN,
+ GFP_KERNEL);
+
+ ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_rssi);
+ if (ret < 0) {
+ stlc45xx_error("failed to create sysfs file cal_rssi");
+ goto out;
+ }
+
+ ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_channels);
+ if (ret < 0) {
+ stlc45xx_error("failed to create sysfs file cal_channels");
+ goto out;
+ }
+
+ ret = device_create_file(&stlc45xx_device.dev, &dev_attr_tx_buf);
+ if (ret < 0) {
+ stlc45xx_error("failed to create sysfs file tx_buf");
+ goto out;
+ }
+
+ ret = stlc45xx_register_mac80211(stlc);
+ if (ret < 0)
+ goto out;
+
+ stlc45xx_info("v" DRIVER_VERSION " loaded");
+
+ stlc45xx_info("config buffer 0x%x-0x%x",
+ FIRMWARE_CONFIG_START, FIRMWARE_CONFIG_END);
+ stlc45xx_info("tx 0x%x-0x%x, rx 0x%x-0x%x",
+ FIRMWARE_TXBUFFER_START, FIRMWARE_TXBUFFER_END,
+ FIRMWARE_RXBUFFER_START, FIRMWARE_RXBUFFER_END);
+
+out:
+ return ret;
+}
+
+static int __devexit stlc45xx_remove(struct spi_device *spi)
+{
+ struct stlc45xx *stlc = dev_get_drvdata(&spi->dev);
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ platform_device_unregister(&stlc45xx_device);
+
+ ieee80211_unregister_hw(stlc->hw);
+
+ free_irq(gpio_to_irq(stlc45xx_gpio_irq), spi);
+
+ gpio_free(stlc45xx_gpio_power);
+ gpio_free(stlc45xx_gpio_irq);
+
+ /* FIXME: free cal_channels and cal_rssi? */
+
+ kfree(stlc->fw);
+
+ mutex_destroy(&stlc->mutex);
+
+ /* frees also stlc */
+ ieee80211_free_hw(stlc->hw);
+ stlc = NULL;
+
+ return 0;
+}
+
+
+static struct spi_driver stlc45xx_spi_driver = {
+ .driver = {
+ /* use cx3110x name because board-n800.c uses that for the
+ * SPI port */
+ .name = "cx3110x",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = stlc45xx_probe,
+ .remove = __devexit_p(stlc45xx_remove),
+};
+
+static int __init stlc45xx_init(void)
+{
+ int ret;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ ret = spi_register_driver(&stlc45xx_spi_driver);
+ if (ret < 0) {
+ stlc45xx_error("failed to register SPI driver: %d", ret);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void __exit stlc45xx_exit(void)
+{
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ spi_unregister_driver(&stlc45xx_spi_driver);
+
+ stlc45xx_info("unloaded");
+}
+
+module_init(stlc45xx_init);
+module_exit(stlc45xx_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
diff --git a/drivers/staging/stlc45xx/stlc45xx.h b/drivers/staging/stlc45xx/stlc45xx.h
new file mode 100644
index 00000000000..ac96bbbde79
--- /dev/null
+++ b/drivers/staging/stlc45xx/stlc45xx.h
@@ -0,0 +1,283 @@
+/*
+ * This file is part of stlc45xx
+ *
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <net/mac80211.h>
+
+#include "stlc45xx_lmac.h"
+
+#define DRIVER_NAME "stlc45xx"
+#define DRIVER_VERSION "0.1.3"
+
+#define DRIVER_PREFIX DRIVER_NAME ": "
+
+enum {
+ DEBUG_NONE = 0,
+ DEBUG_FUNC = 1 << 0,
+ DEBUG_IRQ = 1 << 1,
+ DEBUG_BH = 1 << 2,
+ DEBUG_RX = 1 << 3,
+ DEBUG_RX_CONTENT = 1 << 5,
+ DEBUG_TX = 1 << 6,
+ DEBUG_TX_CONTENT = 1 << 8,
+ DEBUG_TXBUFFER = 1 << 9,
+ DEBUG_QUEUE = 1 << 10,
+ DEBUG_BOOT = 1 << 11,
+ DEBUG_PSM = 1 << 12,
+ DEBUG_ALL = ~0,
+};
+
+#define DEBUG_LEVEL DEBUG_NONE
+/* #define DEBUG_LEVEL DEBUG_ALL */
+/* #define DEBUG_LEVEL (DEBUG_TX | DEBUG_RX | DEBUG_IRQ) */
+/* #define DEBUG_LEVEL (DEBUG_TX | DEBUG_MEMREGION | DEBUG_QUEUE) */
+/* #define DEBUG_LEVEL (DEBUG_MEMREGION | DEBUG_QUEUE) */
+
+#define stlc45xx_error(fmt, arg...) \
+ printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
+
+#define stlc45xx_warning(fmt, arg...) \
+ printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
+
+#define stlc45xx_info(fmt, arg...) \
+ printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
+
+#define stlc45xx_debug(level, fmt, arg...) \
+ do { \
+ if (level & DEBUG_LEVEL) \
+ printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
+ } while (0)
+
+#define stlc45xx_dump(level, buf, len) \
+ do { \
+ if (level & DEBUG_LEVEL) \
+ print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, \
+ 16, 1, buf, len, 1); \
+ } while (0)
+
+#define MAC2STR(a) ((a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5])
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+
+/* Bit 15 is read/write bit; ON = READ, OFF = WRITE */
+#define ADDR_READ_BIT_15 0x8000
+
+#define SPI_ADRS_ARM_INTERRUPTS 0x00
+#define SPI_ADRS_ARM_INT_EN 0x04
+
+#define SPI_ADRS_HOST_INTERRUPTS 0x08
+#define SPI_ADRS_HOST_INT_EN 0x0c
+#define SPI_ADRS_HOST_INT_ACK 0x10
+
+#define SPI_ADRS_GEN_PURP_1 0x14
+#define SPI_ADRS_GEN_PURP_2 0x18
+
+/* high word */
+#define SPI_ADRS_DEV_CTRL_STAT 0x26
+
+#define SPI_ADRS_DMA_DATA 0x28
+
+#define SPI_ADRS_DMA_WRITE_CTRL 0x2c
+#define SPI_ADRS_DMA_WRITE_LEN 0x2e
+#define SPI_ADRS_DMA_WRITE_BASE 0x30
+
+#define SPI_ADRS_DMA_READ_CTRL 0x34
+#define SPI_ADRS_DMA_READ_LEN 0x36
+#define SPI_ADRS_DMA_READ_BASE 0x38
+
+#define SPI_CTRL_STAT_HOST_OVERRIDE 0x8000
+#define SPI_CTRL_STAT_START_HALTED 0x4000
+#define SPI_CTRL_STAT_RAM_BOOT 0x2000
+#define SPI_CTRL_STAT_HOST_RESET 0x1000
+#define SPI_CTRL_STAT_HOST_CPU_EN 0x0800
+
+#define SPI_DMA_WRITE_CTRL_ENABLE 0x0001
+#define SPI_DMA_READ_CTRL_ENABLE 0x0001
+#define HOST_ALLOWED (1 << 7)
+
+#define FIRMWARE_ADDRESS 0x20000
+
+#define SPI_TIMEOUT 100 /* msec */
+
+#define SPI_MAX_TX_PACKETS 32
+
+#define SPI_MAX_PACKET_SIZE 32767
+
+#define SPI_TARGET_INT_WAKEUP 0x00000001
+#define SPI_TARGET_INT_SLEEP 0x00000002
+#define SPI_TARGET_INT_RDDONE 0x00000004
+
+#define SPI_TARGET_INT_CTS 0x00004000
+#define SPI_TARGET_INT_DR 0x00008000
+
+#define SPI_HOST_INT_READY 0x00000001
+#define SPI_HOST_INT_WR_READY 0x00000002
+#define SPI_HOST_INT_SW_UPDATE 0x00000004
+#define SPI_HOST_INT_UPDATE 0x10000000
+
+/* clear to send */
+#define SPI_HOST_INT_CTS 0x00004000
+
+/* data ready */
+#define SPI_HOST_INT_DR 0x00008000
+
+#define SPI_HOST_INTS_DEFAULT \
+ (SPI_HOST_INT_READY | SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE)
+
+#define TARGET_BOOT_SLEEP 50
+
+/* The firmware buffer is divided into three areas:
+ *
+ * o config area (for control commands)
+ * o tx buffer
+ * o rx buffer
+ */
+#define FIRMWARE_BUFFER_START 0x20200
+#define FIRMWARE_BUFFER_END 0x27c60
+#define FIRMWARE_BUFFER_LEN (FIRMWARE_BUFFER_END - FIRMWARE_BUFFER_START)
+#define FIRMWARE_MTU 3240
+#define FIRMWARE_CONFIG_PAYLOAD_LEN 1024
+#define FIRMWARE_CONFIG_START FIRMWARE_BUFFER_START
+#define FIRMWARE_CONFIG_LEN (sizeof(struct s_lm_control) + \
+ FIRMWARE_CONFIG_PAYLOAD_LEN)
+#define FIRMWARE_CONFIG_END (FIRMWARE_CONFIG_START + FIRMWARE_CONFIG_LEN - 1)
+#define FIRMWARE_RXBUFFER_LEN (5 * FIRMWARE_MTU + 1024)
+#define FIRMWARE_RXBUFFER_START (FIRMWARE_BUFFER_END - FIRMWARE_RXBUFFER_LEN)
+#define FIRMWARE_RXBUFFER_END (FIRMWARE_RXBUFFER_START + \
+ FIRMWARE_RXBUFFER_LEN - 1)
+#define FIRMWARE_TXBUFFER_START (FIRMWARE_BUFFER_START + FIRMWARE_CONFIG_LEN)
+#define FIRMWARE_TXBUFFER_LEN (FIRMWARE_BUFFER_LEN - FIRMWARE_CONFIG_LEN - \
+ FIRMWARE_RXBUFFER_LEN)
+#define FIRMWARE_TXBUFFER_END (FIRMWARE_TXBUFFER_START + \
+ FIRMWARE_TXBUFFER_LEN - 1)
+
+#define FIRMWARE_TXBUFFER_HEADER 100
+#define FIRMWARE_TXBUFFER_TRAILER 4
+
+/* FIXME: come up with a proper value */
+#define MAX_FRAME_LEN 2500
+
+/* unit is ms */
+#define TX_FRAME_LIFETIME 2000
+#define TX_TIMEOUT 4000
+
+#define SUPPORTED_CHANNELS 13
+
+/* FIXME */
+/* #define CHANNEL_CAL_LEN offsetof(struct s_lmo_scan, bratemask) - \ */
+/* offsetof(struct s_lmo_scan, channel) */
+#define CHANNEL_CAL_LEN 292
+#define CHANNEL_CAL_ARRAY_LEN (SUPPORTED_CHANNELS * CHANNEL_CAL_LEN)
+/* FIXME */
+/* #define RSSI_CAL_LEN sizeof(struct s_lmo_scan) - \ */
+/* offsetof(struct s_lmo_scan, rssical) */
+#define RSSI_CAL_LEN 8
+#define RSSI_CAL_ARRAY_LEN (SUPPORTED_CHANNELS * RSSI_CAL_LEN)
+
+struct s_dma_regs {
+ unsigned short cmd;
+ unsigned short len;
+ unsigned long addr;
+};
+
+struct stlc45xx_ie_tim {
+ u8 dtim_count;
+ u8 dtim_period;
+ u8 bmap_control;
+ u8 pvbmap[251];
+};
+
+struct txbuffer {
+ /* can be removed when switched to skb queue */
+ struct list_head tx_list;
+
+ struct list_head buffer_list;
+
+ int start;
+ int frame_start;
+ int end;
+
+ struct sk_buff *skb;
+ u32 handle;
+
+ bool status_needed;
+
+ int header_len;
+
+ /* unit jiffies */
+ unsigned long lifetime;
+};
+
+enum fw_state {
+ FW_STATE_OFF,
+ FW_STATE_BOOTING,
+ FW_STATE_READY,
+ FW_STATE_RESET,
+ FW_STATE_RESETTING,
+};
+
+struct stlc45xx {
+ struct ieee80211_hw *hw;
+ struct spi_device *spi;
+ struct work_struct work;
+ struct work_struct work_reset;
+ struct delayed_work work_tx_timeout;
+ struct mutex mutex;
+ struct completion fw_comp;
+
+
+ u8 bssid[ETH_ALEN];
+ u8 mac_addr[ETH_ALEN];
+ int channel;
+
+ u8 *cal_rssi;
+ u8 *cal_channels;
+
+ enum fw_state fw_state;
+
+ spinlock_t tx_lock;
+
+ /* protected by tx_lock */
+ struct list_head txbuffer;
+
+ /* protected by tx_lock */
+ struct list_head tx_pending;
+
+ /* protected by tx_lock */
+ int tx_queue_stopped;
+
+ /* protected by mutex */
+ struct list_head tx_sent;
+
+ int tx_frames;
+
+ u8 *fw;
+ int fw_len;
+
+ bool psm;
+ bool associated;
+ int aid;
+ bool pspolling;
+};
+
+
diff --git a/drivers/staging/stlc45xx/stlc45xx_lmac.h b/drivers/staging/stlc45xx/stlc45xx_lmac.h
new file mode 100644
index 00000000000..af5db801347
--- /dev/null
+++ b/drivers/staging/stlc45xx/stlc45xx_lmac.h
@@ -0,0 +1,434 @@
+/************************************************************************
+* This is the LMAC API interface header file for STLC4560. *
+* Copyright (C) 2007 Conexant Systems, Inc. *
+* This program is free software; you can redistribute it and/or *
+* modify it under the terms of the GNU General Public License *
+* as published by the Free Software Foundation; either version 2 *
+* of the License, or (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program. If not, see <http://www.gnu.org/licenses/>.*
+*************************************************************************/
+
+#ifndef __lmac_h__
+#define __lmac_h__
+
+#define LM_TOP_VARIANT 0x0506
+#define LM_BOTTOM_VARIANT 0x0506
+
+/*
+ * LMAC - UMAC interface definition:
+ */
+
+#define LM_FLAG_CONTROL 0x8000
+#define LM_FLAG_ALIGN 0x4000
+
+#define LM_CTRL_OPSET 0x0001
+
+#define LM_OUT_PROMISC 0x0001
+#define LM_OUT_TIMESTAMP 0x0002
+#define LM_OUT_SEQNR 0x0004
+#define LM_OUT_BURST 0x0010
+#define LM_OUT_NOCANCEL 0x0020
+#define LM_OUT_CLEARTIM 0x0040
+#define LM_OUT_HITCHHIKE 0x0080
+#define LM_OUT_COMPRESS 0x0100
+#define LM_OUT_CONCAT 0x0200
+#define LM_OUT_PCS_ACCEPT 0x0400
+#define LM_OUT_WAITEOSP 0x0800
+
+
+#define LM_ALOFT_SP 0x10
+#define LM_ALOFT_CTS 0x20
+#define LM_ALOFT_RTS 0x40
+#define LM_ALOFT_MASK 0x1f
+#define LM_ALOFT_RATE 0x0f
+
+#define LM_IN_FCS_GOOD 0x0001
+#define LM_IN_MATCH_MAC 0x0002
+#define LM_IN_MCBC 0x0004
+#define LM_IN_BEACON 0x0008
+#define LM_IN_MATCH_BSS 0x0010
+#define LM_IN_BCAST_BSS 0x0020
+#define LM_IN_DATA 0x0040
+#define LM_IN_TRUNCATED 0x0080
+
+#define LM_IN_TRANSPARENT 0x0200
+
+#define LM_QUEUE_BEACON 0
+#define LM_QUEUE_SCAN 1
+#define LM_QUEUE_MGT 2
+#define LM_QUEUE_MCBC 3
+#define LM_QUEUE_DATA 4
+#define LM_QUEUE_DATA0 4
+#define LM_QUEUE_DATA1 5
+#define LM_QUEUE_DATA2 6
+#define LM_QUEUE_DATA3 7
+
+#define LM_SETUP_INFRA 0x0001
+#define LM_SETUP_IBSS 0x0002
+#define LM_SETUP_TRANSPARENT 0x0008
+#define LM_SETUP_PROMISCUOUS 0x0010
+#define LM_SETUP_HIBERNATE 0x0020
+#define LM_SETUP_NOACK 0x0040
+#define LM_SETUP_RX_DISABLED 0x0080
+
+#define LM_ANTENNA_0 0
+#define LM_ANTENNA_1 1
+#define LM_ANTENNA_DIVERSITY 2
+
+#define LM_TX_FAILED 0x0001
+#define LM_TX_PSM 0x0002
+#define LM_TX_PSM_CANCELLED 0x0004
+
+#define LM_SCAN_EXIT 0x0001
+#define LM_SCAN_TRAP 0x0002
+#define LM_SCAN_ACTIVE 0x0004
+#define LM_SCAN_FILTER 0x0008
+
+#define LM_PSM 0x0001
+#define LM_PSM_DTIM 0x0002
+#define LM_PSM_MCBC 0x0004
+#define LM_PSM_CHECKSUM 0x0008
+#define LM_PSM_SKIP_MORE_DATA 0x0010
+#define LM_PSM_BEACON_TIMEOUT 0x0020
+#define LM_PSM_HFOSLEEP 0x0040
+#define LM_PSM_AUTOSWITCH_SLEEP 0x0080
+#define LM_PSM_LPIT 0x0100
+#define LM_PSM_BF_UCAST_SKIP 0x0200
+#define LM_PSM_BF_MCAST_SKIP 0x0400
+
+/* hfosleep */
+#define LM_PSM_SLEEP_OPTION_MASK (LM_PSM_AUTOSWITCH_SLEEP | LM_PSM_HFOSLEEP)
+#define LM_PSM_SLEEP_OPTION_SHIFT 6
+/* hfosleepend */
+#define LM_PSM_BF_OPTION_MASK (LM_PSM_BF_MCAST_SKIP | LM_PSM_BF_UCAST_SKIP)
+#define LM_PSM_BF_OPTION_SHIFT 9
+
+
+#define LM_PRIVACC_WEP 0x01
+#define LM_PRIVACC_TKIP 0x02
+#define LM_PRIVACC_MICHAEL 0x04
+#define LM_PRIVACC_CCX_KP 0x08
+#define LM_PRIVACC_CCX_MIC 0x10
+#define LM_PRIVACC_AES_CCMP 0x20
+
+/* size of s_lm_descr in words */
+#define LM_DESCR_SIZE_WORDS 11
+
+#ifndef __ASSEMBLER__
+
+enum {
+ LM_MODE_CLIENT = 0,
+ LM_MODE_AP
+};
+
+struct s_lm_descr {
+ uint16_t modes;
+ uint16_t flags;
+ uint32_t buffer_start;
+ uint32_t buffer_end;
+ uint8_t header;
+ uint8_t trailer;
+ uint8_t tx_queues;
+ uint8_t tx_depth;
+ uint8_t privacy;
+ uint8_t rx_keycache;
+ uint8_t tim_size;
+ uint8_t pad1;
+ uint8_t rates[16];
+ uint32_t link;
+ uint16_t mtu;
+};
+
+
+struct s_lm_control {
+ uint16_t flags;
+ uint16_t length;
+ uint32_t handle;
+ uint16_t oid;
+ uint16_t pad;
+ /* uint8_t data[]; */
+};
+
+enum {
+ LM_PRIV_NONE = 0,
+ LM_PRIV_WEP,
+ LM_PRIV_TKIP,
+ LM_PRIV_TKIPMICHAEL,
+ LM_PRIV_CCX_WEPMIC,
+ LM_PRIV_CCX_KPMIC,
+ LM_PRIV_CCX_KP,
+ LM_PRIV_AES_CCMP
+};
+
+enum {
+ LM_DECRYPT_NONE,
+ LM_DECRYPT_OK,
+ LM_DECRYPT_NOKEY,
+ LM_DECRYPT_NOMICHAEL,
+ LM_DECRYPT_NOCKIPMIC,
+ LM_DECRYPT_FAIL_WEP,
+ LM_DECRYPT_FAIL_TKIP,
+ LM_DECRYPT_FAIL_MICHAEL,
+ LM_DECRYPT_FAIL_CKIPKP,
+ LM_DECRYPT_FAIL_CKIPMIC,
+ LM_DECRYPT_FAIL_AESCCMP
+};
+
+struct s_lm_data_out {
+ uint16_t flags;
+ uint16_t length;
+ uint32_t handle;
+ uint16_t aid;
+ uint8_t rts_retries;
+ uint8_t retries;
+ uint8_t aloft[8];
+ uint8_t aloft_ctrl;
+ uint8_t crypt_offset;
+ uint8_t keytype;
+ uint8_t keylen;
+ uint8_t key[16];
+ uint8_t queue;
+ uint8_t backlog;
+ uint16_t durations[4];
+ uint8_t antenna;
+ uint8_t cts;
+ int16_t power;
+ uint8_t pad[2];
+ /*uint8_t data[];*/
+};
+
+#define LM_RCPI_INVALID (0xff)
+
+struct s_lm_data_in {
+ uint16_t flags;
+ uint16_t length;
+ uint16_t frequency;
+ uint8_t antenna;
+ uint8_t rate;
+ uint8_t rcpi;
+ uint8_t sq;
+ uint8_t decrypt;
+ uint8_t rssi_raw;
+ uint32_t clock[2];
+ /*uint8_t data[];*/
+};
+
+union u_lm_data {
+ struct s_lm_data_out out;
+ struct s_lm_data_in in;
+};
+
+enum {
+ LM_OID_SETUP = 0,
+ LM_OID_SCAN = 1,
+ LM_OID_TRAP = 2,
+ LM_OID_EDCF = 3,
+ LM_OID_KEYCACHE = 4,
+ LM_OID_PSM = 6,
+ LM_OID_TXCANCEL = 7,
+ LM_OID_TX = 8,
+ LM_OID_BURST = 9,
+ LM_OID_STATS = 10,
+ LM_OID_LED = 13,
+ LM_OID_TIMER = 15,
+ LM_OID_NAV = 20,
+ LM_OID_PCS = 22,
+ LM_OID_BT_BALANCER = 28,
+ LM_OID_GROUP_ADDRESS_TABLE = 30,
+ LM_OID_ARPTABLE = 31,
+ LM_OID_BT_OPTIONS = 35
+};
+
+enum {
+ LM_FRONTEND_UNKNOWN = 0,
+ LM_FRONTEND_DUETTE3,
+ LM_FRONTEND_DUETTE2,
+ LM_FRONTEND_FRISBEE,
+ LM_FRONTEND_CROSSBOW,
+ LM_FRONTEND_LONGBOW
+};
+
+
+#define INVALID_LPF_BANDWIDTH 0xffff
+#define INVALID_OSC_START_DELAY 0xffff
+
+struct s_lmo_setup {
+ uint16_t flags;
+ uint8_t macaddr[6];
+ uint8_t bssid[6];
+ uint8_t antenna;
+ uint8_t rx_align;
+ uint32_t rx_buffer;
+ uint16_t rx_mtu;
+ uint16_t frontend;
+ uint16_t timeout;
+ uint16_t truncate;
+ uint32_t bratemask;
+ uint8_t sbss_offset;
+ uint8_t mcast_window;
+ uint8_t rx_rssi_threshold;
+ uint8_t rx_ed_threshold;
+ uint32_t ref_clock;
+ uint16_t lpf_bandwidth;
+ uint16_t osc_start_delay;
+};
+
+
+struct s_lmo_scan {
+ uint16_t flags;
+ uint16_t dwell;
+ uint8_t channel[292];
+ uint32_t bratemask;
+ uint8_t aloft[8];
+ uint8_t rssical[8];
+};
+
+
+enum {
+ LM_TRAP_SCAN = 0,
+ LM_TRAP_TIMER,
+ LM_TRAP_BEACON_TX,
+ LM_TRAP_FAA_RADIO_ON,
+ LM_TRAP_FAA_RADIO_OFF,
+ LM_TRAP_RADAR,
+ LM_TRAP_NO_BEACON,
+ LM_TRAP_TBTT,
+ LM_TRAP_SCO_ENTER,
+ LM_TRAP_SCO_EXIT
+};
+
+struct s_lmo_trap {
+ uint16_t event;
+ uint16_t frequency;
+};
+
+struct s_lmo_timer {
+ uint32_t interval;
+};
+
+struct s_lmo_nav {
+ uint32_t period;
+};
+
+
+struct s_lmo_edcf_queue;
+
+struct s_lmo_edcf {
+ uint8_t flags;
+ uint8_t slottime;
+ uint8_t sifs;
+ uint8_t eofpad;
+ struct s_lmo_edcf_queue {
+ uint8_t aifs;
+ uint8_t pad0;
+ uint16_t cwmin;
+ uint16_t cwmax;
+ uint16_t txop;
+ } queues[8];
+ uint8_t mapping[4];
+ uint16_t maxburst;
+ uint16_t round_trip_delay;
+};
+
+struct s_lmo_keycache {
+ uint8_t entry;
+ uint8_t keyid;
+ uint8_t address[6];
+ uint8_t pad[2];
+ uint8_t keytype;
+ uint8_t keylen;
+ uint8_t key[24];
+};
+
+
+struct s_lm_interval;
+
+struct s_lmo_psm {
+ uint16_t flags;
+ uint16_t aid;
+ struct s_lm_interval {
+ uint16_t interval;
+ uint16_t periods;
+ } intervals[4];
+ /* uint16_t pad; */
+ uint8_t beacon_rcpi_skip_max;
+ uint8_t rcpi_delta_threshold;
+ uint8_t nr;
+ uint8_t exclude[1];
+};
+
+#define MC_FILTER_ADDRESS_NUM 4
+
+struct s_lmo_group_address_table {
+ uint16_t filter_enable;
+ uint16_t num_address;
+ uint8_t macaddr_list[MC_FILTER_ADDRESS_NUM][6];
+};
+
+struct s_lmo_txcancel {
+ uint32_t address[1];
+};
+
+
+struct s_lmo_tx {
+ uint8_t flags;
+ uint8_t retries;
+ uint8_t rcpi;
+ uint8_t sq;
+ uint16_t seqctrl;
+ uint8_t antenna;
+ uint8_t pad;
+};
+
+struct s_lmo_burst {
+ uint8_t flags;
+ uint8_t queue;
+ uint8_t backlog;
+ uint8_t pad;
+ uint16_t durations[32];
+};
+
+struct s_lmo_stats {
+ uint32_t valid;
+ uint32_t fcs;
+ uint32_t abort;
+ uint32_t phyabort;
+ uint32_t rts_success;
+ uint32_t rts_fail;
+ uint32_t timestamp;
+ uint32_t time_tx;
+ uint32_t noisefloor;
+ uint32_t sample_noise[8];
+ uint32_t sample_cca;
+ uint32_t sample_tx;
+};
+
+
+struct s_lmo_led {
+ uint16_t flags;
+ uint16_t mask[2];
+ uint16_t delay/*[2]*/;
+};
+
+
+struct s_lmo_bt_balancer {
+ uint16_t prio_thresh;
+ uint16_t acl_thresh;
+};
+
+
+struct s_lmo_arp_table {
+ uint16_t filter_enable;
+ uint32_t ipaddr;
+};
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __lmac_h__ */
diff --git a/drivers/staging/sxg/Kconfig b/drivers/staging/sxg/Kconfig
index 6e6cf0b9ef9..c5cbdafee4d 100644
--- a/drivers/staging/sxg/Kconfig
+++ b/drivers/staging/sxg/Kconfig
@@ -8,4 +8,4 @@ config SXG
10Gbe network cards.
To compile this driver as a module, choose
- M here: the module will be called sxg.
+ M here: the module will be called sxg_nic.
diff --git a/drivers/staging/sxg/Makefile b/drivers/staging/sxg/Makefile
index ec48faa7b3e..8e053222c2a 100644
--- a/drivers/staging/sxg/Makefile
+++ b/drivers/staging/sxg/Makefile
@@ -1 +1,3 @@
-obj-$(CONFIG_SXG) += sxg.o
+obj-$(CONFIG_SXG) += sxg_nic.o
+
+sxg_nic-y := sxg.o sxg_ethtool.o
diff --git a/drivers/staging/sxg/saharadbgdownload.h b/drivers/staging/sxg/saharadbgdownload.h
deleted file mode 100644
index d8865ba0504..00000000000
--- a/drivers/staging/sxg/saharadbgdownload.h
+++ /dev/null
@@ -1,4854 +0,0 @@
-#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
index 1e0cfcd7f0f..891f6e33467 100644
--- a/drivers/staging/sxg/sxg.c
+++ b/drivers/staging/sxg/sxg.c
@@ -30,6 +30,8 @@
* are those of the authors and should not be interpreted as representing
* official policies, either expressed or implied, of Alacritech, Inc.
*
+ * Parts developed by LinSysSoft Sahara team
+ *
**************************************************************************/
/*
@@ -46,6 +48,7 @@
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/firmware.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
@@ -61,101 +64,122 @@
#include <linux/types.h>
#include <linux/dma-mapping.h>
#include <linux/mii.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/tcp.h>
+#include <linux/ipv6.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
+#define SXG_UCODE_DEBUG 0
+
#include "sxg_os.h"
#include "sxghw.h"
#include "sxghif.h"
#include "sxg.h"
#include "sxgdbg.h"
-
-#include "sxgphycode.h"
-#include "saharadbgdownload.h"
+#include "sxgphycode-1.2.h"
static int sxg_allocate_buffer_memory(struct adapter_t *adapter, u32 Size,
- enum SXG_BUFFER_TYPE BufferType);
-static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter, void *RcvBlock,
- dma_addr_t PhysicalAddress,
- u32 Length);
+ enum sxg_buffer_type BufferType);
+static int sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
+ void *RcvBlock,
+ dma_addr_t PhysicalAddress,
+ u32 Length);
static void sxg_allocate_sgl_buffer_complete(struct adapter_t *adapter,
- struct SXG_SCATTER_GATHER *SxgSgl,
+ struct sxg_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_entry_open(struct net_device *dev);
+static int sxg_second_open(struct net_device * dev);
+static int sxg_entry_halt(struct net_device *dev);
+static int sxg_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int sxg_send_packets(struct sk_buff *skb, struct net_device *dev);
static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb);
-static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GATHER *SxgSgl);
+static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
+ struct sxg_scatter_gather *SxgSgl);
-static void sxg_handle_interrupt(struct adapter_t *adapter);
+static void sxg_handle_interrupt(struct adapter_t *adapter, int *work_done,
+ int budget);
+static void sxg_interrupt(struct adapter_t *adapter);
+static int sxg_poll(struct napi_struct *napi, int budget);
static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId);
-static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId);
+static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId,
+ int *sxg_napi_continue, int *work_done, int budget);
static void sxg_complete_slow_send(struct adapter_t *adapter);
-static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EVENT *Event);
+static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
+ struct sxg_event *Event);
static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus);
static bool sxg_mac_filter(struct adapter_t *adapter,
struct ether_header *EtherHdr, ushort length);
-
-#if SLIC_GET_STATS_ENABLED
-static struct net_device_stats *sxg_get_stats(p_net_device dev);
-#endif
+static struct net_device_stats *sxg_get_stats(struct net_device * dev);
+void sxg_free_resources(struct adapter_t *adapter);
+void sxg_free_rcvblocks(struct adapter_t *adapter);
+void sxg_free_sgl_buffers(struct adapter_t *adapter);
+void sxg_unmap_resources(struct adapter_t *adapter);
+void sxg_free_mcast_addrs(struct adapter_t *adapter);
+void sxg_collect_statistics(struct adapter_t *adapter);
+static int sxg_register_interrupt(struct adapter_t *adapter);
+static void sxg_remove_isr(struct adapter_t *adapter);
+static irqreturn_t sxg_isr(int irq, void *dev_id);
+
+static void sxg_watchdog(unsigned long data);
+static void sxg_update_link_status (struct work_struct *work);
#define XXXTODO 0
#if XXXTODO
-static int sxg_mac_set_address(p_net_device dev, void *ptr);
-static void sxg_mcast_set_list(p_net_device dev);
+static int sxg_mac_set_address(struct net_device *dev, void *ptr);
#endif
+static void sxg_mcast_set_list(struct net_device *dev);
-static void sxg_adapter_set_hwaddr(struct adapter_t *adapter);
-
-static void sxg_unmap_mmio_space(struct adapter_t *adapter);
+static int sxg_adapter_set_hwaddr(struct adapter_t *adapter);
static int sxg_initialize_adapter(struct adapter_t *adapter);
static void sxg_stock_rcv_buffers(struct adapter_t *adapter);
static void sxg_complete_descriptor_blocks(struct adapter_t *adapter,
unsigned char Index);
+int sxg_change_mtu (struct net_device *netdev, int new_mtu);
static int sxg_initialize_link(struct adapter_t *adapter);
static int sxg_phy_init(struct adapter_t *adapter);
static void sxg_link_event(struct adapter_t *adapter);
static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter);
-static void sxg_link_state(struct adapter_t *adapter, enum SXG_LINK_STATE LinkState);
+static void sxg_link_state(struct adapter_t *adapter,
+ enum SXG_LINK_STATE LinkState);
static int sxg_write_mdio_reg(struct adapter_t *adapter,
u32 DevAddr, u32 RegAddr, u32 Value);
static int sxg_read_mdio_reg(struct adapter_t *adapter,
u32 DevAddr, u32 RegAddr, u32 *pValue);
+static void sxg_set_mcast_addr(struct adapter_t *adapter);
static unsigned int sxg_first_init = 1;
static char *sxg_banner =
- "Alacritech SLIC Technology(tm) Server and Storage 10Gbe Accelerator (Non-Accelerated)\n";
+ "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 struct net_device *head_netdevice = NULL;
-static struct sxgbase_driver_t sxg_global = {
+static struct sxgbase_driver 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"
+char sxg_driver_name[] = "sxg_nic";
#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."
+#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);
@@ -173,12 +197,6 @@ static struct pci_device_id sxg_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, sxg_pci_tbl);
-/***********************************************************************
-************************************************************************
-************************************************************************
-************************************************************************
-************************************************************************/
-
static inline void sxg_reg32_write(void __iomem *reg, u32 value, bool flush)
{
writel(value, reg);
@@ -225,17 +243,143 @@ static void sxg_dbg_macaddrs(struct adapter_t *adapter)
}
/* SXG Globals */
-static struct SXG_DRIVER SxgDriver;
+static struct sxg_driver SxgDriver;
#ifdef ATKDBG
-static struct sxg_trace_buffer_t LSxgTraceBuffer;
+static struct sxg_trace_buffer LSxgTraceBuffer;
#endif /* ATKDBG */
-static struct sxg_trace_buffer_t *SxgTraceBuffer = NULL;
+static struct sxg_trace_buffer *SxgTraceBuffer = NULL;
+
+/*
+ * MSI Related API's
+ */
+int sxg_register_intr(struct adapter_t *adapter);
+int sxg_enable_msi_x(struct adapter_t *adapter);
+int sxg_add_msi_isr(struct adapter_t *adapter);
+void sxg_remove_msix_isr(struct adapter_t *adapter);
+int sxg_set_interrupt_capability(struct adapter_t *adapter);
+
+int sxg_set_interrupt_capability(struct adapter_t *adapter)
+{
+ int ret;
+
+ ret = sxg_enable_msi_x(adapter);
+ if (ret != STATUS_SUCCESS) {
+ adapter->msi_enabled = FALSE;
+ DBG_ERROR("sxg_set_interrupt_capability MSI-X Disable\n");
+ } else {
+ adapter->msi_enabled = TRUE;
+ DBG_ERROR("sxg_set_interrupt_capability MSI-X Enable\n");
+ }
+ return ret;
+}
+
+int sxg_register_intr(struct adapter_t *adapter)
+{
+ int ret = 0;
+
+ if (adapter->msi_enabled) {
+ ret = sxg_add_msi_isr(adapter);
+ }
+ else {
+ DBG_ERROR("MSI-X Enable Failed. Using Pin INT\n");
+ ret = sxg_register_interrupt(adapter);
+ if (ret != STATUS_SUCCESS) {
+ DBG_ERROR("sxg_register_interrupt Failed\n");
+ }
+ }
+ return ret;
+}
+
+int sxg_enable_msi_x(struct adapter_t *adapter)
+{
+ int ret;
+
+ adapter->nr_msix_entries = 1;
+ adapter->msi_entries = kmalloc(adapter->nr_msix_entries *
+ sizeof(struct msix_entry),GFP_KERNEL);
+ if (!adapter->msi_entries) {
+ DBG_ERROR("%s:MSI Entries memory allocation Failed\n",__func__);
+ return -ENOMEM;
+ }
+ memset(adapter->msi_entries, 0, adapter->nr_msix_entries *
+ sizeof(struct msix_entry));
+
+ ret = pci_enable_msix(adapter->pcidev, adapter->msi_entries,
+ adapter->nr_msix_entries);
+ if (ret) {
+ DBG_ERROR("Enabling MSI-X with %d vectors failed\n",
+ adapter->nr_msix_entries);
+ /*Should try with less vector returned.*/
+ kfree(adapter->msi_entries);
+ return STATUS_FAILURE; /*MSI-X Enable failed.*/
+ }
+ return (STATUS_SUCCESS);
+}
+
+int sxg_add_msi_isr(struct adapter_t *adapter)
+{
+ int ret,i;
+
+ if (!adapter->intrregistered) {
+ for (i=0; i<adapter->nr_msix_entries; i++) {
+ ret = request_irq (adapter->msi_entries[i].vector,
+ sxg_isr,
+ IRQF_SHARED,
+ adapter->netdev->name,
+ adapter->netdev);
+ if (ret) {
+ DBG_ERROR("sxg: MSI-X request_irq (%s) "
+ "FAILED [%x]\n", adapter->netdev->name,
+ ret);
+ return (ret);
+ }
+ }
+ }
+ adapter->msi_enabled = TRUE;
+ adapter->intrregistered = 1;
+ adapter->IntRegistered = TRUE;
+ return (STATUS_SUCCESS);
+}
+
+void sxg_remove_msix_isr(struct adapter_t *adapter)
+{
+ int i,vector;
+ struct net_device *netdev = adapter->netdev;
+
+ for(i=0; i< adapter->nr_msix_entries;i++)
+ {
+ vector = adapter->msi_entries[i].vector;
+ DBG_ERROR("%s : Freeing IRQ vector#%d\n",__FUNCTION__,vector);
+ free_irq(vector,netdev);
+ }
+}
+
+
+static void sxg_remove_isr(struct adapter_t *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ if (adapter->msi_enabled)
+ sxg_remove_msix_isr(adapter);
+ else
+ free_irq(adapter->netdev->irq, netdev);
+}
+
+void sxg_reset_interrupt_capability(struct adapter_t *adapter)
+{
+ if (adapter->msi_enabled) {
+ pci_disable_msix(adapter->pcidev);
+ kfree(adapter->msi_entries);
+ adapter->msi_entries = NULL;
+ }
+ return;
+}
/*
* sxg_download_microcode
*
- * Download Microcode to Sahara adapter
+ * Download Microcode to Sahara adapter using the Linux
+ * Firmware module to get the ucode.sys file.
*
* Arguments -
* adapter - A pointer to our adapter structure
@@ -244,98 +388,141 @@ static struct sxg_trace_buffer_t *SxgTraceBuffer = NULL;
* Return
* int
*/
-static bool sxg_download_microcode(struct adapter_t *adapter, enum SXG_UCODE_SEL UcodeSel)
+static bool sxg_download_microcode(struct adapter_t *adapter,
+ enum SXG_UCODE_SEL UcodeSel)
{
- struct SXG_HW_REGS *HwRegs = adapter->HwRegs;
+ const struct firmware *fw;
+ const char *file = "";
+ struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+ int ret;
+ int ucode_start;
u32 Section;
u32 ThisSectionSize;
- u32 *Instruction = NULL;
+ u32 instruction = 0;
u32 BaseAddress, AddressOffset, Address;
-/* u32 Failure; */
+ /* u32 Failure; */
u32 ValueRead;
u32 i;
- u32 numSections = 0;
+ u32 index = 0;
+ u32 num_sections = 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", __func__);
-
- 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;
+
+ /*
+ * This routine is only implemented to download the microcode
+ * for the Revision B Sahara chip. Rev A and Diagnostic
+ * microcode is not supported at this time. If Rev A or
+ * diagnostic ucode is required, this routine will obviously
+ * need to change. Also, eventually need to add support for
+ * Rev B checked version of ucode. That's easy enough once
+ * the free version of Rev B works.
+ */
+ ASSERT(UcodeSel == SXG_UCODE_SYSTEM);
+ ASSERT(adapter->asictype == SAHARA_REV_B);
+#if SXG_UCODE_DEBUG
+ file = "sxg/saharadbgdownloadB.sys";
+#else
+ file = "sxg/saharadownloadB.sys";
+#endif
+ ret = request_firmware(&fw, file, &adapter->pcidev->dev);
+ if (ret) {
+ DBG_ERROR("%s SXG_NIC: Failed to load firmware %s\n", __func__,file);
+ return ret;
+ }
+
+ /*
+ * The microcode .sys file contains starts with a 4 byte word containing
+ * the number of sections. That is followed by "num_sections" 4 byte
+ * words containing each "section" size. That is followed num_sections
+ * 4 byte words containing each section "start" address.
+ *
+ * Following the above header, the .sys file contains num_sections,
+ * where each section size is specified, newline delineatetd 12 byte
+ * microcode instructions.
+ */
+ num_sections = *(u32 *)(fw->data + index);
+ index += 4;
+ ASSERT(num_sections <= 3);
+ for (i = 0; i < num_sections; i++) {
+ sectionSize[i] = *(u32 *)(fw->data + index);
+ index += 4;
+ }
+ for (i = 0; i < num_sections; i++) {
+ sectionStart[i] = *(u32 *)(fw->data + index);
+ index += 4;
}
- DBG_ERROR("sxg: RESET THE CARD\n");
/* First, reset the card */
WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH);
+ udelay(50);
+ HwRegs = adapter->HwRegs;
- /* 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;
- }
+ /*
+ * Download each section of the microcode as specified in
+ * sectionSize[index] to sectionStart[index] address. As
+ * described above, the .sys file contains 12 byte word
+ * microcode instructions. The *download.sys file is generated
+ * using the objtosys.exe utility that was built for Sahara
+ * microcode.
+ */
+ /* See usage of this below when we read back for parity */
+ ucode_start = index;
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
+
+ for (Section = 0; Section < num_sections; Section++) {
BaseAddress = sectionStart[Section];
- ThisSectionSize = sectionSize[Section] / 12; /* Size in instructions */
+ /* Size in instructions */
+ ThisSectionSize = sectionSize[Section] / 12;
for (AddressOffset = 0; AddressOffset < ThisSectionSize;
AddressOffset++) {
+ u32 first_instr = 0; /* See comment below */
+
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 bits 31 - 0 (low) */
+ first_instr = instruction;
+ WRITE_REG(HwRegs->UcodeDataLow, instruction, FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4; /* Advance to the "next" instruction */
+
+ /* Write instruction bits 63-32 (middle) */
+ WRITE_REG(HwRegs->UcodeDataMiddle, instruction, FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4; /* Advance to the "next" instruction */
+
+ /* Write instruction bits 95-64 (high) */
+ WRITE_REG(HwRegs->UcodeDataHigh, instruction, FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4; /* Advance to the "next" instruction */
+
/* 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;
+ /*
+ * 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, first_instr, FLUSH);
}
}
- /* 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;
- }
+ /*
+ * Now repeat the entire operation reading the instruction back and
+ * checking for parity errors
+ */
+ index = ucode_start;
+
+ for (Section = 0; Section < num_sections; Section++) {
BaseAddress = sectionStart[Section];
- ThisSectionSize = sectionSize[Section] / 12; /* Size in instructions */
+ /* Size in instructions */
+ ThisSectionSize = sectionSize[Section] / 12;
for (AddressOffset = 0; AddressOffset < ThisSectionSize;
AddressOffset++) {
Address = BaseAddress + AddressOffset;
@@ -348,62 +535,70 @@ static bool sxg_download_microcode(struct adapter_t *adapter, enum SXG_UCODE_SEL
DBG_ERROR("sxg: %s PARITY ERROR\n",
__func__);
- return (FALSE); /* Parity error */
+ return FALSE; /* Parity error */
}
ASSERT((ValueRead & MICROCODE_ADDRESS_MASK) == Address);
/* Read the instruction back and compare */
+ /* First instruction */
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
READ_REG(HwRegs->UcodeDataLow, ValueRead);
- if (ValueRead != *Instruction) {
+ if (ValueRead != instruction) {
DBG_ERROR("sxg: %s MISCOMPARE LOW\n",
__func__);
- return (FALSE); /* Miscompare */
+ return FALSE; /* Miscompare */
}
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
READ_REG(HwRegs->UcodeDataMiddle, ValueRead);
- if (ValueRead != *(Instruction + 1)) {
+ if (ValueRead != instruction) {
DBG_ERROR("sxg: %s MISCOMPARE MIDDLE\n",
__func__);
- return (FALSE); /* Miscompare */
+ return FALSE; /* Miscompare */
}
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
READ_REG(HwRegs->UcodeDataHigh, ValueRead);
- if (ValueRead != *(Instruction + 2)) {
+ if (ValueRead != instruction) {
DBG_ERROR("sxg: %s MISCOMPARE HIGH\n",
__func__);
- return (FALSE); /* Miscompare */
+ return FALSE; /* Miscompare */
}
- /* Advance 3 u32S to start of next instruction */
- Instruction += 3;
}
}
+ /* download finished */
+ release_firmware(fw);
/* Everything OK, Go. */
WRITE_REG(HwRegs->UcodeAddr, MICROCODE_ADDRESS_GO, FLUSH);
- /* Poll the CardUp register to wait for microcode to initialize */
- /* Give up after 10,000 attemps (500ms). */
+ /*
+ * Poll the CardUp register to wait for microcode to initialize
+ * Give up after 10,000 attemps (500ms).
+ */
for (i = 0; i < 10000; i++) {
udelay(50);
READ_REG(adapter->UcodeRegs[0].CardUp, ValueRead);
if (ValueRead == 0xCAFE) {
- DBG_ERROR("sxg: %s BOO YA 0xCAFE\n", __func__);
break;
}
}
if (i == 10000) {
- DBG_ERROR("sxg: %s TIMEOUT\n", __func__);
+ DBG_ERROR("sxg: %s TIMEOUT bringing up card - verify MICROCODE\n", __func__);
- return (FALSE); /* Timeout */
+ return FALSE; /* Timeout */
}
- /* Now write the LoadSync register. This is used to */
- /* synchronize with the card so it can scribble on the memory */
- /* that contained 0xCAFE from the "CardUp" step above */
- if (UcodeSel == SXG_UCODE_SAHARA) {
+ /*
+ * 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_SYSTEM) {
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", __func__);
-
return (TRUE);
}
@@ -411,18 +606,16 @@ static bool sxg_download_microcode(struct adapter_t *adapter, enum SXG_UCODE_SEL
* sxg_allocate_resources - Allocate memory and locks
*
* Arguments -
- * adapter - A pointer to our adapter structure
+ * adapter - A pointer to our adapter structure
*
- * Return
- * int
+ * Return - int
*/
static int sxg_allocate_resources(struct adapter_t *adapter)
{
- int status;
- u32 i;
+ int status = STATUS_SUCCESS;
u32 RssIds, IsrCount;
-/* struct SXG_XMT_RING *XmtRing; */
-/* struct SXG_RCV_RING *RcvRing; */
+ /* struct sxg_xmt_ring *XmtRing; */
+ /* struct sxg_rcv_ring *RcvRing; */
DBG_ERROR("%s ENTER\n", __func__);
@@ -432,7 +625,7 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
/* Windows tells us how many CPUs it plans to use for */
/* RSS */
RssIds = SXG_RSS_CPU_COUNT(adapter);
- IsrCount = adapter->MsiEnabled ? RssIds : 1;
+ IsrCount = adapter->msi_enabled ? RssIds : 1;
DBG_ERROR("%s Setup the spinlocks\n", __func__);
@@ -442,6 +635,7 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
spin_lock_init(&adapter->XmtZeroLock);
spin_lock_init(&adapter->Bit64RegLock);
spin_lock_init(&adapter->AdapterLock);
+ atomic_set(&adapter->pending_allocations, 0);
DBG_ERROR("%s Setup the lists\n", __func__);
@@ -451,62 +645,82 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
InitializeListHead(&adapter->FreeSglBuffers);
InitializeListHead(&adapter->AllSglBuffers);
- /* Mark these basic allocations done. This flags essentially */
- /* tells the SxgFreeResources routine that it can grab spinlocks */
- /* and reference listheads. */
+ /*
+ * Mark these basic allocations done. This flags essentially
+ * tells the SxgFreeResources routine that it can grab spinlocks
+ * and reference listheads.
+ */
adapter->BasicAllocations = TRUE;
- /* Main allocation loop. Start with the maximum supported by */
- /* the microcode and back off if memory allocation */
- /* fails. If we hit a minimum, fail. */
+ /*
+ * Main allocation loop. Start with the maximum supported by
+ * the microcode and back off if memory allocation
+ * fails. If we hit a minimum, fail.
+ */
for (;;) {
DBG_ERROR("%s Allocate XmtRings size[%x]\n", __func__,
- (unsigned int)(sizeof(struct SXG_XMT_RING) * 1));
+ (unsigned int)(sizeof(struct sxg_xmt_ring) * 1));
- /* Start with big items first - receive and transmit rings. At the moment */
- /* I'm going to keep the ring size fixed and adjust the number of */
- /* TCBs if we fail. Later we might consider reducing the ring size as well.. */
+ /*
+ * Start with big items first - receive and transmit rings.
+ * At the moment I'm going to keep the ring size fixed and
+ * adjust the TCBs if we fail. Later we might
+ * consider reducing the ring size as well..
+ */
adapter->XmtRings = pci_alloc_consistent(adapter->pcidev,
- sizeof(struct SXG_XMT_RING) *
- 1,
- &adapter->PXmtRings);
+ sizeof(struct sxg_xmt_ring) *
+ 1,
+ &adapter->PXmtRings);
DBG_ERROR("%s XmtRings[%p]\n", __func__, adapter->XmtRings);
if (!adapter->XmtRings) {
goto per_tcb_allocation_failed;
}
- memset(adapter->XmtRings, 0, sizeof(struct SXG_XMT_RING) * 1);
+ memset(adapter->XmtRings, 0, sizeof(struct sxg_xmt_ring) * 1);
DBG_ERROR("%s Allocate RcvRings size[%x]\n", __func__,
- (unsigned int)(sizeof(struct SXG_RCV_RING) * 1));
+ (unsigned int)(sizeof(struct sxg_rcv_ring) * 1));
adapter->RcvRings =
pci_alloc_consistent(adapter->pcidev,
- sizeof(struct SXG_RCV_RING) * 1,
+ sizeof(struct sxg_rcv_ring) * 1,
&adapter->PRcvRings);
DBG_ERROR("%s RcvRings[%p]\n", __func__, adapter->RcvRings);
if (!adapter->RcvRings) {
goto per_tcb_allocation_failed;
}
- memset(adapter->RcvRings, 0, sizeof(struct SXG_RCV_RING) * 1);
+ memset(adapter->RcvRings, 0, sizeof(struct sxg_rcv_ring) * 1);
+ adapter->ucode_stats = kzalloc(sizeof(struct sxg_ucode_stats), GFP_ATOMIC);
+ adapter->pucode_stats = pci_map_single(adapter->pcidev,
+ adapter->ucode_stats,
+ sizeof(struct sxg_ucode_stats),
+ PCI_DMA_FROMDEVICE);
+// memset(adapter->ucode_stats, 0, sizeof(struct sxg_ucode_stats));
break;
per_tcb_allocation_failed:
/* an allocation failed. Free any successful allocations. */
if (adapter->XmtRings) {
pci_free_consistent(adapter->pcidev,
- sizeof(struct SXG_XMT_RING) * 4096,
+ sizeof(struct sxg_xmt_ring) * 1,
adapter->XmtRings,
adapter->PXmtRings);
adapter->XmtRings = NULL;
}
if (adapter->RcvRings) {
pci_free_consistent(adapter->pcidev,
- sizeof(struct SXG_RCV_RING) * 4096,
+ sizeof(struct sxg_rcv_ring) * 1,
adapter->RcvRings,
adapter->PRcvRings);
adapter->RcvRings = NULL;
}
/* Loop around and try again.... */
+ if (adapter->ucode_stats) {
+ pci_unmap_single(adapter->pcidev,
+ sizeof(struct sxg_ucode_stats),
+ adapter->pucode_stats, PCI_DMA_FROMDEVICE);
+ adapter->ucode_stats = NULL;
+ }
+
}
DBG_ERROR("%s Initialize RCV ZERO and XMT ZERO rings\n", __func__);
@@ -515,53 +729,37 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
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(struct SXG_RCV_DESCRIPTOR_BLOCK) ==
+ /* ASSERT((adapter->ReceiveBufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
+ (adapter->ReceiveBufferSize == SXG_RCV_JUMBO_BUFFER_SIZE)); */
+ ASSERT(sizeof(struct 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[%x]\n", __func__,
- (unsigned int)(sizeof(struct SXG_EVENT_RING) * RssIds));
+ (unsigned int)(sizeof(struct sxg_event_ring) * RssIds));
/* Allocate event queues. */
adapter->EventRings = pci_alloc_consistent(adapter->pcidev,
- sizeof(struct SXG_EVENT_RING) *
- RssIds,
- &adapter->PEventRings);
+ sizeof(struct sxg_event_ring) *
+ RssIds,
+ &adapter->PEventRings);
if (!adapter->EventRings) {
- /* Caller will call SxgFreeAdapter to clean up above allocations */
+ /* Caller will call SxgFreeAdapter to clean up above
+ * allocations */
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF8",
adapter, SXG_MAX_ENTRIES, 0, 0);
status = STATUS_RESOURCES;
goto per_tcb_allocation_failed;
}
- memset(adapter->EventRings, 0, sizeof(struct SXG_EVENT_RING) * RssIds);
+ memset(adapter->EventRings, 0, sizeof(struct sxg_event_ring) * RssIds);
DBG_ERROR("%s Allocate ISR size[%x]\n", __func__, IsrCount);
/* Allocate ISR */
adapter->Isr = pci_alloc_consistent(adapter->pcidev,
IsrCount, &adapter->PIsr);
if (!adapter->Isr) {
- /* Caller will call SxgFreeAdapter to clean up above allocations */
+ /* Caller will call SxgFreeAdapter to clean up above
+ * allocations */
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF9",
adapter, SXG_MAX_ENTRIES, 0, 0);
status = STATUS_RESOURCES;
@@ -588,8 +786,7 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlcResS",
adapter, SXG_MAX_ENTRIES, 0, 0);
- DBG_ERROR("%s EXIT\n", __func__);
- return (STATUS_SUCCESS);
+ return status;
}
/*
@@ -599,7 +796,6 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
*
* Arguments -
* pcidev - A pointer to our adapter structure
- *
*/
static void sxg_config_pci(struct pci_dev *pcidev)
{
@@ -609,12 +805,19 @@ static void sxg_config_pci(struct pci_dev *pcidev)
pci_read_config_word(pcidev, PCI_COMMAND, &pci_command);
DBG_ERROR("sxg: %s PCI command[%4.4x]\n", __func__, pci_command);
/* Set the command register */
- new_command = pci_command | (PCI_COMMAND_MEMORY | /* Memory Space Enable */
- PCI_COMMAND_MASTER | /* Bus master enable */
- PCI_COMMAND_INVALIDATE | /* Memory write and invalidate */
- PCI_COMMAND_PARITY | /* Parity error response */
- PCI_COMMAND_SERR | /* System ERR */
- PCI_COMMAND_FAST_BACK); /* Fast back-to-back */
+ new_command = pci_command | (
+ /* Memory Space Enable */
+ PCI_COMMAND_MEMORY |
+ /* Bus master enable */
+ PCI_COMMAND_MASTER |
+ /* Memory write and invalidate */
+ PCI_COMMAND_INVALIDATE |
+ /* Parity error response */
+ PCI_COMMAND_PARITY |
+ /* System ERR */
+ PCI_COMMAND_SERR |
+ /* Fast back-to-back */
+ PCI_COMMAND_FAST_BACK);
if (pci_command != new_command) {
DBG_ERROR("%s -- Updating PCI COMMAND register %4.4x->%4.4x.\n",
__func__, pci_command, new_command);
@@ -622,6 +825,77 @@ static void sxg_config_pci(struct pci_dev *pcidev)
}
}
+/*
+ * sxg_read_config
+ * @adapter : Pointer to the adapter structure for the card
+ * This function will read the configuration data from EEPROM/FLASH
+ */
+static inline int sxg_read_config(struct adapter_t *adapter)
+{
+ /* struct sxg_config data; */
+ struct sxg_config *config;
+ struct sw_cfg_data *data;
+ dma_addr_t p_addr;
+ unsigned long status;
+ unsigned long i;
+ config = pci_alloc_consistent(adapter->pcidev,
+ sizeof(struct sxg_config), &p_addr);
+
+ if(!config) {
+ /*
+ * We cant get even this much memory. Raise a hell
+ * Get out of here
+ */
+ printk(KERN_ERR"%s : Could not allocate memory for reading \
+ EEPROM\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ data = &config->SwCfg;
+
+ /* Initialize (reflective memory) status register */
+ WRITE_REG(adapter->UcodeRegs[0].ConfigStat, SXG_CFG_TIMEOUT, TRUE);
+
+ /* Send request to fetch configuration data */
+ WRITE_REG64(adapter, adapter->UcodeRegs[0].Config, p_addr, 0);
+ for(i=0; i<1000; i++) {
+ READ_REG(adapter->UcodeRegs[0].ConfigStat, status);
+ if (status != SXG_CFG_TIMEOUT)
+ break;
+ mdelay(1); /* Do we really need this */
+ }
+
+ switch(status) {
+ /* Config read from EEPROM succeeded */
+ case SXG_CFG_LOAD_EEPROM:
+ /* Config read from Flash succeeded */
+ case SXG_CFG_LOAD_FLASH:
+ /*
+ * Copy the MAC address to adapter structure
+ * TODO: We are not doing the remaining part : FRU, etc
+ */
+ memcpy(adapter->macaddr, data->MacAddr[0].MacAddr,
+ sizeof(struct sxg_config_mac));
+ break;
+ case SXG_CFG_TIMEOUT:
+ case SXG_CFG_LOAD_INVALID:
+ case SXG_CFG_LOAD_ERROR:
+ default: /* Fix default handler later */
+ printk(KERN_WARNING"%s : We could not read the config \
+ word. Status = %ld\n", __FUNCTION__, status);
+ break;
+ }
+ pci_free_consistent(adapter->pcidev, sizeof(struct sw_cfg_data), data,
+ p_addr);
+ if (adapter->netdev) {
+ memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, 6);
+ memcpy(adapter->netdev->perm_addr, adapter->currmacaddr, 6);
+ }
+ sxg_dbg_macaddrs(adapter);
+
+ return status;
+}
+
static int sxg_entry_probe(struct pci_dev *pcidev,
const struct pci_device_id *pci_tbl_entry)
{
@@ -633,6 +907,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
u32 status = 0;
ulong mmio_start = 0;
ulong mmio_len = 0;
+ unsigned char revision_id;
DBG_ERROR("sxg: %s 2.6 VERSION ENTER jiffies[%lx] cpu %d\n",
__func__, jiffies, smp_processor_id());
@@ -654,24 +929,26 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
if (sxg_debug > 0 && did_version++ == 0) {
printk(KERN_INFO "%s\n", sxg_banner);
- printk(KERN_INFO "%s\n", DRV_VERSION);
+ printk(KERN_INFO "%s\n", SXG_DRV_VERSION);
}
- if (!(err = pci_set_dma_mask(pcidev, DMA_64BIT_MASK))) {
- DBG_ERROR("pci_set_dma_mask(DMA_64BIT_MASK) successful\n");
+ pci_read_config_byte(pcidev, PCI_REVISION_ID, &revision_id);
+
+ if (!(err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64)))) {
+ DBG_ERROR("pci_set_dma_mask(DMA_BIT_MASK(64)) successful\n");
} else {
- if ((err = pci_set_dma_mask(pcidev, DMA_32BIT_MASK))) {
+ if ((err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32)))) {
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("pci_set_dma_mask(DMA_BIT_MASK(32)) successful\n");
}
DBG_ERROR("Call pci_request_regions\n");
- err = pci_request_regions(pcidev, DRV_NAME);
+ err = pci_request_regions(pcidev, sxg_driver_name);
if (err) {
DBG_ERROR("pci_request_regions FAILED err[%x]\n", err);
return err;
@@ -692,6 +969,15 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
pci_set_drvdata(pcidev, netdev);
adapter = netdev_priv(netdev);
+ if (revision_id == 1) {
+ adapter->asictype = SAHARA_REV_A;
+ } else if (revision_id == 2) {
+ adapter->asictype = SAHARA_REV_B;
+ } else {
+ ASSERT(0);
+ DBG_ERROR("%s Unexpected revision ID %x\n", __FUNCTION__, revision_id);
+ goto err_out_exit_sxg_probe;
+ }
adapter->netdev = netdev;
adapter->pcidev = pcidev;
@@ -707,12 +993,12 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
if (!memmapped_ioaddr) {
DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
__func__, mmio_len, mmio_start);
- goto err_out_free_mmio_region;
+ goto err_out_free_mmio_region_0;
}
- 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);
+ 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;
@@ -729,7 +1015,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
if (!memmapped_ioaddr) {
DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
__func__, mmio_len, mmio_start);
- goto err_out_free_mmio_region;
+ goto err_out_free_mmio_region_2;
}
DBG_ERROR("sxg: %s found Alacritech SXG PCI, MMIO at %p, "
@@ -739,8 +1025,10 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
adapter->UcodeRegs = (void *)memmapped_ioaddr;
adapter->State = SXG_STATE_INITIALIZING;
- /* Maintain a list of all adapters anchored by */
- /* the global SxgDriver structure. */
+ /*
+ * Maintain a list of all adapters anchored by
+ * the global SxgDriver structure.
+ */
adapter->Next = SxgDriver.Adapters;
SxgDriver.Adapters = adapter;
adapter->AdapterID = ++SxgDriver.AdapterID;
@@ -758,10 +1046,12 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE;
}
-/* status = SXG_READ_EEPROM(adapter); */
-/* if (!status) { */
-/* goto sxg_init_bad; */
-/* } */
+ /*
+ * status = SXG_READ_EEPROM(adapter);
+ * if (!status) {
+ * goto sxg_init_bad;
+ * }
+ */
DBG_ERROR("sxg: %s ENTER sxg_config_pci\n", __func__);
sxg_config_pci(pcidev);
@@ -774,16 +1064,13 @@ static int sxg_entry_probe(struct pci_dev *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->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", __func__);
@@ -795,10 +1082,11 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
}
DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __func__);
- if (sxg_download_microcode(adapter, SXG_UCODE_SAHARA)) {
+ if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) {
DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
__func__);
- sxg_adapter_set_hwaddr(adapter);
+ sxg_read_config(adapter);
+ status = sxg_adapter_set_hwaddr(adapter);
} else {
adapter->state = ADAPT_FAIL;
adapter->linkstate = LINK_DOWN;
@@ -811,40 +1099,63 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
netdev->stop = sxg_entry_halt;
netdev->hard_start_xmit = sxg_send_packets;
netdev->do_ioctl = sxg_ioctl;
+ netdev->change_mtu = sxg_change_mtu;
#if XXXTODO
netdev->set_mac_address = sxg_mac_set_address;
-#if SLIC_GET_STATS_ENABLED
- netdev->get_stats = sxg_get_stats;
#endif
+ netdev->get_stats = sxg_get_stats;
netdev->set_multicast_list = sxg_mcast_set_list;
-#endif
+ SET_ETHTOOL_OPS(netdev, &sxg_nic_ethtool_ops);
+ netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ err = sxg_set_interrupt_capability(adapter);
+ if (err != STATUS_SUCCESS)
+ DBG_ERROR("Cannot enable MSI-X capability\n");
strcpy(netdev->name, "eth%d");
-/* strcpy(netdev->name, pci_name(pcidev)); */
+ /* strcpy(netdev->name, pci_name(pcidev)); */
if ((err = register_netdev(netdev))) {
DBG_ERROR("Cannot register net device, aborting. %s\n",
netdev->name);
goto err_out_unmap;
}
+ netif_napi_add(netdev, &adapter->napi,
+ sxg_poll, SXG_NETDEV_WEIGHT);
+ netdev->watchdog_timeo = 2 * HZ;
+ init_timer(&adapter->watchdog_timer);
+ adapter->watchdog_timer.function = &sxg_watchdog;
+ adapter->watchdog_timer.data = (unsigned long) adapter;
+ INIT_WORK(&adapter->update_link_status, sxg_update_link_status);
+
DBG_ERROR
- ("sxg: %s addr 0x%lx, irq %d, MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n",
+ ("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: */
+ /* sxg_init_bad: */
ASSERT(status == FALSE);
-/* sxg_free_adapter(adapter); */
+ /* sxg_free_adapter(adapter); */
DBG_ERROR("sxg: %s EXIT status[%x] jiffies[%lx] cpu %d\n", __func__,
status, jiffies, smp_processor_id());
return status;
err_out_unmap:
- iounmap((void *)memmapped_ioaddr);
+ sxg_free_resources(adapter);
+
+ err_out_free_mmio_region_2:
+
+ mmio_start = pci_resource_start(pcidev, 2);
+ mmio_len = pci_resource_len(pcidev, 2);
+ release_mem_region(mmio_start, mmio_len);
+
+ err_out_free_mmio_region_0:
+
+ mmio_start = pci_resource_start(pcidev, 0);
+ mmio_len = pci_resource_len(pcidev, 0);
- err_out_free_mmio_region:
release_mem_region(mmio_start, mmio_len);
err_out_exit_sxg_probe:
@@ -852,13 +1163,16 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
DBG_ERROR("%s EXIT jiffies[%lx] cpu %d\n", __func__, jiffies,
smp_processor_id());
+ pci_disable_device(pcidev);
+ DBG_ERROR("sxg: %s deallocate device\n", __FUNCTION__);
+ kfree(netdev);
+ printk("Exit %s, Sxg driver loading failed..\n", __FUNCTION__);
+
return -ENODEV;
}
-/***********************************************************************
- * LINE BASE Interrupt routines..
- ***********************************************************************/
/*
+ * LINE BASE Interrupt routines..
*
* sxg_disable_interrupt
*
@@ -877,10 +1191,7 @@ static void sxg_disable_interrupt(struct adapter_t *adapter)
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;
@@ -890,7 +1201,6 @@ static void sxg_disable_interrupt(struct adapter_t *adapter)
}
/*
- *
* sxg_enable_interrupt
*
* EnableInterrupt Handler
@@ -908,10 +1218,7 @@ static void sxg_enable_interrupt(struct adapter_t *adapter)
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;
@@ -921,50 +1228,51 @@ static void sxg_enable_interrupt(struct adapter_t *adapter)
}
/*
- *
* sxg_isr - Process an line-based interrupt
*
* Arguments:
- * Context - Our adapter structure
+ * Context - Our adapter structure
* QueueDefault - Output parameter to queue to default CPU
- * TargetCpus - Output bitmap to schedule DPC's
+ * TargetCpus - Output bitmap to schedule DPC's
*
- * Return Value:
- * TRUE if our interrupt
+ * 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;
+ struct net_device *dev = (struct net_device *) dev_id;
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
-/* u32 CpuMask = 0, i; */
+ if(adapter->state != ADAPT_UP)
+ return IRQ_NONE;
adapter->Stats.NumInts++;
if (adapter->Isr[0] == 0) {
- /* The SLIC driver used to experience a number of spurious interrupts */
- /* due to the delay associated with the masking of the interrupt */
- /* (we'd bounce back in here). If we see that again with Sahara, */
- /* add a READ_REG of the Icr register after the WRITE_REG below. */
+ /*
+ * The SLIC driver used to experience a number of spurious
+ * interrupts due to the delay associated with the masking of
+ * the interrupt (we'd bounce back in here). If we see that
+ * again with Sahara,add a READ_REG of the Icr register after
+ * the WRITE_REG below.
+ */
adapter->Stats.FalseInts++;
return IRQ_NONE;
}
- /* */
- /* Move the Isr contents and clear the value in */
- /* shared memory, and mask interrupts */
- /* */
- 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); */
+ /*
+ * Move the Isr contents and clear the value in
+ * shared memory, and mask interrupts
+ */
+ /* 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 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++) {
- struct XG_EVENT_RING *EventRing = &adapter->EventRings[i];
- struct SXG_EVENT *Event =
+ struct sxg_event_ring *EventRing =
+ &adapter->EventRings[i];
+ struct sxg_event *Event =
&EventRing->Ring[adapter->NextEvent[i]];
unsigned char Cpu =
adapter->RssSystemInfo->RssIdToCpu[i];
@@ -974,8 +1282,10 @@ static irqreturn_t sxg_isr(int irq, void *dev_id)
}
}
}
- /* Now, either schedule the CPUs specified by the CpuMask, */
- /* or queue default */
+ /*
+ * Now, either schedule the CPUs specified by the CpuMask,
+ * or queue default
+ */
if (CpuMask) {
*QueueDefault = FALSE;
} else {
@@ -984,34 +1294,41 @@ static irqreturn_t sxg_isr(int irq, void *dev_id)
}
*TargetCpus = CpuMask;
#endif
- /* */
- /* There are no DPCs in Linux, so call the handler now */
- /* */
- sxg_handle_interrupt(adapter);
+ sxg_interrupt(adapter);
return IRQ_HANDLED;
}
-static void sxg_handle_interrupt(struct adapter_t *adapter)
+static void sxg_interrupt(struct adapter_t *adapter)
{
-/* unsigned char RssId = 0; */
- u32 NewIsr;
+ WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_MASK), TRUE);
- if (adapter->Stats.RcvNoBuffer < 5) {
- DBG_ERROR("Enter sxg_handle_interrupt ISR[%x]\n",
- adapter->IsrCopy[0]);
+ if (napi_schedule_prep(&adapter->napi)) {
+ __napi_schedule(&adapter->napi);
}
+}
+
+static void sxg_handle_interrupt(struct adapter_t *adapter, int *work_done,
+ int budget)
+{
+ /* unsigned char RssId = 0; */
+ u32 NewIsr;
+ int sxg_napi_continue = 1;
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]);
-/*/////////////////////////// */
+
+ adapter->IsrCopy[0] = adapter->Isr[0];
+ adapter->Isr[0] = 0;
/* Always process the event queue. */
- sxg_process_event_queue(adapter,
- (adapter->RssEnabled ? /*RssId */ 0 : 0));
+ while (sxg_napi_continue)
+ {
+ sxg_process_event_queue(adapter,
+ (adapter->RssEnabled ? /*RssId */ 0 : 0),
+ &sxg_napi_continue, work_done, budget);
+ }
#if XXXTODO /* RSS stuff */
if (--adapter->IsrDpcsPending) {
@@ -1022,30 +1339,31 @@ static void sxg_handle_interrupt(struct adapter_t *adapter)
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);
}
+static int sxg_poll(struct napi_struct *napi, int budget)
+{
+ struct adapter_t *adapter = container_of(napi, struct adapter_t, napi);
+ int work_done = 0;
+
+ sxg_handle_interrupt(adapter, &work_done, budget);
+
+ if (work_done < budget) {
+ napi_complete(napi);
+ WRITE_REG(adapter->UcodeRegs[0].Isr, 0, TRUE);
+ }
+ return work_done;
+}
/*
- *
* sxg_process_isr - Process an interrupt. Called from the line-based and
* message based interrupt DPC routines
*
@@ -1072,24 +1390,28 @@ static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
}
/* 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) {
+ /*
+ * 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 probablyd
+ * 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.rx_missed_errors++;
+ if (adapter->stats.rx_missed_errors< 5) {
DBG_ERROR("%s: SXG_ISR_ERR RMISS!!\n",
__func__);
}
}
/* 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);
+ /*
+ * 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", __func__,
@@ -1097,18 +1419,18 @@ static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
}
/* Event ring full */
if (Isr & SXG_ISR_ERFULL) {
- /* Same issue as RMISS, really. This means the */
- /* host is falling behind the card. Need to increase */
- /* event ring size, process more events per interrupt, */
- /* and/or reduce/remove interrupt aggregation. */
+ /*
+ * Same issue as RMISS, really. This means the
+ * host is falling behind the card. Need to increase
+ * event ring size, process more events per interrupt,
+ * and/or reduce/remove interrupt aggregation.
+ */
adapter->Stats.EventRingFull++;
DBG_ERROR("%s: SXG_ISR_ERR EVENT RING FULL!!\n",
__func__);
}
/* 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", __func__);
}
}
@@ -1118,18 +1440,24 @@ static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
}
/* Dump */
if (Isr & SXG_ISR_UPC) {
- ASSERT(adapter->DumpCmdRunning); /* Maybe change when debug is added.. */
+ /* Maybe change when debug is added.. */
+// ASSERT(adapter->DumpCmdRunning);
adapter->DumpCmdRunning = FALSE;
}
/* Link event */
if (Isr & SXG_ISR_LINK) {
- sxg_link_event(adapter);
+ if (adapter->state != ADAPT_DOWN) {
+ adapter->link_status_changed = 1;
+ schedule_work(&adapter->update_link_status);
+ }
}
/* Debug - breakpoint hit */
if (Isr & SXG_ISR_BREAK) {
- /* At the moment AGDB isn't written to support interactive */
- /* debug sessions. When it is, this interrupt will be used */
- /* to signal AGDB that it has hit a breakpoint. For now, ASSERT. */
+ /*
+ * At the moment AGDB isn't written to support interactive
+ * debug sessions. When it is, this interrupt will be used to
+ * signal AGDB that it has hit a breakpoint. For now, ASSERT.
+ */
ASSERT(0);
}
/* Heartbeat response */
@@ -1143,7 +1471,33 @@ static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
}
/*
+ * sxg_rcv_checksum - Set the checksum for received packet
*
+ * Arguements:
+ * @adapter - Adapter structure on which packet is received
+ * @skb - Packet which is receieved
+ * @Event - Event read from hardware
+ */
+
+void sxg_rcv_checksum(struct adapter_t *adapter, struct sk_buff *skb,
+ struct sxg_event *Event)
+{
+ skb->ip_summed = CHECKSUM_NONE;
+ if (likely(adapter->flags & SXG_RCV_IP_CSUM_ENABLED)) {
+ if (likely(adapter->flags & SXG_RCV_TCP_CSUM_ENABLED)
+ && (Event->Status & EVENT_STATUS_TCPIP)) {
+ if(!(Event->Status & EVENT_STATUS_TCPBAD))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ if(!(Event->Status & EVENT_STATUS_IPBAD))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else if(Event->Status & EVENT_STATUS_IPONLY) {
+ if(!(Event->Status & EVENT_STATUS_IPBAD))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ }
+ }
+}
+
+/*
* sxg_process_event_queue - Process our event queue
*
* Arguments:
@@ -1153,46 +1507,52 @@ static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
* Return Value:
* None.
*/
-static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId)
+static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId,
+ int *sxg_napi_continue, int *work_done, int budget)
{
- struct SXG_EVENT_RING *EventRing = &adapter->EventRings[RssId];
- struct SXG_EVENT *Event = &EventRing->Ring[adapter->NextEvent[RssId]];
+ struct sxg_event_ring *EventRing = &adapter->EventRings[RssId];
+ struct sxg_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;
- struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
+ struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
#endif
u32 ReturnStatus = 0;
+ int sxg_rcv_data_buffers = SXG_RCV_DATA_BUFFERS;
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. */
+ /*
+ * We may still have unprocessed events on the queue if
+ * the card crashed. Don't process them.
+ */
if (adapter->Dead) {
return (0);
}
- /* In theory there should only be a single processor that */
- /* accesses this queue, and only at interrupt-DPC time. So */
- /* we shouldn't need a lock for any of this. */
+ /*
+ * In theory there should only be a single processor that
+ * accesses this queue, and only at interrupt-DPC time. So/
+ * we shouldn't need a lock for any of this.
+ */
while (Event->Status & EVENT_STATUS_VALID) {
+ (*sxg_napi_continue) = 1;
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 */
- /* */
+ /* struct sxg_ring_info Head & Tail == unsigned char */
+ ASSERT(!(Event->CommandIndex & 0xFF00));
sxg_complete_descriptor_blocks(adapter,
Event->CommandIndex);
- /* */
break;
case EVENT_CODE_SLOWRCV:
+ (*work_done)++;
--adapter->RcvBuffersOnCard;
if ((skb = sxg_slow_receive(adapter, Event))) {
u32 rx_bytes;
@@ -1200,51 +1560,61 @@ static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId)
/* 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. */
+ /*
+ * 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);
+ /* CHECK skb_pull(skb, INIC_RCVBUF_HEADSIZE); */
+ /* (rcvbuf->length & IRHDDR_FLEN_MSK); */
+ rx_bytes = Event->Length;
adapter->stats.rx_packets++;
adapter->stats.rx_bytes += rx_bytes;
-#if SXG_OFFLOAD_IP_CHECKSUM
- skb->ip_summed = CHECKSUM_UNNECESSARY;
-#endif
+ sxg_rcv_checksum(adapter, skb, Event);
skb->dev = adapter->netdev;
- skb->protocol = eth_type_trans(skb, skb->dev);
- netif_rx(skb);
+ netif_receive_skb(skb);
#endif
}
break;
default:
DBG_ERROR("%s: ERROR Invalid EventCode %d\n",
__func__, Event->Code);
-/* ASSERT(0); */
+ /* 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) {
+ /*
+ * 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 on 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->JumboEnabled)
+ sxg_rcv_data_buffers = SXG_JUMBO_RCV_DATA_BUFFERS;
+
+ if (adapter->RcvBuffersOnCard < sxg_rcv_data_buffers) {
sxg_stock_rcv_buffers(adapter);
}
- /* It's more efficient to just set this to zero. */
- /* But clearing the top bit saves potential debug info... */
+ /*
+ * It's more efficient to just set this to zero.
+ * But clearing the top bit saves potential debug info...
+ */
Event->Status &= ~EVENT_STATUS_VALID;
- /* Advanct to the next event */
+ /* Advance to the next event */
SXG_ADVANCE_INDEX(adapter->NextEvent[RssId], EVENT_RING_SIZE);
Event = &EventRing->Ring[adapter->NextEvent[RssId]];
EventsProcessed++;
@@ -1253,9 +1623,11 @@ static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId)
WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
EVENT_RING_BATCH, FALSE);
EventsProcessed = 0;
- /* If we've processed our batch limit, break out of the */
- /* loop and return SXG_ISR_EVENT to arrange for us to */
- /* be called again */
+ /*
+ * If we've processed our batch limit, break out of the
+ * loop and return SXG_ISR_EVENT to arrange for us to
+ * be called again
+ */
if (Batches++ == EVENT_BATCH_LIMIT) {
SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
TRACE_NOISY, "EvtLimit", Batches,
@@ -1264,16 +1636,22 @@ static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId)
break;
}
}
+ if (*work_done >= budget) {
+ WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
+ EventsProcessed, FALSE);
+ EventsProcessed = 0;
+ (*sxg_napi_continue) = 0;
+ break;
+ }
}
+ if (!(Event->Status & EVENT_STATUS_VALID))
+ (*sxg_napi_continue) = 0;
+
#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);
@@ -1289,27 +1667,35 @@ static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId)
*
* Arguments -
* adapter - A pointer to our adapter structure
-
* Return
* None
*/
static void sxg_complete_slow_send(struct adapter_t *adapter)
{
- struct SXG_XMT_RING *XmtRing = &adapter->XmtRings[0];
- struct SXG_RING_INFO *XmtRingInfo = &adapter->XmtRingZeroInfo;
+ struct sxg_xmt_ring *XmtRing = &adapter->XmtRings[0];
+ struct sxg_ring_info *XmtRingInfo = &adapter->XmtRingZeroInfo;
u32 *ContextType;
- struct SXG_CMD *XmtCmd;
+ struct sxg_cmd *XmtCmd;
+ unsigned long flags = 0;
+ unsigned long sgl_flags = 0;
+ unsigned int processed_count = 0;
+
+ /*
+ * 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_irqsave(&adapter->XmtZeroLock, flags);
- /* 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 */
+ while ((XmtRingInfo->Tail != *adapter->XmtRingZeroIndex)
+ && processed_count++ < SXG_COMPLETE_SLOW_SEND_LIMIT) {
+ /*
+ * 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",
@@ -1321,30 +1707,45 @@ static void sxg_complete_slow_send(struct adapter_t *adapter)
case SXG_SGL_DUMB:
{
struct sk_buff *skb;
+ struct sxg_scatter_gather *SxgSgl =
+ (struct sxg_scatter_gather *)ContextType;
+ dma64_addr_t FirstSgeAddress;
+ u32 FirstSgeLength;
+
/* Dumb-nic send. Command context is the dumb-nic SGL */
skb = (struct sk_buff *)ContextType;
+ skb = SxgSgl->DumbPacket;
+ FirstSgeAddress = XmtCmd->Buffer.FirstSgeAddress;
+ FirstSgeLength = XmtCmd->Buffer.FirstSgeLength;
/* 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);
+ /*
+ * 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_irqrestore(
+ &adapter->XmtZeroLock, flags);
+
+ SxgSgl->DumbPacket = NULL;
+ SXG_COMPLETE_DUMB_SEND(adapter, skb,
+ FirstSgeAddress,
+ FirstSgeLength);
+ SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL);
/* and reacquire.. */
- spin_lock(&adapter->XmtZeroLock);
+ spin_lock_irqsave(&adapter->XmtZeroLock, flags);
}
break;
default:
ASSERT(0);
}
}
- spin_unlock(&adapter->XmtZeroLock);
+ spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd",
adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
}
@@ -1356,22 +1757,27 @@ static void sxg_complete_slow_send(struct adapter_t *adapter)
* adapter - A pointer to our adapter structure
* Event - Receive event
*
- * Return
- * skb
+ * Return - skb
*/
-static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EVENT *Event)
+static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
+ struct sxg_event *Event)
{
- struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
+ u32 BufferSize = adapter->ReceiveBufferSize;
+ struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
struct sk_buff *Packet;
+ static int read_counter = 0;
- RcvDataBufferHdr = (struct SXG_RCV_DATA_BUFFER_HDR*) Event->HostHandle;
+ RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *) Event->HostHandle;
+ if(read_counter++ & 0x100)
+ {
+ sxg_collect_statistics(adapter);
+ read_counter = 0;
+ }
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);
+ /*RcvDataBufferHdr->VirtualAddress*/ 0);
/* Drop rcv frames in non-running state */
switch (adapter->State) {
case SXG_STATE_RUNNING:
@@ -1385,14 +1791,16 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EV
goto drop;
}
+ /*
+ * memcpy(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
+ * RcvDataBufferHdr->VirtualAddress, Event->Length);
+ */
+
/* 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));
@@ -1400,8 +1808,9 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EV
}
#if XXXTODO /* VLAN stuff */
/* If there's a VLAN tag, extract it and validate it */
- if (((struct ether_header*) (SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)))->
- EtherType == ETHERTYPE_VLAN) {
+ if (((struct ether_header *)
+ (SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)))->EtherType
+ == ETHERTYPE_VLAN) {
if (SxgExtractVlanHeader(adapter, RcvDataBufferHdr, Event) !=
STATUS_SUCCESS) {
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY,
@@ -1412,33 +1821,41 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EV
}
}
#endif
- /* */
/* Dumb-nic frame. See if it passes our mac filter and update stats */
- /* */
- if (!sxg_mac_filter(adapter, (struct ether_header*)
- SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
- Event->Length)) {
+
+ if (!sxg_mac_filter(adapter,
+ (struct 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;
+ Event, SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
+ Event->Length, 0);
+ goto drop;
}
Packet = RcvDataBufferHdr->SxgDumbRcvPacket;
+ SXG_ADJUST_RCV_PACKET(Packet, RcvDataBufferHdr, Event);
+ Packet->protocol = eth_type_trans(Packet, adapter->netdev);
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);
-
+ RcvDataBufferHdr->SxgDumbRcvPacket = NULL;
+ RcvDataBufferHdr->PhysicalAddress = (dma_addr_t)NULL;
+ SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, BufferSize);
+ if (RcvDataBufferHdr->skb)
+ {
+ spin_lock(&adapter->RcvQLock);
+ SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
+ // adapter->RcvBuffersOnCard ++;
+ spin_unlock(&adapter->RcvQLock);
+ }
return (Packet);
drop:
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DropRcv",
RcvDataBufferHdr, Event->Length, 0, 0);
- adapter->Stats.RcvDiscards++;
+ adapter->stats.rx_dropped++;
+// adapter->Stats.RcvDiscards++;
spin_lock(&adapter->RcvQLock);
SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
spin_unlock(&adapter->RcvQLock);
@@ -1453,14 +1870,13 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EV
* adapter - Adapter structure
* ErrorStatus - 4-byte receive error status
*
- * Return Value:
- * None
+ * Return Value : None
*/
static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus)
{
u32 Error;
- adapter->Stats.RcvErrors++;
+ adapter->stats.rx_errors++;
if (ErrorStatus & SXG_RCV_STATUS_TRANSPORT_ERROR) {
Error = ErrorStatus & SXG_RCV_STATUS_TRANSPORT_MASK;
@@ -1532,13 +1948,13 @@ static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus)
* pether - Ethernet header
* length - Frame length
*
- * Return Value:
- * TRUE if the frame is to be allowed
+ * Return Value : TRUE if the frame is to be allowed
*/
-static bool sxg_mac_filter(struct adapter_t *adapter, struct ether_header *EtherHdr,
- ushort length)
+static bool sxg_mac_filter(struct adapter_t *adapter,
+ struct ether_header *EtherHdr, ushort length)
{
bool EqualAddr;
+ struct net_device *dev = adapter->netdev;
if (SXG_MULTICAST_PACKET(EtherHdr)) {
if (SXG_BROADCAST_PACKET(EtherHdr)) {
@@ -1546,8 +1962,6 @@ static bool sxg_mac_filter(struct adapter_t *adapter, struct ether_header *Ether
if (adapter->MacFilter & MAC_BCAST) {
adapter->Stats.DumbRcvBcastPkts++;
adapter->Stats.DumbRcvBcastBytes += length;
- adapter->Stats.DumbRcvPkts++;
- adapter->Stats.DumbRcvBytes += length;
return (TRUE);
}
} else {
@@ -1555,15 +1969,12 @@ static bool sxg_mac_filter(struct adapter_t *adapter, struct ether_header *Ether
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) {
- struct SXG_MULTICAST_ADDRESS *MulticastAddrs =
- adapter->MulticastAddrs;
- while (MulticastAddrs) {
- ETHER_EQ_ADDR(MulticastAddrs->Address,
+ struct dev_mc_list *mclist = dev->mc_list;
+ while (mclist) {
+ ETHER_EQ_ADDR(mclist->da_addr,
EtherHdr->ether_dhost,
EqualAddr);
if (EqualAddr) {
@@ -1571,32 +1982,26 @@ static bool sxg_mac_filter(struct adapter_t *adapter, struct ether_header *Ether
DumbRcvMcastPkts++;
adapter->Stats.
DumbRcvMcastBytes += length;
- adapter->Stats.DumbRcvPkts++;
- adapter->Stats.DumbRcvBytes +=
- length;
return (TRUE);
}
- MulticastAddrs = MulticastAddrs->Next;
+ mclist = mclist->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 */
+ /*
+ * 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);
}
@@ -1627,7 +2032,6 @@ static int sxg_register_interrupt(struct adapter_t *adapter)
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",
__func__, adapter, adapter->netdev->irq);
@@ -1663,12 +2067,12 @@ static void sxg_deregister_interrupt(struct adapter_t *adapter)
*/
static int sxg_if_init(struct adapter_t *adapter)
{
- p_net_device dev = adapter->netdev;
+ struct net_device *dev = adapter->netdev;
int status = 0;
- DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d:%d] flags[%x]\n",
+ DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d] flags[%x]\n",
__func__, adapter->netdev->name,
- adapter->queues_initialized, adapter->state,
+ adapter->state,
adapter->linkstate, dev->flags);
/* adapter should be down at this point */
@@ -1679,31 +2083,31 @@ static int sxg_if_init(struct adapter_t *adapter)
ASSERT(adapter->linkstate == LINK_DOWN);
adapter->devflags_prev = dev->flags;
- adapter->macopts = MAC_DIRECTED;
+ adapter->MacFilter = MAC_DIRECTED;
if (dev->flags) {
DBG_ERROR("sxg: %s (%s) Set MAC options: ", __func__,
adapter->netdev->name);
if (dev->flags & IFF_BROADCAST) {
- adapter->macopts |= MAC_BCAST;
+ adapter->MacFilter |= MAC_BCAST;
DBG_ERROR("BCAST ");
}
if (dev->flags & IFF_PROMISC) {
- adapter->macopts |= MAC_PROMISC;
+ adapter->MacFilter |= MAC_PROMISC;
DBG_ERROR("PROMISC ");
}
if (dev->flags & IFF_ALLMULTI) {
- adapter->macopts |= MAC_ALLMCAST;
+ adapter->MacFilter |= MAC_ALLMCAST;
DBG_ERROR("ALL_MCAST ");
}
if (dev->flags & IFF_MULTICAST) {
- adapter->macopts |= MAC_MCAST;
+ adapter->MacFilter |= MAC_MCAST;
DBG_ERROR("MCAST ");
}
DBG_ERROR("\n");
}
- status = sxg_register_interrupt(adapter);
+ status = sxg_register_intr(adapter);
if (status != STATUS_SUCCESS) {
- DBG_ERROR("sxg_if_init: sxg_register_interrupt FAILED %x\n",
+ DBG_ERROR("sxg_if_init: sxg_register_intr FAILED %x\n",
status);
sxg_deregister_interrupt(adapter);
return (status);
@@ -1711,18 +2115,90 @@ static int sxg_if_init(struct adapter_t *adapter)
adapter->state = ADAPT_UP;
- /*
- * clear any pending events, then enable interrupts
- */
+ /* clear any pending events, then enable interrupts */
DBG_ERROR("sxg: %s ENABLE interrupts(slic)\n", __func__);
return (STATUS_SUCCESS);
}
-static int sxg_entry_open(p_net_device dev)
+void sxg_set_interrupt_aggregation(struct adapter_t *adapter)
+{
+ /*
+ * Top bit disables aggregation on xmt (SXG_AGG_XMT_DISABLE).
+ * Make sure Max is less than 0x8000.
+ */
+ adapter->max_aggregation = SXG_MAX_AGG_DEFAULT;
+ adapter->min_aggregation = SXG_MIN_AGG_DEFAULT;
+ WRITE_REG(adapter->UcodeRegs[0].Aggregation,
+ ((adapter->max_aggregation << SXG_MAX_AGG_SHIFT) |
+ adapter->min_aggregation),
+ TRUE);
+}
+
+static int sxg_entry_open(struct net_device *dev)
{
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
int status;
+ static int turn;
+ int sxg_initial_rcv_data_buffers = SXG_INITIAL_RCV_DATA_BUFFERS;
+ int i;
+
+ if (adapter->JumboEnabled == TRUE) {
+ sxg_initial_rcv_data_buffers =
+ SXG_INITIAL_JUMBO_RCV_DATA_BUFFERS;
+ SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo,
+ SXG_JUMBO_RCV_RING_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)
+ {
+ status = sxg_allocate_buffer_memory(adapter,
+ SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE),
+ SXG_BUFFER_TYPE_RCV);
+ if (status != STATUS_SUCCESS)
+ return status;
+ }
+ /*
+ * 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);
+ }
+ /*
+ * The microcode expects it to be downloaded on every open.
+ */
+ DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __FUNCTION__);
+ if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) {
+ DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
+ __FUNCTION__);
+ sxg_read_config(adapter);
+ } else {
+ adapter->state = ADAPT_FAIL;
+ adapter->linkstate = LINK_DOWN;
+ DBG_ERROR("sxg_download_microcode FAILED status[%x]\n",
+ status);
+ }
+ msleep(5);
+
+ if (turn) {
+ sxg_second_open(adapter->netdev);
+
+ return STATUS_SUCCESS;
+ }
+
+ turn++;
ASSERT(adapter);
DBG_ERROR("sxg: %s adapter->activated[%d]\n", __func__,
@@ -1762,6 +2238,8 @@ static int sxg_entry_open(p_net_device dev)
return (status);
}
DBG_ERROR("sxg: %s ENABLE ALL INTERRUPTS\n", __func__);
+ sxg_set_interrupt_aggregation(adapter);
+ napi_enable(&adapter->napi);
/* Enable interrupts */
SXG_ENABLE_ALL_INTERRUPTS(adapter);
@@ -1772,71 +2250,162 @@ static int sxg_entry_open(p_net_device dev)
return STATUS_SUCCESS;
}
+int sxg_second_open(struct net_device * dev)
+{
+ struct adapter_t *adapter = (struct adapter_t*) netdev_priv(dev);
+ int status = 0;
+
+ spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
+ netif_start_queue(adapter->netdev);
+ adapter->state = ADAPT_UP;
+ adapter->linkstate = LINK_UP;
+
+ status = sxg_initialize_adapter(adapter);
+ sxg_set_interrupt_aggregation(adapter);
+ napi_enable(&adapter->napi);
+ /* Re-enable interrupts */
+ SXG_ENABLE_ALL_INTERRUPTS(adapter);
+
+ sxg_register_intr(adapter);
+ spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
+ mod_timer(&adapter->watchdog_timer, jiffies);
+ 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;
+ u32 mmio_start = 0;
+ u32 mmio_len = 0;
+
+ struct net_device *dev = pci_get_drvdata(pcidev);
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
- ASSERT(adapter);
- DBG_ERROR("sxg: %s ENTER dev[%p] adapter[%p]\n", __func__, dev,
- adapter);
- sxg_deregister_interrupt(adapter);
- sxg_unmap_mmio_space(adapter);
- DBG_ERROR("sxg: %s unregister_netdev\n", __func__);
+ flush_scheduled_work();
+
+ /* Deallocate Resources */
unregister_netdev(dev);
+ sxg_reset_interrupt_capability(adapter);
+ sxg_free_resources(adapter);
- mmio_start = pci_resource_start(pcidev, 0);
- mmio_len = pci_resource_len(pcidev, 0);
+ ASSERT(adapter);
- DBG_ERROR("sxg: %s rel_region(0) start[%x] len[%x]\n", __func__,
- mmio_start, mmio_len);
- release_mem_region(mmio_start, mmio_len);
+ mmio_start = pci_resource_start(pcidev, 0);
+ mmio_len = pci_resource_len(pcidev, 0);
- DBG_ERROR("sxg: %s iounmap dev->base_addr[%x]\n", __func__,
- (unsigned int)dev->base_addr);
- iounmap((char *)dev->base_addr);
+ DBG_ERROR("sxg: %s rel_region(0) start[%x] len[%x]\n", __FUNCTION__,
+ mmio_start, mmio_len);
+ release_mem_region(mmio_start, mmio_len);
+
+ mmio_start = pci_resource_start(pcidev, 2);
+ mmio_len = pci_resource_len(pcidev, 2);
+
+ DBG_ERROR("sxg: %s rel_region(2) start[%x] len[%x]\n", __FUNCTION__,
+ mmio_start, mmio_len);
+ release_mem_region(mmio_start, mmio_len);
+
+ pci_disable_device(pcidev);
DBG_ERROR("sxg: %s deallocate device\n", __func__);
kfree(dev);
DBG_ERROR("sxg: %s EXIT\n", __func__);
}
-static int sxg_entry_halt(p_net_device dev)
+static int sxg_entry_halt(struct net_device *dev)
{
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
+ struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+ int i;
+ u32 RssIds, IsrCount;
+ unsigned long flags;
+ RssIds = SXG_RSS_CPU_COUNT(adapter);
+ IsrCount = adapter->msi_enabled ? RssIds : 1;
+ /* Disable interrupts */
spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
- DBG_ERROR("sxg: %s (%s) ENTER\n", __func__, dev->name);
-
- netif_stop_queue(adapter->netdev);
+ SXG_DISABLE_ALL_INTERRUPTS(adapter);
adapter->state = ADAPT_DOWN;
adapter->linkstate = LINK_DOWN;
+
+ spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
+ sxg_deregister_interrupt(adapter);
+ WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH);
+ mdelay(5000);
+
+ del_timer_sync(&adapter->watchdog_timer);
+ netif_stop_queue(dev);
+ netif_carrier_off(dev);
+
+ napi_disable(&adapter->napi);
+
+ WRITE_REG(adapter->UcodeRegs[0].RcvCmd, 0, true);
adapter->devflags_prev = 0;
DBG_ERROR("sxg: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n",
__func__, dev->name, adapter, adapter->state);
- DBG_ERROR("sxg: %s (%s) EXIT\n", __func__, dev->name);
- DBG_ERROR("sxg: %s EXIT\n", __func__);
- spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
+ spin_lock(&adapter->RcvQLock);
+ /* Free all the blocks and the buffers, moved from remove() routine */
+ if (!(IsListEmpty(&adapter->AllRcvBlocks))) {
+ sxg_free_rcvblocks(adapter);
+ }
+
+
+ InitializeListHead(&adapter->FreeRcvBuffers);
+ InitializeListHead(&adapter->FreeRcvBlocks);
+ InitializeListHead(&adapter->AllRcvBlocks);
+ InitializeListHead(&adapter->FreeSglBuffers);
+ InitializeListHead(&adapter->AllSglBuffers);
+
+ adapter->FreeRcvBufferCount = 0;
+ adapter->FreeRcvBlockCount = 0;
+ adapter->AllRcvBlockCount = 0;
+ adapter->RcvBuffersOnCard = 0;
+ adapter->PendingRcvCount = 0;
+
+ memset(adapter->RcvRings, 0, sizeof(struct sxg_rcv_ring) * 1);
+ memset(adapter->EventRings, 0, sizeof(struct sxg_event_ring) * RssIds);
+ memset(adapter->Isr, 0, sizeof(u32) * IsrCount);
+ for (i = 0; i < SXG_MAX_RING_SIZE; i++)
+ adapter->RcvRingZeroInfo.Context[i] = NULL;
+ SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo, SXG_RCV_RING_SIZE);
+ SXG_INITIALIZE_RING(adapter->XmtRingZeroInfo, SXG_XMT_RING_SIZE);
+
+ spin_unlock(&adapter->RcvQLock);
+
+ spin_lock_irqsave(&adapter->XmtZeroLock, flags);
+ adapter->AllSglBufferCount = 0;
+ adapter->FreeSglBufferCount = 0;
+ adapter->PendingXmtCount = 0;
+ memset(adapter->XmtRings, 0, sizeof(struct sxg_xmt_ring) * 1);
+ memset(adapter->XmtRingZeroIndex, 0, sizeof(u32));
+ spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
+
+ for (i = 0; i < SXG_MAX_RSS; i++) {
+ adapter->NextEvent[i] = 0;
+ }
+ atomic_set(&adapter->pending_allocations, 0);
+ adapter->intrregistered = 0;
+ sxg_remove_isr(adapter);
+ DBG_ERROR("sxg: %s (%s) EXIT\n", __FUNCTION__, dev->name);
return (STATUS_SUCCESS);
}
-static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd)
+static int sxg_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
ASSERT(rq);
-/* DBG_ERROR("sxg: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev); */
+/* DBG_ERROR("sxg: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev);*/
switch (cmd) {
case SIOCSLICSETINTAGG:
{
-/* struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); */
+ /* struct adapter_t *adapter = (struct 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");
+ DBG_ERROR("copy_from_user FAILED getting \
+ initial params\n");
return -EFAULT;
}
intagg = data[0];
@@ -1847,7 +2416,7 @@ static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd)
}
default:
-/* DBG_ERROR("sxg: %s UNSUPPORTED[%x]\n", __func__, cmd); */
+ /* DBG_ERROR("sxg: %s UNSUPPORTED[%x]\n", __func__, cmd); */
return -EOPNOTSUPP;
}
return 0;
@@ -1856,23 +2425,25 @@ static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd)
#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
+ * 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)
+static int sxg_send_packets(struct sk_buff *skb, struct net_device *dev)
{
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
u32 status = STATUS_SUCCESS;
- DBG_ERROR("sxg: %s ENTER sxg_send_packets skb[%p]\n", __func__,
- skb);
+ /*
+ * DBG_ERROR("sxg: %s ENTER sxg_send_packets skb[%p]\n", __FUNCTION__,
+ * skb);
+ */
+
/* Check the adapter state */
switch (adapter->State) {
case SXG_STATE_INITIALIZING:
@@ -1909,17 +2480,18 @@ static int sxg_send_packets(struct sk_buff *skb, p_net_device dev)
/* reject & complete all the packets if they cant be sent */
if (status != STATUS_SUCCESS) {
#if XXXTODO
-/* sxg_send_packets_fail(adapter, skb, status); */
+ /* sxg_send_packets_fail(adapter, skb, status); */
#else
SXG_DROP_DUMB_SEND(adapter, skb);
adapter->stats.tx_dropped++;
+ return NETDEV_TX_BUSY;
#endif
}
DBG_ERROR("sxg: %s EXIT sxg_send_packets status[%x]\n", __func__,
status);
xmit_done:
- return 0;
+ return NETDEV_TX_OK;
}
/*
@@ -1931,33 +2503,35 @@ static int sxg_send_packets(struct sk_buff *skb, p_net_device dev)
* adapter - Pointer to our adapter structure
* skb - The packet to be sent
*
- * Return -
- * STATUS of send
+ * Return - STATUS of send
*/
static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb)
{
- struct SCATTER_GATHER_LIST *pSgl;
- struct SXG_SCATTER_GATHER *SxgSgl;
- void *SglBuffer;
- u32 SglBufferLength;
+ struct sxg_x64_sgl *pSgl;
+ struct sxg_scatter_gather *SxgSgl;
+ unsigned long sgl_flags;
+ /* void *SglBuffer; */
+ /* u32 SglBufferLength; */
- /* The vast majority of work is done in the shared */
- /* sxg_dumb_sgl routine. */
+ /*
+ * The vast majority of work is done in the shared
+ * sxg_dumb_sgl routine.
+ */
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSend",
adapter, skb, 0, 0);
/* Allocate a SGL buffer */
- SXG_GET_SGL_BUFFER(adapter, SxgSgl);
+ SXG_GET_SGL_BUFFER(adapter, SxgSgl, 0);
if (!SxgSgl) {
adapter->Stats.NoSglBuf++;
- adapter->Stats.XmtErrors++;
+ adapter->stats.tx_errors++;
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;
+ /*SglBuffer = SXG_SGL_BUFFER(SxgSgl);
+ SglBufferLength = SXG_SGL_BUF_SIZE; */
SxgSgl->VlanTag.VlanTci = 0;
SxgSgl->VlanTag.VlanTpid = 0;
SxgSgl->Type = SXG_SGL_DUMB;
@@ -1965,9 +2539,7 @@ static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *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);
+ return (sxg_dumb_sgl(pSgl, SxgSgl));
}
/*
@@ -1975,24 +2547,27 @@ static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb)
*
* Arguments:
* pSgl -
- * SxgSgl - SXG_SCATTER_GATHER
+ * SxgSgl - struct sxg_scatter_gather
*
* Return Value:
- * None.
+ * Status of send operation.
*/
-static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GATHER *SxgSgl)
+static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
+ struct sxg_scatter_gather *SxgSgl)
{
struct adapter_t *adapter = SxgSgl->adapter;
struct sk_buff *skb = SxgSgl->DumbPacket;
/* For now, all dumb-nic sends go on RSS queue zero */
- struct SXG_XMT_RING *XmtRing = &adapter->XmtRings[0];
- struct SXG_RING_INFO *XmtRingInfo = &adapter->XmtRingZeroInfo;
- struct SXG_CMD *XmtCmd = NULL;
-/* u32 Index = 0; */
+ struct sxg_xmt_ring *XmtRing = &adapter->XmtRings[0];
+ struct sxg_ring_info *XmtRingInfo = &adapter->XmtRingZeroInfo;
+ struct sxg_cmd *XmtCmd = NULL;
+ /* u32 Index = 0; */
u32 DataLength = skb->len;
-/* unsigned int BufLen; */
-/* u32 SglOffset; */
+ /* unsigned int BufLen; */
+ /* u32 SglOffset; */
u64 phys_addr;
+ unsigned long flags;
+ unsigned long queue_id=0;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl",
pSgl, SxgSgl, 0, 0);
@@ -2001,25 +2576,67 @@ static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GA
SxgSgl->pSgl = pSgl;
/* Sanity check that our SGL format is as we expect. */
- ASSERT(sizeof(SXG_X64_SGE) == sizeof(SCATTER_GATHER_ELEMENT));
+ ASSERT(sizeof(struct sxg_x64_sge) == sizeof(struct sxg_x64_sge));
/* Shouldn't be a vlan tag on this frame */
ASSERT(SxgSgl->VlanTag.VlanTci == 0);
ASSERT(SxgSgl->VlanTag.VlanTpid == 0);
- /* From here below we work with the SGL placed in our */
- /* buffer. */
+ /*
+ * From here below we work with the SGL placed in our
+ * buffer.
+ */
SxgSgl->Sgl.NumberOfElements = 1;
+ /*
+ * Set ucode Queue ID based on bottom bits of destination TCP port.
+ * This Queue ID splits slowpath/dumb-nic packet processing across
+ * multiple threads on the card to improve performance. It is split
+ * using the TCP port to avoid out-of-order packets that can result
+ * from multithreaded processing. We use the destination port because
+ * we expect to be run on a server, so in nearly all cases the local
+ * port is likely to be constant (well-known server port) and the
+ * remote port is likely to be random. The exception to this is iSCSI,
+ * in which case we use the sport instead. Note
+ * that original attempt at XOR'ing source and dest port resulted in
+ * poor balance on NTTTCP/iometer applications since they tend to
+ * line up (even-even, odd-odd..).
+ */
+
+ if (skb->protocol == htons(ETH_P_IP)) {
+ struct iphdr *ip;
+
+ ip = ip_hdr(skb);
+ if ((ip->protocol == IPPROTO_TCP)&&(DataLength >= sizeof(
+ struct tcphdr))){
+ queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ?
+ (ntohs (tcp_hdr(skb)->source) &
+ SXG_LARGE_SEND_QUEUE_MASK):
+ (ntohs(tcp_hdr(skb)->dest) &
+ SXG_LARGE_SEND_QUEUE_MASK));
+ }
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ if ((ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) && (DataLength >=
+ sizeof(struct tcphdr)) ) {
+ queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ?
+ (ntohs (tcp_hdr(skb)->source) &
+ SXG_LARGE_SEND_QUEUE_MASK):
+ (ntohs(tcp_hdr(skb)->dest) &
+ SXG_LARGE_SEND_QUEUE_MASK));
+ }
+ }
/* Grab the spinlock and acquire a command */
- spin_lock(&adapter->XmtZeroLock);
+ spin_lock_irqsave(&adapter->XmtZeroLock, flags);
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);
+ /*
+ * Call sxg_complete_slow_send to see if we can
+ * free up any XmtRingZero entries and then try again
+ */
+
+ spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
sxg_complete_slow_send(adapter);
- spin_lock(&adapter->XmtZeroLock);
+ spin_lock_irqsave(&adapter->XmtZeroLock, flags);
SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
if (XmtCmd == NULL) {
adapter->Stats.XmtZeroFull++;
@@ -2029,8 +2646,8 @@ static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GA
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd",
XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
/* Update stats */
- adapter->Stats.DumbXmtPkts++;
- adapter->Stats.DumbXmtBytes += DataLength;
+ adapter->stats.tx_packets++;
+ adapter->stats.tx_bytes += DataLength;
#if XXXTODO /* Stats stuff */
if (SXG_MULTICAST_PACKET(EtherHdr)) {
if (SXG_BROADCAST_PACKET(EtherHdr)) {
@@ -2045,70 +2662,92 @@ static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GA
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,
+ /*
+ * 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; */
+
+ /*
+ * SAHARA SGL WORKAROUND
+ * See if the SGL straddles a 64k boundary. If so, skip to
+ * the start of the next 64k boundary and continue
+ */
+
+ if ((adapter->asictype == SAHARA_REV_A) &&
+ (SXG_INVALID_SGL(phys_addr,skb->data_len)))
+ {
+ spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
+ /* Silently drop this packet */
+ printk(KERN_EMERG"Dropped a packet for 64k boundary problem\n");
+ return STATUS_SUCCESS;
+ }
+ memset(XmtCmd, '\0', sizeof(*XmtCmd));
+ XmtCmd->Buffer.FirstSgeAddress = phys_addr;
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->SgEntries = 1;
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);
- /* */
- /* */
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ /*
+ * We need to set the Checkum in IP header to 0. This is
+ * required by hardware.
+ */
+ ip_hdr(skb)->check = 0x0;
+ XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_IP;
+ XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_TCP;
+ /* Dont know if length will require a change in case of VLAN */
+ XmtCmd->CsumFlags.MacLen = ETH_HLEN;
+ XmtCmd->CsumFlags.IpHl = skb_network_header_len(skb) >>
+ SXG_NW_HDR_LEN_SHIFT;
+ }
+ /*
+ * 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.
+ * Top 16 bits specify queue_id. See comments about queue_id above
+ */
+ /* Four queues at the moment */
+ ASSERT((queue_id & ~SXG_LARGE_SEND_QUEUE_MASK) == 0);
+ WRITE_REG(adapter->UcodeRegs[0].XmtCmd, ((queue_id << 16) | 1), TRUE);
adapter->Stats.XmtQLen++; /* Stats within lock */
- spin_unlock(&adapter->XmtZeroLock);
+ spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2",
XmtCmd, pSgl, SxgSgl, 0);
- return;
+ return STATUS_SUCCESS;
abortcmd:
- /* NOTE - Only jump to this label AFTER grabbing the */
- /* XmtZeroLock, and DO NOT DROP IT between the */
- /* command allocation and the following abort. */
+ /*
+ * NOTE - Only jump to this label AFTER grabbing the
+ * XmtZeroLock, and DO NOT DROP IT between the
+ * command allocation and the following abort.
+ */
if (XmtCmd) {
SXG_ABORT_CMD(XmtRingInfo);
}
- spin_unlock(&adapter->XmtZeroLock);
+ spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
-/* failsgl: */
- /* Jump to this label if failure occurs before the */
- /* XmtZeroLock is grabbed */
- adapter->Stats.XmtErrors++;
+/*
+ * failsgl:
+ * Jump to this label if failure occurs before the
+ * XmtZeroLock is grabbed
+ */
+ adapter->stats.tx_errors++;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumSGFal",
pSgl, SxgSgl, XmtRingInfo->Head, XmtRingInfo->Tail);
+ /* SxgSgl->DumbPacket is the skb */
+ // SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket);
- SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket); /* SxgSgl->DumbPacket is the skb */
+ return STATUS_FAILURE;
}
-/***************************************************************
- * Link management functions
- ***************************************************************/
-
/*
+ * Link management functions
+ *
* sxg_initialize_link - Initialize the link stuff
*
* Arguments -
@@ -2119,10 +2758,11 @@ static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GA
*/
static int sxg_initialize_link(struct adapter_t *adapter)
{
- struct SXG_HW_REGS *HwRegs = adapter->HwRegs;
+ struct sxg_hw_regs *HwRegs = adapter->HwRegs;
u32 Value;
u32 ConfigData;
u32 MaxFrame;
+ u32 AxgMacReg1;
int status;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitLink",
@@ -2140,15 +2780,17 @@ static int sxg_initialize_link(struct adapter_t *adapter)
/* 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;
+ /*
+ * 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);
+ 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);
@@ -2167,47 +2809,76 @@ static int sxg_initialize_link(struct adapter_t *adapter)
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);
+ AxgMacReg1 = ( /* Enable XMT */
+ AXGMAC_CFG1_XMT_EN |
+ /* Enable receive */
+ AXGMAC_CFG1_RCV_EN |
+ /* short frame detection */
+ AXGMAC_CFG1_SHORT_ASSERT |
+ /* Verify frame length */
+ AXGMAC_CFG1_CHECK_LEN |
+ /* Generate FCS */
+ AXGMAC_CFG1_GEN_FCS |
+ /* Pad frames to 64 bytes */
+ AXGMAC_CFG1_PAD_64);
+
+ if (adapter->XmtFcEnabled) {
+ AxgMacReg1 |= AXGMAC_CFG1_XMT_PAUSE; /* Allow sending of pause */
+ }
+ if (adapter->RcvFcEnabled) {
+ AxgMacReg1 |= AXGMAC_CFG1_RCV_PAUSE; /* Enable detection of pause */
+ }
+
+ WRITE_REG(HwRegs->MacConfig1, AxgMacReg1, 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);
+ /*
+ * 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.
+ */
+ if (adapter->asictype == SAHARA_REV_B) {
+ WRITE_REG(HwRegs->MacAmiimConfig, 0x0000001F, TRUE);
+ } else {
+ 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);
+ (LS_PHY_CLR_RESET |
+ LS_XGXS_ENABLE |
+ LS_XGXS_CTL |
+ LS_PHY_CLK_EN |
+ LS_ATTN_ALARM),
+ TRUE);
DBG_ERROR("After Power Up and enable PHY in sxg_initialize_link\n");
- /* Per information given by Aeluros, wait 100 ms after removing reset. */
- /* It's not enough to wait for the self-clearing reset bit in reg 0 to clear. */
+ /*
+ * Per information given by Aeluros, wait 100 ms after removing reset.
+ * It's not enough to wait for the self-clearing reset bit in reg 0 to
+ * clear.
+ */
mdelay(100);
- /* Verify the PHY has come up by checking that the Reset bit has cleared. */
- status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
- PHY_PMA_CONTROL1, /* PMA/PMD control register */
- &Value);
+ /* 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);
+ DBG_ERROR("After sxg_read_mdio_reg Value[%x] fail=%x\n", Value,
+ (Value & PMA_CONTROL1_RESET));
if (status != STATUS_SUCCESS)
return (STATUS_FAILURE);
if (Value & PMA_CONTROL1_RESET) /* reset complete if bit is 0 */
@@ -2228,16 +2899,26 @@ static int sxg_initialize_link(struct adapter_t *adapter)
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 */
+
+ /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module
+ * LASI_CONTROL - LASI control register
+ * LASI_CTL_LS_ALARM_ENABLE - enable link alarm bit
+ */
+ status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+ LASI_CONTROL,
+ LASI_CTL_LS_ALARM_ENABLE);
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 */
+
+ /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module
+ * LASI_CONTROL - LASI control register
+ */
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+ LASI_CONTROL,
&Value);
+
if (status != STATUS_SUCCESS)
return (STATUS_FAILURE);
if (!(Value & LASI_CTL_LS_ALARM_ENABLE)) {
@@ -2253,6 +2934,11 @@ static int sxg_initialize_link(struct adapter_t *adapter)
RCV_CONFIG_TZIPV4 |
RCV_CONFIG_HASH_16 |
RCV_CONFIG_SOCKET | RCV_CONFIG_BUFSIZE(MaxFrame));
+
+ if (adapter->asictype == SAHARA_REV_B) {
+ ConfigData |= (RCV_CONFIG_HIPRICTL |
+ RCV_CONFIG_NEWSTATUSFMT);
+ }
WRITE_REG(HwRegs->RcvConfig, ConfigData, TRUE);
WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_ENABLE, TRUE);
@@ -2277,21 +2963,25 @@ static int sxg_initialize_link(struct adapter_t *adapter)
static int sxg_phy_init(struct adapter_t *adapter)
{
u32 Value;
- struct PHY_UCODE *p;
+ struct phy_ucode *p;
int status;
DBG_ERROR("ENTER %s\n", __func__);
- /* Read a register to identify the PHY type */
- status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
- 0xC205, /* PHY ID register (?) */
- &Value); /* XXXTODO - add def */
+ /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module
+ * 0xC205 - PHY ID register (?)
+ * &Value - XXXTODO - add def
+ */
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+ 0xC205,
+ &Value);
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");
+ 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++) {
@@ -2299,10 +2989,13 @@ static int sxg_phy_init(struct adapter_t *adapter)
/* if address == 0, data == sleep time in ms */
mdelay(p->Data);
} else {
- /* write the given data to the specified address */
- status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
- p->Addr, /* PHY address */
- p->Data); /* PHY data */
+ /* write the given data to the specified address */
+ status = sxg_write_mdio_reg(adapter,
+ MIIM_DEV_PHY_PMA,
+ /* PHY address */
+ p->Addr,
+ /* PHY data */
+ p->Data);
if (status != STATUS_SUCCESS)
return (STATUS_FAILURE);
}
@@ -2324,11 +3017,14 @@ static int sxg_phy_init(struct adapter_t *adapter)
*/
static void sxg_link_event(struct adapter_t *adapter)
{
- struct SXG_HW_REGS *HwRegs = adapter->HwRegs;
+ struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+ struct net_device *netdev = adapter->netdev;
enum SXG_LINK_STATE LinkState;
int status;
u32 Value;
+ if (adapter->state == ADAPT_DOWN)
+ return;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "LinkEvnt",
adapter, 0, 0, 0);
DBG_ERROR("ENTER %s\n", __func__);
@@ -2336,35 +3032,57 @@ static void sxg_link_event(struct adapter_t *adapter)
/* Check the Link Status register. We should have a Link Alarm. */
READ_REG(HwRegs->LinkStatus, Value);
if (Value & LS_LINK_ALARM) {
- /* We got a Link Status alarm. First, pause to let the */
- /* link state settle (it can bounce a number of times) */
+ /*
+ * We got a Link Status alarm. First, pause to let the
+ * link state settle (it can bounce a number of times)
+ */
mdelay(10);
/* Now clear the alarm by reading the LASI status register. */
- status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
- LASI_STATUS, /* LASI status register */
+ /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module */
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+ /* LASI status register */
+ LASI_STATUS,
&Value);
if (status != STATUS_SUCCESS) {
DBG_ERROR("Error reading LASI Status MDIO register!\n");
sxg_link_state(adapter, SXG_LINK_DOWN);
-/* ASSERT(0); */
+ /* ASSERT(0); */
}
- ASSERT(Value & LASI_STATUS_LS_ALARM);
+ /*
+ * We used to assert that the LASI_LS_ALARM bit was set, as
+ * it should be. But there appears to be cases during
+ * initialization (when the PHY is reset and re-initialized)
+ * when we get a link alarm, but the status bit is 0 when we
+ * read it. Rather than trying to assure this never happens
+ * (and nver being certain), just ignore it.
+
+ * 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"));
+ if (LinkState == SXG_LINK_UP) {
+ netif_carrier_on(netdev);
+ netif_tx_start_all_queues(netdev);
+ } else {
+ netif_tx_stop_all_queues(netdev);
+ netif_carrier_off(netdev);
+ }
} else {
- /* XXXTODO - Assuming Link Attention is only being generated for the */
- /* Link Alarm pin (and not for a XAUI Link Status change), then it's */
- /* impossible to get here. Yet we've gotten here twice (under extreme */
- /* conditions - bouncing the link up and down many times a second). */
- /* Needs further investigation. */
+ /*
+ * XXXTODO - Assuming Link Attention is only being generated
+ * for the Link Alarm pin (and not for a XAUI Link Status change)
+ * , then it's impossible to get here. Yet we've gotten here
+ * twice (under extreme conditions - bouncing the link up and
+ * down many times a second). Needs further investigation.
+ */
DBG_ERROR("SXG: sxg_link_event: Can't get here!\n");
DBG_ERROR("SXG: Link Status == 0x%08X.\n", Value);
-/* ASSERT(0); */
+ /* ASSERT(0); */
}
DBG_ERROR("EXIT %s\n", __func__);
@@ -2389,10 +3107,15 @@ static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter)
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "GetLink",
adapter, 0, 0, 0);
- /* Per the Xenpak spec (and the IEEE 10Gb spec?), the link is up if */
- /* the following 3 bits (from 3 different MDIO registers) are all true. */
- status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
- PHY_PMA_RCV_DET, /* PMA/PMD Receive Signal Detect register */
+ /*
+ * Per the Xenpak spec (and the IEEE 10Gb spec?), the link is up if
+ * the following 3 bits (from 3 different MDIO registers) are all true.
+ */
+
+ /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module */
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+ /* PMA/PMD Receive Signal Detect register */
+ PHY_PMA_RCV_DET,
&Value);
if (status != STATUS_SUCCESS)
goto bad;
@@ -2401,8 +3124,10 @@ static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter)
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 */
+ /* MIIM_DEV_PHY_PCS - PHY PCS module */
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PCS,
+ /* PCS 10GBASE-R Status 1 register */
+ PHY_PCS_10G_STATUS1,
&Value);
if (status != STATUS_SUCCESS)
goto bad;
@@ -2411,8 +3136,9 @@ static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter)
if (!(Value & PCS_10B_BLOCK_LOCK))
return (SXG_LINK_DOWN);
- status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_XS, /* PHY XS module */
- PHY_XS_LANE_STATUS, /* XS Lane Status register */
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_XS,/* PHY XS module */
+ /* XS Lane Status register */
+ PHY_XS_LANE_STATUS,
&Value);
if (status != STATUS_SUCCESS)
goto bad;
@@ -2427,7 +3153,7 @@ static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter)
return (SXG_LINK_UP);
bad:
- /* An error occurred reading an MDIO register. This shouldn't happen. */
+ /* An error occurred reading an MDIO register. This shouldn't happen. */
DBG_ERROR("Error reading an MDIO register!\n");
ASSERT(0);
return (SXG_LINK_DOWN);
@@ -2448,6 +3174,37 @@ static void sxg_indicate_link_state(struct adapter_t *adapter,
}
/*
+ * sxg_change_mtu - Change the Maximum Transfer Unit
+ * * @returns 0 on success, negative on failure
+ */
+int sxg_change_mtu (struct net_device *netdev, int new_mtu)
+{
+ struct adapter_t *adapter = (struct adapter_t *) netdev_priv(netdev);
+
+ if (!((new_mtu == SXG_DEFAULT_MTU) || (new_mtu == SXG_JUMBO_MTU)))
+ return -EINVAL;
+
+ if(new_mtu == netdev->mtu)
+ return 0;
+
+ netdev->mtu = new_mtu;
+
+ if (new_mtu == SXG_JUMBO_MTU) {
+ adapter->JumboEnabled = TRUE;
+ adapter->FrameSize = JUMBOMAXFRAME;
+ adapter->ReceiveBufferSize = SXG_RCV_JUMBO_BUFFER_SIZE;
+ } else {
+ adapter->JumboEnabled = FALSE;
+ adapter->FrameSize = ETHERMAXFRAME;
+ adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE;
+ }
+
+ sxg_entry_halt(netdev);
+ sxg_entry_open(netdev);
+ return 0;
+}
+
+/*
* 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
@@ -2460,27 +3217,32 @@ static void sxg_indicate_link_state(struct adapter_t *adapter,
* Return
* None
*/
-static void sxg_link_state(struct adapter_t *adapter, enum SXG_LINK_STATE LinkState)
+static void sxg_link_state(struct adapter_t *adapter,
+ enum SXG_LINK_STATE LinkState)
{
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "LnkINDCT",
adapter, LinkState, adapter->LinkState, adapter->State);
DBG_ERROR("ENTER %s\n", __func__);
- /* Hold the adapter lock during this routine. Maybe move */
- /* the lock to the caller. */
- spin_lock(&adapter->AdapterLock);
+ /*
+ * Hold the adapter lock during this routine. Maybe move
+ * the lock to the caller.
+ */
+ /* IMP TODO : Check if we can survive without taking this lock */
+// spin_lock(&adapter->AdapterLock);
if (LinkState == adapter->LinkState) {
/* Nothing changed.. */
- spin_unlock(&adapter->AdapterLock);
- DBG_ERROR("EXIT #0 %s\n", __func__);
+// spin_unlock(&adapter->AdapterLock);
+ DBG_ERROR("EXIT #0 %s. Link status = %d\n",
+ __func__, LinkState);
return;
}
/* Save the adapter state */
adapter->LinkState = LinkState;
/* Drop the lock and indicate link state */
- spin_unlock(&adapter->AdapterLock);
+// spin_unlock(&adapter->AdapterLock);
DBG_ERROR("EXIT #1 %s\n", __func__);
sxg_indicate_link_state(adapter, LinkState);
@@ -2501,14 +3263,16 @@ static void sxg_link_state(struct adapter_t *adapter, enum SXG_LINK_STATE LinkSt
static int sxg_write_mdio_reg(struct adapter_t *adapter,
u32 DevAddr, u32 RegAddr, u32 Value)
{
- struct SXG_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) */
+ struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+ /* Address operation (written to MIIM field reg) */
+ u32 AddrOp;
+ /* Write operation (written to MIIM field reg) */
+ u32 WriteOp;
+ u32 Cmd;/* Command (written to MIIM command reg) */
u32 ValueRead;
u32 Timeout;
-/* DBG_ERROR("ENTER %s\n", __func__); */
+ /* DBG_ERROR("ENTER %s\n", __func__); */
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
adapter, 0, 0, 0);
@@ -2571,7 +3335,7 @@ static int sxg_write_mdio_reg(struct adapter_t *adapter,
}
} while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
-/* DBG_ERROR("EXIT %s\n", __func__); */
+ /* DBG_ERROR("EXIT %s\n", __func__); */
return (STATUS_SUCCESS);
}
@@ -2583,7 +3347,7 @@ static int sxg_write_mdio_reg(struct adapter_t *adapter,
* 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
+ * pValue - pointer to where to put data read from the MDIO register
*
* Return
* status
@@ -2591,16 +3355,16 @@ static int sxg_write_mdio_reg(struct adapter_t *adapter,
static int sxg_read_mdio_reg(struct adapter_t *adapter,
u32 DevAddr, u32 RegAddr, u32 *pValue)
{
- struct SXG_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) */
+ struct sxg_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", __func__); */
+ DBG_ERROR("ENTER %s\n", __FUNCTION__);
/* Ensure values don't exceed field width */
DevAddr &= 0x001F; /* 5-bit field */
@@ -2636,6 +3400,8 @@ static int sxg_read_mdio_reg(struct adapter_t *adapter,
udelay(100); /* Timeout in 100us units */
READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
if (--Timeout == 0) {
+ DBG_ERROR("EXIT %s with STATUS_FAILURE 1\n", __FUNCTION__);
+
return (STATUS_FAILURE);
}
} while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
@@ -2655,6 +3421,8 @@ static int sxg_read_mdio_reg(struct adapter_t *adapter,
udelay(100); /* Timeout in 100us units */
READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
if (--Timeout == 0) {
+ DBG_ERROR("EXIT %s with STATUS_FAILURE 2\n", __FUNCTION__);
+
return (STATUS_FAILURE);
}
} while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
@@ -2663,7 +3431,7 @@ static int sxg_read_mdio_reg(struct adapter_t *adapter,
READ_REG(HwRegs->MacAmiimField, *pValue);
*pValue &= 0xFFFF; /* data is in the lower 16 bits */
-/* DBG_ERROR("EXIT %s\n", __func__); */
+ DBG_ERROR("EXIT %s\n", __FUNCTION__);
return (STATUS_SUCCESS);
}
@@ -2672,22 +3440,21 @@ static int sxg_read_mdio_reg(struct adapter_t *adapter,
* 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.
+ * 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_table[256];/* Table of CRC's for all possible byte values */
+static u32 sxg_crc_init; /* Is table initialized */
-/*
- * Contruct the CRC32 table
- */
+/* 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 */
+ 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 };
@@ -2705,8 +3472,6 @@ static void sxg_mcast_init_crc32(void)
}
}
-#if XXXTODO
-static u32 sxg_crc_init; /* Is table initialized */
/*
* Return the MAC hast as described above.
*/
@@ -2737,25 +3502,31 @@ static unsigned char sxg_mcast_get_mac_hash(char *macaddr)
static void sxg_mcast_set_mask(struct adapter_t *adapter)
{
- struct SXG_UCODE_REGS *sxg_regs = adapter->UcodeRegs;
+ struct sxg_ucode_regs *sxg_regs = adapter->UcodeRegs;
- DBG_ERROR("%s ENTER (%s) macopts[%x] mask[%llx]\n", __func__,
+ DBG_ERROR("%s ENTER (%s) MacFilter[%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.
+ /*
+ * Turn on all multicast addresses. We have to do this for
+ * promiscuous mode as well as ALLMCAST mode. It saves the
+ * Microcode from having keep state about the MAC configuration
+ */
+ /* DBG_ERROR("sxg: %s MacFilter = MAC_ALLMCAST | MAC_PROMISC\n \
+ * SLUT MODE!!!\n",__func__);
*/
-/* DBG_ERROR("sxg: %s macopts = MAC_ALLMCAST | MAC_PROMISC\n SLUT MODE!!!\n",__func__); */
WRITE_REG(sxg_regs->McastLow, 0xFFFFFFFF, FLUSH);
WRITE_REG(sxg_regs->McastHigh, 0xFFFFFFFF, FLUSH);
-/* DBG_ERROR("%s (%s) WRITE to slic_regs slic_mcastlow&high 0xFFFFFFFF\n",__func__, adapter->netdev->name); */
+ /* DBG_ERROR("%s (%s) WRITE to slic_regs slic_mcastlow&high \
+ * 0xFFFFFFFF\n",__func__, adapter->netdev->name);
+ */
} else {
- /* Commit our multicast mast to the SLIC by writing to the multicast
- * address mask registers
+ /*
+ * Commit our multicast mast to the SLIC by writing to the
+ * multicast address mask registers
*/
DBG_ERROR("%s (%s) WRITE mcastlow[%lx] mcasthigh[%lx]\n",
__func__, adapter->netdev->name,
@@ -2771,38 +3542,6 @@ static void sxg_mcast_set_mask(struct adapter_t *adapter)
}
}
-/*
- * Allocate a mcast_address structure to hold the multicast address.
- * Link it in.
- */
-static int sxg_mcast_add_list(struct adapter_t *adapter, char *address)
-{
- p_mcast_address_t mcaddr, mlist;
- bool equaladdr;
-
- /* Check to see if it already exists */
- mlist = adapter->mcastaddrs;
- while (mlist) {
- ETHER_EQ_ADDR(mlist->address, address, equaladdr);
- if (equaladdr) {
- return (STATUS_SUCCESS);
- }
- mlist = mlist->next;
- }
-
- /* Doesn't already exist. Allocate a structure to hold it */
- mcaddr = kmalloc(sizeof(mcast_address_t), GFP_ATOMIC);
- if (mcaddr == NULL)
- return 1;
-
- memcpy(mcaddr->address, address, 6);
-
- mcaddr->next = adapter->mcastaddrs;
- adapter->mcastaddrs = mcaddr;
-
- return (STATUS_SUCCESS);
-}
-
static void sxg_mcast_set_bit(struct adapter_t *adapter, char *address)
{
unsigned char crcpoly;
@@ -2810,7 +3549,8 @@ static void sxg_mcast_set_bit(struct adapter_t *adapter, char *address)
/* 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
+ /*
+ * We only have space on the SLIC for 64 entries. Lop
* off the top two bits. (2^6 = 64)
*/
crcpoly &= 0x3F;
@@ -2819,76 +3559,119 @@ static void sxg_mcast_set_bit(struct adapter_t *adapter, char *address)
adapter->MulticastMask |= (u64) 1 << crcpoly;
}
-static void sxg_mcast_set_list(p_net_device dev)
+/*
+ * Function takes MAC addresses from dev_mc_list and generates the Mask
+ */
+
+static void sxg_set_mcast_addr(struct adapter_t *adapter)
+{
+ struct dev_mc_list *mclist;
+ struct net_device *dev = adapter->netdev;
+ int i;
+
+ if (adapter->MacFilter & (MAC_ALLMCAST | MAC_MCAST)) {
+ for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
+ i++, mclist = mclist->next) {
+ sxg_mcast_set_bit(adapter,mclist->da_addr);
+ }
+ }
+ sxg_mcast_set_mask(adapter);
+}
+
+static void sxg_mcast_set_list(struct net_device *dev)
{
struct adapter_t *adapter = (struct 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);
+ if (dev->flags & IFF_PROMISC)
+ adapter->MacFilter |= MAC_PROMISC;
+ if (dev->flags & IFF_MULTICAST)
+ adapter->MacFilter |= MAC_MCAST;
+ if (dev->flags & IFF_ALLMULTI)
+ adapter->MacFilter |= MAC_ALLMCAST;
+
+ //XXX handle other flags as well
+ sxg_set_mcast_addr(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;
- }
+void sxg_free_sgl_buffers(struct adapter_t *adapter)
+{
+ struct list_entry *ple;
+ struct sxg_scatter_gather *Sgl;
+
+ while(!(IsListEmpty(&adapter->AllSglBuffers))) {
+ ple = RemoveHeadList(&adapter->AllSglBuffers);
+ Sgl = container_of(ple, struct sxg_scatter_gather, AllList);
+ kfree(Sgl);
+ adapter->AllSglBufferCount--;
+ }
+}
- DBG_ERROR("%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_ERROR("%s call sxg_config_set adapter->macopts[%x]\n",
- __func__, adapter->macopts);
- sxg_config_set(adapter, TRUE);
- } else {
- if (status == STATUS_SUCCESS) {
- sxg_mcast_set_mask(adapter);
- }
+void sxg_free_rcvblocks(struct adapter_t *adapter)
+{
+ u32 i;
+ void *temp_RcvBlock;
+ struct list_entry *ple;
+ struct sxg_rcv_block_hdr *RcvBlockHdr;
+ struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
+ ASSERT((adapter->state == SXG_STATE_INITIALIZING) ||
+ (adapter->state == SXG_STATE_HALTING));
+ while(!(IsListEmpty(&adapter->AllRcvBlocks))) {
+
+ ple = RemoveHeadList(&adapter->AllRcvBlocks);
+ RcvBlockHdr = container_of(ple, struct sxg_rcv_block_hdr, AllList);
+
+ if(RcvBlockHdr->VirtualAddress) {
+ temp_RcvBlock = RcvBlockHdr->VirtualAddress;
+
+ for(i=0; i< SXG_RCV_DESCRIPTORS_PER_BLOCK;
+ i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) {
+ RcvDataBufferHdr =
+ (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock;
+ SXG_FREE_RCV_PACKET(RcvDataBufferHdr);
+ }
+ }
+
+ pci_free_consistent(adapter->pcidev,
+ SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE),
+ RcvBlockHdr->VirtualAddress,
+ RcvBlockHdr->PhysicalAddress);
+ adapter->AllRcvBlockCount--;
}
- return;
+ ASSERT(adapter->AllRcvBlockCount == 0);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFrRBlk",
+ adapter, 0, 0, 0);
+}
+void sxg_free_mcast_addrs(struct adapter_t *adapter)
+{
+ struct sxg_multicast_address *address;
+ while(adapter->MulticastAddrs) {
+ address = adapter->MulticastAddrs;
+ adapter->MulticastAddrs = address->Next;
+ kfree(address);
+ }
+
+ adapter->MulticastMask= 0;
}
-#endif
-static void sxg_unmap_mmio_space(struct adapter_t *adapter)
+void sxg_unmap_resources(struct adapter_t *adapter)
{
-#if LINUX_FREES_ADAPTER_RESOURCES
-/* if (adapter->Regs) { */
-/* iounmap(adapter->Regs); */
-/* } */
-/* adapter->slic_regs = NULL; */
-#endif
+ if(adapter->HwRegs) {
+ iounmap((void *)adapter->HwRegs);
+ }
+ if(adapter->UcodeRegs) {
+ iounmap((void *)adapter->UcodeRegs);
+ }
+
+ ASSERT(adapter->AllRcvBlockCount == 0);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFrRBlk",
+ adapter, 0, 0, 0);
}
-#if XXXTODO
+
+
/*
- * SxgFreeResources - Free everything allocated in SxgAllocateResources
+ * sxg_free_resources - Free everything allocated in SxgAllocateResources
*
* Arguments -
* adapter - A pointer to our adapter structure
@@ -2896,94 +3679,76 @@ static void sxg_unmap_mmio_space(struct adapter_t *adapter)
* Return
* none
*/
-void SxgFreeResources(struct adapter_t *adapter)
+void sxg_free_resources(struct 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;
+ IsrCount = adapter->msi_enabled ? RssIds : 1;
if (adapter->BasicAllocations == FALSE) {
- /* No allocations have been made, including spinlocks, */
- /* or listhead initializations. Return. */
+ /*
+ * No allocations have been made, including spinlocks,
+ * or listhead initializations. Return.
+ */
return;
}
if (!(IsListEmpty(&adapter->AllRcvBlocks))) {
- SxgFreeRcvBlocks(adapter);
+ sxg_free_rcvblocks(adapter);
}
if (!(IsListEmpty(&adapter->AllSglBuffers))) {
- SxgFreeSglBuffers(adapter);
- }
- /* Free event queues. */
- if (adapter->EventRings) {
- pci_free_consistent(adapter->pcidev,
- sizeof(struct SXG_EVENT_RING) * RssIds,
- adapter->EventRings, adapter->PEventRings);
- }
- if (adapter->Isr) {
- pci_free_consistent(adapter->pcidev,
- sizeof(u32) * IsrCount,
- adapter->Isr, adapter->PIsr);
+ sxg_free_sgl_buffers(adapter);
}
+
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);
+ if (adapter->Isr) {
+ pci_free_consistent(adapter->pcidev,
+ sizeof(u32) * IsrCount,
+ adapter->Isr, adapter->PIsr);
+ }
+
+ if (adapter->EventRings) {
+ pci_free_consistent(adapter->pcidev,
+ sizeof(struct sxg_event_ring) * RssIds,
+ adapter->EventRings, adapter->PEventRings);
+ }
+ if (adapter->RcvRings) {
+ pci_free_consistent(adapter->pcidev,
+ sizeof(struct sxg_rcv_ring) * 1,
+ adapter->RcvRings,
+ adapter->PRcvRings);
+ adapter->RcvRings = NULL;
+ }
+
+ if(adapter->XmtRings) {
+ pci_free_consistent(adapter->pcidev,
+ sizeof(struct sxg_xmt_ring) * 1,
+ adapter->XmtRings,
+ adapter->PXmtRings);
+ adapter->XmtRings = NULL;
+ }
+
+ if (adapter->ucode_stats) {
+ pci_unmap_single(adapter->pcidev,
+ sizeof(struct sxg_ucode_stats),
+ adapter->pucode_stats, PCI_DMA_FROMDEVICE);
+ adapter->ucode_stats = NULL;
}
- 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);
+ sxg_unmap_resources(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);
- }
+ sxg_free_mcast_addrs(adapter);
adapter->BasicAllocations = FALSE;
- SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFreeRes",
- adapter, adapter->MaxTcbs, 0, 0);
}
-#endif
/*
* sxg_allocate_complete -
@@ -3000,31 +3765,34 @@ void SxgFreeResources(struct adapter_t *adapter)
* Return
* None.
*/
-static void sxg_allocate_complete(struct adapter_t *adapter,
+static int sxg_allocate_complete(struct adapter_t *adapter,
void *VirtualAddress,
dma_addr_t PhysicalAddress,
- u32 Length, enum SXG_BUFFER_TYPE Context)
+ u32 Length, enum sxg_buffer_type Context)
{
+ int status = 0;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocCmp",
adapter, VirtualAddress, Length, Context);
- ASSERT(adapter->AllocationsPending);
- --adapter->AllocationsPending;
+ ASSERT(atomic_read(&adapter->pending_allocations));
+ atomic_dec(&adapter->pending_allocations);
switch (Context) {
case SXG_BUFFER_TYPE_RCV:
- sxg_allocate_rcvblock_complete(adapter,
+ status = sxg_allocate_rcvblock_complete(adapter,
VirtualAddress,
PhysicalAddress, Length);
break;
case SXG_BUFFER_TYPE_SGL:
- sxg_allocate_sgl_buffer_complete(adapter, (struct SXG_SCATTER_GATHER*)
+ sxg_allocate_sgl_buffer_complete(adapter, (struct sxg_scatter_gather *)
VirtualAddress,
PhysicalAddress, Length);
break;
}
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocCmp",
adapter, VirtualAddress, Length, Context);
+
+ return status;
}
/*
@@ -3040,7 +3808,7 @@ static void sxg_allocate_complete(struct adapter_t *adapter,
* int
*/
static int sxg_allocate_buffer_memory(struct adapter_t *adapter,
- u32 Size, enum SXG_BUFFER_TYPE BufferType)
+ u32 Size, enum sxg_buffer_type BufferType)
{
int status;
void *Buffer;
@@ -3048,39 +3816,40 @@ static int sxg_allocate_buffer_memory(struct adapter_t *adapter,
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocMem",
adapter, Size, BufferType, 0);
- /* Grab the adapter lock and check the state. */
- /* If we're in anything other than INITIALIZING or */
- /* RUNNING state, fail. This is to prevent */
- /* allocations in an improper driver state */
- 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);
+ /*
+ * 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
+ */
+
+ atomic_inc(&adapter->pending_allocations);
+
+ if(BufferType != SXG_BUFFER_TYPE_SGL)
+ Buffer = pci_alloc_consistent(adapter->pcidev, Size, &pBuffer);
+ else {
+ Buffer = kzalloc(Size, GFP_ATOMIC);
+ pBuffer = (dma_addr_t)NULL;
+ }
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);
+ /*
+ * Decrement the AllocationsPending count while holding
+ * the lock. Pause processing relies on this
+ */
+ atomic_dec(&adapter->pending_allocations);
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;
+ status = sxg_allocate_complete(adapter, Buffer, pBuffer, Size, BufferType);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocMem",
adapter, Size, BufferType, status);
- return (status);
+ return status;
}
/*
- * sxg_allocate_rcvblock_complete - Complete a receive descriptor block allocation
+ * sxg_allocate_rcvblock_complete - Complete a receive descriptor
+ * block allocation
*
* Arguments -
* adapter - A pointer to our adapter structure
@@ -3089,9 +3858,8 @@ static int sxg_allocate_buffer_memory(struct adapter_t *adapter,
* Length - Memory length
*
* Return
- *
*/
-static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
+static int sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
void *RcvBlock,
dma_addr_t PhysicalAddress,
u32 Length)
@@ -3099,11 +3867,11 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
u32 i;
u32 BufferSize = adapter->ReceiveBufferSize;
u64 Paddr;
- struct SXG_RCV_BLOCK_HDR *RcvBlockHdr;
- unsigned char *RcvDataBuffer;
- struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
- struct SXG_RCV_DESCRIPTOR_BLOCK *RcvDescriptorBlock;
- struct SXG_RCV_DESCRIPTOR_BLOCK_HDR *RcvDescriptorBlockHdr;
+ void *temp_RcvBlock;
+ struct sxg_rcv_block_hdr *RcvBlockHdr;
+ struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
+ struct sxg_rcv_descriptor_block *RcvDescriptorBlock;
+ struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlRcvBlk",
adapter, RcvBlock, Length, 0);
@@ -3113,42 +3881,33 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
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 =
- (struct SXG_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;
+ ASSERT(Length == SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE));
+ /*
+ * 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;
+ temp_RcvBlock = RcvBlock;
+ for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
+ i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) {
+ RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *)
+ temp_RcvBlock;
+ /* For FREE macro assertion */
+ RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM;
+ SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, BufferSize);
+ if (RcvDataBufferHdr->SxgDumbRcvPacket == NULL)
+ goto fail;
- }
+ }
- /* Place this entire block of memory on the AllRcvBlocks queue so it can be */
- /* free later */
- RcvBlockHdr =
- (struct SXG_RCV_BLOCK_HDR*) ((unsigned char *)RcvBlock +
- SXG_RCV_BLOCK_HDR_OFFSET(BufferSize));
+ /*
+ * Place this entire block of memory on the AllRcvBlocks queue so it
+ * can be free later
+ */
+
+ RcvBlockHdr = (struct sxg_rcv_block_hdr *) ((unsigned char *)RcvBlock +
+ SXG_RCV_BLOCK_HDR_OFFSET(SXG_RCV_DATA_HDR_SIZE));
RcvBlockHdr->VirtualAddress = RcvBlock;
RcvBlockHdr->PhysicalAddress = PhysicalAddress;
spin_lock(&adapter->RcvQLock);
@@ -3156,14 +3915,15 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
InsertTailList(&adapter->AllRcvBlocks, &RcvBlockHdr->AllList);
spin_unlock(&adapter->RcvQLock);
- /* Now free the contained receive data buffers that we initialized above */
- RcvDataBuffer = RcvBlock;
+ /* Now free the contained receive data buffers that we
+ * initialized above */
+ temp_RcvBlock = RcvBlock;
for (i = 0, Paddr = PhysicalAddress;
i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
- i++, Paddr += BufferSize, RcvDataBuffer += BufferSize) {
- RcvDataBufferHdr = (struct SXG_RCV_DATA_BUFFER_HDR*) (RcvDataBuffer +
- SXG_RCV_DATA_BUFFER_HDR_OFFSET
- (BufferSize));
+ i++, Paddr += SXG_RCV_DATA_HDR_SIZE,
+ temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) {
+ RcvDataBufferHdr =
+ (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock;
spin_lock(&adapter->RcvQLock);
SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
spin_unlock(&adapter->RcvQLock);
@@ -3171,13 +3931,13 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
/* Locate the descriptor block and put it on a separate free queue */
RcvDescriptorBlock =
- (struct SXG_RCV_DESCRIPTOR_BLOCK*) ((unsigned char *)RcvBlock +
+ (struct sxg_rcv_descriptor_block *) ((unsigned char *)RcvBlock +
SXG_RCV_DESCRIPTOR_BLOCK_OFFSET
- (BufferSize));
+ (SXG_RCV_DATA_HDR_SIZE));
RcvDescriptorBlockHdr =
- (struct SXG_RCV_DESCRIPTOR_BLOCK_HDR*) ((unsigned char *)RcvBlock +
+ (struct sxg_rcv_descriptor_block_hdr *) ((unsigned char *)RcvBlock +
SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET
- (BufferSize));
+ (SXG_RCV_DATA_HDR_SIZE));
RcvDescriptorBlockHdr->VirtualAddress = RcvDescriptorBlock;
RcvDescriptorBlockHdr->PhysicalAddress = Paddr;
spin_lock(&adapter->RcvQLock);
@@ -3185,17 +3945,15 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
spin_unlock(&adapter->RcvQLock);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlRBlk",
adapter, RcvBlock, Length, 0);
- return;
- fail:
+ return STATUS_SUCCESS;
+fail:
/* Free any allocated resources */
if (RcvBlock) {
- RcvDataBuffer = RcvBlock;
+ temp_RcvBlock = RcvBlock;
for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
- i++, RcvDataBuffer += BufferSize) {
+ i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) {
RcvDataBufferHdr =
- (struct SXG_RCV_DATA_BUFFER_HDR*) (RcvDataBuffer +
- SXG_RCV_DATA_BUFFER_HDR_OFFSET
- (BufferSize));
+ (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock;
SXG_FREE_RCV_PACKET(RcvDataBufferHdr);
}
pci_free_consistent(adapter->pcidev,
@@ -3206,6 +3964,10 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
adapter, adapter->FreeRcvBufferCount,
adapter->FreeRcvBlockCount, adapter->AllRcvBlockCount);
adapter->Stats.NoMem++;
+ /* As allocation failed, free all previously allocated blocks..*/
+ //sxg_free_rcvblocks(adapter);
+
+ return STATUS_RESOURCES;
}
/*
@@ -3213,46 +3975,65 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
*
* Arguments -
* adapter - A pointer to our adapter structure
- * SxgSgl - SXG_SCATTER_GATHER buffer
+ * SxgSgl - struct sxg_scatter_gather buffer
* PhysicalAddress - Physical address
* Length - Memory length
*
* Return
- *
*/
static void sxg_allocate_sgl_buffer_complete(struct adapter_t *adapter,
- struct SXG_SCATTER_GATHER *SxgSgl,
+ struct sxg_scatter_gather *SxgSgl,
dma_addr_t PhysicalAddress,
u32 Length)
{
+ unsigned long sgl_flags;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlSglCmp",
adapter, SxgSgl, Length, 0);
- spin_lock(&adapter->SglQLock);
+ spin_lock_irqsave(&adapter->SglQLock, sgl_flags);
adapter->AllSglBufferCount++;
- memset(SxgSgl, 0, sizeof(struct SXG_SCATTER_GATHER*));
- SxgSgl->PhysicalAddress = PhysicalAddress; /* *PhysicalAddress; */
- SxgSgl->adapter = adapter; /* Initialize backpointer once */
+ /* PhysicalAddress; */
+ SxgSgl->PhysicalAddress = PhysicalAddress;
+ /* Initialize backpointer once */
+ SxgSgl->adapter = adapter;
InsertTailList(&adapter->AllSglBuffers, &SxgSgl->AllList);
- spin_unlock(&adapter->SglQLock);
+ spin_unlock_irqrestore(&adapter->SglQLock, sgl_flags);
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(struct adapter_t *adapter)
+static int sxg_adapter_set_hwaddr(struct adapter_t *adapter)
{
-/* DBG_ERROR ("%s ENTER card->config_set[%x] port[%d] physport[%d] funct#[%d]\n", __func__, */
-/* card->config_set, adapter->port, adapter->physport, adapter->functionnumber); */
-/* */
-/* sxg_dbg_macaddrs(adapter); */
+ /*
+ * DBG_ERROR ("%s ENTER card->config_set[%x] port[%d] physport[%d] \
+ * funct#[%d]\n", __func__, card->config_set,
+ * adapter->port, adapter->physport, adapter->functionnumber);
+ *
+ * sxg_dbg_macaddrs(adapter);
+ */
+ /* DBG_ERROR ("%s AFTER copying from config.macinfo into currmacaddr\n",
+ * __FUNCTION__);
+ */
+
+ /* sxg_dbg_macaddrs(adapter); */
+
+ struct net_device * dev = adapter->netdev;
+ if(!dev)
+ {
+ printk("sxg: Dev is Null\n");
+ }
+
+ DBG_ERROR("%s ENTER (%s)\n", __FUNCTION__, adapter->netdev->name);
+
+ if (netif_running(dev)) {
+ return -EBUSY;
+ }
+ if (!adapter) {
+ return -EBUSY;
+ }
- memcpy(adapter->macaddr, temp_mac_address, sizeof(struct SXG_CONFIG_MAC));
-/* DBG_ERROR ("%s AFTER copying from config.macinfo into currmacaddr\n", __func__); */
-/* sxg_dbg_macaddrs(adapter); */
if (!(adapter->currmacaddr[0] ||
adapter->currmacaddr[1] ||
adapter->currmacaddr[2] ||
@@ -3262,14 +4043,16 @@ static void sxg_adapter_set_hwaddr(struct adapter_t *adapter)
}
if (adapter->netdev) {
memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, 6);
+ memcpy(adapter->netdev->perm_addr, adapter->currmacaddr, 6);
}
-/* DBG_ERROR ("%s EXIT port %d\n", __func__, adapter->port); */
+ /* DBG_ERROR ("%s EXIT port %d\n", __func__, adapter->port); */
sxg_dbg_macaddrs(adapter);
+ return 0;
}
#if XXXTODO
-static int sxg_mac_set_address(p_net_device dev, void *ptr)
+static int sxg_mac_set_address(struct net_device *dev, void *ptr)
{
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
struct sockaddr *addr = ptr;
@@ -3300,34 +4083,34 @@ static int sxg_mac_set_address(p_net_device dev, void *ptr)
}
#endif
-/*****************************************************************************/
-/************* SXG DRIVER FUNCTIONS (below) ********************************/
-/*****************************************************************************/
-
/*
+ * SXG DRIVER FUNCTIONS (below)
+ *
* sxg_initialize_adapter - Initialize adapter
*
* Arguments -
* adapter - A pointer to our adapter structure
*
- * Return
- * int
+ * Return - int
*/
static int sxg_initialize_adapter(struct adapter_t *adapter)
{
u32 RssIds, IsrCount;
u32 i;
int status;
+ int sxg_rcv_ring_size = SXG_RCV_RING_SIZE;
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;
+ IsrCount = adapter->msi_enabled ? RssIds : 1;
- /* Sanity check SXG_UCODE_REGS structure definition to */
- /* make sure the length is correct */
- ASSERT(sizeof(struct SXG_UCODE_REGS) == SXG_REGISTER_SIZE_PER_CPU);
+ /*
+ * Sanity check SXG_UCODE_REGS structure definition to
+ * make sure the length is correct
+ */
+ ASSERT(sizeof(struct sxg_ucode_regs) == SXG_REGISTER_SIZE_PER_CPU);
/* Disable interrupts */
SXG_DISABLE_ALL_INTERRUPTS(adapter);
@@ -3370,19 +4153,24 @@ static int sxg_initialize_adapter(struct adapter_t *adapter)
/* 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);
+ if (adapter->JumboEnabled == TRUE)
+ sxg_rcv_ring_size = SXG_JUMBO_RCV_RING_SIZE;
+ 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. */
+ /*
+ * 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);
+ adapter->flags |= (SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED );
+
/* Initialize the MAC, XAUI */
DBG_ERROR("sxg: %s ENTER sxg_initialize_link\n", __func__);
status = sxg_initialize_link(adapter);
@@ -3391,10 +4179,16 @@ static int sxg_initialize_adapter(struct adapter_t *adapter)
if (status != STATUS_SUCCESS) {
return (status);
}
- /* Initialize Dead to FALSE. */
- /* SlicCheckForHang or SlicDumpThread will take it from here. */
+ /*
+ * Initialize Dead to FALSE.
+ * SlicCheckForHang or SlicDumpThread will take it from here.
+ */
adapter->Dead = FALSE;
adapter->PingOutstanding = FALSE;
+ adapter->XmtFcEnabled = TRUE;
+ adapter->RcvFcEnabled = TRUE;
+
+ adapter->State = SXG_STATE_RUNNING;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInit",
adapter, 0, 0, 0);
@@ -3413,15 +4207,14 @@ static int sxg_initialize_adapter(struct adapter_t *adapter)
* status
*/
static int sxg_fill_descriptor_block(struct adapter_t *adapter,
- struct SXG_RCV_DESCRIPTOR_BLOCK_HDR
- *RcvDescriptorBlockHdr)
+ struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr)
{
u32 i;
- struct SXG_RING_INFO *RcvRingInfo = &adapter->RcvRingZeroInfo;
- struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
- struct SXG_RCV_DESCRIPTOR_BLOCK *RcvDescriptorBlock;
- struct SXG_CMD *RingDescriptorCmd;
- struct SXG_RCV_RING *RingZero = &adapter->RcvRings[0];
+ struct sxg_ring_info *RcvRingInfo = &adapter->RcvRingZeroInfo;
+ struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
+ struct sxg_rcv_descriptor_block *RcvDescriptorBlock;
+ struct sxg_cmd *RingDescriptorCmd;
+ struct sxg_rcv_ring *RingZero = &adapter->RcvRings[0];
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FilBlk",
adapter, adapter->RcvBuffersOnCard,
@@ -3429,8 +4222,10 @@ static int sxg_fill_descriptor_block(struct adapter_t *adapter,
ASSERT(RcvDescriptorBlockHdr);
- /* If we don't have the resources to fill the descriptor block, */
- /* return failure */
+ /*
+ * If we don't have the resources to fill the descriptor block,
+ * return failure
+ */
if ((adapter->FreeRcvBufferCount < SXG_RCV_DESCRIPTORS_PER_BLOCK) ||
SXG_RING_FULL(RcvRingInfo)) {
adapter->Stats.NoMem++;
@@ -3441,27 +4236,40 @@ static int sxg_fill_descriptor_block(struct adapter_t *adapter,
RcvRingInfo, RingDescriptorCmd, RcvDescriptorBlockHdr);
ASSERT(RingDescriptorCmd);
RcvDescriptorBlockHdr->State = SXG_BUFFER_ONCARD;
- RcvDescriptorBlock =
- (struct SXG_RCV_DESCRIPTOR_BLOCK*) RcvDescriptorBlockHdr->VirtualAddress;
+ RcvDescriptorBlock = (struct sxg_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);
+// ASSERT(RcvDataBufferHdr->SxgDumbRcvPacket);
+ if (!RcvDataBufferHdr->SxgDumbRcvPacket) {
+ SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr,
+ adapter->ReceiveBufferSize);
+ if(RcvDataBufferHdr->skb)
+ RcvDataBufferHdr->SxgDumbRcvPacket =
+ RcvDataBufferHdr->skb;
+ else
+ goto no_memory;
+ }
SXG_REINIATIALIZE_PACKET(RcvDataBufferHdr->SxgDumbRcvPacket);
RcvDataBufferHdr->State = SXG_BUFFER_ONCARD;
RcvDescriptorBlock->Descriptors[i].VirtualAddress =
- (void *)RcvDataBufferHdr;
+ (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. */
+ /*
+ * 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",
@@ -3473,6 +4281,23 @@ static int sxg_fill_descriptor_block(struct adapter_t *adapter,
adapter, adapter->RcvBuffersOnCard,
adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
return (STATUS_SUCCESS);
+no_memory:
+ for (; i >= 0 ; i--) {
+ if (RcvDescriptorBlock->Descriptors[i].VirtualAddress) {
+ RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *)
+ RcvDescriptorBlock->Descriptors[i].
+ VirtualAddress;
+ RcvDescriptorBlock->Descriptors[i].PhysicalAddress =
+ (dma_addr_t)NULL;
+ RcvDescriptorBlock->Descriptors[i].VirtualAddress=NULL;
+ }
+ SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
+ }
+ RcvDescriptorBlockHdr->State = SXG_BUFFER_FREE;
+ SXG_RETURN_CMD(RingZero, RcvRingInfo, RingDescriptorCmd,
+ RcvDescriptorBlockHdr);
+
+ return (-ENOMEM);
}
/*
@@ -3486,34 +4311,42 @@ static int sxg_fill_descriptor_block(struct adapter_t *adapter,
*/
static void sxg_stock_rcv_buffers(struct adapter_t *adapter)
{
- struct SXG_RCV_DESCRIPTOR_BLOCK_HDR *RcvDescriptorBlockHdr;
+ struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr;
+ int sxg_rcv_data_buffers = SXG_RCV_DATA_BUFFERS;
+ int sxg_min_rcv_data_buffers = SXG_MIN_RCV_DATA_BUFFERS;
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) &&
+ /*
+ * 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->JumboEnabled == TRUE)
+ sxg_min_rcv_data_buffers = SXG_MIN_JUMBO_RCV_DATA_BUFFERS;
+ if ((adapter->FreeRcvBufferCount < sxg_min_rcv_data_buffers) &&
(adapter->AllRcvBlockCount < SXG_MAX_RCV_BLOCKS) &&
- (adapter->AllocationsPending == 0)) {
+ (atomic_read(&adapter->pending_allocations) == 0)) {
sxg_allocate_buffer_memory(adapter,
- SXG_RCV_BLOCK_SIZE(adapter->
- ReceiveBufferSize),
+ SXG_RCV_BLOCK_SIZE
+ (SXG_RCV_DATA_HDR_SIZE),
SXG_BUFFER_TYPE_RCV);
}
/* Now grab the RcvQLock lock and proceed */
spin_lock(&adapter->RcvQLock);
- while (adapter->RcvBuffersOnCard < SXG_RCV_DATA_BUFFERS) {
- struct LIST_ENTRY *_ple;
+ if (adapter->JumboEnabled)
+ sxg_rcv_data_buffers = SXG_JUMBO_RCV_DATA_BUFFERS;
+ while (adapter->RcvBuffersOnCard < sxg_rcv_data_buffers) {
+ struct list_entry *_ple;
/* Get a descriptor block */
RcvDescriptorBlockHdr = NULL;
if (adapter->FreeRcvBlockCount) {
_ple = RemoveHeadList(&adapter->FreeRcvBlocks);
RcvDescriptorBlockHdr =
- container_of(_ple, struct SXG_RCV_DESCRIPTOR_BLOCK_HDR,
+ container_of(_ple, struct sxg_rcv_descriptor_block_hdr,
FreeList);
adapter->FreeRcvBlockCount--;
RcvDescriptorBlockHdr->State = SXG_BUFFER_BUSY;
@@ -3553,10 +4386,10 @@ static void sxg_stock_rcv_buffers(struct adapter_t *adapter)
static void sxg_complete_descriptor_blocks(struct adapter_t *adapter,
unsigned char Index)
{
- struct SXG_RCV_RING *RingZero = &adapter->RcvRings[0];
- struct SXG_RING_INFO *RcvRingInfo = &adapter->RcvRingZeroInfo;
- struct SXG_RCV_DESCRIPTOR_BLOCK_HDR *RcvDescriptorBlockHdr;
- struct SXG_CMD *RingDescriptorCmd;
+ struct sxg_rcv_ring *RingZero = &adapter->RcvRings[0];
+ struct sxg_ring_info *RcvRingInfo = &adapter->RcvRingZeroInfo;
+ struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr;
+ struct sxg_cmd *RingDescriptorCmd;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlks",
adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail);
@@ -3564,12 +4397,13 @@ static void sxg_complete_descriptor_blocks(struct adapter_t *adapter,
/* 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 */
- /* */
+ while (sxg_ring_get_forward_diff(RcvRingInfo, Index,
+ RcvRingInfo->Tail) > 3) {
+ /*
+ * Locate the current Cmd (ring descriptor entry), and
+ * associated receive descriptor block, and advance
+ * the tail
+ */
SXG_RETURN_CMD(RingZero,
RcvRingInfo,
RingDescriptorCmd, RcvDescriptorBlockHdr);
@@ -3579,23 +4413,66 @@ static void sxg_complete_descriptor_blocks(struct adapter_t *adapter,
/* 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) {
+ /*
+ * 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);
}
+/*
+ * Read the statistics which the card has been maintaining.
+ */
+void sxg_collect_statistics(struct adapter_t *adapter)
+{
+ if(adapter->ucode_stats)
+ WRITE_REG64(adapter, adapter->UcodeRegs[0].GetUcodeStats,
+ adapter->pucode_stats, 0);
+ adapter->stats.rx_fifo_errors = adapter->ucode_stats->ERDrops;
+ adapter->stats.rx_over_errors = adapter->ucode_stats->NBDrops;
+ adapter->stats.tx_fifo_errors = adapter->ucode_stats->XDrops;
+}
+
+static struct net_device_stats *sxg_get_stats(struct net_device * dev)
+{
+ struct adapter_t *adapter = netdev_priv(dev);
+
+ sxg_collect_statistics(adapter);
+ return (&adapter->stats);
+}
+
+static void sxg_watchdog(unsigned long data)
+{
+ struct adapter_t *adapter = (struct adapter_t *) data;
+
+ if (adapter->state != ADAPT_DOWN) {
+ sxg_link_event(adapter);
+ /* Reset the timer */
+ mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
+ }
+}
+
+static void sxg_update_link_status (struct work_struct *work)
+{
+ struct adapter_t *adapter = (struct adapter_t *)container_of
+ (work, struct adapter_t, update_link_status);
+ if (likely(adapter->link_status_changed)) {
+ sxg_link_event(adapter);
+ adapter->link_status_changed = 0;
+ }
+}
+
static struct pci_driver sxg_driver = {
- .name = DRV_NAME,
+ .name = sxg_driver_name,
.id_table = sxg_pci_tbl,
.probe = sxg_entry_probe,
.remove = sxg_entry_remove,
@@ -3603,7 +4480,7 @@ static struct pci_driver sxg_driver = {
.suspend = sxgpm_suspend,
.resume = sxgpm_resume,
#endif
-/* .shutdown = slic_shutdown, MOOK_INVESTIGATE */
+ /* .shutdown = slic_shutdown, MOOK_INVESTIGATE */
};
static int __init sxg_module_init(void)
diff --git a/drivers/staging/sxg/sxg.h b/drivers/staging/sxg/sxg.h
index 653cf3ba0c4..f07aa708d86 100644
--- a/drivers/staging/sxg/sxg.h
+++ b/drivers/staging/sxg/sxg.h
@@ -42,357 +42,369 @@
#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.
-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:
+#define SLIC_DUMP_ENABLED 0
+
+#define SXG_DRV_NAME "sxg" /* TBD: This might be removed eventually */
+#define SXG_DRV_VERSION "1.0.1"
+
+extern char sxg_driver_name[];
+
+#define SXG_NETDEV_WEIGHT 64
+
+/*
+ * struct sxg_stats - Probably move these to someplace where
+ * the slicstat (sxgstat?) program can get them.
+ */
+struct sxg_stats {
+ /* Xmt */
+ 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 XmtQLen; /* OID_GEN_TRANSMIT_QUEUE_LENGTH */
+ u64 XmtZeroFull; /* Transmit ring zero full */
+ /* Rcv */
+ u64 DumbRcvUcastBytes; /* OID_GEN_DIRECTED_BYTES_RCV */
+ u64 DumbRcvMcastBytes; /* OID_GEN_MULTICAST_BYTES_RCV */
+ u64 DumbRcvBcastBytes; /* OID_GEN_BROADCAST_BYTES_RCV */
+ u64 DumbRcvUcastPkts; /* directed packets */
+ u64 DumbRcvMcastPkts; /* Multicast packets */
+ u64 DumbRcvBcastPkts; /* OID_GEN_BROADCAST_FRAMES_RCV */
+ u64 PdqFull; /* Processed Data Queue Full */
+ u64 EventRingFull; /* Event ring full */
+ /* Verbose stats */
+ u64 NoSglBuf; /* SGL buffer allocation failure */
+ u64 NoMem; /* Memory allocation failure */
+ u64 NumInts; /* Interrupts */
+ u64 FalseInts; /* Interrupt with ISR == 0 */
+ /* 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: */
};
-/****************************************************************************
- * DUMB-NIC Send path definitions
- ****************************************************************************/
+/* DUMB-NIC Send path definitions */
-#define SXG_COMPLETE_DUMB_SEND(_pAdapt, _skb) { \
- ASSERT(_skb); \
- dev_kfree_skb_irq(_skb); \
+#define SXG_COMPLETE_DUMB_SEND(_pAdapt, _skb, _phys_addr, _size) { \
+ ASSERT(_skb); \
+ pci_unmap_single(_pAdapt->pcidev, _size, _phys_addr, PCI_DMA_TODEVICE); \
+ dev_kfree_skb_irq(_skb); \
}
-#define SXG_DROP_DUMB_SEND(_pAdapt, _skb) { \
- ASSERT(_skb); \
- dev_kfree_skb(_skb); \
+#define SXG_DROP_DUMB_SEND(_pAdapt, _skb) { \
+ ASSERT(_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
+/*
+ * 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
+/* Dumb-NIC receive processing */
+/* Define an SXG_PACKET as an NDIS_PACKET */
#define PSXG_PACKET struct sk_buff *
-// Indications array size
+/* 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_ALLOCATE_RCV_PACKET(_pAdapt, _RcvDataBufferHdr, BufferSize) {\
+ struct sk_buff * skb; \
+ skb = netdev_alloc_skb(_pAdapt->netdev, BufferSize); \
+ if (skb) { \
+ (_RcvDataBufferHdr)->skb = skb; \
+ skb->next = NULL; \
+ _RcvDataBufferHdr->PhysicalAddress = pci_map_single(adapter->pcidev,\
+ _RcvDataBufferHdr->skb->data, BufferSize, PCI_DMA_FROMDEVICE); \
+ if (SXG_INVALID_SGL(_RcvDataBufferHdr->PhysicalAddress,BufferSize)) \
+ printk(KERN_EMERG "SXG_ALLOCATE_RCV_PACKET: RCV packet" \
+ "non-64k boundary aligned\n"); \
+ } else { \
+ (_RcvDataBufferHdr)->skb = NULL; \
+ } \
}
-#define SXG_FREE_RCV_PACKET(_RcvDataBufferHdr) { \
- if((_RcvDataBufferHdr)->skb) { \
- dev_kfree_skb((_RcvDataBufferHdr)->skb); \
- } \
+#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; \
- } \
+/*
+ * 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_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 */
+#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)
+/* Definitions to initialize Dumb-nic Receive NBLs */
+#define SXG_RCV_PACKET_BUFFER_HDR(_Packet) (((struct sxg_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_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)); \
+ 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); \
+#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; \
+ _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; \
+#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); */ \
+ skb_put(Packet, (_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) { \
- struct LIST_ENTRY *_ple; \
- _Hdr = NULL; \
- if((_pAdapt)->FreeRcvBufferCount) { \
- ASSERT(!(IsListEmpty(&(_pAdapt)->FreeRcvBuffers))); \
- _ple = RemoveHeadList(&(_pAdapt)->FreeRcvBuffers); \
- (_Hdr) = container_of(_ple, struct SXG_RCV_DATA_BUFFER_HDR, FreeList); \
- (_pAdapt)->FreeRcvBufferCount--; \
- ASSERT((_Hdr)->State == SXG_BUFFER_FREE); \
- } \
+/*
+ * 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) { \
+ struct list_entry *_ple; \
+ _Hdr = NULL; \
+ if((_pAdapt)->FreeRcvBufferCount) { \
+ ASSERT(!(IsListEmpty(&(_pAdapt)->FreeRcvBuffers))); \
+ _ple = RemoveHeadList(&(_pAdapt)->FreeRcvBuffers); \
+ (_Hdr) = container_of(_ple, struct 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_DATA_BUFFER(_pAdapt, _Hdr) { \
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RtnDHdr", \
+ (_Hdr), (_pAdapt)->FreeRcvBufferCount, \
+ (_Hdr)->State, 0/*(_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++; \
+#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); \
+ 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); \
+/* SGL macros */
+#define SXG_FREE_SGL_BUFFER(_pAdapt, _Sgl, _NB) { \
+ spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \
+ (_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_irqrestore(&(_pAdapt)->SglQLock, sgl_flags); \
}
-// 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) { \
- struct LIST_ENTRY *_ple; \
+/*
+ * 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, _irq) { \
+ struct list_entry *_ple; \
if ((_pAdapt->FreeSglBufferCount < SXG_MIN_SGL_BUFFERS) && \
(_pAdapt->AllSglBufferCount < SXG_MAX_SGL_BUFFERS) && \
- (_pAdapt->AllocationsPending == 0)) { \
+ (atomic_read(&_pAdapt->pending_allocations) == 0)) { \
sxg_allocate_buffer_memory(_pAdapt, \
- (sizeof(struct SXG_SCATTER_GATHER) + SXG_SGL_BUF_SIZE),\
+ (sizeof(struct sxg_scatter_gather) + SXG_SGL_BUF_SIZE),\
SXG_BUFFER_TYPE_SGL); \
} \
_Sgl = NULL; \
- spin_lock(&(_pAdapt)->SglQLock); \
+ if(!_irq) \
+ spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \
+ else \
+ spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \
if((_pAdapt)->FreeSglBufferCount) { \
ASSERT(!(IsListEmpty(&(_pAdapt)->FreeSglBuffers))); \
_ple = RemoveHeadList(&(_pAdapt)->FreeSglBuffers); \
- (_Sgl) = container_of(_ple, struct SXG_SCATTER_GATHER, FreeList); \
+ (_Sgl) = container_of(_ple, struct sxg_scatter_gather, \
+ FreeList); \
(_pAdapt)->FreeSglBufferCount--; \
ASSERT((_Sgl)->State == SXG_BUFFER_FREE); \
(_Sgl)->State = SXG_BUFFER_BUSY; \
(_Sgl)->pSgl = NULL; \
} \
- spin_unlock(&(_pAdapt)->SglQLock); \
+ if(!_irq) \
+ spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);\
+ else \
+ spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);\
}
-//
-// SXG_MULTICAST_ADDRESS
-//
-// Linked list of multicast addresses.
-struct SXG_MULTICAST_ADDRESS {
- unsigned char Address[6];
- struct SXG_MULTICAST_ADDRESS *Next;
+/*
+ * struct sxg_multicast_address
+ * Linked list of multicast addresses.
+ */
+struct sxg_multicast_address {
+ unsigned char Address[6];
+ struct sxg_multicast_address *Next;
};
-// 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
-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
+/*
+ * 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
+ */
+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 */
};
#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 { \
+#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; \
+ } \
+ (_Buffer)->Bytes = 0; \
+ (_Buffer)->Head = NULL; \
+ (_Buffer)->Tail = NULL; \
}
-#define SXG_RSS_CPU_COUNT(_pAdapt) \
+#define SXG_RSS_CPU_COUNT(_pAdapt) \
((_pAdapt)->RssEnabled ? NR_CPUS : 1)
-/****************************************************************************
- * DRIVER and ADAPTER structures
- ****************************************************************************/
+/* DRIVER and ADAPTER structures */
-// Adapter states - These states closely match the adapter states
-// documented in the DDK (with a few exceptions).
+/*
+ * Adapter states - These states closely match the adapter states
+ * documented in the DDK (with a few exceptions).
+ */
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_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 */
};
-// Link state
+/* Link state */
enum SXG_LINK_STATE {
SXG_LINK_DOWN,
SXG_LINK_UP
};
-// Link initialization timeout in 100us units
-#define SXG_LINK_TIMEOUT 100000 // 10 Seconds - REDUCE!
+/* Link initialization timeout in 100us units */
+#define SXG_LINK_TIMEOUT 100000 /* 10 Seconds - REDUCE! */
-// Microcode file selection codes
+/* Microcode file selection codes */
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_SYSTEM, /* System (operational) uucode */
+ SXG_UCODE_SDIAGCPU, /* System CPU diagnostic ucode */
+ SXG_UCODE_SDIAGSYS /* System diagnostic ucode */
};
#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
+/* 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))
+#define SXG_BROADCAST_PACKET(_pether) \
+ ((*(u32 *)(_pether)->ether_dhost == 0xFFFFFFFF) && \
+ (*(u16 *)&(_pether)->ether_dhost[4] == 0xFFFF))
-// For DbgPrints
+/* 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.
-struct SXG_DRIVER {
- struct adapter_t *Adapters; // Linked list of adapters
- ushort AdapterID; // Maintain unique adapter ID
+/*
+ * struct sxg_driver structure -
+ *
+ * contains information about the sxg driver. There is only
+ * one of these, and it is defined as a global.
+ */
+
+struct sxg_driver {
+ struct adapter_t *Adapters; /* Linked list of adapters */
+ ushort AdapterID; /* Maintain unique adapter ID */
};
#ifdef STATUS_SUCCESS
#undef STATUS_SUCCESS
#endif
+/* TODO: We need to try and use NETDEV_TX_* before posting this out */
#define STATUS_SUCCESS 0
#define STATUS_PENDING 0
#define STATUS_FAILURE -1
@@ -404,34 +416,36 @@ struct SXG_DRIVER {
#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
+
+/*
+ * 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))
-struct mcast_address_t {
- unsigned char address[6];
- struct mcast_address_t *next;
+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 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_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
@@ -443,29 +457,30 @@ struct mcast_address_t {
#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_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_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 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 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_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")
@@ -481,32 +496,36 @@ struct ether_header {
#define NUM_CFG_SPACES 2
#define NUM_CFG_REGS 64
-struct physcard_t {
- struct adapter_t *adapter[SLIC_MAX_PORTS];
- struct physcard_t *next;
+/*
+ * We split LSS sends across four microcode queues derived from
+ * destination TCP port (if TCP/IP).
+ */
+#define SXG_LARGE_SEND_QUEUE_MASK 0x3
+#define ISCSI_PORT 0xbc0c /* 3260 */
+
+struct physcard {
+ struct adapter_t *adapter[SLIC_MAX_PORTS];
+ struct physcard *next;
unsigned int adapters_allocd;
};
-struct sxgbase_driver_t {
+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;
- struct physcard_t *phys_card;
+ struct physcard *phys_card;
};
struct adapter_t {
void * ifp;
unsigned int port;
- struct physcard_t *physcard;
+ struct napi_struct napi;
+ struct physcard *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;
@@ -514,32 +533,23 @@ struct adapter_t {
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;
+ enum asic_type asictype; /* type of ASIC (chip) */
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;
- struct mcast_address_t *mcastaddrs;
+ struct mcast_address *mcastaddrs;
struct timer_list pingtimer;
u32 pingtimerset;
struct timer_list statstimer;
@@ -574,135 +584,140 @@ struct adapter_t {
u32 rcv_interrupt_yields;
u32 intagg_period;
struct net_device_stats stats;
- u32 * MiniportHandle; // Our miniport handle
- enum SXG_STATE State; // Adapter state
- enum 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;
-
- struct SXG_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 */
- struct SXG_HW_REGS *HwRegs; // Sahara HW Register Memory (BAR0/1)
- struct SXG_UCODE_REGS *UcodeRegs; // Microcode Register Memory (BAR2/3)
- struct SXG_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
- struct SXG_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
- struct SXG_XMT_RING *XmtRings; // Transmit rings
- dma_addr_t PXmtRings; // Transmit rings - physical address
- struct SXG_RING_INFO XmtRingZeroInfo; // Transmit ring 0 info
+ u32 * MiniportHandle; /* Our miniport handle */
+ enum SXG_STATE State; /* Adapter state */
+ enum 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 */
+ struct net_device * netdev;
+ struct net_device * next_netdevice;
+ struct pci_dev *pcidev;
+
+ struct sxg_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 */
+ struct sxg_hw_regs *HwRegs; /* Sahara HW Register Memory (BAR0/1) */
+ struct sxg_ucode_regs *UcodeRegs; /* Microcode Register Memory (BAR2/3) */
+ struct sxg_tcb_regs *TcbRegs; /* Same as Ucode regs - See sxghw.h */
+ 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 */
+ struct sxg_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 */
+ struct sxg_xmt_ring *XmtRings; /* Transmit rings */
+ dma_addr_t PXmtRings; /* Transmit rings - physical address */
+ struct 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
- struct LIST_ENTRY FreeProtocolHeaders;// Free protocol headers
- u32 FreeProtoHdrCount; // Count
- void * ProtocolHeaders; // Block of protocol header
- dma_addr_t PProtocolHeaders; // Block of protocol headers - phys
-
- struct SXG_RCV_RING *RcvRings; // Receive rings
- dma_addr_t PRcvRings; // Receive rings - physical address
- struct 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 */
- struct LIST_ENTRY FreeRcvBuffers; // Free SXG_DATA_BUFFER queue
- struct LIST_ENTRY FreeRcvBlocks; // Free SXG_RCV_DESCRIPTOR_BLOCK Q
- struct 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
+ u32 * XmtRingZeroIndex; /* Shared XMT ring 0 index */
+ dma_addr_t PXmtRingZeroIndex; /* Shared XMT ring 0 index - physical */
+ struct list_entry FreeProtocolHeaders;/* Free protocol headers */
+ u32 FreeProtoHdrCount; /* Count */
+ void * ProtocolHeaders; /* Block of protocol header */
+ dma_addr_t PProtocolHeaders; /* Block of protocol headers - phys */
+
+ struct sxg_rcv_ring *RcvRings; /* Receive rings */
+ dma_addr_t PRcvRings; /* Receive rings - physical address */
+ struct sxg_ucode_stats *ucode_stats; /* Ucode Stats */
+ /* Ucode Stats - physical address */
+ dma_addr_t pucode_stats;
+
+ struct 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 */
+ struct list_entry FreeRcvBuffers; /* Free SXG_DATA_BUFFER queue */
+ struct list_entry FreeRcvBlocks; /* Free SXG_RCV_DESCRIPTOR_BLOCK Q */
+ struct 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 */
+ /* Converted this to a atomic variable
+ u32 AllocationsPending; */
+ atomic_t pending_allocations;
+ u32 AllocationsPending; /* Receive allocation pending */
+ u32 RcvBuffersOnCard; /* SXG_DATA_BUFFERS owned by card */
+ /* SGL buffers */
spinlock_t SglQLock; /* SGL Queue Lock */
- struct LIST_ENTRY FreeSglBuffers; // Free SXG_SCATTER_GATHER
- struct 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
- struct 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
+ struct list_entry FreeSglBuffers; /* Free struct sxg_scatter_gather */
+ struct list_entry AllSglBuffers; /* All struct 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 msi_enabled:1; /* MSI interrupt enabled */
+ u32 RssEnabled:1; /* RSS Enabled */
+ u32 FailOnBadEeprom:1; /* Fail on Bad Eeprom */
+ u32 DiagStart:1; /* Init adapter for diagnostic start */
+ u32 XmtFcEnabled:1;
+ u32 RcvFcEnabled:1;
+ /* Stats */
+ u32 PendingRcvCount; /* Outstanding rcv indications */
+ u32 PendingXmtCount; /* Outstanding send requests */
+ struct 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
+ */
#if defined(CONFIG_X86)
- u32 AddrUpper; // Upper 32 bits of 64-bit register
+ 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
-
+ unsigned short max_aggregation;
+ unsigned short min_aggregation;
+ /*#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 */
+ /*MSI-X related data elements*/
+ u32 nr_msix_entries;
+ struct msix_entry *msi_entries;
+ struct timer_list watchdog_timer;
+ struct work_struct update_link_status;
+ u32 link_status_changed;
};
#if SLIC_DUMP_ENABLED
@@ -710,12 +725,10 @@ struct adapter_t {
#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;
@@ -738,21 +751,25 @@ struct slic_crash_info {
(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 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
+#define SXG_JUMBO_MTU 9000
+#define SXG_DEFAULT_MTU 1500
+
#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)
+#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
@@ -761,8 +778,10 @@ struct slic_crash_info {
#define FLUSH TRUE
#define DONT_FLUSH FALSE
-#define SIOCSLICDUMPCARD SIOCDEVPRIVATE+9
-#define SIOCSLICSETINTAGG SIOCDEVPRIVATE+10
-#define SIOCSLICTRACEDUMP SIOCDEVPRIVATE+11
+#define SIOCSLICDUMPCARD (SIOCDEVPRIVATE+9)
+#define SIOCSLICSETINTAGG (SIOCDEVPRIVATE+10)
+#define SIOCSLICTRACEDUMP (SIOCDEVPRIVATE+11)
+extern struct ethtool_ops sxg_nic_ethtool_ops;
+#define SXG_COMPLETE_SLOW_SEND_LIMIT 128
#endif /* __SXG_DRIVER_H__ */
diff --git a/drivers/staging/sxg/sxg_ethtool.c b/drivers/staging/sxg/sxg_ethtool.c
new file mode 100644
index 00000000000..97f765d1250
--- /dev/null
+++ b/drivers/staging/sxg/sxg_ethtool.c
@@ -0,0 +1,328 @@
+/**************************************************************************
+ *
+ * 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_ethtool.c
+ *
+ * The ethtool support for 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/errno.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+#include <linux/pci.h>
+
+#include "sxg_os.h"
+#include "sxghw.h"
+#include "sxghif.h"
+#include "sxg.h"
+
+struct sxg_nic_stats {
+ char stat_string[ETH_GSTRING_LEN];
+ int sizeof_stat;
+ int stat_offset;
+};
+
+#define SXG_NIC_STATS(m) sizeof(((struct adapter_t *)0)->m), \
+ offsetof(struct adapter_t, m)
+
+#define USER_VIEWABLE_EEPROM_SIZE 28
+
+static struct sxg_nic_stats sxg_nic_gstrings_stats[] = {
+ {"xmit_ring_0_full", SXG_NIC_STATS(Stats.XmtZeroFull)},
+
+ /* May be will need in future */
+/* {"dumb_xmit_broadcast_packets", SXG_NIC_STATS(Stats.DumbXmtBcastPkts)},
+ {"dumb_xmit_broadcast_bytes", SXG_NIC_STATS(Stats.DumbXmtBcastBytes)},
+ {"dumb_xmit_unicast_packets", SXG_NIC_STATS(Stats.DumbXmtUcastPkts)},
+ {"dumb_xmit_unicast_bytes", SXG_NIC_STATS(Stats.DumbXmtUcastBytes)},
+*/
+ {"xmit_queue_length", SXG_NIC_STATS(Stats.XmtQLen)},
+ {"memory_allocation_failure", SXG_NIC_STATS(Stats.NoMem)},
+ {"Interrupts", SXG_NIC_STATS(Stats.NumInts)},
+ {"false_interrupts", SXG_NIC_STATS(Stats.FalseInts)},
+ {"processed_data_queue_full", SXG_NIC_STATS(Stats.PdqFull)},
+ {"event_ring_full", SXG_NIC_STATS(Stats.EventRingFull)},
+ {"transport_checksum_error", SXG_NIC_STATS(Stats.TransportCsum)},
+ {"transport_underflow_error", SXG_NIC_STATS(Stats.TransportUflow)},
+ {"transport_header_length_error", SXG_NIC_STATS(Stats.TransportHdrLen)},
+ {"network_checksum_error", SXG_NIC_STATS(Stats.NetworkCsum)},
+ {"network_underflow_error", SXG_NIC_STATS(Stats.NetworkUflow)},
+ {"network_header_length_error", SXG_NIC_STATS(Stats.NetworkHdrLen)},
+ {"receive_parity_error", SXG_NIC_STATS(Stats.Parity)},
+ {"link_parity_error", SXG_NIC_STATS(Stats.LinkParity)},
+ {"link/data early_error", SXG_NIC_STATS(Stats.LinkEarly)},
+ {"buffer_overflow_error", SXG_NIC_STATS(Stats.LinkBufOflow)},
+ {"link_code_error", SXG_NIC_STATS(Stats.LinkCode)},
+ {"dribble nibble", SXG_NIC_STATS(Stats.LinkDribble)},
+ {"CRC_error", SXG_NIC_STATS(Stats.LinkCrc)},
+ {"link_overflow_error", SXG_NIC_STATS(Stats.LinkOflow)},
+ {"link_underflow_error", SXG_NIC_STATS(Stats.LinkUflow)},
+
+ /* May be need in future */
+/* {"dumb_rcv_broadcast_packets", SXG_NIC_STATS(Stats.DumbRcvBcastPkts)},
+ {"dumb_rcv_broadcast_bytes", SXG_NIC_STATS(Stats.DumbRcvBcastBytes)},
+*/ {"dumb_rcv_multicast_packets", SXG_NIC_STATS(Stats.DumbRcvMcastPkts)},
+ {"dumb_rcv_multicast_bytes", SXG_NIC_STATS(Stats.DumbRcvMcastBytes)},
+/* {"dumb_rcv_unicast_packets", SXG_NIC_STATS(Stats.DumbRcvUcastPkts)},
+ {"dumb_rcv_unicast_bytes", SXG_NIC_STATS(Stats.DumbRcvUcastBytes)},
+*/
+ {"no_sgl_buffer", SXG_NIC_STATS(Stats.NoSglBuf)},
+};
+
+#define SXG_NIC_STATS_LEN ARRAY_SIZE(sxg_nic_gstrings_stats)
+
+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(struct 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_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
+{
+ struct adapter_t *adapter = netdev_priv(dev);
+ strncpy(drvinfo->driver, sxg_driver_name, 32);
+ strncpy(drvinfo->version, SXG_DRV_VERSION, 32);
+// strncpy(drvinfo->fw_version, SAHARA_UCODE_VERS_STRING, 32);
+ strncpy(drvinfo->bus_info, pci_name(adapter->pcidev), 32);
+ /* TODO : Read the major and minor number of firmware. Is this
+ * from the FLASH/EEPROM or download file ?
+ */
+ /* LINSYS : Check if this is correct or if not find the right value
+ * Also check what is the right EEPROM length : EEPROM_SIZE_XFMR or EEPROM_SIZE_NO_XFMR
+ */
+}
+
+static int sxg_nic_set_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ /* No settings are applicable as we support only 10Gb/FIBRE_media */
+ return -EOPNOTSUPP;
+}
+
+static void
+sxg_nic_get_strings(struct net_device *netdev, u32 stringset, u8 * data)
+{
+ int index;
+
+ switch(stringset) {
+ case ETH_SS_TEST:
+ break;
+ case ETH_SS_STATS:
+ for (index = 0; index < SXG_NIC_STATS_LEN; index++) {
+ memcpy(data + index * ETH_GSTRING_LEN,
+ sxg_nic_gstrings_stats[index].stat_string,
+ ETH_GSTRING_LEN);
+ }
+ break;
+ }
+}
+
+static void
+sxg_nic_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *stats, u64 * data)
+{
+ struct adapter_t *adapter = netdev_priv(netdev);
+ int index;
+ for (index = 0; index < SXG_NIC_STATS_LEN; index++) {
+ char *p = (char *)adapter +
+ sxg_nic_gstrings_stats[index].stat_offset;
+ data[index] = (sxg_nic_gstrings_stats[index].sizeof_stat ==
+ sizeof(u64)) ? *(u64 *) p : *(u32 *) p;
+ }
+}
+
+static int sxg_nic_get_sset_count(struct net_device *netdev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return SXG_NIC_STATS_LEN;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int sxg_nic_get_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct adapter_t *adapter = netdev_priv(netdev);
+
+ ecmd->supported = SUPPORTED_10000baseT_Full;
+ ecmd->autoneg = AUTONEG_ENABLE; //VSS check This
+ ecmd->transceiver = XCVR_EXTERNAL; //VSS check This
+
+ /* For Fibre Channel */
+ ecmd->supported |= SUPPORTED_FIBRE;
+ ecmd->advertising = (ADVERTISED_10000baseT_Full |
+ ADVERTISED_FIBRE);
+ ecmd->port = PORT_FIBRE;
+
+
+ /* Link Speed */
+ if(adapter->LinkState & SXG_LINK_UP) {
+ ecmd->speed = SPEED_10000; //adapter->LinkSpeed;
+ ecmd->duplex = DUPLEX_FULL;
+ }
+ return 0;
+}
+
+static u32 sxg_nic_get_rx_csum(struct net_device *netdev)
+{
+ struct adapter_t *adapter = netdev_priv(netdev);
+ return ((adapter->flags & SXG_RCV_IP_CSUM_ENABLED) &&
+ (adapter->flags & SXG_RCV_TCP_CSUM_ENABLED));
+}
+
+static int sxg_nic_set_rx_csum(struct net_device *netdev, u32 data)
+{
+ struct adapter_t *adapter = netdev_priv(netdev);
+ if (data)
+ adapter->flags |= SXG_RCV_IP_CSUM_ENABLED;
+ else
+ adapter->flags &= ~SXG_RCV_IP_CSUM_ENABLED;
+ /*
+ * We dont need to write to the card to do checksums.
+ * It does it anyways.
+ */
+ return 0;
+}
+
+static int sxg_nic_get_regs_len(struct net_device *dev)
+{
+ return (SXG_HWREG_MEMSIZE + SXG_UCODEREG_MEMSIZE);
+}
+
+static void sxg_nic_get_regs(struct net_device *netdev,
+ struct ethtool_regs *regs, void *p)
+{
+ struct adapter_t *adapter = netdev_priv(netdev);
+ struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+ struct sxg_ucode_regs *UcodeRegs = adapter->UcodeRegs;
+ u32 *buff = p;
+
+ memset(p, 0, (sizeof(struct sxg_hw_regs)+sizeof(struct sxg_ucode_regs)));
+ memcpy(buff, HwRegs, sizeof(struct sxg_hw_regs));
+ memcpy((buff+sizeof(struct sxg_hw_regs)), UcodeRegs, sizeof(struct sxg_ucode_regs));
+}
+
+static int sxg_nic_get_eeprom_len(struct net_device *netdev)
+{
+ return (USER_VIEWABLE_EEPROM_SIZE);
+}
+
+static int sxg_nic_get_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+ struct adapter_t *adapter = netdev_priv(netdev);
+ struct sw_cfg_data *data;
+ unsigned long i, status;
+ dma_addr_t p_addr;
+
+ data = pci_alloc_consistent(adapter->pcidev, sizeof(struct sw_cfg_data),
+ &p_addr);
+ if(!data) {
+ /*
+ * We cant get even this much memory. Raise a hell
+ * Get out of here
+ */
+ printk(KERN_ERR"%s : Could not allocate memory for reading \
+ EEPROM\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ WRITE_REG(adapter->UcodeRegs[0].ConfigStat, SXG_CFG_TIMEOUT, TRUE);
+ WRITE_REG64(adapter, adapter->UcodeRegs[0].Config, p_addr, 0);
+ for(i=0; i<1000; i++) {
+ READ_REG(adapter->UcodeRegs[0].ConfigStat, status);
+ if (status != SXG_CFG_TIMEOUT)
+ break;
+ mdelay(1); /* Do we really need this */
+ }
+
+ memset(bytes, 0, eeprom->len);
+ memcpy(bytes, data->MacAddr[0].MacAddr, sizeof(struct sxg_config_mac));
+ memcpy(bytes+6, data->AtkFru.PartNum, 6);
+ memcpy(bytes+12, data->AtkFru.Revision, 2);
+ memcpy(bytes+14, data->AtkFru.Serial, 14);
+
+ return 0;
+}
+
+struct ethtool_ops sxg_nic_ethtool_ops = {
+ .get_settings = sxg_nic_get_settings,
+ .set_settings = sxg_nic_set_settings,
+ .get_drvinfo = sxg_nic_get_drvinfo,
+ .get_regs_len = sxg_nic_get_regs_len,
+ .get_regs = sxg_nic_get_regs,
+ .get_link = ethtool_op_get_link,
+// .get_wol = sxg_nic_get_wol,
+ .get_eeprom_len = sxg_nic_get_eeprom_len,
+ .get_eeprom = sxg_nic_get_eeprom,
+// .get_pauseparam = sxg_nic_get_pauseparam,
+// .set_pauseparam = sxg_nic_set_pauseparam,
+ .set_tx_csum = ethtool_op_set_tx_csum,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+// .get_tso = sxg_nic_get_tso,
+// .set_tso = sxg_nic_set_tso,
+// .self_test = sxg_nic_diag_test,
+ .get_strings = sxg_nic_get_strings,
+ .get_ethtool_stats = sxg_nic_get_ethtool_stats,
+ .get_sset_count = sxg_nic_get_sset_count,
+ .get_rx_csum = sxg_nic_get_rx_csum,
+ .set_rx_csum = sxg_nic_set_rx_csum,
+// .get_coalesce = sxg_nic_get_intr_coalesce,
+// .set_coalesce = sxg_nic_set_intr_coalesce,
+};
diff --git a/drivers/staging/sxg/sxg_os.h b/drivers/staging/sxg/sxg_os.h
index 6d3f23fb5e1..68e1a04b61f 100644
--- a/drivers/staging/sxg/sxg_os.h
+++ b/drivers/staging/sxg/sxg_os.h
@@ -44,34 +44,34 @@
#define FALSE (0)
#define TRUE (1)
-struct LIST_ENTRY {
- struct LIST_ENTRY *nle_flink;
- struct LIST_ENTRY *nle_blink;
+struct list_entry {
+ struct list_entry *nle_flink;
+ struct list_entry *nle_blink;
};
-#define InitializeListHead(l) \
+#define InitializeListHead(l) \
(l)->nle_flink = (l)->nle_blink = (l)
-#define IsListEmpty(h) \
+#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; \
+#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 struct LIST_ENTRY *RemoveHeadList(struct LIST_ENTRY *l)
+static inline struct list_entry *RemoveHeadList(struct list_entry *l)
{
- struct LIST_ENTRY *f;
- struct LIST_ENTRY *e;
+ struct list_entry *f;
+ struct list_entry *e;
e = l->nle_flink;
f = e->nle_flink;
@@ -81,10 +81,10 @@ static __inline struct LIST_ENTRY *RemoveHeadList(struct LIST_ENTRY *l)
return (e);
}
-static __inline struct LIST_ENTRY *RemoveTailList(struct LIST_ENTRY *l)
+static inline struct list_entry *RemoveTailList(struct list_entry *l)
{
- struct LIST_ENTRY *b;
- struct LIST_ENTRY *e;
+ struct list_entry *b;
+ struct list_entry *e;
e = l->nle_blink;
b = e->nle_blink;
@@ -94,54 +94,56 @@ static __inline struct LIST_ENTRY *RemoveTailList(struct LIST_ENTRY *l)
return (e);
}
-#define InsertTailList(l, e) \
- do { \
- struct LIST_ENTRY *b; \
- \
- b = (l)->nle_blink; \
- (e)->nle_flink = (l); \
- (e)->nle_blink = b; \
- b->nle_flink = (e); \
- (l)->nle_blink = (e); \
+#define InsertTailList(l, e) \
+ do { \
+ struct 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 { \
- struct LIST_ENTRY *f; \
- \
- f = (l)->nle_flink; \
- (e)->nle_flink = f; \
- (e)->nle_blink = l; \
- f->nle_blink = (e); \
- (l)->nle_flink = (e); \
+#define InsertHeadList(l, e) \
+ do { \
+ struct 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; \
+#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 *****************************************/
+/* SXG DEFINES */
#ifdef ATKDBG
-#define SXG_TIMESTAMP(value) { \
- struct timeval timev; \
- do_gettimeofday(&timev); \
- value = timev.tv_sec*1000000 + timev.tv_usec; \
+#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 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
index bb58ddf39f3..e613a972b3d 100644
--- a/drivers/staging/sxg/sxgdbg.h
+++ b/drivers/staging/sxg/sxgdbg.h
@@ -44,22 +44,23 @@
#define _SXG_DEBUG_H_
#define ATKDBG 1
-#define ATK_TRACE_ENABLED 1
+#define ATK_TRACE_ENABLED 0
-#define DBG_ERROR(n, args...) printk(KERN_EMERG n, ##args)
+#define DBG_ERROR(n, args...) printk(KERN_WARNING n, ##args)
#ifdef ASSERT
#undef ASSERT
#endif
+#define SXG_ASSERT_ENABLED
#ifdef SXG_ASSERT_ENABLED
#ifndef ASSERT
-#define ASSERT(a) \
- { \
- if (!(a)) { \
- DBG_ERROR("ASSERT() Failure: file %s, function %s line %d\n",\
- __FILE__, __func__, __LINE__); \
- } \
+#define ASSERT(a) \
+ { \
+ if (!(a)) { \
+ DBG_ERROR("ASSERT() Failure: file %s, function %s line %d\n", \
+ __FILE__, __func__, __LINE__); \
+ } \
}
#endif
#else
@@ -78,7 +79,7 @@
extern ulong ATKTimerDiv;
/*
- * trace_entry_t -
+ * trace_entry -
*
* This structure defines an entry in the trace buffer. The
* first few fields mean the same from entry to entry, while
@@ -86,34 +87,34 @@ extern ulong ATKTimerDiv;
* needs of the trace entry. Typically they are function call
* parameters.
*/
-struct trace_entry_t {
- 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 */
+struct trace_entry {
+ 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 */
+ /* pad to 4 byte boundary - will probably get used */
+ unsigned char pad2;
+ u32 arg1; /* Caller arg1 */
+ u32 arg2; /* Caller arg2 */
+ u32 arg3; /* Caller arg3 */
+ u32 arg4; /* Caller arg4 */
};
-/*
- * Driver types for driver field in trace_entry_t
- */
+/* Driver types for driver field in struct trace_entry */
#define TRACE_SXG 1
#define TRACE_VPCI 2
#define TRACE_SLIC 3
#define TRACE_ENTRIES 1024
-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 */
- struct trace_entry_t entries[TRACE_ENTRIES];/* The circular buffer */
+struct sxg_trace_buffer {
+ /* aid for windbg extension */
+ unsigned int size;
+ unsigned int in; /* Where to add */
+ unsigned int level; /* Current Trace level */
+ spinlock_t lock; /* For MP tracing */
+ struct trace_entry entries[TRACE_ENTRIES];/* The circular buffer */
};
/*
@@ -128,15 +129,11 @@ struct sxg_trace_buffer_t {
#define TRACE_NOISY 10 /* Everything in the world */
-/**********************************************************************
- *
- * The macros themselves -
- *
- *********************************************************************/
+/* The macros themselves */
#if ATK_TRACE_ENABLED
#define SXG_TRACE_INIT(buffer, tlevel) \
{ \
- memset((buffer), 0, sizeof(struct sxg_trace_buffer_t)); \
+ memset((buffer), 0, sizeof(struct sxg_trace_buffer)); \
(buffer)->level = (tlevel); \
(buffer)->size = TRACE_ENTRIES; \
spin_lock_init(&(buffer)->lock); \
@@ -145,40 +142,38 @@ struct sxg_trace_buffer_t {
#define SXG_TRACE_INIT(buffer, tlevel)
#endif
-/*
- * The trace macro. This is active only if ATK_TRACE_ENABLED is set.
- */
+/*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; \
- struct trace_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); \
- } \
+ if ((buffer) && ((buffer)->level >= (tlevel))) { \
+ unsigned int trace_irql = 0;/* ?????? FIX THIS */\
+ unsigned int trace_len; \
+ struct trace_entry *trace_entry; \
+ struct timeval timev; \
+ if(spin_trylock(&(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)
diff --git a/drivers/staging/sxg/sxghif.h b/drivers/staging/sxg/sxghif.h
index a4e94685c54..e190d6add29 100644
--- a/drivers/staging/sxg/sxghif.h
+++ b/drivers/staging/sxg/sxghif.h
@@ -1,4 +1,4 @@
-/*
+/*******************************************************************
* Copyright © 1997-2007 Alacritech, Inc. All rights reserved
*
* $Id: sxghif.h,v 1.5 2008/07/24 19:18:22 chris Exp $
@@ -7,129 +7,134 @@
*
* This file contains structures and definitions for the
* Alacritech Sahara host interface
- */
-
-/*******************************************************************************
- * UCODE Registers
- *******************************************************************************/
-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
+ ******************************************************************/
+
+#define DBG 1
+
+/* UCODE Registers */
+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 ConfigStat; /* Code = 8 - Configuration data load status */
+ u32 RsvdReg9; /* Code = 9 - TOE -NA */
+ u32 CodeNotUsed[6]; /* Codes 10-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
+ /* 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
+ /* 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
+ /* 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
+ /* 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
+ /* 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
+ /* 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
+ /* 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
+ /* 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
+ /* ExCode 11 = Read EEPROM/Flash Config */
+ u32 Config; /* Code = 0 (extended), ExCode = 11 */
u32 PadEx11[15];
- // ExCode 12 = Multicast bits 31:0
- u32 McastLow; // Code = 0 (extended), ExCode = 12
+ /* 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
+ /* 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
+ /* ExCode 14 = Ping */
+ u32 Ping; /* Code = 0 (extended), ExCode = 14 */
u32 PadEx14[15];
- // ExCode 15 = Link MTU
- u32 LinkMtu; // Code = 0 (extended), ExCode = 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
+ /* 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
+ /* 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
+ /* ExCode 18 = Slowpath Send Index Address */
+ u32 SPSendIndex; /* Code = 0 (extended), ExCode = 18 */
u32 PadEx18[15];
- u32 RsvdXF; // Code = 0 (extended), ExCode = 19
+ /* ExCode 19 = Get ucode statistics */
+ u32 GetUcodeStats; /* Code = 0 (extended), ExCode = 19 */
u32 PadEx19[15];
- // ExCode 20 = Aggregation
- u32 Aggregation; // Code = 0 (extended), ExCode = 20
+ /* ExCode 20 = Aggregation - See sxgmisc.c:SxgSetInterruptAggregation */
+ u32 Aggregation; /* Code = 0 (extended), ExCode = 20 */
u32 PadEx20[15];
- // ExCode 21 = Receive MDL push timer
- u32 PushTicks; // Code = 0 (extended), ExCode = 21
+ /* 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
+ /* ExCode 22 = ACK Frequency */
+ u32 AckFrequency; /* Code = 0 (extended), ExCode = 22 */
u32 PadEx22[15];
- // ExCode 23 = TOE NA
+ /* ExCode 23 = TOE NA */
u32 RsvdReg23;
u32 PadEx23[15];
- // ExCode 24 = TOE NA
+ /* ExCode 24 = TOE NA */
u32 RsvdReg24;
u32 PadEx24[15];
- // ExCode 25 = TOE NA
- u32 RsvdReg25; // Code = 0 (extended), ExCode = 25
+ /* 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
+ /* 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
+ /* 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
+ /* 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
+ /* 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
+ /* 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
+ /* 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
+ /* 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
+ /* 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)
+ /*
+ * 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)*/
};
-// Interrupt control register (0) values
+/* Interrupt control register (0) values */
#define SXG_ICR_DISABLE 0x00000000
#define SXG_ICR_ENABLE 0x00000001
#define SXG_ICR_MASK 0x00000002
@@ -139,47 +144,65 @@ struct SXG_UCODE_REGS {
((((_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_MIN_AGG_DEFAULT 0x0010 /* Minimum aggregation default */
+#define SXG_MAX_AGG_DEFAULT 0x0040 /* Maximum aggregation default */
+#define SXG_MAX_AGG_SHIFT 16 /* Maximum in top 16 bits of register */
+/* Disable interrupt aggregation on xmt */
+#define SXG_AGG_XMT_DISABLE 0x80000000
+
+/* The Microcode supports up to 16 RSS queues (RevB) */
+#define SXG_MAX_RSS 16
+#define SXG_MAX_RSS_REVA 8
+
+#define SXG_MAX_RSS_TABLE_SIZE 256 /* 256-byte max */
+
+#define SXG_RSS_REVA_TCP6 0x00000001 /* RSS TCP over IPv6 */
+#define SXG_RSS_REVA_TCP4 0x00000002 /* RSS TCP over IPv4 */
+#define SXG_RSS_IP 0x00000001 /* RSS TCP over IPv6 */
+#define SXG_RSS_TCP 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_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_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_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
+/*
+ * Status returned by ucode in the ConfigStat reg (see above) when attempted
+ * to load configuration data from the EEPROM/Flash.
+ */
+#define SXG_CFG_TIMEOUT 1 /* init value - timeout if unchanged */
+#define SXG_CFG_LOAD_EEPROM 2 /* config data loaded from EEPROM */
+#define SXG_CFG_LOAD_FLASH 3 /* config data loaded from flash */
+#define SXG_CFG_LOAD_INVALID 4 /* no valid config data found */
+#define SXG_CFG_LOAD_ERROR 5 /* hardware error */
+
#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
+ * struct sxg_ucode_regs definition above
*/
-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. */
+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 Invalid1; /* Code = 6 - Reserved for "CardUp" see above */
+ u32 Rsvd4; /* Code = 7 - TOE NA */
+ u32 Invalid2; /* Code = 8 - Reserved for "ConfigStat" see above */
+ u32 Rsvd5; /* Code = 9 - TOE NA */
+ u32 Pad[6]; /* Codes 10-15 - Not used. */
};
/***************************************************************************
@@ -206,29 +229,26 @@ struct SXG_TCB_REGS {
* ||---|-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
+#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 ------------>|
@@ -270,196 +290,223 @@ struct SXG_TCB_REGS {
* ||------- ISTCPIP
* |-------- SCERR
*
- */
+ ************************************************************************/
#pragma pack(push, 1)
-struct SXG_EVENT {
- u32 Pad[1]; // not used
- u32 SndUna; // SndUna value
- u32 Resid; // receive MDL resid
+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
+ void * HostHandle; /* Receive host handle */
+ u32 Rsvd1; /* TOE NA */
struct {
u32 NotUsed;
- u32 Rsvd2; // TOE NA
+ u32 Rsvd2; /* TOE NA */
} Flush;
};
- u32 Toeplitz; // RSS Toeplitz hash
+ u32 Toeplitz; /* RSS Toeplitz hash */
union {
- ushort Rsvd3; // TOE NA
- ushort HdrOffset; // Slowpath
+ ushort Rsvd3; /* TOE NA */
+ ushort HdrOffset; /* Slowpath */
};
- ushort Length; //
- unsigned char Rsvd4; // TOE NA
- unsigned char Code; // Event code
- unsigned char CommandIndex; // New ring index
- unsigned char Status; // Event status
+ ushort Length;
+ unsigned char Rsvd4; /* TOE NA */
+ unsigned char Code; /* Event code */
+ unsigned char CommandIndex; /* New ring index */
+ unsigned char Status; /* Event status */
};
#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)
-
-struct SXG_EVENT_RING {
- struct SXG_EVENT Ring[EVENT_RING_SIZE];
+/* 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. */
+/* Stop processing events after 4096 (256 * 16) */
+#define EVENT_BATCH_LIMIT 256
+
+struct sxg_event_ring {
+ struct sxg_event Ring[EVENT_RING_SIZE];
};
-/***************************************************************************
- *
- * TCB Buffers
- *
- ***************************************************************************/
-// Maximum number of TCBS supported by hardware/microcode
+/* TCB Buffers */
+/* Maximum number of TCBS supported by hardware/microcode */
#define SXG_MAX_TCB 4096
-// Minimum TCBs before we fail initialization
+/* 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.
+/*
+ * 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_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_BUFFER_SIZE 512 /* ASSERT format is correct */
-#define SXG_TCB_RCVQ_SIZE 736
+#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 : \
+#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 : \
+#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 : \
+#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; \
- } \
- } \
+/*
+ * 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
+/* Do nothing with free build */
#define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath)
#endif
-/***************************************************************************
- * Receive and transmit rings
- ***************************************************************************/
+/* Receive and transmit rings */
#define SXG_MAX_RING_SIZE 256
-#define SXG_XMT_RING_SIZE 128 // Start with 128
-#define SXG_RCV_RING_SIZE 128 // Start with 128
+#define SXG_XMT_RING_SIZE 128 /* Start with 128 */
+#define SXG_RCV_RING_SIZE 128 /* Start with 128 */
#define SXG_MAX_ENTRIES 4096
-
-// Structure and macros to manage a ring
-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
+#define SXG_JUMBO_RCV_RING_SIZE 32
+
+/* Structure and macros to manage a ring */
+struct sxg_ring_info {
+ /* Where we add entries - Note unsigned char:RING_SIZE */
+ unsigned char Head;
+ 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 */
};
-#define SXG_INITIALIZE_RING(_ring, _size) { \
- (_ring).Head = 0; \
- (_ring).Tail = 0; \
- (_ring).Size = (_size); \
+#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_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)); \
+#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]; \
+/*
+ * 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); \
- } \
+ 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; \
+/*
+ * 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]; \
+/*
+ * 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); \
+ (_ringinfo)->Context[(_ringinfo)->Tail] = NULL; \
+ SXG_RING_ADVANCE_TAIL(_ringinfo); \
}
-/***************************************************************************
- *
+/*
+ * For a given ring find out how much the first pointer is ahead of
+ * the second pointer. "ahead" recognises the fact that the ring can wrap
+ */
+static inline int sxg_ring_get_forward_diff (struct sxg_ring_info *ringinfo,
+ int a, int b) {
+ if ((a < 0 || a > ringinfo->Size ) || (b < 0 || b > ringinfo->Size))
+ return -1;
+ if (a > b) /* _a is lagging _b and _b has not wrapped around */
+ return (a - b);
+ else
+ return ((ringinfo->Size - (b - a)));
+}
+
+/***************************************************************
* Host Command Buffer - commands to INIC via the Cmd Rings
*
- ***************************************************************************/
-/*
* 31 15 0
* .___________________.___________________.
* |<-------------- Sgl Low -------------->|
@@ -479,42 +526,43 @@ struct SXG_RING_INFO {
* |_________|_________|_________|_________|24 0x18
* |<----- LCnt ------>|<----- Flags ----->|
* |_________|_________|_________|_________|28 0x1c
- */
+ ****************************************************************/
#pragma pack(push, 1)
-struct SXG_CMD {
- dma_addr_t Sgl; // Physical address of SGL
+struct sxg_cmd {
+ dma64_addr_t Sgl; /* Physical address of SGL */
union {
struct {
- dma64_addr_t FirstSgeAddress; // Address of first SGE
- u32 FirstSgeLength; // Length of first SGE
+ dma64_addr_t FirstSgeAddress; /* Address of first SGE */
+ u32 FirstSgeLength; /* Length of first SGE */
union {
- u32 Rsvd1; // TOE NA
- u32 SgeOffset; // Slowpath - 2nd SGE offset
- u32 Resid; // MDL completion - clobbers update
+ u32 Rsvd1; /* TOE NA */
+ u32 SgeOffset; /* Slowpath - 2nd SGE offset */
+ /* MDL completion - clobbers update */
+ u32 Resid;
};
union {
- u32 TotalLength; // Total transfer length
- u32 Mss; // LSO MSS
+ u32 TotalLength; /* Total transfer length */
+ u32 Mss; /* LSO MSS */
};
} Buffer;
};
union {
struct {
- unsigned char Flags:4; // slowpath flags
- unsigned char IpHl:4; // Ip header length (>>2)
- unsigned char MacLen; // Mac header len
+ unsigned char Flags:4; /* slowpath flags */
+ unsigned char IpHl:4; /* Ip header length (>>2) */
+ unsigned char MacLen; /* Mac header len */
} CsumFlags;
struct {
- ushort Flags:4; // slowpath flags
- ushort TcpHdrOff:7; // TCP
- ushort MacLen:5; // Mac header len
+ ushort Flags:4; /* slowpath flags */
+ ushort TcpHdrOff:7; /* TCP */
+ ushort MacLen:5; /* Mac header len */
} LsoFlags;
- ushort Flags; // flags
+ ushort Flags; /* flags */
};
union {
- ushort SgEntries; // SG entry count including first sge
+ ushort SgEntries; /* SG entry count including first sge */
struct {
- unsigned char Status; // Copied from event status
+ unsigned char Status; /* Copied from event status */
unsigned char NotUsed;
} Status;
};
@@ -522,13 +570,13 @@ struct SXG_CMD {
#pragma pack(pop)
#pragma pack(push, 1)
-struct VLAN_HDR {
+struct vlan_hdr {
ushort VlanTci;
ushort VlanTpid;
};
#pragma pack(pop)
-/*
+/********************************************************************
* Slowpath Flags:
*
*
@@ -558,36 +606,36 @@ struct VLAN_HDR {
* | 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
-
-struct SXG_XMT_RING {
- struct SXG_CMD Descriptors[SXG_XMT_RING_SIZE];
+ *****************************************************************/
+/* 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 */
+
+struct sxg_xmt_ring {
+ struct sxg_cmd Descriptors[SXG_XMT_RING_SIZE];
};
-struct SXG_RCV_RING {
- struct SXG_CMD Descriptors[SXG_RCV_RING_SIZE];
+struct sxg_rcv_ring {
+ struct sxg_cmd Descriptors[SXG_RCV_RING_SIZE];
};
-/***************************************************************************
+/*
* Share memory buffer types - Used to identify asynchronous
* shared memory allocation
- ***************************************************************************/
-enum SXG_BUFFER_TYPE {
- SXG_BUFFER_TYPE_RCV, // Receive buffer
- SXG_BUFFER_TYPE_SGL // SGL buffer
+ */
+enum sxg_buffer_type {
+ SXG_BUFFER_TYPE_RCV, /* Receive buffer */
+ SXG_BUFFER_TYPE_SGL /* SGL buffer */
};
-// State for SXG buffers
+/* 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.
@@ -597,262 +645,370 @@ enum SXG_BUFFER_TYPE {
* 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.
+ * 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]
+ * 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.
+ * 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
+ * block is managed by a struct 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:
+ * length so that the buffer and it's corresponding struct
+ * 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 |
+ * | sxg_rcv_data_buffer_hdr #1 |
* |_________________________________________| <== Even 2k or 10k boundary
* | |
* | ... repeat 2-128 .. |
* |_________________________________________|
* | |
- * | SXG_RCV_DESCRIPTOR_BLOCK |
- * | Contains SXG_RCV_DATA_DESCRIPTOR * 128 |
+ * | struct sxg_rcv_descriptor_block |
+ * | Contains sxg_rcv_data_descriptor * 128 |
* |_________________________________________|
* | |
- * | SXG_RCV_DESCRIPTOR_BLOCK_HDR |
+ * | struct sxg_rcv_descriptor_block_hdr |
* |_________________________________________|
* | |
- * | SXG_RCV_BLOCK_HDR |
+ * | struct 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
+ * Buffers and sxg_rcv_data_buffer_hdr = 2k * 128 = 256k
+ * + struct sxg_rcv_descriptor_block = 2k
+ * + struct sxg_rcv_descriptor_block_hdr = ~32
+ * + struct 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
+ * Buffers and sxg_rcv_data_buffer_hdr = 10k * 128 = 1280k
+ * + struct sxg_rcv_descriptor_block = 2k
+ * + struct sxg_rcv_descriptor_block_hdr = ~32
+ * + struct 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
-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
- struct 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)
+ */
+#define SXG_RCV_DATA_BUFFERS 8192 /* Amount to give to the card */
+#define SXG_INITIAL_RCV_DATA_BUFFERS 16384 /* Initial pool of buffers */
+/* Minimum amount and when to get more */
+#define SXG_MIN_RCV_DATA_BUFFERS 4096
+#define SXG_MAX_RCV_BLOCKS 256 /* = 32k receive buffers */
+/* Amount to give to the card in case of jumbo frames */
+#define SXG_JUMBO_RCV_DATA_BUFFERS 2048
+/* Initial pool of buffers in case of jumbo buffers */
+#define SXG_INITIAL_JUMBO_RCV_DATA_BUFFERS 4096
+#define SXG_MIN_JUMBO_RCV_DATA_BUFFERS 1024
+
+/* Receive buffer header */
+struct sxg_rcv_data_buffer_hdr {
+ dma64_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.
+ */
+ struct list_entry FreeList; /* Free queue of buffers */
+ unsigned char State; /* See SXG_BUFFER state above */
+ struct sk_buff * skb; /* Double mapped (nbl and pkt)*/
};
-// SxgSlowReceive uses the PACKET (skb) contained
-// in the SXG_RCV_DATA_BUFFER_HDR when indicating dumb-nic data
+/*
+ * SxgSlowReceive uses the PACKET (skb) contained
+ * in the struct 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
+/* Space for struct sxg_rcv_data_buffer_hdr */
+#define SXG_RCV_DATA_HDR_SIZE sizeof(struct sxg_rcv_data_buffer_hdr)
+/* Non jumbo = 2k including HDR */
+#define SXG_RCV_DATA_BUFFER_SIZE 2048
+/* jumbo = 10k including HDR */
+#define SXG_RCV_JUMBO_BUFFER_SIZE 10240
-// Receive data descriptor
-struct SXG_RCV_DATA_DESCRIPTOR {
+/* Receive data descriptor */
+struct sxg_rcv_data_descriptor {
union {
- struct sk_buff *VirtualAddress; // Host handle
- u64 ForceTo8Bytes; // Force x86 to 8-byte boundary
+ struct sk_buff *VirtualAddress; /* Host handle */
+ u64 ForceTo8Bytes; /*Force x86 to 8-byte boundary*/
};
- dma_addr_t PhysicalAddress;
+ dma64_addr_t PhysicalAddress;
};
-// Receive descriptor block
+/* Receive descriptor block */
#define SXG_RCV_DESCRIPTORS_PER_BLOCK 128
-#define SXG_RCV_DESCRIPTOR_BLOCK_SIZE 2048 // For sanity check
+#define SXG_RCV_DESCRIPTOR_BLOCK_SIZE 2048 /* For sanity check */
-struct SXG_RCV_DESCRIPTOR_BLOCK {
- struct SXG_RCV_DATA_DESCRIPTOR Descriptors[SXG_RCV_DESCRIPTORS_PER_BLOCK];
+struct sxg_rcv_descriptor_block {
+ struct sxg_rcv_data_descriptor Descriptors[SXG_RCV_DESCRIPTORS_PER_BLOCK];
};
-// Receive descriptor block header
-struct SXG_RCV_DESCRIPTOR_BLOCK_HDR {
- void *VirtualAddress; // Start of 2k buffer
- dma_addr_t PhysicalAddress; // ..and it's physical address
- struct LIST_ENTRY FreeList; // Free queue of descriptor blocks
- unsigned char State; // See SXG_BUFFER state above
+/* Receive descriptor block header */
+struct sxg_rcv_descriptor_block_hdr {
+ void *VirtualAddress; /* start of 2k buffer */
+ dma64_addr_t PhysicalAddress;/* and it's physical address */
+ struct list_entry FreeList;/* free queue of descriptor blocks */
+ unsigned char State; /* see sxg_buffer state above */
};
-// Receive block header
-struct SXG_RCV_BLOCK_HDR {
- void *VirtualAddress; // Start of virtual memory
- dma_addr_t PhysicalAddress; // ..and it's physical address
- struct LIST_ENTRY AllList; // Queue of all SXG_RCV_BLOCKS
+/* Receive block header */
+struct sxg_rcv_block_hdr {
+ void *VirtualAddress; /* Start of virtual memory */
+ dma64_addr_t PhysicalAddress;/* ..and it's physical address*/
+ struct list_entry AllList; /* Queue of all SXG_RCV_BLOCKS*/
};
-// Macros to determine data structure offsets into receive block
-#define SXG_RCV_BLOCK_SIZE(_Buffersize) \
+/* Macros to determine data structure offsets into receive block */
+#define SXG_RCV_BLOCK_SIZE(_Buffersize) \
(((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \
- (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK)) + \
- (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK_HDR)) + \
- (sizeof(struct SXG_RCV_BLOCK_HDR)))
+ (sizeof(struct sxg_rcv_descriptor_block)) + \
+ (sizeof(struct sxg_rcv_descriptor_block_hdr)) + \
+ (sizeof(struct 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) \
+#define SXG_RCV_DESCRIPTOR_BLOCK_OFFSET(_Buffersize) \
((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK)
-#define SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET(_Buffersize) \
+#define SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET(_Buffersize) \
(((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \
- (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK)))
+ (sizeof(struct sxg_rcv_descriptor_block)))
#define SXG_RCV_BLOCK_HDR_OFFSET(_Buffersize) \
(((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \
- (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK)) + \
- (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK_HDR)))
-
-// Use the miniport reserved portion of the NBL to locate
-// our SXG_RCV_DATA_BUFFER_HDR structure.
-struct SXG_RCV_NBL_RESERVED {
- struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
- void *Available;
-};
+ (sizeof(struct sxg_rcv_descriptor_block)) + \
+ (sizeof(struct sxg_rcv_descriptor_block_hdr)))
-#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*/
+/* Maximum to allocate (note ADAPT:ushort) */
+#define SXG_MAX_SGL_BUFFERS 16384
-/***************************************************************************
- * 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)
+/*
+ * SXG_SGL_POOL_PROPERTIES - This structure is used to define a pool of SGL
+ * buffers. These buffers are allocated out of shared memory and used to
+ * contain a physical scatter gather list structure that is shared
+ * with the card.
+ *
+ * We split our SGL buffers into multiple pools based on size. The motivation
+ * is that some applications perform very large I/Os (1MB for example), so
+ * we need to be able to allocate an SGL to accommodate such a request.
+ * But such an SGL would require 256 24-byte SG entries - ~6k.
+ * Given that the vast majority of I/Os are much smaller than 1M, allocating
+ * a single pool of SGL buffers would be a horribly inefficient use of
+ * memory.
+ *
+ * The following structure includes two fields relating to its size.
+ * The NBSize field specifies the largest NET_BUFFER that can be handled
+ * by the particular pool. The SGEntries field defines the size, in
+ * entries, of the SGL for that pool. The SGEntries is determined by
+ * dividing the NBSize by the expected page size (4k), and then padding
+ * it by some appropriate amount as insurance (20% or so..??).
+ */
+struct sxg_sgl_pool_properties {
+ u32 NBSize; /* Largest NET_BUFFER size for this pool */
+ ushort SGEntries; /* Number of entries in SGL */
+ ushort InitialBuffers; /* Number to allocate at initializationtime */
+ ushort MinBuffers; /* When to get more */
+ ushort MaxBuffers; /* When to stop */
+ ushort PerCpuThreshold;/* See sxgh.h:SXG_RESOURCES */
+};
-// Self identifying structure type
-enum SXG_SGL_TYPE {
- SXG_SGL_DUMB, // Dumb NIC SGL
- SXG_SGL_SLOW, // Slowpath protocol header - see below
- SXG_SGL_CHIMNEY // Chimney offload SGL
+/*
+ * At the moment I'm going to statically initialize 4 pools:
+ * 100k buffer pool: The vast majority of the expected buffers are expected
+ * to be less than or equal to 100k. At 30 entries per and
+ * 8k initial buffers amounts to ~4MB of memory
+ * NOTE - This used to be 64K with 20 entries, but during
+ * WHQL NDIS 6.0 Testing (2c_mini6stress) MS does their
+ * best to send absurd NBL's with ridiculous SGLs, we
+ * have received 400byte sends contained in SGL's that
+ * have 28 entries
+ * 1M buffer pool: Buffers between 64k and 1M. Allocate 256 initial
+ * buffers with 300 entries each => ~2MB of memory
+ * 5M buffer pool: Not expected often, if at all. 32 initial buffers
+ * at 1500 entries each => ~1MB of memory
+ * 10M buffer pool: Not expected at all, except under pathelogical conditions.
+ * Allocate one at initialization time.
+ * Note - 10M is the current limit of what we can realistically
+ * support due to the sahara SGL bug described in the
+ * SAHARA SGL WORKAROUND below. We will likely adjust the
+ * number of pools and/or pool properties over time.
+ */
+#define SXG_NUM_SGL_POOLS 4
+#define INITIALIZE_SGL_POOL_PROPERTIES \
+struct sxg_sgl_pool_properties SxgSglPoolProperties[SXG_NUM_SGL_POOLS] =\
+{ \
+ { 102400, 30, 8192, 2048, 16384, 256}, \
+ { 1048576, 300, 256, 128, 1024, 16}, \
+ { 5252880, 1500, 32, 16, 512, 0}, \
+ {10485760, 2700, 2, 4, 32, 0}, \
};
-// 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
-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
+extern struct sxg_sgl_pool_properties SxgSglPoolProperties[];
+
+#define SXG_MAX_SGL_BUFFER_SIZE \
+ SxgSglPoolProperties[SXG_NUM_SGL_POOLS - 1].NBSize
+
+/*
+ * SAHARA SGL WORKAROUND!!
+ * The current Sahara card uses a 16-bit counter when advancing
+ * SGL address locations. This means that if an SGL crosses
+ * a 64k boundary, the hardware will actually skip back to
+ * the start of the previous 64k boundary, with obviously
+ * undesirable results.
+ *
+ * We currently workaround this issue by allocating SGL buffers
+ * in 64k blocks and skipping over buffers that straddle the boundary.
+ */
+#define SXG_INVALID_SGL(phys_addr,len) \
+ (((phys_addr >> 16) != ( (phys_addr + len) >> 16 )))
+
+/*
+ * Allocate SGLs in blocks so we can skip over invalid entries.
+ * We allocation 64k worth of SGL buffers, including the
+ * struct sxg_sgl_block_hdr, plus one for padding
+ */
+#define SXG_SGL_BLOCK_SIZE 65536
+#define SXG_SGL_ALLOCATION_SIZE(_Pool) \
+ SXG_SGL_BLOCK_SIZE + SXG_SGL_SIZE(_Pool)
+
+struct sxg_sgl_block_hdr {
+ ushort Pool; /* Associated SGL pool */
+ /* struct sxg_scatter_gather blocks */
+ struct list_entry List;
+ dma64_addr_t PhysicalAddress;/* physical address */
};
-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
+/*
+ * The following definition denotes the maximum block of memory that the
+ * card can DMA to.It is specified in the call to NdisMRegisterScatterGatherDma.
+ * For now, use the same value as used in the Slic/Oasis driver, which
+ * is 128M. That should cover any expected MDL that I can think of.
+ */
+#define SXG_MAX_PHYS_MAP (1024 * 1024 * 128)
+
+/* Self identifying structure type */
+enum SXG_SGL_TYPE {
+ SXG_SGL_DUMB, /* Dumb NIC SGL */
+ SXG_SGL_SLOW, /* Slowpath protocol header - see below */
+ SXG_SGL_CHIMNEY /* Chimney offload SGL */
};
-struct SCATTER_GATHER_LIST {
- u32 NumberOfElements;
- u32 *Reserved;
- struct SCATTER_GATHER_ELEMENT Elements[];
+/*
+ * 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
+ */
+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 */
};
-// 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
-struct SXG_X64_SGL {
+/*
+ * Our SGL structure - Essentially the same as
+ * wdm.h:SCATTER_GATHER_LIST. Note the variable number of
+ * elements based on the pool specified above
+ */
+struct sxg_x64_sgl {
u32 NumberOfElements;
u32 *Reserved;
- struct SXG_X64_SGE Elements[SXG_SGL_ENTRIES];
+ struct sxg_x64_sge Elements[1]; /* Variable */
};
-struct SXG_SCATTER_GATHER {
- enum SXG_SGL_TYPE Type; // FIRST! Dumb-nic or offload
- void *adapter; // Back pointer to adapter
- struct LIST_ENTRY FreeList; // Free SXG_SCATTER_GATHER blocks
- struct 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
- struct VLAN_HDR VlanTag; // VLAN tag to be inserted into SGL
- struct SCATTER_GATHER_LIST *pSgl; // SGL Addr. Possibly &Sgl
- struct SXG_X64_SGL Sgl; // SGL handed to card
+struct sxg_scatter_gather {
+ enum SXG_SGL_TYPE Type; /* FIRST! Dumb-nic or offload */
+ ushort Pool; /* Associated SGL pool */
+ ushort Entries; /* SGL total entries */
+ void * adapter; /* Back pointer to adapter */
+ /* Free struct sxg_scatter_gather blocks */
+ struct list_entry FreeList;
+ /* All struct sxg_scatter_gather blocks */
+ struct list_entry AllList;
+ dma64_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 */
+ /* For asynchronous completions */
+ u32 Direction;
+ u32 CurOffset; /* Current SGL offset */
+ u32 SglRef; /* SGL reference count */
+ struct vlan_hdr VlanTag; /* VLAN tag to be inserted into SGL */
+ struct sxg_x64_sgl *pSgl; /* SGL Addr. Possibly &Sgl */
+ struct sxg_x64_sgl Sgl; /* SGL handed to card */
};
+/*
+ * Note - the "- 1" is because struct sxg_scatter_gather=>struct sxg_x64_sgl
+ * includes 1 SGE..
+ */
+#define SXG_SGL_SIZE(_Pool) \
+ (sizeof(struct sxg_scatter_gather) + \
+ ((SxgSglPoolProperties[_Pool].SGEntries - 1) * \
+ sizeof(struct sxg_x64_sge)))
+
+/* 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_BUFFER_LENGTH(_SxgSgl) 0
+#define SXG_SGL_BUF_SIZE 0
+
+/*
#if defined(CONFIG_X86_64)
-#define SXG_SGL_BUFFER(_SxgSgl) (&_SxgSgl->Sgl)
-#define SXG_SGL_BUF_SIZE sizeof(struct SXG_X64_SGL)
+#define SXG_SGL_BUFFER(_SxgSgl) (&_SxgSgl->Sgl)
+#define SXG_SGL_BUFFER_LENGTH(_SxgSgl) ((_SxgSgl)->Entries * \
+ sizeof(struct sxg_x64_sge))
+#define SXG_SGL_BUF_SIZE sizeof(struct 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_BUFFER(_SxgSgl) NULL
+#define SXG_SGL_BUFFER_LENGTH(_SxgSgl) 0
#define SXG_SGL_BUF_SIZE 0
#else
#error staging: sxg: driver is for X86 only!
#endif
+*/
+/* Microcode statistics */
+struct sxg_ucode_stats {
+ u32 RPDQOflow; /* PDQ overflow (unframed ie dq & drop 1st) */
+ u32 XDrops; /* Xmt drops due to no xmt buffer */
+ u32 ERDrops; /* Rcv drops due to ER full */
+ u32 NBDrops; /* Rcv drops due to out of host buffers */
+ u32 PQDrops; /* Rcv drops due to PDQ full */
+ /* Rcv drops due to bad frame: no link addr match, frlen > max */
+ u32 BFDrops;
+ u32 UPDrops; /* Rcv drops due to UPFq full */
+ u32 XNoBufs; /* Xmt drop due to no DRAM Xmit buffer or PxyBuf */
+};
+
+/*
+ * Macros for handling the Offload engine values
+ */
+/* Number of positions to shift Network Header Length before passing to card */
+#define SXG_NW_HDR_LEN_SHIFT 2
diff --git a/drivers/staging/sxg/sxghw.h b/drivers/staging/sxg/sxghw.h
index b0efff9ff11..81f81d4b0ad 100644
--- a/drivers/staging/sxg/sxghw.h
+++ b/drivers/staging/sxg/sxghw.h
@@ -1,4 +1,4 @@
-/*
+/*************************************************************
* Copyright © 1997-2007 Alacritech, Inc. All rights reserved
*
* $Id: sxghw.h,v 1.2 2008/07/24 17:24:23 chris Exp $
@@ -7,682 +7,894 @@
*
* This file contains structures and definitions for the
* Alacritech Sahara hardware
- */
+ *
+ **********************************************************/
-/*******************************************************************************
- * Configuration space
- *******************************************************************************/
+/* PCI Configuration space */
/* PCI Vendor ID */
#define SXG_VENDOR_ID 0x139A /* Alacritech's Vendor ID */
-// PCI Device 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
+
+/* Type of ASIC in use */
+enum asic_type {
+ SAHARA_REV_A,
+ SAHARA_REV_B
+};
+
+/* Type of Xcvr in fiber card */
+enum xcvr_type {
+ XCVR_UNKNOWN,
+ XCVR_NONE,
+ XCVR_SR,
+ XCVR_LR,
+ XCVR_LRM,
+ XCVR_CR
+};
+/*
+ * 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 */
+/* 100022 Sahara prototype (XenPak) board */
+#define SSID_SAHARA_PROTO 0x0018
+#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 */
+/* isolate base SSID bits */
+#define SSID_BASE(ssid) ((ssid) & SSID_BASE_MASK)
+/* isolate SSID OEM bits */
+#define SSID_OEM(ssid) ((ssid) & SSID_OEM_MASK)
+/* isolate SSID function bits */
+#define SSID_FUNC(ssid) ((ssid) & SSID_FUNC_MASK)
+
+
+/* HW Register Space */
+#define SXG_HWREG_MEMSIZE 0x4000 /* 16k */
#pragma pack(push, 1)
-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
+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 */
};
#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
+/* 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
+/* Link Address Registers */
+/* Applied to link address high */
+#define LINK_ADDRESS_ENABLE 0x80000000
-// Microsoft register space size
-#define SXG_UCODEREG_MEMSIZE 0x40000 // 256k
+/* 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
+/*
+ * 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
+/* Extended (or sub) command code */
+#define SXG_ADDRESS_EXCODE_SHIFT 6
#define SXG_ADDRESS_EXCODE_MASK 0x00001FC0
-#define SXG_ADDRESS_CPUID_SHIFT 13 // CPU
+#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
+/* Used to sanity check UCODE_REGS structure */
+#define SXG_REGISTER_SIZE_PER_CPU 0x00002000
+
+/* 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 */
+/* Transport cksum error */
+#define SXG_RCV_STATUS_TRANSPORT_CSUM 0x23000000
+/* Transport underflow */
+#define SXG_RCV_STATUS_TRANSPORT_UFLOW 0x22000000
+ /* Transport header length */
+#define SXG_RCV_STATUS_TRANSPORT_HDRLEN 0x20000000
+/* Transport flags detected */
+#define SXG_RCV_STATUS_TRANSPORT_FLAGS 0x10000000
+ /* Transport options detected */
+#define SXG_RCV_STATUS_TRANSPORT_OPTS 0x08000000
+#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 */
+/* Network cksum error */
+#define SXG_RCV_STATUS_NETWORK_CSUM 0x00830000
+/* Network underflow error */
+#define SXG_RCV_STATUS_NETWORK_UFLOW 0x00820000
+ /* Network header length */
+#define SXG_RCV_STATUS_NETWORK_HDRLEN 0x00800000
+ /* Network overflow detected */
+#define SXG_RCV_STATUS_NETWORK_OFLOW 0x00400000
+/* Network multicast detected */
+#define SXG_RCV_STATUS_NETWORK_MCAST 0x00200000
+/* Network options detected */
+#define SXG_RCV_STATUS_NETWORK_OPTIONS 0x00100000
+/* Network offset detected */
+#define SXG_RCV_STATUS_NETWORK_OFFSET 0x00080000
+/* Network fragment detected */
+#define SXG_RCV_STATUS_NETWORK_FRAGMENT 0x00040000
+/* Network transport type mask */
+#define SXG_RCV_STATUS_NETWORK_TRANS_MASK 0x00030000
+#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 */
+/* Receive priority */
+#define SXG_RCV_STATUS_PKT_PRI 0x00006000
+/* Receive priority shift */
+#define SXG_RCV_STATUS_PKT_PRI_SHFT 13
+/* MAC Receive RAM parity error */
+#define SXG_RCV_STATUS_PARITY 0x00001000
+/* Link address detection mask */
+#define SXG_RCV_STATUS_ADDRESS_MASK 0x00000F00
+
+#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 */
+/* Link address broadcast */
+#define SXG_RCV_STATUS_ADDRESS_BCAST 0x00000300
+ /* Link address multicast */
+#define SXG_RCV_STATUS_ADDRESS_MCAST 0x00000200
+/* Link control multicast */
+#define SXG_RCV_STATUS_ADDRESS_CMCAST 0x00000100
+/* Link status mask */
+#define SXG_RCV_STATUS_LINK_MASK 0x000000FF
+#define SXG_RCV_STATUS_LINK_ERROR 0x00000080 /* Link error */
+/* Link status mask */
+#define SXG_RCV_STATUS_LINK_MASK 0x000000FF
+/* RcvMacQ parity error */
+#define SXG_RCV_STATUS_LINK_PARITY 0x00000087
+#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 */
+/* Network type mask */
+#define SXG_RCV_STATUS_LINK_TYPE_MASK 0x00000007
+#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 */
+/* RcvConfig register reset */
+#define RCV_CONFIG_RESET 0x80000000
+/* Enable the receive logic */
+#define RCV_CONFIG_ENABLE 0x40000000
+/* Enable the receive parser */
+#define RCV_CONFIG_ENPARSE 0x20000000
+/* Enable the socket detector */
+#define RCV_CONFIG_SOCKET 0x10000000
+#define RCV_CONFIG_RCVBAD 0x08000000 /* Receive all bad frames */
+/* Receive all control frames */
+#define RCV_CONFIG_CONTROL 0x04000000
+/* Enable pause transmit when attn */
+#define RCV_CONFIG_RCVPAUSE 0x02000000
+/* Include TCP port w/ IPv6 toeplitz */
+#define RCV_CONFIG_TZIPV6 0x01000000
+/* Include TCP port w/ IPv4 toeplitz */
+#define RCV_CONFIG_TZIPV4 0x00800000
+#define RCV_CONFIG_FLUSH 0x00400000 /* Flush buffers */
+#define RCV_CONFIG_PRIORITY_MASK 0x00300000 /* Priority level */
+#define RCV_CONFIG_CONN_MASK 0x000C0000 /* Number of connections */
+#define RCV_CONFIG_CONN_4K 0x00000000 /* 4k connections */
+#define RCV_CONFIG_CONN_2K 0x00040000 /* 2k connections */
+#define RCV_CONFIG_CONN_1K 0x00080000 /* 1k connections */
+#define RCV_CONFIG_CONN_512 0x000C0000 /* 512 connections */
+#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 */
+/* Buffer length bits 15:4. ie multiple of 16. */
+#define RCV_CONFIG_BUFLEN_MASK 0x0000FFE0
+/* Disable socket detection on attn */
+#define RCV_CONFIG_SKT_DIS 0x00000008
+#define RCV_CONFIG_HIPRICTL 0x00000002 /* Ctrl frames on high-prioirty RcvQ */
+#define RCV_CONFIG_NEWSTATUSFMT 0x00000001 /* Use RevB status format */
+/*
+ * 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 32 byte boundary
+ */
+#define RCV_CONFIG_BUFSIZE(_MaxFrame) \
+ ((((_MaxFrame) + 22) + 31) & RCV_CONFIG_BUFLEN_MASK)
+
+/* XmtConfig register reset */
+#define XMT_CONFIG_RESET 0x80000000
+#define XMT_CONFIG_ENABLE 0x40000000 /* Enable transmit logic */
+/* Inhibit MAC RAM parity error */
+#define XMT_CONFIG_MAC_PARITY 0x20000000
+/* Inhibit D2F buffer parity error */
+#define XMT_CONFIG_BUF_PARITY 0x10000000
+/* Inhibit 1T SRAM parity error */
+#define XMT_CONFIG_MEM_PARITY 0x08000000
+#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 struct 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
+ */
+/* 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 */
+/* Allow the sending of Pause frames */
+#define AXGMAC_CFG1_XMT_PAUSE 0x80000000
+#define AXGMAC_CFG1_XMT_EN 0x40000000 /* Enable transmit */
+/* Allow the detection of Pause frames */
+#define AXGMAC_CFG1_RCV_PAUSE 0x20000000
+#define AXGMAC_CFG1_RCV_EN 0x10000000 /* Enable receive */
+/* Current transmit state - READ ONLY */
+#define AXGMAC_CFG1_XMT_STATE 0x04000000
+/* Current receive state - READ ONLY */
+#define AXGMAC_CFG1_RCV_STATE 0x01000000
+/* Only pause for 64 slot on XOFF */
+#define AXGMAC_CFG1_XOFF_SHORT 0x00001000
+/* Delay transmit FCS 1 4-byte word */
+#define AXGMAC_CFG1_XMG_FCS1 0x00000400
+/* Delay transmit FCS 2 4-byte words */
+#define AXGMAC_CFG1_XMG_FCS2 0x00000800
+/* Delay transmit FCS 3 4-byte words */
+#define AXGMAC_CFG1_XMG_FCS3 0x00000C00
+/* Delay receive FCS 1 4-byte word */
+#define AXGMAC_CFG1_RCV_FCS1 0x00000100
+/* Delay receive FCS 2 4-byte words */
+#define AXGMAC_CFG1_RCV_FCS2 0x00000200
+/* Delay receive FCS 3 4-byte words */
+#define AXGMAC_CFG1_RCV_FCS3 0x00000300
+/* Per-packet override enable */
+#define AXGMAC_CFG1_PKT_OVERRIDE 0x00000080
+#define AXGMAC_CFG1_SWAP 0x00000040 /* Byte swap enable */
+/* ASSERT srdrpfrm on short frame (<64) */
+#define AXGMAC_CFG1_SHORT_ASSERT 0x00000020
+/* RCV only 802.3AE when CLEAR */
+#define AXGMAC_CFG1_RCV_STRICT 0x00000010
+#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 */
+/* Detect VLAN and pad to 68 bytes */
+#define AXGMAC_CFG1_PAD_VLAN 0x00000002
+#define AXGMAC_CFG1_PAD_68 0x00000003 /* Pad to 68 bytes */
+
+/* A-XGMAC Configuration Register 2 */
+/* Generate single pause frame (test) */
+#define AXGMAC_CFG2_GEN_PAUSE 0x80000000
+/* Manual link fault sequence */
+#define AXGMAC_CFG2_LF_MANUAL 0x08000000
+/* Auto link fault sequence */
+#define AXGMAC_CFG2_LF_AUTO 0x04000000
+/* Remote link fault (READ ONLY) */
+#define AXGMAC_CFG2_LF_REMOTE 0x02000000
+/* Local link fault (READ ONLY) */
+#define AXGMAC_CFG2_LF_LOCAL 0x01000000
+#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_CFG2_PAUSE_XMT 0x00008000 /* Pause transmit module */
+/* Enable IPG extension algorithm */
+#define AXGMAC_CFG2_IPG_EXTEN 0x00000020
+#define AXGMAC_CFG2_IPGEX_MASK 0x0000001F /* IPG extension */
+
+/* A-XGMAC Configuration Register 3 */
+/* Receive frame drop filter */
+#define AXGMAC_CFG3_RCV_DROP 0xFFFF0000
+/* Receive frame don't care filter */
+#define AXGMAC_CFG3_RCV_DONT_CARE 0x0000FFFF
+
+/* 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 */
+/* Maximum transmit frame length */
+#define AXGMAC_MAXFRAME_XMT 0x3FFF0000
#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
+/* Maximum receive frame length */
+#define AXGMAC_MAXFRAME_RCV 0x0000FFFF
+/*
+ * 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
+/* 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 */
+/* 10/100/1000 Mbps Phy Write */
+#define AXGMAC_AMIIM_CMD_LEGACY_WRITE 1
+/* 10/100/1000 Mbps Phy Read */
+#define AXGMAC_AMIIM_CMD_LEGACY_READ 2
+#define AXGMAC_AMIIM_CMD_MONITOR_SINGLE 3 /* Monitor single PHY */
+/* Monitor multiple contiguous PHYs */
+#define AXGMAC_AMIIM_CMD_MONITOR_MULTIPLE 4
+/* Present AMIIM Field Reg */
+#define AXGMAC_AMIIM_CMD_10G_OPERATION 5
+/* Clear Link Fail Bit in MIIM */
+#define AXGMAC_AMIIM_CMD_CLEAR_LINK_FAIL 6
+
+/* 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 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)
+/* Port address field (hstphyadx in spec) */
+#define AXGMAC_AMIIM_FIELD_PORT_ADDR 0x0F800000
#define AXGMAC_AMIIM_FIELD_PORT_SHIFT 23
-#define AXGMAC_AMIIM_FIELD_DEV_ADDR 0x007C0000 // Device address field (hstregadx in spec)
+/* Device address field (hstregadx in spec) */
+#define AXGMAC_AMIIM_FIELD_DEV_ADDR 0x007C0000
#define AXGMAC_AMIIM_FIELD_DEV_SHIFT 18
-#define AXGMAC_AMIIM_FIELD_TA 0x00030000 // 2-bit TA field
+#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
+#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
+/* 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
-
-
-/***************************************************************************
+/*
+ * 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
+ */
+/* PHY PMA/PMD module MIIM device number */
+#define MIIM_DEV_PHY_PMA 1
+/* PHY PCS module MIIM device number */
+#define MIIM_DEV_PHY_PCS 3
+/* PHY XS module MIIM device number */
+#define MIIM_DEV_PHY_XS 4
+#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 */
+/* Bypass preamble of mngmt frame */
+#define AXGMAC_AMIIM_CFG_NOPREAM 0x00000080
+/* half-clock duration of MDC output */
+#define AXGMAC_AMIIM_CFG_HALF_CLOCK 0x0000007F
+
+/* A-XGMAC AMIIM Indicator Register */
+/* Link status from legacy PHY or MMD */
+#define AXGMAC_AMIIM_INDC_LINK 0x00000010
+/* Multiple phy operation in progress */
+#define AXGMAC_AMIIM_INDC_MPHY 0x00000008
+/* Single phy operation in progress */
+#define AXGMAC_AMIIM_INDC_SPHY 0x00000004
+/* Single or multiple monitor cmd */
+#define AXGMAC_AMIIM_INDC_MON 0x00000002
+/* Set until cmd operation complete */
+#define AXGMAC_AMIIM_INDC_BUSY 0x00000001
+
+/* 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 */
+/* Hold XAUI XGXS logic reset until Serdes is up */
+#define LS_XGXS_CTL 0x10000000
+/* When 0, XAUI Serdes is up and initialization is complete */
+#define LS_SERDES_DOWN 0x08000000
+/* When 0, Trace Serdes is up and initialization is complete */
+#define LS_TRACE_DOWN 0x04000000
+/* Set PHY clock to 25 MHz (else 156.125 MHz) */
+#define LS_PHY_CLK_25MHZ 0x02000000
+#define LS_PHY_CLK_EN 0x01000000 /* Enable clock to PHY */
+#define LS_XAUI_LINK_UP 0x00000010 /* XAUI link is up */
+/* XAUI link status has changed */
+#define LS_XAUI_LINK_CHNG 0x00000008
+#define LS_LINK_ALARM 0x00000004 /* Link alarm pin */
+/* Mask link attention control bits */
+#define LS_ATTN_CTRL_MASK 0x00000003
+#define LS_ATTN_ALARM 0x00000000 /* 00 => Attn on link alarm */
+/* 01 => Attn on link alarm or status change */
+#define LS_ATTN_ALARM_OR_STAT_CHNG 0x00000001
+/* 10 => Attn on link status change */
+#define LS_ATTN_STAT_CHNG 0x00000002
+#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
-
-/***************************************************************************
+ */
+/* 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 (?) */
+/* Everything reserved except zero (?) */
+#define XGXS_CONTROL1_SPEED 0x003C
+
+/* 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
-struct PHY_UCODE {
+ */
+/*
+ * 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 */
+/* Enable RX_ALARM interrupts */
+#define LASI_CTL_RX_ALARM_ENABLE 0x0004
+/* Enable TX_ALARM interrupts */
+#define LASI_CTL_TX_ALARM_ENABLE 0x0002
+/* Enable Link Status interrupts */
+#define LASI_CTL_LS_ALARM_ENABLE 0x0001
+
+/* 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 */
+
+#define XCVR_VENDOR_LEN 16 /* xcvr vendor len */
+#define XCVR_MODEL_LEN 16 /* xcvr model len */
+
+/* PHY Microcode download data structure */
+struct phy_ucode {
ushort Addr;
ushort Data;
};
+/* Slow Bus Register Definitions */
+
+/* Module 0 registers */
+#define GPIO_L_IN 0x15 /* GPIO input (low) */
+#define GPIO_L_OUT 0x16 /* GPIO output (low) */
+#define GPIO_L_DIR 0x17 /* GPIO direction (low) */
+#define GPIO_H_IN 0x19 /* GPIO input (high) */
+#define GPIO_H_OUT 0x1A /* GPIO output (high) */
+#define GPIO_H_DIR 0x1B /* GPIO direction (high) */
-/*****************************************************************************
+/* Definitions for other slow bus registers can be added as needed */
+
+
+/*
* 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.
+ *
+ * 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)
-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
+struct xmt_desc {
+ ushort XmtLen; /* word 0, bits [15:0] - transmit length */
+ /* word 0, bits [23:16] - transmit control byte */
+ unsigned char XmtCtl;
+ /* word 0, bits [31:24] - transmit command plus misc. */
+ unsigned char Cmd;
+ /* word 1, bits [31:0] - transmit buffer ID */
+ u32 XmtBufId;
+ /* word 2, bits [7:0] - byte address of TCP header */
+ unsigned char TcpStrt;
+ /* word 2, bits [15:8] - byte address of IP header */
+ unsigned char IpStrt;
+ /* word 2, bits [31:16] - partial IP checksum */
+ ushort IpCkSum;
+ /* word 3, bits [15:0] - partial TCP checksum */
+ ushort TcpCkSum;
+ 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 */
};
#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
+/* struct 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 */
+/* comand code shift (shift to bits [31:30] in word 0) */
+#define XMT_DESC_CMD_CODE_SHFT 6
+ /* 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)
+
+/*
+ * struct xmt_desc Control Byte (XmtCtl) definitions
+ * NOTE: These bits do not work on Sahara (Rev A)!
+ */
+/* current frame is a pause control frame (for statistics) */
+#define XMT_CTL_PAUSE_FRAME 0x80
+/* current frame is a control frame (for statistics) */
+#define XMT_CTL_CONTROL_FRAME 0x40
+#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 */
+/* pad frame to 64 bytes, and VLAN frames to 68 bytes */
+#define XMT_CTL_PAD_MODE_VLAN_68 0x10
+#define XMT_CTL_PAD_MODE_68 0x18 /* pad frame to 68 bytes */
+/* generate FCS (CRC) for this frame */
+#define XMT_CTL_GEN_FCS 0x04
+#define XMT_CTL_DELAY_FCS_0 0x00 /* do not delay FCS calcution */
+/* delay FCS calculation by 1 (4-byte) word */
+#define XMT_CTL_DELAY_FCS_1 0x01
+/* delay FCS calculation by 2 (4-byte) words */
+#define XMT_CTL_DELAY_FCS_2 0x02
+/* delay FCS calculation by 3 (4-byte) words */
+#define XMT_CTL_DELAY_FCS_3 0x03
+
+/* struct xmt_desc XmtBufId definition */
+/*
+ * The Xmt buffer ID is formed by dividing the buffer (DRAM) address
+ * by 256 (or << 8)
+ */
+
+#define XMT_BUF_ID_SHFT 8
+
+/* Receiver Sequencer Definitions */
+
+/* Receive Event Queue (queues 3 - 6) bit definitions */
+/* bit mask for the Receive Buffer ID */
+#define RCV_EVTQ_RBFID_MASK 0x0000FFFF
+
+/* Receive Buffer ID definition */
+/*
+ * The Rcv buffer ID is formed by dividing the buffer (DRAM) address
+ * by 32 (or << 5)
+ */
+#define RCV_BUF_ID_SHFT 5
+
+/*
+ * Format of the 18 byte Receive Buffer returned by the
+ * Receive Sequencer for received packets
+ */
#pragma pack(push, 1)
-struct RCV_BUF_HDR {
- u32 Status; // Status word from Rcv Seq Parser
- ushort Length; // Rcv packet byte count
+struct rcv_buf_hdr {
+ u32 Status; /* Status word from Rcv Seq Parser */
+ ushort Length; /* Rcv packet byte count */
union {
- ushort TcpCsum; // TCP checksum
+ ushort TcpCsum; /* TCP checksum */
struct {
- unsigned char TcpCsumL; // lower 8 bits of the TCP checksum
- unsigned char LinkHash; // Link hash (multicast frames only)
+ /* lower 8 bits of the TCP checksum */
+ unsigned char TcpCsumL;
+ /* Link hash (multicast frames only) */
+ unsigned char LinkHash;
};
};
- 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
+ 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 */
};
#pragma pack(pop)
-
-/*****************************************************************************
- * Queue definitions
- *****************************************************************************/
+/* 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 */
+#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 */
+#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 */
+#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 */
+/* enable copy of xmt descriptor to xmt command queue */
+#define PXY_COPY_EN 0x00200000
+#define PXY_SIZE_16 0x00000000 /* copy 16 bytes */
+#define PXY_SIZE_32 0x00100000 /* copy 32 bytes */
+
+/* SXG EEPROM/Flash Configuration Definitions */
+
+/* Location of configuration data in EEPROM or Flash */
+/* start addr for config info in EEPROM */
+#define EEPROM_CONFIG_START_ADDR 0x00
+/* start addr for config info in Flash */
+#define FLASH_CONFIG_START_ADDR 0x80
+
+/* Configuration data section defines */
+#define HW_CFG_SECTION_SIZE 512 /* size of H/W section */
+#define HW_CFG_SECTION_SIZE_A 256 /* size of H/W section (Sahara rev A) */
+/* starting location (offset) of S/W section */
+#define SW_CFG_SECTION_START 512
+/* starting location (offset) of S/W section (Sahara rev A) */
+#define SW_CFG_SECTION_START_A 256
+#define SW_CFG_SECTION_SIZE 128 /* size of S/W section */
+/*
+ * H/W configuration data magic word Goes in Addr field of first
+ * struct hw_cfg_data entry
+ */
+#define HW_CFG_MAGIC_WORD 0xA5A5
+/*
+ * H/W configuration data terminator Goes in Addr field of last
+ * struct hw_cfg_data entry
+ */
+#define HW_CFG_TERMINATOR 0xFFFF
-/*****************************************************************************
- * SXG EEPROM/Flash Configuration Definitions
- *****************************************************************************/
-#pragma pack(push, 1)
+#define SW_CFG_MAGIC_WORD 0x5A5A /* S/W configuration data magic word */
-/* */
-struct HW_CFG_DATA {
- ushort Addr;
- union {
- ushort Data;
- ushort Checksum;
- };
+#pragma pack(push, 1)
+/*
+ * Structure for an element of H/W configuration data.
+ * Read by the Sahara hardware
+ */
+struct hw_cfg_data {
+ ushort Addr;
+ ushort Data;
};
-/* */
-#define NUM_HW_CFG_ENTRIES ((128/sizeof(struct HW_CFG_DATA)) - 4)
-
-/* MAC address */
-struct SXG_CONFIG_MAC {
- unsigned char MacAddr[6]; /* MAC Address */
+/*
+ * Number of struct hw_cfg_data structures to put in the configuration data
+ * data structure (struct sxg_config or struct sxg_config_a). The number is
+ * computed to fill the entire H/W config section of the structure.
+ */
+#define NUM_HW_CFG_ENTRIES \
+ (HW_CFG_SECTION_SIZE / sizeof(struct hw_cfg_data))
+#define NUM_HW_CFG_ENTRIES_A \
+ (HW_CFG_SECTION_SIZE_A / sizeof(struct hw_cfg_data))
+
+/* MAC address structure */
+struct sxg_config_mac {
+ unsigned char MacAddr[6]; /* MAC Address */
};
-/* */
-struct ATK_FRU {
+/* FRU data structure */
+struct atk_fru {
unsigned char PartNum[6];
unsigned char Revision[2];
unsigned char Serial[14];
@@ -697,38 +909,112 @@ struct ATK_FRU {
#define EMC_FRU_FORMAT 0x0005
#define NO_FRU_FORMAT 0xFFFF
+#define ATK_OEM_ASSY_SIZE 10 /* assy num is 9 chars plus \0 */
+
+/* OEM FRU structure for Alacritech */
+struct atk_oem {
+ unsigned char Assy[ATK_OEM_ASSY_SIZE];
+};
+
+#define OEM_EEPROM_FRUSIZE 74 /* size of OEM fru info - size */
+/* chosen to fill out the S/W section */
+
+union oem_fru { /* OEM FRU information */
+ unsigned char OemFru[OEM_EEPROM_FRUSIZE];
+ struct atk_oem AtkOem;
+};
+
+/* Structure to hold the S/W configuration data. */
+struct sw_cfg_data {
+ ushort MagicWord; /* Magic word for section 2 */
+ ushort Version; /* Format version */
+ struct sxg_config_mac MacAddr[4]; /* space for 4 MAC addresses */
+ struct atk_fru AtkFru; /* FRU information */
+ ushort OemFruFormat; /* OEM FRU format type */
+ union oem_fru OemFru; /* OEM FRU information */
+ ushort Checksum; /* Checksum of section 2 */
+};
+
+
/* EEPROM/Flash Format */
-struct SXG_CONFIG {
- /* */
- /* Section 1 (128 bytes) */
- /* */
- ushort MagicWord; /* EEPROM/FLASH Magic code 'A5A5' */
- ushort SpiClks; /* SPI bus clock dividers */
- struct HW_CFG_DATA HwCfg[NUM_HW_CFG_ENTRIES];
- /* */
- /* */
- /* */
- ushort Version; /* EEPROM format version */
- struct SXG_CONFIG_MAC MacAddr[4]; /* space for 4 MAC addresses */
- struct 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 */
+struct sxg_config {
+ /* H/W Section - Read by Sahara hardware (512 bytes) */
+ struct hw_cfg_data HwCfg[NUM_HW_CFG_ENTRIES];
+ /* S/W Section - Other configuration data (128 bytes) */
+ struct sw_cfg_data SwCfg;
};
-#pragma pack(pop)
-/*****************************************************************************
- * Miscellaneous Hardware definitions
- *****************************************************************************/
+#ifdef WINDOWS_COMPILER
+/*
+ * The following macro is something of a kludge, but it is the only way
+ * that I could find to catch certain programming errors at compile time.
+ * If the asserted condition is true, then nothing happens. If false, then
+ * the compiler tries to typedef an array with -1 members, which generates
+ * an error. Unfortunately, the error message is meaningless, but at least
+ * it catches the problem. This macro would be unnecessary if the compiler
+ * allowed the sizeof and offsetof macros to be used in the #if directive.
+ */
+#define compile_time_assert(cond) \
+ typedef char comp_error[(cond) ? 1 : -1]
+
+/*
+ * A compiler error on either of the next two lines indicates that the struct sxg_config
+ * structure was built incorrectly. Unfortunately, the error message produced
+ * is meaningless. But this is apparently the only way to catch this problem
+ * at compile time.
+ */
+compile_time_assert (offsetof(struct sxg_config, SwCfg) == SW_CFG_SECTION_START);
+compile_time_assert (sizeof(struct sxg_config) == HW_CFG_SECTION_SIZE
+ + SW_CFG_SECTION_SIZE);
+
+compile_time_assert (offsetof(struct sxg_config_a, SwCfg)
+ == SW_CFG_SECTION_START_A);
+compile_time_assert (sizeof(struct sxg_config_a) == HW_CFG_SECTION_SIZE_A
+ + SW_CFG_SECTION_SIZE);
+#endif
+/*
+ * Structure used to pass information between driver and user-mode
+ * control application
+ */
+struct adapt_userinfo {
+ bool LinkUp;
+ /* use LinkUp - any need for other states? */
+ /* u32 LinkState; */
+ u32 LinkSpeed; /* not currently needed */
+ u32 LinkDuplex; /* not currently needed */
+ enum xcvr_type XcvrType; /* type of xcvr on fiber card */
+ /* fiber card xcvr vendor */
+ unsigned char XcvrVendor[XCVR_VENDOR_LEN];
+ unsigned char XcvrMode[XCVR_MODEL_LEN];
+ u32 Port; /* not currently needed */
+ u32 PhysPort; /* not currently needed */
+ ushort PciLanes;
+ unsigned char MacAddr[6];
+ unsigned char CurrMacAddr[6];
+ struct atk_fru AtkFru;
+ ushort OemFruFormat;
+ union oem_fru OemFru;
+};
-// 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)
+#pragma pack(pop)
-// 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
+/* Miscellaneous Hardware definitions */
+
+/* Hardware Type definitions */
+
+/* Sahara (ASIC level) defines */
+#define SAHARA_GRAM_SIZE 0x020000 /* GRAM size - 128 KB */
+#define SAHARA_DRAM_SIZE 0x200000 /* DRAM size - 2 MB */
+/* QRAM size - 16K entries (64 KB) */
+#define SAHARA_QRAM_SIZE 0x004000
+/* WCS - 8K instructions (x 108 bits) */
+#define SAHARA_WCS_SIZE 0x002000
+
+/* Arabia (board level) defines */
+#define FLASH_SIZE 0x080000 /* 512 KB (4 Mb) */
+/* EEPROM size (bytes), including xfmr area */
+#define EEPROM_SIZE_XFMR 1024
+/* EEPROM size excluding xfmr area (512 + 128) */
+#define EEPROM_SIZE_NO_XFMR 640
+/* EEPROM size for Sahara rev A */
+#define EEPROM_SIZE_REV_A 512
diff --git a/drivers/staging/sxg/sxgphycode-1.2.h b/drivers/staging/sxg/sxgphycode-1.2.h
new file mode 100644
index 00000000000..b5448b9b278
--- /dev/null
+++ b/drivers/staging/sxg/sxgphycode-1.2.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright ? 1997-2008 Alacritech, Inc. All rights reserved
+ *
+ * $Id: sxgphycode.h,v 1.2 2008/10/02 01:44:07 Exp $
+ *
+ * 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)
+// AEL2005 SR firmware rev 18 (microInit_mdio_SR_AEL2005C_18.tx).
+static struct 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)
+
+ // Transceiver-specific MDIO Patches:
+ {0xc003, 0x0181}, // (bit 7) enable the CDR inc setting in 1.C005 (mandatory patch for SR code)
+ {0xc010, 0x448a}, // (bit 14) mask out high BER input from the LOS signal in 1.000A (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, 0x2ff4}, {0xcc01, 0x3cd4}, {0xcc02, 0x2015}, {0xcc03, 0x3125},
+ {0xcc04, 0x6524}, {0xcc05, 0x27ff}, {0xcc06, 0x300f}, {0xcc07, 0x2c8b},
+ {0xcc08, 0x300b}, {0xcc09, 0x4009}, {0xcc0a, 0x400e}, {0xcc0b, 0x2f12},
+ {0xcc0c, 0x3002}, {0xcc0d, 0x1002}, {0xcc0e, 0x2112}, {0xcc0f, 0x3012},
+ {0xcc10, 0x1002}, {0xcc11, 0x2572}, {0xcc12, 0x3012}, {0xcc13, 0x1002},
+ {0xcc14, 0xd01e}, {0xcc15, 0x2772}, {0xcc16, 0x3012}, {0xcc17, 0x1002},
+ {0xcc18, 0x2004}, {0xcc19, 0x3c84}, {0xcc1a, 0x6436}, {0xcc1b, 0x2007},
+ {0xcc1c, 0x3f87}, {0xcc1d, 0x8676}, {0xcc1e, 0x40b7}, {0xcc1f, 0xa746},
+ {0xcc20, 0x4047}, {0xcc21, 0x5673}, {0xcc22, 0x2982}, {0xcc23, 0x3002},
+ {0xcc24, 0x13d2}, {0xcc25, 0x8bbd}, {0xcc26, 0x2802}, {0xcc27, 0x3012},
+ {0xcc28, 0x1002}, {0xcc29, 0x2032}, {0xcc2a, 0x3012}, {0xcc2b, 0x1002},
+ {0xcc2c, 0x5cc3}, {0xcc2d, 0x0314}, {0xcc2e, 0x2942}, {0xcc2f, 0x3002},
+ {0xcc30, 0x1002}, {0xcc31, 0xd019}, {0xcc32, 0x2fd2}, {0xcc33, 0x3002},
+ {0xcc34, 0x1002}, {0xcc35, 0x2a04}, {0xcc36, 0x3c74}, {0xcc37, 0x6435},
+ {0xcc38, 0x2fa4}, {0xcc39, 0x3cd4}, {0xcc3a, 0x6624}, {0xcc3b, 0x5563},
+ {0xcc3c, 0x2d42}, {0xcc3d, 0x3002}, {0xcc3e, 0x13d2}, {0xcc3f, 0x464d},
+ {0xcc40, 0x2802}, {0xcc41, 0x3012}, {0xcc42, 0x1002}, {0xcc43, 0x2fd2},
+ {0xcc44, 0x3002}, {0xcc45, 0x1002}, {0xcc46, 0x2fb4}, {0xcc47, 0x3cd4},
+ {0xcc48, 0x6624}, {0xcc49, 0x5563}, {0xcc4a, 0x2d42}, {0xcc4b, 0x3002},
+ {0xcc4c, 0x13d2}, {0xcc4d, 0x2e72}, {0xcc4e, 0x3002}, {0xcc4f, 0x1002},
+ {0xcc50, 0x2f72}, {0xcc51, 0x3002}, {0xcc52, 0x1002}, {0xcc53, 0x0004},
+ {0xcc54, 0x2942}, {0xcc55, 0x3002}, {0xcc56, 0x1002}, {0xcc57, 0x2032},
+ {0xcc58, 0x3012}, {0xcc59, 0x1002}, {0xcc5a, 0x5cc3}, {0xcc5b, 0x0317},
+ {0xcc5c, 0x2f12}, {0xcc5d, 0x3002}, {0xcc5e, 0x1002}, {0xcc5f, 0x2942},
+ {0xcc60, 0x3002}, {0xcc61, 0x1002}, {0xcc62, 0x22cd}, {0xcc63, 0x301d},
+ {0xcc64, 0x2802}, {0xcc65, 0x3012}, {0xcc66, 0x1002}, {0xcc67, 0x20b2},
+ {0xcc68, 0x3012}, {0xcc69, 0x1002}, {0xcc6a, 0x5aa3}, {0xcc6b, 0x2dc2},
+ {0xcc6c, 0x3002}, {0xcc6d, 0x1312}, {0xcc6e, 0x2d02}, {0xcc6f, 0x3002},
+ {0xcc70, 0x1002}, {0xcc71, 0x2807}, {0xcc72, 0x31a7}, {0xcc73, 0x20c4},
+ {0xcc74, 0x3c24}, {0xcc75, 0x6724}, {0xcc76, 0x1002}, {0xcc77, 0x2807},
+ {0xcc78, 0x3187}, {0xcc79, 0x20c4}, {0xcc7a, 0x3c24}, {0xcc7b, 0x6724},
+ {0xcc7c, 0x1002}, {0xcc7d, 0x2514}, {0xcc7e, 0x3c64}, {0xcc7f, 0x6436},
+ {0xcc80, 0xdff4}, {0xcc81, 0x6436}, {0xcc82, 0x1002}, {0xcc83, 0x40a4},
+ {0xcc84, 0x643c}, {0xcc85, 0x4016}, {0xcc86, 0x8c6c}, {0xcc87, 0x2b24},
+ {0xcc88, 0x3c24}, {0xcc89, 0x6435}, {0xcc8a, 0x1002}, {0xcc8b, 0x2b24},
+ {0xcc8c, 0x3c24}, {0xcc8d, 0x643a}, {0xcc8e, 0x4025}, {0xcc8f, 0x8a5a},
+ {0xcc90, 0x1002}, {0xcc91, 0x26d1}, {0xcc92, 0x3011}, {0xcc93, 0x1001},
+ {0xcc94, 0xc7a0}, {0xcc95, 0x0100}, {0xcc96, 0xc502}, {0xcc97, 0x53ac},
+ {0xcc98, 0xc503}, {0xcc99, 0xd5d5}, {0xcc9a, 0xc600}, {0xcc9b, 0x2a6d},
+ {0xcc9c, 0xc601}, {0xcc9d, 0x2a4c}, {0xcc9e, 0xc602}, {0xcc9f, 0x0111},
+ {0xcca0, 0xc60c}, {0xcca1, 0x5900}, {0xcca2, 0xc710}, {0xcca3, 0x0700},
+ {0xcca4, 0xc718}, {0xcca5, 0x0700}, {0xcca6, 0xc720}, {0xcca7, 0x4700},
+ {0xcca8, 0xc801}, {0xcca9, 0x7f50}, {0xccaa, 0xc802}, {0xccab, 0x7760},
+ {0xccac, 0xc803}, {0xccad, 0x7fce}, {0xccae, 0xc804}, {0xccaf, 0x5700},
+ {0xccb0, 0xc805}, {0xccb1, 0x5f11}, {0xccb2, 0xc806}, {0xccb3, 0x4751},
+ {0xccb4, 0xc807}, {0xccb5, 0x57e1}, {0xccb6, 0xc808}, {0xccb7, 0x2700},
+ {0xccb8, 0xc809}, {0xccb9, 0x0000}, {0xccba, 0xc821}, {0xccbb, 0x0002},
+ {0xccbc, 0xc822}, {0xccbd, 0x0014}, {0xccbe, 0xc832}, {0xccbf, 0x1186},
+ {0xccc0, 0xc847}, {0xccc1, 0x1e02}, {0xccc2, 0xc013}, {0xccc3, 0xf341},
+ {0xccc4, 0xc01a}, {0xccc5, 0x0446}, {0xccc6, 0xc024}, {0xccc7, 0x1000},
+ {0xccc8, 0xc025}, {0xccc9, 0x0a00}, {0xccca, 0xc026}, {0xcccb, 0x0c0c},
+ {0xcccc, 0xc027}, {0xcccd, 0x0c0c}, {0xccce, 0xc029}, {0xcccf, 0x00a0},
+ {0xccd0, 0xc030}, {0xccd1, 0x0a00}, {0xccd2, 0xc03c}, {0xccd3, 0x001c},
+ {0xccd4, 0xc005}, {0xccd5, 0x7a06}, {0xccd6, 0x0000}, {0xccd7, 0x26d1},
+ {0xccd8, 0x3011}, {0xccd9, 0x1001}, {0xccda, 0xc620}, {0xccdb, 0x0000},
+ {0xccdc, 0xc621}, {0xccdd, 0x003f}, {0xccde, 0xc622}, {0xccdf, 0x0000},
+ {0xcce0, 0xc623}, {0xcce1, 0x0000}, {0xcce2, 0xc624}, {0xcce3, 0x0000},
+ {0xcce4, 0xc625}, {0xcce5, 0x0000}, {0xcce6, 0xc627}, {0xcce7, 0x0000},
+ {0xcce8, 0xc628}, {0xcce9, 0x0000}, {0xccea, 0xc62c}, {0xcceb, 0x0000},
+ {0xccec, 0x0000}, {0xcced, 0x2806}, {0xccee, 0x3cb6}, {0xccef, 0xc161},
+ {0xccf0, 0x6134}, {0xccf1, 0x6135}, {0xccf2, 0x5443}, {0xccf3, 0x0303},
+ {0xccf4, 0x6524}, {0xccf5, 0x000b}, {0xccf6, 0x1002}, {0xccf7, 0x2104},
+ {0xccf8, 0x3c24}, {0xccf9, 0x2105}, {0xccfa, 0x3805}, {0xccfb, 0x6524},
+ {0xccfc, 0xdff4}, {0xccfd, 0x4005}, {0xccfe, 0x6524}, {0xccff, 0x1002},
+ {0xcd00, 0x5dd3}, {0xcd01, 0x0306}, {0xcd02, 0x2ff7}, {0xcd03, 0x38f7},
+ {0xcd04, 0x60b7}, {0xcd05, 0xdffd}, {0xcd06, 0x000a}, {0xcd07, 0x1002},
+ {0xcd08, 0x0000},
+ // end of code block
+
+ // Unpause the microcontroller to start program
+ {0xca00, 0x0080},
+ {0xca12, 0x0000},
+ {0x0000, 0x000A}, // wait 10ms just to be safe
+
+ // Configure the LED's
+ {0xc214, 0x0099}, // configure the LED drivers (for Sahara rev B)
+ {0xc216, 0x0400}, // configure the one LED
+ {0xc217, 0x0000}, // don't drive the 2nd LED (if it exists)
+
+ {0xffff, 0xffff} // table terminator
+};
diff --git a/drivers/staging/sxg/sxgphycode.h b/drivers/staging/sxg/sxgphycode.h
deleted file mode 100644
index 167f356ef86..00000000000
--- a/drivers/staging/sxg/sxgphycode.h
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * 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 struct 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/uc2322/Kconfig b/drivers/staging/uc2322/Kconfig
new file mode 100644
index 00000000000..2e0c6e79df2
--- /dev/null
+++ b/drivers/staging/uc2322/Kconfig
@@ -0,0 +1,10 @@
+config USB_SERIAL_ATEN2011
+ tristate "ATEN 2011 USB to serial device support"
+ depends on USB_SERIAL
+ default N
+ ---help---
+ Say Y here if you want to use a ATEN 2011 dual port USB to serial
+ adapter.
+
+ To compile this driver as a module, choose M here: the module will be
+ called aten2011.
diff --git a/drivers/staging/uc2322/Makefile b/drivers/staging/uc2322/Makefile
new file mode 100644
index 00000000000..49c18d6e579
--- /dev/null
+++ b/drivers/staging/uc2322/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_SERIAL_ATEN2011) += aten2011.o
diff --git a/drivers/staging/uc2322/TODO b/drivers/staging/uc2322/TODO
new file mode 100644
index 00000000000..c189a64c418
--- /dev/null
+++ b/drivers/staging/uc2322/TODO
@@ -0,0 +1,7 @@
+TODO:
+ - checkpatch.pl cleanups
+ - remove dead and useless code (auditing the tty ioctls to
+ verify that they really are correct and needed.)
+
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
+Russell Lang <gsview@ghostgum.com.au>.
diff --git a/drivers/staging/uc2322/aten2011.c b/drivers/staging/uc2322/aten2011.c
new file mode 100644
index 00000000000..85b70545306
--- /dev/null
+++ b/drivers/staging/uc2322/aten2011.c
@@ -0,0 +1,2452 @@
+/*
+ * Aten 2011 USB serial driver for 4 port devices
+ *
+ * Copyright (C) 2000 Inside Out Networks
+ * Copyright (C) 2001-2002, 2009 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2009 Novell Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+
+#define ZLP_REG1 0x3A /* Zero_Flag_Reg1 58 */
+#define ZLP_REG2 0x3B /* Zero_Flag_Reg2 59 */
+#define ZLP_REG3 0x3C /* Zero_Flag_Reg3 60 */
+#define ZLP_REG4 0x3D /* Zero_Flag_Reg4 61 */
+#define ZLP_REG5 0x3E /* Zero_Flag_Reg5 62 */
+
+/* Interrupt Rotinue Defines */
+#define SERIAL_IIR_RLS 0x06
+#define SERIAL_IIR_RDA 0x04
+#define SERIAL_IIR_CTI 0x0c
+#define SERIAL_IIR_THR 0x02
+#define SERIAL_IIR_MS 0x00
+
+/* Emulation of the bit mask on the LINE STATUS REGISTER. */
+#define SERIAL_LSR_DR 0x0001
+#define SERIAL_LSR_OE 0x0002
+#define SERIAL_LSR_PE 0x0004
+#define SERIAL_LSR_FE 0x0008
+#define SERIAL_LSR_BI 0x0010
+#define SERIAL_LSR_THRE 0x0020
+#define SERIAL_LSR_TEMT 0x0040
+#define SERIAL_LSR_FIFOERR 0x0080
+
+/* MSR bit defines(place holders) */
+#define ATEN_MSR_DELTA_CTS 0x10
+#define ATEN_MSR_DELTA_DSR 0x20
+#define ATEN_MSR_DELTA_RI 0x40
+#define ATEN_MSR_DELTA_CD 0x80
+
+/* Serial Port register Address */
+#define RECEIVE_BUFFER_REGISTER ((__u16)(0x00))
+#define TRANSMIT_HOLDING_REGISTER ((__u16)(0x00))
+#define INTERRUPT_ENABLE_REGISTER ((__u16)(0x01))
+#define INTERRUPT_IDENT_REGISTER ((__u16)(0x02))
+#define FIFO_CONTROL_REGISTER ((__u16)(0x02))
+#define LINE_CONTROL_REGISTER ((__u16)(0x03))
+#define MODEM_CONTROL_REGISTER ((__u16)(0x04))
+#define LINE_STATUS_REGISTER ((__u16)(0x05))
+#define MODEM_STATUS_REGISTER ((__u16)(0x06))
+#define SCRATCH_PAD_REGISTER ((__u16)(0x07))
+#define DIVISOR_LATCH_LSB ((__u16)(0x00))
+#define DIVISOR_LATCH_MSB ((__u16)(0x01))
+
+#define SP1_REGISTER ((__u16)(0x00))
+#define CONTROL1_REGISTER ((__u16)(0x01))
+#define CLK_MULTI_REGISTER ((__u16)(0x02))
+#define CLK_START_VALUE_REGISTER ((__u16)(0x03))
+#define DCR1_REGISTER ((__u16)(0x04))
+#define GPIO_REGISTER ((__u16)(0x07))
+
+#define SERIAL_LCR_DLAB ((__u16)(0x0080))
+
+/*
+ * URB POOL related defines
+ */
+#define NUM_URBS 16 /* URB Count */
+#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */
+
+#define USB_VENDOR_ID_ATENINTL 0x0557
+#define ATENINTL_DEVICE_ID_2011 0x2011
+#define ATENINTL_DEVICE_ID_7820 0x7820
+
+static struct usb_device_id id_table[] = {
+ { USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_2011) },
+ { USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_7820) },
+ { } /* terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+/* This structure holds all of the local port information */
+struct ATENINTL_port {
+ int port_num; /*Actual port number in the device(1,2,etc)*/
+ __u8 bulk_out_endpoint; /* the bulk out endpoint handle */
+ unsigned char *bulk_out_buffer; /* buffer used for the bulk out endpoint */
+ struct urb *write_urb; /* write URB for this port */
+ __u8 bulk_in_endpoint; /* the bulk in endpoint handle */
+ unsigned char *bulk_in_buffer; /* the buffer we use for the bulk in endpoint */
+ struct urb *read_urb; /* read URB for this port */
+ __u8 shadowLCR; /* last LCR value received */
+ __u8 shadowMCR; /* last MCR value received */
+ char open;
+ char chaseResponsePending;
+ wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
+ wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */
+ struct async_icount icount;
+ struct usb_serial_port *port; /* loop back to the owner of this object */
+ /*Offsets*/
+ __u8 SpRegOffset;
+ __u8 ControlRegOffset;
+ __u8 DcrRegOffset;
+ /* for processing control URBS in interrupt context */
+ struct urb *control_urb;
+ char *ctrl_buf;
+ int MsrLsr;
+
+ struct urb *write_urb_pool[NUM_URBS];
+ /* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */
+ struct ktermios tmp_termios; /* stores the old termios settings */
+ spinlock_t lock; /* private lock */
+};
+
+/* This structure holds all of the individual serial device information */
+struct ATENINTL_serial {
+ __u8 interrupt_in_endpoint; /* the interrupt endpoint handle */
+ unsigned char *interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */
+ struct urb *interrupt_read_urb; /* our interrupt urb */
+ __u8 bulk_in_endpoint; /* the bulk in endpoint handle */
+ unsigned char *bulk_in_buffer; /* the buffer we use for the bulk in endpoint */
+ struct urb *read_urb; /* our bulk read urb */
+ __u8 bulk_out_endpoint; /* the bulk out endpoint handle */
+ struct usb_serial *serial; /* loop back to the owner of this object */
+ int ATEN2011_spectrum_2or4ports; /* this says the number of ports in the device */
+ /* Indicates about the no.of opened ports of an individual USB-serial adapater. */
+ unsigned int NoOfOpenPorts;
+ /* a flag for Status endpoint polling */
+ unsigned char status_polling_started;
+};
+
+static void ATEN2011_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port,
+ struct ktermios *old_termios);
+static void ATEN2011_change_port_settings(struct tty_struct *tty,
+ struct ATENINTL_port *ATEN2011_port,
+ struct ktermios *old_termios);
+
+/*************************************
+ * Bit definitions for each register *
+ *************************************/
+#define LCR_BITS_5 0x00 /* 5 bits/char */
+#define LCR_BITS_6 0x01 /* 6 bits/char */
+#define LCR_BITS_7 0x02 /* 7 bits/char */
+#define LCR_BITS_8 0x03 /* 8 bits/char */
+#define LCR_BITS_MASK 0x03 /* Mask for bits/char field */
+
+#define LCR_STOP_1 0x00 /* 1 stop bit */
+#define LCR_STOP_1_5 0x04 /* 1.5 stop bits (if 5 bits/char) */
+#define LCR_STOP_2 0x04 /* 2 stop bits (if 6-8 bits/char) */
+#define LCR_STOP_MASK 0x04 /* Mask for stop bits field */
+
+#define LCR_PAR_NONE 0x00 /* No parity */
+#define LCR_PAR_ODD 0x08 /* Odd parity */
+#define LCR_PAR_EVEN 0x18 /* Even parity */
+#define LCR_PAR_MARK 0x28 /* Force parity bit to 1 */
+#define LCR_PAR_SPACE 0x38 /* Force parity bit to 0 */
+#define LCR_PAR_MASK 0x38 /* Mask for parity field */
+
+#define LCR_SET_BREAK 0x40 /* Set Break condition */
+#define LCR_DL_ENABLE 0x80 /* Enable access to divisor latch */
+
+#define MCR_DTR 0x01 /* Assert DTR */
+#define MCR_RTS 0x02 /* Assert RTS */
+#define MCR_OUT1 0x04 /* Loopback only: Sets state of RI */
+#define MCR_MASTER_IE 0x08 /* Enable interrupt outputs */
+#define MCR_LOOPBACK 0x10 /* Set internal (digital) loopback mode */
+#define MCR_XON_ANY 0x20 /* Enable any char to exit XOFF mode */
+
+#define ATEN2011_MSR_CTS 0x10 /* Current state of CTS */
+#define ATEN2011_MSR_DSR 0x20 /* Current state of DSR */
+#define ATEN2011_MSR_RI 0x40 /* Current state of RI */
+#define ATEN2011_MSR_CD 0x80 /* Current state of CD */
+
+
+static int debug;
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "2.0"
+#define DRIVER_DESC "ATENINTL 2011 USB Serial Adapter"
+
+/*
+ * Defines used for sending commands to port
+ */
+
+#define ATEN_WDR_TIMEOUT (50) /* default urb timeout */
+
+/* Requests */
+#define ATEN_RD_RTYPE 0xC0
+#define ATEN_WR_RTYPE 0x40
+#define ATEN_RDREQ 0x0D
+#define ATEN_WRREQ 0x0E
+#define ATEN_CTRL_TIMEOUT 500
+#define VENDOR_READ_LENGTH (0x01)
+
+/* set to 1 for RS485 mode and 0 for RS232 mode */
+/* FIXME make this somehow dynamic and not build time specific */
+static int RS485mode;
+
+static int set_reg_sync(struct usb_serial_port *port, __u16 reg, __u16 val)
+{
+ struct usb_device *dev = port->serial->dev;
+ val = val & 0x00ff;
+
+ dbg("%s: is %x, value %x", __func__, reg, val);
+
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ATEN_WRREQ,
+ ATEN_WR_RTYPE, val, reg, NULL, 0,
+ ATEN_WDR_TIMEOUT);
+}
+
+static int get_reg_sync(struct usb_serial_port *port, __u16 reg, __u16 *val)
+{
+ struct usb_device *dev = port->serial->dev;
+ int ret;
+
+ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ATEN_RDREQ,
+ ATEN_RD_RTYPE, 0, reg, val, VENDOR_READ_LENGTH,
+ ATEN_WDR_TIMEOUT);
+ dbg("%s: offset is %x, return val %x", __func__, reg, *val);
+ *val = (*val) & 0x00ff;
+ return ret;
+}
+
+static int set_uart_reg(struct usb_serial_port *port, __u16 reg, __u16 val)
+{
+ struct usb_device *dev = port->serial->dev;
+ struct ATENINTL_serial *a_serial;
+ __u16 minor;
+
+ a_serial = usb_get_serial_data(port->serial);
+ minor = port->serial->minor;
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+ val = val & 0x00ff;
+
+ /*
+ * For the UART control registers,
+ * the application number need to be Or'ed
+ */
+ if (a_serial->ATEN2011_spectrum_2or4ports == 4)
+ val |= (((__u16)port->number - minor) + 1) << 8;
+ else {
+ if (((__u16) port->number - minor) == 0)
+ val |= (((__u16)port->number - minor) + 1) << 8;
+ else
+ val |= (((__u16)port->number - minor) + 2) << 8;
+ }
+ dbg("%s: application number is %x", __func__, val);
+
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ATEN_WRREQ,
+ ATEN_WR_RTYPE, val, reg, NULL, 0,
+ ATEN_WDR_TIMEOUT);
+}
+
+static int get_uart_reg(struct usb_serial_port *port, __u16 reg, __u16 *val)
+{
+ struct usb_device *dev = port->serial->dev;
+ int ret = 0;
+ __u16 wval;
+ struct ATENINTL_serial *a_serial;
+ __u16 minor = port->serial->minor;
+
+ a_serial = usb_get_serial_data(port->serial);
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+
+ /* wval is same as application number */
+ if (a_serial->ATEN2011_spectrum_2or4ports == 4)
+ wval = (((__u16)port->number - minor) + 1) << 8;
+ else {
+ if (((__u16) port->number - minor) == 0)
+ wval = (((__u16) port->number - minor) + 1) << 8;
+ else
+ wval = (((__u16) port->number - minor) + 2) << 8;
+ }
+ dbg("%s: application number is %x", __func__, wval);
+ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ATEN_RDREQ,
+ ATEN_RD_RTYPE, wval, reg, val, VENDOR_READ_LENGTH,
+ ATEN_WDR_TIMEOUT);
+ *val = (*val) & 0x00ff;
+ return ret;
+}
+
+static int handle_newMsr(struct ATENINTL_port *port, __u8 newMsr)
+{
+ struct ATENINTL_port *ATEN2011_port;
+ struct async_icount *icount;
+ ATEN2011_port = port;
+ icount = &ATEN2011_port->icount;
+ if (newMsr &
+ (ATEN_MSR_DELTA_CTS | ATEN_MSR_DELTA_DSR | ATEN_MSR_DELTA_RI |
+ ATEN_MSR_DELTA_CD)) {
+ icount = &ATEN2011_port->icount;
+
+ /* update input line counters */
+ if (newMsr & ATEN_MSR_DELTA_CTS)
+ icount->cts++;
+ if (newMsr & ATEN_MSR_DELTA_DSR)
+ icount->dsr++;
+ if (newMsr & ATEN_MSR_DELTA_CD)
+ icount->dcd++;
+ if (newMsr & ATEN_MSR_DELTA_RI)
+ icount->rng++;
+ }
+
+ return 0;
+}
+
+static int handle_newLsr(struct ATENINTL_port *port, __u8 newLsr)
+{
+ struct async_icount *icount;
+
+ dbg("%s - %02x", __func__, newLsr);
+
+ if (newLsr & SERIAL_LSR_BI) {
+ /*
+ * Parity and Framing errors only count if they occur exclusive
+ * of a break being received.
+ */
+ newLsr &= (__u8) (SERIAL_LSR_OE | SERIAL_LSR_BI);
+ }
+
+ /* update input line counters */
+ icount = &port->icount;
+ if (newLsr & SERIAL_LSR_BI)
+ icount->brk++;
+ if (newLsr & SERIAL_LSR_OE)
+ icount->overrun++;
+ if (newLsr & SERIAL_LSR_PE)
+ icount->parity++;
+ if (newLsr & SERIAL_LSR_FE)
+ icount->frame++;
+
+ return 0;
+}
+
+static void ATEN2011_control_callback(struct urb *urb)
+{
+ unsigned char *data;
+ struct ATENINTL_port *ATEN2011_port;
+ __u8 regval = 0x0;
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d", __func__,
+ urb->status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d", __func__,
+ urb->status);
+ goto exit;
+ }
+
+ ATEN2011_port = (struct ATENINTL_port *)urb->context;
+
+ dbg("%s urb buffer size is %d", __func__, urb->actual_length);
+ dbg("%s ATEN2011_port->MsrLsr is %d port %d", __func__,
+ ATEN2011_port->MsrLsr, ATEN2011_port->port_num);
+ data = urb->transfer_buffer;
+ regval = (__u8) data[0];
+ dbg("%s data is %x", __func__, regval);
+ if (ATEN2011_port->MsrLsr == 0)
+ handle_newMsr(ATEN2011_port, regval);
+ else if (ATEN2011_port->MsrLsr == 1)
+ handle_newLsr(ATEN2011_port, regval);
+
+exit:
+ return;
+}
+
+static int ATEN2011_get_reg(struct ATENINTL_port *ATEN, __u16 Wval, __u16 reg,
+ __u16 *val)
+{
+ struct usb_device *dev = ATEN->port->serial->dev;
+ struct usb_ctrlrequest *dr = NULL;
+ unsigned char *buffer = NULL;
+ int ret = 0;
+ buffer = (__u8 *) ATEN->ctrl_buf;
+
+ dr = (void *)(buffer + 2);
+ dr->bRequestType = ATEN_RD_RTYPE;
+ dr->bRequest = ATEN_RDREQ;
+ dr->wValue = cpu_to_le16(Wval);
+ dr->wIndex = cpu_to_le16(reg);
+ dr->wLength = cpu_to_le16(2);
+
+ usb_fill_control_urb(ATEN->control_urb, dev, usb_rcvctrlpipe(dev, 0),
+ (unsigned char *)dr, buffer, 2,
+ ATEN2011_control_callback, ATEN);
+ ATEN->control_urb->transfer_buffer_length = 2;
+ ret = usb_submit_urb(ATEN->control_urb, GFP_ATOMIC);
+ return ret;
+}
+
+static void ATEN2011_interrupt_callback(struct urb *urb)
+{
+ int result;
+ int length;
+ struct ATENINTL_port *ATEN2011_port;
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct usb_serial *serial;
+ __u16 Data;
+ unsigned char *data;
+ __u8 sp[5], st;
+ int i;
+ __u16 wval;
+ int minor;
+
+ dbg("%s", " : Entering");
+
+ ATEN2011_serial = (struct ATENINTL_serial *)urb->context;
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d", __func__,
+ urb->status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d", __func__,
+ urb->status);
+ goto exit;
+ }
+ length = urb->actual_length;
+ data = urb->transfer_buffer;
+
+ serial = ATEN2011_serial->serial;
+
+ /* ATENINTL get 5 bytes
+ * Byte 1 IIR Port 1 (port.number is 0)
+ * Byte 2 IIR Port 2 (port.number is 1)
+ * Byte 3 IIR Port 3 (port.number is 2)
+ * Byte 4 IIR Port 4 (port.number is 3)
+ * Byte 5 FIFO status for both */
+
+ if (length && length > 5) {
+ dbg("%s", "Wrong data !!!");
+ return;
+ }
+
+ /* MATRIX */
+ if (ATEN2011_serial->ATEN2011_spectrum_2or4ports == 4) {
+ sp[0] = (__u8) data[0];
+ sp[1] = (__u8) data[1];
+ sp[2] = (__u8) data[2];
+ sp[3] = (__u8) data[3];
+ st = (__u8) data[4];
+ } else {
+ sp[0] = (__u8) data[0];
+ sp[1] = (__u8) data[2];
+ /* sp[2]=(__u8)data[2]; */
+ /* sp[3]=(__u8)data[3]; */
+ st = (__u8) data[4];
+
+ }
+ for (i = 0; i < serial->num_ports; i++) {
+ ATEN2011_port = usb_get_serial_port_data(serial->port[i]);
+ minor = serial->minor;
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+ if ((ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2)
+ && (i != 0))
+ wval =
+ (((__u16) serial->port[i]->number -
+ (__u16) (minor)) + 2) << 8;
+ else
+ wval =
+ (((__u16) serial->port[i]->number -
+ (__u16) (minor)) + 1) << 8;
+ if (ATEN2011_port->open != 0) {
+ if (sp[i] & 0x01) {
+ dbg("SP%d No Interrupt !!!", i);
+ } else {
+ switch (sp[i] & 0x0f) {
+ case SERIAL_IIR_RLS:
+ dbg("Serial Port %d: Receiver status error or address bit detected in 9-bit mode", i);
+ ATEN2011_port->MsrLsr = 1;
+ ATEN2011_get_reg(ATEN2011_port, wval,
+ LINE_STATUS_REGISTER,
+ &Data);
+ break;
+ case SERIAL_IIR_MS:
+ dbg("Serial Port %d: Modem status change", i);
+ ATEN2011_port->MsrLsr = 0;
+ ATEN2011_get_reg(ATEN2011_port, wval,
+ MODEM_STATUS_REGISTER,
+ &Data);
+ break;
+ }
+ }
+ }
+
+ }
+exit:
+ if (ATEN2011_serial->status_polling_started == 0)
+ return;
+
+ result = usb_submit_urb(urb, GFP_ATOMIC);
+ if (result) {
+ dev_err(&urb->dev->dev,
+ "%s - Error %d submitting interrupt urb\n",
+ __func__, result);
+ }
+
+ return;
+}
+
+static void ATEN2011_bulk_in_callback(struct urb *urb)
+{
+ int status;
+ unsigned char *data;
+ struct usb_serial *serial;
+ struct usb_serial_port *port;
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct ATENINTL_port *ATEN2011_port;
+ struct tty_struct *tty;
+
+ if (urb->status) {
+ dbg("nonzero read bulk status received: %d", urb->status);
+ return;
+ }
+
+ ATEN2011_port = (struct ATENINTL_port *)urb->context;
+
+ port = (struct usb_serial_port *)ATEN2011_port->port;
+ serial = port->serial;
+
+ dbg("%s", "Entering...");
+
+ data = urb->transfer_buffer;
+ ATEN2011_serial = usb_get_serial_data(serial);
+
+ if (urb->actual_length) {
+ tty = tty_port_tty_get(&ATEN2011_port->port->port);
+ if (tty) {
+ tty_buffer_request_room(tty, urb->actual_length);
+ tty_insert_flip_string(tty, data, urb->actual_length);
+ tty_flip_buffer_push(tty);
+ tty_kref_put(tty);
+ }
+
+ ATEN2011_port->icount.rx += urb->actual_length;
+ dbg("ATEN2011_port->icount.rx is %d:",
+ ATEN2011_port->icount.rx);
+ }
+
+ if (!ATEN2011_port->read_urb) {
+ dbg("%s", "URB KILLED !!!");
+ return;
+ }
+
+ if (ATEN2011_port->read_urb->status != -EINPROGRESS) {
+ ATEN2011_port->read_urb->dev = serial->dev;
+
+ status = usb_submit_urb(ATEN2011_port->read_urb, GFP_ATOMIC);
+ if (status)
+ dbg("usb_submit_urb(read bulk) failed, status = %d", status);
+ }
+}
+
+static void ATEN2011_bulk_out_data_callback(struct urb *urb)
+{
+ struct ATENINTL_port *ATEN2011_port;
+ struct tty_struct *tty;
+
+ if (urb->status) {
+ dbg("nonzero write bulk status received:%d", urb->status);
+ return;
+ }
+
+ ATEN2011_port = (struct ATENINTL_port *)urb->context;
+
+ dbg("%s", "Entering .........");
+
+ tty = tty_port_tty_get(&ATEN2011_port->port->port);
+
+ if (tty && ATEN2011_port->open) {
+ /* tell the tty driver that something has changed */
+ wake_up_interruptible(&tty->write_wait);
+ }
+
+ /* schedule_work(&ATEN2011_port->port->work); */
+ tty_kref_put(tty);
+
+}
+
+#ifdef ATENSerialProbe
+static int ATEN2011_serial_probe(struct usb_serial *serial,
+ const struct usb_device_id *id)
+{
+
+ /*need to implement the mode_reg reading and updating\
+ structures usb_serial_ device_type\
+ (i.e num_ports, num_bulkin,bulkout etc) */
+ /* Also we can update the changes attach */
+ return 1;
+}
+#endif
+
+static int ATEN2011_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
+{
+ int response;
+ int j;
+ struct usb_serial *serial;
+ struct urb *urb;
+ __u16 Data;
+ int status;
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct ATENINTL_port *ATEN2011_port;
+ struct ktermios tmp_termios;
+ int minor;
+
+ serial = port->serial;
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ if (ATEN2011_port == NULL)
+ return -ENODEV;
+
+ ATEN2011_serial = usb_get_serial_data(serial);
+ if (ATEN2011_serial == NULL)
+ return -ENODEV;
+
+ /* increment the number of opened ports counter here */
+ ATEN2011_serial->NoOfOpenPorts++;
+
+ usb_clear_halt(serial->dev, port->write_urb->pipe);
+ usb_clear_halt(serial->dev, port->read_urb->pipe);
+
+ /* Initialising the write urb pool */
+ for (j = 0; j < NUM_URBS; ++j) {
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ ATEN2011_port->write_urb_pool[j] = urb;
+
+ if (urb == NULL) {
+ err("No more urbs???");
+ continue;
+ }
+
+ urb->transfer_buffer = NULL;
+ urb->transfer_buffer =
+ kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+ if (!urb->transfer_buffer) {
+ err("%s-out of memory for urb buffers.", __func__);
+ continue;
+ }
+ }
+
+/*****************************************************************************
+ * Initialize ATEN2011 -- Write Init values to corresponding Registers
+ *
+ * Register Index
+ * 1 : IER
+ * 2 : FCR
+ * 3 : LCR
+ * 4 : MCR
+ *
+ * 0x08 : SP1/2 Control Reg
+ *****************************************************************************/
+
+/* NEED to check the fallowing Block */
+
+ Data = 0x0;
+ status = get_reg_sync(port, ATEN2011_port->SpRegOffset, &Data);
+ if (status < 0) {
+ dbg("Reading Spreg failed");
+ return -1;
+ }
+ Data |= 0x80;
+ status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+ if (status < 0) {
+ dbg("writing Spreg failed");
+ return -1;
+ }
+
+ Data &= ~0x80;
+ status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+ if (status < 0) {
+ dbg("writing Spreg failed");
+ return -1;
+ }
+
+/* End of block to be checked */
+/**************************CHECK***************************/
+
+ if (RS485mode == 0)
+ Data = 0xC0;
+ else
+ Data = 0x00;
+ status = set_uart_reg(port, SCRATCH_PAD_REGISTER, Data);
+ if (status < 0) {
+ dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x", status);
+ return -1;
+ } else
+ dbg("SCRATCH_PAD_REGISTER Writing success status%d", status);
+
+/**************************CHECK***************************/
+
+ Data = 0x0;
+ status = get_reg_sync(port, ATEN2011_port->ControlRegOffset, &Data);
+ if (status < 0) {
+ dbg("Reading Controlreg failed");
+ return -1;
+ }
+ Data |= 0x08; /* Driver done bit */
+ Data |= 0x20; /* rx_disable */
+ status = 0;
+ status =
+ set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data);
+ if (status < 0) {
+ dbg("writing Controlreg failed");
+ return -1;
+ }
+ /*
+ * do register settings here
+ * Set all regs to the device default values.
+ * First Disable all interrupts.
+ */
+
+ Data = 0x00;
+ status = set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+ if (status < 0) {
+ dbg("disableing interrupts failed");
+ return -1;
+ }
+ /* Set FIFO_CONTROL_REGISTER to the default value */
+ Data = 0x00;
+ status = set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
+ if (status < 0) {
+ dbg("Writing FIFO_CONTROL_REGISTER failed");
+ return -1;
+ }
+
+ Data = 0xcf; /* chk */
+ status = set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
+ if (status < 0) {
+ dbg("Writing FIFO_CONTROL_REGISTER failed");
+ return -1;
+ }
+
+ Data = 0x03; /* LCR_BITS_8 */
+ status = set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+ ATEN2011_port->shadowLCR = Data;
+
+ Data = 0x0b; /* MCR_DTR|MCR_RTS|MCR_MASTER_IE */
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ ATEN2011_port->shadowMCR = Data;
+
+#ifdef Check
+ Data = 0x00;
+ status = get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
+ ATEN2011_port->shadowLCR = Data;
+
+ Data |= SERIAL_LCR_DLAB; /* data latch enable in LCR 0x80 */
+ status = set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+
+ Data = 0x0c;
+ status = set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
+
+ Data = 0x0;
+ status = set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
+
+ Data = 0x00;
+ status = get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
+
+/* Data = ATEN2011_port->shadowLCR; */ /* data latch disable */
+ Data = Data & ~SERIAL_LCR_DLAB;
+ status = set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+ ATEN2011_port->shadowLCR = Data;
+#endif
+ /* clearing Bulkin and Bulkout Fifo */
+ Data = 0x0;
+ status = get_reg_sync(port, ATEN2011_port->SpRegOffset, &Data);
+
+ Data = Data | 0x0c;
+ status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+
+ Data = Data & ~0x0c;
+ status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+ /* Finally enable all interrupts */
+ Data = 0x0;
+ Data = 0x0c;
+ status = set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+
+ /* clearing rx_disable */
+ Data = 0x0;
+ status = get_reg_sync(port, ATEN2011_port->ControlRegOffset, &Data);
+ Data = Data & ~0x20;
+ status = set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data);
+
+ /* rx_negate */
+ Data = 0x0;
+ status = get_reg_sync(port, ATEN2011_port->ControlRegOffset, &Data);
+ Data = Data | 0x10;
+ status = 0;
+ status = set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data);
+
+ /* force low_latency on so that our tty_push actually forces *
+ * the data through,otherwise it is scheduled, and with *
+ * high data rates (like with OHCI) data can get lost. */
+
+ if (tty)
+ tty->low_latency = 1;
+ /*
+ * Check to see if we've set up our endpoint info yet
+ * (can't set it up in ATEN2011_startup as the structures
+ * were not set up at that time.)
+ */
+ if (ATEN2011_serial->NoOfOpenPorts == 1) {
+ /* start the status polling here */
+ ATEN2011_serial->status_polling_started = 1;
+ /* If not yet set, Set here */
+ ATEN2011_serial->interrupt_in_buffer =
+ serial->port[0]->interrupt_in_buffer;
+ ATEN2011_serial->interrupt_in_endpoint =
+ serial->port[0]->interrupt_in_endpointAddress;
+ ATEN2011_serial->interrupt_read_urb =
+ serial->port[0]->interrupt_in_urb;
+
+ /* set up interrupt urb */
+ usb_fill_int_urb(ATEN2011_serial->interrupt_read_urb,
+ serial->dev,
+ usb_rcvintpipe(serial->dev,
+ ATEN2011_serial->
+ interrupt_in_endpoint),
+ ATEN2011_serial->interrupt_in_buffer,
+ ATEN2011_serial->interrupt_read_urb->
+ transfer_buffer_length,
+ ATEN2011_interrupt_callback, ATEN2011_serial,
+ ATEN2011_serial->interrupt_read_urb->interval);
+
+ /* start interrupt read for ATEN2011 *
+ * will continue as long as ATEN2011 is connected */
+
+ response =
+ usb_submit_urb(ATEN2011_serial->interrupt_read_urb,
+ GFP_KERNEL);
+ if (response) {
+ dbg("%s - Error %d submitting interrupt urb",
+ __func__, response);
+ }
+
+ }
+
+ /*
+ * See if we've set up our endpoint info yet
+ * (can't set it up in ATEN2011_startup as the
+ * structures were not set up at that time.)
+ */
+
+ dbg("port number is %d", port->number);
+ dbg("serial number is %d", port->serial->minor);
+ dbg("Bulkin endpoint is %d", port->bulk_in_endpointAddress);
+ dbg("BulkOut endpoint is %d", port->bulk_out_endpointAddress);
+ dbg("Interrupt endpoint is %d",
+ port->interrupt_in_endpointAddress);
+ dbg("port's number in the device is %d", ATEN2011_port->port_num);
+ ATEN2011_port->bulk_in_buffer = port->bulk_in_buffer;
+ ATEN2011_port->bulk_in_endpoint = port->bulk_in_endpointAddress;
+ ATEN2011_port->read_urb = port->read_urb;
+ ATEN2011_port->bulk_out_endpoint = port->bulk_out_endpointAddress;
+
+ minor = port->serial->minor;
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+
+ /* set up our bulk in urb */
+ if ((ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2)
+ && (((__u16) port->number - (__u16) (minor)) != 0)) {
+ usb_fill_bulk_urb(ATEN2011_port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ (port->
+ bulk_in_endpointAddress +
+ 2)), port->bulk_in_buffer,
+ ATEN2011_port->read_urb->
+ transfer_buffer_length,
+ ATEN2011_bulk_in_callback, ATEN2011_port);
+ } else
+ usb_fill_bulk_urb(ATEN2011_port->read_urb,
+ serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->
+ bulk_in_endpointAddress),
+ port->bulk_in_buffer,
+ ATEN2011_port->read_urb->
+ transfer_buffer_length,
+ ATEN2011_bulk_in_callback, ATEN2011_port);
+
+ dbg("ATEN2011_open: bulkin endpoint is %d",
+ port->bulk_in_endpointAddress);
+ response = usb_submit_urb(ATEN2011_port->read_urb, GFP_KERNEL);
+ if (response) {
+ err("%s - Error %d submitting control urb", __func__,
+ response);
+ }
+
+ /* initialize our wait queues */
+ init_waitqueue_head(&ATEN2011_port->wait_chase);
+ init_waitqueue_head(&ATEN2011_port->wait_command);
+
+ /* initialize our icount structure */
+ memset(&(ATEN2011_port->icount), 0x00, sizeof(ATEN2011_port->icount));
+
+ /* initialize our port settings */
+ ATEN2011_port->shadowMCR = MCR_MASTER_IE; /* Must set to enable ints! */
+ ATEN2011_port->chaseResponsePending = 0;
+ /* send a open port command */
+ ATEN2011_port->open = 1;
+ /* ATEN2011_change_port_settings(ATEN2011_port,old_termios); */
+ /* Setup termios */
+ ATEN2011_set_termios(tty, port, &tmp_termios);
+ ATEN2011_port->icount.tx = 0;
+ ATEN2011_port->icount.rx = 0;
+
+ dbg("usb_serial serial:%x ATEN2011_port:%x\nATEN2011_serial:%x usb_serial_port port:%x",
+ (unsigned int)serial, (unsigned int)ATEN2011_port,
+ (unsigned int)ATEN2011_serial, (unsigned int)port);
+
+ return 0;
+
+}
+
+static int ATEN2011_chars_in_buffer(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ int i;
+ int chars = 0;
+ struct ATENINTL_port *ATEN2011_port;
+
+ /* dbg("%s"," ATEN2011_chars_in_buffer:entering ..........."); */
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+ if (ATEN2011_port == NULL) {
+ dbg("%s", "ATEN2011_break:leaving ...........");
+ return -1;
+ }
+
+ for (i = 0; i < NUM_URBS; ++i)
+ if (ATEN2011_port->write_urb_pool[i]->status == -EINPROGRESS)
+ chars += URB_TRANSFER_BUFFER_SIZE;
+
+ dbg("%s - returns %d", __func__, chars);
+ return chars;
+
+}
+
+static void ATEN2011_block_until_tx_empty(struct tty_struct *tty,
+ struct ATENINTL_port *ATEN2011_port)
+{
+ int timeout = HZ / 10;
+ int wait = 30;
+ int count;
+
+ while (1) {
+ count = ATEN2011_chars_in_buffer(tty);
+
+ /* Check for Buffer status */
+ if (count <= 0)
+ return;
+
+ /* Block the thread for a while */
+ interruptible_sleep_on_timeout(&ATEN2011_port->wait_chase,
+ timeout);
+
+ /* No activity.. count down section */
+ wait--;
+ if (wait == 0) {
+ dbg("%s - TIMEOUT", __func__);
+ return;
+ } else {
+ /* Reset timout value back to seconds */
+ wait = 30;
+ }
+ }
+}
+
+static void ATEN2011_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
+{
+ struct usb_serial *serial;
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct ATENINTL_port *ATEN2011_port;
+ int no_urbs;
+ __u16 Data;
+
+ dbg("%s", "ATEN2011_close:entering...");
+ serial = port->serial;
+
+ /* take the Adpater and port's private data */
+ ATEN2011_serial = usb_get_serial_data(serial);
+ ATEN2011_port = usb_get_serial_port_data(port);
+ if ((ATEN2011_serial == NULL) || (ATEN2011_port == NULL))
+ return;
+
+ if (serial->dev) {
+ /* flush and block(wait) until tx is empty */
+ ATEN2011_block_until_tx_empty(tty, ATEN2011_port);
+ }
+ /* kill the ports URB's */
+ for (no_urbs = 0; no_urbs < NUM_URBS; no_urbs++)
+ usb_kill_urb(ATEN2011_port->write_urb_pool[no_urbs]);
+ /* Freeing Write URBs */
+ for (no_urbs = 0; no_urbs < NUM_URBS; ++no_urbs) {
+ kfree(ATEN2011_port->write_urb_pool[no_urbs]->transfer_buffer);
+ usb_free_urb(ATEN2011_port->write_urb_pool[no_urbs]);
+ }
+ /* While closing port, shutdown all bulk read, write *
+ * and interrupt read if they exists */
+ if (serial->dev) {
+ if (ATEN2011_port->write_urb) {
+ dbg("%s", "Shutdown bulk write");
+ usb_kill_urb(ATEN2011_port->write_urb);
+ }
+ if (ATEN2011_port->read_urb) {
+ dbg("%s", "Shutdown bulk read");
+ usb_kill_urb(ATEN2011_port->read_urb);
+ }
+ if ((&ATEN2011_port->control_urb)) {
+ dbg("%s", "Shutdown control read");
+ /* usb_kill_urb (ATEN2011_port->control_urb); */
+
+ }
+ }
+ /* if(ATEN2011_port->ctrl_buf != NULL) */
+ /* kfree(ATEN2011_port->ctrl_buf); */
+ /* decrement the no.of open ports counter of an individual USB-serial adapter. */
+ ATEN2011_serial->NoOfOpenPorts--;
+ dbg("NoOfOpenPorts in close%d:in port%d",
+ ATEN2011_serial->NoOfOpenPorts, port->number);
+ if (ATEN2011_serial->NoOfOpenPorts == 0) {
+ /* stop the stus polling here */
+ ATEN2011_serial->status_polling_started = 0;
+ if (ATEN2011_serial->interrupt_read_urb) {
+ dbg("%s", "Shutdown interrupt_read_urb");
+ /* ATEN2011_serial->interrupt_in_buffer=NULL; */
+ /* usb_kill_urb (ATEN2011_serial->interrupt_read_urb); */
+ }
+ }
+ if (ATEN2011_port->write_urb) {
+ /* if this urb had a transfer buffer already (old tx) free it */
+ kfree(ATEN2011_port->write_urb->transfer_buffer);
+ usb_free_urb(ATEN2011_port->write_urb);
+ }
+
+ /* clear the MCR & IER */
+ Data = 0x00;
+ set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ Data = 0x00;
+ set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+
+ ATEN2011_port->open = 0;
+ dbg("%s", "Leaving ............");
+
+}
+
+static void ATEN2011_block_until_chase_response(struct tty_struct *tty,
+ struct ATENINTL_port
+ *ATEN2011_port)
+{
+ int timeout = 1 * HZ;
+ int wait = 10;
+ int count;
+
+ while (1) {
+ count = ATEN2011_chars_in_buffer(tty);
+
+ /* Check for Buffer status */
+ if (count <= 0) {
+ ATEN2011_port->chaseResponsePending = 0;
+ return;
+ }
+
+ /* Block the thread for a while */
+ interruptible_sleep_on_timeout(&ATEN2011_port->wait_chase,
+ timeout);
+ /* No activity.. count down section */
+ wait--;
+ if (wait == 0) {
+ dbg("%s - TIMEOUT", __func__);
+ return;
+ } else {
+ /* Reset timout value back to seconds */
+ wait = 10;
+ }
+ }
+
+}
+
+static void ATEN2011_break(struct tty_struct *tty, int break_state)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ unsigned char data;
+ struct usb_serial *serial;
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct ATENINTL_port *ATEN2011_port;
+
+ dbg("%s", "Entering ...........");
+ dbg("ATEN2011_break: Start");
+
+ serial = port->serial;
+
+ ATEN2011_serial = usb_get_serial_data(serial);
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ if ((ATEN2011_serial == NULL) || (ATEN2011_port == NULL))
+ return;
+
+ /* flush and chase */
+ ATEN2011_port->chaseResponsePending = 1;
+
+ if (serial->dev) {
+ /* flush and block until tx is empty */
+ ATEN2011_block_until_chase_response(tty, ATEN2011_port);
+ }
+
+ if (break_state == -1)
+ data = ATEN2011_port->shadowLCR | LCR_SET_BREAK;
+ else
+ data = ATEN2011_port->shadowLCR & ~LCR_SET_BREAK;
+
+ ATEN2011_port->shadowLCR = data;
+ dbg("ATEN2011_break ATEN2011_port->shadowLCR is %x",
+ ATEN2011_port->shadowLCR);
+ set_uart_reg(port, LINE_CONTROL_REGISTER, ATEN2011_port->shadowLCR);
+
+ return;
+}
+
+static int ATEN2011_write_room(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ int i;
+ int room = 0;
+ struct ATENINTL_port *ATEN2011_port;
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+ if (ATEN2011_port == NULL) {
+ dbg("%s", "ATEN2011_break:leaving ...........");
+ return -1;
+ }
+
+ for (i = 0; i < NUM_URBS; ++i)
+ if (ATEN2011_port->write_urb_pool[i]->status != -EINPROGRESS)
+ room += URB_TRANSFER_BUFFER_SIZE;
+
+ dbg("%s - returns %d", __func__, room);
+ return room;
+
+}
+
+static int ATEN2011_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *data, int count)
+{
+ int status;
+ int i;
+ int bytes_sent = 0;
+ int transfer_size;
+ int minor;
+
+ struct ATENINTL_port *ATEN2011_port;
+ struct usb_serial *serial;
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct urb *urb;
+ const unsigned char *current_position = data;
+ unsigned char *data1;
+ dbg("%s", "entering ...........");
+
+ serial = port->serial;
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+ if (ATEN2011_port == NULL) {
+ dbg("%s", "ATEN2011_port is NULL");
+ return -1;
+ }
+
+ ATEN2011_serial = usb_get_serial_data(serial);
+ if (ATEN2011_serial == NULL) {
+ dbg("%s", "ATEN2011_serial is NULL");
+ return -1;
+ }
+
+ /* try to find a free urb in the list */
+ urb = NULL;
+
+ for (i = 0; i < NUM_URBS; ++i) {
+ if (ATEN2011_port->write_urb_pool[i]->status != -EINPROGRESS) {
+ urb = ATEN2011_port->write_urb_pool[i];
+ dbg("URB:%d", i);
+ break;
+ }
+ }
+
+ if (urb == NULL) {
+ dbg("%s - no more free urbs", __func__);
+ goto exit;
+ }
+
+ if (urb->transfer_buffer == NULL) {
+ urb->transfer_buffer =
+ kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+
+ if (urb->transfer_buffer == NULL) {
+ err("%s no more kernel memory...", __func__);
+ goto exit;
+ }
+ }
+ transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
+
+ memcpy(urb->transfer_buffer, current_position, transfer_size);
+ /* usb_serial_debug_data (__FILE__, __func__, transfer_size, urb->transfer_buffer); */
+
+ /* fill urb with data and submit */
+ minor = port->serial->minor;
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+ if ((ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2)
+ && (((__u16) port->number - (__u16) (minor)) != 0)) {
+ usb_fill_bulk_urb(urb, ATEN2011_serial->serial->dev,
+ usb_sndbulkpipe(ATEN2011_serial->serial->dev,
+ (port->
+ bulk_out_endpointAddress) +
+ 2), urb->transfer_buffer,
+ transfer_size,
+ ATEN2011_bulk_out_data_callback,
+ ATEN2011_port);
+ } else
+
+ usb_fill_bulk_urb(urb,
+ ATEN2011_serial->serial->dev,
+ usb_sndbulkpipe(ATEN2011_serial->serial->dev,
+ port->
+ bulk_out_endpointAddress),
+ urb->transfer_buffer, transfer_size,
+ ATEN2011_bulk_out_data_callback,
+ ATEN2011_port);
+
+ data1 = urb->transfer_buffer;
+ dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress);
+ /* for(i=0;i < urb->actual_length;i++) */
+ /* dbg("Data is %c ",data1[i]); */
+
+ /* 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);
+ bytes_sent = status;
+ goto exit;
+ }
+ bytes_sent = transfer_size;
+ ATEN2011_port->icount.tx += transfer_size;
+ dbg("ATEN2011_port->icount.tx is %d:", ATEN2011_port->icount.tx);
+
+exit:
+ return bytes_sent;
+}
+
+static void ATEN2011_throttle(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct ATENINTL_port *ATEN2011_port;
+ int status;
+
+ dbg("- port %d", port->number);
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ if (ATEN2011_port == NULL)
+ return;
+
+ if (!ATEN2011_port->open) {
+ dbg("%s", "port not opened");
+ return;
+ }
+
+ dbg("%s", "Entering .......... ");
+
+ if (!tty) {
+ dbg("%s - no tty available", __func__);
+ return;
+ }
+
+ /* if we are implementing XON/XOFF, send the stop character */
+ if (I_IXOFF(tty)) {
+ unsigned char stop_char = STOP_CHAR(tty);
+ status = ATEN2011_write(tty, port, &stop_char, 1);
+ if (status <= 0)
+ return;
+ }
+
+ /* if we are implementing RTS/CTS, toggle that line */
+ if (tty->termios->c_cflag & CRTSCTS) {
+ ATEN2011_port->shadowMCR &= ~MCR_RTS;
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER,
+ ATEN2011_port->shadowMCR);
+ if (status < 0)
+ return;
+ }
+
+ return;
+}
+
+static void ATEN2011_unthrottle(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ int status;
+ struct ATENINTL_port *ATEN2011_port = usb_get_serial_port_data(port);
+
+ if (ATEN2011_port == NULL)
+ return;
+
+ if (!ATEN2011_port->open) {
+ dbg("%s - port not opened", __func__);
+ return;
+ }
+
+ dbg("%s", "Entering .......... ");
+
+ if (!tty) {
+ dbg("%s - no tty available", __func__);
+ return;
+ }
+
+ /* if we are implementing XON/XOFF, send the start character */
+ if (I_IXOFF(tty)) {
+ unsigned char start_char = START_CHAR(tty);
+ status = ATEN2011_write(tty, port, &start_char, 1);
+ if (status <= 0)
+ return;
+ }
+
+ /* if we are implementing RTS/CTS, toggle that line */
+ if (tty->termios->c_cflag & CRTSCTS) {
+ ATEN2011_port->shadowMCR |= MCR_RTS;
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER,
+ ATEN2011_port->shadowMCR);
+ if (status < 0)
+ return;
+ }
+
+ return;
+}
+
+static int ATEN2011_tiocmget(struct tty_struct *tty, struct file *file)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct ATENINTL_port *ATEN2011_port;
+ unsigned int result;
+ __u16 msr;
+ __u16 mcr;
+ /* unsigned int mcr; */
+ int status = 0;
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ dbg("%s - port %d", __func__, port->number);
+
+ if (ATEN2011_port == NULL)
+ return -ENODEV;
+
+ status = get_uart_reg(port, MODEM_STATUS_REGISTER, &msr);
+ status = get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr);
+ /* mcr = ATEN2011_port->shadowMCR; */
+ /* COMMENT2: the Fallowing three line are commented for updating only MSR values */
+ result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
+ | ((mcr & MCR_RTS) ? TIOCM_RTS : 0)
+ | ((mcr & MCR_LOOPBACK) ? TIOCM_LOOP : 0)
+ | ((msr & ATEN2011_MSR_CTS) ? TIOCM_CTS : 0)
+ | ((msr & ATEN2011_MSR_CD) ? TIOCM_CAR : 0)
+ | ((msr & ATEN2011_MSR_RI) ? TIOCM_RI : 0)
+ | ((msr & ATEN2011_MSR_DSR) ? TIOCM_DSR : 0);
+
+ dbg("%s - 0x%04X", __func__, result);
+
+ return result;
+}
+
+static int ATEN2011_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct ATENINTL_port *ATEN2011_port;
+ unsigned int mcr;
+ unsigned int status;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ if (ATEN2011_port == NULL)
+ return -ENODEV;
+
+ mcr = ATEN2011_port->shadowMCR;
+ if (clear & TIOCM_RTS)
+ mcr &= ~MCR_RTS;
+ if (clear & TIOCM_DTR)
+ mcr &= ~MCR_DTR;
+ if (clear & TIOCM_LOOP)
+ mcr &= ~MCR_LOOPBACK;
+
+ if (set & TIOCM_RTS)
+ mcr |= MCR_RTS;
+ if (set & TIOCM_DTR)
+ mcr |= MCR_DTR;
+ if (set & TIOCM_LOOP)
+ mcr |= MCR_LOOPBACK;
+
+ ATEN2011_port->shadowMCR = mcr;
+
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr);
+ if (status < 0) {
+ dbg("setting MODEM_CONTROL_REGISTER Failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void ATEN2011_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port,
+ struct ktermios *old_termios)
+{
+ int status;
+ unsigned int cflag;
+ struct usb_serial *serial;
+ struct ATENINTL_port *ATEN2011_port;
+
+ dbg("ATEN2011_set_termios: START");
+
+ serial = port->serial;
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ if (ATEN2011_port == NULL)
+ return;
+
+ if (!ATEN2011_port->open) {
+ dbg("%s - port not opened", __func__);
+ return;
+ }
+
+ dbg("%s", "setting termios - ");
+
+ cflag = tty->termios->c_cflag;
+
+ if (!cflag) {
+ dbg("%s %s", __func__, "cflag is NULL");
+ return;
+ }
+
+ /* check that they really want us to change something */
+ if (old_termios) {
+ if ((cflag == old_termios->c_cflag) &&
+ (RELEVANT_IFLAG(tty->termios->c_iflag) ==
+ RELEVANT_IFLAG(old_termios->c_iflag))) {
+ dbg("%s", "Nothing to change");
+ return;
+ }
+ }
+
+ dbg("%s - clfag %08x iflag %08x", __func__,
+ tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
+
+ if (old_termios) {
+ dbg("%s - old clfag %08x old iflag %08x", __func__,
+ old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag));
+ }
+
+ dbg("%s - port %d", __func__, port->number);
+
+ /* change the port settings to the new ones specified */
+
+ ATEN2011_change_port_settings(tty, ATEN2011_port, old_termios);
+
+ if (!ATEN2011_port->read_urb) {
+ dbg("%s", "URB KILLED !!!!!");
+ return;
+ }
+
+ if (ATEN2011_port->read_urb->status != -EINPROGRESS) {
+ ATEN2011_port->read_urb->dev = serial->dev;
+ status = usb_submit_urb(ATEN2011_port->read_urb, GFP_ATOMIC);
+ if (status) {
+ dbg
+ (" usb_submit_urb(read bulk) failed, status = %d",
+ status);
+ }
+ }
+ return;
+}
+
+static int get_lsr_info(struct tty_struct *tty,
+ struct ATENINTL_port *ATEN2011_port,
+ unsigned int __user *value)
+{
+ int count;
+ unsigned int result = 0;
+
+ count = ATEN2011_chars_in_buffer(tty);
+ if (count == 0) {
+ dbg("%s -- Empty", __func__);
+ result = TIOCSER_TEMT;
+ }
+
+ if (copy_to_user(value, &result, sizeof(int)))
+ return -EFAULT;
+ return 0;
+}
+
+static int get_number_bytes_avail(struct tty_struct *tty,
+ struct ATENINTL_port *ATEN2011_port,
+ unsigned int __user *value)
+{
+ unsigned int result = 0;
+
+ if (!tty)
+ return -ENOIOCTLCMD;
+
+ result = tty->read_cnt;
+
+ dbg("%s(%d) = %d", __func__, ATEN2011_port->port->number, result);
+ if (copy_to_user(value, &result, sizeof(int)))
+ return -EFAULT;
+
+ return -ENOIOCTLCMD;
+}
+
+static int set_modem_info(struct ATENINTL_port *ATEN2011_port, unsigned int cmd,
+ unsigned int __user *value)
+{
+ unsigned int mcr;
+ unsigned int arg;
+ __u16 Data;
+ int status;
+ struct usb_serial_port *port;
+
+ if (ATEN2011_port == NULL)
+ return -1;
+
+ port = (struct usb_serial_port *)ATEN2011_port->port;
+
+ mcr = ATEN2011_port->shadowMCR;
+
+ if (copy_from_user(&arg, value, sizeof(int)))
+ return -EFAULT;
+
+ switch (cmd) {
+ case TIOCMBIS:
+ if (arg & TIOCM_RTS)
+ mcr |= MCR_RTS;
+ if (arg & TIOCM_DTR)
+ mcr |= MCR_RTS;
+ if (arg & TIOCM_LOOP)
+ mcr |= MCR_LOOPBACK;
+ break;
+
+ case TIOCMBIC:
+ if (arg & TIOCM_RTS)
+ mcr &= ~MCR_RTS;
+ if (arg & TIOCM_DTR)
+ mcr &= ~MCR_RTS;
+ if (arg & TIOCM_LOOP)
+ mcr &= ~MCR_LOOPBACK;
+ break;
+
+ case TIOCMSET:
+ /* turn off the RTS and DTR and LOOPBACK
+ * and then only turn on what was asked to */
+ mcr &= ~(MCR_RTS | MCR_DTR | MCR_LOOPBACK);
+ mcr |= ((arg & TIOCM_RTS) ? MCR_RTS : 0);
+ mcr |= ((arg & TIOCM_DTR) ? MCR_DTR : 0);
+ mcr |= ((arg & TIOCM_LOOP) ? MCR_LOOPBACK : 0);
+ break;
+ }
+
+ ATEN2011_port->shadowMCR = mcr;
+
+ Data = ATEN2011_port->shadowMCR;
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ if (status < 0) {
+ dbg("setting MODEM_CONTROL_REGISTER Failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int get_modem_info(struct ATENINTL_port *ATEN2011_port,
+ unsigned int __user *value)
+{
+ unsigned int result = 0;
+ __u16 msr;
+ unsigned int mcr = ATEN2011_port->shadowMCR;
+ int status;
+
+ status = get_uart_reg(ATEN2011_port->port, MODEM_STATUS_REGISTER, &msr);
+ result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) /* 0x002 */
+ |((mcr & MCR_RTS) ? TIOCM_RTS : 0) /* 0x004 */
+ |((msr & ATEN2011_MSR_CTS) ? TIOCM_CTS : 0) /* 0x020 */
+ |((msr & ATEN2011_MSR_CD) ? TIOCM_CAR : 0) /* 0x040 */
+ |((msr & ATEN2011_MSR_RI) ? TIOCM_RI : 0) /* 0x080 */
+ |((msr & ATEN2011_MSR_DSR) ? TIOCM_DSR : 0); /* 0x100 */
+
+ dbg("%s -- %x", __func__, result);
+
+ if (copy_to_user(value, &result, sizeof(int)))
+ return -EFAULT;
+ return 0;
+}
+
+static int get_serial_info(struct ATENINTL_port *ATEN2011_port,
+ struct serial_struct __user *retinfo)
+{
+ struct serial_struct tmp;
+
+ if (ATEN2011_port == NULL)
+ return -1;
+
+ if (!retinfo)
+ return -EFAULT;
+
+ memset(&tmp, 0, sizeof(tmp));
+
+ tmp.type = PORT_16550A;
+ tmp.line = ATEN2011_port->port->serial->minor;
+ if (tmp.line == SERIAL_TTY_NO_MINOR)
+ tmp.line = 0;
+ tmp.port = ATEN2011_port->port->number;
+ tmp.irq = 0;
+ tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
+ tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
+ tmp.baud_base = 9600;
+ tmp.close_delay = 5 * HZ;
+ tmp.closing_wait = 30 * HZ;
+
+ if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
+ return -EFAULT;
+ return 0;
+}
+
+static int ATEN2011_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct ATENINTL_port *ATEN2011_port;
+ struct async_icount cnow;
+ struct async_icount cprev;
+ struct serial_icounter_struct icount;
+ int ATENret = 0;
+ unsigned int __user *user_arg = (unsigned int __user *)arg;
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ if (ATEN2011_port == NULL)
+ return -1;
+
+ dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
+
+ switch (cmd) {
+ /* return number of bytes available */
+
+ case TIOCINQ:
+ dbg("%s (%d) TIOCINQ", __func__, port->number);
+ return get_number_bytes_avail(tty, ATEN2011_port, user_arg);
+ break;
+
+ case TIOCOUTQ:
+ dbg("%s (%d) TIOCOUTQ", __func__, port->number);
+ return put_user(ATEN2011_chars_in_buffer(tty), user_arg);
+ break;
+
+ case TIOCSERGETLSR:
+ dbg("%s (%d) TIOCSERGETLSR", __func__, port->number);
+ return get_lsr_info(tty, ATEN2011_port, user_arg);
+ return 0;
+
+ case TIOCMBIS:
+ case TIOCMBIC:
+ case TIOCMSET:
+ dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __func__,
+ port->number);
+ ATENret = set_modem_info(ATEN2011_port, cmd, user_arg);
+ return ATENret;
+
+ case TIOCMGET:
+ dbg("%s (%d) TIOCMGET", __func__, port->number);
+ return get_modem_info(ATEN2011_port, user_arg);
+
+ case TIOCGSERIAL:
+ dbg("%s (%d) TIOCGSERIAL", __func__, port->number);
+ return get_serial_info(ATEN2011_port,
+ (struct serial_struct __user *)arg);
+
+ case TIOCSSERIAL:
+ dbg("%s (%d) TIOCSSERIAL", __func__, port->number);
+ break;
+
+ case TIOCMIWAIT:
+ dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
+ cprev = ATEN2011_port->icount;
+ while (1) {
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ cnow = ATEN2011_port->icount;
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+ return -EIO; /* no change => error */
+ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
+ return 0;
+ }
+ cprev = cnow;
+ }
+ /* NOTREACHED */
+ break;
+
+ case TIOCGICOUNT:
+ cnow = ATEN2011_port->icount;
+ icount.cts = cnow.cts;
+ icount.dsr = cnow.dsr;
+ icount.rng = cnow.rng;
+ icount.dcd = cnow.dcd;
+ icount.rx = cnow.rx;
+ icount.tx = cnow.tx;
+ icount.frame = cnow.frame;
+ icount.overrun = cnow.overrun;
+ icount.parity = cnow.parity;
+ icount.brk = cnow.brk;
+ icount.buf_overrun = cnow.buf_overrun;
+
+ dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
+ port->number, icount.rx, icount.tx);
+ if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
+ return -EFAULT;
+ return 0;
+
+ default:
+ break;
+ }
+
+ return -ENOIOCTLCMD;
+}
+
+static int ATEN2011_calc_baud_rate_divisor(int baudRate, int *divisor,
+ __u16 *clk_sel_val)
+{
+ dbg("%s - %d", __func__, baudRate);
+
+ if (baudRate <= 115200) {
+ *divisor = 115200 / baudRate;
+ *clk_sel_val = 0x0;
+ }
+ if ((baudRate > 115200) && (baudRate <= 230400)) {
+ *divisor = 230400 / baudRate;
+ *clk_sel_val = 0x10;
+ } else if ((baudRate > 230400) && (baudRate <= 403200)) {
+ *divisor = 403200 / baudRate;
+ *clk_sel_val = 0x20;
+ } else if ((baudRate > 403200) && (baudRate <= 460800)) {
+ *divisor = 460800 / baudRate;
+ *clk_sel_val = 0x30;
+ } else if ((baudRate > 460800) && (baudRate <= 806400)) {
+ *divisor = 806400 / baudRate;
+ *clk_sel_val = 0x40;
+ } else if ((baudRate > 806400) && (baudRate <= 921600)) {
+ *divisor = 921600 / baudRate;
+ *clk_sel_val = 0x50;
+ } else if ((baudRate > 921600) && (baudRate <= 1572864)) {
+ *divisor = 1572864 / baudRate;
+ *clk_sel_val = 0x60;
+ } else if ((baudRate > 1572864) && (baudRate <= 3145728)) {
+ *divisor = 3145728 / baudRate;
+ *clk_sel_val = 0x70;
+ }
+ return 0;
+}
+
+static int ATEN2011_send_cmd_write_baud_rate(struct ATENINTL_port
+ *ATEN2011_port, int baudRate)
+{
+ int divisor = 0;
+ int status;
+ __u16 Data;
+ unsigned char number;
+ __u16 clk_sel_val;
+ struct usb_serial_port *port;
+ int minor;
+
+ if (ATEN2011_port == NULL)
+ return -1;
+
+ port = (struct usb_serial_port *)ATEN2011_port->port;
+
+ dbg("%s", "Entering .......... ");
+
+ minor = ATEN2011_port->port->serial->minor;
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+ number = ATEN2011_port->port->number - minor;
+
+ dbg("%s - port = %d, baud = %d", __func__,
+ ATEN2011_port->port->number, baudRate);
+ /* reset clk_uart_sel in spregOffset */
+ if (baudRate > 115200) {
+#ifdef HW_flow_control
+ /*
+ * NOTE: need to see the pther register to modify
+ * setting h/w flow control bit to 1;
+ */
+ /* Data = ATEN2011_port->shadowMCR; */
+ Data = 0x2b;
+ ATEN2011_port->shadowMCR = Data;
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ if (status < 0) {
+ dbg("Writing spreg failed in set_serial_baud");
+ return -1;
+ }
+#endif
+
+ } else {
+#ifdef HW_flow_control
+ /* setting h/w flow control bit to 0; */
+ /* Data = ATEN2011_port->shadowMCR; */
+ Data = 0xb;
+ ATEN2011_port->shadowMCR = Data;
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ if (status < 0) {
+ dbg("Writing spreg failed in set_serial_baud");
+ return -1;
+ }
+#endif
+
+ }
+
+ if (1) /* baudRate <= 115200) */ {
+ clk_sel_val = 0x0;
+ Data = 0x0;
+ status =
+ ATEN2011_calc_baud_rate_divisor(baudRate, &divisor,
+ &clk_sel_val);
+ status = get_reg_sync(port, ATEN2011_port->SpRegOffset, &Data);
+ if (status < 0) {
+ dbg("reading spreg failed in set_serial_baud");
+ return -1;
+ }
+ Data = (Data & 0x8f) | clk_sel_val;
+ status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+ if (status < 0) {
+ dbg("Writing spreg failed in set_serial_baud");
+ return -1;
+ }
+ /* Calculate the Divisor */
+
+ if (status) {
+ err("%s - bad baud rate", __func__);
+ dbg("%s", "bad baud rate");
+ return status;
+ }
+ /* Enable access to divisor latch */
+ Data = ATEN2011_port->shadowLCR | SERIAL_LCR_DLAB;
+ ATEN2011_port->shadowLCR = Data;
+ set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+
+ /* Write the divisor */
+ Data = (unsigned char)(divisor & 0xff);
+ dbg("set_serial_baud Value to write DLL is %x", Data);
+ set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
+
+ Data = (unsigned char)((divisor & 0xff00) >> 8);
+ dbg("set_serial_baud Value to write DLM is %x", Data);
+ set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
+
+ /* Disable access to divisor latch */
+ Data = ATEN2011_port->shadowLCR & ~SERIAL_LCR_DLAB;
+ ATEN2011_port->shadowLCR = Data;
+ set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+
+ }
+
+ return status;
+}
+
+static void ATEN2011_change_port_settings(struct tty_struct *tty,
+ struct ATENINTL_port *ATEN2011_port,
+ struct ktermios *old_termios)
+{
+ int baud;
+ unsigned cflag;
+ unsigned iflag;
+ __u8 lData;
+ __u8 lParity;
+ __u8 lStop;
+ int status;
+ __u16 Data;
+ struct usb_serial_port *port;
+ struct usb_serial *serial;
+
+ if (ATEN2011_port == NULL)
+ return;
+
+ port = (struct usb_serial_port *)ATEN2011_port->port;
+
+ serial = port->serial;
+
+ dbg("%s - port %d", __func__, ATEN2011_port->port->number);
+
+ if (!ATEN2011_port->open) {
+ dbg("%s - port not opened", __func__);
+ return;
+ }
+
+ if ((!tty) || (!tty->termios)) {
+ dbg("%s - no tty structures", __func__);
+ return;
+ }
+
+ dbg("%s", "Entering .......... ");
+
+ lData = LCR_BITS_8;
+ lStop = LCR_STOP_1;
+ lParity = LCR_PAR_NONE;
+
+ cflag = tty->termios->c_cflag;
+ iflag = tty->termios->c_iflag;
+
+ /* Change the number of bits */
+
+ /* COMMENT1: the below Line"if(cflag & CSIZE)" is added for the errors we get for serial loop data test i.e serial_loopback.pl -v */
+ /* if(cflag & CSIZE) */
+ {
+ switch (cflag & CSIZE) {
+ case CS5:
+ lData = LCR_BITS_5;
+ break;
+
+ case CS6:
+ lData = LCR_BITS_6;
+ break;
+
+ case CS7:
+ lData = LCR_BITS_7;
+ break;
+ default:
+ case CS8:
+ lData = LCR_BITS_8;
+ break;
+ }
+ }
+ /* Change the Parity bit */
+ if (cflag & PARENB) {
+ if (cflag & PARODD) {
+ lParity = LCR_PAR_ODD;
+ dbg("%s - parity = odd", __func__);
+ } else {
+ lParity = LCR_PAR_EVEN;
+ dbg("%s - parity = even", __func__);
+ }
+
+ } else {
+ dbg("%s - parity = none", __func__);
+ }
+
+ if (cflag & CMSPAR)
+ lParity = lParity | 0x20;
+
+ /* Change the Stop bit */
+ if (cflag & CSTOPB) {
+ lStop = LCR_STOP_2;
+ dbg("%s - stop bits = 2", __func__);
+ } else {
+ lStop = LCR_STOP_1;
+ dbg("%s - stop bits = 1", __func__);
+ }
+
+ /* Update the LCR with the correct value */
+ ATEN2011_port->shadowLCR &=
+ ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
+ ATEN2011_port->shadowLCR |= (lData | lParity | lStop);
+
+ dbg
+ ("ATEN2011_change_port_settings ATEN2011_port->shadowLCR is %x",
+ ATEN2011_port->shadowLCR);
+ /* Disable Interrupts */
+ Data = 0x00;
+ set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+
+ Data = 0x00;
+ set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
+
+ Data = 0xcf;
+ set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
+
+ /* Send the updated LCR value to the ATEN2011 */
+ Data = ATEN2011_port->shadowLCR;
+
+ set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+
+ Data = 0x00b;
+ ATEN2011_port->shadowMCR = Data;
+ set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ Data = 0x00b;
+ set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+
+ /* set up the MCR register and send it to the ATEN2011 */
+
+ ATEN2011_port->shadowMCR = MCR_MASTER_IE;
+ if (cflag & CBAUD)
+ ATEN2011_port->shadowMCR |= (MCR_DTR | MCR_RTS);
+
+ if (cflag & CRTSCTS)
+ ATEN2011_port->shadowMCR |= (MCR_XON_ANY);
+ else
+ ATEN2011_port->shadowMCR &= ~(MCR_XON_ANY);
+
+ Data = ATEN2011_port->shadowMCR;
+ set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+
+ /* Determine divisor based on baud rate */
+ baud = tty_get_baud_rate(tty);
+
+ if (!baud) {
+ /* pick a default, any default... */
+ dbg("%s", "Picked default baud...");
+ baud = 9600;
+ }
+
+ dbg("%s - baud rate = %d", __func__, baud);
+ status = ATEN2011_send_cmd_write_baud_rate(ATEN2011_port, baud);
+
+ /* Enable Interrupts */
+ Data = 0x0c;
+ set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+
+ if (ATEN2011_port->read_urb->status != -EINPROGRESS) {
+ ATEN2011_port->read_urb->dev = serial->dev;
+
+ status = usb_submit_urb(ATEN2011_port->read_urb, GFP_ATOMIC);
+
+ if (status) {
+ dbg
+ (" usb_submit_urb(read bulk) failed, status = %d",
+ status);
+ }
+ }
+ dbg
+ ("ATEN2011_change_port_settings ATEN2011_port->shadowLCR is End %x",
+ ATEN2011_port->shadowLCR);
+
+ return;
+}
+
+static int ATEN2011_calc_num_ports(struct usb_serial *serial)
+{
+
+ __u16 Data = 0x00;
+ int ret = 0;
+ int ATEN2011_2or4ports;
+ ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ ATEN_RDREQ, ATEN_RD_RTYPE, 0, GPIO_REGISTER,
+ &Data, VENDOR_READ_LENGTH, ATEN_WDR_TIMEOUT);
+
+/* ghostgum: here is where the problem appears to bet */
+/* Which of the following are needed? */
+/* Greg used the serial->type->num_ports=2 */
+/* But the code in the ATEN2011_open relies on serial->num_ports=2 */
+ if ((Data & 0x01) == 0) {
+ ATEN2011_2or4ports = 2;
+ serial->type->num_ports = 2;
+ serial->num_ports = 2;
+ }
+ /* else if(serial->interface->cur_altsetting->desc.bNumEndpoints == 9) */
+ else {
+ ATEN2011_2or4ports = 4;
+ serial->type->num_ports = 4;
+ serial->num_ports = 4;
+
+ }
+
+ return ATEN2011_2or4ports;
+}
+
+static int ATEN2011_startup(struct usb_serial *serial)
+{
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct ATENINTL_port *ATEN2011_port;
+ struct usb_device *dev;
+ int i, status;
+ int minor;
+
+ __u16 Data;
+ dbg("%s", " ATEN2011_startup :entering..........");
+
+ if (!serial) {
+ dbg("%s", "Invalid Handler");
+ return -1;
+ }
+
+ dev = serial->dev;
+
+ dbg("%s", "Entering...");
+
+ /* create our private serial structure */
+ ATEN2011_serial = kzalloc(sizeof(struct ATENINTL_serial), GFP_KERNEL);
+ if (ATEN2011_serial == NULL) {
+ err("%s - Out of memory", __func__);
+ return -ENOMEM;
+ }
+
+ /* resetting the private structure field values to zero */
+ memset(ATEN2011_serial, 0, sizeof(struct ATENINTL_serial));
+
+ ATEN2011_serial->serial = serial;
+ /* initilize status polling flag to 0 */
+ ATEN2011_serial->status_polling_started = 0;
+
+ usb_set_serial_data(serial, ATEN2011_serial);
+ ATEN2011_serial->ATEN2011_spectrum_2or4ports =
+ ATEN2011_calc_num_ports(serial);
+ /* we set up the pointers to the endpoints in the ATEN2011_open *
+ * function, as the structures aren't created yet. */
+
+ /* set up port private structures */
+ for (i = 0; i < serial->num_ports; ++i) {
+ ATEN2011_port =
+ kmalloc(sizeof(struct ATENINTL_port), GFP_KERNEL);
+ if (ATEN2011_port == NULL) {
+ err("%s - Out of memory", __func__);
+ usb_set_serial_data(serial, NULL);
+ kfree(ATEN2011_serial);
+ return -ENOMEM;
+ }
+ memset(ATEN2011_port, 0, sizeof(struct ATENINTL_port));
+
+ /*
+ * Initialize all port interrupt end point to port 0
+ * int endpoint. Our device has only one interrupt end point
+ * comman to all port
+ */
+ /* serial->port[i]->interrupt_in_endpointAddress = serial->port[0]->interrupt_in_endpointAddress; */
+
+ ATEN2011_port->port = serial->port[i];
+ usb_set_serial_port_data(serial->port[i], ATEN2011_port);
+
+ minor = serial->port[i]->serial->minor;
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+ ATEN2011_port->port_num =
+ ((serial->port[i]->number - minor) + 1);
+
+ if (ATEN2011_port->port_num == 1) {
+ ATEN2011_port->SpRegOffset = 0x0;
+ ATEN2011_port->ControlRegOffset = 0x1;
+ ATEN2011_port->DcrRegOffset = 0x4;
+ } else if ((ATEN2011_port->port_num == 2)
+ && (ATEN2011_serial->ATEN2011_spectrum_2or4ports ==
+ 4)) {
+ ATEN2011_port->SpRegOffset = 0x8;
+ ATEN2011_port->ControlRegOffset = 0x9;
+ ATEN2011_port->DcrRegOffset = 0x16;
+ } else if ((ATEN2011_port->port_num == 2)
+ && (ATEN2011_serial->ATEN2011_spectrum_2or4ports ==
+ 2)) {
+ ATEN2011_port->SpRegOffset = 0xa;
+ ATEN2011_port->ControlRegOffset = 0xb;
+ ATEN2011_port->DcrRegOffset = 0x19;
+ } else if ((ATEN2011_port->port_num == 3)
+ && (ATEN2011_serial->ATEN2011_spectrum_2or4ports ==
+ 4)) {
+ ATEN2011_port->SpRegOffset = 0xa;
+ ATEN2011_port->ControlRegOffset = 0xb;
+ ATEN2011_port->DcrRegOffset = 0x19;
+ } else if ((ATEN2011_port->port_num == 4)
+ && (ATEN2011_serial->ATEN2011_spectrum_2or4ports ==
+ 4)) {
+ ATEN2011_port->SpRegOffset = 0xc;
+ ATEN2011_port->ControlRegOffset = 0xd;
+ ATEN2011_port->DcrRegOffset = 0x1c;
+ }
+
+ usb_set_serial_port_data(serial->port[i], ATEN2011_port);
+
+ /* enable rx_disable bit in control register */
+
+ status = get_reg_sync(serial->port[i],
+ ATEN2011_port->ControlRegOffset, &Data);
+ if (status < 0) {
+ dbg("Reading ControlReg failed status-0x%x",
+ status);
+ break;
+ } else
+ dbg
+ ("ControlReg Reading success val is %x, status%d",
+ Data, status);
+ Data |= 0x08; /* setting driver done bit */
+ Data |= 0x04; /* sp1_bit to have cts change reflect in modem status reg */
+
+ /* Data |= 0x20; */ /* rx_disable bit */
+ status = set_reg_sync(serial->port[i],
+ ATEN2011_port->ControlRegOffset, Data);
+ if (status < 0) {
+ dbg
+ ("Writing ControlReg failed(rx_disable) status-0x%x",
+ status);
+ break;
+ } else
+ dbg
+ ("ControlReg Writing success(rx_disable) status%d",
+ status);
+
+ /*
+ * Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
+ * and 0x24 in DCR3
+ */
+ Data = 0x01;
+ status = set_reg_sync(serial->port[i],
+ (__u16)(ATEN2011_port->DcrRegOffset + 0),
+ Data);
+ if (status < 0) {
+ dbg("Writing DCR0 failed status-0x%x", status);
+ break;
+ } else
+ dbg("DCR0 Writing success status%d", status);
+
+ Data = 0x05;
+ status = set_reg_sync(serial->port[i],
+ (__u16)(ATEN2011_port->DcrRegOffset + 1),
+ Data);
+ if (status < 0) {
+ dbg("Writing DCR1 failed status-0x%x", status);
+ break;
+ } else
+ dbg("DCR1 Writing success status%d", status);
+
+ Data = 0x24;
+ status = set_reg_sync(serial->port[i],
+ (__u16)(ATEN2011_port->DcrRegOffset + 2),
+ Data);
+ if (status < 0) {
+ dbg("Writing DCR2 failed status-0x%x", status);
+ break;
+ } else
+ dbg("DCR2 Writing success status%d", status);
+
+ /* write values in clkstart0x0 and clkmulti 0x20 */
+ Data = 0x0;
+ status = set_reg_sync(serial->port[i], CLK_START_VALUE_REGISTER,
+ Data);
+ if (status < 0) {
+ dbg
+ ("Writing CLK_START_VALUE_REGISTER failed status-0x%x",
+ status);
+ break;
+ } else
+ dbg
+ ("CLK_START_VALUE_REGISTER Writing success status%d",
+ status);
+
+ Data = 0x20;
+ status = set_reg_sync(serial->port[i], CLK_MULTI_REGISTER,
+ Data);
+ if (status < 0) {
+ dbg
+ ("Writing CLK_MULTI_REGISTER failed status-0x%x",
+ status);
+ break;
+ } else
+ dbg("CLK_MULTI_REGISTER Writing success status%d",
+ status);
+
+ /* Zero Length flag register */
+ if ((ATEN2011_port->port_num != 1)
+ && (ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2)) {
+
+ Data = 0xff;
+ status = set_reg_sync(serial->port[i],
+ (__u16)(ZLP_REG1 + ((__u16)ATEN2011_port->port_num)),
+ Data);
+ dbg("ZLIP offset%x",
+ (__u16) (ZLP_REG1 +
+ ((__u16) ATEN2011_port->port_num)));
+ if (status < 0) {
+ dbg
+ ("Writing ZLP_REG%d failed status-0x%x",
+ i + 2, status);
+ break;
+ } else
+ dbg("ZLP_REG%d Writing success status%d",
+ i + 2, status);
+ } else {
+ Data = 0xff;
+ status = set_reg_sync(serial->port[i],
+ (__u16)(ZLP_REG1 + ((__u16)ATEN2011_port->port_num) - 0x1),
+ Data);
+ dbg("ZLIP offset%x",
+ (__u16) (ZLP_REG1 +
+ ((__u16) ATEN2011_port->port_num) -
+ 0x1));
+ if (status < 0) {
+ dbg
+ ("Writing ZLP_REG%d failed status-0x%x",
+ i + 1, status);
+ break;
+ } else
+ dbg("ZLP_REG%d Writing success status%d",
+ i + 1, status);
+
+ }
+ ATEN2011_port->control_urb = usb_alloc_urb(0, GFP_ATOMIC);
+ ATEN2011_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
+
+ }
+
+ /* Zero Length flag enable */
+ Data = 0x0f;
+ status = set_reg_sync(serial->port[0], ZLP_REG5, Data);
+ if (status < 0) {
+ dbg("Writing ZLP_REG5 failed status-0x%x", status);
+ return -1;
+ } else
+ dbg("ZLP_REG5 Writing success status%d", status);
+
+ /* setting configuration feature to one */
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ);
+ return 0;
+}
+
+static void ATEN2011_shutdown(struct usb_serial *serial)
+{
+ int i;
+ struct ATENINTL_port *ATEN2011_port;
+
+ /* check for the ports to be closed,close the ports and disconnect */
+
+ /* free private structure allocated for serial port *
+ * stop reads and writes on all ports */
+
+ for (i = 0; i < serial->num_ports; ++i) {
+ ATEN2011_port = usb_get_serial_port_data(serial->port[i]);
+ kfree(ATEN2011_port->ctrl_buf);
+ usb_kill_urb(ATEN2011_port->control_urb);
+ kfree(ATEN2011_port);
+ usb_set_serial_port_data(serial->port[i], NULL);
+ }
+
+ /* free private structure allocated for serial device */
+
+ kfree(usb_get_serial_data(serial));
+ usb_set_serial_data(serial, NULL);
+}
+
+static struct usb_serial_driver aten_serial_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "aten2011",
+ },
+ .description = DRIVER_DESC,
+ .id_table = id_table,
+ .open = ATEN2011_open,
+ .close = ATEN2011_close,
+ .write = ATEN2011_write,
+ .write_room = ATEN2011_write_room,
+ .chars_in_buffer = ATEN2011_chars_in_buffer,
+ .throttle = ATEN2011_throttle,
+ .unthrottle = ATEN2011_unthrottle,
+ .calc_num_ports = ATEN2011_calc_num_ports,
+
+ .ioctl = ATEN2011_ioctl,
+ .set_termios = ATEN2011_set_termios,
+ .break_ctl = ATEN2011_break,
+ .tiocmget = ATEN2011_tiocmget,
+ .tiocmset = ATEN2011_tiocmset,
+ .attach = ATEN2011_startup,
+ .shutdown = ATEN2011_shutdown,
+ .read_bulk_callback = ATEN2011_bulk_in_callback,
+ .read_int_callback = ATEN2011_interrupt_callback,
+};
+
+static struct usb_driver aten_driver = {
+ .name = "aten2011",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
+static int __init aten_init(void)
+{
+ int retval;
+
+ /* Register with the usb serial */
+ retval = usb_serial_register(&aten_serial_driver);
+ if (retval)
+ return retval;
+
+ printk(KERN_INFO KBUILD_MODNAME ":"
+ DRIVER_DESC " " DRIVER_VERSION "\n");
+
+ /* Register with the usb */
+ retval = usb_register(&aten_driver);
+ if (retval)
+ usb_serial_deregister(&aten_serial_driver);
+
+ return retval;
+}
+
+static void __exit aten_exit(void)
+{
+ usb_deregister(&aten_driver);
+ usb_serial_deregister(&aten_serial_driver);
+}
+
+module_init(aten_init);
+module_exit(aten_exit);
+
+/* Module information */
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index 2eb61372fe0..1c710628df0 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -334,7 +334,7 @@ static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
spin_lock_irqsave(&sdev->priv_lock, flags);
- priv = kmem_cache_alloc(stub_priv_cache, GFP_ATOMIC);
+ priv = kmem_cache_zalloc(stub_priv_cache, GFP_ATOMIC);
if (!priv) {
dev_err(&sdev->interface->dev, "alloc stub_priv\n");
spin_unlock_irqrestore(&sdev->priv_lock, flags);
@@ -342,8 +342,6 @@ static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
return NULL;
}
- memset(priv, 0, sizeof(struct stub_priv));
-
priv->seqnum = pdu->base.seqnum;
priv->sdev = sdev;
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c
index 0fd33a62d93..e4c71435aa1 100644
--- a/drivers/staging/usbip/vhci_sysfs.c
+++ b/drivers/staging/usbip/vhci_sysfs.c
@@ -31,8 +31,7 @@ static ssize_t show_status(struct device *dev, struct device_attribute *attr,
char *s = out;
int i = 0;
- if (!the_controller || !out)
- BUG();
+ BUG_ON(!the_controller || !out);
spin_lock(&the_controller->lock);
diff --git a/drivers/staging/winbond/bss_f.h b/drivers/staging/winbond/bss_f.h
deleted file mode 100644
index a433b5a8592..00000000000
--- a/drivers/staging/winbond/bss_f.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef __WINBOND_BSS_F_H
-#define __WINBOND_BSS_F_H
-
-#include "core.h"
-
-struct PMKID_Information_Element;
-
-//
-// BSS descriptor DataBase management global function
-//
-
-void vBSSdescriptionInit(struct wbsoft_priv * adapter);
-void vBSSfoundList(struct wbsoft_priv * adapter);
-u8 boChanFilter(struct wbsoft_priv * adapter, u8 ChanNo);
-u16 wBSSallocateEntry(struct wbsoft_priv * adapter);
-u16 wBSSGetEntry(struct wbsoft_priv * adapter);
-void vSimpleHouseKeeping(struct wbsoft_priv * adapter);
-u16 wBSShouseKeeping(struct wbsoft_priv * adapter);
-void ClearBSSdescpt(struct wbsoft_priv * adapter, u16 i);
-u16 wBSSfindBssID(struct wbsoft_priv * adapter, u8 *pbBssid);
-u16 wBSSfindDedicateCandidate(struct wbsoft_priv * adapter, struct SSID_Element *psSsid, u8 *pbBssid);
-u16 wBSSfindMACaddr(struct wbsoft_priv * adapter, u8 *pbMacAddr);
-u16 wBSSsearchMACaddr(struct wbsoft_priv * adapter, u8 *pbMacAddr, u8 band);
-u16 wBSSaddScanData(struct wbsoft_priv *, u16, psRXDATA);
-u16 wBSSUpdateScanData(struct wbsoft_priv * adapter, u16 wBssIdx, psRXDATA psRcvData);
-u16 wBSScreateIBSSdata(struct wbsoft_priv * adapter, PWB_BSSDESCRIPTION psDesData);
-void DesiredRate2BSSdescriptor(struct wbsoft_priv * adapter, PWB_BSSDESCRIPTION psDesData,
- u8 *pBasicRateSet, u8 BasicRateCount,
- u8 *pOperationRateSet, u8 OperationRateCount);
-void DesiredRate2InfoElement(struct wbsoft_priv * adapter, u8 *addr, u16 *iFildOffset,
- u8 *pBasicRateSet, u8 BasicRateCount,
- u8 *pOperationRateSet, u8 OperationRateCount);
-void BSSAddIBSSdata(struct wbsoft_priv * adapter, PWB_BSSDESCRIPTION psDesData);
-unsigned char boCmpMacAddr( u8 *, u8 *);
-unsigned char boCmpSSID(struct SSID_Element *psSSID1, struct SSID_Element *psSSID2);
-u16 wBSSfindSSID(struct wbsoft_priv * adapter, struct SSID_Element *psSsid);
-u16 wRoamingQuery(struct wbsoft_priv * adapter);
-void vRateToBitmap(struct wbsoft_priv * adapter, u16 index);
-u8 bRateToBitmapIndex(struct wbsoft_priv * adapter, u8 bRate);
-u8 bBitmapToRate(u8 i);
-unsigned char boIsERPsta(struct wbsoft_priv * adapter, u16 i);
-unsigned char boCheckConnect(struct wbsoft_priv * adapter);
-unsigned char boCheckSignal(struct wbsoft_priv * adapter);
-void AddIBSSIe(struct wbsoft_priv * adapter,PWB_BSSDESCRIPTION psDesData );//added by ws for WPA_None06/01/04
-void BssScanUpToDate(struct wbsoft_priv * adapter);
-void BssUpToDate(struct wbsoft_priv * adapter);
-void RateSort(u8 *RateArray, u8 num, u8 mode);
-void RateReSortForSRate(struct wbsoft_priv * adapter, u8 *RateArray, u8 num);
-void Assemble_IE(struct wbsoft_priv * adapter, u16 wBssIdx);
-void SetMaxTxRate(struct wbsoft_priv * adapter);
-
-void CreateWpaIE(struct wbsoft_priv * adapter, u16* iFildOffset, u8 *msg, struct Management_Frame* msgHeader,
- struct Association_Request_Frame_Body* msgBody, u16 iMSindex); //added by WS 05/14/05
-
-#ifdef _WPA2_
-void CreateRsnIE(struct wbsoft_priv * adapter, u16* iFildOffset, u8 *msg, struct Management_Frame* msgHeader,
- struct Association_Request_Frame_Body* msgBody, u16 iMSindex);//added by WS 05/14/05
-
-u16 SearchPmkid(struct wbsoft_priv * adapter, struct Management_Frame* msgHeader,
- struct PMKID_Information_Element * AssoReq_PMKID );
-#endif
-
-#endif
diff --git a/drivers/staging/winbond/bssdscpt.h b/drivers/staging/winbond/bssdscpt.h
deleted file mode 100644
index 3a71d4efb89..00000000000
--- a/drivers/staging/winbond/bssdscpt.h
+++ /dev/null
@@ -1,164 +0,0 @@
-#ifndef __WINBOND_BSSDSCPT_H
-#define __WINBOND_BSSDSCPT_H
-
-#include <linux/types.h>
-
-#include "mds_s.h"
-#include "mlme_s.h"
-
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-// 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
- struct timer_list timer; // 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)]))
-
-#endif
diff --git a/drivers/staging/winbond/common.h b/drivers/staging/winbond/common.h
deleted file mode 100644
index c4d96041e9a..00000000000
--- a/drivers/staging/winbond/common.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// 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
-
-//#define DEBUG_ENABLED 1
-
-//==================================================================================================
-// Common function definition
-//==================================================================================================
-#define DEBUG_ENABLED
-#define ETH_LENGTH_OF_ADDRESS 6
-#ifdef DEBUG_ENABLED
-#define WBDEBUG( _M ) printk _M
-#else
-#define WBDEBUG( _M ) 0
-#endif
-
-#endif // COMMON_DEF
-
diff --git a/drivers/staging/winbond/core.h b/drivers/staging/winbond/core.h
index fe142a10ea8..eb4c090972c 100644
--- a/drivers/staging/winbond/core.h
+++ b/drivers/staging/winbond/core.h
@@ -3,9 +3,9 @@
#include <linux/wireless.h>
-#include "bssdscpt.h"
-#include "mto.h"
+#include "mlme_s.h"
#include "wbhal_s.h"
+#include "mto.h"
#define WBLINUX_PACKET_ARRAY_SIZE (ETHERNET_TX_DESCRIPTORS*4)
@@ -15,12 +15,11 @@ struct wbsoft_priv {
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
+ struct hw_data sHwData; //For HAL
MDS Mds;
spinlock_t SpinLock;
diff --git a/drivers/staging/winbond/ds_tkip.h b/drivers/staging/winbond/ds_tkip.h
deleted file mode 100644
index 9c5c4e73f2c..00000000000
--- a/drivers/staging/winbond/ds_tkip.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __WINBOND_DS_TKIP_H
-#define __WINBOND_DS_TKIP_H
-
-#include <linux/types.h>
-
-// 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( u8 *pData, u16 size, tkip_t *p );
-void Mds_MicGet( void* adapter, void* pRxLayer1, u8 *pKey, u8 *pMic );
-void Mds_MicFill( void* adapter, void* pDes, u8 *XmitBufAddress );
-
-#endif
diff --git a/drivers/staging/winbond/gl_80211.h b/drivers/staging/winbond/gl_80211.h
deleted file mode 100644
index 5a244c44a61..00000000000
--- a/drivers/staging/winbond/gl_80211.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef __GL_80211_H__
-#define __GL_80211_H__
-
-#include <linux/types.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
deleted file mode 100644
index e8b35dc7e32..00000000000
--- a/drivers/staging/winbond/ioctls.h
+++ /dev/null
@@ -1,678 +0,0 @@
-//============================================================================
-// 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/mds.c b/drivers/staging/winbond/mds.c
index e431406e25a..c7af09257e6 100644
--- a/drivers/staging/winbond/mds.c
+++ b/drivers/staging/winbond/mds.c
@@ -1,9 +1,7 @@
-#include "ds_tkip.h"
-#include "gl_80211.h"
#include "mds_f.h"
#include "mlmetxrx_f.h"
-#include "mto_f.h"
-#include "os_common.h"
+#include "mto.h"
+#include "sysdef.h"
#include "wbhal_f.h"
#include "wblinux_f.h"
@@ -374,7 +372,7 @@ static void Mds_HeaderCopy(struct wbsoft_priv * adapter, PDESCRIPTOR pDes, u8 *T
pDes->TxRate = ctmp1;
#ifdef _PE_TX_DUMP_
- WBDEBUG(("Tx rate =%x\n", ctmp1));
+ printk("Tx rate =%x\n", ctmp1);
#endif
pT01->T01_modulation_type = (ctmp1%3) ? 0 : 1;
@@ -418,14 +416,14 @@ static void Mds_HeaderCopy(struct wbsoft_priv * adapter, PDESCRIPTOR pDes, u8 *T
void
Mds_Tx(struct wbsoft_priv * adapter)
{
- phw_data_t pHwData = &adapter->sHwData;
+ struct hw_data * pHwData = &adapter->sHwData;
PMDS pMds = &adapter->Mds;
DESCRIPTOR TxDes;
PDESCRIPTOR pTxDes = &TxDes;
u8 *XmitBufAddress;
u16 XmitBufSize, PacketSize, stmp, CurrentSize, FragmentThreshold;
u8 FillIndex, TxDesIndex, FragmentCount, FillCount;
- unsigned char BufferFilled = false, MICAdd = 0;
+ unsigned char BufferFilled = false;
if (pMds->TxPause)
@@ -442,7 +440,7 @@ Mds_Tx(struct wbsoft_priv * adapter)
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"));
+ printk("[Mds_Tx] Tx Owner is H/W.\n");
#endif
break;
}
@@ -488,7 +486,7 @@ Mds_Tx(struct wbsoft_priv * adapter)
// For speed up Key setting
if (pTxDes->EapFix) {
#ifdef _PE_TX_DUMP_
- WBDEBUG(("35: EPA 4th frame detected. Size = %d\n", PacketSize));
+ printk("35: EPA 4th frame detected. Size = %d\n", PacketSize);
#endif
pHwData->IsKeyPreSet = 1;
}
@@ -499,12 +497,6 @@ Mds_Tx(struct wbsoft_priv * adapter)
// 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;
@@ -561,7 +553,7 @@ void
Mds_SendComplete(struct wbsoft_priv * adapter, PT02_DESCRIPTOR pT02)
{
PMDS pMds = &adapter->Mds;
- phw_data_t pHwData = &adapter->sHwData;
+ struct hw_data * pHwData = &adapter->sHwData;
u8 PacketId = (u8)pT02->T02_Tx_PktID;
unsigned char SendOK = true;
u8 RetryCount, TxRate;
@@ -585,7 +577,7 @@ Mds_SendComplete(struct wbsoft_priv * adapter, PT02_DESCRIPTOR pT02)
else
pHwData->tx_retry_count[7] += RetryCount;
#ifdef _PE_STATE_DUMP_
- WBDEBUG(("dto_tx_retry_count =%d\n", pHwData->dto_tx_retry_count));
+ printk("dto_tx_retry_count =%d\n", pHwData->dto_tx_retry_count);
#endif
MTO_SetTxCount(adapter, TxRate, RetryCount);
}
diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h
index ebf61e3ce1d..9ffec1764d6 100644
--- a/drivers/staging/winbond/mds_s.h
+++ b/drivers/staging/winbond/mds_s.h
@@ -9,6 +9,12 @@
#include "mac_structures.h"
#include "scan_s.h"
+/* Preamble_Type, see <SFS-802.11G-MIB-203> */
+enum {
+ WLAN_PREAMBLE_TYPE_SHORT,
+ WLAN_PREAMBLE_TYPE_LONG,
+};
+
////////////////////////////////////////////////////////////////////////////////////////////////////////
#define MAX_USB_TX_DESCRIPTOR 15 // IS89C35 ability
#define MAX_USB_TX_BUFFER_NUMBER 4 // Virtual pre-buffer number of MAX_USB_TX_BUFFER
@@ -17,26 +23,8 @@
#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_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
diff --git a/drivers/staging/winbond/mlme_mib.h b/drivers/staging/winbond/mlme_mib.h
deleted file mode 100644
index ca8922ec633..00000000000
--- a/drivers/staging/winbond/mlme_mib.h
+++ /dev/null
@@ -1,84 +0,0 @@
-//============================================================================
-// 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/mlmetxrx.c b/drivers/staging/winbond/mlmetxrx.c
index 07802afd2b8..643ceb060d5 100644
--- a/drivers/staging/winbond/mlmetxrx.c
+++ b/drivers/staging/winbond/mlmetxrx.c
@@ -15,7 +15,7 @@
//
// Copyright (c) 1996-2002 Winbond Electronics Corp. All Rights Reserved.
//============================================================================
-#include "os_common.h"
+#include "sysdef.h"
#include "mds_f.h"
diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c
index de11a05efae..94a060bcc62 100644
--- a/drivers/staging/winbond/mto.c
+++ b/drivers/staging/winbond/mto.c
@@ -22,9 +22,8 @@
//============================================================================
// LA20040210_DTO kevin
-#include "os_common.h"
+#include "sysdef.h"
#include "sme_api.h"
-#include "gl_80211.h"
#include "wbhal_f.h"
// Declare SQ3 to rate and fragmentation threshold table
@@ -51,20 +50,14 @@ static int retryrate_rec[MTO_MAX_DATA_RATE_LEVELS];//this record the retry rate
static int PeriodTotalTxPkt = 0;
static int PeriodTotalTxPktRetry = 0;
-typedef struct
-{
- s32 RSSI;
- u8 TxRate;
-}RSSI2RATE;
-
static u8 boSparseTxTraffic = false;
-void MTO_Init(MTO_FUNC_INPUT);
-void TxRateReductionCtrl(MTO_FUNC_INPUT);
+void MTO_Init(struct wbsoft_priv *adapter);
+void TxRateReductionCtrl(struct wbsoft_priv *adapter);
/** 1.1.31.1000 Turbo modify */
-void MTO_SetTxCount(MTO_FUNC_INPUT, u8 t0, u8 index);
-void MTO_TxFailed(MTO_FUNC_INPUT);
-void hal_get_dto_para(MTO_FUNC_INPUT, char *buffer);
+void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index);
+void MTO_TxFailed(struct wbsoft_priv *adapter);
+void hal_get_dto_para(struct wbsoft_priv *adapter, char *buffer);
//===========================================================================
// MTO_Init --
@@ -80,10 +73,9 @@ void hal_get_dto_para(MTO_FUNC_INPUT, char *buffer);
// Return Value:
// None
//============================================================================
-void MTO_Init(MTO_FUNC_INPUT)
+void MTO_Init(struct wbsoft_priv *adapter)
{
int i;
- //WBDEBUG(("[MTO] -> MTO_Init()\n"));
//[WKCHEN]pMTOcore_data = pcore_data;
// 20040510 Turbo add for global variable
MTO_TMR_CNT() = 0;
@@ -196,7 +188,7 @@ void MTO_Init(MTO_FUNC_INPUT)
// 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)
+void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 tx_rate, u8 index)
{
MTO_TXFLOWCOUNT()++;
if ((MTO_ENABLE==1) && (MTO_RATE_CHANGE_ENABLE()==1))
diff --git a/drivers/staging/winbond/mto.h b/drivers/staging/winbond/mto.h
index 0d3775eb257..56f2465723b 100644
--- a/drivers/staging/winbond/mto.h
+++ b/drivers/staging/winbond/mto.h
@@ -13,6 +13,8 @@
#include <linux/types.h>
+struct wbsoft_priv;
+
#define MTO_DEFAULT_TH_CNT 5
#define MTO_DEFAULT_TH_SQ3 112 //OLD IS 13 reference JohnXu
#define MTO_DEFAULT_TH_IDLE_SLOT 15
@@ -131,8 +133,6 @@ typedef struct _MTO_PARAMETERS
} MTO_PARAMETERS, *PMTO_PARAMETERS;
-#define MTO_FUNC_INPUT struct wbsoft_priv * 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)
@@ -140,7 +140,6 @@ typedef struct _MTO_PARAMETERS
#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
@@ -259,6 +258,13 @@ typedef struct _STATISTICS_INFO {
s32 Antenna;
} STATISTICS_INFO, *PSTATISTICS_INFO;
+extern void MTO_Init(struct wbsoft_priv *);
+extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *);
+extern void MTO_SetDTORateRange(struct wbsoft_priv *, u8 *, u8);
+extern u8 MTO_GetTxRate(struct wbsoft_priv *adapter, u32 fpdu_len);
+extern u8 MTO_GetTxFallbackRate(struct wbsoft_priv *adapter);
+extern void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index);
+
#endif //__MTO_H__
diff --git a/drivers/staging/winbond/mto_f.h b/drivers/staging/winbond/mto_f.h
deleted file mode 100644
index 81f59137c6d..00000000000
--- a/drivers/staging/winbond/mto_f.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __WINBOND_MTO_F_H
-#define __WINBOND_MTO_F_H
-
-#include "core.h"
-
-extern void MTO_Init(struct wbsoft_priv *);
-extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *);
-extern void MTO_SetDTORateRange(struct wbsoft_priv *, 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);
-
-#endif
diff --git a/drivers/staging/winbond/os_common.h b/drivers/staging/winbond/os_common.h
deleted file mode 100644
index 2c276e3ab51..00000000000
--- a/drivers/staging/winbond/os_common.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "sysdef.h"
-
diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c
index 6782552d366..af8c01e313b 100644
--- a/drivers/staging/winbond/phy_calibration.c
+++ b/drivers/staging/winbond/phy_calibration.c
@@ -10,7 +10,7 @@
*/
/****************** INCLUDE FILES SECTION ***********************************/
-#include "os_common.h"
+#include "sysdef.h"
#include "phy_calibration.h"
#include "wbhal_f.h"
@@ -37,8 +37,8 @@ static const fixed Angles[]=
};
/****************** LOCAL FUNCTION DECLARATION SECTION **********************/
-//void _phy_rf_write_delay(hw_data_t *phw_data);
-//void phy_init_rf(hw_data_t *phw_data);
+//void _phy_rf_write_delay(struct hw_data *phw_data);
+//void phy_init_rf(struct hw_data *phw_data);
/****************** FUNCTION DEFINITION SECTION *****************************/
@@ -341,7 +341,7 @@ void _sin_cos(s32 angle, s32 *sin, s32 *cos)
}
-void _reset_rx_cal(hw_data_t *phw_data)
+void _reset_rx_cal(struct hw_data *phw_data)
{
u32 val;
@@ -366,7 +366,7 @@ void _reset_rx_cal(hw_data_t *phw_data)
//
//
// *********************************************
-void _rxadc_dc_offset_cancellation_winbond(hw_data_t *phw_data, u32 frequency)
+void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequency)
{
u32 reg_agc_ctrl3;
u32 reg_a_acq_ctrl;
@@ -465,7 +465,7 @@ void _rxadc_dc_offset_cancellation_winbond(hw_data_t *phw_data, u32 frequency)
}
////////////////////////////////////////////////////////
-void _txidac_dc_offset_cancellation_winbond(hw_data_t *phw_data)
+void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
{
u32 reg_agc_ctrl3;
u32 reg_mode_ctrl;
@@ -600,7 +600,7 @@ void _txidac_dc_offset_cancellation_winbond(hw_data_t *phw_data)
}
///////////////////////////////////////////////////////
-void _txqdac_dc_offset_cacellation_winbond(hw_data_t *phw_data)
+void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
{
u32 reg_agc_ctrl3;
u32 reg_mode_ctrl;
@@ -726,7 +726,7 @@ void _txqdac_dc_offset_cacellation_winbond(hw_data_t *phw_data)
}
//20060612.1.a 20060718.1 Modify
-u8 _tx_iq_calibration_loop_winbond(hw_data_t *phw_data,
+u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
s32 a_2_threshold,
s32 b_2_threshold)
{
@@ -1032,7 +1032,7 @@ u8 _tx_iq_calibration_loop_winbond(hw_data_t *phw_data,
return 1;
}
-void _tx_iq_calibration_winbond(hw_data_t *phw_data)
+void _tx_iq_calibration_winbond(struct hw_data *phw_data)
{
u32 reg_agc_ctrl3;
#ifdef _DEBUG
@@ -1195,7 +1195,7 @@ void _tx_iq_calibration_winbond(hw_data_t *phw_data)
}
/////////////////////////////////////////////////////////////////////////////////////////
-u8 _rx_iq_calibration_loop_winbond(hw_data_t *phw_data, u16 factor, u32 frequency)
+u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 frequency)
{
u32 reg_mode_ctrl;
s32 iqcal_tone_i;
@@ -1501,7 +1501,7 @@ u8 _rx_iq_calibration_loop_winbond(hw_data_t *phw_data, u16 factor, u32 frequenc
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-void _rx_iq_calibration_winbond(hw_data_t *phw_data, u32 frequency)
+void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
{
// figo 20050523 marked thsi flag for can't compile for relesase
#ifdef _DEBUG
@@ -1579,7 +1579,7 @@ void _rx_iq_calibration_winbond(hw_data_t *phw_data, u32 frequency)
}
////////////////////////////////////////////////////////////////////////
-void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency)
+void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency)
{
u32 reg_mode_ctrl;
u32 iq_alpha;
@@ -1618,7 +1618,7 @@ void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency)
}
//===========================
-void phy_set_rf_data( phw_data_t pHwData, u32 index, u32 value )
+void phy_set_rf_data( struct hw_data * pHwData, u32 index, u32 value )
{
u32 ltmp=0;
@@ -1660,7 +1660,7 @@ void phy_set_rf_data( phw_data_t pHwData, u32 index, u32 value )
}
// 20060717 modify as Bruce's mail
-unsigned char adjust_TXVGA_for_iq_mag(hw_data_t *phw_data)
+unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
{
int init_txvga = 0;
u32 reg_mode_ctrl;
diff --git a/drivers/staging/winbond/phy_calibration.h b/drivers/staging/winbond/phy_calibration.h
index 03b820c6181..51c8fde81e2 100644
--- a/drivers/staging/winbond/phy_calibration.h
+++ b/drivers/staging/winbond/phy_calibration.h
@@ -101,7 +101,7 @@
//#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 );
+void phy_set_rf_data( struct hw_data * pHwData, u32 index, u32 value );
#define phy_init_rf( _A ) //RFSynthesizer_initial( _A )
#endif
diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c
index cd21272d7a9..d915cbdd38e 100644
--- a/drivers/staging/winbond/reg.c
+++ b/drivers/staging/winbond/reg.c
@@ -1,4 +1,4 @@
-#include "os_common.h"
+#include "sysdef.h"
#include "wbhal_f.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -915,7 +915,7 @@ u32 w89rf242_txvga_data[][5] =
// The address is stored in EthernetIDAddr.
//=============================================================================================================
void
-Uxx_ReadEthernetAddress( phw_data_t pHwData )
+Uxx_ReadEthernetAddress( struct hw_data * pHwData )
{
u32 ltmp;
@@ -948,14 +948,13 @@ Uxx_ReadEthernetAddress( phw_data_t pHwData )
// Return Value:
// None.
//==============================================================================================================
-void CardGetMulticastBit( u8 Address[ETH_LENGTH_OF_ADDRESS],
- u8 *Byte, u8 *Value )
+void CardGetMulticastBit( u8 Address[ETH_ALEN], u8 *Byte, u8 *Value )
{
u32 Crc;
u32 BitNumber;
// First compute the CRC.
- Crc = CardComputeCrc(Address, ETH_LENGTH_OF_ADDRESS);
+ Crc = CardComputeCrc(Address, ETH_ALEN);
// 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
@@ -965,7 +964,7 @@ void CardGetMulticastBit( u8 Address[ETH_LENGTH_OF_ADDRESS],
*Value = (u8) ((u8)1 << (BitNumber % 8));
}
-void Uxx_power_on_procedure( phw_data_t pHwData )
+void Uxx_power_on_procedure( struct hw_data * pHwData )
{
u32 ltmp, loop;
@@ -1009,7 +1008,7 @@ void Uxx_power_on_procedure( phw_data_t pHwData )
Wb35Reg_WriteSync( pHwData, 0x03f8, 0x7ff );
}
-void Set_ChanIndep_RfData_al7230_24( phw_data_t pHwData, u32 *pltmp ,char number)
+void Set_ChanIndep_RfData_al7230_24( struct hw_data * pHwData, u32 *pltmp ,char number)
{
u8 i;
@@ -1020,7 +1019,7 @@ void Set_ChanIndep_RfData_al7230_24( phw_data_t pHwData, u32 *pltmp ,char numbe
}
}
-void Set_ChanIndep_RfData_al7230_50( phw_data_t pHwData, u32 *pltmp, char number)
+void Set_ChanIndep_RfData_al7230_50( struct hw_data * pHwData, u32 *pltmp, char number)
{
u8 i;
@@ -1036,7 +1035,7 @@ void Set_ChanIndep_RfData_al7230_50( phw_data_t pHwData, u32 *pltmp, char numbe
// RFSynthesizer_initial --
//=============================================================================================================
void
-RFSynthesizer_initial(phw_data_t pHwData)
+RFSynthesizer_initial(struct hw_data * pHwData)
{
u32 altmp[32];
u32 * pltmp = altmp;
@@ -1115,7 +1114,7 @@ RFSynthesizer_initial(phw_data_t pHwData)
//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"));
+ printk("* PLL_ON low\n");
#endif
number = sizeof(al7230_rf_data_24)/sizeof(al7230_rf_data_24[0]);
@@ -1224,7 +1223,7 @@ RFSynthesizer_initial(phw_data_t pHwData)
//pulled high
Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
#ifdef _PE_STATE_DUMP_
- WBDEBUG(("* PLL_ON high\n"));
+ printk("* PLL_ON high\n");
#endif
//2.4GHz
@@ -1244,7 +1243,7 @@ RFSynthesizer_initial(phw_data_t pHwData)
//5GHz
Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000000 );
#ifdef _PE_STATE_DUMP_
- WBDEBUG(("* PLL_ON low\n"));
+ printk("* PLL_ON low\n");
#endif
number = sizeof(al7230_rf_data_50)/sizeof(al7230_rf_data_50[0]);
@@ -1256,7 +1255,7 @@ RFSynthesizer_initial(phw_data_t pHwData)
Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
#ifdef _PE_STATE_DUMP_
- WBDEBUG(("* PLL_ON high\n"));
+ printk("* PLL_ON high\n");
#endif
//ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x12BACF;
@@ -1272,7 +1271,7 @@ RFSynthesizer_initial(phw_data_t pHwData)
msleep(5);
//Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
- //WBDEBUG(("* PLL_ON high\n"));
+ //printk("* PLL_ON high\n");
break;
case RF_WB_242:
@@ -1414,7 +1413,7 @@ RFSynthesizer_initial(phw_data_t pHwData)
}
}
-void BBProcessor_AL7230_2400( phw_data_t pHwData)
+void BBProcessor_AL7230_2400( struct hw_data * pHwData)
{
struct wb35_reg *reg = &pHwData->reg;
u32 pltmp[12];
@@ -1456,7 +1455,7 @@ void BBProcessor_AL7230_2400( phw_data_t pHwData)
}
-void BBProcessor_AL7230_5000( phw_data_t pHwData)
+void BBProcessor_AL7230_5000( struct hw_data * pHwData)
{
struct wb35_reg *reg = &pHwData->reg;
u32 pltmp[12];
@@ -1510,7 +1509,7 @@ void BBProcessor_AL7230_5000( phw_data_t pHwData)
// None.
//=============================================================================================================
void
-BBProcessor_initial( phw_data_t pHwData )
+BBProcessor_initial( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
u32 i, pltmp[12];
@@ -1824,12 +1823,12 @@ BBProcessor_initial( phw_data_t pHwData )
reg->SQ3_filter[i] = 0x2f; // half of Bit 0 ~ 6
}
-void set_tx_power_per_channel_max2829( phw_data_t pHwData, ChanInfo Channel)
+void set_tx_power_per_channel_max2829( struct hw_data * pHwData, ChanInfo Channel)
{
RFSynthesizer_SetPowerIndex( pHwData, 100 ); // 20060620.1 Modify
}
-void set_tx_power_per_channel_al2230( phw_data_t pHwData, ChanInfo Channel )
+void set_tx_power_per_channel_al2230( struct hw_data * pHwData, ChanInfo Channel )
{
u8 index = 100;
@@ -1839,7 +1838,7 @@ void set_tx_power_per_channel_al2230( phw_data_t pHwData, ChanInfo Channel )
RFSynthesizer_SetPowerIndex( pHwData, index );
}
-void set_tx_power_per_channel_al7230( phw_data_t pHwData, ChanInfo Channel)
+void set_tx_power_per_channel_al7230( struct hw_data * pHwData, ChanInfo Channel)
{
u8 i, index = 100;
@@ -1869,7 +1868,7 @@ void set_tx_power_per_channel_al7230( phw_data_t pHwData, ChanInfo Channel)
RFSynthesizer_SetPowerIndex( pHwData, index );
}
-void set_tx_power_per_channel_wb242( phw_data_t pHwData, ChanInfo Channel)
+void set_tx_power_per_channel_wb242( struct hw_data * pHwData, ChanInfo Channel)
{
u8 index = 100;
@@ -1902,7 +1901,7 @@ void set_tx_power_per_channel_wb242( phw_data_t pHwData, ChanInfo Channel)
// None.
//=============================================================================================================
void
-RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel )
+RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, ChanInfo Channel )
{
struct wb35_reg *reg = &pHwData->reg;
u32 pltmp[16]; // The 16 is the maximum capability of hardware
@@ -2012,7 +2011,7 @@ RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel )
//Start to fill RF parameters, PLL_ON should be pulled low.
//Wb35Reg_Write( pHwData, 0x03dc, 0x00000000 );
- //WBDEBUG(("* PLL_ON low\n"));
+ //printk("* PLL_ON low\n");
//Channel independent registers
if( Channel.band != pHwData->band)
@@ -2037,7 +2036,7 @@ RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel )
// 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"));
+ printk("Band changed\n");
#endif
}
@@ -2130,7 +2129,7 @@ RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel )
}
//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 )
+u8 RFSynthesizer_SetPowerIndex( struct hw_data * pHwData, u8 PowerIndex )
{
u32 Band = pHwData->band;
u8 index=0;
@@ -2188,7 +2187,7 @@ u8 RFSynthesizer_SetPowerIndex( phw_data_t pHwData, u8 PowerIndex )
}
//-- Sub function
-u8 RFSynthesizer_SetMaxim2828_24Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2828_24Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
if( index > 1 ) index = 1;
@@ -2197,7 +2196,7 @@ u8 RFSynthesizer_SetMaxim2828_24Power( phw_data_t pHwData, u8 index )
return index;
}
//--
-u8 RFSynthesizer_SetMaxim2828_50Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2828_50Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
if( index > 1 ) index = 1;
@@ -2206,7 +2205,7 @@ u8 RFSynthesizer_SetMaxim2828_50Power( phw_data_t pHwData, u8 index )
return index;
}
//--
-u8 RFSynthesizer_SetMaxim2827_24Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2827_24Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
if( index > 1 ) index = 1;
@@ -2215,7 +2214,7 @@ u8 RFSynthesizer_SetMaxim2827_24Power( phw_data_t pHwData, u8 index )
return index;
}
//--
-u8 RFSynthesizer_SetMaxim2827_50Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2827_50Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
if( index > 1 ) index = 1;
@@ -2224,7 +2223,7 @@ u8 RFSynthesizer_SetMaxim2827_50Power( phw_data_t pHwData, u8 index )
return index;
}
//--
-u8 RFSynthesizer_SetMaxim2825Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2825Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
if( index > 1 ) index = 1;
@@ -2233,7 +2232,7 @@ u8 RFSynthesizer_SetMaxim2825Power( phw_data_t pHwData, u8 index )
return index;
}
//--
-u8 RFSynthesizer_SetAiroha2230Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetAiroha2230Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
u8 i,count;
@@ -2252,7 +2251,7 @@ u8 RFSynthesizer_SetAiroha2230Power( phw_data_t pHwData, u8 index )
return i;
}
//--
-u8 RFSynthesizer_SetAiroha7230Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetAiroha7230Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
u8 i,count;
@@ -2271,7 +2270,7 @@ u8 RFSynthesizer_SetAiroha7230Power( phw_data_t pHwData, u8 index )
return i;
}
-u8 RFSynthesizer_SetWinbond242Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetWinbond242Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
u8 i,count;
@@ -2312,7 +2311,7 @@ u8 RFSynthesizer_SetWinbond242Power( phw_data_t pHwData, u8 index )
// Initial the hardware setting and module variable
//
//===========================================================================================================
-void Dxx_initial( phw_data_t pHwData )
+void Dxx_initial( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -2326,7 +2325,7 @@ void Dxx_initial( phw_data_t pHwData )
Wb35Reg_WriteSync( pHwData, 0x0400, reg->D00_DmaControl );
}
-void Mxx_initial( phw_data_t pHwData )
+void Mxx_initial( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
u32 tmp;
@@ -2417,7 +2416,7 @@ void Mxx_initial( phw_data_t pHwData )
}
-void Uxx_power_off_procedure( phw_data_t pHwData )
+void Uxx_power_off_procedure( struct hw_data * pHwData )
{
// SW, PMU reset and turn off clock
Wb35Reg_WriteSync( pHwData, 0x03b0, 3 );
@@ -2425,7 +2424,7 @@ void Uxx_power_off_procedure( phw_data_t pHwData )
}
//Decide the TxVga of every channel
-void GetTxVgaFromEEPROM( phw_data_t pHwData )
+void GetTxVgaFromEEPROM( struct hw_data * pHwData )
{
u32 i, j, ltmp;
u16 Value[MAX_TXVGA_EEPROM];
@@ -2479,7 +2478,7 @@ void GetTxVgaFromEEPROM( phw_data_t pHwData )
// 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
+void EEPROMTxVgaAdjust( struct hw_data * pHwData ) // 20060619.5 Add
{
u8 * pTxVga = pHwData->TxVgaSettingInEEPROM;
s16 i, stmp;
@@ -2612,14 +2611,14 @@ void EEPROMTxVgaAdjust( phw_data_t pHwData ) // 20060619.5 Add
}
#ifdef _PE_STATE_DUMP_
- WBDEBUG((" TxVgaFor24 : \n"));
+ printk(" TxVgaFor24 : \n");
DataDmp((u8 *)pHwData->TxVgaFor24, 14 ,0);
- WBDEBUG((" TxVgaFor50 : \n"));
+ printk(" TxVgaFor50 : \n");
DataDmp((u8 *)pHwData->TxVgaFor50, 70 ,0);
#endif
}
-void BBProcessor_RateChanging( phw_data_t pHwData, u8 rate ) // 20060613.1
+void BBProcessor_RateChanging( struct hw_data * pHwData, u8 rate ) // 20060613.1
{
struct wb35_reg *reg = &pHwData->reg;
unsigned char Is11bRate;
diff --git a/drivers/staging/winbond/sme_api.h b/drivers/staging/winbond/sme_api.h
index 188a2532bbf..54987830228 100644
--- a/drivers/staging/winbond/sme_api.h
+++ b/drivers/staging/winbond/sme_api.h
@@ -17,9 +17,6 @@
#include "localpara.h"
-/****************** INCLUDE FILES SECTION ***********************************/
-//#include "GL\gl_core.h"
-
/****************** CONSTANT AND MACRO SECTION ******************************/
#define _INLINE __inline
diff --git a/drivers/staging/winbond/sme_s.h b/drivers/staging/winbond/sme_s.h
deleted file mode 100644
index 1bd118f83d2..00000000000
--- a/drivers/staging/winbond/sme_s.h
+++ /dev/null
@@ -1,236 +0,0 @@
-#ifndef __WINBOND_SME_S_H
-#define __WINBOND_SME_S_H
-
-#include <linux/types.h>
-
-#include "mac_structures.h"
-#include "localpara.h"
-
-//
-// 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
- struct timer_list timer;
-
- 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
-
-#endif
diff --git a/drivers/staging/winbond/wb35_ver.h b/drivers/staging/winbond/wb35_ver.h
deleted file mode 100644
index 2433bc07300..00000000000
--- a/drivers/staging/winbond/wb35_ver.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// 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/wb35reg.c b/drivers/staging/winbond/wb35reg.c
index c74b3fdcbda..f5608ad9ed0 100644
--- a/drivers/staging/winbond/wb35reg.c
+++ b/drivers/staging/winbond/wb35reg.c
@@ -3,7 +3,7 @@
#include <linux/usb.h>
-extern void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency);
+extern void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency);
// true : read command process successfully
// false : register not support
@@ -13,7 +13,7 @@ extern void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency);
// Flag : AUTO_INCREMENT - RegisterNo will auto increment 4
// NO_INCREMENT - Function will write data into the same register
unsigned char
-Wb35Reg_BurstWrite(phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag)
+Wb35Reg_BurstWrite(struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag)
{
struct wb35_reg *reg = &pHwData->reg;
struct urb *urb = NULL;
@@ -73,7 +73,7 @@ Wb35Reg_BurstWrite(phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterData, u8 N
}
void
-Wb35Reg_Update(phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue)
+Wb35Reg_Update(struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue)
{
struct wb35_reg *reg = &pHwData->reg;
switch (RegisterNo) {
@@ -118,7 +118,7 @@ Wb35Reg_Update(phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue)
// true : read command process successfully
// false : register not support
unsigned char
-Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
+Wb35Reg_WriteSync( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue )
{
struct wb35_reg *reg = &pHwData->reg;
int ret = -1;
@@ -149,7 +149,7 @@ Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
if (ret < 0) {
#ifdef _PE_REG_DUMP_
- WBDEBUG(("EP0 Write register usb message sending error\n"));
+ printk("EP0 Write register usb message sending error\n");
#endif
pHwData->SurpriseRemove = 1; // 20060704.2
@@ -162,7 +162,7 @@ Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
// true : read command process successfully
// false : register not support
unsigned char
-Wb35Reg_Write( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
+Wb35Reg_Write( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue )
{
struct wb35_reg *reg = &pHwData->reg;
struct usb_ctrlrequest *dr;
@@ -222,7 +222,7 @@ Wb35Reg_Write( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
// true : read command process successfully
// false : register not support
unsigned char
-Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue,
+Wb35Reg_WriteWithCallbackValue( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue,
s8 *pValue, s8 Len)
{
struct wb35_reg *reg = &pHwData->reg;
@@ -281,7 +281,7 @@ Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, u16 RegisterNo, u32 Register
// false : register not support
// pRegisterValue : It must be a resident buffer due to asynchronous read register.
unsigned char
-Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue )
+Wb35Reg_ReadSync( struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterValue )
{
struct wb35_reg *reg = &pHwData->reg;
u32 * pltmp = pRegisterValue;
@@ -316,7 +316,7 @@ Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue )
if (ret < 0) {
#ifdef _PE_REG_DUMP_
- WBDEBUG(("EP0 Read register usb message sending error\n"));
+ printk("EP0 Read register usb message sending error\n");
#endif
pHwData->SurpriseRemove = 1; // 20060704.2
@@ -330,7 +330,7 @@ Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue )
// false : register not support
// pRegisterValue : It must be a resident buffer due to asynchronous read register.
unsigned char
-Wb35Reg_Read(phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue )
+Wb35Reg_Read(struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterValue )
{
struct wb35_reg *reg = &pHwData->reg;
struct usb_ctrlrequest * dr;
@@ -385,7 +385,7 @@ Wb35Reg_Read(phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue )
void
-Wb35Reg_EP0VM_start( phw_data_t pHwData )
+Wb35Reg_EP0VM_start( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -397,7 +397,7 @@ Wb35Reg_EP0VM_start( phw_data_t pHwData )
}
void
-Wb35Reg_EP0VM(phw_data_t pHwData )
+Wb35Reg_EP0VM(struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
struct urb *urb;
@@ -441,7 +441,7 @@ Wb35Reg_EP0VM(phw_data_t pHwData )
if (ret < 0) {
#ifdef _PE_REG_DUMP_
- WBDEBUG(("EP0 Irp sending error\n"));
+ printk("EP0 Irp sending error\n");
#endif
goto cleanup;
}
@@ -457,7 +457,7 @@ Wb35Reg_EP0VM(phw_data_t pHwData )
void
Wb35Reg_EP0VM_complete(struct urb *urb)
{
- phw_data_t pHwData = (phw_data_t)urb->context;
+ struct hw_data * pHwData = (struct hw_data *)urb->context;
struct wb35_reg *reg = &pHwData->reg;
struct wb35_reg_queue *reg_queue;
@@ -480,8 +480,7 @@ Wb35Reg_EP0VM_complete(struct urb *urb)
if (reg->EP0VM_status) {
#ifdef _PE_REG_DUMP_
- WBDEBUG(("EP0 IoCompleteRoutine return error\n"));
- DebugUsbdStatusInformation( reg->EP0VM_status );
+ printk("EP0 IoCompleteRoutine return error\n");
#endif
reg->EP0vm_state = VM_STOP;
pHwData->SurpriseRemove = 1;
@@ -500,7 +499,7 @@ Wb35Reg_EP0VM_complete(struct urb *urb)
void
-Wb35Reg_destroy(phw_data_t pHwData)
+Wb35Reg_destroy(struct hw_data * pHwData)
{
struct wb35_reg *reg = &pHwData->reg;
struct urb *urb;
@@ -530,7 +529,7 @@ Wb35Reg_destroy(phw_data_t pHwData)
kfree(reg_queue);
} else {
#ifdef _PE_REG_DUMP_
- WBDEBUG(("EP0 queue release error\n"));
+ printk("EP0 queue release error\n");
#endif
}
spin_lock_irq( &reg->EP0VM_spin_lock );
@@ -543,7 +542,7 @@ Wb35Reg_destroy(phw_data_t pHwData)
//====================================================================================
// The function can be run in passive-level only.
//====================================================================================
-unsigned char Wb35Reg_initial(phw_data_t pHwData)
+unsigned char Wb35Reg_initial(struct hw_data * pHwData)
{
struct wb35_reg *reg=&pHwData->reg;
u32 ltmp;
@@ -599,7 +598,7 @@ unsigned char Wb35Reg_initial(phw_data_t pHwData)
Wb35Reg_ReadSync( pHwData, 0x03b4, &Region_ScanInterval );
// Update Ethernet address
- memcpy( pHwData->CurrentMacAddress, pHwData->PermanentMacAddress, ETH_LENGTH_OF_ADDRESS );
+ memcpy( pHwData->CurrentMacAddress, pHwData->PermanentMacAddress, ETH_ALEN );
// Update software variable
pHwData->SoftwareSet = (u16)(SoftwareSet & 0xffff);
@@ -723,7 +722,7 @@ u32 BitReverse( u32 dwData, u32 DataLength)
return dwData;
}
-void Wb35Reg_phy_calibration( phw_data_t pHwData )
+void Wb35Reg_phy_calibration( struct hw_data * pHwData )
{
u32 BB3c, BB54;
diff --git a/drivers/staging/winbond/wb35reg_f.h b/drivers/staging/winbond/wb35reg_f.h
index d97215a1eba..30f5b5ad63a 100644
--- a/drivers/staging/winbond/wb35reg_f.h
+++ b/drivers/staging/winbond/wb35reg_f.h
@@ -6,47 +6,47 @@
//====================================
// 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
+unsigned char Wb35Reg_initial( struct hw_data * pHwData );
+void Uxx_power_on_procedure( struct hw_data * pHwData );
+void Uxx_power_off_procedure( struct hw_data * pHwData );
+void Uxx_ReadEthernetAddress( struct hw_data * pHwData );
+void Dxx_initial( struct hw_data * pHwData );
+void Mxx_initial( struct hw_data * pHwData );
+void RFSynthesizer_initial( struct hw_data * pHwData );
+//void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, s8 Channel );
+void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, ChanInfo Channel );
+void BBProcessor_initial( struct hw_data * pHwData );
+void BBProcessor_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060613.1
+//void RF_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060626.5.c Add
+u8 RFSynthesizer_SetPowerIndex( struct hw_data * pHwData, u8 PowerIndex );
+u8 RFSynthesizer_SetMaxim2828_24Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetMaxim2828_50Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetMaxim2827_24Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetMaxim2827_50Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetMaxim2825Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetAiroha2230Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetAiroha7230Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetWinbond242Power( struct hw_data *, u8 index );
+void GetTxVgaFromEEPROM( struct hw_data * pHwData );
+void EEPROMTxVgaAdjust( struct hw_data * pHwData ); // 20060619.5 Add
#define RFWriteControlData( _A, _V ) Wb35Reg_Write( _A, 0x0864, _V )
-void Wb35Reg_destroy( phw_data_t pHwData );
+void Wb35Reg_destroy( struct hw_data * pHwData );
-unsigned char Wb35Reg_Read( phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue );
-unsigned char Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue );
-unsigned char Wb35Reg_Write( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue );
-unsigned char Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue );
-unsigned char Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData,
+unsigned char Wb35Reg_Read( struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterValue );
+unsigned char Wb35Reg_ReadSync( struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterValue );
+unsigned char Wb35Reg_Write( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue );
+unsigned char Wb35Reg_WriteSync( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue );
+unsigned char Wb35Reg_WriteWithCallbackValue( struct hw_data * pHwData,
u16 RegisterNo,
u32 RegisterValue,
s8 *pValue,
s8 Len);
-unsigned char Wb35Reg_BurstWrite( phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag );
+unsigned char Wb35Reg_BurstWrite( struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag );
-void Wb35Reg_EP0VM( phw_data_t pHwData );
-void Wb35Reg_EP0VM_start( phw_data_t pHwData );
+void Wb35Reg_EP0VM( struct hw_data * pHwData );
+void Wb35Reg_EP0VM_start( struct hw_data * pHwData );
void Wb35Reg_EP0VM_complete(struct urb *urb);
u32 BitReverse( u32 dwData, u32 DataLength);
@@ -54,8 +54,8 @@ u32 BitReverse( u32 dwData, u32 DataLength);
void CardGetMulticastBit( u8 Address[MAC_ADDR_LENGTH], u8 *Byte, u8 *Value );
u32 CardComputeCrc( u8 * Buffer, u32 Length );
-void Wb35Reg_phy_calibration( phw_data_t pHwData );
-void Wb35Reg_Update( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue );
-unsigned char adjust_TXVGA_for_iq_mag( phw_data_t pHwData );
+void Wb35Reg_phy_calibration( struct hw_data * pHwData );
+void Wb35Reg_Update( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue );
+unsigned char adjust_TXVGA_for_iq_mag( struct hw_data * pHwData );
#endif
diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c
index 7f8b6d749a4..3e8cf08b87e 100644
--- a/drivers/staging/winbond/wb35rx.c
+++ b/drivers/staging/winbond/wb35rx.c
@@ -82,9 +82,9 @@ static void Wb35Rx_adjust(PDESCRIPTOR pRxDes)
static u16 Wb35Rx_indicate(struct ieee80211_hw *hw)
{
struct wbsoft_priv *priv = hw->priv;
- phw_data_t pHwData = &priv->sHwData;
+ struct hw_data * pHwData = &priv->sHwData;
DESCRIPTOR RxDes;
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
u8 * pRxBufferAddress;
u16 PacketSize;
u16 stmp, BufferSize, stmp2 = 0;
@@ -118,7 +118,7 @@ static u16 Wb35Rx_indicate(struct ieee80211_hw *hw)
// 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));
+ printk("Serious ERROR : Rx data size too long, size =%d\n", PacketSize);
#endif
pWb35Rx->EP3vm_state = VM_STOP;
@@ -161,8 +161,8 @@ static void Wb35Rx_Complete(struct urb *urb)
{
struct ieee80211_hw *hw = urb->context;
struct wbsoft_priv *priv = hw->priv;
- phw_data_t pHwData = &priv->sHwData;
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct hw_data * pHwData = &priv->sHwData;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
u8 * pRxBufferAddress;
u32 SizeCheck;
u16 BulkLength;
@@ -194,8 +194,7 @@ static void Wb35Rx_Complete(struct urb *urb)
// 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 );
+ printk("EP3 IoCompleteRoutine return error\n");
#endif
pWb35Rx->EP3vm_state = VM_STOP;
goto error;
@@ -239,8 +238,8 @@ error:
static void Wb35Rx(struct ieee80211_hw *hw)
{
struct wbsoft_priv *priv = hw->priv;
- phw_data_t pHwData = &priv->sHwData;
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct hw_data * pHwData = &priv->sHwData;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
u8 * pRxBufferAddress;
struct urb *urb = pWb35Rx->RxUrb;
int retv;
@@ -260,7 +259,7 @@ static void Wb35Rx(struct ieee80211_hw *hw)
if (!pWb35Rx->RxOwner[RxBufferId]) {
// It's impossible to run here.
#ifdef _PE_RX_DUMP_
- WBDEBUG(("Rx driver fifo unavailable\n"));
+ printk("Rx driver fifo unavailable\n");
#endif
goto error;
}
@@ -302,8 +301,8 @@ error:
void Wb35Rx_start(struct ieee80211_hw *hw)
{
struct wbsoft_priv *priv = hw->priv;
- phw_data_t pHwData = &priv->sHwData;
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct hw_data * pHwData = &priv->sHwData;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
// Allow only one thread to run into the Wb35Rx() function
if (atomic_inc_return(&pWb35Rx->RxFireCounter) == 1) {
@@ -314,9 +313,9 @@ void Wb35Rx_start(struct ieee80211_hw *hw)
}
//=====================================================================================
-static void Wb35Rx_reset_descriptor( phw_data_t pHwData )
+static void Wb35Rx_reset_descriptor( struct hw_data * pHwData )
{
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
u32 i;
pWb35Rx->ByteReceived = 0;
@@ -330,9 +329,9 @@ static void Wb35Rx_reset_descriptor( phw_data_t pHwData )
pWb35Rx->RxOwner[i] = 1;
}
-unsigned char Wb35Rx_initial(phw_data_t pHwData)
+unsigned char Wb35Rx_initial(struct hw_data * pHwData)
{
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
// Initial the Buffer Queue
Wb35Rx_reset_descriptor( pHwData );
@@ -341,23 +340,23 @@ unsigned char Wb35Rx_initial(phw_data_t pHwData)
return (!!pWb35Rx->RxUrb);
}
-void Wb35Rx_stop(phw_data_t pHwData)
+void Wb35Rx_stop(struct hw_data * pHwData)
{
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct wb35_rx *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"));
+ printk("EP3 Rx stop\n");
#endif
}
}
// Needs process context
-void Wb35Rx_destroy(phw_data_t pHwData)
+void Wb35Rx_destroy(struct hw_data * pHwData)
{
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
do {
msleep(10); // Delay for waiting function enter 940623.1.a
@@ -367,7 +366,7 @@ void Wb35Rx_destroy(phw_data_t pHwData)
if (pWb35Rx->RxUrb)
usb_free_urb( pWb35Rx->RxUrb );
#ifdef _PE_RX_DUMP_
- WBDEBUG(("Wb35Rx_destroy OK\n"));
+ printk("Wb35Rx_destroy OK\n");
#endif
}
diff --git a/drivers/staging/winbond/wb35rx_f.h b/drivers/staging/winbond/wb35rx_f.h
index d993041e0cd..98acce517d9 100644
--- a/drivers/staging/winbond/wb35rx_f.h
+++ b/drivers/staging/winbond/wb35rx_f.h
@@ -7,9 +7,9 @@
//====================================
// Interface function declare
//====================================
-unsigned char Wb35Rx_initial( phw_data_t pHwData );
-void Wb35Rx_destroy( phw_data_t pHwData );
-void Wb35Rx_stop( phw_data_t pHwData );
+unsigned char Wb35Rx_initial( struct hw_data * pHwData );
+void Wb35Rx_destroy( struct hw_data * pHwData );
+void Wb35Rx_stop( struct hw_data * pHwData );
void Wb35Rx_start(struct ieee80211_hw *hw);
#endif
diff --git a/drivers/staging/winbond/wb35rx_s.h b/drivers/staging/winbond/wb35rx_s.h
index f18350b41c4..4b03274a7d2 100644
--- a/drivers/staging/winbond/wb35rx_s.h
+++ b/drivers/staging/winbond/wb35rx_s.h
@@ -15,8 +15,7 @@
//====================================
// Internal variable for module
//====================================
-typedef struct _WB35RX
-{
+struct wb35_rx {
u32 ByteReceived;// For calculating throughput of BulkIn
atomic_t RxFireCounter;// Does Wb35Rx module fire?
@@ -42,7 +41,4 @@ typedef struct _WB35RX
int EP3VM_status;
u8 * pDRx;
-
-} WB35RX, *PWB35RX;
-
-
+};
diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c
index b9b4456c808..1e4169d9a11 100644
--- a/drivers/staging/winbond/wb35tx.c
+++ b/drivers/staging/winbond/wb35tx.c
@@ -15,9 +15,9 @@
#include "sysdef.h"
unsigned char
-Wb35Tx_get_tx_buffer(phw_data_t pHwData, u8 **pBuffer)
+Wb35Tx_get_tx_buffer(struct hw_data * pHwData, u8 **pBuffer)
{
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
*pBuffer = pWb35Tx->TxBuffer[0];
return true;
@@ -28,8 +28,8 @@ static void Wb35Tx(struct wbsoft_priv *adapter);
static void Wb35Tx_complete(struct urb * pUrb)
{
struct wbsoft_priv *adapter = pUrb->context;
- phw_data_t pHwData = &adapter->sHwData;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct hw_data * pHwData = &adapter->sHwData;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
PMDS pMds = &adapter->Mds;
printk("wb35: tx complete\n");
@@ -64,8 +64,8 @@ error:
static void Wb35Tx(struct wbsoft_priv *adapter)
{
- phw_data_t pHwData = &adapter->sHwData;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct hw_data * pHwData = &adapter->sHwData;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
u8 *pTxBufferAddress;
PMDS pMds = &adapter->Mds;
struct urb * pUrb = (struct urb *)pWb35Tx->Tx4Urb;
@@ -115,8 +115,8 @@ static void Wb35Tx(struct wbsoft_priv *adapter)
void Wb35Tx_start(struct wbsoft_priv *adapter)
{
- phw_data_t pHwData = &adapter->sHwData;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct hw_data * pHwData = &adapter->sHwData;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
// Allow only one thread to run into function
if (atomic_inc_return(&pWb35Tx->TxFireCounter) == 1) {
@@ -126,9 +126,9 @@ void Wb35Tx_start(struct wbsoft_priv *adapter)
atomic_dec(&pWb35Tx->TxFireCounter);
}
-unsigned char Wb35Tx_initial(phw_data_t pHwData)
+unsigned char Wb35Tx_initial(struct hw_data * pHwData)
{
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
pWb35Tx->Tx4Urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!pWb35Tx->Tx4Urb)
@@ -145,29 +145,29 @@ unsigned char Wb35Tx_initial(phw_data_t pHwData)
}
//======================================================
-void Wb35Tx_stop(phw_data_t pHwData)
+void Wb35Tx_stop(struct hw_data * pHwData)
{
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct wb35_tx *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"));
+ printk("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"));
+ printk("EP4 Tx stop\n");
#endif
}
//======================================================
-void Wb35Tx_destroy(phw_data_t pHwData)
+void Wb35Tx_destroy(struct hw_data * pHwData)
{
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
// Wait for VM stop
do {
@@ -182,14 +182,14 @@ void Wb35Tx_destroy(phw_data_t pHwData)
usb_free_urb( pWb35Tx->Tx2Urb );
#ifdef _PE_TX_DUMP_
- WBDEBUG(("Wb35Tx_destroy OK\n"));
+ printk("Wb35Tx_destroy OK\n");
#endif
}
void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter, u32 TimeCount)
{
- phw_data_t pHwData = &adapter->sHwData;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct hw_data * pHwData = &adapter->sHwData;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
unsigned char Trigger = false;
if (pWb35Tx->TxTimer > TimeCount)
@@ -208,9 +208,9 @@ static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter);
static void Wb35Tx_EP2VM_complete(struct urb * pUrb)
{
struct wbsoft_priv *adapter = pUrb->context;
- phw_data_t pHwData = &adapter->sHwData;
+ struct hw_data * pHwData = &adapter->sHwData;
T02_DESCRIPTOR T02, TSTATUS;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
u32 * pltmp = (u32 *)pWb35Tx->EP2_buf;
u32 i;
u16 InterruptInLength;
@@ -229,7 +229,7 @@ static void Wb35Tx_EP2VM_complete(struct urb * pUrb)
//The Urb is completed, check the result
if (pWb35Tx->EP2VM_status != 0) {
- WBDEBUG(("EP2 IoCompleteRoutine return error\n"));
+ printk("EP2 IoCompleteRoutine return error\n");
pWb35Tx->EP2vm_state= VM_STOP;
goto error;
}
@@ -256,8 +256,8 @@ error:
static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter)
{
- phw_data_t pHwData = &adapter->sHwData;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct hw_data * pHwData = &adapter->sHwData;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
struct urb * pUrb = (struct urb *)pWb35Tx->Tx2Urb;
u32 * pltmp = (u32 *)pWb35Tx->EP2_buf;
int retv;
@@ -279,7 +279,7 @@ static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter)
if (retv < 0) {
#ifdef _PE_TX_DUMP_
- WBDEBUG(("EP2 Tx Irp sending error\n"));
+ printk("EP2 Tx Irp sending error\n");
#endif
goto error;
}
@@ -292,8 +292,8 @@ error:
void Wb35Tx_EP2VM_start(struct wbsoft_priv *adapter)
{
- phw_data_t pHwData = &adapter->sHwData;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct hw_data * pHwData = &adapter->sHwData;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
// Allow only one thread to run into function
if (atomic_inc_return(&pWb35Tx->TxResultCount) == 1) {
diff --git a/drivers/staging/winbond/wb35tx_f.h b/drivers/staging/winbond/wb35tx_f.h
index 4222fa80c7b..a7af9cbe202 100644
--- a/drivers/staging/winbond/wb35tx_f.h
+++ b/drivers/staging/winbond/wb35tx_f.h
@@ -7,14 +7,14 @@
//====================================
// 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, u8 **pBuffer );
+unsigned char Wb35Tx_initial( struct hw_data * pHwData );
+void Wb35Tx_destroy( struct hw_data * pHwData );
+unsigned char Wb35Tx_get_tx_buffer( struct hw_data * pHwData, u8 **pBuffer );
void Wb35Tx_EP2VM_start(struct wbsoft_priv *adapter);
void Wb35Tx_start(struct wbsoft_priv *adapter);
-void Wb35Tx_stop( phw_data_t pHwData );
+void Wb35Tx_stop( struct hw_data * pHwData );
void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter, u32 TimeCount);
diff --git a/drivers/staging/winbond/wb35tx_s.h b/drivers/staging/winbond/wb35tx_s.h
index 3960276cae6..f70f4339559 100644
--- a/drivers/staging/winbond/wb35tx_s.h
+++ b/drivers/staging/winbond/wb35tx_s.h
@@ -18,8 +18,7 @@
//====================================
-typedef struct _WB35TX
-{
+struct wb35_tx {
// For Tx buffer
u8 TxBuffer[ MAX_USB_TX_BUFFER_NUMBER ][ MAX_USB_TX_BUFFER ];
@@ -43,7 +42,6 @@ typedef struct _WB35TX
u32 TxFillCount; // 20060928
u32 TxTimer; // 20060928 Add if sending packet not great than 13
-
-} WB35TX, *PWB35TX;
+};
#endif
diff --git a/drivers/staging/winbond/wbhal.c b/drivers/staging/winbond/wbhal.c
index 8a9d21cbb0c..c985ad06523 100644
--- a/drivers/staging/winbond/wbhal.c
+++ b/drivers/staging/winbond/wbhal.c
@@ -1,14 +1,14 @@
-#include "os_common.h"
+#include "sysdef.h"
#include "wbhal_f.h"
#include "wblinux_f.h"
-void hal_set_ethernet_address( phw_data_t pHwData, u8 *current_address )
+void hal_set_ethernet_address( struct hw_data * pHwData, u8 *current_address )
{
u32 ltmp[2];
if( pHwData->SurpriseRemove ) return;
- memcpy( pHwData->CurrentMacAddress, current_address, ETH_LENGTH_OF_ADDRESS );
+ memcpy( pHwData->CurrentMacAddress, current_address, ETH_ALEN );
ltmp[0]= cpu_to_le32( *(u32 *)pHwData->CurrentMacAddress );
ltmp[1]= cpu_to_le32( *(u32 *)(pHwData->CurrentMacAddress + 4) ) & 0xffff;
@@ -16,7 +16,7 @@ void hal_set_ethernet_address( phw_data_t pHwData, u8 *current_address )
Wb35Reg_BurstWrite( pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT );
}
-void hal_get_permanent_address( phw_data_t pHwData, u8 *pethernet_address )
+void hal_get_permanent_address( struct hw_data * pHwData, u8 *pethernet_address )
{
if( pHwData->SurpriseRemove ) return;
@@ -26,7 +26,7 @@ void hal_get_permanent_address( phw_data_t pHwData, u8 *pethernet_address )
static void hal_led_control(unsigned long data)
{
struct wbsoft_priv *adapter = (struct wbsoft_priv *) data;
- phw_data_t pHwData = &adapter->sHwData;
+ struct hw_data * pHwData = &adapter->sHwData;
struct wb35_reg *reg = &pHwData->reg;
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 };
@@ -311,7 +311,7 @@ static void hal_led_control(unsigned long data)
u8 hal_init_hardware(struct ieee80211_hw *hw)
{
struct wbsoft_priv *priv = hw->priv;
- phw_data_t pHwData = &priv->sHwData;
+ struct hw_data * pHwData = &priv->sHwData;
u16 SoftwareSet;
// Initial the variable
@@ -356,7 +356,7 @@ u8 hal_init_hardware(struct ieee80211_hw *hw)
}
-void hal_halt(phw_data_t pHwData, void *ppa_data)
+void hal_halt(struct hw_data * pHwData, void *ppa_data)
{
switch( pHwData->InitialResource )
{
@@ -370,7 +370,7 @@ void hal_halt(phw_data_t pHwData, void *ppa_data)
}
//---------------------------------------------------------------------------------------------------
-void hal_set_beacon_period( phw_data_t pHwData, u16 beacon_period )
+void hal_set_beacon_period( struct hw_data * pHwData, u16 beacon_period )
{
u32 tmp;
@@ -383,7 +383,7 @@ void hal_set_beacon_period( phw_data_t pHwData, u16 beacon_period )
}
-static void hal_set_current_channel_ex( phw_data_t pHwData, ChanInfo channel )
+static void hal_set_current_channel_ex( struct hw_data * pHwData, ChanInfo channel )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -396,7 +396,7 @@ static void hal_set_current_channel_ex( phw_data_t pHwData, ChanInfo 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));
+ printk("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band);
#endif
reg->M28_MacControl &= ~0xff; // Clean channel information field
reg->M28_MacControl |= channel.ChanNo;
@@ -404,12 +404,12 @@ static void hal_set_current_channel_ex( phw_data_t pHwData, ChanInfo channel )
(s8 *)&channel, sizeof(ChanInfo));
}
//---------------------------------------------------------------------------------------------------
-void hal_set_current_channel( phw_data_t pHwData, ChanInfo channel )
+void hal_set_current_channel( struct hw_data * pHwData, ChanInfo channel )
{
hal_set_current_channel_ex( pHwData, channel );
}
//---------------------------------------------------------------------------------------------------
-void hal_set_accept_broadcast( phw_data_t pHwData, u8 enable )
+void hal_set_accept_broadcast( struct hw_data * pHwData, u8 enable )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -424,7 +424,7 @@ void hal_set_accept_broadcast( phw_data_t pHwData, u8 enable )
}
//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)
+void hal_set_accept_promiscuous( struct hw_data * pHwData, u8 enable)
{
struct wb35_reg *reg = &pHwData->reg;
@@ -438,7 +438,7 @@ void hal_set_accept_promiscuous( phw_data_t pHwData, u8 enable)
}
}
-void hal_set_accept_multicast( phw_data_t pHwData, u8 enable )
+void hal_set_accept_multicast( struct hw_data * pHwData, u8 enable )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -449,7 +449,7 @@ void hal_set_accept_multicast( phw_data_t pHwData, u8 enable )
Wb35Reg_Write( pHwData, 0x0800, reg->M00_MacControl );
}
-void hal_set_accept_beacon( phw_data_t pHwData, u8 enable )
+void hal_set_accept_beacon( struct hw_data * pHwData, u8 enable )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -467,7 +467,7 @@ void hal_set_accept_beacon( phw_data_t pHwData, u8 enable )
}
//---------------------------------------------------------------------------------------------------
-void hal_stop( phw_data_t pHwData )
+void hal_stop( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -481,10 +481,10 @@ void hal_stop( phw_data_t pHwData )
Wb35Reg_Write( pHwData, 0x0400, reg->D00_DmaControl );
}
-unsigned char hal_idle(phw_data_t pHwData)
+unsigned char hal_idle(struct hw_data * pHwData)
{
struct wb35_reg *reg = &pHwData->reg;
- PWBUSB pWbUsb = &pHwData->WbUsb;
+ struct wb_usb *pWbUsb = &pHwData->WbUsb;
if( !pHwData->SurpriseRemove && ( pWbUsb->DetectCount || reg->EP0vm_state!=VM_STOP ) )
return false;
@@ -492,12 +492,12 @@ unsigned char hal_idle(phw_data_t pHwData)
return true;
}
//---------------------------------------------------------------------------------------------------
-void hal_set_phy_type( phw_data_t pHwData, u8 PhyType )
+void hal_set_phy_type( struct hw_data * pHwData, u8 PhyType )
{
pHwData->phy_type = PhyType;
}
-void hal_set_radio_mode( phw_data_t pHwData, unsigned char radio_off)
+void hal_set_radio_mode( struct hw_data * pHwData, unsigned char radio_off)
{
struct wb35_reg *reg = &pHwData->reg;
@@ -516,7 +516,7 @@ void hal_set_radio_mode( phw_data_t pHwData, unsigned char radio_off)
Wb35Reg_Write( pHwData, 0x0824, reg->M24_MacControl );
}
-u8 hal_get_antenna_number( phw_data_t pHwData )
+u8 hal_get_antenna_number( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -528,7 +528,7 @@ u8 hal_get_antenna_number( phw_data_t pHwData )
//----------------------------------------------------------------------------------------------------
//0 : radio on; 1: radio off
-u8 hal_get_hw_radio_off( phw_data_t pHwData )
+u8 hal_get_hw_radio_off( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -545,14 +545,14 @@ u8 hal_get_hw_radio_off( phw_data_t pHwData )
}
}
-unsigned char hal_get_dxx_reg( phw_data_t pHwData, u16 number, u32 * pValue )
+unsigned char hal_get_dxx_reg( struct hw_data * pHwData, u16 number, u32 * 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 hal_set_dxx_reg( struct hw_data * pHwData, u16 number, u32 value )
{
unsigned char ret;
@@ -562,7 +562,7 @@ unsigned char hal_set_dxx_reg( phw_data_t pHwData, u16 number, u32 value )
return ret;
}
-void hal_set_rf_power(phw_data_t pHwData, u8 PowerIndex)
+void hal_set_rf_power(struct hw_data * pHwData, u8 PowerIndex)
{
RFSynthesizer_SetPowerIndex( pHwData, PowerIndex );
}
diff --git a/drivers/staging/winbond/wbhal_f.h b/drivers/staging/winbond/wbhal_f.h
index e805f40f635..efcaefb6aa5 100644
--- a/drivers/staging/winbond/wbhal_f.h
+++ b/drivers/staging/winbond/wbhal_f.h
@@ -10,56 +10,56 @@
//====================================================================================
// Function declaration
//====================================================================================
-void hal_remove_mapping_key( phw_data_t pHwData, u8 *pmac_addr );
-void hal_remove_default_key( phw_data_t pHwData, u32 index );
-unsigned char hal_set_mapping_key( phw_data_t adapter, u8 *pmac_addr, u8 null_key, u8 wep_on, u8 *ptx_tsc, u8 *prx_tsc, u8 key_type, u8 key_len, u8 *pkey_data );
-unsigned char hal_set_default_key( phw_data_t adapter, u8 index, u8 null_key, u8 wep_on, u8 *ptx_tsc, u8 *prx_tsc, u8 key_type, u8 key_len, u8 *pkey_data );
-void hal_clear_all_default_key( phw_data_t pHwData );
-void hal_clear_all_group_key( phw_data_t pHwData );
-void hal_clear_all_mapping_key( phw_data_t pHwData );
-void hal_clear_all_key( phw_data_t pHwData );
-void hal_get_ethernet_address( phw_data_t pHwData, u8 *current_address );
-void hal_set_ethernet_address( phw_data_t pHwData, u8 *current_address );
-void hal_get_permanent_address( phw_data_t pHwData, u8 *pethernet_address );
+void hal_remove_mapping_key( struct hw_data * pHwData, u8 *pmac_addr );
+void hal_remove_default_key( struct hw_data * pHwData, u32 index );
+unsigned char hal_set_mapping_key( struct hw_data * adapter, u8 *pmac_addr, u8 null_key, u8 wep_on, u8 *ptx_tsc, u8 *prx_tsc, u8 key_type, u8 key_len, u8 *pkey_data );
+unsigned char hal_set_default_key( struct hw_data * adapter, u8 index, u8 null_key, u8 wep_on, u8 *ptx_tsc, u8 *prx_tsc, u8 key_type, u8 key_len, u8 *pkey_data );
+void hal_clear_all_default_key( struct hw_data * pHwData );
+void hal_clear_all_group_key( struct hw_data * pHwData );
+void hal_clear_all_mapping_key( struct hw_data * pHwData );
+void hal_clear_all_key( struct hw_data * pHwData );
+void hal_get_ethernet_address( struct hw_data * pHwData, u8 *current_address );
+void hal_set_ethernet_address( struct hw_data * pHwData, u8 *current_address );
+void hal_get_permanent_address( struct hw_data * pHwData, u8 *pethernet_address );
u8 hal_init_hardware(struct ieee80211_hw *hw);
-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, u8 *pin_pwr_save );
-void hal_set_slot_time( phw_data_t pHwData, u8 type );
+void hal_set_power_save_mode( struct hw_data * pHwData, unsigned char power_save, unsigned char wakeup, unsigned char dtim );
+void hal_get_power_save_mode( struct hw_data * pHwData, u8 *pin_pwr_save );
+void hal_set_slot_time( struct hw_data * pHwData, u8 type );
#define hal_set_atim_window( _A, _ATM )
-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, u8 *pbssid );
-void hal_get_bssid( phw_data_t pHwData, u8 *pbssid );
-void hal_set_beacon_period( phw_data_t pHwData, u16 beacon_period );
-void hal_set_listen_interval( phw_data_t pHwData, u16 listen_interval );
-void hal_set_cap_info( phw_data_t pHwData, u16 capability_info );
-void hal_set_ssid( phw_data_t pHwData, u8 *pssid, u8 ssid_len );
-void hal_set_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_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_start_bss( struct hw_data * pHwData, u8 mac_op_mode );
+void hal_join_request( struct hw_data * pHwData, u8 bss_type ); // 0:BSS STA 1:IBSS STA//
+void hal_stop_sync_bss( struct hw_data * pHwData );
+void hal_resume_sync_bss( struct hw_data * pHwData);
+void hal_set_aid( struct hw_data * pHwData, u16 aid );
+void hal_set_bssid( struct hw_data * pHwData, u8 *pbssid );
+void hal_get_bssid( struct hw_data * pHwData, u8 *pbssid );
+void hal_set_beacon_period( struct hw_data * pHwData, u16 beacon_period );
+void hal_set_listen_interval( struct hw_data * pHwData, u16 listen_interval );
+void hal_set_cap_info( struct hw_data * pHwData, u16 capability_info );
+void hal_set_ssid( struct hw_data * pHwData, u8 *pssid, u8 ssid_len );
+void hal_set_current_channel( struct hw_data * pHwData, ChanInfo channel );
+void hal_set_accept_broadcast( struct hw_data * pHwData, u8 enable );
+void hal_set_accept_multicast( struct hw_data * pHwData, u8 enable );
+void hal_set_accept_beacon( struct hw_data * pHwData, u8 enable );
+void hal_stop( struct hw_data * pHwData );
+void hal_halt( struct hw_data * pHwData, void *ppa_data );
+void hal_start_tx0( struct hw_data * pHwData );
+void hal_set_phy_type( struct hw_data * pHwData, u8 PhyType );
#define hal_get_cwmin( _A ) ( (_A)->cwmin )
-void hal_set_cwmax( phw_data_t pHwData, u16 cwin_max );
+void hal_set_cwmax( struct hw_data * 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);
-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_set_rf_power( phw_data_t pHwData, u8 PowerIndex ); // 20060621 Modify
-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 );
-u32 hal_get_bss_pk_cnt( phw_data_t pHwData );
+void hal_set_rsn_wpa( struct hw_data * pHwData, u32 * RSN_IE_Bitmap , u32 * RSN_OUI_type , unsigned char bDesiredAuthMode);
+void hal_set_connect_info( struct hw_data * pHwData, unsigned char boConnect );
+u8 hal_get_est_sq3( struct hw_data * pHwData, u8 Count );
+void hal_set_rf_power( struct hw_data * pHwData, u8 PowerIndex ); // 20060621 Modify
+void hal_set_radio_mode( struct hw_data * pHwData, unsigned char boValue);
+void hal_descriptor_indicate( struct hw_data * pHwData, PDESCRIPTOR pDes );
+u8 hal_get_antenna_number( struct hw_data * pHwData );
+u32 hal_get_bss_pk_cnt( struct hw_data * pHwData );
#define hal_get_region_from_EEPROM( _A ) ( (_A)->reg.EEPROMRegion )
-void hal_set_accept_promiscuous ( phw_data_t pHwData, u8 enable);
+void hal_set_accept_promiscuous ( struct hw_data * 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 );
+u8 hal_get_hw_radio_off ( struct hw_data * 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)
@@ -68,8 +68,8 @@ u8 hal_get_hw_radio_off ( phw_data_t pHwData );
#define PHY_DEBUG( msg, args... )
-unsigned char hal_get_dxx_reg( phw_data_t pHwData, u16 number, u32 * pValue );
-unsigned char hal_set_dxx_reg( phw_data_t pHwData, u16 number, u32 value );
+unsigned char hal_get_dxx_reg( struct hw_data * pHwData, u16 number, u32 * pValue );
+unsigned char hal_set_dxx_reg( struct hw_data * 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)
@@ -82,7 +82,7 @@ unsigned char hal_set_dxx_reg( phw_data_t pHwData, u16 number, u32 value );
#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 );
+unsigned char hal_idle( struct hw_data * pHwData );
#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, (u32 *)_C )
diff --git a/drivers/staging/winbond/wbhal_s.h b/drivers/staging/winbond/wbhal_s.h
index 276d2b12632..acfebf05d9d 100644
--- a/drivers/staging/winbond/wbhal_s.h
+++ b/drivers/staging/winbond/wbhal_s.h
@@ -2,8 +2,7 @@
#define __WINBOND_WBHAL_S_H
#include <linux/types.h>
-
-#include "common.h"
+#include <linux/if_ether.h> /* for ETH_ALEN */
//[20040722 WK]
#define HAL_LED_SET_MASK 0x001c //20060901 Extend
@@ -86,19 +85,6 @@ enum {
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
//-----------------------------------------------------
@@ -106,28 +92,6 @@ typedef struct _MAC_FRAME_CONTROL {
#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
@@ -413,8 +377,8 @@ typedef struct _DESCRIPTOR { // Skip length = 8 DWORD
#define MAX_RF_PARAMETER 32
typedef struct _TXVGA_FOR_50 {
- u8 ChanNo;
- u8 TxVgaValue;
+ u8 ChanNo;
+ u8 TxVgaValue;
} TXVGA_FOR_50;
@@ -427,10 +391,8 @@ typedef struct _TXVGA_FOR_50 {
#include "wb35tx_s.h"
#include "wb35rx_s.h"
-
// For Hal using ==================================================================
-typedef struct _HW_DATA_T
-{
+struct hw_data {
// For compatible with 33
u32 revision;
u32 BB3c_cal; // The value for Tx calibration comes from EEPROM
@@ -452,8 +414,8 @@ typedef struct _HW_DATA_T
//===============================================
// 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
+ u8 PermanentMacAddress[ETH_ALEN + 2]; // The Enthernet addr that are stored in EEPROM. + 2 to 8-byte alignment
+ u8 CurrentMacAddress[ETH_ALEN + 2]; // The Enthernet addr that are in used. + 2 to 8-byte alignment
//=====================================================================
// Definition for 802.11
@@ -502,10 +464,10 @@ typedef struct _HW_DATA_T
//========================================================================
// Variable for each module
//========================================================================
- WBUSB WbUsb; // Need WbUsb.h
+ struct wb_usb WbUsb; // Need WbUsb.h
struct wb35_reg reg; // Need Wb35Reg.h
- WB35TX Wb35Tx; // Need Wb35Tx.h
- WB35RX Wb35Rx; // Need Wb35Rx.h
+ struct wb35_tx Wb35Tx; // Need Wb35Tx.h
+ struct wb35_rx Wb35Rx; // Need Wb35Rx.h
struct timer_list LEDTimer;// For LED
@@ -578,35 +540,6 @@ typedef struct _HW_DATA_T
// 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;
+};
#endif
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c
index f716b2e92b6..9c3f9439f35 100644
--- a/drivers/staging/winbond/wbusb.c
+++ b/drivers/staging/winbond/wbusb.c
@@ -9,7 +9,7 @@
#include "core.h"
#include "mds_f.h"
#include "mlmetxrx_f.h"
-#include "mto_f.h"
+#include "mto.h"
#include "wbhal_f.h"
#include "wblinux_f.h"
@@ -149,19 +149,19 @@ static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
hal_set_current_channel(&priv->sHwData, ch);
hal_set_beacon_period(&priv->sHwData, conf->beacon_int);
// hal_set_cap_info(&priv->sHwData, ?? );
-// hal_set_ssid(phw_data_t pHwData, u8 * pssid, u8 ssid_len); ??
+// hal_set_ssid(struct hw_data * pHwData, u8 * pssid, u8 ssid_len); ??
hal_set_accept_broadcast(&priv->sHwData, 1);
hal_set_accept_promiscuous(&priv->sHwData, 1);
hal_set_accept_multicast(&priv->sHwData, 1);
hal_set_accept_beacon(&priv->sHwData, 1);
hal_set_radio_mode(&priv->sHwData, 0);
- //hal_set_antenna_number( phw_data_t pHwData, u8 number )
- //hal_set_rf_power(phw_data_t pHwData, u8 PowerIndex)
+ //hal_set_antenna_number( struct hw_data * pHwData, u8 number )
+ //hal_set_rf_power(struct hw_data * pHwData, u8 PowerIndex)
// hal_start_bss(&priv->sHwData, WLAN_BSSTYPE_INFRASTRUCTURE); ??
-//void hal_set_rates(phw_data_t pHwData, u8 * pbss_rates,
+//void hal_set_rates(struct hw_data * pHwData, u8 * pbss_rates,
// u8 length, unsigned char basic_rate_set)
return 0;
@@ -199,7 +199,7 @@ static const struct ieee80211_ops wbsoft_ops = {
static unsigned char wb35_hw_init(struct ieee80211_hw *hw)
{
struct wbsoft_priv *priv = hw->priv;
- phw_data_t pHwData;
+ struct hw_data * pHwData;
u8 *pMacAddr;
u8 *pMacAddr2;
u32 InitStep = 0;
@@ -277,7 +277,7 @@ static unsigned char wb35_hw_init(struct ieee80211_hw *hw)
//get current antenna
priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData);
#ifdef _PE_STATE_DUMP_
- WBDEBUG(("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo));
+ printk("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo);
#endif
hal_get_hw_radio_off( pHwData );
@@ -312,7 +312,7 @@ error:
static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id_table)
{
- PWBUSB pWbUsb;
+ struct wb_usb *pWbUsb;
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
u32 ltmp;
@@ -366,7 +366,7 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id
SET_IEEE80211_DEV(dev, &udev->dev);
{
- phw_data_t pHwData = &priv->sHwData;
+ struct hw_data * pHwData = &priv->sHwData;
unsigned char dev_addr[MAX_ADDR_LEN];
hal_get_permanent_address(pHwData, dev_addr);
SET_IEEE80211_PERM_ADDR(dev, dev_addr);
@@ -404,7 +404,7 @@ static void wb35_hw_halt(struct wbsoft_priv *adapter)
// Turn off Rx and Tx hardware ability
hal_stop( &adapter->sHwData );
#ifdef _PE_USB_INI_DUMP_
- WBDEBUG(("[w35und] Hal_stop O.K.\n"));
+ printk("[w35und] Hal_stop O.K.\n");
#endif
msleep(100);// Waiting Irp completed
diff --git a/drivers/staging/winbond/wbusb_s.h b/drivers/staging/winbond/wbusb_s.h
index 1de93600d84..0c7e6a383f2 100644
--- a/drivers/staging/winbond/wbusb_s.h
+++ b/drivers/staging/winbond/wbusb_s.h
@@ -16,22 +16,10 @@
#include <linux/types.h>
-//---------------------------------------------------------------------------
-// RW_CONTEXT --
-//
-// Used to track driver-generated io irps
-//---------------------------------------------------------------------------
-typedef struct _RW_CONTEXT
-{
- void* pHwData;
- struct urb *urb;
- void* pCallBackFunctionParameter;
-} RW_CONTEXT, *PRW_CONTEXT;
-
-typedef struct _WBUSB {
+struct wb_usb {
u32 IsUsb20;
struct usb_device *udev;
u32 DetectCount;
-} WBUSB, *PWBUSB;
+};
#endif
diff --git a/drivers/staging/wlan-ng/README b/drivers/staging/wlan-ng/README
index 9c10dbb000d..028c299b613 100644
--- a/drivers/staging/wlan-ng/README
+++ b/drivers/staging/wlan-ng/README
@@ -4,4 +4,6 @@ TODO:
- Lindent cleanups
- move to use the in-kernel wireless stack
-Please send all patches to Greg Kroah-Hartman <greg@kroah.com>
+Please send any patches or complaints about this driver to Greg
+Kroah-Hartman <greg@kroah.com> and don't bother the upstream wireless
+kernel developers about it, they want nothing to do with it.
diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h
index 9b746654a39..f3e87173471 100644
--- a/drivers/staging/wlan-ng/hfa384x.h
+++ b/drivers/staging/wlan-ng/hfa384x.h
@@ -56,75 +56,37 @@
#ifndef _HFA384x_H
#define _HFA384x_H
-/*=============================================================*/
-#define HFA384x_FIRMWARE_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#define HFA384x_FIRMWARE_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-#define HFA384x_LEVEL_TO_dBm(v) (0x100 + (v) * 100 / 255 - 100)
+#include <linux/if_ether.h>
-/*------ Constants --------------------------------------------*/
/*--- Mins & Maxs -----------------------------------*/
-#define HFA384x_CMD_ALLOC_LEN_MIN ((u16)4)
-#define HFA384x_CMD_ALLOC_LEN_MAX ((u16)2400)
-#define HFA384x_BAP_DATALEN_MAX ((u16)4096)
-#define HFA384x_BAP_OFFSET_MAX ((u16)4096)
#define HFA384x_PORTID_MAX ((u16)7)
#define HFA384x_NUMPORTS_MAX ((u16)(HFA384x_PORTID_MAX+1))
-#define HFA384x_PDR_LEN_MAX ((u16)512) /* in bytes, from EK */
-#define HFA384x_PDA_RECS_MAX ((u16)200) /* a guess */
-#define HFA384x_PDA_LEN_MAX ((u16)1024) /* in bytes, from EK */
+#define HFA384x_PDR_LEN_MAX ((u16)512) /* in bytes, from EK */
+#define HFA384x_PDA_LEN_MAX ((u16)1024) /* in bytes, from EK */
#define HFA384x_SCANRESULT_MAX ((u16)31)
#define HFA384x_HSCANRESULT_MAX ((u16)31)
#define HFA384x_CHINFORESULT_MAX ((u16)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_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 ((u16)0)
-#define HFA384x_BAP_int ((u16)1)
#define HFA384x_PORTTYPE_IBSS ((u16)0)
#define HFA384x_PORTTYPE_BSS ((u16)1)
-#define HFA384x_PORTTYPE_WDS ((u16)2)
#define HFA384x_PORTTYPE_PSUEDOIBSS ((u16)3)
-#define HFA384x_PORTTYPE_HOSTAP ((u16)6)
-#define HFA384x_WEPFLAGS_PRIVINVOKED ((u16)BIT0)
-#define HFA384x_WEPFLAGS_EXCLUDE ((u16)BIT1)
-#define HFA384x_WEPFLAGS_DISABLE_TXCRYPT ((u16)BIT4)
-#define HFA384x_WEPFLAGS_DISABLE_RXCRYPT ((u16)BIT7)
-#define HFA384x_WEPFLAGS_DISALLOW_MIXED ((u16)BIT11)
-#define HFA384x_WEPFLAGS_IV_intERVAL1 ((u16)0)
-#define HFA384x_WEPFLAGS_IV_intERVAL10 ((u16)BIT5)
-#define HFA384x_WEPFLAGS_IV_intERVAL50 ((u16)BIT6)
-#define HFA384x_WEPFLAGS_IV_intERVAL100 ((u16)(BIT5 | BIT6))
-#define HFA384x_WEPFLAGS_FIRMWARE_WPA ((u16)BIT8)
-#define HFA384x_WEPFLAGS_HOST_MIC ((u16)BIT9)
-#define HFA384x_ROAMMODE_FWSCAN_FWROAM ((u16)1)
-#define HFA384x_ROAMMODE_FWSCAN_HOSTROAM ((u16)2)
+#define HFA384x_WEPFLAGS_PRIVINVOKED ((u16)BIT(0))
+#define HFA384x_WEPFLAGS_EXCLUDE ((u16)BIT(1))
+#define HFA384x_WEPFLAGS_DISABLE_TXCRYPT ((u16)BIT(4))
+#define HFA384x_WEPFLAGS_DISABLE_RXCRYPT ((u16)BIT(7))
#define HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM ((u16)3)
#define HFA384x_PORTSTATUS_DISABLED ((u16)1)
-#define HFA384x_PORTSTATUS_INITSRCH ((u16)2)
-#define HFA384x_PORTSTATUS_CONN_IBSS ((u16)3)
-#define HFA384x_PORTSTATUS_CONN_ESS ((u16)4)
-#define HFA384x_PORTSTATUS_OOR_ESS ((u16)5)
-#define HFA384x_PORTSTATUS_CONN_WDS ((u16)6)
-#define HFA384x_PORTSTATUS_HOSTAP ((u16)8)
#define HFA384x_RATEBIT_1 ((u16)1)
#define HFA384x_RATEBIT_2 ((u16)2)
#define HFA384x_RATEBIT_5dot5 ((u16)4)
#define HFA384x_RATEBIT_11 ((u16)8)
-/*--- Just some symbolic names for legibility -------*/
-#define HFA384x_TXCMD_NORECL ((u16)0)
-#define HFA384x_TXCMD_RECL ((u16)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
@@ -139,59 +101,28 @@
* macros below help handle some of this.
*/
-/* Handy constant */
-#define HFA384x_ADDR_AUX_OFF_MAX ((u16)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 */
+/* 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) \
- (((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) <<7) | \
+#define HFA384x_ADDR_AUX_MKFLAT(p, o) \
+ (((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \
((u32)(((u16)(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) \
- (((u32)(((u16)(p))&HFA384x_ADDR_CMD_PAGE_MASK)) <<16) | \
- ((u32)(((u16)(o))&HFA384x_ADDR_CMD_OFF_MASK))
-
-/* Make AUX format offset and page from a 32-bit flat address */
-#define HFA384x_ADDR_AUX_MKPAGE(f) \
- ((u16)((((u32)(f))&HFA384x_ADDR_FLAT_AUX_PAGE_MASK)>>7))
-#define HFA384x_ADDR_AUX_MKOFF(f) \
- ((u16)(((u32)(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) \
((u16)((((u32)(f))&HFA384x_ADDR_FLAT_CMD_PAGE_MASK)>>16))
#define HFA384x_ADDR_CMD_MKOFF(f) \
((u16)(((u32)(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) | (((u16)(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)
@@ -201,124 +132,25 @@
#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
-
-#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)
/*--- Register Field Masks --------------------------*/
-#define HFA384x_CMD_BUSY ((u16)BIT15)
-#define HFA384x_CMD_AINFO ((u16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8))
-#define HFA384x_CMD_MACPORT ((u16)(BIT10 | BIT9 | BIT8))
-#define HFA384x_CMD_RECL ((u16)BIT8)
-#define HFA384x_CMD_WRITE ((u16)BIT8)
-#define HFA384x_CMD_PROGMODE ((u16)(BIT9 | BIT8))
-#define HFA384x_CMD_CMDCODE ((u16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0))
-
-#define HFA384x_STATUS_RESULT ((u16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8))
-#define HFA384x_STATUS_CMDCODE ((u16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0))
-
-#define HFA384x_OFFSET_BUSY ((u16)BIT15)
-#define HFA384x_OFFSET_ERR ((u16)BIT14)
-#define HFA384x_OFFSET_DATAOFF ((u16)(BIT11 | BIT10 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1))
-
-#define HFA384x_EVSTAT_TICK ((u16)BIT15)
-#define HFA384x_EVSTAT_WTERR ((u16)BIT14)
-#define HFA384x_EVSTAT_INFDROP ((u16)BIT13)
-#define HFA384x_EVSTAT_INFO ((u16)BIT7)
-#define HFA384x_EVSTAT_DTIM ((u16)BIT5)
-#define HFA384x_EVSTAT_CMD ((u16)BIT4)
-#define HFA384x_EVSTAT_ALLOC ((u16)BIT3)
-#define HFA384x_EVSTAT_TXEXC ((u16)BIT2)
-#define HFA384x_EVSTAT_TX ((u16)BIT1)
-#define HFA384x_EVSTAT_RX ((u16)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 ((u16)BIT15)
-#define HFA384x_intEN_WTERR ((u16)BIT14)
-#define HFA384x_intEN_INFDROP ((u16)BIT13)
-#define HFA384x_intEN_INFO ((u16)BIT7)
-#define HFA384x_intEN_DTIM ((u16)BIT5)
-#define HFA384x_intEN_CMD ((u16)BIT4)
-#define HFA384x_intEN_ALLOC ((u16)BIT3)
-#define HFA384x_intEN_TXEXC ((u16)BIT2)
-#define HFA384x_intEN_TX ((u16)BIT1)
-#define HFA384x_intEN_RX ((u16)BIT0)
-
-#define HFA384x_EVACK_TICK ((u16)BIT15)
-#define HFA384x_EVACK_WTERR ((u16)BIT14)
-#define HFA384x_EVACK_INFDROP ((u16)BIT13)
-#define HFA384x_EVACK_INFO ((u16)BIT7)
-#define HFA384x_EVACK_DTIM ((u16)BIT5)
-#define HFA384x_EVACK_CMD ((u16)BIT4)
-#define HFA384x_EVACK_ALLOC ((u16)BIT3)
-#define HFA384x_EVACK_TXEXC ((u16)BIT2)
-#define HFA384x_EVACK_TX ((u16)BIT1)
-#define HFA384x_EVACK_RX ((u16)BIT0)
-
-#define HFA384x_CONTROL_AUXEN ((u16)(BIT15 | BIT14))
+#define HFA384x_CMD_AINFO ((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8)))
+#define HFA384x_CMD_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define HFA384x_CMD_PROGMODE ((u16)(BIT(9) | BIT(8)))
+#define HFA384x_CMD_CMDCODE ((u16)(BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)))
+#define HFA384x_STATUS_RESULT ((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8)))
/*--- Command Code Constants --------------------------*/
/*--- Controller Commands --------------------------*/
#define HFA384x_CMDCODE_INIT ((u16)0x00)
#define HFA384x_CMDCODE_ENABLE ((u16)0x01)
#define HFA384x_CMDCODE_DISABLE ((u16)0x02)
-#define HFA384x_CMDCODE_DIAG ((u16)0x03)
-
-/*--- Buffer Mgmt Commands --------------------------*/
-#define HFA384x_CMDCODE_ALLOC ((u16)0x0A)
-#define HFA384x_CMDCODE_TX ((u16)0x0B)
-#define HFA384x_CMDCODE_CLRPRST ((u16)0x12)
/*--- Regulate Commands --------------------------*/
-#define HFA384x_CMDCODE_NOTIFY ((u16)0x10)
#define HFA384x_CMDCODE_INQ ((u16)0x11)
/*--- Configure Commands --------------------------*/
-#define HFA384x_CMDCODE_ACCESS ((u16)0x21)
#define HFA384x_CMDCODE_DOWNLD ((u16)0x22)
/*--- Debugging Commands -----------------------------*/
@@ -327,9 +159,6 @@
#define HFA384x_MONITOR_DISABLE ((u16)(0x0f))
/*--- Result Codes --------------------------*/
-#define HFA384x_SUCCESS ((u16)(0x00))
-#define HFA384x_CARD_FAIL ((u16)(0x01))
-#define HFA384x_NO_BUFF ((u16)(0x05))
#define HFA384x_CMD_ERR ((u16)(0x7F))
/*--- Programming Modes --------------------------
@@ -343,16 +172,6 @@
#define HFA384x_PROGMODE_NV ((u16)0x02)
#define HFA384x_PROGMODE_NVWRITE ((u16)0x03)
-/*--- AUX register enable --------------------------*/
-#define HFA384x_AUXPW0 ((u16)0xfe01)
-#define HFA384x_AUXPW1 ((u16)0xdc23)
-#define HFA384x_AUXPW2 ((u16)0xba45)
-
-#define HFA384x_CONTROL_AUX_ISDISABLED ((u16)0x0000)
-#define HFA384x_CONTROL_AUX_ISENABLED ((u16)0xc000)
-#define HFA384x_CONTROL_AUX_DOENABLE ((u16)0x8000)
-#define HFA384x_CONTROL_AUX_DODISABLE ((u16)0x4000)
-
/*--- Record ID Constants --------------------------*/
/*--------------------------------------------------------------------
Configuration RIDs: Network Parameters, Static Configuration Entities
@@ -362,133 +181,25 @@ Configuration RIDs: Network Parameters, Static Configuration Entities
#define HFA384x_RID_CNFDESIREDSSID ((u16)0xFC02)
#define HFA384x_RID_CNFOWNCHANNEL ((u16)0xFC03)
#define HFA384x_RID_CNFOWNSSID ((u16)0xFC04)
-#define HFA384x_RID_CNFOWNATIMWIN ((u16)0xFC05)
-#define HFA384x_RID_CNFSYSSCALE ((u16)0xFC06)
#define HFA384x_RID_CNFMAXDATALEN ((u16)0xFC07)
-#define HFA384x_RID_CNFWDSADDR ((u16)0xFC08)
-#define HFA384x_RID_CNFPMENABLED ((u16)0xFC09)
-#define HFA384x_RID_CNFPMEPS ((u16)0xFC0A)
-#define HFA384x_RID_CNFMULTICASTRX ((u16)0xFC0B)
-#define HFA384x_RID_CNFMAXSLEEPDUR ((u16)0xFC0C)
-#define HFA384x_RID_CNFPMHOLDDUR ((u16)0xFC0D)
-#define HFA384x_RID_CNFOWNNAME ((u16)0xFC0E)
-#define HFA384x_RID_CNFOWNDTIMPER ((u16)0xFC10)
-#define HFA384x_RID_CNFWDSADDR1 ((u16)0xFC11)
-#define HFA384x_RID_CNFWDSADDR2 ((u16)0xFC12)
-#define HFA384x_RID_CNFWDSADDR3 ((u16)0xFC13)
-#define HFA384x_RID_CNFWDSADDR4 ((u16)0xFC14)
-#define HFA384x_RID_CNFWDSADDR5 ((u16)0xFC15)
-#define HFA384x_RID_CNFWDSADDR6 ((u16)0xFC16)
-#define HFA384x_RID_CNFMCASTPMBUFF ((u16)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 ((u16)2)
#define HFA384x_RID_CNFOWNMACADDR_LEN ((u16)6)
#define HFA384x_RID_CNFDESIREDSSID_LEN ((u16)34)
-#define HFA384x_RID_CNFOWNCHANNEL_LEN ((u16)2)
#define HFA384x_RID_CNFOWNSSID_LEN ((u16)34)
-#define HFA384x_RID_CNFOWNATIMWIN_LEN ((u16)2)
-#define HFA384x_RID_CNFSYSSCALE_LEN ((u16)0)
-#define HFA384x_RID_CNFMAXDATALEN_LEN ((u16)0)
-#define HFA384x_RID_CNFWDSADDR_LEN ((u16)6)
-#define HFA384x_RID_CNFPMENABLED_LEN ((u16)0)
-#define HFA384x_RID_CNFPMEPS_LEN ((u16)0)
-#define HFA384x_RID_CNFMULTICASTRX_LEN ((u16)0)
-#define HFA384x_RID_CNFMAXSLEEPDUR_LEN ((u16)0)
-#define HFA384x_RID_CNFPMHOLDDUR_LEN ((u16)0)
-#define HFA384x_RID_CNFOWNNAME_LEN ((u16)34)
-#define HFA384x_RID_CNFOWNDTIMPER_LEN ((u16)0)
-#define HFA384x_RID_CNFWDSADDR1_LEN ((u16)6)
-#define HFA384x_RID_CNFWDSADDR2_LEN ((u16)6)
-#define HFA384x_RID_CNFWDSADDR3_LEN ((u16)6)
-#define HFA384x_RID_CNFWDSADDR4_LEN ((u16)6)
-#define HFA384x_RID_CNFWDSADDR5_LEN ((u16)6)
-#define HFA384x_RID_CNFWDSADDR6_LEN ((u16)6)
-#define HFA384x_RID_CNFMCASTPMBUFF_LEN ((u16)0)
-#define HFA384x_RID_CNFAUTHENTICATION_LEN ((u16)sizeof(u16))
-#define HFA384x_RID_CNFMAXSLEEPDUR_LEN ((u16)0)
/*--------------------------------------------------------------------
Configuration RIDs: Network Parameters, Dynamic Configuration Entities
--------------------------------------------------------------------*/
-#define HFA384x_RID_GROUPADDR ((u16)0xFC80)
#define HFA384x_RID_CREATEIBSS ((u16)0xFC81)
#define HFA384x_RID_FRAGTHRESH ((u16)0xFC82)
#define HFA384x_RID_RTSTHRESH ((u16)0xFC83)
#define HFA384x_RID_TXRATECNTL ((u16)0xFC84)
#define HFA384x_RID_PROMISCMODE ((u16)0xFC85)
-#define HFA384x_RID_FRAGTHRESH0 ((u16)0xFC90)
-#define HFA384x_RID_FRAGTHRESH1 ((u16)0xFC91)
-#define HFA384x_RID_FRAGTHRESH2 ((u16)0xFC92)
-#define HFA384x_RID_FRAGTHRESH3 ((u16)0xFC93)
-#define HFA384x_RID_FRAGTHRESH4 ((u16)0xFC94)
-#define HFA384x_RID_FRAGTHRESH5 ((u16)0xFC95)
-#define HFA384x_RID_FRAGTHRESH6 ((u16)0xFC96)
-#define HFA384x_RID_RTSTHRESH0 ((u16)0xFC97)
-#define HFA384x_RID_RTSTHRESH1 ((u16)0xFC98)
-#define HFA384x_RID_RTSTHRESH2 ((u16)0xFC99)
-#define HFA384x_RID_RTSTHRESH3 ((u16)0xFC9A)
-#define HFA384x_RID_RTSTHRESH4 ((u16)0xFC9B)
-#define HFA384x_RID_RTSTHRESH5 ((u16)0xFC9C)
-#define HFA384x_RID_RTSTHRESH6 ((u16)0xFC9D)
-#define HFA384x_RID_TXRATECNTL0 ((u16)0xFC9E)
-#define HFA384x_RID_TXRATECNTL1 ((u16)0xFC9F)
-#define HFA384x_RID_TXRATECNTL2 ((u16)0xFCA0)
-#define HFA384x_RID_TXRATECNTL3 ((u16)0xFCA1)
-#define HFA384x_RID_TXRATECNTL4 ((u16)0xFCA2)
-#define HFA384x_RID_TXRATECNTL5 ((u16)0xFCA3)
-#define HFA384x_RID_TXRATECNTL6 ((u16)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 ((u16)16 * WLAN_ADDR_LEN)
-#define HFA384x_RID_CREATEIBSS_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL_LEN ((u16)4)
-#define HFA384x_RID_PROMISCMODE_LEN ((u16)2)
-#define HFA384x_RID_FRAGTHRESH0_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH1_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH2_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH3_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH4_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH5_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH6_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH0_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH1_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH2_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH3_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH4_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH5_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH6_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL0_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL1_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL2_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL3_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL4_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL5_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL6_LEN ((u16)0)
-
-/*--------------------------------------------------------------------
-Configuration RIDs: Behavior Parameters
---------------------------------------------------------------------*/
-#define HFA384x_RID_ITICKTIME ((u16)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 ((u16)2)
/*----------------------------------------------------------------------
Information RIDs: NIC Information
@@ -502,41 +213,17 @@ Information RIDs: NIC Information
#define HFA384x_RID_NICIDENTITY ((u16)0xFD0B)
#define HFA384x_RID_MFISUPRANGE ((u16)0xFD0C)
#define HFA384x_RID_CFISUPRANGE ((u16)0xFD0D)
-#define HFA384x_RID_CHANNELLIST ((u16)0xFD10)
-#define HFA384x_RID_REGULATORYDOMAINS ((u16)0xFD11)
-#define HFA384x_RID_TEMPTYPE ((u16)0xFD12)
-#define HFA384x_RID_CIS ((u16)0xFD13)
#define HFA384x_RID_STAIDENTITY ((u16)0xFD20)
#define HFA384x_RID_STASUPRANGE ((u16)0xFD21)
#define HFA384x_RID_STA_MFIACTRANGES ((u16)0xFD22)
#define HFA384x_RID_STA_CFIACTRANGES ((u16)0xFD23)
-#define HFA384x_RID_BUILDSEQ ((u16)0xFFFE)
-#define HFA384x_RID_FWID ((u16)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 ((u16)0)
-#define HFA384x_RID_DOWNLOADBUFFER_LEN ((u16)sizeof(hfa384x_downloadbuffer_t))
-#define HFA384x_RID_PRIIDENTITY_LEN ((u16)8)
-#define HFA384x_RID_PRISUPRANGE_LEN ((u16)10)
-#define HFA384x_RID_CFIACTRANGES_LEN ((u16)10)
#define HFA384x_RID_NICSERIALNUMBER_LEN ((u16)12)
-#define HFA384x_RID_NICIDENTITY_LEN ((u16)8)
-#define HFA384x_RID_MFISUPRANGE_LEN ((u16)10)
-#define HFA384x_RID_CFISUPRANGE_LEN ((u16)10)
-#define HFA384x_RID_CHANNELLIST_LEN ((u16)0)
-#define HFA384x_RID_REGULATORYDOMAINS_LEN ((u16)12)
-#define HFA384x_RID_TEMPTYPE_LEN ((u16)0)
-#define HFA384x_RID_CIS_LEN ((u16)480)
-#define HFA384x_RID_STAIDENTITY_LEN ((u16)8)
-#define HFA384x_RID_STASUPRANGE_LEN ((u16)10)
-#define HFA384x_RID_MFIACTRANGES_LEN ((u16)10)
-#define HFA384x_RID_CFIACTRANGES2_LEN ((u16)10)
-#define HFA384x_RID_BUILDSEQ_LEN ((u16)sizeof(hfa384x_BuildSeq_t))
-#define HFA384x_RID_FWID_LEN ((u16)sizeof(hfa384x_FWID_t))
/*--------------------------------------------------------------------
Information RIDs: MAC Information
@@ -544,87 +231,25 @@ Information RIDs: MAC Information
#define HFA384x_RID_PORTSTATUS ((u16)0xFD40)
#define HFA384x_RID_CURRENTSSID ((u16)0xFD41)
#define HFA384x_RID_CURRENTBSSID ((u16)0xFD42)
-#define HFA384x_RID_COMMSQUALITY ((u16)0xFD43)
#define HFA384x_RID_CURRENTTXRATE ((u16)0xFD44)
-#define HFA384x_RID_CURRENTBCNint ((u16)0xFD45)
-#define HFA384x_RID_CURRENTSCALETHRESH ((u16)0xFD46)
-#define HFA384x_RID_PROTOCOLRSPTIME ((u16)0xFD47)
#define HFA384x_RID_SHORTRETRYLIMIT ((u16)0xFD48)
#define HFA384x_RID_LONGRETRYLIMIT ((u16)0xFD49)
#define HFA384x_RID_MAXTXLIFETIME ((u16)0xFD4A)
-#define HFA384x_RID_MAXRXLIFETIME ((u16)0xFD4B)
-#define HFA384x_RID_CFPOLLABLE ((u16)0xFD4C)
-#define HFA384x_RID_AUTHALGORITHMS ((u16)0xFD4D)
#define HFA384x_RID_PRIVACYOPTIMP ((u16)0xFD4F)
#define HFA384x_RID_DBMCOMMSQUALITY ((u16)0xFD51)
-#define HFA384x_RID_CURRENTTXRATE1 ((u16)0xFD80)
-#define HFA384x_RID_CURRENTTXRATE2 ((u16)0xFD81)
-#define HFA384x_RID_CURRENTTXRATE3 ((u16)0xFD82)
-#define HFA384x_RID_CURRENTTXRATE4 ((u16)0xFD83)
-#define HFA384x_RID_CURRENTTXRATE5 ((u16)0xFD84)
-#define HFA384x_RID_CURRENTTXRATE6 ((u16)0xFD85)
-#define HFA384x_RID_OWNMACADDRESS ((u16)0xFD86)
-// #define HFA384x_RID_PCFINFO ((u16)0xFD87)
-#define HFA384x_RID_SCANRESULTS ((u16)0xFD88) // NEW
-#define HFA384x_RID_HOSTSCANRESULTS ((u16)0xFD89) // NEW
-#define HFA384x_RID_AUTHENTICATIONUSED ((u16)0xFD8A) // NEW
-#define HFA384x_RID_ASSOCIATEFAILURE ((u16)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 ((u16)0)
-#define HFA384x_RID_CURRENTSSID_LEN ((u16)34)
-#define HFA384x_RID_CURRENTBSSID_LEN ((u16)WLAN_BSSID_LEN)
-#define HFA384x_RID_COMMSQUALITY_LEN ((u16)sizeof(hfa384x_commsquality_t))
#define HFA384x_RID_DBMCOMMSQUALITY_LEN ((u16)sizeof(hfa384x_dbmcommsquality_t))
-#define HFA384x_RID_CURRENTTXRATE_LEN ((u16)0)
-#define HFA384x_RID_CURRENTBCNint_LEN ((u16)0)
-#define HFA384x_RID_STACURSCALETHRESH_LEN ((u16)12)
-#define HFA384x_RID_APCURSCALETHRESH_LEN ((u16)6)
-#define HFA384x_RID_PROTOCOLRSPTIME_LEN ((u16)0)
-#define HFA384x_RID_SHORTRETRYLIMIT_LEN ((u16)0)
-#define HFA384x_RID_LONGRETRYLIMIT_LEN ((u16)0)
-#define HFA384x_RID_MAXTXLIFETIME_LEN ((u16)0)
-#define HFA384x_RID_MAXRXLIFETIME_LEN ((u16)0)
-#define HFA384x_RID_CFPOLLABLE_LEN ((u16)0)
-#define HFA384x_RID_AUTHALGORITHMS_LEN ((u16)4)
-#define HFA384x_RID_PRIVACYOPTIMP_LEN ((u16)0)
-#define HFA384x_RID_CURRENTTXRATE1_LEN ((u16)0)
-#define HFA384x_RID_CURRENTTXRATE2_LEN ((u16)0)
-#define HFA384x_RID_CURRENTTXRATE3_LEN ((u16)0)
-#define HFA384x_RID_CURRENTTXRATE4_LEN ((u16)0)
-#define HFA384x_RID_CURRENTTXRATE5_LEN ((u16)0)
-#define HFA384x_RID_CURRENTTXRATE6_LEN ((u16)0)
-#define HFA384x_RID_OWNMACADDRESS_LEN ((u16)6)
-#define HFA384x_RID_PCFINFO_LEN ((u16)6)
-#define HFA384x_RID_CNFAPPCFINFO_LEN ((u16)sizeof(hfa384x_PCFInfo_data_t))
-#define HFA384x_RID_SCANREQUEST_LEN ((u16)sizeof(hfa384x_ScanRequest_data_t))
#define HFA384x_RID_JOINREQUEST_LEN ((u16)sizeof(hfa384x_JoinRequest_data_t))
-#define HFA384x_RID_AUTHENTICATESTA_LEN ((u16)sizeof(hfa384x_authenticateStation_data_t))
-#define HFA384x_RID_CHANNELINFOREQUEST_LEN ((u16)sizeof(hfa384x_ChannelInfoRequest_data_t))
+
/*--------------------------------------------------------------------
Information RIDs: Modem Information
--------------------------------------------------------------------*/
-#define HFA384x_RID_PHYTYPE ((u16)0xFDC0)
#define HFA384x_RID_CURRENTCHANNEL ((u16)0xFDC1)
-#define HFA384x_RID_CURRENTPOWERSTATE ((u16)0xFDC2)
-#define HFA384x_RID_CCAMODE ((u16)0xFDC3)
-#define HFA384x_RID_SUPPORTEDDATARATES ((u16)0xFDC6)
-#define HFA384x_RID_LFOSTATUS ((u16)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 ((u16)0)
-#define HFA384x_RID_CURRENTCHANNEL_LEN ((u16)0)
-#define HFA384x_RID_CURRENTPOWERSTATE_LEN ((u16)0)
-#define HFA384x_RID_CCAMODE_LEN ((u16)0)
-#define HFA384x_RID_SUPPORTEDDATARATES_LEN ((u16)10)
/*--------------------------------------------------------------------
API ENHANCEMENTS (NOT ALREADY IMPLEMENTED)
@@ -635,57 +260,22 @@ API ENHANCEMENTS (NOT ALREADY IMPLEMENTED)
#define HFA384x_RID_CNFWEPDEFAULTKEY2 ((u16)0xFC26)
#define HFA384x_RID_CNFWEPDEFAULTKEY3 ((u16)0xFC27)
#define HFA384x_RID_CNFWEPFLAGS ((u16)0xFC28)
-#define HFA384x_RID_CNFWEPKEYMAPTABLE ((u16)0xFC29)
#define HFA384x_RID_CNFAUTHENTICATION ((u16)0xFC2A)
-#define HFA384x_RID_CNFMAXASSOCSTATIONS ((u16)0xFC2B)
-#define HFA384x_RID_CNFTXCONTROL ((u16)0xFC2C)
#define HFA384x_RID_CNFROAMINGMODE ((u16)0xFC2D)
-#define HFA384x_RID_CNFHOSTAUTHASSOC ((u16)0xFC2E)
-#define HFA384x_RID_CNFRCVCRCERROR ((u16)0xFC30)
-// #define HFA384x_RID_CNFMMLIFE ((u16)0xFC31)
-#define HFA384x_RID_CNFALTRETRYCNT ((u16)0xFC32)
#define HFA384x_RID_CNFAPBCNint ((u16)0xFC33)
-#define HFA384x_RID_CNFAPPCFINFO ((u16)0xFC34)
-#define HFA384x_RID_CNFSTAPCFINFO ((u16)0xFC35)
-#define HFA384x_RID_CNFPRIORITYQUSAGE ((u16)0xFC37)
-#define HFA384x_RID_CNFTIMCTRL ((u16)0xFC40)
-#define HFA384x_RID_CNFTHIRTY2TALLY ((u16)0xFC42)
-#define HFA384x_RID_CNFENHSECURITY ((u16)0xFC43)
-#define HFA384x_RID_CNFDBMADJUST ((u16)0xFC46) // NEW
-#define HFA384x_RID_CNFWPADATA ((u16)0xFC48) // 1.7.0
-#define HFA384x_RID_CNFPROPOGATIONDELAY ((u16)0xFC49) // 1.7.6
-#define HFA384x_RID_CNFSHORTPREAMBLE ((u16)0xFCB0)
-#define HFA384x_RID_CNFEXCLONGPREAMBLE ((u16)0xFCB1)
-#define HFA384x_RID_CNFAUTHRSPTIMEOUT ((u16)0xFCB2)
+#define HFA384x_RID_CNFDBMADJUST ((u16)0xFC46)
+#define HFA384x_RID_CNFWPADATA ((u16)0xFC48)
#define HFA384x_RID_CNFBASICRATES ((u16)0xFCB3)
#define HFA384x_RID_CNFSUPPRATES ((u16)0xFCB4)
-#define HFA384x_RID_CNFFALLBACKCTRL ((u16)0xFCB5) // NEW
-#define HFA384x_RID_WEPKEYSTATUS ((u16)0xFCB6) // NEW
-#define HFA384x_RID_WEPKEYMAPINDEX ((u16)0xFCB7) // NEW
-#define HFA384x_RID_BROADCASTKEYID ((u16)0xFCB8) // NEW
-#define HFA384x_RID_ENTSECFLAGEYID ((u16)0xFCB9) // NEW
-#define HFA384x_RID_CNFPASSIVESCANCTRL ((u16)0xFCBA) // NEW STA
-#define HFA384x_RID_CNFWPAHANDLING ((u16)0xFCBB) // 1.7.0
-#define HFA384x_RID_MDCCONTROL ((u16)0xFCBC) // 1.7.0/1.4.0
-#define HFA384x_RID_MDCCOUNTRY ((u16)0xFCBD) // 1.7.0/1.4.0
-#define HFA384x_RID_TXPOWERMAX ((u16)0xFCBE) // 1.7.0/1.4.0
-#define HFA384x_RID_CNFLFOENBLED ((u16)0xFCBF) // 1.6.3
-#define HFA384x_RID_CAPINFO ((u16)0xFCC0) // 1.7.0/1.3.7
-#define HFA384x_RID_LISTENintERVAL ((u16)0xFCC1) // 1.7.0/1.3.7
-#define HFA384x_RID_DIVERSITYENABLED ((u16)0xFCC2) // 1.7.0/1.3.7
-#define HFA384x_RID_LED_CONTROL ((u16)0xFCC4) // 1.7.6
-#define HFA384x_RID_HFO_DELAY ((u16)0xFCC5) // 1.7.6
-#define HFA384x_RID_DISSALOWEDBSSID ((u16)0xFCC6) // 1.8.0
-#define HFA384x_RID_SCANREQUEST ((u16)0xFCE1)
+#define HFA384x_RID_CNFPASSIVESCANCTRL ((u16)0xFCBA)
+#define HFA384x_RID_TXPOWERMAX ((u16)0xFCBE)
#define HFA384x_RID_JOINREQUEST ((u16)0xFCE2)
#define HFA384x_RID_AUTHENTICATESTA ((u16)0xFCE3)
-#define HFA384x_RID_CHANNELINFOREQUEST ((u16)0xFCE4)
-#define HFA384x_RID_HOSTSCAN ((u16)0xFCE5) // NEW STA
-#define HFA384x_RID_ASSOCIATESTA ((u16)0xFCE6)
+#define HFA384x_RID_HOSTSCAN ((u16)0xFCE5)
#define HFA384x_RID_CNFWEPDEFAULTKEY_LEN ((u16)6)
#define HFA384x_RID_CNFWEP128DEFAULTKEY_LEN ((u16)14)
-#define HFA384x_RID_CNFPRIOQUSAGE_LEN ((u16)4)
+
/*--------------------------------------------------------------------
PD Record codes
--------------------------------------------------------------------*/
@@ -697,22 +287,11 @@ PD Record codes
#define HFA384x_PDR_MFISUPRANGE ((u16)0x0006)
#define HFA384x_PDR_CFISUPRANGE ((u16)0x0007)
#define HFA384x_PDR_NICID ((u16)0x0008)
-//#define HFA384x_PDR_REFDAC_MEASUREMENTS ((u16)0x0010)
-//#define HFA384x_PDR_VGDAC_MEASUREMENTS ((u16)0x0020)
-//#define HFA384x_PDR_LEVEL_COMP_MEASUREMENTS ((u16)0x0030)
-//#define HFA384x_PDR_MODEM_TRIMDAC_MEASUREMENTS ((u16)0x0040)
-//#define HFA384x_PDR_COREGA_HACK ((u16)0x00ff)
#define HFA384x_PDR_MAC_ADDRESS ((u16)0x0101)
-//#define HFA384x_PDR_MKK_CALLNAME ((u16)0x0102)
#define HFA384x_PDR_REGDOMAIN ((u16)0x0103)
#define HFA384x_PDR_ALLOWED_CHANNEL ((u16)0x0104)
#define HFA384x_PDR_DEFAULT_CHANNEL ((u16)0x0105)
-//#define HFA384x_PDR_PRIVACY_OPTION ((u16)0x0106)
#define HFA384x_PDR_TEMPTYPE ((u16)0x0107)
-//#define HFA384x_PDR_REFDAC_SETUP ((u16)0x0110)
-//#define HFA384x_PDR_VGDAC_SETUP ((u16)0x0120)
-//#define HFA384x_PDR_LEVEL_COMP_SETUP ((u16)0x0130)
-//#define HFA384x_PDR_TRIMDAC_SETUP ((u16)0x0140)
#define HFA384x_PDR_IFR_SETTING ((u16)0x0200)
#define HFA384x_PDR_RFR_SETTING ((u16)0x0201)
#define HFA384x_PDR_HFA3861_BASELINE ((u16)0x0202)
@@ -729,7 +308,6 @@ PD Record codes
#define HFA384x_PDR_PCI_PMCONF ((u16)0x0404)
#define HFA384x_PDR_RFENRGY ((u16)0x0406)
#define HFA384x_PDR_USB_POWER_TYPE ((u16)0x0407)
-//#define HFA384x_PDR_UNKNOWN408 ((u16)0x0408)
#define HFA384x_PDR_USB_MAX_POWER ((u16)0x0409)
#define HFA384x_PDR_USB_MANUFACTURER ((u16)0x0410)
#define HFA384x_PDR_USB_PRODUCT ((u16)0x0411)
@@ -741,831 +319,122 @@ PD Record codes
#define HFA384x_PDR_HFA3861_MANF_TESTI ((u16)0x0901)
#define HFA384x_PDR_END_OF_PDA ((u16)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) ((u16)(((u16)value) & HFA384x_CMD_BUSY))
-#define HFA384x_CMD_AINFO_GET(value) ((u16)(((u16)(value) & HFA384x_CMD_AINFO) >> 8))
#define HFA384x_CMD_AINFO_SET(value) ((u16)((u16)(value) << 8))
-#define HFA384x_CMD_MACPORT_GET(value) ((u16)(HFA384x_CMD_AINFO_GET((u16)(value) & HFA384x_CMD_MACPORT)))
#define HFA384x_CMD_MACPORT_SET(value) ((u16)HFA384x_CMD_AINFO_SET(value))
-#define HFA384x_CMD_ISRECL(value) ((u16)(HFA384x_CMD_AINFO_GET((u16)(value) & HFA384x_CMD_RECL)))
-#define HFA384x_CMD_RECL_SET(value) ((u16)HFA384x_CMD_AINFO_SET(value))
-#define HFA384x_CMD_QOS_GET(value) ((u16)((((u16)(value))&((u16)0x3000)) >> 12))
-#define HFA384x_CMD_QOS_SET(value) ((u16)((((u16)(value)) << 12) & 0x3000))
-#define HFA384x_CMD_ISWRITE(value) ((u16)(HFA384x_CMD_AINFO_GET((u16)(value) & HFA384x_CMD_WRITE)))
-#define HFA384x_CMD_WRITE_SET(value) ((u16)HFA384x_CMD_AINFO_SET((u16)value))
-#define HFA384x_CMD_PROGMODE_GET(value) ((u16)(HFA384x_CMD_AINFO_GET((u16)(value) & HFA384x_CMD_PROGMODE)))
#define HFA384x_CMD_PROGMODE_SET(value) ((u16)HFA384x_CMD_AINFO_SET((u16)value))
-#define HFA384x_CMD_CMDCODE_GET(value) ((u16)(((u16)(value)) & HFA384x_CMD_CMDCODE))
#define HFA384x_CMD_CMDCODE_SET(value) ((u16)(value))
-#define HFA384x_STATUS_RESULT_GET(value) ((u16)((((u16)(value)) & HFA384x_STATUS_RESULT) >> 8))
#define HFA384x_STATUS_RESULT_SET(value) (((u16)(value)) << 8)
-#define HFA384x_STATUS_CMDCODE_GET(value) (((u16)(value)) & HFA384x_STATUS_CMDCODE)
-#define HFA384x_STATUS_CMDCODE_SET(value) ((u16)(value))
-
-#define HFA384x_OFFSET_ISBUSY(value) ((u16)(((u16)(value)) & HFA384x_OFFSET_BUSY))
-#define HFA384x_OFFSET_ISERR(value) ((u16)(((u16)(value)) & HFA384x_OFFSET_ERR))
-#define HFA384x_OFFSET_DATAOFF_GET(value) ((u16)(((u16)(value)) & HFA384x_OFFSET_DATAOFF))
-#define HFA384x_OFFSET_DATAOFF_SET(value) ((u16)(value))
-
-#define HFA384x_EVSTAT_ISTICK(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_TICK))
-#define HFA384x_EVSTAT_ISWTERR(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_WTERR))
-#define HFA384x_EVSTAT_ISINFDROP(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_INFDROP))
-#define HFA384x_EVSTAT_ISINFO(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_INFO))
-#define HFA384x_EVSTAT_ISDTIM(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_DTIM))
-#define HFA384x_EVSTAT_ISCMD(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_CMD))
-#define HFA384x_EVSTAT_ISALLOC(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_ALLOC))
-#define HFA384x_EVSTAT_ISTXEXC(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_TXEXC))
-#define HFA384x_EVSTAT_ISTX(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_TX))
-#define HFA384x_EVSTAT_ISRX(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_RX))
-
-#define HFA384x_EVSTAT_ISBAP_OP(value) ((u16)(((u16)(value)) & HFA384x_int_BAP_OP))
-
-#define HFA384x_intEN_ISTICK(value) ((u16)(((u16)(value)) & HFA384x_INTEN_TICK))
-#define HFA384x_intEN_TICK_SET(value) ((u16)(((u16)(value)) << 15))
-#define HFA384x_intEN_ISWTERR(value) ((u16)(((u16)(value)) & HFA384x_INTEN_WTERR))
-#define HFA384x_intEN_WTERR_SET(value) ((u16)(((u16)(value)) << 14))
-#define HFA384x_intEN_ISINFDROP(value) ((u16)(((u16)(value)) & HFA384x_INTEN_INFDROP))
-#define HFA384x_intEN_INFDROP_SET(value) ((u16)(((u16)(value)) << 13))
-#define HFA384x_intEN_ISINFO(value) ((u16)(((u16)(value)) & HFA384x_INTEN_INFO))
-#define HFA384x_intEN_INFO_SET(value) ((u16)(((u16)(value)) << 7))
-#define HFA384x_intEN_ISDTIM(value) ((u16)(((u16)(value)) & HFA384x_INTEN_DTIM))
-#define HFA384x_intEN_DTIM_SET(value) ((u16)(((u16)(value)) << 5))
-#define HFA384x_intEN_ISCMD(value) ((u16)(((u16)(value)) & HFA384x_INTEN_CMD))
-#define HFA384x_intEN_CMD_SET(value) ((u16)(((u16)(value)) << 4))
-#define HFA384x_intEN_ISALLOC(value) ((u16)(((u16)(value)) & HFA384x_INTEN_ALLOC))
-#define HFA384x_intEN_ALLOC_SET(value) ((u16)(((u16)(value)) << 3))
-#define HFA384x_intEN_ISTXEXC(value) ((u16)(((u16)(value)) & HFA384x_INTEN_TXEXC))
-#define HFA384x_intEN_TXEXC_SET(value) ((u16)(((u16)(value)) << 2))
-#define HFA384x_intEN_ISTX(value) ((u16)(((u16)(value)) & HFA384x_INTEN_TX))
-#define HFA384x_intEN_TX_SET(value) ((u16)(((u16)(value)) << 1))
-#define HFA384x_intEN_ISRX(value) ((u16)(((u16)(value)) & HFA384x_INTEN_RX))
-#define HFA384x_intEN_RX_SET(value) ((u16)(((u16)(value)) << 0))
-
-#define HFA384x_EVACK_ISTICK(value) ((u16)(((u16)(value)) & HFA384x_EVACK_TICK))
-#define HFA384x_EVACK_TICK_SET(value) ((u16)(((u16)(value)) << 15))
-#define HFA384x_EVACK_ISWTERR(value) ((u16)(((u16)(value)) & HFA384x_EVACK_WTERR))
-#define HFA384x_EVACK_WTERR_SET(value) ((u16)(((u16)(value)) << 14))
-#define HFA384x_EVACK_ISINFDROP(value) ((u16)(((u16)(value)) & HFA384x_EVACK_INFDROP))
-#define HFA384x_EVACK_INFDROP_SET(value) ((u16)(((u16)(value)) << 13))
-#define HFA384x_EVACK_ISINFO(value) ((u16)(((u16)(value)) & HFA384x_EVACK_INFO))
-#define HFA384x_EVACK_INFO_SET(value) ((u16)(((u16)(value)) << 7))
-#define HFA384x_EVACK_ISDTIM(value) ((u16)(((u16)(value)) & HFA384x_EVACK_DTIM))
-#define HFA384x_EVACK_DTIM_SET(value) ((u16)(((u16)(value)) << 5))
-#define HFA384x_EVACK_ISCMD(value) ((u16)(((u16)(value)) & HFA384x_EVACK_CMD))
-#define HFA384x_EVACK_CMD_SET(value) ((u16)(((u16)(value)) << 4))
-#define HFA384x_EVACK_ISALLOC(value) ((u16)(((u16)(value)) & HFA384x_EVACK_ALLOC))
-#define HFA384x_EVACK_ALLOC_SET(value) ((u16)(((u16)(value)) << 3))
-#define HFA384x_EVACK_ISTXEXC(value) ((u16)(((u16)(value)) & HFA384x_EVACK_TXEXC))
-#define HFA384x_EVACK_TXEXC_SET(value) ((u16)(((u16)(value)) << 2))
-#define HFA384x_EVACK_ISTX(value) ((u16)(((u16)(value)) & HFA384x_EVACK_TX))
-#define HFA384x_EVACK_TX_SET(value) ((u16)(((u16)(value)) << 1))
-#define HFA384x_EVACK_ISRX(value) ((u16)(((u16)(value)) & HFA384x_EVACK_RX))
-#define HFA384x_EVACK_RX_SET(value) ((u16)(((u16)(value)) << 0))
-
-#define HFA384x_CONTROL_AUXEN_SET(value) ((u16)(((u16)(value)) << 14))
-#define HFA384x_CONTROL_AUXEN_GET(value) ((u16)(((u16)(value)) >> 14))
-
-/* Byte Order */
-#ifdef __KERNEL__
-#define hfa384x2host_16(n) (__le16_to_cpu((u16)(n)))
-#define hfa384x2host_32(n) (__le32_to_cpu((u32)(n)))
-#define host2hfa384x_16(n) (__cpu_to_le16((u16)(n)))
-#define host2hfa384x_32(n) (__cpu_to_le32((u32)(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
-{
- u16 len;
- u8 data[0];
-} __WLAN_ATTRIB_PACK__ hfa384x_bytestr_t;
+typedef struct hfa384x_bytestr {
+ u16 len;
+ u8 data[0];
+} __attribute__ ((packed)) hfa384x_bytestr_t;
-typedef struct hfa384x_bytestr32
-{
- u16 len;
- u8 data[32];
-} __WLAN_ATTRIB_PACK__ hfa384x_bytestr32_t;
+typedef struct hfa384x_bytestr32 {
+ u16 len;
+ u8 data[32];
+} __attribute__ ((packed)) 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
-{
- u16 reclen;
- u16 rid;
-} __WLAN_ATTRIB_PACK__ hfa384x_rec_t;
-
-typedef struct hfa384x_record16
-{
- u16 reclen;
- u16 rid;
- u16 val;
-} __WLAN_ATTRIB_PACK__ hfa384x_rec16_t;
-
-typedef struct hfa384x_record32
-{
- u16 reclen;
- u16 rid;
- u32 val;
-} __WLAN_ATTRIB_PACK__ hfa384x_rec32;
/*-- Hardware/Firmware Component Information ----------*/
-typedef struct hfa384x_compident
-{
- u16 id;
- u16 variant;
- u16 major;
- u16 minor;
-} __WLAN_ATTRIB_PACK__ hfa384x_compident_t;
-
-typedef struct hfa384x_caplevel
-{
- u16 role;
- u16 id;
- u16 variant;
- u16 bottom;
- u16 top;
-} __WLAN_ATTRIB_PACK__ hfa384x_caplevel_t;
-
-/*-- Configuration Record: cnfPortType --*/
-typedef struct hfa384x_cnfPortType
-{
- u16 cnfPortType;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfPortType_t;
-
-/*-- Configuration Record: cnfOwnMACAddress --*/
-typedef struct hfa384x_cnfOwnMACAddress
-{
- u8 cnfOwnMACAddress[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnMACAddress_t;
-
-/*-- Configuration Record: cnfDesiredSSID --*/
-typedef struct hfa384x_cnfDesiredSSID
-{
- u8 cnfDesiredSSID[34];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfDesiredSSID_t;
-
-/*-- Configuration Record: cnfOwnChannel --*/
-typedef struct hfa384x_cnfOwnChannel
-{
- u16 cnfOwnChannel;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnChannel_t;
-
-/*-- Configuration Record: cnfOwnSSID --*/
-typedef struct hfa384x_cnfOwnSSID
-{
- u8 cnfOwnSSID[34];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnSSID_t;
-
-/*-- Configuration Record: cnfOwnATIMWindow --*/
-typedef struct hfa384x_cnfOwnATIMWindow
-{
- u16 cnfOwnATIMWindow;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnATIMWindow_t;
-
-/*-- Configuration Record: cnfSystemScale --*/
-typedef struct hfa384x_cnfSystemScale
-{
- u16 cnfSystemScale;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfSystemScale_t;
-
-/*-- Configuration Record: cnfMaxDataLength --*/
-typedef struct hfa384x_cnfMaxDataLength
-{
- u16 cnfMaxDataLength;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxDataLength_t;
-
-/*-- Configuration Record: cnfWDSAddress --*/
-typedef struct hfa384x_cnfWDSAddress
-{
- u8 cnfWDSAddress[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddress_t;
-
-/*-- Configuration Record: cnfPMEnabled --*/
-typedef struct hfa384x_cnfPMEnabled
-{
- u16 cnfPMEnabled;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEnabled_t;
-
-/*-- Configuration Record: cnfPMEPS --*/
-typedef struct hfa384x_cnfPMEPS
-{
- u16 cnfPMEPS;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEPS_t;
-
-/*-- Configuration Record: cnfMulticastReceive --*/
-typedef struct hfa384x_cnfMulticastReceive
-{
- u16 cnfMulticastReceive;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastReceive_t;
+typedef struct hfa384x_compident {
+ u16 id;
+ u16 variant;
+ u16 major;
+ u16 minor;
+} __attribute__ ((packed)) hfa384x_compident_t;
+
+typedef struct hfa384x_caplevel {
+ u16 role;
+ u16 id;
+ u16 variant;
+ u16 bottom;
+ u16 top;
+} __attribute__ ((packed)) hfa384x_caplevel_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
-{
- u16 cnfMaxSleepDuration;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxSleepDuration_t;
-
-/*-- Configuration Record: cnfPMHoldoverDuration --*/
-typedef struct hfa384x_cnfPMHoldoverDuration
-{
- u16 cnfPMHoldoverDuration;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMHoldoverDuration_t;
-
-/*-- Configuration Record: cnfOwnName --*/
-typedef struct hfa384x_cnfOwnName
-{
- u8 cnfOwnName[34];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnName_t;
-
-/*-- Configuration Record: cnfOwnDTIMPeriod --*/
-typedef struct hfa384x_cnfOwnDTIMPeriod
-{
- u16 cnfOwnDTIMPeriod;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnDTIMPeriod_t;
-
-/*-- Configuration Record: cnfWDSAddress --*/
-typedef struct hfa384x_cnfWDSAddressN
-{
- u8 cnfWDSAddress[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddressN_t;
-
-/*-- Configuration Record: cnfMulticastPMBuffering --*/
-typedef struct hfa384x_cnfMulticastPMBuffering
-{
- u16 cnfMulticastPMBuffering;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastPMBuffering_t;
-
/*--------------------------------------------------------------------
Configuration Record Structures:
Network Parameters, Dynamic Configuration Entities
--------------------------------------------------------------------*/
-/*-- Configuration Record: GroupAddresses --*/
-typedef struct hfa384x_GroupAddresses
-{
- u8 MACAddress[16][6];
-} __WLAN_ATTRIB_PACK__ hfa384x_GroupAddresses_t;
-
-/*-- Configuration Record: CreateIBSS --*/
-typedef struct hfa384x_CreateIBSS
-{
- u16 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
-{
- u16 FragmentationThreshold;
-} __WLAN_ATTRIB_PACK__ hfa384x_FragmentationThreshold_t;
-
-/*-- Configuration Record: RTSThreshold --*/
-typedef struct hfa384x_RTSThreshold
-{
- u16 RTSThreshold;
-} __WLAN_ATTRIB_PACK__ hfa384x_RTSThreshold_t;
-
-/*-- Configuration Record: TxRateControl --*/
-typedef struct hfa384x_TxRateControl
-{
- u16 TxRateControl;
-} __WLAN_ATTRIB_PACK__ hfa384x_TxRateControl_t;
-
-/*-- Configuration Record: PromiscuousMode --*/
-typedef struct hfa384x_PromiscuousMode
-{
- u16 PromiscuousMode;
-} __WLAN_ATTRIB_PACK__ hfa384x_PromiscuousMode_t;
-
-/*-- Configuration Record: ScanRequest (data portion only) --*/
-typedef struct hfa384x_ScanRequest_data
-{
- u16 channelList;
- u16 txRate;
-} __WLAN_ATTRIB_PACK__ hfa384x_ScanRequest_data_t;
/*-- Configuration Record: HostScanRequest (data portion only) --*/
-typedef struct hfa384x_HostScanRequest_data
-{
- u16 channelList;
- u16 txRate;
+typedef struct hfa384x_HostScanRequest_data {
+ u16 channelList;
+ u16 txRate;
hfa384x_bytestr32_t ssid;
-} __WLAN_ATTRIB_PACK__ hfa384x_HostScanRequest_data_t;
+} __attribute__ ((packed)) hfa384x_HostScanRequest_data_t;
/*-- Configuration Record: JoinRequest (data portion only) --*/
-typedef struct hfa384x_JoinRequest_data
-{
- u8 bssid[WLAN_BSSID_LEN];
- u16 channel;
-} __WLAN_ATTRIB_PACK__ hfa384x_JoinRequest_data_t;
+typedef struct hfa384x_JoinRequest_data {
+ u8 bssid[WLAN_BSSID_LEN];
+ u16 channel;
+} __attribute__ ((packed)) hfa384x_JoinRequest_data_t;
/*-- Configuration Record: authenticateStation (data portion only) --*/
-typedef struct hfa384x_authenticateStation_data
-{
- u8 address[WLAN_ADDR_LEN];
- u16 status;
- u16 algorithm;
-} __WLAN_ATTRIB_PACK__ hfa384x_authenticateStation_data_t;
-
-/*-- Configuration Record: associateStation (data portion only) --*/
-typedef struct hfa384x_associateStation_data
-{
- u8 address[WLAN_ADDR_LEN];
- u16 status;
- u16 type;
-} __WLAN_ATTRIB_PACK__ hfa384x_associateStation_data_t;
-
-/*-- Configuration Record: ChannelInfoRequest (data portion only) --*/
-typedef struct hfa384x_ChannelInfoRequest_data
-{
- u16 channelList;
- u16 channelDwellTime;
-} __WLAN_ATTRIB_PACK__ hfa384x_ChannelInfoRequest_data_t;
-
-/*-- Configuration Record: WEPKeyMapping (data portion only) --*/
-typedef struct hfa384x_WEPKeyMapping
-{
- u8 address[WLAN_ADDR_LEN];
- u16 key_index;
- u8 key[16];
- u8 mic_transmit_key[4];
- u8 mic_receive_key[4];
-} __WLAN_ATTRIB_PACK__ hfa384x_WEPKeyMapping_t;
+typedef struct hfa384x_authenticateStation_data {
+ u8 address[ETH_ALEN];
+ u16 status;
+ u16 algorithm;
+} __attribute__ ((packed)) hfa384x_authenticateStation_data_t;
/*-- Configuration Record: WPAData (data portion only) --*/
-typedef struct hfa384x_WPAData
-{
- u16 datalen;
- u8 data[0]; // max 80
-} __WLAN_ATTRIB_PACK__ hfa384x_WPAData_t;
-
-/*--------------------------------------------------------------------
-Configuration Record Structures: Behavior Parameters
---------------------------------------------------------------------*/
-
-/*-- Configuration Record: TickTime --*/
-typedef struct hfa384x_TickTime
-{
- u16 TickTime;
-} __WLAN_ATTRIB_PACK__ hfa384x_TickTime_t;
+typedef struct hfa384x_WPAData {
+ u16 datalen;
+ u8 data[0]; // max 80
+} __attribute__ ((packed)) hfa384x_WPAData_t;
/*--------------------------------------------------------------------
Information Record Structures: NIC Information
--------------------------------------------------------------------*/
-/*-- Information Record: MaxLoadTime --*/
-typedef struct hfa384x_MaxLoadTime
-{
- u16 MaxLoadTime;
-} __WLAN_ATTRIB_PACK__ hfa384x_MaxLoadTime_t;
-
/*-- Information Record: DownLoadBuffer --*/
/* NOTE: The page and offset are in AUX format */
-typedef struct hfa384x_downloadbuffer
-{
- u16 page;
- u16 offset;
- u16 len;
-} __WLAN_ATTRIB_PACK__ hfa384x_downloadbuffer_t;
-
-/*-- Information Record: PRIIdentity --*/
-typedef struct hfa384x_PRIIdentity
-{
- u16 PRICompID;
- u16 PRIVariant;
- u16 PRIMajorVersion;
- u16 PRIMinorVersion;
-} __WLAN_ATTRIB_PACK__ hfa384x_PRIIdentity_t;
-
-/*-- Information Record: PRISupRange --*/
-typedef struct hfa384x_PRISupRange
-{
- u16 PRIRole;
- u16 PRIID;
- u16 PRIVariant;
- u16 PRIBottom;
- u16 PRITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_PRISupRange_t;
-
-/*-- Information Record: CFIActRanges --*/
-typedef struct hfa384x_CFIActRanges
-{
- u16 CFIRole;
- u16 CFIID;
- u16 CFIVariant;
- u16 CFIBottom;
- u16 CFITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_CFIActRanges_t;
-
-/*-- Information Record: NICSerialNumber --*/
-typedef struct hfa384x_NICSerialNumber
-{
- u8 NICSerialNumber[12];
-} __WLAN_ATTRIB_PACK__ hfa384x_NICSerialNumber_t;
-
-/*-- Information Record: NICIdentity --*/
-typedef struct hfa384x_NICIdentity
-{
- u16 NICCompID;
- u16 NICVariant;
- u16 NICMajorVersion;
- u16 NICMinorVersion;
-} __WLAN_ATTRIB_PACK__ hfa384x_NICIdentity_t;
-
-/*-- Information Record: MFISupRange --*/
-typedef struct hfa384x_MFISupRange
-{
- u16 MFIRole;
- u16 MFIID;
- u16 MFIVariant;
- u16 MFIBottom;
- u16 MFITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_MFISupRange_t;
-
-/*-- Information Record: CFISupRange --*/
-typedef struct hfa384x_CFISupRange
-{
- u16 CFIRole;
- u16 CFIID;
- u16 CFIVariant;
- u16 CFIBottom;
- u16 CFITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_CFISupRange_t;
-
-/*-- Information Record: BUILDSEQ:BuildSeq --*/
-typedef struct hfa384x_BuildSeq {
- u16 primary;
- u16 secondary;
-} __WLAN_ATTRIB_PACK__ hfa384x_BuildSeq_t;
-
-/*-- Information Record: FWID --*/
-#define HFA384x_FWID_LEN 14
-typedef struct hfa384x_FWID {
- u8 primary[HFA384x_FWID_LEN];
- u8 secondary[HFA384x_FWID_LEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_FWID_t;
-
-/*-- Information Record: ChannelList --*/
-typedef struct hfa384x_ChannelList
-{
- u16 ChannelList;
-} __WLAN_ATTRIB_PACK__ hfa384x_ChannelList_t;
-
-/*-- Information Record: RegulatoryDomains --*/
-typedef struct hfa384x_RegulatoryDomains
-{
- u8 RegulatoryDomains[12];
-} __WLAN_ATTRIB_PACK__ hfa384x_RegulatoryDomains_t;
-
-/*-- Information Record: TempType --*/
-typedef struct hfa384x_TempType
-{
- u16 TempType;
-} __WLAN_ATTRIB_PACK__ hfa384x_TempType_t;
-
-/*-- Information Record: CIS --*/
-typedef struct hfa384x_CIS
-{
- u8 CIS[480];
-} __WLAN_ATTRIB_PACK__ hfa384x_CIS_t;
-
-/*-- Information Record: STAIdentity --*/
-typedef struct hfa384x_STAIdentity
-{
- u16 STACompID;
- u16 STAVariant;
- u16 STAMajorVersion;
- u16 STAMinorVersion;
-} __WLAN_ATTRIB_PACK__ hfa384x_STAIdentity_t;
-
-/*-- Information Record: STASupRange --*/
-typedef struct hfa384x_STASupRange
-{
- u16 STARole;
- u16 STAID;
- u16 STAVariant;
- u16 STABottom;
- u16 STATop;
-} __WLAN_ATTRIB_PACK__ hfa384x_STASupRange_t;
-
-/*-- Information Record: MFIActRanges --*/
-typedef struct hfa384x_MFIActRanges
-{
- u16 MFIRole;
- u16 MFIID;
- u16 MFIVariant;
- u16 MFIBottom;
- u16 MFITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_MFIActRanges_t;
+typedef struct hfa384x_downloadbuffer {
+ u16 page;
+ u16 offset;
+ u16 len;
+} __attribute__ ((packed)) hfa384x_downloadbuffer_t;
/*--------------------------------------------------------------------
Information Record Structures: NIC Information
--------------------------------------------------------------------*/
-/*-- Information Record: PortStatus --*/
-typedef struct hfa384x_PortStatus
-{
- u16 PortStatus;
-} __WLAN_ATTRIB_PACK__ hfa384x_PortStatus_t;
-
-#define HFA384x_PSTATUS_DISABLED ((u16)1)
-#define HFA384x_PSTATUS_SEARCHING ((u16)2)
#define HFA384x_PSTATUS_CONN_IBSS ((u16)3)
-#define HFA384x_PSTATUS_CONN_ESS ((u16)4)
-#define HFA384x_PSTATUS_OUTOFRANGE ((u16)5)
-#define HFA384x_PSTATUS_CONN_WDS ((u16)6)
-
-/*-- Information Record: CurrentSSID --*/
-typedef struct hfa384x_CurrentSSID
-{
- u8 CurrentSSID[34];
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentSSID_t;
-
-/*-- Information Record: CurrentBSSID --*/
-typedef struct hfa384x_CurrentBSSID
-{
- u8 CurrentBSSID[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBSSID_t;
/*-- Information Record: commsquality --*/
-typedef struct hfa384x_commsquality
-{
- u16 CQ_currBSS;
- u16 ASL_currBSS;
- u16 ANL_currFC;
-} __WLAN_ATTRIB_PACK__ hfa384x_commsquality_t;
+typedef struct hfa384x_commsquality {
+ u16 CQ_currBSS;
+ u16 ASL_currBSS;
+ u16 ANL_currFC;
+} __attribute__ ((packed)) hfa384x_commsquality_t;
/*-- Information Record: dmbcommsquality --*/
-typedef struct hfa384x_dbmcommsquality
-{
- u16 CQdbm_currBSS;
- u16 ASLdbm_currBSS;
- u16 ANLdbm_currFC;
-} __WLAN_ATTRIB_PACK__ hfa384x_dbmcommsquality_t;
-
-/*-- Information Record: CurrentTxRate --*/
-typedef struct hfa384x_CurrentTxRate
-{
- u16 CurrentTxRate;
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentTxRate_t;
-
-/*-- Information Record: CurrentBeaconInterval --*/
-typedef struct hfa384x_CurrentBeaconInterval
-{
- u16 CurrentBeaconInterval;
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBeaconInterval_t;
-
-/*-- Information Record: CurrentScaleThresholds --*/
-typedef struct hfa384x_CurrentScaleThresholds
-{
- u16 EnergyDetectThreshold;
- u16 CarrierDetectThreshold;
- u16 DeferDetectThreshold;
- u16 CellSearchThreshold; /* Stations only */
- u16 DeadSpotThreshold; /* Stations only */
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentScaleThresholds_t;
-
-/*-- Information Record: ProtocolRspTime --*/
-typedef struct hfa384x_ProtocolRspTime
-{
- u16 ProtocolRspTime;
-} __WLAN_ATTRIB_PACK__ hfa384x_ProtocolRspTime_t;
-
-/*-- Information Record: ShortRetryLimit --*/
-typedef struct hfa384x_ShortRetryLimit
-{
- u16 ShortRetryLimit;
-} __WLAN_ATTRIB_PACK__ hfa384x_ShortRetryLimit_t;
-
-/*-- Information Record: LongRetryLimit --*/
-typedef struct hfa384x_LongRetryLimit
-{
- u16 LongRetryLimit;
-} __WLAN_ATTRIB_PACK__ hfa384x_LongRetryLimit_t;
-
-/*-- Information Record: MaxTransmitLifetime --*/
-typedef struct hfa384x_MaxTransmitLifetime
-{
- u16 MaxTransmitLifetime;
-} __WLAN_ATTRIB_PACK__ hfa384x_MaxTransmitLifetime_t;
-
-/*-- Information Record: MaxReceiveLifetime --*/
-typedef struct hfa384x_MaxReceiveLifetime
-{
- u16 MaxReceiveLifetime;
-} __WLAN_ATTRIB_PACK__ hfa384x_MaxReceiveLifetime_t;
-
-/*-- Information Record: CFPollable --*/
-typedef struct hfa384x_CFPollable
-{
- u16 CFPollable;
-} __WLAN_ATTRIB_PACK__ hfa384x_CFPollable_t;
-
-/*-- Information Record: AuthenticationAlgorithms --*/
-typedef struct hfa384x_AuthenticationAlgorithms
-{
- u16 AuthenticationType;
- u16 TypeEnabled;
-} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_t;
-
-/*-- Information Record: AuthenticationAlgorithms
-(data only --*/
-typedef struct hfa384x_AuthenticationAlgorithms_data
-{
- u16 AuthenticationType;
- u16 TypeEnabled;
-} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_data_t;
-
-/*-- Information Record: PrivacyOptionImplemented --*/
-typedef struct hfa384x_PrivacyOptionImplemented
-{
- u16 PrivacyOptionImplemented;
-} __WLAN_ATTRIB_PACK__ hfa384x_PrivacyOptionImplemented_t;
-
-/*-- Information Record: OwnMACAddress --*/
-typedef struct hfa384x_OwnMACAddress
-{
- u8 OwnMACAddress[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_OwnMACAddress_t;
-
-/*-- Information Record: PCFInfo --*/
-typedef struct hfa384x_PCFInfo
-{
- u16 MediumOccupancyLimit;
- u16 CFPPeriod;
- u16 CFPMaxDuration;
- u16 CFPFlags;
-} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_t;
-
-/*-- Information Record: PCFInfo (data portion only) --*/
-typedef struct hfa384x_PCFInfo_data
-{
- u16 MediumOccupancyLimit;
- u16 CFPPeriod;
- u16 CFPMaxDuration;
- u16 CFPFlags;
-} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_data_t;
-
-/*--------------------------------------------------------------------
-Information Record Structures: Modem Information Records
---------------------------------------------------------------------*/
-
-/*-- Information Record: PHYType --*/
-typedef struct hfa384x_PHYType
-{
- u16 PHYType;
-} __WLAN_ATTRIB_PACK__ hfa384x_PHYType_t;
-
-/*-- Information Record: CurrentChannel --*/
-typedef struct hfa384x_CurrentChannel
-{
- u16 CurrentChannel;
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentChannel_t;
-
-/*-- Information Record: CurrentPowerState --*/
-typedef struct hfa384x_CurrentPowerState
-{
- u16 CurrentPowerState;
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentPowerState_t;
-
-/*-- Information Record: CCAMode --*/
-typedef struct hfa384x_CCAMode
-{
- u16 CCAMode;
-} __WLAN_ATTRIB_PACK__ hfa384x_CCAMode_t;
-
-/*-- Information Record: SupportedDataRates --*/
-typedef struct hfa384x_SupportedDataRates
-{
- u8 SupportedDataRates[10];
-} __WLAN_ATTRIB_PACK__ hfa384x_SupportedDataRates_t;
-
-/*-- Information Record: LFOStatus --*/
-typedef struct hfa384x_LFOStatus
-{
- u16 TestResults;
- u16 LFOResult;
- u16 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
-{
- u16 searching_on;
- u16 searching_off;
- u16 assoc_on;
- u16 assoc_off;
- u16 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 ((u16)0x44)
-#define HFA384x_FD_TIME_OFF ((u16)0x46)
-#define HFA384x_FD_SWSUPPORT_OFF ((u16)0x4A)
-#define HFA384x_FD_SILENCE_OFF ((u16)0x4A)
-#define HFA384x_FD_SIGNAL_OFF ((u16)0x4B)
-#define HFA384x_FD_RATE_OFF ((u16)0x4C)
-#define HFA384x_FD_RXFLOW_OFF ((u16)0x4D)
-#define HFA384x_FD_RESERVED_OFF ((u16)0x4E)
-#define HFA384x_FD_TXCONTROL_OFF ((u16)0x50)
-/*--------------------------------------------------------------------
-802.11 Header (offset 52-6B)
---------------------------------------------------------------------*/
-#define HFA384x_FD_FRAMECONTROL_OFF ((u16)0x52)
-#define HFA384x_FD_DURATIONID_OFF ((u16)0x54)
-#define HFA384x_FD_ADDRESS1_OFF ((u16)0x56)
-#define HFA384x_FD_ADDRESS2_OFF ((u16)0x5C)
-#define HFA384x_FD_ADDRESS3_OFF ((u16)0x62)
-#define HFA384x_FD_SEQCONTROL_OFF ((u16)0x68)
-#define HFA384x_FD_ADDRESS4_OFF ((u16)0x6A)
-#define HFA384x_FD_DATALEN_OFF ((u16)0x70)
-/*--------------------------------------------------------------------
-802.3 Header (offset 72-7F)
---------------------------------------------------------------------*/
-#define HFA384x_FD_DESTADDRESS_OFF ((u16)0x72)
-#define HFA384x_FD_SRCADDRESS_OFF ((u16)0x78)
-#define HFA384x_FD_DATALENGTH_OFF ((u16)0x7E)
+typedef struct hfa384x_dbmcommsquality {
+ u16 CQdbm_currBSS;
+ u16 ASLdbm_currBSS;
+ u16 ANLdbm_currFC;
+} __attribute__ ((packed)) hfa384x_dbmcommsquality_t;
/*--------------------------------------------------------------------
FRAME STRUCTURES: Communication Frames
@@ -1573,51 +442,46 @@ FRAME STRUCTURES: Communication Frames
Communication Frames: Transmit Frames
--------------------------------------------------------------------*/
/*-- Communication Frame: Transmit Frame Structure --*/
-typedef struct hfa384x_tx_frame
-{
- u16 status;
- u16 reserved1;
- u16 reserved2;
- u32 sw_support;
- u8 tx_retrycount;
- u8 tx_rate;
- u16 tx_control;
+typedef struct hfa384x_tx_frame {
+ u16 status;
+ u16 reserved1;
+ u16 reserved2;
+ u32 sw_support;
+ u8 tx_retrycount;
+ u8 tx_rate;
+ u16 tx_control;
/*-- 802.11 Header Information --*/
- u16 frame_control;
- u16 duration_id;
- u8 address1[6];
- u8 address2[6];
- u8 address3[6];
- u16 sequence_control;
- u8 address4[6];
- u16 data_len; /* little endian format */
+ u16 frame_control;
+ u16 duration_id;
+ u8 address1[6];
+ u8 address2[6];
+ u8 address3[6];
+ u16 sequence_control;
+ u8 address4[6];
+ u16 data_len; /* little endian format */
/*-- 802.3 Header Information --*/
- u8 dest_addr[6];
- u8 src_addr[6];
- u16 data_length; /* big endian format */
-} __WLAN_ATTRIB_PACK__ hfa384x_tx_frame_t;
+ u8 dest_addr[6];
+ u8 src_addr[6];
+ u16 data_length; /* big endian format */
+} __attribute__ ((packed)) hfa384x_tx_frame_t;
/*--------------------------------------------------------------------
Communication Frames: Field Masks for Transmit Frames
--------------------------------------------------------------------*/
/*-- Status Field --*/
-#define HFA384x_TXSTATUS_ACKERR ((u16)BIT5)
-#define HFA384x_TXSTATUS_FORMERR ((u16)BIT3)
-#define HFA384x_TXSTATUS_DISCON ((u16)BIT2)
-#define HFA384x_TXSTATUS_AGEDERR ((u16)BIT1)
-#define HFA384x_TXSTATUS_RETRYERR ((u16)BIT0)
+#define HFA384x_TXSTATUS_ACKERR ((u16)BIT(5))
+#define HFA384x_TXSTATUS_FORMERR ((u16)BIT(3))
+#define HFA384x_TXSTATUS_DISCON ((u16)BIT(2))
+#define HFA384x_TXSTATUS_AGEDERR ((u16)BIT(1))
+#define HFA384x_TXSTATUS_RETRYERR ((u16)BIT(0))
/*-- Transmit Control Field --*/
-#define HFA384x_TX_CFPOLL ((u16)BIT12)
-#define HFA384x_TX_PRST ((u16)BIT11)
-#define HFA384x_TX_MACPORT ((u16)(BIT10 | BIT9 | BIT8))
-#define HFA384x_TX_NOENCRYPT ((u16)BIT7)
-#define HFA384x_TX_RETRYSTRAT ((u16)(BIT6 | BIT5))
-#define HFA384x_TX_STRUCTYPE ((u16)(BIT4 | BIT3))
-#define HFA384x_TX_TXEX ((u16)BIT2)
-#define HFA384x_TX_TXOK ((u16)BIT1)
+#define HFA384x_TX_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define HFA384x_TX_STRUCTYPE ((u16)(BIT(4) | BIT(3)))
+#define HFA384x_TX_TXEX ((u16)BIT(2))
+#define HFA384x_TX_TXOK ((u16)BIT(1))
/*--------------------------------------------------------------------
Communication Frames: Test/Get/Set Field Values for Transmit Frames
--------------------------------------------------------------------*/
@@ -1628,83 +492,53 @@ Communication Frames: Test/Get/Set Field Values for Transmit Frames
HFA384x_TXSTATUS_DISCON|HFA384x_TXSTATUS_AGEDERR|\
HFA384x_TXSTATUS_RETRYERR))
-#define HFA384x_TXSTATUS_ISACKERR(v) ((u16)(((u16)(v)) & HFA384x_TXSTATUS_ACKERR))
-#define HFA384x_TXSTATUS_ISFORMERR(v) ((u16)(((u16)(v)) & HFA384x_TXSTATUS_FORMERR))
-#define HFA384x_TXSTATUS_ISDISCON(v) ((u16)(((u16)(v)) & HFA384x_TXSTATUS_DISCON))
-#define HFA384x_TXSTATUS_ISAGEDERR(v) ((u16)(((u16)(v)) & HFA384x_TXSTATUS_AGEDERR))
-#define HFA384x_TXSTATUS_ISRETRYERR(v) ((u16)(((u16)(v)) & HFA384x_TXSTATUS_RETRYERR))
-
-#define HFA384x_TX_GET(v,m,s) ((((u16)(v))&((u16)(m)))>>((u16)(s)))
-#define HFA384x_TX_SET(v,m,s) ((((u16)(v))<<((u16)(s)))&((u16)(m)))
+#define HFA384x_TX_SET(v, m, s) ((((u16)(v))<<((u16)(s)))&((u16)(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
-{
+typedef struct hfa384x_rx_frame {
/*-- MAC rx descriptor (hfa384x byte order) --*/
- u16 status;
- u32 time;
- u8 silence;
- u8 signal;
- u8 rate;
- u8 rx_flow;
- u16 reserved1;
- u16 reserved2;
+ u16 status;
+ u32 time;
+ u8 silence;
+ u8 signal;
+ u8 rate;
+ u8 rx_flow;
+ u16 reserved1;
+ u16 reserved2;
/*-- 802.11 Header Information (802.11 byte order) --*/
- u16 frame_control;
- u16 duration_id;
- u8 address1[6];
- u8 address2[6];
- u8 address3[6];
- u16 sequence_control;
- u8 address4[6];
- u16 data_len; /* hfa384x (little endian) format */
+ u16 frame_control;
+ u16 duration_id;
+ u8 address1[6];
+ u8 address2[6];
+ u8 address3[6];
+ u16 sequence_control;
+ u8 address4[6];
+ u16 data_len; /* hfa384x (little endian) format */
/*-- 802.3 Header Information --*/
- u8 dest_addr[6];
- u8 src_addr[6];
- u16 data_length; /* IEEE? (big endian) format */
-} __WLAN_ATTRIB_PACK__ hfa384x_rx_frame_t;
+ u8 dest_addr[6];
+ u8 src_addr[6];
+ u16 data_length; /* IEEE? (big endian) format */
+} __attribute__ ((packed)) hfa384x_rx_frame_t;
/*--------------------------------------------------------------------
Communication Frames: Field Masks for Receive Frames
--------------------------------------------------------------------*/
-/*-- Offsets --------*/
-#define HFA384x_RX_DATA_LEN_OFF ((u16)44)
-#define HFA384x_RX_80211HDR_OFF ((u16)14)
-#define HFA384x_RX_DATA_OFF ((u16)60)
/*-- Status Fields --*/
-#define HFA384x_RXSTATUS_MSGTYPE ((u16)(BIT15 | BIT14 | BIT13))
-#define HFA384x_RXSTATUS_MACPORT ((u16)(BIT10 | BIT9 | BIT8))
-#define HFA384x_RXSTATUS_UNDECR ((u16)BIT1)
-#define HFA384x_RXSTATUS_FCSERR ((u16)BIT0)
+#define HFA384x_RXSTATUS_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define HFA384x_RXSTATUS_FCSERR ((u16)BIT(0))
/*--------------------------------------------------------------------
Communication Frames: Test/Get/Set Field Values for Receive Frames
--------------------------------------------------------------------*/
-#define HFA384x_RXSTATUS_MSGTYPE_GET(value) ((u16)((((u16)(value)) & HFA384x_RXSTATUS_MSGTYPE) >> 13))
-#define HFA384x_RXSTATUS_MSGTYPE_SET(value) ((u16)(((u16)(value)) << 13))
#define HFA384x_RXSTATUS_MACPORT_GET(value) ((u16)((((u16)(value)) & HFA384x_RXSTATUS_MACPORT) >> 8))
-#define HFA384x_RXSTATUS_MACPORT_SET(value) ((u16)(((u16)(value)) << 8))
-#define HFA384x_RXSTATUS_ISUNDECR(value) ((u16)(((u16)(value)) & HFA384x_RXSTATUS_UNDECR))
#define HFA384x_RXSTATUS_ISFCSERR(value) ((u16)(((u16)(value)) & HFA384x_RXSTATUS_FCSERR))
/*--------------------------------------------------------------------
FRAME STRUCTURES: Information Types and Information Frame Structures
@@ -1712,7 +546,6 @@ Communication Frames: Test/Get/Set Field Values for Receive Frames
Information Types
--------------------------------------------------------------------*/
#define HFA384x_IT_HANDOVERADDR ((u16)0xF000UL)
-#define HFA384x_IT_HANDOVERDEAUTHADDRESS ((u16)0xF001UL)//AP 1.3.7
#define HFA384x_IT_COMMTALLIES ((u16)0xF100UL)
#define HFA384x_IT_SCANRESULTS ((u16)0xF101UL)
#define HFA384x_IT_CHINFORESULTS ((u16)0xF102UL)
@@ -1730,128 +563,110 @@ Information Frames Structures
----------------------------------------------------------------------
Information Frames: Notification Frame Structures
--------------------------------------------------------------------*/
-/*-- Notification Frame,MAC Mgmt: Handover Address --*/
-typedef struct hfa384x_HandoverAddr
-{
- u16 framelen;
- u16 infotype;
- u8 handover_addr[WLAN_BSSID_LEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_HandoverAddr_t;
/*-- Inquiry Frame, Diagnose: Communication Tallies --*/
-typedef struct hfa384x_CommTallies16
-{
- u16 txunicastframes;
- u16 txmulticastframes;
- u16 txfragments;
- u16 txunicastoctets;
- u16 txmulticastoctets;
- u16 txdeferredtrans;
- u16 txsingleretryframes;
- u16 txmultipleretryframes;
- u16 txretrylimitexceeded;
- u16 txdiscards;
- u16 rxunicastframes;
- u16 rxmulticastframes;
- u16 rxfragments;
- u16 rxunicastoctets;
- u16 rxmulticastoctets;
- u16 rxfcserrors;
- u16 rxdiscardsnobuffer;
- u16 txdiscardswrongsa;
- u16 rxdiscardswepundecr;
- u16 rxmsginmsgfrag;
- u16 rxmsginbadmsgfrag;
-} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies16_t;
-
-typedef struct hfa384x_CommTallies32
-{
- u32 txunicastframes;
- u32 txmulticastframes;
- u32 txfragments;
- u32 txunicastoctets;
- u32 txmulticastoctets;
- u32 txdeferredtrans;
- u32 txsingleretryframes;
- u32 txmultipleretryframes;
- u32 txretrylimitexceeded;
- u32 txdiscards;
- u32 rxunicastframes;
- u32 rxmulticastframes;
- u32 rxfragments;
- u32 rxunicastoctets;
- u32 rxmulticastoctets;
- u32 rxfcserrors;
- u32 rxdiscardsnobuffer;
- u32 txdiscardswrongsa;
- u32 rxdiscardswepundecr;
- u32 rxmsginmsgfrag;
- u32 rxmsginbadmsgfrag;
-} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies32_t;
+typedef struct hfa384x_CommTallies16 {
+ u16 txunicastframes;
+ u16 txmulticastframes;
+ u16 txfragments;
+ u16 txunicastoctets;
+ u16 txmulticastoctets;
+ u16 txdeferredtrans;
+ u16 txsingleretryframes;
+ u16 txmultipleretryframes;
+ u16 txretrylimitexceeded;
+ u16 txdiscards;
+ u16 rxunicastframes;
+ u16 rxmulticastframes;
+ u16 rxfragments;
+ u16 rxunicastoctets;
+ u16 rxmulticastoctets;
+ u16 rxfcserrors;
+ u16 rxdiscardsnobuffer;
+ u16 txdiscardswrongsa;
+ u16 rxdiscardswepundecr;
+ u16 rxmsginmsgfrag;
+ u16 rxmsginbadmsgfrag;
+} __attribute__ ((packed)) hfa384x_CommTallies16_t;
+
+typedef struct hfa384x_CommTallies32 {
+ u32 txunicastframes;
+ u32 txmulticastframes;
+ u32 txfragments;
+ u32 txunicastoctets;
+ u32 txmulticastoctets;
+ u32 txdeferredtrans;
+ u32 txsingleretryframes;
+ u32 txmultipleretryframes;
+ u32 txretrylimitexceeded;
+ u32 txdiscards;
+ u32 rxunicastframes;
+ u32 rxmulticastframes;
+ u32 rxfragments;
+ u32 rxunicastoctets;
+ u32 rxmulticastoctets;
+ u32 rxfcserrors;
+ u32 rxdiscardsnobuffer;
+ u32 txdiscardswrongsa;
+ u32 rxdiscardswepundecr;
+ u32 rxmsginmsgfrag;
+ u32 rxmsginbadmsgfrag;
+} __attribute__ ((packed)) hfa384x_CommTallies32_t;
/*-- Inquiry Frame, Diagnose: Scan Results & Subfields--*/
-typedef struct hfa384x_ScanResultSub
-{
- u16 chid;
- u16 anl;
- u16 sl;
- u8 bssid[WLAN_BSSID_LEN];
- u16 bcnint;
- u16 capinfo;
- hfa384x_bytestr32_t ssid;
- u8 supprates[10]; /* 802.11 info element */
- u16 proberesp_rate;
-} __WLAN_ATTRIB_PACK__ hfa384x_ScanResultSub_t;
-
-typedef struct hfa384x_ScanResult
-{
- u16 rsvd;
- u16 scanreason;
- hfa384x_ScanResultSub_t
- result[HFA384x_SCANRESULT_MAX];
-} __WLAN_ATTRIB_PACK__ hfa384x_ScanResult_t;
+typedef struct hfa384x_ScanResultSub {
+ u16 chid;
+ u16 anl;
+ u16 sl;
+ u8 bssid[WLAN_BSSID_LEN];
+ u16 bcnint;
+ u16 capinfo;
+ hfa384x_bytestr32_t ssid;
+ u8 supprates[10]; /* 802.11 info element */
+ u16 proberesp_rate;
+} __attribute__ ((packed)) hfa384x_ScanResultSub_t;
+
+typedef struct hfa384x_ScanResult {
+ u16 rsvd;
+ u16 scanreason;
+ hfa384x_ScanResultSub_t result[HFA384x_SCANRESULT_MAX];
+} __attribute__ ((packed)) hfa384x_ScanResult_t;
/*-- Inquiry Frame, Diagnose: ChInfo Results & Subfields--*/
-typedef struct hfa384x_ChInfoResultSub
-{
- u16 chid;
- u16 anl;
- u16 pnl;
- u16 active;
-} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResultSub_t;
+typedef struct hfa384x_ChInfoResultSub {
+ u16 chid;
+ u16 anl;
+ u16 pnl;
+ u16 active;
+} __attribute__ ((packed)) hfa384x_ChInfoResultSub_t;
-#define HFA384x_CHINFORESULT_BSSACTIVE BIT0
-#define HFA384x_CHINFORESULT_PCFACTIVE BIT1
+#define HFA384x_CHINFORESULT_BSSACTIVE BIT(0)
+#define HFA384x_CHINFORESULT_PCFACTIVE BIT(1)
-typedef struct hfa384x_ChInfoResult
-{
- u16 scanchannels;
- hfa384x_ChInfoResultSub_t
- result[HFA384x_CHINFORESULT_MAX];
-} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResult_t;
+typedef struct hfa384x_ChInfoResult {
+ u16 scanchannels;
+ hfa384x_ChInfoResultSub_t result[HFA384x_CHINFORESULT_MAX];
+} __attribute__ ((packed)) hfa384x_ChInfoResult_t;
/*-- Inquiry Frame, Diagnose: Host Scan Results & Subfields--*/
-typedef struct hfa384x_HScanResultSub
-{
- u16 chid;
- u16 anl;
- u16 sl;
- u8 bssid[WLAN_BSSID_LEN];
- u16 bcnint;
- u16 capinfo;
- hfa384x_bytestr32_t ssid;
- u8 supprates[10]; /* 802.11 info element */
- u16 proberesp_rate;
- u16 atim;
-} __WLAN_ATTRIB_PACK__ hfa384x_HScanResultSub_t;
-
-typedef struct hfa384x_HScanResult
-{
- u16 nresult;
- u16 rsvd;
- hfa384x_HScanResultSub_t
- result[HFA384x_HSCANRESULT_MAX];
-} __WLAN_ATTRIB_PACK__ hfa384x_HScanResult_t;
+typedef struct hfa384x_HScanResultSub {
+ u16 chid;
+ u16 anl;
+ u16 sl;
+ u8 bssid[WLAN_BSSID_LEN];
+ u16 bcnint;
+ u16 capinfo;
+ hfa384x_bytestr32_t ssid;
+ u8 supprates[10]; /* 802.11 info element */
+ u16 proberesp_rate;
+ u16 atim;
+} __attribute__ ((packed)) hfa384x_HScanResultSub_t;
+
+typedef struct hfa384x_HScanResult {
+ u16 nresult;
+ u16 rsvd;
+ hfa384x_HScanResultSub_t result[HFA384x_HSCANRESULT_MAX];
+} __attribute__ ((packed)) hfa384x_HScanResult_t;
/*-- Unsolicited Frame, MAC Mgmt: LinkStatus --*/
@@ -1863,100 +678,67 @@ typedef struct hfa384x_HScanResult
#define HFA384x_LINK_AP_INRANGE ((u16)5)
#define HFA384x_LINK_ASSOCFAIL ((u16)6)
-typedef struct hfa384x_LinkStatus
-{
- u16 linkstatus;
-} __WLAN_ATTRIB_PACK__ hfa384x_LinkStatus_t;
-
+typedef struct hfa384x_LinkStatus {
+ u16 linkstatus;
+} __attribute__ ((packed)) hfa384x_LinkStatus_t;
/*-- Unsolicited Frame, MAC Mgmt: AssociationStatus (--*/
#define HFA384x_ASSOCSTATUS_STAASSOC ((u16)1)
#define HFA384x_ASSOCSTATUS_REASSOC ((u16)2)
-#define HFA384x_ASSOCSTATUS_DISASSOC ((u16)3)
-#define HFA384x_ASSOCSTATUS_ASSOCFAIL ((u16)4)
#define HFA384x_ASSOCSTATUS_AUTHFAIL ((u16)5)
-typedef struct hfa384x_AssocStatus
-{
- u16 assocstatus;
- u8 sta_addr[WLAN_ADDR_LEN];
+typedef struct hfa384x_AssocStatus {
+ u16 assocstatus;
+ u8 sta_addr[ETH_ALEN];
/* old_ap_addr is only valid if assocstatus == 2 */
- u8 old_ap_addr[WLAN_ADDR_LEN];
- u16 reason;
- u16 reserved;
-} __WLAN_ATTRIB_PACK__ hfa384x_AssocStatus_t;
+ u8 old_ap_addr[ETH_ALEN];
+ u16 reason;
+ u16 reserved;
+} __attribute__ ((packed)) hfa384x_AssocStatus_t;
/*-- Unsolicited Frame, MAC Mgmt: AuthRequest (AP Only) --*/
-typedef struct hfa384x_AuthRequest
-{
- u8 sta_addr[WLAN_ADDR_LEN];
- u16 algorithm;
-} __WLAN_ATTRIB_PACK__ hfa384x_AuthReq_t;
-
-/*-- Unsolicited Frame, MAC Mgmt: AssocRequest (AP Only) --*/
-
-typedef struct hfa384x_AssocRequest
-{
- u8 sta_addr[WLAN_ADDR_LEN];
- u16 type;
- u8 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
-{
- u8 sender[WLAN_ADDR_LEN];
- u8 dest[WLAN_ADDR_LEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_MicFailure_t;
+typedef struct hfa384x_AuthRequest {
+ u8 sta_addr[ETH_ALEN];
+ u16 algorithm;
+} __attribute__ ((packed)) hfa384x_AuthReq_t;
/*-- Unsolicited Frame, MAC Mgmt: PSUserCount (AP Only) --*/
-typedef struct hfa384x_PSUserCount
-{
- u16 usercnt;
-} __WLAN_ATTRIB_PACK__ hfa384x_PSUserCount_t;
+typedef struct hfa384x_PSUserCount {
+ u16 usercnt;
+} __attribute__ ((packed)) hfa384x_PSUserCount_t;
-typedef struct hfa384x_KeyIDChanged
-{
- u8 sta_addr[WLAN_ADDR_LEN];
- u16 keyid;
-} __WLAN_ATTRIB_PACK__ hfa384x_KeyIDChanged_t;
+typedef struct hfa384x_KeyIDChanged {
+ u8 sta_addr[ETH_ALEN];
+ u16 keyid;
+} __attribute__ ((packed)) 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
-{
- u16 framelen;
- u16 infotype;
- hfa384x_infodata_t info;
-} __WLAN_ATTRIB_PACK__ hfa384x_InfFrame_t;
+ 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;
+} __attribute__ ((packed)) hfa384x_infodata_t;
+
+typedef struct hfa384x_InfFrame {
+ u16 framelen;
+ u16 infotype;
+ hfa384x_infodata_t info;
+} __attribute__ ((packed)) hfa384x_InfFrame_t;
/*--------------------------------------------------------------------
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
@@ -1966,7 +748,6 @@ USB Packet structures and constants.
#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
@@ -1982,380 +763,135 @@ USB Packet structures and constants.
/* Request (bulk OUT) packet contents */
typedef struct hfa384x_usb_txfrm {
- hfa384x_tx_frame_t desc;
- u8 data[WLAN_DATA_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_txfrm_t;
+ hfa384x_tx_frame_t desc;
+ u8 data[WLAN_DATA_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_txfrm_t;
typedef struct hfa384x_usb_cmdreq {
- u16 type;
- u16 cmd;
- u16 parm0;
- u16 parm1;
- u16 parm2;
- u8 pad[54];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdreq_t;
+ u16 type;
+ u16 cmd;
+ u16 parm0;
+ u16 parm1;
+ u16 parm2;
+ u8 pad[54];
+} __attribute__ ((packed)) hfa384x_usb_cmdreq_t;
typedef struct hfa384x_usb_wridreq {
- u16 type;
- u16 frmlen;
- u16 rid;
- u8 data[HFA384x_RIDDATA_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_wridreq_t;
+ u16 type;
+ u16 frmlen;
+ u16 rid;
+ u8 data[HFA384x_RIDDATA_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_wridreq_t;
typedef struct hfa384x_usb_rridreq {
- u16 type;
- u16 frmlen;
- u16 rid;
- u8 pad[58];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridreq_t;
+ u16 type;
+ u16 frmlen;
+ u16 rid;
+ u8 pad[58];
+} __attribute__ ((packed)) hfa384x_usb_rridreq_t;
typedef struct hfa384x_usb_wmemreq {
- u16 type;
- u16 frmlen;
- u16 offset;
- u16 page;
- u8 data[HFA384x_USB_RWMEM_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_wmemreq_t;
+ u16 type;
+ u16 frmlen;
+ u16 offset;
+ u16 page;
+ u8 data[HFA384x_USB_RWMEM_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_wmemreq_t;
typedef struct hfa384x_usb_rmemreq {
- u16 type;
- u16 frmlen;
- u16 offset;
- u16 page;
- u8 pad[56];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemreq_t;
+ u16 type;
+ u16 frmlen;
+ u16 offset;
+ u16 page;
+ u8 pad[56];
+} __attribute__ ((packed)) hfa384x_usb_rmemreq_t;
/*------------------------------------*/
/* Response (bulk IN) packet contents */
typedef struct hfa384x_usb_rxfrm {
- hfa384x_rx_frame_t desc;
- u8 data[WLAN_DATA_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rxfrm_t;
+ hfa384x_rx_frame_t desc;
+ u8 data[WLAN_DATA_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_rxfrm_t;
typedef struct hfa384x_usb_infofrm {
- u16 type;
- hfa384x_InfFrame_t info;
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_infofrm_t;
+ u16 type;
+ hfa384x_InfFrame_t info;
+} __attribute__ ((packed)) hfa384x_usb_infofrm_t;
typedef struct hfa384x_usb_statusresp {
- u16 type;
- u16 status;
- u16 resp0;
- u16 resp1;
- u16 resp2;
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdresp_t;
+ u16 type;
+ u16 status;
+ u16 resp0;
+ u16 resp1;
+ u16 resp2;
+} __attribute__ ((packed)) hfa384x_usb_cmdresp_t;
typedef hfa384x_usb_cmdresp_t hfa384x_usb_wridresp_t;
typedef struct hfa384x_usb_rridresp {
- u16 type;
- u16 frmlen;
- u16 rid;
- u8 data[HFA384x_RIDDATA_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridresp_t;
+ u16 type;
+ u16 frmlen;
+ u16 rid;
+ u8 data[HFA384x_RIDDATA_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_rridresp_t;
typedef hfa384x_usb_cmdresp_t hfa384x_usb_wmemresp_t;
typedef struct hfa384x_usb_rmemresp {
- u16 type;
- u16 frmlen;
- u8 data[HFA384x_USB_RWMEM_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemresp_t;
+ u16 type;
+ u16 frmlen;
+ u8 data[HFA384x_USB_RWMEM_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_rmemresp_t;
typedef struct hfa384x_usb_bufavail {
- u16 type;
- u16 frmlen;
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_bufavail_t;
+ u16 type;
+ u16 frmlen;
+} __attribute__ ((packed)) hfa384x_usb_bufavail_t;
typedef struct hfa384x_usb_error {
- u16 type;
- u16 errortype;
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_error_t;
+ u16 type;
+ u16 errortype;
+} __attribute__ ((packed)) hfa384x_usb_error_t;
/*----------------------------------------------------------*/
/* Unions for packaging all the known packet types together */
typedef union hfa384x_usbout {
- u16 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;
+ u16 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;
+} __attribute__ ((packed)) hfa384x_usbout_t;
typedef union hfa384x_usbin {
- u16 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;
- u8 boguspad[3000];
-} __WLAN_ATTRIB_PACK__ hfa384x_usbin_t;
-
-/*--------------------------------------------------------------------
-PD record structures.
---------------------------------------------------------------------*/
-
-typedef struct hfa384x_pdr_pcb_partnum
-{
- u8 num[8];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_partnum_t;
-
-typedef struct hfa384x_pdr_pcb_tracenum
-{
- u8 num[8];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_tracenum_t;
-
-typedef struct hfa384x_pdr_nic_serial
-{
- u8 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
-{
- u8 size[12]; /* units of KB */
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_ramsize_t;
-
-typedef struct hfa384x_pdr_mfisuprange
-{
- u16 id;
- u16 variant;
- u16 bottom;
- u16 top;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mfisuprange_t;
-
-typedef struct hfa384x_pdr_cfisuprange
-{
- u16 id;
- u16 variant;
- u16 bottom;
- u16 top;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_cfisuprange_t;
-
-typedef struct hfa384x_pdr_nicid
-{
- u16 id;
- u16 variant;
- u16 major;
- u16 minor;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nicid_t;
-
-
-typedef struct hfa384x_pdr_refdac_measurements
-{
- u16 value[0];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_measurements_t;
-
-typedef struct hfa384x_pdr_vgdac_measurements
-{
- u16 value[0];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_measurements_t;
-
-typedef struct hfa384x_pdr_level_comp_measurements
-{
- u16 value[0];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_compc_measurements_t;
-
-typedef struct hfa384x_pdr_mac_address
-{
- u8 addr[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mac_address_t;
-
-typedef struct hfa384x_pdr_mkk_callname
-{
- u8 callname[8];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mkk_callname_t;
-
-typedef struct hfa384x_pdr_regdomain
-{
- u16 numdomains;
- u16 domain[5];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_regdomain_t;
-
-typedef struct hfa384x_pdr_allowed_channel
-{
- u16 ch_bitmap;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_allowed_channel_t;
-
-typedef struct hfa384x_pdr_default_channel
-{
- u16 channel;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_default_channel_t;
-
-typedef struct hfa384x_pdr_privacy_option
-{
- u16 available;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_privacy_option_t;
-
-typedef struct hfa384x_pdr_temptype
-{
- u16 type;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_temptype_t;
-
-typedef struct hfa384x_pdr_refdac_setup
-{
- u16 ch_value[14];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_setup_t;
-
-typedef struct hfa384x_pdr_vgdac_setup
-{
- u16 ch_value[14];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_setup_t;
-
-typedef struct hfa384x_pdr_level_comp_setup
-{
- u16 ch_value[14];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_comp_setup_t;
-
-typedef struct hfa384x_pdr_trimdac_setup
-{
- u16 trimidac;
- u16 trimqdac;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_trimdac_setup_t;
-
-typedef struct hfa384x_pdr_ifr_setting
-{
- u16 value[3];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_ifr_setting_t;
-
-typedef struct hfa384x_pdr_rfr_setting
-{
- u16 value[3];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_rfr_setting_t;
-
-typedef struct hfa384x_pdr_hfa3861_baseline
-{
- u16 value[50];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_baseline_t;
-
-typedef struct hfa384x_pdr_hfa3861_shadow
-{
- u32 value[32];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_shadow_t;
-
-typedef struct hfa384x_pdr_hfa3861_ifrf
-{
- u32 value[20];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_ifrf_t;
-
-typedef struct hfa384x_pdr_hfa3861_chcalsp
-{
- u16 value[14];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcalsp_t;
-
-typedef struct hfa384x_pdr_hfa3861_chcali
-{
- u16 value[17];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcali_t;
-
-typedef struct hfa384x_pdr_hfa3861_nic_config
-{
- u16 config_bitmap;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_config_t;
-
-typedef struct hfa384x_pdr_hfo_delay
-{
- u8 hfo_delay;
-} __WLAN_ATTRIB_PACK__ hfa384x_hfo_delay_t;
-
-typedef struct hfa384x_pdr_hfa3861_manf_testsp
-{
- u16 value[30];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testsp_t;
-
-typedef struct hfa384x_pdr_hfa3861_manf_testi
-{
- u16 value[30];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testi_t;
-
-typedef struct hfa384x_end_of_pda
-{
- u16 crc;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_end_of_pda_t;
-
-typedef struct hfa384x_pdrec
-{
- u16 len; /* in words */
- u16 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;
-
+ u16 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;
+ u8 boguspad[3000];
+} __attribute__ ((packed)) hfa384x_usbin_t;
#ifdef __KERNEL__
/*--------------------------------------------------------------------
--- MAC state structure, argument to all functions --
--- Also, a collection of support types --
--------------------------------------------------------------------*/
-typedef struct hfa384x_statusresult
-{
- u16 status;
- u16 resp0;
- u16 resp1;
- u16 resp2;
+typedef struct hfa384x_statusresult {
+ u16 status;
+ u16 resp0;
+ u16 resp1;
+ u16 resp2;
} hfa384x_cmdresult_t;
/* USB Control Exchange (CTLX):
@@ -2365,20 +901,16 @@ typedef struct hfa384x_statusresult
/* 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
-{
- u16 rid;
- const void *riddata;
- unsigned int riddata_len;
+typedef struct hfa384x_rridresult {
+ u16 rid;
+ const void *riddata;
+ unsigned int riddata_len;
} hfa384x_rridresult_t;
enum ctlx_state {
- CTLX_START = 0, /* Start state, not queued */
+ CTLX_START = 0, /* Start state, not queued */
- CTLX_COMPLETE, /* CTLX successfully completed */
+ CTLX_COMPLETE, /* CTLX successfully completed */
CTLX_REQ_FAILED, /* OUT URB completed w/ error */
CTLX_PENDING, /* Queued, data valid */
@@ -2386,114 +918,98 @@ enum ctlx_state {
CTLX_REQ_COMPLETE, /* OUT URB complete */
CTLX_RESP_COMPLETE /* IN URB received */
};
-typedef enum ctlx_state CTLX_STATE;
+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_cmdcb_t) (struct hfa384x *, const struct hfa384x_usbctlx *);
-typedef void (*ctlx_usercb_t)(
- struct hfa384x *hw,
- void *ctlxresult,
- void *usercb_data);
+typedef void (*ctlx_usercb_t) (struct hfa384x *hw,
+ void *ctlxresult, void *usercb_data);
-typedef struct hfa384x_usbctlx
-{
- struct list_head list;
+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) */
+ 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 */
+ CTLX_STATE state; /* Tracks running state */
- struct completion done;
- volatile int reapable; /* Food for the reaper task */
+ 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 */
+ 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 */
+ 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;
+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;
-typedef struct hfa484x_metacmd
-{
- u16 cmd;
+typedef struct hfa484x_metacmd {
+ u16 cmd;
- u16 parm0;
- u16 parm1;
- u16 parm2;
+ u16 parm0;
+ u16 parm1;
+ u16 parm2;
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_COMMENT_MAX 80 /* Max. length of user comment string. */
-#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. */
+#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
-{
- unsigned int cnt;
- u8 addr[WLAN_AUTH_MAX][WLAN_ADDR_LEN];
- u8 assoc[WLAN_AUTH_MAX];
+typedef struct prism2sta_authlist {
+ unsigned int cnt;
+ u8 addr[WLAN_AUTH_MAX][ETH_ALEN];
+ u8 assoc[WLAN_AUTH_MAX];
} prism2sta_authlist_t;
-typedef struct prism2sta_accesslist
-{
- unsigned int modify;
- unsigned int cnt;
- u8 addr[WLAN_ACCESS_MAX][WLAN_ADDR_LEN];
- unsigned int cnt1;
- u8 addr1[WLAN_ACCESS_MAX][WLAN_ADDR_LEN];
+typedef struct prism2sta_accesslist {
+ unsigned int modify;
+ unsigned int cnt;
+ u8 addr[WLAN_ACCESS_MAX][ETH_ALEN];
+ unsigned int cnt1;
+ u8 addr1[WLAN_ACCESS_MAX][ETH_ALEN];
} prism2sta_accesslist_t;
-typedef struct hfa384x
-{
+typedef struct hfa384x {
/* 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 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 timer_list throttle;
- struct tasklet_struct reaper_bh;
- struct tasklet_struct completion_bh;
+ struct tasklet_struct reaper_bh;
+ struct tasklet_struct completion_bh;
- struct work_struct usb_work;
+ struct work_struct usb_work;
- unsigned long usb_flags;
+ unsigned long usb_flags;
#define THROTTLE_RX 0
#define THROTTLE_TX 1
#define WORK_RX_HALT 2
@@ -2501,292 +1017,168 @@ typedef struct hfa384x
#define WORK_RX_RESUME 4
#define WORK_TX_RESUME 5
- unsigned short req_timer_done:1;
- unsigned short resp_timer_done:1;
+ unsigned short req_timer_done:1;
+ unsigned short resp_timer_done:1;
- int endp_in;
- int endp_out;
+ int endp_in;
+ int endp_out;
- int sniff_fcs;
- int sniff_channel;
- int sniff_truncate;
- int sniffhdr;
+ int sniff_fcs;
+ int sniff_channel;
+ int sniff_truncate;
+ int sniffhdr;
- wait_queue_head_t cmdq; /* wait queue itself */
+ wait_queue_head_t cmdq; /* wait queue itself */
/* Controller state */
- u32 state;
- u32 isap;
- u8 port_enabled[HFA384x_NUMPORTS_MAX];
+ u32 state;
+ u32 isap;
+ u8 port_enabled[HFA384x_NUMPORTS_MAX];
/* Download support */
- unsigned int dlstate;
- hfa384x_downloadbuffer_t bufinfo;
- u16 dltimeout;
+ unsigned int dlstate;
+ hfa384x_downloadbuffer_t bufinfo;
+ u16 dltimeout;
- 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 */
+ 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;
+ wlandevice_t *wlandev;
/* Timer to allow for the deferred processing of linkstatus messages */
- struct work_struct link_bh;
+ struct work_struct link_bh;
- struct work_struct commsqual_bh;
- hfa384x_commsquality_t qual;
- struct timer_list commsqual_timer;
+ struct work_struct commsqual_bh;
+ hfa384x_commsquality_t qual;
+ struct timer_list commsqual_timer;
u16 link_status;
u16 link_status_new;
- struct sk_buff_head authq;
+ struct sk_buff_head authq;
/* And here we have stuff that used to be in priv */
/* State variables */
- unsigned int presniff_port_type;
- u16 presniff_wepflags;
- u32 dot11_desired_bss_type;
+ unsigned int presniff_port_type;
+ u16 presniff_wepflags;
+ u32 dot11_desired_bss_type;
- int dbmadjust;
+ int dbmadjust;
/* Group Addresses - right now, there are up to a total
- of MAX_GRP_ADDR group addresses */
- u8 dot11_grp_addr[MAX_GRP_ADDR][WLAN_ADDR_LEN];
- unsigned int dot11_grpcnt;
+ of MAX_GRP_ADDR group addresses */
+ u8 dot11_grp_addr[MAX_GRP_ADDR][ETH_ALEN];
+ unsigned int 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;
- u16 mm_mods;
+ hfa384x_compident_t ident_nic;
+ hfa384x_compident_t ident_pri_fw;
+ hfa384x_compident_t ident_sta_fw;
+ hfa384x_compident_t ident_ap_fw;
+ u16 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;
+ 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 */
+ 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 */
- u32 psusercount; /* Power save user count. */
- hfa384x_CommTallies32_t tallies; /* Communication tallies. */
- u8 comment[WLAN_COMMENT_MAX+1]; /* User comment */
+ u32 psusercount; /* Power save user count. */
+ hfa384x_CommTallies32_t tallies; /* Communication tallies. */
+ u8 comment[WLAN_COMMENT_MAX + 1]; /* User comment */
/* Channel Info request results (AP only) */
struct {
- atomic_t done;
- u8 count;
- hfa384x_ChInfoResult_t results;
+ atomic_t done;
+ u8 count;
+ hfa384x_ChInfoResult_t results;
} channel_info;
- hfa384x_InfFrame_t *scanresults;
+ hfa384x_InfFrame_t *scanresults;
-
- prism2sta_authlist_t authlist; /* Authenticated station list. */
- unsigned int accessmode; /* Access mode. */
- prism2sta_accesslist_t allow; /* Allowed station list. */
- prism2sta_accesslist_t deny; /* Denied station list. */
+ prism2sta_authlist_t authlist; /* Authenticated station list. */
+ unsigned int accessmode; /* Access mode. */
+ prism2sta_accesslist_t allow; /* Allowed station list. */
+ prism2sta_accesslist_t deny; /* Denied station list. */
} hfa384x_t;
-/*=============================================================*/
-/*--- Function Declarations -----------------------------------*/
-/*=============================================================*/
-void
-hfa384x_create(
- hfa384x_t *hw,
- struct usb_device *usb);
-
+void hfa384x_create(hfa384x_t *hw, struct usb_device *usb);
void hfa384x_destroy(hfa384x_t *hw);
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, u16 macport);
-int
-hfa384x_drvr_enable(hfa384x_t *hw, u16 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, u32 daddr, void* buf, u32 len);
-int
-hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
-int
-hfa384x_drvr_handover( hfa384x_t *hw, u8 *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, u32 address, u32 *result);
-int
-hfa384x_drvr_mmi_write(hfa384x_t *hw, u32 address, u32 data);
-int
-hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr);
-int
-hfa384x_drvr_ramdl_disable(hfa384x_t *hw);
-int
-hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void* buf, u32 len);
-int
-hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len);
-int
-hfa384x_drvr_scanresults( hfa384x_t *hw);
-
-int
-hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
-
-static inline int
-hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val)
-{
- int result = 0;
+hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis);
+int hfa384x_drvr_commtallies(hfa384x_t *hw);
+int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport);
+int hfa384x_drvr_enable(hfa384x_t *hw, u16 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, u32 daddr, void *buf, u32 len);
+int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
+int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr);
+int hfa384x_drvr_ramdl_disable(hfa384x_t *hw);
+int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len);
+int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len);
+int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
+
+static inline int hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val)
+{
+ int result = 0;
result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16));
- if ( result == 0 ) {
- *((u16*)val) = hfa384x2host_16(*((u16*)val));
- }
+ if (result == 0)
+ *((u16 *) val) = le16_to_cpu(*((u16 *) val));
return result;
}
-static inline int
-hfa384x_drvr_getconfig32(hfa384x_t *hw, u16 rid, void *val)
-{
- int result = 0;
-
- result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u32));
- if ( result == 0 ) {
- *((u32*)val) = hfa384x2host_32(*((u32*)val));
- }
-
- return result;
-}
-
-static inline int
-hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val)
-{
- u16 value = host2hfa384x_16(val);
- return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
-}
-
-static inline int
-hfa384x_drvr_setconfig32(hfa384x_t *hw, u16 rid, u32 val)
+static inline int hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val)
{
- u32 value = host2hfa384x_32(val);
+ u16 value = cpu_to_le16(val);
return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
}
int
-hfa384x_drvr_getconfig_async(hfa384x_t *hw,
- u16 rid,
- ctlx_usercb_t usercb,
- void *usercb_data);
+hfa384x_drvr_getconfig_async(hfa384x_t *hw,
+ u16 rid, ctlx_usercb_t usercb, void *usercb_data);
int
hfa384x_drvr_setconfig_async(hfa384x_t *hw,
- u16 rid,
- void *buf,
- u16 len,
- ctlx_usercb_t usercb,
- void *usercb_data);
+ u16 rid,
+ void *buf,
+ u16 len, ctlx_usercb_t usercb, void *usercb_data);
static inline int
hfa384x_drvr_setconfig16_async(hfa384x_t *hw, u16 rid, u16 val)
{
- u16 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, u16 rid, u32 val)
-{
- u32 value = host2hfa384x_32(val);
+ u16 value = cpu_to_le16(val);
return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value),
- NULL , NULL);
+ 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, u16 macport);
-int
-hfa384x_cmd_disable(hfa384x_t *hw, u16 macport);
-int
-hfa384x_cmd_diagnose(hfa384x_t *hw);
-int
-hfa384x_cmd_allocate(hfa384x_t *hw, u16 len);
-int
-hfa384x_cmd_transmit(hfa384x_t *hw, u16 reclaim, u16 qos, u16 fid);
-int
-hfa384x_cmd_clearpersist(hfa384x_t *hw, u16 fid);
-int
-hfa384x_cmd_access(hfa384x_t *hw, u16 write, u16 rid, void *buf, u16 len);
-int
-hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable);
-int
-hfa384x_cmd_download(
- hfa384x_t *hw,
- u16 mode,
- u16 lowaddr,
- u16 highaddr,
- u16 codelen);
-int
-hfa384x_cmd_aux_enable(hfa384x_t *hw, int force);
-int
-hfa384x_cmd_aux_disable(hfa384x_t *hw);
+int hfa384x_drvr_start(hfa384x_t *hw);
+int hfa384x_drvr_stop(hfa384x_t *hw);
int
-hfa384x_copy_from_bap(
- hfa384x_t *hw,
- u16 bap,
- u16 id,
- u16 offset,
- void *buf,
- unsigned int len);
+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, u16 macport);
+int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport);
+int hfa384x_cmd_allocate(hfa384x_t *hw, u16 len);
+int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable);
int
-hfa384x_copy_to_bap(
- hfa384x_t *hw,
- u16 bap,
- u16 id,
- u16 offset,
- void *buf,
- unsigned int len);
-void
-hfa384x_copy_from_aux(
- hfa384x_t *hw,
- u32 cardaddr,
- u32 auxctl,
- void *buf,
- unsigned int len);
-void
-hfa384x_copy_to_aux(
- hfa384x_t *hw,
- u32 cardaddr,
- u32 auxctl,
- void *buf,
- unsigned int len);
+hfa384x_cmd_download(hfa384x_t *hw,
+ u16 mode, u16 lowaddr, u16 highaddr, u16 codelen);
#endif /* __KERNEL__ */
-#endif /* _HFA384x_H */
+#endif /* _HFA384x_H */
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
index 8a75b50f863..888198c9a10 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -110,10 +110,6 @@
* --------------------------------------------------------------------
*/
-/*================================================================*/
-/* System Includes */
-#define WLAN_DBVAR prism2_debug
-
#include <linux/version.h>
#include <linux/module.h>
@@ -130,8 +126,7 @@
#include <asm/bitops.h>
#include <linux/list.h>
#include <linux/usb.h>
-
-#include "wlan_compat.h"
+#include <linux/byteorder/generic.h>
#define SUBMIT_URB(u,f) usb_submit_urb(u,f)
@@ -150,69 +145,43 @@
#include "hfa384x.h"
#include "prism2mgmt.h"
-/*================================================================*/
-/* Local Constants */
-
-enum cmd_mode
-{
- DOWAIT = 0,
- DOASYNC
+enum cmd_mode {
+ DOWAIT = 0,
+ DOASYNC
};
typedef enum cmd_mode CMD_MODE;
#define THROTTLE_JIFFIES (HZ/8)
-
-/*================================================================*/
-/* Local Macros */
+#define URB_ASYNC_UNLINK 0
+#define USB_QUEUE_BULK 0
#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);
+static void dbprint_urb(struct urb *urb);
#endif
static void
-hfa384x_int_rxmonitor(
- wlandevice_t *wlandev,
- hfa384x_usb_rxfrm_t *rxfrm);
+hfa384x_int_rxmonitor(wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *rxfrm);
-static void
-hfa384x_usb_defer(struct work_struct *data);
+static void hfa384x_usb_defer(struct work_struct *data);
-static int
-submit_rx_urb(hfa384x_t *hw, gfp_t flags);
+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);
+static int submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t flags);
/*---------------------------------------------------*/
/* Callbacks */
-static void
-hfa384x_usbout_callback(struct urb *urb);
-static void
-hfa384x_ctlxout_callback(struct urb *urb);
-static void
-hfa384x_usbin_callback(struct urb *urb);
+static void hfa384x_usbout_callback(struct urb *urb);
+static void hfa384x_ctlxout_callback(struct urb *urb);
+static void hfa384x_usbin_callback(struct urb *urb);
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_rx(wlandevice_t *wlandev, struct sk_buff *skb);
-static void
-hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
+static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
static void
hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout);
@@ -223,123 +192,94 @@ static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
/*---------------------------------------------------*/
/* Functions to support the prism2 usb command queue */
-static void
-hfa384x_usbctlxq_run(hfa384x_t *hw);
+static void hfa384x_usbctlxq_run(hfa384x_t *hw);
-static void
-hfa384x_usbctlx_reqtimerfn(unsigned long data);
+static void hfa384x_usbctlx_reqtimerfn(unsigned long data);
-static void
-hfa384x_usbctlx_resptimerfn(unsigned long data);
+static void hfa384x_usbctlx_resptimerfn(unsigned long data);
-static void
-hfa384x_usb_throttlefn(unsigned long data);
+static void hfa384x_usb_throttlefn(unsigned long data);
-static void
-hfa384x_usbctlx_completion_task(unsigned long data);
+static void hfa384x_usbctlx_completion_task(unsigned long data);
-static void
-hfa384x_usbctlx_reaper_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 int hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
-static void
-unlocked_usbctlx_complete(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*);
+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);
+ 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_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
-static void
-hfa384x_cb_rrid(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);
+ hfa384x_cmdresult_t *result);
static void
usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
- hfa384x_rridresult_t *result);
+ 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);
+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,
- u16 rid,
- void *riddata,
- unsigned int riddatalen,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data);
+hfa384x_dorrid(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 rid,
+ void *riddata,
+ unsigned int riddatalen,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
static int
-hfa384x_dowrid(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 rid,
- void *riddata,
- unsigned int riddatalen,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data);
+hfa384x_dowrid(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 rid,
+ void *riddata,
+ unsigned int riddatalen,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
static int
-hfa384x_dormem(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 page,
- u16 offset,
- void *data,
- unsigned int len,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data);
+hfa384x_dormem(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 page,
+ u16 offset,
+ void *data,
+ unsigned int len,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
static int
-hfa384x_dowmem(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 page,
- u16 offset,
- void *data,
- unsigned int len,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data);
+hfa384x_dowmem(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 page,
+ u16 offset,
+ void *data,
+ unsigned int len,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
-static int
-hfa384x_isgood_pdrcode(u16 pdrcode);
+static int hfa384x_isgood_pdrcode(u16 pdrcode);
-/*================================================================*/
-/* Function Definitions */
-static inline const char* ctlxstr(CTLX_STATE s)
+static inline const char *ctlxstr(CTLX_STATE s)
{
- static const char* ctlx_str[] = {
+ static const char *ctlx_str[] = {
"Initial state",
"Complete",
"Request failed",
@@ -352,36 +292,36 @@ static inline const char* ctlxstr(CTLX_STATE s)
return ctlx_str[s];
};
-
-static inline hfa384x_usbctlx_t*
-get_active_ctlx(hfa384x_t *hw)
+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)
+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", (unsigned int)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", (unsigned int)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", (unsigned int)urb->context);
- WLAN_LOG_DEBUG(3,"urb->complete=0x%08x\n", (unsigned int)urb->complete);
+ pr_debug("urb->pipe=0x%08x\n", urb->pipe);
+ pr_debug("urb->status=0x%08x\n", urb->status);
+ pr_debug("urb->transfer_flags=0x%08x\n", urb->transfer_flags);
+ pr_debug("urb->transfer_buffer=0x%08x\n",
+ (unsigned int)urb->transfer_buffer);
+ pr_debug("urb->transfer_buffer_length=0x%08x\n",
+ urb->transfer_buffer_length);
+ pr_debug("urb->actual_length=0x%08x\n", urb->actual_length);
+ pr_debug("urb->bandwidth=0x%08x\n", urb->bandwidth);
+ pr_debug("urb->setup_packet(ctl)=0x%08x\n",
+ (unsigned int)urb->setup_packet);
+ pr_debug("urb->start_frame(iso/irq)=0x%08x\n",
+ urb->start_frame);
+ pr_debug("urb->interval(irq)=0x%08x\n", urb->interval);
+ pr_debug("urb->error_count(iso)=0x%08x\n", urb->error_count);
+ pr_debug("urb->timeout=0x%08x\n", urb->timeout);
+ pr_debug("urb->context=0x%08x\n", (unsigned int)urb->context);
+ pr_debug("urb->complete=0x%08x\n",
+ (unsigned int)urb->complete);
}
#endif
-
/*----------------------------------------------------------------
* submit_rx_urb
*
@@ -398,14 +338,11 @@ dbprint_urb(struct urb* urb)
* Call context:
* Any
----------------------------------------------------------------*/
-static int
-submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
+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;
@@ -414,21 +351,22 @@ submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
/* 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->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)) {
+ 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) )
+ printk(KERN_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);
}
}
@@ -439,9 +377,7 @@ submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
hw->rx_urb_skb = NULL;
}
- done:
-
- DBFEXIT;
+done:
return result;
}
@@ -463,24 +399,23 @@ submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
* Call context:
* Any
----------------------------------------------------------------*/
-static int
-submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
+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 (netif_running(netdev)) {
- if ( !hw->wlandev->hwremoved && !test_bit(WORK_TX_HALT, &hw->usb_flags) ) {
+ 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);
+ printk(KERN_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) {
@@ -489,8 +424,6 @@ submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
}
}
- DBFEXIT;
-
return result;
}
@@ -510,27 +443,22 @@ submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
* Call context:
* process (by design)
----------------------------------------------------------------*/
-static void
-hfa384x_usb_defer(struct work_struct *data)
+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;
+ if (hw->wlandev->hwremoved)
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! */
+ usb_kill_urb(&hw->rx_urb); /* Cannot be holding spinlock! */
ret = usb_clear_halt(hw->usb, hw->endp_in);
if (ret != 0) {
@@ -539,14 +467,14 @@ hfa384x_usb_defer(struct work_struct *data)
netdev->name, ret);
} else {
printk(KERN_INFO "%s rx pipe reset complete.\n",
- netdev->name);
+ 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) ) {
+ if (test_bit(WORK_RX_RESUME, &hw->usb_flags)) {
int ret;
ret = submit_rx_urb(hw, GFP_KERNEL);
@@ -570,7 +498,7 @@ hfa384x_usb_defer(struct work_struct *data)
netdev->name, ret);
} else {
printk(KERN_INFO "%s tx pipe reset complete.\n",
- netdev->name);
+ netdev->name);
clear_bit(WORK_TX_HALT, &hw->usb_flags);
set_bit(WORK_TX_RESUME, &hw->usb_flags);
@@ -583,14 +511,10 @@ hfa384x_usb_defer(struct work_struct *data)
}
/* Resume transmitting. */
- if ( test_and_clear_bit(WORK_TX_RESUME, &hw->usb_flags) ) {
+ if (test_and_clear_bit(WORK_TX_RESUME, &hw->usb_flags))
netif_wake_queue(hw->wlandev->netdev);
- }
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_create
*
@@ -612,11 +536,8 @@ hfa384x_usb_defer(struct work_struct *data)
* Call context:
* process
----------------------------------------------------------------*/
-void
-hfa384x_create( hfa384x_t *hw, struct usb_device *usb)
+void hfa384x_create(hfa384x_t *hw, struct usb_device *usb)
{
- DBFENTER;
-
memset(hw, 0, sizeof(hfa384x_t));
hw->usb = usb;
@@ -638,11 +559,9 @@ hfa384x_create( hfa384x_t *hw, struct usb_device *usb)
skb_queue_head_init(&hw->authq);
tasklet_init(&hw->reaper_bh,
- hfa384x_usbctlx_reaper_task,
- (unsigned long)hw);
+ hfa384x_usbctlx_reaper_task, (unsigned long)hw);
tasklet_init(&hw->completion_bh,
- hfa384x_usbctlx_completion_task,
- (unsigned long)hw);
+ hfa384x_usbctlx_completion_task, (unsigned long)hw);
INIT_WORK(&hw->link_bh, prism2sta_processing_defer);
INIT_WORK(&hw->usb_work, hfa384x_usb_defer);
@@ -665,15 +584,12 @@ hfa384x_create( hfa384x_t *hw, struct usb_device *usb)
hw->link_status = HFA384x_LINK_NOTCONNECTED;
hw->state = HFA384x_STATE_INIT;
- INIT_WORK(&hw->commsqual_bh, prism2sta_commsqual_defer);
+ INIT_WORK(&hw->commsqual_bh, prism2sta_commsqual_defer);
init_timer(&hw->commsqual_timer);
- hw->commsqual_timer.data = (unsigned long) hw;
+ hw->commsqual_timer.data = (unsigned long)hw;
hw->commsqual_timer.function = prism2sta_commsqual_timer;
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_destroy
*
@@ -696,16 +612,12 @@ hfa384x_create( hfa384x_t *hw, struct usb_device *usb)
* Call context:
* process
----------------------------------------------------------------*/
-void
-hfa384x_destroy( hfa384x_t *hw)
+void hfa384x_destroy(hfa384x_t *hw)
{
struct sk_buff *skb;
- DBFENTER;
-
- if ( hw->state == HFA384x_STATE_RUNNING ) {
+ if (hw->state == HFA384x_STATE_RUNNING)
hfa384x_drvr_stop(hw);
- }
hw->state = HFA384x_STATE_PREINIT;
if (hw->scanresults) {
@@ -714,23 +626,16 @@ hfa384x_destroy( hfa384x_t *hw)
}
/* Now to clean out the auth queue */
- while ( (skb = skb_dequeue(&hw->authq)) ) {
- dev_kfree_skb(skb);
- }
-
- DBFEXIT;
+ while ((skb = skb_dequeue(&hw->authq)))
+ dev_kfree_skb(skb);
}
-
-/*----------------------------------------------------------------
- */
-static hfa384x_usbctlx_t* usbctlx_alloc(void)
+static hfa384x_usbctlx_t *usbctlx_alloc(void)
{
hfa384x_usbctlx_t *ctlx;
ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
- if (ctlx != NULL)
- {
+ if (ctlx != NULL) {
memset(ctlx, 0, sizeof(*ctlx));
init_completion(&ctlx->done);
}
@@ -738,70 +643,58 @@ static hfa384x_usbctlx_t* usbctlx_alloc(void)
return ctlx;
}
-
-/*----------------------------------------------------------------
- *
-----------------------------------------------------------------*/
static int
usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
- hfa384x_cmdresult_t *result)
+ 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);
+ result->status = le16_to_cpu(cmdresp->status);
+ result->resp0 = le16_to_cpu(cmdresp->resp0);
+ result->resp1 = le16_to_cpu(cmdresp->resp1);
+ result->resp2 = le16_to_cpu(cmdresp->resp2);
+
+ pr_debug("cmdresult:status=0x%04x "
+ "resp0=0x%04x resp1=0x%04x resp2=0x%04x\n",
+ result->status, result->resp0, result->resp1, result->resp2);
+
+ return result->status & HFA384x_STATUS_RESULT;
}
static void
usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
- hfa384x_rridresult_t *result)
+ hfa384x_rridresult_t *result)
{
- DBFENTER;
-
- result->rid = hfa384x2host_16(rridresp->rid);
+ result->rid = le16_to_cpu(rridresp->rid);
result->riddata = rridresp->data;
- result->riddata_len = ((hfa384x2host_16(rridresp->frmlen) - 1) * 2);
+ result->riddata_len = ((le16_to_cpu(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;
+struct usbctlx_cmd_completor {
+ usbctlx_completor_t head;
- const hfa384x_usb_cmdresp_t *cmdresp;
- hfa384x_cmdresult_t *result;
+ 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;
+ 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)
+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;
@@ -814,44 +707,41 @@ init_cmd_completor(usbctlx_cmd_completor_t *completor,
* 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;
+struct usbctlx_rrid_completor {
+ usbctlx_completor_t head;
- const hfa384x_usb_rridresp_t *rridresp;
- void *riddata;
- unsigned int riddatalen;
+ const hfa384x_usb_rridresp_t *rridresp;
+ void *riddata;
+ unsigned int 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;
+ 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);
+ if (rridresult.riddata_len != complete->riddatalen) {
+ printk(KERN_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);
+ 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,
- unsigned int riddatalen)
+static inline usbctlx_completor_t *init_rrid_completor(usbctlx_rrid_completor_t
+ *completor,
+ const
+ hfa384x_usb_rridresp_t *
+ rridresp, void *riddata,
+ unsigned int riddatalen)
{
completor->head.complete = usbctlx_rrid_completor_fn;
completor->rridresp = rridresp;
@@ -878,30 +768,29 @@ typedef usbctlx_cmd_completor_t usbctlx_wmem_completor_t;
* Completor object:
* Interprets the results of a synchronous memory-read
----------------------------------------------------------------*/
-struct usbctlx_rmem_completor
-{
- usbctlx_completor_t head;
+struct usbctlx_rmem_completor {
+ usbctlx_completor_t head;
- const hfa384x_usb_rmemresp_t *rmemresp;
- void *data;
- unsigned int len;
+ const hfa384x_usb_rmemresp_t *rmemresp;
+ void *data;
+ unsigned int 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;
+ usbctlx_rmem_completor_t *complete = (usbctlx_rmem_completor_t *) head;
- WLAN_LOG_DEBUG(4,"rmemresp:len=%d\n", complete->rmemresp->frmlen);
+ pr_debug("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,
- unsigned int len)
+static inline usbctlx_completor_t *init_rmem_completor(usbctlx_rmem_completor_t
+ *completor,
+ hfa384x_usb_rmemresp_t
+ *rmemresp, void *data,
+ unsigned int len)
{
completor->head.complete = usbctlx_rmem_completor_fn;
completor->rmemresp = rmemresp;
@@ -931,28 +820,23 @@ init_rmem_completor(usbctlx_rmem_completor_t *completor,
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void
-hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
+static void hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
{
- DBFENTER;
-
- if ( ctlx->usercb != NULL ) {
+ 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);
+ 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
*
@@ -973,132 +857,114 @@ hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void
-hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
+static void hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
{
- DBFENTER;
-
- if ( ctlx->usercb != NULL ) {
+ 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);
+ rridresult.rid =
+ le16_to_cpu(ctlx->outbuf.rridreq.rid);
} else {
- usbctlx_get_rridresult(&ctlx->inbuf.rridresp, &rridresult);
+ 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)
+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)
+ 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);
+ return hfa384x_docmd(hw, DOASYNC, cmd, cmdcb, usercb, usercb_data);
}
static inline int
-hfa384x_dorrid_wait(hfa384x_t *hw, u16 rid, void *riddata, unsigned int riddatalen)
+hfa384x_dorrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
+ unsigned int riddatalen)
{
return hfa384x_dorrid(hw, DOWAIT,
- rid, riddata, riddatalen,
- NULL, NULL, NULL);
+ rid, riddata, riddatalen, NULL, NULL, NULL);
}
static inline int
hfa384x_dorrid_async(hfa384x_t *hw,
- u16 rid, void *riddata, unsigned int riddatalen,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+ u16 rid, void *riddata, unsigned int riddatalen,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb, void *usercb_data)
{
return hfa384x_dorrid(hw, DOASYNC,
- rid, riddata, riddatalen,
- cmdcb, usercb, usercb_data);
+ rid, riddata, riddatalen,
+ cmdcb, usercb, usercb_data);
}
static inline int
-hfa384x_dowrid_wait(hfa384x_t *hw, u16 rid, void *riddata, unsigned int riddatalen)
+hfa384x_dowrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
+ unsigned int riddatalen)
{
return hfa384x_dowrid(hw, DOWAIT,
- rid, riddata, riddatalen,
- NULL, NULL, NULL);
+ rid, riddata, riddatalen, NULL, NULL, NULL);
}
static inline int
hfa384x_dowrid_async(hfa384x_t *hw,
- u16 rid, void *riddata, unsigned int riddatalen,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+ u16 rid, void *riddata, unsigned int riddatalen,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb, void *usercb_data)
{
return hfa384x_dowrid(hw, DOASYNC,
- rid, riddata, riddatalen,
- cmdcb, usercb, usercb_data);
+ rid, riddata, riddatalen,
+ cmdcb, usercb, usercb_data);
}
static inline int
hfa384x_dormem_wait(hfa384x_t *hw,
- u16 page, u16 offset, void *data, unsigned int len)
+ u16 page, u16 offset, void *data, unsigned int len)
{
return hfa384x_dormem(hw, DOWAIT,
- page, offset, data, len,
- NULL, NULL, NULL);
+ page, offset, data, len, NULL, NULL, NULL);
}
static inline int
hfa384x_dormem_async(hfa384x_t *hw,
- u16 page, u16 offset, void *data, unsigned int len,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+ u16 page, u16 offset, void *data, unsigned int 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);
+ page, offset, data, len,
+ cmdcb, usercb, usercb_data);
}
static inline int
-hfa384x_dowmem_wait(
- hfa384x_t *hw,
- u16 page,
- u16 offset,
- void *data,
- unsigned int len)
+hfa384x_dowmem_wait(hfa384x_t *hw,
+ u16 page, u16 offset, void *data, unsigned int len)
{
return hfa384x_dowmem(hw, DOWAIT,
- page, offset, data, len,
- NULL, NULL, NULL);
+ page, offset, data, len, NULL, NULL, NULL);
}
static inline int
-hfa384x_dowmem_async(
- hfa384x_t *hw,
- u16 page,
- u16 offset,
- void *data,
- unsigned int len,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_dowmem_async(hfa384x_t *hw,
+ u16 page,
+ u16 offset,
+ void *data,
+ unsigned int 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);
+ page, offset, data, len,
+ cmdcb, usercb, usercb_data);
}
/*----------------------------------------------------------------
@@ -1120,16 +986,12 @@ hfa384x_dowmem_async(
* Call context:
* process
----------------------------------------------------------------*/
-int
-hfa384x_cmd_initialize(hfa384x_t *hw)
+int hfa384x_cmd_initialize(hfa384x_t *hw)
{
- int result = 0;
- int i;
+ int result = 0;
+ int i;
hfa384x_metacmd_t cmd;
- DBFENTER;
-
-
cmd.cmd = HFA384x_CMDCODE_INIT;
cmd.parm0 = 0;
cmd.parm1 = 0;
@@ -1137,27 +999,21 @@ hfa384x_cmd_initialize(hfa384x_t *hw)
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++) {
+ pr_debug("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;
+ hw->link_status = HFA384x_LINK_NOTCONNECTED;
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_cmd_disable
*
@@ -1180,24 +1036,20 @@ hfa384x_cmd_initialize(hfa384x_t *hw)
----------------------------------------------------------------*/
int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport)
{
- int result = 0;
+ int result = 0;
hfa384x_metacmd_t cmd;
- DBFENTER;
-
cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) |
- HFA384x_CMD_MACPORT_SET(macport);
+ 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
*
@@ -1220,20 +1072,17 @@ int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport)
----------------------------------------------------------------*/
int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport)
{
- int result = 0;
+ int result = 0;
hfa384x_metacmd_t cmd;
- DBFENTER;
-
cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) |
- HFA384x_CMD_MACPORT_SET(macport);
+ HFA384x_CMD_MACPORT_SET(macport);
cmd.parm0 = 0;
cmd.parm1 = 0;
cmd.parm2 = 0;
result = hfa384x_docmd_wait(hw, &cmd);
- DBFEXIT;
return result;
}
@@ -1268,24 +1117,20 @@ int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport)
----------------------------------------------------------------*/
int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable)
{
- int result = 0;
+ int result = 0;
hfa384x_metacmd_t cmd;
- DBFENTER;
-
cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) |
- HFA384x_CMD_AINFO_SET(enable);
+ 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
*
@@ -1325,15 +1170,14 @@ int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable)
* process
----------------------------------------------------------------*/
int hfa384x_cmd_download(hfa384x_t *hw, u16 mode, u16 lowaddr,
- u16 highaddr, u16 codelen)
+ u16 highaddr, u16 codelen)
{
- int result = 0;
+ 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);
+ printk(KERN_DEBUG
+ "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));
@@ -1344,79 +1188,9 @@ int hfa384x_cmd_download(hfa384x_t *hw, u16 mode, u16 lowaddr,
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, u32 cardaddr, u32 auxctl, void *buf, unsigned int 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, u32 cardaddr, u32 auxctl, void *buf, unsigned int len)
-{
- DBFENTER;
- WLAN_LOG_ERROR("not used in USB.\n");
- DBFEXIT;
-}
-
-
/*----------------------------------------------------------------
* hfa384x_corereset
*
@@ -1442,20 +1216,17 @@ hfa384x_copy_to_aux(
----------------------------------------------------------------*/
int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
{
- int result = 0;
-
- DBFENTER;
+ int result = 0;
- result=usb_reset_device(hw->usb);
- if(result<0) {
- WLAN_LOG_ERROR("usb_reset_device() failed, result=%d.\n",result);
+ result = usb_reset_device(hw->usb);
+ if (result < 0) {
+ printk(KERN_ERR "usb_reset_device() failed, result=%d.\n",
+ result);
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_usbctlx_complete_sync
*
@@ -1487,8 +1258,6 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
unsigned long flags;
int result;
- DBFENTER;
-
result = wait_for_completion_interruptible(&ctlx->done);
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -1497,14 +1266,11 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
* We can only handle the CTLX if the USB disconnect
* function has not run yet ...
*/
- cleanup:
- if ( hw->wlandev->hwremoved )
- {
+cleanup:
+ if (hw->wlandev->hwremoved) {
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
result = -ENODEV;
- }
- else if ( result != 0 )
- {
+ } else if (result != 0) {
int runqueue = 0;
/*
@@ -1516,8 +1282,7 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
* NOTE: We can only delete the timers and
* the URB if this CTLX is active.
*/
- if (ctlx == get_active_ctlx(hw))
- {
+ if (ctlx == get_active_ctlx(hw)) {
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
del_singleshot_timer_sync(&hw->reqtimer);
@@ -1534,7 +1299,7 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
* This scenario is so unlikely that I'm
* happy with a grubby "goto" solution ...
*/
- if ( hw->wlandev->hwremoved )
+ if (hw->wlandev->hwremoved)
goto cleanup;
}
@@ -1555,9 +1320,9 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
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));
+ printk(KERN_WARNING "CTLX[%d] error: state(%s)\n",
+ le16_to_cpu(ctlx->outbuf.type),
+ ctlxstr(ctlx->state));
result = -EIO;
}
@@ -1566,7 +1331,6 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
kfree(ctlx);
}
- DBFEXIT;
return result;
}
@@ -1603,39 +1367,32 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
* 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)
+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;
+ int result;
+ hfa384x_usbctlx_t *ctlx;
- DBFENTER;
ctlx = usbctlx_alloc();
- if ( ctlx == NULL ) {
+ 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->outbuf.cmdreq.type = cpu_to_le16(HFA384x_USB_CMDREQ);
+ ctlx->outbuf.cmdreq.cmd = cpu_to_le16(cmd->cmd);
+ ctlx->outbuf.cmdreq.parm0 = cpu_to_le16(cmd->parm0);
+ ctlx->outbuf.cmdreq.parm1 = cpu_to_le16(cmd->parm1);
+ ctlx->outbuf.cmdreq.parm2 = cpu_to_le16(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);
+ pr_debug("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;
@@ -1648,18 +1405,20 @@ hfa384x_docmd(
} 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) );
+ result =
+ hfa384x_usbctlx_complete_sync(hw, ctlx,
+ init_cmd_completor(&completor,
+ &ctlx->
+ inbuf.
+ cmdresp,
+ &cmd->
+ result));
}
done:
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_dorrid
*
@@ -1697,31 +1456,27 @@ done:
* process (DOWAIT or DOASYNC)
----------------------------------------------------------------*/
static int
-hfa384x_dorrid(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 rid,
- void *riddata,
- unsigned int riddatalen,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_dorrid(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 rid,
+ void *riddata,
+ unsigned int riddatalen,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
- int result;
- hfa384x_usbctlx_t *ctlx;
+ int result;
+ hfa384x_usbctlx_t *ctlx;
- DBFENTER;
ctlx = usbctlx_alloc();
- if ( ctlx == NULL ) {
+ if (ctlx == NULL) {
result = -ENOMEM;
goto done;
}
/* Initialize the command */
- ctlx->outbuf.rridreq.type = host2hfa384x_16(HFA384x_USB_RRIDREQ);
+ ctlx->outbuf.rridreq.type = cpu_to_le16(HFA384x_USB_RRIDREQ);
ctlx->outbuf.rridreq.frmlen =
- host2hfa384x_16(sizeof(ctlx->outbuf.rridreq.rid));
- ctlx->outbuf.rridreq.rid = host2hfa384x_16(rid);
+ cpu_to_le16(sizeof(ctlx->outbuf.rridreq.rid));
+ ctlx->outbuf.rridreq.rid = cpu_to_le16(rid);
ctlx->outbufsize = sizeof(ctlx->outbuf.rridreq);
@@ -1737,19 +1492,18 @@ hfa384x_dorrid(
} 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) );
+ result =
+ hfa384x_usbctlx_complete_sync(hw, ctlx,
+ init_rrid_completor
+ (&completor,
+ &ctlx->inbuf.rridresp,
+ riddata, riddatalen));
}
done:
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_dowrid
*
@@ -1783,38 +1537,34 @@ done:
* process (DOWAIT or DOASYNC)
----------------------------------------------------------------*/
static int
-hfa384x_dowrid(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 rid,
- void *riddata,
- unsigned int riddatalen,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_dowrid(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 rid,
+ void *riddata,
+ unsigned int riddatalen,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
- int result;
- hfa384x_usbctlx_t *ctlx;
+ int result;
+ hfa384x_usbctlx_t *ctlx;
- DBFENTER;
ctlx = usbctlx_alloc();
- if ( ctlx == NULL ) {
+ 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);
+ ctlx->outbuf.wridreq.type = cpu_to_le16(HFA384x_USB_WRIDREQ);
+ ctlx->outbuf.wridreq.frmlen = cpu_to_le16((sizeof
+ (ctlx->outbuf.wridreq.
+ rid) + riddatalen +
+ 1) / 2);
+ ctlx->outbuf.wridreq.rid = cpu_to_le16(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;
+ sizeof(ctlx->outbuf.wridreq.frmlen) +
+ sizeof(ctlx->outbuf.wridreq.rid) + riddatalen;
ctlx->reapable = mode;
ctlx->cmdcb = cmdcb;
@@ -1829,16 +1579,15 @@ hfa384x_dowrid(
usbctlx_wrid_completor_t completor;
hfa384x_cmdresult_t wridresult;
- result = hfa384x_usbctlx_complete_sync(
- hw,
- ctlx,
- init_wrid_completor(&completor,
- &ctlx->inbuf.wridresp,
- &wridresult) );
+ result = hfa384x_usbctlx_complete_sync(hw,
+ ctlx,
+ init_wrid_completor
+ (&completor,
+ &ctlx->inbuf.wridresp,
+ &wridresult));
}
done:
- DBFEXIT;
return result;
}
@@ -1876,47 +1625,41 @@ done:
* process (DOWAIT or DOASYNC)
----------------------------------------------------------------*/
static int
-hfa384x_dormem(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 page,
- u16 offset,
- void *data,
- unsigned int len,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_dormem(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 page,
+ u16 offset,
+ void *data,
+ unsigned int len,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
- int result;
- hfa384x_usbctlx_t *ctlx;
+ int result;
+ hfa384x_usbctlx_t *ctlx;
- DBFENTER;
ctlx = usbctlx_alloc();
- if ( ctlx == NULL ) {
+ 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->outbuf.rmemreq.type = cpu_to_le16(HFA384x_USB_RMEMREQ);
+ ctlx->outbuf.rmemreq.frmlen =
+ cpu_to_le16(sizeof(ctlx->outbuf.rmemreq.offset) +
+ sizeof(ctlx->outbuf.rmemreq.page) + len);
+ ctlx->outbuf.rmemreq.offset = cpu_to_le16(offset);
+ ctlx->outbuf.rmemreq.page = cpu_to_le16(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);
+ printk(KERN_DEBUG
+ "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)));
+ pr_debug("pktsize=%zd\n",
+ ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)));
ctlx->reapable = mode;
ctlx->cmdcb = cmdcb;
@@ -1926,23 +1669,21 @@ hfa384x_dormem(
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) );
+ } 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
*
@@ -1977,45 +1718,39 @@ done:
* process (DOWAIT or DOASYNC)
----------------------------------------------------------------*/
static int
-hfa384x_dowmem(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 page,
- u16 offset,
- void *data,
- unsigned int len,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_dowmem(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 page,
+ u16 offset,
+ void *data,
+ unsigned int len,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
- int result;
- hfa384x_usbctlx_t *ctlx;
+ int result;
+ hfa384x_usbctlx_t *ctlx;
- DBFENTER;
- WLAN_LOG_DEBUG(5, "page=0x%04x offset=0x%04x len=%d\n",
- page,offset,len);
+ pr_debug("page=0x%04x offset=0x%04x len=%d\n",
+ page, offset, len);
ctlx = usbctlx_alloc();
- if ( ctlx == NULL ) {
+ 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);
+ ctlx->outbuf.wmemreq.type = cpu_to_le16(HFA384x_USB_WMEMREQ);
+ ctlx->outbuf.wmemreq.frmlen =
+ cpu_to_le16(sizeof(ctlx->outbuf.wmemreq.offset) +
+ sizeof(ctlx->outbuf.wmemreq.page) + len);
+ ctlx->outbuf.wmemreq.offset = cpu_to_le16(offset);
+ ctlx->outbuf.wmemreq.page = cpu_to_le16(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;
+ sizeof(ctlx->outbuf.wmemreq.frmlen) +
+ sizeof(ctlx->outbuf.wmemreq.offset) +
+ sizeof(ctlx->outbuf.wmemreq.page) + len;
ctlx->reapable = mode;
ctlx->cmdcb = cmdcb;
@@ -2025,24 +1760,22 @@ hfa384x_dowmem(
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) );
+ } 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
*
@@ -2060,12 +1793,10 @@ done:
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_commtallies( hfa384x_t *hw )
+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;
@@ -2073,11 +1804,9 @@ int hfa384x_drvr_commtallies( hfa384x_t *hw )
hfa384x_docmd_async(hw, &cmd, NULL, NULL, NULL);
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_disable
*
@@ -2102,24 +1831,20 @@ int hfa384x_drvr_commtallies( hfa384x_t *hw )
----------------------------------------------------------------*/
int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport)
{
- int result = 0;
+ int result = 0;
- DBFENTER;
if ((!hw->isap && macport != 0) ||
(hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
- !(hw->port_enabled[macport]) ){
+ !(hw->port_enabled[macport])) {
result = -EINVAL;
} else {
result = hfa384x_cmd_disable(hw, macport);
- if ( result == 0 ) {
+ if (result == 0)
hw->port_enabled[macport] = 0;
- }
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_enable
*
@@ -2144,24 +1869,20 @@ int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport)
----------------------------------------------------------------*/
int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport)
{
- int result = 0;
+ int result = 0;
- DBFENTER;
if ((!hw->isap && macport != 0) ||
(hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
- (hw->port_enabled[macport]) ){
+ (hw->port_enabled[macport])) {
result = -EINVAL;
} else {
result = hfa384x_cmd_enable(hw, macport);
- if ( result == 0 ) {
+ if (result == 0)
hw->port_enabled[macport] = 1;
- }
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_flashdl_enable
*
@@ -2185,45 +1906,43 @@ int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport)
----------------------------------------------------------------*/
int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
{
- int result = 0;
- int i;
+ 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");
+ for (i = 0; i < HFA384x_PORTID_MAX; i++) {
+ if (hw->port_enabled[i]) {
+ pr_debug("called when port enabled.\n");
return -EINVAL;
}
}
/* Check that we're not already in a download state */
- if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
+ 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))) ) {
+ 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))) ) {
+ hw->bufinfo.page = le16_to_cpu(hw->bufinfo.page);
+ hw->bufinfo.offset = le16_to_cpu(hw->bufinfo.offset);
+ hw->bufinfo.len = le16_to_cpu(hw->bufinfo.len);
+ if ((result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
+ &(hw->dltimeout)))) {
return result;
}
- hw->dltimeout = hfa384x2host_16(hw->dltimeout);
+ hw->dltimeout = le16_to_cpu(hw->dltimeout);
- WLAN_LOG_DEBUG(1,"flashdl_enable\n");
+ pr_debug("flashdl_enable\n");
hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;
- DBFEXIT;
+
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_flashdl_disable
*
@@ -2245,24 +1964,20 @@ int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
----------------------------------------------------------------*/
int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
{
- DBFENTER;
/* Check that we're already in the download state */
- if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+ if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
return -EINVAL;
- }
- WLAN_LOG_DEBUG(1,"flashdl_enable\n");
+ pr_debug("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);
+ hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0, 0);
hw->dlstate = HFA384x_DLSTATE_DISABLED;
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_flashdl_write
*
@@ -2292,48 +2007,42 @@ int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
* Call context:
* process
----------------------------------------------------------------*/
-int
-hfa384x_drvr_flashdl_write(
- hfa384x_t *hw,
- u32 daddr,
- void *buf,
- u32 len)
+int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
{
- int result = 0;
- u32 dlbufaddr;
- int nburns;
- u32 burnlen;
- u32 burndaddr;
- u16 burnlo;
- u16 burnhi;
- int nwrites;
- u8 *writebuf;
- u16 writepage;
- u16 writeoffset;
- u32 writelen;
- int i;
- int j;
-
- DBFENTER;
- WLAN_LOG_DEBUG(5,"daddr=0x%08x len=%d\n", daddr, len);
+ int result = 0;
+ u32 dlbufaddr;
+ int nburns;
+ u32 burnlen;
+ u32 burndaddr;
+ u16 burnlo;
+ u16 burnhi;
+ int nwrites;
+ u8 *writebuf;
+ u16 writepage;
+ u16 writeoffset;
+ u32 writelen;
+ int i;
+ int j;
+
+ pr_debug("daddr=0x%08x len=%d\n", daddr, len);
/* Check that we're in the flash download state */
- if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+ if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
return -EINVAL;
- }
- WLAN_LOG_INFO("Download %d bytes to flash @0x%06x\n", len, daddr);
+ printk(KERN_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);
+ dlbufaddr =
+ HFA384x_ADDR_AUX_MKFLAT(hw->bufinfo.page, hw->bufinfo.offset);
+ printk(KERN_DEBUG
+ "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);
+ printk(KERN_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
@@ -2351,74 +2060,60 @@ WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw-
nwrites += (hw->bufinfo.len % HFA384x_USB_RWMEM_MAXLEN) ? 1 : 0;
/* For each burn */
- for ( i = 0; i < nburns; i++) {
+ 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));
+ 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);
+ printk(KERN_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);
+ burnlo, burnhi, burnlen);
+ if (result) {
+ printk(KERN_ERR "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++) {
+ 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
-
+ (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);
}
/* 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);
+ HFA384x_PROGMODE_NVWRITE,
+ 0, 0, 0);
+ if (result) {
+ printk(KERN_ERR
+ "download(NVWRITE,lo=%x,hi=%x,len=%x) "
+ "cmd failed, result=%d. Aborting d/l\n",
+ burnlo, burnhi, burnlen, result);
goto exit_proc;
}
@@ -2431,11 +2126,9 @@ exit_proc:
/* actually disable programming mode. Remember, that will cause the */
/* the firmware to effectively reset itself. */
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_getconfig
*
@@ -2463,12 +2156,10 @@ exit_proc:
----------------------------------------------------------------*/
int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
{
- int result;
- DBFENTER;
+ int result;
result = hfa384x_dorrid_wait(hw, rid, buf, len);
- DBFEXIT;
return result;
}
@@ -2500,14 +2191,11 @@ int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
* Any
----------------------------------------------------------------*/
int
-hfa384x_drvr_getconfig_async(
- hfa384x_t *hw,
- u16 rid,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_drvr_getconfig_async(hfa384x_t *hw,
+ u16 rid, ctlx_usercb_t usercb, void *usercb_data)
{
- return hfa384x_dorrid_async(hw, rid, NULL, 0,
- hfa384x_cb_rrid, usercb, usercb_data);
+ return hfa384x_dorrid_async(hw, rid, NULL, 0,
+ hfa384x_cb_rrid, usercb, usercb_data);
}
/*----------------------------------------------------------------
@@ -2534,71 +2222,16 @@ hfa384x_drvr_getconfig_async(
* process
----------------------------------------------------------------*/
int
-hfa384x_drvr_setconfig_async(
- hfa384x_t *hw,
- u16 rid,
- void *buf,
- u16 len,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_drvr_setconfig_async(hfa384x_t *hw,
+ u16 rid,
+ void *buf,
+ u16 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, u8 *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_ramdl_disable
*
* Ends the ram download state.
@@ -2616,27 +2249,22 @@ int hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
* Call context:
* process
----------------------------------------------------------------*/
-int
-hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
+int hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
{
- DBFENTER;
/* Check that we're already in the download state */
- if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) {
+ if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
return -EINVAL;
- }
- WLAN_LOG_DEBUG(3,"ramdl_disable()\n");
+ pr_debug("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);
+ hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0, 0);
hw->dlstate = HFA384x_DLSTATE_DISABLED;
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_ramdl_enable
*
@@ -2661,55 +2289,49 @@ hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
* Call context:
* process
----------------------------------------------------------------*/
-int
-hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
+int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
{
- int result = 0;
- u16 lowaddr;
- u16 hiaddr;
- int i;
- DBFENTER;
+ int result = 0;
+ u16 lowaddr;
+ u16 hiaddr;
+ int i;
+
/* 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");
+ for (i = 0; i < HFA384x_PORTID_MAX; i++) {
+ if (hw->port_enabled[i]) {
+ printk(KERN_ERR
+ "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");
+ if (hw->dlstate != HFA384x_DLSTATE_DISABLED) {
+ printk(KERN_ERR "Download state not disabled.\n");
return -EINVAL;
}
- WLAN_LOG_DEBUG(3,"ramdl_enable, exeaddr=0x%08x\n", exeaddr);
+ pr_debug("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);
+ hiaddr = HFA384x_ADDR_CMD_MKPAGE(exeaddr);
result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM,
- lowaddr, hiaddr, 0);
+ lowaddr, hiaddr, 0);
- if ( result == 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);
+ printk(KERN_DEBUG
+ "cmd_download(0x%04x, 0x%04x) failed, result=%d.\n",
+ lowaddr, hiaddr, result);
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_ramdl_write
*
@@ -2736,57 +2358,54 @@ hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
* Call context:
* process
----------------------------------------------------------------*/
-int
-hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void* buf, u32 len)
+int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
{
- int result = 0;
- int nwrites;
- u8 *data = buf;
- int i;
- u32 curraddr;
- u16 currpage;
- u16 curroffset;
- u16 currlen;
- DBFENTER;
+ int result = 0;
+ int nwrites;
+ u8 *data = buf;
+ int i;
+ u32 curraddr;
+ u16 currpage;
+ u16 curroffset;
+ u16 currlen;
+
/* Check that we're in the ram download state */
- if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) {
+ if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
return -EINVAL;
- }
- WLAN_LOG_INFO("Writing %d bytes to ram @0x%06x\n", len, daddr);
+ printk(KERN_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++) {
+ 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) {
+ 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 );
+ /* Do blocking ctlx */
+ result = hfa384x_dowmem_wait(hw,
+ currpage,
+ curroffset,
+ data +
+ (i * HFA384x_USB_RWMEM_MAXLEN),
+ currlen);
- if (result) break;
+ if (result)
+ break;
/* TODO: We really should have a readback. */
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_readpda
*
@@ -2820,101 +2439,89 @@ hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void* buf, u32 len)
----------------------------------------------------------------*/
int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len)
{
- int result = 0;
- u16 *pda = buf;
- int pdaok = 0;
- int morepdrs = 1;
- int currpdr = 0; /* word offset of the current pdr */
- size_t i;
- u16 pdrlen; /* pdr length in bytes, host order */
- u16 pdrcode; /* pdr code, host order */
- u16 currpage;
- u16 curroffset;
+ int result = 0;
+ u16 *pda = buf;
+ int pdaok = 0;
+ int morepdrs = 1;
+ int currpdr = 0; /* word offset of the current pdr */
+ size_t i;
+ u16 pdrlen; /* pdr length in bytes, host order */
+ u16 pdrcode; /* pdr code, host order */
+ u16 currpage;
+ u16 curroffset;
struct pdaloc {
- u32 cardaddr;
- u16 auxctl;
- } pdaloc[] =
- {
- { HFA3842_PDA_BASE, 0},
- { HFA3841_PDA_BASE, 0},
- { HFA3841_PDA_BOGUS_BASE, 0}
+ u32 cardaddr;
+ u16 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++) {
+ 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 */
+ 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 );
+ printk(KERN_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]);
+ while (pdaok && morepdrs) {
+ pdrlen = le16_to_cpu(pda[currpdr]) * 2;
+ pdrcode = le16_to_cpu(pda[currpdr + 1]);
/* Test the record length */
- if ( pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
- WLAN_LOG_ERROR("pdrlen invalid=%d\n",
- pdrlen);
+ if (pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
+ printk(KERN_ERR "pdrlen invalid=%d\n", pdrlen);
pdaok = 0;
break;
}
/* Test the code */
- if ( !hfa384x_isgood_pdrcode(pdrcode) ) {
- WLAN_LOG_ERROR("pdrcode invalid=%d\n",
- pdrcode);
+ if (!hfa384x_isgood_pdrcode(pdrcode)) {
+ printk(KERN_ERR "pdrcode invalid=%d\n",
+ pdrcode);
pdaok = 0;
break;
}
/* Test for completion */
- if ( pdrcode == HFA384x_PDR_END_OF_PDA) {
+ if (pdrcode == HFA384x_PDR_END_OF_PDA)
morepdrs = 0;
- }
/* Move to the next pdr (if necessary) */
- if ( morepdrs ) {
+ if (morepdrs) {
/* note the access to pda[], need words here */
- currpdr += hfa384x2host_16(pda[currpdr]) + 1;
+ currpdr += le16_to_cpu(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>");
+ if (pdaok) {
+ printk(KERN_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");
- }
+ if (result)
+ pr_debug("Failure: pda is not okay\n");
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_setconfig
*
@@ -2963,9 +2570,8 @@ int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
int hfa384x_drvr_start(hfa384x_t *hw)
{
- int result, result1, result2;
- u16 status;
- DBFENTER;
+ int result, result1, result2;
+ u16 status;
might_sleep();
@@ -2974,27 +2580,23 @@ int hfa384x_drvr_start(hfa384x_t *hw)
* badly if a clear_halt is called when the endpoint is already
* ok
*/
- result = usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, &status);
+ result =
+ usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, &status);
if (result < 0) {
- WLAN_LOG_ERROR(
- "Cannot get bulk in endpoint status.\n");
+ printk(KERN_ERR "Cannot get bulk in endpoint status.\n");
goto done;
}
- if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_in)) {
- WLAN_LOG_ERROR(
- "Failed to reset bulk in endpoint.\n");
- }
+ if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_in))
+ printk(KERN_ERR "Failed to reset bulk in endpoint.\n");
- result = usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, &status);
+ result =
+ usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, &status);
if (result < 0) {
- WLAN_LOG_ERROR(
- "Cannot get bulk out endpoint status.\n");
+ printk(KERN_ERR "Cannot get bulk out endpoint status.\n");
goto done;
}
- if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_out)) {
- WLAN_LOG_ERROR(
- "Failed to reset bulk out endpoint.\n");
- }
+ if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_out))
+ printk(KERN_ERR "Failed to reset bulk out endpoint.\n");
/* Synchronous unlink, in case we're trying to restart the driver */
usb_kill_urb(&hw->rx_urb);
@@ -3002,9 +2604,8 @@ int hfa384x_drvr_start(hfa384x_t *hw)
/* 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);
+ printk(KERN_ERR
+ "Fatal, failed to submit RX URB, result=%d\n", result);
goto done;
}
@@ -3023,32 +2624,33 @@ int hfa384x_drvr_start(hfa384x_t *hw)
result = result2 = hfa384x_cmd_initialize(hw);
if (result1 != 0) {
if (result2 != 0) {
- WLAN_LOG_ERROR(
- "cmd_initialize() failed on two attempts, results %d and %d\n",
- result1, result2);
+ printk(KERN_ERR
+ "cmd_initialize() failed on two attempts, results %d and %d\n",
+ result1, result2);
usb_kill_urb(&hw->rx_urb);
goto done;
} else {
- WLAN_LOG_DEBUG(0, "First cmd_initialize() failed (result %d),\n",
- result1);
- WLAN_LOG_DEBUG(0, "but second attempt succeeded. All should be ok\n");
+ printk(KERN_DEBUG
+ "First cmd_initialize() failed (result %d),\n",
+ result1);
+ printk(KERN_DEBUG
+ "but second attempt succeeded. All should be ok\n");
}
} else if (result2 != 0) {
- WLAN_LOG_WARNING(
- "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n",
- result2);
- WLAN_LOG_WARNING("Most likely the card will be functional\n");
- goto done;
+ printk(KERN_WARNING
+ "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n",
+ result2);
+ printk(KERN_WARNING
+ "Most likely the card will be functional\n");
+ goto done;
}
hw->state = HFA384x_STATE_RUNNING;
done:
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_stop
*
@@ -3068,19 +2670,17 @@ done:
* Call context:
* process
----------------------------------------------------------------*/
-int
-hfa384x_drvr_stop(hfa384x_t *hw)
+int hfa384x_drvr_stop(hfa384x_t *hw)
{
- int result = 0;
- int i;
- DBFENTER;
+ int result = 0;
+ int i;
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 ) {
+ if (!hw->wlandev->hwremoved) {
/* Call initialize to leave the MAC in its 'reset' state */
hfa384x_cmd_initialize(hw);
@@ -3094,11 +2694,9 @@ hfa384x_drvr_stop(hfa384x_t *hw)
del_timer_sync(&hw->commsqual_timer);
/* Clear all the port status */
- for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
+ for (i = 0; i < HFA384x_NUMPORTS_MAX; i++)
hw->port_enabled[i] = 0;
- }
- DBFEXIT;
return result;
}
@@ -3123,18 +2721,17 @@ hfa384x_drvr_stop(hfa384x_t *hw)
* 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 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;
+ int usbpktlen = sizeof(hfa384x_tx_frame_t);
+ int result;
+ int ret;
+ char *ptr;
if (hw->tx_urb.status == -EINPROGRESS) {
- WLAN_LOG_WARNING("TX URB already in use\n");
+ printk(KERN_WARNING "TX URB already in use\n");
result = 3;
goto exit;
}
@@ -3144,7 +2741,7 @@ int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p8021
memset(&hw->txbuff.txfrm.desc, 0, sizeof(hw->txbuff.txfrm.desc));
/* Setup the usb type field */
- hw->txbuff.type = host2hfa384x_16(HFA384x_USB_TXFRM);
+ hw->txbuff.type = cpu_to_le16(HFA384x_USB_TXFRM);
/* Set up the sw_support field to identify this frame */
hw->txbuff.txfrm.desc.sw_support = 0x0123;
@@ -3152,33 +2749,33 @@ int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p8021
/* Tx complete and Tx exception disable per dleach. Might be causing
* buf depletion
*/
-//#define DOEXC SLP -- doboth breaks horribly under load, doexc less so.
+/* #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);
+ 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);
+ 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);
+ 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);
+ cpu_to_le16(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));
+ 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;
+ hw->txbuff.txfrm.desc.data_len = cpu_to_le16(skb->len + 8);
+ usbpktlen += 8;
} else {
- hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len);
+ hw->txbuff.txfrm.desc.data_len = cpu_to_le16(skb->len);
}
usbpktlen += skb->len;
@@ -3187,59 +2784,51 @@ int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p8021
ptr = hw->txbuff.txfrm.data;
if (p80211_wep->data) {
memcpy(ptr, p80211_wep->iv, sizeof(p80211_wep->iv));
- ptr+= 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;
+ ptr += skb->len;
/* copy over the WEP ICV if we are using host WEP */
- if (p80211_wep->data) {
+ 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 );
+ 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);
+ if (ret != 0) {
+ printk(KERN_ERR "submit_tx_urb() failed, error=%d\n", ret);
result = 3;
}
- exit:
- DBFEXIT;
+exit:
return result;
}
void hfa384x_tx_timeout(wlandevice_t *wlandev)
{
- hfa384x_t *hw = wlandev->priv;
+ 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) ) )
- {
+ 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;
}
/*----------------------------------------------------------------
@@ -3257,12 +2846,10 @@ void hfa384x_tx_timeout(wlandevice_t *wlandev)
----------------------------------------------------------------*/
static void hfa384x_usbctlx_reaper_task(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t*)data;
+ hfa384x_t *hw = (hfa384x_t *) data;
struct list_head *entry;
struct list_head *temp;
- unsigned long flags;
-
- DBFENTER;
+ unsigned long flags;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3270,7 +2857,7 @@ static void hfa384x_usbctlx_reaper_task(unsigned long data)
* has unplugged the adapter.
*/
list_for_each_safe(entry, temp, &hw->ctlxq.reapable) {
- hfa384x_usbctlx_t *ctlx;
+ hfa384x_usbctlx_t *ctlx;
ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
list_del(&ctlx->list);
@@ -3279,7 +2866,6 @@ static void hfa384x_usbctlx_reaper_task(unsigned long data)
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
- DBFEXIT;
}
/*----------------------------------------------------------------
@@ -3298,15 +2884,13 @@ static void hfa384x_usbctlx_reaper_task(unsigned long data)
----------------------------------------------------------------*/
static void hfa384x_usbctlx_completion_task(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t*)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
@@ -3320,7 +2904,7 @@ static void hfa384x_usbctlx_completion_task(unsigned long data)
/* Call the completion function that this
* command was assigned, assuming it has one.
*/
- if ( ctlx->cmdcb != NULL ) {
+ if (ctlx->cmdcb != NULL) {
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
ctlx->cmdcb(hw, ctlx);
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3333,8 +2917,7 @@ static void hfa384x_usbctlx_completion_task(unsigned long data)
/* Did someone yank the adapter out
* while our list was (briefly) unlocked?
*/
- if ( hw->wlandev->hwremoved )
- {
+ if (hw->wlandev->hwremoved) {
reap = 0;
break;
}
@@ -3345,7 +2928,7 @@ static void hfa384x_usbctlx_completion_task(unsigned long data)
* threads waiting for them to die. Hence they must
* be delivered to The Reaper!
*/
- if ( ctlx->reapable ) {
+ 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
@@ -3361,8 +2944,6 @@ static void hfa384x_usbctlx_completion_task(unsigned long data)
if (reap)
tasklet_schedule(&hw->reaper_bh);
-
- DBFEXIT;
}
/*----------------------------------------------------------------
@@ -3382,12 +2963,11 @@ static void hfa384x_usbctlx_completion_task(unsigned long data)
* Call context:
* Either process or interrupt, but presumably interrupt
----------------------------------------------------------------*/
-static int unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
+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
@@ -3408,8 +2988,6 @@ static int unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
ret = 0;
}
- DBFEXIT;
-
return ret;
}
@@ -3437,8 +3015,6 @@ static int unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
----------------------------------------------------------------*/
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.
@@ -3453,13 +3029,11 @@ static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
break;
default:
- WLAN_LOG_ERROR("CTLX[%d] not in a terminating state(%s)\n",
- hfa384x2host_16(ctlx->outbuf.type),
- ctlxstr(ctlx->state));
+ printk(KERN_ERR "CTLX[%d] not in a terminating state(%s)\n",
+ le16_to_cpu(ctlx->outbuf.type),
+ ctlxstr(ctlx->state));
break;
- } /* switch */
-
- DBFEXIT;
+ } /* switch */
}
/*----------------------------------------------------------------
@@ -3478,11 +3052,9 @@ static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
* Call context:
* any
----------------------------------------------------------------*/
-static void
-hfa384x_usbctlxq_run(hfa384x_t *hw)
+static void hfa384x_usbctlxq_run(hfa384x_t *hw)
{
- unsigned long flags;
- DBFENTER;
+ unsigned long flags;
/* acquire lock */
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3494,28 +3066,26 @@ hfa384x_usbctlxq_run(hfa384x_t *hw)
* 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 )
+ 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;
+ 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);
+ 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);
+ 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
@@ -3531,7 +3101,7 @@ hfa384x_usbctlxq_run(hfa384x_t *hw)
/* Start the IN wait timer */
hw->resp_timer_done = 0;
- hw->resptimer.expires = jiffies + 2*HZ;
+ hw->resptimer.expires = jiffies + 2 * HZ;
add_timer(&hw->resptimer);
break;
@@ -3542,8 +3112,9 @@ hfa384x_usbctlxq_run(hfa384x_t *hw)
* 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);
+ printk(KERN_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);
@@ -3551,23 +3122,20 @@ hfa384x_usbctlxq_run(hfa384x_t *hw)
}
if (result == -ESHUTDOWN) {
- WLAN_LOG_WARNING("%s urb shutdown!\n",
- hw->wlandev->netdev->name);
+ printk(KERN_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);
+ printk(KERN_ERR "Failed to submit CTLX[%d]: error=%d\n",
+ le16_to_cpu(head->outbuf.type), result);
unlocked_usbctlx_complete(hw, head);
- } /* while */
+ } /* while */
- unlock:
+unlock:
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_usbin_callback
*
@@ -3586,13 +3154,13 @@ hfa384x_usbctlxq_run(hfa384x_t *hw)
----------------------------------------------------------------*/
static void hfa384x_usbin_callback(struct urb *urb)
{
- 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;
- u16 type;
+ 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;
+ u16 type;
enum USBIN_ACTION {
HANDLE,
@@ -3600,11 +3168,7 @@ static void hfa384x_usbin_callback(struct urb *urb)
ABORT
} action;
- DBFENTER;
-
- if ( !wlandev ||
- !wlandev->netdev ||
- wlandev->hwremoved )
+ if (!wlandev || !wlandev->netdev || wlandev->hwremoved)
goto exit;
hw = wlandev->priv;
@@ -3612,9 +3176,8 @@ static void hfa384x_usbin_callback(struct urb *urb)
goto exit;
skb = hw->rx_urb_skb;
- if (!skb || (skb->data != urb->transfer_buffer)) {
- BUG();
- }
+ BUG_ON(!skb || (skb->data != urb->transfer_buffer));
+
hw->rx_urb_skb = NULL;
/* Check for error conditions within the URB */
@@ -3623,7 +3186,7 @@ static void hfa384x_usbin_callback(struct urb *urb)
action = HANDLE;
/* Check for short packet */
- if ( urb->actual_length == 0 ) {
+ if (urb->actual_length == 0) {
++(wlandev->linux_stats.rx_errors);
++(wlandev->linux_stats.rx_length_errors);
action = RESUBMIT;
@@ -3631,9 +3194,9 @@ static void hfa384x_usbin_callback(struct urb *urb)
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) )
+ printk(KERN_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;
@@ -3642,8 +3205,8 @@ static void hfa384x_usbin_callback(struct urb *urb)
case -EILSEQ:
case -ETIMEDOUT:
case -EPROTO:
- if ( !test_and_set_bit(THROTTLE_RX, &hw->usb_flags) &&
- !timer_pending(&hw->throttle) ) {
+ 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);
@@ -3657,19 +3220,20 @@ static void hfa384x_usbin_callback(struct urb *urb)
case -ENODEV:
case -ESHUTDOWN:
- WLAN_LOG_DEBUG(3,"status=%d, device removed.\n", urb->status);
+ pr_debug("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);
+ pr_debug("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);
+ pr_debug("urb status=%d, transfer flags=0x%x\n",
+ urb->status, urb->transfer_flags);
++(wlandev->linux_stats.rx_errors);
action = RESUBMIT;
break;
@@ -3682,9 +3246,9 @@ static void hfa384x_usbin_callback(struct urb *urb)
result = submit_rx_urb(hw, GFP_ATOMIC);
if (result != 0) {
- WLAN_LOG_ERROR(
- "Fatal, failed to resubmit rx_urb. error=%d\n",
- result);
+ printk(KERN_ERR
+ "Fatal, failed to resubmit rx_urb. error=%d\n",
+ result);
}
}
@@ -3692,7 +3256,7 @@ static void hfa384x_usbin_callback(struct urb *urb)
/* 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);
+ type = le16_to_cpu(usbin->type);
if (HFA384x_USB_ISRXFRM(type)) {
if (action == HANDLE) {
if (usbin->txfrm.desc.sw_support == 0x0123) {
@@ -3728,30 +3292,28 @@ static void hfa384x_usbin_callback(struct urb *urb)
break;
case HFA384x_USB_BUFAVAIL:
- WLAN_LOG_DEBUG(3,"Received BUFAVAIL packet, frmlen=%d\n",
- usbin->bufavail.frmlen);
+ pr_debug("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);
+ pr_debug("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);
+ printk(KERN_DEBUG
+ "Unrecognized USBIN packet, type=%x, status=%d\n",
+ usbin->type, urb_status);
break;
- } /* switch */
+ } /* switch */
exit:
if (skb)
dev_kfree_skb(skb);
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_usbin_ctlx
*
@@ -3775,11 +3337,9 @@ exit:
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;
+ hfa384x_usbctlx_t *ctlx;
+ int run_queue = 0;
+ unsigned long flags;
retry:
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3788,9 +3348,8 @@ retry:
* at any one time, and this is the CTLX that the
* timers are waiting for.
*/
- if ( list_empty(&hw->ctlxq.active) ) {
+ 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
@@ -3803,8 +3362,7 @@ retry:
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
goto retry;
}
- }
- else {
+ } else {
hw->resp_timer_done = 1;
}
@@ -3819,15 +3377,16 @@ retry:
if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
run_queue = 1;
} else {
- const u16 intype = (usbin->type&~host2hfa384x_16(0x8000));
+ const u16 intype = (usbin->type & ~cpu_to_le16(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));
+ printk(KERN_WARNING
+ "Expected IN[%d], received IN[%d] - ignored.\n",
+ le16_to_cpu(ctlx->outbuf.type),
+ le16_to_cpu(intype));
goto unlock;
}
@@ -3841,7 +3400,8 @@ retry:
* 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");
+ printk(KERN_DEBUG
+ "Causality violation: please reboot Universe, or email linux-wlan-devel@lists.linux-wlan.com\n");
ctlx->state = CTLX_RESP_COMPLETE;
break;
@@ -3860,14 +3420,15 @@ retry:
/*
* 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));
+ printk(KERN_ERR
+ "Matched IN URB, CTLX[%d] in invalid state(%s)."
+ " Discarded.\n",
+ le16_to_cpu(ctlx->outbuf.type),
+ ctlxstr(ctlx->state));
if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
run_queue = 1;
break;
- } /* switch */
+ } /* switch */
}
unlock:
@@ -3875,11 +3436,8 @@ unlock:
if (run_queue)
hfa384x_usbctlxq_run(hw);
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_usbin_txcompl
*
@@ -3897,25 +3455,20 @@ unlock:
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
+static void hfa384x_usbin_txcompl(wlandevice_t *wlandev,
+ hfa384x_usbin_t *usbin)
{
- u16 status;
- DBFENTER;
+ u16 status;
- status = hfa384x2host_16(usbin->type); /* yeah I know it says type...*/
+ status = le16_to_cpu(usbin->type); /* yeah I know it says type... */
/* Was there an error? */
- if (HFA384x_TXSTATUS_ISERROR(status)) {
+ if (HFA384x_TXSTATUS_ISERROR(status))
prism2sta_ev_txexc(wlandev, status);
- } else {
+ else
prism2sta_ev_tx(wlandev, status);
- }
- // prism2sta_ev_alloc(wlandev);
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_usbin_rx
*
@@ -3935,34 +3488,29 @@ static void hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
----------------------------------------------------------------*/
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;
- u16 data_len;
- u16 fc;
-
- DBFENTER;
+ hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) skb->data;
+ hfa384x_t *hw = wlandev->priv;
+ int hdrlen;
+ p80211_rxmeta_t *rxmeta;
+ u16 data_len;
+ u16 fc;
/* 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);
+ usbin->rxfrm.desc.status = le16_to_cpu(usbin->rxfrm.desc.status);
+ usbin->rxfrm.desc.time = le32_to_cpu(usbin->rxfrm.desc.time);
/* Now handle frame based on port# */
- switch( HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status) )
- {
+ switch (HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status)) {
case 0:
- fc = ieee2host16(usbin->rxfrm.desc.frame_control);
+ fc = le16_to_cpu(usbin->rxfrm.desc.frame_control);
/* If exclude and we receive an unencrypted, drop it */
- if ( (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) &&
- !WLAN_GET_FC_ISWEP(fc)){
+ if ((wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) &&
+ !WLAN_GET_FC_ISWEP(fc)) {
goto done;
}
- data_len = hfa384x2host_16(usbin->rxfrm.desc.data_len);
+ data_len = le16_to_cpu(usbin->rxfrm.desc.data_len);
/* How much header data do we have? */
hdrlen = p80211_headerlen(fc);
@@ -3974,8 +3522,7 @@ static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
* with an "overlapping" copy
*/
memmove(skb_push(skb, hdrlen),
- &usbin->rxfrm.desc.frame_control,
- hdrlen);
+ &usbin->rxfrm.desc.frame_control, hdrlen);
skb->dev = wlandev->netdev;
skb->dev->last_rx = jiffies;
@@ -4001,24 +3548,24 @@ static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
break;
case 7:
- if ( ! HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status) ) {
+ if (!HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status)) {
/* Copy to wlansnif skb */
- hfa384x_int_rxmonitor( wlandev, &usbin->rxfrm);
+ hfa384x_int_rxmonitor(wlandev, &usbin->rxfrm);
dev_kfree_skb(skb);
} else {
- WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n");
+ printk(KERN_DEBUG
+ "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) );
+ printk(KERN_WARNING "Received frame on unsupported port=%d\n",
+ HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status));
goto done;
break;
}
done:
- DBFEXIT;
return;
}
@@ -4043,97 +3590,93 @@ done:
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *rxfrm)
+static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
+ hfa384x_usb_rxfrm_t *rxfrm)
{
- hfa384x_rx_frame_t *rxdesc = &(rxfrm->desc);
- unsigned int hdrlen = 0;
- unsigned int datalen = 0;
- unsigned int skblen = 0;
- u8 *datap;
- u16 fc;
- struct sk_buff *skb;
- hfa384x_t *hw = wlandev->priv;
-
+ hfa384x_rx_frame_t *rxdesc = &(rxfrm->desc);
+ unsigned int hdrlen = 0;
+ unsigned int datalen = 0;
+ unsigned int skblen = 0;
+ u8 *datap;
+ u16 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);
+ fc = le16_to_cpu(rxdesc->frame_control);
hdrlen = p80211_headerlen(fc);
- datalen = hfa384x2host_16(rxdesc->data_len);
+ datalen = le16_to_cpu(rxdesc->data_len);
/* Allocate an ind message+framesize skb */
- skblen = sizeof(p80211_caphdr_t) +
- hdrlen + datalen + WLAN_CRC_LEN;
+ skblen = sizeof(p80211_caphdr_t) + hdrlen + datalen + WLAN_CRC_LEN;
/* sanity check the length */
- if ( skblen >
- (sizeof(p80211_caphdr_t) +
- WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) {
- WLAN_LOG_DEBUG(1, "overlen frm: len=%zd\n",
- skblen - sizeof(p80211_caphdr_t));
+ if (skblen >
+ (sizeof(p80211_caphdr_t) +
+ WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)) {
+ pr_debug("overlen frm: len=%zd\n",
+ skblen - sizeof(p80211_caphdr_t));
}
- if ( (skb = dev_alloc_skb(skblen)) == NULL ) {
- WLAN_LOG_ERROR("alloc_skb failed trying to allocate %d bytes\n", skblen);
+ if ((skb = dev_alloc_skb(skblen)) == NULL) {
+ printk(KERN_ERR
+ "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)) {
- p80211_caphdr_t *caphdr;
+ 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 */
+ 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);
+ memcpy(datap, &(rxdesc->frame_control), hdrlen);
/* If any, copy the data from the card to the skb */
- if ( datalen > 0 )
- {
+ 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 (*(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);
+ memset(datap, 0xff, WLAN_CRC_LEN);
}
/* pass it back up */
prism2sta_ev_rx(wlandev, skb);
- DBFEXIT;
return;
}
-
-
/*----------------------------------------------------------------
* hfa384x_usbin_info
*
@@ -4151,18 +3694,13 @@ static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *r
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
+static void hfa384x_usbin_info(wlandevice_t * wlandev, hfa384x_usbin_t * usbin)
{
- DBFENTER;
-
- usbin->infofrm.info.framelen = hfa384x2host_16(usbin->infofrm.info.framelen);
+ usbin->infofrm.info.framelen =
+ le16_to_cpu(usbin->infofrm.info.framelen);
prism2sta_ev_info(wlandev, &usbin->infofrm.info);
-
- DBFEXIT;
}
-
-
/*----------------------------------------------------------------
* hfa384x_usbout_callback
*
@@ -4181,48 +3719,49 @@ static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
----------------------------------------------------------------*/
static void hfa384x_usbout_callback(struct urb *urb)
{
- wlandevice_t *wlandev = urb->context;
- hfa384x_usbout_t *usbout = urb->transfer_buffer;
- DBFENTER;
+ wlandevice_t *wlandev = urb->context;
+ hfa384x_usbout_t *usbout = urb->transfer_buffer;
#ifdef DEBUG_USB
dbprint_urb(urb);
#endif
- if ( wlandev &&
- wlandev->netdev ) {
+ if (wlandev && wlandev->netdev) {
- switch(urb->status) {
+ 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;
- }
+ {
+ hfa384x_t *hw = wlandev->priv;
+ printk(KERN_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);
+ {
+ 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;
}
- ++(wlandev->linux_stats.tx_errors);
- netif_stop_queue(wlandev->netdev);
- break;
- }
case -ENOENT:
case -ESHUTDOWN:
@@ -4230,16 +3769,14 @@ static void hfa384x_usbout_callback(struct urb *urb)
break;
default:
- WLAN_LOG_INFO("unknown urb->status=%d\n", urb->status);
+ printk(KERN_INFO "unknown urb->status=%d\n",
+ urb->status);
++(wlandev->linux_stats.tx_errors);
break;
- } /* switch */
+ } /* switch */
}
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_ctlxout_callback
*
@@ -4258,22 +3795,19 @@ static void hfa384x_usbout_callback(struct urb *urb)
----------------------------------------------------------------*/
static void hfa384x_ctlxout_callback(struct urb *urb)
{
- 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;
+ hfa384x_t *hw = urb->context;
+ int delete_resptimer = 0;
+ int timer_ok = 1;
+ int run_queue = 0;
+ hfa384x_usbctlx_t *ctlx;
+ unsigned long flags;
- WLAN_LOG_DEBUG(3,"urb->status=%d\n", urb->status);
+ pr_debug("urb->status=%d\n", urb->status);
#ifdef DEBUG_USB
dbprint_urb(urb);
#endif
- if ( (urb->status == -ESHUTDOWN) ||
- (urb->status == -ENODEV) ||
- (hw == NULL) )
+ if ((urb->status == -ESHUTDOWN) ||
+ (urb->status == -ENODEV) || (hw == NULL))
goto done;
retry:
@@ -4285,7 +3819,7 @@ retry:
* rely on the disconnect function to clean everything
* up if someone unplugged the adapter.
*/
- if ( list_empty(&hw->ctlxq.active) ) {
+ if (list_empty(&hw->ctlxq.active)) {
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
goto done;
}
@@ -4304,16 +3838,15 @@ retry:
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
goto retry;
}
- }
- else {
+ } else {
hw->req_timer_done = 1;
}
ctlx = get_active_ctlx(hw);
- if ( urb->status == 0 ) {
+ if (urb->status == 0) {
/* Request portion of a CTLX is successful */
- switch ( ctlx->state ) {
+ switch (ctlx->state) {
case CTLX_REQ_SUBMITTED:
/* This OUT-ACK received before IN */
ctlx->state = CTLX_REQ_COMPLETE;
@@ -4330,18 +3863,19 @@ retry:
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);
+ printk(KERN_ERR
+ "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n",
+ le16_to_cpu(ctlx->outbuf.type),
+ ctlxstr(ctlx->state), urb->status);
break;
- } /* switch */
+ } /* 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);
+ if ((urb->status == -EPIPE) &&
+ !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags)) {
+ printk(KERN_WARNING
+ "%s tx pipe stalled: requesting reset\n",
+ hw->wlandev->netdev->name);
schedule_work(&hw->usb_work);
}
@@ -4354,7 +3888,7 @@ retry:
run_queue = 1;
}
- delresp:
+delresp:
if (delete_resptimer) {
if ((timer_ok = del_timer(&hw->resptimer)) != 0) {
hw->resp_timer_done = 1;
@@ -4363,7 +3897,7 @@ retry:
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
- if ( !timer_ok && (hw->resp_timer_done == 0) ) {
+ if (!timer_ok && (hw->resp_timer_done == 0)) {
spin_lock_irqsave(&hw->ctlxq.lock, flags);
goto delresp;
}
@@ -4371,11 +3905,10 @@ retry:
if (run_queue)
hfa384x_usbctlxq_run(hw);
- done:
- DBFEXIT;
+done:
+ ;
}
-
/*----------------------------------------------------------------
* hfa384x_usbctlx_reqtimerfn
*
@@ -4394,12 +3927,10 @@ retry:
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void
-hfa384x_usbctlx_reqtimerfn(unsigned long data)
+static void hfa384x_usbctlx_reqtimerfn(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t*)data;
- unsigned long flags;
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) data;
+ unsigned long flags;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -4408,15 +3939,13 @@ hfa384x_usbctlx_reqtimerfn(unsigned long data)
/* Removing the hardware automatically empties
* the active list ...
*/
- if ( !list_empty(&hw->ctlxq.active) )
- {
+ 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)
- {
+ if (usb_unlink_urb(&hw->ctlx_urb) == -EINPROGRESS) {
hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
ctlx->state = CTLX_REQ_FAILED;
@@ -4436,11 +3965,8 @@ hfa384x_usbctlx_reqtimerfn(unsigned long data)
}
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_usbctlx_resptimerfn
*
@@ -4459,13 +3985,10 @@ hfa384x_usbctlx_reqtimerfn(unsigned long data)
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void
-hfa384x_usbctlx_resptimerfn(unsigned long data)
+static void hfa384x_usbctlx_resptimerfn(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t*)data;
- unsigned long flags;
-
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) data;
+ unsigned long flags;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -4474,12 +3997,10 @@ hfa384x_usbctlx_resptimerfn(unsigned long data)
/* The active list will be empty if the
* adapter has been unplugged ...
*/
- if ( !list_empty(&hw->ctlxq.active) )
- {
+ if (!list_empty(&hw->ctlxq.active)) {
hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
- if ( unlocked_usbctlx_cancel_async(hw, ctlx) == 0 )
- {
+ if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) {
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
hfa384x_usbctlxq_run(hw);
goto done;
@@ -4488,8 +4009,9 @@ hfa384x_usbctlx_resptimerfn(unsigned long data)
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
- done:
- DBFEXIT;
+done:
+ ;
+
}
/*----------------------------------------------------------------
@@ -4507,13 +4029,10 @@ hfa384x_usbctlx_resptimerfn(unsigned long data)
* Call context:
* Interrupt
----------------------------------------------------------------*/
-static void
-hfa384x_usb_throttlefn(unsigned long data)
+static void hfa384x_usb_throttlefn(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t*)data;
- unsigned long flags;
-
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) data;
+ unsigned long flags;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -4521,25 +4040,20 @@ hfa384x_usb_throttlefn(unsigned long data)
* 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))
- ) )
- {
+ pr_debug("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
*
@@ -4558,16 +4072,11 @@ hfa384x_usb_throttlefn(unsigned long data)
* Call context:
* process or interrupt
----------------------------------------------------------------*/
-static int
-hfa384x_usbctlx_submit(
- hfa384x_t *hw,
- hfa384x_usbctlx_t *ctlx)
+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) {
@@ -4582,11 +4091,9 @@ hfa384x_usbctlx_submit(
ret = 0;
}
- DBFEXIT;
return ret;
}
-
/*----------------------------------------------------------------
* hfa384x_usbout_tx
*
@@ -4608,11 +4115,7 @@ hfa384x_usbctlx_submit(
----------------------------------------------------------------*/
static void hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout)
{
- DBFENTER;
-
prism2sta_ev_alloc(wlandev);
-
- DBFEXIT;
}
/*----------------------------------------------------------------
@@ -4631,10 +4134,9 @@ static void hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout)
*
* Call context:
----------------------------------------------------------------*/
-static int
-hfa384x_isgood_pdrcode(u16 pdrcode)
+static int hfa384x_isgood_pdrcode(u16 pdrcode)
{
- switch(pdrcode) {
+ switch (pdrcode) {
case HFA384x_PDR_END_OF_PDA:
case HFA384x_PDR_PCB_PARTNUM:
case HFA384x_PDR_PDAVER:
@@ -4668,23 +4170,20 @@ hfa384x_isgood_pdrcode(u16 pdrcode)
return 1;
break;
default:
- if ( pdrcode < 0x1000 ) {
+ 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);
+ printk(KERN_DEBUG
+ "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);
+ printk(KERN_DEBUG
+ "Encountered unknown PDR#=0x%04x, "
+ "(>=0x1000), assuming it's bad.\n", pdrcode);
return 0;
}
break;
}
- return 0; /* avoid compiler warnings */
+ return 0; /* avoid compiler warnings */
}
-
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
index dfc7b3a1e9c..2abce0c3444 100644
--- a/drivers/staging/wlan-ng/p80211conv.c
+++ b/drivers/staging/wlan-ng/p80211conv.c
@@ -48,10 +48,8 @@
* 802.11 frame conversions.
*
* --------------------------------------------------------------------
-*/
-/*================================================================*/
-/* System Includes */
-
+*
+*================================================================ */
#include <linux/module.h>
#include <linux/kernel.h>
@@ -63,14 +61,10 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
+#include <linux/byteorder/generic.h>
#include <asm/byteorder.h>
-#include "wlan_compat.h"
-
-/*================================================================*/
-/* Project Includes */
-
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211conv.h"
@@ -80,30 +74,8 @@
#include "p80211ioctl.h"
#include "p80211req.h"
-
-/*================================================================*/
-/* Local Constants */
-
-/*================================================================*/
-/* Local Macros */
-
-
-/*================================================================*/
-/* Local Types */
-
-
-/*================================================================*/
-/* Local Static Definitions */
-
-static u8 oui_rfc1042[] = {0x00, 0x00, 0x00};
-static u8 oui_8021h[] = {0x00, 0x00, 0xf8};
-
-/*================================================================*/
-/* Local Function Declarations */
-
-
-/*================================================================*/
-/* Function Definitions */
+static u8 oui_rfc1042[] = { 0x00, 0x00, 0x00 };
+static u8 oui_8021h[] = { 0x00, 0x00, 0xf8 };
/*----------------------------------------------------------------
* p80211pb_ether_to_80211
@@ -130,35 +102,36 @@ static u8 oui_8021h[] = {0x00, 0x00, 0xf8};
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
-int skb_ether_to_p80211( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep)
+int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
+ struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
+ p80211_metawep_t *p80211_wep)
{
- u16 fc;
- u16 proto;
- wlan_ethhdr_t e_hdr;
- wlan_llc_t *e_llc;
- wlan_snap_t *e_snap;
+ u16 fc;
+ u16 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");
+ pr_debug("zero-length skb!\n");
return 1;
}
- if ( ethconv == WLAN_ETHCONV_ENCAP ) { /* simplest case */
- WLAN_LOG_DEBUG(3, "ENCAP len: %d\n", skb->len);
+ if (ethconv == WLAN_ETHCONV_ENCAP) { /* simplest case */
+ pr_debug("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 */
+ if (proto <= 1500) {
+ pr_debug("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 */
@@ -167,23 +140,28 @@ int skb_ether_to_p80211( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
/* leave off any PAD octets. */
skb_trim(skb, proto);
} else {
- WLAN_LOG_DEBUG(3, "DIXII len: %d\n", skb->len);
+ pr_debug("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 =
+ (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);
+ 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);
+ 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 =
+ (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;
@@ -193,62 +171,61 @@ int skb_ether_to_p80211( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
/* 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));
+ fc = cpu_to_le16(WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) |
+ WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY));
- switch ( wlandev->macmode ) {
+ 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);
+ memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, ETH_ALEN);
+ memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, ETH_ALEN);
+ memcpy(p80211_hdr->a3.a3, wlandev->bssid, ETH_ALEN);
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);
+ fc |= cpu_to_le16(WLAN_SET_FC_TODS(1));
+ memcpy(p80211_hdr->a3.a1, wlandev->bssid, ETH_ALEN);
+ memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, ETH_ALEN);
+ memcpy(p80211_hdr->a3.a3, &e_hdr.daddr, ETH_ALEN);
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);
+ fc |= cpu_to_le16(WLAN_SET_FC_FROMDS(1));
+ memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, ETH_ALEN);
+ memcpy(p80211_hdr->a3.a2, wlandev->bssid, ETH_ALEN);
+ memcpy(p80211_hdr->a3.a3, &e_hdr.saddr, ETH_ALEN);
break;
default:
- WLAN_LOG_ERROR("Error: Converting eth to wlan in unknown mode.\n");
+ printk(KERN_ERR
+ "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 ((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);
+ (wlandev->
+ hostwep & HOSTWEP_DEFAULTKEY_MASK),
+ p80211_wep->iv, p80211_wep->icv))) {
+ printk(KERN_WARNING
+ "Host en-WEP failed, dropping frame (%d).\n",
+ foo);
return 2;
}
- fc |= host2ieee16(WLAN_SET_FC_ISWEP(1));
+ fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1));
}
-
- // skb->nh.raw = skb->data;
+ /* skb->nh.raw = skb->data; */
p80211_hdr->a3.fc = fc;
p80211_hdr->a3.dur = 0;
p80211_hdr->a3.seq = 0;
- DBFEXIT;
return 0;
}
@@ -256,22 +233,24 @@ int skb_ether_to_p80211( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac,
p80211_rxmeta_t *rxmeta)
{
- int i;
+ int i;
- /* Gather wireless spy statistics: for each packet, compare the
- * source address with out list, and if match, get the stats... */
+ /* 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++) {
+ for (i = 0; i < wlandev->spy_number; i++) {
- if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) {
+ 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;
- }
- }
+ 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;
+ }
+ }
}
/*----------------------------------------------------------------
@@ -293,43 +272,42 @@ static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac,
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
-int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb)
+int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
+ struct sk_buff *skb)
{
- netdevice_t *netdev = wlandev->netdev;
- u16 fc;
- unsigned int payload_length;
- unsigned int payload_offset;
- u8 daddr[WLAN_ETHADDR_LEN];
- u8 saddr[WLAN_ETHADDR_LEN];
- p80211_hdr_t *w_hdr;
- wlan_ethhdr_t *e_hdr;
- wlan_llc_t *e_llc;
- wlan_snap_t *e_snap;
+ netdevice_t *netdev = wlandev->netdev;
+ u16 fc;
+ unsigned int payload_length;
+ unsigned int payload_offset;
+ u8 daddr[WLAN_ETHADDR_LEN];
+ u8 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) ) {
+ /* setup some vars for convenience */
+ fc = le16_to_cpu(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) ) {
+ } 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) ) {
+ } 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;
if (payload_length < WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN) {
- WLAN_LOG_ERROR("A4 frame too short!\n");
+ printk(KERN_ERR "A4 frame too short!\n");
return 1;
}
payload_length -= (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN);
@@ -338,18 +316,22 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
}
/* perform de-wep if necessary.. */
- if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && WLAN_GET_FC_ISWEP(fc) && (wlandev->hostwep & HOSTWEP_DECRYPT)) {
+ 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);
+ printk(KERN_ERR "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))) {
+ 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);
+ printk(KERN_DEBUG
+ "Host de-WEP failed, dropping frame (%d).\n",
+ foo);
wlandev->rx.decrypt_err++;
return 2;
}
@@ -367,21 +349,22 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
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));
+ 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) ||
+ 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);
+ pr_debug("802.3 ENCAP len: %d\n", payload_length);
/* 802.3 Encapsulated */
/* Test for an overlength frame */
- if ( payload_length > (netdev->mtu + WLAN_ETHHDR_LEN)) {
+ 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);
+ printk(KERN_ERR "ENCAP frame too large (%d > %d)\n",
+ payload_length, netdev->mtu + WLAN_ETHHDR_LEN);
return 1;
}
@@ -390,25 +373,25 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
/* 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);
+ } 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(le16_to_cpu(e_snap->type))))
+ || (memcmp(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN) !=
+ 0))) {
+ pr_debug("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 ) {
+ 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);
+ printk(KERN_ERR "SNAP frame too large (%d > %d)\n",
+ payload_length, netdev->mtu);
return 1;
}
@@ -424,11 +407,10 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
/* 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);
+ } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t))
+ && (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa)
+ && (e_llc->ctl == 0x03)) {
+ pr_debug("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 */
@@ -437,10 +419,9 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
> 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);
+ printk(KERN_ERR "DIXII frame too large (%ld > %d)\n",
+ (long int)(payload_length - sizeof(wlan_llc_t) -
+ sizeof(wlan_snap_t)), netdev->mtu);
return 1;
}
@@ -462,19 +443,18 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
/* 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);
+ pr_debug("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 ) {
+ 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);
+ printk(KERN_ERR "OTHER frame too large (%d > %d)\n",
+ payload_length, netdev->mtu);
return 1;
}
@@ -492,26 +472,26 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
}
- /*
- * Note that eth_type_trans() expects an skb w/ skb->data pointing
- * at the MAC header, it then sets the following skb members:
- * skb->mac_header,
- * skb->data, and
- * skb->pkt_type.
- * It then _returns_ the value that _we're_ supposed to stuff in
- * skb->protocol. This is nuts.
- */
+ /*
+ * Note that eth_type_trans() expects an skb w/ skb->data pointing
+ * at the MAC header, it then sets the following skb members:
+ * skb->mac_header,
+ * skb->data, and
+ * skb->pkt_type.
+ * It then _returns_ the value that _we're_ supposed to stuff in
+ * skb->protocol. This is nuts.
+ */
skb->protocol = eth_type_trans(skb, netdev);
- /* jkriegl: process signal and noise as set in hfa384x_int_rx() */
+ /* 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));
+ 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;
}
@@ -536,11 +516,11 @@ int p80211_stt_findproto(u16 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.
- */
+ need this to match the CMAC's way of doing things.
+ Need to do some testing to confirm.
+ */
- if (proto == 0x80f3) /* APPLETALK */
+ if (proto == 0x80f3) /* APPLETALK */
return 1;
return 0;
@@ -561,26 +541,24 @@ int p80211_stt_findproto(u16 proto)
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
-void
-p80211skb_rxmeta_detach(struct sk_buff *skb)
+void p80211skb_rxmeta_detach(struct sk_buff *skb)
{
- p80211_rxmeta_t *rxmeta;
- p80211_frmmeta_t *frmmeta;
+ 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");
+ if (skb == NULL) { /* bad skb */
+ pr_debug("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");
+ if (frmmeta == NULL) { /* no magic */
+ pr_debug("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");
+ if (rxmeta == NULL) { /* bad meta ptr */
+ pr_debug("Called w/ bad rxmeta ptr.\n");
goto exit;
}
@@ -590,7 +568,6 @@ p80211skb_rxmeta_detach(struct sk_buff *skb)
/* Clear skb->cb */
memset(skb->cb, 0, sizeof(skb->cb));
exit:
- DBFEXIT;
return;
}
@@ -610,19 +587,16 @@ exit:
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
-int
-p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
+int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
{
- int result = 0;
- p80211_rxmeta_t *rxmeta;
- p80211_frmmeta_t *frmmeta;
-
- DBFENTER;
+ int result = 0;
+ p80211_rxmeta_t *rxmeta;
+ p80211_frmmeta_t *frmmeta;
/* If these already have metadata, we error out! */
if (P80211SKB_RXMETA(skb) != NULL) {
- WLAN_LOG_ERROR("%s: RXmeta already attached!\n",
- wlandev->name);
+ printk(KERN_ERR "%s: RXmeta already attached!\n",
+ wlandev->name);
result = 0;
goto exit;
}
@@ -630,9 +604,9 @@ p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
/* 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);
+ if (rxmeta == NULL) {
+ printk(KERN_ERR "%s: Failed to allocate rxmeta.\n",
+ wlandev->name);
result = 1;
goto exit;
}
@@ -644,11 +618,10 @@ p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
/* Overlay a frmmeta_t onto skb->cb */
memset(skb->cb, 0, sizeof(p80211_frmmeta_t));
- frmmeta = (p80211_frmmeta_t*)(skb->cb);
+ frmmeta = (p80211_frmmeta_t *) (skb->cb);
frmmeta->magic = P80211_FRMMETA_MAGIC;
frmmeta->rx = rxmeta;
exit:
- DBFEXIT;
return result;
}
@@ -668,19 +641,15 @@ exit:
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
-void
-p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb)
+void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb)
{
- p80211_frmmeta_t *meta;
- DBFENTER;
+ p80211_frmmeta_t *meta;
+
meta = P80211SKB_FRMMETA(skb);
- if ( meta && meta->rx) {
+ if (meta && meta->rx)
p80211skb_rxmeta_detach(skb);
- } else {
- WLAN_LOG_ERROR("Freeing an skb (%p) w/ no frmmeta.\n", skb);
- }
-
+ else
+ printk(KERN_ERR "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
index 538e9bd1490..6fe163be24f 100644
--- a/drivers/staging/wlan-ng/p80211conv.h
+++ b/drivers/staging/wlan-ng/p80211conv.h
@@ -53,134 +53,109 @@
#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)) : \
+ (((((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)))
+ (P80211SKB_FRMMETA((s)) ? P80211SKB_FRMMETA((s))->rx : ((p80211_rxmeta_t *)(NULL)))
-typedef struct p80211_rxmeta
-{
- struct wlandevice *wlandev;
+typedef struct p80211_rxmeta {
+ struct wlandevice *wlandev;
- u64 mactime; /* Hi-rez MAC-supplied time value */
- u64 hosttime; /* Best-rez host supplied time value */
+ u64 mactime; /* Hi-rez MAC-supplied time value */
+ u64 hosttime; /* Best-rez host supplied time value */
- unsigned int rxrate; /* Receive data rate in 100kbps */
- unsigned int priority; /* 0-15, 0=contention, 6=CF */
- int signal; /* An SSI, see p80211netdev.h */
- int noise; /* An SSI, see p80211netdev.h */
- unsigned int channel; /* Receive channel (mostly for snifs) */
- unsigned int preamble; /* P80211ENUM_preambletype_* */
- unsigned int encoding; /* P80211ENUM_encoding_* */
+ unsigned int rxrate; /* Receive data rate in 100kbps */
+ unsigned int priority; /* 0-15, 0=contention, 6=CF */
+ int signal; /* An SSI, see p80211netdev.h */
+ int noise; /* An SSI, see p80211netdev.h */
+ unsigned int channel; /* Receive channel (mostly for snifs) */
+ unsigned int preamble; /* P80211ENUM_preambletype_* */
+ unsigned int encoding; /* P80211ENUM_encoding_* */
} p80211_rxmeta_t;
-typedef struct p80211_frmmeta
-{
- unsigned int magic;
- p80211_rxmeta_t *rx;
+typedef struct p80211_frmmeta {
+ unsigned int 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
-{
- u32 version;
- u32 length;
- u64 mactime;
- u64 hosttime;
- u32 phytype;
- u32 channel;
- u32 datarate;
- u32 antenna;
- u32 priority;
- u32 ssi_type;
- s32 ssi_signal;
- s32 ssi_noise;
- u32 preamble;
- u32 encoding;
+typedef struct p80211_caphdr {
+ u32 version;
+ u32 length;
+ u64 mactime;
+ u64 hosttime;
+ u32 phytype;
+ u32 channel;
+ u32 datarate;
+ u32 antenna;
+ u32 priority;
+ u32 ssi_type;
+ s32 ssi_signal;
+ s32 ssi_noise;
+ u32 preamble;
+ u32 encoding;
} p80211_caphdr_t;
/* buffer free method pointer type */
-typedef void (* freebuf_method_t)(void *buf, int size);
+typedef void (*freebuf_method_t) (void *buf, int size);
typedef struct p80211_metawep {
- void *data;
+ void *data;
u8 iv[4];
u8 icv[4];
} p80211_metawep_t;
/* local ether header type */
-typedef struct wlan_ethhdr
-{
- u8 daddr[WLAN_ETHADDR_LEN];
- u8 saddr[WLAN_ETHADDR_LEN];
- u16 type;
-} __WLAN_ATTRIB_PACK__ wlan_ethhdr_t;
+typedef struct wlan_ethhdr {
+ u8 daddr[WLAN_ETHADDR_LEN];
+ u8 saddr[WLAN_ETHADDR_LEN];
+ u16 type;
+} __attribute__ ((packed)) wlan_ethhdr_t;
/* local llc header type */
-typedef struct wlan_llc
-{
- u8 dsap;
- u8 ssap;
- u8 ctl;
-} __WLAN_ATTRIB_PACK__ wlan_llc_t;
+typedef struct wlan_llc {
+ u8 dsap;
+ u8 ssap;
+ u8 ctl;
+} __attribute__ ((packed)) wlan_llc_t;
/* local snap header type */
-typedef struct wlan_snap
-{
- u8 oui[WLAN_IEEE_OUI_LEN];
- u16 type;
-} __WLAN_ATTRIB_PACK__ wlan_snap_t;
+typedef struct wlan_snap {
+ u8 oui[WLAN_IEEE_OUI_LEN];
+ u16 type;
+} __attribute__ ((packed)) wlan_snap_t;
/* Circular include trick */
struct wlandevice;
-/*================================================================*/
-/* Externs */
-
-/*================================================================*/
-/*Function Declarations */
-
-int skb_p80211_to_ether( struct wlandevice *wlandev, u32 ethconv,
- struct sk_buff *skb);
-int skb_ether_to_p80211( struct wlandevice *wlandev, u32 ethconv,
- struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
- p80211_metawep_t *p80211_wep );
+int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv,
+ struct sk_buff *skb);
+int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv,
+ struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
+ p80211_metawep_t *p80211_wep);
int p80211_stt_findproto(u16 proto);
-int p80211_stt_addproto(u16 proto);
#endif
diff --git a/drivers/staging/wlan-ng/p80211hdr.h b/drivers/staging/wlan-ng/p80211hdr.h
index 72f12aff390..ded47751769 100644
--- a/drivers/staging/wlan-ng/p80211hdr.h
+++ b/drivers/staging/wlan-ng/p80211hdr.h
@@ -63,43 +63,23 @@
/*================================================================*/
/* System Includes */
+#include <linux/if_ether.h>
+
/*================================================================*/
/* 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
@@ -143,7 +123,6 @@
#define WLAN_FSTYPE_CFPOLL 0x06
#define WLAN_FSTYPE_CFACK_CFPOLL 0x07
-
/*================================================================*/
/* Macros */
@@ -166,97 +145,51 @@
/* SET_FC_FSTYPE(WLAN_FSTYPE_RTS) ); */
/*------------------------------------------------------------*/
-#define WLAN_GET_FC_PVER(n) (((u16)(n)) & (BIT0 | BIT1))
-#define WLAN_GET_FC_FTYPE(n) ((((u16)(n)) & (BIT2 | BIT3)) >> 2)
-#define WLAN_GET_FC_FSTYPE(n) ((((u16)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
-#define WLAN_GET_FC_TODS(n) ((((u16)(n)) & (BIT8)) >> 8)
-#define WLAN_GET_FC_FROMDS(n) ((((u16)(n)) & (BIT9)) >> 9)
-#define WLAN_GET_FC_MOREFRAG(n) ((((u16)(n)) & (BIT10)) >> 10)
-#define WLAN_GET_FC_RETRY(n) ((((u16)(n)) & (BIT11)) >> 11)
-#define WLAN_GET_FC_PWRMGT(n) ((((u16)(n)) & (BIT12)) >> 12)
-#define WLAN_GET_FC_MOREDATA(n) ((((u16)(n)) & (BIT13)) >> 13)
-#define WLAN_GET_FC_ISWEP(n) ((((u16)(n)) & (BIT14)) >> 14)
-#define WLAN_GET_FC_ORDER(n) ((((u16)(n)) & (BIT15)) >> 15)
+#define WLAN_GET_FC_FTYPE(n) ((((u16)(n)) & (BIT(2) | BIT(3))) >> 2)
+#define WLAN_GET_FC_FSTYPE(n) ((((u16)(n)) & (BIT(4)|BIT(5)|BIT(6)|BIT(7))) >> 4)
+#define WLAN_GET_FC_TODS(n) ((((u16)(n)) & (BIT(8))) >> 8)
+#define WLAN_GET_FC_FROMDS(n) ((((u16)(n)) & (BIT(9))) >> 9)
+#define WLAN_GET_FC_ISWEP(n) ((((u16)(n)) & (BIT(14))) >> 14)
-#define WLAN_SET_FC_PVER(n) ((u16)(n))
#define WLAN_SET_FC_FTYPE(n) (((u16)(n)) << 2)
#define WLAN_SET_FC_FSTYPE(n) (((u16)(n)) << 4)
#define WLAN_SET_FC_TODS(n) (((u16)(n)) << 8)
#define WLAN_SET_FC_FROMDS(n) (((u16)(n)) << 9)
-#define WLAN_SET_FC_MOREFRAG(n) (((u16)(n)) << 10)
-#define WLAN_SET_FC_RETRY(n) (((u16)(n)) << 11)
-#define WLAN_SET_FC_PWRMGT(n) (((u16)(n)) << 12)
-#define WLAN_SET_FC_MOREDATA(n) (((u16)(n)) << 13)
#define WLAN_SET_FC_ISWEP(n) (((u16)(n)) << 14)
-#define WLAN_SET_FC_ORDER(n) (((u16)(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) (((u16)(n)) & (BIT0|BIT1|BIT2|BIT3))
-#define WLAN_GET_SEQ_SEQNUM(n) ((((u16)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
-
-/*--- Data ptr macro -----------------------------------------*/
-/* Creates a u8* 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) (((u8*)(p)) + WLAN_HDR_A3_LEN)
-#define WLAN_HDR_A4_DATAP(p) (((u8*)(p)) + WLAN_HDR_A4_LEN)
-
-#define DOT11_RATE5_ISBASIC_GET(r) (((u8)(r)) & BIT7)
+#define DOT11_RATE5_ISBASIC_GET(r) (((u8)(r)) & BIT(7))
/*================================================================*/
/* Types */
-/* BSS Timestamp */
-typedef u8 wlan_bss_ts_t[WLAN_BSS_TS_LEN];
-
/* Generic 802.11 Header types */
-typedef struct p80211_hdr_a3
-{
- u16 fc;
- u16 dur;
- u8 a1[WLAN_ADDR_LEN];
- u8 a2[WLAN_ADDR_LEN];
- u8 a3[WLAN_ADDR_LEN];
- u16 seq;
-} __WLAN_ATTRIB_PACK__ p80211_hdr_a3_t;
-
-typedef struct p80211_hdr_a4
-{
- u16 fc;
- u16 dur;
- u8 a1[WLAN_ADDR_LEN];
- u8 a2[WLAN_ADDR_LEN];
- u8 a3[WLAN_ADDR_LEN];
- u16 seq;
- u8 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 */
+typedef struct p80211_hdr_a3 {
+ u16 fc;
+ u16 dur;
+ u8 a1[ETH_ALEN];
+ u8 a2[ETH_ALEN];
+ u8 a3[ETH_ALEN];
+ u16 seq;
+} __attribute__ ((packed)) p80211_hdr_a3_t;
+
+typedef struct p80211_hdr_a4 {
+ u16 fc;
+ u16 dur;
+ u8 a1[ETH_ALEN];
+ u8 a2[ETH_ALEN];
+ u8 a3[ETH_ALEN];
+ u16 seq;
+ u8 a4[ETH_ALEN];
+} __attribute__ ((packed)) p80211_hdr_a4_t;
+
+typedef union p80211_hdr {
+ p80211_hdr_a3_t a3;
+ p80211_hdr_a4_t a4;
+} __attribute__ ((packed)) p80211_hdr_t;
+
+
+/* Frame and header length macros */
#define WLAN_CTL_FRAMELEN(fstype) (\
(fstype) == WLAN_FSTYPE_BLOCKACKREQ ? 24 : \
@@ -271,23 +204,22 @@ typedef union p80211_hdr
#define WLAN_FCS_LEN 4
/* ftcl in HOST order */
-inline static u16 p80211_headerlen(u16 fctl)
+static inline u16 p80211_headerlen(u16 fctl)
{
u16 hdrlen = 0;
- switch ( WLAN_GET_FC_FTYPE(fctl) ) {
+ 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;
- }
+ if (WLAN_GET_FC_TODS(fctl) && WLAN_GET_FC_FROMDS(fctl))
+ hdrlen += ETH_ALEN;
break;
case WLAN_FTYPE_CTL:
hdrlen = WLAN_CTL_FRAMELEN(WLAN_GET_FC_FSTYPE(fctl)) -
- WLAN_FCS_LEN;
+ WLAN_FCS_LEN;
break;
default:
hdrlen = WLAN_HDR_A3_LEN;
diff --git a/drivers/staging/wlan-ng/p80211ioctl.h b/drivers/staging/wlan-ng/p80211ioctl.h
index ad67b698fa4..64ca7f95262 100644
--- a/drivers/staging/wlan-ng/p80211ioctl.h
+++ b/drivers/staging/wlan-ng/p80211ioctl.h
@@ -60,14 +60,9 @@
* --------------------------------------------------------------------
*/
-
#ifndef _P80211IOCTL_H
#define _P80211IOCTL_H
-/*================================================================*/
-/* Constants */
-
-/*----------------------------------------------------------------*/
/* p80211 ioctl "request" codes. See argument 2 of ioctl(2). */
#define P80211_IFTEST (SIOCDEVPRIVATE + 0)
@@ -79,45 +74,16 @@
#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];
+typedef struct p80211ioctl_req {
+ char name[WLAN_DEVNAMELEN_MAX];
caddr_t data;
- u32 magic;
- u16 len;
- u32 result;
-} __WLAN_ATTRIB_PACK__ p80211ioctl_req_t;
-
-
-/*================================================================*/
-/* Extern Declarations */
-
-
-/*================================================================*/
-/* Function Declarations */
-
+ u32 magic;
+ u16 len;
+ u32 result;
+} __attribute__ ((packed)) p80211ioctl_req_t;
#endif /* _P80211IOCTL_H */
diff --git a/drivers/staging/wlan-ng/p80211meta.h b/drivers/staging/wlan-ng/p80211meta.h
index 8b61e5fc292..2f3c9fc3358 100644
--- a/drivers/staging/wlan-ng/p80211meta.h
+++ b/drivers/staging/wlan-ng/p80211meta.h
@@ -58,50 +58,8 @@
#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) (**((u32**)(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 */
@@ -111,59 +69,29 @@
/* 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 */
- u32 did; /* partial did */
- u32 flags; /* set of various flag bits */
- u32 min; /* min value of a BOUNDEDint */
- u32 max; /* max value of a BOUNDEDint */
-
- u32 maxlen; /* maxlen of a OCTETSTR or DISPLAYSTR */
- u32 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 */
+typedef struct p80211meta {
+ char *name; /* data item name */
+ u32 did; /* partial did */
+ u32 flags; /* set of various flag bits */
+ u32 min; /* min value of a BOUNDEDint */
+ u32 max; /* max value of a BOUNDEDint */
+
+ u32 maxlen; /* maxlen of a OCTETSTR or DISPLAYSTR */
+ u32 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;
+typedef struct grplistitem {
+ char *name;
+ p80211meta_t *itemlist;
} grplistitem_t;
-typedef struct catlistitem
-{
- char *name;
- grplistitem_t *grplist;
+typedef struct catlistitem {
+ char *name;
+ grplistitem_t *grplist;
} catlistitem_t;
-/*================================================================*/
-/* Extern Declarations */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Function Declarations */
-
-/*----------------------------------------------------------------*/
-/* */
-u32 p80211_text2did(catlistitem_t *catlist, char *catname, char *grpname, char *itemname);
-u32 p80211_text2catdid(catlistitem_t *list, char *name );
-u32 p80211_text2grpdid(grplistitem_t *list, char *name );
-u32 p80211_text2itemdid(p80211meta_t *list, char *name );
-u32 p80211_isvalid_did( catlistitem_t *catlist, u32 did );
-u32 p80211_isvalid_catdid( catlistitem_t *catlist, u32 did );
-u32 p80211_isvalid_grpdid( catlistitem_t *catlist, u32 did );
-u32 p80211_isvalid_itemdid( catlistitem_t *catlist, u32 did );
-catlistitem_t *p80211_did2cat( catlistitem_t *catlist, u32 did );
-grplistitem_t *p80211_did2grp( catlistitem_t *catlist, u32 did );
-p80211meta_t *p80211_did2item( catlistitem_t *catlist, u32 did );
-u32 p80211item_maxdatalen( struct catlistitem *metalist, u32 did );
-u32 p80211_metaname2did(struct catlistitem *metalist, char *itemname);
-u32 p80211item_getoffset( struct catlistitem *metalist, u32 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
index ce4fdd547fc..a29d6ae3e77 100644
--- a/drivers/staging/wlan-ng/p80211metadef.h
+++ b/drivers/staging/wlan-ng/p80211metadef.h
@@ -47,20 +47,9 @@
#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))
@@ -75,579 +64,48 @@
#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_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_p2req \
- P80211DID_MKSECTION(5)
#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_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 DIDmib_cat_dot11smt \
P80211DID_MKSECTION(1)
#define DIDmib_dot11smt_dot11WEPDefaultKeysTable \
@@ -684,8 +142,6 @@
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(4) | 0x18000000)
-#define DIDmib_cat_dot11mac \
- P80211DID_MKSECTION(2)
#define DIDmib_dot11mac_dot11OperationTable \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1))
diff --git a/drivers/staging/wlan-ng/p80211metamib.h b/drivers/staging/wlan-ng/p80211metamib.h
deleted file mode 100644
index 9cd72ede441..00000000000
--- a/drivers/staging/wlan-ng/p80211metamib.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* 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 u32 mib_catlist_size;
-
-
-/*================================================================*/
-/* Function Declarations */
-
-/*----------------------------------------------------------------*/
-/* */
-
-#endif /* _P80211METAMIB_H */
diff --git a/drivers/staging/wlan-ng/p80211metamsg.h b/drivers/staging/wlan-ng/p80211metamsg.h
deleted file mode 100644
index 6e659eae8af..00000000000
--- a/drivers/staging/wlan-ng/p80211metamsg.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* 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 u32 msg_catlist_size;
-
-
-/*================================================================*/
-/* Function Declarations */
-
-/*----------------------------------------------------------------*/
-/* */
-
-#endif /* _P80211METAMSG_H */
diff --git a/drivers/staging/wlan-ng/p80211metastruct.h b/drivers/staging/wlan-ng/p80211metastruct.h
index d2258b0e89c..db12713eeaa 100644
--- a/drivers/staging/wlan-ng/p80211metastruct.h
+++ b/drivers/staging/wlan-ng/p80211metastruct.h
@@ -47,239 +47,223 @@
#ifndef _P80211MKMETASTRUCT_H
#define _P80211MKMETASTRUCT_H
+typedef struct p80211msg_dot11req_mibget {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_unk392_t mibattribute;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_dot11req_mibget_t;
-typedef struct p80211msg_dot11req_mibget
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_unk392_t mibattribute ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibget_t;
+typedef struct p80211msg_dot11req_mibset {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_unk392_t mibattribute;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_dot11req_mibset_t;
-typedef struct p80211msg_dot11req_mibset
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_unk392_t mibattribute ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibset_t;
+typedef struct p80211msg_dot11req_scan {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t bsstype;
+ p80211item_pstr6_t bssid;
+ u8 pad_0C[1];
+ p80211item_pstr32_t ssid;
+ u8 pad_1D[3];
+ p80211item_uint32_t scantype;
+ p80211item_uint32_t probedelay;
+ p80211item_pstr14_t channellist;
+ u8 pad_2C[1];
+ p80211item_uint32_t minchanneltime;
+ p80211item_uint32_t maxchanneltime;
+ p80211item_uint32_t resultcode;
+ p80211item_uint32_t numbss;
+ p80211item_uint32_t append;
+} __attribute__ ((packed)) p80211msg_dot11req_scan_t;
-typedef struct p80211msg_dot11req_scan
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_uint32_t bsstype ;
- p80211item_pstr6_t bssid ;
- u8 pad_0C[1] ;
- p80211item_pstr32_t ssid ;
- u8 pad_1D[3] ;
- p80211item_uint32_t scantype ;
- p80211item_uint32_t probedelay ;
- p80211item_pstr14_t channellist ;
- u8 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 {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t bssindex;
+ p80211item_uint32_t resultcode;
+ p80211item_uint32_t signal;
+ p80211item_uint32_t noise;
+ p80211item_pstr6_t bssid;
+ u8 pad_3C[1];
+ p80211item_pstr32_t ssid;
+ u8 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;
+} __attribute__ ((packed)) p80211msg_dot11req_scan_results_t;
-typedef struct p80211msg_dot11req_scan_results
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_uint32_t bssindex ;
- p80211item_uint32_t resultcode ;
- p80211item_uint32_t signal ;
- p80211item_uint32_t noise ;
- p80211item_pstr6_t bssid ;
- u8 pad_3C[1] ;
- p80211item_pstr32_t ssid ;
- u8 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_start {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_pstr32_t ssid;
+ u8 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;
+} __attribute__ ((packed)) p80211msg_dot11req_start_t;
-typedef struct p80211msg_dot11req_start
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_pstr32_t ssid ;
- u8 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_lnxreq_ifstate {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t ifstate;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_lnxreq_ifstate_t;
-typedef struct p80211msg_lnxreq_ifstate
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_uint32_t ifstate ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_ifstate_t;
+typedef struct p80211msg_lnxreq_wlansniff {
+ u32 msgcode;
+ u32 msglen;
+ u8 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;
+} __attribute__ ((packed)) p80211msg_lnxreq_wlansniff_t;
-typedef struct p80211msg_lnxreq_wlansniff
-{
- u32 msgcode ;
- u32 msglen ;
- u8 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 {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t resultcode;
+ p80211item_uint32_t decrypt;
+ p80211item_uint32_t encrypt;
+} __attribute__ ((packed)) p80211msg_lnxreq_hostwep_t;
-typedef struct p80211msg_lnxreq_hostwep
-{
- u32 msgcode ;
- u32 msglen ;
- u8 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 {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t resultcode;
+ p80211item_uint32_t dbm;
+ p80211item_uint32_t link;
+ p80211item_uint32_t level;
+ p80211item_uint32_t noise;
+} __attribute__ ((packed)) p80211msg_lnxreq_commsquality_t;
-typedef struct p80211msg_lnxreq_commsquality
-{
- u32 msgcode ;
- u32 msglen ;
- u8 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 {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_pstr32_t ssid;
+ u8 pad_19D[3];
+ p80211item_uint32_t authtype;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_lnxreq_autojoin_t;
-typedef struct p80211msg_lnxreq_autojoin
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_pstr32_t ssid ;
- u8 pad_19D[3] ;
- p80211item_uint32_t authtype ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_autojoin_t;
+typedef struct p80211msg_p2req_readpda {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_unk1024_t pda;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_readpda_t;
-typedef struct p80211msg_p2req_readpda
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_unk1024_t pda ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_p2req_readpda_t;
+typedef struct p80211msg_p2req_ramdl_state {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t enable;
+ p80211item_uint32_t exeaddr;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_ramdl_state_t;
-typedef struct p80211msg_p2req_ramdl_state
-{
- u32 msgcode ;
- u32 msglen ;
- u8 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 {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t addr;
+ p80211item_uint32_t len;
+ p80211item_unk4096_t data;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_ramdl_write_t;
-typedef struct p80211msg_p2req_ramdl_write
-{
- u32 msgcode ;
- u32 msglen ;
- u8 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 {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t enable;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_flashdl_state_t;
-typedef struct p80211msg_p2req_flashdl_state
-{
- u32 msgcode ;
- u32 msglen ;
- u8 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
-{
- u32 msgcode ;
- u32 msglen ;
- u8 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_flashdl_write {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t addr;
+ p80211item_uint32_t len;
+ p80211item_unk4096_t data;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_flashdl_write_t;
#endif
diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h
index 6cc16c3f8b1..6235fe7f235 100644
--- a/drivers/staging/wlan-ng/p80211mgmt.h
+++ b/drivers/staging/wlan-ng/p80211mgmt.h
@@ -101,14 +101,8 @@
#define _P80211MGMT_H
/*================================================================*/
-/* System Includes */
-
-/*================================================================*/
/* Project Includes */
-#ifndef _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
#ifndef _P80211HDR_H
#include "p80211hdr.h"
@@ -160,8 +154,6 @@
#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
@@ -211,20 +203,16 @@
#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)
+#define WLAN_GET_MGMT_CAP_INFO_ESS(n) ((n) & BIT(0))
+#define WLAN_GET_MGMT_CAP_INFO_IBSS(n) (((n) & BIT(1)) >> 1)
+#define WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(n) (((n) & BIT(2)) >> 2)
+#define WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(n) (((n) & BIT(3)) >> 3)
+#define WLAN_GET_MGMT_CAP_INFO_PRIVACY(n) (((n) & BIT(4)) >> 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_GET_MGMT_CAP_INFO_SHORT(n) (((n) & BIT(5)) >> 5)
+#define WLAN_GET_MGMT_CAP_INFO_PBCC(n) (((n) & BIT(6)) >> 6)
+#define WLAN_GET_MGMT_CAP_INFO_AGILITY(n) (((n) & BIT(7)) >> 7)
#define WLAN_SET_MGMT_CAP_INFO_ESS(n) (n)
#define WLAN_SET_MGMT_CAP_INFO_IBSS(n) ((n) << 1)
@@ -236,143 +224,126 @@
#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
-{
- u8 eid;
- u8 len;
-} __WLAN_ATTRIB_PACK__ wlan_ie_t;
+typedef struct wlan_ie {
+ u8 eid;
+ u8 len;
+} __attribute__ ((packed)) wlan_ie_t;
/*-- Service Set Identity (SSID) -----------------*/
-typedef struct wlan_ie_ssid
-{
- u8 eid;
- u8 len;
- u8 ssid[1]; /* may be zero, ptrs may overlap */
-} __WLAN_ATTRIB_PACK__ wlan_ie_ssid_t;
+typedef struct wlan_ie_ssid {
+ u8 eid;
+ u8 len;
+ u8 ssid[1]; /* may be zero, ptrs may overlap */
+} __attribute__ ((packed)) wlan_ie_ssid_t;
/*-- Supported Rates -----------------------------*/
-typedef struct wlan_ie_supp_rates
-{
- u8 eid;
- u8 len;
- u8 rates[1]; /* had better be at LEAST one! */
-} __WLAN_ATTRIB_PACK__ wlan_ie_supp_rates_t;
+typedef struct wlan_ie_supp_rates {
+ u8 eid;
+ u8 len;
+ u8 rates[1]; /* had better be at LEAST one! */
+} __attribute__ ((packed)) wlan_ie_supp_rates_t;
/*-- FH Parameter Set ----------------------------*/
-typedef struct wlan_ie_fh_parms
-{
- u8 eid;
- u8 len;
- u16 dwell;
- u8 hopset;
- u8 hoppattern;
- u8 hopindex;
-} __WLAN_ATTRIB_PACK__ wlan_ie_fh_parms_t;
+typedef struct wlan_ie_fh_parms {
+ u8 eid;
+ u8 len;
+ u16 dwell;
+ u8 hopset;
+ u8 hoppattern;
+ u8 hopindex;
+} __attribute__ ((packed)) wlan_ie_fh_parms_t;
/*-- DS Parameter Set ----------------------------*/
-typedef struct wlan_ie_ds_parms
-{
- u8 eid;
- u8 len;
- u8 curr_ch;
-} __WLAN_ATTRIB_PACK__ wlan_ie_ds_parms_t;
+typedef struct wlan_ie_ds_parms {
+ u8 eid;
+ u8 len;
+ u8 curr_ch;
+} __attribute__ ((packed)) wlan_ie_ds_parms_t;
/*-- CF Parameter Set ----------------------------*/
-typedef struct wlan_ie_cf_parms
-{
- u8 eid;
- u8 len;
- u8 cfp_cnt;
- u8 cfp_period;
- u16 cfp_maxdur;
- u16 cfp_durremaining;
-} __WLAN_ATTRIB_PACK__ wlan_ie_cf_parms_t;
+typedef struct wlan_ie_cf_parms {
+ u8 eid;
+ u8 len;
+ u8 cfp_cnt;
+ u8 cfp_period;
+ u16 cfp_maxdur;
+ u16 cfp_durremaining;
+} __attribute__ ((packed)) wlan_ie_cf_parms_t;
/*-- TIM ------------------------------------------*/
-typedef struct wlan_ie_tim
-{
- u8 eid;
- u8 len;
- u8 dtim_cnt;
- u8 dtim_period;
- u8 bitmap_ctl;
- u8 virt_bm[1];
-} __WLAN_ATTRIB_PACK__ wlan_ie_tim_t;
+typedef struct wlan_ie_tim {
+ u8 eid;
+ u8 len;
+ u8 dtim_cnt;
+ u8 dtim_period;
+ u8 bitmap_ctl;
+ u8 virt_bm[1];
+} __attribute__ ((packed)) wlan_ie_tim_t;
/*-- IBSS Parameter Set ---------------------------*/
-typedef struct wlan_ie_ibss_parms
-{
- u8 eid;
- u8 len;
- u16 atim_win;
-} __WLAN_ATTRIB_PACK__ wlan_ie_ibss_parms_t;
+typedef struct wlan_ie_ibss_parms {
+ u8 eid;
+ u8 len;
+ u16 atim_win;
+} __attribute__ ((packed)) wlan_ie_ibss_parms_t;
/*-- Challenge Text ------------------------------*/
-typedef struct wlan_ie_challenge
-{
- u8 eid;
- u8 len;
- u8 challenge[1];
-} __WLAN_ATTRIB_PACK__ wlan_ie_challenge_t;
+typedef struct wlan_ie_challenge {
+ u8 eid;
+ u8 len;
+ u8 challenge[1];
+} __attribute__ ((packed)) wlan_ie_challenge_t;
/*-------------------------------------------------*/
/* Frame Types */
/* prototype structure, all mgmt frame types will start with these members */
-typedef struct wlan_fr_mgmt
-{
- u16 type;
- u16 len; /* DOES NOT include CRC !!!!*/
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_mgmt {
+ u16 type;
+ u16 len; /* DOES NOT include CRC !!!! */
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
/*-- info elements ----------*/
} wlan_fr_mgmt_t;
/*-- Beacon ---------------------------------------*/
-typedef struct wlan_fr_beacon
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_beacon {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u64 *ts;
- u16 *bcn_int;
- u16 *cap_info;
+ u64 *ts;
+ u16 *bcn_int;
+ u16 *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_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
-{
- u16 type;
- u16 len;
- u8* buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_ibssatim {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
/*-- info elements ----------*/
@@ -382,194 +353,176 @@ typedef struct wlan_fr_ibssatim
} wlan_fr_ibssatim_t;
/*-- Disassociation -------------------------------*/
-typedef struct wlan_fr_disassoc
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_disassoc {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *reason;
+ u16 *reason;
/*-- info elements ----------*/
} wlan_fr_disassoc_t;
/*-- Association Request --------------------------*/
-typedef struct wlan_fr_assocreq
-{
- u16 type;
- u16 len;
- u8* buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_assocreq {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *cap_info;
- u16 *listen_int;
+ u16 *cap_info;
+ u16 *listen_int;
/*-- info elements ----------*/
- wlan_ie_ssid_t *ssid;
- wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_ssid_t *ssid;
+ wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_assocreq_t;
/*-- Association Response -------------------------*/
-typedef struct wlan_fr_assocresp
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_assocresp {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *cap_info;
- u16 *status;
- u16 *aid;
+ u16 *cap_info;
+ u16 *status;
+ u16 *aid;
/*-- info elements ----------*/
- wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_assocresp_t;
/*-- Reassociation Request ------------------------*/
-typedef struct wlan_fr_reassocreq
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_reassocreq {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *cap_info;
- u16 *listen_int;
- u8 *curr_ap;
+ u16 *cap_info;
+ u16 *listen_int;
+ u8 *curr_ap;
/*-- info elements ----------*/
- wlan_ie_ssid_t *ssid;
- wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_ssid_t *ssid;
+ wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_reassocreq_t;
/*-- Reassociation Response -----------------------*/
-typedef struct wlan_fr_reassocresp
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_reassocresp {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *cap_info;
- u16 *status;
- u16 *aid;
+ u16 *cap_info;
+ u16 *status;
+ u16 *aid;
/*-- info elements ----------*/
- wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_reassocresp_t;
/*-- Probe Request --------------------------------*/
-typedef struct wlan_fr_probereq
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_probereq {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
/*-- info elements ----------*/
- wlan_ie_ssid_t *ssid;
- wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_ssid_t *ssid;
+ wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_probereq_t;
/*-- Probe Response -------------------------------*/
-typedef struct wlan_fr_proberesp
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_proberesp {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u64 *ts;
- u16 *bcn_int;
- u16 *cap_info;
+ u64 *ts;
+ u16 *bcn_int;
+ u16 *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_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
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_authen {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *auth_alg;
- u16 *auth_seq;
- u16 *status;
+ u16 *auth_alg;
+ u16 *auth_seq;
+ u16 *status;
/*-- info elements ----------*/
- wlan_ie_challenge_t *challenge;
+ wlan_ie_challenge_t *challenge;
} wlan_fr_authen_t;
/*-- Deauthenication -----------------------------*/
-typedef struct wlan_fr_deauthen
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_deauthen {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *reason;
+ u16 *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 );
-
+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/p80211msg.h b/drivers/staging/wlan-ng/p80211msg.h
index 3a575d8cc99..f15a5d921f3 100644
--- a/drivers/staging/wlan-ng/p80211msg.h
+++ b/drivers/staging/wlan-ng/p80211msg.h
@@ -49,54 +49,18 @@
#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
-{
- u32 msgcode;
- u32 msglen;
- u8 devname[WLAN_DEVNAMELEN_MAX];
-} __WLAN_ATTRIB_PACK__ p80211msg_t;
-
-typedef struct p80211msgd
-{
- u32 msgcode;
- u32 msglen;
- u8 devname[WLAN_DEVNAMELEN_MAX];
- u8 args[0];
-} __WLAN_ATTRIB_PACK__ p80211msgd_t;
-
-/*================================================================*/
-/* Extern Declarations */
-
-
-/*================================================================*/
-/* Function Declarations */
-
-#endif /* _P80211MSG_H */
+typedef struct p80211msg {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+} __attribute__ ((packed)) p80211msg_t;
+#endif /* _P80211MSG_H */
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
index 59e5ad10dbd..b2a606a3693 100644
--- a/drivers/staging/wlan-ng/p80211netdev.c
+++ b/drivers/staging/wlan-ng/p80211netdev.c
@@ -49,13 +49,7 @@
* --------------------------------------------------------------------
*/
-
-/*================================================================*/
-/* System Includes */
-
-
#include <linux/version.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -70,9 +64,10 @@
#include <linux/wireless.h>
#include <linux/sockios.h>
#include <linux/etherdevice.h>
-
-#include <asm/bitops.h>
-#include <asm/uaccess.h>
+#include <linux/if_ether.h>
+#include <linux/byteorder/generic.h>
+#include <linux/bitops.h>
+#include <linux/uaccess.h>
#include <asm/byteorder.h>
#ifdef SIOCETHTOOL
@@ -85,7 +80,6 @@
/*================================================================*/
/* Project Includes */
-#include "wlan_compat.h"
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211conv.h"
@@ -97,33 +91,22 @@
#include "p80211metastruct.h"
#include "p80211metadef.h"
-/*================================================================*/
-/* Local Constants */
-
-/*================================================================*/
-/* Local Macros */
-
-
-/*================================================================*/
-/* Local Types */
-
-/*================================================================*/
-/* 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 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_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, u16 fc);
+static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc);
int wlan_watchdog = 5000;
module_param(wlan_watchdog, int, 0644);
@@ -133,15 +116,6 @@ int wlan_wext_write = 1;
module_param(wlan_wext_write, int, 0644);
MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions");
-#ifdef WLAN_INCLUDE_DEBUG
-int wlan_debug=0;
-module_param(wlan_debug, int, 0644);
-MODULE_PARM_DESC(wlan_debug, "p80211 debug level");
-#endif
-
-/*================================================================*/
-/* Function Definitions */
-
/*----------------------------------------------------------------
* p80211knetdev_init
*
@@ -154,18 +128,15 @@ MODULE_PARM_DESC(wlan_debug, "p80211 debug level");
* Returns:
* nothing
----------------------------------------------------------------*/
-static int p80211knetdev_init( netdevice_t *netdev)
+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
*
@@ -180,20 +151,16 @@ static int p80211knetdev_init( netdevice_t *netdev)
* Returns:
* the address of the statistics structure
----------------------------------------------------------------*/
-static struct net_device_stats*
-p80211knetdev_get_stats(netdevice_t *netdev)
+static struct net_device_stats *p80211knetdev_get_stats(netdevice_t *netdev)
{
- wlandevice_t *wlandev = netdev->ml_priv;
- DBFENTER;
+ wlandevice_t *wlandev = netdev->ml_priv;
/* TODO: review the MIB stats for items that correspond to
- linux stats */
+ linux stats */
- DBFEXIT;
return &(wlandev->linux_stats);
}
-
/*----------------------------------------------------------------
* p80211knetdev_open
*
@@ -208,22 +175,19 @@ p80211knetdev_get_stats(netdevice_t *netdev)
* Returns:
* zero on success, non-zero otherwise
----------------------------------------------------------------*/
-static int p80211knetdev_open( netdevice_t *netdev )
+static int p80211knetdev_open(netdevice_t *netdev)
{
- int result = 0; /* success */
- wlandevice_t *wlandev = netdev->ml_priv;
-
- DBFENTER;
+ int result = 0; /* success */
+ wlandevice_t *wlandev = netdev->ml_priv;
/* Check to make sure the MSD is running */
- if ( wlandev->msdstate != WLAN_MSD_RUNNING ) {
+ if (wlandev->msdstate != WLAN_MSD_RUNNING)
return -ENODEV;
- }
/* Tell the MSD to open */
- if ( wlandev->open != NULL) {
+ if (wlandev->open != NULL) {
result = wlandev->open(wlandev);
- if ( result == 0 ) {
+ if (result == 0) {
netif_start_queue(wlandev->netdev);
wlandev->state = WLAN_DEVICE_OPEN;
}
@@ -231,11 +195,9 @@ static int p80211knetdev_open( netdevice_t *netdev )
result = -EAGAIN;
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* p80211knetdev_stop
*
@@ -248,21 +210,17 @@ static int p80211knetdev_open( netdevice_t *netdev )
* Returns:
* zero on success, non-zero otherwise
----------------------------------------------------------------*/
-static int p80211knetdev_stop( netdevice_t *netdev )
+static int p80211knetdev_stop(netdevice_t *netdev)
{
- int result = 0;
- wlandevice_t *wlandev = netdev->ml_priv;
-
- DBFENTER;
+ int result = 0;
+ wlandevice_t *wlandev = netdev->ml_priv;
- if ( wlandev->close != NULL ) {
+ if (wlandev->close != NULL)
result = wlandev->close(wlandev);
- }
netif_stop_queue(wlandev->netdev);
wlandev->state = WLAN_DEVICE_CLOSED;
- DBFEXIT;
return result;
}
@@ -279,17 +237,13 @@ static int p80211knetdev_stop( netdevice_t *netdev )
* Side effects:
*
----------------------------------------------------------------*/
-void
-p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb )
+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;
}
@@ -310,19 +264,17 @@ static void p80211netdev_rx_bh(unsigned long arg)
{
wlandevice_t *wlandev = (wlandevice_t *) arg;
struct sk_buff *skb = NULL;
- netdevice_t *dev = wlandev->netdev;
+ netdevice_t *dev = wlandev->netdev;
p80211_hdr_a3_t *hdr;
u16 fc;
- DBFENTER;
-
/* Let's empty our our queue */
- while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {
+ 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.
+ /* XXX Append the Prism Header here instead. */
/* set up various data fields */
skb->dev = dev;
@@ -337,8 +289,8 @@ static void p80211netdev_rx_bh(unsigned long arg)
netif_rx_ni(skb);
continue;
} else {
- hdr = (p80211_hdr_a3_t *)skb->data;
- fc = ieee2host16(hdr->fc);
+ hdr = (p80211_hdr_a3_t *) skb->data;
+ fc = le16_to_cpu(hdr->fc);
if (p80211_rx_typedrop(wlandev, fc)) {
dev_kfree_skb(skb);
continue;
@@ -347,7 +299,9 @@ static void p80211netdev_rx_bh(unsigned long arg)
/* 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) {
+ if (memcmp
+ (hdr->a1, wlandev->netdev->dev_addr,
+ ETH_ALEN) != 0) {
/* but reject anything else that isn't multicast */
if (!(hdr->a1[0] & 0x01)) {
dev_kfree_skb(skb);
@@ -356,23 +310,22 @@ static void p80211netdev_rx_bh(unsigned long arg)
}
}
- if ( skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0 ) {
+ 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;
+ wlandev->linux_stats.rx_bytes +=
+ skb->len;
netif_rx_ni(skb);
continue;
}
- WLAN_LOG_DEBUG(1, "p80211_to_ether failed.\n");
+ pr_debug("p80211_to_ether failed.\n");
}
}
dev_kfree_skb(skb);
}
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* p80211knetdev_hard_start_xmit
*
@@ -392,21 +345,19 @@ static void p80211netdev_rx_bh(unsigned long arg)
* Returns:
* zero on success, non-zero on failure.
----------------------------------------------------------------*/
-static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev)
+static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
+ netdevice_t *netdev)
{
- int result = 0;
- int txresult = -1;
- wlandevice_t *wlandev = netdev->ml_priv;
- p80211_hdr_t p80211_hdr;
+ int result = 0;
+ int txresult = -1;
+ wlandevice_t *wlandev = netdev->ml_priv;
+ p80211_hdr_t p80211_hdr;
p80211_metawep_t p80211_wep;
- DBFENTER;
-
- if (skb == NULL) {
+ if (skb == NULL)
return 0;
- }
- if (wlandev->state != WLAN_DEVICE_OPEN) {
+ if (wlandev->state != WLAN_DEVICE_OPEN) {
result = 1;
goto failed;
}
@@ -414,8 +365,8 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
memset(&p80211_hdr, 0, sizeof(p80211_hdr_t));
memset(&p80211_wep, 0, sizeof(p80211_metawep_t));
- if ( netif_queue_stopped(netdev) ) {
- WLAN_LOG_DEBUG(1, "called when queue stopped.\n");
+ if (netif_queue_stopped(netdev)) {
+ pr_debug("called when queue stopped.\n");
result = 1;
goto failed;
}
@@ -423,7 +374,7 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
netif_stop_queue(netdev);
/* Check to see that a valid mode is set */
- switch( wlandev->macmode ) {
+ switch (wlandev->macmode) {
case WLAN_MACMODE_IBSS_STA:
case WLAN_MACMODE_ESS_STA:
case WLAN_MACMODE_ESS_AP:
@@ -433,10 +384,10 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
* and return success .
* TODO: we need a saner way to handle this
*/
- if(skb->protocol != ETH_P_80211_RAW) {
+ if (skb->protocol != ETH_P_80211_RAW) {
netif_start_queue(wlandev->netdev);
- WLAN_LOG_NOTICE(
- "Tx attempt prior to association, frame dropped.\n");
+ printk(KERN_NOTICE
+ "Tx attempt prior to association, frame dropped.\n");
wlandev->linux_stats.tx_dropped++;
result = 0;
goto failed;
@@ -445,7 +396,7 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
}
/* Check for raw transmits */
- if(skb->protocol == ETH_P_80211_RAW) {
+ if (skb->protocol == ETH_P_80211_RAW) {
if (!capable(CAP_NET_ADMIN)) {
result = 1;
goto failed;
@@ -454,15 +405,17 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
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 ) {
+ 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);
+ pr_debug("ether_to_80211(%d) failed.\n",
+ wlandev->ethconv);
result = 1;
goto failed;
}
}
- if ( wlandev->txframe == NULL ) {
+ if (wlandev->txframe == NULL) {
result = 1;
goto failed;
}
@@ -475,28 +428,28 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep);
- if ( txresult == 0) {
+ if (txresult == 0) {
/* success and more buf */
/* avail, re: hw_txdata */
netif_wake_queue(wlandev->netdev);
result = 0;
- } else if ( txresult == 1 ) {
+ } else if (txresult == 1) {
/* success, no more avail */
- WLAN_LOG_DEBUG(3, "txframe success, no more bufs\n");
+ pr_debug("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 ) {
+ } else if (txresult == 2) {
/* alloc failure, drop frame */
- WLAN_LOG_DEBUG(3, "txframe returned alloc_fail\n");
+ pr_debug("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");
+ pr_debug("txframe returned full or busy\n");
result = 1;
}
- failed:
+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);
@@ -505,11 +458,9 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
if (!result)
dev_kfree_skb(skb);
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* p80211knetdev_set_multicast_list
*
@@ -524,16 +475,13 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
----------------------------------------------------------------*/
static void p80211knetdev_set_multicast_list(netdevice_t *dev)
{
- wlandevice_t *wlandev = dev->ml_priv;
-
- DBFENTER;
+ wlandevice_t *wlandev = dev->ml_priv;
/* TODO: real multicast support as well */
if (wlandev->set_multicast_list)
wlandev->set_multicast_list(wlandev, dev);
- DBFEXIT;
}
#ifdef SIOCETHTOOL
@@ -558,9 +506,6 @@ static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
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;
@@ -576,7 +521,7 @@ static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
}
if (copy_to_user(useraddr, &edata, sizeof(edata)))
- return -EFAULT;
+ return -EFAULT;
return 0;
}
#endif
@@ -615,45 +560,47 @@ static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
----------------------------------------------------------------*/
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 = dev->ml_priv;
- u8 *msgbuf;
- DBFENTER;
+ int result = 0;
+ p80211ioctl_req_t *req = (p80211ioctl_req_t *) ifr;
+ wlandevice_t *wlandev = dev->ml_priv;
+ u8 *msgbuf;
+
+ pr_debug("rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
- WLAN_LOG_DEBUG(2, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
+ mutex_lock(&wlandev->ioctl_lock);
#ifdef SIOCETHTOOL
if (cmd == SIOCETHTOOL) {
- result = p80211netdev_ethtool(wlandev, (void __user *) ifr->ifr_data);
+ 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 ) {
+ if (req->magic != P80211_IOCTL_MAGIC) {
result = -ENOSYS;
goto bail;
}
- if ( cmd == P80211_IFTEST ) {
+ if (cmd == P80211_IFTEST) {
result = 0;
goto bail;
- } else if ( cmd != P80211_IFREQ ) {
+ } 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) ) {
+ 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);
- }
+ else
+ result = p80211req_dorequest(wlandev, msgbuf);
- if ( result == 0 ) {
- if ( copy_to_user( (void __user *) req->data, msgbuf, req->len)) {
+ if (result == 0) {
+ if (copy_to_user
+ ((void __user *)req->data, msgbuf, req->len)) {
result = -EFAULT;
}
}
@@ -662,9 +609,9 @@ static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
result = -ENOMEM;
}
bail:
- DBFEXIT;
+ mutex_unlock(&wlandev->ioctl_lock);
- return result; /* If allocate,copyfrom or copyto fails, return errno */
+ return result; /* If allocate,copyfrom or copyto fails, return errno */
}
/*----------------------------------------------------------------
@@ -694,22 +641,20 @@ bail:
----------------------------------------------------------------*/
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;
+ 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 (netif_running(dev)) {
+ if (netif_running(dev))
return -EBUSY;
- }
/* Set up some convenience pointers. */
mibattr = &dot11req.mibattribute;
- macaddr = (p80211item_pstr6_t*)&mibattr->data;
+ macaddr = (p80211item_pstr6_t *)&mibattr->data;
resultcode = &dot11req.resultcode;
/* Set up a dot11req_mibset */
@@ -717,8 +662,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
dot11req.msgcode = DIDmsg_dot11req_mibset;
dot11req.msglen = sizeof(p80211msg_dot11req_mibset_t);
memcpy(dot11req.devname,
- ((wlandevice_t *)dev->ml_priv)->name,
- WLAN_DEVNAMELEN_MAX - 1);
+ ((wlandevice_t *) dev->ml_priv)->name, WLAN_DEVNAMELEN_MAX - 1);
/* Set up the mibattribute argument */
mibattr->did = DIDmsg_dot11req_mibset_mibattribute;
@@ -728,8 +672,8 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
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);
+ macaddr->data.len = ETH_ALEN;
+ memcpy(&macaddr->data.data, new_addr->sa_data, ETH_ALEN);
/* Set up the resultcode argument */
resultcode->did = DIDmsg_dot11req_mibset_resultcode;
@@ -743,36 +687,30 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
/* 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");
+ if (result != 0 || resultcode->data != P80211ENUM_resultcode_success) {
+ printk(KERN_ERR
+ "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;
+ /* 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;
- DBFEXIT;
+ dev->mtu = new_mtu;
- return 0;
+ return 0;
}
-
-
/*----------------------------------------------------------------
* wlan_setup
*
@@ -797,10 +735,8 @@ static int wlan_change_mtu(netdevice_t *dev, int new_mtu)
----------------------------------------------------------------*/
int wlan_setup(wlandevice_t *wlandev)
{
- int result = 0;
- netdevice_t *dev;
-
- DBFENTER;
+ int result = 0;
+ netdevice_t *dev;
/* Set up the wlandev */
wlandev->state = WLAN_DEVICE_CLOSED;
@@ -810,28 +746,26 @@ int wlan_setup(wlandevice_t *wlandev)
/* Set up the rx queue */
skb_queue_head_init(&wlandev->nsd_rxq);
tasklet_init(&wlandev->rx_bh,
- p80211netdev_rx_bh,
- (unsigned long)wlandev);
+ p80211netdev_rx_bh, (unsigned long)wlandev);
/* Allocate and initialize the struct device */
- dev = alloc_netdev(0,"wlan%d",ether_setup);
- if ( dev == NULL ) {
- WLAN_LOG_ERROR("Failed to alloc netdev.\n");
+ dev = alloc_netdev(0, "wlan%d", ether_setup);
+ if (dev == NULL) {
+ printk(KERN_ERR "Failed to alloc netdev.\n");
result = 1;
} else {
wlandev->netdev = dev;
dev->ml_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;
+ dev->hard_start_xmit = p80211knetdev_hard_start_xmit;
+ dev->get_stats = p80211knetdev_get_stats;
+ dev->init = p80211knetdev_init;
+ dev->open = p80211knetdev_open;
+ dev->stop = p80211knetdev_stop;
+
+ mutex_init(&wlandev->ioctl_lock);
+ /* block ioctls until fully initialised. Don't forget to call
+ allow_ioctls at some point!*/
+ mutex_lock(&wlandev->ioctl_lock);
#if (WIRELESS_EXT < 21)
dev->get_wireless_stats = p80211wext_get_wireless_stats;
@@ -839,20 +773,9 @@ int wlan_setup(wlandevice_t *wlandev)
dev->wireless_handlers = &p80211wext_handler_def;
netif_stop_queue(dev);
-#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;
}
@@ -879,26 +802,21 @@ int wlan_setup(wlandevice_t *wlandev)
----------------------------------------------------------------*/
int wlan_unsetup(wlandevice_t *wlandev)
{
- int result = 0;
-
- DBFENTER;
+ int result = 0;
tasklet_kill(&wlandev->rx_bh);
- if (wlandev->netdev == NULL ) {
- WLAN_LOG_ERROR("called without wlandev->netdev set.\n");
+ if (wlandev->netdev == NULL) {
+ printk(KERN_ERR "called without wlandev->netdev set.\n");
result = 1;
} else {
free_netdev(wlandev->netdev);
wlandev->netdev = NULL;
}
- DBFEXIT;
return 0;
}
-
-
/*----------------------------------------------------------------
* register_wlandev
*
@@ -920,19 +838,15 @@ int wlan_unsetup(wlandevice_t *wlandev)
----------------------------------------------------------------*/
int register_wlandev(wlandevice_t *wlandev)
{
- int i = 0;
-
- DBFENTER;
+ int i = 0;
i = register_netdev(wlandev->netdev);
if (i)
return i;
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* unregister_wlandev
*
@@ -954,20 +868,15 @@ int unregister_wlandev(wlandevice_t *wlandev)
{
struct sk_buff *skb;
- DBFENTER;
-
unregister_netdev(wlandev->netdev);
/* Now to clean out the rx queue */
- while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {
+ while ((skb = skb_dequeue(&wlandev->nsd_rxq)))
dev_kfree_skb(skb);
- }
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* p80211netdev_hwremoved
*
@@ -1000,18 +909,13 @@ int unregister_wlandev(wlandevice_t *wlandev)
----------------------------------------------------------------*/
void p80211netdev_hwremoved(wlandevice_t *wlandev)
{
- DBFENTER;
wlandev->hwremoved = 1;
- if ( wlandev->state == WLAN_DEVICE_OPEN) {
+ if (wlandev->state == WLAN_DEVICE_OPEN)
netif_stop_queue(wlandev->netdev);
- }
netif_device_detach(wlandev->netdev);
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* p80211_rx_typedrop
*
@@ -1033,28 +937,27 @@ void p80211netdev_hwremoved(wlandevice_t *wlandev)
* Call context:
* interrupt
----------------------------------------------------------------*/
-static int p80211_rx_typedrop( wlandevice_t *wlandev, u16 fc)
+static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc)
{
- u16 ftype;
- u16 fstype;
- int drop = 0;
+ u16 ftype;
+ u16 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);
+ pr_debug("rx_typedrop : ftype=%d fstype=%d.\n", ftype, fstype);
#endif
- switch ( ftype ) {
+ switch (ftype) {
case WLAN_FTYPE_MGMT:
if ((wlandev->netdev->flags & IFF_PROMISC) ||
- (wlandev->netdev->flags & IFF_ALLMULTI)) {
+ (wlandev->netdev->flags & IFF_ALLMULTI)) {
drop = 1;
break;
}
- WLAN_LOG_DEBUG(3, "rx'd mgmt:\n");
+ pr_debug("rx'd mgmt:\n");
wlandev->rx.mgmt++;
- switch( fstype ) {
+ switch (fstype) {
case WLAN_FSTYPE_ASSOCREQ:
/* printk("assocreq"); */
wlandev->rx.assocreq++;
@@ -1110,13 +1013,13 @@ static int p80211_rx_typedrop( wlandevice_t *wlandev, u16 fc)
case WLAN_FTYPE_CTL:
if ((wlandev->netdev->flags & IFF_PROMISC) ||
- (wlandev->netdev->flags & IFF_ALLMULTI)) {
+ (wlandev->netdev->flags & IFF_ALLMULTI)) {
drop = 1;
break;
}
- WLAN_LOG_DEBUG(3, "rx'd ctl:\n");
+ pr_debug("rx'd ctl:\n");
wlandev->rx.ctl++;
- switch( fstype ) {
+ switch (fstype) {
case WLAN_FSTYPE_PSPOLL:
/* printk("pspoll"); */
wlandev->rx.pspoll++;
@@ -1152,7 +1055,7 @@ static int p80211_rx_typedrop( wlandevice_t *wlandev, u16 fc)
case WLAN_FTYPE_DATA:
wlandev->rx.data++;
- switch( fstype ) {
+ switch (fstype) {
case WLAN_FSTYPE_DATAONLY:
wlandev->rx.dataonly++;
break;
@@ -1166,19 +1069,19 @@ static int p80211_rx_typedrop( wlandevice_t *wlandev, u16 fc)
wlandev->rx.data__cfack_cfpoll++;
break;
case WLAN_FSTYPE_NULL:
- WLAN_LOG_DEBUG(3, "rx'd data:null\n");
+ pr_debug("rx'd data:null\n");
wlandev->rx.null++;
break;
case WLAN_FSTYPE_CFACK:
- WLAN_LOG_DEBUG(3, "rx'd data:cfack\n");
+ pr_debug("rx'd data:cfack\n");
wlandev->rx.cfack++;
break;
case WLAN_FSTYPE_CFPOLL:
- WLAN_LOG_DEBUG(3, "rx'd data:cfpoll\n");
+ pr_debug("rx'd data:cfpoll\n");
wlandev->rx.cfpoll++;
break;
case WLAN_FSTYPE_CFACK_CFPOLL:
- WLAN_LOG_DEBUG(3, "rx'd data:cfack_cfpoll\n");
+ pr_debug("rx'd data:cfack_cfpoll\n");
wlandev->rx.cfack_cfpoll++;
break;
default:
@@ -1192,18 +1095,20 @@ static int p80211_rx_typedrop( wlandevice_t *wlandev, u16 fc)
return drop;
}
-static void p80211knetdev_tx_timeout( netdevice_t *netdev)
+static void p80211knetdev_tx_timeout(netdevice_t *netdev)
{
- wlandevice_t *wlandev = netdev->ml_priv;
- DBFENTER;
+ wlandevice_t *wlandev = netdev->ml_priv;
if (wlandev->tx_timeout) {
wlandev->tx_timeout(wlandev);
} else {
- WLAN_LOG_WARNING("Implement tx_timeout for %s\n",
- wlandev->nsdname);
+ printk(KERN_WARNING "Implement tx_timeout for %s\n",
+ wlandev->nsdname);
netif_wake_queue(wlandev->netdev);
}
+}
- DBFEXIT;
+void p80211_allow_ioctls(wlandevice_t *wlandev)
+{
+ mutex_unlock(&wlandev->ioctl_lock);
}
diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h
index 940146fba9c..b96090d8788 100644
--- a/drivers/staging/wlan-ng/p80211netdev.h
+++ b/drivers/staging/wlan-ng/p80211netdev.h
@@ -55,10 +55,16 @@
#include <linux/interrupt.h>
#include <linux/wireless.h>
+#include <linux/netdevice.h>
/*================================================================*/
/* Constants */
+#undef netdevice_t
+typedef struct net_device netdevice_t;
+
+#define WLAN_RELEASE "0.3.0-staging"
+
#define WLAN_DEVICE_CLOSED 0
#define WLAN_DEVICE_OPEN 1
@@ -68,8 +74,6 @@
#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
@@ -79,79 +83,66 @@
#define WLAN_MSD_RUNNING 7
#ifndef ETH_P_ECONET
-#define ETH_P_ECONET 0x0018 /* needed for 2.2.x kernels */
+#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 */
+#define ARPHRD_IEEE80211 801 /* kernel 2.4.6 */
#endif
-#ifndef ARPHRD_IEEE80211_PRISM /* kernel 2.4.18 */
+#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 */
+#define P80211_NSDCAP_HARDWAREWEP 0x01 /* hardware wep engine */
+#define P80211_NSDCAP_SHORT_PREAMBLE 0x10 /* hardware supports */
+#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 */
/* Received frame statistics */
-typedef struct p80211_frmrx_t
-{
- u32 mgmt;
- u32 assocreq;
- u32 assocresp;
- u32 reassocreq;
- u32 reassocresp;
- u32 probereq;
- u32 proberesp;
- u32 beacon;
- u32 atim;
- u32 disassoc;
- u32 authen;
- u32 deauthen;
- u32 mgmt_unknown;
- u32 ctl;
- u32 pspoll;
- u32 rts;
- u32 cts;
- u32 ack;
- u32 cfend;
- u32 cfendcfack;
- u32 ctl_unknown;
- u32 data;
- u32 dataonly;
- u32 data_cfack;
- u32 data_cfpoll;
- u32 data__cfack_cfpoll;
- u32 null;
- u32 cfack;
- u32 cfpoll;
- u32 cfack_cfpoll;
- u32 data_unknown;
- u32 decrypt;
- u32 decrypt_err;
+typedef struct p80211_frmrx_t {
+ u32 mgmt;
+ u32 assocreq;
+ u32 assocresp;
+ u32 reassocreq;
+ u32 reassocresp;
+ u32 probereq;
+ u32 proberesp;
+ u32 beacon;
+ u32 atim;
+ u32 disassoc;
+ u32 authen;
+ u32 deauthen;
+ u32 mgmt_unknown;
+ u32 ctl;
+ u32 pspoll;
+ u32 rts;
+ u32 cts;
+ u32 ack;
+ u32 cfend;
+ u32 cfendcfack;
+ u32 ctl_unknown;
+ u32 data;
+ u32 dataonly;
+ u32 data_cfack;
+ u32 data_cfpoll;
+ u32 data__cfack_cfpoll;
+ u32 null;
+ u32 cfack;
+ u32 cfpoll;
+ u32 cfack_cfpoll;
+ u32 data_unknown;
+ u32 decrypt;
+ u32 decrypt_err;
} p80211_frmrx_t;
/* called by /proc/net/wireless */
-struct iw_statistics* p80211wext_get_wireless_stats(netdevice_t *dev);
+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);
extern struct iw_handler_def p80211wext_handler_def;
int p80211wext_event_associated(struct wlandevice *wlandev, int assoc);
@@ -159,96 +150,99 @@ int p80211wext_event_associated(struct wlandevice *wlandev, int assoc);
#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
+#define HOSTWEP_DEFAULTKEY_MASK (BIT(1)|BIT(0))
+#define HOSTWEP_DECRYPT BIT(4)
+#define HOSTWEP_ENCRYPT BIT(5)
+#define HOSTWEP_PRIVACYINVOKED BIT(6)
+#define HOSTWEP_EXCLUDEUNENCRYPTED BIT(7)
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 */
+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;
+ char name[WLAN_DEVNAMELEN_MAX]; /* Dev name, from register_wlandev() */
+ char *nsdname;
- u32 state; /* Device I/F state (open/closed) */
- u32 msdstate; /* state of underlying driver */
- u32 hwremoved; /* Has the hw been yanked out? */
+ u32 state; /* Device I/F state (open/closed) */
+ u32 msdstate; /* state of underlying driver */
+ u32 hwremoved; /* Has the hw been yanked out? */
/* Hardware config */
- unsigned int irq;
- unsigned int iobase;
- unsigned int membase;
- u32 nsdcaps; /* NSD Capabilities flags */
+ unsigned int irq;
+ unsigned int iobase;
+ unsigned int membase;
+ u32 nsdcaps; /* NSD Capabilities flags */
/* Config vars */
- unsigned int ethconv;
+ unsigned int 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);
+ 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);
/* 802.11 State */
- u8 bssid[WLAN_BSSID_LEN];
- p80211pstr32_t ssid;
- u32 macmode;
- int linkstatus;
+ u8 bssid[WLAN_BSSID_LEN];
+ p80211pstr32_t ssid;
+ u32 macmode;
+ int linkstatus;
/* WEP State */
u8 wep_keys[NUM_WEPKEYS][MAX_KEYLEN];
u8 wep_keylens[NUM_WEPKEYS];
- int hostwep;
+ int hostwep;
/* Request/Confirm i/f state (used by p80211) */
- unsigned long request_pending; /* flag, access atomically */
+ 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 */
+ netdevice_t *netdev; /* ptr to linux netdevice */
struct net_device_stats linux_stats;
/* Rx bottom half */
- struct tasklet_struct rx_bh;
+ struct tasklet_struct rx_bh;
- struct sk_buff_head nsd_rxq;
+ struct sk_buff_head nsd_rxq;
/* 802.11 device statistics */
- struct p80211_frmrx_t rx;
+ struct p80211_frmrx_t rx;
- struct iw_statistics wstats;
+ struct iw_statistics wstats;
/* jkriegl: iwspy fields */
- u8 spy_number;
- char spy_address[IW_MAX_SPY][ETH_ALEN];
- struct iw_quality spy_stat[IW_MAX_SPY];
+ u8 spy_number;
+ char spy_address[IW_MAX_SPY][ETH_ALEN];
+ struct iw_quality spy_stat[IW_MAX_SPY];
+
+ struct mutex ioctl_lock;
} wlandevice_t;
/* WEP stuff */
-int wep_change_key(wlandevice_t *wlandev, int keynum, u8* key, int keylen);
-int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override, u8 *iv, u8 *icv);
-int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum, u8 *iv, u8 *icv);
-
-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);
-
+int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen);
+int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
+ u8 *iv, u8 *icv);
+int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
+ u8 *iv, u8 *icv);
+
+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_allow_ioctls(wlandevice_t *wlandev);
#endif
diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c
index 6e20bff0e67..15ecba6e469 100644
--- a/drivers/staging/wlan-ng/p80211req.c
+++ b/drivers/staging/wlan-ng/p80211req.c
@@ -50,11 +50,6 @@
* --------------------------------------------------------------------
*/
-/*================================================================*/
-/* System Includes */
-
-
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -67,11 +62,6 @@
#include <net/sock.h>
#include <linux/netlink.h>
-#include "wlan_compat.h"
-
-/*================================================================*/
-/* Project Includes */
-
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211mgmt.h"
@@ -83,30 +73,10 @@
#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 */
-
+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);
/*----------------------------------------------------------------
* p80211req_dorequest
@@ -124,33 +94,30 @@ static int p80211req_mibset_mibget(wlandevice_t *wlandev, p80211msg_dot11req_mib
* 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, u8 *msgbuf)
+int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf)
{
- int result = 0;
- p80211msg_t *msg = (p80211msg_t*)msgbuf;
-
- DBFENTER;
+ int result = 0;
+ p80211msg_t *msg = (p80211msg_t *) msgbuf;
/* 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) ) {
+ 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);
+ if (!capable(CAP_NET_ADMIN) && (msg->msgcode != DIDmsg_dot11req_mibget)) {
+ printk(KERN_ERR
+ "%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))) {
+ 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 */
@@ -158,12 +125,11 @@ int p80211req_dorequest( wlandevice_t *wlandev, u8 *msgbuf)
p80211req_handlemsg(wlandev, msg);
/* Pass it down to wlandev via wlandev->mlmerequest */
- if ( wlandev->mlmerequest != NULL )
+ 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 */
+ clear_bit(1, &(wlandev->request_pending));
+ return result; /* if result==0, msg->status still may contain an err */
}
/*----------------------------------------------------------------
@@ -184,34 +150,32 @@ int p80211req_dorequest( wlandevice_t *wlandev, u8 *msgbuf)
* Call context:
* Process thread
----------------------------------------------------------------*/
-static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg)
+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_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);
- }
+ 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;
+ } /* switch msg->msgcode */
return;
}
@@ -220,81 +184,82 @@ 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;
+ p80211itemd_t *mibitem = (p80211itemd_t *) mib_msg->mibattribute.data;
+ p80211pstrd_t *pstr = (p80211pstrd_t *) mibitem->data;
u8 *key = mibitem->data + sizeof(p80211pstrd_t);
- DBFENTER;
-
switch (mibitem->did) {
- 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: {
- u32 *data = (u32 *) mibitem->data;
+ 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:{
+ u32 *data = (u32 *) mibitem->data;
- if (isget) {
- *data = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
+ if (isget) {
+ *data =
+ wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
} else {
wlandev->hostwep &= ~(HOSTWEP_DEFAULTKEY_MASK);
- wlandev->hostwep |= (*data & HOSTWEP_DEFAULTKEY_MASK);
+ wlandev->hostwep |=
+ (*data & HOSTWEP_DEFAULTKEY_MASK);
}
- break;
- }
- case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked: {
- u32 *data = (u32 *) mibitem->data;
-
- if (isget) {
- if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
- *data = P80211ENUM_truth_true;
- else
- *data = P80211ENUM_truth_false;
- } else {
+ break;
+ }
+ case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked:{
+ u32 *data = (u32 *) 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;
+ wlandev->hostwep |=
+ HOSTWEP_PRIVACYINVOKED;
+ }
+ break;
}
- break;
- }
- case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted: {
- u32 *data = (u32 *) 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;
+ case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted:{
+ u32 *data = (u32 *) 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;
}
- break;
- }
default:
- // XXXX do nothing!
;
}
- DBFEXIT;
return 0;
}
-
diff --git a/drivers/staging/wlan-ng/p80211req.h b/drivers/staging/wlan-ng/p80211req.h
index 497a4d6eb59..a95a45a6814 100644
--- a/drivers/staging/wlan-ng/p80211req.h
+++ b/drivers/staging/wlan-ng/p80211req.h
@@ -48,21 +48,6 @@
#ifndef _LINUX_P80211REQ_H
#define _LINUX_P80211REQ_H
-/*================================================================*/
-/* Constants */
-
-/*================================================================*/
-/* Macros */
-
-/*================================================================*/
-/* Types */
-
-/*================================================================*/
-/* Externs */
-
-/*================================================================*/
-/* Function Declarations */
-
-int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf);
+int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf);
#endif
diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h
index 5be6737e3e5..a22437ceddc 100644
--- a/drivers/staging/wlan-ng/p80211types.h
+++ b/drivers/staging/wlan-ng/p80211types.h
@@ -58,37 +58,9 @@
#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 /* u32 min and max limited by 32 bits */
-#define P80211_TYPE_ENUMint 5 /* u32 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 */
@@ -106,25 +78,6 @@
/* 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 */
@@ -132,104 +85,30 @@
/* 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. */
@@ -243,46 +122,6 @@
/* 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) (((u32)(flags & ISREQUIRED)) >> 31 )
-#define P80211ITEM_ISREQUEST(flags) (((u32)(flags & ISREQUEST)) >> 30 )
-#define P80211ITEM_ISCONFIRM(flags) (((u32)(flags & ISCONFIRM)) >> 29 )
-
/*----------------------------------------------------------------*/
/* The following macro creates a name for an enum */
@@ -302,9 +141,6 @@
* . - Unused
*/
-#define P80211DID_INVALID 0xffffffffUL
-#define P80211DID_VALID 0x00000000UL
-
#define P80211DID_LSB_SECTION (0)
#define P80211DID_LSB_GROUP (6)
#define P80211DID_LSB_ITEM (12)
@@ -319,35 +155,32 @@
#define P80211DID_MASK_ISTABLE (0x00000001UL)
#define P80211DID_MASK_ACCESS (0x00000003UL)
-
-#define P80211DID_MK(a,m,l) ((((u32)(a)) & (m)) << (l))
+#define P80211DID_MK(a, m, l) ((((u32)(a)) & (m)) << (l))
#define P80211DID_MKSECTION(a) P80211DID_MK(a, \
P80211DID_MASK_SECTION, \
- P80211DID_LSB_SECTION )
+ P80211DID_LSB_SECTION)
#define P80211DID_MKGROUP(a) P80211DID_MK(a, \
P80211DID_MASK_GROUP, \
- P80211DID_LSB_GROUP )
+ P80211DID_LSB_GROUP)
#define P80211DID_MKITEM(a) P80211DID_MK(a, \
P80211DID_MASK_ITEM, \
- P80211DID_LSB_ITEM )
+ P80211DID_LSB_ITEM)
#define P80211DID_MKINDEX(a) P80211DID_MK(a, \
P80211DID_MASK_INDEX, \
- P80211DID_LSB_INDEX )
+ P80211DID_LSB_INDEX)
#define P80211DID_MKISTABLE(a) P80211DID_MK(a, \
P80211DID_MASK_ISTABLE, \
- P80211DID_LSB_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) )
+ (a))
-
-#define P80211DID_GET(a,m,l) ((((u32)(a)) >> (l)) & (m))
+#define P80211DID_GET(a, m, l) ((((u32)(a)) >> (l)) & (m))
#define P80211DID_SECTION(a) P80211DID_GET(a, \
P80211DID_MASK_SECTION, \
@@ -368,23 +201,18 @@
P80211DID_MASK_ACCESS, \
P80211DID_LSB_ACCESS)
-/*================================================================*/
-/* Types */
-
/*----------------------------------------------------------------*/
/* The following structure types are used for the represenation */
/* of ENUMint type metadata. */
-typedef struct p80211enumpair
-{
- u32 val;
- char *name;
+typedef struct p80211enumpair {
+ u32 val;
+ char *name;
} p80211enumpair_t;
-typedef struct p80211enum
-{
- int nitems;
- p80211enumpair_t *list;
+typedef struct p80211enum {
+ int nitems;
+ p80211enumpair_t *list;
} p80211enum_t;
/*----------------------------------------------------------------*/
@@ -392,140 +220,123 @@ typedef struct p80211enum
/* messages. */
/* Template pascal string */
-typedef struct p80211pstr
-{
- u8 len;
-} __WLAN_ATTRIB_PACK__ p80211pstr_t;
+typedef struct p80211pstr {
+ u8 len;
+} __attribute__ ((packed)) p80211pstr_t;
-typedef struct p80211pstrd
-{
- u8 len;
- u8 data[0];
-} __WLAN_ATTRIB_PACK__ p80211pstrd_t;
+typedef struct p80211pstrd {
+ u8 len;
+ u8 data[0];
+} __attribute__ ((packed)) p80211pstrd_t;
/* Maximum pascal string */
-typedef struct p80211pstr255
-{
- u8 len;
- u8 data[MAXLEN_PSTR255];
-} __WLAN_ATTRIB_PACK__ p80211pstr255_t;
+typedef struct p80211pstr255 {
+ u8 len;
+ u8 data[MAXLEN_PSTR255];
+} __attribute__ ((packed)) p80211pstr255_t;
/* pascal string for macaddress and bssid */
-typedef struct p80211pstr6
-{
- u8 len;
- u8 data[MAXLEN_PSTR6];
-} __WLAN_ATTRIB_PACK__ p80211pstr6_t;
+typedef struct p80211pstr6 {
+ u8 len;
+ u8 data[MAXLEN_PSTR6];
+} __attribute__ ((packed)) p80211pstr6_t;
/* pascal string for channel list */
-typedef struct p80211pstr14
-{
- u8 len;
- u8 data[MAXLEN_PSTR14];
-} __WLAN_ATTRIB_PACK__ p80211pstr14_t;
+typedef struct p80211pstr14 {
+ u8 len;
+ u8 data[MAXLEN_PSTR14];
+} __attribute__ ((packed)) p80211pstr14_t;
/* pascal string for ssid */
-typedef struct p80211pstr32
-{
- u8 len;
- u8 data[MAXLEN_PSTR32];
-} __WLAN_ATTRIB_PACK__ p80211pstr32_t;
+typedef struct p80211pstr32 {
+ u8 len;
+ u8 data[MAXLEN_PSTR32];
+} __attribute__ ((packed)) p80211pstr32_t;
/* MAC address array */
-typedef struct p80211macarray
-{
- u32 cnt;
- u8 data[1][MAXLEN_PSTR6];
-} __WLAN_ATTRIB_PACK__ p80211macarray_t;
+typedef struct p80211macarray {
+ u32 cnt;
+ u8 data[1][MAXLEN_PSTR6];
+} __attribute__ ((packed)) p80211macarray_t;
/* prototype template */
-typedef struct p80211item
-{
- u32 did;
- u16 status;
- u16 len;
-} __WLAN_ATTRIB_PACK__ p80211item_t;
+typedef struct p80211item {
+ u32 did;
+ u16 status;
+ u16 len;
+} __attribute__ ((packed)) p80211item_t;
/* prototype template w/ data item */
-typedef struct p80211itemd
-{
- u32 did;
- u16 status;
- u16 len;
- u8 data[0];
-} __WLAN_ATTRIB_PACK__ p80211itemd_t;
+typedef struct p80211itemd {
+ u32 did;
+ u16 status;
+ u16 len;
+ u8 data[0];
+} __attribute__ ((packed)) p80211itemd_t;
/* message data item for int, BOUNDEDINT, ENUMINT */
-typedef struct p80211item_uint32
-{
- u32 did;
- u16 status;
- u16 len;
- u32 data;
-} __WLAN_ATTRIB_PACK__ p80211item_uint32_t;
+typedef struct p80211item_uint32 {
+ u32 did;
+ u16 status;
+ u16 len;
+ u32 data;
+} __attribute__ ((packed)) p80211item_uint32_t;
/* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr6
-{
- u32 did;
- u16 status;
- u16 len;
- p80211pstr6_t data;
-} __WLAN_ATTRIB_PACK__ p80211item_pstr6_t;
+typedef struct p80211item_pstr6 {
+ u32 did;
+ u16 status;
+ u16 len;
+ p80211pstr6_t data;
+} __attribute__ ((packed)) p80211item_pstr6_t;
/* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr14
-{
- u32 did;
- u16 status;
- u16 len;
- p80211pstr14_t data;
-} __WLAN_ATTRIB_PACK__ p80211item_pstr14_t;
+typedef struct p80211item_pstr14 {
+ u32 did;
+ u16 status;
+ u16 len;
+ p80211pstr14_t data;
+} __attribute__ ((packed)) p80211item_pstr14_t;
/* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr32
-{
- u32 did;
- u16 status;
- u16 len;
- p80211pstr32_t data;
-} __WLAN_ATTRIB_PACK__ p80211item_pstr32_t;
+typedef struct p80211item_pstr32 {
+ u32 did;
+ u16 status;
+ u16 len;
+ p80211pstr32_t data;
+} __attribute__ ((packed)) p80211item_pstr32_t;
/* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr255
-{
- u32 did;
- u16 status;
- u16 len;
- p80211pstr255_t data;
-} __WLAN_ATTRIB_PACK__ p80211item_pstr255_t;
+typedef struct p80211item_pstr255 {
+ u32 did;
+ u16 status;
+ u16 len;
+ p80211pstr255_t data;
+} __attribute__ ((packed)) p80211item_pstr255_t;
/* message data item for UNK 392, namely mib items */
-typedef struct p80211item_unk392
-{
- u32 did;
- u16 status;
- u16 len;
- u8 data[MAXLEN_MIBATTRIBUTE];
-} __WLAN_ATTRIB_PACK__ p80211item_unk392_t;
+typedef struct p80211item_unk392 {
+ u32 did;
+ u16 status;
+ u16 len;
+ u8 data[MAXLEN_MIBATTRIBUTE];
+} __attribute__ ((packed)) p80211item_unk392_t;
/* message data item for UNK 1025, namely p2 pdas */
-typedef struct p80211item_unk1024
-{
- u32 did;
- u16 status;
- u16 len;
- u8 data[1024];
-} __WLAN_ATTRIB_PACK__ p80211item_unk1024_t;
+typedef struct p80211item_unk1024 {
+ u32 did;
+ u16 status;
+ u16 len;
+ u8 data[1024];
+} __attribute__ ((packed)) p80211item_unk1024_t;
/* message data item for UNK 4096, namely p2 download chunks */
-typedef struct p80211item_unk4096
-{
- u32 did;
- u16 status;
- u16 len;
- u8 data[4096];
-} __WLAN_ATTRIB_PACK__ p80211item_unk4096_t;
+typedef struct p80211item_unk4096 {
+ u32 did;
+ u16 status;
+ u16 len;
+ u8 data[4096];
+} __attribute__ ((packed)) p80211item_unk4096_t;
struct catlistitem;
@@ -534,13 +345,11 @@ struct catlistitem;
/* metadata items. Some components may choose to use more, */
/* less or different metadata items. */
-typedef void (*p80211_totext_t)( struct catlistitem *, u32 did, u8* itembuf, char *textbuf);
-typedef void (*p80211_fromtext_t)( struct catlistitem *, u32 did, u8* itembuf, char *textbuf);
-typedef u32 (*p80211_valid_t)( struct catlistitem *, u32 did, u8* itembuf);
-
-
-/*================================================================*/
-/* Extern Declarations */
+typedef void (*p80211_totext_t) (struct catlistitem *, u32 did, u8 *itembuf,
+ char *textbuf);
+typedef void (*p80211_fromtext_t) (struct catlistitem *, u32 did, u8 *itembuf,
+ char *textbuf);
+typedef u32(*p80211_valid_t) (struct catlistitem *, u32 did, u8 *itembuf);
/*----------------------------------------------------------------*/
/* Enumeration Lists */
@@ -568,108 +377,4 @@ 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. */
-
-u32 p80211enum_text2int(p80211enum_t *ep, char *text);
-u32 p80211enum_int2text(p80211enum_t *ep, u32 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, u32 did, u8 *itembuf, char *textbuf );
-
-/* cstr ==> pstr */
-void p80211_fromtext_displaystr( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of a displaystr binary value */
-u32 p80211_isvalid_displaystr( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- OCTETSTR --------------------------------------------------------*/
-/* pstr ==> "xx:xx:...." */
-void p80211_totext_octetstr( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* "xx:xx:...." ==> pstr */
-void p80211_fromtext_octetstr( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of an octetstr binary value */
-u32 p80211_isvalid_octetstr( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- int -------------------------------------------------------------*/
-/* u32 ==> %d */
-void p80211_totext_int( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* %d ==> u32 */
-void p80211_fromtext_int( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of an int's binary value (always successful) */
-u32 p80211_isvalid_int( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- ENUMint ---------------------------------------------------------*/
-/* u32 ==> <valuename> */
-void p80211_totext_enumint( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* <valuename> ==> u32 */
-void p80211_fromtext_enumint( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of an enum's binary value */
-u32 p80211_isvalid_enumint( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- intARRAY --------------------------------------------------------*/
-/* u32[] => %d,%d,%d,... */
-void p80211_totext_intarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* %d,%d,%d,... ==> u32[] */
-void p80211_fromtext_intarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of an integer array's value */
-u32 p80211_isvalid_intarray( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- BITARRAY --------------------------------------------------------*/
-/* u32 ==> %d,%d,%d,... */
-void p80211_totext_bitarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* %d,%d,%d,... ==> u32 */
-void p80211_fromtext_bitarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of a bit array's value */
-u32 p80211_isvalid_bitarray( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- MACARRAY --------------------------------------------------------*/
-void p80211_totext_macarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-void p80211_fromtext_macarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of a MAC address array's value */
-u32 p80211_isvalid_macarray( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- MIBATTRIUBTE ------------------------------------------------------*/
-/* <mibvalue> ==> <textual representation identified in MIB metadata> */
-void p80211_totext_getmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-void p80211_totext_setmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-
-/* <textual representation identified in MIB metadata> ==> <mibvalue> */
-void p80211_fromtext_getmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-void p80211_fromtext_setmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of a mibitem's binary value */
-u32 p80211_isvalid_getmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf );
-u32 p80211_isvalid_setmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
#endif /* _P80211TYPES_H */
-
diff --git a/drivers/staging/wlan-ng/p80211wep.c b/drivers/staging/wlan-ng/p80211wep.c
index 46a2a6b3bdc..405ce89e4e6 100644
--- a/drivers/staging/wlan-ng/p80211wep.c
+++ b/drivers/staging/wlan-ng/p80211wep.c
@@ -55,8 +55,7 @@
#include <linux/wireless.h>
#include <linux/slab.h>
#include <linux/random.h>
-
-#include "wlan_compat.h"
+#include <linux/kernel.h>
// #define WEP_DEBUG
@@ -72,18 +71,9 @@
/*================================================================*/
/* Local Constants */
-#define SSWAP(a,b) {u8 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 u32 wep_crc32_table[256] = {
@@ -211,7 +201,7 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override, u8 *i
j = 0;
for (i = 0; i < 256; i++) {
j = (j + s[i] + key[i % keylen]) & 0xff;
- SSWAP(i,j);
+ swap(i,j);
}
/* Apply the RC4 to the data, update the CRC32 */
@@ -220,7 +210,7 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override, u8 *i
for (k = 0; k < len; k++) {
i = (i+1) & 0xff;
j = (j+s[i]) & 0xff;
- SSWAP(i,j);
+ swap(i,j);
buf[k] ^= s[(s[i] + s[j]) & 0xff];
crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8);
}
@@ -235,7 +225,7 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override, u8 *i
for (k = 0; k < 4; k++) {
i = (i + 1) & 0xff;
j = (j+s[i]) & 0xff;
- SSWAP(i,j);
+ swap(i,j);
if ((c_crc[k] ^ s[(s[i] + s[j]) & 0xff]) != icv[k])
return -(4 | (k << 4)) ; /* ICV mismatch */
}
@@ -283,7 +273,7 @@ int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum, u8
j = 0;
for (i = 0; i < 256; i++) {
j = (j + s[i] + key[i % keylen]) & 0xff;
- SSWAP(i,j);
+ swap(i,j);
}
/* Update CRC32 then apply RC4 to the data */
@@ -293,7 +283,7 @@ int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum, u8
crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8);
i = (i+1) & 0xff;
j = (j+s[i]) & 0xff;
- SSWAP(i,j);
+ swap(i,j);
dst[k] = buf[k] ^ s[(s[i] + s[j]) & 0xff];
}
crc = ~crc;
@@ -307,7 +297,7 @@ int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum, u8
for (k = 0; k < 4; k++) {
i = (i + 1) & 0xff;
j = (j+s[i]) & 0xff;
- SSWAP(i,j);
+ swap(i,j);
icv[k] ^= s[(s[i] + s[j]) & 0xff];
}
diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c
index 0d570f1f378..96078b0ea6a 100644
--- a/drivers/staging/wlan-ng/p80211wext.c
+++ b/drivers/staging/wlan-ng/p80211wext.c
@@ -51,12 +51,12 @@
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
+#include <linux/if_ether.h>
+#include <linux/bitops.h>
/*================================================================*/
/* Project Includes */
-#include "wlan_compat.h"
-
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211conv.h"
@@ -77,16 +77,14 @@ static int p80211wext_giwessid(netdevice_t *dev,
static u8 p80211_mhz_to_channel(u16 mhz)
{
- if (mhz >= 5000) {
- return ((mhz - 5000) / 5);
- }
+ if (mhz >= 5000)
+ return (mhz - 5000) / 5;
if (mhz == 2482)
return 14;
- if (mhz >= 2407) {
- return ((mhz - 2407) / 5);
- }
+ if (mhz >= 2407)
+ return (mhz - 2407) / 5;
return 0;
}
@@ -100,19 +98,15 @@ static u16 p80211_channel_to_mhz(u8 ch, int dot11a)
return 0;
/* 5G */
-
- if (dot11a) {
- return (5000 + (5 * ch));
- }
+ if (dot11a)
+ return 5000 + (5 * ch);
/* 2.4G */
-
if (ch == 14)
return 2484;
- if ((ch < 14) && (ch > 0)) {
- return (2407 + (5 * ch));
- }
+ if ((ch < 14) && (ch > 0))
+ return 2407 + (5 * ch);
return 0;
}
@@ -122,54 +116,46 @@ static const long p80211wext_channel_freq[] = {
2412, 2417, 2422, 2427, 2432, 2437, 2442,
2447, 2452, 2457, 2462, 2467, 2472, 2484
};
-#define NUM_CHANNELS ARRAY_SIZE(p80211wext_channel_freq)
-
-/* steal a spare bit to store the shared/opensystems state. should default to open if not set */
-#define HOSTWEP_SHAREDKEY BIT3
+#define NUM_CHANNELS ARRAY_SIZE(p80211wext_channel_freq)
-/** function declarations =============== */
+/* steal a spare bit to store the shared/opensystems state.
+ should default to open if not set */
+#define HOSTWEP_SHAREDKEY BIT(3)
-static int qual_as_percent(int snr ) {
- if ( snr <= 0 )
- return 0;
- if ( snr <= 40 )
- return snr*5/2;
- return 100;
+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, u32 did, u32 data)
{
- p80211msg_dot11req_mibset_t msg;
- p80211item_uint32_t mibitem;
- int result;
-
- DBFENTER;
+ p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ int result;
msg.msgcode = DIDmsg_dot11req_mibset;
mibitem.did = did;
mibitem.data = data;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
- DBFEXIT;
return result;
}
static int p80211wext_autojoin(wlandevice_t *wlandev)
{
- p80211msg_lnxreq_autojoin_t msg;
- struct iw_point data;
+ 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);
@@ -178,23 +164,22 @@ static int p80211wext_autojoin(wlandevice_t *wlandev)
goto exit;
}
- if ( wlandev->hostwep & HOSTWEP_SHAREDKEY )
- msg.authtype.data = P80211ENUM_authalg_sharedkey;
+ if (wlandev->hostwep & HOSTWEP_SHAREDKEY)
+ msg.authtype.data = P80211ENUM_authalg_sharedkey;
else
- msg.authtype.data = P80211ENUM_authalg_opensystem;
+ 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') {
+ 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, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -203,22 +188,20 @@ static int p80211wext_autojoin(wlandevice_t *wlandev)
exit:
- DBFEXIT;
return err;
}
/* called by /proc/net/wireless */
-struct iw_statistics* p80211wext_get_wireless_stats (netdevice_t *dev)
+struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t * dev)
{
- p80211msg_lnxreq_commsquality_t quality;
+ p80211msg_lnxreq_commsquality_t quality;
wlandevice_t *wlandev = dev->ml_priv;
- struct iw_statistics* wstats = &wlandev->wstats;
+ struct iw_statistics *wstats = &wlandev->wstats;
int retval;
- DBFENTER;
/* Check */
- if ( (wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING) )
+ if ((wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING))
return NULL;
/* XXX Only valid in station mode */
@@ -230,26 +213,24 @@ struct iw_statistics* p80211wext_get_wireless_stats (netdevice_t *dev)
quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
/* send message to nsd */
- if ( wlandev->mlmerequest == NULL )
+ if (wlandev->mlmerequest == NULL)
return NULL;
- retval = wlandev->mlmerequest(wlandev, (p80211msg_t*) &quality);
+ 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 */
+ 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 */
wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
wstats->discard.code = wlandev->rx.decrypt_err;
wstats->discard.nwid = 0;
wstats->discard.misc = 0;
- wstats->discard.fragment = 0; // incomplete fragments
- wstats->discard.retries = 0; // tx retries.
+ wstats->discard.fragment = 0; /* incomplete fragments */
+ wstats->discard.retries = 0; /* tx retries. */
wstats->miss.beacon = 0;
- DBFEXIT;
-
return wstats;
}
@@ -261,8 +242,6 @@ static int p80211wext_giwname(netdevice_t *dev,
int result;
int err = 0;
- DBFENTER;
-
result = p80211wext_giwrate(dev, NULL, &rate, NULL);
if (result) {
@@ -281,7 +260,6 @@ static int p80211wext_giwname(netdevice_t *dev,
break;
}
exit:
- DBFEXIT;
return err;
}
@@ -290,17 +268,15 @@ static int p80211wext_giwfreq(netdevice_t *dev,
struct iw_freq *freq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ 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, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -318,8 +294,7 @@ static int p80211wext_giwfreq(netdevice_t *dev,
freq->e = 1;
freq->m = p80211_channel_to_mhz(mibitem.data, 0) * 100000;
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -328,13 +303,11 @@ static int p80211wext_siwfreq(netdevice_t *dev,
struct iw_freq *freq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
- DBFENTER;
-
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
@@ -344,21 +317,20 @@ static int p80211wext_siwfreq(netdevice_t *dev,
mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
mibitem.status = P80211ENUM_msgitem_status_data_ok;
- if ( (freq->e == 0) && (freq->m <= 1000) )
+ 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, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -368,8 +340,6 @@ static int p80211wext_giwmode(netdevice_t *dev,
{
wlandevice_t *wlandev = dev->ml_priv;
- DBFENTER;
-
switch (wlandev->macmode) {
case WLAN_MACMODE_IBSS_STA:
*mode = IW_MODE_ADHOC;
@@ -385,7 +355,6 @@ static int p80211wext_giwmode(netdevice_t *dev,
*mode = IW_MODE_AUTO;
}
- DBFEXIT;
return 0;
}
@@ -394,12 +363,10 @@ static int p80211wext_siwmode(netdevice_t *dev,
__u32 *mode, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
- int result;
- int err = 0;
-
- DBFENTER;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
@@ -428,7 +395,7 @@ static int p80211wext_siwmode(netdevice_t *dev,
break;
default:
/* Not set yet. */
- WLAN_LOG_INFO("Operation mode: %d not support\n", *mode);
+ printk(KERN_INFO "Operation mode: %d not support\n", *mode);
return -EOPNOTSUPP;
}
@@ -437,33 +404,28 @@ static int p80211wext_siwmode(netdevice_t *dev,
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, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result)
err = -EFAULT;
- exit:
- DBFEXIT;
-
+exit:
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;
+ struct iw_range *range = (struct iw_range *)extra;
int i, val;
- DBFENTER;
-
- // for backward compatability set size & zero everything we don't understand
+ /* for backward compatability set size and zero everything we don't understand */
data->length = sizeof(*range);
- memset(range,0,sizeof(*range));
+ memset(range, 0, sizeof(*range));
range->txpower_capa = IW_TXPOW_DBM;
- // XXX what about min/max_pmp, min/max_pmt, etc.
+ /* XXX what about min/max_pmp, min/max_pmt, etc. */
range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = 13;
@@ -473,18 +435,18 @@ static int p80211wext_giwrange(netdevice_t *dev,
range->min_retry = 0;
range->max_retry = 255;
- 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) );
+ 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));
range->num_channels = NUM_CHANNELS;
/* XXX need to filter against the regulatory domain &| active set */
val = 0;
- for (i = 0; i < NUM_CHANNELS ; i++) {
+ 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;
@@ -498,7 +460,7 @@ static int p80211wext_giwrange(netdevice_t *dev,
range->max_qual.level = 0;
range->max_qual.noise = 0;
range->sensitivity = 3;
- // XXX these need to be nsd-specific!
+ /* XXX these need to be nsd-specific! */
range->min_rts = 0;
range->max_rts = 2347;
@@ -510,14 +472,13 @@ static int p80211wext_giwrange(netdevice_t *dev,
range->encoding_size[0] = 5;
range->encoding_size[1] = 13;
- // XXX what about num_bitrates/throughput?
+ /* XXX what about num_bitrates/throughput? */
range->num_bitrates = 0;
/* estimated max throughput */
- // XXX need to cap it if we're running at ~2Mbps..
+ /* XXX need to cap it if we're running at ~2Mbps.. */
range->throughput = 5500000;
- DBFEXIT;
return 0;
}
@@ -528,12 +489,9 @@ static int p80211wext_giwap(netdevice_t *dev,
wlandevice_t *wlandev = dev->ml_priv;
- DBFENTER;
-
memcpy(ap_addr->sa_data, wlandev->bssid, WLAN_BSSID_LEN);
ap_addr->sa_family = ARPHRD_ETHER;
- DBFEXIT;
return 0;
}
@@ -545,8 +503,6 @@ static int p80211wext_giwencode(netdevice_t *dev,
int err = 0;
int i;
- DBFENTER;
-
i = (erq->flags & IW_ENCODE_INDEX) - 1;
erq->flags = 0;
@@ -576,8 +532,7 @@ static int p80211wext_giwencode(netdevice_t *dev,
erq->length = wlandev->wep_keylens[i];
memcpy(key, wlandev->wep_keys[i], erq->length);
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -586,32 +541,33 @@ static int p80211wext_siwencode(netdevice_t *dev,
struct iw_point *erq, char *key)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211msg_dot11req_mibset_t msg;
- p80211item_pstr32_t pstr;
+ p80211msg_dot11req_mibset_t msg;
+ p80211item_pstr32_t pstr;
int err = 0;
int result = 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 = (erq->flags & IW_ENCODE_INDEX))) {
if ((i < 1) || (i > NUM_WEPKEYS)) {
err = -EINVAL;
goto exit;
- }
- else
+ } else
i--;
/* Set current key number only if no keys are given */
if (erq->flags & IW_ENCODE_NOKEY) {
- result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, i);
+ result =
+ p80211wext_dorequest(wlandev,
+ DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+ i);
if (result) {
err = -EFAULT;
@@ -620,12 +576,12 @@ static int p80211wext_siwencode(netdevice_t *dev,
}
} else {
- // Use defaultkey if no Key Index
+ /* Use defaultkey if no Key Index */
i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
}
/* Check if there is no key information in the iwconfig request */
- if((erq->flags & IW_ENCODE_NOKEY) == 0 ) {
+ if ((erq->flags & IW_ENCODE_NOKEY) == 0) {
/*------------------------------------------------------------
* If there is WEP Key for setting, check the Key Information
@@ -642,32 +598,35 @@ static int p80211wext_siwencode(netdevice_t *dev,
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;
+ 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, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -679,9 +638,15 @@ static int p80211wext_siwencode(netdevice_t *dev,
/* Check the PrivacyInvoked flag */
if (erq->flags & IW_ENCODE_DISABLED) {
- result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false);
+ result =
+ p80211wext_dorequest(wlandev,
+ DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+ P80211ENUM_truth_false);
} else {
- result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true);
+ result =
+ p80211wext_dorequest(wlandev,
+ DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+ P80211ENUM_truth_true);
}
if (result) {
@@ -690,17 +655,22 @@ static int p80211wext_siwencode(netdevice_t *dev,
}
/* The security mode may be open or restricted, and its meaning
- depends on the card used. With most cards, in open mode no
- authentication is used and the card may also accept non-
- encrypted sessions, whereas in restricted mode only encrypted
- sessions are accepted and the card will use authentication if
- available.
- */
+ depends on the card used. With most cards, in open mode no
+ authentication is used and the card may also accept non-
+ encrypted sessions, whereas in restricted mode only encrypted
+ sessions are accepted and the card will use authentication if
+ available.
+ */
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);
+ 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) {
@@ -708,9 +678,8 @@ static int p80211wext_siwencode(netdevice_t *dev,
goto exit;
}
- exit:
+exit:
- DBFEXIT;
return err;
}
@@ -720,8 +689,6 @@ static int p80211wext_giwessid(netdevice_t *dev,
{
wlandevice_t *wlandev = dev->ml_priv;
- DBFENTER;
-
if (wlandev->ssid.len) {
data->length = wlandev->ssid.len;
data->flags = 1;
@@ -731,12 +698,11 @@ static int p80211wext_giwessid(netdevice_t *dev,
data->length++;
#endif
} else {
- memset(essid, 0, sizeof(wlandev->ssid.data));
+ memset(essid, 0, sizeof(wlandev->ssid.data));
data->length = 0;
data->flags = 0;
}
- DBFEXIT;
return 0;
}
@@ -745,55 +711,49 @@ static int p80211wext_siwessid(netdevice_t *dev,
struct iw_point *data, char *essid)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211msg_lnxreq_autojoin_t msg;
+ 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;
+ if (wlandev->hostwep & HOSTWEP_SHAREDKEY)
+ msg.authtype.data = P80211ENUM_authalg_sharedkey;
else
- msg.authtype.data = P80211ENUM_authalg_opensystem;
+ msg.authtype.data = P80211ENUM_authalg_opensystem;
msg.msgcode = DIDmsg_lnxreq_autojoin;
#if (WIRELESS_EXT < 21)
- if (length) length--;
+ if (length)
+ length--;
#endif
/* Trim the last '\0' to fit the SSID format */
-
- if (length && essid[length-1] == '\0') {
- length--;
- }
+ 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, (u8*)&msg);
- WLAN_LOG_DEBUG(1,"autojoin_ssid %d\n",result);
+ pr_debug("autojoin_ssid for %s \n", essid);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
+ pr_debug("autojoin_ssid %d\n", result);
if (result) {
err = -EFAULT;
goto exit;
}
- exit:
- DBFEXIT;
+exit:
return err;
}
-
static int p80211wext_siwcommit(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *data, char *essid)
@@ -801,8 +761,6 @@ static int p80211wext_siwcommit(netdevice_t *dev,
wlandevice_t *wlandev = dev->ml_priv;
int err = 0;
- DBFENTER;
-
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
@@ -811,28 +769,24 @@ static int p80211wext_siwcommit(netdevice_t *dev,
/* Auto Join */
err = p80211wext_autojoin(wlandev);
- exit:
- DBFEXIT;
+exit:
return err;
}
-
static int p80211wext_giwrate(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ 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, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -841,7 +795,7 @@ static int p80211wext_giwrate(netdevice_t *dev,
memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
- rrq->fixed = 0; /* can it change? */
+ rrq->fixed = 0; /* can it change? */
rrq->disabled = 0;
rrq->value = 0;
@@ -866,8 +820,7 @@ static int p80211wext_giwrate(netdevice_t *dev,
default:
err = -EINVAL;
}
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -876,17 +829,15 @@ static int p80211wext_giwrts(netdevice_t *dev,
struct iw_param *rts, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ 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, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -899,24 +850,20 @@ static int p80211wext_giwrts(netdevice_t *dev,
rts->disabled = (rts->value == 2347);
rts->fixed = 1;
- exit:
- DBFEXIT;
+exit:
return err;
}
-
static int p80211wext_siwrts(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *rts, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
- DBFENTER;
-
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
@@ -930,15 +877,14 @@ static int p80211wext_siwrts(netdevice_t *dev,
mibitem.data = rts->value;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -947,17 +893,16 @@ static int p80211wext_giwfrag(netdevice_t *dev,
struct iw_param *frag, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ 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;
+ mibitem.did =
+ DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -970,8 +915,7 @@ static int p80211wext_giwfrag(netdevice_t *dev,
frag->disabled = (frag->value == 2346);
frag->fixed = 1;
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -980,20 +924,19 @@ static int p80211wext_siwfrag(netdevice_t *dev,
struct iw_param *frag, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ 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;
+ mibitem.did =
+ DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
if (frag->disabled)
mibitem.data = 2346;
@@ -1001,15 +944,14 @@ static int p80211wext_siwfrag(netdevice_t *dev,
mibitem.data = frag->value;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -1026,19 +968,17 @@ static int p80211wext_giwretry(netdevice_t *dev,
struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
u16 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, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1052,7 +992,7 @@ static int p80211wext_giwretry(netdevice_t *dev,
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1063,10 +1003,11 @@ static int p80211wext_giwretry(netdevice_t *dev,
longretry = mibitem.data;
- mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
+ mibitem.did =
+ DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1094,8 +1035,7 @@ static int p80211wext_giwretry(netdevice_t *dev,
}
}
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -1105,13 +1045,11 @@ static int p80211wext_siwretry(netdevice_t *dev,
struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
- DBFENTER;
-
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
@@ -1125,11 +1063,12 @@ static int p80211wext_siwretry(netdevice_t *dev,
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;
+ mibitem.did =
+ DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
+ mibitem.data = rrq->value /= 1024;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1137,11 +1076,13 @@ static int p80211wext_siwretry(netdevice_t *dev,
}
} else {
if (rrq->flags & IW_RETRY_LONG) {
- mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
+ mibitem.did =
+ DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
mibitem.data = rrq->value;
- memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ memcpy(&msg.mibattribute.data, &mibitem,
+ sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1150,11 +1091,13 @@ static int p80211wext_siwretry(netdevice_t *dev,
}
if (rrq->flags & IW_RETRY_SHORT) {
- mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
+ mibitem.did =
+ DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
mibitem.data = rrq->value;
- memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ memcpy(&msg.mibattribute.data, &mibitem,
+ sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1163,46 +1106,43 @@ static int p80211wext_siwretry(netdevice_t *dev,
}
}
- exit:
- DBFEXIT;
+exit:
return err;
}
static int p80211wext_siwtxpow(netdevice_t *dev,
- struct iw_request_info *info,
- struct iw_param *rrq, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
- int result;
- int err = 0;
-
- DBFENTER;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
- if (!wlan_wext_write) {
- err = (-EOPNOTSUPP);
- goto exit;
- }
+ if (!wlan_wext_write) {
+ err = (-EOPNOTSUPP);
+ goto exit;
+ }
- msg.msgcode = DIDmsg_dot11req_mibset;
- mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
+ msg.msgcode = DIDmsg_dot11req_mibset;
+ mibitem.did =
+ DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
if (rrq->fixed == 0)
- mibitem.data = 30;
+ mibitem.data = 30;
else
- mibitem.data = rrq->value;
- memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
-
- if (result) {
- err = -EFAULT;
- goto exit;
- }
-
- exit:
- DBFEXIT;
- return err;
+ mibitem.data = rrq->value;
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+exit:
+ return err;
}
static int p80211wext_giwtxpow(netdevice_t *dev,
@@ -1210,18 +1150,17 @@ static int p80211wext_giwtxpow(netdevice_t *dev,
struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ 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;
+ mibitem.did =
+ DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1230,15 +1169,14 @@ static int p80211wext_giwtxpow(netdevice_t *dev,
memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
- // XXX handle OFF by setting disabled = 1;
+ /* XXX handle OFF by setting disabled = 1; */
- rrq->flags = 0; // IW_TXPOW_DBM;
+ rrq->flags = 0; /* IW_TXPOW_DBM; */
rrq->disabled = 0;
rrq->fixed = 0;
rrq->value = mibitem.data;
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -1247,33 +1185,32 @@ static int p80211wext_siwspy(netdevice_t *dev,
struct iw_point *srq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- struct sockaddr address[IW_MAX_SPY];
- int number = srq->length;
- int i;
-
- DBFENTER;
+ struct sockaddr address[IW_MAX_SPY];
+ int number = srq->length;
+ int i;
/* Copy the data from the input buffer */
- memcpy(address, extra, sizeof(struct sockaddr)*number);
+ memcpy(address, extra, sizeof(struct sockaddr) * number);
- wlandev->spy_number = 0;
+ wlandev->spy_number = 0;
- if (number > 0) {
+ if (number > 0) {
- /* extract the addresses */
- for (i = 0; i < number; i++) {
+ /* extract the addresses */
+ for (i = 0; i < number; i++) {
- memcpy(wlandev->spy_address[i], address[i].sa_data, ETH_ALEN);
+ 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);
+ /* reset stats */
+ memset(wlandev->spy_stat, 0,
+ sizeof(struct iw_quality) * IW_MAX_SPY);
- /* set number of addresses */
- wlandev->spy_number = number;
- }
+ /* set number of addresses */
+ wlandev->spy_number = number;
+ }
- DBFEXIT;
return 0;
}
@@ -1284,74 +1221,72 @@ static int p80211wext_giwspy(netdevice_t *dev,
{
wlandevice_t *wlandev = dev->ml_priv;
- struct sockaddr address[IW_MAX_SPY];
- struct iw_quality spy_stat[IW_MAX_SPY];
- int number;
- int i;
-
- DBFENTER;
+ struct sockaddr address[IW_MAX_SPY];
+ struct iw_quality spy_stat[IW_MAX_SPY];
+ int number;
+ int i;
- number = wlandev->spy_number;
+ number = wlandev->spy_number;
- if (number > 0) {
+ 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));
- }
+ /* 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;
- }
+ 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);
+ /* 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)
+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;
+ 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;
}
static int p80211wext_siwscan(netdevice_t *dev,
- struct iw_request_info *info,
- struct iw_point *srq, char *extra)
+ struct iw_request_info *info,
+ struct iw_point *srq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211msg_dot11req_scan_t msg;
+ 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");
+ printk(KERN_ERR "Can't scan in AP mode\n");
err = (-EOPNOTSUPP);
goto exit;
}
@@ -1360,36 +1295,34 @@ static int p80211wext_siwscan(netdevice_t *dev,
msg.msgcode = DIDmsg_dot11req_scan;
msg.bsstype.data = P80211ENUM_bsstype_any;
- memset(&(msg.bssid.data), 0xFF, sizeof (p80211item_pstr6_t));
+ 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.data[i - 1] = i;
msg.channellist.data.len = 14;
msg.maxchanneltime.data = 250;
msg.minchanneltime.data = 200;
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result)
- err = prism2_result2err (msg.resultcode.data);
+ err = prism2_result2err(msg.resultcode.data);
- exit:
- DBFEXIT;
+exit:
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)
+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 */
@@ -1397,7 +1330,9 @@ wext_translate_bss(struct iw_request_info *info, char *current_ev,
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);
+ 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 */
@@ -1406,33 +1341,39 @@ wext_translate_bss(struct iw_request_info *info, char *current_ev,
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));
+ size =
+ min_t(unsigned short, 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);
+ pr_debug(" 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");
+ current_ev =
+ iwe_stream_add_point(info, current_ev, end_buf, &iwe,
+ &essid[0]);
+ pr_debug(" essid size OK.\n");
}
switch (bss->bsstype.data) {
- case P80211ENUM_bsstype_infrastructure:
- iwe.u.mode = IW_MODE_MASTER;
- break;
+ case P80211ENUM_bsstype_infrastructure:
+ iwe.u.mode = IW_MODE_MASTER;
+ break;
- case P80211ENUM_bsstype_independent:
- iwe.u.mode = IW_MODE_ADHOC;
- break;
+ case P80211ENUM_bsstype_independent:
+ iwe.u.mode = IW_MODE_ADHOC;
+ break;
- default:
- iwe.u.mode = 0;
- 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);
+ 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)
@@ -1441,13 +1382,16 @@ wext_translate_bss(struct iw_request_info *info, char *current_ev,
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);
+ 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);
+ 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;
@@ -1455,26 +1399,25 @@ wext_translate_bss(struct iw_request_info *info, char *current_ev,
/* 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);
+ 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)
+ struct iw_request_info *info,
+ struct iw_point *srq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211msg_dot11req_scan_results_t msg;
+ 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.
@@ -1484,110 +1427,115 @@ static int p80211wext_giwscan(netdevice_t *dev,
msg.msgcode = DIDmsg_dot11req_scan_results;
msg.bssindex.data = i;
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&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);
+ 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 */
+ srq->flags = 0; /* todo */
if (result && !scan_good)
- err = prism2_result2err (msg.resultcode.data);
+ err = prism2_result2err(msg.resultcode.data);
- DBFEXIT;
return err;
}
-/*****************************************************/
-//extra wireless extensions stuff to support NetworkManager (I hope)
+/* extra wireless extensions stuff to support NetworkManager (I hope) */
/* SIOCSIWENCODEEXT */
static int p80211wext_set_encodeext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
- wlandevice_t *wlandev = dev->ml_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,(u8*)&msg);
- WLAN_LOG_DEBUG(1,"result (%d)\n",result);
- }
- return result;
+ wlandevice_t *wlandev = dev->ml_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;
+
+ pr_debug("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--;
+ }
+ pr_debug("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)) {
+ pr_debug("asked to set a non wep key :(");
+ return -EINVAL;
+ }
+ if (idx) {
+ if (idx < 1 || idx > NUM_WEPKEYS)
+ return -EINVAL;
+ else
+ idx--;
+ }
+ pr_debug("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, (u8 *)&msg);
+ pr_debug("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)
-
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
@@ -1597,24 +1545,24 @@ static int p80211wext_get_encodeext(struct net_device *dev,
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);
-
+ pr_debug("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);
+ if (max_len <= 0) {
+ pr_debug("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);
+ pr_debug("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);
+ if (idx < 1 || idx > NUM_WEPKEYS) {
+ printk(KERN_DEBUG
+ "get_encode_ext invalid key index [%d]\n", idx);
result = -EINVAL;
goto exit;
}
@@ -1625,203 +1573,207 @@ static int p80211wext_get_encodeext(struct net_device *dev,
}
encoding->flags = idx + 1;
- memset(ext,0,sizeof(*ext));
+ 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 );
+ 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)
+static int p80211_wext_set_iwauth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
- wlandevice_t *wlandev = dev->ml_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;
-}
+ wlandevice_t *wlandev = dev->ml_priv;
+ struct iw_param *param = &wrqu->param;
+ int result = 0;
-/* 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 = dev->ml_priv;
- struct iw_param *param = &wrqu->param;
- int result =0;
+ pr_debug("set_iwauth flags[%d]\n",
+ (int)param->flags & IW_AUTH_INDEX);
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_DROP_UNENCRYPTED:
+ pr_debug("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:
+ pr_debug("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) {
+ pr_debug("set open_system\n");
+ wlandev->hostwep &= ~HOSTWEP_SHAREDKEY;
+ } else if (param->value & IW_AUTH_ALG_SHARED_KEY) {
+ pr_debug("set shared key\n");
+ wlandev->hostwep |= HOSTWEP_SHAREDKEY;
+ } else {
+ /* don't know what to do know */
+ pr_debug("unknown AUTH_ALG (%d)\n",
+ param->value);
+ result = -EINVAL;
+ }
+ break;
- WLAN_LOG_DEBUG(1,"get_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX );
+ default:
+ break;
+ }
- switch (param->flags & IW_AUTH_INDEX) {
- case IW_AUTH_DROP_UNENCRYPTED:
- param->value = wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED?1:0;
- break;
+ return result;
+}
- case IW_AUTH_PRIVACY_INVOKED:
- param->value = wlandev->hostwep & HOSTWEP_PRIVACYINVOKED?1:0;
- break;
+/* 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 = dev->ml_priv;
+ struct iw_param *param = &wrqu->param;
+ int result = 0;
- case IW_AUTH_80211_AUTH_ALG:
- param->value = wlandev->hostwep & HOSTWEP_SHAREDKEY?IW_AUTH_ALG_SHARED_KEY:IW_AUTH_ALG_OPEN_SYSTEM;
- break;
+ pr_debug("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;
- default:
- 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;
+ return result;
}
-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 */
- (iw_handler) p80211wext_siwscan, /* SIOCSIWSCAN */
- (iw_handler) p80211wext_giwscan, /* SIOCGIWSCAN */
- (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 */
+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 */
+ (iw_handler) p80211wext_siwscan, /* SIOCSIWSCAN */
+ (iw_handler) p80211wext_giwscan, /* SIOCGIWSCAN */
+ (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 */
/* 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 */
+ (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 */
};
struct iw_handler_def p80211wext_handler_def = {
.num_standard = ARRAY_SIZE(p80211wext_handlers),
.num_private = 0,
.num_private_args = 0,
- .standard = p80211wext_handlers,
+ .standard = p80211wext_handlers,
.private = NULL,
.private_args = NULL,
.get_wireless_stats = p80211wext_get_wireless_stats
};
-
int p80211wext_event_associated(wlandevice_t *wlandev, int assoc)
{
- union iwreq_data data;
-
- DBFENTER;
+ union iwreq_data data;
- /* 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);
- }
+ /* Send the association state first */
+ data.ap_addr.sa_family = ARPHRD_ETHER;
+ if (assoc)
+ memcpy(data.ap_addr.sa_data, wlandev->bssid, ETH_ALEN);
+ else
+ memset(data.ap_addr.sa_data, 0, ETH_ALEN);
- if (wlan_wext_write)
- wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL);
+ if (wlan_wext_write)
+ wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL);
- if (!assoc) goto done;
+ if (!assoc)
+ goto done;
- // XXX send association data, like IEs, etc etc.
+ /* XXX send association data, like IEs, etc etc. */
- done:
- DBFEXIT;
- return 0;
+done:
+ return 0;
}
-
-
-
-
diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c
index f1727ba6ec6..e7a7939b428 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.c
+++ b/drivers/staging/wlan-ng/prism2mgmt.c
@@ -57,11 +57,6 @@
* --------------------------------------------------------------------
*/
-/*================================================================*/
-/* System Includes */
-#define WLAN_DBVAR prism2_debug
-
-
#include <linux/if_arp.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -76,8 +71,7 @@
#include <asm/byteorder.h>
#include <linux/random.h>
#include <linux/usb.h>
-
-#include "wlan_compat.h"
+#include <linux/bitops.h>
/*================================================================*/
/* Project Includes */
@@ -94,10 +88,10 @@
#include "prism2mgmt.h"
/* 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)
+#define p80211rate_to_p2bit(n) ((((n)&~BIT(7)) == 2) ? BIT(0) : \
+ (((n)&~BIT(7)) == 4) ? BIT(1) : \
+ (((n)&~BIT(7)) == 11) ? BIT(2) : \
+ (((n)&~BIT(7)) == 22) ? BIT(3) : 0)
/*----------------------------------------------------------------
* prism2mgmt_scan
@@ -125,183 +119,188 @@
----------------------------------------------------------------*/
int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
{
- int result = 0;
- hfa384x_t *hw = wlandev->priv;
- p80211msg_dot11req_scan_t *msg = msgp;
- u16 roamingmode, word;
- int i, timeout;
- int istmpenable = 0;
-
- hfa384x_HostScanRequest_data_t scanreq;
-
- DBFENTER;
-
- /* 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;
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_dot11req_scan_t *msg = msgp;
+ u16 roamingmode, word;
+ int i, timeout;
+ int istmpenable = 0;
+
+ hfa384x_HostScanRequest_data_t scanreq;
+
+ /* 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)) {
+ printk(KERN_ERR
+ "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");
- }
- }
+ memset(&scanreq, 0, sizeof(scanreq));
+
+ /* save current roaming mode */
+ result = hfa384x_drvr_getconfig16(hw,
+ HFA384x_RID_CNFROAMINGMODE,
+ &roamingmode);
+ if (result) {
+ printk(KERN_ERR "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) {
+ printk(KERN_ERR "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 = cpu_to_le16(msg->maxchanneltime.data);
+ else
+ word = 0;
+
+ result =
+ hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL,
+ word);
+ if (result) {
+ printk(KERN_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++) {
- u8 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);
+ scanreq.txRate = cpu_to_le16(word);
+
+ /* set up the channel list */
+ word = 0;
+ for (i = 0; i < msg->channellist.data.len; i++) {
+ u8 channel = msg->channellist.data.data[i];
+ if (channel > 14)
+ continue;
+ /* channel 1 is BIT 0 ... channel 14 is BIT 13 */
+ word |= (1 << (channel - 1));
+ }
+ scanreq.channelList = cpu_to_le16(word);
+
+ /* set up the ssid, if present. */
+ scanreq.ssid.len = cpu_to_le16(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);
+ if (result) {
+ printk(KERN_ERR "getconfig(PORTSTATUS) failed. "
+ "result=%d\n", result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
goto exit;
}
if (word == HFA384x_PORTSTATUS_DISABLED) {
u16 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);
+ HFA384x_RID_CNFROAMINGMODE,
+ HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
+ if (result) {
+ printk(KERN_ERR
+ "setconfig(ROAMINGMODE) failed. result=%d\n",
+ result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
goto exit;
}
/* Construct a bogus SSID and assign it to OwnSSID and
* DesiredSSID
*/
- wordbuf[0] = host2hfa384x_16(WLAN_SSID_MAXLEN);
+ wordbuf[0] = cpu_to_le16(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");
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
+ wordbuf,
+ HFA384x_RID_CNFOWNSSID_LEN);
+ if (result) {
+ printk(KERN_ERR "Failed to set OwnSSID.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ 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");
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
+ wordbuf,
+ HFA384x_RID_CNFDESIREDSSID_LEN);
+ if (result) {
+ printk(KERN_ERR "Failed to set DesiredSSID.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ 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");
+ HFA384x_RID_CNFPORTTYPE,
+ HFA384x_PORTTYPE_IBSS);
+ if (result) {
+ printk(KERN_ERR "Failed to set CNFPORTTYPE.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ 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");
+ HFA384x_RID_CREATEIBSS,
+ HFA384x_CREATEIBSS_JOINCREATEIBSS);
+ if (result) {
+ printk(KERN_ERR "Failed to set CREATEIBSS.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ 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);
+ if (result) {
+ printk(KERN_ERR "drvr_enable(0) failed. "
+ "result=%d\n", result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ 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;
+ /* Figure out our timeout first Kus, then HZ */
+ timeout = msg->channellist.data.len * msg->maxchanneltime.data;
+ timeout = (timeout * HZ) / 1000;
- WLAN_HEX_DUMP(5,"hscanreq", &scanreq, sizeof(scanreq));
+ /* Issue the scan request */
+ hw->scanflag = 0;
- 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;
- }
+ result = hfa384x_drvr_setconfig(hw,
+ HFA384x_RID_HOSTSCAN, &scanreq,
+ sizeof(hfa384x_HostScanRequest_data_t));
+ if (result) {
+ printk(KERN_ERR "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);
+ /* 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)
@@ -309,16 +308,16 @@ int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
msg->numbss.data = hw->scanflag;
- hw->scanflag = 0;
+ 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);
+ if (result) {
+ printk(KERN_ERR "drvr_disable(0) failed. "
+ "result=%d\n", result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
goto exit;
}
}
@@ -326,25 +325,23 @@ int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
/* 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:
+ if (result) {
+ printk(KERN_ERR "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
*
@@ -367,32 +364,32 @@ int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
{
- int result = 0;
- p80211msg_dot11req_scan_results_t *req;
- hfa384x_t *hw = wlandev->priv;
+ 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 = (p80211msg_dot11req_scan_results_t *) msgp;
req->resultcode.status = P80211ENUM_msgitem_status_data_ok;
- if (! hw->scanresults) {
- WLAN_LOG_ERROR("dot11req_scan_results can only be used after a successful dot11req_scan.\n");
+ if (!hw->scanresults) {
+ printk(KERN_ERR
+ "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;
+ 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);
+ pr_debug("requested index (%d) out of range (%d)\n",
+ req->bssindex.data, count);
result = 2;
req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
goto exit;
@@ -402,8 +399,8 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
/* 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);
+ req->signal.data = le16_to_cpu(item->sl);
+ req->noise.data = le16_to_cpu(item->anl);
/* BSSID */
req->bssid.status = P80211ENUM_msgitem_status_data_ok;
@@ -412,13 +409,13 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
/* SSID */
req->ssid.status = P80211ENUM_msgitem_status_data_ok;
- req->ssid.data.len = hfa384x2host_16(item->ssid.len);
+ req->ssid.data.len = le16_to_cpu(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;
+ 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])) { \
@@ -452,7 +449,7 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
/* beacon period */
req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok;
- req->beaconperiod.data = hfa384x2host_16(item->bcnint);
+ req->beaconperiod.data = le16_to_cpu(item->bcnint);
/* timestamps */
req->timestamp.status = P80211ENUM_msgitem_status_data_ok;
@@ -462,14 +459,14 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
/* atim window */
req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok;
- req->ibssatimwindow.data = hfa384x2host_16(item->atim);
+ req->ibssatimwindow.data = le16_to_cpu(item->atim);
/* Channel */
req->dschannel.status = P80211ENUM_msgitem_status_data_ok;
- req->dschannel.data = hfa384x2host_16(item->chid);
+ req->dschannel.data = le16_to_cpu(item->chid);
/* capinfo bits */
- count = hfa384x2host_16(item->capinfo);
+ count = le16_to_cpu(item->capinfo);
/* privacy flag */
req->privacy.status = P80211ENUM_msgitem_status_data_ok;
@@ -484,25 +481,14 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count);
/* bsstype */
- req->bsstype.status = P80211ENUM_msgitem_status_data_ok;
+ 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
-*/
+ P80211ENUM_bsstype_infrastructure : P80211ENUM_bsstype_independent;
result = 0;
req->resultcode.data = P80211ENUM_resultcode_success;
- exit:
- DBFEXIT;
+exit:
return result;
}
@@ -527,15 +513,14 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
{
- int result = 0;
- hfa384x_t *hw = wlandev->priv;
- p80211msg_dot11req_start_t *msg = msgp;
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_dot11req_start_t *msg = msgp;
- p80211pstrd_t *pstr;
- u8 bytebuf[80];
- hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
- u16 word;
- DBFENTER;
+ p80211pstrd_t *pstr;
+ u8 bytebuf[80];
+ hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t *) bytebuf;
+ u16 word;
wlandev->macmode = WLAN_MACMODE_NONE;
@@ -547,7 +532,7 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
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)) {
+ 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;
@@ -559,18 +544,19 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
/*** STATION ***/
/* Set the REQUIRED config items */
/* SSID */
- pstr = (p80211pstrd_t*)&(msg->ssid.data);
+ 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");
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
+ bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
+ if (result) {
+ printk(KERN_ERR "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");
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
+ bytebuf,
+ HFA384x_RID_CNFDESIREDSSID_LEN);
+ if (result) {
+ printk(KERN_ERR "Failed to set CnfDesiredSSID\n");
goto failed;
}
@@ -581,84 +567,84 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
/* 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);
+ if (result) {
+ printk(KERN_ERR "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);
+ if (result) {
+ printk(KERN_ERR "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 ) {
+ 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 ) {
+
+ 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 ) {
+
+ 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 ) {
+
+ 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 ) {
+
+ 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 ) {
+
+ 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 ) {
+
+ 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);
+ if (result) {
+ printk(KERN_ERR "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 ) {
+ 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 ) {
+
+ 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 ) {
+
+ 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 ) {
+
+ 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 ) {
+
+ 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 ) {
+
+ 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 ) {
+
+ 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);
+ if (result) {
+ printk(KERN_ERR "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);
+ if (result) {
+ printk(KERN_ERR "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 ) {
+ 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);
@@ -666,8 +652,8 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
/* Enable the Port */
result = hfa384x_drvr_enable(hw, 0);
- if ( result ) {
- WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
+ if (result) {
+ printk(KERN_ERR "Enable macport failed, result=%d.\n", result);
goto failed;
}
@@ -675,13 +661,12 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
goto done;
failed:
- WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result);
+ pr_debug("Failed to set a config option, result=%d\n", result);
msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
done:
result = 0;
- DBFEXIT;
return result;
}
@@ -705,40 +690,35 @@ done:
----------------------------------------------------------------*/
int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
- p80211msg_p2req_readpda_t *msg = msgp;
- int result;
- DBFENTER;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_readpda_t *msg = msgp;
+ int result;
/* 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");
+ printk(KERN_ERR
+ "PDA may only be read " "in the fwload state.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ 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);
+ 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);
+ printk(KERN_ERR
+ "hfa384x_drvr_readpda() failed, "
+ "result=%d\n", result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
msg->resultcode.status =
- P80211ENUM_msgitem_status_data_ok;
- DBFEXIT;
+ P80211ENUM_msgitem_status_data_ok;
return 0;
}
msg->pda.status = P80211ENUM_msgitem_status_data_ok;
@@ -746,7 +726,6 @@ int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
}
- DBFEXIT;
return 0;
}
@@ -777,30 +756,29 @@ int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
- p80211msg_p2req_ramdl_state_t *msg = msgp;
- DBFENTER;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_ramdl_state_t *msg = msgp;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
- WLAN_LOG_ERROR(
- "ramdl_state(): may only be called "
- "in the fwload state.\n");
+ printk(KERN_ERR
+ "ramdl_state(): may only be called "
+ "in the fwload state.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ 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.
- */
+ ** 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;
+ 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;
}
@@ -809,11 +787,9 @@ int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
msg->resultcode.data = P80211ENUM_resultcode_success;
}
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* prism2mgmt_ramdl_write
*
@@ -836,45 +812,41 @@ int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
- p80211msg_p2req_ramdl_write_t *msg = msgp;
- u32 addr;
- u32 len;
- u8 *buf;
- DBFENTER;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_ramdl_write_t *msg = msgp;
+ u32 addr;
+ u32 len;
+ u8 *buf;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
- WLAN_LOG_ERROR(
- "ramdl_write(): may only be called "
- "in the fwload state.\n");
+ printk(KERN_ERR
+ "ramdl_write(): may only be called "
+ "in the fwload state.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ 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;
+ 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) ) {
+ 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
*
@@ -902,31 +874,30 @@ int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
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;
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_flashdl_state_t *msg = msgp;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
- WLAN_LOG_ERROR(
- "flashdl_state(): may only be called "
- "in the fwload state.\n");
+ printk(KERN_ERR
+ "flashdl_state(): may only be called "
+ "in the fwload state.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ 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.
- */
+ ** 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;
+ 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;
}
@@ -943,19 +914,17 @@ int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
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);
+ printk(KERN_ERR "prism2sta_ifstate(fwload) failed,"
+ "P80211ENUM_resultcode=%d\n", result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
result = -1;
}
}
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* prism2mgmt_flashdl_write
*
@@ -976,47 +945,43 @@ int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
- p80211msg_p2req_flashdl_write_t *msg = msgp;
- u32 addr;
- u32 len;
- u8 *buf;
- DBFENTER;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_flashdl_write_t *msg = msgp;
+ u32 addr;
+ u32 len;
+ u8 *buf;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
- WLAN_LOG_ERROR(
- "flashdl_write(): may only be called "
- "in the fwload state.\n");
+ printk(KERN_ERR
+ "flashdl_write(): may only be called "
+ "in the fwload state.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ 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.
- */
+ ** 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) ) {
+ if (msg->len.data > sizeof(msg->data.data)) {
msg->resultcode.status =
- P80211ENUM_resultcode_invalid_parameters;
+ 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) ) {
+ if (hfa384x_drvr_flashdl_write(hw, addr, buf, len))
msg->resultcode.data = P80211ENUM_resultcode_refused;
- }
msg->resultcode.data = P80211ENUM_resultcode_success;
- DBFEXIT;
return 0;
}
@@ -1041,15 +1006,14 @@ int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
- int result = 0;
- u16 reg;
- u16 port_type;
- p80211msg_lnxreq_autojoin_t *msg = msgp;
- p80211pstrd_t *pstr;
- u8 bytebuf[256];
- hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
- DBFENTER;
+ hfa384x_t *hw = wlandev->priv;
+ int result = 0;
+ u16 reg;
+ u16 port_type;
+ p80211msg_lnxreq_autojoin_t *msg = msgp;
+ p80211pstrd_t *pstr;
+ u8 bytebuf[256];
+ hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t *) bytebuf;
wlandev->macmode = WLAN_MACMODE_NONE;
@@ -1064,39 +1028,21 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, 0x000f);
/* Set the auth type */
- if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) {
+ if (msg->authtype.data == P80211ENUM_authalg_sharedkey)
reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY;
- } else {
+ 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);
+ 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
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
+ bytebuf,
+ HFA384x_RID_CNFDESIREDSSID_LEN);
port_type = HFA384x_PORTTYPE_BSS;
-#endif
/* Set the PortType */
hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, port_type);
@@ -1107,11 +1053,9 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* prism2mgmt_wlansniff
*
@@ -1133,38 +1077,36 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
{
- int result = 0;
- p80211msg_lnxreq_wlansniff_t *msg = msgp;
+ int result = 0;
+ p80211msg_lnxreq_wlansniff_t *msg = msgp;
- hfa384x_t *hw = wlandev->priv;
- u16 word;
-
- DBFENTER;
+ hfa384x_t *hw = wlandev->priv;
+ u16 word;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
- switch (msg->enable.data)
- {
+ 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;
+ 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);
+ if (result) {
+ printk(KERN_DEBUG
+ "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);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to disable port 0 after sniffing, result=%d\n",
+ result);
goto failed;
}
/* Clear the driver state */
@@ -1172,32 +1114,34 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
/* 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);
+ HFA384x_RID_CNFWEPFLAGS,
+ hw->presniff_wepflags);
+ if (result) {
+ printk(KERN_DEBUG
+ "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 ) {
+ 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);
+ HFA384x_RID_CNFPORTTYPE,
+ word);
+ if (result) {
+ printk(KERN_DEBUG
+ "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);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to enable port to presniff setting, result=%d\n",
+ result);
goto failed;
}
} else {
@@ -1205,46 +1149,52 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
}
- WLAN_LOG_INFO("monitor mode disabled\n");
+ printk(KERN_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 (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);
+ &(hw->
+ presniff_port_type));
+ if (result) {
+ printk(KERN_DEBUG
+ "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);
+ &(hw->
+ presniff_wepflags));
+ if (result) {
+ printk(KERN_DEBUG
+ "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);
+ if (result) {
+ printk(KERN_DEBUG
+ "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);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to enable port for sniffing, result=%d\n",
+ result);
goto failed;
}
}
@@ -1255,14 +1205,14 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
/* Set the channel we wish to sniff */
word = msg->channel.data;
result = hfa384x_drvr_setconfig16(hw,
- HFA384x_RID_CNFOWNCHANNEL, word);
- hw->sniff_channel=word;
+ HFA384x_RID_CNFOWNCHANNEL,
+ word);
+ hw->sniff_channel = word;
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "failed to set channel %d, result=%d\n",
- word,
- result);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to set channel %d, result=%d\n",
+ word, result);
goto failed;
}
@@ -1271,39 +1221,46 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
/* 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);
+ HFA384x_RID_CNFPORTTYPE,
+ word);
+ if (result) {
+ printk(KERN_DEBUG
+ "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)) {
+ 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);
+ 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);
+ if (result) {
+ printk(KERN_DEBUG
+ "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)) {
+ 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) {
+ if (msg->packet_trunc.status ==
+ P80211ENUM_msgitem_status_data_ok) {
hw->sniff_truncate = msg->packet_trunc.data;
} else {
hw->sniff_truncate = 0;
@@ -1311,31 +1268,35 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
/* 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);
+ if (result) {
+ printk(KERN_DEBUG
+ "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);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to enable monitor mode, result=%d\n",
+ result);
goto failed;
}
- if (wlandev->netdev->type == ARPHRD_ETHER) {
- WLAN_LOG_INFO("monitor mode enabled\n");
- }
+ if (wlandev->netdev->type == ARPHRD_ETHER)
+ printk(KERN_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)) {
+ 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)) {
+ } 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 {
@@ -1357,7 +1318,5 @@ 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
index caf808d5796..07eecebeb6c 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.h
+++ b/drivers/staging/wlan-ng/prism2mgmt.h
@@ -60,43 +60,16 @@
#ifndef _PRISM2MGMT_H
#define _PRISM2MGMT_H
+extern int prism2_reset_holdtime;
+extern int prism2_reset_settletime;
-/*=============================================================*/
-/*------ Constants --------------------------------------------*/
+u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate);
-/*=============================================================*/
-/*------ Macros -----------------------------------------------*/
-
-/*=============================================================*/
-/*------ Types and their related constants --------------------*/
-
-/*=============================================================*/
-/*------ Static variable externs ------------------------------*/
-
-extern int prism2_debug;
-extern int prism2_reset_holdtime;
-extern int prism2_reset_settletime;
-/*=============================================================*/
-/*--- Function Declarations -----------------------------------*/
-/*=============================================================*/
-
-u32
-prism2sta_ifstate(wlandevice_t *wlandev, u32 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, u16 status);
-void
-prism2sta_ev_tx(wlandevice_t *wlandev, u16 status);
-void
-prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
-void
-prism2sta_ev_alloc(wlandevice_t *wlandev);
+void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status);
+void prism2sta_ev_tx(wlandevice_t *wlandev, u16 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_scan(wlandevice_t *wlandev, void *msgp);
@@ -122,34 +95,16 @@ void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len);
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(u16 *prism2int, u32 *wlanint);
-void prism2mgmt_p80211int2prism2int(u16 *prism2int, u32 *wlanint);
-
-/* enumerated integer conversion functions */
-void prism2mgmt_prism2enum2p80211enum(u16 *prism2enum, u32 *wlanenum, u16 rid);
-void prism2mgmt_p80211enum2prism2enum(u16 *prism2enum, u32 *wlanenum, u16 rid);
-
-/* functions to convert a bit area to/from an Operational Rate Set */
-void prism2mgmt_get_oprateset(u16 *rate, p80211pstrd_t *pstr);
-void prism2mgmt_set_oprateset(u16 *rate, p80211pstrd_t *pstr);
-
/* functions to convert Group Addresses */
-void prism2mgmt_get_grpaddr(u32 did,
- p80211pstrd_t *pstr, hfa384x_t *priv );
+void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t *pstr, hfa384x_t *priv);
int prism2mgmt_set_grpaddr(u32 did,
- u8 *prism2buf, p80211pstrd_t *pstr, hfa384x_t *priv );
-int prism2mgmt_get_grpaddr_index( u32 did );
+ u8 *prism2buf, p80211pstrd_t *pstr,
+ hfa384x_t *priv);
+int prism2mgmt_get_grpaddr_index(u32 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
index 539c4479d38..5a6ba86009d 100644
--- a/drivers/staging/wlan-ng/prism2mib.c
+++ b/drivers/staging/wlan-ng/prism2mib.c
@@ -50,12 +50,7 @@
* --------------------------------------------------------------------
*/
-/*================================================================*/
-/* System Includes */
-#define WLAN_DBVAR prism2_debug
-
#include <linux/version.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -63,13 +58,11 @@
#include <linux/slab.h>
#include <linux/wireless.h>
#include <linux/netdevice.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/delay.h>
#include <asm/byteorder.h>
#include <linux/usb.h>
-
-/*================================================================*/
-/* Project Includes */
+#include <linux/bitops.h>
#include "p80211types.h"
#include "p80211hdr.h"
@@ -82,196 +75,169 @@
#include "hfa384x.h"
#include "prism2mgmt.h"
-/*================================================================*/
-/* Local Constants */
-
-#define MIB_TMP_MAXLEN 200 /* Max length of RID record (in bytes). */
-
-/*================================================================*/
-/* Local Types */
-
-#define F_STA 0x1 /* MIB is supported on stations. */
-#define F_READ 0x2 /* MIB may be read. */
-#define F_WRITE 0x4 /* MIB may be written. */
-
-typedef struct mibrec
-{
- u32 did;
- u16 flag;
- u16 parm1;
- u16 parm2;
- u16 parm3;
- int (*func)(struct mibrec *mib,
- int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
- p80211msg_dot11req_mibset_t *msg,
- void *data);
+#define MIB_TMP_MAXLEN 200 /* Max length of RID record (in bytes). */
+
+#define F_STA 0x1 /* MIB is supported on stations. */
+#define F_READ 0x2 /* MIB may be read. */
+#define F_WRITE 0x4 /* MIB may be written. */
+
+typedef struct mibrec {
+ u32 did;
+ u16 flag;
+ u16 parm1;
+ u16 parm2;
+ u16 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_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_flag(
-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_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_priv(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data);
-
-/*================================================================*/
-/* Local Static Definitions */
+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_flag(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_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_priv(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg, void *data);
static mibrec_t mibtab[] = {
- /* dot11smt MIB's */
- { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0,
- F_STA | F_WRITE,
- HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
- prism2mib_wepdefaultkey },
- { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1,
- F_STA | F_WRITE,
- HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
- prism2mib_wepdefaultkey },
- { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2,
- F_STA | F_WRITE,
- HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
- prism2mib_wepdefaultkey },
- { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3,
- F_STA | F_WRITE,
- HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
- prism2mib_wepdefaultkey },
- { DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0,
- prism2mib_privacyinvoked },
- { DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
- prism2mib_uint32 },
- { DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0,
- prism2mib_excludeunencrypted },
-
- /* dot11mac MIB's */
-
- { DIDmib_dot11mac_dot11OperationTable_dot11MACAddress,
- 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_dot11ShortRetryLimit,
- F_STA | F_READ,
- HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
- prism2mib_uint32 },
- { DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit,
- 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_dot11MaxTransmitMSDULifetime,
- F_STA | F_READ,
- HFA384x_RID_MAXTXLIFETIME, 0, 0,
- prism2mib_uint32 },
-
- /* dot11phy MIB's */
-
- { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
- F_STA | F_READ,
- HFA384x_RID_CURRENTCHANNEL, 0, 0,
- prism2mib_uint32 },
- { DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_TXPOWERMAX, 0, 0,
- prism2mib_uint32 },
-
- /* p2Static MIB's */
-
- { DIDmib_p2_p2Static_p2CnfPortType,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_CNFPORTTYPE, 0, 0,
- prism2mib_uint32 },
-
- /* p2MAC MIB's */
-
- { DIDmib_p2_p2MAC_p2CurrentTxRate,
- F_STA | F_READ,
- HFA384x_RID_CURRENTTXRATE, 0, 0,
- prism2mib_uint32 },
-
- /* 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}};
-
-/*================================================================*/
-/* Function Definitions */
+ /* dot11smt MIB's */
+ {DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0,
+ F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
+ prism2mib_wepdefaultkey},
+ {DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1,
+ F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
+ prism2mib_wepdefaultkey},
+ {DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2,
+ F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
+ prism2mib_wepdefaultkey},
+ {DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3,
+ F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
+ prism2mib_wepdefaultkey},
+ {DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0,
+ prism2mib_privacyinvoked},
+ {DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
+ prism2mib_uint32},
+ {DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0,
+ prism2mib_excludeunencrypted},
+
+ /* dot11mac MIB's */
+
+ {DIDmib_dot11mac_dot11OperationTable_dot11MACAddress,
+ 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_dot11ShortRetryLimit,
+ F_STA | F_READ,
+ HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
+ prism2mib_uint32},
+ {DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit,
+ 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_dot11MaxTransmitMSDULifetime,
+ F_STA | F_READ,
+ HFA384x_RID_MAXTXLIFETIME, 0, 0,
+ prism2mib_uint32},
+
+ /* dot11phy MIB's */
+
+ {DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
+ F_STA | F_READ,
+ HFA384x_RID_CURRENTCHANNEL, 0, 0,
+ prism2mib_uint32},
+ {DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_TXPOWERMAX, 0, 0,
+ prism2mib_uint32},
+
+ /* p2Static MIB's */
+
+ {DIDmib_p2_p2Static_p2CnfPortType,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFPORTTYPE, 0, 0,
+ prism2mib_uint32},
+
+ /* p2MAC MIB's */
+
+ {DIDmib_p2_p2MAC_p2CurrentTxRate,
+ F_STA | F_READ,
+ HFA384x_RID_CURRENTTXRATE, 0, 0,
+ prism2mib_uint32},
+
+ /* 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}
+};
/*----------------------------------------------------------------
* prism2mgmt_mibset_mibget
@@ -295,32 +261,30 @@ static mibrec_t mibtab[] = {
int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
- int result, isget;
- mibrec_t *mib;
-
- u16 which;
+ hfa384x_t *hw = wlandev->priv;
+ int result, isget;
+ mibrec_t *mib;
- p80211msg_dot11req_mibset_t *msg = msgp;
- p80211itemd_t *mibitem;
+ u16 which;
- DBFENTER;
+ p80211msg_dot11req_mibset_t *msg = msgp;
+ p80211itemd_t *mibitem;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
/*
- ** Determine if this is an Access Point or a station.
- */
+ ** Determine if this is an Access Point or a station.
+ */
which = 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.
- */
+ ** 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;
@@ -334,58 +298,55 @@ int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp)
}
/*
- ** 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.
- */
+ ** 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;
+ P80211ENUM_resultcode_cant_get_writeonly_mib;
goto done;
}
} else {
if (!(mib->flag & F_WRITE)) {
msg->resultcode.data =
- P80211ENUM_resultcode_cant_set_readonly_mib;
+ 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".
- */
+ ** 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);
+ 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);
+ pr_debug("get/set failure, result=%d\n",
+ result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
} else {
if (isget) {
msg->mibattribute.status =
- P80211ENUM_msgitem_status_data_ok;
+ P80211ENUM_msgitem_status_data_ok;
mibitem->status =
- P80211ENUM_msgitem_status_data_ok;
+ P80211ENUM_msgitem_status_data_ok;
}
}
}
done:
- DBFEXIT;
-
- return(0);
+ return 0;
}
/*----------------------------------------------------------------
@@ -413,31 +374,29 @@ done:
*
----------------------------------------------------------------*/
-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_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;
- u8 bytebuf[MIB_TMP_MAXLEN];
-
- DBFENTER;
+ int result;
+ p80211pstrd_t *pstr = (p80211pstrd_t *) data;
+ u8 bytebuf[MIB_TMP_MAXLEN];
if (isget) {
- result = hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2);
+ 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);
+ result =
+ hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2);
}
- DBFEXIT;
- return(result);
+ return result;
}
/*----------------------------------------------------------------
@@ -465,37 +424,26 @@ 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_uint32(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg, void *data)
{
- int result;
- u32 *uint32 = (u32*) data;
- u8 bytebuf[MIB_TMP_MAXLEN];
- u16 *wordbuf = (u16*) bytebuf;
-
- DBFENTER;
+ int result;
+ u32 *uint32 = (u32 *) data;
+ u8 bytebuf[MIB_TMP_MAXLEN];
+ u16 *wordbuf = (u16 *) bytebuf;
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);
+ return result;
}
/*----------------------------------------------------------------
@@ -523,46 +471,36 @@ 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_flag(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg, void *data)
{
- int result;
- u32 *uint32 = (u32*) data;
- u8 bytebuf[MIB_TMP_MAXLEN];
- u16 *wordbuf = (u16*) bytebuf;
- u32 flags;
-
- DBFENTER;
+ int result;
+ u32 *uint32 = (u32 *) data;
+ u8 bytebuf[MIB_TMP_MAXLEN];
+ u16 *wordbuf = (u16 *) bytebuf;
+ u32 flags;
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;
+ 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);
+ result =
+ hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
}
}
- DBFEXIT;
- return(result);
+ return result;
}
/*----------------------------------------------------------------
@@ -590,33 +528,29 @@ 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_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;
- u8 bytebuf[MIB_TMP_MAXLEN];
- u16 len;
-
- DBFENTER;
+ int result;
+ p80211pstrd_t *pstr = (p80211pstrd_t *) data;
+ u8 bytebuf[MIB_TMP_MAXLEN];
+ u16 len;
if (isget) {
- result = 0; /* Should never happen. */
+ result = 0; /* Should never happen. */
} else {
len = (pstr->len > 5) ? HFA384x_RID_CNFWEP128DEFAULTKEY_LEN :
- HFA384x_RID_CNFWEPDEFAULTKEY_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);
+ return result;
}
/*----------------------------------------------------------------
@@ -644,17 +578,14 @@ 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_privacyinvoked(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data)
{
- int result;
-
- DBFENTER;
+ int result;
if (wlandev->hostwep & HOSTWEP_DECRYPT) {
if (wlandev->hostwep & HOSTWEP_DECRYPT)
@@ -665,8 +596,7 @@ void *data)
result = prism2mib_flag(mib, isget, wlandev, hw, msg, data);
- DBFEXIT;
- return(result);
+ return result;
}
/*----------------------------------------------------------------
@@ -694,22 +624,18 @@ 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_excludeunencrypted(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data)
{
- int result;
-
- DBFENTER;
+ int result;
result = prism2mib_flag(mib, isget, wlandev, hw, msg, data);
- DBFEXIT;
- return(result);
+ return result;
}
/*----------------------------------------------------------------
@@ -737,31 +663,28 @@ 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_fragmentationthreshold(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data)
{
- int result;
- u32 *uint32 = (u32*) data;
-
- DBFENTER;
+ int result;
+ u32 *uint32 = (u32 *) data;
if (!isget)
if ((*uint32) % 2) {
- WLAN_LOG_WARNING("Attempt to set odd number "
- "FragmentationThreshold\n");
- msg->resultcode.data = P80211ENUM_resultcode_not_supported;
- return(0);
+ printk(KERN_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);
+ return result;
}
/*----------------------------------------------------------------
@@ -789,43 +712,43 @@ 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 int prism2mib_priv(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg, void *data)
{
- p80211pstrd_t *pstr = (p80211pstrd_t*) data;
+ p80211pstrd_t *pstr = (p80211pstrd_t *) data;
- int result;
-
- DBFENTER;
+ int result;
switch (mib->did) {
- case DIDmib_lnx_lnxConfigTable_lnxRSNAIE: {
- hfa384x_WPAData_t wpa;
- if (isget) {
- hfa384x_drvr_getconfig( hw, HFA384x_RID_CNFWPADATA,
- (u8 *) &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,
- (u8 *) &wpa, sizeof(wpa));
+ case DIDmib_lnx_lnxConfigTable_lnxRSNAIE:{
+ hfa384x_WPAData_t wpa;
+ if (isget) {
+ hfa384x_drvr_getconfig(hw,
+ HFA384x_RID_CNFWPADATA,
+ (u8 *)&wpa,
+ sizeof(wpa));
+ pstr->len = le16_to_cpu(wpa.datalen);
+ memcpy(pstr->data, wpa.data, pstr->len);
+ } else {
+ wpa.datalen = cpu_to_le16(pstr->len);
+ memcpy(wpa.data, pstr->data, pstr->len);
+
+ result =
+ hfa384x_drvr_setconfig(hw,
+ HFA384x_RID_CNFWPADATA,
+ (u8 *)&wpa,
+ sizeof(wpa));
+ }
+ break;
}
- break;
- }
default:
- WLAN_LOG_ERROR("Unhandled DID 0x%08x\n", mib->did);
+ printk(KERN_ERR "Unhandled DID 0x%08x\n", mib->did);
}
- DBFEXIT;
- return(0);
+ return 0;
}
/*----------------------------------------------------------------
@@ -845,14 +768,10 @@ void *data)
void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
{
- DBFENTER;
-
- bytestr->len = host2hfa384x_16((u16)(pstr->len));
+ bytestr->len = cpu_to_le16((u16) (pstr->len));
memcpy(bytestr->data, pstr->data, pstr->len);
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* prism2mgmt_pstr2bytearea
*
@@ -870,13 +789,9 @@ void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr)
{
- DBFENTER;
-
memcpy(bytearea, pstr->data, pstr->len);
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* prism2mgmt_bytestr2pstr
*
@@ -894,14 +809,10 @@ void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr)
void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
{
- DBFENTER;
-
- pstr->len = (u8)(hfa384x2host_16((u16)(bytestr->len)));
+ pstr->len = (u8) (le16_to_cpu((u16) (bytestr->len)));
memcpy(pstr->data, bytestr->data, pstr->len);
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* prism2mgmt_bytearea2pstr
*
@@ -919,217 +830,11 @@ void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len)
{
- DBFENTER;
-
- pstr->len = (u8)len;
+ pstr->len = (u8) 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(u16 *prism2int, u32 *wlanint)
-{
- DBFENTER;
-
- *wlanint = (u32)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(u16 *prism2int, u32 *wlanint)
-{
- DBFENTER;
-
- *prism2int = host2hfa384x_16((u16)(*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(u16 *prism2enum, u32 *wlanenum, u16 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(u16 *prism2enum, u32 *wlanenum, u16 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(u16 *rate, p80211pstrd_t *pstr)
-{
- u8 len;
- u8 *datarate;
-
- DBFENTER;
-
- len = 0;
- datarate = pstr->data;
-
- /* 1 Mbps */
- if ( BIT0 & (*rate) ) {
- len += (u8)1;
- *datarate = (u8)2;
- datarate++;
- }
- /* 2 Mbps */
- if ( BIT1 & (*rate) ) {
- len += (u8)1;
- *datarate = (u8)4;
- datarate++;
- }
-
- /* 5.5 Mbps */
- if ( BIT2 & (*rate) ) {
- len += (u8)1;
- *datarate = (u8)11;
- datarate++;
- }
-
- /* 11 Mbps */
- if ( BIT3 & (*rate) ) {
- len += (u8)1;
- *datarate = (u8)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(u16 *rate, p80211pstrd_t *pstr)
-{
- u8 *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;
-}
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c
index b279c97cbc0..9d57f82f4a2 100644
--- a/drivers/staging/wlan-ng/prism2sta.c
+++ b/drivers/staging/wlan-ng/prism2sta.c
@@ -50,10 +50,6 @@
* --------------------------------------------------------------------
*/
-/*================================================================*/
-/* System Includes */
-#define WLAN_DBVAR prism2_debug
-
#include <linux/version.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -65,13 +61,15 @@
#include <linux/wireless.h>
#include <linux/netdevice.h>
#include <linux/workqueue.h>
+#include <linux/byteorder/generic.h>
+#include <linux/ctype.h>
#include <asm/io.h>
#include <linux/delay.h>
#include <asm/byteorder.h>
#include <linux/if_arp.h>
-
-#include "wlan_compat.h"
+#include <linux/if_ether.h>
+#include <linux/bitops.h>
/*================================================================*/
/* Project Includes */
@@ -88,111 +86,78 @@
#include "hfa384x.h"
#include "prism2mgmt.h"
-/*================================================================*/
-/* Local Constants */
-
-/*================================================================*/
-/* Local Macros */
-
-/*================================================================*/
-/* Local Types */
-
-/*================================================================*/
-/* Local Static Definitions */
+#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 (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; \
+ } \
+ } \
+}
static char *dev_info = "prism2_usb";
-
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 */
-int prism2_reset_holdtime=30; /* Reset hold time in ms */
-int prism2_reset_settletime=100; /* Reset settle time in ms */
+static int prism2_doreset = 0; /* Do a reset at init? */
-static int prism2_doreset=0; /* Do a reset at init? */
-
-#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_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");
+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");
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);
-
-/*================================================================*/
-/* 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 ", ((u8*)buf)[c]);
- if ( (c % 16) == 15 ) printk("\n");
- }
- if ( (c % 16) != 0 ) printk("\n");
-}
-
+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);
/*----------------------------------------------------------------
* prism2sta_open
@@ -217,8 +182,6 @@ inline void dmpmem(void *buf, int n)
----------------------------------------------------------------*/
static int prism2sta_open(wlandevice_t *wlandev)
{
- DBFENTER;
-
/* We don't currently have to do anything else.
* The setup of the MAC should be subsequently completed via
* the mlme commands.
@@ -227,11 +190,9 @@ static int prism2sta_open(wlandevice_t *wlandev)
* frames because of dev->flags&IFF_UP is true.
*/
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* prism2sta_close
*
@@ -255,19 +216,15 @@ static int prism2sta_open(wlandevice_t *wlandev)
----------------------------------------------------------------*/
static int prism2sta_close(wlandevice_t *wlandev)
{
- DBFENTER;
-
/* 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
*
@@ -285,14 +242,11 @@ static int prism2sta_close(wlandevice_t *wlandev)
* Call context:
* process thread
----------------------------------------------------------------*/
-static void prism2sta_reset(wlandevice_t *wlandev )
+static void prism2sta_reset(wlandevice_t *wlandev)
{
- DBFENTER;
- DBFEXIT;
return;
}
-
/*----------------------------------------------------------------
* prism2sta_txframe
*
@@ -318,22 +272,20 @@ 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;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ int result;
/* 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));
+ if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) ==
+ HOSTWEP_PRIVACYINVOKED) {
+ p80211_hdr->a3.fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1));
}
result = hfa384x_drvr_txframe(hw, skb, p80211_hdr, p80211_wep);
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* prism2sta_mlmerequest
*
@@ -360,109 +312,113 @@ static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
----------------------------------------------------------------*/
static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ 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");
+ switch (msg->msgcode) {
+ case DIDmsg_dot11req_mibget:
+ pr_debug("Received mibget request\n");
result = prism2mgmt_mibset_mibget(wlandev, msg);
break;
- case DIDmsg_dot11req_mibset :
- WLAN_LOG_DEBUG(2,"Received mibset request\n");
+ case DIDmsg_dot11req_mibset:
+ pr_debug("Received mibset request\n");
result = prism2mgmt_mibset_mibget(wlandev, msg);
break;
- case DIDmsg_dot11req_scan :
- WLAN_LOG_DEBUG(2,"Received scan request\n");
+ case DIDmsg_dot11req_scan:
+ pr_debug("Received scan request\n");
result = prism2mgmt_scan(wlandev, msg);
break;
- case DIDmsg_dot11req_scan_results :
- WLAN_LOG_DEBUG(2,"Received scan_results request\n");
+ case DIDmsg_dot11req_scan_results:
+ pr_debug("Received scan_results request\n");
result = prism2mgmt_scan_results(wlandev, msg);
break;
- case DIDmsg_dot11req_start :
- WLAN_LOG_DEBUG(2,"Received mlme start request\n");
+ case DIDmsg_dot11req_start:
+ pr_debug("Received mlme start request\n");
result = prism2mgmt_start(wlandev, msg);
break;
- /*
- * Prism2 specific messages
- */
- case DIDmsg_p2req_readpda :
- WLAN_LOG_DEBUG(2,"Received mlme readpda request\n");
+ /*
+ * Prism2 specific messages
+ */
+ case DIDmsg_p2req_readpda:
+ pr_debug("Received mlme readpda request\n");
result = prism2mgmt_readpda(wlandev, msg);
break;
- case DIDmsg_p2req_ramdl_state :
- WLAN_LOG_DEBUG(2,"Received mlme ramdl_state request\n");
+ case DIDmsg_p2req_ramdl_state:
+ pr_debug("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");
+ case DIDmsg_p2req_ramdl_write:
+ pr_debug("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");
+ case DIDmsg_p2req_flashdl_state:
+ pr_debug("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");
+ case DIDmsg_p2req_flashdl_write:
+ pr_debug("Received mlme flashdl_write request\n");
result = prism2mgmt_flashdl_write(wlandev, msg);
break;
- /*
- * Linux specific messages
- */
- case DIDmsg_lnxreq_hostwep :
- break; // ignore me.
- case DIDmsg_lnxreq_ifstate :
+ /*
+ * 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;
+ p80211msg_lnxreq_ifstate_t *ifstatemsg;
+ pr_debug("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");
+ break;
+ case DIDmsg_lnxreq_wlansniff:
+ pr_debug("Received mlme wlansniff request\n");
+ result = prism2mgmt_wlansniff(wlandev, msg);
+ break;
+ case DIDmsg_lnxreq_autojoin:
+ pr_debug("Received mlme autojoin request\n");
result = prism2mgmt_autojoin(wlandev, msg);
break;
- case DIDmsg_lnxreq_commsquality: {
- p80211msg_lnxreq_commsquality_t *qualmsg;
-
- WLAN_LOG_DEBUG(2,"Received commsquality request\n");
+ case DIDmsg_lnxreq_commsquality:{
+ p80211msg_lnxreq_commsquality_t *qualmsg;
- qualmsg = (p80211msg_lnxreq_commsquality_t*) msg;
+ pr_debug("Received commsquality request\n");
- 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 = (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);
+ qualmsg->link.data =
+ le16_to_cpu(hw->qual.CQ_currBSS);
+ qualmsg->level.data =
+ le16_to_cpu(hw->qual.ASL_currBSS);
+ qualmsg->noise.data =
+ le16_to_cpu(hw->qual.ANL_currFC);
- break;
- }
+ break;
+ }
default:
- WLAN_LOG_WARNING("Unknown mgmt request message 0x%08x", msg->msgcode);
+ printk(KERN_WARNING "Unknown mgmt request message 0x%08x",
+ msg->msgcode);
break;
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* prism2sta_ifstate
*
@@ -486,16 +442,14 @@ static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
----------------------------------------------------------------*/
u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- u32 result;
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ u32 result;
result = P80211ENUM_resultcode_implementation_failure;
- WLAN_LOG_DEBUG(2, "Current MSD state(%d), requesting(%d)\n",
- wlandev->msdstate, ifstate);
- switch (ifstate)
- {
+ pr_debug("Current MSD state(%d), requesting(%d)\n",
+ wlandev->msdstate, ifstate);
+ switch (ifstate) {
case P80211ENUM_ifstate_fwload:
switch (wlandev->msdstate) {
case WLAN_MSD_HWPRESENT:
@@ -504,12 +458,12 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
* Initialize the device+driver sufficiently
* for firmware loading.
*/
- if ((result=hfa384x_drvr_start(hw))) {
- WLAN_LOG_ERROR(
- "hfa384x_drvr_start() failed,"
- "result=%d\n", (int)result);
+ if ((result = hfa384x_drvr_start(hw))) {
+ printk(KERN_ERR
+ "hfa384x_drvr_start() failed,"
+ "result=%d\n", (int)result);
result =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
wlandev->msdstate = WLAN_MSD_HWPRESENT;
break;
}
@@ -521,9 +475,9 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_RUNNING:
- WLAN_LOG_WARNING(
- "Cannot enter fwload state from enable state,"
- "you must disable first.\n");
+ printk(KERN_WARNING
+ "Cannot enter fwload state from enable state,"
+ "you must disable first.\n");
result = P80211ENUM_resultcode_invalid_parameters;
break;
case WLAN_MSD_HWFAIL:
@@ -548,32 +502,32 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
* 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);
+ if ((result = hfa384x_drvr_start(hw))) {
+ printk(KERN_ERR
+ "hfa384x_drvr_start() failed,"
+ "result=%d\n", (int)result);
result =
- P80211ENUM_resultcode_implementation_failure;
+ 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);
+ if ((result = prism2sta_getcardinfo(wlandev))) {
+ printk(KERN_ERR
+ "prism2sta_getcardinfo() failed,"
+ "result=%d\n", (int)result);
result =
- P80211ENUM_resultcode_implementation_failure;
+ 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);
+ if ((result = prism2sta_globalsetup(wlandev))) {
+ printk(KERN_ERR
+ "prism2sta_globalsetup() failed,"
+ "result=%d\n", (int)result);
result =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
hfa384x_drvr_stop(hw);
wlandev->msdstate = WLAN_MSD_HWPRESENT;
break;
@@ -584,7 +538,7 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_RUNNING:
- /* Do nothing, we're already in this state.*/
+ /* Do nothing, we're already in this state. */
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_HWFAIL:
@@ -599,7 +553,7 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
case P80211ENUM_ifstate_disable:
switch (wlandev->msdstate) {
case WLAN_MSD_HWPRESENT:
- /* Do nothing, we're already in this state.*/
+ /* Do nothing, we're already in this state. */
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_FWLOAD:
@@ -634,11 +588,9 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
break;
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* prism2sta_getcardinfo
*
@@ -660,269 +612,284 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
----------------------------------------------------------------*/
static int prism2sta_getcardinfo(wlandevice_t *wlandev)
{
- int result = 0;
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- u16 temp;
- u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN];
- char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1];
-
- DBFENTER;
+ int result = 0;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ u16 temp;
+ u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN];
+ char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1];
/* 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");
+ &hw->ident_nic,
+ sizeof(hfa384x_compident_t));
+ if (result) {
+ printk(KERN_ERR "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);
+ hw->ident_nic.id = le16_to_cpu(hw->ident_nic.id);
+ hw->ident_nic.variant = le16_to_cpu(hw->ident_nic.variant);
+ hw->ident_nic.major = le16_to_cpu(hw->ident_nic.major);
+ hw->ident_nic.minor = le16_to_cpu(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);
+ printk(KERN_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");
+ &hw->ident_pri_fw,
+ sizeof(hfa384x_compident_t));
+ if (result) {
+ printk(KERN_ERR "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);
+ hw->ident_pri_fw.id = le16_to_cpu(hw->ident_pri_fw.id);
+ hw->ident_pri_fw.variant = le16_to_cpu(hw->ident_pri_fw.variant);
+ hw->ident_pri_fw.major = le16_to_cpu(hw->ident_pri_fw.major);
+ hw->ident_pri_fw.minor = le16_to_cpu(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);
+ printk(KERN_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");
+ &hw->ident_sta_fw,
+ sizeof(hfa384x_compident_t));
+ if (result) {
+ printk(KERN_ERR "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");
+ printk(KERN_ERR
+ "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);
+ hw->ident_sta_fw.id = le16_to_cpu(hw->ident_sta_fw.id);
+ hw->ident_sta_fw.variant = le16_to_cpu(hw->ident_sta_fw.variant);
+ hw->ident_sta_fw.major = le16_to_cpu(hw->ident_sta_fw.major);
+ hw->ident_sta_fw.minor = le16_to_cpu(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 &= ~((u16)(BIT14 | BIT15));
-
- if ( hw->ident_sta_fw.id == 0x1f ) {
- 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);
+ hw->mm_mods = hw->ident_sta_fw.variant & (BIT(14) | BIT(15));
+ hw->ident_sta_fw.variant &= ~((u16) (BIT(14) | BIT(15)));
+
+ if (hw->ident_sta_fw.id == 0x1f) {
+ printk(KERN_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 {
- 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);
- WLAN_LOG_ERROR("Unsupported Tertiary AP firmeare loaded!\n");
+ printk(KERN_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);
+ printk(KERN_ERR "Unsupported Tertiary AP firmeare loaded!\n");
goto failed;
}
/* 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");
+ &hw->cap_sup_mfi,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "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);
+ fields in byte order */
+ hw->cap_sup_mfi.role = le16_to_cpu(hw->cap_sup_mfi.role);
+ hw->cap_sup_mfi.id = le16_to_cpu(hw->cap_sup_mfi.id);
+ hw->cap_sup_mfi.variant = le16_to_cpu(hw->cap_sup_mfi.variant);
+ hw->cap_sup_mfi.bottom = le16_to_cpu(hw->cap_sup_mfi.bottom);
+ hw->cap_sup_mfi.top = le16_to_cpu(hw->cap_sup_mfi.top);
+
+ printk(KERN_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");
+ &hw->cap_sup_cfi,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "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);
+ fields in byte order */
+ hw->cap_sup_cfi.role = le16_to_cpu(hw->cap_sup_cfi.role);
+ hw->cap_sup_cfi.id = le16_to_cpu(hw->cap_sup_cfi.id);
+ hw->cap_sup_cfi.variant = le16_to_cpu(hw->cap_sup_cfi.variant);
+ hw->cap_sup_cfi.bottom = le16_to_cpu(hw->cap_sup_cfi.bottom);
+ hw->cap_sup_cfi.top = le16_to_cpu(hw->cap_sup_cfi.top);
+
+ printk(KERN_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");
+ &hw->cap_sup_pri,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "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);
+ fields in byte order */
+ hw->cap_sup_pri.role = le16_to_cpu(hw->cap_sup_pri.role);
+ hw->cap_sup_pri.id = le16_to_cpu(hw->cap_sup_pri.id);
+ hw->cap_sup_pri.variant = le16_to_cpu(hw->cap_sup_pri.variant);
+ hw->cap_sup_pri.bottom = le16_to_cpu(hw->cap_sup_pri.bottom);
+ hw->cap_sup_pri.top = le16_to_cpu(hw->cap_sup_pri.top);
+
+ printk(KERN_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");
+ &hw->cap_sup_sta,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "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);
+ fields in byte order */
+ hw->cap_sup_sta.role = le16_to_cpu(hw->cap_sup_sta.role);
+ hw->cap_sup_sta.id = le16_to_cpu(hw->cap_sup_sta.id);
+ hw->cap_sup_sta.variant = le16_to_cpu(hw->cap_sup_sta.variant);
+ hw->cap_sup_sta.bottom = le16_to_cpu(hw->cap_sup_sta.bottom);
+ hw->cap_sup_sta.top = le16_to_cpu(hw->cap_sup_sta.top);
+
+ if (hw->cap_sup_sta.id == 0x04) {
+ printk(KERN_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);
+ printk(KERN_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");
+ &hw->cap_act_pri_cfi,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "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);
+ fields in byte order */
+ hw->cap_act_pri_cfi.role = le16_to_cpu(hw->cap_act_pri_cfi.role);
+ hw->cap_act_pri_cfi.id = le16_to_cpu(hw->cap_act_pri_cfi.id);
+ hw->cap_act_pri_cfi.variant =
+ le16_to_cpu(hw->cap_act_pri_cfi.variant);
+ hw->cap_act_pri_cfi.bottom =
+ le16_to_cpu(hw->cap_act_pri_cfi.bottom);
+ hw->cap_act_pri_cfi.top = le16_to_cpu(hw->cap_act_pri_cfi.top);
+
+ printk(KERN_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");
+ &hw->cap_act_sta_cfi,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "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);
+ fields in byte order */
+ hw->cap_act_sta_cfi.role = le16_to_cpu(hw->cap_act_sta_cfi.role);
+ hw->cap_act_sta_cfi.id = le16_to_cpu(hw->cap_act_sta_cfi.id);
+ hw->cap_act_sta_cfi.variant =
+ le16_to_cpu(hw->cap_act_sta_cfi.variant);
+ hw->cap_act_sta_cfi.bottom =
+ le16_to_cpu(hw->cap_act_sta_cfi.bottom);
+ hw->cap_act_sta_cfi.top = le16_to_cpu(hw->cap_act_sta_cfi.top);
+
+ printk(KERN_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");
+ &hw->cap_act_sta_mfi,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "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);
+ fields in byte order */
+ hw->cap_act_sta_mfi.role = le16_to_cpu(hw->cap_act_sta_mfi.role);
+ hw->cap_act_sta_mfi.id = le16_to_cpu(hw->cap_act_sta_mfi.id);
+ hw->cap_act_sta_mfi.variant =
+ le16_to_cpu(hw->cap_act_sta_mfi.variant);
+ hw->cap_act_sta_mfi.bottom =
+ le16_to_cpu(hw->cap_act_sta_mfi.bottom);
+ hw->cap_act_sta_mfi.top = le16_to_cpu(hw->cap_act_sta_mfi.top);
+
+ printk(KERN_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 ) {
+ 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);
+ printk(KERN_INFO "Prism2 card SN: %s\n", pstr);
} else {
- WLAN_LOG_ERROR("Failed to retrieve Prism2 Card SN\n");
+ printk(KERN_ERR "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");
+ wlandev->netdev->dev_addr, ETH_ALEN);
+ if (result != 0) {
+ printk(KERN_ERR "Failed to retrieve mac address\n");
goto failed;
}
@@ -939,10 +906,10 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
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)) {
+ 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;
}
@@ -950,13 +917,11 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
goto done;
failed:
- WLAN_LOG_ERROR("Failed, result=%d\n", result);
+ printk(KERN_ERR "Failed, result=%d\n", result);
done:
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* prism2sta_globalsetup
*
@@ -977,43 +942,33 @@ done:
----------------------------------------------------------------*/
static int prism2sta_globalsetup(wlandevice_t *wlandev)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
/* Set the maximum frame size */
return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN,
- WLAN_DATA_MAXLEN);
+ WLAN_DATA_MAXLEN);
}
static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev)
{
int result = 0;
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
- u16 promisc;
-
- DBFENTER;
+ u16 promisc;
/* If we're not ready, what's the point? */
- if ( hw->state != HFA384x_STATE_RUNNING )
+ if (hw->state != HFA384x_STATE_RUNNING)
goto exit;
- if ( (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0 )
+ 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;
+ result =
+ hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE,
+ promisc);
+exit:
return result;
}
@@ -1035,15 +990,13 @@ static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev)
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void prism2sta_inf_handover(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_handover(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf)
{
- DBFENTER;
- WLAN_LOG_DEBUG(2,"received infoframe:HANDOVER (unhandled)\n");
- DBFEXIT;
+ pr_debug("received infoframe:HANDOVER (unhandled)\n");
return;
}
-
/*----------------------------------------------------------------
* prism2sta_inf_tallies
*
@@ -1061,37 +1014,34 @@ static void prism2sta_inf_handover(wlandevice_t *wlandev, hfa384x_InfFrame_t *in
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void prism2sta_inf_tallies(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_tallies(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- u16 *src16;
- u32 *dst;
- u32 *src32;
- int i;
- int cnt;
-
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ u16 *src16;
+ u32 *dst;
+ u32 *src32;
+ int i;
+ int cnt;
/*
- ** Determine if these are 16-bit or 32-bit tallies, based on the
- ** record length of the info record.
- */
+ ** 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(u32);
if (inf->framelen > 22) {
- dst = (u32 *) &hw->tallies;
- src32 = (u32 *) &inf->info.commtallies32;
+ dst = (u32 *)&hw->tallies;
+ src32 = (u32 *)&inf->info.commtallies32;
for (i = 0; i < cnt; i++, dst++, src32++)
- *dst += hfa384x2host_32(*src32);
+ *dst += le32_to_cpu(*src32);
} else {
- dst = (u32 *) &hw->tallies;
- src16 = (u16 *) &inf->info.commtallies16;
+ dst = (u32 *)&hw->tallies;
+ src16 = (u16 *)&inf->info.commtallies16;
for (i = 0; i < cnt; i++, dst++, src16++)
- *dst += hfa384x2host_16(*src16);
+ *dst += le16_to_cpu(*src16);
}
- DBFEXIT;
-
return;
}
@@ -1116,44 +1066,40 @@ 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;
+ 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;
/* Get the number of results, first in bytes, then in results */
nbss = (inf->framelen * sizeof(u16)) -
- sizeof(inf->infotype) -
- sizeof(inf->info.scanresult.scanreason);
+ 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);
+ pr_debug("rx scanresults, reason=%d, nbss=%d:\n",
+ inf->info.scanresult.scanreason, nbss);
+ for (i = 0; i < nbss; i++) {
+ pr_debug("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);
+ pr_debug(" 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);
+ 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);
+ printk(KERN_ERR "setconfig(joinreq) failed, result=%d\n",
+ result);
}
- DBFEXIT;
return;
}
@@ -1177,18 +1123,16 @@ static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- int nbss;
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ int nbss;
nbss = (inf->framelen - 3) / 32;
- WLAN_LOG_DEBUG(1, "Received %d hostscan results\n", nbss);
+ pr_debug("Received %d hostscan results\n", nbss);
if (nbss > 32)
nbss = 32;
- if (hw->scanresults)
- kfree(hw->scanresults);
+ kfree(hw->scanresults);
hw->scanresults = kmalloc(sizeof(hfa384x_InfFrame_t), GFP_ATOMIC);
memcpy(hw->scanresults, inf, sizeof(hfa384x_InfFrame_t));
@@ -1196,11 +1140,9 @@ static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
if (nbss == 0)
nbss = -1;
- /* Notify/wake the sleeping caller. */
- hw->scanflag = nbss;
- wake_up_interruptible(&hw->cmdq);
-
- DBFEXIT;
+ /* Notify/wake the sleeping caller. */
+ hw->scanflag = nbss;
+ wake_up_interruptible(&hw->cmdq);
};
/*----------------------------------------------------------------
@@ -1223,55 +1165,60 @@ static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- unsigned int i, n;
+ 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
- );
+ le16_to_cpu(inf->info.chinforesult.scanchannels);
+
+ for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) {
+ if (hw->channel_info.results.scanchannels & (1 << i)) {
+ int channel =
+ le16_to_cpu(inf->info.chinforesult.result[n].
+ chid) - 1;
+ hfa384x_ChInfoResultSub_t *chinforesult =
+ &hw->channel_info.results.result[channel];
+ chinforesult->chid = channel;
+ chinforesult->anl =
+ le16_to_cpu(inf->info.chinforesult.result[n].
+ anl);
+ chinforesult->pnl =
+ le16_to_cpu(inf->info.chinforesult.result[n].
+ pnl);
+ chinforesult->active =
+ le16_to_cpu(inf->info.chinforesult.result[n].
+ active);
+ printk(KERN_DEBUG
+ "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_t *hw = container_of(data, struct hfa384x, link_bh);
+ wlandevice_t *wlandev = hw->wlandev;
hfa384x_bytestr32_t ssid;
- int result;
+ int result;
- DBFENTER;
/* First let's process the auth frames */
{
- struct sk_buff *skb;
+ struct sk_buff *skb;
hfa384x_InfFrame_t *inf;
- while ( (skb = skb_dequeue(&hw->authq)) ) {
+ while ((skb = skb_dequeue(&hw->authq))) {
inf = (hfa384x_InfFrame_t *) skb->data;
prism2sta_inf_authreq_defer(wlandev, inf);
}
@@ -1284,7 +1231,7 @@ void prism2sta_processing_defer(struct work_struct *data)
hw->link_status = hw->link_status_new;
- switch(hw->link_status) {
+ 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
@@ -1294,7 +1241,7 @@ void prism2sta_processing_defer(struct work_struct *data)
*/
netif_carrier_off(wlandev->netdev);
- WLAN_LOG_INFO("linkstatus=NOTCONNECTED (unhandled)\n");
+ printk(KERN_INFO "linkstatus=NOTCONNECTED (unhandled)\n");
break;
case HFA384x_LINK_CONNECTED:
@@ -1311,53 +1258,56 @@ void prism2sta_processing_defer(struct work_struct *data)
netif_carrier_on(wlandev->netdev);
/* If we are joining a specific AP, set our state and reset retries */
- if(hw->join_ap == 1)
+ 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 ) {
- u16 portstatus;
+ if (wlandev->netdev->type == ARPHRD_ETHER) {
+ u16 portstatus;
- WLAN_LOG_INFO("linkstatus=CONNECTED\n");
+ printk(KERN_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);
+ wlandev->bssid,
+ WLAN_BSSID_LEN);
+ if (result) {
+ printk(KERN_DEBUG
+ "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);
+ if (result) {
+ printk(KERN_DEBUG
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTSSID, result);
goto failed;
}
prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
- (p80211pstrd_t *) &wlandev->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);
+ HFA384x_RID_PORTSTATUS,
+ &portstatus);
+ if (result) {
+ printk(KERN_DEBUG
+ "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;
+ (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);
@@ -1374,18 +1324,20 @@ void prism2sta_processing_defer(struct work_struct *data)
* Indicate Deauthentication
* Block Transmits, Ignore receives of data frames
*/
- if(hw->join_ap == 2)
- {
- hfa384x_JoinRequest_data_t joinreq;
+ 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");
+ hfa384x_drvr_setconfig(hw,
+ HFA384x_RID_JOINREQUEST,
+ &joinreq,
+ HFA384x_RID_JOINREQUEST_LEN);
+ printk(KERN_INFO
+ "linkstatus=DISCONNECTED (re-submitting join)\n");
} else {
if (wlandev->netdev->type == ARPHRD_ETHER)
- WLAN_LOG_INFO("linkstatus=DISCONNECTED (unhandled)\n");
+ printk(KERN_INFO
+ "linkstatus=DISCONNECTED (unhandled)\n");
}
wlandev->macmode = WLAN_MACMODE_NONE;
@@ -1408,30 +1360,29 @@ void prism2sta_processing_defer(struct work_struct *data)
* Indicate Reassociation
* Enable Transmits, Receives and pass up data frames
*/
- WLAN_LOG_INFO("linkstatus=AP_CHANGE\n");
+ printk(KERN_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);
+ if (result) {
+ printk(KERN_DEBUG
+ "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);
+ if (result) {
+ printk(KERN_DEBUG
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTSSID, result);
goto failed;
}
prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
- (p80211pstrd_t *) &wlandev->ssid);
-
+ (p80211pstrd_t *)&wlandev->ssid);
hw->link_status = HFA384x_LINK_CONNECTED;
netif_carrier_on(wlandev->netdev);
@@ -1450,7 +1401,7 @@ void prism2sta_processing_defer(struct work_struct *data)
* Response:
* Block Transmits, Ignore receives of data frames
*/
- WLAN_LOG_INFO("linkstatus=AP_OUTOFRANGE (unhandled)\n");
+ printk(KERN_INFO "linkstatus=AP_OUTOFRANGE (unhandled)\n");
netif_carrier_off(wlandev->netdev);
@@ -1463,7 +1414,7 @@ void prism2sta_processing_defer(struct work_struct *data)
* Response:
* Enable Transmits, Receives and pass up data frames
*/
- WLAN_LOG_INFO("linkstatus=AP_INRANGE\n");
+ printk(KERN_INFO "linkstatus=AP_INRANGE\n");
hw->link_status = HFA384x_LINK_CONNECTED;
netif_carrier_on(wlandev->netdev);
@@ -1479,17 +1430,18 @@ void prism2sta_processing_defer(struct work_struct *data)
* Response:
* Disable Transmits, Ignore receives of data frames
*/
- if(hw->join_ap && --hw->join_retries > 0)
- {
- hfa384x_JoinRequest_data_t joinreq;
+ 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");
+ hfa384x_drvr_setconfig(hw,
+ HFA384x_RID_JOINREQUEST,
+ &joinreq,
+ HFA384x_RID_JOINREQUEST_LEN);
+ printk(KERN_INFO
+ "linkstatus=ASSOCFAIL (re-submitting join)\n");
} else {
- WLAN_LOG_INFO("linkstatus=ASSOCFAIL (unhandled)\n");
+ printk(KERN_INFO "linkstatus=ASSOCFAIL (unhandled)\n");
}
netif_carrier_off(wlandev->netdev);
@@ -1498,8 +1450,8 @@ void prism2sta_processing_defer(struct work_struct *data)
default:
/* This is bad, IO port problems? */
- WLAN_LOG_WARNING(
- "unknown linkstatus=0x%02x\n", hw->link_status);
+ printk(KERN_WARNING
+ "unknown linkstatus=0x%02x\n", hw->link_status);
goto failed;
break;
}
@@ -1509,8 +1461,8 @@ void prism2sta_processing_defer(struct work_struct *data)
p80211wext_event_associated(wlandev, wlandev->linkstatus);
#endif
- failed:
- DBFEXIT;
+failed:
+ return;
}
/*----------------------------------------------------------------
@@ -1533,15 +1485,12 @@ void prism2sta_processing_defer(struct work_struct *data)
static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
- DBFENTER;
-
- hw->link_status_new = hfa384x2host_16(inf->info.linkstatus.linkstatus);
+ hw->link_status_new = le16_to_cpu(inf->info.linkstatus.linkstatus);
schedule_work(&hw->link_bh);
- DBFEXIT;
return;
}
@@ -1566,45 +1515,43 @@ static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
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;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ hfa384x_AssocStatus_t rec;
+ int i;
memcpy(&rec, &inf->info.assocstatus, sizeof(rec));
- rec.assocstatus = hfa384x2host_16(rec.assocstatus);
- rec.reason = hfa384x2host_16(rec.reason);
+ rec.assocstatus = le16_to_cpu(rec.assocstatus);
+ rec.reason = le16_to_cpu(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.
- */
+ ** 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)
+ if (memcmp(rec.sta_addr, hw->authlist.addr[i], ETH_ALEN) == 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");
+ printk(KERN_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);
+ (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");
+ printk(KERN_WARNING
+ "authfail assocstatus info frame received for authenticated station.\n");
}
- DBFEXIT;
-
return;
}
@@ -1630,11 +1577,9 @@ static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
static void prism2sta_inf_authreq(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ 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));
@@ -1642,132 +1587,129 @@ static void prism2sta_inf_authreq(wlandevice_t *wlandev,
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;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ hfa384x_authenticateStation_data_t rec;
- int i, added, result, cnt;
- u8 *addr;
-
- DBFENTER;
+ int i, added, result, cnt;
+ u8 *addr;
/*
- ** Build the AuthenticateStation record. Initialize it for denying
- ** authentication.
- */
+ ** Build the AuthenticateStation record. Initialize it for denying
+ ** authentication.
+ */
- memcpy(rec.address, inf->info.authreq.sta_addr, WLAN_ADDR_LEN);
+ memcpy(rec.address, inf->info.authreq.sta_addr, ETH_ALEN);
rec.status = P80211ENUM_status_unspec_failure;
/*
- ** Authenticate based on the access mode.
- */
+ ** Authenticate based on the access mode.
+ */
switch (hw->accessmode) {
- case WLAN_ACCESS_NONE:
+ case WLAN_ACCESS_NONE:
- /*
- ** Deny all new authentications. However, if a station
- ** is ALREADY authenticated, then accept it.
- */
+ /*
+ ** 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;
- }
+ for (i = 0; i < hw->authlist.cnt; i++)
+ if (memcmp(rec.address, hw->authlist.addr[i],
+ ETH_ALEN) == 0) {
+ rec.status = P80211ENUM_status_successful;
+ break;
+ }
- break;
+ break;
- case WLAN_ACCESS_ALL:
+ case WLAN_ACCESS_ALL:
- /*
- ** Allow all authentications.
- */
+ /*
+ ** Allow all authentications.
+ */
- rec.status = P80211ENUM_status_successful;
- break;
+ rec.status = P80211ENUM_status_successful;
+ break;
- case WLAN_ACCESS_ALLOW:
+ 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];
+ /*
+ ** 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 += ETH_ALEN)
+ if (memcmp(rec.address, addr, ETH_ALEN) == 0) {
+ rec.status = P80211ENUM_status_successful;
+ break;
}
- 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;
- break;
+ case WLAN_ACCESS_DENY:
- 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.
+ */
- /*
- ** 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];
- }
+ 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;
+ 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;
- }
+ for (i = 0; i < cnt; i++, addr += ETH_ALEN)
+ if (memcmp(rec.address, addr, ETH_ALEN) == 0) {
+ rec.status = P80211ENUM_status_unspec_failure;
+ break;
+ }
- 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.)
- */
+ ** 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)
+ if (memcmp(rec.address, hw->authlist.addr[i], ETH_ALEN)
+ == 0)
break;
if (i >= hw->authlist.cnt) {
@@ -1775,7 +1717,7 @@ static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
rec.status = P80211ENUM_status_ap_full;
} else {
memcpy(hw->authlist.addr[hw->authlist.cnt],
- rec.address, WLAN_ADDR_LEN);
+ rec.address, ETH_ALEN);
hw->authlist.cnt++;
added = 1;
}
@@ -1783,27 +1725,26 @@ static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
}
/*
- ** 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.
- */
+ ** 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.status = cpu_to_le16(rec.status);
rec.algorithm = inf->info.authreq.algorithm;
result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA,
- &rec, sizeof(rec));
+ &rec, sizeof(rec));
if (result) {
- if (added) hw->authlist.cnt--;
- WLAN_LOG_ERROR("setconfig(authenticatestation) failed, result=%d\n", result);
+ if (added)
+ hw->authlist.cnt--;
+ printk(KERN_ERR
+ "setconfig(authenticatestation) failed, result=%d\n",
+ result);
}
-
- DBFEXIT;
-
return;
}
-
/*----------------------------------------------------------------
* prism2sta_inf_psusercnt
*
@@ -1825,74 +1766,14 @@ static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
-
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
- hw->psusercount = hfa384x2host_16(inf->info.psusercnt.usercnt);
-
- DBFEXIT;
+ hw->psusercount = le16_to_cpu(inf->info.psusercnt.usercnt);
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.
@@ -1911,56 +1792,53 @@ void prism2sta_ev_infdrop(wlandevice_t *wlandev)
----------------------------------------------------------------*/
void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
{
- DBFENTER;
- inf->infotype = hfa384x2host_16(inf->infotype);
+ inf->infotype = le16_to_cpu(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;
+ 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:
+ printk(KERN_WARNING "Unhandled IT_KEYIDCHANGED\n");
+ break;
+ case HFA384x_IT_ASSOCREQ:
+ printk(KERN_WARNING "Unhandled IT_ASSOCREQ\n");
+ break;
+ case HFA384x_IT_MICFAILURE:
+ printk(KERN_WARNING "Unhandled IT_MICFAILURE\n");
+ break;
+ default:
+ printk(KERN_WARNING
+ "Unknown info type=0x%02x\n", inf->infotype);
+ break;
}
- DBFEXIT;
return;
}
-
/*----------------------------------------------------------------
* prism2sta_ev_txexc
*
@@ -1982,15 +1860,11 @@ void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
----------------------------------------------------------------*/
void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status)
{
- DBFENTER;
-
- WLAN_LOG_DEBUG(3, "TxExc status=0x%x.\n", status);
+ pr_debug("TxExc status=0x%x.\n", status);
- DBFEXIT;
return;
}
-
/*----------------------------------------------------------------
* prism2sta_ev_tx
*
@@ -2009,15 +1883,12 @@ void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status)
----------------------------------------------------------------*/
void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status)
{
- DBFENTER;
- WLAN_LOG_DEBUG(4, "Tx Complete, status=0x%04x\n", status);
+ pr_debug("Tx Complete, status=0x%04x\n", status);
/* update linux network stats */
wlandev->linux_stats.tx_packets++;
- DBFEXIT;
return;
}
-
/*----------------------------------------------------------------
* prism2sta_ev_rx
*
@@ -2036,11 +1907,7 @@ void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status)
----------------------------------------------------------------*/
void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
{
- DBFENTER;
-
p80211netdev_rx(wlandev, skb);
-
- DBFEXIT;
return;
}
@@ -2062,11 +1929,7 @@ void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
----------------------------------------------------------------*/
void prism2sta_ev_alloc(wlandevice_t *wlandev)
{
- DBFENTER;
-
netif_wake_queue(wlandev->netdev);
-
- DBFEXIT;
return;
}
@@ -2091,17 +1954,17 @@ void prism2sta_ev_alloc(wlandevice_t *wlandev)
----------------------------------------------------------------*/
static wlandevice_t *create_wlan(void)
{
- wlandevice_t *wlandev = NULL;
- hfa384x_t *hw = NULL;
+ 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);
+ /* 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);
+ printk(KERN_ERR "%s: Memory allocation failure.\n", dev_info);
+ kfree(wlandev);
+ kfree(hw);
return NULL;
}
@@ -2121,24 +1984,21 @@ static wlandevice_t *create_wlan(void)
wlandev->set_multicast_list = prism2sta_setmulticast;
wlandev->tx_timeout = hfa384x_tx_timeout;
- wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT |
- P80211_NSDCAP_AUTOJOIN;
+ wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT | P80211_NSDCAP_AUTOJOIN;
/* Initialize the device private data stucture. */
- hw->dot11_desired_bss_type = 1;
+ hw->dot11_desired_bss_type = 1;
return wlandev;
}
void prism2sta_commsqual_defer(struct work_struct *data)
{
- hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh);
- wlandevice_t *wlandev = hw->wlandev;
+ 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;
@@ -2155,58 +2015,49 @@ void prism2sta_commsqual_defer(struct work_struct *data)
HFA384x_RID_DBMCOMMSQUALITY_LEN);
if (result) {
- WLAN_LOG_ERROR("error fetching commsqual\n");
+ printk(KERN_ERR "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));
+ pr_debug("commsqual %d %d %d\n",
+ le16_to_cpu(hw->qual.CQ_currBSS),
+ le16_to_cpu(hw->qual.ASL_currBSS),
+ le16_to_cpu(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);
+ if (result) {
+ printk(KERN_DEBUG
+ "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);
+ if (result) {
+ printk(KERN_DEBUG
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTSSID, result);
goto done;
}
prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
- (p80211pstrd_t *) &wlandev->ssid);
-
+ (p80211pstrd_t *)&wlandev->ssid);
/* Reschedule timer */
mod_timer(&hw->commsqual_timer, jiffies + HZ);
- done:
- DBFEXIT;
+done:
+ ;
}
void prism2sta_commsqual_timer(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t *) data;
-
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) data;
schedule_work(&hw->commsqual_bh);
-
- DBFEXIT;
}
diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c
index 8f7b1f281f0..d8a12982135 100644
--- a/drivers/staging/wlan-ng/prism2usb.c
+++ b/drivers/staging/wlan-ng/prism2usb.c
@@ -11,44 +11,70 @@ 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
+ (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
+ (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(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
+ (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
+ (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
+ (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)")},
+ {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 */ }
};
@@ -75,29 +101,26 @@ MODULE_DEVICE_TABLE(usb, usb_prism_tbl);
* I'm not sure, assume it's interrupt.
*
----------------------------------------------------------------*/
-static int prism2sta_probe_usb(
- struct usb_interface *interface,
- const struct usb_device_id *id)
+static int prism2sta_probe_usb(struct usb_interface *interface,
+ const struct usb_device_id *id)
{
struct usb_device *dev;
- wlandevice_t *wlandev = NULL;
- hfa384x_t *hw = NULL;
- int result = 0;
-
- DBFENTER;
+ wlandevice_t *wlandev = NULL;
+ hfa384x_t *hw = NULL;
+ int result = 0;
dev = interface_to_usbdev(interface);
if ((wlandev = create_wlan()) == NULL) {
- WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+ printk(KERN_ERR "%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);
+ if (wlan_setup(wlandev) != 0) {
+ printk(KERN_ERR "%s: wlan_setup() failed.\n", dev_info);
result = -EIO;
goto failed;
}
@@ -114,15 +137,14 @@ static int prism2sta_probe_usb(
/* Do a chip-level reset on the MAC */
if (prism2_doreset) {
result = hfa384x_corereset(hw,
- prism2_reset_holdtime,
- prism2_reset_settletime, 0);
+ 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);
+ printk(KERN_ERR
+ "%s: hfa384x_corereset() failed.\n", dev_info);
goto failed;
}
}
@@ -131,30 +153,28 @@ static int prism2sta_probe_usb(
wlandev->msdstate = WLAN_MSD_HWPRESENT;
- if ( register_wlandev(wlandev) != 0 ) {
- WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
+ if (register_wlandev(wlandev) != 0) {
+ printk(KERN_ERR "%s: register_wlandev() failed.\n", dev_info);
result = -EIO;
goto failed;
- }
+ }
/* enable the card */
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable);
goto done;
- failed:
- if (wlandev) kfree(wlandev);
- if (hw) kfree(hw);
+failed:
+ kfree(wlandev);
+ kfree(hw);
wlandev = NULL;
- done:
- DBFEXIT;
-
+done:
+ p80211_allow_ioctls(wlandev);
usb_set_intfdata(interface, wlandev);
return result;
}
-
/*----------------------------------------------------------------
* prism2sta_disconnect_usb
*
@@ -174,22 +194,19 @@ static int prism2sta_probe_usb(
* Call context:
* process
----------------------------------------------------------------*/
-static void
-prism2sta_disconnect_usb(struct usb_interface *interface)
+static void prism2sta_disconnect_usb(struct usb_interface *interface)
{
- wlandevice_t *wlandev;
-
- DBFENTER;
+ wlandevice_t *wlandev;
wlandev = (wlandevice_t *) usb_get_intfdata(interface);
- if ( wlandev != NULL ) {
+ if (wlandev != NULL) {
LIST_HEAD(cleanlist);
- struct list_head *entry;
- struct list_head *temp;
- unsigned long flags;
+ struct list_head *entry;
+ struct list_head *temp;
+ unsigned long flags;
- hfa384x_t *hw = wlandev->priv;
+ hfa384x_t *hw = wlandev->priv;
if (!hw)
goto exit;
@@ -231,7 +248,7 @@ prism2sta_disconnect_usb(struct usb_interface *interface)
* responses that we have shut down.
*/
list_for_each(entry, &cleanlist) {
- hfa384x_usbctlx_t *ctlx;
+ hfa384x_usbctlx_t *ctlx;
ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
complete(&ctlx->done);
@@ -264,13 +281,10 @@ prism2sta_disconnect_usb(struct usb_interface *interface)
kfree(wlandev);
}
- exit:
-
+exit:
usb_set_intfdata(interface, NULL);
- DBFEXIT;
}
-
static struct usb_driver prism2_usb_driver = {
.name = "prism2_usb",
.probe = prism2sta_probe_usb,
@@ -281,21 +295,13 @@ static struct usb_driver prism2_usb_driver = {
static int __init prism2usb_init(void)
{
- DBFENTER;
-
/* 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);
-
- DBFEXIT;
};
module_init(prism2usb_init);
diff --git a/drivers/staging/wlan-ng/wlan_compat.h b/drivers/staging/wlan-ng/wlan_compat.h
deleted file mode 100644
index 8b8a510685c..00000000000
--- a/drivers/staging/wlan-ng/wlan_compat.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* 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
-
-/*=============================================================*/
-/*------ 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
-
-/*=============================================================*/
-/*------ Compiler Portability Macros --------------------------*/
-/*=============================================================*/
-#define __WLAN_ATTRIB_PACK__ __attribute__ ((packed))
-
-/*=============================================================*/
-/*------ OS Portability Macros --------------------------------*/
-/*=============================================================*/
-
-#ifndef WLAN_DBVAR
-#define WLAN_DBVAR wlan_debug
-#endif
-
-#define WLAN_RELEASE "0.3.0-lkml"
-
-#include <linux/hardirq.h>
-
-#define WLAN_LOG_ERROR(x,args...) printk(KERN_ERR "%s: " x , __func__ , ##args);
-
-#define WLAN_LOG_WARNING(x,args...) printk(KERN_WARNING "%s: " x , __func__ , ##args);
-
-#define WLAN_LOG_NOTICE(x,args...) printk(KERN_NOTICE "%s: " x , __func__ , ##args);
-
-#define WLAN_LOG_INFO(args... ) printk(KERN_INFO args)
-
-#if defined(WLAN_INCLUDE_DEBUG)
- #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", ((u8*)(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 , __func__, (preempt_count() & PREEMPT_MASK), ##args );
-#else
- #define WLAN_HEX_DUMP( l, s, p, n)
- #define DBFENTER
- #define DBFEXIT
-
- #define WLAN_LOG_DEBUG(l, s, args...)
-#endif
-
-#undef netdevice_t
-typedef struct net_device netdevice_t;
-
-#define URB_ASYNC_UNLINK 0
-#define USB_QUEUE_BULK 0
-
-/*=============================================================*/
-/*------ 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)
-
-/*=============================================================*/
-/*--- 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/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 8171ca17b93..d0b093b66ad 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -30,6 +30,7 @@
#include <linux/idr.h>
#include <linux/thermal.h>
#include <linux/spinlock.h>
+#include <linux/reboot.h>
MODULE_AUTHOR("Zhang Rui");
MODULE_DESCRIPTION("Generic thermal management sysfs support");
@@ -104,22 +105,36 @@ static ssize_t
temp_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
+ long temperature;
+ int ret;
if (!tz->ops->get_temp)
return -EPERM;
- return tz->ops->get_temp(tz, buf);
+ ret = tz->ops->get_temp(tz, &temperature);
+
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "%ld\n", temperature);
}
static ssize_t
mode_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
+ enum thermal_device_mode mode;
+ int result;
if (!tz->ops->get_mode)
return -EPERM;
- return tz->ops->get_mode(tz, buf);
+ result = tz->ops->get_mode(tz, &mode);
+ if (result)
+ return result;
+
+ return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled"
+ : "disabled");
}
static ssize_t
@@ -132,7 +147,13 @@ mode_store(struct device *dev, struct device_attribute *attr,
if (!tz->ops->set_mode)
return -EPERM;
- result = tz->ops->set_mode(tz, buf);
+ if (!strncmp(buf, "enabled", sizeof("enabled")))
+ result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
+ else if (!strncmp(buf, "disabled", sizeof("disabled")))
+ result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
+ else
+ result = -EINVAL;
+
if (result)
return result;
@@ -144,7 +165,8 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
- int trip;
+ enum thermal_trip_type type;
+ int trip, result;
if (!tz->ops->get_trip_type)
return -EPERM;
@@ -152,7 +174,22 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip))
return -EINVAL;
- return tz->ops->get_trip_type(tz, trip, buf);
+ result = tz->ops->get_trip_type(tz, trip, &type);
+ if (result)
+ return result;
+
+ switch (type) {
+ case THERMAL_TRIP_CRITICAL:
+ return sprintf(buf, "critical");
+ case THERMAL_TRIP_HOT:
+ return sprintf(buf, "hot");
+ case THERMAL_TRIP_PASSIVE:
+ return sprintf(buf, "passive");
+ case THERMAL_TRIP_ACTIVE:
+ return sprintf(buf, "active");
+ default:
+ return sprintf(buf, "unknown");
+ }
}
static ssize_t
@@ -160,7 +197,8 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
- int trip;
+ int trip, ret;
+ long temperature;
if (!tz->ops->get_trip_temp)
return -EPERM;
@@ -168,12 +206,77 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip))
return -EINVAL;
- return tz->ops->get_trip_temp(tz, trip, buf);
+ ret = tz->ops->get_trip_temp(tz, trip, &temperature);
+
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "%ld\n", temperature);
+}
+
+static ssize_t
+passive_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct thermal_zone_device *tz = to_thermal_zone(dev);
+ struct thermal_cooling_device *cdev = NULL;
+ int state;
+
+ if (!sscanf(buf, "%d\n", &state))
+ return -EINVAL;
+
+ if (state && !tz->forced_passive) {
+ mutex_lock(&thermal_list_lock);
+ list_for_each_entry(cdev, &thermal_cdev_list, node) {
+ if (!strncmp("Processor", cdev->type,
+ sizeof("Processor")))
+ thermal_zone_bind_cooling_device(tz,
+ THERMAL_TRIPS_NONE,
+ cdev);
+ }
+ mutex_unlock(&thermal_list_lock);
+ } else if (!state && tz->forced_passive) {
+ mutex_lock(&thermal_list_lock);
+ list_for_each_entry(cdev, &thermal_cdev_list, node) {
+ if (!strncmp("Processor", cdev->type,
+ sizeof("Processor")))
+ thermal_zone_unbind_cooling_device(tz,
+ THERMAL_TRIPS_NONE,
+ cdev);
+ }
+ mutex_unlock(&thermal_list_lock);
+ }
+
+ tz->tc1 = 1;
+ tz->tc2 = 1;
+
+ if (!tz->passive_delay)
+ tz->passive_delay = 1000;
+
+ if (!tz->polling_delay)
+ tz->polling_delay = 10000;
+
+ tz->forced_passive = state;
+
+ thermal_zone_device_update(tz);
+
+ return count;
+}
+
+static ssize_t
+passive_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct thermal_zone_device *tz = to_thermal_zone(dev);
+
+ return sprintf(buf, "%d\n", tz->forced_passive);
}
static DEVICE_ATTR(type, 0444, type_show, NULL);
static DEVICE_ATTR(temp, 0444, temp_show, NULL);
static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
+static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \
+ passive_store);
static struct device_attribute trip_point_attrs[] = {
__ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL),
@@ -236,8 +339,13 @@ thermal_cooling_device_max_state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct thermal_cooling_device *cdev = to_cooling_device(dev);
+ unsigned long state;
+ int ret;
- return cdev->ops->get_max_state(cdev, buf);
+ ret = cdev->ops->get_max_state(cdev, &state);
+ if (ret)
+ return ret;
+ return sprintf(buf, "%ld\n", state);
}
static ssize_t
@@ -245,8 +353,13 @@ thermal_cooling_device_cur_state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct thermal_cooling_device *cdev = to_cooling_device(dev);
+ unsigned long state;
+ int ret;
- return cdev->ops->get_cur_state(cdev, buf);
+ ret = cdev->ops->get_cur_state(cdev, &state);
+ if (ret)
+ return ret;
+ return sprintf(buf, "%ld\n", state);
}
static ssize_t
@@ -255,10 +368,10 @@ thermal_cooling_device_cur_state_store(struct device *dev,
const char *buf, size_t count)
{
struct thermal_cooling_device *cdev = to_cooling_device(dev);
- int state;
+ unsigned long state;
int result;
- if (!sscanf(buf, "%d\n", &state))
+ if (!sscanf(buf, "%ld\n", &state))
return -EINVAL;
if (state < 0)
@@ -312,13 +425,20 @@ static DEVICE_ATTR(name, 0444, name_show, NULL);
static ssize_t
temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
{
+ long temperature;
+ int ret;
struct thermal_hwmon_attr *hwmon_attr
= container_of(attr, struct thermal_hwmon_attr, attr);
struct thermal_zone_device *tz
= container_of(hwmon_attr, struct thermal_zone_device,
temp_input);
- return tz->ops->get_temp(tz, buf);
+ ret = tz->ops->get_temp(tz, &temperature);
+
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "%ld\n", temperature);
}
static ssize_t
@@ -330,8 +450,14 @@ temp_crit_show(struct device *dev, struct device_attribute *attr,
struct thermal_zone_device *tz
= container_of(hwmon_attr, struct thermal_zone_device,
temp_crit);
+ long temperature;
+ int ret;
+
+ ret = tz->ops->get_trip_temp(tz, 0, &temperature);
+ if (ret)
+ return ret;
- return tz->ops->get_trip_temp(tz, 0, buf);
+ return sprintf(buf, "%ld\n", temperature);
}
@@ -452,6 +578,97 @@ thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
}
#endif
+static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
+ int delay)
+{
+ cancel_delayed_work(&(tz->poll_queue));
+
+ if (!delay)
+ return;
+
+ if (delay > 1000)
+ schedule_delayed_work(&(tz->poll_queue),
+ round_jiffies(msecs_to_jiffies(delay)));
+ else
+ schedule_delayed_work(&(tz->poll_queue),
+ msecs_to_jiffies(delay));
+}
+
+static void thermal_zone_device_passive(struct thermal_zone_device *tz,
+ int temp, int trip_temp, int trip)
+{
+ int trend = 0;
+ struct thermal_cooling_device_instance *instance;
+ struct thermal_cooling_device *cdev;
+ long state, max_state;
+
+ /*
+ * Above Trip?
+ * -----------
+ * Calculate the thermal trend (using the passive cooling equation)
+ * and modify the performance limit for all passive cooling devices
+ * accordingly. Note that we assume symmetry.
+ */
+ if (temp >= trip_temp) {
+ tz->passive = true;
+
+ trend = (tz->tc1 * (temp - tz->last_temperature)) +
+ (tz->tc2 * (temp - trip_temp));
+
+ /* Heating up? */
+ if (trend > 0) {
+ list_for_each_entry(instance, &tz->cooling_devices,
+ node) {
+ if (instance->trip != trip)
+ continue;
+ cdev = instance->cdev;
+ cdev->ops->get_cur_state(cdev, &state);
+ cdev->ops->get_max_state(cdev, &max_state);
+ if (state++ < max_state)
+ cdev->ops->set_cur_state(cdev, state);
+ }
+ } else if (trend < 0) { /* Cooling off? */
+ list_for_each_entry(instance, &tz->cooling_devices,
+ node) {
+ if (instance->trip != trip)
+ continue;
+ cdev = instance->cdev;
+ cdev->ops->get_cur_state(cdev, &state);
+ cdev->ops->get_max_state(cdev, &max_state);
+ if (state > 0)
+ cdev->ops->set_cur_state(cdev, --state);
+ }
+ }
+ return;
+ }
+
+ /*
+ * Below Trip?
+ * -----------
+ * Implement passive cooling hysteresis to slowly increase performance
+ * and avoid thrashing around the passive trip point. Note that we
+ * assume symmetry.
+ */
+ list_for_each_entry(instance, &tz->cooling_devices, node) {
+ if (instance->trip != trip)
+ continue;
+ cdev = instance->cdev;
+ cdev->ops->get_cur_state(cdev, &state);
+ cdev->ops->get_max_state(cdev, &max_state);
+ if (state > 0)
+ cdev->ops->set_cur_state(cdev, --state);
+ if (state == 0)
+ tz->passive = false;
+ }
+}
+
+static void thermal_zone_device_check(struct work_struct *work)
+{
+ struct thermal_zone_device *tz = container_of(work, struct
+ thermal_zone_device,
+ poll_queue.work);
+ thermal_zone_device_update(tz);
+}
/**
* thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
@@ -722,25 +939,113 @@ void thermal_cooling_device_unregister(struct
EXPORT_SYMBOL(thermal_cooling_device_unregister);
/**
+ * thermal_zone_device_update - force an update of a thermal zone's state
+ * @ttz: the thermal zone to update
+ */
+
+void thermal_zone_device_update(struct thermal_zone_device *tz)
+{
+ int count, ret = 0;
+ long temp, trip_temp;
+ enum thermal_trip_type trip_type;
+ struct thermal_cooling_device_instance *instance;
+ struct thermal_cooling_device *cdev;
+
+ mutex_lock(&tz->lock);
+
+ tz->ops->get_temp(tz, &temp);
+
+ for (count = 0; count < tz->trips; count++) {
+ tz->ops->get_trip_type(tz, count, &trip_type);
+ tz->ops->get_trip_temp(tz, count, &trip_temp);
+
+ switch (trip_type) {
+ case THERMAL_TRIP_CRITICAL:
+ if (temp > trip_temp) {
+ if (tz->ops->notify)
+ ret = tz->ops->notify(tz, count,
+ trip_type);
+ if (!ret) {
+ printk(KERN_EMERG
+ "Critical temperature reached (%ld C), shutting down.\n",
+ temp/1000);
+ orderly_poweroff(true);
+ }
+ }
+ break;
+ case THERMAL_TRIP_HOT:
+ if (temp > trip_temp)
+ if (tz->ops->notify)
+ tz->ops->notify(tz, count, trip_type);
+ break;
+ case THERMAL_TRIP_ACTIVE:
+ list_for_each_entry(instance, &tz->cooling_devices,
+ node) {
+ if (instance->trip != count)
+ continue;
+
+ cdev = instance->cdev;
+
+ if (temp > trip_temp)
+ cdev->ops->set_cur_state(cdev, 1);
+ else
+ cdev->ops->set_cur_state(cdev, 0);
+ }
+ break;
+ case THERMAL_TRIP_PASSIVE:
+ if (temp > trip_temp || tz->passive)
+ thermal_zone_device_passive(tz, temp,
+ trip_temp, count);
+ break;
+ }
+ }
+
+ if (tz->forced_passive)
+ thermal_zone_device_passive(tz, temp, tz->forced_passive,
+ THERMAL_TRIPS_NONE);
+
+ tz->last_temperature = temp;
+ if (tz->passive)
+ thermal_zone_device_set_polling(tz, tz->passive_delay);
+ else if (tz->polling_delay)
+ thermal_zone_device_set_polling(tz, tz->polling_delay);
+ mutex_unlock(&tz->lock);
+}
+EXPORT_SYMBOL(thermal_zone_device_update);
+
+/**
* thermal_zone_device_register - register a new thermal zone device
* @type: the thermal zone device type
* @trips: the number of trip points the thermal zone support
* @devdata: private device data
* @ops: standard thermal zone device callbacks
+ * @tc1: thermal coefficient 1 for passive calculations
+ * @tc2: thermal coefficient 2 for passive calculations
+ * @passive_delay: number of milliseconds to wait between polls when
+ * performing passive cooling
+ * @polling_delay: number of milliseconds to wait between polls when checking
+ * whether trip points have been crossed (0 for interrupt
+ * driven systems)
*
* thermal_zone_device_unregister() must be called when the device is no
- * longer needed.
+ * longer needed. The passive cooling formula uses tc1 and tc2 as described in
+ * section 11.1.5.1 of the ACPI specification 3.0.
*/
struct thermal_zone_device *thermal_zone_device_register(char *type,
int trips,
void *devdata, struct
thermal_zone_device_ops
- *ops)
+ *ops, int tc1, int
+ tc2,
+ int passive_delay,
+ int polling_delay)
{
struct thermal_zone_device *tz;
struct thermal_cooling_device *pos;
+ enum thermal_trip_type trip_type;
int result;
int count;
+ int passive = 0;
if (strlen(type) >= THERMAL_NAME_LENGTH)
return ERR_PTR(-EINVAL);
@@ -769,6 +1074,11 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
tz->device.class = &thermal_class;
tz->devdata = devdata;
tz->trips = trips;
+ tz->tc1 = tc1;
+ tz->tc2 = tc2;
+ tz->passive_delay = passive_delay;
+ tz->polling_delay = polling_delay;
+
dev_set_name(&tz->device, "thermal_zone%d", tz->id);
result = device_register(&tz->device);
if (result) {
@@ -798,8 +1108,18 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
TRIP_POINT_ATTR_ADD(&tz->device, count, result);
if (result)
goto unregister;
+ tz->ops->get_trip_type(tz, count, &trip_type);
+ if (trip_type == THERMAL_TRIP_PASSIVE)
+ passive = 1;
}
+ if (!passive)
+ result = device_create_file(&tz->device,
+ &dev_attr_passive);
+
+ if (result)
+ goto unregister;
+
result = thermal_add_hwmon_sysfs(tz);
if (result)
goto unregister;
@@ -814,6 +1134,10 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
}
mutex_unlock(&thermal_list_lock);
+ INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
+
+ thermal_zone_device_update(tz);
+
if (!result)
return tz;
@@ -853,6 +1177,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
tz->ops->unbind(tz, cdev);
mutex_unlock(&thermal_list_lock);
+ thermal_zone_device_set_polling(tz, 0);
+
if (tz->type[0])
device_remove_file(&tz->device, &dev_attr_type);
device_remove_file(&tz->device, &dev_attr_temp);
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index b6483dd98ac..9cf9ff69e3e 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -626,7 +626,7 @@ static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *conte
goto err_fw_corrupted;
/*
- * Start to upload formware : send reset
+ * Start to upload firmware : send reset
*/
value = 1;
ret = uea_send_modem_cmd(usb, F8051_USBCS, sizeof(value), &value);
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index b3d5a23ab56..0a69c0977e3 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -546,10 +546,6 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
tty->driver_data = acm;
acm->tty = tty;
- /* force low_latency on so that our tty_push actually forces the data through,
- otherwise it is scheduled, and with high data rates data can get lost. */
- tty->low_latency = 1;
-
if (usb_autopm_get_interface(acm->control) < 0)
goto early_bail;
else
@@ -1358,6 +1354,9 @@ static struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x079b, 0x000f), /* BT On-Air USB MODEM */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},
+ { USB_DEVICE(0x0ace, 0x1602), /* ZyDAS 56K USB MODEM */
+ .driver_info = SINGLE_RX_URB,
+ },
{ USB_DEVICE(0x0ace, 0x1608), /* ZyDAS 56K USB MODEM */
.driver_info = SINGLE_RX_URB, /* firmware bug */
},
@@ -1493,4 +1492,4 @@ module_exit(acm_exit);
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE("GPL");
-
+MODULE_ALIAS_CHARDEV_MAJOR(ACM_TTY_MAJOR);
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 770b3eaa918..080bb1e4b84 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -392,7 +392,7 @@ config USB_GADGET_FSL_QE
controllers having QE or CPM2, given minor tweaks.
Set CONFIG_USB_GADGET to "m" to build this driver as a
- dynmically linked module called "fsl_qe_udc".
+ dynamically linked module called "fsl_qe_udc".
config USB_FSL_QE
tristate
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index c22fab16411..563d5727544 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -319,7 +319,7 @@ static inline void usba_cleanup_debugfs(struct usba_udc *udc)
static int vbus_is_present(struct usba_udc *udc)
{
- if (udc->vbus_pin != -1)
+ if (gpio_is_valid(udc->vbus_pin))
return gpio_get_value(udc->vbus_pin);
/* No Vbus detection: Assume always present */
@@ -1821,7 +1821,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name);
udc->vbus_prev = 0;
- if (udc->vbus_pin != -1)
+ if (gpio_is_valid(udc->vbus_pin))
enable_irq(gpio_to_irq(udc->vbus_pin));
/* If Vbus is present, enable the controller and wait for reset */
@@ -1852,7 +1852,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
if (driver != udc->driver || !driver->unbind)
return -EINVAL;
- if (udc->vbus_pin != -1)
+ if (gpio_is_valid(udc->vbus_pin))
disable_irq(gpio_to_irq(udc->vbus_pin));
spin_lock_irqsave(&udc->lock, flags);
@@ -1910,7 +1910,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
udc->pdev = pdev;
udc->pclk = pclk;
udc->hclk = hclk;
- udc->vbus_pin = -1;
+ udc->vbus_pin = -ENODEV;
ret = -ENOMEM;
udc->regs = ioremap(regs->start, regs->end - regs->start + 1);
@@ -1996,7 +1996,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
goto err_device_add;
}
- if (pdata->vbus_pin >= 0) {
+ if (gpio_is_valid(pdata->vbus_pin)) {
if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) {
udc->vbus_pin = pdata->vbus_pin;
@@ -2005,7 +2005,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
"atmel_usba_udc", udc);
if (ret) {
gpio_free(udc->vbus_pin);
- udc->vbus_pin = -1;
+ udc->vbus_pin = -ENODEV;
dev_warn(&udc->pdev->dev,
"failed to request vbus irq; "
"assuming always on\n");
@@ -2051,7 +2051,7 @@ static int __exit usba_udc_remove(struct platform_device *pdev)
usba_ep_cleanup_debugfs(&usba_ep[i]);
usba_cleanup_debugfs(udc);
- if (udc->vbus_pin != -1)
+ if (gpio_is_valid(udc->vbus_pin))
gpio_free(udc->vbus_pin);
free_irq(udc->irq, udc);
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index f2618d17710..c637207a1c8 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -622,7 +622,7 @@ static int ehci_run (struct usb_hcd *hcd)
ehci_writel(ehci, 0, &ehci->regs->segment);
#if 0
// this is deeply broken on almost all architectures
- if (!dma_set_mask(hcd->self.controller, DMA_64BIT_MASK))
+ if (!dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)))
ehci_info(ehci, "enabled 64bit DMA\n");
#endif
}
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index abb9a7706ec..5aa8bce90e1 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -108,7 +108,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
case 0x00d8: /* CK8 */
case 0x00e8: /* CK8S */
if (pci_set_consistent_dma_mask(pdev,
- DMA_31BIT_MASK) < 0)
+ DMA_BIT_MASK(31)) < 0)
ehci_warn(ehci, "can't enable NVidia "
"workaround for >2GB RAM\n");
break;
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index 9c9da35abc6..1ba9f9a8c30 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -81,7 +81,7 @@ static int ps3_ehci_probe(struct ps3_system_bus_device *dev)
int result;
struct usb_hcd *hcd;
unsigned int virq;
- static u64 dummy_mask = DMA_32BIT_MASK;
+ static u64 dummy_mask = DMA_BIT_MASK(32);
if (usb_disabled()) {
result = -ENODEV;
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 4ed228a8994..bb5e6f67157 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -280,7 +280,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
* are always powered while this driver is active, and use
* active-low power switches.
*/
- for (i = 0; i < pdata->ports; i++) {
+ for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) {
if (pdata->vbus_pin[i] <= 0)
continue;
gpio_request(pdata->vbus_pin[i], "ohci_vbus");
@@ -298,7 +298,7 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
int i;
if (pdata) {
- for (i = 0; i < pdata->ports; i++) {
+ for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) {
if (pdata->vbus_pin[i] <= 0)
continue;
gpio_direction_output(pdata->vbus_pin[i], 1);
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index 3c1a3b5f89f..3d191031732 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -80,7 +80,7 @@ static int ps3_ohci_probe(struct ps3_system_bus_device *dev)
int result;
struct usb_hcd *hcd;
unsigned int virq;
- static u64 dummy_mask = DMA_32BIT_MASK;
+ static u64 dummy_mask = DMA_BIT_MASK(32);
if (usb_disabled()) {
result = -ENODEV;
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c
index 4b933f646f2..c567168f89a 100644
--- a/drivers/usb/otg/nop-usb-xceiv.c
+++ b/drivers/usb/otg/nop-usb-xceiv.c
@@ -36,14 +36,14 @@ struct nop_usb_xceiv {
struct device *dev;
};
-static u64 nop_xceiv_dmamask = DMA_32BIT_MASK;
+static u64 nop_xceiv_dmamask = DMA_BIT_MASK(32);
static struct platform_device nop_xceiv_device = {
.name = "nop_usb_xceiv",
.id = -1,
.dev = {
.dma_mask = &nop_xceiv_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = NULL,
},
};
diff --git a/drivers/usb/serial/ChangeLog.history b/drivers/usb/serial/ChangeLog.history
index c1b279939bb..f13fd488ebe 100644
--- a/drivers/usb/serial/ChangeLog.history
+++ b/drivers/usb/serial/ChangeLog.history
@@ -715,7 +715,7 @@ io_edgeport.c Change Log comments:
0.2 (01/30/2000) greg kroah-hartman
Milestone 1 release.
- Device is found by USB subsystem, enumerated, fimware is downloaded
+ Device is found by USB subsystem, enumerated, firmware is downloaded
and the descriptors are printed to the debug log, config is set, and
green light starts to blink. Open port works, and data can be sent
and received at the default settings of the UART. Loopback connector
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index a65f9196b0a..c480ea4c19f 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -518,8 +518,8 @@ config USB_SERIAL_SIERRAWIRELESS
help
Say M here if you want to use Sierra Wireless devices.
- Many deviecs have a feature known as TRU-Install, for those devices
- to work properly the USB Storage Sierra feature must be enabled.
+ Many devices have a feature known as TRU-Install. For those devices
+ to work properly, the USB Storage Sierra feature must be enabled.
To compile this driver as a module, choose M here: the
module will be called sierra.
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 1aed584be5e..751a533a434 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -79,6 +79,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_EF81) },
+ { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_ID_S81) }, /* Benq/Siemens S81 */
{ USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) },
{ USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) },
{ USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) },
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index 54974f446a8..1d7a22e3a9f 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -7,6 +7,10 @@
* (at your option) any later version.
*
*/
+
+#define BENQ_VENDOR_ID 0x04a5
+#define BENQ_PRODUCT_ID_S81 0x4027
+
#define PL2303_VENDOR_ID 0x067b
#define PL2303_PRODUCT_ID 0x2303
#define PL2303_PRODUCT_ID_RSAQ2 0x04bb
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
index 8b3cbc87adc..69879e43794 100644
--- a/drivers/usb/serial/symbolserial.c
+++ b/drivers/usb/serial/symbolserial.c
@@ -139,14 +139,6 @@ static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port,
priv->port = port;
spin_unlock_irqrestore(&priv->lock, flags);
- /*
- * Force low_latency on so that our tty_push actually forces the data
- * through, otherwise it is scheduled, and with high data rates (like
- * with OHCI) data can get lost.
- */
- if (tty)
- tty->low_latency = 1;
-
/* Start reading from the device */
usb_fill_int_urb(priv->int_urb, priv->udev,
usb_rcvintpipe(priv->udev, priv->int_address),
@@ -205,62 +197,6 @@ static void symbol_unthrottle(struct tty_struct *tty)
__func__, result);
}
-static int symbol_ioctl(struct tty_struct *tty, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct device *dev = &port->dev;
-
- /*
- * Right now we need to figure out what commands
- * most userspace tools want to see for this driver,
- * so just log the things.
- */
- switch (cmd) {
- case TIOCSERGETLSR:
- dev_info(dev, "%s: TIOCSERGETLSR\n", __func__);
- break;
-
- case TIOCGSERIAL:
- dev_info(dev, "%s: TIOCGSERIAL\n", __func__);
- break;
-
- case TIOCMIWAIT:
- dev_info(dev, "%s: TIOCMIWAIT\n", __func__);
- break;
-
- case TIOCGICOUNT:
- dev_info(dev, "%s: TIOCGICOUNT\n", __func__);
- break;
- default:
- dev_info(dev, "%s: unknown (%d)\n", __func__, cmd);
- }
- return -ENOIOCTLCMD;
-}
-
-static int symbol_tiocmget(struct tty_struct *tty, struct file *file)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct device *dev = &port->dev;
-
- /* TODO */
- /* probably just need to shadow whatever was sent to us here */
- dev_info(dev, "%s\n", __func__);
- return 0;
-}
-
-static int symbol_tiocmset(struct tty_struct *tty, struct file *file,
- unsigned int set, unsigned int clear)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct device *dev = &port->dev;
-
- /* TODO */
- /* probably just need to shadow whatever was sent to us here */
- dev_info(dev, "%s\n", __func__);
- return 0;
-}
-
static int symbol_startup(struct usb_serial *serial)
{
struct symbol_private *priv;
@@ -367,9 +303,6 @@ static struct usb_serial_driver symbol_device = {
.shutdown = symbol_shutdown,
.throttle = symbol_throttle,
.unthrottle = symbol_unthrottle,
- .ioctl = symbol_ioctl,
- .tiocmget = symbol_tiocmget,
- .tiocmset = symbol_tiocmset,
};
static int __init symbol_init(void)
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 2620bf6fe5e..9c4c700c7cc 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -1215,20 +1215,22 @@ static void ti_bulk_in_callback(struct urb *urb)
}
tty = tty_port_tty_get(&port->port);
- if (tty && urb->actual_length) {
- usb_serial_debug_data(debug, dev, __func__,
- urb->actual_length, urb->transfer_buffer);
-
- if (!tport->tp_is_open)
- dbg("%s - port closed, dropping data", __func__);
- else
- ti_recv(&urb->dev->dev, tty,
+ if (tty) {
+ if (urb->actual_length) {
+ usb_serial_debug_data(debug, dev, __func__,
+ urb->actual_length, urb->transfer_buffer);
+
+ if (!tport->tp_is_open)
+ dbg("%s - port closed, dropping data",
+ __func__);
+ else
+ ti_recv(&urb->dev->dev, tty,
urb->transfer_buffer,
urb->actual_length);
-
- spin_lock(&tport->tp_lock);
- tport->tp_icount.rx += urb->actual_length;
- spin_unlock(&tport->tp_lock);
+ spin_lock(&tport->tp_lock);
+ tport->tp_icount.rx += urb->actual_length;
+ spin_unlock(&tport->tp_lock);
+ }
tty_kref_put(tty);
}
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 882c57b399f..fdba2f69d4c 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -46,6 +46,7 @@
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/ata.h>
#include <linux/hdreg.h>
#include <linux/scatterlist.h>
@@ -328,7 +329,7 @@ struct isd200_config {
struct isd200_info {
struct inquiry_data InquiryData;
- struct hd_driveid *id;
+ u16 *id;
struct isd200_config ConfigData;
unsigned char *RegsBuf;
unsigned char ATARegs[8];
@@ -419,19 +420,19 @@ static void isd200_build_sense(struct us_data *us, struct scsi_cmnd *srb)
buf->Flags = UNIT_ATTENTION;
buf->AdditionalSenseCode = 0;
buf->AdditionalSenseCodeQualifier = 0;
- } else if(error & MCR_ERR) {
+ } else if (error & ATA_MCR) {
buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
buf->AdditionalSenseLength = 0xb;
buf->Flags = UNIT_ATTENTION;
buf->AdditionalSenseCode = 0;
buf->AdditionalSenseCodeQualifier = 0;
- } else if(error & TRK0_ERR) {
+ } else if (error & ATA_TRK0NF) {
buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
buf->AdditionalSenseLength = 0xb;
buf->Flags = NOT_READY;
buf->AdditionalSenseCode = 0;
buf->AdditionalSenseCodeQualifier = 0;
- } else if(error & ECC_ERR) {
+ } else if (error & ATA_UNC) {
buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
buf->AdditionalSenseLength = 0xb;
buf->Flags = DATA_PROTECT;
@@ -547,16 +548,16 @@ static int isd200_action( struct us_data *us, int action,
ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_5;
ata.generic.RegisterSelect = REG_DEVICE_HEAD | REG_COMMAND;
ata.write.DeviceHeadByte = info->DeviceHead;
- ata.write.CommandByte = WIN_SRST;
+ ata.write.CommandByte = ATA_CMD_DEV_RESET;
isd200_set_srb(info, DMA_NONE, NULL, 0);
break;
case ACTION_IDENTIFY:
US_DEBUGP(" isd200_action(IDENTIFY)\n");
ata.generic.RegisterSelect = REG_COMMAND;
- ata.write.CommandByte = WIN_IDENTIFY;
+ ata.write.CommandByte = ATA_CMD_ID_ATA;
isd200_set_srb(info, DMA_FROM_DEVICE, info->id,
- sizeof(struct hd_driveid));
+ ATA_ID_WORDS * 2);
break;
default:
@@ -944,22 +945,22 @@ static int isd200_try_enum(struct us_data *us, unsigned char master_slave,
break;
if (!detect) {
- if (regs[ATA_REG_STATUS_OFFSET] & BUSY_STAT) {
+ if (regs[ATA_REG_STATUS_OFFSET] & ATA_BUSY) {
US_DEBUGP(" %s status is still BSY, try again...\n",mstr);
} else {
US_DEBUGP(" %s status !BSY, continue with next operation\n",mstr);
break;
}
}
- /* check for BUSY_STAT and */
- /* WRERR_STAT (workaround ATA Zip drive) and */
- /* ERR_STAT (workaround for Archos CD-ROM) */
+ /* check for ATA_BUSY and */
+ /* ATA_DF (workaround ATA Zip drive) and */
+ /* ATA_ERR (workaround for Archos CD-ROM) */
else if (regs[ATA_REG_STATUS_OFFSET] &
- (BUSY_STAT | WRERR_STAT | ERR_STAT )) {
+ (ATA_BUSY | ATA_DF | ATA_ERR)) {
US_DEBUGP(" Status indicates it is not ready, try again...\n");
}
/* check for DRDY, ATA devices set DRDY after SRST */
- else if (regs[ATA_REG_STATUS_OFFSET] & READY_STAT) {
+ else if (regs[ATA_REG_STATUS_OFFSET] & ATA_DRDY) {
US_DEBUGP(" Identified ATA device\n");
info->DeviceFlags |= DF_ATA_DEVICE;
info->DeviceHead = master_slave;
@@ -1053,103 +1054,50 @@ static int isd200_manual_enum(struct us_data *us)
return(retStatus);
}
-static void isd200_fix_driveid (struct hd_driveid *id)
+static void isd200_fix_driveid(u16 *id)
{
#ifndef __LITTLE_ENDIAN
# ifdef __BIG_ENDIAN
int i;
- u16 *stringcast;
-
- id->config = __le16_to_cpu(id->config);
- id->cyls = __le16_to_cpu(id->cyls);
- id->reserved2 = __le16_to_cpu(id->reserved2);
- id->heads = __le16_to_cpu(id->heads);
- id->track_bytes = __le16_to_cpu(id->track_bytes);
- id->sector_bytes = __le16_to_cpu(id->sector_bytes);
- id->sectors = __le16_to_cpu(id->sectors);
- id->vendor0 = __le16_to_cpu(id->vendor0);
- id->vendor1 = __le16_to_cpu(id->vendor1);
- id->vendor2 = __le16_to_cpu(id->vendor2);
- stringcast = (u16 *)&id->serial_no[0];
- for (i = 0; i < (20/2); i++)
- stringcast[i] = __le16_to_cpu(stringcast[i]);
- id->buf_type = __le16_to_cpu(id->buf_type);
- id->buf_size = __le16_to_cpu(id->buf_size);
- id->ecc_bytes = __le16_to_cpu(id->ecc_bytes);
- stringcast = (u16 *)&id->fw_rev[0];
- for (i = 0; i < (8/2); i++)
- stringcast[i] = __le16_to_cpu(stringcast[i]);
- stringcast = (u16 *)&id->model[0];
- for (i = 0; i < (40/2); i++)
- stringcast[i] = __le16_to_cpu(stringcast[i]);
- id->dword_io = __le16_to_cpu(id->dword_io);
- id->reserved50 = __le16_to_cpu(id->reserved50);
- id->field_valid = __le16_to_cpu(id->field_valid);
- id->cur_cyls = __le16_to_cpu(id->cur_cyls);
- id->cur_heads = __le16_to_cpu(id->cur_heads);
- id->cur_sectors = __le16_to_cpu(id->cur_sectors);
- id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0);
- id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1);
- id->lba_capacity = __le32_to_cpu(id->lba_capacity);
- id->dma_1word = __le16_to_cpu(id->dma_1word);
- id->dma_mword = __le16_to_cpu(id->dma_mword);
- id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
- id->eide_dma_min = __le16_to_cpu(id->eide_dma_min);
- id->eide_dma_time = __le16_to_cpu(id->eide_dma_time);
- id->eide_pio = __le16_to_cpu(id->eide_pio);
- id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
- for (i = 0; i < 2; ++i)
- id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
- for (i = 0; i < 4; ++i)
- id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
- id->queue_depth = __le16_to_cpu(id->queue_depth);
- for (i = 0; i < 4; ++i)
- id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
- id->major_rev_num = __le16_to_cpu(id->major_rev_num);
- id->minor_rev_num = __le16_to_cpu(id->minor_rev_num);
- id->command_set_1 = __le16_to_cpu(id->command_set_1);
- id->command_set_2 = __le16_to_cpu(id->command_set_2);
- id->cfsse = __le16_to_cpu(id->cfsse);
- id->cfs_enable_1 = __le16_to_cpu(id->cfs_enable_1);
- id->cfs_enable_2 = __le16_to_cpu(id->cfs_enable_2);
- id->csf_default = __le16_to_cpu(id->csf_default);
- id->dma_ultra = __le16_to_cpu(id->dma_ultra);
- id->trseuc = __le16_to_cpu(id->trseuc);
- id->trsEuc = __le16_to_cpu(id->trsEuc);
- id->CurAPMvalues = __le16_to_cpu(id->CurAPMvalues);
- id->mprc = __le16_to_cpu(id->mprc);
- id->hw_config = __le16_to_cpu(id->hw_config);
- id->acoustic = __le16_to_cpu(id->acoustic);
- id->msrqs = __le16_to_cpu(id->msrqs);
- id->sxfert = __le16_to_cpu(id->sxfert);
- id->sal = __le16_to_cpu(id->sal);
- id->spg = __le32_to_cpu(id->spg);
- id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
- for (i = 0; i < 22; i++)
- id->words104_125[i] = __le16_to_cpu(id->words104_125[i]);
- id->last_lun = __le16_to_cpu(id->last_lun);
- id->word127 = __le16_to_cpu(id->word127);
- id->dlf = __le16_to_cpu(id->dlf);
- id->csfo = __le16_to_cpu(id->csfo);
- for (i = 0; i < 26; i++)
- id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
- id->word156 = __le16_to_cpu(id->word156);
- for (i = 0; i < 3; i++)
- id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
- id->cfa_power = __le16_to_cpu(id->cfa_power);
- for (i = 0; i < 14; i++)
- id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
- for (i = 0; i < 31; i++)
- id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
- for (i = 0; i < 48; i++)
- id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
- id->integrity_word = __le16_to_cpu(id->integrity_word);
+
+ for (i = 0; i < ATA_ID_WORDS; i++)
+ id[i] = __le16_to_cpu(id[i]);
# else
# error "Please fix <asm/byteorder.h>"
# endif
#endif
}
+static void isd200_dump_driveid(u16 *id)
+{
+ US_DEBUGP(" Identify Data Structure:\n");
+ US_DEBUGP(" config = 0x%x\n", id[ATA_ID_CONFIG]);
+ US_DEBUGP(" cyls = 0x%x\n", id[ATA_ID_CYLS]);
+ US_DEBUGP(" heads = 0x%x\n", id[ATA_ID_HEADS]);
+ US_DEBUGP(" track_bytes = 0x%x\n", id[4]);
+ US_DEBUGP(" sector_bytes = 0x%x\n", id[5]);
+ US_DEBUGP(" sectors = 0x%x\n", id[ATA_ID_SECTORS]);
+ US_DEBUGP(" serial_no[0] = 0x%x\n", *(char *)&id[ATA_ID_SERNO]);
+ US_DEBUGP(" buf_type = 0x%x\n", id[20]);
+ US_DEBUGP(" buf_size = 0x%x\n", id[ATA_ID_BUF_SIZE]);
+ US_DEBUGP(" ecc_bytes = 0x%x\n", id[22]);
+ US_DEBUGP(" fw_rev[0] = 0x%x\n", *(char *)&id[ATA_ID_FW_REV]);
+ US_DEBUGP(" model[0] = 0x%x\n", *(char *)&id[ATA_ID_PROD]);
+ US_DEBUGP(" max_multsect = 0x%x\n", id[ATA_ID_MAX_MULTSECT] & 0xff);
+ US_DEBUGP(" dword_io = 0x%x\n", id[ATA_ID_DWORD_IO]);
+ US_DEBUGP(" capability = 0x%x\n", id[ATA_ID_CAPABILITY] >> 8);
+ US_DEBUGP(" tPIO = 0x%x\n", id[ATA_ID_OLD_PIO_MODES] >> 8);
+ US_DEBUGP(" tDMA = 0x%x\n", id[ATA_ID_OLD_DMA_MODES] >> 8);
+ US_DEBUGP(" field_valid = 0x%x\n", id[ATA_ID_FIELD_VALID]);
+ US_DEBUGP(" cur_cyls = 0x%x\n", id[ATA_ID_CUR_CYLS]);
+ US_DEBUGP(" cur_heads = 0x%x\n", id[ATA_ID_CUR_HEADS]);
+ US_DEBUGP(" cur_sectors = 0x%x\n", id[ATA_ID_CUR_SECTORS]);
+ US_DEBUGP(" cur_capacity = 0x%x\n", ata_id_u32(id, 57));
+ US_DEBUGP(" multsect = 0x%x\n", id[ATA_ID_MULTSECT] & 0xff);
+ US_DEBUGP(" lba_capacity = 0x%x\n", ata_id_u32(id, ATA_ID_LBA_CAPACITY));
+ US_DEBUGP(" command_set_1 = 0x%x\n", id[ATA_ID_COMMAND_SET_1]);
+ US_DEBUGP(" command_set_2 = 0x%x\n", id[ATA_ID_COMMAND_SET_2]);
+}
/**************************************************************************
* isd200_get_inquiry_data
@@ -1163,7 +1111,7 @@ static int isd200_get_inquiry_data( struct us_data *us )
{
struct isd200_info *info = (struct isd200_info *)us->extra;
int retStatus = ISD200_GOOD;
- struct hd_driveid *id = info->id;
+ u16 *id = info->id;
US_DEBUGP("Entering isd200_get_inquiry_data\n");
@@ -1180,8 +1128,7 @@ static int isd200_get_inquiry_data( struct us_data *us )
/* this must be an ATA device */
/* perform an ATA Command Identify */
transferStatus = isd200_action( us, ACTION_IDENTIFY,
- id,
- sizeof(struct hd_driveid) );
+ id, ATA_ID_WORDS * 2);
if (transferStatus != ISD200_TRANSPORT_GOOD) {
/* Error issuing ATA Command Identify */
US_DEBUGP(" Error issuing ATA Command Identify\n");
@@ -1191,35 +1138,9 @@ static int isd200_get_inquiry_data( struct us_data *us )
int i;
__be16 *src;
__u16 *dest;
- isd200_fix_driveid(id);
- US_DEBUGP(" Identify Data Structure:\n");
- US_DEBUGP(" config = 0x%x\n", id->config);
- US_DEBUGP(" cyls = 0x%x\n", id->cyls);
- US_DEBUGP(" heads = 0x%x\n", id->heads);
- US_DEBUGP(" track_bytes = 0x%x\n", id->track_bytes);
- US_DEBUGP(" sector_bytes = 0x%x\n", id->sector_bytes);
- US_DEBUGP(" sectors = 0x%x\n", id->sectors);
- US_DEBUGP(" serial_no[0] = 0x%x\n", id->serial_no[0]);
- US_DEBUGP(" buf_type = 0x%x\n", id->buf_type);
- US_DEBUGP(" buf_size = 0x%x\n", id->buf_size);
- US_DEBUGP(" ecc_bytes = 0x%x\n", id->ecc_bytes);
- US_DEBUGP(" fw_rev[0] = 0x%x\n", id->fw_rev[0]);
- US_DEBUGP(" model[0] = 0x%x\n", id->model[0]);
- US_DEBUGP(" max_multsect = 0x%x\n", id->max_multsect);
- US_DEBUGP(" dword_io = 0x%x\n", id->dword_io);
- US_DEBUGP(" capability = 0x%x\n", id->capability);
- US_DEBUGP(" tPIO = 0x%x\n", id->tPIO);
- US_DEBUGP(" tDMA = 0x%x\n", id->tDMA);
- US_DEBUGP(" field_valid = 0x%x\n", id->field_valid);
- US_DEBUGP(" cur_cyls = 0x%x\n", id->cur_cyls);
- US_DEBUGP(" cur_heads = 0x%x\n", id->cur_heads);
- US_DEBUGP(" cur_sectors = 0x%x\n", id->cur_sectors);
- US_DEBUGP(" cur_capacity = 0x%x\n", (id->cur_capacity1 << 16) + id->cur_capacity0 );
- US_DEBUGP(" multsect = 0x%x\n", id->multsect);
- US_DEBUGP(" lba_capacity = 0x%x\n", id->lba_capacity);
- US_DEBUGP(" command_set_1 = 0x%x\n", id->command_set_1);
- US_DEBUGP(" command_set_2 = 0x%x\n", id->command_set_2);
+ isd200_fix_driveid(id);
+ isd200_dump_driveid(id);
memset(&info->InquiryData, 0, sizeof(info->InquiryData));
@@ -1229,30 +1150,30 @@ static int isd200_get_inquiry_data( struct us_data *us )
/* The length must be at least 36 (5 + 31) */
info->InquiryData.AdditionalLength = 0x1F;
- if (id->command_set_1 & COMMANDSET_MEDIA_STATUS) {
+ if (id[ATA_ID_COMMAND_SET_1] & COMMANDSET_MEDIA_STATUS) {
/* set the removable bit */
info->InquiryData.DeviceTypeModifier = DEVICE_REMOVABLE;
info->DeviceFlags |= DF_REMOVABLE_MEDIA;
}
/* Fill in vendor identification fields */
- src = (__be16*)id->model;
+ src = (__be16 *)&id[ATA_ID_PROD];
dest = (__u16*)info->InquiryData.VendorId;
for (i=0;i<4;i++)
dest[i] = be16_to_cpu(src[i]);
- src = (__be16*)(id->model+8);
+ src = (__be16 *)&id[ATA_ID_PROD + 8/2];
dest = (__u16*)info->InquiryData.ProductId;
for (i=0;i<8;i++)
dest[i] = be16_to_cpu(src[i]);
- src = (__be16*)id->fw_rev;
+ src = (__be16 *)&id[ATA_ID_FW_REV];
dest = (__u16*)info->InquiryData.ProductRevisionLevel;
for (i=0;i<2;i++)
dest[i] = be16_to_cpu(src[i]);
/* determine if it supports Media Status Notification */
- if (id->command_set_2 & COMMANDSET_MEDIA_STATUS) {
+ if (id[ATA_ID_COMMAND_SET_2] & COMMANDSET_MEDIA_STATUS) {
US_DEBUGP(" Device supports Media Status Notification\n");
/* Indicate that it is enabled, even though it is not
@@ -1301,7 +1222,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
union ata_cdb * ataCdb)
{
struct isd200_info *info = (struct isd200_info *)us->extra;
- struct hd_driveid *id = info->id;
+ u16 *id = info->id;
int sendToTransport = 1;
unsigned char sectnum, head;
unsigned short cylinder;
@@ -1369,13 +1290,12 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
US_DEBUGP(" ATA OUT - SCSIOP_READ_CAPACITY\n");
- if (id->capability & CAPABILITY_LBA ) {
- capacity = id->lba_capacity - 1;
- } else {
- capacity = (id->heads *
- id->cyls *
- id->sectors) - 1;
- }
+ if (ata_id_has_lba(id))
+ capacity = ata_id_u32(id, ATA_ID_LBA_CAPACITY) - 1;
+ else
+ capacity = (id[ATA_ID_HEADS] * id[ATA_ID_CYLS] *
+ id[ATA_ID_SECTORS]) - 1;
+
readCapacityData.LogicalBlockAddress = cpu_to_be32(capacity);
readCapacityData.BytesPerBlock = cpu_to_be32(0x200);
@@ -1392,16 +1312,16 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
lba = be32_to_cpu(*(__be32 *)&srb->cmnd[2]);
blockCount = (unsigned long)srb->cmnd[7]<<8 | (unsigned long)srb->cmnd[8];
- if (id->capability & CAPABILITY_LBA) {
+ if (ata_id_has_lba(id)) {
sectnum = (unsigned char)(lba);
cylinder = (unsigned short)(lba>>8);
head = ATA_ADDRESS_DEVHEAD_LBA_MODE | (unsigned char)(lba>>24 & 0x0F);
} else {
- sectnum = (unsigned char)((lba % id->sectors) + 1);
- cylinder = (unsigned short)(lba / (id->sectors *
- id->heads));
- head = (unsigned char)((lba / id->sectors) %
- id->heads);
+ sectnum = (u8)((lba % id[ATA_ID_SECTORS]) + 1);
+ cylinder = (u16)(lba / (id[ATA_ID_SECTORS] *
+ id[ATA_ID_HEADS]));
+ head = (u8)((lba / id[ATA_ID_SECTORS]) %
+ id[ATA_ID_HEADS]);
}
ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
@@ -1415,7 +1335,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
ataCdb->write.CylinderHighByte = (unsigned char)(cylinder>>8);
ataCdb->write.CylinderLowByte = (unsigned char)cylinder;
ataCdb->write.DeviceHeadByte = (head | ATA_ADDRESS_DEVHEAD_STD);
- ataCdb->write.CommandByte = WIN_READ;
+ ataCdb->write.CommandByte = ATA_CMD_PIO_READ;
break;
case WRITE_10:
@@ -1424,14 +1344,16 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
lba = be32_to_cpu(*(__be32 *)&srb->cmnd[2]);
blockCount = (unsigned long)srb->cmnd[7]<<8 | (unsigned long)srb->cmnd[8];
- if (id->capability & CAPABILITY_LBA) {
+ if (ata_id_has_lba(id)) {
sectnum = (unsigned char)(lba);
cylinder = (unsigned short)(lba>>8);
head = ATA_ADDRESS_DEVHEAD_LBA_MODE | (unsigned char)(lba>>24 & 0x0F);
} else {
- sectnum = (unsigned char)((lba % id->sectors) + 1);
- cylinder = (unsigned short)(lba / (id->sectors * id->heads));
- head = (unsigned char)((lba / id->sectors) % id->heads);
+ sectnum = (u8)((lba % id[ATA_ID_SECTORS]) + 1);
+ cylinder = (u16)(lba / (id[ATA_ID_SECTORS] *
+ id[ATA_ID_HEADS]));
+ head = (u8)((lba / id[ATA_ID_SECTORS]) %
+ id[ATA_ID_HEADS]);
}
ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
@@ -1445,7 +1367,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
ataCdb->write.CylinderHighByte = (unsigned char)(cylinder>>8);
ataCdb->write.CylinderLowByte = (unsigned char)cylinder;
ataCdb->write.DeviceHeadByte = (head | ATA_ADDRESS_DEVHEAD_STD);
- ataCdb->write.CommandByte = WIN_WRITE;
+ ataCdb->write.CommandByte = ATA_CMD_PIO_WRITE;
break;
case ALLOW_MEDIUM_REMOVAL:
@@ -1459,7 +1381,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
ataCdb->generic.TransferBlockSize = 1;
ataCdb->generic.RegisterSelect = REG_COMMAND;
ataCdb->write.CommandByte = (srb->cmnd[4] & 0x1) ?
- WIN_DOORLOCK : WIN_DOORUNLOCK;
+ ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
isd200_srb_set_bufflen(srb, 0);
} else {
US_DEBUGP(" Not removeable media, just report okay\n");
@@ -1539,8 +1461,7 @@ static int isd200_init_info(struct us_data *us)
if (!info)
retStatus = ISD200_ERROR;
else {
- info->id = (struct hd_driveid *)
- kzalloc(sizeof(struct hd_driveid), GFP_KERNEL);
+ info->id = kzalloc(ATA_ID_WORDS * 2, GFP_KERNEL);
info->RegsBuf = (unsigned char *)
kmalloc(sizeof(info->ATARegs), GFP_KERNEL);
info->srb.sense_buffer =
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
index 8118db7f1d8..b2f149fedcc 100644
--- a/drivers/usb/wusbcore/security.c
+++ b/drivers/usb/wusbcore/security.c
@@ -562,7 +562,7 @@ void wusbhc_gtk_rekey(struct wusbhc *wusbhc)
struct wusb_dev *wusb_dev;
wusb_dev = wusbhc->port[p].wusb_dev;
- if (!wusb_dev || !wusb_dev->usb_dev | !wusb_dev->usb_dev->authenticated)
+ if (!wusb_dev || !wusb_dev->usb_dev || !wusb_dev->usb_dev->authenticated)
continue;
usb_fill_control_urb(wusb_dev->set_gtk_urb, wusb_dev->usb_dev,
diff --git a/drivers/uwb/Kconfig b/drivers/uwb/Kconfig
index ca783127af3..bac8e7a6f17 100644
--- a/drivers/uwb/Kconfig
+++ b/drivers/uwb/Kconfig
@@ -48,10 +48,10 @@ config UWB_WHCI
help
This driver enables the radio controller for WHCI cards.
- WHCI is an specification developed by Intel
+ WHCI is a specification developed by Intel
(http://www.intel.com/technology/comms/wusb/whci.htm) much
in the spirit of USB's EHCI, but for UWB and Wireless USB
- radio/host controllers connected via memmory mapping (eg:
+ radio/host controllers connected via memory mapping (eg:
PCI). Most of these cards come also with a Wireless USB host
controller.
diff --git a/drivers/uwb/whci.c b/drivers/uwb/whci.c
index 1f8964ed988..2e2784627ad 100644
--- a/drivers/uwb/whci.c
+++ b/drivers/uwb/whci.c
@@ -160,10 +160,10 @@ static int whci_probe(struct pci_dev *pci, const struct pci_device_id *id)
pci_enable_msi(pci);
pci_set_master(pci);
err = -ENXIO;
- if (!pci_set_dma_mask(pci, DMA_64BIT_MASK))
- pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK);
- else if (!pci_set_dma_mask(pci, DMA_32BIT_MASK))
- pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK);
+ if (!pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
+ else if (!pci_set_dma_mask(pci, DMA_BIT_MASK(32)))
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32));
else
goto error_dma;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index ffe2f2796e2..7826bdce4bb 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1550,6 +1550,7 @@ config FB_3DFX
select FB_CFB_IMAGEBLIT
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
+ select FB_MODE_HELPERS
help
This driver supports graphics boards with the 3Dfx Banshee,
Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have
@@ -1565,6 +1566,14 @@ config FB_3DFX_ACCEL
This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer
device driver with acceleration functions.
+config FB_3DFX_I2C
+ bool "Enable DDC/I2C support"
+ depends on FB_3DFX && EXPERIMENTAL
+ select FB_DDC
+ default y
+ help
+ Say Y here if you want DDC/I2C support for your 3dfx Voodoo3.
+
config FB_VOODOO1
tristate "3Dfx Voodoo Graphics (sst1) support"
depends on FB && PCI
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 16bb7e3c031..6c37e8ee5ef 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -698,8 +698,8 @@ static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo)
found:
/*
* Some methods fail to retrieve SCLK and MCLK values, we apply default
- * settings in this case (200Mhz). If that really happne often, we could
- * fetch from registers instead...
+ * settings in this case (200Mhz). If that really happens often, we
+ * could fetch from registers instead...
*/
if (rinfo->pll.mclk == 0)
rinfo->pll.mclk = 20000;
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 72facb9eb7d..f9d19be0554 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -84,6 +84,15 @@ config LCD_TOSA
If you have an Sharp SL-6000 Zaurus say Y to enable a driver
for its LCD.
+config LCD_HP700
+ tristate "HP Jornada 700 series LCD Driver"
+ depends on LCD_CLASS_DEVICE
+ depends on SA1100_JORNADA720_SSP && !PREEMPT
+ default y
+ help
+ If you have an HP Jornada 700 series handheld (710/720/728)
+ say Y to enable LCD control driver.
+
#
# Backlight
#
@@ -157,6 +166,15 @@ config BACKLIGHT_HP680
If you have a HP Jornada 680, say y to enable the
backlight driver.
+config BACKLIGHT_HP700
+ tristate "HP Jornada 700 series Backlight Driver"
+ depends on BACKLIGHT_CLASS_DEVICE
+ depends on SA1100_JORNADA720_SSP && !PREEMPT
+ default y
+ help
+ If you have an HP Jornada 700 series,
+ say Y to include backlight control driver.
+
config BACKLIGHT_PROGEAR
tristate "Frontpath ProGear Backlight Driver"
depends on BACKLIGHT_CLASS_DEVICE && PCI && X86
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 63d75949816..4eb178c1d68 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -2,6 +2,7 @@
obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o
+obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o
obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
obj-$(CONFIG_LCD_ILI9320) += ili9320.o
obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o
@@ -12,6 +13,7 @@ obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o
obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o
obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o
+obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index dd37cbcaf8c..157057c79ca 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -35,8 +35,6 @@ static int fb_notifier_callback(struct notifier_block *self,
return 0;
bd = container_of(self, struct backlight_device, fb_notif);
- if (!lock_fb_info(evdata->info))
- return -ENODEV;
mutex_lock(&bd->ops_lock);
if (bd->ops)
if (!bd->ops->check_fb ||
@@ -49,7 +47,6 @@ static int fb_notifier_callback(struct notifier_block *self,
backlight_update_status(bd);
}
mutex_unlock(&bd->ops_lock);
- unlock_fb_info(evdata->info);
return 0;
}
diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c
new file mode 100644
index 00000000000..c3ebb6b41ce
--- /dev/null
+++ b/drivers/video/backlight/jornada720_bl.c
@@ -0,0 +1,161 @@
+/*
+ *
+ * Backlight driver for HP Jornada 700 series (710/720/728)
+ * Copyright (C) 2006-2009 Kristoffer Ericson <kristoffer.ericson@gmail.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 or any later version as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/backlight.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <mach/jornada720.h>
+#include <mach/hardware.h>
+
+#include <video/s1d13xxxfb.h>
+
+#define BL_MAX_BRIGHT 255
+#define BL_DEF_BRIGHT 25
+
+static int jornada_bl_get_brightness(struct backlight_device *bd)
+{
+ int ret;
+
+ /* check if backlight is on */
+ if (!(PPSR & PPC_LDD1))
+ return 0;
+
+ jornada_ssp_start();
+
+ /* cmd should return txdummy */
+ ret = jornada_ssp_byte(GETBRIGHTNESS);
+
+ if (jornada_ssp_byte(GETBRIGHTNESS) != TXDUMMY) {
+ printk(KERN_ERR "bl : get brightness timeout\n");
+ jornada_ssp_end();
+ return -ETIMEDOUT;
+ } else /* exchange txdummy for value */
+ ret = jornada_ssp_byte(TXDUMMY);
+
+ jornada_ssp_end();
+
+ return (BL_MAX_BRIGHT - ret);
+}
+
+static int jornada_bl_update_status(struct backlight_device *bd)
+{
+ int ret = 0;
+
+ jornada_ssp_start();
+
+ /* If backlight is off then really turn it off */
+ if ((bd->props.power != FB_BLANK_UNBLANK) || (bd->props.fb_blank != FB_BLANK_UNBLANK)) {
+ ret = jornada_ssp_byte(BRIGHTNESSOFF);
+ if (ret != TXDUMMY) {
+ printk(KERN_INFO "bl : brightness off timeout\n");
+ /* turn off backlight */
+ PPSR &= ~PPC_LDD1;
+ PPDR |= PPC_LDD1;
+ ret = -ETIMEDOUT;
+ }
+ } else /* turn on backlight */
+ PPSR |= PPC_LDD1;
+
+ /* send command to our mcu */
+ if (jornada_ssp_byte(SETBRIGHTNESS) != TXDUMMY) {
+ printk(KERN_INFO "bl : failed to set brightness\n");
+ ret = -ETIMEDOUT;
+ goto out
+ }
+
+ /* at this point we expect that the mcu has accepted
+ our command and is waiting for our new value
+ please note that maximum brightness is 255,
+ but due to physical layout it is equal to 0, so we simply
+ invert the value (MAX VALUE - NEW VALUE). */
+ if (jornada_ssp_byte(BL_MAX_BRIGHT - bd->props.brightness) != TXDUMMY) {
+ printk(KERN_ERR "bl : set brightness failed\n");
+ ret = -ETIMEDOUT;
+ }
+
+ /* If infact we get an TXDUMMY as output we are happy and dont
+ make any further comments about it */
+out:
+ jornada_ssp_end();
+
+ return ret;
+}
+
+static struct backlight_ops jornada_bl_ops = {
+ .get_brightness = jornada_bl_get_brightness,
+ .update_status = jornada_bl_update_status,
+ .options = BL_CORE_SUSPENDRESUME,
+};
+
+static int jornada_bl_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct backlight_device *bd;
+
+ bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_bl_ops);
+
+ if (IS_ERR(bd)) {
+ ret = PTR_ERR(bd);
+ printk(KERN_ERR "bl : failed to register device, err=%x\n", ret);
+ return ret;
+ }
+
+ bd->props.power = FB_BLANK_UNBLANK;
+ bd->props.brightness = BL_DEF_BRIGHT;
+ /* note. make sure max brightness is set otherwise
+ you will get seemingly non-related errors when
+ trying to change brightness */
+ bd->props.max_brightness = BL_MAX_BRIGHT;
+ jornada_bl_update_status(bd);
+
+ platform_set_drvdata(pdev, bd);
+ printk(KERN_INFO "HP Jornada 700 series backlight driver\n");
+
+ return 0;
+}
+
+static int jornada_bl_remove(struct platform_device *pdev)
+{
+ struct backlight_device *bd = platform_get_drvdata(pdev);
+
+ backlight_device_unregister(bd);
+
+ return 0;
+}
+
+static struct platform_driver jornada_bl_driver = {
+ .probe = jornada_bl_probe,
+ .remove = jornada_bl_remove,
+ .driver = {
+ .name = "jornada_bl",
+ },
+};
+
+int __init jornada_bl_init(void)
+{
+ return platform_driver_register(&jornada_bl_driver);
+}
+
+void __exit jornada_bl_exit(void)
+{
+ platform_driver_unregister(&jornada_bl_driver);
+}
+
+MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson>");
+MODULE_DESCRIPTION("HP Jornada 710/720/728 Backlight driver");
+MODULE_LICENSE("GPL");
+
+module_init(jornada_bl_init);
+module_exit(jornada_bl_exit);
diff --git a/drivers/video/backlight/jornada720_lcd.c b/drivers/video/backlight/jornada720_lcd.c
new file mode 100644
index 00000000000..cbbb167fd26
--- /dev/null
+++ b/drivers/video/backlight/jornada720_lcd.c
@@ -0,0 +1,153 @@
+/*
+ *
+ * LCD driver for HP Jornada 700 series (710/720/728)
+ * Copyright (C) 2006-2009 Kristoffer Ericson <kristoffer.ericson@gmail.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 or any later version as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/kernel.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <mach/jornada720.h>
+#include <mach/hardware.h>
+
+#include <video/s1d13xxxfb.h>
+
+#define LCD_MAX_CONTRAST 0xff
+#define LCD_DEF_CONTRAST 0x80
+
+static int jornada_lcd_get_power(struct lcd_device *dev)
+{
+ /* LDD2 in PPC = LCD POWER */
+ if (PPSR & PPC_LDD2)
+ return FB_BLANK_UNBLANK; /* PW ON */
+ else
+ return FB_BLANK_POWERDOWN; /* PW OFF */
+}
+
+static int jornada_lcd_get_contrast(struct lcd_device *dev)
+{
+ int ret;
+
+ if (jornada_lcd_get_power(dev) != FB_BLANK_UNBLANK)
+ return 0;
+
+ jornada_ssp_start();
+
+ if (jornada_ssp_byte(GETCONTRAST) != TXDUMMY) {
+ printk(KERN_ERR "lcd: get contrast failed\n");
+ jornada_ssp_end();
+ return -ETIMEDOUT;
+ } else {
+ ret = jornada_ssp_byte(TXDUMMY);
+ jornada_ssp_end();
+ return ret;
+ }
+}
+
+static int jornada_lcd_set_contrast(struct lcd_device *dev, int value)
+{
+ int ret;
+
+ jornada_ssp_start();
+
+ /* start by sending our set contrast cmd to mcu */
+ ret = jornada_ssp_byte(SETCONTRAST);
+
+ /* push the new value */
+ if (jornada_ssp_byte(value) != TXDUMMY) {
+ printk(KERN_ERR "lcd : set contrast failed\n");
+ jornada_ssp_end();
+ return -ETIMEDOUT;
+ }
+
+ /* if we get here we can assume everything went well */
+ jornada_ssp_end();
+
+ return 0;
+}
+
+static int jornada_lcd_set_power(struct lcd_device *dev, int power)
+{
+ if (power != FB_BLANK_UNBLANK) {
+ PPSR &= ~PPC_LDD2;
+ PPDR |= PPC_LDD2;
+ } else
+ PPSR |= PPC_LDD2;
+
+ return 0;
+}
+
+static struct lcd_ops jornada_lcd_props = {
+ .get_contrast = jornada_lcd_get_contrast,
+ .set_contrast = jornada_lcd_set_contrast,
+ .get_power = jornada_lcd_get_power,
+ .set_power = jornada_lcd_set_power,
+};
+
+static int jornada_lcd_probe(struct platform_device *pdev)
+{
+ struct lcd_device *lcd_device;
+ int ret;
+
+ lcd_device = lcd_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_lcd_props);
+
+ if (IS_ERR(lcd_device)) {
+ ret = PTR_ERR(lcd_device);
+ printk(KERN_ERR "lcd : failed to register device\n");
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, lcd_device);
+
+ /* lets set our default values */
+ jornada_lcd_set_contrast(lcd_device, LCD_DEF_CONTRAST);
+ jornada_lcd_set_power(lcd_device, FB_BLANK_UNBLANK);
+ /* give it some time to startup */
+ msleep(100);
+
+ return 0;
+}
+
+static int jornada_lcd_remove(struct platform_device *pdev)
+{
+ struct lcd_device *lcd_device = platform_get_drvdata(pdev);
+
+ lcd_device_unregister(lcd_device);
+
+ return 0;
+}
+
+static struct platform_driver jornada_lcd_driver = {
+ .probe = jornada_lcd_probe,
+ .remove = jornada_lcd_remove,
+ .driver = {
+ .name = "jornada_lcd",
+ },
+};
+
+int __init jornada_lcd_init(void)
+{
+ return platform_driver_register(&jornada_lcd_driver);
+}
+
+void __exit jornada_lcd_exit(void)
+{
+ platform_driver_unregister(&jornada_lcd_driver);
+}
+
+MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
+MODULE_DESCRIPTION("HP Jornada 710/720/728 LCD driver");
+MODULE_LICENSE("GPL");
+
+module_init(jornada_lcd_init);
+module_exit(jornada_lcd_exit);
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 0bb13df0fa8..b6449470106 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -40,8 +40,6 @@ static int fb_notifier_callback(struct notifier_block *self,
if (!ld->ops)
return 0;
- if (!lock_fb_info(evdata->info))
- return -ENODEV;
mutex_lock(&ld->ops_lock);
if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) {
if (event == FB_EVENT_BLANK) {
@@ -53,7 +51,6 @@ static int fb_notifier_callback(struct notifier_block *self,
}
}
mutex_unlock(&ld->ops_lock);
- unlock_fb_info(evdata->info);
return 0;
}
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c
index 65864c50045..3bb4c0a50c6 100644
--- a/drivers/video/backlight/mbp_nvidia_bl.c
+++ b/drivers/video/backlight/mbp_nvidia_bl.c
@@ -27,73 +27,192 @@
static struct backlight_device *mbp_backlight_device;
-static struct dmi_system_id __initdata mbp_device_table[] = {
+/* Structure to be passed to the DMI_MATCH function. */
+struct dmi_match_data {
+ /* I/O resource to allocate. */
+ unsigned long iostart;
+ unsigned long iolen;
+ /* Backlight operations structure. */
+ struct backlight_ops backlight_ops;
+};
+
+/* Module parameters. */
+static int debug;
+module_param_named(debug, debug, int, 0644);
+MODULE_PARM_DESC(debug, "Set to one to enable debugging messages.");
+
+/*
+ * Implementation for MacBooks with Intel chipset.
+ */
+static int intel_chipset_send_intensity(struct backlight_device *bd)
+{
+ int intensity = bd->props.brightness;
+
+ if (debug)
+ printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n",
+ intensity);
+
+ outb(0x04 | (intensity << 4), 0xb3);
+ outb(0xbf, 0xb2);
+ return 0;
+}
+
+static int intel_chipset_get_intensity(struct backlight_device *bd)
+{
+ int intensity;
+
+ outb(0x03, 0xb3);
+ outb(0xbf, 0xb2);
+ intensity = inb(0xb3) >> 4;
+
+ if (debug)
+ printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n",
+ intensity);
+
+ return intensity;
+}
+
+static const struct dmi_match_data intel_chipset_data = {
+ .iostart = 0xb2,
+ .iolen = 2,
+ .backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .get_brightness = intel_chipset_get_intensity,
+ .update_status = intel_chipset_send_intensity,
+ }
+};
+
+/*
+ * Implementation for MacBooks with Nvidia chipset.
+ */
+static int nvidia_chipset_send_intensity(struct backlight_device *bd)
+{
+ int intensity = bd->props.brightness;
+
+ if (debug)
+ printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n",
+ intensity);
+
+ outb(0x04 | (intensity << 4), 0x52f);
+ outb(0xbf, 0x52e);
+ return 0;
+}
+
+static int nvidia_chipset_get_intensity(struct backlight_device *bd)
+{
+ int intensity;
+
+ outb(0x03, 0x52f);
+ outb(0xbf, 0x52e);
+ intensity = inb(0x52f) >> 4;
+
+ if (debug)
+ printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n",
+ intensity);
+
+ return intensity;
+}
+
+static const struct dmi_match_data nvidia_chipset_data = {
+ .iostart = 0x52e,
+ .iolen = 2,
+ .backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .get_brightness = nvidia_chipset_get_intensity,
+ .update_status = nvidia_chipset_send_intensity
+ }
+};
+
+/*
+ * DMI matching.
+ */
+static /* const */ struct dmi_match_data *driver_data;
+
+static int mbp_dmi_match(const struct dmi_system_id *id)
+{
+ driver_data = id->driver_data;
+
+ printk(KERN_INFO "mbp_nvidia_bl: %s detected\n", id->ident);
+ return 1;
+}
+
+static const struct dmi_system_id __initdata mbp_device_table[] = {
{
- .ident = "3,1",
- .matches = {
+ .callback = mbp_dmi_match,
+ .ident = "MacBookPro 3,1",
+ .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"),
},
+ .driver_data = (void *)&intel_chipset_data,
},
{
- .ident = "3,2",
- .matches = {
+ .callback = mbp_dmi_match,
+ .ident = "MacBookPro 3,2",
+ .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,2"),
},
+ .driver_data = (void *)&intel_chipset_data,
},
{
- .ident = "4,1",
- .matches = {
+ .callback = mbp_dmi_match,
+ .ident = "MacBookPro 4,1",
+ .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4,1"),
},
+ .driver_data = (void *)&intel_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
+ .ident = "MacBook 5,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,1"),
+ },
+ .driver_data = (void *)&nvidia_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
+ .ident = "MacBookAir 2,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2,1"),
+ },
+ .driver_data = (void *)&nvidia_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
+ .ident = "MacBookPro 5,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,1"),
+ },
+ .driver_data = (void *)&nvidia_chipset_data,
},
{ }
};
-static int mbp_send_intensity(struct backlight_device *bd)
-{
- int intensity = bd->props.brightness;
-
- outb(0x04 | (intensity << 4), 0xb3);
- outb(0xbf, 0xb2);
-
- return 0;
-}
-
-static int mbp_get_intensity(struct backlight_device *bd)
-{
- outb(0x03, 0xb3);
- outb(0xbf, 0xb2);
- return inb(0xb3) >> 4;
-}
-
-static struct backlight_ops mbp_ops = {
- .options = BL_CORE_SUSPENDRESUME,
- .get_brightness = mbp_get_intensity,
- .update_status = mbp_send_intensity,
-};
-
static int __init mbp_init(void)
{
if (!dmi_check_system(mbp_device_table))
return -ENODEV;
- if (!request_region(0xb2, 2, "Macbook Pro backlight"))
+ if (!request_region(driver_data->iostart, driver_data->iolen,
+ "Macbook Pro backlight"))
return -ENXIO;
mbp_backlight_device = backlight_device_register("mbp_backlight",
- NULL, NULL,
- &mbp_ops);
+ NULL, NULL, &driver_data->backlight_ops);
if (IS_ERR(mbp_backlight_device)) {
- release_region(0xb2, 2);
+ release_region(driver_data->iostart, driver_data->iolen);
return PTR_ERR(mbp_backlight_device);
}
mbp_backlight_device->props.max_brightness = 15;
mbp_backlight_device->props.brightness =
- mbp_get_intensity(mbp_backlight_device);
+ driver_data->backlight_ops.get_brightness(mbp_backlight_device);
backlight_update_status(mbp_backlight_device);
return 0;
@@ -103,7 +222,7 @@ static void __exit mbp_exit(void)
{
backlight_device_unregister(mbp_backlight_device);
- release_region(0xb2, 2);
+ release_region(driver_data->iostart, driver_data->iolen);
}
module_init(mbp_init);
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index ea07258565f..e641584e212 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -3,7 +3,7 @@
*
* simple PWM based backlight control, board code has to setup
* 1) pin configuration so PWM waveforms can output
- * 2) platform_data casts to the PWM id (0/1/2/3 on PXA)
+ * 2) platform_data being correctly configured
*
* 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
@@ -97,7 +97,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
} else
dev_dbg(&pdev->dev, "got pwm for backlight\n");
- bl = backlight_device_register(pdev->name, &pdev->dev,
+ bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
pb, &pwm_backlight_ops);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index d42e385f091..4c2bf923418 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -567,9 +567,7 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
default:
dev_dbg(info->device,
"Unsupported bpp size: %d\n", var->bits_per_pixel);
- assert(false);
- /* should never occur */
- break;
+ return -EINVAL;
}
if (var->xres_virtual < var->xres)
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 2cd500a304f..471a9a60376 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -2263,9 +2263,12 @@ static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info,
}
+ if (!lock_fb_info(info))
+ return;
event.info = info;
event.data = &blank;
fb_notifier_call_chain(FB_EVENT_CONBLANK, &event);
+ unlock_fb_info(info);
}
static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
@@ -2956,8 +2959,6 @@ static int fbcon_fb_unregistered(struct fb_info *info)
{
int i, idx;
- if (!lock_fb_info(info))
- return -ENODEV;
idx = info->node;
for (i = first_fb_vc; i <= last_fb_vc; i++) {
if (con2fb_map[i] == idx)
@@ -2985,8 +2986,6 @@ static int fbcon_fb_unregistered(struct fb_info *info)
if (primary_device == idx)
primary_device = -1;
- unlock_fb_info(info);
-
if (!num_registered_fb)
unregister_con_driver(&fb_con);
@@ -3027,11 +3026,8 @@ static int fbcon_fb_registered(struct fb_info *info)
{
int ret = 0, i, idx;
- if (!lock_fb_info(info))
- return -ENODEV;
idx = info->node;
fbcon_select_primary(info);
- unlock_fb_info(info);
if (info_idx == -1) {
for (i = first_fb_vc; i <= last_fb_vc; i++) {
@@ -3152,53 +3148,23 @@ static int fbcon_event_notify(struct notifier_block *self,
switch(action) {
case FB_EVENT_SUSPEND:
- if (!lock_fb_info(info)) {
- ret = -ENODEV;
- goto done;
- }
fbcon_suspended(info);
- unlock_fb_info(info);
break;
case FB_EVENT_RESUME:
- if (!lock_fb_info(info)) {
- ret = -ENODEV;
- goto done;
- }
fbcon_resumed(info);
- unlock_fb_info(info);
break;
case FB_EVENT_MODE_CHANGE:
- if (!lock_fb_info(info)) {
- ret = -ENODEV;
- goto done;
- }
fbcon_modechanged(info);
- unlock_fb_info(info);
break;
case FB_EVENT_MODE_CHANGE_ALL:
- if (!lock_fb_info(info)) {
- ret = -ENODEV;
- goto done;
- }
fbcon_set_all_vcs(info);
- unlock_fb_info(info);
break;
case FB_EVENT_MODE_DELETE:
mode = event->data;
- if (!lock_fb_info(info)) {
- ret = -ENODEV;
- goto done;
- }
ret = fbcon_mode_deleted(info, mode);
- unlock_fb_info(info);
break;
case FB_EVENT_FB_UNBIND:
- if (!lock_fb_info(info)) {
- ret = -ENODEV;
- goto done;
- }
idx = info->node;
- unlock_fb_info(info);
ret = fbcon_fb_unbind(idx);
break;
case FB_EVENT_FB_REGISTERED:
@@ -3217,29 +3183,14 @@ static int fbcon_event_notify(struct notifier_block *self,
con2fb->framebuffer = con2fb_map[con2fb->console - 1];
break;
case FB_EVENT_BLANK:
- if (!lock_fb_info(info)) {
- ret = -ENODEV;
- goto done;
- }
fbcon_fb_blanked(info, *(int *)event->data);
- unlock_fb_info(info);
break;
case FB_EVENT_NEW_MODELIST:
- if (!lock_fb_info(info)) {
- ret = -ENODEV;
- goto done;
- }
fbcon_new_modelist(info);
- unlock_fb_info(info);
break;
case FB_EVENT_GET_REQ:
caps = event->data;
- if (!lock_fb_info(info)) {
- ret = -ENODEV;
- goto done;
- }
fbcon_get_requirement(info, caps);
- unlock_fb_info(info);
break;
}
done:
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 0c5b9a9fd56..8dea2bc9270 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -210,12 +210,15 @@ static int __init efifb_probe(struct platform_device *dev)
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;
+ if (!screen_info.lfb_base) {
+ printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
+ return -ENODEV;
+ }
+ printk(KERN_INFO "efifb: probing for efifb\n");
/* just assume they're all unset if any are */
if (!screen_info.blue_size) {
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 2ac32e6b595..d412a1ddc12 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1097,8 +1097,11 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
return -EINVAL;
con2fb.framebuffer = -1;
event.data = &con2fb;
+ if (!lock_fb_info(info))
+ return -ENODEV;
event.info = info;
fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
+ unlock_fb_info(info);
ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;
break;
case FBIOPUT_CON2FBMAP:
@@ -1115,8 +1118,11 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
break;
}
event.data = &con2fb;
+ if (!lock_fb_info(info))
+ return -ENODEV;
event.info = info;
ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
+ unlock_fb_info(info);
break;
case FBIOBLANK:
if (!lock_fb_info(info))
@@ -1521,7 +1527,10 @@ register_framebuffer(struct fb_info *fb_info)
registered_fb[i] = fb_info;
event.info = fb_info;
+ if (!lock_fb_info(fb_info))
+ return -ENODEV;
fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
+ unlock_fb_info(fb_info);
return 0;
}
@@ -1555,8 +1564,12 @@ unregister_framebuffer(struct fb_info *fb_info)
goto done;
}
+
+ if (!lock_fb_info(fb_info))
+ return -ENODEV;
event.info = fb_info;
ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
+ unlock_fb_info(fb_info);
if (ret) {
ret = -EINVAL;
@@ -1590,6 +1603,8 @@ void fb_set_suspend(struct fb_info *info, int state)
{
struct fb_event event;
+ if (!lock_fb_info(info))
+ return;
event.info = info;
if (state) {
fb_notifier_call_chain(FB_EVENT_SUSPEND, &event);
@@ -1598,6 +1613,7 @@ void fb_set_suspend(struct fb_info *info, int state)
info->state = FBINFO_STATE_RUNNING;
fb_notifier_call_chain(FB_EVENT_RESUME, &event);
}
+ unlock_fb_info(info);
}
/**
@@ -1667,8 +1683,11 @@ int fb_new_modelist(struct fb_info *info)
err = 1;
if (!list_empty(&info->modelist)) {
+ if (!lock_fb_info(info))
+ return -ENODEV;
event.info = info;
err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
+ unlock_fb_info(info);
}
return err;
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index fb51197d1c9..f153c581cbd 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -1352,14 +1352,15 @@ static int fsl_diu_resume(struct of_device *ofdev)
#endif /* CONFIG_PM */
/* Align to 64-bit(8-byte), 32-byte, etc. */
-static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align)
+static int allocate_buf(struct device *dev, struct diu_addr *buf, u32 size,
+ u32 bytes_align)
{
u32 offset, ssize;
u32 mask;
dma_addr_t paddr = 0;
ssize = size + bytes_align;
- buf->vaddr = dma_alloc_coherent(NULL, ssize, &paddr, GFP_DMA |
+ buf->vaddr = dma_alloc_coherent(dev, ssize, &paddr, GFP_DMA |
__GFP_ZERO);
if (!buf->vaddr)
return -ENOMEM;
@@ -1376,9 +1377,10 @@ static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align)
return 0;
}
-static void free_buf(struct diu_addr *buf, u32 size, u32 bytes_align)
+static void free_buf(struct device *dev, struct diu_addr *buf, u32 size,
+ u32 bytes_align)
{
- dma_free_coherent(NULL, size + bytes_align,
+ dma_free_coherent(dev, size + bytes_align,
buf->vaddr, (buf->paddr - buf->offset));
return;
}
@@ -1476,17 +1478,19 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev,
machine_data->monitor_port = monitor_port;
/* Area descriptor memory pool aligns to 64-bit boundary */
- if (allocate_buf(&pool.ad, sizeof(struct diu_ad) * FSL_AOI_NUM, 8))
+ if (allocate_buf(&ofdev->dev, &pool.ad,
+ sizeof(struct diu_ad) * FSL_AOI_NUM, 8))
return -ENOMEM;
/* Get memory for Gamma Table - 32-byte aligned memory */
- if (allocate_buf(&pool.gamma, 768, 32)) {
+ if (allocate_buf(&ofdev->dev, &pool.gamma, 768, 32)) {
ret = -ENOMEM;
goto error;
}
/* For performance, cursor bitmap buffer aligns to 32-byte boundary */
- if (allocate_buf(&pool.cursor, MAX_CURS * MAX_CURS * 2, 32)) {
+ if (allocate_buf(&ofdev->dev, &pool.cursor, MAX_CURS * MAX_CURS * 2,
+ 32)) {
ret = -ENOMEM;
goto error;
}
@@ -1554,11 +1558,13 @@ error:
i > 0; i--)
uninstall_fb(machine_data->fsl_diu_info[i - 1]);
if (pool.ad.vaddr)
- free_buf(&pool.ad, sizeof(struct diu_ad) * FSL_AOI_NUM, 8);
+ free_buf(&ofdev->dev, &pool.ad,
+ sizeof(struct diu_ad) * FSL_AOI_NUM, 8);
if (pool.gamma.vaddr)
- free_buf(&pool.gamma, 768, 32);
+ free_buf(&ofdev->dev, &pool.gamma, 768, 32);
if (pool.cursor.vaddr)
- free_buf(&pool.cursor, MAX_CURS * MAX_CURS * 2, 32);
+ free_buf(&ofdev->dev, &pool.cursor, MAX_CURS * MAX_CURS * 2,
+ 32);
if (machine_data->dummy_aoi_virt)
fsl_diu_free(machine_data->dummy_aoi_virt, 64);
iounmap(dr.diu_reg);
@@ -1584,11 +1590,13 @@ static int fsl_diu_remove(struct of_device *ofdev)
for (i = ARRAY_SIZE(machine_data->fsl_diu_info); i > 0; i--)
uninstall_fb(machine_data->fsl_diu_info[i - 1]);
if (pool.ad.vaddr)
- free_buf(&pool.ad, sizeof(struct diu_ad) * FSL_AOI_NUM, 8);
+ free_buf(&ofdev->dev, &pool.ad,
+ sizeof(struct diu_ad) * FSL_AOI_NUM, 8);
if (pool.gamma.vaddr)
- free_buf(&pool.gamma, 768, 32);
+ free_buf(&ofdev->dev, &pool.gamma, 768, 32);
if (pool.cursor.vaddr)
- free_buf(&pool.cursor, MAX_CURS * MAX_CURS * 2, 32);
+ free_buf(&ofdev->dev, &pool.cursor, MAX_CURS * MAX_CURS * 2,
+ 32);
if (machine_data->dummy_aoi_virt)
fsl_diu_free(machine_data->dummy_aoi_virt, 64);
iounmap(dr.diu_reg);
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index a50bea61480..40984551c92 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -53,6 +53,7 @@
#define PCI_DEVICE_ID_INTEL_830M 0x3577
#define PCI_DEVICE_ID_INTEL_845G 0x2562
#define PCI_DEVICE_ID_INTEL_85XGM 0x3582
+#define PCI_DEVICE_ID_INTEL_854 0x358E
#define PCI_DEVICE_ID_INTEL_865G 0x2572
#define PCI_DEVICE_ID_INTEL_915G 0x2582
#define PCI_DEVICE_ID_INTEL_915GM 0x2592
@@ -154,6 +155,7 @@ enum intel_chips {
INTEL_85XGM,
INTEL_852GM,
INTEL_852GME,
+ INTEL_854,
INTEL_855GM,
INTEL_855GME,
INTEL_865G,
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
index b3065492bb2..487f2be4746 100644
--- a/drivers/video/intelfb/intelfb_i2c.c
+++ b/drivers/video/intelfb/intelfb_i2c.c
@@ -156,6 +156,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
switch(dinfo->chipset) {
case INTEL_830M:
case INTEL_845G:
+ case INTEL_854:
case INTEL_855GM:
case INTEL_865G:
dinfo->output[i].type = INTELFB_OUTPUT_DVO;
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 6d8e5415c80..ace14fe02fc 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -182,6 +182,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_845G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_845G },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G },
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_854, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_854 },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G },
{ 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 },
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 8b26b27c2db..0689f97c523 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -84,6 +84,11 @@ int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
dinfo->mobile = 0;
dinfo->pll_index = PLLS_I8xx;
return 0;
+ case PCI_DEVICE_ID_INTEL_854:
+ dinfo->mobile = 1;
+ dinfo->name = "Intel(R) 854";
+ dinfo->chipset = INTEL_854;
+ return 0;
case PCI_DEVICE_ID_INTEL_85XGM:
tmp = 0;
dinfo->mobile = 1;
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index fa1a512ce03..21b3692092f 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -400,12 +400,12 @@ static void sdc_disable_channel(struct mx3fb_info *mx3_fbi)
static int sdc_set_window_pos(struct mx3fb_data *mx3fb, enum ipu_channel channel,
int16_t x_pos, int16_t y_pos)
{
- x_pos += mx3fb->h_start_width;
- y_pos += mx3fb->v_start_width;
-
if (channel != IDMAC_SDC_0)
return -EINVAL;
+ x_pos += mx3fb->h_start_width;
+ y_pos += mx3fb->v_start_width;
+
mx3fb_write_reg(mx3fb, (x_pos << 16) | y_pos, SDC_BG_POS);
return 0;
}
@@ -491,11 +491,13 @@ static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel,
* 2^4 to get fractional part, as long as we stay under ~250MHz and on
* i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz
*/
- dev_dbg(mx3fb->dev, "pixel clk = %d\n", pixel_clk);
-
ipu_clk = clk_get(mx3fb->dev, NULL);
- div = clk_get_rate(ipu_clk) * 16 / pixel_clk;
- clk_put(ipu_clk);
+ if (!IS_ERR(ipu_clk)) {
+ div = clk_get_rate(ipu_clk) * 16 / pixel_clk;
+ clk_put(ipu_clk);
+ } else {
+ div = 0;
+ }
if (div < 0x40) { /* Divider less than 4 */
dev_dbg(mx3fb->dev,
@@ -503,6 +505,9 @@ static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel,
div = 0x40;
}
+ dev_dbg(mx3fb->dev, "pixel clk = %u, divider %u.%u\n",
+ pixel_clk, div >> 4, (div & 7) * 125);
+
spin_lock_irqsave(&mx3fb->lock, lock_flags);
/*
@@ -515,16 +520,16 @@ static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel,
/* DI settings */
old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF;
old_conf |= sig.datamask_en << DI_D3_DATAMSK_SHIFT |
- sig.clksel_en << DI_D3_CLK_SEL_SHIFT |
- sig.clkidle_en << DI_D3_CLK_IDLE_SHIFT;
+ sig.clksel_en << DI_D3_CLK_SEL_SHIFT |
+ sig.clkidle_en << DI_D3_CLK_IDLE_SHIFT;
mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF);
old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF;
old_conf |= sig.data_pol << DI_D3_DATA_POL_SHIFT |
- sig.clk_pol << DI_D3_CLK_POL_SHIFT |
- sig.enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT |
- sig.Hsync_pol << DI_D3_HSYNC_POL_SHIFT |
- sig.Vsync_pol << DI_D3_VSYNC_POL_SHIFT;
+ sig.clk_pol << DI_D3_CLK_POL_SHIFT |
+ sig.enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT |
+ sig.Hsync_pol << DI_D3_HSYNC_POL_SHIFT |
+ sig.Vsync_pol << DI_D3_VSYNC_POL_SHIFT;
mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL);
switch (pixel_fmt) {
@@ -721,7 +726,6 @@ static int mx3fb_set_par(struct fb_info *fbi)
struct idmac_channel *ichan = mx3_fbi->idmac_channel;
struct idmac_video_param *video = &ichan->params.video;
struct scatterlist *sg = mx3_fbi->sg;
- size_t screen_size;
dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+');
@@ -745,12 +749,10 @@ static int mx3fb_set_par(struct fb_info *fbi)
}
}
- screen_size = fbi->fix.line_length * fbi->var.yres;
-
sg_init_table(&sg[0], 1);
sg_init_table(&sg[1], 1);
- sg_dma_address(&sg[0]) = fbi->fix.smem_start;
+ sg_dma_address(&sg[0]) = fbi->fix.smem_start;
sg_set_page(&sg[0], virt_to_page(fbi->screen_base),
fbi->fix.smem_len,
offset_in_page(fbi->screen_base));
@@ -927,7 +929,7 @@ static int mx3fb_setcolreg(unsigned int regno, unsigned int red,
u32 val;
int ret = 1;
- dev_dbg(fbi->device, "%s\n", __func__);
+ dev_dbg(fbi->device, "%s, regno = %u\n", __func__, regno);
mutex_lock(&mx3_fbi->mutex);
/*
@@ -973,9 +975,8 @@ static int mx3fb_blank(int blank, struct fb_info *fbi)
struct mx3fb_info *mx3_fbi = fbi->par;
struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
- dev_dbg(fbi->device, "%s\n", __func__);
-
- dev_dbg(fbi->device, "blank = %d\n", blank);
+ dev_dbg(fbi->device, "%s, blank = %d, base %p, len %u\n", __func__,
+ blank, fbi->screen_base, fbi->fix.smem_len);
if (mx3_fbi->blank == blank)
return 0;
@@ -988,8 +989,11 @@ static int mx3fb_blank(int blank, struct fb_info *fbi)
case FB_BLANK_VSYNC_SUSPEND:
case FB_BLANK_HSYNC_SUSPEND:
case FB_BLANK_NORMAL:
- sdc_disable_channel(mx3_fbi);
sdc_set_brightness(mx3fb, 0);
+ memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
+ /* Give LCD time to update - enough for 50 and 60 Hz */
+ msleep(25);
+ sdc_disable_channel(mx3_fbi);
break;
case FB_BLANK_UNBLANK:
sdc_enable_channel(mx3_fbi);
@@ -1063,6 +1067,7 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
mutex_unlock(&mx3_fbi->mutex);
dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ?
"user interrupt" : "timeout");
+ disable_irq(mx3_fbi->idmac_channel->eof_irq);
return ret ? : -ETIMEDOUT;
}
@@ -1073,6 +1078,9 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len,
offset_in_page(fbi->screen_base + offset));
+ if (mx3_fbi->txd)
+ async_tx_ack(mx3_fbi->txd);
+
txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg +
mx3_fbi->cur_ipu_buf, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT);
if (!txd) {
@@ -1099,8 +1107,6 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
return -EIO;
}
- if (mx3_fbi->txd)
- async_tx_ack(mx3_fbi->txd);
mx3_fbi->txd = txd;
fbi->var.xoffset = var->xoffset;
@@ -1506,7 +1512,7 @@ static struct platform_driver mx3fb_driver = {
* example:
* video=mx3fb:bpp=16
*/
-static int mx3fb_setup(void)
+static int __init mx3fb_setup(void)
{
#ifndef MODULE
char *opt, *options = NULL;
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 4dcec48a1d7..c3fad34309e 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -45,11 +45,11 @@ struct s3fb_info {
static const struct svga_fb_format s3fb_formats[] = {
{ 0, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0,
FB_TYPE_TEXT, FB_AUX_TEXT_SVGA_STEP4, FB_VISUAL_PSEUDOCOLOR, 8, 16},
- { 4, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0,
+ { 4, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 0,
FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 8, 16},
- { 4, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 1,
+ { 4, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 1,
FB_TYPE_INTERLEAVED_PLANES, 1, FB_VISUAL_PSEUDOCOLOR, 8, 16},
- { 8, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0,
+ { 8, {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, 0,
FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 4, 8},
{16, {10, 5, 0}, {5, 5, 0}, {0, 5, 0}, {0, 0, 0}, 0,
FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 2, 4},
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index fad58cf9ef7..10ddad8e17d 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -199,16 +199,20 @@
extern void (*sa1100fb_backlight_power)(int on);
extern void (*sa1100fb_lcd_power)(int on);
-/*
- * IMHO this looks wrong. In 8BPP, length should be 8.
- */
-static struct sa1100fb_rgb rgb_8 = {
+static struct sa1100fb_rgb rgb_4 = {
.red = { .offset = 0, .length = 4, },
.green = { .offset = 0, .length = 4, },
.blue = { .offset = 0, .length = 4, },
.transp = { .offset = 0, .length = 0, },
};
+static struct sa1100fb_rgb rgb_8 = {
+ .red = { .offset = 0, .length = 8, },
+ .green = { .offset = 0, .length = 8, },
+ .blue = { .offset = 0, .length = 8, },
+ .transp = { .offset = 0, .length = 0, },
+};
+
static struct sa1100fb_rgb def_rgb_16 = {
.red = { .offset = 11, .length = 5, },
.green = { .offset = 5, .length = 6, },
@@ -613,7 +617,7 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel);
switch (var->bits_per_pixel) {
case 4:
- rgbidx = RGB_8;
+ rgbidx = RGB_4;
break;
case 8:
rgbidx = RGB_8;
@@ -1382,6 +1386,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
fbi->fb.monspecs = monspecs;
fbi->fb.pseudo_palette = (fbi + 1);
+ fbi->rgb[RGB_4] = &rgb_4;
fbi->rgb[RGB_8] = &rgb_8;
fbi->rgb[RGB_16] = &def_rgb_16;
diff --git a/drivers/video/sa1100fb.h b/drivers/video/sa1100fb.h
index 86831db9a04..1c3b459865d 100644
--- a/drivers/video/sa1100fb.h
+++ b/drivers/video/sa1100fb.h
@@ -57,9 +57,10 @@ struct sa1100fb_lcd_reg {
unsigned long lccr3;
};
-#define RGB_8 (0)
-#define RGB_16 (1)
-#define NR_RGB 2
+#define RGB_4 (0)
+#define RGB_8 (1)
+#define RGB_16 (2)
+#define NR_RGB 3
struct sa1100fb_info {
struct fb_info fb;
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 346d6458cf7..7e17ee95a97 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -1129,7 +1129,7 @@ sisfb_bpp_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
switch(var->bits_per_pixel) {
case 8:
var->red.offset = var->green.offset = var->blue.offset = 0;
- var->red.length = var->green.length = var->blue.length = 6;
+ var->red.length = var->green.length = var->blue.length = 8;
break;
case 16:
var->red.offset = 11;
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index a439159204a..89158bc71da 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -308,9 +308,11 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
* color depth = SUM(var->{color}.length)
*
* Pseudocolor:
- * var->{color}.offset is 0
- * var->{color}.length contains width of DAC or the number of unique
- * colors available (color depth)
+ * var->{color}.offset is 0 unless the palette index takes less than
+ * bits_per_pixel bits and is stored in the upper
+ * bits of the pixel value
+ * var->{color}.length is set so that 1 << length is the number of
+ * available palette entries
* pseudo_palette is not used
* RAMDAC[X] is programmed to (red, green, blue)
* color depth = var->{color}.length
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index ee64771fbe3..89f231dc443 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -10,6 +10,12 @@
* Created : Thu Sep 23 18:17:43 1999, hmallat
* Last modified: Tue Nov 2 21:19:47 1999, hmallat
*
+ * I2C part copied from the i2c-voodoo3.c driver by:
+ * Frodo Looijaard <frodol@dds.nl>,
+ * Philip Edelbrock <phil@netroedge.com>,
+ * Ralph Metzler <rjkm@thp.uni-koeln.de>, and
+ * Mark D. Studebaker <mdsxyz123@yahoo.com>
+ *
* Lots of the information here comes from the Daryll Strauss' Banshee
* patches to the XF86 server, and the rest comes from the 3dfx
* Banshee specification. I'm very much indebted to Daryll for his
@@ -481,6 +487,12 @@ static int tdfxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
return -EINVAL;
}
+ if (info->monspecs.hfmax && info->monspecs.vfmax &&
+ info->monspecs.dclkmax && fb_validate_mode(var, info) < 0) {
+ DPRINTK("mode outside monitor's specs\n");
+ return -EINVAL;
+ }
+
var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */
lpitch = var->xres * ((var->bits_per_pixel + 7) >> 3);
@@ -1167,6 +1179,207 @@ static struct fb_ops tdfxfb_ops = {
#endif
};
+#ifdef CONFIG_FB_3DFX_I2C
+/* The voo GPIO registers don't have individual masks for each bit
+ so we always have to read before writing. */
+
+static void tdfxfb_i2c_setscl(void *data, int val)
+{
+ struct tdfxfb_i2c_chan *chan = data;
+ struct tdfx_par *par = chan->par;
+ unsigned int r;
+
+ r = tdfx_inl(par, VIDSERPARPORT);
+ if (val)
+ r |= I2C_SCL_OUT;
+ else
+ r &= ~I2C_SCL_OUT;
+ tdfx_outl(par, VIDSERPARPORT, r);
+ tdfx_inl(par, VIDSERPARPORT); /* flush posted write */
+}
+
+static void tdfxfb_i2c_setsda(void *data, int val)
+{
+ struct tdfxfb_i2c_chan *chan = data;
+ struct tdfx_par *par = chan->par;
+ unsigned int r;
+
+ r = tdfx_inl(par, VIDSERPARPORT);
+ if (val)
+ r |= I2C_SDA_OUT;
+ else
+ r &= ~I2C_SDA_OUT;
+ tdfx_outl(par, VIDSERPARPORT, r);
+ tdfx_inl(par, VIDSERPARPORT); /* flush posted write */
+}
+
+/* The GPIO pins are open drain, so the pins always remain outputs.
+ We rely on the i2c-algo-bit routines to set the pins high before
+ reading the input from other chips. */
+
+static int tdfxfb_i2c_getscl(void *data)
+{
+ struct tdfxfb_i2c_chan *chan = data;
+ struct tdfx_par *par = chan->par;
+
+ return (0 != (tdfx_inl(par, VIDSERPARPORT) & I2C_SCL_IN));
+}
+
+static int tdfxfb_i2c_getsda(void *data)
+{
+ struct tdfxfb_i2c_chan *chan = data;
+ struct tdfx_par *par = chan->par;
+
+ return (0 != (tdfx_inl(par, VIDSERPARPORT) & I2C_SDA_IN));
+}
+
+static void tdfxfb_ddc_setscl(void *data, int val)
+{
+ struct tdfxfb_i2c_chan *chan = data;
+ struct tdfx_par *par = chan->par;
+ unsigned int r;
+
+ r = tdfx_inl(par, VIDSERPARPORT);
+ if (val)
+ r |= DDC_SCL_OUT;
+ else
+ r &= ~DDC_SCL_OUT;
+ tdfx_outl(par, VIDSERPARPORT, r);
+ tdfx_inl(par, VIDSERPARPORT); /* flush posted write */
+}
+
+static void tdfxfb_ddc_setsda(void *data, int val)
+{
+ struct tdfxfb_i2c_chan *chan = data;
+ struct tdfx_par *par = chan->par;
+ unsigned int r;
+
+ r = tdfx_inl(par, VIDSERPARPORT);
+ if (val)
+ r |= DDC_SDA_OUT;
+ else
+ r &= ~DDC_SDA_OUT;
+ tdfx_outl(par, VIDSERPARPORT, r);
+ tdfx_inl(par, VIDSERPARPORT); /* flush posted write */
+}
+
+static int tdfxfb_ddc_getscl(void *data)
+{
+ struct tdfxfb_i2c_chan *chan = data;
+ struct tdfx_par *par = chan->par;
+
+ return (0 != (tdfx_inl(par, VIDSERPARPORT) & DDC_SCL_IN));
+}
+
+static int tdfxfb_ddc_getsda(void *data)
+{
+ struct tdfxfb_i2c_chan *chan = data;
+ struct tdfx_par *par = chan->par;
+
+ return (0 != (tdfx_inl(par, VIDSERPARPORT) & DDC_SDA_IN));
+}
+
+static int __devinit tdfxfb_setup_ddc_bus(struct tdfxfb_i2c_chan *chan,
+ const char *name, struct device *dev)
+{
+ int rc;
+
+ strlcpy(chan->adapter.name, name, sizeof(chan->adapter.name));
+ chan->adapter.owner = THIS_MODULE;
+ chan->adapter.class = I2C_CLASS_DDC;
+ chan->adapter.algo_data = &chan->algo;
+ chan->adapter.dev.parent = dev;
+ chan->algo.setsda = tdfxfb_ddc_setsda;
+ chan->algo.setscl = tdfxfb_ddc_setscl;
+ chan->algo.getsda = tdfxfb_ddc_getsda;
+ chan->algo.getscl = tdfxfb_ddc_getscl;
+ chan->algo.udelay = 10;
+ chan->algo.timeout = msecs_to_jiffies(500);
+ chan->algo.data = chan;
+
+ i2c_set_adapdata(&chan->adapter, chan);
+
+ rc = i2c_bit_add_bus(&chan->adapter);
+ if (rc == 0)
+ DPRINTK("I2C bus %s registered.\n", name);
+ else
+ chan->par = NULL;
+
+ return rc;
+}
+
+static int __devinit tdfxfb_setup_i2c_bus(struct tdfxfb_i2c_chan *chan,
+ const char *name, struct device *dev)
+{
+ int rc;
+
+ strlcpy(chan->adapter.name, name, sizeof(chan->adapter.name));
+ chan->adapter.owner = THIS_MODULE;
+ chan->adapter.class = I2C_CLASS_TV_ANALOG;
+ chan->adapter.algo_data = &chan->algo;
+ chan->adapter.dev.parent = dev;
+ chan->algo.setsda = tdfxfb_i2c_setsda;
+ chan->algo.setscl = tdfxfb_i2c_setscl;
+ chan->algo.getsda = tdfxfb_i2c_getsda;
+ chan->algo.getscl = tdfxfb_i2c_getscl;
+ chan->algo.udelay = 10;
+ chan->algo.timeout = msecs_to_jiffies(500);
+ chan->algo.data = chan;
+
+ i2c_set_adapdata(&chan->adapter, chan);
+
+ rc = i2c_bit_add_bus(&chan->adapter);
+ if (rc == 0)
+ DPRINTK("I2C bus %s registered.\n", name);
+ else
+ chan->par = NULL;
+
+ return rc;
+}
+
+static void __devinit tdfxfb_create_i2c_busses(struct fb_info *info)
+{
+ struct tdfx_par *par = info->par;
+
+ tdfx_outl(par, VIDINFORMAT, 0x8160);
+ tdfx_outl(par, VIDSERPARPORT, 0xcffc0020);
+
+ par->chan[0].par = par;
+ par->chan[1].par = par;
+
+ tdfxfb_setup_ddc_bus(&par->chan[0], "Voodoo3-DDC", info->dev);
+ tdfxfb_setup_i2c_bus(&par->chan[1], "Voodoo3-I2C", info->dev);
+}
+
+static void tdfxfb_delete_i2c_busses(struct tdfx_par *par)
+{
+ if (par->chan[0].par)
+ i2c_del_adapter(&par->chan[0].adapter);
+ par->chan[0].par = NULL;
+
+ if (par->chan[1].par)
+ i2c_del_adapter(&par->chan[1].adapter);
+ par->chan[1].par = NULL;
+}
+
+static int tdfxfb_probe_i2c_connector(struct tdfx_par *par,
+ struct fb_monspecs *specs)
+{
+ u8 *edid = NULL;
+
+ DPRINTK("Probe DDC Bus\n");
+ if (par->chan[0].par)
+ edid = fb_ddc_read(&par->chan[0].adapter);
+
+ if (edid) {
+ fb_edid_to_monspecs(edid, specs);
+ kfree(edid);
+ return 0;
+ }
+ return 1;
+}
+#endif /* CONFIG_FB_3DFX_I2C */
+
/**
* tdfxfb_probe - Device Initializiation
*
@@ -1182,6 +1395,8 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
struct tdfx_par *default_par;
struct fb_info *info;
int err, lpitch;
+ struct fb_monspecs *specs;
+ bool found;
err = pci_enable_device(pdev);
if (err) {
@@ -1284,13 +1499,49 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
if (hwcursor)
info->fix.smem_len = (info->fix.smem_len - 1024) &
(PAGE_MASK << 1);
-
- if (!mode_option)
+ specs = &info->monspecs;
+ found = false;
+ info->var.bits_per_pixel = 8;
+#ifdef CONFIG_FB_3DFX_I2C
+ tdfxfb_create_i2c_busses(info);
+ err = tdfxfb_probe_i2c_connector(default_par, specs);
+
+ if (!err) {
+ if (specs->modedb == NULL)
+ DPRINTK("Unable to get Mode Database\n");
+ else {
+ const struct fb_videomode *m;
+
+ fb_videomode_to_modelist(specs->modedb,
+ specs->modedb_len,
+ &info->modelist);
+ m = fb_find_best_display(specs, &info->modelist);
+ if (m) {
+ fb_videomode_to_var(&info->var, m);
+ /* fill all other info->var's fields */
+ if (tdfxfb_check_var(&info->var, info) < 0)
+ info->var = tdfx_var;
+ else
+ found = true;
+ }
+ }
+ }
+#endif
+ if (!mode_option && !found)
mode_option = "640x480@60";
- err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
- if (!err || err == 4)
- info->var = tdfx_var;
+ if (mode_option) {
+ err = fb_find_mode(&info->var, info, mode_option,
+ specs->modedb, specs->modedb_len,
+ NULL, info->var.bits_per_pixel);
+ if (!err || err == 4)
+ info->var = tdfx_var;
+ }
+
+ if (found) {
+ fb_destroy_modedb(specs->modedb);
+ specs->modedb = NULL;
+ }
/* maximize virtual vertical length */
lpitch = info->var.xres_virtual * ((info->var.bits_per_pixel + 7) >> 3);
@@ -1315,6 +1566,9 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
return 0;
out_err_iobase:
+#ifdef CONFIG_FB_3DFX_I2C
+ tdfxfb_delete_i2c_busses(default_par);
+#endif
if (default_par->mtrr_handle >= 0)
mtrr_del(default_par->mtrr_handle, info->fix.smem_start,
info->fix.smem_len);
@@ -1379,6 +1633,9 @@ static void __devexit tdfxfb_remove(struct pci_dev *pdev)
struct tdfx_par *par = info->par;
unregister_framebuffer(info);
+#ifdef CONFIG_FB_3DFX_I2C
+ tdfxfb_delete_i2c_busses(par);
+#endif
if (par->mtrr_handle >= 0)
mtrr_del(par->mtrr_handle, info->fix.smem_start,
info->fix.smem_len);
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 0b370aebdbf..421770b5e6a 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -55,6 +55,7 @@ static u16 maxvf __devinitdata; /* maximum vertical frequency */
static u16 maxhf __devinitdata; /* maximum horizontal frequency */
static u16 vbemode __devinitdata; /* force use of a specific VBE mode */
static char *mode_option __devinitdata;
+static u8 dac_width = 6;
static struct uvesafb_ktask *uvfb_tasks[UVESAFB_TASKS_MAX];
static DEFINE_MUTEX(uvfb_lock);
@@ -303,22 +304,10 @@ static void uvesafb_setup_var(struct fb_var_screeninfo *var,
var->blue.offset = 0;
var->transp.offset = 0;
- /*
- * We're assuming that we can switch the DAC to 8 bits. If
- * this proves to be incorrect, we'll update the fields
- * later in set_par().
- */
- if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC) {
- var->red.length = 8;
- var->green.length = 8;
- var->blue.length = 8;
- var->transp.length = 0;
- } else {
- var->red.length = 6;
- var->green.length = 6;
- var->blue.length = 6;
- var->transp.length = 0;
- }
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ var->transp.length = 0;
}
}
@@ -1006,7 +995,7 @@ static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
struct fb_info *info)
{
struct uvesafb_pal_entry entry;
- int shift = 16 - info->var.green.length;
+ int shift = 16 - dac_width;
int err = 0;
if (regno >= info->cmap.len)
@@ -1055,7 +1044,7 @@ static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
static int uvesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
{
struct uvesafb_pal_entry *entries;
- int shift = 16 - info->var.green.length;
+ int shift = 16 - dac_width;
int i, err = 0;
if (info->var.bits_per_pixel == 8) {
@@ -1317,13 +1306,9 @@ setmode:
err = uvesafb_exec(task);
if (err || (task->t.regs.eax & 0xffff) != 0x004f ||
((task->t.regs.ebx & 0xff00) >> 8) != 8) {
- /*
- * We've failed to set the DAC palette format -
- * time to correct var.
- */
- info->var.red.length = 6;
- info->var.green.length = 6;
- info->var.blue.length = 6;
+ dac_width = 6;
+ } else {
+ dac_width = 8;
}
}
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index cc919ae4657..050d432c7d9 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -318,13 +318,16 @@ static int vfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* {hardwarespecific} contains width of RAMDAC
* cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset)
* RAMDAC[X] is programmed to (red, green, blue)
- *
+ *
* Pseudocolor:
- * uses offset = 0 && length = RAMDAC register width.
- * var->{color}.offset is 0
- * var->{color}.length contains widht of DAC
+ * var->{color}.offset is 0 unless the palette index takes less than
+ * bits_per_pixel bits and is stored in the upper
+ * bits of the pixel value
+ * var->{color}.length is set so that 1 << length is the number of available
+ * palette entries
* cmap is not used
* RAMDAC[X] is programmed to (red, green, blue)
+ *
* Truecolor:
* does not use DAC. Usually 3 are present.
* var->{color}.offset contains start of bitfield
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 29e144f81cb..37f08c85060 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -16,10 +16,10 @@
#include <linux/irq.h>
#include <linux/pm.h>
#include <linux/platform_device.h>
-#include <linux/clk.h>
#include <linux/err.h>
#include <linux/delay.h>
-#include <linux/ds1wm.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/ds1wm.h>
#include <asm/io.h>
@@ -89,10 +89,9 @@ struct ds1wm_data {
void __iomem *map;
int bus_shift; /* # of shifts to calc register offsets */
struct platform_device *pdev;
- struct ds1wm_platform_data *pdata;
+ struct mfd_cell *cell;
int irq;
int active_high;
- struct clk *clk;
int slave_present;
void *reset_complete;
void *read_complete;
@@ -215,17 +214,17 @@ static int ds1wm_find_divisor(int gclk)
static void ds1wm_up(struct ds1wm_data *ds1wm_data)
{
- int gclk, divisor;
+ int divisor;
+ struct ds1wm_driver_data *plat = ds1wm_data->cell->driver_data;
- if (ds1wm_data->pdata->enable)
- ds1wm_data->pdata->enable(ds1wm_data->pdev);
+ if (ds1wm_data->cell->enable)
+ ds1wm_data->cell->enable(ds1wm_data->pdev);
- gclk = clk_get_rate(ds1wm_data->clk);
- clk_enable(ds1wm_data->clk);
- divisor = ds1wm_find_divisor(gclk);
+ divisor = ds1wm_find_divisor(plat->clock_rate);
if (divisor == 0) {
dev_err(&ds1wm_data->pdev->dev,
- "no suitable divisor for %dHz clock\n", gclk);
+ "no suitable divisor for %dHz clock\n",
+ plat->clock_rate);
return;
}
ds1wm_write_register(ds1wm_data, DS1WM_CLKDIV, divisor);
@@ -244,10 +243,8 @@ static void ds1wm_down(struct ds1wm_data *ds1wm_data)
ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0);
- if (ds1wm_data->pdata->disable)
- ds1wm_data->pdata->disable(ds1wm_data->pdev);
-
- clk_disable(ds1wm_data->clk);
+ if (ds1wm_data->cell->disable)
+ ds1wm_data->cell->disable(ds1wm_data->pdev);
}
/* --------------------------------------------------------------------- */
@@ -330,13 +327,18 @@ static struct w1_bus_master ds1wm_master = {
static int ds1wm_probe(struct platform_device *pdev)
{
struct ds1wm_data *ds1wm_data;
- struct ds1wm_platform_data *plat;
+ struct ds1wm_driver_data *plat;
struct resource *res;
+ struct mfd_cell *cell;
int ret;
if (!pdev)
return -ENODEV;
+ cell = pdev->dev.platform_data;
+ if (!cell)
+ return -ENODEV;
+
ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL);
if (!ds1wm_data)
return -ENOMEM;
@@ -348,15 +350,18 @@ static int ds1wm_probe(struct platform_device *pdev)
ret = -ENXIO;
goto err0;
}
- ds1wm_data->map = ioremap(res->start, res->end - res->start + 1);
+ ds1wm_data->map = ioremap(res->start, resource_size(res));
if (!ds1wm_data->map) {
ret = -ENOMEM;
goto err0;
}
- plat = pdev->dev.platform_data;
- ds1wm_data->bus_shift = plat->bus_shift;
+ plat = cell->driver_data;
+
+ /* calculate bus shift from mem resource */
+ ds1wm_data->bus_shift = resource_size(res) >> 3;
+
ds1wm_data->pdev = pdev;
- ds1wm_data->pdata = plat;
+ ds1wm_data->cell = cell;
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
@@ -376,26 +381,18 @@ static int ds1wm_probe(struct platform_device *pdev)
if (ret)
goto err1;
- ds1wm_data->clk = clk_get(&pdev->dev, "ds1wm");
- if (IS_ERR(ds1wm_data->clk)) {
- ret = PTR_ERR(ds1wm_data->clk);
- goto err2;
- }
-
ds1wm_up(ds1wm_data);
ds1wm_master.data = (void *)ds1wm_data;
ret = w1_add_master_device(&ds1wm_master);
if (ret)
- goto err3;
+ goto err2;
return 0;
-err3:
- ds1wm_down(ds1wm_data);
- clk_put(ds1wm_data->clk);
err2:
+ ds1wm_down(ds1wm_data);
free_irq(ds1wm_data->irq, ds1wm_data);
err1:
iounmap(ds1wm_data->map);
@@ -434,7 +431,6 @@ static int ds1wm_remove(struct platform_device *pdev)
w1_remove_master_device(&ds1wm_master);
ds1wm_down(ds1wm_data);
- clk_put(ds1wm_data->clk);
free_irq(ds1wm_data->irq, ds1wm_data);
iounmap(ds1wm_data->map);
kfree(ds1wm_data);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 63024145215..5eb8f21da82 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -240,8 +240,6 @@ config ORION5X_WATCHDOG
To compile this driver as a module, choose M here: the
module will be called orion5x_wdt.
-# ARM26 Architecture
-
# AVR32 Architecture
config AT32AP700X_WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 806b3eb0853..7f8c56b14f5 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -42,8 +42,6 @@ obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o
obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o
obj-$(CONFIG_ORION5X_WATCHDOG) += orion5x_wdt.o
-# ARM26 Architecture
-
# AVR32 Architecture
obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index e35d5458923..29e52c237a3 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -197,7 +197,7 @@ static struct miscdevice at91wdt_miscdev = {
.fops = &at91wdt_fops,
};
-static int __init at91wdt_probe(struct platform_device *pdev)
+static int __devinit at91wdt_probe(struct platform_device *pdev)
{
int res;
@@ -214,7 +214,7 @@ static int __init at91wdt_probe(struct platform_device *pdev)
return 0;
}
-static int __exit at91wdt_remove(struct platform_device *pdev)
+static int __devexit at91wdt_remove(struct platform_device *pdev)
{
int res;
@@ -252,7 +252,7 @@ static int at91wdt_resume(struct platform_device *pdev)
static struct platform_driver at91wdt_driver = {
.probe = at91wdt_probe,
- .remove = __exit_p(at91wdt_remove),
+ .remove = __devexit_p(at91wdt_remove),
.shutdown = at91wdt_shutdown,
.suspend = at91wdt_suspend,
.resume = at91wdt_resume,
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index 2dbe83570d6..7ba0b11ec52 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -52,10 +52,10 @@
#define ESB_LOCK_REG 0x68 /* WDT lock register */
/* Memory mapped registers */
-#define ESB_TIMER1_REG BASEADDR + 0x00 /* Timer1 value after each reset */
-#define ESB_TIMER2_REG BASEADDR + 0x04 /* Timer2 value after each reset */
-#define ESB_GINTSR_REG BASEADDR + 0x08 /* General Interrupt Status Register */
-#define ESB_RELOAD_REG BASEADDR + 0x0c /* Reload register */
+#define ESB_TIMER1_REG (BASEADDR + 0x00)/* Timer1 value after each reset */
+#define ESB_TIMER2_REG (BASEADDR + 0x04)/* Timer2 value after each reset */
+#define ESB_GINTSR_REG (BASEADDR + 0x08)/* General Interrupt Status Register */
+#define ESB_RELOAD_REG (BASEADDR + 0x0c)/* Reload register */
/* Lock register bits */
#define ESB_WDT_FUNC (0x01 << 2) /* Watchdog functionality */
@@ -68,6 +68,7 @@
#define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */
/* Reload register bits */
+#define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */
#define ESB_WDT_RELOAD (0x01 << 8) /* prevent timeout */
/* Magic constants */
@@ -87,7 +88,6 @@ static struct platform_device *esb_platform_device;
/* 30 sec default heartbeat (1 < heartbeat < 2*1023) */
#define WATCHDOG_HEARTBEAT 30
static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */
-
module_param(heartbeat, int, 0);
MODULE_PARM_DESC(heartbeat,
"Watchdog heartbeat in seconds. (1<heartbeat<2046, default="
@@ -123,7 +123,7 @@ static int esb_timer_start(void)
esb_unlock_registers();
writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
/* Enable or Enable + Lock? */
- val = 0x02 | (nowayout ? 0x01 : 0x00);
+ val = ESB_WDT_ENABLE | (nowayout ? ESB_WDT_LOCK : 0x00);
pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
spin_unlock(&esb_lock);
return 0;
@@ -143,7 +143,7 @@ static int esb_timer_stop(void)
spin_unlock(&esb_lock);
/* Returns 0 if the timer was disabled, non-zero otherwise */
- return (val & 0x01);
+ return val & ESB_WDT_ENABLE;
}
static void esb_timer_keepalive(void)
@@ -190,18 +190,6 @@ static int esb_timer_set_heartbeat(int time)
return 0;
}
-static int esb_timer_read(void)
-{
- u32 count;
-
- /* This isn't documented, and doesn't take into
- * acount which stage is running, but it looks
- * like a 20 bit count down, so we might as well report it.
- */
- pci_read_config_dword(esb_pci, 0x64, &count);
- return (int)count;
-}
-
/*
* /dev/watchdog handling
*/
@@ -282,7 +270,7 @@ static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
sizeof(ident)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
- return put_user(esb_timer_read(), p);
+ return put_user(0, p);
case WDIOC_GETBOOTSTATUS:
return put_user(triggered, p);
@@ -362,8 +350,6 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl);
static unsigned char __devinit esb_getdevice(void)
{
- u8 val1;
- unsigned short val2;
/*
* Find the PCI device
*/
@@ -371,66 +357,79 @@ static unsigned char __devinit esb_getdevice(void)
esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_ESB_9, NULL);
- if (esb_pci) {
- if (pci_enable_device(esb_pci)) {
- printk(KERN_ERR PFX "failed to enable device\n");
- goto err_devput;
- }
+ if (!esb_pci)
+ return 0;
- if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) {
- printk(KERN_ERR PFX "failed to request region\n");
- goto err_disable;
- }
+ if (pci_enable_device(esb_pci)) {
+ printk(KERN_ERR PFX "failed to enable device\n");
+ goto err_devput;
+ }
- BASEADDR = pci_ioremap_bar(esb_pci, 0);
- if (BASEADDR == NULL) {
- /* Something's wrong here, BASEADDR has to be set */
- printk(KERN_ERR PFX "failed to get BASEADDR\n");
- goto err_release;
- }
+ if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) {
+ printk(KERN_ERR PFX "failed to request region\n");
+ goto err_disable;
+ }
- /*
- * The watchdog has two timers, it can be setup so that the
- * expiry of timer1 results in an interrupt and the expiry of
- * timer2 results in a reboot. We set it to not generate
- * any interrupts as there is not much we can do with it
- * right now.
- *
- * We also enable reboots and set the timer frequency to
- * the PCI clock divided by 2^15 (approx 1KHz).
- */
- pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003);
-
- /* Check that the WDT isn't already locked */
- pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1);
- if (val1 & ESB_WDT_LOCK)
- printk(KERN_WARNING PFX "nowayout already set\n");
-
- /* Set the timer to watchdog mode and disable it for now */
- pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00);
-
- /* Check if the watchdog was previously triggered */
- esb_unlock_registers();
- val2 = readw(ESB_RELOAD_REG);
- triggered = (val2 & (0x01 << 9) >> 9);
-
- /* Reset trigger flag and timers */
- esb_unlock_registers();
- writew((0x11 << 8), ESB_RELOAD_REG);
-
- /* Done */
- return 1;
+ BASEADDR = pci_ioremap_bar(esb_pci, 0);
+ if (BASEADDR == NULL) {
+ /* Something's wrong here, BASEADDR has to be set */
+ printk(KERN_ERR PFX "failed to get BASEADDR\n");
+ goto err_release;
+ }
+
+ /* Done */
+ return 1;
err_release:
- pci_release_region(esb_pci, 0);
+ pci_release_region(esb_pci, 0);
err_disable:
- pci_disable_device(esb_pci);
+ pci_disable_device(esb_pci);
err_devput:
- pci_dev_put(esb_pci);
- }
+ pci_dev_put(esb_pci);
return 0;
}
+static void __devinit esb_initdevice(void)
+{
+ u8 val1;
+ u16 val2;
+
+ /*
+ * Config register:
+ * Bit 5 : 0 = Enable WDT_OUTPUT
+ * Bit 2 : 0 = set the timer frequency to the PCI clock
+ * divided by 2^15 (approx 1KHz).
+ * Bits 1:0 : 11 = WDT_INT_TYPE Disabled.
+ * The watchdog has two timers, it can be setup so that the
+ * expiry of timer1 results in an interrupt and the expiry of
+ * timer2 results in a reboot. We set it to not generate
+ * any interrupts as there is not much we can do with it
+ * right now.
+ */
+ pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003);
+
+ /* Check that the WDT isn't already locked */
+ pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1);
+ if (val1 & ESB_WDT_LOCK)
+ printk(KERN_WARNING PFX "nowayout already set\n");
+
+ /* Set the timer to watchdog mode and disable it for now */
+ pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00);
+
+ /* Check if the watchdog was previously triggered */
+ esb_unlock_registers();
+ val2 = readw(ESB_RELOAD_REG);
+ if (val2 & ESB_WDT_TIMEOUT)
+ triggered = WDIOF_CARDRESET;
+
+ /* Reset WDT_TIMEOUT flag and timers */
+ esb_unlock_registers();
+ writew((ESB_WDT_TIMEOUT | ESB_WDT_RELOAD), ESB_RELOAD_REG);
+
+ /* And set the correct timeout value */
+ esb_timer_set_heartbeat(heartbeat);
+}
+
static int __devinit esb_probe(struct platform_device *dev)
{
int ret;
@@ -441,13 +440,17 @@ static int __devinit esb_probe(struct platform_device *dev)
/* Check that the heartbeat value is within it's range;
if not reset to the default */
- if (esb_timer_set_heartbeat(heartbeat)) {
- esb_timer_set_heartbeat(WATCHDOG_HEARTBEAT);
+ if (heartbeat < 0x1 || heartbeat > 2 * 0x03ff) {
+ heartbeat = WATCHDOG_HEARTBEAT;
printk(KERN_INFO PFX
"heartbeat value must be 1<heartbeat<2046, using %d\n",
heartbeat);
}
+ /* Initialize the watchdog and make sure it does not run */
+ esb_initdevice();
+
+ /* Register the watchdog so that userspace has access to it */
ret = misc_register(&esb_miscdev);
if (ret != 0) {
printk(KERN_ERR PFX
@@ -455,7 +458,6 @@ static int __devinit esb_probe(struct platform_device *dev)
WATCHDOG_MINOR, ret);
goto err_unmap;
}
- esb_timer_stop();
printk(KERN_INFO PFX
"initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
BASEADDR, heartbeat, nowayout);
@@ -463,11 +465,8 @@ static int __devinit esb_probe(struct platform_device *dev)
err_unmap:
iounmap(BASEADDR);
-/* err_release: */
pci_release_region(esb_pci, 0);
-/* err_disable: */
pci_disable_device(esb_pci);
-/* err_devput: */
pci_dev_put(esb_pci);
return ret;
}
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index 74c92d38411..ae3832110ac 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -221,7 +221,7 @@ static struct miscdevice ks8695wdt_miscdev = {
.fops = &ks8695wdt_fops,
};
-static int __init ks8695wdt_probe(struct platform_device *pdev)
+static int __devinit ks8695wdt_probe(struct platform_device *pdev)
{
int res;
@@ -238,7 +238,7 @@ static int __init ks8695wdt_probe(struct platform_device *pdev)
return 0;
}
-static int __exit ks8695wdt_remove(struct platform_device *pdev)
+static int __devexit ks8695wdt_remove(struct platform_device *pdev)
{
int res;
@@ -276,7 +276,7 @@ static int ks8695wdt_resume(struct platform_device *pdev)
static struct platform_driver ks8695wdt_driver = {
.probe = ks8695wdt_probe,
- .remove = __exit_p(ks8695wdt_remove),
+ .remove = __devexit_p(ks8695wdt_remove),
.shutdown = ks8695wdt_shutdown,
.suspend = ks8695wdt_suspend,
.resume = ks8695wdt_resume,
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index aa5ad6e33f0..f2713851aaa 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -258,7 +258,7 @@ static const struct file_operations omap_wdt_fops = {
.release = omap_wdt_release,
};
-static int __init omap_wdt_probe(struct platform_device *pdev)
+static int __devinit omap_wdt_probe(struct platform_device *pdev)
{
struct resource *res, *mem;
struct omap_wdt_dev *wdev;
@@ -367,7 +367,7 @@ static void omap_wdt_shutdown(struct platform_device *pdev)
omap_wdt_disable(wdev);
}
-static int omap_wdt_remove(struct platform_device *pdev)
+static int __devexit omap_wdt_remove(struct platform_device *pdev)
{
struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -426,7 +426,7 @@ static int omap_wdt_resume(struct platform_device *pdev)
static struct platform_driver omap_wdt_driver = {
.probe = omap_wdt_probe,
- .remove = omap_wdt_remove,
+ .remove = __devexit_p(omap_wdt_remove),
.shutdown = omap_wdt_shutdown,
.suspend = omap_wdt_suspend,
.resume = omap_wdt_resume,
diff --git a/drivers/watchdog/orion5x_wdt.c b/drivers/watchdog/orion5x_wdt.c
index e81441f103d..7529616739d 100644
--- a/drivers/watchdog/orion5x_wdt.c
+++ b/drivers/watchdog/orion5x_wdt.c
@@ -42,7 +42,17 @@ static unsigned int wdt_tclk;
static unsigned long wdt_status;
static spinlock_t wdt_lock;
-static void wdt_enable(void)
+static void orion5x_wdt_ping(void)
+{
+ spin_lock(&wdt_lock);
+
+ /* Reload watchdog duration */
+ writel(wdt_tclk * heartbeat, WDT_VAL);
+
+ spin_unlock(&wdt_lock);
+}
+
+static void orion5x_wdt_enable(void)
{
u32 reg;
@@ -69,7 +79,7 @@ static void wdt_enable(void)
spin_unlock(&wdt_lock);
}
-static void wdt_disable(void)
+static void orion5x_wdt_disable(void)
{
u32 reg;
@@ -101,7 +111,7 @@ static int orion5x_wdt_open(struct inode *inode, struct file *file)
if (test_and_set_bit(WDT_IN_USE, &wdt_status))
return -EBUSY;
clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
- wdt_enable();
+ orion5x_wdt_enable();
return nonseekable_open(inode, file);
}
@@ -122,18 +132,28 @@ static ssize_t orion5x_wdt_write(struct file *file, const char *data,
set_bit(WDT_OK_TO_CLOSE, &wdt_status);
}
}
- wdt_enable();
+ orion5x_wdt_ping();
}
return len;
}
-static struct watchdog_info ident = {
+static int orion5x_wdt_settimeout(int new_time)
+{
+ if ((new_time <= 0) || (new_time > wdt_max_duration))
+ return -EINVAL;
+
+ /* Set new watchdog time to be used when
+ * orion5x_wdt_enable() or orion5x_wdt_ping() is called. */
+ heartbeat = new_time;
+ return 0;
+}
+
+static const struct watchdog_info ident = {
.options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING,
.identity = "Orion5x Watchdog",
};
-
static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
@@ -152,7 +172,7 @@ static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd,
break;
case WDIOC_KEEPALIVE:
- wdt_enable();
+ orion5x_wdt_ping();
ret = 0;
break;
@@ -161,12 +181,11 @@ static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd,
if (ret)
break;
- if (time <= 0 || time > wdt_max_duration) {
+ if (orion5x_wdt_settimeout(time)) {
ret = -EINVAL;
break;
}
- heartbeat = time;
- wdt_enable();
+ orion5x_wdt_ping();
/* Fall through */
case WDIOC_GETTIMEOUT:
@@ -187,7 +206,7 @@ static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd,
static int orion5x_wdt_release(struct inode *inode, struct file *file)
{
if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
- wdt_disable();
+ orion5x_wdt_disable();
else
printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
"timer will not stop\n");
@@ -230,7 +249,7 @@ static int __devinit orion5x_wdt_probe(struct platform_device *pdev)
orion5x_wdt_miscdev.parent = &pdev->dev;
wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk;
- if (heartbeat <= 0 || heartbeat > wdt_max_duration)
+ if (orion5x_wdt_settimeout(heartbeat))
heartbeat = wdt_max_duration;
ret = misc_register(&orion5x_wdt_miscdev);
@@ -247,7 +266,7 @@ static int __devexit orion5x_wdt_remove(struct platform_device *pdev)
int ret;
if (test_bit(WDT_IN_USE, &wdt_status)) {
- wdt_disable();
+ orion5x_wdt_disable();
clear_bit(WDT_IN_USE, &wdt_status);
}
@@ -258,9 +277,16 @@ static int __devexit orion5x_wdt_remove(struct platform_device *pdev)
return ret;
}
+static void orion5x_wdt_shutdown(struct platform_device *pdev)
+{
+ if (test_bit(WDT_IN_USE, &wdt_status))
+ orion5x_wdt_disable();
+}
+
static struct platform_driver orion5x_wdt_driver = {
.probe = orion5x_wdt_probe,
.remove = __devexit_p(orion5x_wdt_remove),
+ .shutdown = orion5x_wdt_shutdown,
.driver = {
.owner = THIS_MODULE,
.name = "orion5x_wdt",
@@ -285,10 +311,11 @@ MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>");
MODULE_DESCRIPTION("Orion5x Processor Watchdog");
module_param(heartbeat, int, 0);
-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds");
+MODULE_PARM_DESC(heartbeat, "Initial watchdog heartbeat in seconds");
module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
index 5d3b1a8e28b..a38fa4907c9 100644
--- a/drivers/watchdog/wdrtas.c
+++ b/drivers/watchdog/wdrtas.c
@@ -106,6 +106,8 @@ static int wdrtas_set_interval(int interval)
return result;
}
+#define WDRTAS_SP_SPI_LEN 4
+
/**
* wdrtas_get_interval - returns the current watchdog interval
* @fallback_value: value (in seconds) to use, if the RTAS call fails
@@ -119,10 +121,17 @@ static int wdrtas_set_interval(int interval)
static int wdrtas_get_interval(int fallback_value)
{
long result;
- char value[4];
+ char value[WDRTAS_SP_SPI_LEN];
+ spin_lock(&rtas_data_buf_lock);
+ memset(rtas_data_buf, 0, WDRTAS_SP_SPI_LEN);
result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL,
- WDRTAS_SP_SPI, (void *)__pa(&value), 4);
+ WDRTAS_SP_SPI, __pa(rtas_data_buf),
+ WDRTAS_SP_SPI_LEN);
+
+ memcpy(value, rtas_data_buf, WDRTAS_SP_SPI_LEN);
+ spin_unlock(&rtas_data_buf_lock);
+
if (value[0] != 0 || value[1] != 2 || value[3] != 0 || result < 0) {
printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog "
"timeout (%li). Continuing\n", result);
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 526187c8a12..8ac9cddac57 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -37,7 +37,7 @@ config XEN_COMPAT_XENFS
The old xenstore userspace tools expect to find "xenbus"
under /proc/xen, but "xenbus" is now found at the root of the
xenfs filesystem. Selecting this causes the kernel to create
- the compatibilty mount point /proc/xen if it is running on
+ the compatibility mount point /proc/xen if it is running on
a xen platform.
If in doubt, say yes.
diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c
index 974f56d1ebe..bdfd584ad85 100644
--- a/drivers/xen/cpu_hotplug.c
+++ b/drivers/xen/cpu_hotplug.c
@@ -10,7 +10,7 @@ static void enable_hotplug_cpu(int cpu)
if (!cpu_present(cpu))
arch_register_cpu(cpu);
- cpu_set(cpu, cpu_present_map);
+ set_cpu_present(cpu, true);
}
static void disable_hotplug_cpu(int cpu)
@@ -18,32 +18,44 @@ static void disable_hotplug_cpu(int cpu)
if (cpu_present(cpu))
arch_unregister_cpu(cpu);
- cpu_clear(cpu, cpu_present_map);
+ set_cpu_present(cpu, false);
}
-static void vcpu_hotplug(unsigned int cpu)
+static int vcpu_online(unsigned int cpu)
{
int err;
char dir[32], state[32];
- if (!cpu_possible(cpu))
- return;
-
sprintf(dir, "cpu/%u", cpu);
err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state);
if (err != 1) {
printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
- return;
+ return err;
}
- if (strcmp(state, "online") == 0) {
+ if (strcmp(state, "online") == 0)
+ return 1;
+ else if (strcmp(state, "offline") == 0)
+ return 0;
+
+ printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n", state, cpu);
+ return -EINVAL;
+}
+static void vcpu_hotplug(unsigned int cpu)
+{
+ if (!cpu_possible(cpu))
+ return;
+
+ switch (vcpu_online(cpu)) {
+ case 1:
enable_hotplug_cpu(cpu);
- } else if (strcmp(state, "offline") == 0) {
+ break;
+ case 0:
(void)cpu_down(cpu);
disable_hotplug_cpu(cpu);
- } else {
- printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n",
- state, cpu);
+ break;
+ default:
+ break;
}
}
@@ -64,12 +76,20 @@ static void handle_vcpu_hotplug_event(struct xenbus_watch *watch,
static int setup_cpu_watcher(struct notifier_block *notifier,
unsigned long event, void *data)
{
+ int cpu;
static struct xenbus_watch cpu_watch = {
.node = "cpu",
.callback = handle_vcpu_hotplug_event};
(void)register_xenbus_watch(&cpu_watch);
+ for_each_possible_cpu(cpu) {
+ if (vcpu_online(cpu) == 0) {
+ (void)cpu_down(cpu);
+ cpu_clear(cpu, cpu_present_map);
+ }
+ }
+
return NOTIFY_DONE;
}
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 0d61db1e7b4..4b5b84837ee 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -62,14 +62,15 @@ static int xen_suspend(void *data)
gnttab_resume();
xen_mm_unpin_all();
- sysdev_resume();
-
if (!*cancelled) {
xen_irq_resume();
xen_console_resume();
xen_timer_resume();
}
+ sysdev_resume();
+ device_power_up(PMSG_RESUME);
+
return 0;
}
diff --git a/firmware/.gitignore b/firmware/.gitignore
index f89a21fffbf..d9c69017bc9 100644
--- a/firmware/.gitignore
+++ b/firmware/.gitignore
@@ -3,3 +3,4 @@
*.bin
*.csp
*.dsp
+ihex2fw
diff --git a/firmware/Makefile b/firmware/Makefile
index baf5ae45642..142c17ab9e5 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -32,15 +32,26 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \
adaptec/starfire_tx.bin
fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin
fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw
+fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-4.6.17.fw \
+ bnx2/bnx2-rv2p-09-4.6.15.fw \
+ bnx2/bnx2-mips-06-4.6.16.fw \
+ bnx2/bnx2-rv2p-06-4.6.16.fw
fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin
fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin
fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \
cxgb3/t3c_psram-1.1.0.bin \
cxgb3/t3fw-7.1.0.bin
+fw-shipped-$(CONFIG_DVB_AV7110) += av7110/bootcode.bin
fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
e100/d102e_ucode.bin
+fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin
fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin
+fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
+ advansys/3550.bin advansys/38C0800.bin
+fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \
+ qlogic/12160.bin
+fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.bin
fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin
fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp
fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \
@@ -51,6 +62,7 @@ fw-shipped-$(CONFIG_SND_SB16_CSP) += sb16/mulaw_main.csp sb16/alaw_main.csp \
sb16/ima_adpcm_capture.csp
fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \
yamaha/ds1e_ctrl.fw
+fw-shipped-$(CONFIG_SND_WAVEFRONT) += yamaha/yss225_registers.bin
fw-shipped-$(CONFIG_TEHUTI) += tehuti/bdx.bin
fw-shipped-$(CONFIG_TIGON3) += tigon/tg3.bin tigon/tg3_tso.bin \
tigon/tg3_tso5.bin
@@ -107,10 +119,10 @@ quiet_cmd_ihex = IHEX $@
cmd_ihex = $(OBJCOPY) -Iihex -Obinary $< $@
quiet_cmd_ihex2fw = IHEX2FW $@
- cmd_ihex2fw = $(objtree)/scripts/ihex2fw $< $@
+ cmd_ihex2fw = $(objtree)/$(obj)/ihex2fw $< $@
quiet_cmd_h16tofw = H16TOFW $@
- cmd_h16tofw = $(objtree)/scripts/ihex2fw -w $< $@
+ cmd_h16tofw = $(objtree)/$(obj)/ihex2fw -w $< $@
quiet_cmd_fwbin = MK_FW $@
cmd_fwbin = FWNAME="$(patsubst firmware/%.gen.S,%,$@)"; \
@@ -169,15 +181,27 @@ $(patsubst %,$(obj)/%.gen.o, $(fw-external-y)): $(obj)/%.gen.o: $(fwdir)/%
$(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %)
$(call cmd,ihex)
+# Don't depend on ihex2fw if we're installing and it already exists.
+# Putting it after | in the dependencies doesn't seem sufficient when
+# we're installing after a cross-compile, because ihex2fw has dependencies
+# on stuff like /usr/lib/gcc/ppc64-redhat-linux/4.3.0/include/stddef.h and
+# thus wants to be rebuilt. Which it can't be, if the prebuilt kernel tree
+# is exported read-only for someone to run 'make install'.
+ifeq ($(INSTALL):$(wildcard $(obj)/ihex2fw),install:$(obj)/ihex2fw)
+ihex2fw_dep :=
+else
+ihex2fw_dep := $(obj)/ihex2fw
+endif
+
# .HEX is also Intel HEX, but where the offset and length in each record
# is actually meaningful, because the firmware has to be loaded in a certain
# order rather than as a single binary blob. Thus, we convert them into our
# more compact binary representation of ihex records (<linux/ihex.h>)
-$(obj)/%.fw: $(obj)/%.HEX | $(objtree)/$(obj)/$$(dir %)
+$(obj)/%.fw: $(obj)/%.HEX $(ihex2fw_dep) | $(objtree)/$(obj)/$$(dir %)
$(call cmd,ihex2fw)
# .H16 is our own modified form of Intel HEX, with 16-bit length for records.
-$(obj)/%.fw: $(obj)/%.H16 | $(objtree)/$(obj)/$$(dir %)
+$(obj)/%.fw: $(obj)/%.H16 $(ihex2fw_dep) | $(objtree)/$(obj)/$$(dir %)
$(call cmd,h16tofw)
$(firmware-dirs):
@@ -194,3 +218,5 @@ targets := $(fw-shipped-) $(patsubst $(obj)/%,%, \
# Without this, built-in.o won't be created when it's empty, and the
# final vmlinux link will fail.
obj-n := dummy
+
+hostprogs-y := ihex2fw
diff --git a/firmware/README.AddingFirmware b/firmware/README.AddingFirmware
new file mode 100644
index 00000000000..e24cd8986d8
--- /dev/null
+++ b/firmware/README.AddingFirmware
@@ -0,0 +1,34 @@
+
+ DO NOT ADD FIRMWARE TO THIS DIRECTORY.
+ ======================================
+
+This directory is only here to contain firmware images extracted from old
+device drivers which predate the common use of request_firmware().
+
+As we update those drivers to use request_firmware() and keep a clean
+separation between code and firmware, we put the extracted firmware
+here.
+
+This directory is _NOT_ for adding arbitrary new firmware images. The
+place to add those is the separate linux-firmware repository:
+
+ git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git
+
+That repository contains all these firmware images which have been
+extracted from older drivers, as well various new firmware images which
+we were never permitted to include in a GPL'd work, but which we _have_
+been permitted to redistribute under separate cover.
+
+To submit firmware to that repository, please send either a git binary
+diff or preferably a git pull request to:
+ David Woodhouse <dwmw2@infradead.org>
+
+Your commit should include an update to the WHENCE file clearly
+identifying the licence under which the firmware is available, and
+that it is redistributable. If the licence is long and involved, it's
+permitted to include it in a separate file and refer to it from the
+WHENCE file.
+
+Ideally, your commit should contain a Signed-Off-By: from someone
+authoritative on the licensing of the firmware in question (i.e. from
+within the company that owns the code).
diff --git a/firmware/WHENCE b/firmware/WHENCE
index 3814d7d4266..10f61c9e5a8 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -8,6 +8,24 @@ kernel.
--------------------------------------------------------------------------
+Driver: ambassador -- Madge Ambassador (Collage PCI 155 Server) ATM NIC.
+
+File: firmware/atmsar11.fw
+
+Licence: Allegedly GPLv2+, but no source visible. Marked:
+
+ Madge Ambassador ATM Adapter microcode.
+ Copyright (C) 1995-1999 Madge Networks Ltd.
+
+ This microcode data is placed under the terms of the GNU General
+ Public License. The GPL is contained in /usr/doc/copyright/GPL on a
+ Debian system and in the file COPYING in the Linux kernel source.
+
+ We would prefer you not to distribute modified versions without
+ consultation and not to ask for assembly/other microcode source.
+
+--------------------------------------------------------------------------
+
Driver: korg1212 -- Korg 1212 IO audio device
File: korg/k1212.dsp
@@ -45,6 +63,32 @@ Found alsa-firmware package in hex form, with the following comment:
--------------------------------------------------------------------------
+Driver: SCSI_ADVANSYS - AdvanSys SCSI
+
+File: advansys/mcode.bin
+File: advansys/3550.bin
+File: advansys/38C0800.bin
+File: advansys/38C1600.bin
+
+Licence: BSD, no source available.
+
+Found in hex form in kernel source.
+
+--------------------------------------------------------------------------
+
+Driver: SCSI_QLOGIC_1280 - Qlogic QLA 1240/1x80/1x160 SCSI support
+
+File: qlogic/1040.bin
+File: qlogic/1280.bin
+File: qlogic/12160.bin
+
+Licence: Allegedly GPLv2+, but no source visible. Marked:
+
+ QLOGIC LINUX SOFTWARE
+ QLogic ISP1280/ device driver for Linux 2.2.x and 2.4.x
+ Copyright (C) 2001 Qlogic Corporation (www.qlogic.com)
+
+--------------------------------------------------------------------------
Driver: smctr -- SMC ISA/MCA Token Ring adapter
File: tr_smctr.bin
@@ -543,3 +587,64 @@ Licence: Allegedly GPL, but no source visible. Marked:
Found in hex form in kernel source.
--------------------------------------------------------------------------
+
+Driver: SCSI_QLOGICPTI - PTI Qlogic, ISP Driver
+
+File: qlogic/isp1000.bin
+
+Licence: Unknown
+
+Found in hex form in kernel source.
+
+--------------------------------------------------------------------------
+
+Driver: MYRI_SBUS - MyriCOM Gigabit Ethernet
+
+File: myricom/lanai.bin
+
+Licence: Unknown
+
+Found in hex form in kernel source.
+
+--------------------------------------------------------------------------
+
+Driver: BNX2 - Broadcom NetXtremeII
+
+File: bnx2/bnx2-mips-06-4.6.16.fw
+File: bnx2/bnx2-rv2p-06-4.6.16.fw
+File: bnx2/bnx2-mips-09-4.6.17.fw
+File: bnx2/bnx2-rv2p-09-4.6.15.fw
+
+Licence:
+
+ This file contains firmware data derived from proprietary unpublished
+ source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+
+ Permission is hereby granted for the distribution of this firmware data
+ in hexadecimal or equivalent format, provided this copyright notice is
+ accompanying it.
+
+Found in hex form in kernel source.
+
+--------------------------------------------------------------------------
+
+Driver: DVB AV7110 -- AV7110 cards
+
+File: av7110/bootcode.bin
+
+Licence: GPLv2 or later
+
+ARM assembly source code available at http://www.linuxtv.org/downloads/firmware/Boot.S
+
+--------------------------------------------------------------------------
+
+Driver: wavefront - ISA WaveFront sound card
+
+File: yamaha/yss225_registers.bin
+
+Licence: Allegedly GPLv2+, but no source visible.
+
+Found in hex form in kernel source, with the following comment:
+ Copyright (c) 1998-2002 by Paul Davis <pbd@op.net>
+
+--------------------------------------------------------------------------
diff --git a/firmware/advansys/3550.bin.ihex b/firmware/advansys/3550.bin.ihex
new file mode 100644
index 00000000000..6809b0d84e4
--- /dev/null
+++ b/firmware/advansys/3550.bin.ihex
@@ -0,0 +1,317 @@
+:10000000DD2DD504000000F200F0001618E400FC1D
+:10001000010048E4BE18188003F6020000FAFFFF52
+:10002000280E9EE7FF0082E700EA00F601E609E7F6
+:1000300055F001F601FA08000300040018F410005E
+:1000400000EC85F0BC00D5F08E0C385400E61EF0B4
+:1000500086F0B4009857D0010C1C3E1C0C00BB006D
+:10006000AA18028032F001FC880CC6120213184054
+:10007000005701EA3C006C016E0104123E570080FB
+:1000800003E6B600C00001013E01DA0F221008129B
+:10009000024AB95403581B8030E44BE4200032007C
+:1000A0003E00800024013C0168016A017001720178
+:1000B000740176017801620A920C2C102E1006133E
+:1000C0004C1CBB553C5604804AE402EE5BF0B1F098
+:1000D00003F706F703FC0F004000BE000001B00864
+:1000E00030136415321C381C4E1C10440248004C5E
+:1000F00004EA5DF004F602FC0500340036009800C6
+:10010000CC0020014E014E0B1E0E0C100A120413DF
+:100110004013301C004EBD56068300DC05F009F08C
+:1001200059F0A7F0B8F00EF70600190033009B0055
+:10013000A400B500BA00D000E100E700DE03560AD3
+:10014000140E021004100A1036100A131213521360
+:1001500010151415AC16201C341C361C08443844E9
+:1001600091440A454846014868548355B0570158A0
+:10017000835905E60BF00CF05CF04BF404F805F83D
+:1001800002FA03FA04FC05FC07000A000D001C003B
+:100190009E00A800AA00B900E00022012601790112
+:1001A0007A01C001C2017C025A03EA04E807680828
+:1001B0006908BA08E909060B3A0E00101A10ED108A
+:1001C000F11006120C1316131E1382134214D614C8
+:1001D0008A15C617D2176B18121C461C9C32004099
+:1001E0000E47484741488948804C00544455E555DE
+:1001F00014567757BF57405C0680089003A1FE9CB9
+:10020000F02902FEB80CFF100000D0FECC1800CF81
+:10021000FE8001FF030000FE9315FE0F05FF38006E
+:1002200000FE572400FE48004FFF04000010FF09A5
+:100230000000FF080101FF08FFFFFF270000FF107B
+:10024000FFFFFF0F0000FE7856FE3412FF21000072
+:10025000FE04F7CF2A670B01FECE0EFE04F7CF6730
+:100260000B3C2AFE3DF0FE0202FE20F09CFE91F0C7
+:10027000FEF001FE90F0FEF001FE8FF09C05513B78
+:1002800002FED40C01FE440DFEDD12FEFC10FE2821
+:100290001C05FEA600FED3124718FEA600B5FE48B8
+:1002A000F0FE8602FE49F0FEA002FE4AF0FEBE020B
+:1002B000FE46F0FE5002FE47F0FE5602FE43F0FE00
+:1002C0004402FE44F0FE4802FE45F0FE4C02170BCD
+:1002D000A0170618960229FE001CDEFE021CDDFE99
+:1002E0001E1CFEE91001FE2017FEE710FE06FCC7EB
+:1002F0000A6B019E0229144D379701FE640F0A6BA9
+:100300000182FEBD100A6B0182FEAD10FE161CFEBE
+:10031000581C170618962A2529FE3DF0FE020221D8
+:10032000FE9402FE5A1CEAFE141C14FE300037979D
+:1003300001FE540F1706189602D01E20071034FE37
+:10034000691017061896FE04EC20463D1220FE05A3
+:10035000F6C701FE5216094A4C35112D3C8A01E6BA
+:1003600002290A40010E07005D016FFE1810FE41D0
+:10037000580A99010EFEC85464FE0C0301E60229D6
+:100380002A46FE02E827F8FE9E43F7FE27F0FEDC31
+:1003900001FE074BFE20F09CFE401C25D2FE26F0FD
+:1003A000FE5603FEA0F0FE4403FE11F09CFEEF108B
+:1003B000FE9FF0FE6403EB0FFE1100025A2AFE4876
+:1003C0001CEB09041DFE1813231E98AC12980A405A
+:1003D000010EAC7501FEBC1511CA25D2FE01F0D28A
+:1003E000FE82F0FE9203EC11FEE40065FEA40325FC
+:1003F000321FFEB4030143FE06F0FEC4038D81FEEE
+:100400000AF0FE7A060222056B2816FEF604142C6A
+:1004100001338FFE660202D1EB2A671AFE671BF8D2
+:10042000F7FE481C70016E870A40010E070016D3C4
+:100430000ACA010E7460597627056B28FE10121443
+:100440002C01338FFE660202D1BC7DBD7F25226563
+:10045000FE3C041FFE380468FEA000FE9B57FE4EC3
+:10046000122BFF02001001081FFEE0042B01081FE1
+:1004700022302ED5FE4C44FE4C1260FE4448132C14
+:10048000FE4C5464D3467627FAEFFE621309041D2E
+:10049000FE2A132F077EA5FE2010132CFE4C546459
+:1004A000D3FAEF8609041DFE08132F077E6E090498
+:1004B0001DFE1C1214920904063B14C401338FFE66
+:1004C000700C02222B11FEE600FE1C90F903149220
+:1004D00001330229FE425B671AFE4659F8F7FE8790
+:1004E00080FE31E44F09040BFE7813FE2080071ACA
+:1004F000FE7012490406FE601305FEA2002816FED7
+:100500008005FE31E46A49040BFE4A1305FEA00093
+:1005100028FE42125E01082532F1010826FE9805E8
+:1005200011FEE3002349FE4AF0FE6A05FE49F0FE93
+:1005300064058324FE2100A124FE2200A0244CFE99
+:100540000948010826FE9805FEE2084904C53B015A
+:1005500086240612CC37FE270109041DFE2212470D
+:1005600001A714920904063B14C401338FFE700CDA
+:10057000022205FE9C0028FE3E12055028FE36137E
+:100580004701A726FE08060A06490419FE02125F63
+:1005900001FEAA141FFEFE05119A014311FEE5009B
+:1005A0000550B40C5005C628FE6212053F28FE5ABD
+:1005B0001301FE141801FE6618FE4348B719136CA8
+:1005C000FF020057488B1C3D85B7694701A726FEEF
+:1005D000720649041BDF890A4D01FED8141FFE680C
+:1005E00006119A014311FEE500053FB40C3F1706C2
+:1005F00001A7EC7270016E8711FEE200010825323E
+:10060000FE0AF0FEA6068CFE5C07FE06F0FE6407FE
+:100610008D81022209040BFE2E12151A0108150005
+:1006200001081500010815000108FE99A40108152C
+:100630000002FE320861041BFE381209041B6E150D
+:10064000FE1B000108150001081500010815000136
+:100650000815060108150002D9664CFE3A555FFEE2
+:100660009A814B1DBAFE32070A1DFE096FAFFECA02
+:1006700045FE3212622C85667B01082532FE0AF0A7
+:10068000FE32078D818CFE5C070222014302FE8A46
+:1006900006151902FE8A06FE9CF7D4FE2C90FEAECB
+:1006A0009077FECA070C541855094A6A351E200770
+:1006B00010FE0E1274FE808037206327FE0610FEA7
+:1006C00083E7C4A1FE0340094A4F3501A8ADFE1FD0
+:1006D00040125801A5FE0850FE8A50FE4451FEC645
+:1006E0005183FBFE8A900C521853FE0C90FE8E90A4
+:1006F000FE4050FEC2500C39183AFE4A1009046AF6
+:10070000FE2A12FE2C90FEAE900C54185509044F90
+:100710008501A8FE1F801258FE4490FEC6900C561C
+:100720001857FBFE8A900C521853FE4090FEC29060
+:100730000C39183A0C38184E094A19352A13FE4E4E
+:100740001165FE4808FE9EF0FE5C08B116322A7361
+:10075000DDB8FE8008B9FE9E088CFE7408FE06F027
+:10076000FE7A088D8102220143FEC9101519FEC9C7
+:1007700010610406FE101261040B4509040BFE68AB
+:1007800012FE2E1C02FE240A6104064561040BFEC3
+:100790005212FE2C1CFEAAF0FE1E09FEACF0FEBE9C
+:1007A00008FE8A10AAFEF310FEADF0FECA0802FE93
+:1007B000240AABFEE710FE2BF09DE91CFE00FEFEB6
+:1007C0001C12B5FED2F09DFE76181C1A169D05CBA4
+:1007D0001C06169DB86DB96DAAABFEB110705E2BEC
+:1007E000149201330FFE3500FE01F05A0F7C025ABD
+:1007F000FE74181CFE00F8166D671B01FE440D3BCD
+:1008000001E61E2774671A026D09040B21FE060A11
+:1008100009046AFE8212090419FE66131E58ACFC14
+:10082000FE8380FEC844FE2E13FE0491FE86916373
+:1008300027FE4059FEC15977D7055431550C7B1816
+:100840007CBE54BF5501A8AD63271258C038C14EB5
+:1008500079566857F4F5FE04FA38FE05FA4E01A5FC
+:10086000A2230C7B0C7C79566857FE1210090419E0
+:1008700016D77939683A0904FEF700350552315325
+:10088000FE1058FE9158FE1459FE9559026D090448
+:100890001916D70904FEF70035FE3A55FE19815F97
+:1008A000FE1090FE9290FED7102F079B16FEC608F2
+:1008B000119B09040BFE14130539313A77FEC60863
+:1008C000FE0C58FE8D58026D2347FE1980DE090488
+:1008D0000BFE1A12FE6C19FE1941E9B5FED1F0D9D2
+:1008E000147A01330FFE4400FE8E10FE6C19BE39DF
+:1008F000FEED19BF3AFE0C51FE8E51E91CFE00FFC1
+:1009000034FE7410B5FED2F0FEB20AFE76181C1A40
+:100910008405CB1C06FE08130FFE1600025AFED1FA
+:10092000F0FEC40A147A01330FFE1700FE4210FED7
+:10093000CEF0FECA0AFE3C10FECDF0FED60A0FFE37
+:100940002200025AFECBF0FEE20A0FFE2400025AF9
+:10095000FED0F0FEEC0A0F93DCFECFF0FEF60A0F9D
+:100960004CFE1010FECCF0D96104193B0FFE1200B2
+:100970002A13FE4E1165FE0C0BFE9EF0FE200BB1FD
+:1009800016322A73DDB822B9222AEC65FE2C0B251B
+:10099000328CFE480B8D81B8D4B9D402220143FEBB
+:1009A000DB1011FEE800AAAB70BC7DBD7FFE89F0B4
+:1009B00022302ED8BC7DBD7F01081F22302ED6B13B
+:1009C000450FFE4200025A7806FE814916FE380C99
+:1009D00009040BFE44130F004B0BFE54124BFE2870
+:1009E0000021FEA60C0A40010E07005D3EFE280015
+:1009F000FEE21001E701E80A9901FE320E59112DBD
+:100A0000016F02290FFE44004B0BDF3E0BFEB410BA
+:100A100001863E0BFEAA100186FE1982FE3446A313
+:100A20003E0B0FFE4300FE9610094A0B3501E7010D
+:100A3000E859112D016F670B593C8A02FE2A030900
+:100A4000040B843E0B0F00FE5C1061041BFE581269
+:100A500009041BFE5013FE1C1CFE9DF0FE5C0CFEE8
+:100A60001C1CFE9DF0FE620C094A1B35FEA9100FEE
+:100A7000FE1500FE04E60B5F5C0FFE1300FE101077
+:100A80000FFE4700A10FFE4100A00FFE240087AA21
+:100A9000AB70056B2821D15FFE04E61BFE9D41FE75
+:100AA0001C425901DA0229EA140B3795A914FE31C8
+:100AB00000379701FE540F02D03CFE06ECC9EE3E13
+:100AC0001DFECE45343CFE06EAC9FE474B89FE7545
+:100AD000570551FE9856FE38120A42010EFE444850
+:100AE0004609041DFE1A130A40010E47FE41580A2A
+:100AF00099010EFE49548EFE2A0D02FE2A030A5168
+:100B0000FEEE14EE3E1DFECE45343CFECE47FEAD5D
+:100B10001302291E200710FE9E1223124D1294125A
+:100B2000CE1E2D47372DB1E0FEBCF0FEEC0D1306B6
+:100B3000124D01FEE21505FE380131FE3A0177FE45
+:100B4000F00DFE02ECCE62005DFE04EC2046FE05D8
+:100B5000F6FE340101FE5216FBFE48F40DFE18139A
+:100B6000AFFE02EACE627AFEC513141B3795A95C6C
+:100B700005FE38011CFEF0FF0CFE600105FE3A0187
+:100B80000CFE62013D12202406122D112D8A13063F
+:100B90000323031E4DFEF7121E94AC1294077AFE37
+:100BA0007113FE241C141A3795A9FED910B6FE0342
+:100BB000DCFE7357FE805D03B6FE03DCFE5B57FE72
+:100BC000805D03FE0357B623FE00CC03FE0357B639
+:100BD000750309044CFE2213FE1C800706FE1A133F
+:100BE000FE1E80E1FE1D80A4FE0C90FE0E13FE0E84
+:100BF00090A3FE3C90FE30F40BFE3C50A001FE8220
+:100C0000162F072DE001FEBC1509041D4501E70163
+:100C1000E811FEE90009044CFE2C1301FE1416FE37
+:100C20001E1CFE1490FE96900CFE640118FE6601D8
+:100C300009044FFE1212FE038074FE01EC20FE80B8
+:100C4000401220632711C8591E20ED762003FE08AC
+:100C50001C05FEAC00FE065805FEAE00FE0758055A
+:100C6000FEB000FE085805FEB200FE0958FE0A1C40
+:100C7000246912C9230C500C3F1340485F171DFE16
+:100C8000904DFE915421FE080F3E10134248174C20
+:100C9000FE904DFE915421FE1E0F24101220782C40
+:100CA000461E20ED762011C8F6FED6F0FE320FEA81
+:100CB00070FE141CFE101CFE181C033CFE0C14EEEF
+:100CC000FE07E61DFECE47FEF513030186782C468F
+:100CD000FAEFFE42132F072DFE34130A42010EB025
+:100CE000FE3612F0FE454801E3FE00CCB0FEF313E1
+:100CF0003D750710A30A80010EFE805C016FFE0E99
+:100D000010077E45F6FED6F0FE6C0F03FE445874C5
+:100D1000FE01EC97FE9E40FE9DE700FE9CE71B76E1
+:100D20002701DAFEDD102ABC7DBD7F302ED5071BE2
+:100D3000FE4812070BFE5612071AFE301207C216A3
+:100D4000FE3E1107FE230016FE4A11070616FEA8F6
+:100D5000110719FE12120700162214C201339F2B2D
+:100D600001088C43032BFE62080ACA01FE320E11F1
+:100D70007E02292B2F079BFED9137939683A77FE1B
+:100D8000FC1009046AFE7212C038C14EF4F58EFEE2
+:100D9000C6101E58FE2613057B317C77FE820C0C94
+:100DA000541855230C7B0C7C01A82469731258013C
+:100DB000A5C038C14EFE0455FEA555FE04FA38FE06
+:100DC00005FA4EFE911005563157FE4056FEE1568B
+:100DD0000C56185783C038C14EF4F505523153FEF6
+:100DE0000056FEA1560C52185309046AFE1E121E2C
+:100DF00058FE1F4005543155FE2C50FEAE5005568E
+:100E00003157FE4450FEC65005523153FE0850FE85
+:100E10008A500539313AFE4050FEC250025C240629
+:100E200012CD025B2B01081F44302ED5070621444A
+:100E30002F079B215B016E1C3D164409040BE279D0
+:100E400039683AFE0A5534FE8B55BE39BF3AFE0C5E
+:100E500051FE8E51025BFE1981AFFE1941025B2BE0
+:100E6000010825321FA2302ED84B1AFEA6124B0BBA
+:100E70003B0244010825321FA2302ED6071A214416
+:100E800001081FA2302EFEE809FEC2496005FE9C43
+:100E9000002884490419349FFEBB454B00453E069B
+:100EA000783DFEDA14016E87FE4B45E22F079AE18A
+:100EB00005C62884053F28345E025BFEC05DFEF84F
+:100EC00014FE03170550B40C505E2B0108265C017C
+:100ED000FEAA14025C010825321F44302ED60706F4
+:100EE000214401FE8E13FE4258FE8214FEA4148794
+:100EF000FE4AF40B1644FE4AF406FE0C122F079A23
+:100F000085025B053FB40C3F5E2B0108265C01FEA9
+:100F1000D814025C130665FECA1226FEE01272F1B6
+:100F200001082372038FFEDC1225FEDC121FFECAAD
+:100F3000125E2B0108FED510136CFF020057488B80
+:100F40001CFEFF7FFE3056FE005C03136CFF0200A8
+:100F500057488B1C3DFE3056FE005C03136CFF02AD
+:100F60000057488B03136CFF020057488BFE0B5849
+:100F7000030A5001820A3F018203FC1C10FF030098
+:100F800054FE00F41948FE007DFE017DFE027DFE48
+:100F9000037C63270C521853BE56BF5703FE6208EA
+:100FA000FE824AFEE11AFE835A740301FE1418FE03
+:100FB00042485F608901081FFEA214302ED8010844
+:100FC0001FFEA214302EFEE80AFEC15905C628FEF7
+:100FD000CC1249041BFEC41323621BE24BC364FE04
+:100FE000E8133B130617C378DBFE7810FF02835526
+:100FF000A1FF028355621AA4BBFE30008EE4172CB9
+:101000001306FE5610620BE1BBFE64008EE40AFE7E
+:10101000640017931306FE28106206FE6013BBFEE1
+:10102000C8008EE40AFEC800174D130683BBFE906D
+:1010300001BAFE4E1489FE1210FE43F494FE56F0DF
+:10104000FE6014FE04F46CFE43F493FEF310F90109
+:10105000FE22131C3DFE1013FE0017FE4DE469BA7C
+:10106000FE9C14B769FE1C10FE0017FE4DE419BA71
+:10107000FE9C14B719836023FE4DF400DF8913062C
+:10108000FEB456FEC3580360130B03150601082671
+:10109000E5150B010826E5151A010826E572FE89FB
+:1010A000490108031506010826A6151A010826A6F7
+:1010B0001506010826A6FE8949010826A672FE89A2
+:1010C0004A01080360031ECC0706FE4413AD12CC90
+:1010D000FE49F4003B729F5EFE01ECFE2701F10128
+:1010E000082F07FEE300FE20131FFE5A152312CD22
+:1010F00001431ECD070645094A0635030A42010E83
+:10110000ED880710A40A80010E880A51019E030A87
+:1011100080010E88FE80E710071084FE455801E329
+:1011200088030A42010E880A51019E030A42010EF9
+:10113000FE8080F2FE49E410A40A80010EF20A51FA
+:1011400001820317107166FE6001FE18DFFE19DED2
+:10115000FE241CFE1DF71D90FEF61501FEFC16E098
+:10116000911D66FE2C01FE2F1903AE21FEE615FE31
+:10117000DA1017107105FE6401FE00F419FE18580C
+:1011800005FE6601FE19589119FE3C90FE30F406EA
+:10119000FE3C5066FE3800FE0F79FE1CF71990FEEB
+:1011A0004016FEB6143403AE21FE1816FE9C10172E
+:1011B0001071FE835AFE18DFFE19DEFE1DF738900F
+:1011C000FE6216FE9414FE10139138661BFEAF19D2
+:1011D000FE98E70003AE21FE5616FE6C1017107144
+:1011E000FE30BCFEB2BC91C5661BFE0F79FE1CF73B
+:1011F000C590FE9A16FE5C143403AE21FE8616FEE0
+:101200004210FE02F61071FE18FE54FE19FE55FC47
+:10121000FE1DF74F90FEC016FE3614FE1C13914FB4
+:1012200047FE8358FEAF19FE80E710FE81E71011DC
+:10123000FEDD006327036327FE124521FEB016146E
+:10124000063795A90229FE39F0FE04172303FE7E16
+:10125000181C1A5D130D037105CB1C06FEEF12FE60
+:10126000E110782C462F072DFE3C13FE8214FE421F
+:10127000133C8A0A42010EB0FE3E12F0FE454801C0
+:10128000E3FE00CCB0FEF3133D750710A30A800106
+:101290000EF2016FFE1610077E85FE4014FE24122A
+:1012A000F6FED6F0FE2417170B03FE9CE70B0FFE8D
+:1012B000150059762701DA1706033C8A094A1D35BD
+:1012C000112D016F170603FE3890FEBA9079C7689A
+:1012D000C8FE485534FEC955031E98731298030A78
+:1012E00099010EF00A40010EFE494416FEF01773F4
+:1012F00075030A42010E0710450A51019E0A40017A
+:101300000E737503FE4EE41A64FE241805FE900069
+:10131000FE3A455BFE4EE4C264FE361805FE9200BE
+:10132000FE02E61BDCFE4EE4FE0B0064FE481805E0
+:10133000FE9400FE02E619FE081005FE9600FE026D
+:10134000E62CFE4E45FE0C12AFFF046854DE1C690D
+:1013500003077AFE5AF0FE741824FE0900FE3410CA
+:10136000071BFE5AF0FE821824C3FE2610071A5DE2
+:10137000242CDC070B5D2493FE0E1007065D244D24
+:101380009FAD0314FE09000133FE04FE7D057FF9C5
+:101390000325FECA18FE14F00865FEC61803FF1ADE
+:0213A00000004B
+:00000001FF
+/* Microcode buffer is kept after initialization for error recovery. */
diff --git a/firmware/advansys/38C0800.bin.ihex b/firmware/advansys/38C0800.bin.ihex
new file mode 100644
index 00000000000..a60b447ff74
--- /dev/null
+++ b/firmware/advansys/38C0800.bin.ihex
@@ -0,0 +1,336 @@
+:10000000D83F0D05000000F200F000FC001618E4D7
+:10001000010048E4188003F60200CE1900FAFFFF41
+:100020001C0F00F69EE7FF0082E700EA01FA01E6F6
+:1000300009E755F001F60300040010001EF085F0FA
+:1000400018F40800BC00385400ECD5F0820D00E62E
+:1000500086F0B1F0985701FCB400D4010C1C3E1C92
+:100060003C00BB000010BA19028032F07C0D021374
+:10007000BA131840005701EA02FC03FC3E006C0171
+:100080006E0174017601B9543E57008003E6B60054
+:10009000C00001013E017A01CA08CE1016110412F7
+:1000A0000812024ABB553C5603581B8030E44BE40F
+:1000B0005DF002FA200032004000800024013C0183
+:1000C00068016A017001720178017C01620A860D83
+:1000D00006134C1C04804AE402EE5BF003F70C00AC
+:1000E0000F004700BE00000120115C16321C381CB6
+:1000F0004E1C1044004C04EA5CF0A7F004F603FA2E
+:100100000500340036009800CC0020014E014A0B57
+:10011000420C120F0C1022110A120413301C024858
+:10012000004E42544455BD56068300DC05F009F0EC
+:1001300059F0B8F04BF406F70EF704FC05FC060086
+:10014000190033009B00A400B500BA00D000E10004
+:10015000E700E203080F021004100A100A130C1340
+:1001600012132414341404160816A417201C341C6B
+:10017000361C0844384491440A45484601486854AE
+:100180003A558355E555B0570158835905E60BF0AC
+:100190000CF004F805F807000A001C001E009E0081
+:1001A000A800AA00B900E0002201260179017E0121
+:1001B000C401C60180025E03EE049A06F8076208D5
+:1001C00068086908D608E909FA0B2E0F12101A10F0
+:1001D000ED10F1102A1106120C123E121013161314
+:1001E0001E134614761482143615CA156B18BE18E1
+:1001F000CA18E619121C461C9C3200400E47FE9C91
+:10020000F02B02FEAC0DFF100000D7FEE81900D65F
+:10021000FE8401FF030000FE9315FE0F05FF38006A
+:1002200000FE572400FE4C005BFF04000011FF0994
+:100230000000FF080101FF08FFFFFF270000FF107B
+:10024000FFFFFF110000FE7856FE3412FF21000070
+:10025000FE04F7D62C990A01FEC20FFE04F7D699C8
+:100260000A422CFE3DF0FE0602FE20F0A7FE91F0B1
+:10027000FEF401FE90F0FEF401FE8FF0A7035D4D49
+:1002800002FEC80D01FE380EFEDD12FEFC10FE2837
+:100290001C03FEA600FED3124114FEA600C2FE48B7
+:1002A000F0FE8A02FE49F0FEA402FE4AF0FEC202FF
+:1002B000FE46F0FE5402FE47F0FE5A02FE43F0FEF8
+:1002C0004802FE44F0FE4C02FE45F0FE5002180AC1
+:1002D000AA180614A1022BFE001CE7FE021CE6FE73
+:1002E0001E1CFEE91001FE1818FEE710FE06FCCEEB
+:1002F000097001A8022B155939A201FE5810097086
+:100300000187FEBD1009700187FEAD10FE161CFEB0
+:10031000581C180614A12C1C2BFE3DF0FE060223CF
+:10032000FE9802FE5A1CF8FE141C15FE300039A27D
+:1003300001FE4810180614A102D72220071135FE2D
+:100340006910180614A1FE04EC204F431320FE058B
+:10035000F6CE01FE4A1708545837122F429201FE7A
+:100360008216022B0946010E0700660173FE181063
+:10037000FE415809A4010EFEC8546BFE100301FE95
+:100380008216022B2C4FFE02E82AFEBF57FE9E4328
+:10039000FE7757FE27F0FEE001FE074BFE20F0A798
+:1003A000FE401C1CD9FE26F0FE5A03FEA0F0FE48BB
+:1003B00003FE11F0A7FEEF10FE9FF0FE6803F91098
+:1003C000FE110002652CFE481CF908051BFE1813DF
+:1003D0002122A3B713A30946010EB77801FEB41674
+:1003E00012D11CD9FE01F0D9FE82F0FE9603FA125A
+:1003F000FEE40027FEA8031C341DFEB803014BFEDB
+:1004000006F0FEC8039586FE0AF0FE8A0602240363
+:10041000702817FEFA04156D01367BFE6A0202D8B9
+:10042000F92C9919FE671BFEBF57FE7757FE481C33
+:100430007401AF8C0946010E070017DA09D1010ECD
+:100440008D5164792A037028FE1012156D01367BD8
+:10045000FE6A0202D8C781C8831C2427FE40041DFF
+:10046000FE3C043BFEA000FE9B57FE4E122DFF02F9
+:100470000010010B1DFEE4042D010B1D243331DEA1
+:10048000FE4C44FE4C1251FE44480F6FFE4C546B20
+:10049000DA4F792AFE0680FE4847FE621308051BE4
+:1004A000FE2A13320782FE5213FE20100F6FFE4CFD
+:1004B000546BDAFE0680FE4847FE401308051BFE1B
+:1004C0000813320782FE301308051BFE1C12159D0F
+:1004D0000805064D15FE0D0001367BFE640D022455
+:1004E0002D12FEE600FE1C90FE405C04159D0136B8
+:1004F000022BFE425B9919FE4659FEBF57FE775705
+:10050000FE8780FE31E45B08050AFE8413FE20802E
+:100510000719FE7C12530506FE6C1303FEA2002889
+:1005200017FE9005FE31E45A53050AFE561303FEEA
+:10053000A00028FE4E1267FF02001027FE48051C8F
+:1005400034FE8948FF02001027FE560526FEA80546
+:1005500012FEE3002153FE4AF0FE7605FE49F0FE4E
+:1005600070058825FE2100AB25FE2200AA2558FE35
+:100570000948FF02001027FE860526FEA805FEE2B8
+:10058000085305CB4D01B0250613D339FE270108CA
+:10059000051BFE22124101B2159D0805064D15FEF0
+:1005A0000D0001367BFE640D022403FE9C0028EB47
+:1005B000035C28FE36134101B226FE1806090653D5
+:1005C000051FFE02125001FE9E151DFE0E0612A50D
+:1005D000014B12FEE500035CC10C5C03CD28FE62FA
+:1005E00012034528FE5A1301FE0C1901FE7619FE6E
+:1005F0004348C4CC0F71FF02005752931E438BC473
+:100600006E4101B226FE820653051AE9910959018D
+:10061000FECC151DFE780612A5014B12FEE5000367
+:1006200045C10C45180601B2FA767401AF8C12FE72
+:10063000E20027DB1C34FE0AF0FEB60694FE6C07CF
+:10064000FE06F0FE74079586022408050AFE2E12A7
+:100650001619010B1600010B1600010B1600010BF9
+:10066000FE99A4010B160002FE420868051AFE3826
+:100670001208051AFE301316FE1B00010B160001AE
+:100680000B1600010B1600010B1606010B160002DB
+:10069000E26C58BE50FE9A81551B7AFE4207091B38
+:1006A000FE096FBAFECA45FE3212696D8B6C7F2758
+:1006B000FE54071C34FE0AF0FE4207958694FE6C39
+:1006C000070224014B02DB161F02DBFE9CF7DCFE57
+:1006D0002C90FEAE9056FEDA070C60146108545A56
+:1006E0003722200711FE0E128DFE808039206A2AE3
+:1006F000FE0610FE83E7FE4800ABFE034008545B95
+:100700003701B3B8FE1F40136201EFFE0850FE8AA6
+:1007100050FE4451FEC65188FE0890FE8A900C5E41
+:10072000145FFE0C90FE8E90FE4050FEC2500C3DB9
+:10073000143EFE4A1008055AFE2A12FE2C90FEAE08
+:10074000900C60146108055B8B01B3FE1F8013627F
+:10075000FE4490FEC6900C3F1440FE0890FE8A9026
+:100760000C5E145FFE4090FEC2900C3D143E0C2EB9
+:10077000143C210C490C6308541F372C0FFE4E11FA
+:1007800027DDFE9EF0FE7608BC17342C77E6C5FE0A
+:100790009A08C6FEB80894FE8E08FE06F0FE94087D
+:1007A00095860224014BFEC910161FFEC91068056C
+:1007B00006FE101268050A4E08050AFE9012FE2E6B
+:1007C0001C02FE180B6805064E68050AFE7A12FE2A
+:1007D0002C1CFEAAF0FED209FEACF0FE000902FEBF
+:1007E000DE09FEB7F0FEFC08FE02F61A50FE701895
+:1007F000FEF118FE4055FEE155FE1058FE9158FEE0
+:100800001459FE95591C85FE8CF0FEFC08FEACF0D8
+:10081000FEF008B5FECB10FEADF0FE0C0902FE188E
+:100820000BB6FEBF10FE2BF085F41EFE00FEFE1C74
+:1008300012C2FED2F085FE76181E19178503D21E4D
+:10084000061785C54AC64AB5B6FE891074672D15C8
+:100850009D013610FE3500FE01F06510800265FE38
+:100860009880FE19E40AFE1A1251FE1982FE6C18D5
+:10087000FE4454BEFE1981FE74188F9017FECE08F8
+:10088000024A08055AEC032E293C0C3F14409B2ECB
+:100890009C3CFE6C18FEED18FE4454FEE5543A3FB5
+:1008A0003B40034929638FFEE354FE7418FEF5189C
+:1008B0008FFEE35490C056FECE08024AFE37F0FE8B
+:1008C000DA09FE8BF0FE6009024A08050A23FEFAE7
+:1008D0000A3A493B6356FE3E0A0FFEC007419800A4
+:1008E000ADFE0159FE52F0FE0C0A8F7AFE240A3A40
+:1008F000498FFEE35457497D63FE1458FE95580214
+:100900004A3A493B63FE1459FE9559BE574957630D
+:10091000024A08055AFE821208051FFE661322626B
+:10092000B7FE03A1FE8380FEC844FE2E13FE049191
+:10093000FE86916A2AFE4059FEC15956E00360299D
+:10094000610C7F148057607D6101B3B86A2A13621D
+:100950009B2E9C3C3A3F3B4090C0FE04FA2EFE0585
+:10096000FA3C01EFFE3610210C7F0C803A3F3B40F1
+:10097000E408051F17E03A3D3B3E0805FEF7003747
+:10098000035E295FFE1058FE915857497D6302FEB1
+:10099000F40908051F17E00805FEF70037BEFE1929
+:1009A0008150FE1090FE9290FED3103207A617FEE3
+:1009B000080912A608050AFE1413033D293E56FE37
+:1009C0000809FE0C58FE8D58024A2141FE1980E7A5
+:1009D00008050AFE1A12FE6C19FE1941F4C2FED176
+:1009E000F0E2157E013610FE4400FE8E10FE6C19FA
+:1009F000573DFEED197D3EFE0C51FE8E51F41EFE5C
+:100A000000FF35FE7410C2FED2F0FEA60BFE761873
+:100A10001E198A03D21E06FE081310FE1600026578
+:100A2000FED1F0FEB80B157E013610FE1700FE4217
+:100A300010FECEF0FEBE0BFE3C10FECDF0FECA0B4B
+:100A400010FE22000265FECBF0FED60B10FE240045
+:100A50000265FED0F0FEE00B109EE5FECFF0FEEA50
+:100A60000B1058FE1010FECCF0E268051F4D10FE72
+:100A700012002C0FFE4E1127FE000CFE9EF0FE14FD
+:100A80000CBC17342C77E6C524C6242CFA27FE208C
+:100A90000C1C3494FE3C0C9586C5DCC6DC0224019B
+:100AA0004BFEDB1012FEE800B5B674C781C883FEAA
+:100AB00089F0243331E1C781C88327FE660C1D24E9
+:100AC0003331DFBC4E10FE420002657C06FE8149D8
+:100AD00017FE2C0D08050AFE44131000550AFE549B
+:100AE0001255FE280023FE9A0D0946010E070066E6
+:100AF00044FE2800FEE21001F501F609A401FE26DD
+:100B00000F64122F0173022B10FE4400550AE944B2
+:100B10000AFEB41001B0440AFEAA1001B0FE198208
+:100B2000FE3446AC440A10FE4300FE961008540AF8
+:100B30003701F501F664122F0173990A644292029B
+:100B4000FE2E0308050A8A440A1000FE5C106805A0
+:100B50001AFE581208051AFE5013FE1C1CFE9DF0CA
+:100B6000FE500DFE1C1CFE9DF0FE560D08541A375B
+:100B7000FEA91010FE1500FE04E60A50FE2E10100D
+:100B8000FE1300FE1010106FAB10FE4100AA10FE05
+:100B900024008CB5B67403702823D850FE04E61ADE
+:100BA000FE9D41FE1C426401E3022BF8150A39A0A8
+:100BB000B415FE310039A201FE481002D742FE06EC
+:100BC000ECD0FC441BFECE453542FE06EAD0FE4783
+:100BD0004B91FE7557035DFE9856FE381209480189
+:100BE0000EFE44484F08051BFE1A130946010E412C
+:100BF000FE415809A4010EFE495496FE1E0E02FE47
+:100C00002E03095DFEEE14FC441BFECE453542FE6C
+:100C1000CE47FEAD13022B22200711FE9E12211398
+:100C200059139F13D5222F41392FBCADFEBCF0FEC6
+:100C3000E00E0F06135901FEDA1603FE380129FEF5
+:100C40003A0156FEE40EFE02ECD5690066FE04ECA5
+:100C5000204FFE05F6FE340101FE4A17FE0890FE05
+:100C600048F40DFE1813BAFE02EAD5697EFEC513DC
+:100C7000151A39A0B4FE2E1003FE38011EFEF0FF37
+:100C80000CFE600103FE3A010CFE620143132025B5
+:100C900006132F122F920F060421042259FEF71279
+:100CA000229FB7139F077EFE7113FE241C1519396E
+:100CB000A0B4FED910C3FE03DCFE7357FE805D04B2
+:100CC000C3FE03DCFE5B57FE805D04FE0357C321B9
+:100CD000FE00CC04FE0357C37804080558FE221317
+:100CE000FE1C800706FE1A13FE1E80EDFE1D80AE60
+:100CF000FE0C90FE0E13FE0E90ACFE3C90FE30F407
+:100D00000AFE3C50AA01FE7A1732072FAD01FEB44D
+:100D10001608051B4E01F501F612FEE900080558FC
+:100D2000FE2C1301FE0C17FE1E1CFE1490FE969066
+:100D30000CFE640114FE660108055BFE1212FE0340
+:100D4000808DFE01EC20FE804013206A2A12CF64C1
+:100D50002220FB792004FE081C03FEAC00FE06588E
+:100D600003FEAE00FE075803FEB000FE085803FE67
+:100D7000B200FE0958FE0A1C256E13D0210C5C0C33
+:100D8000450F465250181BFE904DFE915423FEFC19
+:100D90000F44110F48521858FE904DFE915423E411
+:100DA000251113207C6F4F2220FB792012CFFE14D7
+:100DB00056FED6F0FE2610F874FE141CFE101CFE23
+:100DC000181C0442FE0C14FCFE07E61BFECE47FE78
+:100DD000F5130401B07C6F4FFE0680FE4847FE42CB
+:100DE0001332072FFE34130948010EBBFE3612FEE4
+:100DF0004148FE454801F0FE00CCBBFEF3134378AA
+:100E00000711AC0984010EFE805C0173FE0E100711
+:100E1000824EFE1456FED6F0FE601004FE44588D3D
+:100E2000FE01ECA2FE9E40FE9DE700FE9CE71A79C3
+:100E30002A01E3FEDD102CC781C8833331DE071A97
+:100E4000FE4812070AFE56120719FE301207C9178C
+:100E5000FE321207FE230017EB070617FE9C12074F
+:100E60001FFE12120700172415C90136A92D010B08
+:100E7000944B042DDD09D101FE260F1282022B2D89
+:100E80003207A6FED9133A3D3B3E56FEF011080547
+:100E90005AFE72129B2E9C3C90C096FEBA112262A2
+:100EA000FE2613037F298056FE760D0C6014612107
+:100EB0000C7F0C8001B3256E77136201EF9B2E9C93
+:100EC0003CFE0455FEA555FE04FA2EFE05FA3CFE36
+:100ED0009110033F2940FE4056FEE1560C3F14405E
+:100EE000889B2E9C3C90C0035E295FFE0056FEA1AD
+:100EF000560C5E145F08055AFE1E122262FE1F4049
+:100F000003602961FE2C50FEAE50033F2940FE4491
+:100F100050FEC650035E295FFE0850FE8A50033D16
+:100F2000293EFE4050FEC2500289250613D40272AB
+:100F30002D010B1D4C3331DE0706234C3207A6234F
+:100F40007201AF1E43174C08050AEE3A3D3B3EFEC8
+:100F50000A5535FE8B55573D7D3EFE0C51FE8E5198
+:100F60000272FE1981BAFE194102722D010B1C3466
+:100F70001DE83331E15519FEA612550A4D024C0108
+:100F80000B1C341DE83331DF0719234C010B1DE81E
+:100F90003331FEE809FEC2495103FE9C00288A5302
+:100FA000051F35A9FEBB4555004E44067C43FEDABD
+:100FB0001401AF8CFE4B45EE3207A5ED03CD288A18
+:100FC00003452835670272FEC05DFEF814FE031764
+:100FD000035CC10C5C672D010B268901FE9E150286
+:100FE00089010B1C341D4C3331DF0706234C01F102
+:100FF000FE4258F1FEA4148CFE4AF40A174CFE4A35
+:10100000F406EA3207A58B02720345C10C45672D31
+:10101000010B268901FECC1502890F0627FEBE139F
+:1010200026FED41376FE8948010B2176047BFED080
+:10103000131CFED0131DFEBE13672D010BFED51031
+:101040000F71FF02005752931EFEFF7FFE3056FEC7
+:10105000005C040F71FF02005752931E43FE30568E
+:10106000FE005C040F71FF0200575293040F71FFE2
+:101070000200575293FE0B5804095C018709450191
+:101080008704FE03A11E11FF030054FE00F41F524B
+:10109000FE007DFE017DFE027DFE037C6A2A0C5E61
+:1010A000145F573F7D4004DDFE824AFEE11AFE8355
+:1010B0005A8D0401FE0C19FE4248505191010B1D3E
+:1010C000FE96153331E1010B1DFE96153331FEE816
+:1010D0000AFEC15903CD28FECC1253051AFEC413D3
+:1010E00021691AEE55CA6BFEDC144D0F0618CA7C36
+:1010F00030FE7810FF028355ABFF0283556919AEAD
+:1011000098FE300096F2186D0F06FE5610690AED33
+:1011100098FE640096F209FE6400189E0F06FE28F1
+:10112000106906FE601398FEC80096F209FEC8001A
+:1011300018590F068898FE90017AFE421591E4FE38
+:1011400043F49FFE56F0FE5415FE04F471FE43F482
+:101150009EFEF310FE405C01FE16141E43ECFE00E2
+:1011600017FE4DE46E7AFE9015C46EFE1C10FE0054
+:1011700017FE4DE4CC7AFE9015C4CC885121FE4D6B
+:10118000F400E9910F06FEB456FEC35804510F0A4D
+:10119000041606010B26F3160A010B26F316190195
+:1011A0000B26F376FE8949010B041606010B26B1C6
+:1011B0001619010B26B11606010B26B1FE8949014D
+:1011C0000B26B176FE894A010B04510422D307068F
+:1011D000FE4813B813D3FE49F4004D76A967FE010B
+:1011E000ECFE2701FE8948FF02001027FE2E163272
+:1011F00007FEE300FE20131DFE52162113D4014BFF
+:1012000022D407064E08540637040948010EFB8E07
+:101210000711AE0984010E8E095D01A8040984013D
+:101220000E8EFE80E71107118AFE455801F08E04EC
+:101230000948010E8E095D01A8040948010EFE80CF
+:1012400080FE804CFE49E411AE0984010EFE804C04
+:10125000095D0187041811756CFE6001FE18DFFE40
+:1012600019DEFE241CFE1DF71B97FEEE1601FEF490
+:1012700017AD9A1B6CFE2C01FE2F1904B923FEDE5C
+:1012800016FEDA1018117503FE6401FE00F41FFE4D
+:10129000185803FE6601FE19589A1FFE3C90FE3056
+:1012A000F406FE3C506CFE3800FE0F79FE1CF71F62
+:1012B00097FE3817FEB6143504B923FE1017FE9CAE
+:1012C00010181175FE835AFE18DFFE19DEFE1DF799
+:1012D0002E97FE5A17FE9414EC9A2E6C1AFEAF1934
+:1012E000FE98E70004B923FE4E17FE6C1018117526
+:1012F000FE30BCFEB2BC9ACB6C1AFE0F79FE1CF716
+:10130000CB97FE9217FE5C143504B923FE7E17FEC0
+:101310004210FE02F61175FE18FE60FE19FE61FE17
+:1013200003A1FE1DF75B97FEB817FE3614FE1C13D3
+:101330009A5B41FE8358FEAF19FE80E711FE81E7FC
+:101340001112FEDD006A2A046A2AFE124523FEA855
+:1013500017150639A0B4022BFE39F0FEFC17210444
+:10136000FE7E181E19660F0D047503D21E06FEEFD1
+:1013700012FEE1107C6F4F32072FFE3C13F1FE424C
+:101380001342920948010EBBEBFE4148FE4548015D
+:10139000F0FE00CCBBFEF31343780711AC098401C7
+:1013A0000EFE804C0173FE161007828BFE4014FE69
+:1013B0002412FE1456FED6F0FE1C18180A04FE9CD9
+:1013C000E70A10FE150064792A01E3180604429228
+:1013D00008541B37122F0173180604FE3890FEBA0A
+:1013E000903ACE3BCFFE485535FEC9550422A3772F
+:1013F00013A30409A4010EFE41480946010EFE494B
+:101400004417FEE8187778040948010E07114E09C1
+:101410005D01A80946010E777804FE4EE4196BFEC3
+:101420001C1903FE9000FE3A45FE2C10FE4EE4C946
+:101430006BFE2E1903FE9200FE02E61AE5FE4EE454
+:10144000FE0B006BFE401903FE9400FE02E61FFE39
+:10145000081003FE9600FE02E66DFE4E45EABAFF56
+:10146000046854E71E6EFE081CFE6719FE0A1CFE87
+:101470001AF4FE0004EAFE48F4197AFE74190F19F2
+:1014800004077EFE5AF0FE841925FE0900FE341082
+:10149000071AFE5AF0FE921925CAFE261007196691
+:1014A000256DE5070A66259EFE0E1007066625597E
+:1014B000A9B80415FE09000136FE04FE810383FE6F
+:1014C000405C041CF7FE14F00B27FED6191CF77BBA
+:0C14D000F7FE82F0FEDA1904FFCC0000E9
+:00000001FF
+/* Microcode buffer is kept after initialization for error recovery. */
diff --git a/firmware/advansys/38C1600.bin.ihex b/firmware/advansys/38C1600.bin.ihex
new file mode 100644
index 00000000000..18c7c486204
--- /dev/null
+++ b/firmware/advansys/38C1600.bin.ihex
@@ -0,0 +1,398 @@
+:1000000077EF0406000000F2001600FC001000F07C
+:1000100018E40100041E48E403F6F7132E1E020044
+:100020000717C05F00FAFFFF040000F609E782E748
+:1000300085F086F04E109EE7FF0055F001F60300B4
+:10004000985701E600EA00EC01FA18F40800F01DE8
+:10005000385432F01000C20E1EF0D5F0BC004BE454
+:1000600000E6B1F0B40002133E1CC8473E00D801C0
+:1000700006130C1C5E1E0057C85701FCBC0EA212D2
+:10008000B9540080620A5A12C8153E1E1840BD5667
+:1000900003E601EA5CF00F0020006C016E0104121F
+:1000A0000413BB553C563E5703584AE44000B60083
+:1000B000BB00C000000101013E01580A44100A12B1
+:1000C0004C1C4E1C024A30E405E60C003C0080004B
+:1000D00024013C0168016A0170017201740176011A
+:1000E00078017C01C60E0C10AC12AE12161A321C2E
+:1000F0006E1E02483A55C95702EE5BF003F706F749
+:1001000003FC06001E00BE00E1000C12181A701A53
+:10011000301C381C1044004CB057405C4DE404EADD
+:100120005DF0A7F004F602FC05000900190032009A
+:1001300033003400360098009E00CC0020014E01B0
+:1001400079013C09680D021004103A1008120A13D4
+:100150004016501600174A19004E0054015800DC92
+:1001600005F009F059F0B8F048F40EF70A009B00CA
+:100170009C00A400B500BA00D000E700F0036908B5
+:10018000E9095C0CB612BC19D81B201C341C361CA7
+:10019000421D0844384491440A45484689486854F9
+:1001A0008355835931E402E607F008F00BF00CF0B8
+:1001B0004BF404F805F802FA03FA04FC05FC070006
+:1001C000A800AA00B900E000E500220126016001B4
+:1001D0007A018201C801CA0186026A031805B207C2
+:1001E0006808100D06100A100E1012106010ED10A5
+:1001F000F310061210121E120C130E131013FE9C95
+:10020000F03505FEEC0EFF100000E9FE341F00E89B
+:10021000FE8801FF030000FE9315FE0F05FF380066
+:1002200000FE572400FE4C0065FF0400001AFF0981
+:100230000000FF080101FF08FFFFFF270000FF107B
+:10024000FFFFFF130000FE7856FE3412FF2100006E
+:10025000FE04F7E8377D0D01FE4A11FE04F7E87D44
+:100260000D5137FE3DF0FE0C02FE20F0BCFE91F079
+:10027000FEF801FE90F0FEF801FE8FF0BC03674D22
+:1002800005FE080F01FE780FFEDD1205FE0E03FECF
+:10029000281C03FEA600FED1123E22FEA600ACFEE4
+:1002A00048F0FE9002FE49F0FEAA02FE4AF0FEC8A7
+:1002B00002FE46F0FE5A02FE47F0FE6002FE43F0E8
+:1002C000FE4E02FE44F0FE5202FE45F0FE56021CB7
+:1002D0000DA21C0722B70535FE001CFEF110FE0220
+:1002E0001CF5FE1E1CFEE910015FFEE710FE06FC79
+:1002F000DE0A8101A305351F9547B801FEE4110A06
+:1003000081015CFEBD100A81015CFEAD10FE161C71
+:10031000FE581C1C0722B7372A35FE3DF0FE0C02A2
+:100320002BFE9E02FE5A1CFE121CFE141C1FFE30E9
+:100330000047B801FED4111C0722B705E9212C099A
+:100340001A31FE69101C0722B7FE04EC2C6001FE76
+:100350001E1E202CFE05F6DE01FE621B010C614A0A
+:100360004415565101FE9E1E01FE961A05350A5788
+:1003700001180900360185FE1810FE41580ABA011D
+:1003800018FEC8547BFE1C0301FE961A0535376023
+:10039000FE02E830FEBF57FE9E43FE7757FE27F071
+:1003A000FEE401FE074BFE20F0BCFE401C2AEBFEE3
+:1003B00026F0FE6603FEA0F0FE5403FE11F0BCFE24
+:1003C000EF10FE9FF0FE7403FE461C19FE1100059F
+:1003D0007037FE481CFE461C010C0628FE1813262A
+:1003E00021B9C720B90A570118C78901FEC81A15D3
+:1003F000E12AEBFE01F0EBFE82F0FEA403FE9C324C
+:1004000015FEE4002FFEB6032A3C16FEC60301418A
+:10041000FE06F0FED603AFA0FE0AF0FEA2070529F5
+:1004200003811E1BFE24051F6301428FFE7002051F
+:10043000EAFE461C377D1DFE671BFEBF57FE775741
+:10044000FE481C7501A6860A57011809001BEC0A14
+:10045000E101187750408D3003811EF81F6301427F
+:100460008FFE700205EAD799D89C2A292FFE4E04E8
+:1004700016FE4A047EFEA000FE9B57FE541232FF79
+:10048000020010010816FE02053201081629272570
+:10049000EEFE4C44FE581250FE44481334FE4C54B9
+:1004A0007BEC608D3001FE4E1EFE4847FE7C130142
+:1004B0000C0628FE32130143099BFE6813FE26102A
+:1004C0001334FE4C547BEC01FE4E1EFE4847FE5496
+:1004D00013010C0628A50143099BFE4013010C06DD
+:1004E00028F91F7F010C06074D1FFE0D0001428FEA
+:1004F000FEA40E05293215FEE6000FFE1C9004FE38
+:100500009C933A0B0E8B021F7F01420535FE425B26
+:100510007D1DFE4659FEBF57FE77570FFE878004AC
+:10052000FE8783FEC9470B0ED065010C060DFE98B1
+:10053000130FFE208004FEA083330B0E091DFE84E2
+:100540001201380607FE701303FEA2001E1BFEDA1E
+:1005500005D0540138060DFE581303FEA0001EFE00
+:1005600050125EFF0200102FFE90052A3CCCFF02C5
+:1005700000102FFE9E0517FEF40515FEE300260170
+:1005800038FE4AF0FEC005FE49F0FEBA05712EFEA7
+:100590002100F12EFE2200A22E4AFE0948FF020091
+:1005A000102FFED00517FEF405FEE208013806FE06
+:1005B0001C004D01A72E0720E447FE2701010C0671
+:1005C00028FE24123E01841F7F010C06074D1FFEEA
+:1005D0000D0001428FFEA40E052903E61EFECA137C
+:1005E00003B61EFE401203661EFE38133E0184173A
+:1005F000FE72060A0701380624FE02124F01FE565B
+:100600001916FE68061582014115E203668A106616
+:10061000039A1EFE701203551EFE681301C60912CE
+:1006200048FE92062E1201FEAC1DFE434862801366
+:1006300058FF02005752AD233F4E62493E018417D6
+:10064000FEEA0601380612F7450A9501FE841916DE
+:10065000FEE0061582014115E203558A10551C077C
+:100660000184FEAE10036F1EFE9E133E0184039AAA
+:100670001EFE1A1201380612FC01C601FEAC1DFE58
+:1006800043486280F0450A9503B61EF801380624F7
+:1006900036FE02F60771788C004D62493E2D934E6E
+:1006A000D00D17FE9A0701FEC01916FE90072620EE
+:1006B0009E1582014115E2219E0907FB03E6FE58C3
+:1006C0005710E605FE2A06036F8A106F1C07018487
+:1006D000FE9C325F7501A68615FEE2002FED2A3CD6
+:1006E000FE0AF0FECE07AEFE9608FE06F0FE9E085D
+:1006F000AFA00529010C060DFE2E12141D010814D1
+:100700000001081400010814000108FE99A4010862
+:10071000140005FEC60901760612FE3A12010C0607
+:1007200012FE301314FE1B0001081400010814000F
+:1007300001081400010814070108140005EF7C4AA1
+:10074000784F0FFE9A8104FE9A83FECB470B0E2D45
+:100750002848FE6C080A28FE096FCAFECA45FE3208
+:100760001253634E7C972FFE7E082A3CFE0AF0FE51
+:100770006C08AFA0AEFE96080529014105ED1424D2
+:1007800005EDFE9CF79F01FEAE1EFE185801FEBE51
+:100790001EFE9958FE7818FEF9188EFE1609106A8A
+:1007A000226B010C615444212C091AF87701FE7E5A
+:1007B0001E472C7A30F0FE83E7FE3F0071FE0340B7
+:1007C000010C61654401C2C8FE1F40206E01FE6A33
+:1007D00016FE0850FE8A50FE4451FEC651FE10100F
+:1007E00001FECE1E01FEDE1E1068226901FEEE1E15
+:1007F00001FEFE1EFE4050FEC250104B224CFE8AEF
+:1008000010010C0654FE501201FEAE1E01FEBE1E6B
+:10081000106A226B010C06654E01C20FFE1F800498
+:10082000FE9F83330B0E206E0FFE449004FEC49394
+:100830003A0BFEC69004FEC693790B0E106C226D27
+:1008400001FECE1E01FEDE1E106822690FFE4090E2
+:1008500004FEC0933A0BFEC29004FEC293790B0EC5
+:10086000104B224C10642234010C6124443713FED7
+:100870004E112FFEDE09FE9EF0FEF209FE01481B1E
+:100880003C3788F5D4FE1E0AD5FE420AD2FE1E0A67
+:10089000D3FE420AAEFE120AFE06F0FE180AAFA010
+:1008A00005290141FEC1101424FEC110017606077E
+:1008B000FE14120176060D5D010C060DFE7412FE8B
+:1008C0002E1C05FE1A0C017606075D0176060D4109
+:1008D000FE2C1CFEAAF0FECE0AFEACF0FE660AFE5E
+:1008E0009210C4F6FEADF0FE720A05FE1A0CC5FEAB
+:1008F000E710FE2BF0BFFE6B1823FE00FEFE1C125D
+:10090000ACFED2F0BFFE7618231D1BBF03E3230706
+:100910001BBFD45BD55BD25BD35BC4C5FEA910758E
+:100920005E321F7F014219FE3500FE01F0701998FA
+:100930000570FE741823FE00F81B5B7D1201FE7823
+:100940000F4D01FE961A2130777D1D055B010C06C7
+:100950000D2BFEE20B010C0654FEA612010C062420
+:10096000FE8813216EC701FE1E1F0FFE838004FE4A
+:100970008383FEC9470B0EFEC844FE42130FFE04DC
+:100980009104FE8493FECA570BFE869104FE869363
+:10099000FECB570B0E7A30FE4059FEC1598E4003F4
+:1009A0006A3B6B10972298D96ADA6B01C2C87A3019
+:1009B000206EDB64DC34916C7E6DFE4455FEE555A3
+:1009C000FE04FA64FE05FA3401FE6A16A3261097A7
+:1009D0001098916C7E6DFE1410010C06241B409142
+:1009E0004B7E4C010C06FEF7004403683B69FE1089
+:1009F00058FE9158FE1459FE9559055B010C0624CA
+:100A00001B40010C06FEF700447801FE8E1E4F0FBE
+:100A1000FE109004FE90933A0BFE929004FE929387
+:100A2000790B0EFEBD10014309BB1BFE6E0A15BB00
+:100A3000010C060DFE1413034B3B4C8EFE6E0AFE9A
+:100A40000C58FE8D58055B263E0FFE198004FE995A
+:100A500083330B0EFEE510010C060DFE1A12FE6C20
+:100A600019FE1941FE6B18ACFED1F0EF1F92014246
+:100A700019FE4400FE9010FE6C19D94BFEED19DAF8
+:100A80004CFE0C51FE8E51FE6B1823FE00FF31FE12
+:100A90007610ACFED2F0FEBA0CFE7618231D5D0374
+:100AA000E32307FE081319FE16000570FED1F0FEC1
+:100AB000CC0C1F92014219FE17005CFECEF0FED254
+:100AC0000CFE3E10FECDF0FEDE0C19FE220005707D
+:100AD000FECBF0FEEA0C19FE24000570FED0F0FEFD
+:100AE000F40C1994FE1C10FECFF0FEFE0C194AF314
+:100AF000FECCF0EF017606244D19FE12003713FEEE
+:100B00004E112FFE160DFE9EF0FE2A0DFE01481B13
+:100B10003C3788F5D429D529D229D32937FE9C32F0
+:100B20002FFE3E0D2A3CAEFE620DAFA0D49FD59F96
+:100B3000D29FD39F05290141FED31015FEE800C4C2
+:100B4000C575D799D89CFE89F0292725BED799D895
+:100B50009C2FFE8C0D16292725BDFE0148A419FEE9
+:100B6000420005709007FE81491BFE640E010C06D1
+:100B70000DFE441319002D0DFE54122DFE28002BDE
+:100B8000FEDA0E0A57011809003646FE2800FEFA62
+:100B90001001FEF41C01FE001D0ABA01FE581040AF
+:100BA00015560185053519FE44002D0DF7460DFE3D
+:100BB000CC1001A7460DFEC21001A70FFE1982043A
+:100BC000FE9983FECC470B0EFE3446A5460D19FE5A
+:100BD0004300FEA210010C610D4401FEF41C01FE55
+:100BE000001D40155601857D0D405101FE9E1E05DC
+:100BF000FE3A03010C060D5D460D1900FE62100160
+:100C0000760612FE5C12010C0612FE5213FE1C1C2C
+:100C1000FE9DF0FE8E0EFE1C1CFE9DF0FE940E014D
+:100C20000C611244FE9F1019FE1500FE04E60D4FE4
+:100C3000FE2E1019FE1300FE101019FE4700F119C8
+:100C4000FE4100A219FE240086C4C57503811E2B37
+:100C5000EA4FFE04E612FE9D41FE1C424001F405EF
+:100C600035FE121C1F0D47B5C31FFE310047B801EA
+:100C7000FED41105E951FE06ECE0FE0E474628FEC3
+:100C8000CE453151FE06EAE0FE474B45FE7557035F
+:100C900067FE9856FE38120A5A0118FE4448600151
+:100CA0000C0628FE18130A5701183EFE41580ABACE
+:100CB000FEFA14FE4954B0FE5E0F05FE3A030A67C1
+:100CC000FEE014FE0E474628FECE453151FECE47CB
+:100CD000FEAD130535212C091AFE98122620962008
+:100CE000E7FE081CFE7C19FEFD19FE0A1C03E5FE4A
+:100CF0004855A53BFE6201FEC95531FE741001FE48
+:100D0000F01A03FE38013BFE3A018EFE1E10FE0271
+:100D1000ECE7530036FE04EC2C60FE05F6FE3401D1
+:100D200001FE621B01FECE1EB211FE1813CAFE02A6
+:100D3000EAE75392FEC3131F1247B5C3FE2A1003FE
+:100D4000FE380123FEF0FF10E503FE3A0110FE62BB
+:100D50000101FE1E1E202C155601FE9E1E130702C9
+:100D600026022196C720960992FE79131F1D47B5CA
+:100D7000C3FEE110CFFE03DCFE7357FE805D02CFA1
+:100D8000FE03DCFE5B57FE805D02FE0357CF26FEAE
+:100D900000CC02FE0357CF8902010C064AFE4E1317
+:100DA0000FFE1C8004FE9C83330B0E0907FE3A13D2
+:100DB0000FFE1E8004FE9E83330B0EFE2A130FFED1
+:100DC0001D8004FE9D83FEF9130EFE1C1301FEEE32
+:100DD0001EACFE141301FEFE1EFE8158FA01FE0E2B
+:100DE0001FFE30F40DFE3C50A201FE921B01430990
+:100DF00056FB01FEC81A010C0628A401FEF41C01D2
+:100E0000FE001D15FEE900010C064AFE4E1301FE10
+:100E1000221BFE1E1C0FFE149004FE94933A0BFE40
+:100E2000969004FE9693790B0E10FE640122FE66E6
+:100E300001010C0665F90FFE038004FE8383330B6A
+:100E40000E77FE01EC2CFE8040202C7A3015DF401E
+:100E5000212CFE00408D2C02FE081C03FEAC00FE7F
+:100E6000065803FEAE00FE075803FEB000FE085809
+:100E700003FEB200FE0958FE0A1C2E4920E026108F
+:100E8000661055106F1357524F1C28FE904DFE915F
+:100E9000542BFE8811461A135A521C4AFE904DFEDE
+:100EA00091542BFE9E112E1A202C903460212CFE82
+:100EB00000408D2C15DFFE1456FED6F0FEB211FE5A
+:100EC000121C75FE141CFE101CFE181C0251FE0C98
+:100ED00014FE0E47FE07E628FECE47FEF51302017C
+:100EE000A7903460FE0680FE4847FE4213FE028053
+:100EF0000956FE34130A5A0118CBFE3612FE414839
+:100F0000FE454801FEB216FE00CCCBFEF3133F892E
+:100F1000091AA50A9D0118FE805C0185F2099BA4AF
+:100F2000FE1456FED6F0FEEC1102FE445877FE0188
+:100F3000ECB8FE9E40FE9DE700FE9CE7128D30015E
+:100F4000F4FEDD1037D799D89C2725EE0912FE480C
+:100F500012090DFE5612091DFE301209DD1BFEC4DA
+:100F60001309FE23001BFED01309071BFE341409CE
+:100F700024FE121209001B291FDD0142A1320108C3
+:100F8000AE410232FE62080AE101FE5810159B05CF
+:100F90003532014309BBFED713914B7E4C8EFE8048
+:100FA00013010C0654FE7212DB64DC34FE4455FE61
+:100FB000E555B0FE4A13216EFE261303973B988E2B
+:100FC000FEB60E106A226B261097109801C22E49A9
+:100FD00088206E01FE6A16DB64DC34FE0455FEA533
+:100FE00055FE04FA64FE05FA34FE8F10036C3B6D67
+:100FF000FE4056FEE156106C226D71DB64DC34FE5F
+:101000004455FEE55503683B69FE0056FEA15610A7
+:10101000682269010C0654F9216EFE1F40036A3BE9
+:101020006BFE2C50FEAE50036C3B6DFE4450FEC672
+:101030005003683B69FE0850FE8A50034B3B4CFE50
+:101040004050FEC25005732E07209E0572320108E3
+:10105000163D2725EE09072B3D014309BB2B7201E5
+:10106000A6233F1B3D010C060DFE1E13914B7E4C2B
+:10107000FE0A5531FE8B55D94BDA4CFE0C51FE8ED3
+:1010800051057201FE8E1ECAFE1941057232010819
+:101090002A3C16C02725BE2D1DC02D0D832D7F1B7C
+:1010A000FE6615053D01082A3C16C02725BD091D11
+:1010B0002B3D010816C02725FEE809FEC249500352
+:1010C000B61E830138062431A1FEBB452D00A4467F
+:1010D00007903F01FEF81501A686FE4B45FE201342
+:1010E00001430982FE1613039A1E5D03551E315EED
+:1010F0000572FEC05D01A7FE031703668A10665ED7
+:10110000320108177301FE5619057301082A3C16AF
+:101110003D2725BD09072B3D01FEBE16FE4258FEA8
+:10112000E81401A686FE4AF40D1B3DFE4AF407FEB4
+:101130000E12014309824E057203558A10555E3224
+:101140000108177301FE8419057301082A3C163D36
+:101150002725BD09122B3D01FEE8178BFEAA14FEC0
+:10116000B61486A8B20D1B3DB207FE0E120143094C
+:10117000824E0572036F8A106F5E32010817730189
+:10118000FEC019057313072FFECC1517FEE2155F7D
+:10119000CC0108265F028FFEDE152AFEDE1516FE44
+:1011A000CC155E320108FED5101358FF02005752CD
+:1011B000AD23FEFF7FFE3056FE005C021358FF0297
+:1011C000005752AD233FFE3056FE005C021358FF1D
+:1011D00002005752AD021358FF02005752FE005E44
+:1011E000021358FF02005752ADFE0B58020A660167
+:1011F0005C0A55015C0A6F015C0201FE1E1F231A86
+:10120000FF030054FE00F424520FFE007C04FE078E
+:101210007C3A0B0EFE0071FEF918FE7A19FEFB19DE
+:10122000FE1AF700FE1BF7007A3010682269D96CAD
+:10123000DA6D02FE6208FE824AFEE11AFE835A77E8
+:101240000201C6FE42484F5045010816FEE017272E
+:1012500025BE010816FEE0172725FEE80AFEC15943
+:10126000039A1EFEDA1201380612FED0132653121C
+:1012700048FE0817D1125312FE1E132DB47BFE2612
+:10128000174D13071CB49004FE7810FF028355F12C
+:10129000FF028355531DFE1213D6FE3000B0FE80B0
+:1012A000171C631307FE5610530DFE1613D6FE646B
+:1012B00000B0FE80170AFE64001C941307FE28107D
+:1012C0005307FE6013D6FEC800B0FE80170AFEC8A2
+:1012D000001C95130771D6FE900148FE8C1745F34C
+:1012E000FE43F496FE56F0FE9E17FE04F458FE43AD
+:1012F000F494F68B01FE2416233FFCA88C4948FE8B
+:10130000DA176249FE1C10A88C8048FEDA1762804A
+:10131000715026FE4DF400F7451307FEB456FEC388
+:10132000580250130D02503E784F45010816A92768
+:1013300025BEFE03EAFE7E01010816A92725FEE967
+:101340000A010816A92725FEE90AFE05EAFE7F0123
+:10135000010816A92725FE6909FE02EAFE8001019F
+:101360000816A92725FEE80847FE810103B61E835B
+:101370000138062431A278F2530736FE34F43FA137
+:1013800078039A1E830138061231F04F45FE901003
+:10139000FE405A233FFB8C4948FEAA186249718CD3
+:1013A0008048FEAA186280FEB456FE405D01C60168
+:1013B000FEAC1DFE0217FEC845FE5AF0FEC018FE28
+:1013C00043482D9336FE34F4FE0011FE40102DB438
+:1013D00036FE34F404FE34102DFE0B00364663FE58
+:1013E0002810FEC049FF020054B2FE900148FEFAE8
+:1013F0001845FE1CF43FF3FE40F496FE56F0FE0C3A
+:1014000019FE04F458FE40F494F63E2D934ED00D90
+:1014100021FE7F01FEC846FE24138C005D2621FEBE
+:101420007E01FEC845FE141321FE8001FE4845FAE8
+:1014300021FE8101FEC8444E260213070278455062
+:10144000130D021407010817FE8219140D01081765
+:10145000FE8219141D010817FE82195FFE894901D9
+:1014600008021407010817C1141D010817C1140749
+:10147000010817C1FE8949010817C15FFE894A01A9
+:1014800008025002140701081774147F010817742A
+:10149000141201081774FE89490108177414000119
+:1014A000081774FE894A01081774FE0949010817D4
+:1014B000745FCC01080221E40907FE4C13C820E444
+:1014C000FE49F4004D5FA15EFE01ECFE2701CCFF5A
+:1014D0000200102FFE3E1A014309FEE300FE221314
+:1014E00016FE641A26209E0141219E09075D010C0B
+:1014F000610744020A5A0118FE0040AA091AFE12A6
+:10150000130A9D0118AA0A6701A3020A9D0118AADD
+:10151000FE80E71A091A5DFE455801FEB216AA02BE
+:101520000A5A0118AA0A6701A3020A5A011801FE01
+:101530007E1EFE804CFE49E41AFE12130A9D01181D
+:10154000FE804C0A67015C021C1A877CE5FE18DFEE
+:10155000FE19DEFE241CFE1DF728B1FE041B01FE51
+:101560002A1CFAB3287CFE2C01FE2F1902C92BFE7F
+:10157000F41AFEFA101C1A8703FE6401FE00F4241C
+:10158000FE185803FE6601FE1958B32401FE0E1F13
+:10159000FE30F407FE3C507CFE3800FE0F79FE1C46
+:1015A000F724B1FE501BFED4143102C92BFE261BBA
+:1015B000FEBA101C1A87FE835AFE18DFFE19DEFEE3
+:1015C0001DF754B1FE721BFEB214FCB3547C12FE24
+:1015D000AF19FE98E70002C92BFE661BFE8A101C9D
+:1015E0001A878B0FFE309004FEB0933A0BFE18580A
+:1015F000FE329004FEB2933A0BFE19580EA8B34A7D
+:101600007C12FE0F79FE1CF74AB1FEC61BFE5E146B
+:101610003102C92BFE961B5CFE02F61A87FE18FEED
+:101620006AFE19FE6B01FE1E1FFE1DF765B1FEEE80
+:101630001BFE3614FE1C13B3653EFE8358FEAF1925
+:10164000FE80E71AFE81E71A15FEDD007A30027A85
+:1016500030FE12452BFEDC1B1F0747B5C30535FEC8
+:1016600039F0752602FE7E18231D361311028703FA
+:10167000E32307FEEF12FEE110903460FE028009C2
+:1016800056FE3C13FE8214FE421351FE06830A5A94
+:101690000118CBFE3E12FE4148FE454801FEB2163F
+:1016A000FE00CCCBFEF3133F89091AA50A9D011851
+:1016B000FE804C0185FE1610099B4EFE4014FE2450
+:1016C00012FE1456FED6F0FE521C1C0D02FE9CE7C4
+:1016D0000D19FE1500408D3001F41C070251FE0665
+:1016E00083FE1880612844155601851C0702FE38C8
+:1016F00090FEBA9091DE7EDFFE485531FEC955025C
+:1017000021B98820B9020ABA0118FE41480A5701D6
+:1017100018FE49441BFE1E1D8889020A5A01180939
+:101720001AA40A6701A30A570118888902FE4EE429
+:101730001D7BFE521D03FE9000FE3A45FE2C10FE5E
+:101740004EE4DD7BFE641D03FE9200D112FE1A10F2
+:10175000FE4EE4FE0B007BFE761D03FE9400D124BA
+:10176000FE081003FE9600D163FE4E4583CAFF04B7
+:101770006854FEF1102349FE081CFE6719FE0A1C7E
+:10178000FE1AF4FE000483B21D48FEAA1D131D02BA
+:101790000992FE5AF0FEBA1D2E93FE34100912FE75
+:1017A0005AF0FEC81D2EB4FE2610091D362E63FE0B
+:1017B0001A10090D362E94F20907362E95A1C8028B
+:1017C0001F930142FE04FE99039C8B022AFE1C1EFD
+:1017D000FE14F0082FFE0C1E2AFE1C1E8FFE1C1E7F
+:1017E000FE82F0FE101E020F3F04FE8083330B0EBC
+:1017F000020FFE188004FE9883330B0E020FFE02C8
+:101800008004FE8283330B0E020FFE068004FE86E8
+:1018100083330B0E020FFE1B8004FE9B83330B0EE3
+:10182000020FFE048004FE8483330B0E020FFE8041
+:101830008004FE8083FEC9470B0E020FFE1981044F
+:10184000FE9983FECA470B0E020FFE068304FE8636
+:1018500083FECE470B0E020FFE2C9004FEAC933A93
+:101860000B0E020FFEAE9004FEAE93790B0E020F2C
+:10187000FE089004FE88933A0B0E020FFE8A900435
+:10188000FE8A93790B0E020FFE0C9004FE8C933AA5
+:101890000B0E020FFE8E9004FE8E93790B0E020F3C
+:1018A000FE3C9004FEBC933A0B0E028B0FFE0380AD
+:0E18B00004FE8383330B770EA802FF66000050
+:00000001FF
+/* Microcode buffer is kept after initialization for error recovery. */
diff --git a/firmware/advansys/mcode.bin.ihex b/firmware/advansys/mcode.bin.ihex
new file mode 100644
index 00000000000..cd160d93866
--- /dev/null
+++ b/firmware/advansys/mcode.bin.ihex
@@ -0,0 +1,147 @@
+:100000003F452C01010301190F0000000000000012
+:10001000000000000F0F0F0F0F0F0F0F0000000068
+:1000200000000000000000000000000000000000D0
+:1000300000000000000000000000000000000000C0
+:100040000000000000000000C3120D0501000000C8
+:1000500000FF000000000000FF80FFFF0100000023
+:10006000000000000000002300000000000700FF67
+:1000700000000000FFFFFF00000000000000E48817
+:100080000000000080734804360000A2C2008073A4
+:1000900003233640B600360005D60CD212DA00A291
+:1000A000C20092801E985000F5004898DF23366009
+:1000B000B60092804F00F5004898EF233660B600F6
+:1000C000928080629280004615EE13EA020109D800
+:1000D000CD044D0000A3D600A6977F2304618401C0
+:1000E000E684D2C18073CD044D0000A3DA01A69747
+:1000F000C681C28880738077000101A1FE004F0095
+:10010000849707A6080100330300C288030301DEB9
+:10011000C288CE006960CE0002034A6000A2780166
+:10012000806307A62401788103038063E20007A6A9
+:10013000340100330400C2880307020104CA0D23FE
+:1001400068984D04048505D80D236898CD041523BF
+:10015000F888FB23026182018063020306A3620127
+:1001600000330A00C2884E0007A36E0100330B0063
+:10017000C288CD04362D00331A00C288500488810D
+:1001800006AB820188814E0007A39201500000A3B4
+:100190003C0100057C814697020105C60423A001AD
+:1001A0001523A101BE81FD23026182010ADA4A0002
+:1001B000066100A0B4018063CD04362D00331B001E
+:1001C000C28806236898CD04E684060100A2D40103
+:1001D000576000A0DA01E6848023A001E6848073E2
+:1001E0004B00066100A2000204010CDE020103CCF8
+:1001F0004F008497FC810823024182014F006297DF
+:1002000048048480F0970046560003C00123E800AC
+:1002100081730629034206E203EE6BEB1123F88893
+:100220000498F0808073807707A42A027C9506A644
+:10023000340203A64C044682040103D8B4986A969B
+:100240004682FE95806783038063B62D02A66C020A
+:1002500007A65A0206A65E0203A66202C2887C9521
+:100260004882609648820423A0011423A1013C84A3
+:1002700004010CDCE0232561EF0014014F04A80108
+:100280006F00A5010323A40106239C01242B1C015C
+:1002900002A6AA0207A65A0206A65E0203A6200428
+:1002A00001A6B40200A6B40200331200C288000EF8
+:1002B0008063004300A08C024D0404010BDCE723A3
+:1002C00004618401103112351401EC006C38003FD8
+:1002D0000000EA821823046118A0E2020401A2C807
+:1002E00000331F00C28808310A350C390E3D7E9854
+:1002F000B62D01A6140300A6140307A60C0306A638
+:10030000100303A6200402A66C0200333300C28847
+:100310007C95EE826096EE82829880427E9864E4BC
+:1003200004012DC83105070100A2540300438701D1
+:10033000050586987E9800A6160307A64C0303A61B
+:100340003C0406A6500301A6160300332500C2880C
+:100350007C95328360963283040110CE07C8050570
+:10036000EB0400330020C020816272830001050588
+:10037000FFA27A03B1010823B2012E8305051501FE
+:1003800000A29A03EC006E0095016C38003F00005B
+:1003900001A6960300A69603108480427E9801A6CB
+:1003A000A40300A6BC031084A898804201A6A4035D
+:1003B00007A6B203D4837C95A88300332F00C2889C
+:1003C000A898804200A6BC0307A6CA03D4837C95E4
+:1003D000C08300332600C288382B80328036042345
+:1003E000A0011223A101108407F006A4F403806B7E
+:1003F000806705238303806303A60E0407A6060413
+:1004000006A60A0400331700C2887C95F483609620
+:10041000F483208407F006A42004806B8067052302
+:1004200083038063B62D03A63C0407A6340406A606
+:10043000380400333000C2887C9520846096208484
+:100440001D0106CC00330084C0200023EA00816235
+:10045000A20D806307A65A0400331800C288030364
+:100460008063A30107A46404230100A286040AA0F8
+:100470007604E00000331D00C2880BA08204E00077
+:1004800000331E00C2884223F888002322A3E6041A
+:10049000082322A3A204282322A3AE04022322A31A
+:1004A000C4044223F8884A00066100A0AE04452334
+:1004B000F888049800A2C004B49800330082C020D9
+:1004C0008162E8814723F88804010BDE0498B49820
+:1004D00000330081C0208162140100A00002432388
+:1004E000F8880423A0014423A10180734D0003A3D5
+:1004F000F40400332700C288040104DC0223A201B3
+:100500000423A001049826954B00F6004F044F00E9
+:1005100000A3220500057600066100A21C050A85DD
+:100520004697CD04248548048480020103DA8023A1
+:10053000820134850223A0014A00066100A2400521
+:100540001D0104D6FF2386414B60CB00FF238001B1
+:1005500049008101040102C830018001F704030150
+:1005600049048001C90000050001FFA0600577046F
+:100570000123EA005D00FEC700620023EA00006379
+:1005800007A4F805030302A08E05F48500332D00AF
+:10059000C28804A0B80580630023DF004A0006611A
+:1005A00000A2A4051D0106D60223024182015000CB
+:1005B00062970485042302418201048508A0BE05D8
+:1005C000F48503A0C405F48501A0CE0588008063EE
+:1005D000CC8607A0EE055F00002BDF0800A2E60531
+:1005E0008067806301A27A067C8506236898482389
+:1005F000F88807238000068780637C850023DF005E
+:1006000000634A00066100A236061D0116D4C0230D
+:1006100007418303806306A61C0600333700C288A7
+:100620001D0101D620236360830380630223DF0062
+:1006300007A67C05EF046F0000634B000641CB006A
+:100640005200066100A24E061D0103CAC0230741E5
+:1006500000631D0104CC00330083C020816280232D
+:1006600007410063806708238303806300630123DD
+:10067000DF0006A6840607A67C058067806300333A
+:100680000040C020816200630000FE958303806308
+:1006900006A6940607A67C05000001A01407002BFF
+:1006A000400E8063010006A6AA0607A67C05400E40
+:1006B0008063004300A0A20606A6BC0607A67C0530
+:1006C0008067400E806307A67C050023DF0000637F
+:1006D00007A6D60600332A00C28803038063890078
+:1006E0000A2B07A6E80600332900C288004300A2AF
+:1006F000F406C00E8063DE86C00E00330080C0208A
+:100700008162040102DA80637C85807B806306A6B7
+:100710008C0600332C00C2880CA22E07FE958303A2
+:10072000806306A62C0707A67C0500333D00C2881F
+:1007300000008067830380630CA0440707A67C0544
+:10074000BF2304618401E6840063F0040101F10029
+:100750000001F20001058001720471008101700442
+:10076000800581050063F004F20072040101F100CC
+:1007700070008101700471008101720080017104B8
+:100780007000800170040063F004F2007204000144
+:10079000F10070008001700471008001720081011D
+:1007A000710470008101700400630023B3018305AC
+:1007B000A301A201A1010123A0010001C80003A11E
+:1007C000C40700330700C28880058105040111C8F1
+:1007D0004800B001B1010823B201050148040043FB
+:1007E00000A2E4070005DA870001C800FF238001AA
+:1007F00005050063F7041A09F6086E040002804339
+:100800007608800277040063F7041A09F6086E047C
+:10081000000200A0140816880043760880027704BE
+:100820000063F3040023F40074008043F400CF401D
+:1008300000A2440874040201F7C9F6D9000101A11D
+:10084000240804982695248873040063F30475042F
+:100850005A88020104D84697049826954A8875005C
+:1008600000A3640800054E8873040063807B8063E6
+:1008700006A6760800333E00C28880678303806343
+:100880000063382B9C88382B928832093105929866
+:100890000505B209006300320036003A003E0063ED
+:1008A00080328036803A803EB43D0063382B40323F
+:1008B0004036403A403E00635A20C94000A0B40888
+:1008C0005D00FEC300638073E6200223E8008273AC
+:1008D000FFFD80731323F8886620C0200423A00145
+:1008E000A123A1018162E28880738077680000A261
+:1008F000800003C2F1C74123F8881123A10104231A
+:04090000A001E684E8
+:00000001FF
+/* Microcode buffer is kept after initialization for error recovery. */
diff --git a/firmware/av7110/Boot.S b/firmware/av7110/Boot.S
new file mode 100644
index 00000000000..d562fdc2908
--- /dev/null
+++ b/firmware/av7110/Boot.S
@@ -0,0 +1,109 @@
+/*
+ Boot.S: boot loader for Siemens DVB-S card
+
+ Copyright (C) 2001 Convergence integrated media GmbH
+ Written by Ralph Metzler
+ <rjkm@convergence.de>
+ Copyright (C) 2006 Matthieu CASTET <castet.mattheiu@free.fr>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+/*
+ check AV711x_3_1.pdf for some hardware infos
+ build it with :
+ $ cc -mbig-endian -c Boot.S
+ $ ld -Ttext 0x2c000000 -EB -o Boot Boot.o
+ $ objcopy -Obinary Boot
+*/
+
+ .text
+ .align
+ .globl _start
+_start:
+ b reset // reset vector
+ movs pc, r14 // undefined
+ subs pc, r14, #4 // SWI
+ subs pc, r14, #4 // prefetch abort
+ subs pc, r14, #8 // data abort
+ subs pc, r14, #4 // reserved
+ subs pc, r14, #4 // IRQ
+ subs pc, r14, #4 // FIQ
+
+ .word tbl // table needed by firmware ROM
+tbl: .word (endtbl - tbl)
+ .word 0
+ .word conf
+endtbl: .word 0
+conf: .word 0xa5a55a5a
+ .word 0x001f1555
+ .word 0x00000009
+
+reset: ldr r13, buffer
+ ldr r4, flag
+ mov r0, #0
+ str r0, [r4]
+ str r0, [r4, #4]
+
+ ldr r1, wait_address
+ ldr r2, flag_address
+ ldr r3, sram
+
+copycode: // copy the code HW Sram
+ ldmia r1!, {r5-r12}
+ stmia r3!, {r5-r12}
+ cmp r1, r2
+ ble copycode
+ ldr pc, sram // jump to the copied code
+
+wait: ldrh r1, [r4] // wait for flag!=0
+ cmp r1, #0
+ beq wait
+
+ mov r1, r13 // buffer address
+ ldr r3, [r4,#4] // destaddr
+
+ ldrh r2, [r4,#2] // get segment length
+ add r2, r2, #63 // round length to next 64 bytes
+ movs r2, r2, lsr #6 // and divide by 64
+ moveq r0, #2 // if 0, set flag to 2, else signal
+ strh r0, [r4] // that buffer is accepted by setting to 0
+ beq wait
+
+copyloop:
+ ldmia r1!, {r5-r12}
+ stmia r3!, {r5-r12}
+ ldmia r1!, {r5-r12}
+ stmia r3!, {r5-r12}
+ subs r2, r2, #1
+ bne copyloop
+
+ eor r13, r13, #0x1400 // switch to other buffer
+ b wait
+
+// flag is stored at 0x2c0003f8, length at 0x2c0003fa,
+// destaddr at 0x2c0003fc
+
+flag: .word 0x2c0003f8
+
+
+// buffer 1 is at 0x2c000400, buffer 2 at 0x2c001000
+
+buffer: .word 0x2c000400
+
+sram: .word 0x9e000800
+wait_address: .word wait
+flag_address: .word flag
diff --git a/firmware/av7110/bootcode.bin.ihex b/firmware/av7110/bootcode.bin.ihex
new file mode 100644
index 00000000000..26a2993e072
--- /dev/null
+++ b/firmware/av7110/bootcode.bin.ihex
@@ -0,0 +1,15 @@
+:10000000EA00000EE1B0F00EE25EF004E25EF00401
+:10001000E25EF008E25EF004E25EF004E25EF0040C
+:100020002C0000240000000C000000002C00003414
+:1000300000000000A5A55A5A001F15550000000930
+:10004000E59FD07CE59F4074E3A00000E5840000BC
+:10005000E5840004E59F1070E59F2070E59F306403
+:10006000E8B11FE0E8A31FE0E1510002DAFFFFFB67
+:10007000E59FF050E1D410B0E35100000AFFFFFC0F
+:10008000E1A0100DE5943004E1D420B2E282203FDB
+:10009000E1B0232203A00002E1C400B00AFFFFF494
+:1000A000E8B11FE0E8A31FE0E8B11FE0E8A31FE00C
+:1000B000E25220011AFFFFF9E22DDB05EAFFFFEC17
+:1000C0002C0003F82C0004009E0008002C00007493
+:0400D0002C0000C040
+:00000001FF
diff --git a/firmware/bnx2/bnx2-mips-06-4.6.16.fw.ihex b/firmware/bnx2/bnx2-mips-06-4.6.16.fw.ihex
new file mode 100644
index 00000000000..0df10b53a6a
--- /dev/null
+++ b/firmware/bnx2/bnx2-mips-06-4.6.16.fw.ihex
@@ -0,0 +1,5805 @@
+:10000000080000F80800000000004DA4000000C82F
+:1000100000000000000000000000000008004DA4E7
+:100020000000001400004E6C080000800800000072
+:10003000000056CC00004E800800582000000084CC
+:100040000000A54C080056CC000001340000A5D0EB
+:10005000080031D808000000000070DC0000A70490
+:10006000000000000000000000000000080070DC3C
+:1000700000000024000117E00800048808000400C4
+:100080000000175C000118040000000000000000E0
+:100090000000000000000000000000000000000060
+:1000A000080000980800000000003A7400012F606A
+:1000B0000000000000000000000000000000000040
+:0800C000000000000000000038
+:0800C8000A00003E00000000E8
+:1000D000000000000000000D636F6D342E362E31DD
+:1000E00036000000040610020000000000000003BB
+:1000F00000000014000000320000000300000000B7
+:1001000000000000000000000000000000000000EF
+:1001100000000010000001360000EA60000000014D
+:1001200000000000000000000000000000000008C7
+:1001300000000000000000000000000000000000BF
+:1001400000000000000000000000000000000000AF
+:10015000000000000000000000000000000000009F
+:10016000000000020000000000000000000000008D
+:10017000000000000000000000000000000000007F
+:10018000000000000000000000000010000000005F
+:10019000000000000000000000000000000000005F
+:1001A000000000000000000000000000000000004F
+:1001B000000000000000000000000000000000003F
+:1001C0000000000010000003000000000000000D0F
+:1001D0000000000D3C02080024424DE03C030800F2
+:1001E00024634ED4AC4000000043202B1480FFFD5C
+:1001F000244200043C1D080037BD7FFC03A0F02111
+:100200003C100800261000F83C1C0800279C4DE01C
+:100210000E0002AA000000000000000D3C03601068
+:100220008C6450002402FF7F3C1A8000008220244E
+:100230003484380C24020037AC645000AF4200080C
+:1002400024020C80AF4200243C1B80083C060800BE
+:1002500024C6079C3C02080024424E182404001BBC
+:100260002484FFFFAC4600000481FFFD244200040B
+:100270003C020800244203803C010800AC224E20CE
+:100280003C020800244206803C010800AC224E24B7
+:100290003C02080024420D803C010800AC224E6064
+:1002A0003C02080024420A103C03080024630908A9
+:1002B0003C040800248409443C05080024A53C248F
+:1002C0003C010800AC224E683C0208002442057044
+:1002D0003C010800AC264E643C010800AC254E747D
+:1002E0003C010800AC234E7C3C010800AC224E804F
+:1002F0003C010800AC244E843C010800AC234E1C99
+:100300003C010800AC204E283C010800AC204E2CDB
+:100310003C010800AC204E303C010800AC204E34BB
+:100320003C010800AC204E383C010800AC204E3C9B
+:100330003C010800AC204E403C010800AC244E4477
+:100340003C010800AC204E483C010800AC204E4C5B
+:100350003C010800AC204E503C010800AC204E543B
+:100360003C010800AC204E583C010800AC264E5C15
+:100370003C010800AC204E6C3C010800AC254E70DE
+:100380003C010800AC234E780A0006F4000000008F
+:100390003C0308008C6300208F8200081043000398
+:1003A000000000000A00052CAF83000803E00008ED
+:1003B0000000000027BDFFE8AFB00010AFBF001481
+:1003C00027500100920200091040001A2403000186
+:1003D0003C0208008C42002010400016000018214A
+:1003E0000E00056400000000960300083C060800AB
+:1003F00094C64E968E0400188F8200209605000C3D
+:1004000000031C0000661825AC440000AC45000445
+:1004100024040001AC400008AC40000CAC400010CB
+:10042000AC400014AC4000180E000589AC43001C21
+:10043000000018218FBF00148FB000100060102141
+:1004400003E0000827BD001827BDFFE8AFBF00107C
+:100450009742010830437000240220001062000A15
+:1004600028642001548000128FBF00102402400035
+:1004700010620008240260001062000A8FBF0010A2
+:100480000A0000FB000010218FBF00100A0000BB13
+:1004900027BD00180E0003F6000000000A0000FA55
+:1004A0008FBF00100E000FB6000000008FBF0010BD
+:1004B0000000102103E0000827BD00183C020800DE
+:1004C0008C42002027BDFFE810400027AFBF00107E
+:1004D0000E00056400000000974201089743010CDC
+:1004E0008F8500203042003E3063FFFF0002140081
+:1004F00000431025ACA200008F4201003C0608001A
+:1005000094C64E968FBF0010ACA20004974301160C
+:100510009744010E3C02200000031C003084FFFFC2
+:1005200000641825ACA3000800C2302597420110D2
+:100530009743011224040001000214003063FFFFFE
+:1005400000431025ACA2000C9742011427BD0018EF
+:100550003042FFFFACA20010ACA00014ACA0001809
+:100560000A000589ACA6001C8FBF001003E000083C
+:1005700027BD00183C0208008C42002027BDFFE880
+:100580001040002AAFBF00100E00056400000000FC
+:10059000974201089743010C8F8500203042003EAE
+:1005A0003063FFFF0002140000431025ACA20000DE
+:1005B0008F4201003C06080094C64E968FBF001083
+:1005C000ACA20004974301169744010E3C022000A0
+:1005D00000031C003084FFFF00641825ACA3000852
+:1005E00000C23025974201109743011224040001F4
+:1005F000000214003063FFFF00431025ACA2000C82
+:100600009742011427BD00183042FFFFACA2001032
+:100610008F420118ACA200149342010B304200FF3C
+:10062000ACA200180A000589ACA6001C8FBF001000
+:1006300003E0000827BD001827BDFFE0AFB00010A1
+:10064000AFBF0018AFB10014275001009203000B98
+:100650002402001A961100081462003500002021BF
+:100660003222000110400009000000008E0200004C
+:1006700096030014000211C200021040005A10211B
+:10068000A44300800A000179322200020E00012BEF
+:10069000000000003C0208008C420040244200019F
+:1006A0003C010800AC220040322200020002202B54
+:1006B0003C0208008C420044322300042442000122
+:1006C0003C010800AC2200441060001A8FBF0018E3
+:1006D0008F4202B804410008240400013C020800D3
+:1006E0008C420060244200013C010800AC22006002
+:1006F0000A00019C8FB100148E02002096030016A0
+:1007000000002021AF4202808E020004A743028431
+:10071000AF4202883C021000AF4202B83C0208001F
+:100720008C42005C244200013C010800AC22005CC9
+:100730008FBF00188FB100148FB0001000801021FF
+:1007400003E0000827BD002027BDFFE0AFB0001088
+:10075000AFBF0018AFB10014275001009203000B87
+:1007600024020003961100081462003500002021C5
+:100770003222000110400009000000008E0200003B
+:1007800096030014000211C200021040005A10210A
+:10079000A44300800A0001BD322200020E0000FDC9
+:1007A000000000003C0208008C420040244200018E
+:1007B0003C010800AC220040322200020002202B43
+:1007C0003C0208008C420044322300042442000111
+:1007D0003C010800AC2200441060001A8FBF0018D2
+:1007E0008F4202B804410008240400013C020800C2
+:1007F0008C420060244200013C010800AC220060F1
+:100800000A0001E08FB100148E020020960300164A
+:1008100000002021AF4202808E020004A743028420
+:10082000AF4202883C021000AF4202B83C0208000E
+:100830008C42005C244200013C010800AC22005CB8
+:100840008FBF00188FB100148FB0001000801021EE
+:1008500003E0000827BD00209362000003E00008C9
+:10086000AF80000403E000080000102127BDFFE86E
+:10087000AFBF0014AFB000108F420100AF420020A4
+:100880008F420104AF4200A89350010B0E0001E417
+:10089000321000FF3C02080024424E18001018805D
+:1008A0002E10001C16000004006210210E0001E74B
+:1008B0000A0001FF000000008C4200000040F8091F
+:1008C00000000000104000053C0240008F4301047E
+:1008D0003C026020AC4300143C024000AF420138AF
+:1008E0003C0208008C4200348FBF00148FB000100F
+:1008F000244200013C010800AC22003403E000085F
+:1009000027BD001827BDFFE8AFBF00108F42014090
+:100910000E0001E4AF4200200E0003800000000042
+:100920003C024000AF4201783C03080024630038D9
+:100930008C6200008FBF001027BD00182442000108
+:1009400003E00008AC62000027BDFFE8AFBF001065
+:100950008F4201800E0001E4AF4200208F430180EE
+:1009600024020F0014620005000000008F4201887D
+:10097000A742009C0A0002393C024000936200003A
+:1009800024030050304200FF144300083C024000A2
+:100990000E00036400000000144000043C0240000C
+:1009A0000E000E42000000003C024000AF4201B8C1
+:1009B0003C0208008C42003C8FBF00102442000122
+:1009C0003C010800AC22003C03E0000827BD0018F1
+:1009D00003E00008000010218F4301048F82001003
+:1009E00010430008000000003C0208008C42008414
+:1009F000244200013C010800AC2200848F42010423
+:100A0000AF82001003E000080000000027BDFFE8EF
+:100A1000AFBF001027440100948200083043000259
+:100A2000304200041040001B000000008F4202B85A
+:100A300004410008240500013C0208008C420060CB
+:100A4000244200013C010800AC2200600A0002813F
+:100A50008FBF00108C820020948300160000282194
+:100A6000AF4202808C820004A7430284AF42028816
+:100A70003C021000AF4202B83C0208008C42005C0D
+:100A8000244200013C010800AC22005C0A00028103
+:100A90008FBF001010600008240500013C02080010
+:100AA0008C420084244200013C010800AC220084F6
+:100AB0000A0002818FBF00108F4401000E00024423
+:100AC00000000000000028218FBF001000A01021AE
+:100AD00003E0000827BD00183C0208008C42008893
+:100AE000274301009465000C244200013C010800EA
+:100AF000AC2200888C64001803451021904540000A
+:100B0000AF4400388C62001C2403FFF800052E005F
+:100B10000043102434420004AF42003C3C02000574
+:100B2000AF420030000000000000000000000000A4
+:100B3000AF450404000000000000000000000000B9
+:100B40003C02000634420001AF42003000000000C9
+:100B500000000000000000008F4200003042001042
+:100B60001040FFFD0000102103E00008000000001D
+:100B700027BDFFE0AFBF0018AFB100140E00005555
+:100B8000AFB000103C028000344200708C42000084
+:100B9000AF8200140E0000B2000000003C02800092
+:100BA000344600703C0308008C6300A03C0208003F
+:100BB0008C4200A4104300048F8400143C01080000
+:100BC000AC2300A4A743009E8CCA00003C0308008D
+:100BD0008C6300BC3C0208008C4200B80144202316
+:100BE00000641821000040210064202B00481021DF
+:100BF000004410213C010800AC2300BC3C0108006B
+:100C0000AC2200B88F510000322200071040FFE1F3
+:100C1000AF8A00148CC600003C0508008CA500BCFF
+:100C20003C0408008C8400B800CA302300A62821A8
+:100C30000000102100A6302B0082202100862021F8
+:100C4000322700013C010800AC2500BC3C01080033
+:100C5000AC2400B810E00021322200028F420100D3
+:100C6000AF4200208F420104AF4200A89342010B23
+:100C70000E0001E4305000FF2E02001C544000041E
+:100C8000001010800E0001E70A0002F800000000CA
+:100C90003C03080024634E18004310218C420000DE
+:100CA0000040F80900000000104000053C02400030
+:100CB0008F4301043C026020AC4300143C0240001E
+:100CC000AF4201383C0208008C420034244200014B
+:100CD0003C010800AC220034322200021040000E19
+:100CE000322200048F4201400E0001E4AF42002096
+:100CF0000E000380000000003C024000AF4201787B
+:100D00003C0208008C420038244200013C010800EB
+:100D1000AC220038322200041040FF9B3C028000CD
+:100D20008F4201800E0001E4AF4200208F4301801A
+:100D300024020F0014620005000000008F420188A9
+:100D4000A742009C0A00032D3C0240009362000071
+:100D500024030050304200FF144300083C024000CE
+:100D60000E00036400000000544000043C024000F8
+:100D70000E000E42000000003C024000AF4201B8ED
+:100D80003C0208008C42003C244200013C01080067
+:100D9000AC22003C0A0002B03C0280003C02900001
+:100DA0003442000100822025AF4400208F42002001
+:100DB0000440FFFE0000000003E000080000000007
+:100DC0003C028000344200010082202503E000083C
+:100DD000AF44002027BDFFE0AFB10014AFB000105A
+:100DE00000808821AFBF00180E00033530B000FF2F
+:100DF0009362007D0220202102028025A370007DE5
+:100E00008F7000743C0280000E00033E02028024BA
+:100E1000160000098FBF00188F4201F80440FFFE42
+:100E200024020002AF5101C0A34201C43C021000E1
+:100E3000AF4201F88FBF00188FB100148FB00010BF
+:100E400003E0000827BD002027BDFFD000001021CF
+:100E500003E0000827BD003027BDFFE8AFBF00104A
+:100E6000974201843042020010400005000020211A
+:100E70000E001079000000000A000378240400012D
+:100E80008F420188044000098FBF00108F42018803
+:100E90003C03FF00004310243C0304001443000300
+:100EA000240400019362003E8FBF001000801021D7
+:100EB00003E0000827BD0018A36000228F44014012
+:100EC0000A0003432405000127BDFFE8AFBF00145B
+:100ED000AFB000109362000024030020304200FFF6
+:100EE0001043000B00000000936200002403003058
+:100EF000304200FF10430006000000009362000033
+:100F000024030050304200FF144300628FBF0014DE
+:100F100093420148304200FF2443FFFF2C6200054A
+:100F20001040005C8FBF0014000310803C030800D9
+:100F300024634DA4004310218C42000000400008AF
+:100F4000000000000E0003358F4401408F70000C3C
+:100F50008F4201441602000224020001AF62000C1D
+:100F60000E00033E8F4401408F42014414500004A0
+:100F70008FBF00148FB000100A000FED27BD0018BE
+:100F80008F62000C0A0003EC000000009762001062
+:100F90008F4301443042FFFF14620009000000004B
+:100FA00024020001A76200108F420140AF420200FC
+:100FB0003C021000AF4202380A0003F38FBF001456
+:100FC000976200100A0003EC000000000E000335D9
+:100FD0008F440140976200128F4301443050FFFF5D
+:100FE0001603000224020001A76200120E00033E55
+:100FF0008F4401408F420144160200048FBF001449
+:101000008FB000100A00037C27BD00189762001201
+:101010000A0003EC00000000976200148F430144B3
+:101020003042FFFF146200068FBF0014240200014B
+:101030008FB00010A76200140A00131927BD001812
+:10104000976200140A0003EC00000000976200168B
+:101050008F4301443042FFFF146200062402000166
+:101060008FBF00148FB00010A76200160A000BE0BB
+:1010700027BD001897620016144000068FBF0014A9
+:101080003C0208008C420070244200013C01080030
+:10109000AC2200708FB0001003E0000827BD0018DC
+:1010A00027BDFFE8AFBF0014AFB0001093430109A4
+:1010B0002402001F8F500100106200A5286200204A
+:1010C00010400018240200382862000A1040000C6A
+:1010D0002402000B286200081040002C00000000D1
+:1010E000046000E728620002144000282402000681
+:1010F000106200268FBF00140A0004F08FB00010A9
+:101100001062005E2862000B144000DE8FBF0014E6
+:101110002402000E106200738FB000100A0004F069
+:1011200000000000106200C2286200391040000A6E
+:101130002402008024020036106200CC28620037AE
+:10114000104000B624020035106200C38FBF0014A7
+:101150000A0004F08FB000101062002B286200819A
+:1011600010400006240200C824020039106200B6B4
+:101170008FBF00140A0004F08FB0001010620099B5
+:101180008FBF00140A0004F08FB000103C0208006A
+:101190008C420020104000BB8FBF00140E0005647D
+:1011A000000000008F4201008F8300209745010C52
+:1011B00097460108AC6200008F4201043C0408001D
+:1011C00094844E9600052C00AC6200048F420118F6
+:1011D0000006340000C43025AC6200088F42011CB8
+:1011E00024040001AC62000C9342010A00A22825ED
+:1011F000AC650010AC600014AC600018AC66001C5C
+:101200000A0004C48FBF00143C0208008C42002076
+:101210001040009C8FBF00140E0005640000000009
+:10122000974401083C03080094634E969745010CCF
+:10123000000422029746010E8F820020000426003F
+:101240000083202500052C003C03008000A62825F3
+:1012500000832025AC400000AC400004AC400008F6
+:10126000AC40000CAC450010AC400014AC40001881
+:10127000AC44001C0A0004C3240400019742010C82
+:101280001440001500000000936200053042001079
+:1012900014400011000000000E0003350200202160
+:1012A0009362000502002021344200100E00033E2C
+:1012B000A36200059362000024030020304200FF77
+:1012C0001043006F020020218FBF00148FB0001068
+:1012D0000A00108F27BD00180000000D0A0004EF5F
+:1012E0008FBF00143C0208008C42002010400065B3
+:1012F0008FBF00140E000564000000008F4201043F
+:101300008F8300209744010C3C05080094A54E965D
+:10131000AC6200009762002C000424003042FFFF02
+:10132000008220253C02400E00A22825AC64000467
+:10133000AC600008AC60000CAC600010AC60001445
+:10134000AC600018AC65001C0A0004C32404000152
+:101350000E00033502002021A76000080E00033EA6
+:1013600002002021020020210E0003432405000179
+:101370003C0208008C420020104000428FBF001445
+:101380000E000564000000009742010C8F830020CE
+:101390003C05080094A54E9600021400AC700000B5
+:1013A000AC620004AC6000088F64004C3C02401F3B
+:1013B00000A22825AC64000C8F62005024040001B8
+:1013C000AC6200108F620054AC620014AC60001874
+:1013D000AC65001C8FBF00148FB000100A00058997
+:1013E00027BD00189362000024030020304200FF54
+:1013F000104300248FBF00140E000FD702002021DD
+:10140000104000208FBF0014020020218FB0001078
+:10141000000028210A00034327BD001802002021F4
+:101420008FBF00148FB000100A00065127BD0018AE
+:101430009745010C020020218FBF00148FB00010CF
+:101440000A00067127BD0018020020218FB000108D
+:101450000A00069627BD00189345010D02002021C1
+:101460008FB000100A0006E027BD001802002021FE
+:101470008FBF00148FB000100A0006BC27BD0018F3
+:101480008FBF00148FB0001003E0000827BD0018C4
+:101490008F4202780440FFFE34820080AF42024057
+:1014A00024020002A34202443C02100003E00008B0
+:1014B000AF4202783C04080094844EA23C0208002B
+:1014C0008C424EAC3083FFFF000318C00043102154
+:1014D000AF42003C3C0208008C424EA8AF420038AC
+:1014E0003C02005034420008AF42003000000000CF
+:1014F00000000000000000008F4200003042002089
+:101500001040FFFD000000008F4204003C01080075
+:10151000AC224E988F4204043C010800AC224E9C41
+:101520003C020020AF420030000000003C020800F6
+:1015300094424EA03C03080094634EA43C0508006E
+:1015400094A54EA624840001004310213083FFFFA0
+:101550003C010800A4224EA03C010800A4244EA295
+:1015600014650003000000003C010800A4204EA206
+:1015700003E00008000000003C05000A27BDFFE86A
+:10158000034528213C04080024844E88AFBF001086
+:101590000E0005EE2406000A3C02080094424E8A22
+:1015A0003C03080094634EA63042000F244200031F
+:1015B0000043180424027FFF0043102B1040000258
+:1015C000AF83001C0000000D0E0004FB00000000B3
+:1015D0003C02080094424E928FBF001027BD0018B5
+:1015E00003E00008A74200A23C02000A03421021C7
+:1015F000944300063C02080094424E923C010800CD
+:10160000A4234E8E004310238F83001C000214007D
+:10161000000214030043102B03E0000838420001CD
+:1016200027BDFFE8AFBF00103C02000A03421021B3
+:10163000944200063C010800A4224E8E0E0005488C
+:10164000000000005440FFF93C02000A8FBF001068
+:1016500003E0000827BD001827BDFFE8AFBF00105A
+:101660000E000548000000001040000300000000CC
+:101670000E000556000000003C0208008C424E9807
+:101680008FBF001027430400AF4200383C0208001F
+:101690008C424E9C27BD0018AF830020AF42003C17
+:1016A0003C020005AF42003003E00008AF800018A4
+:1016B0008F8200183C0300060002114000431025F1
+:1016C000AF420030000000000000000000000000F9
+:1016D0008F420000304200101040FFFD27420400FE
+:1016E000AF82002003E00008AF8000183C0608002D
+:1016F0008CC64E9C8F8500188F8300203C0208000A
+:1017000094424E9227BDFFE024A5000124630020EF
+:101710002442000124C70020AFB10014AFB0001074
+:10172000AFBF0018AF850018AF8300203C01080050
+:10173000A4224E92309000FF3C010800AC274E9C42
+:1017400004C100080000882104E000060000000039
+:101750003C0208008C424E98244200013C010800E3
+:10176000AC224E983C02080094424E923C03080082
+:1017700094634EA00010202B004310262C42000141
+:1017800000441025144000048F8300182402001028
+:101790001462000F000000000E00057A2411000101
+:1017A0003C03080094634E923C02080094424EA011
+:1017B00014620003000000000E0004FB00000000A3
+:1017C00016000003000000000E0005640000000089
+:1017D0003C03080094634E963C02080094424E94E9
+:1017E000246300013064FFFF3C010800A4234E96EF
+:1017F00014820003000000003C010800A4204E9663
+:1018000012000006000000003C02080094424E92C4
+:10181000A74200A20A0005DC022010210E000548A4
+:101820000000000010400004022010210E000556A8
+:1018300000000000022010218FBF00188FB100149B
+:101840008FB0001003E0000827BD00203084FFFFA8
+:1018500030A5FFFF000018211080000700000000E5
+:10186000308200011040000200042042006518216F
+:101870000A0005E40005284003E00008006010218C
+:1018800010C0000624C6FFFF8CA2000024A500049F
+:10189000AC8200000A0005EE2484000403E0000886
+:1018A0000000000010A0000824A3FFFFAC86000089
+:1018B00000000000000000002402FFFF2463FFFF7F
+:1018C0001462FFFA2484000403E000080000000012
+:1018D00024020001AF62000CA7620010A762001290
+:1018E000A762001403E00008A76200163082007FA0
+:1018F000034210213C08000E004818213C02080059
+:101900008C42002027BDFFD82407FF80AFB3001C06
+:10191000AFB20018AFB10014AFB00010AFBF0020DD
+:101920000080802130B100FF0087202430D200FFEA
+:101930001040002F00009821AF44002C906200005E
+:1019400024030050304200FF1443000E000000004A
+:101950003C0208008C4200E00202102100471024E3
+:10196000AF42002C3C0208008C4200E00202102131
+:101970003042007F0342102100481021944200D4DD
+:101980003053FFFF0E000564000000003C02080019
+:1019900094424E968F8300200011340000C23025FF
+:1019A00000122C003C02400000C2302534A500018A
+:1019B000AC7000008FBF0020AC6000048FB2001834
+:1019C000AC7300088FB10014AC60000C8FB3001C26
+:1019D000AC6500108FB00010AC600014240400014E
+:1019E000AC60001827BD00280A000589AC66001C01
+:1019F0008FBF00208FB3001C8FB200188FB100146E
+:101A00008FB0001003E0000827BD00289343010FAA
+:101A1000240200101062000E2865001110A00007BB
+:101A200024020012240200082405003A1062000675
+:101A30000000302103E0000800000000240500350C
+:101A40001462FFFC000030210A00060900000000BB
+:101A50008F42007424420FA003E00008AF62000C24
+:101A600027BDFFE8AFBF00100E00034324050001AF
+:101A70008FBF001024020001A762001227BD0018CA
+:101A80002402000103E00008A360002227BDFFE05C
+:101A9000AFB10014AFB00010AFBF001830B1FFFFFE
+:101AA0000E000335008080219362003F2403000470
+:101AB000304200FF1443000C0200202112200008D5
+:101AC0002402000A0E0006020000000093620005D6
+:101AD0002403FFFE00431024A36200052402001229
+:101AE000A362003F020020210E00033EA36000819C
+:101AF00016200003020020210E00066600000000F0
+:101B000002002021322600FF8FBF00188FB1001481
+:101B10008FB00010240500380A00060927BD0020F8
+:101B200027BDFFE0AFBF001CAFB20018AFB100147B
+:101B3000AFB000100E000335008080210E000602B9
+:101B4000000000009362003F24120018305100FF93
+:101B5000123200030200202124020012A362003F7F
+:101B6000936200052403FFFE004310240E00033E91
+:101B7000A362000502002021240500201632000780
+:101B8000000030218FBF001C8FB200188FB10014ED
+:101B90008FB000100A00034327BD00208FBF001C38
+:101BA0008FB200188FB100148FB0001024050039D7
+:101BB0000A00060927BD002027BDFFE8AFB00010CE
+:101BC000AFBF00149742010C24050036008080212D
+:101BD00014400010304600FF0E00033500000000E6
+:101BE00024020012A362003F9362000534420010F9
+:101BF0000E000602A36200050E00033E0200202133
+:101C0000020020210E000343240500200A0006D50F
+:101C1000000000000E000609000000000E00033561
+:101C200002002021936200232403FF9F0200202151
+:101C3000004310248FBF00148FB00010A362002354
+:101C40000A00033E27BD001827BDFFE0AFBF001804
+:101C5000AFB10014AFB0001030B100FF0E0003357B
+:101C600000808021240200120E000602A362003FC1
+:101C70000E00033E0200202102002021022030211C
+:101C80008FBF00188FB100148FB0001024050035ED
+:101C90000A00060927BD0020A380002C03E00008ED
+:101CA000A380002D8F4202780440FFFE8F82003413
+:101CB000AF42024024020002A34202443C02100050
+:101CC00003E00008AF4202783C0360008C625400DD
+:101CD000304200081440FFFD000000008C625408F0
+:101CE000AF82000024020052AC605408AC6454304F
+:101CF000AC6254342402000803E00008AC625400D3
+:101D00003C0260008C425400304200081040000544
+:101D10003C0360008C625400304200081440FFFD18
+:101D2000000000008F8300003C02600003E0000818
+:101D3000AC43540890A30000240200050080402119
+:101D40003063003F0000482114620005000050216C
+:101D500090A2001C94A3001E304900FF306AFFFFD0
+:101D6000AD00000CAD000010AD0000249502001481
+:101D70008D05001C8D0400183042FFFF0049102320
+:101D800000021100000237C30040382100862023E2
+:101D900000A2102B0082202300A72823AD05001CE1
+:101DA000AD040018A5090014A5090020A50A001615
+:101DB00003E00008A50A00228F4201F80440FFFE5C
+:101DC00024020002AF4401C0A34201C43C0210003F
+:101DD00003E00008AF4201F83C0208008C4200B466
+:101DE00027BDFFE8AFBF001424420001AFB00010D0
+:101DF0003C010800AC2200B48F4300243C02001FC9
+:101E000030AA00FF3442FF8030D800FF00628024F7
+:101E10000080F82130EF00FF1158003B01405821AD
+:101E2000240CFF803C19000A3163007F000310C0BE
+:101E300000031940006218213C0208008C4200DCBB
+:101E400025680001310D007F03E2102100431021BD
+:101E50003043007F03431821004C102400794821AF
+:101E6000AF4200248D220024016C1824006C7026DF
+:101E7000AD22000C8D220024310800FFAD2200109D
+:101E800095220014952300208D27001C3042FFFF6F
+:101E90003063FFFF8D26001800431023000211005D
+:101EA000000227C30040282100C4302300E2102B89
+:101EB00000C2302300E53823AD27001CAD260018F2
+:101EC00095220020A522001495220022154B000A1D
+:101ED000A52200168D2300248D220008254600012E
+:101EE000314500801462000430C4007F108F00026E
+:101EF00038AA008000C0502151AF000131C800FF56
+:101F00001518FFC9010058218F8400343082007FEA
+:101F1000034218213C02000A006218212402FF80BB
+:101F200000822024AF440024A06A0079A06A0083C4
+:101F30008C6200508F840034AC6200708C65007439
+:101F40003C027FFF3442FFFF00A228240E00073C22
+:101F5000AC650074AF5000248FBF00148FB0001028
+:101F600003E0000827BD001827BDFFC0AFBE003842
+:101F7000AFB70034AFB5002CAFB20020AFB1001C3A
+:101F8000AFB00018AFBF003CAFB60030AFB4002810
+:101F9000AFB300248F4500248F4600288F43002CC8
+:101FA0003C02001F3442FF800062182400C230242B
+:101FB0000080A821AFA3001400A2F0240E000700A7
+:101FC000AFA600103C0208008C4200E02410FF8005
+:101FD0000360882102A2102100501024AF42002487
+:101FE0003C0208008C4200E002A210213042007F37
+:101FF000034218213C02000A00629021924200D262
+:1020000093630084305700FF306300FF2402000117
+:1020100010620034036020212402000214620036A2
+:10202000000000000E0012E50240282192230083E8
+:10203000922200833063007F3042007F000210C094
+:1020400000031940006218213C0208008C4200DCA9
+:1020500002A210210043382100F01024AF420028D2
+:10206000922500789224008330E2007F03421821F9
+:102070003C02000C14850007006280212402FFFF4F
+:10208000A24200F12402FFFFA64200F20A0007F874
+:102090002402FFFF96020020A24200F196020022D5
+:1020A000A64200F28E020024AE4200F49222008387
+:1020B000A24200F08E4200C8AE4200FC8E4200C434
+:1020C000AE4200F88E220050AE4201008E4200CC9B
+:1020D000AE420104922200853042003F0A000853BC
+:1020E000344200400E00130802402821922200854D
+:1020F0000A0008533042003F936200852403FFDF4B
+:102100003042003FA36200859362008500431024A3
+:10211000A36200859363008393620078307400FFAC
+:10212000304200FF10540036240AFF803C0C000CA3
+:102130003283007F000310C00003194000621821A1
+:102140003C0208008C4200DC268800013109007F37
+:1021500002A210210043382130E2007F03421821FF
+:1021600000EA1024AF420028006C80218E02002477
+:10217000028A1824006A5826AE02000C8E0200243F
+:10218000310800FFAE0200109602001496030020F2
+:102190008E07001C3042FFFF3063FFFF8E060018E1
+:1021A0000043102300021100000227C30040282131
+:1021B00000C4302300E2102B00C2302300E5382396
+:1021C000AE07001CAE06001896020020A6020014FE
+:1021D00096020022A602001692220079304200FFE9
+:1021E000105400070000000051370001316800FF63
+:1021F00092220078304200FF1448FFCD0100A02158
+:1022000092220083A22200798E2200500A0008B395
+:10221000AE220070A22200858E22004C2405FF8091
+:10222000AE42010C9222008534420020A222008599
+:10223000924200D13C0308008C6300DC305400FF64
+:102240003C0208008C4200E400143140001420C01D
+:1022500002A3182100C4202102A210210064382109
+:10226000004610210045182400E52824AF45002829
+:10227000AF43002C3042007F924400D030E3007F17
+:1022800003422821034318213C02000C00628021F4
+:102290003C02000E309600FF00A298211296002A00
+:1022A000000000008E02000C0200202102602821A4
+:1022B00010400025261000280E00071B000000001B
+:1022C0009262000D26830001307400FF3042007FCF
+:1022D000A262000D2404FF801697FFF026730020F1
+:1022E0003C0208008C4200DC0000A02102A2102168
+:1022F00000441024AF4200283C0208008C4200E455
+:102300003C0308008C6300DC02A21021004410246E
+:10231000AF42002C3C0208008C4200E402A31821CA
+:102320003063007F02A210213042007F034220214F
+:10233000034318213C02000C006280213C02000E85
+:102340000A000875008298218E4200D8AE22005003
+:102350008E4200D8AE22007092250083924600D1B2
+:1023600092230083924400D12402FF8000A22824FB
+:102370003063007F308400FF00A628250064182AFF
+:102380001060000230A500FF38A50080A225008360
+:10239000A22500790E00070E000000009222007EA8
+:1023A00002A02021A222007A8E2300743C027FFF2B
+:1023B0003442FFFF006218240E00073CAE23007475
+:1023C0008FA20010AF5E00248FBF003CAF420028F8
+:1023D0008FBE00388FA200148FB700348FB6003044
+:1023E0008FB5002C8FB400288FB300248FB200204B
+:1023F0008FB1001C8FB0001827BD004003E000081B
+:10240000AF42002C90A2000024420001A0A20000D4
+:102410003C0308008C6300F4304200FF1443000FBB
+:1024200000803021A0A000003C0208008C4200E4A3
+:102430008F840034008220213082007F03421821E3
+:102440003C02000C006218212402FF80008220243C
+:10245000ACC3000003E00008AF4400288C820000F9
+:102460002442002003E00008AC82000094C2000077
+:102470003C080800950800CA30E7FFFF00804821AB
+:1024800001021021A4C2000094C200003042FFFFEC
+:1024900000E2102B54400001A4C7000094A20000E9
+:1024A0003C0308008C6300CC24420001A4A200007D
+:1024B00094A200003042FFFF544300078F8600289B
+:1024C0000107102BA4A00000544000010100382196
+:1024D000A4C700008F8600288CC4001CAF44003CB9
+:1024E00094A200008F43003C3042FFFF000210C066
+:1024F00000621821AF43003C8F42003C0082202341
+:1025000018800004000000008CC200180A000914A2
+:10251000244200018CC20018AF4200383C02005037
+:1025200034420010AF420030000000000000000004
+:10253000000000008F420000304200201040FFFDEC
+:10254000000000008F420404AD2200048F4204000A
+:10255000AD2200003C020020AF42003003E0000842
+:102560000000000027BDFFE0AFB20018AFB10014BB
+:10257000AFB00010AFBF001C94C2000000C08021AB
+:102580003C120800965200C624420001A602000038
+:102590009603000094E2000000E03021144300059F
+:1025A0008FB100300E0008E9024038210A000946C8
+:1025B000000000008C8300048C8200042442004050
+:1025C00004610007AC8200048C8200040440000413
+:1025D000000000008C82000024420001AC82000058
+:1025E000960200003042FFFF50520001A60000009A
+:1025F0009622000024420001A62200008F820028BB
+:102600009623000094420016144300048FBF001C60
+:1026100024020001A62200008FBF001C8FB2001808
+:102620008FB100148FB0001003E0000827BD002018
+:102630008F89002827BDFFE0AFBF00188D2200283A
+:102640002748040030E700FFAF4200388D22002CFD
+:10265000AF880030AF42003C3C020005AF42003082
+:10266000000000000000000000000000000000006A
+:1026700000000000000000008C82000C8C82000C26
+:10268000AD0200008C820010AD0200048C820018A4
+:10269000AD0200088C82001CAD02000C8CA200145C
+:1026A000AD0200108C820020AD0200149082000563
+:1026B000304200FF00021200AD0200188CA2001888
+:1026C000AD02001C8CA2000CAD0200208CA20010F8
+:1026D000AD0200248CA2001CAD0200288CA20020B8
+:1026E000AD02002CAD060030AD000034978300260B
+:1026F0003402FFFF14620002006020213404FFFF57
+:1027000010E00011AD040038952300369524003602
+:10271000240200013063FFFF000318C20069182182
+:1027200090650040308400070082100400451025A9
+:10273000A06200408F820028944200563042FFFF82
+:102740000A0009ADAD02003C952300369524003601
+:10275000240200013063FFFF000318C20069182142
+:1027600090650040308400070082100400021027AA
+:1027700000451024A0620040AD00003C00000000B5
+:1027800000000000000000003C020006344200404F
+:10279000AF42003000000000000000000000000018
+:1027A0008F420000304200101040FFFD8F8600284D
+:1027B000AF88003024C2005624C7003C24C400283F
+:1027C00024C5003224C600360E000927AFA200102F
+:1027D0008FBF001803E0000827BD00208F8300246E
+:1027E0003C0508008CA500E88F82003430633FFF71
+:1027F0000003198000451021004310212403FF80AD
+:102800003045007F00431024AF42002803451821C3
+:102810003C02000C0062302190C2000D0000382103
+:1028200034420010A0C2000D8F8900288F8A002436
+:1028300095230036000A1382304800032402000169
+:10284000A4C3000E1102000B290200021040000573
+:10285000240200021100000C240300010A0009F008
+:102860000000182111020006000000000A0009F013
+:10287000000018218CC2002C0A0009F0244300013A
+:102880008CC20014244300018CC200180043102B9A
+:1028900014400003000000000A0009F924070001A9
+:1028A0009522003E24420001A522003E000A138228
+:1028B000304300032C6200021040000900802821F0
+:1028C000146000040000000094C200360A000A09E7
+:1028D0003046FFFF8CC600380A000A090080282114
+:1028E000000030213C04080024844EB00A00095A3C
+:1028F00000000000274901008D22000C95230006EE
+:1029000001202021000216023045003F3063FFFF06
+:102910002402002728A6002810A2000EAF8300245E
+:1029200010C00008240200312402002110A2000976
+:102930002402002510A200079382002D0A000A2716
+:102940000000000010A200059382002D0A000A2753
+:10295000000000000A0009C5000000000A0006F798
+:102960000000000095230006912400058D25000C31
+:102970008D2600108D2700188D28001C8D29002021
+:10298000244200013C010800A4234EB63C0108008B
+:10299000A0244EB53C010800AC254EBC3C0108000B
+:1029A000AC264EC03C010800AC274EC83C010800D4
+:1029B000AC284ECC3C010800AC294ED003E0000806
+:1029C000A382002D8F87002827BDFFC0AFB300343E
+:1029D000AFB20030AFB1002CAFB00028AFBF0038AD
+:1029E0003C0208008C4200D094E3003030B0FFFF7E
+:1029F000005010073045FFFF3063FFFF00C09821F3
+:102A0000A7A200103C110800963100C614A30006CE
+:102A10003092FFFF8CE2002424420030AF42003CA1
+:102A20000A000A608CE2002094E200323042FFFF8C
+:102A300054A2000827A400188CE2002C2442003085
+:102A4000AF42003C8CE20028AF4200380A000A6E18
+:102A50008F84002827A5001027A6002002203821F7
+:102A60000E0008E9A7A000208FA200182442003021
+:102A7000AF4200388FA2001CAF42003C8F84002878
+:102A80003C020005AF42003094820034274304002A
+:102A90003042FFFF0202102B14400007AF830030CA
+:102AA00094820054948300340202102100431023C6
+:102AB0000A000A823043FFFF94830054948200345A
+:102AC0000223182100501023006218233063FFFFF7
+:102AD000948200163042FFFF144300030000000000
+:102AE0000A000A9024030001948200163042FFFF7E
+:102AF0000043102B104000058F8200309482001696
+:102B0000006210233043FFFF8F820030AC5300007F
+:102B1000AC400004AC520008AC43000C3C02000680
+:102B200034420010AF4200300000000000000000FE
+:102B3000000000008F420000304200101040FFFDF6
+:102B4000001018C20064182190650040320400078C
+:102B5000240200018FBF00388FB300348FB20030E1
+:102B60008FB1002C8FB00028008210040045102582
+:102B700027BD004003E00008A062004027BDFFA879
+:102B8000AFB60050AFB5004CAFB40048AFB300448F
+:102B9000AFB1003CAFBF0054AFB20040AFB000389F
+:102BA0008C9000003C0208008C4200E88F860034C4
+:102BB000960300022413FF8000C2302130633FFFE0
+:102BC0000003198000C3382100F3102490B20000E4
+:102BD000AF42002C9203000230E2007F034230211A
+:102BE0003C02000E00C28821306300C02402004075
+:102BF0000080A82100A0B021146200260000A021BE
+:102C00008E3400388E220018144000022402000185
+:102C1000AE2200189202000D304200201440001530
+:102C20008F8200343C0308008C6300DC001238C043
+:102C3000001231400043102100C7302100463821E6
+:102C400030E300073C02008030E6007800C2302507
+:102C50000343182100F31024AF4208002463090045
+:102C6000AF4608108E2200188C6300080043102124
+:102C7000AE2200188E22002C8E2300182442000160
+:102C80000062182B1060003D000000000A000B4499
+:102C900000000000920300022402FFC00043102441
+:102CA000304200FF1440000524020001AE2200184B
+:102CB000962200360A000B2D3054FFFF8E2200149E
+:102CC00024420001AE220018920200000002160009
+:102CD00000021603044100290000000096020002D1
+:102CE00027A4001000802821A7A200169602000247
+:102CF00024070001000030213042FFFFAF82002492
+:102D00000E00095AAFA0001C960300023C04080004
+:102D10008C8400E88F82003430633FFF0003198009
+:102D200000441021004310213043007F3C05000C7B
+:102D30000053102403431821AF42002800651821D6
+:102D40009062000D001221403042007FA062000D11
+:102D50003C0308008C6300E48F82003400431021A0
+:102D60000044382130E2007F034210210045102149
+:102D700000F31824AF430028AEA200009222000DF9
+:102D8000304200101040001302A020218F83002841
+:102D90008EA40000028030219462003E2442FFFF96
+:102DA000A462003E948400029625000E3084FFFF4A
+:102DB0000E000A3F30A5FFFF8F82002894430034A5
+:102DC0009622000E1443000302A0202124020001D9
+:102DD000A382002C02C028210E0008CF00000000B2
+:102DE0008FBF00548FB600508FB5004C8FB4004891
+:102DF0008FB300448FB200408FB1003C8FB00038D9
+:102E000003E0000827BD00588F85002827BDFFD0AC
+:102E1000AFB40028AFB20020AFBF002CAFB3002486
+:102E2000AFB1001CAFB0001890A800D090A600D1A0
+:102E30003C0208008C4200E48F83003430C700FF5E
+:102E4000A3A600100062182100071140006218219B
+:102E50003062007F034220213C02000C00822021CE
+:102E60002402FF8000621824311200FF8CB100D8C8
+:102E7000AFA400148CB300DC0000A021AF430028F5
+:102E800010F2001F240200018FA6001427A40014D2
+:102E900027A500108CC2000402228021027010239A
+:102EA000044000172402000190C3000D2402FF809B
+:102EB00000431024304200FF144000070200882124
+:102EC00090C2000D344200400E0008CFA0C2000D99
+:102ED0000A000B8B93A200100E000AAD241400010F
+:102EE0008F830028AC7000D893A20010A06200D19C
+:102EF00093A200101452FFE58FA6001424020001D3
+:102F0000168200048FBF002C0E0006F700000000A0
+:102F10008FBF002C8FB400288FB300248FB2002005
+:102F20008FB1001C8FB0001803E0000827BD0030EF
+:102F300027BDFFD8AFB3001CAFB20018AFB100146B
+:102F4000AFB00010AFBF00200080982100E08021CA
+:102F500030B1FFFF0E00056430D200FF000000001A
+:102F600000000000000000008F820020AC51000033
+:102F7000AC520004AC530008AC40000CAC40001054
+:102F8000AC400014AC4000183C03080094634E961B
+:102F900002038025AC50001C00000000000000006F
+:102FA00000000000240400018FBF00208FB3001C2C
+:102FB0008FB200188FB100148FB000100A0005897D
+:102FC00027BD002827BDFFE8AFB00010AFBF001439
+:102FD00030A5FFFF30C600FF0080802124020C8056
+:102FE000AF420024000000000000000000000000CC
+:102FF00000000000000000000E000B9A000000001E
+:103000003C040800248400E08C8200002403FF803C
+:103010008FBF00140202102100431024AF4200248D
+:103020008C8200003C03000A020280213210007FE3
+:10303000035010218FB000100043102127BD00184D
+:1030400003E00008AF82002827BDFFE8AFBF0010F3
+:103050008F4401403C0308008C6300E02402FF80A1
+:10306000AF8400340083182100621024AF42002492
+:103070003C02000803424021950500023063007FB6
+:103080003C02000A034318210062182130A5FFFF0B
+:103090003402FFFF000030213C07602010A2000630
+:1030A000AF8300282402FFFFA5020002946500D42C
+:1030B0000E000BBF30A5FFFF8FBF001024020C8055
+:1030C00027BD001803E00008AF4200243C020008BE
+:1030D00003424021950200023C0A0800954A00C6BE
+:1030E0003046FFFF14C000073402FFFF8F82002824
+:1030F0008F8400343C076020944500D40A000C28DB
+:1031000030A5FFFF10C200248F87002894E20054EE
+:1031100094E400163045FFFF00A6102300A6182BEC
+:103120003089FFFF106000043044FFFF00C510230A
+:10313000012210233044FFFF008A102B1040000CA6
+:10314000012A102324020001A50200162402FFFF19
+:10315000A502000294E500D48F84003400003021E1
+:1031600030A5FFFF3C0760200A000BBF00000000F5
+:103170000044102A104000080000000095020016CC
+:103180003042000110400004000000009742007E21
+:1031900024420014A502001603E00008000000000D
+:1031A0008F84002827BDFFE0AFBF00189482003451
+:1031B0009483003E1060001A3048FFFF9383002C78
+:1031C00024020001146200278FBF00188F8200289C
+:1031D000000818C231080007006218212447003A8D
+:1031E000244900542444002024450030244600345F
+:1031F00090620040304200FF01021007304200019F
+:10320000104000168FBF00180E000927AFA900104C
+:103210008F820028944200340A000C413048FFFF9E
+:1032200094830036948200341043000E8FBF001840
+:1032300094820036A482003494820056A482005402
+:103240008C82002CAC82002494820032A482003054
+:103250009482003CA482003A8FBF00180A000C013F
+:1032600027BD002003E0000827BD002027BDFFE8A0
+:10327000AFBF00108F4A01003C0508008CA500E09C
+:103280003C02080090424EBC3C0C0800958C4EB6A7
+:1032900001452821304B003F30A2007F03424021EE
+:1032A000396900323C02000A3963003F2C63000197
+:1032B000010240212D2900012402FF8000A22824C0
+:1032C00001234825AF8A003400801821AF4500242F
+:1032D000000030210080282124070001AF88002849
+:1032E0003C04080024844EB0AF8C00241520000656
+:1032F000A380002D240200201562000E3402FFFF7F
+:103300001582000C00000000240200201562000558
+:10331000000000008C6300142402FFFF106200070D
+:10332000000000000E00095A000000000A000C9D79
+:10333000000000000E0009C5006020210E000C36C0
+:10334000000000008FBF001024020C8027BD001871
+:1033500003E00008AF4200243C0208008C4200E079
+:1033600027BDFFA0AFB1003C008210212411FF80D7
+:10337000AFBE0058AFB70054AFB20040AFB0003896
+:10338000AFBF005CAFB60050AFB5004CAFB4004863
+:10339000AFB30044005110248F4800248F49002807
+:1033A0008F470028AF4200243C0208008C4200E016
+:1033B0000080902124060006008210213042007F08
+:1033C000034218213C02000A006280213C02001FD7
+:1033D0003442FF8000E2382427A40010260500F0C4
+:1033E0000122F0240102B8240E0005EEAFA7003040
+:1033F0008FA20018AE0200C48FA2001CAE0200C84B
+:103400008FA20024AE0200CC93A40010920300D13E
+:103410002402FF800082102400431025304900FF61
+:103420003083007F3122007F0062102A10400004A8
+:10343000000310C001311026304900FF000310C006
+:1034400000031940006218213C0208008C4200DC95
+:10345000920400D202421021004310210051102496
+:10346000AF42002893A300103063007F000310C018
+:1034700000031940006218213C0208008C4200DC65
+:1034800002421021004310213042007F03421821E4
+:103490003C02000C006240218FA300142402FFFFB5
+:1034A00010620030309500FF93A2001195030014C4
+:1034B000304400FF3063FFFF0064182B1060000DE4
+:1034C00000000000950400148D07001C8D060018F4
+:1034D0003084FFFF0044202300042100000010215D
+:1034E00000E4382100E4202B00C230210A000D172F
+:1034F00000C43021950400148D07001C8D060018AF
+:103500003084FFFF008220230004210000001021EE
+:103510000080182100C2302300E4202B00C4302397
+:1035200000E33823AD07001CAD06001893A200117C
+:10353000A502001497A20012A50200168FA2001483
+:10354000AD0200108FA20014AD02000C93A2001176
+:10355000A502002097A20012A50200228FA200144B
+:10356000AD0200242406FF80024610243256007F5C
+:10357000AF420024035618213C02000A0062802159
+:103580008E02004C8FA200203124007F000428C04E
+:10359000AE0200508FA200200004214000852821A7
+:1035A000AE02007093A2001001208821A2020083C5
+:1035B00093A20010A2020079920200853042003FDF
+:1035C000A20200853C0208008C4200DC024210216D
+:1035D0000045102100461024AF42002C3C02080098
+:1035E0008C4200E43C0308008C6300DC02421021A2
+:1035F0000044102100461024AF4200283C0208007D
+:103600008C4200E402431821006518210242102177
+:10361000004410213042007F3063007F93A50010EA
+:1036200003422021034318213C02000E0062402186
+:103630003C02000C10B1008C008248213233007F24
+:10364000166000192404FF803C0208008C4200DC54
+:103650000242102100441024AF42002C3C0208001A
+:103660008C4200E43C0308008C6300DC0242102121
+:1036700000441024AF4200283C0208008C4200E4C1
+:10368000024318213063007F024210213042007F44
+:1036900003422021034318213C02000E0062402116
+:1036A0003C02000C008248219124000D2414FF806C
+:1036B0000000102100942025A124000D9504000293
+:1036C000950500148D07001C3084FFFF30A5FFFF17
+:1036D0008D060018008520230004210000E4382115
+:1036E00000C2302100E4202B00C43021AD07001CB3
+:1036F000AD06001895020002A5020014A5000016F0
+:103700008D020008AD0200108D020008AD02000C11
+:1037100095020002A5020020A50000228D020008EB
+:10372000AD0200249122000D3042004010400042C2
+:10373000262200013C0208008C4200E0A3B30028CE
+:103740003C10000A0242102100541024AF42002411
+:103750003C0208008C4200E0A380002C27A4002C2F
+:10376000024210213042007F0342182100701821CC
+:103770008C6200D88D26000427A50028AFA9002C54
+:1037800000461021AC6200D80E000AADAF830028BD
+:1037900093A300288F8200280E0006F7A04300D1D3
+:1037A0000E000C360000000002541024AF4200242A
+:1037B0003C0208008C4200DC00132940001320C0AA
+:1037C00000A42021024210210044102100541024A2
+:1037D000AF42002C3C0208008C4200E43C0308008D
+:1037E0008C6300DC03563021024210210045102179
+:1037F00000541024AF4200283C0208008C4200E430
+:1038000002431821006418210242102100451021B2
+:103810003042007F3063007F0342202103431821A0
+:103820003C02000E006240213C02000C00D08021CE
+:1038300000824821262200013043007F14750005D4
+:10384000304400FF2403FF8002231024004310268D
+:10385000304400FF93A20010008088212508002832
+:103860001444FF762529002093A400108FA3001490
+:103870002402FFFF1062000A308900FF2482000149
+:10388000248300013042007F14550005306900FF99
+:103890002403FF800083102400431026304900FFDA
+:1038A00092020078305300FF11330032012088214A
+:1038B0003C0208008C4200DC3225007F000520C05D
+:1038C0000005294000A42021024210212406FF8087
+:1038D0000044102100461024AF42002C3C03080095
+:1038E0008C6300DC3C0208008C4200E40243182197
+:1038F00002421021004510210064182100461024C6
+:103900003063007FAF420028034318213C02000EC1
+:10391000006240213C0208008C4200E48D06000C4D
+:103920000100202102421021004510213042007F79
+:10393000034218213C02000C0062482110C0000D17
+:10394000012028210E00071B000000002402FF8038
+:103950000222182426240001006228263082007FDB
+:1039600014550002308300FF30A300FF1473FFD012
+:10397000006088218E0300743C027FFF3442FFFF09
+:1039800000621824AE0300740E00073C02402021A0
+:10399000AF5700248FA20030AF5E00288FBF005CBD
+:1039A0008FBE00588FB700548FB600508FB5004CB3
+:1039B0008FB400488FB300448FB200408FB1003CF9
+:1039C0008FB0003827BD006003E00008AF42002C34
+:1039D00027BDFFD8AFB1001CAFBF0020AFB00018AB
+:1039E00027510188922200032408FF803C03000A2B
+:1039F0003047007FA3A700108F4601803C020800DB
+:103A00008C4200E0AF86003400C2282100A81024B8
+:103A1000AF4200249224000030A2007F0342102114
+:103A200000431021AF8200283084007F240200026E
+:103A300014820025000719403C0208008C4200E473
+:103A400000C210210043282130A2007F0342182128
+:103A500000A81024AF4200283C02000C006218218C
+:103A60009062000DAFA3001400481025A062000D65
+:103A70008FA300149062000D304200405040006A55
+:103A80008FBF00208F860028A380002C27A400145D
+:103A90008CC200D88C63000427A5001000431021BD
+:103AA0000E000AADACC200D893A300108F8200288C
+:103AB0000E0006F7A04300D10E000C3600000000F7
+:103AC0000A000ED88FBF00200E00070000C0202182
+:103AD0000E00070E000000003C0200080342802197
+:103AE000922300019202007B1443004F8FBF0020FD
+:103AF000922200003044007F24020004108200174C
+:103B0000288200051040000624020005240200035C
+:103B1000108200078FB1001C0A000ED900000000BF
+:103B2000108200128FBF00200A000ED98FB1001C36
+:103B300092050083920600788E0700748F8400340B
+:103B400030A500FF00073E0230C600FF0E0007440C
+:103B500030E7007F0A000ED88FBF00200E000CA4B3
+:103B60008F8400340A000ED88FBF002024020C80FE
+:103B7000AF4200249202003E30420040104000203C
+:103B8000000000009202003E000216000002160330
+:103B900004410006000000008F8400340E0006710E
+:103BA000240500930A000ED88FBF00209202003F28
+:103BB00024030018304200FF1443000C8F840034AB
+:103BC000240500390E000609000030210E000335DF
+:103BD0008F84003424020012A202003F0E00033E34
+:103BE0008F8400340A000ED88FBF002024050036D1
+:103BF0000E000609000030210A000ED88FBF0020F9
+:103C00000E0003358F8400349202000534420020F8
+:103C1000A20200050E00033E8F8400340E00108FB8
+:103C20008F8400348FBF00208FB1001C8FB000182C
+:103C300024020C8027BD002803E00008AF420024C6
+:103C400027BDFFE8AFB00010AFBF0014274301004D
+:103C500094620008000214000002140304410002F0
+:103C6000000080212410000194620008304200808E
+:103C70001040001A02001021946200083042200017
+:103C800010400016020010218C6300183C021C2D0D
+:103C9000344219ED240600061062000F3C07602133
+:103CA0003C0208008C4200D4104000078F8200289C
+:103CB0008F830028906200623042000F344200403F
+:103CC000A06200628F8200288F840034944500D463
+:103CD0000E000BBF30A5FFFF020010218FBF0014A4
+:103CE0008FB0001003E0000827BD001827BDFFE0DB
+:103CF000AFB10014AFB00010A380002CAFBF00180C
+:103D00008F4501003C0308008C6300E02402FF8023
+:103D1000AF85003400A318213064007F03442021C4
+:103D2000006218243C02000A00822021AF430024D4
+:103D3000275001008E0200148C8300DCAF84002821
+:103D40000043102318400004000088218E02001454
+:103D50000E000B50AC8200DC9202000B2403000228
+:103D6000304200FF1443002F0000000096020008BC
+:103D7000304300FF24020082146200052402008404
+:103D80000E000A0B000000000A000F640000000093
+:103D900014620009240200818F8200288F8400347D
+:103DA0003C076021944500D49206000530A5FFFF32
+:103DB0000A000F5330C600FF146200270000000005
+:103DC0009202000A304300FF3062002010400004DD
+:103DD000306200408F8400340A000F4F24060040F8
+:103DE00010400004000316008F8400340A000F4FB7
+:103DF0002406004100021603044100178F8400349A
+:103E0000240600428F8200283C076019944500D4A4
+:103E100030A5FFFF0E000BBF000000000A000F647A
+:103E2000000000009202000B24030016304200FF45
+:103E300010430006000000009202000B240300174C
+:103E4000304200FF14430004000000000E000EDEAC
+:103E500000000000004088210E000C360000000029
+:103E60009202000A304200081040000624020C8032
+:103E70008F8500283C0400080E0012BD0344202159
+:103E800024020C80AF4200248FBF001802201021B2
+:103E90008FB000108FB1001403E0000827BD002090
+:103EA00027BDFFE8AFBF0014AFB000108F50002453
+:103EB0003C0308008C6300E08F4501002402FF8072
+:103EC00000A318213064007F0344202100621824DD
+:103ED0003C02000A00822021AF850034AF43002459
+:103EE00090820062AF8400283042000F34420050BC
+:103EF000A08200623C02001F3442FF800E0006F7E1
+:103F000002028024AF5000248FBF00148FB0001035
+:103F100003E0000827BD00183C0208008C42002086
+:103F20001040001D2745010090A300093C02000835
+:103F30000342202124020018546200033C020008BE
+:103F40000A000FA5240200080342202124020016C3
+:103F5000146200052402001724020012A082003F10
+:103F60000A000FAF94A700085462000694A7000847
+:103F7000936200052403FFFE00431024A3620005A2
+:103F800094A7000890A6001B8CA4000094A500062E
+:103F90000A000B9A00073C0003E000080000000044
+:103FA0002744010094820008304500FF38A30082B6
+:103FB00038A200842C6300012C4200010062182505
+:103FC00010600006240200839382002D1040000D33
+:103FD000000000000A000C690000000014A20005A7
+:103FE00024A2FF808F4301043C02602003E000080C
+:103FF000AC430014304200FF2C420002104000038A
+:10400000240200220A000F090000000014A200038D
+:10401000000000000A000F76000000000A000F9464
+:10402000000000009363007E9362007A144300094D
+:10403000000020219362000024030050304200FF62
+:1040400014430004240400019362007E2442000112
+:10405000A362007E03E00008008010218F4201F877
+:104060000440FFFE24020002AF4401C0A34201C489
+:104070003C02100003E00008AF4201F827BDFFE852
+:10408000AFBF00109362003F2403000A304200FFDC
+:1040900014430046000000008F6300548F62004C00
+:1040A0001062007F036030219362000024030050FF
+:1040B000304200FF1443002F000000008F440140F5
+:1040C0003C0208008C4200E02403FF8000821021A3
+:1040D00000431024AF4200243C0208008C4200E060
+:1040E0008F6500543C03000A008220213084007F49
+:1040F0000344102100431021AC4501089762003CA5
+:104100008F63004C3042FFFF000210400062182114
+:10411000AF63005C8F6300548F64004C9762003C77
+:10412000006418233042FFFF0003184300021040D0
+:104130000043102A10400006000000008F62005467
+:104140008F63004C004310230A0010250002104327
+:104150009762003C3042FFFF00021040ACC2006496
+:1041600024020001A0C0007CA0C2008424020C80B4
+:10417000AF4200240E000FD78F4401401040004989
+:104180008FBF00108F4301408F4201F80440FFFEB3
+:1041900024020002AF4301C0A34201C43C0210004C
+:1041A000AF4201F80A0010778FBF00109362003F02
+:1041B00024030010304200FF1443000400000000FC
+:1041C0008F4401400A001063000028219362003FE1
+:1041D00024030016304200FF14430004240200149C
+:1041E000A362003F0A001071000000008F62004CC3
+:1041F0008F630050004310230441002A8FBF00103A
+:104200009362008124420001A362008193620081D5
+:104210003C0308008C6300C0304200FF14430010D0
+:10422000000000009362003F24030004304200FFBE
+:1042300014430006000000008F4401408FBF0010AF
+:10424000240500930A00067127BD00188F44014021
+:10425000240500938FBF00100A0006E027BD001858
+:104260008F4401400E000335000000008F620054AF
+:104270002442FFFFAF6200548F6200502442FFFFD0
+:10428000AF6200500E00033E8F4401408F44014056
+:104290008FBF0010240500040A00034327BD001847
+:1042A0008FBF001003E0000827BD00188F4201886F
+:1042B0009363007E00021402304400FF306300FF6D
+:1042C0001464000D0000000093620080304200FF83
+:1042D0001044000900000000A36400809362000005
+:1042E00024030050304200FF14430004000000008B
+:1042F0000A0007A88F440180A364008003E000083F
+:104300000000000027BDFFE8AFB00010AFBF0014F1
+:1043100093620005240300303042003014430089CA
+:10432000008080213C0208008C4200201040008068
+:10433000020020210E000564000000008F8500208F
+:10434000ACB000009362003E9363003F304200FF38
+:1043500000021200306300FF00431025ACA20004ED
+:104360009362008200021600000216030441000559
+:10437000000000003C0308008C6300480A0010B5F0
+:10438000000000009362003E3042004014400003F1
+:104390000000182193620081304300FF9362008285
+:1043A00000031E00304200FF0002140000621825C6
+:1043B000ACA300088F620040ACA2000C8F620048E2
+:1043C000ACA200108F62004CACA200148F620050AF
+:1043D0008F63004C004310230441000300000000E1
+:1043E0000A0010C98F62004C8F620050ACA2001806
+:1043F0003C02080094424E963C03C00B0000202172
+:10440000004310250E000589ACA2001C8F620054E9
+:104410008F840020AC8200008F620058AC820004C0
+:104420008F62005CAC8200088F6200608F43007472
+:1044300000431021AC82000C8F620064AC8200103B
+:10444000976300689762006A00031C003042FFFF18
+:1044500000621825AC83001493620082240300805C
+:10446000304200FF14430003000000000A0010FD6A
+:10447000AC8000188F63000C240200011062000E53
+:104480002402FFFF9362003E304200401440000AC5
+:104490002402FFFF8F63000C8F4200740062182318
+:1044A0003C02080000621024144000020000282191
+:1044B0000060282100051043AC8200183C0208006F
+:1044C00094424E963C03C00C00002021004310256E
+:1044D0008F8300200E000589AC62001C8F620018DB
+:1044E0008F8300203C05080094A54E96240400010B
+:1044F000AC620000AC6000048F66006C3C02400DB2
+:1045000000A22825AC6600088F6200DCAC62000CBB
+:10451000AC6000109362000500021600AC6200144B
+:10452000AC6000180E000589AC65001C020020215B
+:104530008FBF00148FB00010A36000050A0004F2C2
+:1045400027BD00188FBF00148FB0001003E00008D3
+:1045500027BD00189742007C30C600FFA08600846B
+:104560003047FFFF2402000514C2000B24E346502D
+:1045700090A201122C4200071040000724E30A0019
+:1045800090A30112240200140062100400E2102122
+:104590000A0011353047FFFF3067FFFF03E00008D6
+:1045A000A4870014AC87004C8CA201080080402135
+:1045B00000A0482100E2102330C600FF184000038D
+:1045C00093AA001324E2FFFCACA2010830C2000150
+:1045D00010400008000000008D02005000E210238F
+:1045E00004410013240600058D02005410E200105F
+:1045F000000000008D02005414E2001A00000000C8
+:104600003C0208008C4200D8304200201040000AD2
+:1046100024020001910300789102008314430006F4
+:104620002402000101002021012028212406000489
+:104630000A00112300000000A100008411400009BD
+:10464000A50200148F4301008F4201F80440FFFED1
+:1046500024020002AF4301C0A34201C43C02100087
+:10466000AF4201F803E000080000000027BDFFE8AA
+:104670008FA90028AFBF00100080402100E9182357
+:104680001860007330C600FFA080007CA08000810D
+:104690008CA2010800E210230440004D000000003D
+:1046A0008C8200509483003C8C8400640047482333
+:1046B0003063FFFF012318210083202B10800004AA
+:1046C000000000008D0200640A00118600E2102143
+:1046D0009502003C3042FFFF0122102100E2102130
+:1046E000AD02005C9502003C8D03005C3042FFFF90
+:1046F0000002104000E210210043102B1040000384
+:10470000000000000A0011958D02005C9502003C3B
+:104710003042FFFF0002104000E21021AD02005CB9
+:10472000A1000084AD07004C8CA2010800E2102318
+:104730001840000224E2FFFCACA2010830C20001D4
+:104740001040000A000000008D02005000E210231B
+:1047500004410004010020218D02005414E20003F2
+:10476000000000000A0011B7240600058D02005465
+:1047700014E200478FBF00103C0208008C4200D8B2
+:10478000304200201040000A24020001910300780A
+:10479000910200831443000624020001010020213D
+:1047A000240600048FBF00100A00112327BD001843
+:1047B000A1000084A50200148F4301008F4201F87C
+:1047C0000440FFFE240200020A0011DC0000000089
+:1047D0008C82005C004910230043102B54400001E0
+:1047E000AC87005C9502003C3042FFFF0062102B5A
+:1047F00014400007240200029502003C8D03005C77
+:104800003042FFFF00621821AD03005C2402000269
+:10481000AD07004CA10200840E000FD78F440100A9
+:104820001040001B8FBF00108F4301008F4201F822
+:104830000440FFFE24020002AF4301C0A34201C4B2
+:104840003C021000AF4201F80A0011F28FBF0010C5
+:1048500030C200101040000E8FBF00108C83005C2F
+:104860009482003C006918233042FFFF0062182147
+:104870003C023FFF3444FFFF0083102B54400001F3
+:104880000080182101231021AD02005C8FBF0010B1
+:1048900003E0000827BD001827BDFFE88FAA002805
+:1048A000AFBF00100080402100EA482319200021FA
+:1048B00030C600FF8C83005C8C820064006A182381
+:1048C0000043102B504000100069182194A20110E1
+:1048D00001221021A4A2011094A201103042FFFF76
+:1048E0000043102B1440000A3C023FFF94A2011029
+:1048F00000431023A4A201109482003C3042FFFF29
+:104900000A00121100621821A4A001103C023FFF0E
+:104910003444FFFF0083102B544000010080182115
+:1049200000671021AD02005CA100007C0A00125952
+:10493000A100008130C200101040003C00000000C7
+:104940008C820050004A10231840003800000000FC
+:104950009082007C24420001A082007C9082007C36
+:104960003C0308008C630024304200FF0043102BFE
+:104970001440005C8FBF00108CA2010800E21023DD
+:1049800018400058000000008C8300549482003CC2
+:10499000006A18233042FFFF000318430002104052
+:1049A0000043102A10400005000000008C820054D3
+:1049B000004A10230A001240000210439482003C77
+:1049C0003042FFFF00021040AD0200649502003C3F
+:1049D0008D0400649503003C3042FFFF000210404C
+:1049E000008220213063FFFF008318210143102142
+:1049F000AD02005C8D020054ACA20108240200024A
+:104A0000A10200840E000FD78F4401001040003532
+:104A10008FBF00108F4301008F4201F80440FFFE5A
+:104A2000240200020A00128200000000AD07004CC0
+:104A30008CA2010800E210231840000224E2FFFCCF
+:104A4000ACA2010830C200011040000A00000000C2
+:104A50008D02005000E210230441000401002021D7
+:104A60008D02005414E20003000000000A001279D5
+:104A7000240600058D02005414E2001A8FBF0010B6
+:104A80003C0208008C4200D8304200201040000A4E
+:104A90002402000191030078910200831443000670
+:104AA0002402000101002021240600048FBF001011
+:104AB0000A00112327BD0018A1000084A5020014DC
+:104AC0008F4301008F4201F80440FFFE24020002E0
+:104AD000AF4301C0A34201C43C021000AF4201F841
+:104AE0008FBF001003E0000827BD00188FAA001038
+:104AF0008C8200500080402130C600FF004A102305
+:104B000000A048211840000700E0182124020001FD
+:104B1000A0800084A0A00112A48200140A0011F455
+:104B2000AFAA0010A0800081AD07004C8CA2010844
+:104B300000E210231840000224E2FFFCACA20108AE
+:104B400030C2000110400008000000008D0200503B
+:104B50000062102304410013240600058D02005456
+:104B600010620010000000008D0200541462001159
+:104B7000000000003C0208008C4200D830420020B7
+:104B80001040000A24020001910300789102008382
+:104B900014430006240200010100202101202821E5
+:104BA000240600040A00112300000000A100008474
+:104BB000A502001403E000080000000027BDFFE08C
+:104BC000AFBF0018274201009046000A8C4800142D
+:104BD0008C8B004C9082008430C900FF0168182340
+:104BE000304A00FF1C60001A2D4600062402000116
+:104BF0000142100410C00016304300030120302190
+:104C00000100382114600007304C000C15800009A9
+:104C1000304200301440000B8FBF00180A0012E32E
+:104C2000000000000E0011F4AFAB00100A0012E308
+:104C30008FBF00180E001169AFAB00100A0012E31D
+:104C40008FBF0018AFAB00100E001289AFAA00147E
+:104C50008FBF001803E0000827BD002024020003D6
+:104C6000A08200848C82005403E00008ACA20108FA
+:104C70003C02000803421821906200812406004390
+:104C80003C07601924420001A0620081906300810A
+:104C90003C0208008C4200C0306300FF1462001028
+:104CA0002403FF803C0208008C4200E000821021B7
+:104CB00000431024AF4200243C0208008C4200E074
+:104CC0003C03000A008210213042007F0342102181
+:104CD00000431021944500D40A000BBF30A5FFFF0C
+:104CE00003E000080000000027BDFFE0AFBF001890
+:104CF000AFB10014AFB000108F420180008080215E
+:104D000000A088210E0012EA00402021A2000084A9
+:104D10008E0200548FBF00188FB00010AE22010821
+:104D20008FB1001403E0000827BD002027BDFFE07D
+:104D30003C020008AFB00010AFBF0018AFB10014C4
+:104D4000034280218F510140920300848E04005061
+:104D50008E02004C14820040306600FF3C020800C6
+:104D60008C4200E02403FF80022210210043102423
+:104D7000AF4200243C0208008C4200E09744007CD3
+:104D800092050081022210213042007F0342182147
+:104D90003C02000A0062182114A0000B3084FFFFBF
+:104DA0002402000554C20014248205DC9062011222
+:104DB00024420001A062011224020C80AF420024B0
+:104DC0000A00134224020005A0600112240200051B
+:104DD00014C20009248205DC920200812C420007E3
+:104DE0005040000524820A0092030081240200142E
+:104DF00000621004008210213044FFFFA60400145A
+:104E00000E0012EA022020219602003C8E03004C84
+:104E1000022020213042FFFF0002104000621821D2
+:104E20000E000335AE03005C9202007D02202021BB
+:104E3000344200400E00033EA202007D8F4201F882
+:104E40000440FFFE24020002AF5101C0A34201C48E
+:104E50003C021000AF4201F88FBF00188FB1001460
+:0C4E60008FB0001003E0000827BD002008
+:044E6C0008000E7CB0
+:104E700008000EC408000F0408000F5008000F843B
+:104E80000A00002000000000000000000000000DEB
+:104E90006370342E362E31360000000004061004F4
+:104EA0000000000000000000000000000000000002
+:104EB00000000000000000000000000000000000F2
+:104EC00000000000000000000000002000000000C2
+:104ED00000000000000000000000000000000000D2
+:104EE00000000000000000000000000000000000C2
+:104EF0000000000000000000000000010000002B86
+:104F00000000000010000003000000000000000D81
+:104F10000000000D3C020800244258A43C03080095
+:104F200024635F70AC4000000043202B1480FFFD21
+:104F3000244200043C1D080037BD7FFC03A0F02183
+:104F40003C100800261000803C1C0800279C58A438
+:104F50000E00019C000000000000000D27BDFFE8CE
+:104F60003C096018AFBF00108D2C5000240DFF7F4E
+:104F700024080031018D5824356A380C24070C00B0
+:104F80003C1A8000AD2A50003C04800AAF4800085B
+:104F90003C1B8008AF4700240E000924AF8400109A
+:104FA0000E0008E7000000000E00083400000000BA
+:104FB0000E00125E000000003C0460168C850000AC
+:104FC0003C06FFFF3C02535300A618241062003F2A
+:104FD00034867C0094C201F2A780002C10400003AC
+:104FE000A78000CC38581E1EA798002C94C201F848
+:104FF00010400004978300CC38591E1EA79900CC9E
+:10500000978300CC2C7F006753E0000124030066E7
+:105010009784002C2C820401144000020060282197
+:10502000240404003C0760008CE904382403103C8D
+:105030003128FFFF1103001730B9FFFF5720000C84
+:10504000A38000CE24020050A38200CE939F00CE06
+:1050500013E0000A8FBF001027BD0018A78000CC06
+:10506000A780002CA780003403E00008A78000E69A
+:10507000939F00CE17E0FFF88FBF001027BD0018E8
+:10508000A78500CCA784002CA780003403E000088B
+:10509000A78000E6A38000CE8CCB003C316A0001E3
+:1050A0001140000E0000000030A7FFFF10E0FFE6F7
+:1050B000240200508CCC00C83186000114C0FFE4EB
+:1050C000939F00CE0A000072240200518C8F0004CE
+:1050D0003C0E60000A00005501EE30218CEF0808FC
+:1050E000240D5708000F740211CD000430B8FFFFE3
+:1050F000240500660A000073240404001700FFD48E
+:10510000939F00CE0A000072240200508F86001088
+:105110003089FFFF000939408CC300103C08005063
+:1051200000E82025AF4300388CC500142742040056
+:10513000AF82001CAF45003CAF44003000000000CF
+:10514000000000000000000000000000000000005F
+:105150000000000000000000000000008F4B000075
+:10516000316A00201140FFFD0000000003E000084C
+:10517000000000008F840010948A001A8C8700249D
+:105180003149FFFF000940C000E83021AF46003C34
+:105190008C8500248F43003C00A310231840002975
+:1051A000000000008C8B0020256200013C0D0050A7
+:1051B00035AC0008AF420038AF4C003000000000B2
+:1051C00000000000000000000000000000000000DF
+:1051D0000000000000000000000000008F4F0000F1
+:1051E00031EE002011C0FFFD000000008F4A0400D6
+:1051F0003C080020AC8A00108F490404AC890014DC
+:10520000AF48003000000000948600189487001C0E
+:1052100000C71821A48300189485001A24A2000155
+:10522000A482001A9498001A9499001E133800035F
+:105230000000000003E000080000000003E0000898
+:10524000A480001A8C8200200A0000CC3C0D005083
+:105250000A0000BD000000003C0308008C63002031
+:105260008F82001827BDFFE810620008AFBF001052
+:105270000E0000F4AF8300183C0308008C6300208C
+:1052800024040001106400048F8900108FBF0010F7
+:1052900003E0000827BD00188FBF00103C07601214
+:1052A000A520000A9528000A34E5001027BD001843
+:1052B0003106FFFF03E00008ACA600903C020800A6
+:1052C0008C42002027BDFFC8AFBF0034AFBE003006
+:1052D000AFB7002CAFB60028AFB50024AFB40020A4
+:1052E000AFB3001CAFB20018AFB1001410400050B3
+:1052F000AFB000108F840010948600069483000ADB
+:1053000000C3282330B6FFFF12C0004A8FBF00340D
+:1053100094890018948A000A012A40233102FFFF71
+:1053200002C2382B14E0000202C0202100402021DC
+:105330002C8C0005158000020080A021241400049C
+:105340000E0000A3028020218F8700100280982188
+:10535000AF80001494ED000A028088211280004E74
+:1053600031B2FFFF3C1770003C1540003C1E60004E
+:105370008F8F001C8DEE000001D71824507500504F
+:105380000220202102A3802B160000353C182000AB
+:105390005078004702202021241000018F83001440
+:1053A00014600039029158230230F8230250C821BA
+:1053B00033F1FFFF1620FFEE3332FFFF8F8700101F
+:1053C0003C110020AF5100300000000094E6000ABC
+:1053D0003C1E601237D5001002662821A4E5000AA1
+:1053E00094E2000A94F2000A94F400183057FFFF88
+:1053F0001292003BAEB700908CED00148CE40010CC
+:105400000013714001AE4021000E5FC3010E502B0E
+:10541000008B4821012A1821ACE80014ACE30010ED
+:1054200002D3382330F6FFFF16C0FFB98F84001077
+:105430008FBF00348FBE00308FB7002C8FB600288E
+:105440008FB500248FB400208FB3001C8FB20018DA
+:105450008FB100148FB0001003E0000827BD0038A2
+:10546000107E001B000000001477FFCC2410000108
+:105470000E0015A9000000008F8300141060FFCB00
+:105480000230F823029158238F87001001702021E9
+:105490000A0001873093FFFF8F8300141460FFCB55
+:1054A0003C110020AF5100300A0001530000000001
+:1054B0000E00079B024028210A000147004080217E
+:1054C0000E000341024028210A00014700408021CC
+:1054D0000E001471022020210A00014700408021A3
+:1054E0000E0000BD000000000A00016902D338234D
+:1054F00027BDFFE8AFB00010AFBF00140E000037AB
+:10550000000000003C028000345000700A0001AA34
+:105510008E0600008F4F000039EE000131C20001FD
+:10552000104000248F8600A88E0700003C0C080065
+:105530008D8C003C3C0908008D29003800E668236A
+:10554000018D28210000502100AD302B012A40217F
+:10555000010620213C010800AC25003CAF8700A8D3
+:105560003C010800AC2400380E0000F600000000EA
+:105570003C0308008C6300701060FFE6006020218F
+:105580003C0508008CA500683C0608008CC6006C31
+:105590000E001538000000003C010800AC2000702F
+:1055A0008F4F000039EE000131C200011440FFDED0
+:1055B0008F8600A88E0A00008F8B00A83C0508008B
+:1055C0008CA5003C3C0408008C840038014B482327
+:1055D00000A938210082182100E9402B0068102121
+:1055E0003C010800AC27003C3C010800AC2200381C
+:1055F0008F5F01002419FF0024180C0003F92024F8
+:1056000010980012AF840000AF440020936D00009A
+:10561000240C002031A600FF10CC0012240E0050F4
+:1056200010CE00043C194000AF5901380A0001A314
+:10563000000000000E0011D4000000003C194000E2
+:10564000AF5901380A0001A3000000000E00010F4D
+:10565000000000003C194000AF5901380A0001A3C6
+:10566000000000008F58010000802821330F00FF48
+:1056700001E020210E0002EEAF8F00043C19400033
+:10568000AF5901380A0001A30000000000A4102B4C
+:1056900024030001104000090000302100052840CB
+:1056A00000A4102B04A00003000318405440FFFC8A
+:1056B000000528405060000A0004182B0085382B94
+:1056C00054E000040003184200C330250085202365
+:1056D000000318421460FFF9000528420004182B4B
+:1056E00003E0000800C310213084FFFF30A5FFFF56
+:1056F0008F4201B80440FFFE3C0740800087302500
+:105700003C031000AF400180AF450184AF460188E3
+:1057100003E00008AF4301B83084FFFF8F4201B8B7
+:105720000440FFFE3C0740388CA600000087282577
+:105730003C031000AF460180AF45018803E000083C
+:10574000AF4301B88F8300388F8600301066000B9E
+:10575000008040213C07080024E75A18000328C0B5
+:1057600000A710218C44000024630001108800056C
+:105770003063000F5466FFFA000328C003E00008FE
+:10578000000010213C07080024E75A1C00A7302124
+:1057900003E000088CC200003C039000346200016A
+:1057A00000822025AF4400208F45002004A0FFFE8A
+:1057B0000000000003E00008000000003C0380003F
+:1057C000346200010082202503E00008AF4400207D
+:1057D00027BDFFE0AFB100143091FFFFAFB0001064
+:1057E000AFBF00181220001500A080218CA500007A
+:1057F00010A00013240400020E000C6B24060140CC
+:10580000AE0000008F4201B80440000D00002821C6
+:105810003C064000022620258FBF00188FB10014DF
+:105820008FB000103C03100027BD0020AF45018061
+:10583000AF44018803E00008AF4301B88CA5000025
+:105840008F4201B80440FFFE3C064000022620259E
+:105850008FBF00188FB100148FB000103C031000F0
+:1058600027BD0020AF450180AF44018803E0000858
+:10587000AF4301B83086FFFF8F4201B80440FFFEFE
+:105880003C0940068CA8000000C93825AF480180BB
+:105890008CA400043C031000AF440184AF4701888E
+:1058A00003E00008AF4301B827BDFFE0AFB0001030
+:1058B000AFBF0018AFB100149363003E0080802199
+:1058C0000080282130620040000020211040000F9D
+:1058D0008E1100000E000860022020219367000056
+:1058E0002404005030E500FF50A400128E0F000089
+:1058F000022020218FBF00188FB100148FB000103C
+:10590000A762013C0A00092027BD00200E00027D8D
+:10591000000000000E0008600220202193670000B4
+:105920002404005030E500FF14A4FFF202202021DF
+:105930008E0F00003C1008008E1000503C0D000C33
+:10594000240BFF8001F05021314E007F01DA6021ED
+:10595000018D4021014B4824AF490028022020211D
+:105960008FBF00188FB100148FB00010A50200D6B1
+:1059700027BD00200A000920AF8800D027BDFFE026
+:10598000AFBF0018AFB10014AFB0001093660001B4
+:10599000008080210E00024630D10004936400058F
+:1059A000001029C2A765000034830040A3630005EE
+:1059B0000E00024F020020210E00092202002021C9
+:1059C00024020001AF62000C02002821A76200102F
+:1059D00024040002A762001224060140A7620014FA
+:1059E0000E000C6BA76200161620000F8FBF001868
+:1059F000978C00343C0B08008D6B00782588FFFFE6
+:105A00003109FFFF256A0001012A382B10E000064A
+:105A1000A78800343C0F6006240E001635ED0010F8
+:105A2000ADAE00508FBF00188FB100148FB00010C2
+:105A300003E0000827BD002027BDFFE0AFB1001440
+:105A4000AFBF0018AFB0001000A088211080000A7E
+:105A50003C0360002402008010820012000000005D
+:105A60000000000D8FBF00188FB100148FB0001020
+:105A700003E0000827BD00208C682BF80500FFFE1E
+:105A800000000000AC712BC08FBF00188FB1001454
+:105A90008FB000103C09100027BD002003E0000873
+:105AA000AC692BF80E00024600A02021936500058A
+:105AB000022020210E00024F30B000FF2403003EE0
+:105AC0001603FFE7000000008F4401780480FFFE0A
+:105AD000240700073C061000AF510140022020219E
+:105AE000A34701448FBF00188FB100148FB000107E
+:105AF000AF4601780A0002BF27BD002027BDFFE89E
+:105B0000AFBF0014AFB000108F50002000000000A5
+:105B10000E000922AF440020AF5000208FBF0014B8
+:105B20008FB0001003E0000827BD00183084FFFF8D
+:105B30008F4201B80440FFFE3C0740350087302506
+:105B40003C031000AF450180AF400184AF4601889F
+:105B500003E00008AF4301B83084FFFF8F4201B873
+:105B60000440FFFE3C074036008730253C03100010
+:105B7000AF450180AF400184AF46018803E00008D3
+:105B8000AF4301B827BDFFD0AFB3001C3093FFFF78
+:105B9000AFB50024AFB20018AFBF0028AFB40020EB
+:105BA000AFB10014AFB0001030B5FFFF1260002796
+:105BB000000090218F90001C8E0300003C068000A6
+:105BC0002402004000033E0200032C0230E4007F68
+:105BD000006688241482001D30A500FF8F830028F2
+:105BE0002C68000A510000108F91001400035880A7
+:105BF0003C0C0800258C56CC016C50218D490000CE
+:105C0000012000080000000002B218213065FFFFEB
+:105C10000E00021A24040084162000028F90001C3B
+:105C2000AF8000288F910014260C0020264B000125
+:105C3000018080213172FFFF16200004AF8C001C10
+:105C40000253402B1500FFDC000000000240102131
+:105C50008FBF00288FB500248FB400208FB3001CA5
+:105C60008FB200188FB100148FB0001003E000084D
+:105C700027BD0030240D003414AD00F600000000F4
+:105C8000920B000E240A16803C07000CA36B002127
+:105C90009203000D0347F8213C066000A363002037
+:105CA000961100123C087FFF350CFFFFA771003CE6
+:105CB00096020010240B00053054FFFFAF740084DF
+:105CC0008E19001CAF4A00288FF800008CCF444882
+:105CD0000319702601EE3021AF66004C8F69004C2D
+:105CE00024CD00013C197F00AF6900508F64005043
+:105CF000AF640054AF660070AF6D00588F650058F8
+:105D000024040050AF65005CA3600023AF6C006406
+:105D1000A36B00378E030014AF6300488F710048F7
+:105D2000AF7100248E020018AF62006C9214000C58
+:105D3000A3740036936A003E355F0020A37F003EC7
+:105D40008F7800740319782435EE4000AF6E00742C
+:105D500093700000320900FF112402332418FF80E1
+:105D60003C04080024845A980E00028A00000000B7
+:105D700024060004240700013C0408008C845A987F
+:105D8000A366007DA36700058F4A01780540FFFEEA
+:105D900024020002AF440140A34201448F90001C42
+:105DA0003C141000AF5401780A000369AF8000284A
+:105DB0002CAD003751A0FF9C8F9100140005A080EE
+:105DC0003C180800271856F4029878218DEE000040
+:105DD00001C00008000000002406000614A60011FF
+:105DE000000000003C1F08008FFF5A9824040005A3
+:105DF000AF5F00208E190018AF7900188F78004C23
+:105E0000AF78001C8F6F0050122000C2AF6F00707F
+:105E10000A000369AF840028240A000710AA00843E
+:105E2000240300063C05080024A55A980E000254DD
+:105E3000240400818F90001C0011102B0A000369BC
+:105E4000AF820028240A000414AAFFF6240300509D
+:105E50003C0E08008DCE5A98AF4E00208E090008E7
+:105E6000AF6900408E060008AF6600448E07000C44
+:105E7000AF6700488E040010AF64004C8E0D001018
+:105E8000AF6D00848E080014AF6800508E050018B6
+:105E9000AF6500548E0C001CAF6C0058936B000073
+:105EA000317400FF128301F5000000008F64004888
+:105EB0008F6600400086382304E000042404008C30
+:105EC0001620FFDE24020003240400823C050800A3
+:105ED00024A55A980E00027D000000008F90001C3F
+:105EE000000010210A000369AF8200282409000580
+:105EF00014A9FFCC240520003C0A08008D4A5A98BA
+:105F0000AF4A00208E1F0004AF7F005C921900088A
+:105F100024100008A37900218F98001C930F00091A
+:105F2000A36F00208F86001C90CE000A31C400FFB2
+:105F300010900010288300091460006C24020002F5
+:105F4000240800201088000B3405800028850021DB
+:105F500014A0000824054000240D0040108D000509
+:105F60003C05000124070080108700023C05000268
+:105F7000240540008F6E00743C0FFF0001CF802489
+:105F800002054825AF69007490C4000BA36400812A
+:105F90008F84001C9486000C10C0019B0000000040
+:105FA000948E000C241FFFBF24060004A76E003C43
+:105FB0009090000EA370003E8F89001C9124000F6A
+:105FC000A364003F8F94001C8E8D00108F470074D7
+:105FD00001A72823AF6500608E880014AF680064B5
+:105FE000968C0018A76C0068968B001AA76B006A45
+:105FF0008E82001CAF62006C96830002A763013E94
+:10600000928A000EA36A003E9379003E033FC024AB
+:106010001220016AA378003E8F90001C0A000369D9
+:10602000AF8600282414002214B4FF7E2403000746
+:106030003C0208008C425A981220000CAF4200200B
+:106040000A000369AF830028240C003310AC00144D
+:10605000240800283C05080024A55A980E000226B2
+:10606000240400810A0003EE8F90001C3C04080009
+:1060700024845A980E00028A00000000936B0000EE
+:1060800024110050316300FF107101540000000022
+:106090008F90001C000018210A000369AF830028BC
+:1060A0003C0508008CA55A9824040081AF450020C7
+:1060B000A36800343C05080024A55A980E00022667
+:1060C000000000008F90001C240200090A000369F0
+:1060D000AF82002802B288213225FFFF0E00021A8B
+:1060E000240400840A0003698F90001C1082FFA121
+:1060F000240504002894000312800176240C000477
+:10610000240B0001548BFF9B240540000A00043D32
+:10611000240501003C04080024845A988F62004C36
+:106120000E00028A8F6300508F90001C0000202117
+:106130000A000369AF8400288E1000042404008A3A
+:10614000AF500020936E000531C900021520016593
+:10615000020028219378002302002821330F002019
+:1061600015E001602404008D9362003F24190012A1
+:10617000305F00FF13F9015B240400810E0002462A
+:106180000200202193740023240A0004020020212D
+:1061900036830042A36300230E00024FA36A007DF2
+:1061A0008F4B01780560FFFE24050002AF500140CF
+:1061B000A34501448F90001C3C0C1000AF4C0178AB
+:1061C0000A0003EF0011102B8E1000042404008A33
+:1061D000AF500020936D000531A800021500001992
+:1061E000020028219367003F2414001230E400FFCE
+:1061F0001094010100000000936E003F240600048B
+:1062000031C900FF112600FC000000000E0002460C
+:1062100002002021936200232419FFFE02002021A6
+:10622000345F0020A37F0023A374003F9378000510
+:10623000031978240E00024FA36F000502002821E5
+:10624000000020210E000336000000000A0003EECB
+:106250008F90001C8E0500043C0F0008034F402166
+:10626000AF450020910E00002406005031C900FF08
+:106270001126017A240400888F5901B80720FFFEF7
+:106280003C0C400E008C58253C031000AF450180AB
+:10629000AF400184AF4B0188AF4301B891020000C9
+:1062A000240AFF8024040004004AF825A11F0000EE
+:1062B0000E000C6B240600300A0003EE8F90001CC9
+:1062C0008E04001C0E000231000000001040014C42
+:1062D000004048218F90001C240500898F4D01B893
+:1062E00005A0FFFE00000000AF4901808E0F001CDA
+:1062F0003C1440010011702B00B448253C111000E3
+:10630000AF4F0184AF8E0028AF490188AF5101B86B
+:106310000A00036A8F910014961900023C140800C9
+:1063200026945A9833380004130000F23C026000AF
+:106330008E1F001C3C010800AC3F5A98AF5F002044
+:10634000920C0010240B0014318400FF148B011CEC
+:106350000000000096090002312D000115A001B2D5
+:10636000000000008E020004AE8200083C0E08000F
+:106370008DCE5AA011C001A8000000008F690074E2
+:106380003C0E800024040001012E6825AF6D0074CE
+:10639000A3600005AF64000C3C0C08008D8C5AA073
+:1063A0008F88001CA7640010000C59C2A76400125B
+:1063B000A7640014A7640016A76B00088D030008EB
+:1063C00024040002AF63002C8D0A000CAF6A003079
+:1063D00091070010A36700348F82001C90450011C4
+:1063E000A36500358F86001C90D00012A370003684
+:1063F0008F9F001C93F90013A37900378F90001C26
+:1064000096180014A778003896140016A774003A5E
+:106410008E0F0018AF6F00245620FE02AF840028B4
+:106420003C05080024A55A980E00025400002021C3
+:106430008F90001C0A0004AC000020218E0F000485
+:106440003C14080026945A983C010800AC2F5A9836
+:10645000AF4F0020920E000331C90004112000024A
+:106460002402001224020006A362003F9203001BD4
+:10647000240AFFC03062003F004AF825A37F003E97
+:106480009219000333380001170000C1000000001A
+:106490008E020008AE8200083C0208008C425AA01E
+:1064A000104000C000000000000221C2A7640008E4
+:1064B0008E0D000C240B000124140014AF6D002C71
+:1064C0008E080010AF68003096050016A7650038EA
+:1064D000960C0014A76C003AAF6B000CA76B001071
+:1064E000A76B0012A76B0014A76B0016122000EB1D
+:1064F000A37400349206000330C700022CF00001A0
+:10650000260200088F90001C0A000369AF82002851
+:106510008E14000424030081AF54002093680023EC
+:106520003105001010A000AC000000008F4401B83D
+:106530000480FFFE3C06401F0011382B006610252A
+:106540003C111000AF540180AF870028AF40018498
+:10655000AF420188AF5101B80A00036A8F9100145D
+:106560008E0600043C19000803592021AF46002084
+:106570008E07000890980000240F0050331400FF8D
+:10658000128F00A7240500888F4401B80480FFFE05
+:106590003C0D40090011602B00AD10253C1110008E
+:1065A000AF460180AF8C0028AF470184AF4201881D
+:1065B000AF5101B80A00036A8F9100143C0508002E
+:1065C00024A55A980E00027D240400828F90001C9E
+:1065D000000030210A000369AF8600283C0408004F
+:1065E0008C845A980E0014F6000000008F90001C56
+:1065F0000A000486000018210E00033624040081DE
+:106600000A0003EE8F90001C3C05080024A55A9850
+:106610000E00027D2404008B8F90001C0011302B93
+:106620000A000369AF8600283C1908008F395A9880
+:106630003C1F08008FFF005024CCFFFE033F782151
+:1066400001F87024AF4E00283C0408008C845A984E
+:106650003C0908008D2900500089682131A5007F80
+:1066600000BA402101078021AE0600D8AF9000D0CB
+:10667000AE0000DC0A0003B8AE0C0108AF60008475
+:106680003C0808008D085A983C0D08008DAD00505C
+:106690002405FF803C02000C010D58210165602497
+:1066A000AF4C00288E0A00143174007F029A182122
+:1066B00000627821ADEA00D88E1F0014AF8F00D0A1
+:1066C000ADFF00DC8E1900102738FFFE0A00040B16
+:1066D000ADF80108548CFE27240540000A00043D53
+:1066E000240510000E00032B000000000A0003EE3A
+:1066F0008F90001C8C46442C3C056C6234B0797041
+:106700003C010800AC205A9814D000082404000270
+:1067100097880034978A002C02802821010A382BA0
+:1067200010E0001124040092240400020E000C89E1
+:10673000240501403C010800AC225A98AF420020D9
+:106740003C0308008C635A98106000052404008301
+:106750000E000854000000001040000924040083CB
+:106760003C05080024A55A980E00025400000000C1
+:106770008F90001C0011202B0A000369AF840028B1
+:106780000E000858000000000A0005308F90001C21
+:106790008E0400080E000231000000000A00058689
+:1067A000AE8200083C05080024A55A980E00022677
+:1067B000240400878F90001C0A0005A20011102BF2
+:1067C0000E00085C000000003C05080024A55A9853
+:1067D0000A00063A2404008B0E00024602802021A3
+:1067E0009370002302802021360D00100E00024F0E
+:1067F000A36D00238F90001C0A0005AB0000182138
+:10680000240400040E000C89240500301440002AE2
+:10681000004048218F90001C0A00051724050083C2
+:106820009205000C30BF000113E0000300000000DF
+:106830009602000EA482002C920A000C314800023D
+:106840001100FF5100002821960B00128E03001446
+:10685000A48B001A0A0005C2AC83001C8F83003889
+:106860008F8700301067FE84000020213C0908005B
+:1068700025295A1C000320C0008930218CD4000037
+:106880001285005E247800013303000F5467FFFA7D
+:10689000000320C00A0004FE000020213C0508007F
+:1068A00024A55A980E00027D240400828F90001CBB
+:1068B0000A0005A2000010213C0B0008034B202118
+:1068C00024030050240A0001AF420020A0830000EE
+:1068D000A08A00018F88001C91070004A08700187F
+:1068E0008F82001C90450005A08500198F86001C32
+:1068F00090DF0006A09F001A8F99001C93380007B4
+:10690000A098001B8F94001C928F0008A08F001C81
+:106910008F90001C920E0009A08E001D8F8D001C10
+:1069200091AC000AA08C001E8F8B001C3C0C080050
+:10693000258C5A1C9163000B3C0B0800256B5A18E0
+:10694000A083001F8F8A001C9148000CA0880020A3
+:106950008F87001C90E5000DA08500218F82001C10
+:10696000240546469046000EA08600228F9F001CFC
+:1069700093F9000FA09900238F98001C9314001026
+:10698000A09400248F8F001C91F00011A09000258E
+:106990008F90001C8F8E00308F990038960D001458
+:1069A000000E18C025C80001A48D0028960A001604
+:1069B000006C3021006BF821A48A002A9607001889
+:1069C0003108000FA487002CA485002E8E02001C25
+:1069D000ACC90000AF88003011190003AFE200001D
+:1069E0000A00051700002821250C00013184000F42
+:1069F000000028210A000517AF8400383C07080072
+:106A000024E75A180087802100002021ACC0000034
+:106A10000A0004FEAE0000003C05080024A55A98B8
+:106A20000A00063A240400878E0400040E00023196
+:106A3000000000000A00053BAE8200083084FFFF22
+:106A400030C600FF8F4201B80440FFFE000644003C
+:106A5000010430253C07200000C720253C0310001E
+:106A6000AF400180AF450184AF44018803E00008D6
+:106A7000AF4301B827BDFFE8AFB00010AFBF0014AF
+:106A80003C076000240600021080000600A0802160
+:106A90000010102B8FBF00148FB0001003E000080F
+:106AA00027BD00183C09600EAD2000348CE5201C89
+:106AB0008F82001C2408FFFC00A81824ACE3201CD3
+:106AC0000E0006EF8C45000C0010102B8FBF001439
+:106AD0008FB0001003E0000827BD00183C02600ED4
+:106AE0003447010024090018274A04000000000070
+:106AF00000000000000000003C06005034C302000B
+:106B0000AF440038AF45003CAF430030014018218E
+:106B10008F4B0000316800201100FFFD2406007F2C
+:106B20002408FFFF8C6C000024C6FFFF24630004D0
+:106B3000ACEC000014C8FFFB24E7000400000000D8
+:106B400000000000000000003C0F0020AF4F0030AC
+:106B50000000000024AD020001A5702B2529FFFFD5
+:106B6000008E20211520FFE101A0282103E000086C
+:106B70000000000027BDFFE0AFB10014AFBF001858
+:106B8000AFB000103C05600E8CA20034008088215C
+:106B9000144000063C0460008C87201C2408FFFC85
+:106BA00000E8302434C30001AC83201C8F8B001C10
+:106BB00024090001ACA90034956900028D65001418
+:106BC0008D70000C2D2400818D6700048D660008F7
+:106BD000108000078D6A00102D2C00041580000E17
+:106BE00030CE0007312D000311A0000B0000000083
+:106BF0002404008B020028210E0006EF2406000367
+:106C00000011102B8FBF00188FB100148FB000102F
+:106C100003E0000827BD002015C0FFF62404008B08
+:106C20003C030020AF4300300000000024020001BC
+:106C3000AF8200140000000000000000000000000F
+:106C40003C1F0150013FC825253800033C0F600E52
+:106C5000AF47003800181882AF46003C35E8003CCA
+:106C6000AF590030274704008F44000030860020D1
+:106C700010C0FFFD00000000106000082466FFFF48
+:106C80002403FFFF8CEB000024C6FFFF24E7000471
+:106C9000AD0B000014C3FFFB250800043C08600E88
+:106CA000AD090038000000000000000000000000F6
+:106CB0003C070020AF470030000000000E0007171F
+:106CC0000140202102002821000020210E0006EFB3
+:106CD000240600030011102B8FBF00188FB1001481
+:106CE0008FB0001003E0000827BD002027BDFFD8AB
+:106CF000AFB200183092FFFFAFB10014AFBF002059
+:106D0000AFB3001CAFB000101240002C000088216F
+:106D10000A0007AF2413000150B3003C8CE5000CBF
+:106D20000000000D262D000131B1FFFF24EC0020F2
+:106D30000232382B10E00021AF8C001C8F8200142F
+:106D40001440001E8F87001C3C0670003C0320008E
+:106D50008CE400000086282414A300188F85003CD2
+:106D6000000444023C0980000089802414A0FFEA4A
+:106D7000310600FF2404000210C4001F28CA0003CB
+:106D800011400016240B000314D3FFE7262D000149
+:106D9000020028210E0006FD240400018F87001C3C
+:106DA000AF82003C262D000131B1FFFF24EC002012
+:106DB0000232382B14E0FFE1AF8C001C02201021BE
+:106DC0008FBF00208FB3001C8FB200188FB100144A
+:106DD0008FB0001003E0000827BD002814CBFFD2BD
+:106DE000262D00010E00073D020020218F87001C88
+:106DF0000A0007C9AF82003C020028210E0006FDF0
+:106E0000000020210A0007C88F87001C0E0006EF33
+:106E1000240400841600FFC38F87001C0A0007A902
+:106E2000AF80003C3082FFFF1440000300001821B7
+:106E30000004240224030010308500FF14A0000584
+:106E40003087000F246600080004220230C300FFD0
+:106E50003087000F14E00005308900032468000427
+:106E600000042102310300FF3089000315200005D2
+:106E7000388B0001246A000200042082314300FFA5
+:106E8000388B00013164000110800002246C000185
+:106E9000318300FF03E0000800601021308BFFFF0A
+:106EA000000B394230E600FF3C09080025295998BB
+:106EB00000064080010960218D8700003164001FB9
+:106EC000240A0001008A180430A500FF00E32025F1
+:106ED00014A000020003102700E22024240F000168
+:106EE00000CF700401096821000E282714800005D6
+:106EF000ADA400008F86000C00A6102403E000085B
+:106F0000AF82000C8F88000C01C8102503E0000838
+:106F1000AF82000C3C06001F3C0360003084FFFF82
+:106F200034C5FF8024020020AC602008AC60200C37
+:106F3000AC602010AC652014AC642018AC6220005A
+:106F4000000000000000000003E000080000000056
+:106F500027BDFFE82402FFFFAFBF0010AF82000C87
+:106F6000000020213C06080024C659982405FFFF94
+:106F700024890001000440803124FFFF010618210C
+:106F80002C87002014E0FFFAAC6500000E000825F5
+:106F900000002021240200013C04600024050020A0
+:106FA000AC822018AC85200000000000000000002A
+:106FB00000000000244A00013142FFFF2C4604007B
+:106FC00014C0FFF78FBF001003E0000827BD0018B2
+:106FD0008F8300082C62040003E00008384200019F
+:106FE0008F8300082462000103E00008AF820008DC
+:106FF0008F8300082462FFFF03E00008AF820008CF
+:1070000027BDFFE0AFB10014AFBF0018AFB0001054
+:107010008F6B00303C06600000808821ACCB2008DC
+:107020008F6A002C3C02800024030008ACCA200CAC
+:107030009769003A9768003800092C003107FFFF74
+:1070400000A72025ACC42010ACC22014ACC3200083
+:107050000000000000000000000000003C03600091
+:107060008C6D200031AC00081580FFF90000000095
+:107070008C6E201405C00020000000000E0007E9FF
+:107080008F84000C000240803C0908002529599893
+:10709000010938218CE400000E0007E9000281405C
+:1070A000020220213090FFFF020020210E0008077D
+:1070B000000028213C0C8000022C58253210FFFFD4
+:1070C0003C116000240A0020AE2B2014AE302018A2
+:1070D000AE2A2000000000000000000000000000B8
+:1070E000020010218FBF00188FB100148FB0001064
+:1070F00003E0000827BD00208C6620143C02001F1E
+:107100003443FF803C1FFFE800C3C02437F9080068
+:1071100003198021001079C23C0C8000022C5825F4
+:1071200031F0FFFF3C116000240A0020AE2B201438
+:10713000AE302018AE2A2000000000000000000041
+:1071400000000000020010218FBF00188FB1001452
+:107150008FB0001003E0000827BD002027BDFFE826
+:10716000AFB000103402FFFF3090FFFFAFBF00143C
+:1071700012020006020020210E0008250000000077
+:10718000020020210E000807240500018F8400085A
+:107190008FBF00148FB000102483FFFF27BD00189D
+:1071A00003E00008AF830008000439C230E6003F66
+:1071B00000043B4200071840240210002CC40020A9
+:1071C00024C8FFE0AF42002C2463000114800003B8
+:1071D00030A900FF00071840310600FF000360805F
+:1071E00024080001019A58213C0A000E00C8280416
+:1071F000016A382111200005000530278CE90000C4
+:107200000125302503E00008ACE600008CEE00000C
+:1072100001C6682403E00008ACED000027BDFFE8CC
+:10722000AFBF0014AFB000103C0460008C850808AC
+:107230003403F00030A2F0005043000624020001A5
+:107240008C8708083404E00030E6F00010C4001E0B
+:1072500024020002AF8200403C1060003C0A0200A1
+:10726000AE0A0814240910003C08000E8E034400E6
+:1072700003482021AF49002C240501200E000CCF2B
+:10728000000030218F830040106000043C02169102
+:10729000240B0001106B000E3C023D6C344F00903B
+:1072A000AE0F44088FBF00148FB000103C0C60007C
+:1072B000240E10003C0D020027BD0018AD8E4420A6
+:1072C00003E00008AD8D08100A0008F6AF8000400A
+:1072D0003C0218DA344F0090AE0F44088FBF001400
+:1072E0008FB000103C0C6000240E10003C0D02001A
+:1072F00027BD0018AD8E442003E00008AD8D0810B6
+:107300000A0008CA240500010A0008CA0000282152
+:107310003C08080025085DA42404FFFF0100182193
+:107320002402001E2442FFFFAC6400000441FFFD64
+:10733000246300043C07080024E75E208CE5FFFC82
+:107340002404001C24060001308A001F0146480462
+:1073500024840001000910272C8300201460FFFA08
+:1073600000A22824ACE5FFFC3C05666634A4616EEF
+:107370003C06080024C65EE0AF840058AF88009C3D
+:107380002404FFFF00C018212402001F2442FFFF35
+:10739000AC6400000441FFFD246300043C07666602
+:1073A0003C05080024A55EA0AF86004834E6616E67
+:1073B000AF8600982404FFFF00A018212402000FCC
+:1073C0002442FFFFAC6400000441FFFD246300047D
+:1073D0003C0B66663C06080024C65E203568616E7C
+:1073E000AF8500A4AF8800702404FFFF00C01821FF
+:1073F0002402001F2442FFFFAC6400000441FFFD93
+:10740000246300043C0D66663C0A0800254A5F6060
+:1074100035AC616EAF860090AF8C005C2404FFFF3A
+:1074200001401821240200032442FFFFAC64000045
+:107430000441FFFD246300043C09080025295F7016
+:107440008D27FFFC24040006240500013099001F4D
+:107450000325C00424840001001878272C8E002006
+:1074600015C0FFFA00EF3824AD27FFFC3C09666623
+:1074700024030400240403DC24050200240600661F
+:107480003522616E3C08080025085AA4AF820074BA
+:10749000AF830044AF83006CAF830050AF830084A0
+:1074A000AF8A008CAF840064AF85004CAF86005477
+:1074B000AF840078AF850060AF860080010018219E
+:1074C000240200022442FFFFAC6000000441FFFDE3
+:1074D00024630004240400032403000C3C0A080075
+:1074E000254A5AB0AF8A00680A00099D2405FFFFAB
+:1074F0000004188024840001006858212C8700C0F3
+:1075000014E0FFFBAD6500003C0E666635CD616E94
+:10751000240C17A024081800AF8D0088AF8C0094AD
+:1075200003E00008AF88007C2484007F000421C2AF
+:1075300000004021000030210000382100002821F7
+:107540000A0009B4AF8400A01060000624E700011F
+:1075500000C4302124A500012CC20BF51440FFFA11
+:107560002CA300663C09080025295F600120182132
+:10757000240200032442FFFFAC6000000441FFFD31
+:107580002463000410E0001A24E3FFFF00032942F3
+:1075900010A0000A000020212406FFFF3C03080081
+:1075A00024635F60248400010085502BAC660000DA
+:1075B000250800011540FFFB2463000430E2001F92
+:1075C0001040000800086880240C0001004C3804BA
+:1075D000000858800169282124E6FFFF03E0000825
+:1075E000ACA6000001A940212409FFFFAD0900005D
+:1075F00003E0000800000000AF4400283C04000C39
+:1076000003442021000528820A000CCF000030210D
+:10761000000421803C036000AC64100800000000FE
+:1076200000052980AC65100C0000000003E0000894
+:107630008C62100C27BDFFE800802821240400384C
+:10764000AFBF00140E0009E4AFB0001024040E0018
+:10765000AF4400283C10000C0350202124050010EA
+:107660000E000CCF0000302103501021AC40000070
+:10767000AC400004240400388FBF00148FB0001009
+:1076800024053FFF27BD00180A0009E48C430000D1
+:10769000000421803C036000AC641008000000007E
+:1076A0008C62100C03E000080002118227BDFFC8A5
+:1076B000AFB400208F940068AFBE0030AFB7002C8D
+:1076C000AFB600280000B8210080B021241E00C001
+:1076D000AFBF0034AFB50024AFB3001CAFB2001889
+:1076E000AFB10014AFB000100A000A21AFA5003CF2
+:1076F000504000018F94006827DEFFFF13C0002870
+:10770000269400048E9200003C03080024635DA0D0
+:107710001240FFF70283102B3C04080024845AA473
+:10772000028410230002A8C0000098210A000A3039
+:1077300024110001001188401220002600000000E2
+:1077400002B38021025128240200202110A0FFF959
+:10775000267300010E0009ED0000000000166840CD
+:1077600032EC000101AC20210E0009E402002821C6
+:107770008F89009426F700018FA6003C3AEB0001A8
+:10778000316A00012528FFFF0011382702CAB02105
+:10779000AF88009416E6FFE702479024AE920000FF
+:1077A00002E010218FBF00348FBE00308FB7002C55
+:1077B0008FB600288FB500248FB400208FB3001C33
+:1077C0008FB200188FB100148FB0001003E00008D2
+:1077D00027BD00383C0E080025CE5DA0028E102B80
+:1077E0000A000A1CAE92000027BDFFD8AFB10014FA
+:1077F000AFB00010AFBF0020AFB3001CAFB2001895
+:1078000000A0882110A0001F000480403C13080045
+:1078100026735AA40A000A692412000112200019D2
+:10782000261000010E000A0402002021000231424D
+:107830002444FFA0000618803045001F2C8217A1A9
+:10784000007318212631FFFF1040FFF400B230040E
+:107850008C6900000200202124053FFF01264024FE
+:107860001500FFEE012638250E0009E4AC67000084
+:107870008F8A009426100001254700011620FFE999
+:10788000AF8700948FBF00208FB3001C8FB2001809
+:107890008FB100148FB0001003E0000827BD00284E
+:1078A0008F85009C00805821000040210000482165
+:1078B000240A001F3C0C0800258C5E1C3C0D0800AF
+:1078C00025AD5DA48CA6000050C00014000040212E
+:1078D00000AD1023000238C0240300010A000AA2F0
+:1078E000000020211500000300E41021244820247A
+:1078F0000000482125290001512B00132506DFDC5B
+:10790000106000062484000100C3702415C0FFF538
+:10791000000318400A000AA00000402110AC002615
+:1079200024A3000400602821254AFFFF1540FFE53D
+:10793000AF85009C512B00042506DFDC00004021B0
+:1079400003E00008010010210006614230C5001F5D
+:10795000000C50803C07080024E75DA424040001CB
+:10796000014730211120000F00A420043C0508002D
+:1079700024A55E20148000052529FFFF24C60004ED
+:1079800010C5001100000000240400018CCF00008D
+:107990000004C0270004204001F868241520FFF5EA
+:1079A000ACCD00008F99007801001021032B4823F3
+:1079B00003E00008AF8900783C05080024A55DA419
+:1079C0000A000AAA000040213C06080024C65DA463
+:1079D0000A000AC324040001308800FF24020002C8
+:1079E0001102000A240300031103005C8F8900A424
+:1079F000240400041104005F24050005110500673C
+:107A00000000182103E00008006010218F89004861
+:107A10003C0C0800258C5EE03C04080024845F6078
+:107A2000240300201060000F00005821240D0002E4
+:107A3000240E00033C0F080025EF5EE08D270000B8
+:107A400014E0000B30F9FFFF252900040124C02BAE
+:107A500053000001018048212463FFFF5460FFF8B8
+:107A60008D2700000160182103E00008006010214C
+:107A7000132000323C0500FF30E200FF00403021BF
+:107A80001040004200005021240500010000202188
+:107A90000005C84000A6C02417000003332500FFDE
+:107AA00014A0FFFB24840001012CC023001828C06F
+:107AB00000AA6021008C50213144001F240C0001D9
+:107AC000008C18040003102700E23024110D00413F
+:107AD000AD260000110E004C000A1840110D0036B2
+:107AE0008F87006C510E00568F8C0060240D0004AF
+:107AF000110D005A8F8E0084240E0005150EFFDA3A
+:107B000001601821240B14301140000600001821D8
+:107B10008F8400A024630001006A402B1500FFFD44
+:107B2000016458218F8A0080AF89008C0160182180
+:107B30002549FFFF0A000AFAAF89008000E52024EA
+:107B4000000736021080FFD0240A001800075402F4
+:107B5000314600FF0A000B02240A00103C0C08000A
+:107B6000258C5EA03C04080024845EE00A000AE93B
+:107B7000240300103C0C0800258C5E203C04080007
+:107B800024845EA00A000AE88F89009000071A0288
+:107B9000306600FF0A000B02240A00088F89008C5F
+:107BA0003C0C0800258C5F603C04080024845F7056
+:107BB0000A000AE924030004000A4080250B003073
+:107BC00024E6FFFF01601821AF8900480A000AFA85
+:107BD000AF86006C000AC982001978803C07080053
+:107BE00024E75EA001E72021000A18428C8F0000E4
+:107BF0003079001F032C38040007C02701F86024E7
+:107C00000A000B17AC8C00000003314200062880EC
+:107C100000AF28213062001F8CB8000024630001EF
+:107C2000004CC804000321420019382700041080CA
+:107C300003073024004F20210A000B5BACA6000094
+:107C4000000A68C025AB0032258AFFFF01601821B9
+:107C5000AF8900A40A000AFAAF8A0060254B1030F1
+:107C6000AF8900900160182125C9FFFF0A000AFAB8
+:107C7000AF890084308600072CC200061040001433
+:107C800000000000000640803C030800246357D039
+:107C9000010338218CE4000000800008000000008F
+:107CA0002409000310A9000E00000000240A0005AA
+:107CB00010AA000B00000000240B000110AB00080C
+:107CC000000000008F8C00A010AC00050000000038
+:107CD00003E00008000010210A000A8800A020210B
+:107CE0000A000AD600C0202127BDFFE8308400FF2B
+:107CF000240300021083000BAFBF00102406000312
+:107D00001086003A2408000410880068240E00053C
+:107D1000108E007F2CAF14308FBF001003E00008DE
+:107D200027BD00182CA200301440FFFC8FBF0010AC
+:107D300024A5FFD0000531C2000668803C0708007A
+:107D400024E75EE001A730218CC9000000052882ED
+:107D500030AC001F240B0001018B50048F840048BD
+:107D6000012A4025ACC800008C830000506000014F
+:107D7000AF8600488F98006C30AE000124A6FFFF4C
+:107D8000270F000115C00002AF8F006C24A6000170
+:107D90000006414200082080008718218C790000ED
+:107DA00030C2001F240600010046F804033F3824B7
+:107DB00010E0FFDA8FBF00100005C182001870804C
+:107DC0003C0F080025EF5EA001CF48218D2B00005D
+:107DD0000005684231A5001F00A66004016C502513
+:107DE00027BD001803E00008AD2A00002CA70030D2
+:107DF00014E0FFCA8FBF001030B900071723FFC778
+:107E000024A8FFCE00086A02000D60803C0B080029
+:107E1000256B5EA0018B30218CC40000000828C2B5
+:107E200030AA001F24080001014848048F8200A4E2
+:107E300000891825ACC300008C5F000053E00001EE
+:107E4000AF8600A400057040000E7942000F288024
+:107E50003C04080024845EE000A418218C6B000020
+:107E600025DF000131CD001F001F514201A8600431
+:107E7000016C4825000A1080AC69000000442821EC
+:107E80008CA600008F98006033F9001F8FBF001090
+:107E90000328380400C77825270E000127BD0018E5
+:107EA000ACAF000003E00008AF8E006024A5EFD067
+:107EB0002CB804001300FF998FBF00100005314259
+:107EC000000658803C0A0800254A5E20016A3021DD
+:107ED0008CC4000030A3001F2409000100691004B5
+:107EE0008F9900900082F825ACDF00008F270000FA
+:107EF00050E00001AF8600908F8D00848FBF00108E
+:107F000027BD001825AC000103E00008AF8C0084F9
+:107F100015E0FF828FBF00108F8600A00006104082
+:107F20000046F821001F210003E4C8210019384051
+:107F300024F8143000B8402B1100FF788FBF0010D8
+:107F400024A4EBD00E00020300C0282100027942D5
+:107F5000000F70803C0D080025AD5F6001CD202131
+:107F60008C8B0000304C001F240600010186180491
+:107F70008F89008C01635025AC8A00008D2500009C
+:107F800050A00001AF84008C8F9800808FBF00103C
+:107F900027BD00182708000103E00008AF88008013
+:107FA00030A500072403000310A3001028A200043A
+:107FB00014400008240700022403000410A3001545
+:107FC0002408000510A8000F8F8500A003E000081A
+:107FD0000000000014A7FFFD0080282114C3FFFB50
+:107FE000240400020A000B9A000000002409000586
+:107FF0000080282110C9FFFB2404000303E00008CF
+:108000000000000014C5FFF1008028210A000B9A2F
+:1080100024040005240A00010080282110CAFFF171
+:108020002404000403E000080000000027BDFFE076
+:10803000AFB00010000581C22603FFD024C5003F69
+:108040002C6223D024C6007FAFB20018AFB1001459
+:10805000AFBF001C309100FF000691C200052982CD
+:1080600002002021104000082403FFFF0E000A5ADE
+:108070000000000002002021022028210E000C48F0
+:1080800002403021000018218FBF001C8FB2001861
+:108090008FB100148FB000100060102103E00008C1
+:1080A00027BD002027BDFFD824A2007FAFB3001C4E
+:1080B000AFB20018000299C2309200FF24A3003F23
+:1080C0000240202102602821AFB10014AFB000109F
+:1080D000AFBF00200E000B7D00038982004080218D
+:1080E000004020210220282114400009000018210E
+:1080F0008FBF00208FB3001C8FB200188FB1001407
+:108100008FB000100060102103E0000827BD002898
+:108110000E000A0B00000000004028210200202170
+:108120001051FFF3001019C00E000A5A00000000A1
+:1081300002002021024028210E000C48026030215C
+:108140008FBF00208FB3001C8FB200188FB10014B6
+:108150008FB00010000018210060102103E000081B
+:1081600027BD00283084FFFF30A5FFFF10800007E7
+:10817000000018213082000110400002000420425B
+:10818000006518211480FFFB0005284003E000086B
+:108190000060102110C00007000000008CA2000049
+:1081A00024C6FFFF24A50004AC82000014C0FFFB1E
+:1081B0002484000403E000080000000010A0000870
+:1081C00024A3FFFFAC8600000000000000000000B8
+:1081D0002402FFFF2463FFFF1462FFFA24840004DB
+:1081E00003E000080000000030A5FFFF8F4201B847
+:1081F0000440FFFE3C07601500A730253C0310003B
+:10820000AF440180AF400184AF46018803E000081D
+:10821000AF4301B88F8500D02C8640000080182124
+:108220008CA700840087102B144000100000000071
+:108230008CA800842D06400050C0000F240340008D
+:108240008CAA0084008A482B512000018CA3008452
+:1082500000035A42000B20803C05080024A558204A
+:108260000085182103E000088C62000014C0FFF4B0
+:10827000000000002403400000035A42000B20804D
+:108280003C05080024A558200085182103E00008BB
+:108290008C6200008F8300D0906600D024C500015E
+:1082A000A06500D08F8500D0906400D090A200D24D
+:1082B0001044001700000000936C00788F8B00BC06
+:1082C000318A00FFA16A000C25490001938700C490
+:1082D000312200FF3048007F1107000B00026827A1
+:1082E000A36200788F4E017805C0FFFE8F9900B021
+:1082F000241800023C0F1000AF590140A35801445C
+:1083000003E00008AF4F01780A000D1831A2008089
+:10831000A0A000D00A000D0E000000008F8700D042
+:1083200027BDFFC8AFBF0030AFB7002CAFB60028E5
+:10833000AFB50024AFB40020AFB3001CAFB200183B
+:10834000AFB10014AFB0001094E300E094E200E29B
+:10835000104300D72405FFFF3C047FFF3497FFFF45
+:108360002415FF800A000DFF3C16000E108A00D174
+:108370008FBF00308F9100B03C1808008F18005C50
+:10838000001230C0001291400311702101D57824F1
+:10839000AF4F002C94EC00E231CD007F01BA5821A0
+:1083A000318A7FFF01764821000A804002091021AE
+:1083B000945300003C0808008D0800580246C02174
+:1083C00032733FFF0013198001032021022428216A
+:1083D00030BF007F03FAC82100B5A024AF54002CA1
+:1083E0000336A0218E8700108E8F0030037858212D
+:1083F000256D008800EF7023240C0002AE8E001063
+:10840000AF8D00ACA16C0088976A003C8E84003070
+:108410008F9100AC0E000CE53150FFFF00024B8045
+:10842000020940253C02420001022025AE2400043E
+:108430008E8300048F8D00AC8E860000240E000811
+:10844000ADA3001CADA60018ADA0000CADA000109F
+:10845000929F000A33F900FFA5B900149685000821
+:108460003C1F000CA5A500169298000A331100FFCE
+:10847000A5B100209690000824180005A5B00022A0
+:10848000ADA00024928F000B2410C00031E700FF44
+:10849000A5A70002A1AE00018E8C00308F8B00AC2E
+:1084A0008F8400B0AD6C00083C0A08008D4A00546F
+:1084B0000144482101354024AF4800283C0208000F
+:1084C0008C4200540044302130C3007F007AC82120
+:1084D000033F282102458821AF9100BCAF8500C031
+:1084E000A23800008F8A00BC2403FFBF2418FFDFDE
+:1084F000954F000201F0382400F37025A54E0002CC
+:10850000914D000231AC003F358B0040A14B000281
+:108510008F8600BC8F8900D0ACC000048D28007C01
+:108520003C098000ACC8000890C4000D3082007F78
+:10853000A0C2000D8F8500BC90BF000D03E3C824CE
+:10854000A0B9000D8F9100BC9233000D02789024E9
+:10855000A232000D8E9000348F8B00BCAD700010E5
+:108560008E87002C8E8F003000EF7023AD6E0014CC
+:10857000916D001831AC007FA16C00188F9F00BC7A
+:108580008E8A00308FE8001801572024010930241A
+:1085900000C41025AFE200189283000AA3E3001C78
+:1085A000969900088F8500BC8F9800D0A4B9001E52
+:1085B0008E9000308E8400300E0002038F05008400
+:1085C0008F8500D0000291400002990090AF00BC5E
+:1085D000025388210040302131E7000210E00003FF
+:1085E00002118021000290800212802190B900BC0B
+:1085F0003327000410E000020006F880021F8021EB
+:108600008E9800308F8B00BC24068000330F00034F
+:10861000000F702331CD0003020D6021AD6C00040A
+:1086200094A400E294AA00E294B000E231497FFFF2
+:108630002522000130537FFF0206182400734025D5
+:10864000A4A800E294A400E23C1408008E94006008
+:1086500030917FFF12340022000000000E000D0553
+:10866000000000008F8700D00000282194F300E074
+:1086700094F000E21213000F8FBF003090E900D099
+:1086800090E800D1313200FF310400FF0244302B6A
+:1086900014C0FF36264A000190EE00D2264B00019E
+:1086A00031CD00FF008D6021158BFF338F9100B01D
+:1086B0008FBF00308FB7002C8FB600288FB50024F5
+:1086C0008FB400208FB3001C8FB200188FB100143C
+:1086D0008FB0001000A0102103E0000827BD003873
+:1086E00094A300E200664024A4A800E290A400E263
+:1086F00090B900E2309100FF0011A1C20014F827E8
+:10870000001F39C03332007F024730250A000DF7C1
+:10871000A0A600E23084FFFF30A5FFFFAF440018A1
+:10872000AF45001C03E000088F42001427BDFFB8CE
+:10873000AFB000208F9000D03084FFFFAFA40010B6
+:10874000AFBF0044AFBE0040AFB7003CAFB600388B
+:10875000AFB50034AFB40030AFB3002CAFB20028D7
+:10876000AFB10024A7A00018920600D1920500D056
+:1087700030C400FF30A300FF0064102B1040012222
+:10878000AFA00014920900D08FB50010312800FF6F
+:108790000088382324F4FFFF0014882B0015982B41
+:1087A00002339024524001268FB40014961E00120A
+:1087B000961F00108FB7001003DFC82300171400A6
+:1087C0000019C400000224030018140302E2B02AB6
+:1087D00052C00001004020210284282B10A000027A
+:1087E000008018210280182100033C0000071C03B0
+:1087F0003064FFFF2C86000914C000020060B8211D
+:10880000241700088E0A0008001769808E09000CE2
+:1088100031ABFFFF3C0C0010016C402527520400D7
+:10882000AF4A0038AF9200B8AF49003CAF480030C3
+:108830000000000000000000000000000000000038
+:108840000000000000000000000000000000000028
+:108850008F4F000031EE002011C0FFFD0017982A55
+:10886000027110240A000E920000B02155E00101AF
+:108870009258000131130080126001CF01202021A5
+:108880009655001232A5FFFF0E000CDAA7B50018AE
+:108890008F9000D00291A02326C800018F9100B8CC
+:1088A0000008B4000016B403262C004002D7782A32
+:1088B0000014882B240B00010180902101F1102469
+:1088C000AF8C00B8AFAB0014104001BC8F8900B072
+:1088D0003C0C08008D8C0054240BFF80921E00D0AD
+:1088E00001895021014B2824921900D0AF4500285E
+:1088F0008E4700103C0808008D0800583C180800FE
+:108900008F18005430E33FFF000321800104302121
+:10891000012658212402FF800162F824920C00D025
+:10892000AF5F002C9248000033D100FF333500FFC9
+:108930000309982100117140001578C0326D007F45
+:1089400001CF382101BA2821318300FF3164007F33
+:108950003C0A000C00AA88210367F0210003314083
+:10896000009A10213108003F3C1F000E00D1C021A9
+:10897000005F982127D900882D150008AF9100C00D
+:10898000AF9900ACAF9800BCAF9300B412A0018ABD
+:1089900000008821240E0001010E4004310D005D0D
+:1089A00011A0FFB2310F00028E4A00283C03008064
+:1089B0003C04FFEFAE6A00008E450024A260000A6E
+:1089C0003488FFFFAE6500049247002C3C1FFF9FD8
+:1089D00037FEFFFFA267000C8E62000C3C180040BF
+:1089E000A267000B0043302500C8C824033E88243A
+:1089F0000238A825AE75000C8E490004AE60001840
+:108A00003C0F00FFAE6900148E4D002C35EEFFFFC9
+:108A10008F8B00B001AE6024AE6C00108E47000852
+:108A2000A660000896450012AE6700208E42000C3A
+:108A300030B03FFF00105180AE6200248E5E001403
+:108A4000014B182130A40001AE7E00288E59001879
+:108A5000000331C200044380AE79002C8E51001C0B
+:108A600000C8F821A67F001CAE71003096580002A5
+:108A70008E550020A678001EAE7500349249003352
+:108A80003130000456000005925000008F8C00D059
+:108A90008D8B007CAE6B0030925000008F8F00BC3D
+:108AA000A1F00000924E003331CD000251A000072A
+:108AB000925E00018F8900BC2418FF809131000074
+:108AC0000311A825A1350000925E00018F9900BC1A
+:108AD0002409FFBF240BFFDFA33E00018F9500BCDC
+:108AE00092B8000D3311007FA2B1000D8F8E00BC33
+:108AF00091D0000D02097824A1CF000D8F8800BC11
+:108B00008E6D0014910A000D2DAC0001000C29405F
+:108B1000014B382400E51825A103000D96420012F0
+:108B20008F8800BC8F8700D0A50200028E4500040C
+:108B300090FF00BC30A400030004302330DE0003AB
+:108B400000BE102133F90002172000022444003433
+:108B50002444003090E200BC00A2302430DF000446
+:108B600017E0000224830004008018218F8F00ACDE
+:108B700024090002AD030004A1E90000924E003F69
+:108B80008F8D00ACA1AE00018F9500AC924C003FE0
+:108B90008E440004A6AC0002976B003C0E000CE56E
+:108BA0003170FFFF00025380020A38253C05420065
+:108BB00000E51825AEA300048F8600AC8E4800386F
+:108BC000ACC800188E440034ACC4001CACC0000C0F
+:108BD000ACC00010A4C00014A4C00016A4C00020A3
+:108BE000A4C00022ACC000248E6400145080000198
+:108BF00024040001ACC400080E000D05241100017E
+:108C00000A000E858F9000D0920F00D2920E00D0F5
+:108C10008FB5001031EB00FF31CD00FF008D6023D8
+:108C2000016C50212554FFFF0014882B0015982B50
+:108C3000023390241640FEDD000000008FB40014C3
+:108C40008FBF00448FBE00403A8200018FB7003CC6
+:108C50008FB600388FB500348FB400308FB3002C3E
+:108C60008FB200288FB100248FB0002003E00008ED
+:108C700027BD004833110020122000EE241500010A
+:108C8000921E00BC241F00010000A82133D900015E
+:108C90001320000DAFBF001C8E4400148E0800840A
+:108CA0000088102B14400002008030218E060084C2
+:108CB0008E03006400C3A82B16A0000200C0202170
+:108CC0008E0400640080A8218E4700148E05006485
+:108CD00000E5302B14C0000200E020218E04006467
+:108CE0000095F02313C000048FAC001C240A00027E
+:108CF000AFAA001C8FAC001C028C582B156000A87A
+:108D0000000018218E4F00388E6D000C3C0E008044
+:108D1000AE6F00008E4A00343C10FF9F01AE582514
+:108D2000AE6A00049246003F360CFFFF016C382407
+:108D30003C0500203C03FFEFA266000B00E5102578
+:108D40003468FFFF8F8700B80048F8243C0400080F
+:108D500003E4C825AE79000C8CF80014AE6000184E
+:108D600002BE7821AE7800148CF10018AE71001CA0
+:108D70008CE90008AE6900248CEE000CAE6F002C6C
+:108D8000AE600028AE6E0020A6600038A660003AF3
+:108D90008CED001401B58023021E902312400011B7
+:108DA000AE72001090EA003D8E6500048E640000F3
+:108DB000000A310000A6C821000010210326402B24
+:108DC0000082F82103E8C021AE790004AE780000EB
+:108DD00090F1003DA271000A8F8900B8953200061B
+:108DE000A67200088F9800AC2419000202A020216E
+:108DF000A31900009769003C8F9200AC0E000CE5AF
+:108E00003131FFFF00027B808F8500B8022F68257B
+:108E10003C0E420001AE8025AE5000048F8400ACB1
+:108E20008CAC0038AC8C00188CAB0034AC8B001CC4
+:108E3000AC80000CAC800010A4800014A48000164C
+:108E4000A4800020A4800022AC80002490A7003FD2
+:108E5000A487000212A001342403000153C00002C1
+:108E600090A2003D90A2003E24480001A08800018D
+:108E70008F9F00ACAFF500088F8300D0240700342B
+:108E8000906600BC30C5000250A0000124070030ED
+:108E90008F9200B88F8A00BC906D00BC924B00008E
+:108EA0002412C00032A50003A14B00008F8600B839
+:108EB0008F8800BC2402000490C4000100451823E0
+:108EC00030790003A10400018F8A00BC8F9F00B895
+:108ED00000F538219558000297E9001200F9382171
+:108EE00003128824312F3FFF022F7025A54E000268
+:108EF0009150000231A80004320C003F358B004035
+:108F0000A14B000212A000028F8500BC00E83821AE
+:108F10008F8E00D0ACA70004240BFFBF8DCD007C4A
+:108F20002EA400012403FFDFACAD000890B0000DBB
+:108F300000044140320C007FA0AC000D8F8600BCC5
+:108F400090CA000D014B1024A0C2000D8F8700BCF9
+:108F500090E5000D00A3F82403E8C825A0F9000D52
+:108F60008F9100B88F8D00BC8E380020ADB80010F6
+:108F70008E290024ADA900148E2F0028ADAF001853
+:108F80008E2E002C0E000D05ADAE001C8FB0001C07
+:108F9000240C0002120C00ED8F9000D08FA3001C57
+:108FA00000608821146000020060A8210000A02158
+:108FB00056A0FE390291A0230014882B8FAE00101A
+:108FC000960700103C0A002001D6F02302C7C021FA
+:108FD00033D2FFFFA6180010AFB20010AF4A003026
+:108FE0000000000096170010961300121277008EF2
+:108FF000001641808E16000C8E0F0008000817C363
+:1090000002C8282100A8582B01E2A82102AB182190
+:10901000AE05000CAE0300088FB300100013B82B90
+:10902000023780241200FF058F9000D00A000E4BFB
+:10903000000000008E480038A6600008240F0003DE
+:10904000AE6800008E4C0034A260000A8F9000B819
+:10905000AE6C00043C050080920B003FA26F000C38
+:109060008E62000C3C11FF9FA26B000B004568252F
+:109070003623FFFF3C04FFEF8F8C00B801A33024A0
+:10908000349FFFFF00DFC824AE79000C8D890014E7
+:10909000959E00128F9800B0AE6900108D8E00145E
+:1090A000AE600018AE600020AE6E0014AE6000240A
+:1090B0008D87001833CE3FFF000E5180AE67002829
+:1090C0008D8800080158902133D00001AE6800302F
+:1090D0008D91000C8F8D00AC001259C200107B8066
+:1090E000016F282124020002A665001CA66000363C
+:1090F000AE71002CA1A200009763003C8F9800ACD9
+:109100003C044200307FFFFF03E43025AF0600043B
+:109110008F9900B824070001240BC0008F3300385A
+:1091200024060034AF1300188F290034AF09001C47
+:10913000AF00000CAF000010A7000014A70000163D
+:10914000A7000020A7000022AF000024A7150002FE
+:10915000A30700018F8A00AC8F9E00B88F8C00BCE3
+:10916000AD55000893C80000A18800008F9200B898
+:109170008F8F00BC92500001A1F000018F8400BCD1
+:1091800094910002022B282400AE1025A482000234
+:10919000908D000231A3003FA08300028F8300D096
+:1091A0008F8400BC907F00BC33F30002526000014A
+:1091B00024060030AC8600048C65007C240DFFBFC3
+:1091C00002A08821AC8500089082000D3043007F0A
+:1091D000A083000D8F8600BC90C4000D008DF82484
+:1091E000A0DF000D8F8E00BC91D9000D3729002023
+:1091F000A1C9000D8F9E00B88F9300BC8FC70020BF
+:10920000AE6700108FD80024AE7800148FCA0028F3
+:10921000AE6A00188FD2002C0E000D05AE72001C35
+:109220000A00104C8F9000D0960200148E040004A7
+:109230003043FFFF000368C0008DF821AF5F003CA2
+:109240008E1900048F46003C032648231920003C59
+:10925000000000008E05000024A200013C0B00105D
+:1092600035750008AF420038AF55003000000000EF
+:1092700000000000000000000000000000000000EE
+:109280000000000000000000000000008F4C000003
+:10929000318F002011E0FFFD000000008F5304001B
+:1092A0003C080020AE1300088F570404AE17000CD2
+:1092B000AF480030000000003C0608008CC60044A7
+:1092C0002416000110D600BB000000009619001201
+:1092D0003C0508008CA5004000B94821A6090012F1
+:1092E000960E001425C70001A60700149618001456
+:1092F0003304FFFF5486FF498FB30010A60000140B
+:109300000E000E2530A5FFFF3C0408008C840024CD
+:10931000961F00120044682303ED3023A6060012B6
+:109320000A0010678FB30010A08300018F8200AC89
+:1093300024040001AC4400080A000FFF8F8300D012
+:109340008E0200000A0010F83C0B00108F9F00C036
+:109350008FB8001C920F00D0920B00D0920D00D05D
+:1093600031F100FF316E00FF000E28C000111140E6
+:109370000045182131A600FF036350210006C940B3
+:10938000033F382125490088AF8900ACAF8700BC76
+:10939000A15800889768003C03C020218F9100AC41
+:1093A0000E000CE53110FFFF00026380020C7825EF
+:1093B0003C0442008F8C00B801E45825AE2B000419
+:1093C0008D9100388F8B00AC00006821000D1100DA
+:1093D000AD7100188D8E00343C087FFF3504FFFF0F
+:1093E000AD6E001C9183003E8D65001C8D790018C8
+:1093F000000331000003870200A6C0210050F825B9
+:109400000306482B033F382100E95021AD78001CAA
+:10941000AD6A0018AD60000CAD600010918F003E89
+:109420002405000503C45024A56F00149591000481
+:1094300003C02021A5710016918E003EA56E00206C
+:10944000958D0004A56D0022AD6000249190003F31
+:10945000A57000029182003D24430001A163000138
+:109460008F8600AC8F9F00BCACDE0008A3E5000037
+:109470008F9000BC8F9900B82405FFBF96070002AB
+:10948000973800120247782433093FFF01E9882505
+:10949000A6110002921200022418FFDF324E003F94
+:1094A00035CD0040A20D00028F8600BC8F8C00D00D
+:1094B0002412FFFFACC000048D8B007C3C0C8000AC
+:1094C000ACCB000890C2000D3043007FA0C3000D5C
+:1094D0008F8700BC90FF000D03E5C824A0F9000DA4
+:1094E0008F9100BC9229000D01387824A22F000D25
+:1094F0008F9000BCAE120010AE150014920E001832
+:109500002415FF8002AE6825A20D00188F8500BCCF
+:109510008F8300B88CAB0018016C1024004A3025F2
+:10952000ACA600189068003EA0A8001C8F9F00B851
+:109530008F8700BC8F9800D097F90004A4F9001E13
+:109540000E0002038F0500848F8600D00002794050
+:109550000002490090D200BC01E988210040282186
+:109560003255000212A0000303D120210002A8807E
+:109570000095202190CC00BC3192000412400003E1
+:1095800033C900030005408000882021241900040D
+:109590008F9E00BC0329382330F800030098502127
+:1095A000AFCA00040E000D05A66500380A0010477A
+:1095B0008F9000D0960A00123C1E08008FDE002417
+:1095C00003CA9021A61200120A0010678FB3001080
+:1095D00027BDFFE03C1808008F180050AFB0001006
+:1095E000AFBF0018AFB10014AF8400B09371007426
+:1095F000030478212410FF8031EE007F3225007FA4
+:1096000001F0582401DA68213C0C000AA38500C44B
+:1096100001AC2821AF4B002494A9001097680006E4
+:1096200090A6006200803821240200300109202326
+:1096300030C300F0AF8500D0106200193090FFFFFA
+:1096400090AE0062240DFFF0240A005001AE6024A9
+:10965000318B00FF116A002F000000001600000788
+:10966000241F0C00AF5F00248FB100148FBF0018BF
+:109670008FB0001003E0000827BD00200E000E2B65
+:1096800002002021241F0C00AF5F00248FB10014C2
+:109690008FBF00188FB0001003E0000827BD002026
+:1096A00094A200E094A400E290BF01130082182667
+:1096B0003079FFFF33E700C014E000092F310001CB
+:1096C00016000038000000005620FFE6241F0C00A2
+:1096D0000E000D27000000000A0011F9241F0C00E5
+:1096E0001620FFDE000000000E000D270000000025
+:1096F0001440FFDC241F0C00160000228F8300D0D2
+:10970000906901133122003FA06201130A0011F990
+:10971000241F0C0094AF00D48F8600D400E02821D1
+:10972000240400050E000C6B31F0FFFF144000050F
+:1097300024030003979100E6000018212625FFFF6F
+:10974000A78500E68F5801B80700FFFE3C1960139B
+:10975000AF400180241F0C00AF50018400793825F0
+:109760003C101000AF4701888FB10014AF5001B812
+:10977000AF5F00248FB000108FBF001803E0000817
+:1097800027BD00200E000E2B020020215040FFB507
+:10979000241F0C008F8300D0906901130A0012224D
+:1097A0003122003F0E000E2B020020211440FFAD9D
+:1097B000241F0C00122000078F8300D09068011333
+:1097C0003106003F34C20040A06201130A0011F9C3
+:1097D000241F0C000E000D27000000005040FFA1C8
+:1097E000241F0C008F8300D0906801133106003FC6
+:1097F0000A00125234C20040AF9B00C803E00008C8
+:10980000AF8000EC3089FFFF000940422D0200418B
+:10981000000929801440000200095040240800403B
+:10982000000879400008C0C001F85821256701A848
+:1098300000EF702125CC007F240DFF80018D1824BE
+:109840000065302100CA282125640088240A008888
+:109850003C010800AC2A004C3C010800AC2400503C
+:10986000AF8500D43C010800AC2900603C01080031
+:10987000AC2800643C010800AC2700543C010800FF
+:10988000AC2300583C010800AC26005C03E0000853
+:1098900000000000308300FF30C6FFFF30E400FF0F
+:1098A0008F4201B80440FFFE00034C00012438251C
+:1098B0003C08600000E820253C031000AF45018013
+:1098C000AF460184AF44018803E00008AF4301B80C
+:1098D0008F86001C3C096012352700108CCB0004D9
+:1098E0003C0C600E35850010316A00062D480001E1
+:1098F000ACE800C48CC40004ACA431808CC2000865
+:1099000094C30002ACA2318403E00008A78300E402
+:109910003C0308008C6300508F8400E88F86001C95
+:109920002402FF800064C0210302C824AF5900282C
+:109930008CCD00043305007F00BA78213C0E000C6A
+:1099400001EE2821ACAD00588CC80008AF8500D0CE
+:109950003C076012ACA8005C8CCC001034E800100E
+:10996000ACAC000C8CCB000CACAB000894AA00147F
+:109970003C0208008C42004425490001A4A90014BF
+:1099800094A400143083FFFF106200178F8400D06E
+:109990003C0A08008D4A0040A4AA00128CCE001890
+:1099A000AC8E00248CCD0014AC8D00208CC7001828
+:1099B000AC87002C8CCC001424060001AC8C002851
+:1099C0008D0B00BC5166001A8D0200B48D0200B8E8
+:1099D000A482003A948F003AA48F003C948800D46B
+:1099E00003E000083102FFFF3C0908008D29002434
+:1099F000A4A000148F8400D0A4A900128CCE00185B
+:109A0000AC8E00248CCD0014AC8D00208CC70018C7
+:109A1000AC87002C8CCC001424060001AC8C0028F0
+:109A20008D0B00BC5566FFEA8D0200B88D0200B4B4
+:109A3000A482003A948F003AA48F003C948800D40A
+:109A400003E000083102FFFF8F86001C3C0C080079
+:109A50008D8C0050240BFF808CCD00083C03000C43
+:109A6000000D51C0018A4021010B4824AF8A00E853
+:109A7000AF49002890C700073105007F00BA1021C8
+:109A80000043282130E400041080002FAF8500D06F
+:109A900090CF000731EE000811C0003C000000002C
+:109AA0008CD9000C8CC400140324C02B1300002696
+:109AB000000000008CC2000CACA200648CCD001829
+:109AC0002402FFF8ACAD00688CCC0010ACAC008078
+:109AD0008CCB000CACAB00848CCA001CACAA007C04
+:109AE00090A900BC01224024A0A800BC90C300079C
+:109AF0003067000810E000048F8500D090AF00BCF4
+:109B000035EE0001A0AE00BC90D90007333800014B
+:109B10001300000F8F8400D024070020908200BC27
+:109B200034490002A08900BC8F8400D09088006274
+:109B3000310300F014670006240A0034AC8A00C028
+:109B40000A001334000000000A00130E8CC2001437
+:109B500090CB00073166000210C000050000000035
+:109B6000908D00BC35AC0004A08C00BC8F8400D06C
+:109B700090980113330F003FA08F01138F8E00D0F8
+:109B800095C500D403E0000830A2FFFFACA000643C
+:109B90000A00130F0000000027BDFFD8AFB000106F
+:109BA0008F90001CAFBF0024AFB40020AFB20018EC
+:109BB000AFB10014AFB3001C9613000E3C07600A4F
+:109BC0003C1460063264FFFF369300100E001261F1
+:109BD00034F404108F8400D43C11600E0E0009AAE6
+:109BE00036310010920E00153C0708008CE700602B
+:109BF0003C12601231CD000FA38D00F08E0E0004D8
+:109C00008E0D000896080012961F00109619001A73
+:109C10009618001E960F001C310CFFFF33EBFFFF60
+:109C2000332AFFFF3309FFFF31E6FFFF3C01080045
+:109C3000AC2B00403C010800AC2C00243C01080087
+:109C4000AC2A0044AE293178AE26317C9202001550
+:109C50009603001636520010304400FF3065FFFFB7
+:109C60003C0608008CC60064AE243188AE4500B4C2
+:109C70009208001496190018241F0001011FC00447
+:109C8000332FFFFF3C0508008CA50058AE5800B8E4
+:109C9000AE4F00BC920C0014AF8E00D8AF8D00DC2C
+:109CA000318B00FFAE4B00C0920A0015AE67004832
+:109CB000AE66004C314900FFAE4900C8AE65007C7D
+:109CC0003C0308008C6300503C0408008C84004C6A
+:109CD0003C0808008D0800543C0208008C42005CDF
+:109CE0008FBF0024AE6300808FB00010AE8300747D
+:109CF0008FB3001CAE22319CAE4200DCAE2731A0F7
+:109D0000AE2631A4AE24318CAE233190AE283194EE
+:109D1000AE253198AE870050AE860054AE850070F7
+:109D20008FB10014AE4700E0AE4600E4AE4400CC74
+:109D3000AE4300D0AE4800D4AE4500D88FB400206A
+:109D40008FB2001803E0000827BD002827BDFFE000
+:109D5000AFB10014AFBF0018241100010E00085469
+:109D6000AFB0001010510005978400E6978300CC37
+:109D70000083102B144000088F8500D424070002B4
+:109D80008FBF00188FB100148FB0001000E01021B9
+:109D900003E0000827BD00200E000C892404000504
+:109DA000AF8200E81040FFF6240700020E000858BA
+:109DB0008F90001C979F00E68F9900E88F8D00C858
+:109DC00027EF0001240E0050AF590020A78F00E6B6
+:109DD000A1AE00003C0C08008D8C00648F8600C88A
+:109DE000240A8000000C5E00ACCB0074A4C0000606
+:109DF00094C9000A241FFF803C0D000C012AC024D6
+:109E0000A4D8000A90C8000A24182000011F1825B1
+:109E1000A0C3000A8F8700C8A0E000788F8500C823
+:109E200000003821A0A000833C0208008C420050B2
+:109E30008F8400E80044782101FFC824AF5900282E
+:109E4000960B000231EE007F01DA6021018D302196
+:109E5000A4CB00D4960A0002AF8600D03C0E0004CA
+:109E600025492401A4C900E68E080004ACC80004FA
+:109E70008E030008ACC30000A4C00010A4C00014EE
+:109E8000A0C000D08F8500D02403FFBFA0A000D1C8
+:109E90003C0408008C8400648F8200D0A04400D26F
+:109EA0008E1F000C8F8A00D0978F00E4AD5F001CDE
+:109EB0008E19001024100030AD590018A540003054
+:109EC000A5510054A5510056A54F0016AD4E00688F
+:109ED000AD580080AD580084914D006231AC000F48
+:109EE000358B0010A14B00628F8600D090C90063B3
+:109EF0003128007FA0C800638F8400D02406FFFFB4
+:109F00009085006300A31024A08200638F9100D08D
+:109F100000E01021923F00BC37F90001A23900BCDB
+:109F20008F8A00D0938F00F0AD580064AD5000C010
+:109F3000914E00D3000F690031CC000F018D5825E0
+:109F4000A14B00D38F8500D08F8900DCACA900E83D
+:109F50008F8800D88FBF00188FB100148FB0001009
+:109F600027BD0020ACA800ECA4A600D6A4A000E069
+:109F7000A4A000E203E000080000000027BDFFE00D
+:109F8000AFB000108F90001CAFB10014AFBF00182D
+:109F90008E1900043C1808008F180050240FFF8011
+:109FA000001989C00238702131CD007F01CF6024B3
+:109FB00001BA50213C0B000CAF4C0028014B402152
+:109FC000950900D4950400D68E0700043131FFFFB7
+:109FD000AF8800D00E000922000721C08E060004C1
+:109FE0008F8300C8000629C0AF4500209064003E62
+:109FF00030820040144000068F8400D0341FFFFFE1
+:10A00000948300D63062FFFF145F0004000000005C
+:10A01000948400D60E0008B73084FFFF8E0500043C
+:10A02000022030218FBF00188FB100148FB00010B4
+:10A030002404002200003821000529C00A001285EE
+:10A0400027BD002027BDFFE0AFB100143091FFFF16
+:10A05000AFB00010AFBF00181220001D000080211B
+:10A060008F86001C8CC500002403000600053F02FB
+:10A070000005140230E4000714830015304500FF8A
+:10A080002CA800061100004D000558803C0C08006B
+:10A09000258C57E8016C50218D49000001200008F3
+:10A0A000000000008F8E00EC240D000111CD00593E
+:10A0B00000000000260B00013170FFFF24CA0020C1
+:10A0C0000211202B014030211480FFE6AF8A001CD2
+:10A0D000020010218FBF00188FB100148FB0001044
+:10A0E00003E0000827BD0020938700CE14E000386D
+:10A0F000240400140E001346000000008F86001C8C
+:10A10000240200010A00148DAF8200EC8F8900EC5C
+:10A11000240800021128003B240400130000282119
+:10A1200000003021240700010E001285000000000D
+:10A130000A00148D8F86001C8F8700EC2405000216
+:10A1400014E5FFF6240400120E0012F200000000D5
+:10A150008F8500E800403021240400120E00128593
+:10A16000000038210A00148D8F86001C8F8300ECBC
+:10A17000241F0003147FFFD0260B00010E0012A441
+:10A18000000000008F8500E800403021240200021A
+:10A190002404001000003821AF8200EC0E0012856C
+:10A1A000000000000A00148D8F86001C8F8F00ECC9
+:10A1B0002406000211E6000B000000002404001039
+:10A1C00000002821000030210A0014AA2407000101
+:10A1D000000028210E001285000030210A00148D95
+:10A1E0008F86001C0E0013B3000000001440001204
+:10A1F0008F99001C8F86001C240200030A00148D16
+:10A20000AF8200EC0E00143F000000000A00148D25
+:10A210008F86001C0E001294000000002402000231
+:10A2200024040014000028210000302100003821FF
+:10A230000A0014C7AF8200EC00403821240400104B
+:10A2400097380002000028210E0012853306FFFF18
+:10A250000A00148D8F86001C8F8400C83C077FFF86
+:10A2600034E6FFFF8C8500742402000100A6182448
+:10A27000AC83007403E00008A082000510A0003643
+:10A280002CA20080274A04003C0B00052409008012
+:10A29000104000072408008030A6000F00C54021B0
+:10A2A0002D0300811460000200A0482124080080D2
+:10A2B000AF4B003000000000000000000000000074
+:10A2C0001100000900003821014030218C8D000070
+:10A2D00024E7000400E8602BACCD000024840004D7
+:10A2E0001580FFFA24C600040000000000000000F2
+:10A2F000000000003C0E0006010E3825AF4700307C
+:10A300000000000000000000000000008F4F00006F
+:10A3100031E800101100FFFD000000008F42003CFA
+:10A320008F43003C0049C8210323C02B13000004C5
+:10A33000000000008F4C003825860001AF46003831
+:10A340008F47003C00A9282300E96821AF4D003C5D
+:10A3500014A0FFCE2CA2008003E000080000000043
+:10A3600027BDFFD03C020002AFB100143C11000C2D
+:10A37000AF450038AFB3001CAF46003C00809821C9
+:10A38000AF42003024050088AF440028035120214B
+:10A39000AFBF0028AFB50024AFB40020AFB20018A3
+:10A3A0000E0014FFAFB000103C1F08008FFF004CE0
+:10A3B0003C1808008F1800642410FF8003F3A821C4
+:10A3C00032B9007F02B078240018A0C0033A70218F
+:10A3D0000018914001D12021AF4F00280E0014FF3A
+:10A3E000025428213C0D08008DAD005024050120A9
+:10A3F00001B35821316C007F01705024019A48212B
+:10A40000013120210E0014FFAF4A00283C0808004B
+:10A410008D0800543C0508008CA500640113382108
+:10A4200030E6007F00F0182400DA2021009120217E
+:10A43000AF4300280E0014FF000529403C0208002D
+:10A440008C4200583C1008008E1000601200001C66
+:10A45000005388212415FF800A0015823C14000C4B
+:10A460003226007F0235182400DA202102402821FC
+:10A47000AF430028009420210E0014FF2610FFC0D7
+:10A480001200000F023288212E05004110A0FFF4B7
+:10A49000241210003226007F00109180023518240B
+:10A4A00000DA202102402821AF4300280094202117
+:10A4B0000E0014FF000080211600FFF302328821F5
+:10A4C0003C0B08008D6B005C240AFF802405000211
+:10A4D00001734021010A4824AF4900283C040800C8
+:10A4E000948400623110007F021A88213C07000C1E
+:10A4F0000E000CB90227982100402821026020217B
+:10A500008FBF00288FB500248FB400208FB3001CAC
+:10A510008FB200188FB100148FB000100A0014FF22
+:10A5200027BD00308F83001C8C62000410400003A4
+:10A530000000000003E00008000000008C64001030
+:0CA540008C6500080A0015388C66000CC1
+:04A54C00000000000B
+:10A550000000001B0000000F0000000A00000008BF
+:10A5600000000006000000050000000500000004D7
+:10A5700000000004000000030000000300000003CE
+:10A5800000000003000000030000000200000002C1
+:10A5900000000002000000020000000200000002B3
+:10A5A00000000002000000020000000200000002A3
+:10A5B0000000000200000002000000020000000293
+:10A5C0000000000200000001000000010000000186
+:10A5D00008000F3008000D8808000FC40800106C38
+:10A5E00008000F5808000F98080011A408000DA4D7
+:10A5F000080011C808000DF4080014980800144061
+:10A6000008000DA408000DA408000DA408001254B1
+:10A610000800125408000DA408000DA4080016E05C
+:10A6200008000DA408000DA408000DA408000DA446
+:10A63000080013D408000DA408000DA408000DA400
+:10A6400008000DA408000DA408000DA408000DA426
+:10A6500008000DA408000DA408000DA408000DA416
+:10A6600008000DA408000DA408000DA408000FB8F0
+:10A6700008000DA408000DA40800169008000DA401
+:10A6800008000DA408000DA408000DA408000DA4E6
+:10A6900008000DA408000DA408000DA408000DA4D6
+:10A6A00008000DA408000DA408000DA408000DA4C6
+:10A6B00008000DA408000DA408000DA408000DA4B6
+:10A6C000080015BC08000DA408000DA408001348DC
+:10A6D000080012B808002E5008002E5808002E203E
+:10A6E00008002E2C08002E3808002E440800532C99
+:10A6F000080052EC080052B80800528C080052685A
+:04A7000008005224D7
+:0CA704000A000C760000000000000000BD
+:10A710000000000D727870342E362E3136000000A5
+:10A72000040610030000000000000001000000000B
+:10A730000000000000000000000000000000000019
+:10A740000000000000000000000000000000000009
+:10A7500000000000000000000000000000000000F9
+:10A7600000000000000000000000000000000000E9
+:10A7700000000000000000000000000000000000D9
+:10A7800000000000000000000000000000000000C9
+:10A7900000000000000000000000000000000000B9
+:10A7A00000000000000000000000000000000000A9
+:10A7B0000000000000000000000000000000000099
+:10A7C0000000000000000000000000000000000089
+:10A7D0000000000000000000000000000000000079
+:10A7E0000000000000000000000000000000000069
+:10A7F0000000000000000000000000000000000059
+:10A800000000000000000000000000000000000048
+:10A810000000000000000000000000000000000038
+:10A820000000000000000000000000000000000028
+:10A830000000000000000000000000000000000018
+:10A840000000000000000000000000000000000008
+:10A8500000000000000000000000000000000000F8
+:10A8600000000000000000000000000000000000E8
+:10A8700000000000000000000000000000000000D8
+:10A8800000000000000000000000000000000000C8
+:10A8900000000000000000000000000000000000B8
+:10A8A00000000000000000000000000000000000A8
+:10A8B0000000000000000000000000000000000098
+:10A8C0000000000000000000000000000000000088
+:10A8D0000000000000000000000000000000000078
+:10A8E0000000000000000000000000000000000068
+:10A8F0000000000000000000000000000000000058
+:10A900000000000000000000000000000000000047
+:10A910000000000000000000000000000000000037
+:10A920000000000000000000000000000000000027
+:10A930000000000000000000000000000000000017
+:10A940000000000000000000000000000000000007
+:10A9500000000000000000000000000000000000F7
+:10A9600000000000000000000000000000000000E7
+:10A9700000000000000000000000000000000000D7
+:10A9800000000000000000000000000000000000C7
+:10A9900000000000000000000000000000000000B7
+:10A9A00000000000000000000000000000000000A7
+:10A9B0000000000000000000000000000000000097
+:10A9C0000000000000000000000000000000000087
+:10A9D0000000000000000000000000000000000077
+:10A9E0000000000000000000000000000000000067
+:10A9F0000000000000000000000000000000000057
+:10AA00000000000000000000000000000000000046
+:10AA10000000000000000000000000000000000036
+:10AA20000000000000000000000000000000000026
+:10AA30000000000000000000000000000000000016
+:10AA40000000000000000000000000000000000006
+:10AA500000000000000000000000000000000000F6
+:10AA600000000000000000000000000000000000E6
+:10AA700000000000000000000000000000000000D6
+:10AA800000000000000000000000000000000000C6
+:10AA900000000000000000000000000000000000B6
+:10AAA00000000000000000000000000000000000A6
+:10AAB0000000000000000000000000000000000096
+:10AAC0000000000000000000000000000000000086
+:10AAD0000000000000000000000000000000000076
+:10AAE0000000000000000000000000000000000066
+:10AAF0000000000000000000000000000000000056
+:10AB00000000000000000000000000000000000045
+:10AB10000000000000000000000000000000000035
+:10AB20000000000000000000000000000000000025
+:10AB30000000000000000000000000000000000015
+:10AB40000000000000000000000000000000000005
+:10AB500000000000000000000000000000000000F5
+:10AB600000000000000000000000000000000000E5
+:10AB700000000000000000000000000000000000D5
+:10AB800000000000000000000000000000000000C5
+:10AB900000000000000000000000000000000000B5
+:10ABA00000000000000000000000000000000000A5
+:10ABB0000000000000000000000000000000000095
+:10ABC0000000000000000000000000000000000085
+:10ABD0000000000000000000000000000000000075
+:10ABE0000000000000000000000000000000000065
+:10ABF0000000000000000000000000000000000055
+:10AC00000000000000000000000000000000000044
+:10AC10000000000000000000000000000000000034
+:10AC20000000000000000000000000000000000024
+:10AC30000000000000000000000000000000000014
+:10AC40000000000000000000000000000000000004
+:10AC500000000000000000000000000000000000F4
+:10AC600000000000000000000000000000000000E4
+:10AC700000000000000000000000000000000000D4
+:10AC800000000000000000000000000000000000C4
+:10AC900000000000000000000000000000000000B4
+:10ACA00000000000000000000000000000000000A4
+:10ACB0000000000000000000000000000000000094
+:10ACC0000000000000000000000000000000000084
+:10ACD0000000000000000000000000000000000074
+:10ACE0000000000000000000000000000000000064
+:10ACF0000000000000000000000000000000000054
+:10AD00000000000000000000000000000000000043
+:10AD10000000000000000000000000000000000033
+:10AD20000000000000000000000000000000000023
+:10AD30000000000000000000000000000000000013
+:10AD40000000000000000000000000000000000003
+:10AD500000000000000000000000000000000000F3
+:10AD600000000000000000000000000000000000E3
+:10AD700000000000000000000000000000000000D3
+:10AD800000000000000000000000000000000000C3
+:10AD900000000000000000000000000000000000B3
+:10ADA00000000000000000000000000000000000A3
+:10ADB0000000000000000000000000000000000093
+:10ADC0000000000000000000000000000000000083
+:10ADD0000000000000000000000000000000000073
+:10ADE0000000000000000000000000000000000063
+:10ADF0000000000000000000000000000000000053
+:10AE00000000000000000000000000000000000042
+:10AE10000000000000000000000000000000000032
+:10AE20000000000000000000000000000000000022
+:10AE30000000000000000000000000000000000012
+:10AE40000000000000000000000000000000000002
+:10AE500000000000000000000000000000000000F2
+:10AE600000000000000000000000000000000000E2
+:10AE700000000000000000000000000000000000D2
+:10AE800000000000000000000000000000000000C2
+:10AE900000000000000000000000000000000000B2
+:10AEA00000000000000000000000000000000000A2
+:10AEB0000000000000000000000000000000000092
+:10AEC0000000000000000000000000000000000082
+:10AED0000000000000000000000000000000000072
+:10AEE0000000000000000000000000000000000062
+:10AEF0000000000000000000000000000000000052
+:10AF00000000000000000000000000000000000041
+:10AF10000000000000000000000000000000000031
+:10AF20000000000000000000000000000000000021
+:10AF30000000000000000000000000000000000011
+:10AF40000000000000000000000000000000000001
+:10AF500000000000000000000000000000000000F1
+:10AF600000000000000000000000000000000000E1
+:10AF700000000000000000000000000000000000D1
+:10AF800000000000000000000000000000000000C1
+:10AF900000000000000000000000000000000000B1
+:10AFA00000000000000000000000000000000000A1
+:10AFB0000000000000000000000000000000000091
+:10AFC0000000000000000000000000000000000081
+:10AFD0000000000000000000000000000000000071
+:10AFE0000000000000000000000000000000000061
+:10AFF0000000000000000000000000000000000051
+:10B000000000000000000000000000000000000040
+:10B010000000000000000000000000000000000030
+:10B020000000000000000000000000000000000020
+:10B030000000000000000000000000000000000010
+:10B040000000000000000000000000000000000000
+:10B0500000000000000000000000000000000000F0
+:10B0600000000000000000000000000000000000E0
+:10B0700000000000000000000000000000000000D0
+:10B0800000000000000000000000000000000000C0
+:10B0900000000000000000000000000000000000B0
+:10B0A00000000000000000000000000000000000A0
+:10B0B0000000000000000000000000000000000090
+:10B0C0000000000000000000000000000000000080
+:10B0D0000000000000000000000000000000000070
+:10B0E0000000000000000000000000000000000060
+:10B0F0000000000000000000000000000000000050
+:10B10000000000000000000000000000000000003F
+:10B11000000000000000000000000000000000002F
+:10B12000000000000000000000000000000000001F
+:10B13000000000000000000000000000000000000F
+:10B1400000000000000000000000000000000000FF
+:10B1500000000000000000000000000000000000EF
+:10B1600000000000000000000000000000000000DF
+:10B1700000000000000000000000000000000000CF
+:10B1800000000000000000000000000000000000BF
+:10B1900000000000000000000000000000000000AF
+:10B1A000000000000000000000000000000000009F
+:10B1B000000000000000000000000000000000008F
+:10B1C000000000000000000000000000000000007F
+:10B1D000000000000000000000000000000000006F
+:10B1E000000000000000000000000000000000005F
+:10B1F000000000000000000000000000000000004F
+:10B20000000000000000000000000000000000003E
+:10B21000000000000000000000000000000000002E
+:10B22000000000000000000000000000000000001E
+:10B23000000000000000000000000000000000000E
+:10B2400000000000000000000000000000000000FE
+:10B2500000000000000000000000000000000000EE
+:10B2600000000000000000000000000000000000DE
+:10B2700000000000000000000000000000000000CE
+:10B2800000000000000000000000000000000000BE
+:10B2900000000000000000000000000000000000AE
+:10B2A000000000000000000000000000000000009E
+:10B2B000000000000000000000000000000000008E
+:10B2C000000000000000000000000000000000007E
+:10B2D000000000000000000000000000000000006E
+:10B2E000000000000000000000000000000000005E
+:10B2F000000000000000000000000000000000004E
+:10B30000000000000000000000000000000000003D
+:10B31000000000000000000000000000000000002D
+:10B32000000000000000000000000000000000001D
+:10B33000000000000000000000000000000000000D
+:10B3400000000000000000000000000000000000FD
+:10B3500000000000000000000000000000000000ED
+:10B3600000000000000000000000000000000000DD
+:10B3700000000000000000000000000000000000CD
+:10B3800000000000000000000000000000000000BD
+:10B3900000000000000000000000000000000000AD
+:10B3A000000000000000000000000000000000009D
+:10B3B000000000000000000000000000000000008D
+:10B3C000000000000000000000000000000000007D
+:10B3D000000000000000000000000000000000006D
+:10B3E000000000000000000000000000000000005D
+:10B3F000000000000000000000000000000000004D
+:10B40000000000000000000000000000000000003C
+:10B41000000000000000000000000000000000002C
+:10B42000000000000000000000000000000000001C
+:10B43000000000000000000000000000000000000C
+:10B4400000000000000000000000000000000000FC
+:10B4500000000000000000000000000000000000EC
+:10B4600000000000000000000000000000000000DC
+:10B4700000000000000000000000000000000000CC
+:10B4800000000000000000000000000000000000BC
+:10B4900000000000000000000000000000000000AC
+:10B4A000000000000000000000000000000000009C
+:10B4B000000000000000000000000000000000008C
+:10B4C000000000000000000000000000000000007C
+:10B4D000000000000000000000000000000000006C
+:10B4E000000000000000000000000000000000005C
+:10B4F000000000000000000000000000000000004C
+:10B50000000000000000000000000000000000003B
+:10B51000000000000000000000000000000000002B
+:10B52000000000000000000000000000000000001B
+:10B53000000000000000000000000000000000000B
+:10B5400000000000000000000000000000000000FB
+:10B5500000000000000000000000000000000000EB
+:10B5600000000000000000000000000000000000DB
+:10B5700000000000000000000000000000000000CB
+:10B5800000000000000000000000000000000000BB
+:10B5900000000000000000000000000000000000AB
+:10B5A000000000000000000000000000000000009B
+:10B5B000000000000000000000000000000000008B
+:10B5C000000000000000000000000000000000007B
+:10B5D000000000000000000000000000000000006B
+:10B5E000000000000000000000000000000000005B
+:10B5F000000000000000000000000000000000004B
+:10B60000000000000000000000000000000000003A
+:10B61000000000000000000000000000000000002A
+:10B62000000000000000000000000000000000001A
+:10B63000000000000000000000000000000000000A
+:10B6400000000000000000000000000000000000FA
+:10B6500000000000000000000000000000000000EA
+:10B6600000000000000000000000000000000000DA
+:10B6700000000000000000000000000000000000CA
+:10B6800000000000000000000000000000000000BA
+:10B6900000000000000000000000000000000000AA
+:10B6A000000000000000000000000000000000009A
+:10B6B000000000000000000000000000000000008A
+:10B6C000000000000000000000000000000000007A
+:10B6D000000000000000000000000000000000006A
+:10B6E000000000000000000000000000000000005A
+:10B6F000000000000000000000000000000000004A
+:10B700000000000000000000000000000000000039
+:10B710000000000000000000000000000000000029
+:10B720000000000000000000000000000000000019
+:10B730000000000000000000000000000000000009
+:10B7400000000000000000000000000000000000F9
+:10B7500000000000000000000000000000000000E9
+:10B7600000000000000000000000000000000000D9
+:10B7700000000000000000000000000000000000C9
+:10B7800000000000000000000000000000000000B9
+:10B7900000000000000000000000000000000000A9
+:10B7A0000000000000000000000000000000000099
+:10B7B0000000000000000000000000000000000089
+:10B7C0000000000000000000000000000000000079
+:10B7D0000000000000000000000000000000000069
+:10B7E0000000000000000000000000000000000059
+:10B7F0000000000000000000000000000000000049
+:10B800000000000000000000000000000000000038
+:10B810000000000000000000000000000000000028
+:10B820000000000000000000000000000000000018
+:10B830000000000000000000000000000000000008
+:10B8400000000000000000000000000000000000F8
+:10B8500000000000000000000000000000000000E8
+:10B8600000000000000000000000000000000000D8
+:10B8700000000000000000000000000000000000C8
+:10B8800000000000000000000000000000000000B8
+:10B8900000000000000000000000000000000000A8
+:10B8A0000000000000000000000000000000000098
+:10B8B0000000000000000000000000000000000088
+:10B8C0000000000000000000000000000000000078
+:10B8D0000000000000000000000000000000000068
+:10B8E0000000000000000000000000000000000058
+:10B8F0000000000000000000000000000000000048
+:10B900000000000000000000000000000000000037
+:10B910000000000000000000000000000000000027
+:10B920000000000000000000000000000000000017
+:10B930000000000000000000000000000000000007
+:10B9400000000000000000000000000000000000F7
+:10B9500000000000000000000000000000000000E7
+:10B9600000000000000000000000000000000000D7
+:10B9700000000000000000000000000000000000C7
+:10B9800000000000000000000000000000000000B7
+:10B9900000000000000000000000000000000000A7
+:10B9A0000000000000000000000000000000000097
+:10B9B0000000000000000000000000000000000087
+:10B9C0000000000000000000000000000000000077
+:10B9D0000000000000000000000000000000000067
+:10B9E0000000000000000000000000000000000057
+:10B9F0000000000000000000000000000000000047
+:10BA00000000000000000000000000000000000036
+:10BA10000000000000000000000000000000000026
+:10BA20000000000000000000000000000000000016
+:10BA30000000000000000000000000000000000006
+:10BA400000000000000000000000000000000000F6
+:10BA500000000000000000000000000000000000E6
+:10BA600000000000000000000000000000000000D6
+:10BA700000000000000000000000000000000000C6
+:10BA800000000000000000000000000000000000B6
+:10BA900000000000000000000000000000000000A6
+:10BAA0000000000000000000000000000000000096
+:10BAB0000000000000000000000000000000000086
+:10BAC0000000000000000000000000000000000076
+:10BAD0000000000000000000000000000000000066
+:10BAE0000000000000000000000000000000000056
+:10BAF0000000000000000000000000000000000046
+:10BB00000000000000000000000000000000000035
+:10BB10000000000000000000000000000000000025
+:10BB20000000000000000000000000000000000015
+:10BB30000000000000000000000000000000000005
+:10BB400000000000000000000000000000000000F5
+:10BB500000000000000000000000000000000000E5
+:10BB600000000000000000000000000000000000D5
+:10BB700000000000000000000000000000000000C5
+:10BB800000000000000000000000000000000000B5
+:10BB900000000000000000000000000000000000A5
+:10BBA0000000000000000000000000000000000095
+:10BBB0000000000000000000000000000000000085
+:10BBC0000000000000000000000000000000000075
+:10BBD0000000000000000000000000000000000065
+:10BBE0000000000000000000000000000000000055
+:10BBF0000000000000000000000000000000000045
+:10BC00000000000000000000000000000000000034
+:10BC10000000000000000000000000000000000024
+:10BC20000000000000000000000000000000000014
+:10BC30000000000000000000000000000000000004
+:10BC400000000000000000000000000000000000F4
+:10BC500000000000000000000000000000000000E4
+:10BC600000000000000000000000000000000000D4
+:10BC700000000000000000000000000000000000C4
+:10BC800000000000000000000000000000000000B4
+:10BC900000000000000000000000000000000000A4
+:10BCA0000000000000000000000000000000000094
+:10BCB0000000000000000000000000000000000084
+:10BCC0000000000000000000000000000000000074
+:10BCD0000000000000000000000000000000000064
+:10BCE0000000000000000000000000000000000054
+:10BCF0000000000000000000000000000000000044
+:10BD00000000000000000000000000000000000033
+:10BD10000000000000000000000000000000000023
+:10BD20000000000000000000000000000000000013
+:10BD30000000000000000000000000000000000003
+:10BD400000000000000000000000000000000000F3
+:10BD500000000000000000000000000000000000E3
+:10BD600000000000000000000000000000000000D3
+:10BD700000000000000000000000000000000000C3
+:10BD800000000000000000000000000000000000B3
+:10BD900000000000000000000000000000000000A3
+:10BDA0000000000000000000000000000000000093
+:10BDB0000000000000000000000000000000000083
+:10BDC0000000000000000000000000000000000073
+:10BDD0000000000000000000000000000000000063
+:10BDE0000000000000000000000000000000000053
+:10BDF0000000000000000000000000000000000043
+:10BE00000000000000000000000000000000000032
+:10BE10000000000000000000000000000000000022
+:10BE20000000000000000000000000000000000012
+:10BE30000000000000000000000000000000000002
+:10BE400000000000000000000000000000000000F2
+:10BE500000000000000000000000000000000000E2
+:10BE600000000000000000000000000000000000D2
+:10BE700000000000000000000000000000000000C2
+:10BE800000000000000000000000000000000000B2
+:10BE900000000000000000000000000000000000A2
+:10BEA0000000000000000000000000000000000092
+:10BEB0000000000000000000000000000000000082
+:10BEC0000000000000000000000000000000000072
+:10BED0000000000000000000000000000000000062
+:10BEE0000000000000000000000000000000000052
+:10BEF0000000000000000000000000000000000042
+:10BF00000000000000000000000000000000000031
+:10BF10000000000000000000000000000000000021
+:10BF20000000000000000000000000000000000011
+:10BF30000000000000000000000000000000000001
+:10BF400000000000000000000000000000000000F1
+:10BF500000000000000000000000000000000000E1
+:10BF600000000000000000000000000000000000D1
+:10BF700000000000000000000000000000000000C1
+:10BF800000000000000000000000000000000000B1
+:10BF900000000000000000000000000000000000A1
+:10BFA0000000000000000000000000000000000091
+:10BFB0000000000000000000000000000000000081
+:10BFC0000000000000000000000000000000000071
+:10BFD0000000000000000000000000000000000061
+:10BFE0000000000000000000000000000000000051
+:10BFF0000000000000000000000000000000000041
+:10C000000000000000000000000000000000000030
+:10C010000000000000000000000000000000000020
+:10C020000000000000000000000000000000000010
+:10C030000000000000000000000000000000000000
+:10C0400000000000000000000000000000000000F0
+:10C0500000000000000000000000000000000000E0
+:10C0600000000000000000000000000000000000D0
+:10C0700000000000000000000000000000000000C0
+:10C0800000000000000000000000000000000000B0
+:10C0900000000000000000000000000000000000A0
+:10C0A0000000000000000000000000000000000090
+:10C0B0000000000000000000000000000000000080
+:10C0C0000000000000000000000000000000000070
+:10C0D0000000000000000000000000000000000060
+:10C0E0000000000000000000000000000000000050
+:10C0F0000000000000000000000000000000000040
+:10C10000000000000000000000000000000000002F
+:10C11000000000000000000000000000000000001F
+:10C12000000000000000000000000000000000000F
+:10C1300000000000000000000000000000000000FF
+:10C1400000000000000000000000000000000000EF
+:10C1500000000000000000000000000000000000DF
+:10C1600000000000000000000000000000000000CF
+:10C1700000000000000000000000000000000000BF
+:10C1800000000000000000000000000000000000AF
+:10C19000000000000000000000000000000000009F
+:10C1A000000000000000000000000000000000008F
+:10C1B000000000000000000000000000000000007F
+:10C1C000000000000000000000000000000000006F
+:10C1D000000000000000000000000000000000005F
+:10C1E000000000000000000000000000000000004F
+:10C1F000000000000000000000000000000000003F
+:10C20000000000000000000000000000000000002E
+:10C21000000000000000000000000000000000001E
+:10C22000000000000000000000000000000000000E
+:10C2300000000000000000000000000000000000FE
+:10C2400000000000000000000000000000000000EE
+:10C2500000000000000000000000000000000000DE
+:10C2600000000000000000000000000000000000CE
+:10C2700000000000000000000000000000000000BE
+:10C2800000000000000000000000000000000000AE
+:10C29000000000000000000000000000000000009E
+:10C2A000000000000000000000000000000000008E
+:10C2B000000000000000000000000000000000007E
+:10C2C000000000000000000000000000000000006E
+:10C2D000000000000000000000000000000000005E
+:10C2E000000000000000000000000000000000004E
+:10C2F000000000000000000000000000000000003E
+:10C30000000000000000000000000000000000002D
+:10C31000000000000000000000000000000000001D
+:10C32000000000000000000000000000000000000D
+:10C3300000000000000000000000000000000000FD
+:10C3400000000000000000000000000000000000ED
+:10C3500000000000000000000000000000000000DD
+:10C3600000000000000000000000000000000000CD
+:10C3700000000000000000000000000000000000BD
+:10C3800000000000000000000000000000000000AD
+:10C39000000000000000000000000000000000009D
+:10C3A000000000000000000000000000000000008D
+:10C3B000000000000000000000000000000000007D
+:10C3C000000000000000000000000000000000006D
+:10C3D000000000000000000000000000000000005D
+:10C3E000000000000000000000000000000000004D
+:10C3F000000000000000000000000000000000003D
+:10C40000000000000000000000000000000000002C
+:10C41000000000000000000000000000000000001C
+:10C42000000000000000000000000000000000000C
+:10C4300000000000000000000000000000000000FC
+:10C4400000000000000000000000000000000000EC
+:10C4500000000000000000000000000000000000DC
+:10C4600000000000000000000000000000000000CC
+:10C4700000000000000000000000000000000000BC
+:10C4800000000000000000000000000000000000AC
+:10C49000000000000000000000000000000000009C
+:10C4A000000000000000000000000000000000008C
+:10C4B000000000000000000000000000000000007C
+:10C4C000000000000000000000000000000000006C
+:10C4D000000000000000000000000000000000005C
+:10C4E000000000000000000000000000000000004C
+:10C4F000000000000000000000000000000000003C
+:10C50000000000000000000000000000000000002B
+:10C51000000000000000000000000000000000001B
+:10C52000000000000000000000000000000000000B
+:10C5300000000000000000000000000000000000FB
+:10C5400000000000000000000000000000000000EB
+:10C5500000000000000000000000000000000000DB
+:10C5600000000000000000000000000000000000CB
+:10C5700000000000000000000000000000000000BB
+:10C5800000000000000000000000000000000000AB
+:10C59000000000000000000000000000000000009B
+:10C5A000000000000000000000000000000000008B
+:10C5B000000000000000000000000000000000007B
+:10C5C000000000000000000000000000000000006B
+:10C5D000000000000000000000000000000000005B
+:10C5E000000000000000000000000000000000004B
+:10C5F000000000000000000000000000000000003B
+:10C60000000000000000000000000000000000002A
+:10C61000000000000000000000000000000000001A
+:10C62000000000000000000000000000000000000A
+:10C6300000000000000000000000000000000000FA
+:10C6400000000000000000000000000000000000EA
+:10C6500000000000000000000000000000000000DA
+:10C6600000000000000000000000000000000000CA
+:10C6700000000000000000000000000000000000BA
+:10C6800000000000000000000000000000000000AA
+:10C69000000000000000000000000000000000009A
+:10C6A000000000000000000000000000000000008A
+:10C6B000000000000000000000000000000000007A
+:10C6C000000000000000000000000000000000006A
+:10C6D000000000000000000000000000000000005A
+:10C6E000000000000000000000000000000000004A
+:10C6F000000000000000000000000000000000003A
+:10C700000000000000000000000000000000000029
+:10C710000000000000000000000000000000000019
+:10C720000000000000000000000000000000000009
+:10C7300000000000000000000000000000000000F9
+:10C7400000000000000000000000000000000000E9
+:10C7500000000000000000000000000000000000D9
+:10C7600000000000000000000000000000000000C9
+:10C7700000000000000000000000000000000000B9
+:10C7800000000000000000000000000000000000A9
+:10C790000000000000000000000000000000000099
+:10C7A0000000000000000000000000000000000089
+:10C7B0000000000000000000000000000000000079
+:10C7C0000000000000000000000000000000000069
+:10C7D0000000000000000000000000000000000059
+:10C7E0000000000000000000000000000000000049
+:10C7F0000000000000000000000000000000000039
+:10C800000000000000000000000000000000000028
+:10C810000000000000000000000000000000000018
+:10C820000000000000000000000000000000000008
+:10C8300000000000000000000000000000000000F8
+:10C8400000000000000000000000000000000000E8
+:10C8500000000000000000000000000000000000D8
+:10C8600000000000000000000000000000000000C8
+:10C8700000000000000000000000000000000000B8
+:10C8800000000000000000000000000000000000A8
+:10C890000000000000000000000000000000000098
+:10C8A0000000000000000000000000000000000088
+:10C8B0000000000000000000000000000000000078
+:10C8C0000000000000000000000000000000000068
+:10C8D0000000000000000000000000000000000058
+:10C8E0000000000000000000000000000000000048
+:10C8F0000000000000000000000000000000000038
+:10C900000000000000000000000000000000000027
+:10C910000000000000000000000000000000000017
+:10C920000000000000000000000000000000000007
+:10C9300000000000000000000000000000000000F7
+:10C9400000000000000000000000000000000000E7
+:10C9500000000000000000000000000000000000D7
+:10C9600000000000000000000000000000000000C7
+:10C9700000000000000000000000000000000000B7
+:10C9800000000000000000000000000000000000A7
+:10C990000000000000000000000000000000000097
+:10C9A0000000000000000000000000000000000087
+:10C9B0000000000000000000000000000000000077
+:10C9C0000000000000000000000000000000000067
+:10C9D0000000000000000000000000000000000057
+:10C9E0000000000000000000000000000000000047
+:10C9F0000000000000000000000000000000000037
+:10CA00000000000000000000000000000000000026
+:10CA10000000000000000000000000000000000016
+:10CA20000000000000000000000000000000000006
+:10CA300000000000000000000000000000000000F6
+:10CA400000000000000000000000000000000000E6
+:10CA500000000000000000000000000000000000D6
+:10CA600000000000000000000000000000000000C6
+:10CA700000000000000000000000000000000000B6
+:10CA800000000000000000000000000000000000A6
+:10CA90000000000000000000000000000000000096
+:10CAA0000000000000000000000000000000000086
+:10CAB0000000000000000000000000000000000076
+:10CAC0000000000000000000000000000000000066
+:10CAD0000000000000000000000000000000000056
+:10CAE0000000000000000000000000000000000046
+:10CAF0000000000000000000000000000000000036
+:10CB00000000000000000000000000000000000025
+:10CB10000000000000000000000000000000000015
+:10CB20000000000000000000000000000000000005
+:10CB300000000000000000000000000000000000F5
+:10CB400000000000000000000000000000000000E5
+:10CB500000000000000000000000000000000000D5
+:10CB600000000000000000000000000000000000C5
+:10CB700000000000000000000000000000000000B5
+:10CB800000000000000000000000000000000000A5
+:10CB90000000000000000000000000000000000095
+:10CBA0000000000000000000000000000000000085
+:10CBB0000000000000000000000000000000000075
+:10CBC0000000000000000000000000000000000065
+:10CBD0000000000000000000000000000000000055
+:10CBE0000000000000000000000000000000000045
+:10CBF0000000000000000000000000000000000035
+:10CC00000000000000000000000000000000000024
+:10CC10000000000000000000000000000000000014
+:10CC20000000000000000000000000000000000004
+:10CC300000000000000000000000000000000000F4
+:10CC400000000000000000000000000000000000E4
+:10CC500000000000000000000000000000000000D4
+:10CC600000000000000000000000000000000000C4
+:10CC700000000000000000000000000000000000B4
+:10CC800000000000000000000000000000000000A4
+:10CC90000000000000000000000000000000000094
+:10CCA0000000000000000000000000000000000084
+:10CCB0000000000000000000000000000000000074
+:10CCC0000000000000000000000000000000000064
+:10CCD0000000000000000000000000000000000054
+:10CCE0000000000000000000000000000000000044
+:10CCF0000000000000000000000000000000000034
+:10CD00000000000000000000000000000000000023
+:10CD10000000000000000000000000000000000013
+:10CD20000000000000000000000000000000000003
+:10CD300000000000000000000000000000000000F3
+:10CD400000000000000000000000000000000000E3
+:10CD500000000000000000000000000000000000D3
+:10CD600000000000000000000000000000000000C3
+:10CD700000000000000000000000000000000000B3
+:10CD800000000000000000000000000000000000A3
+:10CD90000000000000000000000000000000000093
+:10CDA0000000000000000000000000000000000083
+:10CDB0000000000000000000000000000000000073
+:10CDC0000000000000000000000000000000000063
+:10CDD0000000000000000000000000000000000053
+:10CDE0000000000000000000000000000000000043
+:10CDF0000000000000000000000000000000000033
+:10CE00000000000000000000000000000000000022
+:10CE10000000000000000000000000000000000012
+:10CE20000000000000000000000000000000000002
+:10CE300000000000000000000000000000000000F2
+:10CE400000000000000000000000000000000000E2
+:10CE500000000000000000000000000000000000D2
+:10CE600000000000000000000000000000000000C2
+:10CE700000000000000000000000000000000000B2
+:10CE800000000000000000000000000000000000A2
+:10CE90000000000000000000000000000000000092
+:10CEA0000000000000000000000000000000000082
+:10CEB0000000000000000000000000000000000072
+:10CEC0000000000000000000000000000000000062
+:10CED0000000000000000000000000000000000052
+:10CEE0000000000000000000000000000000000042
+:10CEF0000000000000000000000000000000000032
+:10CF00000000000000000000000000000000000021
+:10CF10000000000000000000000000000000000011
+:10CF20000000000000000000000000000000000001
+:10CF300000000000000000000000000000000000F1
+:10CF400000000000000000000000000000000000E1
+:10CF500000000000000000000000000000000000D1
+:10CF600000000000000000000000000000000000C1
+:10CF700000000000000000000000000000000000B1
+:10CF800000000000000000000000000000000000A1
+:10CF90000000000000000000000000000000000091
+:10CFA0000000000000000000000000000000000081
+:10CFB0000000000000000000000000000000000071
+:10CFC0000000000000000000000000000000000061
+:10CFD0000000000000000000000000000000000051
+:10CFE0000000000000000000000000000000000041
+:10CFF0000000000000000000000000000000000031
+:10D000000000000000000000000000000000000020
+:10D010000000000000000000000000000000000010
+:10D020000000000000000000000000000000000000
+:10D0300000000000000000000000000000000000F0
+:10D0400000000000000000000000000000000000E0
+:10D0500000000000000000000000000000000000D0
+:10D0600000000000000000000000000000000000C0
+:10D0700000000000000000000000000000000000B0
+:10D0800000000000000000000000000000000000A0
+:10D090000000000000000000000000000000000090
+:10D0A0000000000000000000000000000000000080
+:10D0B0000000000000000000000000000000000070
+:10D0C0000000000000000000000000000000000060
+:10D0D0000000000000000000000000000000000050
+:10D0E0000000000000000000000000000000000040
+:10D0F0000000000000000000000000000000000030
+:10D10000000000000000000000000000000000001F
+:10D11000000000000000000000000000000000000F
+:10D1200000000000000000000000000000000000FF
+:10D1300000000000000000000000000000000000EF
+:10D1400000000000000000000000000000000000DF
+:10D1500000000000000000000000000000000000CF
+:10D1600000000000000000000000000000000000BF
+:10D1700000000000000000000000000000000000AF
+:10D18000000000000000000000000000000000009F
+:10D19000000000000000000000000000000000008F
+:10D1A000000000000000000000000000000000007F
+:10D1B000000000000000000000000000000000006F
+:10D1C000000000000000000000000000000000005F
+:10D1D000000000000000000000000000000000004F
+:10D1E000000000000000000000000000000000003F
+:10D1F000000000000000000000000000000000002F
+:10D20000000000000000000000000000000000001E
+:10D21000000000000000000000000000000000000E
+:10D2200000000000000000000000000000000000FE
+:10D2300000000000000000000000000000000000EE
+:10D2400000000000000000000000000000000000DE
+:10D2500000000000000000000000000000000000CE
+:10D2600000000000000000000000000000000000BE
+:10D2700000000000000000000000000000000000AE
+:10D28000000000000000000000000000000000009E
+:10D29000000000000000000000000000000000008E
+:10D2A000000000000000000000000000000000007E
+:10D2B000000000000000000000000000000000006E
+:10D2C000000000000000000000000000000000005E
+:10D2D000000000000000000000000000000000004E
+:10D2E000000000000000000000000000000000003E
+:10D2F000000000000000000000000000000000002E
+:10D30000000000000000000000000000000000001D
+:10D31000000000000000000000000000000000000D
+:10D3200000000000000000000000000000000000FD
+:10D3300000000000000000000000000000000000ED
+:10D3400000000000000000000000000000000000DD
+:10D3500000000000000000000000000000000000CD
+:10D3600000000000000000000000000000000000BD
+:10D3700000000000000000000000000000000000AD
+:10D38000000000000000000000000000000000009D
+:10D39000000000000000000000000000000000008D
+:10D3A000000000000000000000000000000000007D
+:10D3B000000000000000000000000000000000006D
+:10D3C000000000000000000000000000000000005D
+:10D3D000000000000000000000000000000000004D
+:10D3E000000000000000000000000000000000003D
+:10D3F000000000000000000000000000000000002D
+:10D40000000000000000000000000000000000001C
+:10D41000000000000000000000000000000000000C
+:10D4200000000000000000000000000000000000FC
+:10D4300000000000000000000000000000000000EC
+:10D4400000000000000000000000000000000000DC
+:10D4500000000000000000000000000000000000CC
+:10D4600000000000000000000000000000000000BC
+:10D4700000000000000000000000000000000000AC
+:10D48000000000000000000000000000000000009C
+:10D49000000000000000000000000000000000008C
+:10D4A000000000000000000000000000000000007C
+:10D4B000000000000000000000000000000000006C
+:10D4C000000000000000000000000000000000005C
+:10D4D000000000000000000000000000000000004C
+:10D4E000000000000000000000000000000000003C
+:10D4F000000000000000000000000000000000002C
+:10D50000000000000000000000000000000000001B
+:10D51000000000000000000000000000000000000B
+:10D5200000000000000000000000000000000000FB
+:10D5300000000000000000000000000000000000EB
+:10D5400000000000000000000000000000000000DB
+:10D5500000000000000000000000000000000000CB
+:10D5600000000000000000000000000000000000BB
+:10D5700000000000000000000000000000000000AB
+:10D58000000000000000000000000000000000009B
+:10D59000000000000000000000000000000000008B
+:10D5A000000000000000000000000000000000007B
+:10D5B000000000000000000000000000000000006B
+:10D5C000000000000000000000000000000000005B
+:10D5D000000000000000000000000000000000004B
+:10D5E000000000000000000000000000000000003B
+:10D5F000000000000000000000000000000000002B
+:10D60000000000000000000000000000000000001A
+:10D61000000000000000000000000000000000000A
+:10D6200000000000000000000000000000000000FA
+:10D6300000000000000000000000000000000000EA
+:10D6400000000000000000000000000000000000DA
+:10D6500000000000000000000000000000000000CA
+:10D6600000000000000000000000000000000000BA
+:10D6700000000000000000000000000000000000AA
+:10D68000000000000000000000000000000000009A
+:10D69000000000000000000000000000000000008A
+:10D6A000000000000000000000000000000000007A
+:10D6B000000000000000000000000000000000006A
+:10D6C000000000000000000000000000000000005A
+:10D6D000000000000000000000000000000000004A
+:10D6E000000000000000000000000000000000003A
+:10D6F000000000000000000000000000000000002A
+:10D700000000000000000000000000000000000019
+:10D710000000000000000000000000000000000009
+:10D7200000000000000000000000000000000000F9
+:10D7300000000000000000000000000000000000E9
+:10D7400000000000000000000000000000000000D9
+:10D7500000000000000000000000000000000000C9
+:10D7600000000000000000000000000000000000B9
+:10D7700000000000000000000000000000000000A9
+:10D780000000000000000000000000000000000099
+:10D790000000000000000000000000000000000089
+:10D7A0000000000000000000000000000000000079
+:10D7B0000000000000000000000000000000000069
+:10D7C0000000000000000000000000000000000059
+:10D7D0000000000000000000000000000000000049
+:10D7E0000000000000000000000000000000000039
+:10D7F0000000000000000000000000000000000029
+:10D800000000000000000000000000000000000018
+:10D810000000000000000000000000000000000008
+:10D8200000000000000000000000000000000000F8
+:10D8300000000000000000000000000000000000E8
+:10D8400000000000000000000000000000000000D8
+:10D8500000000000000000000000000000000000C8
+:10D8600000000000000000000000000000000000B8
+:10D8700000000000000000000000000000000000A8
+:10D880000000000000000000000000000000000098
+:10D890000000000000000000000000000000000088
+:10D8A0000000000000000000000000000000000078
+:10D8B0000000000000000000000000000000000068
+:10D8C0000000000000000000000000000000000058
+:10D8D0000000000000000000000000000000000048
+:10D8E00010000003000000000000000D0000000D0B
+:10D8F0003C020800244271203C030800246375C8E0
+:10D90000AC4000000043202B1480FFFD24420004A3
+:10D910003C1D080037BD7FFC03A0F0213C1008002F
+:10D92000261031D83C1C0800279C71200E00116481
+:10D93000000000000000000D30A5FFFF30C600FF12
+:10D94000274301808F4201B80440FFFE24020002F9
+:10D95000AC640000A4650008A066000AA062000B89
+:10D960003C021000AC67001803E00008AF4201B8A9
+:10D970003C0360008C624FF80440FFFE3C02020052
+:10D98000AC644FC0AC624FC43C02100003E000081E
+:10D99000AC624FF827BDFFE8AFBF0014AFB0001076
+:10D9A0000E0011B300808021936200052403FFFE66
+:10D9B00002002021004310248FBF00148FB00010FC
+:10D9C000A36200050A0011BC27BD001827BDFFE8AF
+:10D9D000AFB00010AFBF00140E000EA40080802175
+:10D9E0009362000024030050304200FF14430004FF
+:10D9F00024020100AF4201800A000CC10200202174
+:10DA0000AF400180020020218FBF00148FB00010B2
+:10DA10000A000F7D27BD001827BDFF98AFBE00602C
+:10DA2000AFB7005CAFB20048AFBF0064AFB60058FC
+:10DA3000AFB50054AFB40050AFB3004CAFB1004429
+:10DA4000AFB000408F5001289363003F9362000500
+:10DA50000000F021307200FF000210273042000168
+:10DA60000000B82114400066AFA0003893420116B0
+:10DA700093430112304200FF306300FF0342202134
+:10DA800003431021244540008F82000010400018FD
+:10DA9000248840008F4201043C030001004310240D
+:10DAA00010400013000000008CA3000C8F620030B7
+:10DAB000146201A2240200018CA300108F62002CCA
+:10DAC0001462019E240200019762003A9483400090
+:10DAD0003042FFFF1462019924020001976200386E
+:10DAE000950300023042FFFF1462019424020001FA
+:10DAF00093620000304300FF240200201062000502
+:10DB00002402005010620006000000000A000D0B05
+:10DB1000000000000000000D0A000D14AFA000304E
+:10DB20003C1E080027DE71880A000D14AFA00030EB
+:10DB30003C0208008C4200DC244200013C01080049
+:10DB4000AC2200DC0E00127D000000000A000E8FE7
+:10DB50008FBF00648F4201043C0300209113000D2D
+:10DB6000004310240002202B00042140AFA4003009
+:10DB70008F4301043C02004000621824146000023C
+:10DB8000348700400080382132620020AFA7003087
+:10DB90001440000234E6008000E0302110C0000B89
+:10DBA000AFA6003093C500088F67004C020020210B
+:10DBB00000052B0034A5008130A5F0810E000C8DEE
+:10DBC00030C600FF0A000E8C000000009362003E89
+:10DBD000304200401040000E24020004564200066D
+:10DBE00024020012020020210E0013DA010030216D
+:10DBF0000A000E8F8FBF006416420005000000006F
+:10DC00000E000CB2000020210A000E8F8FBF0064AE
+:10DC10009742011A9504000E9363003532650004A3
+:10DC20003055FFFF00642004AFA4003C8D110004B8
+:10DC300010A000158D1400089362003E3042004091
+:10DC400010400007000000000E00133B02202021BE
+:10DC50001040000D000000000A000E8C00000000C3
+:10DC60008F620044022210230440013200000000B1
+:10DC70008F620048022210230441012E2404001662
+:10DC80000A000DA28FC200048F62004802221023F6
+:10DC900004400008000000003C0208008C423100F3
+:10DCA000244200013C010800AC2231000A000E8130
+:10DCB000000000008F62004002221023184000097B
+:10DCC0002402000C3C0208008C423100327300FC3C
+:10DCD0000000A821244200013C010800AC223100D0
+:10DCE0002402000CAFA200308F62004000511823C4
+:10DCF0001860000D02A3102A144001030000000068
+:10DD00001475000602A310233A620001304200019C
+:10DD1000144000FD0000000002A31023022388210C
+:10DD20000A000D8A3055FFFF000018213262000200
+:10DD30001040001A326200109362003E30420040F0
+:10DD4000504000118FC200040E0011B302002021C8
+:10DD500024020018A362003F936200052403FFFE23
+:10DD600002002021004310240E0011BCA362000514
+:10DD700024040039000028210E0013242406001872
+:10DD80000A000E8E24020001240400170040F80946
+:10DD9000000000000A000E8E24020001104000E581
+:10DDA000000000008F64004C8F6200540282102338
+:10DDB0001C4000E002841023044200010080A021E6
+:10DDC000AFA30018AFB10010AFB50014934201200B
+:10DDD0008F6600409764003C304200FF03422821D8
+:10DDE0008FA2003C00A328218FA300303084FFFFC6
+:10DDF0000044202B8FC200000064182524A5400099
+:10DE0000AFA50020AFA60028AFA30030AFA6002426
+:10DE1000AFA0002CAFB400340040F80927A40010D4
+:10DE20008FA200303042000254400001327300FEE5
+:10DE30009362003E30420040104000378FA3001430
+:10DE40008F6200541682001A32620001240200140C
+:10DE5000124200102A42001510400006240200164B
+:10DE60002402000C12420007326200010A000DEB8E
+:10DE70000000000012420005326200010A000DEBB2
+:10DE8000000000000A000DE62417000E0A000DE64F
+:10DE9000241700100A000DEA2417001293620023D1
+:10DEA0002403FFBD00431024A3620023326200015B
+:10DEB000104000198FA300142402000C1242000E1F
+:10DEC0002A42000D104000062402000E2402000A1F
+:10DED000124200078FA200240A000E032442000110
+:10DEE000124200088FA200240A000E0324420001FF
+:10DEF0000A000E01241700082402000E16E2000298
+:10DF000024170016241700108FA2002424420001B9
+:10DF1000AFA200248FA300148FA200248F760040AC
+:10DF200000431021AF6200408FA2003C9364003692
+:10DF30008F630040028290213402FFFF00821004B0
+:10DF400000621821AF6300488FA6003030C200087D
+:10DF50001040000E000000008F62005816420004BE
+:10DF600030C600FF9742011A5040000134C600102D
+:10DF700093C500088FA700340200202100052B0064
+:10DF800034A500800E000C8D30A5F0808F6200401B
+:10DF900000561023184000178FA200183C020800FA
+:10DFA0008C423198304200101040000924020001D8
+:10DFB000976200681440000624020001A76200680E
+:10DFC0009742007A2442000A0A000E47A762001214
+:10DFD000A76200120E0011B3020020219362007D9F
+:10DFE0002403000102002021344200010A000E45F2
+:10DFF000AFA300381840000A000000000E0011B363
+:10E00000020020219362007D2403000102002021F0
+:10E01000AFA30038344200040E0011BCA362007D9F
+:10E020009362003E304200401440000C3262000116
+:10E030001040000A000000008F6300408FC20004FF
+:10E0400024040018246300010040F809AF63004075
+:10E050008FA200300A000E8E304200048F620058FA
+:10E0600010520010000000008F62001802221023DE
+:10E070001C400008240200018F62001816220009CB
+:10E08000000000008F62001C028210230440000583
+:10E0900024020001AF720058AFA20038AF7100181F
+:10E0A000AF74001C12E0000B8FA300380E0011B3F8
+:10E0B00002002021A377003F0E0011BC02002021A6
+:10E0C00002E03021240400370E0013240000282130
+:10E0D0008FA3003810600003000000000E000C9BAE
+:10E0E0000200202112A00005000018218FA200309C
+:10E0F0003042000450400011006010212403000150
+:10E100000A000E8E006010210E0011B302002021C3
+:10E110009362007D02002021344200040E0011BCF5
+:10E12000A362007D0E000C9B020020210A000E8ECF
+:10E1300024020001AF400044240200018FBF0064AC
+:10E140008FBE00608FB7005C8FB600588FB500544B
+:10E150008FB400508FB3004C8FB200488FB1004491
+:10E160008FB0004003E0000827BD00688C870004E2
+:10E170008C8600000000102100E5382100E5282BE6
+:10E1800000C2302100C53021AC87000403E0000844
+:10E19000AC8600008F4201B80440FFFE2402080054
+:10E1A000AF4201B803E00008000000003C02000894
+:10E1B0000342282194A200483084FFFF1040001B36
+:10E1C0002484001294A200483042FFFF0044102A29
+:10E1D00010400017240200032402001A9343012078
+:10E1E000A342018B8F820008306300FF3042400061
+:10E1F000104000092463FFFE94A200483042FFFF54
+:10E200000043102B144000058F820014A743019493
+:10E210000A000EC8344200018F8200142403FFFE5E
+:10E220000043102403E00008AF820014240200031E
+:10E2300003E00008A342018B27BDFFE0AFB2001846
+:10E24000AFB10014AFB00010AFBF001C30B1FFFF82
+:10E2500030D0FFFF30F2FFFF8F4201B80440FFFED5
+:10E2600000000000AF440180AF4400200E000EAA61
+:10E27000020020218F8300088F840014A751018C95
+:10E28000A750018EA74301908F8300043082800045
+:10E29000AF4301A8A75201881040000E8F820014DE
+:10E2A00093420116304200FC24420004005A10211F
+:10E2B0008C4240003042FFFF144000068F82001461
+:10E2C0003C02FFFF34427FFF00821024AF82001423
+:10E2D0008F8200142403BFFF00431024A74201A62D
+:10E2E0009743010C8F42010400031C003042FFFFE2
+:10E2F00000621825AF4301AC3C021000AF4201B8E8
+:10E300008FBF001C8FB200188FB100148FB00010A7
+:10E3100003E0000827BD002027BDFFE0AFB20018D2
+:10E3200030D2FFFFAF440180AF44002002402021E3
+:10E33000AFB10014AFB0001030F1FFFFAFBF001C51
+:10E340000E000EAA30B0FFFF8F8300142402BFFF1F
+:10E35000A750018C006218248F820008A752018EFA
+:10E36000A7510188A74301A6A74201903C021000D3
+:10E37000AF4201B88FBF001C8FB200188FB10014DC
+:10E380008FB0001003E0000827BD00202743018064
+:10E390008F4201B80440FFFE24022000A46200085E
+:10E3A00024020002A062000BA46000103C021000D6
+:10E3B000AF4201B803E00008000000008F47007082
+:10E3C000934201128F83000827BDFFF0304200FF07
+:10E3D000000228823062010000003021104000431A
+:10E3E00024A400033062400010400010306220007E
+:10E3F00000041080005A10218C43400024A4000423
+:10E4000000041080AFA30000005A10218C4240008D
+:10E41000AFA2000493420116304200FC005A1021C2
+:10E420008C4240000A000F56AFA200081040002F97
+:10E430000000302100041080005A10218C4340005D
+:10E4400024A4000400041080AFA30000005A10218F
+:10E450008C424000AFA00008AFA200048FA80008C3
+:10E460000000302100002021240A00083C09080097
+:10E470002529010003A41021148A000300042A00A6
+:10E480001100000A000000009042000024840001F6
+:10E490002C83000C00A210210002108000491021E2
+:10E4A0008C4200001460FFF300C230263C040800D8
+:10E4B0008C8431048F4200702C830020106000098E
+:10E4C000004738233C03080024633108000410800F
+:10E4D0000043102124830001AC4700003C010800E8
+:10E4E000AC233104AF8600042406000100C01021D3
+:10E4F00003E0000827BD00103C0208008C420038F1
+:10E5000027BDFFD0AFB50024AFB3001CAFBF0028BC
+:10E51000AFB40020AFB20018AFB10014AFB000101C
+:10E520003C15080026B50038144000022453FFFFB4
+:10E53000000098218F840008308240001040000ABB
+:10E54000308280003C0200200082102450400006EF
+:10E55000308280008F8200142403BFFF00831824C0
+:10E560000A000FA2344210001040000A3C020020B2
+:10E5700000821024104000078F8200143C03FFFF2C
+:10E5800034637FFF0083182434428000AF8200147C
+:10E59000AF8300080E000F2E00000000144000089A
+:10E5A0008F8400089743011E9742011C3063FFFFD0
+:10E5B0000002140000621825AF8300048F84000855
+:10E5C0009742010C30831000106000113046FFFFAD
+:10E5D000308200201440000F241200053C0210007D
+:10E5E000008210241040000B241200013C030E0096
+:10E5F0003C020DFF008318243442FFFF0043102B20
+:10E6000010400004000000000A000FC4241200059E
+:10E61000241200013C0508008CA5003454A0001908
+:10E620008F8400088F82001C544000168F840008DD
+:10E630008F82001430424000544000128F84000842
+:10E640003C021F01008210243C0310001443000D03
+:10E650008F84000830C202001440000B3C0200010D
+:10E660009746010E364700020000202124C6000410
+:10E6700030C6FFFF0E000F05240500020A00108DB2
+:10E680008FBF00283C020001008210241040000CC3
+:10E690008F8300143C0208008C4200D89746010E7C
+:10E6A000240400802442000130C6FFFF240500023C
+:10E6B0003C010800AC2200D80A00108A240700039D
+:10E6C00030624000104000063C0210003C020F0087
+:10E6D0000082102450400001934201163C021000B9
+:10E6E0000082102410400044000000003C0208009A
+:10E6F0008C4200301040000C306240001040000A94
+:10E700003C030F00008318243C0201000043102B3F
+:10E7100014400005000000009746010E3647000235
+:10E720000A0010872404008010A0000D3082010030
+:10E730001040000B3C020F00008210243C0302003A
+:10E74000104300078F82000400531024005510214D
+:10E7500090420004244200040A00103A000221C042
+:10E76000000000008F8600083C0508008CA500D042
+:10E77000000616023050000F38A200012C420001A2
+:10E780002E03000C0043102414400018001021C078
+:10E790002602FFFC2C4200045440001400002021FB
+:10E7A00038A200022C420001004310241040000354
+:10E7B000000612420A00103A000020210010182B17
+:10E7C0000043102450400009001021C09746010E5C
+:10E7D000000020212405000224C6000430C6FFFFEB
+:10E7E0000E000ECD3247FFFB001021C09746010EF0
+:10E7F0000A001087364700028F4240003C11080093
+:10E800008E310024304201001040004032220001CD
+:10E810000220802110A00017325400043082010031
+:10E8200010400015240200013C020F000082102459
+:10E830003C0302001043000F8F8200049746010E34
+:10E840000240382100531024005510219044000448
+:10E8500024C6000430C6FFFF24840004000421C045
+:10E860000E000ECD240500022402FFFE02228024A9
+:10E870003252FFFB2402000116020007320200019F
+:10E880003242000450400001365200029746010E09
+:10E890000A001086024038211040000A32020004AB
+:10E8A0009746010E024038210000202124C60004B2
+:10E8B00030C6FFFF0E000ECD240500023252FFFBD2
+:10E8C000320200041040000B8F8200083042080022
+:10E8D00010400008000000009746010E0240382159
+:10E8E0002404010024C6000430C6FFFF0E000ECD34
+:10E8F00024050002568000108FBF00280E000F2252
+:10E90000000000000A00108D8FBF00281040000A90
+:10E910008FBF00289746010E3647000200002021D5
+:10E9200024C6000430C6FFFF240500020E000ECDF1
+:10E93000000000008FBF00288FB500248FB4002096
+:10E940008FB3001C8FB200188FB100148FB000106D
+:10E950000000102103E0000827BD0030274301809C
+:10E960008F4201B80440FFFE000000008F420148C2
+:10E9700000021402A462000824020002A062000B3C
+:10E980008F420148A46200108F420144AC6200240F
+:10E990003C02100003E00008AF4201B827BDFFE8C9
+:10E9A000AFB000103C04600CAFBF00148C8250006C
+:10E9B0002403FF7F3C1A8000004310243442380CAB
+:10E9C000AC825000240200033C106000AF420008FB
+:10E9D0008E0208083C1B80083C010800AC20002087
+:10E9E0003042FFF0384200102C4200010E001B396B
+:10E9F000AF8200003C04FFFF3C02040034830806A1
+:10EA00003442000CAE021948AE03194C3C056016A6
+:10EA10008E0219808CA30000344202000064182486
+:10EA2000AE0219803C0253531462000334A47C00EC
+:10EA30008CA20004005020218C82007C8C83007802
+:10EA40008FBF00148FB0001027BD0018AF820018D0
+:10EA500003E00008AF83001027BDFFE8AFBF001040
+:10EA60008F4340003402FFFF3C040800248400F080
+:10EA700010620007000000008F4240003C040800C4
+:10EA8000248400E83042010010400009000000002A
+:10EA90009745010E0E000E9A30A5FFFF9745010E17
+:10EAA0003C040800248431C80A0010FC8FBF001009
+:10EAB0008F4340008F8200103C040800248400E053
+:10EAC0001462000A000000008F4340048F82001887
+:10EAD00014620006000000009745010E3C04080087
+:10EAE000248431B80A0010FC8FBF00109745010E36
+:10EAF0008FBF001030A5FFFF0A000E9A27BD001837
+:10EB000027BDFFE8AFBF00108F420128AF420020B1
+:10EB10008F4201048F430100AF8200080E000EA453
+:10EB2000AF8300140E0010D5000000003C02080066
+:10EB30008C4200C0104000088F8400083C0208008E
+:10EB40008C4200C4244200013C010800AC2200C4F5
+:10EB50000A001135000000003C0200100082102461
+:10EB60001440000A8F8300143C0208008C420020ED
+:10EB7000244200013C010800AC2200200E000F7D61
+:10EB8000000020210A001133000000002402BFFF12
+:10EB9000006210241040000800000000240287FFDB
+:10EBA00000621024144000083C020060008210241F
+:10EBB00010400005000000000E000CC50000000021
+:10EBC0000A001133000000000E00119D000000003B
+:10EBD000104000063C0240008F4301243C026020AC
+:10EBE000AC430014000000003C024000AF4201387A
+:10EBF000000000008FBF001003E0000827BD0018D0
+:10EC000027BDFFE8AFBF00108F4201403C04400029
+:10EC1000AF4200208F4301483C027000006218247C
+:10EC2000106400100083102B144000063C026000AA
+:10EC30003C02200010620007000000000A00115F83
+:10EC40003C0240001062000B3C0240000A00115FD1
+:10EC5000000000000E001096000000000A00115F86
+:10EC60003C0240000E0011C1000000000A00115FCC
+:10EC70003C0240000E001B46000000003C02400029
+:10EC8000AF420178000000008FBF001003E00008D1
+:10EC900027BD001827BDFFE8AFBF00140E0010A667
+:10ECA000AFB000103C028000344200708C43000082
+:10ECB00000403821AF830020006030218CE8000044
+:10ECC0003C0508008CA500FC3C0408008C8400F87E
+:10ECD000010630230000102100A6282100A6302BB9
+:10ECE00000822021008620213C010800AC2500FC88
+:10ECF0003C010800AC2400F88F50000032020003F1
+:10ED00001040FFEE010030218CE600003C050800B9
+:10ED10008CA500FC3C0408008C8400F800C830235B
+:10ED200000A628210000102100A6302B00822021FF
+:10ED300000862021320700013C010800AC2500FCC0
+:10ED4000AF8800203C010800AC2400F810E000046B
+:10ED5000320200020E0010FF00000000320200022A
+:10ED60005040FFD13C0280000E00113F0000000027
+:10ED70000A0011693C0280008F4201003042003ECF
+:10ED80001440001124020001AF4000488F420100EE
+:10ED9000304207C01040000500000000AF40004CAA
+:10EDA000AF40005003E0000824020001AF400054CF
+:10EDB000AF4000408F420100304238005440000113
+:10EDC000AF4000442402000103E0000800000000FE
+:10EDD0003C0290003442000100822025AF44002014
+:10EDE0008F4200200440FFFE0000000003E0000806
+:10EDF000000000003C028000344200010082202517
+:10EE000003E00008AF44002027BDFFE0AFB20018C8
+:10EE1000AFBF001CAFB10014AFB000108F50014065
+:10EE20008F5101483C0280000011940202222024EC
+:10EE3000324300FF2402000E1062008A2862000F95
+:10EE40001040001228620037240200061062003BC6
+:10EE50002862000710400007240200091060001A11
+:10EE60002402000110620025000000000A00127652
+:10EE7000000000001062007B2402000B1062005BA7
+:10EE80003222FFFF0A001276000000001040000846
+:10EE90002402003828620035104000802402001F40
+:10EEA0001062007E000000000A00127600000000E0
+:10EEB0001062007A2402008010620042000000000C
+:10EEC0000A001276000000008F4201B80440FFFEE5
+:10EED00024020001AF500180AF400184A752018895
+:10EEE000A342018A24020002A342018BA751019090
+:10EEF0008F4201440A001271AF4201A41080000A3F
+:10EF0000240200023C010800A02271783C010800A4
+:10EF1000AC3071808F4201443C010800AC22717C0E
+:10EF20000A0012788FBF001C8F4201B80440FFFE18
+:10EF3000240200020A00125B000000008F4201B8A8
+:10EF40000440FFFE00000000AF5001803C020800BA
+:10EF50009042717810400003000018213C03080023
+:10EF60008C637180AF430184A75201883C02080082
+:10EF7000904271780000182134420001A342018AB6
+:10EF800024020002A342018BA75101908F42014449
+:10EF9000AF4201A43C020800904271781040000387
+:10EFA0003C0210003C0308008C63717CAF4301A855
+:10EFB000AF4201B83C010800A02071780A00127825
+:10EFC0008FBF001C8F4201B80440FFFE24020002E4
+:10EFD000A342018BA7520188A75101908F4201449F
+:10EFE000A74201920A0012733C0210001440001D57
+:10EFF0000000000093620005304200041440003716
+:10F00000000000000E0011B30200202193620005F1
+:10F0100002002021344200040E0011BCA36200054E
+:10F02000936200053042000414400002000000001A
+:10F030000000000D9362000024030020304200FF16
+:10F0400014430008000000008F4201B80440FFFE96
+:10F0500024020005AF500180A342018B3C02100046
+:10F06000AF4201B88F4201B80440FFFE2402000203
+:10F07000AF400180AF500184A7520188A342018AAA
+:10F08000A342018BA7510190AF4001A48F420144DC
+:10F09000AF4201A80A0012733C0210008F4201B86F
+:10F0A0000440FFFE24020001AF500180AF40018404
+:10F0B000A7520188A342018A24020002A342018BC5
+:10F0C000A7510190AF4001A4AF4001A83C0210003D
+:10F0D000AF4201B80A0012788FBF001C0000000D7B
+:10F0E0008FBF001C8FB200188FB100148FB00010BA
+:10F0F00003E0000827BD002027BDFFE8AFBF0010D8
+:10F100000E000EA400000000AF4001808FBF001071
+:10F11000000020210A000F7D27BD00183084FFFF6A
+:10F1200030A5FFFF0000182110800007000000003C
+:10F1300030820001104000020004204200651821C6
+:10F140000A0012890005284003E000080060102131
+:10F1500010C0000624C6FFFF8CA2000024A50004F6
+:10F16000AC8200000A0012932484000403E000082B
+:10F170000000000010A0000824A3FFFFAC860000E0
+:10F1800000000000000000002402FFFF2463FFFFD6
+:10F190001462FFFA2484000403E000080000000069
+:10F1A00027BDFFE0AFB20018AFB10014AFB0001040
+:10F1B000AFBF001C9482000C00A088212490001492
+:10F1C0000002130200021080008290210000302112
+:10F1D00000A020210E00129C240500050212102B15
+:10F1E0001040005700001021920300002C6200091B
+:10F1F0005040005192020001000310803C030800BF
+:10F20000246370DC004310218C42000000400008A1
+:10F2100000000000920300012402000C1462004868
+:10F2200024020001025010232C42000A1440003630
+:10F23000261000028E22000034420100AE2200009F
+:10F240009202000092030001920400029205000362
+:10F2500000031C00000216000043102500042200D9
+:10F26000004410250045102526100004AE2200049D
+:10F270009202000092030001920400029205000332
+:10F280000002160000031C000043102500042200A9
+:10F290000044102500451025261000040A0012B66F
+:10F2A000AE2200089203000124020004146200163A
+:10F2B0002610000292020000920400018E2300003A
+:10F2C00000021200004410253463000426100002DE
+:10F2D000AE22000C0A0012B6AE2300009203000119
+:10F2E0002402000314620008261000028E2200008F
+:10F2F000920300002610000134420008A2230010EF
+:10F300000A0012B6AE2200000A00130F2402000108
+:10F31000920300012402000210620002260400028F
+:10F32000024020210A0012B6008080210A0012B695
+:10F3300026100001920200010A0012B6020280218A
+:10F340008FBF001C8FB200188FB100148FB0001057
+:10F3500003E0000827BD002027BDFFE8AFBF001471
+:10F36000AFB000100E0011B3008080219362007DC9
+:10F3700002002021344200200E0011BCA362007D57
+:10F38000020020218FBF00148FB000100A000C9BD8
+:10F3900027BD0018308300FF30A500FF30C600FFF6
+:10F3A000274701808F4201B80440FFFE00000000A3
+:10F3B0008F42012834634000ACE2000024020001C7
+:10F3C000ACE00004A4E30008A0E2000A240200026A
+:10F3D000A0E2000B3C021000A4E50010ACE0002409
+:10F3E000ACE00028A4E6001203E00008AF4201B838
+:10F3F00027BDFFE8AFBF00109362003F2403001257
+:10F40000304200FF1043000D008030218F62004425
+:10F41000008210230440000A8FBF00108F62004852
+:10F42000240400390000282100C2102304410004F4
+:10F43000240600120E001324000000008FBF0010ED
+:10F440002402000103E0000827BD001827BDFFC803
+:10F45000AFB1002C00A08821AFB2003027A500106A
+:10F460000080902102202021AFBF00340E0012A79F
+:10F47000AFB0002810400009024020218E22000871
+:10F48000AF6200840E001315AF6000402404003802
+:10F490002405008D0A0013D1240600129362003463
+:10F4A000936300378F640084304200FF306300FFB5
+:10F4B0000043282100A4202B1080000B0000000036
+:10F4C0009763003C8F6200843063FFFF0045102388
+:10F4D0000062182B14600004000000008F6200849A
+:10F4E0000A00137B004580239762003C3050FFFFE9
+:10F4F0008FA3001030620004504000032E02021857
+:10F500008FA2001C0202102B1440000502002021D3
+:10F510003062000410400002240402188FA4001C72
+:10F520002C82008010400002008080212410008086
+:10F530000E0011B30240202124020001AF62000C32
+:10F540009362003E001020403042007FA362003EE4
+:10F550008E22000424420001AF620040A770003CEC
+:10F560008F6200509623000E00431021AF620058B6
+:10F570008F62005000441021AF62005C8E220004B4
+:10F58000AF6200188E220008AF62001C8FA200102C
+:10F59000304200085440000A93A20020A3600036C5
+:10F5A000936200362403FFDFA36200359362003EBE
+:10F5B00000431024A362003E0A0013B18E2200080B
+:10F5C000A36200358E220008AF62004C8F620024D7
+:10F5D0008F63004000431021AF6200489362000037
+:10F5E00024030050304200FF144300122403FF8024
+:10F5F0003C0208008C4231A002421021004310243A
+:10F60000AF4200283C0208008C4231A08E24000842
+:10F610003C03000C024210213042007F03421021C3
+:10F6200000431021AC4400D88E230008AF8200288C
+:10F63000AC4300DC0E0011BC024020212404003841
+:10F64000000028212406000A0E00132400000000F8
+:10F650008FBF00348FB200308FB1002C8FB00028E4
+:10F660002402000103E0000827BD003827BDFFE8A1
+:10F67000AFBF001090C7000D00C0282130E6001079
+:10F6800010C0000A30E200048CA300088F6200540E
+:10F690001062000630E20004144000178FBF001013
+:10F6A000000020210A000CB227BD00181040000DF8
+:10F6B00030E3001210C000108FBF00108CA30008B0
+:10F6C0008F6200541462000D2402000124040038EB
+:10F6D0002405008D0E001324240600120A0013FDD9
+:10F6E0008FBF001024020012146200038FBF0010AD
+:10F6F0000A00135227BD00182402000103E000088D
+:10F7000027BD001827BDFFF827420180AFA20000E7
+:10F71000308A00FF8F4201B80440FFFE0000000065
+:10F720008F4601283C0208008C4231A02403FF8050
+:10F73000AF86005000C2102100431024AF420024C5
+:10F740003C0208008C4231A08FA900008FA8000065
+:10F7500000C210213042007F034218213C02000AFF
+:10F7600000621821946400D48FA700008FA50000C8
+:10F7700024020002AF830028A0A2000B8FA3000088
+:10F78000354260003084FFFFA4E200083C02100014
+:10F79000AD260000AD040004AC60002427BD0008C5
+:10F7A000AF4201B803E00008240200018C8200048B
+:10F7B0008F83002800451023AC8200049062006310
+:10F7C0003042007FA06200638C820020938300306F
+:10F7D0008F85002834420002AF830044A780004296
+:10F7E000AC820020A4A000E490A200632403FFBF29
+:10F7F0000043102403E00008A0A200632743018017
+:10F800008F4201B80440FFFE8F820050AC620000BE
+:10F810008F420124AC62000424026083A4620008C9
+:10F8200024020002A062000B3C02100003E000086A
+:10F83000AF4201B88F880044938200308F83002844
+:10F840003C07080024E7759400481023304200FF6D
+:10F85000304900FC246500888F860048304A000348
+:10F860001120000900002021248200048CA3000044
+:10F87000304400FF0089102AACE3000024A50004F6
+:10F880001440FFF924E70004114000090000202182
+:10F890002482000190A30000304400FF008A102B56
+:10F8A000A0E3000024A500011440FFF924E70001B3
+:10F8B00030C20003144000048F850044310200036D
+:10F8C0001040000D0000000010A0000900002021E1
+:10F8D0002482000190C30000304400FF0085102BFB
+:10F8E000A0E3000024C600011440FFF924E7000152
+:10F8F00003E00008000000001100FFFD00002021CF
+:10F90000248200048CC30000304400FF0088102BC8
+:10F91000ACE3000024C600041440FFF924E700040F
+:10F9200003E00008000000008F8300449382003051
+:10F9300030C600FF30A500FF00431023304300FF16
+:10F940008F820028008038210043102114C000025B
+:10F95000244800880083382130E200031440000569
+:10F9600030A2000314400003306200031040000D79
+:10F970000000000010A000090000202124820001E6
+:10F9800090E30000304400FF0085102BA10300002D
+:10F9900024E700011440FFF92508000103E00008F6
+:10F9A0000000000010A0FFFD0000202124820004C0
+:10F9B0008CE30000304400FF0085102BAD030000F5
+:10F9C00024E700041440FFF92508000403E00008C0
+:10F9D0000000000027BDFFF82402FFFFAFA20000D7
+:10F9E000008038212405002F3C0908002529719446
+:10F9F000240800FF2406FFFF90E2000024A3FFFF7D
+:10FA00000006220200C21026304200FF00021080D1
+:10FA1000004910218C420000306500FF24E70001FE
+:10FA200014A8FFF50082302600061027AFA20004BC
+:10FA3000AFA200000000282127A6000400C5102363
+:10FA40009044000324A2000100BD1821304500FFAE
+:10FA50002CA200041440FFF9A06400008FA2000053
+:10FA600003E0000827BD00080080482130AAFFFFFE
+:10FA700030C600FF30E7FFFF274801808F4201B802
+:10FA80000440FFFE8F820050AD0200008F4201242F
+:10FA9000AD0200048D220020A5070008A102000A83
+:10FAA00024020016A102000B934301208D220008BE
+:10FAB0008D240004306300FF00431021978300422F
+:10FAC000004410218D250024004310233C0308002E
+:10FAD0008C6331A08F840028A502000C246300E809
+:10FAE0002402FFFFA50A000EA5030010A5060012C0
+:10FAF000AD050018AD020024948201142403FFF721
+:10FB00003042FFFFAD0200288C820118AD02002CAC
+:10FB10003C021000AD000030AF4201B88D22002041
+:10FB20000043102403E00008AD2200208F8200284B
+:10FB300030E7FFFF00804821904200D330A5FFFF4F
+:10FB400030C600FF0002110030420F0000E23825ED
+:10FB5000274801808F4201B80440FFFE8F82005089
+:10FB6000AD0200008F420124AD0200048D2200206E
+:10FB7000A5070008A102000A24020017A102000B39
+:10FB8000934301208D2200088D240004306300FF80
+:10FB90000043102197830042004410218F840028E5
+:10FBA000004310233C0308008C6331A0A502000C25
+:10FBB000A505000E246300E8A5030010A5060012A9
+:10FBC000AD0000148D220024AD0200188C82005C70
+:10FBD000AD02001C8C820058AD0200202402FFFF01
+:10FBE000AD020024948200E63042FFFFAD020028FF
+:10FBF00094820060948300BE30427FFF3063FFFF39
+:10FC00000002120000431021AD02002C3C02100043
+:10FC1000AD000030AF4201B8948200BE2403FFF76C
+:10FC200000A21021A48200BE8D22002000431024D7
+:10FC300003E00008AD220020274301808F4201B875
+:10FC40000440FFFE24020018AC640000A062000B18
+:10FC50008F820028944200E6A46200103C0210004B
+:10FC6000AC60003003E00008AF4201B827430180D8
+:10FC70008F4201B80440FFFE8F82002C9442001C8A
+:10FC80003042FFFF000211C0AC62000024020019E4
+:10FC9000A062000B3C021000AC60003003E00008E2
+:10FCA000AF4201B88F87003430C300FF8F4201B8E4
+:10FCB0000440FFFE8F82005034636000ACA200005D
+:10FCC0009382004CA0A200058CE20010A4A20006C2
+:10FCD000A4A300088C8200202403FFF7A0A2000A3E
+:10FCE00024020002A0A2000B8CE20000ACA20010D3
+:10FCF0008CE20004ACA200148CE2001CACA2002434
+:10FD00008CE20020ACA200288CE2002CACA2002CDB
+:10FD10008C820024ACA200183C021000AF4201B853
+:10FD20008C8200200043102403E00008AC820020F5
+:10FD30009382004C2403000127BDFFE800433004F8
+:10FD40002C420020AFB00010AFBF00142410FFFE03
+:10FD500010400005274501803C0208008C4231908C
+:10FD60000A00159C004610243C0208008C42319485
+:10FD70000046102414400007240600848F830028C6
+:10FD80002410FFFF906200623042000F34420040B6
+:10FD9000A06200620E001568000000000200102141
+:10FDA0008FBF00148FB0001003E0000827BD0018BB
+:10FDB0008F83002C27BDFFE0AFB20018AFB1001455
+:10FDC000AFB00010AFBF001C9062000D00A09021EA
+:10FDD00030D100FF3042007FA062000D8F850028E7
+:10FDE0008E430018008080218CA2007C14620005E4
+:10FDF0002402000E90A20063344200200A0015C5C0
+:10FE0000A0A200630E00158BA382004C2403FFFF09
+:10FE1000104300472404FFFF52200045000020212A
+:10FE20008E4300003C020010006210245040000489
+:10FE30003C020008020020210A0015D4240200150B
+:10FE400000621024504000098E450000020020216D
+:10FE5000240200140E00158BA382004C2403FFFF24
+:10FE6000104300332404FFFF8E4500003C020002D3
+:10FE700000A21024104000163C0200048F86002CC3
+:10FE80008CC200148CC300108CC4001400431023D7
+:10FE90000044102B50400005020020218E43002C0E
+:10FEA0008CC2001010620003020020210A00160517
+:10FEB000240200123C02000400A210245040001C46
+:10FEC00000002021020020210A0016052402001350
+:10FED00000A21024104000068F83002C8C620010BA
+:10FEE00050400013000020210A0015FF02002021CD
+:10FEF0008C620010504000048E42002C0200202131
+:10FF00000A001605240200115040000900002021BB
+:10FF100002002021240200170E00158BA382004C42
+:10FF20002403FFFF104300022404FFFF00002021F0
+:10FF30008FBF001C8FB200188FB100148FB000105B
+:10FF40000080102103E0000827BD002093830030CB
+:10FF500027BDFFE024020034AFB20018AFB1001497
+:10FF6000AFBF001CAFB00010008088211462000CED
+:10FF700000A090218F8400340E0014B48C900030C7
+:10FF80001202000724020005022020210E00158B1A
+:10FF9000A382004C2403FFFF1043005F2404FFFFF3
+:10FFA00092420004104000098F8200280220202184
+:10FFB0002402000C0E00158BA382004C2403FFFFCB
+:10FFC000104300552404FFFF8F820028A3800024E3
+:10FFD0008E4300048C4400803C0200FF3442FFFF4B
+:10FFE000006218240083202B10800008AF83003C9F
+:10FFF00002202021240200190E00158BA382004C40
+:020000040001F9
+:100000002403FFFF104300442404FFFF97820042B3
+:100010008F8700448F88003C00471023110000396F
+:10002000A78200428F8600283045FFFF8F84005052
+:1000300090C300BC3C0208008C4231A0000318822F
+:100040003070000100822021001010800102102178
+:1000500000A2282B10A00010248200888F84003476
+:100060001082000D3C033F018E420000004310242B
+:100070003C0325001443000630E500FF8C8200009D
+:10008000ACC200888C8200100A001665ACC20098D1
+:100090000E001489000030218F85003C93830024DA
+:1000A0008F86002830A20003000210233042000394
+:1000B00000433821A387002494C400E400A228212F
+:1000C0008F8300448F82004834841000A4C400E46D
+:1000D00000431021AF8200481200000EAF8500449B
+:1000E00024E20004A382002494C200E424A30004B8
+:1000F000AF83004434422000A4C200E40A00168505
+:10010000000020218F820048AF800044004710216A
+:10011000AF820048000020218FBF001C8FB2001862
+:100120008FB100148FB000100080102103E0000890
+:1001300027BD00208F86002827BDFFE8AFBF001431
+:10014000AFB0001090C200633042002010400008A1
+:1001500030A500FF8CC2007C2403FFDF2442000195
+:10016000ACC2007C90C2006300431024A0C20063B4
+:1001700010A000238F83002827500180020028212F
+:100180000E001568240600828F82002890420063CA
+:100190003042004050400019A380004C8F8300344F
+:1001A0008F4201B80440FFFE8F820050AE02000073
+:1001B00024026082A602000824020002A202000BB0
+:1001C0008C620008AE0200108C62000CAE020014BB
+:1001D0008C620014AE0200188C620018AE0200247B
+:1001E0008C620024AE0200288C620028AE02002C33
+:1001F0003C021000AF4201B8A380004C8F8300285E
+:100200008FBF00148FB000109062006327BD0018EC
+:100210003042007FA0620063978200428F860044D4
+:100220008F8500289383003000461023A782004268
+:10023000A4A000E490A400638F820048AF83004430
+:100240002403FFBF0046102100832024AF82004812
+:10025000A0A400638F820028A04000BD8F820028E8
+:1002600003E00008A44000BE8F8A002827BDFFE0FD
+:10027000AFB10014AFB000108F880044AFBF0018BA
+:1002800093890024954200E430D100FF0109182B26
+:100290000080802130AC00FF3047FFFF0000582174
+:1002A00014600003310600FF0120302101095823AA
+:1002B000978300420068102B1440003200000000B9
+:1002C00014680007240200018E0200202403FFFBB3
+:1002D00034E7800000431024AE0200202402000115
+:1002E00034E70880158200053165FFFF0E0014D940
+:1002F000020020210A00171A020020210E00150A10
+:10030000020020210E00154D8F8400508F8400289C
+:100310009482006024420001A48200609482006004
+:100320003C0308008C63318830427FFF5443000F48
+:1003300002002021948200602403800000431024E6
+:10034000A48200609082006090830060304200FFD1
+:10035000000211C200021027000211C03063007FAA
+:1003600000621825A08300600200202102202821BD
+:100370008FBF00188FB100148FB000100A00168CC8
+:1003800027BD0020914200632403FF800043102515
+:10039000A1420063978200423048FFFF1100002015
+:1003A000938300248F840028004B1023304600FFE5
+:1003B000948300E42402EFFF0168282B00621824D4
+:1003C000A48300E414A000038E0200200100582141
+:1003D000000030212403FFFB34E780000043102499
+:1003E000AE02002024020001158200053165FFFFE6
+:1003F0000E0014D9020020210A0017429783004200
+:100400000E00150A02002021978300428F820044CB
+:10041000A780004200431023AF820044938300244E
+:100420008F8200288FBF00188FB100148FB000108A
+:1004300027BD002003E00008A04300BD8F820028F4
+:1004400090430088904500BD244900883063003FF8
+:100450002463FFE024020001006238042C630020C2
+:1004600030E80019A385002410600010AF89003423
+:100470003C028000344200022405000124060001F1
+:100480001500000800E2182400002821146000056F
+:1004900030E20020104000052405000191260001F3
+:1004A00030C600010A0016D90000000003E0000871
+:1004B0000000000027BDFFD8AFB000108F900034BF
+:1004C000AFB40020AFB10014AFBF0024AFB3001C25
+:1004D000AFB200188E0500103C0208008C4231B00B
+:1004E0008F86003830A33FFF0062182B8CD3001496
+:1004F000008088218CD20020106000780000A021AC
+:1005000090C3000D2402FF8000431024304200FFFE
+:100510005040007302202021000513823042000366
+:100520005440006F0220202194C3001C8F820028B9
+:100530008E050028A44301148CC200100262182307
+:10054000146500072402001F8F82003C0062102106
+:100550000262102B104000088F83002C2402001828
+:100560000E00158BA382004C2403FFFF1043006F85
+:100570002404FFFF8F83002C8F84003C8C620010CA
+:100580000244902100441023AC6200108F820028A6
+:10059000AC7200208C4200680052102B1040000901
+:1005A0008F830038022020212402001D0E00158BAD
+:1005B000A382004C2403FFFF1043005C2404FFFFD0
+:1005C0008F8300388E0200248C63002410430007C0
+:1005D000022020212402001C0E00158BA382004C57
+:1005E0002403FFFF104300512404FFFF8F84002CDD
+:1005F0008C82002424420001AC82002412530004A7
+:100600008F8200288C4200685642000E8E02000045
+:100610008E0200003C030080004310241440000DB3
+:100620002402001A022020210E00158BA382004C08
+:100630002403FFFF1043003D2404FFFF0A0017D6E8
+:100640008E0200143C03008000431024504000033D
+:100650008E020014AC8000208E0200142412FFFFD2
+:10066000105200062402001B022020210E00158BD0
+:10067000A382004C1052002D2404FFFF8E030000C3
+:100680003C020001006210241040001F3C02008068
+:100690000062102414400008022020212402001AC5
+:1006A0000E00158BA382004C2403FFFF1043001F94
+:1006B0002404FFFF02202021020028210E0015AB98
+:1006C000240600012403FFFF2404FFFF1443000E4F
+:1006D000241400010A00180B8FBF002402202021DF
+:1006E0002402000D8FBF00248FB400208FB3001CA4
+:1006F0008FB200188FB100148FB0001027BD0028F2
+:100700000A00158BA382004C8F83002C022020212D
+:100710000280302194620036240500012442000149
+:100720000E0016D9A4620036000020218FBF0024DD
+:100730008FB400208FB3001C8FB200188FB100144B
+:100740008FB000100080102103E0000827BD0028B2
+:100750008F83002827BDFFD8AFB40020AFB3001CA3
+:10076000AFB20018AFB10014AFB00010AFBF00249B
+:10077000906200638F9100342412FFFF34420040E6
+:1007800092250000A06200638E2200100080982154
+:1007900030B0003F105200060360A0212402000D7B
+:1007A0000E00158BA382004C105200522404FFFF50
+:1007B0008F8300288E2200188C63007C1043000772
+:1007C000026020212402000E0E00158BA382004C33
+:1007D0002403FFFF104300472404FFFF24040020EC
+:1007E000120400048F8300289062006334420020CA
+:1007F000A06200638F85003C10A0001E0000000076
+:10080000560400048F820028026020210A00185537
+:100810002402000A9683000A2404FFFD944200602B
+:100820003042FFFF104300348FBF00243C02080019
+:100830008C42318C0045102B1440000602602021B0
+:10084000000028210E0016D9240600010A00187C99
+:10085000000020212402002D0E00158BA382004CE5
+:100860002403FFFF104300232404FFFF0A00187C29
+:1008700000002021160400058F8400288E23001418
+:100880002402FFFF50620018026020219482006061
+:1008900024420001A4820060948200603C030800AE
+:1008A0008C63318830427FFF5443000F0260202167
+:1008B000948200602403800000431024A48200601E
+:1008C0009082006090830060304200FF000211C2FD
+:1008D00000021027000211C03063007F006218255B
+:1008E000A0830060026020210E00168C2405000108
+:1008F000000020218FBF00248FB400208FB3001C84
+:100900008FB200188FB100148FB00010008010213A
+:1009100003E0000827BD00288F83002827BDFFE8DB
+:10092000AFB00010AFBF0014906200638F87003437
+:1009300000808021344200408CE60010A0620063F9
+:100940003C0308008C6331B030C23FFF0043102BE2
+:100950001040004E8F8500382402FF8090A3000DC8
+:1009600000431024304200FF504000490200202183
+:10097000000613823048000324020002550200449E
+:100980000200202194A2001C8F850028240300234C
+:10099000A4A201148CE60000000616023042003FBB
+:1009A000104300103C0300838CE300188CA2007CF1
+:1009B000106200062402000E0E00158BA382004C6C
+:1009C0002403FFFF104300382404FFFF8F83002817
+:1009D0009062006334420020A06200630A0018C1E4
+:1009E0008F83002C00C31024144300078F83002C36
+:1009F00090A200623042000F34420020A0A20062A8
+:100A0000A38800408F83002C9062000D3042007F4D
+:100A1000A062000D8F83003C1060001802002021AE
+:100A20008F8400388C8200100043102B1040000986
+:100A300024020018020020210E00158BA382004C16
+:100A40002403FFFF104300182404FFFF0A0018E9E5
+:100A5000000020218C8200102405000102002021CA
+:100A6000004310238F83002C240600010E0016D9AA
+:100A7000AC6200100A0018E9000020210E00168C5C
+:100A8000240500010A0018E90000202102002021AD
+:100A90002402000D8FBF00148FB0001027BD001876
+:100AA0000A00158BA382004C8FBF00148FB000107A
+:100AB0000080102103E0000827BD001827BDFFD8E3
+:100AC000AFB000108F900034AFB3001CAFBF002058
+:100AD000AFB20018AFB100148E1200103C03080032
+:100AE0008C6331B032423FFF0043102B1040007C3A
+:100AF000008098218F8500382402FF8090A3000D8C
+:100B000000431024304200FF504000760260202154
+:100B10000012138230420003240300015443007189
+:100B20000260202190A2000D3042000854400003D2
+:100B30008F82003C0A00191924020024504000034F
+:100B40008E03000C0A001919240200278CA2002031
+:100B500014620005240200208E0300088CA20024E9
+:100B600010620008240200200E00158BA382004CA6
+:100B70002403FFFF1043006A2404FFFF0A00194406
+:100B80008F84002C8E0200142411FFFF14510003E7
+:100B90008F8700280A00193F240200258E030018C1
+:100BA0008CE2007C146200162402000E8E030024E6
+:100BB0008CA2002814620012240200218E06002854
+:100BC0008CA2002C14C2000E2402001F8E03002CE5
+:100BD0001060000B240200238CE200680043102BFD
+:100BE00014400007240200268CA20014006618217D
+:100BF0000043102B504000078F84002C2402002259
+:100C00000E00158BA382004C105100452404FFFFF9
+:100C10008F84002C2403FFF79082000D00431024E2
+:100C2000A082000D8F8600283C0308008C6331AC45
+:100C30008F82005094C400E08F85002C0043102167
+:100C400030847FFF00042040004410213043007FA7
+:100C5000034320213C03000E008320212403FF8056
+:100C600000431024AF42002CA49200008CA2002864
+:100C700024420001ACA200288CA2002C8E03002C80
+:100C800000431021ACA2002C8E02002CACA200303C
+:100C90008E020014ACA2003494A2003A2442000157
+:100CA000A4A2003A94C600E03C0208008C4231B095
+:100CB00024C4000130837FFF1462001300803021C0
+:100CC000240280000082302430C2FFFF000213C2E1
+:100CD000304200FF000210270A001981000233C0D1
+:100CE000026020212402000D8FBF00208FB3001C62
+:100CF0008FB200188FB100148FB0001027BD0028EC
+:100D00000A00158BA382004C8F82002802602021EC
+:100D1000240500010E00168CA44600E000002021EE
+:100D20008FBF00208FB3001C8FB200188FB100144A
+:100D30008FB000100080102103E0000827BD0028BC
+:100D400027BDFFE0AFB100148F910034AFB00010A9
+:100D5000AFBF00188E2600103C0308008C6331B032
+:100D600030C23FFF0043102B1040005E0080802106
+:100D70008F8500382402FF8090A3000D00431024CB
+:100D8000304200FF50400058020020218F82003C7A
+:100D900010400008000613828F8200289763000A23
+:100DA0002404FFFD944200603042FFFF10430055D1
+:100DB00000061382304200031440000E00000000C1
+:100DC00092220002104000058E230024506000157E
+:100DD000922300030A0019BA020020218CA20024E9
+:100DE0005062001092230003020020210A0019C261
+:100DF0002402000F90A2000D304200085440000968
+:100E00009223000302002021240200100E00158B03
+:100E1000A382004C2403FFFF1043003A2404FFFF89
+:100E200092230003240200025462000C9222000369
+:100E30008F82003C544000099222000302002021CE
+:100E40002402002C0E00158BA382004C2403FFFF0C
+:100E50001043002C2404FFFF9222000302202821CB
+:100E600002002021384600102CC600012C4200014F
+:100E70000E0015AB004630252411FFFF1051002154
+:100E80002404FFFF8F83003C106000120200202129
+:100E90003C0208008C42318C0043102B14400006A9
+:100EA00000000000000028210E0016D924060001D1
+:100EB0000A001A00000020212402002D0E00158BCC
+:100EC000A382004C1051000F2404FFFF0A001A00F7
+:100ED000000020210E00168C240500010A001A00D3
+:100EE00000002021020020212402000D8FBF0018E5
+:100EF0008FB100148FB0001027BD00200A00158BA1
+:100F0000A382004C8FBF00188FB100148FB0001067
+:100F10000080102103E0000827BD002093830040DB
+:100F200027BDFFE024020002AFB10014AFB00010F3
+:100F300000808821AFBF0018000080211062008C63
+:100F40002404FFFD978500428F83004430A2FFFFF9
+:100F50000043102B5440007D8F8400480E00144C39
+:100F6000000000003C020800244275940220202169
+:100F7000004028210E001612AF8200342409FFFF22
+:100F80001049007B2404FFFF3C0808008D0875A46D
+:100F90003C0208008C4231B03C0308009063759419
+:100FA00031043FFF0082102B1040001B3067003FD0
+:100FB0003C0208008C4231A88F830050000421803D
+:100FC00000621821006418213062007F034228214A
+:100FD0003C02000C00A228213C02008034420001A7
+:100FE0003066007800C230252402FF8000621024A1
+:100FF000AF42002830640007AF4208048F82002807
+:101000000344202124840940AF460814AF85002CF6
+:10101000AF840038AC4301189383004024020003DE
+:101020001462003B240200012402002610E2003D6D
+:1010300028E200271040001324020032240200227C
+:1010400010E2003828E200231040000824020024A7
+:101050002402002010E200242402002110E2001EDD
+:10106000022020210A001A7F2402000B10E2002D2A
+:101070002402002510E20010022020210A001A7F1D
+:101080002402000B10E2001A28E200331040000690
+:101090002402003F2402003110E2000B0220202134
+:1010A0000A001A7F2402000B10E200110220202106
+:1010B0000A001A7F2402000B0E00176C0220202168
+:1010C0000A001A9A004080210E0018EE022020210A
+:1010D0000A001A9A004080210E00198F0220202158
+:1010E0000A001A9A004080211509000E0000000035
+:1010F0000E001813022020210A001A9A00408021B5
+:101100000E00158BA382004C0A001A9A0040802121
+:1011100014620017020020212402002314E20005BB
+:101120002402000B0E001885022020210A001A9AC2
+:101130000040802102202021A382004C0E00158B4C
+:101140002410FFFF0A001A9B0200202130A500FF97
+:101150000E00148924060001978300428F82004408
+:10116000A780004200431023AF82004402002021E8
+:101170008FBF00188FB100148FB0001000801021B5
+:1011800003E0000827BD002027BDFFE0AFB1001439
+:10119000AFBF0018AFB000108F4601283C03080015
+:1011A0008C6331A02402FF80AF86005000C3182159
+:1011B0003065007F03452821006218243C02000AA4
+:1011C000AF43002400A2282190A200620080882161
+:1011D000AF850028304200FF00021102A3820040C8
+:1011E00090A200BC304200021440000224030034EC
+:1011F000240300308F820028A383003093830040B3
+:101200008C4200C0A380004CAF8200442402000442
+:10121000106200308F8400448E2400045080002D22
+:101220008F8400448E2200103083FFFFA784004289
+:101230001060001FAF8200488F8300282405FF80C4
+:10124000022020219062006300A21024304200FF9F
+:101250001440000D000000000E001A069790004296
+:1012600010400010004018212402FFFD54620011BC
+:101270008E230020020028210E00142A02202021A3
+:101280000A001AEC8E2300209062006300A2102452
+:10129000304200FF10400003022020210E00174EB4
+:1012A00000000000978200421440FFE48F83002872
+:1012B0008E23002030620004104000068F8400441A
+:1012C0002402FFFB006210240E00143EAE22002018
+:1012D0008F8400448F8300288FBF00188FB10014C3
+:1012E0008FB000102402000127BD002003E0000899
+:1012F000AC6400C030A500FF2403000124A9000154
+:101300000069102B1040000C00004021240A00014D
+:1013100000A31023004A3804246300013082000136
+:101320000069302B104000020004204201074025D4
+:1013300054C0FFF800A3102303E0000801001021AF
+:1013400027BDFFE03C021EDCAFB20018AFB10014B5
+:10135000AFBF001CAFB0001034526F4100008821B5
+:10136000240500080E001AFC0220202100118080B4
+:101370003C07080024E771940002160002071821B8
+:10138000AC6200000000282124A200013045FFFFCC
+:101390008C6200002CA600080441000200022040DC
+:1013A0000092202614C0FFF8AC64000002078021E0
+:1013B0008E0400000E001AFC2405002026230001E4
+:1013C0003071FFFF2E2301001460FFE5AE02000024
+:1013D0008FBF001C8FB200188FB100148FB00010A7
+:1013E00003E0000827BD00203C02080024426A8474
+:1013F0003C010800AC2271883C02080024425000E5
+:101400003C010800AC22718C240200063C0108005B
+:10141000A02271900A001B0F0000000027BDFFD81A
+:10142000AFB3001CAFB20018AFBF0020AFB10014C3
+:10143000AFB000108F5101408F480148000894025E
+:10144000324300FF311300FF8F4201B80440FFFE1A
+:1014500027500180AE1100008F420144AE0200040B
+:1014600024020002A6120008A202000B24020014AB
+:10147000AE130024106200252862001510400008F9
+:101480002402001524020010106200302402001211
+:10149000106200098FBF00200A001C308FB3001CAF
+:1014A0001062006724020022106200378FBF002004
+:1014B0000A001C308FB3001C3C0208008C4231A093
+:1014C0002403FF800222102100431024AF42002495
+:1014D0003C0208008C4231A0022210213042007FE1
+:1014E000034218213C02000A00621821166000B372
+:1014F000AF830028906200623042000F3442003017
+:10150000A06200620A001C2F8FBF00203C04600014
+:101510008C832C083C02F0033442FFFF0062182445
+:10152000AC832C083C0208008C4231A08C832C0830
+:101530002442007400021082000214800062182508
+:10154000AC832C080A001C2F8FBF00203C0208002F
+:101550008C4231A02403FF8002221021004310247A
+:10156000AF4200243C0208008C4231A03C03000A38
+:10157000022210213042007F03421021004310213B
+:101580000A001C2EAF8200283C0208008C4231A0C9
+:101590002404FF800222102100441024AF420024C2
+:1015A0003C0208008C4231A0022210213042007F10
+:1015B000034218213C02000A006218219062006375
+:1015C00000821024304200FF1040007CAF830028CE
+:1015D00024620088944300123C0208008C4231A827
+:1015E00030633FFF000319800222102100431021C5
+:1015F0003043007F03431821004410243C04000CB6
+:1016000000641821AF4200280E00155AAF83002C49
+:101610008F4201B80440FFFE00000000AE11000040
+:101620008F420144AE02000424020002A612000808
+:10163000A202000BAE1300240A001C2F8FBF002053
+:101640002406FF8002261024AF4200203C0208003E
+:101650008C4231A031043FFF00042180022210217E
+:1016600000461024AF4200243C0308008C6331A8DC
+:101670003C0208008C4231A03227007F022318214F
+:1016800002221021006418213042007F3064007F64
+:10169000034228213C02000A0066182400A22821E7
+:1016A000034420213C02000C00822021AF4300288B
+:1016B0003C0200080347182100629021AF850028F2
+:1016C000AF84002C0E00155A010080218F4201B812
+:1016D0000440FFFE8F82002C8F8400282745018064
+:1016E0009042000DACB10000A4B00006000216004C
+:1016F0000002160300021027000237C214C00016B1
+:10170000248200889442001232033FFF30423FFFA0
+:101710001443001224026082908300632402FF803D
+:1017200000431024304200FF5040000C240260822D
+:10173000908200623042000F34420040A08200627A
+:1017400024026084A4A200082402000DA0A20005C7
+:101750000A001C193C02270024026082A4A200088F
+:10176000A0A000053C02270000061C00006218250E
+:1017700024020002A0A2000BACA30010ACA0001435
+:10178000ACA00024ACA00028ACA0002C8E42004CE1
+:101790008F84002CACA200189083000D2402FF80DF
+:1017A00000431024304200FF104000058FBF00208E
+:1017B0009082000D3042007FA082000D8FBF00207C
+:1017C0008FB3001C8FB200188FB100148FB00010BF
+:1017D0003C02100027BD002803E00008AF4201B81A
+:1017E00008004C2808004C2808004BA008004BD8E3
+:1017F00008004C0C08004C3008004C3008004C30FD
+:0418000008004B1081
+:0C1804000A0001220000000000000000AB
+:101810000000000D747061342E362E313600000049
+:10182000040610010000000000000000000000009D
+:1018300000000000000000000000000000000000A8
+:101840000000000000000000000000000000000098
+:101850000000000000000000000000000000000088
+:101860000000000000000000000000000000000078
+:101870000000000000000000000000000000000068
+:101880000000000000000000000000000000000058
+:1018900010000003000000000000000D0000000D1B
+:1018A0003C02080024421B803C03080024632014EF
+:1018B000AC4000000043202B1480FFFD24420004B4
+:1018C0003C1D080037BD2FFC03A0F0213C10080090
+:1018D000261004883C1C0800279C1B800E00015A1F
+:1018E000000000000000000D3084FFFF3082000780
+:1018F0008F85001810400002248300073064FFF831
+:101900000085302130C41FFF03441821247B400090
+:10191000AF85001CAF84001803E00008AF440084CA
+:101920003084FFFF308200078F8500208F860028DB
+:1019300010400002248300073064FFF80085202156
+:101940000086182B14600002AF8500240086202337
+:101950000344282134068000AF840020AF44008077
+:1019600000A6202103E00008AF84003827BDFFD87F
+:10197000AFB3001CAFB20018AFB00010AFBF00246F
+:10198000AFB40020AFB100143C0860088D145000C3
+:101990002418FF7F3C1A8000029898243672380C75
+:1019A000AD1250008F5100083C07601C3C086000DD
+:1019B00036300001AF500008AF800018AF40008003
+:1019C000AF4000848CE600088D0F08083C076016C5
+:1019D0008CEC000031EEFFF039CA00103C0DFFFF27
+:1019E000340B80003C030080034B48212D44000150
+:1019F000018D28243C0253533C010800AC230420F1
+:101A0000AF890038AF860028AF840010275B400004
+:101A100014A2000334E37C008CF90004032818218D
+:101A20008C7F007C8C6500783C0280003452007012
+:101A3000AF85003CAF9F00403C13080026731BC4D9
+:101A40000240A0218E4800008F46000038C30001EC
+:101A50003064000110800017AF88003402804821F4
+:101A60008D2D00003C1908008F39045C3C110800E2
+:101A70008E31045801A8F823033F7821000040214B
+:101A80000228382101FF802B00F070213C01080062
+:101A9000AC2F045C3C010800AC2E04588F4C0000B5
+:101AA000398B0001316A00011540FFED01A0402192
+:101AB000AF8D00348E4E00003C0C08008D8C045C11
+:101AC0003C0A08008D4A045801C86823018D28216A
+:101AD0000000582100AD302B014B20210086102141
+:101AE0003C010800AC25045C3C010800AC22045811
+:101AF0008F4501088F44010030A92000AF85000008
+:101B0000AF84000C1120000A00A030213C0708001F
+:101B10008CE7042C24EF00013C010800AC2F042CBE
+:101B20003C104000AF5001380A0001900000000056
+:101B300030B002001600001424110F0010910012A2
+:101B400024070D001087023330B000065200FFF565
+:101B50003C104000936D0000240C001031A600F0F2
+:101B600010CC0269240E007010CE02DD8F8B0014A1
+:101B700025670001AF8700143C104000AF500138CA
+:101B80000A00019000000000974801041100FFE5E1
+:101B90003C10400030B84000170000A200000000D8
+:101BA0008F5901780720FFFE8F870038240900082D
+:101BB000240508008CE30008AF450178A7490140DF
+:101BC000A7400142974201048F8600003049FFFF81
+:101BD00030DF000113E002D5012040212524FFFE63
+:101BE000240A0002A74A01463088FFFFA7440148A3
+:101BF0003C0B08008D6B043C156002C48F8F000CF9
+:101C000030C30020146000022404000924040001F1
+:101C100030CD0C00240C040051AC000134840004CD
+:101C2000A744014A3C0508008CA504203C0200485A
+:101C30003C19000100A2F82530D8000203F928253C
+:101C400013000004000018213C04010000A4282512
+:101C50002403000130CA000451400005AF8300088E
+:101C60003C06001000A6282524030001AF830008CD
+:101C7000AF45100000000000000000000000000060
+:101C8000000000008F8300081060002300000000A7
+:101C90008F4B10000561FFFE000000001060001E69
+:101CA000000000008F4D10003C03002001A36024C1
+:101CB000118000198F8F000031EE000211C0001654
+:101CC00000000000975010141600001300000000E0
+:101CD0009745100830BFFFFF27F800060018C8829C
+:101CE0000019308000C7282133110001330300039D
+:101CF000122003208CA200000000000D00C7F82174
+:101D0000AFE200003C1908008F390430272600019B
+:101D10003C010800AC2604308F6A00003405FFFF48
+:101D2000AF8A00048CE200001045029A00002021D6
+:101D30008CE5000030BF010013E0027E010020218D
+:101D40003C0708008CE704743C1008008E10044C1B
+:101D500000E858213C1808008F1804700168882B8F
+:101D60003C0808008D080448000078210204602126
+:101D7000030F18210184702B010F6821007150217D
+:101D800001AE10213C010800AC2C044C3C010800C1
+:101D9000AC2204483C010800AC2B04743C01080050
+:101DA000AC2A04708F8D00180120302131290007E2
+:101DB00025AE000831C21FFF03426021AF8D001C19
+:101DC000AF820018259B4000AF4200841120000321
+:101DD0008F90002024C800073106FFF88F84002868
+:101DE00000D0282100A4782B15E00002AF90002439
+:101DF00000A4282303452021340380000083102100
+:101E00003C061000AF850020AF820038AF4500804F
+:101E1000AF4601788F8B0014256700010A0001DDB1
+:101E2000AF8700148F6200088F6700002411003014
+:101E30000007C602330300F0107100A2241900400D
+:101E40001479FF4B8F8B00148F4A01780540FFFEF9
+:101E500030A7020014E00003000512820000000D0C
+:101E6000000512823050000300104900013070213B
+:101E7000000E688001B06021000C58800173802141
+:101E80008E08000015000002000000000000000D98
+:101E90008F6F000405E202B192030006920700056D
+:101EA000920F00043C0200010007288000B060216E
+:101EB0008D8900182771000825EE00050122682190
+:101EC000000E3082AD8D0018022020210E0005800A
+:101ED00026050014920B00068F7F00043C087FFF4C
+:101EE000000B2080009130218CC30004350AFFFFD5
+:101EF00003EAC8240079C021ACD800049207000589
+:101F000092090004960D00080007288000B1F8210E
+:101F10008FEF0000974201043C07FFFF01E75024C8
+:101F2000304EFFFF01C96021018D58233168FFFF4A
+:101F300001482025AFE400009203000724190001A6
+:101F4000107902692406000310660279000000007F
+:101F50008E190010241F000AA75F0140A7590142F3
+:101F6000920300048F86000024070001A743014468
+:101F7000A74001469758010430D100023C050041BA
+:101F8000A758014800001821A747014A1220000362
+:101F900030CA00043C050141240300015140000502
+:101FA000AF8300083C08001000A828252403000186
+:101FB000AF830008AF4510000000000000000000E3
+:101FC00000000000000000008F8B0008116000047A
+:101FD000000000008F4410000481FFFE000000009C
+:101FE0008F6A0000920700043C0508008CA5044499
+:101FF000AF8A0004975F01043C0F08008DEF044096
+:1020000030E300FF33F9FFFF0079C02100B86821F9
+:102010000000102124E6000A30C8FFFF01B8482B59
+:1020200001E2702101C96021311000073C01080064
+:10203000AC2D04443C010800AC2C04401200000309
+:102040008F8D0018250B00073168FFF8010D7021F6
+:1020500031CC1FFFAF8D001CAF8C0018AF4C00843B
+:1020600097440104034C80213084FFFF308800072F
+:1020700011000003261B4000248900073124FFF8CB
+:102080008F8200208F850028008220210085782BF8
+:1020900015E00002AF82002400852023034488213C
+:1020A00034058000022510213C061000AF8400207A
+:1020B000AF820038AF440080AF4601780A00028545
+:1020C0008F8B00148F5F017807E0FFFE30AA0200BB
+:1020D00015400003000542820000000D0005428209
+:1020E000310200030002710001C26821000D60800E
+:1020F000018248210009288000B380218E0B000056
+:1021000011600002000000000000000D8F6F000C45
+:1021100005E001F38F87003824190001AE19000093
+:102120008CE30008A20000078F78000400181C024E
+:10213000306600FF24D10005001130832CC400411B
+:1021400014800002A20300040000000D8F6B000445
+:102150003C0EFFFF00E028213164FFFF248F000BBD
+:10216000000F408200081080004748218D2D00009C
+:1021700026040014A60B000801AE60240E000580A2
+:10218000AD2C00008F5F01083C0A100003EA3824E0
+:1021900010E001A30000000097460104920300072D
+:1021A00024D1FFEC346500023224FFFFA2050007B2
+:1021B000960600082CC7001354E0000592030007A0
+:1021C000920A0007355F0001A21F00079203000773
+:1021D000240B0001106B01BA24090003106901CD22
+:1021E0008F88003830CFFFFF25E400020004C88349
+:1021F000333F00FF001F2880A219000500A85821C6
+:102200008D780000975101043C03FFFF0303602415
+:102210003222FFFF004F702325CDFFFE018D4825A0
+:10222000AD690000920600053C02FFF6344EFFFF48
+:1022300030CA00FF000A388000F020219099001475
+:102240003C1FFF7F37E7FFFF3323000F0066782135
+:1022500031F800FF0018288000B088218E2D002062
+:1022600000A86021A20F000601AE4824AE0D000CAC
+:10227000AD89000C920B00068E04000C0127F82497
+:10228000000B50800150C821972600260148C0212C
+:1022900000874024AF260024AE08000CAF3F00208A
+:1022A000AF0600108F860000240C001024090002E5
+:1022B000A74C0140A7400142A7400144A74901465D
+:1022C000974B01042407000130C80002256AFFFE75
+:1022D000A74A01483C050009A747014A110000032D
+:1022E000000018213C0501092403000130CD000441
+:1022F00051A00005AF8300083C06001000A6282569
+:1023000024030001AF830008AF4510000000000067
+:10231000000000000000000000000000921800040F
+:1023200027110002322F0007000F1023304E000744
+:10233000AE0E00108F900008120000040000000094
+:102340008F4310000461FFFE000000008F78000042
+:102350008F8F00183C1008008E100444AF980004C2
+:102360009751010425E6001030CA1FFF3222FFFFFB
+:10237000AF8F001CAF8A0018AF4A00842449FFFECB
+:102380003C0B08008D6B0440974E0104012068212E
+:10239000000967C3020D282131C9FFFF00AD402BA2
+:1023A000016C382100E82021034AF8213139000767
+:1023B0003C010800AC2504443C010800AC24044066
+:1023C0001320000327FB4000252300073069FFF896
+:1023D0008F9F00208F840028013F382100E4C82B04
+:1023E00017200002AF9F002400E438230347202178
+:1023F00034058000008510213C061000AF870020C6
+:10240000AF820038AF470080AF4601780A000285EE
+:102410008F8B0014975801041300FDC23C1040003C
+:102420008F4301780460FFFE30B9400013200003A1
+:102430003C0400080000000D3C040008AF440140CB
+:1024400024080800AF4801788F8B0000974A0104E8
+:10245000317F000113E000E93146FFFF24D0FFFE89
+:10246000240C0002A74C0146A75001488F8F00188A
+:102470002405000DA745014A8F71000025E20008E0
+:1024800030491FFF0349702130CD0007AF91000490
+:10249000AF8F001CAF89001800C03821AF490084FD
+:1024A00011A0000325DB400024C6000730C7FFF859
+:1024B0008F9800208F84002800F8302100C4382B2A
+:1024C00014E00002AF98002400C430238F8A001467
+:1024D00003465821340880000168F821255900017D
+:1024E0003C0310003C104000AF860020AF9F003836
+:1024F000AF460080AF430178AF990014AF50013868
+:102500000A000190000000008F6900009744010458
+:102510003127FFFF3088FFFF8F4F017805E0FFFE76
+:1025200030FF0007001F18233078000724E6FFFE65
+:102530002419000AA7590140A7580142A74601449F
+:10254000A7400146A74801488F42010830510020AA
+:1025500016200002240300092403000130AA00020F
+:10256000A743014A3C040041114000030000182128
+:102570003C0401412403000130AB0004516000051C
+:10258000AF8300083C0500100085202524030001CE
+:10259000AF830008AF4410000000000000000000FE
+:1025A00000000000000000008F90000812000004EE
+:1025B000000000008F4C10000581FFFE00000000AD
+:1025C0008F780000276200088F8D003CAF980004D0
+:1025D000944600089451000A944F000C30CEFFFF3F
+:1025E0000011240031E9FFFF11CD00A20089202550
+:1025F0003C0308008C6304443C1808008F18044016
+:1026000000E85021255FFFFE007F782100001021A7
+:1026100001FF302B03028821022648213C010800DB
+:10262000AC2F04443C010800AC29044024EB000812
+:102630003162FFFF3047000710E000038F8500186C
+:10264000245000073202FFF83106FFFF30C80007B0
+:102650000045702131CD1FFF034D6021AF85001C67
+:10266000AF8D0018259B4000AF4D00841100000382
+:102670008F8F002024C400073086FFF88F84002845
+:1026800000CF282100A4482B15200002AF8F002482
+:1026900000A42823AF850020AF4500803C1108002E
+:1026A0008E3104340345C0213402800003023021FE
+:1026B00012200005AF860038938300172419000EFE
+:1026C0001079000D241F043F3C0A1000AF4A017826
+:1026D0008F8B0014256700010A0001DDAF8700140D
+:1026E0000E0005A63C1040008F8B001425670001EA
+:1026F0000A0001DEAF8700143C0A1000A75F014802
+:10270000AF4A01780A0004B48F8B0014240E0F0026
+:1027100011EE003D30D100201620000224030009F4
+:10272000240300010A000208A743014A0A0001FB32
+:10273000A740014694E5000894E2000A94EB000CDF
+:102740008F86003C0002FC00316AFFFF30B9FFFFBA
+:102750001326003703EA20253C0508008CA5044415
+:102760003C1F08008FFF04400000502100A83821C2
+:1027700000E8302B03EAC8210326C0213C010800F1
+:10278000AC2704443C010800AC3804400A0002694C
+:102790008F8D00183C1908008F39047C3C03080019
+:1027A0008C6304543C0608008CC604783C0F080077
+:1027B0008DEF0450032838210068682100E8C02B01
+:1027C00000C4882101A8402B01E47021023858215F
+:1027D00001C860213C010800AC2D04543C010800F4
+:1027E000AC2C04503C010800AC27047C3C010800E0
+:1027F000AC2B04780A0002698F8D0018A7400146AF
+:102800000A00041B8F8F001830D000201600FFC56F
+:102810002403000D240300050A000208A743014A0F
+:10282000975901042738FFF00A00036B3304FFFFB8
+:102830008F8C0040148CFFC8000080213C110800E0
+:102840008E31046C3C0408008C84046802287021DA
+:1028500001C8782B00904021010F68213C0108003D
+:10286000AC2E046C3C010800AC2D04680A0002691F
+:102870008F8D00188F9900401499FF5D0000602132
+:102880003C0508008CA5046C3C1008008E10046800
+:1028900000E82021248EFFFE00AEF82103EE582B25
+:1028A000020C5021014B18213C010800AC3F046C84
+:1028B0003C010800AC2304680A00048B24EB0008E8
+:1028C0008F8800383C02FFFF8D0E000C01C2682487
+:1028D00001A46025AD0C000C0A00037930CFFFFF86
+:1028E0000A0003A9AE000000974B01049204000403
+:1028F0008E2A000C01644021251FFFF20147182495
+:1029000033F9FFFF0079C025AE38000C0A0002D46D
+:102910008E1900103C03FFFF8D11001002232824A4
+:1029200000A47825AD0F00100A00037930CFFFFF17
+:1029300097450104920600048E2F001000A6102176
+:102940002449FFEE01E76824312EFFFF01AE602528
+:10295000AE2C00100A0002D48E1900108E06000C56
+:10296000AE0000000003C080031088210A0002A608
+:10297000AE2600201460000D3050FFFF3C04FFFF26
+:102980000044602401846826000D582B000C502B55
+:10299000014B102410400002000000000000000D58
+:1029A0008CA300000A00023E006410253A11FFFFCC
+:1029B0000011782B0010702B01CF20241080000212
+:1029C000000000000000000D8CB800000A00023E6C
+:1029D0003702FFFF3084FFFF30A5FFFF10800007A4
+:1029E0000000182130820001104000020004204243
+:1029F000006518211480FFFB0005284003E0000853
+:102A00000060102110C00007000000008CA2000030
+:102A100024C6FFFF24A50004AC82000014C0FFFB05
+:102A20002484000403E000080000000010A0000857
+:102A300024A3FFFFAC86000000000000000000009F
+:102A40002402FFFF2463FFFF1462FFFA24840004C2
+:102A500003E0000800000000308EFFFF30D8FFFFC9
+:102A600000057C0001F8602539CDFFFF01AC502145
+:102A7000014C582B014B4821000944023127FFFF2C
+:102A800000E830210006240230C5FFFF00A4182111
+:102A90003862FFFF03E000083042FFFF3C0C0800F3
+:102AA0008D8C0484240BFF8027BDFFD0018450212E
+:102AB000014B4824AF4900203C0808008D080484DD
+:102AC000AFB20020AFB00018AFBF0028AFB30024F2
+:102AD000AFB1001C936600040104382130E4007F8C
+:102AE000009A10213C0300080043902130C50020CB
+:102AF000036080213C080111277B000814A000021C
+:102B0000264600702646006C92130004975101047B
+:102B1000920F00043267000F322EFFFF31ED0040AC
+:102B200001C7282311A0000500004821925900BCCC
+:102B3000333800041700009000000000924300BCEE
+:102B4000307F000413E0000F0000000010A0000D13
+:102B500000000000960E0002240AFF8000A76021FA
+:102B600025CDFFFEA74D1016920B0004014B20242B
+:102B7000308200FF10400085010C40253C0F04000E
+:102B8000010F40258F5301780660FFFE2404000AE0
+:102B9000A7440140960D00022404000931AC00074F
+:102BA000000C5823316A0007A74A0142960200022E
+:102BB0002443FFFEA7430144A7400146975F010459
+:102BC000A75F01488F5901083338002053000001E6
+:102BD00024040001920F000431EE001015C0000221
+:102BE0003483001000801821A743014A0000000030
+:102BF000000000000000000000000000AF481000CE
+:102C000000000000000000000000000000000000C4
+:102C10008F5110000621FFFE3113FFFF12600003E9
+:102C2000000000008F481018ACC800009603000692
+:102C3000307FFFFF27F90002001998820013888077
+:102C4000023B30218CD800001520005700183402B8
+:102C5000920300042405FF8000A3F82433F100FF51
+:102C60001220002C00000000924700BC30F200024D
+:102C70001240002800000000974B100C2562FFFE58
+:102C8000A7421016000000003C0A0400354900303D
+:102C9000AF4910000000000000000000000000002C
+:102CA000000000008F4C10000581FFFE00000000B6
+:102CB0009749100C8F51101C00C020213127FFFFB5
+:102CC00024F20030001218820003288000BBF82193
+:102CD0003226FFFFAFF100000E00059500112C0217
+:102CE0000013C880033B98218E7800000002740016
+:102CF000AFB800108FA80010310FFFFFAFAF00106A
+:102D00008FA4001001C46825AFAD00108FA600107D
+:102D1000AE66000097730008976D000A9766000C76
+:102D20008F8A003C000D5C0030CCFFFF3262FFFF59
+:102D3000104A0036016C2025960600023C10100057
+:102D400024D300080E0001393264FFFF974C0104C0
+:102D50000E0001473184FFFFAF5001788FBF00287C
+:102D60008FB300248FB200208FB1001C8FB00018E9
+:102D700003E0000827BD003010A0FF700000000035
+:102D800024A5FFFC0A0005CE240900048CD1000014
+:102D9000AF5110188F5301780660FF7A2404000A9F
+:102DA0000A0005E30000000000A7C8218F88003852
+:102DB0008F4E101C0019C0820018788001E8202175
+:102DC000AC8E0000000E2C0200C020210E000595E4
+:102DD00031C6FFFF023B28218CAD000000025400E9
+:102DE00000403021AFAD00108FAC0010318BFFFFE1
+:102DF000AFAB00108FA2001001424825AFA9001010
+:102E00008FA700100A000613ACA700008F8F0040A8
+:102E1000148FFFC90000000097420104960B0002C6
+:102E20003C0508008CA5046C3049FFFF316AFFFFA8
+:102E30003C1108008E310468012A382124F2FFFE7B
+:102E400000B240210012FFC30112C82B023FC02173
+:102E5000031920213C010800AC28046C3C01080047
+:102E6000AC2404680A00064D0000000000A4102BEA
+:102E700010400009240300010005284000A4102B85
+:102E800004A00003000318405440FFFC0005284044
+:102E900010600007000000000085302B14C0000205
+:102EA00000031842008520231460FFFB0005284220
+:102EB00003E00008008010218F85002C27BDFFE86B
+:102EC000000530272CC300012CA40002008310252C
+:102ED00010400003AFBF00102405007FAF85002C19
+:102EE0000005282730A5FFFF0E000574240426F5F1
+:102EF0008F830030240402BD004030210083382B32
+:102F000010E0000924050001000420400083102B7C
+:102F100004800003000528405440FFFC00042040CA
+:102F200010A0000800C350210064402B15000002CF
+:102F3000000528420064182314A0FFFB000420426F
+:102F400000C350218FBF0010000A4C02312200FF45
+:102F500027BD0018AF8A002C03E00008AF890030BD
+:102F60000A00002600000000000000000000000D24
+:102F7000747870342E362E313600000004061000AE
+:102F80000000000A000001360000EA6000000000B6
+:102F90000000000000000000000000000000000031
+:102FA0000000000000000000000000000000000021
+:102FB0000000000000000000000000000000000011
+:102FC0000000001D000000000000000000000000E4
+:102FD00000000000000000000000000000000000F1
+:102FE00000000000000000000000000000000000E1
+:102FF00000000000000000000000000010000003BE
+:10300000000000000000000D0000000D3C02080060
+:1030100024423AA03C03080024633C54AC40000026
+:103020000043202B1480FFFD244200043C1D0800B7
+:1030300037BD7FFC03A0F0213C100800261000984B
+:103040003C1C0800279C3AA00E000305000000006D
+:103050000000000D8F8300383C08800035070070A9
+:103060008CE50000008330253C02900000C2202542
+:10307000AF850030AF4400208F4900200520FFFEBF
+:103080003C038000346200708C4500008F86003065
+:103090003C1908008F39007C3C0E08008DCE00786A
+:1030A00000A6202303245821000078210164682B06
+:1030B00001CF6021018D50213C010800AC2B007C28
+:1030C0003C010800AC2A007803E000080000000082
+:1030D0000A00003D240400018F8400383C05800074
+:1030E00034A200010082182503E00008AF4300204D
+:1030F00003E00008000010213084FFFF30A5FFFF2F
+:1031000010800007000018213082000110400002EA
+:1031100000042042006518211480FFFB00052840B0
+:1031200003E000080060102110C00007000000004C
+:103130008CA2000024C6FFFF24A50004AC8200007E
+:1031400014C0FFFB2484000403E00008000000001A
+:1031500010A0000824A3FFFFAC86000000000000C0
+:10316000000000002402FFFF2463FFFF1462FFFA47
+:103170002484000403E0000800000000308AFFFF00
+:1031800093A80013A74A014497490E1630C600FFC2
+:103190003C021000A7490146AF450148A346015231
+:1031A000A748015AAF4701608FA400188FA30014ED
+:1031B000A7440158AF43015403E00008AF4201782F
+:1031C00003E00008000000003C038000346200704F
+:1031D0008C4900008F88003C2484000727BDFFF83D
+:1031E0003084FFF8AF890030974D008A31ACFFFF83
+:1031F000AFAC00008FAB0000016850232547FFFFF4
+:1032000030E61FFF00C4282B14A0FFF73C0C800001
+:10321000358B00708D6A00003C0708008CE7008445
+:103220003C0608008CC60080000810820149182363
+:103230000002788000E370210000202101C3C82B28
+:1032400000C4C02101FA4021031948212502400091
+:1032500027BD00083C010800AC2E00843C0108009A
+:10326000AC29008003E00008000000008F82003CD1
+:103270002486000730C5FFF800A2182130641FFF24
+:1032800003E00008AF84003C3C0E20FF27BDFFE0B8
+:103290003C1A80003C0F800835CDFFFDAFBF001801
+:1032A000AFB10014AFB00010AF8F0044AF4D0E00AF
+:1032B000000000000000000000000000000000000E
+:1032C000000000003C0C00FF358BFFFDAF4B0E00F3
+:1032D0003C0660048CC95000240AFF7F3C1160004A
+:1032E000012A40243507380CACC750008E2404381E
+:1032F00024050009AF4500083083FFFF38622F71B5
+:103300002450C0B3AF80004C0E000064AF80003C7E
+:1033100052000001AE20442C0E00046000000000AA
+:103320008FBF00188FB100148FB000100A000E7705
+:1033300027BD002027BDFFD0AFB20028AFB10024C9
+:10334000AFBF002CAFB00020936200080080902136
+:1033500000A088211440002D240400100E00009AC3
+:10336000000000008F8E004C3C10320031C600FF80
+:1033700000067C0001F0602525CD0001AF8D004CDA
+:10338000AC4C0000936B00099369000A316A00FF9E
+:10339000000A3C00312800FF00E82025AC4400046E
+:1033A0008F83004C06400043AC430008AC40000C47
+:1033B000979800403305000814A000022628000654
+:1033C0002628000297420E148F450E1C8F670004BA
+:1033D000937F00023044FFFF33F900FFAFB90010C4
+:1033E0008F710014AFA800180E000087AFB1001451
+:1033F0008FBF002C8FB200288FB100248FB0002027
+:10340000240400100A0000C327BD0030936900099E
+:103410009368000B312300FF310200FF006280211E
+:10342000261F000A33F0FFFF0E00009A0200202141
+:103430008F86004C3C0D410024D90001AF99004C0F
+:103440009378000930C600FF00067400330500FFC2
+:1034500024AF000201CF6025018D5825AC4B000040
+:103460008F6A000C97440E1401523825AC470004B3
+:103470008F450E1C8F670004936900023084FFFFA4
+:10348000312800FFAFA800108F630014AFB10018FF
+:103490000E000087AFA30014020020218FBF002C74
+:1034A0008FB200288FB100248FB000200A0000C323
+:1034B00027BD00303C1280000A000114AC52000C01
+:1034C00027BDFFD8AFB3001CAFBF0020AFB20018BC
+:1034D000AFB10014AFB00010936200081440008137
+:1034E00000809821AF60000C9785004030A4400018
+:1034F0001080008B2403001624104007A363000AE9
+:10350000AF700014938F00428F6C001431EE0007EF
+:10351000000E6A40018D5825AF6B0014978A004059
+:103520008F6800143149001001093825AF67001475
+:103530009786004030C300085060008D00002821AD
+:103540008F6600143C0310003C02810000C3282554
+:10355000AF65001497440E0A2418000E3405FFFCD2
+:10356000309FFFFF03E2C825AF790004A378000273
+:103570009372000A26510004A371000A9783004049
+:103580009364000A30661F00000611830044F8218E
+:1035900027F90028A379000997580E0CA778001086
+:1035A0009372000926510002323000070010782380
+:1035B00031EE0007A36E000B936D0009976C0010AD
+:1035C0008F9000349789004031AB00FF016C50218F
+:1035D000014540213127004010E000053105FFFF83
+:1035E00000B0382B3C06800010E000140000882159
+:1035F0000205402B15000033000020218F4A0E14D5
+:10360000AF4A0E108F490E1CAF490E18AF450E0081
+:103610008F4C0000318B00081160FFFD000000009E
+:10362000974D0E0800A0802100003021A78D00409A
+:103630008F450E0424110001AF850034976E0010F1
+:1036400031D2FFFF8E640000009010231440000967
+:10365000AE6200008F6A00148F8700483549004031
+:10366000AF6900148F480E10ACE800208F430E188D
+:10367000ACE3002400C020210E0000F50200282148
+:103680008E66000014C00005000000008F6B00145F
+:10369000240CFFBF016C9824AF7300148F6D000CD5
+:1036A00001B22821AF65000C937200081640000398
+:1036B000000000001620003100000000A371000887
+:1036C000020020218FBF00208FB3001C8FB2001892
+:1036D0008FB100148FB000100080102103E00008AB
+:1036E00027BD00288F900034979100403C06800051
+:1036F00002009021322F004015E0FFD20000882107
+:10370000977F00108F98003433F9FFFF1738FFEDD3
+:1037100000002021000030210A0001B9241100011D
+:103720002403000E24104007A363000AAF700014A6
+:10373000938F00428F6C001431EE0007000E6A4038
+:10374000018D5825AF6B0014978A00408F680014D4
+:103750003149001001093825AF67001497860040F1
+:1037600030C300081460FF7600000000000028212C
+:10377000AF6000040A000187A36000028F6F00148D
+:103780003C19EFFF3738FFFE01F870240A0001D71B
+:10379000AF6E00148F8700388F8A004427BDFFE08A
+:1037A0008F860048AFB00018AFBF001C8F450104E2
+:1037B0008D4900ACAF4700808CC8002000A9382399
+:1037C00000008021AF480E108F440E1000004821E9
+:1037D000AF440E148CC20024AF420E188F430E1853
+:1037E000AF430E1C10E000362D390001936B00082A
+:1037F0001160004F00000000976E001031CDFFFFF8
+:1038000000ED602B1580004A000000009778001042
+:10381000330FFFFFAF4F0E008F5F000033F900083A
+:103820001320FFFD0000000097420E088F460E0493
+:103830003045FFFF30A300011060008A0000000047
+:103840000000000D30A8A040240400401104003BFB
+:1038500030A9A0001120008500000000936C000832
+:103860005180000927A40010976F001031EEFFFF70
+:1038700000CE682B11A0000427A4001030B800402F
+:103880001300007A00000000AFA70010A7850040D9
+:10389000AF8600340E0001580000000000404821AF
+:1038A0001440FFD08FA700108F420E148F84004861
+:1038B000AC8200208F470E1CAC8700242D390001FC
+:1038C0000330302510C000178FBF001C8F840038D4
+:1038D00024100F0010900085000000008F4F017829
+:1038E00005E0FFFE24180F001098006F0000000094
+:1038F0008F470E14240202403C101000AF470144D1
+:103900008F490E1CAF490148A3400152A740015AFC
+:10391000AF400160A7400158AF420154AF50017859
+:103920008FBF001C8FB0001803E0000827BD0020E7
+:10393000AF470E000A00022E000000008F490178F8
+:103940000520FFFE240A08008F84003CAF4A01785E
+:103950009758008A330FFFFF01E4702325CDFFFF46
+:1039600031AC1FFF2D8B00081560FFF9000000002F
+:103970008F83004C8F9F003800C0482103442021D2
+:103980002466000124190F00AF86004C306A00FF46
+:1039900000E938232486400013F9000524080001BB
+:1039A000938B004231680007000812403448000140
+:1039B000000A7C003C18010001F87025AC8E400024
+:1039C0008F8D004C30AC003630A40008ACCD000424
+:1039D0001080002E010C3025974D0E0A8F8C003C74
+:1039E0003C02810031A4FFFF258B000800824025A6
+:1039F0003C03100031651FFF25390006241F000E0F
+:103A0000AF48016000C33025A75F015AAF85003C75
+:103A1000A759015814E0000A8F9F003824050F00B1
+:103A200053E500022410000134C600408F430E10FD
+:103A30008F880048AD0300208F4B0E18AD0B00247B
+:103A40008F420E14AF4201448F440E1CAF44014814
+:103A5000A34A01523C0A1000AF4601540A00022159
+:103A6000AF4A017814C0FF7830A8A0408F420E14EE
+:103A70008F84004800004821AC8200208F470E1C34
+:103A8000AC8700240A0002582D3900018F98003CB1
+:103A900025390002A7590158270F000831EE1FFFF2
+:103AA0000A0002ADAF8E003CAF40014C1120002C4B
+:103AB000000000008F460E10AF4601448F430E18E1
+:103AC000240200403C101000AF430148A3400152C3
+:103AD000A740015AAF400160A7400158AF420154CE
+:103AE000AF5001780A0002718FBF001C1120000640
+:103AF00000000000975F0E0833E5004014A00002AC
+:103B0000000000000000000D8F4801780500FFFE56
+:103B100000000000974E0E103C0D0500240320000D
+:103B200031CCFFFF018D1025AF42014C8F440E14A4
+:103B30003C0B1000AF4401448F4A0E1CAF4A0148B1
+:103B4000A34001528F840038A740015AAF40016062
+:103B5000A7400158AF4301540A00025FAF4B017800
+:103B60008F590E14AF5901448F430E1C0A0002D91D
+:103B70002402004027BDFFE0AFB20018AFB100142F
+:103B8000AFB00010AFBF001C0E0000CA0000000064
+:103B90003C0280008F8A0044345000703C120800C0
+:103BA00026523B70020088218E0800008F450000DD
+:103BB00038A400013083000110600017AF88003086
+:103BC000022048218D2C00003C0208008C42006C31
+:103BD0003C1808008F1800680188182300436821EA
+:103BE0000000C82101A3782B0319702101CF4021C7
+:103BF0003C010800AC2D006C3C010800AC280068BA
+:103C00008F4B00003967000130E6000114C0FFED62
+:103C100001804021AF8C00308E1800003C0E08005F
+:103C20008DCE006C3C0C08008D8C00680308782356
+:103C300001CF28210000402100AF302B01885821FE
+:103C4000016620213C010800AC25006C3C01080005
+:103C5000AC2400688F49010025470088AF870048E1
+:103C6000AF890038AF4900208E070000AF870030D1
+:103C70008F5901780720FFFE000000008E0F000022
+:103C80003C0D08008DAD00743C0C08008D8C00705C
+:103C900001E7702301AE28210000302100AE582B2F
+:103CA00001862021008B3821240908003C010800EE
+:103CB000AC2500743C010800AC270070AF490178C6
+:103CC00093430108A383004293820042305F0001C6
+:103CD00017E000158F830038241F0D00107F001996
+:103CE00024020F001062001D000000009147000038
+:103CF0002403005030E900FF112300043C0540007C
+:103D0000AF4501380A000312000000000E0008DA77
+:103D1000000000008F8A00443C054000AF45013898
+:103D20000A00031200000000939900423338000695
+:103D3000001851000E00020D0152D8210A00036E36
+:103D40008F8A00443C1B0800277B3BF00E00020DCD
+:103D5000000000000A00036E8F8A00443C1B08002C
+:103D6000277B3C100E00020D000000000A00036ECD
+:103D70008F8A004490AA00018FAB00108CAC001019
+:103D80003C0300FF8D680004AD6C00208CAD001476
+:103D900000E060213462FFFFAD6D00248CA70018A5
+:103DA0003C09FF000109C024AD6700288CAE001C4F
+:103DB0000182C82403197825AD6F0004AD6E002C74
+:103DC0008CAD0008314A00FFAD6D001C94A90002C3
+:103DD0003128FFFFAD68001090A70000A560000229
+:103DE000A1600004A167000090A30002306200FF00
+:103DF0000002198210600005240500011065000E04
+:103E00000000000003E00008A16A00018CD800282F
+:103E1000354A0080AD7800188CCF0014AD6F0014C7
+:103E20008CCE0030AD6E00088CC4002CA16A00015D
+:103E300003E00008AD64000C8CCD001CAD6D0018D3
+:103E40008CC90014AD6900148CC80024AD6800084A
+:103E50008CC70020AD67000C8CC200148C830064FA
+:103E60000043C82B13200007000000008CC2001480
+:103E7000144CFFE400000000354A008003E0000815
+:103E8000A16A00018C8200640A0003C400000000E3
+:103E900090AA000027BDFFF88FA9001CA3AA00006C
+:103EA0008FAE00003C0FFF808FA8001835E2FFFFA7
+:103EB0008CCD002C01C26024AFAC0000A120000416
+:103EC00000E06021A7A000028FB800008D27000449
+:103ED0000188182100A0582100C05021006D28261B
+:103EE0003C06FF7F3C0F00FF2CAD000135EEFFFFCD
+:103EF00034D9FFFF3C02FF0003193024000D1DC020
+:103F0000010EC82400E2C02400C3702503197825DF
+:103F1000AD2E0000AD2F00048D450024AFAE000093
+:103F2000AD2500088D4D00202405FFFFAD2D000CB0
+:103F3000956800023107FFFFAD2700109166001859
+:103F400030C200FF000219C2506000018D450034EC
+:103F5000AD2500148D67000827BD0008AD27001CA3
+:103F60008C8B00CCAD2C0028AD20002CAD2B002478
+:103F7000AD20001803E00008AD20002027BDFFE0C1
+:103F8000AFB20018AFB10014AFB00010AFBF001C4B
+:103F90009098000000C088213C0D00FF330F007F87
+:103FA000A0CF0000908E000135ACFFFF3C0AFF005F
+:103FB000A0CE000194A6001EA22000048CAB001429
+:103FC0008E29000400A08021016C2824012A4024AD
+:103FD0000080902101052025A6260002AE240004C1
+:103FE00026050020262400080E0000722406000288
+:103FF00092470000260500282624001400071E0012
+:104000000003160324060004044000032403FFFFFA
+:10401000965900023323FFFF0E000072AE230010FA
+:10402000262400248FBF001C8FB200188FB100140B
+:104030008FB0001024050003000030210A00007C2E
+:1040400027BD002027BDFFD8AFB1001CAFB00018BE
+:10405000AFBF002090A80000240200018FB0003CF8
+:104060003103003F00808821106200148FAA0038BD
+:10407000240B0005506B0016AFAA001000A02021F1
+:1040800000C028210E00040702003021922400BC49
+:10409000308300021060000326060030ACC0000030
+:1040A00024C600048FBF00208FB1001C8FB0001801
+:1040B00000C0102103E0000827BD0028014038217E
+:1040C0000E000385AFB000100A00044B0000000092
+:1040D0000E0003CCAFB000140A00044B0000000037
+:1040E0003C02000A034218213C04080024843B08D7
+:1040F0002405001A000030210A00007CAF83002C48
+:104100003C038000346200708C48000000A05821FD
+:1041100000C04821308A00FFAF8800308F4401780A
+:104120000480FFFE3C0C8000358600708CC50000CA
+:104130003C0308008C6300743C1808008F18007062
+:1041400000A82023006468210000C82101A4782B66
+:104150000319702101CF60213C010800AC2D0074CF
+:104160003C010800AC2C00708F480E14AF4801448D
+:10417000AF47014CA34A0152A74B0158934601088F
+:1041800030C5000854A0000135291000934B0900E8
+:1041900024070050316A00FF1147000700000000AB
+:1041A0008F450E1CAF450148AF4901543C09100032
+:1041B00003E00008AF490178934D010831A80008D9
+:1041C0001100001000000000934F010831EE0010B4
+:1041D00051C00001352900083C04080090843B6C64
+:1041E000A34401508F4309A4AF4301488F4209A063
+:1041F000AF420144AF4901543C09100003E00008FC
+:10420000AF4901783C1908008F393B283338000842
+:104210005700FFF1352900080A00049E0000000045
+:1042200024070040AF470814AF4008108F420944EC
+:104230008F4309508F4409548F45095C8F46094CC0
+:10424000AF820064AF830054AF840050AF85005C40
+:1042500003E00008AF8600609346010930C5007F87
+:10426000000518C0000521400083102103E000086C
+:10427000244200883C0A0800914A3B2D3C09080072
+:1042800095293B263C051100000A3C002528000228
+:1042900000E8302500C5182524820008AC83000002
+:1042A00003E00008AC8000048F4A002C974D0908F9
+:1042B0003C0E000E034E382131ACFFFF000C41C014
+:1042C000AF48002C9743090894EB001A0080402166
+:1042D000240200013169FFFFAC8900008CE6001C5C
+:1042E00000A05821AC8600048CE40020AD04000836
+:1042F00090E30019306300031062003E00000000EC
+:104300002865000214A00071240F0002106F004CF9
+:104310000000000024180003107800550000000081
+:104320003C09080095293B1C93430934934F09210C
+:104330003C05080094A53B22306400FF94EE002A5F
+:104340000004688231EC00FF978F0058000DC60012
+:10435000000CCC003127FFFF0319102500A73021E6
+:104360000046202501CF68213C03400000836025E2
+:10437000000D4C00AD090004AD0C0000935909205C
+:104380003C1800062509001400193E0000F82825F5
+:10439000AD0500088F4E092C25E6000130C27FFFD5
+:1043A000AD0E000C8F440930A7820058250200286A
+:1043B000AD0400108F4D0938AD0D0014AD2B000475
+:1043C0008F4C0940AD2C0008934309373C19080075
+:1043D00093393B2CAD200010000347000019C400A6
+:1043E000011858253567FFFFAD27000C03E00008D2
+:1043F000AF4A002C3C09080095293B1C3C0D0800E5
+:1044000095AD3B263C0C0800958C3B1894E40024A9
+:10441000312EFFFF01AE302100CC18230004CC0068
+:104420002462FFF20322C025240F0800AD18000CFF
+:10443000AD0F0014AD0000100A0004F225080018AA
+:1044400094E5002494EE00283C09080095293B1CC3
+:1044500000056C00000E640035A68100358408005C
+:10446000AD06000CAD0400100A0004F2250800148B
+:104470003C09080095293B1C3C0F080095EF3B26A2
+:104480003C06080094C63B1894E400243125FFFF45
+:1044900094ED002801E5702101C660230004CC00E2
+:1044A000000D1C002582FFEE006278253738810060
+:1044B00024050800AD18000CAD0F0010AD05001864
+:1044C000AD0000140A0004F22508001C1460FF94DB
+:1044D0000000000094E300243C09080095293B1CDF
+:1044E0000003140034590800AD19000C0A0004F24E
+:1044F0002508001003E00008240201F427BDFFE8AE
+:10450000AFB00010AFBF00140E00005C008080212F
+:1045100024050040AF4508148F8300548F84005059
+:104520008F85005C0070182100641023184000047F
+:10453000AF830054AF6300548F660054AF860050C1
+:104540001200000C000000008F440074936800818A
+:104550003409FA002D07000710E00005008910213A
+:10456000936C0081240B01F4018B50040144102151
+:10457000AF62000C8F4E095C01C5682319A00004CE
+:104580008FBF00148F4F095CAF8F005C8FBF00148A
+:104590008FB000100A00005E27BD00188F840064F1
+:1045A0008F8300548F820050AF640044AF6300508B
+:1045B00003E00008AF6200543C03800034620070E6
+:1045C0008C43000027BDFFF8308700FF30A900FFB3
+:1045D00030C800FFAF8300308F4401780480FFFEB5
+:1045E0003C028000345900708F380000A3A70003FC
+:1045F0003C0708008CE700748FAC00003C06080004
+:104600008CC60070030378233C0E7FFF00EFC821A7
+:1046100035CDFFFF00005021018D282400CA18214C
+:10462000000847C0032F202B00A810250064C021DC
+:10463000AFA200003C010800AC3900743C01080046
+:10464000AC380070934F010AA3A000023C0E80FF1B
+:10465000A3AF00018FAC0000312B007F35CDFFFFF1
+:10466000018D4824000B5600012A40252407300004
+:104670002406FF803C05100027BD0008AF48014C10
+:10468000AF470154A7400158A346015203E0000878
+:10469000AF45017827BDFFE8AFBF0014AFB00010F1
+:1046A0008F6500743C068000309000FF00A6202536
+:1046B0000E00005CAF640074936300053462000870
+:1046C0000E00005EA3620005020020218FBF0014CF
+:1046D0008FB0001024050005240600010A0005968D
+:1046E00027BD001827BDFFE03C038000AFB00010DD
+:1046F000AFBF0018AFB10014346200708C470000E7
+:10470000309000FF30A800FFAF8700308F44017861
+:104710000480FFFE3C188000371100708E2F0000CF
+:104720003C0D08008DAD00743C0A08008D4A0070F5
+:1047300001E7702301AE28210000582100AE302B84
+:10474000014B4821012638213C010800AC250074AA
+:10475000000088213C010800AC2700701100000F08
+:10476000000000008F6200742619FFFF3208007FEE
+:104770000002FE0233E5007F15000006332200FF31
+:104780002407FF800207202624A3FFFF0083802543
+:10479000320200FF00408021241110080E00005C4E
+:1047A000000000008F4908183125000414A0FFFD07
+:1047B0003218007F001878C00018714001CF6821BE
+:1047C00025AC0088AF4C0818274A09808D4B002083
+:1047D000AF4B01448D460024AF460148A350015021
+:1047E0000E00005EA7400158022010218FBF001864
+:1047F0008FB100148FB0001003E0000827BD002027
+:1048000027BDFFE8308400FFAFBF00100E0005E1B8
+:1048100030A500FF8F8300548FBF00103445004047
+:104820002404FF903C02100027BD0018AF43014C48
+:10483000A3440152AF45015403E00008AF420178A0
+:1048400027BDFFE8AFBF0014AFB000109345093F8C
+:10485000240200063C08080095083B2230A300FF14
+:104860002487FFD8240500041062003624060002C5
+:10487000974E093C3C0D02040006340031CCFFFF8A
+:10488000018D5825AC8B0000934A093E3149002028
+:104890001120000800000000935F09363C19010355
+:1048A0003738030033F000FF02187825240500088C
+:1048B000AC8F000493580934934D09213C104000FB
+:1048C000330E00FF000E608231AB00FF000C56007B
+:1048D000000B1400014218250068F82503F0C825D4
+:1048E000AC99FFD8935809378F4C09488F4D094030
+:1048F00000057882330E00FF01CF5821018D282357
+:10490000000B57000146102530A3FFFF0043402550
+:10491000000F488001273021ACE800200E00005C29
+:1049200024D00028240400040E00005EA364003F8D
+:10493000020010218FBF00148FB0001003E00008A8
+:1049400027BD00180A0006442406001227BDFFD028
+:1049500024090010AFB50024AFB40020AFB3001C91
+:10496000AFB10014AFB000103C010800A0293B2CEF
+:10497000AFBF0028AFB2001897480908309400FF75
+:104980003C02000E3107FFFF000731C0AF46002C8C
+:10499000974409089344010B30B300FF0342802180
+:1049A000308300300000A821106000E4000088215E
+:1049B000240C00043C010800A02C3B2C934B093E26
+:1049C000000B5600000A2E0304A001310000000075
+:1049D000AF4000489352010B324F002011E0000617
+:1049E00000000000935F093E001FCE000019C603BF
+:1049F00007000148000000009346010B30C2004050
+:104A0000104000038F9200548F87005424F2FFFF60
+:104A1000960A002C9345093493490937A78A005810
+:104A200030A600FF312700FF00071080004620213C
+:104A30000091F8213C010800A43F3B22920300189A
+:104A40003C010800A4203B1C3C010800A4203B18AA
+:104A5000307000FF03F04021250B000A3170FFFF8A
+:104A60003C010800A4283B243C010800A4283B2664
+:104A70000E00009A020020210E0004C500402021F3
+:104A80008F4B002C975809083C19000E0359402100
+:104A9000330FFFFF000F71C0AF4E002C9743090882
+:104AA000950D001A241100010040382131ACFFFFA0
+:104AB000AC4C00008D0A001CAC4A00048D0500209F
+:104AC000AC4500089109001931230003107100BDA5
+:104AD0002871000216200103240C0002106C00F55E
+:104AE000240D0003106D00CA000000003C090800FE
+:104AF00095293B1C93430934935809213C0A08002B
+:104B0000954A3B22306400FF950C002A0004F8828D
+:104B1000331900FF97980058001F760000197C0099
+:104B20003126FFFF01CF402501466821010D882570
+:104B3000019828213C0840000228102500054C005F
+:104B4000ACE90004ACE20000934309203C040006F9
+:104B500024E900140003FE0003E4C825ACF90008B2
+:104B60008F4E092C270F000131E67FFFACEE000CC1
+:104B70008F4D0930A786005824E60028ACED0010C0
+:104B80008F4C0938ACEC0014AD3200048F51094051
+:104B9000AD310008934209373C05080090A53B2C35
+:104BA000AD2000100002270000051C000083F8253E
+:104BB00037F2FFFFAD32000CAF4B002C12A00033D8
+:104BC000000000009352093F24150006240500044C
+:104BD000324B00FF117500CD24090002974F093CAC
+:104BE0003C0E020431EDFFFF01AE6025ACEC002865
+:104BF0009351093E322200201040000800000000BE
+:104C0000934409363C180103371F0300309900FF15
+:104C1000033F2825ACC5000424050008935209343D
+:104C20009343092100056082324B00FF000BA882EC
+:104C3000306400FF0015FE000004C40003F8C8251E
+:104C4000032A782501E87025ACCEFFD8934D0937AB
+:104C50008F5209488F42094031B100FF022C582180
+:104C600002423023000B1F000009AC0000754825EC
+:104C700030C8FFFF012850250E00005CACEA002080
+:104C8000240700040E00005EA367003F0E0000C36F
+:104C9000020020213C05080090A53B2C30B0000309
+:104CA0001200000F028020218F8800542509000186
+:104CB000AF890054AF6900508F6A0054014938230E
+:104CC00018E00002012020218F640054AF640054DA
+:104CD0008F420074244601F4AF66000C028020214C
+:104CE00002602821A76000680E0005E13C13100057
+:104CF0008F8E005434540006AF4E014C8F8D004C03
+:104D00008FBF00288FB5002431B100FF25AC000112
+:104D1000AF8C004C8FB20018A35101528FB000101D
+:104D2000AF5401548FB10014AF5301788FB40020F9
+:104D30008FB3001C03E0000827BD00309359093EE3
+:104D40000019C6000018960306420048241100020C
+:104D500093420923304400021080FF1E8F870060B9
+:104D60008F86005414E6FF1B000000000E00005C5C
+:104D7000000000009365003F2408001630A900FFE2
+:104D80001128000C240A00083C0D080091AD3B2CB2
+:104D900035AC00013C010800A02C3B2C936B003F7C
+:104DA000316300FF106A0065240E000A106E005E79
+:104DB0002402000C0E00005E000000000A00069DA8
+:104DC000000000003C09080095293B1C3C19080024
+:104DD00097393B263C18080097183B18950E00247D
+:104DE000313FFFFF033F782101F86823000E8C005C
+:104DF00025ACFFF2022C502524050800244700189A
+:104E0000AC4A000CAC4500140A0006E5AC400010AA
+:104E10003C09080095293B1C3C18080097183B26C4
+:104E20003C0F080095EF3B18950D00243139FFFF2A
+:104E3000950C00280319702101CF8823000D2C0048
+:104E4000000C54002622FFEE0142302534A48100DC
+:104E500024030800ACE4000CACE60010ACE300183E
+:104E6000ACE000140A0006E524E7001C3C01080041
+:104E7000A0313B2C9343093E24150001307F0020D4
+:104E800017E0FED4241100080A00069D2411000436
+:104E90008F6E00848F4D094011A0FECDAF8E00545F
+:104EA000240F00143C010800A02F3B2C0A00069C94
+:104EB0000000000095020024950600283C09080027
+:104EC00095293B1C0002240000061C00349F810031
+:104ED00034790800ACFF000CACF900100A0006E5BC
+:104EE00024E700141460FF0100000000951800245E
+:104EF0003C09080095293B1C2447001000187C0041
+:104F000035EE08000A0006E5AC4E000C0A00071F4B
+:104F1000240900128F64004CAF6400548F63005466
+:104F20000A0006A6AF630050A362003F0E00005EB9
+:104F3000000000000A00069D00000000240200148A
+:104F40000A0007F3A362003F27BDFFE8308400FF9B
+:104F5000AFBF00100E0005E130A500FF9378007E82
+:104F60009379007F936E00809368007A332F00FF5F
+:104F700000186600000F6C0031CB00FF018D482542
+:104F8000000B52008FBF0010012A3825310600FFA8
+:104F90003444700000E628252402FF813C03100001
+:104FA00027BD0018AF45014CAF440154A342015244
+:104FB00003E00008AF43017827BDFFD8AFB2001867
+:104FC000AFB10014AFB00010AFBF0020AFB3001CF2
+:104FD00093420109308600FF30B000FF000618C27E
+:104FE000320400023071000114800005305200FFCD
+:104FF0009367000530E5000810A0000D30C80010D0
+:10500000024020210E0005CD0220282124040001A9
+:105010008FBF00208FB3001C8FB200188FB1001417
+:105020008FB000100080102103E0000827BD002889
+:105030001500003200000000934301090000282100
+:105040003062007F000220C00002F94003E4982192
+:1050500026790088033B98218E7800248E6F000803
+:10506000130F0046000000008F6400842418000223
+:105070000004FD8233F900031338007C00000000B7
+:1050800093660083934A0109514600043205007C6F
+:1050900010A00060000000003205007C14A0005346
+:1050A0000240202116200006320400018E7F0024D9
+:1050B0008F59010417F9FFD60000202132040001A6
+:1050C0001080000A024020218F4209408F93006423
+:1050D00010530006000000000E00067B022028216D
+:1050E0008F430940AF630044024020210E00062890
+:1050F000022028210A00082C240400013C09080091
+:105100008D290064252600013C010800AC260064BE
+:1051100016000012000000008F6D00843C0E00C0DD
+:1051200001AE602415800005024020210E0007FA20
+:10513000022028210A00082C240400012405000470
+:105140000E00059624060001024020210E0007FAF9
+:10515000022028210A00082C240400010E00003D32
+:1051600024040001936B007D020B50250E00005EAD
+:10517000A36A007D0A00086F8F6D00848F6600743B
+:105180008F4801048E67002400064E021507FFB603
+:105190003126007F936B008326440001308A007F14
+:1051A00011460043316300FF5464FFB08F640084F4
+:1051B0002645000130B1007F30A200FF1226000416
+:1051C00024050001004090210A000842241100013A
+:1051D000240FFF80024F702401CF9026324200FF3F
+:1051E000004090210A000842241100010E00067BB5
+:1051F00002202821321800301300FFAA321000824A
+:10520000024020210E0005CD022028210A00082C92
+:10521000240400018F6E00743C0F800024050003FD
+:1052200001CF9025AF7200749371008324060001B2
+:105230000E000596322400FF0E00003D24040001FC
+:10524000936D007D020D60250E00005EA36C007D55
+:105250003C0B08008D6B0054257000013C010800D8
+:10526000AC3000540A00082C240400018F6800743C
+:105270003C0980002405000401093825AF6700744B
+:1052800093630083240600010E000596306400FF3E
+:105290000E00003D240400019362007D0202982567
+:1052A0000E00005EA373007D0A00082C2404000198
+:1052B000324D008039AC0080546CFF6C8F640084E8
+:1052C0000A0008952645000127BDFFD03C0A0008CA
+:1052D000AFBF002CAFB40028AFB30024AFB20020A2
+:1052E000AFB1001CAFB00018034AD8212409004018
+:1052F000AF490814AF4008108F4209448F4309504A
+:105300008F4609548F47095C8F48094C9344010824
+:105310009345010BAF820064308400FF30A500FF8D
+:10532000AF830054AF860050AF87005C0E000816B4
+:10533000AF8800601440015A8FBF002CA76000683E
+:10534000934D0900240B00503C14080026943C3077
+:1053500031AC00FF3C12080026523C40118B000388
+:10536000000000000000A02100009021934F0109DF
+:105370008F8800542402001031F1007F001170C0AA
+:105380000011694001AE282124B80088AF580818E0
+:105390008F4A01048F4B09A43C0C000E034CC8211A
+:1053A000014B48233C010800AC293B088F440958B5
+:1053B0003C010800A0223B2C9746090800881823CE
+:1053C0003C010800AC233B0C30C7FFFF0007F9C0CD
+:1053D0003C010800AC283B30AF5F002C9742090825
+:1053E0009730002C8E910000932F0018037898219D
+:1053F000A7900058AF9300480220F80931F000FF51
+:10540000304E000215C0018E30530001126001427F
+:10541000000000008F4F09A4241300013C01080084
+:10542000AC2F3B3493510934934E0937322500FF9A
+:1054300031CD00FF000D60800185502101505821C1
+:105440003C010800A42B3B243C010800A42A3B2279
+:1054500093490934312200FF0202202124900010D8
+:105460003C010800A4303B20240800068F9900541A
+:105470003C010800AC283B288F9F005C8F580958DE
+:105480000000802103F9282304A0013C03192023F4
+:105490000480013A00A4382B10E0013C0000000019
+:1054A0003C010800AC253B0C8E4200000040F8098E
+:1054B000000000003046000214C000DD00408821DA
+:1054C00030430001546000108E4200043C04080088
+:1054D0008C843B103C09C00000898025AF500E0031
+:1054E0008F4B0000316A00081140FFFD00000000F2
+:1054F00097450E0824100001A78500408F4C0E042C
+:10550000AF8C00348E4200040040F8090000000017
+:1055100002228825322D000215A00159000000004A
+:105520003C09080095293B183C06080094C63B241A
+:105530003C04080094843B1A3C1908008F393B1046
+:10554000012658213C1808008F183B343C1F0800E6
+:1055500097FF3B2E016418218F4E09400329282113
+:10556000246F00020319682100BF60213C0108007C
+:10557000A42B3B26AF8E00643C010800AC2D3B34CD
+:105580003C010800A42C3B1C0E00009A31E4FFFFF4
+:105590008F87004C004020213C010800A0273B2DB4
+:1055A0008E42000824E80001AF88004C0040F80952
+:1055B000000000008F4B002C974909083C0A000EA0
+:1055C000034A38213124FFFF000419C08F8A005498
+:1055D000AF43002C9743090894E6001A004040218D
+:1055E00030DFFFFFAC5F00008CF9001CAC590004F9
+:1055F0008CF80020AC58000890EF001931E300034C
+:10560000107300E60000000028620002144001024E
+:10561000240C0002106C00F4240D0003106D00A790
+:10562000000000003C09080095293B1C9345093403
+:10563000934C09213C0F080095EF3B2230BF00FF3F
+:1056400094EE002A001F6882319900FF978C005861
+:10565000000D16000019C4003124FFFF01E43021C1
+:10566000005848250126382501CC28213C0340005C
+:1056700000E3F82500056C00AD0D0004AD1F00002F
+:10568000935909203C180006250D001400197E00CE
+:1056900001F87025AD0E00088F42092C2586000107
+:1056A0008E4C000CAD02000C8F44093030C97FFFD6
+:1056B000A7890058AD0400108F4709382504002839
+:1056C000AD070014ADAA00048F450940ADA5000840
+:1056D000934309373C1F080093FF3B2CADA00010FB
+:1056E0000003C700001FCC000319782535EEFFFF2B
+:1056F000ADAE000CAF4B002C0180F809000000009B
+:105700003C06080094C63B263C02080094423B1A23
+:1057100000C24821252B00020E0000C33164FFFFA8
+:105720003C0808008D083B083C0708008CE73B104C
+:10573000010750233C010800AC2A3B081540000635
+:10574000000000003C0808008D083B28350A004096
+:105750003C010800AC2A3B28120000848F830048DB
+:105760008F470E108F900048AE0700208F4B0E1809
+:10577000AE0B00243C10080096103B1C0E00005C91
+:1057800000000000240F0040AF4F08148F86005423
+:105790008F89005000D018210069702319C00004BF
+:1057A000AF830054AF6300548F640054AF84005043
+:1057B0001200000C000000008F44007493780081F8
+:1057C0003419FA002F020007104000050099182133
+:1057D000937F0081240C01F403EC680401A41821D8
+:1057E000AF63000C8F4A095C8F88005C0148282356
+:1057F00018A00003000000008F50095CAF90005C0F
+:105800000E00005E000000008F8300548E470010E1
+:105810003C010800AC233B3000E0F8090000000028
+:105820003C0B08008D6B3B081560FF102408000638
+:105830008F590024975F09088F8900648F8E005468
+:105840003C0C001F978400588F8F002C8F930050C2
+:1058500033F8FFFF358DFF80032D3024001811C071
+:1058600032320010AF420024A5E4002CAF460024E1
+:10587000AF690044AF6E0050AF7300545640007CD7
+:105880008E850004322A0040554000318E91000878
+:105890008E88000C0100F809000000008FBF002C6A
+:1058A0008FB400288FB300248FB200208FB1001C6A
+:1058B0008FB0001803E0000827BD00303C09080045
+:1058C00095293B1C3C03080094633B263C040800DC
+:1058D00094843B1894F900243125FFFF94F80028A4
+:1058E0000065F82103E478230019640000186C00B7
+:1058F00025EEFFEE01AE302535828100240308003D
+:10590000AD02000CAD060010AD030018AD00001490
+:105910000A0009B32508001C934301098F8600384B
+:1059200000033E0000E64025AF4800808F5F09A0DD
+:105930008F5809A4AFBF0010AF5F0E148FB90010CD
+:10594000AF590E10AF580E1C0A00092DAF580E1893
+:105950000220F809000000008E88000C0100F80900
+:10596000000000000A000A508FBF002CA460002035
+:10597000A47300220A000A05AC7300243C0108004D
+:10598000AC203B0C0A0009538E4200003C01080089
+:10599000AC243B0C0A0009538E4200003C0908006D
+:1059A00095293B1C3C1F080097FF3B263C0508003F
+:1059B00094A53B1894F800243124FFFF03E4C82188
+:1059C0000325782300186C0025EEFFF201AE602558
+:1059D000AC4C000C24020800AD020014AD00001015
+:1059E0000A0009B32508001894E6002494E300286F
+:1059F0003C09080095293B1C000624000003FC001C
+:105A00003485810037F90800AD05000CAD19001090
+:105A10000A0009B3250800141460FF02000000000A
+:105A200094F800243C09080095293B1C00187C00D0
+:105A300035EE0800AD0E000C0A0009B32508001071
+:105A400093520109000028210E000628324400FF6D
+:105A50008FBF002C8FB400288FB300248FB200209A
+:105A60008FB1001C8FB0001803E0000827BD003084
+:105A700000A0F809000000000A000A4A322A00408B
+:105A80001200FF6B000000008F4E0E148F92004832
+:105A9000AE4E00208F530E1C0A000A34AE53002471
+:105AA0008F820018008040213C040100904700854F
+:105AB00030E3002010600009000000003C070800EF
+:105AC0008CE73B308F83001400E320230480000820
+:105AD0009389000014E300030100202103E0000883
+:105AE000008010213C04010003E000080080102128
+:105AF0001120000B006738238F8C001C2409003410
+:105B0000918B00BC316A0002514000012409003031
+:105B100000E9682B15A0FFF10100202100E93823DE
+:105B20002419FFFC00B9C02400F9782400F8702B78
+:105B300015C0FFEA01E8202130C20003000218234B
+:105B400014C00012306900030000302100A9702148
+:105B500001C6682100ED602B1180FFE03C040100CC
+:105B60002D2F00010006482B0105382101E93024C2
+:105B700014C0FFDA24E4FFFC2419FFFC00B9C024A0
+:105B80000308202103E00008008010218F8B001CF7
+:105B900024060004916A00BC314400041480FFEC28
+:105BA00000A970210A000AFC0000302127BDFFE88F
+:105BB000AFBF00108F460100934A01093C1F080047
+:105BC0008FFF00902407FF80314F00FF31E8007FF6
+:105BD0000008614003E6C821032CC02127090120E9
+:105BE000012770243C010800A02F3B6CAF4E080C2D
+:105BF0003C0D08008DAD00903C0400803482000311
+:105C000001A65821016C18212465012030AA0078D2
+:105C100001424025AF48081C3C1F08008FFF009040
+:105C20008F88004403E6C021331900070307482486
+:105C3000033A7821AF49002825E909C0952E0002D2
+:105C40003C0D08008DAD008C3C0A08008D4A009088
+:105C500031CC3FFF01A61821000C5980006B282190
+:105C600000A72024AF44002C952200023C1F08000E
+:105C70008FFF008C9107008530593FFF03E67821A4
+:105C80000019C1800146702101F8682131CC007FE4
+:105C900031AB007F019A2821017A50213C03000C8E
+:105CA0003C04000E00A328210144102130E600200E
+:105CB00027470980AF820028AF880018AF890020ED
+:105CC000AF85001C10C00006AF8700248D02005075
+:105CD0008CA4010C0044302318C0007700000000A1
+:105CE000910C0085240DFFDF018D3824A10700856C
+:105CF0008F8B00188F8900208F8700248D65004CC2
+:105D0000AF850014912F000D31EE002011C0001757
+:105D10000000000024090001A3890000AF800008F2
+:105D20008CE400248F850008240A0008AF8000045A
+:105D3000AF80000C3C010800A42A3B1A3C0108007B
+:105D4000A4203B2E0E000AD0000030218F850020B9
+:105D50008FBF0010AF82001090A8000D27BD001863
+:105D60000008394203E0000830E20001913F0002E0
+:105D70002418000133F900FF00192182109800391E
+:105D8000240800021088005B8F8600288CE5002420
+:105D900014A0001B8F9F001C91220000240A000504
+:105DA0003046003F10CA0047240400018F860004DB
+:105DB000A3840000AF86000CAF8600088CE40024AA
+:105DC0008F850008240A00083C010800A42A3B1A19
+:105DD0003C010800A4203B2E0E000AD00000000069
+:105DE0008F8500208FBF0010AF82001090A8000D9B
+:105DF00027BD00180008394203E0000830E2000126
+:105E00008CF800088CF900248FEE00C4A3800000F9
+:105E10008CE40024AF8E00088F8500088F86000474
+:105E200003197823240A0008AF8F000C3C010800F6
+:105E3000A42A3B1A3C010800A4203B2E0E000AD0E5
+:105E4000000000008F8500208FBF0010AF8200107F
+:105E500090A8000D27BD00180008394203E0000893
+:105E600030E20001912300003062003F104400271F
+:105E70008F85001C8CE400241480002100000000A9
+:105E80008D2E00183C187FFF8F85001C370FFFFFF9
+:105E900001CF1824AF8300048F9F00048CA80084D6
+:105EA00003E8C82B1720000203E020218CA4008403
+:105EB0000A000B8BAF8400048CA3010C0A000B6951
+:105EC000AF8300148D2C00188F8600043C0D7FFFDB
+:105ED0008F89001C35A3FFFF01835824240400018F
+:105EE000AF8B000CAD2000CCA38400000A000B9700
+:105EF000AF8600088CCA00140A000B8BAF8A00041E
+:105F00008CA300C80A000BCEAF8300048F84002846
+:105F10008CAC00648C8D0014018D582B1160000432
+:105F2000000000008CA200640A000BCEAF820004C7
+:105F30008C8200140A000BCEAF8200048F8500080B
+:105F400027BDFFE0AFBF0018AFB1001414A00007D9
+:105F5000AFB000108F8600202402000590C400001E
+:105F60003083003F106200B68F84001C8F910004C4
+:105F700000A080218F8C00243C0508008CA53B0CE0
+:105F80008D8B000431663FFF00C5502B554000014A
+:105F900000C02821938D000011A0007300B0F82BE1
+:105FA0008F98001C24040034930F00BC31EE0002D3
+:105FB00051C000012404003000A4C82B172000D1D8
+:105FC0000000000000A4282300B0F82B3C010800CA
+:105FD000A4243B1817E00068020020213C030800BD
+:105FE0008C633B080083102B544000010080182173
+:105FF0008F8800203C010800AC233B1000004821A2
+:106000009104000D30830020506000018F490E186C
+:106010008F8300100123382B10E00059000000008E
+:106020003C0408008C843B1000895821006B502BE5
+:10603000114000560090602B0069302300C02021E1
+:106040003C010800AC263B1012000003241FFFFC9B
+:106050001090008A32270003009FC8243C010800EA
+:10606000AC393B103C010800A4203B2E8F84000873
+:10607000120400078F83001CAF910004020020214E
+:106080008C7100CCAF90000826300001AC7000CCC1
+:106090003C0208008C423B108F8A000C2407001839
+:1060A0000082202301422823AF84000810800002D0
+:1060B000AF85000C240700108F8600183C010800F3
+:1060C000A0273B2C2407004090CC0085318B00C0DA
+:1060D000116700408F8D001014A0001500002021D2
+:1060E000934A01098F420974314500FF00022602DC
+:1060F00024A300013090007F3071007F1230007ABD
+:106100002407FF80A0C300833C0908008D293B2899
+:106110008F880020240D0002352C00083C01080067
+:10612000A02D3B6D3C010800AC2C3B282404001042
+:10613000910E000D31C6002010C00005008018210E
+:10614000240800013C010800AC283B103483000106
+:106150008FBF00188FB100148FB0001000601021A5
+:1061600003E0000827BD00203C010800A4203B18E4
+:1061700013E0FF9A020020210A000C1F00A020213A
+:106180003C0408008C843B100090602B1180FFAE13
+:10619000000000003C0F080095EF3B1801E470215F
+:1061A00001C6682B11A000072C8200043C1F600070
+:1061B0008FF954043338003F1700FFE524030042F1
+:1061C0002C8200041040FFA0240300420A000C7D32
+:1061D0008FBF0018152DFFC0000000008CDF007479
+:1061E0003C0380002405FF8003E3C825ACD900747C
+:1061F00090D80085240E000424040010330F003FC3
+:1062000001E54025A0C800858F8800203C010800DA
+:10621000A02E3B6D240300019106000D30C9002023
+:1062200015200003000000003C0308008C633B10B5
+:106230003C010800AC233B080A000C74000000007D
+:106240008F87000C8C88008400E8282B14A00002A3
+:1062500000E088218C91008424090001A3890000BA
+:106260008F440E18022028210E000AD0022030216F
+:10627000022080210A000C05AF82001000071823BD
+:10628000306600033C010800A4263B2E12200005C6
+:106290008F8C001C918B00BC316A000415400015E6
+:1062A00024CD00043C0F080095EF3B2E01E4702143
+:1062B00000AE302B50C0FF6E8F8400082C85000587
+:1062C00014A0FFA32403004230980003170000022B
+:1062D000009818232483FFFC3C010800AC233B10EA
+:1062E0000A000C410000000000A758240A000C69B5
+:1062F000016718263C010800A42D3B2E0A000CD192
+:10630000000000003C010800AC203B100A000C7C9F
+:10631000240300428F83000C14600007000010214A
+:106320008F880020240500059106000030C400FF7E
+:10633000108500030000000003E0000800000000DA
+:10634000910A0018314900FF000939C214E0FFFA30
+:106350008F8500183C04080094843B183C03080017
+:106360008C633B303C1908008F393B103C0F080010
+:1063700095EF3B2E0064C0218CAD005403197021B1
+:1063800001CF6021018D58231960001D000000001D
+:10639000910E001C8F8C0028974B0E1031CD00FF02
+:1063A0008D850004016D30238D88000030CEFFFF05
+:1063B000000E510000AAC821000038210107202149
+:1063C000032A182B0083C021AD990004AD9800006A
+:1063D000918F000A01CF6821A18D000A8F880028C3
+:1063E000974B0E12A50B0008950A003825490001AD
+:1063F000A50900389107000D34E60008A106000D3C
+:1064000003E000080000000027BDFFE093870000C4
+:106410008F8F00208FAD00143C0E7FFF8F89000806
+:1064200035C8FFFFAFBF001CAFB0001801A818248B
+:1064300091EA000D000717C03C1FBFFF00625825FE
+:106440002D2E00018F90001437F9FFFF3C18080033
+:106450008F183B303C0F080095EF3B2601796824EC
+:10646000000E47803C07EFFF3C05F0FF01A8182510
+:106470003149002034E2FFFF34ACFFFF0310582302
+:1064800027A500102406000225EA00020062182455
+:106490000080802115200002000040218F480E1C42
+:1064A000A7AA0012056000372407000030FF00FF94
+:1064B000001FCF008F8B001800793825AFA700147C
+:1064C000916F00853C08080091083B2D3C18DFFFC8
+:1064D00031EE00C0370AFFFF000E182B3C1F0800EA
+:1064E00097FF3B2000EA6824A3A80011000317408F
+:1064F00001A248258FB90010AFA900143C0A08007A
+:10650000914A3B2FA7BF00168FA80014032CC0246C
+:106510003C0B01003C0F0FFF030B18253147000314
+:1065200035EEFFFF010C682400071600006EF8240A
+:106530003C09700001A2C82503E95825AFB9001431
+:10654000AFAB00100E000072A3A000158F8C0020CE
+:10655000260200089186000D30C40020108000063D
+:106560008FBF001C3C05080094A53B1C24B0FFFF16
+:106570003C010800A4303B1C8FB0001803E0000869
+:1065800027BD00208F9800100118502B5540FFC7E1
+:10659000240700010A000D5430FF00FF9382000021
+:1065A00027BDFFE0AFBF00181040000F0080502152
+:1065B0008F880020240B00058F89000491070000BC
+:1065C0008F84001C0100282130E3003F8F860028C3
+:1065D000106B000800003821AFA900100E0004392C
+:1065E000AFAA0014A38000008FBF001803E00008CA
+:1065F00027BD00208D1900183C0F08008DEF3B10BF
+:106600008F98000C3C027FFF8D080014345FFFFF61
+:10661000033F682401F8702101AE6023018838210E
+:10662000AFA900100E000439AFAA00140A000DA291
+:10663000A38000008F8700203C05080094A53B2E16
+:106640003C0208008C423B2890E6000D0005240027
+:1066500030C300201060002C004440258F850018B6
+:1066600000006021240B000190A300850000482158
+:10667000240A00013C0F800035EE00708DC7000039
+:10668000AF8700308F5801780700FFFE3C03800081
+:10669000347900708F3800003C0508008CA5007428
+:1066A0003C0D08008DAD00700307782300AF382142
+:1066B0000000102100EF302B01A2202100861821BC
+:1066C0003C010800AC2700743C010800AC230070BA
+:1066D000AF4B01483C1908008F393B30A7490144B2
+:1066E000A74A0146AF59014C3C0B0800916B3B2D6A
+:1066F000A34B0152AF4801543C081000A74C01586D
+:1067000003E00008AF4801788F4B0E1C3C0A0800DC
+:106710008D4A3B1097490E16974D0E140145602186
+:10672000312AFFFF0A000DC531A9FFFF8F8300202A
+:106730009064000D3082002010400029000000000D
+:106740000000482100005021000040213C0780004B
+:1067500034EB00708D670000AF8700308F4C0178FC
+:106760000580FFFE3C0D800035AC00708D8B000075
+:106770003C0508008CA500743C0408008C84007063
+:106780000167302300A678210000102101E6C82B04
+:106790000082C021031970213C010800AC2F007455
+:1067A0003C010800AC2E0070AF4901483C0D0800C8
+:1067B0008DAD3B30A748014424090040A74A01465B
+:1067C0003C081000240AFF91AF4D014CA34A01522E
+:1067D000AF490154A740015803E00008AF480178D1
+:1067E0008F490E1897460E1297450E1030CAFFFFBC
+:1067F0000A000DFB30A8FFFF8F83002027BDFFF8A4
+:106800009064000D308200201040003A000000002B
+:10681000240B000100004821240A00013C088000EC
+:10682000350700708CE30000AF8300308F4C017897
+:106830000580FFFE3C0E80003C04080090843B6C09
+:1068400035C700708CEC00003C0508008CA5007476
+:10685000A3A400033C1908008F3900708FAD00001D
+:106860000183302300A63821000010210322782163
+:1068700000E6C02B01F8602101AE4025AFA8000062
+:106880003C010800AC2700743C010800AC2C0070EF
+:106890009346010A3C04080090843B6DA3A00002CB
+:1068A000A3A600018FA300003C0580FF3099007F64
+:1068B00034A2FFFF006278240019C60001F8702599
+:1068C000240D3000AF4E014C27BD0008AF4D0154E0
+:1068D000A7400158AF4B0148A7490144A74A0146C8
+:1068E0003C091000240AFF80A34A015203E000087B
+:1068F000AF4901788F4B0E1897460E1297450E1030
+:1069000030CAFFFF0A000E2F30A9FFFF8F85001845
+:106910002402008090A40085308300C0106200052E
+:106920008F86001C8F8800048F870008ACC800C8C1
+:10693000ACC700C403E00008000000003C0A0800E7
+:10694000254A37CC3C090800252938983C0808001E
+:1069500025082C4C3C07080024E739AC3C0608000D
+:1069600024C6363C3C05080024A533B43C0408008A
+:1069700024842FDC3C030800246336D43C02080046
+:10698000244234A83C010800AC2A3C383C010800F1
+:10699000AC293C343C010800AC283C303C010800E8
+:1069A000AC273C3C3C010800AC263C4C3C010800B8
+:1069B000AC253C443C010800AC243C403C010800B0
+:1069C000AC233C503C010800AC223C4803E00008EA
+:0469D00000000000C3
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/firmware/bnx2/bnx2-mips-09-4.6.17.fw.ihex b/firmware/bnx2/bnx2-mips-09-4.6.17.fw.ihex
new file mode 100644
index 00000000000..7667c663e50
--- /dev/null
+++ b/firmware/bnx2/bnx2-mips-09-4.6.17.fw.ihex
@@ -0,0 +1,5816 @@
+:10000000080000F80800000000004AC8000000C80E
+:1000100000000000000000000000000008004AC8C6
+:100020000000003000004B90080000800800000035
+:10003000000053A800004BC0080055400000008499
+:1000400000009F68080053A80000016C00009FECAE
+:10005000080031D808000000000079080000A1580D
+:100060000000000000000000000000000800790807
+:100070000000012400011A60080004880800040040
+:10008000000013A400011B84000000000000000019
+:1000900000000000080017A40000000400012F2841
+:1000A000080000980800000000003AFC00012F2C16
+:1000B00000000000000000000000000008003AFC02
+:0800C0000000003000016A2875
+:0800C8000A00003E00000000E8
+:1000D000000000000000000D636F6D342E362E31DD
+:1000E00036000000040610020000000000000003BB
+:1000F00000000014000000320000000300000000B7
+:1001000000000000000000000000000000000000EF
+:1001100000000010000001360000EA60000000014D
+:1001200000000000000000000000000000000008C7
+:1001300000000000000000000000000000000000BF
+:1001400000000000000000000000000000000000AF
+:10015000000000000000000000000000000000009F
+:10016000000000020000000000000000000000008D
+:10017000000000000000000000000000000000007F
+:10018000000000000000000000000010000000005F
+:10019000000000000000000000000000000000005F
+:1001A000000000000000000000000000000000004F
+:1001B000000000000000000000000000000000003F
+:1001C0000000000010000003000000000000000D0F
+:1001D0000000000D3C02080024424B203C030800B4
+:1001E00024634C18AC4000000043202B1480FFFD1A
+:1001F000244200043C1D080037BD9FFC03A0F021F1
+:100200003C100800261000F83C1C0800279C4B20DE
+:100210000E000273000000000000000D27BDFFE883
+:100220003C028000AFB00010AFBF0014345001009A
+:10023000920200091040001A240300013C02080049
+:100240008C42002010400016000018210E000D7195
+:1002500000000000960300083C06080094C64BFE10
+:100260008E0400188F82002C9605000C00031C00E1
+:1002700000661825AC440000AC45000424040001CD
+:10028000AC400008AC40000CAC400010AC40001486
+:10029000AC4000180E000D98AC43001C0000182163
+:1002A0008FBF00148FB000100060102103E0000821
+:1002B00027BD001827BDFFE8AFBF00103C0280003B
+:1002C0009442010830437000240220001062000AAA
+:1002D00028642001548000128FBF001024024000C7
+:1002E00010620008240260001062000A8FBF001034
+:1002F0000A000097000010218FBF00100A0000556F
+:1003000027BD00180E000433000000000A0000960C
+:100310008FBF00100E000C81000000008FBF001086
+:100320000000102103E0000827BD00183C0208006F
+:100330008C42002027BDFFE810400028AFBF00100E
+:100340000E000D71000000003C05800094A2010821
+:1003500094A3010C8F86002C3042003E3063FFFFD7
+:100360000002140000431025ACC200008CA2010062
+:100370003C07080094E74BFE8FBF0010ACC200049E
+:1003800094A3011694A4010E3C02200000031C005B
+:100390003084FFFF00641825ACC3000800E2382554
+:1003A00094A2011094A3011224040001000214007D
+:1003B0003063FFFF00431025ACC2000C94A201146F
+:1003C00027BD00183042FFFFACC20010ACC00014C3
+:1003D000ACC000180A000D98ACC7001C8FBF0010FD
+:1003E00003E0000827BD00183C0680008CC202B85C
+:1003F0002403000104410008008028213C02080079
+:100400008C420060244200013C010800AC220060E4
+:1004100003E00008006010218C8300209482001605
+:10042000ACC302802442FFFCA4C202843C02080048
+:100430008C42005C8C84000494A3000E24420001D2
+:100440003C010800AC22005C3C021000A4C3028600
+:10045000ACC4028800001821ACC202B803E0000856
+:10046000006010213C0208008C42002027BDFFE8FC
+:100470001040002BAFBF00100E000D7100000000F7
+:100480003C05800094A2010894A3010C8F86002CE7
+:100490003042003E3063FFFF00021400004310258D
+:1004A000ACC200008CA201003C07080094E74BFEA0
+:1004B0008FBF0010ACC2000494A3011694A4010ED7
+:1004C0003C02200000031C003084FFFF006418255C
+:1004D000ACC3000800E2382594A2011094A30112D5
+:1004E00024040001000214003063FFFF00431025C4
+:1004F000ACC2000C94A2011427BD00183042FFFFCB
+:10050000ACC200108CA20118ACC2001490A2010B66
+:10051000304200FFACC200180A000D98ACC7001CA6
+:100520008FBF001003E0000827BD001827BDFFE0C3
+:10053000AFB000103C108000AFB20018AFBF001C7D
+:10054000AFB10014361201009243000B2402001ACE
+:10055000965100081462005B00002821322200013D
+:1005600010400018000000008E42000000022340EE
+:100570003C02003F3442FFFF0044102B10400004B7
+:100580003C030040964200140A00013B00832021F6
+:100590008E030100240201005462000696420014FA
+:1005A0003C028008944200043042000F0002250003
+:1005B0009642001400821025AE0200800A00016FEE
+:1005C000000000003C0208008C420020104000287F
+:1005D000000000000E000D710000000096020108EE
+:1005E0009603010C8F85002C3042003E3063FFFFE4
+:1005F0000002140000431025ACA200008E0201008E
+:100600003C06080094C64BFEACA2000496030116FB
+:100610009604010E3C02200000031C003084FFFF02
+:1006200000641825ACA3000800C230259602011012
+:100630009603011224040001000214003063FFFF3E
+:1006400000431025ACA2000C960201143042FFFFBB
+:10065000ACA200108E020118ACA200149202010B91
+:10066000304200FFACA200180E000D98ACA6001C92
+:100670003C0208008C420040244200013C0108007A
+:10068000AC2200403C0308008C630044322200028C
+:1006900032240004246300013C010800AC23004420
+:1006A000108000080002282B024020218FBF001C70
+:1006B0008FB200188FB100148FB000100A0000C86C
+:1006C00027BD00208FBF001C8FB200188FB100140F
+:1006D0008FB0001000A0102103E0000827BD00200B
+:1006E00027BDFFE03C058000AFB10014AFBF00188C
+:1006F000AFB0001034B101009223000B24020003BC
+:1007000014620043963000083202000110400016C7
+:100710003C02003F8E2300003442FFFF00032340D1
+:100720000044102B504000052402010096220014C2
+:100730003C0300400A0001A400832021546200060B
+:10074000962200143C028008944200043042000FBC
+:10075000000225009622001400821025ACA2008021
+:100760000A0001AF000000000E0000990000000028
+:100770003C0208008C420040244200013C01080079
+:10078000AC2200403C0208008C42004432030004CA
+:10079000244200013C010800AC2200441060000724
+:1007A00032020002022020218FBF00188FB10014F6
+:1007B0008FB000100A0000C827BD002010400015AF
+:1007C0008FBF00183C0480008C8301043C02602031
+:1007D000AC4300148C420004240301FE304203FFAA
+:1007E0001443000C8FBF00188C820100000219C254
+:1007F0002462FFFC2C420008104000032404000285
+:100800002462FFFD004420043C026000AC446914F3
+:100810008FBF00188FB100148FB00010000010219E
+:1008200003E0000827BD00203C0480008C83010009
+:1008300024020100506200033C0280080000000D09
+:100840003C02800894430004000010213063000F34
+:1008500000031D0003E00008AC8300803C02800818
+:10086000344200809042000003E00008AF800000A6
+:1008700003E000080000102127BDFFE83C028000D3
+:10088000AFBF0014AFB000108C430100AC43002098
+:100890008C430104AC4300A89050010B0E0001E50D
+:1008A000321000FF3C02080024424B580010188010
+:1008B0002E10001D16000005006210210E0001EA36
+:1008C000004018210A000205000000008C420000D0
+:1008D0000040F80900000000004018213C02080018
+:1008E0008C42003410600005244400013C0280006A
+:1008F0008C4301043C026020AC4300148FBF001401
+:100900008FB000103C0340003C02800027BD00185F
+:10091000AC4301383C010800AC24003403E000087B
+:100920000000000027BDFFE8AFBF0014AFB000100B
+:100930003C1080008E0201400E0001E5AE02002056
+:100940000E000399000000003C04080024840038D5
+:100950008C8200003C034000AE0301788FBF00147E
+:100960008FB000102442000127BD001803E00008EA
+:10097000AC82000027BDFFE8AFB00010AFBF00148D
+:100980003C1080008E0201800E0001E5AE020020C6
+:100990008E03018024020F00546200083C0280088C
+:1009A0008E0201883C0300E03042FFFF0043102527
+:1009B000AE0200800A00024A3C02800034420080FD
+:1009C0009042000024030050304200FF144300080E
+:1009D0003C0280000E000379000000001440000477
+:1009E0003C0280000E000967000000003C0280000D
+:1009F0003C034000AC4301B83C0208008C42003C80
+:100A00008FBF00148FB00010244200013C01080089
+:100A1000AC22003C03E0000827BD001803E00008FA
+:100A2000000010213C05800034A4010094820008DD
+:100A30003043000230420004104000030000000078
+:100A40000A0000C800000000106000052404000136
+:100A50003C0208008C4200840A00026F244200011C
+:100A60008CA301048F82000C104300080000202199
+:100A70008CA301043C0208008C420084AF83000C6C
+:100A8000244200013C010800AC22008403E000087D
+:100A90000080102127BDFFE83C036010AFBF0014A9
+:100AA000AFB000108C6550002402FF7F3C04800032
+:100AB00000A2282434A5380C24020037AC6550006D
+:100AC000AC82000824020C80AC8200243C060800A2
+:100AD00024C607A83C02080024424B582405001CE9
+:100AE00024A5FFFFAC46000004A1FFFD2442000442
+:100AF0003C020800244201EC3C010800AC224B609F
+:100B00003C020800244206183C010800AC224B6459
+:100B10003C02080024420D103C010800AC224BA00E
+:100B20003C020800244204643C0308002463095486
+:100B30003C0408002484095C3C05080024A52C948E
+:100B40003C010800AC224BC03C0208002442076074
+:100B50003C010800AC264BA83C010800AC254BB476
+:100B60003C010800AC234BBC3C010800AC244BC446
+:100B70003C010800AC224BC83C010800AC234B5C94
+:100B80003C010800AC204B683C010800AC204B6CD9
+:100B90003C010800AC204B703C010800AC204B74B9
+:100BA0003C010800AC204B783C010800AC204B7C99
+:100BB0003C010800AC204B803C010800AC244B8475
+:100BC0003C010800AC204B883C010800AC204B8C59
+:100BD0003C010800AC204B903C010800AC204B9439
+:100BE0003C010800AC204B983C010800AC264B9C13
+:100BF0003C010800AC264BA43C010800AC204BACE7
+:100C00003C010800AC254BB03C010800AC234BB8BC
+:100C10000E00055A000000003C02800034420070C3
+:100C20008C420000AF8200103C0308008C6300205F
+:100C30008F820004104300043C0580000E000D3735
+:100C4000AF8300043C05800034A900708D280000AB
+:100C50008F8400103C0708008CE700BC3C060800AD
+:100C60008CC600B8010420230000102100E43821C4
+:100C700000C2302100E4202B00C430213C010800D8
+:100C8000AC2700BC3C010800AC2600B88CB00000CA
+:100C9000320200071040FFE4AF8800108D260000EC
+:100CA0003C0508008CA500BC3C0408008C8400B8FE
+:100CB00000C8302300A628210000102100A6302BF8
+:100CC0000082202100862021320700013C0108001B
+:100CD000AC2500BC3C010800AC2400B810E00004C6
+:100CE000320200020E0001EC00000000320200029D
+:100CF00010400004320200040E0002170000000041
+:100D0000320200045040FFC53C0280000E00022B5E
+:100D1000000000000A0002D53C0280003C02900066
+:100D200034420001008220253C028000AC440020B7
+:100D30003C0380008C6200200440FFFE00000000A5
+:100D400003E00008000000003C0280003443000182
+:100D50000083202503E00008AC44002027BDFFE00D
+:100D6000AFB10014AFB0001000808821AFBF0018F1
+:100D70000E00031530B000FF8F83FFAC022020214E
+:100D80009062002502028025A07000258C7000185A
+:100D90003C0280000E000320020280241600000A9C
+:100DA0008FBF00183C0380008C6201F80440FFFEF6
+:100DB00024020002AC7101C0A06201C43C02100018
+:100DC000AC6201F88FBF00188FB100148FB0001013
+:100DD00003E0000827BD002027BDFFB8AFBF0044D7
+:100DE000AFB000403C0780008CE601048F82FFA872
+:100DF000AFA600288C450020AFA5002C8C44003CF9
+:100E0000AFA400308C430040AFA300348C42004CB0
+:100E1000AFA60010AFA50014AFA20020AFA200380B
+:100E20003C0208008C420020AFA40018AFA3001CB5
+:100E30008CF00100104000198FBF00440E000D71AE
+:100E4000000000008F83002C3C05080094A54BFE99
+:100E50003C024018AC70000000A228258FA20010B0
+:100E600024040001AC6200048FA20014AC620008EC
+:100E70008FA20018AC62000C8FA2001CAC620010A4
+:100E80008FA20020AC6200148FA20024AC62001874
+:100E90000E000D98AC65001C8FBF00448FB0004061
+:100EA0000000102103E0000827BD004827BDFFE82F
+:100EB000AFBF00103C038000946201843042020006
+:100EC00010400005000020210E000FE3000000008C
+:100ED0000A00038F240400018C6201880440000A88
+:100EE0008FBF00108C6201883C03FF000043102478
+:100EF0003C03040014430004240400018F82FFAC6F
+:100F0000904200088FBF00100080102103E000080D
+:100F100027BD00188F82FFB024050001A040001AF1
+:100F20003C0280000A0003258C44014027BDFFE0FD
+:100F3000AFB100148F91FFACAFBF001CAFB200186F
+:100F4000AFB000109222000024030020304200FFC6
+:100F50001043000C3C028000922200002403003069
+:100F6000304200FF104300073C0280009222000044
+:100F700024030050304200FF144300818FBF001C47
+:100F80003C02800090420148304200FF2443FFFFB2
+:100F90002C6200051040007A8FBF001C00031080F7
+:100FA0003C03080024634AD8004310218C4200000F
+:100FB00000400008000000003C1180008E24014029
+:100FC0000E0003158F92FFAC8E50000C8E22014450
+:100FD0001602000224020001AE42000C0E000320A3
+:100FE0008E2401408E220144145000068FBF001C45
+:100FF0008FB200188FB100148FB000100A000F518B
+:1010000027BD00208E42000C0A00042700000000CB
+:10101000962200103C0480008C8301443042FFFF84
+:10102000146200090000000024020001A622001042
+:101030008C820140AC8202003C021000AC8202387B
+:101040000A00042E8FBF001C962200100A000427FD
+:10105000000000009222000024030020304200FF24
+:101060001443000B3C128000962200123C038000C7
+:101070008C6301443042FFFF14620018000000003E
+:1010800024020001A62200120A0004008FBF001CE7
+:101090008E4401400E00031500000000962200124D
+:1010A0008E4301443050FFFF16030002240200016A
+:1010B000A62200120E0003208E4401408E420144FD
+:1010C000160200068FBF001C8FB200188FB10014EB
+:1010D0008FB000100A00039327BD00209622001253
+:1010E0000A00042700000000962200143C03800040
+:1010F0008C6301443042FFFF1462000900000000CD
+:1011000024020001A62200148FBF001C8FB2001819
+:101110008FB100148FB000100A00126827BD0020A4
+:10112000962200140A0004270000000096220016F0
+:101130003C0380008C6301443042FFFF14620008CE
+:1011400024020001A62200168FBF001C8FB20018D7
+:101150008FB100148FB000100A000B0B27BD0020C8
+:1011600096220016144000068FBF001C3C020800A7
+:101170008C420070244200013C010800AC22007047
+:101180008FB200188FB100148FB0001003E0000878
+:1011900027BD002027BDFFE03C028000AFB1001456
+:1011A000AFBF001CAFB20018AFB000103451010047
+:1011B000922300098C5001002402001F106200AA33
+:1011C0002862002010400018240200382862000A1B
+:1011D0001040000C2402000B286200081040002C74
+:1011E0000000000004600100286200021440002892
+:1011F00024020006106200268FBF001C0A00054A68
+:101200008FB20018106200602862000B144000F7D3
+:101210008FBF001C2402000E106200778FB20018EE
+:101220000A00054A00000000106200D3286200395D
+:101230001040000A2402008024020036106200E3FD
+:1012400028620037104000C524020035106200D823
+:101250008FBF001C0A00054A8FB200181062002DD3
+:101260002862008110400006240200C824020039D0
+:10127000106200C98FBF001C0A00054A8FB2001817
+:10128000106200A28FBF001C0A00054A8FB200182E
+:101290003C0208008C420020104000D48FBF001C8C
+:1012A0000E000D71000000003C028000344201007D
+:1012B0008C4400008F83002C944700083C050800F4
+:1012C00094A54BFEAC6400008C44000400073C0075
+:1012D00000E53825AC6400048C4400189446000CEA
+:1012E000AC6400088C45001C000634002404000196
+:1012F000AC65000C9042000A00C23025AC660010BC
+:10130000AC600014AC600018AC67001C0A00050C4F
+:101310008FBF001C3C0208008C420020104000B32C
+:101320008FBF001C0E000D71000000009624000805
+:101330003C03080094634BFE9625000C0004220237
+:101340009626000E8F82002C0004260000832025A4
+:1013500000052C003C03008000A6282500832025E2
+:10136000AC400000AC400004AC400008AC40000CB5
+:10137000AC450010AC400014AC400018AC44001C5C
+:101380000A00050B240400019622000C14400017EB
+:101390008F91FFAC922200053042001014400013E0
+:1013A000000000000E00031502002021922200051B
+:1013B00002002021344200100E000320A22200056A
+:1013C0009222000024030020304200FF10430086D8
+:1013D000020020218FBF001C8FB200188FB10014B3
+:1013E0008FB000100A00104C27BD00200000000D37
+:1013F0000A0005498FBF001C3C0208008C420020F7
+:101400001040007A8FBF001C0E000D71000000001C
+:101410008E2200048F83002C9624000C3C050800CB
+:1014200094A54BFEAC6200003C0280089442002C64
+:10143000000424003042FFFF008220253C02400EC1
+:1014400000A22825AC640004AC600008AC60000C6D
+:10145000AC600010AC600014AC600018AC65001CFF
+:101460000A00050B240400010E00031502002021D0
+:101470008F92FFB0020020210E000320A640000C36
+:10148000020020210E000325240500013C02080073
+:101490008C420020104000558FBF001C0E000D71C3
+:1014A000000000009622000C8F83002C8F84FFAC7C
+:1014B00000021400AC700000AC620004AC600008D4
+:1014C0008C8200383C05080094A54BFEAC62000CF1
+:1014D0008C86003C3C02401F00A22825AC66001010
+:1014E0008E42000424040001AC620014AC600018B9
+:1014F000AC65001C8FBF001C8FB200188FB10014A8
+:101500008FB000100A000D9827BD00208F82FFAC1D
+:101510002403002090420000304200FF10430033BB
+:101520008FBF001C0E000F37000000001040002F7E
+:101530008FBF001C3C0380008C6201F80440FFFE5A
+:1015400024020002AC7001C0A06201C43C02100081
+:10155000AC6201F80A0005498FBF001C020020217F
+:101560008FBF001C8FB200188FB100148FB0001015
+:101570000A000E8027BD00209625000C02002021C5
+:101580008FBF001C8FB200188FB100148FB00010F5
+:101590000A000EA527BD0020020020218FB20018EE
+:1015A0008FB100148FB000100A000ED027BD0020AC
+:1015B0009225000D020020218FB200188FB1001477
+:1015C0008FB000100A000F2127BD0020020020214B
+:1015D0008FBF001C8FB200188FB100148FB00010A5
+:1015E0000A000EF827BD00208FBF001C8FB2001824
+:1015F0008FB100148FB0001003E0000827BD002059
+:101600003C0380008C6202780440FFFE240200024A
+:10161000AC640240A06202443C02100003E00008F7
+:10162000AC620278000411C003E0000824420240CA
+:10163000A380001803E00008A38000193C03800089
+:101640008C6202780440FFFE8F82001CAC62024074
+:1016500024020002A06202443C02100003E00008E1
+:10166000AC62027803E000080000000090830030C4
+:1016700024020005008040213063003F0000482123
+:1016800014620005000050219082004C9483004EAB
+:10169000304900FF306AFFFFAD00000CAD000010C4
+:1016A000AD000024950200148D05001C8D04001867
+:1016B0003042FFFF0049102300021100000237C32F
+:1016C000004038210086202300A2102B0082202316
+:1016D00000A72823AD05001CAD040018A5090014BF
+:1016E000A5090020A50A001603E00008A50A0022AB
+:1016F00003E000080000000027BDFFD8AFB20018CB
+:101700003C128008AFB40020AFB3001CAFB100148E
+:10171000AFBF0024AFB00010365101009222000C80
+:101720003C140800929400F7304300FF24020001AB
+:1017300010620031008098212402000214620034FB
+:10174000365000800E001242000000009204004C4F
+:101750000E0005573084007F026210212403FF80B1
+:10176000004318243C048000AC8300949245000898
+:101770009204004C3042007F3C0380061485000731
+:10178000004380212402FFFFA22200112402FFFF58
+:10179000A62200120A0005BA2402FFFF96020020CA
+:1017A000A222001196020022A62200128E0200241C
+:1017B0003C048008AE2200143485008090A2004CC6
+:1017C00034830100A06200108CA2003CAC620018BF
+:1017D0008C820068AC6200E48C820064AC6200E041
+:1017E0008C82006CAC6200E824020001A0A20068B8
+:1017F0000A0005D63C0480080E00125B00000000C1
+:1018000036420080A04000680A0005D63C048008EB
+:10181000A2000068A20000690A0006123C028008CB
+:10182000348300808C62003834850100AC62006C27
+:1018300024020001A062006990A200C59083000804
+:10184000305100FF3072007F1232001B3C088008CC
+:101850000E00055702202021026210212403FF8080
+:10186000004318243C048000AC8300943042007F85
+:101870003C038006004380218E02000C1040000DC6
+:10188000020020210E000569000000002622000150
+:10189000305100FF9203003C023410260002102B4E
+:1018A000000210233063007F022288240A0005E032
+:1018B000A203003C3C088008350401008C8200D063
+:1018C00035070080ACE2003C8C8200D0AD02000005
+:1018D00090E5004C908600C590E3004C908400C5D4
+:1018E0002402FF8000A228243063007F308400FFA0
+:1018F00000A628250064182A1060000230A500FF09
+:1019000038A50080A0E5004CA10500093C02800834
+:101910009043000E344400803C058000A043000A40
+:101920008C8300183C027FFF3442FFFF00621824C2
+:10193000AC8300188CA201F80440FFFE00000000F8
+:10194000ACB301C08FBF00248FB400208FB3001C44
+:101950008FB200188FB100148FB000102402000263
+:10196000A0A201C427BD00283C02100003E000082B
+:10197000ACA201F890A2000027BDFFE0AFB20018B2
+:1019800024420001A0A200003C0308008C6300F484
+:10199000304200FFAFB10014AFBF001CAFB0001069
+:1019A00000A088211443000200809021A0A0000024
+:1019B0000E000557922400008F90001C2403FF8026
+:1019C00002021021004310243C038000AC6200247A
+:1019D0000E00055792240000020280213210007F81
+:1019E0003C02800A02028021AE5000008FBF001C22
+:1019F0008FB200188FB100148FB0001003E0000800
+:101A000027BD002094820006908300058C85000C81
+:101A10008C8600108C8700188C88001C8C84002019
+:101A20003C010800A4224BD23C010800A0234BD16A
+:101A30003C010800AC254BD83C010800AC264BDC2F
+:101A40003C010800AC274BE43C010800AC284BE803
+:101A50003C010800AC244BEC03E00008000000004F
+:101A60003C028008344201008C4400343C03800076
+:101A700034650400AC6400388C420038AF85003017
+:101A8000AC62003C3C020005AC620030000000008B
+:101A90000000000003E00008000000003C02000617
+:101AA000308400FF008220253C028000AC440030DE
+:101AB0000000000000000000000000003C03800067
+:101AC0008C620000304200101040FFFD34620400C0
+:101AD00003E00008AF82003094C200003C08080018
+:101AE000950800CA30E7FFFF00804821010210215D
+:101AF000A4C2000094C200003042FFFF00E2102B9D
+:101B000054400001A4C7000094A200003C03080058
+:101B10008C6300CC24420001A4A2000094A2000027
+:101B20003042FFFF144300073C0280080107102BDE
+:101B3000A4A000005440000101003821A4C7000007
+:101B40003C028008344601008CC3002894A20000A7
+:101B50003C0480003042FFFE000210C000621021F1
+:101B6000AC82003C8C82003C0062182318600004A8
+:101B7000000000008CC200240A0006AF24420001CD
+:101B80008CC20024AC8200383C0200503442001069
+:101B90003C038000AC620030000000000000000048
+:101BA000000000008C620000304200201040FFFD69
+:101BB0000000000094A200003C04800030420001BC
+:101BC000000210C0004410218C430400AD2300002B
+:101BD0008C420404AD2200043C02002003E0000813
+:101BE000AC82003027BDFFE0AFB20018AFB10014E7
+:101BF000AFB00010AFBF001C94C2000000C0802135
+:101C00003C120800965200C624420001A6020000C1
+:101C10009603000094E2000000E030211443000528
+:101C20008FB100300E000684024038210A0006E61B
+:101C3000000000008C8300048C82000424420040D9
+:101C400004610007AC8200048C820004044000049C
+:101C5000000000008C82000024420001AC820000E1
+:101C6000960200003042FFFF50520001A600000023
+:101C70009622000024420001A62200003C028008B7
+:101C800034420100962300009442003C14430004B7
+:101C90008FBF001C24020001A62200008FBF001C81
+:101CA0008FB200188FB100148FB0001003E000084D
+:101CB00027BD002027BDFFE03C028008AFBF001811
+:101CC000344201008C4800343C0380003469040035
+:101CD000AC6800388C42003830E700FFAF89003034
+:101CE000AC62003C3C020005AC6200300000000029
+:101CF00000000000000000000000000000000000E4
+:101D0000000000008C82000C8C82000C978300166F
+:101D1000AD2200008C82001000604021AD22000442
+:101D20008C820018AD2200088C82001CAD22000CB1
+:101D30008CA20014AD2200108C820020AD22001471
+:101D400090820005304200FF00021200AD22001810
+:101D50008CA20018AD22001C8CA2000CAD22002029
+:101D60008CA20010AD2200248CA2001CAD22002801
+:101D70008CA20020AD22002C3402FFFFAD260030E3
+:101D8000AD200034506200013408FFFFAD28003858
+:101D900050E000113C0280083C04800834840100BB
+:101DA000948200503042FFFFAD22003C94830044F7
+:101DB00094850044240200013063FFFF000318C231
+:101DC000006418219064005430A5000700A210049C
+:101DD0000A0007510044102534420100AD20003CA8
+:101DE00094430044944400443063FFFF000318C24E
+:101DF000006218213084000790650054240200011D
+:101E0000008210040002102700451024A062005434
+:101E10000000000000000000000000003C0200067E
+:101E2000344200403C038000AC62003000000000FF
+:101E300000000000000000008C6200003042001032
+:101E40001040FFFD3C06800834C20150346304009A
+:101E500034C7014A34C4013434C5014034C6014496
+:101E6000AFA200100E0006C7AF8300308FBF00186E
+:101E700003E0000827BD00208F8300143C05080004
+:101E80008CA500E88F82001C30633FFF000319809F
+:101E900000451021004310212403FF800043182433
+:101EA0003C058000ACA300283042007F3C03800C3E
+:101EB0000043302190C2000D000038213442001050
+:101EC000A0C2000D8F8900143C028008344201003A
+:101ED00094430044000913823048000324020001A7
+:101EE000A4C3000E1102000B2902000210400005DD
+:101EF000240200021100000C240300010A000798CC
+:101F00000000182111020006000000000A000798D6
+:101F1000000018218CC2002C0A00079824430001FD
+:101F20008CC20014244300018CC200180043102B03
+:101F3000144000033C0380080A0007A224070001A4
+:101F4000346301009462004C24420001A462004CFE
+:101F500000091382304300032C6200021040000984
+:101F600000802821146000040000000094C20034A6
+:101F70000A0007B23046FFFF8CC600380A0007B2DD
+:101F800000802821000030213C04080024844BCC30
+:101F90000A0006FB0000000027BDFF90AFB60068F6
+:101FA000AFB50064AFB40060AFB3005CAFB200582F
+:101FB000AFB10054AFBF006CAFB000508C900000C8
+:101FC0000080B0213C0208008C4200E896040032F8
+:101FD0008F83001C2414FF8030843FFF006218218F
+:101FE0000004218000641821007410243C13800038
+:101FF00000A0902190A50000AE620028920400325B
+:102000003C02800C3063007F00628821308400C075
+:10201000240200401482002D0000A8218E350038D3
+:102020008E2200181440000224020001AE22001883
+:102030009202003C304200201440000F00000000DB
+:102040000E00055700A020218F83001C006218217C
+:10205000306400783C02008000822025007418243F
+:10206000AE630800AE6408108E2200188E030008CC
+:1020700000431021AE2200188E22002C8E2300185F
+:10208000244200010062182B1060003D0000000097
+:102090009242000024420001A24200003C030800DA
+:1020A0008C6300F4304200FF50430001A240000066
+:1020B0000E000557924400008F90001C0202102170
+:1020C000005410240A0008B8AE62002492030032C3
+:1020D0002402FFC000431024304200FF14400005DA
+:1020E00024020001AE220018962200340A00082EB5
+:1020F0003055FFFF8E22001424420001AE2200184A
+:102100009202003000021600000216030441001C77
+:10211000000000009602003227A400100080282151
+:10212000A7A2001696020032000030212407000109
+:102130003042FFFFAF8200140E0006FBAFA0001C70
+:10214000960200328F83001C3C0408008C8400E857
+:1021500030423FFF00021180006418210062182104
+:1021600000741024AE62002C3063007F3C02800EAD
+:10217000006218219062000D3042007FA062000DC5
+:102180009222000D30420010504000789242000030
+:102190003C028008344401009482004C8EC300004D
+:1021A0003C130800967300C62442FFFFA482004C33
+:1021B000946200329623000E3054FFFF3070FFFF10
+:1021C0003C0308008C6300D000701807A7A30038F8
+:1021D0009482003E3063FFFF3042FFFF146200072D
+:1021E000000000008C8200303C038000244200305C
+:1021F000AC62003C0A0008568C82002C948200409D
+:102200003042FFFF5462000927A400408C8200384E
+:102210003C03800024420030AC62003C8C820034DD
+:10222000AC6200380A0008653C03800027A500382E
+:1022300027A60048026038210E000684A7A00048A7
+:102240008FA300403C02800024630030AC43003880
+:102250008FA30044AC43003C3C0380003C020005DB
+:10226000AC6200303C028008344401009482004299
+:10227000346304003042FFFF0202102B14400007B9
+:10228000AF8300309482004E9483004202021021FA
+:10229000004310230A00087B3043FFFF9483004E65
+:1022A0009482004202631821005010230062182318
+:1022B0003063FFFF3C028008344401009482003CFC
+:1022C0003042FFFF14430003000000000A00088BA7
+:1022D000240300019482003C3042FFFF0062102B77
+:1022E000144000058F8200309482003C006210236D
+:1022F0003043FFFF8F820030AC550000AC4000043B
+:10230000AC540008AC43000C3C0200063442001000
+:102310003C038000AC6200300000000000000000C0
+:10232000000000008C620000304200101040FFFDF1
+:102330003C04800834840100001018C20064182195
+:102340009065005432020007240600010046100484
+:1023500000451025A0620054948300429622000E8E
+:1023600050430001A386001892420000244200015D
+:10237000A24200003C0308008C6300F4304200FFDE
+:1023800050430001A24000000E0005579244000097
+:102390008F90001C2403FF800202102100431024B0
+:1023A0003C038000AC6200240E00055792440000FC
+:1023B000020280213210007F3C02800A020280214A
+:1023C000AED000008FBF006C8FB600688FB5006480
+:1023D0008FB400608FB3005C8FB200588FB100548F
+:1023E0008FB0005003E0000827BD007027BDFFD864
+:1023F000AFB3001CAFB20018AFB10014AFB0001003
+:10240000AFBF00200080982100E0802130B1FFFFA5
+:102410000E000D7130D200FF00000000000000002F
+:10242000000000008F82002CAC510000AC52000470
+:10243000AC530008AC40000CAC400010AC400014A1
+:10244000AC4000183C03080094634BFE0203802557
+:10245000AC50001C00000000000000000000000064
+:10246000240400018FBF00208FB3001C8FB200181E
+:102470008FB100148FB000100A000D9827BD0028FE
+:1024800030A5FFFF30C600FF24030C803C02800013
+:10249000AC43002400000000000000000000000029
+:1024A00000000000000000000A0008C90000000051
+:1024B0003C028008344301009462000E3C0808008E
+:1024C000950800C63046FFFF14C000043402FFFF29
+:1024D000946500DA0A00091F8F84001C10C20027CF
+:1024E000000000009462004E9464003C3045FFFF01
+:1024F00000A6102300A6182B3087FFFF10600004F1
+:102500003044FFFF00C5102300E210233044FFFFDA
+:102510000088102B1040000E00E810233C028008B9
+:10252000344401002403000134420080A443001617
+:102530002402FFFFA482000E948500DA8F84001C21
+:102540000000302130A5FFFF0A0008EE3C076020A4
+:102550000044102A104000093C02800834430080E7
+:102560009462001630420001104000043C028000DA
+:102570009442007E24420014A462001603E0000886
+:102580000000000027BDFFE03C028008AFBF001C38
+:10259000AFB0001834420100944300429442004C12
+:1025A000104000193068FFFF9383001824020001D7
+:1025B000146200298FBF001C3C06800834D0010043
+:1025C000000810C20050102190420054310300074F
+:1025D00034C70148304200FF00621007304200015A
+:1025E00034C9014E34C4012C34C5013E10400016DC
+:1025F00034C601420E0006C7AFA900109602004281
+:102600000A00093C3048FFFF3C02800834440100C6
+:1026100094830044948200421043000F8FBF001C3B
+:1026200094820044A482004294820050A482004E0E
+:102630008C820038AC82003094820040A482003E3C
+:102640009482004AA48200488FBF001C8FB00018FB
+:102650000A0008FA27BD00208FB0001803E0000828
+:1026600027BD002027BDFFA0AFB1004C3C1180006A
+:10267000AFBF0058AFB30054AFB20050AFB0004886
+:102680003626018890C200033044007FA3A40010C6
+:102690008E32018090C200003043007F240200038C
+:1026A0001062003BAF92001C28620004104000063C
+:1026B0002402000424020002106200098FBF0058A7
+:1026C0000A000B038FB300541062004B2402000574
+:1026D0001062014C8FBF00580A000B038FB30054E7
+:1026E000000411C0024210212404FF802442024051
+:1026F0000044102426430040AE2200243063007FB3
+:102700003C02800A006218219062003CAFA3003CAA
+:1027100000441025A062003C8FA3003C9062003C66
+:10272000304200401040016A8FBF00583C108008C2
+:10273000A3800018361001008E0200D08C63003494
+:1027400027A4003C27A50010004310210E0007B469
+:10275000AE0200D093A200103C038000A20200C58C
+:102760008C6202780440FFFE8F82001CAC62024043
+:1027700024020002A06202443C021000AC62027813
+:102780000E00092F000000000A000B028FBF005846
+:102790003C05800890C3000190A2000B1443014C3B
+:1027A0008FBF005834A400808C8200189082004CA7
+:1027B00090A200088C8300183C027FFF3442FFFF88
+:1027C000006218243C0208008C4200B4AC8300185C
+:1027D0003C038000244200013C010800AC2200B40C
+:1027E0008C6201F80440FFFE8F82001CAC6201C0C5
+:1027F0000A000ACA240200023C10800890C30001AB
+:102800009202000B144301328FBF005836050110AD
+:1028100027A400180E000E202406000327A4002879
+:10282000360501E00E000E20240600038FA20028CA
+:1028300036030100AE0200648FA2002CAE020068D5
+:102840008FA20030AE02006C93A40018906300C504
+:102850002402FF800082102400431025305000FF26
+:102860003084007F3202007F0082102A5440000131
+:102870003A1000800E0005570000000002421021AF
+:102880002403FF8000431024AE22009493A4001878
+:102890003C130800927300F70E0005573084007F48
+:1028A000024210213042007F3C0380060043402159
+:1028B0008FA3001C2402FFFF10620034AFA8004069
+:1028C00093A2001995030014304400FF3063FFFF0A
+:1028D0000064182B10600010000000009504001424
+:1028E0008D07001C8D0600183084FFFF0044202354
+:1028F0000004210000E438210000102100E4202B16
+:1029000000C2302100C43021AD07001CAD06001804
+:102910000A000A2393A20019950400148D07001CD5
+:102920008D0600183084FFFF008220230004210060
+:10293000000010210080182100C2302300E4202B69
+:1029400000C4302300E33823AD07001CAD06001897
+:1029500093A200198FA30040A462001497A2001A4A
+:10296000A46200168FA2001CAC6200108FA2001C93
+:10297000AC62000C93A20019A462002097A2001A76
+:10298000A46200228FA2001CAC6200243C048008D8
+:10299000348300808C6200388FA2002002008821DE
+:1029A000AC62003C8FA20020AC82000093A2001811
+:1029B000A062004C93A20018A0820009A0600068E9
+:1029C00093A200181051005293A400183230007FD7
+:1029D0000E00055702002021024210212407FF802B
+:1029E0003046007F3C03800000471024AC62009416
+:1029F0003C02800600C2302190C2003CAFA60040DD
+:102A00000000202100471025A0C2003C8FA80040F4
+:102A100095020002950300148D07001C3042FFFF51
+:102A20003063FFFF8D0600180043102300021100E1
+:102A300000E2382100E2102B00C4302100C2302116
+:102A4000AD07001CAD06001895020002A502001497
+:102A5000A50000168D020008AD0200108D020008CE
+:102A6000AD02000C95020002A5020020A500002284
+:102A70008D020008AD0200249102003C304200406B
+:102A80001040001A26220001A3B000383C10800834
+:102A9000A3800018361001008E0200D08D03003490
+:102AA00027A4004027A50038004310210E0007B4DA
+:102AB000AE0200D093A200383C038000A20200C501
+:102AC0008C6202780440FFFE8F82001CAC620240E0
+:102AD00024020002A06202443C021000AC620278B0
+:102AE0000E00092F00000000262200013043007F65
+:102AF00014730004004020212403FF8002231024CB
+:102B00000043202693A200180A000A3F309100FFDC
+:102B10008FA3001C2402FFFF1062000A309000FF08
+:102B200024820001248300013042007F14530005F9
+:102B3000307000FF2403FF80008310240043102620
+:102B4000305000FF3C0280089042000802008821BB
+:102B5000305000FF123000193222007F000211C0F5
+:102B600002421021244202402403FF800043182423
+:102B70003C048000AC8300943042007F3C0380061C
+:102B8000004310218C43000C004020211060000BFA
+:102B9000AFA200400E0005690000000026230001DE
+:102BA0002405FF803062007F145300020225202498
+:102BB000008518260A000AA3307100FF3C04800833
+:102BC000348400808C8300183C027FFF3442FFFF76
+:102BD00000621824AC8300183C0380008C6201F86A
+:102BE0000440FFFE00000000AC7201C0240200029D
+:102BF000A06201C43C021000AC6201F80A000B02A2
+:102C00008FBF00583C04800890C300019082000BE5
+:102C10001443002F8FBF00583490008092020008A8
+:102C200030420040104000200000000092020008E6
+:102C30000002160000021603044100050240202194
+:102C40000E000EA5240500930A000B028FBF00584A
+:102C50009202000924030018304200FF1443000DC3
+:102C600002402021240500390E000E3D00003021D5
+:102C70000E0003158F84001C8F82FFAC240300120A
+:102C8000A04300090E0003208F84001C0A000B02E1
+:102C90008FBF0058240500360E000E3D0000302185
+:102CA0000A000B028FBF00580E00031502402021BE
+:102CB000920200058F84001C344200200E00032085
+:102CC000A20200050E00104C8F84001C8FBF00581C
+:102CD0008FB300548FB200508FB1004C8FB00048BA
+:102CE00024030C803C02800027BD006003E0000844
+:102CF000AC43002427BDFFE83C028008AFB00010C1
+:102D0000AFBF0014344501003C1080008E0201402A
+:102D100094A3000E0000302100402021AF82001C4F
+:102D20003063FFFF3402FFFF106200063C076020A3
+:102D30002402FFFFA4A2000E94A500DA0E0008EE04
+:102D400030A5FFFF24020C80AE0200248FBF0014C8
+:102D50008FB0001003E0000827BD001827BDFFC09A
+:102D60003C0980003C058008AFB70034AFB20020BA
+:102D7000AFBF0038AFB60030AFB5002CAFB40028FD
+:102D8000AFB30024AFB1001CAFB000183532010062
+:102D900034A801008D2701008E4200148D0300D459
+:102DA0000000B821A38000180043102318400055EC
+:102DB000AF87001C8E4200142403FF8024E40040EF
+:102DC000AD0200D490A60008910500C53084007FB4
+:102DD00030D3007F30A200FF000211C000E21021BA
+:102DE00024420240A3A50010004310248D1400D0FB
+:102DF0008D1500D4AD22002493A300103C02800A5C
+:102E000000822021AFA40014107300330000B02111
+:102E10008FA3001427A4001427A500108C6200348F
+:102E20000282802102B010230440002B2411FF8075
+:102E30009062003C02221024304200FF1440001B2C
+:102E40000200A0219062003C34420040A062003C9D
+:102E500093A2001024420001304300FFA3A20010FF
+:102E60003C0208008C4200F450620001A3A0001054
+:102E70000E00055793A400108F90001C3C038000A7
+:102E80000202102100511024AC6200240E000557EC
+:102E900093A40010020280213210007F3C02800ABD
+:102EA000020280210A000B81AFB000140E0007B4AB
+:102EB000000000003C02800834420100AC5000D009
+:102EC00093A3001024160001A04300C593A2001094
+:102ED0001453FFD08FA300142402000116C200096E
+:102EE0003C0380008C6202780440FFFE8F82001C4D
+:102EF000AC62024024020002A06202443C021000C4
+:102F0000AC6202789242000B24030002304200FFC0
+:102F1000144300720000000096420008304300FF96
+:102F20002402008214620040240200843C028000DB
+:102F3000344901008D22000C952300060002160280
+:102F40003063FFFF3044003F240200271082000F4F
+:102F5000AF830014288200281040000824020031AA
+:102F6000240200211082000924020025108200079B
+:102F7000938200190A000BC00000000010820007B5
+:102F8000938200190A000BC0000000000E00076CBD
+:102F9000012020210A000C40000000003C038000BA
+:102FA0008C6202780440FFFE8F82001CAC620240FB
+:102FB00024020002A06202443C021000AC620278CB
+:102FC0000A000C4000000000952300069124000533
+:102FD0008D25000C8D2600108D2700188D28001CD3
+:102FE0008D290020244200013C010800A4234BD27B
+:102FF0003C010800A0244BD13C010800AC254BD873
+:103000003C010800AC264BDC3C010800AC274BE43B
+:103010003C010800AC284BE83C010800AC294BEC13
+:103020000A000C40A38200191462000A24020081E5
+:103030003C02800834420100944500DA92460005C3
+:103040008F84001C30A5FFFF30C600FF0A000C0172
+:103050003C0760211462005C000000009242000AFC
+:10306000304300FF30620020104000073062004013
+:103070003C02800834420100944500DA8F84001C31
+:103080000A000BFF24060040104000070003160052
+:103090003C02800834420100944500DA8F84001C11
+:1030A0000A000BFF240600410002160304410046FB
+:1030B0003C02800834420100944500DA8F84001CF1
+:1030C0002406004230A5FFFF3C0760190E0008EE01
+:1030D000000000000A000C40000000009242000BBB
+:1030E00024040016304200FF104400063C06800015
+:1030F0009242000B24030017304200FF14430032B9
+:103100000000000034C5010090A2000B304200FF17
+:103110001444000B000080218CA200208CA400200D
+:103120002403FF8000431024000211403084007FFC
+:10313000004410253C03200000431025ACC2083099
+:1031400094A20008000214000002140304420001CB
+:103150002410000194A20008304200805040001A60
+:103160000200B82194A2000830422000504000160E
+:103170000200B8218CA300183C021C2D344219ED2A
+:10318000106200110200B8213C0208008C4200D4F9
+:10319000104000053C028008240300043442010072
+:1031A000A04300EC3C02800834420100944500DA60
+:1031B0008F84001C2406000630A5FFFF0E0008EED9
+:1031C0003C0760210200B8210E00092F000000001A
+:1031D0009242000A30420008104000043C02800085
+:1031E0000E00121F000000003C02800024030C802F
+:1031F000AC4300248FBF003802E010218FB60030AE
+:103200008FB700348FB5002C8FB400288FB3002403
+:103210008FB200208FB1001C8FB0001803E00008AF
+:1032200027BD00402402FF80008220243C02900041
+:1032300034420007008220253C028000AC4400207C
+:103240003C0380008C6200200440FFFE0000000070
+:1032500003E00008000000003C0380002402FF801F
+:10326000008220243462000700822025AC64002004
+:103270008C6200200440FFFE0000000003E0000814
+:10328000000000003C0280082403000534420100D5
+:10329000A04300EC3C0280008C4201003C03800013
+:1032A000AF82001C8C6202780440FFFE8F82001CFB
+:1032B000AC62024024020002A06202443C02100000
+:1032C000AC62027803E000080000000027BDFFE8C0
+:1032D0003C068000AFBF001034C5010094A2000876
+:1032E000304400FF38830082388200842C63000160
+:1032F0002C42000100621825106000302402008377
+:1033000093820019504000398FBF00103C02080022
+:1033100090424BD88CC401003C07080094E74BD284
+:103320003046003F38C3003238C2003F2C630001F2
+:103330002C42000100621825AF84001CAF870014E6
+:10334000A38000191460000600A0202124020020A0
+:1033500014C200113402FFFF14E2000F000000004D
+:103360002402002014C20005000000008CA30014F9
+:103370002402FFFF1062000A000000003C04080065
+:1033800024844BCC000030210E0006FB24070001F2
+:103390000A000CB6000000000E00076C00000000E0
+:1033A0000E00092F0000000024030C803C02800066
+:1033B000AC4300240A000CEF8FBF001014820006FB
+:1033C0002482FF808CC301043C026020AC430014C3
+:1033D0000A000CEF8FBF0010304200FF2C420002A9
+:1033E00010400004240200228FBF00100A000B25A9
+:1033F00027BD0018148200038FBF00100A000C6F55
+:1034000027BD00183C0208008C4200201040001D1F
+:103410002402001890A3000914620003240200167D
+:103420000A000CDB240300081462000724020017C2
+:10343000240300123C02800834420080A0430009AB
+:103440000A000CE894A700085462000794A700083B
+:103450008F82FFAC2404FFFE904300050064182413
+:10346000A043000594A7000890A6001B8CA40000B0
+:1034700094A500068FBF001000073C000A0008C991
+:1034800027BD001803E0000827BD00183C05080010
+:1034900094A54C0A3C0308008C634C143C04800047
+:1034A00030A2FFFF000230C02402FFF000C210244F
+:1034B00000621821AC83003C3C0208008C424C1096
+:1034C0003C038000AC8200383C02005034420010C3
+:1034D000AC620030000000000000000000000000AE
+:1034E0008C620000304200201040FFFD30C2000816
+:1034F000104000093C0280008C6204088C63040CBC
+:103500003C010800AC224C003C010800AC234C04F8
+:103510000A000D1B3C0300208C4304008C42040471
+:103520003C010800AC234C003C010800AC224C04D8
+:103530003C0300203C028000AC4300303C0780008C
+:103540008CE20030004310241440FFFD0000000016
+:103550003C03080094634C083C02080094424C0C65
+:103560003C06080094C64C0E24A5000100621821F8
+:1035700030A4FFFF3C020040ACE200303C010800F8
+:10358000A4234C083C010800A4254C0A148600031F
+:10359000000000003C010800A4204C0A03E00008E1
+:1035A0000000000027BDFFE83C04080024844BF025
+:1035B0003C05800AAFBF00100E000E202406000A52
+:1035C0003C02080094424BF23C03080094634C0E0A
+:1035D0003042000F244200030043180424027FFFFE
+:1035E0000043102B10400002AF8300280000000DA4
+:1035F0000E000CF1000000003C02080094424BF465
+:103600003C03080094634BFA8FBF00103042000F58
+:10361000000215000062182527BD00183C0280003A
+:1036200003E00008AC4300A03C02800A944300067B
+:103630003C02080094424BFA3C010800A4234BF6DC
+:10364000004310238F8300283042FFFF0043102BDC
+:1036500003E000083842000127BDFFE8AFBF0010BB
+:103660003C02800A944200063C010800A4224BF66A
+:103670000E000D58000000005440FFFA3C02800A82
+:103680008FBF001003E0000827BD001827BDFFE82A
+:10369000AFBF00100E000D580000000010400003E6
+:1036A000000000000E000D64000000003C02080055
+:1036B0008C424C003C0380008FBF0010AC6200388D
+:1036C0003C0208008C424C043464040027BD0018FE
+:1036D000AC62003C3C020005AC620030AF84002CC0
+:1036E00003E00008AF8000248F8200243C03000622
+:1036F00000021140004310253C038000AC62003002
+:103700000000000000000000000000008C620000CB
+:10371000304200101040FFFD34620400AF82002CE4
+:1037200003E00008AF8000243C0608008CC64C046F
+:103730008F8500248F83002C3C02080094424BFAB2
+:1037400027BDFFE024A500012463002024420001DE
+:1037500024C70020AFB10014AFB00010AFBF0018F5
+:10376000AF850024AF83002C3C010800A4224BFA53
+:10377000309000FF3C010800AC274C0404C1000855
+:103780000000882104E00006000000003C02080060
+:103790008C424C00244200013C010800AC224C0049
+:1037A0003C04080094844C083C02080094424BFA04
+:1037B0002E030001004410262C440001008318242D
+:1037C000106000040010102B24020001AF820020C2
+:1037D0000010102B00821025144000068F8200205C
+:1037E000144000048F830024240200101462000F90
+:1037F000000000000E000D88241100013C030800A9
+:1038000094634BFA3C02080094424C081462000393
+:10381000000000000E000CF1000000001600000384
+:10382000000000000E000D71000000003C030800C5
+:1038300094634BFE3C02080094424BFC246300015D
+:103840003064FFFF3C010800A4234BFE14820003F8
+:10385000000000003C010800A4204BFE1200000BF9
+:10386000000000003C02080094424BF43C030800B6
+:1038700094634BFA00021500006218253C02800098
+:10388000AC4300A00A000DF7AF8000200E000D58D9
+:103890000000000010400004022010210E000D6402
+:1038A00000000000022010218FBF00188FB100140B
+:1038B0008FB0001003E0000827BD002003E00008DF
+:1038C000000000008F8200343C030006000211401B
+:1038D000004310253C038000AC6200300000000073
+:1038E00000000000000000008C6200003042001068
+:1038F0001040FFFD34620400AF82003003E0000896
+:10390000AF80003403E000080000102103E000084D
+:10391000000000003084FFFF30A5FFFF00001821E9
+:1039200010800007000000003082000110400002FB
+:1039300000042042006518210A000E1600052840E8
+:1039400003E000080060102110C0000624C6FFFF3D
+:103950008CA2000024A50004AC8200000A000E2006
+:103960002484000403E000080000000010A0000808
+:1039700024A3FFFFAC860000000000000000000050
+:103980002402FFFF2463FFFF1462FFFA2484000473
+:1039900003E00008000000003C0280083442008080
+:1039A00024030001AC43000CA4430010A443001204
+:1039B000A443001403E00008A443001627BDFFD869
+:1039C000248200802407FF803043007FAFB00010C6
+:1039D00000808021004720243C0208008C42002007
+:1039E0003C08800EAFB3001CAFB20018AFB100149A
+:1039F000AFBF00203C0980000068182130B100FFF3
+:103A000030D200FF1040002900009821260201005A
+:103A1000AD24002C004728243042007F004820219C
+:103A20009062000024030050304200FF1443000461
+:103A300000000000AD25002C948200DA3053FFFF17
+:103A40000E000D71000000003C03080094634BFE63
+:103A50008F82002C00112C0000A3282500122400C6
+:103A60003C0340003484000100A32825AC50000032
+:103A70008FBF0020AC4000048FB20018AC53000888
+:103A80008FB10014AC40000C8FB3001CAC4400108C
+:103A90008FB00010AC40001424040001AC400018AA
+:103AA00027BD00280A000D98AC45001C8FBF0020E0
+:103AB0008FB3001C8FB200188FB100148FB00010AC
+:103AC00003E0000827BD00283C06800034C2010046
+:103AD0009043000F240200101062000E28650011B0
+:103AE00010A0000724020012240200082405003A56
+:103AF000106200060000302103E000080000000012
+:103B0000240500351462FFFC000030210A000E3D40
+:103B1000000000008CC200748F83FFAC24420FA011
+:103B200003E00008AC62000C27BDFFE8AFBF001047
+:103B30000E000325240500013C0480088FBF0010FF
+:103B40002402000134830080A462001227BD001803
+:103B50002402000103E00008A080001A27BDFFE056
+:103B6000AFB20018AFB10014AFB00010AFBF001C6F
+:103B700030B2FFFF0E000315008088213C02800850
+:103B8000345000809202000924030004304200FFF8
+:103B90001443000C3C028008124000082402000A72
+:103BA0000E000E3400000000920200052403FFFE08
+:103BB00000431024A202000524020012A202000900
+:103BC0003C02800834420080022020210E000320A5
+:103BD000A040002716400003022020210E000E986E
+:103BE0000000000002202021324600FF8FBF001C91
+:103BF0008FB200188FB100148FB000102405003868
+:103C00000A000E3D27BD002027BDFFE0AFBF001C0E
+:103C1000AFB20018AFB10014AFB000100E00031522
+:103C2000008080210E000E34000000003C0280085D
+:103C30003445008090A2000924120018305100FF82
+:103C4000123200030200202124020012A0A2000967
+:103C500090A200052403FFFE004310240E00032061
+:103C6000A0A2000502002021240500201632000732
+:103C7000000030218FBF001C8FB200188FB10014DC
+:103C80008FB000100A00032527BD00208FBF001C45
+:103C90008FB200188FB100148FB0001024050039C6
+:103CA0000A000E3D27BD002027BDFFE83C02800032
+:103CB000AFB00010AFBF0014344201009442000CBA
+:103CC000240500360080802114400012304600FF99
+:103CD0000E000315000000003C0280083442008002
+:103CE00024030012A0430009904300053463001030
+:103CF0000E000E34A04300050E0003200200202118
+:103D0000020020210E000325240500200A000F15C3
+:103D1000000000000E000E3D000000000E00031524
+:103D2000020020213C0280089043001B2405FF9FD5
+:103D300002002021006518248FBF00148FB00010EE
+:103D4000A043001B0A00032027BD001827BDFFE089
+:103D5000AFBF0018AFB10014AFB0001030B100FF1A
+:103D60000E000315008080213C028008240300120D
+:103D7000344200800E000E34A04300090E000320E0
+:103D80000200202102002021022030218FBF0018D4
+:103D90008FB100148FB00010240500350A000E3DCD
+:103DA00027BD00203C0480089083000E9082000A0A
+:103DB0001443000B000028218F82FFAC2403005025
+:103DC0002405000190420000304200FF144300042B
+:103DD000000000009082000E24420001A082000E2C
+:103DE00003E0000800A010213C0380008C6201F871
+:103DF0000440FFFE24020002AC6401C0A06201C4C2
+:103E00003C02100003E00008AC6201F827BDFFE0AF
+:103E1000AFB200183C128008AFB10014AFBF001C55
+:103E2000AFB0001036510080922200092403000A2E
+:103E3000304200FF1443003A000000008E430004AB
+:103E40008E2200385062007E8FBF001C922200003C
+:103E500024030050304200FF144300253C02800040
+:103E60008C4201408E43000436420100022028218A
+:103E7000AC43001C9622005C8E2300383042FFFFCA
+:103E80000002104000621821AE23001C8E43000483
+:103E90008E2400389622005C006418233042FFFF15
+:103EA00000031843000210400043102A104000068F
+:103EB000000000008E4200048E23003800431023CF
+:103EC0000A000F83000220439622005C3042FFFF6D
+:103ED000000220403C02800834430100344200804C
+:103EE000ACA4002CA040002424020001A062000C1D
+:103EF0000E000F3700000000104000518FBF001C63
+:103F00003C0280008C4401408FBF001C8FB200181F
+:103F10008FB100148FB000100A000F4827BD002099
+:103F20009222000924030010304200FF14430004D1
+:103F30003C0280008C4401400A000FC5000028218B
+:103F40009222000924030016304200FF14430006A9
+:103F500024020014A22200093C0280008C4401408B
+:103F60000A000FD88FBF001C8E2200388E23003C21
+:103F700000431023044100328FBF001C922200270F
+:103F800024420001A2220027922200273C030800BD
+:103F90008C630048304200FF144300163C10800040
+:103FA0009222000924030004304200FF1443000958
+:103FB0003C0280008C4401408FBF001C8FB200186F
+:103FC0008FB100148FB00010240500930A000EA5D5
+:103FD00027BD00208C440140240500938FBF001CA6
+:103FE0008FB200188FB100148FB000100A000F219B
+:103FF00027BD00208E0401400E00031500000000C4
+:104000008E4200042442FFFFAE4200048E22003C98
+:104010002442FFFFAE22003C0E0003208E0401402C
+:104020008E0401408FBF001C8FB200188FB10014A6
+:104030008FB00010240500040A00032527BD0020CE
+:104040008FB200188FB100148FB0001003E0000889
+:1040500027BD00203C0680008CC201883C038008FC
+:10406000346500809063000E00021402304400FFAB
+:10407000306300FF1464000E3C02800890A200260A
+:10408000304200FF104400098F82FFACA0A400263C
+:104090002403005090420000304200FF1443000609
+:1040A000000000000A00058C8CC401803C028008DE
+:1040B00034420080A044002603E000080000000015
+:1040C00027BDFFE030E700FFAFB20018AFBF001C14
+:1040D000AFB10014AFB000100080902114E00006D2
+:1040E00030C600FF000000000000000D00000000CE
+:1040F0000A001037240001173C0380089062000E6C
+:10410000304200FF144600233462008090420026B3
+:10411000304200FF1446001F000000009062000FB4
+:10412000304200FF1446001B000000009062000AAD
+:10413000304200FF144600038F90FFAC0000000DDA
+:104140008F90FFAC8F82FFB03C118000AE05003C29
+:10415000AC450000A066000A0E0003158E24010085
+:10416000A20000240E0003208E2401003C038000E6
+:104170008C6201F80440FFFE24020002AC7201C010
+:10418000A06201C43C021000AC6201F80A001038C1
+:104190008FBF001C000000000000000D00000000A8
+:1041A000240001408FBF001C8FB200188FB1001493
+:1041B0008FB0001003E0000827BD00208F83FFAC04
+:1041C0003C0280008C440100344201008C65003CBC
+:1041D0009046001B0A000FFE240700013C028008E5
+:1041E0009043000E9042000A00431026304200FF28
+:1041F00003E000080002102B27BDFFE03C0280080E
+:10420000AFB10014AFB00010AFBF00183450008041
+:104210009202000524030030304200301443008431
+:10422000008088213C0208008C4200201040008160
+:104230008FBF00180E000D71000000008F86002C4B
+:10424000ACD100009202000892030009304200FF46
+:1042500000021200306300FF00431025ACC20004CE
+:104260009202004D000216000002160304410005F0
+:10427000000000003C0308008C6300480A00107630
+:104280003C108008920200083042004014400003B5
+:104290000000182192020027304300FF3C108008E4
+:1042A000361100809222004D00031E003C050800DC
+:1042B00094A54BFE304200FF000214000062182556
+:1042C000ACC300088E2300303C02C00B00A228259E
+:1042D000ACC3000C8E22003400002021ACC20010C0
+:1042E0008E220038ACC200148E22003CACC20018F2
+:1042F0000E000D98ACC5001C8E0200048F84002CAB
+:104300003C058000AC8200008E220020AC820004BC
+:104310008E22001CAC8200088E2200588CA30074F0
+:1043200000431021AC82000C8E22002CAC820010C5
+:104330008E2200408E23004400021400004310250A
+:10434000AC8200149222004D24030080304200FF12
+:1043500014430003000000000A0010B8AC800018ED
+:104360008E23000C240200011062000E2402FFFFC5
+:1043700092220008304200401440000A2402FFFF4D
+:104380008E23000C8CA20074006218233C020800EB
+:10439000006210241440000200002821006028213F
+:1043A00000051043AC8200183C02080094424BFE0A
+:1043B0003C03C00C00002021004310258F83002CFB
+:1043C0000E000D98AC62001C3C0480083482010091
+:1043D0008C4200008F83002C348400803C0608004F
+:1043E00094C64BFEAC620000AC6000048C850048B3
+:1043F0003C02400D00C23025AC650008AC60000CEA
+:10440000AC600010908200058FBF00188FB10014BF
+:1044100000021600AC6200148FB00010AC600018EF
+:1044200024040001AC66001C0A000D9827BD002082
+:104430008FBF00188FB100148FB0001003E0000888
+:1044400027BD00203C0280009443007C3C02800891
+:1044500034460100308400FF3065FFFF2402000570
+:1044600024A34650A0C4000C5482000C3065FFFF0A
+:1044700090C2000D2C4200071040000724A30A0040
+:1044800090C3000D240200140062100400A2102149
+:104490000A0010F53045FFFF3065FFFF3C02800841
+:1044A0003442008003E00008A44500143C03800867
+:1044B00034680080AD050038346701008CE2001CD0
+:1044C000308400FF00A210231840000330C600FF14
+:1044D00024A2FFFCACE2001C308200015040000826
+:1044E0003C0380088D02003C00A21023044100120E
+:1044F000240400058C62000410A2000F3C03800815
+:104500008C62000414A20018000000003C020800A5
+:104510008C4200D830420020104000093C02800844
+:1045200034620080906300089042004C1443000401
+:104530003C028008240400040A0010DF0000000090
+:104540003443008034420100A040000C24020001EA
+:10455000A462001410C000043C0280008C440100DE
+:104560000A000F480000000003E0000800000000FF
+:1045700027BDFFE800A61823AFBF00101860004E4B
+:10458000308800FF3C02800834470080A0E000240F
+:1045900034440100A0E000278C82001C00A21023FC
+:1045A0000440002B000000008CE2003C94E3005C1F
+:1045B0008CE4002C004530233063FFFF00C318213A
+:1045C0000083202B1080000400E018218CE2002CD6
+:1045D0000A00114800A2102194E2005C3042FFFF63
+:1045E00000C2102100A21021AC62001C3C02800815
+:1045F0003447008094E2005C8CE3001C3042FFFFF3
+:104600000002104000A210210043102B10400003B4
+:10461000000000000A0011598CE2001C94E2005CCA
+:104620003042FFFF0002104000A21021ACE2001C4B
+:104630003C028008344201008FBF0010010020219D
+:1046400024060001A040000C0A0010F927BD001844
+:104650008CE2001C004610230043102B5440000144
+:10466000ACE5001C94E2005C3042FFFF0062102BBE
+:10467000144000072402000294E2005C8CE3001C5A
+:104680003042FFFF00621821ACE3001C240200024C
+:10469000ACE500380E000F37A082000C1040001867
+:1046A0008FBF00103C0280008C4401008FBF0010BF
+:1046B0000A000F4827BD00183102001010400010FA
+:1046C0008FBF00103C028008344500808CA3001C82
+:1046D00094A2005C006618233042FFFF006218219C
+:1046E0003C023FFF3444FFFF0083102B5440000185
+:1046F0000080182100C31021ACA2001C8FBF001045
+:1047000003E0000827BD001827BDFFE800C04021D6
+:1047100000A63023AFBF001018C00026308A00FF6B
+:104720003C028008344900808D24001C8D23002C1D
+:10473000008820230064182B1060000F344701000C
+:104740008CE2002000461021ACE200208CE2002028
+:104750000044102B1440000B3C023FFF8CE2002071
+:1047600000441023ACE200209522005C3042FFFFA1
+:104770000A0011AE00822021ACE00020008620213A
+:104780003C023FFF3443FFFF0064102B5440000104
+:10479000006020213C0280083442008000851821FE
+:1047A000AC43001CA0400024A04000270A0011FDDB
+:1047B0008FBF001031420010104000408FBF00102A
+:1047C0003C06800834C400808C82003C00481023E2
+:1047D0005840003B014020219082002424420001E7
+:1047E000A0820024908200243C0308008C630024F3
+:1047F000304200FF0043102B544000348FBF0010A4
+:1048000034C201008C42001C00A210231840002F6B
+:104810008FBF00108CC300049482005C00681823D2
+:104820003042FFFF00031843000210400043102AEB
+:1048300010400005000000008CC200040048102356
+:104840000A0011E3000210439482005C3042FFFF33
+:10485000000210403C068008AC82002C34C5008069
+:1048600094A2005C8CA4002C94A3005C3042FFFF57
+:1048700000021040008220213063FFFF00832021CE
+:1048800001041021ACA2001C8CC2000434C601003B
+:10489000ACC2001C240200020E000F37A0C2000CA4
+:1048A0001040000A8FBF00103C0280008C440100C1
+:1048B0008FBF00100A000F4827BD001801402021BB
+:1048C000240600010A0010F927BD001803E00008C3
+:1048D00027BD00183C098008352A00808D42003C25
+:1048E000308300FF352B01000046102330E700FF26
+:1048F000184000060060202124020001A160000C85
+:10490000A160000D0A001190A542001424020005C8
+:10491000352901000000302114E20008A1400027E1
+:104920009122000D2C4200061040000400000000FF
+:104930009122000D24420001A122000D0A0010F96D
+:10494000000000003C0380083C028000344201006B
+:1049500034640080346301009045000A8C480014E0
+:104960008C8900389062000C30AA00FF01281823BF
+:10497000304700FF1C60000E2CE4000624020001FA
+:1049800000E210041080000A30430003014020219F
+:10499000010028210120302114600007304B000C59
+:1049A000156000073042003014400007000000008E
+:1049B00003E00008000000000A0011900000000061
+:1049C0000A00112A000000000A0012030000000083
+:1049D0003C0380083464010024020003A082000C20
+:1049E0008C62000403E00008AC82001C3C058008D7
+:1049F00034A300809062002734A501002406004300
+:104A000024420001A0620027906300273C020800B6
+:104A10008C420048306300FF146200043C076021B0
+:104A200094A500DA0A0008EE30A5FFFF03E00008B5
+:104A30000000000027BDFFE8AFBF00103C0280006F
+:104A40000E0012498C4401803C028008344301006E
+:104A5000A060000C8C4200048FBF001027BD00181E
+:104A600003E00008AC62001C27BDFFE03C028008A8
+:104A7000AFBF0018AFB10014AFB0001034450080D4
+:104A8000344601003C0880008D09014090C3000CB1
+:104A90008CA4003C8CA2003814820038306700FFE0
+:104AA0009502007C90A30027146000093045FFFFA9
+:104AB0002402000554E200083C04800890C2000D66
+:104AC00024420001A0C2000D0A0012843C048008A8
+:104AD000A0C0000D3C048008348201009042000C0C
+:104AE00024030005304200FF1443000A24A205DC21
+:104AF00034830080906200272C420007504000055C
+:104B000024A20A009063002724020014006210040B
+:104B100000A210213C108008361000803045FFFFB5
+:104B2000012020210E001249A60500149602005C07
+:104B30008E0300383C1180003042FFFF000210401D
+:104B400000621821AE03001C0E0003158E240140E4
+:104B50009202002534420040A20200250E000320EC
+:104B60008E2401408E2401408FBF00188FB10014A5
+:104B70008FB000100A000F4827BD00208FBF00181B
+:104B80008FB100148FB0001003E0000827BD002093
+:104B90008008010080080080800800008008024032
+:104BA00008000EF008000F4808000F8C08001020C5
+:104BB0000800106480080100800800808008000060
+:104BC0000A00002000000000000000000000000DAE
+:104BD0006370342E362E31370000000004061104B5
+:104BE00000000000000000000000000000000000C5
+:104BF0000000000038003C00000000000000000041
+:104C00000000000000000000000000200000000084
+:104C10000000000000000000000000000000000094
+:104C20000000000000000000000000000000000084
+:104C30000000000021003800000000010000002BEF
+:104C40000000000010000003000000000000000D44
+:104C50000000000D3C020800244255C43C0308003B
+:104C6000246357F4AC4000000043202B1480FFFD68
+:104C7000244200043C1D080037BD9FFC03A0F02126
+:104C80003C100800261000803C1C0800279C55C4DE
+:104C90000E00026A000000000000000D00A01821B4
+:104CA00000801021008028213C0460003C07600047
+:104CB0002406000810600006348420788C4200002E
+:104CC000ACE220088C63000003E00008ACE3200C99
+:104CD0000A000E1C00000000240300403C0260009B
+:104CE00003E00008AC4320003C0760008F86000012
+:104CF0008CE520740086102100A2182B1460000798
+:104D0000000028218F8AFDEC24050001A144001336
+:104D10008F89000001244021AF88000003E00008D3
+:104D200000A010218F84FDEC8F8500009086001379
+:104D300030C300FF00A31023AF82000003E000088F
+:104D4000A08000138F84FDEC27BDFFE8AFB00010FA
+:104D5000AFBF001490890011908700112402002831
+:104D6000312800FF3906002830E300FF2485002C9D
+:104D70002CD00001106200162484001C0E000037A5
+:104D8000000000008F8FFDEC3C056000240202044F
+:104D900095EE003E95ED003C000E5C0031ACFFFF4F
+:104DA000016C5025ACAA201052000001240200041E
+:104DB000ACA2200000000000000000000000000085
+:104DC0008FBF00148FB0001003E0000827BD00184B
+:104DD0000A00006F000028218F85FDEC27BDFFD859
+:104DE000AFBF0020AFB3001CAFB20018AFB10014CA
+:104DF000AFB000100080982190A4001124B0001CD6
+:104E000024B1002C308300FF386200280E000059C6
+:104E10002C5200010E000061000000000200202161
+:104E20001240000202202821000028210E00003735
+:104E3000000000008F8DFDEC3C0880003C05600008
+:104E400095AC003E95AB003C02683025000C4C0050
+:104E5000316AFFFF012A3825ACA720102402020284
+:104E6000ACA6201452400001240200028FBF002093
+:104E70008FB3001C8FB200188FB100148FB00010D8
+:104E800027BD002803E00008ACA2200027BDFFE0FA
+:104E9000AFB20018AFB10014AFB00010AFBF001C2C
+:104EA0003C1160008E2320748F82000030D0FFFF01
+:104EB00030F2FFFF1062000C2406008F0E00003756
+:104EC000000000003C06801F0010440034C5FF00B5
+:104ED0000112382524040002AE27201000003021E2
+:104EE000AE252014AE2420008FBF001C8FB2001806
+:104EF0008FB100148FB0001000C0102103E0000833
+:104F000027BD002027BDFFE0AFB0001030D0FFFF6D
+:104F1000AFBF0018AFB100140E00003730F1FFFF33
+:104F200000102400009180253C036000AC7020102C
+:104F30008FBF00188FB100148FB00010240200043E
+:104F4000AC62200027BD002003E000080000102113
+:104F500027BDFFE83C0C6018AFBF00108D985000D3
+:104F60002419FF7F3C0880000319782435EE380CA3
+:104F7000340D8071240A003124090C00AD8E5000DC
+:104F80003C0B800AAD8D53BCAD0A0008AD0900246E
+:104F90000E00048DAF8B002C0E00044B00000000AF
+:104FA0000E000046000000003C0760008CE5080889
+:104FB0002406FFF03C03570900A620243462F000C9
+:104FC00010820048241F0001AF8000380E000BAE95
+:104FD000000000003C0660168CC700003C0860140E
+:104FE0008D0500A03C03FFFF00E320243C02535347
+:104FF00000051FC21082003534C57C0094A201F266
+:10500000A780005010400003A7800060384C1E1E8F
+:10501000A78C005094A201F8104000048F8E003835
+:10502000384D1E1EA78D00608F8E003811C0000401
+:1050300097840060240F0020A78F005097840060A1
+:105040002C980081530000012404008097850050B3
+:105050002CB9040153200001240504003C03600026
+:105060008C670438241F103C30E2FFFF105F000300
+:105070003088FFFF5100000B24060050A38000621F
+:10508000938900621120000B8FBF001027BD00180C
+:10509000A7800060A7800050A780005803E00008A8
+:1050A000A7800076A3860062938900621520FFF72F
+:1050B0008FBF001027BD0018A7840060A78500508F
+:1050C000A780005803E00008A780007600035880FE
+:1050D000016650218D4900043C0660000A00010F62
+:1050E000012628210A000103AF9F00383083FFFF0B
+:1050F0008F88002C8F870028000321403C0580000A
+:105100003C020050008248253C0660003C0A010039
+:1051100034AC04008CCD08E001AA582411600005CD
+:10512000000000008CCF08E024E7000101EA7025B0
+:10513000ACCE08E08D19001001805821ACB90038C0
+:105140008D180014ACB8003CACA900300000000081
+:10515000000000000000000000000000000000004F
+:105160000000000000000000000000003C03800080
+:105170008C640000308200201040FFFD3C0F600076
+:105180008DED08E03C0E010001AE18241460FFE133
+:1051900000000000AF87002803E00008AF8B003C50
+:1051A0008F85002C240BFFF03C06800094A7001A8A
+:1051B0008CA9002430ECFFFF000C38C000EB502419
+:1051C000012A4021ACC8003C8CA400248CC3003CC4
+:1051D0000083102318400033000000008CAD002035
+:1051E00025A200013C0F0050ACC2003835EE001083
+:1051F0003C068000ACCE0030000000000000000043
+:10520000000000000000000000000000000000009E
+:1052100000000000000000003C0480008C990000A9
+:10522000333800201300FFFD30E200081040001763
+:105230003C0980008C880408ACA800108C83040C06
+:10524000ACA300143C1900203C188000AF190030BA
+:1052500094AE001894AF001C01CF3021A4A6001812
+:1052600094AD001A25A70001A4A7001A94AB001A58
+:1052700094AC001E118B00030000000003E0000846
+:105280000000000003E00008A4A0001A8D2A04001A
+:10529000ACAA00108D240404ACA400140A0001A2DE
+:1052A0003C1900208CA200200A00018A3C0F00500B
+:1052B0000A000178000000003C0308008C63002015
+:1052C0008F82003427BDFFE810620008AFBF0010D6
+:1052D0000E0001BCAF8300343C0308008C63002047
+:1052E00024040001106400048F8C002C8FBF001078
+:1052F00003E0000827BD00188FBF00103C058000A8
+:10530000A580000A958B000A958A000427BD001825
+:105310003167FFFF3149000F0009450000E83025E3
+:1053200003E00008ACA600803C0208008C4200208C
+:1053300027BDFFC8AFBF0034AFBE0030AFB7002CF1
+:10534000AFB60028AFB50024AFB40020AFB3001C47
+:10535000AFB20018AFB1001410400053AFB000104E
+:105360008F84002C948600069483000A00C32823AF
+:1053700030B6FFFF12C0004D8FBF00349489001873
+:10538000948A000A012A40233102FFFF02C2382B0F
+:1053900014E0000202C02021004020212C8C0005D6
+:1053A000158000020080A021241400040E00014B8F
+:1053B000028020218F87002C02809821AF8000304E
+:1053C00094ED000A028088211280005131B2FFFF63
+:1053D0003C1770003C1540003C1E60008F8F003C65
+:1053E0008DEE000001D718245075005302202021B3
+:1053F00002A3802B160000383C1820001078004AC9
+:1054000000000000241000018F8300301460003C75
+:10541000029158230230F8230250C82133F1FFFFD4
+:105420001620FFEE3332FFFF8F87002C3C12002046
+:105430003C118000AE32003094EA000A3C17800034
+:10544000026A4821A4E9000A94E3000A94E80004EF
+:105450003065FFFF3106000F0006150000A2F025A1
+:10546000AEFE008094F4000A94F5001812B4003ADD
+:105470000013C9408CF800148CEE00100319582159
+:10548000000078210179682B01CF6021018D202156
+:10549000ACEB0014ACE4001002D3382330F6FFFF6D
+:1054A00016C0FFB68F84002C8FBF00348FBE003033
+:1054B0008FB7002C8FB600288FB500248FB4002042
+:1054C0008FB3001C8FB200188FB100148FB0001082
+:1054D00003E0000827BD0038107E001B000000001C
+:1054E0001477FFC9241000010E0014E00000000032
+:1054F0008F8300301060FFC80230F82302915823D8
+:105500008F87002C017020210A0002553093FFFF85
+:105510008F8300301460FFC83C1200203C118000D3
+:105520000A00021EAE3200300E0003CE02202021FF
+:105530000A000212004080210E0007C60240282106
+:105540000A000212004080210E000D7D0220202161
+:105550000A000212004080210E00017800000000C5
+:105560000A00023702D3382327BDFFD0AFB500248D
+:10557000AFB40020AFB3001CAFB20018AFB100143D
+:10558000AFB00010AFBF00280E0000E43C14800054
+:105590003C0280083C0320003C010800AC20007065
+:1055A00034550080347200032413000136900070DB
+:1055B0002411FF800A0002858E0600003C1980003D
+:1055C0008F3800003B0F000131E200011040002540
+:1055D0008F8600848E0700003C0D08008DAD003CD6
+:1055E0003C0A08008D4A003800E6702301AE4021D5
+:1055F00000005821010E302B014B482101262021AB
+:105600003C010800AC28003CAF8700843C01080046
+:10561000AC2400380E0001BE000000003C0508006C
+:105620008CA5007010A0FFE500A020213C0508001B
+:105630008CA500683C0608008CC6006C0E00148324
+:10564000000000003C010800AC2000703C19800004
+:105650008F3800003B0F000131E200011440FFDDF4
+:105660008F8600848E0C00008F8D00843C0708001C
+:105670008CE7003C3C0608008CC60038018D58239E
+:1056800000EB282100AB202B00C24821012410216F
+:105690003C010800AC25003C3C0880003C010800AF
+:1056A000AC2200388D030100241F0C00107F00265F
+:1056B000000000008D180100240E0020AD1800200D
+:1056C00092AF000031E300FF106E00232419005058
+:1056D00010790026000000003C0480008C88010046
+:1056E0001500000300000000566000143C04400058
+:1056F0008C9901008C8F0100000098210331C02497
+:105700000018694031EE007F01AE602501925825F6
+:10571000AC8B08308C8701008C89010024EA0100E1
+:1057200001513024000629403123007F00A31025B9
+:105730000052F825AC9F08303C044000AE8401388C
+:105740000A00027D000000000E0001DA00000000E7
+:105750000A0002C73C0480008D0401000E00077F90
+:10576000000000000A0002C73C0480008D04010014
+:105770000E00139B000000000A0002C73C048000DA
+:1057800000A4102B24030001104000090000302168
+:105790000005284000A4102B04A0000300031840BB
+:1057A0005440FFFC000528405060000A0004182BFC
+:1057B0000085382B54E000040003184200C3302554
+:1057C00000852023000318421460FFF900052842D9
+:1057D0000004182B03E0000800C310213084FFFFF1
+:1057E00030C600FF3C0780008CE201B80440FFFE99
+:1057F00000064C00012430253C08200000C820256C
+:105800003C031000ACE00180ACE50184ACE401880D
+:1058100003E00008ACE301B83C0660008CC5201C26
+:105820002402FFF030830200308601001060000E79
+:1058300000A2282434A500013087300010E00005C4
+:1058400030830C0034A500043C04600003E0000831
+:10585000AC85201C1060FFFD3C04600034A50008EE
+:1058600003E00008AC85201C54C0FFF334A50002FF
+:105870000A00031F3087300027BDFFE8AFB00010DB
+:10588000AFBF00143C076000240600021080001126
+:1058900000A080218F83003C0E0003168C6400184A
+:1058A0008F82003C00002021240600018C45000C62
+:1058B0000E0003070000000016000002240200038F
+:1058C000000010218FBF00148FB0001003E000080B
+:1058D00027BD00188CE8201C2409FFF001092824AA
+:1058E000ACE5201C8F87003C0A00033C8CE5000CD3
+:1058F0003C02600E0080402134460100240900185B
+:105900000000000000000000000000003C0A005001
+:105910003C03800035470200AC6800383464040062
+:10592000AC65003CAC6700308C6C0000318B002013
+:105930001160FFFD2407FFFF2403007F8C8D000012
+:105940002463FFFF24840004ACCD00001467FFFB38
+:1059500024C6000400000000000000000000000059
+:1059600024A402000085282B3C0300203C0E80006C
+:105970002529FFFF01054021ADC300301520FFE0C0
+:105980000080282103E00008000000008F82003C16
+:1059900027BDFFD8AFB3001CAFBF0020AFB20018C7
+:1059A000AFB10014AFB000109446000200809821FF
+:1059B0008C5200182CC300818C4800048C470008CE
+:1059C0008C51000C8C490010106000078C4A0014A8
+:1059D0002CC400041480001330EB000730C5000312
+:1059E00010A00010000000002410008B02002021F5
+:1059F000022028210E00030724060003166000027F
+:105A000024020003000010218FBF00208FB3001C70
+:105A10008FB200188FB100148FB0001003E000089F
+:105A200027BD00281560FFF12410008B3C0C80007E
+:105A30003C030020241F0001AD830030AF9F0030E5
+:105A40000000000000000000000000002419FFF02A
+:105A500024D8000F031978243C1000D0AD880038FA
+:105A600001F0702524CD00033C08600EAD87003C9A
+:105A700035850400AD8E0030000D38823504003CC1
+:105A80003C0380008C6B0000316200201040FFFD61
+:105A90000000000010E0000824E3FFFF2407FFFFE0
+:105AA0008CA800002463FFFF24A50004AC8800003C
+:105AB0001467FFFB248400043C04600EAC860038AD
+:105AC0000000000000000000000000003C07002073
+:105AD0003C0680000120202101402821ACC7003075
+:105AE0000E00034C000080210E000316024020210E
+:105AF0000A00038C0200202127BDFFD8AFB2001896
+:105B00003092FFFFAFB10014AFBF0020AFB3001C55
+:105B1000AFB000101240002D000088210A0003E2FF
+:105B20002413000350B300428CE5000C0000000D6C
+:105B3000263900013331FFFF24F800200232382BD0
+:105B400010E00022AF98003C8F8200301440001F0C
+:105B50008F87003C3C0670003C0320008CE4000072
+:105B60000086282414A300198F85004400044402F1
+:105B70003C0980000089802414A0FFEA310600FF60
+:105B8000240A000210CA003028CB0003116000175D
+:105B9000000000002404000114C4FFE626390001BF
+:105BA000020028210E00032E240400018F87003CF0
+:105BB000AF820044263900013331FFFF24F8002072
+:105BC0000232382B14E0FFE0AF98003C0220102195
+:105BD0008FBF00208FB3001C8FB200188FB100144C
+:105BE0008FB0001003E0000827BD002810D3001B71
+:105BF000240C000414CCFFCF26390001308DFFFFA8
+:105C0000000D19C03C0480008C8E01B805C0FFFE59
+:105C10003C0F10003C102004AC830180AC80018458
+:105C2000AC900188AC8F01B80A0003DD2639000171
+:105C30000E000307240400841600FFBD8F87003C7C
+:105C40000A0003DCAF800044020028210E00032E6E
+:105C5000000020210A0003FC8F87003C0E00037324
+:105C6000020020218F87003C0A0003FDAF82004420
+:105C7000000449C23127003F000443423C02800037
+:105C800000082040240316802CE60020AC43002CA2
+:105C900024EAFFE02482000114C0000330A900FFC1
+:105CA00000801021314700FF000260803C0D800021
+:105CB000240A0001018D20213C0B000E00EA28047B
+:105CC000008B302111200005000538278CCE000004
+:105CD00001C5382503E00008ACC700008CD80000DF
+:105CE0000307782403E00008ACCF000027BDFFE0E5
+:105CF000AFB10014AFB00010AFBF00183C07600098
+:105D00008CE408083402F0003C1160003083F0009D
+:105D1000240501C03C04800E000030211062000602
+:105D2000241000018CEA08083149F0003928E0000D
+:105D30000008382B000780403C0D0200AE2D0814EF
+:105D4000240C16803C0B80008E2744000E000E268B
+:105D5000AD6C002C120000043C02169124050001D9
+:105D6000120500103C023D6C345800E0AE38440887
+:105D70003C1108008E31007C8FBF00183C0660008B
+:105D800000118540360F16808FB100148FB00010BF
+:105D90003C0E020027BD0020ACCF442003E00008E9
+:105DA000ACCE08103C0218DA345800E0AE38440893
+:105DB0003C1108008E31007C8FBF00183C0660004B
+:105DC00000118540360F16808FB100148FB000107F
+:105DD0003C0E020027BD0020ACCF442003E00008A9
+:105DE000ACCE08100A00042C240500010A00042C83
+:105DF0000000282124020400A782000CA7800004D0
+:105E0000000020213C06080024C656582405FFFF48
+:105E100024890001000440803124FFFF010618217D
+:105E20002C87002014E0FFFAAC6500002404040075
+:105E3000A784000EA7800006000020213C06080071
+:105E400024C656D82405FFFF248D0001000460807D
+:105E500031A4FFFF018658212C8A00201540FFFA4B
+:105E6000AD650000A7800010A7800008A780000A89
+:105E7000000020213C06080024C657582405FFFFD7
+:105E8000249900010004C0803324FFFF0306782119
+:105E90002C8E000415C0FFFAADE500003C05600043
+:105EA0008CA73D002403E08F00E31024344601401A
+:105EB00003E00008ACA63D002487007F000731C244
+:105EC00024C5FFFF000518C2246400013082FFFFD3
+:105ED000000238C0A78400183C010800AC2700303D
+:105EE000AF80001400002821000020210000302194
+:105EF0002489000100A728213124FFFF2CA81701C5
+:105F0000110000032C8300801460FFF924C60001F7
+:105F100000C02821AF86001410C0001DA786001203
+:105F200024CAFFFF000A11423C0808002508575800
+:105F30001040000A00002021004030212407FFFF0C
+:105F4000248E00010004688031C4FFFF01A8602195
+:105F50000086582B1560FFFAAD87000030A2001FA5
+:105F60005040000800043080240300010043C804AE
+:105F700000041080004878212738FFFF03E0000864
+:105F8000ADF8000000C820212405FFFFAC8500000B
+:105F900003E000080000000030A5FFFF30C6FFFF4F
+:105FA00030A8001F0080602130E700FF0005294273
+:105FB0000000502110C0001D24090001240B000125
+:105FC00025180001010B2004330800FF0126782664
+:105FD000390E00202DED00012DC2000101A218256F
+:105FE0001060000D014450250005C880032C40219D
+:105FF0000100182110E0000F000A20278D04000086
+:10600000008A1825AD03000024AD000100004021E6
+:106010000000502131A5FFFF252E000131C9FFFFEF
+:1060200000C9102B1040FFE72518000103E000080D
+:10603000000000008D0A0000014440240A000512FF
+:10604000AC68000027BDFFE830A5FFFF30C6FFFFAA
+:10605000AFB00010AFBF001430E7FFFF00005021C9
+:106060003410FFFF0000602124AF001F00C0482152
+:10607000241800012419002005E0001601E0102179
+:106080000002F943019F682A0009702B01AE4024E9
+:1060900011000017000C18800064102110E00005AA
+:1060A0008C4B000000F84004000838230167582496
+:1060B00000003821154000410000402155600016C5
+:1060C0003169FFFF258B0001316CFFFF05E1FFEC1B
+:1060D00001E0102124A2003E0002F943019F682A3A
+:1060E0000009702B01AE40241500FFEB000C188056
+:1060F000154600053402FFFF020028210E0004F6B9
+:1061000000003821020010218FBF00148FB0001052
+:1061100003E0000827BD00181520000301601821C6
+:10612000000B1C0224080010306A00FF1540000517
+:10613000306E000F250D000800031A0231A800FF81
+:10614000306E000F15C00005307F000325100004DD
+:1061500000031902320800FF307F000317E000053A
+:10616000386900012502000200031882304800FF50
+:10617000386900013123000110600004310300FF81
+:10618000250A0001314800FF310300FF000C69407F
+:1061900001A34021240A000110CAFFD53110FFFFDE
+:1061A000246E000131C800FF1119FFC638C9000173
+:1061B0002D1F002053E0001C258B0001240D000141
+:1061C0000A000589240E002051460017258B000186
+:1061D00025090001312800FF2D090020512000125F
+:1061E000258B000125430001010D5004014B1024B3
+:1061F000250900011440FFF4306AFFFF3127FFFF3B
+:1062000010EE000C2582FFFF304CFFFF00005021F4
+:106210003410FFFF312800FF2D0900205520FFF228
+:1062200025430001258B0001014648260A0005434D
+:10623000316CFFFF00003821000050210A00059555
+:106240003410FFFF27BDFFD8AFB0001030F0FFFFC4
+:10625000AFB10014001039423211FFE00007108086
+:10626000AFB3001C00B1282330D3FFFFAFB200183A
+:1062700030A5FFFF008090210260302100442021E2
+:10628000AFBF00200E0005213207001F0222882127
+:106290003403FFFF02402021020028210260302148
+:1062A00000003821104300093231FFFF0220102185
+:1062B0008FBF00208FB3001C8FB200188FB1001465
+:1062C0008FB0001003E0000827BD00280E00052154
+:1062D0000000000000408821022010218FBF002014
+:1062E0008FB3001C8FB200188FB100148FB0001054
+:1062F00003E0000827BD0028000424003C036000E0
+:10630000AC603D0810A000023482100634821016E2
+:1063100003E00008AC623D0427BDFFE0AFB0001011
+:10632000309000FF2E020006AFBF0018104000089A
+:10633000AFB10014001030803C030800246353B454
+:1063400000C328218CA40000008000080000000089
+:10635000000020218FBF00188FB100148FB00010F3
+:106360000080102103E0000827BD00209791001253
+:1063700016200051000020213C020800904200330A
+:106380000A0005FC00000000978D000E15A00031EA
+:10639000000020210A0005FC240200089787000C59
+:1063A00014E0001A000018210060202124020001DE
+:1063B0001080FFE98FBF0018000429C2004530217A
+:1063C00000A6582B1160FFE43C0880003C07200029
+:1063D000000569C001A76025AD0C00203C038008C2
+:1063E0002402001F2442FFFFAC6000000441FFFDB7
+:1063F0002463000424A5000100A6702B15C0FFF53E
+:10640000000569C00A0005E68FBF001897870004E1
+:106410003C04080024845658240504000E0005A1FD
+:1064200024060001978B000C24440001308AFFFFF2
+:106430002569FFFF2D480400004028211500004079
+:10644000A789000C24AC3800000C19C00A0005FA1A
+:10645000A7800004978700063C040800248456D8CF
+:10646000240504000E0005A1240600019799000EE2
+:10647000244400013098FFFF272FFFFF2F0E040058
+:106480000040882115C0002CA78F000EA7800006B1
+:106490003A020003262401003084FFFF0E0005CEDF
+:1064A0002C4500010011F8C027F00100001021C0A8
+:1064B0000A0005FC24020008978500169787000A49
+:1064C0003C040800248457580E0005A1240600014E
+:1064D000978700128F8900142445000130A8FFFF20
+:1064E00024E3FFFF0109302B0040802114C0001875
+:1064F000A7830012A780000A978500180E000E10CF
+:1065000002002021244A05003144FFFF0E0005CE81
+:10651000240500013C05080094A500320E000E1071
+:1065200002002021244521003C0208009042003353
+:106530000A0005FC000521C00A000634A7840006F5
+:1065400024AC3800000C19C00A0005FAA784000426
+:106550000A00064EA785000A308400FF27BDFFE829
+:106560002C820006AFBF0014AFB000101040001521
+:1065700000A03821000440803C030800246353CC71
+:10658000010328218CA40000008000080000000006
+:1065900024CC007F000751C2000C59C23170FFFFAC
+:1065A0002547C40030E5FFFF2784000402003021A6
+:1065B0000E0004F624070001978600100206202131
+:1065C000A78400108FBF00148FB0001003E00008F4
+:1065D00027BD00183C0508008CA50030000779C2D3
+:1065E0000E0002F025E4DF003045FFFF3C04080008
+:1065F00024845758240600010E0004F624070001E5
+:10660000978E00128FBF00148FB0001025CD0001AF
+:1066100027BD001803E00008A78D00120007C9C2BB
+:106620002738FF00001878C231F0FFFF3C04080053
+:10663000248456D802002821240600010E0004F606
+:1066400024070001978D000E260E0100000E840025
+:1066500025AC00013C0B6000A78C000EAD603D082E
+:1066600036040006000030213C0760008CE23D0447
+:10667000305F000617E0FFFD24C9000100061B0083
+:10668000312600FF006440252CC50004ACE83D0421
+:1066900014A0FFF68FBF00148FB0001003E00008B5
+:1066A00027BD0018000751C22549C8002406000173
+:1066B000240700013C040800248456580E0004F608
+:1066C0003125FFFF9787000C8FBF00148FB000109B
+:1066D00024E6000127BD001803E00008A786000C8F
+:1066E0003084FFFF30A5FFFF3C0680008CC201B85C
+:1066F0000440FFFE3C084080008838253C03100021
+:10670000ACC00180ACC50184ACC7018803E00008BF
+:10671000ACC301B83084FFFF3C0680008CC201B8D6
+:106720000440FFFE3C0840388CA700000088282564
+:106730003C031000ACC70180ACC5018803E0000831
+:10674000ACC301B88F83005C8F8600541066000BC9
+:10675000008040213C07080024E75768000328C058
+:1067600000A710218C44000024630001108800055C
+:106770003063000F5466FFFA000328C003E00008EE
+:10678000000010213C07080024E7576C00A73021C7
+:1067900003E000088CC200003C039000346200015A
+:1067A000008220253C038000AC6400208C65002022
+:1067B00004A0FFFE0000000003E00008000000004D
+:1067C0003C028000344300010083202503E00008E0
+:1067D000AC44002027BDFFE0AFB100143091FFFFB3
+:1067E000AFB00010AFBF00181220001200A080212F
+:1067F0008CA5000014A00011240400023C068000B7
+:106800008CC201B80440FFFE3C074000022720254F
+:106810008FBF00188FB100148FB000103C03100020
+:1068200027BD0020ACC50180ACC4018803E000088E
+:10683000ACC301B80A00070F8CA500000E00066665
+:1068400024060200000028210A00070FAE00000005
+:106850003087FFFF3C0680008CC201B80440FFFE79
+:106860003C0A40068CA9000000EA4025ACC9018022
+:106870008CA400043C031000ACC40184ACC80188A3
+:1068800003E00008ACC301B88F83FDE827BDFFE833
+:10689000AFBF0014AFB00010906700080080102157
+:1068A0000080282130E600400000202110C00008B0
+:1068B0008C5000000E0000860200202102002021E2
+:1068C0008FBF00148FB000100A00048927BD001884
+:1068D0000E000724000000000E00008602002021A8
+:1068E000020020218FBF00148FB000100A0004891D
+:1068F00027BD001827BDFFE0AFB000108F90FDE866
+:10690000AFBF001CAFB20018AFB100149206000177
+:10691000008088210E0006F630D2000492040005A3
+:10692000001129C2A605000034830040A20300051F
+:106930000E000700022020210E00048B02202021DF
+:1069400024020001AE02000C02202821A602001041
+:1069500024040002A602001224060200A60200146B
+:106960000E000666A60200161640000F8FBF001C20
+:10697000978C00583C0B08008D6B00782588FFFF32
+:106980003109FFFF256A0001012A382B10E00006BB
+:10699000A78800583C0F6006240E001635ED001045
+:1069A000ADAE00508FBF001C8FB200188FB1001425
+:1069B0008FB0001003E0000827BD002027BDFFE0D6
+:1069C000AFBF0018AFB10014AFB000100E0006F654
+:1069D000008088218F85FDE80220202190A30005FA
+:1069E0000E000700307000FF2402003E1202000576
+:1069F0008FBF00188FB100148FB0001003E00008A3
+:106A000027BD00203C0580008CA401780480FFFE97
+:106A1000240700073C061000ACB1014002202021F1
+:106A2000A0A701448FBF00188FB100148FB00010D1
+:106A3000ACA601780A00074D27BD002027BDFFE066
+:106A4000AFB00010AFBF0018AFB100143C10800011
+:106A50008E110020000000000E00048BAE04002008
+:106A6000AE1100208FBF00188FB100148FB000103E
+:106A700003E0000827BD00203084FFFF3C068000B3
+:106A80008CC201B80440FFFE3C0840350088382520
+:106A90003C031000ACC50180ACC00184ACC70188C8
+:106AA00003E00008ACC301B83084FFFF3C0680005F
+:106AB0008CC201B80440FFFE3C08403600883825EF
+:106AC0003C031000ACC50180ACC00184ACC7018898
+:106AD00003E00008ACC301B827BDFFD0AFB5002468
+:106AE0003095FFFFAFB60028AFB40020AFBF002C39
+:106AF000AFB3001CAFB20018AFB10014AFB00010BC
+:106B000030B6FFFF12A000270000A0218F92003CAA
+:106B10008E4300003C0680002402004000033E0239
+:106B200000032C0230E4007F006698241482001DCC
+:106B300030A500FF8F83004C2C68000A5100001024
+:106B40008F860030000358803C0C0800258C53E8E9
+:106B5000016C50218D490000012000080000000058
+:106B600002D448213125FFFF0E0006C8240400840A
+:106B7000166000028F92003CAF80004C8F86003080
+:106B800026580020268F00010300902131F4FFFFDA
+:106B900014C00004AF98003C0295282B14A0FFDC21
+:106BA00000000000028010218FBF002C8FB600284B
+:106BB0008FB500248FB400208FB3001C8FB2001853
+:106BC0008FB100148FB0001003E0000827BD003023
+:106BD0002407003414A70146000000009247000E6D
+:106BE0008F99FDEC8F90FDE824181600A32700195B
+:106BF000924A000D3C0880003C07800CA32A001834
+:106C0000964400123C0F60003C117FFFA604005C1C
+:106C1000965F00103622FFFF240A000533E5FFFFD0
+:106C2000AE0500548E46001CAD1800288CE900000B
+:106C30008DEE44480126682601CD3021AE0600388D
+:106C40008E03003824CB00013C0E7F00AE03003CD5
+:106C50008E0C003CAF2C0004AE0B00208E130020E5
+:106C6000AE13001CA320001BAE02002CA32A0012AE
+:106C70008E44001424130050AE0400348E1F0034E0
+:106C8000AF3F00148E450018AE0500489258000C26
+:106C9000A218004E920F000835E90020A209000852
+:106CA0008E0D001801AE1824346C4000AE0C001894
+:106CB000920B0000317200FF125302AD2413FF80CB
+:106CC0003C040800248457E80E000732000000004E
+:106CD00024030004240800013C0508008CA557E8A3
+:106CE0003C048000A2030025A20800058C900178D6
+:106CF0000600FFFE8F92003C240E00023C0D1000A7
+:106D0000AC850140A08E0144AC8D01780A0007EFEC
+:106D1000AF80004C2CAD003711A0FF998F8600305A
+:106D2000000580803C1108002631541002117821A2
+:106D30008DEE000001C000080000000024100004D7
+:106D400014B0008E3C0780003C0C08008D8C57E886
+:106D50008F86FDE8ACEC00208E4B00088F98FDEC90
+:106D600024090050ACCB00308E430008ACC3005067
+:106D70008E42000CACC200348E4A0010ACCA0038FF
+:106D80008E440010ACC400548E5F0014ACDF003C95
+:106D90008E590018AF1900048E4F001CACCF002094
+:106DA00090D10000322500FF10A9027D00000000F4
+:106DB0008CD100348CCF0030022F302304C000F37C
+:106DC0002404008C126000F0240200030A0007EF84
+:106DD000AF82004C2418000514B800683C0B8000FA
+:106DE0003C0C08008D8C57E88F86FDE8AD6C0020C8
+:106DF0008E4300048F9FFDEC24072000ACC3001CD1
+:106E00009242000824120008A3E200198F8A003C75
+:106E100091440009A3E400188F85003C90B9000A52
+:106E2000332400FF1092001028880009150000BCD0
+:106E3000240D0002240900201089000B3407800073
+:106E4000289100211620000824074000240F00404C
+:106E5000108F00053C0700012418008010980002E4
+:106E60003C070002240740008CC400183C0AFF00C5
+:106E7000008AF82403E7C825ACD9001890B2000BAB
+:106E8000A0D200278F83003C9465000C10A0023133
+:106E9000000000009467000C3C1F8000A4C7005C49
+:106EA0009062000E2403FFBF24070004A0C2000864
+:106EB0008F8A003C9144000FA0C400098F88003CD9
+:106EC0008D1200108FF9007402592823ACC50058A8
+:106ED0008D180014ACD8002C950F001831F1FFFF6D
+:106EE000ACD100409509001A3130FFFFACD000440E
+:106EF0008D0E001CACCE0048950D0002A4CD00788C
+:106F0000910C000EA0CC000890CB00080163102467
+:106F1000126001D7A0C200088F92003C0A0007EF60
+:106F2000AF87004C2406000614A600143C0E800017
+:106F30003C1008008E1057E88F8CFDE4ADD0002087
+:106F40008E4D00188F86FDE88F8BFDECAD8D000017
+:106F50008CC8003824040005AD8800048CC3003CB4
+:106F600012600081AD6300000A0007EFAF84004C9F
+:106F70002409000710A9004B240400063C05080062
+:106F800024A557E80E000705240400818F92003CD9
+:106F90000013102B0A0007EFAF82004C241F0023C0
+:106FA00014BFFFF63C0C80003C0308008C6357E8DC
+:106FB0008F8BFDECAD8300208F91FDE88E460004A1
+:106FC0002564002026450014AE2600282406000370
+:106FD0000E000E1C257000308F87003C020020211F
+:106FE000240600030E000E1C24E500083C040800E3
+:106FF000248457E80E0007320000000092220000AF
+:1070000024040050304A00FF5544FFE18F92003CB9
+:107010000E000E07000000000A0008F48F92003CEA
+:107020002408003314A800323C0280003C11080000
+:107030008E3157E88F89FDECAC5100208E4A000854
+:10704000240F00288F8DFDE8AD2A00308E44000CFF
+:1070500024060009AD2400348E5F0010AD3F0038D7
+:107060008E590014AD3900208E450018AD2500243E
+:107070008E58001CAD380028A12F00118E4E000440
+:1070800012600031ADAE00288F92003C0A0007EF7D
+:10709000AF86004C2411002214B1FFB8000000009C
+:1070A000240400073C1808008F1857E83C0F8000A4
+:1070B000ADF800205660FEB1AF84004C3C040800DF
+:1070C000248457E80E000732241300508F99FDE8FE
+:1070D00093320000324500FF10B3016C0000000045
+:1070E0008F92003C000020210A0007EFAF84004C83
+:1070F0003C05080024A557E80E0006D524040081AD
+:107100000A0008F48F92003C02D498213265FFFFF8
+:107110000E0006C8240400840A0007EF8F92003C8A
+:10712000108DFF51240704002887000310E001AAF6
+:1071300024100004240E0001548EFF4B240740004D
+:107140000A0008AA240701003C05080024A557E806
+:107150000E000724240400828F92003C000030219E
+:107160000A0007EFAF86004C3C040800248457E86F
+:107170008CC200380E0007328CC3003C8F92003C5A
+:107180000A00094A00002021240400823C0508006E
+:1071900024A557E80E000724000000008F92003C51
+:1071A000000010210A0007EFAF82004C8E5000044F
+:1071B0008F91FDE83C0A8000AD500020922200052E
+:1071C000020028213046000214C001872404008AEE
+:1071D0008F92FDEC020028212404008D924B001BAD
+:1071E000316300201460018000000000922D00092E
+:1071F000240C001231A800FF110C017B2404008133
+:107200000E0006F6020020219245001B240E000409
+:107210000200202134A90042A249001B0E000700F1
+:10722000A22E00253C0480008C9101780620FFFEF0
+:1072300024180002AC900140A09801448F92003CB9
+:107240003C0F1000AC8F01780A0008F50013102BDA
+:107250008E5000048F91FDE83C1F8000AFF00020AD
+:1072600092390005020028213327000214E0001A99
+:107270002404008A922600092412001230C400FF60
+:10728000109201110000000092230009240A00045A
+:10729000306200FF104A010C000000000E0006F6EC
+:1072A000020020218F88FDEC240CFFFE020020212B
+:1072B000910E001B35CD0020A10D001BA23200094C
+:1072C000922B0005016C90240E000700A2320005ED
+:1072D00002002821000020210E0007BA0000000053
+:1072E0000A0008F48F92003C8E5100043C0280009A
+:1072F0003C100800261057E8AC5100203C01080063
+:10730000AC3157E89246000330C400041080016994
+:107310008F84FDE824020006A0820009924D001B24
+:107320002408FFC031AC003F01885825A08B00081D
+:1073300092430003306A0001154001600000000024
+:107340008E420008AE0200083C0208008C4257F052
+:107350001040015F8F8EFDEC000281C28F85FDE839
+:10736000A5D0000C8E5F000C240F0001240900142E
+:10737000ADDF002C8E590010ADD9001C96470016C9
+:10738000A5C7003C96580014A5D8003EACAF000C31
+:10739000A4AF0010A4AF0012A4AF0014A4AF001655
+:1073A00012600163A1C900119244000330920002EF
+:1073B0002E5300018F92003C266200080A0007EF5E
+:1073C000AF82004C8E4600043C0580003C048008DF
+:1073D000ACA600208E4700089089000024110050C0
+:1073E000312200FF105100BC240500883C048000BD
+:1073F0008C8F01B805E0FFFE0013802B3C1840097C
+:1074000000B81025AF90004C3C101000AC860180F5
+:10741000AC870184AC820188AC9001B80A0007F007
+:107420008F8600308E4500043C0680003C098008B1
+:10743000ACC50020913F00002404005033F900FF48
+:10744000132400B4240600883C0480008C8A01B810
+:107450000540FFFE3C0E400E00CE68253C081000A3
+:10746000AC850180AC800184AC8D0188AC8801B80A
+:10747000912B0000240CFF8024040004016C1825CB
+:10748000240600300E000666A12300000A0008F45E
+:107490008F92003C8E5000048F91FDEC3C0F8000D9
+:1074A000ADF000209225001B30A900101120007CB7
+:1074B000240300813C0480008C8701B804E0FFFEB7
+:1074C0003C1F401FAC900180007F10250013C82B8B
+:1074D0003C101000AC800184AF99004CAC82018854
+:1074E000AC9001B80A0007F08F8600308E44001C73
+:1074F0000E0006E100000000104000FC00403821B2
+:107500008F92003C240600893C0580008CAE01B8B7
+:1075100005C0FFFE00000000ACA701808E50001CDB
+:107520003C1140010013782B00D138253C1310008A
+:10753000ACB00184AF8F004CACA70188ACB301B8EC
+:107540000A0007F08F860030965900023C100800B0
+:10755000261057E833380004130000A73C046000ED
+:107560008E5F001C3C068000ACDF00203C01080060
+:10757000AC3F57E8964F000231E7000114E000E706
+:10758000000000008E420004AE0200083C1008001B
+:107590008E1057F0120000DD3C0680008F85FDE85C
+:1075A000241000018CBF00188F91FDEC8F89FDE441
+:1075B00003E6C825ACB90018A0A00005ACB0000CCB
+:1075C0003C1808008F1857F08F87003CA4B00010BB
+:1075D000001879C2A4B00012A4B00014A4B0001620
+:1075E000A62F000C8CEE00088F8D003C8F8C003C89
+:1075F000AE2E002C8DA8000C24070002AE28001C23
+:10760000918B0010A22B00118F83003C906A001117
+:10761000A12A00088F82003C90440012A0A4004ED2
+:107620008F92003C92460013A22600128F92003CDB
+:10763000965F0014A63F003C96590016A639003EFE
+:107640008E580018AE3800145660FD4CAF87004CC1
+:107650003C05080024A557E80E000705000020217E
+:107660008F92003C000038210A0007EFAF87004CE2
+:107670003C05080024A557E80E00072424040082D6
+:107680008F92003C0A0008D7000038210E000E0738
+:10769000000000008F92003C0A00094A00002021EF
+:1076A0000E0006F6020020219232001B020020216B
+:1076B000365800100E000700A238001B8F92003CC5
+:1076C0000A000A3D000018210E0007BA24040081B8
+:1076D0000A0008F48F92003C9243000C306A0001CB
+:1076E0001140000300000000964B000EA48B002CFC
+:1076F0009248000C310C00021180FF3C0000282150
+:10770000964E00128E4D0014A48E001A0A000A0B29
+:10771000AC8D001C8F83005C8F8700541067FF4A7C
+:10772000000030213C0808002508576C000320C0E9
+:10773000008830218CD10000122500C8246200018D
+:107740003043000F1467FFFA000320C00A000A222A
+:10775000000030213C05080024A557E80E0007244E
+:107760002404008B8F92003C0A0008D70013382BAA
+:107770003C0C08008D8C57E824D9FFFE25910100B0
+:10778000322B007F0167902102331024AD020028C4
+:10779000AE4600D0AE4000D40A000840AE59001CEE
+:1077A000ACC000543C0908008D2957E83C05800C0A
+:1077B00034A80100ACE900288E500014AD1000D0B0
+:1077C0008E4E0014AD0E00D48E4D001025A7FFFE86
+:1077D0000A00087CAD07001C5490FDA3240740005C
+:1077E0000A0008AA240710000E0007AE00000000DF
+:1077F0000A0008F48F92003C8C83442C3C05DEADDB
+:1078000034B2BEEF3C010800AC2057E81072004FC4
+:10781000000000003C046C6234827970146200083D
+:1078200024040002978A0058978300500200282100
+:107830000143482B11200019240400922404000263
+:107840000E0005D6240502003C0B8000AD6200202E
+:107850003C010800AC2257E81040000D8F8E003C20
+:10786000240C00282404000391CD001031A800FF4F
+:10787000550C0001240400010E00004A0000000025
+:1078800010400004240400830A000A6D8F92003C1B
+:10789000240400833C05080024A557E80E000705D2
+:1078A000000000008F92003C0013382B0A0007EF05
+:1078B000AF87004C0A0009D6240200128E4400084B
+:1078C0000E0006E1000000000A0009E2AE02000816
+:1078D0003C05080024A557E80E0006D524040087BF
+:1078E0008F92003C0A0009FF0013102B24040004AF
+:1078F0000E0005D624050030144000170040382142
+:107900008F92003C0A000A52240600833C050800BE
+:1079100024A557E80A000B37240400878E4400048E
+:107920000E0006E1000000000A000A73AE02000823
+:107930003C05080024A557E80E0007242404008213
+:107940008F92003C0A0009FF000010218C83442C18
+:107950000A000B163C046C628F92003C3C088008C5
+:107960003C0C8000240B0050240A0001AD82002052
+:10797000A10B0000A10A000192490004A10900180E
+:1079800092440005A1040019924300063C0408003B
+:107990002484576CA103001A924200073C0308009C
+:1079A00024635768A102001B92450008A105001C32
+:1079B00092460009A106001D925F000AA11F001E49
+:1079C0009259000BA119001F9258000CA118002019
+:1079D0009251000DA11100219250000EA110002221
+:1079E000924F000FA10F0023924E0010A10E002411
+:1079F000924D0011A10D0025964C0014A50C0028F5
+:107A0000964B00168F8A00548F98005CA50B002AB5
+:107A100096490018000A10C025450001A509002C50
+:107A20008E46001C0044C8210043F82130A5000FF9
+:107A3000AFE60000AF27000010B80003AF85005488
+:107A40000A000A520000302124AD000131A8000FC5
+:107A5000000030210A000A52AF88005C3C07080091
+:107A600024E7576800879021ACC000000000302157
+:107A70000A000A22AE4000003C0482013C03600080
+:107A800034820E02AC603D68AF80007C03E00008E9
+:107A9000AC623D6C27BDFFE8AFB000103090FFFF37
+:107AA000001018422C620041AFBF001414400002C5
+:107AB00024040080240300403C010800AC30006036
+:107AC0003C010800AC2300640E000E100060282169
+:107AD000244802BF2409FF800109282400103980AE
+:107AE000001030408FBF00148FB0001000A720217D
+:107AF00000861821AF8300643C010800AC250058C3
+:107B00003C010800AC24005C03E0000827BD00181D
+:107B1000308300FF30C6FFFF30E400FF3C088000E8
+:107B20008D0201B80440FFFE0003540001443825D3
+:107B30003C09600000E920253C031000AD050180F0
+:107B4000AD060184AD04018803E00008AD0301B86F
+:107B50008F86003C3C096012352700108CCB000456
+:107B60003C0C600E35850010316A00062D4800017E
+:107B7000ACE800C48CC40004ACA431808CC2000802
+:107B800094C30002ACA2318403E00008A783007410
+:107B90008F85003C8F87FF408F86FF488CAE0004A6
+:107BA0003C0F601235E80010ACEE00688CAD0008A8
+:107BB000ACED006C8CAC0010ACCC004C8CAB000C71
+:107BC000ACCB004894CA00543C0208008C420044EC
+:107BD00025490001A4C9005494C400543083FFFF18
+:107BE00010620017000000003C0208008C420040B8
+:107BF000A4C200528CA30018ACE300308CA2001485
+:107C0000ACE2002C8CB90018ACF900388CB8001428
+:107C100024050001ACF800348D0600BC50C50019E5
+:107C20008D0200B48D0200B8A4E2004894E400483C
+:107C3000A4E4004A94E800DA03E000083102FFFF00
+:107C40003C0208008C420024A4C00054A4C200528C
+:107C50008CA30018ACE300308CA20014ACE2002C22
+:107C60008CB90018ACF900388CB800142405000158
+:107C7000ACF800348D0600BC54C5FFEB8D0200B893
+:107C80008D0200B4A4E2004894E40048A4E4004A51
+:107C900094E800DA03E000083102FFFF8F86003C21
+:107CA0003C0480008CC900088CC80008000929C069
+:107CB000000839C0AC87002090C300073062000480
+:107CC0001040003AAF85007890CB0007316A000879
+:107CD000114000398F87FF448CCD000C8CCE0014EE
+:107CE00001AE602B11800032000000008CC2000C3D
+:107CF000ACE200708CCB00188F85FF408F88FF4866
+:107D0000ACEB00748CCA00102402FFF8ACAA00C8C7
+:107D10008CC9000CAD0900608CC4001CACA400C070
+:107D200090E3007C0062C824A0F9007C90D8000792
+:107D3000330F000811E000040000000090ED007C0B
+:107D400035AC0001A0EC007C90CF000731EE0001C3
+:107D500011C000090000000090E4007C241800021B
+:107D600034820002A0E2007C90A300EC307900FF96
+:107D7000133800132408003490C90007312600028C
+:107D800010C000040000000090EB007C356A000485
+:107D9000A0EA007C90ED007D31AC003FA0EC007DBE
+:107DA00094A700DA03E0000830E2FFFF8F87FF446A
+:107DB0000A000C4C8CC200140A000C4DACE00070A0
+:107DC0000A000C6EACA800CC8F8C003C27BDFFD8FD
+:107DD000AFB3001CAFB20018AFB00010AFBF0020AF
+:107DE000AFB10014918F00153C13600E3673001074
+:107DF00031EB000FA38B00808D8F00048D8B00086A
+:107E0000959F0012959900109584001A9598001E70
+:107E1000958E001C33EDFFFF332AFFFF3089FFFFF3
+:107E20003308FFFF31C7FFFF3C010800AC2D0024E1
+:107E30003C010800AC2900443C010800AC2A004089
+:107E4000AE683178AE67317C91850015959100164A
+:107E50003C1260123652001030A200FF3230FFFF99
+:107E6000AE623188AE5000B491830014959F001823
+:107E7000240600010066C80433F8FFFFAE5900B8BD
+:107E8000AE5800BC918E0014AF8F00683C086006AD
+:107E900031CD00FFAE4D00C0918A00159584000ED3
+:107EA0003C07600A314900FFAF8B006C3084FFFF54
+:107EB000AE4900C8351100100E000BB534F00410A7
+:107EC0003C0208008C4200603C0308008C630064A4
+:107ED0003C0608008CC600583C0508008CA5005CD8
+:107EE0008F8400648FBF0020AE23004CAE65319CB0
+:107EF000AE030054AE4500DCAE6231A0AE6331A4E7
+:107F0000AE663198AE2200488FB3001CAE0200501E
+:107F10008FB10014AE4200E0AE4300E4AE4600D89C
+:107F20008FB000108FB200180A0004BE27BD0028D1
+:107F3000978500769783006027BDFFE8AFB00010FB
+:107F400000A3102BAFBF0014240400058F90003C49
+:107F500010400055240900020E0005D68F850064EC
+:107F6000AF820078240400031040004F240900026F
+:107F70003C0680000E00004AACC20020240700012D
+:107F8000240820001040004D24040005978E007640
+:107F90008F8AFF442409005025C50001A78500767B
+:107FA000A14900003C0D08008DAD00642403800051
+:107FB0008F84FF40000D6600AD4C0018A540000600
+:107FC000954B000A8F85FF482402FF80016330240F
+:107FD000A546000A915F000A0000482103E2C82577
+:107FE000A159000AA0A00008A140004CA08000C533
+:107FF00096180002978300743C020004A49800DAEB
+:10800000960F00022418FFBF25EE2401A48E00AEB7
+:108010008E0D0004ACAD00448E0C0008ACAC0040EA
+:10802000A4A00050A4A000548E0B000C240C00301F
+:10803000AC8B00288E060010AC860024A480003E85
+:10804000A487004EA4870050A483003CAD42007476
+:10805000AC8800C8ACA80060A08700EC909F00C46A
+:1080600033F9007FA09900C4909000C402187824CE
+:10807000A08F00C4914E007C35CD0001A14D007C45
+:10808000938B0080AD480070AC8C00CCA08B00C6F8
+:108090008F88006C8F870068AC8800B4AC8700B80C
+:1080A000A5400078A540007A8FBF00148FB0001063
+:1080B0000120102103E0000827BD00188F850078FB
+:1080C0000E0006668F8600640A000D3A240900023D
+:1080D00027BDFFE0AFB000108F90003CAFB100149F
+:1080E000AFBF00188E0900040E00048B000921C0E8
+:1080F0008E0800048F84FF408F82FF48000839C03B
+:108100003C068000ACC70020948500DA9043001341
+:108110001460001C30B1FFFF8F8CFF44918B00086E
+:10812000316A00401540000B000000008E0D000475
+:10813000022030218FBF00188FB100148FB00010C3
+:108140002404002200003821000D29C00A000BD4AD
+:1081500027BD00200E000061000000008E0D00040D
+:10816000022030218FBF00188FB100148FB0001093
+:108170002404002200003821000D29C00A000BD47D
+:1081800027BD00200E000059000000008E0D0004E5
+:10819000022030218FBF00188FB100148FB0001063
+:1081A0002404002200003821000D29C00A000BD44D
+:1081B00027BD002027BDFFE0AFB200183092FFFFBF
+:1081C000AFB00010AFBF001CAFB100141240001ED2
+:1081D000000080218F86003C8CC50000240300062F
+:1081E00000053F020005140230E400071483001666
+:1081F000304500FF2CA80006110000400005588003
+:108200003C0C0800258C54EC016C50218D49000079
+:1082100001200008000000008F8E007C240D00016A
+:1082200011CD005024020002AF82007C260900011B
+:108230003130FFFF24C800200212202B0100302122
+:108240001480FFE5AF88003C020010218FBF001CA6
+:108250008FB200188FB100148FB0001003E0000837
+:1082600027BD00209387006254E0003400003021D5
+:108270000E000C82000000008F86003C0A000D9A60
+:10828000240200018F87007C2405000210E50031E4
+:1082900024040013000028210000302124070001DD
+:1082A0000E000BD4000000000A000D9B8F86003CDE
+:1082B0008F83007C240200021462FFF62404001263
+:1082C0000E000C37000000008F8500780040302140
+:1082D000240400120E000BD4000038210A000D9B6C
+:1082E0008F86003C8F83007C2411000310710029CD
+:1082F000241F0002107FFFCE260900012404001075
+:1083000000002821000030210A000DB824070001D8
+:108310008F91007C240600021626FFF92404001029
+:108320000E000CDC00000000144000238F98003C7D
+:108330008F86003C0A000D9A2402000324040014D6
+:108340000E000BD4000028218F86003C0A000D9AF5
+:10835000240200020E000D44000000000A000D9BE4
+:108360008F86003C0E000BE4000000002419000280
+:1083700024040014000028210000302100003821CE
+:10838000AF99007C0E000BD4000000000A000D9B8A
+:108390008F86003C0E000BF4000000008F850078F3
+:1083A000241900020040302124040010000038216C
+:1083B0000A000DF1AF99007C004038212404001020
+:1083C000970F0002000028210E000BD431E6FFFFBA
+:1083D0008F86003C0A000D9BAF91007C8F84FF4488
+:1083E0003C077FFF34E6FFFF8C8500182402000164
+:1083F00000A61824AC83001803E00008A082000542
+:108400003084FFFF30A5FFFF108000070000182117
+:108410003082000110400002000420420065182153
+:108420001480FFFB0005284003E0000800601021D5
+:1084300010C00007000000008CA2000024C6FFFF4F
+:1084400024A50004AC82000014C0FFFB24840004B7
+:1084500003E000080000000010A0000824A3FFFFB4
+:10846000AC86000000000000000000002402FFFFB6
+:108470002463FFFF1462FFFA2484000403E0000871
+:1084800000000000000411C003E000082442024084
+:1084900027BDFFE8AFB0001000808021AFBF0014FF
+:1084A0000E000E3100A0202100504821240AFF8038
+:1084B0008FBF00148FB00010012A30243127007FB5
+:1084C0003C08800A3C04210000E8102100C4282553
+:1084D0003C03800027BD0018AC650024AF8200205B
+:1084E000AC400000AC65002403E00008AC40004054
+:1084F0003C0D08008DAD005800056180240AFF8006
+:1085000001A45821016C4821012A30243127007F21
+:108510003C08800C3C04210000E8102100C4282500
+:108520003C038000AC650028AF82001C03E000081B
+:10853000AC40002430A5FFFF3C0680008CC201B88F
+:108540000440FFFE3C08601500A838253C031000DD
+:10855000ACC40180ACC00184ACC7018803E0000852
+:10856000ACC301B83C0D08008DAD0058000561801A
+:10857000240AFF8001A45821016C4021010A4824EB
+:10858000000931403107007F00C728253C04200046
+:1085900000A418253C028000AC43083003E000082A
+:1085A000AF80001C27BDFFE8AFB000100080802125
+:1085B000AFBF00140E000E3100A020210050482152
+:1085C000240BFF80012B5024000A39403128007F02
+:1085D0003C0620008FBF00148FB0001000E8282553
+:1085E00034C2000100A218253C04800027BD0018F9
+:1085F000AC83083003E00008AF8000203C05800811
+:108600008CA700603C0680080087102B14400011E6
+:108610002C8340008CA800602D0340001060000FE8
+:10862000240340008CC900600089282B14A000029C
+:10863000008018218CC3006000035A42000B308078
+:108640003C0A0800254A554000CA202103E00008E2
+:108650008C8200001460FFF32403400000035A42A0
+:10866000000B30803C0A0800254A554000CA2021F2
+:1086700003E000088C8200003C05800890A60008FA
+:108680009384009024C20001304200FF3043007FF9
+:108690001064000C00023827A0A200083C048000EF
+:1086A0008C85017804A0FFFE8F8A008824090002CF
+:1086B0003C081000AC8A0140A089014403E0000896
+:1086C000AC8801780A000EB630E2008027BDFFC8F2
+:1086D0003C05800834A40080AFBF0034AFBE00303A
+:1086E000AFB7002CAFB60028AFB50024AFB4002060
+:1086F000AFB3001CAFB20018AFB10014AFB00010A0
+:10870000948300789482007A104300CD2405FFFF03
+:108710003C1E80080080B8210A000F923C168000A1
+:10872000108A00C88FBF00348F8400883C0B08007B
+:108730008D6B005C240AFF803C07800E01644021A1
+:10874000010A4824AEC9002C96E6007A3102007F67
+:108750000047182130C57FFF000580400203A82193
+:1087600096BF00003C1908008F390058240FFF8085
+:1087700033F53FFF032488210015C1800238902182
+:10878000024F58243C0C0100016C5025324E007FF2
+:108790003C0D800C01CD9021028028210E000E346A
+:1087A000AECA00288E4800108E4900308F86002007
+:1087B0002402000201093823AE470010A0C20000C5
+:1087C00096E3005C8E4400308F9100200E000E8FE7
+:1087D0003070FFFF00022B800205C8253C1F4200BD
+:1087E000033FC025AE3800048E5100048F8700205F
+:1087F0008E4F000024080008ACF1001CACEF0018FC
+:10880000ACE0000CACE000109250000A2406000519
+:108810002405C000320E00FFA4EE0014964D00089F
+:1088200002E09821A4ED0016924C000A3C0D80084D
+:10883000318B00FFA4EB00209644000835AC01000A
+:10884000A4E40022ACE00024924A000B314900FF6E
+:10885000A4E90002A0E800018E4200308F830020CE
+:108860002408FFBFAC620008A06600308F8E002095
+:108870002403FFDF95DF003203E5C8240335C0255C
+:10888000A5D8003291D10032322F003F35F00040A0
+:10889000A1D000328F890020AD2000348D8B00C024
+:1088A000AD2B00389124003C3C0B7FFF308A007FC9
+:1088B000A12A003C8F8600203564FFFF90C7003C52
+:1088C00000E81024A0C2003C8F9900209325003CB2
+:1088D00000A3F824A33F003C8E5800348F8C002066
+:1088E000AD9800408E4F002C8E51003001F1802356
+:1088F000AD900044918E004831CD007FA18D00489D
+:108900008F8500208E4A00308CA900480144402405
+:108910000136382400E83025ACA600489242000A0F
+:10892000A0A2004C964300088F9F0020A7E3004EB2
+:108930008E5000308E4400300E0002F08FC5006073
+:1089400092F1007C0002C1400002C90003197821A5
+:10895000322E00020040282111C00003020F8021A6
+:108960000002208002048021926D007C31AC000462
+:108970001180000200057080020E80218E440030BC
+:108980008F87002024058000308B0003000B5023CC
+:108990003149000302094021ACE800349664007AB2
+:1089A0009662007A9670007A30467FFF24C30001F9
+:1089B000307F7FFF0205C824033FC025A678007AD8
+:1089C0009671007A3C1208008E520060322F7FFFB1
+:1089D00011F20028000000008F8400880E000E694C
+:1089E00002A028218F8400880E000E7902802821A1
+:1089F0000E000EAE0000000096F3007896F4007AA8
+:108A00001293000F000028213C0980083524010042
+:108A100093C80008908700C53114007F30E400FF40
+:108A20000284302B14C0FF3E268A0001938D0090F3
+:108A3000268B0001008D6021158BFF3C8F84008800
+:108A40008FBF00348FBE00308FB7002C8FB6002848
+:108A50008FB500248FB400208FB3001C8FB2001894
+:108A60008FB100148FB0001000A0102103E00008A7
+:108A700027BD0038967F007A03E5C824A679007ADE
+:108A80009278007A926E007A331100FF001179C259
+:108A9000000F9027001269C031CC007F018D28257E
+:108AA000A265007A0A000F878F8400883C0380004B
+:108AB0003084FFFF30A5FFFFAC640018AC65001CDC
+:108AC00003E000088C62001427BDFFA83C06800864
+:108AD000AFBF0054AFBE0050AFB7004CAFB60048B8
+:108AE000AFB50044AFB40040AFB3003CAFB2003804
+:108AF000AFB10034AFB0003034C80100910500C5FB
+:108B000090C700083084FFFF30A500FF30E2007FEF
+:108B10000045182AAFA40010A7A000181060009C00
+:108B2000AFA0001490CA00083149007F00A930238B
+:108B300024D4FFFF0014882B8FB300100013902B58
+:108B400002328024520000858FB400143C03800858
+:108B500094790052947E00508FB60010033EC023DB
+:108B60000018BC00001714030016FC0002C2A82A5B
+:108B700016A00002001F2C030040282100143C0016
+:108B80000007240300A4102A5440000100A0202163
+:108B90002885000914A000020080B02124160008D6
+:108BA0003C0C80088D860048001659808D88004C4A
+:108BB0003C0380003169FFFF3C0A0010012A202598
+:108BC00034700400AC660038AF90008CAC68003C98
+:108BD000AC64003000000000000000000000000055
+:108BE0000000000000000000000000000000000085
+:108BF000000000008C6E000031CD002011A0FFFDB0
+:108C00000016902A0251782411E000360000B821A5
+:108C10003C1580003C118008922200088EA40100BF
+:108C200000008821305E007F0E000E3403C0282132
+:108C30008E1F00108EA4010033F93FFF032028216E
+:108C40000E000E4CAFB9001C921800003302003F1A
+:108C50002C5300085260000D000080212405000103
+:108C6000004518043067005D14E000B18F92008C5D
+:108C7000306400021480014D8F86008C30680080C3
+:108C80005500004A96180012000080218EA40100B1
+:108C90000E000E698FA5001C8EA401000E000E7937
+:108CA00003C028211200004F3C07800826E4000181
+:108CB0008F8C008C0004BC000291A0230017BC0321
+:108CC00002F6302A0014882B259F00402412000150
+:108CD00000D1F02403E08021AF9F008C17C0FFCDAE
+:108CE000AFB200143C07800894E800508FB3001026
+:108CF0003C05800002E810213C0D0020A4E2005059
+:108D0000ACAD003094F5005094F600520277502339
+:108D10003149FFFF12D50041AFA900108CF6004C7D
+:108D2000001749808CF7004802C9F8210000202173
+:108D300003E9302B02E4602101868021ACFF004C66
+:108D4000ACF000488FB300100013902B0232802447
+:108D50001600FF7F3C0380088FB400148FBF0054BF
+:108D60008FBE00503A8200018FB7004C8FB600488A
+:108D70008FB500448FB400408FB3003C8FB20038F1
+:108D80008FB100348FB0003003E0000827BD0058D9
+:108D900090CF0008938C009031EE007F00AE6823E6
+:108DA000018D58210A000FDD2574FFFF8F84008894
+:108DB00024100001A7B800180E000E5D97A500183A
+:108DC0008EA401000E000E698FA5001C8EA4010068
+:108DD0000E000E7903C028211600FFB526E400011D
+:108DE0003C07800894E800508FB300103C058000D9
+:108DF00002E810213C0D0020A4E20050ACAD003090
+:108E000094F5005094F60052027750233149FFFF49
+:108E10000014882B16D5FFC1AFA9001094FE005492
+:108E20008CF0004433D8FFFE001878C0020F702188
+:108E3000ACAE003C8CF900448CA3003C03235823C7
+:108E4000196002EA000000008CF200402642000196
+:108E5000ACA200383C05005034A700103C03800051
+:108E6000AC670030000000000000000000000000BF
+:108E700000000000000000000000000000000000F2
+:108E8000000000008C7F000033E6002010C0FFFDD2
+:108E90003C108008960D00543C1780003C0680086A
+:108EA00031B30001001350C00157B0218EC9040036
+:108EB0003C0708008CE700443C040020ACC9004893
+:108EC0008ED50404240C0001ACD5004C10EC02D06B
+:108ED000AEE40030961800523C0508008CA5004016
+:108EE00000B87821A60F0052960E005425C3000149
+:108EF000A6030054961900543324FFFF5487FF0F34
+:108F00008FB3001030A5FFFF0E000FBBA60000546A
+:108F10003C0508008CA50024961200520045382319
+:108F20000247F023A61E00520A000FDF8FB3001085
+:108F30008F93001C3C0700808E4400283C1FFFEFED
+:108F400037F9FFFFAE6400008E420024A260000AE1
+:108F50003C0FFF9FAE6200049245002C35EEFFFFF0
+:108F60003C0C0040A265000C8E71000CA265000B49
+:108F70003C0600FF0227C0250319682401AE5824CF
+:108F8000016C5025AE6A000C8E490004AE600018DA
+:108F900034D0FFFFAE6900148E48002C8F82008809
+:108FA000A660000801102024AE6400108E51000855
+:108FB00096470012AE7100208E58000C30E33FFF40
+:108FC00000032980AE7800248E4C001400A2F82102
+:108FD00030F90001AE6C00288E4B0018001F71C2E2
+:108FE00000197B80AE6B002C8E49001C01CF6821DC
+:108FF000A66D001CAE690030964A00028E46002025
+:10900000A66A001EAE66003492430033307000043E
+:1090100056000006924B00003C06800834D0010048
+:109020008E0800C0AE680030924B00008F8A00208E
+:10903000A14B0030924900333123000250600007F9
+:10904000924400018F8C0020240FFF80918E00300D
+:1090500001CF6825A18D0030924400018F8200204D
+:109060002418FFBF240AFFDFA04400318F9900209D
+:109070003C088008350400809331003C323F007F7B
+:10908000A33F003C8F8D002091AF003C01F870247D
+:10909000A1AE003C8F8700208E6C001490E3003C52
+:1090A0002D8B0001000B4940006A302400C9802547
+:1090B000A0F0003C964500128F870020A4E5003206
+:1090C0008E450004909F007C30A20003000288239C
+:1090D0003239000300B9102133F8000217000002F2
+:1090E00024440034244400303C038008346600806B
+:1090F00090C9007C00A980243208000415000002F9
+:1091000024830004008018218F840020240800029A
+:10911000ACE30034A08800009242003F8F9F002003
+:109120003C188008370F0080A3E200018F910020D7
+:109130009259003F8E440004A639000295EE005C6F
+:109140000E000E8F31D0FFFF00026B80020D5825FC
+:109150003C0C4200016C2825AE2500048E4A0038E4
+:109160008F850020ACAA00188E470034ACA7001CE5
+:10917000ACA0000CACA00010A4A00014A4A0001689
+:10918000A4A00020A4A00022ACA000248E620014A1
+:109190005040000124020001ACA200080E000EAEF7
+:1091A000241100010A0010332410000190D30001A3
+:1091B000327200201240018A241000013C0A80080B
+:1091C0003547008090E3007C8F93001CAFA0002403
+:1091D0003069000111200011AFB000203C0580086B
+:1091E0008CCB00148CAC0060016C882B1620000323
+:1091F000016028213C1080088E0500603C0F80082B
+:1092000035E300808C6E007000AE682B15A0000264
+:1092100000A020218C640070AFA400248F82FF4C3A
+:109220008CC400148C5900700099C02B53000001AD
+:109230008C4400708FA200240082F82313E0000306
+:10924000AFBF002824040002AFA400208FB200208A
+:109250000292402B1500015B000018218CC50038DC
+:109260008E6B000C3C0C0080AE6500008CC9003495
+:109270003C11FF9F016C5025AE69000490C8003F6F
+:109280003623FFFF014310243C1200203C04FFEF73
+:10929000A268000B00523825349FFFFF00FFC02456
+:1092A0003C1900088F87008C03197825AE6F000CDD
+:1092B0008CED0014AE6000188FB10024AE6D001468
+:1092C0008CF000188FAE0028AE70001C8CE50008F2
+:1092D000022E6021AE6500248CEB000CA6600038E5
+:1092E000A660003AAE6C002CAE600028AE6B002089
+:1092F0008CEA00148FA30028015148230123302356
+:1093000010C00011AE66001090E9003D8E620004AE
+:109310008E7F00000009910000527821000020217A
+:1093200001F2C82B03E4C02103197021AE6F0004C1
+:10933000AE6E000090ED003DA26D000A8F90008C93
+:1093400096060006A66600088F98002024190002E1
+:109350003C0F80088FA4002435EE0080A319000084
+:1093600095CD005C8F9200200E000E8F31B0FFFF74
+:1093700000022B80020560253C0642008F85008C90
+:1093800001865825AE4B00048F8400208CB1003834
+:10939000AC9100188CA30034AC83001CAC80000C92
+:1093A000AC800010A4800014A4800016A4800020CB
+:1093B000A4800022AC80002490AA003F8FA7002444
+:1093C000A48A000210E0000C240900018FBF0028CD
+:1093D00053E0018890A2003D90A2003E2448000185
+:1093E000A08800018F8500208FA40024ACA4000871
+:1093F0000A0012133C118008A08900018F8500200B
+:1094000024020001ACA200083C1180083623008031
+:10941000906A007C3147000214E000022406003408
+:10942000240600308F8D008C3C0F800835EE0080C4
+:1094300091AC000091C8007C8FB00024A0AC00303B
+:109440008F91008C8F8200208FAA00249227000128
+:1094500032120003240B0004A047003101721823CC
+:109460008F84008C8F8B0020241FC00094980012E2
+:109470009579003230690003330F3FFF033F7024BA
+:1094800001CF6825A56D00329165003200CA3021F8
+:1094900000C9302130B0003F360C0040A16C0032D2
+:1094A0008FB2002431070004124000028F85002093
+:1094B00000C730213C048008ACA600343488010089
+:1094C0008D1900C08FBF0024240DFFBFACB9003838
+:1094D00090AF003C2FF800012412FFDF31EE007F37
+:1094E000A0AE003C8F8B0020001889409170003C9A
+:1094F000020D6024A16C003C8F87002090E3003CAB
+:109500000072502401511025A0E2003C8F88008C8D
+:109510008F9900208D090020AF2900408D0600247E
+:10952000AF2600448D040028AF2400488D1F002C76
+:10953000AF3F004C0E000EAE000000008FB80020C0
+:10954000240500025705009F8FA300203C1F8000C8
+:109550003C1280088FE40100925800088F92FF4C63
+:109560000E000E343305007F8F8E00208FAF002059
+:109570008FA40028A1CF00009659005C8F91002095
+:109580000E000E8F3330FFFF00025B80020B682558
+:109590003C0842008F8B008C01A83025AE260004C9
+:1095A0008D7000388F8600200000282100051100F2
+:1095B000ACD000188D6C00343C047FFF3488FFFF72
+:1095C000ACCC001C9171003E8CCA001C8CDF0018D2
+:1095D0000011390000111F02014770210043482586
+:1095E00001C7C02B03E9782101F8C821ACCE001CCB
+:1095F000ACD90018ACC0000CACC00010916D003E9E
+:109600008FAA002824070005A4CD0014957000043B
+:109610002418C0000148C824A4D00016916C003E54
+:1096200001402021A4CC002095650004A4C500229F
+:10963000ACC000249163003FA4C300029171003DBF
+:1096400026220001A0C200018F8900203C02800870
+:1096500034460100AD2A0008A12700308F91002078
+:109660008F9F008C2402FF80962F003297EE00120D
+:10967000030F802431CD3FFF020D6025A62C003260
+:10968000922500322418FFBF2410FFDF30AB003FCB
+:1096900035630040A22300328F9F00202403FFFF88
+:1096A000AFE000348CCA00C0AFEA003893E7003C5A
+:1096B00030E9007FA3E9003C8F8D00203C09800049
+:1096C00091AF003C01F87024A1AE003C8F8B0020CC
+:1096D000916C003C01902824A165003C8F870020FC
+:1096E000ACE300408FB100243C038008ACF100449F
+:1096F00090EA004801423025A0E600488F90002003
+:109700008F8E008C8E1F004803E9C0240319782532
+:10971000AE0F004891CD003EA20D004C8F8C008C06
+:109720008F8B002095850004A565004E0E0002F089
+:109730008C650060924A007C004028218FA600289A
+:109740000002114000058900005138213149000212
+:109750001120000300C71821000520800064182193
+:109760003C028008344A00809147007C30E90004C4
+:10977000112000038FB9002800056080006C1821BB
+:10978000240B00048F91002033300003017040232C
+:10979000310D0003006D3021AE2600343C038008FB
+:1097A000A66500383C0580008CA401009073000879
+:1097B0000E000E793265007F0E000EAE0000000034
+:1097C0008FA300200003782B000F80230290A02499
+:1097D00000608021006088210A0010330010802B77
+:1097E0008F91001C8CD8003824190003A620000893
+:1097F000AE3800008CCF0034A220000A8F8E008C7F
+:10980000AE2F00043C05008091CB003FA239000C34
+:109810008E28000C3C0DFF9FA22B000B010510258C
+:1098200035A3FFFF3C13FFEF8F8E008C00433824DD
+:10983000366AFFFF00EA4824AE29000C8DC40014EC
+:1098400095D800128F860088AE2400108DCC0014AD
+:10985000AE200018AE200020AE2C0014AE20002454
+:109860008DDF0018330C3FFF000C9180AE3F0028C5
+:109870008DCF00080246C821330B0001AE2F003007
+:109880008DC3000C8F930020001941C2000B2B8068
+:1098900001056821240200023C0A8008A62D001C54
+:1098A000A6200034AE23002C35470080A2620000C1
+:1098B00094E9005C8F9900203C044200313FFFFF97
+:1098C00003E43025AF2600048F98008C240E00019D
+:1098D0002402C0008F12003824060034AF32001872
+:1098E0008F0F00343C12800836580080AF2F001CC8
+:1098F000AF20000CAF200010A7200014A7200016F6
+:10990000A7200020A7200022AF200024A7300002BB
+:10991000A32E00018F8D00208F8B008CADB000082E
+:1099200091680000A1A800308F91008C8F830020E7
+:1099300092250001A06500318F9F002097F300322F
+:1099400002625024014C3825A7E7003293E9003227
+:109950003124003FA3E40032930F007C31EE00027B
+:1099600015C000028F840020240600303C0E8008C1
+:10997000AC86003435D101008E3900C02403FFBF0E
+:1099800002008821AC990038908B003C0010802B9D
+:109990003165007FA085003C8F8D002091A8003CA0
+:1099A00001031024A1A2003C8F87002090F3003C0B
+:1099B000366A0020A0EA003C8F9F008C8F92002026
+:1099C0008FE90020AE4900408FE40024AE440044FB
+:1099D0008FEC0028AE4C00488FE6002C0E000EAE37
+:1099E000AE46004C0A001033000000000A0010A42C
+:1099F0008CE2004024480001A08800018F850020EF
+:109A00008FA40024ACA400080A0012133C118008A3
+:109A100094CB00523C0808008D080024010B102153
+:109A2000A4C200520A000FDF8FB3001027BDFFE071
+:109A30003C0D8008AFB20018AFB00010AFBF001CE3
+:109A4000AFB1001435B200808E4C001835A801006B
+:109A5000964B000695A70050910900EC000C5602A9
+:109A6000016728233143007F312600FF24020003D1
+:109A7000A3830090AF84008810C2001B30B0FFFFAA
+:109A8000910600EC2412000530C200FF1052003392
+:109A900000000000160000098FBF001C8FB20018E4
+:109AA0008FB100148FB00010240D0C003C0C80000E
+:109AB00027BD002003E00008AD8D00240E000FC27A
+:109AC000020020218FBF001C8FB200188FB100143C
+:109AD0008FB00010240D0C003C0C800027BD00202E
+:109AE00003E00008AD8D0024965800789651007A66
+:109AF000924E007D0238782631E8FFFF31C400C065
+:109B0000148000092D11000116000037000000002C
+:109B10005620FFE28FBF001C0E000EC300000000A5
+:109B20000A0013B78FBF001C1620FFDA00000000E8
+:109B30000E000EC3000000001440FFD88FBF001CB1
+:109B40001600002200000000925F007D33E2003F1B
+:109B5000A242007D0A0013B78FBF001C950900DAEE
+:109B60008F86006400802821240400050E0006660C
+:109B70003130FFFF978300763C0480002465FFFFAF
+:109B8000A78500768C8A01B80540FFFE0000000022
+:109B9000AC8001808FBF001CAC9001848FB2001894
+:109BA0008FB100148FB000103C0760133C0B100005
+:109BB000240D0C003C0C800027BD0020AC870188E0
+:109BC000AC8B01B803E00008AD8D00240E000FC27D
+:109BD000020020215040FFB18FBF001C925F007D2A
+:109BE0000A0013E433E2003F0E000FC202002021FE
+:109BF0001440FFAA8FBF001C1220000700000000C5
+:109C00009259007D3330003F36020040A242007D71
+:109C10000A0013B78FBF001C0E000EC30000000027
+:109C20005040FF9E8FBF001C9259007D3330003F93
+:109C30000A00141336020040000411C003E00008BB
+:109C4000244202403C050006008510253C038000AC
+:109C5000AC620030000000000000000000000000C6
+:109C60003C0580008CA7000030E6001010C0FFFD0E
+:109C7000000000008CAB003C8CAA003C0164482131
+:109C8000012A402B110000043C0680008CAD0038F6
+:109C900025AC0001ACAC00388CCF003C01E4702155
+:109CA00003E00008ACCE003C27BDFFD0AFB20018E7
+:109CB000AFB00010AFBF0028AFB50024AFB4002094
+:109CC000AFB3001CAFB1001400A0902114A000128B
+:109CD000008080218F8200240002188014600037E9
+:109CE000240400100E001421000000008FBF002883
+:109CF0008FB500248FB400208FB3001C8FB20018E2
+:109D00008FB100148FB000100000102127BD00306B
+:109D100003E00008AF80002410A0001E000088218E
+:109D20003C138000241400200A0014603C15000538
+:109D3000263100040232502B11400017024010213E
+:109D40008F8800248E0700002404008000084880CB
+:109D50000133182125060001AC6704002610000419
+:109D600014D4FFF3AF8600240E001421000000007D
+:109D7000AE75003000000000000000000000000090
+:109D800000000000263100040232502B1540FFEC89
+:109D9000AF800024024010218FBF00288FB500241F
+:109DA0008FB400208FB3001C8FB200188FB1001445
+:109DB0008FB0001003E0000827BD0030000320230F
+:109DC0003085000F0A0014490065202127BDFFD807
+:109DD0003C03800000A03821AC670038AFB100140C
+:109DE000AC66003C008088213C060022AC66003056
+:109DF000AFB00010AC7100283C10800C3C04800C0B
+:109E000024050070AFBF0024AFB40020AFB3001C26
+:109E10000E00143AAFB20018260400800E00143A67
+:109E200024050080260401000E00143A240500F0E9
+:109E30003C0208008C4200641040001300008021A6
+:109E40003C1480002413FF803C12800C0E00141E72
+:109E50000200202100514821312A007F0133402493
+:109E60000152202124050050AE8800280E00143A2B
+:109E7000261000013C0508008CA500640205202B7B
+:109E80001480FFF2000000003C0608008CC6006051
+:109E900010C00015000080213C1480002413FF80B6
+:109EA0003C12800C3C1908008F3900580010C1800A
+:109EB000240500400331782101F8682131AE007F8C
+:109EC00001B3602401D22021AE8C00280E00143A88
+:109ED000261000013C0608008CC600600206582BC4
+:109EE0001560FFF0000000003C1008008E10005CC0
+:109EF0002414FF803C1F800C0211982102749024CE
+:109F00003262007F3C118000005F2021AE320028C9
+:109F10000E00143A000628408FBF00248FB40020A2
+:109F20008FB3001C8FB200188FB100148FB00010D7
+:109F300000002021000028210A00143A27BD002833
+:109F40008F83003C8C62000410400003000000007E
+:109F500003E00008000000008C6400108C6500081D
+:089F60000A0014838C66000C5A
+:089F6800000000000000001BD6
+:109F70000000000F0000000A0000000800000006BA
+:109F800000000005000000050000000400000004BF
+:109F900000000003000000030000000300000003B5
+:109FA00000000003000000020000000200000002A8
+:109FB0000000000200000002000000020000000299
+:109FC0000000000200000002000000020000000289
+:109FD0000000000200000002000000020000000279
+:0C9FE00000000001000000010000000172
+:049FEC0080080100E8
+:109FF0008008008080080000080017900800179073
+:10A00000080017C8080017C8080017DC080017ACBC
+:10A0100008001A04080019D008001A5C08001A5C2D
+:10A0200008001AE408001A148008024008002154AD
+:10A0300008001FA00800217C0800221408002364E7
+:10A04000080023B0080024D4080023DC08002460A2
+:10A0500008002010080029880800292C08001FBCCF
+:10A0600008001FBC08001FBC080025480800254840
+:10A0700008001FBC08001FBC0800280408001FBC03
+:10A0800008001FBC08001FBC08001FBC0800286493
+:10A0900008001FBC08001FBC08001FBC08001FBC34
+:10A0A00008001FBC08001FBC08001FBC08001FBC24
+:10A0B00008001FBC08001FBC08001FBC08001FBC14
+:10A0C00008001FBC08001FBC080023D008001FBCEC
+:10A0D00008001FBC080028D408001FBC08001FBCD3
+:10A0E00008001FBC08001FBC08001FBC08001FBCE4
+:10A0F00008001FBC08001FBC08001FBC08001FBCD4
+:10A1000008001FBC08001FBC08001FBC08001FBCC3
+:10A1100008001FBC08001FBC08001FBC080027283F
+:10A1200008001FBC08001FBC08002690080025EC92
+:10A130000800375008003724080036F0080036C4FD
+:10A14000080036A408003658800801008008008006
+:08A15000800800008008008077
+:08A158000A000C760000000073
+:10A16000000000000000000D727870342E362E3191
+:10A17000360000000406100300000000000000018B
+:10A1800000000000000000000000000000000000CF
+:10A1900000000000000000000000000000000000BF
+:10A1A00000000000000000000000000000000000AF
+:10A1B000000000000000000000000000000000009F
+:10A1C000000000000000000000000000000000008F
+:10A1D000000000000000000000000000000000007F
+:10A1E000000000000000000000000000000000006F
+:10A1F000000000000000000000000000000000005F
+:10A20000000000000000000000000000000000004E
+:10A21000000000000000000000000000000000003E
+:10A22000000000000000000000000000000000002E
+:10A23000000000000000000000000000000000001E
+:10A24000000000000000000000000000000000000E
+:10A2500000000000000000000000000000000000FE
+:10A2600000000000000000000000000000000000EE
+:10A2700000000000000000000000000000000000DE
+:10A2800000000000000000000000000000000000CE
+:10A2900000000000000000000000000000000000BE
+:10A2A00000000000000000000000000000000000AE
+:10A2B000000000000000000000000000000000009E
+:10A2C000000000000000000000000000000000008E
+:10A2D000000000000000000000000000000000007E
+:10A2E000000000000000000000000000000000006E
+:10A2F000000000000000000000000000000000005E
+:10A30000000000000000000000000000000000004D
+:10A31000000000000000000000000000000000003D
+:10A32000000000000000000000000000000000002D
+:10A33000000000000000000000000000000000001D
+:10A34000000000000000000000000000000000000D
+:10A3500000000000000000000000000000000000FD
+:10A3600000000000000000000000000000000000ED
+:10A3700000000000000000000000000000000000DD
+:10A3800000000000000000000000000000000000CD
+:10A3900000000000000000000000000000000000BD
+:10A3A00000000000000000000000000000000000AD
+:10A3B000000000000000000000000000000000009D
+:10A3C000000000000000000000000000000000008D
+:10A3D000000000000000000000000000000000007D
+:10A3E000000000000000000000000000000000006D
+:10A3F000000000000000000000000000000000005D
+:10A40000000000000000000000000000000000004C
+:10A41000000000000000000000000000000000003C
+:10A42000000000000000000000000000000000002C
+:10A43000000000000000000000000000000000001C
+:10A44000000000000000000000000000000000000C
+:10A4500000000000000000000000000000000000FC
+:10A4600000000000000000000000000000000000EC
+:10A4700000000000000000000000000000000000DC
+:10A4800000000000000000000000000000000000CC
+:10A4900000000000000000000000000000000000BC
+:10A4A00000000000000000000000000000000000AC
+:10A4B000000000000000000000000000000000009C
+:10A4C000000000000000000000000000000000008C
+:10A4D000000000000000000000000000000000007C
+:10A4E000000000000000000000000000000000006C
+:10A4F000000000000000000000000000000000005C
+:10A50000000000000000000000000000000000004B
+:10A51000000000000000000000000000000000003B
+:10A52000000000000000000000000000000000002B
+:10A53000000000000000000000000000000000001B
+:10A54000000000000000000000000000000000000B
+:10A5500000000000000000000000000000000000FB
+:10A5600000000000000000000000000000000000EB
+:10A5700000000000000000000000000000000000DB
+:10A5800000000000000000000000000000000000CB
+:10A5900000000000000000000000000000000000BB
+:10A5A00000000000000000000000000000000000AB
+:10A5B000000000000000000000000000000000009B
+:10A5C000000000000000000000000000000000008B
+:10A5D000000000000000000000000000000000007B
+:10A5E000000000000000000000000000000000006B
+:10A5F000000000000000000000000000000000005B
+:10A60000000000000000000000000000000000004A
+:10A61000000000000000000000000000000000003A
+:10A62000000000000000000000000000000000002A
+:10A63000000000000000000000000000000000001A
+:10A64000000000000000000000000000000000000A
+:10A6500000000000000000000000000000000000FA
+:10A6600000000000000000000000000000000000EA
+:10A6700000000000000000000000000000000000DA
+:10A6800000000000000000000000000000000000CA
+:10A6900000000000000000000000000000000000BA
+:10A6A00000000000000000000000000000000000AA
+:10A6B000000000000000000000000000000000009A
+:10A6C000000000000000000000000000000000008A
+:10A6D000000000000000000000000000000000007A
+:10A6E000000000000000000000000000000000006A
+:10A6F000000000000000000000000000000000005A
+:10A700000000000000000000000000000000000049
+:10A710000000000000000000000000000000000039
+:10A720000000000000000000000000000000000029
+:10A730000000000000000000000000000000000019
+:10A740000000000000000000000000000000000009
+:10A7500000000000000000000000000000000000F9
+:10A7600000000000000000000000000000000000E9
+:10A7700000000000000000000000000000000000D9
+:10A7800000000000000000000000000000000000C9
+:10A7900000000000000000000000000000000000B9
+:10A7A00000000000000000000000000000000000A9
+:10A7B0000000000000000000000000000000000099
+:10A7C0000000000000000000000000000000000089
+:10A7D0000000000000000000000000000000000079
+:10A7E0000000000000000000000000000000000069
+:10A7F0000000000000000000000000000000000059
+:10A800000000000000000000000000000000000048
+:10A810000000000000000000000000000000000038
+:10A820000000000000000000000000000000000028
+:10A830000000000000000000000000000000000018
+:10A840000000000000000000000000000000000008
+:10A8500000000000000000000000000000000000F8
+:10A8600000000000000000000000000000000000E8
+:10A8700000000000000000000000000000000000D8
+:10A8800000000000000000000000000000000000C8
+:10A8900000000000000000000000000000000000B8
+:10A8A00000000000000000000000000000000000A8
+:10A8B0000000000000000000000000000000000098
+:10A8C0000000000000000000000000000000000088
+:10A8D0000000000000000000000000000000000078
+:10A8E0000000000000000000000000000000000068
+:10A8F0000000000000000000000000000000000058
+:10A900000000000000000000000000000000000047
+:10A910000000000000000000000000000000000037
+:10A920000000000000000000000000000000000027
+:10A930000000000000000000000000000000000017
+:10A940000000000000000000000000000000000007
+:10A9500000000000000000000000000000000000F7
+:10A9600000000000000000000000000000000000E7
+:10A9700000000000000000000000000000000000D7
+:10A9800000000000000000000000000000000000C7
+:10A9900000000000000000000000000000000000B7
+:10A9A00000000000000000000000000000000000A7
+:10A9B0000000000000000000000000000000000097
+:10A9C0000000000000000000000000000000000087
+:10A9D0000000000000000000000000000000000077
+:10A9E0000000000000000000000000000000000067
+:10A9F0000000000000000000000000000000000057
+:10AA00000000000000000000000000000000000046
+:10AA10000000000000000000000000000000000036
+:10AA20000000000000000000000000000000000026
+:10AA30000000000000000000000000000000000016
+:10AA40000000000000000000000000000000000006
+:10AA500000000000000000000000000000000000F6
+:10AA600000000000000000000000000000000000E6
+:10AA700000000000000000000000000000000000D6
+:10AA800000000000000000000000000000000000C6
+:10AA900000000000000000000000000000000000B6
+:10AAA00000000000000000000000000000000000A6
+:10AAB0000000000000000000000000000000000096
+:10AAC0000000000000000000000000000000000086
+:10AAD0000000000000000000000000000000000076
+:10AAE0000000000000000000000000000000000066
+:10AAF0000000000000000000000000000000000056
+:10AB00000000000000000000000000000000000045
+:10AB10000000000000000000000000000000000035
+:10AB20000000000000000000000000000000000025
+:10AB30000000000000000000000000000000000015
+:10AB40000000000000000000000000000000000005
+:10AB500000000000000000000000000000000000F5
+:10AB600000000000000000000000000000000000E5
+:10AB700000000000000000000000000000000000D5
+:10AB800000000000000000000000000000000000C5
+:10AB900000000000000000000000000000000000B5
+:10ABA00000000000000000000000000000000000A5
+:10ABB0000000000000000000000000000000000095
+:10ABC0000000000000000000000000000000000085
+:10ABD0000000000000000000000000000000000075
+:10ABE0000000000000000000000000000000000065
+:10ABF0000000000000000000000000000000000055
+:10AC00000000000000000000000000000000000044
+:10AC10000000000000000000000000000000000034
+:10AC20000000000000000000000000000000000024
+:10AC30000000000000000000000000000000000014
+:10AC40000000000000000000000000000000000004
+:10AC500000000000000000000000000000000000F4
+:10AC600000000000000000000000000000000000E4
+:10AC700000000000000000000000000000000000D4
+:10AC800000000000000000000000000000000000C4
+:10AC900000000000000000000000000000000000B4
+:10ACA00000000000000000000000000000000000A4
+:10ACB0000000000000000000000000000000000094
+:10ACC0000000000000000000000000000000000084
+:10ACD0000000000000000000000000000000000074
+:10ACE0000000000000000000000000000000000064
+:10ACF0000000000000000000000000000000000054
+:10AD00000000000000000000000000000000000043
+:10AD10000000000000000000000000000000000033
+:10AD20000000000000000000000000000000000023
+:10AD30000000000000000000000000000000000013
+:10AD40000000000000000000000000000000000003
+:10AD500000000000000000000000000000000000F3
+:10AD600000000000000000000000000000000000E3
+:10AD700000000000000000000000000000000000D3
+:10AD800000000000000000000000000000000000C3
+:10AD900000000000000000000000000000000000B3
+:10ADA00000000000000000000000000000000000A3
+:10ADB0000000000000000000000000000000000093
+:10ADC0000000000000000000000000000000000083
+:10ADD0000000000000000000000000000000000073
+:10ADE0000000000000000000000000000000000063
+:10ADF0000000000000000000000000000000000053
+:10AE00000000000000000000000000000000000042
+:10AE10000000000000000000000000000000000032
+:10AE20000000000000000000000000000000000022
+:10AE30000000000000000000000000000000000012
+:10AE40000000000000000000000000000000000002
+:10AE500000000000000000000000000000000000F2
+:10AE600000000000000000000000000000000000E2
+:10AE700000000000000000000000000000000000D2
+:10AE800000000000000000000000000000000000C2
+:10AE900000000000000000000000000000000000B2
+:10AEA00000000000000000000000000000000000A2
+:10AEB0000000000000000000000000000000000092
+:10AEC0000000000000000000000000000000000082
+:10AED0000000000000000000000000000000000072
+:10AEE0000000000000000000000000000000000062
+:10AEF0000000000000000000000000000000000052
+:10AF00000000000000000000000000000000000041
+:10AF10000000000000000000000000000000000031
+:10AF20000000000000000000000000000000000021
+:10AF30000000000000000000000000000000000011
+:10AF40000000000000000000000000000000000001
+:10AF500000000000000000000000000000000000F1
+:10AF600000000000000000000000000000000000E1
+:10AF700000000000000000000000000000000000D1
+:10AF800000000000000000000000000000000000C1
+:10AF900000000000000000000000000000000000B1
+:10AFA00000000000000000000000000000000000A1
+:10AFB0000000000000000000000000000000000091
+:10AFC0000000000000000000000000000000000081
+:10AFD0000000000000000000000000000000000071
+:10AFE0000000000000000000000000000000000061
+:10AFF0000000000000000000000000000000000051
+:10B000000000000000000000000000000000000040
+:10B010000000000000000000000000000000000030
+:10B020000000000000000000000000000000000020
+:10B030000000000000000000000000000000000010
+:10B040000000000000000000000000000000000000
+:10B0500000000000000000000000000000000000F0
+:10B0600000000000000000000000000000000000E0
+:10B0700000000000000000000000000000000000D0
+:10B0800000000000000000000000000000000000C0
+:10B0900000000000000000000000000000000000B0
+:10B0A00000000000000000000000000000000000A0
+:10B0B0000000000000000000000000000000000090
+:10B0C0000000000000000000000000000000000080
+:10B0D0000000000000000000000000000000000070
+:10B0E0000000000000000000000000000000000060
+:10B0F0000000000000000000000000000000000050
+:10B10000000000000000000000000000000000003F
+:10B11000000000000000000000000000000000002F
+:10B12000000000000000000000000000000000001F
+:10B13000000000000000000000000000000000000F
+:10B1400000000000000000000000000000000000FF
+:10B1500000000000000000000000000000000000EF
+:10B1600000000000000000000000000000000000DF
+:10B1700000000000000000000000000000000000CF
+:10B1800000000000000000000000000000000000BF
+:10B1900000000000000000000000000000000000AF
+:10B1A000000000000000000000000000000000009F
+:10B1B000000000000000000000000000000000008F
+:10B1C000000000000000000000000000000000007F
+:10B1D000000000000000000000000000000000006F
+:10B1E000000000000000000000000000000000005F
+:10B1F000000000000000000000000000000000004F
+:10B20000000000000000000000000000000000003E
+:10B21000000000000000000000000000000000002E
+:10B22000000000000000000000000000000000001E
+:10B23000000000000000000000000000000000000E
+:10B2400000000000000000000000000000000000FE
+:10B2500000000000000000000000000000000000EE
+:10B2600000000000000000000000000000000000DE
+:10B2700000000000000000000000000000000000CE
+:10B2800000000000000000000000000000000000BE
+:10B2900000000000000000000000000000000000AE
+:10B2A000000000000000000000000000000000009E
+:10B2B000000000000000000000000000000000008E
+:10B2C000000000000000000000000000000000007E
+:10B2D000000000000000000000000000000000006E
+:10B2E000000000000000000000000000000000005E
+:10B2F000000000000000000000000000000000004E
+:10B30000000000000000000000000000000000003D
+:10B31000000000000000000000000000000000002D
+:10B32000000000000000000000000000000000001D
+:10B33000000000000000000000000000000000000D
+:10B3400000000000000000000000000000000000FD
+:10B3500000000000000000000000000000000000ED
+:10B3600000000000000000000000000000000000DD
+:10B3700000000000000000000000000000000000CD
+:10B3800000000000000000000000000000000000BD
+:10B3900000000000000000000000000000000000AD
+:10B3A000000000000000000000000000000000009D
+:10B3B000000000000000000000000000000000008D
+:10B3C000000000000000000000000000000000007D
+:10B3D000000000000000000000000000000000006D
+:10B3E000000000000000000000000000000000005D
+:10B3F000000000000000000000000000000000004D
+:10B40000000000000000000000000000000000003C
+:10B41000000000000000000000000000000000002C
+:10B42000000000000000000000000000000000001C
+:10B43000000000000000000000000000000000000C
+:10B4400000000000000000000000000000000000FC
+:10B4500000000000000000000000000000000000EC
+:10B4600000000000000000000000000000000000DC
+:10B4700000000000000000000000000000000000CC
+:10B4800000000000000000000000000000000000BC
+:10B4900000000000000000000000000000000000AC
+:10B4A000000000000000000000000000000000009C
+:10B4B000000000000000000000000000000000008C
+:10B4C000000000000000000000000000000000007C
+:10B4D000000000000000000000000000000000006C
+:10B4E000000000000000000000000000000000005C
+:10B4F000000000000000000000000000000000004C
+:10B50000000000000000000000000000000000003B
+:10B51000000000000000000000000000000000002B
+:10B52000000000000000000000000000000000001B
+:10B53000000000000000000000000000000000000B
+:10B5400000000000000000000000000000000000FB
+:10B5500000000000000000000000000000000000EB
+:10B5600000000000000000000000000000000000DB
+:10B5700000000000000000000000000000000000CB
+:10B5800000000000000000000000000000000000BB
+:10B5900000000000000000000000000000000000AB
+:10B5A000000000000000000000000000000000009B
+:10B5B000000000000000000000000000000000008B
+:10B5C000000000000000000000000000000000007B
+:10B5D000000000000000000000000000000000006B
+:10B5E000000000000000000000000000000000005B
+:10B5F000000000000000000000000000000000004B
+:10B60000000000000000000000000000000000003A
+:10B61000000000000000000000000000000000002A
+:10B62000000000000000000000000000000000001A
+:10B63000000000000000000000000000000000000A
+:10B6400000000000000000000000000000000000FA
+:10B6500000000000000000000000000000000000EA
+:10B6600000000000000000000000000000000000DA
+:10B6700000000000000000000000000000000000CA
+:10B6800000000000000000000000000000000000BA
+:10B6900000000000000000000000000000000000AA
+:10B6A000000000000000000000000000000000009A
+:10B6B000000000000000000000000000000000008A
+:10B6C000000000000000000000000000000000007A
+:10B6D000000000000000000000000000000000006A
+:10B6E000000000000000000000000000000000005A
+:10B6F000000000000000000000000000000000004A
+:10B700000000000000000000000000000000000039
+:10B710000000000000000000000000000000000029
+:10B720000000000000000000000000000000000019
+:10B730000000000000000000000000000000000009
+:10B7400000000000000000000000000000000000F9
+:10B7500000000000000000000000000000000000E9
+:10B7600000000000000000000000000000000000D9
+:10B7700000000000000000000000000000000000C9
+:10B7800000000000000000000000000000000000B9
+:10B7900000000000000000000000000000000000A9
+:10B7A0000000000000000000000000000000000099
+:10B7B0000000000000000000000000000000000089
+:10B7C0000000000000000000000000000000000079
+:10B7D0000000000000000000000000000000000069
+:10B7E0000000000000000000000000000000000059
+:10B7F0000000000000000000000000000000000049
+:10B800000000000000000000000000000000000038
+:10B810000000000000000000000000000000000028
+:10B820000000000000000000000000000000000018
+:10B830000000000000000000000000000000000008
+:10B8400000000000000000000000000000000000F8
+:10B8500000000000000000000000000000000000E8
+:10B8600000000000000000000000000000000000D8
+:10B8700000000000000000000000000000000000C8
+:10B8800000000000000000000000000000000000B8
+:10B8900000000000000000000000000000000000A8
+:10B8A0000000000000000000000000000000000098
+:10B8B0000000000000000000000000000000000088
+:10B8C0000000000000000000000000000000000078
+:10B8D0000000000000000000000000000000000068
+:10B8E0000000000000000000000000000000000058
+:10B8F0000000000000000000000000000000000048
+:10B900000000000000000000000000000000000037
+:10B910000000000000000000000000000000000027
+:10B920000000000000000000000000000000000017
+:10B930000000000000000000000000000000000007
+:10B9400000000000000000000000000000000000F7
+:10B9500000000000000000000000000000000000E7
+:10B9600000000000000000000000000000000000D7
+:10B9700000000000000000000000000000000000C7
+:10B9800000000000000000000000000000000000B7
+:10B9900000000000000000000000000000000000A7
+:10B9A0000000000000000000000000000000000097
+:10B9B0000000000000000000000000000000000087
+:10B9C0000000000000000000000000000000000077
+:10B9D0000000000000000000000000000000000067
+:10B9E0000000000000000000000000000000000057
+:10B9F0000000000000000000000000000000000047
+:10BA00000000000000000000000000000000000036
+:10BA10000000000000000000000000000000000026
+:10BA20000000000000000000000000000000000016
+:10BA30000000000000000000000000000000000006
+:10BA400000000000000000000000000000000000F6
+:10BA500000000000000000000000000000000000E6
+:10BA600000000000000000000000000000000000D6
+:10BA700000000000000000000000000000000000C6
+:10BA800000000000000000000000000000000000B6
+:10BA900000000000000000000000000000000000A6
+:10BAA0000000000000000000000000000000000096
+:10BAB0000000000000000000000000000000000086
+:10BAC0000000000000000000000000000000000076
+:10BAD0000000000000000000000000000000000066
+:10BAE0000000000000000000000000000000000056
+:10BAF0000000000000000000000000000000000046
+:10BB00000000000000000000000000000000000035
+:10BB10000000000000000000000000000000000025
+:10BB20000000000000000000000000000000000015
+:10BB30000000000000000000000000000000000005
+:10BB400000000000000000000000000000000000F5
+:10BB500000000000000000000000000000000000E5
+:10BB600000000000000000000000000000000000D5
+:10BB700000000000000000000000000000000000C5
+:10BB800000000000000000000000000000000000B5
+:10BB900000000000000000000000000000000000A5
+:10BBA0000000000000000000000000000000000095
+:10BBB0000000000000000000000000000000000085
+:10BBC0000000000000000000000000000000000075
+:10BBD0000000000000000000000000000000000065
+:10BBE0000000000000000000000000000000000055
+:10BBF0000000000000000000000000000000000045
+:10BC00000000000000000000000000000000000034
+:10BC10000000000000000000000000000000000024
+:10BC20000000000000000000000000000000000014
+:10BC30000000000000000000000000000000000004
+:10BC400000000000000000000000000000000000F4
+:10BC500000000000000000000000000000000000E4
+:10BC600000000000000000000000000000000000D4
+:10BC700000000000000000000000000000000000C4
+:10BC800000000000000000000000000000000000B4
+:10BC900000000000000000000000000000000000A4
+:10BCA0000000000000000000000000000000000094
+:10BCB0000000000000000000000000000000000084
+:10BCC0000000000000000000000000000000000074
+:10BCD0000000000000000000000000000000000064
+:10BCE0000000000000000000000000000000000054
+:10BCF0000000000000000000000000000000000044
+:10BD00000000000000000000000000000000000033
+:10BD10000000000000000000000000000000000023
+:10BD20000000000000000000000000000000000013
+:10BD30000000000000000000000000000000000003
+:10BD400000000000000000000000000000000000F3
+:10BD500000000000000000000000000000000000E3
+:10BD600000000000000000000000000000000000D3
+:10BD700000000000000000000000000000000000C3
+:10BD800000000000000000000000000000000000B3
+:10BD900000000000000000000000000000000000A3
+:10BDA0000000000000000000000000000000000093
+:10BDB0000000000000000000000000000000000083
+:10BDC0000000000000000000000000000000000073
+:10BDD0000000000000000000000000000000000063
+:10BDE0000000000000000000000000000000000053
+:10BDF0000000000000000000000000000000000043
+:10BE00000000000000000000000000000000000032
+:10BE10000000000000000000000000000000000022
+:10BE20000000000000000000000000000000000012
+:10BE30000000000000000000000000000000000002
+:10BE400000000000000000000000000000000000F2
+:10BE500000000000000000000000000000000000E2
+:10BE600000000000000000000000000000000000D2
+:10BE700000000000000000000000000000000000C2
+:10BE800000000000000000000000000000000000B2
+:10BE900000000000000000000000000000000000A2
+:10BEA0000000000000000000000000000000000092
+:10BEB0000000000000000000000000000000000082
+:10BEC0000000000000000000000000000000000072
+:10BED0000000000000000000000000000000000062
+:10BEE0000000000000000000000000000000000052
+:10BEF0000000000000000000000000000000000042
+:10BF00000000000000000000000000000000000031
+:10BF10000000000000000000000000000000000021
+:10BF20000000000000000000000000000000000011
+:10BF30000000000000000000000000000000000001
+:10BF400000000000000000000000000000000000F1
+:10BF500000000000000000000000000000000000E1
+:10BF600000000000000000000000000000000000D1
+:10BF700000000000000000000000000000000000C1
+:10BF800000000000000000000000000000000000B1
+:10BF900000000000000000000000000000000000A1
+:10BFA0000000000000000000000000000000000091
+:10BFB0000000000000000000000000000000000081
+:10BFC0000000000000000000000000000000000071
+:10BFD0000000000000000000000000000000000061
+:10BFE0000000000000000000000000000000000051
+:10BFF0000000000000000000000000000000000041
+:10C000000000000000000000000000000000000030
+:10C010000000000000000000000000000000000020
+:10C020000000000000000000000000000000000010
+:10C030000000000000000000000000000000000000
+:10C0400000000000000000000000000000000000F0
+:10C0500000000000000000000000000000000000E0
+:10C0600000000000000000000000000000000000D0
+:10C0700000000000000000000000000000000000C0
+:10C0800000000000000000000000000000000000B0
+:10C0900000000000000000000000000000000000A0
+:10C0A0000000000000000000000000000000000090
+:10C0B0000000000000000000000000000000000080
+:10C0C0000000000000000000000000000000000070
+:10C0D0000000000000000000000000000000000060
+:10C0E0000000000000000000000000000000000050
+:10C0F0000000000000000000000000000000000040
+:10C10000000000000000000000000000000000002F
+:10C11000000000000000000000000000000000001F
+:10C12000000000000000000000000000000000000F
+:10C1300000000000000000000000000000000000FF
+:10C1400000000000000000000000000000000000EF
+:10C1500000000000000000000000000000000000DF
+:10C1600000000000000000000000000000000000CF
+:10C1700000000000000000000000000000000000BF
+:10C1800000000000000000000000000000000000AF
+:10C19000000000000000000000000000000000009F
+:10C1A000000000000000000000000000000000008F
+:10C1B000000000000000000000000000000000007F
+:10C1C000000000000000000000000000000000006F
+:10C1D000000000000000000000000000000000005F
+:10C1E000000000000000000000000000000000004F
+:10C1F000000000000000000000000000000000003F
+:10C20000000000000000000000000000000000002E
+:10C21000000000000000000000000000000000001E
+:10C22000000000000000000000000000000000000E
+:10C2300000000000000000000000000000000000FE
+:10C2400000000000000000000000000000000000EE
+:10C2500000000000000000000000000000000000DE
+:10C2600000000000000000000000000000000000CE
+:10C2700000000000000000000000000000000000BE
+:10C2800000000000000000000000000000000000AE
+:10C29000000000000000000000000000000000009E
+:10C2A000000000000000000000000000000000008E
+:10C2B000000000000000000000000000000000007E
+:10C2C000000000000000000000000000000000006E
+:10C2D000000000000000000000000000000000005E
+:10C2E000000000000000000000000000000000004E
+:10C2F000000000000000000000000000000000003E
+:10C30000000000000000000000000000000000002D
+:10C31000000000000000000000000000000000001D
+:10C32000000000000000000000000000000000000D
+:10C3300000000000000000000000000000000000FD
+:10C3400000000000000000000000000000000000ED
+:10C3500000000000000000000000000000000000DD
+:10C3600000000000000000000000000000000000CD
+:10C3700000000000000000000000000000000000BD
+:10C3800000000000000000000000000000000000AD
+:10C39000000000000000000000000000000000009D
+:10C3A000000000000000000000000000000000008D
+:10C3B000000000000000000000000000000000007D
+:10C3C000000000000000000000000000000000006D
+:10C3D000000000000000000000000000000000005D
+:10C3E000000000000000000000000000000000004D
+:10C3F000000000000000000000000000000000003D
+:10C40000000000000000000000000000000000002C
+:10C41000000000000000000000000000000000001C
+:10C42000000000000000000000000000000000000C
+:10C4300000000000000000000000000000000000FC
+:10C4400000000000000000000000000000000000EC
+:10C4500000000000000000000000000000000000DC
+:10C4600000000000000000000000000000000000CC
+:10C4700000000000000000000000000000000000BC
+:10C4800000000000000000000000000000000000AC
+:10C49000000000000000000000000000000000009C
+:10C4A000000000000000000000000000000000008C
+:10C4B000000000000000000000000000000000007C
+:10C4C000000000000000000000000000000000006C
+:10C4D000000000000000000000000000000000005C
+:10C4E000000000000000000000000000000000004C
+:10C4F000000000000000000000000000000000003C
+:10C50000000000000000000000000000000000002B
+:10C51000000000000000000000000000000000001B
+:10C52000000000000000000000000000000000000B
+:10C5300000000000000000000000000000000000FB
+:10C5400000000000000000000000000000000000EB
+:10C5500000000000000000000000000000000000DB
+:10C5600000000000000000000000000000000000CB
+:10C5700000000000000000000000000000000000BB
+:10C5800000000000000000000000000000000000AB
+:10C59000000000000000000000000000000000009B
+:10C5A000000000000000000000000000000000008B
+:10C5B000000000000000000000000000000000007B
+:10C5C000000000000000000000000000000000006B
+:10C5D000000000000000000000000000000000005B
+:10C5E000000000000000000000000000000000004B
+:10C5F000000000000000000000000000000000003B
+:10C60000000000000000000000000000000000002A
+:10C61000000000000000000000000000000000001A
+:10C62000000000000000000000000000000000000A
+:10C6300000000000000000000000000000000000FA
+:10C6400000000000000000000000000000000000EA
+:10C6500000000000000000000000000000000000DA
+:10C6600000000000000000000000000000000000CA
+:10C6700000000000000000000000000000000000BA
+:10C6800000000000000000000000000000000000AA
+:10C69000000000000000000000000000000000009A
+:10C6A000000000000000000000000000000000008A
+:10C6B000000000000000000000000000000000007A
+:10C6C000000000000000000000000000000000006A
+:10C6D000000000000000000000000000000000005A
+:10C6E000000000000000000000000000000000004A
+:10C6F000000000000000000000000000000000003A
+:10C700000000000000000000000000000000000029
+:10C710000000000000000000000000000000000019
+:10C720000000000000000000000000000000000009
+:10C7300000000000000000000000000000000000F9
+:10C7400000000000000000000000000000000000E9
+:10C7500000000000000000000000000000000000D9
+:10C7600000000000000000000000000000000000C9
+:10C7700000000000000000000000000000000000B9
+:10C7800000000000000000000000000000000000A9
+:10C790000000000000000000000000000000000099
+:10C7A0000000000000000000000000000000000089
+:10C7B0000000000000000000000000000000000079
+:10C7C0000000000000000000000000000000000069
+:10C7D0000000000000000000000000000000000059
+:10C7E0000000000000000000000000000000000049
+:10C7F0000000000000000000000000000000000039
+:10C800000000000000000000000000000000000028
+:10C810000000000000000000000000000000000018
+:10C820000000000000000000000000000000000008
+:10C8300000000000000000000000000000000000F8
+:10C8400000000000000000000000000000000000E8
+:10C8500000000000000000000000000000000000D8
+:10C8600000000000000000000000000000000000C8
+:10C8700000000000000000000000000000000000B8
+:10C8800000000000000000000000000000000000A8
+:10C890000000000000000000000000000000000098
+:10C8A0000000000000000000000000000000000088
+:10C8B0000000000000000000000000000000000078
+:10C8C0000000000000000000000000000000000068
+:10C8D0000000000000000000000000000000000058
+:10C8E0000000000000000000000000000000000048
+:10C8F0000000000000000000000000000000000038
+:10C900000000000000000000000000000000000027
+:10C910000000000000000000000000000000000017
+:10C920000000000000000000000000000000000007
+:10C9300000000000000000000000000000000000F7
+:10C9400000000000000000000000000000000000E7
+:10C9500000000000000000000000000000000000D7
+:10C9600000000000000000000000000000000000C7
+:10C9700000000000000000000000000000000000B7
+:10C9800000000000000000000000000000000000A7
+:10C990000000000000000000000000000000000097
+:10C9A0000000000000000000000000000000000087
+:10C9B0000000000000000000000000000000000077
+:10C9C0000000000000000000000000000000000067
+:10C9D0000000000000000000000000000000000057
+:10C9E0000000000000000000000000000000000047
+:10C9F0000000000000000000000000000000000037
+:10CA00000000000000000000000000000000000026
+:10CA10000000000000000000000000000000000016
+:10CA20000000000000000000000000000000000006
+:10CA300000000000000000000000000000000000F6
+:10CA400000000000000000000000000000000000E6
+:10CA500000000000000000000000000000000000D6
+:10CA600000000000000000000000000000000000C6
+:10CA700000000000000000000000000000000000B6
+:10CA800000000000000000000000000000000000A6
+:10CA90000000000000000000000000000000000096
+:10CAA0000000000000000000000000000000000086
+:10CAB0000000000000000000000000000000000076
+:10CAC0000000000000000000000000000000000066
+:10CAD0000000000000000000000000000000000056
+:10CAE0000000000000000000000000000000000046
+:10CAF0000000000000000000000000000000000036
+:10CB00000000000000000000000000000000000025
+:10CB10000000000000000000000000000000000015
+:10CB20000000000000000000000000000000000005
+:10CB300000000000000000000000000000000000F5
+:10CB400000000000000000000000000000000000E5
+:10CB500000000000000000000000000000000000D5
+:10CB600000000000000000000000000000000000C5
+:10CB700000000000000000000000000000000000B5
+:10CB800000000000000000000000000000000000A5
+:10CB90000000000000000000000000000000000095
+:10CBA0000000000000000000000000000000000085
+:10CBB0000000000000000000000000000000000075
+:10CBC0000000000000000000000000000000000065
+:10CBD0000000000000000000000000000000000055
+:10CBE0000000000000000000000000000000000045
+:10CBF0000000000000000000000000000000000035
+:10CC00000000000000000000000000000000000024
+:10CC10000000000000000000000000000000000014
+:10CC20000000000000000000000000000000000004
+:10CC300000000000000000000000000000000000F4
+:10CC400000000000000000000000000000000000E4
+:10CC500000000000000000000000000000000000D4
+:10CC600000000000000000000000000000000000C4
+:10CC700000000000000000000000000000000000B4
+:10CC800000000000000000000000000000000000A4
+:10CC90000000000000000000000000000000000094
+:10CCA0000000000000000000000000000000000084
+:10CCB0000000000000000000000000000000000074
+:10CCC0000000000000000000000000000000000064
+:10CCD0000000000000000000000000000000000054
+:10CCE0000000000000000000000000000000000044
+:10CCF0000000000000000000000000000000000034
+:10CD00000000000000000000000000000000000023
+:10CD10000000000000000000000000000000000013
+:10CD20000000000000000000000000000000000003
+:10CD300000000000000000000000000000000000F3
+:10CD400000000000000000000000000000000000E3
+:10CD500000000000000000000000000000000000D3
+:10CD600000000000000000000000000000000000C3
+:10CD700000000000000000000000000000000000B3
+:10CD800000000000000000000000000000000000A3
+:10CD90000000000000000000000000000000000093
+:10CDA0000000000000000000000000000000000083
+:10CDB0000000000000000000000000000000000073
+:10CDC0000000000000000000000000000000000063
+:10CDD0000000000000000000000000000000000053
+:10CDE0000000000000000000000000000000000043
+:10CDF0000000000000000000000000000000000033
+:10CE00000000000000000000000000000000000022
+:10CE10000000000000000000000000000000000012
+:10CE20000000000000000000000000000000000002
+:10CE300000000000000000000000000000000000F2
+:10CE400000000000000000000000000000000000E2
+:10CE500000000000000000000000000000000000D2
+:10CE600000000000000000000000000000000000C2
+:10CE700000000000000000000000000000000000B2
+:10CE800000000000000000000000000000000000A2
+:10CE90000000000000000000000000000000000092
+:10CEA0000000000000000000000000000000000082
+:10CEB0000000000000000000000000000000000072
+:10CEC0000000000000000000000000000000000062
+:10CED0000000000000000000000000000000000052
+:10CEE0000000000000000000000000000000000042
+:10CEF0000000000000000000000000000000000032
+:10CF00000000000000000000000000000000000021
+:10CF10000000000000000000000000000000000011
+:10CF20000000000000000000000000000000000001
+:10CF300000000000000000000000000000000000F1
+:10CF400000000000000000000000000000000000E1
+:10CF500000000000000000000000000000000000D1
+:10CF600000000000000000000000000000000000C1
+:10CF700000000000000000000000000000000000B1
+:10CF800000000000000000000000000000000000A1
+:10CF90000000000000000000000000000000000091
+:10CFA0000000000000000000000000000000000081
+:10CFB0000000000000000000000000000000000071
+:10CFC0000000000000000000000000000000000061
+:10CFD0000000000000000000000000000000000051
+:10CFE0000000000000000000000000000000000041
+:10CFF0000000000000000000000000000000000031
+:10D000000000000000000000000000000000000020
+:10D010000000000000000000000000000000000010
+:10D020000000000000000000000000000000000000
+:10D0300000000000000000000000000000000000F0
+:10D0400000000000000000000000000000000000E0
+:10D0500000000000000000000000000000000000D0
+:10D0600000000000000000000000000000000000C0
+:10D0700000000000000000000000000000000000B0
+:10D0800000000000000000000000000000000000A0
+:10D090000000000000000000000000000000000090
+:10D0A0000000000000000000000000000000000080
+:10D0B0000000000000000000000000000000000070
+:10D0C0000000000000000000000000000000000060
+:10D0D0000000000000000000000000000000000050
+:10D0E0000000000000000000000000000000000040
+:10D0F0000000000000000000000000000000000030
+:10D10000000000000000000000000000000000001F
+:10D11000000000000000000000000000000000000F
+:10D1200000000000000000000000000000000000FF
+:10D1300000000000000000000000000000000000EF
+:10D1400000000000000000000000000000000000DF
+:10D1500000000000000000000000000000000000CF
+:10D1600000000000000000000000000000000000BF
+:10D1700000000000000000000000000000000000AF
+:10D18000000000000000000000000000000000009F
+:10D19000000000000000000000000000000000008F
+:10D1A000000000000000000000000000000000007F
+:10D1B000000000000000000000000000000000006F
+:10D1C000000000000000000000000000000000005F
+:10D1D000000000000000000000000000000000004F
+:10D1E000000000000000000000000000000000003F
+:10D1F000000000000000000000000000000000002F
+:10D20000000000000000000000000000000000001E
+:10D21000000000000000000000000000000000000E
+:10D2200000000000000000000000000000000000FE
+:10D2300000000000000000000000000000000000EE
+:10D2400000000000000000000000000000000000DE
+:10D2500000000000000000000000000000000000CE
+:10D2600000000000000000000000000000000000BE
+:10D2700000000000000000000000000000000000AE
+:10D28000000000000000000000000000000000009E
+:10D29000000000000000000000000000000000008E
+:10D2A000000000000000000000000000000000007E
+:10D2B000000000000000000000000000000000006E
+:10D2C000000000000000000000000000000000005E
+:10D2D000000000000000000000000000000000004E
+:10D2E000000000000000000000000000000000003E
+:10D2F000000000000000000000000000000000002E
+:10D30000000000000000000000000000000000001D
+:10D31000000000000000000000000000000000000D
+:10D3200000000000000000000000000000000000FD
+:10D330000000000010000003000000000000000DCD
+:10D340000000000D3C02080024427A603C03080003
+:10D3500024637AD8AC4000000043202B1480FFFDEA
+:10D36000244200043C1D080037BD9FFC03A0F021AF
+:10D370003C100800261031D83C1C0800279C7A601D
+:10D380000E001253000000000000000D3C0280005F
+:10D3900030A5FFFF30C600FF344301803C08800009
+:10D3A0008D0901B80520FFFE00000000AC640000FC
+:10D3B00024040002A4650008A066000AA064000B13
+:10D3C000AC6700183C03100003E00008AD0301B88F
+:10D3D0003C0560008CA24FF80440FFFE00000000F6
+:10D3E000ACA44FC03C0310003C040200ACA44FC4EA
+:10D3F00003E00008ACA34FF827BDFFE8AFBF00145F
+:10D40000AFB000100E0012A5008080213C048008FF
+:10D410003485008090A600052403FFFE0200202131
+:10D4200000C310248FBF00148FB00010A0A200050D
+:10D430000A0012AF27BD001827BDFFE8AFB00010EB
+:10D44000AFBF00140E000ED6008080213C0680087D
+:10D4500034C5008090A4000024020050308300FFF7
+:10D46000106200073C098000020020218FBF0014D9
+:10D470008FB00010AD2001800A000FC527BD001835
+:10D48000240801003C078000020020218FBF001407
+:10D490008FB00010ACE801800A000FC527BD00184E
+:10D4A00027BDFF883C088008AFBE0070AFB600689B
+:10D4B000AFB40060AFB00050AFBF0074AFB7006C46
+:10D4C000AFB50064AFB3005CAFB20058AFB1005469
+:10D4D000350500803C0780008CF1012890A40009EC
+:10D4E000ACE0008490A60005309000FF0000A02171
+:10D4F00000061827306200010000B02114400067C8
+:10D500000000F02190A9000024050020312400FF34
+:10D5100010850016240A0050108A008D00000000BB
+:10D520003C0C08008D8C00DC258B00013C010800C0
+:10D53000AC2B00DC0E00139B000000008FBF0074BA
+:10D540008FBE00708FB7006C8FB600688FB5006417
+:10D550008FB400608FB3005C8FB200588FB100545D
+:10D560008FB0005003E0000827BD00780000000DD8
+:10D570003C158000AFA0003096A201168EB90104C0
+:10D580003C1F002036B20C00033FC0240018B82B0B
+:10D5900000173140AFA600308EAE01043053FFFFBC
+:10D5A0003C0F00400272382101CF682490F2000D38
+:10D5B00011A0004834C4004032430020146000022F
+:10D5C000348600800080302114C00094AFA6003063
+:10D5D0003C0980083525008090A8000831060040ED
+:10D5E00050C000063C088008240A0004120A00A368
+:10D5F000240B0012120B00293C088008351501008D
+:10D600003C17800096F3011A94EE000E92AF0008CA
+:10D61000324C00043275FFFF01EE6804AFAD003CF0
+:10D620008CF30004118000318CF700083503008072
+:10D63000907800083307004014E000280000000044
+:10D640008C72005002728823062000063C0680007F
+:10D650008C7F0034027FC823072200848E8200085A
+:10D660003C068000ACC00044240200018FBF00745F
+:10D670008FBE00708FB7006C8FB600688FB50064E6
+:10D680008FB400608FB3005C8FB200588FB100542C
+:10D690008FB0005003E0000827BD00780E000CB8E2
+:10D6A000000020218FBF00748FBE00708FB7006C08
+:10D6B0008FB600688FB500648FB400608FB3005CD4
+:10D6C0008FB200588FB100548FB0005003E00008B3
+:10D6D00027BD00780A000D1800C020210E00146C30
+:10D6E000026020211440FFDF3C0680003C038008DC
+:10D6F000346300808C6400340264102304400018FA
+:10D70000000000003C1408008E94310026900001B7
+:10D710003C010800AC3031000E0012A5022020218F
+:10D720003C048008349F008093FE002502202021C5
+:10D7300037C90004A3E900250E0012AF0000000065
+:10D740000E000C9E022020210A000D45240200013B
+:10D750003C14080026947AC80A000D073C15800086
+:10D760008C6800300268302318C00008240B000CBD
+:10D770003C0908008D293100325200FC0000A8212C
+:10D78000252500013C010800AC253100AFAB00307D
+:10D790008C6A003001534023190000E002A8602A7F
+:10D7A0001580FFDD0000000012A8002A02A87823DF
+:10D7B0000268982131F5FFFF3247000210E0003483
+:10D7C000325900103C13800836700080921E000809
+:10D7D00033D6004052C000D38E82000802202021A0
+:10D7E0000E0012A524120018A212000992170005BB
+:10D7F0002418FFFE0220202102F8A8240E0012AFF8
+:10D80000A215000524040039000028210E00144749
+:10D81000240600180A000D45240200019296000C0F
+:10D820003C048008349E00808FC700380016A30097
+:10D830003690008130C600FF022020210E000C8DA2
+:10D840003205F0813C068000ACC000440A000D4562
+:10D85000240200013A4E000131CD000115A0FFAEB7
+:10D86000026898210A000D97000000000040F809A6
+:10D87000240400160A000D45240200010220202184
+:10D880000E00152900E028210A000CFA8FBF007451
+:10D890001320FF733C048008348900808D230038F6
+:10D8A0008C82000402E2F8231FE0FF6E3C06800039
+:10D8B00002E3302304C200010060B821AFA80018C1
+:10D8C0003C198000AFB30010AFB5001497260120BB
+:10D8D0008D2A00309524005C8FB8003C8FAD00305D
+:10D8E0003087FFFF30DFFFFF03E87021372F400054
+:10D8F0000307282B8E82000401CF602101A5582543
+:10D90000AFA90048AFAC0020AFAA0028AFAB0030F1
+:10D91000AFAA0024AFA0002CAFB700340040F80934
+:10D9200027A400108FA8003031030002106000020D
+:10D930008FA90048325200FE912300083069004050
+:10D94000512000138FA400243C0280088C4800045E
+:10D95000111700A4240A0014325800015300000CCF
+:10D960008FA400242419000C121900C02A1F000DD6
+:10D9700013E000BA2406000E2404000A5204000139
+:10D98000241600088FA9002425240001AFA4002438
+:10D990003C188008370500808FA700148CAF00303A
+:10D9A000340CFFFF00877021ACAE0030AFAF003801
+:10D9B00090AD004E8CAB00308FA8003C01AC100441
+:10D9C00001625021ACAA00348FA6003002E8202169
+:10D9D00030C300081060000BAFA400408CB90020D9
+:10D9E0001324008F30C600FF9289000C8FA70034EB
+:10D9F00000098300360400803085F0800E000C8D15
+:10DA0000022020213C0A8008355000808E0300301F
+:10DA10008FA800380068302318C00065262F0080CA
+:10DA20003C0E08008DCE31982407FF8001E7682462
+:10DA300031EC007F3C0680003C02800431CB0010BA
+:10DA4000ACCD00901160003B0182282190B8006BA2
+:10DA5000570000393C048008241F0001A0BF006B60
+:10DA600094C5007A24B9000AA61900123C0A80085D
+:10DA70003545008090A800083110004016000004D1
+:10DA80003C038008324B00011560006B0000000071
+:10DA9000346400808C8C00208FB200401192000909
+:10DAA000346301008C6D0000026D102318400012D9
+:10DAB0008FB80040241E0001AC980020AC73000019
+:10DAC000AC77000416C0002D0000000017C000272E
+:10DAD0000000000012A00005000018218FA50030F2
+:10DAE00030B5000452A0FE9500601021240300010F
+:10DAF0000A000CF9006010218C6E000015D3FFF1B4
+:10DB0000000000008C67000402E7782305E1FFE9CC
+:10DB10008FB800400A000E5B000000000A000D985C
+:10DB2000000040210040F809240400170A000D45B8
+:10DB3000240200013C04800834900080241E00016F
+:10DB4000022020210E0012A5A61E00129209002517
+:10DB500002202021241E0001352200010E0012AFF8
+:10DB6000A20200250A000E463C0A80080E000C9E08
+:10DB7000022020210A000E5F000000000E0012A506
+:10DB8000022020213C198008373700800220202104
+:10DB90000E0012AFA2F6000902C0302124040037A3
+:10DBA0000E001447000028210A000E5D000000004E
+:10DBB0008FA6001858C0FFAE3C0A80080E0012A5C0
+:10DBC000022020219203002502202021241E000192
+:10DBD000346200040E0012AFA20200250A000E46B5
+:10DBE0003C0A8008120A00302A0B0015116000243C
+:10DBF000240D0016240C000C560CFF58325800015E
+:10DC00003C05800890AF001B2407FFBD2416000EC2
+:10DC100001E77024A0AE001B0A000E01325800017B
+:10DC20003C1F800097E5011A50A0FF6F34C600101A
+:10DC30000A000E259289000C8CB300308E960008E5
+:10DC4000240400182674000102C0F809ACB40030A6
+:10DC50008FB100300A000CF9322200041606FF4A88
+:10DC60008FA900240A000E0C241600102410000EA8
+:10DC700052D0FF44241600100A000E0B2416001682
+:10DC8000560DFF36325800013C05800890AF001B4E
+:10DC90002407FFBD2416001001E77024A0AE001B6E
+:10DCA0000A000E01325800010A000E00241600126C
+:10DCB0003C0380008C6201B80440FFFE240408008D
+:10DCC000AC6401B803E00008000000003C058008D7
+:10DCD00094A200483084FFFF1040001924840012F1
+:10DCE00094A900483C0380003128FFFF0104382A32
+:10DCF00010E0001334660180946D01208F8C0004C5
+:10DD0000240B001A31AAFFFF31834000A0CB000B87
+:10DD1000106000102544FFFE94AF004831EEFFFF75
+:10DD200001C4282B14A0000C8F98000CA4C400146C
+:10DD30008F86000C34C2000103E00008AF82000CA3
+:10DD40003C0780002404000334E2018003E0000863
+:10DD5000A044000B8F98000C2419FFFE0319102417
+:10DD600003E00008AF82000C27BDFFD8AFB400204D
+:10DD7000AFB3001CAFB20018AFB10014AFBF0024A6
+:10DD8000AFB000100080182130B3FFFF30D2FFFF8A
+:10DD900030F4FFFF3C1180008E2201B80440FFFEEA
+:10DDA00036300180AE030000024020210E000EDD5F
+:10DDB000AE2300208F86000C8F8500048F83000027
+:10DDC00030C48000A613000CA612000EA605001099
+:10DDD000AE030028A61400081080000E3C0F80003F
+:10DDE000962C0116318BFFFC256A00040151482155
+:10DDF0008D2840003107FFFF14E000072414BFFF07
+:10DE00003C0EFFFF35CD7FFF00CD3024AF86000CE8
+:10DE10003C0F80002414BFFF35F1018000D498240A
+:10DE2000A63300268DF20104AE32002C3C06100011
+:10DE3000ADE601B88FBF00248FB400208FB3001C63
+:10DE40008FB200188FB100148FB0001003E00008EB
+:10DE500027BD002827BDFFD8AFB100143C118000BA
+:10DE600000804021AFB40020AFB0001030D4FFFFDD
+:10DE70003630018002802021AE080000AE2800204C
+:10DE8000AFB3001CAFB2001830F3FFFFAFBF0024E8
+:10DE90000E000EDD30B2FFFF8F85000C8F83000473
+:10DEA0002406BFFF00A62024A612000CA614000E14
+:10DEB000A6130008A6040026A60300103C021000CA
+:10DEC000AE2201B88FBF00248FB400208FB3001C96
+:10DED0008FB200188FB100148FB0001003E000085B
+:10DEE00027BD00283C028000344501803C048000AE
+:10DEF0008C8301B80460FFFE240720002406000282
+:10DF0000A4A70008A0A6000BA4A000103C051000C8
+:10DF1000AC8501B803E00008000000003C0580006B
+:10DF200034A400708C8A000090A601128F84000433
+:10DF300027BDFFF030C300FF0003188230820100CC
+:10DF4000000038211040003924660003308740006B
+:10DF500050E0003930882000000610800045C821BC
+:10DF60008F2F40002478000400187080AFAF0000AD
+:10DF700001C568218DAC4000AFAC000494AB011624
+:10DF80003169FFFC012540218D054000AFA5000847
+:10DF90008FA9000800003021000028213C0708005C
+:10DFA00024E701000A000F9E2408000890420000A8
+:10DFB00024A500012CAD000C0062C8210019C0800E
+:10DFC000030778218DEE000011A0000600CE302658
+:10DFD00003A5102114A8FFF500051A005520FFF431
+:10DFE000904200003C048000348700703C0508002B
+:10DFF0008CA531048CE300002CA80020110000093E
+:10E00000006A3823000558803C0C0800258C310834
+:10E01000016C482124AA0001AD2700003C01080042
+:10E02000AC2A3104AF8600002407000100E0102173
+:10E0300003E0000827BD00101100FFFC000038219C
+:10E0400000066080018558218D6440002469000429
+:10E0500000093880AFA4000000E518218C6640005C
+:10E06000AFA000080A000F8EAFA600043C02080013
+:10E070008C42003827BDFFD8AFB40020AFB20018E3
+:10E08000AFBF0024AFB3001CAFB10014AFB000109D
+:10E090003C14080026940038144000022452FFFF6C
+:10E0A000000090218F85000430A340001060000F15
+:10E0B00030A980003C06002000A620241080000B20
+:10E0C0008F87000C2408BFFF00A8282434E3100029
+:10E0D000AF85000430AF200015E0000A3C110004B9
+:10E0E0002413FFBF0A000FEF0073102415200062F5
+:10E0F0003C0B002030AF200011E0FFF98F83000CB3
+:10E100003C11000400B180241200FFF62413FFBF6D
+:10E110003462004030B801001300000FAF82000CE1
+:10E120003C1F002000BFC824132000053C0A8000CB
+:10E130003C03000400A31024104000C800000000AD
+:10E140009549011E9548011C3126FFFF00083C003F
+:10E1500000C72025AF8400003C0D800095AC010C69
+:10E1600030AB1000116000083186FFFF30AE002098
+:10E1700015C00006241100053C10100000B07824E2
+:10E1800015E000733C1F0C002411000130A20100B7
+:10E19000544000093C0C00018F83001454600006B9
+:10E1A0003C0C00018F87000C30E440001080009A86
+:10E1B0003C0A1F013C0C000100AC302414C0006C70
+:10E1C0003C1080008F84000C3093400012600006E9
+:10E1D0003C0310003C190F0000B9C0241300008B51
+:10E1E0003C1F80003C03100000A310241040002CB2
+:10E1F0003C0680003C0708008CE7003014E0007308
+:10E200003088400030A6010010C000983C0E0F007E
+:10E2100000AE68243C0C020011AC00948F93000007
+:10E22000027280240214782191F4000426920004E2
+:10E23000001221C03C0E800095C6010E3627000258
+:10E2400024D400043286FFFF240500020E000F04D0
+:10E25000000000008FBF00248FB400208FB3001C8B
+:10E260008FB200188FB100148FB000100000102181
+:10E2700003E0000827BD002800AB50241140FF9E9A
+:10E2800030AF20008F8C000C3C0EFFFF35CD7FFFA0
+:10E2900000AD2824358380000A000FDFAF8500041D
+:10E2A0008CD04000320F010011E0003C30B801007A
+:10E2B0003C1008008E1000241300001432330004B8
+:10E2C0003C020F0000A2F8243C19020013F9000FD1
+:10E2D0008F83000094C9010E022038210072582457
+:10E2E0000174502191480004252400043086FFFF6A
+:10E2F00025140004001421C0240500020E000F04A0
+:10E300002412FFFE021280243231FFFB2407000199
+:10E310001207006F3206000114C000903C0E80000E
+:10E32000320F000411E000048F980004331008003D
+:10E33000160000783C1F80005660FFC78FBF002486
+:10E340000E000F63000000000A0010408FBF002481
+:10E350003C190BFF00BFC0243733FFFF0278882B26
+:10E360005220FF8A241100010A00100D241100051B
+:10E370003C0E08008DCE00D8960F010E24040080BC
+:10E3800025CD000131E6FFFF240500023C01080015
+:10E39000AC2D00D80A00103D240700033C120800F1
+:10E3A0008E520024324200011040FFAB8FBF002488
+:10E3B00094C6010E362700020000202124D4000458
+:10E3C0003286FFFF0A00103D240500021100FF8E77
+:10E3D00030A601003C0B0F0000AB50243C090100AB
+:10E3E000012A202B1480FF88000000003C058000DB
+:10E3F00094A6010E362700022404008024D40004D1
+:10E400003286FFFF0A00103D2405000297E3011643
+:10E410000A0010243C03100000AA48243C08100005
+:10E420001528FF653C0C000130CB02001560FF632E
+:10E4300000AC30243C1480009692010E3627000276
+:10E44000000020212645000430A6FFFF0E000F3FEC
+:10E45000240500020A0010408FBF00240E000F7137
+:10E46000000000000A0010008F850004000000007A
+:10E470003C0608008CC600D0000516023050000F84
+:10E4800038DF00012FF900012E03000C0323C02404
+:10E490001700FF68001021C02608FFFC2D070004AC
+:10E4A00014E000073C0E800038CA00022D4900012C
+:10E4B000012320245080000E000532423C0E8000D3
+:10E4C00095C6010E000020210A00103A36270002EE
+:10E4D0003233000452600001363100023C0C8000EF
+:10E4E0009586010E022038210A0010990000202193
+:10E4F0000010182B00C358241560000F3C05800045
+:10E50000001021C03C0E800095C6010E0A00103A92
+:10E510003627000297F9010E022038212404010059
+:10E52000273100043226FFFF0E000F0424050002ED
+:10E530000A0010780000000094AD010E00002021B8
+:10E540002405000225AC00043186FFFF0E000F04F5
+:10E550003227FFFB0A0010EB001021C095C5010E09
+:10E56000022038210000202124AD000431A6FFFF45
+:10E570000E000F04240500020A0010723231FFFB66
+:10E580003C0580008CA701482403000434A60180C8
+:10E5900000072402308200FF104300103C0480007A
+:10E5A0008C8901B80520FFFE000000008C8F014817
+:10E5B000240D00023C0A1000000F7402A4CE0008D3
+:10E5C000A0CD000B8C8C0148A4CC00108C8B014496
+:10E5D000ACCB002403E00008AC8A01B88CA4014055
+:10E5E0003C03800000C028218C6601B804C0FFFEF7
+:10E5F0002408001CACA40000A0A8000B3C051000DF
+:10E60000AC6501B803E000080000000027BDFFE88A
+:10E61000AFB00010AFBF00143C10600C8E0D500066
+:10E62000240EFF7F2406000301AE60243588380CD9
+:10E630003C058000AE085000ACA600083C01080074
+:10E64000AC2000200E001555000000003C086016AC
+:10E650008D0A00003C0BFFFF3C0900103523805160
+:10E660003C046000014B38243C025353AE03537CFE
+:10E67000348420203C05080024A579082406000ADB
+:10E6800010E2000935037C008C7F007C8C790078D7
+:10E690008FB00010AF9F00108FBF001427BD00186F
+:10E6A0000A0013B1AF9900088D0F00043C186000F8
+:10E6B0008FB0001001F818218C7F007C8C790078D5
+:10E6C000AF9F00108FBF001427BD00180A0013B1C0
+:10E6D000AF9900083C0480008C8340003402FFFFA7
+:10E6E0001062003A000000008C87400030E5010015
+:10E6F00010A00021000000009487010E3C020800D9
+:10E700008C4200EC9485010E3C0D08008DAD31CC9F
+:10E7100030E3FFFF3C1808008F1800E83C090800B0
+:10E720008D2931C80043602130ABFFFF0183782B76
+:10E730000000C82101AB18210000502103197021ED
+:10E74000006B302B012A402101CF2021010610212E
+:10E750003C010800AC2C00EC3C010800AC2400E8B3
+:10E760003C010800AC2331CC3C010800AC2231C88C
+:10E7700003E00008000000008C8840008F8C000837
+:10E78000110C00323C0D800095AB010E3C0A0800D4
+:10E790008D4A00E43C0808008D0800E03169FFFF65
+:10E7A000014928210000302100A9602B01063821F1
+:10E7B00000EC10213C010800AC2500E43C010800FD
+:10E7C000AC2200E003E00008000000009483010E8A
+:10E7D0009482010E3C1908008F3900F43C090800AE
+:10E7E0008D2931CC3C0E08008DCE00F03C0808008D
+:10E7F0008D0831C83078FFFF304BFFFF03382821E8
+:10E80000012B1821000078210000502100B8682B4E
+:10E8100001CF6021006B302B010A3821018D2021AE
+:10E8200000E610213C010800AC2500F43C01080082
+:10E83000AC2400F03C010800AC2331CC3C010800C2
+:10E84000AC2231C803E00008000000008C894004BD
+:10E850008F8600101526FFCC3C0D80009483010E9E
+:10E860003C1908008F3931BC3C0E08008DCE31B800
+:10E870003078FFFF03385821000078210178202BE1
+:10E8800001CF682101A450213C010800AC2B31BC10
+:10E890003C010800AC2A31B803E000080000000089
+:10E8A00027BDFFE83C058000AFBF0014AFB00010EB
+:10E8B0008CB00128ACB000208CA301048CA4010012
+:10E8C000AF8300040E000ED6AF84000C0E00115F63
+:10E8D000000000003C0208008C4200C010400026EE
+:10E8E0008F8400043C0708008CE700C424E6000184
+:10E8F0003C010800AC2600C43C0280008C4401248A
+:10E900003C1F6020AFE40014000000003C068000C3
+:10E910003C034000ACC301380000000012000013AB
+:10E920008FBF0014260F0140261900802404FF80A9
+:10E9300001E4C0240324F824001F6940332E007F23
+:10E940000018594031EC007F3C0A20003548000295
+:10E9500001AE3825016C48250128802500E82825CE
+:10E96000ACC50830ACD008308FBF00148FB0001099
+:10E9700003E0000827BD00183C090010008940246E
+:10E980001100000F8F83000C240DBFFF006D602469
+:10E9900011800007240F87FF006F702415C000133B
+:10E9A0003C1900600099C024130000100000000012
+:10E9B0000E000CD2000000000A001221000000002E
+:10E9C0003C0B08008D6B0020256A00013C0108000B
+:10E9D000AC2A00200E000FC5000020211040FFCC03
+:10E9E0003C0680000A0011E93C0280000E00128EF5
+:10E9F000000000000A0012210000000027BDFFE80F
+:10EA00003C028000AFBF00108C4601403C03700008
+:10EA10003C054000AC4600208C4401480083202483
+:10EA20001085001300A4102B1040000B3C072000A1
+:10EA30003C08600010880017000000003C0A4000FD
+:10EA40003C098000AD2A0178000000008FBF001053
+:10EA500003E0000827BD00185487FFF93C0A400076
+:10EA60000E00110A000000000A00123A3C0A4000A1
+:10EA70000E0012B4000000003C0A40003C09800077
+:10EA8000AD2A0178000000008FBF001003E00008ED
+:10EA900027BD00180E001D6F000000000A00123A8A
+:10EAA0003C0A400027BDFFE0AFB200183C128000D6
+:10EAB000AFB10014AFBF001CAFB000100E00112D9D
+:10EAC000365100708E260000AF8600188E28000098
+:10EAD0003C0B08008D6B00FC3C0708008CE700F83D
+:10EAE00001066023016C28210000482100AC302B76
+:10EAF00000E91821006620213C010800AC2500FC3B
+:10EB00003C010800AC2400F88E50000032020003E3
+:10EB10001040FFEE010030218E2600003C05080069
+:10EB20008CA500FC3C1F08008FFF00F800C81823CC
+:10EB300000A378210000102101E3C82B03E2C021CB
+:10EB400003197021320D00013C010800AC2F00FCBC
+:10EB5000AF8800183C010800AC2E00F815A0000892
+:10EB600000000000320800021100FFD60000000083
+:10EB70000E001229000000000A00125B00000000D5
+:10EB80000E0011D2000000000A00128432080002B8
+:10EB90003C0380008C6401003082003E1440000879
+:10EBA00000000000AC6000488C66010030C507C062
+:10EBB00010A0000500000000AC60004CAC600050EC
+:10EBC00003E0000824020001AC600054AC60004087
+:10EBD0008C6801003107380010E0FFF900000000E8
+:10EBE0002402000103E00008AC6000443C039000F4
+:10EBF00034620001008220253C038000AC640020C8
+:10EC00008C65002004A0FFFE0000000003E0000867
+:10EC1000000000003C0280003443000100832025F6
+:10EC200003E00008AC44002027BDFFD8AFB10014BA
+:10EC30003C048000AFBF0020AFB3001CAFB200188F
+:10EC4000AFB000108C9201408C9001482402000E5D
+:10EC500000108C02322300FF1062005902042824A5
+:10EC60002866000F10C00013286A0037240700062A
+:10EC70001067008E286800075100002D2404000949
+:10EC8000106000783C06800024090001106900B083
+:10EC9000000000000000000D8FBF00208FB3001C9B
+:10ECA0008FB200188FB100148FB0001003E000087D
+:10ECB00027BD002811400059240D0038286B00356D
+:10ECC000116000053C058000240C001F146CFFF14E
+:10ECD000000000003C0580008CB801B80700FFFE72
+:10ECE00034B90180AF320000241F00012412000259
+:10ECF0003C021000AF200004A7310008A33F000A27
+:10ED0000A332000BA7300010AF200024AF20002852
+:10ED1000ACA201B88FBF00208FB3001C8FB20018C7
+:10ED20008FB100148FB0001003E0000827BD002849
+:10ED3000106400232405000B1465FFD63218FFFF72
+:10ED4000170000203C0580008F93FED4927F0005C1
+:10ED500033F900041720FFCF000000000E0012A5B9
+:10ED6000024020219269000502402021352800043C
+:10ED70000E0012AFA26800059267000530E20004A1
+:10ED800014400002000000000000000D926B000023
+:10ED900024060020316A00FF1546000A3C05800069
+:10EDA0008CA401B80480FFFE34AD0180240E000560
+:10EDB0003C0C1000ADB20000A1AE000BACAC01B831
+:10EDC0003C0580008CA301B80460FFFE34AF0180D5
+:10EDD00024130002ADE00000ADF20004A5F100082C
+:10EDE000A1F3000AA1F3000BA5F00010ADE0002490
+:10EDF0008CB101443C101000ADF10028ACB001B85A
+:10EE00008FBF00208FB3001C8FB200188FB1001489
+:10EE10008FB0001003E0000827BD0028106DFFAD83
+:10EE2000240E0080146EFF9B000000003C05800053
+:10EE30008CA301B80460FFFE34AF018024120002ED
+:10EE4000A1F2000BA5F10008A5F000108CB301445D
+:10EE50003C021000A5F30012ACA201B80A0012F0A7
+:10EE60008FBF00208CC301B80460FFFE34D3018043
+:10EE7000AE720000AE60000424120001A67100080A
+:10EE800024110002A272000AA271000BA6700010E9
+:10EE90008CD001443C0F1000AE700024AE600028FE
+:10EEA000ACCF01B80A00132B8FBF00203C038000B9
+:10EEB0008C6601B804C0FFFE346201803C06080085
+:10EEC00090C67AB8AC52000010C000030000382190
+:10EED0003C0708008CE77AC03C05800034AA01801A
+:10EEE0002404000234CC0001AC470004A551000802
+:10EEF000A14C000AA144000BA55000108CAB0144AA
+:10EF00000000202101402821AD4B002410C0000347
+:10EF10008FBF00203C0408008C847ABC8FB3001C97
+:10EF20008FB200188FB100148FB000103C0E10008B
+:10EF30003C0D800027BD0028ACA40028ADAE01B870
+:10EF40003C010800A0207AB803E00008000000009F
+:10EF500010A0000B3C0680008C980144241900028C
+:10EF60003C010800A0397AB83C010800AC327AC0F4
+:10EF70003C010800AC387ABC0A00132B8FBF00207C
+:10EF80008CDF01B807E0FFFE34C7018024090002CE
+:10EF9000ACE00000ACF20004A4F10008A0E9000A13
+:10EFA000A0E9000BA4F00010ACE000248CC80144E0
+:10EFB0003C021000ACE80028ACC201B80A00132BD8
+:10EFC0008FBF002027BDFFE8AFBF00100E000ED698
+:10EFD000000000003C0280008FBF001000002021D4
+:10EFE000AC4001800A000FC527BD00183084FFFF28
+:10EFF00030A5FFFF108000070000182130820001BB
+:10F000001040000200042042006518211480FFFB1C
+:10F010000005284003E000080060102110C0000730
+:10F02000000000008CA2000024C6FFFF24A50004FD
+:10F03000AC82000014C0FFFB2484000403E000083D
+:10F040000000000010A0000824A3FFFFAC86000011
+:10F0500000000000000000002402FFFF2463FFFF07
+:10F060001462FFFA2484000403E00008000000009A
+:10F0700027BDFFE0AFB20018AFB10014AFB0001071
+:10F08000AFBF001C9486000C00A0902124900014B7
+:10F0900000061B020003108000448821000030217C
+:10F0A00000A020210E0013BB240500050211202B17
+:10F0B0001080001200001021920300002C6500094E
+:10F0C00050A0000992020001000348803C0A080099
+:10F0D000254A793C012A40218D07000000E0000804
+:10F0E0000000000092020001020280210211202B88
+:10F0F0005480FFF292030000000010218FBF001C1B
+:10F100008FB200188FB100148FB0001003E0000818
+:10F1100027BD00200A0013D526100001920C000123
+:10F12000240B000C158B0040023070232DCD000AFB
+:10F1300015A0003D260800068E43000026020002AE
+:10F1400034640100AE440000921F00029059000197
+:10F15000904E0002904B0003001F7E000019C40077
+:10F1600001F86025000E6A00018D5025014B4825ED
+:10F17000AE490004920700069105000191040002C7
+:10F180009119000300071E00000534000066F825F1
+:10F190000004120003E2C025031978252610000A96
+:10F1A0000A0013D5AE4F0008921F0001260400028A
+:10F1B0002410000257F00001022020210A0013D57C
+:10F1C00000808021920E0001240D000315CDFFCB9D
+:10F1D000240200018E59000092180002261000033C
+:10F1E000372F0008A25800100A0013D5AE4F0000B8
+:10F1F000920500012406000414A6FFC024020001A9
+:10F20000920C0002920B00038E490000000C520089
+:10F21000014B40253527000426100004AE48000CA1
+:10F220000A0013D5AE4700000A0013E924020001CA
+:10F2300027BDFFE8AFBF0014AFB000100E0012A54D
+:10F24000008080213C048008348300809065002584
+:10F250000200202134A200200E0012AFA06200257F
+:10F26000020020218FBF00148FB000100A000C9EF6
+:10F2700027BD00183C03800027BDFFF834620180E1
+:10F28000AFA20000308C00FF30AD00FF30CE00FF99
+:10F290003C0B80008D6401B80480FFFE000000007C
+:10F2A0008FA900008D6801288FAA00008FA7000099
+:10F2B0008FA400002405000124020002A085000A9A
+:10F2C0008FA30000359940003C051000A062000BA0
+:10F2D0008FB800008FAC00008FA600008FAF000039
+:10F2E00027BD0008AD280000AD400004AD8000241B
+:10F2F000ACC00028A4F90008A70D0010A5EE00126C
+:10F3000003E00008AD6501B83C06800827BDFFE8B2
+:10F3100034C50080AFBF001090A70009240200127E
+:10F3200030E300FF1062000B008030218CA80050F9
+:10F3300000882023048000088FBF00108CAA0034AE
+:10F34000240400390000282100CA482305200005B4
+:10F35000240600128FBF00102402000103E0000801
+:10F3600027BD00180E001447000000008FBF0010DA
+:10F370002402000103E0000827BD001827BDFFC8D4
+:10F38000AFB1002C00A08821AFB2003027A500103B
+:10F390000080902102202021AFBF00340E0013C650
+:10F3A000AFB00028144000813C0C8008918B001104
+:10F3B000918A0012358600808CC80054316500FFA8
+:10F3C000314900FF00A9282100A8382B14E0004F84
+:10F3D0008FA3001094DF005C3066000410C000565C
+:10F3E00033E4FFFF8FA2001C0082102B5440000565
+:10F3F0002C8300803067000414E0007E240402188F
+:10F400002C83008010600002008080212410008086
+:10F410000E0012A5024020213C03800834660080C3
+:10F4200024070001ACC7000C90C200080010604027
+:10F4300034670100305F007FA0DF00088E390004D0
+:10F4400027380001ACD80030A4D0005C8CCE003C42
+:10F45000962F000E01CF6821ACCD00208CCB003C54
+:10F46000016C5021ACCA001C8E290004ACE90000DC
+:10F470008E250008ACE500048FA8001031040008B8
+:10F480005480002F93A60020A0C0004E90C5004ECF
+:10F490002408FFDF3C188008A0E5000890C400089D
+:10F4A000370C00802409005000888024A0D0000878
+:10F4B0008E390008AD9900388F0E00148D8F003002
+:10F4C00001CF6821AD8D0034918B0000316A00FFBF
+:10F4D00011490029264801000E0012AF02402021E8
+:10F4E00024040038000028210E0014472406000AD6
+:10F4F0008FBF00348FB200308FB1002C8FB0002846
+:10F500002402000103E0000827BD003894D8005C05
+:10F510008CD00054330EFFFF0205782301CF682BF7
+:10F5200015A0FFAC8FA300108CD9005430660004E6
+:10F5300014C0FFAC032520230A0014A52C82021856
+:10F540003C188008370C0080A0E600088E390008BF
+:10F5500024090050AD9900388F0E00148D8F0030B3
+:10F5600001CF6821AD8D0034918B0000316A00FF1E
+:10F570001549FFD9264801002406FF8001062824EA
+:10F580003C048000AC8500288E2700083103007FF2
+:10F590003C10800C0070F821AFE700D08E220008EC
+:10F5A000AF9F00240A0014E0AFE200D48E230008CD
+:10F5B0003C04800834820080AC4300540240202187
+:10F5C0000E001436AC400030240400382405008DB1
+:10F5D0000E001447240600128FBF00348FB2003093
+:10F5E0008FB1002C8FB000282402000103E0000836
+:10F5F00027BD00380A0014AA8FA4001C27BDFFE80D
+:10F60000AFBF001090A6000D30C7001010E0000C36
+:10F61000008040213C0280088C4400048CA3000838
+:10F620001064000830C9000430C5000410A0001C9C
+:10F630008FBF00102402000103E0000827BD00185E
+:10F6400030C900041120001030CB001210E0FFF987
+:10F650008FBF00103C0880088CA700088D060004AE
+:10F6600014E6FFF524020001240400382405008D6F
+:10F670000E001447240600128FBF00102402000160
+:10F6800003E0000827BD0018240A0012156AFFE9EC
+:10F690008FBF0010010020210A00148927BD001827
+:10F6A000000020210A000CB827BD00183C05080006
+:10F6B00024A555983C040800248473583C02080093
+:10F6C000244255A0240300063C010800AC257AC85A
+:10F6D0003C010800AC247ACC3C010800AC227AD072
+:10F6E0003C010800A0237AD403E0000800000000D9
+:10F6F00003E00008240200013C028000308800FF83
+:10F70000344701803C0680008CC301B80460FFFED2
+:10F71000000000008CC501282418FF803C0D800AE1
+:10F7200024AF010001F8702431EC007FACCE00243E
+:10F73000018D2021ACE50000948B00DA35096000D2
+:10F7400024080002316AFFFFACEA00042402000131
+:10F75000A4E90008A0E8000BACE000243C0710007E
+:10F76000ACC701B8AF84002403E00008AF850054A3
+:10F770008C9900048F8D00242409FFBF0325C0232A
+:10F78000AC98000491AF00C42403FFEF31EE007F7A
+:10F79000A1AE00C48C8C0020938B00308F86002497
+:10F7A000358A0002AF8B0048A7800044AC8A002055
+:10F7B000A4C000AC90C800C401093824A0C700C48C
+:10F7C0008F840024AC8000DC908500C400A310244A
+:10F7D00003E00008A08200C43C02800034450180A0
+:10F7E0003C0480008C8301B80460FFFE8F890054C4
+:10F7F0002407608324060002ACA900008C88012441
+:10F80000ACA80004A4A70008A0A6000B3C051000AB
+:10F8100003E00008AC8501B8938800308F89004868
+:10F820008F82002430C600FF0109382330E900FF31
+:10F830000122182130A500FF2468007810C00002C2
+:10F84000012438210080382130E4000314800003B3
+:10F8500030AA00031140000D312B000310A0000955
+:10F860000000102190ED0000244E000131C200FF85
+:10F870000045602BA10D000024E700011580FFF971
+:10F880002508000103E00008000000001560FFF3F8
+:10F890000000000010A0FFFB000010218CF8000009
+:10F8A00024590004332200FF0045782BAD180000D6
+:10F8B00024E7000415E0FFF92508000403E0000830
+:10F8C0000000000093850030938800408F87004837
+:10F8D000000432003103007F00E5102B30C47F00AC
+:10F8E0001040000F006428258F8400243C0980000C
+:10F8F0008C8A00DCAD2A00A43C03800000A35825BC
+:10F90000AC6B00A08C6C00A00580FFFE0000000026
+:10F910008C6D00ACAC8D00DC03E000088C6200A8AC
+:10F920000A0015E88F840024938800413C0280007F
+:10F9300000805021310300FEA383004130ABFFFF64
+:10F9400030CC00FF30E7FFFF344801803C098000E5
+:10F950008D2401B80480FFFE8F8D005424180016FA
+:10F96000AD0D00008D2201248F8D0024AD02000416
+:10F970008D590020A5070008240201B4A119000A2E
+:10F98000A118000B952F01208D4E00088D47000413
+:10F99000978300448D59002401CF302100C72821CE
+:10F9A00000A320232418FFFFA504000CA50B000EC4
+:10F9B000A5020010A50C0012AD190018AD18002406
+:10F9C00095AF00D83C0B10002407FFF731EEFFFF86
+:10F9D000AD0E00288DAC0074AD0C002CAD2B01B821
+:10F9E0008D46002000C7282403E00008AD45002014
+:10F9F0008F8800240080582130E7FFFF910900C65E
+:10FA00003C02800030A5FFFF312400FF00041A00F3
+:10FA10000067502530C600FF344701803C09800054
+:10FA20008D2C01B80580FFFE8F820054240F001733
+:10FA3000ACE200008D390124ACF900048D7800207F
+:10FA4000A4EA0008241901B4A0F8000AA0EF000BF2
+:10FA5000952301208D6E00088D6D0004978400446D
+:10FA600001C35021014D602101841023A4E2000C48
+:10FA7000A4E5000EA4F90010A4E60012ACE0001406
+:10FA80008D780024240DFFFFACF800188D0F006C5A
+:10FA9000ACEF001C8D0E00683C0F1000ACEE002097
+:10FAA000ACED0024950A00AE240DFFF73146FFFFB0
+:10FAB000ACE60028950C00709504007231837FFF3E
+:10FAC0000003CA003082FFFF0322C021ACF8002CE3
+:10FAD000AD2F01B8950E00728D6A002000AE302166
+:10FAE000014D2824A506007203E00008AD65002042
+:10FAF0003C028000344601803C0580008CA301B8A4
+:10FB00000460FFFE24090018ACC40000A0C9000B6B
+:10FB10008F8800243C041000950700AEA4C7001095
+:10FB2000ACC0003003E00008ACA401B83C02800087
+:10FB3000344501803C0480008C8301B80460FFFEE2
+:10FB40008F8A002C240600199549001C3128FFFFDC
+:10FB5000000839C0ACA70000A0A6000B3C051000AF
+:10FB600003E00008AC8501B88F8700340080402195
+:10FB700030C400FF3C0680008CC201B80440FFFE88
+:10FB80008F8900549383005034996000ACA9000021
+:10FB9000A0A300058CE20010240F00022403FFF74D
+:10FBA000A4A20006A4B900088D180020A0B8000A7D
+:10FBB000A0AF000B8CEE0000ACAE00108CED00048A
+:10FBC000ACAD00148CEC001CACAC00248CEB002021
+:10FBD000ACAB00288CEA002C3C071000ACAA002C2F
+:10FBE0008D090024ACA90018ACC701B88D05002010
+:10FBF00000A3202403E00008AD04002093850050FA
+:10FC00002403000127BDFFE800A330042CA200203C
+:10FC1000AFB00010AFBF001400C018211040001397
+:10FC20002410FFFE3C0708008CE7319000E610240A
+:10FC30003C0880003505018014400005240600843E
+:10FC40008F890024240A00042410FFFFA12A00EC5D
+:10FC50000E00168400000000020010218FBF001467
+:10FC60008FB0001003E0000827BD00183C06080014
+:10FC70008CC631940A0016B600C310248F87002C5E
+:10FC800027BDFFE0AFB20018AFB10014AFB0001055
+:10FC9000AFBF001C30D000FF90E6000D00A088210F
+:10FCA0000080902130C5007FA0E5000D8F850024E5
+:10FCB0008E2300188CA200C01062002E240A000EB1
+:10FCC0000E0016A9A38A00502409FFFF1049002244
+:10FCD0002404FFFF52000020000020218E26000097
+:10FCE0003C0C001000CC5824156000393C0E000874
+:10FCF00000CE682455A0003F024020213C1800029D
+:10FD000000D880241200001F3C0A00048F87002CBA
+:10FD10008CE200148CE300108CE500140043F823FF
+:10FD200003E5C82B13200005024020218E24002C5F
+:10FD30008CF10010109100310240202124020012A9
+:10FD4000A38200500E0016A92412FFFF10520002D9
+:10FD50002404FFFF000020218FBF001C8FB2001879
+:10FD60008FB100148FB000100080102103E0000854
+:10FD700027BD002090A800C4350400200A0016DF2B
+:10FD8000A0A400C400CA48241520000B8F8B002CAF
+:10FD90008F8D002C8DAC00101580000B02402021AF
+:10FDA0008E2E002C51C0FFEC0000202102402021AB
+:10FDB0000A0016FA240200178D66001050C0FFE6F4
+:10FDC00000002021024020210A0016FA240200111E
+:10FDD00002402021240200150E0016A9A382005023
+:10FDE000240FFFFF104FFFDC2404FFFF0A0016E979
+:10FDF0008E2600000A001720240200143C0800048C
+:10FE000000C8382450E0FFD4000020210240202107
+:10FE10000A0016FA240200138F86002427BDFFE093
+:10FE2000AFB10014AFBF0018AFB0001090C300C452
+:10FE300030A500FF306200201040000800808821BB
+:10FE40008CCB00C02409FFDF256A0001ACCA00C0CA
+:10FE500090C800C401093824A0C700C414A0004001
+:10FE60003C0C80008F840024908700C42418FFBFBE
+:10FE70002406FFEF30E3007FA08300C4979F004477
+:10FE80008F8200488F8D002403E2C823A799004485
+:10FE9000A5A000AC91AF00C401F87024A1AE00C4CD
+:10FEA0008F8C0024A18000C78F8A0024A540007297
+:10FEB000AD4000DC914500C400A65824A14B00C40D
+:10FEC0008F9000208F8400489786004402042821E8
+:10FED00010C0000FAF850020A38000403C078000C9
+:10FEE0008E2C000894ED01208E2B0004018D5021F2
+:10FEF000014B8021020620233086FFFF30C8000F0F
+:10FF0000390900013131000116200009A3880040A1
+:10FF1000938600308FBF00188FB100148FB000108F
+:10FF200027BD0020AF85004C03E00008AF860048E5
+:10FF300000C870238FBF0018938600308FB1001463
+:10FF40008FB0001034EF0C00010F282127BD0020D6
+:10FF5000ACEE0084AF85004C03E00008AF8600489B
+:10FF600035900180020028210E00168424060082AC
+:10FF70008F840024908600C430C5004050A0FFBA92
+:10FF8000A38000508F8500343C0680008CCD01B8E2
+:10FF900005A0FFFE8F890054240860822407000218
+:10FFA000AE090000A6080008A207000B8CA30008F9
+:10FFB0003C0E1000AE0300108CA2000CAE02001428
+:10FFC0008CBF0014AE1F00188CB90018AE190024A5
+:10FFD0008CB80024AE1800288CAF0028AE0F002C7F
+:10FFE000ACCE01B80A001744A38000508F8A0024C9
+:10FFF00027BDFFE0AFB10014AFB000108F880048FC
+:020000040001F9
+:10000000AFBF001893890028954200AC30D100FFA3
+:100010000109182B0080802130AC00FF3047FFFF22
+:100020000000582114600003310600FF0120302138
+:1000300001095823978300440068202B1480001B7B
+:100040000000000010680043240A0001118A0048E3
+:1000500034E708803165FFFF0E00162602002021DC
+:100060000E0016668F8400548F840024948D0070D7
+:1000700025AC0001A48C0070948B00703C06080035
+:100080008CC6318831677FFF10E6004F000000000A
+:1000900002002021022028218FBF00188FB10014F8
+:1000A0008FB000100A00173027BD0020914400C413
+:1000B0002406FF8000868825A15100C4978400444F
+:1000C0003088FFFF1100001C938900288F8E0024C8
+:1000D0002419EFFF008BF82395D800AC0168682B3A
+:1000E00033E900FF03197824A5CF00AC51A0002A02
+:1000F000010058218E0500202408FFFB2403000185
+:1001000000A81024AE0200201183002534E78000EF
+:10011000020020213165FFFF0E001626012030214C
+:10012000978B00448F870048A780004400EB802312
+:10013000AF900048938900288F8C00248FBF00184F
+:100140008FB100148FB0001027BD002003E000081D
+:10015000A18900C78E0800202409FFFB34E7800036
+:1001600001092824AE050020158AFFBA34E708806B
+:10017000020020210E0015F43165FFFF020020214E
+:10018000022028218FBF00188FB100148FB00010FB
+:100190000A00173027BD00200A0017E70000482199
+:1001A000020020213165FFFF0E0015F401203021EF
+:1001B000978B00448F870048A780004400EB802382
+:1001C0000A0017F7AF90004894890070240A800055
+:1001D000012A4024A48800709085007090990070D6
+:1001E00030A200FF000219C20003F827001FC1C09F
+:1001F000332F007F01F87025A08E00700A0017CF02
+:10020000020020218F88002424030001910A007835
+:10021000910500C7250900783147003F24E6FFE03B
+:1002200000C318042CC2002030670019A3850028E1
+:100230001040001AAF8900343C0A8000354B0002A0
+:10024000240500012406000114E00016006B1024B0
+:10025000000028211440000F306300201060000FC0
+:10026000240500018D0600748D1900742403FF809D
+:1002700000C31024000279403338007F01F868255C
+:100280003C0E100001AE6025AD4C083091280001F5
+:10029000310600010A0017A50000000003E0000875
+:1002A000000000008D0F00748D0D00742418FF8075
+:1002B00001F87024000E414031AC007F010C502544
+:1002C0003C0B1000014B38253C0980000A0017A5A3
+:1002D000AD27083027BDFFD8AFB000108F90003495
+:1002E000AFB40020AFB10014AFBF0024AFB3001C07
+:1002F000AFB200188E0500103C0208008C4231B0ED
+:100300008F86003830A73FFF00E2182B8CD20014F4
+:10031000008088218CD30020106000070000A021FD
+:1003200090CB000D240AFF80014B4824312800FFA8
+:100330001500000C00056382022020212411000D0D
+:10034000A39100508FBF00248FB400208FB3001CF6
+:100350008FB200188FB100148FB000100A0016A9D8
+:1003600027BD00283185000354A0FFF4022020217E
+:1003700094CF001C8F8E00248E070028A5CF00D8B4
+:100380008CCD0010024D302310E6005C2402001FCB
+:100390000E0016A9A3820050241FFFFF105F004E1D
+:1003A0002404FFFF8F83003C8F88002C0263982178
+:1003B0008D090010012310238F83001CAD02001053
+:1003C000AD1300208C67007400F3202B14800062B2
+:1003D000022020218F8600388E0C00248CC500243A
+:1003E0001185000702202021240E001C0E0016A9F2
+:1003F000A38E0050240DFFFF104D00372404FFFF93
+:100400008F84002C8C980024270F0001AC8F0024CF
+:10041000127200448F99001C8F32007412530041F5
+:100420003C0A00808E090000012A10241440003A82
+:10043000000000008E0400142412FFFF109200063A
+:10044000240B001B022020210E0016A9A38B0050B4
+:10045000105200212404FFFF8E0300003C0C000119
+:10046000006C282410A000133C0600800066A02425
+:10047000168000090200282102202021240E001AE3
+:100480000E0016A9A38E0050240DFFFF104D001280
+:100490002404FFFF02002821022020210E0016C99B
+:1004A000240600012410FFFF2404FFFF1050000A5F
+:1004B000241400018F8F002C022020210280302183
+:1004C00095F2003424050001265800010E0017A5FE
+:1004D000A5F80034000020218FBF00248FB4002035
+:1004E0008FB3001C8FB200188FB100148FB00010B2
+:1004F0000080102103E0000827BD00288F83003C06
+:1005000000E3C8210259C02B1300FFA88F88002CDC
+:100510000A00188E24020018AC8000200A0018B8C7
+:100520008E0400148E1F00003C07008003E798240F
+:100530001660FFF92408001A022020210E0016A9D7
+:10054000A38800502403FFFF1443FFBA2404FFFFD5
+:100550000A0018E18FBF0024240B001D0E0016A90D
+:10056000A38B0050240AFFFF144AFF9A2404FFFFC4
+:100570000A0018E18FBF00248F85002427BDFFD813
+:10058000AFB3001CAFB20018AFB10014AFB0001091
+:10059000AFBF002090A700C48F9000342412FFFF4B
+:1005A00034E2004092060000A0A200C48E030010B6
+:1005B000008098211072000630D1003F2408000D01
+:1005C0000E0016A9A3880050105200262406FFFF33
+:1005D0008F8A00248E0900188D4400C01124000762
+:1005E000240C000E026020210E0016A9A38C0050DE
+:1005F000240BFFFF104B001B2406FFFF24040020E8
+:10060000122400048F8D002491AF00C435EE002029
+:10061000A1AE00C48F85003C10A0001A00000000AD
+:100620001224004B8F9800248F92FED42406FFFDE5
+:10063000971000709651000A1230000B8FBF0020F7
+:100640003C1F08008FFF318C03E5C82B1720001ECC
+:1006500002602021000028210E0017A524060001B9
+:10066000000030218FBF00208FB3001C8FB2001814
+:100670008FB100148FB0001000C0102103E00008FB
+:1006800027BD00285224002A8E0300148F840024E2
+:100690009489007025280001A48800709487007058
+:1006A0003C0508008CA5318830E27FFF1045000E24
+:1006B00000000000026020210E0017302405000118
+:1006C0000A001943000030212402002DA3820050AB
+:1006D0000E0016A92413FFFF1453FFE12406FFFFA9
+:1006E0000A0019448FBF00209498007024198000DC
+:1006F0002405000103199024A492007090910070C9
+:10070000908D0070323000FF001079C2000F70270A
+:10071000000E61C031AB007F016C5025A08A0070D3
+:100720000E001730026020210A001943000030211A
+:100730002406FFFF1466FFD68F8400240260202168
+:100740000E001730240500010A0019430000302173
+:10075000026020210A00195D2402000A8F8800240B
+:1007600027BDFFE8AFB00010AFBF0014910A00C46E
+:100770008F87003400808021354900408CE60010CE
+:10078000A10900C43C0208008C4231B030C53FFFD3
+:1007900000A2182B106000078F850038240DFF8001
+:1007A00090AE000D01AE6024318B00FF1560000893
+:1007B0000006C382020020212403000D8FBF001415
+:1007C0008FB0001027BD00180A0016A9A38300509F
+:1007D00033060003240F000254CFFFF7020020214C
+:1007E00094A2001C8F85002424190023A4A200D801
+:1007F0008CE8000000081E02307F003F13F900352E
+:100800003C0A00838CE800188CA600C01106000882
+:10081000000000002405000E0E0016A9A38500505C
+:100820002407FFFF104700182404FFFF8F850024D2
+:1008300090A900C435240020A0A400C48F8C002CF3
+:10084000918E000D31CD007FA18D000D8F83003C76
+:100850001060001C020020218F8400388C9800104A
+:100860000303782B11E0000D241900180200202149
+:10087000A39900500E0016A92410FFFF105000028B
+:100880002404FFFF000020218FBF00148FB0001050
+:100890000080102103E0000827BD00188C8600109E
+:1008A0008F9F002C0200202100C31023AFE2001014
+:1008B000240500010E0017A5240600010A0019CC2A
+:1008C000000020210E001730240500010A0019CC79
+:1008D00000002021010A5824156AFFD98F8C002CB2
+:1008E000A0A600EC0A0019B9A386004227BDFFD8D4
+:1008F000AFB000108F900034AFB20018AFBF00202F
+:10090000AFB3001CAFB100148E1100103C030800FF
+:100910008C6331B032253FFF00A3102B104000083C
+:10092000008090218F8600382409FF8090CA000D36
+:10093000012A4024310700FF14E0000B00116B82F4
+:10094000024020212412000DA39200508FBF0020EE
+:100950008FB3001C8FB200188FB100148FB000103D
+:100960000A0016A927BD002831AC0003240B0001A2
+:10097000558BFFF40240202190CF000D31EE00088E
+:1009800011C000608F93003C16600009240200270C
+:100990008E19000C8CD80020173800052402002086
+:1009A0008E0200088CDF0024105F0040240200202B
+:1009B0000E0016A9A38200502406FFFF1046003344
+:1009C0002404FFFF8F99002C240AFFF73C13800EAC
+:1009D0009329000D2404FF803C0D8000012AF82497
+:1009E000A33F000D8F99001C3C0808008D0831AC16
+:1009F0008F830054972700788F9F002C01031021CC
+:100A000030E57FFF000530400046782131F8007F57
+:100A10000313602101E47024ADAE002CA591000009
+:100A20008FEB0028256A0001AFEA00288FE3002C35
+:100A30008E09002C00694021AFE8002C8E07002CA5
+:100A4000AFE700308E050014AFE5003497E6003ABA
+:100A500024C20001A7E2003A973300783C10080056
+:100A60008E1031B02663000130717FFF12300027F5
+:100A7000006030218F8F001C0240202124050001DE
+:100A80000E001730A5E60078000020218FBF00205F
+:100A90008FB3001C8FB200188FB100148FB00010FC
+:100AA0000080102103E0000827BD00288E050014F7
+:100AB0002413FFFF10B3001D8F8300248E0800183D
+:100AC0008C6700C0150700092402000E8E0A00245E
+:100AD0008CC9002815490005240200218E07002832
+:100AE0008CCB002C10EB00132402001F0E0016A963
+:100AF000A38200501453FFB32404FFFF0A001A4ED0
+:100B00008FBF00200A001A1624020024240E800041
+:100B1000006E682431ACFFFF000C5BC2317100FF36
+:100B2000001180270A001A47001033C00A001A6516
+:100B3000240200258E05002C10A0FFEC24020023C7
+:100B40008F8E001C8DCD007401A5602B1580FFE7F2
+:100B5000240200268CCF001400A7C02101F8202B0E
+:100B60001080FF998F99002C024020210A001A65FD
+:100B70002402002227BDFFE0AFB000108F900034A8
+:100B8000AFB10014AFBF00188E0500103C03080081
+:100B90008C6331B00080882130A43FFF0083102B8C
+:100BA000104000078F8600382409FF8090CA000D8E
+:100BB000012A4024310700FF14E000098F8B003C1C
+:100BC0002410000D02202021A39000508FBF001898
+:100BD0008FB100148FB000100A0016A927BD0020A5
+:100BE000116000080005C3828F8F00248F8EFED411
+:100BF0002407FFFD95EC007095CD000A11AC00387C
+:100C00008FBF00183305000314A00010000000007F
+:100C10009219000213200041000000008E060024FB
+:100C200050C0000F92040003022020212402000F74
+:100C30000E0016A9A38200502408FFFF14480007E5
+:100C40002407FFFF0A001AE28FBF001890C3000DAF
+:100C50003064000810800037022020219204000335
+:100C600024070002308900FF15270005308F00FFA0
+:100C70008F8A003C11400031240C002C308F00FF83
+:100C800039E500102CAD00012DEE000102002821F5
+:100C900001CD30250E0016C9022020212410FFFFAF
+:100CA0001050000E2407FFFF8F83003C10600017D8
+:100CB000022020213C1908008F39318C0323C02BDE
+:100CC0005700000C2411002D0220202100002821B3
+:100CD0000E0017A524060001000038218FBF001860
+:100CE0008FB100148FB0001000E0102103E0000865
+:100CF00027BD00200E0016A9A39100501450FFF646
+:100D00002407FFFF0A001AE28FBF00180E001730F9
+:100D1000240500010A001AE1000038218CDF0024BC
+:100D20008E020024545FFFC1022020210A001AC253
+:100D3000920400030A001AB62402001002202021A7
+:100D40000E0016A9A38C0050240BFFFF104BFFE3ED
+:100D50002407FFFF0A001AC99204000330A500FF10
+:100D60002406000124A9000100C9102B1040000C2A
+:100D700000004021240A000100A61823308B000146
+:100D800024C60001006A38040004204211600002F9
+:100D900000C9182B010740251460FFF800A618238E
+:100DA00003E000080100102127BDFFD8AFB00018F4
+:100DB0008F900034AFB1001CAFBF00202403FFFFB1
+:100DC0002411002FAFA30010920600002405000894
+:100DD00026100001006620260E001B01308400FF53
+:100DE00000021E003C021EDC34466F410A001B2933
+:100DF0000000102110A000090080182124450001E6
+:100E000030A2FFFF2C4500080461FFFA00032040D8
+:100E10000086202614A0FFF9008018210E001B0177
+:100E2000240500208FA300102629FFFF313100FF89
+:100E300000034202240700FF1627FFE201021826E2
+:100E400000035027AFAA0014AFAA00100000302101
+:100E500027A8001027A7001400E6782391ED0003CF
+:100E600024CE000100C8602131C600FF2CCB000455
+:100E70001560FFF9A18D00008FA200108FBF002028
+:100E80008FB1001C8FB0001803E0000827BD0028B8
+:100E90009383003027BDFFE024020034AFB100147B
+:100EA000AFB00010AFBF001CAFB2001800808821A7
+:100EB0001062006200A080219204000414800045AA
+:100EC0008F880024A38000288E0500048D0600C8AA
+:100ED0003C0700FF34E3FFFF00A3282400C5102BCC
+:100EE0001440004DAF85003C978A00448F8700482E
+:100EF0000147102310A00032A78200448F98001CE5
+:100F0000304CFFFF9312007C0012788231F1000117
+:100F10000011708001C56821018D582B116000619E
+:100F20008F8600248F8900208F84004C1089005EFA
+:100F30003C023F018E1F00003C10250003E2C82444
+:100F40001730007A8F8400348F8700348F86002416
+:100F50008CE30000ACC300788CE50010ACC50088C1
+:100F60008F8700488F85003C938D002830AE0003AA
+:100F7000000E4023310A0003014D4021A3880028C0
+:100F800094CB00AC01276021AF8C002035691000A4
+:100F9000A4C900AC1620005101452021AF840048AF
+:100FA000000020218FBF001C8FB200188FB10014E9
+:100FB0008FB000100080102103E0000827BD002042
+:100FC0008F840020AF800048008730210A001B92E8
+:100FD000AF860020241F000CA39F00500E0016A90E
+:100FE000022020212419FFFF1059FFEE2404FFFFE7
+:100FF0008F880024A38000288E0500048D0600C879
+:101000003C0700FF34E3FFFF00A3282400C5102B9A
+:101010001040FFB5AF85003C0220202124090019B3
+:10102000A38900500E0016A92411FFFF1051FFDD07
+:101030002404FFFF0A001B648F85003C8F8400247A
+:101040008F8700348CF20030908600C430C50010C9
+:1010500014A000108F8300482C680005150000289C
+:1010600000000000908A00C4246BFFFC314900108E
+:1010700015200008316400FF8F8D004C8F8C0020FC
+:1010800011AC0004388F000131EE000115C0002FB3
+:10109000000000000E001B14000000000A001BEB03
+:1010A000000000008F890020938D002830AE0003DF
+:1010B000000E4023310A0003014D4021A38800287F
+:1010C00094CB00AC01276021AF8C00203569100063
+:1010D000A4C900AC1220FFB101452021251800044D
+:1010E000A398002894CF00AC24920004AF9200484B
+:1010F00035F12000A4D100AC0A001B930000202190
+:101100008C8200DC1242FF6C022020212418000592
+:10111000A39800500E0016A92412FFFF1452FF6678
+:101120002404FFFF0A001B948FBF001C30E500FF62
+:101130000E0015B0000030218F8600248F870048F4
+:101140008F8900200A001B848F85003C0E0015DB70
+:10115000000000000A001BEB000000009383004227
+:1011600027BDFFE024020002AFB20018AFB10014A7
+:10117000AFBF001C00808821AFB00010000090219C
+:10118000106200552404FFFD978300448F850048BA
+:101190003066FFFF00C5202B1480005B9387003072
+:1011A0003C0880009504012010E500528F8A002041
+:1011B0008F84004C30A500FF0E0015B024060001FE
+:1011C0008F9F00543C0580003C19408027ED01783A
+:1011D00031B00078240EFF800219582534AF090081
+:1011E00031B8000701AE6024ACAC0800030F8021C9
+:1011F000ACAB081002202021020028210E001B4E5B
+:10120000AF9000342403FFFF104300332404FFFF9A
+:101210008E0C00103C0708008CE731B092060000ED
+:1012200031843FFF0087102B1040002330CD003F5A
+:101230008F980054000471803C0408008C8431A80D
+:101240002409FF809390004100984021010E202145
+:1012500000897024000E51403C0980003099007FC5
+:101260003C0F00808F8800243525094035E20001BD
+:1012700001593825308B0078308600073C03100078
+:101280003C1F800C00C5C0210162582500E3502599
+:10129000033F782136050001AD2E0804AF980038D1
+:1012A000AD2B0814AF8F002CAD2E0028AD040074B8
+:1012B000AD2A0830A3850041938300422410000327
+:1012C0005070002725A3FFE0240C0001106C001CC7
+:1012D00024060023024020218FBF001C8FB200187B
+:1012E0008FB100148FB000100080102103E00008BF
+:1012F00027BD0020314900035520FFAE8F84004CEC
+:101300000A001C278F90004C8F84004C306500FF32
+:101310000E0015B024060001938B00302405003424
+:1013200011650018978300448F8500483062FFFFE5
+:1013300000A25823AF8B00480A001C5FA78000441E
+:1013400011A6003700000000022020212411000B0C
+:101350000E0016A9A39100500A001C5F00409021C6
+:101360002C7200201240FFF80003F8803C070800B0
+:1013700024E7796003E7C8218F2D000001A0000851
+:10138000000000008F8500482CA200055440001D7D
+:10139000A7800044978A00443148FFFF00A84823F3
+:1013A0002D2F000511E00003314400FF24AEFFFCA7
+:1013B00031C400FF8F90004C8F9800201218000459
+:1013C00038990001332D000115A00029000000000C
+:1013D0008F910024922500C434A30010A22300C4DE
+:1013E000978300448F8500488F8400243062FFFF7C
+:1013F00000A25823AC8000DCA78000440A001C5FD8
+:10140000AF8B00483062FFFF00A258230A001C5F28
+:10141000AF8B00482403FFFF11830005000000008C
+:101420000E001981022020210A001C5F004090213B
+:101430000E001908022020210A001C5F00409021A4
+:101440000E0019E5022020210A001C5F00409021B7
+:101450000E00185F022020210A001C5F004090212E
+:101460000E001A87022020210A001C5F00409021F4
+:101470000E0015DB00000000978300448F850048B4
+:10148000306CFFFF00AC38232CFF000553E0FFA8B1
+:101490003062FFFF8F860024A7800044ACC200DCCE
+:1014A0003062FFFF00A258230A001C5FAF8B004888
+:1014B00027BDFFD0AFB20018AFB00010AFBF0028FB
+:1014C000AFB50024AFB40020AFB3001CAFB100141F
+:1014D0003C0C80008D880128240FFF803C07800A87
+:1014E00025100100250B0080020F68243205007FC3
+:1014F000016F7024AD8E009000A72821AD8D0024CF
+:1015000090A700EC3169007F3C0A8004012A182171
+:10151000A38700429066007C00809021AF83001C6E
+:1015200030C20002AF880054AF85002400A018210B
+:10153000144000022404003424040030A38400304A
+:101540008C6600CC30F100FF24040004AF86004814
+:1015500012240004A38000508E5300041660001D66
+:101560003C0880009387004130F200011240000FD8
+:101570008FBF00288CB800748CA400742419FF80DD
+:101580000319882400117140308F007F01CF60253E
+:101590003C0D2000018D582530F500FE3C0A8000EE
+:1015A000AD4B0830A39500418FBF00288FB50024B4
+:1015B0008FB400208FB3001C8FB200188FB10014BD
+:1015C0008FB000102402000127BD003003E00008A6
+:1015D000ACA600CC8E590008951F01208E46001045
+:1015E000033FC0213307FFFF30F5000F32B4000185
+:1015F000AF8600201680003BA395004035060C0006
+:1016000002A6102100F51823AD030084AF82004C20
+:101610008E4900043128FFFF1100002BA7890044E8
+:101620002410FF803C1580003C1420000A001D4D52
+:101630002413FFFE90AE00C4020E682431AC00FFFC
+:101640001580002A0240202193840041978600449F
+:10165000308F000111E0000B026428248F890024E0
+:101660008D2300748D280074A38500410070102420
+:101670000002C940311F007F033FC02503148825A5
+:10168000AEB1083010C000108F85002490A700C4B0
+:1016900002075824316A00FF1540FFE6024020216E
+:1016A0000E001C01979100441040FFE89384004114
+:1016B0002405FFFD544500058E430020022028210B
+:1016C0000E001586024020218E4300203070000459
+:1016D0001600000A2414FFFB8F8500240A001D0356
+:1016E0008F8600480A001D2EAF86004C0E00182B76
+:1016F000000000000A001D3D9384004100749824FE
+:101700000E0015A0AE5300208F8500240A001D0393
+:101710008F86004827BDFFD8AFB3001CAFB10014BF
+:10172000AFBF0020AFB20018AFB000103C02800085
+:101730008C5201408C4B01483C048000000B8C0211
+:10174000322300FF317300FF8C8501B804A0FFFE37
+:1017500034900180AE1200008C8701442464FFF0B5
+:10176000240600022C830013AE070004A611000813
+:10177000A206000BAE1300241060004F8FBF0020A4
+:10178000000448803C0A0800254A79E0012A4021EB
+:101790008D04000000800008000000003C100800DC
+:1017A0008E1031A831733FFF001389800212282167
+:1017B000240CFF8000B12021264D01002647008027
+:1017C0003C0F80003C03800431A8007F30E9007F9B
+:1017D000308A007F3C0E800A3C02800C008CC024C2
+:1017E00001AC302400ECC82401239821014280215F
+:1017F000ADE60024010EF821ADF90090ADF8002807
+:10180000AF90002CAF9F0024AF93001C0E00167504
+:10181000016080213C0380008C6B01B80560FFFEF5
+:101820008F87002C8F8600243465018090F9000D8D
+:10183000ACB2000024C200780019C60000187E0374
+:10184000000F9027001227C2A4B00006108000707D
+:10185000240E6082A4AE0008A0A00005240F0002A0
+:10186000A0AF000B0004C4008F8B001C3C192700A4
+:1018700003199025ACB20010ACA00014ACA0002459
+:10188000ACA00028ACA0002C8D7300382411FF8080
+:10189000ACB3001890F0000D0230282430A400FFF3
+:1018A000108000058FBF002090EC000D319F007F5D
+:1018B000A0FF000D8FBF00208FB3001C8FB2001857
+:1018C0008FB100148FB000103C0A10003C0D800056
+:1018D00027BD002803E00008ADAA01B8265F01007B
+:1018E0002405FF8033F8007F3C06800003E5782460
+:1018F0003C19800A03192021ACCF0024908E00C42B
+:1019000000AE682431AC00FF1180FFEAAF840024F0
+:10191000248E007895CD00123C0C08008D8C31A8E7
+:101920003C03800C31AB3FFF01924821000B5180FA
+:10193000012A40213104007F010510240083382151
+:10194000ACC200280E001675AF87002C3C03800047
+:101950008C6501B804A0FFFE00000000AE1200007C
+:101960008C720144AE120004A6110008241100027A
+:10197000A211000BAE1300240A001DD88FBF002057
+:101980003C1260008E452C083C03F0033462FFFFDC
+:1019900000A2F824AE5F2C088E582C083C1901B028
+:1019A00003199825AE532C080A001DD88FBF0020BC
+:1019B000264D010031AF007F3C10800A240EFF80CD
+:1019C00001F0282101AE60243C0B8000AD6C0024A6
+:1019D0001660FFB8AF85002424110003A0B100EC0D
+:1019E0000A001DD88FBF002026480100310A007F61
+:1019F0003C0B800A2409FF80014B3021010920247F
+:101A00003C078000ACE400240A001DD7AF86002408
+:101A1000944D0012321F3FFF31AC3FFF159FFF8DE9
+:101A2000240E608290C300C42409FF800123102487
+:101A3000304A00FF1140FF87000000002407000427
+:101A4000A0C700EC8F87002C240860842406000DBA
+:101A5000A4A80008A0A600050A001DC2240F0002C9
+:101A60005F865437E4AC62CC50103A453662198533
+:101A7000BF14C0E81BC27A1E84F4B556094EA6FEF8
+:101A80007DDA01E7C04D7481800801008008008084
+:101A90008008000008004FBC08004FBC08005098A8
+:101AA0000800506C0800505008004F8C08004F8C04
+:101AB00008004F8C08004FC4080072BC080073086F
+:101AC000080072C8080071F0080072C8080072F8B7
+:101AD000080072C8080071F0080071F0080071F089
+:101AE000080071F0080071F0080071F0080071F052
+:101AF000080071F0080071F0080071F0080072E849
+:101B0000080072D8080071F0080071F0080071F048
+:101B1000080071F0080071F0080071F0080071F021
+:101B2000080071F0080071F0080071F0080071F011
+:101B3000080071F0080072D8080078900800775CFF
+:101B4000080078580800775C080078280800764478
+:101B50000800775C0800775C0800775C0800775C19
+:101B60000800775C0800775C0800775C0800775C09
+:101B70000800775C0800775C0800775C0800775CF9
+:041B8000080077845E
+:0C1B84000A000122000000000000000028
+:101B90000000000D747061342E362E3135000000C7
+:101BA00004060F010000000000000000000000001B
+:101BB0000000000000000000000000000000000025
+:101BC0000000000000000000000000000000000015
+:101BD0000000000000000000000000000000000005
+:101BE00000000000000000000000000000000000F5
+:101BF00000000000000000000000000000000000E5
+:101C000000000000000000000000000000000000D4
+:101C100010000003000000000000000D0000000D97
+:101C20003C020800244217C03C03080024632AB485
+:101C3000AC4000000043202B1480FFFD2442000430
+:101C40003C1D080037BD2FFC03A0F0213C1008000C
+:101C5000261004883C1C0800279C17C00E00025E5A
+:101C6000000000000000000D2402FF8027BDFFE0FF
+:101C700000821024AFB00010AF420020AFBF0018A8
+:101C8000AFB10014936500043084007F0344182131
+:101C90003C0200080062182130A50020036080216A
+:101CA0003C080111277B000814A000022466005C98
+:101CB0002466005892020004974301049204000431
+:101CC0003047000F3063FFFF308400400067282357
+:101CD00010800009000048219202000530420004F3
+:101CE000104000050000000010A0000300000000EC
+:101CF00024A5FFFC240900049202000530420004E0
+:101D0000104000120000000010A0001000000000B1
+:101D10009602000200A72021010440252442FFFE74
+:101D2000A7421016920300042402FF8000431024EF
+:101D3000304200FF104000033C0204000A00017220
+:101D4000010240258CC20000AF4210188F4201787A
+:101D50000440FFFE2402000AA7420140960200024E
+:101D6000240400093042000700021023304200071B
+:101D7000A7420142960200022442FFFEA74201440C
+:101D8000A740014697420104A74201488F4201083B
+:101D9000304200205040000124040001920200045F
+:101DA00030420010144000023483001000801821DB
+:101DB000A743014A000000000000000000000000EE
+:101DC00000000000AF48100000000000000000000C
+:101DD00000000000000000008F4210000441FFFEE0
+:101DE0003102FFFF104000070000000092020004D3
+:101DF0003042004014400003000000008F421018E1
+:101E0000ACC20000960200063042FFFF24420002EE
+:101E10000002104300021040036288219622000055
+:101E20001120000D3044FFFF00A710218F83003CDC
+:101E30008F45101C00021082000210800043102108
+:101E4000AC45000030A6FFFF0E0005B700052C02D0
+:101E500000402021A6220000920300042402FF80FB
+:101E600000431024304200FF1040001F000000001B
+:101E700092020005304200021040001B00000000EA
+:101E80009742100C2442FFFEA742101600000000EB
+:101E90003C02040034420030AF4210000000000059
+:101EA0000000000000000000000000008F42100051
+:101EB0000441FFFE000000009742100C8F45101CEB
+:101EC0003042FFFF244200300002108200021080E6
+:101ED000005B1021AC45000030A6FFFF0E0005B7E7
+:101EE00000052C02A62200009604000224840008AB
+:101EF0000E0001E73084FFFF974401040E0001F556
+:101F00003084FFFF8FBF00188FB100148FB0001016
+:101F10003C02100027BD002003E00008AF4201781A
+:101F20003084FFFF308200078F85002410400002BC
+:101F3000248300073064FFF800A4102130421FFF03
+:101F400003421821247B4000AF850028AF82002483
+:101F500003E00008AF4200843084FFFF3082000FAE
+:101F60008F85002C8F860034104000022483000FE0
+:101F70003064FFF000A410210046182BAF8500301C
+:101F80000046202314600002AF82002CAF84002C96
+:101F90008F82002C34048000034218210064182131
+:101FA000AF83003C03E00008AF4200808F82001442
+:101FB000104000088F8200048F82FFE41440000567
+:101FC0008F8200043C02FFBF3442FFFF00822024C6
+:101FD0008F82000430430006240200021062000FCA
+:101FE0003C0201012C620003504000052402000461
+:101FF0001060000F3C0200010A00022E00000000E9
+:1020000010620005240200061462000C3C0201115B
+:102010000A000227008210253C02001100821025D0
+:10202000AF421000240200010A00022EAF82000C11
+:1020300000821025AF421000AF80000C00000000AD
+:10204000000000000000000003E0000800000000A5
+:102050008F82000C10400004000000008F4210002E
+:102060000441FFFE0000000003E000080000000043
+:102070008F820010000229C224A3FFF0000318423F
+:102080002444F80000031140004310210002108096
+:1020900000431021000210803C0308002463180054
+:1020A0002C84030114800013004330218F84001816
+:1020B00000A4102B1440000F0000302100A41023B6
+:1020C00000021940006218210003188000621821E4
+:1020D0008F82001C008210212442FFFF0045102B3C
+:1020E00014400004000318803C02080024421A1423
+:1020F0000062302103E0000800C0102127BDFFE08E
+:10210000AFBF0018AFB10014AFB000103C046008BE
+:102110008C8250002403FF7F3C06600000431024A3
+:102120003442380CAC8250008CC24C1C3C1A8000EB
+:10213000000216023042000F10400007AF82001C60
+:102140008CC34C1C3C02001F3442FC00006218246B
+:10215000000319C2AF8300188F420008275B4000BC
+:1021600034420001AF420008AF8000243C02601CF2
+:10217000AF400080AF4000848C4500088CC3080845
+:1021800034028000034220212402FFF00062182460
+:102190003C0200803C010800AC2204203C025709AC
+:1021A000AF84003C14620004AF85003424020001B7
+:1021B0000A00028EAF820014AF8000143C0280003F
+:1021C000344400708C8300008F42000038420001CC
+:1021D0003042000110400018AF83003800804021D9
+:1021E000006030218D0700003C0508008CA5045CD0
+:1021F0003C0408008C84045800E6302300001021C1
+:1022000000A6282100A6302B008220210086202154
+:102210003C010800AC25045C3C010800AC240458D7
+:102220008F42000038420001304200011440FFEDAF
+:1022300000E03021AF8700383C028000344200705B
+:102240008C4700008F8600383C0508008CA5045C94
+:102250003C0408008C84045800E638230000102158
+:1022600000A72821008220218F82001400A7302B94
+:10227000008620213C010800AC25045C3C010800DC
+:10228000AC240458104000160000000097420104DE
+:10229000104000058F830000146000072462FFFFD8
+:1022A0000A0002D02C62000A2C6200105040000488
+:1022B0008F83000024620001AF8200008F83000042
+:1022C0002C62000A144000032C6200070A0002D7A7
+:1022D000AF80FFE41040000224020001AF82FFE45F
+:1022E0008F4301088F44010030622000AF83000457
+:1022F00010400008AF8400103C0208008C42042CFF
+:10230000244200013C010800AC22042C0A0005B361
+:102310003C0240003065020014A0000324020F00BC
+:102320001482026024020D0097420104104002C88A
+:102330003C02400030624000144000AD8F82003CFF
+:102340008C4400088F4201780440FFFE24020800FC
+:10235000AF42017824020008A7420140A740014291
+:10236000974201048F8400043051FFFF3082000146
+:1023700010400007022080212623FFFE24020002D5
+:102380003070FFFFA74201460A000304A74301483B
+:10239000A74001463C0208008C42043C1440000D5A
+:1023A0008F830010308200201440000224030009B3
+:1023B00024030001006020218F8300102402090003
+:1023C0005062000134840004A744014A0A00031F3C
+:1023D0000000000024020F0014620005308200207B
+:1023E000144000062403000D0A00031E2403000508
+:1023F000144000022403000924030001A743014AFA
+:102400003C0208008C4204203C0400480E00020AF2
+:10241000004420250E000233000000008F82000CD3
+:102420001040003E000000008F4210003C030020DE
+:1024300000431024104000398F8200043042000213
+:102440001040003600000000974210141440003382
+:1024500000000000974210088F88003C3042FFFFC8
+:1024600024420006000218820003388000E8302170
+:10247000304300018CC400001060000430420003AF
+:102480000000000D0A00036000E810215440001015
+:102490003084FFFF3C05FFFF0085202400851826BF
+:1024A0000003182B0004102B0043102410400005DB
+:1024B00000000000000000000000000D000000000F
+:1024C000240001CB8CC200000A00035F00452025D8
+:1024D0003883FFFF0003182B0004102B0043102447
+:1024E0001040000500000000000000000000000D8A
+:1024F00000000000240001D48CC200003444FFFF1F
+:1025000000E81021AC4400003C0208008C4204307A
+:10251000244200013C010800AC2204308F6200001C
+:102520008F84003CAF8200088C8300003402FFFFE0
+:102530001462000F000010213C0508008CA5045413
+:102540003C0408008C84045000B0282100B0302BDB
+:1025500000822021008620213C010800AC25045483
+:102560003C010800AC2404500A0005A9240400081A
+:102570008C820000304201001040000F000010214A
+:102580003C0508008CA5044C3C0408008C840448DD
+:1025900000B0282100B0302B0082202100862021AD
+:1025A0003C010800AC25044C3C010800AC24044864
+:1025B0000A0005A9240400083C0508008CA5044471
+:1025C0003C0408008C84044000B0282100B0302B6B
+:1025D00000822021008620213C010800AC25044413
+:1025E0003C010800AC2404400A0005A924040008AA
+:1025F0008F6200088F62000000021602304300F074
+:10260000240200301062000524020040106200E045
+:102610008F8200200A0005B12442000114A00005A9
+:1026200000000000000000000000000D000000009D
+:10263000240001FE8F4201780440FFFE00000000EC
+:102640000E00023B00000000144000050040802105
+:10265000000000000000000D000000002400020542
+:102660008E02000010400005000000000000000085
+:102670000000000D00000000240002088F62000C22
+:1026800004430003240200010A000457AE000000C6
+:10269000AE0200008F82003C8C480008A2000007B8
+:1026A0008F65000C8F64000430A3FFFF0004240238
+:1026B00000852023308200FF0043102124420005C2
+:1026C000000230832CC20081A605000A14400005D8
+:1026D000A2040004000000000000000D0000000043
+:1026E000240002208F85003C0E0005D5260400142E
+:1026F0008F6200048F430108A60200083C0210000C
+:1027000000621824106000080000000097420104D5
+:10271000920300072442FFEC346300023045FFFFC0
+:102720000A0003ECA2030007974201042442FFF0D1
+:102730003045FFFF960600082CC2001354400005E8
+:10274000920300079202000734420001A202000730
+:102750009203000724020001106200052402000316
+:102760001062000B8F82003C0A00040930C6FFFF94
+:102770008F82003C3C04FFFF8C43000C0064182453
+:1027800000651825AC43000C0A00040930C6FFFFA1
+:102790003C04FFFF8C4300100064182400651825DA
+:1027A000AC43001030C6FFFF24C2000200021083B9
+:1027B000A20200058F83003C304200FF000210801F
+:1027C000004328218CA800008CA2000024030004F0
+:1027D0000002170214430012000000009742010497
+:1027E0003C03FFFF010318243042FFFF0046102383
+:1027F0002442FFFE00624025ACA8000092030005C1
+:10280000306200FF0002108000501021904200143E
+:102810003042000F004310210A00043EA2020006CD
+:102820008CA40004974201049603000A3088FFFF3D
+:102830003042FFFF004610232442FFD6000214005E
+:1028400001024025ACA80004920200079204000592
+:102850002463002800031883006418213442000414
+:10286000A2030006A20200078F8200042403FFFBDC
+:102870003442000200431024AF8200049203000699
+:102880008F87003C00031880007010218C440020CA
+:102890003C02FFF63442FFFF00824024006718210B
+:1028A000AE04000CAC68000C920500063C03FF7FF0
+:1028B0008E02000C0005288000B020213463FFFF49
+:1028C000010330249488002600A728210043102407
+:1028D000AE02000CAC860020AC880024ACA800102E
+:1028E00024020010A742014024020002A740014236
+:1028F000A7400144A7420146974201043C04000856
+:102900002442FFFEA7420148240200010E00020AF1
+:10291000A742014A9603000A9202000400431021D4
+:102920002442000230420007000210233042000718
+:102930000E000233AE0200108F6200003C0308005C
+:102940008C63044424040010AF8200089742010401
+:102950003042FFFF2442FFFE00403821000237C30F
+:102960003C0208008C420440006718210067282BB5
+:1029700000461021004510213C010800AC2304440E
+:102980003C010800AC2204400A00053E00000000A3
+:1029900014A0000500000000000000000000000D71
+:1029A000000000002400029E8F4201780440FFFED8
+:1029B000000000000E00023B000000001440000573
+:1029C00000408021000000000000000D0000000019
+:1029D000240002A58E020000544000069202000767
+:1029E000000000000000000D00000000240002A80C
+:1029F0009202000730420004104000058F8200045C
+:102A00002403FFFB3442000200431024AF82000481
+:102A10008F6200040443000892020007920200063D
+:102A20008E03000CAE000000000210800050102148
+:102A3000AC430020920200073042000454400009D9
+:102A40009602000A920200053C0300010002108079
+:102A5000005010218C46001800C33021AC460018ED
+:102A60009602000A92060004277100080220202125
+:102A700000C2302124C60005260500140E0005D52D
+:102A800000063082920400068F6500043C027FFF3E
+:102A900000042080009120218C8300043442FFFF39
+:102AA00000A2282400651821AC83000492020007CC
+:102AB0009204000592030004304200041040001408
+:102AC00096070008308400FF000420800091202138
+:102AD0008C860004974201049605000A306300FFCB
+:102AE0003042FFFF004310210045102130E3FFFF7B
+:102AF000004310232442FFD830C6FFFF0002140019
+:102B000000C23025AC8600040A0004F292030007DC
+:102B1000308500FF0005288000B128218CA400002A
+:102B200097420104306300FF3042FFFF0043102151
+:102B3000004710233C03FFFF008320243042FFFFA7
+:102B400000822025ACA400009203000724020001AB
+:102B50001062000600000000240200031062001151
+:102B6000000000000A0005158E03001097420104C2
+:102B7000920300049605000A8E24000C00431021E5
+:102B8000004510212442FFF23C03FFFF0083202474
+:102B90003042FFFF00822025AE24000C0A000515FC
+:102BA0008E03001097420104920300049605000A68
+:102BB0008E24001000431021004510212442FFEE16
+:102BC0003C03FFFF008320243042FFFF00822025CA
+:102BD000AE2400108E0300102402000AA742014018
+:102BE000A74301429603000A920200043C040040FD
+:102BF00000431021A7420144A74001469742010427
+:102C0000A7420148240200010E00020AA742014A1D
+:102C10000E000233000000008F62000092030004E7
+:102C200000002021AF820008974201049606000AA6
+:102C30003042FFFF00621821006028213C03080099
+:102C40008C6304443C0208008C4204400065182157
+:102C5000004410210065382B004710213C0108007A
+:102C6000AC2304443C010800AC220440920400045C
+:102C7000008620212484000A3084FFFF0E0001E733
+:102C800000000000974401043084FFFF0E0001F5AE
+:102C9000000000003C021000AF4201780A0005B0BD
+:102CA0008F820020148200273062000697420104C0
+:102CB000104000673C0240003062400010400005B8
+:102CC00000000000000000000000000D00000000F7
+:102CD000240003968F4201780440FFFE240208007E
+:102CE000AF42017824020008A7420140A7400142F8
+:102CF0008F82000497430104304200011040000716
+:102D00003070FFFF2603FFFE24020002A7420146A7
+:102D1000A74301480A0005682402000DA7400146A8
+:102D20002402000DA742014A8F620000240400081B
+:102D3000AF8200080E0001E7000000000A00054213
+:102D400002002021104000423C024000936200003B
+:102D5000304300F0240200101062000524020070CD
+:102D600010620035000000000A0005B08F820020CC
+:102D70008F620000974301043050FFFF3071FFFF66
+:102D80008F4201780440FFFE320200070002102348
+:102D9000304200072403000A2604FFFEA743014037
+:102DA000A7420142A7440144A7400146A751014858
+:102DB0008F42010830420020144000022403000921
+:102DC00024030001A743014A0E00020A3C0400400C
+:102DD0000E000233000000003C0708008CE70444AA
+:102DE000021110212442FFFE3C0608008CC604405C
+:102DF0000040182100E33821000010218F650000F9
+:102E000000E3402B00C230212604000800C8302116
+:102E10003084FFFFAF8500083C010800AC27044464
+:102E20003C010800AC2604400E0001E70000000051
+:102E30000A000542022020210E0001390000000096
+:102E40008F82002024420001AF8200203C0240001B
+:102E5000AF420138000000000A00028F3C028000EF
+:102E60003084FFFF30C6FFFF00052C0000A6282598
+:102E70003882FFFF004510210045282B0045102116
+:102E800000021C023042FFFF0043102100021C021E
+:102E90003042FFFF004310213842FFFF03E00008EB
+:102EA0003042FFFF3084FFFF30A5FFFF00001821F4
+:102EB0001080000700000000308200011040000276
+:102EC00000042042006518210A0005CB00052840B7
+:102ED00003E000080060102110C0000624C6FFFFB8
+:102EE0008CA2000024A50004AC8200000A0005D5D5
+:102EF0002484000403E000080000000010A0000883
+:102F000024A3FFFFAC8600000000000000000000CA
+:102F10002402FFFF2463FFFF1462FFFA24840004ED
+:082F200003E0000800000000BE
+:042F280000000001A4
+:042F2C000A00002671
+:102F300000000000000000000000000D74787034F4
+:102F40002E362E3136000000040610000000000A64
+:102F5000000001360000EA600000000000000000F0
+:102F60000000000000000000000000000000000061
+:102F70000000000000000000000000000000000051
+:102F80000000000000000000000000000000001D24
+:102F90000000000000000000000000000000000031
+:102FA0000000000000000000000000000000000021
+:102FB0000000000000000000000000000000000011
+:102FC00000000000000000001000000300000000EE
+:102FD0000000000D0000000D3C02080024423B6090
+:102FE0003C03080024633E18AC4000000043202B43
+:102FF0001480FFFD244200043C1D080037BD7FFC07
+:1030000003A0F0213C100800261000983C1C08008A
+:10301000279C3B600E0004AE000000000000000D85
+:103020003C0580008F83003034A800708D070000BD
+:10303000008330253C02900000C22025ACA4002073
+:10304000AF8700243C0480008C8900200520FFFE0F
+:1030500000000000348400708C8500003C180800DB
+:103060008F18007C3C0D08008DAD007800A7C823A8
+:1030700003195021000070210159602B01AE582125
+:10308000016C38213C010800AC2A007C3C0108009E
+:10309000AC27007803E00008000000000A00003DB3
+:1030A000240400018F8500303C048000348300013B
+:1030B00000A3102503E00008AC82002003E0000814
+:1030C000000010213084FFFF30A5FFFF10800007B3
+:1030D000000018213082000110400002000420424C
+:1030E000006518211480FFFB0005284003E000085C
+:1030F0000060102110C00007000000008CA200003A
+:1031000024C6FFFF24A50004AC82000014C0FFFB0E
+:103110002484000403E000080000000010A0000860
+:1031200024A3FFFFAC8600000000000000000000A8
+:103130002402FFFF2463FFFF1462FFFA24840004CB
+:1031400003E000080000000090AA00318FAB0010DF
+:103150008CAC00403C0300FF8D680004AD6C002087
+:103160008CAD004400E060213462FFFFAD6D0024AF
+:103170008CA700483C09FF000109C024AD67002866
+:103180008CAE004C0182C82403197825AD6F000471
+:10319000AD6E002C8CAD0038314A00FFAD6D001CC7
+:1031A00094A900323128FFFFAD68001090A70030CD
+:1031B000A5600002A1600004A167000090A3003296
+:1031C000306200FF00021982106000052405000132
+:1031D0001065000E0000000003E00008A16A000175
+:1031E0008CD80028354A0080AD7800188CCF0014A8
+:1031F000AD6F00148CCE0030AD6E00088CC4002C76
+:10320000A16A000103E00008AD64000C8CCD001C35
+:10321000AD6D00188CC90014AD6900148CC8002471
+:10322000AD6800088CC70020AD67000C8CC200148C
+:103230008C8300700043C82B13200007000000009F
+:103240008CC20014144CFFE400000000354A0080DA
+:1032500003E00008A16A00018C8200700A0000C629
+:10326000000000009089003027BDFFF88FA8001CE7
+:10327000A3A900008FA300003C0DFF8035A2FFFF33
+:103280008CAC002C00625824AFAB0000A1000004FD
+:1032900000C05821A7A000028D06000400A048210C
+:1032A0000167C8218FA50000008050213C18FF7FD6
+:1032B000032C20263C0E00FF2C8C0001370FFFFF53
+:1032C00035CDFFFF3C02FF0000AFC82400EDC02455
+:1032D00000C27824000C1DC00323682501F8702566
+:1032E000AD0D0000AD0E00048D240024AFAD000034
+:1032F000AD0400088D2C00202404FFFFAD0C000C51
+:103300009547003230E6FFFFAD06001091450048BA
+:1033100030A200FF000219C2506000018D24003469
+:10332000AD0400148D4700388FAA001827BD00088F
+:10333000AD0B0028AD0A0024AD07001CAD00002C29
+:10334000AD00001803E00008AD00002027BDFFE03D
+:10335000AFB20018AFB10014AFB00010AFBF001C87
+:103360009098003000C088213C0D00FF330F007F93
+:10337000A0CF0000908E003135ACFFFF3C0AFF006B
+:10338000A0CE000194A6001EA22000048CAB001465
+:103390008E29000400A08021016C2824012A4024E9
+:1033A0000080902101052025A6260002AE240004FD
+:1033B00026050020262400080E00007224060002C4
+:1033C00092470030260500282624001400071E001E
+:1033D0000003160324060004044000032403FFFF37
+:1033E000965900323323FFFF0E000072AE23001007
+:1033F000262400248FBF001C8FB200188FB1001448
+:103400008FB0001024050003000030210A00007C6A
+:1034100027BD002027BDFFD8AFB1001CAFB00018FA
+:10342000AFBF002090A900302402000100E050212D
+:103430003123003F00A040218FB000400080882150
+:1034400000C04821106200148FA70038240B00052B
+:1034500000A0202100C02821106B001302003021A1
+:103460000E000108000000009225007C30A400023C
+:103470001080000326030030AE0000302603003425
+:103480008FBF00208FB1001C8FB00018006010218A
+:1034900003E0000827BD00280E000087AFB0001031
+:1034A0000A00014F000000008FA3003C0100202112
+:1034B0000120282101403021AFA300100E0000CED2
+:1034C000AFB000140A00014F000000008F820050CE
+:1034D00024430001304200FFAF83005003E00008A6
+:1034E000000000003C0580008CA30E108F84004477
+:1034F000AC8300208CA20E1803E00008AC820024EC
+:103500003C0580008CA30E148F840044AC83002003
+:103510008CA20E1C03E00008AC82002493820038C9
+:103520001040001B2483000F2404FFF000643824A3
+:1035300010E00019978B002C9784004C9389002E83
+:103540003C0A601C0A0001900164402301037021C1
+:10355000006428231126000231C2FFFF30A2FFFFC2
+:103560000047302B50C0000E00E448218D4D000C68
+:1035700031A3FFFF00036400000C2C0304A1FFF340
+:103580000000302130637FFF0A000188240600011B
+:1035900003E00008000000009784004C00E448218C
+:1035A0003123FFFF3168FFFF0068382B54E0FFF83C
+:1035B000A783004C938A002E11400005240F0001C0
+:1035C000006BC023A380002E03E00008A798004CE6
+:1035D000006BC023A38F002E03E00008A798004CC7
+:1035E00003E000080000000027BDFFE8AFB00010B6
+:1035F0003084FFFF3C10800093A8002BAFBF001465
+:10360000A6040144960A0E1630C600FF8FA90030AA
+:10361000A60A0146AE050148A2060152A608015AB3
+:10362000AE0701608FA3002CA609015801202021BC
+:103630000E00017CAE0301543C021000AE02017882
+:103640008FBF00148FB0001003E0000827BD0018E2
+:103650003C038000346200708C4900008F87003C7E
+:103660002484000727BDFFF83084FFF8AF890024C9
+:103670003C088000950E008A31CDFFFFAFAD000001
+:103680008FAC000001875823256AFFFF31461FFFDA
+:1036900000C4282B14A0FFF7350D00708DAC00007E
+:1036A0003C0508008CA500843C0A08008D4A008077
+:1036B000018958230000102100ABC0210007C882F7
+:1036C00001422021030B302B0019388035094000BE
+:1036D0000086782100E9102127BD00083C01080080
+:1036E000AC3800843C010800AC2F008003E00008E7
+:1036F000000000008F82003C2486000730C5FFF8E0
+:1037000000A2182130641FFF03E00008AF84003CD2
+:103710003C0320FF27BDFFE83C0760003C08800019
+:10372000240500103464FFFDACE53008AFBF001085
+:10373000AD040E00000000000000000000000000CA
+:1037400000000000000000003C0200FF345FFFFDAD
+:10375000AD1F0E003C0B60048D7850002419FF7FD4
+:103760003C0E00020319782435EC380C35CD0109E4
+:10377000ACED4C1824060009AD6C50008CEA0438FE
+:10378000AD060008AD0000148CE94C1C3145FFFF6C
+:103790003C06570900091E0238A42F713062000F41
+:1037A00034C80010AF820048104000072485C0B321
+:1037B0008CEB4C1C3C0D001F35ACFC00016C502404
+:1037C000000A49C2AF8900348CF90808241FF000B0
+:1037D000033FC02403087026030678262DE8000165
+:1037E0002DC600010106382550E00009A3800038ED
+:1037F0003C09601C8D24000824030001A3830038C9
+:1038000030827C00A780004CA380002EA782002C71
+:10381000AF80005014A00003AF80003C3C05600066
+:10382000ACA0442C0E000559000000008FBF001012
+:103830000A000E9927BD001827BDFFC8AFB3002CA2
+:10384000AFB20028AFBF0030AFB10024AFB000204E
+:10385000936200080080982100A090211440003558
+:10386000240400100E0001C9000000000E000168D1
+:10387000004080210002C4003C1932000319882551
+:10388000AE110000936F0009976E0012936A000A50
+:1038900031EC00FF31CDFFFF018D5821000B4400BA
+:1038A000314900FF01093825AE0700048F8500501B
+:1038B0009784004000403021308320001460004D88
+:1038C000AE050008AE00000C3C0580009784004067
+:1038D0000662004F8E03000C3090000816000002B4
+:1038E000264800062648000294A40E148CA50E1C3F
+:1038F0008F670004936A00023084FFFF314900FFA4
+:10390000AFA900108F720014AFA800180E0001AF0D
+:10391000AFB200148FBF00308FB3002C8FB20028DD
+:103920008FB100248FB00020240400100A0001F29F
+:1039300027BD00389365000997710012936C000B46
+:1039400030AD00FF01B13021318B00FF00CB802171
+:103950002602000A3050FFFF0E0001C9020020219C
+:103960000E000168004088219368000997640012E6
+:103970000002FC00310900FF308AFFFF012A3821D4
+:1039800024E3000203E3C0253C1941000319782514
+:10399000AE2F00008F6E000C3C0D800095AC0E1415
+:1039A00001D32825AE2500048DA50E1C8F670004C9
+:1039B000936B00023184FFFF316600FFAFA6001059
+:1039C0008F68001400403021AFB200180E0001AF24
+:1039D000AFA80014020020218FBF00308FB3002C4D
+:1039E0008FB200288FB100248FB000200A0001F2AE
+:1039F00027BD0038976200123C0580009784004084
+:103A0000305FFFFF0661FFB4AE1F000C8E03000C99
+:103A10003C078000006798250A00026BAE13000C7B
+:103A200027BDFFD8AFB40020AFBF0024AFB3001C48
+:103A3000AFB20018AFB10014AFB00010936200082D
+:103A4000144000940080A021AF60000C97850040D6
+:103A500030A440001080009E24030016241040076C
+:103A6000A363000AAF700014938F00428F6C0014A0
+:103A700031EE0001000E6A40018D5825AF6B001435
+:103A8000978A00408F6800143149001001093825D9
+:103A9000AF6700149786004030C300081060009F95
+:103AA000000000008F6600143C0310003C048000FE
+:103AB00000C32825AF65001494820E0A3C1F8100C4
+:103AC0002413000E3059FFFF033FC025AF780004D8
+:103AD000A37300029372000A3406FFFC265100040F
+:103AE000A371000A978800403107200010E0009180
+:103AF000000000003C0B80009789004095680E0C88
+:103B000097840040000918423107C0003065000367
+:103B100000071303309F100000A2C025001FCA0336
+:103B200003199825001390C0A772001297910040C6
+:103B3000936F000A00118182320E003C01CF682190
+:103B400025AC003CA36C0009956A0E0C31493FFF7F
+:103B5000A7690010976D0012936C0009018D582120
+:103B6000256A00023149000700094023310300079C
+:103B7000A363000B93670009976400129765001018
+:103B800030E200FF8F900028979800400044F82111
+:103B900003E5C82103269821331200401240000596
+:103BA0003266FFFF00D0702B3C11800011C0001660
+:103BB000000090210206782B15E0002D0000202146
+:103BC0003C1080008E120E143C058000AE120E10C8
+:103BD0008E110E1CAE110E18AE060E008CB8000031
+:103BE000331300081260FFFD0000000094B90E08B6
+:103BF00000C0802100008821A79900408CA60E04F7
+:103C000024120001AF860028977F001033F3FFFFD6
+:103C10008E8900000130202310800058AE840000FF
+:103C2000022020210E000243020028218E8C000079
+:103C300015800005000000008F6D0014240EFFBFEA
+:103C400001AEA024AF7400148F78000C03138821F8
+:103C5000AF71000C936F000815E000030000000036
+:103C60001640004000000000A3720008020020215E
+:103C70008FBF00248FB400208FB3001C8FB20018B8
+:103C80008FB100148FB000100080102103E00008F5
+:103C900027BD00288F900028978200403C118000AB
+:103CA000020098213045004014A0FFD90000902167
+:103CB000976800108F8700283103FFFF1467FFEC1F
+:103CC00000002021000088210A000339241200018D
+:103CD0002403000E24104007A363000AAF700014F1
+:103CE000938F00428F6C001431EE0001000E6A4089
+:103CF000018D5825AF6B0014978A00408F6800141F
+:103D00003149001001093825AF670014978600403B
+:103D100030C300081460FF6300000000AF600004BF
+:103D2000A3600002978800403107200014E0FF7173
+:103D300000003021A760001297910040936F000AA5
+:103D40003C0B800032301F000010718301CF6821CE
+:103D500025AC0028A36C0009956A0E0C0A00030A22
+:103D6000A76A00108F6600143C1FEFFF37F9FFFEB3
+:103D700000D998240A00034FAF7300148F6B00140E
+:103D8000356A00400E00016EAF6A00140A00033E5F
+:103D9000022020218F8500448F8A003027BDFFC07C
+:103DA0003C048000AFB70034AFB40028AFB1001CB2
+:103DB000AFBF0038AFB60030AFB5002CAFB30024B2
+:103DC000AFB20020AFB000188C8701048CA900248A
+:103DD000AC8A00808CA8002000E988230000B8216C
+:103DE000AC880E108CA600240000A021AC860E1812
+:103DF0008C820E10AC820E148C830E18AC830E1CB9
+:103E0000122000333C168000936B000811600054B0
+:103E100000000000976E001031CDFFFF022D602BD7
+:103E20001580004F0000000097700010320FFFFF58
+:103E3000AECF0E003C0580008CB30000327200084B
+:103E40001240FFFD0000000094B50E088CA50E0482
+:103E500032B0FFFF32140001128000440000000065
+:103E60000000000D3219A04024180040133800450E
+:103E70003214A0001280003F00000000937300087D
+:103E80001260000927A4001097620010305FFFFF46
+:103E900000BFC82B53200005AFB10010320800400E
+:103EA0001100003400000000AFB10010A7900040E6
+:103EB000AF8500280E0002BD000000000040A021D8
+:103EC000104000BE8FB100101620FFCF0000000090
+:103ED0002E96000102D78825122000178FBF0038C8
+:103EE0008F85003024170F0010B700713C0480004C
+:103EF0008C8F017805E0FFFE24180F0050B8008F6A
+:103F00003C0480008C990E14241402403C051000DF
+:103F1000AC9901448C930E1CAC930148A0800152D3
+:103F2000A480015AAC800160A4800158AC94015473
+:103F3000AC8501788FBF00388FB700348FB6003062
+:103F40008FB5002C8FB400288FB300248FB20020CF
+:103F50008FB1001C8FB0001803E0000827BD00409F
+:103F6000AED10E000A0003C33C05800014A0FFBEC2
+:103F70003219A0400E0001750000A0210A0003EADA
+:103F80002E9600013C0380008C7F017807E0FFFE45
+:103F9000240208008F84003CAC6201783C0380005E
+:103FA000946B008A316AFFFF0144382324E9FFFF44
+:103FB00031281FFF2D06000814C0FFF9346C4000A3
+:103FC00000A0A0210E000168008C90218F8300309A
+:103FD00024040F000040A821023488233C068000FE
+:103FE0001064000524050001938E004231C50001D4
+:103FF00000056A4035A500010015FC003C020100E7
+:1040000003E2C825AE5900008F93005032180036E5
+:10401000320F0008AE53000411E0004100B89825AB
+:1040200094C30E0A8F84003C3C0B8100306AFFFF72
+:104030002492000832481FFF014B48253C0710001E
+:10404000269200062410000EACC901600267982574
+:10405000A4D0015AAF88003CA4D201581620000811
+:104060003C1080008F8E003024050F0051C50002E7
+:1040700024170001367300400E00016E3C108000D2
+:104080008E180E1402402021AE1801448E0F0E1C13
+:10409000AE0F0148A2150152AE1301540E00017C6F
+:1040A0003C151000AE1501780A0003E7000000007F
+:1040B000128000053C07800094F20E08324900404F
+:1040C00011200042000000008C8A01780540FFFEAC
+:1040D0000000000094950E103C1005002403200001
+:1040E00032AEFFFF01D06825AC8D014C8C8C0E14D4
+:1040F0003C0B1000AC8C01448C860E1CAC86014835
+:10410000A0800152A480015AAC800160A4800158B3
+:10411000AC830154AC8B01780A0003F13C048000AD
+:104120008F8D003C26920002A4D2015825AC0008D5
+:1041300031861FFF0A00044CAF86003CAC80014C66
+:1041400012800019000000008C9F0E10AC9F0144EB
+:104150008C830E183C08800024110040AC83014879
+:104160008FBF0038A10001528FB70034A500015A5B
+:104170008FB60030AD0001608FB5002CA50001584E
+:104180008FB40028AD1101548FB300248FB20020EA
+:104190008FB1001C8FB000183C04100027BD0040F8
+:1041A00003E00008AD0401788C820E14AC82014457
+:1041B0008C830E1C0A00048B3C0880000E000175E5
+:1041C0002E9600010A0003EB02D7882500000000AC
+:1041D0000000000D000000002400033A0A000467FC
+:1041E0003C04800027BDFFD8AFB100143C11800013
+:1041F000AFB00010AFB40020AFB3001CAFB20018D6
+:10420000AFBF00243C13080026733C340E0001F9B4
+:10421000363000703C14080026943CB40200902113
+:104220008E0800008E2400003883000130620001F7
+:10423000104000163C0A8000024048218D270000F3
+:104240003C1F08008FFF006C3C0F08008DEF0068DA
+:1042500000E8102303E260210000C0210182702BDE
+:1042600001F8682101AE40213C010800AC2C006C33
+:104270003C010800AC2800688D4B00003966000145
+:1042800030C5000114A0FFED00E040218E1F0000AA
+:104290003C1808008F18006C3C0D08008DAD0068BC
+:1042A00003E8C823031938210000702100F9602BAE
+:1042B00001AE4021010C58213C010800AC27006CE4
+:1042C0003C010800AC2B00688E2801002406FF800A
+:1042D0003C04800A2505024000A64824AE280020A0
+:1042E000AE2900248E09000030A3007F0064502115
+:1042F0003C078000AF8A0044AF880030AF890024BB
+:104300008CE201780440FFFE000000008E1F0000D8
+:104310003C1808008F1800743C0D08008DAD00702B
+:1043200003E9C82303195821000070210179302BBB
+:1043300001AE602101864821240508003C010800E7
+:10434000AC2B00743C010800AC290070ACE501788E
+:1043500090E40108A384004293830042306A000184
+:104360001140000F240E0D002502F8002C47030118
+:1043700010E0001C000819C22464FFF00004504241
+:10438000000A41400E00039A0113D8213C0A400064
+:104390003C088000AD0A01380A0004BD000000009E
+:1043A000110E0026240F0F00110F002A3C02800876
+:1043B0003447008090FF00002418005033F900FFBC
+:1043C0001738FFF33C0A40000E0009A3000000006C
+:1043D0003C0A40003C088000AD0A01380A0004BDD8
+:1043E000000000008F8400340064282B14A0000B10
+:1043F0008F86004800866021258BFFFF0163482BD4
+:104400001520000600646823000D19400E00039A71
+:104410000074D8210A0005193C0A40000000000081
+:104420000000000D00000000240003AD0E00039A00
+:10443000000000000A0005193C0A40003C1B08006F
+:10444000277B3DB40E00039A000000000A00051906
+:104450003C0A40003C1B0800277B3DD40E00039A19
+:10446000000000000A0005193C0A40008F8200503D
+:1044700024430001304200FFAF83005003E00008F6
+:1044800000000000000411C003E0000824420240C4
+:104490003C04080024843BCC2405001A0A00007C5C
+:1044A0000000302127BDFFE0AFBF001CAFB20018F5
+:1044B000AFB10014AFB000103C108000920B0109A6
+:1044C0002412FF800E0005563164007F8F9100306A
+:1044D0000051502101524024AE08002492030109EA
+:1044E0000E0005563064007F24060080240700C0BB
+:1044F00024040040AE000810AE040814AE060818EC
+:10450000AE07081C920C01090051F82133F8007F16
+:104510003C19800A031910213184007F0E000556D2
+:10452000AF8200448E1101003C0C008035850001F3
+:104530000222782101F24824AE0908048E0E0100FF
+:10454000359800023609090001C2682131AB0078B4
+:1045500001655025AE0A08208E0501008E08010075
+:10456000360509800102182124640040009230249D
+:10457000AE0608088E07010000E2F82127F9004086
+:104580003332007802588825AE1108248E040100C9
+:10459000952F000C8FBF001C8FB2001831EEFFFF6B
+:1045A000000E69C0AE0D0800AE0C0828952B000C5B
+:1045B0008FB10014316AFFFF000A41C0AE08002C21
+:1045C0008CA300508FB000108CA2003C8D240004FE
+:1045D0008CA6001C8CA7003827BD0020AF83006884
+:1045E000AF820058AF840054AF86006003E000083B
+:1045F000AF8700643C0A0800914A3BF13C0908007F
+:1046000095293BEA3C051100000A3C0025280002E0
+:1046100000E8302500C5182524820008AC8300007E
+:1046200003E00008AC8000043C0880003507090066
+:1046300090E60011240200280080502130C300FFC2
+:1046400000A0602110620002340B86DD240B0800FC
+:104650003C07800034E20A9A9459000034EF0A9C27
+:1046600034ED0AA03338FFFFAD5800008DEE000096
+:1046700034E80A8024040001AD4E00048DA9000036
+:10468000AD4900089105001930A3000310640043F0
+:104690002866000214C000B0240400021064008BDD
+:1046A000240500031065009634E60AA43C090800BE
+:1046B00095293BE0240208005162004D3C0E800029
+:1046C0003C0E800035C5090090A6001290B9001973
+:1046D00035CB09808D68002830C700FF000778803F
+:1046E0003138FFFF332300FF01F8102100032500BC
+:1046F0000088702500025C003C0D600001CD302573
+:10470000356906FFAD490004AD4600008CA7002CBA
+:1047100025490028AD4700088CB90030AD59000C80
+:104720008CB80034AD5800108CAF0038AD4F001479
+:104730008CA3001CAD4300188CA800203C03800013
+:104740003462093CAD48001C8CA40024346F09007D
+:10475000AD4400208CAD0028AD4D00248C590000E4
+:10476000AD2C000425220014AD3900008C78010C1A
+:10477000AD38000891E800123C04080090843BF03A
+:10478000AD20001000082F0000046C0000AD602573
+:10479000358AFFFF03E00008AD2A000C3C09080041
+:1047A00095293BE03C0F080095EF3BEA34F90AA459
+:1047B0003C0E080095CE3BDC972800003138FFFF07
+:1047C00001F8682101AE382300082C0024E3FFF231
+:1047D00000A3202524020800AD44000CAD400010C9
+:1047E000AD4B00141562FFB6254A00183C0E800040
+:1047F00035CD090091A2001191A700193C050800D0
+:1048000094A53BE6304600FF35CB0A80956E002A22
+:104810000006C88230F800FF9787005C00191E0070
+:1048200000187C003128FFFF00A82021006F4825D8
+:104830000124102501C730213C0B4000004BC82546
+:104840000006C400AD590000AD58000491AF001837
+:104850003C03000624E90001000F46000103702517
+:10486000AD4E00088DA5002C3C0380003462093C4D
+:10487000AD45000C8DAB001C31247FFF2549001491
+:10488000AD4B00108C590000AD2C0004346F0900B2
+:10489000AD3900008C78010CA784005C252200143F
+:1048A000AD38000891E800123C04080090843BF009
+:1048B000AD20001000082F0000046C0000AD602542
+:1048C000358AFFFF03E00008AD2A000C34E20AA499
+:1048D00094460000951900283C09080095293BE002
+:1048E0000006C40000197C00370E810001EB68252A
+:1048F000AD4E000CAD4D00100A0005E2254A001433
+:104900003C09080095293BE03C18080097183BEA51
+:104910003C0F080095EF3BDC94CE00003139FFFFDF
+:10492000950D002803194021010F3823000E2400A3
+:10493000000D2C0024E3FFEE00A33025348281001B
+:10494000AD42000CAD460010AD400014AD4B001858
+:104950000A0005E2254A001C1460FF5434E90AA449
+:10496000952800003C09080095293BE000083C0020
+:1049700000EB1825AD43000C0A0005E2254A0010A3
+:1049800003E00008240207D027BDFFE0AFB2001803
+:10499000AFB10014AFB00010AFBF001C0E00005C40
+:1049A000008088218F8800588F8700543C0580083C
+:1049B00034B20080011128213C10800024020080C4
+:1049C000240300C000A72023AE0208183C0680087C
+:1049D000AE03081C18800004AF850058ACC5000465
+:1049E0008CC90004AF8900541220000936040980E4
+:1049F0000E00069500000000924C00278E0B0074FC
+:104A000001825004014B3021AE46000C360409806F
+:104A10008C8E001C8F8F006001CF682319A00004CA
+:104A20008FBF001C8C90001CAF9000608FBF001CDB
+:104A30008FB200188FB100148FB000100A00005E12
+:104A400027BD00208F8600688F8300588F82005416
+:104A50003C05800834A40080AC860050AC83003C48
+:104A600003E00008ACA200043C038000346700703F
+:104A70008CE30000308700FF3C0408008C84005465
+:104A800027BDFFF830AA00FF248200013C01080086
+:104A9000AC22005430C800FFAF8300243C098000E2
+:104AA0008D25017804A0FFFE352B00708D65000078
+:104AB000A3A700033C1808008F1800748FB90000EA
+:104AC0003C0D08008DAD007000A338233C047FFF2F
+:104AD00000E078213482FFFF0307382100007021B5
+:104AE0000322582401AE302100EF602B000847C09C
+:104AF00000CC182101682825AFA500003C01080062
+:104B0000AC2700743C010800AC2300709124010A1A
+:104B1000A3A000023C0280FFA3A400018FB8000004
+:104B2000314F007F3459FFFF03196824000F7600CE
+:104B30003C0B002001AE6025356A20002408FF8070
+:104B40003C06100027BD0008AD2C014CAD2A0154D5
+:104B5000A5200158A128015203E00008AD260178E4
+:104B60003C038000346200708C480000308A00FFF3
+:104B700030A900FFAF8800243C0480008C850178B8
+:104B800004A0FFFE348700708CEB00003C05080099
+:104B90008CA500743C1908008F390070016820232F
+:104BA00000A470210000102101C4C02B0322782131
+:104BB0003C07800001F868213C010800AC2E00741D
+:104BC00034E60A003C010800AC2D00708CCC0020BB
+:104BD0000009582B34E80980ACEC01448CC900244E
+:104BE000000B1540ACE90148A0EA01509104004CCB
+:104BF000A0E4016D03E00008A4E0015827BDFFE830
+:104C0000308400FFAFBF00100E00070D30A500FF7D
+:104C10008F8300588FBF00103C0580003446004051
+:104C20002404FF903C02100027BD0018ACA3014CE7
+:104C3000A0A40152ACA6015403E00008ACA2017884
+:104C400027BDFFE03C088008AFBF001CAFB20018D2
+:104C5000AFB10014AFB00010351000808E06001800
+:104C60003C078000309200FF00C72025AE040018EA
+:104C70000E00005C30B100FF9203000534620008B2
+:104C80000E00005EA2020005024020210E00073443
+:104C900002202821024020218FBF001C8FB2001863
+:104CA0008FB100148FB00010240500052406000108
+:104CB0000A0006CF27BD00203C08800027BDFFE882
+:104CC000AFB0001035050980AFBF001490A70009F0
+:104CD000240200063506090030E300FF241000041A
+:104CE000106200722408000294AE005C3C0D0204C5
+:104CF00031CCFFFF018D5825AC8B000090AA000835
+:104D000031490020112000080000000090BF004E33
+:104D10003C1901033738030033EF00FF01F8282561
+:104D200024100008AC85000490CC001190C900113B
+:104D3000318A00FF000A5882312700FF256A0005EA
+:104D4000000A108038E300281460002900824823FC
+:104D500090CF00123C1980003722090031E500FF96
+:104D60000005708001D06821000D340034C406FFB6
+:104D7000AD240004904C001190580012373F098078
+:104D80008FE400348F2F010C00105882330500FF90
+:104D900000AB702100083400008F1823000E6F0054
+:104DA00001A61025319F00FC3067FFFF03E9C021F9
+:104DB0000047C825014B7821000F2880AF19000C4F
+:104DC0000E00005C012580213C0A800824090004B3
+:104DD000354800800E00005EA10900090200102184
+:104DE0008FBF00148FB0001003E0000827BD00182B
+:104DF00090CE001190CD00193C07080094E73BE6E7
+:104E000031C600FF0006208231AC00FF00045E00C6
+:104E1000000C1C00016310250047C8253C1F400002
+:104E2000033FC0253C198000AD380000372209003F
+:104E3000904C001190580012373F09808FE40034E5
+:104E40008F2F010C00105882330500FF00AB70213A
+:104E500000083400008F1823000E6F0001A61025F3
+:104E6000319F00FC3067FFFF03E9C0210047C825E0
+:104E7000014B7821000F2880AF19000C0E00005C58
+:104E8000012580213C0A800824090004354800805F
+:104E90000E00005EA1090009020010218FBF00145E
+:104EA0008FB0001003E0000827BD00180A00076F4C
+:104EB0002408001227BDFFD8AFB40020AFB3001CF8
+:104EC000AFB20018AFB10014AFBF0024AFB00010F4
+:104ED0003C06800090C3010B309200FF30B300FF0E
+:104EE000306200300000A0211040007000008821D6
+:104EF00034C409809088000800083E0000072E0393
+:104F000004A00097240400048F8800583C01080086
+:104F1000A0243BF03C0C8000AD8000483C038000A6
+:104F2000906E010B31C5002010A000073C028000EC
+:104F300034790980933800080018860000107E0339
+:104F400005E2009C3C0280083450090034470A8086
+:104F5000904D010B94EB002C92030011921F001254
+:104F600090E50018307800FF33F900FF00197880D1
+:104F700001F8702101D1502130B100FF01514821C9
+:104F80002524000A31AC00403091FFFF000C302B8B
+:104F900002202021A78B005C3C010800A42A3BE6EC
+:104FA0003C010800A4293BE83C010800A4293BEA95
+:104FB0003C010800A4203BE03C010800A4203BDCAD
+:104FC0000E0001C9010680230E0005B20040202119
+:104FD000004020210E0005BF020028211680005C41
+:104FE000000000000E0001F2022020213C08080011
+:104FF00091083BF031140003128000163C1F80081A
+:105000008F8400583C0C800835860080248B00017A
+:10501000ACCB003C3C0580088CAA00040160202138
+:10502000014B482319200002AF8B00588CA40004C8
+:105030000E000695ACA400043C0F80008DEE0074B9
+:105040003C05800834AD0080004E8821ADB1000CD5
+:105050003C1F800837F9008002402021026028218F
+:10506000A320006B0E00070D3C1280008F980058A3
+:1050700034500006AE58014C0E0005503C13100091
+:10508000A24201528FBF0024AE5001548FB40020C1
+:10509000AE5301788FB100148FB3001C8FB200188B
+:1050A0008FB0001003E0000827BD002834C309803A
+:1050B000906F0008000F7600000E6E0305A000330D
+:1050C00034C209009059001B241F00103C01080045
+:1050D000A03F3BF0333800021300FF908F88005848
+:1050E0008F8300641468FF8E3C0380000E00005C18
+:1050F000000000003C0980083525008090A40009CC
+:1051000024070016308800FF1107000D0000000082
+:1051100090A600093C0C0800918C3BF0240A000882
+:1051200030C400FF358B00013C010800A02B3BF090
+:10513000108A002F240D000A108D00282402000C74
+:105140000E00005E000000000A0007FC8F88005877
+:105150000E000763004020210A00082E0000000016
+:105160003C0B8008356A00808D4800548CC9010CC6
+:105170001120FF66AF880058240600143C01080087
+:10518000A0263BF00A0007FB3C0C80009071000851
+:10519000241400023C010800A0343BF0323000200F
+:1051A0001200000B241400018F8800580A0007FC2D
+:1051B00024110008345F00808FE70038AC470004FA
+:1051C0008C430004AFE3003C0A0008073C02800067
+:1051D0008F8800580A0007FC24110004A0A20009CF
+:1051E0000E00005E000000000A0007FC8F880058D7
+:1051F000240200140A0008ADA0A2000927BDFFE8A0
+:10520000AFBF0014AFB000103C1080009202010943
+:10521000240500010E00070D304400FF3C1F8008EC
+:1052200093F8000E37E3008093F9000F906E00268C
+:1052300093E9000A332F00FF00186600000F6C008E
+:1052400031CB00FF018D5025000B3200014638257F
+:10525000312800FF3445600000E820252402FF814A
+:105260003C031000AE04014C8FBF0014AE05015486
+:10527000A2020152AE0301788FB0001003E00008D3
+:1052800027BD001827BDFFE8308400FFAFBF001026
+:105290000E00070D30A500FF344600403C0480009E
+:1052A0002405FF92AC860154A08501528F830058DB
+:1052B0008FBF00103C02100027BD0018AC83014CCA
+:1052C00003E00008AC82017827BDFFD8AFB2001818
+:1052D000AFB10014AFB00010AFBF0020AFB3001CDF
+:1052E0003C07800090E20109308600FF30B000FFEB
+:1052F000000618C232040002307100011480000759
+:10530000305200FF3C098008353300809268000568
+:105310003105000810A0000C30CA00100240202106
+:105320000E00074502202821240200018FBF002023
+:105330008FB3001C8FB200188FB100148FB0001013
+:1053400003E0000827BD00281540003034E50A00BE
+:105350008CB900248CB800081338004700004021A5
+:105360003C0E800835D30080926D0068240B00024B
+:1053700031AC00FF118B00803C068000927F004C16
+:1053800090C40109509F00043213007C1100006793
+:10539000000000003213007C1660005A02402021F9
+:1053A00016200008320C00013C07800034EB0A0094
+:1053B0008D6500248CE8010414A8FFDC0000102196
+:1053C000320C00011180000D024020213C108000B1
+:1053D0008E0E010C8F8D006811CD000800000000BA
+:1053E0000E0007E2022028218E0F010C3C188008D5
+:1053F00037100080AE0F0050024020210E0007340D
+:10540000022028210A000900240200013C070800AC
+:105410008CE7006424E600013C010800AC2600642F
+:105420001600000D00000000022028210E000734A5
+:1054300002402021926F0068240D000231EE00FF2F
+:1054400011CD0022024020210E0008B4000000000F
+:105450000A000900240200010E00003D240400019E
+:10546000926C0025020C58250E00005EA26B0025F0
+:105470000A000940022028218E6300188CE40104F0
+:105480008CBF002400031602149FFFB53045007F37
+:105490009269004C264400013093007F1265004061
+:1054A000312300FF1464FFAF3C0E80082648000142
+:1054B0003111007F310200FF1225000B240800018A
+:1054C000004090210A00090D241100012405000468
+:1054D0000E0006CF240600010E0008B400000000F4
+:1054E0000A000900240200012407FF800247282443
+:1054F00000A79026324200FF004090210A00090DCB
+:10550000241100010E0007E202202821320600309B
+:1055100010C0FFA332100082024020210E00074578
+:10552000022028210A000900240200018E630018CD
+:105530000240202102202821006610250E0008D6F6
+:10554000AE6200189264004C24050003240600019A
+:105550000E0006CF308400FF0E00003D2404000141
+:10556000926A0025020A48250E00005EA269002505
+:105570000A000900240200018E7800183C198000FE
+:105580000240202103197825022028210E0007342B
+:10559000AE6F00189264004C0A00098824050004CC
+:1055A0003246008038CA0080146AFF6E3C0E8008C4
+:1055B0000A0009612648000127BDFFC0AFB00018EE
+:1055C0003C108000AFBF0038AFB70034AFB600303A
+:1055D000AFB5002CAFB40028AFB30024AFB20020A9
+:1055E0000E00055EAFB1001C920401089205010B8C
+:1055F000308400FF0E0008E730A500FF144000D6FD
+:105600008FBF00383C09800835280080A100006B5E
+:105610003607098090E60000240200503C1708007D
+:1056200026F73DF430C300FF3C14080026943E04E6
+:10563000106200033C1080000000B8210000A0218F
+:10564000241F001036110A00361309808E1601043B
+:105650008F8D00588E38002436190A808E720020F3
+:105660003C010800A03F3BF0972C002C8EF5000079
+:10567000932B0018024D702302D878233C010800B8
+:10568000AC2F3BCC3C010800AC2E3BD03C010800C9
+:10569000AC2D3BF4A78C005C02A0F809317200FF2E
+:1056A000304A0002154000DA3045000110A000B475
+:1056B00000000000360509008E2B002490BF001169
+:1056C00090B9001290B6001133EF00FF333800FF9D
+:1056D00032CD00FF0018708001CF8021024D602183
+:1056E0000212A821258A00103C010800A4353BE8DD
+:1056F0003C010800AC2B3BF83C010800A42A3BE429
+:105700003C010800A4303BE60260B0213C1580005B
+:105710008F9200588F8400608ED3002024110006E1
+:1057200000923023027228233C010800AC313BEC8C
+:1057300004C000AF0000982104A000AD00C5102BEC
+:10574000104000AF000000003C010800AC263BD038
+:105750008E9000000200F8090000000030430002B3
+:105760001460006F004088213046000154C00011D1
+:105770008E9200043C0808008D083BD43C09C00010
+:105780003C04800001093825AEA70E008C8B000078
+:10579000316A00081140FFFD00000000948D0E08E2
+:1057A00024130001A78D00408C8C0E04AF8C0028C0
+:1057B0008E9200040240F8090000000002228825B1
+:1057C000322E000215C000A5000000003C180800A1
+:1057D00097183BDC3C12080096523BE83C19080045
+:1057E00097393BDE3C0708008CE73BD4031240218D
+:1057F0003C0B08008D6B3BF83C0E080095CE3BF24D
+:105800003C128000011978218E46010C00F86821B5
+:1058100025EC000201AE482101675021AF860068E7
+:105820003C010800AC2A3BF83C010800A4293BE0FD
+:105830003C010800A4283BEA0E0001C93184FFFFA7
+:105840000E000550004080213C010800A0223BF1E1
+:105850008E8200080040F809020020218F85005840
+:105860000E0005BF004020218E90000C0200F809B8
+:10587000004020213C03080094633BEA3C020800FE
+:1058800094423BDE00622021248500020E0001F2DA
+:1058900030A4FFFF3C1908008F393BCC3C1F0800A7
+:1058A0008FFF3BD4033FC0233C010800AC383BCC06
+:1058B00017000006000000003C0508008CA53BEC2A
+:1058C00034BF00403C010800AC3F3BEC126000429A
+:1058D0008F8200448E430E108F930044AE630020ED
+:1058E0008E440E18AE6400243C04080094843BE00F
+:1058F0000E000697000000008F8600588E8A001068
+:105900003C010800AC263BF40140F809000000000F
+:105910003C0908008D293BCC1520FF7E8F92005852
+:105920009796005C3C14800E323500100E0006C6BF
+:10593000A696002C56A000458EEB000432270040AE
+:1059400054E0001E8EF100088EEC000C0180F80976
+:10595000000000008FBF00388FB700348FB60030D2
+:105960008FB5002C8FB400288FB300248FB2002095
+:105970008FB1001C8FB0001803E0000827BD004065
+:10598000920901098F88003000093E0000E83025A7
+:10599000AE0600808E2300208E240024AFA30010CA
+:1059A000AE030E148FA20010AE020E10AE040E1C39
+:1059B000AE040E180A0009E3360509000220F809B2
+:1059C000000000008EEC000C0180F80900000000CF
+:1059D0000A000A8B8FBF0038240800012410000140
+:1059E000A4400020A44800220A000A6FAC50002402
+:1059F0003C010800AC203BD00A000A0A8E9000004F
+:105A00003C010800AC253BD00A000A0A8E90000039
+:105A100092110109000028210E000734322400FFF2
+:105A20008FBF00388FB700348FB600308FB5002C91
+:105A30008FB400288FB300248FB200208FB1001CD8
+:105A40008FB0001803E0000827BD00400160F8098E
+:105A5000000000000A000A85322700405260FFB1B2
+:105A60009796005C8EB60E148F940044AE9600207C
+:105A70008EAF0E1CAE8F00240A000A7E9796005C43
+:105A80008F8200000004218003E0000800821021C2
+:105A90003C07800834E20080904300690080402188
+:105AA000106000093C0401003C0708008CE73BF44F
+:105AB0008F83001C00E320230480000893890008E2
+:105AC00014E300030100202103E0000800801021FE
+:105AD0003C04010003E00008008010211120000BAD
+:105AE000006738233C0D800035AC0980918B007C29
+:105AF000316A0002114000202409003400E9702BB3
+:105B000015C0FFF10100202100E938232403FFFC28
+:105B100000A3C82400E3C02400F9782B15E0FFEAB5
+:105B20000308202130C400030004102314C0001413
+:105B3000304900030000302100A9782101E67021DE
+:105B400000EE682B11A0FFE03C0401002D3800019D
+:105B50000006C82B010548210319382414E0FFDA98
+:105B60002524FFFC2402FFFC00A218240068202149
+:105B700003E00008008010210A000AF42409003024
+:105B80003C0C80003586098090CB007C316A000493
+:105B90001540FFE9240600040A000B030000302131
+:105BA0003C0308008C63005C8F82000427BDFFE883
+:105BB000AFBF001410620005AFB00010000329C091
+:105BC00024A40280AF840000AF8300043C10800056
+:105BD00036030A00946500320E000AD530A43FFF58
+:105BE0008E0401003C180080370F00030082C8219A
+:105BF0002402FF80032260243329007F000CF94037
+:105C000003E94025332E00783C0D1000010D50258E
+:105C100001CF5825AE0C002836080980AE0C080CC0
+:105C2000AE0B082CAE0A0830910300693C06800CCC
+:105C30000126382110600006AF8700208D09003C46
+:105C40008D06006C0126382318E0007F000000005C
+:105C50003C0C8008358B00803C0A8000A160006904
+:105C6000355009808E0200383C06800034C50A0099
+:105C700090AD003C31A8002011000019AF82001C3B
+:105C8000240E00013C19800037300A00A38E000862
+:105C9000AF8000108E0400248F85001024180008A7
+:105CA000AF80000CAF8000143C010800A4383BDE3C
+:105CB0003C010800A4203BF20E000AD9000030216C
+:105CC000920F003C8FBF00148FB00010000F714284
+:105CD000AF82001827BD001803E0000831C20001A0
+:105CE00090B90032240F0001333800FF00182182E0
+:105CF000108F003F241F0002109F006234C20AC0B0
+:105D00003C03800034640A008C9900241720001D95
+:105D10003466090090830030241F00053062003F84
+:105D2000105F004C240500018F86000CA38500083D
+:105D3000AF860014AF8600103C19800037300A008F
+:105D40008E0400248F850010241800083C010800F0
+:105D5000A4383BDE3C010800A4203BF20E000AD927
+:105D600000000000920F003C8FBF00148FB00010A5
+:105D7000000F7142AF82001827BD001803E0000831
+:105D800031C200018C8800088C8D00248CCB00640B
+:105D90003C19800037300A00AF8B0010A380000848
+:105DA0008E0400248F86000C8F850010010D602367
+:105DB00024180008AF8C00143C010800A4383BDE16
+:105DC0003C010800A4203BF20E000AD900000000AC
+:105DD000920F003C8FBF00148FB00010000F714273
+:105DE000AF82001827BD001803E0000831C200018F
+:105DF00090A7003030E3003F5064002834C50AC04B
+:105E00008CAA00241540002234C809008CAB00483D
+:105E10003C0C7FFF3585FFFF016510243C18800096
+:105E2000AF82000C370509008F8E000C8CAF00602C
+:105E300001CF682B15A0000201C020218CA40060B6
+:105E40000A000B75AF84000C8D02006C0A000B5029
+:105E50003C0680008C8900488F86000C3C0A7FFF3E
+:105E60003550FFFF013038243C0480082405000130
+:105E7000AF870014AC80006CA38500080A000B8378
+:105E8000AF8600108C4400140A000B75AF84000C20
+:105E90008D0200680A000BBD3C18800034C40980E4
+:105EA0008C8600708CB0001400D0482B11200004A8
+:105EB000000000008C8200700A000BBD3C188000BE
+:105EC0008CA200140A000BBD3C1880008F850010C6
+:105ED00027BDFFE0AFBF0018AFB1001414A0000849
+:105EE000AFB000103C04800034870A0090E6003018
+:105EF0002402000530C3003F106200B7348409005B
+:105F00008F91000C00A080213C048000348E0A0098
+:105F10008DCD00043C0608008CC63BD031A73FFF66
+:105F200000E6602B5580000100E03021938F0008CF
+:105F300011E0007600D0102B349909809338007C52
+:105F400033040002108000772403003400C3F82BD0
+:105F500017E000D600C3302300D0102B3C0108000E
+:105F6000A4233BDC1440006D020018213C0408000F
+:105F70008C843BCC0064282B54A0000100602021BD
+:105F80003C05800034A90A009128003C3C0108002F
+:105F9000AC243BD4310300201460000200004821EF
+:105FA0008CA90E188F8800180128502B1140005F13
+:105FB000000000003C0508008CA53BD400A960212E
+:105FC000010C582B1160005C00B0682B01093823CC
+:105FD00000E028213C010800AC273BD4120000035C
+:105FE0002402FFFC10B0008C322A000300A2F82427
+:105FF0003C010800A4203BF23C010800AC3F3BD42C
+:1060000003E028218F840010120400063C0380085E
+:106010008C6A006C02002021AF91000C2550000119
+:10602000AC70006C8F8B001400858823AF9100103A
+:1060300001652023AF8400141220000224070018F9
+:10604000240700103C0E800835C6008090CD006803
+:10605000240C00013C010800A0273BF031A700FF01
+:1060600010EC0047000000001480001800002821F8
+:106070003C0B800091650109357109808E23001861
+:1060800030A500FF0003560224A300013146007F23
+:106090003070007F1206007E240CFF803C0F8008C9
+:1060A00035E90080A123004C3C0808008D083BEC3A
+:1060B000240E00023C010800A02E3C31350D0008E2
+:1060C0003C010800AC2D3BEC240500103C1F800077
+:1060D00037E40A009099003C333800201300000593
+:1060E00000A02021240200013C010800AC223BD486
+:1060F00034A400018FBF00188FB100148FB00010BE
+:106100000080102103E0000827BD00203C010800AA
+:10611000A4203BDC1040FF95020018210A000C105F
+:1061200000C018210A000C08240300303C050800B8
+:106130008CA53BD400B0682B11A0FFA80000000084
+:106140003C04080094843BDC0085782101E7702B37
+:1061500011C000072CA200043C1F60008FF95404FA
+:106160003338003F1700FFE3240400422CA2000450
+:106170001040FF9A240400420A000C738FBF0018DD
+:106180001528FFB9000000008CC200183C188000E0
+:10619000241900020058F825ACDF001837040A0063
+:1061A000A0D900689089003C240F000400A01021B1
+:1061B000312800203C010800A02F3C3111000002D2
+:1061C00024050010240200013C010800AC223BCC55
+:1061D0000A000C693C1F80008F8800148C890060C5
+:1061E0000109282B14A00002010088218C91006075
+:1061F0003C0B80008D640E18240A00010220282127
+:1062000002203021A38A00080E000AD90220802132
+:106210000A000BF7AF820018000A182312200007AB
+:10622000306400033C0D800035A7098090EC007CB1
+:10623000318B000415600019248E00043C01080015
+:10624000A4243BF23C18080097183BF203052021D8
+:1062500000C4782B11E0FF6C8F8400102CA6000581
+:1062600014C0FFA42404004230B900031720000228
+:1062700000B9182324A3FFFC3C010800AC233BD445
+:106280003C010800A4203BF20A000C3600602821E3
+:1062900000AC38240A000C5C00EC18263C01080015
+:1062A000A42E3BF20A000CC6000000003C010800CE
+:1062B000AC203BD40A000C72240400428F830014EB
+:1062C0003C0B8000356A0A001460000600001021B3
+:1062D000914600302405000530C400FF10850003FE
+:1062E0000000000003E000080000000091490048A1
+:1062F000312800FF000839C214E0FFFA3C0480088E
+:106300003C06080094C63BDC3C0308008C633BF46D
+:106310003C0508008CA53BD43C18080097183BF2BC
+:106320000066C8218C8E00040325782101F86821BD
+:1063300001AE60231980001D000000009158004C40
+:106340008F8D0020956E0E10330F00FF8DA9000475
+:1063500001CF30238DAA000030CFFFFF000F610076
+:10636000012C2821000038210147202100AC182BE6
+:106370000083C821ADA50004ADB9000091B8000AA2
+:1063800001F87021A1AE000A956C0E128F8A0020D0
+:10639000A54C00089549003825280001A54800387B
+:1063A0009147000D34EB0008A14B000D03E00008FD
+:1063B0000000000027BDFFD8AFB00018938F000881
+:1063C0008FB000143C087FFF8F8700103C0C8000CA
+:1063D0003518FFFFAFBF0020AFB1001C35990A0090
+:1063E00002181824932A003C000F5FC03C02BFFF34
+:1063F0002CF000013449FFFF006BF8253C08080031
+:106400008D083BF48F99001C3C18080097183BEA54
+:1064100003E9582400107F803C07EFFF3C05F0FFA4
+:10642000016F18253C1180003149002034E2FFFF44
+:1064300034ADFFFF362E098027A500102406000288
+:1064400001194023270A00020062182400808021DD
+:1064500015200002000058218D8B0E1CA7AA0012E7
+:106460000500003A2407000030EF00FF000F3F0056
+:10647000006740253C028008AFA80014344B008020
+:10648000916A00683C0F080091EF3BF13C09DFFF87
+:10649000353FFFFF000A602B3C02080094423BE4BA
+:1064A000A3AF0011011FC024000CCF400319182511
+:1064B0008FA70010AFA300143C1F080093FF3BF30D
+:1064C000A7A200168FA8001400ED48243C0B010081
+:1064D0003C0A0FFF012BC82533F80003354CFFFFA2
+:1064E000010D78243C027000032C382400181E0093
+:1064F00000E2482501E35825AFAB0014AFA9001016
+:1065000091DF007CA3BF00150E00007200000000A8
+:10651000362D0A0091A6003C30C4002010800006F1
+:10652000260200083C11080096313BE0262EFFFFB2
+:106530003C010800A42E3BE08FBF00208FB1001C5F
+:106540008FB0001803E0000827BD00288F8A0018CC
+:10655000016A602B5580FFC4240700010A000D501A
+:1065600030EF00FF938300083C02800027BDFFD876
+:1065700034480A0000805021AFBF002034460AC0D2
+:10658000010028211060000E34440980910700307A
+:10659000240B00058F89000C30EC003F118B000BA1
+:1065A00000003821AFA900103C0B80088D69006CF9
+:1065B000AFAA00180E00013AAFA90014A38000088A
+:1065C0008FBF002003E0000827BD00288D1F004872
+:1065D0003C1808008F183BD48F9900143C027FFFB1
+:1065E0008D0800443443FFFFAFA900103C0B800826
+:1065F0008D69006C03E370240319782101CF6823AF
+:1066000001A83821AFAA00180E00013AAFA9001462
+:106610000A000DA5A38000083C05800034A60A00EE
+:1066200090C7003C3C06080094C63BF23C020800C0
+:106630008C423BEC30E30020000624001060003167
+:10664000004448253C0880083505008090A3006878
+:1066500000006821240C000100005021240B0001DF
+:106660003C188000370F00708DE800003C07800068
+:10667000AF8800248CF901780720FFFE34E5007014
+:106680008CA200003C0308008C6300743C0F0800DF
+:106690008DEF007000482023006428210000C021F5
+:1066A00000A4302B01F8702101C640213C010800F4
+:1066B000AC2500743C010800AC280070ACEC01482B
+:1066C0003C0208008C423BF4A4EA0144A4EB0146DE
+:1066D000ACE2014C3C04080090843BF13C03800890
+:1066E000A0E40152ACE90154A4ED0158346D0080DE
+:1066F00091AC004C3C091000A0EC016D03E00008D7
+:10670000ACE901788CAC0E1C3C0B08008D6B3BD4C3
+:1067100094AA0E1694AE0E1401666821314BFFFF49
+:106720000A000DCD31CAFFFF3C04800034830A000B
+:106730009065003C30A200201040002B00000000BB
+:106740000000582100005021000048213C08800032
+:10675000350400708C8800003C078000AF8800245E
+:106760008CEC01780580FFFE34EE00708DCD0000CA
+:106770003C0508008CA500743C0408008C84007063
+:1067800001A8602300ACC02100001021030C302BB5
+:106790000082C821032678213C010800AC3800742F
+:1067A0003C010800AC2F0070ACEB01483C0E080027
+:1067B0008DCE3BF4240DFF91240B0040A4E901444D
+:1067C000A4EA0146ACEE014CA0ED0152ACEB015441
+:1067D000A4E0015890EA01093C091000A0EA016D0B
+:1067E00003E00008ACE901788C8B0E1894870E1238
+:1067F00094860E1030EAFFFF0A000E0830C9FFFF32
+:106800003C04800034830A009065003C30A20020E4
+:106810001040003927BDFFF8240C00010000502172
+:10682000240B00013C088000350400708C890000B6
+:106830003C088000AF8900248D0D017805A0FFFE83
+:10684000350E00708DC700003C0508008CA5007453
+:106850003C0408008C84007000E9682300ADC0216E
+:1068600000001021030D302B0082C821032678215F
+:106870003C010800AC3800743C010800AC2F0070EB
+:10688000910901093C0E080091CE3C313C0380FF88
+:10689000A3A900038FAD000031C7007F3462FFFF62
+:1068A00001A82025AFA400009106010AA3A00002C0
+:1068B0000007CE00A3A600018FA50000240E300023
+:1068C0003C09100000A2C02403197825AD0F014C2B
+:1068D00027BD0008AD0E0154A5000158AD0C0148BC
+:1068E000A50A0144240AFF80A50B0146A10A015212
+:1068F00003E00008AD0901788C8C0E1894870E1205
+:1069000094860E1030EBFFFF0A000E3E30CAFFFFE8
+:1069100027BDFFE8AFB000103C108000AFBF0014EF
+:1069200036180A00970F00320E000AD531E43FFFF7
+:106930008E0E0100240DFF803C04200001C258216E
+:10694000016D6024000C4940316A007F012A402516
+:10695000010438253C048008AE07083034860080E6
+:1069600090C500682403000230A200FF1043000419
+:106970008F9F000C8F990010AC9F0068AC99006449
+:106980008FBF00148FB0001003E0000827BD00186F
+:106990003C0A0800254A37FC3C090800252938D460
+:1069A0003C08080025082C743C07080024E739E45B
+:1069B0003C06080024C636383C05080024A5339060
+:1069C0003C04080024842FA03C030800246336EC18
+:1069D0003C020800244234883C010800AC2A3DFCFB
+:1069E0003C010800AC293DF83C010800AC283DF40E
+:1069F0003C010800AC273E003C010800AC263E10DC
+:106A00003C010800AC253E083C010800AC243E04D3
+:106A10003C010800AC233E143C010800AC223E0CB3
+:086A200003E000080000000083
+:086A2800800009408000090014
+:106A3000800801008008008080080000800E0000AF
+:106A4000800800808008000080000A8080000A0022
+:086A50008000098080000900AC
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/firmware/bnx2/bnx2-rv2p-06-4.6.16.fw.ihex b/firmware/bnx2/bnx2-rv2p-06-4.6.16.fw.ihex
new file mode 100644
index 00000000000..871de9e3421
--- /dev/null
+++ b/firmware/bnx2/bnx2-rv2p-06-4.6.16.fw.ihex
@@ -0,0 +1,441 @@
+:100000000000000000000CA00000005800000000EC
+:1000100000000000000000000000000000000000E0
+:1000200000000000000000000000000000000000D0
+:1000300000000DE000000CF80000000500000000CA
+:1000400000000000000000000000000000000000B0
+:080050000000000000000000A8
+:0800580000000010B18000025D
+:100060000000001F0103010000000008AC000001B7
+:1000700000000000050000000000000C2F800001BF
+:10008000000000002B000000000000002B8000009A
+:1000900000000010203F006300000010213F00031B
+:1000A0000000001020BF0032000000188000FFFD9B
+:1000B00000000010B1B8B00D0000000B2FDF0002EF
+:1000C0000000000003D80000000000002C380000F1
+:1000D0000000001091D400000000000806005555F3
+:1000E0000000001880000075000000188000010B5F
+:1000F00000000008020000020000000F42E0001CA7
+:100100000000001091840A11000000102C62000B06
+:10011000000000188000001E00000008020000021D
+:100120000000000F42E0001C0000001091840A183B
+:10013000000000082C8000B1000000082D0000091C
+:100140000000001091D40000000000082D8001077D
+:10015000000000188000006F0000001880000015EB
+:1001600000000008B1000001000000082C8000B071
+:10017000000000082D000008000000082D8000018C
+:1001800000000018800000690000000B2FDF000253
+:100190000000000C1F800002000000002C0700007F
+:1001A0000000001091DE00000000000005000000CB
+:1001B000000000188000FFDC0000000B2FDF0002B1
+:1001C0000000000C1F800000000000002C07000051
+:1001D0000000001091DE000000000000050000009B
+:1001E000000000188000FFD60000000C1F800002F5
+:1001F0000000000005000000000000188000FFD390
+:100200000000000C298000020000000C1F8000028A
+:10021000000000002ADF0000000000082A0000059E
+:100220000000000805005555000000188000FFCDB3
+:10023000000000080224003C000000180004000038
+:10024000000000188000001C000000188000001E44
+:100250000000001880000052000000188000009E7E
+:10026000000000188000009D0000001880000000C1
+:10027000000000188000000000000018800000004E
+:10028000000000188000000000000018800000003E
+:10029000000000188000000000000018800000002E
+:1002A000000000188000000000000018800000DF3F
+:1002B000000000188000000000000018800000000E
+:1002C0000000001880000015000000188000001BCE
+:1002D000000000188000000000000018800000B43A
+:1002E000000000188000002E00000018800000DFD1
+:1002F000000000188000010A00000018800000D5EE
+:10030000000000188000012E000000188000003B53
+:10031000000000188000000000000018800000713C
+:100320000000000C1F80000100000000050000001C
+:10033000000000188000FFAC0000001091D4000005
+:100340000000000C298000010000000C1F8000014B
+:10035000000000082A000002000000000500000064
+:10036000000000188000FFA60000001091D40000DB
+:100370000000000C298000010000000C1F8000011B
+:100380000000000029420000000000082A000002CE
+:100390000000000005000000000000188000FF9F22
+:1003A000000000188000FF9E00000010B1BCB00AE1
+:1003B0000000000B2FDF00020000000003D8000047
+:1003C000000000002C3C00000000001091D4000050
+:1003D00000000008060055550000001880000016B7
+:1003E00000000018800000AC000000102C6201BA70
+:1003F0000000001880000005000000082C8000B1FB
+:10040000000000082D0000090000001091D4000039
+:10041000000000082D8001070000000C298000006A
+:100420000000000C1F8000000000001091DE0000A2
+:10043000000000002ADF0000000000082A0000067B
+:100440000000000805005555000000188000FF89D5
+:100450000000001091D400000000000C2980000171
+:100460000000000C1F800001000000082A00000BA3
+:100470000000000005000000000000188000FF835D
+:1004800000000018000200000000000006820000CA
+:1004900000000010B18A000600000000860C140065
+:1004A00000000010B18C00040000000005000000F6
+:1004B000000000082A0000010000001091D4000094
+:1004C00000000018000D0000000000000502000000
+:1004D0000000001091DE000000000018000A00007B
+:1004E00000000010B1A0B0130000000B2FDF0002CD
+:1004F000000000002C200000000000082C800000FC
+:10050000000000082D0000000000001091D4000041
+:100510000000000806005555000000188000FFEE9E
+:10052000000000082D80011C00000010001F0000CA
+:100530000000001091DE00000000000F476000087E
+:100540000000000F060E0001000000000F58000020
+:10055000000000000A640000000000000AE500003E
+:10056000000000090B66FFFF000000000D610000A5
+:1005700000000018800000130000000F4760000812
+:100580000000000B2FDF0002000000082C8000009C
+:10059000000000082D0000000000001091D40000B1
+:1005A000000000082D80011C0000000F060E000155
+:1005B00000000010001F0000000000000F580000A5
+:1005C0000000001091DE0000000000000A6400003E
+:1005D000000000000AE50000000000090B66FFFFB4
+:1005E000000000000D610000000000000262000039
+:1005F0000000000B2FDF00020000000031040000AB
+:1006000000000000309A0000000000000C96180066
+:10061000000000090C99FFFF00000004CC99340091
+:1006200000000010B1963202000000080F800000A8
+:100630000000000C298000010000001000220002D0
+:100640000000000C295200010000000C295200009B
+:10065000000000080200000E000000080280001ADE
+:1006600000000010B1C40A020000000802000003EC
+:1006700000000008220000010000000C1F800001A3
+:10068000000000002ADF0000000000002A0008002F
+:100690000000000805005555000000188000FF3FCD
+:1006A0000000000B2FDF00020000001091D40000BA
+:1006B000000000082A000001000000002C200000BB
+:1006C000000000082C800000000000082D00000041
+:1006D000000000082D80011C0000001091D40000D3
+:1006E0000000001091DE0000000000082C800006D1
+:1006F000000000082D00000600000000308000000F
+:100700000000000031000000000000082D800006FD
+:100710000000000C298000010000000C1F80000177
+:100720000000001091DE0000000000002ADF000041
+:10073000000000082A000010000000000500000072
+:10074000000000188000FF2A0000001091A0B009EE
+:10075000000000082C8000B1000000082D000009F6
+:100760000000001091D40000000000082D80010757
+:10077000000000188000FFAB00000018800000108F
+:1007800000000008AC000001000000188000000B11
+:10079000000000000380B0000000000B2FDF00020B
+:1007A000000000002C0040000000001091D4000068
+:1007B0000000000806005555000000188000FF9A50
+:1007C00000000018800000300000001880000006C3
+:1007D0000000000B2FDF0002000000002C000E00C4
+:1007E000000000082A000007000000080500555519
+:1007F000000000188000FF140000000006820000C6
+:100800000000000C298000010000000C1F80000186
+:10081000000000100CE70007000000090562FFFF60
+:1008200000000010BA6C1405000000002ADF000070
+:100830000000000021000000000000082A00000560
+:100840000000001091D40000000000082C8000B0CF
+:10085000000000082D0000080000000C31620018A4
+:10086000000000082D800001000000188000FF8CAF
+:1008700000000018000D000000000010B1A0B00E34
+:100880000000000B2FDF00020000000003D8000072
+:10089000000000002C2000000000001091D4000097
+:1008A0000000001880000014000000102C620002FC
+:1008B000000000188000000B0000000B2FDF00027A
+:1008C000000000002C0700000000000C1F80000149
+:1008D0000000001091DE0000000000000500000094
+:1008E000000000188000FEF6000000082C8000B117
+:1008F000000000082D0000090000001091D4000045
+:10090000000000082D8001070000000C2980000174
+:100910000000000C1F8000010000001091DE0000AC
+:10092000000000002ADF0000000000082A00000A82
+:100930000000000005000000000000188000FEEB31
+:100940000000000005020000000000082C8000B03C
+:10095000000000082D000008000000082D80015054
+:10096000000000000000000000000010205F0000F8
+:10097000000000082C800000000000082D0000008E
+:10098000000000082D8001080000000000000000A9
+:100990000000001091DE000000000018000A0000B6
+:1009A0000000001091D40000000000080600AAAA70
+:1009B000000000188000FF5B0000000C298000018F
+:1009C0000000000C1F800001000000082A00000940
+:1009D000000000080500AAAA000000188000FED749
+:1009E0000000001091D400000000000806005555DA
+:1009F000000000188000FF530000001091A03C028E
+:100A000000000010B1E662070000000B2FDF0002BB
+:100A1000000000002C310000000000092CB1007F14
+:100A2000000000082CD90000000000082D00000084
+:100A3000000000082D80010D00000010B1A8000684
+:100A400000000010205F0000000000002C200000CB
+:100A5000000000002CA70000000000082D0000107E
+:100A6000000000082D800108000000188000FF4CE5
+:100A700000000010B1A6001000000010001F0000D0
+:100A80000000000F0F300007000000000A600000A7
+:100A9000000000000AE100000000000F4B620008A7
+:100AA000000000090B1600FF000000000D620000AE
+:100AB000000000090D1A00FF0000001007300003BD
+:100AC0000000000C0D1A00080000000C0B160008B6
+:100AD0000000000F4CE30018000000000C992C00EF
+:100AE00000000004CC993400000000080F800000D2
+:100AF0000000000C298000010000000033310000DC
+:100B00000000000822000016000000002ADF00009C
+:100B1000000000082A00000C00000010009F0000E8
+:100B2000000000000F2000000000000C1F800001EA
+:100B30000000000805005555000000188000FEABBD
+:100B40000000001091D40000000000080600AAAACE
+:100B5000000000188000FF270000000F4722000857
+:100B600000000009070E000F00000008070E000833
+:100B700000000008028000010000000702851C0040
+:100B800000000008828500010000000002854C0082
+:100B90000000000742851C0000000003C3AA5200A9
+:100BA0000000000003B10E00000000074B071C000E
+:100BB0000000000F0F3000070000000F0A9600032E
+:100BC000000000000A955C00000000004A005A0086
+:100BD000000000000C960A00000000090C99FFFFBD
+:100BE000000000080D00FFFF00000010B196320267
+:100BF000000000080F80000500000010B1A80008E8
+:100C000000000010205F00000000000B2FDF00023A
+:100C1000000000002C200000000000002CA70000B5
+:100C2000000000082D000010000000082D800108C1
+:100C3000000000188000FF130000000C2980000154
+:100C400000000010001F00000000000C1F800001C9
+:100C5000000000002ADF0000000000082A00000D4C
+:100C6000000000080500AAAA000000188000FE8508
+:100C70000000001091D40000000000080600555547
+:100C8000000000188000FF010000000C2980000116
+:100C90000000000C1F800001000000082A0000076F
+:100CA0000000000805005555000000188000FE7D7A
+:100CB00000000008030500040000000683040C0087
+:100CC00000000008028502000000000086050C00FC
+:100CD00000000001860C0E00000000080204000461
+:100CE00000000000020418000000000083871800C4
+:080CF0000000001800020000E2
+:080CF80000000010B1800004AF
+:100D00000000001F0103010000000008050000FFB3
+:100D10000000001800020000000000002A0000008F
+:100D200000000010B1D400000000000C2980000178
+:100D30000000000802540008000000180004000031
+:100D40000000001880000010000000188000001152
+:100D5000000000188000003A000000188000010424
+:100D6000000000188000010300000018800001024C
+:100D70000000001880000102000000188000000040
+:100D8000000000188000011400000018800000FE20
+:100D9000000000188000000C0000001880000118FE
+:100DA000000000188000016A000000188000006741
+:100DB00000000018800000DA00000018800000E742
+:100DC000000000002A000000000000188000FFEB77
+:100DD000000000002A0000000000000C2980000034
+:100DE0000000001020530000000000188000FFE702
+:100DF000000000002A000000000000188000FFE54D
+:100E000000000018000200000000000005020000C1
+:100E1000000000109196342100000010205F0000B7
+:100E2000000000002C1E0000000000082C800006BE
+:100E3000000000082D000006000000082D800102BF
+:100E400000000000000000000000001091DE000023
+:100E5000000000000D61000000000018000A000002
+:100E600000000000050200000000001091963416FA
+:100E700000000010205F00000000000009D8000002
+:100E8000000000002C1E0000000000082C8000B2B2
+:100E9000000000082D00000A000000082D8001025B
+:100EA00000000000000000000000001091DE0000C3
+:100EB000000000000D620000000000002C13000084
+:100EC00000000018000A00000000000005020000F9
+:100ED000000000109196340900000010205F00000F
+:100EE000000000002C1E0000000000082C800006FE
+:100EF000000000082D00006A000000082D8001029B
+:100F000000000000000000000000001091DE000062
+:100F1000000000000D7A000000000018000A000028
+:100F20000000001091DE000000000010001F000013
+:100F3000000000002F80AA00000000002A0000002E
+:100F4000000000000D6100000000000003620000CE
+:100F5000000000002C4000000000000002638C0034
+:100F600000000000264600000000000802040012F5
+:100F700000000010B9060827000000000F5800000C
+:100F8000000000000A640000000000000AE5000004
+:100F9000000000090B66FFFF000000000C000000CD
+:100FA000000000000B800000000000080CC60012CA
+:100FB000000000188000FFCB000000080F80000335
+:100FC000000000000000000000000010009F000072
+:100FD00000000008271100120000000066900000C9
+:100FE00000000008A31B001200000010B1980003CD
+:100FF00000000010001F0000000000080F80000427
+:101000000000000822000003000000082C80000CF3
+:10101000000000082D00000C00000010009F0000E0
+:1010200000000000259600000000000C2980000050
+:101030000000000006660000000000008661180045
+:10104000000000090260000F0000000F020400020F
+:1010500000000010B60C08030000000C1FBF0000C9
+:101060000000000C33660010000000003214000085
+:1010700000000000329500000000000573662C009F
+:101080000000000031E32E00000000082D80001059
+:1010900000000010205300000000001091DE00004E
+:1010A000000000188000FF900000000023000000F6
+:1010B0000000000925E6FFFF000000082200000BE9
+:1010C0000000000C695200000000000C29800000A4
+:1010D0000000001020530000000000188000FF896D
+:1010E0000000001091DE000000000010001F000052
+:1010F000000000002F80AA00000000002A0000006D
+:10110000000000002C400000000000082C8000407F
+:10111000000000082D000020000000082D80011CA8
+:1011200000000000000000000000001091DE000040
+:101130000000000F42EA001000000010004F000401
+:1011400000000010B746920000000008024900129B
+:1011500000000010B5840A00000000000D610000CE
+:1011600000000010BA66345A00000000036200005C
+:1011700000000010B8630C5800000008830500123E
+:1011800000000010004F00020000000003490000B2
+:101190000000000183068C000000000083C60C00E4
+:1011A00000000010B1870010000000000B6E00006E
+:1011B000000000188000FF6B0000000106691400A9
+:1011C00000000010918C000200000008B4E900014A
+:1011D00000000010B1E92C4C0000000086692C00D2
+:1011E00000000000020000000000000902EAFFFF0A
+:1011F00000000010000C00020000000002040A00C1
+:101200000000000F460C00010000000F02850001E5
+:1012100000000010918C01FC00000010B7040E4388
+:10122000000000002C400000000000000F40000003
+:10123000000000000D610000000000000A640000D2
+:10124000000000000AE50000000000090B66FFFF37
+:10125000000000000C000000000000000B800000F7
+:10126000000000080C860012000000080F80000338
+:101270000000000C2952000000000010009F000038
+:101280000000000827110012000000006690000016
+:1012900000000000264600000000000023060000B9
+:1012A00000000010B198000500000010001F0000B1
+:1012B000000000080F800004000000000000000093
+:1012C00000000010001F00000000000032140000A9
+:1012D00000000000329500000000000031E32E0005
+:1012E0000000000573662C00000000002596000039
+:1012F00000000010B18700160000000C29800000DB
+:101300000000000F0F6B0007000000000D690000D7
+:10131000000000000A6C0000000000000AED000060
+:10132000000000000B6E0000000000000B800000B9
+:10133000000000000C870000000000080F80000380
+:1013400000000010205300000000000C6952000152
+:1013500000000010001F00000000000022C58C00EB
+:1013600000000000231B0000000000002711000007
+:10137000000000002690000000000010B8170E03C7
+:101380000000000C29800000000000188000FFF61B
+:1013900000000010B1980002000000080F80000457
+:1013A000000000082200001A000000082C80000C39
+:1013B000000000082D00000C000000082D80001027
+:1013C00000000010001F0000000000000D6E000073
+:1013D00000000003E7CF34000000000C298000006B
+:1013E0000000001091DE000000000010B18700072F
+:1013F00000000000361400000000000036950000D8
+:101400000000000037160000000000082C8000508B
+:10141000000000082D000030000000082D80000CA6
+:101420000000001020530000000000188000FF1F83
+:10143000000000002646000000000000230000001D
+:101440000000000925E6FFFF000000000B6E000011
+:1014500000000003E7CF2C00000000082200001B62
+:101460000000000C695200000000000C2980000000
+:101470000000001020530000000000188000FF153D
+:10148000000000002FD50000000000002A0000002E
+:1014900000000010003F000B000000000666000086
+:1014A000000000008661180000000009026000F0E2
+:1014B00000000010B70C08070000000C7366001055
+:1014C000000000082C800018000000082D00001803
+:1014D000000000082D8000020000000C5FBF00002B
+:1014E0000000001091DE0000000000188000FF07DF
+:1014F000000000002FD50000000000002A000000BE
+:10150000000000002C4000000000000C29800000BA
+:101510000000001091DE0000000000082C80001A7E
+:10152000000000082D00001A000000003300000039
+:10153000000000082D800002000000003180000043
+:101540000000001091DE0000000000082C80000C5C
+:10155000000000082D00000C000000082D80000491
+:1015600000000010205300000000001091DE000079
+:10157000000000188000FEF6000000188000FEF554
+:10158000000000002A00000000000010001F000002
+:10159000000000000F008000000000080F8000071E
+:1015A0000000001880000014000000000502000088
+:1015B000000000082200000900000000286D000063
+:1015C00000000000290000000000000F6568001006
+:1015D00000000003F66C940000000010B972A00433
+:1015E0000000000C73E700190000000C2142000409
+:1015F000000000003BF600000000000C2980000005
+:101600000000001020530000000000082200000825
+:101610000000000C6142000400000018000A0000F5
+:10162000000000002A00000000000010001F000061
+:101630000000000F0F470007000000080F8000089F
+:101640000000000C29800000000000102053000062
+:10165000000000188000FEDA0000001091DE00009B
+:10166000000000002FD5000000000010001F000047
+:101670000000000033510000000000002A000000BC
+:1016800000000010B1C600230000000F0F5000073B
+:10169000000000000A600000000000000AE10000F5
+:1016A0000000000F4B620008000000090B1600FF4D
+:1016B0000000000F4C620010000000000D620000EE
+:1016C000000000090D1A00FF000000100750000381
+:1016D0000000000C0D1A00080000000C0B1600089A
+:1016E000000000000CC60000000000000B8000009D
+:1016F0000000000006980000000000080F800003B2
+:101700000000001006C200040000000C29000002C6
+:1017100000000010264200020000000C29520003C5
+:10172000000000082200000100000010009F0000DF
+:1017300000000000231B00000000000027111A0019
+:1017400000000000669000000000000C295200001C
+:1017500000000010B19732090000000C2980000041
+:101760000000000006980000000000102053000058
+:101770000000000C295200030000000022C58C006C
+:1017800000000010001F0000000000080F80000390
+:10179000000000188000FFF300000010B1C8001323
+:1017A00000000010B1C600030000000C29800000FA
+:1017B00000000010205300000000000C295200001F
+:1017C0000000000C295200030000001006C20002B5
+:1017D0000000000C295200020000000022C58C000D
+:1017E00000000000276500000000000026E4000063
+:1017F000000000082200001600000010B1C600031F
+:10180000000000002348000000000010B180000527
+:1018100000000000234800000000000C29800000A8
+:101820000000000F0F500007000000188000001299
+:1018300000000008220000160000000C29800000B3
+:10184000000000003014000000000000309500008F
+:101850000000001007500003000000090B1600FFF5
+:10186000000000090D1A00FF0000000F31160008EB
+:10187000000000003162340000000003F16230001B
+:1018800000000010205F0000000000002C5100004C
+:10189000000000092CD1007F000000082CD90000B6
+:1018A000000000082D000000000000082D80000C42
+:1018B00000000000000000000000001091DE0000A9
+:1018C0000000001005C2000300000000330000000B
+:1018D000000000080F8000070000001020530000E7
+:1018E00000000010009F0000000000188000FE872C
+:1018F000000000002FD50000000000002A000000BA
+:101900000000000F0F50000700000010B1C6002DAE
+:101910000000000F4742000800000009070E000FFA
+:1019200000000008070E000800000010001F000063
+:1019300000000008090000010000000709121C0057
+:1019400000000003CBCA9200000000000B97A20029
+:101950000000000742171C00000000000B040000FC
+:101960000000000F0A840003000000000A959C009C
+:10197000000000004A009A000000000882120001E6
+:10198000000000010C170800000000000C978C00FC
+:101990000000000002180000000000080D00FFFF1A
+:1019A000000000080F8000060000000C2900000065
+:1019B0000000001006C200040000000C29520002C2
+:1019C00000000010264200020000000C2952000313
+:1019D000000000082200000100000010009F00002D
+:1019E00000000010B197320C00000000231B000023
+:1019F00000000000271108000000000066900000B1
+:101A00000000000C29800000000000000218000007
+:101A100000000010205300000000000C29520003B9
+:101A20000000000022C5360000000010001F00006A
+:101A3000000000080F800006000000188000FFF47E
+:101A400000000000231B0000000000002711080018
+:101A5000000000006690000000000010B1C8000BFC
+:101A60000000000C2980000000000010205300003E
+:101A70000000000C295200000000000C2952000355
+:101A80000000001006C200020000000C29520002F3
+:101A90000000000022C58C00000000002765000047
+:101AA0000000000026E400000000000023480000C1
+:101AB00000000008220000170000000C2980000030
+:101AC00000000010001F0000000000102053000064
+:081AD000000000188000FE4A2E
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/firmware/bnx2/bnx2-rv2p-09-4.6.15.fw.ihex b/firmware/bnx2/bnx2-rv2p-09-4.6.15.fw.ihex
new file mode 100644
index 00000000000..63995bbc8e2
--- /dev/null
+++ b/firmware/bnx2/bnx2-rv2p-09-4.6.15.fw.ihex
@@ -0,0 +1,490 @@
+:100000000000000000000D88000000580000000003
+:1000100000000000000000000000000000000000E0
+:1000200000000000000000000000000000000000D0
+:100030000000101800000DE00000000500000000A6
+:1000400000000000000000000000000000000000B0
+:080050000000000000000000A8
+:0800580000000010B18000025D
+:100060000000001F0303010000000008AC000001B5
+:1000700000000000050000000000000C2F800001BF
+:10008000000000002B000000000000002B8000009A
+:1000900000000010203F006C00000010213F000312
+:1000A0000000001020BF003B000000188000FFFD92
+:1000B00000000010B1B8B0150000000B2FDF0002E7
+:1000C0000000000003D80000000000002C380000F1
+:1000D000000000082C800000000000082D00000037
+:1000E0000000001091D400000000000806005555E3
+:1000F000000000188000008F000000082D80011C07
+:1001000000000008020000010000001091DE000065
+:100110000000000F42E0001C0000001091840A174C
+:1001200000000010086600160000000C2980000284
+:100130000000000C1F800002000000002ADF000009
+:10014000000000082A00000F0000000805005555B7
+:10015000000000188000FFE8000000080200000115
+:100160000000000F42E0001C0000001091840A19FA
+:10017000000000082C800006000000082D0000068A
+:100180000000001091D40000000000082D8001063E
+:1001900000000018800000830000001008660013B3
+:1001A000000000188000FFF100000008B10000010D
+:1001B000000000082C80010C000000082D00000841
+:1001C000000000082D800001000000188000007C65
+:1001D0000000000B2FDF00020000000C1F80000257
+:1001E000000000002C0700000000001091DE00005D
+:1001F0000000000005000000000000188000FFD390
+:100200000000000B2FDF00020000000C1F80000028
+:10021000000000002C0700000000001091DE00002C
+:100220000000000005000000000000188000FFCD65
+:100230000000000C1F80000200000000050000000C
+:10024000000000188000FFCA0000000C2980000296
+:100250000000000C1F800002000000002ADF0000E8
+:10026000000000082A0000050000000805005555A0
+:10027000000000188000FFC40000000802240045B0
+:100280000000001800040000000000188000001C9E
+:10029000000000188000001E0000001880000065AB
+:1002A00000000018800000AD00000018800000ACC5
+:1002B000000000188000000000000018800000000E
+:1002C00000000018800000000000001880000000FE
+:1002D00000000018800000000000001880000000EE
+:1002E00000000018800000000000001880000000DE
+:1002F00000000018800000F30000001880000000DB
+:1003000000000018800000000000001880000015A8
+:10031000000000188000001B000000188000000092
+:1003200000000018800000C3000000188000002EAC
+:1003300000000018800000F3000000188000011E7B
+:1003400000000018800000E9000000188000014251
+:10035000000000188000004E00000018800000001F
+:1003600000000018800000800000000C1F800001C9
+:100370000000000005000000000000188000FFA33E
+:100380000000001091D400000000000C2980000142
+:100390000000000C1F800001000000082A0000027D
+:1003A0000000000005000000000000188000FF9D14
+:1003B0000000001091D400000000000C2980000112
+:1003C0000000000C1F800001000000002942000016
+:1003D000000000082A0000020000000005000000E4
+:1003E000000000188000FF96000000188000FF95B4
+:1003F00000000010B1BCB00A0000000B2FDF0002AB
+:100400000000000003D80000000000002C3C0000A9
+:100410000000001091D400000000000806005555AF
+:10042000000000188000002900000018800000BBB8
+:10043000000000102C6201BA0000001880000005C6
+:10044000000000082C80010D000000082D000009AC
+:100450000000001091D40000000000082D8001076A
+:100460000000000C298000000000000C1F8000002C
+:100470000000001091DE0000000000002ADF0000F4
+:10048000000000082A00000600000008050055557D
+:10049000000000188000FF800000001091D40000D0
+:1004A0000000000C298000010000000C1F800001EA
+:1004B000000000082A00000B0000000005000000FA
+:1004C000000000188000FF7A000000000202000017
+:1004D00000000000029A000000000000060C2C0042
+:1004E00000000004C60C340000000010001F0000D3
+:1004F00000000010B196180C0000000806960004D9
+:1005000000000009068DFFFC00000004CD051A0064
+:1005100000000004CC9A18000000001020D7000052
+:100520000000000C2B56000000000000000000003E
+:1005300000000000000000000000001020D70000B4
+:10054000000000080F80000100000010B18001F4DD
+:1005500000000010001F00000000000C6B5600009F
+:1005600000000018000400000000000006820000E7
+:1005700000000010B18A000600000000860C140084
+:1005800000000010B18C0004000000000500000015
+:10059000000000082A0000010000001091D40000B3
+:1005A00000000018000D000000000000050200001F
+:1005B0000000001091DE000000000018000A00009A
+:1005C00000000010B1A0B0130000000B2FDF0002EC
+:1005D000000000002C200000000000082C8000001B
+:1005E000000000082D0000000000001091D4000061
+:1005F0000000000806005555000000188000FFEEBE
+:10060000000000082D80011C00000010001F0000E9
+:100610000000001091DE00000000000F476000089D
+:100620000000000F060E0001000000000F5800003F
+:10063000000000000A640000000000000AE500005D
+:10064000000000090B66FFFF000000000D610000C4
+:1006500000000018800000130000000F4760000831
+:100660000000000B2FDF0002000000082C800000BB
+:10067000000000082D0000000000001091D40000D0
+:10068000000000082D80011C0000000F060E000174
+:1006900000000010001F0000000000000F580000C4
+:1006A0000000001091DE0000000000000A6400005D
+:1006B000000000000AE50000000000090B66FFFFD3
+:1006C000000000000D610000000000000262000058
+:1006D0000000000B2FDF00020000000031040000CA
+:1006E00000000000309A0000000000188000FFBCED
+:1006F0000000000C29800001000000100022000210
+:100700000000000C295200010000000C29520000DA
+:10071000000000080200000E000000080280001A1D
+:1007200000000010B1C40A0200000008020000032B
+:1007300000000008220000010000000C1F800001E2
+:10074000000000002ADF0000000000002A0008006E
+:100750000000000805005555000000188000FF2724
+:100760000000000B2FDF00020000001091D40000F9
+:10077000000000082A000001000000002C200000FA
+:10078000000000082C800000000000082D00000080
+:10079000000000082D80011C0000001091D4000012
+:1007A0000000001091DE0000000000082C80000610
+:1007B000000000082D00000600000000308000004E
+:1007C0000000000031000000000000082D8000063D
+:1007D0000000000C298000010000000C1F800001B7
+:1007E0000000001091DE0000000000002ADF000081
+:1007F000000000082A0000100000000005000000B2
+:10080000000000188000FF120000001091A0B00945
+:10081000000000082C80010D000000082D000009D8
+:100820000000001091D40000000000082D80010796
+:10083000000000188000FFAF0000001880000010CA
+:1008400000000008AC000001000000188000000B50
+:10085000000000000380B0000000000B2FDF00024A
+:10086000000000002C0040000000001091D40000A7
+:100870000000000806005555000000188000FF9E8B
+:100880000000001880000030000000188000000602
+:100890000000000B2FDF0002000000002C000E0003
+:1008A000000000082A000007000000080500555558
+:1008B000000000188000FEFC00000000068200001E
+:1008C0000000000C298000010000000C1F800001C6
+:1008D000000000100CE70007000000090562FFFFA0
+:1008E00000000010BA6C1405000000002ADF0000B0
+:1008F0000000000021000000000000082A000005A0
+:100900000000001091D40000000000082C80010CB1
+:10091000000000082D0000080000000C31620018E3
+:10092000000000082D800001000000188000FF90EA
+:1009300000000018000D000000000010B1A0B00E73
+:100940000000000B2FDF00020000000003D80000B1
+:10095000000000002C2000000000001091D40000D6
+:100960000000001880000014000000102C6200023B
+:10097000000000188000000B0000000B2FDF0002B9
+:10098000000000002C0700000000000C1F80000188
+:100990000000001091DE00000000000005000000D3
+:1009A000000000188000FEDE000000082C80010D11
+:1009B000000000082D0000090000001091D4000084
+:1009C000000000082D8001070000000C29800001B4
+:1009D0000000000C1F8000010000001091DE0000EC
+:1009E000000000002ADF0000000000082A00000AC2
+:1009F0000000000005000000000000188000FED389
+:100A00000000000005020000000000082C80010C1E
+:100A1000000000082D000008000000082D800134AF
+:100A2000000000000000000000000010205F000037
+:100A3000000000082C800140000000082D00003C50
+:100A4000000000082D80011C0000000000000000D4
+:100A500000000010205F0000000000082C800080D3
+:100A6000000000082D000000000000082D80010893
+:100A700000000000000000000000001091DE0000F7
+:100A800000000018000A00000000001091D40000CF
+:100A9000000000080600AAAA000000188000FF5A03
+:100AA0000000000C298000010000000C1F800001E4
+:100AB000000000082A000009000000080500AAAA9A
+:100AC000000000188000FEBA0000001091D4000061
+:100AD0000000000806005555000000188000FF5275
+:100AE0000000001091A03C0200000010B1E6620777
+:100AF0000000000B2FDF0002000000002C3100007E
+:100B0000000000092CB1007F000000082CD9000073
+:100B1000000000082D000000000000082D80010DDD
+:100B200000000010B1A8000600000010205F0000C7
+:100B3000000000002C200000000000002CA7000096
+:100B4000000000082D000010000000082D800108A2
+:100B5000000000188000FF4B00000010B1A600103C
+:100B600000000010001F00000000000F0F30000701
+:100B7000000000000A600000000000000AE1000020
+:100B80000000000F4B620008000000090B1600FF78
+:100B9000000000000D620000000000090D1A00FFB7
+:100BA00000000010073000030000000C0D1A0008C0
+:100BB0000000000C0B1600080000000F4CE30018AA
+:100BC000000000000C992C0000000004CC993400B7
+:100BD000000000080F8000000000000C29800001C8
+:100BE0000000000033310000000000082200001661
+:100BF000000000002ADF0000000000082A00000CAE
+:100C000000000010009F0000000000000F20000006
+:100C10000000000C1F800001000000080500555571
+:100C2000000000188000FE8E0000001091D400002B
+:100C3000000000080600AAAA000000188000FF2695
+:100C40000000000F4722000800000009070E000FF7
+:100C500000000008070E00080000000802800001E4
+:100C60000000000702851C000000000882850001CA
+:100C70000000000002854C000000000742851C00B7
+:100C800000000003C3AA52000000000003B10E00E0
+:100C9000000000074B071C000000000F0F3000078A
+:100CA0000000000F0A960003000000000A955C0097
+:100CB000000000004A005A00000000000C960A00E4
+:100CC000000000090C99FFFF000000080D00FFFF65
+:100CD00000000010B1963202000000080F800005ED
+:100CE00000000010B1A8000800000010205F000004
+:100CF0000000000B2FDF0002000000002C2000008D
+:100D0000000000002CA70000000000082D000010CB
+:100D1000000000082D800108000000188000FF126C
+:100D20000000000C2980000100000010001F0000DE
+:100D30000000000C1F800001000000002ADF0000FE
+:100D4000000000082A00000D000000080500AAAA03
+:100D5000000000188000FE680000001091D4000020
+:100D60000000000806005555000000188000FF0034
+:100D70000000000C298000010000000C1F80000111
+:100D8000000000082A000007000000080500555573
+:100D9000000000188000FE60000000080305000449
+:100DA0000000000683040C00000000080285020019
+:100DB0000000000086050C0000000001860C0E00FB
+:100DC00000000008020400040000000002041800F3
+:100DD00000000000838718000000001800020000D7
+:100DE00000000010B18000040000001F0303010098
+:100DF00000000008050000FF0000001800020000CD
+:100E0000000000002A00000000000010B1D4000023
+:100E10000000000C298000010000000802540009B5
+:100E2000000000092952003F0000001800040000E3
+:100E30000000001880000010000000188000001161
+:100E4000000000188000004B000000188000013CEA
+:100E5000000000188000013B000000188000013AEB
+:100E6000000000188000013A000000188000000017
+:100E7000000000188000014D0000001880000136BD
+:100E8000000000188000000C0000001880000152D3
+:100E900000000018800001AC0000001880000080F5
+:100EA00000000018800001070000001880000115F4
+:100EB000000000002A000000000000188000FFEA87
+:100EC000000000002A0000000000000C2980000043
+:100ED0000000001020530000000000188000FFE612
+:100EE000000000002A000000000000188000FFE45D
+:100EF0000000000003820000000000188000FFDFF7
+:100F0000000000010C161400000000008C181400F2
+:100F10000000001091980003000000080C960002E9
+:100F200000000010B1800003000000080C960001D2
+:100F3000000000000C000000000000000D1900007F
+:100F400000000010205600000000000C2BD700010C
+:100F5000000000080F8000010000000000000000F9
+:100F600000000010001F00000000000C6BD7000103
+:100F700000000010011301F100000018000700003C
+:100F800000000000050200000000001091963421CE
+:100F900000000010205F0000000000002C1E000078
+:100FA000000000082C800006000000082D0000064C
+:100FB000000000082D800102000000000000000079
+:100FC0000000001091DE0000000000000D61000034
+:100FD00000000018000A00000000000005020000E8
+:100FE000000000109196341600000010205F0000F1
+:100FF0000000000009D80000000000002C1E0000C6
+:10100000000000082C80010E000000082D00000ADE
+:10101000000000082D800102000000000000000018
+:101020000000001091DE0000000000000D620000D2
+:10103000000000002C13000000000018000A00004F
+:101040000000000005020000000000109196340925
+:1010500000000010205F0000000000002C1E0000B7
+:10106000000000082C800006000000082D00006A27
+:10107000000000082D8001020000000000000000B8
+:101080000000001091DE0000000000000D7A00005A
+:1010900000000018000A00000000001091DE0000AF
+:1010A00000000010001F00000000000C6BD70001C2
+:1010B000000000002F80AA00000000002A000000AD
+:1010C000000000000D61000000000000036200004D
+:1010D000000000002C4000000000000002638C00B3
+:1010E0000000000026460000000000080204001274
+:1010F00000000010B906082E000000000F58000084
+:10110000000000000A640000000000000AE5000082
+:10111000000000090B66FFFF000000000C0000004B
+:10112000000000000B800000000000080CC6001248
+:10113000000000188000FFCA0000001020560000C8
+:101140000000000C2BD70001000000080F800003F6
+:10115000000000000000000000000010001F000060
+:101160000000000C6BD700010000000827110012DE
+:10117000000000006690000000000008A31B0012A1
+:1011800000000010B198000600000010001F0000D1
+:101190000000000C6BD7000100000010205600007A
+:1011A0000000000C2BD70001000000080F80000495
+:1011B0000000000822000003000000082C80000C42
+:1011C000000000082D00000C00000010001F0000AF
+:1011D0000000000C6BD70001000000002596000005
+:1011E0000000000C298000000000000006660000DE
+:1011F0000000000086611800000000090260000F76
+:101200000000000F0204000200000010B60C0803EA
+:101210000000000C1FBF00000000000C336600102F
+:1012200000000000321400000000000032950000B1
+:101230000000000573662C000000000031E32E0062
+:10124000000000082D800010000000102053000056
+:101250000000001091DE0000000000188000FF7602
+:1012600000000000230000000000000925E6FFFF49
+:10127000000000082200000B0000000C6952000072
+:101280000000000C29800000000000102053000026
+:10129000000000188000FF6F0000001091DE0000C9
+:1012A00000000010001F00000000000C6BD70001C0
+:1012B000000000002F80AA00000000002A000000AB
+:1012C000000000002C400000000000082C800040BE
+:1012D000000000082D000020000000082D80011CE7
+:1012E00000000000000000000000001091DE00007F
+:1012F0000000000F42EA001000000010004F000440
+:1013000000000010B74692000000000802490012D9
+:1013100000000010B5840A00000000000D6100000C
+:1013200000000010BA66346D000000000362000087
+:1013300000000010B8630C6B000000088305001269
+:1013400000000010004F00020000000003490000F0
+:101350000000000183068C000000000083C60C0022
+:1013600000000010B1870010000000000B6E0000AC
+:10137000000000188000FF50000000010669140002
+:1013800000000010918C000200000008B4E9000188
+:1013900000000010B1E92C5F0000000086692C00FD
+:1013A00000000000020000000000000902EAFFFF48
+:1013B00000000010000C00020000000002040A00FF
+:1013C0000000000F460C00010000000F0285000124
+:1013D00000000010918C01FC00000010B7040E56B4
+:1013E000000000002C400000000000000F40000042
+:1013F000000000000D610000000000000A64000011
+:10140000000000000AE50000000000090B66FFFF75
+:10141000000000000C000000000000000B80000035
+:10142000000000080C86001200000010205600008A
+:101430000000000C2BD70001000000080F80000303
+:101440000000000C2952000000000010001F0000E6
+:101450000000000C6BD700010000000827110012EB
+:10146000000000006690000000000000264600001A
+:10147000000000002306000000000010B1980009E1
+:1014800000000010001F00000000000C6BD70001DE
+:1014900000000010205600000000000C2BD70001B7
+:1014A000000000080F8000040000000000000000A1
+:1014B00000000010001F00000000000C6BD70001AE
+:1014C000000000003214000000000000329500000F
+:1014D0000000000031E32E000000000573662C00C0
+:1014E000000000002596000000000010B1870021D8
+:1014F0000000000C298000000000000F0F6B0007A7
+:10150000000000000D690000000000000A6C0000EF
+:10151000000000000AED0000000000000B6E00005B
+:10152000000000000B800000000000000C8700009D
+:10153000000000188000FF18000000010C161400C5
+:10154000000000008C181400000000080C96000138
+:101550000000001091980002000000080C990001A2
+:10156000000000000D190000000000000C00000049
+:1015700000000010205600000000000C2BD70001D6
+:10158000000000080F800001000000102053000040
+:101590000000000C6952000100000010001F000054
+:1015A0000000000C6BD700010000000022C58C0079
+:1015B00000000000231200000000000027110000BE
+:1015C000000000002690000000000010B8170E0375
+:1015D0000000000C29800000000000188000FFEBD4
+:1015E0000000000082970E0000000000A3120A0015
+:1015F000000000082200001A000000082C80000CE7
+:10160000000000082D00000C000000082D800010D4
+:1016100000000010001F00000000000C6BD700014C
+:10162000000000000D6E000000000003E7CF340052
+:101630000000000C298000000000001091DE000076
+:1016400000000010B1870007000000003614000001
+:101650000000000036950000000000003716000072
+:10166000000000082C800050000000082D00003011
+:10167000000000082D80000C000000102053000026
+:10168000000000188000FEF1000000002646000067
+:1016900000000000230000000000000925E6FFFF15
+:1016A000000000000B6E000000000003E7CF2C00DC
+:1016B000000000082200001B0000000C695200001E
+:1016C0000000000C298000000000001020530000E2
+:1016D000000000188000FEE7000000002FD5000089
+:1016E000000000002A00000000000010003F000C75
+:1016F000000000000666000000000000866118007F
+:1017000000000009026000F000000010B70C08089B
+:10171000000000002C4000000000000C7366001068
+:10172000000000082C800018000000082D000018A0
+:10173000000000082D8000020000000C5FBF0000C8
+:101740000000001091DE0000000000188000FED8AC
+:10175000000000002FD50000000000002A0000005B
+:10176000000000002C4000000000000C7366001018
+:10177000000000082C800018000000082D00001850
+:10178000000000082D8000020000000C5FBF000078
+:101790000000001091DE0000000000082C80000313
+:1017A000000000082D000003000000093060FFF079
+:1017B000000000082D8000010000000C29800000BE
+:1017C0000000001091DE0000000000082C80001ACC
+:1017D000000000082D00001A000000003300000087
+:1017E000000000082D800002000000003180000091
+:1017F0000000001091DE0000000000082C80000CAA
+:10180000000000082D00000C000000082D800004DE
+:1018100000000010205300000000001091DE0000C6
+:10182000000000188000FEBD000000188000FEBC13
+:10183000000000002A00000000000010001F00004F
+:101840000000000C6BD70001000000000F008000BA
+:10185000000000080F80000700000018800000153D
+:10186000000000000502000000000008220000093E
+:1018700000000000286D00000000000029000000AA
+:101880000000000F6568001000000003F66C940073
+:1018900000000010B972A0040000000C73E70019EA
+:1018A0000000000C21420004000000003BF6000094
+:1018B0000000000C298000000000001020530000F0
+:1018C00000000008220000080000000C6142000433
+:1018D00000000018000A0000000000002A000000BC
+:1018E00000000010001F00000000000C6BD700017A
+:1018F0000000000F0F470007000000080F800008DD
+:101900000000000C2980000000000010205300009F
+:10191000000000188000FE9F0000001091DE000013
+:10192000000000002FD5000000000010001F000084
+:101930000000000C6BD700010000000033510000D4
+:10194000000000002A00000000000010B1C60029BD
+:101950000000000F0F500007000000000A600000A8
+:10196000000000000AE100000000000F4B620008C8
+:10197000000000090B1600FF0000000F4C62001071
+:10198000000000000D620000000000090D1A00FFB9
+:1019900000000010075000030000000C0D1A0008A2
+:1019A0000000000C0B160008000000000CC6000030
+:1019B000000000000B8000000000000006980000FE
+:1019C00000000010205600000000000C2BD7000182
+:1019D000000000080F8000030000001006C2000491
+:1019E0000000000C29000002000000102642000246
+:1019F0000000000C29520003000000082200000132
+:101A000000000010001F00000000000C6BD7000158
+:101A100000000000231B00000000000027111A0036
+:101A200000000000669000000000000C2952000039
+:101A300000000010B197320C0000000C298000005B
+:101A40000000000006980000000000102053000075
+:101A50000000000C295200030000000022C58C0089
+:101A600000000010001F00000000000C6BD70001F8
+:101A700000000010205600000000000C2BD70001D1
+:101A8000000000080F800003000000188000FFEF36
+:101A900000000010B1C8001300000010B1C6000320
+:101AA0000000000C298000000000001020530000FE
+:101AB0000000000C295200000000000C2952000315
+:101AC0000000001006C200020000000C29520002B3
+:101AD0000000000022C58C00000000002765000007
+:101AE0000000000026E400000000000822000016AC
+:101AF00000000010B1C600030000000023480000F1
+:101B000000000010B1800005000000002348000024
+:101B10000000000C298000000000000F0F5000079B
+:101B200000000018800000120000000822000016CB
+:101B30000000000C298000000000000030140000AC
+:101B40000000000030950000000000100750000366
+:101B5000000000090B1600FF000000090D1A00FF2D
+:101B60000000000F31160008000000003162340050
+:101B700000000003F162300000000010205F000050
+:101B8000000000002C510000000000092CD1007F53
+:101B9000000000082CD90000000000082D00000003
+:101BA000000000082D80000C000000000000000074
+:101BB0000000001091DE00000000001005C20003CC
+:101BC0000000000033000000000000080F80000744
+:101BD000000000102053000000000010001F000053
+:101BE0000000000C6BD70001000000188000FE44CC
+:101BF000000000002FD50000000000002A000000B7
+:101C00000000000F0F50000700000010B1C60030A8
+:101C10000000000F4742000800000009070E000FF7
+:101C200000000008070E000800000010001F000060
+:101C30000000000C6BD70001000000080900000143
+:101C40000000000709121C0000000003CBCA92002C
+:101C5000000000000B97A2000000000742171C00C4
+:101C6000000000000B0400000000000F0A840003C5
+:101C7000000000000A959C00000000004A009A0045
+:101C80000000000882120001000000010C1708008B
+:101C9000000000000C978C000000000002180000FB
+:101CA000000000080D00FFFF000000080F80000684
+:101CB0000000000C290000000000001006C2000413
+:101CC0000000000C29520002000000102642000211
+:101CD0000000000C2952000300000008220000014F
+:101CE00000000010001F00000000000C6BD7000176
+:101CF00000000010B197320D00000000231B00000F
+:101D0000000000002711080000000000669000009D
+:101D10000000000C298000000000000002180000F4
+:101D200000000010205300000000000C29520003A6
+:101D30000000000022C5360000000010001F000057
+:101D40000000000C6BD70001000000080F800006A7
+:101D5000000000188000FFF200000000231B0000BC
+:101D6000000000002711080000000000669000003D
+:101D700000000010B1C8000B0000000C298000001A
+:101D800000000010205300000000000C2952000049
+:101D90000000000C295200030000001006C20002DF
+:101DA0000000000C295200020000000022C58C0037
+:101DB00000000000276500000000000026E400008D
+:101DC0000000000023480000000000082200001767
+:101DD0000000000C2980000000000010001F00001F
+:101DE0000000000C6BD70001000000102053000021
+:081DF000000000188000FE0352
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/scripts/ihex2fw.c b/firmware/ihex2fw.c
index 8f7fdaa9e01..8f7fdaa9e01 100644
--- a/scripts/ihex2fw.c
+++ b/firmware/ihex2fw.c
diff --git a/firmware/myricom/lanai.bin.ihex b/firmware/myricom/lanai.bin.ihex
new file mode 100644
index 00000000000..bf47f4c7494
--- /dev/null
+++ b/firmware/myricom/lanai.bin.ihex
@@ -0,0 +1,4771 @@
+:100000004FF8F20EFE00C290000007880008E001E1
+:10001000014C9793FFFCE000001400000001000079
+:1000200000009293FFFC02900008F7062A6C9713D9
+:10003000FFFCF7062C109713FFFC07880008E00070
+:1000400015489793FFFCF702053C9713FFFCF70256
+:1000500000039713FFFCF70629E09713FFFC0788BE
+:100060000008E000161C9793FFFCF7062B849713FB
+:10007000FFFCF7062C1C9713FFFC07880008E00024
+:1000800015489793FFFCF7020ABC9713FFFCF70291
+:1000900000029713FFFCF7062AF89713FFFC078866
+:1000A0000008E000161C9793FFFC8796FFFC8296E1
+:1000B000FFF802140000013C0000000000019293D0
+:1000C000FFFC02900008F7044A9C85160000203AC5
+:1000D0000001EE00010100000001F70475EC0000D2
+:1000E0000001203A0000E600010000000001F704D2
+:1000F00075F000000001203A0000E600012D00002C
+:100100000001F7042D38F6862C2806380001F60584
+:100110002D3877390002F482001220320044E600C4
+:1001200001E0B4BA6802E00001E0F0052D38F70400
+:100130003B64F5844F54F7057A10202E0000E6004A
+:100140000199972A002095AA001CF6064A9826AC29
+:10015000000177350001C738680077390002073899
+:10016000000CA4BA60020000000194AA0010C73875
+:100170006000873A000400000001972A0014F70489
+:100180004A9C0000000127380001C02E7200D700F1
+:100190000A01E00001D0F7057A1895AA001CF606BE
+:1001A0004A9806AC000177350001C73868007739F6
+:1001B00000020738000CA4BA60020000000194AAF3
+:1001C0000010C7386000873A0004F0057A18972AB3
+:1001D0000014F50579D807880008E00001F497932A
+:1001E000FFFC8796FFFC8296FFF802140004013C96
+:1001F0000000000000019293FFFC02900008221012
+:100200000038F7047A10F6843B6400000001C03A1D
+:100210006A00470C0001D7000A70203A0000E6008F
+:10022000024C00000001F70475EC00000001203AC8
+:100230000000E600024C00000001F70475F0000029
+:100240000001203A0000E6000285F4820000F70475
+:100250002D38F6862C2806380001F6052D3877391A
+:100260000002F302001220320044E6000274B33AA6
+:100270006802F0052D38F3062A6CF3052C10E00017
+:100280000528F0057A18F38479D8F6844AA0231457
+:1002900000209316FFC4841E00109696FFD4F70426
+:1002A0004A9C9416FFE0851E0014C0367200EC00D4
+:1002B000036C9516FFE477350001C738680077397D
+:1002C0000002F3064A98C6B8300006B4000CC58494
+:1002D00000008736000000000001C03A4200E6003E
+:1002E00002FCC62400008736000400000001C03A6A
+:1002F0005200E600030020320000F6020001203226
+:100300000000E600030D00000001F58200008636C3
+:1003100000008716FFE000000001C0327200E2001A
+:100320000348F5020000C0327200E6000350202AA4
+:10033000000086B600048716FFE400000001C03606
+:100340007200E2000351202A0000F5020001202A79
+:100350000000E6000361202E0000F5820001202E3F
+:100360000000E600037020260000F4820001202631
+:100370000000E60003A5F60200018716FFD4F3068D
+:100380004A9876B90001C6B4700076B50002C6B4CA
+:10039000300006B4001486B600009716FFD8E000BF
+:1003A00004189696FFDC2714002C9713FFFC831685
+:1003B000FFC4000000019313FFFCF3064A98931357
+:1003C000FFFC9396FFCC07880008E001256897930F
+:1003D000FFFC8396FFCC20220000E6000415F60205
+:1003E00000018716FFD4F3064A9876B90001C6B417
+:1003F000700076B50002C6B4300006B4001486B6AC
+:1004000000009716FFD89696FFDCF7054AA0E0009B
+:10041000041C20320000F602000020320000E6003A
+:10042000042CF4820001E0000484F482000086962B
+:10043000FFD80000000177350002C738680077391F
+:100440000002F68642C8A63A6802C73868007539C5
+:10045000001E7528FFE505B8000286AE00000738CB
+:1004600000049716FFECC63057C07630FFF09616A2
+:10047000FFF475AD001E75ACFFE5C6B45FC076B481
+:10048000FFF09696FFF020260000E6000525F30613
+:1004900029E08696FFF0F5820000C7346800C49C0E
+:1004A0007200C02E6A00EC0004F0C5240000C62CC7
+:1004B00000008716FFEC00000001A6B2700205AC38
+:1004C0000001C73070007739001E7738FFE5C6B4E9
+:1004D00077C076B4FFF0F6AB280005280002871637
+:1004E000FFF000000001C02E7200EC0004B10630E5
+:1004F0000002F3020003F30576F48716FFF0869EF0
+:100500000004C7387000C7384800C6B470008716AA
+:10051000FFF406B400209702FF6C9482FF5096828D
+:10052000FF58F30629E0F3052C108796FFFC82960E
+:10053000FFF802140000013C00000000000192934B
+:10054000FFFC02900008F7047A1800000001203A2E
+:100550000000E60005CD00000001F7047A10F684E3
+:100560003B6400000001C03A6A00470C0001203AD9
+:100570000000E60005CDF5864A98F60479D8F684A1
+:100580004F540000000196B2001C06B400017735FC
+:100590000001C7386800773900020738000CA53A17
+:1005A00058020000000195320010C7385800873A01
+:1005B0000004F0057A189732001407880008E0005C
+:1005C00001F49793FFFCE00005FC00000001F70434
+:1005D0002D38F6862C2806380001F6052D38773997
+:1005E0000002F502001220320044E60005F4B53A9C
+:1005F0006802F0052D38F5062A6CF5052C10879653
+:10060000FFFC8296FFF802140000013C000000008D
+:1006100000019293FFFC0290000885960000F70409
+:1006200075EC852E0020203A0000E60006CCF5058A
+:100630007A08F70475F000000001203A0000E60097
+:1006400006CC00000001F7047A08F6843B64000041
+:100650000001C03A6A00470C0001D7000A70203A36
+:100660000000E60006CC00000001872E001CF68486
+:100670004F54F7057A00C7347200203A0000EE00AC
+:10068000068DF5020001E0000690F50579F8F08589
+:1006900079F8F6847A00C7387000C6B47000F704A1
+:1006A00079F8F68579E8C7387000C6347000F70429
+:1006B0004A9C00000001C0367200EC0006CCF60532
+:1006C00079F020360000EC0006F800000001F70485
+:1006D0002D38F6862C2806380001F6052D38773996
+:1006E0000002F502001320320044E6000738B53A54
+:1006F0006802E0000738F0052D38F7044A9C000036
+:100700000001C0327200EE00071900000001F7047A
+:100710004A9CE0000728F70579F020320000EC0041
+:10072000072800000001F08579F0F58579E0078859
+:100730000008E000074C9793FFFC8796FFFC829629
+:10074000FFF802140004013C000000000001929335
+:10075000FFFC0290000822100038F70475EC00003E
+:100760000001203A0000E60007A400000001F704A1
+:1007700075F000000001203A0000E60007A4000028
+:100780000001F7047A08F6843B6400000001C03AD7
+:100790006A00470C0001D7000A70203A0000E6000A
+:1007A00007D5F4020000F7042D38F6862C28063809
+:1007B0000001F6052D3877390002F30200132032CC
+:1007C0000044E60007CCB33A6802F0052D38E0009B
+:1007D0000AA4F3062B84F68479E8F6064A9877355E
+:1007E0000001C738680077390002F68479E00738DD
+:1007F000000CA33A6002C3B4000093360010C7385F
+:100800006000873A0004231400209316FFC4973633
+:100810000014849E0010F6844AA09496FFE09696F9
+:10082000FFD4851E0014F7044A9C00000001C03666
+:100830007200EC0008EC9516FFE477350001C7382C
+:10084000680077390002C6B8600006B4000CC584A1
+:1008500000008736000000000001C03A4A00E600B0
+:10086000087CC62000008736000400000001C03A62
+:100870005200E600088020320000F602000120321B
+:100880000000E600088D00000001F58200008636B9
+:1008900000008716FFE000000001C0327200E20095
+:1008A00008C8F5020000C0327200E60008D0202A15
+:1008B000000086B600048716FFE400000001C03681
+:1008C0007200E20008D1202A0000F5020001202A6F
+:1008D0000000E60008E1202E0000F5820001202E35
+:1008E0000000E60008F020220000F40200012022AF
+:1008F0000000E6000925F60200018716FFD4F30682
+:100900004A9876B90001C6B4700076B50002C6B444
+:10091000300006B4001486B600009716FFD8E00039
+:1009200009989696FFDC2714002C9713FFFC83167A
+:10093000FFC4000000019313FFFCF3064A989313D1
+:10094000FFFC9396FFCC07880008E0012568979389
+:10095000FFFC8396FFCC20220000E6000995F602FA
+:1009600000018716FFD4F3064A9876B90001C6B491
+:10097000700076B50002C6B4300006B4001486B626
+:1009800000009716FFD89696FFDCF7054AA0E00016
+:10099000099C20320000F602000020320000E60030
+:1009A00009ACF4820001E0000A04F482000086969B
+:1009B000FFD80000000177350002C738680077399A
+:1009C0000002F68642C8A63A6802C7386800753940
+:1009D000001E7528FFE505B8000286AE0000073846
+:1009E00000049716FFECC63057C07630FFF096161D
+:1009F000FFF475AD001E75ACFFE5C6B45FC076B4FC
+:100A0000FFF09696FFF020260000E6000AA5F30608
+:100A10002AF88696FFF0F5820000C7346800C49C6F
+:100A20007200C02E6A00EC000A70C5240000C62CBB
+:100A300000008716FFEC00000001A6B2700205ACB2
+:100A40000001C73070007739001E7738FFE5C6B463
+:100A500077C076B4FFF0F6AB2800052800028716B1
+:100A6000FFF000000001C02E7200EC000A310630D9
+:100A70000002F3020002F30576F48716FFF0869E6B
+:100A80000004C7387000C7384800C6B47000871625
+:100A9000FFF406B400209702FF6C9482FF50968208
+:100AA000FF58F3062AF8F3052C1C8796FFFC829664
+:100AB000FFF802140000013C0000000000019293C6
+:100AC000FFFC02900008F68479E8F70479F800004A
+:100AD0000001C6B47000F7047A20F68579E807387B
+:100AE0000001F7057A20F70479F0F6047A20C03681
+:100AF0007200E6000B2CF6862C28F7042D38000037
+:100B0000000106380001F6052D3877390002F5821C
+:100B1000001320320044E6000B20B5BA6802F0054D
+:100B20002D38F5862B84E0000B38F5852C1C0788C2
+:100B30000008E000074C9793FFFC8796FFFC829625
+:100B4000FFF802140000013C000000000001929335
+:100B5000FFFC02900008F7062C109713FFFCF70625
+:100B600029E09713FFFC07880008E00014F497932E
+:100B7000FFFCF7062C109713FFFCF7062A6C97135F
+:100B8000FFFC07880008E00014F49793FFFCF706C9
+:100B90002C1C9713FFFCF7062AF89713FFFC078815
+:100BA0000008E00014F49793FFFCF7062C1C971341
+:100BB000FFFCF7062B849713FFFC07880008E00072
+:100BC00014F49793FFFC8796FFFC8296FFF80214BB
+:100BD0000000013C0000000000019293FFFC029025
+:100BE0000008F0052D38F0052D3C8796FFFC829615
+:100BF000FFF802140000013C000000000001929385
+:100C0000FFFC0290000822100018FF852EDCF7067A
+:100C10000C3EC77C7400203A0000E60014299716A9
+:100C2000FFF44738FFFBF6846F50CFB8000083967F
+:100C3000FFF4F702003FC39C6D80C71C7400203A8C
+:100C4000003FE20012609396FFF477390002F682CB
+:100C50000C5CA6B6700200000001C1340000000068
+:100C600012600000126000000D6800000D680000B6
+:100C70000D5C00000D5C00000D6800000D680000B8
+:100C80001250000012500000123C0000123C000004
+:100C90000DE000000DE00000123C0000123C0000DE
+:100CA0000DE800000DF400000E0000000E20000012
+:100CB0000E4000000E6000000E8000000EA000003C
+:100CC0000EC000000EC800000ED000001228000068
+:100CD0000ED800000EF400000F10000012280000D3
+:100CE0000F1800000F1800000F2400000F24000050
+:100CF0000F4400000F4400000F6400000F64000068
+:100D00000F8400000F8400000F8C00000F8C000087
+:100D10000F9400000F9400000FB000000FB000000F
+:100D20000FB800000FD800000FF80000102C0000D2
+:100D3000106000001094000010C8000010FC0000BB
+:100D400011300000114C0000116800001214000066
+:100D50001184000011B4000011E400001214F382A9
+:100D60000006E00012549393FFFCF60200052032C7
+:100D70000014E6000DB527000010203A0001E20043
+:100D80000DB5F7062DCCF6842ECC0000000175B50C
+:100D90000002B62E700206B40001F6852ECC860243
+:100DA000FF34F7062E4C2036001FE2000DB5B62E9C
+:100DB0007002F0052ECCF7042D5800000001873A90
+:100DC000000000000001873A0018000000010788B9
+:100DD0000008C13800009793FFFCE000126000009B
+:100DE0000001E0001240F3820006F382000BE000F5
+:100DF00012549393FFFCF3820007E0001254939384
+:100E0000FFFCF382000B9393FFFC07880008E000CF
+:100E100015849793FFFCF3820005E000125493932E
+:100E2000FFFCF38200079393FFFC07880008E000B3
+:100E300015849793FFFCF3820005E000125493930E
+:100E4000FFFCF382000B9393FFFC07880008E0008F
+:100E500015849793FFFCF3820006E00012549393ED
+:100E6000FFFCF38200079393FFFC07880008E00073
+:100E700015849793FFFCF3820006E00012549393CD
+:100E8000FFFCF382000B9393FFFC07880008E0004F
+:100E900015849793FFFCF3820005E00012549393AE
+:100EA000FFFCF38200079393FFFC07880008E00033
+:100EB00015849793FFFCF3820005E000125493938E
+:100EC000FFFCE0001240F382000BE0001240F382CE
+:100ED0000007E000122CF382000BF382000B9393C7
+:100EE000FFFC07880008E00015849793FFFCE000F2
+:100EF0001240F3820006F38200079393FFFC0788F9
+:100F00000008E00015849793FFFCE0001240F38294
+:100F10000006E000122CF382000BF3820014E000C4
+:100F200012549393FFFCF38200149393FFFC078801
+:100F30000008E00015849793FFFCF3820005E000B1
+:100F400012549393FFFCF38200149393FFFC0788E1
+:100F50000008E00015849793FFFCF3820006E00090
+:100F600012549393FFFCF38200149393FFFC0788C1
+:100F70000008E00015849793FFFCF3820005E00071
+:100F800012549393FFFCE0001240F3820014E0003F
+:100F9000122CF3820014F38200149393FFFC078851
+:100FA0000008E00015849793FFFCE0001240F382F4
+:100FB0000006E000122CF3820014F38200149393D5
+:100FC000FFFC07880008E00015849793FFFCF3827C
+:100FD000000BE00012549393FFFCF38200149393F0
+:100FE000FFFC07880008E00015849793FFFCF3825C
+:100FF0000007E00012549393FFFCF38200149393D4
+:10100000FFFC07880008E00015849793FFFCF3823B
+:10101000000B9393FFFC07880008E000158497936A
+:10102000FFFCF3820005E00012549393FFFCF3826F
+:1010300000149393FFFC07880008E0001584979341
+:10104000FFFCF38200079393FFFC07880008E00091
+:1010500015849793FFFCF3820005E00012549393EC
+:10106000FFFCF38200149393FFFC07880008E00064
+:1010700015849793FFFCF382000B9393FFFC078882
+:101080000008E00015849793FFFCF3820006E0005F
+:1010900012549393FFFCF38200149393FFFC078890
+:1010A0000008E00015849793FFFCF38200079393F8
+:1010B000FFFC07880008E00015849793FFFCF3828B
+:1010C0000006E00012549393FFFCF3820014939304
+:1010D000FFFC07880008E00015849793FFFCF3826B
+:1010E000000B9393FFFC07880008E000158497939A
+:1010F000FFFCF3820005E00012549393FFFCF3829F
+:1011000000149393FFFC07880008E0001584979370
+:10111000FFFCF38200079393FFFC07880008E000C0
+:1011200015849793FFFCF3820005E000125493931B
+:10113000FFFCF38200149393FFFC07880008E00093
+:1011400015849793FFFCE0001240F382000BF382BA
+:1011500000149393FFFC07880008E0001584979320
+:10116000FFFCE0001240F3820007F3820014939327
+:10117000FFFC07880008E00015849793FFFCE0005F
+:10118000122CF382000BF38200149393FFFC078868
+:101190000008E00015849793FFFCF382000B939303
+:1011A000FFFC07880008E00015849793FFFCE0002F
+:1011B0001240F3820006F38200149393FFFC078829
+:1011C0000008E00015849793FFFCF38200079393D7
+:1011D000FFFC07880008E00015849793FFFCE000FF
+:1011E0001240F3820006F38200149393FFFC0788F9
+:1011F0000008E00015849793FFFCE000122CF382B6
+:10120000000BF7043528F682000107380008E000DB
+:1012100013CCF7053544F38200149393FFFC078841
+:101220000008E00015849793FFFCF3820007939376
+:10123000FFFC07880008E00015849793FFFCF38209
+:1012400000059393FFFC07880008E000158497933E
+:10125000FFFC9013FFFC07880008E00015849793BB
+:10126000FFFC8396FFF400000001779C0014703EA1
+:10127000FFE1E600129DF7060400F7046F5C000032
+:10128000000107380001F7056F5CF7046F5CE000B0
+:101290000000000000018396FFF4F7060400C01E62
+:1012A0007400E600142900000001F7042ED0F68433
+:1012B00035240738000120360000E6001405F70544
+:1012C0002ED0F704E01400000001203A0000E600F0
+:1012D0001405F6820000F685E014F7042ED8C53414
+:1012E000000007380001F7052ED8202A0002EE0082
+:1012F00013CCF6820000F684352800000001873602
+:10130000000000000001203A0002E60013A005B42E
+:1013100000089593FFFC9516FFE89596FFE49696D6
+:10132000FFE007880008E00016649793FFFC85162D
+:10133000FFE88596FFE48696FFE020220000E600A5
+:101340001390F70200008636000C000000012032E6
+:10135000000FE20013750000000187360014000042
+:101360000001073800019736001487360014E000AA
+:101370001390F702000076B10002C6B46000773522
+:101380000005C7386A00C738600007380010C72C4E
+:101390007000203A0000E6001200F705352CF684B4
+:1013A0003528F7046F4C00000001C0367200E600DB
+:1013B00013C007341494F3846F44E00013C4F3851E
+:1013C0003528F7053528E00012E805280001203609
+:1013D0000000E6001429F6862C28F7042D38F005C5
+:1013E000352406380001F6052D3877390002F382DE
+:1013F000000D20320044E6001428B3BA6802E00071
+:101400001428F0052D38F704E01000000001203A00
+:101410000000E6001429F7020000F705E010078835
+:101420000008E00102989793FFFCF4842D38F7043C
+:101430002D3C00000001C03A4A00E6000C09F68687
+:101440002C2877390002A53A680200000001202A02
+:101450000014E600149127280015203A0001E2004C
+:101460001491F7062DCCF6842ECC8602FF3475B588
+:101470000002B52E700206B40001F6852ECCF706E8
+:101480002E4C2036001FE2001491B62E7002F0059B
+:101490002ECCF7062D4476A90002A7367002000074
+:1014A0000001873A000000000001C6B470008736D2
+:1014B00000049496FFEC07880008C1380000979359
+:1014C000FFFCF7042D3C8496FFEC07380001203A1E
+:1014D0000044E600142CF7052D3CE000142CF00528
+:1014E0002D3C8796FFFC8296FFF802140000013C19
+:1014F0000000000000019293FFFC02900008841697
+:101500000000F702000085960004203A0021EE005A
+:10151000153495A20000F606233807200084C6A0E3
+:101520000000963A000427380004C03A6A00EC0034
+:101530001520000000018796FFFC8296FFF8021438
+:101540000008013C0000000000019293FFFC0290A3
+:1015500000088696000087160004F6042D40973692
+:1015600000009736000407300001F7052D4096363D
+:1015700000088796FFFC8296FFF802140008013CE1
+:101580000000000000019293FFFC02900008851605
+:10159000000000000001202A0014E60015D92728C9
+:1015A0000015203A0001E20015D9F7062DCCF6848B
+:1015B0002ECC8602FF3475B50002B52E700206B43B
+:1015C0000001F6852ECCF7062E4C2036001FE200D7
+:1015D00015D9B62E7002F0052ECCF6862D4477294B
+:1015E0000002A6BA68020000000186B600000000F2
+:1015F0000001C7386800873A00040000000107882E
+:101600000008C13800009793FFFC8796FFFC829684
+:10161000FFF802140004013C000000000001929356
+:10162000FFFC029000088716000086960004F6066C
+:101630002D4476B5000285BA000000000001B5B661
+:101640006002C6B47000859600080000000195B6DF
+:1016500000048796FFFC8296FFF80214000C013C00
+:101660000000000000019293FFFC02900008861623
+:101670000000000000018732000400000001203A51
+:10168000000F86B20000C5380000EE0016B4C5B4E5
+:1016900000002036000FEE0016B400000001203AD2
+:1016A0000000EC0016B50000000120360000EC0040
+:1016B00016D0000000018732000C0000000107383E
+:1016C00000019732000C8732000CE00016D8F402BB
+:1016D0000000C02A5A00440C00018796FFFC829645
+:1016E000FFF802140004013C0000000000010000AB
+:1016F00000009293FFFC02900008F7062EE097137B
+:10170000FFFCF70632D49713FFFC07880008E000BF
+:1017100015489793FFFCF702182C9713FFFCF782EC
+:1017200000099793FFFCF7062EE09713FFFC07884C
+:101730000008E000161C9793FFFCF702345897133B
+:10174000FFFCF702000C9713FFFCF7062F6C9713B2
+:10175000FFFC07880008E000161C9793FFFCF702C7
+:101760003F949713FFFCF782000B9793FFFCF7065B
+:101770002FF89713FFFC07880008E000161C9793CA
+:10178000FFFCF7023B849713FFFCF782000B979353
+:10179000FFFCF70632289713FFFC07880008E000DB
+:1017A000161C9793FFFCF70226E49713FFFCF70241
+:1017B00000139713FFFCF70630849713FFFC07888C
+:1017C0000008E000161C9793FFFCF70226A0971371
+:1017D000FFFCF70200119713FFFCF7063110971377
+:1017E000FFFC07880008E000161C9793FFFCF70237
+:1017F000182C9713FFFCF78200099793FFFCF7065C
+:10180000319C9713FFFC07880008E000161C979393
+:10181000FFFCF0057A78F00532E88796FFFC8296A7
+:10182000FFF802140000013C000000000001929348
+:10183000FFFC0290000822100050F70471C800005D
+:101840000001203A0000E6001855F68671C4E00059
+:10185000186CF6020000F70471D40000000177391B
+:101860000002C7386800863A001800000001F6053B
+:1018700032C486B2000807018000C5B47400F58543
+:1018800032D087320018F6866F4477390002A73AC3
+:101890006802202E0000F70532C0073809D886B24A
+:1018A0000004F70532CCE6001941F68532C8F7048A
+:1018B0007198F6847A782738000120360000E60017
+:1018C0001910F7057198F70476FC00000001203A22
+:1018D0000000E60018E8F3020011F30632D4F30525
+:1018E00076FCE00018F8F7020001F30576F8F3063D
+:1018F00032D4F3057700F7020000203A0000E6003A
+:101900001914F3020001F3063110E000268CF305F0
+:1019100032D4F3020001F3057A78F3063084F3053C
+:1019200032D4F30432C4000000019313FFFC078893
+:101930000008E00006109793FFFCE000268C0000F2
+:101940000001F3020000202E0000E6001CB99316EF
+:10195000FFE4873200088696FFE4C3040000C03A23
+:101960003200E6001984203600008732000C0000A7
+:101970000001C03A3200E600198420360000F682E9
+:10198000000120360000E6001CB8F3020000F70456
+:1019900032C09316FFACF58432C4863A142803B8DB
+:1019A0001420042C000886BA142400000001C03260
+:1019B0006A00EC001A709616FFEC77310001C73808
+:1019C000600077390002C63838000630000C86B255
+:1019D0000000872E00088516FFACC0367200E600B6
+:1019E0001A00C484000086B20004872E000C000098
+:1019F0000001C0367200E6001A04202A0000F50239
+:101A00000001202A0000E6001A1100000001F48203
+:101A1000000086B200008722000000000001C036EE
+:101A20007200E2001A4CF5820000C0367200E60037
+:101A30001A54202E000086B2000487220004000001
+:101A40000001C0367200E2001A55202E0000F58217
+:101A50000001202E0000E6001A6520260000F48216
+:101A6000000120260000E6001A70F3020001931620
+:101A7000FFAC8316FFAC00000001201A0000E60056
+:101A80001AB1F60200018716FFEC0000000176B9DA
+:101A90000001C6B4700076B50002C6B4380006B4C2
+:101AA000001486B600009716FFF0E0001B1896960B
+:101AB000FFF4271400149713FFFC9413FFFC939377
+:101AC000FFFC9396FFBC07880008E0012568979308
+:101AD000FFFC8396FFBC20220000E6001B15F602E7
+:101AE00000018716FFEC0000000176B90001C6B4C2
+:101AF000700076B50002C6B4380006B4001486B68D
+:101B000000009716FFF09696FFF4971E0008E0007D
+:101B10001B1C20320000F602000020320000E6000C
+:101B20001CB8F3020000F60432C09316FFAC86B274
+:101B3000142803B014200430148C873214240000BD
+:101B40000001C0367200EC001C049696FFEC77355D
+:101B50000001C738680077390002C5B8380005AC05
+:101B6000000C86AE00008732148C8516FFACC036A0
+:101B70007200E6001B94C484000086AE0004873225
+:101B8000149000000001C0367200E6001B98202A65
+:101B90000000F5020001202A0000E6001BA500005D
+:101BA0000001F482000086AE0000872200000000E1
+:101BB0000001C0367200E2001BE0F6020000C036F1
+:101BC0007200E6001BE82032000086AE0004872287
+:101BD000000400000001C0367200E2001BE9203260
+:101BE0000000F602000120320000E6001BF920266A
+:101BF0000000F482000120260000E6001C04F3022D
+:101C000000019316FFAC8316FFAC00000001201A00
+:101C10000000E6001C45F60200018716FFEC0000FC
+:101C2000000176B90001C6B4700076B50002C6B4F2
+:101C3000380006B4001486B600009716FFF0E000E6
+:101C40001CAC9696FFF4271400149713FFFC941312
+:101C5000FFFC9393FFFC9396FFBC07880008E0010C
+:101C600025689793FFFC8396FFBC20220000E600C6
+:101C70001CA9F60200018716FFEC0000000176B9EE
+:101C80000001C6B4700076B50002C6B4380006B4D0
+:101C9000001486B600009716FFF09696FFF4971E84
+:101CA0000008E0001CB020320000F60200002032E4
+:101CB0000000E6001E15F3020001F68432C00000A9
+:101CC000000185B60EF486360EF8202E0010E200D4
+:101CD0001CDC20320010E2001CF9000000018736F5
+:101CE0000F00000000010738000197360F0087360B
+:101CF0000F00E0001D24F702000007300001C03A89
+:101D00005A00E6001D1DF682000020320010E60099
+:101D10001D20202E0000E6001D24C7340000F6829E
+:101D20000001C7340000203A0000E6001E14F30250
+:101D30000001F30432CC000000019316FFDC931382
+:101D4000FFFC07880008E00043689793FFFC20220F
+:101D50000000E6001DFCF30200008316FFDC00001B
+:101D60000001861A00000000000120320010E2008D
+:101D70001D9176B10002871A000C0000000107389F
+:101D80000001971A000C871A000CE0001DFCF302FA
+:101D90000000F302004C9313FFFCC6B460007735DB
+:101DA0000004C7386A008316FFDCC7386000C738F4
+:101DB0003000073800109713FFFCF3067A289313BE
+:101DC000FFFC9616FFB407880008E00126F89793F9
+:101DD000FFFC8616FFB4000000010630000120322F
+:101DE0000011E6001DEC00000001F6020000831661
+:101DF000FFDC00000001961A0000F30200019316B8
+:101E0000FFD48316FFD400000001201A0000E60072
+:101E10001E18F30200019316FFE48316FFE400008E
+:101E20000001201A0000E6001F35F6820CABF70413
+:101E300032B48316FFD407380001F70532B4F70433
+:101E400032B4201A0000E6001E7000000001F70402
+:101E500032C0F306E030C03A3200E6001E700000E7
+:101E60000001F70432E80000000107380001F7051F
+:101E700032E8F70471C400000001203A0000E600D7
+:101E80001EADF6862C28F7042D3800000001063818
+:101E90000001F6052D3877390002F302000A2032DE
+:101EA0000044E6001EACB33A6802F0052D38F70492
+:101EB00071D4F68471CC07380001C03A6A00E6009C
+:101EC0001EC8F70571D4F00571D4F68471D4F704F7
+:101ED00071D0F00571C4C0367200470C0001F68461
+:101EE00032D00000000120360000E60025D9F705B9
+:101EF00071C8F704719800000001203A0000E60064
+:101F0000257900000001F70475EC00000001203A7B
+:101F10000000E600257800000001F70475F00000DD
+:101F20000001203A0000E600257800000001E000F2
+:101F300025DCF306319CF00532E8F70432C0F604E4
+:101F40006F5496BA000420320000E6001F60F302CE
+:101F5000000CF3020001F3056F54E0001F68F70264
+:101F60000001F3056F58F7020000203A0000E60078
+:101F70001F7CF3062F6CE000268CF30532D4F58429
+:101F80007A7024940010202E0001E6002284F5854A
+:101F90007AA0F7020001F60432C8F7057A70F70458
+:101FA00032C4F68432C0F6057A2C9002FF8090028B
+:101FB000FF38F5847A28073800249582FF3C970281
+:101FC000FF409602FF448736141000000001C73816
+:101FD0006000973614108736141800000001073887
+:101FE00000019736141887361418F0056F50F7045F
+:101FF00032B89596FFECC7386000F70532B8F704A1
+:1020000032BCF3062FF807380001F70532BCF7049D
+:1020100032BCF30532D4F7060C3EC07E7400E600F5
+:10202000203400000001C07E7400E600202500007E
+:102030000001F7060C3EC77C7400203A0010E60051
+:10204000268C00000001F70432E4FF820010F584C2
+:102050006F5807380001202E0021E2002090F7057C
+:1020600032E4F7042D38F6862C2806380001F605F0
+:102070002D387739000220320044E6002084B5BABA
+:102080006802F0052D38F3020022E0002094F305E9
+:102090006F58F0056F54F58432C000000001902E97
+:1020A0000004872E000000000001203A0002E60034
+:1020B00021C0000000018702FF38032C0EF49316A4
+:1020C000FFCCF7057A689313FFFC9596FFB8078855
+:1020D0000008E00043A09793FFFC8596FFB82022FC
+:1020E0000000E600217C00000001862E0EF80000B2
+:1020F000000120320010E2002119F302004C872E6B
+:102100000F000000000107380001972E0F00872EF6
+:102110000F00E000217C000000019313FFFCF30698
+:102120007A289313FFFC76B10002C6B460007735BD
+:102130000004C7386A008316FFCCC7386000C73870
+:102140003000073800109713FFFC9596FFB89616DD
+:10215000FFB407880008E00126F89793FFFC861675
+:10216000FFB48596FFB80630000120320011E6006A
+:10217000217800000001F6020000962E0EF8F70408
+:1021800032C0F306E030C03A3200E60021C0000061
+:102190000001F704E0180000000177B8001E703E4F
+:1021A000FFE1E60021C1000000010F814000F704BB
+:1021B00079C80000000107380001F70579C8F70465
+:1021C00079C8F70471C400000001203A0000E6005D
+:1021D00021FDF6862C28F7042D3800000001063872
+:1021E0000001F6052D3877390002F302000A20328B
+:1021F0000044E60021FCB33A6802F0052D38F704EC
+:1022000071D4F68471CC07380001C03A6A00E60048
+:102210002218F70571D4F00571D4F68471D4F7044F
+:1022200071D0F00571C4C0367200470C0001F6840D
+:1022300032D00000000120360000E60025D9F70565
+:1022400071C8F704719800000001203A0000E60010
+:10225000257900000001F70475EC00000001203A28
+:102260000000E600257800000001F70475F000008A
+:102270000001203A0000E600257800000001E0009F
+:1022800025DCF306319CF0057A889002FF38F005D2
+:102290006F509002FF80F70432C4F3063228F30532
+:1022A00032D4F60432C8F6847A2CF50200000738DE
+:1022B0000024F7057A9820320000E60022D5F605C2
+:1022C0007A90C02A5A00E6002620C0326A00EE004A
+:1022D000262100000001F68432C00000000187368C
+:1022E000141000000001C7386000973614108736BC
+:1022F00014180000000107380001973614188736BB
+:102300001418F70432B800000001C7386000F70560
+:1023100032B8F70432BC0000000107380001F705AD
+:1023200032BCF70432BC20320000E6002345000036
+:102330000001F70432E0F5057A7007380001E0008B
+:102340002348F70532E0F5057A70F5846F580000F0
+:102350000001202E0021E200238CF6862C28F704B1
+:102360002D380000000106380001F6052D387739B8
+:10237000000220320044E6002380B5BA6802F0056E
+:102380002D38F3020022E0002390F3056F58F0058A
+:102390006F54F58432C000000001902E0004872E97
+:1023A000000000000001203A0002E60024BC00000A
+:1023B00000018702FF38032C0EF49316FFC4F705C3
+:1023C0007A689313FFFC9596FFB807880008E00031
+:1023D00043A09793FFFC8596FFB820220000E600FB
+:1023E000247800000001862E0EF800000001203243
+:1023F0000010E2002415F302004C872E0F000000AD
+:10240000000107380001972E0F00872E0F00E00013
+:102410002478000000019313FFFCF3067A2893133D
+:10242000FFFC76B10002C6B4600077350004C738FF
+:102430006A008316FFC4C7386000C7383000073809
+:1024400000109713FFFC9596FFB89616FFB4078807
+:102450000008E00126F89793FFFC8616FFB48596E6
+:10246000FFB80630000120320011E600247400009D
+:102470000001F6020000962E0EF8F70432C0F306B3
+:10248000E030C03A3200E60024BC00000001F7044E
+:10249000E0180000000177B8001E703EFFE1E60082
+:1024A00024BD000000010F814000F70479C800003E
+:1024B000000107380001F70579C8F70479C8F70467
+:1024C00071C400000001203A0000E60024F9F686FD
+:1024D0002C28F7042D380000000106380001F6050D
+:1024E0002D3877390002F302000A20320044E6005A
+:1024F00024F8B33A6802F0052D38F70471D4F68455
+:1025000071CC07380001C03A6A00E6002514F705CF
+:1025100071D4F00571D4F68471D4F70471D0F0054C
+:1025200071C4C0367200470C0001F68432D000003E
+:10253000000120360000E60025D9F70571C8F70430
+:10254000719800000001203A0000E60025790000A3
+:102550000001F70475EC00000001203A0000E600DD
+:10256000257800000001F70475F000000001203A12
+:102570000000E60025D100000001F58476F8000097
+:102580000001202E0021E20025C4F6862C28F70445
+:102590002D380000000106380001F6052D38773986
+:1025A000000220320044E60025B0B5BA6802F0050A
+:1025B0002D38F3020022F30576F8F3047700E000EB
+:1025C00025C8F30576FCF00576FCE00025D8F0057B
+:1025D0007A78E00025DCF306319CF3062EE0F30563
+:1025E00032D4F70471C800000001203A0000E60070
+:1025F000268CF6862C28F7042D38000000010638BA
+:102600000001F6052D3877390002F3020009203267
+:102610000044E600268CB33A6802E000268CF00500
+:102620002D38F7047A9000000001C03A6A00EE00ED
+:102630002641C5B40000C7385A00E0002648F70517
+:102640007A90C5B80000F0057A90F6847A88F7068B
+:102650007A2876350003A732700206B40001971677
+:10266000FFEC84A6FFFCF7067A2CF3047A98948298
+:10267000FF3C9302FF409582FF44B5B27002F7041D
+:102680007A98F6857A88C7385800F7057A98879639
+:10269000FFFC8296FFF802140000013C00000000DD
+:1026A00000019293FFFC02900008F7020001F70579
+:1026B0007A78F7063084F70532D4F70432C4000084
+:1026C00000019713FFFC07880008E00006109793AD
+:1026D000FFFC8796FFFC8296FFF802140000013C85
+:1026E0000000000000019293FFFC029000082210FD
+:1026F0000050F70432D0F3020000203A0000E60058
+:102700002A719316FFE4F68432C48616FFE48736F6
+:102710000008C3040000C03A3200E600273C203223
+:1027200000008736000C00000001C03A3200E600CD
+:10273000273C20320000F602000120320000E600B3
+:102740002A70F3020000F70432C09316FFACF58440
+:1027500032C4863A142803B81420042C000886BA20
+:10276000142400000001C0326A00EC0028289616EC
+:10277000FFEC77310001C738600077390002C638B6
+:1027800038000630000C86B20000872E000885163F
+:10279000FFACC0367200E60027B8C484000086B2E1
+:1027A0000004872E000C00000001C0367200E60015
+:1027B00027BC202A0000F5020001202A0000E600C4
+:1027C00027C900000001F482000086B200008722C1
+:1027D000000000000001C0367200E2002804F5820B
+:1027E0000000C0367200E600280C202E000086B2E1
+:1027F00000048722000400000001C0367200E200DD
+:10280000280D202E0000F5820001202E0000E60099
+:10281000281D20260000F482000120260000E6008A
+:102820002828F30200019316FFAC8316FFAC0000CA
+:102830000001201A0000E6002869F6020001871650
+:10284000FFEC0000000176B90001C6B4700076B557
+:102850000002C6B4380006B4001486B6000097160D
+:10286000FFF0E00028D09696FFF427140014971389
+:10287000FFFC9413FFFC9393FFFC9396FFBC078827
+:102880000008E00125689793FFFC8396FFBC202297
+:102890000000E60028CDF60200018716FFEC0000DC
+:1028A000000176B90001C6B4700076B50002C6B466
+:1028B000380006B4001486B600009716FFF096960E
+:1028C000FFF4971E0008E00028D420320000F60232
+:1028D000000020320000E6002A70F3020000F60437
+:1028E00032C09316FFAC86B2142803B01420043013
+:1028F000148C8732142400000001C0367200EC00F2
+:1029000029BC9696FFEC77350001C7386800773907
+:102910000002C5B8380005AC000C86AE0000873256
+:10292000148C8516FFACC0367200E600294CC484B6
+:10293000000086AE00048732149000000001C0360B
+:102940007200E6002950202A0000F5020001202A2A
+:102950000000E600295D00000001F482000086AE60
+:1029600000008722000000000001C0367200E20073
+:102970002998F6020000C0367200E60029A0203235
+:10298000000086AE00048722000400000001C0366B
+:102990007200E20029A120320000F602000120327C
+:1029A0000000E60029B120260000F4820001202664
+:1029B0000000E60029BCF30200019316FFAC831669
+:1029C000FFAC00000001201A0000E60029FDF6021D
+:1029D00000018716FFEC0000000176B90001C6B4C3
+:1029E000700076B50002C6B4380006B4001486B68E
+:1029F00000009716FFF0E0002A649696FFF4271473
+:102A000000149713FFFC9413FFFC9393FFFC939621
+:102A1000FFBC07880008E00125689793FFFC8396B8
+:102A2000FFBC20220000E6002A61F60200018716A2
+:102A3000FFEC0000000176B90001C6B4700076B565
+:102A40000002C6B4380006B4001486B6000097161B
+:102A5000FFF09696FFF4971E0008E0002A682032E7
+:102A60000000F602000020320000E6002BCDF30249
+:102A70000001F68432C00000000185B60EF48636EF
+:102A80000EF8202E0010E2002A9420320010E200FE
+:102A90002AB10000000187360F000000000107384E
+:102AA000000197360F0087360F00E0002ADCF7029E
+:102AB000000007300001C03A5A00E6002AD5F6822D
+:102AC000000020320010E6002AD8202E0000E60088
+:102AD0002ADCC7340000F6820001C7340000203A27
+:102AE0000000E6002BCCF3020001F30432CC00001E
+:102AF00000019316FFDC9313FFFC07880008E00039
+:102B000043689793FFFC20220000E6002BB4F302F9
+:102B100000008316FFDC00000001861A00000000A0
+:102B2000000120320010E2002B4976B10002871A22
+:102B3000000C0000000107380001971A000C871AEA
+:102B4000000CE0002BB4F3020000F302004C9313DE
+:102B5000FFFCC6B4600077350004C7386A008316EE
+:102B6000FFDCC7386000C738300007380010971303
+:102B7000FFFCF3067A289313FFFC9616FFB4078830
+:102B80000008E00126F89793FFFC8616FFB40000CA
+:102B900000010630000120320011E6002BA40000E5
+:102BA0000001F60200008316FFDC00000001961A07
+:102BB0000000F30200019316FFD48316FFD4000037
+:102BC0000001201A0000E6002BD0F302000193164A
+:102BD000FFE48316FFE400000001201A0000E60075
+:102BE0002CEDF6820CABF70432B48316FFD4073811
+:102BF0000001F70532B4F70432B4201A0000E600F1
+:102C00002C2800000001F70432C0F306E030C03A7F
+:102C10003200E6002C2800000001F70432E8000032
+:102C2000000107380001F70532E8F70471C400001D
+:102C30000001203A0000E6002C65F6862C28F704F7
+:102C40002D380000000106380001F6052D387739CF
+:102C50000002F302000A20320044E6002C64B33A7A
+:102C60006802F0052D38F70471D4F68471CC07386A
+:102C70000001C03A6A00E6002C80F70571D4F00527
+:102C800071D4F68471D4F70471D0F00571C4C036E4
+:102C90007200470C0001F68432D00000000120369B
+:102CA0000000E6003391F70571C8F7047198000041
+:102CB0000001203A0000E600333100000001F70473
+:102CC00075EC00000001203A0000E60033300000FF
+:102CD0000001F70475F000000001203A0000E60052
+:102CE000333000000001E0003394F306319CF0051E
+:102CF00032E8F70432C0F6046F5496BA000420326A
+:102D00000000E6002D18F302000CF3020001F305A9
+:102D10006F54E0002D20F7020001F3056F58F70211
+:102D20000000203A0000E6002D34F3062F6CE0008E
+:102D30003444F30532D4F5847A7024940010202EA4
+:102D40000001E600303CF5857AA0F7020001F604A8
+:102D500032C8F7057A70F70432C4F68432C0F6053B
+:102D60007A2C9002FF809002FF38F5847A28073889
+:102D700000249582FF3C9702FF409602FF4487366D
+:102D8000141000000001C738600097361410873611
+:102D90001418000000010738000197361418873610
+:102DA0001418F0056F50F70432B89596FFECC73849
+:102DB0006000F70532B8F70432BCF3062FF8073885
+:102DC0000001F70532BCF70432BCF30532D4F70634
+:102DD0000C3EC07E7400E6002DEC00000001C07EB9
+:102DE0007400E6002DDD00000001F7060C3EC77CF4
+:102DF0007400203A0010E600344400000001F7049B
+:102E000032E4FF820010F5846F5807380001202E4D
+:102E10000021E2002E48F70532E4F7042D38F6864B
+:102E20002C2806380001F6052D38773900022032AB
+:102E30000044E6002E3CB5BA6802F0052D38F302D6
+:102E40000022E0002E4CF3056F58F0056F54F58416
+:102E500032C000000001902E0004872E0000000008
+:102E60000001203A0002E6002F78000000018702EE
+:102E7000FF38032C0EF49316FFCCF7057A689313F2
+:102E8000FFFC9596FFB807880008E00043A09793E1
+:102E9000FFFC8596FFB820220000E6002F340000DA
+:102EA0000001862E0EF80000000120320010E20022
+:102EB0002ED1F302004C872E0F00000000010738CE
+:102EC0000001972E0F00872E0F00E0002F34000026
+:102ED00000019313FFFCF3067A289313FFFC76B1ED
+:102EE0000002C6B4600077350004C7386A00831654
+:102EF000FFCCC7386000C738300007380010971380
+:102F0000FFFC9596FFB89616FFB407880008E0010D
+:102F100026F89793FFFC8616FFB48596FFB8063017
+:102F2000000120320011E6002F3000000001F602FF
+:102F30000000962E0EF8F70432C0F306E030C03AD7
+:102F40003200E6002F7800000001F704E0180000CE
+:102F5000000177B8001E703EFFE1E6002F79000007
+:102F600000010F814000F70479C800000001073814
+:102F70000001F70579C8F70479C8F70471C40000A7
+:102F80000001203A0000E6002FB5F6862C28F70451
+:102F90002D380000000106380001F6052D3877397C
+:102FA0000002F302000A20320044E6002FB4B33AD4
+:102FB0006802F0052D38F70471D4F68471CC073817
+:102FC0000001C03A6A00E6002FD0F70571D4F00581
+:102FD00071D4F68471D4F70471D0F00571C4C03691
+:102FE0007200470C0001F68432D000000001203648
+:102FF0000000E6003391F70571C8F70471980000EE
+:103000000001203A0000E600333100000001F7041F
+:1030100075EC00000001203A0000E60033300000AB
+:103020000001F70475F000000001203A0000E600FE
+:10303000333000000001E0003394F306319CF005CA
+:103040007A889002FF38F0056F509002FF80F704F5
+:1030500032C4F3063228F30532D4F60432C8F684BB
+:103060007A2CF502000007380024F7057A98203200
+:103070000000E600308DF6057A90C02A5A00E6007E
+:1030800033D8C0326A00EE0033D900000001F68464
+:1030900032C0000000018736141000000001C7385C
+:1030A00060009736141087361418000000010738A6
+:1030B00000019736141887361418F70432B8000048
+:1030C0000001C7386000F70532B8F70432BC0000D1
+:1030D000000107380001F70532BCF70432BC20328A
+:1030E0000000E60030FD00000001F70432E0F505C5
+:1030F0007A7007380001E0003100F70532E0F5058D
+:103100007A70F5846F5800000001202E0021E20043
+:103110003144F6862C28F7042D38000000010638CB
+:103120000001F6052D387739000220320044E60010
+:103130003138B5BA6802F0052D38F3020022E000FC
+:103140003148F3056F58F0056F54F58432C0000024
+:103150000001902E0004872E000000000001203A9C
+:103160000002E6003274000000018702FF38032CE1
+:103170000EF49316FFC4F7057A689313FFFC959637
+:10318000FFB807880008E00043A09793FFFC8596EE
+:10319000FFB820220000E600323000000001862E39
+:1031A0000EF80000000120320010E20031CDF302E1
+:1031B000004C872E0F000000000107380001972EF9
+:1031C0000F00872E0F00E000323000000001931343
+:1031D000FFFCF3067A289313FFFC76B10002C6B415
+:1031E000600077350004C7386A008316FFC4C7380B
+:1031F0006000C7383000073800109713FFFC959621
+:10320000FFB89616FFB407880008E00126F89793E8
+:10321000FFFC8616FFB48596FFB806300001203209
+:103220000011E600322C00000001F6020000962E8C
+:103230000EF8F70432C0F306E030C03A3200E60080
+:10324000327400000001F704E0180000000177B8B4
+:10325000001E703EFFE1E6003275000000010F81A4
+:103260004000F70479C80000000107380001F705A5
+:1032700079C8F70479C8F70471C400000001203A46
+:103280000000E60032B1F6862C28F7042D38000045
+:10329000000106380001F6052D3877390002F302E7
+:1032A000000A20320044E60032B0B33A6802F0056A
+:1032B0002D38F70471D4F68471CC07380001C03A78
+:1032C0006A00E60032CCF70571D4F00571D4F684BB
+:1032D00071D4F70471D0F00571C4C0367200470C88
+:1032E0000001F68432D00000000120360000E60024
+:1032F0003391F70571C8F704719800000001203A76
+:103300000000E600333100000001F70475EC000016
+:103310000001203A0000E600333000000001F7040D
+:1033200075F000000001203A0000E600338900003B
+:103330000001F58476F800000001202E0021E20053
+:10334000337CF6862C28F7042D380000000106385F
+:103350000001F6052D387739000220320044E600DE
+:103360003368B5BA6802F0052D38F3020022F30580
+:1033700076F8F3047700E0003380F30576FCF0057F
+:1033800076FCE0003390F0057A78E0003394F306A1
+:10339000319CF3062EE0F30532D4F70471C8000027
+:1033A0000001203A0000E6003444F6862C28F70499
+:1033B0002D380000000106380001F6052D38773958
+:1033C0000002F302000920320044E6003444B33A1C
+:1033D0006802E0003444F0052D38F7047A900000CC
+:1033E0000001C03A6A00EE0033F9C5B40000C738E6
+:1033F0005A00E0003400F7057A90C5B80000F005E7
+:103400007A90F6847A88F7067A2876350003A73210
+:10341000700206B400019716FFEC84A6FFFCF706C5
+:103420007A2CF3047A989482FF3C9302FF409582B1
+:10343000FF44B5B27002F7047A98F6857A88C738E7
+:103440005800F7057A988796FFFC8296FFF80214D9
+:103450000000013C0000000000019293FFFC02907C
+:10346000000822100020F5847A7000000001202E50
+:103470000001E600376CF5857AA0F7020001F6043A
+:1034800032C8F7057A70F70432C4F68432C0F60504
+:103490007A2C9002FF809002FF38F5847A28073852
+:1034A00000249582FF3C9702FF409602FF44873636
+:1034B000141000000001C7386000973614108736DA
+:1034C00014180000000107380001973614188736D9
+:1034D0001418F0056F50F70432B89596FFF4C7380A
+:1034E0006000F70532B8F70432BCF4862FF80738CD
+:1034F0000001F70532BCF70432BCF48532D4F7067C
+:103500000C3EC07E7400E600351C00000001C07E49
+:103510007400E600350D00000001F7060C3EC77C84
+:103520007400203A0010E6003B7000000001F70430
+:1035300032E4FF820010F5846F5807380001202E16
+:103540000021E2003578F70532E4F7042D38F686DD
+:103550002C2806380001F6052D3877390002203274
+:103560000044E600356CB5BA6802F0052D38F482E7
+:103570000022E000357CF4856F58F0056F54F58427
+:1035800032C000000001902E0004872E00000000D1
+:103590000001203A0002E60036A800000001870280
+:1035A000FF3804AC0EF49496FFECF7057A68949318
+:1035B000FFFC9596FFDC07880008E00043A0979386
+:1035C000FFFC8596FFDC20220000E6003664000048
+:1035D0000001862E0EF80000000120320010E200EB
+:1035E0003601F482004C872E0F00000000010738DE
+:1035F0000001972E0F00872E0F00E00036640000B8
+:1036000000019493FFFCF4867A289493FFFC76B132
+:103610000002C6B4600077350004C7386A0084969B
+:10362000FFECC7386000C738480007380010971310
+:10363000FFFC9596FFDC9616FFD807880008E0018E
+:1036400026F89793FFFC8616FFD88596FFDC063098
+:10365000000120320011E600366000000001F60291
+:103660000000962E0EF8F70432C0F486E030C03A1F
+:103670004A00E60036A800000001F704E018000048
+:10368000000177B8001E703EFFE1E60036A9000099
+:1036900000010F814000F70479C8000000010738DD
+:1036A0000001F70579C8F70479C8F70471C4000070
+:1036B0000001203A0000E60036E5F6862C28F704E3
+:1036C0002D380000000106380001F6052D38773945
+:1036D0000002F482000A20320044E60036E4B4BA64
+:1036E0006802F0052D38F70471D4F68471CC0738E0
+:1036F0000001C03A6A00E6003700F70571D4F00512
+:1037000071D4F68471D4F70471D0F00571C4C03659
+:103710007200470C0001F68432D000000001203610
+:103720000000E6003AC1F70571C8F704719800007F
+:103730000001203A0000E6003A6100000001F704B1
+:1037400075EC00000001203A0000E6003A6000003D
+:103750000001F70475F000000001203A0000E600C7
+:103760003A6000000001E0003AC4F486319CF005A4
+:103770007A889002FF38F0056F509002FF80F704BE
+:1037800032C4F4863228F48532D4F60432C8F68482
+:103790007A2CF502000007380024F7057A982032C9
+:1037A0000000E60037BDF6057A90C02A5A00E60010
+:1037B0003B08C0326A00EE003B0900000001F684BD
+:1037C00032C0000000018736141000000001C73825
+:1037D000600097361410873614180000000107386F
+:1037E00000019736141887361418F70432B8000011
+:1037F0000001C7386000F70532B8F70432BC00009A
+:10380000000107380001F70532BCF70432BC203252
+:103810000000E600382D00000001F70432E0F50555
+:103820007A7007380001E0003830F70532E0F5051E
+:103830007A70F5846F5800000001202E0021E2000C
+:103840003874F6862C28F7042D380000000106385D
+:103850000001F6052D387739000220320044E600D9
+:103860003868B5BA6802F0052D38F4820022E0000D
+:103870003878F4856F58F0056F54F58432C0000035
+:103880000001902E0004872E000000000001203A65
+:103890000002E60039A4000000018702FF3804ACF2
+:1038A0000EF49496FFE4F7057A689493FFFC9596DE
+:1038B000FFDC07880008E00043A09793FFFC859693
+:1038C000FFDC20220000E600396000000001862EA7
+:1038D0000EF80000000120320010E20038FDF482F2
+:1038E000004C872E0F000000000107380001972EC2
+:1038F0000F00872E0F00E000396000000001949354
+:10390000FFFCF4867A289493FFFC76B10002C6B4DB
+:10391000600077350004C7386A008496FFE4C73832
+:103920006000C7384800073800109713FFFC9596D1
+:10393000FFDC9616FFD807880008E00126F8979369
+:10394000FFFC8616FFD88596FFDC0630000120328A
+:103950000011E600395C00000001F6020000962E1E
+:103960000EF8F70432C0F486E030C03A4A00E600B0
+:1039700039A400000001F704E0180000000177B846
+:10398000001E703EFFE1E60039A5000000010F8136
+:103990004000F70479C80000000107380001F7056E
+:1039A00079C8F70479C8F70471C400000001203A0F
+:1039B0000000E60039E1F6862C28F7042D380000D7
+:1039C000000106380001F6052D3877390002F4822F
+:1039D000000A20320044E60039E0B4BA6802F0057B
+:1039E0002D38F70471D4F68471CC07380001C03A41
+:1039F0006A00E60039FCF70571D4F00571D4F6844D
+:103A000071D4F70471D0F00571C4C0367200470C50
+:103A10000001F68432D00000000120360000E600EC
+:103A20003AC1F70571C8F704719800000001203A07
+:103A30000000E6003A6100000001F70475EC0000A8
+:103A40000001203A0000E6003A6000000001F7049F
+:103A500075F000000001203A0000E6003AB90000CD
+:103A60000001F58476F800000001202E0021E2001C
+:103A70003AACF6862C28F7042D38000000010638F1
+:103A80000001F6052D387739000220320044E600A7
+:103A90003A98B5BA6802F0052D38F4820022F48510
+:103AA00076F8F4847700E0003AB0F48576FCF0050F
+:103AB00076FCE0003AC0F0057A78E0003AC4F4867B
+:103AC000319CF4862EE0F48532D4F70471C80000EE
+:103AD0000001203A0000E6003B70F6862C28F7042F
+:103AE0002D380000000106380001F6052D38773921
+:103AF0000002F482000920320044E6003B70B4BAB0
+:103B00006802E0003B70F0052D38F7047A90000061
+:103B10000001C03A6A00EE003B29C5B40000C73876
+:103B20005A00E0003B30F7057A90C5B80000F00578
+:103B30007A90F7047A88F6867A2876390003A6B256
+:103B4000680207380001F7057A88F7047A98969694
+:103B5000FFF49682FF3CF4847A98F6867A2CC73874
+:103B600058009482FF409582FF44B5B26802F70581
+:103B70007A988796FFFC8296FFF802140000013CB9
+:103B80000000000000019293FFFC02900008221048
+:103B90000018F5047A88F7067A2CF5847A9076A9CD
+:103BA0000003A6B67002202E0000E6003BCD000008
+:103BB0000001F7047AA000000001C02A7200E600AC
+:103BC0003F18C02E6A00EE003F1900000001F68485
+:103BD00032C0F60432C88736141000000001C7381E
+:103BE000600097361410873614180000000107385B
+:103BF00000019736141887361418F70432B80000FD
+:103C00000001C7386000F70532B8F70432BC000085
+:103C1000000107380001F70532BCF70432BC202E42
+:103C20000000E6003C3DF6820000F70432E0F68535
+:103C30007A7007380001E0003C40F70532E0F505F6
+:103C40007A70F5846F5800000001202E0021E200F8
+:103C50003C84F6862C28F7042D3800000001063835
+:103C60000001F6052D387739000220320044E600C5
+:103C70003C78B5BA6802F0052D38F4820022E000E5
+:103C80003C88F4856F58F0056F54F58432C000000D
+:103C90000001902E0004872E000000000001203A51
+:103CA0000002E6003DB4000000018702FF3804ACCA
+:103CB0000EF49496FFECF7057A689493FFFC9596C2
+:103CC000FFE407880008E00043A09793FFFC859677
+:103CD000FFE420220000E6003D7000000001862E77
+:103CE0000EF80000000120320010E2003D0DF482C9
+:103CF000004C872E0F000000000107380001972EAE
+:103D00000F00872E0F00E0003D700000000194932B
+:103D1000FFFCF4867A289493FFFC76B10002C6B4C7
+:103D2000600077350004C7386A008496FFECC73816
+:103D30006000C7384800073800109713FFFC9596BD
+:103D4000FFE49616FFE007880008E00126F8979345
+:103D5000FFFC8616FFE08596FFE406300001203266
+:103D60000011E6003D6C00000001F6020000962EF6
+:103D70000EF8F70432C0F486E030C03A4A00E6009C
+:103D80003DB400000001F704E0180000000177B81E
+:103D9000001E703EFFE1E6003DB5000000010F810E
+:103DA0004000F70479C80000000107380001F7055A
+:103DB00079C8F70479C8F70471C400000001203AFB
+:103DC0000000E6003DF1F6862C28F7042D380000AF
+:103DD000000106380001F6052D3877390002F4821B
+:103DE000000A20320044E6003DF0B4BA6802F00553
+:103DF0002D38F70471D4F68471CC07380001C03A2D
+:103E00006A00E6003E0CF70571D4F00571D4F68423
+:103E100071D4F70471D0F00571C4C0367200470C3C
+:103E20000001F68432D00000000120360000E600D8
+:103E30003ED1F70571C8F704719800000001203ADF
+:103E40000000E6003E7100000001F70475EC000080
+:103E50000001203A0000E6003E7000000001F70477
+:103E600075F000000001203A0000E6003EC90000A5
+:103E70000001F58476F800000001202E0021E20008
+:103E80003EBCF6862C28F7042D38000000010638C9
+:103E90000001F6052D387739000220320044E60093
+:103EA0003EA8B5BA6802F0052D38F4820022F485E8
+:103EB00076F8F4847700E0003EC0F48576FCF005E7
+:103EC00076FCE0003ED0F0057A78E0003ED4F4863F
+:103ED000319CF4862EE0F48532D4F70471C80000DA
+:103EE0000001203A0000E6003F80F6862C28F70407
+:103EF0002D380000000106380001F6052D3877390D
+:103F00000002F482000920320044E6003F80B4BA87
+:103F10006802E0003F80F0052D38F7047A90000039
+:103F20000001C03A6A00EE003F39C5B40000C7384E
+:103F30005A00E0003F40F7057A90C5B80000F00550
+:103F40007A90F7047A88F6867A2876390003A6B242
+:103F5000680207380001F7057A88F7047A98969680
+:103F6000FFF49682FF3CF4847A98F6867A2CC73860
+:103F700058009482FF409582FF44B5B26802F7056D
+:103F80007A988796FFFC8296FFF802140000013CA5
+:103F90000000000000019293FFFC02900008221034
+:103FA0000010F5846F5800000001202E0021E2006F
+:103FB0003FE4F6862C28F7042D380000000106386F
+:103FC0000001F6052D387739000220320044E60062
+:103FD0003FD8B5BA6802F0052D38F5020022E0009E
+:103FE0003FE8F5056F58F0056F54F58432C00000C6
+:103FF0000001902E0004872E000000000001203AEE
+:104000000002E6004114000000018702FF38052C81
+:104010000EF49516FFF4F7057A689513FFFC959654
+:10402000FFEC07880008E00043A09793FFFC85960B
+:10403000FFEC20220000E60040D000000001862EA8
+:104040000EF80000000120320010E200406DF50281
+:10405000004C872E0F000000000107380001972E4A
+:104060000F00872E0F00E00040D0000000019513E4
+:10407000FFFCF5067A289513FFFC76B10002C6B462
+:10408000600077350004C7386A008516FFF4C7382A
+:104090006000C7385000073800109713FFFC959652
+:1040A000FFEC9616FFE807880008E00126F89793D2
+:1040B000FFFC8616FFE88596FFEC063000012032F3
+:1040C0000011E60040CC00000001F6020000962E30
+:1040D0000EF8F70432C0F506E030C03A5200E600B0
+:1040E000411400000001F704E0180000000177B857
+:1040F000001E703EFFE1E6004115000000010F8147
+:104100004000F70479C80000000107380001F705F6
+:1041100079C8F70479C8F70471C400000001203A97
+:104120000000E6004151F6862C28F7042D380000E7
+:10413000000106380001F6052D3877390002F50236
+:10414000000A20320044E6004150B53A6802F0050A
+:104150002D38F70471D4F68471CC07380001C03AC9
+:104160006A00E600416CF70571D4F00571D4F6845D
+:1041700071D4F70471D0F00571C4C0367200470CD9
+:104180000001F68432D00000000120360000E60075
+:104190004231F70571C8F704719800000001203A18
+:1041A0000000E60041D100000001F70475EC0000BA
+:1041B0000001203A0000E60041D000000001F704B1
+:1041C00075F000000001203A0000E60042290000DE
+:1041D0000001F58476F800000001202E0021E200A5
+:1041E000421CF6862C28F7042D3800000001063802
+:1041F0000001F6052D387739000220320044E60030
+:104200004208B5BA6802F0052D38F5020022F5051E
+:1042100076F8F5047700E0004220F50576FCF0051D
+:1042200076FCE0004230F0057A78E0004234F50692
+:10423000319CF5062EE0F50532D4F70471C8000074
+:104240000001203A0000E6004274F6862C28F704AC
+:104250002D380000000106380001F6052D387739A9
+:104260000002F502000920320044E6004274B53A2B
+:104270006802F0052D388796FFFC8296FFF802143D
+:104280000000013C0000000000019293FFFC02903E
+:104290000008F70632D49713FFFCF7062EE09713B9
+:1042A000FFFC07880008E00014F49793FFFCF70672
+:1042B00032D49713FFFCF7062F6C9713FFFC078887
+:1042C0000008E00014F49793FFFCF70632D497132C
+:1042D000FFFCF7062FF89713FFFC07880008E000A3
+:1042E00014F49793FFFCF70632D49713FFFCF706FC
+:1042F00030849713FFFC07880008E00014F49793BC
+:10430000FFFCF70632D49713FFFCF7063110971322
+:10431000FFFC07880008E00014F49793FFFCF70601
+:1043200032D49713FFFCF706319C9713FFFC0788E4
+:104330000008E00014F49793FFFCF70632D49713BB
+:10434000FFFCF70632289713FFFC07880008E000FF
+:1043500014F49793FFFC8796FFFC8296FFF80214F3
+:104360000000013C0000000000019293FFFC02905D
+:104370000008871600000000000186BA0000873A96
+:10438000000400000001C0367200440C0001879652
+:10439000FFFC8296FFF802140004013C00000000BC
+:1043A00000019293FFFC0290000885960000000037
+:1043B0000001862E000086AE000420320010E200CC
+:1043C00043D00000000120360010E20043ED073426
+:1043D0000001872E000C0000000107380001972E15
+:1043E000000C872E000CE0004414F4020000C03AD8
+:1043F0006200E6004411F402000020360010E600DE
+:1044000044140000000120320000E60044140000C3
+:104410000001F40200018796FFFC8296FFF8021467
+:104420000004013C0000000000019293FFFC029098
+:104430000008F7020001F7053524F7046F44000077
+:104440000001F7053528F70632F49713FFFCF7064D
+:1044500035309713FFFC07880008E0001548979354
+:10446000FFFCF70245049713FFFCF702000D9713BA
+:10447000FFFCF70632F49713FFFC07880008E00002
+:10448000161C9793FFFCF7024A049713FFFCF702F0
+:10449000000F9713FFFCF70633809713FFFC078884
+:1044A0000008E000161C9793FFFCF7024EEC9713F0
+:1044B000FFFCF70200089713FFFCF706340C971374
+:1044C000FFFC07880008E000161C9793FFFCF7022A
+:1044D00057649713FFFCF70200079713FFFCF706DA
+:1044E00034989713FFFC07880008E000161C979388
+:1044F000FFFC8796FFFC8296FFF802140000013C47
+:104500000000000000019293FFFC029000082210BE
+:104510000014F70475F800000001203A0000E600DE
+:10452000452DF68675F8E0004544F7020000F704D3
+:1045300076040000000177390002C7386800873A26
+:10454000001800000001203A0000E600455CF70575
+:104550003548F4863380E00049F0F4853530F704BF
+:104560006F5400000001203A0000E6004580F4820C
+:104570000008F4820001F4856F54E0004588F702DA
+:104580000001F4856F58F7020000203A0000E600B1
+:1045900045A0F4820004F486340CE00049F0F48570
+:1045A0003530F6843548F604352CF4B72800073446
+:1045B0000002F4820001F4BB28008732008CF482F0
+:1045C00000019736001887320090F4856F509736B7
+:1045D000000484B200840000000194B6001084B28C
+:1045E00000880000000194B6001484B6001000009A
+:1045F000000194B6000884B600140000000194B6CF
+:10460000000C84B2009800000001F4853554F48257
+:1046100000019482FF80F5043554F4863498F485C3
+:1046200035309502FF3885B2000006B4002495822B
+:10463000FF3C9682FF4087320004F6853550970292
+:10464000FF4486B20004F005354CF704354095165A
+:10465000FFF49596FFF4C7386800F7053540F584F8
+:10466000352886B20004872E141400000001C738D4
+:104670006800972E14148732008000000001203A51
+:104680000001EE0049F0F7060C3EC07E7400E60023
+:1046900046A400000001C07E7400E60046950000BC
+:1046A0000001F7060C3EC77C7400203A0010E600BB
+:1046B00049F000000001FF8200108682FF38F704F5
+:1046C0003558F5846F58F685355407380001202E8B
+:1046D0000021E2004708F7053558F7042D38F68623
+:1046E0002C2806380001F6052D38773900022032D3
+:1046F0000044E60046FCB5BA6802F0052D38F482A5
+:104700000022E000470CF4856F58F0056F54F684E2
+:10471000352C0000000187360094C4840000C03AA4
+:104720004A00E60047710000000186360094F684D6
+:1047300035540000000176B4FFF0F7043554969626
+:10474000FFF4473900009716FFF0C6B47000F70475
+:10475000354877B4000F703EFFE107380024E600CB
+:104760004769C638600006B40001C7046E00F7331D
+:104770002800F6843544000000018736000400005C
+:104780000001203A000FE20047BD073800018736DC
+:10479000000C00000001073800019736000C873636
+:1047A000000CE00047D000000001F7043528F68235
+:1047B000000107380008E0004968F7053544203A51
+:1047C0000010E60047CC00000001F7020000973619
+:1047D0000004F704353CF684352807380001F70556
+:1047E000353CF704353C8736141C000000010738BF
+:1047F00000019736141CF704760486B6141CF604E0
+:1048000075FC07380001F684760000000001C03A0C
+:104810006A00E600481CF7057604F0057604F68485
+:104820007604F7047608F00575FCC0367200470C74
+:10483000000120320000E6004881F70575F8F70412
+:104840007648F4867218C03A4A00470C0001203AB4
+:104850000000E6004881F6862C28F7042D38000079
+:10486000000106380001F6052D3877390002F48280
+:10487000000E20320044E6004880B4BA6802F00519
+:104880002D38F5020000202A0002EE004968F68269
+:104890000000F68435280000000187360000000083
+:1048A0000001203A0002E600493C05B40008959357
+:1048B000FFFC9516FFEC9596FFE89696FFE40788B7
+:1048C0000008E0005EDC9793FFFC8516FFEC859600
+:1048D000FFE88696FFE420220000E600492CF7025C
+:1048E00000008636000C000000012032000FE200BC
+:1048F000491100000001873600140000000107384C
+:1049000000019736001487360014E000492CF702A6
+:10491000000076B10002C6B4600077350005C738E4
+:104920006A00C738600007380010C72C7000203AB2
+:104930000000E60047A8F705352CF6843528F70473
+:104940006F4C00000001C0367200E600495C07347D
+:104950001494F4846F44E0004960F4853528F70529
+:104960003528E00048840528000120360000E600D4
+:1049700049A1F6862C28F7042D38000000010638DE
+:104980000001F6052D3877390002F482000D20323F
+:104990000044E60049A8B4BA6802E00049A8F0055E
+:1049A0002D38F4820001F4853524F6843528F70487
+:1049B0006F44F48632F4C0367200E60049F0F485A4
+:1049C0003530F704E0180000000177B8001F703E92
+:1049D000FFE1E60049F1000000010F814000F7040B
+:1049E00079C80000000107380001F70579C8F7040D
+:1049F00079C88796FFFC8296FFF802140000013CFC
+:104A00000000000000019293FFFC029000082210B9
+:104A10000014F70475F800000001203A0000E600D9
+:104A20004A2DF68675F8E0004A40F6820000F70449
+:104A300076040000000177390002C738680086BAA2
+:104A40000018F7046F5400000001203A0000E6004F
+:104A50004A64F6853548F4820001F4856F54E0001D
+:104A60004A70F7020001F4820008F4856F58F702DB
+:104A70000000203A0000E6004A88F4820004F48630
+:104A8000340CE0004ED8F4853530F6843548F60411
+:104A9000352CF4B7280007340002F4820001F4BB7F
+:104AA00028008732008CF482000197360018873284
+:104AB0000090F4856F509736000484B200840000A3
+:104AC000000194B6001084B200880000000194B682
+:104AD000001484B600100000000194B6000884B6EB
+:104AE00000140000000194B6000C84B2009800008D
+:104AF0000001F4853554F48200019482FF80F504AE
+:104B00003554F4863498F48535309502FF3885B2F3
+:104B1000000006B400249582FF3C9682FF40873255
+:104B20000004F68535509702FF4486B20004F00574
+:104B3000354CF70435409516FFF49596FFF4C738C9
+:104B40006800F7053540F584352886B20004872EC5
+:104B5000141400000001C7386800972E141487321F
+:104B6000008000000001203A0001EE004ED8F70658
+:104B70000C3EC07E7400E6004B8C00000001C07E3D
+:104B80007400E6004B7D00000001F7060C3EC77C78
+:104B90007400203A0010E6004ED800000001FF82A9
+:104BA00000108682FF38F7043558F5846F58F68573
+:104BB000355407380001202E0021E2004BF0F705A4
+:104BC0003558F7042D38F6862C2806380001F605EE
+:104BD0002D387739000220320044E6004BE4B5BAA4
+:104BE0006802F0052D38F4820022E0004BF4F485D1
+:104BF0006F58F0056F54F684352C0000000187369D
+:104C00000094C4840000C03A4A00E6004C590000F9
+:104C1000000186360094F68435540000000176B415
+:104C2000FFF0F70435549696FFF4473900009716C5
+:104C3000FFF0C6B47000F704354877B4000F703E3B
+:104C4000FFE107380024E6004C51C638600006B486
+:104C50000001C7046E00F7332800F68435440000D5
+:104C600000018736000400000001203A000FE20036
+:104C70004CA5073800018736000C000000010738FA
+:104C800000019736000C8736000CE0004CB800009D
+:104C90000001F7043528F682000107380008E0001B
+:104CA0004E50F7053544203A0010E6004CB40000A1
+:104CB0000001F702000097360004F704353CF68443
+:104CC000352807380001F705353CF704353C8736B1
+:104CD000141C00000001073800019736141CF7046B
+:104CE000760486B6141CF60475FC07380001F684B9
+:104CF000760000000001C03A6A00E6004D04F705A6
+:104D00007604F0057604F6847604F7047608F00558
+:104D100075FCC0367200470C000120320000E6002E
+:104D20004D69F70575F8F7047648F4867218C03AAD
+:104D30004A00470C0001203A0000E6004D69F68663
+:104D40002C28F7042D380000000106380001F60574
+:104D50002D3877390002F482000E20320044E6003C
+:104D60004D68B4BA6802F0052D38F5020000202A1B
+:104D70000002EE004E50F6820000F6843528000056
+:104D800000018736000000000001203A0002E60022
+:104D90004E2405B400089593FFFC9516FFEC9596FC
+:104DA000FFE89696FFE407880008E0005EDC979332
+:104DB000FFFC8516FFEC8596FFE88696FFE420222F
+:104DC0000000E6004E14F70200008636000C0000DA
+:104DD00000012032000FE2004DF90000000187368B
+:104DE00000140000000107380001973600148736D0
+:104DF0000014E0004E14F702000076B10002C6B4C1
+:104E0000600077350005C7386A00C738600007388A
+:104E10000010C72C7000203A0000E6004C90F70507
+:104E2000352CF6843528F7046F4C00000001C0369D
+:104E30007200E6004E4407341494F4846F44E0009A
+:104E40004E48F4853528F7053528E0004D6C0528D7
+:104E5000000120360000E6004E89F6862C28F70473
+:104E60002D380000000106380001F6052D3877398D
+:104E70000002F482000D20320044E6004E90B4BAE5
+:104E80006802E0004E90F0052D38F4820001F485B0
+:104E90003524F6843528F7046F44F48632F4C0369E
+:104EA0007200E6004ED8F4853530F704E0180000B3
+:104EB000000177B8001F703EFFE1E6004ED9000008
+:104EC00000010F814000F70479C800000001073895
+:104ED0000001F70579C8F70479C88796FFFC829628
+:104EE000FFF802140000013C000000000001929352
+:104EF000FFFC0290000822100014F6843548F604E6
+:104F0000352CF4820004F4B7280007340002F48240
+:104F10000001F4BB28008732008CF4820001973630
+:104F2000001887320090F4856F509736000484B2E1
+:104F300000840000000194B6001084B200880000D4
+:104F4000000194B6001484B600100000000194B66D
+:104F5000000884B600140000000194B6000C84B26E
+:104F6000009800000001F4853554F4820001948219
+:104F7000FF80F5043554F4863498F4853530950275
+:104F8000FF3885B2000006B400249582FF3C96826B
+:104F9000FF4087320004F68535509702FF4486B201
+:104FA0000004F005354CF70435409516FFF495964E
+:104FB000FFF4C7386800F7053540F584352886B218
+:104FC0000004872E141400000001C7386800972ED3
+:104FD00014148732008000000001203A0001EE0026
+:104FE000534CF7060C3EC07E7400E60050000000F3
+:104FF0000001C07E7400E6004FF100000001F706DA
+:105000000C3EC77C7400203A0010E600534C0000B0
+:105010000001FF8200108682FF38F7043558F584BE
+:105020006F58F685355407380001202E0021E20024
+:105030005064F7053558F7042D38F6862C280638C5
+:105040000001F6052D387739000220320044E600D1
+:105050005058B5BA6802F0052D38F4820022E000FD
+:105060005068F4856F58F0056F54F684352C0000B5
+:10507000000187360094C4840000C03A4A00E6006C
+:1050800050CD0000000186360094F68435540000AF
+:10509000000176B4FFF0F70435549696FFF44739D3
+:1050A00000009716FFF0C6B47000F704354877B4D7
+:1050B000000F703EFFE107380024E60050C5C638F7
+:1050C000600006B40001C7046E00F7332800F684C0
+:1050D0003544000000018736000400000001203A3A
+:1050E000000FE2005119073800018736000C00005C
+:1050F0000001073800019736000C8736000CE000ED
+:10510000512C00000001F7043528F6820001073811
+:105110000008E00052C4F7053544203A0010E600CC
+:10512000512800000001F702000097360004F70440
+:10513000353CF684352807380001F705353CF7047F
+:10514000353C8736141C00000001073800019736F3
+:10515000141CF704760486B6141CF60475FC073894
+:105160000001F684760000000001C03A6A00E60003
+:105170005178F7057604F0057604F6847604F70492
+:105180007608F00575FCC0367200470C000120322D
+:105190000000E60051DDF70575F8F7047648F4865F
+:1051A0007218C03A4A00470C0001203A0000E6009D
+:1051B00051DDF6862C28F7042D3800000001063852
+:1051C0000001F6052D3877390002F482000E2032F6
+:1051D0000044E60051DCB4BA6802F0052D38F5024F
+:1051E0000000202A0002EE0052C4F6820000F6847D
+:1051F0003528000000018736000000000001203A39
+:105200000002E600529805B400089593FFFC95163D
+:10521000FFEC9596FFE89696FFE407880008E0000B
+:105220005EDC9793FFFC8516FFEC8596FFE886967B
+:10523000FFE420220000E6005288F70200008636D4
+:10524000000C000000012032000FE200526D00004F
+:10525000000187360014000000010738000197366E
+:10526000001487360014E0005288F702000076B17F
+:105270000002C6B4600077350005C7386A00C73839
+:10528000600007380010C72C7000203A0000E600CC
+:105290005104F705352CF6843528F7046F4C0000CF
+:1052A0000001C0367200E60052B807341494F4844A
+:1052B0006F44E00052BCF4853528F7053528E0003E
+:1052C00051E00528000120360000E60052FDF68678
+:1052D0002C28F7042D380000000106380001F605DF
+:1052E0002D3877390002F482000D20320044E600A8
+:1052F0005304B4BA6802E0005304F0052D38F48278
+:105300000001F4853524F6843528F7046F44F486CB
+:1053100032F4C0367200E600534CF4853530F704A1
+:10532000E0180000000177B8001F703EFFE1E600C2
+:10533000534D000000010F814000F70479C80000C0
+:10534000000107380001F70579C8F70479C8879686
+:10535000FFFC8296FFF802140000013C00000000F0
+:1053600000019293FFFC0290000822100014F484C4
+:105370003554F684354CF584352C9482FF3876B557
+:105380000003A52E6802000000019502FF3CF38493
+:105390003550C6AC68009382FF4087360004000099
+:1053A00000019702FF4486360004F70435400000F0
+:1053B0000001C7386000F7053540F604352886B689
+:1053C0000004873214149496FFF4C73868009732AB
+:1053D0001414872E008000000001203A0001EE0026
+:1053E00057509516FFF4F7060C3EC07E7400E60099
+:1053F000540400000001C07E7400E60053F5000074
+:105400000001F7060C3EC77C7400203A0010E6004D
+:10541000575000000001FF8200108682FF38F70419
+:105420003558F5846F58F685355407380001202E1D
+:105430000021E2005468F7053558F7042D38F68648
+:105440002C2806380001F6052D3877390002203265
+:105450000044E600545CB5BA6802F0052D38F382CA
+:105460000022E000546CF3856F58F0056F54F68409
+:10547000352C0000000187360094C3840000C03A38
+:105480003A00E60054D10000000186360094F6840C
+:1054900035540000000176B4FFF0F70435549696B9
+:1054A000FFF4473900009716FFF0C6B47000F70408
+:1054B000354877B4000F703EFFE107380024E6005E
+:1054C00054C9C638600006B40001C7046E00F73343
+:1054D0002800F684354400000001873600040000EF
+:1054E0000001203A000FE200551D07380001873601
+:1054F000000C00000001073800019736000C8736C9
+:10550000000CE000553000000001F7043528F68259
+:10551000000107380008E00056C8F7053544203A76
+:105520000010E600552C00000001F702000097363D
+:105530000004F704353CF684352807380001F705E8
+:10554000353CF704353C8736141C00000001073851
+:1055500000019736141CF704760486B6141CF60472
+:1055600075FC07380001F684760000000001C03A9F
+:105570006A00E600557CF7057604F0057604F684AB
+:105580007604F7047608F00575FCC0367200470C07
+:10559000000120320000E60055E1F70575F8F70438
+:1055A0007648F3867218C03A3A00470C0001203A58
+:1055B0000000E60055E1F6862C28F7042D3800009F
+:1055C000000106380001F6052D3877390002F38214
+:1055D000000E20320044E60055E0B3BA6802F00540
+:1055E0002D38F5020000202A0002EE0056C8F6828F
+:1055F0000000F68435280000000187360000000016
+:105600000001203A0002E600569C05B4000895937C
+:10561000FFFC9516FFEC9596FFE89696FFE4078849
+:105620000008E0005EDC9793FFFC8516FFEC859692
+:10563000FFE88696FFE420220000E600568CF70281
+:1056400000008636000C000000012032000FE2004E
+:105650005671000000018736001400000001073871
+:1056600000019736001487360014E000568CF702CC
+:10567000000076B10002C6B4600077350005C73877
+:105680006A00C738600007380010C72C7000203A45
+:105690000000E6005508F705352CF6843528F70498
+:1056A0006F4C00000001C0367200E60056BC0734A3
+:1056B0001494F3846F44E00056C0F3853528F70551
+:1056C0003528E00055E40528000120360000E600FA
+:1056D0005701F6862C28F7042D3800000001063803
+:1056E0000001F6052D3877390002F382000D2032D3
+:1056F0000044E6005708B3BA6802E0005708F00516
+:105700002D38F3820001F3853524F6843528F7041B
+:105710006F44F38632F4C0367200E6005750F385CA
+:105720003530F704E0180000000177B8001F703E24
+:10573000FFE1E6005751000000010F814000F7042F
+:1057400079C80000000107380001F70579C8F7049F
+:1057500079C88796FFFC8296FFF802140000013C8E
+:105760000000000000019293FFFC0290000822104C
+:1057700000148702FF38F384352CF7053554871E53
+:105780000080F504354C27380001C02A7200E6007D
+:105790005A4C00000001F5846F5800000001202ED3
+:1057A0000021E20057D8F6862C28F7042D38000097
+:1057B000000106380001F6052D3877390002203245
+:1057C0000044E60057CCB5BA6802F0052D38F30264
+:1057D0000022E00057DCF3056F58F0056F54F684A3
+:1057E000352C0000000187360094C3040000C03A45
+:1057F0003200E60058410000000186360094F6842D
+:1058000035540000000176B4FFF0F7043554969645
+:10581000FFF4473900009716FFF0C6B47000F70494
+:10582000354877B4000F703EFFE107380024E600EA
+:105830005839C638600006B40001C7046E00F7335B
+:105840002800F6843544000000018736000400007B
+:105850000001203A000FE200588D0738000187361A
+:10586000000C00000001073800019736000C873655
+:10587000000CE00058A000000001F7043528F68273
+:10588000000107380008E0005A38F7053544203A8F
+:105890000010E600589C00000001F7020000973657
+:1058A0000004F704353CF684352807380001F70575
+:1058B000353CF704353C8736141C000000010738DE
+:1058C00000019736141CF704760486B6141CF604FF
+:1058D00075FC07380001F684760000000001C03A2C
+:1058E0006A00E60058ECF7057604F0057604F684C5
+:1058F0007604F7047608F00575FCC0367200470C94
+:10590000000120320000E6005951F70575F8F70450
+:105910007648F3067218C03A3200470C0001203A6C
+:105920000000E6005951F6862C28F7042D380000B7
+:10593000000106380001F6052D3877390002F30220
+:10594000000E20320044E6005950B33A6802F005D8
+:105950002D38F5020000202A0002EE005A38F682A7
+:105960000000F684352800000001873600000000A2
+:105970000001203A0002E6005A0C05B40008959395
+:10598000FFFC9516FFEC9596FFE89696FFE40788D6
+:105990000008E0005EDC9793FFFC8516FFEC85961F
+:1059A000FFE88696FFE420220000E60059FCF7029B
+:1059B00000008636000C000000012032000FE200DB
+:1059C00059E100000001873600140000000107388B
+:1059D00000019736001487360014E00059FCF702E6
+:1059E000000076B10002C6B4600077350005C73804
+:1059F0006A00C738600007380010C72C7000203AD2
+:105A00000000E6005878F705352CF6843528F704B1
+:105A10006F4C00000001C0367200E6005A2C0734BB
+:105A20001494F3046F44E0005A30F3053528F70569
+:105A30003528E00059540528000120360000E60012
+:105A40005DC4F3020001E0005DF000000001772971
+:105A50000003C71C7000873A00040528000176A9DE
+:105A60000003F4843554F60435509482FF38A41EA4
+:105A70006802C63070009402FF3C9602FF40C69C4C
+:105A8000680087360004000000019702FF4485B6D5
+:105A90000004F704354000000001C7385800F7053E
+:105AA000354085B60004F505354CF6843528F605F5
+:105AB0003550873614149496FFF4C738580097363B
+:105AC0001414871E008000000001203A0001EE003F
+:105AD0005E3C9416FFF4F7060C3EC07E7400E600B0
+:105AE0005AF400000001C07E7400E6005AE5000090
+:105AF0000001F7060C3EC77C7400203A0010E60057
+:105B00005E3C00000001FF8200108682FF38F7042F
+:105B10003558F5846F58F685355407380001202E26
+:105B20000021E2005B58F7053558F7042D38F6865A
+:105B30002C2806380001F6052D387739000220326E
+:105B40000044E6005B4CB5BA6802F0052D38F3025C
+:105B50000022E0005B5CF3056F58F0056F54F6849B
+:105B6000352C0000000187360094C3040000C03AC1
+:105B70003200E6005BC10000000186360094F68426
+:105B800035540000000176B4FFF0F70435549696C2
+:105B9000FFF4473900009716FFF0C6B47000F70411
+:105BA000354877B4000F703EFFE107380024E60067
+:105BB0005BB9C638600006B40001C7046E00F73355
+:105BC0002800F684354400000001873600040000F8
+:105BD0000001203A000FE2005C0D07380001873613
+:105BE000000C00000001073800019736000C8736D2
+:105BF000000CE0005C2000000001F7043528F6826C
+:105C0000000107380008E0005DB8F7053544203A88
+:105C10000010E6005C1C00000001F702000097364F
+:105C20000004F704353CF684352807380001F705F1
+:105C3000353CF704353C8736141C0000000107385A
+:105C400000019736141CF704760486B6141CF6047B
+:105C500075FC07380001F684760000000001C03AA8
+:105C60006A00E6005C6CF7057604F0057604F684BD
+:105C70007604F7047608F00575FCC0367200470C10
+:105C8000000120320000E6005CD1F70575F8F7044A
+:105C90007648F3067218C03A3200470C0001203AE9
+:105CA0000000E6005CD1F6862C28F7042D380000B1
+:105CB000000106380001F6052D3877390002F3029D
+:105CC000000E20320044E6005CD0B33A6802F005D2
+:105CD0002D38F5020000202A0002EE005DB8F682A1
+:105CE0000000F6843528000000018736000000001F
+:105CF0000001203A0002E6005D8C05B4000895938F
+:105D0000FFFC9516FFEC9596FFE89696FFE4078852
+:105D10000008E0005EDC9793FFFC8516FFEC85969B
+:105D2000FFE88696FFE420220000E6005D7CF70293
+:105D300000008636000C000000012032000FE20057
+:105D40005D61000000018736001400000001073883
+:105D500000019736001487360014E0005D7CF702DE
+:105D6000000076B10002C6B4600077350005C73880
+:105D70006A00C738600007380010C72C7000203A4E
+:105D80000000E6005BF8F705352CF6843528F704AB
+:105D90006F4C00000001C0367200E6005DAC0734B5
+:105DA0001494F3046F44E0005DB0F3053528F70563
+:105DB0003528E0005CD40528000120360000E6000C
+:105DC0005DF1F3020001F7042D38F6862C28063821
+:105DD0000001F6052D3877390002F302000D20325C
+:105DE0000044E6005DF4B33A6802E0005DF4F005BB
+:105DF0002D38F3053524F6843528F7046F44F3066F
+:105E000032F4C0367200E6005E3CF3053530F7042C
+:105E1000E0180000000177B8001F703EFFE1E600C7
+:105E20005E3D000000010F814000F70479C80000CA
+:105E3000000107380001F70579C8F70479C887968B
+:105E4000FFFC8296FFF802140000013C00000000F5
+:105E500000019293FFFC02900008F706353097137B
+:105E6000FFFCF70632F49713FFFC07880008E000F8
+:105E700014F49793FFFCF70635309713FFFCF706F1
+:105E800033809713FFFC07880008E00014F4979311
+:105E9000FFFCF70635309713FFFCF706340C971319
+:105EA000FFFC07880008E00014F49793FFFCF70656
+:105EB00035309713FFFCF70634989713FFFC0788DB
+:105EC0000008E00014F49793FFFC8796FFFC82968D
+:105ED000FFF802140000013C000000000001929352
+:105EE000FFFC0290000886160000000000018732C7
+:105EF000000400000001203A000F86B20000C538FF
+:105F00000000EE005F2CC5B400002036000FEE004C
+:105F10005F2C00000001203A0000EC005F2D000023
+:105F2000000120360000EC005F48000000018732CD
+:105F3000000C00000001073800019732000C873286
+:105F4000000CE0005F50F4020000C02A5A00440C2C
+:105F500000018796FFFC8296FFF802140004013CC2
+:105F6000000000000001000000009293FFFC02907E
+:105F70000008F68635609693FFFCF68642309693CD
+:105F8000FFFC07880008E00015489793FFFCF682A5
+:105F900066F89693FFFCF78200179793FFFCF6864E
+:105FA00035609693FFFC07880008E000161C979365
+:105FB000FFFCF68269809693FFFCF78200189793A6
+:105FC000FFFCF68635609693FFFC07880008E0002A
+:105FD000161C9793FFFCF6826B509693FFFCF7829A
+:105FE00000169793FFFCF68635609693FFFC0788B2
+:105FF0000008E000161C9793FFFCF68261789693E8
+:10600000FFFCF782001F9793FFFCF686356096939E
+:10601000FFFC07880008E000161C9793FFFCF6823F
+:10602000627C9693FFFCF78200209793FFFCF68634
+:1060300035609693FFFC07880008E000161C9793D4
+:10604000FFFCF68266F89693FFFCF78200179793A1
+:10605000FFFCF68635EC9693FFFC07880008E0000D
+:10606000161C9793FFFCF68269809693FFFCF782DB
+:1060700000189793FFFCF68635EC9693FFFC078893
+:106080000008E000161C9793FFFCF6826B50969375
+:10609000FFFCF78200169793FFFCF68635EC96938B
+:1060A000FFFC07880008E000161C9793FFFCF682AF
+:1060B00061789693FFFCF782001F9793FFFCF686AA
+:1060C00035EC9693FFFC07880008E000161C9793B8
+:1060D000FFFCF682627C9693FFFCF7820020979388
+:1060E000FFFCF68635EC9693FFFC07880008E0007D
+:1060F000161C9793FFFCF704E02800000001203AEB
+:106100000000E600611500000001F704E028E0004F
+:10611000611877390002F70200F0F7054228F70608
+:10612000408AF03B2800F706408CF03B2800F7023D
+:106130000000F7057AC0F7057AB8F7057AB0F705D9
+:106140007AC8F682C3509693FFFCF68200169693A7
+:10615000FFFCF68642309693FFFC07880008E001BA
+:106160001EC09793FFFC8796FFFC8296FFF80214EF
+:106170000000013C0000000000019293FFFC02902F
+:106180000008F6046F340000000120320000E60031
+:1061900061ED76B1001E8732000076B4FFE5C738A6
+:1061A0006FC07739FFF0203A0007E60061EC06B0D7
+:1061B00000028736000076B5001E76B4FFE5C738CA
+:1061C0006FC07739FFF0203A0001E60061ECF50678
+:1061D00035ECF704423000000001C03A5200470C91
+:1061E0000001203A0000E6006211F5820000F70489
+:1061F00042A0F60642A276B1001E76B4FFE5C7388B
+:106200006FC07739FFF007380001E0006268F733AC
+:1062100028008732000400000001F705E00086B284
+:106220000008203A0000E600623CF685E0042036D3
+:106230000000E6006240202E0000F5820001202EC2
+:106240000000E6006265F60642A2F70442A076B1BD
+:10625000001E76B4FFE5C7386FC07739FFF0073806
+:106260000001F7332800F00542288796FFFC82964C
+:10627000FFF802140000013C0000000000019293AE
+:10628000FFFC02900008F704423CF6846F340738A4
+:10629000000120360000E60062B1F705423C873677
+:1062A0000000F59E0002C03A5A00E60062BDF58685
+:1062B00035ECF70442A0E00062DCF60642A2F704E7
+:1062C000423000000001C03A5A00470C0001203A59
+:1062D0000000E60062F9F60642A4F70442A476B193
+:1062E000001E76B4FFE5C7386FC07739FFF0073876
+:1062F0000001E000630CF73328009693FFFC078849
+:106300000008E00063209793FFFCF0054228879681
+:10631000FFFC8296FFF802140000013C0000000020
+:1063200000019293FFFC02900008221000208316C7
+:10633000000000000001871A001800000001203A48
+:106340000000E600636CF7020000839A001C000066
+:106350000001F3857AC0849A0014F7057AC8F485A1
+:106360007AB0F7057AB88316000000000001869A1B
+:106370000014F7047AB000000001C0367200E60095
+:1063800063D0F6020000869A001CF7047AC0000071
+:106390000001C0367200E60063D000000001869A5A
+:1063A0000018F7047AB800000001C0367200E60059
+:1063B00063D000000001869A0020F7047AC800002C
+:1063C0000001C7386800203A0064EE0063D920322B
+:1063D0000000F602000120320000E60064580000D0
+:1063E00000018396000000000001871E00180000D5
+:1063F0000001203A0000E600643CF7020000F705C7
+:106400004080F7054084F6846E50F482FFFF831EBF
+:10641000000CF4854F5493360010839E0010849630
+:10642000000093B6001484A600080000000194B692
+:106430001DDCF6820064F6854A98F7054A9C8316AF
+:10644000000000000001871A002000000001203A2F
+:106450000000EE00647CF3820000F70442A4F6061C
+:1064600042A676B1001E76B4FFE5C7386FC0773913
+:10647000FFF007380001E00066E4F7332800939648
+:10648000FFF484160000F48642C89496FFECF302F1
+:10649000000C9316FFE4839600008496FFF4871E99
+:1064A000002000000001C0267200EC006648F38660
+:1064B0004A9884A200248316FFE4C5040000B49A1D
+:1064C0003802C7183800832200288396FFF4849688
+:1064D000FFE4933A000493BA0008F604E000F306E0
+:1064E0004A98A6A63002F5820000C0326A00E60093
+:1064F0006510C6380000F684E0048732000400000E
+:106500000001C0367200E6006514202E0000F582FE
+:106510000001202E0000E600652100000001F502C8
+:106520000000F684E0008732000000000001C03661
+:106530007200E200655CF5820000C0367200E60081
+:106540006564202E0000F684E00487320004000019
+:106550000001C0367200E2006565202E0000F58261
+:106560000001202E0000E6006575202A0000F502DB
+:106570000001202A0000E6006588000000018396E3
+:10658000FFF400000001F3854F548722002C76A110
+:10659000001E76B4FFE505A0002E762D001E763095
+:1065A000FFE5F48200009496FFDC8316FFEC2026C2
+:1065B0000007C7386FC07738FFF0F71B2800872E19
+:1065C000000006980002C73867C07738FFF0E20085
+:1065D000661CF73728008516FFEC8596FFDC000067
+:1065E0000001C72C400086BA0030062800040528A8
+:1065F000000205AC00028396FFDC7739001E773875
+:10660000FFE5039C00019396FFDC201E0007C6B443
+:1066100077C076B4FFF0E20065E1F6B3280004200D
+:10662000001C8496FFEC8316FFE48396FFF404A419
+:1066300000149496FFEC0318000C9316FFE4039CDF
+:106640000001E00064949396FFF48496000000003B
+:1066500000018726002000000001F7054A9C85A65E
+:106660000020F7047AB80000000107380001F705A0
+:106670007AB8F7047AB8F6847AC886260018C6B4C1
+:1066800058008726001C0000000127380001C03296
+:106690007200470C0001203A0000E60066E5F6852E
+:1066A0007AC883260008F7046E50F3053B6483A67E
+:1066B0000008F682000093BA1DDC84A6000C831645
+:1066C000000094BA0010831A0010F6857AC8933A35
+:1066D0000014F7020001F7054084F6857AC0F685BC
+:1066E0007AB8F6857AB08796FFFC8296FFF8021496
+:1066F0000004013C0000000000019293FFFC0290A6
+:10670000000822100008F3846F3400000001871E87
+:106710000018F684E01C00000001C0367200EC0096
+:106720006729F7020001F7020000203A0000E600A6
+:1067300067E8F5820001F704E01C869E001800005F
+:106740000001C03A6A00470C0001203A0000E60050
+:1067500067E9C5840000869E0010F704E000F60299
+:106760000000C0367200E6006788051C0010869E97
+:106770000014F704E00400000001C0367200E600D7
+:10678000678C20320000F602000120320000E60093
+:10679000679900000001F582000086AA0000F70456
+:1067A000E00000000001C0367200E20067D4F6028B
+:1067B0000000C0367200E60067DC2032000086AAC6
+:1067C0000004F704E00400000001C0367200E2009B
+:1067D00067DD20320000F602000120320000E600F2
+:1067E00067ED202E0000F5820001202E0000E6005B
+:1067F0006810F606429CF704429C76B1001E76B4FF
+:10680000FFE5C7386FC07739FFF007380001F7336D
+:106810002800F70475F475ACFFE1203A0000E600AB
+:1068200068459596FFF4F7044298F606429876B1CB
+:10683000001E76B4FFE5C7386FC07739FFF0073820
+:106840000001F7332800871E0020041C002076A1D9
+:10685000001E76B4FFE5C7386FC07739FFF0203AE5
+:106860000008EE0068C4F3061554F5020000059C0C
+:106870000022C4AC0000F60200018722000076A1CD
+:10688000001E76B4FFE5C7386FC07739FFF0C02A25
+:106890007200EC0068C0C6A46000A726600276B54E
+:1068A000001E76B4FFE505280001C7386FC07739B0
+:1068B000FFE8F72F680005AC0001E00068780630BB
+:1068C0000002F30615549313FFFCF704E0240000C4
+:1068D00000019713FFFCF704E01C00000001971370
+:1068E000FFFCF306E0009313FFFC9393FFFCF3021D
+:1068F00000019313FFFC07880008E000EE64979303
+:10690000FFFC20220000E6006928F606429EF704FC
+:10691000429C76B1001E76B4FFE5C7386FC0773968
+:10692000FFF007380001F73328008316FFF400005A
+:106930000001201A0000E600696CF30635ECF7044C
+:10694000423000000001C03A3200470C0001203AFA
+:106950000000E600696DF0054228F3063560F30596
+:10696000423007880008E000789C9793FFFC8796E8
+:10697000FFFC8296FFF802140000013C00000000BA
+:1069800000019293FFFC0290000822100004F5041D
+:106990006F34F7044240862A001807380001F68455
+:1069A000E01CF7054240C0366200EC0069B5F70212
+:1069B0000001F7020000203A0000E6006A80F702BA
+:1069C0000001F704E01C86AA001800000001C03A8C
+:1069D0006A00470C0001203A0000E6006A7DC58489
+:1069E000000086AA0010F704E000F6020000C0369E
+:1069F0007200E6006A1404A8001086AA0014F704C6
+:106A0000E00400000001C0367200E6006A1820327F
+:106A10000000F602000120320000E6006A250000B6
+:106A20000001F582000086A60000F704E0000000E7
+:106A30000001C0367200E2006A60F6020000C03653
+:106A40007200E6006A682032000086A60004F7049F
+:106A5000E00400000001C0367200E2006A692032E2
+:106A60000000F602000120320000E6006A81C72C17
+:106A70000000F5820001E0006A80C72C0000C70416
+:106A80000000203A0000EE006B3DF686408AF704D5
+:106A9000408876B5001E76B4FFE5C7386FC07738FA
+:106AA000FFF0203A0000E6006B3CF6820000F6851D
+:106AB0004080F68540849693FFFC9693FFFCF70494
+:106AC000E01C000000019713FFFCF386E0009393A5
+:106AD000FFFC9513FFFCF38200029393FFFC969654
+:106AE000FFF407880008E000EE649793FFFCF405CC
+:106AF00040848696FFF4F7046E50F38635ECF685F5
+:106B00004090F6854094873A1DDCF6854228F705CB
+:106B10003B64F7044230F4054080C03A3A00470C29
+:106B20000001203A0000E6006B3DF3863560F385F6
+:106B3000423007880008E000789C9793FFFC879616
+:106B4000FFFC8296FFF802140000013C00000000E8
+:106B500000019293FFFC02900008F4864230949367
+:106B6000FFFC07880008E00120E49793FFFC202247
+:106B70000000E6006DD9F5820000F704408CF606AF
+:106B8000408C7631001EF68442287630FFE506B44C
+:106B90000001C73867C07738FFF0203A0000E600F0
+:106BA0006BC8F6854228F7044088F686408A76B599
+:106BB000001E76B4FFE5C7386FC07738FFF0203A83
+:106BC0000000E6006D0D00000001F704408CF68621
+:106BD000408C76B5001E76B4FFE5C7386FC07738B5
+:106BE000FFF0203A0000E6006C35F606408AF70414
+:106BF000408876B1001E76B4FFE5C7386FC077389D
+:106C0000FFF0203A0000E6006C34F4863678F70492
+:106C1000424400000001C03A4A00470C0001203AFB
+:106C20000000E6006C35F4820001F4B32800E000B7
+:106C30006D10F005422CF704408CF506408C76A9C7
+:106C4000001E76B4FFE5C7386FC07738FFF0203AF2
+:106C50000000E6006CC1F606408AF704408876B171
+:106C6000001E76B4FFE5C7386FC07738FFF0203AD2
+:106C70000000E6006CC100000001F704422C000097
+:106C8000000107380001203A0009EE006D11F705F8
+:106C9000422CF02B2800F0332800F5820001F70485
+:106CA0004294F606429476B1001E76B4FFE5C738EA
+:106CB0006FC07739FFF007380001E0006D10F7333F
+:106CC0002800F704408CF686408C76B5001E76B41A
+:106CD000FFE5C7386FC07738FFF0203A0000E600C4
+:106CE0006D14202E0000F7044088F606408A76B125
+:106CF000001E76B4FFE5C7386FC07738FFF0203A42
+:106D00000000E6006D15202E0000F0332800F5820B
+:106D10000001202E0000E6006DB5F48635ECF70486
+:106D2000423000000001C03A4A00470C0001203AFE
+:106D30000000E6006D5900000001F704E0280000A3
+:106D40000001203A0000E6006D79F682003CF684EE
+:106D5000E028E0006D7800000001F704E028000062
+:106D60000001203A0000E6006D79F68200F0F70499
+:106D7000E0280000000176B90002F7044228000074
+:106D80000001C03A6A00EC006DB5F6862C28F704C5
+:106D90002D38F005422806380001F6052D387739E0
+:106DA0000002F482001920320044E6006DB4B4BA47
+:106DB0006802F0052D38F482C3509493FFFCF482EE
+:106DC00000169493FFFCF48642309493FFFC0788EE
+:106DD0000008E0011EC09793FFFC8796FFFC829697
+:106DE000FFF802140000013C000000000001929333
+:106DF000FFFC0290000822100004F5863678959377
+:106E0000FFFCF58642449593FFFC07880008E000EC
+:106E100015489793FFFCF58274189593FFFCF58253
+:106E200000199593FFFCF58636789593FFFC07884B
+:106E30000008E000161C9793FFFCF58274AC959354
+:106E4000FFFCF782001D9793FFFCF58637049593AE
+:106E5000FFFC07880008E000161C9793FFFCF582F2
+:106E600078009593FFFCF782001B9793FFFCF58653
+:106E700037049593FFFC07880008E000161C9793E1
+:106E8000FFFCF58278FC9593FFFCF782001A97933C
+:106E9000FFFCF58637909593FFFC07880008E0001B
+:106EA000161C9793FFFCF58280D89593FFFCF78220
+:106EB000001B9793FFFCF58637909593FFFC07889E
+:106EC0000008E000161C9793FFFCF58281749593EF
+:106ED000FFFCF782001D9793FFFCF586381C959305
+:106EE000FFFC07880008E000161C9793FFFCF58262
+:106EF00087749593FFFCF782001B9793FFFCF58640
+:106F0000381C9593FFFC07880008E000161C979337
+:106F1000FFFCF58294F89593FFFCF782001B979392
+:106F2000FFFCF58639349593FFFC07880008E000E4
+:106F3000161C9793FFFCF5828A009593FFFCF7825D
+:106F4000001C9793FFFCF58639349593FFFC078866
+:106F50000008E000161C9793FFFCF5828E089593BD
+:106F6000FFFCF782001A9793FFFCF586393495935E
+:106F7000FFFC07880008E000161C9793FFFCF582D1
+:106F8000969C9593FFFCF782001E9793FFFCF58675
+:106F900038A89593FFFC07880008E000161C97931B
+:106FA000FFFCF5829B2C9593FFFCF782001B9793C7
+:106FB000FFFCF58638A89593FFFC07880008E000E1
+:106FC000161C9793FFFCF582A2DC9593FFFCF782D9
+:106FD000001E9793FFFCF5863AD89593FFFC07882F
+:106FE0000008E000161C9793FFFCF5829E549593D1
+:106FF000FFFCF782001B9793FFFCF5863AD8959328
+:10700000FFFC07880008E000161C9793FFFCF58240
+:10701000A3C09593FFFCF782001C9793FFFCF586B5
+:1070200039C09593FFFC07880008E000161C979371
+:10703000FFFCF582A7649593FFFCF782001E9793EF
+:10704000FFFCF58639C09593FFFC07880008E00037
+:10705000161C9793FFFCF582AA049593FFFCF78218
+:10706000001B9793FFFCF58639C09593FFFC0788BA
+:107070000008E000161C9793FFFCF582AEF895938C
+:10708000FFFCF782001C9793FFFCF5863A4C959322
+:10709000FFFC07880008E000161C9793FFFCF7062A
+:1070A0004250F03B2800F7064088F03B2800F602EB
+:1070B0000000F6054080F6054084F7063B70F63B7D
+:1070C0002800F7063B72F0BB2800F582CA20F58540
+:1070D0003B74F7063B78F03B2800F7063B7AF0BBA1
+:1070E0002800F582B194F5853B7CF7063B80F03BA8
+:1070F0002800F7063B82F0BB2800F582C754F585CF
+:107100003B84F7063B88F03B2800F7063B8AF0BB40
+:107110002800F582BEF8F5853B8CF7063B90F03BE6
+:107120002800F7063B92F0BB2800F582C8F8F585E9
+:107130003B94F7063B98F03B2800F7063B9AF0BBE0
+:107140002800F582C5D8F5853B9CF7063BA0F03BAF
+:107150002800F7063BA2F0BB2800F582C770F58532
+:107160003BA4F7063BA8F03B2800F7063BAAF0BB80
+:107170002800F582C1B4F5853BAC9616FFF407886C
+:107180000008E000D5409793FFFCF6846E50861609
+:10719000FFF40000000196361DDCF6053B6487967F
+:1071A000FFFC8296FFF802140000013C0000000082
+:1071B00000019293FFFC02900008221000302594F9
+:1071C0000020F02F280026140038F03328009013F8
+:1071D000FFFCF7044250F686425076B5001E76B4A6
+:1071E000FFE5C7386FC07739FFF09713FFFC9613A0
+:1071F000FFFC9593FFFC07880008E000F5F49793E7
+:10720000FFFC20220000E600721DF5021770F70453
+:1072100042540000000127380001F705425495133D
+:10722000FFFCF502001B9513FFFCF5064244951385
+:10723000FFFC07880008E0011EC09793FFFC8796BB
+:10724000FFFC8296FFF802140000013C00000000E1
+:1072500000019293FFFC02900008F704E0048616F8
+:107260000000F68200FF7739FFF0C7386C00F73373
+:107270002800F706E006873A000006B00002F7375C
+:107280002800F6843B6407300004F6BB2800870220
+:10729000FF3406300006F73328008796FFFC8296FD
+:1072A000FFF802140004013C00000000000192936A
+:1072B000FFFC029000082210003026140020F0335A
+:1072C000280027140038F03B28009713FFFC909308
+:1072D000FFFCF7044250F686425076B5001E76B4A5
+:1072E000FFE5C7386FC07739FFF09713FFFC96139F
+:1072F000FFFC07880008E000F3389793FFFC20228A
+:107300000000E6007319F5821770F704425400007C
+:10731000000127380001F70542549593FFFCF582E0
+:10732000001B9593FFFCF58642449593FFFC07886C
+:107330000008E0011EC09793FFFC8796FFFC829631
+:10734000FFF802140000013C0000000000019293CD
+:10735000FFFC029000082210004026140020961620
+:10736000FFC4F03328009013FFFC9613FFFC261493
+:1073700000389616FFBC9613FFFC07880008E00053
+:10738000D0DC9793FFFC9013FFFCF7044250F68685
+:10739000425076B5001E76B4FFE5C7386FC0773926
+:1073A000FFF09713FFFC8616FFBC00000001961348
+:1073B000FFFC8616FFC4000000019613FFFC07883F
+:1073C0000008E000F5F49793FFFC20220000E6009F
+:1073D00073E5F6021770F7044254000000012738E5
+:1073E0000001F70542549613FFFCF602001B9613AA
+:1073F000FFFCF60642449613FFFC07880008E001F4
+:107400001EC09793FFFC8796FFFC8296FFF802143C
+:107410000000013C0000000000019293FFFC02907C
+:10742000000822100004F5820000F5854080959642
+:10743000FFF407880008E000CB509793FFFC859687
+:10744000FFF4F5020064F5053BB4F7044250F486FE
+:10745000425076A5001E76B4FFE5F6044F5CF402B8
+:107460000006F4054254F5853B6CF5853BB8953232
+:10747000000095B20004C7386FC07739FFF00738B5
+:107480000001F727280007880008E00071B09793F3
+:10749000FFFCF4063704F40542448796FFFC82960D
+:1074A000FFF802140000013C00000000000192936C
+:1074B000FFFC0290000822100050F7044250F686AC
+:1074C000425076B5001E76B4FFE5F6046F34C73837
+:1074D0006FC086B2000C7739FFF0C0367200E6004C
+:1074E00077ECC504000086B20010F704E000F30258
+:1074F0000000C0367200E600751804B0001086B2B5
+:107500000014F704E00400000001C0367200E60039
+:10751000751C201A0000F3020001201A0000E6008A
+:10752000752900000001F502000086A60000F7049E
+:10753000E00000000001C0367200E2007564F6024F
+:107540000000C0367200E600756C2032000086A68E
+:107550000004F704E00400000001C0367200E200FD
+:10756000756D20320000F602000120320000E600B6
+:10757000757D202A0000F5020001202A0000E600A7
+:1075800077EC0000000107880008E000CBCC97935F
+:10759000FFFC26140020F033280004A00002F0278E
+:1075A0002800F582000023940022F59F280003A004
+:1075B000001A9396FFD42594002285AE000077AD83
+:1075C000001E77BCFFE5C5AC7FC075ADFFF076311E
+:1075D000001E7630FFE506A400022314001E751578
+:1075E000001EF59F2800F384E0007528FFE593A2B4
+:1075F000001CF584E0047399001E739CFFE59396CC
+:10760000FFAC7395001E739CFFE59396FFCC23940B
+:10761000004295A200208716FFE07595001E75AC0C
+:10762000FFE59596FFB47595001E75ACFFE5959640
+:10763000FFC4C73867C07738FFF0F7272800F48405
+:107640004F58871A0000C4A04A0074A4FFFAC5A4CA
+:107650000000F59F28008396FFAC2314001A7619CA
+:10766000001E7630FFE58596FFB4C7383FC07738F7
+:10767000FFF0F737280006B400028716FFE4839670
+:10768000FFCCC73857C07738FFF0F7372800871A84
+:10769000000006B40002C73867C07738FFF0F7373C
+:1076A000280006B400028716FFE823140016761996
+:1076B000001E7630FFE5C7385FC07738FFF0F73738
+:1076C0002800871A000006B40002C73867C0773860
+:1076D000FFF0F737280006B400028716FFEC2314EA
+:1076E00000127619001E7630FFE5C7383FC07738A4
+:1076F000FFF0F7372800871A000006B400028596CD
+:10770000FFC4C73867C07738FFF0F73728008716FF
+:10771000FFF006B40002C7385FC07738FFF0F737D4
+:107720002800F3820002F3A3280004200018259407
+:10773000002285AE000077AD001E77BCFFE5C5AC2A
+:107740007FC075ADFFF08396FFD4F5A32800F49FAA
+:1077500028002594004285AE000077AD001E77BC5E
+:10776000FFE5C5AC7FC075ADFFF044AD000094935C
+:10777000FFFCF786E0009793FFFCF3844F5C00006A
+:1077800000019393FFFC07880008E00123409793D2
+:10779000FFFC07880008E00078D89793FFFCF0050D
+:1077A0004084F786E0009793FFFC07880008E0001C
+:1077B000D5A09793FFFCF7046E50F4054084873AF8
+:1077C0001DDC00000001F7053B64F5863678F58581
+:1077D0004244F3863560F3854230F5864244959302
+:1077E000FFFC07880008E0011F489793FFFC87967D
+:1077F000FFFC8296FFF802140000013C000000002C
+:1078000000019293FFFC02900008F5864244959394
+:10781000FFFC07880008E00120E49793FFFC20228A
+:107820000000E600788900000001F70442540000DF
+:107830000001203A0000EE007851F6064250078819
+:107840000008E00071B09793FFFCE000788800002A
+:107850000001F704425076B1001E76B4FFE5F582D0
+:107860000006F5854254C7386FC07739FFF00738F6
+:107870000001F733280007880008E00072AC9793F6
+:10788000FFFCF5863790F58542448796FFFC82968B
+:10789000FFF802140000013C000000000001929378
+:1078A000FFFC02900008F6063678F6054244F7021F
+:1078B0000000F7054080F7054094F6846E50F70508
+:1078C000409097361DDC8796FFFC8296FFF80214E5
+:1078D0000000013C0000000000019293FFFC0290B8
+:1078E0000008F7020001F70540808796FFFC8296AA
+:1078F000FFF802140000013C000000000001929318
+:10790000FFFC02900008221000A8F7044250F58600
+:10791000425076AD001EF4846F3476B4FFE5949641
+:10792000FFC4C7386FC086A6000C7739FFF0C03699
+:107930007200E6007955F606429AF704429876B14D
+:10794000001E76B4FFE5C7386FC07739FFF00738FF
+:107950000001F7332800F704425076AD001E76B4DC
+:10796000FFE58516FFC4C7386FC086AA000C7739BB
+:10797000FFF0C0367200E60080A8F606429A872A19
+:107980000010862A001C203A0000E60079A8F68242
+:107990000000872A001400000001203A0000E600E1
+:1079A00079AC20360000F682000120360000E600A7
+:1079B0007A05249400209496FFBC8516FFC4F02716
+:1079C0002800052800109516FFB49513FFFC0788C2
+:1079D0000008E00072509793FFFC8496FFB400000B
+:1079E00000019493FFFC8516FFBC00000001951375
+:1079F000FFFC07880008E000F9349793FFFCE000E3
+:107A000080C40000000120320000E600806C00000D
+:107A1000000107880008E000CBCC9793FFFC259479
+:107A20000020F02F280004A000029496FF5CF027AD
+:107A30002800F48200002514005AF4AB2800072027
+:107A4000001A2514005A852A000077A9001E77BC69
+:107A5000FFE5C5287FC07529FFF075AD001E75AC28
+:107A6000FFE52314001E7619001EF53B2800F48460
+:107A7000E0007630FFE594A2001CF504E004849653
+:107A8000FF5C952200208716FFE006A40002751512
+:107A9000001E7528FFE59516FF547495001E74A40A
+:107AA000FFE59496FF9C7515001E7528FFE5951659
+:107AB000FF947495001E8516FF5C74A4FFE59496F0
+:107AC000FF8C8496FF54C7385FC07738FFF0F72BE0
+:107AD0002800871A00008516FF9CC73867C07738D2
+:107AE000FFF0F737280006B400028716FFE42314DE
+:107AF000001A7619001E7630FFE5C7384FC0773878
+:107B0000FFF0F7372800871A000006B400028496B9
+:107B1000FF94C73867C07738FFF0F737280006B4FE
+:107B200000028716FFE8231400167619001E76302F
+:107B3000FFE5C73857C07738FFF0F7372800871AB6
+:107B4000000006B40002C73867C07738FFF0F73787
+:107B5000280006B400028716FFEC231400127619E1
+:107B6000001E7630FFE5C7384FC07738FFF0F73793
+:107B70002800871A000006B400028516FF8CC7385B
+:107B800067C07738FFF0F73728008716FFF006B494
+:107B90000002C73857C07738FFF0F7372800F48263
+:107BA0000002F4A328002514005A852A000077A9B2
+:107BB000001E77BCFFE5C5287FC07529FFF00720B0
+:107BC0000018F53B28009416FFAC07880008E00079
+:107BD000CBCC9793FFFC261400382494005A84A63B
+:107BE000000077A5001E77BCFFE5C4A47FC074A584
+:107BF000FFF005A0000206AC000223940036751DBC
+:107C0000001E7528FFE50720001AF4B3280076311E
+:107C1000001E7630FFE59516FF547495001E74A47F
+:107C2000FFE59496FF5C7515001E7528FFE5951617
+:107C3000FF7C7495001E8516FFC474A4FFE594961E
+:107C4000FF74852A00342494005A9516FF8484A674
+:107C5000000077A5001E77BCFFE5C4A47FC074A513
+:107C6000FFF02514005AF4AF2800852A000077A9F8
+:107C7000001E77BCFFE5C5287FC07529FFF08496FC
+:107C8000FFC4F53B280084A600108516FFC494A20B
+:107C9000001C852A00147495001E74A4FFE59496B8
+:107CA000FF6C952200208716FFC88516FF54C73841
+:107CB00067C07738FFF0F72F2800871E00008496F2
+:107CC000FF5CC73857C07738FFF0F737280006B495
+:107CD00000028716FFCC23940032761D001E7630FA
+:107CE000FFE58516FF7CC7384FC07738FFF0F737C0
+:107CF0002800871E000006B40002C73867C0773826
+:107D0000FFF0F737280006B400028716FFD023944F
+:107D1000002E761D001E7630FFE5C73857C0773835
+:107D2000FFF0F7372800871E000006B40002849693
+:107D3000FF748516FF6CC73867C07738FFF0F737D8
+:107D4000280006B400028716FFD42394002A761D6B
+:107D5000001E7630FFE5C7384FC07738FFF0F737A1
+:107D60002800871E000006B40002C73867C07738B5
+:107D7000FFF0F73728008716FFD806B40002C7388F
+:107D800057C07738FFF0F7372800F4820002F4A3D9
+:107D90002800072000182514007A852A000077A9FA
+:107DA000001E77BCFFE5C5287FC07529FFF08496CB
+:107DB000FFC4F53B28008726000400000001203A9C
+:107DC0000024F7044F58E6007EF99416FF54C720AC
+:107DD0007200F6846E508626002C7738FFFA251440
+:107DE000005A842A000077A9001E77BCFFE5C42052
+:107DF0007FC07421FFF04739000086B61DDC77395B
+:107E00000002C0326A00468C0001D6800A68203623
+:107E10000000F6864098E6007EC0C3B86800C584BE
+:107E2000000086A60024F704E000F6020000C03639
+:107E30007200E6007E540324002486A60028F7047E
+:107E4000E00400000001C0367200E6007E582032D7
+:107E50000000F602000120320000E6007E6500000E
+:107E60000001F5820000869A0000F704E00000009F
+:107E70000001C0367200E2007EA0F6020000C036AB
+:107E80007200E6007EA820320000869A0004F70403
+:107E9000E00400000001C0367200E2007EA920323A
+:107EA0000000F602000120320000E6007EB9202E1C
+:107EB0000000F5820001202E0000E6007EC50000D3
+:107EC0000001F4020001F7044F58F41F28008496C3
+:107ED000FF548516FFC4F686409AC724720077388F
+:107EE000FFFA862A00304739000077390002C73888
+:107EF0006800E0007F4CF63B28008496FF54F606AD
+:107F00004098C72472007738FFFAC6B8000046B51B
+:107F1000000076B50002C6B46000F5020001F53736
+:107F200028004739000077390002C73860002494E0
+:107F3000005A84A6000077A5001E77BCFFE5C4A404
+:107F40007FC074A5FFF007380002F4BB2800F704D7
+:107F50004F588516FF548496FFACC6A8720076B4BD
+:107F6000FFFA0624001AF6B32800C72472007738F7
+:107F7000FFFA06A8001AF7372800473900009713C0
+:107F8000FFFC0724001C9713FFFCF5044F5C000066
+:107F900000019513FFFC07880008E0012340979338
+:107FA000FFFCF7044F588496FF5400000001C724DB
+:107FB00072007738FFFA473900009713FFFC072457
+:107FC000001C9713FFFCF5044F5C000000019513A3
+:107FD000FFFC07880008E00123409793FFFC078817
+:107FE0000008E00078D89793FFFCF6846E500000FC
+:107FF000000187361DDC00000001073800019736BC
+:108000001DDC87361DDCF0054084F486E000949387
+:10801000FFFC07880008E000D5A09793FFFCF4055B
+:108020004084F7046E50F005425C873A1DDCF6860A
+:108030002C28F7053B64F7042D38F5063A4CF50576
+:10804000424406380001F6052D3877390002F482E3
+:10805000001C20320044E6008060B4BA6802F005DB
+:108060002D38F50635ECE000808CF50542302032E5
+:108070000001E60080C40000000107880008E0005D
+:10808000789C9793FFFCF4863560F4854230F506C2
+:1080900042449513FFFC07880008E0011F489793AE
+:1080A000FFFCE00080C400000001F704429876B1B4
+:1080B000001E76B4FFE5C7386FC07739FFF0073888
+:1080C0000001F73328008796FFFC8296FFF8021420
+:1080D0000000013C0000000000019293FFFC0290B0
+:1080E0000008F58642449593FFFC07880008E001EC
+:1080F00020E49793FFFC20220000E600816100004D
+:108100000001F704425400000001203A0000EE0094
+:108110008129F606425007880008E00072AC979368
+:10812000FFFCE000816000000001F704425076B1DE
+:10813000001E76B4FFE5F5820006F5854254C73887
+:108140006FC07739FFF007380001F7332800078840
+:108150000008E000734C9793FFFCF586381CF5850A
+:1081600042448796FFFC8296FFF802140000013C0F
+:108170000000000000019293FFFC02900008221012
+:108180000058F7044250F686425076B5001E76B489
+:10819000FFE5F6046F34C7386FC086B2000C77393C
+:1081A000FFF0C0367200E6008250F4820000C50481
+:1081B000000086B20010F704E000C5A40000C0363D
+:1081C0007200E60081E40430001086B20014F70467
+:1081D000E00400000001C0367200E60081E8202EB5
+:1081E0000000F5820001202E0000E60081F500006D
+:1081F0000001F502000086A20000F704E000000084
+:108200000001C0367200E2008230F6020000C03683
+:108210007200E60082382032000086A20004F704D3
+:10822000E00400000001C0367200E2008239203212
+:108230000000F602000120320000E6008249202AF8
+:108240000000F5020001202A0000E60082592026E5
+:108250000000F482000120260000E6008760000094
+:10826000000107880008E000CBCC9793FFFC0720B3
+:108270000002F03B2800F7044F58F4053BB006A07D
+:108280000014C72072007738FFFAF737280006A0DD
+:108290000016F7372800F3020001F32328000788AF
+:1082A0000008E000CBCC9793FFFC26140020F033AD
+:1082B000280004A00002F0272800F3020000239405
+:1082C000002AF31F28000720001A2394002A839E07
+:1082D0000000779D001E77BCFFE5C39C7FC0739DA7
+:1082E000FFF07631001E7630FFE506A4000275151A
+:1082F000001EF3BB2800F304E0007528FFE593227D
+:10830000001CF384E0042314001E9316FFA4759947
+:10831000001E75ACFFE57315001E7318FFE593167C
+:10832000FFCC8316FFA493A200208716FFE073956D
+:10833000001E739CFFE59396FFAC7395001E739C23
+:10834000FFE5C73867C07738FFF0F7272800871A9E
+:1083500000009396FFC4C7385FC07738FFF0F73747
+:10836000280006B400028716FFE42394001A9396AF
+:10837000FFA4761D001E7630FFE5C73857C077385A
+:10838000FFF0F7372800871E000006B40002C73848
+:1083900067C07738FFF0F737280006B40002871669
+:1083A000FFE8231400169316FFA47619001E839687
+:1083B000FFAC7630FFE5C7383FC07738FFF0F737BE
+:1083C0002800871A000006B40002C73867C0773853
+:1083D000FFF0F737280006B400028716FFEC2314DD
+:1083E00000129316FFA47619001E8396FFCC7630F8
+:1083F000FFE5C7383FC07738FFF0F7372800871A06
+:10840000000006B40002C73867C07738FFF0F737BE
+:1084100028008716FFF08316FFC406B40002C73891
+:1084200037C07738FFF0F7372800F3820002F3A354
+:1084300028002314002A831A00007799001E77BCB5
+:10844000FFE5C3187FC07319FFF007200018F33B46
+:1084500028009416FFDC07880008E000CBCC979337
+:10846000FFFC072000022394002A839E0000779DD2
+:10847000001E77BCFFE5C39C7FC0739DFFF0248086
+:1084800000070520000AF3BB280020260007EE00A5
+:1084900084E00628000E86B200007731001E77388F
+:1084A000FFE575B1001E75ACFFE50528000204A4C8
+:1084B0000001C6B477C076B5FFF0F702FF00C6B47E
+:1084C0007400F6B3280087320000F30200FFC738BB
+:1084D0005FC07739FFF0C7383400E0008488F73395
+:1084E000280005200026862A000076A9001EF584B3
+:1084F0004F5876B4FFE58396FFDCF30200FF941635
+:10850000FFBCC71C5A007738FFFAC6306FC07631FF
+:10851000FFF047390000C7383400F682FF00C6304C
+:108520006C00C7386000F6843B6CF72B2800C5A0B0
+:108530005A0075ACFFFA8316FFDC07340001F7051B
+:108540003B6C0720003AF6BB280007200036F03BC2
+:108550002800F3820003F3A328000718001AF5BBD4
+:10856000280007880008E000CBCC9793FFFC072089
+:108570000002F03B2800248000070520000A202686
+:108580000007EE0085D40628000E86B20000773181
+:10859000001E7738FFE575B1001E75ACFFE50528B4
+:1085A000000204A40001C6B477C076B5FFF0F7025C
+:1085B000FF00C6B47400F6B3280087320000F382CF
+:1085C00000FFC7385FC07739FFF0C7383C00E000D4
+:1085D000857CF733280005A00026862E000076ADA6
+:1085E000001E76B4FFE5C520000024000007F3025A
+:1085F00000019316FFA4F7044F588396FFBC248014
+:10860000000EC71C72007738FFFAC6306FC0763193
+:10861000FFF047390000F68200FFC7386C00F68291
+:10862000FF00C6306C00C7386000F6843B6CF72F43
+:10863000280007340001F7053B6C0728003AF6BB19
+:10864000280007280036F03B2800F3020003F32B34
+:10865000280020220007EE008694C6284800063035
+:1086600000268732000076B1001E76B4FFE504A430
+:108670000002042000018396FFA4C7386FC0773939
+:10868000FFF0F682FF00C7386C00C71C7000E000E6
+:108690008650F73328000628002686B2000077317E
+:1086A000001E7738FFE5C6B477C076B5FFF0F70255
+:1086B000FF00C6B47400F6B328009513FFFCF30462
+:1086C0003BB0000000019313FFFC9516FFB4078830
+:1086D0000008E000D42C9793FFFC8516FFB4F0054A
+:1086E000407C8396FFBC23000007F3054258F70443
+:1086F0004250F606425076B1001E76B4FFE5F3060E
+:108700003934F3054244F5054074F3854260F38241
+:108710000006F3854254C7386FC07739FFF0F684FE
+:108720002D3807380001F733280006340001F6051C
+:108730002D38F7062C2876B50002F382001C203273
+:108740000044E600874CB3B67002F0052D38F306FE
+:1087500042449313FFFC07880008E0011F489793E9
+:10876000FFFC8796FFFC8296FFF802140000013C94
+:108770000000000000019293FFFC0290000822100C
+:108780000048F38642449393FFFC07880008E00109
+:1087900020E49793FFFC20220000E60089ED000012
+:1087A0000001F704425400000001203A0000EE00EE
+:1087B00087C90000000107880008E000734C979308
+:1087C000FFFCE00089EC0000000107880008E000E1
+:1087D000CBCC9793FFFC26140020F033280005A093
+:1087E0000002F02F2800F382000024940022F3A757
+:1087F000280004A0001A9496FFD423940022839E9C
+:108800000000779D001E77BCFFE5C39C7FC0739D71
+:10881000FFF07631001E7630FFE506AC000223142F
+:10882000001E7519001EF3A72800F484E0007528C7
+:10883000FFE594A2001CF384E0047495001E74A468
+:10884000FFE59496FFB47495001E74A4FFE594961A
+:10885000FFCC8496FFB493A200208716FFE07395A7
+:10886000001E739CFFE59396FFBC7395001E739CDE
+:10887000FFE59396FFC48396FFBCC73867C077387F
+:10888000FFF0F72F2800F5844F58871A0000C5A085
+:108890005A0075ACFFFAC73857C07738FFF0F73782
+:1088A000280006B400028716FFE42314001A761984
+:1088B000001E7630FFE545AD0000C7384FC0773861
+:1088C000FFF0F7372800871A000006B400028496EC
+:1088D000FFCCC73867C07738FFF0F737280006B4F9
+:1088E00000028716FFE8231400167619001E763062
+:1088F000FFE5C7383FC07738FFF0F7372800871A01
+:10890000000006B40002C73867C07738FFF0F737B9
+:10891000280006B400028716FFEC23140012761913
+:10892000001E7630FFE5C7384FC07738FFF0F737C5
+:108930002800871A000006B400028396FFC4C738D7
+:1089400067C07738FFF0F73728008716FFF006B4C6
+:108950000002C7383FC07738FFF0F7372800F482AD
+:108960000002F4A328000420001823940022839E10
+:108970000000779D001E77BCFFE5C39C7FC0739D00
+:10898000FFF08496FFD4F3A32800F3820001F3A73D
+:1089900028009593FFFCF486E0009493FFFCF38499
+:1089A0004F5C000000019393FFFC07880008E00182
+:1089B00023409793FFFC07880008E00078D897933E
+:1089C000FFFCF4863678F4854244F0054084F68452
+:1089D0004F5CF70200649736000090360004F702FF
+:1089E0000001F7054084F38635ECF3854230879625
+:1089F000FFFC8296FFF802140000013C000000001A
+:108A000000019293FFFC0290000822100090F704EE
+:108A10004260F502000005B80018F6044258000054
+:108A2000000120320007EE008A70C7306000C738AE
+:108A300058000738000E86BA00007739001E7738D4
+:108A4000FFE5C6B477C076B5FFF0F70200FFC6B405
+:108A50007400C0365200470C0001D7000A70203A5B
+:108A60000000E6008A7107300001E0008A18F7056F
+:108A70004258F40442580000000120220007EE0092
+:108A80008D9424940036F604426025140038239413
+:108A90000020063000028732000076B1001E76B456
+:108AA000FFE50630000275B1001EC7386FC0773889
+:108AB000FFF0F72B28008732000075ACFFE5C738C0
+:108AC0005FC07738FFF0F727280024940034063081
+:108AD00000028732000076B1001E76B4FFE5C73889
+:108AE0006FC07738FFF0F727280024940032063053
+:108AF00000028732000076B1001E76B4FFE5C73869
+:108B00006FC07738FFF0F727280024940030063034
+:108B100000028732000076B1001E76B4FFE5C73848
+:108B20006FC07738FFF0F72728002494002E063016
+:108B300000028732000076B1001E76B4FFE5C73828
+:108B40006FC07738FFF0F72728002494002C0630F8
+:108B500000028732000076B1001E76B4FFE5C73808
+:108B60006FC07738FFF0F72728002494002A0630DA
+:108B700000028732000076B1001E76B4FFE5C738E8
+:108B80006FC07738FFF0F7272800063000028732E1
+:108B90000000249400287631001E7630FFE5C738A7
+:108BA00067C07738FFF0F72728009413FFFC951370
+:108BB000FFFC9396FF7C9393FFFC07880008E0007E
+:108BC000D0DC9793FFFCF60442602494007E2514C9
+:108BD000008023940068063000028732000076B1DE
+:108BE000001E76B4FFE50630000275B1001EC738DE
+:108BF0006FC07738FFF0F72B28008732000075AC84
+:108C0000FFE5C7385FC07738FFF0F72728002494C6
+:108C1000007C063000028732000076B1001E76B478
+:108C2000FFE5C7386FC07738FFF0F7272800249496
+:108C3000007A063000028732000076B1001E76B45A
+:108C4000FFE5C7386FC07738FFF0F7272800249476
+:108C50000078063000028732000076B1001E76B43C
+:108C6000FFE5C7386FC07738FFF0F7272800249456
+:108C70000076063000028732000076B1001E76B41E
+:108C8000FFE5C7386FC07738FFF0F7272800249436
+:108C90000074063000028732000076B1001E76B400
+:108CA000FFE5C7386FC07738FFF0F7272800249416
+:108CB0000072063000028732000076B1001E76B4E2
+:108CC000FFE5C7386FC07738FFF0F7272800063078
+:108CD000000287320000249400707631001E763046
+:108CE000FFE5C73867C07738FFF0F72728009513EE
+:108CF000FFFC9396FF749393FFFC07880008E00045
+:108D0000D2589793FFFC8396FF7400000001939361
+:108D1000FFFCF704425823940050C70072009713D9
+:108D2000FFFC9396FF6C9393FFFC07880008E0001C
+:108D3000CF249793FFFC8396FF6CF6864250939363
+:108D4000FFFCF384425876B5001E9393FFFCF704B2
+:108D5000425076B4FFE5C7386FC07739FFF09713FC
+:108D6000FFFC8396FF7C000000019393FFFC0788C3
+:108D70000008E000F3389793FFFC20220000E60093
+:108D80008D9500000001F7044258000000010738EB
+:108D90000001F7054258F704425800000001203A4C
+:108DA0000007EE008DD4F3821770F7042D38F68695
+:108DB0002C2806380001F6052D3877390002F38299
+:108DC000001C20320044E6008DF4B3BA6802E000D3
+:108DD0008DF4F0052D389393FFFCF382001B9393E1
+:108DE000FFFCF38642449393FFFC07880008E001F0
+:108DF0001EC09793FFFC8796FFFC8296FFF8021433
+:108E00000000013C0000000000019293FFFC029072
+:108E1000000822100088F7044250F686425076B5CA
+:108E2000001EF3846F3476B4FFE59396FFC4C73811
+:108E30006FC0869E000C7739FFF0C0367200E600E6
+:108E40008E65F60642A0F70442A076B1001E76B405
+:108E5000FFE5C7386FC07739FFF007380001E00041
+:108E600094E4F7332800F604426024940036851613
+:108E7000FFC423940038063000028732000076B128
+:108E8000001E76B4FFE5852A001C0630000275B18D
+:108E9000001EC7386FC07738FFF09516FFBCF71F6C
+:108EA00028008732000075ACFFE58516FFC4C7387F
+:108EB0005FC07738FFF0F72728002494003406308D
+:108EC00000028732000076B1001E76B4FFE5C73895
+:108ED0006FC07738FFF0F72728002494003206305F
+:108EE00000028732000076B1001E76B4FFE5C73875
+:108EF0006FC07738FFF0F727280024940030063041
+:108F000000028732000076B1001E76B4FFE5C73854
+:108F10006FC07738FFF0F72728002494002E063022
+:108F200000028732000076B1001E76B4FFE5C73834
+:108F30006FC07738FFF0F72728002494002C063004
+:108F400000028732000076B1001E76B4FFE5C73814
+:108F50006FC07738FFF0F72728002494002A0630E6
+:108F600000028732000076B1001E76B4FFE5C738F4
+:108F70006FC07738FFF0F7272800063000028732ED
+:108F80000000249400287631001E7630FFE5C738B3
+:108F900067C07738FFF0F7272800872A00200000F5
+:108FA00000019713FFFC9393FFFC271400209713F5
+:108FB000FFFC07880008E000D0DC9793FFFC839655
+:108FC000FFC400000001871E001000000001203ACD
+:108FD0000000E6008FF0F6820000871E00140000FB
+:108FE0000001203A0000E6008FF420360000F682EF
+:108FF000000120360000E6009041000000018516C7
+:10900000FFC400000001052800109516FFB4951359
+:10901000FFFC07880008E00072509793FFFC8396DE
+:10902000FFB4271400209393FFFC9713FFFC0788DD
+:109030000008E000F9349793FFFCE00094E400009E
+:1090400000018516FFBC00000001202A0000E60098
+:1090500094BC0000000107880008E000CBCC979387
+:10906000FFFCF502000023940062F51F28007595AF
+:10907000001E75ACFFE50620000206B000022314B6
+:10908000001E7399001E739CFFE59396FF7475157F
+:10909000001E7528FFE59516FF7C7395001E739CD6
+:1090A000FFE59396FF8C8516FFC47395001E93967B
+:1090B000FF84852A0034239400629516FFACF033B8
+:1090C00028000520001A9516FF94839E0000779DC6
+:1090D000001E77BCFFE5C39C7FC0739DFFF07495B5
+:1090E000001EF3AB28008516FFC474A4FFE5852A93
+:1090F00000108396FFC49522001C839E00148516E1
+:10910000FF8493A200208716FFE07528FFE59516DF
+:10911000FF84F3844F588516FF74C7385FC07738D3
+:10912000FFF0F7332800871A00009396FFA4C022AF
+:109130003A008396FF7CC73857C07738FFF0F7377F
+:10914000280006B400028716FFE42314001A7619DB
+:10915000001E7630FFE5C7384FC07738FFF0F7378D
+:109160002800871A000006B40002C73867C07738A5
+:10917000FFF0F737280006B400028716FFE8231433
+:1091800000167619001E7630FFE5C7383FC07738E5
+:10919000FFF0F7372800871A000006B40002851692
+:1091A000FF8C8396FF84C73867C07738FFF0F737A6
+:1091B000280006B400028716FFEC2314001276196B
+:1091C000001E7630FFE5C73857C07738FFF0F73715
+:1091D0002800871A000006B40002C73867C0773835
+:1091E000FFF0F73728008716FFF006B40002C738F3
+:1091F0003FC07738FFF0F7372800F5020002F5236B
+:10920000280023940052839E0000779D001E77BCA7
+:10921000FFE5C39C7FC0739DFFF003200018E600AC
+:109220009230F39B2800F7044270E000929CF6060F
+:1092300042728516FFC40000000186AA00200000CB
+:10924000000107340007203A000EE2009294C73470
+:109250006800F5844260F38200FFC72C7000073875
+:10926000002686BA00009716FF747739001E7738FB
+:10927000FFE5C6B477C076B5FFF0C6B43C00203633
+:109280000000470C0001D7000A70203A0000E600F9
+:1092900092C900000001F7044274F606427476B1E8
+:1092A000001E76B4FFE5C7386FC07739FFF0073886
+:1092B0000001F733280007880008E000789C9793A6
+:1092C000FFFCE00094E4000000018516FFA48396F3
+:1092D000FF74C720520074B8FFFAC6240000871E2E
+:1092E0000000769D001E76B4FFE5C5AC520075AC5B
+:1092F000FFFA46310000F50200FFC6305400C738BF
+:109300006FC07739FFF0F682FF00C7386C00C630B7
+:109310007000F61F28008396FF948516FFC4F59F02
+:109320002800872A000400000001203A0024E600FB
+:109330009469F6864098F7046E50862A002CC6A4DD
+:10934000000023940062849E0000779D001E77BC7D
+:10935000FFE5C4A47FC074A5FFF046B50000873ABE
+:109360001DDC76B50002C0327200470C0001D70048
+:109370000A70203A0000F7064098E6009434C3349F
+:109380007000C584000086AA0024F704E000F602FD
+:109390000000C036720005280024E60093C495162C
+:1093A000FF748396FFC400000001869E0028F70426
+:1093B000E00400000001C0367200E60093C82032CD
+:1093C0000000F602000120320000E60093D5000004
+:1093D0000001F58200008516FF74F704E00086AAFC
+:1093E000000000000001C0367200E2009414F60292
+:1093F0000000C0367200E600941C2032000086AAED
+:109400000004F704E00400000001C0367200E2002E
+:10941000941D20320000F602000120320000E60018
+:10942000942D202E0000F5820001202E0000E60081
+:10943000943900000001F4820001F7044F58F49BB6
+:1094400028008396FFC4F686409AC72072007738BA
+:10945000FFFA861E00304739000077390002C7380E
+:109460006800E00094E4F63B2800472500007739C7
+:109470000002C7386800F5020001F53B28000738F4
+:10948000000223940062839E0000779D001E77BC3B
+:10949000FFE5C39C7FC0739DFFF025140062F3BB02
+:1094A0002800852A000077A9001E77BCFFE5C528A3
+:1094B0007FC07529FFF0E00094E4F51B2800839637
+:1094C000FFBC00000001201E0001E60094E4000043
+:1094D000000107880008E000789C9793FFFCF506E0
+:1094E0003560F50542308796FFFC8296FFF802143E
+:1094F0000000013C0000000000019293FFFC02907C
+:109500000008F50642449513FFFC07880008E001B7
+:1095100020E49793FFFC20220000E60096890000DB
+:109520000001F68442540000000120360000EE00E5
+:10953000958DF5864250F7044250762D001E763008
+:10954000FFE526B40001F685425425000007F50525
+:109550004258F6842D38C73867C07739FFF007388E
+:109560000001F72F280006340001F6052D38F70614
+:109570002C2876B50002F502001C20320044E600DB
+:109580009688B5367002E0009688F0052D38F5040F
+:109590004260000000019513FFFC07880008E0000E
+:1095A000B2849793FFFCF6844F5800000001073403
+:1095B0000040C0227200E60095ECF6064276F70401
+:1095C000427476B1001E76B4FFE5C7386FC07739B4
+:1095D000FFF007380001F733280007880008E00093
+:1095E000789C9793FFFCE000968800000001F70448
+:1095F000426000000001C0227200E60096240000D4
+:1096000000019713FFFCF5043BB000000001951327
+:10961000FFFC07880008E000D42C9793FFFCE000D3
+:10962000964000000001C0226A00E600967100002A
+:1096300000019713FFFC07880008E000CC609793B7
+:10964000FFFCF704407C000000010738000197137D
+:10965000FFFCF5044074000000019513FFFC07882F
+:109660000008E000BEF89793FFFCE0009688000039
+:109670000001F5044074000000019513FFFC078809
+:109680000008E000C1B49793FFFC8796FFFC829628
+:10969000FFF802140000013C00000000000192935A
+:1096A000FFFC0290000822100070F6046F34F704EB
+:1096B000426486B2000400000001C0367200E60079
+:1096C0009B1806B0000287360000F404407C76B593
+:1096D000001E76B4FFE5C7386FC07739FFF0C03A97
+:1096E0004200E6009B1824940036F604407423944C
+:1096F0000038063000028732000076B1001E76B4D2
+:10970000FFE50630000275B1001EC7386FC077381C
+:10971000FFF0F71F28008732000075ACFFE5C7385F
+:109720005FC07738FFF0F727280024940034063014
+:1097300000028732000076B1001E76B4FFE5C7381C
+:109740006FC07738FFF0F7272800249400320630E6
+:1097500000028732000076B1001E76B4FFE5C738FC
+:109760006FC07738FFF0F7272800249400300630C8
+:1097700000028732000076B1001E76B4FFE5C738DC
+:109780006FC07738FFF0F72728002494002E0630AA
+:1097900000028732000076B1001E76B4FFE5C738BC
+:1097A0006FC07738FFF0F72728002494002C06308C
+:1097B00000028732000076B1001E76B4FFE5C7389C
+:1097C0006FC07738FFF0F72728002494002A06306E
+:1097D00000028732000076B1001E76B4FFE5C7387C
+:1097E0006FC07738FFF0F727280006300002873275
+:1097F0000000249400287631001E7630FFE5C7383B
+:1098000067C07738FFF0F72728009413FFFC939385
+:10981000FFFC271400209713FFFC07880008E000D6
+:10982000D0DC9793FFFC07880008E000CBCC97932F
+:10983000FFFCF50440749416FFC407200002F03BBF
+:10984000280024800007F40200FF8396FFC49516C9
+:10985000FFBC031C000A20260007EE0098A806188B
+:10986000000E86B200007731001E7738FFE575B133
+:10987000001E75ACFFE503180002C6B477C076B5CC
+:10988000FFF0F702FF00C6B47400F6B32800873279
+:10989000000004A40001C7385FC07739FFF0C73863
+:1098A0004400E0009854F73328008516FFC47495EF
+:1098B000001E74A4FFE58396FFC42314001E7419D0
+:1098C000001E7420FFE5052800269516FF8C85AA4A
+:1098D000000076A9001E76B4FFE5039C0002939673
+:1098E000FFB4061C00027395001E739CFFE593965F
+:1098F000FFAC7395001E739CFFE59396FF9C8396C7
+:10990000FFBC7515001E7528FFE59516FF947515AB
+:10991000001E7528FFE59516FFA48516FFC4C5AC8B
+:109920006FC075ADFFF0F5054260F5044F58F68243
+:1099300000FFC71C52007738FFFA47390000C738CC
+:109940006C00F682FF00C5AC6C00C73858008396E7
+:10995000FF8CF5843B6C8516FFB4F71F2800871633
+:10996000FFE006AC0001F6853B6C8396FFC4C73868
+:109970004FC07738FFF0F72B2800F5044F58871AAF
+:109980000000C01E5200C73847C07738FFF0F733D9
+:109990002800063000028716FFE42314001A769987
+:1099A000001E8396FF9476B4FFE5C7383FC0773832
+:1099B000FFF0F7332800871A000006300002C7388E
+:1099C0006FC07738FFF0F7332800063000028716A3
+:1099D000FFE8231400167699001E76B4FFE585167D
+:1099E000FFAC8396FFA4C73857C07738FFF0F73332
+:1099F0002800871A0000063000028516FF9CC73831
+:109A00006FC07738FFF0F733280006300002871662
+:109A1000FFEC231400127699001E76B4FFE5C738D8
+:109A20003FC07738FFF0F7332800871A0000063070
+:109A300000028396FFC4C7386FC07738FFF0F73352
+:109A400028008716FFF006300002C73857C0773865
+:109A5000FFF0F7332800071C003AF5BB2800071C6D
+:109A60000036F03B2800F5020003E6009AA4F51F3B
+:109A70002800F7044278F606427876B1001E76B4E4
+:109A8000FFE5C7386FC07739FFF007380001F733BB
+:109A9000280007880008E000789C9793FFFCE0000E
+:109AA0009B1800000001F38642449393FFFC078853
+:109AB0000008E0011F489793FFFC25000007F5050B
+:109AC0004258F7044250F606425076B1001E76B472
+:109AD000FFE5F3820006F3854254F5063934F505B7
+:109AE0004244C7386FC07739FFF0F6842D38073805
+:109AF0000001F733280006340001F6052D38F7067B
+:109B00002C2876B50002F382001C20320044E600C7
+:109B10009B18B3B67002F0052D388796FFFC82962D
+:109B2000FFF802140000013C0000000000019293C5
+:109B3000FFFC0290000822100078F38642449393C1
+:109B4000FFFC07880008E00120E49793FFFC202237
+:109B50000000E6009E4100000001F70442540000AE
+:109B60000001203A0000EE009D8524940036F604A2
+:109B7000407425140038063000028732000076B1A8
+:109B8000001E76B4FFE50630000275B1001EC7382E
+:109B90006FC07738FFF0F72B28008732000075ACD4
+:109BA000FFE5C7385FC07738FFF0F7272800249417
+:109BB0000034063000028732000076B1001E76B411
+:109BC000FFE5C7386FC07738FFF0F72728002494E7
+:109BD0000032063000028732000076B1001E76B4F3
+:109BE000FFE5C7386FC07738FFF0F72728002494C7
+:109BF0000030063000028732000076B1001E76B4D5
+:109C0000FFE5C7386FC07738FFF0F72728002494A6
+:109C1000002E063000028732000076B1001E76B4B6
+:109C2000FFE5C7386FC07738FFF0F7272800249486
+:109C3000002C063000028732000076B1001E76B498
+:109C4000FFE5C7386FC07738FFF0F7272800249466
+:109C5000002A063000028732000076B1001E76B47A
+:109C6000FFE5C7386FC07738FFF0F72728000630C8
+:109C7000000287320000249400287631001E7630DE
+:109C8000FFE5C73867C07738FFF0F7272800F3846F
+:109C9000407C000000019393FFFC9513FFFC23948C
+:109CA00000209396FF949393FFFC07880008E00040
+:109CB000D0DC9793FFFC8396FF9400000001939300
+:109CC000FFFC239400689396FF8C9393FFFC078816
+:109CD0000008E000D2589793FFFC8396FF8C0000A9
+:109CE00000019393FFFC9013FFFC23940050939684
+:109CF000FF849393FFFC07880008E000CF2497932C
+:109D0000FFFC8702FF3400000001F7054264F38482
+:109D1000407C000000019393FFFC9713FFFC8396A7
+:109D2000FF84000000019393FFFC8396FF940000E2
+:109D300000019393FFFC07880008E000F7C89793A1
+:109D4000FFFC20220000E6009D5DF3821770F704FF
+:109D500042540000000127380001F7054254939354
+:109D6000FFFCF382001B9393FFFCF3864244939322
+:109D7000FFFC07880008E0011EC09793FFFCE0008D
+:109D80009E4000000001F504407CF4844074C72824
+:109D90005000C724700005B8002686AE0000772D5D
+:109DA000001E7738FFE5C6B477C077B40008703E70
+:109DB000FFE8470C0001D7000A70203A0000F704C2
+:109DC0004F58E6009DFDF60200FFF7044278F606C4
+:109DD000427A76B1001E76B4FFE5C7386FC0773996
+:109DE000FFF007380001F733280007880008E0007B
+:109DF000789C9793FFFCE0009E400000000186AE37
+:109E00000000772D001E7738FFE5C6B477C076B521
+:109E1000FFF0F7020001C7386400F602FF00C6B485
+:109E20006400C7386800F72F28000728000197133F
+:109E3000FFFC9493FFFC07880008E000BEF89793AE
+:109E4000FFFC8796FFFC8296FFF802140000013C9D
+:109E50000000000000019293FFFC02900008221015
+:109E600000D8F38642449393FFFC07880008E00182
+:109E700020E49793FFFC20220000E600A2C9000026
+:109E80000001F704425400000001203A0000EE00F7
+:109E9000A03524940036F6044074251400380630AA
+:109EA00000028732000076B1001E76B4FFE506306E
+:109EB000000275B1001EC7386FC07738FFF0F72B6E
+:109EC00028008732000075ACFFE5C7385FC07738DF
+:109ED000FFF0F72728002494003406300002873270
+:109EE000000076B1001E76B4FFE5C7386FC0773842
+:109EF000FFF0F72728002494003206300002873252
+:109F0000000076B1001E76B4FFE5C7386FC0773821
+:109F1000FFF0F72728002494003006300002873233
+:109F2000000076B1001E76B4FFE5C7386FC0773801
+:109F3000FFF0F72728002494002E06300002873215
+:109F4000000076B1001E76B4FFE5C7386FC07738E1
+:109F5000FFF0F72728002494002C063000028732F7
+:109F6000000076B1001E76B4FFE5C7386FC07738C1
+:109F7000FFF0F72728002494002A063000028732D9
+:109F8000000076B1001E76B4FFE5C7386FC07738A1
+:109F9000FFF0F727280006300002873200002494E3
+:109FA00000287631001E7630FFE5C73867C0773865
+:109FB000FFF0F7272800F384407C00000001939312
+:109FC000FFFC9513FFFC239400209396FF4C939382
+:109FD000FFFC07880008E000D0DC9793FFFC839625
+:109FE000FF4C000000019393FFFC239400509396D4
+:109FF000FF449393FFFC07880008E000D258979332
+:10A00000FFFC8702FF3400000001F7054264F3847F
+:10A01000407C000000019393FFFC9713FFFC8396A4
+:10A02000FF44000000019393FFFC8396FF4CE00087
+:10A03000A2809393FFFCF404407CF6044074F38206
+:10A040000000C7204000C73070000738002686BADD
+:10A0500000007739001E7738FFE5C6B477C077B4C3
+:10A060000008703EFFE8470C0001D7000A70203A54
+:10A070000000E600A0AD9396FF3CF70442A0F60670
+:10A0800042A076B1001E76B4FFE5C7386FC07739BD
+:10A09000FFF007380001F733280007880008E000C8
+:10A0A000789C9793FFFCE000A2C8000000010630F6
+:10A0B00000028732000076B1001E76B4FFE52494DA
+:10A0C000007E25140080239400680630000275B1DC
+:10A0D000001EC7386FC07738FFF0F72B2800873293
+:10A0E000000075ACFFE5C7385FC07738FFF0F72791
+:10A0F00028002494007C063000028732000076B1EC
+:10A10000001E76B4FFE5C7386FC07738FFF0F72739
+:10A1100028002494007A063000028732000076B1CD
+:10A12000001E76B4FFE5C7386FC07738FFF0F72719
+:10A13000280024940078063000028732000076B1AF
+:10A14000001E76B4FFE5C7386FC07738FFF0F727F9
+:10A15000280024940076063000028732000076B191
+:10A16000001E76B4FFE5C7386FC07738FFF0F727D9
+:10A17000280024940074063000028732000076B173
+:10A18000001E76B4FFE5C7386FC07738FFF0F727B9
+:10A19000280024940072063000028732000076B155
+:10A1A000001E76B4FFE5C7386FC07738FFF0F72799
+:10A1B00028000630000287320000249400707631B7
+:10A1C000001E7630FFE5C73867C07738FFF0F72705
+:10A1D00028009413FFFC9513FFFC9396FF34939390
+:10A1E000FFFC07880008E000D0DC9793FFFC839613
+:10A1F000FF34000000019393FFFC239400B093967A
+:10A20000FF2C9393FFFC07880008E000D258979337
+:10A21000FFFC8396FF2C000000019393FFFC8396C4
+:10A22000FF3C000000019393FFFC23940098939659
+:10A23000FF249393FFFC07880008E000CF24979346
+:10A24000FFFCF3820006F38542548702FF34F38655
+:10A2500038A8F3854244F7054264F384407C00004B
+:10A2600000019393FFFC9713FFFC8396FF240000EB
+:10A2700000019393FFFC8396FF3400000001939349
+:10A28000FFFC07880008E000F7C89793FFFC202236
+:10A290000000E600A2A9F3821770F7044254000000
+:10A2A000000127380001F70542549393FFFCF38225
+:10A2B000001B9393FFFCF38642449393FFFC0788B3
+:10A2C0000008E0011EC09793FFFC8796FFFC829672
+:10A2D000FFF802140000013C00000000000192930E
+:10A2E000FFFC02900008F6046F34F704426486B263
+:10A2F000000400000001C0367200E600A3AC06B006
+:10A3000000028736000076B5001E76B4FFE5C73838
+:10A310006FC0F684407C7739FFF0C03A6A00E600EF
+:10A32000A3ACC7346800F5844074F6044F580000AD
+:10A330000001C62C62007630FFFAC5AC700005AC97
+:10A34000002686AE0000772D001E7738FFE54631E7
+:10A350000000C6B477C076B5FFF0F70200FFC63044
+:10A360007400F702FF00C6B47400C6306800F62F10
+:10A370002800F50642449513FFFC07880008E00119
+:10A380001F489793FFFCF704407C0000000107384A
+:10A3900000019713FFFCF5044074000000019513C1
+:10A3A000FFFC07880008E000BEF89793FFFC879643
+:10A3B000FFFC8296FFF802140000013C0000000040
+:10A3C00000019293FFFC0290000822100080F70425
+:10A3D000425800000001203A0000E600A3F4203AB1
+:10A3E0000007F5020001F5054258F7044258000045
+:10A3F0000001203A0007EE00A6F02394001EF604A8
+:10A40000426023140066F4844078063000028732EC
+:10A41000000076B1001E76B4FFE504A400027425A6
+:10A42000001E7420FFE5063000027531001E7528FD
+:10A43000FFE59516FF7CC7386FC07738FFF025140D
+:10A4400000209516FF94F72B280087320000851610
+:10A45000FF7C05A40002C73857C07738FFF0F71F0C
+:10A4600028002394001C063000028732000076B1D9
+:10A47000001E76B4FFE525140050C7386FC077384A
+:10A48000FFF0F71F28002394001A063000028732DD
+:10A49000000076B1001E76B4FFE5C7386FC077388C
+:10A4A000FFF0F71F280023940018063000028732BF
+:10A4B000000076B1001E76B4FFE5C7386FC077386C
+:10A4C000FFF0F71F280023940016063000028732A1
+:10A4D000000076B1001E76B4FFE5C7386FC077384C
+:10A4E000FFF0F71F28002394001406300002873283
+:10A4F000000076B1001E76B4FFE5C7386FC077382C
+:10A50000FFF0F71F28002394001206300002873264
+:10A51000000076B1001E76B4FFE5C7386FC077380B
+:10A52000FFF0F71F28002394001006300002873246
+:10A53000000076AD001E7631001E7630FFE5C7388C
+:10A5400067C07738FFF0F71F280087260000261421
+:10A550000068C73847C07738FFF0F7332800872EE8
+:10A56000000076B4FFE5C7386FC07738FFF0F71BFF
+:10A5700028002314006405AC0002872E000076AD8D
+:10A58000001E76B4FFE5C7386FC07738FFF0F71BC1
+:10A5900028002314006205AC0002872E000076AD6F
+:10A5A000001E76B4FFE5C7386FC07738FFF0F71BA1
+:10A5B00028002314006005AC0002872E000076AD51
+:10A5C000001E76B4FFE5C7386FC07738FFF0F71B81
+:10A5D00028002314005E05AC0002872E000076AD33
+:10A5E000001E76B4FFE5C7386FC07738FFF0F71B61
+:10A5F00028002314005C05AC0002872E000076AD15
+:10A60000001E76B4FFE5C7386FC07738FFF0F71B40
+:10A6100028002314005A05AC0002872E000076ADF6
+:10A62000001E76B4FFE5C7386FC07738FFF0F71B20
+:10A63000280005AC0002872E00002314005875ADD9
+:10A64000001E75ACFFE5C7385FC07738FFF0F71B19
+:10A6500028009613FFFC9516FF8C9513FFFC0788C6
+:10A660000008E000D2589793FFFC8516FF8C00008D
+:10A6700000019513FFFCF5044258000000019513FA
+:10A68000FFFC251400389516FF849513FFFC0788FE
+:10A690000008E000CF249793FFFCF5044258000027
+:10A6A00000019513FFFCF5044264000000019513BE
+:10A6B000FFFC8516FF84000000019513FFFC851642
+:10A6C000FF94000000019513FFFC07880008E000DC
+:10A6D000F7C89793FFFC20220000E600A6F10000D7
+:10A6E0000001F70442580000000107380001F70597
+:10A6F0004258F704425800000001203A0007EE00DB
+:10A70000A730F5021770F7042D38F6862C28063886
+:10A710000001F6052D3877390002F502001C2032C1
+:10A720000044E600A750B53A6802E000A750F005E3
+:10A730002D389513FFFCF502001B9513FFFCF50661
+:10A7400042449513FFFC07880008E0011EC0979360
+:10A75000FFFC8796FFFC8296FFF802140000013C84
+:10A760000000000000019293FFFC029000082210FC
+:10A770000030F6046F34F704426486B2000400002F
+:10A780000001C0367200E600A9F007300002863AE8
+:10A790000000F5820000F684407C7739001E77388F
+:10A7A000FFE5C63077C0F7044074C6B46800763160
+:10A7B000FFF0C60062009616FFF4C738680007383D
+:10A7C000002686BA00007739001E7738FFE5C6B448
+:10A7D00077C077B40008703EFFE8470C0001D7004F
+:10A7E0000A70203A0000E600A834F60200FF831643
+:10A7F000FFF48396FFF4F7044078C6983800C73812
+:10A8000068000738002686BA00007739001E7738BE
+:10A81000FFE5C6B477C076B5FFF0C6B46400C036B5
+:10A820005A00470C0001D7000A70203A0000E600E9
+:10A83000A83D202E0000F5820001202E0000E60039
+:10A84000A875F606427CF704427C76B1001E76B409
+:10A85000FFE5C7386FC07739FFF007380001F733DD
+:10A86000280007880008E000789C9793FFFCE00030
+:10A87000A9F000000001F3044260000000019313FE
+:10A88000FFFC07880008E000CC609793FFFCF4040D
+:10A890004078F7044F58F5044074F384407CF30487
+:10A8A000407CC62072007630FFFAC59C3000C5A8F7
+:10A8B000580005AC002686AE000074AD001E74A4DE
+:10A8C000FFE573AD001E739CFFE59396FFD4C5288A
+:10A8D00072007528FFFA8316FFF48396FFF4463161
+:10A8E000000045290000C7183800C420700004206B
+:10A8F00000267321001EC6B44FC076B5FFF0F48267
+:10A9000000FFC6304C00F382FF00C6B43C00C630E6
+:10A910006800F62F2800872E00007318FFE59316B5
+:10A92000FFCC8316FFD48396FFF4C5284C00C738AC
+:10A9300037C07739FFF0769D001076B5FFF8C7383D
+:10A940004C00C6B47000F6AF28008722000076A144
+:10A95000001E8316FFCCF382FF0076B4FFE5C738F4
+:10A9600037C07739FFF0C7383C00C5287000F523A1
+:10A97000280087220000F304407CC7386FC0773975
+:10A98000FFF0731900109316FFEC7399FFF8C738A6
+:10A990004C00C71C70009716FFDC23140022831A9A
+:10A9A00000007799001E77BCFFE5C3187FC07319BC
+:10A9B000FFF0F3232800F38642449393FFFC0788BB
+:10A9C0000008E0011F489793FFFCF704407C00005B
+:10A9D0000001073800019713FFFCF30440740000E6
+:10A9E00000019313FFFC07880008E000BEF897936E
+:10A9F000FFFC8796FFFC8296FFF802140000013CE2
+:10AA00000000000000019293FFFC02900008221059
+:10AA10000098F30642449313FFFC07880008E00106
+:10AA200020E49793FFFC20220000E600AEE5000042
+:10AA30000001F704425400000001203A0000EE003B
+:10AA4000AD8927380001F70542542394001EF6040F
+:10AA50004260249400669496FF64F3044078249442
+:10AA600000209496FF94063000028732000076B1F1
+:10AA7000001E76B4FFE5031800029316FF747419E4
+:10AA8000001E7420FFE505980002063000027531B3
+:10AA9000001EC7386FC07738FFF0F72728008732CD
+:10AAA00000007528FFE5C73857C07738FFF0F71F5B
+:10AAB00028002394001C063000028732000076B183
+:10AAC000001E76B4FFE58516FF64C7386FC077387F
+:10AAD000FFF0F71F28002394001A06300002873287
+:10AAE000000076B1001E76B4FFE5C7386FC0773836
+:10AAF000FFF0F71F28002394001806300002873269
+:10AB0000000076B1001E76B4FFE5C7386FC0773815
+:10AB1000FFF0F71F2800239400160630000287324A
+:10AB2000000076B1001E76B4FFE5C7386FC07738F5
+:10AB3000FFF0F71F2800239400140630000287322C
+:10AB4000000076B1001E76B4FFE5C7386FC07738D5
+:10AB5000FFF0F71F2800239400120630000287320E
+:10AB6000000076B1001E76B4FFE5C7386FC07738B5
+:10AB7000FFF0F71F280023940010063000028732F0
+:10AB8000000076AD001E7631001E7630FFE5C73836
+:10AB900067C07738FFF0F71F2800871A00002614D7
+:10ABA0000068C73847C07738FFF0F7332800872E92
+:10ABB000000076B4FFE5C7386FC07738FFF0F72B99
+:10ABC0002800231400649316FF6405AC0002872E4E
+:10ABD000000076AD001E76B4FFE5C7386FC0773849
+:10ABE000FFF0F71B2800249400629496FF6405ACE4
+:10ABF0000002872E000076AD001E76B4FFE5C73850
+:10AC00006FC07738FFF0F7272800251400609516ED
+:10AC1000FF6405AC0002872E000076AD001E76B4FE
+:10AC2000FFE5C7386FC07738FFF0F72B28002314F3
+:10AC3000005E9316FF6405AC0002872E000076AD1F
+:10AC4000001E76B4FFE5C7386FC07738FFF0F71BFA
+:10AC500028002494005C9496FF6405AC0002872EC3
+:10AC6000000076AD001E76B4FFE5C7386FC07738B8
+:10AC7000FFF0F72728002514005A9516FF6405AC4D
+:10AC80000002872E000076AD001E76B4FFE5249406
+:10AC90000050C7386FC07738FFF0F72B2800231417
+:10ACA000005805AC0002872E00009316FF6475ADB6
+:10ACB000001E75ACFFE5C7385FC07738FFF0F71BA3
+:10ACC00028009613FFFC9496FF8C9493FFFC078852
+:10ACD0000008E000D2589793FFFC8516FF8C2314E0
+:10ACE00000389513FFFC278000079793FFFC93160D
+:10ACF000FF849313FFFC07880008E000CF2497939C
+:10AD0000FFFC27800007F7854258278000079793AC
+:10AD1000FFFCF4844264000000019493FFFC85165C
+:10AD2000FF84000000019513FFFC8316FF940000D0
+:10AD300000019313FFFC07880008E000F7C8979311
+:10AD4000FFFC20220000E600AD5D00000001F704DA
+:10AD500042580000000107380001F7054258F70487
+:10AD60002D38F6862C2806380001F6052D3877395F
+:10AD70000002F482001C20320044E600AEE4B4BAC3
+:10AD80006802E000AEE4F0052D38F7044078F58461
+:10AD90004F580738001686BA0000F4063B90773902
+:10ADA000001E7738FFE5C6B477C076B4FFF076357D
+:10ADB0000006A72E6002C52C600076A9001E76B49E
+:10ADC000FFE5C7386FC07739FFF077390003C73820
+:10ADD00040000738000286BA00007739001E773835
+:10ADE000FFE5C6B477C073B7FFF0EE00AE55951619
+:10ADF000FF64A72E600276A9001E76B4FFE5C7386F
+:10AE00006FC07739FFF077390003C738400086BA42
+:10AE10000004231400887739001E7738FFE5C6B494
+:10AE200077C076B5FFF0A6AA6802771D0003C73881
+:10AE3000680027380008853A000484BA0000000042
+:10AE40000001951A0004949A00008596FF7CE000AA
+:10AE5000AE78000000018496FF64A72E600276A5FC
+:10AE6000001E76B4FFE5C7386FC07739FFF0773939
+:10AE70000003C738400085BA00048516FF64F60653
+:10AE80003B90872A000076A9001E76B4FFE5C738FC
+:10AE90006FC07739FFF077390003A6BA6002201E31
+:10AEA0000000C73860007739001E7738FFE5C6B468
+:10AEB00077C0EE00AEC976B5FFF08316FF780000CC
+:10AEC00000017719FFF0C6B868008496FF6400009F
+:10AED0000001C72468009713FFFC07880008C12CF5
+:10AEE00000009793FFFC8796FFFC8296FFF8021400
+:10AEF0000000013C0000000000019293FFFC029062
+:10AF0000000822100010F704408400000001203ADD
+:10AF10000000E600AF3CF60642B8F70442B876B14E
+:10AF2000001E76B4FFE5F3063678F3054244C738D1
+:10AF30006FC07739FFF007380001F7332800F704B6
+:10AF40004F5CF384425C833A0004C43800009316DB
+:10AF5000FFEC771D0001C73838007739000204B8CC
+:10AF6000000C8316FFEC00000001C01E3200EC0054
+:10AF7000B070C5040000A6A24802F704E000F58204
+:10AF80000000C0367200E600AFA8C620480086B2B6
+:10AF90000004F704E00400000001C0367200E6007F
+:10AFA000AFAC202E0000F5820001202E0000E6004C
+:10AFB000AFB900000001F502000086B20000F704FE
+:10AFC000E00000000001C0367200E200AFF4F5823C
+:10AFD0000000C0367200E600AFFC202E000086B2F2
+:10AFE0000004F704E00400000001C0367200E20033
+:10AFF000AFFD202E0000F5820001202E0000E600AB
+:10B00000B00D202A0000F5020001202A0000E60011
+:10B01000B05900000001F7047AD000000001203A86
+:10B020000000E600B064C7204800873A0008F60632
+:10B03000409877390002A6BA6002C73860007739B5
+:10B04000001E7738FFE5C6B477C076B5FFF020362E
+:10B050000000E600B0640000000104A4000CE00061
+:10B06000AF60039C00018316FFEC00000001C01ECE
+:10B070003200EC00B104F3063678F6844F5C771D9D
+:10B080000001C7383800773900020738000CC6B411
+:10B09000700087360008F6844F5877390006C6B42A
+:10B0A00070009693FFFC9396FFF407880008E00079
+:10B0B000FA989793FFFC20220000F684426C839656
+:10B0C000FFF4470C0001D7000A70C71C7000F70599
+:10B0D000425C06B40001F7042D38F685426CF68612
+:10B0E0002C2806380001F6052D3877390002F302C6
+:10B0F000001C20320044E600B108B33A6802E000C8
+:10B10000B108F0052D38F30542448796FFFC82967E
+:10B11000FFF802140000013C0000000000019293BF
+:10B12000FFFC02900008F4020000C5A00000F682B7
+:10B130000770F7046E5020360000E600B16D063847
+:10B14000001C8732000000000001C4207000C022F3
+:10B150007200E400B15D0000000105AC000126B4FE
+:10B16000000120360000E600B14006300004C42093
+:10B170005800C0225A00E400B18100000001042000
+:10B1800000018796FFFC8296FFF802140000013C44
+:10B190000000000000019293FFFC02900008078865
+:10B1A0000008E00078D89793FFFC07880008E000CB
+:10B1B000B11C9793FFFCF704409400000001C022EB
+:10B1C0007200E600B1EDF4054090F7046E50000007
+:10B1D000000186BA1DDCF582000106B4000196BAB2
+:10B1E0001DDC873A1DDCE000B1F0F5857AD0F00572
+:10B1F0007AD0F5844090F0054084F5854094F5863A
+:10B20000E0009593FFFC07880008E000D5A0979325
+:10B21000FFFCF7046E50F405408485BA1DDC000085
+:10B220000001F5853B64F584E000F005425C95BAC9
+:10B230000010F584E004F6862C2895BA0014F70473
+:10B240002D38F5863A4CF585424406380001F6055E
+:10B250002D3877390002F582001C20320044E600C8
+:10B26000B268B5BA6802F0052D38F58635ECF5857B
+:10B2700042308796FFFC8296FFF802140008013CDA
+:10B280000000000000019293FFFC029000082210D1
+:10B2900000C8F30200009316FF94248000089496DF
+:10B2A000FF84238000078316FF940000000193169B
+:10B2B000FF54201E0007EE00B564C71C38008496BA
+:10B2C000000000000001C72470000738002686BA7D
+:10B2D0000000F5844F587739001E7738FFE5C6B473
+:10B2E00077C076B5FFF0F70200FFC6B67400E6003F
+:10B2F000B32D20360001E600B32D77350006A6BA3F
+:10B300005802C73858007639001E7630FFE5C6B4BB
+:10B3100067C076B5FFF020360002E600B331C6B84C
+:10B320000000C72C0000E000B330C6B80000F6846F
+:10B330004F58F7044F58C5340000C02A7200E60089
+:10B34000B55D00000001F6843BBCF30200009316DB
+:10B35000FF3C0428001CF7043BB800000001C03685
+:10B360007200EC00B4409696FFAC77350001C73808
+:10B37000680077390002F4863BB4C63848000630CE
+:10B38000000CC30400009316FF3486B20000872A25
+:10B39000001C8596FF3CC0367200E600B3C0202E2C
+:10B3A000000086B20004872A002000000001C03699
+:10B3B0007200E600B3C0202E0000F5820001202EAE
+:10B3C0000000E600B3D100000001F4820000949672
+:10B3D000FF3486B200008722000000000001C03662
+:10B3E0007200E200B40CF5820000C0367200E60084
+:10B3F000B414202E000086B200048722000400004E
+:10B400000001C0367200E200B415202E0000F58263
+:10B410000001202E0000E600B42500000001F30228
+:10B4200000019316FF348496FF34000000012026AB
+:10B430000000E600B44000000001F3020001931692
+:10B44000FF3C8496FF3C0000000120260000E6003F
+:10B45000B481F60200018716FFACF3063BB476B95F
+:10B460000001C6B4700076B50002C6B4300006B460
+:10B47000001486B600009716FFB0E000B4F496966C
+:10B48000FFB4271400549713FFFC9413FFFCF486B9
+:10B490003BB49493FFFC9396FF4C9516FF440788AA
+:10B4A0000008E00125689793FFFC8396FF4C851602
+:10B4B000FF4420220000E600B4F1F60200018716E6
+:10B4C000FFACF3063BB476B90001C6B4700076B5A4
+:10B4D0000002C6B4300006B4001486B60000971609
+:10B4E000FFB09696FFB4F7053BBCE000B4F82032FD
+:10B4F0000000F602000020320000E600B52D2714FF
+:10B5000000088496FF5400000001C72470008316D1
+:10B51000FFB404A400049496FF548496FF94933AD5
+:10B52000FFC004A40001E000B5549496FF94831674
+:10B53000FF5400000001C7187000F4844F5803182E
+:10B5400000049316FF548316FF9494BAFFC00318A7
+:10B5500000019316FF949516FF3C9396FF8CE00034
+:10B56000B2B0039C00018496FF94000000012026E5
+:10B570000000E600B584F3820001F4044F58E000B7
+:10B58000BEE4000000018316FFB88496FF9400001B
+:10B590000001C01E4A00EC00B5CC9316FF7C269437
+:10B5A00000048736FFC08316FF7C00000001C03A0C
+:10B5B0003200E600BB98039C00018496FF940000D3
+:10B5C0000001C01E4A00EC00B5A106B40004F4045A
+:10B5D0004F588316FF7C00000001C01A4200E600AD
+:10B5E000BA2DF48200009496FF7423800007201E79
+:10B5F0000007EE00B748C71C38008316FF7C000028
+:10B600000001C71870000738002686BA0000F584CC
+:10B610004F587739001E7738FFE5C6B477C076B546
+:10B62000FFF0F70200FFC6B67400E600B6692036E8
+:10B630000001E600B66977350006A6BA5802C73899
+:10B6400058007639001E7630FFE5C6B467C076B57F
+:10B65000FFF020360002E600B66DC6B80000C72C29
+:10B660000000E000B66CC6B80000F6844F58F7043E
+:10B670004F58C5340000C02A7200E600B741C584A7
+:10B6800000008496FF7486AA001C8316FF3CF60215
+:10B69000000004A400019496FF74871A001C04A8FB
+:10B6A000001C9496FF34C0367200E600B6CC041835
+:10B6B000001C86AA0020871A002000000001C03666
+:10B6C0007200E600B6D020320000F60200012032FF
+:10B6D0000000E600B6DD00000001F58200008316E0
+:10B6E000FF3487220000869A000000000001C03667
+:10B6F0007200E200B71CF6020000C0367200E600DD
+:10B70000B72420320000869A00048722000400003B
+:10B710000001C0367200E200B72520320000F602B8
+:10B72000000120320000E600B735202E0000F5822F
+:10B730000001202E0000E600B740000000019396B3
+:10B74000FF84E000B5EC039C00018496FF7483162F
+:10B75000FF9400000001C0263200E600BB982300E1
+:10B7600000088496FF8400000001C0263200E60035
+:10B77000BB99F6020000F684407CF7044074C6B41E
+:10B780006800C73868000738002686BA0000773995
+:10B79000001E7738FFE5C6B477C077B40008703E66
+:10B7A000FFE8470C0001D7000A70203A0000E600CD
+:10B7B000B804F58200FF8496FF848316FF8C000096
+:10B7C0000001C72432008496FF7CC7387000C7246C
+:10B7D00070000738002686BA00007739001E7738D7
+:10B7E000FFE5C6B477C076B5FFF0C6B45C00C036DE
+:10B7F0006200470C0001D7000A70203A0000E60002
+:10B80000B80D20320000F602000120320000E600F0
+:10B81000BB9823800007201E0007EE00B8C8C71C95
+:10B8200038008316000000000001C71870000738B8
+:10B83000002686BA0000F5844F587739001E773805
+:10B84000FFE5C6B477C076B5FFF0F70200FFC6B6D5
+:10B850007400E600B89120360001E600B891773513
+:10B860000006A6BA5802C73858007639001E76304E
+:10B87000FFE5C6B467C076B5FFF020360002E600EB
+:10B88000B895C6B80000C72C0000E000B894C6B850
+:10B890000000F6844F58F7044F58C5340000C02A02
+:10B8A0007200E600B8C1000000019513FFFC9396FA
+:10B8B000FF4C07880008E000CC609793FFFC83965C
+:10B8C000FF4CE000B814039C00018496FF848316AB
+:10B8D000FF8CF384407CF5044074C4A43200949639
+:10B8E000FF348316FF34C59C3800C5A8580005AC4A
+:10B8F000002686AE0000772D001E7738FFE5742DF8
+:10B90000001E7420FFE5739D0010739DFFF8C4A412
+:10B9100030009496FF3C8316FF7CC6B477C0C49871
+:10B9200048009496FF3C04A400269496FF3C73259F
+:10B93000001E7318FFE59316FF6C74A5001E949605
+:10B94000FF6474A4FFE59496FF648316FF7CF4847F
+:10B950004F5876B5FFF0C6184A007630FFFA4631E8
+:10B960000000F30200FFC6303400F482FF00C6B4CA
+:10B970004C00C6306800F62F2800872E0000831682
+:10B98000FF34C73847C07739FFF07319001093169A
+:10B99000FF347499FFF8F30200FFC7383400C7245E
+:10B9A00070009716FF34249400CA84A6000077A57F
+:10B9B000001E77BCFFE5C4A47FC074A5FFF083160A
+:10B9C000FF3CF4AF2800F4844F58871A0000C528C4
+:10B9D0004A007528FFFA8316FF6C45290000F4829F
+:10B9E00000FFC5284C008496FF3CC73837C0773924
+:10B9F000FFF0F302FF00C7383400C5287000F527B8
+:10BA00002800872600008316FF648416FF7CC73851
+:10BA100037C07739FFF0F48200FFC7384C00831637
+:10BA2000FF3CC39C7000E000BEE4F39B2800F704D9
+:10BA3000407CF6044074C7387000C7307000073887
+:10BA4000002686BA00007739001E7738FFE5C6B4B5
+:10BA500077C077B40008703EFFE8470C0001D700BC
+:10BA60000A70203A0000E600BA7D25800007E00059
+:10BA7000BEE404200040E000BAD8C42C0000C73067
+:10BA80004200849600007538FFFA0624000A202E32
+:10BA90000007EE00BAD40730000E86BA00007739EE
+:10BAA000001E7738FFE5C6B477C076B5FFF0F70221
+:10BAB00000FFC6B4740047290000C0367200470C6E
+:10BAC0000001203A0000E600BA7406300002E000EF
+:10BAD000BA8C05AC0001F402000807200007203AE8
+:10BAE000000EE200BBA4C5A0400083160000F504D0
+:10BAF000407CF48200FFF6044F58C598580005AC0E
+:10BB0000002686AE0000772D001E7738FFE5C618A8
+:10BB100062007630FFFA46310000C6304C00C6B4F1
+:10BB200077C076B5FFF0772900107739FFF8C6B4F3
+:10BB30004C00C7386800F72F2800F5844074C528EA
+:10BB40005000C5AC500005AC002686AE0000772D35
+:10BB5000001E7738FFE5752D001E7528FFE5C6B479
+:10BB600077C076B5FFF0F702FF00C6B47400C630A8
+:10BB70006800F62F2800872E000076A1001076B509
+:10BB8000FFF8C73857C07739FFF0C7384C00C6B444
+:10BB90007000E000BBF8F6AF2800F4044F58E00056
+:10BBA000BEE404200040F6044F5883160000F7045A
+:10BBB000407CF5844074C61862007630FFFAC738BE
+:10BBC0007000C5AC700005AC002686AE0000772D75
+:10BBD000001E7738FFE546310000C6B477C076B561
+:10BBE000FFF0F70200FFC6307400F702FF00C6B492
+:10BBF0007400C6306800F62F280023800007201E3E
+:10BC00000007EE00BEE0C71C38008496000000006C
+:10BC10000001C72470000738002686BA0000F584AA
+:10BC20004F587739001E7738FFE5C6B477C076B530
+:10BC3000FFF0F70200FFC6B67400E600BC792036BC
+:10BC40000001E600BC7977350006A6BA5802C7386D
+:10BC500058007639001E7630FFE5C6B467C076B569
+:10BC6000FFF020360002E600BC7DC6B80000C72CFD
+:10BC70000000E000BC7CC6B80000F6844F58F70412
+:10BC80004F58C5340000C02A7200E600BED906A88D
+:10BC9000001C83160000000000019313FFFC969324
+:10BCA000FFFCF4863BB49493FFFC9396FF4C9516EF
+:10BCB000FF449696FF4007880008E00123409793D1
+:10BCC000FFFCF3044F5CF48200009496FF5C8696C0
+:10BCD000FF408396FF4C8516FF449316FF34861A67
+:10BCE00000089696FF3C871A000400000001C0324D
+:10BCF0007200EC00BDB89616FF9C77310001C73882
+:10BD0000600077390002C63830000630000C86B279
+:10BD10000000872A001C8596FF5CC0367200E60092
+:10BD2000BD40C404000086B20004872A0020000041
+:10BD30000001C0367200E600BD44202E0000F582EE
+:10BD40000001202E0000E600BD5100000001F402B9
+:10BD500000008316FF3C86B20000871A0000000036
+:10BD60000001C0367200E200BD90F5820000C036CE
+:10BD70007200E600BD98202E000086B20004871AEB
+:10BD8000000400000001C0367200E200BD99202EC0
+:10BD90000000F5820001202E0000E600BDA920224F
+:10BDA0000000F402000120220000E600BDB80000FF
+:10BDB0000001F48200019496FF5C8316FF5C000092
+:10BDC0000001201A0000E600BDF9F6020001871606
+:10BDD000FF9C8496FF3476B90001C6B4700076B536
+:10BDE0000002C6B4480006B4001486B600009716D8
+:10BDF000FFA0E000BE709696FFA42714006497137E
+:10BE0000FFFC8316FF3C000000019313FFFC8496A7
+:10BE1000FF34000000019493FFFC9396FF4C9516AD
+:10BE2000FF4407880008E00125689793FFFC83968C
+:10BE3000FF4C8516FF4420220000E600BE71F6028A
+:10BE400000008716FF9C8316FF3476B90001C6B444
+:10BE5000700076B50002C6B4300006B4001486B691
+:10BE600000009716FFA09696FFA4971A0008F60206
+:10BE7000000120320000E600BE99F606429CF7045D
+:10BE8000429C76B1001E76B4FFE5C7386FC07739A3
+:10BE9000FFF007380001F7332800F7044F5800007F
+:10BEA0000001C72872007738FFFA4739000097135E
+:10BEB000FFFC0728001C9713FFFCF4844F5C000074
+:10BEC00000019493FFFC9396FF4C07880008E00163
+:10BED00023409793FFFC8396FF4CE000BBFC039C40
+:10BEE0000001841600008796FFFC8296FFF802147A
+:10BEF0000004013C0000000000019293FFFC02904E
+:10BF0000000822100060851600008616000406A8AE
+:10BF10000018C7306000C5B8680020320007EE0086
+:10BF2000BF64072C000E86BA00007739001E7738F0
+:10BF3000FFE5C6B477C076B5FFF0F70200FFC6B4E0
+:10BF4000740020360000470C0001D7000A70203A28
+:10BF50000000E600BF6105AC0002E000BF1806303B
+:10BF6000000120320007EE00C04C06A80016F505BF
+:10BF70004074F605407CF3020006F3054254961324
+:10BF8000FFFC052800029516FFC49513FFFC2394BF
+:10BF900000209396FFBC9393FFFC9616FFAC078896
+:10BFA0000008E000D0DC9793FFFC8496FFC42314C4
+:10BFB00000389493FFFC9316FFB49313FFFC07889B
+:10BFC0000008E000D2589793FFFC8702FF348616E2
+:10BFD000FFACF70542649613FFFC9713FFFC8396B2
+:10BFE000FFB4000000019393FFFC8496FFBC0000A7
+:10BFF00000019493FFFC07880008E000F7C89793BE
+:10C00000FFFC20220000E600C01DF3063AD8F7042A
+:10C0100042540000000127380001F7054254F3059F
+:10C020004244F38217709393FFFCF482001B9493B5
+:10C03000FFFCF30642449313FFFC07880008E0016D
+:10C040001EC09793FFFCE000C1A0000000018736EE
+:10C050000000F5844F58F4063B7076B5001E76B4A8
+:10C06000FFE5C7386FC07738FFF076390006A72E96
+:10C070006002C52C600076A9001E76B4FFE5C738C3
+:10C080006FC07739FFF077390003C73840000738B1
+:10C09000000286BA00007739001E7738FFE5C6B483
+:10C0A00077C076B7FFF0EE00C1159696FF9CA72EDD
+:10C0B000600276A9001E76B4FFE58396FF9CC73820
+:10C0C0006FC07739FFF077390003C738400086BA70
+:10C0D0000004249400607739001E7738FFE5C6B469
+:10C0E00077C076B5FFF0A6AA6802771D0003C738AF
+:10C0F00068002738000883BA0004833A0000000073
+:10C10000000193A60004932600008596FFA4E0009A
+:10C11000C13823000007A72E600276A9001E76B45E
+:10C12000FFE5C7386FC07739FFF077390003C738AC
+:10C13000400085BA0004230000079313FFFC872A00
+:10C14000000076A9001E76B4FFE58396FF9CF606F4
+:10C150003B70C7386FC07739FFF077390003A6BA54
+:10C160006002201E0000C73860007739001E773853
+:10C17000FFE5C6B477C0EE00C18D76B5FFF08496BA
+:10C18000FFA0000000017725FFF0C6B86800C728AF
+:10C1900068009713FFFC07880008C12C00009793E4
+:10C1A000FFFC8796FFFC8296FFF802140008013C12
+:10C1B0000000000000019293FFFC02900008221092
+:10C1C000007025000007202A0007EE00C3B8C7282A
+:10C1D00050008316000000000001C71870000738E7
+:10C1E000002686BA0000F5844F587739001E77384C
+:10C1F000FFE5C6B477C076B5FFF0F70200FFC6B61C
+:10C200007400E600C23D20360001E600C23D7735ED
+:10C210000006A6BA5802C73858007639001E763094
+:10C22000FFE5C6B467C076B5FFF020360002E60031
+:10C23000C24DC03A5A00E000C248C72C0000F704C3
+:10C240004F58F5844F5800000001C03A5A00E600EC
+:10C25000C3B1F4863B908396000000000001069C69
+:10C2600000168736000076B5001E76B4FFE5C738A5
+:10C270006FC07738FFF076390006A72E6002C52C14
+:10C28000600076A9001E76B4FFE5C7386FC0773925
+:10C29000FFF077390003C73848000738000286BA34
+:10C2A00000007739001E7738FFE5C6B477C076B74F
+:10C2B000FFF0EE00C3219696FF8CA72E600276A9B0
+:10C2C000001E76B4FFE58316FF8CC7386FC0773940
+:10C2D000FFF077390003C738480086BA0004249479
+:10C2E00000707739001E7738FFE5C6B477C076B5A1
+:10C2F000FFF0A6AA680277190003C738680027383C
+:10C30000000883BA0004833A00000000000193A6ED
+:10C310000004932600008616FF94E000C34400004A
+:10C320000001A72E600276A9001E76B4FFE5F30691
+:10C330003B90C7386FC07739FFF077390003C738B3
+:10C340003000863A0004872A000076A9001E76B4E1
+:10C35000FFE58396FF8CF4863B90C7386FC0773932
+:10C36000FFF077390003A6BA4802201E0000C73844
+:10C3700048007739001E7738FFE5C6B477C0EE0075
+:10C38000C39576B5FFF08316FF9000000001771982
+:10C39000FFF0C6B86800C72868009713FFFC07883D
+:10C3A0000008C13000009793FFFCE000C5C4000006
+:10C3B0000001E000C1C40528000183960000F4825A
+:10C3C0000006F4854254F60442602514001E23142E
+:10C3D00000209316FFACF3854078063000028732C8
+:10C3E000000076B1001E76B4FFE50630000275B19C
+:10C3F000001EC7386FC07738FFF0F71B2800873260
+:10C40000000075ACFFE5C7385FC07738FFF0F72B49
+:10C4100028002514001C063000028732000076B187
+:10C42000001E76B4FFE5C7386FC07738FFF0F72BF2
+:10C4300028002514001A063000028732000076B169
+:10C44000001E76B4FFE5C7386FC07738FFF0F72BD2
+:10C45000280025140018063000028732000076B14B
+:10C46000001E76B4FFE5C7386FC07738FFF0F72BB2
+:10C47000280025140016063000028732000076B12D
+:10C48000001E76B4FFE5C7386FC07738FFF0F72B92
+:10C49000280025140014063000028732000076B10F
+:10C4A000001E76B4FFE5C7386FC07738FFF0F72B72
+:10C4B000280025140012063000028732000076B1F1
+:10C4C000001E76B4FFE5C7386FC07738FFF0F72B52
+:10C4D0002800063000028732000025140010763153
+:10C4E000001E7630FFE5C73867C07738FFF0F72BBE
+:10C4F0002800071C00029713FFFC2394005093961A
+:10C50000FFA49393FFFC07880008E000D25897939C
+:10C51000FFFC8496FFA4231400389493FFFC27802B
+:10C5200000079793FFFC9316FF9C9313FFFC07886B
+:10C530000008E000CF249793FFFC8702FF34278098
+:10C540000007F7854258F705426427800007979354
+:10C55000FFFC9713FFFC8396FF9C00000001939360
+:10C56000FFFC8496FFAC000000019493FFFC078859
+:10C570000008E000F5F49793FFFC20220000E6009D
+:10C58000C59500000001F70442580000000107387B
+:10C590000001F7054258F7042D38F30639C0F305BA
+:10C5A0004244F6862C2806380001F6052D387739E6
+:10C5B0000002F382001C20320044E600C5C4B3BA76
+:10C5C0006802F0052D388796FFFC8296FFF802146A
+:10C5D0000004013C0000000000019293FFFC029067
+:10C5E000000825000007F7044074F6844F58F6044D
+:10C5F0004260C7386A0075B8FFFA0630000A202A80
+:10C600000007EE00C6480730000E86BA00007739F2
+:10C61000001E7738FFE5C6B477C076B5FFF0F702A5
+:10C6200000FFC6B47400472D0000C0367200470CEE
+:10C630000001203A0000E600C64CC3280000063086
+:10C640000002E000C5FC05280001F3020008C5183F
+:10C650003000F3844260F6044F58F704407CF484C1
+:10C660004074C51C50000528002685AA00007429C6
+:10C67000001E7420FFE5C61C62007630FFFAC6B8C3
+:10C680007000C4A4680004A4002676A5001E76B439
+:10C69000FFE5773900107739FFF846310000C5AC67
+:10C6A00047C075ADFFF0F40200FFC5AC4400C738C9
+:10C6B0005800F72B28008726000075A5001EC630FD
+:10C6C000440075ACFFE5C7386FC07739FFF0F682DC
+:10C6D000FF00C7386C00C6307000F6272800872698
+:10C6E00000007699001076B5FFF8C7385FC077393B
+:10C6F000FFF0C7384400C6B47000F6A72800939333
+:10C70000FFFCF3843BB0000000019393FFFC07881B
+:10C710000008E000D42C9793FFFCF704407C000055
+:10C720000001073800019713FFFCF38440740000F8
+:10C7300000019393FFFC07880008E000BEF8979380
+:10C74000FFFC8796FFFC8296FFF802140004013C70
+:10C750000000000000019293FFFC02900008879601
+:10C76000FFFC8296FFF802140008013C0000000064
+:10C7700000019293FFFC029000088796FFFC8296CE
+:10C78000FFF802140004013C000000000001929335
+:10C79000FFFC029000088796FFFC8296FFF80214C7
+:10C7A0000000013C0000000000019293FFFC029099
+:10C7B0000008F70642309713FFFCF7063560971321
+:10C7C000FFFC07880008E00014F49793FFFCF706CD
+:10C7D00042309713FFFCF70635EC9713FFFC0788F0
+:10C7E0000008E00014F49793FFFCF7064244971307
+:10C7F000FFFCF70636789713FFFC07880008E00077
+:10C8000014F49793FFFCF70642449713FFFCF706D6
+:10C8100037049713FFFC07880008E00014F497938F
+:10C82000FFFCF70642449713FFFCF7063790971377
+:10C83000FFFC07880008E00014F49793FFFCF7065C
+:10C8400042449713FFFCF706381C9713FFFC078838
+:10C850000008E00014F49793FFFCF7064244971396
+:10C86000FFFCF70638A89713FFFC07880008E000D4
+:10C8700014F49793FFFCF70642449713FFFCF70666
+:10C8800039349713FFFC07880008E00014F49793ED
+:10C89000FFFCF70642449713FFFCF70639C09713D5
+:10C8A000FFFC07880008E00014F49793FFFCF706EC
+:10C8B00042449713FFFCF7063A4C9713FFFC078896
+:10C8C0000008E00014F49793FFFCF7064244971326
+:10C8D000FFFCF7063AD89713FFFC07880008E00032
+:10C8E00014F49793FFFC8796FFFC8296FFF80214DE
+:10C8F0000000013C0000000000019293FFFC029048
+:10C90000000885960000F5063B90872E000076AD66
+:10C91000001E76B4FFE5C7386FC07739FFF077396E
+:10C920000003C73850000738000286BA0000773984
+:10C93000001E7738FFE5C6B477C07637FFF0EE000B
+:10C94000C99500000001872E000076AD001E76B468
+:10C95000FFE5C7386FC07739FFF077390003C73874
+:10C96000500086BA00047739001E7738FFE5C6B458
+:10C9700077C076B5FFF0A6AE680277310003C738FE
+:10C9800068002738000884BA0004843A0000E000F8
+:10C99000C9B4C5240000872E000076AD001E76B411
+:10C9A000FFE5C7386FC07739FFF077390003C73824
+:10C9B0005000853A0004872E000076AD001E76B444
+:10C9C000FFE520320000F6063B90C7386FC077398C
+:10C9D000FFF077390003A6BA6002C73860007739E4
+:10C9E000001E7738FFE5C6B477C0EE00C9F976B50A
+:10C9F000FFF07721FFF0C6B86800C72C68009713D6
+:10CA0000FFFC07880008C12800009793FFFC879669
+:10CA1000FFFC8296FFF802140004013C00000000B5
+:10CA200000019293FFFC0290000885960000F50635
+:10CA30003B70872E000076AD001E76B4FFE5C73848
+:10CA40006FC07739FFF077390003C73850000738D7
+:10CA5000000286BA00007739001E7738FFE5C6B4B9
+:10CA600077C07637FFF0EE00CABD00000001872EC8
+:10CA7000000076AD001E76B4FFE5C7386FC0773989
+:10CA8000FFF077390003C738500086BA00047739C1
+:10CA9000001E7738FFE5C6B477C076B5FFF0A6AEC6
+:10CAA000680277310003C73868002738000884BA65
+:10CAB0000004843A0000E000CADCC5240000872E90
+:10CAC000000076AD001E76B4FFE5C7386FC0773939
+:10CAD000FFF077390003C7385000853A0004839689
+:10CAE000000476AD001E76B4FFE52032000093937B
+:10CAF000FFFC872E0000F6063B70C7386FC0773901
+:10CB0000FFF077390003A6BA6002C73860007739B2
+:10CB1000001E7738FFE5C6B477C0EE00CB2976B5A6
+:10CB2000FFF07721FFF0C6B86800C72C68009713A4
+:10CB3000FFFC07880008C12800009793FFFC879638
+:10CB4000FFFC8296FFF802140008013C0000000080
+:10CB500000019293FFFC02900008F5044F58F58203
+:10CB6000000206280080202E0062EE00CB900730E5
+:10CB70000040F0332800C6B8520076B4FFFA063001
+:10CB80000014F6B32800C6380000E000CB6405AC02
+:10CB90000001F7044F580000000106B818D4F482D1
+:10CBA0000001F4B72800073818C0F03B2800F7064A
+:10CBB00042C0F4820002F4BB28008796FFFC8296F4
+:10CBC000FFF802140000013C0000000000019293F5
+:10CBD000FFFC02900008F68442C0F60642C077319E
+:10CBE000001E7738FFE575B1001EC6B477C076B475
+:10CBF000FFF0F7044F5876B50006C4386800872266
+:10CC0000001476A1001E76B4FFE5C7386FC07738F0
+:10CC1000FFF0F7332800F70442C075ACFFE5C738D2
+:10CC20005FC07738FFF0203A0001E600CC4CF606F2
+:10CC30004290F704429076B1001E76B4FFE5C73803
+:10CC40006FC07739FFF007380001F7332800879667
+:10CC5000FFFC8296FFF802140000013C0000000077
+:10CC600000019293FFFC0290000822100004851638
+:10CC70000000000000019513FFFC9516FFF40788E3
+:10CC80000008E000CD009793FFFC8516FFF42022FA
+:10CC90000000E600CCBCF58642C0F7044290F606E0
+:10CCA000429276B1001E76B4FFE5C7386FC077397F
+:10CCB000FFF007380001E000CCECF7332800F02B40
+:10CCC0002800F68442C0772D001E7738FFE506283D
+:10CCD0000014C6B477C076B4FFF0F7044F58F6B32B
+:10CCE0002800C72872007738FFFAF72F28008796A8
+:10CCF000FFFC8296FFF802140004013C00000000D3
+:10CD000000019293FFFC0290000886960000F70451
+:10CD10004F58F4020000C6B472007734FFFA273887
+:10CD20000002203A0061F702003FE200CD40C6B4A5
+:10CD3000740020360000E600CD4000000001F4023F
+:10CD400000018796FFFC8296FFF802140004013C64
+:10CD50000000000000019293FFFC0290000886167C
+:10CD600000008716000885960004C5307000C032A8
+:10CD70005200E600CDA10000000186B2000077312C
+:10CD8000001E7738FFE5C6B477C076B5FFE8F6AF8A
+:10CD9000680006300001C0325200E600CD7805ACD4
+:10CDA00000018796FFFC8296FFF80214000C013CFC
+:10CDB000000000000001000000009293FFFC0290C0
+:10CDC000000884960000841600048596000886A654
+:10CDD00000007725001E7738FFE5C6B477C07535AB
+:10CDE000FFF0202A0010E200CE0DF606428EF5027A
+:10CDF0000010F704428C76B1001E76B4FFE5C73808
+:10CE00006FC07739FFF007380001F7332800202E74
+:10CE10000001E600CE70202A0000EE00CE7107244B
+:10CE2000000225280001A5BA50028622000076A142
+:10CE3000001E76B4FFE5C73850007739001E7738FA
+:10CE4000FFE5C5AC77C0C6306FC07631FFF075AD79
+:10CE5000FFE8F68200FFF702F15475AD0002A72E3D
+:10CE60007002C6306C00C6307580F623280024207E
+:10CE7000000225A80001F302F24603A40002C4AC9C
+:10CE80003800252C0001202E0000EC00CF110000FE
+:10CE90000001E600CEA0C71C5000E000CEB4F602B0
+:10CEA0000000A69E50027739001E7738FFE5C6B411
+:10CEB00077C07635FFE886A600007725001E773814
+:10CEC000FFE52528000225AC0002C6B477C076B580
+:10CED000FFE877310004C738620077390001C738AE
+:10CEE0003000C6B46800C6B4700006B4000E8736C1
+:10CEF000000024A4000276B5001E76B4FFE5C73812
+:10CF00006FC07738FFF0F7232800E000CE8424209C
+:10CF100000028796FFFC8296FFF80214000C013C89
+:10CF20000000000000019293FFFC029000088616AA
+:10CF3000000883160004839600008732000076B153
+:10CF4000001E76B4FFE5059C0002749D001E74A4CB
+:10CF5000FFE5741D001E063000027531001EC73843
+:10CF60006FC07738FFF0F71F280087320000752860
+:10CF7000FFE5C73857C07738FFF0F72F280005AC1A
+:10CF80000002063000028732000076B1001E76B43F
+:10CF9000FFE5C7386FC07738FFF0F72F280005ACE2
+:10CFA0000002063000028732000076B1001E76B41F
+:10CFB000FFE5C7386FC07738FFF0F72F280005ACC2
+:10CFC0000002063000028732000076B1001E76B4FF
+:10CFD000FFE5C7386FC07738FFF0F72F280005ACA2
+:10CFE0000002063000028732000076B1001E76B4DF
+:10CFF000FFE5C7386FC07738FFF0F72F280005AC82
+:10D000000002063000028732000076B1001E76B4BE
+:10D01000FFE5C7386FC07738FFF0F72F280005AC61
+:10D020000002063000028732000076B1001E76B49E
+:10D03000FFE5C7386FC07738FFF0F72F28000630BC
+:10D0400000028732000005AC00027631001E763007
+:10D05000FFE5C73867C07738FFF0F72F2800871E35
+:10D0600000007420FFE5C7384FC07739FFF007385C
+:10D070000001F71F2800871E0000049C0002C7382B
+:10D0800047C07739FFF025380001202A0000EE0064
+:10D09000D0BD26280001A7266002C6A4600076B590
+:10D0A000001E76B4FFE5C5A45000C5300000C738A7
+:10D0B0006FC07739FFE8E000D088F72F6800071CC1
+:10D0C0000002F33B6800C41C00008796FFFC8296B8
+:10D0D000FFF80214000C013C0000000000019293D4
+:10D0E000FFFC0290000886160004841600008732B8
+:10D0F000000076B1001E76B4FFE505A0000274A121
+:10D10000001E74A4FFE5063000027531001EC7380A
+:10D110006FC07738FFF0F7232800873200007528AA
+:10D12000FFE5C73857C07738FFF0F72F280005AC68
+:10D130000002063000028732000076B1001E76B48D
+:10D14000FFE5C7386FC07738FFF0F72F280005AC30
+:10D150000002063000028732000076B1001E76B46D
+:10D16000FFE5C7386FC07738FFF0F72F280005AC10
+:10D170000002063000028732000076B1001E76B44D
+:10D18000FFE5C7386FC07738FFF0F72F280005ACF0
+:10D190000002063000028732000076B1001E76B42D
+:10D1A000FFE5C7386FC07738FFF0F72F280005ACD0
+:10D1B0000002063000028732000076B1001E76B40D
+:10D1C000FFE5C7386FC07738FFF0F72F280005ACB0
+:10D1D0000002063000028732000076B1001E76B4ED
+:10D1E000FFE5C7386FC07738FFF0F72F280005AC90
+:10D1F0000002063000028732000006A000027631ED
+:10D20000001E7630FFE5C73867C07738FFF0F72F8C
+:10D210002800872200007621001E85960008C73866
+:10D220004FC07739FFF0C6B47000F5B768008722A9
+:10D2300000007630FFE5C73867C07739FFF0073860
+:10D240000001F72328008796FFFC8296FFF802145E
+:10D25000000C013C0000000000019293FFFC0290D2
+:10D2600000082210002027140020F03B280084969C
+:10D270000004F502000086A600007625001E763028
+:10D28000FFE504240002C6B467C076B4FFF0F6BB25
+:10D2900028008726000076A5001E76B4FFE5C73873
+:10D2A0006FC07739FFF0C02A7200EC00D2F876A583
+:10D2B000001E8726000076B4FFE5062800012594AD
+:10D2C000001EC5AC5000C5300000C7386FC07739AC
+:10D2D000FFF0C7385200A6A27002C720700077394D
+:10D2E000001E7738FFE5C6B477C076B5FFE8C68084
+:10D2F0006A00E000D290F6AF68008716FFE076156E
+:10D30000001E7630FFE5839600002314001E7599F9
+:10D31000001E75ACFFE57515001E7528FFE57495B8
+:10D32000001E74A4FFE57415001E7420FFE5069C22
+:10D3300000027395001E9396FFDCC73867C0839682
+:10D3400000007738FFF0F71F28008396FFDC871A6C
+:10D350000000739CFFE59396FFDCC7385FC0773809
+:10D36000FFF0F737280006B400028716FFE4231405
+:10D37000001A7619001E7630FFE5C73857C0773897
+:10D38000FFF0F7372800871A000006B40002C738FC
+:10D3900067C07738FFF0F737280006B40002871619
+:10D3A000FFE8231400167619001E7630FFE5C73813
+:10D3B0004FC07738FFF0F7372800871A000006B40F
+:10D3C0000002C73867C07738FFF0F737280006B487
+:10D3D00000028716FFEC231400127619001E763027
+:10D3E000FFE5C73847C07738FFF0F7372800871ABE
+:10D3F000000006B4000284160000C73867C0773802
+:10D40000FFF0F73728008716FFF006B40002C73890
+:10D410003FC07738FFF0F73728008796FFFC8296E9
+:10D42000FFF802140008013C000000000001929384
+:10D43000FFFC029000088616000084160004F684A3
+:10D440004F5887320014033000147519001E7528D8
+:10D45000FFE5C3A06A00739CFFFA04A0001475A541
+:10D46000001EC6306A007630FFFAC73857C07738DA
+:10D47000FFF0F7272800F39B280007200016F63B53
+:10D4800028008722001475ACFFE5C7385FC07738E5
+:10D49000FFF077390006C6B4700006B40016F3B783
+:10D4A00028008796FFFC8296FFF802140008013CD2
+:10D4B0000000000000019293FFFC02900008861615
+:10D4C0000000F5844F5805300016872A000076A921
+:10D4D000001E76B4FFE5C7386FC07738FFF07739A4
+:10D4E0000006C42C7000C0226200E600D52906A008
+:10D4F000001687360000C6305A007630FFFA76B53F
+:10D50000001E76B4FFE5C7386FC07738FFF0773973
+:10D51000000676B8FFFAF6AB2800C72C7000073873
+:10D520000014E000D52CF63B2800C42C00008796A0
+:10D53000FFFC8296FFF802140004013C000000008A
+:10D5400000019293FFFC02900008F7064F844738D1
+:10D55000FFFCF7056F30F686505C46B4FFFCF6859D
+:10D560006E50F7066E7C4738FFFCF7056E540734A3
+:10D57000191CF7054F5CF70200649736191CF70277
+:10D5800000009736192006B4001CF6854F58879680
+:10D59000FFFC8296FFF802140000013C000000002E
+:10D5A00000019293FFFC0290000822100090F30209
+:10D5B000FFFFF3054F54F38200009396FFAC231452
+:10D5C00000209316FF9C239400389396FF948316B3
+:10D5D000FFACF7044F5CF382000C9396FF74931634
+:10D5E000FF8C873A0004000000019716FFA4831601
+:10D5F000FFAC8396FFA400000001C01A3A00EC00C3
+:10D60000DB78F30204BCF7044F5C8316FF74000060
+:10D610000001C7383000873A0008F6844F58773940
+:10D620000006C4B470009493FFFC9496FF7C0788B6
+:10D630000008E000CD009793FFFC8496FF7C202239
+:10D640000000E600D654C5040000F7044288E0005C
+:10D65000D87CF6064288F6044F5C83960000831659
+:10D66000FF74869E0000A7323002F5820000C036AB
+:10D670007200E600D694C6303000869E00048732E1
+:10D68000000400000001C0367200E600D698202E8B
+:10D690000000F5820001202E0000E600D6A5000063
+:10D6A0000001F50200008396000087320000869E8C
+:10D6B000000000000001C0367200E200D6E4F582EE
+:10D6C0000000C0367200E600D6EC202E0000869ED8
+:10D6D00000048732000400000001C0367200E2003E
+:10D6E000D6ED202E0000F5820001202E0000E6007D
+:10D6F000D6FD202A0000F5020001202A0000E600E5
+:10D70000D72804A400028316FFACF70642C883960C
+:10D71000FF8CF3054F54C71C7000F03B28000738FE
+:10D720000002E000DB50F03B28009496FF6C872657
+:10D73000000076A5001E76B4FFE58316FF6C839685
+:10D74000FF9C2494001E0618000275B1001E75ACE3
+:10D75000FFE5C7386FC07738FFF0F71F2800873222
+:10D760000000751D001E7528FFE5C7385FC07738BB
+:10D77000FFF0F72728002494001C063000028732AF
+:10D78000000076B1001E76B4FFE5C7386FC0773869
+:10D79000FFF0F72728002494001A06300002873291
+:10D7A000000076B1001E76B4FFE5C7386FC0773849
+:10D7B000FFF0F72728002494001806300002873273
+:10D7C000000076B1001E76B4FFE5C7386FC0773829
+:10D7D000FFF0F72728002494001606300002873255
+:10D7E000000076B1001E76B4FFE5C7386FC0773809
+:10D7F000FFF0F72728002494001406300002873237
+:10D80000000076B1001E76B4FFE5C7386FC07738E8
+:10D81000FFF0F72728002494001206300002873218
+:10D82000000076B1001E76B4FFE5C7386FC07738C8
+:10D83000FFF0F7272800063000028732000024940A
+:10D8400000107631001E7630FFE5C73867C07738A4
+:10D85000FFF0F72728008716FFE0F682FFFCC738A5
+:10D8600057C07739FFF007380003C4B86C00202692
+:10D870000010E200D89DF606428AF704428876B18D
+:10D88000001E76B4FFE5F4020000C7386FC0773998
+:10D89000FFF007380001E000DBA0F7332800831613
+:10D8A000FF6C251400368396FF94871A0000769942
+:10D8B000001E76B4FFE50618000275B1001EC738D9
+:10D8C0006FC07738FFF0F71F28008732000075AC73
+:10D8D000FFE5C7385FC07738FFF0F72B2800251425
+:10D8E0000034063000028732000076B1001E76B4A4
+:10D8F000FFE5C7386FC07738FFF0F72B28002514F5
+:10D900000032063000028732000076B1001E76B485
+:10D91000FFE5C7386FC07738FFF0F72B28002514D4
+:10D920000030063000028732000076B1001E76B467
+:10D93000FFE5C7386FC07738FFF0F72B28002514B4
+:10D94000002E063000028732000076B1001E76B449
+:10D95000FFE5C7386FC07738FFF0F72B2800251494
+:10D96000002C063000028732000076B1001E76B42B
+:10D97000FFE5C7386FC07738FFF0F72B2800251474
+:10D98000002A063000028732000076B1001E76B40D
+:10D99000FFE5C7386FC07738FFF0F72B2800251454
+:10D9A0000028063000028732000026A4000274A47A
+:10D9B000FFFF7631001E7630FFE5C73867C0773845
+:10D9C000FFF0F72B28009013FFFC8316FF8CF7065F
+:10D9D00042CCC7187000C73868009713FFFC9393B8
+:10D9E000FFFC9496FF7C07880008E000CDB8979371
+:10D9F000FFFC8396FF6C2414004E25140050831600
+:10DA0000FF8C8496FF7C871E0000769D001E76B4F6
+:10DA1000FFE5061C000275B1001E75ACFFE5C738B6
+:10DA20006FC07738FFF0F72B280087320000752988
+:10DA3000001E7528FFE5C7385FC07738FFF0F72371
+:10DA400028002414004C063000028732000076B112
+:10DA5000001E76B4FFE5C7386FC07738FFF0F723B4
+:10DA600028002414004A063000028732000076B1F4
+:10DA7000001E76B4FFE5C7386FC07738FFF0F72394
+:10DA8000280024140048063000028732000076B1D6
+:10DA9000001E76B4FFE5C7386FC07738FFF0F72374
+:10DAA000280024140046063000028732000076B1B8
+:10DAB000001E76B4FFE5C7386FC07738FFF0F72354
+:10DAC000280024140044063000028732000076B19A
+:10DAD000001E76B4FFE5C7386FC07738FFF0F72334
+:10DAE000280024140042063000028732000076B17C
+:10DAF000001E76B4FFE5C7386FC07738FFF0F72314
+:10DB000028000630000287320000241400407631DD
+:10DB1000001E7630FFE5C73867C07738FFF0F7237F
+:10DB200028008696FFB0F60642C8C6186000F702C5
+:10DB30000003C6B457C076B5FFF0C6B47400F70250
+:10DB40000004C7386A00F733280006300002F4B337
+:10DB500028008396FF8C8316FF74039C0014939611
+:10DB6000FF8C0318000C8396FFAC9316FF74039C84
+:10DB70000001E000D5EC9396FFAC9313FFFCF38417
+:10DB80004F5C000000019393FFFCF3064A98931347
+:10DB9000FFFC07880008E00126F89793FFFCF402D9
+:10DBA00000018796FFFC8296FFF802140004013CF6
+:10DBB0000000000000019293FFFC02900008221078
+:10DBC00001A0F5020000F3846E50F602001C202A2A
+:10DBD0000063EE00DC08C59C6000A69E6002772D05
+:10DBE000001E7738FFE5C6B477C076B5FFF0203663
+:10DBF0000003E600DBFC072C0036F03B2800063073
+:10DC00000040E000DBCC05280001F5844F5C0000FB
+:10DC1000000186AE0008F4020000872E0004000018
+:10DC20000001C0367200EC00DCF09696FFEC773510
+:10DC30000001C738680077390002C638580006303E
+:10DC4000000CC38400008316000086B20000871A0F
+:10DC5000000000000001C0367200E600DC7CC52038
+:10DC6000000086B20004871A000400000001C036DC
+:10DC70007200E600DC80202A0000F5020001202A64
+:10DC80000000E600DC8D00000001F38200008496B5
+:10DC9000000086B200008726000000000001C036A8
+:10DCA0007200E200DCCCF5020000C0367200E60033
+:10DCB000DCD4202A000086B200048726000400007D
+:10DCC0000001C0367200E200DCD5202A0000F50217
+:10DCD0000001202A0000E600DCE5201E0000F3829F
+:10DCE0000001201E0000E600DCF420220000F40207
+:10DCF000000120220000E600DD29F602000187165F
+:10DD0000FFEC0000000176B90001C6B4700076B5E2
+:10DD10000002C6B4580006B4001486B60000971678
+:10DD2000FFF0E000DD989696FFF427140014971397
+:10DD3000FFFC83160000000000019313FFFC959385
+:10DD4000FFFC9596FE7007880008E0012568979310
+:10DD5000FFFC8596FE7020220000E600DD95F602AD
+:10DD600000018716FFEC0000000176B90001C6B47F
+:10DD7000700076B50002C6B4580006B4001486B62A
+:10DD800000009716FFF09696FFF4972E0008E0002B
+:10DD9000DD9C20320000F602000020320000E60088
+:10DDA000DDB0F4820000F704427CE000E09CF6065F
+:10DDB000427E9496FF448716FFF4F6044F58773955
+:10DDC0000006C73070009716FF5406B8001A873651
+:10DDD00000008316FF5476B5001E76B4FFE5C73801
+:10DDE0006FC09313FFFC7738FFF077390006C63019
+:10DDF00070009616FF4C07880008E000CD0097934E
+:10DE0000FFFC20220000E600DE35F30200018496CC
+:10DE1000FF4C000000019493FFFC07880008E0001D
+:10DE2000CD009793FFFC20220000E600DE380000C2
+:10DE30000001F30200019316FF448496FF440000A2
+:10DE4000000120260000E600DE59F60642A4F70491
+:10DE500042A4E000E0A076B1001E8316FF4C8616B7
+:10DE6000FF4C871A00007699001E76B4FFE5C7388C
+:10DE70006FC07739FFF0203A0002E600DE8500002F
+:10DE80000001F6044F58F5844F5800000001C032DD
+:10DE90005A00E600E025000000018496FF4C0000D7
+:10DEA000000106A4001A873600008316FF5476B5D9
+:10DEB000001E76B4FFE5C7386FC07738FFF07739BA
+:10DEC0000006C72C7000C03A3200E600DEDDF60620
+:10DED0004280F7044280E000E0A076B1001E2614E4
+:10DEE0000030F03328008716FFD07631001E7630E0
+:10DEF000FFE58496FF4C2314002E9316FE6475995B
+:10DF0000001E75ACFFE57515001E7528FFE573153D
+:10DF1000001E7318FFE59316FF348316FE64042475
+:10DF2000000206A000027495001E74A4FFE59496FA
+:10DF3000FF3C7495001EC73867C07738FFF0F723A1
+:10DF40002800871A000074A4FFE59496FF2CC738B8
+:10DF50005FC07738FFF0F737280006B40002871655
+:10DF6000FFD42494002A9496FE647625001E763011
+:10DF7000FFE5C73857C07738FFF0F7372800872606
+:10DF8000000006B40002C73867C07738FFF0F737E3
+:10DF9000280006B400028716FFD823140026931623
+:10DFA000FE647619001E8496FF3C7630FFE5C73884
+:10DFB0004FC07738FFF0F7372800871A000006B403
+:10DFC00000028496FF34C73867C07738FFF0F73710
+:10DFD000280006B400028716FFDC231400229316E3
+:10DFE000FE647619001E7630FFE5C7384FC07738DB
+:10DFF000FFF0F7372800871A000006B40002C73880
+:10E0000067C07738FFF0F73728008716FFE08316E0
+:10E01000FF2C06B40002C73837C07738FFF0E000A5
+:10E02000EAA0F737280007880008E000CBCC9793D8
+:10E03000FFFC06A00002F7044F58F037280006A0A6
+:10E0400000149416FF24C72072007738FFFAF737C0
+:10E05000280006A00016F7372800F4820001F4A378
+:10E0600028009413FFFC07880008E000CD00979378
+:10E07000FFFC20220000E600E0BC26940048F704E4
+:10E080004280E000E09CF60642828696FEF4E000C4
+:10E09000E29400000001F7044284F606428476B15F
+:10E0A000001E76B4FFE5F4020000C7386FC0773970
+:10E0B000FFF007380001E000EAA4F73328008316D8
+:10E0C000FF4C7515001E7528FFE59316FF1C0718F9
+:10E0D0000036F4820001F4BB2800F03728008716D0
+:10E0E000FFB876B5001E76B4FFE5041800020620DE
+:10E0F0000002231400469316FF147599001E75AC98
+:10E10000FFE57495001E74A4FFE59496FF0C73154B
+:10E11000001E7318FFE59316FF047495001E74A487
+:10E12000FFE59496FEFC230000079316FEF4849608
+:10E13000FF1C8316FF1404A4000A9496FE7CC738C3
+:10E140006FC07738FFF0F7232800F6844F58849685
+:10E15000FF54871A0000C6A46A007434FFFAC73857
+:10E160005FC07738FFF0F7332800063000028716CB
+:10E17000FFBC231400429316FF147699001E76B458
+:10E18000FFE5C73857C07738FFF0F7332800871A04
+:10E19000000006300002C7386FC07738FFF0F73351
+:10E1A0002800063000028716FFC02494003E949693
+:10E1B000FF1476A5001E8316FF0C76B4FFE5C73862
+:10E1C00037C07738FFF0F733280087260000063085
+:10E1D0000002C7386FC07738FFF0F73328000630E9
+:10E1E00000028716FFC42494003A9496FF1476A583
+:10E1F000001E8316FF0476B4FFE5C73837C07738B2
+:10E20000FFF0F73328008726000006300002C738E9
+:10E210006FC07738FFF0F73328008716FFC8849661
+:10E22000FEFC06300002C7384FC07738FFF0F733E6
+:10E2300028008316FEF400000001201A0007EE00FB
+:10E24000E294F68200088496FE7C00000001072418
+:10E25000000E86BA00007739001E7738FFE5C6B495
+:10E2600077C076B5FFF0F70200FFC6B4740047210F
+:10E270000000C0367200470C0001203A0000E600A2
+:10E28000E08804A400029496FE7C03180001E000DC
+:10E29000E2309316FEF48316FF1C000000010718FD
+:10E2A0000038F6BB28009313FFFC8496FF2400007F
+:10E2B00000019493FFFC07880008E000D42C97939A
+:10E2C000FFFC231400789316FEBC849600002314F0
+:10E2D00000A886A60004872600009316FE9CC6B4FC
+:10E2E00070009696FEECF7020001C7347400971692
+:10E2F000FEE48496FF24000000019493FFFC07884D
+:10E300000008E000D4B49793FFFCF7044F580000D6
+:10E310000001C0227200E600EAA19416FF1C86A24A
+:10E3200000387721001E7738FFE5F30200009316CE
+:10E33000FED4C6B477C076B5FFF09696FEDC849620
+:10E34000FED4000000012026000EEE00E2F0F302F1
+:10E35000000F9313FFFC8316FEEC00000001C718AA
+:10E3600048009713FFFC07880008E00127E897930F
+:10E37000FFFCC3A000008496FEE4000000012026FC
+:10E380000000E600E38D239C0007C3803A00C71C11
+:10E3900038008316FF1CF48200FFF6044F58C7189C
+:10E3A00070000738002686BA00009716FEC4773939
+:10E3B000001E7738FFE5C6B477C076B5FFF0C6B467
+:10E3C0004C0076B50006C330680007300040C01A24
+:10E3D0007200E600E40D9316FECC9313FFFC9396B7
+:10E3E000FE749616FE6C9696FE6807880008E0009C
+:10E3F000CD009793FFFC8396FE748616FE6C86967E
+:10E40000FE6820220000E600E09500000001F5848F
+:10E410004F588496FECC072C0040C0267200E600C0
+:10E42000EA8D00000001A732680276A5001E76B4CE
+:10E43000FFE58616FECCC7386FC07739FFF0203A6B
+:10E440000002E600E451C0325A00C62C0000C0327F
+:10E450005A00E600E6E5251400768316FF1C849634
+:10E46000FEBC061800028732000076B1001E76B4AA
+:10E47000FFE58316FEDC0630000275B1001EC738CA
+:10E480006FC07738FFF0F72728008732000075AC9F
+:10E49000FFE5C7385FC07738FFF0F72B2800251459
+:10E4A0000074063000028732000076B1001E76B498
+:10E4B000FFE5C7386FC07738FFF0F72B2800251429
+:10E4C0000072063000028732000076B1001E76B47A
+:10E4D000FFE5C7386FC07738FFF0F72B2800251409
+:10E4E0000070063000028732000076B1001E76B45C
+:10E4F000FFE5C7386FC07738FFF0F72B28002514E9
+:10E50000006E063000028732000076B1001E76B43D
+:10E51000FFE5C7386FC07738FFF0F72B28002514C8
+:10E52000006C063000028732000076B1001E76B41F
+:10E53000FFE5C7386FC07738FFF0F72B28002514A8
+:10E54000006A063000028732000076B1001E76B401
+:10E55000FFE5C7386FC07738FFF0F72B280006308B
+:10E56000000287320000251400687631001E7630E4
+:10E57000FFE5C73867C07738FFF0F72B2800C71CC6
+:10E5800032009713FFFC9493FFFC2614006096134F
+:10E59000FFFC9616FE6C07880008E000D0DC97931D
+:10E5A000FFFC8716FFA08616FE6C8496FECC231413
+:10E5B000005E9316FE5C7599001E75ACFFE5741540
+:10E5C000001E7420FFE57315001E7318FFE59316F7
+:10E5D000FEAC8316FE5C7631001E7630FFE5052426
+:10E5E000000206A800027495001E74A4FFE594962C
+:10E5F000FEB47495001EC73867C07738FFF0F72B5C
+:10E600002800871A000074A4FFE59496FEA4C7387A
+:10E610005FC07738FFF0F737280006B4000287168E
+:10E62000FFA42494005A9496FE5C7625001E83165F
+:10E63000FEB47630FFE5C73837C07738FFF0F737DC
+:10E6400028008726000006B40002C73867C0773864
+:10E65000FFF0F737280006B400028716FFA82494BD
+:10E6600000569496FE5C7625001E7630FFE5C7388E
+:10E6700047C07738FFF0F73728008726000006B438
+:10E680000002C73867C07738FFF0F737280006B4B4
+:10E6900000028716FFAC231400529316FE5C761915
+:10E6A000001E8496FEAC7630FFE5C7384FC0773841
+:10E6B000FFF0F7372800871A000006B40002C738B9
+:10E6C00067C07738FFF0F73728008716FFB083164A
+:10E6D000FEA406B40002C73837C07738FFF0E00068
+:10E6E000EA8CF73728008496FECC0000000104A4D1
+:10E6F00000369496FE5C8726000076A5001E76B450
+:10E70000FFE5C7386FC07739FFF0203A0000470CAB
+:10E710000001203A0000E600EA8D000000018316A7
+:10E72000FECC8496FF1C0618003A85B20000072430
+:10E73000003A86BA00007631001E7630FFE5773960
+:10E74000001E7738FFE5C5AC67C0C6B477C075ADAD
+:10E75000FFF076B5FFF0C02E6A00EC00E764F5022A
+:10E760000002F50200018316FF1C000000010718DB
+:10E77000003686BA00007739001E7738FFE5C6B448
+:10E7800077C076B5FFF020360002E600E79C000077
+:10E790000001202A0001E600EA8D000000018496B5
+:10E7A000FE5C8316FF1CF52728000618000287323E
+:10E7B000000076B1001E76B4FFE5251400A684960D
+:10E7C000FE9C8316FEDC0630000275B1001EC738C1
+:10E7D0006FC07738FFF0F72728008732000075AC4C
+:10E7E000FFE5C7385FC07738FFF0F72B2800251406
+:10E7F00000A4063000028732000076B1001E76B415
+:10E80000FFE5C7386FC07738FFF0F72B28002514D5
+:10E8100000A2063000028732000076B1001E76B4F6
+:10E82000FFE5C7386FC07738FFF0F72B28002514B5
+:10E8300000A0063000028732000076B1001E76B4D8
+:10E84000FFE5C7386FC07738FFF0F72B2800251495
+:10E85000009E063000028732000076B1001E76B4BA
+:10E86000FFE5C7386FC07738FFF0F72B2800251475
+:10E87000009C063000028732000076B1001E76B49C
+:10E88000FFE5C7386FC07738FFF0F72B2800251455
+:10E89000009A063000028732000076B1001E76B47E
+:10E8A000FFE5C7386FC07738FFF0F72B2800063038
+:10E8B000000287320000251400987631001E763061
+:10E8C000FFE5C73867C07738FFF0F72B2800C71C73
+:10E8D00032009713FFFC9493FFFC261400909613CC
+:10E8E000FFFC9616FE6C07880008E000D0DC9793CA
+:10E8F000FFFC8716FF708616FE6C8496FECC239470
+:10E90000008E759D001E75ACFFE57315001E731813
+:10E91000FFE59316FE947415001E7420FFE5731531
+:10E92000001E7318FFE59316FE848316FE9476315D
+:10E93000001E7630FFE50524000206A8000274954B
+:10E94000001E74A4FFE59496FE8CC73867C0773824
+:10E95000FFF0F72B28008496FEC4871E0000752563
+:10E96000001EC7385FC07738FFF0F737280006B4BD
+:10E9700000028716FF742394008A761D001E7630ED
+:10E98000FFE58496FE8C7528FFE5C73837C07738D9
+:10E99000FFF0F7372800871E000006B40002831638
+:10E9A000FE84C73867C07738FFF0F737280006B411
+:10E9B00000028716FF7823940086761D001E7630AD
+:10E9C000FFE5C73847C07738FFF0F7372800871EC4
+:10E9D000000006B40002C73867C07738FFF0F73789
+:10E9E000280006B400028716FF7C23940082761D5F
+:10E9F000001E7630FFE5C7384FC07738FFF0F73795
+:10EA00002800871E000006B400028496FEC4C738A2
+:10EA100067C07738FFF0F73728008716FF8006B405
+:10EA20000002C73837C07738FFF0F737280087264D
+:10EA30000000F30200FFC73857C07738FFE8C6B8B8
+:10EA40003400F7020080C73474007739001077393A
+:10EA5000FFF0203A0000E600EA6127000100C6B49A
+:10EA600075808496FECC0000000107240038F6BBB8
+:10EA700028009493FFFC8316FF24000000019313E9
+:10EA8000FFFC07880008E000D42C9793FFFC8496D5
+:10EA9000FED40000000104A40001E000E33C9496D1
+:10EAA000FED4F40200018796FFFC8296FFF8021460
+:10EAB0000004013C0000000000019293FFFC029062
+:10EAC0000008861600088696000CF502FFFC859665
+:10EAD000000484160010F484E0000730000294B2B1
+:10EAE0000010F484E00406B4000394B20014F4842B
+:10EAF000E01CC6B4540094B20018F4820005F4B3CC
+:10EB00002800F4820001F4BB280027340008973263
+:10EB1000000486160000072C0003C7385400C6B84E
+:10EB200068009693FFFCC63072009613FFFCF70254
+:10EB30000003C5AC7400F7020004C7385A009713ED
+:10EB4000FFFC07880008C12000009793FFFC879610
+:10EB5000FFFC8296FFF802140014013C0000000044
+:10EB600000019293FFFC0290000822100018871603
+:10EB700000040000000183BA000084960000939610
+:10EB8000FFF0F3846E54873A00049396FFEC9716D7
+:10EB9000FFF49013FFFC271C00029713FFFC0724CF
+:10EBA00000209713FFFC9496FFE407880008E0001C
+:10EBB000CDB89793FFFC8496FFE4839600088726E0
+:10EBC00000188516FFECC03A3A00EE00EC7CF582A6
+:10EBD0000001872600188396000800000001C01E6F
+:10EBE0007200E600EC7CC584000086A60010871643
+:10EBF000FFF0F6020000C0367200E600EC1C0424B0
+:10EC0000001086A600148716FFF400000001C0362D
+:10EC10007200E600EC2020320000F60200012032F3
+:10EC20000000E600EC2D00000001F582000086A245
+:10EC300000008716FFF000000001C0367200E200FD
+:10EC4000EC68F6020000C0367200E600EC7020327C
+:10EC5000000086A200048716FFF400000001C03601
+:10EC60007200E200EC7120320000F6020001203256
+:10EC70000000E600EC81202E0000F5820001202E2D
+:10EC80000000E600ECACF7020001F704429CF60637
+:10EC9000429C76B1001E76B4FFE5C7386FC0773965
+:10ECA000FFF007380001F7332800F7020001972A28
+:10ECB000000883A6000C772CFFE193AA000C972A8A
+:10ECC000001C83A6001CF7046E5093AA002083BA90
+:10ECD0001DDCF682000093AA002C8396000CC5B4BC
+:10ECE000000093AA003083BA0010C634000093AA33
+:10ECF0000024873A001400000001972A00282036DB
+:10ED0000001FEE00ED1CC73050000738003495BAE4
+:10ED1000000006300004E000ECFC06B4000183961D
+:10ED2000001076A5001E9393FFFCF38200B493932A
+:10ED3000FFFC9513FFFC8726002076B4FFE5C7385B
+:10ED40006FC07739FFF09713FFFC8396FFEC00004C
+:10ED500000019393FFFC07880008E000EAB897934E
+:10ED6000FFFC8796FFFC8296FFF802140014013C1A
+:10ED70000000000000019293FFFC029000082210A6
+:10ED800000188716000400000001863A0000000009
+:10ED900000019616FFF0873A000400000001971664
+:10EDA000FFF4F6021DE09613FFFC8616000000003B
+:10EDB00000019613FFFCF6046E500000000196134C
+:10EDC000FFFC261400109616FFEC07880008E001EF
+:10EDD00026F89793FFFCF6846E50F6020000873603
+:10EDE0001DD89616FFE476B5001E76B4FFE5C73849
+:10EDF0006FC07738FFF0F68642C0F73728008616D6
+:10EE0000FFEC000000019613FFFC07880008E000FB
+:10EE1000DBB49793FFFC20220000E600EE4D0000DB
+:10EE200000018616FFEC000000019613FFFC078826
+:10EE30000008E000D5A09793FFFC20220000E60028
+:10EE4000EE4D00000001F60200019616FFE4841664
+:10EE5000FFE48796FFFC8296FFF802140008013C4D
+:10EE60000000000000019293FFFC029000088696CB
+:10EE70000004861600008736000885960008203AB0
+:10EE80000000E600EE99203A0003E600EEE9F40205
+:10EE90000000E000EF0C0000000177B0001F703EA2
+:10EEA000FFE1E600EF0DF4020000851600140000FB
+:10EEB00000019513FFFC851600100000000195135A
+:10EEC000FFFC8516000C000000019513FFFC9593D4
+:10EED000FFFC9693FFFC07880008E000EB60979327
+:10EEE000FFFCE000EF0C0000000177B0001E703E58
+:10EEF000FFE1E600EF0D000000019593FFFC969303
+:10EF0000FFFC07880008E000ED749793FFFC8796EC
+:10EF1000FFFC8296FFF802140018013C000000007C
+:10EF200000019293FFFC0290000822100018F48266
+:10EF3000000086960000F6044AA023940010843650
+:10EF400000009616FFE4F7044A9C9416FFF08536FD
+:10EF50000004C0327200EC00F0149516FFF4773113
+:10EF60000001C738600077390002F3064A98C6B836
+:10EF7000300006B4000CC584000087360000000095
+:10EF80000001C03A4200E600EFA4C6240000873624
+:10EF9000000400000001C03A5200E600EFA8203251
+:10EFA0000000F602000120320000E600EFB500008C
+:10EFB0000001F5820000863600008716FFF0000091
+:10EFC0000001C0327200E200EFF0F5020000C03232
+:10EFD0007200E600EFF8202A000086B600048716CB
+:10EFE000FFF400000001C0367200E200EFF9202AB1
+:10EFF0000000F5020001202A0000E600F009202EA2
+:10F000000000F5820001202E0000E600F018202606
+:10F010000000F482000120260000E600F04DF60218
+:10F0200000018716FFE4F3064A9876B90001C6B4DA
+:10F03000700076B50002C6B4300006B4001486B67F
+:10F0400000009716FFE8E000F0B09696FFEC27145A
+:10F05000001C9713FFFC9393FFFCF3064A9893134D
+:10F06000FFFC07880008E00125689793FFFC202239
+:10F070000000E600F0ADF60200018716FFE4F3069B
+:10F080004A9876B90001C6B4700076B50002C6B4DD
+:10F09000300006B4001486B600009716FFE8969676
+:10F0A000FFECF7054AA0E000F0B420320000F602C1
+:10F0B000000020320000E600F121F4020001871672
+:10F0C000FFE8F60642C876B90002C6B4700076B50D
+:10F0D0000002A736600283160004C6B460007635CD
+:10F0E000001E7630FFE50534000275A9001EC73802
+:10F0F00067C07738FFF0971A0000872A000075ACC8
+:10F10000FFE583160008C7385FC07738FFF0971A0D
+:10F1100000008316000C06B40004E000F124969A67
+:10F120000000F40200008796FFFC8296FFF80214AC
+:10F130000010013C0000000000010000B9000000C8
+:10F14000BA000000BB000000BC000000BD000000D1
+:10F15000BE000000BF000000800000008100000031
+:10F160008200000083000000840000008500000091
+:10F17000860000008700B9B9B9BAB9BBB9BCB9BD3E
+:10F18000B9BEB9BFB980B981B982B983B984B9852B
+:10F19000B986B987BAB9BABABABBBABCBABDBABE2F
+:10F1A000BABFBA80BA81BA82BA83BA84BA85BA863B
+:10F1B000BA87BBB9BBBABBBBBBBCBBBDBBBEBBBFCD
+:10F1C000BB80BB81BB82BB83BB84BB85BB86BB874B
+:10F1D000BCB9BCBABCBBBCBCBCBDBCBEBCBFBC80AB
+:10F1E000BC81BC82BC83BC84BC85BC86BC87BDB9E9
+:10F1F000BDBABDBBBDBCBDBDBDBEBDBFBD80BD81BB
+:10F20000BD82BD83BD84BD85BD86BD87BEB9BEBA86
+:10F21000BEBBBEBCBEBDBEBEBEBFBE80BE81BE82CA
+:10F22000BE83BE84BE85BE86BE87BFB9BFBABFBB24
+:10F23000BFBCBFBDBFBEBFBFBF80BF81BF82BF83DA
+:10F24000BF84BF85BF86BF8780B980BA80BB80BCC2
+:10F2500080BD80BE80BF80808081808280838084EA
+:10F2600080858086808781B981BA81BB81BC81BD60
+:10F2700081BE81BF818081818182818381848185FA
+:10F280008186818782B982BA82BB82BC82BD82BEFE
+:10F2900082BF82808281828282838284828582860A
+:10F2A000828783B983BA83BB83BC83BD83BE83BF9C
+:10F2B000838083818382838383848385838683871A
+:10F2C00084B984BA84BB84BC84BD84BE84BF84807A
+:10F2D000848184828483848484858486848785B9B8
+:10F2E00085BA85BB85BC85BD85BE85BF858085818A
+:10F2F00085828583858485858586858786B986BA56
+:10F3000086BB86BC86BD86BE86BF86808681868299
+:10F310008683868486858686868787B987BA87BBF3
+:10F3200087BC87BD87BE87BF8780878187828783A9
+:10F33000878487858786878700009293FFFC0290E9
+:10F34000000822100018F70475EC00000001203AB4
+:10F350000000E600F37DF6064296F704429476B18B
+:10F36000001E76B4FFE5F4020000C7386FC077399D
+:10F37000FFF007380001E000F5E0F7332800F384E0
+:10F380006F309013FFFC271C00029713FFFC8316BD
+:10F390000000000000019313FFFC9396FFEC078828
+:10F3A0000008E000CDB89793FFFC8396FFECF702CE
+:10F3B0000000971E00088316000400000001931E41
+:10F3C000000C83160008049C0022931E001C831668
+:10F3D000000C9396FFF4871A00007699001E76B40D
+:10F3E000FFE50618000275B1001E75ACFFE5C738D1
+:10F3F0006FC07738FFF0069C0020F737280087326F
+:10F4000000009696FFE47535001EC7385FC0773858
+:10F41000FFF0F7272800049C002406300002873202
+:10F42000000076B1001E76B4FFE5C7386FC07738AC
+:10F43000FFF0F7272800049C0026063000028732E0
+:10F44000000076B1001E76B4FFE5C7386FC077388C
+:10F45000FFF0F7272800049C0028063000028732BE
+:10F46000000076B1001E76B4FFE5C7386FC077386C
+:10F47000FFF0F7272800049C002A0630000287329C
+:10F48000000076B1001E76B4FFE5C7386FC077384C
+:10F49000FFF0F7272800049C002C0630000287327A
+:10F4A000000076B1001E76B4FFE5C7386FC077382C
+:10F4B000FFF0F7272800049C002E06300002873258
+:10F4C000000076B1001E76B4FFE5C7386FC077380C
+:10F4D000FFF0F72728000630000287320000049C66
+:10F4E00000307631001E7630FFE5C73867C07738C8
+:10F4F000FFF0F7272800871E00207528FFE5C73892
+:10F5000057C07739FFF0203A0008EE00F598F3066F
+:10F5100014D88316FFE4871E00207699001E76B467
+:10F52000FFE5C7386FC07739FFF025B80001C4ACDC
+:10F53000580004240001202E0000EC00F595F5028F
+:10F5400000008316FFE40000000106180002A73245
+:10F550005802C6B0580076B5001E76B4FFE5C7382D
+:10F560006FC07739FFE8C6B0400077B80018703E2A
+:10F57000FFE1E600F57DF7376800F502FFFFC730D1
+:10F580004800F53B680024A4000224200002E000AB
+:10F59000F53425AC0001F30614D89313FFFCF302F5
+:10F5A00000349313FFFC8316FFF400000001931353
+:10F5B000FFFC8316000000000001871A0000769906
+:10F5C000001E76B4FFE5C7386FC07739FFF0971398
+:10F5D000FFFC9393FFFC07880008E000EAB89793CC
+:10F5E000FFFC8796FFFC8296FFF802140010013C96
+:10F5F0000000000000019293FFFC0290000822101E
+:10F600000010F70475EC00000001203A0000E6004D
+:10F61000F639F6064296F704429476B1001E76B4A7
+:10F62000FFE5F4020000C7386FC07739FFF00738F4
+:10F630000001E000F748F7332800F5046F300000C0
+:10F6400000019516FFF49013FFFC27280002971382
+:10F65000FFFC85960004000000019593FFFC0788DD
+:10F660000008E000CDB89793FFFC85160004F60271
+:10F67000000086AA00007729001E7738FFE5C6B48F
+:10F6800077C076B5FFF0F7020001C0367400E600DF
+:10F69000F6999696FFECC63800009613FFFC859607
+:10F6A000FFEC8516FFF4472CFFFE07380002C72841
+:10F6B00072009713FFFC85960000000000019593EF
+:10F6C000FFFC07880008E000CDB89793FFFC851683
+:10F6D000FFF4F7020002972A000885960008000050
+:10F6E000000195AA000C8596000C0000000195AA67
+:10F6F000001CF50614D89513FFFCF58200209593A5
+:10F70000FFFC8516FFF4000000019513FFFC8596B1
+:10F7100000008516FFEC872E000076AD001E76B443
+:10F72000FFE5C7386FC07739FFF0C738500097132F
+:10F73000FFFC8596FFF4000000019593FFFC07880D
+:10F740000008E000EAB89793FFFC8796FFFC8296DA
+:10F75000FFF802140010013C000000000001929329
+:10F76000FFFC0290000885960000851600048716AD
+:10F770000008F602FFFC06A80003C6B464000738C0
+:10F780000003C7386400C73470009713FFFCC5AC92
+:10F790006A009593FFFCF7020003C5287400F70286
+:10F7A0000004C73852009713FFFC07880008E001E7
+:10F7B00014D89793FFFC8796FFFC8296FFF80214FB
+:10F7C0000010013C0000000000019293FFFC029039
+:10F7D000000822100010F70475EC00000001203A28
+:10F7E0000000E600F80DF6064296F704429476B162
+:10F7F000001E76B4FFE5F4020000C7386FC0773909
+:10F80000FFF007380001E000F920F7332800F50485
+:10F810006F30000000019516FFF49013FFFC2728BD
+:10F8200000029713FFFC85960004000000019593E9
+:10F83000FFFC07880008E000CDB89793FFFC851611
+:10F840000004F602000086AA00007729001E77381F
+:10F85000FFE5C6B477C076B5FFF0F7020001C03609
+:10F860007400E600F86D9696FFECC638000096131B
+:10F87000FFFC8596FFEC8516FFF4472CFFFE07384A
+:10F880000002C72872009713FFFC85960000000055
+:10F8900000019593FFFC07880008E000CDB897931E
+:10F8A000FFFC8516FFF4F5820006F5AB280085966F
+:10F8B00000080728000295AA00040514000E852AF6
+:10F8C000000077A9001E77BCFFE5C5287FC0752919
+:10F8D000FFF0F53B2800F58614D89593FFFCF50260
+:10F8E00000089513FFFC859600008516FFEC872E17
+:10F8F000000076AD001E76B4FFE5C7386FC07739DB
+:10F90000FFF0C73850009713FFFC8596FFF4000006
+:10F9100000019593FFFC07880008E000F75C9793CF
+:10F92000FFFC8796FFFC8296FFF802140010013C52
+:10F930000000000000019293FFFC029000082210DA
+:10F940000008F70475EC83960004203A0000E600F6
+:10F95000FA64F6064296F5046F309013FFFC2728F0
+:10F9600000029713FFFC83160000000000019313B0
+:10F97000FFFC9396FFF49516FFF007880008E0005F
+:10F98000CDB89793FFFC8516FFF0F302000783962E
+:10F99000FFF4F32B280007280002F3020001F33BD9
+:10F9A0002800871E0000769D001E76B4FFE5059CAA
+:10F9B0000002762D001E7630FFE5749D001E74A4B3
+:10F9C000FFE5041C000683160000C7386FC07738B7
+:10F9D000FFF006A80004F7372800872E000006A8CD
+:10F9E000000675A1001EC73867C07738FFF0F737EB
+:10F9F0002800871E000475ACFFE506A800087619EC
+:10FA0000001EC7384FC07738FFF0F737280087222D
+:10FA1000000006A8000AC7385FC07738FFF0F73744
+:10FA20002800F30614D89313FFFCF302000C931381
+:10FA3000FFFC8316000000000001871A00007630EA
+:10FA4000FFE5C73867C07739FFF09713FFFC9513C0
+:10FA5000FFFC07880008E000F75C9793FFFCE000DC
+:10FA6000FA8400000001F704429476B1001E76B4D7
+:10FA7000FFE5F4020000C7386FC07739FFF00738A0
+:10FA80000001F73328008796FFFC8296FFF80214E6
+:10FA90000008013C0000000000019293FFFC02906E
+:10FAA000000822100048F70475EC85960000203A03
+:10FAB0000000E600FD98F606429605AC0002872E8F
+:10FAC000000076AD001E76B4FFE52414001E062C5F
+:10FAD00000027531001E249400207528FFE5F38490
+:10FAE0006E50C7386FC07738FFF0F727280087328D
+:10FAF00000009396FFC4C73857C07738FFF0F7234C
+:10FB000028002414001C063000028732000076B161
+:10FB1000001E76B4FFE5C7386FC07738FFF0F723D3
+:10FB200028002414001A063000028732000076B143
+:10FB3000001E76B4FFE5C7386FC07738FFF0F723B3
+:10FB4000280024140018063000028732000076B125
+:10FB5000001E76B4FFE5C7386FC07738FFF0F72393
+:10FB6000280024140016063000028732000076B107
+:10FB7000001E76B4FFE5C7386FC07738FFF0F72373
+:10FB8000280024140014063000028732000076B1E9
+:10FB9000001E76B4FFE5C7386FC07738FFF0F72353
+:10FBA000280024140012063000028732000076B1CB
+:10FBB000001E76B4FFE5C7386FC07738FFF0F72333
+:10FBC000280006300002873200002414001076312D
+:10FBD000001E7630FFE5C73867C07738FFF0F7239F
+:10FBE00028009013FFFC271C00029713FFFC94933E
+:10FBF000FFFC9596FFBC07880008E000CDB89793FE
+:10FC0000FFFC8596FFBC231400362494003873A5AE
+:10FC1000001E739CFFE5F40442C0F68642C076B530
+:10FC2000001E76B4FFE5872E0000762D001E76308C
+:10FC3000FFE5C4206FC07420FFF005AC0002752DF5
+:10FC4000001E7528FFE5C73867C07738FFF0F72733
+:10FC50002800872E0000F6046E50C73857C077384A
+:10FC6000FFF0F71B28002314003405AC0002872E98
+:10FC7000000076AD001E76B4FFE5C7386FC0773858
+:10FC8000FFF0F71B28002314003205AC0002872E7A
+:10FC9000000076AD001E76B4FFE5C7386FC0773838
+:10FCA000FFF0F71B28002314003005AC0002872E5C
+:10FCB000000076AD001E76B4FFE5C7386FC0773818
+:10FCC000FFF0F71B28002314002E05AC0002872E3E
+:10FCD000000076AD001E76B4FFE5C7386FC07738F8
+:10FCE000FFF0F71B28002314002C05AC0002872E20
+:10FCF000000076AD001E76B4FFE5C7386FC07738D8
+:10FD0000FFF0F71B28002314002A05AC0002872E01
+:10FD1000000076AD001E76B4FFE5C7386FC07738B7
+:10FD2000FFF0F71B280005AC0002872E000023140B
+:10FD3000002875AD001E75ACFFE5C7385FC0773889
+:10FD4000FFF0F71B28008716FFC8F6820003C738AC
+:10FD50003FC096B2000806B01DD8F4372800F386DD
+:10FD600014D89393FFFCF3821DE09393FFFC96134A
+:10FD7000FFFC7739FFF09713FFFC8396FFC4000068
+:10FD800000019393FFFC07880008E000EAB897930E
+:10FD9000FFFCE000FDB800000001F704429476B1DA
+:10FDA000001E76B4FFE5F4020000C7386FC0773953
+:10FDB000FFF007380001F73328008796FFFC829692
+:10FDC000FFF802140004013C0000000000019293BF
+:10FDD000FFFC029000088616000000000001873238
+:10FDE000000076B1001E76B4FFE5C7386FC07739E2
+:10FDF000FFF0203A0006E600FE21F582001EF7041F
+:10FE000042A8F60642A876B1001E76B4FFE5C738D0
+:10FE10006FC07739FFF007380001E000FE34F73398
+:10FE20002800F6056F349593FFFC07880008E00072
+:10FE300015849793FFFC8796FFFC8296FFF80214C7
+:10FE40000004013C0000000000019293FFFC0290BE
+:10FE5000000886160000859600048732000076B1FF
+:10FE6000001E76B4FFE5C7386FC07739FFF0203A3F
+:10FE70000007E600FE9DF4020000F70442A8F60623
+:10FE800042AA76B1001E76B4FFE5C7386FC0773955
+:10FE9000FFF007380001E000FF1CF73328000730AF
+:10FEA000000286BA00007739001E7738FFE5C6B435
+:10FEB00077C076B5FFF020360001E600FED5F605E6
+:10FEC0006F3420360002E600FEE5F5020020E00077
+:10FED000FEFCF60642AC202E000CE600FF1CF402ED
+:10FEE0000000F502001F9513FFFC07880008E000E2
+:10FEF00015849793FFFCE000FF1CF4020001F70457
+:10FF000042AC76B1001E76B4FFE5C7386FC07739D2
+:10FF1000FFF007380001F7332800F402000187964C
+:10FF2000FFFC8296FFF802140008013C000000006C
+:10FF300000019293FFFC02900008869600000000EA
+:10FF4000000187360004F6020000073800089736E3
+:10FF500000048736000800000001203A0000EC0091
+:10FF6000FF7DF6856F348736000800000001203AD7
+:10FF70000003EE00FF8020320000F6020001203274
+:10FF80000000E600FFBDF60642AEF7046F34000045
+:10FF90000001873A0008F682FFEC77390002A73AA1
+:10FFA0006802000000019713FFFC07880008E000CA
+:10FFB00015849793FFFCE000FFD800000001F704D0
+:10FFC00042AC76B1001E76B4FFE5C7386FC0773912
+:10FFD000FFF007380001F73328008796FFFC829670
+:10FFE000FFF802140004013C0000000000010000C2
+:10FFF00000170000001A0000001D0000001800009B
+:020000021000EC
+:10000000000056657273696F6E537472696E673A59
+:10001000206D63702D6C34763320332E303863209E
+:1000200044656320313120313939362031333A305B
+:10003000363A313600009293FFFC02900008F70434
+:10004000E00CFF0200009702FF84F7060C3ECFFC95
+:100050007580F60200029602FF8C9002FF88F7047A
+:10006000E02000000001203A0000E6010074F68262
+:100070000000F68200039682FF988796FFFC829626
+:10008000FFF802140000013C000000000001929300
+:10009000FFFC029000082210000CF5021494F505F4
+:1000A0007B00F50EF014F5057B08F706E000F686F8
+:1000B0007B68C7386A00F7057AF0F502004CF682D3
+:1000C000000020360002EE010124F5057AF8C5B4DF
+:1000D0000000C6340000F706E030C72C7000F506BB
+:1000E0006F44B73250029013FFFC9713FFFC9596B4
+:1000F000FFF49616FFF09696FFEC07880008E001E3
+:10010000031C9793FFFC8596FFF48616FFF08696F6
+:10011000FFEC05AC149406B4000120360002EE0199
+:1001200000D506300004F5020022F5056F58F005F1
+:100130006F54F0056F50F0052D408796FFFC8296B6
+:10014000FFF802140000013C00000000000192933F
+:10015000FFFC0290000807880008E00129589793E7
+:10016000FFFCF7020003F705E008F7047AD8F6026F
+:1001700000019602FF94203A0000E6010191F70683
+:100180007AE807880008E00103DC9793FFFCF70694
+:100190007AE8F6020005F63B2800F7067AE0868248
+:1001A000FF44F602000320360000E60101C9F63BD9
+:1001B0002800F7046F648682FF4407380001203668
+:1001C0000000E60101B0F7056F6407880008E00150
+:1001D00000349793FFFC07880008E001008C979398
+:1001E000FFFC07880008E00044289793FFFC07887D
+:1001F0000008E00016F09793FFFC07880008E00174
+:100200000C609793FFFC07880008E00104089793AF
+:10021000FFFC07880008E00000209793FFFC078898
+:100220000008E0000BD89793FFFC07880008E00166
+:100230001D689793FFFC07880008E0011E50979304
+:10024000FFFC07880008E0005F689793FFFC0788C1
+:100250000008E0006DEC9793FFFC07880008E001C0
+:1002600021D09793FFFC07880008E001222C979388
+:10027000FFFC9002FF9407880008E0000BFC9793B6
+:10028000FFFCF40200008796FFFC8296FFF8021440
+:100290000000013C0000000000019293FFFC02906E
+:1002A000000822100008F6020000C5B0000020324D
+:1002B0000002EE010308F5066F44A6AE50020000EE
+:1002C00000018736000000000001203A0001E6012D
+:1002D00002FCF50200029513FFFC9693FFFC959635
+:1002E000FFF49616FFF007880008E001031C9793BF
+:1002F000FFFC8616FFF08596FFF40000000105ACB8
+:100300000004E00102AC063000018796FFFC8296F3
+:10031000FFF802140000013C00000000000192936D
+:10032000FFFC0290000887160000F6020000F6822B
+:100330000008963A0008963A000C963A09D8963A80
+:1003400009DC963A0EF4963A0EF896BA1420963ACC
+:10035000142490BA148C8696000490BA149096BA1D
+:100360000000963A00048796FFFC8296FFF802147C
+:100370000008013C0000000000019293FFFC029085
+:100380000008859600008716000886160004773856
+:10039000FFFFC5307000C0325200E40103C9000005
+:1003A0000001872E000076AD001E76B4FFE5C73849
+:1003B0006FC07738FFF0F733280006300002C032F4
+:1003C0005200E40103A005AC00028796FFFC829670
+:1003D000FFF80214000C013C0000000000019293A1
+:1003E000FFFC02900008F7020001E00103E8F705B6
+:1003F0007AD88796FFFC8296FFF802140000013C31
+:10040000000000000001000000009293FFFC029039
+:100410000008F502000AF50571CCF00571D4F0056D
+:1004200071D0F00571C4F5020001F682000020369B
+:10043000000AEC010464F50571C8F58A1E00F60691
+:1004400071C4472CFFFC973200180630000406B434
+:100450000001F70471CC00000001C0367200EC010D
+:10046000044105AC214CF0057198F5066F689513B1
+:10047000FFFCF5067B189513FFFC07880008E000D9
+:1004800015489793FFFCF50605D49513FFFCF782FA
+:1004900000059793FFFCF5066F689513FFFC07882E
+:1004A0000008E000161C9793FFFCF5060B709513EF
+:1004B000FFFCF78200069793FFFCF5066F68951323
+:1004C000FFFC07880008E000161C9793FFFCF50668
+:1004D0000BA09513FFFCF78200059793FFFCF50630
+:1004E00070809513FFFC07880008E000161C9793A6
+:1004F000FFFCF5060B709513FFFCF782000697933F
+:10050000FFFCF50670809513FFFC07880008E000EB
+:10051000161C9793FFFCF50605589513FFFCF50292
+:10052000000A9513FFFCF506710C9513FFFC078874
+:100530000008E000161C9793FFFC07880008E00104
+:1005400005589793FFFC8796FFFC8296FFF80214EC
+:100550000000013C0000000000019293FFFC0290AB
+:100560000008F70471C400000001203A0000E60111
+:10057000057DF68671C4E0010594F7020000F704DA
+:1005800071D00000000177390002C7386800873A4F
+:10059000001800000001203A0000E60105ACF70554
+:1005A0007B10F606710CE00105C0F6057B18F60617
+:1005B0006F68F6057B189702FF48073821289702D5
+:1005C000FF4C8796FFFC8296FFF802140000013C66
+:1005D0000000000000019293FFFC0290000822102E
+:1005E00000108682FF48F4866F68F4857B18F50456
+:1005F0007B1026B4000285B60000872A0000762909
+:10060000001E7630FFE576B5001E76B4FFE5C5AC7A
+:100610006FC0C73867C07739FFF077B80010703EF9
+:10062000FFE1E601064575ACFFF0F70471AC000090
+:10063000000107380001F70571ACF70471ACE00167
+:1006400008C4F7020001772CFFF8203A0000E60109
+:10065000067176A9001EF70471A800000001073892
+:100660000001F70571A8F70471A8E00108C4F702BA
+:100670000001872A000076B4FFE5C7386FC07739DC
+:10068000FFF027380004203A0003E20108A400002C
+:10069000000177390002F68606A4A6B670020000B3
+:1006A0000001C1340000000106B40001077C000114
+:1006B00007EC00010844872A0004C4840000C03A03
+:1006C0004A00E60106D8000000018702FF4800004A
+:1006D0000001C7385200972A0004872A000400004E
+:1006E0000001203A2100EE01073CF602000086AA34
+:1006F00000048702FF4800000001C7385200273875
+:100700000028C0367200E601073C0000000177FCBB
+:10071000001D703EFFE1E601073C0000000177FC90
+:100720000017703EFFE1E601073D0000000177FC85
+:100730000016703EFFE1E601074420320000F60299
+:10074000000120320000E601088800000001872A2D
+:10075000001800000001203A0002EE0108C100006C
+:100760000001F70471A40000000107380001F7053B
+:1007700071A4F70471A4E00108C4F7020001872AFC
+:10078000000400000001203A2100EE0107E0F6021B
+:10079000000086AA00048702FF4800000001C73855
+:1007A00052002738000CC0367200E60107E0000056
+:1007B000000177FC001D703EFFE1E60107E000004C
+:1007C000000177FC0017703EFFE1E60107E1000041
+:1007D000000177FC0016703EFFE1E6010880203240
+:1007E0000000F6020001E0010880203200008702CC
+:1007F000FF4800000001C738520027380004203AA3
+:100800000008E6010838F682000077FC001D703E03
+:10081000FFE1E60108380000000177FC0017703E98
+:10082000FFE1E60108390000000177FC0016703E88
+:10083000FFE1E601088020360000F6820001E001B9
+:10084000088020360000F702000077FC001D703E93
+:10085000FFE1E60108780000000177FC0017703E18
+:10086000FFE1E60108790000000177FC0016703E08
+:10087000FFE1E6010880203A0000F7020001203A7B
+:100880000000E60108C100000001F70471A00000AB
+:10089000000107380001F70571A0F70471A0E0011D
+:1008A00008C4F7020001F704719C0000000107383A
+:1008B0000001F705719CF704719CE00108C4F70280
+:1008C0000001F7020000203A0000E601096800007C
+:1008D0000001F6847B10000000018736000076B529
+:1008E000001E76B4FFE5C7386FC07739FFF02738B0
+:1008F0000004203A0003E2010B5077390002F6862B
+:10090000090CA6B6700200000001C134000000010D
+:10091000091C00010AE000010AAC00010B14F704F5
+:1009200071D0F60471CC06B80001C0366200E60151
+:100930000938C7340000F7020000F58471D40000C4
+:100940000001C03A5A00470C0001203A0000E601BD
+:10095000098500000001F70471B0000000010738AC
+:100960000001F70571B0F70471B0F70471B400002D
+:10097000000107380001F70571B4F70471B4E00114
+:100980000B5000000001F48471C8F68571D0949674
+:10099000FFF4F4847B10C0366200E60109A494964B
+:1009A000FFECF00571D0F70471D0F00571C88496A2
+:1009B000FFECC03A5A00470C0001F70571C48726C6
+:1009C000000800000001703AFFE1E60109E10000C3
+:1009D0000001F70471980000000107380001F705D5
+:1009E00071988496FFF40000000120260000E601C3
+:1009F0000A710000000107880008E001055897937C
+:100A0000FFFCF602000920320014E6010A4D27001F
+:100A1000000C203A0001E2010A4DF7062DCCF684C5
+:100A20002ECC0000000175B50002B62E700206B48F
+:100A30000001F6852ECC8602FF34F7062E4C2036B8
+:100A4000001FE2010A4DB62E7002F0052ECCF7040D
+:100A50002D6800000001873A000000000001873A7D
+:100A600000280000000107880008C13800009793A3
+:100A7000FFFCF70471BC8496FFEC07380001F70512
+:100A800071BCF70471BC86A600048496FFF4F704D9
+:100A900071B820260000C7386800F70571B8E60174
+:100AA0000B5100000001E0010B5C00000001F704A5
+:100AB00071C00000000107380001F70571C0F7049C
+:100AC00071C0F4847B10000000019493FFFC078840
+:100AD0000008E000FDCC9793FFFCE0010B50000004
+:100AE0000001F70471C00000000107380001F7059C
+:100AF00071C0F70471C0F4847B100000000194936E
+:100B0000FFFC07880008E000FF309793FFFCE0013E
+:100B10000B5000000001F70471C00000000107380D
+:100B20000001F70571C0F70471C0F6847B108702DD
+:100B3000FF4800000001C7386A00273800049713F7
+:100B4000FFFC9693FFFC07880008E000FE4897939F
+:100B5000FFFC07880008E00105589793FFFC879683
+:100B6000FFFC8296FFF802140000013C0000000028
+:100B700000019293FFFC02900008F7067080F705D1
+:100B80007B1807880008E00105589793FFFC8796BB
+:100B9000FFFC8296FFF802140000013C00000000F8
+:100BA00000019293FFFC02900008F7066F68F705BA
+:100BB0007B1807880008E00105589793FFFC87968B
+:100BC000FFFC8296FFF802140000013C00000000C8
+:100BD00000019293FFFC02900008F7067B18971320
+:100BE000FFFCF7066F689713FFFC07880008E0001A
+:100BF00014F49793FFFCF7067B189713FFFCF70696
+:100C00006FF49713FFFC07880008E00014F4979333
+:100C1000FFFCF7067B189713FFFCF706708097130D
+:100C2000FFFC07880008E00014F49793FFFCF70628
+:100C30007B189713FFFCF706710C9713FFFC0788CE
+:100C40000008E00014F49793FFFC8796FFFC82965F
+:100C5000FFF802140000013C000000000001000049
+:100C600000009293FFFC02900008F5020004F505D5
+:100C70007600F0057608F0057604F00575F8F502C3
+:100C80000001F682000020360004EC010CBCF505E2
+:100C900075FCF58E6AF8F60675F8472CFFFC97325E
+:100CA00000180630000406B40001F70476000000C6
+:100CB0000001C0367200EC010C9905AC214CF50620
+:100CC00072189513FFFCF50676489513FFFC07880C
+:100CD0000008E00015489793FFFCF5060DF4951306
+:100CE000FFFCF782000E9793FFFCF5067218951330
+:100CF000FFFC07880008E000161C9793FFFCF50630
+:100D00000DF49513FFFCF782000E9793FFFCF50698
+:100D100072A49513FFFC07880008E000161C979347
+:100D2000FFFCF506132C9513FFFCF7820001979347
+:100D3000FFFCF50673309513FFFC07880008E00000
+:100D4000161C9793FFFCF50616C89513FFFCF78257
+:100D500000019793FFFCF50673BC9513FFFC078811
+:100D60000008E000161C9793FFFCF5061800951389
+:100D7000FFFCF78200109793FFFCF506744895136B
+:100D8000FFFC07880008E000161C9793FFFCF5069F
+:100D900016409513FFFCF78200109793FFFCF506B1
+:100DA00074D49513FFFC07880008E000161C979385
+:100DB000FFFCF506132C9513FFFCF50200129513AA
+:100DC000FFFCF50675609513FFFC07880008E0003E
+:100DD000161C9793FFFCF00575F0F00575ECF00517
+:100DE00075F48796FFFC8296FFF802140000013C20
+:100DF0000000000000019293FFFC02900008221006
+:100E00000038F70475EC00000001203A0000E6010C
+:100E10000E2800000001F70475F000000001203AE0
+:100E20000000E6010E3D0000000107880008E00117
+:100E300015D09793FFFCE001131800000001F704A0
+:100E400075FC00000001203A0000E6010E59F6860C
+:100E500075F8E0010E6CF6820000F70476080000D9
+:100E6000000177390002C738680086BA0018F70415
+:100E700076FC00000001203A0000E6010E90F685A5
+:100E80007660F3067648F30576FCE0010EA4F702DF
+:100E90000001F3020010F30576F8F3067648F30537
+:100EA0007700F7020000203A0000E6011315F30670
+:100EB0007448F70475EC00000001203A0000E601D8
+:100EC0000ED800000001F70475F000000001203A80
+:100ED0000000E6010EED0000000107880008E001B7
+:100EE00016409793FFFCE001131800000001F68400
+:100EF0007660000000018736000800000001703AAB
+:100F0000FFE1E6010F21F48200009693FFFC0788C1
+:100F10000008E00000BC9793FFFCE0011314F30607
+:100F20007560C3B40000841E0010F6844AA0231428
+:100F300000209316FFC49416FFE09696FFD4851EFA
+:100F40000014F7044A9C00000001C0367200EC0156
+:100F5000100C9516FFE477350001C7386800773923
+:100F60000002F3064A98C6B8300006B4000CC584E7
+:100F700000008736000000000001C03A4200E60190
+:100F80000F9CC62400008736000400000001C03A10
+:100F90005200E6010FA020320000F60200012032CC
+:100FA0000000E6010FAD00000001F582000086366A
+:100FB00000008716FFE000000001C0327200E2016D
+:100FC0000FE8F5020000C0327200E6010FF0202A9F
+:100FD000000086B600048716FFE400000001C0365A
+:100FE0007200E2010FF1202A0000F5020001202A20
+:100FF0000000E6011001202E0000F5820001202EE5
+:101000000000E601101020260000F48200012026D6
+:101010000000E6011045F60200018716FFD4F30632
+:101020004A9876B90001C6B4700076B50002C6B41D
+:10103000300006B4001486B600009716FFD8E00111
+:1010400010B89696FFDC2714002C9713FFFC83162C
+:10105000FFC4000000019313FFFCF3064A989313AA
+:10106000FFFC9396FFCC07880008E0012568979362
+:10107000FFFC8396FFCC20220000E60110B5F602AB
+:1010800000018716FFD4F3064A9876B90001C6B46A
+:10109000700076B50002C6B4300006B4001486B6FF
+:1010A00000009716FFD89696FFDCF7054AA0E001EE
+:1010B00010BC20320000F602000020320000E601E1
+:1010C00010CCF4820001E0011124F4820000869625
+:1010D000FFD80000000177350002C7386800773973
+:1010E0000002F68642C8A63A6802C7386800753919
+:1010F000001E7528FFE505B8000286AE000007381F
+:1011000000049716FFECC63057C07630FFF09616F5
+:10111000FFF475AD001E75ACFFE5C6B45FC076B4D4
+:10112000FFF09696FFF020260000E6011138F582C8
+:101130000000E00111CCF60200008696FFF00000EE
+:101140000001C7346800C49C7200C02E6A00EC0124
+:101150001198C5240000C62C00008716FFEC000083
+:101160000001A6B2700205AC0001C73070007739EB
+:10117000001E7738FFE5C6B477C076B4FFF0F6AB53
+:101180002800052800028716FFF000000001C02E8D
+:101190007200EC01115906300002F3020001F30560
+:1011A00076F4F60200018716FFF0869E0004C73829
+:1011B0007000C7384800C6B470008716FFF406B444
+:1011C00000209702FF6C9482FF509682FF582032D5
+:1011D0000000E601131000000001F704765CF584BE
+:1011E00076F807380001F705765CF704765C202E68
+:1011F0000021E2011230F6862C28F7042D38000079
+:10120000000106380001F6052D387739000220323A
+:101210000044E601121CB5BA6802F0052D38F3024D
+:101220000022F30576F8F3047700E0011234F305A9
+:1012300076FCF00576FCF70475F800000001203A12
+:101240000000E6011271F6862C28F7042D38000004
+:10125000000106380001F6052D3877390002F30247
+:10126000000F20320044E6011270B33A6802F00524
+:101270002D38F7047608F684760007380001C03A66
+:101280006A00E601128CF7057608F0057608F68408
+:101290007608F7047604F00575F8F60675F8C0369A
+:1012A0007200470C0001203A0000E60112B9F70570
+:1012B00075FCE00112C8F702000077350002C7385C
+:1012C0006000873A001800000001203A0000E601A3
+:1012D0001309F7057660F7042D38F30672A4F305B9
+:1012E0007648F6862C2806380001F6052D38773921
+:1012F0000002F302000E20320044E6011318B33A54
+:101300006802E0011318F0052D38E0011314F3060C
+:101310007218F3067330F30576488796FFFC8296C1
+:10132000FFF802140000013C00000000000192934D
+:10133000FFFC02900008F70476600000000186BA06
+:101340000004F704765400000001C7386800F70570
+:101350007654F70476580000000107380001F705BD
+:101360007658F70475F8F6847658203A0000E601BE
+:10137000139DF6862C28F7042D380000000106384E
+:101380000001F6052D3877390002F502000F2032F2
+:101390000044E601139CB53A6802F0052D38F704C5
+:1013A0007608F684760007380001C03A6A00E60144
+:1013B00013B8F7057608F0057608F7047608F68482
+:1013C0007604F00575F8F58476F8C03A6A00470CA3
+:1013D0000001202E0021E2011414F70575FCF7042A
+:1013E0002D38F6862C2806380001F6052D38773979
+:1013F000000220320044E6011400B5BA6802F0058C
+:101400002D38F5020022F50576F8F5047700E001A5
+:101410001418F50576FCF00576FCF70475ECF50676
+:101420007218203A0000E6011440F5057648F704EA
+:1014300075F000000001203A0000E601145500009C
+:10144000000107880008E00115D09793FFFCE00138
+:1014500014C400000001F70475FC00000001203AEC
+:101460000000E6011471F68675F8E0011488F702B1
+:101470000000F70476080000000177390002C73841
+:101480006800873A001800000001203A0000E601D9
+:1014900014C5F7057660F7042D38F6862C28063833
+:1014A0000001F6052D3877390002F502000E2032D2
+:1014B0000044E60114BCB53A6802F0052D38F50683
+:1014C00072A4F50576488796FFFC8296FFF8021411
+:1014D0000000013C0000000000019293FFFC02901C
+:1014E0000008F70475EC00000001203A0000E60156
+:1014F0001540F40200008696000400000001F68505
+:1015000075EC8696000800000001F6857B3886960B
+:101510000000F7047648F6857B30F6867218C03AEC
+:101520006A00470C0001203A0000E6011541F40270
+:10153000000107880008E00115D09793FFFCF40232
+:1015400000018796FFFC8296FFF80214000C013C14
+:101550000000000000019293FFFC02900008F704D5
+:1015600075F400000001203A0000E60115BCF40209
+:1015700000008696000400000001F68575F086964E
+:10158000000800000001F6857B4886960000F704FD
+:101590007648F6857B40F6867218C03A6A00470C9A
+:1015A0000001203A0000E60115BDF40200010788A1
+:1015B0000008E00115D09793FFFCF4020001879624
+:1015C000FFFC8296FFF80214000C013C00000000B2
+:1015D00000019293FFFC02900008F70476FC0000E3
+:1015E0000001203A0000E60115FCF6820010F686A4
+:1015F0007648F68576FCE001160CF7020001F685C8
+:1016000076F8F6867648F6857700F7020000203AED
+:101610000000E6011620F68674D4E001162CF6854B
+:10162000764807880008E00116409793FFFC8796EC
+:10163000FFFC8296FFF802140000013C000000004D
+:1016400000019293FFFC02900008F60475F0000080
+:10165000000120320000E6011685F7020001F705BF
+:1016600075F4F6847B48F70576F4F7047B40C6B042
+:10167000680026B400049702FF6C9602FF50E00158
+:1016800016A800000001F70475ECF6847B38F5829B
+:101690000001F58576F4F6047B30C6B8680026B400
+:1016A00000049602FF6C9702FF509682FF58F58661
+:1016B00073BCF58576488796FFFC8296FFF8021486
+:1016C0000000013C0000000000019293FFFC02902A
+:1016D0000008F7047B280000000107380001F70527
+:1016E0007B28F70475F4F6847B28203A0000E60195
+:1016F000172100000001F00575F4F70475EC0000F7
+:101700000001203A0000E6011725F00575F0078872
+:101710000008E00116409793FFFCE00117EC000081
+:101720000001F00575ECF70475FC00000001203A9B
+:101730000000E6011741F68675F8E0011758F70238
+:101740000000F70476080000000177390002C7386E
+:101750006800873A001800000001203A0000E60106
+:101760001795F7057660F7042D38F6862C2806388D
+:101770000001F6052D3877390002F502000E2032FF
+:101780000044E601178CB53A6802F0052D38E001F7
+:101790001798F50672A4F5067218F5057648F584D3
+:1017A00076F800000001202E0021E20117E8F686FD
+:1017B0002C28F7042D380000000106380001F6053A
+:1017C0002D387739000220320044E60117D4B5BA2B
+:1017D0006802F0052D38F5020022F50576F8F504CB
+:1017E0007700E00117ECF50576FCF00576FC8796AE
+:1017F000FFFC8296FFF802140000013C000000008C
+:1018000000019293FFFC0290000822100038F704B8
+:1018100075EC00000001203A0000E60118340000D9
+:101820000001F70475F000000001203A0000E60115
+:1018300018490000000107880008E001164097934E
+:10184000FFFCE0011C7400000001F68476600000DB
+:1018500000018736000800000001703AFFE1E60150
+:10186000187DF48200009693FFFC07880008E000D2
+:1018700000BC9793FFFCE0011C70F3067560C3B4D5
+:101880000000841E0010F6844AA023140020931642
+:10189000FFC49416FFE09696FFD4851E0014F7044B
+:1018A0004A9C00000001C0367200EC0119689516D0
+:1018B000FFE477350001C738680077390002F30686
+:1018C0004A98C6B8300006B4000CC58400008736BC
+:1018D000000000000001C03A4200E60118F8C624EA
+:1018E00000008736000400000001C03A5200E60103
+:1018F00018FC20320000F602000120320000E60150
+:10190000190900000001F5820000863600008716E4
+:10191000FFE000000001C0327200E2011944F5024C
+:101920000000C0327200E601194C202A000086B681
+:1019300000048716FFE400000001C0367200E201D7
+:10194000194D202A0000F5020001202A0000E601BE
+:10195000195D202E0000F5820001202E0000E60116
+:10196000196C20260000F482000120260000E60108
+:1019700019A1F60200018716FFD4F3064A9876B93A
+:101980000001C6B4700076B50002C6B4300006B4DB
+:10199000001486B600009716FFD8E0011A14969638
+:1019A000FFDC2714002C9713FFFC8316FFC40000F4
+:1019B00000019313FFFCF3064A989313FFFC9396E0
+:1019C000FFCC07880008E00125689793FFFC839609
+:1019D000FFCC20220000E6011A11F6020001871652
+:1019E000FFD4F3064A9876B90001C6B4700076B504
+:1019F0000002C6B4300006B4001486B60000971684
+:101A0000FFD89696FFDCF7054AA0E0011A182032AD
+:101A10000000F602000020320000E6011A28F482DD
+:101A20000001E0011A80F48200008696FFD80000D1
+:101A3000000177350002C738680077390002F68662
+:101A400042C8A63A6802C73868007539001E752872
+:101A5000FFE505B8000286AE0000073800049716BF
+:101A6000FFECC63057C07630FFF09616FFF475AD28
+:101A7000001E75ACFFE5C6B45FC076B4FFF0969665
+:101A8000FFF020260000E6011A94F5820000E00134
+:101A90001B28F60200008696FFF000000001C73404
+:101AA0006800C49C7200C02E6A00EC011AF4C524C0
+:101AB0000000C62C00008716FFEC00000001A6B253
+:101AC000700205AC0001C73070007739001E77380E
+:101AD000FFE5C6B477C076B4FFF0F6AB2800052862
+:101AE00000028716FFF000000001C02E7200EC011A
+:101AF0001AB506300002F3020001F30576F4F6028F
+:101B000000018716FFF0869E0004C7387000C738B2
+:101B10004800C6B470008716FFF406B40020970290
+:101B2000FF6C9482FF509682FF5820320000E6013D
+:101B30001C6C00000001F704765CF58476F8073829
+:101B40000001F705765CF704765C202E0021E201A7
+:101B50001B8CF6862C28F7042D380000000106386F
+:101B60000001F6052D387739000220320044E601E5
+:101B70001B78B5BA6802F0052D38F3020022F30590
+:101B800076F8F3047700E0011B90F30576FCF0058E
+:101B900076FCF70475F800000001203A0000E60129
+:101BA0001BCDF6862C28F7042D38000000010638DE
+:101BB0000001F6052D3877390002F302000F2032BC
+:101BC0000044E6011BCCB33A6802F0052D38F70457
+:101BD0007608F684760007380001C03A6A00E6010C
+:101BE0001BE8F7057608F0057608F6847608F70412
+:101BF0007604F00575F8F60675F8C0367200470CE5
+:101C00000001203A0000E6011C15F70575FCE00113
+:101C10001C24F702000077350002C7386000873ABD
+:101C2000001800000001203A0000E6011C65F705DD
+:101C30007660F7042D38F30672A4F3057648F6862D
+:101C40002C2806380001F6052D3877390002F302FA
+:101C5000000E20320044E6011C74B33A6802E00131
+:101C60001C74F0052D38E0011C70F3067218F306A1
+:101C70007330F30576488796FFFC8296FFF80214CE
+:101C80000000013C0000000000019293FFFC029064
+:101C90000008F70676489713FFFCF70672189713AB
+:101CA000FFFC07880008E00014F49793FFFCF70698
+:101CB00076489713FFFCF70672A49713FFFC07887A
+:101CC0000008E00014F49793FFFCF706764897139A
+:101CD000FFFCF70673309713FFFC07880008E0004D
+:101CE00014F49793FFFCF70676489713FFFCF7066A
+:101CF00073BC9713FFFC07880008E00014F4979367
+:101D0000FFFCF70676489713FFFCF7067448971315
+:101D1000FFFC07880008E00014F49793FFFCF70627
+:101D200076489713FFFCF70674D49713FFFC0788D7
+:101D30000008E00014F49793FFFCF7067648971329
+:101D4000FFFCF70675609713FFFC07880008E000AA
+:101D500014F49793FFFC8796FFFC8296FFF8021419
+:101D60000000013C0000000000019293FFFC029083
+:101D70000008F68676689693FFFCF68677049693BD
+:101D8000FFFC07880008E00015489793FFFCF686E3
+:101D90001DD49693FFFC9013FFFCF686766896930D
+:101DA000FFFC07880008E000161C9793FFFCF70271
+:101DB0000022F70576F4F70576F8F00576FCF005D5
+:101DC00077008796FFFC8296FFF802140000013C22
+:101DD0000000000000019293FFFC02900008F7044D
+:101DE00076F400000001203A0022E6011E01000006
+:101DF00000019713FFFC07880008E0001584979303
+:101E0000FFFC8796FFFC8296FFF802140000013C5D
+:101E10000000000000019293FFFC02900008F7060A
+:101E200077049713FFFCF70676689713FFFC078883
+:101E30000008E00014F49793FFFC8796FFFC82965D
+:101E4000FFF802140000013C000000000001000047
+:101E500000009293FFFC02900008F686781096939B
+:101E6000FFFCF68678A49693FFFC07880008E00044
+:101E700015489793FFFCF6861FBC9693FFFCF682ED
+:101E800000149693FFFCF68678109693FFFC078863
+:101E90000008E000161C9793FFFCF005789C900268
+:101EA000FF34F7027FFFF70578A09702FF3087968F
+:101EB000FFFC8296FFF802140000013C00000000C5
+:101EC00000019293FFFC02900008F604789C8716AC
+:101ED000000084960008F5867710873A0008F68699
+:101EE000218C7539000477390002A73A6802203244
+:101EF0000000C6A8580084160004C63075809436C9
+:101F00000004B4AA580287360008F605789C073802
+:101F10000001E6011F2D973600088702FF30000000
+:101F20000001C03A4A00EE011F3500000001F485AF
+:101F300078A09482FF308796FFFC8296FFF8021407
+:101F4000000C013C0000000000019293FFFC029095
+:101F500000088596000000000001872E0008F68624
+:101F6000218C77390002A73A6802F604789CC704EE
+:101F7000760086AE0008C6307400F7067710F605C6
+:101F8000789C76B50004C6B470008736000820320D
+:101F9000000007380001E6011FA897360008F70285
+:101FA0007FFFF70578A09702FF308796FFFC8296A7
+:101FB000FFF802140004013C0000000000019293AD
+:101FC000FFFC0290000822100008F704789C000033
+:101FD0000001203A0000E60120D1F6027FFF9616AC
+:101FE000FFF4F6842D40F606771026B4000177350D
+:101FF0000004C4B86000C338000074350002F6065F
+:102000007710C0266200EC0120C1F606218CF38413
+:10201000789CA722600200000001C01E7400E60147
+:1020200020B10000000186A60000F70478A000009F
+:102030000001C6B4720020360000EE01209896A67A
+:102040000000F7042D38F6067710C5186000F686F4
+:102050002C28862A000405B80001F5852D3877392B
+:102060000002202E0044E6012070B63A6802F00516
+:102070002D38862A000800000001962A000CF6067A
+:10208000218CA722600200000001C7047600C71C53
+:102090007400E00120B0F705789C8616FFF400007C
+:1020A0000001C0366200EC0120B0000000019696ED
+:1020B000FFF424A4001023180010E0011FFC2420CA
+:1020C00000048616FFF400000001F60578A09602D1
+:1020D000FF308796FFFC8296FFF802140000013C57
+:1020E0000000000000019293FFFC02900008871698
+:1020F000000000000001873A0008F6867710773963
+:102100000004C738680086BA000C873A000800004F
+:102110000001C0367200440C00018796FFFC8296D5
+:10212000FFF802140004013C00000000000192933B
+:10213000FFFC02900008F702000F203A0000EC01BB
+:10214000215DF68677189036000027380001C60416
+:102150000000C03A6200E601214406B40010F60611
+:1021600078A49613FFFCF60678109613FFFC0788F8
+:102170000008E00014F49793FFFC8796FFFC82961A
+:10218000FFF802140000013C000000000001000004
+:102190000001000000020000000400000008000030
+:1021A000001000000020000000400000008000003F
+:1021B0000100000002000000040000000800000010
+:1021C000100000002000000040000000800000001F
+:1021D00000009293FFFC02900008F70678B0971376
+:1021E000FFFCF70679CC9713FFFC07880008E00096
+:1021F00015489793FFFCF706222C9713FFFCF70274
+:1022000000159713FFFCF70678B09713FFFC0788BB
+:102210000008E000161C9793FFFC8796FFFC82964F
+:10222000FFF802140000013C00000000000192933E
+:10223000FFFC02900008F6846F440000000187361E
+:10224000000000000001203A0002E6012270F602C0
+:10225000000087360EF486B60EF800000001C03A82
+:102260006A00470C0001203A0000E6012278203283
+:102270000000F602000120320000E6012294000076
+:102280000001F70432E800000001203A0000E601F6
+:1022900022B1F58203E80F814000F70479C80000FD
+:1022A000000107380001F70579C8F70479C8F582FD
+:1022B00003E89593FFFCF58200159593FFFCF586E6
+:1022C00079CC9593FFFC07880008E0011EC0979326
+:1022D000FFFC8796FFFC8296FFF802140000013C89
+:1022E0000000000000019293FFFC02900008F70636
+:1022F00079CC9713FFFCF70678B09713FFFC07889B
+:102300000008E00014F49793FFFCF70679CC9713CC
+:10231000FFFCF706793C9713FFFC07880008E000F4
+:1023200014F49793FFFC8796FFFC8296FFF8021443
+:102330000000013C000000000001C13C0000021050
+:1023400000049293FFFC029000082210000C859676
+:1023500000000000000186AE0004000000012036ED
+:102360000000E60123842714000C872E00040000DF
+:10237000000107380001972E0004872E0004E001B9
+:1023800024349696FFF49713FFFC85160004000092
+:1023900000019513FFFC9593FFFC9596FFEC0788D1
+:1023A0000008E00125689793FFFC8596FFEC20224A
+:1023B0000000E60124340000000186AE0004861609
+:1023C000FFF400000001C0366200EE0124217735E1
+:1023D0000001C738680077390002C6B85800773165
+:1023E0000001C738600077390002C73858008536C9
+:1023F0000000000000019536000C85360004000046
+:102400000001953600108536000800000001953661
+:10241000001426B4000CC0367200EE0123EC00005C
+:102420000001872E00040000000107380001972EEC
+:102430000004872E00048696FFF485160004773585
+:102440000001C738680077390002C72C7000852A60
+:10245000000000000001953A000C85160004000001
+:102460000001852A000400000001953A001085163D
+:102470000008F4020001953A001496AE0008879611
+:10248000FFFC8296FFF80214000C013C00000000E3
+:1024900000019293FFFC029000082210000C859628
+:1024A000000000000001842E000400000001202232
+:1024B0000000E60125552714000C9713FFFC851634
+:1024C0000004000000019513FFFC9593FFFC959616
+:1024D000FFEC07880008E00125689793FFFC8596CC
+:1024E000FFEC20220000E6012555000000018616C1
+:1024F000FFF40000000120320000EE012545773195
+:102500000001C6AC0000C738600077390002C73848
+:10251000580085360018000000019536000C8536FD
+:10252000001C0000000195360010853600200000D8
+:1025300000019536001406B4000CC0367200EC01A0
+:10254000251100000001872E0004F4020001273845
+:102550000001972E00048796FFFC8296FFF8021474
+:102560000008013C0000000000019293FFFC029073
+:102570000008221000088396000483160000C5009E
+:102580000000841A0004C4A800009416FFF4C026BA
+:102590004200E60126D1000000018316FFF400008E
+:1025A0000001C02A3200E60126D1C7204A00951654
+:1025B000FFF476B8FFE1C73868007739FFFFC5241C
+:1025C000700077290001C738500077390002831660
+:1025D0000000869E0000C5B8300005AC000C872EB8
+:1025E0000000C6000000C0367200E601261020324E
+:1025F0000000869E0004872E000400000001C03603
+:102600007200E601261020320000F602000120329E
+:102610000000E601262500000001C7000000E001DF
+:102620002678203A0000869E0000872E00000000D9
+:102630000001C0367200E201265C00000001E601E4
+:10264000266420320000869E0004872E00040000CD
+:102650000001C0367200E201266520320000F60259
+:102660000001203200004704FFFFE6012679203AEE
+:102670000000F7020001203A0000E60126B1203AEE
+:102680000000EE0126A0203A00014304FFFFC03AFB
+:102690003200E60126C9C0264200E0012590000074
+:1026A0000001E60126C1C0264200E001259000009D
+:1026B000000183160008F4020001E00126E0951AEB
+:1026C0000000E001258CC4A80000E001258CC4288E
+:1026D00000008316000800000001941A0000C400E6
+:1026E00000008796FFFC8296FFF80214000C013C64
+:1026F000000000000001000000009293FFFC029027
+:102700000008859600048416000084960008F702ED
+:102710000003C6A04D80C6B67400E6012771C6202E
+:10272000000020360002E60127A0C5204800C7208F
+:10273000480027380002C0227200E201279CC538F9
+:102740000000872E000076AD001E76B4FFE5C73886
+:102750006FC07738FFF0F733280006300002C03230
+:102760005200E201274105AC0002E00127A0C5208C
+:102770004800C720480027380004C0227200E20148
+:1027800027A0C520480083AD00040000000193B1DC
+:102790000004C0327200E201278500000001C5205C
+:1027A0004800C0325200E40127D50000000186AE87
+:1027B0000000772D001E7738FFE5C6B477C076B5E8
+:1027C000FFE8F6B3680006300001C0325200E401B1
+:1027D00027AC05AC00018796FFFC8296FFF8021437
+:1027E000000C013C0000000000019293FFFC0290ED
+:1027F0000008841600008696000400000001C7222D
+:102800006D80E601281020360000E0012874C438ED
+:102810000000F7020001EE012841F602000076B543
+:10282000000120360000EE01281C77390001E0018C
+:10283000284420220000742100017738FFFF063071
+:10284000000120220000EE012834203A0000E601B9
+:10285000287100000001C0226A00E4012864000021
+:102860000001C4206A00773AFFFFE601285476B4DD
+:10287000FFFFD42007628796FFFC8296FFF80214C0
+:102880000008013C0000000000019293FFFC029050
+:10289000000822100004E00128CCF70629DC86BAE3
+:1028A00000000000000120360000E60128C90000F9
+:1028B00000019716FFF407880008C13400009793C1
+:1028C000FFFC8716FFF40000000127380004F6061D
+:1028D00029E0C03A6200E401289D000000018796CB
+:1028E000FFFC8296FFF802140000013C000000008B
+:1028F00000019293FFFC0290000822100004E00106
+:102900002934F706299886BA000000000001203615
+:102910000000E6012931000000019716FFF4078846
+:102920000008C13400009793FFFC8716FFF40000F5
+:10293000000107380004F60629E0C03A6200E4010D
+:102940002904000000018796FFFC8296FFF802141C
+:102950000000013C0000000000019293FFFC029087
+:102960000008F7047B5000000001203A0000E60157
+:102970002984F6820001F6857B5007880008E00173
+:1029800028F09793FFFC8796FFFC8296FFF80214CD
+:102990000000013C00000000000100000B4C0000A2
+:1029A0000000000042880000000000005E500000AF
+:1029B00000000000C7A80000000000010BD00000CC
+:1029C000000000011C880000000000011E1400002F
+:1029D00000000001212C00000000000122E40000A2
+:0229E0000000F5
+:00000001FF
+/* This is the Myrinet MCP code for LANai4.x */
+/* Generated by cat $MYRI_HOME/lib/lanai/mcp4.dat > myri_code4.h */
diff --git a/firmware/qlogic/1040.bin.ihex b/firmware/qlogic/1040.bin.ihex
new file mode 100644
index 00000000000..d1213307f71
--- /dev/null
+++ b/firmware/qlogic/1040.bin.ihex
@@ -0,0 +1,2111 @@
+:1000000007410600001078003A1000005841000037
+:100010004320504F525947495448312039392035EF
+:100020004C51474F43494320524F4F50415249543E
+:100030004E4F49205053303130324920542F462002
+:100040007269776D726120655620726569736E6F93
+:1000500030202E3735362020432073756F74656D40
+:1000600020726F4E202E303050206F727564746392
+:100070004E202E6F2020313024200120FD0404204A
+:1000800082A005004800451038004B10780047104A
+:1000900028004B10B920121278004D10B9202222EE
+:1000A000C120080071201000C3700400C920FF782F
+:1000B00089208611C7705349CB702050CF70202003
+:1000C000D3700700003FD670C1200800192000003F
+:1000D0000920FFFE00210B20A5A5ECA1FF7F642DC8
+:1000E0006B200A0ADCADFF3F542B5B2050501421DB
+:1000F00086A2A5A54000BF1086A30F004000851072
+:100100006A2C5A2AC120000019200F0078006510BF
+:100110006A2C5A2AC12008000920FF7F482144295F
+:100120004B200A0ABCA9FF3F34273B205050142122
+:1001300086A20A0A4000A9104A283A26C1200400D3
+:100140000920FF3F34210B205050142186A250502B
+:100150004000AA1078008E114A283A26C09888A13B
+:1001600000102C210B20A5A5142186A2A5A54000D6
+:10017000BC100A258AA10010C1987800C1100A2578
+:100180007800C1106A2C5A2A30218AA14000282107
+:10019000A2A10052248424842484248424842484DA
+:1001A00092A1007909200000012031007810261D5D
+:1001B000182279200052A02F082411200000A92025
+:1001C0004000A4420981C000DC10F27E2885E67D53
+:1001D000EA7CEE7B8378000031203000CF7801018B
+:1001E0000B7802000F7802004F780300692040521C
+:1001F0000120FD04042082A00500480004113800FD
+:100200000011780008111B683C0078000A11A80052
+:1002100008111B683C001B682800076807000B6872
+:10022000FA000F68080013680500236800002768BB
+:100230000600176808002B6800001F681900692075
+:10024000805411202000092010000B680C080F6852
+:100250001900036800FD076818001A6A002DE8A05D
+:10026000080090A204000981C000221169200055F5
+:1002700009200200A9200001376800000B68400037
+:10028000F07B86A3FFFEC0004811176800011F68BD
+:10029000640078004C11176864001F680200E8AD24
+:1002A000100070005211780039110981C000371117
+:1002B0007810A72278103D497810B5197810334E80
+:1002C000003285A00D009020C370000090006C11DA
+:1002D000C07086A00200C0006C11781084127810E3
+:1002E0009611CC7805A0C0007A1178104F1D10002F
+:1002F000801168008011781086211000801168003C
+:1003000080117810B91AE0006C117810BA4C78009E
+:100310006C118E119011AC24AC24BE49BE49AC24A2
+:10032000AC2478008E11780090117800921178003A
+:1003300094116800011261200000186084A001007F
+:10034000C0000112147805A0C000A711100002120D
+:100350007800011209205B52042105A0C00001129F
+:10036000092064520B200000147986A14200C000CD
+:10037000CC1116780920625264210B20000018600D
+:10038000C6701460CA701C618CA100FF206084A03C
+:10039000FF0005A1CE7078109A197800FF1114782B
+:1003A00086A01800C000D3117810781617780000C6
+:1003B00009206252042165A04000EF117E0C9C6070
+:1003C00060207810171A7F0C9F60000078104E177D
+:1003D00009200C000760030178107619C000FB119A
+:1003E00078109A19092062520B20000009205C52F3
+:1003F00004210B20000005A04000FF110120054052
+:1004000078008612780084127C00C3700000C770E8
+:100410000000CB700000CF700000C070BCA0C0FF17
+:10042000C00052123820790012128412E512A9126B
+:10043000FE120D131313A012661717139812AD12A4
+:10044000AF12B112B3126B179812291365139016DD
+:100450006017B512AF15CB15E7151216681576158E
+:100460008A159E15E913981297139D13A213A713CB
+:10047000AD13B213B713BC13C113C513DA13E613CC
+:100480009812981298129812F513FE130D14511425
+:100490005B146214A814B714C614D8144815581560
+:1004A00098129812981298125D15BCA0A0FFC00077
+:1004B0009812382084A01F0079005B12A417A71798
+:1004C000B7179812981231194E199812981298125B
+:1004D00052195A199812981298129812DB12F412A3
+:1004E0001F135B1386168217961798124718601908
+:1004F0000D1917191B19291998129812CA72C67169
+:100500000120064078008612CE73CA72C67101209F
+:100510000040C27068008712612000001B6001006B
+:1005200091200050E0008F12E000911268009112BB
+:10053000912080407C00C370014078008712C37016
+:1005400006407800871299204100A1204100A9208F
+:100550000500A35378008412C470C37004007A00AD
+:100560007800841278008412780084127800841253
+:1005700091200080C3700000C7705349CB70205099
+:10058000CF702020D3700700003FD6707920000084
+:100590001B78010031203000592000102920570419
+:1005A0005120700461207204B920FFFFC1200000B7
+:1005B0009120005091208040780055047810C41B91
+:1005C000C0009C12D875DC74DA75DE747800E8120D
+:1005D000292000002025D071C873CC72C470781017
+:1005E000FE1A40008412C370024078008412781012
+:1005F000C41BC0009C12D875DC74DA75DE747800F8
+:100600000113292000002025D071C873CC72C4705A
+:1006100078105E1B40008412C37002407800841280
+:10062000C471C87014210A2078008212C471142188
+:1006300078008212C7700700CB704100CF700600AF
+:10064000780084127810C41BC0009C12D875DC7628
+:10065000DA75DE7678002C13292000003025C4706E
+:10066000C872CC73D074C670CA72CE73D27405A02F
+:10067000400055130AA440003C13C80046130180F3
+:10068000927884A000FC40004A13CC7885A0010039
+:10069000CE7801200540780086129A7A9E7BA27D52
+:1006A000A67E967CCC7884A0FCFFCE787800591387
+:1006B000CC7885A00100CE78780084127810C41B15
+:1006C000C0009C12D875DC76DA75DE767800681387
+:1006D000292000003025C470C872CC73D474C67051
+:1006E000CA72CE73D67405A0400091130AA44000CC
+:1006F0007813C80082130180AE7884A000FC40000B
+:100700008613CC7885A00001CE78012005407800C2
+:100710008612B67ABA7BBE7DC27EB27CCC7884A0CB
+:10072000FFFCCE7878009513CC7885A00001CE78B8
+:1007300078008412092061520C21EC7A7800821230
+:10074000092041520C2178008312092042520C21C9
+:1007500078008312612040520C611062780082128E
+:10076000092045520C2178008312092046520C21A1
+:1007700078008312092048520C2178008312092046
+:1007800049520C217800831208790C7A7800821281
+:10079000C471078184A00F00038003800380E8A058
+:1007A0008054006A046884A008004000D713086BD6
+:1007B0007800D8130C6B78008112C4777810C519B3
+:1007C000912000801C6B146A91200180082778001A
+:1007D00081124C7978008312C4777810C519912062
+:1007E00000800869186A106B9120018078008112DE
+:1007F000C47182A11000C8007C1278107F23780099
+:100800008112C47182A11000C8007C1211204152D3
+:1008100004227E001221781038237F017800831291
+:10082000C47119200001042382A0060048001B1493
+:1008300011204914A920080078001F141120411428
+:10084000A9200800042206A140002A14108270008A
+:10085000281478001F1478007C12042382A006005C
+:100860004800331492A249147800351492A241141E
+:100870007E0211204252042212217F017E00781054
+:1008800044237F0178008312E803FA00F401EE02AA
+:100890006400190032004B00E803FA00F401EE0294
+:1008A0000400010002000300612040520C6110624C
+:1008B000C4700E60C87012607800821261204052CD
+:1008C0001461C47016607800831261204052C471B4
+:1008D000112004001F6019001920121286A128009F
+:1008E00040008314112005001F6019001920121206
+:1008F00086A1320040008314112006001F600C0006
+:100900001920222286A13C00C0007C1218607E00C3
+:100910001A61007884A00100C0009E140120FD042B
+:10092000042082A005004800961438009A1478002C
+:100930009E1428009A1478009E1419202222780010
+:10094000A01419201212B823781055237810334EB2
+:100950007F0178008312C47184A1CFFFC0007C1294
+:1009600011204852042212217E00781077237F0143
+:1009700078008312C47182A11000C8007C1211207B
+:10098000495204227E001221781066237F017800EC
+:100990008312C471C87284A1FDFFC0007B1284A2BF
+:1009A000FDFFC0007B12002108790A7800220C7A32
+:1009B0000E7878008212C471078184A00F00038032
+:1009C00003800380E8A0805419200000C872BCD2C4
+:1009D0004000E9149DA31000B4D24000EE149DA382
+:1009E000080000687E0026A240001115026A84A457
+:1009F00000204000FA149DA3100084A400104000C1
+:100A000000159DA3080084A40040400011150F812B
+:100A100084A2004040000D1578109923780011152C
+:100A200078108B2378001115CC72086806A240005C
+:100A30004015A4A2FF0061204052186186A1280041
+:100A40004000271586A1320040002D1586A13C00EC
+:100A50004000331582A4640048003D157800371526
+:100A600082A4500048003D157800371582A4430049
+:100A700048003D15C471C6717F02CA7278007D12AC
+:100A80000A6A9DA30A00046805A306687F020C6B2E
+:100A9000C47178008112C4777810C5199120008044
+:100AA000146A1C6B91200180C8701668CC701E6897
+:100AB000082778008112C4704C794E787800831230
+:100AC000C471C872CC7382A11000C8007C12781067
+:100AD000A72378008112C4777810C519912000806F
+:100AE000086A95A202000A6A91200180082778000E
+:100AF0008212C4777810C51991200080086A94A2E8
+:100B0000F9FF0A6A046805A04000851578106F2275
+:100B100091200180082778008212C4777810C519C7
+:100B200091200080086A95A204000A6A046805A062
+:100B30004000991578106F229120018008277800D5
+:100B40008212C47741200100492005005120200075
+:100B5000912000807810D219912001800827086A1E
+:100B600078008212C477C872CC73C677CA72CE730B
+:100B70007810521AC000C715186805A04000C715A4
+:100B800008277810B723C000C715177815009120E3
+:100B900001807C009120018078008412C477C677A0
+:100BA0004120210049200500512020009120008093
+:100BB0007810D219612040526F6003008267936001
+:100BC0000F00736000001778160078106F229120D4
+:100BD00001807C00C877CA77C477C677BCA700FFBE
+:100BE00091200080612040526F600200736000001D
+:100BF000826793600F001778170078106F2291209A
+:100C00000180412021004920040051201000912042
+:100C100000807810D219C8703668388784A71F0002
+:100C2000C0000616912001807C00CC7884A00300CF
+:100C3000C000361639200000412021004920040060
+:100C4000512008007810C5199120008008680DA86F
+:100C50000A6991200180388784A71F00C0001F16F1
+:100C6000BCA700FF3F8738873F8784A7000FC000DD
+:100C70001F169120008069200001306884A0400088
+:100C800040005F164B680400A9201400486884A047
+:100C9000040040004C1670004C16780043164B6858
+:100CA0000900A9201400486884A0010040005916DA
+:100CB0007000591678005016A920FA0070005F16CF
+:100CC00078005B1679200052177818006120405296
+:100CD0006F6001007360000093600F00CC7885A006
+:100CE0000200CE78086884A0FDFF0A681B684800EF
+:100CF000912001807C00CC7884A0FDFFCE7884A078
+:100D00000100C000821678109C1AC471C6714A791D
+:100D10007C007810C41BC0009C12D875DC74DA7596
+:100D2000DE7478009316292000002025C471C87352
+:100D3000CC72C671CA73CE727920005291200080A5
+:100D4000781080199120018040004A17A9200500E1
+:100D5000A120185291200080A141912001800920FA
+:100D6000200078107B194000B61678109A19780088
+:100D70004A17046084A000FF07800980400019170B
+:100D80007E0C682C912000807810801991200180C1
+:100D90004000EA16002C9E680981C000BE169F60C4
+:100DA00000007F0C7E0C18721C7320742475682C54
+:100DB0009C6865A0400018170920200078107B1956
+:100DC000C0000117046084A0FF0086A00200C000DC
+:100DD000EA16002D02607800D0167F0C7E0C9C6015
+:100DE00060207810171A7F0C9F60000078104E1753
+:100DF00009200C00086085A000020A6078107619AE
+:100E000078109A1978004A177F0C7E0C9C6060203D
+:100E10007810171A7F0C9F60000078104E17092079
+:100E20000C00076003011B6003007810761978102E
+:100E30009A1978004A177F0CC474C873CC72146076
+:100E400091200080177812007E0E712040526F7042
+:100E500005007370000076737A727E7482708770FA
+:100E60000000002C8A708F7000002EA030251C61BD
+:100E7000A26184A1600040003C177810D3487F0E27
+:100E80009665A6659A66AA66AF600000B36000002A
+:100E900078106F22912001807C00C370054078009B
+:100EA0008712A920050099201852912000800A532A
+:100EB00091200180002110A299A30000A1A40000AC
+:100EC000A9A500007C00C471C770000006797800F5
+:100ED0008412C471C671682178006D1769200010F2
+:100EE0000C6916A0042D10A2688D0981C0006F172F
+:100EF00085A20000C0007D17C370004078007F17F6
+:100F0000C3700340CA7078008712112067520C2208
+:100F1000C470038048008F177810513C84A1FF7F74
+:100F2000780093177810443C85A100801220780047
+:100F30008312C47178103B3C006101206752042089
+:100F400084A000800DA10462086378008112E47916
+:100F500078008312C471C6719821A1204200A92093
+:100F60000400A353A02199204200A9200400A35308
+:100F700078008412C470682079200052912000808B
+:100F8000781080199120018040004318076001000B
+:100F90000B6000002B6000001B600600106A8CA232
+:100FA0000F0084A2F000038003800380038005A16A
+:100FB000166084A200084000DE171B600A0078005B
+:100FC000E41784A200104000E4171B600C0084A208
+:100FD00000034000ED172B600100048004800480B2
+:100FE00085A001001E60236000002760000084A22D
+:100FF00000044000FA172B600000A920060080AC16
+:101000000B00A02080AD05009820A35384A200030C
+:10101000C0000F1846604A604E60526096609A6049
+:10102000780019180068466004684A60086E4E66C9
+:101030000C6D526596659A66146091200080177851
+:101040004200082C612040526F6005007360000070
+:10105000776000007B6000007F60000082608A6132
+:1010600084A200048E60912001807E0E71202000F9
+:1010700007700A0007700200037000007F0E9120C5
+:10108000008078106F22912001807C00C3700540A1
+:10109000780087127E0C7E0D7E0E7E0F91200080E0
+:1010A000712040527920000161201000A0706DA0D5
+:1010B00040000319046A94A2FF0086A207004000C2
+:1010C000621886A20F00C00003191C6984A1C00029
+:1010D0004000031984A18000C000D318246884A0B4
+:1010E00000FF85A019002668B071FF8140008918B3
+:1010F0007E0D69202000076810000869086806A1B5
+:10110000C0007A180C690C6806A1C0007F1884A181
+:10111000FF00C0007F187F0DB87884A01F80C0003A
+:101120008918487885A00C004A78B071FF8140008A
+:10113000AC18B37000007E0D69202000076818000D
+:10114000046884A00800C0009D18076808000468AF
+:1011500084A00800C000A418076802007F0DC461C5
+:10116000C862CC63C661CA62CE637E0E7120005233
+:1011700066726A7380AE19007F0E487884A00C00F6
+:10118000C000BA187810E147A3780000587884A00E
+:10119000FFED5A78B47080A0DA001A787F0F7F0EC6
+:1011A0007F0D7F0C9120018078008412246884A038
+:1011B00000FF85A019002668B87884A01F80C000B1
+:1011C000D918487885A00C004A78487884A00C008B
+:1011D000C000E218B071FF8140000119B370000037
+:1011E0007E0D6920200007681800046884A00800AC
+:1011F000C000F21807680800046884A00800C00056
+:10120000F918076802007F0D7800CB187F0F7F0E5A
+:101210007F0D7F0C9120018001200540780086120F
+:101220008079C671C47182A10300C8007C128279E2
+:10123000780084128079C671780084127479C6713E
+:10124000C47176797879CA71C8717A797C79CE71EE
+:10125000CC717E79780084127479C6717879CA71FC
+:101260007C79CE71780084120079C671C4710279DC
+:101270000120FD04042082A0050048004019380028
+:10128000421978004C19A8004C198CA10100C0002B
+:101290004A19B920222278004C19B920121278007C
+:1012A00084120079C67178008412092074520421D6
+:1012B000C670C4700A207800841209207452042178
+:1012C000C67078008412C471078184A00F00038067
+:1012D00003800380E8A08054146AB4D240007119DE
+:1012E0001120010078007319112000000C6B7800A8
+:1012F000811280AC01007810801B7C0080AC010062
+:101300007810201B7C00507865A040008819042CC0
+:101310005278632000007C007E0F792000525078C4
+:101320006DA040009819042D5278036800000768EA
+:1013300000000B6800007F0F7C00912000807E0F72
+:101340007920005250786220002C05A0C000A71917
+:1013500078108C2452787F0F912001807C007E0FC2
+:101360007920005250786A20002D52787F0F7C003F
+:1013700011200079527AEC7B19834000C21980A2B7
+:101380003100122010207800B919132000007C00D1
+:1013900084A7000F0B8084A71F00038003800380B5
+:1013A000038005A1E8A000557C007810C51900292C
+:1013B0002A68002A2E68086884A0EFFF0DA80A6931
+:1013C000092052520C21046805A04000041A16A1FD
+:1013D000C000EF196020006006687E010B2000004D
+:1013E0007800F219092000007E01046865A0400021
+:1013F000011A006006687810311A7810CB1C10684A
+:1014000001801268C000F2197F01026906697C0040
+:1014100065A04000161A08209C6005A04000131A21
+:1014200062209F60000065A07800091A5078527908
+:1014300062207C0065A04000301A08209C6005A056
+:101440004000251A62209F60000065A078001B1AEA
+:101450007E0F7920005291200080507852797F0FC2
+:101460006220912001807C00076003018F600000F2
+:10147000A9201C0080AC0500A02001200000A44091
+:1014800028681A602C6822607C007E0E7120405211
+:101490004C708CA00002C000501A88A080520A2D07
+:1014A00000804E7006A07F0E7C007810C519912038
+:1014B000008004681E7865A040009B1A7800631ABB
+:1014C000002C1E78006065A040009B1A0C6006A3EB
+:1014D000C0005D1A106006A2C0005D1A282C012011
+:1014E0005252042006ACC000741A7800991A04689D
+:1014F00006ACC000811A006065A00668C0008B1AA7
+:101500000368000078008B1A00641C786020026475
+:1015100086A40000C0008B1A002C02686025781099
+:10152000311A1B600500236020007810CB1C106866
+:10153000018050108C24126885A0FFFF7C003920A8
+:101540000000412021004920040051200800912082
+:1015500000807810D219388784A71F00C000A61A0F
+:10156000BCA700FF3F8738873F8784A7000FC000D4
+:10157000A61A912001807C0061200000186084A0E0
+:101580000100C000CA1A91200080E078E3780000D2
+:101590009120018005A0C000CB1A7C008CA0F0FF38
+:1015A0004000D11A78108C247900D31AE31AE61A75
+:1015B000EC1AF01AE41AF41AFA1AE41AE41A951C4E
+:1015C000B91CBD1CE41AE41AE41AE41A7C00781071
+:1015D0008C2478109C1A012001807800C31C012003
+:1015E00003807800C31C012004807800C31C78109D
+:1015F0009C1A012006807800C31C01200780780017
+:10160000C31C3020382182A721004800061B092076
+:10161000200000267810201BC0001F1BBAA7200046
+:1016200048001E1B40001E1B0827B0A6200090A2E9
+:10163000400099A30000A1A40000A9A50000780023
+:10164000001B06A07C00FF8140005B1B992030003E
+:10165000A0200C7084A0FF004000321B0770040023
+:10166000047084A00400C0002D1BA8211770000086
+:101670000B8112711A721E73227426750C7885A064
+:1016800001000270077001000120FD04042082A007
+:101690000500C8004F1B09202200042184A000403F
+:1016A000C000411B08700B80C800411B077002007E
+:1016B0008CA0E001C0005B1BA55306A003700000D6
+:1016C0007C003020382182A721004800661B0920B9
+:1016D000200000267810801BC0007F1BBAA72000C6
+:1016E00048007E1B40007E1B0827B0A6200090A269
+:1016F000400099A30000A1A40000A9A50000780063
+:10170000601B06A07C00FF814000C11B9820A12027
+:1017100030000C7084A0FF004000921B0770040092
+:10172000047084A00400C0008D1BA8211770000065
+:101730000B8112711A721E73227426750C7885A0A3
+:1017400000000270A653077001000120FD04042070
+:1017500082A00500C800B01B09202200042184A03B
+:101760000040C000A21B107084A000F04000B91B14
+:10177000077008007800BD1B08710381C800A21B18
+:101780000770020084A1E001037000007C000120CA
+:10179000FD04042082A00400C800CD1B7800D01BEB
+:1017A00006A07800D21B85A001007C007E0E71206F
+:1017B0000052082D5870026805A0C000DD1B5E7144
+:1017C0005A717F0E7C00082C5878026005A0C0007A
+:1017D000E71B5E795A797C009120008014617810B3
+:1017E0008021006984A10001C000352084A100028D
+:1017F000C00031201C6805A0C0003D20036000002F
+:10180000082C5C7865A0C000051C5A797800061C7D
+:1018100002615E799120018078108C227C007E0E1E
+:101820007120005258706DA040001A1C00685A7058
+:1018300005A0C000191C5E70FF8D7F0E7C007E0D20
+:101840007E0C7E0F7920005280AF16006020006071
+:1018500005A04000431C6820146806A3C000331C88
+:10186000286884A0FF0006A44000361C602D780084
+:10187000241C006805A00260C000421C80AF160056
+:1018800006AC4000411C002C5E78002D7F0F7F0CC1
+:101890007F0D05A07C007E0D7E0C7E0F792000520E
+:1018A00080AF16006020006005A040006B1C68201F
+:1018B000146884A0FF0006A340005E1C602D780021
+:1018C000501C006805A00260C0006A1C80AF1600B2
+:1018D00006AC4000691C002C5E78002D7F0F7F0C49
+:1018E0007F0D05A07C007E0D7E0C7E0F79200052BE
+:1018F00080AF1600602000606DA04000901C14684E
+:1019000006A34000831C602D7800781C006805A0A9
+:101910000260C0008F1C80AF160006AC40008E1C19
+:10192000002C5E78002D7F0F7F0C7F0D05A07C00C2
+:101930009120008069204052006886A0000040008D
+:10194000A31C91200180E37809007C008068BCA082
+:1019500000FF412021004920040051201000781090
+:10196000D219388784A71F00C000AC1C91200180C9
+:1019700001200A807800C31C01200C807800C31C61
+:1019800078109C1A01200D807800C31CC270612061
+:1019900000001B600100912080407C000460082C46
+:1019A00063200000847800808678887805A08A7992
+:1019B0004000DA1C022C7800DB1C8E797C00076862
+:1019C00003017E0C61200052082D6B200000846012
+:1019D00000808660886005A08A614000EF1C022DAF
+:1019E0007800F01C8E617F0C7C007810031D400095
+:1019F000021D7E0C9C6065A04000FD1C7810171A2B
+:101A00007F0C9F60000078109A197C008C7865A08C
+:101A10004000151D91200080847801808678042C78
+:101A20008E7805A0C000131D8A7800809120018067
+:101A30007C00A920100006A0048086808E81C8004A
+:101A40001F1D00A27000231D78001A1D86808E8144
+:101A50007C007E15A920100005A04000491D1AA198
+:101A6000C800491D13828D8148003A1D1AA1C80083
+:101A70003B1D7000411D78002F1D1AA10823108204
+:101A80007000411D78002F1D7E00003284A0FFF7FA
+:101A900080207F007F157C007E00003285A000083A
+:101AA0007800451D9479D07006A14000BD1D91209D
+:101AB000008071202000047005A0C000BD1D0870CA
+:101AC000087206A2C000BD1D86A20800C000BD1D90
+:101AD00071201000781080194000BD1D9C7A987B01
+:101AE000A47CA07D84A100FF40008B1D312000005C
+:101AF0000B81B5860B81B5860B81B5860B81B586CA
+:101B00000B81B5860B81B586002110A2002619A392
+:101B1000A1A40000A9A500007800951D07810480FC
+:101B2000048010A299A30000A1A40000A9A50000B0
+:101B30000920200078107B19912001804000B41DFD
+:101B400078109A19A8780080AA7886A00200C000B0
+:101B5000BD1D91200080E3780200AB780000CC78B6
+:101B600085A00300CE78912001807800BD1DAB7860
+:101B7000000078104921046084A00F007900C21D84
+:101B800071201000912001807C00D21DF41D1A1ECE
+:101B9000D21D371EE11DC91FE41FD21DEE1D141EEC
+:101BA0007F1EEE1E571F691FE01F39200004DC78DE
+:101BB00005A7DE78086005A70A60781064209C609D
+:101BC000DA78781031217C00DC7884A000014000B4
+:101BD000E81D7800D21D1C6085A080001E60780082
+:101BE000FB1D7810C41BC000D21D78106321DC7867
+:101BF00084A000014000FB1D7800D21DDF780000AA
+:101C00000460078084A0FF00D27801809F600000FC
+:101C10004000111E781064204000111EDC7885A061
+:101C20000001DE787800131E781088207C00781080
+:101C3000C41BC000D21D78105F21DC788CA0000E80
+:101C4000C000231E84A00001C000251E7800D21D04
+:101C500078106420C000361E04618CA1FF0086A1AC
+:101C600007004000212086A10F00400021207810AD
+:101C700088207C00DC7884A0000140003E1E7800B3
+:101C8000D21DDF780000146711200100A920010097
+:101C9000186084A0FF0005A04000611E1120010013
+:101CA000BCA700FFA92020008EA001004000611EFB
+:101CB0003920000011200200A92000018EA002009E
+:101CC0004000611E78007C1E7810C51991200080AC
+:101CD0002B6800002F680000086884A0DEFF0A68F7
+:101CE000E8AD1000912001807000751E7800631E21
+:101CF000118240007C1EA92000017800631E78102C
+:101D00009A197C0001206752042084A000804000C2
+:101D10004920146178108021006984A101004000ED
+:101D2000A01E286084A0FF00C0004120006884A09D
+:101D3000010040004920036800000B6800000768AC
+:101D4000000078005120112001002060F4D04000F4
+:101D5000A81E95A20200C4D04000AD1E95A20800A6
+:101D6000CCD04000B21E95A200041C6084A00200EA
+:101D70004000B91E95A204002C608CA0FF0082A137
+:101D8000020048004D2082A11B00C8004D204000E9
+:101D90004D200E692C6007808CA0FF0082A10200FC
+:101DA00048004D2082A11B00C8004D2040004D205E
+:101DB0001269306005A0C000DC1E01201E000080FA
+:101DC0001668286084A0FF0040004920066828604B
+:101DD000078084A0FF00400049200A68026A78005A
+:101DE000512001204052042086A00700C000531F4C
+:101DF00001206752042084A0008040004920146123
+:101E0000781080210120525204201020FF824000CF
+:101E10000E1F80A00500042084A0FF0006A1C000C2
+:101E2000531F91200080046A086B186484A4030087
+:101E300040002D1F28618CA1FF000180C000231FDE
+:101E4000002110A24800531F78002D1F0180C00000
+:101E5000531F002112A24800531FFF824000531F4E
+:101E600084A40C004000471F28610F818CA1FF0053
+:101E700082A00400C0003F1F002118A34800531F88
+:101E80007800471F82A00400C000531F00211AA33E
+:101E90004800531F306005A040004D1F00801668A9
+:101EA000066A0A6B91200180780051209120018000
+:101EB00078004D2014617810802191200080086BFB
+:101EC00018834800651F0A6B91200180780060200C
+:101ED0009120018078004D202460078084A0FF00BD
+:101EE0004000871F86A08000C000C71FA9200800EF
+:101EF0006920107691200080006884A0FFFC0268B1
+:101F0000E8AD08007000831F7800791F91200180E0
+:101F100078005120286015A04000C71F1461781078
+:101F200080217E0C7E0DE8AD0700912000800068C6
+:101F30000DA04000C31F06A240009E1F682178002C
+:101F4000941F602100600268682C7810AC197F0D26
+:101F500018680DA04000BB1F602000621A6A1C6A4E
+:101F600002621E6878108919A02D9821A9203100DD
+:101F7000A353602D7810CB1C7800BE1F086800802A
+:101F80000A68912001807F0C7800602091200180F8
+:101F90007F0D7F0C78004920146178108021006843
+:101FA00084A001004000392091200080046A108242
+:101FB0004800DC1F066A9120018078006020912093
+:101FC000018078004D207810C41BC000D21D146120
+:101FD00078108021BE60BB600000006984A1080009
+:101FE0004000F31F206085A00001226084A1010051
+:101FF0004000492084A10001C000352084A10002D6
+:10200000C00031201C6805A0C0003D20046084A0F1
+:10201000FF0086A00F00C0000C2078106321DF783D
+:1020200000000460078084A0FF00D27801809F60D8
+:102030000000400021207810642040002120DC783E
+:1020400085A00001DE787C00D7780000DB780000F6
+:10205000246084A000FF26607810AC3A40004F1D39
+:102060007810E91B78004F1D0920170078005320D5
+:1020700009200E0078005320092007007800532023
+:10208000092035007800532009203E0078005320B5
+:10209000092004007800532009200600780053200E
+:1020A000092016007800532009200100246084A034
+:1020B00000FF05A12660912000807810CB1C9120A4
+:1020C000018078004F1D78109A1978004F1DD47840
+:1020D0006DA0C0006F20002CD678DA789F600000D9
+:1020E00078007B20002C9E689F600000D678002D31
+:1020F0000260D87806ADC0007B200260D0780180F5
+:10210000D278C0008720DC7884A0FFFEDE78D87803
+:10211000602006A07C002EA030251C61A26184A155
+:10212000FFE11E6084A16000400097207E0E7810C1
+:10213000D3487F0E9665A6659A66AA66AF600000D2
+:10214000B360000014677810C51991200080A0606A
+:1021500084A00080C000BE20086884A00100400068
+:10216000BE20912001807810311A912000807810D3
+:10217000CB1C91200180D7780000DB78000078002C
+:102180003021246096A00100C000C5200080266098
+:10219000106A14689120018002A24800D4204000F7
+:1021A000D420392000027810312178003021082C09
+:1021B00091200080A06084A0008040000121006880
+:1021C00065A040000621046A7E0E71204052007016
+:1021D00084A001004000FB20487006A2C000FB2044
+:1021E000046B1C2360210263002305A0C000F620BD
+:1021F0000269602202617F0E78000D216021026277
+:1022000006697F0E78000D21006865A04000062158
+:1022100002610269C0000A210669602103600000B2
+:102220006021A06084A0008040001721086884A07D
+:10223000FCFF0A681068008012689120018008681D
+:102240008CA040004000262186A040000A6878103B
+:10225000421A9120008078106F2291200180DB7853
+:102260000000D77800007C00086005A70A60912074
+:1022700000807810CB1C91200180D87865A04000A8
+:1022800044219C60DA789F60000078003421D77880
+:102290000000DB7800007C009079947800800AA12F
+:1022A000C800502106A09678D270047805A040009E
+:1022B0005E2101800678C0005E2168005E219120C9
+:1022C00080407C00392077217800652139207D21EC
+:1022D000042705A04000762100AC6820086B0C6C38
+:1022E0001069146A0A690E6A126B166C38877800D6
+:1022F00065217C00030009000F0015001B00000091
+:1023000015001B0000007E0C78103B3C682C7F0CF5
+:102310007C001000F7216800F72129200000CB780D
+:1023200000008C7865A04000F0210920745204213F
+:1023300084A001004000BE21046086A00301C0000B
+:10234000BE21186005A0C000BE21146005A0C00019
+:10235000BE217E0D69200000186884A00100C00025
+:10236000BD210C60C6701060CA70C37020801B68ED
+:102370000100912080407F0D7810F21C7800F5213B
+:102380007F0D7810F8214000F021046294A2FF0034
+:1023900096A203004000D021046296A21001C00062
+:1023A000DE21CB780100046294A200FF1782118223
+:1023B0004000DE21FF85C000F021108202A2C8008B
+:1023C000F0217E05781007227F054000EB21E078A0
+:1023D00086A003004000F0217800DE212885C8781F
+:1023E00005A040008E21FF854000F721912080400C
+:1023F000B078D6707C00AC7BB079D47002A1C000FC
+:102400000122002305A07C004800052202A37C00D5
+:1024100002807C000120FD04042082A00500C80089
+:1024200021229120008071202000047005A0C000AE
+:1024300056220870087206A2C000562286A2080022
+:10244000C00056227120100078105B220920200065
+:10245000046086A00301C0003022286005A0C000EF
+:10246000302209200C007810761940004922C478E7
+:102470000080C67886A00200C0005622912000800D
+:10248000E3780300C7780000CC7885A00003CE78FD
+:102490009120018078005622C77800007810F21C45
+:1024A000AC79B07800800AA1C800542206A0B278A6
+:1024B00006A071201000912001807C00078104801B
+:1024C0000480B87AB47BC07CBC7D10A299A30000C4
+:1024D000A1A40000A9A500007C0009205B52912066
+:1024E00000800A207E0F7E0E71204052007086A070
+:1024F0000000C000892209201252042105A0C0005A
+:10250000892279200001307884A0C000C00089228F
+:10251000180089221B784B007F0E7F0F7C007E0FF6
+:102520007E0E7120405291200080007086A0000035
+:10253000C000A22279200001307884A0C000C00031
+:10254000A2221800A2221B784D00912001807F0E4C
+:102550007F0F7C007E129120002371204052792051
+:1025600000014B780F009800B52238787800AE2231
+:10257000A9204000007882A004004800BE22A920C3
+:1025800060009B780000AF780000AF78000070001A
+:10259000C8227800C022007882A004004800D72218
+:1025A000B77093001920F04F781013232F7001801B
+:1025B0007800E322B77000001920704E78101323C2
+:1025C0001920AF4E781013232F7000800370000085
+:1025D00078102024047084A00F007E010920FD04DF
+:1025E0000C218AA105004800F8223800FE2285A0AF
+:1025F0008062780000232800FE2285A08062780097
+:10260000002385A0C0627F0106780F7804B243786A
+:10261000D800537880000B7808004770080053708A
+:102620007F524F7000007F1200207C007E137E14CA
+:102630007E157E04A1202B01042305A09A7840007A
+:1026400033231883242318839823A82484A400FF09
+:1026500040002B2382A40001A92000012020A653C2
+:1026600005A0C00022231833780019237F047F15AA
+:102670007F147F137C008CA10F0011200101042224
+:1026800084A0F0FF05A11220781020247C001120E6
+:102690000101A92009000B8170004D237800482317
+:1026A0008CA1000E042284A0FFF105A112207C0061
+:1026B00009200101A9200500138270005E23780023
+:1026C000592394A2E000042184A01FFF05A20A2040
+:1026D0007C0011200101A9200C000B8170006F23E8
+:1026E00078006A238CA100F0042284A0FF0F05A1CA
+:1026F00012207C0011200201042284A0CFFF05A13A
+:1027000012207C000381038080A020007E0C6120C9
+:1027100000019A60AC62AC637F0C7C000381038093
+:1027200080A022007E0C612000019A60A46084A039
+:10273000DFFFAE607F0C7C000381038080A022005D
+:102740007E0C612000019A60A46085A02000AE602C
+:102750007F0C7C000381038080A020007E0C612020
+:1027600000019A60A460AE621020A460AE631820DD
+:102770007F0C7C00912000807E0C7E0E186805A0E6
+:102780004000FE2361200076781006244000E823F4
+:10279000A9200000612000757E0C781006244000FE
+:1027A000D6237F0C608C7000D4237800C923780076
+:1027B000FE237F0082A000757120405286708271D6
+:1027C000012004006E7093700F0073700000781089
+:1027D0006A227800FA23C06005A0C000FE237120A1
+:1027E00040528271002C8A70012006006E70937036
+:1027F0000F007370000078106A220120000078003A
+:102800000024012001009120018005A07F0E7F0C93
+:102810007C00042C05A040001D2460200C6006A351
+:10282000C0001A24106006A2C0001A24146006A179
+:10283000C0001A2406A078001F2400607800072436
+:1028400085A001007C00112041520C228CA10F00B8
+:1028500011203B01042284A00001400036242120E5
+:1028600004FF22210B810B810B810B818DA1000FB5
+:1028700004217C007E0EE4688CA0200040008A24A5
+:1028800084A00600C0008A241460078084A00F0082
+:10289000038003800380F0A08054047084A00A00A9
+:1028A000C0008A24087194A100FF40008A248CA1F2
+:1028B000FF0001200C0006A140007124012012003D
+:1028C00006A1400075240120140006A140007924CF
+:1028D0000120190006A140007D240120320006A13C
+:1028E0004000812478008524092012007800872484
+:1028F0000920140078008724092019007800872413
+:10290000092020007800872409203F0078008724D0
+:1029100011200000002105A20A707F0E7C006800D3
+:102920008C2491200080712000007E00187084A00B
+:102930000100C00093247F0071201000CA707F0046
+:10294000C670C3700280DB704107DF700600712023
+:1029500000001B700100912080407800AA247E10A6
+:102960007E007E12912000233C7F587E307C387D93
+:10297000C277C674CA76CE7594A53F009CA40300A6
+:1029800084A40F007900C124D324D324D3240D2898
+:10299000093AD12402250C25D124D124D124D124D3
+:1029A000D124D124D124D12478108C24078584A06B
+:1029B0001F007900D82416250D28C729C42AEC2A1F
+:1029C0008C2D37309A30FB3080313832D6320225A8
+:1029D000E9280C30F824AC3DCC3D8F3F9B3F744040
+:1029E000F824F82449414D41AA3DF824FA3EF82440
+:1029F0005E3C0C25F82478108C241800B1247F123A
+:102A0000912001807F007F107C001920494F7810B1
+:102A100013232F7001001B784F007800FA2419202F
+:102A2000AF4E781013232F7000801B78CD007800F4
+:102A3000FA24427209200F520B20000084A50100E5
+:102A4000C000723C4000332578108C2403700000D5
+:102A50004B70000043700000377000007810E039C0
+:102A60001800B12409200F520B200000687005A047
+:102A7000C000FE256C7084A0070079003C25352637
+:102A8000442550256D258F25DC25B5254425781056
+:102A9000C839092048007810D82EC0004E25037090
+:102AA00004007800FA247810C839C0006B258070C3
+:102AB000078082789B781000AB780C009B786000D0
+:102AC000AB7801005B7804000920DD007810CC2E83
+:102AD000C0006B250370040093700F007800FA2487
+:102AE0007810C839C0008D258071078182789B7865
+:102AF00010008CA11F008DA1C000AA79AB78060040
+:102B00009B786000AB7802005B7804000920DD0050
+:102B10007810CC2EC0008D250370040093700F0038
+:102B20007800FA247810C839C000B3258071078175
+:102B300082789B7810008CA11F008DA1C000AA791B
+:102B4000AB7820008471AA79AB780D009B78600087
+:102B5000AB7804005B7804000920DD007810CC2EEF
+:102B6000C000B3250370040093700F007800FA24AE
+:102B70007810C839C000DA258071078182789B7887
+:102B800010008CA11F008DA1C000AA79AB780600AF
+:102B90009B786000AB7802005B7804000920DD00C0
+:102BA0007810CC2EC000DA2588708B700000682069
+:102BB0004A700370020093700F007800FA247810B6
+:102BC000C839C000FA2488706820146F7810BD38A6
+:102BD000502C78107A3A9B781000146884A01F005B
+:102BE00085A08000AA781C6E412001008C7084A012
+:102BF0000004012004004000FC25012006007800AC
+:102C00001D277810C839C000FA249B78100068701E
+:102C10006820146F7810BD38502C78107A3A08600C
+:102C200085A010000A60246805A040001C2682A030
+:102C3000060048001A2678001C2627680500146B39
+:102C40009CA31F009DA3C000587084A0008040007A
+:102C50002A2684A6010040002C269CA3BFFFAA7B45
+:102C600031202000412001000120030078001D27B1
+:102C70001800B1244C7485A4000040004F2680A0A9
+:102C800080523020507108812AA148004626092030
+:102C9000805264210465FF85C00060262184C00045
+:102CA00040265271037000004B700000407005A078
+:102CB0004000723C7800FA244C76B0A680525071E5
+:102CC000002678004B265271682558254A75502CED
+:102CD000346085A00000C0005D2608673A7784A7AD
+:102CE0003F034000962684A72100C0005D2684A7EC
+:102CF000020040007F2684A7040040005D26BCA798
+:102D0000FBFF0A6784A70800C0005D2684A71000A7
+:102D1000C0005D2684A70002C0005D2684A70001D4
+:102D200040009626186005A0C0005D26BCA7FFFEE7
+:102D30000A67236800001C6E84A60E00186140001C
+:102D4000A6261C6002A14800A9264000A9267800FA
+:102D50005926FF81C0005926C368000084A780005F
+:102D6000C000B1260C702260BCA77FFF0A677810F4
+:102D70007A3A1800B1249B78100046A07810C83920
+:102D8000C000FA24146B9CA31F009DA3C0005870C0
+:102D900084A000804000CD2684A601004000CF26FC
+:102DA0009CA3BFFF84A610004000D5269DA3200051
+:102DB000AA7B408884A60E00C000E026BDA71000B4
+:102DC0000A6778001B2758718CA100084000CB349B
+:102DD0001120200084A60800C000F126108284A6DD
+:102DE0000200C000F1261082AA7A40887810E039EB
+:102DF000146A0C6108818CA1FF00E0A10075642CAD
+:102E0000FF8C40001227146006A2C000FC26B860A8
+:102E10000180BA60C000F7267E0C602A086085A099
+:102E200000010A607F0C780035267810C839C00090
+:102E3000FA24602A0E61AA794088327101200100CB
+:102E40007E005C7184A118004000382784A1100026
+:102E500040002B277810D036C0005B2784A10800E3
+:102E600040003827A06984A10006C00038277810E8
+:102E7000BB3578005B27A06984A1000840004F277C
+:102E80007E0C7E026029006085A000200260046143
+:102E90008DA1100006617F027F0C7810D036C00033
+:102EA0005B27A06984A100024000572778100C36E8
+:102EB00078005B2784A10004C0003427A06984A1A6
+:102EC00000104000662714698CA100FF0F81781064
+:102ED0008B237F0002708CA6E00084A66000400077
+:102EE000742786A06000C00074278DA10040FF8871
+:102EF000400079278DA104005A79B6699B7860005B
+:102F00000028AA789B78610018688DA0008084A0B2
+:102F1000FF7F1A698CA680004000982797700000F8
+:102F20008AA00D00500096278AA00C0096710120FF
+:102F30000C000C809A71AA7808800C814000D13472
+:102F40008CA1F800C000D1347E157E137E14A12020
+:102F50002B019B7800000080AC8080AD0B00982096
+:102F6000A6537F147F137F15146807808278946DB1
+:102F7000D67DDE7D986ED27EDA7E7810C839C000AC
+:102F8000CF272C7003804800C8271920AF4E781037
+:102F900013232F700080307884A0C000C000CF279A
+:102FA0009800D727086084A0EFFF0A607810E03906
+:102FB00078002325007284A2070086A00100C000CB
+:102FC000E4271B784F007810E0397800F527B46AC1
+:102FD00095A200205A7A1B784F007810E0390072D1
+:102FE000002505A64000F52784A2070079100328D4
+:102FF00080AD0900367084A2070086A00100C000E1
+:10300000FA24186000801A607800FA240B284B4BD1
+:103010004B4B3A4B4B4B0B283A4B0B2878108C24DC
+:103020007810C8397E0F79200052CC787F0F84A0A9
+:103030000100400031286C7086A00100C0002028EB
+:103040006E707800C4286C7086A00500C0002F2820
+:10305000887068201B68040017680000206885A03D
+:10306000080022686F700000112004006C7186A1B6
+:1030700001004000522886A10700C0004228092014
+:1030800038520B20050078005228092013520421E1
+:10309000092012520A20092038520B2001006F70BB
+:1030A000000073700100780054286F7000007810E1
+:1030B00087487E15A9201000392000007810B0370D
+:1030C000B8A700017000632878005B287F150070A6
+:1030D0007900672895287C287C286F2895289528D2
+:1030E0009528952821205A52042405A040009528AF
+:1030F00006ADC0007C280068222078008C2820685B
+:1031000084A00100C0008828146F7810BD387810A2
+:10311000A23478008C2860706020006802601A6A0F
+:1031200017680000206885A0080022687810DC1C61
+:10313000212000767810D12821205A527810D128E9
+:103140007E15A9200000212000757810D128208448
+:103150007000A9287800A2286120005521200200D3
+:10316000A920000118601061FF814000B82802A169
+:103170005000B82812601B600000E0AC1000700026
+:10318000C0287800AF282184C000AD287F159C702E
+:1031900084A000804000CB287810CE3A0370000055
+:1031A0004B7000007800FA247E04042405A040003F
+:1031B000E528682000687E001A6A17680000206809
+:1031C00085A0080022687810DC1C7F007800D328D6
+:1031D0007F04232000007C0082A203005000EF281F
+:1031E00078108C2400237900F228F5286829852995
+:1031F00082A202004000FB2878108C246C706F7053
+:10320000000093700000790002290A290A290C297C
+:103210004029D7340A2940290A2978108C2480773C
+:103220007810B0378077BCA7000F7810BD381860D1
+:1032300005A0400037292120007609200400112034
+:1032400010007810A029400037297E15A920000021
+:10325000212000757E040920040011201000781040
+:10326000A0297F0440003629208470003629780088
+:1032700027297F15388784A71F00C00012297800EE
+:1032800023257800232580777810BD38186005A0A5
+:103290004000662921200076092005001120200029
+:1032A0007810A029400066297E15A9200000212061
+:1032B00000757E0409200500112020007810A02947
+:1032C0007F04400065292084700065297800562914
+:1032D0007F1578002325002279006B296E2970293B
+:1032E000702978108C24092012006C7086A00200CE
+:1032F0004000792909200E00186884A00080400051
+:103300007F291A696F7000007370010078005639C8
+:103310000022790088298D2970298B2978108C2426
+:1033200078108748007086A00100C00067347810CC
+:10333000B834086084A0EFFF0A6078105A34400067
+:10334000673478003526042405A04000C32968208E
+:10335000042D7E00146806A74000AF29202D7F00B1
+:103360007800A1297F0022201A69176800002068D0
+:1033700005A222687810DC1C1060018012600860D1
+:1033800084A0EFFF0A607810B8347C0085A00100AB
+:103390007800C22900237900CA29CF29CD29682ABB
+:1033A00078108C24EC7884A00100C000E329007020
+:1033B00086A00400C000DB297800062A7810B83403
+:1033C000086084A0EFFF0A6078006734E47805A005
+:1033D000D000062A1800FA24082084A03000C0007B
+:1033E000F2291B784F007800FA24EC7884A00300BF
+:1033F0004000EE29002184A007007900FC293F2A23
+:103400004A2A302A042ABB39BB39042A592A78109F
+:103410008C24007086A00400C000202A6C7086A056
+:103420000200C000162A11200200192000007800B6
+:10343000E9286C7086A006004000102A6C7086A0F7
+:1034400004004000102AE47984A1300040002A2AB8
+:10345000EC7884A00300C0002C2A78000C300120F6
+:1034600003007800A02D186884A000804000372A4F
+:103470001B681D0078108F372B7808301B7856009A
+:103480007800FA24186884A000804000462A1B684F
+:103490001D0078108F3778008639186884A0008066
+:1034A0004000512A1B681D0078108F372B78083098
+:1034B0001B78CA007800FA24186884A000804000B5
+:1034C000602A1B681D0078108F372B7808301B7816
+:1034D0008F007800FA2484A50F00C000852A0070B0
+:1034E00079006F2A2325792A772A6734673467346D
+:1034F0006734772A78108C247810B834086084A058
+:10350000EFFF0A6078105A3440006734780035269F
+:10351000E47805A0D000062A1800062A082084A016
+:103520003000C000942A1B784F007800FA24EC7811
+:1035300084A003004000902A002184A107007900A4
+:103540009E2AB02AB42AA82AA62ABB39BB39A62AA1
+:10355000B13978108C24781097372B7808301B7885
+:1035600056007800FA24781097377800863978105A
+:1035700097372B7808301B78CA007800FA24781027
+:1035800097372B7808301B788F007800FA240023B7
+:103590007900C72ACC2ACA2ACE2A78108C2478002F
+:1035A00080311B680800A3780000E47984A1300012
+:1035B00040008031EC7884A003004000803184A179
+:1035C00007007900E02AE82AB42A302A5639BB39A4
+:1035D000BB39E82AB13978106A397800FA2482A216
+:1035E00005005000F22A78108C2400237900F52A77
+:1035F000F82A4D2D5B2D00227900FB2A152B022B7A
+:10360000152B002B322D78108C249B781800A8786D
+:1036100084A0FF0082A0200048006B378AA004002D
+:10362000C8006B377900112B6B376B376B37193745
+:103630009B781800A87984A180004000262B780090
+:103640006B37007005A0C0001C2B1120040078000F
+:10365000E93284A1FF008AA01000C8006B3779000E
+:103660002E2B402B3E2B582B5C2B172C6B376B379C
+:10367000192C6B376B372E2D2E2D6B376B376B3725
+:10368000302D78108C2484A6001040004D2B012092
+:103690000005008000803A781B788D007800FA24BD
+:1036A000186884A000804000562B1B681D0078001D
+:1036B000442B780056391B681D0078007B37206941
+:1036C000226984A60018C0009D2B206884A00100F8
+:1036D000C000A52B186886A00800C0006E2B1B68D0
+:1036E000000084A600044000132C84A68000400043
+:1036F000992B97700000186884A03F008AA00D00E5
+:103700005000992B8AA00C00967101200C000C80AF
+:103710009A719B786100AA787E157E137E14A12091
+:103720002B019B7800000080AC8080AD0B009820BE
+:10373000A6537F147F137F151B7858007800FA2456
+:1037400084A600104000A52B1B7865007800FA24A1
+:1037500084A6600040000F2C84A6000840000F2CB7
+:1037600084A60080C000B32B7800CB2BB4A6FF7FCB
+:103770005A7EB66EDC7AD879D0781B80C800BE2B12
+:10378000008084A03F0008A191A20000986B002156
+:1037900002A3B268946B002203A3AE6884A6004023
+:1037A0004000D32BB4A6FFBF5A7EB66E007086A031
+:1037B0000300C000E02B78103D4978103A4B1B788D
+:1037C00064007800FA2406A07810414CB06AAC6915
+:1037D000986C946B002205A14000EF2B002222A4DC
+:1037E00000211BA3AA6CD27CDA7CA66BD67BDE7B85
+:1037F000002305A4C000012CB5A600405A7EB66E79
+:103800001B7864007800FA241B786400002215A15C
+:10381000C0000B2C78104B4B7800FA247810964B94
+:103820007800FA241B7865007800FA241B78580089
+:103830007800FA2478108C2478007A2C206984A1EE
+:1038400000014000312C8CA1FFFE22697E0C5470D7
+:103850006020006084A0FFEF0260046084A0F5FF98
+:1038600006607F0C7800692C84A100024000692C5E
+:103870008CA1FFFD22697E0C54706020006084A042
+:10388000FFDF0260046084A0EFFF06600820482C80
+:103890007F0C84A108004000692C7810B93878109A
+:1038A000BB35FF884000692C9B7860000028AA780F
+:1038B000587EB5A604005A7E84A60004C000632C7E
+:1038C0002B7808301B7856007800FA242B780830C3
+:1038D0001B7865007800FA24587E84A60004C00096
+:1038E000722C1B7858007800FA241B786500780049
+:1038F000FA24780073377800733719200000907924
+:103900008CA10700C000882C206884A00001400022
+:10391000782C092008009B781000A87894A0FF005C
+:1039200086A20100C000BF2C0023A87C00A41820A0
+:1039300002A14000B72C48009C2C7800B92C80A331
+:10394000020002A1C800B72C20698CA1FFFC2269EB
+:103950007E0C54706020006084A0EFEF0260046071
+:1039600084A0E5FF06607F0C587EB4A6FBFF5A7E5C
+:1039700078006A2C78001B2CA824A87AF000B92CB7
+:1039800078008A2C84A2F00086A02000C0001F2DA1
+:1039900018831883002302A14000CF2C4800CF2CAD
+:1039A00078001C2D86A223004000782C1C6884A07F
+:1039B000F1FF1E68587E84A6F1FF85A0100030201C
+:1039C0005A7E086085A010000A607E0C547060204A
+:1039D00004600820482C7F0C84A110004000F32CC8
+:1039E0007810B9387810D0367800022D7E0C5470DB
+:1039F000602004600820482C7F0C84A1080040004F
+:103A0000692C7810B9387810BB35FF884000692CD4
+:103A10009B7860000028AA78B5A604005A7E84A688
+:103A20000004C000162D2B7808301B785600780053
+:103A3000FA242B7808301B7865007800FA24A87ADD
+:103A400078008A2C1883002302A14000282D48000A
+:103A5000282D78008A2C84A28000C0007B37780053
+:103A6000733778007B3778006B379B781800A8781D
+:103A700084A0FF008EA0010040003D2D78108C2412
+:103A8000A87A94A2FF00A87884A0FF008AA004006E
+:103A9000C8006B377900492D6B3708356B376536B1
+:103AA00082A20000C000532D78108C2478108F372C
+:103AB0002B7808301B7865007800FA2482A2030076
+:103AC000C000612D78108C2484A40080C000842D57
+:103AD0006C7005A040006B2D78108C24146F8277D9
+:103AE000BCA7000F7810BD38086085A021000A60CF
+:103AF000388784A71F00C0006F2D781093376F7030
+:103B00000200092038520B2009007800862D781019
+:103B10009F372B7808301B7865007800FA2482A242
+:103B200004005000922D78108C2400237900952DEC
+:103B3000982D812EB42E86A2030040009E2D781071
+:103B40008C24012000007E00C06805A04000A72D45
+:103B500003700300A06884A000204000B02D08601E
+:103B600085A002000A607F003E70007084A00700FC
+:103B70007900B72D2325C12DC12DB62FF22F232576
+:103B8000F22FBF2D78108C2484A60010C000C92D00
+:103B90007810874840005B2E68788CA0FF004000BA
+:103BA000112E86A10800C000E02D7810B8340860FE
+:103BB00084A0EFFF0A6078105A344000112E78106C
+:103BC00087487800F82D86A12800C000112E7810B3
+:103BD0008748086084A0EFFF0A60186005A04000D5
+:103BE000F82D01801A6005A04000F82D018005A085
+:103BF0004000F82D1E60206884A0010040002325AD
+:103C0000206884A0FEFF226860707E0C602000683F
+:103C100002607F0C0460026805A0002DC0000E2E1B
+:103C200002600660780023257E017810E52E7F0172
+:103C300084A600DF1E682B680000146FFF8140001F
+:103C40005B2E86A10200C0005B2E84A60008C00087
+:103C50002E2E84A6600040002E2ED878DC7A2E68A6
+:103C6000326A206884A00008C0005B2E178794A2E7
+:103C70000F0013821382138290A2805490A200003E
+:103C80001C2284A30001C000442E78004A2E10821A
+:103C9000042285A018001220118284A30004400091
+:103CA000572EA06884A00001C000572E7810692FFD
+:103CB00078002325086085A002000A60166918684C
+:103CC00084A000804000632E3C701A688CA600DF40
+:103CD0001E697810A9347810B834C000702E0860BE
+:103CE00084A0EFFF0A60206884A00100C000792E44
+:103CF0007810A23478007D2E607060200068026029
+:103D00007810DC1C7800232582A204004800872E4E
+:103D100078108C24002279008A2E852E8E2E9B2EE0
+:103D20008E2E007086A005004000972E78108F37E9
+:103D30002B7808301B7865007800FA24907807808B
+:103D4000018084A0070080A018009A78A8798CA12F
+:103D5000FF0086A103004000B02E86A100004000B5
+:103D6000B02E78006B371B7865007800FA24206845
+:103D700085A004002268FF82C000BF2E78108F3714
+:103D80007800C62E11824000C42E78108C24781042
+:103D90009F372B7808301B7865007800FA242C7048
+:103DA00003804800D62E1920AF4E781013232F70B1
+:103DB00000807810E039307884A0C000C000E22E86
+:103DC0001800E22E1A7906A07C0085A001007C0074
+:103DD00084A66000C000EF2E2F680000336800004A
+:103DE0007800682F84A60008C000112FB46884A052
+:103DF000004835A684A60008C000112F9869946A6F
+:103E00002E69326A3C7005A0C000092F002205A16E
+:103E10004000102F3F701500007086A00600400083
+:103E2000102F781087487C0084A620004000332F94
+:103E300084A6004040001F2F2F6800003368000058
+:103E40007800092FB46884A0004835A684A60040F5
+:103E5000C000192F3C7005A0C0002D2F3F70150029
+:103E6000D879DC7A2E69326A7800092F84A600405E
+:103E700040003D2F2F680000336800007800092FB4
+:103E8000B46884A0004835A684A60040C000372F3F
+:103E90003C7005A0C0004B2F3F701500D879DC7A2C
+:103EA000D078FB80C800522F008084A03F0008A17A
+:103EB00091A200002E69326A002105A2C0005F2F86
+:103EC0007800092F007086A006004000682F781047
+:103ED000414C7800092F7C00086085A000020A6030
+:103EE00084A300024000752F086085A002000A60CC
+:103EF0001B6806008F68000093680000306A2C6918
+:103F00003E6A42692F68030033680000376820006A
+:103F1000976800009B682000B3680000AF6800004D
+:103F200000707900902F23259A2FA32F982F982F78
+:103F3000982F982F982F78108C24206884A0010047
+:103F4000C000A32F7810A2347800A92F6070502CE5
+:103F5000602000680260602A21205A52042405A0D3
+:103F60004000B22F20207800AB2F222D6B200000C4
+:103F70007C007810A9347810B834086084A0FFFD64
+:103F80000A602B6800009B780E00146F176802000F
+:103F90007810894C84A600084000CF2F1C698DA1A1
+:103FA00000201E69186884A000804000DF2F687818
+:103FB0008CA0FF004000DD2F1B681E007800DF2F63
+:103FC0001B68000021205A52042406AD4000E62F51
+:103FD000607400682220C36800003C6A4069326A4D
+:103FE0002E697810DC1C780023257810E52E2B68CC
+:103FF000000001200E00146F7810E6398CA0FF003D
+:104000001669186884A00080400005303C701A686A
+:104010008CA600DF1E696F700000780023250070F9
+:1040200005A0C00012307800232506A0781087482C
+:10403000176800001B6814008CA600DF1E692B683F
+:104040000000206885A0FF002268007079002530FC
+:1040500023252F302F3031303130313031302D3079
+:1040600078108C247810B834086084A0EFFF0A60C0
+:1040700078007234002379003A303D303F30983078
+:1040800078108C2484A60080C0007D3000707900F8
+:1040900046302325503050306C30503079306C3001
+:1040A0004E3078108C2484A6600086A06000C0008A
+:1040B0006830B4A6DFFFB4A6FFBFB5A600205A7EC5
+:1040C000B66E1C6884A0DFFF1E68781087487810E1
+:1040D0004B4B7800563984A6002040005A301868AF
+:1040E00084A00080400079301B68150084A6004041
+:1040F000400079301B68070078106A397800FA248C
+:10410000B4A6FF7F5A7EDC7AD879D078D2791B802A
+:10411000C8008830008084A03F0008A191A2000060
+:10412000986B002102A3B268946B002203A3AE68CF
+:104130001B7865007C0078108C24002379009D306A
+:10414000A030A230EB3078108C2484A60080C00010
+:10415000DA3000707900A9302325B330B330CF3086
+:10416000B330D630CF30B13078108C2484A66000C4
+:1041700086A06000C000CB30B4A6BFFFB4A6FFBFCE
+:10418000B5A600205A7EB66E1C6884A0BFFF1E68CC
+:104190007810874878104B4B7800563984A6002059
+:1041A0004000BD30186884A000804000D6301B68F5
+:1041B00007001B78CA007800FA24B4A6FF7F5A7E55
+:1041C000DC7AD879986B002102A3B268946B002244
+:1041D00003A3AE68D2791B7865007C00206885A0B7
+:1041E0000400226878102139B5A6000878108F37AE
+:1041F0002B7808301B7865007800FA2400237900BA
+:10420000FE3001310331053178108C2478007B3782
+:1042100084A60004C0002E31E47984A1200040006F
+:104220001531EC7884A00300400015312B7809305B
+:104230009B786000AB78000084A6FBFF5A78E47995
+:1042400084A1200040002631EC7884A00300C00047
+:104250002A31012014007800A02D84A107007900E4
+:104260006631907A94A207009B786000A879FF815C
+:10427000400064319B781000A87B84A30100C0003B
+:104280005531A87BA87B86A30100C00048310920D6
+:10429000F7FF78004E3186A30300C0005531092096
+:1042A000EFFF7E0C54706020046004A106607F0C58
+:1042B0009B786000AB78000084A6FBFF5A782B78CF
+:1042C000093020698CA1FFFD8CA1FFFE22697800D6
+:1042D00056393F2A4A2A703178316E316E3156395B
+:1042E000563978108C2420698CA1FFFD8CA1FFFE2B
+:1042F00022697800603920698CA1FFFD8CA1FFFE46
+:10430000226978005639E47984A1300040008A316E
+:10431000EC7884A00300C000B131007086A00400D6
+:10432000C000A4316C7086A00200C0009A31112038
+:104330000200192000007800E9286C7086A00600B1
+:10434000400094316C7086A00400400094310070ED
+:1043500086A000004000FA24186885A000801A6832
+:10436000012014007800A02D84A107007900B53148
+:1043700056395639BD315639BB39BB39563956399C
+:1043800084A680004000EC319471FF814000EC3144
+:1043900082A10D00D000CD31977000007800D2319D
+:1043A00082A10C00967009200C009B786100AA790C
+:1043B0007E157E137E149870148110A29A7280A0CC
+:1043C0000B0000AD9820A1202B019B7800000881F4
+:1043D000AC81A6537F147F137F157800603984A6C3
+:1043E0000004C0002D32206884A001004000603924
+:1043F0008CA6600084A660004000013286A06000A8
+:10440000C00001328DA100408CA1FBFF5A79B66932
+:104410009B786000AB7800009B786100186885A0ED
+:1044200000801A68AA7808800C814000D1348CA1E1
+:10443000F800C000D1347E157E137E14A1202B011C
+:104440009B7800000080AC8080AD0B009820A653C4
+:104450007F147F137F151468078082787800603995
+:10446000186884A00080400034321B6808001B7864
+:10447000C0007800FA24002379003B324032D43265
+:104480003E3278108C24007084A0070079004532F9
+:1044900023254F3284325A324D3223254D324D324C
+:1044A00078108C241C6884A00020400068320860CA
+:1044B00085A002000A6078006832C06805A0C000CC
+:1044C000843220698DA101002269C368010000685F
+:1044D0006A7078007E3220698DA10100226900682F
+:1044E000066005A0C000723202601C6884A00E0045
+:1044F00040007E321470BA68307188A1007578006F
+:10450000803209200076042102680A2D6271B66E9D
+:1045100084A660004000D23284A60008C000983211
+:1045200084A6FF7FB6689468A6689868AA68781021
+:1045300087487800D23284A620004000AD32C0689F
+:1045400005A04000A4327810894C7800A73206A05C
+:104550007810414CD879DC7AAA69A66A7800B3321F
+:104560007810CA38AA69A66A7810414C84A60080DF
+:104570004000D23284A6FF7FB668DC7AD87984A660
+:104580002000C000CA32D0781B80C800C53200802D
+:1045900084A03F0008A191A20000986B002102A313
+:1045A000B268946B002203A3AE68780023257800DC
+:1045B0007B373770000082A206005000DE32781090
+:1045C0008C24007084A00700C0108C3A002379006E
+:1045D000E632E9321233263300227900EC3210330E
+:1045E0007B37F232103342338433037005000120ED
+:1045F000107768204A707E15A92031000320000042
+:104600000080700002337800FB327F1580AD090016
+:10461000367017680000B76800072368000827682D
+:10462000030078006B3778108C240370050001209C
+:10463000107768204A7080AD09003670002279003A
+:104640001E337B3724332433423324337B377810B3
+:104650008C24037005000120107768204A7080AD1B
+:10466000090036700022790032333A333833383358
+:104670003A3338333A3378108C2478109F372B78BC
+:1046800008301B7865007800FA2403700200807AF5
+:1046900094A2000F9B781800A87C84A41F0015A288
+:1046A00069200076042D082D6271682005A0400065
+:1046B0005D33146806A240007933006878005033F7
+:1046C000037005000120107768204A7036707E154F
+:1046D000A920310003200000008070006E337800B4
+:1046E00067337F1580AD09003670166AB76800071A
+:1046F0002368000827680300B46E5A7E206884A0EF
+:10470000000C4000D333781097377800D333037010
+:104710000200807A94A2000F9B781800A87C84A4E1
+:104720001F0015A2A879A8798CA1FF00E8A1007547
+:10473000042D082D6271682005A04000A333146881
+:1047400006A24000BE33006878009633037005006F
+:104750000120107768204A707E15A92031000320BF
+:10476000000000807000B3337800AC337F1580AD5B
+:1047700009003670166AB7680007236800082768C2
+:104780000300B46E5A7E206884A0000C4000D3332E
+:1047900084A000084000CD3378109B377800D333D5
+:1047A000781097378B7000007800D3337E02078231
+:1047B00084A00F0003800380038080A080546020C9
+:1047C000567000605A7004605E7084A660004000FD
+:1047D0002B34986B946CAC69B06805A1C0000D34A3
+:1047E000D27BDA7BD67CDE7CB4A6FFB75A7E84A669
+:1047F000600086A0600040002B34C06805A0400027
+:104800000634037003002B68000078103A4B7800E0
+:10481000083478104B4BB5A600205A7E78002B3414
+:10482000B0681AA3002123A4002405A340002B3460
+:10483000D27BDA7BD67CDE7CB068B4A6FFBF5A7E22
+:104840007E00C06805A07F0040002934037003008B
+:1048500078103A4B78002B347810964B7F077810FD
+:10486000BD380920650084A6040040004C34E4787B
+:1048700084A0300040004434EC7884A00300400061
+:1048800044342B7808300920650078004C347E0FC2
+:1048900079200052781087487F0F400023251A792D
+:1048A000002D4A70078284A00F00038003800380DC
+:1048B00080A0805448207800FA24206005A04000A1
+:1048C000663401802260086085A008000A601070CC
+:1048D00026607C0006A078108748176800001B68D7
+:1048E0000100236840001F680001007084A00700D9
+:1048F000790077342325813481349E348934873498
+:1049000089347F3478108C247810A9347810A2343C
+:104910007810DC1C780023256C706F700000937099
+:104920000000790090349A349A349834983498344A
+:104930009A3498349A34790002296F700000780014
+:1049400023251B6800007800B62F006805A0C00072
+:10495000A734026006607C00106005A04000B234FD
+:104960000180D000B23478108C241260086084A0DA
+:10497000EFFF0A607C00186005A04000BE34018093
+:104980001A607C007810E0391B6818007800F53454
+:104990007810E0391B6819007800F5347810E03998
+:1049A0001B681A007800F5347810E0391B680300A2
+:1049B0007800F53480777810BD3884718CA1FF00C1
+:1049C000E8A10075042D082D682005A0C000E7347B
+:1049D000780023251468807206A24000EF34006836
+:1049E0007800E03400680A201B6805008B70000026
+:1049F0007810A934206884A00100C000FE3478102B
+:104A0000A2347810B8341F680000236820007810A2
+:104A1000DC1C7800232582A20300C0006B37A87D30
+:104A2000ACA5FF00A87CA4A4FF0020698DA1800094
+:104A3000226984A1000140006C358CA1FFFE22692F
+:104A4000A4A4FF004000563582A40C00480029357C
+:104A50004000293521200C002B852B8578102E381D
+:104A6000400033357810273678005F357810E93705
+:104A70007E0C6029046084A0F5FF06607810523631
+:104A80007F0C20698DA100012269587EB5A6040023
+:104A90005A7E84A60004C00050352B7808301B785D
+:104AA00056007800FA242B7808301B7865007800CF
+:104AB000FA247E0C6029046084A0F5FF066078105B
+:104AC00052367F0C587E84A60004C00068351B78DF
+:104AD00058007800FA241B7865007800FA247E0CD0
+:104AE0005470602000618CA100104000AC35086259
+:104AF000178294A2FF0082A20C004800803540007B
+:104B0000803511200C00002402A2C8008535202227
+:104B1000086294A2FF00187086A02800C000953596
+:104B200082A21900C8009B351120190078009B351E
+:104B300082A20C00C8009B3511200C00002202A5A7
+:104B4000C800A03528227810ED372B852B857810EA
+:104B50002E384000AC35781027367800B035781004
+:104B6000E93778105236587885A004005A787F0CBF
+:104B70002B7808301B7865007800FA247E0C6029B9
+:104B80000060E4D0C000D535B4D0C000CF3510608F
+:104B900084A00F00C000CF3504618CA1F5FF066131
+:104BA0007F0C7C0011203200192000007800FC35B9
+:104BB000A06884A00002C000CF35086294A2FF0064
+:104BC000187086A02800C000EA3582A21900C8002B
+:104BD000F035112019007800F03582A20C00C800D1
+:104BE000F03511200C0008631F839CA3FF0082A3F3
+:104BF0000C004800FC354000FC3519200C00AB7857
+:104C00000100AB780300AB780100AA7AAA7BC0A8A8
+:104C10000500206885A0000122687F0C7C007E0CC6
+:104C200060298CA1F5FF06611120320019200000D7
+:104C300078001736AB780100AB780300AB78010041
+:104C4000AA7AAA7BC0A80500206885A00001226876
+:104C50007F0C7C007E0C5471602178102E367F0C06
+:104C60007C00082084A0F0FF25A4867C18609A7838
+:104C7000AE7C1264A47884A0F8FF8CA1070005A183
+:104C8000A67816608A78A4A40F0027840482048082
+:104C900084A0FF0005A40E60EC788CD0C0005136D3
+:104CA000046084A0F5FF06607C007E0C54706020D8
+:104CB000781059367F0C7C0018609A78A47884A00C
+:104CC000F0FFA6781260847884A0F0FF86787C00DC
+:104CD00082A20200C0006B37A87A20698DA18000F3
+:104CE000226984A100024000AE368CA1FFFD22693A
+:104CF00094A2FF0082A20200C8006B377810F93638
+:104D00007810523680A901000C207810B93878103C
+:104D1000BB35FF884000A1369B7860000028AA7848
+:104D2000587EB5A604005A7E84A60004C0009B36B7
+:104D30002B7808301B7856007800FA242B7808303E
+:104D40001B7865007800FA24587E84A60004C00011
+:104D5000AA361B7858007800FA241B786500780082
+:104D6000FA2482A20200C800B63684A201004000E4
+:104D7000C036547188A100000C218CA10020C00015
+:104D8000C036112000007810DB377810F936781023
+:104D90005236587885A004005A782B7808301B7852
+:104DA00065007800FA247E0C7E02602900601120E4
+:104DB0000100ECD0C000E936BCD0C000E73614607A
+:104DC00084A04000C000E7368CA1EFFF066106A07A
+:104DD0007800F63611200000AB780100AB780200B5
+:104DE000AB780300AA7AC0A80400206885A000025E
+:104DF00022687F027F0C7C007E0C5470602078104B
+:104E000000377F0C7C00FF824000053711204000F6
+:104E1000186080A002009A78A47884A0BFFF05A241
+:104E2000A6788A781660EC788CD0C00018370460B9
+:104E300084A0EFFF06607C007E00007086A0030067
+:104E4000400022377F00780025377F0078006737E1
+:104E500084A6200040006737887884A04000400086
+:104E60006737B87B84A33F001B83C80035370080B9
+:104E700005A040004B371B83C8003E37018040002F
+:104E8000633784A6004040004B37B8781B80C800C9
+:104E90004737008084A03F00C0006337B4A6FFBF3F
+:104EA0005A7ED879DC7A0120010008A1C800573762
+:104EB00091A20000D279DA79D67ADE7A7810414C64
+:104EC0001B7864007810C64A7800FA241B786400C6
+:104ED0007800FA241B7865007800FA247810A3374C
+:104EE0002B7808301B7865007800FA2478108F370B
+:104EF0002B7808301B7865007800FA2427680200B8
+:104F000078109737E47884A0300040002325EC78AF
+:104F100084A00300400023252B7808301B7865000F
+:104F20007800FA24012005007800A53701200C0044
+:104F30007800A537012006007800A53701200D0074
+:104F40007800A537012009007800A5370120070067
+:104F50009B781000AA789B786000AB780100B5A61A
+:104F600004005A7E7C007E073F87BCA70F003B876A
+:104F70003B870387E0A08054B8A720009A7FA479DC
+:104F800084A10F004000C93784A1F0FFA678126009
+:104F9000046085A008000660388738879A7FA47966
+:104FA00084A140004000D93784A1BFFFA6781660D5
+:104FB000046085A0100006607F077C009B781000CD
+:104FC000AB780100AB780200AB780300AA7A9B783B
+:104FD0006000AB7804007C00212000002920320012
+:104FE0009B781000AB780100AB780300AB78010030
+:104FF000AA7DAA7C9B786000AB7805007C007E15BA
+:10500000078084A0FF000380038080A020009A789E
+:10501000A4798CA1F0FF01204652042082A0280030
+:10502000400017382120A03819201400A9200C00B6
+:1050300078001D382120AC3819201900A9200D0056
+:1050400011206400042484A0F0FF06A140002C3845
+:105050002084002310A270002C3878001F387F15A0
+:105060007C007E15092046520C2182A132004800A6
+:105070004238400046380920923819201100A920F2
+:105080000E00112032007800583882A1280040001C
+:1050900050380920A03819201400A9200C00112034
+:1050A0006400780058380920AC3819201900A9206C
+:1050B0000D0011206400002202A54000683848005D
+:1050C00068380881002310A27000653878005838CD
+:1050D0007F1506A07C007F1582A56400C800773884
+:1050E000087885A070000A78447085A0700046702A
+:1050F00078007738EC7884A0000340007F380421E2
+:105100007800903804219EA00211C0009038012040
+:10511000FD04042082A0050048008F380120011200
+:1051200078009038042105A07C0002110230023280
+:105130000342034404540456056605680678067A5B
+:10514000070C070C070E0232024202520262027280
+:10515000056605760578057A057C057E057F0222C1
+:105160000232024202520454046404740476047845
+:10517000047A047C047E047F9B78100046A07C00A7
+:1051800084A7000F0B8084A71F0003800380038087
+:10519000038005A1E0A000557C00D879DC7AD078A6
+:1051A0001B80C800D138008084A03F0008A191A2D4
+:1051B00000007C007E0F79200001092040529120E0
+:1051C000008004217900E1381739EB38EB38EB38EF
+:1051D000EB38EB38EB381B3978108C244B78040013
+:1051E000487884A00400C000ED384B780800487867
+:1051F00084A00800C000F438B46885A00040B668F8
+:10520000587885A000405A78307884A08000C0008B
+:105210001739180017391C6884A02000C000153900
+:105220007E0E7120405278106A397F0E780017394F
+:105230001B78CA00912001807F0F7C00B3700000B2
+:105240007810443B780017397E0C1468078084A0DE
+:105250000F00038003800380E0A08054046084A0DA
+:105260000A00C0005439086194A100FF400054397D
+:105270008CA1FF000120190006A140004339012044
+:10528000320006A14000473978004B390920200040
+:1052900078004D3909203F0078004D391120000079
+:1052A000002105A20A60046085A0020006607F0C50
+:1052B0007C001B7865007800FA242B7808301B7876
+:1052C00065007800FA241B7858007800FA242B78BF
+:1052D00008301B7856007800FA24092020520C214F
+:1052E00086A1000040007E3986A10100400081397E
+:1052F000092038520B200B006F7001001B7848000A
+:105300007C001B78C4007C00092038520B200A0066
+:105310007C00092020520C2186A100004000A13908
+:1053200086A1010040009B39092038520B200B0058
+:105330006F7001001B7848007800FA240920385269
+:105340000B200A007800FA242B7808301B78C40060
+:105350007800FA241B78CA007800FA242B780830E9
+:105360001B78CA007800FA241B788F007800FA2492
+:105370002B7808301B788F007800FA24186884A0F6
+:1053800000804000C2391B681D006F7001001B784F
+:1053900048007800FA247E00307884A0C000C00065
+:1053A000DE39087884A0FCFF0A78050005000500B6
+:1053B0000500EC7884A021004000DE3944700A78B2
+:1053C00005A07F007C00447085A0020046700A782A
+:1053D0007C007E00307884A04000C000E73998004F
+:1053E000F2397F009A78AC787C00087884A0FDFFC1
+:1053F0000A780500050005000500EC7884A021006E
+:105400004000013A9800FF397F009A78AC787E001E
+:1054100044700A787F007C00EC7884A00200C00011
+:10542000714884A77D00C000153A002778108C24AD
+:1054300084A70100C0000C3084A770004000253A0A
+:105440007E0C602D682F78103724782D682C7F0C07
+:1054500084A708004000323A4B780800EC7884A01A
+:105460000300400023257800563984A7040040003B
+:10547000653AB87884A001404000653A4B7808004E
+:10548000EC7884A0030040002325E47884A0070082
+:1054900086A00100C000653AC07885A00048302091
+:1054A0005A7E1B78CA007800FA244B7808001868E6
+:1054B00084A000804000613A1B68150084A600406B
+:1054C0004000613A1B68070078106A397800FA24B6
+:1054D0001B680300587884A0003F1E682F680000F6
+:1054E000336800004B780800EC7884A0030040008B
+:1054F000062A1800FA2478007337146B078384A0F7
+:105500000F0003800380038080A080546020482027
+:10551000567000605A7004605E70602A7C007900EA
+:105520008E3A963A973A963A993A963A963A963AFF
+:105530009E3A7C007810B8347810874838700A603A
+:105540007C00A07005A04000AB3A68207810D31B07
+:105550007810FE4778100548A37000007C007E0E8E
+:105560009120008071204052007086A00700C0008A
+:10557000C23A1061BC7006A1C000C23A7F0E78101A
+:10558000E01B7810C83A06A07C00912001807F0EB5
+:1055900085A001007C007E0F7E0E712040527800B5
+:1055A00097225B780000AF700E00092000017E0199
+:1055B000A0706DA04000DD3AA37000007800E33ACF
+:1055C000B370000078100C1C4000E93AAC702668FB
+:1055D0007810C63B7800DD3A7F017E157E0C7E0D8B
+:1055E000A920080061201076006005A102601C60FF
+:1055F0006DA04000013B00681E607810AC19086087
+:1056000000800A607800F43A18606DA040000B3BFF
+:1056100000681A607810AC197800013BE0AC080013
+:105620007000113B7800F13A9C7084A0008040002B
+:10563000183B7810443C7F0D7F0C7F157C007E1258
+:1056400091200023046884A00F007900243B343BA0
+:10565000343B343B343B343B343B363B3C3B343BC8
+:10566000343B343B343B343B3E3B343B363B78109D
+:105670008C247810D3457810AC197800423B276809
+:105680000B007810D3457810C63B7F127C007E1249
+:10569000912000239800603B307884A0C000C000B7
+:1056A000603B7E0D78101248002D2E680920040002
+:1056B00001200000276884007810C7477810C63B97
+:1056C0007F0D7800943B487985A100404A78980086
+:1056D000693B4A7978004E3B287886A03418C00090
+:1056E000723B85A104007800793B287886A01418C5
+:1056F000C000663B85A10C004A789B780E00AB7811
+:105700000200587884A0FF0085A000045A78B47085
+:1057100080A091001A78276884022C683668306867
+:105720003A6809200400012000007810C7477F1262
+:105730007C007E0D146B7810701C4000A33B682029
+:10574000276802007810C63B7800983B7F0D7C00EC
+:105750007E0D146B286CA4A4FF0078101C1C400064
+:10576000B33B6820276802007810C63B7F0D7C00A1
+:105770007E0D146B9CA3FF007810481C4000C43BB6
+:105780006820276802007810C63B7800B93B7F0D7F
+:105790007C007E0C146978103B3C04698CA1FF00EE
+:1057A00086A106004000E13B86A10D004000003CC0
+:1057B00086A11700C000DD3B7810AC197800DF3BF4
+:1057C0007810DE1C7F0C7C00046001804800FE3BEA
+:1057D00006600920000084A60100C000EE3B8DA1F8
+:1057E000008084A604004000F43B8DA102001E69E5
+:1057F0002368000004710F81186805A11A687800F9
+:10580000DD3B78108C24186005A0C0000F3C0860B8
+:10581000018048000F3C0A601C600268002D1E6079
+:105820007800253C88AC0600042105A04000183C07
+:1058300008207800113C02680A2D086001804800A9
+:10584000DF3B0A601860682000681A607800093C35
+:105850007E157E137E147E0C7E0D78108919C00093
+:10586000303C78108C24A02D7F13A9203100A35345
+:105870007F0C7F147F137F157800DD3B84A11F0010
+:1058800003800380038080A0107660207C001920B4
+:105890005152042385A001001A201920020104237B
+:1058A00085A001001A207C0019205152042384A0F5
+:1058B000FEFF1A2019200201042384A0FEFF1A20F3
+:1058C0007C0090798CA1F8FF9279B47080A0D80008
+:1058D0001A787800FA24A370000003700000437067
+:1058E0000100377000001800B12478100C1C400033
+:1058F000993C09200F520B200000BC686020006119
+:1059000084A1000340008D3C27680E0084A00002A3
+:105910004000893C276817007810C63B7800683C37
+:10592000007086A00700C0000D3D002DA27080AD64
+:105930000F0036707800A03C407086A00100400047
+:1059400033257800FA24312000001C6984A102006C
+:105950004000A93CB5A6040084A1C00003800380D8
+:10596000078080A0A63D042035A6206884A00004FE
+:105970004000C13C9B781800AB7803009B78810005
+:10598000AB780100B5A60050206884A000804000DC
+:10599000CF3CB5A600049B780E0024680780AA7847
+:1059A0007800EF3C1C68FCD0C000DD3CB5A60008C8
+:1059B0002068C4D04000EF3CB5A600407800EF3C22
+:1059C0002068C4D04000E53CB5A600407800EF3C1C
+:1059D0009B781800AB7802009B788100AB780100BF
+:1059E000B5A6001084A600024000093D2C68D278BC
+:1059F0003068D67884A600014000073D2C6884A05A
+:105A000001004000073D887884A040004000073D29
+:105A1000B5A600807810F6475A7EB66E78003548F5
+:105A20007810C839C000A03D2C70048048001B3D90
+:105A30001920494F781013232F70010041200100D5
+:105A4000312000109B781800146884A01F0085A0E6
+:105A50008000AA781C6984A102004000343DB5A6EC
+:105A60000400AB7820002868AA78C0A802001C684F
+:105A7000F4D040003D3D502C78107A3A781002471F
+:105A8000206884A0008040004B3DB5A600049B78B0
+:105A90000E0024680780AA787800523D1C6884A014
+:105AA0000080C000523DB5A60008206884A0000117
+:105AB0004000593DB5A600401C6884A0C00003808A
+:105AC0000380078080A0A63D042035A684A600019F
+:105AD0004000733D2C6884A001004000733D88782D
+:105AE00084A040004000733DB5A600809B787E00F6
+:105AF000AE7EB66E14680780AA7882781028AA7ADB
+:105B0000307884A0C000C000A03D1800A03DB47053
+:105B100080A0DD001A787810E03984A600024000E9
+:105B2000943D2C68D2783068D6787810F647002DEE
+:105B3000A2704A701068BE700370070080AD0F003D
+:105B400036707800FA247810D31B7810E03978008A
+:105B5000FA24000000030002000078108C240023C7
+:105B60007900AF3DB23DB23DB43D78108C24781041
+:105B70000548246984A1FF0086A00A004000C63DB4
+:105B800084A100FF85A00A0026687810D31B780046
+:105B9000683C01200A00781097477800683C82A290
+:105BA00005005000D23D78108C24007084A00700BE
+:105BB000C0108C3A78108919C000F43D6920FFFFAD
+:105BC00084A604004000E53D012000287800E73D60
+:105BD00001200008B47188A191009B780E00078015
+:105BE000AA78312000045A7E1A797800FA240768CE
+:105BF00006010B6800009F6800002768000086A36C
+:105C00000200C000153E86A20200C000153EA0782A
+:105C100005A0C000153E84A40080C000153EE478B5
+:105C200084A008004000153EB5A608001920000019
+:105C300078101742002DA2704A7003700700377069
+:105C40000000246884A080004000273E7810CD42E8
+:105C50007800FA24002379002A3E2D3EAE3EC73E4E
+:105C600000227900303E353E453E6B3E773E9A3EFF
+:105C70002920010026A0112000007810F3437900AC
+:105C80003E3E433EFA24683C433E433E78108C241B
+:105C900090798CA10700C0004C3E0920080011201B
+:105CA000010084A604004000543E1120030020227D
+:105CB0002AA1112001007810F34379005C3E613E77
+:105CC000FA24683C693E633E78003B48AB70673E0F
+:105CD0007800FA247800613E78108C2484A61000A5
+:105CE0004000753E78109C424000753E7800FA24D2
+:105CF00078000D43006084A002004000943EB47020
+:105D000080A0CD001A787E0D78101248002D2E68E4
+:105D1000276800007810C63B7F0D7810AC1903701F
+:105D20000000377000004B7000007800683C84A6CB
+:105D30000400C0009A3E78003B48006084A0040044
+:105D4000C000AC3E006084A001004000AC3EAB70DF
+:105D5000AC3E0120070078108F477800414878005A
+:105D60003B4800227900B13EB63EB83EB63EB63E54
+:105D7000B63E78108C24A770BC3E78004748E47883
+:105D800084A00800C000B83E78108147AB70C53EC3
+:105D900078003B4800227900CA3ECF3ED13ED13E3A
+:105DA000CF3ECF3E78108C24E47884A008004000D9
+:105DB000E63EA770DA3E78004748112004007810CC
+:105DC000ED437900E03EE63EFA24683CE63EF03ED4
+:105DD000F43EAB70EE3E0120030078108F47780050
+:105DE000414878003B48AB70E63E7800FA24AB703F
+:105DF000F83E7800FA247800EE3E82A203005000BC
+:105E0000003F78108C2486A30200C000193F86A2B0
+:105E10000200C0001F3FA07805A0C0001F3F84A45F
+:105E20000080C0001F3FE47884A008004000193FB4
+:105E3000B5A608001920000084A6080040001F3FF6
+:105E4000781079421068BE70037007000023790053
+:105E5000263F293F563F5E3F002279002C3F313FCD
+:105E60002F3F4A3F78108C249079ACA1070026A0E0
+:105E7000112001007810F34379003B3F403FFA24A2
+:105E8000683C483F423F78003B48AB70463F780053
+:105E9000FA247800403F78108C2484A6100040003B
+:105EA000543F78109C424000543F7800FA24780018
+:105EB0000D4300227900593F5C3F5C3F5C3F781006
+:105EC0008C2400227900613F643F663F663F781072
+:105ED0008C24E47884A0080040007B3FA7706F3FCB
+:105EE00078004748112004007810ED437900753F91
+:105EF0007B3FFA24683C7B3F853F893FAB70833F03
+:105F00000120030078108F477800414878003B4813
+:105F1000AB707B3F7800FA24AB708D3F7800FA2499
+:105F20007800833F00237900923F973F993F953F48
+:105F300078108C24A4707A00A4707A0082A20200E7
+:105F40005000A13F78108C2484A600024000AB3F93
+:105F50007810FE477810D543781005480023790063
+:105F6000AE3FB13FD93F3F4086ADFFFF4000683CA8
+:105F700086A201004000BB3F78108C2484A600025A
+:105F80004000C33F7810FE4778100548012001000B
+:105F900078109747B87884A001C04000D53F487872
+:105FA00085A008004A78487884A00800C000D03F47
+:105FB000037000007800683C00227900DC3FDE3F7F
+:105FC0000F40A770E23F7800474811200D0078107D
+:105FD000ED437900E83FEF3FFA24683CF73FFF3F8D
+:105FE00005400740B4A6FF00B5A60004B66E5A7E71
+:105FF00078003548B4A6FF00B5A60004B66E5A7EF8
+:1060000078003548AB7003407800FA247800EF3F01
+:1060100078108C24AB700B407800FA2478104D482F
+:106020007800FA24A7701340780047481120120026
+:106030007810ED43790019401F40FA24683C2B404A
+:1060400033403940B4A6FF00B5A60004B66E5A7EB0
+:10605000B47080A0AA001A787800FA24B4A6FF00D1
+:10606000B5A60004B66E5A7E78003548AB7037404E
+:106070007800FA2478001F40AB703D407800FA2485
+:1060800078002B4086A201004000454078108C2407
+:10609000A770494078004748112015007810ED435B
+:1060A00079004F405440FA24683C62406E40B4A6E8
+:1060B000FF00B5A60004B66E5A7E3B780113B4709B
+:1060C00080A0B5001A787800FA24B4A6FF00B5A61F
+:1060D0000004B66E5A7EB47080A0AA001A787800C8
+:1060E000FA24AB7072407800FA247800544082A2FF
+:1060F000030050007A4078108C24002379007D4002
+:106100008040B740144186A20100400086407810CC
+:106110008C24046884A0FF0086A00600C000934081
+:106120007810C63B037000007800683C3B680000B4
+:106130003768000084A600024000A1407810FE47A6
+:106140007810D54378100548012001007810974752
+:10615000B87884A001C04000B340487885A008000A
+:106160004A78487884A00800C000AE400370000060
+:106170007800683C00227900BA40BC40EF40A7702C
+:10618000C0407800474811200D007810ED43790099
+:10619000C640CD40FA24683CD540DD40E340E540B0
+:1061A000B4A6FF00B5A60008B66E5A7E7800354842
+:1061B000B4A6FF00B5A60008B66E5A7E7800354832
+:1061C000AB70E1407800FA247800CD4078108C2440
+:1061D000AB70EB40781005487800FA2478104D48F1
+:1061E0007800FA24A770F340780047481120050092
+:1061F0007810ED437900F940FE40FA24683C0641EE
+:106200000E41B4A6FF00B5A60008B66E5A7E78000F
+:106210003548B4A6FF00B5A60008B66E5A7E7800D1
+:106220003548AB7012417800FA247800FE4086A20F
+:10623000010040001A4178108C24A7701E4178009C
+:106240004748112006007810ED4379002441294188
+:10625000FA24683C2F413941B5A60008B66E5A7E33
+:1062600078003548B4A6FF00B5A60008B66EB5A6FE
+:1062700000405A7E78003548AB703D417800FA24E2
+:106280007800294100237900424147414541454179
+:1062900078108C2478108C240023A87105A07A0132
+:1062A0001068BE7082A203005000554178108C2403
+:1062B0000023790058415B4169418B4184A600026B
+:1062C000400063417810FE47781005480120010026
+:1062D000781097477800FA2496A202004000724195
+:1062E000FF824000724178108C24A77076417800BC
+:1062F0004748112018007810ED4379007C41814116
+:10630000FA24683C83418541780035487800354857
+:10631000AB7089417800FA2478008141002279002D
+:106320008E419041A941A7709441780047481120BF
+:1063300017007810ED4379009A419F41FA24683C98
+:10634000A141A3417800354878003548AB70A7419A
+:106350007800FA2478009F4184A40080C0000542A0
+:1063600084A600014000B5417810FE477810D5435F
+:10637000D878D278DC78D678B4A6FFEF5A7EA770AA
+:10638000C0417800474811200D007810ED43790096
+:10639000C641CD41FA24683CCD41F341F941FB416E
+:1063A000D878DC7905A1C000DF41B87884A01F004F
+:1063B000C000DF41B3700000587884A0FFFD5A7818
+:1063C0007800354884A600014000F141487885A056
+:1063D00008004A787810BC472C68D2783068D678A4
+:1063E000B37000007810F64778003548AB70F7417D
+:1063F0007800FA247800CD4178108C24AB700142EB
+:10640000781005487800FA2478104D487800FA246E
+:1064100078100548AB700F420120030078108F47B9
+:10642000780041487810F6472C68D2783068D678E2
+:1064300078003548B8701268BE700080BA701B686A
+:10644000000084A6080040003A427E157E137E14A8
+:106450009078048004800480048084A00F001A686F
+:10646000AC809B78000080AF2B00982080AD0B00A3
+:10647000A020A5537F147F137F15C4A6000F84A608
+:106480000200C00049422C690D810D810D8184A15B
+:106490000700082078005C429B781000AC7984A14A
+:1064A000200040005C427E01092005000120003DE3
+:1064B0007810C747246885A03B0026687F0184A127
+:1064C0001F0005A8166878103B3CBE6884A604002F
+:1064D00040006D428CA100FFA87884A0FF0005A1B8
+:1064E0002A68B4A6FF00006084A00800400077423C
+:1064F000B5A60040B66E7C007E157E137E1418692A
+:106500009078048004800480048084A00F007E00C2
+:1065100000A11A687F000080048040009842A820F3
+:10652000048180A00B0000ADA0209B78000080AF0C
+:106530002B009820A5537F147F137F157C002C68B7
+:1065400084A02000C000A4420C627800A542106222
+:10655000186B002302A24000C542182082A30E003F
+:106560004800B5424000B54219200E007800B942FB
+:10657000587884A0EFFF5A783B78011B937800008D
+:10658000A27BB47080A08E001A7885A001007C00E8
+:10659000587884A0EFFF5A789378000006A07C001A
+:1065A00004698CA1FF0096A107004000DA4296A181
+:1065B0000F004000DA4207681701146978103B3C6D
+:1065C00000610481C800F5421C6005A04000E9425A
+:1065D000012000087800F7427E0D24687E007810C4
+:1065E00012487F002668002D2E687810C63B7F0D6C
+:1065F0000120000224698CA1FF000DA126690780FB
+:106600009B780E00AA78206885A00080226831203F
+:106610000004B66E5A7EB47188A191001A797C008C
+:10662000C4A6000F84A60200C00021432C690D817E
+:106630000D810D8184A10700082005A81668781037
+:106640003B3CBE6878002443146978103B3C0061F1
+:106650000481C800824384A10003400030430768DE
+:10666000170178004E43046005A0C0005743076837
+:1066700017011C6005A0C00044437E0D781012482D
+:1066800027683400002D2E687810C63B7F0D84A645
+:10669000040040004E43312000040120002878000F
+:1066A00052433120000401200008B47188A19100F8
+:1066B0007800B043186005A0C00044431C6005A0EA
+:1066C000C00044439F68000027683D0084A6010085
+:1066D0004000BE4394D6C0007B430061D4D140004B
+:1066E0007B432C698CA1FF004000BE4386A10300C0
+:1066F0004000BE4386A112004000BE43B5A600087C
+:10670000B47188A1AE007800B94307681701312041
+:1067100000042C698CA1FF0086A11200C0009343E5
+:106720000120CB43092001007800A44386A1030087
+:10673000C0009D430120CC43092012007800A443EF
+:1067400001200002B47188A191007800B043781054
+:10675000E147A37800001C6885A040001E68B47162
+:1067600088A1DA0006A0266807809B780E00AA7828
+:10677000206885A000802268B66E5A7E1A7978005B
+:10678000FA24B66E7810C63B1068BE70037007001E
+:10679000A37000004B7000007800FA242300700002
+:1067A00005000000000A00000000250000000000B5
+:1067B0003B6800003768000084A600024000EC43FC
+:1067C000B8788CA01F0084A000804000E5430881B9
+:1067D000D87800A13668DC7881A000003A687C0097
+:1067E00090790F81ACA507002120000080A4100043
+:1067F0009A78A8798CA1FF0084A18000C0001B4476
+:1068000082A12000C800394482A11200C80081473B
+:106810000021791009447C008147EB45814781477D
+:10682000464449448344B944ED44F0448147814798
+:10683000A44414454E4581478147744584A12000F6
+:10684000C000A8458CA11F00146884A01F0006A1E9
+:1068500040003644B47080A0CD001A7801201400A6
+:106860007810974778100548037000000120020057
+:106870007C00012000007C0082A12400C800814728
+:1068800084A10300791009447C0081478147814736
+:106890008147781081477C00002279004C4477457D
+:1068A0007745704470447044704470447044704440
+:1068B00070446E4470446544704470447044704445
+:1068C000704478447B4477457B4470447044704402
+:1068D0007E0C7E07146F7810B0377F077F0C78002E
+:1068E000704478108E462768B30209200B000120FF
+:1068F00000487800AB45781073477C002768930008
+:1069000009200B000120004878009345582D0468A9
+:1069100084A0FF0086A00600C0008D440768170110
+:106920002768020078101248276836003269002D67
+:106930002E687E0D7810963B7810D345682B781022
+:10694000C63B7F0D7810C63B012002007C0078100A
+:10695000D3450120170078109747A3700000092045
+:1069600038520B200600AF70170009200002781083
+:10697000D43A012001007C0000227900BC44774514
+:10698000A845A845A845DD44BA45E544BA45BA45F9
+:10699000BD45BD45C245C245D544D544A845A845D9
+:1069A000BA45A845E5447745E544E544E544E54472
+:1069B0002768840009200B00012000437800CC45A3
+:1069C00027680D0009200B00012000437800AB452B
+:1069D0002768930009200B000120004378009345AD
+:1069E000012000007C0000227900F34477450C452B
+:1069F0000C450C450C45BA45BA45BA45BA45BA45A9
+:106A0000BA45BA45BA450C450C450C450C45BA4546
+:106A10000C450C45BA45BA45BA45BA45774527688D
+:106A2000930009200B00012000437800934584A6C1
+:106A30000400C0002845046884A0FF0086A006006A
+:106A4000C00081477810D345076817017810C63B0E
+:106A5000012002007C00006084A004004000814707
+:106A6000582D046884A0FF0086A00600C0003745AA
+:106A70000768170127680200781012482768360057
+:106A80003269002D2E687E0D7810A53B7810D34515
+:106A9000682B7810C63B7F0D7810C63B01200200A2
+:106AA0007C00006084A0040040008147046A94A236
+:106AB000FF0086A20600C0005C4507681701276832
+:106AC0000200582D78101248276836003269002DD0
+:106AD0002E687E0D7810B53B7810D345682B781062
+:106AE000C63B7F0D7810C63B012002007C00781069
+:106AF00081477C00B47080A0CD001A78012001008D
+:106B000078109747781005480370000001200200B4
+:106B10007C007810C7477810FE477810D54378106E
+:106B2000CD4278100548012001007C007810C7474D
+:106B30007810FE477810D543B47080A0CD001A7845
+:106B40000120130078109747781005480370000063
+:106B5000012002007C00781081477C007810C74734
+:106B60007810FE477810D5437810CD42781005484C
+:106B700078104D48012001007C00012003007C00BA
+:106B800078108E46012000007C007E0C7E07146F7A
+:106B90007810B0377F077F0C012000007C00781050
+:106BA000C74778108147012006007C0004698CA14A
+:106BB000FF0086A107004000DE4586A10F00C0004F
+:106BC000E2457810FE477810D543B47080A0CD0020
+:106BD0001A7878100548037000007C00A87A94A207
+:106BE000FF00A87884A0FF008AA00400C8008147A5
+:106BF0007910F8457C008147FC458147954682A283
+:106C0000030040000346781081477C00A87DACA5B6
+:106C1000FF00A87CA4A4FF00B86984A10001400083
+:106C200042468CA1FFFEBA69A07805A0C00042468A
+:106C3000A4A4FF004000364682A40C0040001F467A
+:106C4000C80029462B852B8578102E384000294610
+:106C5000781027367800384678106047781052361A
+:106C6000B8698DA10001BA69B5A600105A7E7800F6
+:106C70003B4678105236B4A6FFEF5A7EB47080A01F
+:106C800091001A78012001007C007E0C7810824669
+:106C90000062E4D2400073460862178294A2FF00AB
+:106CA00082A20C00480055464000554611200C00B9
+:106CB000002402A2C8005A462022086294A2FF00C3
+:106CC0001C7002A2C80062461C72002202A5C80005
+:106CD00067462822781064472B852B8578102E383C
+:106CE0004000734678102E3678007746781060475B
+:106CF00078105936B5A600105A7EB47080A0B9003D
+:106D00001A78012004007F0C7C007E001468078044
+:106D100084A00F00038003800380E0A080547F00E4
+:106D20007C007E0C78108246781059367F0C7C00EF
+:106D300082A20200C0008147A87A94A2FF00B8692D
+:106D400084A100024000CC468CA1FFFDBA69A07866
+:106D500005A0C000CC4682A20200C8006B377810A4
+:106D60002A477810F9367810523684A60001400080
+:106D7000C2462C6884A001004000C246FCC6887848
+:106D800084A040004000C246FDC6B5A600105A7E51
+:106D9000B47080A091001A78012001007C007E0C64
+:106DA0007810824684A2FEFF4000D74611200100E1
+:106DB0007800DB4684A201004000E1460061ECD18E
+:106DC000C000E1461120000078101C477810003701
+:106DD0007810593684A600014000F7462C6884A03C
+:106DE00001004000F746FCC6887884A040004000BF
+:106DF000F746FDC6B5A600105A7EB47080A0B90053
+:106E00001A78012004007F0C7C007E0C6029006051
+:106E10001120010084A00020C0000D4711200000B7
+:106E2000AB780100AB780200AB780300AA7AC0A867
+:106E30000400B86885A00002BA687F0C7C009B78CB
+:106E40001800AB780100AB780200AB780300AA7A97
+:106E50009B788100AB7804007C007E0C547060202D
+:106E6000006084A00010C000384729203200212093
+:106E70000000780058470865ACA5FF00187086A090
+:106E80002800C000484782A51900C8004E472920A5
+:106E9000190078004E4782A50C00C8004E472920F3
+:106EA0000C0008642784A4A4FF0082A40C004800FE
+:106EB000584721200C0078106447B86885A000016D
+:106EC000BA687F0C7C0021200000292032009B78CA
+:106ED0001800AB780100AB780300AB780100AA7D05
+:106EE000AA7C9B788100AB7805007C000120030020
+:106EF00078108F47B5A600105A7EB47080A0B900F4
+:106F00001A78012005007C000120070078108F47C7
+:106F1000B5A600105A7EB47080A0B9001A7801207E
+:106F200004007C009B781800AA789B788100AB78DD
+:106F300001007C0004698CA1FF0096A107004000BD
+:106F4000A54796A10F004000A5477810AC197C001A
+:106F5000246994A13F00C000AE478CA1C0FF05A1E9
+:106F600026687810C63B1C6984A100014000BB471D
+:106F7000146978103B3C0462108206627C002C6924
+:106F800034682E6812A13069386832681BA100A2EB
+:106F900001A37C007E0CE0AD180003607000066168
+:106FA0000B6000000F60000A136000001760000013
+:106FB00007801A601F600000236000007F0C2468B7
+:106FC00085A0800026687C007E157E137E149820A4
+:106FD00080AF2D00A020AC814000EC47A65384A1D7
+:106FE00001004000F2470433BE787F147F137F1501
+:106FF0007C00B07005A0C0108C24B37000807800B5
+:107000004B4BB071FF81400004487810414C7C002C
+:10701000B071FF8140001148487885A008004A7887
+:10702000B3700000781087487C007E0C7E0D7810CD
+:107030008919C0001A4878108C247F0C7E157E13A5
+:107040007E14A02D982CA9203100A3537F147F1308
+:107050007F1507680D010B680000047007801A682F
+:10706000236800001F6800009F6800007F0C7C0000
+:10707000B47080A091001A787800FA24B47080A0CF
+:1070800081001A787800FA24B47080A0B9001A78C8
+:107090007800FA24B47080A0C3001A787800FA242B
+:1070A00004698CA1FF0096A1070040005A4896A1F0
+:1070B0000F0040005A4807681701246884A0FF00A9
+:1070C00085A00002266807809B780E00AA782068B9
+:1070D00085A00080226831200004B66E5A7EB4710B
+:1070E00088A191001A797C0078100548487885A01D
+:1070F0000C004A78B47080A0CD001A7809200B00EB
+:10710000012000447810C7470120130078109747EA
+:107110007800683C7E129120002249208748007048
+:10712000047205A20C7215A2087084A0F7FF05A2D4
+:107130004000994878009E48037000007F120020AC
+:107140007C00007084A00100C000CC48087103815D
+:10715000C800AB487810CE497800A3480C708CA0CA
+:10716000FF004000CC4804700480C800C34814707D
+:1071700005A0C000BF48107005A04000C34802A190
+:10718000C800A348077010007800CC48FF8A400070
+:10719000CC487810184CC000C6484000A34878106E
+:1071A0005749037000007F1200207C007E010461BB
+:1071B0008CA1FF0086A107004000DF488EA10F00D0
+:1071C000C000E24840607800E34828647F01FF8403
+:1071D00040000D49702C0470BCA00F00B8A71D49D9
+:1071E0003C27FB87C000FB484800F54878108C24FA
+:1071F0009C6075A040000D497800E848042768AEFF
+:10720000086830A60C6829A5218440000D493887FC
+:10721000042705A0C000FC489C7075A0C000E84889
+:107220007C000000050009000D0011001500190088
+:107230001D000000030009000F0015001B000000E6
+:10724000000012490F4900000000008000001249B0
+:1072500000001A49174900000000000000001A4908
+:107260000000154915490000000000800000154984
+:1072700000001B491B4900000000000000001B49E2
+:107280007E12912000227920005271201000077098
+:107290000A000770020003700000712020000770D0
+:1072A0000A000770020003700000492000007F12EE
+:1072B00000207C00492057491920000004700480F8
+:1072C000C800AA49077012000871087006A1C00022
+:1072D000614984A1E00140006C4978108C240120B0
+:1072E000FD04042082A00500C800774984A1004065
+:1072F000C00061499CA10C3086A304204000854950
+:1073000086A308004000904986A30C20C000614974
+:1073100000720482480090490C7384A3FF0040006F
+:10732000904978108C2407701200007084A001002E
+:10733000C000AA49087084A0E001C000AA491073E7
+:10734000147005A34000AA490C7184A10003C00079
+:10735000AA4984A1FF00C0005749077012000770B6
+:107360000800047084A00800C000AE490770120035
+:10737000087103814800B3490370000049200000F0
+:107380007C007E107E007E127E1591200022087106
+:107390007810CE497F157F12912001807F007F10E9
+:1073A0007C00047200750C7384A30003C000F549CF
+:1073B00084A1E001C000194A087184A1E001C00065
+:1073C000194A0120FD04042082A00500C800E949F3
+:1073D00084A10040C000D94984A107007900ED498B
+:1073E000F749094AF549094AF549554AF549534AC1
+:1073F00078108C24047084A0100085A00200067010
+:10740000FF8AC000044A492000007800084A78102A
+:10741000184CC000044A7C00047084A0100085A0B1
+:1074200002000670FF8AC000144A7800184A7810DB
+:10743000184CC000144A7C00077012000871E0006C
+:107440001C4A91200060E000204A912000600770F3
+:10745000120007700800047084A00800C000284AC9
+:10746000077012000871038148002D4A0370000064
+:10747000007005A0C000414A047005A0C000414A48
+:107480000C7005A04000434A7800244A49200000BF
+:107490007810D738186884A0008040004E4A1B68D6
+:1074A00002007C0078108C2478108C247810B14A6B
+:1074B000107214710C709CA0FF00002800A311A290
+:1074C00089A100007810B14A0427582C60AC0863E9
+:1074D000002222A30C6300211BA3002405A340006B
+:1074E000784AC800784A128410820A8389A1000071
+:1074F000602B78005F4A602B078A7E00046084A0BE
+:1075000008004000844ABAA717497800864ABAA7FB
+:107510000F497F003DA7002C86688A6F926C8E6BA6
+:1075200007701200781057497C003887042705A09F
+:10753000C000A54A9C6005A04000AE4A60200460DF
+:1075400084A00F0080A01D493C20FB8740108C24A4
+:10755000518A4000AD4A087084A0030086A0030051
+:107560007C00512000007C00508A3987042704A049
+:10757000C000C54A006064A0C000BC4A602D046021
+:1075800084A00F0080A02D493C20FB8740108C2454
+:107590007C007E127E0D912000227F0D8468602089
+:1075A00088688C6B906C5780D4AAFF0084A0FF0081
+:1075B0007E00046884A008007F004000E04AB8A074
+:1075C00017497800E24AB8A00F49087EB5A60C001A
+:1075D00004698CA1FF0086A107004000F04A8EA13B
+:1075E0000F00C000F94A1C6884A040004000004B16
+:1075F000B5A601007800004B1C6884A04000400044
+:10760000004BB5A6010007700400047084A00400BC
+:10761000C000024B002405A3C0000D4B7800334B83
+:10762000582C0427046160AC006000A41A70046048
+:1076300001A31E7084A108004000234B106081A0AC
+:1076400000002270146081A00000267008620024EF
+:1076500002A212700C62002303A216700276077059
+:107660000100602B7810924A7800354B7810184C46
+:10767000C000334B7F1200207C007E127E0D9120D3
+:1076800000227F0D07700400047084A00400C00075
+:10769000414B037008007F1200207C007E127E0D9B
+:1076A000912000227F0D49204B4B0770040004708D
+:1076B00084A00400C000544B087EB5A60C000469E9
+:1076C0008CA1FF0086A107004000674B8EA10F0030
+:1076D000C000724B1C6884A0400040006E4BB5A6F1
+:1076E00001004068502078007B4B1C6884A020007B
+:1076F000C000794BB5A6010028685020602D0460B9
+:10770000BCA00F00B8A71D493C27FB87C0008F4BCA
+:107710004800894B78108C249C6865A04000934BEE
+:1077200078007C4B7810184CC0008F4B7F120020E3
+:107730007C007E127E007E017E0D912000227F0D56
+:107740007F037F04087EB5A60C0004698CA1FF00AE
+:1077500086A107004000AD4B8EA10F00C000B64BC4
+:107760001C6884A040004000BD4BB5A60100780015
+:10777000BD4B1C6884A040004000BD4BB5A6010075
+:107780004920964B7E0104698CA1FF0086A1070069
+:107790004000CB4B8EA10F00C000CE4B406878005C
+:1077A000CF4B28687F0155A04000154C702D602EEE
+:1077B0000470BCA00F00B8A71D493C27FB87C00080
+:1077C000E94B4800E24B78108C249C7075A0602037
+:1077D0004000154C7800D54B042768AE086822A4F9
+:1077E0000C681BA34800024C518AC000F64B78106D
+:1077F0008C243887042705A0C000EA4B9C7075A034
+:1078000060204000154C7800D54B228420841A83D8
+:1078100099A300000869002422A10C6900231BA180
+:10782000C800114C78108C24712020007800004B87
+:107830007F1200207C00087084A0030086A0030053
+:107840004000404C042708AC04211A700881042130
+:107850001E700881042112700881042116700460D2
+:1078600084A008004000374C088104212270088160
+:10787000042126700276047084A0100085A0010007
+:1078800006707810924A7C007E127E007E0D912058
+:1078900000224920414C7F0D7F08087184A103001C
+:1078A000C0006B4C7E0104698CA1FF0086A107001B
+:1078B00040005B4C8EA10F00C0005E4C4068780019
+:1078C0005F4C28687F0105A04000794C78009E48F5
+:1078D00020006B4C7810554A7800794CA000724C0F
+:1078E00008717810CE4978004A4C07701000A0004B
+:1078F000744C08717810CE49087086A00800C0004A
+:107900004A4C007005A0C0004A4C0370000049209A
+:1079100000007F1200207C007E127E147E137E15F4
+:107920007E0C7E0D912000227F0D4920894C80AD78
+:107930001100A020992031000C7084A0FF002A685B
+:107940000770080007700200037001004000A84C97
+:107950000080AC80A55307700400047084A004006C
+:10796000C000AA4C7F0C49200000037000007F1566
+:107970007F137F147F1200207C00912000609120F3
+:107980000080CC7805A04000D14C9479D07006A13D
+:10799000C000D14C047805A04000D14C077800000D
+:1079A0006800D14C91208040207801802278C0006E
+:1079B0002C4D2478227869204052006884A007006A
+:1079C0004000EF4C86A002004000EF4C34680DA050
+:1079D0004000EF4C042105A04000EF4C01800A203C
+:1079E0004000D44D487805A04000FD4C01804A7805
+:1079F000C000FD4C0920020144680A2078106F2263
+:107A0000906805A04000094D01809268C000094DB2
+:107A10006F6800007368010061200055A920000113
+:107A200009200200346005A040001F4D018036602F
+:107A3000C0001F4D106005A040001F4D7E01781052
+:107A40006F227F01E0AC10007000254D78000F4DD3
+:107A5000098140002C4DA920000178000F4D7810BD
+:107A6000394D78105E4D0920515204210920020140
+:107A70000A20912001807C00347801803678C00093
+:107A80005D4D3878367891200080447805A0C0009C
+:107A9000484D012001010180467880A000754020FA
+:107AA000042065A040005D4D246005A04000594DB4
+:107AB0000180266040008D4D0060402C78004E4DC6
+:107AC0007C00287801802A78C0008C4D2C782A7898
+:107AD000307805A0C0006B4D012000020180327893
+:107AE000038003800380038090A0005598A20200C9
+:107AF000042384A0080040008C4D90A209000422B9
+:107B000005A04000844D01801220C0008C4D04234C
+:107B100084A0F7FF85A080001A2078106F227C00D7
+:107B200069204052006805A04000974D486806ACA7
+:107B30004000D44D1B600600B46084A0003F1E606E
+:107B4000206084A0FF0085A06000226000604220C9
+:107B50001467826F7810C519186805A04000AF4DF2
+:107B600001801A68086884A0EFFF0A681068018025
+:107B7000D000B94D78108C2412682F60000033605B
+:107B80000000682C7810DC1C69204052447984A1E4
+:107B90000001012006006E68C000CF4D86690120FB
+:107BA00004006E6878106A22912001807C006920B0
+:107BB000000109204052042184A007004000304EFB
+:107BC00086A00700C000EA4D7E0D092052526C21AC
+:107BD00078101C3B7F0D7800304E092052526421F2
+:107BE000781037241B600600586884A0003F1E6090
+:107BF000206084A0FF0085A0480022602F60000064
+:107C000033600000306884A040004000244E4B6880
+:107C10000400A9201400486884A004004000114E0C
+:107C20007000114E7800084E4B680900A92014001E
+:107C3000486884A0010040001E4E70001E4E78006F
+:107C4000154EA920FA007000244E7800204E0868D6
+:107C500084A0FDFF0A681B68480009205B520B20C6
+:107C600007004C784A78912001807C0079200052EE
+:107C700078105E4E7810424E7810504E33780000E7
+:107C8000477800004B7800007C0019200300112089
+:107C90004652042286A03C0040004D4E19200200AE
+:107CA0002A7B2E7B7C0019203900112046520422A9
+:107CB00086A03C0040005B4E19202700367B3A7BB3
+:107CC0007C001920713911204652042286A03C0004
+:107CD0004000694E19202626227B267B3F78000033
+:107CE00043780A007C0020002B00000020000000E8
+:107CF0002000000020000000200000002000000004
+:107D000020000000200000002000000020000000F3
+:107D100020000000200000002000000020000000E3
+:107D200020000000200000002000000014001400CB
+:107D300049981400140014001400140014001400D6
+:107D400080000F00000001020406080C20212240E0
+:107D500080F818000B3001A2140000A2140000A249
+:107D6000140200006C0002001400CD989E009300E5
+:107D700002A2388806383988C32064088598C1284B
+:107D8000AE9C03A20C30462861816A840083561899
+:107D90003A886598F228919C58980C30E128919C7B
+:107DA000022806A2C3642E2807A2A064E06DA06783
+:107DB000C06F14183B882478C16864783E8879982D
+:107DC000768577866B20C128AE9C44200321A220B3
+:107DD0008120659809A201298D98140005A200A3AD
+:107DE00072189A873C88E21F01C60AA26E850407B2
+:107DF000919C140004A200A30930E21964F86E8576
+:107E00003F88E608919881F88C9801C81400C1F861
+:107E10001600B285F080329502FBE21D1400328517
+:107E200041F21400E21DA884A0D7E61F140008A2A6
+:107E300043600880C11D1600008360812A8441F0E0
+:107E40000830A884D6114270DD201100D520228888
+:107E50001600008047281110C098008000A002285A
+:107E60001110C69865983E281110CA980BA21700E9
+:107E70000C3000A3E21D81DB14001002D79814001F
+:107E8000E0263A8702FBF219E21F14000DA2063821
+:107E90001002B39C040700006C0002004F9814000D
+:107EA0009E00A0001700FF600C30208711A2D09C1C
+:107EB0007287378801217A98D210E278D39C59983A
+:107EC00084D9E2F0A1F0CD981400318866D13088D1
+:107ED0000F80019420B502C820887A9801237A98EF
+:107EE000D210E478D39C21882088599823F142F15C
+:107EF00001F1C698D210F670328803820C879ED9A1
+:107F000001601400456814021BA2D09C0120C59892
+:107F10000182521884D163D1348801808D98273032
+:107F2000A884561A3388140018A28169BC9C26695B
+:107F30000269341A9998141A2170140000A341613F
+:107F40006469108092852680B984E4692380E116F3
+:107F50000180F110466913A2621413A20080E11699
+:107F6000B598696914A2C2610280E1140480E11627
+:107F700001010A302788140017A2BC9C140000A33A
+:107F800081812A84A884E61C2C88160012A2D09C29
+:107F9000D210E4700400078024941ACCD39CC598B6
+:107FA00027880A3013000080A4841600C2111E2105
+:107FB0000E871DA214008E8716001CA23510919802
+:107FC00010A200A0108092853B8544D02280073803
+:107FD000BB84EA9821800738B9840C307E812B87D6
+:107FE00072879198000020002B0000002000000004
+:107FF0002000000020000000200000002000000001
+:1080000020000000200000002000000020000000F0
+:1080100020000000200000002000000020000000E0
+:1080200020000000200000002000000014001400C8
+:10803000499814001400E298CD981400140014001C
+:1080400080003701000001020406080C20212240B4
+:1080500080F818000B3001A2140000A2140000A246
+:10806000140202A2388806383988C32064082FA871
+:10807000C128AE9C03A20C30462861816A8400832B
+:1080800056183A8804A8F228919CF4A80C30E128EC
+:10809000919C022806A2C3642E2807A2A064E06D6A
+:1080A000A067C06F14183B882478C16864783E8844
+:1080B00002A8768577866B20C128AE9C44200321D8
+:1080C000A2208120E4A809A2012909A8140005A280
+:1080D00000A372189A873C88E21F01C60AA26E8527
+:1080E0000407919C140004A200A30930E21964F86B
+:1080F0006E853F88E608F7A881F8F0A801C814004B
+:10810000C1F81600B285F080329502FBE21D140022
+:10811000328541F21400E21DA884A0D7E61F1400A6
+:1081200008A243600880C11D1600008360812A8474
+:1081300041F00830A884D6114270DD201100D5200E
+:1081400022881600008047281110FCA8008000A09B
+:1081500002281110FDA89BA83E281110FDA80BA213
+:1081600017000C3000A3E21D81DB1400100201A8EF
+:108170001400E0263A8702FBF219E21F14000DA258
+:1081800006381002B39C04071700FF600C302087EC
+:1081900011A2639D72873788012121A8D210E2784D
+:1081A000669DFCA884D9E2F0A1F06CA81400318887
+:1081B00066D130880F80019420B502C820880FA8AE
+:1081C00001230DA8D210E478669D21882088E6A8B6
+:1081D00023F142F101F14FA8D210F67032880382E8
+:1081E0000C879ED901601400456814021BA2639D90
+:1081F000012040A80182521884D163D134880180C3
+:1082000001A82730A884561A3388140018A281695F
+:108210004F9D26690269341A01A8141A21701400AE
+:1082200000A341616469108092852680B984E46965
+:108230002380E1160180F110466913A2621413A293
+:108240000080E11607A8696914A2C2610280E114E6
+:108250000480E11601010A302788140017A24F9DFF
+:10826000140000A381812A84A884E61C2C881600AF
+:1082700012A2639DD210E4700400078024941ACCEB
+:10828000669DF8A827880A3013000080A484160091
+:10829000C2111E210E871DA214008E8716001CA27B
+:1082A0003510B4A810A207380C307E812B87728756
+:0682B000ADA800000C0D5A
+:00000001FF
+/**************************************************************************
+ * QLOGIC LINUX SOFTWARE
+ *
+ * Copyright (C) 2004 QLogic Corporation
+ * (www.qlogic.com)
+ *
+ *************************************************************************/
+
+/************************************************************************
+ * *
+ * --- ISP1040 Initiator/Target Firmware --- *
+ * 32 LUN Support *
+ * *
+ ************************************************************************/
+
+/*
+ * Firmware Version 7.65.06 (14:38 Jan 07, 2002)
+ */
diff --git a/firmware/qlogic/12160.bin.ihex b/firmware/qlogic/12160.bin.ihex
new file mode 100644
index 00000000000..dc800ecdaf3
--- /dev/null
+++ b/firmware/qlogic/12160.bin.ihex
@@ -0,0 +1,1771 @@
+:100000000A042A000010040841100000C93600004C
+:100010004320504F525947495448312039392C31E7
+:1000200039313239312C39392C3339313439512085
+:100030004F4C494720434F435052524F54414F4930
+:10004000004E492050533231363146207269776D67
+:10005000726120655620726569736E6F31202E3093
+:1000600034302020432073756F74656D20726F4E9D
+:10007000202E303050206F72756474634E202E6FC6
+:100080002020303020200024C920FF907120000261
+:10009000A070A2700120FF010420FCD0201171206B
+:1000A0000001A070A270C1202000892021127120BF
+:1000B0001000C3700400C7705349CB702050CF703C
+:1000C0002020D3700A000120FD040420D6700920EE
+:1000D000FFFE30212821A2A1004724842484248407
+:1000E00024842484248492A100910920000001200A
+:1000F00032000C08051E182279200047A02F082482
+:1001000011200000A9204000A4420981D81D092027
+:1001100000FF003402A118021001A820A4421B789D
+:1001200064001478CDC0D5C0167871200002D600C6
+:10013000692040470C085C460120FF010420FCD0E8
+:10014000301169208047712000010C085C4614784A
+:10015000D4C01678DE00CA7EC27CC67B67780000F9
+:1001600000788DC0027831203000AF78010123780B
+:1001700002002778020009200200692040471B681E
+:100180000300236807002768FA002B6808002F681F
+:10019000280037680600336808003B6800000981C2
+:1001A0000005CF680A00BF68C04779200047D368C0
+:1001B0002D76C368C04CC768C04BCB68C08CA7689D
+:1001C000448FAB68498FAF68448FB368448FA3688E
+:1001D00001000120FF010420FCD0C81169208047E4
+:1001E0007008CF680A00BF68C049D3683978C3680F
+:1001F000C06CC768404CCB68D08DA768498FAB688E
+:100200004E8FAF68498FB368498FA3680100E6003D
+:100210006920C04B71200002EC70E4D0192009184D
+:1002200021200900201119200C1821200C000C0895
+:10023000751D0120FF010420FCD088116920404C6D
+:1002400071200001EC70E4D0192009182120090068
+:10025000201119200C1821200C000C08751DEE002F
+:10026000112002006920C04C09200200A9200001D1
+:10027000376800000B684000C87B86A3FFFE28118A
+:10028000176800011F6864002000176864001F6879
+:100290000200E8AD1000041F35110981381D01204E
+:1002A000FF010420FCD02811118218016920C06CC4
+:1002B000D8080C08F6220C083D400C088C1B0C08D2
+:1002C000154691200022792000477120500091208E
+:1002D00000247920004771202000912000267920F9
+:1002E00000027120404791200028792000017120F0
+:1002F00080479120002079200047712010000032B3
+:1003000085A03D30902071201000C37000000410C3
+:100310008C11C07086A0020010110C08BA1339208D
+:1003200000000C08AB12AC7805A08011040E9A11E5
+:100330006C7865A010010C08A1200C08261E040E84
+:10034000AF116C7865A010010C08A120040EAF114C
+:10035000092047471120874704210C2205A11001DD
+:100360000C089B1C71204047A07005A0E8014C744C
+:1003700085A40000C8017920000291200080D0727D
+:100380008CA23D3090210C084C27912000809120B8
+:100390003D30040ED111792000476C7865A0200112
+:1003A000712010000C08A120041DD91179200047EC
+:1003B000712010000C08294471208047A07005A00E
+:1003C00088014C7025A070017920000191200080E7
+:1003D000D0728CA23D3090210C084C2791200080D7
+:1003E00091203D307920004771201000040EFA1151
+:1003F0006C7865A010010C08A120041D8E110C085A
+:10040000294404088E11003C84A0070002000C124D
+:100410000C120E120E1213121312181218120C08CC
+:100420007525912000240C08D5400500912000225C
+:100430000C08D5400500912000220C08D5409120E1
+:1004400000240C08D540050041124112421242120C
+:100450004D124D124D124D1256125612611261126A
+:100460004D124D124D124D12701270127012701208
+:10047000701270127012701270127012701270126C
+:100480007012701270127012F80C0600060126012C
+:10049000912000280C0892252E010E010E000D005F
+:1004A0000600060126010C0800122E010E010E00A6
+:1004B0000D00060006012601912000260C08922559
+:1004C0002E010E010E000D000600060126019120EE
+:1004D00000260C089225912000280C0892252E0158
+:1004E0000E010E000D00060006012601D600E600F2
+:1004F000F600792000477120000269204047003D46
+:100500008CD03001EC7084A0001CE2780C085C46B2
+:10051000003D84D050016920804771200001EC70BB
+:1005200084A0001CE6780C085C460C082625FE001A
+:10053000EE00DE002E010E010E000D0008700B8093
+:100540004012077002008CA0E00120119CD008012D
+:1005500087089708C37002400408BD13040E1E13D9
+:1005600061200000186084D004191E13287805A0AB
+:10057000201104001F1304081E13FCD030010600D4
+:100580000C08291B0E005001280006000C081E1B39
+:100590000E002001012007400408BC131079FCD094
+:1005A0002811612040479CC1FCC720006120804782
+:1005B0009DC1FDC7606005A004191E1312797E60FD
+:1005C0002878FCC086A018002011C6000C08261947
+:1005D000CE002B780000786065A0E001C6009C602A
+:1005E0000C08F31BCE009F6000000C08601A092065
+:1005F00018008760030110780600FF841011FF8542
+:100600001001C5C012780C08341B0E001278981126
+:100610000C087F1B10789CD01811612040472000E7
+:10062000612080479CC012787B600000D060C4D0FD
+:100630003001C4C0D260012005400408BC13040886
+:10064000BA13050006A0C270C670CA70CE70DA7008
+:10065000C0703DA08AA04000041A6C130200BA13B7
+:100660000814D6133C1470147014CE13781A7A142C
+:10067000C813DA13DB13DC13DD137C1AC8138714D9
+:10068000DB144119721ADE13C817FE1730187618DA
+:1006900085179217A517B717BF15C8130D1518158D
+:1006A000261534154B1559155C156E157C158615D8
+:1006B000A515B115C813C813C813C813CC15DD157B
+:1006C000F7152B165416661669169316CC16DE16F9
+:1006D00053176317C813C813C813C813751700211D
+:1006E0008AA04000041AC8130200C813C813C81314
+:1006F000C813C8139E1AA41AC813C813C813A81A7B
+:10070000E81AC813C813C813C81303146B1482144F
+:10071000D6143C19C813C8130B19C813EC1A901A35
+:100720009A1AC813C813C813C813C813C813C81318
+:10073000C813C813C813C813C813C813C813C813E1
+:10074000C813C813C813C813C813C813C813C813D1
+:10075000C813C813C813C813C813C813C813C813C1
+:10076000C813C813C813C813C813CA72C6710120AE
+:1007700006402800CE73CA72C67101200040C270C4
+:10078000040EBD13612000001B6001009120005089
+:10079000912080400500C3700140900CC37006405A
+:1007A000780C99204100A1204100A9200500A35305
+:1007B000200CC470C37004000708F808F008E808AB
+:1007C000E00891200080C3700400C7705349CB70CB
+:1007D0002050CF702020D3700A0001200400D67072
+:1007E000792000001B7801003120300059200010D2
+:1007F00029201A045120450461204704C12020000B
+:10080000912000509120804004081804D875DC74B1
+:10081000DA75DE741800292000002025D071C87216
+:10082000CC73C470A02099203000037001000770C1
+:1008300006001A731E722274267521204000FF8163
+:100840000409BA1382A140001012202106A008203A
+:100850000384127007700400077001000870FCD058
+:10086000E80D0770020084A0E0012001C37002407F
+:100870000408BD13A824A553100C0408BA1329209A
+:1008800000002025D071C872CC73C4709820A120BC
+:10089000300003700000077006001A731E72227485
+:1008A00026752120400007700600FF810409BA1355
+:1008B00082A140001012202106A00820038412709B
+:1008C000A824A653077001000870FCD0E80D84A08E
+:1008D000E001480DC37002400408BD13D875DC74F4
+:1008E000DA75DE747808C471C87014219EA70400FC
+:1008F00008110A20CA720408B913C7700A00CB7025
+:100900000400CF702A000408BA13D875DC76DA75B3
+:10091000DE761800292000003025C470C872CC7320
+:10092000D074C670CA72CE73D27405A0E8050AA44A
+:10093000080140120180727884A000FC3801AC7874
+:1009400085C0AE78012005400408BC137E7B7A7A0E
+:10095000867E827D767C8CA400FF700107840480F3
+:1009600004800C810C810F8118A191A20000B1A616
+:10097000000081A50000500007840480048018A3B3
+:1009800091A20000B1A6000081A500001A731E729A
+:100990002276267005A61801107AC5C2127AAC78A4
+:1009A00084A0FCFFAE781800AC7885C0AE7804084F
+:1009B000BA13D875DC76DA75DE76180029200000C7
+:1009C0003025C470C872CC73D474C670CA72CE732A
+:1009D000D67405A000050AA41001041ABC130180F6
+:1009E000927884A000FC3801AC78C5C0AE780120B4
+:1009F00005400408BC139A7A9E7BA27DA67E002641
+:100A000005A51801107AC5C2127A967CAC7884A02C
+:100A1000FFFCAE781800AC78C5C0AE780408BA13F5
+:100A2000092000006C7865A0180108810060D80CCE
+:100A3000C47A0408B813092048470C210120FF019B
+:100A40000420FCD00419B91311208847142204088B
+:100A5000B813092049470C210120FF010420FCD0D4
+:100A60000419B9131120894714220408B81361200E
+:100A7000404728612C621482148214820120FF01F5
+:100A80000420FCD04811612080472863DA732C636E
+:100A90001C831C831C83DE730408B81309204C4795
+:100AA0000C210120FF010420FCD00419B9131120EE
+:100AB0008C4714220408B81318790408B9130920C4
+:100AC00002020C218CA1300F0120FF010420FCD078
+:100AD0000419B91311200201142294A2300F040842
+:100AE000B81309204D470C210120FF010420FCD040
+:100AF0000419B91311208D4714220408B813207962
+:100B00000120FF010420FCD00419B913247A040841
+:100B1000B8131120404CC471FCD110111120C04BEE
+:100B2000078184A00F0003800380038068A2006A0D
+:100B3000086B1C6CDA74FCD1181121203B021000E8
+:100B400021203B012424A4A4001CDE740408B71354
+:100B5000C4770C089A1B912000801C6B146A9120AA
+:100B6000018008270408B71361204047186101205D
+:100B7000FF010420FCD00419B913612080471862DA
+:100B80000408B813C4770C089A1B912000800869E8
+:100B9000186A106BDA77912001800408B713C471CA
+:100BA000102194A20F0082A21000041AB3130C08A3
+:100BB000B42384A30040100195A220000408B713B9
+:100BC000C4710021BCC082A01000041AB313BCD1B0
+:100BD00020111120484704222000112088470422B8
+:100BE000BDC006000021BCC012200C0858231E0006
+:100BF0000408B913C471212049470424C670192080
+:100C000000003000C871212089470424CA70FDC348
+:100C100011202316A9200800042206A13801108201
+:100C2000041F0916C471C8720408B21392A22316D5
+:100C3000260022211E000C086A230120FF01042047
+:100C4000FCD01011FCD3F0090408BA13E803FA0031
+:100C5000F401EE020400010002000300612040479D
+:100C600028612C62148214821482C4702A60C870B5
+:100C70000380038003802E600120FF010420FCD04C
+:100C8000A011260016006120804728612C62148282
+:100C900014821482D8702A60DC7003800380038081
+:100CA0002E60DA71DE721E002E000408B813612077
+:100CB00040473061C47032600120FF010420FCD045
+:100CC0000419B913612080473062C870326004088B
+:100CD000B81318790408B913C47184A1CFF048017E
+:100CE0000120FF010420FCD00419B313C8720408CA
+:100CF000B213192000000C08A62336000120FF01C2
+:100D00000420FCD018011E000408B913C87184A186
+:100D1000CFF028010E001021C4710408B213FDC3E6
+:100D20000C08A62310231E000408B813C47182A166
+:100D3000100048020120FF010420FCD00419B31365
+:100D4000C8720408B21311204D4704220600048122
+:100D5000081208811221192000000C089323012099
+:100D6000FF010420FCD018011E000408B913C8714B
+:100D700082A11000280206001021C4710408B213D9
+:100D800011208D47042206000481081208811221D7
+:100D9000FDC30C0893232E001E000408B813C47171
+:100DA000C87284A1FDFF0419B21384A2FDFF0419C7
+:100DB000B2130021207922780022247A26780408B0
+:100DC000B8131120404CC471FCD110111120C04B3C
+:100DD000078184A00F0003800380038068A2C8728B
+:100DE000CC73D874C6710068CA70CE73DA7491205F
+:100DF0000080026AACD2181121200000900084A467
+:100E0000FF0082A00200041A4F173F84BCA7FF0016
+:100E1000400186A7020004194F1784A4FF000409AB
+:100E20004F1761200002FCD1100161200001292030
+:100E30000900312062003F84BCA7FF003001078316
+:100E400084A0FF0010113DA738114120190084A390
+:100E5000FF0082A01A001002A4A4FF00078384A050
+:100E6000FF00880142A8F00286A0100020119CA378
+:100E7000FF009DA3000FBCA3FF00002502A7900266
+:100E8000002602A7781239203A00046805A70668F0
+:100E90000A6B0C6BCE731C68DA701E6C912001809B
+:100EA0000408BA13912001800408B413C4770C0815
+:100EB0009A1B91200080146A1C6B91200180C870DD
+:100EC0001668CC701E6808270408B713C470612028
+:100ED000404718611A600120FF010420FCD004196A
+:100EE000B913C8706120804718621A600408B813EB
+:100EF000C471C872CC7382A11000041AB3130C0819
+:100F0000D82384A30040100195A220000408B71341
+:100F1000C4770C089A1B91200080086A8DC20A6A67
+:100F20009120018008270408B813C4770C089A1B85
+:100F300091200080086A94A2F9FF0A6A046805A05B
+:100F400010010C08D5229120018008270408B8134D
+:100F5000C4770C089A1B91200080086A95C20A6A1F
+:100F6000046805A010010C08D522912001800827F3
+:100F70000408B813C477412001004920050051201E
+:100F80002000912000800C08B21B912001800827CE
+:100F9000086A0408B813C477FCD728010C08291B79
+:100FA00038010408BC130C081E1B10010408BC13F4
+:100FB000C873CC72C677CA73CE720C082A1CE811AB
+:100FC000186805A0A001082776000C08F7237E000A
+:100FD000701101201500FCD718116120404718003E
+:100FE000FDC0612080472A78912001800500912072
+:100FF0000180012005400408BC13912001800408F1
+:10100000BA13C477FCD728010C08291B380104083F
+:10101000BC130C081E1B10010408BC13C67741202A
+:1010200021004920050051202000912000800C085B
+:10103000B21B09201600FCD7181161204047180088
+:1010400061208047FDC1636003007B600000726720
+:101050007F600F002A79D061C4C1D2610C08D5220B
+:10106000912001800500C877CA77C477C677FCD77E
+:1010700028010C08291B38010408BC130C081E1B8E
+:1010800010010408BC13BCA700FF912000800920B8
+:101090001700FCD7181161204047180061208047D5
+:1010A000FDC17B6000006360020072677F600F001B
+:1010B0002A79D061C4C1D2610C08D5229120018067
+:1010C000412021004920050051201000912000807E
+:1010D000C87005A01801D060FDC0D2600C08B21B1A
+:1010E000C8703668388784A71F00C01D9120018012
+:1010F000050019200000C87284D228010C08291BA1
+:1011000038010408BC130C081E1B10010408BC1392
+:10111000C872CA72AC7884A0030018153920000088
+:1011200084D20801FDC7412021004920040051203C
+:1011300008000C089A1B912000800868D4C00DA8F4
+:101140000A693768000091200180388784A71F0052
+:10115000801DBCA700FF3F8738873F8784A7000F0B
+:10116000401D91200080C8726920000184D21011B6
+:1011700069200002086884A0FDFF0A683068B4D0C6
+:10118000B0014B680400A9201400486894D01001F5
+:10119000041FC2184B680900A9201400486884D0B5
+:1011A0001001041FCB18A920FA00041FD2187920BF
+:1011B000004709201800C87284D2181161204047E6
+:1011C000180061208047FDC17B6000002A796360C0
+:1011D00001007F600F00A3600000A460AE60B260F9
+:1011E000D060B4D06001B4C0D260C600B46065A065
+:1011F0000860D4C00A60186001801A60CE00D06018
+:1012000084A0FF7ED260AC788DC0AE78FF830801E9
+:1012100005001B685400912001800500CC730C0868
+:101220007818EC69486A85A100184A6885A14000D1
+:10123000EE68CC7321200400A920FF09041F1B19AC
+:101240002184D01D1983B01DEE694A6A9120018066
+:101250000500FCD71811692040471000692080471D
+:10126000C471C6711669FF811011A3680100AC78C2
+:101270008CC0AE7884D010110C087A1C0500D8758B
+:10128000DC74DA75DE7410002EA02025C471C873DA
+:10129000CC72C671CA73CE7279200047DE7DDA7CCB
+:1012A000D67BD27A0C08771B04095C1AA9200500AA
+:1012B000A120144791200080A141912001800920A4
+:1012C00040000C08411D20010C087F1B04085C1A1B
+:1012D00004608CA0FF008EA10900201106000C08FC
+:1012E00086200E0084A000FF078009800409F11900
+:1012F000C600682C0C08771BA805002C9E68098185
+:10130000C01D9F600000CE00C600DC7DD87CD47B71
+:10131000D07A90A2400099A30000A1A40000A9A542
+:101320000000DE7DDA7CD67BD27A682C9C6865A0D2
+:101330000409F019092040000C08411DA0150460A3
+:1013400084A0FF0086A002005001046084A0FF007A
+:1013500086A00A00381116000C0883201E00002DFC
+:1013600002609808CE00C6009C600C08F31BCE00FB
+:101370009F6000000C08601A092018000860CDC0AA
+:101380000A600460866010780600FF841011FF85F3
+:101390001001C5C012780C08341B0E0012780C081E
+:1013A0007F1B04085C1ACE00C6009C600C08F31B6F
+:1013B000CE009F6000000C08601A092018008760AA
+:1013C00003011B60030010780600FF841011FF85E5
+:1013D0001001C5C012780C08341B0E0012780C08DE
+:1013E0007F1B04085C1ACE001461FCD120010C089C
+:1013F000291BF00118000C081E1BD0010C08601AF4
+:1014000009201800876003011B6021001078060086
+:10141000FF841011FF851001C5C012780C08341B21
+:101420000E0012780C087F1B012007400408BC1333
+:1014300004618CA1FF0086A1050018111C60BDC0CD
+:101440001E60C474C873CC72146091200080E600E2
+:1014500009201200FCD0181171204047180071209B
+:101460008047FDC12A7963700500D071C4C1D27173
+:1014700066736A726E74727077700000002C7A70F6
+:101480002EA030251C6184A1600010010C08E93FEA
+:10149000EE009665A6659A66AA66AF600000B36026
+:1014A0000000146723600000246096A00100101162
+:1014B000008026600C08D522912001800500C370B1
+:1014C00005400408BD13A920050099201447912068
+:1014D00000800A5391200180002110A299A30000EE
+:1014E000A1A40000A9A500000500C471C7700000F8
+:1014F0001E790408BA13C471C671682110006920EE
+:1015000000100C6916A0042D10A2688D0981D81D49
+:1015100085A200001811C37000401000C370034082
+:10152000CA700408BD136479C671C47182A1030036
+:10153000041AB31366790408BA136479C6710408EF
+:10154000BA130079C671C47102790408BA1300791C
+:10155000C6710408BA13C470112000008CA00D00DD
+:1015600060010C81300210820C810C81100210820B
+:101570000C81FF810419B41310820E7A8CD23805C5
+:101580001079CDC11279092021001920030084D2DD
+:10159000C00108811920410011204E8F122319200B
+:1015A00042001082122319204300108212231920B6
+:1015B000460010821223192047001082122319209E
+:1015C00006001120538F12211120738F12230479EA
+:1015D00006780408B9130478C6700408BA13C471F5
+:1015E000FCD118111120C04B10001120404C078174
+:1015F00084A00F0003800380038068A211200000F4
+:101600001468FCD0100195A20002B4D0100195A27C
+:1016100001000C6B0068DA700408B7131478F4D07A
+:10162000300101200740DB70000005A04800FCD01D
+:10163000300101200740DB70010005A0080006A072
+:1016400005001478F4D0300101200740DB70000061
+:1016500005A0080006A005001478FCD03001012088
+:101660000740DB70010005A0080006A0050012710C
+:101670001A721E731078C4D010012274267580ACC3
+:10168000010008810C81A9819880A120300003709D
+:1016900000008460A220A65307700100747984A121
+:1016A00000FF40010F810C810C81048004800780C1
+:1016B00000A118000781048004807C7908A1787A51
+:1016C00006A011A2107DC4D52001847B19A3807CC3
+:1016D00021A40870FCD0E80D03700100077006001B
+:1016E0001A711E72107DC4D510012273267484A055
+:1016F000E0010500487865A02001042C4A786320A9
+:1017000000000500F6007920004748786220002C90
+:1017100005A010110C0875254A78FE00050011205F
+:1017200000914A7AC47B1983280180A232001220DA
+:101730001020C80C13200000050016002600FCD75E
+:1017400018111120C04C10001120C06C84A7000F8C
+:101750000B8084A71F002001038003800380038087
+:1017600005A168A22E001E000500390C00292A6878
+:10177000002A2E68086884A0EFF90DA80A69E6001F
+:10178000FCD728110920524771204047200009202A
+:101790009247712080470C21046805A0480116A1DA
+:1017A000381160200060066816000B200000180049
+:1017B000092000001600046865A078010060066832
+:1017C00021040C08B21D1068087909810A7901808A
+:1017D0001268881D1079A5C112791E000269066978
+:1017E000002D60200C08BF26EE00050065A06001FA
+:1017F00008209C6005A0280162209F60000065A071
+:10180000C00C48784A7962200500076003018F60A8
+:101810000000A9201C0080AC0500A02001200000D1
+:10182000A44028681A602C6822600500E600FCD7F6
+:101830002811712040473120C04720007120804787
+:101840003120C0494C708CA00002281108A60A2D36
+:1018500000804E7006A0EE000500F600FCD71811BF
+:10186000792040471000792080470C089A1B91206E
+:10187000008004680A7865A0F0053000002C0A7822
+:101880006020006065A0B805106006A3B81D0C605C
+:1018900006A2A01D282C487806AC0811480404684C
+:1018A00006AC401100606020066805A018110368AE
+:1018B00000004800006408786020026486A40000EC
+:1018C0001011002C026860250C08021C1B6005002A
+:1018D00023602000FE000C08B21DF6000879098183
+:1018E0000A7910680180126818111078A5C0127862
+:1018F0000120FFFF05A0FE0005007600002739202B
+:101900000000FCD00801FDC741202100492004004F
+:1019100051200800912000800C08B21B388784A752
+:101920001F00D01DBCA700FF3F8738873F8784A7D3
+:10193000000F901D912001807E0005006C78092029
+:10194000748F0C210DA1180165A00408A12061204D
+:101950000000186084D0B81110788CD030018CC091
+:101960001278FCC76920404728008DC01278692092
+:101970008047FDC7912000801C681F6800009120EF
+:10198000018005A0081105008CA0F0FF10010C08D3
+:1019900075250200D71CDA1CE01CE41CD81CE81CCE
+:1019A000D81CD81CD81CEE1C181D1B1D201D291D61
+:1019B000D81CD81C05000C0875250C087A1C0120C1
+:1019C00001800408321D012003800408321D01201B
+:1019D00004800408321D0C087A1C012006800408CB
+:1019E000321D11200A8091200080FCD71811692037
+:1019F00040471000692080473820006886A000001A
+:101A000020011E6F91200180050026007068BCA097
+:101A100000FF4120210049200400512010000C0843
+:101A2000B21B388784A71F00D01D912001800E00B3
+:101A30007069C671D00001200C80B8000C087A1CB7
+:101A400001200D809000FCD71001E4780800E078B8
+:101A5000C67001200E804800FCD71001EC78080009
+:101A6000E878C67001200F800000C270FCD7181102
+:101A7000DB7000001000DB700100612000001B60C3
+:101A8000010091208040050080AC0100FF81180515
+:101A900099203000A0200C7084A0FF07000118706E
+:101AA00006001C70060020700600247006001271EB
+:101AB000AC811A721E7322742675037001000770C0
+:101AC000010008700B80E81E077002008CA0E00186
+:101AD0001011A55306A003700000077004000E004B
+:101AE00026700E0022700E001E700E001A70050087
+:101AF00011202000092010000A6B0E6C1F680102E3
+:101B0000036820FD076838001A6A002DE8A0080065
+:101B100090A204000981801D0500EC70DCD0201526
+:101B2000292001001478CCD06011EC70E4D0192089
+:101B30000A0C21200A00201119200C0C21200C0075
+:101B40007000EC70E4D0281119200C1821200C0032
+:101B500030001920091821200900ADA500020A6BE8
+:101B60000E6C1E6D07683800050004608660082C46
+:101B700063200000687805A06A791001022C080033
+:101B80006E790500C6006120004787680301082DB3
+:101B90006B200000686005A06A611001022D08003A
+:101BA0006E61CE00050091200080042C6E7805A0A7
+:101BB00008116A78912001809C6005A08801C60008
+:101BC000602008209C6005A0380162209F60000012
+:101BD00065A09C6005A0C81D48784A796220CE00A7
+:101BE000487862209F60000085AC000010110C084E
+:101BF00075254A780500A920100006A0048086807B
+:101C00008E81081200A2041FFC1D86808E810500B3
+:101C10005601A920100005A0B8011AA1A81213822C
+:101C20008D8128021AA12012041F0C1E28001AA15F
+:101C300008231082041F0C1E0600003284A0FFEF50
+:101C400080200E005E0105000600003285A0001015
+:101C5000B80C747DD07006A50409DA1E10785020E7
+:101C60000C08771B0409DA1E46A070790025008055
+:101C700012A10920400008123000D07206A21801FB
+:101C8000408809208000C600127107700100992069
+:101C90003000A920200080AC0100A02061200000BD
+:101CA000FF8810010C08771B0870FCD0E80D077046
+:101CB0000200912001808CA0E0013815A553FF8C13
+:101CC0002011FF880409C71E5000002C8E78A9201F
+:101CD000200080AC0100A020A5530408C71E46A028
+:101CE00018721C73C4DA10012074247592A240008B
+:101CF0009BA30000A3A40000ABA500001A721E73F2
+:101D0000C4DA18012274267506A0077004000409BD
+:101D1000C71EFF8C10010C087F1BCE000C087F1B18
+:101D200046A0887800808A7886A00200C0017C7A6C
+:101D3000787BC4DA1001847C807D7479078104800B
+:101D4000048010A299A30000A1A40000A9A500008E
+:101D50001A721E73C4DA8805227426757004146022
+:101D6000FCD018116920404710006920804791205D
+:101D700000801F680200FF88200146A08C78602048
+:101D8000700C8B780000AC7885A00300AE789120B1
+:101D900001809800CE008B7800000C085C20046065
+:101DA00084A00F005900FF8830018C786020046007
+:101DB00084A00F0019000408261E05000200EC1E76
+:101DC000071F201FEC1E2D1FFD1EEC1EEC1EEC1E1F
+:101DD000051F1E1FEC1EEC1EEC1EEC1EEC1E392017
+:101DE0000004BC7805A7BE78086005A70A600C0847
+:101DF000691F9C60BA789F6000000C0848200500AD
+:101E0000BC78C4D00801580C1C60BDC01E603000F6
+:101E10000C088620BC78C4D00801080CBF780000EC
+:101E20000460078084A0FF00B278018038010C08AC
+:101E3000691F2001BC78C5C0BE7810000408841F4B
+:101E400005000C088320BC788CA0000E1011C4D0B3
+:101E5000081128080C08691F10110408841F0500C8
+:101E6000BC78C4D010010408EC1EBF7800001467D1
+:101E700011200100A822186084A0FF0005A088019D
+:101E8000BCA700FFA92020008EA001005001BCA724
+:101E9000008011200200A92000018EA0020008018C
+:101EA000C0000C089A1B002D912000802B680000B8
+:101EB0002F680000086884A0DEFF0A68E8AD100003
+:101EC00091200180041F511F11821801A9200001D7
+:101ED000580C0C087F1B05009F600000B4786DA0B3
+:101EE000002CB6781011BA7838009E68002D026078
+:101EF000B87806AD08110260B0780180B278301170
+:101F0000BC78C4C0BE78B878602006A00500E600A2
+:101F10002EA03025BA7DB67DAE65B2651C60A2608C
+:101F2000482084A9FFE11E6084A9600060010C08BC
+:101F3000E93FFF864011FF853011392000080C0869
+:101F40004820040846209665A6659A66AA66146726
+:101F500071208047FCD710117120404784A7000FE3
+:101F60000B8084A71F00200103800380038003806F
+:101F700005A1C07168A10027078084A00F0003801D
+:101F800003800380C47100A1C26091200080147896
+:101F9000C4D03801FCD71811F4D040111000FCD087
+:101FA0002811086E84D6F001FCD9E011912001803F
+:101FB0000C08021C912000800C08B21D91200180A9
+:101FC0001478C4D004094620FCD72011F4D0301175
+:101FD00004084620FCD01011040846201B60210094
+:101FE00004084620246096A001001011008026609D
+:101FF000106A146802A268026001912001803920F1
+:1020000000029C60BA789F6000000C084820040819
+:102010004620082CFCD9F001006865A0D801046AAC
+:10202000007084A002006801487006A25011046B81
+:1020300060210423026005A0081102696022026188
+:102040009800002D60200C08BF26086E60210262F7
+:10205000066950000068026965A01001026108006D
+:1020600006696021036000006021FCD91801B4A654
+:10207000FCFF0A6E1068087D28850A7D00801268C2
+:1020800091200180B4D62801B6A640000A6E0C0843
+:10209000131CEE000500086005A70A60912000806F
+:1020A0000C08B21D91200180B87865A028019C60C1
+:1020B000BA789F600000780CB678BA78050070791D
+:1020C0007478182884D31801008012A1200200809F
+:1020D00012A1781284C37C7A1A72787A1E72C4DADA
+:1020E0002001847A2272807A267206A084D30801A5
+:1020F00000807678D2701C7805A0380101801E78A7
+:102100002011040E82209120804005003920982063
+:10211000100039209E20042705A0600100AC682033
+:102120000869106812690A680C69146816690E68F3
+:102130003887880C0500030009000F0015001B00FC
+:10214000000015001B000000412000000C78020078
+:102150004A222522A92019213920748F3427107D85
+:10216000C000846086A00301041903211461186073
+:1021700005A12001FF86D81104080321038680A051
+:10218000558F0C6202220080106202220C08D01DC2
+:1021900030868EA60F00040984216C7865A0081D86
+:1021A000087802A62012ACD510113A26050082A6A6
+:1021B0000300041A8421912000806920000018681F
+:1021C00084D0F8111120558F0422C6701082042289
+:1021D000CA7084D6301110820422DA701082042270
+:1021E000DE7085A62080C2701B68010091208040AF
+:1021F000107884A0CFFF1278912001803B2000004E
+:1022000005001078ADC01278040884213A260C0825
+:10221000502204196C226C7865A00419AE2091201C
+:102220000080107884A0CFFFFF860801ADC012782F
+:102230009120018004086C223920748F3427107D8E
+:10224000A000846086A0030104196E211461186047
+:1022500005A12001FF86B81104086E2180A6558FC4
+:102260000C6202220C08D01D30868EA61E000409C6
+:1022700084216C7865A0281D087802A62012ACD5B0
+:1022800010113A26050082A60600041A8421912026
+:10229000008069200000186884D0F8111120558F43
+:1022A00009204E8FA8261C2104221A2008811082A2
+:1022B000041F502185A63080C2701B680100912048
+:1022C0008040107884A0CFFF12789120018006A072
+:1022D0000920758F0A203A2005001078ADC01278C9
+:1022E000B0003A260C08502204196C226C7865A0C4
+:1022F00004191E2191200080107884A0CFFFFF8652
+:102300000801ADC012789120018004086C22912050
+:102310000080077004009479D47002A1280268013B
+:10232000907B02A350111000028038113A261078D9
+:10233000ADC0127891200180050084A100FF40010A
+:102340000F810C810C8104800480078000A118009B
+:102350000781048004809C7A10A21A72987A06A0E1
+:1023600011A21E72C4D43001A47A11A22272A07AE2
+:1023700011A22672A1203000037000000920548FA2
+:102380000A2609819821042184D008013386B0A649
+:102390000200A826A65303861270077001009079E8
+:1023A000947800800AA1081206A02820747984A1DC
+:1023B00000FF40010F810C810C81048004800780A4
+:1023C00000A118000781048004807C7908A1787A34
+:1023D00006A011A2C4D42001847B19A3807C21A46F
+:1023E0000870FCD0E80D84A0E001D001107D312000
+:1023F000548F3426A8780080AA788CD038110770C2
+:102400000600047094D0E81D04088621692047471F
+:102410006B200300AC7885A00003AE7806A04800CE
+:102420003020D67591208040967D107DACA5CFFFE1
+:10243000127D91200180AA78077006003A26037069
+:1024400001001A711E72C4D5100122732674050092
+:10245000846086A00301D8111461186005A1B81129
+:1024600069200000186884D090110C60C67010605C
+:10247000CA70C37020801B680100912080400C0846
+:10248000D01D040E43226C7865A0101D0500590074
+:1024900030156C7865A0E0191004290000156C78DF
+:1024A00065A0D81DE000846086A003016811186053
+:1024B000FCC01A6086A0040038110478A4D0200162
+:1024C0000C08D01D06A005007900181185A0010098
+:1024D0000500B900101141200100107D0500FF88A2
+:1024E0001001912080400500907B9479D47002A166
+:1024F000181185A300000500100202A30500028048
+:10250000050084A100FF40010F810C810C81048033
+:102510000480078000A118000781048004809C7A51
+:10252000987BA47CA07D10A206A019A321A429A5B4
+:1025300009201800286005A01001092040000C089F
+:10254000341BD001A8780080AA788CD010151460B4
+:10255000FCD0181169204047100069208047912065
+:1025600000801F680300AB780000AC7885A00003F2
+:10257000AE78912001806800AB7800000C08D01D77
+:102580009079947800800AA1081206A09678D670F7
+:1025900006A071201000912001800500FCD71811C1
+:1025A00009205847100009209847912000800A20F0
+:1025B000F6000920804779200001FCD7201109206E
+:1025C000404779200002042186A000008011FCD73A
+:1025D000181109204547100009208547042105A04E
+:1025E0003011307884A0C00010111B785200FE001A
+:1025F000050009200200692000470120FF01042096
+:10260000FCD004194B237120804779200001212040
+:10261000BF494B780F000120FF010420FCD01801B6
+:102620001920373E3000A1202B011920373E84D1DC
+:102630001001A1202B02042305A040019A781883E1
+:10264000AC2318839823A6531833A80C9B7800005A
+:102650009B782000A9201000AF780000AF782020E0
+:10266000041F29230370000016008CD109200000EC
+:102670000801BDC10C086C241E00207084A00F004E
+:1026800085A0006306780F7800904378D8005378CF
+:1026900090000B78082F52744F70000009814001A0
+:1026A00071204047792000022120BF4704080623FB
+:1026B0000C0826250500160011200101BCD11011BF
+:1026C000112001028CA10F00042284A0F0FF05A1BB
+:1026D00012201E000C086C24050011200101FCD3FF
+:1026E000101111200102A92009000B81041F72237F
+:1026F0008CA1000E042284A0FFF105A11220050088
+:102700001920020009200101A92005001382041FDD
+:10271000832394A2E000042184A01FFF05A20A20C5
+:102720001983180109200102780C0500112001010C
+:10273000FCD3101111200102A9200C000B81041FF1
+:102740009B238CA100F0042284A0FF0F05A112207E
+:10275000050011200201FCD31011112002020422F5
+:102760009CA0300F84A0CFF005A112200500C60068
+:1027700061200001BCD1101161200002BCC10381A5
+:10278000038080A020009A60AC62AC63CE0005009C
+:10279000C60061200001BCD1101161200002BCC143
+:1027A0000381038080A022009A60A46084A0DFFFE0
+:1027B000AE60CE000500C60061200001BCD1101142
+:1027C00061200002BCC10381038080A020009A60C8
+:1027D000A4608CA220001801ACC29DA30040ECC3F1
+:1027E000B4D30811EDC3AE621020A460AE6318200C
+:1027F000CE00050091200080C600E600186805A004
+:1028000004095024FCD118016120D08E10006120F1
+:10281000C08D0C0858246005A9200101FCD11801C5
+:102820006120D08D10006120C08CC6000C08582497
+:102830002801CE00608C041F1224A8040E00FCD1D5
+:10284000280182A0D08D71208047200082A0C08CFA
+:102850007120404776707271382101200400627047
+:102860007F700F00D071C4C1D2710C08CB22C000A0
+:10287000FCD1181171204047100071208047206062
+:10288000DDC0226072713821002C7A7001200600B0
+:1028900062707F700F00D071C4C1D2710C08CB225E
+:1028A000012000001000012001009120018005A0FE
+:1028B000EE00CE000500042C05A070016020106021
+:1028C00006A340110C6006A22811146006A1101185
+:1028D00006A020000060800C85A001000500F60025
+:1028E000E60016007920804771200001BCD120113C
+:1028F000792040477120000220798CA10F00EC70F4
+:10290000C4D010111E0060000B810B810B810B8164
+:102910000E008DA10008BCD010118DA1000F042164
+:10292000EE00FE000500012001470420ACD0381164
+:10293000E468ACD0200184A006000811090005005D
+:102940001460E600360018207120404CFCD01011B5
+:102950007120C04B078084A00F0003800380038098
+:1029600070AE047084A00A0004192325087194A194
+:1029700000FF040923258CA1FF001C7084A000FF28
+:10298000C001047085A03A0006700120090002A170
+:10299000D81601200A0002A1D01601200C0002A1C5
+:1029A000C8161C7084A0FF001E70047084A0DFFF96
+:1029B000067001200A0006A1A80101200C0006A152
+:1029C000A0010120120006A198010120140006A117
+:1029D00090010120190006A188010120320006A102
+:1029E0008001D80009200C00D00009201200B80096
+:1029F00009201400A00009201900880009202000E7
+:102A0000700009203F00580009200A0040000920FA
+:102A10000C002800092019001000112000000021DE
+:102A200005A20A70047085A00A0006707120004794
+:102A30000470BCD05801FCD32011EA7371204047C8
+:102A40001800EE73712080471F700D003E00EE00ED
+:102A500005000120FF010420FCD0D0110120FD045D
+:102A6000042082A00500A01271200002EC718CA14C
+:102A7000001C0F810C810C8179200001EC7884A06E
+:102A8000001C07800480048005A18AA007000802BA
+:102A90000500020074255B2574255B254E256825FD
+:102AA0004E25087084A0FFC385A000300A70087806
+:102AB00084A0FFC385A000300A780500087084A0B8
+:102AC000FFC385A000200A70087884A0FFC385A0FA
+:102AD00000200A780500087084A0FFC385A0000CC0
+:102AE0000A70087884A0FFC385A0000C0A7805004E
+:102AF000040E7525912000807120000006001870DA
+:102B000084D0E81D0E0071201000CA700E00C6703F
+:102B1000C3700280DB70040ADF702A00712000009D
+:102B20001B70010091208040F80C3C7F587E307C67
+:102B3000387DA0788A708E75927496769A7794A56F
+:102B40003F00F4D43801BCD7281184A77D000419B4
+:102B50009C3C71089CA40F0082A304002003A6A340
+:102B6000070030191824078584A00F0002006C2B81
+:102B7000572C952CFB2E7932D03276330534D9344C
+:102B8000AB35C725C4259E29852A4D32C4250C089E
+:102B90007525050006A0380008788DC00A7806A0C3
+:102BA00002704A704270CE705C7005A0041918273C
+:102BB000607084A007000200E12552265A26632691
+:102BC0006C26FE26752652263078BCD0101DD0719A
+:102BD000BCD1F819B4D104192F26A07086A0010029
+:102BE000C009147005A0A819B0706DA0006865A098
+:102BF00055A09B7880000C6BAA7B086845A0106DDF
+:102C000004686DA05DA086A801001801BC69AA7DBA
+:102C1000AA79C0684DA01C6E0120100004084B2842
+:102C20005C7005A00419C625C600D600B0706DA062
+:102C3000006865A055A09B7880000C6BAA7B086893
+:102C400045A0106D04686DA05DA086A80100180164
+:102C5000BC69AA7DAA79C0684DA01C6E0120200025
+:102C600004084B280C085B3C0419C6251B78680037
+:102C7000B8706DA0B4685A789468D678DE78986891
+:102C8000D278DA7808788DC00A78BC683E70B4C112
+:102C9000D271B47065A0C068567003700200002D38
+:102CA0004A7080AD0900427005000C085B3C2011A1
+:102CB0001B7854000370040005000C085B3C2811CD
+:102CC00011200C0019040370040005000C085B3C83
+:102CD000281111200600D1000370040005000C0823
+:102CE0005B3C281111200D008900037004000500D1
+:102CF0000C085B3C501111200600410078707B707D
+:102D0000000068204A700370040005007071FCC167
+:102D1000078182789B78800086A20C002011AA7A15
+:102D20000120010098008CA11F008DA1C000AA798C
+:102D300086A20D002001AA7A012002003800AB789B
+:102D400020007471AA79AA7A012004009B7860009F
+:102D5000AA785B7804001B7813010C086E3C7F7026
+:102D60000F00D070B4D06801B4C0D270C600B47087
+:102D700065A0086084A0EFFB0A60186001801A60FB
+:102D8000CE000500147005A03811D070B4D0280111
+:102D9000B47006AC1011290C05001600A07186A1B4
+:102DA00001002805D600260000211120010012A2F2
+:102DB000B0706820006806AC20011182B001C90023
+:102DC000C80CC60000211120010012A2B0706820BA
+:102DD00000686020086084A0EFFB0A601182100187
+:102DE0004100B00CA3700100CE002E00DE001E00DA
+:102DF0000500E8AD0500A87006AD1011A4706820AC
+:102E000005000C085B3C0419C625787068207077B3
+:102E10000C08953B502C0C08F63C9B7880001468FD
+:102E200084A01F00BDC0AA781C6E412001000120B3
+:102E30000400040850280C085B3C0419C6259B7844
+:102E400080005C706820146FD070B4D06801B4C08A
+:102E5000D270C600B47065A0086084A0EFFB0A6061
+:102E6000186001801A60CE000C08953B502C0C08AD
+:102E7000F63C246805A0300182A00600080210007C
+:102E800027680500146884A01F00BDC0AA783120FF
+:102E900020004120010001200300040850288DC2B9
+:102EA000D272BC7200A215A0507108812AA108023A
+:102EB000BC7164210465FF85701152712184A81DC5
+:102EC000D0708CD02801CC7005A01011CF700A00F2
+:102ED00005000022900CD0708CC0D270CF70000022
+:102EE000346005A0B01D086784A73F07D001D4D780
+:102EF000801D84A72100681D84A70200300184A7DB
+:102F00000400380DBCA7FBFF0A6784A71802081D40
+:102F100084A700013001186005A0D819BCA7FFFEE6
+:102F20000A676825236800001C6E84A60E001863DB
+:102F300028011C6002A3200218015808FF834819C9
+:102F4000582D502C5271BCD72011287022603A6045
+:102F50001000BCC70A67C06865A04DA00061602A68
+:102F600041200100146B9CA31F009DA3C000FCD155
+:102F7000100184D610019CA3BFFFA4D610019DA30D
+:102F8000200084A60E0004190228A5C70A67002C99
+:102F9000C668A07786A701007811D070B4D0601100
+:102FA000007082A0020040123078BCD028119B78BB
+:102FB0008000AA7B040849283987A2775027AC777C
+:102FC000B0A70500A87006A60811A476AE763A2C24
+:102FD00038873A2D38873A2838873A2338873A2570
+:102FE0003078BCD050019120008091203D30D070CD
+:102FF00084A03D30912000809020D5AA00002001BF
+:1030000021840022041951270500DCD10409F1377D
+:10301000292020009CD6201128858CD608112885CF
+:103020004088146F0C6108818CA1FF00C87060A1FA
+:10303000642CFF8C8801146006A7D01DB860018045
+:10304000BA60881D602A086085A000010A6000221D
+:103050002184041951270500602A0E61BE69002CE5
+:10306000C66840880860D5C00A60A07786A70100BE
+:103070000419D927D070B4D00419D927007082A0C0
+:103080000200041AD9273078BCD00419D9279B78BC
+:103090008000AA7BAA7DAA790120020006001860A0
+:1030A00000801A600800060060290461602A0C088C
+:1030B000093D901584A11800800184A11000180119
+:1030C0000C089A39481584A108003801A06984A128
+:1030D000000618110C08B838F800A06984A1001E79
+:1030E000280584A100087801C6006029006085A039
+:1030F0000020026004618DA110000661CE000C0862
+:103100009A395011A06984A1000218010C08FD38F9
+:10311000180084A10004F019A06984A100103001F6
+:1031200014698CA100FF0F810C08C5232E008CA60A
+:10313000E00084A66000280186A0600010118DA127
+:1031400000408DA10401B6699B7860000028AA7830
+:103150001868FDC01A68BCD66801FCC08370000006
+:103160008AA00D0028038AA00C00827101200C00A7
+:103170000C808671AA781835403328340080AC80E2
+:1031800080AF2B00A0209B78000080AD0B00982022
+:10319000A653A8239828A02586A220000815D07041
+:1031A000B5C0D270002CB670002DBA701468FCC087
+:1031B0000780827886A2020004092129A07000807D
+:1031C000A270B07498A40500A87006A30811A47397
+:1031D000B27386A210000409C625DE00CE000500E9
+:1031E000007005A0E01986A20200041938290C0815
+:1031F0005B3CA8191468FCC007808278912000808D
+:103200001B786800B4685A789468D678DE78986835
+:10321000D278DA789120018008788DC00A7826016A
+:10322000D600C600D07084A0002E9020CE00DE0014
+:103230002E0100295670BC683E7003700200002DFC
+:103240004A7080AD090042703078BCD040019120B6
+:103250003D30D07084A03D30912000809020A0703F
+:1032600005A0081105002184E80D4C72BC7000A275
+:1032700015A00408512786A2100060150C085B3CBD
+:103280000419CC281468FCC0078082781B78680079
+:10329000B4685A789468D678DE789868D278DA7804
+:1032A00008788DC00A78A0700080A270B07490A4D5
+:1032B0000500A87006A20811A472B2720029567007
+:1032C000BC683E7003700200002D4A7080AD09009A
+:1032D00042700500B46B9DA300205A7B1468FCC0AB
+:1032E00007808278946BD67BDE7B986ED27EDA7E06
+:1032F0001B78680000295670027208788DC00A7821
+:10330000002305A67001D07084A0002E86A00026A0
+:1033100018110920000010000920010084A20F00EC
+:10332000330080AD09004270002D4A7005009C29D1
+:1033300008420842F64108429C299C299C290C0815
+:103340007525087884A0FDFF0A78F60079200047EB
+:10335000AC78FE0084D0C001607186A10100040930
+:10336000612A86A10700700186A1050058117870B6
+:1033700068201B68040017680000206884A0FF0014
+:103380009DC0226863700000A3700000A470AE703E
+:10339000B2700C08AE26560111200400607186A19F
+:1033A0000100580186A1070018111F7005001000C8
+:1033B0001F700100D070C5C0D27001200A470420E0
+:1033C00084A0FF0086A0180030011870167005A0B8
+:1033D0001011A370010066000C084E3FA9201000D8
+:1033E000392000000C088B3AB8A70001041FEF2910
+:1033F0006E00007002002C2A0A2A0A2A022A2C2AAD
+:103400002C2A2C2A002A0C0875255C7005A038058A
+:1034100006AD181100685E708000206884D04811E5
+:10342000146F0C08953B0860D4C00A600C08C737BD
+:103430002000587060200068026084A6005F1E684B
+:103440001868FCD008011A6A176800002B68000091
+:10345000206884A0FF009DC022680C08BF1D1120B9
+:103460000400C874A0A40001B104A0AE1700990420
+:10347000A9200101C87479042084041F382AC0706F
+:10348000602021200200A92000011061FF81980125
+:10349000186016000600112002470C2202A112201B
+:1034A0000E001E0002A138031260281111200447EB
+:1034B0000422A5C012201B600000E0AC1000041F15
+:1034C000422A2184001D5E01637000000370000029
+:1034D0004B70000005004600042405A0A8016820E8
+:1034E000006806001A6A176800002B680000B468BC
+:1034F00084A0005F1E68206884A0FF009DC0226831
+:103500000C08BF1D0E00480C4E00232000000500D3
+:1035100082A2030010030C087525002302008F2AE5
+:103520000C2B1A2B82A2020010010C08752560706A
+:10353000637000007F7000002200D077C5C7D2778B
+:103540000200A62AA62AA82AE02AFB37A62AE02AF1
+:10355000A62A0C08752570770C088B3A7077BCA7E3
+:10356000008F0C08953B186005A02805FCD71811A2
+:103570002120C08D10002120D08E092005001120AF
+:1035800010000C08342BB8015601A9200101FCD70A
+:1035900018112120C08C10002120D08D4600092058
+:1035A0000500112010000C08342B4E001801208457
+:1035B000041FCB2A5E01388784A71F0090190408D6
+:1035C000C9250408C92570770C08953B186005A02B
+:1035D0002005FCD718112120C08D10002120D08E8D
+:1035E00009200500112020000C08342BB0015601E1
+:1035F000A9200101FCD718112120C08C1000212026
+:10360000D08D4600092005001120200081044E00C5
+:1036100018012084041FFE2A5E010408C925002227
+:103620000200112B132B132B0C087525637000005F
+:10363000D070C5C0D2700408C92500220200212B19
+:10364000132B1F2B0C0875250C084E3F007086A00D
+:103650000200041980370C08E137086084A0EFFBF2
+:103660000A600C087237040980370408C92504244D
+:1036700005A090056820042D0600146806A718010F
+:10368000202D0E00A80C0E0022201A6917680000D9
+:103690002B680000B46884A0005F1E68206884A0C6
+:1036A000FF0005A222680C08BF1D212002471C2430
+:1036B0001983222310600180126028112120044701
+:1036C0000424A5C02220086084A0EFF90A600C0839
+:1036D000CA260C08E137050085A00100E00C002394
+:1036E0000200732B712BEE2B0C087525E47805A0D6
+:1036F000B01708328CA1000818010401C62510007B
+:103700000403C625082084A03000101104084D329F
+:10371000EC7884A00300D00D8478FCD0181184A12B
+:103720000700900084A1070086A004001811012062
+:103730000000500084A1070086A00500180184A1A4
+:1037400007001000012001000200D12BDA2BC72B4B
+:10375000AA2B4F3C4F3CAA2BE42B0C08752500707C
+:1037600086A004009011607086A002003011112024
+:103770000200192000000408852A607086A0060057
+:10378000B00D607086A00400900DE4790120030064
+:1037900004083B2F1868FCD010011B681D000C08A2
+:1037A000613A1B786E0005001868FCD010011B6898
+:1037B0001D000C08613A04082D3C1868FCD010016B
+:1037C0001B681D000C08613A1B78FA000500186898
+:1037D000FCD010011B681D000C08613A1B78CB005F
+:1037E000050084A50F00C01100700200C925FB2B45
+:1037F000FD2B803780378037FB2BFB2B0C08752582
+:103800000C08E137086084A0EFFB0A600C087237EF
+:10381000040980370408C925E47805A0041BAC2BF3
+:1038200008328CA1000818010401AC2B100004031D
+:10383000AC2B082084A0300018111B78680005000C
+:10384000EC7884A00300C80D8478FCD0181184A102
+:103850000700900084A1070086A004001811012031
+:103860000000500084A1070086A00500180184A173
+:1038700007001000012001000200492C4D2C442CAF
+:10388000422C4F3C4F3C422C493C0C0875250C08FF
+:10389000673A1B786E0005000C08673A04082D3C57
+:1038A0000C08673A1B78FA0005000C08673A1B7889
+:1038B000CB000500002302005E2C5C2C602C0C0861
+:1038C0007525040805341B681600A3780000E47908
+:1038D00084A1300004090534EC7884A003000409B5
+:1038E000053484A10001980D8478FCD0181184A1BE
+:1038F0000700900084A1070086A004001811012091
+:103900000000500084A1070086A00500180184A1D2
+:1039100007001000012001000200922C4D2CC72B43
+:103920000B3C4F3C4F3C0B3C493C0C08173C050002
+:1039300082A2050010030C0875259878402000230A
+:103940000200A12CCB2ED52E00220200BD2CAA2CC9
+:10395000BD2CA82CAD2E0C0875259B781800A878D6
+:10396000102084A0FF0082A02000040A303A8AA020
+:103970000400041A303A0200303A303A303AE4395E
+:103980009B781800A87984A1800048010408303A87
+:10399000007005A0D81D112004000408B73584A1CB
+:1039A000FF008AA01000041A303A0200E52CE32C34
+:1039B000F72CFB2CA92D303A303AAB2D303A303A67
+:1039C000A92EA92E303A303A303AAB2E0C08752584
+:1039D000E4D6400101200003008000803A781B7883
+:1039E000C70005001868FCD018011B681D00900C6A
+:1039F00004080B3C1B681D0004085B3A206922691F
+:103A000084A6001804194C2D206884D00419542D64
+:103A1000186886A0080010111B680000D4D668053D
+:103A2000BCD6580583700000186884A03F008AA0A7
+:103A30000D0018078AA00C00827101200C000C8078
+:103A400086719B786100AA785601360146011600FE
+:103A500008328CA100061801A1202B021000A12021
+:103A60002B011E009B7800000080AC8080AD0B0015
+:103A70009820A6534E013E015E01386005A050110A
+:103A80001C6884A00E0004095B3A0C086D3A2B7880
+:103A90000830100001803A601B7871000500E4D600
+:103AA00030011B78830005001B788300050084A685
+:103AB0006000D00DDCD6C00DFCD6A001FCC65A7E3D
+:103AC000B66EDC7AD879D078078084A07F0008A110
+:103AD00091A20000986B002102A3B268946B0022AF
+:103AE00003A3AE68F4D61801F4C65A7EB66E007011
+:103AF00086A00300481106000C084E3F0C0808423F
+:103B00000E001B788000050006A00C08E842B06A91
+:103B1000AC69986C946B002205A12001002222A4BC
+:103B200000211BA3AA6CD27CDA7CA66BD67BDE7B41
+:103B3000002305A43011F5C65A7EB66E1B788000AE
+:103B400005001B788000002215A118110C080842FE
+:103B500005000C08354205000C08752504083F2EA9
+:103B6000C6005470602020698CA1FFEC22690060BF
+:103B700084A0DFCF02600C08173906A0402038204F
+:103B80000C08BF390408332EC60054706020482C3E
+:103B9000A87A94A2FF0086A20400D8112069E4D17B
+:103BA000701139200000412000003120000006A0E3
+:103BB00010200C081A390C08BF390408332E8CA1C8
+:103BC000FFEC226904618CA1DDFF06610060ACC0DE
+:103BD000026086A20300D001046184A110004805A0
+:103BE0000C08913B0C089A39FF881805CE009B7889
+:103BF00060000028AA78587E95C65A7ED4D618113F
+:103C00001B786E0005001B78820005002069CCD16E
+:103C100030018CA1FFFD22690060ECC002603920F8
+:103C20000000412000003120000006A010200C08F8
+:103C3000BF3986A201005801046184A10800B001C7
+:103C40000C08913B0C08B838FF888019780020696F
+:103C5000C4D130018CA1FFFE22690060E4C0026083
+:103C60003120000006A010200C081A39CE00587E22
+:103C7000D4D618111B78710005001B78830005004D
+:103C80000408573A08289B78800019208000A878FB
+:103C900094A0FF0086A20100B811002302A186A013
+:103CA00001000409AD2DA87CA4A4FF0080A402009B
+:103CB00000A3182002A1040AC12D0409C12DA824C3
+:103CC000A87A041F5D2E180C84A2F00082A02000A8
+:103CD000B806002282A021009816A87A18831883BB
+:103CE000002102A3A00A86A2230050091C6884A018
+:103CF000F1FF1E68587E84A6F1FFA5C030205A7ED1
+:103D00000860A5C00A60A07805A00409342EA82088
+:103D100098799B786000AA78112080009A79A87819
+:103D200098799A7AAA78987A041F8B2E95C65A7E2B
+:103D3000D4D618111B786E0005001B788200050090
+:103D40001883002102A3040A442E84A280000419CF
+:103D50005B3AA07805A0C80804085B3A0408303A2A
+:103D600054704DA09B781800A87884A0FF008EA006
+:103D7000010010010C087525A87A94A2FF004B7869
+:103D80000800A87884A0FF008AA00500041A303A31
+:103D90000200303A2F38303A4A39593D82A20000A9
+:103DA00010110C0875250C08613A1B78820005007B
+:103DB00082A2030010110C087525FCD4D01160708C
+:103DC00005A010010C087525146F7277BCA7008F31
+:103DD0000C08953B086085A021000A60388784A7FD
+:103DE0001F00B01D0C08643A637002001F700900C8
+:103DF00010000C08703A1B788200050082A20400B3
+:103E000010030C08752500230200052F9B30D730C6
+:103E100086A2030098050072D87CDC7DD07FD0712B
+:103E2000B4D12805BCD11815012001470420C4D005
+:103E3000F011687884A0FF00D01182A20200B812AD
+:103E4000D6003B7800831B785900B8706DA0B46829
+:103E50005A789468D678DE789868D278DA78B4C1DF
+:103E6000D27103703000DE000120000058003B7862
+:103E700000131B7857000120000020000072D87C3E
+:103E8000DC7DD07F4670A068ECD0180108608DC042
+:103E90000A6084A20F0002007C30562F532FA731F6
+:103EA0003232C925512F512F0C0875250860D4C016
+:103EB0000A60E4D62001447086A01400E8110C08C2
+:103EC0004E3F092000001868FCD00801447086A00D
+:103ED00014006801186886A0080004193E3058785C
+:103EE0009CD004093E302068ACD004093E301B68E9
+:103EF000140009200200A80468788CA0FF0088053F
+:103F000086A1080058110860A4C00A600C08723726
+:103F100040050C08E1370C084E3F600086A12800E0
+:103F20000015186005A0780D0180680D0180580DFE
+:103F30001E60480C206884D00409C92584C022680A
+:103F40000C08BF265870C600602000680260CE00D2
+:103F50000460026805A0002D0811026006600408D4
+:103F6000C9251600FF81F015007086A03000D0052D
+:103F7000D071BCD1B815B4D1E8115C7005A0901512
+:103F8000A07086A001007005037000004600560076
+:103F900076006600C600D6000C08F125DE00CE00D3
+:103FA0006E007E005E004E00D071B4D1D811037057
+:103FB0004000C0000C085B3CA8111B786800D600CC
+:103FC000B8706DA0B4685A789468D678DE7898682E
+:103FD000D278DA78B4C1D2710370300008788DC01D
+:103FE0000A78DE000C08FF301E00FF8104093E3015
+:103FF00084A600DF1E682B680000146F86A10200F3
+:1040000004193F30186886A0140030110820E4D647
+:10401000180168788CA0FF000C087A3A0C08CA26B0
+:104020002068DCD07815178794A20F0013821382C2
+:10403000138284B20006180190A2C04B100090A217
+:10404000404C90A200001C22C4D370012068E4D030
+:10405000280184A0FFEF2268ACC31223108204223F
+:1040600085A0380012201182D4D33801A068C4D0B2
+:1040700020110C0867310408C92508608DC00A604A
+:1040800008002A6916691868FCD0100144701A6883
+:104090008CA600DF1E691064FF84680109200247B6
+:1040A000042101800A202184126428112120044760
+:1040B0000424A5C02220186005A0180101801A6000
+:1040C00018110860A4C00A60206884D0301100680C
+:1040D00005A008110260066020005870602000688A
+:1040E00002606120004787680301082D6B200000F3
+:1040F000686005A06A611001022D08006E610072FF
+:1041000086A23000580186A240000419C925037018
+:10411000020048706820C468602005000370020037
+:10412000B8706DA0BC683E70B47065A0C068567071
+:10413000002D4A7080AD09004270050082A2040083
+:1041400010020C08752500220200A630B530C130DF
+:10415000B53086A50013600186A50083901D03700D
+:104160000000186001801A60086084A0EFFB0A60FC
+:10417000007086A0050028010C08613A1B788200B7
+:1041800005001B788300050090780780018084A0DB
+:10419000070080A018009A78A8798CA1FF0086A15A
+:1041A0000300280186A1000010010408303A1B78A2
+:1041B00083000500206895C02268FF8218110C0852
+:1041C000613A3000118210010C0875250C08703A14
+:1041D0001B78820005000C086E3C307884A0C0007B
+:1041E0007011160008328CA100081E00180104018D
+:1041F000FC3010000403FC301A7906A0050085A0ED
+:104200000100050084A6600030112F6800003368AB
+:10421000000004086631DCD69811B468DCD0801147
+:104220009869946A2E69326A447005A030110022A0
+:1042300005A104094E3F4770150004084E3F0500D4
+:10424000ACD6F001F4D630012F68000033680000CE
+:1042500004084E3FB46884A0004035A6F4D6A01DE3
+:10426000447005A0101147701500DCD62811B46801
+:10427000DCD01001A86CA46D2E6C326D04084E3F8A
+:10428000F4D630012F6800003368000004084E3F68
+:10429000B46884A0004835A6F4D6A01D447005A0DB
+:1042A000101147701500082410250027078084A0EE
+:1042B0007F0008A191A200002E69326A002105A2A8
+:1042C000101104084E3F007086A00600100104087B
+:1042D0004E3F050046690860CDC0CCD308018DC0B3
+:1042E0000A6018683A681B6806008F6800009368C7
+:1042F0000000306A2C693E6A42692F680300336807
+:10430000000037682000976800009B68200000705C
+:104310000200C925963190318E318E318E318E3129
+:104320008E310C087525206884D018110C08C73709
+:1043300030005870502C602000680260602AA0AEE7
+:104340001700042405A010012020D80C222D6B207A
+:10435000000005000C08CD370C08E1370860CCC020
+:104360000A602B6800009B780E00146F38691A6988
+:10437000446916690920000086AE404710010920F3
+:1043800001000C081F43DCD6C8011C69EDC11E6981
+:10439000286882A00E009002486884A00F0086A0C2
+:1043A0000B0060115C6886A04700401101200147A6
+:1043B0000420ACD0181100270C089E241868FCD0EB
+:1043C00040011B68000068788CA0FF0010011B688A
+:1043D0001E00A0AE1700006822203C6A4069326AC5
+:1043E0002E69C06860200060A4D0800541202100B3
+:1043F0004920050051202000D600F6005601460154
+:10440000792000470C08B21B4E015E01FE00C87007
+:10441000102009200101260004226DA0400114682B
+:1044200006A710010068C80C2068D5C022682E00BD
+:1044300010820981801DDE00637003007B70000024
+:1044400072777F700F00D071C4C1D271186886A0D6
+:1044500002003811176800002B6800001C68ECC0CF
+:104460001E680C08BF1D0408C925D87CDC7DD07FE0
+:104470000C08FF302B6800009B780E00146F0C08AE
+:10448000723C8CA0FF0016691868FCD010014470C3
+:104490001A688CA600DF1E69637000000408C92535
+:1044A000007005A010110408C92506A00C084E3F95
+:1044B0002069ACD110111B6814008CA600DF1E69A6
+:1044C0002B680000206884A0FF00226800700200B2
+:1044D000C9256F326F327232723272326D326D3282
+:1044E0000C087525186804083B2F0860A4C00A60F2
+:1044F0001768000004089537002302007E328032DE
+:10450000CE320C087525FCD604195B2D00700DA069
+:104510000200C92590329032BA329032CB328E32BC
+:104520008E320C08752584A66000380586A06000D0
+:104530001015ACC6F4C6EDC65A7EB66E1C68ACC08B
+:104540001E6886A1020048010C084E3FAC69B068A5
+:1045500015A118010C08354210000C0808421B7800
+:104560008300D071B4D10419C625A07086A00100C3
+:1045700004190D260500ECD6F0091868FCD070016E
+:10458000F4D630111B6815001B7883000408C6257B
+:104590001B6807002F680000336800000C08173CF8
+:1045A00005000C08752500230200D732F93251337B
+:1045B0000C08752500700200E132E332EA32E13284
+:1045C000E132E132E132E1320C087525AC69B068C4
+:1045D00015A118010C08354210000C0808421C688F
+:1045E000B4C01E68D070B4D00419C625A07086A0CF
+:1045F000010004190D260500FCD604194133007092
+:104600000DA00200C9250F33093339330F333E3370
+:10461000073307330C0875259468D678DE789868D8
+:10462000D278DA7884A66000380586A0600010157C
+:10463000B4A6BFBFEDC65A7EB66E86A10200480181
+:104640000C084E3FAC69B06815A118010C08354242
+:1046500010000C0808421B7883001C68B4C01E6858
+:10466000D071B4D10419C625A07086A00100041928
+:104670000D260500ECD6F0091868FCD010011B6867
+:1046800007001B78FB000500FCC65A7EDC7AD8794F
+:10469000986B002102A3B268946B002203A3AE685A
+:1046A000D2791B7883000500DCD630012B780930E5
+:1046B0001B7883000408C6258478ACC08678E4782B
+:1046C00084A00800501184A400020801F5C6DDC6CC
+:1046D0005A7E1B7883000408C625206895C022688E
+:1046E0000C08023CDDC60C08613A1B788200040805
+:1046F000C625002302007B337D337F330C087525EC
+:1047000004085B3A987DD4D6A815E479ACD1300181
+:10471000EC7884A0030010012B7809309B786000AE
+:10472000AB78000084A6FBFF5A789A7DE479ACD17F
+:104730002001EC7884A0030020110120140004085B
+:104740003B2F8478FCD0181184A10700900084A12D
+:10475000070086A00400181101200000500084A169
+:10476000070086A00500180184A1070010000120A1
+:104770000100C204907A94A207009B786000A87997
+:10478000FF8168059B788000A87B84A30100D0117D
+:10479000A87BA87B86A3040018110920DFFF58001E
+:1047A00086A3010018110920F7FF280086A3030043
+:1047B00048110920EFFFC60054706020046004A176
+:1047C0000660CE009B786000AB78000084A6FBFFFB
+:1047D0005A782B78093020698CA1FFEC22699A7DE8
+:1047E00004080B3CD12BDA2BF933FF33F733F733C3
+:1047F0000B3C0B3C0C08752520698CA1FFFC226941
+:104800000408113C20698CA1FFFC226904080B3CC0
+:10481000E47984A130002001EC7884A003007015B5
+:10482000007086A004009011607086A00200301114
+:1048300011200200192000000408852A607086A05B
+:104840000600B00D607086A00400900D007086A078
+:1048500000000409C625206984A120042801D4C1D0
+:104860002269186804083B2F18688EA002002001F6
+:10487000FDC01A680120140004083B2F8478FCD086
+:10488000181184A10700900084A1070086A00400ED
+:10489000181101200000500084A1070086A0050027
+:1048A000180184A1070010000120010002000B3C48
+:1048B0000B3C5C340B3C4F3C4F3C0B3C0B3CBCD6A4
+:1048C00070058071FF81580582A10D001813837057
+:1048D0000000280082A10C00827009200C009B7847
+:1048E0006100AA795601360146018470148110A234
+:1048F000867280A00B0000AD982084B200061801DB
+:10490000A1202B021000A1202B019B780000088120
+:10491000AC81A6534E013E015E010408113CD4D681
+:104920000419CF34206884D00409113C8CA660009F
+:1049300084A66000200186A060000811F5C194C122
+:104940005A79B6699B786000AB7800009B7861006B
+:104950001868FDC01A68AA7808800C810409F63727
+:104960008CA1F8000419F6375601360146011600ED
+:10497000A1202B0108328CA100061001A1202B02DE
+:104980001E009B7800000080AC8080AD0B0098205A
+:10499000A6534E013E015E011468FCC00780827878
+:1049A0000408113C1868FCD010011B6808000C08B2
+:1049B000613A1B78ED00050000230200E0349D35CC
+:1049C000DE340C087525D87CDC7DD07FFF8228156D
+:1049D000007286A203000409092FD071BCD1F8111E
+:1049E000B4D1E801012001470420C4D0C011D60091
+:1049F0003B7800881B785900B8706DA0B468A5C0DA
+:104A00005A789468D678DE789868D278DA78B4C123
+:104A1000D27103703000DE003000007220003B785D
+:104A200000181B78570084A20F0002008835453516
+:104A30001D35382F1B3588351B351B350C08752562
+:104A40001C68ECD0180108608DC00A60206985C11F
+:104A500022690068066005A0081102600860D4C0E1
+:104A60000A601C6884A00E002011C87188A1000192
+:104A700028003070BA683C71C87008A1042102682F
+:104A80000A2D5A71DCD62011FCC6B66E0408883592
+:104A9000B66E84A66000201184A6FF7FB668D80495
+:104AA000DCD6501184A6FF7FB6689468A668986823
+:104AB000AA680C084E3F7804ACD6400106A00C084A
+:104AC0004E3F08241025AA69A66A6800082410250C
+:104AD0000027078084A07F0008A191A20000AA6996
+:104AE000A66A0C084E3FFCD6B00184A6FF7FB668CC
+:104AF00010250824ACD638110027078084A07F0039
+:104B000008A191A20000986B002102A3B268946BE7
+:104B1000002203A3AE68007086A030000419C925E6
+:104B200003700200B8706DA0BC683E70B47065A0E0
+:104B3000C0685670002D4A7080AD090042700500B3
+:104B400086A50088481103700000186001801A6073
+:104B5000086084A0EFFB0A6004085B3A4370000021
+:104B600082A2060010030C08752500230200B73549
+:104B7000C835D23500220200BF355B3AC135BF359A
+:104B8000033651360C087525807A94A2000F0C0864
+:104B9000A5360408303AC10002005B3AD035D03562
+:104BA0000336D0355B3A0C08752571000200DC3500
+:104BB000DA35DA35DC35DA35DC350C0875250C08E4
+:104BC000703A1B7882000500007086A00200501128
+:104BD0000C08E13710000C084E3F086084A0EFFB82
+:104BE0000A602000007086A00300A80D0370050075
+:104BF0000120E08E8EAE404710010120128F682008
+:104C00004A7080AD0900427000220500007086A045
+:104C100002005811D070B5C0D270002CB670002DB3
+:104C2000BA7038000C084E3F2000007086A00300C8
+:104C3000C80D03700100807A94A2000F9B781800C1
+:104C4000A87C84A41F0015A26920C08D84B2000630
+:104C50001811FDC26920D08E042D082D5A716DA047
+:104C60002801146806A220010068B80C0C08A536BB
+:104C7000B46E5A7E206984A1000C0409CB366070A2
+:104C800086A006002811707006A2101162707A705A
+:104C90001B680500ADC11B680500ADC1D4C1226908
+:104CA0000C08673A0408CB36007286A2020058113D
+:104CB000D070B5C0D270002CB670002DBA70300024
+:104CC0000C084E3F180086A20300D00D03700100AF
+:104CD000807A94A2000F9B781800A87C84A41F00FF
+:104CE00015A286AE40470801FDC2A879A8798CA11B
+:104CF000FF001821C87068A1042D082D5A716DA0FD
+:104D00002801146806A218010068B80C0904B46EE2
+:104D1000206984A1000C0409CB36DCD078016070D6
+:104D200086A004004011707006A22811747006A3BA
+:104D3000101162707A700C086D3A80041B680500CF
+:104D4000ADC1D4C122690C08673A7B700000300401
+:104D50000370050084B2000618010120E08E1000E7
+:104D60000120128F68204A705601A92032000320CA
+:104D700000000080041FB4365E0184B200061001FA
+:104D8000FCC20800FDC2166A80AD09004270B76817
+:104D9000000723680008276803000500ECC6ACA6DE
+:104DA000600004091237986B946CAC69B06805A177
+:104DB000E011D27BDA7BD67CDE7C86A56000C8055C
+:104DC000F4D60811EDC6B4A6FFB75A7E09208300B9
+:104DD0009CD62801092082001920000020231A797E
+:104DE000ECD688050C0808427004B0681AA30021AC
+:104DF00023A4002405A3F801D27BDA7BD67CDE7CD9
+:104E0000B068F4D60811EDC6F4C65A7E11208300AE
+:104E10009CD62801112082001920000020231A7A34
+:104E2000ECD688010C0835427000192000002023C0
+:104E30001000B4A6FFB75A7E092083009CD610014B
+:104E4000092082001A79C0685670002D4A70C46823
+:104E50006020D071012001470420C4D0C815D4704F
+:104E60002DA0B801BCD14805807A94A2000FD8705B
+:104E700006A21801E07804A55815D670BCC1D271FD
+:104E80003804312001002C85180233861082D80C9A
+:104E90000500E07D94A500FF3001112008002F855A
+:104EA000810C37860800690C1782807884A0000F77
+:104EB00006A27001DA72D6765800807A94A2000FAA
+:104EC000D87036A2C00DE07834A5A80DBDC1D2714E
+:104ED000B4D10419C625002305A40409C625A07071
+:104EE00086A0010004190D260500206005A05001D0
+:104EF00001802260086085A008000A600F70000130
+:104F00002C702660050006A00C084E3F007086A09D
+:104F100002002001607086A0050050112B6800007F
+:104F2000176800001B680100236840001F6800012B
+:104F3000007084A00F000200C925A637A337C3372D
+:104F4000AF37C925A137A1370C08752549041104CD
+:104F50002800310458706020006802600C08BF1DF2
+:104F60000408C9256070637000007F7000000200B3
+:104F7000BF37BF37BD37BD37BD37BF37BD37BF3789
+:104F800004089A2A637000000408C9251B68000001
+:104F90000408A731006805A008110260066005003A
+:104FA0001064FF84680109200247042101800A205F
+:104FB000218412642811212004470424A5C0222042
+:104FC0000860A4C00A600500186005A010010180F7
+:104FD0001A6005000C086E3C1B68180090040C0851
+:104FE0006E3C1B68190068040C086E3C1B681A00B4
+:104FF00040040C086E3C1B680300180470770C0812
+:10500000953B74718CA1FF00103294A20006180128
+:10501000E8A1C08C1000E8A1D08D042D082D6820D7
+:1050200005A018117A700408C9251468707206A2C8
+:1050300010010068980C00680A201B6805007B704E
+:1050400000000C08CD37206884D010110C08C73739
+:105050000C08E1371F680000236820000C08BF1D02
+:105060000408C92582A203000419353AA87DACA51D
+:10507000FF00A87EB4A6FF002069BDC12269C4D18B
+:10508000B005C4C12269B4A6FF00300582A618008D
+:10509000180210013120180086A610000811308671
+:1050A0002B852B85412000000C08EE3A18010C08D6
+:1050B0001A39A0000C08BA3A0C0817392069C5C182
+:1050C0002269587E95C65A7ED4D618111B786E0078
+:1050D00005001B78820005000C081739587ED4D6CD
+:1050E00018111B78710005001B7883000500C600AD
+:1050F000547060200061E4D198050862178294A280
+:10510000FF0082A2180018021001112018000026CA
+:1051100002A20812302286A610000811308608620A
+:1051200094A2FF00EC78E4D0300182A20A00401281
+:1051300011200A00280082A20C00101211200C007D
+:10514000002202A5081228220C08BE3A2B852B85C6
+:10515000412000000C08EE3A18010C081A39200012
+:105160000C08BA3A0C081739587895C05A78CE000E
+:105170001B7882000500C60060290060E4D0881119
+:10518000B4D05011106084A00F00301104618CA1C4
+:10519000F5FF0661CE000500112032001920000045
+:1051A000F000A068CCD0C01D086294A2FF00EC788B
+:1051B000E4D0300182A20B00181211200A0028004E
+:1051C00082A20C00101211200C0008631F839CA304
+:1051D000FF0082A318001802100119201800AB78F4
+:1051E0000100AB780300AB780100AA7AAA7BC0A8C3
+:1051F00005002068C5C022680C087A3ACE00050078
+:10520000C600602904618CA1F5FF066111203200FF
+:10521000192000000000AB780100AB780300AB78E8
+:105220000100AA7AAA7BC0A805002068C5C0226830
+:10523000CE00050006A030201020C6005471602169
+:105240001820082084A0E0FF35A6867E18609A7892
+:10525000AE7E1266A47884A070778CA10F0005A1A1
+:10526000292005472C25CCD54001A4D3100185A0C9
+:105270000008FCD3100185A08080A67816608A788B
+:10528000B4A61F0037860482048005A60E60046061
+:1052900084A0D5FF0660CE00050082A2020004199A
+:1052A0003F3AA87A2069BDC12269CCD16805CCC13A
+:1052B000226994A2FF0082A20200041A303A0C086C
+:1052C000C1390C08173980A901000C200C08913B4A
+:1052D0000C08B838FF8878019B7860000028AA780D
+:1052E000587E95C65A7ED4D618111B786E000500DC
+:1052F0001B7882000500587ED4D618111B787100E7
+:1053000005001B788300050082A20200181284A207
+:1053100001004001547188A100000C21ECD1101152
+:10532000112000000C08AC3A79040C0817395878A1
+:1053300095C05A781B7882000500C60026006029B7
+:10534000006011200100ECD05811BCD0381114605D
+:10535000B4D02011A4C1066106A08800112000006D
+:10536000AB780100AB780200AB780300AA7AC0A842
+:1053700004000C087A3A206885A0000222682E00FA
+:10538000CE000500078815A7C6000920000054704C
+:105390006020FF82100109204000186080A00200F8
+:1053A0009A78A47884A09FFF05A1ECC0B4D008111E
+:1053B000EDC00061F4D1100185A02000A678166030
+:1053C0008A78046084A0EFFF0660CE000500060026
+:1053D000007086A0030010010E0010000E0098045B
+:1053E000ACD68805887884A040006805B87B078320
+:1053F00084A07F001815078284A0FF000409573A93
+:105400009AA00400041A573AF4D6D011D879DC7A5D
+:1054100008A191A20000D279DA79D67ADE7A0C0856
+:10542000E8421B78800084B20006180101200000C9
+:105430001000012001000C089A4105000C08752598
+:105440001B78800005001B788300050039200000D0
+:10545000412000003120000006A010200C081A395D
+:105460000C08BF39587E0C08733A1B78820005007F
+:10547000D10C2068C4C02268C600547060200C089B
+:105480004439B000810C2068CCC02268C60054703A
+:1054900060200C08DE396000310C206884A0FFEC2D
+:1054A0002268C60054706020046084A0C5FF0660B6
+:1054B000CE00050049001B78820005002768020025
+:1054C00049001B78820005000120050088000120AA
+:1054D0000C0070002068D5C0226801200600400042
+:1054E00001200D0028000120090010000120070004
+:1054F0009B787E00AA789DC65A7ED070B4D0680191
+:10550000B4C0D270C600B47065A0086084A0EFFB80
+:105510000A60186001801A60CE00050076003F879F
+:10552000BCA70F003B873B870387E0A0C04B8EAE34
+:1055300040471001E0A0404CB8A720009A7FA47912
+:1055400084A1E07FAE781260A47984A13F77A67829
+:105550001660046085A0380006607E0005009B7818
+:105560008000AB780100AB780200AB780300AA7A28
+:105570009B786000AB7804000008312000002920EF
+:1055800032009B788000AB780100AB780300AB78E9
+:105590000100AA7DAA7E9B786000AB780500040814
+:1055A0007A3A5601078084A0FF000380038080A020
+:1055B00020009A78A4798CA1E0FF21207A3B192061
+:1055C0001100A9200E0011203200042484A0E0FF65
+:1055D00006A128012084002310A2041FE23A5E01E4
+:1055E000050056010408303B2120883BA920090012
+:1055F0001120290082A5280050052084A99511209A
+:10560000330082A5330018062084A99519200A00CA
+:1056100011206500002202A5D0022084002310A2E0
+:10562000041F073B5E01880021207A3B19201100EE
+:10563000A9200E0011203300002202A54002208480
+:10564000002310A2041F193B5E0106A00500118271
+:105650005E0182A564002012087885A070000A7897
+:10566000042405A0050086A80200E8012120663B6D
+:10567000A9200D001120280082A52800480D2084B3
+:105680001920190011203300002202A5000E2084E9
+:10569000002310A2041F413B5E011120840182A55A
+:1056A0008501B00A90082120753BA9200300112034
+:1056B000240086A52400600920841120280086A5E6
+:1056C0002800300920841920190011203300040813
+:1056D000193B21100222033404460558066A077C50
+:1056E000104612461258125A146A146C146E177E21
+:1056F000219002B004E210E210E2091202300232FC
+:105700000342034404540456056605680678067A85
+:10571000070C070C070EE1100A330558055A066AF4
+:10572000066C077C077E000E9B78800046A0050073
+:1057300084A7000F0B8084A71F00038003800380D1
+:10574000038005A1FCD71801E0A0C06C1000E0A008
+:10575000C04C0500E600F60084D038017920000135
+:105760000920804771208047300009204047792078
+:1057700000027120404791200080042184A00F0086
+:105780000200C83BC83BC83BC83BC83BC83BC63B04
+:10579000C63B0C087525B469F5C18CA19FFFB6699D
+:1057A00005A08005587884A09FFF85A000605A78E6
+:1057B000287886A0141830154B780400487884A007
+:1057C0000400E01D4B780800487884A00800E01D24
+:1057D0003078BCD0B81184B2000818010401FF3B36
+:1057E00010000403FF3BE47984A130005801EC78F9
+:1057F00084A0030038011C68ACD01011D90010003F
+:105800001B78FB00FE00EE0005000120014704208C
+:10581000ACD0181114680C089E2405001B78830076
+:1058200005001B78820005001B78710005001B78BD
+:105830006E000500092019470C2186A100005001C7
+:1058400086A1010050011F700B00637001001B78DE
+:10585000540005001B78F30005001F700A000500C6
+:10586000092019470C2186A10000680186A10100CA
+:1058700038011F700B00637001001B785400050095
+:105880001F700A0005001B78F20005001B78FB0062
+:1058900005001B78FA0005001B78CC0005001B787A
+:1058A000CB0005001868FCD010011B681D001F709C
+:1058B0000B00637001001B7854000500307884A051
+:1058C000C000701108788CC00A7800E000E000E0A9
+:1058D00000E0EC7884A02100180108788DC00A78D7
+:1058E000050008788DC00A780500307884A0400053
+:1058F000E01D84B2000818010411803C100004135C
+:10590000803CAC780500087884A0FDFF0A7800E0B0
+:1059100000E000E000E0EC7884A02100400184B2C7
+:105920000008180104118F3C10000413923CAC785D
+:105930000600087885A002000A780E00050084A7FA
+:10594000010004194D3284A770004001C600602D8B
+:10595000682F0C089024782D682CCE0084A70800AE
+:1059600048014B780800EC7884A0030004094D320C
+:1059700004080B3C84A70400C801B87884A0008008
+:10598000A8014B780800EC7884A0030004094D328C
+:10599000E47884A0070086A001004011C07885A6A5
+:1059A000004830205A7E1B78FB00050084A7800049
+:1059B00040018478FCD028010C08573A1B6822006B
+:1059C00005001B680300587884A0005F1E682F68DC
+:1059D0000000336800004B780800EC7884A00300D6
+:1059E0000409AC2B84B2000810010401C62504038D
+:1059F000C625146B078384A00F00038003800380F7
+:105A0000FCD3180180A0404C100080A0C04B602047
+:105A100048205670602A0500C60060290060ACD09E
+:105A20000409573DA068ACD1201184A0000E0409E0
+:105A3000553D086117818CA1FF001C632F83DCD0CA
+:105A400010019DA30100CCD0C81184A5FF0038012E
+:105A5000EC78E4D010011382B8002920000082A164
+:105A60000C009012EC78E4D0181109200C006000B2
+:105A700082A10B00481209200A00300009203200E0
+:105A80001120000029200000AB780100AB7806004F
+:105A9000AB780400AA79AB780000AA7AAA7BAA7D29
+:105AA000C0A80800206885A0001022680C087A3A77
+:105AB00085A00100CE00050082A206000419493A23
+:105AC000A87DAC7E3786ACA5FF00B4A6FF00AC7FF6
+:105AD0004787BCA7FF00C4A8FF002069BDC1226999
+:105AE000E4D10409CB3D8CA1FFEC226982A702001E
+:105AF000041A233AB4A6FF000409C83D82A6310067
+:105B0000041A233A82A50900040A233A82A8030052
+:105B1000041A233A86A80200D00186A800000419BE
+:105B2000233A01200C00EC79E4D1100101200A0095
+:105B300002A590120C08233AC6006029046085A0D3
+:105B40001A0006600060ACC00260CE00050086A7A7
+:105B500000000409233A348682A618002802200196
+:105B6000312018000408193E86A61000081130865E
+:105B70002B852B850C08EE3A0409233A0C081A39B8
+:105B80000C08BF39587ED4D618111B787100050057
+:105B90001B78830005000C081739900C86A80200BA
+:105BA00008113486547188A100000C21ACD104097D
+:105BB000233AECD120113920000041200000E4D12B
+:105BC0002011312000004120000082A70200C812ED
+:105BD0001C6284A2FF0006A710013920000005A660
+:105BE000900108611F819CA3FF00680102A30812B5
+:105BF0003023078805A786A00102600186A800005F
+:105C0000680139200000412000003120000006A07A
+:105C10001020700084A200FF0811402084A1FF0022
+:105C200002A5080128212B852B850C08EE3A580D7A
+:105C30000C081A390C08BF399B788000AB7801003A
+:105C4000AB780600AB780400AA7DAB780000AA7E92
+:105C5000AA7F0028AA789B786000AB7808002068AB
+:105C6000E5C022680C087A3A587895C05A781B78B3
+:105C7000820005002000200000002000000020001D
+:105C80000000200000002000000020000000200094
+:105C90000000200000002000000020000000200084
+:105CA0000000200000002000000020000000200074
+:105CB0000000200000002000620009001400140011
+:105CC00055984D9814001199FF98140014009000F5
+:105CD000E70000010204082080F8180017000F8474
+:105CE000C1D8140016000AA214000B300CA2140034
+:105CF00000251300002510001000100010001000F7
+:105D00001000100010001000100010001000100013
+:105D1000100000A206383988C420640850A8083052
+:105D2000C128189D01A20C30472861816A84008037
+:105D3000A48456183A8808A8E228CE9CF3A86408E0
+:105D40003EA80C3001A80830E128CE9CA22863713F
+:105D500031A8212018A805A20C87DED8A064E06D28
+:105D6000C06FA467806C120205A23D882B881418AE
+:105D70003B882770F28537A732A503F076857786B2
+:105D800013A83E8811A88228627114A80A2804A2C8
+:105D9000C064E06DA067C06F14183B8823707685DF
+:105DA000778602A861783E886A20C128189D422023
+:105DB0000121CAA802290EA20BA807A2140003A25F
+:105DC0000080A48572189A873C88E21F01F608A219
+:105DD0006E852171140004070830CE9C140002A2C5
+:105DE0000080A4850930A884E21944F86E853F88B4
+:105DF000E608F5A861F8EBA801F8140081F8160090
+:105E0000B285F0803295A2FAE21D1400328521F2AB
+:105E10001400E21DA884E0D6E61F140008300080BC
+:105E200049281110FCA80830008000A08120022819
+:105E30001110FCA889A80830A1203C281110FCA84A
+:105E400009A217000C300080A485E21DC1DA1400FD
+:105E5000100201A81400E0263A87A3FAF219E026FE
+:105E6000F21814000BA214000DA206381002229D95
+:105E7000040706A265687E812A84C11D2388160056
+:105E800042600880FAA860812A84808121F008306D
+:105E9000A884D7114270DD201100D5202288160079
+:105EA00000002601D07084A0004C04809020047271
+:105EB00008709CC005A2A0110C72FF822801FF8A05
+:105EC0007811007284D260110478CCD010010C08D3
+:105ED0005B4307700800037008002E0100200500D6
+:105EE000007084A0030002709CC684D088050871ED
+:105EF00000E0087006A1D81D84A103000409CA3F70
+:105F000084A1E0010419CA3FF4D1881D84A10030A6
+:105F100086A00010600D112080010C7111823001EB
+:105F20000870F4D0201D0C7006A1C00D077012007F
+:105F3000087100E0087006A1D81D84A1030068055F
+:105F400094D1B00DF4D148050770020080082804F0
+:105F50000871FCD130010C08D640FF8A0409543F77
+:105F6000B80C0C708CA0FF07E801047084D0780195
+:105F7000147005A048111070107306A3E01D0023D3
+:105F800005A0280102A1201E077010003000FF8A22
+:105F900048010C089A42E81DD8090C085C402E0103
+:105FA00000200500047208719CC10381181207705B
+:105FB0000200C00C05A2881D0770080003700800CD
+:105FC0000600012001470420CCD010010C085B43DF
+:105FD0000E002E01002005002864FF840805702CA7
+:105FE0000470BCA00F00B8A71D403C27FB874811D8
+:105FF00010020C0875259C6075A09001880C392052
+:106000001240042768AE086830A60C6829A52184D0
+:1060100038013887042705A0A81D9C7075A0001DB5
+:1060200005000000050009000D0011001500190011
+:106030001D000000030009000F0015001B000000F8
+:10604000000012400F4000000000008000001240DD
+:1060500000001A40174000000000000000001A4035
+:1060600000001540154000000000008000001540B1
+:1060700000001B401B4000000000000000001B400F
+:10608000792000477120100007700A000770020095
+:1060900003700100092002007120500007700A00FF
+:1060A00007700200037000000120FF010420FCD0F3
+:1060B00028110981180171202000800C050004704E
+:1060C0000480041AB2400871087006A1E01D84A182
+:1060D000E00120010C080E410408D24007701200B4
+:1060E000192000000871087006A1E01D84A1E001DC
+:1060F00020010C080E410408D2409CA10C3086A35C
+:106100000420900186A30800C001047084D04811C7
+:106110000871087006A1E01D84A1030010010408A5
+:106120000E4186A30C20F0190072048230020C7319
+:1061300084A3FF0710010C0875250871087006A1DB
+:10614000E01D84A1E00118010C080E4170040770E5
+:106150001200007084D048111073147005A3280138
+:106160000C7184A1FF0704195C400871087006A136
+:10617000E01D84A1E00118010C080E41B000077079
+:1061800012000770080004709CD0E81D08710870A8
+:1061900006A1E01D84A1E00118010C080E412800B1
+:1061A0000770120008710381880E03700800050053
+:1061B000087184A1E001A815087184A1E001881587
+:1061C00084A107000200EA40F840E840F840E840B7
+:1061D0004841E84046410C087525047084A0100031
+:1061E0008DC00670FF8A18114920000005000C08B8
+:1061F0009A42E81D0500047084A010008DC006704E
+:10620000047084D040110871087006A1E01D84A1BB
+:10621000030008013000FF8A18010C089A42E81DAB
+:106220000500077012000871041D114191200060E3
+:10623000041D1541912000600770120007700800CE
+:1062400004709CD0E81D077012000871FCD1D81DA5
+:1062500003700000007005A03011047005A0181133
+:106260000C7005A00801400C4920000084B2000217
+:106270001801012000001000012001000C08A73BBC
+:106280001B6802005120000005000C0875250C0851
+:1062900075250C088741107214710C709CA0FF07C3
+:1062A000002800A311A289A10000A1040427582CF2
+:1062B00060AC0863002222A30C6300211BA300240E
+:1062C00005A340013812128410820A8389A10000BC
+:1062D000602B580C602B078A060004609CD01801C4
+:1062E000BAA717401000BAA70F400E003DA7002C18
+:1062F00086688A6F926C8E6B0871087006A1E01D2B
+:1063000084A1E00110010C080E41077012000C0876
+:106310005C400500508A3987042704A0681100609A
+:1063200064A00811602D046084A00F0080A02D409F
+:106330003C20FB870C09752505002601D600D0708E
+:1063400084A0004C04809020DE008468602088686F
+:106350008C6B906C5780D4AAFF0084A0FF000600CD
+:10636000046884A008000E001801B8A017401000AF
+:10637000B8A00F4084B200021001207E0800247EE5
+:10638000B5A60C001C68B4D0080185C6002405A37E
+:106390005005582C0427046160AC006000A448201C
+:1063A000CCA9040018010C08A34300041A7004606F
+:1063B00001A31E709CD14001106081A000002270DA
+:1063C000146081A0000026700862002402A21270EE
+:1063D0000C62002303A21670027607700100602B86
+:1063E0000C08C54210000C089A42E81D2E0100203E
+:1063F00005002601D600D07084A0004C04809020B7
+:10640000DE0007700400047094D0E81D03700800DB
+:106410002E01002005002601D600D07084A0004C7B
+:1064200004809020DE00207E84B200020811247EC9
+:10643000B5A60C001C68ACD0181185C6037000000E
+:1064400028685020602D0460BCA00F00B8A71D4034
+:106450003C27FB87381110020C0875259C6865A045
+:106460002001880C0C089A42E81D2E01002005002E
+:10647000260106001600D600D07084A0004C0480CF
+:106480009020207E84B200020811247EDE003E00AF
+:106490004E00B5A60C001C68B4D0280185C6037058
+:1064A00000000770040049203542286855A0D60036
+:1064B00004099642702D602E0470BCA00F00B8A78E
+:1064C0001D403C27FB87401110020C0875259C706D
+:1064D00075A060207005800C042768AE086822A4AF
+:1064E0000C681BA36802518A10110C0875253887A7
+:1064F000042705A0901D9C7075A06020D001E008C5
+:10650000228420841A8399A300000869002422A110
+:106510000C6900231BA110120C08752584B200021F
+:10652000180171205000100071202000DE000408C6
+:10653000C341DE002E01002005000870060084A083
+:10654000E0010E00100106A0050084A0030086A053
+:10655000030008110500042778AC0078082F94D0B8
+:106560000419A6431A7004781E70087812700C780B
+:10657000167004609CD02001107822701478267068
+:106580000276047084A0100085C006707920004750
+:10659000518AE8013887042705A068119C6005A08E
+:1065A000B8016020046084A00F0080A01D403C2042
+:1065B000FB870C0975250870060084A0E0010E0019
+:1065C000100106A0280084A0030086A00300050097
+:1065D00051200000050026010600D600D07084A0DE
+:1065E000004C04809020DE008E00087184A103001E
+:1065F0002811286805A0780104086D3F0871FCD1B6
+:1066000018010C08D640880C077010000871FCD1E6
+:10661000E80D0C08D640087086A00800301D0070F8
+:1066200005A0181D0370000049200000060001208D
+:1066300001470420CCD010010C085B430E002E0152
+:10664000002005002601460136015601C600D6008D
+:10665000D07084A0004C04809020DE0049201F43AD
+:1066600080AD1100A02084B20002180199203200F0
+:106670001000992031000C7084A0FF072A68077071
+:106680000800077002000370010018010080AC8050
+:10669000A5530C7084A0FF0730010770040004703C
+:1066A00084A00400E01DCE0049200000037000001B
+:1066B0005E013E014E012E01002005001468FCD051
+:1066C00004099E43007084D0E005247EB5A6040032
+:1066D00007700400047084A00400E01D1871160007
+:1066E0001C71160020711600247116001B7000002A
+:1066F0001F70FF3F2370000027700000137004001C
+:10670000177000000276077001000120FFFF0920CA
+:1067100031000A200A200871087006A1E01DFCD192
+:10672000D00D2E0026722E0022722E001E722E0018
+:106730001A7207700200087086A008001001040891
+:106740000E41077004000370000005004920C3419A
+:106750006800087084A00300100106A0050006A0D0
+:1067600020201820582C602149200000588B0061FF
+:10677000002108A41A71046001A31E700600042BF6
+:1067800084A008005001106081A000002270060063
+:10679000146081A000002670060084A1070011206B
+:1067A00008002AA20862002412A226000C624022DD
+:1067B000002343A82E00FF887011002502A20801C3
+:1067C0005012202241200000042B9CD010010E000A
+:1067D0000E000E005004127517700000027686A994
+:1067E000C3411811077001002800047084A0100034
+:1067F00085C00670002500A11A70042B84A0080033
+:1068000010010E004E001E0089A100001E710C2B0D
+:106810008CA108003001A1A40000227481A0000016
+:106820002670002522A2C3A8000012742028167426
+:10683000027686A9C3411811077001002800047070
+:1068400084A0100085C00670598B602B792000470A
+:106850000C08C54206A00500912000809120006030
+:10686000AC7805A068117479D07006A148111C7825
+:1068700005A030011F780000040E3D4491208040A7
+:1068800069208047FDC7006884A00F009811D06878
+:10689000B4D08001BCD07011F60079200001FCD783
+:1068A000101179200002307884A0C00010110C086B
+:1068B000D522FE00FCD7200169204047FCC7180CF8
+:1068C0003078018032780419C744347832786120F6
+:1068D000C06C69208047FDC7CC6805A028010180F5
+:1068E000CE6810110C083946006884A00F006801BA
+:1068F00086A00100500140680DA03801042105A0C8
+:10690000200101800A200409D645146805A0A801C9
+:10691000018016689011A3680100F600FCD71811D9
+:10692000792000021000792000010C086E3CFE0066
+:10693000606805A010010C08D5227C6805A0400104
+:1069400001807E68281163680000D068C5C0D268E5
+:10695000D068FCD0B001FCC0D268A920000234602D
+:1069600005A0580101803660D068FDC0D2682811AA
+:10697000106005A010010C08D522E0AC1000041F27
+:10698000AC44FCD738016120C04C69204047FCC7AB
+:10699000040869445904387801803A78A0113C7899
+:1069A0003A786120C04C69204047FCC70C6805A0BC
+:1069B00010010C084345FCD730116120C06C6920E0
+:1069C0008047FDC7980C1078CCD06801ACD020115E
+:1069D000A4D04801ADC0127891200180040EEF448C
+:1069E0000C08A1200500912001800500407801805D
+:1069F0004278041942454478427869204047FCC7F0
+:106A000079200002D46805A03801E07D04A520119A
+:106A1000D668D068BCC0D26879200047106805A04D
+:106A200010110120010101801268FCD7180180A01B
+:106A3000D08D100080A0C08C4020042065A0E00113
+:106A4000246005A0B001018026609811006805A0AF
+:106A50003001486806AC18110C08D645680060681B
+:106A600005A018012760010020000C0884450428B7
+:106A7000280C0060402C100CFCD73811692080478E
+:106A8000FDC7792000010408FF440500092000002B
+:106A9000A920000208609CD05805246005A01801B8
+:106AA00001802660180408609CC084D01011ACD00E
+:106AB000C0010A60046005A0D801D600C600160017
+:106AC00068201060018012600C08C737002D682C08
+:106AD00060200C08021C0C08B21D1E00CE00DE0057
+:106AE0003800BDC00A608DA1010010008DA1000119
+:106AF000E0AC1000041F474584A1010030018CA1C7
+:106B0000FEFF0E690C08D52208000E690500002C56
+:106B10007A681467726F176000002B6000001B60BA
+:106B20000600B46084A0005F1E60206084A0FF00A7
+:106B300085A0600022600060422069208047FCD769
+:106B4000101169204047586806AC101100285A6897
+:106B50000C089A1B186805A0100101801A680868C3
+:106B6000A4C00A681068087909810A7901801013A5
+:106B70000C087525126818111079A5C112792F60BB
+:106B8000000033600000682C0C08BF1DFCD71811F2
+:106B900069204047100069208047106984A10001E6
+:106BA0000120060018117669012004000C08CB2290
+:106BB0000500D60048696021FCD718116920000241
+:106BC0001000692000010C0890241B600600586822
+:106BD00084A0005F1E60206084A0FF0085A04800A4
+:106BE00022602F60000033600000086884A0FDFF71
+:106BF0000A683068B4D0B0014B680400A9201400C2
+:106C0000486894D01001041FFD454B680900A92075
+:106C10001400486884D01001041F0646A920FA0019
+:106C2000041F0D461B685400DE0063680700050062
+:106C300079200047E1008900A900092002006920AD
+:106C400080470F6800001368000017680000098182
+:106C5000180169204047A80C05001920A3003A7BC1
+:106C60003E7B050019203300427B467B050019203E
+:106C7000DD32327B367B05004C6A85A20000F001D4
+:106C80005069BC6B00A3C60064210463FF83381104
+:106C90001182480108811AA1B80EBC69A80CCF68FE
+:106CA0000A00CE0005004C69BC6A64220860B5C0C9
+:106CB0000A6010820981C81D4E69CE0005001600C9
+:106CC000041D5D4691200060041D61469120006016
+:106CD000EC70DCD01811D4D09001A0008EAE000171
+:106CE00038011478F5C0C5C01678D4D0801560047A
+:106CF0001478FDC0C5C01678D4D048152804E4D057
+:106D00000409C446041D7F469120006009200C0040
+:106D1000041D8546912000600981D01DE47084A087
+:106D2000FF0186A0FF011011EC70C0088EAE0001BB
+:106D300028011478F4C0FCD0301120001478FCC075
+:106D4000F4D00811C4C0167804788CD00005C600B1
+:106D500061200000186084D0B81186AE0002E60001
+:106D6000712010002001DB700100E4781800DB7056
+:106D70000000E078C670C3700E801B600100912097
+:106D80008040EE00CE001800CE001F680C001E00F0
+:086D9000A070A2700500260CA2
+:00000001FF
+/*****************************************************************************
+ * QLOGIC LINUX SOFTWARE
+ *
+ * QLogic ISP12160 device driver for Linux 2.2.x and 2.4.x
+ * Copyright (C) 2002 Qlogic Corporation (www.qlogic.com)
+ *
+ *****************************************************************************/
+
+/************************************************************************
+ * --- ISP12160A Initiator Firmware --- *
+ * 32 LUN Support *
+ ************************************************************************/
+
+/*
+ * Firmware Version 10.04.42 (15:44 Apr 18, 2003)
+ */
diff --git a/firmware/qlogic/1280.bin.ihex b/firmware/qlogic/1280.bin.ihex
new file mode 100644
index 00000000000..612c2633f8c
--- /dev/null
+++ b/firmware/qlogic/1280.bin.ihex
@@ -0,0 +1,2008 @@
+:10000000080F0B0000107800411000002E3E000089
+:100010004320504F525947495448312039392C31E7
+:1000200039313239312C39392C3339313439512085
+:100030004F4C494720434F435052524F54414F4930
+:10004000004E492050533231303446207269776D6A
+:10005000726120655620726569736E6F30202E388C
+:1000600035312020432073756F74656D20726F4E9B
+:10007000202E303050206F72756474634E202E6FC6
+:100080002020303020200024C920FF980120FC04CB
+:10009000042086A08010C000541071200001A070C0
+:1000A000A270C12010008920741378006D10012007
+:1000B000FC04042086A08012C00069107120000298
+:1000C000A070A27071200001A070A270C120100069
+:1000D0008920F81378006D10C120200089201C139E
+:1000E00071201000C3700400C7705349CB702050BA
+:1000F000CF702020D37008000120FE04D670C120EC
+:100100002100192000000920FFFE00210B20A5A5D9
+:10011000ECA1FF7F642D6B200A0ADCADFF3F542B5E
+:100120005B205050142186A2A5A54000A41086A3F0
+:100130000F004000A0106A2C5A2AC120200019206C
+:100140000F00780080106A2C5A2A7800A2106A2CBE
+:100150005A2A30212821A2A1004F248424842484F7
+:1001600024842484248492A1009909200000012081
+:1001700032007810C12018227920004FA02F0824C7
+:1001800011200000A9204000A4420981C000BF1036
+:10019000092000FF003402A14800CF104000CF101A
+:1001A000A820A4420120FC04042086A08010C000E6
+:1001B000E510712000017E0D6920404F7810B04D90
+:1001C0007F0D1078EDC012781B78640078000A115A
+:1001D0000120FC04042086A08012C00005111478C0
+:1001E000EDC0D5C016781B786400712000027E0D2A
+:1001F0006920404F7810B04D6920804F7120000178
+:100200007810B04D1478D4C016787F0D78000A119C
+:100210001478E5C016781B783C00CA7EC27CC67B89
+:100220006778000000788DC0027831203000AF7808
+:1002300001012378020027780200092002006920CA
+:10024000404F1B680300236807002768FA002B68EB
+:1002500008002F682800376800003B6806003368F4
+:1002600008003F680000098140005E11D3680A0061
+:10027000C368C04F7920004F1478E4D0C000441107
+:10028000ECD0C0004811D768297378004A11D768AC
+:100290000D7378004A11D7682D73C768C054CB68B6
+:1002A000C053CF68C094AB684497AF684997B368B0
+:1002B0004497B7684497A76801006920804F780089
+:1002C0001E11D3680A00C368C0511478E4D0C0007E
+:1002D0006A11D768397478006C11D7681974C768C7
+:1002E000C074CB684054CF68D095AB684997AF686D
+:1002F0004E97B3684997B7684997A7680100107887
+:10030000ECD0C000C2111478E4D0C000B4117E0E4D
+:100310006920C05371200002EC70E4D0C000951138
+:1003200019200C0C21200C007810502078009B1113
+:1003300019200A0C21200A0078105020692040540E
+:1003400071200001EC70E4D0C000AB1119200C0C3E
+:1003500021200C00781050207800B11119200A0CCF
+:1003600021200A00781050207F0E7800DB11192020
+:100370000C0C21200C006920C053781050206920FB
+:100380004054781050207800DB116920C0537E0E55
+:1003900071200001EC70E4D0C000D41119200C0CC5
+:1003A00021200C00781050207F0E7800DB111920DE
+:1003B0000A0C21200A00781050207F0E1120020024
+:1003C0006920C05409200200A920000137680000FC
+:1003D0000B684000C87B86A3FFFEC000F2111768BF
+:1003E00000011F6864007800F611176864001F6838
+:1003F0000200E8AD1000F000E3110981C000E11136
+:100400001182400004126920C0747800DF11781056
+:10041000A2267810124778101B1E7810424D9120AA
+:1004200000217920004F1078ECD040001812712084
+:10043000200078001A1271205000912000227920AB
+:10044000004F71202000912000237920004F107868
+:10045000ECD040002C127920000178002E12792077
+:1004600000027120404F912000247920000171206A
+:10047000804F912000207920004F71201000003221
+:1004800085A03D30902071201000C37000009000C6
+:100490004D12C07086A00200C0004D127810C11528
+:1004A000392000001078ECD0C000CF1278108E14E4
+:1004B000AC7805A0C0006B12680061126C7865A072
+:1004C000400061127810DC237810E8206800781270
+:1004D0006C7865A040006B127810DC2368007812FD
+:1004E0000920474F1120874F04210C2205A140000D
+:1004F00078127810511F7120404FA47005A0400061
+:100500009D12507485A4000040009D1279200002C5
+:1005100091200080D4728CA23D3090217810B12BB4
+:100520009120008091203D3068009D127920004F7D
+:100530006C7865A040009D12712010007810DC23BB
+:10054000E000A5127920004F712010007810164BA2
+:100550007120804FA47005A04000BD12507025A0EE
+:100560004000BD127920000191200080D4728CA23D
+:100570003D3090217810B12B9120008091203D30AA
+:100580007920004F712010006800C9126C7865A0B6
+:100590004000C9127810DC23E00053127810164B8B
+:1005A0007800531278108E14AC7805A0C000E712C2
+:1005B0006800DD126C7865A04000DD127810DC2345
+:1005C0007810E8206800F1126C7865A04000E7120E
+:1005D0007810DC236800F1120920474F042105A0A0
+:1005E0004000F1127810511F7120404FA47005A0F7
+:1005F00040000C13507485A4000040000C137920B7
+:10060000000191200080D4728CA23D30902178109E
+:10061000B12B9120008091203D307920004F712036
+:100620001000680016136C7865A04000161378104F
+:10063000DC23E000CF127810164B7800CF123C1369
+:100640003C133E133E134B134B134B134B135613D8
+:100650005613631363134B134B134B134B133C137E
+:100660003C133E133E134B134B134B134B135613B8
+:100670005613631363134B134B134B134B13780035
+:100680003C137E007E107E12912000247810D12928
+:100690007F127F107F00912001807C007E007E1001
+:1006A0007E127810C8137F127F107F009120018086
+:1006B0007C007E007E107E12912000237810D129CC
+:1006C0007F127F107F00912001807C007E007E10D1
+:1006D0007E12912000237810D129912000247810D7
+:1006E000D1297F127F107F00912001807C0094131C
+:1006F000941396139613A313A313A313A313AE1368
+:10070000AE1396139613A313A313A313A313AF133C
+:10071000AF13AF13AF13AF13AF13AF13AF13AF13C9
+:10072000AF13AF13AF13AF13AF13AF13AF13780003
+:1007300094137E007E107E12912000237810D12920
+:100740007F127F107F00912001807C007E007E1050
+:100750007E127810D5137F127F107F0091200180C8
+:100760007C007C007E107E127E0D7E0E7E0F7E0051
+:10077000712000016920404F7920004FEC7084A067
+:10078000001CE2787810B04D7F007F0F7F0E7F0D48
+:100790007F127F107C00003C84A007007900CD13FD
+:1007A000DE13DE13E013E013E513E513EA13EA1397
+:1007B000003C84A003007900DA13DE13DE13F31388
+:1007C000F3137810B229912000227810EC477C00B6
+:1007D000912000217810EC477C00912000217810B6
+:1007E000EC47912000227810EC477C0091200021FA
+:1007F0007810EC477C00181418141A141A142714D3
+:10080000271427142714321432143F143F142714CA
+:100810002714271427145014501450145014501433
+:1008200050145014501450145014501450145014A8
+:10083000501450145014780018147E007E107E124C
+:10084000912000247810D1297F127F107F00912001
+:1008500001807C007E007E107E127810C8137F120B
+:100860007F107F00912001807C007E007E107E1230
+:10087000912000237810D1297F127F107F009120D2
+:1008800001807C007E007E107E1291200023781073
+:10089000D129912000247810D1297F127F107F0068
+:1008A000912001807C007E007E107E127E0D7E0EE7
+:1008B0007E0F7920004F712000026920404F003DDB
+:1008C0008CD040006614EC7084A0001CE278781094
+:1008D000B04D003D84D0400074146920804F7120D9
+:1008E0000001EC7084A0001CE6787810B04D7F0FFA
+:1008F0007F0E7F0D7F127F107F007C0008700B80C1
+:10090000C8008914077002008CA0E001C0008A149E
+:100910009CD0400089147A087A09C370024078009C
+:10092000C41568001A1561200000186084D0C0004A
+:100930001A15287805A0C0009E1410001B15780019
+:100940001A151079F4D14000A4147800B914147960
+:10095000ECD14000BD14FCD04000B3147E007810F0
+:10096000AE1D7F004000BD147800B9147E007810E1
+:10097000A11D7F004000BD14012007407800C31571
+:100980001079FCD0C000C7146120404F9CC1FCC747
+:100990007800CB146120804F9DC1FDC7646005A025
+:1009A000C0001A15127982602878FCC086A0180051
+:1009B000C000DB147E0C7810851B7F0C2B780000A8
+:1009C0007C6065A0400000157E0C9C607810901E35
+:1009D0007F0C9F6000007810D51C092018008760EC
+:1009E000030110787E00FF84C000F614FF854000EC
+:1009F000F814C5C012787810BB1D7F001278C000B3
+:100A0000141578100D1E10789CD0C00008156120B8
+:100A1000404F78000C156120804F9CC012787F6099
+:100A20000000D460DCD040001815DCC0D660012086
+:100A300005407800C3157800C1157C001078F4D00B
+:100A400040002315012007407800C31506A0C2709E
+:100A5000C670CA70CE70DA70C0703DA08AA0400027
+:100A6000C80031157900381500218AA04000C8005F
+:100A7000CF1579007815C1151716E0154F16871692
+:100A80008716D715ED1C9216CF15E415E615E81557
+:100A9000EA15F21CCF15A016FD16A51BE71CEC15D8
+:100AA000EA192C1A671AB81AA519B219C619D91950
+:100AB000EB17CF15341741174D1759176F177B17C1
+:100AC0007E178A1796179E17D317DF17CF15CF15E6
+:100AD000CF15CF15F8170A1826185C188418941823
+:100AE0009718C818F9180B1974198419CF15CF1550
+:100AF000CF15CF159419CF15CF15CF15CF15CF150D
+:100B0000171D1D1DCF15CF15CF15211D661DCF1526
+:100B1000CF15CF15CF15111681169A16F7169F1BF4
+:100B2000CF15CF15681BCF156A1D091D131DCF15D5
+:100B3000CF15CF15CF15CF15CF15CF15CF15CF1595
+:100B4000CF15CF15CF15CF15CF15CF15CF15CF1585
+:100B5000CF15CF15CF15CF15CF15CF15CF15CF1575
+:100B6000CF15CF15CF15CF15CF15CF15CF15CF1565
+:100B7000CF15CF15CF15CA72C67101200640780077
+:100B8000C315CE73CA72C67101200040C2706800DE
+:100B9000C415612000001B600100912000509120CD
+:100BA00080407C00C37001407800C415C3700640CB
+:100BB0007800C41599204100A1204100A92005001A
+:100BC000A3537800C115C470C37004007A00780084
+:100BD000C1157800C1157800C1157800C1159120A4
+:100BE0000080C3700400C7705349CB702050CF7091
+:100BF0002020D370080001200F00D670792000005B
+:100C00001B780100312030005920001029201A04DF
+:100C10005120450461204704C1202000912000504C
+:100C20009120804078001804D875DC74DA75DE7481
+:100C300078001A16292000002025D071C872CC73C4
+:100C4000C470A020992030000370010007700600D6
+:100C50001A731E722274267521204000FF81400005
+:100C6000C11582A14000C8003416202106A008202A
+:100C70000384127007700400077001000870FCD034
+:100C800040003B160770020084A0E00140004916B6
+:100C9000C37002407800C415A824A55378002B1611
+:100CA0007800C115292000002025D071C872CC73AE
+:100CB000C4709820A1203000037000000770060067
+:100CC0001A731E72227426752120400007700600D8
+:100CD000FF814000C11582A14000C8006E1620218E
+:100CE00006A0082003841270A824A65307700100F0
+:100CF0000870FCD04000751684A0E0014000631627
+:100D0000C37002407800C415D875DC74DA75DE74DF
+:100D100078005216C471C87014219EA70400C00048
+:100D20008F160A20CA727800C015C7700800CB70F1
+:100D30000F00CF700B007800C115D875DC76DA751E
+:100D4000DE767800A316292000003025C470C87212
+:100D5000CC73D074C670CA72CE73D27405A0400032
+:100D6000F2160AA44000B316C800BC1601807278BF
+:100D700084A000FC4000C016AC7885C0AE7801208D
+:100D800005407800C3157E7B7A7A867E827D767CEC
+:100D90008CA400FF4000D8160784048004800C81D6
+:100DA0000C810F8118A191A20000B1A6000081A5BD
+:100DB00000007800E21607840480048018A391A242
+:100DC0000000B1A6000081A500001A731E722276F1
+:100DD000267005A64000EC16107AC5C2127AAC78CF
+:100DE00084A0FCFFAE787800F516AC7885C0AE78AC
+:100DF0007800C115D875DC76DA75DE7678000017D4
+:100E0000292000003025C470C872CC73D474C67019
+:100E1000CA72CE73D67405A040002F170AA44000F2
+:100E20001017C80019170180927884A000FC4000B8
+:100E30001D17AC78C5C0AE78012005407800C315F9
+:100E40009A7A9E7BA27DA67E002605A540002817E3
+:100E5000107AC5C2127A967CAC7884A0FFFCAE787A
+:100E600078003217AC78C5C0AE787800C11509207B
+:100E700000006C7865A040003E1708810060780093
+:100E80003717C47A7800BF150920484F0C21107815
+:100E9000ECD0C000C0151120884F14227800BF1577
+:100EA0000920494F0C211078ECD0C000C01511204A
+:100EB000894F14227800BF156120404F28612C62B1
+:100EC0001482148214821078ECD0C0006D17612057
+:100ED000804F2863DA732C631C831C831C83DE73AE
+:100EE0007800BF1509204C4F0C211078ECD0C000C1
+:100EF000C01511208C4F14227800BF151879780086
+:100F0000C01509204D4F0C211078ECD0C000C01541
+:100F100011208D4F14227800BF1509204E4F0C214F
+:100F20001078ECD0C000C01511208E4F142278002C
+:100F3000BF1520791078ECD0C000C015247A780055
+:100F4000BF15C471FCD1C000A6171120C053780092
+:100F5000A81711204054078184A00F00038003804C
+:100F6000038068A2006A04689CD04000B717086B31
+:100F70007800B8170C6BFCD1C000BF1721203B02D2
+:100F80007800C11721203B0124241479E4D14000CA
+:100F9000CD17C4D4C000CC17D5C47800CD17DDC49C
+:100FA000A4A4001CDE74C4717800BE15C477781048
+:100FB0002B1E912000801C6B146A91200180082751
+:100FC0007800BE156120404F18611078ECD0C00049
+:100FD000C0156120804F18627800BF15C477781063
+:100FE0002B1E912000800869186A106BDA77912017
+:100FF00001807800BE15C471102194A20F0082A256
+:101000001000C800B9157810C62784A3004040001E
+:10101000081895A220007800BE15C4710021BCC03C
+:1010200082A01000C800B915BCD1C0001918112049
+:10103000484F042278001D181120884F0422BDC09B
+:101040007E000021BCC01220781023277F01780089
+:10105000C015C4712120494F0424C6701920000016
+:1010600078003518C8712120894F0424CA70FDC347
+:1010700011205418A9200800042206A14000441899
+:101080001082F0003918C471C8727800B81592A2A5
+:1010900054187E0222217F01781044271078ECD06A
+:1010A000C0005218FCD340002F187800C115E80387
+:1010B000FA00F401EE0204000100020003006120C6
+:1010C000404F28612C62148214821482C4702A60FA
+:1010D000C8700380038003802E601078ECD0C000BD
+:1010E00082187E027E016120804F28612C6214826A
+:1010F00014821482D8702A60DC700380038003801D
+:101100002E60DA71DE727F017F027800BF156120E8
+:10111000404F3061C47032601078ECD0C000C01510
+:101120006120804F3062C87032607800BF15187936
+:101130007800C015C47184A1CFFF4000A3181078B7
+:10114000ECD0C000B915C8727800B81511204D4F09
+:10115000042212217E00192000007810AB2710789D
+:10116000ECD04000B3187F017800C015C87184A18D
+:10117000CFFF4000BC181021C4717800B8151120B1
+:101180008D4F042212217E00FDC37810AB277F0211
+:101190007F017800BF15C47182A110004800D418E7
+:1011A0001078ECD0C000B915C8727800B8151120BD
+:1011B0004E4F04227E00122119200000781089274A
+:1011C0001078ECD04000E4187F017800C015C87199
+:1011D00082A110004800ED181021C4717800B815E4
+:1011E00011208E4F04227E001221FDC37810892722
+:1011F0007F027F017800BF15C471C87284A1FDFF12
+:10120000C000B81584A2FDFFC000B81500212079E8
+:1012100022780022247A26787800BF15C471FCD188
+:10122000C00013191120C053780015191120405423
+:10123000078184A00F0003800380038068A2192027
+:101240000000C872BCD2400024199DA31000B4D283
+:10125000400029199DA308009120008000687E00AD
+:1012600026A240004819026AECD440003519A5C3F3
+:10127000E4D4400039199DC3F4D4400048190F81CB
+:10128000F4D24000441978100828780048197810E2
+:10129000E62778004819CC72086806A240006A194F
+:1012A000A4A2FF001478E4D0C0005B1982A4280037
+:1012B000480067194000671978005F1982A443004D
+:1012C00048006719C471C6717F02CA7291200180FB
+:1012D0007800BA150A6A9DA30A00046805A3066887
+:1012E0007F020C6BC471912001807800BE15C47719
+:1012F00078102B1E91200080146A1C6B91200180B5
+:10130000C8701668CC701E6808277800BE15C470B7
+:101310006120404F18611A601078ECD0C000C015F1
+:10132000C8706120804F18621A607800BF15C471C0
+:10133000C872CC7382A11000C800B91578102A2891
+:1013400084A300404000A31995A220007800BE1598
+:10135000C47778102B1E91200080086A8DC20A6A1B
+:101360009120018008277800BF15C47778102B1EC4
+:1013700091200080086A94A2F9FF0A6A046805A017
+:101380004000C11978106F2691200180082778004D
+:10139000BF15C47778102B1E91200080086A95C273
+:1013A0000A6A046805A04000D41978106F269120BD
+:1013B000018008277800BF15C4774120010049202B
+:1013C000050051202000912000807810461E9120B9
+:1013D00001800827086A7800BF15C4771478E4D024
+:1013E000C000FE19FCD74000F8197810AE1D40006F
+:1013F000FE197800C3157810A11D4000FE19780071
+:10140000C315C873CC72C677CA73CE727810CD1E5E
+:10141000C000281A186805A04000221A08277E0775
+:1014200078105A287F07C000221A01201500FCD727
+:10143000C0001B1A6120404F78001E1AFDC06120B9
+:10144000804F2A78912001807C009120018001202A
+:1014500005407800C315912001807800C115C4773C
+:101460001478E4D0C000401AFCD740003A1A781033
+:10147000AE1D4000401A7800C3157810A11D400031
+:10148000401A7800C315C677412021004920050085
+:1014900051202000912000807810461E092016005F
+:1014A000FCD7C000541A6120404F7800571A6120C1
+:1014B000804FFDC1676003007F6000007667836036
+:1014C0000F002A79D461DCC1D66178106F26912093
+:1014D00001807C00C877CA77C477C6771478E4D0D7
+:1014E000C0007E1AFCD74000781A7810AE1D40006C
+:1014F0007E1A7800C3157810A11D40007E1A78006E
+:10150000C315BCA700FF9120008009201700FCD75D
+:10151000C0008B1A6120404F78008E1A6120804FE6
+:10152000FDC17F60000067600200766783600F0086
+:101530002A79D461DCC1D66178106F2691200180B0
+:1015400041202100492005005120100091200080F9
+:10155000C87005A04000AC1AD460FDC0D6607810F9
+:10156000461EC8703668388784A71F00C000AC1AB2
+:10157000912001807C00192000001478E4D0C00084
+:10158000CE1AC87284D24000C81A7810AE1D40002E
+:10159000CE1A7800C3157810A11D4000CE1A78002D
+:1015A000C315C872CA72AC7884A00300C000F91ACF
+:1015B0003920000084D24000DB1AFDC74120210001
+:1015C000492004005120080078102B1E9120008033
+:1015D0000868D4C00DA80A6991200180388784A7C3
+:1015E0001F00C000E11ABCA700FF3F8738873F8774
+:1015F00084A7000FC000E11A91200080C87284D235
+:10160000C0000B1B1078ECD04000071B69200001C4
+:1016100078000D1B6920000278000D1B6920000175
+:10162000086884A0FDFF0A683068B4D040002D1B14
+:101630004B680400A9201400486894D040001F1B88
+:10164000F000191B4B680900A9201400486884D0D9
+:101650004000291BF000231BA920FA00F0002B1BDF
+:101660007920004F09201800C87284D2C000391BAD
+:101670006120404F78003C1B6120804FFDC17F609E
+:1016800000002A796760010083600F00A7600000F6
+:10169000A860B260B660D460B4D04000581BB4C03B
+:1016A000D6607E0CB86065A00860D4C00A6018607F
+:1016B00001801A607F0CD46084A0FF77D660AC787C
+:1016C0008DC0AE78FF834000631B7C001B68470021
+:1016D000912001807C00CC737810BA1AEC69486ABA
+:1016E00085A100184A6885A14000EE68CC732120CE
+:1016F0000400A920FF09F000781B2184C000761B9C
+:101700001983C000741BEE694A6A912001807C0035
+:10171000FCD7C0008C1B6920404F78008E1B6920CD
+:10172000804FC471C6711669FF81C000961BA768FF
+:101730000100AC788CC0AE7884D0C0009E1B7810BD
+:101740002D1F7C00D875DC74DA75DE747800A71B59
+:101750002EA02025C471C873CC72C671CA73CE7214
+:101760007920004FDE7DDA7CD67BD27A7810041E99
+:101770004000D11CA9200500A120144F9120008019
+:10178000A1419120018009204000781018204000DC
+:10179000CA1B78100D1E7800D11C04608CA0FF00BD
+:1017A0008EA10900C000D51B7E007810BF237F00EA
+:1017B00084A000FF078009804000611C7E0C682C1B
+:1017C0007810041E40001B1C002C9E680981C0007C
+:1017D000DC1B9F6000007F0C7E0CDC7DD87CD47B02
+:1017E000D07A90A2400099A30000A1A40000A9A56E
+:1017F0000000DE7DDA7CD67BD27A682C9C6865A0FE
+:101800004000601C0920400078101820C0003E1CD9
+:10181000046084A0FF0086A00200C0001B1C0460BE
+:1018200084A0FF0086A00A00C000171C7E0178106B
+:10183000BB237F01002D02607800EA1B7F0C7E0C29
+:101840009C607810901E7F0C9F6000007810D51C63
+:10185000092018000860CDC00A6004608660107816
+:101860007E00FF84C000341CFF854000361CC5C0CC
+:1018700012787810BB1D7F00127878100D1E78004A
+:10188000D11C7F0C7E0C9C607810901E7F0C9F609A
+:1018900000007810D51C09201800876003011B6028
+:1018A000030010787E00FF84C000561CFF854000B6
+:1018B000581CC5C012787810BB1D7F0012787810B4
+:1018C0000D1E7800D11C7F0C1478E4D0C0008F1C52
+:1018D0001461FCD140006F1C7810AE1D40008F1CBD
+:1018E0007800731C7810A11D40008F1C7810D51C47
+:1018F00009201800876003011B60210010787E001A
+:10190000FF84C000831CFF854000851CC5C0127881
+:101910007810BB1D7F00127878100D1E0120074043
+:101920007800C315C474C873CC7214609120008011
+:101930007E0E09201200FCD0C0009F1C7120404F79
+:101940007800A21C7120804FFDC12A7967700500C4
+:10195000D471DCC1D6716A736E72727476707B70EA
+:101960000000002C7E702EA030251C6184A1600038
+:101970004000B91C7810B6467F0E9665A6659A663B
+:10198000AA66AF600000B360000014672360000027
+:10199000246096A00100C000CC1C00802660781056
+:1019A0006F26912001807C00C37005407800C4152B
+:1019B000A92005009920144F912000800A539120FE
+:1019C0000180002110A299A30000A1A40000A9A5F4
+:1019D00000007C00C471C77000001E797800C1153A
+:1019E000C471C67168217800F41C692000100C696C
+:1019F00016A0042D10A2688D0981C000F61C85A2D6
+:101A00000000C000041DC37000407800061DC370B4
+:101A10000340CA707800C4156479C671C47182A18C
+:101A20000300C800B91566797800C1156479C671DC
+:101A30007800C1150079C671C47102797800C115AA
+:101A40000079C6717800C115C470112000008CA007
+:101A50000D004000361D0C814800321D10820C81A3
+:101A60000C814800321D10820C81FF81C000BA1524
+:101A700010820E7A8CD24000621D1079CDC112798D
+:101A8000092021001920030084D240005C1D088138
+:101A90001920410011204E97122319204200108274
+:101AA00012231920430010821223192046001082AD
+:101AB000122319204700108212231920060011203A
+:101AC0005397122111207397122304790678780016
+:101AD000C0150478C6707800C115C471FCD1C0006F
+:101AE000721D1120C0537800741D112040540781CD
+:101AF00084A00F0003800380038068A2146AB4D21C
+:101B00004000831D112001007800851D1120000078
+:101B10000C6B0068DA707800BE151478F4D04000C1
+:101B2000951D01200740DB70000005A07800A01D76
+:101B3000FCD040009F1D01200740DB70010005A084
+:101B40007800A01D06A07C001478F4D04000AC1DE5
+:101B500001200740DB70000005A07800AD1D06A045
+:101B60007C001478FCD04000B91D01200740DB70D8
+:101B7000010005A07800BA1D06A07C0012711A723F
+:101B80001E731078C4D04000C41D2274267580AC2A
+:101B9000010008810C81A9819880A1203000037088
+:101BA00000008460A220A65307700100747984A10C
+:101BB00000FF4000E11D0F810C810C810480048036
+:101BC000078000A17800E41D0781048004807C79EF
+:101BD00008A1787A06A011A2107DC4D54000F11D9D
+:101BE000847B19A3807C21A40870FCD04000F11DE7
+:101BF00003700100077006001A711E72107DC4D5B3
+:101C00004000011E2273267484A0E0017C00487805
+:101C100065A040000C1E042C4A78632000007C0064
+:101C20007E0F7920004F48786220002C05A0C0006C
+:101C3000181E7810B2294A787F0F7C001120009975
+:101C40004A7AC47B19834000281E80A232001220E9
+:101C5000102078001F1E132000007C007E017E02F1
+:101C6000FCD7C000341E1120C0547800361E11204D
+:101C7000C07484A7000F0B8084A71F004000411E82
+:101C8000038003800380038005A168A27F027F0197
+:101C90007C0078102B1E00292A68002A2E6808680C
+:101CA00084A0EFF90DA80A697E0EFCD7C0005B1E68
+:101CB0000920534F7120404F78005F1E0920934F39
+:101CC0007120804F0C21046805A040006F1E16A1F2
+:101CD000C0006F1E6020006006687E010B200000BF
+:101CE0007800721E092000007E01046865A0400093
+:101CF000871E006006687810A21E781064201068A5
+:101D0000087909810A7901801268C000721E107971
+:101D1000A5C112797F0102690669002D6020781043
+:101D2000132B7F0E7C0065A04000A11E08209C6044
+:101D300005A040009E1E62209F60000065A0780004
+:101D4000941E48784A7962207C00076003018F6006
+:101D50000000A9201C0080AC0500A020012000008C
+:101D6000A44028681A602C6822607C007E0EFCD794
+:101D7000C000BD1E7120404F3120C04F7800C11EF1
+:101D80007120804F3120C05150708CA00002C000E3
+:101D9000CB1E08A60A2D0080527006A07F0E7C0084
+:101DA0007E0FFCD7C000D51E7920404F7800D71E8B
+:101DB0007920804F78102B1E9120008004680A78CB
+:101DC00065A040002B1F7800E91E002C0A786020D7
+:101DD000006065A040002B1F106006A3C000E21E3B
+:101DE0000C6006A2C000E21E282C4C7806ACC00095
+:101DF000F81E7800281F046806ACC000061F0060AB
+:101E00006020066805A0C000061F03680000780077
+:101E1000101F006408786020026486A40000C000DF
+:101E2000101F002C026860257F0F7810A21E7E0F05
+:101E30001B600500236020007F0F781064207E0F58
+:101E4000087909810A79106801801268C000281F8A
+:101E50001078A5C012780120FFFF05A07F0F7C003D
+:101E60007E07002739200000FCD04000351FFDC749
+:101E700041202100492004005120080091200080C9
+:101E80007810461E388784A71F00C0003D1FBCA7DE
+:101E900000FF3F8738873F8784A7000FC0003D1FA2
+:101EA000912001807F077C006C78092074970C21B9
+:101EB0000DA140005B1F65A07800DC2361200000BD
+:101EC000186084D0C0007B1F10788CD040006C1F3D
+:101ED0008CC01278FCC76920404F7800711F8DC0FC
+:101EE00012786920804FFDC7912000801C681F6810
+:101EF00000009120018005A0C0007C1F7C008CA008
+:101F0000F0FF4000821F7810B2297900841F941FCF
+:101F1000971F9D1FA11F951FA51F951F951F951FFB
+:101F2000AB1FDC1FE01FE61FFB1F951F951F7C00EA
+:101F30007810B22978102D1F012001807800072029
+:101F4000012003807800072001200480780007200A
+:101F500078102D1F01200680780007209120008036
+:101F60007E07FCD7C000B71F6920404F3920090009
+:101F70007800BB1F6920804F39200900006886A0C7
+:101F800000004000C51F7F001E6F912001807C0073
+:101F900074687F07BCA000FF412021004920040095
+:101FA000512010007810461E388784A71F00C000FB
+:101FB000CF1F9120018001200A8078000720012096
+:101FC0000C807800072078102D1F01200D807800EC
+:101FD00007201478E4D0C000F91FECD04000F31FB4
+:101FE000FCD74000F31FE4787800F41FE078C67057
+:101FF00001200E80780007207800951FFCD7400054
+:102000000120EC7878000220E878C67001200F806B
+:1020100078000720C270FCD7C0000F20DB700000E2
+:1020200078001120DB700100612000001B600100BE
+:10203000912080407C0080AC0100FF814000432063
+:1020400099203000A0200C7084A0FF0340002520C0
+:1020500018707E001C707E0020707E0024707E0050
+:102060001271AC811A721E732274267503700100FE
+:102070000770010008700B80C8003720077002004D
+:102080008CA0E001C0004320A55306A0037000000F
+:10209000077004007F0026707F0022707F001E7092
+:1020A0007F001A707C0011202000092010000A6BAC
+:1020B0000E6C036800FD076818001A6A002DE8A07E
+:1020C000080090A204000981C00054207C00046034
+:1020D0008660082C63200000687805A06A794000BB
+:1020E0007120022C780072206E797C007E0C6120B9
+:1020F000004F87680301082D6B200000686005A071
+:102100006A6140008320022D780084206E617F0C7C
+:102110007C0091200080042C6E7805A0C0008E20E9
+:102120006A78912001809C6005A04000A7207E0C69
+:10213000602008209C6005A04000A32062209F60D2
+:10214000000065A09C6005A0C0009B2048784A79EB
+:1021500062207F0C487862209F60000085AC000000
+:10216000C000B1207810B2294A787C00A920100064
+:1021700006A0048086808E81C800BC2000A2F000EA
+:10218000B72086808E817C007E15A920100005A0D6
+:102190004000E2201AA1C800E22013828D8148008D
+:1021A000D5201AA1C800D620F000CA207800DA2075
+:1021B0001AA108231082F000CA207E00003284A0F9
+:1021C000FFF780207F007F157C007E00003285A015
+:1021D00000087800DE20747DD07006A54000CE2176
+:1021E0001078502000788CD040000A21ECDA4000B2
+:1021F0000A217E0E9120008071202000047005A02D
+:10220000C000072108707F0E86A0080040000A2148
+:102210007800CE217F0E7800CE217810041E400079
+:10222000CE2146A070790025008012A1092040002F
+:10223000C800192178002021D07206A24000202178
+:102240004088092080007E0C1271077001009920DF
+:102250003000A920200080AC0100A02061200000F7
+:10226000FF88400032217810041E0870FCD0400026
+:10227000322107700200912001808CA0E001C00093
+:102280006921A553FF8CC0004721FF884000B82179
+:1022900078005121002C8E78A920200080AC01000C
+:1022A000A020A5537800B82146A018721C73C4DA88
+:1022B000400059212074247592A240009BA3000085
+:1022C000A3A40000ABA500001A721E73C4DA40007C
+:1022D00069212274267506A0077004004000B82109
+:1022E000FF8C4000722178100D1E7F0C78100D1E9F
+:1022F00046A0887800808A7886A002004000982155
+:102300007C7A787BC4DA40008421847C807D747977
+:1023100007810480048010A299A30000A1A40000FA
+:10232000A9A500001A721E73C4DA4000CE212274DF
+:1023300026757800CE211460FCD0C000A021692051
+:10234000404F7800A2216920804F912000801F68B3
+:102350000200FF884000AE2146A08C786020780003
+:1023600098218B780000AC7885A00300AE7891208E
+:1023700001807800CE217F0C8B78000078108D23AF
+:10238000046084A00F007810CF21FF884000CC218A
+:102390008C786020046084A00F007810CF21780032
+:1023A000E8207C007900D121E121FF211D22E121DB
+:1023B0002E22F221E121E121E121FD211B22E12157
+:1023C000E121E121E121E12139200004BC7805A7C8
+:1023D000BE78086005A70A60781071229C60BA7800
+:1023E0009F600000781077237C00BC78C4D0400048
+:1023F000F8217800E1211C60BDC01E607800052234
+:102400007810BF23BC78C4D0400005227800E121B9
+:10241000BF7800000460078084A0FF00B2780180CC
+:10242000400018227810712240001822BC78C5C0E4
+:10243000BE7878001A22780090227C007810BB23A6
+:10244000BC788CA0000EC0002522C4D0C00027227A
+:102450007800E12178107122C0002D2278009022AE
+:102460007C00BC78C4D0400034227800E121BF78E1
+:102470000000146711200100A822186084A0FF004A
+:1024800005A040005422BCA700FFA92020008EA078
+:10249000010040005422BCA7008011200200A920A6
+:1024A00000018EA002004000542278006E227810B5
+:1024B0002B1E002D912000802B6800002F6800004B
+:1024C000086884A0DEFF0A68E8AD10009120018052
+:1024D000F0005722118240006E22A92000017800EE
+:1024E000572278100D1E7C009F600000B4786DA00C
+:1024F000002CB678C0007C22BA78780084229E68CE
+:10250000002D0260B87806ADC00084220260B07869
+:102510000180B278C0008F22BC78C4C0BE78B87881
+:10252000602006A07C007E0E2EA03025BA7DB67DF0
+:10253000AE65B2651C60A260482084A9FFE11E6000
+:1025400084A960004000A3227810B6469665A6656F
+:102550009A66AA6614677120804FFCD7C000AF222C
+:102560007120404F84A7000F0B8084A71F004000FC
+:10257000BA22038003800380038005A1C47168A18F
+:102580000027078084A00F00038003800380C871A8
+:1025900000A1C260912000801478C4D04000DF22E6
+:1025A000ECD04000DB22FCD7C000D822F4D0C00021
+:1025B000E6227800DF22FCD0C000E6221078F4D0BA
+:1025C000C000E622086E84D640001023FCD9C0006B
+:1025D0001023912001807810A21E91200080781095
+:1025E0006420912001801478E4D0C0007523147811
+:1025F000C4D040007523ECD040000823FCD7C000B5
+:102600000323F4D0C0000C2378007523FCD0C00055
+:102610000C23780075231078F4D0400075231B60DC
+:10262000210078007523246096A00100C0001723C4
+:1026300000802660106A146802A248002A23400025
+:102640002A2391200180392000029C60BA789F6083
+:1026500000007810772378007523082CFCD94000FF
+:102660005223006865A040005223046A007084A0D1
+:102670000200400048234C7006A2C0004823046BAF
+:1026800060210423026005A0C00044230269602287
+:10269000026178005E23002D60207810132B086EF5
+:1026A00060210262066978005E230068026965A005
+:1026B00040005A23026178005B23066960210360B1
+:1026C00000006021FCD940006523B4A6FCFF0A6E1F
+:1026D0001068087D28850A7D00801268912001809D
+:1026E000B4D640007523B6A640000A6E7810B31E1B
+:1026F0007F0E7C00086005A70A609120008078109A
+:10270000642091200180B87865A040008A239C60F5
+:10271000BA789F60000078007723B678BA787C009A
+:1027200070797478182884D340009723008012A110
+:1027300048009C23008012A1C800AC2384C37C7A8B
+:102740001A72787A1E72C4DA4000A723847A227241
+:10275000807A267206A084D34000AC23008076786D
+:10276000D2701C7805A04000BA2301801E78C000FA
+:10277000BA236800BA23912080407C003920D323FB
+:102780007800C1233920D923042705A04000D22393
+:1027900000AC68200869106812690A680C6914683E
+:1027A00016690E6838877800C1237C000300090091
+:1027B0000F0015001B00000015001B000000412049
+:1027C00000000C787900E123B3258625E5235E24FB
+:1027D000392074973427107D78000524846086A002
+:1027E0000301C00047241461186005A14000FA23CA
+:1027F000FF86C000162478004724038680A05597E2
+:102800000C6202220080106202227810862030863C
+:102810008EA60F004000D2246C7865A0C000EB2388
+:10282000087802A6C8001624ACD5C00016243A26A3
+:102830007C0082A60300C800D22491200080692079
+:102840000000186884D0C00042241120559704224B
+:10285000C67010820422CA7084D6C000322410824E
+:102860000422DA7010820422DE7085A62080C270F5
+:102870001B68010091208040107884A0CFFF12785F
+:10288000912001803B2000007C001078ADC01278C0
+:102890007800D2243A267810BD25C000E0256C7857
+:1028A00065A0C000EB2391200080107884A0CFFFAA
+:1028B000FF8640005924ADC0127891200180780035
+:1028C000E025392074973427107D78007A248460BD
+:1028D00086A00301C000BB241461186005A140005C
+:1028E0007324FF86C0008B247800BB2480A65597F4
+:1028F0000C6202227810862030868EA61E004000D0
+:10290000D2246C7865A0C0006424087802A6C800B0
+:102910008B24ACD5C0008B243A267C0082A606000E
+:10292000C800D2249120008069200000186884D05B
+:10293000C000B6241120559709204E97A8261C21C7
+:1029400004221A2008811082F0009C2485A6308081
+:10295000C2701B68010091208040107884A0CFFFD6
+:1029600012789120018006A0092075970A203A204C
+:102970007C001078ADC012787800D2243A26781006
+:10298000BD25C000E0256C7865A0C00064249120BE
+:102990000080107884A0CFFFFF864000CD24ADC01A
+:1029A0001278912001807800E02591200080077046
+:1029B00004009479D47002A14800E3244000ED247F
+:1029C000907B02A3C000ED247800E6240280C000C2
+:1029D000ED243A261078ADC01278912001807C0059
+:1029E00084A100FF4000FA240F810C810C81048037
+:1029F0000480078000A17800FD2407810480048002
+:102A00009C7A10A21A72987A06A011A21E72C4D4DF
+:102A100040000D25A47A11A22272A07A11A226727A
+:102A2000A120300003700000092054970A26098174
+:102A30009821042184D040001B253386B0A60200D3
+:102A4000A826A65303861270077001009079947827
+:102A500000800AA1C8002A2506A02820747984A134
+:102A600000FF400039250F810C810C810480048017
+:102A7000078000A178003C250781048004807C79D0
+:102A800008A1787A06A011A2C4D440004825847B0E
+:102A900019A3807C21A40870FCD04000482584A0A4
+:102AA000E00140006D25107D312054973426A87830
+:102AB0000080AA788CD0C0006225077006000470E0
+:102AC00094D0C0005C257800D4246920474F6B2047
+:102AD0000300AC7885A00003AE7806A078007625C8
+:102AE0003020D67591208040967D107DACA5CFFF1B
+:102AF000127D91200180AA78077006003A260370A3
+:102B000001001A711E72C4D54000852522732674F7
+:102B10007C00846086A00301C000A92514611860B0
+:102B200005A1C000A92569200000186884D0C00054
+:102B3000A9250C60C6701060CA70C37020801B6825
+:102B4000010091208040781086206800A8256C78CC
+:102B500065A0C00086257C007810BD25C000E0255A
+:102B60006C7865A0C00086257800E0257810BD252A
+:102B7000C000E0256C7865A0C000B3257800E02592
+:102B8000846086A00301C000D1251860FCC01A60D3
+:102B900086A00400C000D1250478A4D04000D1252F
+:102BA0007810862006A07C007810E625C000D82585
+:102BB00085A001007C007810F525C000DE254120AD
+:102BC0000100107D7C00FF884000E52591208040B9
+:102BD0007C00907B9479D47002A1C000EF2585A37E
+:102BE00000007C004800F32502A37C0002807C00EA
+:102BF0001078ECD040000D267E0E912000807120D0
+:102C00002000047005A0C0000A2608707F0E86A070
+:102C1000080040000D2678005E267F0E78005E26B4
+:102C200084A100FF40001A260F810C810C810480D2
+:102C30000480078000A178001D260781048004809D
+:102C40009C7A987BA47CA07D10A206A019A321A445
+:102C500029A509201800286005A040002E2609207B
+:102C600040007810BB1D40005026A8780080AA784C
+:102C70008CD0C0005E261460FCD0C00040266920C5
+:102C8000404F780042266920804F912000801F68C5
+:102C90000300AB780000AC7885A00003AE789120EB
+:102CA000018078005E26AB7800007810862090794D
+:102CB000947800800AA1C8005B2606A09678D6709A
+:102CC00006A071201000912001807C00FCD7C0007C
+:102CD0006A260920594F78006C260920994F9120C7
+:102CE00000800A207E0FFCD7C00083260920404FB9
+:102CF0000120044F0420ECD040007F267920000101
+:102D00007800872679200002780087260920804FE6
+:102D100079200001042186A00000C000A026FCD775
+:102D2000C00093260920454F780095260920854F3D
+:102D3000042105A0C000A026307884A0C000C000F7
+:102D4000A0261B7845007F0F7C0009200200692027
+:102D5000004F1068ECD0C0000F277120804F792001
+:102D600000012120BF514B780F001920A74484D1C6
+:102D70004000C3261068ECD04000BF26A1202B01E4
+:102D80007800C526A1202B027800C526A1202B01A2
+:102D9000042305A04000D2269A781883AC23188318
+:102DA0009823A65318337800C5269B782000A920C5
+:102DB00010001468E4D04000E226AF780000AF783D
+:102DC0002090F000DA267800E826AF780000AF788F
+:102DD0002080F000E226037000007E018CD10920E3
+:102DE00000004000F126BDC17810E2287F0120706C
+:102DF00084A00F007E001468E4D07F00C00001278B
+:102E000085A040637800032785A0C06206780F780C
+:102E100000924378D800537880000B7808005674ED
+:102E2000537000000981400022277120404F106834
+:102E3000ECD040001C277920000178001E27792063
+:102E400000022120BF4F7800B0267C007E01BCD15B
+:102E5000C00037277E000120044F0420ECD07F0003
+:102E60004000332711200101780039271120010289
+:102E700078003927112001018CA10F00042284A0C1
+:102E8000F0FF05A112207F017810E2287C00FCD31E
+:102E9000C00057277E000120044F0420ECD07F00A3
+:102EA0004000532711200101780059271120010209
+:102EB0007800592711200101A92009000B81F00099
+:102EC0005B278CA1000E042284A0FFF105A1122033
+:102ED0007C00192002000120044F0420ECD04000A7
+:102EE0007327198309200101780075270920010142
+:102EF000A92005001382F000772794A2E0000421A6
+:102F000084A01FFF05A20A201983400088270920FA
+:102F10000102780075277C00FCD3C0009C277E004E
+:102F20000120044F0420ECD07F004000982711209E
+:102F3000010178009E271120010278009E271120B0
+:102F40000101A9200C000B81F000A0278CA100F04A
+:102F5000042284A0FF0F05A112207C00FCD3C00036
+:102F6000BE277E000120044F0420ECD07F004000EB
+:102F7000BA27112002017800C02711200202780030
+:102F8000C02711200201042284A0CFFF05A1122036
+:102F90007C007E0CBCD1C000DA277E000120044FEB
+:102FA0000420ECD07F004000D6276120000178008B
+:102FB000DC27612000027800DC2761200001BCC111
+:102FC0000381038080A020009A60AC62AC637F0C18
+:102FD0007C007E0CBCD1C000FA277E000120044F8B
+:102FE0000420ECD07F004000F6276120000178002B
+:102FF000FC27612000027800FC2761200001BCC191
+:103000000381038080A022009A60A46084A0DFFF77
+:10301000AE607F0C7C007E0CBCD1C0001C287E0002
+:103020000120044F0420ECD07F00400018286120CC
+:10303000000178001E286120000278001E2861200F
+:103040000001BCC10381038080A022009A60A460BB
+:1030500085A02000AE607F0C7C007E0CBCD1C0003F
+:103060003E287E000120044F0420ECD07F00400069
+:103070003A28612000017800402861200002780091
+:10308000402861200001BCC10381038080A0200092
+:103090009A60A4608CA2200040004E28ACC29DA380
+:1030A0000040FCC3B4D3C0005328FDC3AE6210205F
+:1030B000A460AE6318207F0C7C00912000807E0C01
+:1030C0007E0E186805A04000C028FCD14000692889
+:1030D0006120D09678006B286120C0957810C828B0
+:1030E0004000A228A9200101FCD1400078286120DD
+:1030F000D09578007A286120C0947E0C7810C8287A
+:10310000400085287F0C608CF0007A287800C02869
+:103110007F00FCD140008F2882A0D0957120804F85
+:103120007800932882A0C0947120404F7A70767105
+:10313000382101200400667083700F00D471DCC157
+:10314000D671781063267800BC28FCD1C000A9286D
+:103150007120404F7800AB287120804F2060DDC087
+:10316000226076713821002C7E7001200600667086
+:1031700083700F00D471DCC1D671781063260120F2
+:1031800000007800C228012001009120018005A0E4
+:103190007F0E7F0C7C00042C05A04000DF286020FF
+:1031A000106006A3C000DC280C6006A2C000DC286A
+:1031B000146006A1C000DC2806A07800E1280060A9
+:1031C0007800C92885A001007C007E0F7E0E7E015C
+:1031D000BCD1C000FA287920404F7E000120044F66
+:1031E0000420ECD07F004000F62871200001780018
+:1031F000FE28712000027800FE287920804F71207F
+:10320000000120798CA10F00EC70C4D0C000082907
+:103210007F01780023290B810B810B810B817F00BB
+:10322000BCD0C00020297E000120044F0420ECD037
+:103230007F0040001C298DA1000F780022298DA15C
+:10324000000F780022298DA1000804217F0E7F0F36
+:103250007C007E0E0120014F0420ACD0C000A329C9
+:10326000E468ACD04000A32984A00600C000A329D4
+:103270001460FCD0C0003D297120C05378003F2964
+:1032800071204054078084A00F00038003800380D6
+:1032900070AE047084A00A00C000A329087194A134
+:1032A00000FF4000A3298CA1FF0001200A0006A115
+:1032B0004000722901200C0006A14000762901205F
+:1032C000120006A140007A290120140006A1400046
+:1032D0007E290120190006A1400082290120320028
+:1032E00006A14000862978008A2909200C00780070
+:1032F0008C290920120078008C29092014007800FC
+:103300008C290920190078008C29092020007800D8
+:103310008C2909203F0078008C2911200000002111
+:1033200005A20A707120004F0470BCD04000A32990
+:103330001460FCD0C0009E29EA707120404F7800D4
+:10334000A129EE707120804F1F700D007F0E7C0050
+:103350000120054F0420E4D0C000B129047884A0E6
+:103360001FFF85A0406306787C006800B229912089
+:103370000080712000007E00187084D0C000B92940
+:103380007F0071201000CA707F00C670C370028079
+:10339000DB700F08DF700B00712000001B70010054
+:1033A000912080407800CF293C7F587E307C387D4A
+:1033B000A0788E70927596749A769E7794A53F0049
+:1033C000F4D44000E62984A77D00C0001D44781095
+:1033D000B2299CA40F0082A304005000F129A6A3E7
+:1033E0000700C000B2291824078584A00F007900C7
+:1033F000F629713062318D31FF33E8376238173981
+:10340000A839963A853B092A062A422E652FB937F4
+:10341000062A7810B2297C0006A07800132A0878C2
+:103420008DC00A7806A002704E704670D27060702F
+:1034300005A0C000792B647084A0070079001D2AC4
+:10344000252A982AA12AAC2AB72A5F2BC22A982AB1
+:103450003078BCD0C000082AD471BCD1C000082A82
+:10346000B4D1C000752AA47086A001004000082ACB
+:10347000B4706DA0006865A055A09B7810000C6B1F
+:10348000AA7B086845A0106D04686DA05DA086A8A1
+:10349000010040004B2ABC69AA7DAA79C0684DA0F2
+:1034A0001C6E012010007800D32C607005A0C000B5
+:1034B000082A7E0C7E0DB4706DA0006865A055A032
+:1034C0009B7810000C6BAA7B086845A0106D0468FF
+:1034D0006DA05DA086A8010040006E2ABC69AA7D8F
+:1034E000AA79C0684DA01C6E012020007800D32C62
+:1034F0007810B043C000082A1B785B00BC706DA038
+:10350000B4685A789468D678DE789868D278DA7891
+:1035100008788DC00A78BC684270B4C1D671B870A2
+:1035200065A0C0685A7003700200002D4E7080AD17
+:10353000090046707C007810B043C000A02A1B78B8
+:103540004700037004007C007810B043C000AB2A31
+:1035500011200C007810D22A037004007C0078102F
+:10356000B043C000B62A112006007810D22A03709A
+:1035700004007C007810B043C000C12A11200D0067
+:103580007810D22A037004007C007810B043C00089
+:10359000D12A112006007810D22A7C707F7000009A
+:1035A00068204E70037001007C007471FCC10781BB
+:1035B00082789B78100086A20C00C000E12AAA7ACB
+:1035C000012001007800F62A8CA11F008DA1C00007
+:1035D000AA7986A20D004000EF2AAA7A01200200F3
+:1035E0007800F62AAB7820007871AA79AA7A0120AF
+:1035F00004009B786000AA785B7804001B781601B1
+:103600007810D34383700F00D470B4D04000122BD5
+:10361000B4C0D6707E0CB87065A0086084A0EFFBC3
+:103620000A60186001801A607F0C7C00147005A08D
+:10363000C000212BD470B4D04000222BB87006AC4F
+:10364000C000222B7810012B7C007E01A47186A182
+:1036500001004000542B7E0D7E020021112001004C
+:1036600012A2B4706820006806AC40003B2B1182A7
+:103670004000522B7810562B7800302B7E0C002106
+:103680001120010012A2B470682000686020086058
+:1036900084A0EFFB0A60118240004F2B7810562B5C
+:1036A0007800422BA77001007F0C7F027F0D7F0105
+:1036B0007C00E8AD0500AC7006ADC0005E2BA870C4
+:1036C00068207C007810B043C000082A7C70682015
+:1036D000747778104E42502C781092449B781000EA
+:1036E000146884A01F00BDC0AA781C6E4120010090
+:1036F000012004007800D92C7810B043C000082ABB
+:103700009B78100060706820146FD470B4D04000B3
+:10371000932BB4C0D6707E0CB87065A0086084A0EE
+:10372000EFFB0A60186001801A607F0C78104E422F
+:10373000502C78109244246805A04000A42B82A04D
+:1037400006004800A22B7800A42B27680500146807
+:1037500084A01F00BDC0AA783120200041200100B4
+:10376000012003007800D92C8DC2D672C07200A24D
+:1037700015A0547108812AA14800BC2BC071642196
+:103780000465FF85C000D32B56712184C000B72B80
+:10379000D4708CD04000CF2BD07005A0C000CF2BB0
+:1037A000D3700A007C0000227800C12BD4708CC03A
+:1037B000D670D3700000346005A0C000D02B08671D
+:1037C00084A73F074000022CD4D7C000D02B84A789
+:1037D0002100C000D02B84A702004000F32B84A757
+:1037E00004004000D02BBCA7FBFF0A6784A7180287
+:1037F000C000D02B84A700014000022C186005A057
+:10380000C000D02BBCA7FFFE0A6768252368000014
+:103810001C6E84A60E0018634000132C1C6002A3CB
+:103820004800162C4000162C7800D02BFF83C000D7
+:10383000D02B582D502C5671BCD7C0001F2C28708F
+:1038400022603A60BCC70A67C06865A04DA00061ED
+:10385000602A41200100146B9CA31F009DA3C0009F
+:10386000FCD14000332C84D64000352C9CA3BFFFF4
+:10387000A4D640003A2C9DA3200084A60E00C000D0
+:10388000852CA5C70A67002CC668A47786A7010007
+:10389000C000592CD470B4D0C000592C007082A044
+:1038A0000200C800592C3078BCD0C000592C9B783D
+:1038B0001000AA7B7800D12C3987A6775027B077E3
+:1038C000B0A70500AC7006A6C000642CA876B2763E
+:1038D0003A2C38873A2D38873A2838873A23388760
+:1038E0003A253078BCD040007C2C9120008091207B
+:1038F0003D30D47084A03D30912000809020D5AA26
+:1039000000004000842C21840022C000B62B7C00E3
+:10391000DCD14000493E292020009CD6C000922CDA
+:1039200028858CD6C000922C28854088146F0C61A5
+:1039300008818CA1FF00CC7060A1642CFF8C40003A
+:10394000B12C146006A7C0009A2CB8600180BA6040
+:10395000C000952C602A086085A000010A60002242
+:103960002184C000B62B7C00602A0E61BE69002C49
+:10397000C66840880860D5C00A60A47786A70100A1
+:10398000C000592CD470B4D0C000592C007082A053
+:103990000200C800592C3078BCD0C000592C9B784C
+:1039A0001000AA7BAA7DAA79012002007E0018607F
+:1039B00000801A607800DA2C7E0060290461602A99
+:1039C00084A118004000F62C84A110004000E92CCE
+:1039D00078105E40C0001B2D84A108004000F62C2A
+:1039E000A06984A10006C000F62C78103E3F780044
+:1039F0001B2DA06984A1001E4000262D84A1000873
+:103A000040000F2D7E0C6029006085A00020026020
+:103A100004618DA1100006617F0C78105E40C0002B
+:103A20001B2DA06984A100024000172D7810A13F32
+:103A300078001B2D84A10004C000F22CA06984A191
+:103A400000104000262D14698CA100FF0F81781012
+:103A5000E6277F028CA6E00084A660004000332D9C
+:103A600086A06000C000332D8DA100408DA104010F
+:103A7000B6699B7860000028AA781868FDC01A68AB
+:103A8000BCD640004E2DFCC0877000008AA00D00FF
+:103A900050004C2D8AA00C00867101200C000C8077
+:103AA0008A71AA781835403328340080AC8080AF02
+:103AB0002B00A0209B78000080AD0B009820A6531F
+:103AC000A8239828A02586A22000C000862DD470A7
+:103AD000B5C0D670002CBA70002DBE701468FCC042
+:103AE0000780827886A202004000BC2DA47000806E
+:103AF000A670B47498A40500AC7006A3C0007E2D17
+:103B0000A873B67386A210004000082A7F0D7F0CB0
+:103B10007C00007005A0C000642D86A20200C000D9
+:103B2000D62D7810B043C000642D1468FCC0078007
+:103B30008278912000801B785B00B4685A78946882
+:103B4000D678DE789868D278DA7891200180087883
+:103B50008DC00A787E127E0D7E0CD47084A0002762
+:103B600090207F0C7F0D7F1200295A70BC68427034
+:103B700003700200002D4E7080AD09004670307851
+:103B8000BCD04000C82D91203D30D47084A03D3081
+:103B9000912000809020A47005A0C000CD2D7C0055
+:103BA00021844000CC2D5072C07000A215A0780076
+:103BB000B62B86A21000C000072E7810B043C000BC
+:103BC000642D1468FCC0078082781B785B00B468A1
+:103BD0005A789468D678DE789868D278DA78087857
+:103BE0008DC00A78A4700080A670B47490A40500FB
+:103BF000AC7006A2C000FA2DA872B67200295A70E5
+:103C0000BC68427003700200002D4E7080AD090048
+:103C100046707C00B46B9DA300205A7B1468FCC0E6
+:103C200007808278946BD67BDE7B986ED27EDA7EBC
+:103C30001B785B0000295A70027208788DC00A78E0
+:103C4000002305A64000322ED47084A0002786A051
+:103C50000023C0002C2E0920000078002E2E092001
+:103C6000010084A20F007910382E80AD0900467043
+:103C7000002D4E707C00402E3F493F492C493F4962
+:103C8000402E402E402E7810B229087884A0FDFFE7
+:103C90000A787810A5297E0F7920004FAC787F0F25
+:103CA00084D040006A2E647086A00100C000582EA7
+:103CB00066707800412F647086A00500C000682EF1
+:103CC0007C7068201B68040017680000206884A0CE
+:103CD000FF009DC0226867700000A7700000A870F8
+:103CE000B270B6707810012B7E151120040064713B
+:103CF00086A1010040008A2E86A10700C000812E07
+:103D00001F70050078008A2E1F7001006770000088
+:103D1000D470DDC0D67078008C2E67700000012052
+:103D20000A4F042084A0FF0086A0180040009C2EAB
+:103D30001870167005A0C0009C2EA77001007E06AA
+:103D40007810D645A920100039200000781048418D
+:103D5000B8A70001F000A32E7F0600707900AD2EF9
+:103D6000E72EC22EC22EB72EE72EE72EE72EB52E57
+:103D70007810B229607005A04000E72E06ADC000A3
+:103D8000C22E006862707800D42E206884D0C000F3
+:103D9000D02E146F78104E420860D4C00A6078109C
+:103DA000193E7800D42E5C7060200068026084A602
+:103DB000005F1E681868FCD04000DC2E1A6A176885
+:103DC00000002B680000206884A0FF009DC02268CE
+:103DD0007810732084B200044000EF2E2120D0968A
+:103DE0007800F12E2120C0957810462F84B200046F
+:103DF0004000FB2E2120984F7800FD2E2120584FA7
+:103E00007810462FA920010184B200044000092F38
+:103E10002120D09578000B2F2120C0947810462FB8
+:103E20002084F0000B2F84B200034000182F612083
+:103E3000C05478001A2F6120C07421200200A920EC
+:103E400000011061FF814000372F18607E017E0065
+:103E50001120024F0C2202A112207F007F0102A13B
+:103E60005000372F1260C000372F1120044F04225A
+:103E7000A5C012201B600000E0AC1000F0001E2F57
+:103E80002184C0001C2F7F15037000004F700000BC
+:103E90007C007E04042405A04000612F6820006897
+:103EA0007E001A6A176800002B680000B46884A0BE
+:103EB000005F1E68206884A0FF009DC02268781003
+:103EC00073207F007800482F7F04232000007C00AF
+:103ED00082A2030050006B2F7810B22900237900D2
+:103EE0006E2F712FFC2F193082A202004000772F15
+:103EF0007810B22964706770000083700000790048
+:103F00007E2F862F862F882FC82F553E862FC82FAD
+:103F1000862F7810B2297477781048417477BCA73F
+:103F2000008F78104E42186005A04000BF2FFCD7CC
+:103F3000C0009B2F2120C09578009D2F2120D09676
+:103F40000920050011201000781034304000BF2FE8
+:103F50007E15A9200101FCD7C000AF2F2120C094FD
+:103F60007800B12F2120D0957E0409200500112072
+:103F70001000781034307F044000BE2F2084F00001
+:103F8000B12F7F15388784A71F00C0008E2F7800BF
+:103F90000C2A78000C2A747778104E42186005A01D
+:103FA0004000FA2FFCD7C000D62F2120C095780002
+:103FB000D82F2120D096092005001120200078104C
+:103FC00034304000FA2F7E15A9200101FCD7C00033
+:103FD000EA2F2120C0947800EC2F2120D0957E0478
+:103FE0000920050011202000781034307F044000A3
+:103FF000F92F2084F000EC2F7F1578000C2A002286
+:104000007900FF2F0230043004307810B2290920E3
+:104010001200647086A0020040000D3009200E00DE
+:104020001868FCD0400012301A6967700000D47024
+:10403000DDC0D67078005D43002279001C3021304D
+:1040400004301F307810B2297810D645007086A051
+:104050000200C000C73D7810363E086084A0EFFB28
+:104060000A607810B83D4000C73D78000C2A04244F
+:1040700005A040006D306820042D7E00146806A75E
+:1040800040004330202D7F00780035307F00222013
+:104090001A69176800002B680000B46884A0005FEC
+:1040A0001E68206884A0FF0005A222687810732093
+:1040B0002120024F1C2419832223106001801260EA
+:1040C000C00064302120044F0424A5C022200860D1
+:1040D00084A0EFF90A607810222B7810363E7C001D
+:1040E00085A0010078006C300023790074307930AD
+:1040F0007730F9307810B229E47805A0D000AF30DD
+:1041000008327E000120044F0420ECD07F004000E4
+:104110008A308CA1000378008C308CA10004400010
+:1041200092301800082A780094302800082A0820C5
+:1041300084A03000C0009B307800B937EC7884A0B0
+:10414000030040009930002184A007007900A530C9
+:10415000D930E330CE30AD30A543A543AD30EE309D
+:104160007810B229007086A00400C000C9306470C5
+:1041700086A00200C000BF301120020019200000FC
+:104180007800652F647086A006004000B930647026
+:1041900086A004004000B930E479012003007800D3
+:1041A00043341868FCD04000D4301B681D007810E0
+:1041B00018411B7864007C001868FCD04000DF3098
+:1041C0001B681D0078101841780081431868FCD0E6
+:1041D0004000E9301B681D00781018411B78F8007A
+:1041E0007C001868FCD04000F4301B681D0078107B
+:1041F00018411B78C8007C0084A50F00C00018314E
+:104200007810A5290070790002310C2A0A310C318E
+:10421000C73DC73DC73D0A310A317810B229781031
+:10422000363E086084A0EFFB0A607810B83D40007D
+:10423000C73D78000C2AE47805A0D000AF300832E2
+:104240007E000120044F0420ECD07F004000293183
+:104250008CA1000378002B318CA100044000313187
+:104260001800AF30780033312800AF30082084A028
+:104270003000C0003B311B785B007C00EC7884A0F0
+:10428000030040003831002184A107007900453146
+:10429000543158314F314D31A543A5434D319F43E2
+:1042A0007810B229781020411B7864007C007810C7
+:1042B000204178008143781020411B78F8007C0071
+:1042C000781020411B78C8007C00002379006531FC
+:1042D0006A3168316C317810B2297800A8391B68CE
+:1042E0001600A3780000E47984A130004000A839CA
+:1042F000EC7884A003004000A83984A100014000AC
+:10430000703184A10700790082318A315831CE3072
+:104310005D43A543A5435D439F43781069437C00FB
+:1043200082A20500500093317810B2290023790051
+:1043300096319931C933D433002279009C31B6319A
+:10434000A331B631A131AC337810B2299B78180073
+:10435000A87884A0FF0082A02000480007418AA01E
+:104360000400C80007417900B23107410741074105
+:10437000B1409B781800A87984A180004000C73123
+:1043800078000741007005A0C000BD311120040075
+:104390007800933B84A1FF008AA01000C800074169
+:1043A0007900CF31E131DF31F631FA31CD320741D9
+:1043B0000741CF3207410741A833A83307410741DE
+:1043C0000741AA337810B229E4D64000EC3101202D
+:1043D0000003008000803A781B78C3007C001868D6
+:1043E000FCD04000F4311B681D007800E4317800F7
+:1043F0005D431B681D00780011412069226984A675
+:104400000018C0005F32206884D0C0006532186890
+:1044100086A00800C0000B321B680000D4D6400004
+:10442000CA32BCD640004B3287700000186884A0A6
+:104430003F008AA00D0050004B328AA00C0086710C
+:1044400001200C000C808A719B786100AA787E158F
+:104450007E137E147E0108328CA1000340003D32A1
+:104460007E000120044F0420ECD07F004000393250
+:10447000A1202B0178003F32A1202B0278003F328F
+:10448000A1202B017F019B7800000080AC8080ADD3
+:104490000B009820A6537F147F137F15386005A06A
+:1044A000C0005A321C6884A00E00400011417810F0
+:1044B00027412B78083078005C3201803A601B7805
+:1044C00067007C00E4D6400065321B7879007C00F0
+:1044D00084A660004000C732DCD64000C732FCD65C
+:1044E000C000713278008832FCC65A7EB66EDC7A23
+:1044F000D879D0781B80C8007B32008084A03F0030
+:1045000008A191A20000986B002102A3B268946BED
+:10451000002203A3AE68F4D640008E32F4C65A7E61
+:10452000B66E007086A00300C0009C327E0078103A
+:10453000D64578103F497F001B7876007C0006A0A6
+:104540007810444AB06AAC69986C946B002205A15B
+:104550004000AB32002222A400211BA3AA6CD27C13
+:10456000DA7CA66BD67BDE7B002305A4C000BB32C1
+:10457000F5C65A7EB66E1B7876007C001B787600F6
+:10458000002215A1C000C43278103F497C00781089
+:1045900077497C001B7879007C001B7867007C00E1
+:1045A0007810B22978001B332069C4D14000E4326E
+:1045B000C4C122697E0C587060200060E4C00260B3
+:1045C000046084A0F5FF06607F0C78000F33CCD127
+:1045D00040000F33CCC122697E0C5870602000600F
+:1045E000ECC002600460A4C006600820482C7F0C68
+:1045F0009CD140000F3378104A4278103E3FFF882C
+:1046000040000F339B7860000028AA78587E95C63A
+:104610005A7ED4D6C0000C331B7864007C001B7813
+:1046200078007C00587ED4D6C00016331B78670013
+:104630007C001B7879007C0078000C411920000078
+:1046400090798CA10700C0002933206884A0000164
+:1046500040001933092008009B781000A87894A026
+:10466000FF0086A20100C00045330023A87C00A4FF
+:10467000182002A140003D3348003D3378003F330D
+:104680007800D132A824A87AF0003F3378002B3389
+:1046900084A2F00086A02000C000993318831883FC
+:1046A000002302A14000553348005533780096336B
+:1046B00086A22300400019331C6884A0F1FF1E6805
+:1046C000587E84A6F1FFA5C030205A7E0860A5C0A0
+:1046D0000A607E0C5870602004600820482C7F0C13
+:1046E000A4D14000763378104A4278105E407800BA
+:1046F00084337E0C5870602004600820482C7F0CA6
+:104700009CD140000F3378104A4278103E3FFF881A
+:1047100040000F339B7860000028AA7895C65A7E27
+:10472000D4D6C00093331B7864007C001B787800DB
+:104730007C00A87A78002B331883002302A1400064
+:10474000A2334800A23378002B3384A28000C0003B
+:10475000114178000C4178001141780007415870F0
+:104760004DA09B781800A87884A0FF008EA00100BF
+:104770004000B9337810B229A87A94A2FF00A87833
+:1047800084A0FF008AA00400C80007417900C53357
+:1047900007418F3E0741064082A20000C000CF3390
+:1047A0007810B229781018411B7878007C0082A21A
+:1047B0000300C000DA337810B229FCD4C000FA3309
+:1047C000647005A04000E3337810B229146F767747
+:1047D000BCA7008F78104E42086085A021000A60B7
+:1047E000388784A71F00C000E73378101C4167702A
+:1047F00002001F7009007800FC3378102B411B78F1
+:1048000078007C0082A20400500005347810B229A0
+:104810000023790008340B34CB350E3686A2030012
+:10482000400043340072D87CDC7DD07FD471BCD191
+:10483000C0003B34B4D140003B34687884A0FF0012
+:10484000C0003B3482A20200C8003B347E0D3B789E
+:1048500000831B784C00BC706DA0B4685A789468D3
+:10486000D678DE789868D278DA78B4C1D6710370D9
+:1048700030007F0D01200000780047343B780013A2
+:104880001B784A0001200000780047340072D87C71
+:10489000DC7DD07F4A70A068ECD040004F340860C7
+:1048A0008DC00A6084A20F0079005334AB356034A8
+:1048B0005D3411379D370C2A5B345B347810B22994
+:1048C0000860D4C00A60E4D640006834487086A00E
+:1048D0001400C00088347810D645092000001868FC
+:1048E000FCD040007134487086A01400400082342F
+:1048F000186886A00800C000633558789CD0400036
+:1049000063352068ACD0400063351B681400092073
+:1049100002007800C73468788CA0FF004000C734DC
+:1049200086A10800C0009E340860A4C00A60781008
+:10493000B83D4000C7347810363E7810D645780030
+:10494000AF3486A12800C000C734186005A040001D
+:1049500091340180400091340180400091341E6008
+:1049600078009134206884D040000C2A84C02268EA
+:104970007810132B5C707E0C6020006802607F0C46
+:104980000460026805A0002DC000C4340260066007
+:1049900078000C2A7E01FF81C0001135007086A0CE
+:1049A000300040001135D471BCD1C0001135B4D1F4
+:1049B000C000F834607005A0C0001135A47086A056
+:1049C000010040001135037000007E047E057E0763
+:1049D0007E067E0C7E0D7810352A7F0D7F0C7F06BB
+:1049E0007F077F057F04D471B4D1C00011350370F7
+:1049F0004000780011357810B043C00011351B78A5
+:104A00005B007E0DBC706DA0B4685A789468D6784F
+:104A1000DE789868D278DA78B4C1D6710370300045
+:104A200008788DC00A787F0D781048367F01FF81A5
+:104A30004000633584A600DF1E682B680000146FF9
+:104A400086A10200C0006435186886A01400C0006A
+:104A50002D350820E4D640002D3568788CA0FF0065
+:104A60007810012B7810222B2068DCD0C000643530
+:104A7000178794A20F0013821382138284B200035B
+:104A80004000433590A2C0537800453590A2405471
+:104A900090A200001C22C4D3C0004D3578005335CD
+:104AA0001082042285A0180012201182D4D3400065
+:104AB0005E35A068C4D0C0005E357810C23678007C
+:104AC0000C2A08608DC00A60780064352A6916696E
+:104AD0001868FCD040006B3548701A688CA600DF5F
+:104AE0001E691064FF84400080350920024F0421B4
+:104AF00001800A2021841264C00080352120044FE7
+:104B00000424A5C02220186005A04000883501803B
+:104B10001A60C0008B350860A4C00A60206884D089
+:104B2000C0009735006805A0C0009435026006609B
+:104B300078009B355C706020006802606120004F47
+:104B400087680301082D6B200000686005A06A617A
+:104B50004000AA35022D7800AB356E61007286A246
+:104B600030004000BB3586A24000C0000C2A037014
+:104B700002004C706820C46860207C000370020052
+:104B8000BC706DA0BC684270B87065A0C0685A70F7
+:104B9000002D4E7080AD090046707C0082A204009A
+:104BA0004800D1357810B22900227900D435D835A3
+:104BB000E935F635E93586A500134000E93586A5C7
+:104BC0000083C000CF3503700000186001801A60B8
+:104BD000086084A0EFFB0A60007086A0050040001A
+:104BE000F335781018411B7878007C001B78790029
+:104BF0007C0090780780018084A0070080A01800C6
+:104C00009A78A8798CA1FF0086A1030040000B369A
+:104C100086A1000040000B36780007411B78790020
+:104C20007C00206895C02268FF82C000183678108A
+:104C3000184178001F36118240001D367810B229C5
+:104C400078102B411B7878007C007810D3433078A3
+:104C500084A0C000C00045367E0108327E000120DD
+:104C6000044F0420ECD07F00400037368CA10003B5
+:104C7000780039368CA100047F01400040361800CE
+:104C8000453678004236280045361A7906A07C0061
+:104C900085A001007C0084A66000C00052362F6809
+:104CA0000000336800007800C136DCD6C0006A36E8
+:104CB000B468DCD0C0006A369869946A2E69326A9A
+:104CC000487005A0C0006736002205A14000D64507
+:104CD0004B7015007800D6457C00ACD6400090366D
+:104CE000F4D6400076362F68000033680000780064
+:104CF000D645B46884A0004035A6F4D6C00070360E
+:104D0000487005A0C00083364B701500DCD6C0008B
+:104D10008C36B468DCD040008C36A86CA46D2E6C48
+:104D2000326D7800D645F4D6400099362F680000E1
+:104D3000336800007800D645B46884A0004835A6E2
+:104D4000F4D6C0009336487005A0C000A6364B705C
+:104D50001500082410250027FB80C800AD36008010
+:104D600084A03F0008A191A200002E69326A0021B0
+:104D700005A2C000BA367800D645007086A00600AD
+:104D80004000C1367800D6457C0046690860CDC039
+:104D9000CCD34000C9368DC00A6018683A681B68D9
+:104DA00006008F68000093680000306A2C693E6A34
+:104DB00042692F6803003368000037682000976855
+:104DC00000009B68200000707900E3360C2AF5365D
+:104DD000ED36EB36EB36EB36EB36EB367810B229A8
+:104DE000206884D0C000F5367810193E7800FB3674
+:104DF0005C70502C602000680260602A08328CA130
+:104E00000003400004372120584F78000637212046
+:104E1000984F042405A040000D3720207800063765
+:104E2000222D6B2000007C007810203E7810363E4A
+:104E30000860CCC00A602B6800009B780E00146FDD
+:104E400038691A694469166908328CA10003400068
+:104E50002A370920000078002C370920010078103B
+:104E6000814ADCD6400034371C69EDC11E691868E0
+:104E7000FCD04000433768788CA0FF0040004137E9
+:104E80001B681E00780043371B68000084B20003D3
+:104E9000C0004B372120984F78004D372120584FC4
+:104EA000006822203C6A4069326A2E69C06860202E
+:104EB0000060A4D040008D3741202100492005002A
+:104EC000512020007E0D7E0F7E157E147920004F2C
+:104ED0007810461E7F147F157F0FCC70102009209C
+:104EE00001017E0204226DA040007D37146806A7F0
+:104EF00040007A370068780070372068D5C0226893
+:104F00007F0210820981C0006E377F0D6770030039
+:104F10007F700000767783700F00D471DCC1D6718A
+:104F2000186886A00200C0009937176800002B6837
+:104F300000001C68ECC01E687810732078000C2AF2
+:104F4000D87CDC7DD07F781048362B6800009B78B9
+:104F50000E00146F7810D7438CA0FF0016691868F4
+:104F6000FCD04000B23748701A688CA600DF1E697A
+:104F70006770000078000C2A007005A0C000BF37E1
+:104F800078000C2A06A07810D6452069ACD1C00064
+:104F9000C8371B6814008CA600DF1E692B68000050
+:104FA000206884A0FF00226800707900D4370C2AA2
+:104FB000DE37DE37E137E137E137DC37DC377810D1
+:104FC000B2291868780043340860A4C00A601768E2
+:104FD00000007800DE3D00237900EB37EE37F03734
+:104FE00060387810B229FCD6C000473800700DA098
+:104FF0007900F7370C2A0138013831380138443844
+:10500000FF37FF377810B22984A66000400031389E
+:1050100086A06000C0002E38ACC6F4C6EDC65A7E2D
+:10502000B66E1C68ACC01E6886A102004000203825
+:105030007810D645AC69B06815A1400020387810CA
+:1050400077497800223878103F491B787900D4716D
+:10505000B4D1C000082AA47086A00100C000522A62
+:105060007C00ECD640000B381868FCD04000443877
+:10507000F4D6C0003E381B6815001B787900780014
+:10508000082A1B6807002F680000336800007810AA
+:1050900069437C00FCC65A7EDC7AD879D0781B80C4
+:1050A000C8005038008084A03F0008A191A20000F1
+:1050B000986B002102A3B268946B002203A3AE6830
+:1050C0001B7879007C007810B229002379006538BC
+:1050D0006A388F38EF387810B229007079006D384F
+:1050E000753877388038753875387538753875384B
+:1050F0007810B229AC69B06815A1400080387810EA
+:1051000077497800823878103F491C68B4C01E681F
+:10511000D470B4D0C000082AA47086A00100C000DA
+:10512000522A7C00FCD6C000DF3800700DA0790048
+:1051300096380C2AA638A038D638A638DC389E38DF
+:105140009E387810B2299468D678DE789868D2783C
+:10515000DA7884A660004000D63886A06000C000DF
+:10516000D338B4A6BFBFEDC65A7EB66E86A1020084
+:105170004000C2387810D645AC69B06815A140002F
+:10518000C238781077497800C43878103F491B78C6
+:1051900079001C68B4C01E68D471B4D1C000082A5C
+:1051A000A47086A00100C000522A7C00ECD640000A
+:1051B000B0381868FCD04000DC381B6807001B784A
+:1051C000F9007C00FCC65A7EDC7AD879986B002105
+:1051D00002A3B268946B002203A3AE68D2791B7855
+:1051E00079007C00DCD64000F8382B7809301B7839
+:1051F00079007800082A8478ACC08678E47884A0A6
+:105200000800C0000B3984A4000240000539F5C62F
+:10521000DDC65A7E1B7879007800082A206895C080
+:1052200022687810E242DDC6781018411B787800B9
+:105230007800082A002379001A391D391F392139CD
+:105240007810B22978001141D4D6C0005C39E479D5
+:10525000ACD140002F39EC7884A0030040002F39F6
+:105260002B7809309B786000AB78000084A6FBFFA8
+:105270005A78E479ACD140003F39EC7884A003003F
+:10528000C00058390120044F0420E4D0C000543934
+:105290002068C4D0400054397E0C587060200460EF
+:1052A0009DC00660086084A0FF000A607F0C01209A
+:1052B00014007800433484A1070079009239907A71
+:1052C00094A207009B786000A879FF814000903984
+:1052D0009B781000A87B84A30100C0008339A87BC1
+:1052E000A87B86A30100C00076390920F7FF78006B
+:1052F0007C3986A30300C00083390920EFFF7E0CB0
+:1053000058706020046004A106607F0C9B786000E8
+:10531000AB78000084A6FBFF5A782B78093020690F
+:105320008CA1FFFC226978005D43D930E3309C39C1
+:10533000A2399A399A395D435D437810B2292069C0
+:105340008CA1FFFC22697800634320698CA1FFFCDB
+:10535000226978005D43E47984A130004000B239CD
+:10536000EC7884A00300C000E639007086A0040039
+:10537000C000CC39647086A00200C000C239112080
+:105380000200192000007800652F647086A00600D6
+:105390004000BC39647086A004004000BC39007035
+:1053A00086A000004000082A206984A12004400053
+:1053B000DB39D4C1226918687800433418688EA09C
+:1053C00002004000E439FDC01A6801201400780092
+:1053D000433484A107007900EA395D435D43F23923
+:1053E0005D43A543A5435D435D43BCD64000343ACD
+:1053F0008471FF814000343A82A10D00D000013A4F
+:10540000877000007800063A82A10C00867009209F
+:105410000C009B786100AA797E157E137E1488703B
+:10542000148110A28A7280A00B0000AD982084B273
+:1054300000034000283A7E000120044F0420ECD0F5
+:105440007F004000243AA1202B0178002A3AA120B5
+:105450002B0278002A3AA1202B019B7800000881BA
+:10546000AC81A6537F147F137F1578006343D4D695
+:10547000C000883A206884D0400063438CA6600056
+:1054800084A660004000463A86A06000C000463A0C
+:10549000F5C194C15A79B6699B786000AB78000079
+:1054A0009B7861001868FDC01A68AA7808800C8192
+:1054B00040004F3E8CA1F800C0004F3E7E157E1389
+:1054C0007E147E0108328CA100034000743A7E00F5
+:1054D0000120044F0420ECD07F004000703AA1204E
+:1054E0002B017800763AA1202B027800763AA12091
+:1054F0002B017F019B7800000080AC8080AD0B0009
+:105500009820A6537F147F137F151468FCC0078072
+:105510008278780063431868FCD040008E3A1B689C
+:1055200008002068ADC02268781020411B78EA008E
+:105530007C0000237900993A9E3A763B9C3A781099
+:10554000B229D87CDC7DD07FFF82C000C73A0072D0
+:1055500086A2030040001034D471BCD1C000CA3A06
+:10556000B4D14000CA3A7E0D3B7800881B784C00CD
+:10557000BC706DA0B468A5C05A789468D678DE78FF
+:105580009868D278DA78B4C1D671037030007F0D94
+:105590007800CE3A00727800CE3A3B7800181B783B
+:1055A0004A0084A20F007900D23A613B103BDC3AFA
+:1055B0003F34DA3A613BDA3ADA3A7810B2291C68B9
+:1055C000ECD04000E33A08608DC00A60206985C1D4
+:1055D00022690068066005A0C000EC3A026008601D
+:1055E000D4C00A601C6884A00E00C000003B84B2D6
+:1055F00000034000FC3A0920C0957800053B0920D3
+:10560000D0967800053B3070BA684071CC7008A124
+:10561000042102680A2D5E71DCD6C000103BFCC676
+:10562000B66E7800613BB66E84A66000C0001A3B7F
+:1056300084A6FF7FB6687800613BDCD6C000283BBB
+:1056400084A6FF7FB6689468A6689868AA687810F0
+:10565000D6457800613BACD64000343B06A07810BC
+:10566000D64508241025AA69A66A7800443B082478
+:10567000102500271B80C8003B3B008084A03F0012
+:1056800008A191A20000AA69A66A7810D645FCD6A6
+:105690004000613B84A6FF7FB66810250824ACD685
+:1056A000C000593B00271B80C800543B008084A0E9
+:1056B0003F0008A191A20000986B002102A3B268EC
+:1056C000946B002203A3AE68007086A03000C00077
+:1056D0000C2A03700200BC706DA0BC684270B870E8
+:1056E00065A0C0685A70002D4E7080AD09004670EC
+:1056F0007C0086A50088C000833B03700000186012
+:1057000001801A60086084A0EFFB0A6078001141F4
+:105710004770000082A2060050008D3B7810B2292D
+:1057200000237900903B933BA53BB13B00227900DD
+:10573000963B9C3B11419E3B9C3BEB3B403C781095
+:10574000B229807A94A2000F7810CA3C78000741F1
+:105750007810C23B7900A93B1141AF3BAF3BEB3B1B
+:10576000AF3B11417810B2297810C23B7900B53BAC
+:10577000BD3BBB3BBB3BBD3BBB3BBD3B7810B229FC
+:1057800078102B411B7878007C00007086A0020006
+:10579000C000D33B7810363E7800CD3B7810D6451C
+:1057A000086084A0EFFB0A607800D83B007086A0F8
+:1057B00003004000CB3B0370050084B200034000AF
+:1057C000E23B0120E0967800E43B0120129768203C
+:1057D0004E7080AD0900467000227C00007086A0EB
+:1057E0000200C000FD3BD470B5C0D670002CBA706A
+:1057F000002DBE707800023C7810D6457800023C3F
+:10580000007086A003004000F93B03700100807A1D
+:1058100094A2000F9B781800A87C84A41F0015A2F6
+:105820006920C09584B20003C000163CFDC2692007
+:10583000D096042D082D5E716DA04000233C1468A5
+:1058400006A24000253C00687800173C7810CA3C4E
+:10585000B46E5A7E206984A1000C4000F43C647050
+:1058600086A00600C000373C747006A2C000373C1A
+:1058700066707E701B680500ADC1D4C122697810C6
+:1058800020417800F43C007286A20200C000523C25
+:10589000D470B5C0D670002CBA70002DBE707800E0
+:1058A000563C7810D6457800563C86A2030040004E
+:1058B0004E3C03700100807A94A2000F9B78180080
+:1058C000A87C84A41F0015A284B20003C000663C1B
+:1058D000FDC2A879A8798CA1FF001821CC7068A11D
+:1058E000042D082D5E716DA040007A3C146806A25C
+:1058F0004000A33C006878006E3C0370050084B251
+:1059000000034000843C0120E0967800863C0120A2
+:10591000129768204E707E15A920320003200000E7
+:105920000080F0008B3C7F1584B200034000983C5F
+:10593000FCC27800993CFDC2166A80AD0900467031
+:10594000B76800072368000827680300B46E206961
+:1059500084A1000C4000F43CDCD04000BF3C6470EB
+:1059600086A00400C000BB3C747006A2C000BB3C13
+:10597000787006A3C000BB3C66707E70781027412B
+:105980007800F43C1B680500ADC1D4C122697810D1
+:1059900020417F7000007800F43C0370050084B261
+:1059A00000034000D43C0120E0967800D63C012062
+:1059B000129768204E707E15A92032000320000047
+:1059C0000080F000DB3C7F1584B200034000E83C1F
+:1059D000FCC27800E93CFDC2166A80AD0900467041
+:1059E000B768000723680008276803007C00ECC63E
+:1059F000ACA660004000463D986B946CAC69B06802
+:105A000005A1C000213DD27BDA7BD67CDE7C86A559
+:105A1000600040004B3DF4D6C0000C3DEDC6B4A67E
+:105A2000FFB75A7E092079009CD64000193D092015
+:105A300078001920000020231A79ECD64000563D4A
+:105A400078103F497800563DB0681AA3002123A47E
+:105A5000002405A340004D3DD27BDA7BD67CDE7C62
+:105A6000B068F4D6C000323DEDC6F4C65A7E1120AF
+:105A700079009CD640003E3D11207800192000009E
+:105A800020231A7AECD64000563D781077497800EA
+:105A9000563D19200000202378004D3DB4A6FFB7E5
+:105AA0005A7E092079009CD64000553D0920780097
+:105AB0001A79C0685A70002D4E70C4686020D47185
+:105AC0000120014F0420C4D0C000AB3DD8702DA0F0
+:105AD0004000843DBCD140009E3D807A94A2000FDE
+:105AE000DC7006A24000753DE07804A5C000AB3D27
+:105AF000DA70BCC1D6717800AB3D312001002C8535
+:105B00004800833D3386108278007C3D7C00E07D38
+:105B100094A500FF4000913D112008002F857810CA
+:105B20007A3D37867800933D78107A3D17828078E9
+:105B300084A0000F06A24000AB3DDE72DA7678004A
+:105B4000AB3D807A94A2000FDC7036A240009B3DF2
+:105B5000E07834A540009B3DBDC1D671B4D1C000F2
+:105B6000082A002305A44000082AA47086A001008A
+:105B7000C000522A7C00206005A04000C63D018084
+:105B80002260086085A008000A600F7000012C7078
+:105B900026607C0006A07810D645007086A0020022
+:105BA0004000D43D647086A00500C000DE3D2B6837
+:105BB0000000176800001B680100236840001F6890
+:105BC0000001007084A00F007900E33D0C2AF33D32
+:105BD000ED3D153EFD3D0C2AEB3DEB3D7810B22925
+:105BE0007810203E7810193E7800F93D7810203E5C
+:105BF0005C706020006802607810732078000C2AC6
+:105C0000647067700000837000007900043E113EEC
+:105C1000113E0C3E0C3E0C3E113E0C3E113ED47724
+:105C2000DDC7D67779007E2F6770000078000C2AD8
+:105C30001B68000078001137006805A0C0001E3EF8
+:105C4000026006607C001064FF844000323E092040
+:105C5000024F042101800A2021841264C000323ED8
+:105C60002120044F0424A5C022200860A4C00A609B
+:105C70007C00186005A040003C3E01801A607C005A
+:105C80007810D3431B68180078007D3E7810D3430A
+:105C90001B68190078007D3E7810D3431B681A00FA
+:105CA00078007D3E7810D3431B68030078007D3E6A
+:105CB000747778104E4278718CA1FF00103294A254
+:105CC00000034000643EE8A1C0947800663EE8A16D
+:105CD000D095042D082D682005A0C0006F3E7E7071
+:105CE00078000C2A1468747206A24000773E00689F
+:105CF0007800673E00680A201B6805007F7000007E
+:105D00007810203E206884D0C000853E7810193E6F
+:105D10007810363E1F68000023682000781073203A
+:105D200078000C2A82A20300C0000741A87DACA520
+:105D3000FF005A7EA87EB4A6FF002069BDC122697B
+:105D4000C4D14000EA3EC4C12269B4A6FF004000AD
+:105D5000D73E82A60C004800AE3E4000AE3E312049
+:105D60000C00002586A00A004000B53E2B852B853F
+:105D70007810E0414000BD3E7810BC3F7800E03E26
+:105D800078109B417E0C6029046084A0F5FF0660BA
+:105D90007810F23F7F0C2069C5C12269587E95C6F4
+:105DA0005A7ED4D6C000D43E1B7864007C001B7899
+:105DB00078007C007E0C6029046084A0F5FF0660FA
+:105DC0007810F23F7F0C587ED4D6C000E73E1B7897
+:105DD00067007C001B7879007C007E0C5870602086
+:105DE0000061E4D14000333F0862178294A2FF00B3
+:105DF00082A20C004800FD3E4000FD3E11200C0038
+:105E0000002602A2C800023F3022086294A2FF00CE
+:105E10000120054F0420E4D0C000173FEC78E4D007
+:105E20004000173F82A20A00C8001D3F11200A004F
+:105E300078001D3F82A20C00C8001D3F11200C00FD
+:105E4000002202A5C800223F282278109F41002589
+:105E500086A00A0040002B3F2B852B857810E0415F
+:105E60004000333F7810BC3F7800373F78109B41AB
+:105E70007810F23F587895C05A787F0C1B787800DC
+:105E80007C007E0C60290060E4D0C000583FB4D094
+:105E9000C000523F106084A00F00C000523F046158
+:105EA0008CA1F5FF06617F0C7C00112032001920C7
+:105EB00000007800833FA068CCD0C000523F086249
+:105EC00094A2FF000120054F0420E4D0C000713FE0
+:105ED000EC78E4D04000713F82A20B00C800713F13
+:105EE00011200A007800773F82A20C00C800773F9B
+:105EF00011200C0008631F839CA3FF0082A30C00E9
+:105F00004800833F4000833F19200C00AB7801001C
+:105F1000AB780300AB780100AA7AAA7BC0A8050081
+:105F20002068C5C02268D470B4D040009F3FB4C080
+:105F3000D670B87065A0086084A0EFFB0A60186096
+:105F400001801A607F0C7C007E0C602904618CA1AA
+:105F5000F5FF066111203200192000007800AD3FE6
+:105F6000AB780100AB780300AB780100AA7AAA7B7A
+:105F7000C0A805002068C5C022687F0C7C007E0C8C
+:105F80005871602118208CA020004000C53FACC093
+:105F9000082084A0F0FF35A6867E18609A78AE7E31
+:105FA0001266A47884A0F0FF8CA10F0005A1F4C0B4
+:105FB0009CA320004000DB3F85A00040FCC0B4D083
+:105FC000C000E03FFDC0A67816608A78B4A60F0036
+:105FD00037860482048084A0FF0005A60E6004605A
+:105FE00084A0F5FF06607F0C7C007E0C587060205A
+:105FF00018609A78A47884A0F0FFA678126084785C
+:1060000084A0F0FF86780C6084A0FF000E607F0CF7
+:106010007C0082A20200C0000741A87A2069BDC1AD
+:106020002269CCD140004140CCC1226994A2FF003A
+:1060300082A20200C8000741781094407810F23F15
+:1060400080A901000C2078104A4278103E3FFF885A
+:10605000400037409B7860000028AA78587E95C69B
+:106060005A7ED4D6C00034401B7864007C001B7874
+:1060700078007C00587ED4D6C0003E401B78670074
+:106080007C001B7879007C0082A20200C800494095
+:1060900084A2010040005240587188A100000C21E8
+:1060A000ECD1C00052401120000078107C417810E3
+:1060B00094407810F23F587895C05A781B78780051
+:1060C0007C007E0C7E026029006011200100ECD073
+:1060D000C0007540BCD0C00073401460B4D0C00094
+:1060E0007340A4C1066106A0780091401120000011
+:1060F000AB780100AB780200AB780300AA7AC0A8A5
+:106100000400D470B4D040008D40B4C0D670B870D4
+:1061100065A0086084A0EFFB0A60186001801A6027
+:10612000206885A0000222687F027F0C7C007E0C24
+:1061300058706020FF8240009C4011204000186091
+:1061400080A002009A78A47884A0BFFF05A2FCC0BA
+:10615000B4D0C000A940FDC0A67816608A7804605B
+:10616000A4C006607F0C7C007E00007086A0030047
+:106170004000BA407F007800BD407F0078000441B5
+:10618000ACD640000441887884A04000400004411F
+:10619000B87B84A33F001B83C800CC40008005A0CF
+:1061A0004000E1401B83C800D54001804000014110
+:1061B000F4D64000E140B8781B80C800DD40008084
+:1061C00084A03F00C0000141F4C65A7ED879DC7A31
+:1061D0000120010008A1C800EC4091A20000D27982
+:1061E000DA79D67ADE7A7810444A1B78760084B25F
+:1061F00000034000FC40012000007800FE40012028
+:1062000001007810CE487C001B7876007C001B785B
+:1062100079007C0078102F411B7878007C00781082
+:1062200018411B7878007C00276802007810204114
+:106230001B7878007C0001200500780031410120A6
+:106240000C00780031412068D5C02268012006008A
+:106250007800314101200D00780031410120090012
+:1062600078003141012007009B787E00AA789DC606
+:106270005A7ED470B4D040004741B4C0D6707E0C72
+:10628000B87065A0086084A0EFFB0A601860018008
+:106290001A607F0C7C007E073F87BCA70F003B87FE
+:1062A0003B8703877E018CB2000340005841E0A089
+:1062B000C05378005A41E0A040547F01B8A72000A5
+:1062C0009A7FA47984A10F0040006A4184A1F0FF65
+:1062D000A678126004609DC00660388738879A7F70
+:1062E000A47984A1400040007A4184A1BFFFFDC091
+:1062F000A67816600460A5C006607F077C009B78C6
+:106300001000AB780100AB780200AB780300AA7AEA
+:106310009B786000AB780400D470B4D040009A4100
+:10632000B4C0D6707E0CB87065A0086084A0EFFB86
+:106330000A60186001801A607F0C7C003120000028
+:10634000292032009B781000AB780100AB78030065
+:10635000AB780100AA7DAA7E9B786000AB7805002F
+:10636000D470B4D04000BE41B4C0D6707E0CB870BA
+:1063700065A0086084A0EFFB0A60186001801A60C5
+:106380007F0C7C007E15078084A0FF0003800380C3
+:1063900080A020009A78A4798CA1F0FF21203342BC
+:1063A00019201100A9200E0011203200042484A01D
+:1063B000F0FF06A14000DE412084002310A2F0007F
+:1063C000D3417F157C007E150120054F0420E4D0C9
+:1063D000C000114221204142A920090011202800BB
+:1063E00082A5190040002742480027422084A99531
+:1063F0001120320082A53200400027424800274287
+:106400002084A99519200A0011206400002202A509
+:1064100040002742480027422084002310A2F000B9
+:1064200003427F15780025422120334219201100B4
+:10643000A9200E0011203200002202A540002742B0
+:10644000480027422084002310A2F00019427F1543
+:1064500006A07C007F1582A56400C8003042087841
+:1064600085A070000A78042405A07C00091202307F
+:106470000232034203440454045605660568067854
+:10648000067A070C070C070EE1100A330558055A67
+:10649000066A066C077C077E000E9B78100046A0FB
+:1064A0007C0084A7000F0B8084A71F00038003805B
+:1064B0000380038005A1FCD740005F42E0A0C074C8
+:1064C00078006142E0A0C0547C007E0E7E0F84D034
+:1064D00040006F42792000010920804F7120804FD9
+:1064E00078007F420920404F7120404F0120044F27
+:1064F0000420ECD040007D427920000178007F42EA
+:106500007920000291200080042184A00F007900EE
+:1065100086429042904290429042904290428E42F7
+:106520008E427810B229B469F5C18CA19FFFB6697B
+:1065300005A04000DF42587884A09FFF85A000603E
+:106540005A78287886A01418C000DF424B780400DF
+:10655000487884A00400C000A5424B780800487821
+:1065600084A00800C000AC423078BCD0C000DF423C
+:106570007E000120044F0420ECD07F004000C14287
+:1065800084B200037800C34284B200044000C942D0
+:106590001800DF427800CB422800DF42E47984A172
+:1065A00030004000DF42EC7884A003004000DF426E
+:1065B0001C68ACD0C000DD42781069437800DF422F
+:1065C0001B78F9007F0F7F0E7C007E0C0120014FAD
+:1065D0000420ACD0C0005B431468078084A00F0087
+:1065E0000380038003808CB200034000F842E0A0E7
+:1065F000C0537800FA42E0A04054046084A00A002E
+:10660000C0005B43086194A100FF40005B438CA184
+:10661000FF0001200A0006A14000264301200C00D3
+:1066200006A140002A430120120006A140002E438B
+:106630000120140006A1400032430120190006A1E8
+:10664000400036430120320006A140003A43780062
+:106650003E4309200C0078004043092012007800D6
+:1066600040430920140078004043092019007800B5
+:106670004043092020007800404309203F00780073
+:10668000404311200000002105A20A60046085A09B
+:10669000020006606120004F0460BCD040005B43F4
+:1066A0001468FCD0C0005643EA606120404F780077
+:1066B0005943EE606120804F1F600F807F0C7C008B
+:1066C0001B7879007C001B7878007C001B786700C1
+:1066D0007C001B7864007C000920194F0C2186A1E6
+:1066E000000040007B4386A1010040007E431F70F4
+:1066F0000B00677001001B7847007C001B78F000DE
+:106700007C001F700A007C000920194F0C2186A113
+:1067100000004000964386A10100400093431F7093
+:106720000B00677001001B7847007C001F700A0097
+:106730007C001B78EF007C001B78F9007C001B7844
+:10674000F8007C001B78C9007C001B78C8007C0026
+:106750001868FCD04000AB431B681D006770010047
+:106760001B7847007C00307884A0C000C000D24372
+:1067700008788CC00A780500050005000500EC7853
+:1067800084A02100C000CF430120054F0420E4D0A5
+:10679000C000CD43047884A01FFF85A0E0000678E8
+:1067A00006A07C0008788DC00A787C0008788DC02F
+:1067B0000A787C00307884A04000C000D7430120D4
+:1067C000044F0420ECD04000E64384B2000378007C
+:1067D000E84384B200044000EE439800F24378009E
+:1067E000F043A800F243AC787C00087884A0FDFF59
+:1067F0000A780500050005000500EC7884A021005A
+:10680000400015447E000120044F0420ECD07F009E
+:1068100040000B4484B2000378000D4484B20004AD
+:106820004000134498000F4478001544A800134416
+:10683000AC787E00087885A002000A787F007C0092
+:1068400084A70100C000B93784A7700040002D4420
+:106850007E0C602D682F78102629782D682C7F0CEF
+:1068600084A7080040003A444B780800EC7884A0E4
+:1068700003004000B93778005D4384A7040040005E
+:106880006944B87884A00140400069444B7808000E
+:10689000EC7884A003004000B937E47884A00700B6
+:1068A00086A00100C0006944C07885A60048302059
+:1068B0005A7E1B78F9007C004B7808001868FCD0E1
+:1068C000400066441B681500F4D6400066441B680F
+:1068D0000700781069437C001B680300587884A087
+:1068E000003F1E682F680000336800004B780800E6
+:1068F000EC7884A003004000AF307E000120044FFC
+:106900000420ECD07F004000864484B2000378006D
+:10691000884484B2000440008E441800082A78009D
+:1069200090442800082A78000C41146B078384A047
+:106930000F00038003800380FCD34000A04480A0AC
+:1069400040547800A24480A0C053602048205A7070
+:10695000602A7C00200020000000200000002000B1
+:1069600000002000000020000000200000002000A7
+:106970000000200000002000000020000000200097
+:106980000000200000002000000020000000200087
+:106990000000200000002000620009001400140024
+:1069A0004898140014001499FD98140014008000F5
+:1069B000FF0000010204082080F818000AA2140059
+:1069C0000B300CA21400002513000025100010004D
+:1069D0001000100010001000100010001000100037
+:1069E000100010001000100000A2063802715F8035
+:1069F00081943988C420640856A80830C1281B9D9A
+:106A000001A20C30472861816A840080A484561852
+:106A10003A8808A8E228CB9CF3A8640844A80C3064
+:106A200001A80830E128CB9C21201DA805A20C87D5
+:106A3000DED8A064E06DC06FA463806C120205A272
+:106A40003D8842792080A1A42B8814183B88DF80E0
+:106A5000A1942770F28537A732A503F07685778653
+:106A600016A83E8814A8012012A804A2C064E06DF4
+:106A7000A067C06F42792080A1A41418DF80A19480
+:106A80003B8823707685778602A861783E886B20E4
+:106A9000C1281B9D44200321A2208120C3A807A256
+:106AA00004090EA209A803A20080A48572189A877F
+:106AB0003C88E21F01F608A26E856F8661711400A2
+:106AC00004070830CB9C140002A20080A485093082
+:106AD000A884E21944F86E853F88E608F5A861F8B5
+:106AE000EAA801F8140081F81600B285F08032950A
+:106AF000A2FAE21D1400328521F21400E21DA884DE
+:106B0000E0D6E61F1400083000804A281110FCA8C7
+:106B10000830339D008000A002281110FDA8399D87
+:106B2000BDA80830339D3B281110FDA809A20271B1
+:106B30005F80819417000C3009A20080A485E21DBB
+:106B400009A2C1DA1400100201A81400E0263A8755
+:106B5000A3FAF219E026F21814000BA214000DA2F9
+:106B600006381002259D040706A265687E812A84E6
+:106B7000C11D2388160042600880FAA80080A48402
+:106B800060812A8421F00830A884D6114270DD206B
+:106B90001100D420228816004479218420A032A537
+:106BA000A184160044792184DFA03295A1841600C7
+:106BB00000007E12D47084A00046048090200472ED
+:106BC00008709CC005A2C00002460C72FF82400003
+:106BD000ED45FF8AC0000246007284D2C000024622
+:106BE0000478CCD04000F3457810CC4A23700000E4
+:106BF00027700000007084D04000FD45077004003D
+:106C0000037008007F1200207C00007084A0030045
+:106C100002709CC684D040005B4608710500087075
+:106C200006A1C0000A4684A1030040008C4684A14E
+:106C3000E001C0008C46F4D1C0000A4684A10030B7
+:106C400086A0001040000A460120054F0420E4D031
+:106C500040003746112080010C71118240004546EA
+:106C60000870F4D0C0000A460C7006A140002A4605
+:106C700078002746112080010C71118240004546A2
+:106C80000870F4D0C0000A460C7006A140003A46D5
+:106C90000770120008710500087006A1C000474681
+:106CA00084A1030040008C4694D140004746F4D1B3
+:106CB00040008C460770020078000A460871FCD13B
+:106CC000400066467810ED47FF8A4000DC457800BA
+:106CD0005B460C708CA0FF0340009146047084D08A
+:106CE00040008346147005A0C0007F4610701073EA
+:106CF00006A3C0007346002305A04000834602A1FE
+:106D0000C8005B460770100078008C46FF8A400080
+:106D100091467810F249C000864640005B467810E4
+:106D200038477F1200207C00047208719CC10381E7
+:106D3000C800A04607700200780091460370080062
+:106D40007F1200207C0005A2C0008C46237000004A
+:106D500027700000037008007E000120014F04200E
+:106D6000CCD04000B2467810CC4A7F007F12002081
+:106D70007C002864FF844000E246702C0470BCA0B4
+:106D80000F00B8A7F2463C27FB87C000D04648005A
+:106D9000C8467810B2299C6075A04000E246780091
+:106DA000BB463920E746042768AE086830A60C6861
+:106DB00029A521844000E2463887042705A0C000A9
+:106DC000D1469C7075A0C000BB467C000000050049
+:106DD00009000D001100150019001D00000003003E
+:106DE00009000F0015001B0000000000E746E44604
+:106DF0000000000000800000E7460000EF46EC467F
+:106E00000000000000000000EF460000EA46EA46ED
+:106E10000000000000800000EA460000F046F04656
+:106E20000000000000000000F0467920004F7120B3
+:106E3000100007700A00077002000370010010784C
+:106E4000ECD0400026470920010071202000780086
+:106E50002A47092002007120500007700A000770BD
+:106E600002000370000009814000374771202000B4
+:106E700078002A477C0004700480C800C14708716C
+:106E8000087006A1C0003C4784A1E00140004947CA
+:106E9000781030487800E947077012001920000088
+:106EA0000871087006A1C0004D4784A1E0014000B0
+:106EB0005A47781030487800E9471078ECD0400005
+:106EC00074470120FD04042086A00300C000784719
+:106ED00084A1004040007C4782A30300C8007C4797
+:106EE00084A1040040004D47188378004D47147872
+:106EF000ECD0C0007C4784A10040C0004D479CA15D
+:106F00000C3086A304204000994786A30800400067
+:106F1000A447047084D0C00095470871087006A18A
+:106F2000C0008A4784A1030040009547780030489C
+:106F300086A30C20C0004D47007204824800A4477D
+:106F40000C7384A3FF034000A4477810B229087192
+:106F5000087006A1C000A44784A1E0014000B14729
+:106F6000781030487800E94707701200007084D02C
+:106F7000C000C1471073147005A34000C1470C71D5
+:106F800084A1FF03C00038470871087006A1C00043
+:106F9000C14784A1E0014000CE4778103048780016
+:106FA000E947077012000770080004709CD0C00009
+:106FB000D2470871087006A1C000D64784A1E0013D
+:106FC0004000E347781030487800E9470770120026
+:106FD000087103814800D647037008007C000871DF
+:106FE00084A1E001C0003048087184A1E001C00024
+:106FF000304884A107007900FA4704481448024841
+:10700000144802487248024870487810B229047047
+:1070100084A010008DC00670FF8AC0000F48492070
+:1070200000007C007810F249C0000F487C0004701A
+:1070300084A010008DC00670047084D0C000284861
+:107040000871087006A1C0001D4884A1030040001B
+:10705000284878003048FF8A40002F487810F249CD
+:10706000C0002B487C00077012000871E000334814
+:1070700091200060E0003748912000600770120006
+:107080000770080004709CD0C0003F4807701200D1
+:107090000871FCD1C000434803700000007005A0D7
+:1070A000C0005748047005A0C00057480C7005A0E8
+:1070B0004000594878003B484920000084B2000154
+:1070C000400063480120000078006548012001006D
+:1070D000781062421B680200512000007C0078108A
+:1070E000B2297810B2297810B948107214710C7056
+:1070F0009CA0FF03002800A311A289A10000781022
+:10710000B9480427582C60AC0863002222A30C6302
+:1071100000211BA3002405A340009548C800954802
+:10712000128410820A8389A10000602B78007C48B9
+:10713000602B078A7E0004609CD04000A048BAA75C
+:10714000EC467800A248BAA7E4467F003DA7002C91
+:1071500086688A6F926C8E6B0871087006A1C000F9
+:10716000A94884A1E0014000B44878103048077075
+:107170001200781038477C00508A3987042704A011
+:10718000C000CD48006064A0C000C448602D046009
+:1071900084A00F0080A002473C20FB874010B2294A
+:1071A0007C007E127E0DD47084A000460480902066
+:1071B0007F0D8468602088688C6B906C5780D4AA9F
+:1071C000FF0084A0FF007E00046884A008007F0008
+:1071D0004000EB48B8A0EC467800ED48B8A0E44683
+:1071E00084B200014000F448207E7800F548247EF7
+:1071F000B5A60C001C68B4D04000FC4885C600242D
+:1072000005A340002549582C0427046160AC0060A8
+:1072100000A41A70046001A31E709CD1400015499F
+:10722000106081A000002270146081A00000267010
+:107230000862002402A212700C62002303A21670DE
+:10724000027607700100602B78101C4A78002749ED
+:107250007810F249C00025497F1200207C007E1280
+:107260007E0DD47084A00046048090207F0D0770AE
+:107270000400047094D0C0003649037008007F12E7
+:1072800000207C007E127E0DD47084A00046048015
+:107290007E0090207F007F0D207E84B20001C00020
+:1072A0004F49247EB5A60C001C68ACD0C0005A49DA
+:1072B00085C6037000000770040028685020602D08
+:1072C0000460BCA00F00B8A7F2463C27FB87C000B3
+:1072D000704948006A497810B2299C6865A040004E
+:1072E000744978005D497810F249C00070497F12F6
+:1072F00000207C007E127E007E017E0DD47084A072
+:10730000004604807E0090207F00207E84B2000131
+:10731000C0008849247E7F0D7F037F04B5A60C0042
+:107320001C68B4D04000964985C603700000077001
+:10733000040049207749286855A07E0D4000EE4999
+:10734000702D602E0470BCA00F00B8A7F2463C2739
+:10735000FB87C000B3494800AC497810B2299C7043
+:1073600075A060204000EE4978009F49042768AE70
+:10737000086822A40C681BA34800CC49518AC000AD
+:10738000C0497810B2293887042705A0C000B44945
+:107390009C7075A060204000EE4978009F492284CF
+:1073A00020841A8399A300000869002422A10C6993
+:1073B00000231BA1C800DB497810B22984B2000168
+:1073C0004000E9490120044F0420ECD0C000E94905
+:1073D000712050007800EB49712020007F0D78006B
+:1073E000FC487F0D7F1200207C0008707E0084A086
+:1073F000E0017F004000FB4906A07C0084A0030060
+:1074000086A00300C000024A7C00042778AC007804
+:107410001A7004781E70087812700C781670046068
+:107420009CD04000144A107822701478267002769E
+:10743000047084A0100085C006707920004F388742
+:10744000518A4000404A042705A0C000324A9C608F
+:1074500005A04000414A6020046084A00F0080A085
+:10746000F2463C20FB874010B22908707E0084A0C1
+:10747000E0017F0040003C4A06A07800414A84A019
+:10748000030086A003007C00512000007C007E12D7
+:107490007E007E0DD47084A00046048090207F0D75
+:1074A0007F08087184A10300C000594A286805A01C
+:1074B0004000694A780002460871FCD14000614AE8
+:1074C0007810ED4778004E4A077010000871FCD123
+:1074D0004000634A7810ED47087086A00800C0009D
+:1074E0004E4A007005A0C0004E4A037000004920BB
+:1074F00000007E000478CCD040007D4A7810CC4A51
+:107500007F007F1200207C007E127E147E137E1589
+:107510007E0C7E0DD47084A00046048090207F0DE8
+:107520004920814A80AD1100A02084B200014000B2
+:10753000A44A0120044F0420ECD04000A04A992026
+:1075400031007800A64A992032007800A64A992096
+:1075500031000C7084A0FF032A68077008000770D0
+:107560000200037001004000B54A0080AC80A553C2
+:107570000C7084A0FF034000C14A0770040004702F
+:1075800084A00400C000BC4A7F0C492000000370A6
+:1075900000007F157F137F147F1200207C00146889
+:1075A000FCD04000114B007084D04000114B247E71
+:1075B000B5A6040007700400047084A00400C00095
+:1075C000D94A18717E011C717E0120717E012471DF
+:1075D0007E010EA01A711F70FF3F22712671137079
+:1075E000040016710276077001000120FFFF0920D8
+:1075F00031000A200A200871087006A1C000F84A6C
+:10760000FCD14000F84A7F0226727F0222727F027C
+:107610001E727F021A7207700200087086A00800AE
+:107620004000114B780030480770040003700000E0
+:107630007C009120008091200060AC7805A0C00003
+:107640002D4B7479D07006A1C0002D4B1C7805A07D
+:1076500040002D4B1F78000068002D4B912080408A
+:10766000307801803278C000B54B347832781078A9
+:10767000ECD0C000AE4B6120C0746920804FFDC7C4
+:10768000D06805A04000474B0180D268C000474B3E
+:107690007810834D006884A00F0040005C4B86A0EA
+:1076A000010040005C4B44680DA040005C4B04218D
+:1076B00005A040005C4B01800A204000F64C146895
+:1076C00005A04000814B01801668C000814BA7686F
+:1076D00001007E0FFCD7C000764B1078ECD0400044
+:1076E000724B792000017800784B792000027800F5
+:1076F000784B792000017810D3437F0F646805A090
+:107700004000814B78106F26806805A040008E4BAA
+:1077100001808268C0008E4B67680000D468DDC0BD
+:10772000D668D468FCD04000AB4BFCC0D668A9201A
+:107730000002346005A04000A74B01803660D46889
+:10774000FDC0D668C000A74B106005A04000A74B45
+:1077500078106F26E0AC1000F000964BFCD740008C
+:10776000B54B6120C0546920404FFCC778003D4BA9
+:107770007810F14B387801803A78C000D74B3C78CC
+:107780003A786120C0546920404FFCC70C6805A0BE
+:107790004000C94B78105B4CFCD7C000D74B107829
+:1077A000ECD0C000D74B6120C0746920804FFDC76A
+:1077B0007800C34B1478E4D0C000DB4B1078CCD0F9
+:1077C0004000EE4BACD0C000E74BA4D04000EE4BE5
+:1077D000ADC01278912001806800ED4B7810DC2359
+:1077E0007C00912001807C00407801804278C000BC
+:1077F0005A4C447842786920404FFCC71078792071
+:107800000002ECD04000034C79200001D86805A0AC
+:1078100040000F4CE07D04A5C0000F4CDA68D4682E
+:10782000BCC0D6687920004F106805A0C000174C76
+:107830000120010101801268FCD74000204C80A08B
+:10784000D0957800224C80A0C0944020042065A0F0
+:1078500040004C4C246005A04000484C018026604C
+:10786000C000484C006805A040003B4C4C6806AC8A
+:10787000C0003B4C7810F64C78004C4C646805A076
+:107880004000434C276001007800484C7810A94C18
+:1078900004287800244C0060402C7800244CFCD74D
+:1078A000C0005A4C1078ECD0C0005A4C6920804F70
+:1078B000FDC7792000017800034C7C0009200000FE
+:1078C000A920000208609CD04000954C246005A0CF
+:1078D00040006B4C018026607800934C08609CC08F
+:1078E00084D0C000734CACD040008D4C0A60046062
+:1078F00005A04000954C7E0D7E0C7E016820106036
+:10790000018012607810193E002D682C60207810DC
+:10791000A21E781064207F017F0C7F0D7800954CAB
+:10792000BDC00A608DA101007800954C8DA10001B9
+:10793000E0AC1000F0005F4C84A101004000A44CBA
+:107940008CA1FEFF0E6978106F267800A54C0E6999
+:107950007C00C000A54C6C78002C7E681467766FA4
+:10796000176000002B6000001B600600B46084A05C
+:10797000003F1E60206084A0FF0085A060002260A0
+:107980000060422078102B1E186805A04000C74CEC
+:1079900001801A680868A4C00A681068087909811B
+:1079A0000A790180D000D34C7810B2291268C00047
+:1079B000D94C1079A5C112792F6000003360000006
+:1079C000682C78107320FCD7C000E74C6920404F2A
+:1079D0007800E94C6920804F106984A100010120E2
+:1079E0000600C000F34C7A69012004007810632679
+:1079F0007C007E0D4C696021FCD7C000084D1078DA
+:107A0000ECD04000044D6920000178000A4D692047
+:107A1000000278000A4D69200001781026291B60B9
+:107A20000600586884A0003F1E60206084A0FF000C
+:107A300085A0480022602F600000336000000868C5
+:107A400084A0FDFF0A683068B4D040003C4D4B680C
+:107A50000400A9201400486894D040002E4DF00086
+:107A6000284D4B680900A9201400486884D04000C4
+:107A7000384DF000324DA920FA00F0003A4D1B6855
+:107A800047007F0D676807007C007920004F781061
+:107A9000764D78105C4D7810694D09200200692000
+:107AA000804F0F680000136800001768000009810C
+:107AB00040005B4D6920404F78004E4D7C001078AF
+:107AC000ECD04000644D1920CC007800664D1920A0
+:107AD0007B003A7B3E7B7C001478E4D0C000714D83
+:107AE000192040007800734D19202600427B467B08
+:107AF0007C001478E4D0C0007E4D1920943F7800BB
+:107B0000804D19202426327B367B7C00506A85A26A
+:107B100000004000AF4D5469C06B00A37E0C64218F
+:107B20000463FF83C0009B4D118240009F4D08817C
+:107B30001AA148008C4DC06978008C4DD3680A00AA
+:107B40007F0C7C005069C06A64222B6000002F60AB
+:107B500000000860B5C00A6010820981C000A14D14
+:107B600052697F0C7C00E000B04D91200060E00085
+:107B7000B44D91200060EC70DCD0C000C14DD4D079
+:107B80004000EA4D7800ED4D08201078ECD0400020
+:107B9000D44DC4D1C0000E4E1478C5C016781078EC
+:107BA000F5C01278ECD040000A4E7800064E8EAE3A
+:107BB00000014000E14D1478F5C0C5C01678D4D05E
+:107BC000C0000A4E7800064E1478FDC0C5C0167875
+:107BD000D4D0C0000A4E7800064EE4D040000C4ECF
+:107BE000E000ED4D9120006009200C00E000F34D15
+:107BF000912000600981C000F34DE47084A0FF0172
+:107C000086A0FF01C000044EEC707800C14D7810D2
+:107C10000F4E04788CD040000C4E1F680C00A070F2
+:107C2000A2707C001079ECD14000194E1478C4C0C9
+:107C3000F4C1127978002B4E8EAE00014000254E23
+:107C40001478F4C0FCD0C0002B4EC4C078002B4E7A
+:107C50001478FCC0F4D0C0002B4EC4C016787C0051
+:027C6000E3142B
+:00000001FF
+/*****************************************************************************
+ * QLOGIC LINUX SOFTWARE
+ *
+ * QLogic ISP1280/ device driver for Linux 2.2.x and 2.4.x
+ * Copyright (C) 2001 Qlogic Corporation (www.qlogic.com)
+ *
+ *****************************************************************************/
+
+/************************************************************************
+ * --- ISP1240/1080/1280 Initiator Firmware --- *
+ * 32 LUN Support *
+ ************************************************************************/
+
+/*
+ * Firmware Version 8.15.11 (10:20 Jan 02, 2002)
+ */
diff --git a/firmware/qlogic/isp1000.bin.ihex b/firmware/qlogic/isp1000.bin.ihex
new file mode 100644
index 00000000000..a5c242cda22
--- /dev/null
+++ b/firmware/qlogic/isp1000.bin.ihex
@@ -0,0 +1,1158 @@
+:1000000078003010000019240000FF124320504FE8
+:10001000525947495448312039392C313931323914
+:10002000312C39392C333931343951204F4C49472F
+:1000300020434F435052524F54414F49004E4920A4
+:1000400050533031303046207269776D72612065CF
+:100050005620726569736E6F30202E313133202047
+:10006000B9201212C120080071201000C3700400D2
+:10007000C920FF3F8920C810C7705349CB7020505A
+:10008000CF702020D3700100003FD67031203000A7
+:100090007920003563780000A02F09202703112064
+:1000A0000000A9204000A4420981C00051109B78A3
+:1000B00001010B7802000F7802004F78B80B69201D
+:1000C0004035A8006A101B683C0009201313B821B2
+:1000D00078006C101B682800076807000B68FA009E
+:1000E0000F680800136805001F68000023680600F9
+:1000F00017680800276800006920003611202000DA
+:10010000092010000B68190C0F681900036800DD46
+:1001100007681A001A6A002DE8A0080090A20400DF
+:100120000981C000821069208036A92080003768CC
+:1001300000000B684000176800011F686400E8AD0C
+:1001400010007000A510780097107810381A7810F9
+:100150003A2F781081167810BA33003285A00D003E
+:100160009020C37000009000BC10C07086A00200F8
+:10017000C000BC107810BA117810EC107810171865
+:100180007810A81978107D3278107D177800BC108F
+:10019000D010D210C31BC31B982F982FC31BC31B97
+:1001A0007800D0107800D2107800D4107800D610E3
+:1001B00008700C80C800E710077002008CA00C00CB
+:1001C000C000E81004800480C800E7107A087A09AB
+:1001D000C37002407800BD11147805A0C000F4106F
+:1001E0001000301178002F1109206835042105A076
+:1001F000C0002F11147886A00100C00001117810F2
+:1002000036151778000009206F35042165A04000DD
+:100210001D1109206A351C2108811421088104213F
+:1002200010A299A3000009201C008360030178102C
+:100230001116C00029117810781609206F350B208F
+:1002400000000920693504210B20000005A04000B2
+:100250002D11012005407800BC117800BA117C00F6
+:1002600061200000186084A00100400038117C006B
+:10027000C3700000C7700000CB700000CF7000009A
+:10028000C070BCA0C0FFC0008811382079004811A0
+:10029000BA110512D311051256125612CA11901531
+:1002A0006112C611D711D911DB11DD119515C611D7
+:1002B0006712831244158A15DF116B148D14A7146D
+:1002C000D0142414321446145A14EF12C6119F127B
+:1002D000A612AB12B012B612BB12C012C512CA12CD
+:1002E000CE12E312C611C611C611C611C611FB12F9
+:1002F00004131313391343134A1370137F138E130C
+:10030000A0130914C611C611C611C611C6111914BD
+:10031000BCA0A0FFC000C611382084A01F00790037
+:100320009111C611C611C611C611C611C611C6114A
+:10033000C611C611C611C611C611C611C611C61105
+:10034000C611C611C611C611C611C611C611C611F5
+:10035000C611C611C611ED15F715FB150916C61104
+:10036000C611CA72C671012006407800BC11CE7356
+:10037000CA72C67101200040C270612000001B607B
+:10038000010091200050912080407C00C37001400A
+:100390007800BD1199204100A1204100A92005004D
+:1003A000A3537800BA11C470C37004007A007800B7
+:1003B000BA117800BA117800BA117800BA119120F8
+:1003C0000080C3700000C7705349CB702050CF70BD
+:1003D0002020D3700100003FD670792000001B78E8
+:1003E00001003120300059200010292057045120ED
+:1003F000700461207204B920FFFFC1200000912029
+:1004000000509120804078005504D071C872CC73A0
+:10041000C470A020982031203000FF814000BA1124
+:10042000077004001A731E72512012004920341202
+:100430004120BA110370020086A70100C0002612F5
+:100440004920421241204E12037003001770000031
+:100450000B811271C8002E12177001000770010085
+:1004600086A70100400042120C7084A07F00048027
+:100470000920200002A142094A09A820A026A6536B
+:100480007800D8100C7084A07F0040004212AC802D
+:10049000480042129826A5537800D8100C7084A00A
+:1004A0007F00AC809826A5537800BA11C471C8703B
+:1004B00014219EA70400C0005E120A20CA727800B0
+:1004C000B911C7700100CB701F007800BA11C47059
+:1004D000C872CC73D074C670CA72CE73D27405A0C1
+:1004E00040007D12018072787A7A7E7B767C9878E3
+:1004F00084A0FCFF9A7878008112987885A001008A
+:100500009A787800BA11C470C872CC73D474C6706B
+:10051000CA72CE73D67405A0400099120180867805
+:100520008E7A927B8A7C987884A0FFFC9A787800F7
+:100530009D12987885A000019A787800BA11092058
+:1005400059350C21112010047800B81109204135CB
+:100550000C217800B911092042350C217800B9111D
+:10056000612040350C6110627800B81109204535D2
+:100570000C217800B911092046350C217800B911F9
+:10058000092047350C217800B911092048350C2184
+:100590007800B91108790C7A7800B811C471078114
+:1005A00084A00F00038003800380E8A00036006A67
+:1005B000046884A008004000E012086B7800E11293
+:1005C0000C6B7800B711C4777810921691200080D8
+:1005D0001C6B146A9120018008277800B711C4773A
+:1005E00078109216912000800869186A106B91208B
+:1005F00001807800B711C47182A11000C800B21147
+:100600007810BC1A7800B711C47182A11000C8001C
+:10061000B2111120413504227E0012217810751A82
+:100620007F017800B911C47111203113A92008008D
+:10063000042206A1400023131082700021137800C9
+:1006400018137800B21192A231137E0211204235A4
+:10065000042212217F017E007810811A7F01780028
+:10066000B911E803FA00F401EE0264001900320047
+:100670004B00612040350C611062C4700E60C87080
+:1006800012607800B811612040351461C4701660A2
+:100690007800B911C471112004001920121286A12A
+:1006A000280040006313112005001920121286A1B2
+:1006B000320040006313112006001920131386A195
+:1006C0003C00C000B2116120403518607E001A6104
+:1006D000B8237810921A7810BA337F017800B911D4
+:1006E000C47184A1CFFFC000B2111120473504228C
+:1006F00012217E007810B41A7F017800B911C471FC
+:1007000082A11000C800B2111120483504227E00D9
+:1007100012217810A31A7F017800B911C471C87230
+:1007200084A1FDFFC000B11184A2FDFFC000B11182
+:10073000002108790A7800220C7A0E787800B81126
+:10074000C471078184A00F00038003800380E8A0A8
+:10075000003619200000C87200687E0026A2400002
+:10076000CF13026A84A400204000B8139DA3100098
+:1007700084A400104000BE139DA3080084A4004080
+:100780004000CF130F8184A200404000CB137810AB
+:10079000D61A7800CF137810C81A7800CF13CC720D
+:1007A000FF8240000114086806A240000114A4A2C0
+:1007B000FF0061204035186186A128004000E81341
+:1007C00086A132004000EE1386A13C004000F413E5
+:1007D00082A464004800FE137800F81382A450003D
+:1007E0004800FE137800F81382A443004800FE136B
+:1007F000C471C6717F02CA727800B3110A6A9DA3E0
+:100800000A00046805A306687F020C6BC4717800B7
+:10081000B711C4777810921691200080146A1C6B6F
+:1008200091200180C8701668CC701E680827780077
+:10083000B711C471C872CC7382A11000C800B21184
+:100840007810E41A7800B711C477781092169120C6
+:100850000080086A95A202000A6A91200180082798
+:100860007800B811C4777810921691200080086A39
+:1008700094A2F9FF0A6A046805A0400041147810A8
+:10088000191A9120018008277800B811C4777810D0
+:10089000921691200080086A95A204000A6A0468F2
+:1008A00005A0400055147810191A912001800827DE
+:1008B0007800B811C477412001004920050051207B
+:1008C00020009120008078109F1691200180082739
+:1008D000086A7800B811C477C872CC73C677CA7238
+:1008E000CE7378101817C0008914186805A040004E
+:1008F000831408277810F41AC00083141778FFFFB8
+:10090000912001807C009120018001200540780029
+:10091000BC11912001807800BA11C477C6774120BC
+:1009200021004920050051202000912000807810EE
+:100930009F1661204035A3600300B667A7600000E2
+:100940001778FFFF912001807810191A7C00C87772
+:10095000CA77C477C677BCA700FF912000806120CA
+:100960004035A3600200A7600000B6671778FFFF5C
+:100970007810191A9120018041202100492004009B
+:10098000512010009120008078109F16C8703668A2
+:10099000388784A70700C000C414912001807C0020
+:1009A000987884A00300C000F4143920000041208E
+:1009B000210049200400512008007810921691204F
+:1009C000008008680DA80A6991200180388784A7F3
+:1009D0000700C000DD14BCA700FF3F8738873F87B2
+:1009E00084A7000FC000DD14912000806920000161
+:1009F000306884A0400040001D154B680400A92009
+:100A00001400486884A0040040000A1570000A150C
+:100A1000780001154B680900A9201400486884A0DB
+:100A20000100400017157000171578000E15A92059
+:100A3000FA0070001D157800191579200035177817
+:100A4000010061204035A3600100A7600000C36081
+:100A50000F00987885A002009A78086884A0FDFFAE
+:100A60000A681B684600912001807C00987884A069
+:100A7000FDFF9A7884A00100C0004015781060172F
+:100A8000C471C6714A797C00C474C873CC72C674D0
+:100A9000CA73CE72792000350920400078106F1695
+:100AA0004000861578103F1640005A1578107816C9
+:100AB000780086151060912001801778FFFF0920CB
+:100AC00068350B20050008810B20000008810A23EF
+:100AD00008810A2208810A2408810A2008810B2043
+:100AE000000008810A2C2EA030257E0E7810132FCE
+:100AF0007F0E9265A2659666A666AB600000AF6049
+:100B00000000912001807810191A7C00C370054004
+:100B10007800BD11C471C770000006797800BA1161
+:100B2000C471C671682178009715692000100C699E
+:100B300016A0042D10A2688D0981C000991585A208
+:100B40000000C000A715C37000407800A915C3704D
+:100B50000340CA707800BD11C471C872CC73002103
+:100B600084A1FCFFC000C61100217900B715CE1585
+:100B7000E315E515E715C3700340CE71D272D67345
+:100B80007800CA15C3700040CF700000D370000019
+:100B9000D7700000C677CA717800BA113120E91504
+:100BA000242630861224042246A4C000BB1584A447
+:100BB000FFFFC000D0153120E9151082198384A3EE
+:100BC000FFFFC000D0157800C2157800C21578006C
+:100BD000C2155555AAAAFFFF00006079C671C471FD
+:100BE00082A10300C800B21162797800BA1160795D
+:100BF000C6717800BA115479C671C47156795879A2
+:100C0000CA71C8715A795C79CE71CC715E797800FD
+:100C1000BA115479C6715879CA715C79CE7178006D
+:100C2000BA110C7084A07F0040001D1607700400EC
+:100C3000047084A00400C000181617700000127120
+:100C40001A721E7308810C81A981988CA120300032
+:100C50008060A220A6530C7885A000000270077067
+:100C6000010008710481C80031160770020084A1D8
+:100C70000C000C7184A10003037000007C000C7058
+:100C800084A07F0040004B1607700400047084A00D
+:100C90000400C00046161770000012711A721E730D
+:100CA000992030000881AC810C7885A00100027089
+:100CB0000770010008700C80C8005A160770020007
+:100CC0008CA00C00C0006C160C7184A10003C00045
+:100CD0006C16A02CA55306A0037000007C00507871
+:100CE00065A040007716042C5278632000007C0039
+:100CF0007E0F7920003550786220002C52787F0FCB
+:100D00007C0011200040527A192010041983400001
+:100D10008F1680A22F001220102078008616132034
+:100D200000007C0084A7000F0C8084A707000380CC
+:100D300003800380038005A1E8A080367C00781042
+:100D4000921600292A68002A2E68086884A0EFFFFE
+:100D50000DA80A6909204F350C21046805A0400040
+:100D6000BC1616A1C000BC166020006006687E019B
+:100D70000B2000007800BF16092000007E010468E7
+:100D800065A04000CE16006006687810DF16781067
+:100D9000CB17106801801268C000BF167F0102697E
+:100DA00006697C0065A04000DE1698609B6000002C
+:100DB00008207810781600217800D2167C00036095
+:100DC0000301A9201C0080AC0400A0200120000029
+:100DD000A440286816602C681E607C007E0E71207E
+:100DE000403540708CA08000C000FC1688A0803583
+:100DF0000A2D0080427006A07F0E7C007E0E7120BE
+:100E00004035092080354072218211824800161732
+:100E10000421088106ADC000051719811E21088133
+:100E200018831182C8000E17427406A07F0E7C0042
+:100E3000781092169120008004681E7865A040000A
+:100E40005F1778002917002C1E78006065A040000D
+:100E50005F170C6006A3C0002317086006A2C0003D
+:100E60002317282C01204F35042006AC40005F17C3
+:100E7000046806ACC000461700606020066805A044
+:100E8000C0004617036800007800501700641C7803
+:100E90006020026486A40000C0005017002C026885
+:100EA00060257810DF16176005001F60200078109D
+:100EB000CB171068018012680120FFFF05A07C009D
+:100EC0003920000041202100492004005120080061
+:100ED0009120008078109F16388784A70700C000F3
+:100EE0006A17BCA700FF3F8738873F8784A7000F9A
+:100EF000C0006A17912001807C006120000018600A
+:100F000084A00100C0008A17AC78AF78000005A06B
+:100F1000C0008B177C008CA0F0FF40009117781068
+:100F2000A51B79009317A317A517AB17AF17A31726
+:100F3000B317A317A317A317A317B917BD17A317A1
+:100F4000A317A317A3177810A51B7810601701200B
+:100F500001807800C317012003807800C3170120A7
+:100F600004807800C317781060170120068078008D
+:100F7000C31701200C807800C31778106017012078
+:100F80000D807800C317C270612000001B60010053
+:100F9000912080407C00042C8260082C632000009B
+:100FA000647800806678687805A06A794000DB176D
+:100FB000022C7800DC176E797C007E0C61200035F5
+:100FC00083680301082D6B20000064600080666068
+:100FD000686005A06A614000F017022D7800F117E3
+:100FE0006E617F0C7C0078100418400003187E0CA2
+:100FF000986065A04000FE177810D2167F0C9B60A9
+:101000000000781078167C006C7865A040001618F7
+:1010100091200080647801806678042C6E7805A0A9
+:10102000C00014186A780080912001807C009878B4
+:1010300005A0C00065187479D07005000500D07255
+:1010400006A2C0001C18002206A1C00033180478B4
+:1010500005A0400065180778000068006518912019
+:1010600080407800651878106F16400065187C7A0B
+:10107000787B07810480048010A299A300000920D6
+:10108000400078103F1640005C1878107816807881
+:101090000080827886A00200C00065189120008040
+:1010A000AF78020083780000987885A003009A78D2
+:1010B00091200180780065188378000078109219DB
+:1010C000006084A00700790066187C006E187D1807
+:1010D0009D186E18AF186E186E186E18392000041F
+:1010E000A87805A7AA78046005A706607810ED180F
+:1010F0001860A67878107A197C00A87884A000017E
+:101100004000841878006E18AB78000000600780FB
+:1011100084A0FF009E7801809B60000040009A1828
+:101120007810ED1840009A18A87885A00001AA78D8
+:1011300078009C18781011197C00A8788CA0000EFB
+:10114000C000A61884A00001C000A81878006E187E
+:101150007810ED18C000AE18781011197C00A8782E
+:1011600084A000014000B61878006E18AB7800002B
+:101170001067A9200100146084A0FF0005A04000B2
+:10118000D318BCA700FFA92008008EA001004000D2
+:10119000D31839200000A92080008EA00200400052
+:1011A000D3187800EA1878109216002D912000804C
+:1011B0002B6800002F680000086884A0DEFF0A6822
+:1011C000002D80A010006820912001807000EA1896
+:1011D0007800D618781078167C00A0786DA0C00032
+:1011E000F818002CA278A6789B60000078000419FB
+:1011F000002C9A689B600000A278002D0260A47801
+:1012000006ADC000041902609C7801809E78C00081
+:101210001019A87884A00000AA78A478602006A0FD
+:101220007C002EA03025186184A160009E614000E2
+:101230001D197E0E7810132F7F0E9265A26596669B
+:10124000A666AB600000AF600000106778109216D1
+:1012500091200080086884A0010040003F1991207F
+:1012600001807810DF16912000807810CB17912034
+:101270000180A3780000A778000078007919206029
+:1012800096A00100C000461900802260106A146810
+:101290009120018002A248005519400055193920BB
+:1012A000000278107A1978007919082C91200080B2
+:1012B000006865A040005D1902610269C000611903
+:1012C00006696021036000001068008012689120A8
+:1012D000018008688CA040004000731986A040007F
+:1012E0000A687810EE167810191AA7780000A3780B
+:1012F00000007C00046005A7066091200080781043
+:10130000CB1791200180A47865A040008D199860CA
+:10131000A6789B60000078007D19A3780000A7786C
+:1013200000007C007079747800800AA1C8009919C7
+:1013300006A07678D270047805A04000A719018035
+:101340000678C000A7196800A719912080407C008A
+:101350006800C219292000006C7865A04000BD1902
+:101360007810C3194000BD197E057810D9197F0582
+:10137000C000BD1928857800AC19FF854000C2194E
+:10138000912080407C00847B8879D4720500050020
+:10139000D47006A2C000C519002202A1C000D31952
+:1013A000002305A07C004800D71902A37C0002801E
+:1013B0007C0078100B1A09201C00246005A0400056
+:1013C000E31909204000781011164000FC199478A8
+:1013D0000080967886A00200C0000A1A9120008042
+:1013E000AF78030097780000987885A000039A787A
+:1013F0009120018078000A1A977800007810F3177E
+:101400008479887800800AA1C800071A06A08A7823
+:10141000D67006A07C00078104800480907A8C7BC3
+:1014200010A299A300007C0009206835912000805B
+:101430000A207E0F7920000109204035912000808C
+:10144000042186A00000C000341A092012350421AE
+:1014500005A0C000341A307884A0C000C000341A3F
+:101460001800341A1B784400912001807F0F7C0003
+:101470007E1291200023712040357920000119202F
+:10148000D82DA1202B01042305A04000501A9A78E2
+:101490001883AC2318839823A65318337800431A73
+:1014A0009B782000A9201000AF780000AF782002C0
+:1014B00070005C1A7800541A0370000078105B1BEF
+:1014C000047084A00F0085A0806206780F780092D7
+:1014D0004378D800537880000B78380047707F3508
+:1014E000437000007F1200207C008CA10F001120AF
+:1014F0000101042284A0F0FF05A1122078105B1BDB
+:101500007C0011200101A92009000B8170008A1ABA
+:101510007800851A8CA1000E042284A0FFF105A199
+:1015200012207C0009200101A9200500138270000F
+:101530009B1A7800961A94A2E000042184A01FFF51
+:1015400005A20A207C0011200101A9200C000B81BA
+:101550007000AC1A7800A71A8CA100F0042284A0B5
+:10156000FF0F05A112207C0011200201042284A09B
+:10157000CFFF05A112207C000381038080A0200002
+:101580007E0C612000019A60AC62AC637F0C7C0031
+:101590000381038080A022007E0C612000019A60FC
+:1015A000A46084A0DFFFAE607F0C7C000381038019
+:1015B00080A022007E0C612000019A60A46085A0BA
+:1015C0002000AE607F0C7C000381038080A020009F
+:1015D0007E0C612000019A60A460AE621020A460BD
+:1015E000AE6318207F0C7C00912000807E0C7E0E64
+:1015F000186805A04000391B6120803F7810411B0E
+:101600004000271BA92000006120803E7E0C78103E
+:10161000411B4000131B7F0C608C7000111B780075
+:10162000061B7800391B7F0082A0803E7120403568
+:10163000BA701C6085A000081E60B671A76000002B
+:1016400001200400A2707810141A7800351B712054
+:1016500040351C6085A000081E60B671A7600000C0
+:1016600001200600A2707810141A012000007800F2
+:101670003B1B012001009120018005A07F0E7F0C03
+:101680007C00042C05A04000581B60200C6006A3C1
+:10169000C000551B086006A2C000551B106006A1C3
+:1016A000C000551B06A078005A1B00607800421B42
+:1016B00085A001007C00112041350C228CA10F0077
+:1016C00011203B01042284A0000140006A1B21205C
+:1016D00080FF22217C007E0EE4688CA02000400068
+:1016E000A31B84A00600C000A31B1060078084A079
+:1016F0000F00038003800380F0A00036047084A0F4
+:101700000A00C000A31B087194A100FF4000A31BA6
+:101710008CA1FF000120190006A14000961B0120AA
+:10172000320006A140009A1B78009E1B0920200071
+:101730007800A01B09203F007800A01B11200000AA
+:10174000002105A20A707F0E7C006800A51B7E00A8
+:1017500071200000187084A00100C000AA1B7F0047
+:10176000082E71201000CA707F00C670C3700280FE
+:10177000712000001B700100912080407F007020CC
+:101780007F007800C11B7E107E007E129120002316
+:101790003C7F587E307C387D94A53F0084A4004077
+:1017A0004000D81B84A77C00C0009C2D7810A51B8E
+:1017B0009CA40F0082A304005000E01B7810A51B1E
+:1017C000078584A00F007900E51BEA1F9A20C0203E
+:1017D000E6226B25B325EA256526BF2644270B1C88
+:1017E000F51B531E1D1F4A25F51B7810A51B18005D
+:1017F000C81B7F12912001807F007F107C00037046
+:1018000000003F700000307005A04000091C3370DC
+:1018100000001800C81B5C7005A0C000B61CA070BA
+:1018200084A007007900141CD61C1C1C2A1C4B1C0D
+:10183000711C9D1C9B1C1C1C087884A0FDFF0A7851
+:101840000920460078101224C000281C03700400F0
+:101850007800F71B78105E2DC000491CB47007801B
+:101860009B787E00AA789B781000AB780C009B7860
+:101870006000AB7801005B7804000920F700781065
+:101880001024C000491C03700400C3700F003370A3
+:1018900070357800F71B78105E2DC0006F1CB47196
+:1018A00007819B787E00AA789B7810008CA10700A6
+:1018B0008DA1C000AA79AB7806009B786000AB7858
+:1018C00002005B7804000920F70078101024C000A3
+:1018D0006F1C03700400C3700F0033707035780004
+:1018E000F71B78105E2DC000991CB47107819B789E
+:1018F0007E00AA789B7810008CA107008DA1C00003
+:10190000AA79AB782000B871AA79AB780D009B78E2
+:101910006000AB7804005B7804000920F7007810C1
+:101920001024C000991C03700400C3700F003370B2
+:1019300070357800F71B78004B1C78105E2DC000C6
+:10194000F71BBC7068209B781000106F7810A12CDA
+:10195000502C106884A0070085A08000AA78186E1B
+:1019600041200100012004007800DE1D78105E2D6A
+:10197000C000F71B9B7810005C706820106F781017
+:10198000A12C502C086085A010000A60106884A06B
+:10199000070085A08000AA783120200041200100A6
+:1019A0007810C52D012003007800C91D1800C81B40
+:1019B000407485A400004000F01C80A080353020D9
+:1019C000447108812AA14800E71C09208035642160
+:1019D0000465FF85C000FD1C2184C000E11C467128
+:1019E000037000003F7000007800F71B4076B0A63F
+:1019F0008035447100267800EC1C46716825582516
+:101A00003E75502C346085A00000C000FA1C0867A9
+:101A1000367784A73F0140002F1D84A72100C00016
+:101A2000FA1C84A7020040001C1D84A7040040008B
+:101A3000FA1CBCA7FBFF0A6784A70800C000FA1CB9
+:101A400084A71000C000FA1C84A7000140002F1DCD
+:101A5000186005A0C000FA1CBCA7FFFE0A671F683B
+:101A60000000186E84A60E00186140003F1D1C6027
+:101A700002A14800421D4000421D7800F61CFF8173
+:101A8000C000F61C84A78000C000481D0C702260B6
+:101A9000BCA77FFF0A67106B078384A00F00038039
+:101AA0000380038080A00036602048204A700060D8
+:101AB0004E7004605270602A1800C81B9B7810009A
+:101AC00046A078105E2DC000F71B106B9CA307008A
+:101AD0009DA3C0004C7084A000804000731D84A6AC
+:101AE00001004000751D9CA3BFFF84A610004000AC
+:101AF0007B1D9DA32000AA7B408884A60E00C00009
+:101B0000861DBDA710000A677800C71D4C718CA107
+:101B100000084000022911202100048004804800B0
+:101B20009D1D11202200048048009D1D11202000D1
+:101B3000048048009D1D4000C71DAA7A4088781087
+:101B4000772D106A0C6108818CA1FF00E0A1803E16
+:101B5000642CFF8C4000BE1D106006A2C000A81DB2
+:101B6000B4600180B660C000A31D7E0C602A0860CE
+:101B700085A000010A607F0C7800D61C78105E2DCD
+:101B8000C000F71B602A0E61AA7940882E710120DF
+:101B900001007E00507184A118004000DD1D84A169
+:101BA00010004000D71D7810CC2AC000DD1D84A194
+:101BB00008004000DD1D7810E6297F0002708CA629
+:101BC0006000FF884000E61D8DA104005A79B269CB
+:101BD0009B7860000028AA789B786100146885A033
+:101BE00000801668AA787E157E137E14A1202C0131
+:101BF0009B7800000080AC8080AD0A009820A6533E
+:101C00007F147F137F15106807809B787E00AA7869
+:101C1000906DD67DDE7D946ED27EDA7E307884A0A3
+:101C2000C000C000151E98001D1E086084A0EFFFB4
+:101C30000A607810772D7800FF1B007284A20700DD
+:101C400086A00100C0002A1E1B7849007810772D5D
+:101C500078003B1EB06A95A200205A7A1B78490092
+:101C60007810772D0072002505A640003B1E84A247
+:101C700007007910491E80AD0800327084A2070069
+:101C800086A00100C000471E186000801A6078001E
+:101C9000F71B511EF030F030DF30F030511E511E76
+:101CA000511E7810A51B087884A0FDFF0A787E0FCE
+:101CB0007920003598787F0F84A001004000791EBC
+:101CC000A07086A00100C000681EA2707800011FED
+:101CD000A07086A00500C000771EBC706820176841
+:101CE0000400136800001C6885A008001E68A3702B
+:101CF00000007E1511200400A07186A101004000A3
+:101D00009B1E86A10700C0008B1E09202B350B20CF
+:101D1000050078009B1E0920133504210920123587
+:101D20000A2009202B350B200100A3700000A770AA
+:101D3000010078009D1EA37000007810C72EA92016
+:101D40001000392000007810A62BB8A70001700001
+:101D5000AB1E7800A31E007020207900AF1EDD1E90
+:101D6000C61EC61EB91EDD1EDD1EB71EB71E7810AC
+:101D7000A51B21205735042405A04000C61E06AD32
+:101D8000C000C61E006822207800D61E1C6884A0F1
+:101D90000100C000D21E106F7810A12C7810D92835
+:101DA0007800D61E5470602000680260166A1C68B5
+:101DB00085A008001E687810DD172120803F78106C
+:101DC000071F212057357810071FA9200000212068
+:101DD000803E7810071F20847000F01E7800E91EF6
+:101DE000A9208000612080361860106102A1126075
+:101DF0001B600000E0AC10007000001F7800F41EB3
+:101E00007F15037000003F7000007800F71B7E0410
+:101E1000042405A04000191F682000687E00166A8F
+:101E20001C6885A008001E687810DD177F00780008
+:101E3000091F7F04232000007C0082A203005000C1
+:101E4000231F7810A51B00237900261F291F9C1F24
+:101E5000AA1F82A2020040002F1F7810A51BA070AD
+:101E6000A3700000C37000007900361F3E1F3E1FA4
+:101E7000401F741F08293E1F741F3E1F7810A51BAA
+:101E8000B4777810A62BB477BCA7000F7810A12CDC
+:101E9000186005A040006B1F2120803F092004002E
+:101EA000112010007810C51F40006B1F7E15A9205F
+:101EB00000002120803E7E04092004001120100033
+:101EC0007810C51F7F0440006A1F208470006A1FBD
+:101ED00078005B1F7F15388784A70700C000461F66
+:101EE0007800FF1B7800FF1BB4777810A12C1860D6
+:101EF00005A040009A1F2120803F092005001120E5
+:101F000020007810C51F40009A1F7E15A9200000F0
+:101F10002120803E7E040920050011202000781039
+:101F2000C51F7F044000991F20847000991F78000E
+:101F30008A1F7F157800FF1B002279009F1FA21FB8
+:101F4000A41FA41F7810A51BA3700000A770010098
+:101F50007800F71B00227900AD1FB21FA41FB01F2D
+:101F60007810A51B78101F24007086A00100C00007
+:101F7000AF287810EF28086084A0EFFF0A6078107F
+:101F8000A2284000AF287800D61C042405A04000F9
+:101F9000E61F6820042D7E00106806A74000D41FAD
+:101FA000202D7F007800C61F7F00222016691C6844
+:101FB00005A21E687810DD171060018012600860AD
+:101FC00084A0EFFF0A607810EF287C0085A0010054
+:101FD0007800E51F00237900ED1FF21FF01F352068
+:101FE0007810A51BE47805A0D00015201800152056
+:101FF000082084A03000C00001201B784900780030
+:10200000F71BEC7884A003004000FD1F002184A092
+:10201000070079000B20232029201D201320582D94
+:10202000582D13202F207810A51B007005A040000C
+:10203000FF1B012003007800FA227810892B1B78FF
+:1020400055007800F71B7810892B1B78DC0078008E
+:10205000F71B7810892B1B78E3007800F71B7810AA
+:10206000892B1B789D007800F71B84A50F00C0000A
+:102070005F2078101F24007079003E2046205320F6
+:102080004620AF284820AF28462046207810A51BC0
+:10209000A071A370000086A10400C0005120780048
+:1020A00008297800AF287810EF28086084A0EFFF97
+:1020B0000A607810A2284000AF287800D61CE47887
+:1020C00005A0D000152018001520082084A030009D
+:1020D000C0006E201B7849007800F71BEC7884A0C4
+:1020E000030040006A20002184A1070079007820C5
+:1020F00088208E2082208020582D582D8020502D21
+:102100007810A51B7810912B1B7855007800F71BD1
+:102110007810912B1B78DC007800F71B7810912B3E
+:102120001B78E3007800F71B7810912B1B789D003B
+:102130007800F71B002379009D20A220A020A42076
+:102140007810A51B7800652617680800A3780000A2
+:10215000E47984A1300040006526EC7884A0030077
+:102160004000652684A107007900B620232029209D
+:102170001D20302D582D582DBE20502D7810A51B18
+:1021800082A205005000C6207810A51B002379000C
+:10219000C920CC20CE22DA2200227900CF20D42000
+:1021A000D620E920D420B3227810A51B9B781800F4
+:1021B000A87884A0FF0082A0200048006A2B8AA093
+:1021C0000400C8006A2B7900E5206A2B6A2B6A2B71
+:1021D0000C2B9B781800A87984A180004000FE2079
+:1021E00084A118004000FA2078006A2B007005A036
+:1021F000C000F420112003007800522784A1FF00C2
+:102200008AA01000C8006A2B790006211821162127
+:102210002E213021C2216A2B6A2BC4216A2B6A2B02
+:10222000AF22AF226A2B6A2B6A2BB1227810A51B32
+:1022300084A60010400025210120000300800080BA
+:102240003A781B789A007800F71B146884A0008005
+:1022500040002C21176803007800302D7810A51B52
+:102260001C691E6984A60018C0004A211C6884A04D
+:102270000100C0005221146886A00800C00042215D
+:102280001768000084A600044000BE211B78580097
+:102290007800F71B84A60010400052211B785800DC
+:1022A0007800F71B84A660004000BA2184A60008CD
+:1022B0004000BA2184A60080C000602178007A2105
+:1022C000B4A6FF7F5A7EB26E9B787400AC7AAC796C
+:1022D000AC781B80C8006D21008084A03F0008A15D
+:1022E00091A20000946B002102A3AE68906B0022C3
+:1022F00003A3AA6884A6004040008221B4A6FFBFC1
+:102300005A7EB26E007086A00300C0008F21781044
+:102310003A2F7810DF301B7867007800F71B06A093
+:1023200078109431AC6AA869946C906B002205A176
+:1023300040009E21002222A400211BA3D27CD67B38
+:10234000002305A4C000AC21B5A600405A7EB26EA1
+:102350001B7867007800F71B1B786700002215A127
+:10236000C000B6217810F0307800F71B78101D31CE
+:102370007800F71B1B786A007800F71B1B78580061
+:102380007800F71B7810A51B780021221C6984A116
+:1023900000014000DC218CA1FFFE1E697E0C48700C
+:1023A0006020006084A0FFEF0260046084A0F5FF5D
+:1023B00006607F0C7800102284A1000240001022E9
+:1023C0008CA1FFFD1E697E0C48706020006084A017
+:1023D000FFDF0260046084A0EFFF06600820482C45
+:1023E0007F0C84A108004000102278109D2C7810EA
+:1023F000E629FF88400010229B7860000028AA7818
+:10240000587EB5A604005A7E84A60004C0000C22A3
+:102410001B7855007800F71B1B7869007800F71BC4
+:10242000587E84A60004C00019221B78580078004A
+:10243000F71B1B786A007800F71B7800702B780078
+:10244000702B1920000090798CA1070040001F22FA
+:102450009B781000A87894A0FF0086A20100C0001D
+:1024600044220023A87C00A4182002A140003C22A2
+:1024700048003C2278003E227800C621A824A87A91
+:10248000F0003E2278002A2284A2F00086A02000DC
+:10249000C000A02218831883002302A14000542208
+:1024A0004800542278009D2286A2230040001F226B
+:1024B000186884A0F1FF1A68587E84A6F1FF85A0F1
+:1024C000100030205A7E086085A010000A607E0C43
+:1024D0004870602004600820482C7F0C84A1100004
+:1024E0004000782278109D2C7810CC2A7800872222
+:1024F0007E0C4870602004600820482C7F0C84A16A
+:1025000008004000102278109D2C7810E629FF88E2
+:10251000400010229B7860000028AA78B5A604002D
+:102520005A7E84A60004C00099221B7855007800CA
+:10253000F71B1B7869007800F71BA87A78002A221D
+:102540001883002302A14000A9224800A922780094
+:102550002A2284A28000C000762B7800702B78009D
+:10256000762B78006A2B9B781800A87884A0FF004F
+:102570008EA001004000BE227810A51BA87A94A26C
+:10258000FF00A87884A0FF008AA00400C8006A2B7E
+:102590007900CA226A2B39296A2B672A82A2000095
+:1025A000C000D4227810A51B7810892B1B786900F5
+:1025B0007800F71B82A20300C000E0227810A51B60
+:1025C0007810992B1B7869007800F71B82A2040011
+:1025D0005000EC227810A51B00237900EF22F22294
+:1025E000C923FA2386A203004000F8227810A51B15
+:1025F000012000003A70007084A0070079000023D9
+:1026000008230A230A2308253025D2240823082377
+:102610007810A51B84A60010C00012237810C72EC6
+:102620004000A32368788CA0FF0040005A2386A1B5
+:102630000800C00029237810EF28086084A0EFFF6D
+:102640000A607810A22840005A237810C72E78001C
+:10265000412386A12800C0005A237810C72E0860A5
+:1026600084A0EFFF0A60186005A0400041230180AC
+:102670001A6005A040004123018005A040004123CD
+:102680001E601C6884A001004000FF1B1C6884A021
+:10269000FEFF1E6854707E0C6020006802607F0C94
+:1026A0000460026805A0002DC00057230260066088
+:1026B0007800FF1B7E0178101F247F0184A600DFB5
+:1026C0001A6827680000106FFF814000A32386A1CD
+:1026D0000200C0009B2384A60008C000772384A6C4
+:1026E000600040007723D878DC7A2E682A6A178742
+:1026F00094A20F0013821382138290A2003690A23C
+:1027000000001C2284A30001C000882378008E23CF
+:102710001082042285A018001220118284A30004D4
+:1027200040009B239C6884A00001C0009B2378107C
+:1027300091247800FF1B86A118004000A32386A1E6
+:1027400014004000FF1B1269146884A00080400040
+:10275000AB23387016688CA600DF1A697810E02861
+:102760007810EF28C000B823086084A0EFFF0A604B
+:102770001C6884A00100C000C1237810D92878000B
+:10278000C52354706020006802607810DD1778005F
+:10279000FF1B82A204004800CF237810A51B002253
+:1027A0007900D223D623D823E523D8237810A51B7C
+:1027B000007086A005004000E1237810892B1B786B
+:1027C00069001B786A007800F71B90780780018009
+:1027D00084A0070080A018009A78A8798CA1FF0037
+:1027E00086A103004000F62378006A2B1B786A005C
+:1027F0007800F71B1C6885A004001E68FF82C000DB
+:1028000005247810892B78000C24118240000A24BA
+:102810007810A51B7810992B1B7869007800F71B9E
+:102820007810772D307884A0C000C0001C241800D8
+:102830001C241A7906A07C0085A001007C0084A6D7
+:102840006000C00029242F6800002B680000780079
+:10285000902484A60008C0003824B06884A00048F2
+:1028600035A684A60008C00038247810C72E7C0046
+:1028700084A6200040006224D0780380C80046244B
+:1028800006A078109431D4787810F93184A60040ED
+:10289000400050242F6800002B6800007800352489
+:1028A000B06884A0004835A684A60040C0004A2431
+:1028B000387005A0C0005C24D879DC7A2E692A6AB9
+:1028C0007800352484A6004040006C242F68000066
+:1028D0002B68000078003524B06884A0004835A635
+:1028E00084A60040C0006624387005A0C0007A2489
+:1028F0003B700700D879DC7AD078F380C800812457
+:10290000008084A03F0008A191A200002E692A6ADD
+:10291000002105A2C0008E2478003524781094315F
+:102920007C0084A3000240009924086085A0020076
+:102930000A6017680600286A2C693A6A3E692B68A3
+:1029400000032F6800003368002093680000976838
+:10295000200000707900AC24B424B624BF24B42431
+:10296000B424B424B424B4247810A51B1C6884A017
+:102970000100C000BF247810D9287800C524547005
+:10298000502C602000680260602A21205735042402
+:1029900005A04000CE2420207800C724222D6B20E3
+:1029A00000007C00B4777810A62BBCA7000F78102D
+:1029B000A12C186005A0400001257E0D0120903F4C
+:1029C00068207F0D2120803F092004001120100085
+:1029D0007810C51F400001257E15A9200000212088
+:1029E000803E7E0409200400112010007810C51FCD
+:1029F0007F04400000252084700000257800F12429
+:102A00007F15388784A70700C000D7247800FF1BF4
+:102A10007810E0287810EF28276800009B780E00D7
+:102A2000106F136802007810CA3184A600084000B5
+:102A30001D2518698DA100201A69146884A00080E2
+:102A40004000242517680000212057350068222007
+:102A5000386A3C692A6A2E697810DD177800FF1BF6
+:102A600078101F24276800009B780E00106F7810E4
+:102A70007C2D8CA0FF001269146884A000804000A7
+:102A80004325387016688CA600DF1A69A370000011
+:102A90007800FF1B06A07810C72E13680000176887
+:102AA00001008CA600DF1A69276800000070790019
+:102AB00059256125632563256525652565256125DE
+:102AC00061257810A51B7810EF28086084A0EFFF1F
+:102AD0000A607800BA28002379006E2571257325D5
+:102AE000B1257810A51B0070790076257E258025FC
+:102AF00080258B25802592257E257E257810A51B97
+:102B000084A60020C0008B25B5A600205A7E781030
+:102B1000F0307800302D146884A0008040009225A9
+:102B200017680700092018350C2186A10000400015
+:102B3000A72586A101004000AB2509202B350B20DD
+:102B40000B00A37001001B7846007800F71B1B7870
+:102B5000DD007800F71B09202B350B200A007800D8
+:102B6000F71B7810A51B00237900B625B925BB25D6
+:102B7000DE257810A51B00707900BE25C625C82566
+:102B8000C825D325C825DA25C625C6257810A51B56
+:102B900084A60020C000D325B5A600205A7E781058
+:102BA000F0307800302D146884A000804000DA25D1
+:102BB000176807001B78E4007800F71B1C6885A0E5
+:102BC00004001E68B5A600087810892B1B786900E0
+:102BD0007800F71B00237900ED25F025F225F42578
+:102BE0007810A51B7810A51B84A60004C00013262E
+:102BF0002B7809309B786000AB78000084A6FBFF3F
+:102C00005A78E47984A1200040000B26EC7884A057
+:102C10000300C0000F26012014007800FA2284A1CE
+:102C2000070079004B26907A94A207009B786000F9
+:102C3000A879FF81400049269B781000A87B84A3D7
+:102C40000100C0003A26A87BA87B86A30100C00033
+:102C50002D260920F7FF7800332686A30300C00045
+:102C60003A260920EFFF7E0C48706020046004A122
+:102C700006607F0C9B786000AB78000084A6FBFFA9
+:102C80005A782B7809301C698CA1FFFD8CA1FFFEBE
+:102C90001E697800302D2320292055265D265326D5
+:102CA00053265326302D7810A51B1C698CA1FFFDDF
+:102CB0008CA1FFFE1E697800382D1C698CA1FFFDD8
+:102CC0008CA1FFFE1E697800302DE47984A13000CC
+:102CD00040006F26EC7884A00300C00077261468BB
+:102CE00085A000801668012014007800FA2284A1D3
+:102CF000070079007B26302D302D8326302D582D6E
+:102D0000582D302D302D84A60004C000B4261C6838
+:102D100084A001004000382D8CA660208CA1FBFF10
+:102D20005A79B2699B786000AB7800009B786100AB
+:102D3000146885A000801668AA787E157E137E141C
+:102D4000A1202C019B7800000080AC8080AD0A009F
+:102D50009820A6537F147F137F15106807809B78F7
+:102D60007E00AA787800382D146884A00080400086
+:102D7000BB26176808001B78D8007800F71B0023D3
+:102D80007900C226C7264227C5267810A51B0070E9
+:102D900084A007007900CC26D426D626F226D42695
+:102DA000D426D224D426D4267810A51B1C698DA144
+:102DB00001001E690068066005A0C000E0260260F0
+:102DC000186884A00E004000EC261470B6682C71C0
+:102DD00088A1803E7800EE260920803F0421026809
+:102DE0000A2D5671B26E84A660004000402784A66A
+:102DF0000008C000042784A6FF7FB268906894682A
+:102E00007810C72E7800402784A62000400016279F
+:102E100006A078109431D0780380C8001227D478A7
+:102E20007810F931D879DC7A78001A277810AE2C2E
+:102E30007810943184A600804000402784A6FF7F4C
+:102E4000B2689B78740078107C2D102078107C2D4F
+:102E5000082084A62000C000382778107C2D1B8015
+:102E6000C8003327008084A03F0008A191A2000081
+:102E7000946B002102A3AE68906B002203A3AA68A2
+:102E80007800FF1B7800762B3370000082A20500CB
+:102E900050004C277810A51B002379004F2752279C
+:102EA0005C277F270022790055275A27762B5A273F
+:102EB000A827F9277810A51B007086A00100C00084
+:102EC00069277810EF287810C72E34700A607800D0
+:102ED0006E27007086A00300400063270370050082
+:102EE0000120903F68203E703270002279007827E0
+:102EF000762B7D27A8277D27762B7810A51B0070C1
+:102F000086A00100C0008C277810EF287810C72E0B
+:102F100034700A6078009127007086A0030040009A
+:102F20008627037005000120903F68203E703270B4
+:102F3000002279009B27A227A027A227A027A2274B
+:102F40007810A51B7810992B1B7869007800F71B67
+:102F5000007086A00100C000B5277810EF28781017
+:102F6000C72E34700A607800BA27007086A003006C
+:102F70004000AF2703700200807A94A2000F9B7874
+:102F80001800A87C84A4070015A26920803F042DA6
+:102F9000082D5671682005A04000D527106806A2AC
+:102FA0004000EE2700687800C82703700500012064
+:102FB000903F68203E7032707E15A9202F000320BC
+:102FC000000000807000E6277800DF277F15126A76
+:102FD000B36800071F68000823680300B06E5A7EBC
+:102FE0001C6884A0000C40004F287810912B7800BA
+:102FF0004F28007086A00100C00006287810EF2836
+:103000007810C72E34700A6078000B28007086A0F4
+:1030100003004000002803700200807A94A2000F91
+:103020009B781800A87C84A4070015A2A879A87929
+:103030008CA1FF00E8A1803E042D082D5671682068
+:1030400005A040002A28106806A240004328006816
+:1030500078001D28037005000120903F68203E7015
+:1030600032707E15A9202F00032000000080700020
+:103070003B28780034287F15126AB36800071F6860
+:10308000000823680300B06E5A7E1C6884A0000C00
+:1030900040004F2878108D2B587E78004F287E02F4
+:1030A000078284A00F0003800380038080A0003685
+:1030B00060204A7000604E700460527084A6600008
+:1030C00040008628946B906CA869AC6805A1C0008C
+:1030D0007428D27BDA7BD67CDE7CB4A6FFB75A7E1E
+:1030E0007810F03078008628AC681AA3002123A459
+:1030F000002405A340008628D27BDA7BD67CDE7CC8
+:10310000AC68B4A6FFBF5A7E78101D317F077810D7
+:10311000A12C09206A0084A60800400091280920FB
+:103120006900B5A600205A7E1A79002D3E700782EC
+:1031300084A00F0003800380038080A00036482015
+:103140007800F71B206005A04000AE2801802260B7
+:10315000086085A008000A60107026607C0006A048
+:103160007810C72E13680000176801001F68400020
+:103170001B680001007084A007007900BF28C728E1
+:10318000C928C928D528D128C728C728C728781012
+:10319000A51B7810E0287810D9287810DD17780062
+:1031A000FF1BA37000007800FF1B17680000780069
+:1031B0000825006805A0C000DE28026006607C00CB
+:1031C000106005A04000E9280180D000E9287810AF
+:1031D000A51B1260086084A0EFFF0A607C001860E5
+:1031E00005A04000F52801801A607C007810772D3A
+:1031F00017681800780026297810772D17681900AD
+:10320000780026297810772D17681A00780026296B
+:10321000B4777810A12CB8718CA1FF00E8A1803E92
+:10322000042D082D682005A0C00018297800FF1B78
+:103230001068B47206A240002029006878001129A5
+:1032400000680A2017680500BF7000007810E028A9
+:103250001C6884A00100C0002F297810D92878109C
+:10326000EF281B6800001F6820007810DD17780029
+:10327000FF1B82A20300C0006A2BA87DACA5FF0043
+:10328000A87EB4A6FF001C698DA180001E6984A1E0
+:103290000001400099298CA1FFFE1E69B4A6FF0021
+:1032A0004000832982A60F0048005A2940005A296D
+:1032B00031200F002B852B857810242C40006429A9
+:1032C0007810332A78008C297810DF2B7E0C602947
+:1032D000046084A0F5FF06607810572A7F0C1C69F3
+:1032E0008DA100011E69587EB5A604005A7E84A6F1
+:1032F0000004C0007F291B7855007800F71B1B785D
+:1033000069007800F71B7E0C6029046084A0F5FF3B
+:1033100006607810572A7F0C587E84A60004C000EF
+:1033200095291B7858007800F71B1B786A007800F5
+:10333000F71B7E0C4870602000618CA100104000DB
+:10334000D9290862178294A2FF0082A20F004800C8
+:10335000AD294000AD2911200F00002602A2C800AF
+:10336000B2293022086294A2FF00187086A02800BB
+:10337000C000C22982A21900C800C8291120190062
+:103380007800C82982A20C00C800C82911200C00AE
+:10339000002202A5C800CD2928227810E32B2B8516
+:1033A0002B857810242C4000D9297810332A7800F6
+:1033B000DD297810DF2B7810572A587885A0040073
+:1033C0005A787F0C1B7869007800F71B7E0C602907
+:1033D000006084A00010C000012A106084A00F00CB
+:1033E000C000FB298CA10200C000FB298CA1F5FFC5
+:1033F00006617F0C7C00112032001920000078004B
+:10340000232A086294A2FF00187086A02800C0003A
+:10341000112A82A21900C800172A11201900780069
+:10342000172A82A20C00C800172A11200C0008637A
+:103430001F839CA3FF0082A30F004800232A4000A3
+:10344000232A19200F00AB780100AB780300AB787A
+:103450000100AA7AAA7BC0A805001C6885A000010B
+:103460001E687F0C7C007E0C48716021082084A0BF
+:10347000F0FF35A6867E18609A78AE7E1266A47834
+:1034800084A0F8FF8CA1070005A1A67816608A78B1
+:10349000B4A60F0037860482048084A0FF0005A62E
+:1034A0000E60046084A0F5FF06607F0C7C007E0C3B
+:1034B0004870602018609A78A47884A0F0FFA678FD
+:1034C0001260847884A0F0FF86787F0C7C0082A252
+:1034D0000200C0006A2BA87A1C698DA180001E69B9
+:1034E00084A100024000AC2A8CA1FFFD1E6994A2B9
+:1034F000FF0082A20200C8006A2B7810F32A78101D
+:10350000572A80A901000C2078109D2C7810E629FC
+:10351000FF8840009F2A9B7860000028AA78587E88
+:10352000B5A604005A7E84A60004C0009B2A1B781E
+:1035300055007800F71B1B7869007800F71B587E50
+:1035400084A60004C000A82A1B7858007800F71B46
+:103550001B786A007800F71B82A20200C800B42A18
+:1035600084A201004000BE2A487188A100000C21FD
+:103570008CA10020C000BE2A112000007810D12BA1
+:103580007810F32A7810572A587885A004005A78C2
+:103590001B7869007800F71B7E0C7E0260290060B2
+:1035A0001120010084A00020C000E32A146084A040
+:1035B0004000C000E12A8CA1EFFF066106A0780060
+:1035C000F02A11200000AB780100AB780200AB7844
+:1035D0000300AA7AC0A804001C6885A000021E6827
+:1035E0007F027F0C7C007E0C48706020FF824000D0
+:1035F000FB2A11204000186080A002009A78A4786D
+:1036000084A0BFFF05A2A67816608A78046084A013
+:10361000EFFF06607F0C7C007E00007086A0030038
+:103620004000152B7F007800182B7F007800662B58
+:1036300084A620004000662B887884A040004000CB
+:10364000662BA87801804000252BB87B84A33F001F
+:103650001B83C8002C2B008005A040004D2B1B8332
+:10366000C800352B01804000622B06A078109431F1
+:10367000B4787810F9317800662B84A600404000B9
+:103680004D2BB8781B80C800462B008084A03F00DB
+:10369000C000622BB4A6FFBF5A7ED879DC7A012025
+:1036A000010008A1C800562B91A20000D279DA7956
+:1036B000D67ADE7A781094311B78670078105E3005
+:1036C0007800F71B1B7867007800F71B1B786A00EF
+:1036D0007800F71B78109D2B1B7869007800F71B8A
+:1036E0007810892B1B7869007800F71B236802008B
+:1036F0007810912B1C698DA120001E69146884A08C
+:1037000000804000852B176805001B786900780051
+:10371000F71B0120050078009F2B01200C0078008A
+:103720009F2B0120060078009F2B01200D007800C0
+:103730009F2B0120090078009F2B012007009B7818
+:103740007F00AA78B5A608005A7E7C007E073F87D6
+:10375000BCA70F003B873B870387E0A00036B8A7D4
+:1037600020009A7FA47984A10F004000BF2B84A180
+:10377000F0FFA6781260046085A008000660388714
+:1037800038879A7FA47984A140004000CF2B84A180
+:10379000BFFFA6781660046085A0100006607F0752
+:1037A0007C009B781000AB780100AB780200AB780E
+:1037B0000300AA7A9B786000AB7804007C0031207B
+:1037C0000000292032009B781000AB780100AB7814
+:1037D0000300AB780100AA7DAA7E9B786000AB78DD
+:1037E00005007C007E15078084A0FF000380038015
+:1037F00080A020009A78A4798CA1F0FF01204635A2
+:10380000042082A0280040000D2C2120842C1920A7
+:103810001400A9200C007800132C2120902C1920D2
+:103820001900A9200D0011206400042484A0F0FFD9
+:1038300006A14000222C2084002310A27000222C1C
+:103840007800152C7F157C007E151120463514223A
+:1038500082A232004800382C40003C2C2120762CDB
+:1038600019201100A9200E001120320078004C2CE4
+:1038700082A228004000442C2120842C192014000E
+:10388000A9200C0078004A2C2120902C1920190026
+:10389000A9200D0011206400002202A540005C2C2C
+:1038A00048005C2C2084002310A27000592C780062
+:1038B0004C2C7F1506A07C007F1582A56400C800F3
+:1038C000652C087885A070000A78EC7884A0000345
+:1038D0004000732C04249EA00112C000732C012010
+:1038E00001217800742C042405A07C000112023010
+:1038F0000232034203440454045605660568067800
+:10390000067A070A070C070E0232024202520262CE
+:103910000272056605760578057A057C057E057FC9
+:1039200002220232024202520454046404740476F5
+:103930000478047A047C047E047F9B78100046A0FF
+:103940007C0084A7000F0C8084A7070003800380FD
+:103950000380038005A1E0A080367C00D879DC7A62
+:10396000D0781B80C800B52C008084A03F0008A13F
+:1039700091A200007C007E0F7920000109204035D3
+:103980009120008004217900C52CF72CCF2CCF2C5E
+:10399000CF2CCF2CCF2CCD2CCD2C7810A51B4B7839
+:1039A0000400487884A00400C000D12C4B780800A3
+:1039B000487884A00800C000D82CB06885A00040DA
+:1039C000B268587885A000405A78307884A080008A
+:1039D000C000F72C1800F72C186884A02000C00045
+:1039E000F52C1B78DD007800F72C1B78E400912083
+:1039F00001807F0F7C007E0C1068078084A00F0080
+:103A0000038003800380E0A00036046084A00A00E5
+:103A1000C0002E2D086194A100FF40002E2D8CA126
+:103A2000FF000120190006A140001D2D01203200D9
+:103A300006A14000212D7800252D092020007800C6
+:103A4000272D09203F007800272D1120000000219C
+:103A500005A20A60046085A0020006607F0C7C005D
+:103A60001B786A007800F71B1B7869007800F71B49
+:103A70001B7858007800F71B1B7855007800F71B5F
+:103A80001B78DD007800F71B1B78DC007800F71B43
+:103A90001B78E4007800F71B1B78E3007800F71B25
+:103AA0001B789E007800F71B1B789D007800F71BA1
+:103AB000A37001001B7846007800F71B7E00307869
+:103AC00084A0C000C000752D087884A0FDFF0A788E
+:103AD0000500050005000500EC7884A021004000E9
+:103AE000752D087885A002000A787F007C00087890
+:103AF00085A002000A787C00307884A04000C000D5
+:103B00007C2D9800852DAC787C00087884A0FDFF82
+:103B10000A780500050005000500EC7884A0210066
+:103B20004000942D9800922DAC787E00087885A0F6
+:103B300002000A787F007C0084A770004000A82D56
+:103B40007E0C602D682F78106B1B782D682C7F0CF5
+:103B500017680300587884A0003F1A682F68000097
+:103B60002B6800004B780800E47805A0D0001520F1
+:103B700084A0200040001520EC7884A003004000C1
+:103B80001520180015207800702B7E0C1068078017
+:103B900084A00F0003800380038080A00036602093
+:103BA00048204A7000604E70046052707F0C7C00A8
+:103BB0002000200000002000000020000000200065
+:103BC0000000200000002000000020000000200075
+:103BD0000000200000002000000020000000200065
+:103BE0000000200000002000000020000000200055
+:103BF000000020006200090014001400479814001F
+:103C00001400F598E798140014008000BF0000012C
+:103C10000204082080F80AA214000B300CA2140041
+:103C200000A238887E812A84A08406383988C22878
+:103C3000C39C05A864083BA80830C128C39C01A206
+:103C40000C30472861816A840080A48456183A8821
+:103C500008A8E228A09CF3A8640829A80C3001A8B1
+:103C60000830E128A09C0D2804A2C064A067C06FA2
+:103C700014183B882370768577860FA86E783E8867
+:103C80000CA82B2805A2A064A067C06F14183B885D
+:103C900023707685778601A83E886920C128C39C59
+:103CA00044200321A2208120DCA807A2140003A243
+:103CB0000080A884A48572189A843C88E21F01F6CB
+:103CC00008A26E856F8604070830A09C140002A22B
+:103CD0000080A4850930A884E21948F87481EB8635
+:103CE000EB852E87A9873F88E608F1A861F8E8A848
+:103CF00001F8140081F81600B285F0803295A2FA1E
+:103D0000E21D1400328521F21400E21DA884E0D6E1
+:103D1000E61F140006A265687F812A84C11D2388DE
+:103D2000160042600880FAA80080A48460812A847A
+:103D300021F00830A884C61DD720228816000080F4
+:103D400048281110FCA80830008000A0022811109B
+:103D5000FDA887A808303D281110FDA809A217006A
+:103D60000C300080A485E21DC1DA1400E0263A87F9
+:103D7000A2FAF219E21F14000BA214000DA27E8118
+:103D80002A84A08406381002CD9C040700007E120D
+:103D9000912000224920C72E0070047205A20C72E7
+:103DA00015A2087084A0FDFF05A24000D92E78005E
+:103DB000DE2E037000007F1200207C00007084A0C3
+:103DC0000100C0000C2F08710481C800EB2E781090
+:103DD000A82F7800E32E0C708CA07F0040000C2FE1
+:103DE00004700480C800032F147005A0C000FF2ECB
+:103DF000107005A04000032F02A1C800E32E077039
+:103E0000100078000C2FFF8A40000C2F78106B31C7
+:103E1000C000062F4000E32E7810562F03700000DC
+:103E20007F1200207C002464FF844000302F702C1F
+:103E30003920352F042768AE0C6830A6086829A5FC
+:103E400021844000302F3887042705A0C0001B2F95
+:103E5000987075A04000302F3920322F78001A2F2B
+:103E60007C000000040008000C0010001400180082
+:103E70001C0000007E129120002279200035712064
+:103E8000100007700A000770020003700000712024
+:103E9000200007700A00077002000370000049202C
+:103EA0000000B37800007F1200207C004920562FCC
+:103EB00004700480C800822F077012000871087017
+:103EC00006A1C0005E2F84A1300040006B2F86A0A9
+:103ED0003000C0005E2F007084A00100C000822F5F
+:103EE000087084A00C00C000802F0C7184A1000316
+:103EF000C000802F84A17F00C000562F7800822F41
+:103F0000176803000770120007700800047084A08F
+:103F10000800C000862F0770120008710481480055
+:103F20008B2FB378000003700000492000007C0054
+:103F30007E107E007E127E1591200022087178107E
+:103F4000A82F7F157F12912001807F007F107C00B9
+:103F50000472182108710C7084A00003C000EA2FBD
+:103F600084A10C00C000EA2F1382138213821382F3
+:103F700084A200010DA10B810B810F8184A1070098
+:103F80007900C22FCC2FDC2FEA2FDC2FFE2FFE2F43
+:103F9000EA2FFC2F7810A51B07700200FF8AC000D3
+:103FA000D52F492000007800D92F78106B31C00040
+:103FB000D52FB37800007C0007700200FF8AC00094
+:103FC000E32F7800E72F78106B31C000E32FB37830
+:103FD00000007C00077002007810562F7810BB2C70
+:103FE000146884A000804000F72F176802007C004E
+:103FF0007810A51B7810A51B781050301072147122
+:104000000C709CA07F00002800A311A289A10000D1
+:10401000B07805A040001030B3780000780033304D
+:10402000781050300427582C60AC0C63002222A377
+:10403000086300211BA3002405A340002930C80009
+:104040002930128410820A8389A10000602B780035
+:104050001030602B078ABAA7322F3DA7002C826848
+:10406000866F8E6C8A6B077012007810562F7C005A
+:104070003887042705A0C0004430986005A04000A0
+:104080004D3060203920322F518A40004C3008706A
+:1040900084A0C00086A0C0007C00512000007C00ED
+:1040A000508A3987042704A0C0005D303920382F9A
+:1040B000006064A0C0005D30602D7C007E127E0D2B
+:1040C000912000227F0D806860208468886B8C6C52
+:1040D0005780D4AAFF0084A0FF00B8A0322F087E2A
+:1040E000B5A60C00186884A0400040007930B5A641
+:1040F00001007E0F7920000158787F0F84A04000D6
+:104100004000883084A60100C0008830B5A60100B8
+:1041100007700400047084A00400C0008A3000709E
+:1041200005A0400095307810A51B002405A3C00011
+:104130009B307800D830582C042760AC046000A471
+:104140007E001A70006001A31E700920FD04042186
+:1041500086A0FD047F00C000C83084A0010040009C
+:10416000C83084A60100C000C83013700100177069
+:104170000000027607700100B3780100A0A40100DE
+:1041800099A30000046000A41A70006001A31E70CF
+:104190000C62002402A212700862002303A21670AF
+:1041A000027607700100602B781038307800DA3022
+:1041B00078106B31C000D8307F1200207C007E1256
+:1041C0007E0D912000227F0D07700400047084A0F2
+:1041D0000400C000E630037008007F1200207C005D
+:1041E0007E127E0D912000227F0D4920F030077055
+:1041F0000400047084A00400C000F930007005A021
+:10420000400004317810A51B087EB5A60C00186884
+:1042100084A0400040000E31B5A60100246805A02E
+:1042200040001A3150203920352F602D78106B3125
+:10423000C00016317F1200207C007E127E007E01BD
+:104240007E0D912000227F0D7F037F04087EB5A69E
+:104250000C00186884A0400040003031B5A6010071
+:1042600049201D31246855A040006831702D602E12
+:104270003920352F042768AE0C6822A408681BA3D8
+:1042800048005531518AC00047317810A51B388746
+:10429000042705A0C0003B31987075A06020400045
+:1042A00068313920322F78003A31228420841A83F1
+:1042B00099A300000C69002422A1086900231BA116
+:1042C000C80064317810A51B712020007800883068
+:1042D0007F1200207C00087084A0C00086A0C0006F
+:1042E00040009331042708AC04211E70088104218A
+:1042F0001A700881042116700881042112707E0F43
+:104300007920000158787F0F84A0400040008E3152
+:1043100084A60100C0008E31B5A6010002760770A8
+:104320000100781038307C007E127E007E0D9120D6
+:104330000022492094317F0D7F08087184A1C000BC
+:10434000C000AA31246805A04000BA317800DE2EF2
+:104350007800BA3108710481C800B2317810A82FF2
+:1043600078009D310770100008710481C800B431D5
+:104370007810A82F087086A00200C0009D31007040
+:1043800005A0C0009D3103700000492000007F128D
+:1043900000207C007E127E147E137E157E0D9120FF
+:1043A00000227F0D4920CA3180AD1000A020992045
+:1043B00031000C7084A07F00266807700800077029
+:1043C0000200037001004000E8310080AC80A5537A
+:1043D00007700400047084A00400C000EA31492082
+:1043E0000000037000007F157F137F147F120020F0
+:1043F0007C007E127E007E0D912000227F0D4920E0
+:10440000F931806860208468886B8C6C5780D4AAEE
+:10441000FF0084A0FF00B8A0322F087EB5A60400DC
+:1044200007700400047084A00400C0001232582CED
+:10443000042760AC046000A41A70006001A31E7021
+:1044400013700100177000000276077001007F00F2
+:104450000780092031000A20A0002C320871077063
+:1044600002000C81C8002C320C81480039327800DF
+:10447000EA2FA0A4010099A300008A6B8E6C07703C
+:10448000040049200000037000007F1200207C001F
+:10449000A920100006A0048086808E81C8005132B9
+:1044A00000A2F0004C3286808E817C007E15A9200F
+:1044B000100005A0400077321AA1C800773213829D
+:1044C0008D8148006A321AA1C8006B32F0005F3259
+:1044D00078006F321AA108231082F0005F327E004C
+:1044E000003284A0FFF780207F007F157C007E00D3
+:1044F000003285A0000878007332E000BF329120BE
+:104500000060207801802278C000B93224782278B7
+:104510009120008069204035006884A00700400099
+:10452000A13286A002004000A13230680DA04000F8
+:10453000A132042105A04000A13201800A204000E0
+:104540006F3361208036A9208000346005A04000D0
+:10455000B33201803660C000B332106005A0400065
+:10456000B3327810191AE0AC10007000B93278003C
+:10457000A5327810D4327810C2327810F9329120F6
+:1045800001807C003C7801803E78C000D3324078C6
+:104590003E78487805A04000D33201804A78C000B8
+:1045A000D3327810191A7C00347801803678C00034
+:1045B000F8323878367891200080447805A0C00021
+:1045C000E332012001010180467880A0803E402036
+:1045D000042065A04000F832206005A04000F432BD
+:1045E00001802260400028330060402C7800E932CE
+:1045F0007C00287801802A78C00027332C782A781C
+:10460000307805A0C0000633012080000180327898
+:10461000038003800380038090A0803698A202006C
+:10462000042384A008004000273390A2090004223C
+:1046300005A040001F3301801220C000273304234F
+:1046400084A0F7FF85A080001A207810191A7C003A
+:1046500069204035006805A0400032333C6806AC54
+:1046600040006F3317600600B06084A0003F1A60FE
+:104670001C6084A0FF0085A060001E6000604220D6
+:104680001067B66F78109216186805A040004A337C
+:1046900001801A68086884A0EFFF0A68106801802A
+:1046A000D00054337810A51B12682F6000002B60D7
+:1046B0000000682C7810DD176920403501200600C5
+:1046C000A268447984A10001C0006A33BA6901205C
+:1046D0000400A2687810141A912001807C0009203F
+:1046E0004F3564216920000178106B1B17600600AC
+:1046F000586884A0003F1A601C6084A0FF0085A059
+:1047000048001E602F6000002B600000306884A00D
+:1047100040004000AB334B680400A92014004868F7
+:1047200084A00400400098337000983378008F33E1
+:104730004B680900A9201400486884A001004000CB
+:10474000A5337000A53378009C33A920FA007000CF
+:10475000AB337800A733086884A0FDFF0A681B68A4
+:104760004600092068350B2007004C784A789120D4
+:1047700001807C0079200035781003347810CB3329
+:104780007810E0337810F533337800004778000074
+:104790004B7800007C0019200A00112046350422C5
+:1047A00086A032004000DD3319200C00042286A0D0
+:1047B0003C004000DD33192008002A7B2E7B7C0062
+:1047C0001920300011204635042286A03200400016
+:1047D000F23319203900042286A03C004000F23355
+:1047E00019202700367B3A7B7C0019200D00112010
+:1047F0004635042286A03C004000003419200A00FF
+:104800003E7B427B7C001920AF2F112046350422CD
+:1048100086A032004000153419207139042286A088
+:104820003C004000153419202626227B267B7C0084
+:02483000A7924D
+:00000001FF
+/* Version 1.31.00 ISP1000 Initiator RISC firmware */
diff --git a/firmware/yamaha/yss225_registers.bin.ihex b/firmware/yamaha/yss225_registers.bin.ihex
new file mode 100644
index 00000000000..6dd3d8c4de2
--- /dev/null
+++ b/firmware/yamaha/yss225_registers.bin.ihex
@@ -0,0 +1,998 @@
+:10000000FF000E100F00FF000E110F00FF000E1278
+:100010000F00FF000E130F00FF000E140F00FF0073
+:100020000E150F00FF000E160F00FF000E170F0039
+:10003000FF000E180F00FF000E190F00FF000E1A30
+:100040000F00FF000E1B0F00FF000E1C0F00FF0033
+:100050000E1D0F00FF000E1E0F00FF000E1F0F00F1
+:10006000FF000E200F00FF000E210F00FF000E22E8
+:100070000F00FF000E230F00FF000E240F00FF00F3
+:100080000E250F00FF000E260F00FF000E270F00A9
+:10009000FF000E280F00FF000E290F00FF000E2AA0
+:1000A0000F00FF000E2B0F00FF000E2C0F00FF00B3
+:1000B0000E2D0F00FF000E2E0F00FF000E2F0F0061
+:1000C000FF000E300F00FF000E310F00FF000E3258
+:1000D0000F00FF000E330F00FF000E340F00FF0073
+:1000E0000E350F00FF000E360F00FF000E370F0019
+:1000F000FF000E380F00FF000E390F00FF000E3A10
+:100100000F00FF000E3B0F00FF000E3C0F00FF0032
+:100110000E3D0F00FF000E3E0F00FF000E3F0F00D0
+:10012000FF000E400F00FF000E410F00FF000E42C7
+:100130000F00FF000E430F00FF000E440F00FF00F2
+:100140000E450F00FF000E460F00FF000E470F0088
+:10015000FF000E480F00FF000E490F00FF000E4A7F
+:100160000F00FF000E4B0F00FF000E4C0F00FF00B2
+:100170000E4D0F00FF000E4E0F00FF000E4F0F0040
+:10018000FF000E500F00FF000E510F00FF000E5237
+:100190000F00FF000E530F00FF000E540F00FF0072
+:1001A0000E550F00FF000E560F00FF000E570F00F8
+:1001B000FF000E580F00FF000E590F00FF000E5AEF
+:1001C0000F00FF000E5B0F00FF000E5C0F00FF0032
+:1001D0000E5D0F00FF000E5E0F00FF000E5F0F00B0
+:1001E000FF000E600F00FF000E610F00FF000E62A7
+:1001F0000F00FF000E630F00FF000E640F00FF00F2
+:100200000E650F00FF000E660F00FF000E670F0067
+:10021000FF000E680F00FF000E690F00FF000E6A5E
+:100220000F00FF000E6B0F00FF000E6C0F00FF00B1
+:100230000E6D0F00FF000E6E0F00FF000E6F0F001F
+:10024000FF000E700F00FF000E710F00FF000E7216
+:100250000F00FF000E730F00FF000E740F00FF0071
+:100260000E750F00FF000E760F00FF000E770F00D7
+:10027000FF000E780F00FF000E790F00FF000E7ACE
+:100280000F00FF000E7B0F00FF000E7C0F00FF0031
+:100290000E7D0F00FF000E7E0F00FF000E7F0F008F
+:1002A000FF000E800F00FF000E810F00FF000E8286
+:1002B0000F00FF000E830F00FF000E840F00FF00F1
+:1002C0000E850F00FF000E860F00FF000E870F0047
+:1002D000FF000E880F00FF000E890F00FF000E8A3E
+:1002E0000F00FF000E8B0F00FF000E8C0F00FF00B1
+:1002F0000E8D0F00FF000E8E0F00FF000E8F0F00FF
+:10030000FF000E900F00FF000E910F00FF000E92F5
+:100310000F00FF000E930F00FF000E940F00FF0070
+:100320000E950F00FF000E960F00FF000E970F00B6
+:10033000FF000E980F00FF000E990F00FF000E9AAD
+:100340000F00FF000E9B0F00FF000E9C0F00FF0030
+:100350000E9D0F00FF000E9E0F00FF000E9F0F006E
+:10036000FF000EA00F00FF000EA10F00FF000EA265
+:100370000F00FF000EA30F00FF000EA40F00FF00F0
+:100380000EA50F00FF000EA60F00FF000EA70F0026
+:10039000FF000EA80F00FF000EA90F00FF000EAA1D
+:1003A0000F00FF000EAB0F00FF000EAC0F00FF00B0
+:1003B0000EAD0F00FF000EAE0F00FF000EAF0F00DE
+:1003C000FF000EB00F00FF000EB10F00FF000EB2D5
+:1003D0000F00FF000EB30F00FF000EB40F00FF0070
+:1003E0000EB50F00FF000EB60F00FF000EB70F0096
+:1003F000FF000EB80F00FF000EB90F00FF000EBA8D
+:100400000F00FF000EBB0F00FF000EBC0F00FF002F
+:100410000EBD0F00FF000EBE0F00FF000EBF0F004D
+:10042000FF000EC00F00FF000EC10F00FF000EC244
+:100430000F00FF000EC30F00FF000EC40F00FF00EF
+:100440000EC50F00FF000EC60F00FF000EC70F0005
+:10045000FF000EC80F00FF000EC90F00FF000ECAFC
+:100460000F00FF000ECB0F00FF000ECC0F00FF00AF
+:100470000ECD0F00FF000ECE0F00FF000ECF0F00BD
+:10048000FF000ED00F00FF000ED10F00FF000ED2B4
+:100490000F00FF000ED30F00FF000ED40F00FF006F
+:1004A0000ED50F00FF000ED60F00FF000ED70F0075
+:1004B000FF000ED80F00FF000ED90F00FF000EDA6C
+:1004C0000F00FF000EDB0F00FF000EDC0F00FF002F
+:1004D0000EDD0F00FF000EDE0F00FF000EDF0F002D
+:1004E000FF000EE00F00FF000EE10F00FF000EE224
+:1004F0000F00FF000EE30F00FF000EE40F00FF00EF
+:100500000EE50F00FF000EE60F00FF000EE70F00E4
+:10051000FF000EE80F00FF000EE90F00FF000EEADB
+:100520000F00FF000EEB0F00FF000EEC0F00FF00AE
+:100530000EED0F00FF000EEE0F00FF000EEF0F009C
+:10054000FF000EF00F00FF000EF10F00FF000EF293
+:100550000F00FF000EF30F00FF000EF40F00FF006E
+:100560000EF50F00FF000EF60F00FF000EF70F0054
+:10057000FF000EF80F00FF000EF90F00FF000EFA4B
+:100580000F00FF000EFB0F00FF000EFC0F00FF002E
+:100590000EFD0F00FF000EFE0F00FF000EFF0F000C
+:1005A000FF000E100F00FF000E110F00FF000E12D3
+:1005B0000F00FF000E130F00FF000E140F00FF00CE
+:1005C0000E150F00FF000E160F00FF000E170F0094
+:1005D000FF000E180F00FF000E190F00FF000E1A8B
+:1005E0000F00FF000E1B0F00FF000E1C0F00FF008E
+:1005F0000E1D0F00FF000E1E0F00FF000E1F0F004C
+:10060000FF000E200F00FF000E210F00FF000E2242
+:100610000F00FF000E230F00FF000E240F00FF004D
+:100620000E250F00FF000E260F00FF000E270F0003
+:10063000FF000E280F00FF000E290F00FF000E2AFA
+:100640000F00FF000E2B0F00FF000E2C0F00FF000D
+:100650000E2D0F00FF000E2E0F00FF000E2F0F00BB
+:10066000FF000E300F00FF000E310F00FF000E32B2
+:100670000F00FF000E330F00FF000E340F00FF00CD
+:100680000E350F00FF000E360F00FF000E370F0073
+:10069000FF000E380F00FF000E390F00FF000E3A6A
+:1006A0000F00FF000E3B0F00FF000E3C0F00FF008D
+:1006B0000E3D0F00FF000E3E0F00FF000E3F0F002B
+:1006C000FF000E400F00FF000E410F00FF000E4222
+:1006D0000F00FF000E430F00FF000E440F00FF004D
+:1006E0000E450F00FF000E460F00FF000E470F00E3
+:1006F000FF000E480F00FF000E490F00FF000E4ADA
+:100700000F00FF000E4B0F00FF000E4C0F00FF000C
+:100710000E4D0F00FF000E4E0F00FF000E4F0F009A
+:10072000FF000E500F00FF000E510F00FF000E5291
+:100730000F00FF000E530F00FF000E540F00FF00CC
+:100740000E550F00FF000E560F00FF000E570F0052
+:10075000FF000E580F00FF000E590F00FF000E5A49
+:100760000F00FF000E5B0F00FF000E5C0F00FF008C
+:100770000E5D0F00FF000E5E0F00FF000E5F0F000A
+:10078000FF000E600F00FF000E610F00FF000E6201
+:100790000F00FF000E630F00FF000E640F00FF004C
+:1007A0000E650F00FF000E660F00FF000E670F00C2
+:1007B000FF000E680F00FF000E690F00FF000E6AB9
+:1007C0000F00FF000E6B0F00FF000E6C0F00FF000C
+:1007D0000E6D0F00FF000E6E0F00FF000E6F0F007A
+:1007E000FF000E700F00FF000E710F00FF000E7271
+:1007F0000F00FF000E730F00FF000E740F00FF00CC
+:100800000E750F00FF000E760F00FF000E770F0031
+:10081000FF000E780F00FF000E790F00FF000E7A28
+:100820000F00FF000E7B0F00FF000E7C0F00FF008B
+:100830000E7D0F00FF000E7E0F00FF000E7F0F00E9
+:10084000FF000E800F00FF000E810F00FF000E82E0
+:100850000F00FF000E830F00FF000E840F00FF004B
+:100860000E850F00FF000E860F00FF000E870F00A1
+:10087000FF000E880F00FF000E890F00FF000E8A98
+:100880000F00FF000E8B0F00FF000E8C0F00FF000B
+:100890000E8D0F00FF000E8E0F00FF000E8F0F0059
+:1008A000FF000E900F00FF000E910F00FF000E9250
+:1008B0000F00FF000E930F00FF000E940F00FF00CB
+:1008C0000E950F00FF000E960F00FF000E970F0011
+:1008D000FF000E980F00FF000E990F00FF000E9A08
+:1008E0000F00FF000E9B0F00FF000E9C0F00FF008B
+:1008F0000E9D0F00FF000E9E0F00FF000E9F0F00C9
+:10090000FF000EA00F00FF000EA10F00FF000EA2BF
+:100910000F00FF000EA30F00FF000EA40F00FF004A
+:100920000EA50F00FF000EA60F00FF000EA70F0080
+:10093000FF000EA80F00FF000EA90F00FF000EAA77
+:100940000F00FF000EAB0F00FF000EAC0F00FF000A
+:100950000EAD0F00FF000EAE0F00FF000EAF0F0038
+:10096000FF000EB00F00FF000EB10F00FF000EB22F
+:100970000F00FF000EB30F00FF000EB40F00FF00CA
+:100980000EB50F00FF000EB60F00FF000EB70F00F0
+:10099000FF000EB80F00FF000EB90F00FF000EBAE7
+:1009A0000F00FF000EBB0F00FF000EBC0F00FF008A
+:1009B0000EBD0F00FF000EBE0F00FF000EBF0F00A8
+:1009C000FF000EC00F00FF000EC10F00FF000EC29F
+:1009D0000F00FF000EC30F00FF000EC40F00FF004A
+:1009E0000EC50F00FF000EC60F00FF000EC70F0060
+:1009F000FF000EC80F00FF000EC90F00FF000ECA57
+:100A00000F00FF000ECB0F00FF000ECC0F00FF0009
+:100A10000ECD0F00FF000ECE0F00FF000ECF0F0017
+:100A2000FF000ED00F00FF000ED10F00FF000ED20E
+:100A30000F00FF000ED30F00FF000ED40F00FF00C9
+:100A40000ED50F00FF000ED60F00FF000ED70F00CF
+:100A5000FF000ED80F00FF000ED90F00FF000EDAC6
+:100A60000F00FF000EDB0F00FF000EDC0F00FF0089
+:100A70000EDD0F00FF000EDE0F00FF000EDF0F0087
+:100A8000FF000EE00F00FF000EE10F00FF000EE27E
+:100A90000F00FF000EE30F00FF000EE40F00FF0049
+:100AA0000EE50F00FF000EE60F00FF000EE70F003F
+:100AB000FF000EE80F00FF000EE90F00FF000EEA36
+:100AC0000F00FF000EEB0F00FF000EEC0F00FF0009
+:100AD0000EED0F00FF000EEE0F00FF000EEF0F00F7
+:100AE000FF000EF00F00FF000EF10F00FF000EF2EE
+:100AF0000F00FF000EF30F00FF000EF40F00FF00C9
+:100B00000EF50F00FF000EF60F00FF000EF70F00AE
+:100B1000FF000EF80F00FF000EF90F00FF000EFAA5
+:100B20000F00FF000EFB0F00FF000EFC0F00FF0088
+:100B30000EFD0F00FF000EFE0F00FF000EFF0F0066
+:100B4000FF000802FF000B070A440D000C00FF0025
+:100B50000B070A420D000C00FF000B070A430D00B3
+:100B60000C00FF000B070A7C0D000C00FF000B07B8
+:100B70000A7E0D000C00FF000B070A460D000C005A
+:100B8000FF000B070A490D000C00FF000B070A4786
+:100B90000D000C00FF000B070A4A0D000C00FF00BF
+:100BA0000E100F00FF000E110F00FF000E120F00BD
+:100BB000FF000E130F00FF000E140F00FF000E15B4
+:100BC0000F00FF000E160F00FF000E170F00FF00B2
+:100BD0000E180F00FF000E190F00FF000E1A0F0075
+:100BE000FF000E1B0F00FF000E1C0F00FF000E1D6C
+:100BF0000F00FF000E1E0F00FF000E1F0F00FF0072
+:100C00000E200F00FF000E210F00FF000E220F002C
+:100C1000FF000E230F00FF000E240F00FF000E2523
+:100C20000F00FF000E260F00FF000E270F00FF0031
+:100C30000E280F00FF000E290F00FF000E2A0F00E4
+:100C4000FF000E2B0F00FF000E2C0F00FF000E2DDB
+:100C50000F00FF000E2E0F00FF000E2F0F00FF00F1
+:100C60000E300F00FF000E310F00FF000E320F009C
+:100C7000FF000E330F00FF000E340F00FF000E3593
+:100C80000F00FF000E360F00FF000E370F00FF00B1
+:100C90000E380F00FF000E390F00FF000E3A0F0054
+:100CA000FF000E3B0F00FF000E3C0F00FF000E3D4B
+:100CB0000F00FF000E3E0F00FF000E3F0F00FF0071
+:100CC0000E400F00FF000E410F00FF000E420F000C
+:100CD000FF000E430F00FF000E440F00FF000E4503
+:100CE0000F00FF000E460F00FF000E470F00FF0031
+:100CF0000E480F00FF000E490F00FF000E4A0F00C4
+:100D0000FF000E4B0F00FF000E4C0F00FF000E4DBA
+:100D10000F00FF000E4E0F00FF000E4F0F00FF00F0
+:100D20000E500F00FF000E510F00FF000E520F007B
+:100D3000FF000E530F00FF000E540F00FF000E5572
+:100D40000F00FF000E560F00FF000E570F00FF00B0
+:100D50000E580F00FF000E590F00FF000E5A0F0033
+:100D6000FF000E5B0F00FF000E5C0F00FF000E5D2A
+:100D70000F00FF000E5E0F00FF000E5F0F00FF0070
+:100D80000E600F00FF000E610F00FF000E620F00EB
+:100D9000FF000E630F00FF000E640F00FF000E65E2
+:100DA0000F00FF000E660F00FF000E670F00FF0030
+:100DB0000E680F00FF000E690F00FF000E6A0F00A3
+:100DC000FF000E6B0F00FF000E6C0F00FF000E6D9A
+:100DD0000F00FF000E6E0F00FF000E6F0F00FF00F0
+:100DE0000E700F00FF000E710F00FF000E720F005B
+:100DF000FF000E730F00FF000E740F00FF000E7552
+:100E00000F00FF000E760F00FF000E770F00FF00AF
+:100E10000E780F00FF000E790F00FF000E7A0F0012
+:100E2000FF000E7B0F00FF000E7C0F00FF000E7D09
+:100E30000F00FF000E7E0F00FF000E7F0F00FF006F
+:100E40000E800F00FF000E810F00FF000E820F00CA
+:100E5000FF000E830F00FF000E840F00FF000E85C1
+:100E60000F00FF000E860F00FF000E870F00FF002F
+:100E70000E880F00FF000E890F00FF000E8A0F0082
+:100E8000FF000E8B0F00FF000E8C0F00FF000E8D79
+:100E90000F00FF000E8E0F00FF000E8F0F00FF00EF
+:100EA0000E900F00FF000E910F00FF000E920F003A
+:100EB000FF000E930F00FF000E940F00FF000E9531
+:100EC0000F00FF000E960F00FF000E970F00FF00AF
+:100ED0000E980F00FF000E990F00FF000E9A0F00F2
+:100EE000FF000E9B0F00FF000E9C0F00FF000E9DE9
+:100EF0000F00FF000E9E0F00FF000E9F0F00FF006F
+:100F00000EA00F00FF000EA10F00FF000EA20F00A9
+:100F1000FF000EA30F00FF000EA40F00FF000EA5A0
+:100F20000F00FF000EA60F00FF000EA70F00FF002E
+:100F30000EA80F00FF000EA90F00FF000EAA0F0061
+:100F4000FF000EAB0F00FF000EAC0F00FF000EAD58
+:100F50000F00FF000EAE0F00FF000EAF0F00FF00EE
+:100F60000EB00F00FF000EB10F00FF000EB20F0019
+:100F7000FF000EB30F00FF000EB40F00FF000EB510
+:100F80000F00FF000EB60F00FF000EB70F00FF00AE
+:100F90000EB80F00FF000EB90F00FF000EBA0F00D1
+:100FA000FF000EBB0F00FF000EBC0F00FF000EBDC8
+:100FB0000F00FF000EBE0F00FF000EBF0F00FF006E
+:100FC0000EC00F00FF000EC10F00FF000EC20F0089
+:100FD000FF000EC30F00FF000EC40F00FF000EC580
+:100FE0000F00FF000EC60F00FF000EC70F00FF002E
+:100FF0000EC80F00FF000EC90F00FF000ECA0F0041
+:10100000FF000ECB0F00FF000ECC0F00FF000ECD37
+:101010000F00FF000ECE0F00FF000ECF0F00FF00ED
+:101020000ED00F00FF000ED10F00FF000ED20F00F8
+:10103000FF000ED30F00FF000ED40F00FF000ED5EF
+:101040000F00FF000ED60F00FF000ED70F00FF00AD
+:101050000ED80F00FF000ED90F00FF000EDA0F00B0
+:10106000FF000EDB0F00FF000EDC0F00FF000EDDA7
+:101070000F00FF000EDE0F00FF000EDF0F00FF006D
+:101080000EE00F00FF000EE10F00FF000EE20F0068
+:10109000FF000EE30F00FF000EE40F00FF000EE55F
+:1010A0000F00FF000EE60F00FF000EE70F00FF002D
+:1010B0000EE80F00FF000EE90F00FF000EEA0F0020
+:1010C000FF000EEB0F00FF000EEC0F00FF000EED17
+:1010D0000F00FF000EEE0F00FF000EEF0F00FF00ED
+:1010E0000EF00F00FF000EF10F00FF000EF20F00D8
+:1010F000FF000EF30F00FF000EF40F00FF000EF5CF
+:101100000F00FF000EF60F00FF000EF70F00FF00AC
+:101110000EF80F00FF000EF90F00FF000EFA0F008F
+:10112000FF000EFB0F00FF000EFC0F00FF000EFD86
+:101130000F00FF000EFE0F00FF000EFF0F0009055D
+:101140000B000A000D010C7CFF000D000C1EFF00BF
+:101150000D000C00FF000D000C00FF000D000CF551
+:10116000FF000D000C11FF000D000C20FF000D0012
+:101170000C32FF000D000C40FF000D000C13FF00AF
+:101180000D000C00FF000D000C14FF000D020C768A
+:10119000FF000D000C60FF000D000C80FF000D0231
+:1011A0000C00FF000D000C00FF000D000C00FF0004
+:1011B0000D020C00FF000D000C00FF000D000C00E4
+:1011C000FF000D000C00FF000D000C00FF000D00E3
+:1011D0000C00FF000D000C00FF000D000C00FF00D4
+:1011E0000D000C00FF000D000C00FF000D000C00B6
+:1011F000FF000D000C00FF000D000C00FF000D00B3
+:101200000C00FF000D000C00FF000D000C00FF00A3
+:101210000D000C00FF000D000C00FF000D000C0085
+:10122000FF000D000C00FF000D000C00FF000D0082
+:101230000C00FF000D000C00FF000D000C00FF0073
+:101240000D000C00FF000D000C00FF000D000C0055
+:10125000FF000D000C00FF000D000C00FF000D0052
+:101260000C00FF000D000C00FF000D000C00FF0043
+:101270000D000C00FF000D000C00FF000D000C0025
+:10128000FF000D000C00FF000D000C00FF000D0022
+:101290000C00FF000D000C00FF000D000C00FF0013
+:1012A0000D000C00FF000D000C00FF000D000C00F5
+:1012B000FF000D000C00FF000D000C00FF000D00F2
+:1012C0000C00FF000D000C18FF000D000C19FF00B2
+:1012D0000D010C1AFF000D010C20FF000D010C4048
+:1012E000FF000D010C17FF000D000C00FF000D01A9
+:1012F0000C80FF000D010C20FF000D000C10FF0002
+:101300000D010CA0FF000D030CD1FF000D000C001F
+:10131000FF000D010CF2FF000D020C00FF000D009C
+:101320000C13FF000D000C00FF000D000CF4FF007B
+:101330000D020CE0FF000D000C15FF000D000C006D
+:10134000FF000D000C16FF000D000C00FF000D004B
+:101350000C17FF000D000C20FF000D000C00FF001B
+:101360000D000C20FF000D000C50FF000D000C00C4
+:10137000FF000D000C40FF000D000C00FF000D00F1
+:101380000C71FF000D020C00FF000D000C60FF004F
+:101390000D000C00FF000D000C92FF000D000C0072
+:1013A000FF000D000C80FF000D000C00FF000D0081
+:1013B0000CB3FF000D020C00FF000D000CA0FF009D
+:1013C0000D000C00FF000D000CD4FF000D000C0000
+:1013D000FF000D000C40FF000D000C80FF000D0011
+:1013E0000CF5FF000D000C20FF000D000C70FF003D
+:1013F0000D000CA0FF000D020C11FF000D000C16DB
+:10140000FF000D000C00FF000D000C00FF000D00A0
+:101410000C00FF000D000C20FF000D020C00FF006F
+:101420000D000C20FF000D000C10FF000D000C172C
+:10143000FF000D000C1BFF000D000C1DFF000D0236
+:101440000CDFFF0009050B010A000D000C00FF0076
+:101450000D000C00FF000D000C00FF000D020C0041
+:10146000FF000D000C19FF000D000C1FFF000D0008
+:101470000C00FF000D000C00FF000D000C00FF0031
+:101480000D030CD8FF000D000C00FF000D020C2016
+:10149000FF000D000C19FF000D000C00FF000D00F7
+:1014A0000C00FF000D000C18FF000D010CC0FF0028
+:1014B0000D010CFAFF000D000C1AFF000D000C00CE
+:1014C000FF000D000C00FF000D000C00FF000D00E0
+:1014D0000C00FF000D000C00FF000D000C00FF00D1
+:1014E0000D000C00FF000D000C00FF000D000C00B3
+:1014F000FF000D000C00FF000D000C00FF000D00B0
+:101500000C00FF000D000C00FF000D000C00FF00A0
+:101510000D000C00FF000D000C00FF000D000C0082
+:10152000FF000D000C00FF000D000C00FF000D007F
+:101530000C00FF000D000C00FF000D000C00FF0070
+:101540000D000C00FF000D000C00FF000D000C0052
+:10155000FF000D000C00FF000D000C00FF000D004F
+:101560000C00FF000D000C00FF000D000C00FF0040
+:101570000D000C00FF000D000C00FF000D000C0022
+:10158000FF000D000C00FF000D000C00FF000D001F
+:101590000C00FF000D000C00FF000D000C00FF0010
+:1015A0000D000C00FF000D000C00FF000D000C00F2
+:1015B000FF000D000C00FF000D000C00FF000D00EF
+:1015C0000C00FF000D000C00FF000D020C40FF009E
+:1015D0000D020C60FF000D000C00FF000D000C0060
+:1015E000FF000D000C00FF000D020CC0FF000D02FB
+:1015F0000C80FF000D000C00FF000D020CFBFF0033
+:101600000D020CA0FF000D000C00FF000D000C1BD4
+:10161000FF000D020CD7FF000D000C00FF000D02B3
+:101620000CF7FF000D030C20FF000D030C00FF0062
+:101630000D000C00FF000D000C1CFF000D030C3C06
+:10164000FF000D000C00FF000D030C3FFF000D001C
+:101650000C00FF000D030CC0FF000D000C00FF008C
+:101660000D030CDFFF000D000C00FF000D000C004F
+:10167000FF000D030C5DFF000D000C00FF000D03CB
+:101680000CC0FF000D000C00FF000D030C7DFF00DF
+:101690000D000C00FF000D030CC0FF000D000C003E
+:1016A000FF000D030C9EFF000D000C00FF000D035A
+:1016B0000CC0FF000D000C00FF000D030CBEFF006E
+:1016C0000D000C00FF000D030CC0FF000D000C000E
+:1016D000FF000D000C00FF000D000C00FF000D00CE
+:1016E0000C00FF000D000C1BFF000D000C00FF00A4
+:1016F0000D000C00FF000D000C00FF000D020CDBC4
+:10170000FF000D000C00FF000D020CDBFF000D00C0
+:101710000C00FF000D020CE0FF000D000C00FF00AC
+:101720000D020CFBFF000D000C00FF000D020CC0B1
+:10173000FF000D020C40FF000D020CFBFF000D022C
+:101740000C60FF000D000C1BFF0009050B020A00D6
+:101750000CC4FF000C00FF000C44FF000C07FF004E
+:101760000C44FF000C00FF000C40FF000C25FF00A4
+:101770000C01FF000C06FF000CC4FF000C07FF006B
+:101780000C40FF000C25FF000C01FF000C00FF00C7
+:101790000C46FF000C46FF000C00FF000C00FF0091
+:1017A0000C00FF000C00FF000C00FF000C00FF000D
+:1017B0000C00FF000C00FF000C00FF000C00FF00FD
+:1017C0000C00FF000C00FF000C00FF000C00FF00ED
+:1017D0000C00FF000C00FF000C00FF000C00FF00DD
+:1017E0000C00FF000C00FF000C00FF000C00FF00CD
+:1017F0000C00FF000C00FF000C00FF000C00FF00BD
+:101800000C00FF000C00FF000C00FF000C00FF00AC
+:101810000C00FF000C00FF000C00FF000C00FF009C
+:101820000C00FF000C00FF000C00FF000C00FF008C
+:101830000C00FF000C00FF000C00FF000C00FF007C
+:101840000C00FF000C00FF000C00FF000C00FF006C
+:101850000C46FF000C07FF000C05FF000C05FF0005
+:101860000C05FF000C04FF000C07FF000C05FF0037
+:101870000C04FF000C07FF000C05FF000C44FF00E8
+:101880000C46FF000C44FF000C46FF000C46FF0016
+:101890000C07FF000C05FF000C44FF000C46FF0086
+:1018A0000C05FF000C46FF000C05FF000C46FF0076
+:1018B0000C05FF000C46FF000C05FF000C44FF0068
+:1018C0000C46FF000C05FF000C07FF000C44FF0056
+:1018D0000C46FF000C05FF000C07FF000C44FF0046
+:1018E0000C46FF000C05FF000C07FF000C44FF0036
+:1018F0000C46FF000C05FF000C07FF000C44FF0026
+:101900000C05FF000C05FF000C05FF000C44FF0058
+:101910000C05FF000C05FF000C05FF000C46FF0046
+:101920000C05FF000C46FF000C05FF000C46FF00F5
+:101930000C05FF000C46FF000C05FF000C46FF00E5
+:101940000C07FF000C46FF000C07FF000C44FF00D3
+:1019500009050B030A000C07FF000C40FF000C00F8
+:10196000FF000C00FF000C00FF000C47FF000C0004
+:10197000FF000C40FF000C00FF000C40FF000C06B5
+:10198000FF000C40FF000C00FF000C00FF000C00EB
+:10199000FF000C00FF000C00FF000C00FF000C001B
+:1019A000FF000C00FF000C00FF000C00FF000C000B
+:1019B000FF000C00FF000C00FF000C00FF000C00FB
+:1019C000FF000C00FF000C00FF000C00FF000C00EB
+:1019D000FF000C00FF000C00FF000C00FF000C00DB
+:1019E000FF000C00FF000C00FF000C00FF000C00CB
+:1019F000FF000C00FF000C00FF000C00FF000C00BB
+:101A0000FF000C00FF000C00FF000C00FF000C00AA
+:101A1000FF000C00FF000C00FF000C00FF000C009A
+:101A2000FF000C00FF000C00FF000C00FF000C008A
+:101A3000FF000C00FF000C00FF000C00FF000C007A
+:101A4000FF000C00FF000C00FF000C00FF000C006A
+:101A5000FF000C00FF000C80FF000C80FF000CC09A
+:101A6000FF000C00FF000C00FF000C40FF000C000A
+:101A7000FF000C00FF000C00FF000C40FF000C00FA
+:101A8000FF000C40FF000C00FF000C60FF000C008A
+:101A9000FF000C70FF000C00FF000C40FF000C006A
+:101AA000FF000C40FF000C00FF000C42FF000C0088
+:101AB000FF000C40FF000C00FF000C02FF000C00B8
+:101AC000FF000C40FF000C00FF000C00FF000C00AA
+:101AD000FF000C40FF000C00FF000C00FF000C009A
+:101AE000FF000C40FF000C00FF000C00FF000C008A
+:101AF000FF000C40FF000C00FF000C00FF000C007A
+:101B0000FF000C40FF000C00FF000C00FF000C0069
+:101B1000FF000C42FF000C00FF000C40FF000C0017
+:101B2000FF000C42FF000C00FF000C02FF000C0045
+:101B3000FF000C02FF000C00FF000C02FF000C0075
+:101B4000FF000C42FF000C00FF000CC0FF000C0067
+:101B5000FF000C40FF0009050B040A000C63FF00A6
+:101B60000C03FF000C26FF000C02FF000C2CFF00F2
+:101B70000C00FF000C24FF000C00FF000C2EFF00E7
+:101B80000C02FF000C02FF000C02FF000C00FF0023
+:101B90000C00FF000C00FF000C00FF000C00FF0019
+:101BA0000C00FF000C00FF000C00FF000C00FF0009
+:101BB0000C00FF000C00FF000C00FF000C00FF00F9
+:101BC0000C00FF000C00FF000C00FF000C00FF00E9
+:101BD0000C00FF000C00FF000C00FF000C00FF00D9
+:101BE0000C00FF000C00FF000C00FF000C00FF00C9
+:101BF0000C00FF000C00FF000C00FF000C00FF00B9
+:101C00000C00FF000C00FF000C00FF000C00FF00A8
+:101C10000C00FF000C00FF000C00FF000C00FF0098
+:101C20000C00FF000C00FF000C00FF000C00FF0088
+:101C30000C00FF000C00FF000C00FF000C00FF0078
+:101C40000C00FF000C00FF000C00FF000C00FF0068
+:101C50000C00FF000C00FF000C00FF000C00FF0058
+:101C60000C01FF000C20FF000C00FF000C60FF00C7
+:101C70000C00FF000C20FF000C00FF000C20FF00F8
+:101C80000C00FF000C20FF000C00FF000C20FF00E8
+:101C90000C00FF000C20FF000C00FF000C20FF00D8
+:101CA0000C00FF000C20FF000C00FF000C20FF00C8
+:101CB0000C00FF000C60FF000C00FF000C20FF0078
+:101CC0000C00FF000C60FF000C00FF000C20FF0068
+:101CD0000C00FF000C60FF000C00FF000C20FF0058
+:101CE0000C00FF000C60FF000C00FF000C20FF0048
+:101CF0000C00FF000C60FF000C00FF000C20FF0038
+:101D00000C00FF000C60FF000C00FF000C20FF0027
+:101D10000C00FF000C20FF000C00FF000C22FF0055
+:101D20000C02FF000C22FF000C02FF000C20FF0041
+:101D30000C00FF000C60FF000C00FF000C22FF00F5
+:101D40000C02FF000C62FF000C02FF000C20FF00E1
+:101D50000C01FF000C21FF000C01FF0009010B0624
+:101D60000A000D000C00FF000A020D000C00FF002D
+:101D70000A040D000C00FF000A060D000C00FF0015
+:101D80000A080D000C00FF000A0A0D000C00FF00FD
+:101D90000A0C0D000C00FF000A0E0D000C00FF00E5
+:101DA0000A100D000C00FF000A120D000C00FF00CD
+:101DB0000A140D000C00FF000A160D000C00FF00B5
+:101DC0000A180D000C00FF000A1A0D000C00FF009D
+:101DD0000A1C0D000C00FF000A1E0D000C00FF0085
+:101DE0000A200D000C00FF000A220D000C00FF006D
+:101DF0000A240D000C00FF000A260D000C00FF0055
+:101E00000A280D000C00FF000A2A0D000C00FF003C
+:101E10000A2C0D000C00FF000A2E0D000C00FF0024
+:101E20000A300D000C00FF000A320D000C00FF000C
+:101E30000A340D000C00FF000A360D000C00FF00F4
+:101E40000A380D000C00FF000A3A0D000C00FF00DC
+:101E50000A3C0D000C00FF000A3E0D000C00FF00C4
+:101E60000A400D000C00FF000A420D030C00FF00A9
+:101E70000A440D010C00FF000A460D0A0C21FF0068
+:101E80000A480D0D0C23FF000A4A0D230C1BFF000E
+:101E90000A4C0D370C8FFF000A4E0D450C77FF00E2
+:101EA0000A500D520CE2FF000A520D1C0C92FF006A
+:101EB0000A540D1C0C52FF000A560D070C00FF00BF
+:101EC0000A580D2F0CC6FF000A5A0D0B0C00FF001C
+:101ED0000A5C0D300C06FF000A5E0D170C00FF00B7
+:101EE0000A600D3D0CDAFF000A620D290C00FF00AC
+:101EF0000A640D3E0C41FF000A660D390C00FF001C
+:101F00000A680D4C0C48FF000A6A0D490C00FF00DE
+:101F10000A6C0D4C0C6CFF000A6E0D110CD2FF0008
+:101F20000A700D160C0CFF000A720D000C00FF0069
+:101F30000A740D000C80FF000A760D0F0C00FF00E4
+:101F40000A780D000C80FF000A7A0D130C00FF00C8
+:101F50000A7C0D800C00FF000A7E0D800C80FF00C3
+:101F600009050B070A000D0F0CFFFF000D000C0008
+:101F7000FF000D080C00FF000D080C00FF000D0213
+:101F80000C00FF000D000C00FF000D000C00FF0016
+:101F90000D0F0CFFFF000D000C00FF000D000C00EA
+:101FA000FF000D080C00FF000D080C00FF000D00E5
+:101FB0000C00FF000D0F0CFFFF000D000C00FF00D8
+:101FC0000D000C00FF000D0F0CFFFF000D0F0CFFAC
+:101FD000FF000D000C00FF000D000C00FF000D00C5
+:101FE0000C00FF000D000C00FF000D000C00FF00B6
+:101FF0000D000C00FF000D000C00FF000D000C0098
+:10200000FF000D000C00FF000D000C00FF000D0094
+:102010000C00FF000D000C00FF000D000C00FF0085
+:102020000D000C00FF000D000C00FF000D000C0067
+:10203000FF000D000C00FF000D000C00FF000D0064
+:102040000C00FF000D000C00FF000D000C00FF0055
+:102050000D000C00FF000D000C00FF000D000C0037
+:10206000FF000D000C00FF000D000C00FF000D0034
+:102070000C00FF000D000C00FF000D000C00FF0025
+:102080000D000C00FF000D000C00FF000D000C0007
+:10209000FF000D000C00FF000D000C00FF000D0004
+:1020A0000C00FF000D000C00FF000D000C00FF00F5
+:1020B0000D000C00FF000D000C00FF000D000C00D7
+:1020C000FF000D000C00FF000D000C00FF000D00D4
+:1020D0000C00FF000D000C00FF000D000C00FF00C5
+:1020E0000D000C00FF000D000C00FF000D000C00A7
+:1020F000FF000D000C00FF000D000C00FF000D00A4
+:102100000C00FF000D000C00FF000D000C00FF0094
+:102110000D000C00FF000D000C00FF000D000C0076
+:10212000FF000D000C00FF000D0F0CFFFF000D0F56
+:102130000CFFFF000D0F0CFFFF000D0F0CFFFF0049
+:102140000D020CE9FF000D060C8CFF000D060C8C37
+:10215000FF000D0F0CFFFF000D1A0C75FF000D0D99
+:102160000C8BFF000D040CE9FF000D0B0C16FF009B
+:102170000D1A0C38FF000D0D0CC8FF000D040C6F7C
+:10218000FF000D0B0C91FF000D0F0CFFFF000D0663
+:102190000C40FF000D060C40FF000D020C8FFF00ED
+:1021A0000D0F0CFFFF000D060C62FF000D060C6208
+:1021B000FF000D020C7BFF000D0F0CFFFF000D0652
+:1021C0000C97FF000D060C97FF000D020C52FF004C
+:1021D0000D0F0CFFFF000D060CF6FF000D060CF6B0
+:1021E000FF000D020C19FF000D050C55FF000D0539
+:1021F0000C55FF000D050C55FF000D050C55FF009B
+:102200000D050C55FF000D050C55FF000D050C5577
+:10221000FF000D050C55FF000D140CDAFF000D0D2D
+:102220000C93FF000D040CDAFF000D050C93FF006A
+:102230000D140CDAFF000D0D0C93FF000D040CDAE9
+:10224000FF000D050C93FF000D000C00FF000D00BA
+:102250000C00FF000D000C00FF000D000C00FF0043
+:102260000D020C00FF000E010F00FF000E020F0018
+:10227000FF000E010F01FF000E020F00FF000E0114
+:102280000F02FF000E020F00FF000E010F03FF0000
+:102290000E020F00FF000E010F04FF000E020F00E0
+:1022A000FF000E010F05FF000E020F00FF000E01E0
+:1022B0000F06FF000E020F00FF000E010F07FF00C8
+:1022C0000E020F00FF000E010F08FF000E020F00AC
+:1022D000FF000E010F09FF000E020F00FF000E01AC
+:1022E0000F0AFF000E020F00FF000E010F0BFF0090
+:1022F0000E020F00FF000E010F0CFF000E020F0078
+:10230000FF000E010F0DFF000E020F00FF000E0177
+:102310000F0EFF000E020F00FF000E010F0FFF0057
+:102320000E020F00FF000EB00F20FF000EB10F20B5
+:10233000FF000EB20F20FF000EB30F20FF000EB4FF
+:102340000F20FF000EB50F20FF000EB60F20FF007C
+:102350000EB70F20FF000EB80F20FF000EB90F20A0
+:10236000FF000EBA0F20FF000EBB0F20FF000EBCB7
+:102370000F20FF000EBD0F20FF000EBE0F20FF003C
+:102380000EBF0F20FF000EF00F20FF000EF10F20F8
+:10239000FF000EF20F20FF000EF30F20FF000EF4DF
+:1023A0000F20FF000EF50F20FF000EF60F20FF009C
+:1023B0000EF70F20FF000EF80F20FF000EF90F2080
+:1023C000FF000EFA0F20FF000EFB0F20FF000EFC97
+:1023D0000F20FF000EFD0F20FF000EFE0F20FF005C
+:1023E0000EFF0F20FF000E100FFFFF000E110FFF5A
+:1023F000FF000E120FFFFF000E130FFFFF000E1461
+:102400000FFFFF000E150FFFFF000E160FFFFF005E
+:102410000E170FFFFF000E180FFFFF000E190FFF22
+:10242000FF000E1A0FFFFF000E1B0FFFFF000E1C18
+:102430000FFFFF000E1D0FFFFF000E1E0F40FF00DD
+:102440000E1F0FFFFF000E200FFFFF000E210FFFDA
+:10245000FF000E220FFFFF000E230FFFFF000E24D0
+:102460000FFFFF000E250FFFFF000E260FFFFF00DE
+:102470000E270FFFFF000E280FFFFF000E290FFF92
+:10248000FF000E2A0FFFFF000E2B0FFFFF000E2C88
+:102490000FFFFF000E2D0FFFFF000E2E0F00FF009D
+:1024A0000E2F0F00FF000E300F00FF000E310F0047
+:1024B000FF000E320F00FF000E330F00FF000E343E
+:1024C0000F00FF000E350F00FF000E360F00FF005B
+:1024D0000E370F00FF000E380F00FF000E390F00FF
+:1024E000FF000E3A0F00FF000E3B0F00FF000E3CF6
+:1024F0000F00FF000E3D0F00FF000E3E0F00FF001B
+:102500000E3F0F20FF000E400F00FF000E410F0096
+:10251000FF000E420F00FF000E430F00FF000E44AD
+:102520000F00FF000E450F00FF000E460F00FF00DA
+:102530000E470F00FF000E480F00FF000E490F006E
+:10254000FF000E4A0F00FF000E4B0F00FF000E4C65
+:102550000F00FF000E4D0F00FF000E4E0F0EFF008C
+:102560000E4F0F0EFF000E500F00FF000E510F0018
+:10257000FF000E520F00FF000E530F00FF000E541D
+:102580000F00FF000E550F00FF000E560F00FF005A
+:102590000E570F00FF000E580F00FF000E590F00DE
+:1025A000FF000E5A0F00FF000E5B0F00FF000E5CD5
+:1025B0000F00FF000E5D0F00FF000E5E0F00FF001A
+:1025C0000E5F0F00FF000E600F00FF000E610F0096
+:1025D000FF000E620F00FF000E630F00FF000E648D
+:1025E0000F00FF000E650F00FF000E660F00FF00DA
+:1025F0000E670F00FF000E680F00FF000E690F004E
+:10260000FF000E6A0F00FF000E6B0F00FF000E6C44
+:102610000F40FF000E6D0F00FF000E6E0F40FF0019
+:102620000E6F0F40FF000E700FC0FF000E710FC045
+:10263000FF000E720FC0FF000E730FC0FF000E747C
+:102640000FC0FF000E750FC0FF000E760FC0FF0019
+:102650000E770FC0FF000E780FC0FF000E790FC07D
+:10266000FF000E7A0FC0FF000E7B0FC0FF000E7C34
+:102670000FC0FF000E7D0FC0FF000E7E0FC0FF00D9
+:102680000E7F0FC0FF000E800F00FF000E810F00B5
+:10269000FF000E820F00FF000E830F00FF000E846C
+:1026A0000F00FF000E850F00FF000E860F00FF00D9
+:1026B0000E870F00FF000E880F00FF000E890F002D
+:1026C000FF000E8A0F00FF000E8B0F00FF000E8C24
+:1026D0000F00FF000E8D0F00FF000E8E0F00FF0099
+:1026E0000E8F0F00FF000E900F00FF000E910F00E5
+:1026F000FF000E920F00FF000E930F00FF000E94DC
+:102700000F00FF000E950F00FF000E960F00FF0058
+:102710000E970F00FF000E980F00FF000E990F009C
+:10272000FF000E9A0F00FF000E9B0F00FF000E9C93
+:102730000F00FF000E9D0F00FF000E9E0F00FF0018
+:102740000E9F0F00FF000EA00F00FF000EA10F0054
+:10275000FF000EA20F00FF000EA30F00FF000EA44B
+:102760000F00FF000EA50F00FF000EA60F00FF00D8
+:102770000EA70F00FF000EA80F00FF000EA90F000C
+:10278000FF000EAA0F00FF000EAB0F00FF000EAC03
+:102790000F00FF000EAD0F00FF000EAE0F00FF0098
+:1027A0000EAF0F00FF000EC00F00FF000EC10F00A4
+:1027B000FF000EC20F00FF000EC30F00FF000EC48B
+:1027C0000F00FF000EC50F00FF000EC60F00FF0038
+:1027D0000EC70F00FF000EC80F00FF000EC90F004C
+:1027E000FF000ECA0F00FF000ECB0F00FF000ECC43
+:1027F0000F00FF000ECD0F00FF000ECE0F00FF00F8
+:102800000ECF0F00FF000ED00F00FF000ED10F0003
+:10281000FF000ED20F00FF000ED30F00FF000ED4FA
+:102820000F00FF000ED50F00FF000ED60F00FF00B7
+:102830000ED70F00FF000ED80F00FF000ED90F00BB
+:10284000FF000EDA0F00FF000EDB0F00FF000EDCB2
+:102850000F00FF000EDD0F00FF000EDE0F10FF0067
+:102860000EDF0F10FF000EE00F00FF000EE10F0063
+:10287000FF000EE20F00FF000EE30F00FF000EE46A
+:102880000F00FF000EE50F00FF000EE60F00FF0037
+:102890000EE70F00FF000EE80F00FF000EE90F002B
+:1028A000FF000EEA0F00FF000EEB0F00FF000EEC22
+:1028B0000F00FF000EED0F00FF000EEE0F00FF00F7
+:1028C0000EEF0F00FF000E010F000E020F01FF00C0
+:1028D0000E010F010E020F01FF000E010F020E028A
+:1028E0000F01FF000E010F030E020F01FF000E018A
+:1028F0000F040E020F01FF000E010F050E020F0163
+:10290000FF000E010F060E020F01FF000E010F0760
+:102910000E020F01FF000E010F080E020F01FF0053
+:102920000E010F090E020F01FF000E010F0A0E0229
+:102930000F01FF000E010F0B0E020F01FF000E0131
+:102940000F0C0E020F01FF000E010F0D0E020F0102
+:10295000FF000E010F0E0E020F01FF000E010F0F00
+:102960000E020F01FF0008020B070A460D000C00C3
+:10297000FF000B070A490D000C00FF000B000A4B7B
+:102980000D030C11FF000B000A4D0D010C32FF006E
+:102990000B070A460D000C00FF000B070A490D004B
+:1029A0000C00FF000B070A400D000C00FF000B0796
+:1029B0000A410D000C00FF000B010A400D020C4003
+:1029C000FF000B010A410D020C60FF000B070A40DB
+:1029D0000D000C00FF000B070A410D000C00FF006A
+:1029E0000B070A470D000C00FF000B070A4A0D00F9
+:1029F0000C00FF000B000A470D010C00FF000B004C
+:102A00000A4A0D010C20FF000B070A470D000C00BD
+:102A1000FF000B070A4A0D000C00FF000B070A7CA1
+:102A20000D000C00FF000B070A7E0D000C00FF00DC
+:102A30000B000A000D010C1CFF000B070A7C0D00A7
+:102A40000C00FF000B070A7E0D000C00FF000B07B7
+:102A50000A440D000C00FF000B000A440D010C009D
+:102A6000FF000B070A440D000C00FF000B070A4291
+:102A70000D000C00FF000B070A430D000C00FF00C7
+:102A80000B000A420D010C1AFF000B000A430D0156
+:102A90000C20FF000B070A420D000C00FF000B0783
+:102AA0000A430D000C00FF000B070A400D000C004C
+:102AB000FF000B070A410D000C00FF000B010A404C
+:102AC0000D020C40FF000B010A410D020C60FF00DB
+:102AD0000B070A400D000C00FF000B070A410D0018
+:102AE0000C00FF000B070A440D0F0CFFFF000B0743
+:102AF0000A420D000C00FF000B070A430D000C00FA
+:102B0000FF000B070A400D000C00FF000B070A41F5
+:102B10000D000C00FF000B070A510D060C40FF00D2
+:102B20000B070A500D060C40FF000B070A4F0D0360
+:102B30000C81FF000B070A530D1A0C76FF000B07E0
+:102B40000A540D0D0C8BFF000B070A550D040CE900
+:102B5000FF000B070A560D0B0C17FF000B070A5757
+:102B60000D1A0C38FF000B070A580D0D0CC9FF0099
+:102B70000B070A590D040C6FFF000B070A5A0D0BC7
+:102B80000C91FF000B070A730D140CDAFF000B0702
+:102B90000A740D0D0C93FF000B070A750D040CD978
+:102BA000FF000B070A760D050C93FF000B070A7751
+:102BB0000D140CDAFF000B070A780D0D0C93FF00C3
+:102BC0000B070A790D040CD9FF000B070A7A0D05D3
+:102BD0000C93FF000B070A5E0D030C68FF000B0748
+:102BE0000A5C0D040C31FF000B070A5D0D040C316B
+:102BF000FF000B070A620D030C52FF000B070A606F
+:102C00000D040C76FF000B070A610D040C76FF0023
+:102C10000B070A660D030C2EFF000B070A640D0458
+:102C20000CDAFF000B070A650D040CDAFF000B0736
+:102C30000A6A0D020CF6FF000B070A680D050C620C
+:102C4000FF000B070A690D050C62FF000B060A4620
+:102C50000D0A0C22FF000B060A480D0D0C24FF0084
+:102C60000B060A6E0D110CD3FF000B060A700D1532
+:102C70000CCBFF000B060A520D200C93FF000B0635
+:102C80000A540D200C54FF000B060A4A0D270C1D98
+:102C9000FF000B060A580D2F0CC8FF000B060A5C3C
+:102CA0000D300C07FF000B060A4C0D370C90FF008F
+:102CB0000B060A600D3D0CDBFF000B060A640D3E9F
+:102CC0000C42FF000B060A4E0D450C78FF000B0668
+:102CD0000A680D4C0C48FF000B060A6C0D4C0C6C7E
+:102CE000FF000B060A500D520CE2FF000B060A42D1
+:102CF0000D020CBAFF00FF000E1E0F14FF000EDEC7
+:102D00000F20FF000EDF0F20FF000B060A780D00DA
+:102D10000C40FF000B070A030D0F0CFFFF000B0711
+:102D20000A0B0D0F0CFFFF000B070A020D000C0031
+:102D3000FF000B070A0A0D000C00FF000B070A46F4
+:102D40000D000C00FF000B070A490D000C000905DF
+:102D50000B000A100D000C00FF000D000C00FF001E
+:102D60000D020C00FF000D000C00FF000D000C0018
+:102D7000FF000D000C00FF000D000C00FF000D0017
+:102D80000C00FF000D000C00FF000D000C00FF0008
+:102D90000D000C00FF000D000C00FF000D000C00EA
+:102DA000FF000D000C00FF000D000C00FF000D00E7
+:102DB0000C00FF000D000C00FF000D000C00FF00D8
+:102DC0000D000C00FF000D000C00FF000D000C00BA
+:102DD000FF000D000C00FF000D000C00FF000D00B7
+:102DE0000C00FF000D000C00FF000D000C00FF00A8
+:102DF0000D000C00FF000D000C00FF000D000C008A
+:102E0000FF000D000C00FF000D000C00FF000D0086
+:102E10000C00FF000D000C00FF000D000C00FF0077
+:102E20000D000C00FF000D000C00FF000D000C0059
+:102E3000FF000D000C00FF000D000C00FF000D0056
+:102E40000C00FF000D000C00FF000D000C00FF0047
+:102E50000D000C00FF000D000C00FF000D000C0029
+:102E6000FF000D000C00FF000D000C00FF000D0026
+:102E70000C00FF0009050B010A100D010CC0FF003A
+:102E80000D010CFAFF000D000C1AFF000D000C00E4
+:102E9000FF000D000C00FF000D000C00FF000D00F6
+:102EA0000C00FF000D000C00FF000D000C00FF00E7
+:102EB0000D000C00FF000D000C00FF000D000C00C9
+:102EC000FF000D000C00FF000D000C00FF000D00C6
+:102ED0000C00FF000D000C00FF000D000C00FF00B7
+:102EE0000D000C00FF000D000C00FF000D000C0099
+:102EF000FF000D000C00FF000D000C00FF000D0096
+:102F00000C00FF000D000C00FF000D000C00FF0086
+:102F10000D000C00FF000D000C00FF000D000C0068
+:102F2000FF000D000C00FF000D000C00FF000D0065
+:102F30000C00FF000D000C00FF000D000C00FF0056
+:102F40000D000C00FF000D000C00FF000D000C0038
+:102F5000FF000D000C00FF000D000C00FF000D0035
+:102F60000C00FF000D000C00FF000D000C00FF0026
+:102F70000D000C00FF000D000C00FF000D000C0008
+:102F8000FF000D000C00FF000D000C00FF000D0005
+:102F90000C00FF000D000C00FF00FF00FF00090502
+:102FA0000B020A100C46FF000C46FF000C00FF004D
+:102FB0000C00FF000C00FF000C00FF000C00FF00E5
+:102FC0000C00FF000C00FF000C00FF000C00FF00D5
+:102FD0000C00FF000C00FF000C00FF000C00FF00C5
+:102FE0000C00FF000C00FF000C00FF000C00FF00B5
+:102FF0000C00FF000C00FF000C00FF000C00FF00A5
+:103000000C00FF000C00FF000C00FF000C00FF0094
+:103010000C00FF000C00FF000C00FF000C00FF0084
+:103020000C00FF000C00FF000C00FF000C00FF0074
+:103030000C00FF000C00FF000C00FF000C00FF0064
+:103040000C00FF000C00FF000C00FF000C00FF0054
+:103050000C00FF000C00FF000C00FF000C00FF0044
+:103060000C00FF0009050B030A100C00FF000C0008
+:10307000FF000C00FF000C00FF000C00FF000C0024
+:10308000FF000C00FF000C00FF000C00FF000C0014
+:10309000FF000C00FF000C00FF000C00FF000C0004
+:1030A000FF000C00FF000C00FF000C00FF000C00F4
+:1030B000FF000C00FF000C00FF000C00FF000C00E4
+:1030C000FF000C00FF000C00FF000C00FF000C00D4
+:1030D000FF000C00FF000C00FF000C00FF000C00C4
+:1030E000FF000C00FF000C00FF000C00FF000C00B4
+:1030F000FF000C00FF000C00FF000C00FF000C00A4
+:10310000FF000C00FF000C00FF000C00FF000C0093
+:10311000FF000C00FF000C00FF000C00FF000C0083
+:10312000FF000C00FF000C00FF0009050B040A1053
+:103130000C00FF000C00FF000C00FF000C00FF0063
+:103140000C00FF000C00FF000C00FF000C00FF0053
+:103150000C00FF000C00FF000C00FF000C00FF0043
+:103160000C00FF000C00FF000C00FF000C00FF0033
+:103170000C00FF000C00FF000C00FF000C00FF0023
+:103180000C00FF000C00FF000C00FF000C00FF0013
+:103190000C00FF000C00FF000C00FF000C00FF0003
+:1031A0000C00FF000C00FF000C00FF000C00FF00F3
+:1031B0000C00FF000C00FF000C00FF000C00FF00E3
+:1031C0000C00FF000C00FF000C00FF000C00FF00D3
+:1031D0000C00FF000C00FF000C00FF000C00FF00C3
+:1031E0000C00FF000C00FF000C00FF000C00FF00B3
+:1031F00009010B060A100D000C00FF000A120D0059
+:103200000C00FF000A140D000C00FF000A160D0050
+:103210000C00FF000A180D000C00FF000A1A0D0038
+:103220000C00FF000A1C0D000C00FF000A1E0D0020
+:103230000C00FF000A200D000C00FF000A220D0008
+:103240000C00FF000A240D000C00FF000A260D00F0
+:103250000C00FF000A280D000C00FF000A2A0D00D8
+:103260000C00FF000A2C0D000C00FF000A2E0D00C0
+:103270000C00FF000A300D000C00FF000A320D00A8
+:103280000C00FF000A340D000C00FF000A360D0090
+:103290000C00FF000A380D000C00FF000A3A0D0078
+:1032A0000C00FF000A3C0D000C00FF000A3E0D0060
+:1032B0000C00FF0009050B070A100D0F0CFFFF00A3
+:1032C0000D0F0CFFFF000D000C00FF000D000C00A7
+:1032D000FF000D000C00FF000D000C00FF000D00B2
+:1032E0000C00FF000D000C00FF000D000C00FF00A3
+:1032F0000D000C00FF000D000C00FF000D000C0085
+:10330000FF000D000C00FF000D000C00FF000D0081
+:103310000C00FF000D000C00FF000D000C00FF0072
+:103320000D000C00FF000D000C00FF000D000C0054
+:10333000FF000D000C00FF000D000C00FF000D0051
+:103340000C00FF000D000C00FF000D000C00FF0042
+:103350000D000C00FF000D000C00FF000D000C0024
+:10336000FF000D000C00FF000D000C00FF000D0021
+:103370000C00FF000D000C00FF000D000C00FF0012
+:103380000D000C00FF000D000C00FF000D000C00F4
+:10339000FF000D000C00FF000D000C00FF000D00F1
+:1033A0000C00FF000D000C00FF000D000C00FF00E2
+:1033B0000D000C00FF000D000C00FF000D000C00C4
+:1033C000FF000D000C00FF000D000C00FF000D00C1
+:1033D0000C00FF000D000C00FF000E010F00FF00AD
+:1033E0000E020F00FF000E010F01FF000E020F0082
+:1033F000FF000E010F02FF000E020F00FF000E0182
+:103400000F03FF000E020F00FF000E010F04FF006C
+:103410000E020F00FF000E010F05FF000E020F004D
+:10342000FF000E010F06FF000E020F00FF000E014D
+:103430000F07FF000E020F00FF000EB00F20FF006D
+:103440000EB10F20FF000EB20F20FF000EB30F20B1
+:10345000FF000EB40F20FF000EB50F20FF000EB6C8
+:103460000F20FF000EB70F20FF000EF00F20FF000F
+:103470000EF10F20FF000EF20F20FF000EF30F20C1
+:10348000FF000EF40F20FF000EF50F20FF000EF6D8
+:103490000F20FF000EF70F20FF000E100FFFFF00A0
+:1034A0000E110FFFFF000E120FFFFF000E130FFF94
+:1034B000FF000E140FFFFF000E150FFFFF000E168A
+:1034C0000FFFFF000E170FFFFF000E200FFFFF0082
+:1034D0000E210FFFFF000E220FFFFF000E230FFF34
+:1034E000FF000E240FFFFF000E250FFFFF000E262A
+:1034F0000FFFFF000E270FFFFF000E300F00FF0031
+:103500000E310F00FF000E320F00FF000E330F00D0
+:10351000FF000E340F00FF000E350F00FF000E36C7
+:103520000F00FF000E370F00FF000E400F00FF00DE
+:103530000E410F00FF000E420F00FF000E430F0070
+:10354000FF000E440F00FF000E450F00FF000E4667
+:103550000F00FF000E470F00FF000E500F00FF008E
+:103560000E510F00FF000E520F00FF000E530F0010
+:10357000FF000E540F00FF000E550F00FF000E5607
+:103580000F00FF000E570F00FF000E600F00FF003E
+:103590000E610F00FF000E620F00FF000E630F00B0
+:1035A000FF000E640F00FF000E650F00FF000E66A7
+:1035B0000F00FF000E670F00FF000E700FC0FF002E
+:1035C0000E710FC0FF000E720FC0FF000E730FC010
+:1035D000FF000E740FC0FF000E750FC0FF000E76C7
+:1035E0000FC0FF000E770FC0FF000E800F00FF001E
+:1035F0000E810F00FF000E820F00FF000E830F00F0
+:10360000FF000E840F00FF000E850F00FF000E86E6
+:103610000F00FF000E870F00FF000E900F00FF004D
+:103620000E910F00FF000E920F00FF000E930F008F
+:10363000FF000E940F00FF000E950F00FF000E9686
+:103640000F00FF000E970F00FF000EA00F00FF00FD
+:103650000EA10F00FF000EA20F00FF000EA30F002F
+:10366000FF000EA40F00FF000EA50F00FF000EA626
+:103670000F00FF000EA70F00FF000EC00F00FF009D
+:103680000EC10F00FF000EC20F00FF000EC30F009F
+:10369000FF000EC40F00FF000EC50F00FF000EC696
+:1036A0000F00FF000EC70F00FF000ED00F00FF003D
+:1036B0000ED10F00FF000ED20F00FF000ED30F003F
+:1036C000FF000ED40F00FF000ED50F00FF000ED636
+:1036D0000F00FF000ED70F00FF000EE00F00FF00ED
+:1036E0000EE10F00FF000EE20F00FF000EE30F00DF
+:1036F000FF000EE40F00FF000EE50F00FF000EE6D6
+:103700000F00FF000EE70F00FF000E010F00FF008B
+:103710000E020F01FF000E010F01FF000E020F014C
+:10372000FF000E010F02FF000E020F01FF000E014D
+:103730000F03FF000E020F01FF000E010F04FF0038
+:103740000E020F01FF000E010F05FF000E020F0118
+:10375000FF000E010F06FF000E020F01FF000E0119
+:103760000F07FF000E020F01FF000B070A460D00B6
+:103770000C00FF000B070A490D000C00FF000B07AF
+:103780000A450D0F0CFFFF000B070A480D0F0CFF39
+:10379000FF000B070A7B0D040CCCFF000B070A7D12
+:1037A0000D040CCCFF000B070A7C0D000C00FF0081
+:1037B0000B070A7E0D000C00FF000B070A460D00E8
+:1037C0000C00FF000B070A490D000C00FF000B075F
+:1037D0000A470D000C00FF000B070A4A0D000C0001
+:1037E000FF000B070A4C0D000C00FF000B070A4EF0
+:1037F0000D000C00FF000B070A4C0D000C000B071E
+:103800000A4E0D000C000B070A4C0D000C280B078C
+:103810000A4E0D000C280B070A4C0D000C510B072B
+:103820000A4E0D000C510B070A4C0D000C7A0B07C9
+:103830000A4E0D000C7A0B070A4C0D000CA30B0767
+:103840000A4E0D000CA30B070A4C0D000CCC0B0705
+:103850000A4E0D000CCC0B070A4C0D000CF50B07A3
+:103860000A4E0D000CF50B070A4C0D010C1E0B0740
+:103870000A4E0D010C1E0B070A4C0D010C470B07DD
+:103880000A4E0D010C470B070A4C0D010C700B077B
+:103890000A4E0D010C700B070A4C0D010C990B0719
+:1038A0000A4E0D010C990B070A4C0D010CC20B07B7
+:1038B0000A4E0D010CC20B070A4C0D010CEB0B0755
+:1038C0000A4E0D010CEB0B070A4C0D020C140B07F2
+:1038D0000A4E0D020C140B070A4C0D020C3D0B078F
+:1038E0000A4E0D020C3D0B070A4C0D020C660B072D
+:1038F0000A4E0D020C660B070A4C0D020C8F0B07CB
+:103900000A4E0D020C8F0B070A4C0D020CB80B0768
+:103910000A4E0D020CB80B070A4C0D020CE10B0706
+:103920000A4E0D020CE10B070A4C0D030C0A0B07A3
+:103930000A4E0D030C0A0B070A4C0D030C330B0740
+:103940000A4E0D030C330B070A4C0D030C5C0B07DE
+:103950000A4E0D030C5C0B070A4C0D030C850B077C
+:103960000A4E0D030C850B070A4C0D030CAE0B071A
+:103970000A4E0D030CAE0B070A4C0D030CD70B07B8
+:103980000A4E0D030CD70B070A4C0D040C000B0755
+:103990000A4E0D040C000B070A4C0D040C280B07F3
+:1039A0000A4E0D040C280B070A4C0D040C510B0792
+:1039B0000A4E0D040C510B070A4C0D040C7A0B0730
+:1039C0000A4E0D040C7A0B070A4C0D040CA30B07CE
+:1039D0000A4E0D040CA30B070A4C0D040CCC0B076C
+:1039E0000A4E0D040CCC0B070A4C0D040CF50B070A
+:1039F0000A4E0D040CF50B070A4C0D050C1E0B07A7
+:103A00000A4E0D050C1E0B070A4C0D050C470B0743
+:103A10000A4E0D050C470B070A4C0D050C700B07E1
+:103A20000A4E0D050C700B070A4C0D050C990B077F
+:103A30000A4E0D050C990B070A4C0D050CC20B071D
+:103A40000A4E0D050CC20B070A4C0D050CEB0B07BB
+:103A50000A4E0D050CEB0B070A4C0D060C140B0758
+:103A60000A4E0D060C140B070A4C0D060C3D0B07F5
+:103A70000A4E0D060C3D0B070A4C0D060C660B0793
+:103A80000A4E0D060C660B070A4C0D060C8F0B0731
+:103A90000A4E0D060C8F0B070A4C0D060CB80B07CF
+:103AA0000A4E0D060CB80B070A4C0D060CE10B076D
+:103AB0000A4E0D060CE10B070A4C0D070C0A0B070A
+:103AC0000A4E0D070C0A0B070A4C0D070C330B07A7
+:103AD0000A4E0D070C330B070A4C0D070C5C0B0745
+:103AE0000A4E0D070C5C0B070A4C0D070C850B07E3
+:103AF0000A4E0D070C850B070A4C0D070CAE0B0781
+:103B00000A4E0D070CAE0B070A4C0D070CD70B071E
+:103B10000A4E0D070CD70B070A4C0D080C000B07BB
+:103B20000A4E0D080C000B070A4C0D080C280B0759
+:103B30000A4E0D080C280B070A4C0D080C510B07F8
+:103B40000A4E0D080C510B070A4C0D080C7A0B0796
+:103B50000A4E0D080C7A0B070A4C0D080CA30B0734
+:103B60000A4E0D080CA30B070A4C0D080CCC0B07D2
+:103B70000A4E0D080CCC0B070A4C0D080CF50B0770
+:103B80000A4E0D080CF50B070A4C0D090C1E0B070D
+:103B90000A4E0D090C1E0B070A4C0D090C470B07AA
+:103BA0000A4E0D090C470B070A4C0D090C700B0748
+:103BB0000A4E0D090C700B070A4C0D090C990B07E6
+:103BC0000A4E0D090C990B070A4C0D090CC20B0784
+:103BD0000A4E0D090CC20B070A4C0D090CEB0B0722
+:103BE0000A4E0D090CEB0B070A4C0D0A0C140B07BF
+:103BF0000A4E0D0A0C140B070A4C0D0A0C3D0B075C
+:103C00000A4E0D0A0C3D0B070A4C0D0A0C660B07F9
+:103C10000A4E0D0A0C660B070A4C0D0A0C8F0B0797
+:103C20000A4E0D0A0C8F0B070A4C0D0A0CB80B0735
+:103C30000A4E0D0A0CB80B070A4C0D0A0CE10B07D3
+:103C40000A4E0D0A0CE10B070A4C0D0B0C0A0B0770
+:103C50000A4E0D0B0C0A0B070A4C0D0B0C330B070D
+:103C60000A4E0D0B0C330B070A4C0D0B0C5C0B07AB
+:103C70000A4E0D0B0C5C0B070A4C0D0B0C850B0749
+:103C80000A4E0D0B0C850B070A4C0D0B0CAE0B07E7
+:103C90000A4E0D0B0CAE0B070A4C0D0B0CD70B0785
+:103CA0000A4E0D0B0CD70B070A4C0D0C0C000B0722
+:103CB0000A4E0D0C0C000B070A4C0D0C0C280B07C0
+:103CC0000A4E0D0C0C280B070A4C0D0C0C510B075F
+:103CD0000A4E0D0C0C510B070A4C0D0C0C7A0B07FD
+:103CE0000A4E0D0C0C7A0B070A4C0D0C0CA30B079B
+:103CF0000A4E0D0C0CA30B070A4C0D0C0CCC0B0739
+:103D00000A4E0D0C0CCC0B070A4C0D0C0CF50B07D6
+:103D10000A4E0D0C0CF50B070A4C0D0D0C1E0B0773
+:103D20000A4E0D0D0C1E0B070A4C0D0D0C470B0710
+:103D30000A4E0D0D0C470B070A4C0D0D0C700B07AE
+:103D40000A4E0D0D0C700B070A4C0D0D0C990B074C
+:103D50000A4E0D0D0C990B070A4C0D0D0CC20B07EA
+:103D60000A4E0D0D0CC20B070A4C0D0D0CEB0B0788
+:103D70000A4E0D0D0CEB0B070A4C0D0E0C140B0725
+:103D80000A4E0D0E0C140B070A4C0D0E0C3D0B07C2
+:103D90000A4E0D0E0C3D0B070A4C0D0E0C660B0760
+:103DA0000A4E0D0E0C660B070A4C0D0E0C8F0B07FE
+:103DB0000A4E0D0E0C8F0B070A4C0D0E0CB80B079C
+:103DC0000A4E0D0E0CB80B070A4C0D0E0CE10B073A
+:103DD0000A4E0D0E0CE10B070A4C0D0F0C0A0B07D7
+:103DE0000A4E0D0F0C0A0B070A4C0D0F0C330B0774
+:103DF0000A4E0D0F0C330B070A4C0D0F0C5C0B0712
+:103E00000A4E0D0F0C5C0B070A4C0D0F0C850B07AF
+:103E10000A4E0D0F0C850B070A4C0D0F0CAE0B074D
+:103E20000A4E0D0F0CAE0B070A4C0D0F0CD70B07EB
+:103E30000A4E0D0F0CD70B070A4C0D0F0CFF0B078A
+:0A3E40000A4E0D0F0CFF0800FF00F2
+:00000001FF
diff --git a/fs/Kconfig b/fs/Kconfig
index cef8b18ceaa..9f7270f36b2 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -66,6 +66,13 @@ config GENERIC_ACL
bool
select FS_POSIX_ACL
+menu "Caches"
+
+source "fs/fscache/Kconfig"
+source "fs/cachefiles/Kconfig"
+
+endmenu
+
if BLOCK
menu "CD-ROM/DVD Filesystems"
@@ -168,6 +175,33 @@ source "fs/qnx4/Kconfig"
source "fs/romfs/Kconfig"
source "fs/sysv/Kconfig"
source "fs/ufs/Kconfig"
+source "fs/exofs/Kconfig"
+
+config NILFS2_FS
+ tristate "NILFS2 file system support (EXPERIMENTAL)"
+ depends on BLOCK && EXPERIMENTAL
+ select CRC32
+ help
+ NILFS2 is a log-structured file system (LFS) supporting continuous
+ snapshotting. In addition to versioning capability of the entire
+ file system, users can even restore files mistakenly overwritten or
+ destroyed just a few seconds ago. Since this file system can keep
+ consistency like conventional LFS, it achieves quick recovery after
+ system crashes.
+
+ NILFS2 creates a number of checkpoints every few seconds or per
+ synchronous write basis (unless there is no change). Users can
+ select significant versions among continuously created checkpoints,
+ and can change them into snapshots which will be preserved for long
+ periods until they are changed back to checkpoints. Each
+ snapshot is mountable as a read-only file system concurrently with
+ its writable mount, and this feature is convenient for online backup.
+
+ Some features including atime, extended attributes, and POSIX ACLs,
+ are not supported yet.
+
+ To compile this file system support as a module, choose M here: the
+ module will be called nilfs2. If unsure, say N.
endif # MISC_FILESYSTEMS
diff --git a/fs/Makefile b/fs/Makefile
index b5cd8e18dd9..af6d04700d9 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_PROFILING) += dcookies.o
obj-$(CONFIG_DLM) += dlm/
# Do not add any filesystems before this line
+obj-$(CONFIG_FSCACHE) += fscache/
obj-$(CONFIG_REISERFS_FS) += reiserfs/
obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3
obj-$(CONFIG_EXT2_FS) += ext2/
@@ -113,10 +114,13 @@ obj-$(CONFIG_JFS_FS) += jfs/
obj-$(CONFIG_XFS_FS) += xfs/
obj-$(CONFIG_9P_FS) += 9p/
obj-$(CONFIG_AFS_FS) += afs/
+obj-$(CONFIG_NILFS2_FS) += nilfs2/
obj-$(CONFIG_BEFS_FS) += befs/
obj-$(CONFIG_HOSTFS) += hostfs/
obj-$(CONFIG_HPPFS) += hppfs/
+obj-$(CONFIG_CACHEFILES) += cachefiles/
obj-$(CONFIG_DEBUG_FS) += debugfs/
obj-$(CONFIG_OCFS2_FS) += ocfs2/
obj-$(CONFIG_BTRFS_FS) += btrfs/
obj-$(CONFIG_GFS2_FS) += gfs2/
+obj-$(CONFIG_EXOFS_FS) += exofs/
diff --git a/fs/afs/Kconfig b/fs/afs/Kconfig
index e7b522fe15e..5c4e61d3c77 100644
--- a/fs/afs/Kconfig
+++ b/fs/afs/Kconfig
@@ -19,3 +19,11 @@ config AFS_DEBUG
See <file:Documentation/filesystems/afs.txt> for more information.
If unsure, say N.
+
+config AFS_FSCACHE
+ bool "Provide AFS client caching support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ depends on AFS_FS=m && FSCACHE || AFS_FS=y && FSCACHE=y
+ help
+ Say Y here if you want AFS data to be cached locally on disk through
+ the generic filesystem cache manager
diff --git a/fs/afs/Makefile b/fs/afs/Makefile
index a66671082cf..4f64b95d57b 100644
--- a/fs/afs/Makefile
+++ b/fs/afs/Makefile
@@ -2,7 +2,10 @@
# Makefile for Red Hat Linux AFS client.
#
+afs-cache-$(CONFIG_AFS_FSCACHE) := cache.o
+
kafs-objs := \
+ $(afs-cache-y) \
callback.o \
cell.o \
cmservice.o \
diff --git a/fs/afs/cache.c b/fs/afs/cache.c
index de0d7de69ed..e2b1d3f1651 100644
--- a/fs/afs/cache.c
+++ b/fs/afs/cache.c
@@ -1,6 +1,6 @@
/* AFS caching stuff
*
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -9,248 +9,395 @@
* 2 of the License, or (at your option) any later version.
*/
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_cell_cache_match(void *target,
- const void *entry);
-static void afs_cell_cache_update(void *source, void *entry);
-
-struct cachefs_index_def afs_cache_cell_index_def = {
- .name = "cell_ix",
- .data_size = sizeof(struct afs_cache_cell),
- .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
- .match = afs_cell_cache_match,
- .update = afs_cell_cache_update,
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include "internal.h"
+
+static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data,
+ void *buffer, uint16_t buflen);
+static uint16_t afs_cell_cache_get_aux(const void *cookie_netfs_data,
+ void *buffer, uint16_t buflen);
+static enum fscache_checkaux afs_cell_cache_check_aux(void *cookie_netfs_data,
+ const void *buffer,
+ uint16_t buflen);
+
+static uint16_t afs_vlocation_cache_get_key(const void *cookie_netfs_data,
+ void *buffer, uint16_t buflen);
+static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data,
+ void *buffer, uint16_t buflen);
+static enum fscache_checkaux afs_vlocation_cache_check_aux(
+ void *cookie_netfs_data, const void *buffer, uint16_t buflen);
+
+static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data,
+ void *buffer, uint16_t buflen);
+
+static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data,
+ void *buffer, uint16_t buflen);
+static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
+ uint64_t *size);
+static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data,
+ void *buffer, uint16_t buflen);
+static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
+ const void *buffer,
+ uint16_t buflen);
+static void afs_vnode_cache_now_uncached(void *cookie_netfs_data);
+
+struct fscache_netfs afs_cache_netfs = {
+ .name = "afs",
+ .version = 0,
+};
+
+struct fscache_cookie_def afs_cell_cache_index_def = {
+ .name = "AFS.cell",
+ .type = FSCACHE_COOKIE_TYPE_INDEX,
+ .get_key = afs_cell_cache_get_key,
+ .get_aux = afs_cell_cache_get_aux,
+ .check_aux = afs_cell_cache_check_aux,
+};
+
+struct fscache_cookie_def afs_vlocation_cache_index_def = {
+ .name = "AFS.vldb",
+ .type = FSCACHE_COOKIE_TYPE_INDEX,
+ .get_key = afs_vlocation_cache_get_key,
+ .get_aux = afs_vlocation_cache_get_aux,
+ .check_aux = afs_vlocation_cache_check_aux,
+};
+
+struct fscache_cookie_def afs_volume_cache_index_def = {
+ .name = "AFS.volume",
+ .type = FSCACHE_COOKIE_TYPE_INDEX,
+ .get_key = afs_volume_cache_get_key,
+};
+
+struct fscache_cookie_def afs_vnode_cache_index_def = {
+ .name = "AFS.vnode",
+ .type = FSCACHE_COOKIE_TYPE_DATAFILE,
+ .get_key = afs_vnode_cache_get_key,
+ .get_attr = afs_vnode_cache_get_attr,
+ .get_aux = afs_vnode_cache_get_aux,
+ .check_aux = afs_vnode_cache_check_aux,
+ .now_uncached = afs_vnode_cache_now_uncached,
};
-#endif
/*
- * match a cell record obtained from the cache
+ * set the key for the index entry
*/
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_cell_cache_match(void *target,
- const void *entry)
+static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax)
{
- const struct afs_cache_cell *ccell = entry;
- struct afs_cell *cell = target;
+ const struct afs_cell *cell = cookie_netfs_data;
+ uint16_t klen;
- _enter("{%s},{%s}", ccell->name, cell->name);
+ _enter("%p,%p,%u", cell, buffer, bufmax);
- if (strncmp(ccell->name, cell->name, sizeof(ccell->name)) == 0) {
- _leave(" = SUCCESS");
- return CACHEFS_MATCH_SUCCESS;
- }
+ klen = strlen(cell->name);
+ if (klen > bufmax)
+ return 0;
- _leave(" = FAILED");
- return CACHEFS_MATCH_FAILED;
+ memcpy(buffer, cell->name, klen);
+ return klen;
}
-#endif
/*
- * update a cell record in the cache
+ * provide new auxilliary cache data
*/
-#ifdef AFS_CACHING_SUPPORT
-static void afs_cell_cache_update(void *source, void *entry)
+static uint16_t afs_cell_cache_get_aux(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax)
{
- struct afs_cache_cell *ccell = entry;
- struct afs_cell *cell = source;
+ const struct afs_cell *cell = cookie_netfs_data;
+ uint16_t dlen;
- _enter("%p,%p", source, entry);
+ _enter("%p,%p,%u", cell, buffer, bufmax);
- strncpy(ccell->name, cell->name, sizeof(ccell->name));
+ dlen = cell->vl_naddrs * sizeof(cell->vl_addrs[0]);
+ dlen = min(dlen, bufmax);
+ dlen &= ~(sizeof(cell->vl_addrs[0]) - 1);
- memcpy(ccell->vl_servers,
- cell->vl_addrs,
- min(sizeof(ccell->vl_servers), sizeof(cell->vl_addrs)));
+ memcpy(buffer, cell->vl_addrs, dlen);
+ return dlen;
+}
+/*
+ * check that the auxilliary data indicates that the entry is still valid
+ */
+static enum fscache_checkaux afs_cell_cache_check_aux(void *cookie_netfs_data,
+ const void *buffer,
+ uint16_t buflen)
+{
+ _leave(" = OKAY");
+ return FSCACHE_CHECKAUX_OKAY;
}
-#endif
-
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_vlocation_cache_match(void *target,
- const void *entry);
-static void afs_vlocation_cache_update(void *source, void *entry);
-
-struct cachefs_index_def afs_vlocation_cache_index_def = {
- .name = "vldb",
- .data_size = sizeof(struct afs_cache_vlocation),
- .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
- .match = afs_vlocation_cache_match,
- .update = afs_vlocation_cache_update,
-};
-#endif
+/*****************************************************************************/
/*
- * match a VLDB record stored in the cache
- * - may also load target from entry
+ * set the key for the index entry
*/
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_vlocation_cache_match(void *target,
- const void *entry)
+static uint16_t afs_vlocation_cache_get_key(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax)
{
- const struct afs_cache_vlocation *vldb = entry;
- struct afs_vlocation *vlocation = target;
+ const struct afs_vlocation *vlocation = cookie_netfs_data;
+ uint16_t klen;
+
+ _enter("{%s},%p,%u", vlocation->vldb.name, buffer, bufmax);
+
+ klen = strnlen(vlocation->vldb.name, sizeof(vlocation->vldb.name));
+ if (klen > bufmax)
+ return 0;
- _enter("{%s},{%s}", vlocation->vldb.name, vldb->name);
+ memcpy(buffer, vlocation->vldb.name, klen);
- if (strncmp(vlocation->vldb.name, vldb->name, sizeof(vldb->name)) == 0
- ) {
- if (!vlocation->valid ||
- vlocation->vldb.rtime == vldb->rtime
+ _leave(" = %u", klen);
+ return klen;
+}
+
+/*
+ * provide new auxilliary cache data
+ */
+static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax)
+{
+ const struct afs_vlocation *vlocation = cookie_netfs_data;
+ uint16_t dlen;
+
+ _enter("{%s},%p,%u", vlocation->vldb.name, buffer, bufmax);
+
+ dlen = sizeof(struct afs_cache_vlocation);
+ dlen -= offsetof(struct afs_cache_vlocation, nservers);
+ if (dlen > bufmax)
+ return 0;
+
+ memcpy(buffer, (uint8_t *)&vlocation->vldb.nservers, dlen);
+
+ _leave(" = %u", dlen);
+ return dlen;
+}
+
+/*
+ * check that the auxilliary data indicates that the entry is still valid
+ */
+static
+enum fscache_checkaux afs_vlocation_cache_check_aux(void *cookie_netfs_data,
+ const void *buffer,
+ uint16_t buflen)
+{
+ const struct afs_cache_vlocation *cvldb;
+ struct afs_vlocation *vlocation = cookie_netfs_data;
+ uint16_t dlen;
+
+ _enter("{%s},%p,%u", vlocation->vldb.name, buffer, buflen);
+
+ /* check the size of the data is what we're expecting */
+ dlen = sizeof(struct afs_cache_vlocation);
+ dlen -= offsetof(struct afs_cache_vlocation, nservers);
+ if (dlen != buflen)
+ return FSCACHE_CHECKAUX_OBSOLETE;
+
+ cvldb = container_of(buffer, struct afs_cache_vlocation, nservers);
+
+ /* if what's on disk is more valid than what's in memory, then use the
+ * VL record from the cache */
+ if (!vlocation->valid || vlocation->vldb.rtime == cvldb->rtime) {
+ memcpy((uint8_t *)&vlocation->vldb.nservers, buffer, dlen);
+ vlocation->valid = 1;
+ _leave(" = SUCCESS [c->m]");
+ return FSCACHE_CHECKAUX_OKAY;
+ }
+
+ /* need to update the cache if the cached info differs */
+ if (memcmp(&vlocation->vldb, buffer, dlen) != 0) {
+ /* delete if the volume IDs for this name differ */
+ if (memcmp(&vlocation->vldb.vid, &cvldb->vid,
+ sizeof(cvldb->vid)) != 0
) {
- vlocation->vldb = *vldb;
- vlocation->valid = 1;
- _leave(" = SUCCESS [c->m]");
- return CACHEFS_MATCH_SUCCESS;
- } else if (memcmp(&vlocation->vldb, vldb, sizeof(*vldb)) != 0) {
- /* delete if VIDs for this name differ */
- if (memcmp(&vlocation->vldb.vid,
- &vldb->vid,
- sizeof(vldb->vid)) != 0) {
- _leave(" = DELETE");
- return CACHEFS_MATCH_SUCCESS_DELETE;
- }
-
- _leave(" = UPDATE");
- return CACHEFS_MATCH_SUCCESS_UPDATE;
- } else {
- _leave(" = SUCCESS");
- return CACHEFS_MATCH_SUCCESS;
+ _leave(" = OBSOLETE");
+ return FSCACHE_CHECKAUX_OBSOLETE;
}
+
+ _leave(" = UPDATE");
+ return FSCACHE_CHECKAUX_NEEDS_UPDATE;
}
- _leave(" = FAILED");
- return CACHEFS_MATCH_FAILED;
+ _leave(" = OKAY");
+ return FSCACHE_CHECKAUX_OKAY;
}
-#endif
+/*****************************************************************************/
/*
- * update a VLDB record stored in the cache
+ * set the key for the volume index entry
*/
-#ifdef AFS_CACHING_SUPPORT
-static void afs_vlocation_cache_update(void *source, void *entry)
+static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax)
{
- struct afs_cache_vlocation *vldb = entry;
- struct afs_vlocation *vlocation = source;
+ const struct afs_volume *volume = cookie_netfs_data;
+ uint16_t klen;
+
+ _enter("{%u},%p,%u", volume->type, buffer, bufmax);
+
+ klen = sizeof(volume->type);
+ if (klen > bufmax)
+ return 0;
- _enter("");
+ memcpy(buffer, &volume->type, sizeof(volume->type));
+
+ _leave(" = %u", klen);
+ return klen;
- *vldb = vlocation->vldb;
}
-#endif
-
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_volume_cache_match(void *target,
- const void *entry);
-static void afs_volume_cache_update(void *source, void *entry);
-
-struct cachefs_index_def afs_volume_cache_index_def = {
- .name = "volume",
- .data_size = sizeof(struct afs_cache_vhash),
- .keys[0] = { CACHEFS_INDEX_KEYS_BIN, 1 },
- .keys[1] = { CACHEFS_INDEX_KEYS_BIN, 1 },
- .match = afs_volume_cache_match,
- .update = afs_volume_cache_update,
-};
-#endif
+/*****************************************************************************/
/*
- * match a volume hash record stored in the cache
+ * set the key for the index entry
*/
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_volume_cache_match(void *target,
- const void *entry)
+static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax)
{
- const struct afs_cache_vhash *vhash = entry;
- struct afs_volume *volume = target;
+ const struct afs_vnode *vnode = cookie_netfs_data;
+ uint16_t klen;
- _enter("{%u},{%u}", volume->type, vhash->vtype);
+ _enter("{%x,%x,%llx},%p,%u",
+ vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
+ buffer, bufmax);
- if (volume->type == vhash->vtype) {
- _leave(" = SUCCESS");
- return CACHEFS_MATCH_SUCCESS;
- }
+ klen = sizeof(vnode->fid.vnode);
+ if (klen > bufmax)
+ return 0;
+
+ memcpy(buffer, &vnode->fid.vnode, sizeof(vnode->fid.vnode));
- _leave(" = FAILED");
- return CACHEFS_MATCH_FAILED;
+ _leave(" = %u", klen);
+ return klen;
}
-#endif
/*
- * update a volume hash record stored in the cache
+ * provide updated file attributes
*/
-#ifdef AFS_CACHING_SUPPORT
-static void afs_volume_cache_update(void *source, void *entry)
+static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
+ uint64_t *size)
{
- struct afs_cache_vhash *vhash = entry;
- struct afs_volume *volume = source;
+ const struct afs_vnode *vnode = cookie_netfs_data;
- _enter("");
+ _enter("{%x,%x,%llx},",
+ vnode->fid.vnode, vnode->fid.unique,
+ vnode->status.data_version);
- vhash->vtype = volume->type;
+ *size = vnode->status.size;
}
-#endif
-
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_vnode_cache_match(void *target,
- const void *entry);
-static void afs_vnode_cache_update(void *source, void *entry);
-
-struct cachefs_index_def afs_vnode_cache_index_def = {
- .name = "vnode",
- .data_size = sizeof(struct afs_cache_vnode),
- .keys[0] = { CACHEFS_INDEX_KEYS_BIN, 4 },
- .match = afs_vnode_cache_match,
- .update = afs_vnode_cache_update,
-};
-#endif
/*
- * match a vnode record stored in the cache
+ * provide new auxilliary cache data
+ */
+static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax)
+{
+ const struct afs_vnode *vnode = cookie_netfs_data;
+ uint16_t dlen;
+
+ _enter("{%x,%x,%Lx},%p,%u",
+ vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
+ buffer, bufmax);
+
+ dlen = sizeof(vnode->fid.unique) + sizeof(vnode->status.data_version);
+ if (dlen > bufmax)
+ return 0;
+
+ memcpy(buffer, &vnode->fid.unique, sizeof(vnode->fid.unique));
+ buffer += sizeof(vnode->fid.unique);
+ memcpy(buffer, &vnode->status.data_version,
+ sizeof(vnode->status.data_version));
+
+ _leave(" = %u", dlen);
+ return dlen;
+}
+
+/*
+ * check that the auxilliary data indicates that the entry is still valid
*/
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_vnode_cache_match(void *target,
- const void *entry)
+static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
+ const void *buffer,
+ uint16_t buflen)
{
- const struct afs_cache_vnode *cvnode = entry;
- struct afs_vnode *vnode = target;
-
- _enter("{%x,%x,%Lx},{%x,%x,%Lx}",
- vnode->fid.vnode,
- vnode->fid.unique,
- vnode->status.version,
- cvnode->vnode_id,
- cvnode->vnode_unique,
- cvnode->data_version);
-
- if (vnode->fid.vnode != cvnode->vnode_id) {
- _leave(" = FAILED");
- return CACHEFS_MATCH_FAILED;
+ struct afs_vnode *vnode = cookie_netfs_data;
+ uint16_t dlen;
+
+ _enter("{%x,%x,%llx},%p,%u",
+ vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
+ buffer, buflen);
+
+ /* check the size of the data is what we're expecting */
+ dlen = sizeof(vnode->fid.unique) + sizeof(vnode->status.data_version);
+ if (dlen != buflen) {
+ _leave(" = OBSOLETE [len %hx != %hx]", dlen, buflen);
+ return FSCACHE_CHECKAUX_OBSOLETE;
}
- if (vnode->fid.unique != cvnode->vnode_unique ||
- vnode->status.version != cvnode->data_version) {
- _leave(" = DELETE");
- return CACHEFS_MATCH_SUCCESS_DELETE;
+ if (memcmp(buffer,
+ &vnode->fid.unique,
+ sizeof(vnode->fid.unique)
+ ) != 0) {
+ unsigned unique;
+
+ memcpy(&unique, buffer, sizeof(unique));
+
+ _leave(" = OBSOLETE [uniq %x != %x]",
+ unique, vnode->fid.unique);
+ return FSCACHE_CHECKAUX_OBSOLETE;
+ }
+
+ if (memcmp(buffer + sizeof(vnode->fid.unique),
+ &vnode->status.data_version,
+ sizeof(vnode->status.data_version)
+ ) != 0) {
+ afs_dataversion_t version;
+
+ memcpy(&version, buffer + sizeof(vnode->fid.unique),
+ sizeof(version));
+
+ _leave(" = OBSOLETE [vers %llx != %llx]",
+ version, vnode->status.data_version);
+ return FSCACHE_CHECKAUX_OBSOLETE;
}
_leave(" = SUCCESS");
- return CACHEFS_MATCH_SUCCESS;
+ return FSCACHE_CHECKAUX_OKAY;
}
-#endif
/*
- * update a vnode record stored in the cache
+ * indication the cookie is no longer uncached
+ * - this function is called when the backing store currently caching a cookie
+ * is removed
+ * - the netfs should use this to clean up any markers indicating cached pages
+ * - this is mandatory for any object that may have data
*/
-#ifdef AFS_CACHING_SUPPORT
-static void afs_vnode_cache_update(void *source, void *entry)
+static void afs_vnode_cache_now_uncached(void *cookie_netfs_data)
{
- struct afs_cache_vnode *cvnode = entry;
- struct afs_vnode *vnode = source;
+ struct afs_vnode *vnode = cookie_netfs_data;
+ struct pagevec pvec;
+ pgoff_t first;
+ int loop, nr_pages;
+
+ _enter("{%x,%x,%Lx}",
+ vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version);
+
+ pagevec_init(&pvec, 0);
+ first = 0;
+
+ for (;;) {
+ /* grab a bunch of pages to clean */
+ nr_pages = pagevec_lookup(&pvec, vnode->vfs_inode.i_mapping,
+ first,
+ PAGEVEC_SIZE - pagevec_count(&pvec));
+ if (!nr_pages)
+ break;
- _enter("");
+ for (loop = 0; loop < nr_pages; loop++)
+ ClearPageFsCache(pvec.pages[loop]);
+
+ first = pvec.pages[nr_pages - 1]->index + 1;
+
+ pvec.nr = nr_pages;
+ pagevec_release(&pvec);
+ cond_resched();
+ }
- cvnode->vnode_id = vnode->fid.vnode;
- cvnode->vnode_unique = vnode->fid.unique;
- cvnode->data_version = vnode->status.version;
+ _leave("");
}
-#endif
diff --git a/fs/afs/cache.h b/fs/afs/cache.h
index 36a3642cf90..5c4f6b499e9 100644
--- a/fs/afs/cache.h
+++ b/fs/afs/cache.h
@@ -1,6 +1,6 @@
/* AFS local cache management interface
*
- * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -9,15 +9,4 @@
* 2 of the License, or (at your option) any later version.
*/
-#ifndef AFS_CACHE_H
-#define AFS_CACHE_H
-
-#undef AFS_CACHING_SUPPORT
-
-#include <linux/mm.h>
-#ifdef AFS_CACHING_SUPPORT
-#include <linux/cachefs.h>
-#endif
-#include "types.h"
-
-#endif /* AFS_CACHE_H */
+#include <linux/fscache.h>
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index 5e1df14e16b..e19c13f059e 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -147,12 +147,11 @@ struct afs_cell *afs_cell_create(const char *name, char *vllist)
if (ret < 0)
goto error;
-#ifdef AFS_CACHING_SUPPORT
- /* put it up for caching */
- cachefs_acquire_cookie(afs_cache_netfs.primary_index,
- &afs_vlocation_cache_index_def,
- cell,
- &cell->cache);
+#ifdef CONFIG_AFS_FSCACHE
+ /* put it up for caching (this never returns an error) */
+ cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index,
+ &afs_cell_cache_index_def,
+ cell);
#endif
/* add to the cell lists */
@@ -362,10 +361,9 @@ static void afs_cell_destroy(struct afs_cell *cell)
list_del_init(&cell->proc_link);
up_write(&afs_proc_cells_sem);
-#ifdef AFS_CACHING_SUPPORT
- cachefs_relinquish_cookie(cell->cache, 0);
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_relinquish_cookie(cell->cache, 0);
#endif
-
key_put(cell->anonymous_key);
kfree(cell);
diff --git a/fs/afs/file.c b/fs/afs/file.c
index a3901769a96..7a1d942ef68 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -23,6 +23,9 @@ static void afs_invalidatepage(struct page *page, unsigned long offset);
static int afs_releasepage(struct page *page, gfp_t gfp_flags);
static int afs_launder_page(struct page *page);
+static int afs_readpages(struct file *filp, struct address_space *mapping,
+ struct list_head *pages, unsigned nr_pages);
+
const struct file_operations afs_file_operations = {
.open = afs_open,
.release = afs_release,
@@ -46,6 +49,7 @@ const struct inode_operations afs_file_inode_operations = {
const struct address_space_operations afs_fs_aops = {
.readpage = afs_readpage,
+ .readpages = afs_readpages,
.set_page_dirty = afs_set_page_dirty,
.launder_page = afs_launder_page,
.releasepage = afs_releasepage,
@@ -101,37 +105,18 @@ int afs_release(struct inode *inode, struct file *file)
/*
* deal with notification that a page was read from the cache
*/
-#ifdef AFS_CACHING_SUPPORT
-static void afs_readpage_read_complete(void *cookie_data,
- struct page *page,
- void *data,
- int error)
+static void afs_file_readpage_read_complete(struct page *page,
+ void *data,
+ int error)
{
- _enter("%p,%p,%p,%d", cookie_data, page, data, error);
+ _enter("%p,%p,%d", page, data, error);
- if (error)
- SetPageError(page);
- else
+ /* if the read completes with an error, we just unlock the page and let
+ * the VM reissue the readpage */
+ if (!error)
SetPageUptodate(page);
unlock_page(page);
-
}
-#endif
-
-/*
- * deal with notification that a page was written to the cache
- */
-#ifdef AFS_CACHING_SUPPORT
-static void afs_readpage_write_complete(void *cookie_data,
- struct page *page,
- void *data,
- int error)
-{
- _enter("%p,%p,%p,%d", cookie_data, page, data, error);
-
- unlock_page(page);
-}
-#endif
/*
* AFS read page from file, directory or symlink
@@ -161,9 +146,9 @@ static int afs_readpage(struct file *file, struct page *page)
if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
goto error;
-#ifdef AFS_CACHING_SUPPORT
/* is it cached? */
- ret = cachefs_read_or_alloc_page(vnode->cache,
+#ifdef CONFIG_AFS_FSCACHE
+ ret = fscache_read_or_alloc_page(vnode->cache,
page,
afs_file_readpage_read_complete,
NULL,
@@ -171,20 +156,21 @@ static int afs_readpage(struct file *file, struct page *page)
#else
ret = -ENOBUFS;
#endif
-
switch (ret) {
- /* read BIO submitted and wb-journal entry found */
- case 1:
- BUG(); // TODO - handle wb-journal match
-
/* read BIO submitted (page in cache) */
case 0:
break;
- /* no page available in cache */
- case -ENOBUFS:
+ /* page not yet cached */
case -ENODATA:
+ _debug("cache said ENODATA");
+ goto go_on;
+
+ /* page will not be cached */
+ case -ENOBUFS:
+ _debug("cache said ENOBUFS");
default:
+ go_on:
offset = page->index << PAGE_CACHE_SHIFT;
len = min_t(size_t, i_size_read(inode) - offset, PAGE_SIZE);
@@ -198,27 +184,25 @@ static int afs_readpage(struct file *file, struct page *page)
set_bit(AFS_VNODE_DELETED, &vnode->flags);
ret = -ESTALE;
}
-#ifdef AFS_CACHING_SUPPORT
- cachefs_uncache_page(vnode->cache, page);
+
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_uncache_page(vnode->cache, page);
#endif
+ BUG_ON(PageFsCache(page));
goto error;
}
SetPageUptodate(page);
-#ifdef AFS_CACHING_SUPPORT
- if (cachefs_write_page(vnode->cache,
- page,
- afs_file_readpage_write_complete,
- NULL,
- GFP_KERNEL) != 0
- ) {
- cachefs_uncache_page(vnode->cache, page);
- unlock_page(page);
+ /* send the page to the cache */
+#ifdef CONFIG_AFS_FSCACHE
+ if (PageFsCache(page) &&
+ fscache_write_page(vnode->cache, page, GFP_KERNEL) != 0) {
+ fscache_uncache_page(vnode->cache, page);
+ BUG_ON(PageFsCache(page));
}
-#else
- unlock_page(page);
#endif
+ unlock_page(page);
}
_leave(" = 0");
@@ -232,34 +216,59 @@ error:
}
/*
- * invalidate part or all of a page
+ * read a set of pages
*/
-static void afs_invalidatepage(struct page *page, unsigned long offset)
+static int afs_readpages(struct file *file, struct address_space *mapping,
+ struct list_head *pages, unsigned nr_pages)
{
- int ret = 1;
+ struct afs_vnode *vnode;
+ int ret = 0;
- _enter("{%lu},%lu", page->index, offset);
+ _enter(",{%lu},,%d", mapping->host->i_ino, nr_pages);
- BUG_ON(!PageLocked(page));
+ vnode = AFS_FS_I(mapping->host);
+ if (vnode->flags & AFS_VNODE_DELETED) {
+ _leave(" = -ESTALE");
+ return -ESTALE;
+ }
- if (PagePrivate(page)) {
- /* We release buffers only if the entire page is being
- * invalidated.
- * The get_block cached value has been unconditionally
- * invalidated, so real IO is not possible anymore.
- */
- if (offset == 0) {
- BUG_ON(!PageLocked(page));
-
- ret = 0;
- if (!PageWriteback(page))
- ret = page->mapping->a_ops->releasepage(page,
- 0);
- /* possibly should BUG_ON(!ret); - neilb */
- }
+ /* attempt to read as many of the pages as possible */
+#ifdef CONFIG_AFS_FSCACHE
+ ret = fscache_read_or_alloc_pages(vnode->cache,
+ mapping,
+ pages,
+ &nr_pages,
+ afs_file_readpage_read_complete,
+ NULL,
+ mapping_gfp_mask(mapping));
+#else
+ ret = -ENOBUFS;
+#endif
+
+ switch (ret) {
+ /* all pages are being read from the cache */
+ case 0:
+ BUG_ON(!list_empty(pages));
+ BUG_ON(nr_pages != 0);
+ _leave(" = 0 [reading all]");
+ return 0;
+
+ /* there were pages that couldn't be read from the cache */
+ case -ENODATA:
+ case -ENOBUFS:
+ break;
+
+ /* other error */
+ default:
+ _leave(" = %d", ret);
+ return ret;
}
- _leave(" = %d", ret);
+ /* load the missing pages from the network */
+ ret = read_cache_pages(mapping, pages, (void *) afs_readpage, file);
+
+ _leave(" = %d [netting]", ret);
+ return ret;
}
/*
@@ -273,25 +282,82 @@ static int afs_launder_page(struct page *page)
}
/*
- * release a page and cleanup its private data
+ * invalidate part or all of a page
+ * - release a page and clean up its private data if offset is 0 (indicating
+ * the entire page)
+ */
+static void afs_invalidatepage(struct page *page, unsigned long offset)
+{
+ struct afs_writeback *wb = (struct afs_writeback *) page_private(page);
+
+ _enter("{%lu},%lu", page->index, offset);
+
+ BUG_ON(!PageLocked(page));
+
+ /* we clean up only if the entire page is being invalidated */
+ if (offset == 0) {
+#ifdef CONFIG_AFS_FSCACHE
+ if (PageFsCache(page)) {
+ struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
+ fscache_wait_on_page_write(vnode->cache, page);
+ fscache_uncache_page(vnode->cache, page);
+ ClearPageFsCache(page);
+ }
+#endif
+
+ if (PagePrivate(page)) {
+ if (wb && !PageWriteback(page)) {
+ set_page_private(page, 0);
+ afs_put_writeback(wb);
+ }
+
+ if (!page_private(page))
+ ClearPagePrivate(page);
+ }
+ }
+
+ _leave("");
+}
+
+/*
+ * release a page and clean up its private state if it's not busy
+ * - return true if the page can now be released, false if not
*/
static int afs_releasepage(struct page *page, gfp_t gfp_flags)
{
+ struct afs_writeback *wb = (struct afs_writeback *) page_private(page);
struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
- struct afs_writeback *wb;
_enter("{{%x:%u}[%lu],%lx},%x",
vnode->fid.vid, vnode->fid.vnode, page->index, page->flags,
gfp_flags);
+ /* deny if page is being written to the cache and the caller hasn't
+ * elected to wait */
+#ifdef CONFIG_AFS_FSCACHE
+ if (PageFsCache(page)) {
+ if (fscache_check_page_write(vnode->cache, page)) {
+ if (!(gfp_flags & __GFP_WAIT)) {
+ _leave(" = F [cache busy]");
+ return 0;
+ }
+ fscache_wait_on_page_write(vnode->cache, page);
+ }
+
+ fscache_uncache_page(vnode->cache, page);
+ ClearPageFsCache(page);
+ }
+#endif
+
if (PagePrivate(page)) {
- wb = (struct afs_writeback *) page_private(page);
- ASSERT(wb != NULL);
- set_page_private(page, 0);
+ if (wb) {
+ set_page_private(page, 0);
+ afs_put_writeback(wb);
+ }
ClearPagePrivate(page);
- afs_put_writeback(wb);
}
- _leave(" = 0");
- return 0;
+ /* indicate that the page can be released */
+ _leave(" = T");
+ return 1;
}
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index bb47217f6a1..c048f065875 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -61,6 +61,11 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key)
return -EBADMSG;
}
+#ifdef CONFIG_AFS_FSCACHE
+ if (vnode->status.size != inode->i_size)
+ fscache_attr_changed(vnode->cache);
+#endif
+
inode->i_nlink = vnode->status.nlink;
inode->i_uid = vnode->status.owner;
inode->i_gid = 0;
@@ -149,15 +154,6 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
return inode;
}
-#ifdef AFS_CACHING_SUPPORT
- /* set up caching before reading the status, as fetch-status reads the
- * first page of symlinks to see if they're really mntpts */
- cachefs_acquire_cookie(vnode->volume->cache,
- NULL,
- vnode,
- &vnode->cache);
-#endif
-
if (!status) {
/* it's a remotely extant inode */
set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags);
@@ -183,6 +179,15 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
}
}
+ /* set up caching before mapping the status, as map-status reads the
+ * first page of symlinks to see if they're really mountpoints */
+ inode->i_size = vnode->status.size;
+#ifdef CONFIG_AFS_FSCACHE
+ vnode->cache = fscache_acquire_cookie(vnode->volume->cache,
+ &afs_vnode_cache_index_def,
+ vnode);
+#endif
+
ret = afs_inode_map_status(vnode, key);
if (ret < 0)
goto bad_inode;
@@ -196,6 +201,10 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
/* failure */
bad_inode:
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_relinquish_cookie(vnode->cache, 0);
+ vnode->cache = NULL;
+#endif
iget_failed(inode);
_leave(" = %d [bad]", ret);
return ERR_PTR(ret);
@@ -340,8 +349,8 @@ void afs_clear_inode(struct inode *inode)
ASSERT(list_empty(&vnode->writebacks));
ASSERT(!vnode->cb_promised);
-#ifdef AFS_CACHING_SUPPORT
- cachefs_relinquish_cookie(vnode->cache, 0);
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_relinquish_cookie(vnode->cache, 0);
vnode->cache = NULL;
#endif
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 67f259d99cd..106be66dafd 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -21,6 +21,7 @@
#include "afs.h"
#include "afs_vl.h"
+#include "cache.h"
#define AFS_CELL_MAX_ADDRS 15
@@ -193,8 +194,8 @@ struct afs_cell {
struct key *anonymous_key; /* anonymous user key for this cell */
struct list_head proc_link; /* /proc cell list link */
struct proc_dir_entry *proc_dir; /* /proc dir for this cell */
-#ifdef AFS_CACHING_SUPPORT
- struct cachefs_cookie *cache; /* caching cookie */
+#ifdef CONFIG_AFS_FSCACHE
+ struct fscache_cookie *cache; /* caching cookie */
#endif
/* server record management */
@@ -249,8 +250,8 @@ struct afs_vlocation {
struct list_head grave; /* link in master graveyard list */
struct list_head update; /* link in master update list */
struct afs_cell *cell; /* cell to which volume belongs */
-#ifdef AFS_CACHING_SUPPORT
- struct cachefs_cookie *cache; /* caching cookie */
+#ifdef CONFIG_AFS_FSCACHE
+ struct fscache_cookie *cache; /* caching cookie */
#endif
struct afs_cache_vlocation vldb; /* volume information DB record */
struct afs_volume *vols[3]; /* volume access record pointer (index by type) */
@@ -302,8 +303,8 @@ struct afs_volume {
atomic_t usage;
struct afs_cell *cell; /* cell to which belongs (unrefd ptr) */
struct afs_vlocation *vlocation; /* volume location */
-#ifdef AFS_CACHING_SUPPORT
- struct cachefs_cookie *cache; /* caching cookie */
+#ifdef CONFIG_AFS_FSCACHE
+ struct fscache_cookie *cache; /* caching cookie */
#endif
afs_volid_t vid; /* volume ID */
afs_voltype_t type; /* type of volume */
@@ -333,8 +334,8 @@ struct afs_vnode {
struct afs_server *server; /* server currently supplying this file */
struct afs_fid fid; /* the file identifier for this inode */
struct afs_file_status status; /* AFS status info for this file */
-#ifdef AFS_CACHING_SUPPORT
- struct cachefs_cookie *cache; /* caching cookie */
+#ifdef CONFIG_AFS_FSCACHE
+ struct fscache_cookie *cache; /* caching cookie */
#endif
struct afs_permits *permits; /* cache of permits so far obtained */
struct mutex permits_lock; /* lock for altering permits list */
@@ -428,6 +429,22 @@ struct afs_uuid {
/*****************************************************************************/
/*
+ * cache.c
+ */
+#ifdef CONFIG_AFS_FSCACHE
+extern struct fscache_netfs afs_cache_netfs;
+extern struct fscache_cookie_def afs_cell_cache_index_def;
+extern struct fscache_cookie_def afs_vlocation_cache_index_def;
+extern struct fscache_cookie_def afs_volume_cache_index_def;
+extern struct fscache_cookie_def afs_vnode_cache_index_def;
+#else
+#define afs_cell_cache_index_def (*(struct fscache_cookie_def *) NULL)
+#define afs_vlocation_cache_index_def (*(struct fscache_cookie_def *) NULL)
+#define afs_volume_cache_index_def (*(struct fscache_cookie_def *) NULL)
+#define afs_vnode_cache_index_def (*(struct fscache_cookie_def *) NULL)
+#endif
+
+/*
* callback.c
*/
extern void afs_init_callback_state(struct afs_server *);
@@ -446,9 +463,6 @@ extern void afs_callback_update_kill(void);
*/
extern struct rw_semaphore afs_proc_cells_sem;
extern struct list_head afs_proc_cells;
-#ifdef AFS_CACHING_SUPPORT
-extern struct cachefs_index_def afs_cache_cell_index_def;
-#endif
#define afs_get_cell(C) do { atomic_inc(&(C)->usage); } while(0)
extern int afs_cell_init(char *);
@@ -554,9 +568,6 @@ extern void afs_clear_inode(struct inode *);
* main.c
*/
extern struct afs_uuid afs_uuid;
-#ifdef AFS_CACHING_SUPPORT
-extern struct cachefs_netfs afs_cache_netfs;
-#endif
/*
* misc.c
@@ -637,10 +648,6 @@ extern int afs_get_MAC_address(u8 *, size_t);
/*
* vlclient.c
*/
-#ifdef AFS_CACHING_SUPPORT
-extern struct cachefs_index_def afs_vlocation_cache_index_def;
-#endif
-
extern int afs_vl_get_entry_by_name(struct in_addr *, struct key *,
const char *, struct afs_cache_vlocation *,
const struct afs_wait_mode *);
@@ -664,12 +671,6 @@ extern void afs_vlocation_purge(void);
/*
* vnode.c
*/
-#ifdef AFS_CACHING_SUPPORT
-extern struct cachefs_index_def afs_vnode_cache_index_def;
-#endif
-
-extern struct afs_timer_ops afs_vnode_cb_timed_out_ops;
-
static inline struct afs_vnode *AFS_FS_I(struct inode *inode)
{
return container_of(inode, struct afs_vnode, vfs_inode);
@@ -711,10 +712,6 @@ extern int afs_vnode_release_lock(struct afs_vnode *, struct key *);
/*
* volume.c
*/
-#ifdef AFS_CACHING_SUPPORT
-extern struct cachefs_index_def afs_volume_cache_index_def;
-#endif
-
#define afs_get_volume(V) do { atomic_inc(&(V)->usage); } while(0)
extern void afs_put_volume(struct afs_volume *);
diff --git a/fs/afs/main.c b/fs/afs/main.c
index 2d3e5d4fb9f..66d54d348c5 100644
--- a/fs/afs/main.c
+++ b/fs/afs/main.c
@@ -1,6 +1,6 @@
/* AFS client file system
*
- * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2002,5 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -29,18 +29,6 @@ static char *rootcell;
module_param(rootcell, charp, 0);
MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
-#ifdef AFS_CACHING_SUPPORT
-static struct cachefs_netfs_operations afs_cache_ops = {
- .get_page_cookie = afs_cache_get_page_cookie,
-};
-
-struct cachefs_netfs afs_cache_netfs = {
- .name = "afs",
- .version = 0,
- .ops = &afs_cache_ops,
-};
-#endif
-
struct afs_uuid afs_uuid;
/*
@@ -104,10 +92,9 @@ static int __init afs_init(void)
if (ret < 0)
return ret;
-#ifdef AFS_CACHING_SUPPORT
+#ifdef CONFIG_AFS_FSCACHE
/* we want to be able to cache */
- ret = cachefs_register_netfs(&afs_cache_netfs,
- &afs_cache_cell_index_def);
+ ret = fscache_register_netfs(&afs_cache_netfs);
if (ret < 0)
goto error_cache;
#endif
@@ -142,8 +129,8 @@ error_fs:
error_open_socket:
error_vl_update_init:
error_cell_init:
-#ifdef AFS_CACHING_SUPPORT
- cachefs_unregister_netfs(&afs_cache_netfs);
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_unregister_netfs(&afs_cache_netfs);
error_cache:
#endif
afs_callback_update_kill();
@@ -175,8 +162,8 @@ static void __exit afs_exit(void)
afs_vlocation_purge();
flush_scheduled_work();
afs_cell_purge();
-#ifdef AFS_CACHING_SUPPORT
- cachefs_unregister_netfs(&afs_cache_netfs);
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_unregister_netfs(&afs_cache_netfs);
#endif
afs_proc_cleanup();
rcu_barrier();
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index 78db4953a80..2b9e2d03a39 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -173,9 +173,9 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
if (PageError(page))
goto error;
- buf = kmap(page);
+ buf = kmap_atomic(page, KM_USER0);
memcpy(devname, buf, size);
- kunmap(page);
+ kunmap_atomic(buf, KM_USER0);
page_cache_release(page);
page = NULL;
diff --git a/fs/afs/netdevices.c b/fs/afs/netdevices.c
index 49f18942306..7ad36506c25 100644
--- a/fs/afs/netdevices.c
+++ b/fs/afs/netdevices.c
@@ -20,8 +20,7 @@ int afs_get_MAC_address(u8 *mac, size_t maclen)
struct net_device *dev;
int ret = -ENODEV;
- if (maclen != ETH_ALEN)
- BUG();
+ BUG_ON(maclen != ETH_ALEN);
rtnl_lock();
dev = __dev_getfirstbyhwtype(&init_net, ARPHRD_ETHER);
diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c
index 849fc3160cb..ec2a7431e45 100644
--- a/fs/afs/vlocation.c
+++ b/fs/afs/vlocation.c
@@ -281,9 +281,8 @@ static void afs_vlocation_apply_update(struct afs_vlocation *vl,
vl->vldb = *vldb;
-#ifdef AFS_CACHING_SUPPORT
- /* update volume entry in local cache */
- cachefs_update_cookie(vl->cache);
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_update_cookie(vl->cache);
#endif
}
@@ -304,11 +303,9 @@ static int afs_vlocation_fill_in_record(struct afs_vlocation *vl,
memset(&vldb, 0, sizeof(vldb));
/* see if we have an in-cache copy (will set vl->valid if there is) */
-#ifdef AFS_CACHING_SUPPORT
- cachefs_acquire_cookie(cell->cache,
- &afs_volume_cache_index_def,
- vlocation,
- &vl->cache);
+#ifdef CONFIG_AFS_FSCACHE
+ vl->cache = fscache_acquire_cookie(vl->cell->cache,
+ &afs_vlocation_cache_index_def, vl);
#endif
if (vl->valid) {
@@ -420,6 +417,11 @@ fill_in_record:
spin_unlock(&vl->lock);
wake_up(&vl->waitq);
+ /* update volume entry in local cache */
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_update_cookie(vl->cache);
+#endif
+
/* schedule for regular updates */
afs_vlocation_queue_for_updates(vl);
goto success;
@@ -465,7 +467,7 @@ found_in_memory:
spin_unlock(&vl->lock);
success:
- _leave(" = %p",vl);
+ _leave(" = %p", vl);
return vl;
error_abandon:
@@ -523,10 +525,9 @@ static void afs_vlocation_destroy(struct afs_vlocation *vl)
{
_enter("%p", vl);
-#ifdef AFS_CACHING_SUPPORT
- cachefs_relinquish_cookie(vl->cache, 0);
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_relinquish_cookie(vl->cache, 0);
#endif
-
afs_put_cell(vl->cell);
kfree(vl);
}
diff --git a/fs/afs/volume.c b/fs/afs/volume.c
index 8bab0e3437f..a353e69e239 100644
--- a/fs/afs/volume.c
+++ b/fs/afs/volume.c
@@ -124,13 +124,11 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params)
}
/* attach the cache and volume location */
-#ifdef AFS_CACHING_SUPPORT
- cachefs_acquire_cookie(vlocation->cache,
- &afs_vnode_cache_index_def,
- volume,
- &volume->cache);
+#ifdef CONFIG_AFS_FSCACHE
+ volume->cache = fscache_acquire_cookie(vlocation->cache,
+ &afs_volume_cache_index_def,
+ volume);
#endif
-
afs_get_vlocation(vlocation);
volume->vlocation = vlocation;
@@ -194,8 +192,8 @@ void afs_put_volume(struct afs_volume *volume)
up_write(&vlocation->cell->vl_sem);
/* finish cleaning up the volume */
-#ifdef AFS_CACHING_SUPPORT
- cachefs_relinquish_cookie(volume->cache, 0);
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_relinquish_cookie(volume->cache, 0);
#endif
afs_put_vlocation(vlocation);
diff --git a/fs/afs/write.c b/fs/afs/write.c
index 3fb36d43362..c2e7a7ff008 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -780,3 +780,24 @@ int afs_fsync(struct file *file, struct dentry *dentry, int datasync)
_leave(" = %d", ret);
return ret;
}
+
+/*
+ * notification that a previously read-only page is about to become writable
+ * - if it returns an error, the caller will deliver a bus error signal
+ */
+int afs_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+{
+ struct afs_vnode *vnode = AFS_FS_I(vma->vm_file->f_mapping->host);
+
+ _enter("{{%x:%u}},{%lx}",
+ vnode->fid.vid, vnode->fid.vnode, page->index);
+
+ /* wait for the page to be written to the cache before we allow it to
+ * be modified */
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_wait_on_page_write(vnode->cache, page);
+#endif
+
+ _leave(" = 0");
+ return 0;
+}
diff --git a/fs/befs/debug.c b/fs/befs/debug.c
index b8e304a0661..622e73775c8 100644
--- a/fs/befs/debug.c
+++ b/fs/befs/debug.c
@@ -17,6 +17,7 @@
#include <linux/spinlock.h>
#include <linux/kernel.h>
#include <linux/fs.h>
+#include <linux/slab.h>
#endif /* __KERNEL__ */
diff --git a/fs/befs/super.c b/fs/befs/super.c
index 41f2b4d0093..ca40f828f64 100644
--- a/fs/befs/super.c
+++ b/fs/befs/super.c
@@ -8,6 +8,7 @@
*/
#include <linux/fs.h>
+#include <asm/page.h> /* for PAGE_SIZE */
#include "befs.h"
#include "super.h"
diff --git a/fs/bio.c b/fs/bio.c
index a040cde7f6f..e0c9e545bbf 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1420,8 +1420,7 @@ static void bio_pair_end_2(struct bio *bi, int err)
}
/*
- * split a bio - only worry about a bio with a single page
- * in it's iovec
+ * split a bio - only worry about a bio with a single page in its iovec
*/
struct bio_pair *bio_split(struct bio *bi, int first_sectors)
{
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c
index c84ca1f5259..51bfdfc8fcd 100644
--- a/fs/btrfs/async-thread.c
+++ b/fs/btrfs/async-thread.c
@@ -20,7 +20,6 @@
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/freezer.h>
-#include <linux/ftrace.h>
#include "async-thread.h"
#define WORK_QUEUED_BIT 0
@@ -195,6 +194,9 @@ again_locked:
if (!list_empty(&worker->pending))
continue;
+ if (kthread_should_stop())
+ break;
+
/* still no more work?, sleep for real */
spin_lock_irq(&worker->lock);
set_current_state(TASK_INTERRUPTIBLE);
@@ -208,7 +210,8 @@ again_locked:
worker->working = 0;
spin_unlock_irq(&worker->lock);
- schedule();
+ if (!kthread_should_stop())
+ schedule();
}
__set_current_state(TASK_RUNNING);
}
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index dbb72412463..e5b2533b691 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1244,9 +1244,9 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
* readahead one full node of leaves, finding things that are close
* to the block in 'slot', and triggering ra on them.
*/
-static noinline void reada_for_search(struct btrfs_root *root,
- struct btrfs_path *path,
- int level, int slot, u64 objectid)
+static void reada_for_search(struct btrfs_root *root,
+ struct btrfs_path *path,
+ int level, int slot, u64 objectid)
{
struct extent_buffer *node;
struct btrfs_disk_key disk_key;
@@ -1447,6 +1447,117 @@ noinline void btrfs_unlock_up_safe(struct btrfs_path *path, int level)
}
/*
+ * helper function for btrfs_search_slot. The goal is to find a block
+ * in cache without setting the path to blocking. If we find the block
+ * we return zero and the path is unchanged.
+ *
+ * If we can't find the block, we set the path blocking and do some
+ * reada. -EAGAIN is returned and the search must be repeated.
+ */
+static int
+read_block_for_search(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, struct btrfs_path *p,
+ struct extent_buffer **eb_ret, int level, int slot,
+ struct btrfs_key *key)
+{
+ u64 blocknr;
+ u64 gen;
+ u32 blocksize;
+ struct extent_buffer *b = *eb_ret;
+ struct extent_buffer *tmp;
+
+ blocknr = btrfs_node_blockptr(b, slot);
+ gen = btrfs_node_ptr_generation(b, slot);
+ blocksize = btrfs_level_size(root, level - 1);
+
+ tmp = btrfs_find_tree_block(root, blocknr, blocksize);
+ if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
+ *eb_ret = tmp;
+ return 0;
+ }
+
+ /*
+ * reduce lock contention at high levels
+ * of the btree by dropping locks before
+ * we read.
+ */
+ btrfs_release_path(NULL, p);
+ if (tmp)
+ free_extent_buffer(tmp);
+ if (p->reada)
+ reada_for_search(root, p, level, slot, key->objectid);
+
+ tmp = read_tree_block(root, blocknr, blocksize, gen);
+ if (tmp)
+ free_extent_buffer(tmp);
+ return -EAGAIN;
+}
+
+/*
+ * helper function for btrfs_search_slot. This does all of the checks
+ * for node-level blocks and does any balancing required based on
+ * the ins_len.
+ *
+ * If no extra work was required, zero is returned. If we had to
+ * drop the path, -EAGAIN is returned and btrfs_search_slot must
+ * start over
+ */
+static int
+setup_nodes_for_search(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, struct btrfs_path *p,
+ struct extent_buffer *b, int level, int ins_len)
+{
+ int ret;
+ if ((p->search_for_split || ins_len > 0) && btrfs_header_nritems(b) >=
+ BTRFS_NODEPTRS_PER_BLOCK(root) - 3) {
+ int sret;
+
+ sret = reada_for_balance(root, p, level);
+ if (sret)
+ goto again;
+
+ btrfs_set_path_blocking(p);
+ sret = split_node(trans, root, p, level);
+ btrfs_clear_path_blocking(p, NULL);
+
+ BUG_ON(sret > 0);
+ if (sret) {
+ ret = sret;
+ goto done;
+ }
+ b = p->nodes[level];
+ } else if (ins_len < 0 && btrfs_header_nritems(b) <
+ BTRFS_NODEPTRS_PER_BLOCK(root) / 4) {
+ int sret;
+
+ sret = reada_for_balance(root, p, level);
+ if (sret)
+ goto again;
+
+ btrfs_set_path_blocking(p);
+ sret = balance_level(trans, root, p, level);
+ btrfs_clear_path_blocking(p, NULL);
+
+ if (sret) {
+ ret = sret;
+ goto done;
+ }
+ b = p->nodes[level];
+ if (!b) {
+ btrfs_release_path(NULL, p);
+ goto again;
+ }
+ BUG_ON(btrfs_header_nritems(b) == 1);
+ }
+ return 0;
+
+again:
+ ret = -EAGAIN;
+done:
+ return ret;
+}
+
+/*
* look for key in the tree. path is filled in with nodes along the way
* if key is found, we return zero and you can find the item in the leaf
* level of the path (level 0)
@@ -1464,16 +1575,11 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
ins_len, int cow)
{
struct extent_buffer *b;
- struct extent_buffer *tmp;
int slot;
int ret;
int level;
- int should_reada = p->reada;
int lowest_unlock = 1;
- int blocksize;
u8 lowest_level = 0;
- u64 blocknr;
- u64 gen;
lowest_level = p->lowest_level;
WARN_ON(lowest_level && ins_len > 0);
@@ -1502,7 +1608,11 @@ again:
if (cow) {
int wret;
- /* is a cow on this block not required */
+ /*
+ * if we don't really need to cow this block
+ * then we don't want to set the path blocking,
+ * so we test it here
+ */
if (btrfs_header_generation(b) == trans->transid &&
btrfs_header_owner(b) == root->root_key.objectid &&
!btrfs_header_flag(b, BTRFS_HEADER_FLAG_WRITTEN)) {
@@ -1557,51 +1667,15 @@ cow_done:
if (ret && slot > 0)
slot -= 1;
p->slots[level] = slot;
- if ((p->search_for_split || ins_len > 0) &&
- btrfs_header_nritems(b) >=
- BTRFS_NODEPTRS_PER_BLOCK(root) - 3) {
- int sret;
-
- sret = reada_for_balance(root, p, level);
- if (sret)
- goto again;
-
- btrfs_set_path_blocking(p);
- sret = split_node(trans, root, p, level);
- btrfs_clear_path_blocking(p, NULL);
-
- BUG_ON(sret > 0);
- if (sret) {
- ret = sret;
- goto done;
- }
- b = p->nodes[level];
- slot = p->slots[level];
- } else if (ins_len < 0 &&
- btrfs_header_nritems(b) <
- BTRFS_NODEPTRS_PER_BLOCK(root) / 4) {
- int sret;
-
- sret = reada_for_balance(root, p, level);
- if (sret)
- goto again;
-
- btrfs_set_path_blocking(p);
- sret = balance_level(trans, root, p, level);
- btrfs_clear_path_blocking(p, NULL);
+ ret = setup_nodes_for_search(trans, root, p, b, level,
+ ins_len);
+ if (ret == -EAGAIN)
+ goto again;
+ else if (ret)
+ goto done;
+ b = p->nodes[level];
+ slot = p->slots[level];
- if (sret) {
- ret = sret;
- goto done;
- }
- b = p->nodes[level];
- if (!b) {
- btrfs_release_path(NULL, p);
- goto again;
- }
- slot = p->slots[level];
- BUG_ON(btrfs_header_nritems(b) == 1);
- }
unlock_up(p, level, lowest_unlock);
/* this is only true while dropping a snapshot */
@@ -1610,44 +1684,11 @@ cow_done:
goto done;
}
- blocknr = btrfs_node_blockptr(b, slot);
- gen = btrfs_node_ptr_generation(b, slot);
- blocksize = btrfs_level_size(root, level - 1);
+ ret = read_block_for_search(trans, root, p,
+ &b, level, slot, key);
+ if (ret == -EAGAIN)
+ goto again;
- tmp = btrfs_find_tree_block(root, blocknr, blocksize);
- if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
- b = tmp;
- } else {
- /*
- * reduce lock contention at high levels
- * of the btree by dropping locks before
- * we read.
- */
- if (level > 0) {
- btrfs_release_path(NULL, p);
- if (tmp)
- free_extent_buffer(tmp);
- if (should_reada)
- reada_for_search(root, p,
- level, slot,
- key->objectid);
-
- tmp = read_tree_block(root, blocknr,
- blocksize, gen);
- if (tmp)
- free_extent_buffer(tmp);
- goto again;
- } else {
- btrfs_set_path_blocking(p);
- if (tmp)
- free_extent_buffer(tmp);
- if (should_reada)
- reada_for_search(root, p,
- level, slot,
- key->objectid);
- b = read_node_slot(root, b, slot);
- }
- }
if (!p->skip_locking) {
int lret;
@@ -2116,8 +2157,7 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
BUG_ON(!path->nodes[level]);
lower = path->nodes[level];
nritems = btrfs_header_nritems(lower);
- if (slot > nritems)
- BUG();
+ BUG_ON(slot > nritems);
if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
BUG();
if (slot != nritems) {
@@ -4086,28 +4126,44 @@ next:
int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
{
int slot;
- int level = 1;
+ int level;
struct extent_buffer *c;
- struct extent_buffer *next = NULL;
+ struct extent_buffer *next;
struct btrfs_key key;
u32 nritems;
int ret;
+ int old_spinning = path->leave_spinning;
+ int force_blocking = 0;
nritems = btrfs_header_nritems(path->nodes[0]);
if (nritems == 0)
return 1;
- btrfs_item_key_to_cpu(path->nodes[0], &key, nritems - 1);
+ /*
+ * we take the blocks in an order that upsets lockdep. Using
+ * blocking mode is the only way around it.
+ */
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ force_blocking = 1;
+#endif
+ btrfs_item_key_to_cpu(path->nodes[0], &key, nritems - 1);
+again:
+ level = 1;
+ next = NULL;
btrfs_release_path(root, path);
+
path->keep_locks = 1;
+
+ if (!force_blocking)
+ path->leave_spinning = 1;
+
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
path->keep_locks = 0;
if (ret < 0)
return ret;
- btrfs_set_path_blocking(path);
nritems = btrfs_header_nritems(path->nodes[0]);
/*
* by releasing the path above we dropped all our locks. A balance
@@ -4117,19 +4173,24 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
*/
if (nritems > 0 && path->slots[0] < nritems - 1) {
path->slots[0]++;
+ ret = 0;
goto done;
}
while (level < BTRFS_MAX_LEVEL) {
- if (!path->nodes[level])
- return 1;
+ if (!path->nodes[level]) {
+ ret = 1;
+ goto done;
+ }
slot = path->slots[level] + 1;
c = path->nodes[level];
if (slot >= btrfs_header_nritems(c)) {
level++;
- if (level == BTRFS_MAX_LEVEL)
- return 1;
+ if (level == BTRFS_MAX_LEVEL) {
+ ret = 1;
+ goto done;
+ }
continue;
}
@@ -4138,16 +4199,22 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
free_extent_buffer(next);
}
- /* the path was set to blocking above */
- if (level == 1 && (path->locks[1] || path->skip_locking) &&
- path->reada)
- reada_for_search(root, path, level, slot, 0);
+ next = c;
+ ret = read_block_for_search(NULL, root, path, &next, level,
+ slot, &key);
+ if (ret == -EAGAIN)
+ goto again;
- next = read_node_slot(root, c, slot);
if (!path->skip_locking) {
- btrfs_assert_tree_locked(c);
- btrfs_tree_lock(next);
- btrfs_set_lock_blocking(next);
+ ret = btrfs_try_spin_lock(next);
+ if (!ret) {
+ btrfs_set_path_blocking(path);
+ btrfs_tree_lock(next);
+ if (!force_blocking)
+ btrfs_clear_path_blocking(path, next);
+ }
+ if (force_blocking)
+ btrfs_set_lock_blocking(next);
}
break;
}
@@ -4157,27 +4224,42 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
c = path->nodes[level];
if (path->locks[level])
btrfs_tree_unlock(c);
+
free_extent_buffer(c);
path->nodes[level] = next;
path->slots[level] = 0;
if (!path->skip_locking)
path->locks[level] = 1;
+
if (!level)
break;
- btrfs_set_path_blocking(path);
- if (level == 1 && path->locks[1] && path->reada)
- reada_for_search(root, path, level, slot, 0);
- next = read_node_slot(root, next, 0);
+ ret = read_block_for_search(NULL, root, path, &next, level,
+ 0, &key);
+ if (ret == -EAGAIN)
+ goto again;
+
if (!path->skip_locking) {
btrfs_assert_tree_locked(path->nodes[level]);
- btrfs_tree_lock(next);
- btrfs_set_lock_blocking(next);
+ ret = btrfs_try_spin_lock(next);
+ if (!ret) {
+ btrfs_set_path_blocking(path);
+ btrfs_tree_lock(next);
+ if (!force_blocking)
+ btrfs_clear_path_blocking(path, next);
+ }
+ if (force_blocking)
+ btrfs_set_lock_blocking(next);
}
}
+ ret = 0;
done:
unlock_up(path, 0, 1);
- return 0;
+ path->leave_spinning = old_spinning;
+ if (!old_spinning)
+ btrfs_set_path_blocking(path);
+
+ return ret;
}
/*
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 9417713542a..ad96495dedc 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -143,12 +143,15 @@ static int btrfs_csum_sizes[] = { 4, 0 };
#define BTRFS_FT_MAX 9
/*
- * the key defines the order in the tree, and so it also defines (optimal)
- * block layout. objectid corresonds to the inode number. The flags
- * tells us things about the object, and is a kind of stream selector.
- * so for a given inode, keys with flags of 1 might refer to the inode
- * data, flags of 2 may point to file data in the btree and flags == 3
- * may point to extents.
+ * The key defines the order in the tree, and so it also defines (optimal)
+ * block layout.
+ *
+ * objectid corresponds to the inode number.
+ *
+ * type tells us things about the object, and is a kind of stream selector.
+ * so for a given inode, keys with type of 1 might refer to the inode data,
+ * type of 2 may point to file data in the btree and type == 3 may point to
+ * extents.
*
* offset is the starting byte offset for this key in the stream.
*
@@ -200,7 +203,7 @@ struct btrfs_dev_item {
/*
* starting byte of this partition on the device,
- * to allowr for stripe alignment in the future
+ * to allow for stripe alignment in the future
*/
__le64 start_offset;
@@ -633,18 +636,35 @@ struct btrfs_space_info {
struct rw_semaphore groups_sem;
};
-struct btrfs_free_space {
- struct rb_node bytes_index;
- struct rb_node offset_index;
- u64 offset;
- u64 bytes;
+/*
+ * free clusters are used to claim free space in relatively large chunks,
+ * allowing us to do less seeky writes. They are used for all metadata
+ * allocations and data allocations in ssd mode.
+ */
+struct btrfs_free_cluster {
+ spinlock_t lock;
+ spinlock_t refill_lock;
+ struct rb_root root;
+
+ /* largest extent in this cluster */
+ u64 max_size;
+
+ /* first extent starting offset */
+ u64 window_start;
+
+ struct btrfs_block_group_cache *block_group;
+ /*
+ * when a cluster is allocated from a block group, we put the
+ * cluster onto a list in the block group so that it can
+ * be freed before the block group is freed.
+ */
+ struct list_head block_group_list;
};
struct btrfs_block_group_cache {
struct btrfs_key key;
struct btrfs_block_group_item item;
spinlock_t lock;
- struct mutex alloc_mutex;
struct mutex cache_mutex;
u64 pinned;
u64 reserved;
@@ -656,6 +676,7 @@ struct btrfs_block_group_cache {
struct btrfs_space_info *space_info;
/* free space cache stuff */
+ spinlock_t tree_lock;
struct rb_root free_space_bytes;
struct rb_root free_space_offset;
@@ -667,6 +688,11 @@ struct btrfs_block_group_cache {
/* usage count */
atomic_t count;
+
+ /* List of struct btrfs_free_clusters for this block group.
+ * Today it will only have one thing on it, but that may change
+ */
+ struct list_head cluster_list;
};
struct btrfs_leaf_ref_tree {
@@ -728,7 +754,6 @@ struct btrfs_fs_info {
struct mutex tree_log_mutex;
struct mutex transaction_kthread_mutex;
struct mutex cleaner_mutex;
- struct mutex pinned_mutex;
struct mutex chunk_mutex;
struct mutex drop_mutex;
struct mutex volume_mutex;
@@ -839,8 +864,12 @@ struct btrfs_fs_info {
spinlock_t delalloc_lock;
spinlock_t new_trans_lock;
u64 delalloc_bytes;
- u64 last_alloc;
- u64 last_data_alloc;
+
+ /* data_alloc_cluster is only used in ssd mode */
+ struct btrfs_free_cluster data_alloc_cluster;
+
+ /* all metadata allocations go through this cluster */
+ struct btrfs_free_cluster meta_alloc_cluster;
spinlock_t ref_cache_lock;
u64 total_ref_cache_size;
@@ -932,7 +961,6 @@ struct btrfs_root {
};
/*
-
* inode items have the data typically returned from stat and store other
* info about object characteristics. There is one for every file and dir in
* the FS
@@ -963,7 +991,7 @@ struct btrfs_root {
#define BTRFS_EXTENT_CSUM_KEY 128
/*
- * root items point to tree roots. There are typically in the root
+ * root items point to tree roots. They are typically in the root
* tree used by the super block to find all the other trees
*/
#define BTRFS_ROOT_ITEM_KEY 132
@@ -1010,6 +1038,8 @@ struct btrfs_root {
#define BTRFS_MOUNT_SSD (1 << 3)
#define BTRFS_MOUNT_DEGRADED (1 << 4)
#define BTRFS_MOUNT_COMPRESS (1 << 5)
+#define BTRFS_MOUNT_NOTREELOG (1 << 6)
+#define BTRFS_MOUNT_FLUSHONCOMMIT (1 << 7)
#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
@@ -1748,6 +1778,7 @@ static inline struct dentry *fdentry(struct file *file)
}
/* extent-tree.c */
+void btrfs_put_block_group(struct btrfs_block_group_cache *cache);
int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
struct btrfs_root *root, unsigned long count);
int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len);
@@ -2174,21 +2205,4 @@ int btrfs_check_acl(struct inode *inode, int mask);
int btrfs_init_acl(struct inode *inode, struct inode *dir);
int btrfs_acl_chmod(struct inode *inode);
-/* free-space-cache.c */
-int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
- u64 bytenr, u64 size);
-int btrfs_add_free_space_lock(struct btrfs_block_group_cache *block_group,
- u64 offset, u64 bytes);
-int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
- u64 bytenr, u64 size);
-int btrfs_remove_free_space_lock(struct btrfs_block_group_cache *block_group,
- u64 offset, u64 bytes);
-void btrfs_remove_free_space_cache(struct btrfs_block_group_cache
- *block_group);
-struct btrfs_free_space *btrfs_find_free_space(struct btrfs_block_group_cache
- *block_group, u64 offset,
- u64 bytes);
-void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
- u64 bytes);
-u64 btrfs_block_group_free_space(struct btrfs_block_group_cache *block_group);
#endif
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index cbf7dc8ae3e..d6c01c096a4 100644
--- a/fs/btrfs/delayed-ref.c
+++ b/fs/btrfs/delayed-ref.c
@@ -18,7 +18,6 @@
#include <linux/sched.h>
#include <linux/sort.h>
-#include <linux/ftrace.h>
#include "ctree.h"
#include "delayed-ref.h"
#include "transaction.h"
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 92d73929d38..92caa8035f3 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -38,6 +38,7 @@
#include "locking.h"
#include "ref-cache.h"
#include "tree-log.h"
+#include "free-space-cache.h"
static struct extent_io_ops btree_extent_io_ops;
static void end_workqueue_fn(struct btrfs_work *work);
@@ -1412,8 +1413,6 @@ static int bio_ready_for_csum(struct bio *bio)
ret = extent_range_uptodate(io_tree, start + length,
start + buf_len - 1);
- if (ret == 1)
- return ret;
return ret;
}
@@ -1647,12 +1646,15 @@ struct btrfs_root *open_ctree(struct super_block *sb,
mutex_init(&fs_info->ordered_operations_mutex);
mutex_init(&fs_info->tree_log_mutex);
mutex_init(&fs_info->drop_mutex);
- mutex_init(&fs_info->pinned_mutex);
mutex_init(&fs_info->chunk_mutex);
mutex_init(&fs_info->transaction_kthread_mutex);
mutex_init(&fs_info->cleaner_mutex);
mutex_init(&fs_info->volume_mutex);
mutex_init(&fs_info->tree_reloc_mutex);
+
+ btrfs_init_free_cluster(&fs_info->meta_alloc_cluster);
+ btrfs_init_free_cluster(&fs_info->data_alloc_cluster);
+
init_waitqueue_head(&fs_info->transaction_throttle);
init_waitqueue_head(&fs_info->transaction_wait);
init_waitqueue_head(&fs_info->async_submit_wait);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index f5e7cae63d8..178df4c67de 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -31,6 +31,7 @@
#include "volumes.h"
#include "locking.h"
#include "ref-cache.h"
+#include "free-space-cache.h"
#define PENDING_EXTENT_INSERT 0
#define PENDING_EXTENT_DELETE 1
@@ -166,7 +167,6 @@ static int add_new_free_space(struct btrfs_block_group_cache *block_group,
u64 extent_start, extent_end, size;
int ret;
- mutex_lock(&info->pinned_mutex);
while (start < end) {
ret = find_first_extent_bit(&info->pinned_extents, start,
&extent_start, &extent_end,
@@ -192,7 +192,6 @@ static int add_new_free_space(struct btrfs_block_group_cache *block_group,
ret = btrfs_add_free_space(block_group, start, size);
BUG_ON(ret);
}
- mutex_unlock(&info->pinned_mutex);
return 0;
}
@@ -291,8 +290,8 @@ next:
block_group->key.objectid +
block_group->key.offset);
- remove_sb_from_cache(root, block_group);
block_group->cached = 1;
+ remove_sb_from_cache(root, block_group);
ret = 0;
err:
btrfs_free_path(path);
@@ -326,7 +325,7 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(
return cache;
}
-static inline void put_block_group(struct btrfs_block_group_cache *cache)
+void btrfs_put_block_group(struct btrfs_block_group_cache *cache)
{
if (atomic_dec_and_test(&cache->count))
kfree(cache);
@@ -399,12 +398,12 @@ again:
div_factor(cache->key.offset, factor)) {
group_start = cache->key.objectid;
spin_unlock(&cache->lock);
- put_block_group(cache);
+ btrfs_put_block_group(cache);
goto found;
}
}
spin_unlock(&cache->lock);
- put_block_group(cache);
+ btrfs_put_block_group(cache);
cond_resched();
}
if (!wrapped) {
@@ -1594,7 +1593,7 @@ int btrfs_extent_readonly(struct btrfs_root *root, u64 bytenr)
if (!block_group || block_group->ro)
readonly = 1;
if (block_group)
- put_block_group(block_group);
+ btrfs_put_block_group(block_group);
return readonly;
}
@@ -2018,7 +2017,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
WARN_ON(ret);
}
}
- put_block_group(cache);
+ btrfs_put_block_group(cache);
total -= num_bytes;
bytenr += num_bytes;
}
@@ -2035,7 +2034,7 @@ static u64 first_logical_byte(struct btrfs_root *root, u64 search_start)
return 0;
bytenr = cache->key.objectid;
- put_block_group(cache);
+ btrfs_put_block_group(cache);
return bytenr;
}
@@ -2047,7 +2046,6 @@ int btrfs_update_pinned_extents(struct btrfs_root *root,
struct btrfs_block_group_cache *cache;
struct btrfs_fs_info *fs_info = root->fs_info;
- WARN_ON(!mutex_is_locked(&root->fs_info->pinned_mutex));
if (pin) {
set_extent_dirty(&fs_info->pinned_extents,
bytenr, bytenr + num - 1, GFP_NOFS);
@@ -2055,7 +2053,6 @@ int btrfs_update_pinned_extents(struct btrfs_root *root,
clear_extent_dirty(&fs_info->pinned_extents,
bytenr, bytenr + num - 1, GFP_NOFS);
}
- mutex_unlock(&root->fs_info->pinned_mutex);
while (num > 0) {
cache = btrfs_lookup_block_group(fs_info, bytenr);
@@ -2081,7 +2078,7 @@ int btrfs_update_pinned_extents(struct btrfs_root *root,
if (cache->cached)
btrfs_add_free_space(cache, bytenr, len);
}
- put_block_group(cache);
+ btrfs_put_block_group(cache);
bytenr += len;
num -= len;
}
@@ -2112,7 +2109,7 @@ static int update_reserved_extents(struct btrfs_root *root,
}
spin_unlock(&cache->lock);
spin_unlock(&cache->space_info->lock);
- put_block_group(cache);
+ btrfs_put_block_group(cache);
bytenr += len;
num -= len;
}
@@ -2127,7 +2124,6 @@ int btrfs_copy_pinned(struct btrfs_root *root, struct extent_io_tree *copy)
struct extent_io_tree *pinned_extents = &root->fs_info->pinned_extents;
int ret;
- mutex_lock(&root->fs_info->pinned_mutex);
while (1) {
ret = find_first_extent_bit(pinned_extents, last,
&start, &end, EXTENT_DIRTY);
@@ -2136,7 +2132,6 @@ int btrfs_copy_pinned(struct btrfs_root *root, struct extent_io_tree *copy)
set_extent_dirty(copy, start, end, GFP_NOFS);
last = end + 1;
}
- mutex_unlock(&root->fs_info->pinned_mutex);
return 0;
}
@@ -2149,7 +2144,6 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
int ret;
while (1) {
- mutex_lock(&root->fs_info->pinned_mutex);
ret = find_first_extent_bit(unpin, 0, &start, &end,
EXTENT_DIRTY);
if (ret)
@@ -2163,7 +2157,6 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
cond_resched();
}
- mutex_unlock(&root->fs_info->pinned_mutex);
return ret;
}
@@ -2205,7 +2198,6 @@ static int pin_down_bytes(struct btrfs_trans_handle *trans,
free_extent_buffer(buf);
pinit:
btrfs_set_path_blocking(path);
- mutex_lock(&root->fs_info->pinned_mutex);
/* unlocks the pinned mutex */
btrfs_update_pinned_extents(root, bytenr, num_bytes, 1);
@@ -2511,8 +2503,6 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans,
*/
if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID &&
owner_objectid < BTRFS_FIRST_FREE_OBJECTID) {
- mutex_lock(&root->fs_info->pinned_mutex);
-
/* unlocks the pinned mutex */
btrfs_update_pinned_extents(root, bytenr, num_bytes, 1);
update_reserved_extents(root, bytenr, num_bytes, 0);
@@ -2554,228 +2544,237 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
{
int ret = 0;
struct btrfs_root *root = orig_root->fs_info->extent_root;
- u64 total_needed = num_bytes;
- u64 *last_ptr = NULL;
- u64 last_wanted = 0;
+ struct btrfs_free_cluster *last_ptr = NULL;
struct btrfs_block_group_cache *block_group = NULL;
- int chunk_alloc_done = 0;
int empty_cluster = 2 * 1024 * 1024;
int allowed_chunk_alloc = 0;
- struct list_head *head = NULL, *cur = NULL;
- int loop = 0;
- int extra_loop = 0;
struct btrfs_space_info *space_info;
+ int last_ptr_loop = 0;
+ int loop = 0;
WARN_ON(num_bytes < root->sectorsize);
btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
ins->objectid = 0;
ins->offset = 0;
+ space_info = __find_space_info(root->fs_info, data);
+
if (orig_root->ref_cows || empty_size)
allowed_chunk_alloc = 1;
if (data & BTRFS_BLOCK_GROUP_METADATA) {
- last_ptr = &root->fs_info->last_alloc;
+ last_ptr = &root->fs_info->meta_alloc_cluster;
if (!btrfs_test_opt(root, SSD))
empty_cluster = 64 * 1024;
}
- if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD))
- last_ptr = &root->fs_info->last_data_alloc;
+ if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) {
+ last_ptr = &root->fs_info->data_alloc_cluster;
+ }
if (last_ptr) {
- if (*last_ptr) {
- hint_byte = *last_ptr;
- last_wanted = *last_ptr;
- } else
- empty_size += empty_cluster;
- } else {
- empty_cluster = 0;
+ spin_lock(&last_ptr->lock);
+ if (last_ptr->block_group)
+ hint_byte = last_ptr->window_start;
+ spin_unlock(&last_ptr->lock);
}
+
search_start = max(search_start, first_logical_byte(root, 0));
search_start = max(search_start, hint_byte);
- if (last_wanted && search_start != last_wanted) {
- last_wanted = 0;
- empty_size += empty_cluster;
+ if (!last_ptr) {
+ empty_cluster = 0;
+ loop = 1;
}
- total_needed += empty_size;
- block_group = btrfs_lookup_block_group(root->fs_info, search_start);
- if (!block_group)
- block_group = btrfs_lookup_first_block_group(root->fs_info,
- search_start);
- space_info = __find_space_info(root->fs_info, data);
+ if (search_start == hint_byte) {
+ block_group = btrfs_lookup_block_group(root->fs_info,
+ search_start);
+ if (block_group && block_group_bits(block_group, data)) {
+ down_read(&space_info->groups_sem);
+ goto have_block_group;
+ } else if (block_group) {
+ btrfs_put_block_group(block_group);
+ }
+ }
+search:
down_read(&space_info->groups_sem);
- while (1) {
- struct btrfs_free_space *free_space;
- /*
- * the only way this happens if our hint points to a block
- * group thats not of the proper type, while looping this
- * should never happen
- */
- if (empty_size)
- extra_loop = 1;
+ list_for_each_entry(block_group, &space_info->block_groups, list) {
+ u64 offset;
- if (!block_group)
- goto new_group_no_lock;
+ atomic_inc(&block_group->count);
+ search_start = block_group->key.objectid;
+have_block_group:
if (unlikely(!block_group->cached)) {
mutex_lock(&block_group->cache_mutex);
ret = cache_block_group(root, block_group);
mutex_unlock(&block_group->cache_mutex);
- if (ret)
+ if (ret) {
+ btrfs_put_block_group(block_group);
break;
+ }
}
- mutex_lock(&block_group->alloc_mutex);
- if (unlikely(!block_group_bits(block_group, data)))
- goto new_group;
-
if (unlikely(block_group->ro))
- goto new_group;
+ goto loop;
- free_space = btrfs_find_free_space(block_group, search_start,
- total_needed);
- if (free_space) {
- u64 start = block_group->key.objectid;
- u64 end = block_group->key.objectid +
- block_group->key.offset;
+ if (last_ptr) {
+ /*
+ * the refill lock keeps out other
+ * people trying to start a new cluster
+ */
+ spin_lock(&last_ptr->refill_lock);
+ offset = btrfs_alloc_from_cluster(block_group, last_ptr,
+ num_bytes, search_start);
+ if (offset) {
+ /* we have a block, we're done */
+ spin_unlock(&last_ptr->refill_lock);
+ goto checks;
+ }
- search_start = stripe_align(root, free_space->offset);
+ spin_lock(&last_ptr->lock);
+ /*
+ * whoops, this cluster doesn't actually point to
+ * this block group. Get a ref on the block
+ * group is does point to and try again
+ */
+ if (!last_ptr_loop && last_ptr->block_group &&
+ last_ptr->block_group != block_group) {
+
+ btrfs_put_block_group(block_group);
+ block_group = last_ptr->block_group;
+ atomic_inc(&block_group->count);
+ spin_unlock(&last_ptr->lock);
+ spin_unlock(&last_ptr->refill_lock);
+
+ last_ptr_loop = 1;
+ search_start = block_group->key.objectid;
+ goto have_block_group;
+ }
+ spin_unlock(&last_ptr->lock);
- /* move on to the next group */
- if (search_start + num_bytes >= search_end)
- goto new_group;
+ /*
+ * this cluster didn't work out, free it and
+ * start over
+ */
+ btrfs_return_cluster_to_free_space(NULL, last_ptr);
- /* move on to the next group */
- if (search_start + num_bytes > end)
- goto new_group;
+ last_ptr_loop = 0;
- if (last_wanted && search_start != last_wanted) {
- total_needed += empty_cluster;
- empty_size += empty_cluster;
- last_wanted = 0;
+ /* allocate a cluster in this block group */
+ ret = btrfs_find_space_cluster(trans,
+ block_group, last_ptr,
+ offset, num_bytes,
+ empty_cluster + empty_size);
+ if (ret == 0) {
/*
- * if search_start is still in this block group
- * then we just re-search this block group
+ * now pull our allocation out of this
+ * cluster
*/
- if (search_start >= start &&
- search_start < end) {
- mutex_unlock(&block_group->alloc_mutex);
- continue;
+ offset = btrfs_alloc_from_cluster(block_group,
+ last_ptr, num_bytes,
+ search_start);
+ if (offset) {
+ /* we found one, proceed */
+ spin_unlock(&last_ptr->refill_lock);
+ goto checks;
}
-
- /* else we go to the next block group */
- goto new_group;
}
-
- if (exclude_nr > 0 &&
- (search_start + num_bytes > exclude_start &&
- search_start < exclude_start + exclude_nr)) {
- search_start = exclude_start + exclude_nr;
- /*
- * if search_start is still in this block group
- * then we just re-search this block group
- */
- if (search_start >= start &&
- search_start < end) {
- mutex_unlock(&block_group->alloc_mutex);
- last_wanted = 0;
- continue;
- }
-
- /* else we go to the next block group */
- goto new_group;
+ /*
+ * at this point we either didn't find a cluster
+ * or we weren't able to allocate a block from our
+ * cluster. Free the cluster we've been trying
+ * to use, and go to the next block group
+ */
+ if (loop < 2) {
+ btrfs_return_cluster_to_free_space(NULL,
+ last_ptr);
+ spin_unlock(&last_ptr->refill_lock);
+ goto loop;
}
+ spin_unlock(&last_ptr->refill_lock);
+ }
- ins->objectid = search_start;
- ins->offset = num_bytes;
+ offset = btrfs_find_space_for_alloc(block_group, search_start,
+ num_bytes, empty_size);
+ if (!offset)
+ goto loop;
+checks:
+ search_start = stripe_align(root, offset);
+
+ /* move on to the next group */
+ if (search_start + num_bytes >= search_end) {
+ btrfs_add_free_space(block_group, offset, num_bytes);
+ goto loop;
+ }
- btrfs_remove_free_space_lock(block_group, search_start,
- num_bytes);
- /* we are all good, lets return */
- mutex_unlock(&block_group->alloc_mutex);
- break;
+ /* move on to the next group */
+ if (search_start + num_bytes >
+ block_group->key.objectid + block_group->key.offset) {
+ btrfs_add_free_space(block_group, offset, num_bytes);
+ goto loop;
}
-new_group:
- mutex_unlock(&block_group->alloc_mutex);
- put_block_group(block_group);
- block_group = NULL;
-new_group_no_lock:
- /* don't try to compare new allocations against the
- * last allocation any more
- */
- last_wanted = 0;
- /*
- * Here's how this works.
- * loop == 0: we were searching a block group via a hint
- * and didn't find anything, so we start at
- * the head of the block groups and keep searching
- * loop == 1: we're searching through all of the block groups
- * if we hit the head again we have searched
- * all of the block groups for this space and we
- * need to try and allocate, if we cant error out.
- * loop == 2: we allocated more space and are looping through
- * all of the block groups again.
- */
- if (loop == 0) {
- head = &space_info->block_groups;
- cur = head->next;
- loop++;
- } else if (loop == 1 && cur == head) {
- int keep_going;
-
- /* at this point we give up on the empty_size
- * allocations and just try to allocate the min
- * space.
- *
- * The extra_loop field was set if an empty_size
- * allocation was attempted above, and if this
- * is try we need to try the loop again without
- * the additional empty_size.
+ if (exclude_nr > 0 &&
+ (search_start + num_bytes > exclude_start &&
+ search_start < exclude_start + exclude_nr)) {
+ search_start = exclude_start + exclude_nr;
+
+ btrfs_add_free_space(block_group, offset, num_bytes);
+ /*
+ * if search_start is still in this block group
+ * then we just re-search this block group
*/
- total_needed -= empty_size;
- empty_size = 0;
- keep_going = extra_loop;
- loop++;
+ if (search_start >= block_group->key.objectid &&
+ search_start < (block_group->key.objectid +
+ block_group->key.offset))
+ goto have_block_group;
+ goto loop;
+ }
- if (allowed_chunk_alloc && !chunk_alloc_done) {
- up_read(&space_info->groups_sem);
- ret = do_chunk_alloc(trans, root, num_bytes +
- 2 * 1024 * 1024, data, 1);
- down_read(&space_info->groups_sem);
- if (ret < 0)
- goto loop_check;
- head = &space_info->block_groups;
- /*
- * we've allocated a new chunk, keep
- * trying
- */
- keep_going = 1;
- chunk_alloc_done = 1;
- } else if (!allowed_chunk_alloc) {
- space_info->force_alloc = 1;
- }
-loop_check:
- if (keep_going) {
- cur = head->next;
- extra_loop = 0;
- } else {
- break;
- }
- } else if (cur == head) {
- break;
+ ins->objectid = search_start;
+ ins->offset = num_bytes;
+
+ if (offset < search_start)
+ btrfs_add_free_space(block_group, offset,
+ search_start - offset);
+ BUG_ON(offset > search_start);
+
+ /* we are all good, lets return */
+ break;
+loop:
+ btrfs_put_block_group(block_group);
+ }
+ up_read(&space_info->groups_sem);
+
+ /* loop == 0, try to find a clustered alloc in every block group
+ * loop == 1, try again after forcing a chunk allocation
+ * loop == 2, set empty_size and empty_cluster to 0 and try again
+ */
+ if (!ins->objectid && loop < 3 &&
+ (empty_size || empty_cluster || allowed_chunk_alloc)) {
+ if (loop >= 2) {
+ empty_size = 0;
+ empty_cluster = 0;
}
- block_group = list_entry(cur, struct btrfs_block_group_cache,
- list);
- atomic_inc(&block_group->count);
+ if (allowed_chunk_alloc) {
+ ret = do_chunk_alloc(trans, root, num_bytes +
+ 2 * 1024 * 1024, data, 1);
+ allowed_chunk_alloc = 0;
+ } else {
+ space_info->force_alloc = 1;
+ }
- search_start = block_group->key.objectid;
- cur = cur->next;
+ if (loop < 3) {
+ loop++;
+ goto search;
+ }
+ ret = -ENOSPC;
+ } else if (!ins->objectid) {
+ ret = -ENOSPC;
}
/* we found what we needed */
@@ -2783,21 +2782,10 @@ loop_check:
if (!(data & BTRFS_BLOCK_GROUP_DATA))
trans->block_group = block_group->key.objectid;
- if (last_ptr)
- *last_ptr = ins->objectid + ins->offset;
+ btrfs_put_block_group(block_group);
ret = 0;
- } else if (!ret) {
- printk(KERN_ERR "btrfs searching for %llu bytes, "
- "num_bytes %llu, loop %d, allowed_alloc %d\n",
- (unsigned long long)total_needed,
- (unsigned long long)num_bytes,
- loop, allowed_chunk_alloc);
- ret = -ENOSPC;
}
- if (block_group)
- put_block_group(block_group);
- up_read(&space_info->groups_sem);
return ret;
}
@@ -2902,7 +2890,7 @@ int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len)
ret = btrfs_discard_extent(root, start, len);
btrfs_add_free_space(cache, start, len);
- put_block_group(cache);
+ btrfs_put_block_group(cache);
update_reserved_extents(root, start, len, 0);
return ret;
@@ -3040,7 +3028,7 @@ int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans,
ret = btrfs_remove_free_space(block_group, ins->objectid,
ins->offset);
BUG_ON(ret);
- put_block_group(block_group);
+ btrfs_put_block_group(block_group);
ret = __btrfs_alloc_reserved_extent(trans, root, parent, root_objectid,
ref_generation, owner, ins, 1);
return ret;
@@ -5729,7 +5717,7 @@ next:
WARN_ON(block_group->reserved > 0);
WARN_ON(btrfs_block_group_used(&block_group->item) > 0);
spin_unlock(&block_group->lock);
- put_block_group(block_group);
+ btrfs_put_block_group(block_group);
ret = 0;
out:
btrfs_free_path(path);
@@ -5856,9 +5844,10 @@ int btrfs_read_block_groups(struct btrfs_root *root)
atomic_set(&cache->count, 1);
spin_lock_init(&cache->lock);
- mutex_init(&cache->alloc_mutex);
+ spin_lock_init(&cache->tree_lock);
mutex_init(&cache->cache_mutex);
INIT_LIST_HEAD(&cache->list);
+ INIT_LIST_HEAD(&cache->cluster_list);
read_extent_buffer(leaf, &cache->item,
btrfs_item_ptr_offset(leaf, path->slots[0]),
sizeof(cache->item));
@@ -5912,9 +5901,10 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
atomic_set(&cache->count, 1);
spin_lock_init(&cache->lock);
- mutex_init(&cache->alloc_mutex);
+ spin_lock_init(&cache->tree_lock);
mutex_init(&cache->cache_mutex);
INIT_LIST_HEAD(&cache->list);
+ INIT_LIST_HEAD(&cache->cluster_list);
btrfs_set_block_group_used(&cache->item, bytes_used);
btrfs_set_block_group_chunk_objectid(&cache->item, chunk_objectid);
@@ -5974,8 +5964,8 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
spin_unlock(&block_group->space_info->lock);
block_group->space_info->full = 0;
- put_block_group(block_group);
- put_block_group(block_group);
+ btrfs_put_block_group(block_group);
+ btrfs_put_block_group(block_group);
ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
if (ret > 0)
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 08085af089e..eb2bee8b7fb 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2884,25 +2884,19 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
disko = 0;
flags = 0;
- switch (em->block_start) {
- case EXTENT_MAP_LAST_BYTE:
+ if (em->block_start == EXTENT_MAP_LAST_BYTE) {
end = 1;
flags |= FIEMAP_EXTENT_LAST;
- break;
- case EXTENT_MAP_HOLE:
+ } else if (em->block_start == EXTENT_MAP_HOLE) {
flags |= FIEMAP_EXTENT_UNWRITTEN;
- break;
- case EXTENT_MAP_INLINE:
+ } else if (em->block_start == EXTENT_MAP_INLINE) {
flags |= (FIEMAP_EXTENT_DATA_INLINE |
FIEMAP_EXTENT_NOT_ALIGNED);
- break;
- case EXTENT_MAP_DELALLOC:
+ } else if (em->block_start == EXTENT_MAP_DELALLOC) {
flags |= (FIEMAP_EXTENT_DELALLOC |
FIEMAP_EXTENT_UNKNOWN);
- break;
- default:
+ } else {
disko = em->block_start;
- break;
}
if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags))
flags |= FIEMAP_EXTENT_ENCODED;
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 50da69da20c..b187917b36f 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -234,7 +234,6 @@ int add_extent_mapping(struct extent_map_tree *tree,
rb = tree_insert(&tree->map, em->start, &em->rb_node);
if (rb) {
ret = -EEXIST;
- free_extent_map(merge);
goto out;
}
atomic_inc(&em->refs);
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index d1e5f0e84c5..768b9523662 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -18,6 +18,15 @@
#include <linux/sched.h>
#include "ctree.h"
+#include "free-space-cache.h"
+#include "transaction.h"
+
+struct btrfs_free_space {
+ struct rb_node bytes_index;
+ struct rb_node offset_index;
+ u64 offset;
+ u64 bytes;
+};
static int tree_insert_offset(struct rb_root *root, u64 offset,
struct rb_node *node)
@@ -68,14 +77,24 @@ static int tree_insert_bytes(struct rb_root *root, u64 bytes,
}
/*
- * searches the tree for the given offset. If contains is set we will return
- * the free space that contains the given offset. If contains is not set we
- * will return the free space that starts at or after the given offset and is
- * at least bytes long.
+ * searches the tree for the given offset.
+ *
+ * fuzzy == 1: this is used for allocations where we are given a hint of where
+ * to look for free space. Because the hint may not be completely on an offset
+ * mark, or the hint may no longer point to free space we need to fudge our
+ * results a bit. So we look for free space starting at or after offset with at
+ * least bytes size. We prefer to find as close to the given offset as we can.
+ * Also if the offset is within a free space range, then we will return the free
+ * space that contains the given offset, which means we can return a free space
+ * chunk with an offset before the provided offset.
+ *
+ * fuzzy == 0: this is just a normal tree search. Give us the free space that
+ * starts at the given offset which is at least bytes size, and if its not there
+ * return NULL.
*/
static struct btrfs_free_space *tree_search_offset(struct rb_root *root,
u64 offset, u64 bytes,
- int contains)
+ int fuzzy)
{
struct rb_node *n = root->rb_node;
struct btrfs_free_space *entry, *ret = NULL;
@@ -84,13 +103,14 @@ static struct btrfs_free_space *tree_search_offset(struct rb_root *root,
entry = rb_entry(n, struct btrfs_free_space, offset_index);
if (offset < entry->offset) {
- if (!contains &&
+ if (fuzzy &&
(!ret || entry->offset < ret->offset) &&
(bytes <= entry->bytes))
ret = entry;
n = n->rb_left;
} else if (offset > entry->offset) {
- if ((entry->offset + entry->bytes - 1) >= offset &&
+ if (fuzzy &&
+ (entry->offset + entry->bytes - 1) >= offset &&
bytes <= entry->bytes) {
ret = entry;
break;
@@ -171,6 +191,7 @@ static int link_free_space(struct btrfs_block_group_cache *block_group,
int ret = 0;
+ BUG_ON(!info->bytes);
ret = tree_insert_offset(&block_group->free_space_offset, info->offset,
&info->offset_index);
if (ret)
@@ -184,108 +205,70 @@ static int link_free_space(struct btrfs_block_group_cache *block_group,
return ret;
}
-static int __btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
- u64 offset, u64 bytes)
+int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
+ u64 offset, u64 bytes)
{
struct btrfs_free_space *right_info;
struct btrfs_free_space *left_info;
struct btrfs_free_space *info = NULL;
- struct btrfs_free_space *alloc_info;
int ret = 0;
- alloc_info = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS);
- if (!alloc_info)
+ info = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS);
+ if (!info)
return -ENOMEM;
+ info->offset = offset;
+ info->bytes = bytes;
+
+ spin_lock(&block_group->tree_lock);
+
/*
* first we want to see if there is free space adjacent to the range we
* are adding, if there is remove that struct and add a new one to
* cover the entire range
*/
right_info = tree_search_offset(&block_group->free_space_offset,
- offset+bytes, 0, 1);
+ offset+bytes, 0, 0);
left_info = tree_search_offset(&block_group->free_space_offset,
offset-1, 0, 1);
- if (right_info && right_info->offset == offset+bytes) {
+ if (right_info) {
unlink_free_space(block_group, right_info);
- info = right_info;
- info->offset = offset;
- info->bytes += bytes;
- } else if (right_info && right_info->offset != offset+bytes) {
- printk(KERN_ERR "btrfs adding space in the middle of an "
- "existing free space area. existing: "
- "offset=%llu, bytes=%llu. new: offset=%llu, "
- "bytes=%llu\n", (unsigned long long)right_info->offset,
- (unsigned long long)right_info->bytes,
- (unsigned long long)offset,
- (unsigned long long)bytes);
- BUG();
+ info->bytes += right_info->bytes;
+ kfree(right_info);
}
- if (left_info) {
+ if (left_info && left_info->offset + left_info->bytes == offset) {
unlink_free_space(block_group, left_info);
-
- if (unlikely((left_info->offset + left_info->bytes) !=
- offset)) {
- printk(KERN_ERR "btrfs free space to the left "
- "of new free space isn't "
- "quite right. existing: offset=%llu, "
- "bytes=%llu. new: offset=%llu, bytes=%llu\n",
- (unsigned long long)left_info->offset,
- (unsigned long long)left_info->bytes,
- (unsigned long long)offset,
- (unsigned long long)bytes);
- BUG();
- }
-
- if (info) {
- info->offset = left_info->offset;
- info->bytes += left_info->bytes;
- kfree(left_info);
- } else {
- info = left_info;
- info->bytes += bytes;
- }
+ info->offset = left_info->offset;
+ info->bytes += left_info->bytes;
+ kfree(left_info);
}
- if (info) {
- ret = link_free_space(block_group, info);
- if (!ret)
- info = NULL;
- goto out;
- }
-
- info = alloc_info;
- alloc_info = NULL;
- info->offset = offset;
- info->bytes = bytes;
-
ret = link_free_space(block_group, info);
if (ret)
kfree(info);
-out:
+
+ spin_unlock(&block_group->tree_lock);
+
if (ret) {
printk(KERN_ERR "btrfs: unable to add free space :%d\n", ret);
- if (ret == -EEXIST)
- BUG();
+ BUG_ON(ret == -EEXIST);
}
- kfree(alloc_info);
-
return ret;
}
-static int
-__btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
- u64 offset, u64 bytes)
+int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
+ u64 offset, u64 bytes)
{
struct btrfs_free_space *info;
int ret = 0;
+ spin_lock(&block_group->tree_lock);
+
info = tree_search_offset(&block_group->free_space_offset, offset, 0,
1);
-
if (info && info->offset == offset) {
if (info->bytes < bytes) {
printk(KERN_ERR "Found free space at %llu, size %llu,"
@@ -295,12 +278,14 @@ __btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
(unsigned long long)bytes);
WARN_ON(1);
ret = -EINVAL;
+ spin_unlock(&block_group->tree_lock);
goto out;
}
unlink_free_space(block_group, info);
if (info->bytes == bytes) {
kfree(info);
+ spin_unlock(&block_group->tree_lock);
goto out;
}
@@ -308,6 +293,7 @@ __btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
info->bytes -= bytes;
ret = link_free_space(block_group, info);
+ spin_unlock(&block_group->tree_lock);
BUG_ON(ret);
} else if (info && info->offset < offset &&
info->offset + info->bytes >= offset + bytes) {
@@ -333,70 +319,33 @@ __btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
*/
kfree(info);
}
-
+ spin_unlock(&block_group->tree_lock);
/* step two, insert a new info struct to cover anything
* before the hole
*/
- ret = __btrfs_add_free_space(block_group, old_start,
- offset - old_start);
+ ret = btrfs_add_free_space(block_group, old_start,
+ offset - old_start);
BUG_ON(ret);
} else {
+ spin_unlock(&block_group->tree_lock);
+ if (!info) {
+ printk(KERN_ERR "couldn't find space %llu to free\n",
+ (unsigned long long)offset);
+ printk(KERN_ERR "cached is %d, offset %llu bytes %llu\n",
+ block_group->cached, block_group->key.objectid,
+ block_group->key.offset);
+ btrfs_dump_free_space(block_group, bytes);
+ } else if (info) {
+ printk(KERN_ERR "hmm, found offset=%llu bytes=%llu, "
+ "but wanted offset=%llu bytes=%llu\n",
+ info->offset, info->bytes, offset, bytes);
+ }
WARN_ON(1);
}
out:
return ret;
}
-int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
- u64 offset, u64 bytes)
-{
- int ret;
- struct btrfs_free_space *sp;
-
- mutex_lock(&block_group->alloc_mutex);
- ret = __btrfs_add_free_space(block_group, offset, bytes);
- sp = tree_search_offset(&block_group->free_space_offset, offset, 0, 1);
- BUG_ON(!sp);
- mutex_unlock(&block_group->alloc_mutex);
-
- return ret;
-}
-
-int btrfs_add_free_space_lock(struct btrfs_block_group_cache *block_group,
- u64 offset, u64 bytes)
-{
- int ret;
- struct btrfs_free_space *sp;
-
- ret = __btrfs_add_free_space(block_group, offset, bytes);
- sp = tree_search_offset(&block_group->free_space_offset, offset, 0, 1);
- BUG_ON(!sp);
-
- return ret;
-}
-
-int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
- u64 offset, u64 bytes)
-{
- int ret = 0;
-
- mutex_lock(&block_group->alloc_mutex);
- ret = __btrfs_remove_free_space(block_group, offset, bytes);
- mutex_unlock(&block_group->alloc_mutex);
-
- return ret;
-}
-
-int btrfs_remove_free_space_lock(struct btrfs_block_group_cache *block_group,
- u64 offset, u64 bytes)
-{
- int ret;
-
- ret = __btrfs_remove_free_space(block_group, offset, bytes);
-
- return ret;
-}
-
void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
u64 bytes)
{
@@ -408,6 +357,8 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
info = rb_entry(n, struct btrfs_free_space, offset_index);
if (info->bytes >= bytes)
count++;
+ printk(KERN_ERR "entry offset %llu, bytes %llu\n", info->offset,
+ info->bytes);
}
printk(KERN_INFO "%d blocks of free space at or bigger than bytes is"
"\n", count);
@@ -428,68 +379,337 @@ u64 btrfs_block_group_free_space(struct btrfs_block_group_cache *block_group)
return ret;
}
+/*
+ * for a given cluster, put all of its extents back into the free
+ * space cache. If the block group passed doesn't match the block group
+ * pointed to by the cluster, someone else raced in and freed the
+ * cluster already. In that case, we just return without changing anything
+ */
+static int
+__btrfs_return_cluster_to_free_space(
+ struct btrfs_block_group_cache *block_group,
+ struct btrfs_free_cluster *cluster)
+{
+ struct btrfs_free_space *entry;
+ struct rb_node *node;
+
+ spin_lock(&cluster->lock);
+ if (cluster->block_group != block_group)
+ goto out;
+
+ cluster->window_start = 0;
+ node = rb_first(&cluster->root);
+ while(node) {
+ entry = rb_entry(node, struct btrfs_free_space, offset_index);
+ node = rb_next(&entry->offset_index);
+ rb_erase(&entry->offset_index, &cluster->root);
+ link_free_space(block_group, entry);
+ }
+ list_del_init(&cluster->block_group_list);
+
+ btrfs_put_block_group(cluster->block_group);
+ cluster->block_group = NULL;
+ cluster->root.rb_node = NULL;
+out:
+ spin_unlock(&cluster->lock);
+ return 0;
+}
+
void btrfs_remove_free_space_cache(struct btrfs_block_group_cache *block_group)
{
struct btrfs_free_space *info;
struct rb_node *node;
+ struct btrfs_free_cluster *cluster;
+ struct btrfs_free_cluster *safe;
+
+ spin_lock(&block_group->tree_lock);
+
+ list_for_each_entry_safe(cluster, safe, &block_group->cluster_list,
+ block_group_list) {
+
+ WARN_ON(cluster->block_group != block_group);
+ __btrfs_return_cluster_to_free_space(block_group, cluster);
+ }
- mutex_lock(&block_group->alloc_mutex);
while ((node = rb_last(&block_group->free_space_bytes)) != NULL) {
info = rb_entry(node, struct btrfs_free_space, bytes_index);
unlink_free_space(block_group, info);
kfree(info);
if (need_resched()) {
- mutex_unlock(&block_group->alloc_mutex);
+ spin_unlock(&block_group->tree_lock);
cond_resched();
- mutex_lock(&block_group->alloc_mutex);
+ spin_lock(&block_group->tree_lock);
}
}
- mutex_unlock(&block_group->alloc_mutex);
+ spin_unlock(&block_group->tree_lock);
}
-#if 0
-static struct btrfs_free_space *btrfs_find_free_space_offset(struct
- btrfs_block_group_cache
- *block_group, u64 offset,
- u64 bytes)
+u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,
+ u64 offset, u64 bytes, u64 empty_size)
{
- struct btrfs_free_space *ret;
+ struct btrfs_free_space *entry = NULL;
+ u64 ret = 0;
- mutex_lock(&block_group->alloc_mutex);
- ret = tree_search_offset(&block_group->free_space_offset, offset,
- bytes, 0);
- mutex_unlock(&block_group->alloc_mutex);
+ spin_lock(&block_group->tree_lock);
+ entry = tree_search_offset(&block_group->free_space_offset, offset,
+ bytes + empty_size, 1);
+ if (!entry)
+ entry = tree_search_bytes(&block_group->free_space_bytes,
+ offset, bytes + empty_size);
+ if (entry) {
+ unlink_free_space(block_group, entry);
+ ret = entry->offset;
+ entry->offset += bytes;
+ entry->bytes -= bytes;
+
+ if (!entry->bytes)
+ kfree(entry);
+ else
+ link_free_space(block_group, entry);
+ }
+ spin_unlock(&block_group->tree_lock);
return ret;
}
-static struct btrfs_free_space *btrfs_find_free_space_bytes(struct
- btrfs_block_group_cache
- *block_group, u64 offset,
- u64 bytes)
+/*
+ * given a cluster, put all of its extents back into the free space
+ * cache. If a block group is passed, this function will only free
+ * a cluster that belongs to the passed block group.
+ *
+ * Otherwise, it'll get a reference on the block group pointed to by the
+ * cluster and remove the cluster from it.
+ */
+int btrfs_return_cluster_to_free_space(
+ struct btrfs_block_group_cache *block_group,
+ struct btrfs_free_cluster *cluster)
{
- struct btrfs_free_space *ret;
+ int ret;
- mutex_lock(&block_group->alloc_mutex);
+ /* first, get a safe pointer to the block group */
+ spin_lock(&cluster->lock);
+ if (!block_group) {
+ block_group = cluster->block_group;
+ if (!block_group) {
+ spin_unlock(&cluster->lock);
+ return 0;
+ }
+ } else if (cluster->block_group != block_group) {
+ /* someone else has already freed it don't redo their work */
+ spin_unlock(&cluster->lock);
+ return 0;
+ }
+ atomic_inc(&block_group->count);
+ spin_unlock(&cluster->lock);
- ret = tree_search_bytes(&block_group->free_space_bytes, offset, bytes);
- mutex_unlock(&block_group->alloc_mutex);
+ /* now return any extents the cluster had on it */
+ spin_lock(&block_group->tree_lock);
+ ret = __btrfs_return_cluster_to_free_space(block_group, cluster);
+ spin_unlock(&block_group->tree_lock);
+ /* finally drop our ref */
+ btrfs_put_block_group(block_group);
return ret;
}
-#endif
-struct btrfs_free_space *btrfs_find_free_space(struct btrfs_block_group_cache
- *block_group, u64 offset,
- u64 bytes)
+/*
+ * given a cluster, try to allocate 'bytes' from it, returns 0
+ * if it couldn't find anything suitably large, or a logical disk offset
+ * if things worked out
+ */
+u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
+ struct btrfs_free_cluster *cluster, u64 bytes,
+ u64 min_start)
+{
+ struct btrfs_free_space *entry = NULL;
+ struct rb_node *node;
+ u64 ret = 0;
+
+ spin_lock(&cluster->lock);
+ if (bytes > cluster->max_size)
+ goto out;
+
+ if (cluster->block_group != block_group)
+ goto out;
+
+ node = rb_first(&cluster->root);
+ if (!node)
+ goto out;
+
+ entry = rb_entry(node, struct btrfs_free_space, offset_index);
+
+ while(1) {
+ if (entry->bytes < bytes || entry->offset < min_start) {
+ struct rb_node *node;
+
+ node = rb_next(&entry->offset_index);
+ if (!node)
+ break;
+ entry = rb_entry(node, struct btrfs_free_space,
+ offset_index);
+ continue;
+ }
+ ret = entry->offset;
+
+ entry->offset += bytes;
+ entry->bytes -= bytes;
+
+ if (entry->bytes == 0) {
+ rb_erase(&entry->offset_index, &cluster->root);
+ kfree(entry);
+ }
+ break;
+ }
+out:
+ spin_unlock(&cluster->lock);
+ return ret;
+}
+
+/*
+ * here we try to find a cluster of blocks in a block group. The goal
+ * is to find at least bytes free and up to empty_size + bytes free.
+ * We might not find them all in one contiguous area.
+ *
+ * returns zero and sets up cluster if things worked out, otherwise
+ * it returns -enospc
+ */
+int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
+ struct btrfs_block_group_cache *block_group,
+ struct btrfs_free_cluster *cluster,
+ u64 offset, u64 bytes, u64 empty_size)
{
- struct btrfs_free_space *ret = NULL;
+ struct btrfs_free_space *entry = NULL;
+ struct rb_node *node;
+ struct btrfs_free_space *next;
+ struct btrfs_free_space *last;
+ u64 min_bytes;
+ u64 window_start;
+ u64 window_free;
+ u64 max_extent = 0;
+ int total_retries = 0;
+ int ret;
+
+ /* for metadata, allow allocates with more holes */
+ if (block_group->flags & BTRFS_BLOCK_GROUP_METADATA) {
+ /*
+ * we want to do larger allocations when we are
+ * flushing out the delayed refs, it helps prevent
+ * making more work as we go along.
+ */
+ if (trans->transaction->delayed_refs.flushing)
+ min_bytes = max(bytes, (bytes + empty_size) >> 1);
+ else
+ min_bytes = max(bytes, (bytes + empty_size) >> 4);
+ } else
+ min_bytes = max(bytes, (bytes + empty_size) >> 2);
+
+ spin_lock(&block_group->tree_lock);
+ spin_lock(&cluster->lock);
+
+ /* someone already found a cluster, hooray */
+ if (cluster->block_group) {
+ ret = 0;
+ goto out;
+ }
+again:
+ min_bytes = min(min_bytes, bytes + empty_size);
+ entry = tree_search_bytes(&block_group->free_space_bytes,
+ offset, min_bytes);
+ if (!entry) {
+ ret = -ENOSPC;
+ goto out;
+ }
+ window_start = entry->offset;
+ window_free = entry->bytes;
+ last = entry;
+ max_extent = entry->bytes;
+
+ while(1) {
+ /* out window is just right, lets fill it */
+ if (window_free >= bytes + empty_size)
+ break;
- ret = tree_search_offset(&block_group->free_space_offset, offset,
- bytes, 0);
- if (!ret)
- ret = tree_search_bytes(&block_group->free_space_bytes,
- offset, bytes);
+ node = rb_next(&last->offset_index);
+ if (!node) {
+ ret = -ENOSPC;
+ goto out;
+ }
+ next = rb_entry(node, struct btrfs_free_space, offset_index);
+
+ /*
+ * we haven't filled the empty size and the window is
+ * very large. reset and try again
+ */
+ if (next->offset - window_start > (bytes + empty_size) * 2) {
+ entry = next;
+ window_start = entry->offset;
+ window_free = entry->bytes;
+ last = entry;
+ max_extent = 0;
+ total_retries++;
+ if (total_retries % 256 == 0) {
+ if (min_bytes >= (bytes + empty_size)) {
+ ret = -ENOSPC;
+ goto out;
+ }
+ /*
+ * grow our allocation a bit, we're not having
+ * much luck
+ */
+ min_bytes *= 2;
+ goto again;
+ }
+ } else {
+ last = next;
+ window_free += next->bytes;
+ if (entry->bytes > max_extent)
+ max_extent = entry->bytes;
+ }
+ }
+
+ cluster->window_start = entry->offset;
+
+ /*
+ * now we've found our entries, pull them out of the free space
+ * cache and put them into the cluster rbtree
+ *
+ * The cluster includes an rbtree, but only uses the offset index
+ * of each free space cache entry.
+ */
+ while(1) {
+ node = rb_next(&entry->offset_index);
+ unlink_free_space(block_group, entry);
+ ret = tree_insert_offset(&cluster->root, entry->offset,
+ &entry->offset_index);
+ BUG_ON(ret);
+
+ if (!node || entry == last)
+ break;
+
+ entry = rb_entry(node, struct btrfs_free_space, offset_index);
+ }
+ ret = 0;
+ cluster->max_size = max_extent;
+ atomic_inc(&block_group->count);
+ list_add_tail(&cluster->block_group_list, &block_group->cluster_list);
+ cluster->block_group = block_group;
+out:
+ spin_unlock(&cluster->lock);
+ spin_unlock(&block_group->tree_lock);
return ret;
}
+
+/*
+ * simple code to zero out a cluster
+ */
+void btrfs_init_free_cluster(struct btrfs_free_cluster *cluster)
+{
+ spin_lock_init(&cluster->lock);
+ spin_lock_init(&cluster->refill_lock);
+ cluster->root.rb_node = NULL;
+ cluster->max_size = 0;
+ INIT_LIST_HEAD(&cluster->block_group_list);
+ cluster->block_group = NULL;
+}
+
diff --git a/fs/btrfs/free-space-cache.h b/fs/btrfs/free-space-cache.h
new file mode 100644
index 00000000000..ab0bdc0a63c
--- /dev/null
+++ b/fs/btrfs/free-space-cache.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 Oracle. 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 v2 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 021110-1307, USA.
+ */
+
+#ifndef __BTRFS_FREE_SPACE_CACHE
+#define __BTRFS_FREE_SPACE_CACHE
+
+int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
+ u64 bytenr, u64 size);
+int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
+ u64 bytenr, u64 size);
+void btrfs_remove_free_space_cache(struct btrfs_block_group_cache
+ *block_group);
+u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,
+ u64 offset, u64 bytes, u64 empty_size);
+void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
+ u64 bytes);
+u64 btrfs_block_group_free_space(struct btrfs_block_group_cache *block_group);
+int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
+ struct btrfs_block_group_cache *block_group,
+ struct btrfs_free_cluster *cluster,
+ u64 offset, u64 bytes, u64 empty_size);
+void btrfs_init_free_cluster(struct btrfs_free_cluster *cluster);
+u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
+ struct btrfs_free_cluster *cluster, u64 bytes,
+ u64 min_start);
+int btrfs_return_cluster_to_free_space(
+ struct btrfs_block_group_cache *block_group,
+ struct btrfs_free_cluster *cluster);
+#endif
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 06d8db5afb0..a0d1dd492a5 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3481,8 +3481,10 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
if (dir) {
ret = btrfs_set_inode_index(dir, index);
- if (ret)
+ if (ret) {
+ iput(inode);
return ERR_PTR(ret);
+ }
}
/*
* index_cnt is ignored for everything but a dir,
@@ -3565,6 +3567,7 @@ fail:
if (dir)
BTRFS_I(dir)->index_cnt--;
btrfs_free_path(path);
+ iput(inode);
return ERR_PTR(ret);
}
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c
index a5310c0f41e..1c36e5cd8f5 100644
--- a/fs/btrfs/locking.c
+++ b/fs/btrfs/locking.c
@@ -60,8 +60,8 @@ void btrfs_clear_lock_blocking(struct extent_buffer *eb)
/*
* unfortunately, many of the places that currently set a lock to blocking
- * don't end up blocking for every long, and often they don't block
- * at all. For a dbench 50 run, if we don't spin one the blocking bit
+ * don't end up blocking for very long, and often they don't block
+ * at all. For a dbench 50 run, if we don't spin on the blocking bit
* at all, the context switch rate can jump up to 400,000/sec or more.
*
* So, we're still stuck with this crummy spin on the blocking bit,
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 19a4daf03cc..9744af9d71e 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -24,6 +24,7 @@
#include <linux/highmem.h>
#include <linux/time.h>
#include <linux/init.h>
+#include <linux/seq_file.h>
#include <linux/string.h>
#include <linux/smp_lock.h>
#include <linux/backing-dev.h>
@@ -66,7 +67,8 @@ static void btrfs_put_super(struct super_block *sb)
enum {
Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
- Opt_ssd, Opt_thread_pool, Opt_noacl, Opt_compress, Opt_err,
+ Opt_ssd, Opt_thread_pool, Opt_noacl, Opt_compress, Opt_notreelog,
+ Opt_flushoncommit, Opt_err,
};
static match_table_t tokens = {
@@ -83,6 +85,8 @@ static match_table_t tokens = {
{Opt_compress, "compress"},
{Opt_ssd, "ssd"},
{Opt_noacl, "noacl"},
+ {Opt_notreelog, "notreelog"},
+ {Opt_flushoncommit, "flushoncommit"},
{Opt_err, NULL},
};
@@ -222,6 +226,14 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
case Opt_noacl:
root->fs_info->sb->s_flags &= ~MS_POSIXACL;
break;
+ case Opt_notreelog:
+ printk(KERN_INFO "btrfs: disabling tree log\n");
+ btrfs_set_opt(info->mount_opt, NOTREELOG);
+ break;
+ case Opt_flushoncommit:
+ printk(KERN_INFO "btrfs: turning on flush-on-commit\n");
+ btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT);
+ break;
default:
break;
}
@@ -363,9 +375,8 @@ fail_close:
int btrfs_sync_fs(struct super_block *sb, int wait)
{
struct btrfs_trans_handle *trans;
- struct btrfs_root *root;
+ struct btrfs_root *root = btrfs_sb(sb);
int ret;
- root = btrfs_sb(sb);
if (sb->s_flags & MS_RDONLY)
return 0;
@@ -385,6 +396,41 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
return ret;
}
+static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+ struct btrfs_root *root = btrfs_sb(vfs->mnt_sb);
+ struct btrfs_fs_info *info = root->fs_info;
+
+ if (btrfs_test_opt(root, DEGRADED))
+ seq_puts(seq, ",degraded");
+ if (btrfs_test_opt(root, NODATASUM))
+ seq_puts(seq, ",nodatasum");
+ if (btrfs_test_opt(root, NODATACOW))
+ seq_puts(seq, ",nodatacow");
+ if (btrfs_test_opt(root, NOBARRIER))
+ seq_puts(seq, ",nobarrier");
+ if (info->max_extent != (u64)-1)
+ seq_printf(seq, ",max_extent=%llu", info->max_extent);
+ if (info->max_inline != 8192 * 1024)
+ seq_printf(seq, ",max_inline=%llu", info->max_inline);
+ if (info->alloc_start != 0)
+ seq_printf(seq, ",alloc_start=%llu", info->alloc_start);
+ if (info->thread_pool_size != min_t(unsigned long,
+ num_online_cpus() + 2, 8))
+ seq_printf(seq, ",thread_pool=%d", info->thread_pool_size);
+ if (btrfs_test_opt(root, COMPRESS))
+ seq_puts(seq, ",compress");
+ if (btrfs_test_opt(root, SSD))
+ seq_puts(seq, ",ssd");
+ if (btrfs_test_opt(root, NOTREELOG))
+ seq_puts(seq, ",no-treelog");
+ if (btrfs_test_opt(root, FLUSHONCOMMIT))
+ seq_puts(seq, ",flush-on-commit");
+ if (!(root->fs_info->sb->s_flags & MS_POSIXACL))
+ seq_puts(seq, ",noacl");
+ return 0;
+}
+
static void btrfs_write_super(struct super_block *sb)
{
sb->s_dirt = 0;
@@ -630,7 +676,7 @@ static struct super_operations btrfs_super_ops = {
.put_super = btrfs_put_super,
.write_super = btrfs_write_super,
.sync_fs = btrfs_sync_fs,
- .show_options = generic_show_options,
+ .show_options = btrfs_show_options,
.write_inode = btrfs_write_inode,
.dirty_inode = btrfs_dirty_inode,
.alloc_inode = btrfs_alloc_inode,
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 664782c6a2d..2869b3361eb 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -53,8 +53,6 @@ static noinline int join_transaction(struct btrfs_root *root)
GFP_NOFS);
BUG_ON(!cur_trans);
root->fs_info->generation++;
- root->fs_info->last_alloc = 0;
- root->fs_info->last_data_alloc = 0;
cur_trans->num_writers = 1;
cur_trans->num_joined = 0;
cur_trans->transid = root->fs_info->generation;
@@ -974,6 +972,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
int ret;
int should_grow = 0;
unsigned long now = get_seconds();
+ int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT);
btrfs_run_ordered_operations(root, 0);
@@ -1053,7 +1052,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
mutex_unlock(&root->fs_info->trans_mutex);
- if (snap_pending) {
+ if (flush_on_commit || snap_pending) {
+ if (flush_on_commit)
+ btrfs_start_delalloc_inodes(root);
ret = btrfs_wait_ordered_extents(root, 1);
BUG_ON(ret);
}
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index fc9b87a7975..25f20ea11f2 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -262,11 +262,9 @@ static int process_one_buffer(struct btrfs_root *log,
struct extent_buffer *eb,
struct walk_control *wc, u64 gen)
{
- if (wc->pin) {
- mutex_lock(&log->fs_info->pinned_mutex);
+ if (wc->pin)
btrfs_update_pinned_extents(log->fs_info->extent_root,
eb->start, eb->len, 1);
- }
if (btrfs_buffer_uptodate(eb, gen)) {
if (wc->write)
@@ -1224,8 +1222,7 @@ insert:
ret = insert_one_name(trans, root, path, key->objectid, key->offset,
name, name_len, log_type, &log_key);
- if (ret && ret != -ENOENT)
- BUG();
+ BUG_ON(ret && ret != -ENOENT);
goto out;
}
@@ -2900,6 +2897,11 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
sb = inode->i_sb;
+ if (btrfs_test_opt(root, NOTREELOG)) {
+ ret = 1;
+ goto end_no_trans;
+ }
+
if (root->fs_info->last_trans_log_full_commit >
root->fs_info->last_trans_committed) {
ret = 1;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index dd06e18e5aa..e0913e46972 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -20,6 +20,7 @@
#include <linux/buffer_head.h>
#include <linux/blkdev.h>
#include <linux/random.h>
+#include <linux/iocontext.h>
#include <asm/div64.h>
#include "compat.h"
#include "ctree.h"
@@ -145,8 +146,9 @@ static noinline int run_scheduled_bios(struct btrfs_device *device)
int again = 0;
unsigned long num_run = 0;
unsigned long limit;
+ unsigned long last_waited = 0;
- bdi = device->bdev->bd_inode->i_mapping->backing_dev_info;
+ bdi = blk_get_backing_dev_info(device->bdev);
fs_info = device->dev_root->fs_info;
limit = btrfs_async_submit_limit(fs_info);
limit = limit * 2 / 3;
@@ -207,7 +209,32 @@ loop_lock:
if (pending && bdi_write_congested(bdi) && num_run > 16 &&
fs_info->fs_devices->open_devices > 1) {
struct bio *old_head;
+ struct io_context *ioc;
+ ioc = current->io_context;
+
+ /*
+ * the main goal here is that we don't want to
+ * block if we're going to be able to submit
+ * more requests without blocking.
+ *
+ * This code does two great things, it pokes into
+ * the elevator code from a filesystem _and_
+ * it makes assumptions about how batching works.
+ */
+ if (ioc && ioc->nr_batch_requests > 0 &&
+ time_before(jiffies, ioc->last_waited + HZ/50UL) &&
+ (last_waited == 0 ||
+ ioc->last_waited == last_waited)) {
+ /*
+ * we want to go through our batch of
+ * requests and stop. So, we copy out
+ * the ioc->last_waited time and test
+ * against it before looping
+ */
+ last_waited = ioc->last_waited;
+ continue;
+ }
spin_lock(&device->io_lock);
old_head = device->pending_bios;
@@ -231,6 +258,18 @@ loop_lock:
if (device->pending_bios)
goto loop_lock;
spin_unlock(&device->io_lock);
+
+ /*
+ * IO has already been through a long path to get here. Checksumming,
+ * async helper threads, perhaps compression. We've done a pretty
+ * good job of collecting a batch of IO and should just unplug
+ * the device right away.
+ *
+ * This will help anyone who is waiting on the IO, they might have
+ * already unplugged, but managed to do so before the bio they
+ * cared about found its way down here.
+ */
+ blk_run_backing_dev(bdi, NULL);
done:
return 0;
}
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 86c44e9ae11..2185de72ff7 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -76,7 +76,7 @@ struct btrfs_device {
struct btrfs_fs_devices {
u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
- /* the device with this id has the most recent coyp of the super */
+ /* the device with this id has the most recent copy of the super */
u64 latest_devid;
u64 latest_trans;
u64 num_devices;
diff --git a/fs/buffer.c b/fs/buffer.c
index c2fa1be4923..13edf7ad3ff 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -737,7 +737,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
{
struct buffer_head *bh;
struct list_head tmp;
- struct address_space *mapping;
+ struct address_space *mapping, *prev_mapping = NULL;
int err = 0, err2;
INIT_LIST_HEAD(&tmp);
@@ -762,7 +762,18 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
* contents - it is a noop if I/O is still in
* flight on potentially older contents.
*/
- ll_rw_block(SWRITE_SYNC, 1, &bh);
+ ll_rw_block(SWRITE_SYNC_PLUG, 1, &bh);
+
+ /*
+ * Kick off IO for the previous mapping. Note
+ * that we will not run the very last mapping,
+ * wait_on_buffer() will do that for us
+ * through sync_buffer().
+ */
+ if (prev_mapping && prev_mapping != mapping)
+ blk_run_address_space(prev_mapping);
+ prev_mapping = mapping;
+
brelse(bh);
spin_lock(lock);
}
@@ -1585,6 +1596,16 @@ EXPORT_SYMBOL(unmap_underlying_metadata);
* locked buffer. This only can happen if someone has written the buffer
* directly, with submit_bh(). At the address_space level PageWriteback
* prevents this contention from occurring.
+ *
+ * If block_write_full_page() is called with wbc->sync_mode ==
+ * WB_SYNC_ALL, the writes are posted using WRITE_SYNC_PLUG; this
+ * causes the writes to be flagged as synchronous writes, but the
+ * block device queue will NOT be unplugged, since usually many pages
+ * will be pushed to the out before the higher-level caller actually
+ * waits for the writes to be completed. The various wait functions,
+ * such as wait_on_writeback_range() will ultimately call sync_page()
+ * which will ultimately call blk_run_backing_dev(), which will end up
+ * unplugging the device queue.
*/
static int __block_write_full_page(struct inode *inode, struct page *page,
get_block_t *get_block, struct writeback_control *wbc)
@@ -1595,6 +1616,8 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
struct buffer_head *bh, *head;
const unsigned blocksize = 1 << inode->i_blkbits;
int nr_underway = 0;
+ int write_op = (wbc->sync_mode == WB_SYNC_ALL ?
+ WRITE_SYNC_PLUG : WRITE);
BUG_ON(!PageLocked(page));
@@ -1686,7 +1709,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
do {
struct buffer_head *next = bh->b_this_page;
if (buffer_async_write(bh)) {
- submit_bh(WRITE, bh);
+ submit_bh(write_op, bh);
nr_underway++;
}
bh = next;
@@ -1740,7 +1763,7 @@ recover:
struct buffer_head *next = bh->b_this_page;
if (buffer_async_write(bh)) {
clear_buffer_dirty(bh);
- submit_bh(WRITE, bh);
+ submit_bh(write_op, bh);
nr_underway++;
}
bh = next;
@@ -2956,12 +2979,13 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
for (i = 0; i < nr; i++) {
struct buffer_head *bh = bhs[i];
- if (rw == SWRITE || rw == SWRITE_SYNC)
+ if (rw == SWRITE || rw == SWRITE_SYNC || rw == SWRITE_SYNC_PLUG)
lock_buffer(bh);
else if (!trylock_buffer(bh))
continue;
- if (rw == WRITE || rw == SWRITE || rw == SWRITE_SYNC) {
+ if (rw == WRITE || rw == SWRITE || rw == SWRITE_SYNC ||
+ rw == SWRITE_SYNC_PLUG) {
if (test_clear_buffer_dirty(bh)) {
bh->b_end_io = end_buffer_write_sync;
get_bh(bh);
@@ -2997,7 +3021,7 @@ int sync_dirty_buffer(struct buffer_head *bh)
if (test_clear_buffer_dirty(bh)) {
get_bh(bh);
bh->b_end_io = end_buffer_write_sync;
- ret = submit_bh(WRITE, bh);
+ ret = submit_bh(WRITE_SYNC, bh);
wait_on_buffer(bh);
if (buffer_eopnotsupp(bh)) {
clear_buffer_eopnotsupp(bh);
diff --git a/fs/cachefiles/Kconfig b/fs/cachefiles/Kconfig
new file mode 100644
index 00000000000..80e9c6167f0
--- /dev/null
+++ b/fs/cachefiles/Kconfig
@@ -0,0 +1,39 @@
+
+config CACHEFILES
+ tristate "Filesystem caching on files"
+ depends on FSCACHE && BLOCK
+ help
+ This permits use of a mounted filesystem as a cache for other
+ filesystems - primarily networking filesystems - thus allowing fast
+ local disk to enhance the speed of slower devices.
+
+ See Documentation/filesystems/caching/cachefiles.txt for more
+ information.
+
+config CACHEFILES_DEBUG
+ bool "Debug CacheFiles"
+ depends on CACHEFILES
+ help
+ This permits debugging to be dynamically enabled in the filesystem
+ caching on files module. If this is set, the debugging output may be
+ enabled by setting bits in /sys/modules/cachefiles/parameter/debug or
+ by including a debugging specifier in /etc/cachefilesd.conf.
+
+config CACHEFILES_HISTOGRAM
+ bool "Gather latency information on CacheFiles"
+ depends on CACHEFILES && PROC_FS
+ help
+
+ This option causes latency information to be gathered on CacheFiles
+ operation and exported through file:
+
+ /proc/fs/cachefiles/histogram
+
+ The generation of this histogram adds a certain amount of overhead to
+ execution as there are a number of points at which data is gathered,
+ and on a multi-CPU system these may be on cachelines that keep
+ bouncing between CPUs. On the other hand, the histogram may be
+ useful for debugging purposes. Saying 'N' here is recommended.
+
+ See Documentation/filesystems/caching/cachefiles.txt for more
+ information.
diff --git a/fs/cachefiles/Makefile b/fs/cachefiles/Makefile
new file mode 100644
index 00000000000..32cbab0ffce
--- /dev/null
+++ b/fs/cachefiles/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for caching in a mounted filesystem
+#
+
+cachefiles-y := \
+ bind.o \
+ daemon.o \
+ interface.o \
+ key.o \
+ main.o \
+ namei.o \
+ rdwr.o \
+ security.o \
+ xattr.o
+
+cachefiles-$(CONFIG_CACHEFILES_HISTOGRAM) += proc.o
+
+obj-$(CONFIG_CACHEFILES) := cachefiles.o
diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c
new file mode 100644
index 00000000000..3797e0077b3
--- /dev/null
+++ b/fs/cachefiles/bind.c
@@ -0,0 +1,286 @@
+/* Bind and unbind a cache from the filesystem backing it
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/statfs.h>
+#include <linux/ctype.h>
+#include "internal.h"
+
+static int cachefiles_daemon_add_cache(struct cachefiles_cache *caches);
+
+/*
+ * bind a directory as a cache
+ */
+int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args)
+{
+ _enter("{%u,%u,%u,%u,%u,%u},%s",
+ cache->frun_percent,
+ cache->fcull_percent,
+ cache->fstop_percent,
+ cache->brun_percent,
+ cache->bcull_percent,
+ cache->bstop_percent,
+ args);
+
+ /* start by checking things over */
+ ASSERT(cache->fstop_percent >= 0 &&
+ cache->fstop_percent < cache->fcull_percent &&
+ cache->fcull_percent < cache->frun_percent &&
+ cache->frun_percent < 100);
+
+ ASSERT(cache->bstop_percent >= 0 &&
+ cache->bstop_percent < cache->bcull_percent &&
+ cache->bcull_percent < cache->brun_percent &&
+ cache->brun_percent < 100);
+
+ if (*args) {
+ kerror("'bind' command doesn't take an argument");
+ return -EINVAL;
+ }
+
+ if (!cache->rootdirname) {
+ kerror("No cache directory specified");
+ return -EINVAL;
+ }
+
+ /* don't permit already bound caches to be re-bound */
+ if (test_bit(CACHEFILES_READY, &cache->flags)) {
+ kerror("Cache already bound");
+ return -EBUSY;
+ }
+
+ /* make sure we have copies of the tag and dirname strings */
+ if (!cache->tag) {
+ /* the tag string is released by the fops->release()
+ * function, so we don't release it on error here */
+ cache->tag = kstrdup("CacheFiles", GFP_KERNEL);
+ if (!cache->tag)
+ return -ENOMEM;
+ }
+
+ /* add the cache */
+ return cachefiles_daemon_add_cache(cache);
+}
+
+/*
+ * add a cache
+ */
+static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache)
+{
+ struct cachefiles_object *fsdef;
+ struct nameidata nd;
+ struct kstatfs stats;
+ struct dentry *graveyard, *cachedir, *root;
+ const struct cred *saved_cred;
+ int ret;
+
+ _enter("");
+
+ /* we want to work under the module's security ID */
+ ret = cachefiles_get_security_ID(cache);
+ if (ret < 0)
+ return ret;
+
+ cachefiles_begin_secure(cache, &saved_cred);
+
+ /* allocate the root index object */
+ ret = -ENOMEM;
+
+ fsdef = kmem_cache_alloc(cachefiles_object_jar, GFP_KERNEL);
+ if (!fsdef)
+ goto error_root_object;
+
+ ASSERTCMP(fsdef->backer, ==, NULL);
+
+ atomic_set(&fsdef->usage, 1);
+ fsdef->type = FSCACHE_COOKIE_TYPE_INDEX;
+
+ _debug("- fsdef %p", fsdef);
+
+ /* look up the directory at the root of the cache */
+ memset(&nd, 0, sizeof(nd));
+
+ ret = path_lookup(cache->rootdirname, LOOKUP_DIRECTORY, &nd);
+ if (ret < 0)
+ goto error_open_root;
+
+ cache->mnt = mntget(nd.path.mnt);
+ root = dget(nd.path.dentry);
+ path_put(&nd.path);
+
+ /* check parameters */
+ ret = -EOPNOTSUPP;
+ if (!root->d_inode ||
+ !root->d_inode->i_op ||
+ !root->d_inode->i_op->lookup ||
+ !root->d_inode->i_op->mkdir ||
+ !root->d_inode->i_op->setxattr ||
+ !root->d_inode->i_op->getxattr ||
+ !root->d_sb ||
+ !root->d_sb->s_op ||
+ !root->d_sb->s_op->statfs ||
+ !root->d_sb->s_op->sync_fs)
+ goto error_unsupported;
+
+ ret = -EROFS;
+ if (root->d_sb->s_flags & MS_RDONLY)
+ goto error_unsupported;
+
+ /* determine the security of the on-disk cache as this governs
+ * security ID of files we create */
+ ret = cachefiles_determine_cache_security(cache, root, &saved_cred);
+ if (ret < 0)
+ goto error_unsupported;
+
+ /* get the cache size and blocksize */
+ ret = vfs_statfs(root, &stats);
+ if (ret < 0)
+ goto error_unsupported;
+
+ ret = -ERANGE;
+ if (stats.f_bsize <= 0)
+ goto error_unsupported;
+
+ ret = -EOPNOTSUPP;
+ if (stats.f_bsize > PAGE_SIZE)
+ goto error_unsupported;
+
+ cache->bsize = stats.f_bsize;
+ cache->bshift = 0;
+ if (stats.f_bsize < PAGE_SIZE)
+ cache->bshift = PAGE_SHIFT - ilog2(stats.f_bsize);
+
+ _debug("blksize %u (shift %u)",
+ cache->bsize, cache->bshift);
+
+ _debug("size %llu, avail %llu",
+ (unsigned long long) stats.f_blocks,
+ (unsigned long long) stats.f_bavail);
+
+ /* set up caching limits */
+ do_div(stats.f_files, 100);
+ cache->fstop = stats.f_files * cache->fstop_percent;
+ cache->fcull = stats.f_files * cache->fcull_percent;
+ cache->frun = stats.f_files * cache->frun_percent;
+
+ _debug("limits {%llu,%llu,%llu} files",
+ (unsigned long long) cache->frun,
+ (unsigned long long) cache->fcull,
+ (unsigned long long) cache->fstop);
+
+ stats.f_blocks >>= cache->bshift;
+ do_div(stats.f_blocks, 100);
+ cache->bstop = stats.f_blocks * cache->bstop_percent;
+ cache->bcull = stats.f_blocks * cache->bcull_percent;
+ cache->brun = stats.f_blocks * cache->brun_percent;
+
+ _debug("limits {%llu,%llu,%llu} blocks",
+ (unsigned long long) cache->brun,
+ (unsigned long long) cache->bcull,
+ (unsigned long long) cache->bstop);
+
+ /* get the cache directory and check its type */
+ cachedir = cachefiles_get_directory(cache, root, "cache");
+ if (IS_ERR(cachedir)) {
+ ret = PTR_ERR(cachedir);
+ goto error_unsupported;
+ }
+
+ fsdef->dentry = cachedir;
+ fsdef->fscache.cookie = NULL;
+
+ ret = cachefiles_check_object_type(fsdef);
+ if (ret < 0)
+ goto error_unsupported;
+
+ /* get the graveyard directory */
+ graveyard = cachefiles_get_directory(cache, root, "graveyard");
+ if (IS_ERR(graveyard)) {
+ ret = PTR_ERR(graveyard);
+ goto error_unsupported;
+ }
+
+ cache->graveyard = graveyard;
+
+ /* publish the cache */
+ fscache_init_cache(&cache->cache,
+ &cachefiles_cache_ops,
+ "%s",
+ fsdef->dentry->d_sb->s_id);
+
+ fscache_object_init(&fsdef->fscache, NULL, &cache->cache);
+
+ ret = fscache_add_cache(&cache->cache, &fsdef->fscache, cache->tag);
+ if (ret < 0)
+ goto error_add_cache;
+
+ /* done */
+ set_bit(CACHEFILES_READY, &cache->flags);
+ dput(root);
+
+ printk(KERN_INFO "CacheFiles:"
+ " File cache on %s registered\n",
+ cache->cache.identifier);
+
+ /* check how much space the cache has */
+ cachefiles_has_space(cache, 0, 0);
+ cachefiles_end_secure(cache, saved_cred);
+ return 0;
+
+error_add_cache:
+ dput(cache->graveyard);
+ cache->graveyard = NULL;
+error_unsupported:
+ mntput(cache->mnt);
+ cache->mnt = NULL;
+ dput(fsdef->dentry);
+ fsdef->dentry = NULL;
+ dput(root);
+error_open_root:
+ kmem_cache_free(cachefiles_object_jar, fsdef);
+error_root_object:
+ cachefiles_end_secure(cache, saved_cred);
+ kerror("Failed to register: %d", ret);
+ return ret;
+}
+
+/*
+ * unbind a cache on fd release
+ */
+void cachefiles_daemon_unbind(struct cachefiles_cache *cache)
+{
+ _enter("");
+
+ if (test_bit(CACHEFILES_READY, &cache->flags)) {
+ printk(KERN_INFO "CacheFiles:"
+ " File cache on %s unregistering\n",
+ cache->cache.identifier);
+
+ fscache_withdraw_cache(&cache->cache);
+ }
+
+ dput(cache->graveyard);
+ mntput(cache->mnt);
+
+ kfree(cache->rootdirname);
+ kfree(cache->secctx);
+ kfree(cache->tag);
+
+ _leave("");
+}
diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c
new file mode 100644
index 00000000000..4618516dd99
--- /dev/null
+++ b/fs/cachefiles/daemon.c
@@ -0,0 +1,755 @@
+/* Daemon interface
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/namei.h>
+#include <linux/poll.h>
+#include <linux/mount.h>
+#include <linux/statfs.h>
+#include <linux/ctype.h>
+#include <linux/fs_struct.h>
+#include "internal.h"
+
+static int cachefiles_daemon_open(struct inode *, struct file *);
+static int cachefiles_daemon_release(struct inode *, struct file *);
+static ssize_t cachefiles_daemon_read(struct file *, char __user *, size_t,
+ loff_t *);
+static ssize_t cachefiles_daemon_write(struct file *, const char __user *,
+ size_t, loff_t *);
+static unsigned int cachefiles_daemon_poll(struct file *,
+ struct poll_table_struct *);
+static int cachefiles_daemon_frun(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_fcull(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_fstop(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_brun(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_bcull(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_bstop(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_cull(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_debug(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_dir(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_inuse(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_secctx(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_tag(struct cachefiles_cache *, char *);
+
+static unsigned long cachefiles_open;
+
+const struct file_operations cachefiles_daemon_fops = {
+ .owner = THIS_MODULE,
+ .open = cachefiles_daemon_open,
+ .release = cachefiles_daemon_release,
+ .read = cachefiles_daemon_read,
+ .write = cachefiles_daemon_write,
+ .poll = cachefiles_daemon_poll,
+};
+
+struct cachefiles_daemon_cmd {
+ char name[8];
+ int (*handler)(struct cachefiles_cache *cache, char *args);
+};
+
+static const struct cachefiles_daemon_cmd cachefiles_daemon_cmds[] = {
+ { "bind", cachefiles_daemon_bind },
+ { "brun", cachefiles_daemon_brun },
+ { "bcull", cachefiles_daemon_bcull },
+ { "bstop", cachefiles_daemon_bstop },
+ { "cull", cachefiles_daemon_cull },
+ { "debug", cachefiles_daemon_debug },
+ { "dir", cachefiles_daemon_dir },
+ { "frun", cachefiles_daemon_frun },
+ { "fcull", cachefiles_daemon_fcull },
+ { "fstop", cachefiles_daemon_fstop },
+ { "inuse", cachefiles_daemon_inuse },
+ { "secctx", cachefiles_daemon_secctx },
+ { "tag", cachefiles_daemon_tag },
+ { "", NULL }
+};
+
+
+/*
+ * do various checks
+ */
+static int cachefiles_daemon_open(struct inode *inode, struct file *file)
+{
+ struct cachefiles_cache *cache;
+
+ _enter("");
+
+ /* only the superuser may do this */
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ /* the cachefiles device may only be open once at a time */
+ if (xchg(&cachefiles_open, 1) == 1)
+ return -EBUSY;
+
+ /* allocate a cache record */
+ cache = kzalloc(sizeof(struct cachefiles_cache), GFP_KERNEL);
+ if (!cache) {
+ cachefiles_open = 0;
+ return -ENOMEM;
+ }
+
+ mutex_init(&cache->daemon_mutex);
+ cache->active_nodes = RB_ROOT;
+ rwlock_init(&cache->active_lock);
+ init_waitqueue_head(&cache->daemon_pollwq);
+
+ /* set default caching limits
+ * - limit at 1% free space and/or free files
+ * - cull below 5% free space and/or free files
+ * - cease culling above 7% free space and/or free files
+ */
+ cache->frun_percent = 7;
+ cache->fcull_percent = 5;
+ cache->fstop_percent = 1;
+ cache->brun_percent = 7;
+ cache->bcull_percent = 5;
+ cache->bstop_percent = 1;
+
+ file->private_data = cache;
+ cache->cachefilesd = file;
+ return 0;
+}
+
+/*
+ * release a cache
+ */
+static int cachefiles_daemon_release(struct inode *inode, struct file *file)
+{
+ struct cachefiles_cache *cache = file->private_data;
+
+ _enter("");
+
+ ASSERT(cache);
+
+ set_bit(CACHEFILES_DEAD, &cache->flags);
+
+ cachefiles_daemon_unbind(cache);
+
+ ASSERT(!cache->active_nodes.rb_node);
+
+ /* clean up the control file interface */
+ cache->cachefilesd = NULL;
+ file->private_data = NULL;
+ cachefiles_open = 0;
+
+ kfree(cache);
+
+ _leave("");
+ return 0;
+}
+
+/*
+ * read the cache state
+ */
+static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer,
+ size_t buflen, loff_t *pos)
+{
+ struct cachefiles_cache *cache = file->private_data;
+ char buffer[256];
+ int n;
+
+ //_enter(",,%zu,", buflen);
+
+ if (!test_bit(CACHEFILES_READY, &cache->flags))
+ return 0;
+
+ /* check how much space the cache has */
+ cachefiles_has_space(cache, 0, 0);
+
+ /* summarise */
+ clear_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
+
+ n = snprintf(buffer, sizeof(buffer),
+ "cull=%c"
+ " frun=%llx"
+ " fcull=%llx"
+ " fstop=%llx"
+ " brun=%llx"
+ " bcull=%llx"
+ " bstop=%llx",
+ test_bit(CACHEFILES_CULLING, &cache->flags) ? '1' : '0',
+ (unsigned long long) cache->frun,
+ (unsigned long long) cache->fcull,
+ (unsigned long long) cache->fstop,
+ (unsigned long long) cache->brun,
+ (unsigned long long) cache->bcull,
+ (unsigned long long) cache->bstop
+ );
+
+ if (n > buflen)
+ return -EMSGSIZE;
+
+ if (copy_to_user(_buffer, buffer, n) != 0)
+ return -EFAULT;
+
+ return n;
+}
+
+/*
+ * command the cache
+ */
+static ssize_t cachefiles_daemon_write(struct file *file,
+ const char __user *_data,
+ size_t datalen,
+ loff_t *pos)
+{
+ const struct cachefiles_daemon_cmd *cmd;
+ struct cachefiles_cache *cache = file->private_data;
+ ssize_t ret;
+ char *data, *args, *cp;
+
+ //_enter(",,%zu,", datalen);
+
+ ASSERT(cache);
+
+ if (test_bit(CACHEFILES_DEAD, &cache->flags))
+ return -EIO;
+
+ if (datalen < 0 || datalen > PAGE_SIZE - 1)
+ return -EOPNOTSUPP;
+
+ /* drag the command string into the kernel so we can parse it */
+ data = kmalloc(datalen + 1, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ ret = -EFAULT;
+ if (copy_from_user(data, _data, datalen) != 0)
+ goto error;
+
+ data[datalen] = '\0';
+
+ ret = -EINVAL;
+ if (memchr(data, '\0', datalen))
+ goto error;
+
+ /* strip any newline */
+ cp = memchr(data, '\n', datalen);
+ if (cp) {
+ if (cp == data)
+ goto error;
+
+ *cp = '\0';
+ }
+
+ /* parse the command */
+ ret = -EOPNOTSUPP;
+
+ for (args = data; *args; args++)
+ if (isspace(*args))
+ break;
+ if (*args) {
+ if (args == data)
+ goto error;
+ *args = '\0';
+ for (args++; isspace(*args); args++)
+ continue;
+ }
+
+ /* run the appropriate command handler */
+ for (cmd = cachefiles_daemon_cmds; cmd->name[0]; cmd++)
+ if (strcmp(cmd->name, data) == 0)
+ goto found_command;
+
+error:
+ kfree(data);
+ //_leave(" = %zd", ret);
+ return ret;
+
+found_command:
+ mutex_lock(&cache->daemon_mutex);
+
+ ret = -EIO;
+ if (!test_bit(CACHEFILES_DEAD, &cache->flags))
+ ret = cmd->handler(cache, args);
+
+ mutex_unlock(&cache->daemon_mutex);
+
+ if (ret == 0)
+ ret = datalen;
+ goto error;
+}
+
+/*
+ * poll for culling state
+ * - use POLLOUT to indicate culling state
+ */
+static unsigned int cachefiles_daemon_poll(struct file *file,
+ struct poll_table_struct *poll)
+{
+ struct cachefiles_cache *cache = file->private_data;
+ unsigned int mask;
+
+ poll_wait(file, &cache->daemon_pollwq, poll);
+ mask = 0;
+
+ if (test_bit(CACHEFILES_STATE_CHANGED, &cache->flags))
+ mask |= POLLIN;
+
+ if (test_bit(CACHEFILES_CULLING, &cache->flags))
+ mask |= POLLOUT;
+
+ return mask;
+}
+
+/*
+ * give a range error for cache space constraints
+ * - can be tail-called
+ */
+static int cachefiles_daemon_range_error(struct cachefiles_cache *cache,
+ char *args)
+{
+ kerror("Free space limits must be in range"
+ " 0%%<=stop<cull<run<100%%");
+
+ return -EINVAL;
+}
+
+/*
+ * set the percentage of files at which to stop culling
+ * - command: "frun <N>%"
+ */
+static int cachefiles_daemon_frun(struct cachefiles_cache *cache, char *args)
+{
+ unsigned long frun;
+
+ _enter(",%s", args);
+
+ if (!*args)
+ return -EINVAL;
+
+ frun = simple_strtoul(args, &args, 10);
+ if (args[0] != '%' || args[1] != '\0')
+ return -EINVAL;
+
+ if (frun <= cache->fcull_percent || frun >= 100)
+ return cachefiles_daemon_range_error(cache, args);
+
+ cache->frun_percent = frun;
+ return 0;
+}
+
+/*
+ * set the percentage of files at which to start culling
+ * - command: "fcull <N>%"
+ */
+static int cachefiles_daemon_fcull(struct cachefiles_cache *cache, char *args)
+{
+ unsigned long fcull;
+
+ _enter(",%s", args);
+
+ if (!*args)
+ return -EINVAL;
+
+ fcull = simple_strtoul(args, &args, 10);
+ if (args[0] != '%' || args[1] != '\0')
+ return -EINVAL;
+
+ if (fcull <= cache->fstop_percent || fcull >= cache->frun_percent)
+ return cachefiles_daemon_range_error(cache, args);
+
+ cache->fcull_percent = fcull;
+ return 0;
+}
+
+/*
+ * set the percentage of files at which to stop allocating
+ * - command: "fstop <N>%"
+ */
+static int cachefiles_daemon_fstop(struct cachefiles_cache *cache, char *args)
+{
+ unsigned long fstop;
+
+ _enter(",%s", args);
+
+ if (!*args)
+ return -EINVAL;
+
+ fstop = simple_strtoul(args, &args, 10);
+ if (args[0] != '%' || args[1] != '\0')
+ return -EINVAL;
+
+ if (fstop < 0 || fstop >= cache->fcull_percent)
+ return cachefiles_daemon_range_error(cache, args);
+
+ cache->fstop_percent = fstop;
+ return 0;
+}
+
+/*
+ * set the percentage of blocks at which to stop culling
+ * - command: "brun <N>%"
+ */
+static int cachefiles_daemon_brun(struct cachefiles_cache *cache, char *args)
+{
+ unsigned long brun;
+
+ _enter(",%s", args);
+
+ if (!*args)
+ return -EINVAL;
+
+ brun = simple_strtoul(args, &args, 10);
+ if (args[0] != '%' || args[1] != '\0')
+ return -EINVAL;
+
+ if (brun <= cache->bcull_percent || brun >= 100)
+ return cachefiles_daemon_range_error(cache, args);
+
+ cache->brun_percent = brun;
+ return 0;
+}
+
+/*
+ * set the percentage of blocks at which to start culling
+ * - command: "bcull <N>%"
+ */
+static int cachefiles_daemon_bcull(struct cachefiles_cache *cache, char *args)
+{
+ unsigned long bcull;
+
+ _enter(",%s", args);
+
+ if (!*args)
+ return -EINVAL;
+
+ bcull = simple_strtoul(args, &args, 10);
+ if (args[0] != '%' || args[1] != '\0')
+ return -EINVAL;
+
+ if (bcull <= cache->bstop_percent || bcull >= cache->brun_percent)
+ return cachefiles_daemon_range_error(cache, args);
+
+ cache->bcull_percent = bcull;
+ return 0;
+}
+
+/*
+ * set the percentage of blocks at which to stop allocating
+ * - command: "bstop <N>%"
+ */
+static int cachefiles_daemon_bstop(struct cachefiles_cache *cache, char *args)
+{
+ unsigned long bstop;
+
+ _enter(",%s", args);
+
+ if (!*args)
+ return -EINVAL;
+
+ bstop = simple_strtoul(args, &args, 10);
+ if (args[0] != '%' || args[1] != '\0')
+ return -EINVAL;
+
+ if (bstop < 0 || bstop >= cache->bcull_percent)
+ return cachefiles_daemon_range_error(cache, args);
+
+ cache->bstop_percent = bstop;
+ return 0;
+}
+
+/*
+ * set the cache directory
+ * - command: "dir <name>"
+ */
+static int cachefiles_daemon_dir(struct cachefiles_cache *cache, char *args)
+{
+ char *dir;
+
+ _enter(",%s", args);
+
+ if (!*args) {
+ kerror("Empty directory specified");
+ return -EINVAL;
+ }
+
+ if (cache->rootdirname) {
+ kerror("Second cache directory specified");
+ return -EEXIST;
+ }
+
+ dir = kstrdup(args, GFP_KERNEL);
+ if (!dir)
+ return -ENOMEM;
+
+ cache->rootdirname = dir;
+ return 0;
+}
+
+/*
+ * set the cache security context
+ * - command: "secctx <ctx>"
+ */
+static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
+{
+ char *secctx;
+
+ _enter(",%s", args);
+
+ if (!*args) {
+ kerror("Empty security context specified");
+ return -EINVAL;
+ }
+
+ if (cache->secctx) {
+ kerror("Second security context specified");
+ return -EINVAL;
+ }
+
+ secctx = kstrdup(args, GFP_KERNEL);
+ if (!secctx)
+ return -ENOMEM;
+
+ cache->secctx = secctx;
+ return 0;
+}
+
+/*
+ * set the cache tag
+ * - command: "tag <name>"
+ */
+static int cachefiles_daemon_tag(struct cachefiles_cache *cache, char *args)
+{
+ char *tag;
+
+ _enter(",%s", args);
+
+ if (!*args) {
+ kerror("Empty tag specified");
+ return -EINVAL;
+ }
+
+ if (cache->tag)
+ return -EEXIST;
+
+ tag = kstrdup(args, GFP_KERNEL);
+ if (!tag)
+ return -ENOMEM;
+
+ cache->tag = tag;
+ return 0;
+}
+
+/*
+ * request a node in the cache be culled from the current working directory
+ * - command: "cull <name>"
+ */
+static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args)
+{
+ struct fs_struct *fs;
+ struct dentry *dir;
+ const struct cred *saved_cred;
+ int ret;
+
+ _enter(",%s", args);
+
+ if (strchr(args, '/'))
+ goto inval;
+
+ if (!test_bit(CACHEFILES_READY, &cache->flags)) {
+ kerror("cull applied to unready cache");
+ return -EIO;
+ }
+
+ if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
+ kerror("cull applied to dead cache");
+ return -EIO;
+ }
+
+ /* extract the directory dentry from the cwd */
+ fs = current->fs;
+ read_lock(&fs->lock);
+ dir = dget(fs->pwd.dentry);
+ read_unlock(&fs->lock);
+
+ if (!S_ISDIR(dir->d_inode->i_mode))
+ goto notdir;
+
+ cachefiles_begin_secure(cache, &saved_cred);
+ ret = cachefiles_cull(cache, dir, args);
+ cachefiles_end_secure(cache, saved_cred);
+
+ dput(dir);
+ _leave(" = %d", ret);
+ return ret;
+
+notdir:
+ dput(dir);
+ kerror("cull command requires dirfd to be a directory");
+ return -ENOTDIR;
+
+inval:
+ kerror("cull command requires dirfd and filename");
+ return -EINVAL;
+}
+
+/*
+ * set debugging mode
+ * - command: "debug <mask>"
+ */
+static int cachefiles_daemon_debug(struct cachefiles_cache *cache, char *args)
+{
+ unsigned long mask;
+
+ _enter(",%s", args);
+
+ mask = simple_strtoul(args, &args, 0);
+ if (args[0] != '\0')
+ goto inval;
+
+ cachefiles_debug = mask;
+ _leave(" = 0");
+ return 0;
+
+inval:
+ kerror("debug command requires mask");
+ return -EINVAL;
+}
+
+/*
+ * find out whether an object in the current working directory is in use or not
+ * - command: "inuse <name>"
+ */
+static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args)
+{
+ struct fs_struct *fs;
+ struct dentry *dir;
+ const struct cred *saved_cred;
+ int ret;
+
+ //_enter(",%s", args);
+
+ if (strchr(args, '/'))
+ goto inval;
+
+ if (!test_bit(CACHEFILES_READY, &cache->flags)) {
+ kerror("inuse applied to unready cache");
+ return -EIO;
+ }
+
+ if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
+ kerror("inuse applied to dead cache");
+ return -EIO;
+ }
+
+ /* extract the directory dentry from the cwd */
+ fs = current->fs;
+ read_lock(&fs->lock);
+ dir = dget(fs->pwd.dentry);
+ read_unlock(&fs->lock);
+
+ if (!S_ISDIR(dir->d_inode->i_mode))
+ goto notdir;
+
+ cachefiles_begin_secure(cache, &saved_cred);
+ ret = cachefiles_check_in_use(cache, dir, args);
+ cachefiles_end_secure(cache, saved_cred);
+
+ dput(dir);
+ //_leave(" = %d", ret);
+ return ret;
+
+notdir:
+ dput(dir);
+ kerror("inuse command requires dirfd to be a directory");
+ return -ENOTDIR;
+
+inval:
+ kerror("inuse command requires dirfd and filename");
+ return -EINVAL;
+}
+
+/*
+ * see if we have space for a number of pages and/or a number of files in the
+ * cache
+ */
+int cachefiles_has_space(struct cachefiles_cache *cache,
+ unsigned fnr, unsigned bnr)
+{
+ struct kstatfs stats;
+ int ret;
+
+ //_enter("{%llu,%llu,%llu,%llu,%llu,%llu},%u,%u",
+ // (unsigned long long) cache->frun,
+ // (unsigned long long) cache->fcull,
+ // (unsigned long long) cache->fstop,
+ // (unsigned long long) cache->brun,
+ // (unsigned long long) cache->bcull,
+ // (unsigned long long) cache->bstop,
+ // fnr, bnr);
+
+ /* find out how many pages of blockdev are available */
+ memset(&stats, 0, sizeof(stats));
+
+ ret = vfs_statfs(cache->mnt->mnt_root, &stats);
+ if (ret < 0) {
+ if (ret == -EIO)
+ cachefiles_io_error(cache, "statfs failed");
+ _leave(" = %d", ret);
+ return ret;
+ }
+
+ stats.f_bavail >>= cache->bshift;
+
+ //_debug("avail %llu,%llu",
+ // (unsigned long long) stats.f_ffree,
+ // (unsigned long long) stats.f_bavail);
+
+ /* see if there is sufficient space */
+ if (stats.f_ffree > fnr)
+ stats.f_ffree -= fnr;
+ else
+ stats.f_ffree = 0;
+
+ if (stats.f_bavail > bnr)
+ stats.f_bavail -= bnr;
+ else
+ stats.f_bavail = 0;
+
+ ret = -ENOBUFS;
+ if (stats.f_ffree < cache->fstop ||
+ stats.f_bavail < cache->bstop)
+ goto begin_cull;
+
+ ret = 0;
+ if (stats.f_ffree < cache->fcull ||
+ stats.f_bavail < cache->bcull)
+ goto begin_cull;
+
+ if (test_bit(CACHEFILES_CULLING, &cache->flags) &&
+ stats.f_ffree >= cache->frun &&
+ stats.f_bavail >= cache->brun &&
+ test_and_clear_bit(CACHEFILES_CULLING, &cache->flags)
+ ) {
+ _debug("cease culling");
+ cachefiles_state_changed(cache);
+ }
+
+ //_leave(" = 0");
+ return 0;
+
+begin_cull:
+ if (!test_and_set_bit(CACHEFILES_CULLING, &cache->flags)) {
+ _debug("### CULL CACHE ###");
+ cachefiles_state_changed(cache);
+ }
+
+ _leave(" = %d", ret);
+ return ret;
+}
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
new file mode 100644
index 00000000000..1e962348d11
--- /dev/null
+++ b/fs/cachefiles/interface.c
@@ -0,0 +1,449 @@
+/* FS-Cache interface to CacheFiles
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/mount.h>
+#include <linux/buffer_head.h>
+#include "internal.h"
+
+#define list_to_page(head) (list_entry((head)->prev, struct page, lru))
+
+struct cachefiles_lookup_data {
+ struct cachefiles_xattr *auxdata; /* auxiliary data */
+ char *key; /* key path */
+};
+
+static int cachefiles_attr_changed(struct fscache_object *_object);
+
+/*
+ * allocate an object record for a cookie lookup and prepare the lookup data
+ */
+static struct fscache_object *cachefiles_alloc_object(
+ struct fscache_cache *_cache,
+ struct fscache_cookie *cookie)
+{
+ struct cachefiles_lookup_data *lookup_data;
+ struct cachefiles_object *object;
+ struct cachefiles_cache *cache;
+ struct cachefiles_xattr *auxdata;
+ unsigned keylen, auxlen;
+ void *buffer;
+ char *key;
+
+ cache = container_of(_cache, struct cachefiles_cache, cache);
+
+ _enter("{%s},%p,", cache->cache.identifier, cookie);
+
+ lookup_data = kmalloc(sizeof(*lookup_data), GFP_KERNEL);
+ if (!lookup_data)
+ goto nomem_lookup_data;
+
+ /* create a new object record and a temporary leaf image */
+ object = kmem_cache_alloc(cachefiles_object_jar, GFP_KERNEL);
+ if (!object)
+ goto nomem_object;
+
+ ASSERTCMP(object->backer, ==, NULL);
+
+ BUG_ON(test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags));
+ atomic_set(&object->usage, 1);
+
+ fscache_object_init(&object->fscache, cookie, &cache->cache);
+
+ object->type = cookie->def->type;
+
+ /* get hold of the raw key
+ * - stick the length on the front and leave space on the back for the
+ * encoder
+ */
+ buffer = kmalloc((2 + 512) + 3, GFP_KERNEL);
+ if (!buffer)
+ goto nomem_buffer;
+
+ keylen = cookie->def->get_key(cookie->netfs_data, buffer + 2, 512);
+ ASSERTCMP(keylen, <, 512);
+
+ *(uint16_t *)buffer = keylen;
+ ((char *)buffer)[keylen + 2] = 0;
+ ((char *)buffer)[keylen + 3] = 0;
+ ((char *)buffer)[keylen + 4] = 0;
+
+ /* turn the raw key into something that can work with as a filename */
+ key = cachefiles_cook_key(buffer, keylen + 2, object->type);
+ if (!key)
+ goto nomem_key;
+
+ /* get hold of the auxiliary data and prepend the object type */
+ auxdata = buffer;
+ auxlen = 0;
+ if (cookie->def->get_aux) {
+ auxlen = cookie->def->get_aux(cookie->netfs_data,
+ auxdata->data, 511);
+ ASSERTCMP(auxlen, <, 511);
+ }
+
+ auxdata->len = auxlen + 1;
+ auxdata->type = cookie->def->type;
+
+ lookup_data->auxdata = auxdata;
+ lookup_data->key = key;
+ object->lookup_data = lookup_data;
+
+ _leave(" = %p [%p]", &object->fscache, lookup_data);
+ return &object->fscache;
+
+nomem_key:
+ kfree(buffer);
+nomem_buffer:
+ BUG_ON(test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags));
+ kmem_cache_free(cachefiles_object_jar, object);
+ fscache_object_destroyed(&cache->cache);
+nomem_object:
+ kfree(lookup_data);
+nomem_lookup_data:
+ _leave(" = -ENOMEM");
+ return ERR_PTR(-ENOMEM);
+}
+
+/*
+ * attempt to look up the nominated node in this cache
+ */
+static void cachefiles_lookup_object(struct fscache_object *_object)
+{
+ struct cachefiles_lookup_data *lookup_data;
+ struct cachefiles_object *parent, *object;
+ struct cachefiles_cache *cache;
+ const struct cred *saved_cred;
+ int ret;
+
+ _enter("{OBJ%x}", _object->debug_id);
+
+ cache = container_of(_object->cache, struct cachefiles_cache, cache);
+ parent = container_of(_object->parent,
+ struct cachefiles_object, fscache);
+ object = container_of(_object, struct cachefiles_object, fscache);
+ lookup_data = object->lookup_data;
+
+ ASSERTCMP(lookup_data, !=, NULL);
+
+ /* look up the key, creating any missing bits */
+ cachefiles_begin_secure(cache, &saved_cred);
+ ret = cachefiles_walk_to_object(parent, object,
+ lookup_data->key,
+ lookup_data->auxdata);
+ cachefiles_end_secure(cache, saved_cred);
+
+ /* polish off by setting the attributes of non-index files */
+ if (ret == 0 &&
+ object->fscache.cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX)
+ cachefiles_attr_changed(&object->fscache);
+
+ if (ret < 0) {
+ printk(KERN_WARNING "CacheFiles: Lookup failed error %d\n",
+ ret);
+ fscache_object_lookup_error(&object->fscache);
+ }
+
+ _leave(" [%d]", ret);
+}
+
+/*
+ * indication of lookup completion
+ */
+static void cachefiles_lookup_complete(struct fscache_object *_object)
+{
+ struct cachefiles_object *object;
+
+ object = container_of(_object, struct cachefiles_object, fscache);
+
+ _enter("{OBJ%x,%p}", object->fscache.debug_id, object->lookup_data);
+
+ if (object->lookup_data) {
+ kfree(object->lookup_data->key);
+ kfree(object->lookup_data->auxdata);
+ kfree(object->lookup_data);
+ object->lookup_data = NULL;
+ }
+}
+
+/*
+ * increment the usage count on an inode object (may fail if unmounting)
+ */
+static
+struct fscache_object *cachefiles_grab_object(struct fscache_object *_object)
+{
+ struct cachefiles_object *object =
+ container_of(_object, struct cachefiles_object, fscache);
+
+ _enter("{OBJ%x,%d}", _object->debug_id, atomic_read(&object->usage));
+
+#ifdef CACHEFILES_DEBUG_SLAB
+ ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
+#endif
+
+ atomic_inc(&object->usage);
+ return &object->fscache;
+}
+
+/*
+ * update the auxilliary data for an object object on disk
+ */
+static void cachefiles_update_object(struct fscache_object *_object)
+{
+ struct cachefiles_object *object;
+ struct cachefiles_xattr *auxdata;
+ struct cachefiles_cache *cache;
+ struct fscache_cookie *cookie;
+ const struct cred *saved_cred;
+ unsigned auxlen;
+
+ _enter("{OBJ%x}", _object->debug_id);
+
+ object = container_of(_object, struct cachefiles_object, fscache);
+ cache = container_of(object->fscache.cache, struct cachefiles_cache,
+ cache);
+ cookie = object->fscache.cookie;
+
+ if (!cookie->def->get_aux) {
+ _leave(" [no aux]");
+ return;
+ }
+
+ auxdata = kmalloc(2 + 512 + 3, GFP_KERNEL);
+ if (!auxdata) {
+ _leave(" [nomem]");
+ return;
+ }
+
+ auxlen = cookie->def->get_aux(cookie->netfs_data, auxdata->data, 511);
+ ASSERTCMP(auxlen, <, 511);
+
+ auxdata->len = auxlen + 1;
+ auxdata->type = cookie->def->type;
+
+ cachefiles_begin_secure(cache, &saved_cred);
+ cachefiles_update_object_xattr(object, auxdata);
+ cachefiles_end_secure(cache, saved_cred);
+ kfree(auxdata);
+ _leave("");
+}
+
+/*
+ * discard the resources pinned by an object and effect retirement if
+ * requested
+ */
+static void cachefiles_drop_object(struct fscache_object *_object)
+{
+ struct cachefiles_object *object;
+ struct cachefiles_cache *cache;
+ const struct cred *saved_cred;
+
+ ASSERT(_object);
+
+ object = container_of(_object, struct cachefiles_object, fscache);
+
+ _enter("{OBJ%x,%d}",
+ object->fscache.debug_id, atomic_read(&object->usage));
+
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
+#ifdef CACHEFILES_DEBUG_SLAB
+ ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
+#endif
+
+ /* delete retired objects */
+ if (object->fscache.state == FSCACHE_OBJECT_RECYCLING &&
+ _object != cache->cache.fsdef
+ ) {
+ _debug("- retire object OBJ%x", object->fscache.debug_id);
+ cachefiles_begin_secure(cache, &saved_cred);
+ cachefiles_delete_object(cache, object);
+ cachefiles_end_secure(cache, saved_cred);
+ }
+
+ /* close the filesystem stuff attached to the object */
+ if (object->backer != object->dentry)
+ dput(object->backer);
+ object->backer = NULL;
+
+ /* note that the object is now inactive */
+ if (test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
+ write_lock(&cache->active_lock);
+ if (!test_and_clear_bit(CACHEFILES_OBJECT_ACTIVE,
+ &object->flags))
+ BUG();
+ rb_erase(&object->active_node, &cache->active_nodes);
+ wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE);
+ write_unlock(&cache->active_lock);
+ }
+
+ dput(object->dentry);
+ object->dentry = NULL;
+
+ _leave("");
+}
+
+/*
+ * dispose of a reference to an object
+ */
+static void cachefiles_put_object(struct fscache_object *_object)
+{
+ struct cachefiles_object *object;
+ struct fscache_cache *cache;
+
+ ASSERT(_object);
+
+ object = container_of(_object, struct cachefiles_object, fscache);
+
+ _enter("{OBJ%x,%d}",
+ object->fscache.debug_id, atomic_read(&object->usage));
+
+#ifdef CACHEFILES_DEBUG_SLAB
+ ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
+#endif
+
+ ASSERTIFCMP(object->fscache.parent,
+ object->fscache.parent->n_children, >, 0);
+
+ if (atomic_dec_and_test(&object->usage)) {
+ _debug("- kill object OBJ%x", object->fscache.debug_id);
+
+ ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags));
+ ASSERTCMP(object->fscache.parent, ==, NULL);
+ ASSERTCMP(object->backer, ==, NULL);
+ ASSERTCMP(object->dentry, ==, NULL);
+ ASSERTCMP(object->fscache.n_ops, ==, 0);
+ ASSERTCMP(object->fscache.n_children, ==, 0);
+
+ if (object->lookup_data) {
+ kfree(object->lookup_data->key);
+ kfree(object->lookup_data->auxdata);
+ kfree(object->lookup_data);
+ object->lookup_data = NULL;
+ }
+
+ cache = object->fscache.cache;
+ kmem_cache_free(cachefiles_object_jar, object);
+ fscache_object_destroyed(cache);
+ }
+
+ _leave("");
+}
+
+/*
+ * sync a cache
+ */
+static void cachefiles_sync_cache(struct fscache_cache *_cache)
+{
+ struct cachefiles_cache *cache;
+ const struct cred *saved_cred;
+ int ret;
+
+ _enter("%p", _cache);
+
+ cache = container_of(_cache, struct cachefiles_cache, cache);
+
+ /* make sure all pages pinned by operations on behalf of the netfs are
+ * written to disc */
+ cachefiles_begin_secure(cache, &saved_cred);
+ ret = fsync_super(cache->mnt->mnt_sb);
+ cachefiles_end_secure(cache, saved_cred);
+
+ if (ret == -EIO)
+ cachefiles_io_error(cache,
+ "Attempt to sync backing fs superblock"
+ " returned error %d",
+ ret);
+}
+
+/*
+ * notification the attributes on an object have changed
+ * - called with reads/writes excluded by FS-Cache
+ */
+static int cachefiles_attr_changed(struct fscache_object *_object)
+{
+ struct cachefiles_object *object;
+ struct cachefiles_cache *cache;
+ const struct cred *saved_cred;
+ struct iattr newattrs;
+ uint64_t ni_size;
+ loff_t oi_size;
+ int ret;
+
+ _object->cookie->def->get_attr(_object->cookie->netfs_data, &ni_size);
+
+ _enter("{OBJ%x},[%llu]",
+ _object->debug_id, (unsigned long long) ni_size);
+
+ object = container_of(_object, struct cachefiles_object, fscache);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
+ if (ni_size == object->i_size)
+ return 0;
+
+ if (!object->backer)
+ return -ENOBUFS;
+
+ ASSERT(S_ISREG(object->backer->d_inode->i_mode));
+
+ fscache_set_store_limit(&object->fscache, ni_size);
+
+ oi_size = i_size_read(object->backer->d_inode);
+ if (oi_size == ni_size)
+ return 0;
+
+ newattrs.ia_size = ni_size;
+ newattrs.ia_valid = ATTR_SIZE;
+
+ cachefiles_begin_secure(cache, &saved_cred);
+ mutex_lock(&object->backer->d_inode->i_mutex);
+ ret = notify_change(object->backer, &newattrs);
+ mutex_unlock(&object->backer->d_inode->i_mutex);
+ cachefiles_end_secure(cache, saved_cred);
+
+ if (ret == -EIO) {
+ fscache_set_store_limit(&object->fscache, 0);
+ cachefiles_io_error_obj(object, "Size set failed");
+ ret = -ENOBUFS;
+ }
+
+ _leave(" = %d", ret);
+ return ret;
+}
+
+/*
+ * dissociate a cache from all the pages it was backing
+ */
+static void cachefiles_dissociate_pages(struct fscache_cache *cache)
+{
+ _enter("");
+}
+
+const struct fscache_cache_ops cachefiles_cache_ops = {
+ .name = "cachefiles",
+ .alloc_object = cachefiles_alloc_object,
+ .lookup_object = cachefiles_lookup_object,
+ .lookup_complete = cachefiles_lookup_complete,
+ .grab_object = cachefiles_grab_object,
+ .update_object = cachefiles_update_object,
+ .drop_object = cachefiles_drop_object,
+ .put_object = cachefiles_put_object,
+ .sync_cache = cachefiles_sync_cache,
+ .attr_changed = cachefiles_attr_changed,
+ .read_or_alloc_page = cachefiles_read_or_alloc_page,
+ .read_or_alloc_pages = cachefiles_read_or_alloc_pages,
+ .allocate_page = cachefiles_allocate_page,
+ .allocate_pages = cachefiles_allocate_pages,
+ .write_page = cachefiles_write_page,
+ .uncache_page = cachefiles_uncache_page,
+ .dissociate_pages = cachefiles_dissociate_pages,
+};
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
new file mode 100644
index 00000000000..19218e1463d
--- /dev/null
+++ b/fs/cachefiles/internal.h
@@ -0,0 +1,360 @@
+/* General netfs cache on cache files internal defs
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/fscache-cache.h>
+#include <linux/timer.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/security.h>
+
+struct cachefiles_cache;
+struct cachefiles_object;
+
+extern unsigned cachefiles_debug;
+#define CACHEFILES_DEBUG_KENTER 1
+#define CACHEFILES_DEBUG_KLEAVE 2
+#define CACHEFILES_DEBUG_KDEBUG 4
+
+/*
+ * node records
+ */
+struct cachefiles_object {
+ struct fscache_object fscache; /* fscache handle */
+ struct cachefiles_lookup_data *lookup_data; /* cached lookup data */
+ struct dentry *dentry; /* the file/dir representing this object */
+ struct dentry *backer; /* backing file */
+ loff_t i_size; /* object size */
+ unsigned long flags;
+#define CACHEFILES_OBJECT_ACTIVE 0 /* T if marked active */
+ atomic_t usage; /* object usage count */
+ uint8_t type; /* object type */
+ uint8_t new; /* T if object new */
+ spinlock_t work_lock;
+ struct rb_node active_node; /* link in active tree (dentry is key) */
+};
+
+extern struct kmem_cache *cachefiles_object_jar;
+
+/*
+ * Cache files cache definition
+ */
+struct cachefiles_cache {
+ struct fscache_cache cache; /* FS-Cache record */
+ struct vfsmount *mnt; /* mountpoint holding the cache */
+ struct dentry *graveyard; /* directory into which dead objects go */
+ struct file *cachefilesd; /* manager daemon handle */
+ const struct cred *cache_cred; /* security override for accessing cache */
+ struct mutex daemon_mutex; /* command serialisation mutex */
+ wait_queue_head_t daemon_pollwq; /* poll waitqueue for daemon */
+ struct rb_root active_nodes; /* active nodes (can't be culled) */
+ rwlock_t active_lock; /* lock for active_nodes */
+ atomic_t gravecounter; /* graveyard uniquifier */
+ unsigned frun_percent; /* when to stop culling (% files) */
+ unsigned fcull_percent; /* when to start culling (% files) */
+ unsigned fstop_percent; /* when to stop allocating (% files) */
+ unsigned brun_percent; /* when to stop culling (% blocks) */
+ unsigned bcull_percent; /* when to start culling (% blocks) */
+ unsigned bstop_percent; /* when to stop allocating (% blocks) */
+ unsigned bsize; /* cache's block size */
+ unsigned bshift; /* min(ilog2(PAGE_SIZE / bsize), 0) */
+ uint64_t frun; /* when to stop culling */
+ uint64_t fcull; /* when to start culling */
+ uint64_t fstop; /* when to stop allocating */
+ sector_t brun; /* when to stop culling */
+ sector_t bcull; /* when to start culling */
+ sector_t bstop; /* when to stop allocating */
+ unsigned long flags;
+#define CACHEFILES_READY 0 /* T if cache prepared */
+#define CACHEFILES_DEAD 1 /* T if cache dead */
+#define CACHEFILES_CULLING 2 /* T if cull engaged */
+#define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */
+ char *rootdirname; /* name of cache root directory */
+ char *secctx; /* LSM security context */
+ char *tag; /* cache binding tag */
+};
+
+/*
+ * backing file read tracking
+ */
+struct cachefiles_one_read {
+ wait_queue_t monitor; /* link into monitored waitqueue */
+ struct page *back_page; /* backing file page we're waiting for */
+ struct page *netfs_page; /* netfs page we're going to fill */
+ struct fscache_retrieval *op; /* retrieval op covering this */
+ struct list_head op_link; /* link in op's todo list */
+};
+
+/*
+ * backing file write tracking
+ */
+struct cachefiles_one_write {
+ struct page *netfs_page; /* netfs page to copy */
+ struct cachefiles_object *object;
+ struct list_head obj_link; /* link in object's lists */
+ fscache_rw_complete_t end_io_func;
+ void *context;
+};
+
+/*
+ * auxiliary data xattr buffer
+ */
+struct cachefiles_xattr {
+ uint16_t len;
+ uint8_t type;
+ uint8_t data[];
+};
+
+/*
+ * note change of state for daemon
+ */
+static inline void cachefiles_state_changed(struct cachefiles_cache *cache)
+{
+ set_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
+ wake_up_all(&cache->daemon_pollwq);
+}
+
+/*
+ * cf-bind.c
+ */
+extern int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args);
+extern void cachefiles_daemon_unbind(struct cachefiles_cache *cache);
+
+/*
+ * cf-daemon.c
+ */
+extern const struct file_operations cachefiles_daemon_fops;
+
+extern int cachefiles_has_space(struct cachefiles_cache *cache,
+ unsigned fnr, unsigned bnr);
+
+/*
+ * cf-interface.c
+ */
+extern const struct fscache_cache_ops cachefiles_cache_ops;
+
+/*
+ * cf-key.c
+ */
+extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type);
+
+/*
+ * cf-namei.c
+ */
+extern int cachefiles_delete_object(struct cachefiles_cache *cache,
+ struct cachefiles_object *object);
+extern int cachefiles_walk_to_object(struct cachefiles_object *parent,
+ struct cachefiles_object *object,
+ const char *key,
+ struct cachefiles_xattr *auxdata);
+extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
+ struct dentry *dir,
+ const char *name);
+
+extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
+ char *filename);
+
+extern int cachefiles_check_in_use(struct cachefiles_cache *cache,
+ struct dentry *dir, char *filename);
+
+/*
+ * cf-proc.c
+ */
+#ifdef CONFIG_CACHEFILES_HISTOGRAM
+extern atomic_t cachefiles_lookup_histogram[HZ];
+extern atomic_t cachefiles_mkdir_histogram[HZ];
+extern atomic_t cachefiles_create_histogram[HZ];
+
+extern int __init cachefiles_proc_init(void);
+extern void cachefiles_proc_cleanup(void);
+static inline
+void cachefiles_hist(atomic_t histogram[], unsigned long start_jif)
+{
+ unsigned long jif = jiffies - start_jif;
+ if (jif >= HZ)
+ jif = HZ - 1;
+ atomic_inc(&histogram[jif]);
+}
+
+#else
+#define cachefiles_proc_init() (0)
+#define cachefiles_proc_cleanup() do {} while (0)
+#define cachefiles_hist(hist, start_jif) do {} while (0)
+#endif
+
+/*
+ * cf-rdwr.c
+ */
+extern int cachefiles_read_or_alloc_page(struct fscache_retrieval *,
+ struct page *, gfp_t);
+extern int cachefiles_read_or_alloc_pages(struct fscache_retrieval *,
+ struct list_head *, unsigned *,
+ gfp_t);
+extern int cachefiles_allocate_page(struct fscache_retrieval *, struct page *,
+ gfp_t);
+extern int cachefiles_allocate_pages(struct fscache_retrieval *,
+ struct list_head *, unsigned *, gfp_t);
+extern int cachefiles_write_page(struct fscache_storage *, struct page *);
+extern void cachefiles_uncache_page(struct fscache_object *, struct page *);
+
+/*
+ * cf-security.c
+ */
+extern int cachefiles_get_security_ID(struct cachefiles_cache *cache);
+extern int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
+ struct dentry *root,
+ const struct cred **_saved_cred);
+
+static inline void cachefiles_begin_secure(struct cachefiles_cache *cache,
+ const struct cred **_saved_cred)
+{
+ *_saved_cred = override_creds(cache->cache_cred);
+}
+
+static inline void cachefiles_end_secure(struct cachefiles_cache *cache,
+ const struct cred *saved_cred)
+{
+ revert_creds(saved_cred);
+}
+
+/*
+ * cf-xattr.c
+ */
+extern int cachefiles_check_object_type(struct cachefiles_object *object);
+extern int cachefiles_set_object_xattr(struct cachefiles_object *object,
+ struct cachefiles_xattr *auxdata);
+extern int cachefiles_update_object_xattr(struct cachefiles_object *object,
+ struct cachefiles_xattr *auxdata);
+extern int cachefiles_check_object_xattr(struct cachefiles_object *object,
+ struct cachefiles_xattr *auxdata);
+extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
+ struct dentry *dentry);
+
+
+/*
+ * error handling
+ */
+#define kerror(FMT, ...) printk(KERN_ERR "CacheFiles: "FMT"\n", ##__VA_ARGS__)
+
+#define cachefiles_io_error(___cache, FMT, ...) \
+do { \
+ kerror("I/O Error: " FMT, ##__VA_ARGS__); \
+ fscache_io_error(&(___cache)->cache); \
+ set_bit(CACHEFILES_DEAD, &(___cache)->flags); \
+} while (0)
+
+#define cachefiles_io_error_obj(object, FMT, ...) \
+do { \
+ struct cachefiles_cache *___cache; \
+ \
+ ___cache = container_of((object)->fscache.cache, \
+ struct cachefiles_cache, cache); \
+ cachefiles_io_error(___cache, FMT, ##__VA_ARGS__); \
+} while (0)
+
+
+/*
+ * debug tracing
+ */
+#define dbgprintk(FMT, ...) \
+ printk(KERN_DEBUG "[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
+
+/* make sure we maintain the format strings, even when debugging is disabled */
+static inline void _dbprintk(const char *fmt, ...)
+ __attribute__((format(printf, 1, 2)));
+static inline void _dbprintk(const char *fmt, ...)
+{
+}
+
+#define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
+#define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
+#define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
+
+
+#if defined(__KDEBUG)
+#define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
+#define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
+#define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
+
+#elif defined(CONFIG_CACHEFILES_DEBUG)
+#define _enter(FMT, ...) \
+do { \
+ if (cachefiles_debug & CACHEFILES_DEBUG_KENTER) \
+ kenter(FMT, ##__VA_ARGS__); \
+} while (0)
+
+#define _leave(FMT, ...) \
+do { \
+ if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE) \
+ kleave(FMT, ##__VA_ARGS__); \
+} while (0)
+
+#define _debug(FMT, ...) \
+do { \
+ if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG) \
+ kdebug(FMT, ##__VA_ARGS__); \
+} while (0)
+
+#else
+#define _enter(FMT, ...) _dbprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
+#define _leave(FMT, ...) _dbprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
+#define _debug(FMT, ...) _dbprintk(FMT, ##__VA_ARGS__)
+#endif
+
+#if 1 /* defined(__KDEBUGALL) */
+
+#define ASSERT(X) \
+do { \
+ if (unlikely(!(X))) { \
+ printk(KERN_ERR "\n"); \
+ printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
+ BUG(); \
+ } \
+} while (0)
+
+#define ASSERTCMP(X, OP, Y) \
+do { \
+ if (unlikely(!((X) OP (Y)))) { \
+ printk(KERN_ERR "\n"); \
+ printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
+ printk(KERN_ERR "%lx " #OP " %lx is false\n", \
+ (unsigned long)(X), (unsigned long)(Y)); \
+ BUG(); \
+ } \
+} while (0)
+
+#define ASSERTIF(C, X) \
+do { \
+ if (unlikely((C) && !(X))) { \
+ printk(KERN_ERR "\n"); \
+ printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
+ BUG(); \
+ } \
+} while (0)
+
+#define ASSERTIFCMP(C, X, OP, Y) \
+do { \
+ if (unlikely((C) && !((X) OP (Y)))) { \
+ printk(KERN_ERR "\n"); \
+ printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
+ printk(KERN_ERR "%lx " #OP " %lx is false\n", \
+ (unsigned long)(X), (unsigned long)(Y)); \
+ BUG(); \
+ } \
+} while (0)
+
+#else
+
+#define ASSERT(X) do {} while (0)
+#define ASSERTCMP(X, OP, Y) do {} while (0)
+#define ASSERTIF(C, X) do {} while (0)
+#define ASSERTIFCMP(C, X, OP, Y) do {} while (0)
+
+#endif
diff --git a/fs/cachefiles/key.c b/fs/cachefiles/key.c
new file mode 100644
index 00000000000..81b8b2b3a67
--- /dev/null
+++ b/fs/cachefiles/key.c
@@ -0,0 +1,159 @@
+/* Key to pathname encoder
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/slab.h>
+#include "internal.h"
+
+static const char cachefiles_charmap[64] =
+ "0123456789" /* 0 - 9 */
+ "abcdefghijklmnopqrstuvwxyz" /* 10 - 35 */
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* 36 - 61 */
+ "_-" /* 62 - 63 */
+ ;
+
+static const char cachefiles_filecharmap[256] = {
+ /* we skip space and tab and control chars */
+ [33 ... 46] = 1, /* '!' -> '.' */
+ /* we skip '/' as it's significant to pathwalk */
+ [48 ... 127] = 1, /* '0' -> '~' */
+};
+
+/*
+ * turn the raw key into something cooked
+ * - the raw key should include the length in the two bytes at the front
+ * - the key may be up to 514 bytes in length (including the length word)
+ * - "base64" encode the strange keys, mapping 3 bytes of raw to four of
+ * cooked
+ * - need to cut the cooked key into 252 char lengths (189 raw bytes)
+ */
+char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type)
+{
+ unsigned char csum, ch;
+ unsigned int acc;
+ char *key;
+ int loop, len, max, seg, mark, print;
+
+ _enter(",%d", keylen);
+
+ BUG_ON(keylen < 2 || keylen > 514);
+
+ csum = raw[0] + raw[1];
+ print = 1;
+ for (loop = 2; loop < keylen; loop++) {
+ ch = raw[loop];
+ csum += ch;
+ print &= cachefiles_filecharmap[ch];
+ }
+
+ if (print) {
+ /* if the path is usable ASCII, then we render it directly */
+ max = keylen - 2;
+ max += 2; /* two base64'd length chars on the front */
+ max += 5; /* @checksum/M */
+ max += 3 * 2; /* maximum number of segment dividers (".../M")
+ * is ((514 + 251) / 252) = 3
+ */
+ max += 1; /* NUL on end */
+ } else {
+ /* calculate the maximum length of the cooked key */
+ keylen = (keylen + 2) / 3;
+
+ max = keylen * 4;
+ max += 5; /* @checksum/M */
+ max += 3 * 2; /* maximum number of segment dividers (".../M")
+ * is ((514 + 188) / 189) = 3
+ */
+ max += 1; /* NUL on end */
+ }
+
+ max += 1; /* 2nd NUL on end */
+
+ _debug("max: %d", max);
+
+ key = kmalloc(max, GFP_KERNEL);
+ if (!key)
+ return NULL;
+
+ len = 0;
+
+ /* build the cooked key */
+ sprintf(key, "@%02x%c+", (unsigned) csum, 0);
+ len = 5;
+ mark = len - 1;
+
+ if (print) {
+ acc = *(uint16_t *) raw;
+ raw += 2;
+
+ key[len + 1] = cachefiles_charmap[acc & 63];
+ acc >>= 6;
+ key[len] = cachefiles_charmap[acc & 63];
+ len += 2;
+
+ seg = 250;
+ for (loop = keylen; loop > 0; loop--) {
+ if (seg <= 0) {
+ key[len++] = '\0';
+ mark = len;
+ key[len++] = '+';
+ seg = 252;
+ }
+
+ key[len++] = *raw++;
+ ASSERT(len < max);
+ }
+
+ switch (type) {
+ case FSCACHE_COOKIE_TYPE_INDEX: type = 'I'; break;
+ case FSCACHE_COOKIE_TYPE_DATAFILE: type = 'D'; break;
+ default: type = 'S'; break;
+ }
+ } else {
+ seg = 252;
+ for (loop = keylen; loop > 0; loop--) {
+ if (seg <= 0) {
+ key[len++] = '\0';
+ mark = len;
+ key[len++] = '+';
+ seg = 252;
+ }
+
+ acc = *raw++;
+ acc |= *raw++ << 8;
+ acc |= *raw++ << 16;
+
+ _debug("acc: %06x", acc);
+
+ key[len++] = cachefiles_charmap[acc & 63];
+ acc >>= 6;
+ key[len++] = cachefiles_charmap[acc & 63];
+ acc >>= 6;
+ key[len++] = cachefiles_charmap[acc & 63];
+ acc >>= 6;
+ key[len++] = cachefiles_charmap[acc & 63];
+
+ ASSERT(len < max);
+ }
+
+ switch (type) {
+ case FSCACHE_COOKIE_TYPE_INDEX: type = 'J'; break;
+ case FSCACHE_COOKIE_TYPE_DATAFILE: type = 'E'; break;
+ default: type = 'T'; break;
+ }
+ }
+
+ key[mark] = type;
+ key[len++] = 0;
+ key[len] = 0;
+
+ _leave(" = %p %d", key, len);
+ return key;
+}
diff --git a/fs/cachefiles/main.c b/fs/cachefiles/main.c
new file mode 100644
index 00000000000..4bfa8cf43bf
--- /dev/null
+++ b/fs/cachefiles/main.c
@@ -0,0 +1,106 @@
+/* Network filesystem caching backend to use cache files on a premounted
+ * filesystem
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/statfs.h>
+#include <linux/sysctl.h>
+#include <linux/miscdevice.h>
+#include "internal.h"
+
+unsigned cachefiles_debug;
+module_param_named(debug, cachefiles_debug, uint, S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(cachefiles_debug, "CacheFiles debugging mask");
+
+MODULE_DESCRIPTION("Mounted-filesystem based cache");
+MODULE_AUTHOR("Red Hat, Inc.");
+MODULE_LICENSE("GPL");
+
+struct kmem_cache *cachefiles_object_jar;
+
+static struct miscdevice cachefiles_dev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "cachefiles",
+ .fops = &cachefiles_daemon_fops,
+};
+
+static void cachefiles_object_init_once(void *_object)
+{
+ struct cachefiles_object *object = _object;
+
+ memset(object, 0, sizeof(*object));
+ spin_lock_init(&object->work_lock);
+}
+
+/*
+ * initialise the fs caching module
+ */
+static int __init cachefiles_init(void)
+{
+ int ret;
+
+ ret = misc_register(&cachefiles_dev);
+ if (ret < 0)
+ goto error_dev;
+
+ /* create an object jar */
+ ret = -ENOMEM;
+ cachefiles_object_jar =
+ kmem_cache_create("cachefiles_object_jar",
+ sizeof(struct cachefiles_object),
+ 0,
+ SLAB_HWCACHE_ALIGN,
+ cachefiles_object_init_once);
+ if (!cachefiles_object_jar) {
+ printk(KERN_NOTICE
+ "CacheFiles: Failed to allocate an object jar\n");
+ goto error_object_jar;
+ }
+
+ ret = cachefiles_proc_init();
+ if (ret < 0)
+ goto error_proc;
+
+ printk(KERN_INFO "CacheFiles: Loaded\n");
+ return 0;
+
+error_proc:
+ kmem_cache_destroy(cachefiles_object_jar);
+error_object_jar:
+ misc_deregister(&cachefiles_dev);
+error_dev:
+ kerror("failed to register: %d", ret);
+ return ret;
+}
+
+fs_initcall(cachefiles_init);
+
+/*
+ * clean up on module removal
+ */
+static void __exit cachefiles_exit(void)
+{
+ printk(KERN_INFO "CacheFiles: Unloading\n");
+
+ cachefiles_proc_cleanup();
+ kmem_cache_destroy(cachefiles_object_jar);
+ misc_deregister(&cachefiles_dev);
+}
+
+module_exit(cachefiles_exit);
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
new file mode 100644
index 00000000000..4ce818ae39e
--- /dev/null
+++ b/fs/cachefiles/namei.c
@@ -0,0 +1,771 @@
+/* CacheFiles path walking and related routines
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/fsnotify.h>
+#include <linux/quotaops.h>
+#include <linux/xattr.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/security.h>
+#include "internal.h"
+
+static int cachefiles_wait_bit(void *flags)
+{
+ schedule();
+ return 0;
+}
+
+/*
+ * record the fact that an object is now active
+ */
+static void cachefiles_mark_object_active(struct cachefiles_cache *cache,
+ struct cachefiles_object *object)
+{
+ struct cachefiles_object *xobject;
+ struct rb_node **_p, *_parent = NULL;
+ struct dentry *dentry;
+
+ _enter(",%p", object);
+
+try_again:
+ write_lock(&cache->active_lock);
+
+ if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags))
+ BUG();
+
+ dentry = object->dentry;
+ _p = &cache->active_nodes.rb_node;
+ while (*_p) {
+ _parent = *_p;
+ xobject = rb_entry(_parent,
+ struct cachefiles_object, active_node);
+
+ ASSERT(xobject != object);
+
+ if (xobject->dentry > dentry)
+ _p = &(*_p)->rb_left;
+ else if (xobject->dentry < dentry)
+ _p = &(*_p)->rb_right;
+ else
+ goto wait_for_old_object;
+ }
+
+ rb_link_node(&object->active_node, _parent, _p);
+ rb_insert_color(&object->active_node, &cache->active_nodes);
+
+ write_unlock(&cache->active_lock);
+ _leave("");
+ return;
+
+ /* an old object from a previous incarnation is hogging the slot - we
+ * need to wait for it to be destroyed */
+wait_for_old_object:
+ if (xobject->fscache.state < FSCACHE_OBJECT_DYING) {
+ printk(KERN_ERR "\n");
+ printk(KERN_ERR "CacheFiles: Error:"
+ " Unexpected object collision\n");
+ printk(KERN_ERR "xobject: OBJ%x\n",
+ xobject->fscache.debug_id);
+ printk(KERN_ERR "xobjstate=%s\n",
+ fscache_object_states[xobject->fscache.state]);
+ printk(KERN_ERR "xobjflags=%lx\n", xobject->fscache.flags);
+ printk(KERN_ERR "xobjevent=%lx [%lx]\n",
+ xobject->fscache.events, xobject->fscache.event_mask);
+ printk(KERN_ERR "xops=%u inp=%u exc=%u\n",
+ xobject->fscache.n_ops, xobject->fscache.n_in_progress,
+ xobject->fscache.n_exclusive);
+ printk(KERN_ERR "xcookie=%p [pr=%p nd=%p fl=%lx]\n",
+ xobject->fscache.cookie,
+ xobject->fscache.cookie->parent,
+ xobject->fscache.cookie->netfs_data,
+ xobject->fscache.cookie->flags);
+ printk(KERN_ERR "xparent=%p\n",
+ xobject->fscache.parent);
+ printk(KERN_ERR "object: OBJ%x\n",
+ object->fscache.debug_id);
+ printk(KERN_ERR "cookie=%p [pr=%p nd=%p fl=%lx]\n",
+ object->fscache.cookie,
+ object->fscache.cookie->parent,
+ object->fscache.cookie->netfs_data,
+ object->fscache.cookie->flags);
+ printk(KERN_ERR "parent=%p\n",
+ object->fscache.parent);
+ BUG();
+ }
+ atomic_inc(&xobject->usage);
+ write_unlock(&cache->active_lock);
+
+ _debug(">>> wait");
+ wait_on_bit(&xobject->flags, CACHEFILES_OBJECT_ACTIVE,
+ cachefiles_wait_bit, TASK_UNINTERRUPTIBLE);
+ _debug("<<< waited");
+
+ cache->cache.ops->put_object(&xobject->fscache);
+ goto try_again;
+}
+
+/*
+ * delete an object representation from the cache
+ * - file backed objects are unlinked
+ * - directory backed objects are stuffed into the graveyard for userspace to
+ * delete
+ * - unlocks the directory mutex
+ */
+static int cachefiles_bury_object(struct cachefiles_cache *cache,
+ struct dentry *dir,
+ struct dentry *rep)
+{
+ struct dentry *grave, *trap;
+ char nbuffer[8 + 8 + 1];
+ int ret;
+
+ _enter(",'%*.*s','%*.*s'",
+ dir->d_name.len, dir->d_name.len, dir->d_name.name,
+ rep->d_name.len, rep->d_name.len, rep->d_name.name);
+
+ /* non-directories can just be unlinked */
+ if (!S_ISDIR(rep->d_inode->i_mode)) {
+ _debug("unlink stale object");
+ ret = vfs_unlink(dir->d_inode, rep);
+
+ mutex_unlock(&dir->d_inode->i_mutex);
+
+ if (ret == -EIO)
+ cachefiles_io_error(cache, "Unlink failed");
+
+ _leave(" = %d", ret);
+ return ret;
+ }
+
+ /* directories have to be moved to the graveyard */
+ _debug("move stale object to graveyard");
+ mutex_unlock(&dir->d_inode->i_mutex);
+
+try_again:
+ /* first step is to make up a grave dentry in the graveyard */
+ sprintf(nbuffer, "%08x%08x",
+ (uint32_t) get_seconds(),
+ (uint32_t) atomic_inc_return(&cache->gravecounter));
+
+ /* do the multiway lock magic */
+ trap = lock_rename(cache->graveyard, dir);
+
+ /* do some checks before getting the grave dentry */
+ if (rep->d_parent != dir) {
+ /* the entry was probably culled when we dropped the parent dir
+ * lock */
+ unlock_rename(cache->graveyard, dir);
+ _leave(" = 0 [culled?]");
+ return 0;
+ }
+
+ if (!S_ISDIR(cache->graveyard->d_inode->i_mode)) {
+ unlock_rename(cache->graveyard, dir);
+ cachefiles_io_error(cache, "Graveyard no longer a directory");
+ return -EIO;
+ }
+
+ if (trap == rep) {
+ unlock_rename(cache->graveyard, dir);
+ cachefiles_io_error(cache, "May not make directory loop");
+ return -EIO;
+ }
+
+ if (d_mountpoint(rep)) {
+ unlock_rename(cache->graveyard, dir);
+ cachefiles_io_error(cache, "Mountpoint in cache");
+ return -EIO;
+ }
+
+ grave = lookup_one_len(nbuffer, cache->graveyard, strlen(nbuffer));
+ if (IS_ERR(grave)) {
+ unlock_rename(cache->graveyard, dir);
+
+ if (PTR_ERR(grave) == -ENOMEM) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+ }
+
+ cachefiles_io_error(cache, "Lookup error %ld",
+ PTR_ERR(grave));
+ return -EIO;
+ }
+
+ if (grave->d_inode) {
+ unlock_rename(cache->graveyard, dir);
+ dput(grave);
+ grave = NULL;
+ cond_resched();
+ goto try_again;
+ }
+
+ if (d_mountpoint(grave)) {
+ unlock_rename(cache->graveyard, dir);
+ dput(grave);
+ cachefiles_io_error(cache, "Mountpoint in graveyard");
+ return -EIO;
+ }
+
+ /* target should not be an ancestor of source */
+ if (trap == grave) {
+ unlock_rename(cache->graveyard, dir);
+ dput(grave);
+ cachefiles_io_error(cache, "May not make directory loop");
+ return -EIO;
+ }
+
+ /* attempt the rename */
+ ret = vfs_rename(dir->d_inode, rep, cache->graveyard->d_inode, grave);
+ if (ret != 0 && ret != -ENOMEM)
+ cachefiles_io_error(cache, "Rename failed with error %d", ret);
+
+ unlock_rename(cache->graveyard, dir);
+ dput(grave);
+ _leave(" = 0");
+ return 0;
+}
+
+/*
+ * delete an object representation from the cache
+ */
+int cachefiles_delete_object(struct cachefiles_cache *cache,
+ struct cachefiles_object *object)
+{
+ struct dentry *dir;
+ int ret;
+
+ _enter(",{%p}", object->dentry);
+
+ ASSERT(object->dentry);
+ ASSERT(object->dentry->d_inode);
+ ASSERT(object->dentry->d_parent);
+
+ dir = dget_parent(object->dentry);
+
+ mutex_lock(&dir->d_inode->i_mutex);
+ ret = cachefiles_bury_object(cache, dir, object->dentry);
+
+ dput(dir);
+ _leave(" = %d", ret);
+ return ret;
+}
+
+/*
+ * walk from the parent object to the child object through the backing
+ * filesystem, creating directories as we go
+ */
+int cachefiles_walk_to_object(struct cachefiles_object *parent,
+ struct cachefiles_object *object,
+ const char *key,
+ struct cachefiles_xattr *auxdata)
+{
+ struct cachefiles_cache *cache;
+ struct dentry *dir, *next = NULL;
+ unsigned long start;
+ const char *name;
+ int ret, nlen;
+
+ _enter("{%p},,%s,", parent->dentry, key);
+
+ cache = container_of(parent->fscache.cache,
+ struct cachefiles_cache, cache);
+
+ ASSERT(parent->dentry);
+ ASSERT(parent->dentry->d_inode);
+
+ if (!(S_ISDIR(parent->dentry->d_inode->i_mode))) {
+ // TODO: convert file to dir
+ _leave("looking up in none directory");
+ return -ENOBUFS;
+ }
+
+ dir = dget(parent->dentry);
+
+advance:
+ /* attempt to transit the first directory component */
+ name = key;
+ nlen = strlen(key);
+
+ /* key ends in a double NUL */
+ key = key + nlen + 1;
+ if (!*key)
+ key = NULL;
+
+lookup_again:
+ /* search the current directory for the element name */
+ _debug("lookup '%s'", name);
+
+ mutex_lock(&dir->d_inode->i_mutex);
+
+ start = jiffies;
+ next = lookup_one_len(name, dir, nlen);
+ cachefiles_hist(cachefiles_lookup_histogram, start);
+ if (IS_ERR(next))
+ goto lookup_error;
+
+ _debug("next -> %p %s", next, next->d_inode ? "positive" : "negative");
+
+ if (!key)
+ object->new = !next->d_inode;
+
+ /* if this element of the path doesn't exist, then the lookup phase
+ * failed, and we can release any readers in the certain knowledge that
+ * there's nothing for them to actually read */
+ if (!next->d_inode)
+ fscache_object_lookup_negative(&object->fscache);
+
+ /* we need to create the object if it's negative */
+ if (key || object->type == FSCACHE_COOKIE_TYPE_INDEX) {
+ /* index objects and intervening tree levels must be subdirs */
+ if (!next->d_inode) {
+ ret = cachefiles_has_space(cache, 1, 0);
+ if (ret < 0)
+ goto create_error;
+
+ start = jiffies;
+ ret = vfs_mkdir(dir->d_inode, next, 0);
+ cachefiles_hist(cachefiles_mkdir_histogram, start);
+ if (ret < 0)
+ goto create_error;
+
+ ASSERT(next->d_inode);
+
+ _debug("mkdir -> %p{%p{ino=%lu}}",
+ next, next->d_inode, next->d_inode->i_ino);
+
+ } else if (!S_ISDIR(next->d_inode->i_mode)) {
+ kerror("inode %lu is not a directory",
+ next->d_inode->i_ino);
+ ret = -ENOBUFS;
+ goto error;
+ }
+
+ } else {
+ /* non-index objects start out life as files */
+ if (!next->d_inode) {
+ ret = cachefiles_has_space(cache, 1, 0);
+ if (ret < 0)
+ goto create_error;
+
+ start = jiffies;
+ ret = vfs_create(dir->d_inode, next, S_IFREG, NULL);
+ cachefiles_hist(cachefiles_create_histogram, start);
+ if (ret < 0)
+ goto create_error;
+
+ ASSERT(next->d_inode);
+
+ _debug("create -> %p{%p{ino=%lu}}",
+ next, next->d_inode, next->d_inode->i_ino);
+
+ } else if (!S_ISDIR(next->d_inode->i_mode) &&
+ !S_ISREG(next->d_inode->i_mode)
+ ) {
+ kerror("inode %lu is not a file or directory",
+ next->d_inode->i_ino);
+ ret = -ENOBUFS;
+ goto error;
+ }
+ }
+
+ /* process the next component */
+ if (key) {
+ _debug("advance");
+ mutex_unlock(&dir->d_inode->i_mutex);
+ dput(dir);
+ dir = next;
+ next = NULL;
+ goto advance;
+ }
+
+ /* we've found the object we were looking for */
+ object->dentry = next;
+
+ /* if we've found that the terminal object exists, then we need to
+ * check its attributes and delete it if it's out of date */
+ if (!object->new) {
+ _debug("validate '%*.*s'",
+ next->d_name.len, next->d_name.len, next->d_name.name);
+
+ ret = cachefiles_check_object_xattr(object, auxdata);
+ if (ret == -ESTALE) {
+ /* delete the object (the deleter drops the directory
+ * mutex) */
+ object->dentry = NULL;
+
+ ret = cachefiles_bury_object(cache, dir, next);
+ dput(next);
+ next = NULL;
+
+ if (ret < 0)
+ goto delete_error;
+
+ _debug("redo lookup");
+ goto lookup_again;
+ }
+ }
+
+ /* note that we're now using this object */
+ cachefiles_mark_object_active(cache, object);
+
+ mutex_unlock(&dir->d_inode->i_mutex);
+ dput(dir);
+ dir = NULL;
+
+ _debug("=== OBTAINED_OBJECT ===");
+
+ if (object->new) {
+ /* attach data to a newly constructed terminal object */
+ ret = cachefiles_set_object_xattr(object, auxdata);
+ if (ret < 0)
+ goto check_error;
+ } else {
+ /* always update the atime on an object we've just looked up
+ * (this is used to keep track of culling, and atimes are only
+ * updated by read, write and readdir but not lookup or
+ * open) */
+ touch_atime(cache->mnt, next);
+ }
+
+ /* open a file interface onto a data file */
+ if (object->type != FSCACHE_COOKIE_TYPE_INDEX) {
+ if (S_ISREG(object->dentry->d_inode->i_mode)) {
+ const struct address_space_operations *aops;
+
+ ret = -EPERM;
+ aops = object->dentry->d_inode->i_mapping->a_ops;
+ if (!aops->bmap)
+ goto check_error;
+
+ object->backer = object->dentry;
+ } else {
+ BUG(); // TODO: open file in data-class subdir
+ }
+ }
+
+ object->new = 0;
+ fscache_obtained_object(&object->fscache);
+
+ _leave(" = 0 [%lu]", object->dentry->d_inode->i_ino);
+ return 0;
+
+create_error:
+ _debug("create error %d", ret);
+ if (ret == -EIO)
+ cachefiles_io_error(cache, "Create/mkdir failed");
+ goto error;
+
+check_error:
+ _debug("check error %d", ret);
+ write_lock(&cache->active_lock);
+ rb_erase(&object->active_node, &cache->active_nodes);
+ clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
+ wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE);
+ write_unlock(&cache->active_lock);
+
+ dput(object->dentry);
+ object->dentry = NULL;
+ goto error_out;
+
+delete_error:
+ _debug("delete error %d", ret);
+ goto error_out2;
+
+lookup_error:
+ _debug("lookup error %ld", PTR_ERR(next));
+ ret = PTR_ERR(next);
+ if (ret == -EIO)
+ cachefiles_io_error(cache, "Lookup failed");
+ next = NULL;
+error:
+ mutex_unlock(&dir->d_inode->i_mutex);
+ dput(next);
+error_out2:
+ dput(dir);
+error_out:
+ if (ret == -ENOSPC)
+ ret = -ENOBUFS;
+
+ _leave(" = error %d", -ret);
+ return ret;
+}
+
+/*
+ * get a subdirectory
+ */
+struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
+ struct dentry *dir,
+ const char *dirname)
+{
+ struct dentry *subdir;
+ unsigned long start;
+ int ret;
+
+ _enter(",,%s", dirname);
+
+ /* search the current directory for the element name */
+ mutex_lock(&dir->d_inode->i_mutex);
+
+ start = jiffies;
+ subdir = lookup_one_len(dirname, dir, strlen(dirname));
+ cachefiles_hist(cachefiles_lookup_histogram, start);
+ if (IS_ERR(subdir)) {
+ if (PTR_ERR(subdir) == -ENOMEM)
+ goto nomem_d_alloc;
+ goto lookup_error;
+ }
+
+ _debug("subdir -> %p %s",
+ subdir, subdir->d_inode ? "positive" : "negative");
+
+ /* we need to create the subdir if it doesn't exist yet */
+ if (!subdir->d_inode) {
+ ret = cachefiles_has_space(cache, 1, 0);
+ if (ret < 0)
+ goto mkdir_error;
+
+ _debug("attempt mkdir");
+
+ ret = vfs_mkdir(dir->d_inode, subdir, 0700);
+ if (ret < 0)
+ goto mkdir_error;
+
+ ASSERT(subdir->d_inode);
+
+ _debug("mkdir -> %p{%p{ino=%lu}}",
+ subdir,
+ subdir->d_inode,
+ subdir->d_inode->i_ino);
+ }
+
+ mutex_unlock(&dir->d_inode->i_mutex);
+
+ /* we need to make sure the subdir is a directory */
+ ASSERT(subdir->d_inode);
+
+ if (!S_ISDIR(subdir->d_inode->i_mode)) {
+ kerror("%s is not a directory", dirname);
+ ret = -EIO;
+ goto check_error;
+ }
+
+ ret = -EPERM;
+ if (!subdir->d_inode->i_op ||
+ !subdir->d_inode->i_op->setxattr ||
+ !subdir->d_inode->i_op->getxattr ||
+ !subdir->d_inode->i_op->lookup ||
+ !subdir->d_inode->i_op->mkdir ||
+ !subdir->d_inode->i_op->create ||
+ !subdir->d_inode->i_op->rename ||
+ !subdir->d_inode->i_op->rmdir ||
+ !subdir->d_inode->i_op->unlink)
+ goto check_error;
+
+ _leave(" = [%lu]", subdir->d_inode->i_ino);
+ return subdir;
+
+check_error:
+ dput(subdir);
+ _leave(" = %d [check]", ret);
+ return ERR_PTR(ret);
+
+mkdir_error:
+ mutex_unlock(&dir->d_inode->i_mutex);
+ dput(subdir);
+ kerror("mkdir %s failed with error %d", dirname, ret);
+ return ERR_PTR(ret);
+
+lookup_error:
+ mutex_unlock(&dir->d_inode->i_mutex);
+ ret = PTR_ERR(subdir);
+ kerror("Lookup %s failed with error %d", dirname, ret);
+ return ERR_PTR(ret);
+
+nomem_d_alloc:
+ mutex_unlock(&dir->d_inode->i_mutex);
+ _leave(" = -ENOMEM");
+ return ERR_PTR(-ENOMEM);
+}
+
+/*
+ * find out if an object is in use or not
+ * - if finds object and it's not in use:
+ * - returns a pointer to the object and a reference on it
+ * - returns with the directory locked
+ */
+static struct dentry *cachefiles_check_active(struct cachefiles_cache *cache,
+ struct dentry *dir,
+ char *filename)
+{
+ struct cachefiles_object *object;
+ struct rb_node *_n;
+ struct dentry *victim;
+ unsigned long start;
+ int ret;
+
+ //_enter(",%*.*s/,%s",
+ // dir->d_name.len, dir->d_name.len, dir->d_name.name, filename);
+
+ /* look up the victim */
+ mutex_lock_nested(&dir->d_inode->i_mutex, 1);
+
+ start = jiffies;
+ victim = lookup_one_len(filename, dir, strlen(filename));
+ cachefiles_hist(cachefiles_lookup_histogram, start);
+ if (IS_ERR(victim))
+ goto lookup_error;
+
+ //_debug("victim -> %p %s",
+ // victim, victim->d_inode ? "positive" : "negative");
+
+ /* if the object is no longer there then we probably retired the object
+ * at the netfs's request whilst the cull was in progress
+ */
+ if (!victim->d_inode) {
+ mutex_unlock(&dir->d_inode->i_mutex);
+ dput(victim);
+ _leave(" = -ENOENT [absent]");
+ return ERR_PTR(-ENOENT);
+ }
+
+ /* check to see if we're using this object */
+ read_lock(&cache->active_lock);
+
+ _n = cache->active_nodes.rb_node;
+
+ while (_n) {
+ object = rb_entry(_n, struct cachefiles_object, active_node);
+
+ if (object->dentry > victim)
+ _n = _n->rb_left;
+ else if (object->dentry < victim)
+ _n = _n->rb_right;
+ else
+ goto object_in_use;
+ }
+
+ read_unlock(&cache->active_lock);
+
+ //_leave(" = %p", victim);
+ return victim;
+
+object_in_use:
+ read_unlock(&cache->active_lock);
+ mutex_unlock(&dir->d_inode->i_mutex);
+ dput(victim);
+ //_leave(" = -EBUSY [in use]");
+ return ERR_PTR(-EBUSY);
+
+lookup_error:
+ mutex_unlock(&dir->d_inode->i_mutex);
+ ret = PTR_ERR(victim);
+ if (ret == -ENOENT) {
+ /* file or dir now absent - probably retired by netfs */
+ _leave(" = -ESTALE [absent]");
+ return ERR_PTR(-ESTALE);
+ }
+
+ if (ret == -EIO) {
+ cachefiles_io_error(cache, "Lookup failed");
+ } else if (ret != -ENOMEM) {
+ kerror("Internal error: %d", ret);
+ ret = -EIO;
+ }
+
+ _leave(" = %d", ret);
+ return ERR_PTR(ret);
+}
+
+/*
+ * cull an object if it's not in use
+ * - called only by cache manager daemon
+ */
+int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
+ char *filename)
+{
+ struct dentry *victim;
+ int ret;
+
+ _enter(",%*.*s/,%s",
+ dir->d_name.len, dir->d_name.len, dir->d_name.name, filename);
+
+ victim = cachefiles_check_active(cache, dir, filename);
+ if (IS_ERR(victim))
+ return PTR_ERR(victim);
+
+ _debug("victim -> %p %s",
+ victim, victim->d_inode ? "positive" : "negative");
+
+ /* okay... the victim is not being used so we can cull it
+ * - start by marking it as stale
+ */
+ _debug("victim is cullable");
+
+ ret = cachefiles_remove_object_xattr(cache, victim);
+ if (ret < 0)
+ goto error_unlock;
+
+ /* actually remove the victim (drops the dir mutex) */
+ _debug("bury");
+
+ ret = cachefiles_bury_object(cache, dir, victim);
+ if (ret < 0)
+ goto error;
+
+ dput(victim);
+ _leave(" = 0");
+ return 0;
+
+error_unlock:
+ mutex_unlock(&dir->d_inode->i_mutex);
+error:
+ dput(victim);
+ if (ret == -ENOENT) {
+ /* file or dir now absent - probably retired by netfs */
+ _leave(" = -ESTALE [absent]");
+ return -ESTALE;
+ }
+
+ if (ret != -ENOMEM) {
+ kerror("Internal error: %d", ret);
+ ret = -EIO;
+ }
+
+ _leave(" = %d", ret);
+ return ret;
+}
+
+/*
+ * find out if an object is in use or not
+ * - called only by cache manager daemon
+ * - returns -EBUSY or 0 to indicate whether an object is in use or not
+ */
+int cachefiles_check_in_use(struct cachefiles_cache *cache, struct dentry *dir,
+ char *filename)
+{
+ struct dentry *victim;
+
+ //_enter(",%*.*s/,%s",
+ // dir->d_name.len, dir->d_name.len, dir->d_name.name, filename);
+
+ victim = cachefiles_check_active(cache, dir, filename);
+ if (IS_ERR(victim))
+ return PTR_ERR(victim);
+
+ mutex_unlock(&dir->d_inode->i_mutex);
+ dput(victim);
+ //_leave(" = 0");
+ return 0;
+}
diff --git a/fs/cachefiles/proc.c b/fs/cachefiles/proc.c
new file mode 100644
index 00000000000..eccd3394119
--- /dev/null
+++ b/fs/cachefiles/proc.c
@@ -0,0 +1,134 @@
+/* CacheFiles statistics
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+atomic_t cachefiles_lookup_histogram[HZ];
+atomic_t cachefiles_mkdir_histogram[HZ];
+atomic_t cachefiles_create_histogram[HZ];
+
+/*
+ * display the latency histogram
+ */
+static int cachefiles_histogram_show(struct seq_file *m, void *v)
+{
+ unsigned long index;
+ unsigned x, y, z, t;
+
+ switch ((unsigned long) v) {
+ case 1:
+ seq_puts(m, "JIFS SECS LOOKUPS MKDIRS CREATES\n");
+ return 0;
+ case 2:
+ seq_puts(m, "===== ===== ========= ========= =========\n");
+ return 0;
+ default:
+ index = (unsigned long) v - 3;
+ x = atomic_read(&cachefiles_lookup_histogram[index]);
+ y = atomic_read(&cachefiles_mkdir_histogram[index]);
+ z = atomic_read(&cachefiles_create_histogram[index]);
+ if (x == 0 && y == 0 && z == 0)
+ return 0;
+
+ t = (index * 1000) / HZ;
+
+ seq_printf(m, "%4lu 0.%03u %9u %9u %9u\n", index, t, x, y, z);
+ return 0;
+ }
+}
+
+/*
+ * set up the iterator to start reading from the first line
+ */
+static void *cachefiles_histogram_start(struct seq_file *m, loff_t *_pos)
+{
+ if ((unsigned long long)*_pos >= HZ + 2)
+ return NULL;
+ if (*_pos == 0)
+ *_pos = 1;
+ return (void *)(unsigned long) *_pos;
+}
+
+/*
+ * move to the next line
+ */
+static void *cachefiles_histogram_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ (*pos)++;
+ return (unsigned long long)*pos > HZ + 2 ?
+ NULL : (void *)(unsigned long) *pos;
+}
+
+/*
+ * clean up after reading
+ */
+static void cachefiles_histogram_stop(struct seq_file *m, void *v)
+{
+}
+
+static const struct seq_operations cachefiles_histogram_ops = {
+ .start = cachefiles_histogram_start,
+ .stop = cachefiles_histogram_stop,
+ .next = cachefiles_histogram_next,
+ .show = cachefiles_histogram_show,
+};
+
+/*
+ * open "/proc/fs/cachefiles/XXX" which provide statistics summaries
+ */
+static int cachefiles_histogram_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &cachefiles_histogram_ops);
+}
+
+static const struct file_operations cachefiles_histogram_fops = {
+ .owner = THIS_MODULE,
+ .open = cachefiles_histogram_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+/*
+ * initialise the /proc/fs/cachefiles/ directory
+ */
+int __init cachefiles_proc_init(void)
+{
+ _enter("");
+
+ if (!proc_mkdir("fs/cachefiles", NULL))
+ goto error_dir;
+
+ if (!proc_create("fs/cachefiles/histogram", S_IFREG | 0444, NULL,
+ &cachefiles_histogram_fops))
+ goto error_histogram;
+
+ _leave(" = 0");
+ return 0;
+
+error_histogram:
+ remove_proc_entry("fs/cachefiles", NULL);
+error_dir:
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+}
+
+/*
+ * clean up the /proc/fs/cachefiles/ directory
+ */
+void cachefiles_proc_cleanup(void)
+{
+ remove_proc_entry("fs/cachefiles/histogram", NULL);
+ remove_proc_entry("fs/cachefiles", NULL);
+}
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
new file mode 100644
index 00000000000..a69787e7dd9
--- /dev/null
+++ b/fs/cachefiles/rdwr.c
@@ -0,0 +1,879 @@
+/* Storage object read/write
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/mount.h>
+#include <linux/file.h>
+#include "internal.h"
+
+/*
+ * detect wake up events generated by the unlocking of pages in which we're
+ * interested
+ * - we use this to detect read completion of backing pages
+ * - the caller holds the waitqueue lock
+ */
+static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode,
+ int sync, void *_key)
+{
+ struct cachefiles_one_read *monitor =
+ container_of(wait, struct cachefiles_one_read, monitor);
+ struct cachefiles_object *object;
+ struct wait_bit_key *key = _key;
+ struct page *page = wait->private;
+
+ ASSERT(key);
+
+ _enter("{%lu},%u,%d,{%p,%u}",
+ monitor->netfs_page->index, mode, sync,
+ key->flags, key->bit_nr);
+
+ if (key->flags != &page->flags ||
+ key->bit_nr != PG_locked)
+ return 0;
+
+ _debug("--- monitor %p %lx ---", page, page->flags);
+
+ if (!PageUptodate(page) && !PageError(page))
+ dump_stack();
+
+ /* remove from the waitqueue */
+ list_del(&wait->task_list);
+
+ /* move onto the action list and queue for FS-Cache thread pool */
+ ASSERT(monitor->op);
+
+ object = container_of(monitor->op->op.object,
+ struct cachefiles_object, fscache);
+
+ spin_lock(&object->work_lock);
+ list_add_tail(&monitor->op_link, &monitor->op->to_do);
+ spin_unlock(&object->work_lock);
+
+ fscache_enqueue_retrieval(monitor->op);
+ return 0;
+}
+
+/*
+ * copy data from backing pages to netfs pages to complete a read operation
+ * - driven by FS-Cache's thread pool
+ */
+static void cachefiles_read_copier(struct fscache_operation *_op)
+{
+ struct cachefiles_one_read *monitor;
+ struct cachefiles_object *object;
+ struct fscache_retrieval *op;
+ struct pagevec pagevec;
+ int error, max;
+
+ op = container_of(_op, struct fscache_retrieval, op);
+ object = container_of(op->op.object,
+ struct cachefiles_object, fscache);
+
+ _enter("{ino=%lu}", object->backer->d_inode->i_ino);
+
+ pagevec_init(&pagevec, 0);
+
+ max = 8;
+ spin_lock_irq(&object->work_lock);
+
+ while (!list_empty(&op->to_do)) {
+ monitor = list_entry(op->to_do.next,
+ struct cachefiles_one_read, op_link);
+ list_del(&monitor->op_link);
+
+ spin_unlock_irq(&object->work_lock);
+
+ _debug("- copy {%lu}", monitor->back_page->index);
+
+ error = -EIO;
+ if (PageUptodate(monitor->back_page)) {
+ copy_highpage(monitor->netfs_page, monitor->back_page);
+
+ pagevec_add(&pagevec, monitor->netfs_page);
+ fscache_mark_pages_cached(monitor->op, &pagevec);
+ error = 0;
+ }
+
+ if (error)
+ cachefiles_io_error_obj(
+ object,
+ "Readpage failed on backing file %lx",
+ (unsigned long) monitor->back_page->flags);
+
+ page_cache_release(monitor->back_page);
+
+ fscache_end_io(op, monitor->netfs_page, error);
+ page_cache_release(monitor->netfs_page);
+ fscache_put_retrieval(op);
+ kfree(monitor);
+
+ /* let the thread pool have some air occasionally */
+ max--;
+ if (max < 0 || need_resched()) {
+ if (!list_empty(&op->to_do))
+ fscache_enqueue_retrieval(op);
+ _leave(" [maxed out]");
+ return;
+ }
+
+ spin_lock_irq(&object->work_lock);
+ }
+
+ spin_unlock_irq(&object->work_lock);
+ _leave("");
+}
+
+/*
+ * read the corresponding page to the given set from the backing file
+ * - an uncertain page is simply discarded, to be tried again another time
+ */
+static int cachefiles_read_backing_file_one(struct cachefiles_object *object,
+ struct fscache_retrieval *op,
+ struct page *netpage,
+ struct pagevec *pagevec)
+{
+ struct cachefiles_one_read *monitor;
+ struct address_space *bmapping;
+ struct page *newpage, *backpage;
+ int ret;
+
+ _enter("");
+
+ pagevec_reinit(pagevec);
+
+ _debug("read back %p{%lu,%d}",
+ netpage, netpage->index, page_count(netpage));
+
+ monitor = kzalloc(sizeof(*monitor), GFP_KERNEL);
+ if (!monitor)
+ goto nomem;
+
+ monitor->netfs_page = netpage;
+ monitor->op = fscache_get_retrieval(op);
+
+ init_waitqueue_func_entry(&monitor->monitor, cachefiles_read_waiter);
+
+ /* attempt to get hold of the backing page */
+ bmapping = object->backer->d_inode->i_mapping;
+ newpage = NULL;
+
+ for (;;) {
+ backpage = find_get_page(bmapping, netpage->index);
+ if (backpage)
+ goto backing_page_already_present;
+
+ if (!newpage) {
+ newpage = page_cache_alloc_cold(bmapping);
+ if (!newpage)
+ goto nomem_monitor;
+ }
+
+ ret = add_to_page_cache(newpage, bmapping,
+ netpage->index, GFP_KERNEL);
+ if (ret == 0)
+ goto installed_new_backing_page;
+ if (ret != -EEXIST)
+ goto nomem_page;
+ }
+
+ /* we've installed a new backing page, so now we need to add it
+ * to the LRU list and start it reading */
+installed_new_backing_page:
+ _debug("- new %p", newpage);
+
+ backpage = newpage;
+ newpage = NULL;
+
+ page_cache_get(backpage);
+ pagevec_add(pagevec, backpage);
+ __pagevec_lru_add_file(pagevec);
+
+read_backing_page:
+ ret = bmapping->a_ops->readpage(NULL, backpage);
+ if (ret < 0)
+ goto read_error;
+
+ /* set the monitor to transfer the data across */
+monitor_backing_page:
+ _debug("- monitor add");
+
+ /* install the monitor */
+ page_cache_get(monitor->netfs_page);
+ page_cache_get(backpage);
+ monitor->back_page = backpage;
+ monitor->monitor.private = backpage;
+ add_page_wait_queue(backpage, &monitor->monitor);
+ monitor = NULL;
+
+ /* but the page may have been read before the monitor was installed, so
+ * the monitor may miss the event - so we have to ensure that we do get
+ * one in such a case */
+ if (trylock_page(backpage)) {
+ _debug("jumpstart %p {%lx}", backpage, backpage->flags);
+ unlock_page(backpage);
+ }
+ goto success;
+
+ /* if the backing page is already present, it can be in one of
+ * three states: read in progress, read failed or read okay */
+backing_page_already_present:
+ _debug("- present");
+
+ if (newpage) {
+ page_cache_release(newpage);
+ newpage = NULL;
+ }
+
+ if (PageError(backpage))
+ goto io_error;
+
+ if (PageUptodate(backpage))
+ goto backing_page_already_uptodate;
+
+ if (!trylock_page(backpage))
+ goto monitor_backing_page;
+ _debug("read %p {%lx}", backpage, backpage->flags);
+ goto read_backing_page;
+
+ /* the backing page is already up to date, attach the netfs
+ * page to the pagecache and LRU and copy the data across */
+backing_page_already_uptodate:
+ _debug("- uptodate");
+
+ pagevec_add(pagevec, netpage);
+ fscache_mark_pages_cached(op, pagevec);
+
+ copy_highpage(netpage, backpage);
+ fscache_end_io(op, netpage, 0);
+
+success:
+ _debug("success");
+ ret = 0;
+
+out:
+ if (backpage)
+ page_cache_release(backpage);
+ if (monitor) {
+ fscache_put_retrieval(monitor->op);
+ kfree(monitor);
+ }
+ _leave(" = %d", ret);
+ return ret;
+
+read_error:
+ _debug("read error %d", ret);
+ if (ret == -ENOMEM)
+ goto out;
+io_error:
+ cachefiles_io_error_obj(object, "Page read error on backing file");
+ ret = -ENOBUFS;
+ goto out;
+
+nomem_page:
+ page_cache_release(newpage);
+nomem_monitor:
+ fscache_put_retrieval(monitor->op);
+ kfree(monitor);
+nomem:
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+}
+
+/*
+ * read a page from the cache or allocate a block in which to store it
+ * - cache withdrawal is prevented by the caller
+ * - returns -EINTR if interrupted
+ * - returns -ENOMEM if ran out of memory
+ * - returns -ENOBUFS if no buffers can be made available
+ * - returns -ENOBUFS if page is beyond EOF
+ * - if the page is backed by a block in the cache:
+ * - a read will be started which will call the callback on completion
+ * - 0 will be returned
+ * - else if the page is unbacked:
+ * - the metadata will be retained
+ * - -ENODATA will be returned
+ */
+int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
+ struct page *page,
+ gfp_t gfp)
+{
+ struct cachefiles_object *object;
+ struct cachefiles_cache *cache;
+ struct pagevec pagevec;
+ struct inode *inode;
+ sector_t block0, block;
+ unsigned shift;
+ int ret;
+
+ object = container_of(op->op.object,
+ struct cachefiles_object, fscache);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
+ _enter("{%p},{%lx},,,", object, page->index);
+
+ if (!object->backer)
+ return -ENOBUFS;
+
+ inode = object->backer->d_inode;
+ ASSERT(S_ISREG(inode->i_mode));
+ ASSERT(inode->i_mapping->a_ops->bmap);
+ ASSERT(inode->i_mapping->a_ops->readpages);
+
+ /* calculate the shift required to use bmap */
+ if (inode->i_sb->s_blocksize > PAGE_SIZE)
+ return -ENOBUFS;
+
+ shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
+
+ op->op.flags = FSCACHE_OP_FAST;
+ op->op.processor = cachefiles_read_copier;
+
+ pagevec_init(&pagevec, 0);
+
+ /* we assume the absence or presence of the first block is a good
+ * enough indication for the page as a whole
+ * - TODO: don't use bmap() for this as it is _not_ actually good
+ * enough for this as it doesn't indicate errors, but it's all we've
+ * got for the moment
+ */
+ block0 = page->index;
+ block0 <<= shift;
+
+ block = inode->i_mapping->a_ops->bmap(inode->i_mapping, block0);
+ _debug("%llx -> %llx",
+ (unsigned long long) block0,
+ (unsigned long long) block);
+
+ if (block) {
+ /* submit the apparently valid page to the backing fs to be
+ * read from disk */
+ ret = cachefiles_read_backing_file_one(object, op, page,
+ &pagevec);
+ } else if (cachefiles_has_space(cache, 0, 1) == 0) {
+ /* there's space in the cache we can use */
+ pagevec_add(&pagevec, page);
+ fscache_mark_pages_cached(op, &pagevec);
+ ret = -ENODATA;
+ } else {
+ ret = -ENOBUFS;
+ }
+
+ _leave(" = %d", ret);
+ return ret;
+}
+
+/*
+ * read the corresponding pages to the given set from the backing file
+ * - any uncertain pages are simply discarded, to be tried again another time
+ */
+static int cachefiles_read_backing_file(struct cachefiles_object *object,
+ struct fscache_retrieval *op,
+ struct list_head *list,
+ struct pagevec *mark_pvec)
+{
+ struct cachefiles_one_read *monitor = NULL;
+ struct address_space *bmapping = object->backer->d_inode->i_mapping;
+ struct pagevec lru_pvec;
+ struct page *newpage = NULL, *netpage, *_n, *backpage = NULL;
+ int ret = 0;
+
+ _enter("");
+
+ pagevec_init(&lru_pvec, 0);
+
+ list_for_each_entry_safe(netpage, _n, list, lru) {
+ list_del(&netpage->lru);
+
+ _debug("read back %p{%lu,%d}",
+ netpage, netpage->index, page_count(netpage));
+
+ if (!monitor) {
+ monitor = kzalloc(sizeof(*monitor), GFP_KERNEL);
+ if (!monitor)
+ goto nomem;
+
+ monitor->op = fscache_get_retrieval(op);
+ init_waitqueue_func_entry(&monitor->monitor,
+ cachefiles_read_waiter);
+ }
+
+ for (;;) {
+ backpage = find_get_page(bmapping, netpage->index);
+ if (backpage)
+ goto backing_page_already_present;
+
+ if (!newpage) {
+ newpage = page_cache_alloc_cold(bmapping);
+ if (!newpage)
+ goto nomem;
+ }
+
+ ret = add_to_page_cache(newpage, bmapping,
+ netpage->index, GFP_KERNEL);
+ if (ret == 0)
+ goto installed_new_backing_page;
+ if (ret != -EEXIST)
+ goto nomem;
+ }
+
+ /* we've installed a new backing page, so now we need to add it
+ * to the LRU list and start it reading */
+ installed_new_backing_page:
+ _debug("- new %p", newpage);
+
+ backpage = newpage;
+ newpage = NULL;
+
+ page_cache_get(backpage);
+ if (!pagevec_add(&lru_pvec, backpage))
+ __pagevec_lru_add_file(&lru_pvec);
+
+ reread_backing_page:
+ ret = bmapping->a_ops->readpage(NULL, backpage);
+ if (ret < 0)
+ goto read_error;
+
+ /* add the netfs page to the pagecache and LRU, and set the
+ * monitor to transfer the data across */
+ monitor_backing_page:
+ _debug("- monitor add");
+
+ ret = add_to_page_cache(netpage, op->mapping, netpage->index,
+ GFP_KERNEL);
+ if (ret < 0) {
+ if (ret == -EEXIST) {
+ page_cache_release(netpage);
+ continue;
+ }
+ goto nomem;
+ }
+
+ page_cache_get(netpage);
+ if (!pagevec_add(&lru_pvec, netpage))
+ __pagevec_lru_add_file(&lru_pvec);
+
+ /* install a monitor */
+ page_cache_get(netpage);
+ monitor->netfs_page = netpage;
+
+ page_cache_get(backpage);
+ monitor->back_page = backpage;
+ monitor->monitor.private = backpage;
+ add_page_wait_queue(backpage, &monitor->monitor);
+ monitor = NULL;
+
+ /* but the page may have been read before the monitor was
+ * installed, so the monitor may miss the event - so we have to
+ * ensure that we do get one in such a case */
+ if (trylock_page(backpage)) {
+ _debug("2unlock %p {%lx}", backpage, backpage->flags);
+ unlock_page(backpage);
+ }
+
+ page_cache_release(backpage);
+ backpage = NULL;
+
+ page_cache_release(netpage);
+ netpage = NULL;
+ continue;
+
+ /* if the backing page is already present, it can be in one of
+ * three states: read in progress, read failed or read okay */
+ backing_page_already_present:
+ _debug("- present %p", backpage);
+
+ if (PageError(backpage))
+ goto io_error;
+
+ if (PageUptodate(backpage))
+ goto backing_page_already_uptodate;
+
+ _debug("- not ready %p{%lx}", backpage, backpage->flags);
+
+ if (!trylock_page(backpage))
+ goto monitor_backing_page;
+
+ if (PageError(backpage)) {
+ _debug("error %lx", backpage->flags);
+ unlock_page(backpage);
+ goto io_error;
+ }
+
+ if (PageUptodate(backpage))
+ goto backing_page_already_uptodate_unlock;
+
+ /* we've locked a page that's neither up to date nor erroneous,
+ * so we need to attempt to read it again */
+ goto reread_backing_page;
+
+ /* the backing page is already up to date, attach the netfs
+ * page to the pagecache and LRU and copy the data across */
+ backing_page_already_uptodate_unlock:
+ _debug("uptodate %lx", backpage->flags);
+ unlock_page(backpage);
+ backing_page_already_uptodate:
+ _debug("- uptodate");
+
+ ret = add_to_page_cache(netpage, op->mapping, netpage->index,
+ GFP_KERNEL);
+ if (ret < 0) {
+ if (ret == -EEXIST) {
+ page_cache_release(netpage);
+ continue;
+ }
+ goto nomem;
+ }
+
+ copy_highpage(netpage, backpage);
+
+ page_cache_release(backpage);
+ backpage = NULL;
+
+ if (!pagevec_add(mark_pvec, netpage))
+ fscache_mark_pages_cached(op, mark_pvec);
+
+ page_cache_get(netpage);
+ if (!pagevec_add(&lru_pvec, netpage))
+ __pagevec_lru_add_file(&lru_pvec);
+
+ fscache_end_io(op, netpage, 0);
+ page_cache_release(netpage);
+ netpage = NULL;
+ continue;
+ }
+
+ netpage = NULL;
+
+ _debug("out");
+
+out:
+ /* tidy up */
+ pagevec_lru_add_file(&lru_pvec);
+
+ if (newpage)
+ page_cache_release(newpage);
+ if (netpage)
+ page_cache_release(netpage);
+ if (backpage)
+ page_cache_release(backpage);
+ if (monitor) {
+ fscache_put_retrieval(op);
+ kfree(monitor);
+ }
+
+ list_for_each_entry_safe(netpage, _n, list, lru) {
+ list_del(&netpage->lru);
+ page_cache_release(netpage);
+ }
+
+ _leave(" = %d", ret);
+ return ret;
+
+nomem:
+ _debug("nomem");
+ ret = -ENOMEM;
+ goto out;
+
+read_error:
+ _debug("read error %d", ret);
+ if (ret == -ENOMEM)
+ goto out;
+io_error:
+ cachefiles_io_error_obj(object, "Page read error on backing file");
+ ret = -ENOBUFS;
+ goto out;
+}
+
+/*
+ * read a list of pages from the cache or allocate blocks in which to store
+ * them
+ */
+int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
+ struct list_head *pages,
+ unsigned *nr_pages,
+ gfp_t gfp)
+{
+ struct cachefiles_object *object;
+ struct cachefiles_cache *cache;
+ struct list_head backpages;
+ struct pagevec pagevec;
+ struct inode *inode;
+ struct page *page, *_n;
+ unsigned shift, nrbackpages;
+ int ret, ret2, space;
+
+ object = container_of(op->op.object,
+ struct cachefiles_object, fscache);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
+ _enter("{OBJ%x,%d},,%d,,",
+ object->fscache.debug_id, atomic_read(&op->op.usage),
+ *nr_pages);
+
+ if (!object->backer)
+ return -ENOBUFS;
+
+ space = 1;
+ if (cachefiles_has_space(cache, 0, *nr_pages) < 0)
+ space = 0;
+
+ inode = object->backer->d_inode;
+ ASSERT(S_ISREG(inode->i_mode));
+ ASSERT(inode->i_mapping->a_ops->bmap);
+ ASSERT(inode->i_mapping->a_ops->readpages);
+
+ /* calculate the shift required to use bmap */
+ if (inode->i_sb->s_blocksize > PAGE_SIZE)
+ return -ENOBUFS;
+
+ shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
+
+ pagevec_init(&pagevec, 0);
+
+ op->op.flags = FSCACHE_OP_FAST;
+ op->op.processor = cachefiles_read_copier;
+
+ INIT_LIST_HEAD(&backpages);
+ nrbackpages = 0;
+
+ ret = space ? -ENODATA : -ENOBUFS;
+ list_for_each_entry_safe(page, _n, pages, lru) {
+ sector_t block0, block;
+
+ /* we assume the absence or presence of the first block is a
+ * good enough indication for the page as a whole
+ * - TODO: don't use bmap() for this as it is _not_ actually
+ * good enough for this as it doesn't indicate errors, but
+ * it's all we've got for the moment
+ */
+ block0 = page->index;
+ block0 <<= shift;
+
+ block = inode->i_mapping->a_ops->bmap(inode->i_mapping,
+ block0);
+ _debug("%llx -> %llx",
+ (unsigned long long) block0,
+ (unsigned long long) block);
+
+ if (block) {
+ /* we have data - add it to the list to give to the
+ * backing fs */
+ list_move(&page->lru, &backpages);
+ (*nr_pages)--;
+ nrbackpages++;
+ } else if (space && pagevec_add(&pagevec, page) == 0) {
+ fscache_mark_pages_cached(op, &pagevec);
+ ret = -ENODATA;
+ }
+ }
+
+ if (pagevec_count(&pagevec) > 0)
+ fscache_mark_pages_cached(op, &pagevec);
+
+ if (list_empty(pages))
+ ret = 0;
+
+ /* submit the apparently valid pages to the backing fs to be read from
+ * disk */
+ if (nrbackpages > 0) {
+ ret2 = cachefiles_read_backing_file(object, op, &backpages,
+ &pagevec);
+ if (ret2 == -ENOMEM || ret2 == -EINTR)
+ ret = ret2;
+ }
+
+ if (pagevec_count(&pagevec) > 0)
+ fscache_mark_pages_cached(op, &pagevec);
+
+ _leave(" = %d [nr=%u%s]",
+ ret, *nr_pages, list_empty(pages) ? " empty" : "");
+ return ret;
+}
+
+/*
+ * allocate a block in the cache in which to store a page
+ * - cache withdrawal is prevented by the caller
+ * - returns -EINTR if interrupted
+ * - returns -ENOMEM if ran out of memory
+ * - returns -ENOBUFS if no buffers can be made available
+ * - returns -ENOBUFS if page is beyond EOF
+ * - otherwise:
+ * - the metadata will be retained
+ * - 0 will be returned
+ */
+int cachefiles_allocate_page(struct fscache_retrieval *op,
+ struct page *page,
+ gfp_t gfp)
+{
+ struct cachefiles_object *object;
+ struct cachefiles_cache *cache;
+ struct pagevec pagevec;
+ int ret;
+
+ object = container_of(op->op.object,
+ struct cachefiles_object, fscache);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
+ _enter("%p,{%lx},", object, page->index);
+
+ ret = cachefiles_has_space(cache, 0, 1);
+ if (ret == 0) {
+ pagevec_init(&pagevec, 0);
+ pagevec_add(&pagevec, page);
+ fscache_mark_pages_cached(op, &pagevec);
+ } else {
+ ret = -ENOBUFS;
+ }
+
+ _leave(" = %d", ret);
+ return ret;
+}
+
+/*
+ * allocate blocks in the cache in which to store a set of pages
+ * - cache withdrawal is prevented by the caller
+ * - returns -EINTR if interrupted
+ * - returns -ENOMEM if ran out of memory
+ * - returns -ENOBUFS if some buffers couldn't be made available
+ * - returns -ENOBUFS if some pages are beyond EOF
+ * - otherwise:
+ * - -ENODATA will be returned
+ * - metadata will be retained for any page marked
+ */
+int cachefiles_allocate_pages(struct fscache_retrieval *op,
+ struct list_head *pages,
+ unsigned *nr_pages,
+ gfp_t gfp)
+{
+ struct cachefiles_object *object;
+ struct cachefiles_cache *cache;
+ struct pagevec pagevec;
+ struct page *page;
+ int ret;
+
+ object = container_of(op->op.object,
+ struct cachefiles_object, fscache);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
+ _enter("%p,,,%d,", object, *nr_pages);
+
+ ret = cachefiles_has_space(cache, 0, *nr_pages);
+ if (ret == 0) {
+ pagevec_init(&pagevec, 0);
+
+ list_for_each_entry(page, pages, lru) {
+ if (pagevec_add(&pagevec, page) == 0)
+ fscache_mark_pages_cached(op, &pagevec);
+ }
+
+ if (pagevec_count(&pagevec) > 0)
+ fscache_mark_pages_cached(op, &pagevec);
+ ret = -ENODATA;
+ } else {
+ ret = -ENOBUFS;
+ }
+
+ _leave(" = %d", ret);
+ return ret;
+}
+
+/*
+ * request a page be stored in the cache
+ * - cache withdrawal is prevented by the caller
+ * - this request may be ignored if there's no cache block available, in which
+ * case -ENOBUFS will be returned
+ * - if the op is in progress, 0 will be returned
+ */
+int cachefiles_write_page(struct fscache_storage *op, struct page *page)
+{
+ struct cachefiles_object *object;
+ struct cachefiles_cache *cache;
+ mm_segment_t old_fs;
+ struct file *file;
+ loff_t pos;
+ void *data;
+ int ret;
+
+ ASSERT(op != NULL);
+ ASSERT(page != NULL);
+
+ object = container_of(op->op.object,
+ struct cachefiles_object, fscache);
+
+ _enter("%p,%p{%lx},,,", object, page, page->index);
+
+ if (!object->backer) {
+ _leave(" = -ENOBUFS");
+ return -ENOBUFS;
+ }
+
+ ASSERT(S_ISREG(object->backer->d_inode->i_mode));
+
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
+ /* write the page to the backing filesystem and let it store it in its
+ * own time */
+ dget(object->backer);
+ mntget(cache->mnt);
+ file = dentry_open(object->backer, cache->mnt, O_RDWR,
+ cache->cache_cred);
+ if (IS_ERR(file)) {
+ ret = PTR_ERR(file);
+ } else {
+ ret = -EIO;
+ if (file->f_op->write) {
+ pos = (loff_t) page->index << PAGE_SHIFT;
+ data = kmap(page);
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = file->f_op->write(
+ file, (const void __user *) data, PAGE_SIZE,
+ &pos);
+ set_fs(old_fs);
+ kunmap(page);
+ if (ret != PAGE_SIZE)
+ ret = -EIO;
+ }
+ fput(file);
+ }
+
+ if (ret < 0) {
+ if (ret == -EIO)
+ cachefiles_io_error_obj(
+ object, "Write page to backing file failed");
+ ret = -ENOBUFS;
+ }
+
+ _leave(" = %d", ret);
+ return ret;
+}
+
+/*
+ * detach a backing block from a page
+ * - cache withdrawal is prevented by the caller
+ */
+void cachefiles_uncache_page(struct fscache_object *_object, struct page *page)
+{
+ struct cachefiles_object *object;
+ struct cachefiles_cache *cache;
+
+ object = container_of(_object, struct cachefiles_object, fscache);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
+ _enter("%p,{%lu}", object, page->index);
+
+ spin_unlock(&object->fscache.cookie->lock);
+}
diff --git a/fs/cachefiles/security.c b/fs/cachefiles/security.c
new file mode 100644
index 00000000000..b5808cdb223
--- /dev/null
+++ b/fs/cachefiles/security.c
@@ -0,0 +1,116 @@
+/* CacheFiles security management
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/fs.h>
+#include <linux/cred.h>
+#include "internal.h"
+
+/*
+ * determine the security context within which we access the cache from within
+ * the kernel
+ */
+int cachefiles_get_security_ID(struct cachefiles_cache *cache)
+{
+ struct cred *new;
+ int ret;
+
+ _enter("{%s}", cache->secctx);
+
+ new = prepare_kernel_cred(current);
+ if (!new) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ if (cache->secctx) {
+ ret = set_security_override_from_ctx(new, cache->secctx);
+ if (ret < 0) {
+ put_cred(new);
+ printk(KERN_ERR "CacheFiles:"
+ " Security denies permission to nominate"
+ " security context: error %d\n",
+ ret);
+ goto error;
+ }
+ }
+
+ cache->cache_cred = new;
+ ret = 0;
+error:
+ _leave(" = %d", ret);
+ return ret;
+}
+
+/*
+ * see if mkdir and create can be performed in the root directory
+ */
+static int cachefiles_check_cache_dir(struct cachefiles_cache *cache,
+ struct dentry *root)
+{
+ int ret;
+
+ ret = security_inode_mkdir(root->d_inode, root, 0);
+ if (ret < 0) {
+ printk(KERN_ERR "CacheFiles:"
+ " Security denies permission to make dirs: error %d",
+ ret);
+ return ret;
+ }
+
+ ret = security_inode_create(root->d_inode, root, 0);
+ if (ret < 0)
+ printk(KERN_ERR "CacheFiles:"
+ " Security denies permission to create files: error %d",
+ ret);
+
+ return ret;
+}
+
+/*
+ * check the security details of the on-disk cache
+ * - must be called with security override in force
+ */
+int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
+ struct dentry *root,
+ const struct cred **_saved_cred)
+{
+ struct cred *new;
+ int ret;
+
+ _enter("");
+
+ /* duplicate the cache creds for COW (the override is currently in
+ * force, so we can use prepare_creds() to do this) */
+ new = prepare_creds();
+ if (!new)
+ return -ENOMEM;
+
+ cachefiles_end_secure(cache, *_saved_cred);
+
+ /* use the cache root dir's security context as the basis with
+ * which create files */
+ ret = set_create_files_as(new, root->d_inode);
+ if (ret < 0) {
+ _leave(" = %d [cfa]", ret);
+ return ret;
+ }
+
+ put_cred(cache->cache_cred);
+ cache->cache_cred = new;
+
+ cachefiles_begin_secure(cache, _saved_cred);
+ ret = cachefiles_check_cache_dir(cache, root);
+
+ if (ret == -EOPNOTSUPP)
+ ret = 0;
+ _leave(" = %d", ret);
+ return ret;
+}
diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
new file mode 100644
index 00000000000..f3e7a0bf068
--- /dev/null
+++ b/fs/cachefiles/xattr.c
@@ -0,0 +1,291 @@
+/* CacheFiles extended attribute management
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/fsnotify.h>
+#include <linux/quotaops.h>
+#include <linux/xattr.h>
+#include "internal.h"
+
+static const char cachefiles_xattr_cache[] =
+ XATTR_USER_PREFIX "CacheFiles.cache";
+
+/*
+ * check the type label on an object
+ * - done using xattrs
+ */
+int cachefiles_check_object_type(struct cachefiles_object *object)
+{
+ struct dentry *dentry = object->dentry;
+ char type[3], xtype[3];
+ int ret;
+
+ ASSERT(dentry);
+ ASSERT(dentry->d_inode);
+
+ if (!object->fscache.cookie)
+ strcpy(type, "C3");
+ else
+ snprintf(type, 3, "%02x", object->fscache.cookie->def->type);
+
+ _enter("%p{%s}", object, type);
+
+ /* attempt to install a type label directly */
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2,
+ XATTR_CREATE);
+ if (ret == 0) {
+ _debug("SET"); /* we succeeded */
+ goto error;
+ }
+
+ if (ret != -EEXIST) {
+ kerror("Can't set xattr on %*.*s [%lu] (err %d)",
+ dentry->d_name.len, dentry->d_name.len,
+ dentry->d_name.name, dentry->d_inode->i_ino,
+ -ret);
+ goto error;
+ }
+
+ /* read the current type label */
+ ret = vfs_getxattr(dentry, cachefiles_xattr_cache, xtype, 3);
+ if (ret < 0) {
+ if (ret == -ERANGE)
+ goto bad_type_length;
+
+ kerror("Can't read xattr on %*.*s [%lu] (err %d)",
+ dentry->d_name.len, dentry->d_name.len,
+ dentry->d_name.name, dentry->d_inode->i_ino,
+ -ret);
+ goto error;
+ }
+
+ /* check the type is what we're expecting */
+ if (ret != 2)
+ goto bad_type_length;
+
+ if (xtype[0] != type[0] || xtype[1] != type[1])
+ goto bad_type;
+
+ ret = 0;
+
+error:
+ _leave(" = %d", ret);
+ return ret;
+
+bad_type_length:
+ kerror("Cache object %lu type xattr length incorrect",
+ dentry->d_inode->i_ino);
+ ret = -EIO;
+ goto error;
+
+bad_type:
+ xtype[2] = 0;
+ kerror("Cache object %*.*s [%lu] type %s not %s",
+ dentry->d_name.len, dentry->d_name.len,
+ dentry->d_name.name, dentry->d_inode->i_ino,
+ xtype, type);
+ ret = -EIO;
+ goto error;
+}
+
+/*
+ * set the state xattr on a cache file
+ */
+int cachefiles_set_object_xattr(struct cachefiles_object *object,
+ struct cachefiles_xattr *auxdata)
+{
+ struct dentry *dentry = object->dentry;
+ int ret;
+
+ ASSERT(object->fscache.cookie);
+ ASSERT(dentry);
+
+ _enter("%p,#%d", object, auxdata->len);
+
+ /* attempt to install the cache metadata directly */
+ _debug("SET %s #%u", object->fscache.cookie->def->name, auxdata->len);
+
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_CREATE);
+ if (ret < 0 && ret != -ENOMEM)
+ cachefiles_io_error_obj(
+ object,
+ "Failed to set xattr with error %d", ret);
+
+ _leave(" = %d", ret);
+ return ret;
+}
+
+/*
+ * update the state xattr on a cache file
+ */
+int cachefiles_update_object_xattr(struct cachefiles_object *object,
+ struct cachefiles_xattr *auxdata)
+{
+ struct dentry *dentry = object->dentry;
+ int ret;
+
+ ASSERT(object->fscache.cookie);
+ ASSERT(dentry);
+
+ _enter("%p,#%d", object, auxdata->len);
+
+ /* attempt to install the cache metadata directly */
+ _debug("SET %s #%u", object->fscache.cookie->def->name, auxdata->len);
+
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_REPLACE);
+ if (ret < 0 && ret != -ENOMEM)
+ cachefiles_io_error_obj(
+ object,
+ "Failed to update xattr with error %d", ret);
+
+ _leave(" = %d", ret);
+ return ret;
+}
+
+/*
+ * check the state xattr on a cache file
+ * - return -ESTALE if the object should be deleted
+ */
+int cachefiles_check_object_xattr(struct cachefiles_object *object,
+ struct cachefiles_xattr *auxdata)
+{
+ struct cachefiles_xattr *auxbuf;
+ struct dentry *dentry = object->dentry;
+ int ret;
+
+ _enter("%p,#%d", object, auxdata->len);
+
+ ASSERT(dentry);
+ ASSERT(dentry->d_inode);
+
+ auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, GFP_KERNEL);
+ if (!auxbuf) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+ }
+
+ /* read the current type label */
+ ret = vfs_getxattr(dentry, cachefiles_xattr_cache,
+ &auxbuf->type, 512 + 1);
+ if (ret < 0) {
+ if (ret == -ENODATA)
+ goto stale; /* no attribute - power went off
+ * mid-cull? */
+
+ if (ret == -ERANGE)
+ goto bad_type_length;
+
+ cachefiles_io_error_obj(object,
+ "Can't read xattr on %lu (err %d)",
+ dentry->d_inode->i_ino, -ret);
+ goto error;
+ }
+
+ /* check the on-disk object */
+ if (ret < 1)
+ goto bad_type_length;
+
+ if (auxbuf->type != auxdata->type)
+ goto stale;
+
+ auxbuf->len = ret;
+
+ /* consult the netfs */
+ if (object->fscache.cookie->def->check_aux) {
+ enum fscache_checkaux result;
+ unsigned int dlen;
+
+ dlen = auxbuf->len - 1;
+
+ _debug("checkaux %s #%u",
+ object->fscache.cookie->def->name, dlen);
+
+ result = fscache_check_aux(&object->fscache,
+ &auxbuf->data, dlen);
+
+ switch (result) {
+ /* entry okay as is */
+ case FSCACHE_CHECKAUX_OKAY:
+ goto okay;
+
+ /* entry requires update */
+ case FSCACHE_CHECKAUX_NEEDS_UPDATE:
+ break;
+
+ /* entry requires deletion */
+ case FSCACHE_CHECKAUX_OBSOLETE:
+ goto stale;
+
+ default:
+ BUG();
+ }
+
+ /* update the current label */
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_REPLACE);
+ if (ret < 0) {
+ cachefiles_io_error_obj(object,
+ "Can't update xattr on %lu"
+ " (error %d)",
+ dentry->d_inode->i_ino, -ret);
+ goto error;
+ }
+ }
+
+okay:
+ ret = 0;
+
+error:
+ kfree(auxbuf);
+ _leave(" = %d", ret);
+ return ret;
+
+bad_type_length:
+ kerror("Cache object %lu xattr length incorrect",
+ dentry->d_inode->i_ino);
+ ret = -EIO;
+ goto error;
+
+stale:
+ ret = -ESTALE;
+ goto error;
+}
+
+/*
+ * remove the object's xattr to mark it stale
+ */
+int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
+ struct dentry *dentry)
+{
+ int ret;
+
+ ret = vfs_removexattr(dentry, cachefiles_xattr_cache);
+ if (ret < 0) {
+ if (ret == -ENOENT || ret == -ENODATA)
+ ret = 0;
+ else if (ret != -ENOMEM)
+ cachefiles_io_error(cache,
+ "Can't remove xattr from %lu"
+ " (error %d)",
+ dentry->d_inode->i_ino, -ret);
+ }
+
+ _leave(" = %d", ret);
+ return ret;
+}
diff --git a/fs/compat.c b/fs/compat.c
index 1c859dae758..3f84d5f1588 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1236,7 +1236,7 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec,
asmlinkage ssize_t
compat_sys_preadv(unsigned long fd, const struct compat_iovec __user *vec,
- unsigned long vlen, u32 pos_high, u32 pos_low)
+ unsigned long vlen, u32 pos_low, u32 pos_high)
{
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
struct file *file;
@@ -1293,7 +1293,7 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec,
asmlinkage ssize_t
compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec,
- unsigned long vlen, u32 pos_high, u32 pos_low)
+ unsigned long vlen, u32 pos_low, u32 pos_high)
{
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
struct file *file;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index ff786687e93..3e87ce443ea 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -23,7 +23,7 @@
#include <linux/if.h>
#include <linux/if_bridge.h>
#include <linux/slab.h>
-#include <linux/raid/md.h>
+#include <linux/raid/md_u.h>
#include <linux/kd.h>
#include <linux/route.h>
#include <linux/in6.h>
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 81ae9ea3c6e..0662ba6de85 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -30,6 +30,7 @@
static struct vfsmount *debugfs_mount;
static int debugfs_mount_count;
+static bool debugfs_registered;
static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev)
{
@@ -496,6 +497,16 @@ exit:
}
EXPORT_SYMBOL_GPL(debugfs_rename);
+/**
+ * debugfs_initialized - Tells whether debugfs has been registered
+ */
+bool debugfs_initialized(void)
+{
+ return debugfs_registered;
+}
+EXPORT_SYMBOL_GPL(debugfs_initialized);
+
+
static struct kobject *debug_kobj;
static int __init debugfs_init(void)
@@ -509,11 +520,16 @@ static int __init debugfs_init(void)
retval = register_filesystem(&debug_fs_type);
if (retval)
kobject_put(debug_kobj);
+ else
+ debugfs_registered = true;
+
return retval;
}
static void __exit debugfs_exit(void)
{
+ debugfs_registered = false;
+
simple_release_fs(&debugfs_mount, &debugfs_mount_count);
unregister_filesystem(&debug_fs_type);
kobject_put(debug_kobj);
diff --git a/fs/direct-io.c b/fs/direct-io.c
index b6d43908ff7..da258e7249c 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -1126,7 +1126,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
int acquire_i_mutex = 0;
if (rw & WRITE)
- rw = WRITE_SYNC;
+ rw = WRITE_ODIRECT;
if (bdev)
bdev_blkbits = blksize_bits(bdev_hardsect_size(bdev));
diff --git a/fs/exofs/BUGS b/fs/exofs/BUGS
new file mode 100644
index 00000000000..1b2d4c63a57
--- /dev/null
+++ b/fs/exofs/BUGS
@@ -0,0 +1,3 @@
+- Out-of-space may cause a severe problem if the object (and directory entry)
+ were written, but the inode attributes failed. Then if the filesystem was
+ unmounted and mounted the kernel can get into an endless loop doing a readdir.
diff --git a/fs/exofs/Kbuild b/fs/exofs/Kbuild
new file mode 100644
index 00000000000..cc2d22db119
--- /dev/null
+++ b/fs/exofs/Kbuild
@@ -0,0 +1,16 @@
+#
+# Kbuild for the EXOFS module
+#
+# Copyright (C) 2008 Panasas Inc. All rights reserved.
+#
+# Authors:
+# Boaz Harrosh <bharrosh@panasas.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
+#
+# Kbuild - Gets included from the Kernels Makefile and build system
+#
+
+exofs-y := osd.o inode.o file.o symlink.o namei.o dir.o super.o
+obj-$(CONFIG_EXOFS_FS) += exofs.o
diff --git a/fs/exofs/Kconfig b/fs/exofs/Kconfig
new file mode 100644
index 00000000000..86194b2f799
--- /dev/null
+++ b/fs/exofs/Kconfig
@@ -0,0 +1,13 @@
+config EXOFS_FS
+ tristate "exofs: OSD based file system support"
+ depends on SCSI_OSD_ULD
+ help
+ EXOFS is a file system that uses an OSD storage device,
+ as its backing storage.
+
+# Debugging-related stuff
+config EXOFS_DEBUG
+ bool "Enable debugging"
+ depends on EXOFS_FS
+ help
+ This option enables EXOFS debug prints.
diff --git a/fs/exofs/common.h b/fs/exofs/common.h
new file mode 100644
index 00000000000..b1512c4bb8c
--- /dev/null
+++ b/fs/exofs/common.h
@@ -0,0 +1,184 @@
+/*
+ * common.h - Common definitions for both Kernel and user-mode utilities
+ *
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ * from
+ * linux/fs/minix/inode.c
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs 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. Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs 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 exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __EXOFS_COM_H__
+#define __EXOFS_COM_H__
+
+#include <linux/types.h>
+
+#include <scsi/osd_attributes.h>
+#include <scsi/osd_initiator.h>
+#include <scsi/osd_sec.h>
+
+/****************************************************************************
+ * Object ID related defines
+ * NOTE: inode# = object ID - EXOFS_OBJ_OFF
+ ****************************************************************************/
+#define EXOFS_MIN_PID 0x10000 /* Smallest partition ID */
+#define EXOFS_OBJ_OFF 0x10000 /* offset for objects */
+#define EXOFS_SUPER_ID 0x10000 /* object ID for on-disk superblock */
+#define EXOFS_ROOT_ID 0x10002 /* object ID for root directory */
+
+/* exofs Application specific page/attribute */
+# define EXOFS_APAGE_FS_DATA (OSD_APAGE_APP_DEFINED_FIRST + 3)
+# define EXOFS_ATTR_INODE_DATA 1
+
+/*
+ * The maximum number of files we can have is limited by the size of the
+ * inode number. This is the largest object ID that the file system supports.
+ * Object IDs 0, 1, and 2 are always in use (see above defines).
+ */
+enum {
+ EXOFS_MAX_INO_ID = (sizeof(ino_t) * 8 == 64) ? ULLONG_MAX :
+ (1ULL << (sizeof(ino_t) * 8ULL - 1ULL)),
+ EXOFS_MAX_ID = (EXOFS_MAX_INO_ID - 1 - EXOFS_OBJ_OFF),
+};
+
+/****************************************************************************
+ * Misc.
+ ****************************************************************************/
+#define EXOFS_BLKSHIFT 12
+#define EXOFS_BLKSIZE (1UL << EXOFS_BLKSHIFT)
+
+/****************************************************************************
+ * superblock-related things
+ ****************************************************************************/
+#define EXOFS_SUPER_MAGIC 0x5DF5
+
+/*
+ * The file system control block - stored in an object's data (mainly, the one
+ * with ID EXOFS_SUPER_ID). This is where the in-memory superblock is stored
+ * on disk. Right now it just has a magic value, which is basically a sanity
+ * check on our ability to communicate with the object store.
+ */
+struct exofs_fscb {
+ __le64 s_nextid; /* Highest object ID used */
+ __le32 s_numfiles; /* Number of files on fs */
+ __le16 s_magic; /* Magic signature */
+ __le16 s_newfs; /* Non-zero if this is a new fs */
+};
+
+/****************************************************************************
+ * inode-related things
+ ****************************************************************************/
+#define EXOFS_IDATA 5
+
+/*
+ * The file control block - stored in an object's attributes. This is where
+ * the in-memory inode is stored on disk.
+ */
+struct exofs_fcb {
+ __le64 i_size; /* Size of the file */
+ __le16 i_mode; /* File mode */
+ __le16 i_links_count; /* Links count */
+ __le32 i_uid; /* Owner Uid */
+ __le32 i_gid; /* Group Id */
+ __le32 i_atime; /* Access time */
+ __le32 i_ctime; /* Creation time */
+ __le32 i_mtime; /* Modification time */
+ __le32 i_flags; /* File flags (unused for now)*/
+ __le32 i_generation; /* File version (for NFS) */
+ __le32 i_data[EXOFS_IDATA]; /* Short symlink names and device #s */
+};
+
+#define EXOFS_INO_ATTR_SIZE sizeof(struct exofs_fcb)
+
+/* This is the Attribute the fcb is stored in */
+static const struct __weak osd_attr g_attr_inode_data = ATTR_DEF(
+ EXOFS_APAGE_FS_DATA,
+ EXOFS_ATTR_INODE_DATA,
+ EXOFS_INO_ATTR_SIZE);
+
+/****************************************************************************
+ * dentry-related things
+ ****************************************************************************/
+#define EXOFS_NAME_LEN 255
+
+/*
+ * The on-disk directory entry
+ */
+struct exofs_dir_entry {
+ __le64 inode_no; /* inode number */
+ __le16 rec_len; /* directory entry length */
+ u8 name_len; /* name length */
+ u8 file_type; /* umm...file type */
+ char name[EXOFS_NAME_LEN]; /* file name */
+};
+
+enum {
+ EXOFS_FT_UNKNOWN,
+ EXOFS_FT_REG_FILE,
+ EXOFS_FT_DIR,
+ EXOFS_FT_CHRDEV,
+ EXOFS_FT_BLKDEV,
+ EXOFS_FT_FIFO,
+ EXOFS_FT_SOCK,
+ EXOFS_FT_SYMLINK,
+ EXOFS_FT_MAX
+};
+
+#define EXOFS_DIR_PAD 4
+#define EXOFS_DIR_ROUND (EXOFS_DIR_PAD - 1)
+#define EXOFS_DIR_REC_LEN(name_len) \
+ (((name_len) + offsetof(struct exofs_dir_entry, name) + \
+ EXOFS_DIR_ROUND) & ~EXOFS_DIR_ROUND)
+
+/*************************
+ * function declarations *
+ *************************/
+/* osd.c */
+void exofs_make_credential(u8 cred_a[OSD_CAP_LEN],
+ const struct osd_obj_id *obj);
+
+int exofs_check_ok_resid(struct osd_request *or, u64 *in_resid, u64 *out_resid);
+static inline int exofs_check_ok(struct osd_request *or)
+{
+ return exofs_check_ok_resid(or, NULL, NULL);
+}
+int exofs_sync_op(struct osd_request *or, int timeout, u8 *cred);
+int exofs_async_op(struct osd_request *or,
+ osd_req_done_fn *async_done, void *caller_context, u8 *cred);
+
+int extract_attr_from_req(struct osd_request *or, struct osd_attr *attr);
+
+int osd_req_read_kern(struct osd_request *or,
+ const struct osd_obj_id *obj, u64 offset, void *buff, u64 len);
+
+int osd_req_write_kern(struct osd_request *or,
+ const struct osd_obj_id *obj, u64 offset, void *buff, u64 len);
+
+#endif /*ifndef __EXOFS_COM_H__*/
diff --git a/fs/exofs/dir.c b/fs/exofs/dir.c
new file mode 100644
index 00000000000..65b0c8c776a
--- /dev/null
+++ b/fs/exofs/dir.c
@@ -0,0 +1,672 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ * from
+ * linux/fs/minix/inode.c
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs 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. Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs 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 exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "exofs.h"
+
+static inline unsigned exofs_chunk_size(struct inode *inode)
+{
+ return inode->i_sb->s_blocksize;
+}
+
+static inline void exofs_put_page(struct page *page)
+{
+ kunmap(page);
+ page_cache_release(page);
+}
+
+/* Accesses dir's inode->i_size must be called under inode lock */
+static inline unsigned long dir_pages(struct inode *inode)
+{
+ return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+}
+
+static unsigned exofs_last_byte(struct inode *inode, unsigned long page_nr)
+{
+ loff_t last_byte = inode->i_size;
+
+ last_byte -= page_nr << PAGE_CACHE_SHIFT;
+ if (last_byte > PAGE_CACHE_SIZE)
+ last_byte = PAGE_CACHE_SIZE;
+ return last_byte;
+}
+
+static int exofs_commit_chunk(struct page *page, loff_t pos, unsigned len)
+{
+ struct address_space *mapping = page->mapping;
+ struct inode *dir = mapping->host;
+ int err = 0;
+
+ dir->i_version++;
+
+ if (!PageUptodate(page))
+ SetPageUptodate(page);
+
+ if (pos+len > dir->i_size) {
+ i_size_write(dir, pos+len);
+ mark_inode_dirty(dir);
+ }
+ set_page_dirty(page);
+
+ if (IS_DIRSYNC(dir))
+ err = write_one_page(page, 1);
+ else
+ unlock_page(page);
+
+ return err;
+}
+
+static void exofs_check_page(struct page *page)
+{
+ struct inode *dir = page->mapping->host;
+ unsigned chunk_size = exofs_chunk_size(dir);
+ char *kaddr = page_address(page);
+ unsigned offs, rec_len;
+ unsigned limit = PAGE_CACHE_SIZE;
+ struct exofs_dir_entry *p;
+ char *error;
+
+ /* if the page is the last one in the directory */
+ if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
+ limit = dir->i_size & ~PAGE_CACHE_MASK;
+ if (limit & (chunk_size - 1))
+ goto Ebadsize;
+ if (!limit)
+ goto out;
+ }
+ for (offs = 0; offs <= limit - EXOFS_DIR_REC_LEN(1); offs += rec_len) {
+ p = (struct exofs_dir_entry *)(kaddr + offs);
+ rec_len = le16_to_cpu(p->rec_len);
+
+ if (rec_len < EXOFS_DIR_REC_LEN(1))
+ goto Eshort;
+ if (rec_len & 3)
+ goto Ealign;
+ if (rec_len < EXOFS_DIR_REC_LEN(p->name_len))
+ goto Enamelen;
+ if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
+ goto Espan;
+ }
+ if (offs != limit)
+ goto Eend;
+out:
+ SetPageChecked(page);
+ return;
+
+Ebadsize:
+ EXOFS_ERR("ERROR [exofs_check_page]: "
+ "size of directory #%lu is not a multiple of chunk size",
+ dir->i_ino
+ );
+ goto fail;
+Eshort:
+ error = "rec_len is smaller than minimal";
+ goto bad_entry;
+Ealign:
+ error = "unaligned directory entry";
+ goto bad_entry;
+Enamelen:
+ error = "rec_len is too small for name_len";
+ goto bad_entry;
+Espan:
+ error = "directory entry across blocks";
+ goto bad_entry;
+bad_entry:
+ EXOFS_ERR(
+ "ERROR [exofs_check_page]: bad entry in directory #%lu: %s - "
+ "offset=%lu, inode=%llu, rec_len=%d, name_len=%d",
+ dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
+ _LLU(le64_to_cpu(p->inode_no)),
+ rec_len, p->name_len);
+ goto fail;
+Eend:
+ p = (struct exofs_dir_entry *)(kaddr + offs);
+ EXOFS_ERR("ERROR [exofs_check_page]: "
+ "entry in directory #%lu spans the page boundary"
+ "offset=%lu, inode=%llu",
+ dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
+ _LLU(le64_to_cpu(p->inode_no)));
+fail:
+ SetPageChecked(page);
+ SetPageError(page);
+}
+
+static struct page *exofs_get_page(struct inode *dir, unsigned long n)
+{
+ 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))
+ exofs_check_page(page);
+ if (PageError(page))
+ goto fail;
+ }
+ return page;
+
+fail:
+ exofs_put_page(page);
+ return ERR_PTR(-EIO);
+}
+
+static inline int exofs_match(int len, const unsigned char *name,
+ struct exofs_dir_entry *de)
+{
+ if (len != de->name_len)
+ return 0;
+ if (!de->inode_no)
+ return 0;
+ return !memcmp(name, de->name, len);
+}
+
+static inline
+struct exofs_dir_entry *exofs_next_entry(struct exofs_dir_entry *p)
+{
+ return (struct exofs_dir_entry *)((char *)p + le16_to_cpu(p->rec_len));
+}
+
+static inline unsigned
+exofs_validate_entry(char *base, unsigned offset, unsigned mask)
+{
+ struct exofs_dir_entry *de = (struct exofs_dir_entry *)(base + offset);
+ struct exofs_dir_entry *p =
+ (struct exofs_dir_entry *)(base + (offset&mask));
+ while ((char *)p < (char *)de) {
+ if (p->rec_len == 0)
+ break;
+ p = exofs_next_entry(p);
+ }
+ return (char *)p - base;
+}
+
+static unsigned char exofs_filetype_table[EXOFS_FT_MAX] = {
+ [EXOFS_FT_UNKNOWN] = DT_UNKNOWN,
+ [EXOFS_FT_REG_FILE] = DT_REG,
+ [EXOFS_FT_DIR] = DT_DIR,
+ [EXOFS_FT_CHRDEV] = DT_CHR,
+ [EXOFS_FT_BLKDEV] = DT_BLK,
+ [EXOFS_FT_FIFO] = DT_FIFO,
+ [EXOFS_FT_SOCK] = DT_SOCK,
+ [EXOFS_FT_SYMLINK] = DT_LNK,
+};
+
+#define S_SHIFT 12
+static unsigned char exofs_type_by_mode[S_IFMT >> S_SHIFT] = {
+ [S_IFREG >> S_SHIFT] = EXOFS_FT_REG_FILE,
+ [S_IFDIR >> S_SHIFT] = EXOFS_FT_DIR,
+ [S_IFCHR >> S_SHIFT] = EXOFS_FT_CHRDEV,
+ [S_IFBLK >> S_SHIFT] = EXOFS_FT_BLKDEV,
+ [S_IFIFO >> S_SHIFT] = EXOFS_FT_FIFO,
+ [S_IFSOCK >> S_SHIFT] = EXOFS_FT_SOCK,
+ [S_IFLNK >> S_SHIFT] = EXOFS_FT_SYMLINK,
+};
+
+static inline
+void exofs_set_de_type(struct exofs_dir_entry *de, struct inode *inode)
+{
+ mode_t mode = inode->i_mode;
+ de->file_type = exofs_type_by_mode[(mode & S_IFMT) >> S_SHIFT];
+}
+
+static int
+exofs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+ loff_t pos = filp->f_pos;
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ unsigned int offset = pos & ~PAGE_CACHE_MASK;
+ unsigned long n = pos >> PAGE_CACHE_SHIFT;
+ unsigned long npages = dir_pages(inode);
+ unsigned chunk_mask = ~(exofs_chunk_size(inode)-1);
+ unsigned char *types = NULL;
+ int need_revalidate = (filp->f_version != inode->i_version);
+
+ if (pos > inode->i_size - EXOFS_DIR_REC_LEN(1))
+ return 0;
+
+ types = exofs_filetype_table;
+
+ for ( ; n < npages; n++, offset = 0) {
+ char *kaddr, *limit;
+ struct exofs_dir_entry *de;
+ struct page *page = exofs_get_page(inode, n);
+
+ if (IS_ERR(page)) {
+ EXOFS_ERR("ERROR: "
+ "bad page in #%lu",
+ inode->i_ino);
+ filp->f_pos += PAGE_CACHE_SIZE - offset;
+ return PTR_ERR(page);
+ }
+ kaddr = page_address(page);
+ if (unlikely(need_revalidate)) {
+ if (offset) {
+ offset = exofs_validate_entry(kaddr, offset,
+ chunk_mask);
+ filp->f_pos = (n<<PAGE_CACHE_SHIFT) + offset;
+ }
+ filp->f_version = inode->i_version;
+ need_revalidate = 0;
+ }
+ de = (struct exofs_dir_entry *)(kaddr + offset);
+ limit = kaddr + exofs_last_byte(inode, n) -
+ EXOFS_DIR_REC_LEN(1);
+ for (; (char *)de <= limit; de = exofs_next_entry(de)) {
+ if (de->rec_len == 0) {
+ EXOFS_ERR("ERROR: "
+ "zero-length directory entry");
+ exofs_put_page(page);
+ return -EIO;
+ }
+ if (de->inode_no) {
+ int over;
+ unsigned char d_type = DT_UNKNOWN;
+
+ if (types && de->file_type < EXOFS_FT_MAX)
+ d_type = types[de->file_type];
+
+ offset = (char *)de - kaddr;
+ over = filldir(dirent, de->name, de->name_len,
+ (n<<PAGE_CACHE_SHIFT) | offset,
+ le64_to_cpu(de->inode_no),
+ d_type);
+ if (over) {
+ exofs_put_page(page);
+ return 0;
+ }
+ }
+ filp->f_pos += le16_to_cpu(de->rec_len);
+ }
+ exofs_put_page(page);
+ }
+
+ return 0;
+}
+
+struct exofs_dir_entry *exofs_find_entry(struct inode *dir,
+ struct dentry *dentry, struct page **res_page)
+{
+ const unsigned char *name = dentry->d_name.name;
+ int namelen = dentry->d_name.len;
+ unsigned reclen = EXOFS_DIR_REC_LEN(namelen);
+ unsigned long start, n;
+ unsigned long npages = dir_pages(dir);
+ struct page *page = NULL;
+ struct exofs_i_info *oi = exofs_i(dir);
+ struct exofs_dir_entry *de;
+
+ if (npages == 0)
+ goto out;
+
+ *res_page = NULL;
+
+ start = oi->i_dir_start_lookup;
+ if (start >= npages)
+ start = 0;
+ n = start;
+ do {
+ char *kaddr;
+ page = exofs_get_page(dir, n);
+ if (!IS_ERR(page)) {
+ kaddr = page_address(page);
+ de = (struct exofs_dir_entry *) kaddr;
+ kaddr += exofs_last_byte(dir, n) - reclen;
+ while ((char *) de <= kaddr) {
+ if (de->rec_len == 0) {
+ EXOFS_ERR(
+ "ERROR: exofs_find_entry: "
+ "zero-length directory entry");
+ exofs_put_page(page);
+ goto out;
+ }
+ if (exofs_match(namelen, name, de))
+ goto found;
+ de = exofs_next_entry(de);
+ }
+ exofs_put_page(page);
+ }
+ if (++n >= npages)
+ n = 0;
+ } while (n != start);
+out:
+ return NULL;
+
+found:
+ *res_page = page;
+ oi->i_dir_start_lookup = n;
+ return de;
+}
+
+struct exofs_dir_entry *exofs_dotdot(struct inode *dir, struct page **p)
+{
+ struct page *page = exofs_get_page(dir, 0);
+ struct exofs_dir_entry *de = NULL;
+
+ if (!IS_ERR(page)) {
+ de = exofs_next_entry(
+ (struct exofs_dir_entry *)page_address(page));
+ *p = page;
+ }
+ return de;
+}
+
+ino_t exofs_parent_ino(struct dentry *child)
+{
+ struct page *page;
+ struct exofs_dir_entry *de;
+ ino_t ino;
+
+ de = exofs_dotdot(child->d_inode, &page);
+ if (!de)
+ return 0;
+
+ ino = le64_to_cpu(de->inode_no);
+ exofs_put_page(page);
+ return ino;
+}
+
+ino_t exofs_inode_by_name(struct inode *dir, struct dentry *dentry)
+{
+ ino_t res = 0;
+ struct exofs_dir_entry *de;
+ struct page *page;
+
+ de = exofs_find_entry(dir, dentry, &page);
+ if (de) {
+ res = le64_to_cpu(de->inode_no);
+ exofs_put_page(page);
+ }
+ return res;
+}
+
+int exofs_set_link(struct inode *dir, struct exofs_dir_entry *de,
+ struct page *page, struct inode *inode)
+{
+ loff_t pos = page_offset(page) +
+ (char *) de - (char *) page_address(page);
+ unsigned len = le16_to_cpu(de->rec_len);
+ int err;
+
+ lock_page(page);
+ err = exofs_write_begin(NULL, page->mapping, pos, len,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ if (err)
+ EXOFS_ERR("exofs_set_link: exofs_write_begin FAILD => %d\n",
+ err);
+
+ de->inode_no = cpu_to_le64(inode->i_ino);
+ exofs_set_de_type(de, inode);
+ if (likely(!err))
+ err = exofs_commit_chunk(page, pos, len);
+ exofs_put_page(page);
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+ mark_inode_dirty(dir);
+ return err;
+}
+
+int exofs_add_link(struct dentry *dentry, struct inode *inode)
+{
+ struct inode *dir = dentry->d_parent->d_inode;
+ const unsigned char *name = dentry->d_name.name;
+ int namelen = dentry->d_name.len;
+ unsigned chunk_size = exofs_chunk_size(dir);
+ unsigned reclen = EXOFS_DIR_REC_LEN(namelen);
+ unsigned short rec_len, name_len;
+ struct page *page = NULL;
+ struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
+ struct exofs_dir_entry *de;
+ unsigned long npages = dir_pages(dir);
+ unsigned long n;
+ char *kaddr;
+ loff_t pos;
+ int err;
+
+ for (n = 0; n <= npages; n++) {
+ char *dir_end;
+
+ page = exofs_get_page(dir, n);
+ err = PTR_ERR(page);
+ if (IS_ERR(page))
+ goto out;
+ lock_page(page);
+ kaddr = page_address(page);
+ dir_end = kaddr + exofs_last_byte(dir, n);
+ de = (struct exofs_dir_entry *)kaddr;
+ kaddr += PAGE_CACHE_SIZE - reclen;
+ while ((char *)de <= kaddr) {
+ if ((char *)de == dir_end) {
+ name_len = 0;
+ rec_len = chunk_size;
+ de->rec_len = cpu_to_le16(chunk_size);
+ de->inode_no = 0;
+ goto got_it;
+ }
+ if (de->rec_len == 0) {
+ EXOFS_ERR("ERROR: exofs_add_link: "
+ "zero-length directory entry");
+ err = -EIO;
+ goto out_unlock;
+ }
+ err = -EEXIST;
+ if (exofs_match(namelen, name, de))
+ goto out_unlock;
+ name_len = EXOFS_DIR_REC_LEN(de->name_len);
+ rec_len = le16_to_cpu(de->rec_len);
+ if (!de->inode_no && rec_len >= reclen)
+ goto got_it;
+ if (rec_len >= name_len + reclen)
+ goto got_it;
+ de = (struct exofs_dir_entry *) ((char *) de + rec_len);
+ }
+ unlock_page(page);
+ exofs_put_page(page);
+ }
+
+ EXOFS_ERR("exofs_add_link: BAD dentry=%p or inode=%p", dentry, inode);
+ return -EINVAL;
+
+got_it:
+ pos = page_offset(page) +
+ (char *)de - (char *)page_address(page);
+ err = exofs_write_begin(NULL, page->mapping, pos, rec_len, 0,
+ &page, NULL);
+ if (err)
+ goto out_unlock;
+ if (de->inode_no) {
+ struct exofs_dir_entry *de1 =
+ (struct exofs_dir_entry *)((char *)de + name_len);
+ de1->rec_len = cpu_to_le16(rec_len - name_len);
+ de->rec_len = cpu_to_le16(name_len);
+ de = de1;
+ }
+ de->name_len = namelen;
+ memcpy(de->name, name, namelen);
+ de->inode_no = cpu_to_le64(inode->i_ino);
+ exofs_set_de_type(de, inode);
+ err = exofs_commit_chunk(page, pos, rec_len);
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+ mark_inode_dirty(dir);
+ sbi->s_numfiles++;
+
+out_put:
+ exofs_put_page(page);
+out:
+ return err;
+out_unlock:
+ unlock_page(page);
+ goto out_put;
+}
+
+int exofs_delete_entry(struct exofs_dir_entry *dir, struct page *page)
+{
+ struct address_space *mapping = page->mapping;
+ struct inode *inode = mapping->host;
+ struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
+ char *kaddr = page_address(page);
+ unsigned from = ((char *)dir - kaddr) & ~(exofs_chunk_size(inode)-1);
+ unsigned to = ((char *)dir - kaddr) + le16_to_cpu(dir->rec_len);
+ loff_t pos;
+ struct exofs_dir_entry *pde = NULL;
+ struct exofs_dir_entry *de = (struct exofs_dir_entry *) (kaddr + from);
+ int err;
+
+ while (de < dir) {
+ if (de->rec_len == 0) {
+ EXOFS_ERR("ERROR: exofs_delete_entry:"
+ "zero-length directory entry");
+ err = -EIO;
+ goto out;
+ }
+ pde = de;
+ de = exofs_next_entry(de);
+ }
+ if (pde)
+ from = (char *)pde - (char *)page_address(page);
+ pos = page_offset(page) + from;
+ lock_page(page);
+ err = exofs_write_begin(NULL, page->mapping, pos, to - from, 0,
+ &page, NULL);
+ if (err)
+ EXOFS_ERR("exofs_delete_entry: exofs_write_begin FAILD => %d\n",
+ err);
+ if (pde)
+ pde->rec_len = cpu_to_le16(to - from);
+ dir->inode_no = 0;
+ if (likely(!err))
+ err = exofs_commit_chunk(page, pos, to - from);
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+ mark_inode_dirty(inode);
+ sbi->s_numfiles--;
+out:
+ exofs_put_page(page);
+ return err;
+}
+
+/* kept aligned on 4 bytes */
+#define THIS_DIR ".\0\0"
+#define PARENT_DIR "..\0"
+
+int exofs_make_empty(struct inode *inode, struct inode *parent)
+{
+ struct address_space *mapping = inode->i_mapping;
+ struct page *page = grab_cache_page(mapping, 0);
+ unsigned chunk_size = exofs_chunk_size(inode);
+ struct exofs_dir_entry *de;
+ int err;
+ void *kaddr;
+
+ if (!page)
+ return -ENOMEM;
+
+ err = exofs_write_begin(NULL, page->mapping, 0, chunk_size, 0,
+ &page, NULL);
+ if (err) {
+ unlock_page(page);
+ goto fail;
+ }
+
+ kaddr = kmap_atomic(page, KM_USER0);
+ de = (struct exofs_dir_entry *)kaddr;
+ de->name_len = 1;
+ de->rec_len = cpu_to_le16(EXOFS_DIR_REC_LEN(1));
+ memcpy(de->name, THIS_DIR, sizeof(THIS_DIR));
+ de->inode_no = cpu_to_le64(inode->i_ino);
+ exofs_set_de_type(de, inode);
+
+ de = (struct exofs_dir_entry *)(kaddr + EXOFS_DIR_REC_LEN(1));
+ de->name_len = 2;
+ de->rec_len = cpu_to_le16(chunk_size - EXOFS_DIR_REC_LEN(1));
+ de->inode_no = cpu_to_le64(parent->i_ino);
+ memcpy(de->name, PARENT_DIR, sizeof(PARENT_DIR));
+ exofs_set_de_type(de, inode);
+ kunmap_atomic(page, KM_USER0);
+ err = exofs_commit_chunk(page, 0, chunk_size);
+fail:
+ page_cache_release(page);
+ return err;
+}
+
+int exofs_empty_dir(struct inode *inode)
+{
+ struct page *page = NULL;
+ unsigned long i, npages = dir_pages(inode);
+
+ for (i = 0; i < npages; i++) {
+ char *kaddr;
+ struct exofs_dir_entry *de;
+ page = exofs_get_page(inode, i);
+
+ if (IS_ERR(page))
+ continue;
+
+ kaddr = page_address(page);
+ de = (struct exofs_dir_entry *)kaddr;
+ kaddr += exofs_last_byte(inode, i) - EXOFS_DIR_REC_LEN(1);
+
+ while ((char *)de <= kaddr) {
+ if (de->rec_len == 0) {
+ EXOFS_ERR("ERROR: exofs_empty_dir: "
+ "zero-length directory entry"
+ "kaddr=%p, de=%p\n", kaddr, de);
+ goto not_empty;
+ }
+ if (de->inode_no != 0) {
+ /* check for . and .. */
+ if (de->name[0] != '.')
+ goto not_empty;
+ if (de->name_len > 2)
+ goto not_empty;
+ if (de->name_len < 2) {
+ if (le64_to_cpu(de->inode_no) !=
+ inode->i_ino)
+ goto not_empty;
+ } else if (de->name[1] != '.')
+ goto not_empty;
+ }
+ de = exofs_next_entry(de);
+ }
+ exofs_put_page(page);
+ }
+ return 1;
+
+not_empty:
+ exofs_put_page(page);
+ return 0;
+}
+
+const struct file_operations exofs_dir_operations = {
+ .llseek = generic_file_llseek,
+ .read = generic_read_dir,
+ .readdir = exofs_readdir,
+};
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h
new file mode 100644
index 00000000000..0fd4c785967
--- /dev/null
+++ b/fs/exofs/exofs.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ * from
+ * linux/fs/minix/inode.c
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs 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. Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs 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 exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/fs.h>
+#include <linux/time.h>
+#include "common.h"
+
+#ifndef __EXOFS_H__
+#define __EXOFS_H__
+
+#define EXOFS_ERR(fmt, a...) printk(KERN_ERR "exofs: " fmt, ##a)
+
+#ifdef CONFIG_EXOFS_DEBUG
+#define EXOFS_DBGMSG(fmt, a...) \
+ printk(KERN_NOTICE "exofs @%s:%d: " fmt, __func__, __LINE__, ##a)
+#else
+#define EXOFS_DBGMSG(fmt, a...) \
+ do { if (0) printk(fmt, ##a); } while (0)
+#endif
+
+/* u64 has problems with printk this will cast it to unsigned long long */
+#define _LLU(x) (unsigned long long)(x)
+
+/*
+ * our extension to the in-memory superblock
+ */
+struct exofs_sb_info {
+ struct osd_dev *s_dev; /* returned by get_osd_dev */
+ osd_id s_pid; /* partition ID of file system*/
+ int s_timeout; /* timeout for OSD operations */
+ uint64_t s_nextid; /* highest object ID used */
+ uint32_t s_numfiles; /* number of files on fs */
+ spinlock_t s_next_gen_lock; /* spinlock for gen # update */
+ u32 s_next_generation; /* next gen # to use */
+ atomic_t s_curr_pending; /* number of pending commands */
+ uint8_t s_cred[OSD_CAP_LEN]; /* all-powerful credential */
+};
+
+/*
+ * our extension to the in-memory inode
+ */
+struct exofs_i_info {
+ unsigned long i_flags; /* various atomic flags */
+ uint32_t i_data[EXOFS_IDATA];/*short symlink names and device #s*/
+ uint32_t i_dir_start_lookup; /* which page to start lookup */
+ wait_queue_head_t i_wq; /* wait queue for inode */
+ uint64_t i_commit_size; /* the object's written length */
+ uint8_t i_cred[OSD_CAP_LEN];/* all-powerful credential */
+ struct inode vfs_inode; /* normal in-memory inode */
+};
+
+/*
+ * our inode flags
+ */
+#define OBJ_2BCREATED 0 /* object will be created soon*/
+#define OBJ_CREATED 1 /* object has been created on the osd*/
+
+static inline int obj_2bcreated(struct exofs_i_info *oi)
+{
+ return test_bit(OBJ_2BCREATED, &oi->i_flags);
+}
+
+static inline void set_obj_2bcreated(struct exofs_i_info *oi)
+{
+ set_bit(OBJ_2BCREATED, &oi->i_flags);
+}
+
+static inline int obj_created(struct exofs_i_info *oi)
+{
+ return test_bit(OBJ_CREATED, &oi->i_flags);
+}
+
+static inline void set_obj_created(struct exofs_i_info *oi)
+{
+ set_bit(OBJ_CREATED, &oi->i_flags);
+}
+
+int __exofs_wait_obj_created(struct exofs_i_info *oi);
+static inline int wait_obj_created(struct exofs_i_info *oi)
+{
+ if (likely(obj_created(oi)))
+ return 0;
+
+ return __exofs_wait_obj_created(oi);
+}
+
+/*
+ * get to our inode from the vfs inode
+ */
+static inline struct exofs_i_info *exofs_i(struct inode *inode)
+{
+ return container_of(inode, struct exofs_i_info, vfs_inode);
+}
+
+/*
+ * Maximum count of links to a file
+ */
+#define EXOFS_LINK_MAX 32000
+
+/*************************
+ * function declarations *
+ *************************/
+/* inode.c */
+void exofs_truncate(struct inode *inode);
+int exofs_setattr(struct dentry *, struct iattr *);
+int exofs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata);
+extern struct inode *exofs_iget(struct super_block *, unsigned long);
+struct inode *exofs_new_inode(struct inode *, int);
+extern int exofs_write_inode(struct inode *, int);
+extern void exofs_delete_inode(struct inode *);
+
+/* dir.c: */
+int exofs_add_link(struct dentry *, struct inode *);
+ino_t exofs_inode_by_name(struct inode *, struct dentry *);
+int exofs_delete_entry(struct exofs_dir_entry *, struct page *);
+int exofs_make_empty(struct inode *, struct inode *);
+struct exofs_dir_entry *exofs_find_entry(struct inode *, struct dentry *,
+ struct page **);
+int exofs_empty_dir(struct inode *);
+struct exofs_dir_entry *exofs_dotdot(struct inode *, struct page **);
+ino_t exofs_parent_ino(struct dentry *child);
+int exofs_set_link(struct inode *, struct exofs_dir_entry *, struct page *,
+ struct inode *);
+
+/*********************
+ * operation vectors *
+ *********************/
+/* dir.c: */
+extern const struct file_operations exofs_dir_operations;
+
+/* file.c */
+extern const struct inode_operations exofs_file_inode_operations;
+extern const struct file_operations exofs_file_operations;
+
+/* inode.c */
+extern const struct address_space_operations exofs_aops;
+
+/* namei.c */
+extern const struct inode_operations exofs_dir_inode_operations;
+extern const struct inode_operations exofs_special_inode_operations;
+
+/* symlink.c */
+extern const struct inode_operations exofs_symlink_inode_operations;
+extern const struct inode_operations exofs_fast_symlink_inode_operations;
+
+#endif
diff --git a/fs/exofs/file.c b/fs/exofs/file.c
new file mode 100644
index 00000000000..6ed7fe48475
--- /dev/null
+++ b/fs/exofs/file.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ * from
+ * linux/fs/minix/inode.c
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs 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. Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs 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 exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/buffer_head.h>
+
+#include "exofs.h"
+
+static int exofs_release_file(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static int exofs_file_fsync(struct file *filp, struct dentry *dentry,
+ int datasync)
+{
+ int ret;
+ struct address_space *mapping = filp->f_mapping;
+
+ ret = filemap_write_and_wait(mapping);
+ if (ret)
+ return ret;
+
+ /*Note: file_fsync below also calles sync_blockdev, which is a no-op
+ * for exofs, but other then that it does sync_inode and
+ * sync_superblock which is what we need here.
+ */
+ return file_fsync(filp, dentry, datasync);
+}
+
+static int exofs_flush(struct file *file, fl_owner_t id)
+{
+ exofs_file_fsync(file, file->f_path.dentry, 1);
+ /* TODO: Flush the OSD target */
+ return 0;
+}
+
+const struct file_operations exofs_file_operations = {
+ .llseek = generic_file_llseek,
+ .read = do_sync_read,
+ .write = do_sync_write,
+ .aio_read = generic_file_aio_read,
+ .aio_write = generic_file_aio_write,
+ .mmap = generic_file_mmap,
+ .open = generic_file_open,
+ .release = exofs_release_file,
+ .fsync = exofs_file_fsync,
+ .flush = exofs_flush,
+ .splice_read = generic_file_splice_read,
+ .splice_write = generic_file_splice_write,
+};
+
+const struct inode_operations exofs_file_inode_operations = {
+ .truncate = exofs_truncate,
+ .setattr = exofs_setattr,
+};
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
new file mode 100644
index 00000000000..ba8d9fab469
--- /dev/null
+++ b/fs/exofs/inode.c
@@ -0,0 +1,1303 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ * from
+ * linux/fs/minix/inode.c
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs 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. Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs 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 exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/writeback.h>
+#include <linux/buffer_head.h>
+#include <scsi/scsi_device.h>
+
+#include "exofs.h"
+
+#ifdef CONFIG_EXOFS_DEBUG
+# define EXOFS_DEBUG_OBJ_ISIZE 1
+#endif
+
+struct page_collect {
+ struct exofs_sb_info *sbi;
+ struct request_queue *req_q;
+ struct inode *inode;
+ unsigned expected_pages;
+
+ struct bio *bio;
+ unsigned nr_pages;
+ unsigned long length;
+ loff_t pg_first; /* keep 64bit also in 32-arches */
+};
+
+static void _pcol_init(struct page_collect *pcol, unsigned expected_pages,
+ struct inode *inode)
+{
+ struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
+ struct request_queue *req_q = sbi->s_dev->scsi_device->request_queue;
+
+ pcol->sbi = sbi;
+ pcol->req_q = req_q;
+ pcol->inode = inode;
+ pcol->expected_pages = expected_pages;
+
+ pcol->bio = NULL;
+ pcol->nr_pages = 0;
+ pcol->length = 0;
+ pcol->pg_first = -1;
+
+ EXOFS_DBGMSG("_pcol_init ino=0x%lx expected_pages=%u\n", inode->i_ino,
+ expected_pages);
+}
+
+static void _pcol_reset(struct page_collect *pcol)
+{
+ pcol->expected_pages -= min(pcol->nr_pages, pcol->expected_pages);
+
+ pcol->bio = NULL;
+ pcol->nr_pages = 0;
+ pcol->length = 0;
+ pcol->pg_first = -1;
+ EXOFS_DBGMSG("_pcol_reset ino=0x%lx expected_pages=%u\n",
+ pcol->inode->i_ino, pcol->expected_pages);
+
+ /* this is probably the end of the loop but in writes
+ * it might not end here. don't be left with nothing
+ */
+ if (!pcol->expected_pages)
+ pcol->expected_pages = 128;
+}
+
+static int pcol_try_alloc(struct page_collect *pcol)
+{
+ int pages = min_t(unsigned, pcol->expected_pages, BIO_MAX_PAGES);
+
+ for (; pages; pages >>= 1) {
+ pcol->bio = bio_alloc(GFP_KERNEL, pages);
+ if (likely(pcol->bio))
+ return 0;
+ }
+
+ EXOFS_ERR("Failed to kcalloc expected_pages=%u\n",
+ pcol->expected_pages);
+ return -ENOMEM;
+}
+
+static void pcol_free(struct page_collect *pcol)
+{
+ bio_put(pcol->bio);
+ pcol->bio = NULL;
+}
+
+static int pcol_add_page(struct page_collect *pcol, struct page *page,
+ unsigned len)
+{
+ int added_len = bio_add_pc_page(pcol->req_q, pcol->bio, page, len, 0);
+ if (unlikely(len != added_len))
+ return -ENOMEM;
+
+ ++pcol->nr_pages;
+ pcol->length += len;
+ return 0;
+}
+
+static int update_read_page(struct page *page, int ret)
+{
+ if (ret == 0) {
+ /* Everything is OK */
+ SetPageUptodate(page);
+ if (PageError(page))
+ ClearPageError(page);
+ } else if (ret == -EFAULT) {
+ /* In this case we were trying to read something that wasn't on
+ * disk yet - return a page full of zeroes. This should be OK,
+ * because the object should be empty (if there was a write
+ * before this read, the read would be waiting with the page
+ * locked */
+ clear_highpage(page);
+
+ SetPageUptodate(page);
+ if (PageError(page))
+ ClearPageError(page);
+ ret = 0; /* recovered error */
+ EXOFS_DBGMSG("recovered read error\n");
+ } else /* Error */
+ SetPageError(page);
+
+ return ret;
+}
+
+static void update_write_page(struct page *page, int ret)
+{
+ if (ret) {
+ mapping_set_error(page->mapping, ret);
+ SetPageError(page);
+ }
+ end_page_writeback(page);
+}
+
+/* Called at the end of reads, to optionally unlock pages and update their
+ * status.
+ */
+static int __readpages_done(struct osd_request *or, struct page_collect *pcol,
+ bool do_unlock)
+{
+ struct bio_vec *bvec;
+ int i;
+ u64 resid;
+ u64 good_bytes;
+ u64 length = 0;
+ int ret = exofs_check_ok_resid(or, &resid, NULL);
+
+ osd_end_request(or);
+
+ if (likely(!ret))
+ good_bytes = pcol->length;
+ else if (!resid)
+ good_bytes = 0;
+ else
+ good_bytes = pcol->length - resid;
+
+ EXOFS_DBGMSG("readpages_done(0x%lx) good_bytes=0x%llx"
+ " length=0x%lx nr_pages=%u\n",
+ pcol->inode->i_ino, _LLU(good_bytes), pcol->length,
+ pcol->nr_pages);
+
+ __bio_for_each_segment(bvec, pcol->bio, i, 0) {
+ struct page *page = bvec->bv_page;
+ struct inode *inode = page->mapping->host;
+ int page_stat;
+
+ if (inode != pcol->inode)
+ continue; /* osd might add more pages at end */
+
+ if (likely(length < good_bytes))
+ page_stat = 0;
+ else
+ page_stat = ret;
+
+ EXOFS_DBGMSG(" readpages_done(0x%lx, 0x%lx) %s\n",
+ inode->i_ino, page->index,
+ page_stat ? "bad_bytes" : "good_bytes");
+
+ ret = update_read_page(page, page_stat);
+ if (do_unlock)
+ unlock_page(page);
+ length += bvec->bv_len;
+ }
+
+ pcol_free(pcol);
+ EXOFS_DBGMSG("readpages_done END\n");
+ return ret;
+}
+
+/* callback of async reads */
+static void readpages_done(struct osd_request *or, void *p)
+{
+ struct page_collect *pcol = p;
+
+ __readpages_done(or, pcol, true);
+ atomic_dec(&pcol->sbi->s_curr_pending);
+ kfree(p);
+}
+
+static void _unlock_pcol_pages(struct page_collect *pcol, int ret, int rw)
+{
+ struct bio_vec *bvec;
+ int i;
+
+ __bio_for_each_segment(bvec, pcol->bio, i, 0) {
+ struct page *page = bvec->bv_page;
+
+ if (rw == READ)
+ update_read_page(page, ret);
+ else
+ update_write_page(page, ret);
+
+ unlock_page(page);
+ }
+ pcol_free(pcol);
+}
+
+static int read_exec(struct page_collect *pcol, bool is_sync)
+{
+ struct exofs_i_info *oi = exofs_i(pcol->inode);
+ struct osd_obj_id obj = {pcol->sbi->s_pid,
+ pcol->inode->i_ino + EXOFS_OBJ_OFF};
+ struct osd_request *or = NULL;
+ struct page_collect *pcol_copy = NULL;
+ loff_t i_start = pcol->pg_first << PAGE_CACHE_SHIFT;
+ int ret;
+
+ if (!pcol->bio)
+ return 0;
+
+ /* see comment in _readpage() about sync reads */
+ WARN_ON(is_sync && (pcol->nr_pages != 1));
+
+ or = osd_start_request(pcol->sbi->s_dev, GFP_KERNEL);
+ if (unlikely(!or)) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ osd_req_read(or, &obj, pcol->bio, i_start);
+
+ if (is_sync) {
+ exofs_sync_op(or, pcol->sbi->s_timeout, oi->i_cred);
+ return __readpages_done(or, pcol, false);
+ }
+
+ pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL);
+ if (!pcol_copy) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ *pcol_copy = *pcol;
+ ret = exofs_async_op(or, readpages_done, pcol_copy, oi->i_cred);
+ if (unlikely(ret))
+ goto err;
+
+ atomic_inc(&pcol->sbi->s_curr_pending);
+
+ EXOFS_DBGMSG("read_exec obj=0x%llx start=0x%llx length=0x%lx\n",
+ obj.id, _LLU(i_start), pcol->length);
+
+ /* pages ownership was passed to pcol_copy */
+ _pcol_reset(pcol);
+ return 0;
+
+err:
+ if (!is_sync)
+ _unlock_pcol_pages(pcol, ret, READ);
+ kfree(pcol_copy);
+ if (or)
+ osd_end_request(or);
+ return ret;
+}
+
+/* readpage_strip is called either directly from readpage() or by the VFS from
+ * within read_cache_pages(), to add one more page to be read. It will try to
+ * collect as many contiguous pages as posible. If a discontinuity is
+ * encountered, or it runs out of resources, it will submit the previous segment
+ * and will start a new collection. Eventually caller must submit the last
+ * segment if present.
+ */
+static int readpage_strip(void *data, struct page *page)
+{
+ struct page_collect *pcol = data;
+ struct inode *inode = pcol->inode;
+ struct exofs_i_info *oi = exofs_i(inode);
+ loff_t i_size = i_size_read(inode);
+ pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
+ size_t len;
+ int ret;
+
+ /* FIXME: Just for debugging, will be removed */
+ if (PageUptodate(page))
+ EXOFS_ERR("PageUptodate(0x%lx, 0x%lx)\n", pcol->inode->i_ino,
+ page->index);
+
+ if (page->index < end_index)
+ len = PAGE_CACHE_SIZE;
+ else if (page->index == end_index)
+ len = i_size & ~PAGE_CACHE_MASK;
+ else
+ len = 0;
+
+ if (!len || !obj_created(oi)) {
+ /* this will be out of bounds, or doesn't exist yet.
+ * Current page is cleared and the request is split
+ */
+ clear_highpage(page);
+
+ SetPageUptodate(page);
+ if (PageError(page))
+ ClearPageError(page);
+
+ unlock_page(page);
+ EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page,"
+ " splitting\n", inode->i_ino, page->index);
+
+ return read_exec(pcol, false);
+ }
+
+try_again:
+
+ if (unlikely(pcol->pg_first == -1)) {
+ pcol->pg_first = page->index;
+ } else if (unlikely((pcol->pg_first + pcol->nr_pages) !=
+ page->index)) {
+ /* Discontinuity detected, split the request */
+ ret = read_exec(pcol, false);
+ if (unlikely(ret))
+ goto fail;
+ goto try_again;
+ }
+
+ if (!pcol->bio) {
+ ret = pcol_try_alloc(pcol);
+ if (unlikely(ret))
+ goto fail;
+ }
+
+ if (len != PAGE_CACHE_SIZE)
+ zero_user(page, len, PAGE_CACHE_SIZE - len);
+
+ EXOFS_DBGMSG(" readpage_strip(0x%lx, 0x%lx) len=0x%zx\n",
+ inode->i_ino, page->index, len);
+
+ ret = pcol_add_page(pcol, page, len);
+ if (ret) {
+ EXOFS_DBGMSG("Failed pcol_add_page pages[i]=%p "
+ "this_len=0x%zx nr_pages=%u length=0x%lx\n",
+ page, len, pcol->nr_pages, pcol->length);
+
+ /* split the request, and start again with current page */
+ ret = read_exec(pcol, false);
+ if (unlikely(ret))
+ goto fail;
+
+ goto try_again;
+ }
+
+ return 0;
+
+fail:
+ /* SetPageError(page); ??? */
+ unlock_page(page);
+ return ret;
+}
+
+static int exofs_readpages(struct file *file, struct address_space *mapping,
+ struct list_head *pages, unsigned nr_pages)
+{
+ struct page_collect pcol;
+ int ret;
+
+ _pcol_init(&pcol, nr_pages, mapping->host);
+
+ ret = read_cache_pages(mapping, pages, readpage_strip, &pcol);
+ if (ret) {
+ EXOFS_ERR("read_cache_pages => %d\n", ret);
+ return ret;
+ }
+
+ return read_exec(&pcol, false);
+}
+
+static int _readpage(struct page *page, bool is_sync)
+{
+ struct page_collect pcol;
+ int ret;
+
+ _pcol_init(&pcol, 1, page->mapping->host);
+
+ /* readpage_strip might call read_exec(,async) inside at several places
+ * but this is safe for is_async=0 since read_exec will not do anything
+ * when we have a single page.
+ */
+ ret = readpage_strip(&pcol, page);
+ if (ret) {
+ EXOFS_ERR("_readpage => %d\n", ret);
+ return ret;
+ }
+
+ return read_exec(&pcol, is_sync);
+}
+
+/*
+ * We don't need the file
+ */
+static int exofs_readpage(struct file *file, struct page *page)
+{
+ return _readpage(page, false);
+}
+
+/* Callback for osd_write. All writes are asynchronouse */
+static void writepages_done(struct osd_request *or, void *p)
+{
+ struct page_collect *pcol = p;
+ struct bio_vec *bvec;
+ int i;
+ u64 resid;
+ u64 good_bytes;
+ u64 length = 0;
+
+ int ret = exofs_check_ok_resid(or, NULL, &resid);
+
+ osd_end_request(or);
+ atomic_dec(&pcol->sbi->s_curr_pending);
+
+ if (likely(!ret))
+ good_bytes = pcol->length;
+ else if (!resid)
+ good_bytes = 0;
+ else
+ good_bytes = pcol->length - resid;
+
+ EXOFS_DBGMSG("writepages_done(0x%lx) good_bytes=0x%llx"
+ " length=0x%lx nr_pages=%u\n",
+ pcol->inode->i_ino, _LLU(good_bytes), pcol->length,
+ pcol->nr_pages);
+
+ __bio_for_each_segment(bvec, pcol->bio, i, 0) {
+ struct page *page = bvec->bv_page;
+ struct inode *inode = page->mapping->host;
+ int page_stat;
+
+ if (inode != pcol->inode)
+ continue; /* osd might add more pages to a bio */
+
+ if (likely(length < good_bytes))
+ page_stat = 0;
+ else
+ page_stat = ret;
+
+ update_write_page(page, page_stat);
+ unlock_page(page);
+ EXOFS_DBGMSG(" writepages_done(0x%lx, 0x%lx) status=%d\n",
+ inode->i_ino, page->index, page_stat);
+
+ length += bvec->bv_len;
+ }
+
+ pcol_free(pcol);
+ kfree(pcol);
+ EXOFS_DBGMSG("writepages_done END\n");
+}
+
+static int write_exec(struct page_collect *pcol)
+{
+ struct exofs_i_info *oi = exofs_i(pcol->inode);
+ struct osd_obj_id obj = {pcol->sbi->s_pid,
+ pcol->inode->i_ino + EXOFS_OBJ_OFF};
+ struct osd_request *or = NULL;
+ struct page_collect *pcol_copy = NULL;
+ loff_t i_start = pcol->pg_first << PAGE_CACHE_SHIFT;
+ int ret;
+
+ if (!pcol->bio)
+ return 0;
+
+ or = osd_start_request(pcol->sbi->s_dev, GFP_KERNEL);
+ if (unlikely(!or)) {
+ EXOFS_ERR("write_exec: Faild to osd_start_request()\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL);
+ if (!pcol_copy) {
+ EXOFS_ERR("write_exec: Faild to kmalloc(pcol)\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ *pcol_copy = *pcol;
+
+ osd_req_write(or, &obj, pcol_copy->bio, i_start);
+ ret = exofs_async_op(or, writepages_done, pcol_copy, oi->i_cred);
+ if (unlikely(ret)) {
+ EXOFS_ERR("write_exec: exofs_async_op() Faild\n");
+ goto err;
+ }
+
+ atomic_inc(&pcol->sbi->s_curr_pending);
+ EXOFS_DBGMSG("write_exec(0x%lx, 0x%llx) start=0x%llx length=0x%lx\n",
+ pcol->inode->i_ino, pcol->pg_first, _LLU(i_start),
+ pcol->length);
+ /* pages ownership was passed to pcol_copy */
+ _pcol_reset(pcol);
+ return 0;
+
+err:
+ _unlock_pcol_pages(pcol, ret, WRITE);
+ kfree(pcol_copy);
+ if (or)
+ osd_end_request(or);
+ return ret;
+}
+
+/* writepage_strip is called either directly from writepage() or by the VFS from
+ * within write_cache_pages(), to add one more page to be written to storage.
+ * It will try to collect as many contiguous pages as possible. If a
+ * discontinuity is encountered or it runs out of resources it will submit the
+ * previous segment and will start a new collection.
+ * Eventually caller must submit the last segment if present.
+ */
+static int writepage_strip(struct page *page,
+ struct writeback_control *wbc_unused, void *data)
+{
+ struct page_collect *pcol = data;
+ struct inode *inode = pcol->inode;
+ struct exofs_i_info *oi = exofs_i(inode);
+ loff_t i_size = i_size_read(inode);
+ pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
+ size_t len;
+ int ret;
+
+ BUG_ON(!PageLocked(page));
+
+ ret = wait_obj_created(oi);
+ if (unlikely(ret))
+ goto fail;
+
+ if (page->index < end_index)
+ /* in this case, the page is within the limits of the file */
+ len = PAGE_CACHE_SIZE;
+ else {
+ len = i_size & ~PAGE_CACHE_MASK;
+
+ if (page->index > end_index || !len) {
+ /* in this case, the page is outside the limits
+ * (truncate in progress)
+ */
+ ret = write_exec(pcol);
+ if (unlikely(ret))
+ goto fail;
+ if (PageError(page))
+ ClearPageError(page);
+ unlock_page(page);
+ return 0;
+ }
+ }
+
+try_again:
+
+ if (unlikely(pcol->pg_first == -1)) {
+ pcol->pg_first = page->index;
+ } else if (unlikely((pcol->pg_first + pcol->nr_pages) !=
+ page->index)) {
+ /* Discontinuity detected, split the request */
+ ret = write_exec(pcol);
+ if (unlikely(ret))
+ goto fail;
+ goto try_again;
+ }
+
+ if (!pcol->bio) {
+ ret = pcol_try_alloc(pcol);
+ if (unlikely(ret))
+ goto fail;
+ }
+
+ EXOFS_DBGMSG(" writepage_strip(0x%lx, 0x%lx) len=0x%zx\n",
+ inode->i_ino, page->index, len);
+
+ ret = pcol_add_page(pcol, page, len);
+ if (unlikely(ret)) {
+ EXOFS_DBGMSG("Failed pcol_add_page "
+ "nr_pages=%u total_length=0x%lx\n",
+ pcol->nr_pages, pcol->length);
+
+ /* split the request, next loop will start again */
+ ret = write_exec(pcol);
+ if (unlikely(ret)) {
+ EXOFS_DBGMSG("write_exec faild => %d", ret);
+ goto fail;
+ }
+
+ goto try_again;
+ }
+
+ BUG_ON(PageWriteback(page));
+ set_page_writeback(page);
+
+ return 0;
+
+fail:
+ set_bit(AS_EIO, &page->mapping->flags);
+ unlock_page(page);
+ return ret;
+}
+
+static int exofs_writepages(struct address_space *mapping,
+ struct writeback_control *wbc)
+{
+ struct page_collect pcol;
+ long start, end, expected_pages;
+ int ret;
+
+ start = wbc->range_start >> PAGE_CACHE_SHIFT;
+ end = (wbc->range_end == LLONG_MAX) ?
+ start + mapping->nrpages :
+ wbc->range_end >> PAGE_CACHE_SHIFT;
+
+ if (start || end)
+ expected_pages = min(end - start + 1, 32L);
+ else
+ expected_pages = mapping->nrpages;
+
+ EXOFS_DBGMSG("inode(0x%lx) wbc->start=0x%llx wbc->end=0x%llx"
+ " m->nrpages=%lu start=0x%lx end=0x%lx\n",
+ mapping->host->i_ino, wbc->range_start, wbc->range_end,
+ mapping->nrpages, start, end);
+
+ _pcol_init(&pcol, expected_pages, mapping->host);
+
+ ret = write_cache_pages(mapping, wbc, writepage_strip, &pcol);
+ if (ret) {
+ EXOFS_ERR("write_cache_pages => %d\n", ret);
+ return ret;
+ }
+
+ return write_exec(&pcol);
+}
+
+static int exofs_writepage(struct page *page, struct writeback_control *wbc)
+{
+ struct page_collect pcol;
+ int ret;
+
+ _pcol_init(&pcol, 1, page->mapping->host);
+
+ ret = writepage_strip(page, NULL, &pcol);
+ if (ret) {
+ EXOFS_ERR("exofs_writepage => %d\n", ret);
+ return ret;
+ }
+
+ return write_exec(&pcol);
+}
+
+int exofs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+{
+ int ret = 0;
+ struct page *page;
+
+ page = *pagep;
+ if (page == NULL) {
+ ret = simple_write_begin(file, mapping, pos, len, flags, pagep,
+ fsdata);
+ if (ret) {
+ EXOFS_DBGMSG("simple_write_begin faild\n");
+ return ret;
+ }
+
+ page = *pagep;
+ }
+
+ /* read modify write */
+ if (!PageUptodate(page) && (len != PAGE_CACHE_SIZE)) {
+ ret = _readpage(page, true);
+ if (ret) {
+ /*SetPageError was done by _readpage. Is it ok?*/
+ unlock_page(page);
+ EXOFS_DBGMSG("__readpage_filler faild\n");
+ }
+ }
+
+ return ret;
+}
+
+static int exofs_write_begin_export(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+{
+ *pagep = NULL;
+
+ return exofs_write_begin(file, mapping, pos, len, flags, pagep,
+ fsdata);
+}
+
+const struct address_space_operations exofs_aops = {
+ .readpage = exofs_readpage,
+ .readpages = exofs_readpages,
+ .writepage = exofs_writepage,
+ .writepages = exofs_writepages,
+ .write_begin = exofs_write_begin_export,
+ .write_end = simple_write_end,
+};
+
+/******************************************************************************
+ * INODE OPERATIONS
+ *****************************************************************************/
+
+/*
+ * Test whether an inode is a fast symlink.
+ */
+static inline int exofs_inode_is_fast_symlink(struct inode *inode)
+{
+ struct exofs_i_info *oi = exofs_i(inode);
+
+ return S_ISLNK(inode->i_mode) && (oi->i_data[0] != 0);
+}
+
+/*
+ * get_block_t - Fill in a buffer_head
+ * An OSD takes care of block allocation so we just fake an allocation by
+ * putting in the inode's sector_t in the buffer_head.
+ * TODO: What about the case of create==0 and @iblock does not exist in the
+ * object?
+ */
+static int exofs_get_block(struct inode *inode, sector_t iblock,
+ struct buffer_head *bh_result, int create)
+{
+ map_bh(bh_result, inode->i_sb, iblock);
+ return 0;
+}
+
+const struct osd_attr g_attr_logical_length = ATTR_DEF(
+ OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8);
+
+/*
+ * Truncate a file to the specified size - all we have to do is set the size
+ * attribute. We make sure the object exists first.
+ */
+void exofs_truncate(struct inode *inode)
+{
+ struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
+ struct exofs_i_info *oi = exofs_i(inode);
+ struct osd_obj_id obj = {sbi->s_pid, inode->i_ino + EXOFS_OBJ_OFF};
+ struct osd_request *or;
+ struct osd_attr attr;
+ loff_t isize = i_size_read(inode);
+ __be64 newsize;
+ int ret;
+
+ if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
+ || S_ISLNK(inode->i_mode)))
+ return;
+ if (exofs_inode_is_fast_symlink(inode))
+ return;
+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ return;
+ inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+
+ nobh_truncate_page(inode->i_mapping, isize, exofs_get_block);
+
+ or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+ if (unlikely(!or)) {
+ EXOFS_ERR("ERROR: exofs_truncate: osd_start_request failed\n");
+ goto fail;
+ }
+
+ osd_req_set_attributes(or, &obj);
+
+ newsize = cpu_to_be64((u64)isize);
+ attr = g_attr_logical_length;
+ attr.val_ptr = &newsize;
+ osd_req_add_set_attr_list(or, &attr, 1);
+
+ /* if we are about to truncate an object, and it hasn't been
+ * created yet, wait
+ */
+ if (unlikely(wait_obj_created(oi)))
+ goto fail;
+
+ ret = exofs_sync_op(or, sbi->s_timeout, oi->i_cred);
+ osd_end_request(or);
+ if (ret)
+ goto fail;
+
+out:
+ mark_inode_dirty(inode);
+ return;
+fail:
+ make_bad_inode(inode);
+ goto out;
+}
+
+/*
+ * Set inode attributes - just call generic functions.
+ */
+int exofs_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+ struct inode *inode = dentry->d_inode;
+ int error;
+
+ error = inode_change_ok(inode, iattr);
+ if (error)
+ return error;
+
+ error = inode_setattr(inode, iattr);
+ return error;
+}
+
+/*
+ * Read an inode from the OSD, and return it as is. We also return the size
+ * attribute in the 'sanity' argument if we got compiled with debugging turned
+ * on.
+ */
+static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
+ struct exofs_fcb *inode, uint64_t *sanity)
+{
+ struct exofs_sb_info *sbi = sb->s_fs_info;
+ struct osd_request *or;
+ struct osd_attr attr;
+ struct osd_obj_id obj = {sbi->s_pid,
+ oi->vfs_inode.i_ino + EXOFS_OBJ_OFF};
+ int ret;
+
+ exofs_make_credential(oi->i_cred, &obj);
+
+ or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+ if (unlikely(!or)) {
+ EXOFS_ERR("exofs_get_inode: osd_start_request failed.\n");
+ return -ENOMEM;
+ }
+ osd_req_get_attributes(or, &obj);
+
+ /* we need the inode attribute */
+ osd_req_add_get_attr_list(or, &g_attr_inode_data, 1);
+
+#ifdef EXOFS_DEBUG_OBJ_ISIZE
+ /* we get the size attributes to do a sanity check */
+ osd_req_add_get_attr_list(or, &g_attr_logical_length, 1);
+#endif
+
+ ret = exofs_sync_op(or, sbi->s_timeout, oi->i_cred);
+ if (ret)
+ goto out;
+
+ attr = g_attr_inode_data;
+ ret = extract_attr_from_req(or, &attr);
+ if (ret) {
+ EXOFS_ERR("exofs_get_inode: extract_attr_from_req failed\n");
+ goto out;
+ }
+
+ WARN_ON(attr.len != EXOFS_INO_ATTR_SIZE);
+ memcpy(inode, attr.val_ptr, EXOFS_INO_ATTR_SIZE);
+
+#ifdef EXOFS_DEBUG_OBJ_ISIZE
+ attr = g_attr_logical_length;
+ ret = extract_attr_from_req(or, &attr);
+ if (ret) {
+ EXOFS_ERR("ERROR: extract attr from or failed\n");
+ goto out;
+ }
+ *sanity = get_unaligned_be64(attr.val_ptr);
+#endif
+
+out:
+ osd_end_request(or);
+ return ret;
+}
+
+/*
+ * Fill in an inode read from the OSD and set it up for use
+ */
+struct inode *exofs_iget(struct super_block *sb, unsigned long ino)
+{
+ struct exofs_i_info *oi;
+ struct exofs_fcb fcb;
+ struct inode *inode;
+ uint64_t uninitialized_var(sanity);
+ int ret;
+
+ inode = iget_locked(sb, ino);
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+ if (!(inode->i_state & I_NEW))
+ return inode;
+ oi = exofs_i(inode);
+
+ /* read the inode from the osd */
+ ret = exofs_get_inode(sb, oi, &fcb, &sanity);
+ if (ret)
+ goto bad_inode;
+
+ init_waitqueue_head(&oi->i_wq);
+ set_obj_created(oi);
+
+ /* copy stuff from on-disk struct to in-memory struct */
+ inode->i_mode = le16_to_cpu(fcb.i_mode);
+ inode->i_uid = le32_to_cpu(fcb.i_uid);
+ inode->i_gid = le32_to_cpu(fcb.i_gid);
+ inode->i_nlink = le16_to_cpu(fcb.i_links_count);
+ inode->i_ctime.tv_sec = (signed)le32_to_cpu(fcb.i_ctime);
+ inode->i_atime.tv_sec = (signed)le32_to_cpu(fcb.i_atime);
+ inode->i_mtime.tv_sec = (signed)le32_to_cpu(fcb.i_mtime);
+ inode->i_ctime.tv_nsec =
+ inode->i_atime.tv_nsec = inode->i_mtime.tv_nsec = 0;
+ oi->i_commit_size = le64_to_cpu(fcb.i_size);
+ i_size_write(inode, oi->i_commit_size);
+ inode->i_blkbits = EXOFS_BLKSHIFT;
+ inode->i_generation = le32_to_cpu(fcb.i_generation);
+
+#ifdef EXOFS_DEBUG_OBJ_ISIZE
+ if ((inode->i_size != sanity) &&
+ (!exofs_inode_is_fast_symlink(inode))) {
+ EXOFS_ERR("WARNING: Size of object from inode and "
+ "attributes differ (%lld != %llu)\n",
+ inode->i_size, _LLU(sanity));
+ }
+#endif
+
+ oi->i_dir_start_lookup = 0;
+
+ if ((inode->i_nlink == 0) && (inode->i_mode == 0)) {
+ ret = -ESTALE;
+ goto bad_inode;
+ }
+
+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
+ if (fcb.i_data[0])
+ inode->i_rdev =
+ old_decode_dev(le32_to_cpu(fcb.i_data[0]));
+ else
+ inode->i_rdev =
+ new_decode_dev(le32_to_cpu(fcb.i_data[1]));
+ } else {
+ memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data));
+ }
+
+ if (S_ISREG(inode->i_mode)) {
+ inode->i_op = &exofs_file_inode_operations;
+ inode->i_fop = &exofs_file_operations;
+ inode->i_mapping->a_ops = &exofs_aops;
+ } else if (S_ISDIR(inode->i_mode)) {
+ inode->i_op = &exofs_dir_inode_operations;
+ inode->i_fop = &exofs_dir_operations;
+ inode->i_mapping->a_ops = &exofs_aops;
+ } else if (S_ISLNK(inode->i_mode)) {
+ if (exofs_inode_is_fast_symlink(inode))
+ inode->i_op = &exofs_fast_symlink_inode_operations;
+ else {
+ inode->i_op = &exofs_symlink_inode_operations;
+ inode->i_mapping->a_ops = &exofs_aops;
+ }
+ } else {
+ inode->i_op = &exofs_special_inode_operations;
+ if (fcb.i_data[0])
+ init_special_inode(inode, inode->i_mode,
+ old_decode_dev(le32_to_cpu(fcb.i_data[0])));
+ else
+ init_special_inode(inode, inode->i_mode,
+ new_decode_dev(le32_to_cpu(fcb.i_data[1])));
+ }
+
+ unlock_new_inode(inode);
+ return inode;
+
+bad_inode:
+ iget_failed(inode);
+ return ERR_PTR(ret);
+}
+
+int __exofs_wait_obj_created(struct exofs_i_info *oi)
+{
+ if (!obj_created(oi)) {
+ BUG_ON(!obj_2bcreated(oi));
+ wait_event(oi->i_wq, obj_created(oi));
+ }
+ return unlikely(is_bad_inode(&oi->vfs_inode)) ? -EIO : 0;
+}
+/*
+ * Callback function from exofs_new_inode(). The important thing is that we
+ * set the obj_created flag so that other methods know that the object exists on
+ * the OSD.
+ */
+static void create_done(struct osd_request *or, void *p)
+{
+ struct inode *inode = p;
+ struct exofs_i_info *oi = exofs_i(inode);
+ struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
+ int ret;
+
+ ret = exofs_check_ok(or);
+ osd_end_request(or);
+ atomic_dec(&sbi->s_curr_pending);
+
+ if (unlikely(ret)) {
+ EXOFS_ERR("object=0x%llx creation faild in pid=0x%llx",
+ _LLU(sbi->s_pid), _LLU(inode->i_ino + EXOFS_OBJ_OFF));
+ make_bad_inode(inode);
+ } else
+ set_obj_created(oi);
+
+ atomic_dec(&inode->i_count);
+ wake_up(&oi->i_wq);
+}
+
+/*
+ * Set up a new inode and create an object for it on the OSD
+ */
+struct inode *exofs_new_inode(struct inode *dir, int mode)
+{
+ struct super_block *sb;
+ struct inode *inode;
+ struct exofs_i_info *oi;
+ struct exofs_sb_info *sbi;
+ struct osd_request *or;
+ struct osd_obj_id obj;
+ int ret;
+
+ sb = dir->i_sb;
+ inode = new_inode(sb);
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+
+ oi = exofs_i(inode);
+
+ init_waitqueue_head(&oi->i_wq);
+ set_obj_2bcreated(oi);
+
+ sbi = sb->s_fs_info;
+
+ sb->s_dirt = 1;
+ inode->i_uid = current->cred->fsuid;
+ if (dir->i_mode & S_ISGID) {
+ inode->i_gid = dir->i_gid;
+ if (S_ISDIR(mode))
+ mode |= S_ISGID;
+ } else {
+ inode->i_gid = current->cred->fsgid;
+ }
+ inode->i_mode = mode;
+
+ inode->i_ino = sbi->s_nextid++;
+ inode->i_blkbits = EXOFS_BLKSHIFT;
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+ oi->i_commit_size = inode->i_size = 0;
+ spin_lock(&sbi->s_next_gen_lock);
+ inode->i_generation = sbi->s_next_generation++;
+ spin_unlock(&sbi->s_next_gen_lock);
+ insert_inode_hash(inode);
+
+ mark_inode_dirty(inode);
+
+ obj.partition = sbi->s_pid;
+ obj.id = inode->i_ino + EXOFS_OBJ_OFF;
+ exofs_make_credential(oi->i_cred, &obj);
+
+ or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+ if (unlikely(!or)) {
+ EXOFS_ERR("exofs_new_inode: osd_start_request failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ osd_req_create_object(or, &obj);
+
+ /* increment the refcount so that the inode will still be around when we
+ * reach the callback
+ */
+ atomic_inc(&inode->i_count);
+
+ ret = exofs_async_op(or, create_done, inode, oi->i_cred);
+ if (ret) {
+ atomic_dec(&inode->i_count);
+ osd_end_request(or);
+ return ERR_PTR(-EIO);
+ }
+ atomic_inc(&sbi->s_curr_pending);
+
+ return inode;
+}
+
+/*
+ * struct to pass two arguments to update_inode's callback
+ */
+struct updatei_args {
+ struct exofs_sb_info *sbi;
+ struct exofs_fcb fcb;
+};
+
+/*
+ * Callback function from exofs_update_inode().
+ */
+static void updatei_done(struct osd_request *or, void *p)
+{
+ struct updatei_args *args = p;
+
+ osd_end_request(or);
+
+ atomic_dec(&args->sbi->s_curr_pending);
+
+ kfree(args);
+}
+
+/*
+ * Write the inode to the OSD. Just fill up the struct, and set the attribute
+ * synchronously or asynchronously depending on the do_sync flag.
+ */
+static int exofs_update_inode(struct inode *inode, int do_sync)
+{
+ struct exofs_i_info *oi = exofs_i(inode);
+ struct super_block *sb = inode->i_sb;
+ struct exofs_sb_info *sbi = sb->s_fs_info;
+ struct osd_obj_id obj = {sbi->s_pid, inode->i_ino + EXOFS_OBJ_OFF};
+ struct osd_request *or;
+ struct osd_attr attr;
+ struct exofs_fcb *fcb;
+ struct updatei_args *args;
+ int ret;
+
+ args = kzalloc(sizeof(*args), GFP_KERNEL);
+ if (!args)
+ return -ENOMEM;
+
+ fcb = &args->fcb;
+
+ fcb->i_mode = cpu_to_le16(inode->i_mode);
+ fcb->i_uid = cpu_to_le32(inode->i_uid);
+ fcb->i_gid = cpu_to_le32(inode->i_gid);
+ fcb->i_links_count = cpu_to_le16(inode->i_nlink);
+ fcb->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
+ fcb->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
+ fcb->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
+ oi->i_commit_size = i_size_read(inode);
+ fcb->i_size = cpu_to_le64(oi->i_commit_size);
+ fcb->i_generation = cpu_to_le32(inode->i_generation);
+
+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
+ if (old_valid_dev(inode->i_rdev)) {
+ fcb->i_data[0] =
+ cpu_to_le32(old_encode_dev(inode->i_rdev));
+ fcb->i_data[1] = 0;
+ } else {
+ fcb->i_data[0] = 0;
+ fcb->i_data[1] =
+ cpu_to_le32(new_encode_dev(inode->i_rdev));
+ fcb->i_data[2] = 0;
+ }
+ } else
+ memcpy(fcb->i_data, oi->i_data, sizeof(fcb->i_data));
+
+ or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+ if (unlikely(!or)) {
+ EXOFS_ERR("exofs_update_inode: osd_start_request failed.\n");
+ ret = -ENOMEM;
+ goto free_args;
+ }
+
+ osd_req_set_attributes(or, &obj);
+
+ attr = g_attr_inode_data;
+ attr.val_ptr = fcb;
+ osd_req_add_set_attr_list(or, &attr, 1);
+
+ if (!obj_created(oi)) {
+ EXOFS_DBGMSG("!obj_created\n");
+ BUG_ON(!obj_2bcreated(oi));
+ wait_event(oi->i_wq, obj_created(oi));
+ EXOFS_DBGMSG("wait_event done\n");
+ }
+
+ if (do_sync) {
+ ret = exofs_sync_op(or, sbi->s_timeout, oi->i_cred);
+ osd_end_request(or);
+ goto free_args;
+ } else {
+ args->sbi = sbi;
+
+ ret = exofs_async_op(or, updatei_done, args, oi->i_cred);
+ if (ret) {
+ osd_end_request(or);
+ goto free_args;
+ }
+ atomic_inc(&sbi->s_curr_pending);
+ goto out; /* deallocation in updatei_done */
+ }
+
+free_args:
+ kfree(args);
+out:
+ EXOFS_DBGMSG("ret=>%d\n", ret);
+ return ret;
+}
+
+int exofs_write_inode(struct inode *inode, int wait)
+{
+ return exofs_update_inode(inode, wait);
+}
+
+/*
+ * Callback function from exofs_delete_inode() - don't have much cleaning up to
+ * do.
+ */
+static void delete_done(struct osd_request *or, void *p)
+{
+ struct exofs_sb_info *sbi;
+ osd_end_request(or);
+ sbi = p;
+ atomic_dec(&sbi->s_curr_pending);
+}
+
+/*
+ * Called when the refcount of an inode reaches zero. We remove the object
+ * from the OSD here. We make sure the object was created before we try and
+ * delete it.
+ */
+void exofs_delete_inode(struct inode *inode)
+{
+ struct exofs_i_info *oi = exofs_i(inode);
+ struct super_block *sb = inode->i_sb;
+ struct exofs_sb_info *sbi = sb->s_fs_info;
+ struct osd_obj_id obj = {sbi->s_pid, inode->i_ino + EXOFS_OBJ_OFF};
+ struct osd_request *or;
+ int ret;
+
+ truncate_inode_pages(&inode->i_data, 0);
+
+ if (is_bad_inode(inode))
+ goto no_delete;
+
+ mark_inode_dirty(inode);
+ exofs_update_inode(inode, inode_needs_sync(inode));
+
+ inode->i_size = 0;
+ if (inode->i_blocks)
+ exofs_truncate(inode);
+
+ clear_inode(inode);
+
+ or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+ if (unlikely(!or)) {
+ EXOFS_ERR("exofs_delete_inode: osd_start_request failed\n");
+ return;
+ }
+
+ osd_req_remove_object(or, &obj);
+
+ /* if we are deleting an obj that hasn't been created yet, wait */
+ if (!obj_created(oi)) {
+ BUG_ON(!obj_2bcreated(oi));
+ wait_event(oi->i_wq, obj_created(oi));
+ }
+
+ ret = exofs_async_op(or, delete_done, sbi, oi->i_cred);
+ if (ret) {
+ EXOFS_ERR(
+ "ERROR: @exofs_delete_inode exofs_async_op failed\n");
+ osd_end_request(or);
+ return;
+ }
+ atomic_inc(&sbi->s_curr_pending);
+
+ return;
+
+no_delete:
+ clear_inode(inode);
+}
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c
new file mode 100644
index 00000000000..77fdd765e76
--- /dev/null
+++ b/fs/exofs/namei.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ * from
+ * linux/fs/minix/inode.c
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs 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. Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs 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 exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "exofs.h"
+
+static inline int exofs_add_nondir(struct dentry *dentry, struct inode *inode)
+{
+ int err = exofs_add_link(dentry, inode);
+ if (!err) {
+ d_instantiate(dentry, inode);
+ return 0;
+ }
+ inode_dec_link_count(inode);
+ iput(inode);
+ return err;
+}
+
+static struct dentry *exofs_lookup(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nd)
+{
+ struct inode *inode;
+ ino_t ino;
+
+ if (dentry->d_name.len > EXOFS_NAME_LEN)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ ino = exofs_inode_by_name(dir, dentry);
+ inode = NULL;
+ if (ino) {
+ inode = exofs_iget(dir->i_sb, ino);
+ if (IS_ERR(inode))
+ return ERR_CAST(inode);
+ }
+ return d_splice_alias(inode, dentry);
+}
+
+static int exofs_create(struct inode *dir, struct dentry *dentry, int mode,
+ struct nameidata *nd)
+{
+ struct inode *inode = exofs_new_inode(dir, mode);
+ int err = PTR_ERR(inode);
+ if (!IS_ERR(inode)) {
+ inode->i_op = &exofs_file_inode_operations;
+ inode->i_fop = &exofs_file_operations;
+ inode->i_mapping->a_ops = &exofs_aops;
+ mark_inode_dirty(inode);
+ err = exofs_add_nondir(dentry, inode);
+ }
+ return err;
+}
+
+static int exofs_mknod(struct inode *dir, struct dentry *dentry, int mode,
+ dev_t rdev)
+{
+ struct inode *inode;
+ int err;
+
+ if (!new_valid_dev(rdev))
+ return -EINVAL;
+
+ inode = exofs_new_inode(dir, mode);
+ err = PTR_ERR(inode);
+ if (!IS_ERR(inode)) {
+ init_special_inode(inode, inode->i_mode, rdev);
+ mark_inode_dirty(inode);
+ err = exofs_add_nondir(dentry, inode);
+ }
+ return err;
+}
+
+static int exofs_symlink(struct inode *dir, struct dentry *dentry,
+ const char *symname)
+{
+ struct super_block *sb = dir->i_sb;
+ int err = -ENAMETOOLONG;
+ unsigned l = strlen(symname)+1;
+ struct inode *inode;
+ struct exofs_i_info *oi;
+
+ if (l > sb->s_blocksize)
+ goto out;
+
+ inode = exofs_new_inode(dir, S_IFLNK | S_IRWXUGO);
+ err = PTR_ERR(inode);
+ if (IS_ERR(inode))
+ goto out;
+
+ oi = exofs_i(inode);
+ if (l > sizeof(oi->i_data)) {
+ /* slow symlink */
+ inode->i_op = &exofs_symlink_inode_operations;
+ inode->i_mapping->a_ops = &exofs_aops;
+ memset(oi->i_data, 0, sizeof(oi->i_data));
+
+ err = page_symlink(inode, symname, l);
+ if (err)
+ goto out_fail;
+ } else {
+ /* fast symlink */
+ inode->i_op = &exofs_fast_symlink_inode_operations;
+ memcpy(oi->i_data, symname, l);
+ inode->i_size = l-1;
+ }
+ mark_inode_dirty(inode);
+
+ err = exofs_add_nondir(dentry, inode);
+out:
+ return err;
+
+out_fail:
+ inode_dec_link_count(inode);
+ iput(inode);
+ goto out;
+}
+
+static int exofs_link(struct dentry *old_dentry, struct inode *dir,
+ struct dentry *dentry)
+{
+ struct inode *inode = old_dentry->d_inode;
+
+ if (inode->i_nlink >= EXOFS_LINK_MAX)
+ return -EMLINK;
+
+ inode->i_ctime = CURRENT_TIME;
+ inode_inc_link_count(inode);
+ atomic_inc(&inode->i_count);
+
+ return exofs_add_nondir(dentry, inode);
+}
+
+static int exofs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ struct inode *inode;
+ int err = -EMLINK;
+
+ if (dir->i_nlink >= EXOFS_LINK_MAX)
+ goto out;
+
+ inode_inc_link_count(dir);
+
+ inode = exofs_new_inode(dir, S_IFDIR | mode);
+ err = PTR_ERR(inode);
+ if (IS_ERR(inode))
+ goto out_dir;
+
+ inode->i_op = &exofs_dir_inode_operations;
+ inode->i_fop = &exofs_dir_operations;
+ inode->i_mapping->a_ops = &exofs_aops;
+
+ inode_inc_link_count(inode);
+
+ err = exofs_make_empty(inode, dir);
+ if (err)
+ goto out_fail;
+
+ err = exofs_add_link(dentry, inode);
+ if (err)
+ goto out_fail;
+
+ d_instantiate(dentry, inode);
+out:
+ return err;
+
+out_fail:
+ inode_dec_link_count(inode);
+ inode_dec_link_count(inode);
+ iput(inode);
+out_dir:
+ inode_dec_link_count(dir);
+ goto out;
+}
+
+static int exofs_unlink(struct inode *dir, struct dentry *dentry)
+{
+ struct inode *inode = dentry->d_inode;
+ struct exofs_dir_entry *de;
+ struct page *page;
+ int err = -ENOENT;
+
+ de = exofs_find_entry(dir, dentry, &page);
+ if (!de)
+ goto out;
+
+ err = exofs_delete_entry(de, page);
+ if (err)
+ goto out;
+
+ inode->i_ctime = dir->i_ctime;
+ inode_dec_link_count(inode);
+ err = 0;
+out:
+ return err;
+}
+
+static int exofs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+ struct inode *inode = dentry->d_inode;
+ int err = -ENOTEMPTY;
+
+ if (exofs_empty_dir(inode)) {
+ err = exofs_unlink(dir, dentry);
+ if (!err) {
+ inode->i_size = 0;
+ inode_dec_link_count(inode);
+ inode_dec_link_count(dir);
+ }
+ }
+ return err;
+}
+
+static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ struct inode *old_inode = old_dentry->d_inode;
+ struct inode *new_inode = new_dentry->d_inode;
+ struct page *dir_page = NULL;
+ struct exofs_dir_entry *dir_de = NULL;
+ struct page *old_page;
+ struct exofs_dir_entry *old_de;
+ int err = -ENOENT;
+
+ old_de = exofs_find_entry(old_dir, old_dentry, &old_page);
+ if (!old_de)
+ goto out;
+
+ if (S_ISDIR(old_inode->i_mode)) {
+ err = -EIO;
+ dir_de = exofs_dotdot(old_inode, &dir_page);
+ if (!dir_de)
+ goto out_old;
+ }
+
+ if (new_inode) {
+ struct page *new_page;
+ struct exofs_dir_entry *new_de;
+
+ err = -ENOTEMPTY;
+ if (dir_de && !exofs_empty_dir(new_inode))
+ goto out_dir;
+
+ err = -ENOENT;
+ new_de = exofs_find_entry(new_dir, new_dentry, &new_page);
+ if (!new_de)
+ goto out_dir;
+ inode_inc_link_count(old_inode);
+ err = exofs_set_link(new_dir, new_de, new_page, old_inode);
+ new_inode->i_ctime = CURRENT_TIME;
+ if (dir_de)
+ drop_nlink(new_inode);
+ inode_dec_link_count(new_inode);
+ if (err)
+ goto out_dir;
+ } else {
+ if (dir_de) {
+ err = -EMLINK;
+ if (new_dir->i_nlink >= EXOFS_LINK_MAX)
+ goto out_dir;
+ }
+ inode_inc_link_count(old_inode);
+ err = exofs_add_link(new_dentry, old_inode);
+ if (err) {
+ inode_dec_link_count(old_inode);
+ goto out_dir;
+ }
+ if (dir_de)
+ inode_inc_link_count(new_dir);
+ }
+
+ old_inode->i_ctime = CURRENT_TIME;
+
+ exofs_delete_entry(old_de, old_page);
+ inode_dec_link_count(old_inode);
+
+ if (dir_de) {
+ err = exofs_set_link(old_inode, dir_de, dir_page, new_dir);
+ inode_dec_link_count(old_dir);
+ if (err)
+ goto out_dir;
+ }
+ return 0;
+
+
+out_dir:
+ if (dir_de) {
+ kunmap(dir_page);
+ page_cache_release(dir_page);
+ }
+out_old:
+ kunmap(old_page);
+ page_cache_release(old_page);
+out:
+ return err;
+}
+
+const struct inode_operations exofs_dir_inode_operations = {
+ .create = exofs_create,
+ .lookup = exofs_lookup,
+ .link = exofs_link,
+ .unlink = exofs_unlink,
+ .symlink = exofs_symlink,
+ .mkdir = exofs_mkdir,
+ .rmdir = exofs_rmdir,
+ .mknod = exofs_mknod,
+ .rename = exofs_rename,
+ .setattr = exofs_setattr,
+};
+
+const struct inode_operations exofs_special_inode_operations = {
+ .setattr = exofs_setattr,
+};
diff --git a/fs/exofs/osd.c b/fs/exofs/osd.c
new file mode 100644
index 00000000000..b249ae97fb1
--- /dev/null
+++ b/fs/exofs/osd.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * This file is part of exofs.
+ *
+ * exofs 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. Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs 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 exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <scsi/scsi_device.h>
+#include <scsi/osd_sense.h>
+
+#include "exofs.h"
+
+int exofs_check_ok_resid(struct osd_request *or, u64 *in_resid, u64 *out_resid)
+{
+ struct osd_sense_info osi;
+ int ret = osd_req_decode_sense(or, &osi);
+
+ if (ret) { /* translate to Linux codes */
+ if (osi.additional_code == scsi_invalid_field_in_cdb) {
+ if (osi.cdb_field_offset == OSD_CFO_STARTING_BYTE)
+ ret = -EFAULT;
+ if (osi.cdb_field_offset == OSD_CFO_OBJECT_ID)
+ ret = -ENOENT;
+ else
+ ret = -EINVAL;
+ } else if (osi.additional_code == osd_quota_error)
+ ret = -ENOSPC;
+ else
+ ret = -EIO;
+ }
+
+ /* FIXME: should be include in osd_sense_info */
+ if (in_resid)
+ *in_resid = or->in.req ? or->in.req->data_len : 0;
+
+ if (out_resid)
+ *out_resid = or->out.req ? or->out.req->data_len : 0;
+
+ return ret;
+}
+
+void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], const struct osd_obj_id *obj)
+{
+ osd_sec_init_nosec_doall_caps(cred_a, obj, false, true);
+}
+
+/*
+ * Perform a synchronous OSD operation.
+ */
+int exofs_sync_op(struct osd_request *or, int timeout, uint8_t *credential)
+{
+ int ret;
+
+ or->timeout = timeout;
+ ret = osd_finalize_request(or, 0, credential, NULL);
+ if (ret) {
+ EXOFS_DBGMSG("Faild to osd_finalize_request() => %d\n", ret);
+ return ret;
+ }
+
+ ret = osd_execute_request(or);
+
+ if (ret)
+ EXOFS_DBGMSG("osd_execute_request() => %d\n", ret);
+ /* osd_req_decode_sense(or, ret); */
+ return ret;
+}
+
+/*
+ * Perform an asynchronous OSD operation.
+ */
+int exofs_async_op(struct osd_request *or, osd_req_done_fn *async_done,
+ void *caller_context, u8 *cred)
+{
+ int ret;
+
+ ret = osd_finalize_request(or, 0, cred, NULL);
+ if (ret) {
+ EXOFS_DBGMSG("Faild to osd_finalize_request() => %d\n", ret);
+ return ret;
+ }
+
+ ret = osd_execute_request_async(or, async_done, caller_context);
+
+ if (ret)
+ EXOFS_DBGMSG("osd_execute_request_async() => %d\n", ret);
+ return ret;
+}
+
+int extract_attr_from_req(struct osd_request *or, struct osd_attr *attr)
+{
+ struct osd_attr cur_attr = {.attr_page = 0}; /* start with zeros */
+ void *iter = NULL;
+ int nelem;
+
+ do {
+ nelem = 1;
+ osd_req_decode_get_attr_list(or, &cur_attr, &nelem, &iter);
+ if ((cur_attr.attr_page == attr->attr_page) &&
+ (cur_attr.attr_id == attr->attr_id)) {
+ attr->len = cur_attr.len;
+ attr->val_ptr = cur_attr.val_ptr;
+ return 0;
+ }
+ } while (iter);
+
+ return -EIO;
+}
+
+int osd_req_read_kern(struct osd_request *or,
+ const struct osd_obj_id *obj, u64 offset, void* buff, u64 len)
+{
+ struct request_queue *req_q = or->osd_dev->scsi_device->request_queue;
+ struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL);
+
+ if (!bio)
+ return -ENOMEM;
+
+ osd_req_read(or, obj, bio, offset);
+ return 0;
+}
+
+int osd_req_write_kern(struct osd_request *or,
+ const struct osd_obj_id *obj, u64 offset, void* buff, u64 len)
+{
+ struct request_queue *req_q = or->osd_dev->scsi_device->request_queue;
+ struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL);
+
+ if (!bio)
+ return -ENOMEM;
+
+ osd_req_write(or, obj, bio, offset);
+ return 0;
+}
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
new file mode 100644
index 00000000000..9f1985e857e
--- /dev/null
+++ b/fs/exofs/super.c
@@ -0,0 +1,584 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ * from
+ * linux/fs/minix/inode.c
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs 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. Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs 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 exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/string.h>
+#include <linux/parser.h>
+#include <linux/vfs.h>
+#include <linux/random.h>
+#include <linux/exportfs.h>
+
+#include "exofs.h"
+
+/******************************************************************************
+ * MOUNT OPTIONS
+ *****************************************************************************/
+
+/*
+ * struct to hold what we get from mount options
+ */
+struct exofs_mountopt {
+ const char *dev_name;
+ uint64_t pid;
+ int timeout;
+};
+
+/*
+ * exofs-specific mount-time options.
+ */
+enum { Opt_pid, Opt_to, Opt_mkfs, Opt_format, Opt_err };
+
+/*
+ * Our mount-time options. These should ideally be 64-bit unsigned, but the
+ * kernel's parsing functions do not currently support that. 32-bit should be
+ * sufficient for most applications now.
+ */
+static match_table_t tokens = {
+ {Opt_pid, "pid=%u"},
+ {Opt_to, "to=%u"},
+ {Opt_err, NULL}
+};
+
+/*
+ * The main option parsing method. Also makes sure that all of the mandatory
+ * mount options were set.
+ */
+static int parse_options(char *options, struct exofs_mountopt *opts)
+{
+ char *p;
+ substring_t args[MAX_OPT_ARGS];
+ int option;
+ bool s_pid = false;
+
+ EXOFS_DBGMSG("parse_options %s\n", options);
+ /* defaults */
+ memset(opts, 0, sizeof(*opts));
+ opts->timeout = BLK_DEFAULT_SG_TIMEOUT;
+
+ while ((p = strsep(&options, ",")) != NULL) {
+ int token;
+ char str[32];
+
+ if (!*p)
+ continue;
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_pid:
+ if (0 == match_strlcpy(str, &args[0], sizeof(str)))
+ return -EINVAL;
+ opts->pid = simple_strtoull(str, NULL, 0);
+ if (opts->pid < EXOFS_MIN_PID) {
+ EXOFS_ERR("Partition ID must be >= %u",
+ EXOFS_MIN_PID);
+ return -EINVAL;
+ }
+ s_pid = 1;
+ break;
+ case Opt_to:
+ if (match_int(&args[0], &option))
+ return -EINVAL;
+ if (option <= 0) {
+ EXOFS_ERR("Timout must be > 0");
+ return -EINVAL;
+ }
+ opts->timeout = option * HZ;
+ break;
+ }
+ }
+
+ if (!s_pid) {
+ EXOFS_ERR("Need to specify the following options:\n");
+ EXOFS_ERR(" -o pid=pid_no_to_use\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/******************************************************************************
+ * INODE CACHE
+ *****************************************************************************/
+
+/*
+ * Our inode cache. Isn't it pretty?
+ */
+static struct kmem_cache *exofs_inode_cachep;
+
+/*
+ * Allocate an inode in the cache
+ */
+static struct inode *exofs_alloc_inode(struct super_block *sb)
+{
+ struct exofs_i_info *oi;
+
+ oi = kmem_cache_alloc(exofs_inode_cachep, GFP_KERNEL);
+ if (!oi)
+ return NULL;
+
+ oi->vfs_inode.i_version = 1;
+ return &oi->vfs_inode;
+}
+
+/*
+ * Remove an inode from the cache
+ */
+static void exofs_destroy_inode(struct inode *inode)
+{
+ kmem_cache_free(exofs_inode_cachep, exofs_i(inode));
+}
+
+/*
+ * Initialize the inode
+ */
+static void exofs_init_once(void *foo)
+{
+ struct exofs_i_info *oi = foo;
+
+ inode_init_once(&oi->vfs_inode);
+}
+
+/*
+ * Create and initialize the inode cache
+ */
+static int init_inodecache(void)
+{
+ exofs_inode_cachep = kmem_cache_create("exofs_inode_cache",
+ sizeof(struct exofs_i_info), 0,
+ SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
+ exofs_init_once);
+ if (exofs_inode_cachep == NULL)
+ return -ENOMEM;
+ return 0;
+}
+
+/*
+ * Destroy the inode cache
+ */
+static void destroy_inodecache(void)
+{
+ kmem_cache_destroy(exofs_inode_cachep);
+}
+
+/******************************************************************************
+ * SUPERBLOCK FUNCTIONS
+ *****************************************************************************/
+static const struct super_operations exofs_sops;
+static const struct export_operations exofs_export_ops;
+
+/*
+ * Write the superblock to the OSD
+ */
+static void exofs_write_super(struct super_block *sb)
+{
+ struct exofs_sb_info *sbi;
+ struct exofs_fscb *fscb;
+ struct osd_request *or;
+ struct osd_obj_id obj;
+ int ret;
+
+ fscb = kzalloc(sizeof(struct exofs_fscb), GFP_KERNEL);
+ if (!fscb) {
+ EXOFS_ERR("exofs_write_super: memory allocation failed.\n");
+ return;
+ }
+
+ lock_kernel();
+ sbi = sb->s_fs_info;
+ fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
+ fscb->s_numfiles = cpu_to_le32(sbi->s_numfiles);
+ fscb->s_magic = cpu_to_le16(sb->s_magic);
+ fscb->s_newfs = 0;
+
+ or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+ if (unlikely(!or)) {
+ EXOFS_ERR("exofs_write_super: osd_start_request failed.\n");
+ goto out;
+ }
+
+ obj.partition = sbi->s_pid;
+ obj.id = EXOFS_SUPER_ID;
+ ret = osd_req_write_kern(or, &obj, 0, fscb, sizeof(*fscb));
+ if (unlikely(ret)) {
+ EXOFS_ERR("exofs_write_super: osd_req_write_kern failed.\n");
+ goto out;
+ }
+
+ ret = exofs_sync_op(or, sbi->s_timeout, sbi->s_cred);
+ if (unlikely(ret)) {
+ EXOFS_ERR("exofs_write_super: exofs_sync_op failed.\n");
+ goto out;
+ }
+ sb->s_dirt = 0;
+
+out:
+ if (or)
+ osd_end_request(or);
+ unlock_kernel();
+ kfree(fscb);
+}
+
+/*
+ * This function is called when the vfs is freeing the superblock. We just
+ * need to free our own part.
+ */
+static void exofs_put_super(struct super_block *sb)
+{
+ int num_pend;
+ struct exofs_sb_info *sbi = sb->s_fs_info;
+
+ /* make sure there are no pending commands */
+ for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0;
+ num_pend = atomic_read(&sbi->s_curr_pending)) {
+ wait_queue_head_t wq;
+ init_waitqueue_head(&wq);
+ wait_event_timeout(wq,
+ (atomic_read(&sbi->s_curr_pending) == 0),
+ msecs_to_jiffies(100));
+ }
+
+ osduld_put_device(sbi->s_dev);
+ kfree(sb->s_fs_info);
+ sb->s_fs_info = NULL;
+}
+
+/*
+ * Read the superblock from the OSD and fill in the fields
+ */
+static int exofs_fill_super(struct super_block *sb, void *data, int silent)
+{
+ struct inode *root;
+ struct exofs_mountopt *opts = data;
+ struct exofs_sb_info *sbi; /*extended info */
+ struct exofs_fscb fscb; /*on-disk superblock info */
+ struct osd_request *or = NULL;
+ struct osd_obj_id obj;
+ int ret;
+
+ sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+ if (!sbi)
+ return -ENOMEM;
+ sb->s_fs_info = sbi;
+
+ /* use mount options to fill superblock */
+ sbi->s_dev = osduld_path_lookup(opts->dev_name);
+ if (IS_ERR(sbi->s_dev)) {
+ ret = PTR_ERR(sbi->s_dev);
+ sbi->s_dev = NULL;
+ goto free_sbi;
+ }
+
+ sbi->s_pid = opts->pid;
+ sbi->s_timeout = opts->timeout;
+
+ /* fill in some other data by hand */
+ memset(sb->s_id, 0, sizeof(sb->s_id));
+ strcpy(sb->s_id, "exofs");
+ sb->s_blocksize = EXOFS_BLKSIZE;
+ sb->s_blocksize_bits = EXOFS_BLKSHIFT;
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
+ atomic_set(&sbi->s_curr_pending, 0);
+ sb->s_bdev = NULL;
+ sb->s_dev = 0;
+
+ /* read data from on-disk superblock object */
+ obj.partition = sbi->s_pid;
+ obj.id = EXOFS_SUPER_ID;
+ exofs_make_credential(sbi->s_cred, &obj);
+
+ or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+ if (unlikely(!or)) {
+ if (!silent)
+ EXOFS_ERR(
+ "exofs_fill_super: osd_start_request failed.\n");
+ ret = -ENOMEM;
+ goto free_sbi;
+ }
+ ret = osd_req_read_kern(or, &obj, 0, &fscb, sizeof(fscb));
+ if (unlikely(ret)) {
+ if (!silent)
+ EXOFS_ERR(
+ "exofs_fill_super: osd_req_read_kern failed.\n");
+ ret = -ENOMEM;
+ goto free_sbi;
+ }
+
+ ret = exofs_sync_op(or, sbi->s_timeout, sbi->s_cred);
+ if (unlikely(ret)) {
+ if (!silent)
+ EXOFS_ERR("exofs_fill_super: exofs_sync_op failed.\n");
+ ret = -EIO;
+ goto free_sbi;
+ }
+
+ sb->s_magic = le16_to_cpu(fscb.s_magic);
+ sbi->s_nextid = le64_to_cpu(fscb.s_nextid);
+ sbi->s_numfiles = le32_to_cpu(fscb.s_numfiles);
+
+ /* make sure what we read from the object store is correct */
+ if (sb->s_magic != EXOFS_SUPER_MAGIC) {
+ if (!silent)
+ EXOFS_ERR("ERROR: Bad magic value\n");
+ ret = -EINVAL;
+ goto free_sbi;
+ }
+
+ /* start generation numbers from a random point */
+ get_random_bytes(&sbi->s_next_generation, sizeof(u32));
+ spin_lock_init(&sbi->s_next_gen_lock);
+
+ /* set up operation vectors */
+ sb->s_op = &exofs_sops;
+ sb->s_export_op = &exofs_export_ops;
+ root = exofs_iget(sb, EXOFS_ROOT_ID - EXOFS_OBJ_OFF);
+ if (IS_ERR(root)) {
+ EXOFS_ERR("ERROR: exofs_iget failed\n");
+ ret = PTR_ERR(root);
+ goto free_sbi;
+ }
+ sb->s_root = d_alloc_root(root);
+ if (!sb->s_root) {
+ iput(root);
+ EXOFS_ERR("ERROR: get root inode failed\n");
+ ret = -ENOMEM;
+ goto free_sbi;
+ }
+
+ if (!S_ISDIR(root->i_mode)) {
+ dput(sb->s_root);
+ sb->s_root = NULL;
+ EXOFS_ERR("ERROR: corrupt root inode (mode = %hd)\n",
+ root->i_mode);
+ ret = -EINVAL;
+ goto free_sbi;
+ }
+
+ ret = 0;
+out:
+ if (or)
+ osd_end_request(or);
+ return ret;
+
+free_sbi:
+ osduld_put_device(sbi->s_dev); /* NULL safe */
+ kfree(sbi);
+ goto out;
+}
+
+/*
+ * Set up the superblock (calls exofs_fill_super eventually)
+ */
+static int exofs_get_sb(struct file_system_type *type,
+ int flags, const char *dev_name,
+ void *data, struct vfsmount *mnt)
+{
+ struct exofs_mountopt opts;
+ int ret;
+
+ ret = parse_options(data, &opts);
+ if (ret)
+ return ret;
+
+ opts.dev_name = dev_name;
+ return get_sb_nodev(type, flags, &opts, exofs_fill_super, mnt);
+}
+
+/*
+ * Return information about the file system state in the buffer. This is used
+ * by the 'df' command, for example.
+ */
+static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+ struct super_block *sb = dentry->d_sb;
+ struct exofs_sb_info *sbi = sb->s_fs_info;
+ struct osd_obj_id obj = {sbi->s_pid, 0};
+ struct osd_attr attrs[] = {
+ ATTR_DEF(OSD_APAGE_PARTITION_QUOTAS,
+ OSD_ATTR_PQ_CAPACITY_QUOTA, sizeof(__be64)),
+ ATTR_DEF(OSD_APAGE_PARTITION_INFORMATION,
+ OSD_ATTR_PI_USED_CAPACITY, sizeof(__be64)),
+ };
+ uint64_t capacity = ULLONG_MAX;
+ uint64_t used = ULLONG_MAX;
+ struct osd_request *or;
+ uint8_t cred_a[OSD_CAP_LEN];
+ int ret;
+
+ /* get used/capacity attributes */
+ exofs_make_credential(cred_a, &obj);
+
+ or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+ if (unlikely(!or)) {
+ EXOFS_DBGMSG("exofs_statfs: osd_start_request failed.\n");
+ return -ENOMEM;
+ }
+
+ osd_req_get_attributes(or, &obj);
+ osd_req_add_get_attr_list(or, attrs, ARRAY_SIZE(attrs));
+ ret = exofs_sync_op(or, sbi->s_timeout, cred_a);
+ if (unlikely(ret))
+ goto out;
+
+ ret = extract_attr_from_req(or, &attrs[0]);
+ if (likely(!ret))
+ capacity = get_unaligned_be64(attrs[0].val_ptr);
+ else
+ EXOFS_DBGMSG("exofs_statfs: get capacity failed.\n");
+
+ ret = extract_attr_from_req(or, &attrs[1]);
+ if (likely(!ret))
+ used = get_unaligned_be64(attrs[1].val_ptr);
+ else
+ EXOFS_DBGMSG("exofs_statfs: get used-space failed.\n");
+
+ /* fill in the stats buffer */
+ buf->f_type = EXOFS_SUPER_MAGIC;
+ buf->f_bsize = EXOFS_BLKSIZE;
+ buf->f_blocks = (capacity >> EXOFS_BLKSHIFT);
+ buf->f_bfree = ((capacity - used) >> EXOFS_BLKSHIFT);
+ buf->f_bavail = buf->f_bfree;
+ buf->f_files = sbi->s_numfiles;
+ buf->f_ffree = EXOFS_MAX_ID - sbi->s_numfiles;
+ buf->f_namelen = EXOFS_NAME_LEN;
+
+out:
+ osd_end_request(or);
+ return ret;
+}
+
+static const struct super_operations exofs_sops = {
+ .alloc_inode = exofs_alloc_inode,
+ .destroy_inode = exofs_destroy_inode,
+ .write_inode = exofs_write_inode,
+ .delete_inode = exofs_delete_inode,
+ .put_super = exofs_put_super,
+ .write_super = exofs_write_super,
+ .statfs = exofs_statfs,
+};
+
+/******************************************************************************
+ * EXPORT OPERATIONS
+ *****************************************************************************/
+
+struct dentry *exofs_get_parent(struct dentry *child)
+{
+ unsigned long ino = exofs_parent_ino(child);
+
+ if (!ino)
+ return NULL;
+
+ return d_obtain_alias(exofs_iget(child->d_inode->i_sb, ino));
+}
+
+static struct inode *exofs_nfs_get_inode(struct super_block *sb,
+ u64 ino, u32 generation)
+{
+ struct inode *inode;
+
+ inode = exofs_iget(sb, ino);
+ if (IS_ERR(inode))
+ return ERR_CAST(inode);
+ if (generation && inode->i_generation != generation) {
+ /* we didn't find the right inode.. */
+ iput(inode);
+ return ERR_PTR(-ESTALE);
+ }
+ return inode;
+}
+
+static struct dentry *exofs_fh_to_dentry(struct super_block *sb,
+ struct fid *fid, int fh_len, int fh_type)
+{
+ return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+ exofs_nfs_get_inode);
+}
+
+static struct dentry *exofs_fh_to_parent(struct super_block *sb,
+ struct fid *fid, int fh_len, int fh_type)
+{
+ return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+ exofs_nfs_get_inode);
+}
+
+static const struct export_operations exofs_export_ops = {
+ .fh_to_dentry = exofs_fh_to_dentry,
+ .fh_to_parent = exofs_fh_to_parent,
+ .get_parent = exofs_get_parent,
+};
+
+/******************************************************************************
+ * INSMOD/RMMOD
+ *****************************************************************************/
+
+/*
+ * struct that describes this file system
+ */
+static struct file_system_type exofs_type = {
+ .owner = THIS_MODULE,
+ .name = "exofs",
+ .get_sb = exofs_get_sb,
+ .kill_sb = generic_shutdown_super,
+};
+
+static int __init init_exofs(void)
+{
+ int err;
+
+ err = init_inodecache();
+ if (err)
+ goto out;
+
+ err = register_filesystem(&exofs_type);
+ if (err)
+ goto out_d;
+
+ return 0;
+out_d:
+ destroy_inodecache();
+out:
+ return err;
+}
+
+static void __exit exit_exofs(void)
+{
+ unregister_filesystem(&exofs_type);
+ destroy_inodecache();
+}
+
+MODULE_AUTHOR("Avishay Traeger <avishay@gmail.com>");
+MODULE_DESCRIPTION("exofs");
+MODULE_LICENSE("GPL");
+
+module_init(init_exofs)
+module_exit(exit_exofs)
diff --git a/fs/exofs/symlink.c b/fs/exofs/symlink.c
new file mode 100644
index 00000000000..36e2d7bc7f7
--- /dev/null
+++ b/fs/exofs/symlink.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ * from
+ * linux/fs/minix/inode.c
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs 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. Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs 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 exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/namei.h>
+
+#include "exofs.h"
+
+static void *exofs_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+ struct exofs_i_info *oi = exofs_i(dentry->d_inode);
+
+ nd_set_link(nd, (char *)oi->i_data);
+ return NULL;
+}
+
+const struct inode_operations exofs_symlink_inode_operations = {
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
+};
+
+const struct inode_operations exofs_fast_symlink_inode_operations = {
+ .readlink = generic_readlink,
+ .follow_link = exofs_follow_link,
+};
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index b43b9556366..acf67883110 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -590,9 +590,8 @@ static int ext2_get_blocks(struct inode *inode,
if (depth == 0)
return (err);
-reread:
- partial = ext2_get_branch(inode, depth, offsets, chain, &err);
+ partial = ext2_get_branch(inode, depth, offsets, chain, &err);
/* Simplest case - block found, no allocation needed */
if (!partial) {
first_block = le32_to_cpu(chain[depth - 1].key);
@@ -602,15 +601,16 @@ reread:
while (count < maxblocks && count <= blocks_to_boundary) {
ext2_fsblk_t blk;
- if (!verify_chain(chain, partial)) {
+ if (!verify_chain(chain, chain + depth - 1)) {
/*
* Indirect block might be removed by
* truncate while we were reading it.
* Handling of that case: forget what we've
* got now, go to reread.
*/
+ err = -EAGAIN;
count = 0;
- goto changed;
+ break;
}
blk = le32_to_cpu(*(chain[depth-1].p + count));
if (blk == first_block + count)
@@ -618,7 +618,8 @@ reread:
else
break;
}
- goto got_it;
+ if (err != -EAGAIN)
+ goto got_it;
}
/* Next simple case - plain lookup or failed read of indirect block */
@@ -626,6 +627,33 @@ reread:
goto cleanup;
mutex_lock(&ei->truncate_mutex);
+ /*
+ * If the indirect block is missing while we are reading
+ * the chain(ext3_get_branch() returns -EAGAIN err), or
+ * if the chain has been changed after we grab the semaphore,
+ * (either because another process truncated this branch, or
+ * another get_block allocated this branch) re-grab the chain to see if
+ * the request block has been allocated or not.
+ *
+ * Since we already block the truncate/other get_block
+ * at this point, we will have the current copy of the chain when we
+ * splice the branch into the tree.
+ */
+ if (err == -EAGAIN || !verify_chain(chain, partial)) {
+ while (partial > chain) {
+ brelse(partial->bh);
+ partial--;
+ }
+ partial = ext2_get_branch(inode, depth, offsets, chain, &err);
+ if (!partial) {
+ count++;
+ mutex_unlock(&ei->truncate_mutex);
+ if (err)
+ goto cleanup;
+ clear_buffer_new(bh_result);
+ goto got_it;
+ }
+ }
/*
* Okay, we need to do block allocation. Lazily initialize the block
@@ -683,12 +711,6 @@ cleanup:
partial--;
}
return err;
-changed:
- while (partial > chain) {
- brelse(partial->bh);
- partial--;
- }
- goto reread;
}
int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
diff --git a/fs/ext3/Kconfig b/fs/ext3/Kconfig
index 8e0cfe44b0f..fb3c1a21b13 100644
--- a/fs/ext3/Kconfig
+++ b/fs/ext3/Kconfig
@@ -28,6 +28,25 @@ config EXT3_FS
To compile this file system support as a module, choose M here: the
module will be called ext3.
+config EXT3_DEFAULTS_TO_ORDERED
+ bool "Default to 'data=ordered' in ext3 (legacy option)"
+ depends on EXT3_FS
+ help
+ If a filesystem does not explicitly specify a data ordering
+ mode, and the journal capability allowed it, ext3 used to
+ historically default to 'data=ordered'.
+
+ That was a rather unfortunate choice, because it leads to all
+ kinds of latency problems, and the 'data=writeback' mode is more
+ appropriate these days.
+
+ You should probably always answer 'n' here, and if you really
+ want to use 'data=ordered' mode, set it in the filesystem itself
+ with 'tune2fs -o journal_data_ordered'.
+
+ But if you really want to enable the legacy default, you can do
+ so by answering 'y' to this question.
+
config EXT3_FS_XATTR
bool "Ext3 extended attributes"
depends on EXT3_FS
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 521f8238b2f..5b49704b231 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -33,6 +33,10 @@
*/
static int ext3_release_file (struct inode * inode, struct file * filp)
{
+ if (EXT3_I(inode)->i_state & EXT3_STATE_FLUSH_ON_CLOSE) {
+ filemap_flush(inode->i_mapping);
+ EXT3_I(inode)->i_state &= ~EXT3_STATE_FLUSH_ON_CLOSE;
+ }
/* if we are the last writer on the inode, drop the block reservation */
if ((filp->f_mode & FMODE_WRITE) &&
(atomic_read(&inode->i_writecount) == 1))
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index d3ef6566b01..fcfa2436185 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1521,12 +1521,16 @@ static int ext3_ordered_writepage(struct page *page,
if (!page_has_buffers(page)) {
create_empty_buffers(page, inode->i_sb->s_blocksize,
(1 << BH_Dirty)|(1 << BH_Uptodate));
- } else if (!walk_page_buffers(NULL, page_buffers(page), 0, PAGE_CACHE_SIZE, NULL, buffer_unmapped)) {
- /* Provide NULL instead of get_block so that we catch bugs if buffers weren't really mapped */
- return block_write_full_page(page, NULL, wbc);
+ page_bufs = page_buffers(page);
+ } else {
+ page_bufs = page_buffers(page);
+ if (!walk_page_buffers(NULL, page_bufs, 0, PAGE_CACHE_SIZE,
+ NULL, buffer_unmapped)) {
+ /* Provide NULL get_block() to catch bugs if buffers
+ * weren't really mapped */
+ return block_write_full_page(page, NULL, wbc);
+ }
}
- page_bufs = page_buffers(page);
-
handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
if (IS_ERR(handle)) {
@@ -1581,6 +1585,15 @@ static int ext3_writeback_writepage(struct page *page,
if (ext3_journal_current_handle())
goto out_fail;
+ if (page_has_buffers(page)) {
+ if (!walk_page_buffers(NULL, page_buffers(page), 0,
+ PAGE_CACHE_SIZE, NULL, buffer_unmapped)) {
+ /* Provide NULL get_block() to catch bugs if buffers
+ * weren't really mapped */
+ return block_write_full_page(page, NULL, wbc);
+ }
+ }
+
handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
if (IS_ERR(handle)) {
ret = PTR_ERR(handle);
@@ -2363,6 +2376,9 @@ void ext3_truncate(struct inode *inode)
if (!ext3_can_truncate(inode))
return;
+ if (inode->i_size == 0 && ext3_should_writeback_data(inode))
+ ei->i_state |= EXT3_STATE_FLUSH_ON_CLOSE;
+
/*
* We have to lock the EOF page here, because lock_page() nests
* outside journal_start().
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 6ddaa0a42b2..6ff7b973023 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -2274,7 +2274,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
struct inode * old_inode, * new_inode;
struct buffer_head * old_bh, * new_bh, * dir_bh;
struct ext3_dir_entry_2 * old_de, * new_de;
- int retval;
+ int retval, flush_file = 0;
old_bh = new_bh = dir_bh = NULL;
@@ -2410,6 +2410,8 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
ext3_mark_inode_dirty(handle, new_inode);
if (!new_inode->i_nlink)
ext3_orphan_add(handle, new_inode);
+ if (ext3_should_writeback_data(new_inode))
+ flush_file = 1;
}
retval = 0;
@@ -2418,6 +2420,8 @@ end_rename:
brelse (old_bh);
brelse (new_bh);
ext3_journal_stop(handle);
+ if (retval == 0 && flush_file)
+ filemap_flush(old_inode->i_mapping);
return retval;
}
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 9e5b8e387e1..599dbfe504c 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -44,6 +44,12 @@
#include "acl.h"
#include "namei.h"
+#ifdef CONFIG_EXT3_DEFAULTS_TO_ORDERED
+ #define EXT3_MOUNT_DEFAULT_DATA_MODE EXT3_MOUNT_ORDERED_DATA
+#else
+ #define EXT3_MOUNT_DEFAULT_DATA_MODE EXT3_MOUNT_WRITEBACK_DATA
+#endif
+
static int ext3_load_journal(struct super_block *, struct ext3_super_block *,
unsigned long journal_devnum);
static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
@@ -1919,7 +1925,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
cope, else JOURNAL_DATA */
if (journal_check_available_features
(sbi->s_journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE))
- set_opt(sbi->s_mount_opt, ORDERED_DATA);
+ set_opt(sbi->s_mount_opt, DEFAULT_DATA_MODE);
else
set_opt(sbi->s_mount_opt, JOURNAL_DATA);
break;
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index 7505482a08f..418b6f3b0ae 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -18,7 +18,7 @@ config EXT4_FS
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, or formatting a new filesystem as an ext4
filesystem initially.
To compile this file system support as a module, choose M here. The
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index ac77d8b8251..6132353dcf6 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -342,7 +342,7 @@ static int ext4_valid_extent_idx(struct inode *inode,
ext4_fsblk_t block = idx_pblock(ext_idx);
struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
if (unlikely(block < le32_to_cpu(es->s_first_data_block) ||
- (block > ext4_blocks_count(es))))
+ (block >= ext4_blocks_count(es))))
return 0;
else
return 1;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index a2e7952bc5f..c6bd6ced3bb 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -372,16 +372,16 @@ static int ext4_block_to_path(struct inode *inode,
}
static int __ext4_check_blockref(const char *function, struct inode *inode,
- unsigned int *p, unsigned int max) {
+ __le32 *p, unsigned int max) {
unsigned int maxblocks = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es);
- unsigned int *bref = p;
+ __le32 *bref = p;
while (bref < p+max) {
- if (unlikely(*bref >= maxblocks)) {
+ if (unlikely(le32_to_cpu(*bref) >= maxblocks)) {
ext4_error(inode->i_sb, function,
"block reference %u >= max (%u) "
"in inode #%lu, offset=%d",
- *bref, maxblocks,
+ le32_to_cpu(*bref), maxblocks,
inode->i_ino, (int)(bref-p));
return -EIO;
}
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 9987bba99db..2958f4e6f22 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2508,6 +2508,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
if (EXT4_BLOCKS_PER_GROUP(sb) == 0)
goto cantfind_ext4;
+ /* check blocks count against device size */
+ blocks_count = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits;
+ if (blocks_count && ext4_blocks_count(es) > blocks_count) {
+ printk(KERN_WARNING "EXT4-fs: bad geometry: block count %llu "
+ "exceeds size of device (%llu blocks)\n",
+ ext4_blocks_count(es), blocks_count);
+ goto failed_mount;
+ }
+
/*
* It makes no sense for the first data block to be beyond the end
* of the filesystem.
diff --git a/fs/file_table.c b/fs/file_table.c
index b74a8e1da91..54018fe4884 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -169,7 +169,6 @@ struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry,
fmode_t mode, const struct file_operations *fop)
{
struct file *file;
- struct path;
file = get_empty_filp();
if (!file)
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index eed48063990..91013ff7dd5 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -435,7 +435,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
* If older_than_this is non-NULL, then only write out inodes which
* had their first dirtying at a time earlier than *older_than_this.
*
- * If we're a pdlfush thread, then implement pdflush collision avoidance
+ * If we're a pdflush thread, then implement pdflush collision avoidance
* against the entire list.
*
* If `bdi' is non-zero then we're being asked to writeback a specific queue.
diff --git a/fs/fscache/Kconfig b/fs/fscache/Kconfig
new file mode 100644
index 00000000000..9bbb8ce7bea
--- /dev/null
+++ b/fs/fscache/Kconfig
@@ -0,0 +1,56 @@
+
+config FSCACHE
+ tristate "General filesystem local caching manager"
+ depends on EXPERIMENTAL
+ select SLOW_WORK
+ help
+ This option enables a generic filesystem caching manager that can be
+ used by various network and other filesystems to cache data locally.
+ Different sorts of caches can be plugged in, depending on the
+ resources available.
+
+ See Documentation/filesystems/caching/fscache.txt for more information.
+
+config FSCACHE_STATS
+ bool "Gather statistical information on local caching"
+ depends on FSCACHE && PROC_FS
+ help
+ This option causes statistical information to be gathered on local
+ caching and exported through file:
+
+ /proc/fs/fscache/stats
+
+ The gathering of statistics adds a certain amount of overhead to
+ execution as there are a quite a few stats gathered, and on a
+ multi-CPU system these may be on cachelines that keep bouncing
+ between CPUs. On the other hand, the stats are very useful for
+ debugging purposes. Saying 'Y' here is recommended.
+
+ See Documentation/filesystems/caching/fscache.txt for more information.
+
+config FSCACHE_HISTOGRAM
+ bool "Gather latency information on local caching"
+ depends on FSCACHE && PROC_FS
+ help
+ This option causes latency information to be gathered on local
+ caching and exported through file:
+
+ /proc/fs/fscache/histogram
+
+ The generation of this histogram adds a certain amount of overhead to
+ execution as there are a number of points at which data is gathered,
+ and on a multi-CPU system these may be on cachelines that keep
+ bouncing between CPUs. On the other hand, the histogram may be
+ useful for debugging purposes. Saying 'N' here is recommended.
+
+ See Documentation/filesystems/caching/fscache.txt for more information.
+
+config FSCACHE_DEBUG
+ bool "Debug FS-Cache"
+ depends on FSCACHE
+ help
+ This permits debugging to be dynamically enabled in the local caching
+ management module. If this is set, the debugging output may be
+ enabled by setting bits in /sys/modules/fscache/parameter/debug.
+
+ See Documentation/filesystems/caching/fscache.txt for more information.
diff --git a/fs/fscache/Makefile b/fs/fscache/Makefile
new file mode 100644
index 00000000000..91571b95aac
--- /dev/null
+++ b/fs/fscache/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for general filesystem caching code
+#
+
+fscache-y := \
+ cache.o \
+ cookie.o \
+ fsdef.o \
+ main.o \
+ netfs.o \
+ object.o \
+ operation.o \
+ page.o
+
+fscache-$(CONFIG_PROC_FS) += proc.o
+fscache-$(CONFIG_FSCACHE_STATS) += stats.o
+fscache-$(CONFIG_FSCACHE_HISTOGRAM) += histogram.o
+
+obj-$(CONFIG_FSCACHE) := fscache.o
diff --git a/fs/fscache/cache.c b/fs/fscache/cache.c
new file mode 100644
index 00000000000..e21985bbb1f
--- /dev/null
+++ b/fs/fscache/cache.c
@@ -0,0 +1,415 @@
+/* FS-Cache cache handling
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL CACHE
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "internal.h"
+
+LIST_HEAD(fscache_cache_list);
+DECLARE_RWSEM(fscache_addremove_sem);
+DECLARE_WAIT_QUEUE_HEAD(fscache_cache_cleared_wq);
+EXPORT_SYMBOL(fscache_cache_cleared_wq);
+
+static LIST_HEAD(fscache_cache_tag_list);
+
+/*
+ * look up a cache tag
+ */
+struct fscache_cache_tag *__fscache_lookup_cache_tag(const char *name)
+{
+ struct fscache_cache_tag *tag, *xtag;
+
+ /* firstly check for the existence of the tag under read lock */
+ down_read(&fscache_addremove_sem);
+
+ list_for_each_entry(tag, &fscache_cache_tag_list, link) {
+ if (strcmp(tag->name, name) == 0) {
+ atomic_inc(&tag->usage);
+ up_read(&fscache_addremove_sem);
+ return tag;
+ }
+ }
+
+ up_read(&fscache_addremove_sem);
+
+ /* the tag does not exist - create a candidate */
+ xtag = kzalloc(sizeof(*xtag) + strlen(name) + 1, GFP_KERNEL);
+ if (!xtag)
+ /* return a dummy tag if out of memory */
+ return ERR_PTR(-ENOMEM);
+
+ atomic_set(&xtag->usage, 1);
+ strcpy(xtag->name, name);
+
+ /* write lock, search again and add if still not present */
+ down_write(&fscache_addremove_sem);
+
+ list_for_each_entry(tag, &fscache_cache_tag_list, link) {
+ if (strcmp(tag->name, name) == 0) {
+ atomic_inc(&tag->usage);
+ up_write(&fscache_addremove_sem);
+ kfree(xtag);
+ return tag;
+ }
+ }
+
+ list_add_tail(&xtag->link, &fscache_cache_tag_list);
+ up_write(&fscache_addremove_sem);
+ return xtag;
+}
+
+/*
+ * release a reference to a cache tag
+ */
+void __fscache_release_cache_tag(struct fscache_cache_tag *tag)
+{
+ if (tag != ERR_PTR(-ENOMEM)) {
+ down_write(&fscache_addremove_sem);
+
+ if (atomic_dec_and_test(&tag->usage))
+ list_del_init(&tag->link);
+ else
+ tag = NULL;
+
+ up_write(&fscache_addremove_sem);
+
+ kfree(tag);
+ }
+}
+
+/*
+ * select a cache in which to store an object
+ * - the cache addremove semaphore must be at least read-locked by the caller
+ * - the object will never be an index
+ */
+struct fscache_cache *fscache_select_cache_for_object(
+ struct fscache_cookie *cookie)
+{
+ struct fscache_cache_tag *tag;
+ struct fscache_object *object;
+ struct fscache_cache *cache;
+
+ _enter("");
+
+ if (list_empty(&fscache_cache_list)) {
+ _leave(" = NULL [no cache]");
+ return NULL;
+ }
+
+ /* we check the parent to determine the cache to use */
+ spin_lock(&cookie->lock);
+
+ /* the first in the parent's backing list should be the preferred
+ * cache */
+ if (!hlist_empty(&cookie->backing_objects)) {
+ object = hlist_entry(cookie->backing_objects.first,
+ struct fscache_object, cookie_link);
+
+ cache = object->cache;
+ if (object->state >= FSCACHE_OBJECT_DYING ||
+ test_bit(FSCACHE_IOERROR, &cache->flags))
+ cache = NULL;
+
+ spin_unlock(&cookie->lock);
+ _leave(" = %p [parent]", cache);
+ return cache;
+ }
+
+ /* the parent is unbacked */
+ if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
+ /* cookie not an index and is unbacked */
+ spin_unlock(&cookie->lock);
+ _leave(" = NULL [cookie ub,ni]");
+ return NULL;
+ }
+
+ spin_unlock(&cookie->lock);
+
+ if (!cookie->def->select_cache)
+ goto no_preference;
+
+ /* ask the netfs for its preference */
+ tag = cookie->def->select_cache(cookie->parent->netfs_data,
+ cookie->netfs_data);
+ if (!tag)
+ goto no_preference;
+
+ if (tag == ERR_PTR(-ENOMEM)) {
+ _leave(" = NULL [nomem tag]");
+ return NULL;
+ }
+
+ if (!tag->cache) {
+ _leave(" = NULL [unbacked tag]");
+ return NULL;
+ }
+
+ if (test_bit(FSCACHE_IOERROR, &tag->cache->flags))
+ return NULL;
+
+ _leave(" = %p [specific]", tag->cache);
+ return tag->cache;
+
+no_preference:
+ /* netfs has no preference - just select first cache */
+ cache = list_entry(fscache_cache_list.next,
+ struct fscache_cache, link);
+ _leave(" = %p [first]", cache);
+ return cache;
+}
+
+/**
+ * fscache_init_cache - Initialise a cache record
+ * @cache: The cache record to be initialised
+ * @ops: The cache operations to be installed in that record
+ * @idfmt: Format string to define identifier
+ * @...: sprintf-style arguments
+ *
+ * Initialise a record of a cache and fill in the name.
+ *
+ * See Documentation/filesystems/caching/backend-api.txt for a complete
+ * description.
+ */
+void fscache_init_cache(struct fscache_cache *cache,
+ const struct fscache_cache_ops *ops,
+ const char *idfmt,
+ ...)
+{
+ va_list va;
+
+ memset(cache, 0, sizeof(*cache));
+
+ cache->ops = ops;
+
+ va_start(va, idfmt);
+ vsnprintf(cache->identifier, sizeof(cache->identifier), idfmt, va);
+ va_end(va);
+
+ INIT_WORK(&cache->op_gc, fscache_operation_gc);
+ INIT_LIST_HEAD(&cache->link);
+ INIT_LIST_HEAD(&cache->object_list);
+ INIT_LIST_HEAD(&cache->op_gc_list);
+ spin_lock_init(&cache->object_list_lock);
+ spin_lock_init(&cache->op_gc_list_lock);
+}
+EXPORT_SYMBOL(fscache_init_cache);
+
+/**
+ * fscache_add_cache - Declare a cache as being open for business
+ * @cache: The record describing the cache
+ * @ifsdef: The record of the cache object describing the top-level index
+ * @tagname: The tag describing this cache
+ *
+ * Add a cache to the system, making it available for netfs's to use.
+ *
+ * See Documentation/filesystems/caching/backend-api.txt for a complete
+ * description.
+ */
+int fscache_add_cache(struct fscache_cache *cache,
+ struct fscache_object *ifsdef,
+ const char *tagname)
+{
+ struct fscache_cache_tag *tag;
+
+ BUG_ON(!cache->ops);
+ BUG_ON(!ifsdef);
+
+ cache->flags = 0;
+ ifsdef->event_mask = ULONG_MAX & ~(1 << FSCACHE_OBJECT_EV_CLEARED);
+ ifsdef->state = FSCACHE_OBJECT_ACTIVE;
+
+ if (!tagname)
+ tagname = cache->identifier;
+
+ BUG_ON(!tagname[0]);
+
+ _enter("{%s.%s},,%s", cache->ops->name, cache->identifier, tagname);
+
+ /* we use the cache tag to uniquely identify caches */
+ tag = __fscache_lookup_cache_tag(tagname);
+ if (IS_ERR(tag))
+ goto nomem;
+
+ if (test_and_set_bit(FSCACHE_TAG_RESERVED, &tag->flags))
+ goto tag_in_use;
+
+ cache->kobj = kobject_create_and_add(tagname, fscache_root);
+ if (!cache->kobj)
+ goto error;
+
+ ifsdef->cookie = &fscache_fsdef_index;
+ ifsdef->cache = cache;
+ cache->fsdef = ifsdef;
+
+ down_write(&fscache_addremove_sem);
+
+ tag->cache = cache;
+ cache->tag = tag;
+
+ /* add the cache to the list */
+ list_add(&cache->link, &fscache_cache_list);
+
+ /* add the cache's netfs definition index object to the cache's
+ * list */
+ spin_lock(&cache->object_list_lock);
+ list_add_tail(&ifsdef->cache_link, &cache->object_list);
+ spin_unlock(&cache->object_list_lock);
+
+ /* add the cache's netfs definition index object to the top level index
+ * cookie as a known backing object */
+ spin_lock(&fscache_fsdef_index.lock);
+
+ hlist_add_head(&ifsdef->cookie_link,
+ &fscache_fsdef_index.backing_objects);
+
+ atomic_inc(&fscache_fsdef_index.usage);
+
+ /* done */
+ spin_unlock(&fscache_fsdef_index.lock);
+ up_write(&fscache_addremove_sem);
+
+ printk(KERN_NOTICE "FS-Cache: Cache \"%s\" added (type %s)\n",
+ cache->tag->name, cache->ops->name);
+ kobject_uevent(cache->kobj, KOBJ_ADD);
+
+ _leave(" = 0 [%s]", cache->identifier);
+ return 0;
+
+tag_in_use:
+ printk(KERN_ERR "FS-Cache: Cache tag '%s' already in use\n", tagname);
+ __fscache_release_cache_tag(tag);
+ _leave(" = -EXIST");
+ return -EEXIST;
+
+error:
+ __fscache_release_cache_tag(tag);
+ _leave(" = -EINVAL");
+ return -EINVAL;
+
+nomem:
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+}
+EXPORT_SYMBOL(fscache_add_cache);
+
+/**
+ * fscache_io_error - Note a cache I/O error
+ * @cache: The record describing the cache
+ *
+ * Note that an I/O error occurred in a cache and that it should no longer be
+ * used for anything. This also reports the error into the kernel log.
+ *
+ * See Documentation/filesystems/caching/backend-api.txt for a complete
+ * description.
+ */
+void fscache_io_error(struct fscache_cache *cache)
+{
+ set_bit(FSCACHE_IOERROR, &cache->flags);
+
+ printk(KERN_ERR "FS-Cache: Cache %s stopped due to I/O error\n",
+ cache->ops->name);
+}
+EXPORT_SYMBOL(fscache_io_error);
+
+/*
+ * request withdrawal of all the objects in a cache
+ * - all the objects being withdrawn are moved onto the supplied list
+ */
+static void fscache_withdraw_all_objects(struct fscache_cache *cache,
+ struct list_head *dying_objects)
+{
+ struct fscache_object *object;
+
+ spin_lock(&cache->object_list_lock);
+
+ while (!list_empty(&cache->object_list)) {
+ object = list_entry(cache->object_list.next,
+ struct fscache_object, cache_link);
+ list_move_tail(&object->cache_link, dying_objects);
+
+ _debug("withdraw %p", object->cookie);
+
+ spin_lock(&object->lock);
+ spin_unlock(&cache->object_list_lock);
+ fscache_raise_event(object, FSCACHE_OBJECT_EV_WITHDRAW);
+ spin_unlock(&object->lock);
+
+ cond_resched();
+ spin_lock(&cache->object_list_lock);
+ }
+
+ spin_unlock(&cache->object_list_lock);
+}
+
+/**
+ * fscache_withdraw_cache - Withdraw a cache from the active service
+ * @cache: The record describing the cache
+ *
+ * Withdraw a cache from service, unbinding all its cache objects from the
+ * netfs cookies they're currently representing.
+ *
+ * See Documentation/filesystems/caching/backend-api.txt for a complete
+ * description.
+ */
+void fscache_withdraw_cache(struct fscache_cache *cache)
+{
+ LIST_HEAD(dying_objects);
+
+ _enter("");
+
+ printk(KERN_NOTICE "FS-Cache: Withdrawing cache \"%s\"\n",
+ cache->tag->name);
+
+ /* make the cache unavailable for cookie acquisition */
+ if (test_and_set_bit(FSCACHE_CACHE_WITHDRAWN, &cache->flags))
+ BUG();
+
+ down_write(&fscache_addremove_sem);
+ list_del_init(&cache->link);
+ cache->tag->cache = NULL;
+ up_write(&fscache_addremove_sem);
+
+ /* make sure all pages pinned by operations on behalf of the netfs are
+ * written to disk */
+ cache->ops->sync_cache(cache);
+
+ /* dissociate all the netfs pages backed by this cache from the block
+ * mappings in the cache */
+ cache->ops->dissociate_pages(cache);
+
+ /* we now have to destroy all the active objects pertaining to this
+ * cache - which we do by passing them off to thread pool to be
+ * disposed of */
+ _debug("destroy");
+
+ fscache_withdraw_all_objects(cache, &dying_objects);
+
+ /* wait for all extant objects to finish their outstanding operations
+ * and go away */
+ _debug("wait for finish");
+ wait_event(fscache_cache_cleared_wq,
+ atomic_read(&cache->object_count) == 0);
+ _debug("wait for clearance");
+ wait_event(fscache_cache_cleared_wq,
+ list_empty(&cache->object_list));
+ _debug("cleared");
+ ASSERT(list_empty(&dying_objects));
+
+ kobject_put(cache->kobj);
+
+ clear_bit(FSCACHE_TAG_RESERVED, &cache->tag->flags);
+ fscache_release_cache_tag(cache->tag);
+ cache->tag = NULL;
+
+ _leave("");
+}
+EXPORT_SYMBOL(fscache_withdraw_cache);
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
new file mode 100644
index 00000000000..72fd18f6c71
--- /dev/null
+++ b/fs/fscache/cookie.c
@@ -0,0 +1,500 @@
+/* netfs cookie management
+ *
+ * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for more information on
+ * the netfs API.
+ */
+
+#define FSCACHE_DEBUG_LEVEL COOKIE
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "internal.h"
+
+struct kmem_cache *fscache_cookie_jar;
+
+static atomic_t fscache_object_debug_id = ATOMIC_INIT(0);
+
+static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie);
+static int fscache_alloc_object(struct fscache_cache *cache,
+ struct fscache_cookie *cookie);
+static int fscache_attach_object(struct fscache_cookie *cookie,
+ struct fscache_object *object);
+
+/*
+ * initialise an cookie jar slab element prior to any use
+ */
+void fscache_cookie_init_once(void *_cookie)
+{
+ struct fscache_cookie *cookie = _cookie;
+
+ memset(cookie, 0, sizeof(*cookie));
+ spin_lock_init(&cookie->lock);
+ INIT_HLIST_HEAD(&cookie->backing_objects);
+}
+
+/*
+ * request a cookie to represent an object (index, datafile, xattr, etc)
+ * - parent specifies the parent object
+ * - the top level index cookie for each netfs is stored in the fscache_netfs
+ * struct upon registration
+ * - def points to the definition
+ * - the netfs_data will be passed to the functions pointed to in *def
+ * - all attached caches will be searched to see if they contain this object
+ * - index objects aren't stored on disk until there's a dependent file that
+ * needs storing
+ * - other objects are stored in a selected cache immediately, and all the
+ * indices forming the path to it are instantiated if necessary
+ * - we never let on to the netfs about errors
+ * - we may set a negative cookie pointer, but that's okay
+ */
+struct fscache_cookie *__fscache_acquire_cookie(
+ struct fscache_cookie *parent,
+ const struct fscache_cookie_def *def,
+ void *netfs_data)
+{
+ struct fscache_cookie *cookie;
+
+ BUG_ON(!def);
+
+ _enter("{%s},{%s},%p",
+ parent ? (char *) parent->def->name : "<no-parent>",
+ def->name, netfs_data);
+
+ fscache_stat(&fscache_n_acquires);
+
+ /* if there's no parent cookie, then we don't create one here either */
+ if (!parent) {
+ fscache_stat(&fscache_n_acquires_null);
+ _leave(" [no parent]");
+ return NULL;
+ }
+
+ /* validate the definition */
+ BUG_ON(!def->get_key);
+ BUG_ON(!def->name[0]);
+
+ BUG_ON(def->type == FSCACHE_COOKIE_TYPE_INDEX &&
+ parent->def->type != FSCACHE_COOKIE_TYPE_INDEX);
+
+ /* allocate and initialise a cookie */
+ cookie = kmem_cache_alloc(fscache_cookie_jar, GFP_KERNEL);
+ if (!cookie) {
+ fscache_stat(&fscache_n_acquires_oom);
+ _leave(" [ENOMEM]");
+ return NULL;
+ }
+
+ atomic_set(&cookie->usage, 1);
+ atomic_set(&cookie->n_children, 0);
+
+ atomic_inc(&parent->usage);
+ atomic_inc(&parent->n_children);
+
+ cookie->def = def;
+ cookie->parent = parent;
+ cookie->netfs_data = netfs_data;
+ cookie->flags = 0;
+
+ INIT_RADIX_TREE(&cookie->stores, GFP_NOFS);
+
+ switch (cookie->def->type) {
+ case FSCACHE_COOKIE_TYPE_INDEX:
+ fscache_stat(&fscache_n_cookie_index);
+ break;
+ case FSCACHE_COOKIE_TYPE_DATAFILE:
+ fscache_stat(&fscache_n_cookie_data);
+ break;
+ default:
+ fscache_stat(&fscache_n_cookie_special);
+ break;
+ }
+
+ /* if the object is an index then we need do nothing more here - we
+ * create indices on disk when we need them as an index may exist in
+ * multiple caches */
+ if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
+ if (fscache_acquire_non_index_cookie(cookie) < 0) {
+ atomic_dec(&parent->n_children);
+ __fscache_cookie_put(cookie);
+ fscache_stat(&fscache_n_acquires_nobufs);
+ _leave(" = NULL");
+ return NULL;
+ }
+ }
+
+ fscache_stat(&fscache_n_acquires_ok);
+ _leave(" = %p", cookie);
+ return cookie;
+}
+EXPORT_SYMBOL(__fscache_acquire_cookie);
+
+/*
+ * acquire a non-index cookie
+ * - this must make sure the index chain is instantiated and instantiate the
+ * object representation too
+ */
+static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
+{
+ struct fscache_object *object;
+ struct fscache_cache *cache;
+ uint64_t i_size;
+ int ret;
+
+ _enter("");
+
+ cookie->flags = 1 << FSCACHE_COOKIE_UNAVAILABLE;
+
+ /* now we need to see whether the backing objects for this cookie yet
+ * exist, if not there'll be nothing to search */
+ down_read(&fscache_addremove_sem);
+
+ if (list_empty(&fscache_cache_list)) {
+ up_read(&fscache_addremove_sem);
+ _leave(" = 0 [no caches]");
+ return 0;
+ }
+
+ /* select a cache in which to store the object */
+ cache = fscache_select_cache_for_object(cookie->parent);
+ if (!cache) {
+ up_read(&fscache_addremove_sem);
+ fscache_stat(&fscache_n_acquires_no_cache);
+ _leave(" = -ENOMEDIUM [no cache]");
+ return -ENOMEDIUM;
+ }
+
+ _debug("cache %s", cache->tag->name);
+
+ cookie->flags =
+ (1 << FSCACHE_COOKIE_LOOKING_UP) |
+ (1 << FSCACHE_COOKIE_CREATING) |
+ (1 << FSCACHE_COOKIE_NO_DATA_YET);
+
+ /* ask the cache to allocate objects for this cookie and its parent
+ * chain */
+ ret = fscache_alloc_object(cache, cookie);
+ if (ret < 0) {
+ up_read(&fscache_addremove_sem);
+ _leave(" = %d", ret);
+ return ret;
+ }
+
+ /* pass on how big the object we're caching is supposed to be */
+ cookie->def->get_attr(cookie->netfs_data, &i_size);
+
+ spin_lock(&cookie->lock);
+ if (hlist_empty(&cookie->backing_objects)) {
+ spin_unlock(&cookie->lock);
+ goto unavailable;
+ }
+
+ object = hlist_entry(cookie->backing_objects.first,
+ struct fscache_object, cookie_link);
+
+ fscache_set_store_limit(object, i_size);
+
+ /* initiate the process of looking up all the objects in the chain
+ * (done by fscache_initialise_object()) */
+ fscache_enqueue_object(object);
+
+ spin_unlock(&cookie->lock);
+
+ /* we may be required to wait for lookup to complete at this point */
+ if (!fscache_defer_lookup) {
+ _debug("non-deferred lookup %p", &cookie->flags);
+ wait_on_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP,
+ fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+ _debug("complete");
+ if (test_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags))
+ goto unavailable;
+ }
+
+ up_read(&fscache_addremove_sem);
+ _leave(" = 0 [deferred]");
+ return 0;
+
+unavailable:
+ up_read(&fscache_addremove_sem);
+ _leave(" = -ENOBUFS");
+ return -ENOBUFS;
+}
+
+/*
+ * recursively allocate cache object records for a cookie/cache combination
+ * - caller must be holding the addremove sem
+ */
+static int fscache_alloc_object(struct fscache_cache *cache,
+ struct fscache_cookie *cookie)
+{
+ struct fscache_object *object;
+ struct hlist_node *_n;
+ int ret;
+
+ _enter("%p,%p{%s}", cache, cookie, cookie->def->name);
+
+ spin_lock(&cookie->lock);
+ hlist_for_each_entry(object, _n, &cookie->backing_objects,
+ cookie_link) {
+ if (object->cache == cache)
+ goto object_already_extant;
+ }
+ spin_unlock(&cookie->lock);
+
+ /* ask the cache to allocate an object (we may end up with duplicate
+ * objects at this stage, but we sort that out later) */
+ object = cache->ops->alloc_object(cache, cookie);
+ if (IS_ERR(object)) {
+ fscache_stat(&fscache_n_object_no_alloc);
+ ret = PTR_ERR(object);
+ goto error;
+ }
+
+ fscache_stat(&fscache_n_object_alloc);
+
+ object->debug_id = atomic_inc_return(&fscache_object_debug_id);
+
+ _debug("ALLOC OBJ%x: %s {%lx}",
+ object->debug_id, cookie->def->name, object->events);
+
+ ret = fscache_alloc_object(cache, cookie->parent);
+ if (ret < 0)
+ goto error_put;
+
+ /* only attach if we managed to allocate all we needed, otherwise
+ * discard the object we just allocated and instead use the one
+ * attached to the cookie */
+ if (fscache_attach_object(cookie, object) < 0)
+ cache->ops->put_object(object);
+
+ _leave(" = 0");
+ return 0;
+
+object_already_extant:
+ ret = -ENOBUFS;
+ if (object->state >= FSCACHE_OBJECT_DYING) {
+ spin_unlock(&cookie->lock);
+ goto error;
+ }
+ spin_unlock(&cookie->lock);
+ _leave(" = 0 [found]");
+ return 0;
+
+error_put:
+ cache->ops->put_object(object);
+error:
+ _leave(" = %d", ret);
+ return ret;
+}
+
+/*
+ * attach a cache object to a cookie
+ */
+static int fscache_attach_object(struct fscache_cookie *cookie,
+ struct fscache_object *object)
+{
+ struct fscache_object *p;
+ struct fscache_cache *cache = object->cache;
+ struct hlist_node *_n;
+ int ret;
+
+ _enter("{%s},{OBJ%x}", cookie->def->name, object->debug_id);
+
+ spin_lock(&cookie->lock);
+
+ /* there may be multiple initial creations of this object, but we only
+ * want one */
+ ret = -EEXIST;
+ hlist_for_each_entry(p, _n, &cookie->backing_objects, cookie_link) {
+ if (p->cache == object->cache) {
+ if (p->state >= FSCACHE_OBJECT_DYING)
+ ret = -ENOBUFS;
+ goto cant_attach_object;
+ }
+ }
+
+ /* pin the parent object */
+ spin_lock_nested(&cookie->parent->lock, 1);
+ hlist_for_each_entry(p, _n, &cookie->parent->backing_objects,
+ cookie_link) {
+ if (p->cache == object->cache) {
+ if (p->state >= FSCACHE_OBJECT_DYING) {
+ ret = -ENOBUFS;
+ spin_unlock(&cookie->parent->lock);
+ goto cant_attach_object;
+ }
+ object->parent = p;
+ spin_lock(&p->lock);
+ p->n_children++;
+ spin_unlock(&p->lock);
+ break;
+ }
+ }
+ spin_unlock(&cookie->parent->lock);
+
+ /* attach to the cache's object list */
+ if (list_empty(&object->cache_link)) {
+ spin_lock(&cache->object_list_lock);
+ list_add(&object->cache_link, &cache->object_list);
+ spin_unlock(&cache->object_list_lock);
+ }
+
+ /* attach to the cookie */
+ object->cookie = cookie;
+ atomic_inc(&cookie->usage);
+ hlist_add_head(&object->cookie_link, &cookie->backing_objects);
+ ret = 0;
+
+cant_attach_object:
+ spin_unlock(&cookie->lock);
+ _leave(" = %d", ret);
+ return ret;
+}
+
+/*
+ * update the index entries backing a cookie
+ */
+void __fscache_update_cookie(struct fscache_cookie *cookie)
+{
+ struct fscache_object *object;
+ struct hlist_node *_p;
+
+ fscache_stat(&fscache_n_updates);
+
+ if (!cookie) {
+ fscache_stat(&fscache_n_updates_null);
+ _leave(" [no cookie]");
+ return;
+ }
+
+ _enter("{%s}", cookie->def->name);
+
+ BUG_ON(!cookie->def->get_aux);
+
+ spin_lock(&cookie->lock);
+
+ /* update the index entry on disk in each cache backing this cookie */
+ hlist_for_each_entry(object, _p,
+ &cookie->backing_objects, cookie_link) {
+ fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE);
+ }
+
+ spin_unlock(&cookie->lock);
+ _leave("");
+}
+EXPORT_SYMBOL(__fscache_update_cookie);
+
+/*
+ * release a cookie back to the cache
+ * - the object will be marked as recyclable on disk if retire is true
+ * - all dependents of this cookie must have already been unregistered
+ * (indices/files/pages)
+ */
+void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
+{
+ struct fscache_cache *cache;
+ struct fscache_object *object;
+ unsigned long event;
+
+ fscache_stat(&fscache_n_relinquishes);
+
+ if (!cookie) {
+ fscache_stat(&fscache_n_relinquishes_null);
+ _leave(" [no cookie]");
+ return;
+ }
+
+ _enter("%p{%s,%p},%d",
+ cookie, cookie->def->name, cookie->netfs_data, retire);
+
+ if (atomic_read(&cookie->n_children) != 0) {
+ printk(KERN_ERR "FS-Cache: Cookie '%s' still has children\n",
+ cookie->def->name);
+ BUG();
+ }
+
+ /* wait for the cookie to finish being instantiated (or to fail) */
+ if (test_bit(FSCACHE_COOKIE_CREATING, &cookie->flags)) {
+ fscache_stat(&fscache_n_relinquishes_waitcrt);
+ wait_on_bit(&cookie->flags, FSCACHE_COOKIE_CREATING,
+ fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+ }
+
+ event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE;
+
+ /* detach pointers back to the netfs */
+ spin_lock(&cookie->lock);
+
+ cookie->netfs_data = NULL;
+ cookie->def = NULL;
+
+ /* break links with all the active objects */
+ while (!hlist_empty(&cookie->backing_objects)) {
+ object = hlist_entry(cookie->backing_objects.first,
+ struct fscache_object,
+ cookie_link);
+
+ _debug("RELEASE OBJ%x", object->debug_id);
+
+ /* detach each cache object from the object cookie */
+ spin_lock(&object->lock);
+ hlist_del_init(&object->cookie_link);
+
+ cache = object->cache;
+ object->cookie = NULL;
+ fscache_raise_event(object, event);
+ spin_unlock(&object->lock);
+
+ if (atomic_dec_and_test(&cookie->usage))
+ /* the cookie refcount shouldn't be reduced to 0 yet */
+ BUG();
+ }
+
+ spin_unlock(&cookie->lock);
+
+ if (cookie->parent) {
+ ASSERTCMP(atomic_read(&cookie->parent->usage), >, 0);
+ ASSERTCMP(atomic_read(&cookie->parent->n_children), >, 0);
+ atomic_dec(&cookie->parent->n_children);
+ }
+
+ /* finally dispose of the cookie */
+ ASSERTCMP(atomic_read(&cookie->usage), >, 0);
+ fscache_cookie_put(cookie);
+
+ _leave("");
+}
+EXPORT_SYMBOL(__fscache_relinquish_cookie);
+
+/*
+ * destroy a cookie
+ */
+void __fscache_cookie_put(struct fscache_cookie *cookie)
+{
+ struct fscache_cookie *parent;
+
+ _enter("%p", cookie);
+
+ for (;;) {
+ _debug("FREE COOKIE %p", cookie);
+ parent = cookie->parent;
+ BUG_ON(!hlist_empty(&cookie->backing_objects));
+ kmem_cache_free(fscache_cookie_jar, cookie);
+
+ if (!parent)
+ break;
+
+ cookie = parent;
+ BUG_ON(atomic_read(&cookie->usage) <= 0);
+ if (!atomic_dec_and_test(&cookie->usage))
+ break;
+ }
+
+ _leave("");
+}
diff --git a/fs/fscache/fsdef.c b/fs/fscache/fsdef.c
new file mode 100644
index 00000000000..f5b4baee735
--- /dev/null
+++ b/fs/fscache/fsdef.c
@@ -0,0 +1,144 @@
+/* Filesystem index definition
+ *
+ * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL CACHE
+#include <linux/module.h>
+#include "internal.h"
+
+static uint16_t fscache_fsdef_netfs_get_key(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax);
+
+static uint16_t fscache_fsdef_netfs_get_aux(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax);
+
+static
+enum fscache_checkaux fscache_fsdef_netfs_check_aux(void *cookie_netfs_data,
+ const void *data,
+ uint16_t datalen);
+
+/*
+ * The root index is owned by FS-Cache itself.
+ *
+ * When a netfs requests caching facilities, FS-Cache will, if one doesn't
+ * already exist, create an entry in the root index with the key being the name
+ * of the netfs ("AFS" for example), and the auxiliary data holding the index
+ * structure version supplied by the netfs:
+ *
+ * FSDEF
+ * |
+ * +-----------+
+ * | |
+ * NFS AFS
+ * [v=1] [v=1]
+ *
+ * If an entry with the appropriate name does already exist, the version is
+ * compared. If the version is different, the entire subtree from that entry
+ * will be discarded and a new entry created.
+ *
+ * The new entry will be an index, and a cookie referring to it will be passed
+ * to the netfs. This is then the root handle by which the netfs accesses the
+ * cache. It can create whatever objects it likes in that index, including
+ * further indices.
+ */
+static struct fscache_cookie_def fscache_fsdef_index_def = {
+ .name = ".FS-Cache",
+ .type = FSCACHE_COOKIE_TYPE_INDEX,
+};
+
+struct fscache_cookie fscache_fsdef_index = {
+ .usage = ATOMIC_INIT(1),
+ .lock = __SPIN_LOCK_UNLOCKED(fscache_fsdef_index.lock),
+ .backing_objects = HLIST_HEAD_INIT,
+ .def = &fscache_fsdef_index_def,
+};
+EXPORT_SYMBOL(fscache_fsdef_index);
+
+/*
+ * Definition of an entry in the root index. Each entry is an index, keyed to
+ * a specific netfs and only applicable to a particular version of the index
+ * structure used by that netfs.
+ */
+struct fscache_cookie_def fscache_fsdef_netfs_def = {
+ .name = "FSDEF.netfs",
+ .type = FSCACHE_COOKIE_TYPE_INDEX,
+ .get_key = fscache_fsdef_netfs_get_key,
+ .get_aux = fscache_fsdef_netfs_get_aux,
+ .check_aux = fscache_fsdef_netfs_check_aux,
+};
+
+/*
+ * get the key data for an FSDEF index record - this is the name of the netfs
+ * for which this entry is created
+ */
+static uint16_t fscache_fsdef_netfs_get_key(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax)
+{
+ const struct fscache_netfs *netfs = cookie_netfs_data;
+ unsigned klen;
+
+ _enter("{%s.%u},", netfs->name, netfs->version);
+
+ klen = strlen(netfs->name);
+ if (klen > bufmax)
+ return 0;
+
+ memcpy(buffer, netfs->name, klen);
+ return klen;
+}
+
+/*
+ * get the auxiliary data for an FSDEF index record - this is the index
+ * structure version number of the netfs for which this version is created
+ */
+static uint16_t fscache_fsdef_netfs_get_aux(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax)
+{
+ const struct fscache_netfs *netfs = cookie_netfs_data;
+ unsigned dlen;
+
+ _enter("{%s.%u},", netfs->name, netfs->version);
+
+ dlen = sizeof(uint32_t);
+ if (dlen > bufmax)
+ return 0;
+
+ memcpy(buffer, &netfs->version, dlen);
+ return dlen;
+}
+
+/*
+ * check that the index structure version number stored in the auxiliary data
+ * matches the one the netfs gave us
+ */
+static enum fscache_checkaux fscache_fsdef_netfs_check_aux(
+ void *cookie_netfs_data,
+ const void *data,
+ uint16_t datalen)
+{
+ struct fscache_netfs *netfs = cookie_netfs_data;
+ uint32_t version;
+
+ _enter("{%s},,%hu", netfs->name, datalen);
+
+ if (datalen != sizeof(version)) {
+ _leave(" = OBSOLETE [dl=%d v=%zu]", datalen, sizeof(version));
+ return FSCACHE_CHECKAUX_OBSOLETE;
+ }
+
+ memcpy(&version, data, sizeof(version));
+ if (version != netfs->version) {
+ _leave(" = OBSOLETE [ver=%x net=%x]", version, netfs->version);
+ return FSCACHE_CHECKAUX_OBSOLETE;
+ }
+
+ _leave(" = OKAY");
+ return FSCACHE_CHECKAUX_OKAY;
+}
diff --git a/fs/fscache/histogram.c b/fs/fscache/histogram.c
new file mode 100644
index 00000000000..bad496748a5
--- /dev/null
+++ b/fs/fscache/histogram.c
@@ -0,0 +1,109 @@
+/* FS-Cache latency histogram
+ *
+ * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL THREAD
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+atomic_t fscache_obj_instantiate_histogram[HZ];
+atomic_t fscache_objs_histogram[HZ];
+atomic_t fscache_ops_histogram[HZ];
+atomic_t fscache_retrieval_delay_histogram[HZ];
+atomic_t fscache_retrieval_histogram[HZ];
+
+/*
+ * display the time-taken histogram
+ */
+static int fscache_histogram_show(struct seq_file *m, void *v)
+{
+ unsigned long index;
+ unsigned n[5], t;
+
+ switch ((unsigned long) v) {
+ case 1:
+ seq_puts(m, "JIFS SECS OBJ INST OP RUNS OBJ RUNS "
+ " RETRV DLY RETRIEVLS\n");
+ return 0;
+ case 2:
+ seq_puts(m, "===== ===== ========= ========= ========="
+ " ========= =========\n");
+ return 0;
+ default:
+ index = (unsigned long) v - 3;
+ n[0] = atomic_read(&fscache_obj_instantiate_histogram[index]);
+ n[1] = atomic_read(&fscache_ops_histogram[index]);
+ n[2] = atomic_read(&fscache_objs_histogram[index]);
+ n[3] = atomic_read(&fscache_retrieval_delay_histogram[index]);
+ n[4] = atomic_read(&fscache_retrieval_histogram[index]);
+ if (!(n[0] | n[1] | n[2] | n[3] | n[4]))
+ return 0;
+
+ t = (index * 1000) / HZ;
+
+ seq_printf(m, "%4lu 0.%03u %9u %9u %9u %9u %9u\n",
+ index, t, n[0], n[1], n[2], n[3], n[4]);
+ return 0;
+ }
+}
+
+/*
+ * set up the iterator to start reading from the first line
+ */
+static void *fscache_histogram_start(struct seq_file *m, loff_t *_pos)
+{
+ if ((unsigned long long)*_pos >= HZ + 2)
+ return NULL;
+ if (*_pos == 0)
+ *_pos = 1;
+ return (void *)(unsigned long) *_pos;
+}
+
+/*
+ * move to the next line
+ */
+static void *fscache_histogram_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ (*pos)++;
+ return (unsigned long long)*pos > HZ + 2 ?
+ NULL : (void *)(unsigned long) *pos;
+}
+
+/*
+ * clean up after reading
+ */
+static void fscache_histogram_stop(struct seq_file *m, void *v)
+{
+}
+
+static const struct seq_operations fscache_histogram_ops = {
+ .start = fscache_histogram_start,
+ .stop = fscache_histogram_stop,
+ .next = fscache_histogram_next,
+ .show = fscache_histogram_show,
+};
+
+/*
+ * open "/proc/fs/fscache/histogram" to provide latency data
+ */
+static int fscache_histogram_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &fscache_histogram_ops);
+}
+
+const struct file_operations fscache_histogram_fops = {
+ .owner = THIS_MODULE,
+ .open = fscache_histogram_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
new file mode 100644
index 00000000000..e0cbd16f6dc
--- /dev/null
+++ b/fs/fscache/internal.h
@@ -0,0 +1,380 @@
+/* Internal definitions for FS-Cache
+ *
+ * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * Lock order, in the order in which multiple locks should be obtained:
+ * - fscache_addremove_sem
+ * - cookie->lock
+ * - cookie->parent->lock
+ * - cache->object_list_lock
+ * - object->lock
+ * - object->parent->lock
+ * - fscache_thread_lock
+ *
+ */
+
+#include <linux/fscache-cache.h>
+#include <linux/sched.h>
+
+#define FSCACHE_MIN_THREADS 4
+#define FSCACHE_MAX_THREADS 32
+
+/*
+ * fsc-cache.c
+ */
+extern struct list_head fscache_cache_list;
+extern struct rw_semaphore fscache_addremove_sem;
+
+extern struct fscache_cache *fscache_select_cache_for_object(
+ struct fscache_cookie *);
+
+/*
+ * fsc-cookie.c
+ */
+extern struct kmem_cache *fscache_cookie_jar;
+
+extern void fscache_cookie_init_once(void *);
+extern void __fscache_cookie_put(struct fscache_cookie *);
+
+/*
+ * fsc-fsdef.c
+ */
+extern struct fscache_cookie fscache_fsdef_index;
+extern struct fscache_cookie_def fscache_fsdef_netfs_def;
+
+/*
+ * fsc-histogram.c
+ */
+#ifdef CONFIG_FSCACHE_HISTOGRAM
+extern atomic_t fscache_obj_instantiate_histogram[HZ];
+extern atomic_t fscache_objs_histogram[HZ];
+extern atomic_t fscache_ops_histogram[HZ];
+extern atomic_t fscache_retrieval_delay_histogram[HZ];
+extern atomic_t fscache_retrieval_histogram[HZ];
+
+static inline void fscache_hist(atomic_t histogram[], unsigned long start_jif)
+{
+ unsigned long jif = jiffies - start_jif;
+ if (jif >= HZ)
+ jif = HZ - 1;
+ atomic_inc(&histogram[jif]);
+}
+
+extern const struct file_operations fscache_histogram_fops;
+
+#else
+#define fscache_hist(hist, start_jif) do {} while (0)
+#endif
+
+/*
+ * fsc-main.c
+ */
+extern unsigned fscache_defer_lookup;
+extern unsigned fscache_defer_create;
+extern unsigned fscache_debug;
+extern struct kobject *fscache_root;
+
+extern int fscache_wait_bit(void *);
+extern int fscache_wait_bit_interruptible(void *);
+
+/*
+ * fsc-object.c
+ */
+extern void fscache_withdrawing_object(struct fscache_cache *,
+ struct fscache_object *);
+extern void fscache_enqueue_object(struct fscache_object *);
+
+/*
+ * fsc-operation.c
+ */
+extern int fscache_submit_exclusive_op(struct fscache_object *,
+ struct fscache_operation *);
+extern int fscache_submit_op(struct fscache_object *,
+ struct fscache_operation *);
+extern void fscache_abort_object(struct fscache_object *);
+extern void fscache_start_operations(struct fscache_object *);
+extern void fscache_operation_gc(struct work_struct *);
+
+/*
+ * fsc-proc.c
+ */
+#ifdef CONFIG_PROC_FS
+extern int __init fscache_proc_init(void);
+extern void fscache_proc_cleanup(void);
+#else
+#define fscache_proc_init() (0)
+#define fscache_proc_cleanup() do {} while (0)
+#endif
+
+/*
+ * fsc-stats.c
+ */
+#ifdef CONFIG_FSCACHE_STATS
+extern atomic_t fscache_n_ops_processed[FSCACHE_MAX_THREADS];
+extern atomic_t fscache_n_objs_processed[FSCACHE_MAX_THREADS];
+
+extern atomic_t fscache_n_op_pend;
+extern atomic_t fscache_n_op_run;
+extern atomic_t fscache_n_op_enqueue;
+extern atomic_t fscache_n_op_deferred_release;
+extern atomic_t fscache_n_op_release;
+extern atomic_t fscache_n_op_gc;
+
+extern atomic_t fscache_n_attr_changed;
+extern atomic_t fscache_n_attr_changed_ok;
+extern atomic_t fscache_n_attr_changed_nobufs;
+extern atomic_t fscache_n_attr_changed_nomem;
+extern atomic_t fscache_n_attr_changed_calls;
+
+extern atomic_t fscache_n_allocs;
+extern atomic_t fscache_n_allocs_ok;
+extern atomic_t fscache_n_allocs_wait;
+extern atomic_t fscache_n_allocs_nobufs;
+extern atomic_t fscache_n_alloc_ops;
+extern atomic_t fscache_n_alloc_op_waits;
+
+extern atomic_t fscache_n_retrievals;
+extern atomic_t fscache_n_retrievals_ok;
+extern atomic_t fscache_n_retrievals_wait;
+extern atomic_t fscache_n_retrievals_nodata;
+extern atomic_t fscache_n_retrievals_nobufs;
+extern atomic_t fscache_n_retrievals_intr;
+extern atomic_t fscache_n_retrievals_nomem;
+extern atomic_t fscache_n_retrieval_ops;
+extern atomic_t fscache_n_retrieval_op_waits;
+
+extern atomic_t fscache_n_stores;
+extern atomic_t fscache_n_stores_ok;
+extern atomic_t fscache_n_stores_again;
+extern atomic_t fscache_n_stores_nobufs;
+extern atomic_t fscache_n_stores_oom;
+extern atomic_t fscache_n_store_ops;
+extern atomic_t fscache_n_store_calls;
+
+extern atomic_t fscache_n_marks;
+extern atomic_t fscache_n_uncaches;
+
+extern atomic_t fscache_n_acquires;
+extern atomic_t fscache_n_acquires_null;
+extern atomic_t fscache_n_acquires_no_cache;
+extern atomic_t fscache_n_acquires_ok;
+extern atomic_t fscache_n_acquires_nobufs;
+extern atomic_t fscache_n_acquires_oom;
+
+extern atomic_t fscache_n_updates;
+extern atomic_t fscache_n_updates_null;
+extern atomic_t fscache_n_updates_run;
+
+extern atomic_t fscache_n_relinquishes;
+extern atomic_t fscache_n_relinquishes_null;
+extern atomic_t fscache_n_relinquishes_waitcrt;
+
+extern atomic_t fscache_n_cookie_index;
+extern atomic_t fscache_n_cookie_data;
+extern atomic_t fscache_n_cookie_special;
+
+extern atomic_t fscache_n_object_alloc;
+extern atomic_t fscache_n_object_no_alloc;
+extern atomic_t fscache_n_object_lookups;
+extern atomic_t fscache_n_object_lookups_negative;
+extern atomic_t fscache_n_object_lookups_positive;
+extern atomic_t fscache_n_object_created;
+extern atomic_t fscache_n_object_avail;
+extern atomic_t fscache_n_object_dead;
+
+extern atomic_t fscache_n_checkaux_none;
+extern atomic_t fscache_n_checkaux_okay;
+extern atomic_t fscache_n_checkaux_update;
+extern atomic_t fscache_n_checkaux_obsolete;
+
+static inline void fscache_stat(atomic_t *stat)
+{
+ atomic_inc(stat);
+}
+
+extern const struct file_operations fscache_stats_fops;
+#else
+
+#define fscache_stat(stat) do {} while (0)
+#endif
+
+/*
+ * raise an event on an object
+ * - if the event is not masked for that object, then the object is
+ * queued for attention by the thread pool.
+ */
+static inline void fscache_raise_event(struct fscache_object *object,
+ unsigned event)
+{
+ if (!test_and_set_bit(event, &object->events) &&
+ test_bit(event, &object->event_mask))
+ fscache_enqueue_object(object);
+}
+
+/*
+ * drop a reference to a cookie
+ */
+static inline void fscache_cookie_put(struct fscache_cookie *cookie)
+{
+ BUG_ON(atomic_read(&cookie->usage) <= 0);
+ if (atomic_dec_and_test(&cookie->usage))
+ __fscache_cookie_put(cookie);
+}
+
+/*
+ * get an extra reference to a netfs retrieval context
+ */
+static inline
+void *fscache_get_context(struct fscache_cookie *cookie, void *context)
+{
+ if (cookie->def->get_context)
+ cookie->def->get_context(cookie->netfs_data, context);
+ return context;
+}
+
+/*
+ * release a reference to a netfs retrieval context
+ */
+static inline
+void fscache_put_context(struct fscache_cookie *cookie, void *context)
+{
+ if (cookie->def->put_context)
+ cookie->def->put_context(cookie->netfs_data, context);
+}
+
+/*****************************************************************************/
+/*
+ * debug tracing
+ */
+#define dbgprintk(FMT, ...) \
+ printk(KERN_DEBUG "[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
+
+/* make sure we maintain the format strings, even when debugging is disabled */
+static inline __attribute__((format(printf, 1, 2)))
+void _dbprintk(const char *fmt, ...)
+{
+}
+
+#define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
+#define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
+#define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
+
+#define kjournal(FMT, ...) _dbprintk(FMT, ##__VA_ARGS__)
+
+#ifdef __KDEBUG
+#define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
+#define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
+#define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
+
+#elif defined(CONFIG_FSCACHE_DEBUG)
+#define _enter(FMT, ...) \
+do { \
+ if (__do_kdebug(ENTER)) \
+ kenter(FMT, ##__VA_ARGS__); \
+} while (0)
+
+#define _leave(FMT, ...) \
+do { \
+ if (__do_kdebug(LEAVE)) \
+ kleave(FMT, ##__VA_ARGS__); \
+} while (0)
+
+#define _debug(FMT, ...) \
+do { \
+ if (__do_kdebug(DEBUG)) \
+ kdebug(FMT, ##__VA_ARGS__); \
+} while (0)
+
+#else
+#define _enter(FMT, ...) _dbprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
+#define _leave(FMT, ...) _dbprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
+#define _debug(FMT, ...) _dbprintk(FMT, ##__VA_ARGS__)
+#endif
+
+/*
+ * determine whether a particular optional debugging point should be logged
+ * - we need to go through three steps to persuade cpp to correctly join the
+ * shorthand in FSCACHE_DEBUG_LEVEL with its prefix
+ */
+#define ____do_kdebug(LEVEL, POINT) \
+ unlikely((fscache_debug & \
+ (FSCACHE_POINT_##POINT << (FSCACHE_DEBUG_ ## LEVEL * 3))))
+#define ___do_kdebug(LEVEL, POINT) \
+ ____do_kdebug(LEVEL, POINT)
+#define __do_kdebug(POINT) \
+ ___do_kdebug(FSCACHE_DEBUG_LEVEL, POINT)
+
+#define FSCACHE_DEBUG_CACHE 0
+#define FSCACHE_DEBUG_COOKIE 1
+#define FSCACHE_DEBUG_PAGE 2
+#define FSCACHE_DEBUG_OPERATION 3
+
+#define FSCACHE_POINT_ENTER 1
+#define FSCACHE_POINT_LEAVE 2
+#define FSCACHE_POINT_DEBUG 4
+
+#ifndef FSCACHE_DEBUG_LEVEL
+#define FSCACHE_DEBUG_LEVEL CACHE
+#endif
+
+/*
+ * assertions
+ */
+#if 1 /* defined(__KDEBUGALL) */
+
+#define ASSERT(X) \
+do { \
+ if (unlikely(!(X))) { \
+ printk(KERN_ERR "\n"); \
+ printk(KERN_ERR "FS-Cache: Assertion failed\n"); \
+ BUG(); \
+ } \
+} while (0)
+
+#define ASSERTCMP(X, OP, Y) \
+do { \
+ if (unlikely(!((X) OP (Y)))) { \
+ printk(KERN_ERR "\n"); \
+ printk(KERN_ERR "FS-Cache: Assertion failed\n"); \
+ printk(KERN_ERR "%lx " #OP " %lx is false\n", \
+ (unsigned long)(X), (unsigned long)(Y)); \
+ BUG(); \
+ } \
+} while (0)
+
+#define ASSERTIF(C, X) \
+do { \
+ if (unlikely((C) && !(X))) { \
+ printk(KERN_ERR "\n"); \
+ printk(KERN_ERR "FS-Cache: Assertion failed\n"); \
+ BUG(); \
+ } \
+} while (0)
+
+#define ASSERTIFCMP(C, X, OP, Y) \
+do { \
+ if (unlikely((C) && !((X) OP (Y)))) { \
+ printk(KERN_ERR "\n"); \
+ printk(KERN_ERR "FS-Cache: Assertion failed\n"); \
+ printk(KERN_ERR "%lx " #OP " %lx is false\n", \
+ (unsigned long)(X), (unsigned long)(Y)); \
+ BUG(); \
+ } \
+} while (0)
+
+#else
+
+#define ASSERT(X) do {} while (0)
+#define ASSERTCMP(X, OP, Y) do {} while (0)
+#define ASSERTIF(C, X) do {} while (0)
+#define ASSERTIFCMP(C, X, OP, Y) do {} while (0)
+
+#endif /* assert or not */
diff --git a/fs/fscache/main.c b/fs/fscache/main.c
new file mode 100644
index 00000000000..4de41b59749
--- /dev/null
+++ b/fs/fscache/main.c
@@ -0,0 +1,124 @@
+/* General filesystem local caching manager
+ *
+ * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL CACHE
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include "internal.h"
+
+MODULE_DESCRIPTION("FS Cache Manager");
+MODULE_AUTHOR("Red Hat, Inc.");
+MODULE_LICENSE("GPL");
+
+unsigned fscache_defer_lookup = 1;
+module_param_named(defer_lookup, fscache_defer_lookup, uint,
+ S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(fscache_defer_lookup,
+ "Defer cookie lookup to background thread");
+
+unsigned fscache_defer_create = 1;
+module_param_named(defer_create, fscache_defer_create, uint,
+ S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(fscache_defer_create,
+ "Defer cookie creation to background thread");
+
+unsigned fscache_debug;
+module_param_named(debug, fscache_debug, uint,
+ S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(fscache_debug,
+ "FS-Cache debugging mask");
+
+struct kobject *fscache_root;
+
+/*
+ * initialise the fs caching module
+ */
+static int __init fscache_init(void)
+{
+ int ret;
+
+ ret = slow_work_register_user();
+ if (ret < 0)
+ goto error_slow_work;
+
+ ret = fscache_proc_init();
+ if (ret < 0)
+ goto error_proc;
+
+ fscache_cookie_jar = kmem_cache_create("fscache_cookie_jar",
+ sizeof(struct fscache_cookie),
+ 0,
+ 0,
+ fscache_cookie_init_once);
+ if (!fscache_cookie_jar) {
+ printk(KERN_NOTICE
+ "FS-Cache: Failed to allocate a cookie jar\n");
+ ret = -ENOMEM;
+ goto error_cookie_jar;
+ }
+
+ fscache_root = kobject_create_and_add("fscache", kernel_kobj);
+ if (!fscache_root)
+ goto error_kobj;
+
+ printk(KERN_NOTICE "FS-Cache: Loaded\n");
+ return 0;
+
+error_kobj:
+ kmem_cache_destroy(fscache_cookie_jar);
+error_cookie_jar:
+ fscache_proc_cleanup();
+error_proc:
+ slow_work_unregister_user();
+error_slow_work:
+ return ret;
+}
+
+fs_initcall(fscache_init);
+
+/*
+ * clean up on module removal
+ */
+static void __exit fscache_exit(void)
+{
+ _enter("");
+
+ kobject_put(fscache_root);
+ kmem_cache_destroy(fscache_cookie_jar);
+ fscache_proc_cleanup();
+ slow_work_unregister_user();
+ printk(KERN_NOTICE "FS-Cache: Unloaded\n");
+}
+
+module_exit(fscache_exit);
+
+/*
+ * wait_on_bit() sleep function for uninterruptible waiting
+ */
+int fscache_wait_bit(void *flags)
+{
+ schedule();
+ return 0;
+}
+EXPORT_SYMBOL(fscache_wait_bit);
+
+/*
+ * wait_on_bit() sleep function for interruptible waiting
+ */
+int fscache_wait_bit_interruptible(void *flags)
+{
+ schedule();
+ return signal_pending(current);
+}
+EXPORT_SYMBOL(fscache_wait_bit_interruptible);
diff --git a/fs/fscache/netfs.c b/fs/fscache/netfs.c
new file mode 100644
index 00000000000..e028b8eb1c4
--- /dev/null
+++ b/fs/fscache/netfs.c
@@ -0,0 +1,103 @@
+/* FS-Cache netfs (client) registration
+ *
+ * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL COOKIE
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "internal.h"
+
+static LIST_HEAD(fscache_netfs_list);
+
+/*
+ * register a network filesystem for caching
+ */
+int __fscache_register_netfs(struct fscache_netfs *netfs)
+{
+ struct fscache_netfs *ptr;
+ int ret;
+
+ _enter("{%s}", netfs->name);
+
+ INIT_LIST_HEAD(&netfs->link);
+
+ /* allocate a cookie for the primary index */
+ netfs->primary_index =
+ kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL);
+
+ if (!netfs->primary_index) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+ }
+
+ /* initialise the primary index cookie */
+ atomic_set(&netfs->primary_index->usage, 1);
+ atomic_set(&netfs->primary_index->n_children, 0);
+
+ netfs->primary_index->def = &fscache_fsdef_netfs_def;
+ netfs->primary_index->parent = &fscache_fsdef_index;
+ netfs->primary_index->netfs_data = netfs;
+
+ atomic_inc(&netfs->primary_index->parent->usage);
+ atomic_inc(&netfs->primary_index->parent->n_children);
+
+ spin_lock_init(&netfs->primary_index->lock);
+ INIT_HLIST_HEAD(&netfs->primary_index->backing_objects);
+
+ /* check the netfs type is not already present */
+ down_write(&fscache_addremove_sem);
+
+ ret = -EEXIST;
+ list_for_each_entry(ptr, &fscache_netfs_list, link) {
+ if (strcmp(ptr->name, netfs->name) == 0)
+ goto already_registered;
+ }
+
+ list_add(&netfs->link, &fscache_netfs_list);
+ ret = 0;
+
+ printk(KERN_NOTICE "FS-Cache: Netfs '%s' registered for caching\n",
+ netfs->name);
+
+already_registered:
+ up_write(&fscache_addremove_sem);
+
+ if (ret < 0) {
+ netfs->primary_index->parent = NULL;
+ __fscache_cookie_put(netfs->primary_index);
+ netfs->primary_index = NULL;
+ }
+
+ _leave(" = %d", ret);
+ return ret;
+}
+EXPORT_SYMBOL(__fscache_register_netfs);
+
+/*
+ * unregister a network filesystem from the cache
+ * - all cookies must have been released first
+ */
+void __fscache_unregister_netfs(struct fscache_netfs *netfs)
+{
+ _enter("{%s.%u}", netfs->name, netfs->version);
+
+ down_write(&fscache_addremove_sem);
+
+ list_del(&netfs->link);
+ fscache_relinquish_cookie(netfs->primary_index, 0);
+
+ up_write(&fscache_addremove_sem);
+
+ printk(KERN_NOTICE "FS-Cache: Netfs '%s' unregistered from caching\n",
+ netfs->name);
+
+ _leave("");
+}
+EXPORT_SYMBOL(__fscache_unregister_netfs);
diff --git a/fs/fscache/object.c b/fs/fscache/object.c
new file mode 100644
index 00000000000..392a41b1b79
--- /dev/null
+++ b/fs/fscache/object.c
@@ -0,0 +1,810 @@
+/* FS-Cache object state machine handler
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * See Documentation/filesystems/caching/object.txt for a description of the
+ * object state machine and the in-kernel representations.
+ */
+
+#define FSCACHE_DEBUG_LEVEL COOKIE
+#include <linux/module.h>
+#include "internal.h"
+
+const char *fscache_object_states[] = {
+ [FSCACHE_OBJECT_INIT] = "OBJECT_INIT",
+ [FSCACHE_OBJECT_LOOKING_UP] = "OBJECT_LOOKING_UP",
+ [FSCACHE_OBJECT_CREATING] = "OBJECT_CREATING",
+ [FSCACHE_OBJECT_AVAILABLE] = "OBJECT_AVAILABLE",
+ [FSCACHE_OBJECT_ACTIVE] = "OBJECT_ACTIVE",
+ [FSCACHE_OBJECT_UPDATING] = "OBJECT_UPDATING",
+ [FSCACHE_OBJECT_DYING] = "OBJECT_DYING",
+ [FSCACHE_OBJECT_LC_DYING] = "OBJECT_LC_DYING",
+ [FSCACHE_OBJECT_ABORT_INIT] = "OBJECT_ABORT_INIT",
+ [FSCACHE_OBJECT_RELEASING] = "OBJECT_RELEASING",
+ [FSCACHE_OBJECT_RECYCLING] = "OBJECT_RECYCLING",
+ [FSCACHE_OBJECT_WITHDRAWING] = "OBJECT_WITHDRAWING",
+ [FSCACHE_OBJECT_DEAD] = "OBJECT_DEAD",
+};
+EXPORT_SYMBOL(fscache_object_states);
+
+static void fscache_object_slow_work_put_ref(struct slow_work *);
+static int fscache_object_slow_work_get_ref(struct slow_work *);
+static void fscache_object_slow_work_execute(struct slow_work *);
+static void fscache_initialise_object(struct fscache_object *);
+static void fscache_lookup_object(struct fscache_object *);
+static void fscache_object_available(struct fscache_object *);
+static void fscache_release_object(struct fscache_object *);
+static void fscache_withdraw_object(struct fscache_object *);
+static void fscache_enqueue_dependents(struct fscache_object *);
+static void fscache_dequeue_object(struct fscache_object *);
+
+const struct slow_work_ops fscache_object_slow_work_ops = {
+ .get_ref = fscache_object_slow_work_get_ref,
+ .put_ref = fscache_object_slow_work_put_ref,
+ .execute = fscache_object_slow_work_execute,
+};
+EXPORT_SYMBOL(fscache_object_slow_work_ops);
+
+/*
+ * we need to notify the parent when an op completes that we had outstanding
+ * upon it
+ */
+static inline void fscache_done_parent_op(struct fscache_object *object)
+{
+ struct fscache_object *parent = object->parent;
+
+ _enter("OBJ%x {OBJ%x,%x}",
+ object->debug_id, parent->debug_id, parent->n_ops);
+
+ spin_lock_nested(&parent->lock, 1);
+ parent->n_ops--;
+ parent->n_obj_ops--;
+ if (parent->n_ops == 0)
+ fscache_raise_event(parent, FSCACHE_OBJECT_EV_CLEARED);
+ spin_unlock(&parent->lock);
+}
+
+/*
+ * process events that have been sent to an object's state machine
+ * - initiates parent lookup
+ * - does object lookup
+ * - does object creation
+ * - does object recycling and retirement
+ * - does object withdrawal
+ */
+static void fscache_object_state_machine(struct fscache_object *object)
+{
+ enum fscache_object_state new_state;
+
+ ASSERT(object != NULL);
+
+ _enter("{OBJ%x,%s,%lx}",
+ object->debug_id, fscache_object_states[object->state],
+ object->events);
+
+ switch (object->state) {
+ /* wait for the parent object to become ready */
+ case FSCACHE_OBJECT_INIT:
+ object->event_mask =
+ ULONG_MAX & ~(1 << FSCACHE_OBJECT_EV_CLEARED);
+ fscache_initialise_object(object);
+ goto done;
+
+ /* look up the object metadata on disk */
+ case FSCACHE_OBJECT_LOOKING_UP:
+ fscache_lookup_object(object);
+ goto lookup_transit;
+
+ /* create the object metadata on disk */
+ case FSCACHE_OBJECT_CREATING:
+ fscache_lookup_object(object);
+ goto lookup_transit;
+
+ /* handle an object becoming available; start pending
+ * operations and queue dependent operations for processing */
+ case FSCACHE_OBJECT_AVAILABLE:
+ fscache_object_available(object);
+ goto active_transit;
+
+ /* normal running state */
+ case FSCACHE_OBJECT_ACTIVE:
+ goto active_transit;
+
+ /* update the object metadata on disk */
+ case FSCACHE_OBJECT_UPDATING:
+ clear_bit(FSCACHE_OBJECT_EV_UPDATE, &object->events);
+ fscache_stat(&fscache_n_updates_run);
+ object->cache->ops->update_object(object);
+ goto active_transit;
+
+ /* handle an object dying during lookup or creation */
+ case FSCACHE_OBJECT_LC_DYING:
+ object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE);
+ object->cache->ops->lookup_complete(object);
+
+ spin_lock(&object->lock);
+ object->state = FSCACHE_OBJECT_DYING;
+ if (test_and_clear_bit(FSCACHE_COOKIE_CREATING,
+ &object->cookie->flags))
+ wake_up_bit(&object->cookie->flags,
+ FSCACHE_COOKIE_CREATING);
+ spin_unlock(&object->lock);
+
+ fscache_done_parent_op(object);
+
+ /* wait for completion of all active operations on this object
+ * and the death of all child objects of this object */
+ case FSCACHE_OBJECT_DYING:
+ dying:
+ clear_bit(FSCACHE_OBJECT_EV_CLEARED, &object->events);
+ spin_lock(&object->lock);
+ _debug("dying OBJ%x {%d,%d}",
+ object->debug_id, object->n_ops, object->n_children);
+ if (object->n_ops == 0 && object->n_children == 0) {
+ object->event_mask &=
+ ~(1 << FSCACHE_OBJECT_EV_CLEARED);
+ object->event_mask |=
+ (1 << FSCACHE_OBJECT_EV_WITHDRAW) |
+ (1 << FSCACHE_OBJECT_EV_RETIRE) |
+ (1 << FSCACHE_OBJECT_EV_RELEASE) |
+ (1 << FSCACHE_OBJECT_EV_ERROR);
+ } else {
+ object->event_mask &=
+ ~((1 << FSCACHE_OBJECT_EV_WITHDRAW) |
+ (1 << FSCACHE_OBJECT_EV_RETIRE) |
+ (1 << FSCACHE_OBJECT_EV_RELEASE) |
+ (1 << FSCACHE_OBJECT_EV_ERROR));
+ object->event_mask |=
+ 1 << FSCACHE_OBJECT_EV_CLEARED;
+ }
+ spin_unlock(&object->lock);
+ fscache_enqueue_dependents(object);
+ goto terminal_transit;
+
+ /* handle an abort during initialisation */
+ case FSCACHE_OBJECT_ABORT_INIT:
+ _debug("handle abort init %lx", object->events);
+ object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE);
+
+ spin_lock(&object->lock);
+ fscache_dequeue_object(object);
+
+ object->state = FSCACHE_OBJECT_DYING;
+ if (test_and_clear_bit(FSCACHE_COOKIE_CREATING,
+ &object->cookie->flags))
+ wake_up_bit(&object->cookie->flags,
+ FSCACHE_COOKIE_CREATING);
+ spin_unlock(&object->lock);
+ goto dying;
+
+ /* handle the netfs releasing an object and possibly marking it
+ * obsolete too */
+ case FSCACHE_OBJECT_RELEASING:
+ case FSCACHE_OBJECT_RECYCLING:
+ object->event_mask &=
+ ~((1 << FSCACHE_OBJECT_EV_WITHDRAW) |
+ (1 << FSCACHE_OBJECT_EV_RETIRE) |
+ (1 << FSCACHE_OBJECT_EV_RELEASE) |
+ (1 << FSCACHE_OBJECT_EV_ERROR));
+ fscache_release_object(object);
+ spin_lock(&object->lock);
+ object->state = FSCACHE_OBJECT_DEAD;
+ spin_unlock(&object->lock);
+ fscache_stat(&fscache_n_object_dead);
+ goto terminal_transit;
+
+ /* handle the parent cache of this object being withdrawn from
+ * active service */
+ case FSCACHE_OBJECT_WITHDRAWING:
+ object->event_mask &=
+ ~((1 << FSCACHE_OBJECT_EV_WITHDRAW) |
+ (1 << FSCACHE_OBJECT_EV_RETIRE) |
+ (1 << FSCACHE_OBJECT_EV_RELEASE) |
+ (1 << FSCACHE_OBJECT_EV_ERROR));
+ fscache_withdraw_object(object);
+ spin_lock(&object->lock);
+ object->state = FSCACHE_OBJECT_DEAD;
+ spin_unlock(&object->lock);
+ fscache_stat(&fscache_n_object_dead);
+ goto terminal_transit;
+
+ /* complain about the object being woken up once it is
+ * deceased */
+ case FSCACHE_OBJECT_DEAD:
+ printk(KERN_ERR "FS-Cache:"
+ " Unexpected event in dead state %lx\n",
+ object->events & object->event_mask);
+ BUG();
+
+ default:
+ printk(KERN_ERR "FS-Cache: Unknown object state %u\n",
+ object->state);
+ BUG();
+ }
+
+ /* determine the transition from a lookup state */
+lookup_transit:
+ switch (fls(object->events & object->event_mask) - 1) {
+ case FSCACHE_OBJECT_EV_WITHDRAW:
+ case FSCACHE_OBJECT_EV_RETIRE:
+ case FSCACHE_OBJECT_EV_RELEASE:
+ case FSCACHE_OBJECT_EV_ERROR:
+ new_state = FSCACHE_OBJECT_LC_DYING;
+ goto change_state;
+ case FSCACHE_OBJECT_EV_REQUEUE:
+ goto done;
+ case -1:
+ goto done; /* sleep until event */
+ default:
+ goto unsupported_event;
+ }
+
+ /* determine the transition from an active state */
+active_transit:
+ switch (fls(object->events & object->event_mask) - 1) {
+ case FSCACHE_OBJECT_EV_WITHDRAW:
+ case FSCACHE_OBJECT_EV_RETIRE:
+ case FSCACHE_OBJECT_EV_RELEASE:
+ case FSCACHE_OBJECT_EV_ERROR:
+ new_state = FSCACHE_OBJECT_DYING;
+ goto change_state;
+ case FSCACHE_OBJECT_EV_UPDATE:
+ new_state = FSCACHE_OBJECT_UPDATING;
+ goto change_state;
+ case -1:
+ new_state = FSCACHE_OBJECT_ACTIVE;
+ goto change_state; /* sleep until event */
+ default:
+ goto unsupported_event;
+ }
+
+ /* determine the transition from a terminal state */
+terminal_transit:
+ switch (fls(object->events & object->event_mask) - 1) {
+ case FSCACHE_OBJECT_EV_WITHDRAW:
+ new_state = FSCACHE_OBJECT_WITHDRAWING;
+ goto change_state;
+ case FSCACHE_OBJECT_EV_RETIRE:
+ new_state = FSCACHE_OBJECT_RECYCLING;
+ goto change_state;
+ case FSCACHE_OBJECT_EV_RELEASE:
+ new_state = FSCACHE_OBJECT_RELEASING;
+ goto change_state;
+ case FSCACHE_OBJECT_EV_ERROR:
+ new_state = FSCACHE_OBJECT_WITHDRAWING;
+ goto change_state;
+ case FSCACHE_OBJECT_EV_CLEARED:
+ new_state = FSCACHE_OBJECT_DYING;
+ goto change_state;
+ case -1:
+ goto done; /* sleep until event */
+ default:
+ goto unsupported_event;
+ }
+
+change_state:
+ spin_lock(&object->lock);
+ object->state = new_state;
+ spin_unlock(&object->lock);
+
+done:
+ _leave(" [->%s]", fscache_object_states[object->state]);
+ return;
+
+unsupported_event:
+ printk(KERN_ERR "FS-Cache:"
+ " Unsupported event %lx [mask %lx] in state %s\n",
+ object->events, object->event_mask,
+ fscache_object_states[object->state]);
+ BUG();
+}
+
+/*
+ * execute an object
+ */
+static void fscache_object_slow_work_execute(struct slow_work *work)
+{
+ struct fscache_object *object =
+ container_of(work, struct fscache_object, work);
+ unsigned long start;
+
+ _enter("{OBJ%x}", object->debug_id);
+
+ clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+
+ start = jiffies;
+ fscache_object_state_machine(object);
+ fscache_hist(fscache_objs_histogram, start);
+ if (object->events & object->event_mask)
+ fscache_enqueue_object(object);
+}
+
+/*
+ * initialise an object
+ * - check the specified object's parent to see if we can make use of it
+ * immediately to do a creation
+ * - we may need to start the process of creating a parent and we need to wait
+ * for the parent's lookup and creation to complete if it's not there yet
+ * - an object's cookie is pinned until we clear FSCACHE_COOKIE_CREATING on the
+ * leaf-most cookies of the object and all its children
+ */
+static void fscache_initialise_object(struct fscache_object *object)
+{
+ struct fscache_object *parent;
+
+ _enter("");
+ ASSERT(object->cookie != NULL);
+ ASSERT(object->cookie->parent != NULL);
+ ASSERT(list_empty(&object->work.link));
+
+ if (object->events & ((1 << FSCACHE_OBJECT_EV_ERROR) |
+ (1 << FSCACHE_OBJECT_EV_RELEASE) |
+ (1 << FSCACHE_OBJECT_EV_RETIRE) |
+ (1 << FSCACHE_OBJECT_EV_WITHDRAW))) {
+ _debug("abort init %lx", object->events);
+ spin_lock(&object->lock);
+ object->state = FSCACHE_OBJECT_ABORT_INIT;
+ spin_unlock(&object->lock);
+ return;
+ }
+
+ spin_lock(&object->cookie->lock);
+ spin_lock_nested(&object->cookie->parent->lock, 1);
+
+ parent = object->parent;
+ if (!parent) {
+ _debug("no parent");
+ set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events);
+ } else {
+ spin_lock(&object->lock);
+ spin_lock_nested(&parent->lock, 1);
+ _debug("parent %s", fscache_object_states[parent->state]);
+
+ if (parent->state >= FSCACHE_OBJECT_DYING) {
+ _debug("bad parent");
+ set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events);
+ } else if (parent->state < FSCACHE_OBJECT_AVAILABLE) {
+ _debug("wait");
+
+ /* we may get woken up in this state by child objects
+ * binding on to us, so we need to make sure we don't
+ * add ourself to the list multiple times */
+ if (list_empty(&object->dep_link)) {
+ object->cache->ops->grab_object(object);
+ list_add(&object->dep_link,
+ &parent->dependents);
+
+ /* fscache_acquire_non_index_cookie() uses this
+ * to wake the chain up */
+ if (parent->state == FSCACHE_OBJECT_INIT)
+ fscache_enqueue_object(parent);
+ }
+ } else {
+ _debug("go");
+ parent->n_ops++;
+ parent->n_obj_ops++;
+ object->lookup_jif = jiffies;
+ object->state = FSCACHE_OBJECT_LOOKING_UP;
+ set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+ }
+
+ spin_unlock(&parent->lock);
+ spin_unlock(&object->lock);
+ }
+
+ spin_unlock(&object->cookie->parent->lock);
+ spin_unlock(&object->cookie->lock);
+ _leave("");
+}
+
+/*
+ * look an object up in the cache from which it was allocated
+ * - we hold an "access lock" on the parent object, so the parent object cannot
+ * be withdrawn by either party till we've finished
+ * - an object's cookie is pinned until we clear FSCACHE_COOKIE_CREATING on the
+ * leaf-most cookies of the object and all its children
+ */
+static void fscache_lookup_object(struct fscache_object *object)
+{
+ struct fscache_cookie *cookie = object->cookie;
+ struct fscache_object *parent;
+
+ _enter("");
+
+ parent = object->parent;
+ ASSERT(parent != NULL);
+ ASSERTCMP(parent->n_ops, >, 0);
+ ASSERTCMP(parent->n_obj_ops, >, 0);
+
+ /* make sure the parent is still available */
+ ASSERTCMP(parent->state, >=, FSCACHE_OBJECT_AVAILABLE);
+
+ if (parent->state >= FSCACHE_OBJECT_DYING ||
+ test_bit(FSCACHE_IOERROR, &object->cache->flags)) {
+ _debug("unavailable");
+ set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events);
+ _leave("");
+ return;
+ }
+
+ _debug("LOOKUP \"%s/%s\" in \"%s\"",
+ parent->cookie->def->name, cookie->def->name,
+ object->cache->tag->name);
+
+ fscache_stat(&fscache_n_object_lookups);
+ object->cache->ops->lookup_object(object);
+
+ if (test_bit(FSCACHE_OBJECT_EV_ERROR, &object->events))
+ set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
+
+ _leave("");
+}
+
+/**
+ * fscache_object_lookup_negative - Note negative cookie lookup
+ * @object: Object pointing to cookie to mark
+ *
+ * Note negative lookup, permitting those waiting to read data from an already
+ * existing backing object to continue as there's no data for them to read.
+ */
+void fscache_object_lookup_negative(struct fscache_object *object)
+{
+ struct fscache_cookie *cookie = object->cookie;
+
+ _enter("{OBJ%x,%s}",
+ object->debug_id, fscache_object_states[object->state]);
+
+ spin_lock(&object->lock);
+ if (object->state == FSCACHE_OBJECT_LOOKING_UP) {
+ fscache_stat(&fscache_n_object_lookups_negative);
+
+ /* transit here to allow write requests to begin stacking up
+ * and read requests to begin returning ENODATA */
+ object->state = FSCACHE_OBJECT_CREATING;
+ spin_unlock(&object->lock);
+
+ set_bit(FSCACHE_COOKIE_PENDING_FILL, &cookie->flags);
+ set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
+
+ _debug("wake up lookup %p", &cookie->flags);
+ smp_mb__before_clear_bit();
+ clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
+ smp_mb__after_clear_bit();
+ wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP);
+ set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+ } else {
+ ASSERTCMP(object->state, ==, FSCACHE_OBJECT_CREATING);
+ spin_unlock(&object->lock);
+ }
+
+ _leave("");
+}
+EXPORT_SYMBOL(fscache_object_lookup_negative);
+
+/**
+ * fscache_obtained_object - Note successful object lookup or creation
+ * @object: Object pointing to cookie to mark
+ *
+ * Note successful lookup and/or creation, permitting those waiting to write
+ * data to a backing object to continue.
+ *
+ * Note that after calling this, an object's cookie may be relinquished by the
+ * netfs, and so must be accessed with object lock held.
+ */
+void fscache_obtained_object(struct fscache_object *object)
+{
+ struct fscache_cookie *cookie = object->cookie;
+
+ _enter("{OBJ%x,%s}",
+ object->debug_id, fscache_object_states[object->state]);
+
+ /* if we were still looking up, then we must have a positive lookup
+ * result, in which case there may be data available */
+ spin_lock(&object->lock);
+ if (object->state == FSCACHE_OBJECT_LOOKING_UP) {
+ fscache_stat(&fscache_n_object_lookups_positive);
+
+ clear_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
+
+ object->state = FSCACHE_OBJECT_AVAILABLE;
+ spin_unlock(&object->lock);
+
+ smp_mb__before_clear_bit();
+ clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
+ smp_mb__after_clear_bit();
+ wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP);
+ set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+ } else {
+ ASSERTCMP(object->state, ==, FSCACHE_OBJECT_CREATING);
+ fscache_stat(&fscache_n_object_created);
+
+ object->state = FSCACHE_OBJECT_AVAILABLE;
+ spin_unlock(&object->lock);
+ set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+ smp_wmb();
+ }
+
+ if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &cookie->flags))
+ wake_up_bit(&cookie->flags, FSCACHE_COOKIE_CREATING);
+
+ _leave("");
+}
+EXPORT_SYMBOL(fscache_obtained_object);
+
+/*
+ * handle an object that has just become available
+ */
+static void fscache_object_available(struct fscache_object *object)
+{
+ _enter("{OBJ%x}", object->debug_id);
+
+ spin_lock(&object->lock);
+
+ if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags))
+ wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING);
+
+ fscache_done_parent_op(object);
+ if (object->n_in_progress == 0) {
+ if (object->n_ops > 0) {
+ ASSERTCMP(object->n_ops, >=, object->n_obj_ops);
+ ASSERTIF(object->n_ops > object->n_obj_ops,
+ !list_empty(&object->pending_ops));
+ fscache_start_operations(object);
+ } else {
+ ASSERT(list_empty(&object->pending_ops));
+ }
+ }
+ spin_unlock(&object->lock);
+
+ object->cache->ops->lookup_complete(object);
+ fscache_enqueue_dependents(object);
+
+ fscache_hist(fscache_obj_instantiate_histogram, object->lookup_jif);
+ fscache_stat(&fscache_n_object_avail);
+
+ _leave("");
+}
+
+/*
+ * drop an object's attachments
+ */
+static void fscache_drop_object(struct fscache_object *object)
+{
+ struct fscache_object *parent = object->parent;
+ struct fscache_cache *cache = object->cache;
+
+ _enter("{OBJ%x,%d}", object->debug_id, object->n_children);
+
+ spin_lock(&cache->object_list_lock);
+ list_del_init(&object->cache_link);
+ spin_unlock(&cache->object_list_lock);
+
+ cache->ops->drop_object(object);
+
+ if (parent) {
+ _debug("release parent OBJ%x {%d}",
+ parent->debug_id, parent->n_children);
+
+ spin_lock(&parent->lock);
+ parent->n_children--;
+ if (parent->n_children == 0)
+ fscache_raise_event(parent, FSCACHE_OBJECT_EV_CLEARED);
+ spin_unlock(&parent->lock);
+ object->parent = NULL;
+ }
+
+ /* this just shifts the object release to the slow work processor */
+ object->cache->ops->put_object(object);
+
+ _leave("");
+}
+
+/*
+ * release or recycle an object that the netfs has discarded
+ */
+static void fscache_release_object(struct fscache_object *object)
+{
+ _enter("");
+
+ fscache_drop_object(object);
+}
+
+/*
+ * withdraw an object from active service
+ */
+static void fscache_withdraw_object(struct fscache_object *object)
+{
+ struct fscache_cookie *cookie;
+ bool detached;
+
+ _enter("");
+
+ spin_lock(&object->lock);
+ cookie = object->cookie;
+ if (cookie) {
+ /* need to get the cookie lock before the object lock, starting
+ * from the object pointer */
+ atomic_inc(&cookie->usage);
+ spin_unlock(&object->lock);
+
+ detached = false;
+ spin_lock(&cookie->lock);
+ spin_lock(&object->lock);
+
+ if (object->cookie == cookie) {
+ hlist_del_init(&object->cookie_link);
+ object->cookie = NULL;
+ detached = true;
+ }
+ spin_unlock(&cookie->lock);
+ fscache_cookie_put(cookie);
+ if (detached)
+ fscache_cookie_put(cookie);
+ }
+
+ spin_unlock(&object->lock);
+
+ fscache_drop_object(object);
+}
+
+/*
+ * withdraw an object from active service at the behest of the cache
+ * - need break the links to a cached object cookie
+ * - called under two situations:
+ * (1) recycler decides to reclaim an in-use object
+ * (2) a cache is unmounted
+ * - have to take care as the cookie can be being relinquished by the netfs
+ * simultaneously
+ * - the object is pinned by the caller holding a refcount on it
+ */
+void fscache_withdrawing_object(struct fscache_cache *cache,
+ struct fscache_object *object)
+{
+ bool enqueue = false;
+
+ _enter(",OBJ%x", object->debug_id);
+
+ spin_lock(&object->lock);
+ if (object->state < FSCACHE_OBJECT_WITHDRAWING) {
+ object->state = FSCACHE_OBJECT_WITHDRAWING;
+ enqueue = true;
+ }
+ spin_unlock(&object->lock);
+
+ if (enqueue)
+ fscache_enqueue_object(object);
+
+ _leave("");
+}
+
+/*
+ * allow the slow work item processor to get a ref on an object
+ */
+static int fscache_object_slow_work_get_ref(struct slow_work *work)
+{
+ struct fscache_object *object =
+ container_of(work, struct fscache_object, work);
+
+ return object->cache->ops->grab_object(object) ? 0 : -EAGAIN;
+}
+
+/*
+ * allow the slow work item processor to discard a ref on a work item
+ */
+static void fscache_object_slow_work_put_ref(struct slow_work *work)
+{
+ struct fscache_object *object =
+ container_of(work, struct fscache_object, work);
+
+ return object->cache->ops->put_object(object);
+}
+
+/*
+ * enqueue an object for metadata-type processing
+ */
+void fscache_enqueue_object(struct fscache_object *object)
+{
+ _enter("{OBJ%x}", object->debug_id);
+
+ slow_work_enqueue(&object->work);
+}
+
+/*
+ * enqueue the dependents of an object for metadata-type processing
+ * - the caller must hold the object's lock
+ * - this may cause an already locked object to wind up being processed again
+ */
+static void fscache_enqueue_dependents(struct fscache_object *object)
+{
+ struct fscache_object *dep;
+
+ _enter("{OBJ%x}", object->debug_id);
+
+ if (list_empty(&object->dependents))
+ return;
+
+ spin_lock(&object->lock);
+
+ while (!list_empty(&object->dependents)) {
+ dep = list_entry(object->dependents.next,
+ struct fscache_object, dep_link);
+ list_del_init(&dep->dep_link);
+
+
+ /* sort onto appropriate lists */
+ fscache_enqueue_object(dep);
+ dep->cache->ops->put_object(dep);
+
+ if (!list_empty(&object->dependents))
+ cond_resched_lock(&object->lock);
+ }
+
+ spin_unlock(&object->lock);
+}
+
+/*
+ * remove an object from whatever queue it's waiting on
+ * - the caller must hold object->lock
+ */
+void fscache_dequeue_object(struct fscache_object *object)
+{
+ _enter("{OBJ%x}", object->debug_id);
+
+ if (!list_empty(&object->dep_link)) {
+ spin_lock(&object->parent->lock);
+ list_del_init(&object->dep_link);
+ spin_unlock(&object->parent->lock);
+ }
+
+ _leave("");
+}
+
+/**
+ * fscache_check_aux - Ask the netfs whether an object on disk is still valid
+ * @object: The object to ask about
+ * @data: The auxiliary data for the object
+ * @datalen: The size of the auxiliary data
+ *
+ * This function consults the netfs about the coherency state of an object
+ */
+enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
+ const void *data, uint16_t datalen)
+{
+ enum fscache_checkaux result;
+
+ if (!object->cookie->def->check_aux) {
+ fscache_stat(&fscache_n_checkaux_none);
+ return FSCACHE_CHECKAUX_OKAY;
+ }
+
+ result = object->cookie->def->check_aux(object->cookie->netfs_data,
+ data, datalen);
+ switch (result) {
+ /* entry okay as is */
+ case FSCACHE_CHECKAUX_OKAY:
+ fscache_stat(&fscache_n_checkaux_okay);
+ break;
+
+ /* entry requires update */
+ case FSCACHE_CHECKAUX_NEEDS_UPDATE:
+ fscache_stat(&fscache_n_checkaux_update);
+ break;
+
+ /* entry requires deletion */
+ case FSCACHE_CHECKAUX_OBSOLETE:
+ fscache_stat(&fscache_n_checkaux_obsolete);
+ break;
+
+ default:
+ BUG();
+ }
+
+ return result;
+}
+EXPORT_SYMBOL(fscache_check_aux);
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c
new file mode 100644
index 00000000000..e7f8d53b8b6
--- /dev/null
+++ b/fs/fscache/operation.c
@@ -0,0 +1,459 @@
+/* FS-Cache worker operation management routines
+ *
+ * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * See Documentation/filesystems/caching/operations.txt
+ */
+
+#define FSCACHE_DEBUG_LEVEL OPERATION
+#include <linux/module.h>
+#include "internal.h"
+
+atomic_t fscache_op_debug_id;
+EXPORT_SYMBOL(fscache_op_debug_id);
+
+/**
+ * fscache_enqueue_operation - Enqueue an operation for processing
+ * @op: The operation to enqueue
+ *
+ * Enqueue an operation for processing by the FS-Cache thread pool.
+ *
+ * This will get its own ref on the object.
+ */
+void fscache_enqueue_operation(struct fscache_operation *op)
+{
+ _enter("{OBJ%x OP%x,%u}",
+ op->object->debug_id, op->debug_id, atomic_read(&op->usage));
+
+ ASSERT(op->processor != NULL);
+ ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE);
+ ASSERTCMP(atomic_read(&op->usage), >, 0);
+
+ if (list_empty(&op->pend_link)) {
+ switch (op->flags & FSCACHE_OP_TYPE) {
+ case FSCACHE_OP_FAST:
+ _debug("queue fast");
+ atomic_inc(&op->usage);
+ if (!schedule_work(&op->fast_work))
+ fscache_put_operation(op);
+ break;
+ case FSCACHE_OP_SLOW:
+ _debug("queue slow");
+ slow_work_enqueue(&op->slow_work);
+ break;
+ case FSCACHE_OP_MYTHREAD:
+ _debug("queue for caller's attention");
+ break;
+ default:
+ printk(KERN_ERR "FS-Cache: Unexpected op type %lx",
+ op->flags);
+ BUG();
+ break;
+ }
+ fscache_stat(&fscache_n_op_enqueue);
+ }
+}
+EXPORT_SYMBOL(fscache_enqueue_operation);
+
+/*
+ * start an op running
+ */
+static void fscache_run_op(struct fscache_object *object,
+ struct fscache_operation *op)
+{
+ object->n_in_progress++;
+ if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
+ wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
+ if (op->processor)
+ fscache_enqueue_operation(op);
+ fscache_stat(&fscache_n_op_run);
+}
+
+/*
+ * submit an exclusive operation for an object
+ * - other ops are excluded from running simultaneously with this one
+ * - this gets any extra refs it needs on an op
+ */
+int fscache_submit_exclusive_op(struct fscache_object *object,
+ struct fscache_operation *op)
+{
+ int ret;
+
+ _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id);
+
+ spin_lock(&object->lock);
+ ASSERTCMP(object->n_ops, >=, object->n_in_progress);
+ ASSERTCMP(object->n_ops, >=, object->n_exclusive);
+
+ ret = -ENOBUFS;
+ if (fscache_object_is_active(object)) {
+ op->object = object;
+ object->n_ops++;
+ object->n_exclusive++; /* reads and writes must wait */
+
+ if (object->n_ops > 0) {
+ atomic_inc(&op->usage);
+ list_add_tail(&op->pend_link, &object->pending_ops);
+ fscache_stat(&fscache_n_op_pend);
+ } else if (!list_empty(&object->pending_ops)) {
+ atomic_inc(&op->usage);
+ list_add_tail(&op->pend_link, &object->pending_ops);
+ fscache_stat(&fscache_n_op_pend);
+ fscache_start_operations(object);
+ } else {
+ ASSERTCMP(object->n_in_progress, ==, 0);
+ fscache_run_op(object, op);
+ }
+
+ /* need to issue a new write op after this */
+ clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags);
+ ret = 0;
+ } else if (object->state == FSCACHE_OBJECT_CREATING) {
+ op->object = object;
+ object->n_ops++;
+ object->n_exclusive++; /* reads and writes must wait */
+ atomic_inc(&op->usage);
+ list_add_tail(&op->pend_link, &object->pending_ops);
+ fscache_stat(&fscache_n_op_pend);
+ ret = 0;
+ } else {
+ /* not allowed to submit ops in any other state */
+ BUG();
+ }
+
+ spin_unlock(&object->lock);
+ return ret;
+}
+
+/*
+ * report an unexpected submission
+ */
+static void fscache_report_unexpected_submission(struct fscache_object *object,
+ struct fscache_operation *op,
+ unsigned long ostate)
+{
+ static bool once_only;
+ struct fscache_operation *p;
+ unsigned n;
+
+ if (once_only)
+ return;
+ once_only = true;
+
+ kdebug("unexpected submission OP%x [OBJ%x %s]",
+ op->debug_id, object->debug_id,
+ fscache_object_states[object->state]);
+ kdebug("objstate=%s [%s]",
+ fscache_object_states[object->state],
+ fscache_object_states[ostate]);
+ kdebug("objflags=%lx", object->flags);
+ kdebug("objevent=%lx [%lx]", object->events, object->event_mask);
+ kdebug("ops=%u inp=%u exc=%u",
+ object->n_ops, object->n_in_progress, object->n_exclusive);
+
+ if (!list_empty(&object->pending_ops)) {
+ n = 0;
+ list_for_each_entry(p, &object->pending_ops, pend_link) {
+ ASSERTCMP(p->object, ==, object);
+ kdebug("%p %p", op->processor, op->release);
+ n++;
+ }
+
+ kdebug("n=%u", n);
+ }
+
+ dump_stack();
+}
+
+/*
+ * submit an operation for an object
+ * - objects may be submitted only in the following states:
+ * - during object creation (write ops may be submitted)
+ * - whilst the object is active
+ * - after an I/O error incurred in one of the two above states (op rejected)
+ * - this gets any extra refs it needs on an op
+ */
+int fscache_submit_op(struct fscache_object *object,
+ struct fscache_operation *op)
+{
+ unsigned long ostate;
+ int ret;
+
+ _enter("{OBJ%x OP%x},{%u}",
+ object->debug_id, op->debug_id, atomic_read(&op->usage));
+
+ ASSERTCMP(atomic_read(&op->usage), >, 0);
+
+ spin_lock(&object->lock);
+ ASSERTCMP(object->n_ops, >=, object->n_in_progress);
+ ASSERTCMP(object->n_ops, >=, object->n_exclusive);
+
+ ostate = object->state;
+ smp_rmb();
+
+ if (fscache_object_is_active(object)) {
+ op->object = object;
+ object->n_ops++;
+
+ if (object->n_exclusive > 0) {
+ atomic_inc(&op->usage);
+ list_add_tail(&op->pend_link, &object->pending_ops);
+ fscache_stat(&fscache_n_op_pend);
+ } else if (!list_empty(&object->pending_ops)) {
+ atomic_inc(&op->usage);
+ list_add_tail(&op->pend_link, &object->pending_ops);
+ fscache_stat(&fscache_n_op_pend);
+ fscache_start_operations(object);
+ } else {
+ ASSERTCMP(object->n_exclusive, ==, 0);
+ fscache_run_op(object, op);
+ }
+ ret = 0;
+ } else if (object->state == FSCACHE_OBJECT_CREATING) {
+ op->object = object;
+ object->n_ops++;
+ atomic_inc(&op->usage);
+ list_add_tail(&op->pend_link, &object->pending_ops);
+ fscache_stat(&fscache_n_op_pend);
+ ret = 0;
+ } else if (!test_bit(FSCACHE_IOERROR, &object->cache->flags)) {
+ fscache_report_unexpected_submission(object, op, ostate);
+ ASSERT(!fscache_object_is_active(object));
+ ret = -ENOBUFS;
+ } else {
+ ret = -ENOBUFS;
+ }
+
+ spin_unlock(&object->lock);
+ return ret;
+}
+
+/*
+ * queue an object for withdrawal on error, aborting all following asynchronous
+ * operations
+ */
+void fscache_abort_object(struct fscache_object *object)
+{
+ _enter("{OBJ%x}", object->debug_id);
+
+ fscache_raise_event(object, FSCACHE_OBJECT_EV_ERROR);
+}
+
+/*
+ * jump start the operation processing on an object
+ * - caller must hold object->lock
+ */
+void fscache_start_operations(struct fscache_object *object)
+{
+ struct fscache_operation *op;
+ bool stop = false;
+
+ while (!list_empty(&object->pending_ops) && !stop) {
+ op = list_entry(object->pending_ops.next,
+ struct fscache_operation, pend_link);
+
+ if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) {
+ if (object->n_in_progress > 0)
+ break;
+ stop = true;
+ }
+ list_del_init(&op->pend_link);
+ object->n_in_progress++;
+
+ if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
+ wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
+ if (op->processor)
+ fscache_enqueue_operation(op);
+
+ /* the pending queue was holding a ref on the object */
+ fscache_put_operation(op);
+ }
+
+ ASSERTCMP(object->n_in_progress, <=, object->n_ops);
+
+ _debug("woke %d ops on OBJ%x",
+ object->n_in_progress, object->debug_id);
+}
+
+/*
+ * release an operation
+ * - queues pending ops if this is the last in-progress op
+ */
+void fscache_put_operation(struct fscache_operation *op)
+{
+ struct fscache_object *object;
+ struct fscache_cache *cache;
+
+ _enter("{OBJ%x OP%x,%d}",
+ op->object->debug_id, op->debug_id, atomic_read(&op->usage));
+
+ ASSERTCMP(atomic_read(&op->usage), >, 0);
+
+ if (!atomic_dec_and_test(&op->usage))
+ return;
+
+ _debug("PUT OP");
+ if (test_and_set_bit(FSCACHE_OP_DEAD, &op->flags))
+ BUG();
+
+ fscache_stat(&fscache_n_op_release);
+
+ if (op->release) {
+ op->release(op);
+ op->release = NULL;
+ }
+
+ object = op->object;
+
+ /* now... we may get called with the object spinlock held, so we
+ * complete the cleanup here only if we can immediately acquire the
+ * lock, and defer it otherwise */
+ if (!spin_trylock(&object->lock)) {
+ _debug("defer put");
+ fscache_stat(&fscache_n_op_deferred_release);
+
+ cache = object->cache;
+ spin_lock(&cache->op_gc_list_lock);
+ list_add_tail(&op->pend_link, &cache->op_gc_list);
+ spin_unlock(&cache->op_gc_list_lock);
+ schedule_work(&cache->op_gc);
+ _leave(" [defer]");
+ return;
+ }
+
+ if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) {
+ ASSERTCMP(object->n_exclusive, >, 0);
+ object->n_exclusive--;
+ }
+
+ ASSERTCMP(object->n_in_progress, >, 0);
+ object->n_in_progress--;
+ if (object->n_in_progress == 0)
+ fscache_start_operations(object);
+
+ ASSERTCMP(object->n_ops, >, 0);
+ object->n_ops--;
+ if (object->n_ops == 0)
+ fscache_raise_event(object, FSCACHE_OBJECT_EV_CLEARED);
+
+ spin_unlock(&object->lock);
+
+ kfree(op);
+ _leave(" [done]");
+}
+EXPORT_SYMBOL(fscache_put_operation);
+
+/*
+ * garbage collect operations that have had their release deferred
+ */
+void fscache_operation_gc(struct work_struct *work)
+{
+ struct fscache_operation *op;
+ struct fscache_object *object;
+ struct fscache_cache *cache =
+ container_of(work, struct fscache_cache, op_gc);
+ int count = 0;
+
+ _enter("");
+
+ do {
+ spin_lock(&cache->op_gc_list_lock);
+ if (list_empty(&cache->op_gc_list)) {
+ spin_unlock(&cache->op_gc_list_lock);
+ break;
+ }
+
+ op = list_entry(cache->op_gc_list.next,
+ struct fscache_operation, pend_link);
+ list_del(&op->pend_link);
+ spin_unlock(&cache->op_gc_list_lock);
+
+ object = op->object;
+
+ _debug("GC DEFERRED REL OBJ%x OP%x",
+ object->debug_id, op->debug_id);
+ fscache_stat(&fscache_n_op_gc);
+
+ ASSERTCMP(atomic_read(&op->usage), ==, 0);
+
+ spin_lock(&object->lock);
+ if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) {
+ ASSERTCMP(object->n_exclusive, >, 0);
+ object->n_exclusive--;
+ }
+
+ ASSERTCMP(object->n_in_progress, >, 0);
+ object->n_in_progress--;
+ if (object->n_in_progress == 0)
+ fscache_start_operations(object);
+
+ ASSERTCMP(object->n_ops, >, 0);
+ object->n_ops--;
+ if (object->n_ops == 0)
+ fscache_raise_event(object, FSCACHE_OBJECT_EV_CLEARED);
+
+ spin_unlock(&object->lock);
+
+ } while (count++ < 20);
+
+ if (!list_empty(&cache->op_gc_list))
+ schedule_work(&cache->op_gc);
+
+ _leave("");
+}
+
+/*
+ * allow the slow work item processor to get a ref on an operation
+ */
+static int fscache_op_get_ref(struct slow_work *work)
+{
+ struct fscache_operation *op =
+ container_of(work, struct fscache_operation, slow_work);
+
+ atomic_inc(&op->usage);
+ return 0;
+}
+
+/*
+ * allow the slow work item processor to discard a ref on an operation
+ */
+static void fscache_op_put_ref(struct slow_work *work)
+{
+ struct fscache_operation *op =
+ container_of(work, struct fscache_operation, slow_work);
+
+ fscache_put_operation(op);
+}
+
+/*
+ * execute an operation using the slow thread pool to provide processing context
+ * - the caller holds a ref to this object, so we don't need to hold one
+ */
+static void fscache_op_execute(struct slow_work *work)
+{
+ struct fscache_operation *op =
+ container_of(work, struct fscache_operation, slow_work);
+ unsigned long start;
+
+ _enter("{OBJ%x OP%x,%d}",
+ op->object->debug_id, op->debug_id, atomic_read(&op->usage));
+
+ ASSERT(op->processor != NULL);
+ start = jiffies;
+ op->processor(op);
+ fscache_hist(fscache_ops_histogram, start);
+
+ _leave("");
+}
+
+const struct slow_work_ops fscache_op_slow_work_ops = {
+ .get_ref = fscache_op_get_ref,
+ .put_ref = fscache_op_put_ref,
+ .execute = fscache_op_execute,
+};
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
new file mode 100644
index 00000000000..2568e0eb644
--- /dev/null
+++ b/fs/fscache/page.c
@@ -0,0 +1,816 @@
+/* Cache page management and data I/O routines
+ *
+ * Copyright (C) 2004-2008 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL PAGE
+#include <linux/module.h>
+#include <linux/fscache-cache.h>
+#include <linux/buffer_head.h>
+#include <linux/pagevec.h>
+#include "internal.h"
+
+/*
+ * check to see if a page is being written to the cache
+ */
+bool __fscache_check_page_write(struct fscache_cookie *cookie, struct page *page)
+{
+ void *val;
+
+ rcu_read_lock();
+ val = radix_tree_lookup(&cookie->stores, page->index);
+ rcu_read_unlock();
+
+ return val != NULL;
+}
+EXPORT_SYMBOL(__fscache_check_page_write);
+
+/*
+ * wait for a page to finish being written to the cache
+ */
+void __fscache_wait_on_page_write(struct fscache_cookie *cookie, struct page *page)
+{
+ wait_queue_head_t *wq = bit_waitqueue(&cookie->flags, 0);
+
+ wait_event(*wq, !__fscache_check_page_write(cookie, page));
+}
+EXPORT_SYMBOL(__fscache_wait_on_page_write);
+
+/*
+ * note that a page has finished being written to the cache
+ */
+static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *page)
+{
+ struct page *xpage;
+
+ spin_lock(&cookie->lock);
+ xpage = radix_tree_delete(&cookie->stores, page->index);
+ spin_unlock(&cookie->lock);
+ ASSERT(xpage != NULL);
+
+ wake_up_bit(&cookie->flags, 0);
+}
+
+/*
+ * actually apply the changed attributes to a cache object
+ */
+static void fscache_attr_changed_op(struct fscache_operation *op)
+{
+ struct fscache_object *object = op->object;
+
+ _enter("{OBJ%x OP%x}", object->debug_id, op->debug_id);
+
+ fscache_stat(&fscache_n_attr_changed_calls);
+
+ if (fscache_object_is_active(object) &&
+ object->cache->ops->attr_changed(object) < 0)
+ fscache_abort_object(object);
+
+ _leave("");
+}
+
+/*
+ * notification that the attributes on an object have changed
+ */
+int __fscache_attr_changed(struct fscache_cookie *cookie)
+{
+ struct fscache_operation *op;
+ struct fscache_object *object;
+
+ _enter("%p", cookie);
+
+ ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
+
+ fscache_stat(&fscache_n_attr_changed);
+
+ op = kzalloc(sizeof(*op), GFP_KERNEL);
+ if (!op) {
+ fscache_stat(&fscache_n_attr_changed_nomem);
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+ }
+
+ fscache_operation_init(op, NULL);
+ fscache_operation_init_slow(op, fscache_attr_changed_op);
+ op->flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_EXCLUSIVE);
+
+ spin_lock(&cookie->lock);
+
+ if (hlist_empty(&cookie->backing_objects))
+ goto nobufs;
+ object = hlist_entry(cookie->backing_objects.first,
+ struct fscache_object, cookie_link);
+
+ if (fscache_submit_exclusive_op(object, op) < 0)
+ goto nobufs;
+ spin_unlock(&cookie->lock);
+ fscache_stat(&fscache_n_attr_changed_ok);
+ fscache_put_operation(op);
+ _leave(" = 0");
+ return 0;
+
+nobufs:
+ spin_unlock(&cookie->lock);
+ kfree(op);
+ fscache_stat(&fscache_n_attr_changed_nobufs);
+ _leave(" = %d", -ENOBUFS);
+ return -ENOBUFS;
+}
+EXPORT_SYMBOL(__fscache_attr_changed);
+
+/*
+ * handle secondary execution given to a retrieval op on behalf of the
+ * cache
+ */
+static void fscache_retrieval_work(struct work_struct *work)
+{
+ struct fscache_retrieval *op =
+ container_of(work, struct fscache_retrieval, op.fast_work);
+ unsigned long start;
+
+ _enter("{OP%x}", op->op.debug_id);
+
+ start = jiffies;
+ op->op.processor(&op->op);
+ fscache_hist(fscache_ops_histogram, start);
+ fscache_put_operation(&op->op);
+}
+
+/*
+ * release a retrieval op reference
+ */
+static void fscache_release_retrieval_op(struct fscache_operation *_op)
+{
+ struct fscache_retrieval *op =
+ container_of(_op, struct fscache_retrieval, op);
+
+ _enter("{OP%x}", op->op.debug_id);
+
+ fscache_hist(fscache_retrieval_histogram, op->start_time);
+ if (op->context)
+ fscache_put_context(op->op.object->cookie, op->context);
+
+ _leave("");
+}
+
+/*
+ * allocate a retrieval op
+ */
+static struct fscache_retrieval *fscache_alloc_retrieval(
+ struct address_space *mapping,
+ fscache_rw_complete_t end_io_func,
+ void *context)
+{
+ struct fscache_retrieval *op;
+
+ /* allocate a retrieval operation and attempt to submit it */
+ op = kzalloc(sizeof(*op), GFP_NOIO);
+ if (!op) {
+ fscache_stat(&fscache_n_retrievals_nomem);
+ return NULL;
+ }
+
+ fscache_operation_init(&op->op, fscache_release_retrieval_op);
+ op->op.flags = FSCACHE_OP_MYTHREAD | (1 << FSCACHE_OP_WAITING);
+ op->mapping = mapping;
+ op->end_io_func = end_io_func;
+ op->context = context;
+ op->start_time = jiffies;
+ INIT_WORK(&op->op.fast_work, fscache_retrieval_work);
+ INIT_LIST_HEAD(&op->to_do);
+ return op;
+}
+
+/*
+ * wait for a deferred lookup to complete
+ */
+static int fscache_wait_for_deferred_lookup(struct fscache_cookie *cookie)
+{
+ unsigned long jif;
+
+ _enter("");
+
+ if (!test_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags)) {
+ _leave(" = 0 [imm]");
+ return 0;
+ }
+
+ fscache_stat(&fscache_n_retrievals_wait);
+
+ jif = jiffies;
+ if (wait_on_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP,
+ fscache_wait_bit_interruptible,
+ TASK_INTERRUPTIBLE) != 0) {
+ fscache_stat(&fscache_n_retrievals_intr);
+ _leave(" = -ERESTARTSYS");
+ return -ERESTARTSYS;
+ }
+
+ ASSERT(!test_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags));
+
+ smp_rmb();
+ fscache_hist(fscache_retrieval_delay_histogram, jif);
+ _leave(" = 0 [dly]");
+ return 0;
+}
+
+/*
+ * read a page from the cache or allocate a block in which to store it
+ * - we return:
+ * -ENOMEM - out of memory, nothing done
+ * -ERESTARTSYS - interrupted
+ * -ENOBUFS - no backing object available in which to cache the block
+ * -ENODATA - no data available in the backing object for this block
+ * 0 - dispatched a read - it'll call end_io_func() when finished
+ */
+int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
+ struct page *page,
+ fscache_rw_complete_t end_io_func,
+ void *context,
+ gfp_t gfp)
+{
+ struct fscache_retrieval *op;
+ struct fscache_object *object;
+ int ret;
+
+ _enter("%p,%p,,,", cookie, page);
+
+ fscache_stat(&fscache_n_retrievals);
+
+ if (hlist_empty(&cookie->backing_objects))
+ goto nobufs;
+
+ ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
+ ASSERTCMP(page, !=, NULL);
+
+ if (fscache_wait_for_deferred_lookup(cookie) < 0)
+ return -ERESTARTSYS;
+
+ op = fscache_alloc_retrieval(page->mapping, end_io_func, context);
+ if (!op) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+ }
+
+ spin_lock(&cookie->lock);
+
+ if (hlist_empty(&cookie->backing_objects))
+ goto nobufs_unlock;
+ object = hlist_entry(cookie->backing_objects.first,
+ struct fscache_object, cookie_link);
+
+ ASSERTCMP(object->state, >, FSCACHE_OBJECT_LOOKING_UP);
+
+ if (fscache_submit_op(object, &op->op) < 0)
+ goto nobufs_unlock;
+ spin_unlock(&cookie->lock);
+
+ fscache_stat(&fscache_n_retrieval_ops);
+
+ /* pin the netfs read context in case we need to do the actual netfs
+ * read because we've encountered a cache read failure */
+ fscache_get_context(object->cookie, op->context);
+
+ /* we wait for the operation to become active, and then process it
+ * *here*, in this thread, and not in the thread pool */
+ if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
+ _debug(">>> WT");
+ fscache_stat(&fscache_n_retrieval_op_waits);
+ wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
+ fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+ _debug("<<< GO");
+ }
+
+ /* ask the cache to honour the operation */
+ if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) {
+ ret = object->cache->ops->allocate_page(op, page, gfp);
+ if (ret == 0)
+ ret = -ENODATA;
+ } else {
+ ret = object->cache->ops->read_or_alloc_page(op, page, gfp);
+ }
+
+ if (ret == -ENOMEM)
+ fscache_stat(&fscache_n_retrievals_nomem);
+ else if (ret == -ERESTARTSYS)
+ fscache_stat(&fscache_n_retrievals_intr);
+ else if (ret == -ENODATA)
+ fscache_stat(&fscache_n_retrievals_nodata);
+ else if (ret < 0)
+ fscache_stat(&fscache_n_retrievals_nobufs);
+ else
+ fscache_stat(&fscache_n_retrievals_ok);
+
+ fscache_put_retrieval(op);
+ _leave(" = %d", ret);
+ return ret;
+
+nobufs_unlock:
+ spin_unlock(&cookie->lock);
+ kfree(op);
+nobufs:
+ fscache_stat(&fscache_n_retrievals_nobufs);
+ _leave(" = -ENOBUFS");
+ return -ENOBUFS;
+}
+EXPORT_SYMBOL(__fscache_read_or_alloc_page);
+
+/*
+ * read a list of page from the cache or allocate a block in which to store
+ * them
+ * - we return:
+ * -ENOMEM - out of memory, some pages may be being read
+ * -ERESTARTSYS - interrupted, some pages may be being read
+ * -ENOBUFS - no backing object or space available in which to cache any
+ * pages not being read
+ * -ENODATA - no data available in the backing object for some or all of
+ * the pages
+ * 0 - dispatched a read on all pages
+ *
+ * end_io_func() will be called for each page read from the cache as it is
+ * finishes being read
+ *
+ * any pages for which a read is dispatched will be removed from pages and
+ * nr_pages
+ */
+int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
+ struct address_space *mapping,
+ struct list_head *pages,
+ unsigned *nr_pages,
+ fscache_rw_complete_t end_io_func,
+ void *context,
+ gfp_t gfp)
+{
+ fscache_pages_retrieval_func_t func;
+ struct fscache_retrieval *op;
+ struct fscache_object *object;
+ int ret;
+
+ _enter("%p,,%d,,,", cookie, *nr_pages);
+
+ fscache_stat(&fscache_n_retrievals);
+
+ if (hlist_empty(&cookie->backing_objects))
+ goto nobufs;
+
+ ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
+ ASSERTCMP(*nr_pages, >, 0);
+ ASSERT(!list_empty(pages));
+
+ if (fscache_wait_for_deferred_lookup(cookie) < 0)
+ return -ERESTARTSYS;
+
+ op = fscache_alloc_retrieval(mapping, end_io_func, context);
+ if (!op)
+ return -ENOMEM;
+
+ spin_lock(&cookie->lock);
+
+ if (hlist_empty(&cookie->backing_objects))
+ goto nobufs_unlock;
+ object = hlist_entry(cookie->backing_objects.first,
+ struct fscache_object, cookie_link);
+
+ if (fscache_submit_op(object, &op->op) < 0)
+ goto nobufs_unlock;
+ spin_unlock(&cookie->lock);
+
+ fscache_stat(&fscache_n_retrieval_ops);
+
+ /* pin the netfs read context in case we need to do the actual netfs
+ * read because we've encountered a cache read failure */
+ fscache_get_context(object->cookie, op->context);
+
+ /* we wait for the operation to become active, and then process it
+ * *here*, in this thread, and not in the thread pool */
+ if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
+ _debug(">>> WT");
+ fscache_stat(&fscache_n_retrieval_op_waits);
+ wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
+ fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+ _debug("<<< GO");
+ }
+
+ /* ask the cache to honour the operation */
+ if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags))
+ func = object->cache->ops->allocate_pages;
+ else
+ func = object->cache->ops->read_or_alloc_pages;
+ ret = func(op, pages, nr_pages, gfp);
+
+ if (ret == -ENOMEM)
+ fscache_stat(&fscache_n_retrievals_nomem);
+ else if (ret == -ERESTARTSYS)
+ fscache_stat(&fscache_n_retrievals_intr);
+ else if (ret == -ENODATA)
+ fscache_stat(&fscache_n_retrievals_nodata);
+ else if (ret < 0)
+ fscache_stat(&fscache_n_retrievals_nobufs);
+ else
+ fscache_stat(&fscache_n_retrievals_ok);
+
+ fscache_put_retrieval(op);
+ _leave(" = %d", ret);
+ return ret;
+
+nobufs_unlock:
+ spin_unlock(&cookie->lock);
+ kfree(op);
+nobufs:
+ fscache_stat(&fscache_n_retrievals_nobufs);
+ _leave(" = -ENOBUFS");
+ return -ENOBUFS;
+}
+EXPORT_SYMBOL(__fscache_read_or_alloc_pages);
+
+/*
+ * allocate a block in the cache on which to store a page
+ * - we return:
+ * -ENOMEM - out of memory, nothing done
+ * -ERESTARTSYS - interrupted
+ * -ENOBUFS - no backing object available in which to cache the block
+ * 0 - block allocated
+ */
+int __fscache_alloc_page(struct fscache_cookie *cookie,
+ struct page *page,
+ gfp_t gfp)
+{
+ struct fscache_retrieval *op;
+ struct fscache_object *object;
+ int ret;
+
+ _enter("%p,%p,,,", cookie, page);
+
+ fscache_stat(&fscache_n_allocs);
+
+ if (hlist_empty(&cookie->backing_objects))
+ goto nobufs;
+
+ ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
+ ASSERTCMP(page, !=, NULL);
+
+ if (fscache_wait_for_deferred_lookup(cookie) < 0)
+ return -ERESTARTSYS;
+
+ op = fscache_alloc_retrieval(page->mapping, NULL, NULL);
+ if (!op)
+ return -ENOMEM;
+
+ spin_lock(&cookie->lock);
+
+ if (hlist_empty(&cookie->backing_objects))
+ goto nobufs_unlock;
+ object = hlist_entry(cookie->backing_objects.first,
+ struct fscache_object, cookie_link);
+
+ if (fscache_submit_op(object, &op->op) < 0)
+ goto nobufs_unlock;
+ spin_unlock(&cookie->lock);
+
+ fscache_stat(&fscache_n_alloc_ops);
+
+ if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
+ _debug(">>> WT");
+ fscache_stat(&fscache_n_alloc_op_waits);
+ wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
+ fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+ _debug("<<< GO");
+ }
+
+ /* ask the cache to honour the operation */
+ ret = object->cache->ops->allocate_page(op, page, gfp);
+
+ if (ret < 0)
+ fscache_stat(&fscache_n_allocs_nobufs);
+ else
+ fscache_stat(&fscache_n_allocs_ok);
+
+ fscache_put_retrieval(op);
+ _leave(" = %d", ret);
+ return ret;
+
+nobufs_unlock:
+ spin_unlock(&cookie->lock);
+ kfree(op);
+nobufs:
+ fscache_stat(&fscache_n_allocs_nobufs);
+ _leave(" = -ENOBUFS");
+ return -ENOBUFS;
+}
+EXPORT_SYMBOL(__fscache_alloc_page);
+
+/*
+ * release a write op reference
+ */
+static void fscache_release_write_op(struct fscache_operation *_op)
+{
+ _enter("{OP%x}", _op->debug_id);
+}
+
+/*
+ * perform the background storage of a page into the cache
+ */
+static void fscache_write_op(struct fscache_operation *_op)
+{
+ struct fscache_storage *op =
+ container_of(_op, struct fscache_storage, op);
+ struct fscache_object *object = op->op.object;
+ struct fscache_cookie *cookie = object->cookie;
+ struct page *page;
+ unsigned n;
+ void *results[1];
+ int ret;
+
+ _enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage));
+
+ spin_lock(&cookie->lock);
+ spin_lock(&object->lock);
+
+ if (!fscache_object_is_active(object)) {
+ spin_unlock(&object->lock);
+ spin_unlock(&cookie->lock);
+ _leave("");
+ return;
+ }
+
+ fscache_stat(&fscache_n_store_calls);
+
+ /* find a page to store */
+ page = NULL;
+ n = radix_tree_gang_lookup_tag(&cookie->stores, results, 0, 1,
+ FSCACHE_COOKIE_PENDING_TAG);
+ if (n != 1)
+ goto superseded;
+ page = results[0];
+ _debug("gang %d [%lx]", n, page->index);
+ if (page->index > op->store_limit)
+ goto superseded;
+
+ radix_tree_tag_clear(&cookie->stores, page->index,
+ FSCACHE_COOKIE_PENDING_TAG);
+
+ spin_unlock(&object->lock);
+ spin_unlock(&cookie->lock);
+
+ if (page) {
+ ret = object->cache->ops->write_page(op, page);
+ fscache_end_page_write(cookie, page);
+ page_cache_release(page);
+ if (ret < 0)
+ fscache_abort_object(object);
+ else
+ fscache_enqueue_operation(&op->op);
+ }
+
+ _leave("");
+ return;
+
+superseded:
+ /* this writer is going away and there aren't any more things to
+ * write */
+ _debug("cease");
+ clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags);
+ spin_unlock(&object->lock);
+ spin_unlock(&cookie->lock);
+ _leave("");
+}
+
+/*
+ * request a page be stored in the cache
+ * - returns:
+ * -ENOMEM - out of memory, nothing done
+ * -ENOBUFS - no backing object available in which to cache the page
+ * 0 - dispatched a write - it'll call end_io_func() when finished
+ *
+ * if the cookie still has a backing object at this point, that object can be
+ * in one of a few states with respect to storage processing:
+ *
+ * (1) negative lookup, object not yet created (FSCACHE_COOKIE_CREATING is
+ * set)
+ *
+ * (a) no writes yet (set FSCACHE_COOKIE_PENDING_FILL and queue deferred
+ * fill op)
+ *
+ * (b) writes deferred till post-creation (mark page for writing and
+ * return immediately)
+ *
+ * (2) negative lookup, object created, initial fill being made from netfs
+ * (FSCACHE_COOKIE_INITIAL_FILL is set)
+ *
+ * (a) fill point not yet reached this page (mark page for writing and
+ * return)
+ *
+ * (b) fill point passed this page (queue op to store this page)
+ *
+ * (3) object extant (queue op to store this page)
+ *
+ * any other state is invalid
+ */
+int __fscache_write_page(struct fscache_cookie *cookie,
+ struct page *page,
+ gfp_t gfp)
+{
+ struct fscache_storage *op;
+ struct fscache_object *object;
+ int ret;
+
+ _enter("%p,%x,", cookie, (u32) page->flags);
+
+ ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
+ ASSERT(PageFsCache(page));
+
+ fscache_stat(&fscache_n_stores);
+
+ op = kzalloc(sizeof(*op), GFP_NOIO);
+ if (!op)
+ goto nomem;
+
+ fscache_operation_init(&op->op, fscache_release_write_op);
+ fscache_operation_init_slow(&op->op, fscache_write_op);
+ op->op.flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_WAITING);
+
+ ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM);
+ if (ret < 0)
+ goto nomem_free;
+
+ ret = -ENOBUFS;
+ spin_lock(&cookie->lock);
+
+ if (hlist_empty(&cookie->backing_objects))
+ goto nobufs;
+ object = hlist_entry(cookie->backing_objects.first,
+ struct fscache_object, cookie_link);
+ if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
+ goto nobufs;
+
+ /* add the page to the pending-storage radix tree on the backing
+ * object */
+ spin_lock(&object->lock);
+
+ _debug("store limit %llx", (unsigned long long) object->store_limit);
+
+ ret = radix_tree_insert(&cookie->stores, page->index, page);
+ if (ret < 0) {
+ if (ret == -EEXIST)
+ goto already_queued;
+ _debug("insert failed %d", ret);
+ goto nobufs_unlock_obj;
+ }
+
+ radix_tree_tag_set(&cookie->stores, page->index,
+ FSCACHE_COOKIE_PENDING_TAG);
+ page_cache_get(page);
+
+ /* we only want one writer at a time, but we do need to queue new
+ * writers after exclusive ops */
+ if (test_and_set_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags))
+ goto already_pending;
+
+ spin_unlock(&object->lock);
+
+ op->op.debug_id = atomic_inc_return(&fscache_op_debug_id);
+ op->store_limit = object->store_limit;
+
+ if (fscache_submit_op(object, &op->op) < 0)
+ goto submit_failed;
+
+ spin_unlock(&cookie->lock);
+ radix_tree_preload_end();
+ fscache_stat(&fscache_n_store_ops);
+ fscache_stat(&fscache_n_stores_ok);
+
+ /* the slow work queue now carries its own ref on the object */
+ fscache_put_operation(&op->op);
+ _leave(" = 0");
+ return 0;
+
+already_queued:
+ fscache_stat(&fscache_n_stores_again);
+already_pending:
+ spin_unlock(&object->lock);
+ spin_unlock(&cookie->lock);
+ radix_tree_preload_end();
+ kfree(op);
+ fscache_stat(&fscache_n_stores_ok);
+ _leave(" = 0");
+ return 0;
+
+submit_failed:
+ radix_tree_delete(&cookie->stores, page->index);
+ page_cache_release(page);
+ ret = -ENOBUFS;
+ goto nobufs;
+
+nobufs_unlock_obj:
+ spin_unlock(&object->lock);
+nobufs:
+ spin_unlock(&cookie->lock);
+ radix_tree_preload_end();
+ kfree(op);
+ fscache_stat(&fscache_n_stores_nobufs);
+ _leave(" = -ENOBUFS");
+ return -ENOBUFS;
+
+nomem_free:
+ kfree(op);
+nomem:
+ fscache_stat(&fscache_n_stores_oom);
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+}
+EXPORT_SYMBOL(__fscache_write_page);
+
+/*
+ * remove a page from the cache
+ */
+void __fscache_uncache_page(struct fscache_cookie *cookie, struct page *page)
+{
+ struct fscache_object *object;
+
+ _enter(",%p", page);
+
+ ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
+ ASSERTCMP(page, !=, NULL);
+
+ fscache_stat(&fscache_n_uncaches);
+
+ /* cache withdrawal may beat us to it */
+ if (!PageFsCache(page))
+ goto done;
+
+ /* get the object */
+ spin_lock(&cookie->lock);
+
+ if (hlist_empty(&cookie->backing_objects)) {
+ ClearPageFsCache(page);
+ goto done_unlock;
+ }
+
+ object = hlist_entry(cookie->backing_objects.first,
+ struct fscache_object, cookie_link);
+
+ /* there might now be stuff on disk we could read */
+ clear_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
+
+ /* only invoke the cache backend if we managed to mark the page
+ * uncached here; this deals with synchronisation vs withdrawal */
+ if (TestClearPageFsCache(page) &&
+ object->cache->ops->uncache_page) {
+ /* the cache backend releases the cookie lock */
+ object->cache->ops->uncache_page(object, page);
+ goto done;
+ }
+
+done_unlock:
+ spin_unlock(&cookie->lock);
+done:
+ _leave("");
+}
+EXPORT_SYMBOL(__fscache_uncache_page);
+
+/**
+ * fscache_mark_pages_cached - Mark pages as being cached
+ * @op: The retrieval op pages are being marked for
+ * @pagevec: The pages to be marked
+ *
+ * Mark a bunch of netfs pages as being cached. After this is called,
+ * the netfs must call fscache_uncache_page() to remove the mark.
+ */
+void fscache_mark_pages_cached(struct fscache_retrieval *op,
+ struct pagevec *pagevec)
+{
+ struct fscache_cookie *cookie = op->op.object->cookie;
+ unsigned long loop;
+
+#ifdef CONFIG_FSCACHE_STATS
+ atomic_add(pagevec->nr, &fscache_n_marks);
+#endif
+
+ for (loop = 0; loop < pagevec->nr; loop++) {
+ struct page *page = pagevec->pages[loop];
+
+ _debug("- mark %p{%lx}", page, page->index);
+ if (TestSetPageFsCache(page)) {
+ static bool once_only;
+ if (!once_only) {
+ once_only = true;
+ printk(KERN_WARNING "FS-Cache:"
+ " Cookie type %s marked page %lx"
+ " multiple times\n",
+ cookie->def->name, page->index);
+ }
+ }
+ }
+
+ if (cookie->def->mark_pages_cached)
+ cookie->def->mark_pages_cached(cookie->netfs_data,
+ op->mapping, pagevec);
+ pagevec_reinit(pagevec);
+}
+EXPORT_SYMBOL(fscache_mark_pages_cached);
diff --git a/fs/fscache/proc.c b/fs/fscache/proc.c
new file mode 100644
index 00000000000..beeab44bc31
--- /dev/null
+++ b/fs/fscache/proc.c
@@ -0,0 +1,68 @@
+/* FS-Cache statistics viewing interface
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL OPERATION
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+/*
+ * initialise the /proc/fs/fscache/ directory
+ */
+int __init fscache_proc_init(void)
+{
+ _enter("");
+
+ if (!proc_mkdir("fs/fscache", NULL))
+ goto error_dir;
+
+#ifdef CONFIG_FSCACHE_STATS
+ if (!proc_create("fs/fscache/stats", S_IFREG | 0444, NULL,
+ &fscache_stats_fops))
+ goto error_stats;
+#endif
+
+#ifdef CONFIG_FSCACHE_HISTOGRAM
+ if (!proc_create("fs/fscache/histogram", S_IFREG | 0444, NULL,
+ &fscache_histogram_fops))
+ goto error_histogram;
+#endif
+
+ _leave(" = 0");
+ return 0;
+
+#ifdef CONFIG_FSCACHE_HISTOGRAM
+error_histogram:
+#endif
+#ifdef CONFIG_FSCACHE_STATS
+ remove_proc_entry("fs/fscache/stats", NULL);
+error_stats:
+#endif
+ remove_proc_entry("fs/fscache", NULL);
+error_dir:
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+}
+
+/*
+ * clean up the /proc/fs/fscache/ directory
+ */
+void fscache_proc_cleanup(void)
+{
+#ifdef CONFIG_FSCACHE_HISTOGRAM
+ remove_proc_entry("fs/fscache/histogram", NULL);
+#endif
+#ifdef CONFIG_FSCACHE_STATS
+ remove_proc_entry("fs/fscache/stats", NULL);
+#endif
+ remove_proc_entry("fs/fscache", NULL);
+}
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c
new file mode 100644
index 00000000000..65deb99e756
--- /dev/null
+++ b/fs/fscache/stats.c
@@ -0,0 +1,212 @@
+/* FS-Cache statistics
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL THREAD
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+/*
+ * operation counters
+ */
+atomic_t fscache_n_op_pend;
+atomic_t fscache_n_op_run;
+atomic_t fscache_n_op_enqueue;
+atomic_t fscache_n_op_requeue;
+atomic_t fscache_n_op_deferred_release;
+atomic_t fscache_n_op_release;
+atomic_t fscache_n_op_gc;
+
+atomic_t fscache_n_attr_changed;
+atomic_t fscache_n_attr_changed_ok;
+atomic_t fscache_n_attr_changed_nobufs;
+atomic_t fscache_n_attr_changed_nomem;
+atomic_t fscache_n_attr_changed_calls;
+
+atomic_t fscache_n_allocs;
+atomic_t fscache_n_allocs_ok;
+atomic_t fscache_n_allocs_wait;
+atomic_t fscache_n_allocs_nobufs;
+atomic_t fscache_n_alloc_ops;
+atomic_t fscache_n_alloc_op_waits;
+
+atomic_t fscache_n_retrievals;
+atomic_t fscache_n_retrievals_ok;
+atomic_t fscache_n_retrievals_wait;
+atomic_t fscache_n_retrievals_nodata;
+atomic_t fscache_n_retrievals_nobufs;
+atomic_t fscache_n_retrievals_intr;
+atomic_t fscache_n_retrievals_nomem;
+atomic_t fscache_n_retrieval_ops;
+atomic_t fscache_n_retrieval_op_waits;
+
+atomic_t fscache_n_stores;
+atomic_t fscache_n_stores_ok;
+atomic_t fscache_n_stores_again;
+atomic_t fscache_n_stores_nobufs;
+atomic_t fscache_n_stores_oom;
+atomic_t fscache_n_store_ops;
+atomic_t fscache_n_store_calls;
+
+atomic_t fscache_n_marks;
+atomic_t fscache_n_uncaches;
+
+atomic_t fscache_n_acquires;
+atomic_t fscache_n_acquires_null;
+atomic_t fscache_n_acquires_no_cache;
+atomic_t fscache_n_acquires_ok;
+atomic_t fscache_n_acquires_nobufs;
+atomic_t fscache_n_acquires_oom;
+
+atomic_t fscache_n_updates;
+atomic_t fscache_n_updates_null;
+atomic_t fscache_n_updates_run;
+
+atomic_t fscache_n_relinquishes;
+atomic_t fscache_n_relinquishes_null;
+atomic_t fscache_n_relinquishes_waitcrt;
+
+atomic_t fscache_n_cookie_index;
+atomic_t fscache_n_cookie_data;
+atomic_t fscache_n_cookie_special;
+
+atomic_t fscache_n_object_alloc;
+atomic_t fscache_n_object_no_alloc;
+atomic_t fscache_n_object_lookups;
+atomic_t fscache_n_object_lookups_negative;
+atomic_t fscache_n_object_lookups_positive;
+atomic_t fscache_n_object_created;
+atomic_t fscache_n_object_avail;
+atomic_t fscache_n_object_dead;
+
+atomic_t fscache_n_checkaux_none;
+atomic_t fscache_n_checkaux_okay;
+atomic_t fscache_n_checkaux_update;
+atomic_t fscache_n_checkaux_obsolete;
+
+/*
+ * display the general statistics
+ */
+static int fscache_stats_show(struct seq_file *m, void *v)
+{
+ seq_puts(m, "FS-Cache statistics\n");
+
+ seq_printf(m, "Cookies: idx=%u dat=%u spc=%u\n",
+ atomic_read(&fscache_n_cookie_index),
+ atomic_read(&fscache_n_cookie_data),
+ atomic_read(&fscache_n_cookie_special));
+
+ seq_printf(m, "Objects: alc=%u nal=%u avl=%u ded=%u\n",
+ atomic_read(&fscache_n_object_alloc),
+ atomic_read(&fscache_n_object_no_alloc),
+ atomic_read(&fscache_n_object_avail),
+ atomic_read(&fscache_n_object_dead));
+ seq_printf(m, "ChkAux : non=%u ok=%u upd=%u obs=%u\n",
+ atomic_read(&fscache_n_checkaux_none),
+ atomic_read(&fscache_n_checkaux_okay),
+ atomic_read(&fscache_n_checkaux_update),
+ atomic_read(&fscache_n_checkaux_obsolete));
+
+ seq_printf(m, "Pages : mrk=%u unc=%u\n",
+ atomic_read(&fscache_n_marks),
+ atomic_read(&fscache_n_uncaches));
+
+ seq_printf(m, "Acquire: n=%u nul=%u noc=%u ok=%u nbf=%u"
+ " oom=%u\n",
+ atomic_read(&fscache_n_acquires),
+ atomic_read(&fscache_n_acquires_null),
+ atomic_read(&fscache_n_acquires_no_cache),
+ atomic_read(&fscache_n_acquires_ok),
+ atomic_read(&fscache_n_acquires_nobufs),
+ atomic_read(&fscache_n_acquires_oom));
+
+ seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u\n",
+ atomic_read(&fscache_n_object_lookups),
+ atomic_read(&fscache_n_object_lookups_negative),
+ atomic_read(&fscache_n_object_lookups_positive),
+ atomic_read(&fscache_n_object_created));
+
+ seq_printf(m, "Updates: n=%u nul=%u run=%u\n",
+ atomic_read(&fscache_n_updates),
+ atomic_read(&fscache_n_updates_null),
+ atomic_read(&fscache_n_updates_run));
+
+ seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u\n",
+ atomic_read(&fscache_n_relinquishes),
+ atomic_read(&fscache_n_relinquishes_null),
+ atomic_read(&fscache_n_relinquishes_waitcrt));
+
+ seq_printf(m, "AttrChg: n=%u ok=%u nbf=%u oom=%u run=%u\n",
+ atomic_read(&fscache_n_attr_changed),
+ atomic_read(&fscache_n_attr_changed_ok),
+ atomic_read(&fscache_n_attr_changed_nobufs),
+ atomic_read(&fscache_n_attr_changed_nomem),
+ atomic_read(&fscache_n_attr_changed_calls));
+
+ seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u\n",
+ atomic_read(&fscache_n_allocs),
+ atomic_read(&fscache_n_allocs_ok),
+ atomic_read(&fscache_n_allocs_wait),
+ atomic_read(&fscache_n_allocs_nobufs));
+ seq_printf(m, "Allocs : ops=%u owt=%u\n",
+ atomic_read(&fscache_n_alloc_ops),
+ atomic_read(&fscache_n_alloc_op_waits));
+
+ seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u"
+ " int=%u oom=%u\n",
+ atomic_read(&fscache_n_retrievals),
+ atomic_read(&fscache_n_retrievals_ok),
+ atomic_read(&fscache_n_retrievals_wait),
+ atomic_read(&fscache_n_retrievals_nodata),
+ atomic_read(&fscache_n_retrievals_nobufs),
+ atomic_read(&fscache_n_retrievals_intr),
+ atomic_read(&fscache_n_retrievals_nomem));
+ seq_printf(m, "Retrvls: ops=%u owt=%u\n",
+ atomic_read(&fscache_n_retrieval_ops),
+ atomic_read(&fscache_n_retrieval_op_waits));
+
+ seq_printf(m, "Stores : n=%u ok=%u agn=%u nbf=%u oom=%u\n",
+ atomic_read(&fscache_n_stores),
+ atomic_read(&fscache_n_stores_ok),
+ atomic_read(&fscache_n_stores_again),
+ atomic_read(&fscache_n_stores_nobufs),
+ atomic_read(&fscache_n_stores_oom));
+ seq_printf(m, "Stores : ops=%u run=%u\n",
+ atomic_read(&fscache_n_store_ops),
+ atomic_read(&fscache_n_store_calls));
+
+ seq_printf(m, "Ops : pend=%u run=%u enq=%u\n",
+ atomic_read(&fscache_n_op_pend),
+ atomic_read(&fscache_n_op_run),
+ atomic_read(&fscache_n_op_enqueue));
+ seq_printf(m, "Ops : dfr=%u rel=%u gc=%u\n",
+ atomic_read(&fscache_n_op_deferred_release),
+ atomic_read(&fscache_n_op_release),
+ atomic_read(&fscache_n_op_gc));
+ return 0;
+}
+
+/*
+ * open "/proc/fs/fscache/stats" allowing provision of a statistical summary
+ */
+static int fscache_stats_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, fscache_stats_show, NULL);
+}
+
+const struct file_operations fscache_stats_fops = {
+ .owner = THIS_MODULE,
+ .open = fscache_stats_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 06da05261e0..8b8eebc5614 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1032,6 +1032,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
fuse_put_request(fc, req);
return -ENOMEM;
}
+ req->out.argpages = 1;
req->num_pages = 1;
req->pages[0] = page;
fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR);
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 4e340fedf76..06f30e96567 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -386,7 +386,6 @@ void fuse_read_fill(struct fuse_req *req, struct file *file,
req->in.numargs = 1;
req->in.args[0].size = sizeof(struct fuse_read_in);
req->in.args[0].value = inarg;
- req->out.argpages = 1;
req->out.argvar = 1;
req->out.numargs = 1;
req->out.args[0].size = count;
@@ -453,6 +452,7 @@ static int fuse_readpage(struct file *file, struct page *page)
attr_ver = fuse_get_attr_version(fc);
req->out.page_zeroing = 1;
+ req->out.argpages = 1;
req->num_pages = 1;
req->pages[0] = page;
num_read = fuse_send_read(req, file, inode, pos, count, NULL);
@@ -510,6 +510,8 @@ static void fuse_send_readpages(struct fuse_req *req, struct file *file,
struct fuse_conn *fc = get_fuse_conn(inode);
loff_t pos = page_offset(req->pages[0]);
size_t count = req->num_pages << PAGE_CACHE_SHIFT;
+
+ req->out.argpages = 1;
req->out.page_zeroing = 1;
fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
req->misc.read.attr_ver = fuse_get_attr_version(fc);
@@ -621,7 +623,6 @@ static void fuse_write_fill(struct fuse_req *req, struct file *file,
inarg->flags = file ? file->f_flags : 0;
req->in.h.opcode = FUSE_WRITE;
req->in.h.nodeid = get_node_id(inode);
- req->in.argpages = 1;
req->in.numargs = 2;
if (fc->minor < 9)
req->in.args[0].size = FUSE_COMPAT_WRITE_IN_SIZE;
@@ -695,6 +696,7 @@ static int fuse_buffered_write(struct file *file, struct inode *inode,
if (IS_ERR(req))
return PTR_ERR(req);
+ req->in.argpages = 1;
req->num_pages = 1;
req->pages[0] = page;
req->page_offset = offset;
@@ -771,6 +773,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
size_t count = 0;
int err;
+ req->in.argpages = 1;
req->page_offset = offset;
do {
@@ -935,21 +938,28 @@ static void fuse_release_user_pages(struct fuse_req *req, int write)
}
static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
- unsigned nbytes, int write)
+ size_t *nbytesp, int write)
{
+ size_t nbytes = *nbytesp;
unsigned long user_addr = (unsigned long) buf;
unsigned offset = user_addr & ~PAGE_MASK;
int npages;
- /* This doesn't work with nfsd */
- if (!current->mm)
- return -EPERM;
+ /* Special case for kernel I/O: can copy directly into the buffer */
+ if (segment_eq(get_fs(), KERNEL_DS)) {
+ if (write)
+ req->in.args[1].value = (void *) user_addr;
+ else
+ req->out.args[0].value = (void *) user_addr;
+
+ return 0;
+ }
- nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
+ nbytes = min_t(size_t, nbytes, FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
npages = clamp(npages, 1, FUSE_MAX_PAGES_PER_REQ);
down_read(&current->mm->mmap_sem);
- npages = get_user_pages(current, current->mm, user_addr, npages, write,
+ npages = get_user_pages(current, current->mm, user_addr, npages, !write,
0, req->pages, NULL);
up_read(&current->mm->mmap_sem);
if (npages < 0)
@@ -957,6 +967,15 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
req->num_pages = npages;
req->page_offset = offset;
+
+ if (write)
+ req->in.argpages = 1;
+ else
+ req->out.argpages = 1;
+
+ nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset;
+ *nbytesp = min(*nbytesp, nbytes);
+
return 0;
}
@@ -979,15 +998,13 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
while (count) {
size_t nres;
- size_t nbytes_limit = min(count, nmax);
- size_t nbytes;
- int err = fuse_get_user_pages(req, buf, nbytes_limit, !write);
+ size_t nbytes = min(count, nmax);
+ int err = fuse_get_user_pages(req, buf, &nbytes, write);
if (err) {
res = err;
break;
}
- nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset;
- nbytes = min(nbytes_limit, nbytes);
+
if (write)
nres = fuse_send_write(req, file, inode, pos, nbytes,
current->files);
@@ -1163,6 +1180,7 @@ static int fuse_writepage_locked(struct page *page)
fuse_write_fill(req, NULL, ff, inode, page_offset(page), 0, 1);
copy_highpage(tmp_page, page);
+ req->in.argpages = 1;
req->num_pages = 1;
req->pages[0] = tmp_page;
req->page_offset = 0;
@@ -1274,6 +1292,17 @@ static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
+static int fuse_direct_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ /* Can't provide the coherency needed for MAP_SHARED */
+ if (vma->vm_flags & VM_MAYSHARE)
+ return -ENODEV;
+
+ invalidate_inode_pages2(file->f_mapping);
+
+ return generic_file_mmap(file, vma);
+}
+
static int convert_fuse_file_lock(const struct fuse_file_lock *ffl,
struct file_lock *fl)
{
@@ -1908,6 +1937,7 @@ static const struct file_operations fuse_direct_io_file_operations = {
.llseek = fuse_file_llseek,
.read = fuse_direct_read,
.write = fuse_direct_write,
+ .mmap = fuse_direct_mmap,
.open = fuse_open,
.flush = fuse_flush,
.release = fuse_release,
@@ -1917,7 +1947,7 @@ static const struct file_operations fuse_direct_io_file_operations = {
.unlocked_ioctl = fuse_file_ioctl,
.compat_ioctl = fuse_file_compat_ioctl,
.poll = fuse_file_poll,
- /* no mmap and splice_read */
+ /* no splice_read */
};
static const struct address_space_operations fuse_file_aops = {
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 9435dda8f1e..a1cbff2b4d9 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -70,6 +70,10 @@ static int hfs_releasepage(struct page *page, gfp_t mask)
BUG();
return 0;
}
+
+ if (!tree)
+ return 0;
+
if (tree->node_size >= PAGE_CACHE_SIZE) {
nidx = page->index >> (tree->node_size_shift - PAGE_CACHE_SHIFT);
spin_lock(&tree->hash_lock);
diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c
index 36ca2e1a4fa..7b6165f25fb 100644
--- a/fs/hfs/mdb.c
+++ b/fs/hfs/mdb.c
@@ -349,6 +349,7 @@ void hfs_mdb_put(struct super_block *sb)
if (HFS_SB(sb)->nls_disk)
unload_nls(HFS_SB(sb)->nls_disk);
+ free_pages((unsigned long)HFS_SB(sb)->bitmap, PAGE_SIZE < 8192 ? 1 : 0);
kfree(HFS_SB(sb));
sb->s_fs_info = NULL;
}
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 3fbffb1ea71..a8e8513a78a 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -20,6 +20,7 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
+#include <linux/bio.h>
/*
* Default IO end handler for temporary BJ_IO buffer_heads.
@@ -171,14 +172,15 @@ static int journal_write_commit_record(journal_t *journal,
return (ret == -EIO);
}
-static void journal_do_submit_data(struct buffer_head **wbuf, int bufs)
+static void journal_do_submit_data(struct buffer_head **wbuf, int bufs,
+ int write_op)
{
int i;
for (i = 0; i < bufs; i++) {
wbuf[i]->b_end_io = end_buffer_write_sync;
/* We use-up our safety reference in submit_bh() */
- submit_bh(WRITE, wbuf[i]);
+ submit_bh(write_op, wbuf[i]);
}
}
@@ -186,7 +188,8 @@ static void journal_do_submit_data(struct buffer_head **wbuf, int bufs)
* Submit all the data buffers to disk
*/
static int journal_submit_data_buffers(journal_t *journal,
- transaction_t *commit_transaction)
+ transaction_t *commit_transaction,
+ int write_op)
{
struct journal_head *jh;
struct buffer_head *bh;
@@ -225,7 +228,7 @@ write_out_data:
BUFFER_TRACE(bh, "needs blocking lock");
spin_unlock(&journal->j_list_lock);
/* Write out all data to prevent deadlocks */
- journal_do_submit_data(wbuf, bufs);
+ journal_do_submit_data(wbuf, bufs, write_op);
bufs = 0;
lock_buffer(bh);
spin_lock(&journal->j_list_lock);
@@ -256,7 +259,7 @@ write_out_data:
jbd_unlock_bh_state(bh);
if (bufs == journal->j_wbufsize) {
spin_unlock(&journal->j_list_lock);
- journal_do_submit_data(wbuf, bufs);
+ journal_do_submit_data(wbuf, bufs, write_op);
bufs = 0;
goto write_out_data;
}
@@ -286,7 +289,7 @@ write_out_data:
}
}
spin_unlock(&journal->j_list_lock);
- journal_do_submit_data(wbuf, bufs);
+ journal_do_submit_data(wbuf, bufs, write_op);
return err;
}
@@ -315,6 +318,7 @@ void journal_commit_transaction(journal_t *journal)
int first_tag = 0;
int tag_flag;
int i;
+ int write_op = WRITE;
/*
* First job: lock down the current transaction and wait for
@@ -347,6 +351,13 @@ void journal_commit_transaction(journal_t *journal)
spin_lock(&journal->j_state_lock);
commit_transaction->t_state = T_LOCKED;
+ /*
+ * Use plugged writes here, since we want to submit several before
+ * we unplug the device. We don't do explicit unplugging in here,
+ * instead we rely on sync_buffer() doing the unplug for us.
+ */
+ if (commit_transaction->t_synchronous_commit)
+ write_op = WRITE_SYNC_PLUG;
spin_lock(&commit_transaction->t_handle_lock);
while (commit_transaction->t_updates) {
DEFINE_WAIT(wait);
@@ -431,7 +442,8 @@ void journal_commit_transaction(journal_t *journal)
* Now start flushing things to disk, in the order they appear
* on the transaction lists. Data blocks go first.
*/
- err = journal_submit_data_buffers(journal, commit_transaction);
+ err = journal_submit_data_buffers(journal, commit_transaction,
+ write_op);
/*
* Wait for all previously submitted IO to complete.
@@ -660,7 +672,7 @@ start_journal_io:
clear_buffer_dirty(bh);
set_buffer_uptodate(bh);
bh->b_end_io = journal_end_buffer_io_sync;
- submit_bh(WRITE, bh);
+ submit_bh(write_op, bh);
}
cond_resched();
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c
index c7bd649bbbd..3e9afc2a91d 100644
--- a/fs/jbd/revoke.c
+++ b/fs/jbd/revoke.c
@@ -55,6 +55,25 @@
* need do nothing.
* RevokeValid set, Revoked set:
* buffer has been revoked.
+ *
+ * Locking rules:
+ * We keep two hash tables of revoke records. One hashtable belongs to the
+ * running transaction (is pointed to by journal->j_revoke), the other one
+ * belongs to the committing transaction. Accesses to the second hash table
+ * happen only from the kjournald and no other thread touches this table. Also
+ * journal_switch_revoke_table() which switches which hashtable belongs to the
+ * running and which to the committing transaction is called only from
+ * kjournald. Therefore we need no locks when accessing the hashtable belonging
+ * to the committing transaction.
+ *
+ * All users operating on the hash table belonging to the running transaction
+ * have a handle to the transaction. Therefore they are safe from kjournald
+ * switching hash tables under them. For operations on the lists of entries in
+ * the hash table j_revoke_lock is used.
+ *
+ * Finally, also replay code uses the hash tables but at this moment noone else
+ * can touch them (filesystem isn't mounted yet) and hence no locking is
+ * needed.
*/
#ifndef __KERNEL__
@@ -402,8 +421,6 @@ int journal_revoke(handle_t *handle, unsigned long blocknr,
* the second time we would still have a pending revoke to cancel. So,
* do not trust the Revoked bit on buffers unless RevokeValid is also
* set.
- *
- * The caller must have the journal locked.
*/
int journal_cancel_revoke(handle_t *handle, struct journal_head *jh)
{
@@ -481,10 +498,7 @@ void journal_switch_revoke_table(journal_t *journal)
/*
* Write revoke records to the journal for all entries in the current
* revoke hash, deleting the entries as we go.
- *
- * Called with the journal lock held.
*/
-
void journal_write_revoke_records(journal_t *journal,
transaction_t *transaction)
{
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index e6a11743127..ed886e6db39 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -1440,6 +1440,8 @@ int journal_stop(handle_t *handle)
}
}
+ if (handle->h_sync)
+ transaction->t_synchronous_commit = 1;
current->journal_info = NULL;
spin_lock(&journal->j_state_lock);
spin_lock(&transaction->t_handle_lock);
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 4ea72377c7a..073c8c3df7c 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -138,7 +138,7 @@ static int journal_submit_commit_record(journal_t *journal,
set_buffer_ordered(bh);
barrier_done = 1;
}
- ret = submit_bh(WRITE_SYNC, bh);
+ ret = submit_bh(WRITE_SYNC_PLUG, bh);
if (barrier_done)
clear_buffer_ordered(bh);
@@ -159,7 +159,7 @@ static int journal_submit_commit_record(journal_t *journal,
lock_buffer(bh);
set_buffer_uptodate(bh);
clear_buffer_dirty(bh);
- ret = submit_bh(WRITE_SYNC, bh);
+ ret = submit_bh(WRITE_SYNC_PLUG, bh);
}
*cbh = bh;
return ret;
@@ -190,7 +190,7 @@ retry:
set_buffer_uptodate(bh);
bh->b_end_io = journal_end_buffer_io_sync;
- ret = submit_bh(WRITE_SYNC, bh);
+ ret = submit_bh(WRITE_SYNC_PLUG, bh);
if (ret) {
unlock_buffer(bh);
return ret;
@@ -402,8 +402,13 @@ void jbd2_journal_commit_transaction(journal_t *journal)
spin_lock(&journal->j_state_lock);
commit_transaction->t_state = T_LOCKED;
+ /*
+ * Use plugged writes here, since we want to submit several before
+ * we unplug the device. We don't do explicit unplugging in here,
+ * instead we rely on sync_buffer() doing the unplug for us.
+ */
if (commit_transaction->t_synchronous_commit)
- write_op = WRITE_SYNC;
+ write_op = WRITE_SYNC_PLUG;
stats.u.run.rs_wait = commit_transaction->t_max_wait;
stats.u.run.rs_locked = jiffies;
stats.u.run.rs_running = jbd2_time_diff(commit_transaction->t_start,
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
index 77ccf8cb082..043740dde20 100644
--- a/fs/jffs2/acl.c
+++ b/fs/jffs2/acl.c
@@ -38,12 +38,12 @@ static int jffs2_acl_count(size_t size)
size_t s;
size -= sizeof(struct jffs2_acl_header);
- s = size - 4 * sizeof(struct jffs2_acl_entry_short);
- if (s < 0) {
+ if (size < 4 * sizeof(struct jffs2_acl_entry_short)) {
if (size % sizeof(struct jffs2_acl_entry_short))
return -1;
return size / sizeof(struct jffs2_acl_entry_short);
} else {
+ s = size - 4 * sizeof(struct jffs2_acl_entry_short);
if (s % sizeof(struct jffs2_acl_entry))
return -1;
return s / sizeof(struct jffs2_acl_entry) + 4;
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c
index f9211252b5f..9eff2bdae8a 100644
--- a/fs/jffs2/malloc.c
+++ b/fs/jffs2/malloc.c
@@ -284,10 +284,9 @@ void jffs2_free_inode_cache(struct jffs2_inode_cache *x)
struct jffs2_xattr_datum *jffs2_alloc_xattr_datum(void)
{
struct jffs2_xattr_datum *xd;
- xd = kmem_cache_alloc(xattr_datum_cache, GFP_KERNEL);
+ xd = kmem_cache_zalloc(xattr_datum_cache, GFP_KERNEL);
dbg_memalloc("%p\n", xd);
- memset(xd, 0, sizeof(struct jffs2_xattr_datum));
xd->class = RAWNODE_CLASS_XATTR_DATUM;
xd->node = (void *)xd;
INIT_LIST_HEAD(&xd->xindex);
@@ -303,10 +302,9 @@ void jffs2_free_xattr_datum(struct jffs2_xattr_datum *xd)
struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void)
{
struct jffs2_xattr_ref *ref;
- ref = kmem_cache_alloc(xattr_ref_cache, GFP_KERNEL);
+ ref = kmem_cache_zalloc(xattr_ref_cache, GFP_KERNEL);
dbg_memalloc("%p\n", ref);
- memset(ref, 0, sizeof(struct jffs2_xattr_ref));
ref->class = RAWNODE_CLASS_XATTR_REF;
ref->node = (void *)ref;
return ref;
diff --git a/fs/libfs.c b/fs/libfs.c
index 4910a36f516..cd223190c4e 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -575,6 +575,21 @@ ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
* possibly a read which collects the result - which is stored in a
* file-local buffer.
*/
+
+void simple_transaction_set(struct file *file, size_t n)
+{
+ struct simple_transaction_argresp *ar = file->private_data;
+
+ BUG_ON(n > SIMPLE_TRANSACTION_LIMIT);
+
+ /*
+ * The barrier ensures that ar->size will really remain zero until
+ * ar->data is ready for reading.
+ */
+ smp_mb();
+ ar->size = n;
+}
+
char *simple_transaction_get(struct file *file, const char __user *buf, size_t size)
{
struct simple_transaction_argresp *ar;
@@ -820,6 +835,7 @@ EXPORT_SYMBOL(simple_sync_file);
EXPORT_SYMBOL(simple_unlink);
EXPORT_SYMBOL(simple_read_from_buffer);
EXPORT_SYMBOL(memory_read_from_buffer);
+EXPORT_SYMBOL(simple_transaction_set);
EXPORT_SYMBOL(simple_transaction_get);
EXPORT_SYMBOL(simple_transaction_read);
EXPORT_SYMBOL(simple_transaction_release);
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 763b78a6e9d..83ee34203bd 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -426,8 +426,15 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
ret = nlm_granted;
goto out;
case -EAGAIN:
+ /*
+ * If this is a blocking request for an
+ * already pending lock request then we need
+ * to put it back on lockd's block list
+ */
+ if (wait)
+ break;
ret = nlm_lck_denied;
- break;
+ goto out;
case FILE_LOCK_DEFERRED:
if (wait)
break;
@@ -443,10 +450,6 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
goto out;
}
- ret = nlm_lck_denied;
- if (!wait)
- goto out;
-
ret = nlm_lck_blocked;
/* Append to list of blocked */
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 36fe20d6eba..e67f3ec0773 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -84,3 +84,11 @@ config ROOT_NFS
<file:Documentation/filesystems/nfsroot.txt>.
Most people say N here.
+
+config NFS_FSCACHE
+ bool "Provide NFS client caching support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ depends on NFS_FS=m && FSCACHE || NFS_FS=y && FSCACHE=y
+ help
+ Say Y here if you want NFS data to be cached locally on disc through
+ the general filesystem cache manager
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index ac6170c594a..845159814de 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -15,3 +15,4 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
callback.o callback_xdr.o callback_proc.o \
nfs4namespace.o
nfs-$(CONFIG_SYSCTL) += sysctl.o
+nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index aba38017bde..75c9cd2aa11 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -45,6 +45,7 @@
#include "delegation.h"
#include "iostat.h"
#include "internal.h"
+#include "fscache.h"
#define NFSDBG_FACILITY NFSDBG_CLIENT
@@ -154,6 +155,8 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
if (!IS_ERR(cred))
clp->cl_machine_cred = cred;
+ nfs_fscache_get_client_cookie(clp);
+
return clp;
error_3:
@@ -187,6 +190,8 @@ static void nfs_free_client(struct nfs_client *clp)
nfs4_shutdown_client(clp);
+ nfs_fscache_release_client_cookie(clp);
+
/* -EIO all pending I/O */
if (!IS_ERR(clp->cl_rpcclient))
rpc_shutdown_client(clp->cl_rpcclient);
@@ -760,6 +765,7 @@ static int nfs_init_server(struct nfs_server *server,
/* Initialise the client representation from the mount data */
server->flags = data->flags;
+ server->options = data->options;
if (data->rsize)
server->rsize = nfs_block_size(data->rsize, NULL);
@@ -1148,6 +1154,7 @@ static int nfs4_init_server(struct nfs_server *server,
/* Initialise the client representation from the mount data */
server->flags = data->flags;
server->caps |= NFS_CAP_ATOMIC_OPEN;
+ server->options = data->options;
/* Get a client record */
error = nfs4_set_client(server,
@@ -1559,7 +1566,7 @@ static int nfs_volume_list_show(struct seq_file *m, void *v)
/* display header on line 1 */
if (v == &nfs_volume_list) {
- seq_puts(m, "NV SERVER PORT DEV FSID\n");
+ seq_puts(m, "NV SERVER PORT DEV FSID FSC\n");
return 0;
}
/* display one transport per line on subsequent lines */
@@ -1573,12 +1580,13 @@ static int nfs_volume_list_show(struct seq_file *m, void *v)
(unsigned long long) server->fsid.major,
(unsigned long long) server->fsid.minor);
- seq_printf(m, "v%u %s %s %-7s %-17s\n",
+ seq_printf(m, "v%u %s %s %-7s %-17s %s\n",
clp->rpc_ops->version,
rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT),
dev,
- fsid);
+ fsid,
+ nfs_server_fscache_state(server));
return 0;
}
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 0abf3f331f5..5a97bcfe03e 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -35,6 +35,7 @@
#include "delegation.h"
#include "internal.h"
#include "iostat.h"
+#include "fscache.h"
#define NFSDBG_FACILITY NFSDBG_FILE
@@ -409,6 +410,13 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
return copied;
}
+/*
+ * Partially or wholly invalidate a page
+ * - Release the private state associated with a page if undergoing complete
+ * page invalidation
+ * - Called if either PG_private or PG_fscache is set on the page
+ * - Caller holds page lock
+ */
static void nfs_invalidate_page(struct page *page, unsigned long offset)
{
dfprintk(PAGECACHE, "NFS: invalidate_page(%p, %lu)\n", page, offset);
@@ -417,23 +425,43 @@ static void nfs_invalidate_page(struct page *page, unsigned long offset)
return;
/* Cancel any unstarted writes on this page */
nfs_wb_page_cancel(page->mapping->host, page);
+
+ nfs_fscache_invalidate_page(page, page->mapping->host);
}
+/*
+ * Attempt to release the private state associated with a page
+ * - Called if either PG_private or PG_fscache is set on the page
+ * - Caller holds page lock
+ * - Return true (may release page) or false (may not)
+ */
static int nfs_release_page(struct page *page, gfp_t gfp)
{
dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page);
/* If PagePrivate() is set, then the page is not freeable */
- return 0;
+ if (PagePrivate(page))
+ return 0;
+ return nfs_fscache_release_page(page, gfp);
}
+/*
+ * Attempt to clear the private state associated with a page when an error
+ * occurs that requires the cached contents of an inode to be written back or
+ * destroyed
+ * - Called if either PG_private or fscache is set on the page
+ * - Caller holds page lock
+ * - Return 0 if successful, -error otherwise
+ */
static int nfs_launder_page(struct page *page)
{
struct inode *inode = page->mapping->host;
+ struct nfs_inode *nfsi = NFS_I(inode);
dfprintk(PAGECACHE, "NFS: launder_page(%ld, %llu)\n",
inode->i_ino, (long long)page_offset(page));
+ nfs_fscache_wait_on_page_write(nfsi, page);
return nfs_wb_page(inode, page);
}
@@ -451,6 +479,11 @@ const struct address_space_operations nfs_file_aops = {
.launder_page = nfs_launder_page,
};
+/*
+ * Notification that a PTE pointing to an NFS page is about to be made
+ * writable, implying that someone is about to modify the page through a
+ * shared-writable mapping
+ */
static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct page *page = vmf->page;
@@ -465,6 +498,9 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
filp->f_mapping->host->i_ino,
(long long)page_offset(page));
+ /* make sure the cache has finished storing the page */
+ nfs_fscache_wait_on_page_write(NFS_I(dentry->d_inode), page);
+
lock_page(page);
mapping = page->mapping;
if (mapping != dentry->d_inode->i_mapping)
@@ -480,8 +516,6 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
goto out_unlock;
ret = nfs_updatepage(filp, page, 0, pagelen);
- if (ret == 0)
- ret = pagelen;
out_unlock:
unlock_page(page);
if (ret)
diff --git a/fs/nfs/fscache-index.c b/fs/nfs/fscache-index.c
new file mode 100644
index 00000000000..5b1006480bc
--- /dev/null
+++ b/fs/nfs/fscache-index.c
@@ -0,0 +1,337 @@
+/* NFS FS-Cache index structure definition
+ *
+ * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/nfs_fs.h>
+#include <linux/nfs_fs_sb.h>
+#include <linux/in6.h>
+
+#include "internal.h"
+#include "fscache.h"
+
+#define NFSDBG_FACILITY NFSDBG_FSCACHE
+
+/*
+ * Define the NFS filesystem for FS-Cache. Upon registration FS-Cache sticks
+ * the cookie for the top-level index object for NFS into here. The top-level
+ * index can than have other cache objects inserted into it.
+ */
+struct fscache_netfs nfs_fscache_netfs = {
+ .name = "nfs",
+ .version = 0,
+};
+
+/*
+ * Register NFS for caching
+ */
+int nfs_fscache_register(void)
+{
+ return fscache_register_netfs(&nfs_fscache_netfs);
+}
+
+/*
+ * Unregister NFS for caching
+ */
+void nfs_fscache_unregister(void)
+{
+ fscache_unregister_netfs(&nfs_fscache_netfs);
+}
+
+/*
+ * Layout of the key for an NFS server cache object.
+ */
+struct nfs_server_key {
+ uint16_t nfsversion; /* NFS protocol version */
+ uint16_t family; /* address family */
+ uint16_t port; /* IP port */
+ union {
+ struct in_addr ipv4_addr; /* IPv4 address */
+ struct in6_addr ipv6_addr; /* IPv6 address */
+ } addr[0];
+};
+
+/*
+ * Generate a key to describe a server in the main NFS index
+ * - We return the length of the key, or 0 if we can't generate one
+ */
+static uint16_t nfs_server_get_key(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax)
+{
+ const struct nfs_client *clp = cookie_netfs_data;
+ const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &clp->cl_addr;
+ const struct sockaddr_in *sin = (struct sockaddr_in *) &clp->cl_addr;
+ struct nfs_server_key *key = buffer;
+ uint16_t len = sizeof(struct nfs_server_key);
+
+ key->nfsversion = clp->rpc_ops->version;
+ key->family = clp->cl_addr.ss_family;
+
+ memset(key, 0, len);
+
+ switch (clp->cl_addr.ss_family) {
+ case AF_INET:
+ key->port = sin->sin_port;
+ key->addr[0].ipv4_addr = sin->sin_addr;
+ len += sizeof(key->addr[0].ipv4_addr);
+ break;
+
+ case AF_INET6:
+ key->port = sin6->sin6_port;
+ key->addr[0].ipv6_addr = sin6->sin6_addr;
+ len += sizeof(key->addr[0].ipv6_addr);
+ break;
+
+ default:
+ printk(KERN_WARNING "NFS: Unknown network family '%d'\n",
+ clp->cl_addr.ss_family);
+ len = 0;
+ break;
+ }
+
+ return len;
+}
+
+/*
+ * Define the server object for FS-Cache. This is used to describe a server
+ * object to fscache_acquire_cookie(). It is keyed by the NFS protocol and
+ * server address parameters.
+ */
+const struct fscache_cookie_def nfs_fscache_server_index_def = {
+ .name = "NFS.server",
+ .type = FSCACHE_COOKIE_TYPE_INDEX,
+ .get_key = nfs_server_get_key,
+};
+
+/*
+ * Generate a key to describe a superblock key in the main NFS index
+ */
+static uint16_t nfs_super_get_key(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax)
+{
+ const struct nfs_fscache_key *key;
+ const struct nfs_server *nfss = cookie_netfs_data;
+ uint16_t len;
+
+ key = nfss->fscache_key;
+ len = sizeof(key->key) + key->key.uniq_len;
+ if (len > bufmax) {
+ len = 0;
+ } else {
+ memcpy(buffer, &key->key, sizeof(key->key));
+ memcpy(buffer + sizeof(key->key),
+ key->key.uniquifier, key->key.uniq_len);
+ }
+
+ return len;
+}
+
+/*
+ * Define the superblock object for FS-Cache. This is used to describe a
+ * superblock object to fscache_acquire_cookie(). It is keyed by all the NFS
+ * parameters that might cause a separate superblock.
+ */
+const struct fscache_cookie_def nfs_fscache_super_index_def = {
+ .name = "NFS.super",
+ .type = FSCACHE_COOKIE_TYPE_INDEX,
+ .get_key = nfs_super_get_key,
+};
+
+/*
+ * Definition of the auxiliary data attached to NFS inode storage objects
+ * within the cache.
+ *
+ * The contents of this struct are recorded in the on-disk local cache in the
+ * auxiliary data attached to the data storage object backing an inode. This
+ * permits coherency to be managed when a new inode binds to an already extant
+ * cache object.
+ */
+struct nfs_fscache_inode_auxdata {
+ struct timespec mtime;
+ struct timespec ctime;
+ loff_t size;
+ u64 change_attr;
+};
+
+/*
+ * Generate a key to describe an NFS inode in an NFS server's index
+ */
+static uint16_t nfs_fscache_inode_get_key(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax)
+{
+ const struct nfs_inode *nfsi = cookie_netfs_data;
+ uint16_t nsize;
+
+ /* use the inode's NFS filehandle as the key */
+ nsize = nfsi->fh.size;
+ memcpy(buffer, nfsi->fh.data, nsize);
+ return nsize;
+}
+
+/*
+ * Get certain file attributes from the netfs data
+ * - This function can be absent for an index
+ * - Not permitted to return an error
+ * - The netfs data from the cookie being used as the source is presented
+ */
+static void nfs_fscache_inode_get_attr(const void *cookie_netfs_data,
+ uint64_t *size)
+{
+ const struct nfs_inode *nfsi = cookie_netfs_data;
+
+ *size = nfsi->vfs_inode.i_size;
+}
+
+/*
+ * Get the auxiliary data from netfs data
+ * - This function can be absent if the index carries no state data
+ * - Should store the auxiliary data in the buffer
+ * - Should return the amount of amount stored
+ * - Not permitted to return an error
+ * - The netfs data from the cookie being used as the source is presented
+ */
+static uint16_t nfs_fscache_inode_get_aux(const void *cookie_netfs_data,
+ void *buffer, uint16_t bufmax)
+{
+ struct nfs_fscache_inode_auxdata auxdata;
+ const struct nfs_inode *nfsi = cookie_netfs_data;
+
+ memset(&auxdata, 0, sizeof(auxdata));
+ auxdata.size = nfsi->vfs_inode.i_size;
+ auxdata.mtime = nfsi->vfs_inode.i_mtime;
+ auxdata.ctime = nfsi->vfs_inode.i_ctime;
+
+ if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
+ auxdata.change_attr = nfsi->change_attr;
+
+ if (bufmax > sizeof(auxdata))
+ bufmax = sizeof(auxdata);
+
+ memcpy(buffer, &auxdata, bufmax);
+ return bufmax;
+}
+
+/*
+ * Consult the netfs about the state of an object
+ * - This function can be absent if the index carries no state data
+ * - The netfs data from the cookie being used as the target is
+ * presented, as is the auxiliary data
+ */
+static
+enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data,
+ const void *data,
+ uint16_t datalen)
+{
+ struct nfs_fscache_inode_auxdata auxdata;
+ struct nfs_inode *nfsi = cookie_netfs_data;
+
+ if (datalen != sizeof(auxdata))
+ return FSCACHE_CHECKAUX_OBSOLETE;
+
+ memset(&auxdata, 0, sizeof(auxdata));
+ auxdata.size = nfsi->vfs_inode.i_size;
+ auxdata.mtime = nfsi->vfs_inode.i_mtime;
+ auxdata.ctime = nfsi->vfs_inode.i_ctime;
+
+ if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
+ auxdata.change_attr = nfsi->change_attr;
+
+ if (memcmp(data, &auxdata, datalen) != 0)
+ return FSCACHE_CHECKAUX_OBSOLETE;
+
+ return FSCACHE_CHECKAUX_OKAY;
+}
+
+/*
+ * Indication from FS-Cache that the cookie is no longer cached
+ * - This function is called when the backing store currently caching a cookie
+ * is removed
+ * - The netfs should use this to clean up any markers indicating cached pages
+ * - This is mandatory for any object that may have data
+ */
+static void nfs_fscache_inode_now_uncached(void *cookie_netfs_data)
+{
+ struct nfs_inode *nfsi = cookie_netfs_data;
+ struct pagevec pvec;
+ pgoff_t first;
+ int loop, nr_pages;
+
+ pagevec_init(&pvec, 0);
+ first = 0;
+
+ dprintk("NFS: nfs_inode_now_uncached: nfs_inode 0x%p\n", nfsi);
+
+ for (;;) {
+ /* grab a bunch of pages to unmark */
+ nr_pages = pagevec_lookup(&pvec,
+ nfsi->vfs_inode.i_mapping,
+ first,
+ PAGEVEC_SIZE - pagevec_count(&pvec));
+ if (!nr_pages)
+ break;
+
+ for (loop = 0; loop < nr_pages; loop++)
+ ClearPageFsCache(pvec.pages[loop]);
+
+ first = pvec.pages[nr_pages - 1]->index + 1;
+
+ pvec.nr = nr_pages;
+ pagevec_release(&pvec);
+ cond_resched();
+ }
+}
+
+/*
+ * Get an extra reference on a read context.
+ * - This function can be absent if the completion function doesn't require a
+ * context.
+ * - The read context is passed back to NFS in the event that a data read on the
+ * cache fails with EIO - in which case the server must be contacted to
+ * retrieve the data, which requires the read context for security.
+ */
+static void nfs_fh_get_context(void *cookie_netfs_data, void *context)
+{
+ get_nfs_open_context(context);
+}
+
+/*
+ * Release an extra reference on a read context.
+ * - This function can be absent if the completion function doesn't require a
+ * context.
+ */
+static void nfs_fh_put_context(void *cookie_netfs_data, void *context)
+{
+ if (context)
+ put_nfs_open_context(context);
+}
+
+/*
+ * Define the inode object for FS-Cache. This is used to describe an inode
+ * object to fscache_acquire_cookie(). It is keyed by the NFS file handle for
+ * an inode.
+ *
+ * Coherency is managed by comparing the copies of i_size, i_mtime and i_ctime
+ * held in the cache auxiliary data for the data storage object with those in
+ * the inode struct in memory.
+ */
+const struct fscache_cookie_def nfs_fscache_inode_object_def = {
+ .name = "NFS.fh",
+ .type = FSCACHE_COOKIE_TYPE_DATAFILE,
+ .get_key = nfs_fscache_inode_get_key,
+ .get_attr = nfs_fscache_inode_get_attr,
+ .get_aux = nfs_fscache_inode_get_aux,
+ .check_aux = nfs_fscache_inode_check_aux,
+ .now_uncached = nfs_fscache_inode_now_uncached,
+ .get_context = nfs_fh_get_context,
+ .put_context = nfs_fh_put_context,
+};
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
new file mode 100644
index 00000000000..379be678cb7
--- /dev/null
+++ b/fs/nfs/fscache.c
@@ -0,0 +1,523 @@
+/* NFS filesystem cache interface
+ *
+ * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/nfs_fs.h>
+#include <linux/nfs_fs_sb.h>
+#include <linux/in6.h>
+#include <linux/seq_file.h>
+
+#include "internal.h"
+#include "iostat.h"
+#include "fscache.h"
+
+#define NFSDBG_FACILITY NFSDBG_FSCACHE
+
+static struct rb_root nfs_fscache_keys = RB_ROOT;
+static DEFINE_SPINLOCK(nfs_fscache_keys_lock);
+
+/*
+ * Get the per-client index cookie for an NFS client if the appropriate mount
+ * flag was set
+ * - We always try and get an index cookie for the client, but get filehandle
+ * cookies on a per-superblock basis, depending on the mount flags
+ */
+void nfs_fscache_get_client_cookie(struct nfs_client *clp)
+{
+ /* create a cache index for looking up filehandles */
+ clp->fscache = fscache_acquire_cookie(nfs_fscache_netfs.primary_index,
+ &nfs_fscache_server_index_def,
+ clp);
+ dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n",
+ clp, clp->fscache);
+}
+
+/*
+ * Dispose of a per-client cookie
+ */
+void nfs_fscache_release_client_cookie(struct nfs_client *clp)
+{
+ dfprintk(FSCACHE, "NFS: releasing client cookie (0x%p/0x%p)\n",
+ clp, clp->fscache);
+
+ fscache_relinquish_cookie(clp->fscache, 0);
+ clp->fscache = NULL;
+}
+
+/*
+ * Get the cache cookie for an NFS superblock. We have to handle
+ * uniquification here because the cache doesn't do it for us.
+ */
+void nfs_fscache_get_super_cookie(struct super_block *sb,
+ struct nfs_parsed_mount_data *data)
+{
+ struct nfs_fscache_key *key, *xkey;
+ struct nfs_server *nfss = NFS_SB(sb);
+ struct rb_node **p, *parent;
+ const char *uniq = data->fscache_uniq ?: "";
+ int diff, ulen;
+
+ ulen = strlen(uniq);
+ key = kzalloc(sizeof(*key) + ulen, GFP_KERNEL);
+ if (!key)
+ return;
+
+ key->nfs_client = nfss->nfs_client;
+ key->key.super.s_flags = sb->s_flags & NFS_MS_MASK;
+ key->key.nfs_server.flags = nfss->flags;
+ key->key.nfs_server.rsize = nfss->rsize;
+ key->key.nfs_server.wsize = nfss->wsize;
+ key->key.nfs_server.acregmin = nfss->acregmin;
+ key->key.nfs_server.acregmax = nfss->acregmax;
+ key->key.nfs_server.acdirmin = nfss->acdirmin;
+ key->key.nfs_server.acdirmax = nfss->acdirmax;
+ key->key.nfs_server.fsid = nfss->fsid;
+ key->key.rpc_auth.au_flavor = nfss->client->cl_auth->au_flavor;
+
+ key->key.uniq_len = ulen;
+ memcpy(key->key.uniquifier, uniq, ulen);
+
+ spin_lock(&nfs_fscache_keys_lock);
+ p = &nfs_fscache_keys.rb_node;
+ parent = NULL;
+ while (*p) {
+ parent = *p;
+ xkey = rb_entry(parent, struct nfs_fscache_key, node);
+
+ if (key->nfs_client < xkey->nfs_client)
+ goto go_left;
+ if (key->nfs_client > xkey->nfs_client)
+ goto go_right;
+
+ diff = memcmp(&key->key, &xkey->key, sizeof(key->key));
+ if (diff < 0)
+ goto go_left;
+ if (diff > 0)
+ goto go_right;
+
+ if (key->key.uniq_len == 0)
+ goto non_unique;
+ diff = memcmp(key->key.uniquifier,
+ xkey->key.uniquifier,
+ key->key.uniq_len);
+ if (diff < 0)
+ goto go_left;
+ if (diff > 0)
+ goto go_right;
+ goto non_unique;
+
+ go_left:
+ p = &(*p)->rb_left;
+ continue;
+ go_right:
+ p = &(*p)->rb_right;
+ }
+
+ rb_link_node(&key->node, parent, p);
+ rb_insert_color(&key->node, &nfs_fscache_keys);
+ spin_unlock(&nfs_fscache_keys_lock);
+ nfss->fscache_key = key;
+
+ /* create a cache index for looking up filehandles */
+ nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache,
+ &nfs_fscache_super_index_def,
+ nfss);
+ dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n",
+ nfss, nfss->fscache);
+ return;
+
+non_unique:
+ spin_unlock(&nfs_fscache_keys_lock);
+ kfree(key);
+ nfss->fscache_key = NULL;
+ nfss->fscache = NULL;
+ printk(KERN_WARNING "NFS:"
+ " Cache request denied due to non-unique superblock keys\n");
+}
+
+/*
+ * release a per-superblock cookie
+ */
+void nfs_fscache_release_super_cookie(struct super_block *sb)
+{
+ struct nfs_server *nfss = NFS_SB(sb);
+
+ dfprintk(FSCACHE, "NFS: releasing superblock cookie (0x%p/0x%p)\n",
+ nfss, nfss->fscache);
+
+ fscache_relinquish_cookie(nfss->fscache, 0);
+ nfss->fscache = NULL;
+
+ if (nfss->fscache_key) {
+ spin_lock(&nfs_fscache_keys_lock);
+ rb_erase(&nfss->fscache_key->node, &nfs_fscache_keys);
+ spin_unlock(&nfs_fscache_keys_lock);
+ kfree(nfss->fscache_key);
+ nfss->fscache_key = NULL;
+ }
+}
+
+/*
+ * Initialise the per-inode cache cookie pointer for an NFS inode.
+ */
+void nfs_fscache_init_inode_cookie(struct inode *inode)
+{
+ NFS_I(inode)->fscache = NULL;
+ if (S_ISREG(inode->i_mode))
+ set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
+}
+
+/*
+ * Get the per-inode cache cookie for an NFS inode.
+ */
+static void nfs_fscache_enable_inode_cookie(struct inode *inode)
+{
+ struct super_block *sb = inode->i_sb;
+ struct nfs_inode *nfsi = NFS_I(inode);
+
+ if (nfsi->fscache || !NFS_FSCACHE(inode))
+ return;
+
+ if ((NFS_SB(sb)->options & NFS_OPTION_FSCACHE)) {
+ nfsi->fscache = fscache_acquire_cookie(
+ NFS_SB(sb)->fscache,
+ &nfs_fscache_inode_object_def,
+ nfsi);
+
+ dfprintk(FSCACHE, "NFS: get FH cookie (0x%p/0x%p/0x%p)\n",
+ sb, nfsi, nfsi->fscache);
+ }
+}
+
+/*
+ * Release a per-inode cookie.
+ */
+void nfs_fscache_release_inode_cookie(struct inode *inode)
+{
+ struct nfs_inode *nfsi = NFS_I(inode);
+
+ dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n",
+ nfsi, nfsi->fscache);
+
+ fscache_relinquish_cookie(nfsi->fscache, 0);
+ nfsi->fscache = NULL;
+}
+
+/*
+ * Retire a per-inode cookie, destroying the data attached to it.
+ */
+void nfs_fscache_zap_inode_cookie(struct inode *inode)
+{
+ struct nfs_inode *nfsi = NFS_I(inode);
+
+ dfprintk(FSCACHE, "NFS: zapping cookie (0x%p/0x%p)\n",
+ nfsi, nfsi->fscache);
+
+ fscache_relinquish_cookie(nfsi->fscache, 1);
+ nfsi->fscache = NULL;
+}
+
+/*
+ * Turn off the cache with regard to a per-inode cookie if opened for writing,
+ * invalidating all the pages in the page cache relating to the associated
+ * inode to clear the per-page caching.
+ */
+static void nfs_fscache_disable_inode_cookie(struct inode *inode)
+{
+ clear_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
+
+ if (NFS_I(inode)->fscache) {
+ dfprintk(FSCACHE,
+ "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode));
+
+ /* Need to invalidate any mapped pages that were read in before
+ * turning off the cache.
+ */
+ if (inode->i_mapping && inode->i_mapping->nrpages)
+ invalidate_inode_pages2(inode->i_mapping);
+
+ nfs_fscache_zap_inode_cookie(inode);
+ }
+}
+
+/*
+ * wait_on_bit() sleep function for uninterruptible waiting
+ */
+static int nfs_fscache_wait_bit(void *flags)
+{
+ schedule();
+ return 0;
+}
+
+/*
+ * Lock against someone else trying to also acquire or relinquish a cookie
+ */
+static inline void nfs_fscache_inode_lock(struct inode *inode)
+{
+ struct nfs_inode *nfsi = NFS_I(inode);
+
+ while (test_and_set_bit(NFS_INO_FSCACHE_LOCK, &nfsi->flags))
+ wait_on_bit(&nfsi->flags, NFS_INO_FSCACHE_LOCK,
+ nfs_fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+}
+
+/*
+ * Unlock cookie management lock
+ */
+static inline void nfs_fscache_inode_unlock(struct inode *inode)
+{
+ struct nfs_inode *nfsi = NFS_I(inode);
+
+ smp_mb__before_clear_bit();
+ clear_bit(NFS_INO_FSCACHE_LOCK, &nfsi->flags);
+ smp_mb__after_clear_bit();
+ wake_up_bit(&nfsi->flags, NFS_INO_FSCACHE_LOCK);
+}
+
+/*
+ * Decide if we should enable or disable local caching for this inode.
+ * - For now, with NFS, only regular files that are open read-only will be able
+ * to use the cache.
+ * - May be invoked multiple times in parallel by parallel nfs_open() functions.
+ */
+void nfs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
+{
+ if (NFS_FSCACHE(inode)) {
+ nfs_fscache_inode_lock(inode);
+ if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
+ nfs_fscache_disable_inode_cookie(inode);
+ else
+ nfs_fscache_enable_inode_cookie(inode);
+ nfs_fscache_inode_unlock(inode);
+ }
+}
+
+/*
+ * Replace a per-inode cookie due to revalidation detecting a file having
+ * changed on the server.
+ */
+void nfs_fscache_reset_inode_cookie(struct inode *inode)
+{
+ struct nfs_inode *nfsi = NFS_I(inode);
+ struct nfs_server *nfss = NFS_SERVER(inode);
+ struct fscache_cookie *old = nfsi->fscache;
+
+ nfs_fscache_inode_lock(inode);
+ if (nfsi->fscache) {
+ /* retire the current fscache cache and get a new one */
+ fscache_relinquish_cookie(nfsi->fscache, 1);
+
+ nfsi->fscache = fscache_acquire_cookie(
+ nfss->nfs_client->fscache,
+ &nfs_fscache_inode_object_def,
+ nfsi);
+
+ dfprintk(FSCACHE,
+ "NFS: revalidation new cookie (0x%p/0x%p/0x%p/0x%p)\n",
+ nfss, nfsi, old, nfsi->fscache);
+ }
+ nfs_fscache_inode_unlock(inode);
+}
+
+/*
+ * Release the caching state associated with a page, if the page isn't busy
+ * interacting with the cache.
+ * - Returns true (can release page) or false (page busy).
+ */
+int nfs_fscache_release_page(struct page *page, gfp_t gfp)
+{
+ struct nfs_inode *nfsi = NFS_I(page->mapping->host);
+ struct fscache_cookie *cookie = nfsi->fscache;
+
+ BUG_ON(!cookie);
+
+ if (fscache_check_page_write(cookie, page)) {
+ if (!(gfp & __GFP_WAIT))
+ return 0;
+ fscache_wait_on_page_write(cookie, page);
+ }
+
+ if (PageFsCache(page)) {
+ dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n",
+ cookie, page, nfsi);
+
+ fscache_uncache_page(cookie, page);
+ nfs_add_fscache_stats(page->mapping->host,
+ NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
+ }
+
+ return 1;
+}
+
+/*
+ * Release the caching state associated with a page if undergoing complete page
+ * invalidation.
+ */
+void __nfs_fscache_invalidate_page(struct page *page, struct inode *inode)
+{
+ struct nfs_inode *nfsi = NFS_I(inode);
+ struct fscache_cookie *cookie = nfsi->fscache;
+
+ BUG_ON(!cookie);
+
+ dfprintk(FSCACHE, "NFS: fscache invalidatepage (0x%p/0x%p/0x%p)\n",
+ cookie, page, nfsi);
+
+ fscache_wait_on_page_write(cookie, page);
+
+ BUG_ON(!PageLocked(page));
+ fscache_uncache_page(cookie, page);
+ nfs_add_fscache_stats(page->mapping->host,
+ NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
+}
+
+/*
+ * Handle completion of a page being read from the cache.
+ * - Called in process (keventd) context.
+ */
+static void nfs_readpage_from_fscache_complete(struct page *page,
+ void *context,
+ int error)
+{
+ dfprintk(FSCACHE,
+ "NFS: readpage_from_fscache_complete (0x%p/0x%p/%d)\n",
+ page, context, error);
+
+ /* if the read completes with an error, we just unlock the page and let
+ * the VM reissue the readpage */
+ if (!error) {
+ SetPageUptodate(page);
+ unlock_page(page);
+ } else {
+ error = nfs_readpage_async(context, page->mapping->host, page);
+ if (error)
+ unlock_page(page);
+ }
+}
+
+/*
+ * Retrieve a page from fscache
+ */
+int __nfs_readpage_from_fscache(struct nfs_open_context *ctx,
+ struct inode *inode, struct page *page)
+{
+ int ret;
+
+ dfprintk(FSCACHE,
+ "NFS: readpage_from_fscache(fsc:%p/p:%p(i:%lx f:%lx)/0x%p)\n",
+ NFS_I(inode)->fscache, page, page->index, page->flags, inode);
+
+ ret = fscache_read_or_alloc_page(NFS_I(inode)->fscache,
+ page,
+ nfs_readpage_from_fscache_complete,
+ ctx,
+ GFP_KERNEL);
+
+ switch (ret) {
+ case 0: /* read BIO submitted (page in fscache) */
+ dfprintk(FSCACHE,
+ "NFS: readpage_from_fscache: BIO submitted\n");
+ nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_OK, 1);
+ return ret;
+
+ case -ENOBUFS: /* inode not in cache */
+ case -ENODATA: /* page not in cache */
+ nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL, 1);
+ dfprintk(FSCACHE,
+ "NFS: readpage_from_fscache %d\n", ret);
+ return 1;
+
+ default:
+ dfprintk(FSCACHE, "NFS: readpage_from_fscache %d\n", ret);
+ nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL, 1);
+ }
+ return ret;
+}
+
+/*
+ * Retrieve a set of pages from fscache
+ */
+int __nfs_readpages_from_fscache(struct nfs_open_context *ctx,
+ struct inode *inode,
+ struct address_space *mapping,
+ struct list_head *pages,
+ unsigned *nr_pages)
+{
+ int ret, npages = *nr_pages;
+
+ dfprintk(FSCACHE, "NFS: nfs_getpages_from_fscache (0x%p/%u/0x%p)\n",
+ NFS_I(inode)->fscache, npages, inode);
+
+ ret = fscache_read_or_alloc_pages(NFS_I(inode)->fscache,
+ mapping, pages, nr_pages,
+ nfs_readpage_from_fscache_complete,
+ ctx,
+ mapping_gfp_mask(mapping));
+ if (*nr_pages < npages)
+ nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_OK,
+ npages);
+ if (*nr_pages > 0)
+ nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL,
+ *nr_pages);
+
+ switch (ret) {
+ case 0: /* read submitted to the cache for all pages */
+ BUG_ON(!list_empty(pages));
+ BUG_ON(*nr_pages != 0);
+ dfprintk(FSCACHE,
+ "NFS: nfs_getpages_from_fscache: submitted\n");
+
+ return ret;
+
+ case -ENOBUFS: /* some pages aren't cached and can't be */
+ case -ENODATA: /* some pages aren't cached */
+ dfprintk(FSCACHE,
+ "NFS: nfs_getpages_from_fscache: no page: %d\n", ret);
+ return 1;
+
+ default:
+ dfprintk(FSCACHE,
+ "NFS: nfs_getpages_from_fscache: ret %d\n", ret);
+ }
+
+ return ret;
+}
+
+/*
+ * Store a newly fetched page in fscache
+ * - PG_fscache must be set on the page
+ */
+void __nfs_readpage_to_fscache(struct inode *inode, struct page *page, int sync)
+{
+ int ret;
+
+ dfprintk(FSCACHE,
+ "NFS: readpage_to_fscache(fsc:%p/p:%p(i:%lx f:%lx)/%d)\n",
+ NFS_I(inode)->fscache, page, page->index, page->flags, sync);
+
+ ret = fscache_write_page(NFS_I(inode)->fscache, page, GFP_KERNEL);
+ dfprintk(FSCACHE,
+ "NFS: readpage_to_fscache: p:%p(i:%lu f:%lx) ret %d\n",
+ page, page->index, page->flags, ret);
+
+ if (ret != 0) {
+ fscache_uncache_page(NFS_I(inode)->fscache, page);
+ nfs_add_fscache_stats(inode,
+ NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL, 1);
+ nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
+ } else {
+ nfs_add_fscache_stats(inode,
+ NFSIOS_FSCACHE_PAGES_WRITTEN_OK, 1);
+ }
+}
diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h
new file mode 100644
index 00000000000..6e809bb0ff0
--- /dev/null
+++ b/fs/nfs/fscache.h
@@ -0,0 +1,220 @@
+/* NFS filesystem cache interface definitions
+ *
+ * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _NFS_FSCACHE_H
+#define _NFS_FSCACHE_H
+
+#include <linux/nfs_fs.h>
+#include <linux/nfs_mount.h>
+#include <linux/nfs4_mount.h>
+#include <linux/fscache.h>
+
+#ifdef CONFIG_NFS_FSCACHE
+
+/*
+ * set of NFS FS-Cache objects that form a superblock key
+ */
+struct nfs_fscache_key {
+ struct rb_node node;
+ struct nfs_client *nfs_client; /* the server */
+
+ /* the elements of the unique key - as used by nfs_compare_super() and
+ * nfs_compare_mount_options() to distinguish superblocks */
+ struct {
+ struct {
+ unsigned long s_flags; /* various flags
+ * (& NFS_MS_MASK) */
+ } super;
+
+ struct {
+ struct nfs_fsid fsid;
+ int flags;
+ unsigned int rsize; /* read size */
+ unsigned int wsize; /* write size */
+ unsigned int acregmin; /* attr cache timeouts */
+ unsigned int acregmax;
+ unsigned int acdirmin;
+ unsigned int acdirmax;
+ } nfs_server;
+
+ struct {
+ rpc_authflavor_t au_flavor;
+ } rpc_auth;
+
+ /* uniquifier - can be used if nfs_server.flags includes
+ * NFS_MOUNT_UNSHARED */
+ u8 uniq_len;
+ char uniquifier[0];
+ } key;
+};
+
+/*
+ * fscache-index.c
+ */
+extern struct fscache_netfs nfs_fscache_netfs;
+extern const struct fscache_cookie_def nfs_fscache_server_index_def;
+extern const struct fscache_cookie_def nfs_fscache_super_index_def;
+extern const struct fscache_cookie_def nfs_fscache_inode_object_def;
+
+extern int nfs_fscache_register(void);
+extern void nfs_fscache_unregister(void);
+
+/*
+ * fscache.c
+ */
+extern void nfs_fscache_get_client_cookie(struct nfs_client *);
+extern void nfs_fscache_release_client_cookie(struct nfs_client *);
+
+extern void nfs_fscache_get_super_cookie(struct super_block *,
+ struct nfs_parsed_mount_data *);
+extern void nfs_fscache_release_super_cookie(struct super_block *);
+
+extern void nfs_fscache_init_inode_cookie(struct inode *);
+extern void nfs_fscache_release_inode_cookie(struct inode *);
+extern void nfs_fscache_zap_inode_cookie(struct inode *);
+extern void nfs_fscache_set_inode_cookie(struct inode *, struct file *);
+extern void nfs_fscache_reset_inode_cookie(struct inode *);
+
+extern void __nfs_fscache_invalidate_page(struct page *, struct inode *);
+extern int nfs_fscache_release_page(struct page *, gfp_t);
+
+extern int __nfs_readpage_from_fscache(struct nfs_open_context *,
+ struct inode *, struct page *);
+extern int __nfs_readpages_from_fscache(struct nfs_open_context *,
+ struct inode *, struct address_space *,
+ struct list_head *, unsigned *);
+extern void __nfs_readpage_to_fscache(struct inode *, struct page *, int);
+
+/*
+ * wait for a page to complete writing to the cache
+ */
+static inline void nfs_fscache_wait_on_page_write(struct nfs_inode *nfsi,
+ struct page *page)
+{
+ if (PageFsCache(page))
+ fscache_wait_on_page_write(nfsi->fscache, page);
+}
+
+/*
+ * release the caching state associated with a page if undergoing complete page
+ * invalidation
+ */
+static inline void nfs_fscache_invalidate_page(struct page *page,
+ struct inode *inode)
+{
+ if (PageFsCache(page))
+ __nfs_fscache_invalidate_page(page, inode);
+}
+
+/*
+ * Retrieve a page from an inode data storage object.
+ */
+static inline int nfs_readpage_from_fscache(struct nfs_open_context *ctx,
+ struct inode *inode,
+ struct page *page)
+{
+ if (NFS_I(inode)->fscache)
+ return __nfs_readpage_from_fscache(ctx, inode, page);
+ return -ENOBUFS;
+}
+
+/*
+ * Retrieve a set of pages from an inode data storage object.
+ */
+static inline int nfs_readpages_from_fscache(struct nfs_open_context *ctx,
+ struct inode *inode,
+ struct address_space *mapping,
+ struct list_head *pages,
+ unsigned *nr_pages)
+{
+ if (NFS_I(inode)->fscache)
+ return __nfs_readpages_from_fscache(ctx, inode, mapping, pages,
+ nr_pages);
+ return -ENOBUFS;
+}
+
+/*
+ * Store a page newly fetched from the server in an inode data storage object
+ * in the cache.
+ */
+static inline void nfs_readpage_to_fscache(struct inode *inode,
+ struct page *page,
+ int sync)
+{
+ if (PageFsCache(page))
+ __nfs_readpage_to_fscache(inode, page, sync);
+}
+
+/*
+ * indicate the client caching state as readable text
+ */
+static inline const char *nfs_server_fscache_state(struct nfs_server *server)
+{
+ if (server->fscache && (server->options & NFS_OPTION_FSCACHE))
+ return "yes";
+ return "no ";
+}
+
+
+#else /* CONFIG_NFS_FSCACHE */
+static inline int nfs_fscache_register(void) { return 0; }
+static inline void nfs_fscache_unregister(void) {}
+
+static inline void nfs_fscache_get_client_cookie(struct nfs_client *clp) {}
+static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {}
+
+static inline void nfs_fscache_get_super_cookie(
+ struct super_block *sb,
+ struct nfs_parsed_mount_data *data)
+{
+}
+static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {}
+
+static inline void nfs_fscache_init_inode_cookie(struct inode *inode) {}
+static inline void nfs_fscache_release_inode_cookie(struct inode *inode) {}
+static inline void nfs_fscache_zap_inode_cookie(struct inode *inode) {}
+static inline void nfs_fscache_set_inode_cookie(struct inode *inode,
+ struct file *filp) {}
+static inline void nfs_fscache_reset_inode_cookie(struct inode *inode) {}
+
+static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp)
+{
+ return 1; /* True: may release page */
+}
+static inline void nfs_fscache_invalidate_page(struct page *page,
+ struct inode *inode) {}
+static inline void nfs_fscache_wait_on_page_write(struct nfs_inode *nfsi,
+ struct page *page) {}
+
+static inline int nfs_readpage_from_fscache(struct nfs_open_context *ctx,
+ struct inode *inode,
+ struct page *page)
+{
+ return -ENOBUFS;
+}
+static inline int nfs_readpages_from_fscache(struct nfs_open_context *ctx,
+ struct inode *inode,
+ struct address_space *mapping,
+ struct list_head *pages,
+ unsigned *nr_pages)
+{
+ return -ENOBUFS;
+}
+static inline void nfs_readpage_to_fscache(struct inode *inode,
+ struct page *page, int sync) {}
+
+static inline const char *nfs_server_fscache_state(struct nfs_server *server)
+{
+ return "no ";
+}
+
+#endif /* CONFIG_NFS_FSCACHE */
+#endif /* _NFS_FSCACHE_H */
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index a834d1d850b..64f87194d39 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -46,6 +46,7 @@
#include "delegation.h"
#include "iostat.h"
#include "internal.h"
+#include "fscache.h"
#define NFSDBG_FACILITY NFSDBG_VFS
@@ -121,6 +122,7 @@ void nfs_clear_inode(struct inode *inode)
BUG_ON(!list_empty(&NFS_I(inode)->open_files));
nfs_zap_acl_cache(inode);
nfs_access_zap_cache(inode);
+ nfs_fscache_release_inode_cookie(inode);
}
/**
@@ -355,6 +357,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
nfsi->attrtimeo_timestamp = now;
nfsi->access_cache = RB_ROOT;
+ nfs_fscache_init_inode_cookie(inode);
+
unlock_new_inode(inode);
} else
nfs_refresh_inode(inode, fattr);
@@ -686,6 +690,7 @@ int nfs_open(struct inode *inode, struct file *filp)
ctx->mode = filp->f_mode;
nfs_file_set_open_context(filp, ctx);
put_nfs_open_context(ctx);
+ nfs_fscache_set_inode_cookie(inode, filp);
return 0;
}
@@ -786,6 +791,7 @@ static int nfs_invalidate_mapping_nolock(struct inode *inode, struct address_spa
memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
spin_unlock(&inode->i_lock);
nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
+ nfs_fscache_reset_inode_cookie(inode);
dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
inode->i_sb->s_id, (long long)NFS_FILEID(inode));
return 0;
@@ -1030,6 +1036,7 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
spin_lock(&inode->i_lock);
status = nfs_refresh_inode_locked(inode, fattr);
spin_unlock(&inode->i_lock);
+
return status;
}
@@ -1436,6 +1443,10 @@ static int __init init_nfs_fs(void)
{
int err;
+ err = nfs_fscache_register();
+ if (err < 0)
+ goto out7;
+
err = nfsiod_start();
if (err)
goto out6;
@@ -1488,6 +1499,8 @@ out4:
out5:
nfsiod_stop();
out6:
+ nfs_fscache_unregister();
+out7:
return err;
}
@@ -1498,6 +1511,7 @@ static void __exit exit_nfs_fs(void)
nfs_destroy_readpagecache();
nfs_destroy_inodecache();
nfs_destroy_nfspagecache();
+ nfs_fscache_unregister();
#ifdef CONFIG_PROC_FS
rpc_proc_unregister("nfs");
#endif
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 2041f68ff1c..e4d6a8348ad 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -5,6 +5,8 @@
#include <linux/mount.h>
#include <linux/security.h>
+#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
+
struct nfs_string;
/* Maximum number of readahead requests
@@ -37,10 +39,12 @@ struct nfs_parsed_mount_data {
int acregmin, acregmax,
acdirmin, acdirmax;
int namlen;
+ unsigned int options;
unsigned int bsize;
unsigned int auth_flavor_len;
rpc_authflavor_t auth_flavors[1];
char *client_address;
+ char *fscache_uniq;
struct {
struct sockaddr_storage address;
diff --git a/fs/nfs/iostat.h b/fs/nfs/iostat.h
index a3695281003..a2ab2529b5c 100644
--- a/fs/nfs/iostat.h
+++ b/fs/nfs/iostat.h
@@ -16,6 +16,9 @@
struct nfs_iostats {
unsigned long long bytes[__NFSIOS_BYTESMAX];
+#ifdef CONFIG_NFS_FSCACHE
+ unsigned long long fscache[__NFSIOS_FSCACHEMAX];
+#endif
unsigned long events[__NFSIOS_COUNTSMAX];
} ____cacheline_aligned;
@@ -57,6 +60,21 @@ static inline void nfs_add_stats(const struct inode *inode,
nfs_add_server_stats(NFS_SERVER(inode), stat, addend);
}
+#ifdef CONFIG_NFS_FSCACHE
+static inline void nfs_add_fscache_stats(struct inode *inode,
+ enum nfs_stat_fscachecounters stat,
+ unsigned long addend)
+{
+ struct nfs_iostats *iostats;
+ int cpu;
+
+ cpu = get_cpu();
+ iostats = per_cpu_ptr(NFS_SERVER(inode)->io_stats, cpu);
+ iostats->fscache[stat] += addend;
+ put_cpu_no_resched();
+}
+#endif
+
static inline struct nfs_iostats *nfs_alloc_iostats(void)
{
return alloc_percpu(struct nfs_iostats);
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index f856004bb7f..4ace3c50a8e 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -24,6 +24,7 @@
#include "internal.h"
#include "iostat.h"
+#include "fscache.h"
#define NFSDBG_FACILITY NFSDBG_PAGECACHE
@@ -111,8 +112,8 @@ static void nfs_readpage_truncate_uninitialised_page(struct nfs_read_data *data)
}
}
-static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
- struct page *page)
+int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
+ struct page *page)
{
LIST_HEAD(one_request);
struct nfs_page *new;
@@ -139,6 +140,11 @@ static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
static void nfs_readpage_release(struct nfs_page *req)
{
+ struct inode *d_inode = req->wb_context->path.dentry->d_inode;
+
+ if (PageUptodate(req->wb_page))
+ nfs_readpage_to_fscache(d_inode, req->wb_page, 0);
+
unlock_page(req->wb_page);
dprintk("NFS: read done (%s/%Ld %d@%Ld)\n",
@@ -510,8 +516,15 @@ int nfs_readpage(struct file *file, struct page *page)
} else
ctx = get_nfs_open_context(nfs_file_open_context(file));
+ if (!IS_SYNC(inode)) {
+ error = nfs_readpage_from_fscache(ctx, inode, page);
+ if (error == 0)
+ goto out;
+ }
+
error = nfs_readpage_async(ctx, inode, page);
+out:
put_nfs_open_context(ctx);
return error;
out_unlock:
@@ -584,6 +597,15 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
return -EBADF;
} else
desc.ctx = get_nfs_open_context(nfs_file_open_context(filp));
+
+ /* attempt to read as many of the pages as possible from the cache
+ * - this returns -ENOBUFS immediately if the cookie is negative
+ */
+ ret = nfs_readpages_from_fscache(desc.ctx, inode, mapping,
+ pages, &nr_pages);
+ if (ret == 0)
+ goto read_complete; /* all pages were read */
+
if (rsize < PAGE_CACHE_SIZE)
nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0);
else
@@ -594,6 +616,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
nfs_pageio_complete(&pgio);
npages = (pgio.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
nfs_add_stats(inode, NFSIOS_READPAGES, npages);
+read_complete:
put_nfs_open_context(desc.ctx);
out:
return ret;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 0942fcbbad3..6717200923f 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -60,6 +60,7 @@
#include "delegation.h"
#include "iostat.h"
#include "internal.h"
+#include "fscache.h"
#define NFSDBG_FACILITY NFSDBG_VFS
@@ -76,6 +77,7 @@ enum {
Opt_rdirplus, Opt_nordirplus,
Opt_sharecache, Opt_nosharecache,
Opt_resvport, Opt_noresvport,
+ Opt_fscache, Opt_nofscache,
/* Mount options that take integer arguments */
Opt_port,
@@ -93,6 +95,7 @@ enum {
Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
Opt_addr, Opt_mountaddr, Opt_clientaddr,
Opt_lookupcache,
+ Opt_fscache_uniq,
/* Special mount options */
Opt_userspace, Opt_deprecated, Opt_sloppy,
@@ -132,6 +135,9 @@ static const match_table_t nfs_mount_option_tokens = {
{ Opt_nosharecache, "nosharecache" },
{ Opt_resvport, "resvport" },
{ Opt_noresvport, "noresvport" },
+ { Opt_fscache, "fsc" },
+ { Opt_fscache_uniq, "fsc=%s" },
+ { Opt_nofscache, "nofsc" },
{ Opt_port, "port=%u" },
{ Opt_rsize, "rsize=%u" },
@@ -563,6 +569,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
if (clp->rpc_ops->version == 4)
seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr);
#endif
+ if (nfss->options & NFS_OPTION_FSCACHE)
+ seq_printf(m, ",fsc");
}
/*
@@ -641,6 +649,10 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
totals.events[i] += stats->events[i];
for (i = 0; i < __NFSIOS_BYTESMAX; i++)
totals.bytes[i] += stats->bytes[i];
+#ifdef CONFIG_NFS_FSCACHE
+ for (i = 0; i < __NFSIOS_FSCACHEMAX; i++)
+ totals.fscache[i] += stats->fscache[i];
+#endif
preempt_enable();
}
@@ -651,6 +663,13 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
seq_printf(m, "\n\tbytes:\t");
for (i = 0; i < __NFSIOS_BYTESMAX; i++)
seq_printf(m, "%Lu ", totals.bytes[i]);
+#ifdef CONFIG_NFS_FSCACHE
+ if (nfss->options & NFS_OPTION_FSCACHE) {
+ seq_printf(m, "\n\tfsc:\t");
+ for (i = 0; i < __NFSIOS_FSCACHEMAX; i++)
+ seq_printf(m, "%Lu ", totals.bytes[i]);
+ }
+#endif
seq_printf(m, "\n");
rpc_print_iostats(m, nfss->client);
@@ -1044,6 +1063,24 @@ static int nfs_parse_mount_options(char *raw,
case Opt_noresvport:
mnt->flags |= NFS_MOUNT_NORESVPORT;
break;
+ case Opt_fscache:
+ mnt->options |= NFS_OPTION_FSCACHE;
+ kfree(mnt->fscache_uniq);
+ mnt->fscache_uniq = NULL;
+ break;
+ case Opt_nofscache:
+ mnt->options &= ~NFS_OPTION_FSCACHE;
+ kfree(mnt->fscache_uniq);
+ mnt->fscache_uniq = NULL;
+ break;
+ case Opt_fscache_uniq:
+ string = match_strdup(args);
+ if (!string)
+ goto out_nomem;
+ kfree(mnt->fscache_uniq);
+ mnt->fscache_uniq = string;
+ mnt->options |= NFS_OPTION_FSCACHE;
+ break;
/*
* options that take numeric values
@@ -1191,7 +1228,6 @@ static int nfs_parse_mount_options(char *raw,
goto out_nomem;
token = match_token(string,
nfs_xprt_protocol_tokens, args);
- kfree(string);
switch (token) {
case Opt_xprt_udp:
@@ -1221,6 +1257,7 @@ static int nfs_parse_mount_options(char *raw,
goto out_nomem;
token = match_token(string,
nfs_xprt_protocol_tokens, args);
+ kfree(string);
switch (token) {
case Opt_xprt_udp:
@@ -1870,8 +1907,6 @@ static void nfs_clone_super(struct super_block *sb,
nfs_initialise_sb(sb);
}
-#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
-
static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags)
{
const struct nfs_server *a = s->s_fs_info;
@@ -2036,6 +2071,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
if (!s->s_root) {
/* initial superblock/root creation */
nfs_fill_super(s, data);
+ nfs_fscache_get_super_cookie(s, data);
}
mntroot = nfs_get_root(s, mntfh);
@@ -2056,6 +2092,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
out:
kfree(data->nfs_server.hostname);
kfree(data->mount_server.hostname);
+ kfree(data->fscache_uniq);
security_free_mnt_opts(&data->lsm_opts);
out_free_fh:
kfree(mntfh);
@@ -2083,6 +2120,7 @@ static void nfs_kill_super(struct super_block *s)
bdi_unregister(&server->backing_dev_info);
kill_anon_super(s);
+ nfs_fscache_release_super_cookie(s);
nfs_free_server(server);
}
@@ -2390,6 +2428,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
if (!s->s_root) {
/* initial superblock/root creation */
nfs4_fill_super(s);
+ nfs_fscache_get_super_cookie(s, data);
}
mntroot = nfs4_get_root(s, mntfh);
@@ -2411,6 +2450,7 @@ out:
kfree(data->client_address);
kfree(data->nfs_server.export_path);
kfree(data->nfs_server.hostname);
+ kfree(data->fscache_uniq);
security_free_mnt_opts(&data->lsm_opts);
out_free_fh:
kfree(mntfh);
@@ -2437,6 +2477,7 @@ static void nfs4_kill_super(struct super_block *sb)
kill_anon_super(sb);
nfs4_renewd_prepare_shutdown(server);
+ nfs_fscache_release_super_cookie(sb);
nfs_free_server(server);
}
diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
index 44d7d04dab9..503b9da159a 100644
--- a/fs/nfsd/Kconfig
+++ b/fs/nfsd/Kconfig
@@ -1,6 +1,7 @@
config NFSD
tristate "NFS server support"
depends on INET
+ depends on FILE_LOCKING
select LOCKD
select SUNRPC
select EXPORTFS
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 9dbd2eb9128..7c9fe838f03 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -18,6 +18,7 @@
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/major.h>
+#include <linux/magic.h>
#include <linux/sunrpc/svc.h>
#include <linux/nfsd/nfsd.h>
@@ -202,6 +203,7 @@ nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,
struct nfsd3_writeres *resp)
{
__be32 nfserr;
+ unsigned long cnt = argp->len;
dprintk("nfsd: WRITE(3) %s %d bytes at %ld%s\n",
SVCFH_fmt(&argp->fh),
@@ -214,9 +216,9 @@ nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,
nfserr = nfsd_write(rqstp, &resp->fh, NULL,
argp->offset,
rqstp->rq_vec, argp->vlen,
- argp->len,
+ &cnt,
&resp->committed);
- resp->count = argp->count;
+ resp->count = cnt;
RETURN_STATUS(nfserr);
}
@@ -569,7 +571,7 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
struct super_block *sb = argp->fh.fh_dentry->d_inode->i_sb;
/* Note that we don't care for remote fs's here */
- if (sb->s_magic == 0x4d44 /* MSDOS_SUPER_MAGIC */) {
+ if (sb->s_magic == MSDOS_SUPER_MAGIC) {
resp->f_properties = NFS3_FSF_BILLYBOY;
}
resp->f_maxfilesize = sb->s_maxbytes;
@@ -610,7 +612,7 @@ nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
resp->p_link_max = EXT2_LINK_MAX;
resp->p_name_max = EXT2_NAME_LEN;
break;
- case 0x4d44: /* MSDOS_SUPER_MAGIC */
+ case MSDOS_SUPER_MAGIC:
resp->p_case_insensitive = 1;
resp->p_case_preserving = 0;
break;
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index c464181b599..290289bd44f 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -218,7 +218,7 @@ static int
encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec)
{
__be32 *p;
- int len = cb_rec->cbr_fhlen;
+ int len = cb_rec->cbr_fh.fh_size;
RESERVE_SPACE(12+sizeof(cb_rec->cbr_stateid) + len);
WRITE32(OP_CB_RECALL);
@@ -226,7 +226,7 @@ encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec)
WRITEMEM(&cb_rec->cbr_stateid.si_opaque, sizeof(stateid_opaque_t));
WRITE32(cb_rec->cbr_trunc);
WRITE32(len);
- WRITEMEM(cb_rec->cbr_fhval, len);
+ WRITEMEM(&cb_rec->cbr_fh.fh_base, len);
return 0;
}
@@ -361,9 +361,8 @@ static struct rpc_program cb_program = {
/* Reference counting, callback cleanup, etc., all look racy as heck.
* And why is cb_set an atomic? */
-static int do_probe_callback(void *data)
+static struct rpc_clnt *setup_callback_client(struct nfs4_client *clp)
{
- struct nfs4_client *clp = data;
struct sockaddr_in addr;
struct nfs4_callback *cb = &clp->cl_callback;
struct rpc_timeout timeparms = {
@@ -384,17 +383,10 @@ static int do_probe_callback(void *data)
.flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
.client_name = clp->cl_principal,
};
- struct rpc_message msg = {
- .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
- .rpc_argp = clp,
- };
struct rpc_clnt *client;
- int status;
- if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) {
- status = nfserr_cb_path_down;
- goto out_err;
- }
+ if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5))
+ return ERR_PTR(-EINVAL);
/* Initialize address */
memset(&addr, 0, sizeof(addr));
@@ -404,9 +396,29 @@ static int do_probe_callback(void *data)
/* Create RPC client */
client = rpc_create(&args);
+ if (IS_ERR(client))
+ dprintk("NFSD: couldn't create callback client: %ld\n",
+ PTR_ERR(client));
+ return client;
+
+}
+
+static int do_probe_callback(void *data)
+{
+ struct nfs4_client *clp = data;
+ struct nfs4_callback *cb = &clp->cl_callback;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
+ .rpc_argp = clp,
+ };
+ struct rpc_clnt *client;
+ int status;
+
+ client = setup_callback_client(clp);
if (IS_ERR(client)) {
- dprintk("NFSD: couldn't create callback client\n");
status = PTR_ERR(client);
+ dprintk("NFSD: couldn't create callback client: %d\n",
+ status);
goto out_err;
}
@@ -422,10 +434,10 @@ static int do_probe_callback(void *data)
out_release_client:
rpc_shutdown_client(client);
out_err:
- dprintk("NFSD: warning: no callback path to client %.*s\n",
- (int)clp->cl_name.len, clp->cl_name.data);
+ dprintk("NFSD: warning: no callback path to client %.*s: error %d\n",
+ (int)clp->cl_name.len, clp->cl_name.data, status);
put_nfs4_client(clp);
- return status;
+ return 0;
}
/*
@@ -451,7 +463,6 @@ nfsd4_probe_callback(struct nfs4_client *clp)
/*
* called with dp->dl_count inc'ed.
- * nfs4_lock_state() may or may not have been called.
*/
void
nfsd4_cb_recall(struct nfs4_delegation *dp)
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 9fa60a3ad48..b2883e9c638 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -93,6 +93,21 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
open->op_truncate = 0;
if (open->op_create) {
+ /* FIXME: check session persistence and pnfs flags.
+ * The nfsv4.1 spec requires the following semantics:
+ *
+ * Persistent | pNFS | Server REQUIRED | Client Allowed
+ * Reply Cache | server | |
+ * -------------+--------+-----------------+--------------------
+ * no | no | EXCLUSIVE4_1 | EXCLUSIVE4_1
+ * | | | (SHOULD)
+ * | | and EXCLUSIVE4 | or EXCLUSIVE4
+ * | | | (SHOULD NOT)
+ * no | yes | EXCLUSIVE4_1 | EXCLUSIVE4_1
+ * yes | no | GUARDED4 | GUARDED4
+ * yes | yes | GUARDED4 | GUARDED4
+ */
+
/*
* Note: create modes (UNCHECKED,GUARDED...) are the same
* in NFSv4 as in v3.
@@ -103,11 +118,13 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
(u32 *)open->op_verf.data,
&open->op_truncate, &created);
- /* If we ever decide to use different attrs to store the
- * verifier in nfsd_create_v3, then we'll need to change this
+ /*
+ * Following rfc 3530 14.2.16, use the returned bitmask
+ * to indicate which attributes we used to store the
+ * verifier:
*/
if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0)
- open->op_bmval[1] |= (FATTR4_WORD1_TIME_ACCESS |
+ open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS |
FATTR4_WORD1_TIME_MODIFY);
} else {
status = nfsd_lookup(rqstp, current_fh,
@@ -118,13 +135,11 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
goto out;
set_change_info(&open->op_cinfo, current_fh);
-
- /* set reply cache */
fh_dup2(current_fh, &resfh);
- open->op_stateowner->so_replay.rp_openfh_len = resfh.fh_handle.fh_size;
- memcpy(open->op_stateowner->so_replay.rp_openfh,
- &resfh.fh_handle.fh_base, resfh.fh_handle.fh_size);
+ /* set reply cache */
+ fh_copy_shallow(&open->op_stateowner->so_replay.rp_openfh,
+ &resfh.fh_handle);
if (!created)
status = do_open_permission(rqstp, current_fh, open,
NFSD_MAY_NOP);
@@ -150,10 +165,8 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_
memset(&open->op_cinfo, 0, sizeof(struct nfsd4_change_info));
/* set replay cache */
- open->op_stateowner->so_replay.rp_openfh_len = current_fh->fh_handle.fh_size;
- memcpy(open->op_stateowner->so_replay.rp_openfh,
- &current_fh->fh_handle.fh_base,
- current_fh->fh_handle.fh_size);
+ fh_copy_shallow(&open->op_stateowner->so_replay.rp_openfh,
+ &current_fh->fh_handle);
open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) &&
(open->op_iattr.ia_size == 0);
@@ -164,12 +177,23 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_
return status;
}
+static void
+copy_clientid(clientid_t *clid, struct nfsd4_session *session)
+{
+ struct nfsd4_sessionid *sid =
+ (struct nfsd4_sessionid *)session->se_sessionid.data;
+
+ clid->cl_boot = sid->clientid.cl_boot;
+ clid->cl_id = sid->clientid.cl_id;
+}
static __be32
nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct nfsd4_open *open)
{
__be32 status;
+ struct nfsd4_compoundres *resp;
+
dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n",
(int)open->op_fname.len, open->op_fname.data,
open->op_stateowner);
@@ -178,16 +202,19 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL)
return nfserr_inval;
+ if (nfsd4_has_session(cstate))
+ copy_clientid(&open->op_clientid, cstate->session);
+
nfs4_lock_state();
/* check seqid for replay. set nfs4_owner */
- status = nfsd4_process_open1(open);
+ resp = rqstp->rq_resp;
+ status = nfsd4_process_open1(&resp->cstate, open);
if (status == nfserr_replay_me) {
struct nfs4_replay *rp = &open->op_stateowner->so_replay;
fh_put(&cstate->current_fh);
- cstate->current_fh.fh_handle.fh_size = rp->rp_openfh_len;
- memcpy(&cstate->current_fh.fh_handle.fh_base, rp->rp_openfh,
- rp->rp_openfh_len);
+ fh_copy_shallow(&cstate->current_fh.fh_handle,
+ &rp->rp_openfh);
status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP);
if (status)
dprintk("nfsd4_open: replay failed"
@@ -209,10 +236,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
switch (open->op_claim_type) {
case NFS4_OPEN_CLAIM_DELEGATE_CUR:
- status = nfserr_inval;
- if (open->op_create)
- goto out;
- /* fall through */
case NFS4_OPEN_CLAIM_NULL:
/*
* (1) set CURRENT_FH to the file being opened,
@@ -455,8 +478,9 @@ nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (getattr->ga_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)
return nfserr_inval;
- getattr->ga_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0;
- getattr->ga_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1;
+ getattr->ga_bmval[0] &= nfsd_suppattrs0(cstate->minorversion);
+ getattr->ga_bmval[1] &= nfsd_suppattrs1(cstate->minorversion);
+ getattr->ga_bmval[2] &= nfsd_suppattrs2(cstate->minorversion);
getattr->ga_fhp = &cstate->current_fh;
return nfs_ok;
@@ -520,9 +544,8 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
nfs4_lock_state();
/* check stateid */
- if ((status = nfs4_preprocess_stateid_op(&cstate->current_fh,
- &read->rd_stateid,
- CHECK_FH | RD_STATE, &read->rd_filp))) {
+ if ((status = nfs4_preprocess_stateid_op(cstate, &read->rd_stateid,
+ RD_STATE, &read->rd_filp))) {
dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
goto out;
}
@@ -548,8 +571,9 @@ nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (readdir->rd_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)
return nfserr_inval;
- readdir->rd_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0;
- readdir->rd_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1;
+ readdir->rd_bmval[0] &= nfsd_suppattrs0(cstate->minorversion);
+ readdir->rd_bmval[1] &= nfsd_suppattrs1(cstate->minorversion);
+ readdir->rd_bmval[2] &= nfsd_suppattrs2(cstate->minorversion);
if ((cookie > ~(u32)0) || (cookie == 1) || (cookie == 2) ||
(cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE)))
@@ -653,8 +677,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
nfs4_lock_state();
- status = nfs4_preprocess_stateid_op(&cstate->current_fh,
- &setattr->sa_stateid, CHECK_FH | WR_STATE, NULL);
+ status = nfs4_preprocess_stateid_op(cstate,
+ &setattr->sa_stateid, WR_STATE, NULL);
nfs4_unlock_state();
if (status) {
dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
@@ -685,6 +709,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct file *filp = NULL;
u32 *p;
__be32 status = nfs_ok;
+ unsigned long cnt;
/* no need to check permission - this will be done in nfsd_write() */
@@ -692,8 +717,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
return nfserr_inval;
nfs4_lock_state();
- status = nfs4_preprocess_stateid_op(&cstate->current_fh, stateid,
- CHECK_FH | WR_STATE, &filp);
+ status = nfs4_preprocess_stateid_op(cstate, stateid, WR_STATE, &filp);
if (filp)
get_file(filp);
nfs4_unlock_state();
@@ -703,7 +727,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
return status;
}
- write->wr_bytes_written = write->wr_buflen;
+ cnt = write->wr_buflen;
write->wr_how_written = write->wr_stable_how;
p = (u32 *)write->wr_verifier.data;
*p++ = nfssvc_boot.tv_sec;
@@ -711,10 +735,12 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
status = nfsd_write(rqstp, &cstate->current_fh, filp,
write->wr_offset, rqstp->rq_vec, write->wr_vlen,
- write->wr_buflen, &write->wr_how_written);
+ &cnt, &write->wr_how_written);
if (filp)
fput(filp);
+ write->wr_bytes_written = cnt;
+
if (status == nfserr_symlink)
status = nfserr_inval;
return status;
@@ -737,8 +763,9 @@ _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (status)
return status;
- if ((verify->ve_bmval[0] & ~NFSD_SUPPORTED_ATTRS_WORD0)
- || (verify->ve_bmval[1] & ~NFSD_SUPPORTED_ATTRS_WORD1))
+ if ((verify->ve_bmval[0] & ~nfsd_suppattrs0(cstate->minorversion))
+ || (verify->ve_bmval[1] & ~nfsd_suppattrs1(cstate->minorversion))
+ || (verify->ve_bmval[2] & ~nfsd_suppattrs2(cstate->minorversion)))
return nfserr_attrnotsupp;
if ((verify->ve_bmval[0] & FATTR4_WORD0_RDATTR_ERROR)
|| (verify->ve_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1))
@@ -766,7 +793,8 @@ _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (status)
goto out_kfree;
- p = buf + 3;
+ /* skip bitmap */
+ p = buf + 1 + ntohl(buf[0]);
status = nfserr_not_same;
if (ntohl(*p++) != verify->ve_attrlen)
goto out_kfree;
@@ -813,39 +841,17 @@ static inline void nfsd4_increment_op_stats(u32 opnum)
nfsdstats.nfs4_opcount[opnum]++;
}
-static void cstate_free(struct nfsd4_compound_state *cstate)
-{
- if (cstate == NULL)
- return;
- fh_put(&cstate->current_fh);
- fh_put(&cstate->save_fh);
- BUG_ON(cstate->replay_owner);
- kfree(cstate);
-}
-
-static struct nfsd4_compound_state *cstate_alloc(void)
-{
- struct nfsd4_compound_state *cstate;
-
- cstate = kmalloc(sizeof(struct nfsd4_compound_state), GFP_KERNEL);
- if (cstate == NULL)
- return NULL;
- fh_init(&cstate->current_fh, NFS4_FHSIZE);
- fh_init(&cstate->save_fh, NFS4_FHSIZE);
- cstate->replay_owner = NULL;
- return cstate;
-}
-
typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
void *);
+enum nfsd4_op_flags {
+ ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */
+ ALLOWED_ON_ABSENT_FS = 2 << 0, /* ops processed on absent fs */
+ ALLOWED_AS_FIRST_OP = 3 << 0, /* ops reqired first in compound */
+};
struct nfsd4_operation {
nfsd4op_func op_func;
u32 op_flags;
-/* Most ops require a valid current filehandle; a few don't: */
-#define ALLOWED_WITHOUT_FH 1
-/* GETATTR and ops not listed as returning NFS4ERR_MOVED: */
-#define ALLOWED_ON_ABSENT_FS 2
char *op_name;
};
@@ -854,6 +860,51 @@ static struct nfsd4_operation nfsd4_ops[];
static const char *nfsd4_op_name(unsigned opnum);
/*
+ * This is a replay of a compound for which no cache entry pages
+ * were used. Encode the sequence operation, and if cachethis is FALSE
+ * encode the uncache rep error on the next operation.
+ */
+static __be32
+nfsd4_enc_uncached_replay(struct nfsd4_compoundargs *args,
+ struct nfsd4_compoundres *resp)
+{
+ struct nfsd4_op *op;
+
+ dprintk("--> %s resp->opcnt %d ce_cachethis %u \n", __func__,
+ resp->opcnt, resp->cstate.slot->sl_cache_entry.ce_cachethis);
+
+ /* Encode the replayed sequence operation */
+ BUG_ON(resp->opcnt != 1);
+ op = &args->ops[resp->opcnt - 1];
+ nfsd4_encode_operation(resp, op);
+
+ /*return nfserr_retry_uncached_rep in next operation. */
+ if (resp->cstate.slot->sl_cache_entry.ce_cachethis == 0) {
+ op = &args->ops[resp->opcnt++];
+ op->status = nfserr_retry_uncached_rep;
+ nfsd4_encode_operation(resp, op);
+ }
+ return op->status;
+}
+
+/*
+ * Enforce NFSv4.1 COMPOUND ordering rules.
+ *
+ * TODO:
+ * - enforce NFS4ERR_NOT_ONLY_OP,
+ * - DESTROY_SESSION MUST be the final operation in the COMPOUND request.
+ */
+static bool nfs41_op_ordering_ok(struct nfsd4_compoundargs *args)
+{
+ if (args->minorversion && args->opcnt > 0) {
+ struct nfsd4_op *op = &args->ops[0];
+ return (op->status == nfserr_op_illegal) ||
+ (nfsd4_ops[op->opnum].op_flags & ALLOWED_AS_FIRST_OP);
+ }
+ return true;
+}
+
+/*
* COMPOUND call.
*/
static __be32
@@ -863,12 +914,13 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
{
struct nfsd4_op *op;
struct nfsd4_operation *opdesc;
- struct nfsd4_compound_state *cstate = NULL;
+ struct nfsd4_compound_state *cstate = &resp->cstate;
int slack_bytes;
__be32 status;
resp->xbuf = &rqstp->rq_res;
- resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len;
+ resp->p = rqstp->rq_res.head[0].iov_base +
+ rqstp->rq_res.head[0].iov_len;
resp->tagp = resp->p;
/* reserve space for: taglen, tag, and opcnt */
resp->p += 2 + XDR_QUADLEN(args->taglen);
@@ -877,18 +929,25 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
resp->tag = args->tag;
resp->opcnt = 0;
resp->rqstp = rqstp;
+ resp->cstate.minorversion = args->minorversion;
+ resp->cstate.replay_owner = NULL;
+ fh_init(&resp->cstate.current_fh, NFS4_FHSIZE);
+ fh_init(&resp->cstate.save_fh, NFS4_FHSIZE);
+ /* Use the deferral mechanism only for NFSv4.0 compounds */
+ rqstp->rq_usedeferral = (args->minorversion == 0);
/*
* According to RFC3010, this takes precedence over all other errors.
*/
status = nfserr_minor_vers_mismatch;
- if (args->minorversion > NFSD_SUPPORTED_MINOR_VERSION)
+ if (args->minorversion > nfsd_supported_minorversion)
goto out;
- status = nfserr_resource;
- cstate = cstate_alloc();
- if (cstate == NULL)
- goto out;
+ if (!nfs41_op_ordering_ok(args)) {
+ op = &args->ops[0];
+ op->status = nfserr_sequence_pos;
+ goto encode_op;
+ }
status = nfs_ok;
while (!status && resp->opcnt < args->opcnt) {
@@ -897,7 +956,6 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
dprintk("nfsv4 compound op #%d/%d: %d (%s)\n",
resp->opcnt, args->opcnt, op->opnum,
nfsd4_op_name(op->opnum));
-
/*
* The XDR decode routines may have pre-set op->status;
* for example, if there is a miscellaneous XDR error
@@ -938,6 +996,15 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
BUG_ON(op->status == nfs_ok);
encode_op:
+ /* Only from SEQUENCE or CREATE_SESSION */
+ if (resp->cstate.status == nfserr_replay_cache) {
+ dprintk("%s NFS4.1 replay from cache\n", __func__);
+ if (nfsd4_not_cached(resp))
+ status = nfsd4_enc_uncached_replay(args, resp);
+ else
+ status = op->status;
+ goto out;
+ }
if (op->status == nfserr_replay_me) {
op->replay = &cstate->replay_owner->so_replay;
nfsd4_encode_replay(resp, op);
@@ -961,15 +1028,24 @@ encode_op:
nfsd4_increment_op_stats(op->opnum);
}
+ if (!rqstp->rq_usedeferral && status == nfserr_dropit) {
+ dprintk("%s Dropit - send NFS4ERR_DELAY\n", __func__);
+ status = nfserr_jukebox;
+ }
- cstate_free(cstate);
+ resp->cstate.status = status;
+ fh_put(&resp->cstate.current_fh);
+ fh_put(&resp->cstate.save_fh);
+ BUG_ON(resp->cstate.replay_owner);
out:
nfsd4_release_compoundargs(args);
+ /* Reset deferral mechanism for RPC deferrals */
+ rqstp->rq_usedeferral = 1;
dprintk("nfsv4 compound returned %d\n", ntohl(status));
return status;
}
-static struct nfsd4_operation nfsd4_ops[OP_RELEASE_LOCKOWNER+1] = {
+static struct nfsd4_operation nfsd4_ops[] = {
[OP_ACCESS] = {
.op_func = (nfsd4op_func)nfsd4_access,
.op_name = "OP_ACCESS",
@@ -1045,7 +1121,7 @@ static struct nfsd4_operation nfsd4_ops[OP_RELEASE_LOCKOWNER+1] = {
.op_name = "OP_PUTFH",
},
[OP_PUTPUBFH] = {
- /* unsupported, just for future reference: */
+ .op_func = (nfsd4op_func)nfsd4_putrootfh,
.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
.op_name = "OP_PUTPUBFH",
},
@@ -1119,6 +1195,28 @@ static struct nfsd4_operation nfsd4_ops[OP_RELEASE_LOCKOWNER+1] = {
.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
.op_name = "OP_RELEASE_LOCKOWNER",
},
+
+ /* NFSv4.1 operations */
+ [OP_EXCHANGE_ID] = {
+ .op_func = (nfsd4op_func)nfsd4_exchange_id,
+ .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
+ .op_name = "OP_EXCHANGE_ID",
+ },
+ [OP_CREATE_SESSION] = {
+ .op_func = (nfsd4op_func)nfsd4_create_session,
+ .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
+ .op_name = "OP_CREATE_SESSION",
+ },
+ [OP_DESTROY_SESSION] = {
+ .op_func = (nfsd4op_func)nfsd4_destroy_session,
+ .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
+ .op_name = "OP_DESTROY_SESSION",
+ },
+ [OP_SEQUENCE] = {
+ .op_func = (nfsd4op_func)nfsd4_sequence,
+ .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
+ .op_name = "OP_SEQUENCE",
+ },
};
static const char *nfsd4_op_name(unsigned opnum)
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 74f7b67567f..3444c0052a8 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -182,36 +182,26 @@ out_unlock:
typedef int (recdir_func)(struct dentry *, struct dentry *);
-struct dentry_list {
- struct dentry *dentry;
+struct name_list {
+ char name[HEXDIR_LEN];
struct list_head list;
};
-struct dentry_list_arg {
- struct list_head dentries;
- struct dentry *parent;
-};
-
static int
-nfsd4_build_dentrylist(void *arg, const char *name, int namlen,
+nfsd4_build_namelist(void *arg, const char *name, int namlen,
loff_t offset, u64 ino, unsigned int d_type)
{
- struct dentry_list_arg *dla = arg;
- struct list_head *dentries = &dla->dentries;
- struct dentry *parent = dla->parent;
- struct dentry *dentry;
- struct dentry_list *child;
+ struct list_head *names = arg;
+ struct name_list *entry;
- if (name && isdotent(name, namlen))
+ if (namlen != HEXDIR_LEN - 1)
return 0;
- dentry = lookup_one_len(name, parent, namlen);
- if (IS_ERR(dentry))
- return PTR_ERR(dentry);
- child = kmalloc(sizeof(*child), GFP_KERNEL);
- if (child == NULL)
+ entry = kmalloc(sizeof(struct name_list), GFP_KERNEL);
+ if (entry == NULL)
return -ENOMEM;
- child->dentry = dentry;
- list_add(&child->list, dentries);
+ memcpy(entry->name, name, HEXDIR_LEN - 1);
+ entry->name[HEXDIR_LEN - 1] = '\0';
+ list_add(&entry->list, names);
return 0;
}
@@ -220,11 +210,9 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
{
const struct cred *original_cred;
struct file *filp;
- struct dentry_list_arg dla = {
- .parent = dir,
- };
- struct list_head *dentries = &dla.dentries;
- struct dentry_list *child;
+ LIST_HEAD(names);
+ struct name_list *entry;
+ struct dentry *dentry;
int status;
if (!rec_dir_init)
@@ -233,31 +221,34 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
status = nfs4_save_creds(&original_cred);
if (status < 0)
return status;
- INIT_LIST_HEAD(dentries);
filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY,
current_cred());
status = PTR_ERR(filp);
if (IS_ERR(filp))
goto out;
- INIT_LIST_HEAD(dentries);
- status = vfs_readdir(filp, nfsd4_build_dentrylist, &dla);
+ status = vfs_readdir(filp, nfsd4_build_namelist, &names);
fput(filp);
- while (!list_empty(dentries)) {
- child = list_entry(dentries->next, struct dentry_list, list);
- status = f(dir, child->dentry);
+ while (!list_empty(&names)) {
+ entry = list_entry(names.next, struct name_list, list);
+
+ dentry = lookup_one_len(entry->name, dir, HEXDIR_LEN-1);
+ if (IS_ERR(dentry)) {
+ status = PTR_ERR(dentry);
+ goto out;
+ }
+ status = f(dir, dentry);
+ dput(dentry);
if (status)
goto out;
- list_del(&child->list);
- dput(child->dentry);
- kfree(child);
+ list_del(&entry->list);
+ kfree(entry);
}
out:
- while (!list_empty(dentries)) {
- child = list_entry(dentries->next, struct dentry_list, list);
- list_del(&child->list);
- dput(child->dentry);
- kfree(child);
+ while (!list_empty(&names)) {
+ entry = list_entry(names.next, struct name_list, list);
+ list_del(&entry->list);
+ kfree(entry);
}
nfs4_reset_creds(original_cred);
return status;
@@ -353,7 +344,8 @@ purge_old(struct dentry *parent, struct dentry *child)
{
int status;
- if (nfs4_has_reclaimed_state(child->d_name.name))
+ /* note: we currently use this path only for minorversion 0 */
+ if (nfs4_has_reclaimed_state(child->d_name.name, false))
return 0;
status = nfsd4_clear_clid_dir(parent, child);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b6f60f48e94..c65a27b76a9 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -68,6 +68,7 @@ static u32 current_delegid = 1;
static u32 nfs4_init;
static stateid_t zerostateid; /* bits all 0 */
static stateid_t onestateid; /* bits all 1 */
+static u64 current_sessionid = 1;
#define ZERO_STATEID(stateid) (!memcmp((stateid), &zerostateid, sizeof(stateid_t)))
#define ONE_STATEID(stateid) (!memcmp((stateid), &onestateid, sizeof(stateid_t)))
@@ -75,18 +76,21 @@ static stateid_t onestateid; /* bits all 1 */
/* forward declarations */
static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
-static void release_stateid_lockowners(struct nfs4_stateid *open_stp);
static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
static void nfs4_set_recdir(char *recdir);
-/* Locking:
- *
- * client_mutex:
- * protects clientid_hashtbl[], clientstr_hashtbl[],
- * unconfstr_hashtbl[], uncofid_hashtbl[].
- */
+/* Locking: */
+
+/* Currently used for almost all code touching nfsv4 state: */
static DEFINE_MUTEX(client_mutex);
+/*
+ * Currently used for the del_recall_lru and file hash table. In an
+ * effort to decrease the scope of the client_mutex, this spinlock may
+ * eventually cover more:
+ */
+static DEFINE_SPINLOCK(recall_lock);
+
static struct kmem_cache *stateowner_slab = NULL;
static struct kmem_cache *file_slab = NULL;
static struct kmem_cache *stateid_slab = NULL;
@@ -117,37 +121,23 @@ opaque_hashval(const void *ptr, int nbytes)
return x;
}
-/* forward declarations */
-static void release_stateowner(struct nfs4_stateowner *sop);
-static void release_stateid(struct nfs4_stateid *stp, int flags);
-
-/*
- * Delegation state
- */
-
-/* recall_lock protects the del_recall_lru */
-static DEFINE_SPINLOCK(recall_lock);
static struct list_head del_recall_lru;
-static void
-free_nfs4_file(struct kref *kref)
-{
- struct nfs4_file *fp = container_of(kref, struct nfs4_file, fi_ref);
- list_del(&fp->fi_hash);
- iput(fp->fi_inode);
- kmem_cache_free(file_slab, fp);
-}
-
static inline void
put_nfs4_file(struct nfs4_file *fi)
{
- kref_put(&fi->fi_ref, free_nfs4_file);
+ if (atomic_dec_and_lock(&fi->fi_ref, &recall_lock)) {
+ list_del(&fi->fi_hash);
+ spin_unlock(&recall_lock);
+ iput(fi->fi_inode);
+ kmem_cache_free(file_slab, fi);
+ }
}
static inline void
get_nfs4_file(struct nfs4_file *fi)
{
- kref_get(&fi->fi_ref);
+ atomic_inc(&fi->fi_ref);
}
static int num_delegations;
@@ -220,9 +210,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
dp->dl_stateid.si_stateownerid = current_delegid++;
dp->dl_stateid.si_fileid = 0;
dp->dl_stateid.si_generation = 0;
- dp->dl_fhlen = current_fh->fh_handle.fh_size;
- memcpy(dp->dl_fhval, &current_fh->fh_handle.fh_base,
- current_fh->fh_handle.fh_size);
+ fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle);
dp->dl_time = 0;
atomic_set(&dp->dl_count, 1);
list_add(&dp->dl_perfile, &fp->fi_delegations);
@@ -311,6 +299,291 @@ static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
static struct list_head client_lru;
static struct list_head close_lru;
+static void unhash_generic_stateid(struct nfs4_stateid *stp)
+{
+ list_del(&stp->st_hash);
+ list_del(&stp->st_perfile);
+ list_del(&stp->st_perstateowner);
+}
+
+static void free_generic_stateid(struct nfs4_stateid *stp)
+{
+ put_nfs4_file(stp->st_file);
+ kmem_cache_free(stateid_slab, stp);
+}
+
+static void release_lock_stateid(struct nfs4_stateid *stp)
+{
+ unhash_generic_stateid(stp);
+ locks_remove_posix(stp->st_vfs_file, (fl_owner_t)stp->st_stateowner);
+ free_generic_stateid(stp);
+}
+
+static void unhash_lockowner(struct nfs4_stateowner *sop)
+{
+ struct nfs4_stateid *stp;
+
+ list_del(&sop->so_idhash);
+ list_del(&sop->so_strhash);
+ list_del(&sop->so_perstateid);
+ while (!list_empty(&sop->so_stateids)) {
+ stp = list_first_entry(&sop->so_stateids,
+ struct nfs4_stateid, st_perstateowner);
+ release_lock_stateid(stp);
+ }
+}
+
+static void release_lockowner(struct nfs4_stateowner *sop)
+{
+ unhash_lockowner(sop);
+ nfs4_put_stateowner(sop);
+}
+
+static void
+release_stateid_lockowners(struct nfs4_stateid *open_stp)
+{
+ struct nfs4_stateowner *lock_sop;
+
+ while (!list_empty(&open_stp->st_lockowners)) {
+ lock_sop = list_entry(open_stp->st_lockowners.next,
+ struct nfs4_stateowner, so_perstateid);
+ /* list_del(&open_stp->st_lockowners); */
+ BUG_ON(lock_sop->so_is_open_owner);
+ release_lockowner(lock_sop);
+ }
+}
+
+static void release_open_stateid(struct nfs4_stateid *stp)
+{
+ unhash_generic_stateid(stp);
+ release_stateid_lockowners(stp);
+ nfsd_close(stp->st_vfs_file);
+ free_generic_stateid(stp);
+}
+
+static void unhash_openowner(struct nfs4_stateowner *sop)
+{
+ struct nfs4_stateid *stp;
+
+ list_del(&sop->so_idhash);
+ list_del(&sop->so_strhash);
+ list_del(&sop->so_perclient);
+ list_del(&sop->so_perstateid); /* XXX: necessary? */
+ while (!list_empty(&sop->so_stateids)) {
+ stp = list_first_entry(&sop->so_stateids,
+ struct nfs4_stateid, st_perstateowner);
+ release_open_stateid(stp);
+ }
+}
+
+static void release_openowner(struct nfs4_stateowner *sop)
+{
+ unhash_openowner(sop);
+ list_del(&sop->so_close_lru);
+ nfs4_put_stateowner(sop);
+}
+
+static DEFINE_SPINLOCK(sessionid_lock);
+#define SESSION_HASH_SIZE 512
+static struct list_head sessionid_hashtbl[SESSION_HASH_SIZE];
+
+static inline int
+hash_sessionid(struct nfs4_sessionid *sessionid)
+{
+ struct nfsd4_sessionid *sid = (struct nfsd4_sessionid *)sessionid;
+
+ return sid->sequence % SESSION_HASH_SIZE;
+}
+
+static inline void
+dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
+{
+ u32 *ptr = (u32 *)(&sessionid->data[0]);
+ dprintk("%s: %u:%u:%u:%u\n", fn, ptr[0], ptr[1], ptr[2], ptr[3]);
+}
+
+static void
+gen_sessionid(struct nfsd4_session *ses)
+{
+ struct nfs4_client *clp = ses->se_client;
+ struct nfsd4_sessionid *sid;
+
+ sid = (struct nfsd4_sessionid *)ses->se_sessionid.data;
+ sid->clientid = clp->cl_clientid;
+ sid->sequence = current_sessionid++;
+ sid->reserved = 0;
+}
+
+/*
+ * Give the client the number of slots it requests bound by
+ * NFSD_MAX_SLOTS_PER_SESSION and by sv_drc_max_pages.
+ *
+ * If we run out of pages (sv_drc_pages_used == sv_drc_max_pages) we
+ * should (up to a point) re-negotiate active sessions and reduce their
+ * slot usage to make rooom for new connections. For now we just fail the
+ * create session.
+ */
+static int set_forechannel_maxreqs(struct nfsd4_channel_attrs *fchan)
+{
+ int status = 0, np = fchan->maxreqs * NFSD_PAGES_PER_SLOT;
+
+ spin_lock(&nfsd_serv->sv_lock);
+ if (np + nfsd_serv->sv_drc_pages_used > nfsd_serv->sv_drc_max_pages)
+ np = nfsd_serv->sv_drc_max_pages - nfsd_serv->sv_drc_pages_used;
+ nfsd_serv->sv_drc_pages_used += np;
+ spin_unlock(&nfsd_serv->sv_lock);
+
+ if (np <= 0) {
+ status = nfserr_resource;
+ fchan->maxreqs = 0;
+ } else
+ fchan->maxreqs = np / NFSD_PAGES_PER_SLOT;
+
+ return status;
+}
+
+/*
+ * fchan holds the client values on input, and the server values on output
+ */
+static int init_forechannel_attrs(struct svc_rqst *rqstp,
+ struct nfsd4_session *session,
+ struct nfsd4_channel_attrs *fchan)
+{
+ int status = 0;
+ __u32 maxcount = svc_max_payload(rqstp);
+
+ /* headerpadsz set to zero in encode routine */
+
+ /* Use the client's max request and max response size if possible */
+ if (fchan->maxreq_sz > maxcount)
+ fchan->maxreq_sz = maxcount;
+ session->se_fmaxreq_sz = fchan->maxreq_sz;
+
+ if (fchan->maxresp_sz > maxcount)
+ fchan->maxresp_sz = maxcount;
+ session->se_fmaxresp_sz = fchan->maxresp_sz;
+
+ /* Set the max response cached size our default which is
+ * a multiple of PAGE_SIZE and small */
+ session->se_fmaxresp_cached = NFSD_PAGES_PER_SLOT * PAGE_SIZE;
+ fchan->maxresp_cached = session->se_fmaxresp_cached;
+
+ /* Use the client's maxops if possible */
+ if (fchan->maxops > NFSD_MAX_OPS_PER_COMPOUND)
+ fchan->maxops = NFSD_MAX_OPS_PER_COMPOUND;
+ session->se_fmaxops = fchan->maxops;
+
+ /* try to use the client requested number of slots */
+ if (fchan->maxreqs > NFSD_MAX_SLOTS_PER_SESSION)
+ fchan->maxreqs = NFSD_MAX_SLOTS_PER_SESSION;
+
+ /* FIXME: Error means no more DRC pages so the server should
+ * recover pages from existing sessions. For now fail session
+ * creation.
+ */
+ status = set_forechannel_maxreqs(fchan);
+
+ session->se_fnumslots = fchan->maxreqs;
+ return status;
+}
+
+static int
+alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp,
+ struct nfsd4_create_session *cses)
+{
+ struct nfsd4_session *new, tmp;
+ int idx, status = nfserr_resource, slotsize;
+
+ memset(&tmp, 0, sizeof(tmp));
+
+ /* FIXME: For now, we just accept the client back channel attributes. */
+ status = init_forechannel_attrs(rqstp, &tmp, &cses->fore_channel);
+ if (status)
+ goto out;
+
+ /* allocate struct nfsd4_session and slot table in one piece */
+ slotsize = tmp.se_fnumslots * sizeof(struct nfsd4_slot);
+ new = kzalloc(sizeof(*new) + slotsize, GFP_KERNEL);
+ if (!new)
+ goto out;
+
+ memcpy(new, &tmp, sizeof(*new));
+
+ new->se_client = clp;
+ gen_sessionid(new);
+ idx = hash_sessionid(&new->se_sessionid);
+ memcpy(clp->cl_sessionid.data, new->se_sessionid.data,
+ NFS4_MAX_SESSIONID_LEN);
+
+ new->se_flags = cses->flags;
+ kref_init(&new->se_ref);
+ spin_lock(&sessionid_lock);
+ list_add(&new->se_hash, &sessionid_hashtbl[idx]);
+ list_add(&new->se_perclnt, &clp->cl_sessions);
+ spin_unlock(&sessionid_lock);
+
+ status = nfs_ok;
+out:
+ return status;
+}
+
+/* caller must hold sessionid_lock */
+static struct nfsd4_session *
+find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid)
+{
+ struct nfsd4_session *elem;
+ int idx;
+
+ dump_sessionid(__func__, sessionid);
+ idx = hash_sessionid(sessionid);
+ dprintk("%s: idx is %d\n", __func__, idx);
+ /* Search in the appropriate list */
+ list_for_each_entry(elem, &sessionid_hashtbl[idx], se_hash) {
+ dump_sessionid("list traversal", &elem->se_sessionid);
+ if (!memcmp(elem->se_sessionid.data, sessionid->data,
+ NFS4_MAX_SESSIONID_LEN)) {
+ return elem;
+ }
+ }
+
+ dprintk("%s: session not found\n", __func__);
+ return NULL;
+}
+
+/* caller must hold sessionid_lock */
+static void
+unhash_session(struct nfsd4_session *ses)
+{
+ list_del(&ses->se_hash);
+ list_del(&ses->se_perclnt);
+}
+
+static void
+release_session(struct nfsd4_session *ses)
+{
+ spin_lock(&sessionid_lock);
+ unhash_session(ses);
+ spin_unlock(&sessionid_lock);
+ nfsd4_put_session(ses);
+}
+
+static void nfsd4_release_respages(struct page **respages, short resused);
+
+void
+free_session(struct kref *kref)
+{
+ struct nfsd4_session *ses;
+ int i;
+
+ ses = container_of(kref, struct nfsd4_session, se_ref);
+ for (i = 0; i < ses->se_fnumslots; i++) {
+ struct nfsd4_cache_entry *e = &ses->se_slots[i].sl_cache_entry;
+ nfsd4_release_respages(e->ce_respages, e->ce_resused);
+ }
+ kfree(ses->se_slots);
+ kfree(ses);
+}
+
static inline void
renew_client(struct nfs4_client *clp)
{
@@ -330,8 +603,8 @@ STALE_CLIENTID(clientid_t *clid)
{
if (clid->cl_boot == boot_time)
return 0;
- dprintk("NFSD stale clientid (%08x/%08x)\n",
- clid->cl_boot, clid->cl_id);
+ dprintk("NFSD stale clientid (%08x/%08x) boot_time %08lx\n",
+ clid->cl_boot, clid->cl_id, boot_time);
return 1;
}
@@ -376,6 +649,8 @@ static inline void
free_client(struct nfs4_client *clp)
{
shutdown_callback_client(clp);
+ nfsd4_release_respages(clp->cl_slot.sl_cache_entry.ce_respages,
+ clp->cl_slot.sl_cache_entry.ce_resused);
if (clp->cl_cred.cr_group_info)
put_group_info(clp->cl_cred.cr_group_info);
kfree(clp->cl_principal);
@@ -420,7 +695,13 @@ expire_client(struct nfs4_client *clp)
list_del(&clp->cl_lru);
while (!list_empty(&clp->cl_openowners)) {
sop = list_entry(clp->cl_openowners.next, struct nfs4_stateowner, so_perclient);
- release_stateowner(sop);
+ release_openowner(sop);
+ }
+ while (!list_empty(&clp->cl_sessions)) {
+ struct nfsd4_session *ses;
+ ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
+ se_perclnt);
+ release_session(ses);
}
put_nfs4_client(clp);
}
@@ -439,6 +720,7 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir)
INIT_LIST_HEAD(&clp->cl_strhash);
INIT_LIST_HEAD(&clp->cl_openowners);
INIT_LIST_HEAD(&clp->cl_delegations);
+ INIT_LIST_HEAD(&clp->cl_sessions);
INIT_LIST_HEAD(&clp->cl_lru);
return clp;
}
@@ -568,25 +850,45 @@ find_unconfirmed_client(clientid_t *clid)
return NULL;
}
+/*
+ * Return 1 iff clp's clientid establishment method matches the use_exchange_id
+ * parameter. Matching is based on the fact the at least one of the
+ * EXCHGID4_FLAG_USE_{NON_PNFS,PNFS_MDS,PNFS_DS} flags must be set for v4.1
+ *
+ * FIXME: we need to unify the clientid namespaces for nfsv4.x
+ * and correctly deal with client upgrade/downgrade in EXCHANGE_ID
+ * and SET_CLIENTID{,_CONFIRM}
+ */
+static inline int
+match_clientid_establishment(struct nfs4_client *clp, bool use_exchange_id)
+{
+ bool has_exchange_flags = (clp->cl_exchange_flags != 0);
+ return use_exchange_id == has_exchange_flags;
+}
+
static struct nfs4_client *
-find_confirmed_client_by_str(const char *dname, unsigned int hashval)
+find_confirmed_client_by_str(const char *dname, unsigned int hashval,
+ bool use_exchange_id)
{
struct nfs4_client *clp;
list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) {
- if (same_name(clp->cl_recdir, dname))
+ if (same_name(clp->cl_recdir, dname) &&
+ match_clientid_establishment(clp, use_exchange_id))
return clp;
}
return NULL;
}
static struct nfs4_client *
-find_unconfirmed_client_by_str(const char *dname, unsigned int hashval)
+find_unconfirmed_client_by_str(const char *dname, unsigned int hashval,
+ bool use_exchange_id)
{
struct nfs4_client *clp;
list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) {
- if (same_name(clp->cl_recdir, dname))
+ if (same_name(clp->cl_recdir, dname) &&
+ match_clientid_establishment(clp, use_exchange_id))
return clp;
}
return NULL;
@@ -685,6 +987,534 @@ out_err:
return;
}
+void
+nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp)
+{
+ struct nfsd4_compoundres *resp = rqstp->rq_resp;
+
+ resp->cstate.statp = statp;
+}
+
+/*
+ * Dereference the result pages.
+ */
+static void
+nfsd4_release_respages(struct page **respages, short resused)
+{
+ int i;
+
+ dprintk("--> %s\n", __func__);
+ for (i = 0; i < resused; i++) {
+ if (!respages[i])
+ continue;
+ put_page(respages[i]);
+ respages[i] = NULL;
+ }
+}
+
+static void
+nfsd4_copy_pages(struct page **topages, struct page **frompages, short count)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ topages[i] = frompages[i];
+ if (!topages[i])
+ continue;
+ get_page(topages[i]);
+ }
+}
+
+/*
+ * Cache the reply pages up to NFSD_PAGES_PER_SLOT + 1, clearing the previous
+ * pages. We add a page to NFSD_PAGES_PER_SLOT for the case where the total
+ * length of the XDR response is less than se_fmaxresp_cached
+ * (NFSD_PAGES_PER_SLOT * PAGE_SIZE) but the xdr_buf pages is used for a
+ * of the reply (e.g. readdir).
+ *
+ * Store the base and length of the rq_req.head[0] page
+ * of the NFSv4.1 data, just past the rpc header.
+ */
+void
+nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
+{
+ struct nfsd4_cache_entry *entry = &resp->cstate.slot->sl_cache_entry;
+ struct svc_rqst *rqstp = resp->rqstp;
+ struct nfsd4_compoundargs *args = rqstp->rq_argp;
+ struct nfsd4_op *op = &args->ops[resp->opcnt];
+ struct kvec *resv = &rqstp->rq_res.head[0];
+
+ dprintk("--> %s entry %p\n", __func__, entry);
+
+ /* Don't cache a failed OP_SEQUENCE. */
+ if (resp->opcnt == 1 && op->opnum == OP_SEQUENCE && resp->cstate.status)
+ return;
+
+ nfsd4_release_respages(entry->ce_respages, entry->ce_resused);
+ entry->ce_opcnt = resp->opcnt;
+ entry->ce_status = resp->cstate.status;
+
+ /*
+ * Don't need a page to cache just the sequence operation - the slot
+ * does this for us!
+ */
+
+ if (nfsd4_not_cached(resp)) {
+ entry->ce_resused = 0;
+ entry->ce_rpchdrlen = 0;
+ dprintk("%s Just cache SEQUENCE. ce_cachethis %d\n", __func__,
+ resp->cstate.slot->sl_cache_entry.ce_cachethis);
+ return;
+ }
+ entry->ce_resused = rqstp->rq_resused;
+ if (entry->ce_resused > NFSD_PAGES_PER_SLOT + 1)
+ entry->ce_resused = NFSD_PAGES_PER_SLOT + 1;
+ nfsd4_copy_pages(entry->ce_respages, rqstp->rq_respages,
+ entry->ce_resused);
+ entry->ce_datav.iov_base = resp->cstate.statp;
+ entry->ce_datav.iov_len = resv->iov_len - ((char *)resp->cstate.statp -
+ (char *)page_address(rqstp->rq_respages[0]));
+ /* Current request rpc header length*/
+ entry->ce_rpchdrlen = (char *)resp->cstate.statp -
+ (char *)page_address(rqstp->rq_respages[0]);
+}
+
+/*
+ * We keep the rpc header, but take the nfs reply from the replycache.
+ */
+static int
+nfsd41_copy_replay_data(struct nfsd4_compoundres *resp,
+ struct nfsd4_cache_entry *entry)
+{
+ struct svc_rqst *rqstp = resp->rqstp;
+ struct kvec *resv = &resp->rqstp->rq_res.head[0];
+ int len;
+
+ /* Current request rpc header length*/
+ len = (char *)resp->cstate.statp -
+ (char *)page_address(rqstp->rq_respages[0]);
+ if (entry->ce_datav.iov_len + len > PAGE_SIZE) {
+ dprintk("%s v41 cached reply too large (%Zd).\n", __func__,
+ entry->ce_datav.iov_len);
+ return 0;
+ }
+ /* copy the cached reply nfsd data past the current rpc header */
+ memcpy((char *)resv->iov_base + len, entry->ce_datav.iov_base,
+ entry->ce_datav.iov_len);
+ resv->iov_len = len + entry->ce_datav.iov_len;
+ return 1;
+}
+
+/*
+ * Keep the first page of the replay. Copy the NFSv4.1 data from the first
+ * cached page. Replace any futher replay pages from the cache.
+ */
+__be32
+nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
+ struct nfsd4_sequence *seq)
+{
+ struct nfsd4_cache_entry *entry = &resp->cstate.slot->sl_cache_entry;
+ __be32 status;
+
+ dprintk("--> %s entry %p\n", __func__, entry);
+
+ /*
+ * If this is just the sequence operation, we did not keep
+ * a page in the cache entry because we can just use the
+ * slot info stored in struct nfsd4_sequence that was checked
+ * against the slot in nfsd4_sequence().
+ *
+ * This occurs when seq->cachethis is FALSE, or when the client
+ * session inactivity timer fires and a solo sequence operation
+ * is sent (lease renewal).
+ */
+ if (seq && nfsd4_not_cached(resp)) {
+ seq->maxslots = resp->cstate.session->se_fnumslots;
+ return nfs_ok;
+ }
+
+ if (!nfsd41_copy_replay_data(resp, entry)) {
+ /*
+ * Not enough room to use the replay rpc header, send the
+ * cached header. Release all the allocated result pages.
+ */
+ svc_free_res_pages(resp->rqstp);
+ nfsd4_copy_pages(resp->rqstp->rq_respages, entry->ce_respages,
+ entry->ce_resused);
+ } else {
+ /* Release all but the first allocated result page */
+
+ resp->rqstp->rq_resused--;
+ svc_free_res_pages(resp->rqstp);
+
+ nfsd4_copy_pages(&resp->rqstp->rq_respages[1],
+ &entry->ce_respages[1],
+ entry->ce_resused - 1);
+ }
+
+ resp->rqstp->rq_resused = entry->ce_resused;
+ resp->opcnt = entry->ce_opcnt;
+ resp->cstate.iovlen = entry->ce_datav.iov_len + entry->ce_rpchdrlen;
+ status = entry->ce_status;
+
+ return status;
+}
+
+/*
+ * Set the exchange_id flags returned by the server.
+ */
+static void
+nfsd4_set_ex_flags(struct nfs4_client *new, struct nfsd4_exchange_id *clid)
+{
+ /* pNFS is not supported */
+ new->cl_exchange_flags |= EXCHGID4_FLAG_USE_NON_PNFS;
+
+ /* Referrals are supported, Migration is not. */
+ new->cl_exchange_flags |= EXCHGID4_FLAG_SUPP_MOVED_REFER;
+
+ /* set the wire flags to return to client. */
+ clid->flags = new->cl_exchange_flags;
+}
+
+__be32
+nfsd4_exchange_id(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *cstate,
+ struct nfsd4_exchange_id *exid)
+{
+ struct nfs4_client *unconf, *conf, *new;
+ int status;
+ unsigned int strhashval;
+ char dname[HEXDIR_LEN];
+ nfs4_verifier verf = exid->verifier;
+ u32 ip_addr = svc_addr_in(rqstp)->sin_addr.s_addr;
+
+ dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p "
+ " ip_addr=%u flags %x, spa_how %d\n",
+ __func__, rqstp, exid, exid->clname.len, exid->clname.data,
+ ip_addr, exid->flags, exid->spa_how);
+
+ if (!check_name(exid->clname) || (exid->flags & ~EXCHGID4_FLAG_MASK_A))
+ return nfserr_inval;
+
+ /* Currently only support SP4_NONE */
+ switch (exid->spa_how) {
+ case SP4_NONE:
+ break;
+ case SP4_SSV:
+ return nfserr_encr_alg_unsupp;
+ default:
+ BUG(); /* checked by xdr code */
+ case SP4_MACH_CRED:
+ return nfserr_serverfault; /* no excuse :-/ */
+ }
+
+ status = nfs4_make_rec_clidname(dname, &exid->clname);
+
+ if (status)
+ goto error;
+
+ strhashval = clientstr_hashval(dname);
+
+ nfs4_lock_state();
+ status = nfs_ok;
+
+ conf = find_confirmed_client_by_str(dname, strhashval, true);
+ if (conf) {
+ if (!same_verf(&verf, &conf->cl_verifier)) {
+ /* 18.35.4 case 8 */
+ if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) {
+ status = nfserr_not_same;
+ goto out;
+ }
+ /* Client reboot: destroy old state */
+ expire_client(conf);
+ goto out_new;
+ }
+ if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) {
+ /* 18.35.4 case 9 */
+ if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) {
+ status = nfserr_perm;
+ goto out;
+ }
+ expire_client(conf);
+ goto out_new;
+ }
+ if (ip_addr != conf->cl_addr &&
+ !(exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A)) {
+ /* Client collision. 18.35.4 case 3 */
+ status = nfserr_clid_inuse;
+ goto out;
+ }
+ /*
+ * Set bit when the owner id and verifier map to an already
+ * confirmed client id (18.35.3).
+ */
+ exid->flags |= EXCHGID4_FLAG_CONFIRMED_R;
+
+ /*
+ * Falling into 18.35.4 case 2, possible router replay.
+ * Leave confirmed record intact and return same result.
+ */
+ copy_verf(conf, &verf);
+ new = conf;
+ goto out_copy;
+ } else {
+ /* 18.35.4 case 7 */
+ if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) {
+ status = nfserr_noent;
+ goto out;
+ }
+ }
+
+ unconf = find_unconfirmed_client_by_str(dname, strhashval, true);
+ if (unconf) {
+ /*
+ * Possible retry or client restart. Per 18.35.4 case 4,
+ * a new unconfirmed record should be generated regardless
+ * of whether any properties have changed.
+ */
+ expire_client(unconf);
+ }
+
+out_new:
+ /* Normal case */
+ new = create_client(exid->clname, dname);
+ if (new == NULL) {
+ status = nfserr_resource;
+ goto out;
+ }
+
+ copy_verf(new, &verf);
+ copy_cred(&new->cl_cred, &rqstp->rq_cred);
+ new->cl_addr = ip_addr;
+ gen_clid(new);
+ gen_confirm(new);
+ add_to_unconfirmed(new, strhashval);
+out_copy:
+ exid->clientid.cl_boot = new->cl_clientid.cl_boot;
+ exid->clientid.cl_id = new->cl_clientid.cl_id;
+
+ new->cl_slot.sl_seqid = 0;
+ exid->seqid = 1;
+ nfsd4_set_ex_flags(new, exid);
+
+ dprintk("nfsd4_exchange_id seqid %d flags %x\n",
+ new->cl_slot.sl_seqid, new->cl_exchange_flags);
+ status = nfs_ok;
+
+out:
+ nfs4_unlock_state();
+error:
+ dprintk("nfsd4_exchange_id returns %d\n", ntohl(status));
+ return status;
+}
+
+static int
+check_slot_seqid(u32 seqid, struct nfsd4_slot *slot)
+{
+ dprintk("%s enter. seqid %d slot->sl_seqid %d\n", __func__, seqid,
+ slot->sl_seqid);
+
+ /* The slot is in use, and no response has been sent. */
+ if (slot->sl_inuse) {
+ if (seqid == slot->sl_seqid)
+ return nfserr_jukebox;
+ else
+ return nfserr_seq_misordered;
+ }
+ /* Normal */
+ if (likely(seqid == slot->sl_seqid + 1))
+ return nfs_ok;
+ /* Replay */
+ if (seqid == slot->sl_seqid)
+ return nfserr_replay_cache;
+ /* Wraparound */
+ if (seqid == 1 && (slot->sl_seqid + 1) == 0)
+ return nfs_ok;
+ /* Misordered replay or misordered new request */
+ return nfserr_seq_misordered;
+}
+
+__be32
+nfsd4_create_session(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *cstate,
+ struct nfsd4_create_session *cr_ses)
+{
+ u32 ip_addr = svc_addr_in(rqstp)->sin_addr.s_addr;
+ struct nfsd4_compoundres *resp = rqstp->rq_resp;
+ struct nfs4_client *conf, *unconf;
+ struct nfsd4_slot *slot = NULL;
+ int status = 0;
+
+ nfs4_lock_state();
+ unconf = find_unconfirmed_client(&cr_ses->clientid);
+ conf = find_confirmed_client(&cr_ses->clientid);
+
+ if (conf) {
+ slot = &conf->cl_slot;
+ status = check_slot_seqid(cr_ses->seqid, slot);
+ if (status == nfserr_replay_cache) {
+ dprintk("Got a create_session replay! seqid= %d\n",
+ slot->sl_seqid);
+ cstate->slot = slot;
+ cstate->status = status;
+ /* Return the cached reply status */
+ status = nfsd4_replay_cache_entry(resp, NULL);
+ goto out;
+ } else if (cr_ses->seqid != conf->cl_slot.sl_seqid + 1) {
+ status = nfserr_seq_misordered;
+ dprintk("Sequence misordered!\n");
+ dprintk("Expected seqid= %d but got seqid= %d\n",
+ slot->sl_seqid, cr_ses->seqid);
+ goto out;
+ }
+ conf->cl_slot.sl_seqid++;
+ } else if (unconf) {
+ if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) ||
+ (ip_addr != unconf->cl_addr)) {
+ status = nfserr_clid_inuse;
+ goto out;
+ }
+
+ slot = &unconf->cl_slot;
+ status = check_slot_seqid(cr_ses->seqid, slot);
+ if (status) {
+ /* an unconfirmed replay returns misordered */
+ status = nfserr_seq_misordered;
+ goto out;
+ }
+
+ slot->sl_seqid++; /* from 0 to 1 */
+ move_to_confirmed(unconf);
+
+ /*
+ * We do not support RDMA or persistent sessions
+ */
+ cr_ses->flags &= ~SESSION4_PERSIST;
+ cr_ses->flags &= ~SESSION4_RDMA;
+
+ conf = unconf;
+ } else {
+ status = nfserr_stale_clientid;
+ goto out;
+ }
+
+ status = alloc_init_session(rqstp, conf, cr_ses);
+ if (status)
+ goto out;
+
+ memcpy(cr_ses->sessionid.data, conf->cl_sessionid.data,
+ NFS4_MAX_SESSIONID_LEN);
+ cr_ses->seqid = slot->sl_seqid;
+
+ slot->sl_inuse = true;
+ cstate->slot = slot;
+ /* Ensure a page is used for the cache */
+ slot->sl_cache_entry.ce_cachethis = 1;
+out:
+ nfs4_unlock_state();
+ dprintk("%s returns %d\n", __func__, ntohl(status));
+ return status;
+}
+
+__be32
+nfsd4_destroy_session(struct svc_rqst *r,
+ struct nfsd4_compound_state *cstate,
+ struct nfsd4_destroy_session *sessionid)
+{
+ struct nfsd4_session *ses;
+ u32 status = nfserr_badsession;
+
+ /* Notes:
+ * - The confirmed nfs4_client->cl_sessionid holds destroyed sessinid
+ * - Should we return nfserr_back_chan_busy if waiting for
+ * callbacks on to-be-destroyed session?
+ * - Do we need to clear any callback info from previous session?
+ */
+
+ dump_sessionid(__func__, &sessionid->sessionid);
+ spin_lock(&sessionid_lock);
+ ses = find_in_sessionid_hashtbl(&sessionid->sessionid);
+ if (!ses) {
+ spin_unlock(&sessionid_lock);
+ goto out;
+ }
+
+ unhash_session(ses);
+ spin_unlock(&sessionid_lock);
+
+ /* wait for callbacks */
+ shutdown_callback_client(ses->se_client);
+ nfsd4_put_session(ses);
+ status = nfs_ok;
+out:
+ dprintk("%s returns %d\n", __func__, ntohl(status));
+ return status;
+}
+
+__be32
+nfsd4_sequence(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *cstate,
+ struct nfsd4_sequence *seq)
+{
+ struct nfsd4_compoundres *resp = rqstp->rq_resp;
+ struct nfsd4_session *session;
+ struct nfsd4_slot *slot;
+ int status;
+
+ if (resp->opcnt != 1)
+ return nfserr_sequence_pos;
+
+ spin_lock(&sessionid_lock);
+ status = nfserr_badsession;
+ session = find_in_sessionid_hashtbl(&seq->sessionid);
+ if (!session)
+ goto out;
+
+ status = nfserr_badslot;
+ if (seq->slotid >= session->se_fnumslots)
+ goto out;
+
+ slot = &session->se_slots[seq->slotid];
+ dprintk("%s: slotid %d\n", __func__, seq->slotid);
+
+ status = check_slot_seqid(seq->seqid, slot);
+ if (status == nfserr_replay_cache) {
+ cstate->slot = slot;
+ cstate->session = session;
+ /* Return the cached reply status and set cstate->status
+ * for nfsd4_svc_encode_compoundres processing */
+ status = nfsd4_replay_cache_entry(resp, seq);
+ cstate->status = nfserr_replay_cache;
+ goto replay_cache;
+ }
+ if (status)
+ goto out;
+
+ /* Success! bump slot seqid */
+ slot->sl_inuse = true;
+ slot->sl_seqid = seq->seqid;
+ slot->sl_cache_entry.ce_cachethis = seq->cachethis;
+ /* Always set the cache entry cachethis for solo sequence */
+ if (nfsd4_is_solo_sequence(resp))
+ slot->sl_cache_entry.ce_cachethis = 1;
+
+ cstate->slot = slot;
+ cstate->session = session;
+
+replay_cache:
+ /* Renew the clientid on success and on replay.
+ * Hold a session reference until done processing the compound:
+ * nfsd4_put_session called only if the cstate slot is set.
+ */
+ renew_client(session->se_client);
+ nfsd4_get_session(session);
+out:
+ spin_unlock(&sessionid_lock);
+ dprintk("%s: return %d\n", __func__, ntohl(status));
+ return status;
+}
+
__be32
nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct nfsd4_setclientid *setclid)
@@ -716,14 +1546,13 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
strhashval = clientstr_hashval(dname);
nfs4_lock_state();
- conf = find_confirmed_client_by_str(dname, strhashval);
+ conf = find_confirmed_client_by_str(dname, strhashval, false);
if (conf) {
/* RFC 3530 14.2.33 CASE 0: */
status = nfserr_clid_inuse;
- if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)
- || conf->cl_addr != sin->sin_addr.s_addr) {
- dprintk("NFSD: setclientid: string in use by clientat %pI4\n",
- &conf->cl_addr);
+ if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) {
+ dprintk("NFSD: setclientid: string in use by client"
+ " at %pI4\n", &conf->cl_addr);
goto out;
}
}
@@ -732,7 +1561,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
* has a description of SETCLIENTID request processing consisting
* of 5 bullet points, labeled as CASE0 - CASE4 below.
*/
- unconf = find_unconfirmed_client_by_str(dname, strhashval);
+ unconf = find_unconfirmed_client_by_str(dname, strhashval, false);
status = nfserr_resource;
if (!conf) {
/*
@@ -887,7 +1716,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
unsigned int hash =
clientstr_hashval(unconf->cl_recdir);
conf = find_confirmed_client_by_str(unconf->cl_recdir,
- hash);
+ hash, false);
if (conf) {
nfsd4_remove_clid_dir(conf);
expire_client(conf);
@@ -923,11 +1752,13 @@ alloc_init_file(struct inode *ino)
fp = kmem_cache_alloc(file_slab, GFP_KERNEL);
if (fp) {
- kref_init(&fp->fi_ref);
+ atomic_set(&fp->fi_ref, 1);
INIT_LIST_HEAD(&fp->fi_hash);
INIT_LIST_HEAD(&fp->fi_stateids);
INIT_LIST_HEAD(&fp->fi_delegations);
+ spin_lock(&recall_lock);
list_add(&fp->fi_hash, &file_hashtbl[hashval]);
+ spin_unlock(&recall_lock);
fp->fi_inode = igrab(ino);
fp->fi_id = current_fileid++;
fp->fi_had_conflict = false;
@@ -1037,48 +1868,6 @@ alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, str
return sop;
}
-static void
-release_stateid_lockowners(struct nfs4_stateid *open_stp)
-{
- struct nfs4_stateowner *lock_sop;
-
- while (!list_empty(&open_stp->st_lockowners)) {
- lock_sop = list_entry(open_stp->st_lockowners.next,
- struct nfs4_stateowner, so_perstateid);
- /* list_del(&open_stp->st_lockowners); */
- BUG_ON(lock_sop->so_is_open_owner);
- release_stateowner(lock_sop);
- }
-}
-
-static void
-unhash_stateowner(struct nfs4_stateowner *sop)
-{
- struct nfs4_stateid *stp;
-
- list_del(&sop->so_idhash);
- list_del(&sop->so_strhash);
- if (sop->so_is_open_owner)
- list_del(&sop->so_perclient);
- list_del(&sop->so_perstateid);
- while (!list_empty(&sop->so_stateids)) {
- stp = list_entry(sop->so_stateids.next,
- struct nfs4_stateid, st_perstateowner);
- if (sop->so_is_open_owner)
- release_stateid(stp, OPEN_STATE);
- else
- release_stateid(stp, LOCK_STATE);
- }
-}
-
-static void
-release_stateowner(struct nfs4_stateowner *sop)
-{
- unhash_stateowner(sop);
- list_del(&sop->so_close_lru);
- nfs4_put_stateowner(sop);
-}
-
static inline void
init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) {
struct nfs4_stateowner *sop = open->op_stateowner;
@@ -1100,30 +1889,13 @@ init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *
stp->st_stateid.si_generation = 0;
stp->st_access_bmap = 0;
stp->st_deny_bmap = 0;
- __set_bit(open->op_share_access, &stp->st_access_bmap);
+ __set_bit(open->op_share_access & ~NFS4_SHARE_WANT_MASK,
+ &stp->st_access_bmap);
__set_bit(open->op_share_deny, &stp->st_deny_bmap);
stp->st_openstp = NULL;
}
static void
-release_stateid(struct nfs4_stateid *stp, int flags)
-{
- struct file *filp = stp->st_vfs_file;
-
- list_del(&stp->st_hash);
- list_del(&stp->st_perfile);
- list_del(&stp->st_perstateowner);
- if (flags & OPEN_STATE) {
- release_stateid_lockowners(stp);
- stp->st_vfs_file = NULL;
- nfsd_close(filp);
- } else if (flags & LOCK_STATE)
- locks_remove_posix(filp, (fl_owner_t) stp->st_stateowner);
- put_nfs4_file(stp->st_file);
- kmem_cache_free(stateid_slab, stp);
-}
-
-static void
move_to_close_lru(struct nfs4_stateowner *sop)
{
dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop);
@@ -1160,20 +1932,33 @@ find_file(struct inode *ino)
unsigned int hashval = file_hashval(ino);
struct nfs4_file *fp;
+ spin_lock(&recall_lock);
list_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) {
if (fp->fi_inode == ino) {
get_nfs4_file(fp);
+ spin_unlock(&recall_lock);
return fp;
}
}
+ spin_unlock(&recall_lock);
return NULL;
}
-static inline int access_valid(u32 x)
+static inline int access_valid(u32 x, u32 minorversion)
{
- if (x < NFS4_SHARE_ACCESS_READ)
+ if ((x & NFS4_SHARE_ACCESS_MASK) < NFS4_SHARE_ACCESS_READ)
return 0;
- if (x > NFS4_SHARE_ACCESS_BOTH)
+ if ((x & NFS4_SHARE_ACCESS_MASK) > NFS4_SHARE_ACCESS_BOTH)
+ return 0;
+ x &= ~NFS4_SHARE_ACCESS_MASK;
+ if (minorversion && x) {
+ if ((x & NFS4_SHARE_WANT_MASK) > NFS4_SHARE_WANT_CANCEL)
+ return 0;
+ if ((x & NFS4_SHARE_WHEN_MASK) > NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED)
+ return 0;
+ x &= ~(NFS4_SHARE_WANT_MASK | NFS4_SHARE_WHEN_MASK);
+ }
+ if (x)
return 0;
return 1;
}
@@ -1409,7 +2194,8 @@ static struct lock_manager_operations nfsd_lease_mng_ops = {
__be32
-nfsd4_process_open1(struct nfsd4_open *open)
+nfsd4_process_open1(struct nfsd4_compound_state *cstate,
+ struct nfsd4_open *open)
{
clientid_t *clientid = &open->op_clientid;
struct nfs4_client *clp = NULL;
@@ -1432,10 +2218,13 @@ nfsd4_process_open1(struct nfsd4_open *open)
return nfserr_expired;
goto renew;
}
+ /* When sessions are used, skip open sequenceid processing */
+ if (nfsd4_has_session(cstate))
+ goto renew;
if (!sop->so_confirmed) {
/* Replace unconfirmed owners without checking for replay. */
clp = sop->so_client;
- release_stateowner(sop);
+ release_openowner(sop);
open->op_stateowner = NULL;
goto renew;
}
@@ -1709,6 +2498,7 @@ out:
__be32
nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
{
+ struct nfsd4_compoundres *resp = rqstp->rq_resp;
struct nfs4_file *fp = NULL;
struct inode *ino = current_fh->fh_dentry->d_inode;
struct nfs4_stateid *stp = NULL;
@@ -1716,7 +2506,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
__be32 status;
status = nfserr_inval;
- if (!access_valid(open->op_share_access)
+ if (!access_valid(open->op_share_access, resp->cstate.minorversion)
|| !deny_valid(open->op_share_deny))
goto out;
/*
@@ -1764,12 +2554,17 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
init_stateid(stp, fp, open);
status = nfsd4_truncate(rqstp, current_fh, open);
if (status) {
- release_stateid(stp, OPEN_STATE);
+ release_open_stateid(stp);
goto out;
}
+ if (nfsd4_has_session(&resp->cstate))
+ update_stateid(&stp->st_stateid);
}
memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
+ if (nfsd4_has_session(&resp->cstate))
+ open->op_stateowner->so_confirmed = 1;
+
/*
* Attempt to hand out a delegation. No error return, because the
* OPEN succeeds even if we fail.
@@ -1790,7 +2585,8 @@ out:
* To finish the open response, we just need to set the rflags.
*/
open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX;
- if (!open->op_stateowner->so_confirmed)
+ if (!open->op_stateowner->so_confirmed &&
+ !nfsd4_has_session(&resp->cstate))
open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM;
return status;
@@ -1898,7 +2694,7 @@ nfs4_laundromat(void)
}
dprintk("NFSD: purging unused open stateowner (so_id %d)\n",
sop->so_id);
- release_stateowner(sop);
+ release_openowner(sop);
}
if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT)
clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT;
@@ -1983,10 +2779,7 @@ out:
static inline __be32
check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
{
- /* Trying to call delegreturn with a special stateid? Yuch: */
- if (!(flags & (RD_STATE | WR_STATE)))
- return nfserr_bad_stateid;
- else if (ONE_STATEID(stateid) && (flags & RD_STATE))
+ if (ONE_STATEID(stateid) && (flags & RD_STATE))
return nfs_ok;
else if (locks_in_grace()) {
/* Answer in remaining cases depends on existance of
@@ -2005,14 +2798,20 @@ check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
* that are not able to provide mandatory locking.
*/
static inline int
-io_during_grace_disallowed(struct inode *inode, int flags)
+grace_disallows_io(struct inode *inode)
{
- return locks_in_grace() && (flags & (RD_STATE | WR_STATE))
- && mandatory_lock(inode);
+ return locks_in_grace() && mandatory_lock(inode);
}
-static int check_stateid_generation(stateid_t *in, stateid_t *ref)
+static int check_stateid_generation(stateid_t *in, stateid_t *ref, int flags)
{
+ /*
+ * When sessions are used the stateid generation number is ignored
+ * when it is zero.
+ */
+ if ((flags & HAS_SESSION) && in->si_generation == 0)
+ goto out;
+
/* If the client sends us a stateid from the future, it's buggy: */
if (in->si_generation > ref->si_generation)
return nfserr_bad_stateid;
@@ -2028,74 +2827,77 @@ static int check_stateid_generation(stateid_t *in, stateid_t *ref)
*/
if (in->si_generation < ref->si_generation)
return nfserr_old_stateid;
+out:
return nfs_ok;
}
+static int is_delegation_stateid(stateid_t *stateid)
+{
+ return stateid->si_fileid == 0;
+}
+
/*
* Checks for stateid operations
*/
__be32
-nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct file **filpp)
+nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
+ stateid_t *stateid, int flags, struct file **filpp)
{
struct nfs4_stateid *stp = NULL;
struct nfs4_delegation *dp = NULL;
- stateid_t *stidp;
+ struct svc_fh *current_fh = &cstate->current_fh;
struct inode *ino = current_fh->fh_dentry->d_inode;
__be32 status;
- dprintk("NFSD: preprocess_stateid_op: stateid = (%08x/%08x/%08x/%08x)\n",
- stateid->si_boot, stateid->si_stateownerid,
- stateid->si_fileid, stateid->si_generation);
if (filpp)
*filpp = NULL;
- if (io_during_grace_disallowed(ino, flags))
+ if (grace_disallows_io(ino))
return nfserr_grace;
+ if (nfsd4_has_session(cstate))
+ flags |= HAS_SESSION;
+
if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
return check_special_stateids(current_fh, stateid, flags);
- /* STALE STATEID */
status = nfserr_stale_stateid;
if (STALE_STATEID(stateid))
goto out;
- /* BAD STATEID */
status = nfserr_bad_stateid;
- if (!stateid->si_fileid) { /* delegation stateid */
- if(!(dp = find_delegation_stateid(ino, stateid))) {
- dprintk("NFSD: delegation stateid not found\n");
+ if (is_delegation_stateid(stateid)) {
+ dp = find_delegation_stateid(ino, stateid);
+ if (!dp)
goto out;
- }
- stidp = &dp->dl_stateid;
+ status = check_stateid_generation(stateid, &dp->dl_stateid,
+ flags);
+ if (status)
+ goto out;
+ status = nfs4_check_delegmode(dp, flags);
+ if (status)
+ goto out;
+ renew_client(dp->dl_client);
+ if (filpp)
+ *filpp = dp->dl_vfs_file;
} else { /* open or lock stateid */
- if (!(stp = find_stateid(stateid, flags))) {
- dprintk("NFSD: open or lock stateid not found\n");
+ stp = find_stateid(stateid, flags);
+ if (!stp)
goto out;
- }
- if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp))
+ if (nfs4_check_fh(current_fh, stp))
goto out;
if (!stp->st_stateowner->so_confirmed)
goto out;
- stidp = &stp->st_stateid;
- }
- status = check_stateid_generation(stateid, stidp);
- if (status)
- goto out;
- if (stp) {
- if ((status = nfs4_check_openmode(stp,flags)))
+ status = check_stateid_generation(stateid, &stp->st_stateid,
+ flags);
+ if (status)
+ goto out;
+ status = nfs4_check_openmode(stp, flags);
+ if (status)
goto out;
renew_client(stp->st_stateowner->so_client);
if (filpp)
*filpp = stp->st_vfs_file;
- } else {
- if ((status = nfs4_check_delegmode(dp, flags)))
- goto out;
- renew_client(dp->dl_client);
- if (flags & DELEG_RET)
- unhash_delegation(dp);
- if (filpp)
- *filpp = dp->dl_vfs_file;
}
status = nfs_ok;
out:
@@ -2113,10 +2915,14 @@ setlkflg (int type)
* Checks for sequence id mutating operations.
*/
static __be32
-nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, struct nfsd4_lock *lock)
+nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
+ stateid_t *stateid, int flags,
+ struct nfs4_stateowner **sopp,
+ struct nfs4_stateid **stpp, struct nfsd4_lock *lock)
{
struct nfs4_stateid *stp;
struct nfs4_stateowner *sop;
+ struct svc_fh *current_fh = &cstate->current_fh;
__be32 status;
dprintk("NFSD: preprocess_seqid_op: seqid=%d "
@@ -2134,6 +2940,10 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
if (STALE_STATEID(stateid))
return nfserr_stale_stateid;
+
+ if (nfsd4_has_session(cstate))
+ flags |= HAS_SESSION;
+
/*
* We return BAD_STATEID if filehandle doesn't match stateid,
* the confirmed flag is incorrecly set, or the generation
@@ -2166,8 +2976,9 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
if (lock->lk_is_new) {
if (!sop->so_is_open_owner)
return nfserr_bad_stateid;
- if (!same_clid(&clp->cl_clientid, lockclid))
- return nfserr_bad_stateid;
+ if (!(flags & HAS_SESSION) &&
+ !same_clid(&clp->cl_clientid, lockclid))
+ return nfserr_bad_stateid;
/* stp is the open stateid */
status = nfs4_check_openmode(stp, lkflg);
if (status)
@@ -2190,7 +3001,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
* For the moment, we ignore the possibility of
* generation number wraparound.
*/
- if (seqid != sop->so_seqid)
+ if (!(flags & HAS_SESSION) && seqid != sop->so_seqid)
goto check_replay;
if (sop->so_confirmed && flags & CONFIRM) {
@@ -2203,7 +3014,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
" confirmed yet!\n");
return nfserr_bad_stateid;
}
- status = check_stateid_generation(stateid, &stp->st_stateid);
+ status = check_stateid_generation(stateid, &stp->st_stateid, flags);
if (status)
return status;
renew_client(sop->so_client);
@@ -2239,7 +3050,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
nfs4_lock_state();
- if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh,
+ if ((status = nfs4_preprocess_seqid_op(cstate,
oc->oc_seqid, &oc->oc_req_stateid,
CONFIRM | OPEN_STATE,
&oc->oc_stateowner, &stp, NULL)))
@@ -2304,12 +3115,12 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
(int)cstate->current_fh.fh_dentry->d_name.len,
cstate->current_fh.fh_dentry->d_name.name);
- if (!access_valid(od->od_share_access)
+ if (!access_valid(od->od_share_access, cstate->minorversion)
|| !deny_valid(od->od_share_deny))
return nfserr_inval;
nfs4_lock_state();
- if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh,
+ if ((status = nfs4_preprocess_seqid_op(cstate,
od->od_seqid,
&od->od_stateid,
OPEN_STATE,
@@ -2362,7 +3173,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
nfs4_lock_state();
/* check close_lru for replay */
- if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh,
+ if ((status = nfs4_preprocess_seqid_op(cstate,
close->cl_seqid,
&close->cl_stateid,
OPEN_STATE | CLOSE_STATE,
@@ -2373,7 +3184,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t));
/* release_stateid() calls nfsd_close() if needed */
- release_stateid(stp, OPEN_STATE);
+ release_open_stateid(stp);
/* place unused nfs4_stateowners on so_close_lru list to be
* released by the laundromat service after the lease period
@@ -2394,16 +3205,40 @@ __be32
nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct nfsd4_delegreturn *dr)
{
+ struct nfs4_delegation *dp;
+ stateid_t *stateid = &dr->dr_stateid;
+ struct inode *inode;
__be32 status;
+ int flags = 0;
if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
- goto out;
+ return status;
+ inode = cstate->current_fh.fh_dentry->d_inode;
+ if (nfsd4_has_session(cstate))
+ flags |= HAS_SESSION;
nfs4_lock_state();
- status = nfs4_preprocess_stateid_op(&cstate->current_fh,
- &dr->dr_stateid, DELEG_RET, NULL);
- nfs4_unlock_state();
+ status = nfserr_bad_stateid;
+ if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
+ goto out;
+ status = nfserr_stale_stateid;
+ if (STALE_STATEID(stateid))
+ goto out;
+ status = nfserr_bad_stateid;
+ if (!is_delegation_stateid(stateid))
+ goto out;
+ dp = find_delegation_stateid(inode, stateid);
+ if (!dp)
+ goto out;
+ status = check_stateid_generation(stateid, &dp->dl_stateid, flags);
+ if (status)
+ goto out;
+ renew_client(dp->dl_client);
+
+ unhash_delegation(dp);
out:
+ nfs4_unlock_state();
+
return status;
}
@@ -2684,11 +3519,12 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct nfs4_file *fp;
status = nfserr_stale_clientid;
- if (STALE_CLIENTID(&lock->lk_new_clientid))
+ if (!nfsd4_has_session(cstate) &&
+ STALE_CLIENTID(&lock->lk_new_clientid))
goto out;
/* validate and update open stateid and open seqid */
- status = nfs4_preprocess_seqid_op(&cstate->current_fh,
+ status = nfs4_preprocess_seqid_op(cstate,
lock->lk_new_open_seqid,
&lock->lk_new_open_stateid,
OPEN_STATE,
@@ -2715,7 +3551,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
goto out;
} else {
/* lock (lock owner + lock stateid) already exists */
- status = nfs4_preprocess_seqid_op(&cstate->current_fh,
+ status = nfs4_preprocess_seqid_op(cstate,
lock->lk_old_lock_seqid,
&lock->lk_old_lock_stateid,
LOCK_STATE,
@@ -2788,7 +3624,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
}
out:
if (status && lock->lk_is_new && lock_sop)
- release_stateowner(lock_sop);
+ release_lockowner(lock_sop);
if (lock->lk_replay_owner) {
nfs4_get_stateowner(lock->lk_replay_owner);
cstate->replay_owner = lock->lk_replay_owner;
@@ -2838,7 +3674,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
nfs4_lock_state();
status = nfserr_stale_clientid;
- if (STALE_CLIENTID(&lockt->lt_clientid))
+ if (!nfsd4_has_session(cstate) && STALE_CLIENTID(&lockt->lt_clientid))
goto out;
if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) {
@@ -2911,7 +3747,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
nfs4_lock_state();
- if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh,
+ if ((status = nfs4_preprocess_seqid_op(cstate,
locku->lu_seqid,
&locku->lu_stateid,
LOCK_STATE,
@@ -3037,7 +3873,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
/* unhash_stateowner deletes so_perclient only
* for openowners. */
list_del(&sop->so_perclient);
- release_stateowner(sop);
+ release_lockowner(sop);
}
out:
nfs4_unlock_state();
@@ -3051,12 +3887,12 @@ alloc_reclaim(void)
}
int
-nfs4_has_reclaimed_state(const char *name)
+nfs4_has_reclaimed_state(const char *name, bool use_exchange_id)
{
unsigned int strhashval = clientstr_hashval(name);
struct nfs4_client *clp;
- clp = find_confirmed_client_by_str(name, strhashval);
+ clp = find_confirmed_client_by_str(name, strhashval, use_exchange_id);
return clp ? 1 : 0;
}
@@ -3153,6 +3989,8 @@ nfs4_state_init(void)
INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
}
+ for (i = 0; i < SESSION_HASH_SIZE; i++)
+ INIT_LIST_HEAD(&sessionid_hashtbl[i]);
for (i = 0; i < FILE_HASH_SIZE; i++) {
INIT_LIST_HEAD(&file_hashtbl[i]);
}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 9250067943d..b820c311931 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -45,6 +45,7 @@
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/vfs.h>
+#include <linux/utsname.h>
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/svc.h>
#include <linux/sunrpc/clnt.h>
@@ -188,6 +189,11 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
return p;
}
+static int zero_clientid(clientid_t *clid)
+{
+ return (clid->cl_boot == 0) && (clid->cl_id == 0);
+}
+
static int
defer_free(struct nfsd4_compoundargs *argp,
void (*release)(const void *), void *p)
@@ -230,6 +236,7 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
bmval[0] = 0;
bmval[1] = 0;
+ bmval[2] = 0;
READ_BUF(4);
READ32(bmlen);
@@ -241,13 +248,27 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
READ32(bmval[0]);
if (bmlen > 1)
READ32(bmval[1]);
+ if (bmlen > 2)
+ READ32(bmval[2]);
DECODE_TAIL;
}
+static u32 nfsd_attrmask[] = {
+ NFSD_WRITEABLE_ATTRS_WORD0,
+ NFSD_WRITEABLE_ATTRS_WORD1,
+ NFSD_WRITEABLE_ATTRS_WORD2
+};
+
+static u32 nfsd41_ex_attrmask[] = {
+ NFSD_SUPPATTR_EXCLCREAT_WORD0,
+ NFSD_SUPPATTR_EXCLCREAT_WORD1,
+ NFSD_SUPPATTR_EXCLCREAT_WORD2
+};
+
static __be32
-nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr,
- struct nfs4_acl **acl)
+nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable,
+ struct iattr *iattr, struct nfs4_acl **acl)
{
int expected_len, len = 0;
u32 dummy32;
@@ -263,9 +284,12 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
* According to spec, unsupported attributes return ERR_ATTRNOTSUPP;
* read-only attributes return ERR_INVAL.
*/
- if ((bmval[0] & ~NFSD_SUPPORTED_ATTRS_WORD0) || (bmval[1] & ~NFSD_SUPPORTED_ATTRS_WORD1))
+ if ((bmval[0] & ~nfsd_suppattrs0(argp->minorversion)) ||
+ (bmval[1] & ~nfsd_suppattrs1(argp->minorversion)) ||
+ (bmval[2] & ~nfsd_suppattrs2(argp->minorversion)))
return nfserr_attrnotsupp;
- if ((bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0) || (bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1))
+ if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1]) ||
+ (bmval[2] & ~writable[2]))
return nfserr_inval;
READ_BUF(4);
@@ -400,6 +424,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
goto xdr_error;
}
}
+ BUG_ON(bmval[2]); /* no such writeable attr supported yet */
if (len != expected_len)
goto xdr_error;
@@ -493,7 +518,9 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
if ((status = check_filename(create->cr_name, create->cr_namelen, nfserr_inval)))
return status;
- if ((status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr, &create->cr_acl)))
+ status = nfsd4_decode_fattr(argp, create->cr_bmval, nfsd_attrmask,
+ &create->cr_iattr, &create->cr_acl);
+ if (status)
goto out;
DECODE_TAIL;
@@ -583,6 +610,8 @@ nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
READ_BUF(lockt->lt_owner.len);
READMEM(lockt->lt_owner.data, lockt->lt_owner.len);
+ if (argp->minorversion && !zero_clientid(&lockt->lt_clientid))
+ return nfserr_inval;
DECODE_TAIL;
}
@@ -652,13 +681,26 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
switch (open->op_createmode) {
case NFS4_CREATE_UNCHECKED:
case NFS4_CREATE_GUARDED:
- if ((status = nfsd4_decode_fattr(argp, open->op_bmval, &open->op_iattr, &open->op_acl)))
+ status = nfsd4_decode_fattr(argp, open->op_bmval,
+ nfsd_attrmask, &open->op_iattr, &open->op_acl);
+ if (status)
goto out;
break;
case NFS4_CREATE_EXCLUSIVE:
READ_BUF(8);
COPYMEM(open->op_verf.data, 8);
break;
+ case NFS4_CREATE_EXCLUSIVE4_1:
+ if (argp->minorversion < 1)
+ goto xdr_error;
+ READ_BUF(8);
+ COPYMEM(open->op_verf.data, 8);
+ status = nfsd4_decode_fattr(argp, open->op_bmval,
+ nfsd41_ex_attrmask, &open->op_iattr,
+ &open->op_acl);
+ if (status)
+ goto out;
+ break;
default:
goto xdr_error;
}
@@ -851,7 +893,7 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
status = nfsd4_decode_stateid(argp, &setattr->sa_stateid);
if (status)
return status;
- return nfsd4_decode_fattr(argp, setattr->sa_bmval,
+ return nfsd4_decode_fattr(argp, setattr->sa_bmval, nfsd_attrmask,
&setattr->sa_iattr, &setattr->sa_acl);
}
@@ -993,6 +1035,241 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel
READ_BUF(rlockowner->rl_owner.len);
READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len);
+ if (argp->minorversion && !zero_clientid(&rlockowner->rl_clientid))
+ return nfserr_inval;
+ DECODE_TAIL;
+}
+
+static __be32
+nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
+ struct nfsd4_exchange_id *exid)
+{
+ int dummy;
+ DECODE_HEAD;
+
+ READ_BUF(NFS4_VERIFIER_SIZE);
+ COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
+
+ READ_BUF(4);
+ READ32(exid->clname.len);
+
+ READ_BUF(exid->clname.len);
+ SAVEMEM(exid->clname.data, exid->clname.len);
+
+ READ_BUF(4);
+ READ32(exid->flags);
+
+ /* Ignore state_protect4_a */
+ READ_BUF(4);
+ READ32(exid->spa_how);
+ switch (exid->spa_how) {
+ case SP4_NONE:
+ break;
+ case SP4_MACH_CRED:
+ /* spo_must_enforce */
+ READ_BUF(4);
+ READ32(dummy);
+ READ_BUF(dummy * 4);
+ p += dummy;
+
+ /* spo_must_allow */
+ READ_BUF(4);
+ READ32(dummy);
+ READ_BUF(dummy * 4);
+ p += dummy;
+ break;
+ case SP4_SSV:
+ /* ssp_ops */
+ READ_BUF(4);
+ READ32(dummy);
+ READ_BUF(dummy * 4);
+ p += dummy;
+
+ READ_BUF(4);
+ READ32(dummy);
+ READ_BUF(dummy * 4);
+ p += dummy;
+
+ /* ssp_hash_algs<> */
+ READ_BUF(4);
+ READ32(dummy);
+ READ_BUF(dummy);
+ p += XDR_QUADLEN(dummy);
+
+ /* ssp_encr_algs<> */
+ READ_BUF(4);
+ READ32(dummy);
+ READ_BUF(dummy);
+ p += XDR_QUADLEN(dummy);
+
+ /* ssp_window and ssp_num_gss_handles */
+ READ_BUF(8);
+ READ32(dummy);
+ READ32(dummy);
+ break;
+ default:
+ goto xdr_error;
+ }
+
+ /* Ignore Implementation ID */
+ READ_BUF(4); /* nfs_impl_id4 array length */
+ READ32(dummy);
+
+ if (dummy > 1)
+ goto xdr_error;
+
+ if (dummy == 1) {
+ /* nii_domain */
+ READ_BUF(4);
+ READ32(dummy);
+ READ_BUF(dummy);
+ p += XDR_QUADLEN(dummy);
+
+ /* nii_name */
+ READ_BUF(4);
+ READ32(dummy);
+ READ_BUF(dummy);
+ p += XDR_QUADLEN(dummy);
+
+ /* nii_date */
+ READ_BUF(12);
+ p += 3;
+ }
+ DECODE_TAIL;
+}
+
+static __be32
+nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
+ struct nfsd4_create_session *sess)
+{
+ DECODE_HEAD;
+
+ u32 dummy;
+ char *machine_name;
+ int i;
+ int nr_secflavs;
+
+ READ_BUF(16);
+ COPYMEM(&sess->clientid, 8);
+ READ32(sess->seqid);
+ READ32(sess->flags);
+
+ /* Fore channel attrs */
+ READ_BUF(28);
+ READ32(dummy); /* headerpadsz is always 0 */
+ READ32(sess->fore_channel.maxreq_sz);
+ READ32(sess->fore_channel.maxresp_sz);
+ READ32(sess->fore_channel.maxresp_cached);
+ READ32(sess->fore_channel.maxops);
+ READ32(sess->fore_channel.maxreqs);
+ READ32(sess->fore_channel.nr_rdma_attrs);
+ if (sess->fore_channel.nr_rdma_attrs == 1) {
+ READ_BUF(4);
+ READ32(sess->fore_channel.rdma_attrs);
+ } else if (sess->fore_channel.nr_rdma_attrs > 1) {
+ dprintk("Too many fore channel attr bitmaps!\n");
+ goto xdr_error;
+ }
+
+ /* Back channel attrs */
+ READ_BUF(28);
+ READ32(dummy); /* headerpadsz is always 0 */
+ READ32(sess->back_channel.maxreq_sz);
+ READ32(sess->back_channel.maxresp_sz);
+ READ32(sess->back_channel.maxresp_cached);
+ READ32(sess->back_channel.maxops);
+ READ32(sess->back_channel.maxreqs);
+ READ32(sess->back_channel.nr_rdma_attrs);
+ if (sess->back_channel.nr_rdma_attrs == 1) {
+ READ_BUF(4);
+ READ32(sess->back_channel.rdma_attrs);
+ } else if (sess->back_channel.nr_rdma_attrs > 1) {
+ dprintk("Too many back channel attr bitmaps!\n");
+ goto xdr_error;
+ }
+
+ READ_BUF(8);
+ READ32(sess->callback_prog);
+
+ /* callback_sec_params4 */
+ READ32(nr_secflavs);
+ for (i = 0; i < nr_secflavs; ++i) {
+ READ_BUF(4);
+ READ32(dummy);
+ switch (dummy) {
+ case RPC_AUTH_NULL:
+ /* Nothing to read */
+ break;
+ case RPC_AUTH_UNIX:
+ READ_BUF(8);
+ /* stamp */
+ READ32(dummy);
+
+ /* machine name */
+ READ32(dummy);
+ READ_BUF(dummy);
+ SAVEMEM(machine_name, dummy);
+
+ /* uid, gid */
+ READ_BUF(8);
+ READ32(sess->uid);
+ READ32(sess->gid);
+
+ /* more gids */
+ READ_BUF(4);
+ READ32(dummy);
+ READ_BUF(dummy * 4);
+ for (i = 0; i < dummy; ++i)
+ READ32(dummy);
+ break;
+ case RPC_AUTH_GSS:
+ dprintk("RPC_AUTH_GSS callback secflavor "
+ "not supported!\n");
+ READ_BUF(8);
+ /* gcbp_service */
+ READ32(dummy);
+ /* gcbp_handle_from_server */
+ READ32(dummy);
+ READ_BUF(dummy);
+ p += XDR_QUADLEN(dummy);
+ /* gcbp_handle_from_client */
+ READ_BUF(4);
+ READ32(dummy);
+ READ_BUF(dummy);
+ p += XDR_QUADLEN(dummy);
+ break;
+ default:
+ dprintk("Illegal callback secflavor\n");
+ return nfserr_inval;
+ }
+ }
+ DECODE_TAIL;
+}
+
+static __be32
+nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp,
+ struct nfsd4_destroy_session *destroy_session)
+{
+ DECODE_HEAD;
+ READ_BUF(NFS4_MAX_SESSIONID_LEN);
+ COPYMEM(destroy_session->sessionid.data, NFS4_MAX_SESSIONID_LEN);
+
+ DECODE_TAIL;
+}
+
+static __be32
+nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
+ struct nfsd4_sequence *seq)
+{
+ DECODE_HEAD;
+
+ READ_BUF(NFS4_MAX_SESSIONID_LEN + 16);
+ COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
+ READ32(seq->seqid);
+ READ32(seq->slotid);
+ READ32(seq->maxslots);
+ READ32(seq->cachethis);
+
DECODE_TAIL;
}
@@ -1005,7 +1282,7 @@ nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
static __be32
nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p)
{
- return nfserr_opnotsupp;
+ return nfserr_notsupp;
}
typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *);
@@ -1031,7 +1308,7 @@ static nfsd4_dec nfsd4_dec_ops[] = {
[OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm,
[OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade,
[OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh,
- [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_noop,
[OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop,
[OP_READ] = (nfsd4_dec)nfsd4_decode_read,
[OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir,
@@ -1050,6 +1327,67 @@ static nfsd4_dec nfsd4_dec_ops[] = {
[OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner,
};
+static nfsd4_dec nfsd41_dec_ops[] = {
+ [OP_ACCESS] (nfsd4_dec)nfsd4_decode_access,
+ [OP_CLOSE] (nfsd4_dec)nfsd4_decode_close,
+ [OP_COMMIT] (nfsd4_dec)nfsd4_decode_commit,
+ [OP_CREATE] (nfsd4_dec)nfsd4_decode_create,
+ [OP_DELEGPURGE] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_DELEGRETURN] (nfsd4_dec)nfsd4_decode_delegreturn,
+ [OP_GETATTR] (nfsd4_dec)nfsd4_decode_getattr,
+ [OP_GETFH] (nfsd4_dec)nfsd4_decode_noop,
+ [OP_LINK] (nfsd4_dec)nfsd4_decode_link,
+ [OP_LOCK] (nfsd4_dec)nfsd4_decode_lock,
+ [OP_LOCKT] (nfsd4_dec)nfsd4_decode_lockt,
+ [OP_LOCKU] (nfsd4_dec)nfsd4_decode_locku,
+ [OP_LOOKUP] (nfsd4_dec)nfsd4_decode_lookup,
+ [OP_LOOKUPP] (nfsd4_dec)nfsd4_decode_noop,
+ [OP_NVERIFY] (nfsd4_dec)nfsd4_decode_verify,
+ [OP_OPEN] (nfsd4_dec)nfsd4_decode_open,
+ [OP_OPENATTR] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_OPEN_CONFIRM] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_OPEN_DOWNGRADE] (nfsd4_dec)nfsd4_decode_open_downgrade,
+ [OP_PUTFH] (nfsd4_dec)nfsd4_decode_putfh,
+ [OP_PUTPUBFH] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_PUTROOTFH] (nfsd4_dec)nfsd4_decode_noop,
+ [OP_READ] (nfsd4_dec)nfsd4_decode_read,
+ [OP_READDIR] (nfsd4_dec)nfsd4_decode_readdir,
+ [OP_READLINK] (nfsd4_dec)nfsd4_decode_noop,
+ [OP_REMOVE] (nfsd4_dec)nfsd4_decode_remove,
+ [OP_RENAME] (nfsd4_dec)nfsd4_decode_rename,
+ [OP_RENEW] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_RESTOREFH] (nfsd4_dec)nfsd4_decode_noop,
+ [OP_SAVEFH] (nfsd4_dec)nfsd4_decode_noop,
+ [OP_SECINFO] (nfsd4_dec)nfsd4_decode_secinfo,
+ [OP_SETATTR] (nfsd4_dec)nfsd4_decode_setattr,
+ [OP_SETCLIENTID] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_SETCLIENTID_CONFIRM](nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_VERIFY] (nfsd4_dec)nfsd4_decode_verify,
+ [OP_WRITE] (nfsd4_dec)nfsd4_decode_write,
+ [OP_RELEASE_LOCKOWNER] (nfsd4_dec)nfsd4_decode_notsupp,
+
+ /* new operations for NFSv4.1 */
+ [OP_BACKCHANNEL_CTL] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_BIND_CONN_TO_SESSION](nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_EXCHANGE_ID] (nfsd4_dec)nfsd4_decode_exchange_id,
+ [OP_CREATE_SESSION] (nfsd4_dec)nfsd4_decode_create_session,
+ [OP_DESTROY_SESSION] (nfsd4_dec)nfsd4_decode_destroy_session,
+ [OP_FREE_STATEID] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_GET_DIR_DELEGATION] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_GETDEVICEINFO] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_GETDEVICELIST] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_LAYOUTCOMMIT] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_LAYOUTGET] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_LAYOUTRETURN] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_SECINFO_NO_NAME] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_SEQUENCE] (nfsd4_dec)nfsd4_decode_sequence,
+ [OP_SET_SSV] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_TEST_STATEID] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_WANT_DELEGATION] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_DESTROY_CLIENTID] (nfsd4_dec)nfsd4_decode_notsupp,
+ [OP_RECLAIM_COMPLETE] (nfsd4_dec)nfsd4_decode_notsupp,
+};
+
struct nfsd4_minorversion_ops {
nfsd4_dec *decoders;
int nops;
@@ -1057,6 +1395,7 @@ struct nfsd4_minorversion_ops {
static struct nfsd4_minorversion_ops nfsd4_minorversion[] = {
[0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) },
+ [1] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) },
};
static __be32
@@ -1412,6 +1751,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
{
u32 bmval0 = bmval[0];
u32 bmval1 = bmval[1];
+ u32 bmval2 = bmval[2];
struct kstat stat;
struct svc_fh tempfh;
struct kstatfs statfs;
@@ -1425,12 +1765,16 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
int err;
int aclsupport = 0;
struct nfs4_acl *acl = NULL;
+ struct nfsd4_compoundres *resp = rqstp->rq_resp;
+ u32 minorversion = resp->cstate.minorversion;
BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
- BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0);
- BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1);
+ BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion));
+ BUG_ON(bmval1 & ~nfsd_suppattrs1(minorversion));
+ BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion));
if (exp->ex_fslocs.migrated) {
+ BUG_ON(bmval[2]);
status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err);
if (status)
goto out;
@@ -1476,22 +1820,42 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
if ((buflen -= 16) < 0)
goto out_resource;
- WRITE32(2);
- WRITE32(bmval0);
- WRITE32(bmval1);
+ if (unlikely(bmval2)) {
+ WRITE32(3);
+ WRITE32(bmval0);
+ WRITE32(bmval1);
+ WRITE32(bmval2);
+ } else if (likely(bmval1)) {
+ WRITE32(2);
+ WRITE32(bmval0);
+ WRITE32(bmval1);
+ } else {
+ WRITE32(1);
+ WRITE32(bmval0);
+ }
attrlenp = p++; /* to be backfilled later */
if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
- u32 word0 = NFSD_SUPPORTED_ATTRS_WORD0;
+ u32 word0 = nfsd_suppattrs0(minorversion);
+ u32 word1 = nfsd_suppattrs1(minorversion);
+ u32 word2 = nfsd_suppattrs2(minorversion);
+
if ((buflen -= 12) < 0)
goto out_resource;
if (!aclsupport)
word0 &= ~FATTR4_WORD0_ACL;
if (!exp->ex_fslocs.locations)
word0 &= ~FATTR4_WORD0_FS_LOCATIONS;
- WRITE32(2);
- WRITE32(word0);
- WRITE32(NFSD_SUPPORTED_ATTRS_WORD1);
+ if (!word2) {
+ WRITE32(2);
+ WRITE32(word0);
+ WRITE32(word1);
+ } else {
+ WRITE32(3);
+ WRITE32(word0);
+ WRITE32(word1);
+ WRITE32(word2);
+ }
}
if (bmval0 & FATTR4_WORD0_TYPE) {
if ((buflen -= 4) < 0)
@@ -1801,6 +2165,13 @@ out_acl:
}
WRITE64(stat.ino);
}
+ if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
+ WRITE32(3);
+ WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0);
+ WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD1);
+ WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD2);
+ }
+
*attrlenp = htonl((char *)p - (char *)attrlenp - 4);
*countp = p - buffer;
status = nfs_ok;
@@ -2572,6 +2943,143 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_w
}
static __be32
+nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr,
+ struct nfsd4_exchange_id *exid)
+{
+ ENCODE_HEAD;
+ char *major_id;
+ char *server_scope;
+ int major_id_sz;
+ int server_scope_sz;
+ uint64_t minor_id = 0;
+
+ if (nfserr)
+ return nfserr;
+
+ major_id = utsname()->nodename;
+ major_id_sz = strlen(major_id);
+ server_scope = utsname()->nodename;
+ server_scope_sz = strlen(server_scope);
+
+ RESERVE_SPACE(
+ 8 /* eir_clientid */ +
+ 4 /* eir_sequenceid */ +
+ 4 /* eir_flags */ +
+ 4 /* spr_how (SP4_NONE) */ +
+ 8 /* so_minor_id */ +
+ 4 /* so_major_id.len */ +
+ (XDR_QUADLEN(major_id_sz) * 4) +
+ 4 /* eir_server_scope.len */ +
+ (XDR_QUADLEN(server_scope_sz) * 4) +
+ 4 /* eir_server_impl_id.count (0) */);
+
+ WRITEMEM(&exid->clientid, 8);
+ WRITE32(exid->seqid);
+ WRITE32(exid->flags);
+
+ /* state_protect4_r. Currently only support SP4_NONE */
+ BUG_ON(exid->spa_how != SP4_NONE);
+ WRITE32(exid->spa_how);
+
+ /* The server_owner struct */
+ WRITE64(minor_id); /* Minor id */
+ /* major id */
+ WRITE32(major_id_sz);
+ WRITEMEM(major_id, major_id_sz);
+
+ /* Server scope */
+ WRITE32(server_scope_sz);
+ WRITEMEM(server_scope, server_scope_sz);
+
+ /* Implementation id */
+ WRITE32(0); /* zero length nfs_impl_id4 array */
+ ADJUST_ARGS();
+ return 0;
+}
+
+static __be32
+nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr,
+ struct nfsd4_create_session *sess)
+{
+ ENCODE_HEAD;
+
+ if (nfserr)
+ return nfserr;
+
+ RESERVE_SPACE(24);
+ WRITEMEM(sess->sessionid.data, NFS4_MAX_SESSIONID_LEN);
+ WRITE32(sess->seqid);
+ WRITE32(sess->flags);
+ ADJUST_ARGS();
+
+ RESERVE_SPACE(28);
+ WRITE32(0); /* headerpadsz */
+ WRITE32(sess->fore_channel.maxreq_sz);
+ WRITE32(sess->fore_channel.maxresp_sz);
+ WRITE32(sess->fore_channel.maxresp_cached);
+ WRITE32(sess->fore_channel.maxops);
+ WRITE32(sess->fore_channel.maxreqs);
+ WRITE32(sess->fore_channel.nr_rdma_attrs);
+ ADJUST_ARGS();
+
+ if (sess->fore_channel.nr_rdma_attrs) {
+ RESERVE_SPACE(4);
+ WRITE32(sess->fore_channel.rdma_attrs);
+ ADJUST_ARGS();
+ }
+
+ RESERVE_SPACE(28);
+ WRITE32(0); /* headerpadsz */
+ WRITE32(sess->back_channel.maxreq_sz);
+ WRITE32(sess->back_channel.maxresp_sz);
+ WRITE32(sess->back_channel.maxresp_cached);
+ WRITE32(sess->back_channel.maxops);
+ WRITE32(sess->back_channel.maxreqs);
+ WRITE32(sess->back_channel.nr_rdma_attrs);
+ ADJUST_ARGS();
+
+ if (sess->back_channel.nr_rdma_attrs) {
+ RESERVE_SPACE(4);
+ WRITE32(sess->back_channel.rdma_attrs);
+ ADJUST_ARGS();
+ }
+ return 0;
+}
+
+static __be32
+nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr,
+ struct nfsd4_destroy_session *destroy_session)
+{
+ return nfserr;
+}
+
+__be32
+nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
+ struct nfsd4_sequence *seq)
+{
+ ENCODE_HEAD;
+
+ if (nfserr)
+ return nfserr;
+
+ RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 20);
+ WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
+ WRITE32(seq->seqid);
+ WRITE32(seq->slotid);
+ WRITE32(seq->maxslots);
+ /*
+ * FIXME: for now:
+ * target_maxslots = maxslots
+ * status_flags = 0
+ */
+ WRITE32(seq->maxslots);
+ WRITE32(0);
+
+ ADJUST_ARGS();
+ return 0;
+}
+
+static __be32
nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
{
return nfserr;
@@ -2579,6 +3087,11 @@ nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
+/*
+ * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1
+ * since we don't need to filter out obsolete ops as this is
+ * done in the decoding phase.
+ */
static nfsd4_enc nfsd4_enc_ops[] = {
[OP_ACCESS] = (nfsd4_enc)nfsd4_encode_access,
[OP_CLOSE] = (nfsd4_enc)nfsd4_encode_close,
@@ -2617,8 +3130,77 @@ static nfsd4_enc nfsd4_enc_ops[] = {
[OP_VERIFY] = (nfsd4_enc)nfsd4_encode_noop,
[OP_WRITE] = (nfsd4_enc)nfsd4_encode_write,
[OP_RELEASE_LOCKOWNER] = (nfsd4_enc)nfsd4_encode_noop,
+
+ /* NFSv4.1 operations */
+ [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id,
+ [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session,
+ [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_destroy_session,
+ [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence,
+ [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_WANT_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_DESTROY_CLIENTID] = (nfsd4_enc)nfsd4_encode_noop,
+ [OP_RECLAIM_COMPLETE] = (nfsd4_enc)nfsd4_encode_noop,
};
+/*
+ * Calculate the total amount of memory that the compound response has taken
+ * after encoding the current operation.
+ *
+ * pad: add on 8 bytes for the next operation's op_code and status so that
+ * there is room to cache a failure on the next operation.
+ *
+ * Compare this length to the session se_fmaxresp_cached.
+ *
+ * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so
+ * will be at least a page and will therefore hold the xdr_buf head.
+ */
+static int nfsd4_check_drc_limit(struct nfsd4_compoundres *resp)
+{
+ int status = 0;
+ struct xdr_buf *xb = &resp->rqstp->rq_res;
+ struct nfsd4_compoundargs *args = resp->rqstp->rq_argp;
+ struct nfsd4_session *session = NULL;
+ struct nfsd4_slot *slot = resp->cstate.slot;
+ u32 length, tlen = 0, pad = 8;
+
+ if (!nfsd4_has_session(&resp->cstate))
+ return status;
+
+ session = resp->cstate.session;
+ if (session == NULL || slot->sl_cache_entry.ce_cachethis == 0)
+ return status;
+
+ if (resp->opcnt >= args->opcnt)
+ pad = 0; /* this is the last operation */
+
+ if (xb->page_len == 0) {
+ length = (char *)resp->p - (char *)xb->head[0].iov_base + pad;
+ } else {
+ if (xb->tail[0].iov_base && xb->tail[0].iov_len > 0)
+ tlen = (char *)resp->p - (char *)xb->tail[0].iov_base;
+
+ length = xb->head[0].iov_len + xb->page_len + tlen + pad;
+ }
+ dprintk("%s length %u, xb->page_len %u tlen %u pad %u\n", __func__,
+ length, xb->page_len, tlen, pad);
+
+ if (length <= session->se_fmaxresp_cached)
+ return status;
+ else
+ return nfserr_rep_too_big_to_cache;
+}
+
void
nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
{
@@ -2635,6 +3217,9 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
!nfsd4_enc_ops[op->opnum]);
op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u);
+ /* nfsd4_check_drc_limit guarantees enough room for error status */
+ if (!op->status && nfsd4_check_drc_limit(resp))
+ op->status = nfserr_rep_too_big_to_cache;
status:
/*
* Note: We write the status directly, instead of using WRITE32(),
@@ -2735,6 +3320,18 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo
iov = &rqstp->rq_res.head[0];
iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base;
BUG_ON(iov->iov_len > PAGE_SIZE);
+ if (nfsd4_has_session(&resp->cstate)) {
+ if (resp->cstate.status == nfserr_replay_cache &&
+ !nfsd4_not_cached(resp)) {
+ iov->iov_len = resp->cstate.iovlen;
+ } else {
+ nfsd4_store_cache_entry(resp);
+ dprintk("%s: SET SLOT STATE TO AVAILABLE\n", __func__);
+ resp->cstate.slot->sl_inuse = 0;
+ }
+ if (resp->cstate.session)
+ nfsd4_put_session(resp->cstate.session);
+ }
return 1;
}
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index a4ed8644d69..af16849d243 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -60,6 +60,7 @@ enum {
NFSD_FO_UnlockFS,
NFSD_Threads,
NFSD_Pool_Threads,
+ NFSD_Pool_Stats,
NFSD_Versions,
NFSD_Ports,
NFSD_MaxBlkSize,
@@ -172,6 +173,16 @@ static const struct file_operations exports_operations = {
.owner = THIS_MODULE,
};
+extern int nfsd_pool_stats_open(struct inode *inode, struct file *file);
+
+static struct file_operations pool_stats_operations = {
+ .open = nfsd_pool_stats_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+ .owner = THIS_MODULE,
+};
+
/*----------------------------------------------------------------------------*/
/*
* payload - write methods
@@ -781,8 +792,9 @@ out_free:
static ssize_t __write_versions(struct file *file, char *buf, size_t size)
{
char *mesg = buf;
- char *vers, sign;
+ char *vers, *minorp, sign;
int len, num;
+ unsigned minor;
ssize_t tlen = 0;
char *sep;
@@ -803,9 +815,20 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
do {
sign = *vers;
if (sign == '+' || sign == '-')
- num = simple_strtol((vers+1), NULL, 0);
+ num = simple_strtol((vers+1), &minorp, 0);
else
- num = simple_strtol(vers, NULL, 0);
+ num = simple_strtol(vers, &minorp, 0);
+ if (*minorp == '.') {
+ if (num < 4)
+ return -EINVAL;
+ minor = simple_strtoul(minorp+1, NULL, 0);
+ if (minor == 0)
+ return -EINVAL;
+ if (nfsd_minorversion(minor, sign == '-' ?
+ NFSD_CLEAR : NFSD_SET) < 0)
+ return -EINVAL;
+ goto next;
+ }
switch(num) {
case 2:
case 3:
@@ -815,6 +838,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
default:
return -EINVAL;
}
+ next:
vers += len + 1;
tlen += len;
} while ((len = qword_get(&mesg, vers, size)) > 0);
@@ -833,6 +857,13 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
num);
sep = " ";
}
+ if (nfsd_vers(4, NFSD_AVAIL))
+ for (minor = 1; minor <= NFSD_SUPPORTED_MINOR_VERSION; minor++)
+ len += sprintf(buf+len, " %c4.%u",
+ (nfsd_vers(4, NFSD_TEST) &&
+ nfsd_minorversion(minor, NFSD_TEST)) ?
+ '+' : '-',
+ minor);
len += sprintf(buf+len, "\n");
return len;
}
@@ -1248,6 +1279,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
+ [NFSD_Pool_Stats] = {"pool_stats", &pool_stats_operations, S_IRUGO},
[NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
[NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 6f7f2635122..e298e260b5f 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -180,6 +180,7 @@ nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp,
{
__be32 nfserr;
int stable = 1;
+ unsigned long cnt = argp->len;
dprintk("nfsd: WRITE %s %d bytes at %d\n",
SVCFH_fmt(&argp->fh),
@@ -188,7 +189,7 @@ nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp,
nfserr = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh), NULL,
argp->offset,
rqstp->rq_vec, argp->vlen,
- argp->len,
+ &cnt,
&stable);
return nfsd_return_attrs(nfserr, resp);
}
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 7c09852be71..cbba4a93578 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -22,6 +22,7 @@
#include <linux/freezer.h>
#include <linux/fs_struct.h>
#include <linux/kthread.h>
+#include <linux/swap.h>
#include <linux/sunrpc/types.h>
#include <linux/sunrpc/stats.h>
@@ -40,9 +41,6 @@
extern struct svc_program nfsd_program;
static int nfsd(void *vrqstp);
struct timeval nfssvc_boot;
-static atomic_t nfsd_busy;
-static unsigned long nfsd_last_call;
-static DEFINE_SPINLOCK(nfsd_call_lock);
/*
* nfsd_mutex protects nfsd_serv -- both the pointer itself and the members
@@ -123,6 +121,8 @@ struct svc_program nfsd_program = {
};
+u32 nfsd_supported_minorversion;
+
int nfsd_vers(int vers, enum vers_op change)
{
if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
@@ -149,6 +149,28 @@ int nfsd_vers(int vers, enum vers_op change)
}
return 0;
}
+
+int nfsd_minorversion(u32 minorversion, enum vers_op change)
+{
+ if (minorversion > NFSD_SUPPORTED_MINOR_VERSION)
+ return -1;
+ switch(change) {
+ case NFSD_SET:
+ nfsd_supported_minorversion = minorversion;
+ break;
+ case NFSD_CLEAR:
+ if (minorversion == 0)
+ return -1;
+ nfsd_supported_minorversion = minorversion - 1;
+ break;
+ case NFSD_TEST:
+ return minorversion <= nfsd_supported_minorversion;
+ case NFSD_AVAIL:
+ return minorversion <= NFSD_SUPPORTED_MINOR_VERSION;
+ }
+ return 0;
+}
+
/*
* Maximum number of nfsd processes
*/
@@ -200,6 +222,28 @@ void nfsd_reset_versions(void)
}
}
+/*
+ * Each session guarantees a negotiated per slot memory cache for replies
+ * which in turn consumes memory beyond the v2/v3/v4.0 server. A dedicated
+ * NFSv4.1 server might want to use more memory for a DRC than a machine
+ * with mutiple services.
+ *
+ * Impose a hard limit on the number of pages for the DRC which varies
+ * according to the machines free pages. This is of course only a default.
+ *
+ * For now this is a #defined shift which could be under admin control
+ * in the future.
+ */
+static void set_max_drc(void)
+{
+ /* The percent of nr_free_buffer_pages used by the V4.1 server DRC */
+ #define NFSD_DRC_SIZE_SHIFT 7
+ nfsd_serv->sv_drc_max_pages = nr_free_buffer_pages()
+ >> NFSD_DRC_SIZE_SHIFT;
+ nfsd_serv->sv_drc_pages_used = 0;
+ dprintk("%s svc_drc_max_pages %u\n", __func__,
+ nfsd_serv->sv_drc_max_pages);
+}
int nfsd_create_serv(void)
{
@@ -227,11 +271,12 @@ int nfsd_create_serv(void)
nfsd_max_blksize /= 2;
}
- atomic_set(&nfsd_busy, 0);
nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
nfsd_last_thread, nfsd, THIS_MODULE);
if (nfsd_serv == NULL)
err = -ENOMEM;
+ else
+ set_max_drc();
do_gettimeofday(&nfssvc_boot); /* record boot time */
return err;
@@ -375,26 +420,6 @@ nfsd_svc(unsigned short port, int nrservs)
return error;
}
-static inline void
-update_thread_usage(int busy_threads)
-{
- unsigned long prev_call;
- unsigned long diff;
- int decile;
-
- spin_lock(&nfsd_call_lock);
- prev_call = nfsd_last_call;
- nfsd_last_call = jiffies;
- decile = busy_threads*10/nfsdstats.th_cnt;
- if (decile>0 && decile <= 10) {
- diff = nfsd_last_call - prev_call;
- if ( (nfsdstats.th_usage[decile-1] += diff) >= NFSD_USAGE_WRAP)
- nfsdstats.th_usage[decile-1] -= NFSD_USAGE_WRAP;
- if (decile == 10)
- nfsdstats.th_fullcnt++;
- }
- spin_unlock(&nfsd_call_lock);
-}
/*
* This is the NFS server kernel thread
@@ -460,8 +485,6 @@ nfsd(void *vrqstp)
continue;
}
- update_thread_usage(atomic_read(&nfsd_busy));
- atomic_inc(&nfsd_busy);
/* Lock the export hash tables for reading. */
exp_readlock();
@@ -470,8 +493,6 @@ nfsd(void *vrqstp)
/* Unlock export hash tables */
exp_readunlock();
- update_thread_usage(atomic_read(&nfsd_busy));
- atomic_dec(&nfsd_busy);
}
/* Clear signals before calling svc_exit_thread() */
@@ -539,6 +560,10 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
+ rqstp->rq_res.head[0].iov_len;
rqstp->rq_res.head[0].iov_len += sizeof(__be32);
+ /* NFSv4.1 DRC requires statp */
+ if (rqstp->rq_vers == 4)
+ nfsd4_set_statp(rqstp, statp);
+
/* Now call the procedure handler, and encode NFS status. */
nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
nfserr = map_new_errors(rqstp->rq_vers, nfserr);
@@ -570,3 +595,10 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1);
return 1;
}
+
+int nfsd_pool_stats_open(struct inode *inode, struct file *file)
+{
+ if (nfsd_serv == NULL)
+ return -ENODEV;
+ return svc_pool_stats_open(nfsd_serv, file);
+}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 78376b6c023..ab93fcfef25 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -366,8 +366,9 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
}
/* Revoke setuid/setgid on chown */
- if (((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) ||
- ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)) {
+ if (!S_ISDIR(inode->i_mode) &&
+ (((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) ||
+ ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid))) {
iap->ia_valid |= ATTR_KILL_PRIV;
if (iap->ia_valid & ATTR_MODE) {
/* we're setting mode too, just clear the s*id bits */
@@ -960,7 +961,7 @@ static void kill_suid(struct dentry *dentry)
static __be32
nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
loff_t offset, struct kvec *vec, int vlen,
- unsigned long cnt, int *stablep)
+ unsigned long *cnt, int *stablep)
{
struct svc_export *exp;
struct dentry *dentry;
@@ -974,7 +975,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
err = nfserr_perm;
if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
- (!lock_may_write(file->f_path.dentry->d_inode, offset, cnt)))
+ (!lock_may_write(file->f_path.dentry->d_inode, offset, *cnt)))
goto out;
#endif
@@ -1009,7 +1010,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
set_fs(oldfs);
if (host_err >= 0) {
- nfsdstats.io_write += cnt;
+ nfsdstats.io_write += host_err;
fsnotify_modify(file->f_path.dentry);
}
@@ -1054,9 +1055,10 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
}
dprintk("nfsd: write complete host_err=%d\n", host_err);
- if (host_err >= 0)
+ if (host_err >= 0) {
err = 0;
- else
+ *cnt = host_err;
+ } else
err = nfserrno(host_err);
out:
return err;
@@ -1098,7 +1100,7 @@ out:
*/
__be32
nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
- loff_t offset, struct kvec *vec, int vlen, unsigned long cnt,
+ loff_t offset, struct kvec *vec, int vlen, unsigned long *cnt,
int *stablep)
{
__be32 err = 0;
@@ -1179,6 +1181,21 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp,
return 0;
}
+/* HPUX client sometimes creates a file in mode 000, and sets size to 0.
+ * setting size to 0 may fail for some specific file systems by the permission
+ * checking which requires WRITE permission but the mode is 000.
+ * we ignore the resizing(to 0) on the just new created file, since the size is
+ * 0 after file created.
+ *
+ * call this only after vfs_create() is called.
+ * */
+static void
+nfsd_check_ignore_resizing(struct iattr *iap)
+{
+ if ((iap->ia_valid & ATTR_SIZE) && (iap->ia_size == 0))
+ iap->ia_valid &= ~ATTR_SIZE;
+}
+
/*
* Create a file (regular, directory, device, fifo); UNIX sockets
* not yet implemented.
@@ -1274,6 +1291,8 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
switch (type) {
case S_IFREG:
host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
+ if (!host_err)
+ nfsd_check_ignore_resizing(iap);
break;
case S_IFDIR:
host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
@@ -1427,6 +1446,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
/* setattr will sync the child (or not) */
}
+ nfsd_check_ignore_resizing(iap);
+
if (createmode == NFS3_CREATE_EXCLUSIVE) {
/* Cram the verifier into atime/mtime */
iap->ia_valid = ATTR_MTIME|ATTR_ATIME
diff --git a/fs/nilfs2/Makefile b/fs/nilfs2/Makefile
new file mode 100644
index 00000000000..df3e62c1ddc
--- /dev/null
+++ b/fs/nilfs2/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_NILFS2_FS) += nilfs2.o
+nilfs2-y := inode.o file.o dir.o super.o namei.o page.o mdt.o \
+ btnode.o bmap.o btree.o direct.o dat.o recovery.o \
+ the_nilfs.o segbuf.o segment.o cpfile.o sufile.o \
+ ifile.o alloc.o gcinode.o ioctl.o gcdat.o
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c
new file mode 100644
index 00000000000..d69e6ae5925
--- /dev/null
+++ b/fs/nilfs2/alloc.c
@@ -0,0 +1,504 @@
+/*
+ * alloc.c - NILFS dat/inode allocator
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Original code was written by Koji Sato <koji@osrg.net>.
+ * Two allocators were unified by Ryusuke Konishi <ryusuke@osrg.net>,
+ * Amagai Yoshiji <amagai@osrg.net>.
+ */
+
+#include <linux/types.h>
+#include <linux/buffer_head.h>
+#include <linux/fs.h>
+#include <linux/bitops.h>
+#include "mdt.h"
+#include "alloc.h"
+
+
+static inline unsigned long
+nilfs_palloc_groups_per_desc_block(const struct inode *inode)
+{
+ return (1UL << inode->i_blkbits) /
+ sizeof(struct nilfs_palloc_group_desc);
+}
+
+static inline unsigned long
+nilfs_palloc_groups_count(const struct inode *inode)
+{
+ return 1UL << (BITS_PER_LONG - (inode->i_blkbits + 3 /* log2(8) */));
+}
+
+int nilfs_palloc_init_blockgroup(struct inode *inode, unsigned entry_size)
+{
+ struct nilfs_mdt_info *mi = NILFS_MDT(inode);
+
+ mi->mi_bgl = kmalloc(sizeof(*mi->mi_bgl), GFP_NOFS);
+ if (!mi->mi_bgl)
+ return -ENOMEM;
+
+ bgl_lock_init(mi->mi_bgl);
+
+ nilfs_mdt_set_entry_size(inode, entry_size, 0);
+
+ mi->mi_blocks_per_group =
+ DIV_ROUND_UP(nilfs_palloc_entries_per_group(inode),
+ mi->mi_entries_per_block) + 1;
+ /* Number of blocks in a group including entry blocks and
+ a bitmap block */
+ mi->mi_blocks_per_desc_block =
+ nilfs_palloc_groups_per_desc_block(inode) *
+ mi->mi_blocks_per_group + 1;
+ /* Number of blocks per descriptor including the
+ descriptor block */
+ return 0;
+}
+
+static unsigned long nilfs_palloc_group(const struct inode *inode, __u64 nr,
+ unsigned long *offset)
+{
+ __u64 group = nr;
+
+ *offset = do_div(group, nilfs_palloc_entries_per_group(inode));
+ return group;
+}
+
+static unsigned long
+nilfs_palloc_desc_blkoff(const struct inode *inode, unsigned long group)
+{
+ unsigned long desc_block =
+ group / nilfs_palloc_groups_per_desc_block(inode);
+ return desc_block * NILFS_MDT(inode)->mi_blocks_per_desc_block;
+}
+
+static unsigned long
+nilfs_palloc_bitmap_blkoff(const struct inode *inode, unsigned long group)
+{
+ unsigned long desc_offset =
+ group % nilfs_palloc_groups_per_desc_block(inode);
+ return nilfs_palloc_desc_blkoff(inode, group) + 1 +
+ desc_offset * NILFS_MDT(inode)->mi_blocks_per_group;
+}
+
+static unsigned long
+nilfs_palloc_group_desc_nfrees(struct inode *inode, unsigned long group,
+ const struct nilfs_palloc_group_desc *desc)
+{
+ unsigned long nfree;
+
+ spin_lock(nilfs_mdt_bgl_lock(inode, group));
+ nfree = le32_to_cpu(desc->pg_nfrees);
+ spin_unlock(nilfs_mdt_bgl_lock(inode, group));
+ return nfree;
+}
+
+static void
+nilfs_palloc_group_desc_add_entries(struct inode *inode,
+ unsigned long group,
+ struct nilfs_palloc_group_desc *desc,
+ u32 n)
+{
+ spin_lock(nilfs_mdt_bgl_lock(inode, group));
+ le32_add_cpu(&desc->pg_nfrees, n);
+ spin_unlock(nilfs_mdt_bgl_lock(inode, group));
+}
+
+static unsigned long
+nilfs_palloc_entry_blkoff(const struct inode *inode, __u64 nr)
+{
+ unsigned long group, group_offset;
+
+ group = nilfs_palloc_group(inode, nr, &group_offset);
+
+ return nilfs_palloc_bitmap_blkoff(inode, group) + 1 +
+ group_offset / NILFS_MDT(inode)->mi_entries_per_block;
+}
+
+static void nilfs_palloc_desc_block_init(struct inode *inode,
+ struct buffer_head *bh, void *kaddr)
+{
+ struct nilfs_palloc_group_desc *desc = kaddr + bh_offset(bh);
+ unsigned long n = nilfs_palloc_groups_per_desc_block(inode);
+ __le32 nfrees;
+
+ nfrees = cpu_to_le32(nilfs_palloc_entries_per_group(inode));
+ while (n-- > 0) {
+ desc->pg_nfrees = nfrees;
+ desc++;
+ }
+}
+
+static int nilfs_palloc_get_desc_block(struct inode *inode,
+ unsigned long group,
+ int create, struct buffer_head **bhp)
+{
+ return nilfs_mdt_get_block(inode,
+ nilfs_palloc_desc_blkoff(inode, group),
+ create, nilfs_palloc_desc_block_init, bhp);
+}
+
+static int nilfs_palloc_get_bitmap_block(struct inode *inode,
+ unsigned long group,
+ int create, struct buffer_head **bhp)
+{
+ return nilfs_mdt_get_block(inode,
+ nilfs_palloc_bitmap_blkoff(inode, group),
+ create, NULL, bhp);
+}
+
+int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr,
+ int create, struct buffer_head **bhp)
+{
+ return nilfs_mdt_get_block(inode, nilfs_palloc_entry_blkoff(inode, nr),
+ create, NULL, bhp);
+}
+
+static struct nilfs_palloc_group_desc *
+nilfs_palloc_block_get_group_desc(const struct inode *inode,
+ unsigned long group,
+ const struct buffer_head *bh, void *kaddr)
+{
+ return (struct nilfs_palloc_group_desc *)(kaddr + bh_offset(bh)) +
+ group % nilfs_palloc_groups_per_desc_block(inode);
+}
+
+static unsigned char *
+nilfs_palloc_block_get_bitmap(const struct inode *inode,
+ const struct buffer_head *bh, void *kaddr)
+{
+ return (unsigned char *)(kaddr + bh_offset(bh));
+}
+
+void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr,
+ const struct buffer_head *bh, void *kaddr)
+{
+ unsigned long entry_offset, group_offset;
+
+ nilfs_palloc_group(inode, nr, &group_offset);
+ entry_offset = group_offset % NILFS_MDT(inode)->mi_entries_per_block;
+
+ return kaddr + bh_offset(bh) +
+ entry_offset * NILFS_MDT(inode)->mi_entry_size;
+}
+
+static int nilfs_palloc_find_available_slot(struct inode *inode,
+ unsigned long group,
+ unsigned long target,
+ unsigned char *bitmap,
+ int bsize) /* size in bits */
+{
+ int curr, pos, end, i;
+
+ if (target > 0) {
+ end = (target + BITS_PER_LONG - 1) & ~(BITS_PER_LONG - 1);
+ if (end > bsize)
+ end = bsize;
+ pos = nilfs_find_next_zero_bit(bitmap, end, target);
+ if (pos < end &&
+ !nilfs_set_bit_atomic(
+ nilfs_mdt_bgl_lock(inode, group), pos, bitmap))
+ return pos;
+ } else
+ end = 0;
+
+ for (i = 0, curr = end;
+ i < bsize;
+ i += BITS_PER_LONG, curr += BITS_PER_LONG) {
+ /* wrap around */
+ if (curr >= bsize)
+ curr = 0;
+ while (*((unsigned long *)bitmap + curr / BITS_PER_LONG)
+ != ~0UL) {
+ end = curr + BITS_PER_LONG;
+ if (end > bsize)
+ end = bsize;
+ pos = nilfs_find_next_zero_bit(bitmap, end, curr);
+ if ((pos < end) &&
+ !nilfs_set_bit_atomic(
+ nilfs_mdt_bgl_lock(inode, group), pos,
+ bitmap))
+ return pos;
+ }
+ }
+ return -ENOSPC;
+}
+
+static unsigned long
+nilfs_palloc_rest_groups_in_desc_block(const struct inode *inode,
+ unsigned long curr, unsigned long max)
+{
+ return min_t(unsigned long,
+ nilfs_palloc_groups_per_desc_block(inode) -
+ curr % nilfs_palloc_groups_per_desc_block(inode),
+ max - curr + 1);
+}
+
+int nilfs_palloc_prepare_alloc_entry(struct inode *inode,
+ struct nilfs_palloc_req *req)
+{
+ struct buffer_head *desc_bh, *bitmap_bh;
+ struct nilfs_palloc_group_desc *desc;
+ unsigned char *bitmap;
+ void *desc_kaddr, *bitmap_kaddr;
+ unsigned long group, maxgroup, ngroups;
+ unsigned long group_offset, maxgroup_offset;
+ unsigned long n, entries_per_group, groups_per_desc_block;
+ unsigned long i, j;
+ int pos, ret;
+
+ ngroups = nilfs_palloc_groups_count(inode);
+ maxgroup = ngroups - 1;
+ group = nilfs_palloc_group(inode, req->pr_entry_nr, &group_offset);
+ entries_per_group = nilfs_palloc_entries_per_group(inode);
+ groups_per_desc_block = nilfs_palloc_groups_per_desc_block(inode);
+
+ for (i = 0; i < ngroups; i += n) {
+ if (group >= ngroups) {
+ /* wrap around */
+ group = 0;
+ maxgroup = nilfs_palloc_group(inode, req->pr_entry_nr,
+ &maxgroup_offset) - 1;
+ }
+ ret = nilfs_palloc_get_desc_block(inode, group, 1, &desc_bh);
+ if (ret < 0)
+ return ret;
+ desc_kaddr = kmap(desc_bh->b_page);
+ desc = nilfs_palloc_block_get_group_desc(
+ inode, group, desc_bh, desc_kaddr);
+ n = nilfs_palloc_rest_groups_in_desc_block(inode, group,
+ maxgroup);
+ for (j = 0; j < n; j++, desc++, group++) {
+ if (nilfs_palloc_group_desc_nfrees(inode, group, desc)
+ > 0) {
+ ret = nilfs_palloc_get_bitmap_block(
+ inode, group, 1, &bitmap_bh);
+ if (ret < 0)
+ goto out_desc;
+ bitmap_kaddr = kmap(bitmap_bh->b_page);
+ bitmap = nilfs_palloc_block_get_bitmap(
+ inode, bitmap_bh, bitmap_kaddr);
+ pos = nilfs_palloc_find_available_slot(
+ inode, group, group_offset, bitmap,
+ entries_per_group);
+ if (pos >= 0) {
+ /* found a free entry */
+ nilfs_palloc_group_desc_add_entries(
+ inode, group, desc, -1);
+ req->pr_entry_nr =
+ entries_per_group * group + pos;
+ kunmap(desc_bh->b_page);
+ kunmap(bitmap_bh->b_page);
+
+ req->pr_desc_bh = desc_bh;
+ req->pr_bitmap_bh = bitmap_bh;
+ return 0;
+ }
+ kunmap(bitmap_bh->b_page);
+ brelse(bitmap_bh);
+ }
+
+ group_offset = 0;
+ }
+
+ kunmap(desc_bh->b_page);
+ brelse(desc_bh);
+ }
+
+ /* no entries left */
+ return -ENOSPC;
+
+ out_desc:
+ kunmap(desc_bh->b_page);
+ brelse(desc_bh);
+ return ret;
+}
+
+void nilfs_palloc_commit_alloc_entry(struct inode *inode,
+ struct nilfs_palloc_req *req)
+{
+ nilfs_mdt_mark_buffer_dirty(req->pr_bitmap_bh);
+ nilfs_mdt_mark_buffer_dirty(req->pr_desc_bh);
+ nilfs_mdt_mark_dirty(inode);
+
+ brelse(req->pr_bitmap_bh);
+ brelse(req->pr_desc_bh);
+}
+
+void nilfs_palloc_commit_free_entry(struct inode *inode,
+ struct nilfs_palloc_req *req)
+{
+ struct nilfs_palloc_group_desc *desc;
+ unsigned long group, group_offset;
+ unsigned char *bitmap;
+ void *desc_kaddr, *bitmap_kaddr;
+
+ group = nilfs_palloc_group(inode, req->pr_entry_nr, &group_offset);
+ desc_kaddr = kmap(req->pr_desc_bh->b_page);
+ desc = nilfs_palloc_block_get_group_desc(inode, group,
+ req->pr_desc_bh, desc_kaddr);
+ bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
+ bitmap = nilfs_palloc_block_get_bitmap(inode, req->pr_bitmap_bh,
+ bitmap_kaddr);
+
+ if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
+ group_offset, bitmap))
+ printk(KERN_WARNING "%s: entry number %llu already freed\n",
+ __func__, (unsigned long long)req->pr_entry_nr);
+
+ nilfs_palloc_group_desc_add_entries(inode, group, desc, 1);
+
+ kunmap(req->pr_bitmap_bh->b_page);
+ kunmap(req->pr_desc_bh->b_page);
+
+ nilfs_mdt_mark_buffer_dirty(req->pr_desc_bh);
+ nilfs_mdt_mark_buffer_dirty(req->pr_bitmap_bh);
+ nilfs_mdt_mark_dirty(inode);
+
+ brelse(req->pr_bitmap_bh);
+ brelse(req->pr_desc_bh);
+}
+
+void nilfs_palloc_abort_alloc_entry(struct inode *inode,
+ struct nilfs_palloc_req *req)
+{
+ struct nilfs_palloc_group_desc *desc;
+ void *desc_kaddr, *bitmap_kaddr;
+ unsigned char *bitmap;
+ unsigned long group, group_offset;
+
+ group = nilfs_palloc_group(inode, req->pr_entry_nr, &group_offset);
+ desc_kaddr = kmap(req->pr_desc_bh->b_page);
+ desc = nilfs_palloc_block_get_group_desc(inode, group,
+ req->pr_desc_bh, desc_kaddr);
+ bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
+ bitmap = nilfs_palloc_block_get_bitmap(inode, req->pr_bitmap_bh,
+ bitmap_kaddr);
+ if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
+ group_offset, bitmap))
+ printk(KERN_WARNING "%s: entry numer %llu already freed\n",
+ __func__, (unsigned long long)req->pr_entry_nr);
+
+ nilfs_palloc_group_desc_add_entries(inode, group, desc, 1);
+
+ kunmap(req->pr_bitmap_bh->b_page);
+ kunmap(req->pr_desc_bh->b_page);
+
+ brelse(req->pr_bitmap_bh);
+ brelse(req->pr_desc_bh);
+
+ req->pr_entry_nr = 0;
+ req->pr_bitmap_bh = NULL;
+ req->pr_desc_bh = NULL;
+}
+
+int nilfs_palloc_prepare_free_entry(struct inode *inode,
+ struct nilfs_palloc_req *req)
+{
+ struct buffer_head *desc_bh, *bitmap_bh;
+ unsigned long group, group_offset;
+ int ret;
+
+ group = nilfs_palloc_group(inode, req->pr_entry_nr, &group_offset);
+ ret = nilfs_palloc_get_desc_block(inode, group, 1, &desc_bh);
+ if (ret < 0)
+ return ret;
+ ret = nilfs_palloc_get_bitmap_block(inode, group, 1, &bitmap_bh);
+ if (ret < 0) {
+ brelse(desc_bh);
+ return ret;
+ }
+
+ req->pr_desc_bh = desc_bh;
+ req->pr_bitmap_bh = bitmap_bh;
+ return 0;
+}
+
+void nilfs_palloc_abort_free_entry(struct inode *inode,
+ struct nilfs_palloc_req *req)
+{
+ brelse(req->pr_bitmap_bh);
+ brelse(req->pr_desc_bh);
+
+ req->pr_entry_nr = 0;
+ req->pr_bitmap_bh = NULL;
+ req->pr_desc_bh = NULL;
+}
+
+static int
+nilfs_palloc_group_is_in(struct inode *inode, unsigned long group, __u64 nr)
+{
+ __u64 first, last;
+
+ first = group * nilfs_palloc_entries_per_group(inode);
+ last = first + nilfs_palloc_entries_per_group(inode) - 1;
+ return (nr >= first) && (nr <= last);
+}
+
+int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
+{
+ struct buffer_head *desc_bh, *bitmap_bh;
+ struct nilfs_palloc_group_desc *desc;
+ unsigned char *bitmap;
+ void *desc_kaddr, *bitmap_kaddr;
+ unsigned long group, group_offset;
+ int i, j, n, ret;
+
+ for (i = 0; i < nitems; i += n) {
+ group = nilfs_palloc_group(inode, entry_nrs[i], &group_offset);
+ ret = nilfs_palloc_get_desc_block(inode, group, 0, &desc_bh);
+ if (ret < 0)
+ return ret;
+ ret = nilfs_palloc_get_bitmap_block(inode, group, 0,
+ &bitmap_bh);
+ if (ret < 0) {
+ brelse(desc_bh);
+ return ret;
+ }
+ desc_kaddr = kmap(desc_bh->b_page);
+ desc = nilfs_palloc_block_get_group_desc(
+ inode, group, desc_bh, desc_kaddr);
+ bitmap_kaddr = kmap(bitmap_bh->b_page);
+ bitmap = nilfs_palloc_block_get_bitmap(
+ inode, bitmap_bh, bitmap_kaddr);
+ for (j = i, n = 0;
+ (j < nitems) && nilfs_palloc_group_is_in(inode, group,
+ entry_nrs[j]);
+ j++, n++) {
+ nilfs_palloc_group(inode, entry_nrs[j], &group_offset);
+ if (!nilfs_clear_bit_atomic(
+ nilfs_mdt_bgl_lock(inode, group),
+ group_offset, bitmap)) {
+ printk(KERN_WARNING
+ "%s: entry number %llu already freed\n",
+ __func__,
+ (unsigned long long)entry_nrs[j]);
+ }
+ }
+ nilfs_palloc_group_desc_add_entries(inode, group, desc, n);
+
+ kunmap(bitmap_bh->b_page);
+ kunmap(desc_bh->b_page);
+
+ nilfs_mdt_mark_buffer_dirty(desc_bh);
+ nilfs_mdt_mark_buffer_dirty(bitmap_bh);
+ nilfs_mdt_mark_dirty(inode);
+
+ brelse(bitmap_bh);
+ brelse(desc_bh);
+ }
+ return 0;
+}
diff --git a/fs/nilfs2/alloc.h b/fs/nilfs2/alloc.h
new file mode 100644
index 00000000000..4ace5475c2c
--- /dev/null
+++ b/fs/nilfs2/alloc.h
@@ -0,0 +1,72 @@
+/*
+ * alloc.h - persistent object (dat entry/disk inode) allocator/deallocator
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Original code was written by Koji Sato <koji@osrg.net>.
+ * Two allocators were unified by Ryusuke Konishi <ryusuke@osrg.net>,
+ * Amagai Yoshiji <amagai@osrg.net>.
+ */
+
+#ifndef _NILFS_ALLOC_H
+#define _NILFS_ALLOC_H
+
+#include <linux/types.h>
+#include <linux/buffer_head.h>
+#include <linux/fs.h>
+
+static inline unsigned long
+nilfs_palloc_entries_per_group(const struct inode *inode)
+{
+ return 1UL << (inode->i_blkbits + 3 /* log2(8 = CHAR_BITS) */);
+}
+
+int nilfs_palloc_init_blockgroup(struct inode *, unsigned);
+int nilfs_palloc_get_entry_block(struct inode *, __u64, int,
+ struct buffer_head **);
+void *nilfs_palloc_block_get_entry(const struct inode *, __u64,
+ const struct buffer_head *, void *);
+
+/**
+ * nilfs_palloc_req - persistent alloctor request and reply
+ * @pr_entry_nr: entry number (vblocknr or inode number)
+ * @pr_desc_bh: buffer head of the buffer containing block group descriptors
+ * @pr_bitmap_bh: buffer head of the buffer containing a block group bitmap
+ * @pr_entry_bh: buffer head of the buffer containing translation entries
+ */
+struct nilfs_palloc_req {
+ __u64 pr_entry_nr;
+ struct buffer_head *pr_desc_bh;
+ struct buffer_head *pr_bitmap_bh;
+ struct buffer_head *pr_entry_bh;
+};
+
+int nilfs_palloc_prepare_alloc_entry(struct inode *,
+ struct nilfs_palloc_req *);
+void nilfs_palloc_commit_alloc_entry(struct inode *,
+ struct nilfs_palloc_req *);
+void nilfs_palloc_abort_alloc_entry(struct inode *, struct nilfs_palloc_req *);
+void nilfs_palloc_commit_free_entry(struct inode *, struct nilfs_palloc_req *);
+int nilfs_palloc_prepare_free_entry(struct inode *, struct nilfs_palloc_req *);
+void nilfs_palloc_abort_free_entry(struct inode *, struct nilfs_palloc_req *);
+int nilfs_palloc_freev(struct inode *, __u64 *, size_t);
+
+#define nilfs_set_bit_atomic ext2_set_bit_atomic
+#define nilfs_clear_bit_atomic ext2_clear_bit_atomic
+#define nilfs_find_next_zero_bit ext2_find_next_zero_bit
+
+#endif /* _NILFS_ALLOC_H */
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
new file mode 100644
index 00000000000..064279e33bb
--- /dev/null
+++ b/fs/nilfs2/bmap.c
@@ -0,0 +1,788 @@
+/*
+ * bmap.c - NILFS block mapping.
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include "nilfs.h"
+#include "bmap.h"
+#include "sb.h"
+#include "btnode.h"
+#include "mdt.h"
+#include "dat.h"
+#include "alloc.h"
+
+int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level,
+ __u64 *ptrp)
+{
+ __u64 ptr;
+ int ret;
+
+ down_read(&bmap->b_sem);
+ ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp);
+ if (ret < 0)
+ goto out;
+ if (bmap->b_pops->bpop_translate != NULL) {
+ ret = bmap->b_pops->bpop_translate(bmap, *ptrp, &ptr);
+ if (ret < 0)
+ goto out;
+ *ptrp = ptr;
+ }
+
+ out:
+ up_read(&bmap->b_sem);
+ return ret;
+}
+
+
+/**
+ * nilfs_bmap_lookup - find a record
+ * @bmap: bmap
+ * @key: key
+ * @recp: pointer to record
+ *
+ * Description: nilfs_bmap_lookup() finds a record whose key matches @key in
+ * @bmap.
+ *
+ * Return Value: On success, 0 is returned and the record associated with @key
+ * is stored in the place pointed by @recp. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOENT - A record associated with @key does not exist.
+ */
+int nilfs_bmap_lookup(struct nilfs_bmap *bmap,
+ unsigned long key,
+ unsigned long *recp)
+{
+ __u64 ptr;
+ int ret;
+
+ /* XXX: use macro for level 1 */
+ ret = nilfs_bmap_lookup_at_level(bmap, key, 1, &ptr);
+ if (recp != NULL)
+ *recp = ptr;
+ return ret;
+}
+
+static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
+{
+ __u64 keys[NILFS_BMAP_SMALL_HIGH + 1];
+ __u64 ptrs[NILFS_BMAP_SMALL_HIGH + 1];
+ int ret, n;
+
+ if (bmap->b_ops->bop_check_insert != NULL) {
+ ret = bmap->b_ops->bop_check_insert(bmap, key);
+ if (ret > 0) {
+ n = bmap->b_ops->bop_gather_data(
+ bmap, keys, ptrs, NILFS_BMAP_SMALL_HIGH + 1);
+ if (n < 0)
+ return n;
+ ret = nilfs_btree_convert_and_insert(
+ bmap, key, ptr, keys, ptrs, n,
+ NILFS_BMAP_LARGE_LOW, NILFS_BMAP_LARGE_HIGH);
+ if (ret == 0)
+ bmap->b_u.u_flags |= NILFS_BMAP_LARGE;
+
+ return ret;
+ } else if (ret < 0)
+ return ret;
+ }
+
+ return bmap->b_ops->bop_insert(bmap, key, ptr);
+}
+
+/**
+ * nilfs_bmap_insert - insert a new key-record pair into a bmap
+ * @bmap: bmap
+ * @key: key
+ * @rec: record
+ *
+ * Description: nilfs_bmap_insert() inserts the new key-record pair specified
+ * by @key and @rec into @bmap.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-EEXIST - A record associated with @key already exist.
+ */
+int nilfs_bmap_insert(struct nilfs_bmap *bmap,
+ unsigned long key,
+ unsigned long rec)
+{
+ int ret;
+
+ down_write(&bmap->b_sem);
+ ret = nilfs_bmap_do_insert(bmap, key, rec);
+ up_write(&bmap->b_sem);
+ return ret;
+}
+
+static int nilfs_bmap_do_delete(struct nilfs_bmap *bmap, __u64 key)
+{
+ __u64 keys[NILFS_BMAP_LARGE_LOW + 1];
+ __u64 ptrs[NILFS_BMAP_LARGE_LOW + 1];
+ int ret, n;
+
+ if (bmap->b_ops->bop_check_delete != NULL) {
+ ret = bmap->b_ops->bop_check_delete(bmap, key);
+ if (ret > 0) {
+ n = bmap->b_ops->bop_gather_data(
+ bmap, keys, ptrs, NILFS_BMAP_LARGE_LOW + 1);
+ if (n < 0)
+ return n;
+ ret = nilfs_direct_delete_and_convert(
+ bmap, key, keys, ptrs, n,
+ NILFS_BMAP_SMALL_LOW, NILFS_BMAP_SMALL_HIGH);
+ if (ret == 0)
+ bmap->b_u.u_flags &= ~NILFS_BMAP_LARGE;
+
+ return ret;
+ } else if (ret < 0)
+ return ret;
+ }
+
+ return bmap->b_ops->bop_delete(bmap, key);
+}
+
+int nilfs_bmap_last_key(struct nilfs_bmap *bmap, unsigned long *key)
+{
+ __u64 lastkey;
+ int ret;
+
+ down_read(&bmap->b_sem);
+ ret = bmap->b_ops->bop_last_key(bmap, &lastkey);
+ if (!ret)
+ *key = lastkey;
+ up_read(&bmap->b_sem);
+ return ret;
+}
+
+/**
+ * nilfs_bmap_delete - delete a key-record pair from a bmap
+ * @bmap: bmap
+ * @key: key
+ *
+ * Description: nilfs_bmap_delete() deletes the key-record pair specified by
+ * @key from @bmap.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOENT - A record associated with @key does not exist.
+ */
+int nilfs_bmap_delete(struct nilfs_bmap *bmap, unsigned long key)
+{
+ int ret;
+
+ down_write(&bmap->b_sem);
+ ret = nilfs_bmap_do_delete(bmap, key);
+ up_write(&bmap->b_sem);
+ return ret;
+}
+
+static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, unsigned long key)
+{
+ __u64 lastkey;
+ int ret;
+
+ ret = bmap->b_ops->bop_last_key(bmap, &lastkey);
+ if (ret < 0) {
+ if (ret == -ENOENT)
+ ret = 0;
+ return ret;
+ }
+
+ while (key <= lastkey) {
+ ret = nilfs_bmap_do_delete(bmap, lastkey);
+ if (ret < 0)
+ return ret;
+ ret = bmap->b_ops->bop_last_key(bmap, &lastkey);
+ if (ret < 0) {
+ if (ret == -ENOENT)
+ ret = 0;
+ return ret;
+ }
+ }
+ return 0;
+}
+
+/**
+ * nilfs_bmap_truncate - truncate a bmap to a specified key
+ * @bmap: bmap
+ * @key: key
+ *
+ * Description: nilfs_bmap_truncate() removes key-record pairs whose keys are
+ * greater than or equal to @key from @bmap.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ */
+int nilfs_bmap_truncate(struct nilfs_bmap *bmap, unsigned long key)
+{
+ int ret;
+
+ down_write(&bmap->b_sem);
+ ret = nilfs_bmap_do_truncate(bmap, key);
+ up_write(&bmap->b_sem);
+ return ret;
+}
+
+/**
+ * nilfs_bmap_clear - free resources a bmap holds
+ * @bmap: bmap
+ *
+ * Description: nilfs_bmap_clear() frees resources associated with @bmap.
+ */
+void nilfs_bmap_clear(struct nilfs_bmap *bmap)
+{
+ down_write(&bmap->b_sem);
+ if (bmap->b_ops->bop_clear != NULL)
+ bmap->b_ops->bop_clear(bmap);
+ up_write(&bmap->b_sem);
+}
+
+/**
+ * nilfs_bmap_propagate - propagate dirty state
+ * @bmap: bmap
+ * @bh: buffer head
+ *
+ * Description: nilfs_bmap_propagate() marks the buffers that directly or
+ * indirectly refer to the block specified by @bh dirty.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ */
+int nilfs_bmap_propagate(struct nilfs_bmap *bmap, struct buffer_head *bh)
+{
+ int ret;
+
+ down_write(&bmap->b_sem);
+ ret = bmap->b_ops->bop_propagate(bmap, bh);
+ up_write(&bmap->b_sem);
+ return ret;
+}
+
+/**
+ * nilfs_bmap_lookup_dirty_buffers -
+ * @bmap: bmap
+ * @listp: pointer to buffer head list
+ */
+void nilfs_bmap_lookup_dirty_buffers(struct nilfs_bmap *bmap,
+ struct list_head *listp)
+{
+ if (bmap->b_ops->bop_lookup_dirty_buffers != NULL)
+ bmap->b_ops->bop_lookup_dirty_buffers(bmap, listp);
+}
+
+/**
+ * nilfs_bmap_assign - assign a new block number to a block
+ * @bmap: bmap
+ * @bhp: pointer to buffer head
+ * @blocknr: block number
+ * @binfo: block information
+ *
+ * Description: nilfs_bmap_assign() assigns the block number @blocknr to the
+ * buffer specified by @bh.
+ *
+ * Return Value: On success, 0 is returned and the buffer head of a newly
+ * create buffer and the block information associated with the buffer are
+ * stored in the place pointed by @bh and @binfo, respectively. On error, one
+ * of the following negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ */
+int nilfs_bmap_assign(struct nilfs_bmap *bmap,
+ struct buffer_head **bh,
+ unsigned long blocknr,
+ union nilfs_binfo *binfo)
+{
+ int ret;
+
+ down_write(&bmap->b_sem);
+ ret = bmap->b_ops->bop_assign(bmap, bh, blocknr, binfo);
+ up_write(&bmap->b_sem);
+ return ret;
+}
+
+/**
+ * nilfs_bmap_mark - mark block dirty
+ * @bmap: bmap
+ * @key: key
+ * @level: level
+ *
+ * Description: nilfs_bmap_mark() marks the block specified by @key and @level
+ * as dirty.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ */
+int nilfs_bmap_mark(struct nilfs_bmap *bmap, __u64 key, int level)
+{
+ int ret;
+
+ if (bmap->b_ops->bop_mark == NULL)
+ return 0;
+
+ down_write(&bmap->b_sem);
+ ret = bmap->b_ops->bop_mark(bmap, key, level);
+ up_write(&bmap->b_sem);
+ return ret;
+}
+
+/**
+ * nilfs_bmap_test_and_clear_dirty - test and clear a bmap dirty state
+ * @bmap: bmap
+ *
+ * Description: nilfs_test_and_clear() is the atomic operation to test and
+ * clear the dirty state of @bmap.
+ *
+ * Return Value: 1 is returned if @bmap is dirty, or 0 if clear.
+ */
+int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *bmap)
+{
+ int ret;
+
+ down_write(&bmap->b_sem);
+ ret = nilfs_bmap_dirty(bmap);
+ nilfs_bmap_clear_dirty(bmap);
+ up_write(&bmap->b_sem);
+ return ret;
+}
+
+
+/*
+ * Internal use only
+ */
+
+void nilfs_bmap_add_blocks(const struct nilfs_bmap *bmap, int n)
+{
+ inode_add_bytes(bmap->b_inode, (1 << bmap->b_inode->i_blkbits) * n);
+ if (NILFS_MDT(bmap->b_inode))
+ nilfs_mdt_mark_dirty(bmap->b_inode);
+ else
+ mark_inode_dirty(bmap->b_inode);
+}
+
+void nilfs_bmap_sub_blocks(const struct nilfs_bmap *bmap, int n)
+{
+ inode_sub_bytes(bmap->b_inode, (1 << bmap->b_inode->i_blkbits) * n);
+ if (NILFS_MDT(bmap->b_inode))
+ nilfs_mdt_mark_dirty(bmap->b_inode);
+ else
+ mark_inode_dirty(bmap->b_inode);
+}
+
+int nilfs_bmap_get_block(const struct nilfs_bmap *bmap, __u64 ptr,
+ struct buffer_head **bhp)
+{
+ return nilfs_btnode_get(&NILFS_BMAP_I(bmap)->i_btnode_cache,
+ ptr, 0, bhp, 0);
+}
+
+void nilfs_bmap_put_block(const struct nilfs_bmap *bmap,
+ struct buffer_head *bh)
+{
+ brelse(bh);
+}
+
+int nilfs_bmap_get_new_block(const struct nilfs_bmap *bmap, __u64 ptr,
+ struct buffer_head **bhp)
+{
+ int ret;
+
+ ret = nilfs_btnode_get(&NILFS_BMAP_I(bmap)->i_btnode_cache,
+ ptr, 0, bhp, 1);
+ if (ret < 0)
+ return ret;
+ set_buffer_nilfs_volatile(*bhp);
+ return 0;
+}
+
+void nilfs_bmap_delete_block(const struct nilfs_bmap *bmap,
+ struct buffer_head *bh)
+{
+ nilfs_btnode_delete(bh);
+}
+
+__u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap,
+ const struct buffer_head *bh)
+{
+ struct buffer_head *pbh;
+ __u64 key;
+
+ key = page_index(bh->b_page) << (PAGE_CACHE_SHIFT -
+ bmap->b_inode->i_blkbits);
+ for (pbh = page_buffers(bh->b_page); pbh != bh;
+ pbh = pbh->b_this_page, key++);
+
+ return key;
+}
+
+__u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *bmap, __u64 key)
+{
+ __s64 diff;
+
+ diff = key - bmap->b_last_allocated_key;
+ if ((nilfs_bmap_keydiff_abs(diff) < NILFS_INODE_BMAP_SIZE) &&
+ (bmap->b_last_allocated_ptr != NILFS_BMAP_INVALID_PTR) &&
+ (bmap->b_last_allocated_ptr + diff > 0))
+ return bmap->b_last_allocated_ptr + diff;
+ else
+ return NILFS_BMAP_INVALID_PTR;
+}
+
+static struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap)
+{
+ return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode));
+}
+
+#define NILFS_BMAP_GROUP_DIV 8
+__u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
+{
+ struct inode *dat = nilfs_bmap_get_dat(bmap);
+ unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
+ unsigned long group = bmap->b_inode->i_ino / entries_per_group;
+
+ return group * entries_per_group +
+ (bmap->b_inode->i_ino % NILFS_BMAP_GROUP_DIV) *
+ (entries_per_group / NILFS_BMAP_GROUP_DIV);
+}
+
+static int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *req)
+{
+ return nilfs_dat_prepare_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
+}
+
+static void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *req)
+{
+ nilfs_dat_commit_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
+}
+
+static void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *req)
+{
+ nilfs_dat_abort_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
+}
+
+static int nilfs_bmap_prepare_start_v(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *req)
+{
+ return nilfs_dat_prepare_start(nilfs_bmap_get_dat(bmap), &req->bpr_req);
+}
+
+static void nilfs_bmap_commit_start_v(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *req,
+ sector_t blocknr)
+{
+ nilfs_dat_commit_start(nilfs_bmap_get_dat(bmap), &req->bpr_req,
+ blocknr);
+}
+
+static void nilfs_bmap_abort_start_v(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *req)
+{
+ nilfs_dat_abort_start(nilfs_bmap_get_dat(bmap), &req->bpr_req);
+}
+
+static int nilfs_bmap_prepare_end_v(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *req)
+{
+ return nilfs_dat_prepare_end(nilfs_bmap_get_dat(bmap), &req->bpr_req);
+}
+
+static void nilfs_bmap_commit_end_v(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *req)
+{
+ nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req, 0);
+}
+
+static void nilfs_bmap_commit_end_vmdt(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *req)
+{
+ nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req, 1);
+}
+
+static void nilfs_bmap_abort_end_v(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *req)
+{
+ nilfs_dat_abort_end(nilfs_bmap_get_dat(bmap), &req->bpr_req);
+}
+
+int nilfs_bmap_move_v(const struct nilfs_bmap *bmap, __u64 vblocknr,
+ sector_t blocknr)
+{
+ return nilfs_dat_move(nilfs_bmap_get_dat(bmap), vblocknr, blocknr);
+}
+
+int nilfs_bmap_mark_dirty(const struct nilfs_bmap *bmap, __u64 vblocknr)
+{
+ return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(bmap), vblocknr);
+}
+
+int nilfs_bmap_prepare_update(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *oldreq,
+ union nilfs_bmap_ptr_req *newreq)
+{
+ int ret;
+
+ ret = bmap->b_pops->bpop_prepare_end_ptr(bmap, oldreq);
+ if (ret < 0)
+ return ret;
+ ret = bmap->b_pops->bpop_prepare_alloc_ptr(bmap, newreq);
+ if (ret < 0)
+ bmap->b_pops->bpop_abort_end_ptr(bmap, oldreq);
+
+ return ret;
+}
+
+void nilfs_bmap_commit_update(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *oldreq,
+ union nilfs_bmap_ptr_req *newreq)
+{
+ bmap->b_pops->bpop_commit_end_ptr(bmap, oldreq);
+ bmap->b_pops->bpop_commit_alloc_ptr(bmap, newreq);
+}
+
+void nilfs_bmap_abort_update(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *oldreq,
+ union nilfs_bmap_ptr_req *newreq)
+{
+ bmap->b_pops->bpop_abort_end_ptr(bmap, oldreq);
+ bmap->b_pops->bpop_abort_alloc_ptr(bmap, newreq);
+}
+
+static int nilfs_bmap_translate_v(const struct nilfs_bmap *bmap, __u64 ptr,
+ __u64 *ptrp)
+{
+ sector_t blocknr;
+ int ret;
+
+ ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), ptr, &blocknr);
+ if (ret < 0)
+ return ret;
+ if (ptrp != NULL)
+ *ptrp = blocknr;
+ return 0;
+}
+
+static int nilfs_bmap_prepare_alloc_p(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *req)
+{
+ /* ignore target ptr */
+ req->bpr_ptr = bmap->b_last_allocated_ptr++;
+ return 0;
+}
+
+static void nilfs_bmap_commit_alloc_p(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *req)
+{
+ /* do nothing */
+}
+
+static void nilfs_bmap_abort_alloc_p(struct nilfs_bmap *bmap,
+ union nilfs_bmap_ptr_req *req)
+{
+ bmap->b_last_allocated_ptr--;
+}
+
+static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_v = {
+ .bpop_prepare_alloc_ptr = nilfs_bmap_prepare_alloc_v,
+ .bpop_commit_alloc_ptr = nilfs_bmap_commit_alloc_v,
+ .bpop_abort_alloc_ptr = nilfs_bmap_abort_alloc_v,
+ .bpop_prepare_start_ptr = nilfs_bmap_prepare_start_v,
+ .bpop_commit_start_ptr = nilfs_bmap_commit_start_v,
+ .bpop_abort_start_ptr = nilfs_bmap_abort_start_v,
+ .bpop_prepare_end_ptr = nilfs_bmap_prepare_end_v,
+ .bpop_commit_end_ptr = nilfs_bmap_commit_end_v,
+ .bpop_abort_end_ptr = nilfs_bmap_abort_end_v,
+
+ .bpop_translate = nilfs_bmap_translate_v,
+};
+
+static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_vmdt = {
+ .bpop_prepare_alloc_ptr = nilfs_bmap_prepare_alloc_v,
+ .bpop_commit_alloc_ptr = nilfs_bmap_commit_alloc_v,
+ .bpop_abort_alloc_ptr = nilfs_bmap_abort_alloc_v,
+ .bpop_prepare_start_ptr = nilfs_bmap_prepare_start_v,
+ .bpop_commit_start_ptr = nilfs_bmap_commit_start_v,
+ .bpop_abort_start_ptr = nilfs_bmap_abort_start_v,
+ .bpop_prepare_end_ptr = nilfs_bmap_prepare_end_v,
+ .bpop_commit_end_ptr = nilfs_bmap_commit_end_vmdt,
+ .bpop_abort_end_ptr = nilfs_bmap_abort_end_v,
+
+ .bpop_translate = nilfs_bmap_translate_v,
+};
+
+static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_p = {
+ .bpop_prepare_alloc_ptr = nilfs_bmap_prepare_alloc_p,
+ .bpop_commit_alloc_ptr = nilfs_bmap_commit_alloc_p,
+ .bpop_abort_alloc_ptr = nilfs_bmap_abort_alloc_p,
+ .bpop_prepare_start_ptr = NULL,
+ .bpop_commit_start_ptr = NULL,
+ .bpop_abort_start_ptr = NULL,
+ .bpop_prepare_end_ptr = NULL,
+ .bpop_commit_end_ptr = NULL,
+ .bpop_abort_end_ptr = NULL,
+
+ .bpop_translate = NULL,
+};
+
+static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_gc = {
+ .bpop_prepare_alloc_ptr = NULL,
+ .bpop_commit_alloc_ptr = NULL,
+ .bpop_abort_alloc_ptr = NULL,
+ .bpop_prepare_start_ptr = NULL,
+ .bpop_commit_start_ptr = NULL,
+ .bpop_abort_start_ptr = NULL,
+ .bpop_prepare_end_ptr = NULL,
+ .bpop_commit_end_ptr = NULL,
+ .bpop_abort_end_ptr = NULL,
+
+ .bpop_translate = NULL,
+};
+
+static struct lock_class_key nilfs_bmap_dat_lock_key;
+
+/**
+ * nilfs_bmap_read - read a bmap from an inode
+ * @bmap: bmap
+ * @raw_inode: on-disk inode
+ *
+ * Description: nilfs_bmap_read() initializes the bmap @bmap.
+ *
+ * Return Value: On success, 0 is returned. On error, the following negative
+ * error code is returned.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ */
+int nilfs_bmap_read(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode)
+{
+ if (raw_inode == NULL)
+ memset(bmap->b_u.u_data, 0, NILFS_BMAP_SIZE);
+ else
+ memcpy(bmap->b_u.u_data, raw_inode->i_bmap, NILFS_BMAP_SIZE);
+
+ init_rwsem(&bmap->b_sem);
+ bmap->b_state = 0;
+ bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
+ switch (bmap->b_inode->i_ino) {
+ case NILFS_DAT_INO:
+ bmap->b_pops = &nilfs_bmap_ptr_ops_p;
+ bmap->b_last_allocated_key = 0; /* XXX: use macro */
+ bmap->b_last_allocated_ptr = NILFS_BMAP_NEW_PTR_INIT;
+ lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key);
+ break;
+ case NILFS_CPFILE_INO:
+ case NILFS_SUFILE_INO:
+ bmap->b_pops = &nilfs_bmap_ptr_ops_vmdt;
+ bmap->b_last_allocated_key = 0; /* XXX: use macro */
+ bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
+ break;
+ default:
+ bmap->b_pops = &nilfs_bmap_ptr_ops_v;
+ bmap->b_last_allocated_key = 0; /* XXX: use macro */
+ bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
+ break;
+ }
+
+ return (bmap->b_u.u_flags & NILFS_BMAP_LARGE) ?
+ nilfs_btree_init(bmap,
+ NILFS_BMAP_LARGE_LOW,
+ NILFS_BMAP_LARGE_HIGH) :
+ nilfs_direct_init(bmap,
+ NILFS_BMAP_SMALL_LOW,
+ NILFS_BMAP_SMALL_HIGH);
+}
+
+/**
+ * nilfs_bmap_write - write back a bmap to an inode
+ * @bmap: bmap
+ * @raw_inode: on-disk inode
+ *
+ * Description: nilfs_bmap_write() stores @bmap in @raw_inode.
+ */
+void nilfs_bmap_write(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode)
+{
+ down_write(&bmap->b_sem);
+ memcpy(raw_inode->i_bmap, bmap->b_u.u_data,
+ NILFS_INODE_BMAP_SIZE * sizeof(__le64));
+ if (bmap->b_inode->i_ino == NILFS_DAT_INO)
+ bmap->b_last_allocated_ptr = NILFS_BMAP_NEW_PTR_INIT;
+
+ up_write(&bmap->b_sem);
+}
+
+void nilfs_bmap_init_gc(struct nilfs_bmap *bmap)
+{
+ memset(&bmap->b_u, 0, NILFS_BMAP_SIZE);
+ init_rwsem(&bmap->b_sem);
+ bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
+ bmap->b_pops = &nilfs_bmap_ptr_ops_gc;
+ bmap->b_last_allocated_key = 0;
+ bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
+ bmap->b_state = 0;
+ nilfs_btree_init_gc(bmap);
+}
+
+void nilfs_bmap_init_gcdat(struct nilfs_bmap *gcbmap, struct nilfs_bmap *bmap)
+{
+ memcpy(gcbmap, bmap, sizeof(union nilfs_bmap_union));
+ init_rwsem(&gcbmap->b_sem);
+ lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key);
+ gcbmap->b_inode = &NILFS_BMAP_I(gcbmap)->vfs_inode;
+}
+
+void nilfs_bmap_commit_gcdat(struct nilfs_bmap *gcbmap, struct nilfs_bmap *bmap)
+{
+ memcpy(bmap, gcbmap, sizeof(union nilfs_bmap_union));
+ init_rwsem(&bmap->b_sem);
+ lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key);
+ bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
+}
diff --git a/fs/nilfs2/bmap.h b/fs/nilfs2/bmap.h
new file mode 100644
index 00000000000..4f2708abb1b
--- /dev/null
+++ b/fs/nilfs2/bmap.h
@@ -0,0 +1,244 @@
+/*
+ * bmap.h - NILFS block mapping.
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#ifndef _NILFS_BMAP_H
+#define _NILFS_BMAP_H
+
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/nilfs2_fs.h>
+#include "alloc.h"
+
+#define NILFS_BMAP_INVALID_PTR 0
+
+#define nilfs_bmap_dkey_to_key(dkey) le64_to_cpu(dkey)
+#define nilfs_bmap_key_to_dkey(key) cpu_to_le64(key)
+#define nilfs_bmap_dptr_to_ptr(dptr) le64_to_cpu(dptr)
+#define nilfs_bmap_ptr_to_dptr(ptr) cpu_to_le64(ptr)
+
+#define nilfs_bmap_keydiff_abs(diff) ((diff) < 0 ? -(diff) : (diff))
+
+
+struct nilfs_bmap;
+
+/**
+ * union nilfs_bmap_ptr_req - request for bmap ptr
+ * @bpr_ptr: bmap pointer
+ * @bpr_req: request for persistent allocator
+ */
+union nilfs_bmap_ptr_req {
+ __u64 bpr_ptr;
+ struct nilfs_palloc_req bpr_req;
+};
+
+/**
+ * struct nilfs_bmap_stats - bmap statistics
+ * @bs_nblocks: number of blocks created or deleted
+ */
+struct nilfs_bmap_stats {
+ unsigned int bs_nblocks;
+};
+
+/**
+ * struct nilfs_bmap_operations - bmap operation table
+ */
+struct nilfs_bmap_operations {
+ int (*bop_lookup)(const struct nilfs_bmap *, __u64, int, __u64 *);
+ int (*bop_insert)(struct nilfs_bmap *, __u64, __u64);
+ int (*bop_delete)(struct nilfs_bmap *, __u64);
+ void (*bop_clear)(struct nilfs_bmap *);
+
+ int (*bop_propagate)(const struct nilfs_bmap *, struct buffer_head *);
+ void (*bop_lookup_dirty_buffers)(struct nilfs_bmap *,
+ struct list_head *);
+
+ int (*bop_assign)(struct nilfs_bmap *,
+ struct buffer_head **,
+ sector_t,
+ union nilfs_binfo *);
+ int (*bop_mark)(struct nilfs_bmap *, __u64, int);
+
+ /* The following functions are internal use only. */
+ int (*bop_last_key)(const struct nilfs_bmap *, __u64 *);
+ int (*bop_check_insert)(const struct nilfs_bmap *, __u64);
+ int (*bop_check_delete)(struct nilfs_bmap *, __u64);
+ int (*bop_gather_data)(struct nilfs_bmap *, __u64 *, __u64 *, int);
+};
+
+
+/**
+ * struct nilfs_bmap_ptr_operations - bmap ptr operation table
+ */
+struct nilfs_bmap_ptr_operations {
+ int (*bpop_prepare_alloc_ptr)(struct nilfs_bmap *,
+ union nilfs_bmap_ptr_req *);
+ void (*bpop_commit_alloc_ptr)(struct nilfs_bmap *,
+ union nilfs_bmap_ptr_req *);
+ void (*bpop_abort_alloc_ptr)(struct nilfs_bmap *,
+ union nilfs_bmap_ptr_req *);
+ int (*bpop_prepare_start_ptr)(struct nilfs_bmap *,
+ union nilfs_bmap_ptr_req *);
+ void (*bpop_commit_start_ptr)(struct nilfs_bmap *,
+ union nilfs_bmap_ptr_req *,
+ sector_t);
+ void (*bpop_abort_start_ptr)(struct nilfs_bmap *,
+ union nilfs_bmap_ptr_req *);
+ int (*bpop_prepare_end_ptr)(struct nilfs_bmap *,
+ union nilfs_bmap_ptr_req *);
+ void (*bpop_commit_end_ptr)(struct nilfs_bmap *,
+ union nilfs_bmap_ptr_req *);
+ void (*bpop_abort_end_ptr)(struct nilfs_bmap *,
+ union nilfs_bmap_ptr_req *);
+
+ int (*bpop_translate)(const struct nilfs_bmap *, __u64, __u64 *);
+};
+
+
+#define NILFS_BMAP_SIZE (NILFS_INODE_BMAP_SIZE * sizeof(__le64))
+#define NILFS_BMAP_KEY_BIT (sizeof(unsigned long) * 8 /* CHAR_BIT */)
+#define NILFS_BMAP_NEW_PTR_INIT \
+ (1UL << (sizeof(unsigned long) * 8 /* CHAR_BIT */ - 1))
+
+static inline int nilfs_bmap_is_new_ptr(unsigned long ptr)
+{
+ return !!(ptr & NILFS_BMAP_NEW_PTR_INIT);
+}
+
+
+/**
+ * struct nilfs_bmap - bmap structure
+ * @b_u: raw data
+ * @b_sem: semaphore
+ * @b_inode: owner of bmap
+ * @b_ops: bmap operation table
+ * @b_pops: bmap ptr operation table
+ * @b_low: low watermark of conversion
+ * @b_high: high watermark of conversion
+ * @b_last_allocated_key: last allocated key for data block
+ * @b_last_allocated_ptr: last allocated ptr for data block
+ * @b_state: state
+ */
+struct nilfs_bmap {
+ union {
+ __u8 u_flags;
+ __le64 u_data[NILFS_BMAP_SIZE / sizeof(__le64)];
+ } b_u;
+ struct rw_semaphore b_sem;
+ struct inode *b_inode;
+ const struct nilfs_bmap_operations *b_ops;
+ const struct nilfs_bmap_ptr_operations *b_pops;
+ __u64 b_low;
+ __u64 b_high;
+ __u64 b_last_allocated_key;
+ __u64 b_last_allocated_ptr;
+ int b_state;
+};
+
+/* state */
+#define NILFS_BMAP_DIRTY 0x00000001
+
+
+int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *);
+int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *);
+void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *);
+int nilfs_bmap_lookup(struct nilfs_bmap *, unsigned long, unsigned long *);
+int nilfs_bmap_insert(struct nilfs_bmap *, unsigned long, unsigned long);
+int nilfs_bmap_delete(struct nilfs_bmap *, unsigned long);
+int nilfs_bmap_last_key(struct nilfs_bmap *, unsigned long *);
+int nilfs_bmap_truncate(struct nilfs_bmap *, unsigned long);
+void nilfs_bmap_clear(struct nilfs_bmap *);
+int nilfs_bmap_propagate(struct nilfs_bmap *, struct buffer_head *);
+void nilfs_bmap_lookup_dirty_buffers(struct nilfs_bmap *, struct list_head *);
+int nilfs_bmap_assign(struct nilfs_bmap *, struct buffer_head **,
+ unsigned long, union nilfs_binfo *);
+int nilfs_bmap_lookup_at_level(struct nilfs_bmap *, __u64, int, __u64 *);
+int nilfs_bmap_mark(struct nilfs_bmap *, __u64, int);
+
+void nilfs_bmap_init_gc(struct nilfs_bmap *);
+void nilfs_bmap_init_gcdat(struct nilfs_bmap *, struct nilfs_bmap *);
+void nilfs_bmap_commit_gcdat(struct nilfs_bmap *, struct nilfs_bmap *);
+
+
+/*
+ * Internal use only
+ */
+
+int nilfs_bmap_move_v(const struct nilfs_bmap *, __u64, sector_t);
+int nilfs_bmap_mark_dirty(const struct nilfs_bmap *, __u64);
+
+
+__u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *,
+ const struct buffer_head *);
+
+__u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *, __u64);
+__u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *);
+
+int nilfs_bmap_prepare_update(struct nilfs_bmap *,
+ union nilfs_bmap_ptr_req *,
+ union nilfs_bmap_ptr_req *);
+void nilfs_bmap_commit_update(struct nilfs_bmap *,
+ union nilfs_bmap_ptr_req *,
+ union nilfs_bmap_ptr_req *);
+void nilfs_bmap_abort_update(struct nilfs_bmap *,
+ union nilfs_bmap_ptr_req *,
+ union nilfs_bmap_ptr_req *);
+
+void nilfs_bmap_add_blocks(const struct nilfs_bmap *, int);
+void nilfs_bmap_sub_blocks(const struct nilfs_bmap *, int);
+
+
+int nilfs_bmap_get_block(const struct nilfs_bmap *, __u64,
+ struct buffer_head **);
+void nilfs_bmap_put_block(const struct nilfs_bmap *, struct buffer_head *);
+int nilfs_bmap_get_new_block(const struct nilfs_bmap *, __u64,
+ struct buffer_head **);
+void nilfs_bmap_delete_block(const struct nilfs_bmap *, struct buffer_head *);
+
+
+/* Assume that bmap semaphore is locked. */
+static inline int nilfs_bmap_dirty(const struct nilfs_bmap *bmap)
+{
+ return !!(bmap->b_state & NILFS_BMAP_DIRTY);
+}
+
+/* Assume that bmap semaphore is locked. */
+static inline void nilfs_bmap_set_dirty(struct nilfs_bmap *bmap)
+{
+ bmap->b_state |= NILFS_BMAP_DIRTY;
+}
+
+/* Assume that bmap semaphore is locked. */
+static inline void nilfs_bmap_clear_dirty(struct nilfs_bmap *bmap)
+{
+ bmap->b_state &= ~NILFS_BMAP_DIRTY;
+}
+
+
+#define NILFS_BMAP_LARGE 0x1
+
+#define NILFS_BMAP_SMALL_LOW NILFS_DIRECT_KEY_MIN
+#define NILFS_BMAP_SMALL_HIGH NILFS_DIRECT_KEY_MAX
+#define NILFS_BMAP_LARGE_LOW NILFS_BTREE_ROOT_NCHILDREN_MAX
+#define NILFS_BMAP_LARGE_HIGH NILFS_BTREE_KEY_MAX
+
+#endif /* _NILFS_BMAP_H */
diff --git a/fs/nilfs2/bmap_union.h b/fs/nilfs2/bmap_union.h
new file mode 100644
index 00000000000..d41509bff47
--- /dev/null
+++ b/fs/nilfs2/bmap_union.h
@@ -0,0 +1,42 @@
+/*
+ * bmap_union.h - NILFS block mapping.
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#ifndef _NILFS_BMAP_UNION_H
+#define _NILFS_BMAP_UNION_H
+
+#include "bmap.h"
+#include "direct.h"
+#include "btree.h"
+
+/**
+ * nilfs_bmap_union -
+ * @bi_bmap: bmap structure
+ * @bi_btree: direct map structure
+ * @bi_direct: B-tree structure
+ */
+union nilfs_bmap_union {
+ struct nilfs_bmap bi_bmap;
+ struct nilfs_direct bi_direct;
+ struct nilfs_btree bi_btree;
+};
+
+#endif /* _NILFS_BMAP_UNION_H */
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
new file mode 100644
index 00000000000..4cc07b2c30e
--- /dev/null
+++ b/fs/nilfs2/btnode.c
@@ -0,0 +1,316 @@
+/*
+ * btnode.c - NILFS B-tree node cache
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This file was originally written by Seiji Kihara <kihara@osrg.net>
+ * and fully revised by Ryusuke Konishi <ryusuke@osrg.net> for
+ * stabilization and simplification.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/buffer_head.h>
+#include <linux/mm.h>
+#include <linux/backing-dev.h>
+#include "nilfs.h"
+#include "mdt.h"
+#include "dat.h"
+#include "page.h"
+#include "btnode.h"
+
+
+void nilfs_btnode_cache_init_once(struct address_space *btnc)
+{
+ INIT_RADIX_TREE(&btnc->page_tree, GFP_ATOMIC);
+ spin_lock_init(&btnc->tree_lock);
+ INIT_LIST_HEAD(&btnc->private_list);
+ spin_lock_init(&btnc->private_lock);
+
+ spin_lock_init(&btnc->i_mmap_lock);
+ INIT_RAW_PRIO_TREE_ROOT(&btnc->i_mmap);
+ INIT_LIST_HEAD(&btnc->i_mmap_nonlinear);
+}
+
+static struct address_space_operations def_btnode_aops;
+
+void nilfs_btnode_cache_init(struct address_space *btnc)
+{
+ btnc->host = NULL; /* can safely set to host inode ? */
+ btnc->flags = 0;
+ mapping_set_gfp_mask(btnc, GFP_NOFS);
+ btnc->assoc_mapping = NULL;
+ btnc->backing_dev_info = &default_backing_dev_info;
+ btnc->a_ops = &def_btnode_aops;
+}
+
+void nilfs_btnode_cache_clear(struct address_space *btnc)
+{
+ invalidate_mapping_pages(btnc, 0, -1);
+ truncate_inode_pages(btnc, 0);
+}
+
+int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
+ sector_t pblocknr, struct buffer_head **pbh,
+ int newblk)
+{
+ struct buffer_head *bh;
+ struct inode *inode = NILFS_BTNC_I(btnc);
+ int err;
+
+ bh = nilfs_grab_buffer(inode, btnc, blocknr, 1 << BH_NILFS_Node);
+ if (unlikely(!bh))
+ return -ENOMEM;
+
+ err = -EEXIST; /* internal code */
+ if (newblk) {
+ if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) ||
+ buffer_dirty(bh))) {
+ brelse(bh);
+ BUG();
+ }
+ bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
+ bh->b_blocknr = blocknr;
+ set_buffer_mapped(bh);
+ set_buffer_uptodate(bh);
+ goto found;
+ }
+
+ if (buffer_uptodate(bh) || buffer_dirty(bh))
+ goto found;
+
+ if (pblocknr == 0) {
+ pblocknr = blocknr;
+ if (inode->i_ino != NILFS_DAT_INO) {
+ struct inode *dat =
+ nilfs_dat_inode(NILFS_I_NILFS(inode));
+
+ /* blocknr is a virtual block number */
+ err = nilfs_dat_translate(dat, blocknr, &pblocknr);
+ if (unlikely(err)) {
+ brelse(bh);
+ goto out_locked;
+ }
+ }
+ }
+ lock_buffer(bh);
+ if (buffer_uptodate(bh)) {
+ unlock_buffer(bh);
+ err = -EEXIST; /* internal code */
+ goto found;
+ }
+ set_buffer_mapped(bh);
+ bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
+ bh->b_blocknr = pblocknr; /* set block address for read */
+ bh->b_end_io = end_buffer_read_sync;
+ get_bh(bh);
+ submit_bh(READ, bh);
+ bh->b_blocknr = blocknr; /* set back to the given block address */
+ err = 0;
+found:
+ *pbh = bh;
+
+out_locked:
+ unlock_page(bh->b_page);
+ page_cache_release(bh->b_page);
+ return err;
+}
+
+int nilfs_btnode_get(struct address_space *btnc, __u64 blocknr,
+ sector_t pblocknr, struct buffer_head **pbh, int newblk)
+{
+ struct buffer_head *bh;
+ int err;
+
+ err = nilfs_btnode_submit_block(btnc, blocknr, pblocknr, pbh, newblk);
+ if (err == -EEXIST) /* internal code (cache hit) */
+ return 0;
+ if (unlikely(err))
+ return err;
+
+ bh = *pbh;
+ wait_on_buffer(bh);
+ if (!buffer_uptodate(bh)) {
+ brelse(bh);
+ return -EIO;
+ }
+ return 0;
+}
+
+/**
+ * nilfs_btnode_delete - delete B-tree node buffer
+ * @bh: buffer to be deleted
+ *
+ * nilfs_btnode_delete() invalidates the specified buffer and delete the page
+ * including the buffer if the page gets unbusy.
+ */
+void nilfs_btnode_delete(struct buffer_head *bh)
+{
+ struct address_space *mapping;
+ struct page *page = bh->b_page;
+ pgoff_t index = page_index(page);
+ int still_dirty;
+
+ page_cache_get(page);
+ lock_page(page);
+ wait_on_page_writeback(page);
+
+ nilfs_forget_buffer(bh);
+ still_dirty = PageDirty(page);
+ mapping = page->mapping;
+ unlock_page(page);
+ page_cache_release(page);
+
+ if (!still_dirty && mapping)
+ invalidate_inode_pages2_range(mapping, index, index);
+}
+
+/**
+ * nilfs_btnode_prepare_change_key
+ * prepare to move contents of the block for old key to one of new key.
+ * the old buffer will not be removed, but might be reused for new buffer.
+ * it might return -ENOMEM because of memory allocation errors,
+ * and might return -EIO because of disk read errors.
+ */
+int nilfs_btnode_prepare_change_key(struct address_space *btnc,
+ struct nilfs_btnode_chkey_ctxt *ctxt)
+{
+ struct buffer_head *obh, *nbh;
+ struct inode *inode = NILFS_BTNC_I(btnc);
+ __u64 oldkey = ctxt->oldkey, newkey = ctxt->newkey;
+ int err;
+
+ if (oldkey == newkey)
+ return 0;
+
+ obh = ctxt->bh;
+ ctxt->newbh = NULL;
+
+ if (inode->i_blkbits == PAGE_CACHE_SHIFT) {
+ lock_page(obh->b_page);
+ /*
+ * We cannot call radix_tree_preload for the kernels older
+ * than 2.6.23, because it is not exported for modules.
+ */
+ err = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
+ if (err)
+ goto failed_unlock;
+ /* BUG_ON(oldkey != obh->b_page->index); */
+ if (unlikely(oldkey != obh->b_page->index))
+ NILFS_PAGE_BUG(obh->b_page,
+ "invalid oldkey %lld (newkey=%lld)",
+ (unsigned long long)oldkey,
+ (unsigned long long)newkey);
+
+retry:
+ spin_lock_irq(&btnc->tree_lock);
+ err = radix_tree_insert(&btnc->page_tree, newkey, obh->b_page);
+ spin_unlock_irq(&btnc->tree_lock);
+ /*
+ * Note: page->index will not change to newkey until
+ * nilfs_btnode_commit_change_key() will be called.
+ * To protect the page in intermediate state, the page lock
+ * is held.
+ */
+ radix_tree_preload_end();
+ if (!err)
+ return 0;
+ else if (err != -EEXIST)
+ goto failed_unlock;
+
+ err = invalidate_inode_pages2_range(btnc, newkey, newkey);
+ if (!err)
+ goto retry;
+ /* fallback to copy mode */
+ unlock_page(obh->b_page);
+ }
+
+ err = nilfs_btnode_get(btnc, newkey, 0, &nbh, 1);
+ if (likely(!err)) {
+ BUG_ON(nbh == obh);
+ ctxt->newbh = nbh;
+ }
+ return err;
+
+ failed_unlock:
+ unlock_page(obh->b_page);
+ return err;
+}
+
+/**
+ * nilfs_btnode_commit_change_key
+ * commit the change_key operation prepared by prepare_change_key().
+ */
+void nilfs_btnode_commit_change_key(struct address_space *btnc,
+ struct nilfs_btnode_chkey_ctxt *ctxt)
+{
+ struct buffer_head *obh = ctxt->bh, *nbh = ctxt->newbh;
+ __u64 oldkey = ctxt->oldkey, newkey = ctxt->newkey;
+ struct page *opage;
+
+ if (oldkey == newkey)
+ return;
+
+ if (nbh == NULL) { /* blocksize == pagesize */
+ opage = obh->b_page;
+ if (unlikely(oldkey != opage->index))
+ NILFS_PAGE_BUG(opage,
+ "invalid oldkey %lld (newkey=%lld)",
+ (unsigned long long)oldkey,
+ (unsigned long long)newkey);
+ if (!test_set_buffer_dirty(obh) && TestSetPageDirty(opage))
+ BUG();
+
+ spin_lock_irq(&btnc->tree_lock);
+ radix_tree_delete(&btnc->page_tree, oldkey);
+ radix_tree_tag_set(&btnc->page_tree, newkey,
+ PAGECACHE_TAG_DIRTY);
+ spin_unlock_irq(&btnc->tree_lock);
+
+ opage->index = obh->b_blocknr = newkey;
+ unlock_page(opage);
+ } else {
+ nilfs_copy_buffer(nbh, obh);
+ nilfs_btnode_mark_dirty(nbh);
+
+ nbh->b_blocknr = newkey;
+ ctxt->bh = nbh;
+ nilfs_btnode_delete(obh); /* will decrement bh->b_count */
+ }
+}
+
+/**
+ * nilfs_btnode_abort_change_key
+ * abort the change_key operation prepared by prepare_change_key().
+ */
+void nilfs_btnode_abort_change_key(struct address_space *btnc,
+ struct nilfs_btnode_chkey_ctxt *ctxt)
+{
+ struct buffer_head *nbh = ctxt->newbh;
+ __u64 oldkey = ctxt->oldkey, newkey = ctxt->newkey;
+
+ if (oldkey == newkey)
+ return;
+
+ if (nbh == NULL) { /* blocksize == pagesize */
+ spin_lock_irq(&btnc->tree_lock);
+ radix_tree_delete(&btnc->page_tree, newkey);
+ spin_unlock_irq(&btnc->tree_lock);
+ unlock_page(ctxt->bh->b_page);
+ } else
+ brelse(nbh);
+}
diff --git a/fs/nilfs2/btnode.h b/fs/nilfs2/btnode.h
new file mode 100644
index 00000000000..35faa86444a
--- /dev/null
+++ b/fs/nilfs2/btnode.h
@@ -0,0 +1,58 @@
+/*
+ * btnode.h - NILFS B-tree node cache
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Seiji Kihara <kihara@osrg.net>
+ * Revised by Ryusuke Konishi <ryusuke@osrg.net>
+ */
+
+#ifndef _NILFS_BTNODE_H
+#define _NILFS_BTNODE_H
+
+#include <linux/types.h>
+#include <linux/buffer_head.h>
+#include <linux/fs.h>
+#include <linux/backing-dev.h>
+
+
+struct nilfs_btnode_chkey_ctxt {
+ __u64 oldkey;
+ __u64 newkey;
+ struct buffer_head *bh;
+ struct buffer_head *newbh;
+};
+
+void nilfs_btnode_cache_init_once(struct address_space *);
+void nilfs_btnode_cache_init(struct address_space *);
+void nilfs_btnode_cache_clear(struct address_space *);
+int nilfs_btnode_submit_block(struct address_space *, __u64, sector_t,
+ struct buffer_head **, int);
+int nilfs_btnode_get(struct address_space *, __u64, sector_t,
+ struct buffer_head **, int);
+void nilfs_btnode_delete(struct buffer_head *);
+int nilfs_btnode_prepare_change_key(struct address_space *,
+ struct nilfs_btnode_chkey_ctxt *);
+void nilfs_btnode_commit_change_key(struct address_space *,
+ struct nilfs_btnode_chkey_ctxt *);
+void nilfs_btnode_abort_change_key(struct address_space *,
+ struct nilfs_btnode_chkey_ctxt *);
+
+#define nilfs_btnode_mark_dirty(bh) nilfs_mark_buffer_dirty(bh)
+
+
+#endif /* _NILFS_BTNODE_H */
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
new file mode 100644
index 00000000000..6b37a276729
--- /dev/null
+++ b/fs/nilfs2/btree.c
@@ -0,0 +1,2269 @@
+/*
+ * btree.c - NILFS B-tree.
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/pagevec.h>
+#include "nilfs.h"
+#include "page.h"
+#include "btnode.h"
+#include "btree.h"
+#include "alloc.h"
+
+/**
+ * struct nilfs_btree_path - A path on which B-tree operations are executed
+ * @bp_bh: buffer head of node block
+ * @bp_sib_bh: buffer head of sibling node block
+ * @bp_index: index of child node
+ * @bp_oldreq: ptr end request for old ptr
+ * @bp_newreq: ptr alloc request for new ptr
+ * @bp_op: rebalance operation
+ */
+struct nilfs_btree_path {
+ struct buffer_head *bp_bh;
+ struct buffer_head *bp_sib_bh;
+ int bp_index;
+ union nilfs_bmap_ptr_req bp_oldreq;
+ union nilfs_bmap_ptr_req bp_newreq;
+ struct nilfs_btnode_chkey_ctxt bp_ctxt;
+ void (*bp_op)(struct nilfs_btree *, struct nilfs_btree_path *,
+ int, __u64 *, __u64 *);
+};
+
+/*
+ * B-tree path operations
+ */
+
+static struct kmem_cache *nilfs_btree_path_cache;
+
+int __init nilfs_btree_path_cache_init(void)
+{
+ nilfs_btree_path_cache =
+ kmem_cache_create("nilfs2_btree_path_cache",
+ sizeof(struct nilfs_btree_path) *
+ NILFS_BTREE_LEVEL_MAX, 0, 0, NULL);
+ return (nilfs_btree_path_cache != NULL) ? 0 : -ENOMEM;
+}
+
+void nilfs_btree_path_cache_destroy(void)
+{
+ kmem_cache_destroy(nilfs_btree_path_cache);
+}
+
+static inline struct nilfs_btree_path *
+nilfs_btree_alloc_path(const struct nilfs_btree *btree)
+{
+ return (struct nilfs_btree_path *)
+ kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS);
+}
+
+static inline void nilfs_btree_free_path(const struct nilfs_btree *btree,
+ struct nilfs_btree_path *path)
+{
+ kmem_cache_free(nilfs_btree_path_cache, path);
+}
+
+static void nilfs_btree_init_path(const struct nilfs_btree *btree,
+ struct nilfs_btree_path *path)
+{
+ int level;
+
+ for (level = NILFS_BTREE_LEVEL_DATA;
+ level < NILFS_BTREE_LEVEL_MAX;
+ level++) {
+ path[level].bp_bh = NULL;
+ path[level].bp_sib_bh = NULL;
+ path[level].bp_index = 0;
+ path[level].bp_oldreq.bpr_ptr = NILFS_BMAP_INVALID_PTR;
+ path[level].bp_newreq.bpr_ptr = NILFS_BMAP_INVALID_PTR;
+ path[level].bp_op = NULL;
+ }
+}
+
+static void nilfs_btree_clear_path(const struct nilfs_btree *btree,
+ struct nilfs_btree_path *path)
+{
+ int level;
+
+ for (level = NILFS_BTREE_LEVEL_DATA;
+ level < NILFS_BTREE_LEVEL_MAX;
+ level++) {
+ if (path[level].bp_bh != NULL) {
+ nilfs_bmap_put_block(&btree->bt_bmap,
+ path[level].bp_bh);
+ path[level].bp_bh = NULL;
+ }
+ /* sib_bh is released or deleted by prepare or commit
+ * operations. */
+ path[level].bp_sib_bh = NULL;
+ path[level].bp_index = 0;
+ path[level].bp_oldreq.bpr_ptr = NILFS_BMAP_INVALID_PTR;
+ path[level].bp_newreq.bpr_ptr = NILFS_BMAP_INVALID_PTR;
+ path[level].bp_op = NULL;
+ }
+}
+
+
+/*
+ * B-tree node operations
+ */
+
+static inline int
+nilfs_btree_node_get_flags(const struct nilfs_btree *btree,
+ const struct nilfs_btree_node *node)
+{
+ return node->bn_flags;
+}
+
+static inline void
+nilfs_btree_node_set_flags(struct nilfs_btree *btree,
+ struct nilfs_btree_node *node,
+ int flags)
+{
+ node->bn_flags = flags;
+}
+
+static inline int nilfs_btree_node_root(const struct nilfs_btree *btree,
+ const struct nilfs_btree_node *node)
+{
+ return nilfs_btree_node_get_flags(btree, node) & NILFS_BTREE_NODE_ROOT;
+}
+
+static inline int
+nilfs_btree_node_get_level(const struct nilfs_btree *btree,
+ const struct nilfs_btree_node *node)
+{
+ return node->bn_level;
+}
+
+static inline void
+nilfs_btree_node_set_level(struct nilfs_btree *btree,
+ struct nilfs_btree_node *node,
+ int level)
+{
+ node->bn_level = level;
+}
+
+static inline int
+nilfs_btree_node_get_nchildren(const struct nilfs_btree *btree,
+ const struct nilfs_btree_node *node)
+{
+ return le16_to_cpu(node->bn_nchildren);
+}
+
+static inline void
+nilfs_btree_node_set_nchildren(struct nilfs_btree *btree,
+ struct nilfs_btree_node *node,
+ int nchildren)
+{
+ node->bn_nchildren = cpu_to_le16(nchildren);
+}
+
+static inline int
+nilfs_btree_node_size(const struct nilfs_btree *btree)
+{
+ return 1 << btree->bt_bmap.b_inode->i_blkbits;
+}
+
+static inline int
+nilfs_btree_node_nchildren_min(const struct nilfs_btree *btree,
+ const struct nilfs_btree_node *node)
+{
+ return nilfs_btree_node_root(btree, node) ?
+ NILFS_BTREE_ROOT_NCHILDREN_MIN :
+ NILFS_BTREE_NODE_NCHILDREN_MIN(nilfs_btree_node_size(btree));
+}
+
+static inline int
+nilfs_btree_node_nchildren_max(const struct nilfs_btree *btree,
+ const struct nilfs_btree_node *node)
+{
+ return nilfs_btree_node_root(btree, node) ?
+ NILFS_BTREE_ROOT_NCHILDREN_MAX :
+ NILFS_BTREE_NODE_NCHILDREN_MAX(nilfs_btree_node_size(btree));
+}
+
+static inline __le64 *
+nilfs_btree_node_dkeys(const struct nilfs_btree *btree,
+ const struct nilfs_btree_node *node)
+{
+ return (__le64 *)((char *)(node + 1) +
+ (nilfs_btree_node_root(btree, node) ?
+ 0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE));
+}
+
+static inline __le64 *
+nilfs_btree_node_dptrs(const struct nilfs_btree *btree,
+ const struct nilfs_btree_node *node)
+{
+ return (__le64 *)(nilfs_btree_node_dkeys(btree, node) +
+ nilfs_btree_node_nchildren_max(btree, node));
+}
+
+static inline __u64
+nilfs_btree_node_get_key(const struct nilfs_btree *btree,
+ const struct nilfs_btree_node *node, int index)
+{
+ return nilfs_bmap_dkey_to_key(*(nilfs_btree_node_dkeys(btree, node) +
+ index));
+}
+
+static inline void
+nilfs_btree_node_set_key(struct nilfs_btree *btree,
+ struct nilfs_btree_node *node, int index, __u64 key)
+{
+ *(nilfs_btree_node_dkeys(btree, node) + index) =
+ nilfs_bmap_key_to_dkey(key);
+}
+
+static inline __u64
+nilfs_btree_node_get_ptr(const struct nilfs_btree *btree,
+ const struct nilfs_btree_node *node,
+ int index)
+{
+ return nilfs_bmap_dptr_to_ptr(*(nilfs_btree_node_dptrs(btree, node) +
+ index));
+}
+
+static inline void
+nilfs_btree_node_set_ptr(struct nilfs_btree *btree,
+ struct nilfs_btree_node *node,
+ int index,
+ __u64 ptr)
+{
+ *(nilfs_btree_node_dptrs(btree, node) + index) =
+ nilfs_bmap_ptr_to_dptr(ptr);
+}
+
+static void nilfs_btree_node_init(struct nilfs_btree *btree,
+ struct nilfs_btree_node *node,
+ int flags, int level, int nchildren,
+ const __u64 *keys, const __u64 *ptrs)
+{
+ __le64 *dkeys;
+ __le64 *dptrs;
+ int i;
+
+ nilfs_btree_node_set_flags(btree, node, flags);
+ nilfs_btree_node_set_level(btree, node, level);
+ nilfs_btree_node_set_nchildren(btree, node, nchildren);
+
+ dkeys = nilfs_btree_node_dkeys(btree, node);
+ dptrs = nilfs_btree_node_dptrs(btree, node);
+ for (i = 0; i < nchildren; i++) {
+ dkeys[i] = nilfs_bmap_key_to_dkey(keys[i]);
+ dptrs[i] = nilfs_bmap_ptr_to_dptr(ptrs[i]);
+ }
+}
+
+/* Assume the buffer heads corresponding to left and right are locked. */
+static void nilfs_btree_node_move_left(struct nilfs_btree *btree,
+ struct nilfs_btree_node *left,
+ struct nilfs_btree_node *right,
+ int n)
+{
+ __le64 *ldkeys, *rdkeys;
+ __le64 *ldptrs, *rdptrs;
+ int lnchildren, rnchildren;
+
+ ldkeys = nilfs_btree_node_dkeys(btree, left);
+ ldptrs = nilfs_btree_node_dptrs(btree, left);
+ lnchildren = nilfs_btree_node_get_nchildren(btree, left);
+
+ rdkeys = nilfs_btree_node_dkeys(btree, right);
+ rdptrs = nilfs_btree_node_dptrs(btree, right);
+ rnchildren = nilfs_btree_node_get_nchildren(btree, right);
+
+ memcpy(ldkeys + lnchildren, rdkeys, n * sizeof(*rdkeys));
+ memcpy(ldptrs + lnchildren, rdptrs, n * sizeof(*rdptrs));
+ memmove(rdkeys, rdkeys + n, (rnchildren - n) * sizeof(*rdkeys));
+ memmove(rdptrs, rdptrs + n, (rnchildren - n) * sizeof(*rdptrs));
+
+ lnchildren += n;
+ rnchildren -= n;
+ nilfs_btree_node_set_nchildren(btree, left, lnchildren);
+ nilfs_btree_node_set_nchildren(btree, right, rnchildren);
+}
+
+/* Assume that the buffer heads corresponding to left and right are locked. */
+static void nilfs_btree_node_move_right(struct nilfs_btree *btree,
+ struct nilfs_btree_node *left,
+ struct nilfs_btree_node *right,
+ int n)
+{
+ __le64 *ldkeys, *rdkeys;
+ __le64 *ldptrs, *rdptrs;
+ int lnchildren, rnchildren;
+
+ ldkeys = nilfs_btree_node_dkeys(btree, left);
+ ldptrs = nilfs_btree_node_dptrs(btree, left);
+ lnchildren = nilfs_btree_node_get_nchildren(btree, left);
+
+ rdkeys = nilfs_btree_node_dkeys(btree, right);
+ rdptrs = nilfs_btree_node_dptrs(btree, right);
+ rnchildren = nilfs_btree_node_get_nchildren(btree, right);
+
+ memmove(rdkeys + n, rdkeys, rnchildren * sizeof(*rdkeys));
+ memmove(rdptrs + n, rdptrs, rnchildren * sizeof(*rdptrs));
+ memcpy(rdkeys, ldkeys + lnchildren - n, n * sizeof(*rdkeys));
+ memcpy(rdptrs, ldptrs + lnchildren - n, n * sizeof(*rdptrs));
+
+ lnchildren -= n;
+ rnchildren += n;
+ nilfs_btree_node_set_nchildren(btree, left, lnchildren);
+ nilfs_btree_node_set_nchildren(btree, right, rnchildren);
+}
+
+/* Assume that the buffer head corresponding to node is locked. */
+static void nilfs_btree_node_insert(struct nilfs_btree *btree,
+ struct nilfs_btree_node *node,
+ __u64 key, __u64 ptr, int index)
+{
+ __le64 *dkeys;
+ __le64 *dptrs;
+ int nchildren;
+
+ dkeys = nilfs_btree_node_dkeys(btree, node);
+ dptrs = nilfs_btree_node_dptrs(btree, node);
+ nchildren = nilfs_btree_node_get_nchildren(btree, node);
+ if (index < nchildren) {
+ memmove(dkeys + index + 1, dkeys + index,
+ (nchildren - index) * sizeof(*dkeys));
+ memmove(dptrs + index + 1, dptrs + index,
+ (nchildren - index) * sizeof(*dptrs));
+ }
+ dkeys[index] = nilfs_bmap_key_to_dkey(key);
+ dptrs[index] = nilfs_bmap_ptr_to_dptr(ptr);
+ nchildren++;
+ nilfs_btree_node_set_nchildren(btree, node, nchildren);
+}
+
+/* Assume that the buffer head corresponding to node is locked. */
+static void nilfs_btree_node_delete(struct nilfs_btree *btree,
+ struct nilfs_btree_node *node,
+ __u64 *keyp, __u64 *ptrp, int index)
+{
+ __u64 key;
+ __u64 ptr;
+ __le64 *dkeys;
+ __le64 *dptrs;
+ int nchildren;
+
+ dkeys = nilfs_btree_node_dkeys(btree, node);
+ dptrs = nilfs_btree_node_dptrs(btree, node);
+ key = nilfs_bmap_dkey_to_key(dkeys[index]);
+ ptr = nilfs_bmap_dptr_to_ptr(dptrs[index]);
+ nchildren = nilfs_btree_node_get_nchildren(btree, node);
+ if (keyp != NULL)
+ *keyp = key;
+ if (ptrp != NULL)
+ *ptrp = ptr;
+
+ if (index < nchildren - 1) {
+ memmove(dkeys + index, dkeys + index + 1,
+ (nchildren - index - 1) * sizeof(*dkeys));
+ memmove(dptrs + index, dptrs + index + 1,
+ (nchildren - index - 1) * sizeof(*dptrs));
+ }
+ nchildren--;
+ nilfs_btree_node_set_nchildren(btree, node, nchildren);
+}
+
+static int nilfs_btree_node_lookup(const struct nilfs_btree *btree,
+ const struct nilfs_btree_node *node,
+ __u64 key, int *indexp)
+{
+ __u64 nkey;
+ int index, low, high, s;
+
+ /* binary search */
+ low = 0;
+ high = nilfs_btree_node_get_nchildren(btree, node) - 1;
+ index = 0;
+ s = 0;
+ while (low <= high) {
+ index = (low + high) / 2;
+ nkey = nilfs_btree_node_get_key(btree, node, index);
+ if (nkey == key) {
+ s = 0;
+ goto out;
+ } else if (nkey < key) {
+ low = index + 1;
+ s = -1;
+ } else {
+ high = index - 1;
+ s = 1;
+ }
+ }
+
+ /* adjust index */
+ if (nilfs_btree_node_get_level(btree, node) >
+ NILFS_BTREE_LEVEL_NODE_MIN) {
+ if ((s > 0) && (index > 0))
+ index--;
+ } else if (s < 0)
+ index++;
+
+ out:
+ *indexp = index;
+
+ return s == 0;
+}
+
+static inline struct nilfs_btree_node *
+nilfs_btree_get_root(const struct nilfs_btree *btree)
+{
+ return (struct nilfs_btree_node *)btree->bt_bmap.b_u.u_data;
+}
+
+static inline struct nilfs_btree_node *
+nilfs_btree_get_nonroot_node(const struct nilfs_btree *btree,
+ const struct nilfs_btree_path *path,
+ int level)
+{
+ return (struct nilfs_btree_node *)path[level].bp_bh->b_data;
+}
+
+static inline struct nilfs_btree_node *
+nilfs_btree_get_sib_node(const struct nilfs_btree *btree,
+ const struct nilfs_btree_path *path,
+ int level)
+{
+ return (struct nilfs_btree_node *)path[level].bp_sib_bh->b_data;
+}
+
+static inline int nilfs_btree_height(const struct nilfs_btree *btree)
+{
+ return nilfs_btree_node_get_level(btree, nilfs_btree_get_root(btree))
+ + 1;
+}
+
+static inline struct nilfs_btree_node *
+nilfs_btree_get_node(const struct nilfs_btree *btree,
+ const struct nilfs_btree_path *path,
+ int level)
+{
+ return (level == nilfs_btree_height(btree) - 1) ?
+ nilfs_btree_get_root(btree) :
+ nilfs_btree_get_nonroot_node(btree, path, level);
+}
+
+static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ __u64 key, __u64 *ptrp, int minlevel)
+{
+ struct nilfs_btree_node *node;
+ __u64 ptr;
+ int level, index, found, ret;
+
+ node = nilfs_btree_get_root(btree);
+ level = nilfs_btree_node_get_level(btree, node);
+ if ((level < minlevel) ||
+ (nilfs_btree_node_get_nchildren(btree, node) <= 0))
+ return -ENOENT;
+
+ found = nilfs_btree_node_lookup(btree, node, key, &index);
+ ptr = nilfs_btree_node_get_ptr(btree, node, index);
+ path[level].bp_bh = NULL;
+ path[level].bp_index = index;
+
+ for (level--; level >= minlevel; level--) {
+ ret = nilfs_bmap_get_block(&btree->bt_bmap, ptr,
+ &path[level].bp_bh);
+ if (ret < 0)
+ return ret;
+ node = nilfs_btree_get_nonroot_node(btree, path, level);
+ BUG_ON(level != nilfs_btree_node_get_level(btree, node));
+ if (!found)
+ found = nilfs_btree_node_lookup(btree, node, key,
+ &index);
+ else
+ index = 0;
+ if (index < nilfs_btree_node_nchildren_max(btree, node))
+ ptr = nilfs_btree_node_get_ptr(btree, node, index);
+ else {
+ WARN_ON(found || level != NILFS_BTREE_LEVEL_NODE_MIN);
+ /* insert */
+ ptr = NILFS_BMAP_INVALID_PTR;
+ }
+ path[level].bp_index = index;
+ }
+ if (!found)
+ return -ENOENT;
+
+ if (ptrp != NULL)
+ *ptrp = ptr;
+
+ return 0;
+}
+
+static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ __u64 *keyp, __u64 *ptrp)
+{
+ struct nilfs_btree_node *node;
+ __u64 ptr;
+ int index, level, ret;
+
+ node = nilfs_btree_get_root(btree);
+ index = nilfs_btree_node_get_nchildren(btree, node) - 1;
+ if (index < 0)
+ return -ENOENT;
+ level = nilfs_btree_node_get_level(btree, node);
+ ptr = nilfs_btree_node_get_ptr(btree, node, index);
+ path[level].bp_bh = NULL;
+ path[level].bp_index = index;
+
+ for (level--; level > 0; level--) {
+ ret = nilfs_bmap_get_block(&btree->bt_bmap, ptr,
+ &path[level].bp_bh);
+ if (ret < 0)
+ return ret;
+ node = nilfs_btree_get_nonroot_node(btree, path, level);
+ BUG_ON(level != nilfs_btree_node_get_level(btree, node));
+ index = nilfs_btree_node_get_nchildren(btree, node) - 1;
+ ptr = nilfs_btree_node_get_ptr(btree, node, index);
+ path[level].bp_index = index;
+ }
+
+ if (keyp != NULL)
+ *keyp = nilfs_btree_node_get_key(btree, node, index);
+ if (ptrp != NULL)
+ *ptrp = ptr;
+
+ return 0;
+}
+
+static int nilfs_btree_lookup(const struct nilfs_bmap *bmap,
+ __u64 key, int level, __u64 *ptrp)
+{
+ struct nilfs_btree *btree;
+ struct nilfs_btree_path *path;
+ __u64 ptr;
+ int ret;
+
+ btree = (struct nilfs_btree *)bmap;
+ path = nilfs_btree_alloc_path(btree);
+ if (path == NULL)
+ return -ENOMEM;
+ nilfs_btree_init_path(btree, path);
+
+ ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level);
+
+ if (ptrp != NULL)
+ *ptrp = ptr;
+
+ nilfs_btree_clear_path(btree, path);
+ nilfs_btree_free_path(btree, path);
+
+ return ret;
+}
+
+static void nilfs_btree_promote_key(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level, __u64 key)
+{
+ if (level < nilfs_btree_height(btree) - 1) {
+ do {
+ lock_buffer(path[level].bp_bh);
+ nilfs_btree_node_set_key(
+ btree,
+ nilfs_btree_get_nonroot_node(
+ btree, path, level),
+ path[level].bp_index, key);
+ if (!buffer_dirty(path[level].bp_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_bh);
+ unlock_buffer(path[level].bp_bh);
+ } while ((path[level].bp_index == 0) &&
+ (++level < nilfs_btree_height(btree) - 1));
+ }
+
+ /* root */
+ if (level == nilfs_btree_height(btree) - 1) {
+ nilfs_btree_node_set_key(btree,
+ nilfs_btree_get_root(btree),
+ path[level].bp_index, key);
+ }
+}
+
+static void nilfs_btree_do_insert(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level, __u64 *keyp, __u64 *ptrp)
+{
+ struct nilfs_btree_node *node;
+
+ if (level < nilfs_btree_height(btree) - 1) {
+ lock_buffer(path[level].bp_bh);
+ node = nilfs_btree_get_nonroot_node(btree, path, level);
+ nilfs_btree_node_insert(btree, node, *keyp, *ptrp,
+ path[level].bp_index);
+ if (!buffer_dirty(path[level].bp_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_bh);
+ unlock_buffer(path[level].bp_bh);
+
+ if (path[level].bp_index == 0)
+ nilfs_btree_promote_key(btree, path, level + 1,
+ nilfs_btree_node_get_key(
+ btree, node, 0));
+ } else {
+ node = nilfs_btree_get_root(btree);
+ nilfs_btree_node_insert(btree, node, *keyp, *ptrp,
+ path[level].bp_index);
+ }
+}
+
+static void nilfs_btree_carry_left(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level, __u64 *keyp, __u64 *ptrp)
+{
+ struct nilfs_btree_node *node, *left;
+ int nchildren, lnchildren, n, move;
+
+ lock_buffer(path[level].bp_bh);
+ lock_buffer(path[level].bp_sib_bh);
+
+ node = nilfs_btree_get_nonroot_node(btree, path, level);
+ left = nilfs_btree_get_sib_node(btree, path, level);
+ nchildren = nilfs_btree_node_get_nchildren(btree, node);
+ lnchildren = nilfs_btree_node_get_nchildren(btree, left);
+ move = 0;
+
+ n = (nchildren + lnchildren + 1) / 2 - lnchildren;
+ if (n > path[level].bp_index) {
+ /* move insert point */
+ n--;
+ move = 1;
+ }
+
+ nilfs_btree_node_move_left(btree, left, node, n);
+
+ if (!buffer_dirty(path[level].bp_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_bh);
+ if (!buffer_dirty(path[level].bp_sib_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
+
+ unlock_buffer(path[level].bp_bh);
+ unlock_buffer(path[level].bp_sib_bh);
+
+ nilfs_btree_promote_key(btree, path, level + 1,
+ nilfs_btree_node_get_key(btree, node, 0));
+
+ if (move) {
+ nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_bh);
+ path[level].bp_bh = path[level].bp_sib_bh;
+ path[level].bp_sib_bh = NULL;
+ path[level].bp_index += lnchildren;
+ path[level + 1].bp_index--;
+ } else {
+ nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+ path[level].bp_sib_bh = NULL;
+ path[level].bp_index -= n;
+ }
+
+ nilfs_btree_do_insert(btree, path, level, keyp, ptrp);
+}
+
+static void nilfs_btree_carry_right(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level, __u64 *keyp, __u64 *ptrp)
+{
+ struct nilfs_btree_node *node, *right;
+ int nchildren, rnchildren, n, move;
+
+ lock_buffer(path[level].bp_bh);
+ lock_buffer(path[level].bp_sib_bh);
+
+ node = nilfs_btree_get_nonroot_node(btree, path, level);
+ right = nilfs_btree_get_sib_node(btree, path, level);
+ nchildren = nilfs_btree_node_get_nchildren(btree, node);
+ rnchildren = nilfs_btree_node_get_nchildren(btree, right);
+ move = 0;
+
+ n = (nchildren + rnchildren + 1) / 2 - rnchildren;
+ if (n > nchildren - path[level].bp_index) {
+ /* move insert point */
+ n--;
+ move = 1;
+ }
+
+ nilfs_btree_node_move_right(btree, node, right, n);
+
+ if (!buffer_dirty(path[level].bp_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_bh);
+ if (!buffer_dirty(path[level].bp_sib_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
+
+ unlock_buffer(path[level].bp_bh);
+ unlock_buffer(path[level].bp_sib_bh);
+
+ path[level + 1].bp_index++;
+ nilfs_btree_promote_key(btree, path, level + 1,
+ nilfs_btree_node_get_key(btree, right, 0));
+ path[level + 1].bp_index--;
+
+ if (move) {
+ nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_bh);
+ path[level].bp_bh = path[level].bp_sib_bh;
+ path[level].bp_sib_bh = NULL;
+ path[level].bp_index -=
+ nilfs_btree_node_get_nchildren(btree, node);
+ path[level + 1].bp_index++;
+ } else {
+ nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+ path[level].bp_sib_bh = NULL;
+ }
+
+ nilfs_btree_do_insert(btree, path, level, keyp, ptrp);
+}
+
+static void nilfs_btree_split(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level, __u64 *keyp, __u64 *ptrp)
+{
+ struct nilfs_btree_node *node, *right;
+ __u64 newkey;
+ __u64 newptr;
+ int nchildren, n, move;
+
+ lock_buffer(path[level].bp_bh);
+ lock_buffer(path[level].bp_sib_bh);
+
+ node = nilfs_btree_get_nonroot_node(btree, path, level);
+ right = nilfs_btree_get_sib_node(btree, path, level);
+ nchildren = nilfs_btree_node_get_nchildren(btree, node);
+ move = 0;
+
+ n = (nchildren + 1) / 2;
+ if (n > nchildren - path[level].bp_index) {
+ n--;
+ move = 1;
+ }
+
+ nilfs_btree_node_move_right(btree, node, right, n);
+
+ if (!buffer_dirty(path[level].bp_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_bh);
+ if (!buffer_dirty(path[level].bp_sib_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
+
+ unlock_buffer(path[level].bp_bh);
+ unlock_buffer(path[level].bp_sib_bh);
+
+ newkey = nilfs_btree_node_get_key(btree, right, 0);
+ newptr = path[level].bp_newreq.bpr_ptr;
+
+ if (move) {
+ path[level].bp_index -=
+ nilfs_btree_node_get_nchildren(btree, node);
+ nilfs_btree_node_insert(btree, right, *keyp, *ptrp,
+ path[level].bp_index);
+
+ *keyp = nilfs_btree_node_get_key(btree, right, 0);
+ *ptrp = path[level].bp_newreq.bpr_ptr;
+
+ nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_bh);
+ path[level].bp_bh = path[level].bp_sib_bh;
+ path[level].bp_sib_bh = NULL;
+ } else {
+ nilfs_btree_do_insert(btree, path, level, keyp, ptrp);
+
+ *keyp = nilfs_btree_node_get_key(btree, right, 0);
+ *ptrp = path[level].bp_newreq.bpr_ptr;
+
+ nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+ path[level].bp_sib_bh = NULL;
+ }
+
+ path[level + 1].bp_index++;
+}
+
+static void nilfs_btree_grow(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level, __u64 *keyp, __u64 *ptrp)
+{
+ struct nilfs_btree_node *root, *child;
+ int n;
+
+ lock_buffer(path[level].bp_sib_bh);
+
+ root = nilfs_btree_get_root(btree);
+ child = nilfs_btree_get_sib_node(btree, path, level);
+
+ n = nilfs_btree_node_get_nchildren(btree, root);
+
+ nilfs_btree_node_move_right(btree, root, child, n);
+ nilfs_btree_node_set_level(btree, root, level + 1);
+
+ if (!buffer_dirty(path[level].bp_sib_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
+
+ unlock_buffer(path[level].bp_sib_bh);
+
+ path[level].bp_bh = path[level].bp_sib_bh;
+ path[level].bp_sib_bh = NULL;
+
+ nilfs_btree_do_insert(btree, path, level, keyp, ptrp);
+
+ *keyp = nilfs_btree_node_get_key(btree, child, 0);
+ *ptrp = path[level].bp_newreq.bpr_ptr;
+}
+
+static __u64 nilfs_btree_find_near(const struct nilfs_btree *btree,
+ const struct nilfs_btree_path *path)
+{
+ struct nilfs_btree_node *node;
+ int level;
+
+ if (path == NULL)
+ return NILFS_BMAP_INVALID_PTR;
+
+ /* left sibling */
+ level = NILFS_BTREE_LEVEL_NODE_MIN;
+ if (path[level].bp_index > 0) {
+ node = nilfs_btree_get_node(btree, path, level);
+ return nilfs_btree_node_get_ptr(btree, node,
+ path[level].bp_index - 1);
+ }
+
+ /* parent */
+ level = NILFS_BTREE_LEVEL_NODE_MIN + 1;
+ if (level <= nilfs_btree_height(btree) - 1) {
+ node = nilfs_btree_get_node(btree, path, level);
+ return nilfs_btree_node_get_ptr(btree, node,
+ path[level].bp_index);
+ }
+
+ return NILFS_BMAP_INVALID_PTR;
+}
+
+static __u64 nilfs_btree_find_target_v(const struct nilfs_btree *btree,
+ const struct nilfs_btree_path *path,
+ __u64 key)
+{
+ __u64 ptr;
+
+ ptr = nilfs_bmap_find_target_seq(&btree->bt_bmap, key);
+ if (ptr != NILFS_BMAP_INVALID_PTR)
+ /* sequential access */
+ return ptr;
+ else {
+ ptr = nilfs_btree_find_near(btree, path);
+ if (ptr != NILFS_BMAP_INVALID_PTR)
+ /* near */
+ return ptr;
+ }
+ /* block group */
+ return nilfs_bmap_find_target_in_group(&btree->bt_bmap);
+}
+
+static void nilfs_btree_set_target_v(struct nilfs_btree *btree, __u64 key,
+ __u64 ptr)
+{
+ btree->bt_bmap.b_last_allocated_key = key;
+ btree->bt_bmap.b_last_allocated_ptr = ptr;
+}
+
+static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int *levelp, __u64 key, __u64 ptr,
+ struct nilfs_bmap_stats *stats)
+{
+ struct buffer_head *bh;
+ struct nilfs_btree_node *node, *parent, *sib;
+ __u64 sibptr;
+ int pindex, level, ret;
+
+ stats->bs_nblocks = 0;
+ level = NILFS_BTREE_LEVEL_DATA;
+
+ /* allocate a new ptr for data block */
+ if (btree->bt_ops->btop_find_target != NULL)
+ path[level].bp_newreq.bpr_ptr =
+ btree->bt_ops->btop_find_target(btree, path, key);
+
+ ret = btree->bt_bmap.b_pops->bpop_prepare_alloc_ptr(
+ &btree->bt_bmap, &path[level].bp_newreq);
+ if (ret < 0)
+ goto err_out_data;
+
+ for (level = NILFS_BTREE_LEVEL_NODE_MIN;
+ level < nilfs_btree_height(btree) - 1;
+ level++) {
+ node = nilfs_btree_get_nonroot_node(btree, path, level);
+ if (nilfs_btree_node_get_nchildren(btree, node) <
+ nilfs_btree_node_nchildren_max(btree, node)) {
+ path[level].bp_op = nilfs_btree_do_insert;
+ stats->bs_nblocks++;
+ goto out;
+ }
+
+ parent = nilfs_btree_get_node(btree, path, level + 1);
+ pindex = path[level + 1].bp_index;
+
+ /* left sibling */
+ if (pindex > 0) {
+ sibptr = nilfs_btree_node_get_ptr(btree, parent,
+ pindex - 1);
+ ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr,
+ &bh);
+ if (ret < 0)
+ goto err_out_child_node;
+ sib = (struct nilfs_btree_node *)bh->b_data;
+ if (nilfs_btree_node_get_nchildren(btree, sib) <
+ nilfs_btree_node_nchildren_max(btree, sib)) {
+ path[level].bp_sib_bh = bh;
+ path[level].bp_op = nilfs_btree_carry_left;
+ stats->bs_nblocks++;
+ goto out;
+ } else
+ nilfs_bmap_put_block(&btree->bt_bmap, bh);
+ }
+
+ /* right sibling */
+ if (pindex <
+ nilfs_btree_node_get_nchildren(btree, parent) - 1) {
+ sibptr = nilfs_btree_node_get_ptr(btree, parent,
+ pindex + 1);
+ ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr,
+ &bh);
+ if (ret < 0)
+ goto err_out_child_node;
+ sib = (struct nilfs_btree_node *)bh->b_data;
+ if (nilfs_btree_node_get_nchildren(btree, sib) <
+ nilfs_btree_node_nchildren_max(btree, sib)) {
+ path[level].bp_sib_bh = bh;
+ path[level].bp_op = nilfs_btree_carry_right;
+ stats->bs_nblocks++;
+ goto out;
+ } else
+ nilfs_bmap_put_block(&btree->bt_bmap, bh);
+ }
+
+ /* split */
+ path[level].bp_newreq.bpr_ptr =
+ path[level - 1].bp_newreq.bpr_ptr + 1;
+ ret = btree->bt_bmap.b_pops->bpop_prepare_alloc_ptr(
+ &btree->bt_bmap, &path[level].bp_newreq);
+ if (ret < 0)
+ goto err_out_child_node;
+ ret = nilfs_bmap_get_new_block(&btree->bt_bmap,
+ path[level].bp_newreq.bpr_ptr,
+ &bh);
+ if (ret < 0)
+ goto err_out_curr_node;
+
+ stats->bs_nblocks++;
+
+ lock_buffer(bh);
+ nilfs_btree_node_init(btree,
+ (struct nilfs_btree_node *)bh->b_data,
+ 0, level, 0, NULL, NULL);
+ unlock_buffer(bh);
+ path[level].bp_sib_bh = bh;
+ path[level].bp_op = nilfs_btree_split;
+ }
+
+ /* root */
+ node = nilfs_btree_get_root(btree);
+ if (nilfs_btree_node_get_nchildren(btree, node) <
+ nilfs_btree_node_nchildren_max(btree, node)) {
+ path[level].bp_op = nilfs_btree_do_insert;
+ stats->bs_nblocks++;
+ goto out;
+ }
+
+ /* grow */
+ path[level].bp_newreq.bpr_ptr = path[level - 1].bp_newreq.bpr_ptr + 1;
+ ret = btree->bt_bmap.b_pops->bpop_prepare_alloc_ptr(
+ &btree->bt_bmap, &path[level].bp_newreq);
+ if (ret < 0)
+ goto err_out_child_node;
+ ret = nilfs_bmap_get_new_block(&btree->bt_bmap,
+ path[level].bp_newreq.bpr_ptr, &bh);
+ if (ret < 0)
+ goto err_out_curr_node;
+
+ lock_buffer(bh);
+ nilfs_btree_node_init(btree, (struct nilfs_btree_node *)bh->b_data,
+ 0, level, 0, NULL, NULL);
+ unlock_buffer(bh);
+ path[level].bp_sib_bh = bh;
+ path[level].bp_op = nilfs_btree_grow;
+
+ level++;
+ path[level].bp_op = nilfs_btree_do_insert;
+
+ /* a newly-created node block and a data block are added */
+ stats->bs_nblocks += 2;
+
+ /* success */
+ out:
+ *levelp = level;
+ return ret;
+
+ /* error */
+ err_out_curr_node:
+ btree->bt_bmap.b_pops->bpop_abort_alloc_ptr(&btree->bt_bmap,
+ &path[level].bp_newreq);
+ err_out_child_node:
+ for (level--; level > NILFS_BTREE_LEVEL_DATA; level--) {
+ nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_sib_bh);
+ btree->bt_bmap.b_pops->bpop_abort_alloc_ptr(
+ &btree->bt_bmap, &path[level].bp_newreq);
+
+ }
+
+ btree->bt_bmap.b_pops->bpop_abort_alloc_ptr(&btree->bt_bmap,
+ &path[level].bp_newreq);
+ err_out_data:
+ *levelp = level;
+ stats->bs_nblocks = 0;
+ return ret;
+}
+
+static void nilfs_btree_commit_insert(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int maxlevel, __u64 key, __u64 ptr)
+{
+ int level;
+
+ set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr));
+ ptr = path[NILFS_BTREE_LEVEL_DATA].bp_newreq.bpr_ptr;
+ if (btree->bt_ops->btop_set_target != NULL)
+ btree->bt_ops->btop_set_target(btree, key, ptr);
+
+ for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) {
+ if (btree->bt_bmap.b_pops->bpop_commit_alloc_ptr != NULL) {
+ btree->bt_bmap.b_pops->bpop_commit_alloc_ptr(
+ &btree->bt_bmap, &path[level - 1].bp_newreq);
+ }
+ path[level].bp_op(btree, path, level, &key, &ptr);
+ }
+
+ if (!nilfs_bmap_dirty(&btree->bt_bmap))
+ nilfs_bmap_set_dirty(&btree->bt_bmap);
+}
+
+static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
+{
+ struct nilfs_btree *btree;
+ struct nilfs_btree_path *path;
+ struct nilfs_bmap_stats stats;
+ int level, ret;
+
+ btree = (struct nilfs_btree *)bmap;
+ path = nilfs_btree_alloc_path(btree);
+ if (path == NULL)
+ return -ENOMEM;
+ nilfs_btree_init_path(btree, path);
+
+ ret = nilfs_btree_do_lookup(btree, path, key, NULL,
+ NILFS_BTREE_LEVEL_NODE_MIN);
+ if (ret != -ENOENT) {
+ if (ret == 0)
+ ret = -EEXIST;
+ goto out;
+ }
+
+ ret = nilfs_btree_prepare_insert(btree, path, &level, key, ptr, &stats);
+ if (ret < 0)
+ goto out;
+ nilfs_btree_commit_insert(btree, path, level, key, ptr);
+ nilfs_bmap_add_blocks(bmap, stats.bs_nblocks);
+
+ out:
+ nilfs_btree_clear_path(btree, path);
+ nilfs_btree_free_path(btree, path);
+ return ret;
+}
+
+static void nilfs_btree_do_delete(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level, __u64 *keyp, __u64 *ptrp)
+{
+ struct nilfs_btree_node *node;
+
+ if (level < nilfs_btree_height(btree) - 1) {
+ lock_buffer(path[level].bp_bh);
+ node = nilfs_btree_get_nonroot_node(btree, path, level);
+ nilfs_btree_node_delete(btree, node, keyp, ptrp,
+ path[level].bp_index);
+ if (!buffer_dirty(path[level].bp_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_bh);
+ unlock_buffer(path[level].bp_bh);
+ if (path[level].bp_index == 0)
+ nilfs_btree_promote_key(btree, path, level + 1,
+ nilfs_btree_node_get_key(btree, node, 0));
+ } else {
+ node = nilfs_btree_get_root(btree);
+ nilfs_btree_node_delete(btree, node, keyp, ptrp,
+ path[level].bp_index);
+ }
+}
+
+static void nilfs_btree_borrow_left(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level, __u64 *keyp, __u64 *ptrp)
+{
+ struct nilfs_btree_node *node, *left;
+ int nchildren, lnchildren, n;
+
+ nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
+
+ lock_buffer(path[level].bp_bh);
+ lock_buffer(path[level].bp_sib_bh);
+
+ node = nilfs_btree_get_nonroot_node(btree, path, level);
+ left = nilfs_btree_get_sib_node(btree, path, level);
+ nchildren = nilfs_btree_node_get_nchildren(btree, node);
+ lnchildren = nilfs_btree_node_get_nchildren(btree, left);
+
+ n = (nchildren + lnchildren) / 2 - nchildren;
+
+ nilfs_btree_node_move_right(btree, left, node, n);
+
+ if (!buffer_dirty(path[level].bp_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_bh);
+ if (!buffer_dirty(path[level].bp_sib_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
+
+ unlock_buffer(path[level].bp_bh);
+ unlock_buffer(path[level].bp_sib_bh);
+
+ nilfs_btree_promote_key(btree, path, level + 1,
+ nilfs_btree_node_get_key(btree, node, 0));
+
+ nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+ path[level].bp_sib_bh = NULL;
+ path[level].bp_index += n;
+}
+
+static void nilfs_btree_borrow_right(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level, __u64 *keyp, __u64 *ptrp)
+{
+ struct nilfs_btree_node *node, *right;
+ int nchildren, rnchildren, n;
+
+ nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
+
+ lock_buffer(path[level].bp_bh);
+ lock_buffer(path[level].bp_sib_bh);
+
+ node = nilfs_btree_get_nonroot_node(btree, path, level);
+ right = nilfs_btree_get_sib_node(btree, path, level);
+ nchildren = nilfs_btree_node_get_nchildren(btree, node);
+ rnchildren = nilfs_btree_node_get_nchildren(btree, right);
+
+ n = (nchildren + rnchildren) / 2 - nchildren;
+
+ nilfs_btree_node_move_left(btree, node, right, n);
+
+ if (!buffer_dirty(path[level].bp_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_bh);
+ if (!buffer_dirty(path[level].bp_sib_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
+
+ unlock_buffer(path[level].bp_bh);
+ unlock_buffer(path[level].bp_sib_bh);
+
+ path[level + 1].bp_index++;
+ nilfs_btree_promote_key(btree, path, level + 1,
+ nilfs_btree_node_get_key(btree, right, 0));
+ path[level + 1].bp_index--;
+
+ nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+ path[level].bp_sib_bh = NULL;
+}
+
+static void nilfs_btree_concat_left(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level, __u64 *keyp, __u64 *ptrp)
+{
+ struct nilfs_btree_node *node, *left;
+ int n;
+
+ nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
+
+ lock_buffer(path[level].bp_bh);
+ lock_buffer(path[level].bp_sib_bh);
+
+ node = nilfs_btree_get_nonroot_node(btree, path, level);
+ left = nilfs_btree_get_sib_node(btree, path, level);
+
+ n = nilfs_btree_node_get_nchildren(btree, node);
+
+ nilfs_btree_node_move_left(btree, left, node, n);
+
+ if (!buffer_dirty(path[level].bp_sib_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
+
+ unlock_buffer(path[level].bp_bh);
+ unlock_buffer(path[level].bp_sib_bh);
+
+ nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_bh);
+ path[level].bp_bh = path[level].bp_sib_bh;
+ path[level].bp_sib_bh = NULL;
+ path[level].bp_index += nilfs_btree_node_get_nchildren(btree, left);
+}
+
+static void nilfs_btree_concat_right(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level, __u64 *keyp, __u64 *ptrp)
+{
+ struct nilfs_btree_node *node, *right;
+ int n;
+
+ nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
+
+ lock_buffer(path[level].bp_bh);
+ lock_buffer(path[level].bp_sib_bh);
+
+ node = nilfs_btree_get_nonroot_node(btree, path, level);
+ right = nilfs_btree_get_sib_node(btree, path, level);
+
+ n = nilfs_btree_node_get_nchildren(btree, right);
+
+ nilfs_btree_node_move_left(btree, node, right, n);
+
+ if (!buffer_dirty(path[level].bp_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_bh);
+
+ unlock_buffer(path[level].bp_bh);
+ unlock_buffer(path[level].bp_sib_bh);
+
+ nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_sib_bh);
+ path[level].bp_sib_bh = NULL;
+ path[level + 1].bp_index++;
+}
+
+static void nilfs_btree_shrink(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level, __u64 *keyp, __u64 *ptrp)
+{
+ struct nilfs_btree_node *root, *child;
+ int n;
+
+ nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
+
+ lock_buffer(path[level].bp_bh);
+ root = nilfs_btree_get_root(btree);
+ child = nilfs_btree_get_nonroot_node(btree, path, level);
+
+ nilfs_btree_node_delete(btree, root, NULL, NULL, 0);
+ nilfs_btree_node_set_level(btree, root, level);
+ n = nilfs_btree_node_get_nchildren(btree, child);
+ nilfs_btree_node_move_left(btree, root, child, n);
+ unlock_buffer(path[level].bp_bh);
+
+ nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_bh);
+ path[level].bp_bh = NULL;
+}
+
+
+static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int *levelp,
+ struct nilfs_bmap_stats *stats)
+{
+ struct buffer_head *bh;
+ struct nilfs_btree_node *node, *parent, *sib;
+ __u64 sibptr;
+ int pindex, level, ret;
+
+ ret = 0;
+ stats->bs_nblocks = 0;
+ for (level = NILFS_BTREE_LEVEL_NODE_MIN;
+ level < nilfs_btree_height(btree) - 1;
+ level++) {
+ node = nilfs_btree_get_nonroot_node(btree, path, level);
+ path[level].bp_oldreq.bpr_ptr =
+ nilfs_btree_node_get_ptr(btree, node,
+ path[level].bp_index);
+ if (btree->bt_bmap.b_pops->bpop_prepare_end_ptr != NULL) {
+ ret = btree->bt_bmap.b_pops->bpop_prepare_end_ptr(
+ &btree->bt_bmap, &path[level].bp_oldreq);
+ if (ret < 0)
+ goto err_out_child_node;
+ }
+
+ if (nilfs_btree_node_get_nchildren(btree, node) >
+ nilfs_btree_node_nchildren_min(btree, node)) {
+ path[level].bp_op = nilfs_btree_do_delete;
+ stats->bs_nblocks++;
+ goto out;
+ }
+
+ parent = nilfs_btree_get_node(btree, path, level + 1);
+ pindex = path[level + 1].bp_index;
+
+ if (pindex > 0) {
+ /* left sibling */
+ sibptr = nilfs_btree_node_get_ptr(btree, parent,
+ pindex - 1);
+ ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr,
+ &bh);
+ if (ret < 0)
+ goto err_out_curr_node;
+ sib = (struct nilfs_btree_node *)bh->b_data;
+ if (nilfs_btree_node_get_nchildren(btree, sib) >
+ nilfs_btree_node_nchildren_min(btree, sib)) {
+ path[level].bp_sib_bh = bh;
+ path[level].bp_op = nilfs_btree_borrow_left;
+ stats->bs_nblocks++;
+ goto out;
+ } else {
+ path[level].bp_sib_bh = bh;
+ path[level].bp_op = nilfs_btree_concat_left;
+ stats->bs_nblocks++;
+ /* continue; */
+ }
+ } else if (pindex <
+ nilfs_btree_node_get_nchildren(btree, parent) - 1) {
+ /* right sibling */
+ sibptr = nilfs_btree_node_get_ptr(btree, parent,
+ pindex + 1);
+ ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr,
+ &bh);
+ if (ret < 0)
+ goto err_out_curr_node;
+ sib = (struct nilfs_btree_node *)bh->b_data;
+ if (nilfs_btree_node_get_nchildren(btree, sib) >
+ nilfs_btree_node_nchildren_min(btree, sib)) {
+ path[level].bp_sib_bh = bh;
+ path[level].bp_op = nilfs_btree_borrow_right;
+ stats->bs_nblocks++;
+ goto out;
+ } else {
+ path[level].bp_sib_bh = bh;
+ path[level].bp_op = nilfs_btree_concat_right;
+ stats->bs_nblocks++;
+ /* continue; */
+ }
+ } else {
+ /* no siblings */
+ /* the only child of the root node */
+ WARN_ON(level != nilfs_btree_height(btree) - 2);
+ if (nilfs_btree_node_get_nchildren(btree, node) - 1 <=
+ NILFS_BTREE_ROOT_NCHILDREN_MAX) {
+ path[level].bp_op = nilfs_btree_shrink;
+ stats->bs_nblocks += 2;
+ } else {
+ path[level].bp_op = nilfs_btree_do_delete;
+ stats->bs_nblocks++;
+ }
+
+ goto out;
+
+ }
+ }
+
+ node = nilfs_btree_get_root(btree);
+ path[level].bp_oldreq.bpr_ptr =
+ nilfs_btree_node_get_ptr(btree, node, path[level].bp_index);
+ if (btree->bt_bmap.b_pops->bpop_prepare_end_ptr != NULL) {
+ ret = btree->bt_bmap.b_pops->bpop_prepare_end_ptr(
+ &btree->bt_bmap, &path[level].bp_oldreq);
+ if (ret < 0)
+ goto err_out_child_node;
+ }
+ /* child of the root node is deleted */
+ path[level].bp_op = nilfs_btree_do_delete;
+ stats->bs_nblocks++;
+
+ /* success */
+ out:
+ *levelp = level;
+ return ret;
+
+ /* error */
+ err_out_curr_node:
+ if (btree->bt_bmap.b_pops->bpop_abort_end_ptr != NULL)
+ btree->bt_bmap.b_pops->bpop_abort_end_ptr(
+ &btree->bt_bmap, &path[level].bp_oldreq);
+ err_out_child_node:
+ for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--) {
+ nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+ if (btree->bt_bmap.b_pops->bpop_abort_end_ptr != NULL)
+ btree->bt_bmap.b_pops->bpop_abort_end_ptr(
+ &btree->bt_bmap, &path[level].bp_oldreq);
+ }
+ *levelp = level;
+ stats->bs_nblocks = 0;
+ return ret;
+}
+
+static void nilfs_btree_commit_delete(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int maxlevel)
+{
+ int level;
+
+ for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) {
+ if (btree->bt_bmap.b_pops->bpop_commit_end_ptr != NULL)
+ btree->bt_bmap.b_pops->bpop_commit_end_ptr(
+ &btree->bt_bmap, &path[level].bp_oldreq);
+ path[level].bp_op(btree, path, level, NULL, NULL);
+ }
+
+ if (!nilfs_bmap_dirty(&btree->bt_bmap))
+ nilfs_bmap_set_dirty(&btree->bt_bmap);
+}
+
+static int nilfs_btree_delete(struct nilfs_bmap *bmap, __u64 key)
+
+{
+ struct nilfs_btree *btree;
+ struct nilfs_btree_path *path;
+ struct nilfs_bmap_stats stats;
+ int level, ret;
+
+ btree = (struct nilfs_btree *)bmap;
+ path = nilfs_btree_alloc_path(btree);
+ if (path == NULL)
+ return -ENOMEM;
+ nilfs_btree_init_path(btree, path);
+ ret = nilfs_btree_do_lookup(btree, path, key, NULL,
+ NILFS_BTREE_LEVEL_NODE_MIN);
+ if (ret < 0)
+ goto out;
+
+ ret = nilfs_btree_prepare_delete(btree, path, &level, &stats);
+ if (ret < 0)
+ goto out;
+ nilfs_btree_commit_delete(btree, path, level);
+ nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks);
+
+out:
+ nilfs_btree_clear_path(btree, path);
+ nilfs_btree_free_path(btree, path);
+ return ret;
+}
+
+static int nilfs_btree_last_key(const struct nilfs_bmap *bmap, __u64 *keyp)
+{
+ struct nilfs_btree *btree;
+ struct nilfs_btree_path *path;
+ int ret;
+
+ btree = (struct nilfs_btree *)bmap;
+ path = nilfs_btree_alloc_path(btree);
+ if (path == NULL)
+ return -ENOMEM;
+ nilfs_btree_init_path(btree, path);
+
+ ret = nilfs_btree_do_lookup_last(btree, path, keyp, NULL);
+
+ nilfs_btree_clear_path(btree, path);
+ nilfs_btree_free_path(btree, path);
+
+ return ret;
+}
+
+static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key)
+{
+ struct buffer_head *bh;
+ struct nilfs_btree *btree;
+ struct nilfs_btree_node *root, *node;
+ __u64 maxkey, nextmaxkey;
+ __u64 ptr;
+ int nchildren, ret;
+
+ btree = (struct nilfs_btree *)bmap;
+ root = nilfs_btree_get_root(btree);
+ switch (nilfs_btree_height(btree)) {
+ case 2:
+ bh = NULL;
+ node = root;
+ break;
+ case 3:
+ nchildren = nilfs_btree_node_get_nchildren(btree, root);
+ if (nchildren > 1)
+ return 0;
+ ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1);
+ ret = nilfs_bmap_get_block(bmap, ptr, &bh);
+ if (ret < 0)
+ return ret;
+ node = (struct nilfs_btree_node *)bh->b_data;
+ break;
+ default:
+ return 0;
+ }
+
+ nchildren = nilfs_btree_node_get_nchildren(btree, node);
+ maxkey = nilfs_btree_node_get_key(btree, node, nchildren - 1);
+ nextmaxkey = (nchildren > 1) ?
+ nilfs_btree_node_get_key(btree, node, nchildren - 2) : 0;
+ if (bh != NULL)
+ nilfs_bmap_put_block(bmap, bh);
+
+ return (maxkey == key) && (nextmaxkey < bmap->b_low);
+}
+
+static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
+ __u64 *keys, __u64 *ptrs, int nitems)
+{
+ struct buffer_head *bh;
+ struct nilfs_btree *btree;
+ struct nilfs_btree_node *node, *root;
+ __le64 *dkeys;
+ __le64 *dptrs;
+ __u64 ptr;
+ int nchildren, i, ret;
+
+ btree = (struct nilfs_btree *)bmap;
+ root = nilfs_btree_get_root(btree);
+ switch (nilfs_btree_height(btree)) {
+ case 2:
+ bh = NULL;
+ node = root;
+ break;
+ case 3:
+ nchildren = nilfs_btree_node_get_nchildren(btree, root);
+ WARN_ON(nchildren > 1);
+ ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1);
+ ret = nilfs_bmap_get_block(bmap, ptr, &bh);
+ if (ret < 0)
+ return ret;
+ node = (struct nilfs_btree_node *)bh->b_data;
+ break;
+ default:
+ node = NULL;
+ return -EINVAL;
+ }
+
+ nchildren = nilfs_btree_node_get_nchildren(btree, node);
+ if (nchildren < nitems)
+ nitems = nchildren;
+ dkeys = nilfs_btree_node_dkeys(btree, node);
+ dptrs = nilfs_btree_node_dptrs(btree, node);
+ for (i = 0; i < nitems; i++) {
+ keys[i] = nilfs_bmap_dkey_to_key(dkeys[i]);
+ ptrs[i] = nilfs_bmap_dptr_to_ptr(dptrs[i]);
+ }
+
+ if (bh != NULL)
+ nilfs_bmap_put_block(bmap, bh);
+
+ return nitems;
+}
+
+static int
+nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
+ union nilfs_bmap_ptr_req *dreq,
+ union nilfs_bmap_ptr_req *nreq,
+ struct buffer_head **bhp,
+ struct nilfs_bmap_stats *stats)
+{
+ struct buffer_head *bh;
+ struct nilfs_btree *btree;
+ int ret;
+
+ btree = (struct nilfs_btree *)bmap;
+ stats->bs_nblocks = 0;
+
+ /* for data */
+ /* cannot find near ptr */
+ if (btree->bt_ops->btop_find_target != NULL)
+ dreq->bpr_ptr
+ = btree->bt_ops->btop_find_target(btree, NULL, key);
+ ret = bmap->b_pops->bpop_prepare_alloc_ptr(bmap, dreq);
+ if (ret < 0)
+ return ret;
+
+ *bhp = NULL;
+ stats->bs_nblocks++;
+ if (nreq != NULL) {
+ nreq->bpr_ptr = dreq->bpr_ptr + 1;
+ ret = bmap->b_pops->bpop_prepare_alloc_ptr(bmap, nreq);
+ if (ret < 0)
+ goto err_out_dreq;
+
+ ret = nilfs_bmap_get_new_block(bmap, nreq->bpr_ptr, &bh);
+ if (ret < 0)
+ goto err_out_nreq;
+
+ *bhp = bh;
+ stats->bs_nblocks++;
+ }
+
+ /* success */
+ return 0;
+
+ /* error */
+ err_out_nreq:
+ bmap->b_pops->bpop_abort_alloc_ptr(bmap, nreq);
+ err_out_dreq:
+ bmap->b_pops->bpop_abort_alloc_ptr(bmap, dreq);
+ stats->bs_nblocks = 0;
+ return ret;
+
+}
+
+static void
+nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
+ __u64 key, __u64 ptr,
+ const __u64 *keys, const __u64 *ptrs,
+ int n, __u64 low, __u64 high,
+ union nilfs_bmap_ptr_req *dreq,
+ union nilfs_bmap_ptr_req *nreq,
+ struct buffer_head *bh)
+{
+ struct nilfs_btree *btree;
+ struct nilfs_btree_node *node;
+ __u64 tmpptr;
+
+ /* free resources */
+ if (bmap->b_ops->bop_clear != NULL)
+ bmap->b_ops->bop_clear(bmap);
+
+ /* ptr must be a pointer to a buffer head. */
+ set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr));
+
+ /* convert and insert */
+ btree = (struct nilfs_btree *)bmap;
+ nilfs_btree_init(bmap, low, high);
+ if (nreq != NULL) {
+ if (bmap->b_pops->bpop_commit_alloc_ptr != NULL) {
+ bmap->b_pops->bpop_commit_alloc_ptr(bmap, dreq);
+ bmap->b_pops->bpop_commit_alloc_ptr(bmap, nreq);
+ }
+
+ /* create child node at level 1 */
+ lock_buffer(bh);
+ node = (struct nilfs_btree_node *)bh->b_data;
+ nilfs_btree_node_init(btree, node, 0, 1, n, keys, ptrs);
+ nilfs_btree_node_insert(btree, node,
+ key, dreq->bpr_ptr, n);
+ if (!buffer_dirty(bh))
+ nilfs_btnode_mark_dirty(bh);
+ if (!nilfs_bmap_dirty(bmap))
+ nilfs_bmap_set_dirty(bmap);
+
+ unlock_buffer(bh);
+ nilfs_bmap_put_block(bmap, bh);
+
+ /* create root node at level 2 */
+ node = nilfs_btree_get_root(btree);
+ tmpptr = nreq->bpr_ptr;
+ nilfs_btree_node_init(btree, node, NILFS_BTREE_NODE_ROOT,
+ 2, 1, &keys[0], &tmpptr);
+ } else {
+ if (bmap->b_pops->bpop_commit_alloc_ptr != NULL)
+ bmap->b_pops->bpop_commit_alloc_ptr(bmap, dreq);
+
+ /* create root node at level 1 */
+ node = nilfs_btree_get_root(btree);
+ nilfs_btree_node_init(btree, node, NILFS_BTREE_NODE_ROOT,
+ 1, n, keys, ptrs);
+ nilfs_btree_node_insert(btree, node,
+ key, dreq->bpr_ptr, n);
+ if (!nilfs_bmap_dirty(bmap))
+ nilfs_bmap_set_dirty(bmap);
+ }
+
+ if (btree->bt_ops->btop_set_target != NULL)
+ btree->bt_ops->btop_set_target(btree, key, dreq->bpr_ptr);
+}
+
+/**
+ * nilfs_btree_convert_and_insert -
+ * @bmap:
+ * @key:
+ * @ptr:
+ * @keys:
+ * @ptrs:
+ * @n:
+ * @low:
+ * @high:
+ */
+int nilfs_btree_convert_and_insert(struct nilfs_bmap *bmap,
+ __u64 key, __u64 ptr,
+ const __u64 *keys, const __u64 *ptrs,
+ int n, __u64 low, __u64 high)
+{
+ struct buffer_head *bh;
+ union nilfs_bmap_ptr_req dreq, nreq, *di, *ni;
+ struct nilfs_bmap_stats stats;
+ int ret;
+
+ if (n + 1 <= NILFS_BTREE_ROOT_NCHILDREN_MAX) {
+ di = &dreq;
+ ni = NULL;
+ } else if ((n + 1) <= NILFS_BTREE_NODE_NCHILDREN_MAX(
+ 1 << bmap->b_inode->i_blkbits)) {
+ di = &dreq;
+ ni = &nreq;
+ } else {
+ di = NULL;
+ ni = NULL;
+ BUG();
+ }
+
+ ret = nilfs_btree_prepare_convert_and_insert(bmap, key, di, ni, &bh,
+ &stats);
+ if (ret < 0)
+ return ret;
+ nilfs_btree_commit_convert_and_insert(bmap, key, ptr, keys, ptrs, n,
+ low, high, di, ni, bh);
+ nilfs_bmap_add_blocks(bmap, stats.bs_nblocks);
+ return 0;
+}
+
+static int nilfs_btree_propagate_p(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level,
+ struct buffer_head *bh)
+{
+ while ((++level < nilfs_btree_height(btree) - 1) &&
+ !buffer_dirty(path[level].bp_bh))
+ nilfs_btnode_mark_dirty(path[level].bp_bh);
+
+ return 0;
+}
+
+static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level)
+{
+ struct nilfs_btree_node *parent;
+ int ret;
+
+ parent = nilfs_btree_get_node(btree, path, level + 1);
+ path[level].bp_oldreq.bpr_ptr =
+ nilfs_btree_node_get_ptr(btree, parent,
+ path[level + 1].bp_index);
+ path[level].bp_newreq.bpr_ptr = path[level].bp_oldreq.bpr_ptr + 1;
+ ret = nilfs_bmap_prepare_update(&btree->bt_bmap,
+ &path[level].bp_oldreq,
+ &path[level].bp_newreq);
+ if (ret < 0)
+ return ret;
+
+ if (buffer_nilfs_node(path[level].bp_bh)) {
+ path[level].bp_ctxt.oldkey = path[level].bp_oldreq.bpr_ptr;
+ path[level].bp_ctxt.newkey = path[level].bp_newreq.bpr_ptr;
+ path[level].bp_ctxt.bh = path[level].bp_bh;
+ ret = nilfs_btnode_prepare_change_key(
+ &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
+ &path[level].bp_ctxt);
+ if (ret < 0) {
+ nilfs_bmap_abort_update(&btree->bt_bmap,
+ &path[level].bp_oldreq,
+ &path[level].bp_newreq);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void nilfs_btree_commit_update_v(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level)
+{
+ struct nilfs_btree_node *parent;
+
+ nilfs_bmap_commit_update(&btree->bt_bmap,
+ &path[level].bp_oldreq,
+ &path[level].bp_newreq);
+
+ if (buffer_nilfs_node(path[level].bp_bh)) {
+ nilfs_btnode_commit_change_key(
+ &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
+ &path[level].bp_ctxt);
+ path[level].bp_bh = path[level].bp_ctxt.bh;
+ }
+ set_buffer_nilfs_volatile(path[level].bp_bh);
+
+ parent = nilfs_btree_get_node(btree, path, level + 1);
+ nilfs_btree_node_set_ptr(btree, parent, path[level + 1].bp_index,
+ path[level].bp_newreq.bpr_ptr);
+}
+
+static void nilfs_btree_abort_update_v(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level)
+{
+ nilfs_bmap_abort_update(&btree->bt_bmap,
+ &path[level].bp_oldreq,
+ &path[level].bp_newreq);
+ if (buffer_nilfs_node(path[level].bp_bh))
+ nilfs_btnode_abort_change_key(
+ &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
+ &path[level].bp_ctxt);
+}
+
+static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int minlevel,
+ int *maxlevelp)
+{
+ int level, ret;
+
+ level = minlevel;
+ if (!buffer_nilfs_volatile(path[level].bp_bh)) {
+ ret = nilfs_btree_prepare_update_v(btree, path, level);
+ if (ret < 0)
+ return ret;
+ }
+ while ((++level < nilfs_btree_height(btree) - 1) &&
+ !buffer_dirty(path[level].bp_bh)) {
+
+ WARN_ON(buffer_nilfs_volatile(path[level].bp_bh));
+ ret = nilfs_btree_prepare_update_v(btree, path, level);
+ if (ret < 0)
+ goto out;
+ }
+
+ /* success */
+ *maxlevelp = level - 1;
+ return 0;
+
+ /* error */
+ out:
+ while (--level > minlevel)
+ nilfs_btree_abort_update_v(btree, path, level);
+ if (!buffer_nilfs_volatile(path[level].bp_bh))
+ nilfs_btree_abort_update_v(btree, path, level);
+ return ret;
+}
+
+static void nilfs_btree_commit_propagate_v(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int minlevel,
+ int maxlevel,
+ struct buffer_head *bh)
+{
+ int level;
+
+ if (!buffer_nilfs_volatile(path[minlevel].bp_bh))
+ nilfs_btree_commit_update_v(btree, path, minlevel);
+
+ for (level = minlevel + 1; level <= maxlevel; level++)
+ nilfs_btree_commit_update_v(btree, path, level);
+}
+
+static int nilfs_btree_propagate_v(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level,
+ struct buffer_head *bh)
+{
+ int maxlevel, ret;
+ struct nilfs_btree_node *parent;
+ __u64 ptr;
+
+ get_bh(bh);
+ path[level].bp_bh = bh;
+ ret = nilfs_btree_prepare_propagate_v(btree, path, level, &maxlevel);
+ if (ret < 0)
+ goto out;
+
+ if (buffer_nilfs_volatile(path[level].bp_bh)) {
+ parent = nilfs_btree_get_node(btree, path, level + 1);
+ ptr = nilfs_btree_node_get_ptr(btree, parent,
+ path[level + 1].bp_index);
+ ret = nilfs_bmap_mark_dirty(&btree->bt_bmap, ptr);
+ if (ret < 0)
+ goto out;
+ }
+
+ nilfs_btree_commit_propagate_v(btree, path, level, maxlevel, bh);
+
+ out:
+ brelse(path[level].bp_bh);
+ path[level].bp_bh = NULL;
+ return ret;
+}
+
+static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
+ struct buffer_head *bh)
+{
+ struct nilfs_btree *btree;
+ struct nilfs_btree_path *path;
+ struct nilfs_btree_node *node;
+ __u64 key;
+ int level, ret;
+
+ WARN_ON(!buffer_dirty(bh));
+
+ btree = (struct nilfs_btree *)bmap;
+ path = nilfs_btree_alloc_path(btree);
+ if (path == NULL)
+ return -ENOMEM;
+ nilfs_btree_init_path(btree, path);
+
+ if (buffer_nilfs_node(bh)) {
+ node = (struct nilfs_btree_node *)bh->b_data;
+ key = nilfs_btree_node_get_key(btree, node, 0);
+ level = nilfs_btree_node_get_level(btree, node);
+ } else {
+ key = nilfs_bmap_data_get_key(bmap, bh);
+ level = NILFS_BTREE_LEVEL_DATA;
+ }
+
+ ret = nilfs_btree_do_lookup(btree, path, key, NULL, level + 1);
+ if (ret < 0) {
+ if (unlikely(ret == -ENOENT))
+ printk(KERN_CRIT "%s: key = %llu, level == %d\n",
+ __func__, (unsigned long long)key, level);
+ goto out;
+ }
+
+ ret = btree->bt_ops->btop_propagate(btree, path, level, bh);
+
+ out:
+ nilfs_btree_clear_path(btree, path);
+ nilfs_btree_free_path(btree, path);
+
+ return ret;
+}
+
+static int nilfs_btree_propagate_gc(const struct nilfs_bmap *bmap,
+ struct buffer_head *bh)
+{
+ return nilfs_bmap_mark_dirty(bmap, bh->b_blocknr);
+}
+
+static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree,
+ struct list_head *lists,
+ struct buffer_head *bh)
+{
+ struct list_head *head;
+ struct buffer_head *cbh;
+ struct nilfs_btree_node *node, *cnode;
+ __u64 key, ckey;
+ int level;
+
+ get_bh(bh);
+ node = (struct nilfs_btree_node *)bh->b_data;
+ key = nilfs_btree_node_get_key(btree, node, 0);
+ level = nilfs_btree_node_get_level(btree, node);
+ list_for_each(head, &lists[level]) {
+ cbh = list_entry(head, struct buffer_head, b_assoc_buffers);
+ cnode = (struct nilfs_btree_node *)cbh->b_data;
+ ckey = nilfs_btree_node_get_key(btree, cnode, 0);
+ if (key < ckey)
+ break;
+ }
+ list_add_tail(&bh->b_assoc_buffers, head);
+}
+
+static void nilfs_btree_lookup_dirty_buffers(struct nilfs_bmap *bmap,
+ struct list_head *listp)
+{
+ struct nilfs_btree *btree = (struct nilfs_btree *)bmap;
+ struct address_space *btcache = &NILFS_BMAP_I(bmap)->i_btnode_cache;
+ struct list_head lists[NILFS_BTREE_LEVEL_MAX];
+ struct pagevec pvec;
+ struct buffer_head *bh, *head;
+ pgoff_t index = 0;
+ int level, i;
+
+ for (level = NILFS_BTREE_LEVEL_NODE_MIN;
+ level < NILFS_BTREE_LEVEL_MAX;
+ level++)
+ INIT_LIST_HEAD(&lists[level]);
+
+ pagevec_init(&pvec, 0);
+
+ while (pagevec_lookup_tag(&pvec, btcache, &index, PAGECACHE_TAG_DIRTY,
+ PAGEVEC_SIZE)) {
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ bh = head = page_buffers(pvec.pages[i]);
+ do {
+ if (buffer_dirty(bh))
+ nilfs_btree_add_dirty_buffer(btree,
+ lists, bh);
+ } while ((bh = bh->b_this_page) != head);
+ }
+ pagevec_release(&pvec);
+ cond_resched();
+ }
+
+ for (level = NILFS_BTREE_LEVEL_NODE_MIN;
+ level < NILFS_BTREE_LEVEL_MAX;
+ level++)
+ list_splice(&lists[level], listp->prev);
+}
+
+static int nilfs_btree_assign_p(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level,
+ struct buffer_head **bh,
+ sector_t blocknr,
+ union nilfs_binfo *binfo)
+{
+ struct nilfs_btree_node *parent;
+ __u64 key;
+ __u64 ptr;
+ int ret;
+
+ parent = nilfs_btree_get_node(btree, path, level + 1);
+ ptr = nilfs_btree_node_get_ptr(btree, parent,
+ path[level + 1].bp_index);
+ if (buffer_nilfs_node(*bh)) {
+ path[level].bp_ctxt.oldkey = ptr;
+ path[level].bp_ctxt.newkey = blocknr;
+ path[level].bp_ctxt.bh = *bh;
+ ret = nilfs_btnode_prepare_change_key(
+ &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
+ &path[level].bp_ctxt);
+ if (ret < 0)
+ return ret;
+ nilfs_btnode_commit_change_key(
+ &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
+ &path[level].bp_ctxt);
+ *bh = path[level].bp_ctxt.bh;
+ }
+
+ nilfs_btree_node_set_ptr(btree, parent,
+ path[level + 1].bp_index, blocknr);
+
+ key = nilfs_btree_node_get_key(btree, parent,
+ path[level + 1].bp_index);
+ /* on-disk format */
+ binfo->bi_dat.bi_blkoff = nilfs_bmap_key_to_dkey(key);
+ binfo->bi_dat.bi_level = level;
+
+ return 0;
+}
+
+static int nilfs_btree_assign_v(struct nilfs_btree *btree,
+ struct nilfs_btree_path *path,
+ int level,
+ struct buffer_head **bh,
+ sector_t blocknr,
+ union nilfs_binfo *binfo)
+{
+ struct nilfs_btree_node *parent;
+ __u64 key;
+ __u64 ptr;
+ union nilfs_bmap_ptr_req req;
+ int ret;
+
+ parent = nilfs_btree_get_node(btree, path, level + 1);
+ ptr = nilfs_btree_node_get_ptr(btree, parent,
+ path[level + 1].bp_index);
+ req.bpr_ptr = ptr;
+ ret = btree->bt_bmap.b_pops->bpop_prepare_start_ptr(&btree->bt_bmap,
+ &req);
+ if (ret < 0)
+ return ret;
+ btree->bt_bmap.b_pops->bpop_commit_start_ptr(&btree->bt_bmap,
+ &req, blocknr);
+
+ key = nilfs_btree_node_get_key(btree, parent,
+ path[level + 1].bp_index);
+ /* on-disk format */
+ binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr);
+ binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
+
+ return 0;
+}
+
+static int nilfs_btree_assign(struct nilfs_bmap *bmap,
+ struct buffer_head **bh,
+ sector_t blocknr,
+ union nilfs_binfo *binfo)
+{
+ struct nilfs_btree *btree;
+ struct nilfs_btree_path *path;
+ struct nilfs_btree_node *node;
+ __u64 key;
+ int level, ret;
+
+ btree = (struct nilfs_btree *)bmap;
+ path = nilfs_btree_alloc_path(btree);
+ if (path == NULL)
+ return -ENOMEM;
+ nilfs_btree_init_path(btree, path);
+
+ if (buffer_nilfs_node(*bh)) {
+ node = (struct nilfs_btree_node *)(*bh)->b_data;
+ key = nilfs_btree_node_get_key(btree, node, 0);
+ level = nilfs_btree_node_get_level(btree, node);
+ } else {
+ key = nilfs_bmap_data_get_key(bmap, *bh);
+ level = NILFS_BTREE_LEVEL_DATA;
+ }
+
+ ret = nilfs_btree_do_lookup(btree, path, key, NULL, level + 1);
+ if (ret < 0) {
+ WARN_ON(ret == -ENOENT);
+ goto out;
+ }
+
+ ret = btree->bt_ops->btop_assign(btree, path, level, bh,
+ blocknr, binfo);
+
+ out:
+ nilfs_btree_clear_path(btree, path);
+ nilfs_btree_free_path(btree, path);
+
+ return ret;
+}
+
+static int nilfs_btree_assign_gc(struct nilfs_bmap *bmap,
+ struct buffer_head **bh,
+ sector_t blocknr,
+ union nilfs_binfo *binfo)
+{
+ struct nilfs_btree *btree;
+ struct nilfs_btree_node *node;
+ __u64 key;
+ int ret;
+
+ btree = (struct nilfs_btree *)bmap;
+ ret = nilfs_bmap_move_v(bmap, (*bh)->b_blocknr, blocknr);
+ if (ret < 0)
+ return ret;
+
+ if (buffer_nilfs_node(*bh)) {
+ node = (struct nilfs_btree_node *)(*bh)->b_data;
+ key = nilfs_btree_node_get_key(btree, node, 0);
+ } else
+ key = nilfs_bmap_data_get_key(bmap, *bh);
+
+ /* on-disk format */
+ binfo->bi_v.bi_vblocknr = cpu_to_le64((*bh)->b_blocknr);
+ binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
+
+ return 0;
+}
+
+static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
+{
+ struct buffer_head *bh;
+ struct nilfs_btree *btree;
+ struct nilfs_btree_path *path;
+ __u64 ptr;
+ int ret;
+
+ btree = (struct nilfs_btree *)bmap;
+ path = nilfs_btree_alloc_path(btree);
+ if (path == NULL)
+ return -ENOMEM;
+ nilfs_btree_init_path(btree, path);
+
+ ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level + 1);
+ if (ret < 0) {
+ WARN_ON(ret == -ENOENT);
+ goto out;
+ }
+ ret = nilfs_bmap_get_block(&btree->bt_bmap, ptr, &bh);
+ if (ret < 0) {
+ WARN_ON(ret == -ENOENT);
+ goto out;
+ }
+
+ if (!buffer_dirty(bh))
+ nilfs_btnode_mark_dirty(bh);
+ nilfs_bmap_put_block(&btree->bt_bmap, bh);
+ if (!nilfs_bmap_dirty(&btree->bt_bmap))
+ nilfs_bmap_set_dirty(&btree->bt_bmap);
+
+ out:
+ nilfs_btree_clear_path(btree, path);
+ nilfs_btree_free_path(btree, path);
+ return ret;
+}
+
+static const struct nilfs_bmap_operations nilfs_btree_ops = {
+ .bop_lookup = nilfs_btree_lookup,
+ .bop_insert = nilfs_btree_insert,
+ .bop_delete = nilfs_btree_delete,
+ .bop_clear = NULL,
+
+ .bop_propagate = nilfs_btree_propagate,
+
+ .bop_lookup_dirty_buffers = nilfs_btree_lookup_dirty_buffers,
+
+ .bop_assign = nilfs_btree_assign,
+ .bop_mark = nilfs_btree_mark,
+
+ .bop_last_key = nilfs_btree_last_key,
+ .bop_check_insert = NULL,
+ .bop_check_delete = nilfs_btree_check_delete,
+ .bop_gather_data = nilfs_btree_gather_data,
+};
+
+static const struct nilfs_bmap_operations nilfs_btree_ops_gc = {
+ .bop_lookup = NULL,
+ .bop_insert = NULL,
+ .bop_delete = NULL,
+ .bop_clear = NULL,
+
+ .bop_propagate = nilfs_btree_propagate_gc,
+
+ .bop_lookup_dirty_buffers = nilfs_btree_lookup_dirty_buffers,
+
+ .bop_assign = nilfs_btree_assign_gc,
+ .bop_mark = NULL,
+
+ .bop_last_key = NULL,
+ .bop_check_insert = NULL,
+ .bop_check_delete = NULL,
+ .bop_gather_data = NULL,
+};
+
+static const struct nilfs_btree_operations nilfs_btree_ops_v = {
+ .btop_find_target = nilfs_btree_find_target_v,
+ .btop_set_target = nilfs_btree_set_target_v,
+ .btop_propagate = nilfs_btree_propagate_v,
+ .btop_assign = nilfs_btree_assign_v,
+};
+
+static const struct nilfs_btree_operations nilfs_btree_ops_p = {
+ .btop_find_target = NULL,
+ .btop_set_target = NULL,
+ .btop_propagate = nilfs_btree_propagate_p,
+ .btop_assign = nilfs_btree_assign_p,
+};
+
+int nilfs_btree_init(struct nilfs_bmap *bmap, __u64 low, __u64 high)
+{
+ struct nilfs_btree *btree;
+
+ btree = (struct nilfs_btree *)bmap;
+ bmap->b_ops = &nilfs_btree_ops;
+ bmap->b_low = low;
+ bmap->b_high = high;
+ switch (bmap->b_inode->i_ino) {
+ case NILFS_DAT_INO:
+ btree->bt_ops = &nilfs_btree_ops_p;
+ break;
+ default:
+ btree->bt_ops = &nilfs_btree_ops_v;
+ break;
+ }
+
+ return 0;
+}
+
+void nilfs_btree_init_gc(struct nilfs_bmap *bmap)
+{
+ bmap->b_low = NILFS_BMAP_LARGE_LOW;
+ bmap->b_high = NILFS_BMAP_LARGE_HIGH;
+ bmap->b_ops = &nilfs_btree_ops_gc;
+}
diff --git a/fs/nilfs2/btree.h b/fs/nilfs2/btree.h
new file mode 100644
index 00000000000..4766deb52fb
--- /dev/null
+++ b/fs/nilfs2/btree.h
@@ -0,0 +1,117 @@
+/*
+ * btree.h - NILFS B-tree.
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#ifndef _NILFS_BTREE_H
+#define _NILFS_BTREE_H
+
+#include <linux/types.h>
+#include <linux/buffer_head.h>
+#include <linux/list.h>
+#include <linux/nilfs2_fs.h>
+#include "btnode.h"
+#include "bmap.h"
+
+struct nilfs_btree;
+struct nilfs_btree_path;
+
+/**
+ * struct nilfs_btree_operations - B-tree operation table
+ */
+struct nilfs_btree_operations {
+ __u64 (*btop_find_target)(const struct nilfs_btree *,
+ const struct nilfs_btree_path *, __u64);
+ void (*btop_set_target)(struct nilfs_btree *, __u64, __u64);
+
+ struct the_nilfs *(*btop_get_nilfs)(struct nilfs_btree *);
+
+ int (*btop_propagate)(struct nilfs_btree *,
+ struct nilfs_btree_path *,
+ int,
+ struct buffer_head *);
+ int (*btop_assign)(struct nilfs_btree *,
+ struct nilfs_btree_path *,
+ int,
+ struct buffer_head **,
+ sector_t,
+ union nilfs_binfo *);
+};
+
+/**
+ * struct nilfs_btree_node - B-tree node
+ * @bn_flags: flags
+ * @bn_level: level
+ * @bn_nchildren: number of children
+ * @bn_pad: padding
+ */
+struct nilfs_btree_node {
+ __u8 bn_flags;
+ __u8 bn_level;
+ __le16 bn_nchildren;
+ __le32 bn_pad;
+};
+
+/* flags */
+#define NILFS_BTREE_NODE_ROOT 0x01
+
+/* level */
+#define NILFS_BTREE_LEVEL_DATA 0
+#define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1)
+#define NILFS_BTREE_LEVEL_MAX 14
+
+/**
+ * struct nilfs_btree - B-tree structure
+ * @bt_bmap: bmap base structure
+ * @bt_ops: B-tree operation table
+ */
+struct nilfs_btree {
+ struct nilfs_bmap bt_bmap;
+
+ /* B-tree-specific members */
+ const struct nilfs_btree_operations *bt_ops;
+};
+
+
+#define NILFS_BTREE_ROOT_SIZE NILFS_BMAP_SIZE
+#define NILFS_BTREE_ROOT_NCHILDREN_MAX \
+ ((NILFS_BTREE_ROOT_SIZE - sizeof(struct nilfs_btree_node)) / \
+ (sizeof(__le64 /* dkey */) + sizeof(__le64 /* dptr */)))
+#define NILFS_BTREE_ROOT_NCHILDREN_MIN 0
+#define NILFS_BTREE_NODE_EXTRA_PAD_SIZE (sizeof(__le64))
+#define NILFS_BTREE_NODE_NCHILDREN_MAX(nodesize) \
+ (((nodesize) - sizeof(struct nilfs_btree_node) - \
+ NILFS_BTREE_NODE_EXTRA_PAD_SIZE) / \
+ (sizeof(__le64 /* dkey */) + sizeof(__le64 /* dptr */)))
+#define NILFS_BTREE_NODE_NCHILDREN_MIN(nodesize) \
+ ((NILFS_BTREE_NODE_NCHILDREN_MAX(nodesize) - 1) / 2 + 1)
+#define NILFS_BTREE_KEY_MIN ((__u64)0)
+#define NILFS_BTREE_KEY_MAX (~(__u64)0)
+
+
+int nilfs_btree_path_cache_init(void);
+void nilfs_btree_path_cache_destroy(void);
+int nilfs_btree_init(struct nilfs_bmap *, __u64, __u64);
+int nilfs_btree_convert_and_insert(struct nilfs_bmap *, __u64, __u64,
+ const __u64 *, const __u64 *,
+ int, __u64, __u64);
+void nilfs_btree_init_gc(struct nilfs_bmap *);
+
+#endif /* _NILFS_BTREE_H */
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c
new file mode 100644
index 00000000000..e90b60dfced
--- /dev/null
+++ b/fs/nilfs2/cpfile.c
@@ -0,0 +1,925 @@
+/*
+ * cpfile.c - NILFS checkpoint file.
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/buffer_head.h>
+#include <linux/errno.h>
+#include <linux/nilfs2_fs.h>
+#include "mdt.h"
+#include "cpfile.h"
+
+
+static inline unsigned long
+nilfs_cpfile_checkpoints_per_block(const struct inode *cpfile)
+{
+ return NILFS_MDT(cpfile)->mi_entries_per_block;
+}
+
+/* block number from the beginning of the file */
+static unsigned long
+nilfs_cpfile_get_blkoff(const struct inode *cpfile, __u64 cno)
+{
+ __u64 tcno = cno + NILFS_MDT(cpfile)->mi_first_entry_offset - 1;
+ do_div(tcno, nilfs_cpfile_checkpoints_per_block(cpfile));
+ return (unsigned long)tcno;
+}
+
+/* offset in block */
+static unsigned long
+nilfs_cpfile_get_offset(const struct inode *cpfile, __u64 cno)
+{
+ __u64 tcno = cno + NILFS_MDT(cpfile)->mi_first_entry_offset - 1;
+ return do_div(tcno, nilfs_cpfile_checkpoints_per_block(cpfile));
+}
+
+static unsigned long
+nilfs_cpfile_checkpoints_in_block(const struct inode *cpfile,
+ __u64 curr,
+ __u64 max)
+{
+ return min_t(__u64,
+ nilfs_cpfile_checkpoints_per_block(cpfile) -
+ nilfs_cpfile_get_offset(cpfile, curr),
+ max - curr);
+}
+
+static inline int nilfs_cpfile_is_in_first(const struct inode *cpfile,
+ __u64 cno)
+{
+ return nilfs_cpfile_get_blkoff(cpfile, cno) == 0;
+}
+
+static unsigned int
+nilfs_cpfile_block_add_valid_checkpoints(const struct inode *cpfile,
+ struct buffer_head *bh,
+ void *kaddr,
+ unsigned int n)
+{
+ struct nilfs_checkpoint *cp = kaddr + bh_offset(bh);
+ unsigned int count;
+
+ count = le32_to_cpu(cp->cp_checkpoints_count) + n;
+ cp->cp_checkpoints_count = cpu_to_le32(count);
+ return count;
+}
+
+static unsigned int
+nilfs_cpfile_block_sub_valid_checkpoints(const struct inode *cpfile,
+ struct buffer_head *bh,
+ void *kaddr,
+ unsigned int n)
+{
+ struct nilfs_checkpoint *cp = kaddr + bh_offset(bh);
+ unsigned int count;
+
+ WARN_ON(le32_to_cpu(cp->cp_checkpoints_count) < n);
+ count = le32_to_cpu(cp->cp_checkpoints_count) - n;
+ cp->cp_checkpoints_count = cpu_to_le32(count);
+ return count;
+}
+
+static inline struct nilfs_cpfile_header *
+nilfs_cpfile_block_get_header(const struct inode *cpfile,
+ struct buffer_head *bh,
+ void *kaddr)
+{
+ return kaddr + bh_offset(bh);
+}
+
+static struct nilfs_checkpoint *
+nilfs_cpfile_block_get_checkpoint(const struct inode *cpfile, __u64 cno,
+ struct buffer_head *bh,
+ void *kaddr)
+{
+ return kaddr + bh_offset(bh) + nilfs_cpfile_get_offset(cpfile, cno) *
+ NILFS_MDT(cpfile)->mi_entry_size;
+}
+
+static void nilfs_cpfile_block_init(struct inode *cpfile,
+ struct buffer_head *bh,
+ void *kaddr)
+{
+ struct nilfs_checkpoint *cp = kaddr + bh_offset(bh);
+ size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size;
+ int n = nilfs_cpfile_checkpoints_per_block(cpfile);
+
+ while (n-- > 0) {
+ nilfs_checkpoint_set_invalid(cp);
+ cp = (void *)cp + cpsz;
+ }
+}
+
+static inline int nilfs_cpfile_get_header_block(struct inode *cpfile,
+ struct buffer_head **bhp)
+{
+ return nilfs_mdt_get_block(cpfile, 0, 0, NULL, bhp);
+}
+
+static inline int nilfs_cpfile_get_checkpoint_block(struct inode *cpfile,
+ __u64 cno,
+ int create,
+ struct buffer_head **bhp)
+{
+ return nilfs_mdt_get_block(cpfile,
+ nilfs_cpfile_get_blkoff(cpfile, cno),
+ create, nilfs_cpfile_block_init, bhp);
+}
+
+static inline int nilfs_cpfile_delete_checkpoint_block(struct inode *cpfile,
+ __u64 cno)
+{
+ return nilfs_mdt_delete_block(cpfile,
+ nilfs_cpfile_get_blkoff(cpfile, cno));
+}
+
+/**
+ * nilfs_cpfile_get_checkpoint - get a checkpoint
+ * @cpfile: inode of checkpoint file
+ * @cno: checkpoint number
+ * @create: create flag
+ * @cpp: pointer to a checkpoint
+ * @bhp: pointer to a buffer head
+ *
+ * Description: nilfs_cpfile_get_checkpoint() acquires the checkpoint
+ * specified by @cno. A new checkpoint will be created if @cno is the current
+ * checkpoint number and @create is nonzero.
+ *
+ * Return Value: On success, 0 is returned, and the checkpoint and the
+ * buffer head of the buffer on which the checkpoint is located are stored in
+ * the place pointed by @cpp and @bhp, respectively. On error, one of the
+ * following negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOENT - No such checkpoint.
+ *
+ * %-EINVAL - invalid checkpoint.
+ */
+int nilfs_cpfile_get_checkpoint(struct inode *cpfile,
+ __u64 cno,
+ int create,
+ struct nilfs_checkpoint **cpp,
+ struct buffer_head **bhp)
+{
+ struct buffer_head *header_bh, *cp_bh;
+ struct nilfs_cpfile_header *header;
+ struct nilfs_checkpoint *cp;
+ void *kaddr;
+ int ret;
+
+ if (unlikely(cno < 1 || cno > nilfs_mdt_cno(cpfile) ||
+ (cno < nilfs_mdt_cno(cpfile) && create)))
+ return -EINVAL;
+
+ down_write(&NILFS_MDT(cpfile)->mi_sem);
+
+ ret = nilfs_cpfile_get_header_block(cpfile, &header_bh);
+ if (ret < 0)
+ goto out_sem;
+ ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, create, &cp_bh);
+ if (ret < 0)
+ goto out_header;
+ kaddr = kmap(cp_bh->b_page);
+ cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr);
+ if (nilfs_checkpoint_invalid(cp)) {
+ if (!create) {
+ kunmap(cp_bh->b_page);
+ brelse(cp_bh);
+ ret = -ENOENT;
+ goto out_header;
+ }
+ /* a newly-created checkpoint */
+ nilfs_checkpoint_clear_invalid(cp);
+ if (!nilfs_cpfile_is_in_first(cpfile, cno))
+ nilfs_cpfile_block_add_valid_checkpoints(cpfile, cp_bh,
+ kaddr, 1);
+ nilfs_mdt_mark_buffer_dirty(cp_bh);
+
+ kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+ header = nilfs_cpfile_block_get_header(cpfile, header_bh,
+ kaddr);
+ le64_add_cpu(&header->ch_ncheckpoints, 1);
+ kunmap_atomic(kaddr, KM_USER0);
+ nilfs_mdt_mark_buffer_dirty(header_bh);
+ nilfs_mdt_mark_dirty(cpfile);
+ }
+
+ if (cpp != NULL)
+ *cpp = cp;
+ *bhp = cp_bh;
+
+ out_header:
+ brelse(header_bh);
+
+ out_sem:
+ up_write(&NILFS_MDT(cpfile)->mi_sem);
+ return ret;
+}
+
+/**
+ * nilfs_cpfile_put_checkpoint - put a checkpoint
+ * @cpfile: inode of checkpoint file
+ * @cno: checkpoint number
+ * @bh: buffer head
+ *
+ * Description: nilfs_cpfile_put_checkpoint() releases the checkpoint
+ * specified by @cno. @bh must be the buffer head which has been returned by
+ * a previous call to nilfs_cpfile_get_checkpoint() with @cno.
+ */
+void nilfs_cpfile_put_checkpoint(struct inode *cpfile, __u64 cno,
+ struct buffer_head *bh)
+{
+ kunmap(bh->b_page);
+ brelse(bh);
+}
+
+/**
+ * nilfs_cpfile_delete_checkpoints - delete checkpoints
+ * @cpfile: inode of checkpoint file
+ * @start: start checkpoint number
+ * @end: end checkpoint numer
+ *
+ * Description: nilfs_cpfile_delete_checkpoints() deletes the checkpoints in
+ * the period from @start to @end, excluding @end itself. The checkpoints
+ * which have been already deleted are ignored.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-EINVAL - invalid checkpoints.
+ */
+int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
+ __u64 start,
+ __u64 end)
+{
+ struct buffer_head *header_bh, *cp_bh;
+ struct nilfs_cpfile_header *header;
+ struct nilfs_checkpoint *cp;
+ size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size;
+ __u64 cno;
+ void *kaddr;
+ unsigned long tnicps;
+ int ret, ncps, nicps, count, i;
+
+ if (unlikely(start == 0 || start > end)) {
+ printk(KERN_ERR "%s: invalid range of checkpoint numbers: "
+ "[%llu, %llu)\n", __func__,
+ (unsigned long long)start, (unsigned long long)end);
+ return -EINVAL;
+ }
+
+ /* cannot delete the latest checkpoint */
+ if (start == nilfs_mdt_cno(cpfile) - 1)
+ return -EPERM;
+
+ down_write(&NILFS_MDT(cpfile)->mi_sem);
+
+ ret = nilfs_cpfile_get_header_block(cpfile, &header_bh);
+ if (ret < 0)
+ goto out_sem;
+ tnicps = 0;
+
+ for (cno = start; cno < end; cno += ncps) {
+ ncps = nilfs_cpfile_checkpoints_in_block(cpfile, cno, end);
+ ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh);
+ if (ret < 0) {
+ if (ret != -ENOENT)
+ goto out_sem;
+ /* skip hole */
+ ret = 0;
+ continue;
+ }
+
+ kaddr = kmap_atomic(cp_bh->b_page, KM_USER0);
+ cp = nilfs_cpfile_block_get_checkpoint(
+ cpfile, cno, cp_bh, kaddr);
+ nicps = 0;
+ for (i = 0; i < ncps; i++, cp = (void *)cp + cpsz) {
+ WARN_ON(nilfs_checkpoint_snapshot(cp));
+ if (!nilfs_checkpoint_invalid(cp)) {
+ nilfs_checkpoint_set_invalid(cp);
+ nicps++;
+ }
+ }
+ if (nicps > 0) {
+ tnicps += nicps;
+ nilfs_mdt_mark_buffer_dirty(cp_bh);
+ nilfs_mdt_mark_dirty(cpfile);
+ if (!nilfs_cpfile_is_in_first(cpfile, cno) &&
+ (count = nilfs_cpfile_block_sub_valid_checkpoints(
+ cpfile, cp_bh, kaddr, nicps)) == 0) {
+ /* make hole */
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(cp_bh);
+ ret = nilfs_cpfile_delete_checkpoint_block(
+ cpfile, cno);
+ if (ret == 0)
+ continue;
+ printk(KERN_ERR "%s: cannot delete block\n",
+ __func__);
+ goto out_sem;
+ }
+ }
+
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(cp_bh);
+ }
+
+ if (tnicps > 0) {
+ kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+ header = nilfs_cpfile_block_get_header(cpfile, header_bh,
+ kaddr);
+ le64_add_cpu(&header->ch_ncheckpoints, -(u64)tnicps);
+ nilfs_mdt_mark_buffer_dirty(header_bh);
+ nilfs_mdt_mark_dirty(cpfile);
+ kunmap_atomic(kaddr, KM_USER0);
+ }
+ brelse(header_bh);
+
+ out_sem:
+ up_write(&NILFS_MDT(cpfile)->mi_sem);
+ return ret;
+}
+
+static void nilfs_cpfile_checkpoint_to_cpinfo(struct inode *cpfile,
+ struct nilfs_checkpoint *cp,
+ struct nilfs_cpinfo *ci)
+{
+ ci->ci_flags = le32_to_cpu(cp->cp_flags);
+ ci->ci_cno = le64_to_cpu(cp->cp_cno);
+ ci->ci_create = le64_to_cpu(cp->cp_create);
+ ci->ci_nblk_inc = le64_to_cpu(cp->cp_nblk_inc);
+ ci->ci_inodes_count = le64_to_cpu(cp->cp_inodes_count);
+ ci->ci_blocks_count = le64_to_cpu(cp->cp_blocks_count);
+ ci->ci_next = le64_to_cpu(cp->cp_snapshot_list.ssl_next);
+}
+
+static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop,
+ struct nilfs_cpinfo *ci, size_t nci)
+{
+ struct nilfs_checkpoint *cp;
+ struct buffer_head *bh;
+ size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size;
+ __u64 cur_cno = nilfs_mdt_cno(cpfile), cno = *cnop;
+ void *kaddr;
+ int n, ret;
+ int ncps, i;
+
+ if (cno == 0)
+ return -ENOENT; /* checkpoint number 0 is invalid */
+ down_read(&NILFS_MDT(cpfile)->mi_sem);
+
+ for (n = 0; cno < cur_cno && n < nci; cno += ncps) {
+ ncps = nilfs_cpfile_checkpoints_in_block(cpfile, cno, cur_cno);
+ ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &bh);
+ if (ret < 0) {
+ if (ret != -ENOENT)
+ goto out;
+ continue; /* skip hole */
+ }
+
+ kaddr = kmap_atomic(bh->b_page, KM_USER0);
+ cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr);
+ for (i = 0; i < ncps && n < nci; i++, cp = (void *)cp + cpsz) {
+ if (!nilfs_checkpoint_invalid(cp))
+ nilfs_cpfile_checkpoint_to_cpinfo(
+ cpfile, cp, &ci[n++]);
+ }
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(bh);
+ }
+
+ ret = n;
+ if (n > 0)
+ *cnop = ci[n - 1].ci_cno + 1;
+
+ out:
+ up_read(&NILFS_MDT(cpfile)->mi_sem);
+ return ret;
+}
+
+static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
+ struct nilfs_cpinfo *ci, size_t nci)
+{
+ struct buffer_head *bh;
+ struct nilfs_cpfile_header *header;
+ struct nilfs_checkpoint *cp;
+ __u64 curr = *cnop, next;
+ unsigned long curr_blkoff, next_blkoff;
+ void *kaddr;
+ int n = 0, ret;
+
+ down_read(&NILFS_MDT(cpfile)->mi_sem);
+
+ if (curr == 0) {
+ ret = nilfs_cpfile_get_header_block(cpfile, &bh);
+ if (ret < 0)
+ goto out;
+ kaddr = kmap_atomic(bh->b_page, KM_USER0);
+ header = nilfs_cpfile_block_get_header(cpfile, bh, kaddr);
+ curr = le64_to_cpu(header->ch_snapshot_list.ssl_next);
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(bh);
+ if (curr == 0) {
+ ret = 0;
+ goto out;
+ }
+ } else if (unlikely(curr == ~(__u64)0)) {
+ ret = 0;
+ goto out;
+ }
+
+ curr_blkoff = nilfs_cpfile_get_blkoff(cpfile, curr);
+ ret = nilfs_cpfile_get_checkpoint_block(cpfile, curr, 0, &bh);
+ if (unlikely(ret < 0)) {
+ if (ret == -ENOENT)
+ ret = 0; /* No snapshots (started from a hole block) */
+ goto out;
+ }
+ kaddr = kmap_atomic(bh->b_page, KM_USER0);
+ while (n < nci) {
+ cp = nilfs_cpfile_block_get_checkpoint(cpfile, curr, bh, kaddr);
+ curr = ~(__u64)0; /* Terminator */
+ if (unlikely(nilfs_checkpoint_invalid(cp) ||
+ !nilfs_checkpoint_snapshot(cp)))
+ break;
+ nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, &ci[n++]);
+ next = le64_to_cpu(cp->cp_snapshot_list.ssl_next);
+ if (next == 0)
+ break; /* reach end of the snapshot list */
+
+ next_blkoff = nilfs_cpfile_get_blkoff(cpfile, next);
+ if (curr_blkoff != next_blkoff) {
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(bh);
+ ret = nilfs_cpfile_get_checkpoint_block(cpfile, next,
+ 0, &bh);
+ if (unlikely(ret < 0)) {
+ WARN_ON(ret == -ENOENT);
+ goto out;
+ }
+ kaddr = kmap_atomic(bh->b_page, KM_USER0);
+ }
+ curr = next;
+ curr_blkoff = next_blkoff;
+ }
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(bh);
+ *cnop = curr;
+ ret = n;
+
+ out:
+ up_read(&NILFS_MDT(cpfile)->mi_sem);
+ return ret;
+}
+
+/**
+ * nilfs_cpfile_get_cpinfo -
+ * @cpfile:
+ * @cno:
+ * @ci:
+ * @nci:
+ */
+
+ssize_t nilfs_cpfile_get_cpinfo(struct inode *cpfile, __u64 *cnop, int mode,
+ struct nilfs_cpinfo *ci, size_t nci)
+{
+ switch (mode) {
+ case NILFS_CHECKPOINT:
+ return nilfs_cpfile_do_get_cpinfo(cpfile, cnop, ci, nci);
+ case NILFS_SNAPSHOT:
+ return nilfs_cpfile_do_get_ssinfo(cpfile, cnop, ci, nci);
+ default:
+ return -EINVAL;
+ }
+}
+
+/**
+ * nilfs_cpfile_delete_checkpoint -
+ * @cpfile:
+ * @cno:
+ */
+int nilfs_cpfile_delete_checkpoint(struct inode *cpfile, __u64 cno)
+{
+ struct nilfs_cpinfo ci;
+ __u64 tcno = cno;
+ ssize_t nci;
+ int ret;
+
+ nci = nilfs_cpfile_do_get_cpinfo(cpfile, &tcno, &ci, 1);
+ if (nci < 0)
+ return nci;
+ else if (nci == 0 || ci.ci_cno != cno)
+ return -ENOENT;
+
+ /* cannot delete the latest checkpoint nor snapshots */
+ ret = nilfs_cpinfo_snapshot(&ci);
+ if (ret < 0)
+ return ret;
+ else if (ret > 0 || cno == nilfs_mdt_cno(cpfile) - 1)
+ return -EPERM;
+
+ return nilfs_cpfile_delete_checkpoints(cpfile, cno, cno + 1);
+}
+
+static struct nilfs_snapshot_list *
+nilfs_cpfile_block_get_snapshot_list(const struct inode *cpfile,
+ __u64 cno,
+ struct buffer_head *bh,
+ void *kaddr)
+{
+ struct nilfs_cpfile_header *header;
+ struct nilfs_checkpoint *cp;
+ struct nilfs_snapshot_list *list;
+
+ if (cno != 0) {
+ cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr);
+ list = &cp->cp_snapshot_list;
+ } else {
+ header = nilfs_cpfile_block_get_header(cpfile, bh, kaddr);
+ list = &header->ch_snapshot_list;
+ }
+ return list;
+}
+
+static int nilfs_cpfile_set_snapshot(struct inode *cpfile, __u64 cno)
+{
+ struct buffer_head *header_bh, *curr_bh, *prev_bh, *cp_bh;
+ struct nilfs_cpfile_header *header;
+ struct nilfs_checkpoint *cp;
+ struct nilfs_snapshot_list *list;
+ __u64 curr, prev;
+ unsigned long curr_blkoff, prev_blkoff;
+ void *kaddr;
+ int ret;
+
+ if (cno == 0)
+ return -ENOENT; /* checkpoint number 0 is invalid */
+ down_write(&NILFS_MDT(cpfile)->mi_sem);
+
+ ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh);
+ if (ret < 0)
+ goto out_sem;
+ kaddr = kmap_atomic(cp_bh->b_page, KM_USER0);
+ cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr);
+ if (nilfs_checkpoint_invalid(cp)) {
+ ret = -ENOENT;
+ kunmap_atomic(kaddr, KM_USER0);
+ goto out_cp;
+ }
+ if (nilfs_checkpoint_snapshot(cp)) {
+ ret = 0;
+ kunmap_atomic(kaddr, KM_USER0);
+ goto out_cp;
+ }
+ kunmap_atomic(kaddr, KM_USER0);
+
+ ret = nilfs_cpfile_get_header_block(cpfile, &header_bh);
+ if (ret < 0)
+ goto out_cp;
+ kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+ header = nilfs_cpfile_block_get_header(cpfile, header_bh, kaddr);
+ list = &header->ch_snapshot_list;
+ curr_bh = header_bh;
+ get_bh(curr_bh);
+ curr = 0;
+ curr_blkoff = 0;
+ prev = le64_to_cpu(list->ssl_prev);
+ while (prev > cno) {
+ prev_blkoff = nilfs_cpfile_get_blkoff(cpfile, prev);
+ curr = prev;
+ if (curr_blkoff != prev_blkoff) {
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(curr_bh);
+ ret = nilfs_cpfile_get_checkpoint_block(cpfile, curr,
+ 0, &curr_bh);
+ if (ret < 0)
+ goto out_header;
+ kaddr = kmap_atomic(curr_bh->b_page, KM_USER0);
+ }
+ curr_blkoff = prev_blkoff;
+ cp = nilfs_cpfile_block_get_checkpoint(
+ cpfile, curr, curr_bh, kaddr);
+ list = &cp->cp_snapshot_list;
+ prev = le64_to_cpu(list->ssl_prev);
+ }
+ kunmap_atomic(kaddr, KM_USER0);
+
+ if (prev != 0) {
+ ret = nilfs_cpfile_get_checkpoint_block(cpfile, prev, 0,
+ &prev_bh);
+ if (ret < 0)
+ goto out_curr;
+ } else {
+ prev_bh = header_bh;
+ get_bh(prev_bh);
+ }
+
+ kaddr = kmap_atomic(curr_bh->b_page, KM_USER0);
+ list = nilfs_cpfile_block_get_snapshot_list(
+ cpfile, curr, curr_bh, kaddr);
+ list->ssl_prev = cpu_to_le64(cno);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ kaddr = kmap_atomic(cp_bh->b_page, KM_USER0);
+ cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr);
+ cp->cp_snapshot_list.ssl_next = cpu_to_le64(curr);
+ cp->cp_snapshot_list.ssl_prev = cpu_to_le64(prev);
+ nilfs_checkpoint_set_snapshot(cp);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ kaddr = kmap_atomic(prev_bh->b_page, KM_USER0);
+ list = nilfs_cpfile_block_get_snapshot_list(
+ cpfile, prev, prev_bh, kaddr);
+ list->ssl_next = cpu_to_le64(cno);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+ header = nilfs_cpfile_block_get_header(cpfile, header_bh, kaddr);
+ le64_add_cpu(&header->ch_nsnapshots, 1);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ nilfs_mdt_mark_buffer_dirty(prev_bh);
+ nilfs_mdt_mark_buffer_dirty(curr_bh);
+ nilfs_mdt_mark_buffer_dirty(cp_bh);
+ nilfs_mdt_mark_buffer_dirty(header_bh);
+ nilfs_mdt_mark_dirty(cpfile);
+
+ brelse(prev_bh);
+
+ out_curr:
+ brelse(curr_bh);
+
+ out_header:
+ brelse(header_bh);
+
+ out_cp:
+ brelse(cp_bh);
+
+ out_sem:
+ up_write(&NILFS_MDT(cpfile)->mi_sem);
+ return ret;
+}
+
+static int nilfs_cpfile_clear_snapshot(struct inode *cpfile, __u64 cno)
+{
+ struct buffer_head *header_bh, *next_bh, *prev_bh, *cp_bh;
+ struct nilfs_cpfile_header *header;
+ struct nilfs_checkpoint *cp;
+ struct nilfs_snapshot_list *list;
+ __u64 next, prev;
+ void *kaddr;
+ int ret;
+
+ if (cno == 0)
+ return -ENOENT; /* checkpoint number 0 is invalid */
+ down_write(&NILFS_MDT(cpfile)->mi_sem);
+
+ ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh);
+ if (ret < 0)
+ goto out_sem;
+ kaddr = kmap_atomic(cp_bh->b_page, KM_USER0);
+ cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr);
+ if (nilfs_checkpoint_invalid(cp)) {
+ ret = -ENOENT;
+ kunmap_atomic(kaddr, KM_USER0);
+ goto out_cp;
+ }
+ if (!nilfs_checkpoint_snapshot(cp)) {
+ ret = 0;
+ kunmap_atomic(kaddr, KM_USER0);
+ goto out_cp;
+ }
+
+ list = &cp->cp_snapshot_list;
+ next = le64_to_cpu(list->ssl_next);
+ prev = le64_to_cpu(list->ssl_prev);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ ret = nilfs_cpfile_get_header_block(cpfile, &header_bh);
+ if (ret < 0)
+ goto out_cp;
+ if (next != 0) {
+ ret = nilfs_cpfile_get_checkpoint_block(cpfile, next, 0,
+ &next_bh);
+ if (ret < 0)
+ goto out_header;
+ } else {
+ next_bh = header_bh;
+ get_bh(next_bh);
+ }
+ if (prev != 0) {
+ ret = nilfs_cpfile_get_checkpoint_block(cpfile, prev, 0,
+ &prev_bh);
+ if (ret < 0)
+ goto out_next;
+ } else {
+ prev_bh = header_bh;
+ get_bh(prev_bh);
+ }
+
+ kaddr = kmap_atomic(next_bh->b_page, KM_USER0);
+ list = nilfs_cpfile_block_get_snapshot_list(
+ cpfile, next, next_bh, kaddr);
+ list->ssl_prev = cpu_to_le64(prev);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ kaddr = kmap_atomic(prev_bh->b_page, KM_USER0);
+ list = nilfs_cpfile_block_get_snapshot_list(
+ cpfile, prev, prev_bh, kaddr);
+ list->ssl_next = cpu_to_le64(next);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ kaddr = kmap_atomic(cp_bh->b_page, KM_USER0);
+ cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr);
+ cp->cp_snapshot_list.ssl_next = cpu_to_le64(0);
+ cp->cp_snapshot_list.ssl_prev = cpu_to_le64(0);
+ nilfs_checkpoint_clear_snapshot(cp);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+ header = nilfs_cpfile_block_get_header(cpfile, header_bh, kaddr);
+ le64_add_cpu(&header->ch_nsnapshots, -1);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ nilfs_mdt_mark_buffer_dirty(next_bh);
+ nilfs_mdt_mark_buffer_dirty(prev_bh);
+ nilfs_mdt_mark_buffer_dirty(cp_bh);
+ nilfs_mdt_mark_buffer_dirty(header_bh);
+ nilfs_mdt_mark_dirty(cpfile);
+
+ brelse(prev_bh);
+
+ out_next:
+ brelse(next_bh);
+
+ out_header:
+ brelse(header_bh);
+
+ out_cp:
+ brelse(cp_bh);
+
+ out_sem:
+ up_write(&NILFS_MDT(cpfile)->mi_sem);
+ return ret;
+}
+
+/**
+ * nilfs_cpfile_is_snapshot -
+ * @cpfile: inode of checkpoint file
+ * @cno: checkpoint number
+ *
+ * Description:
+ *
+ * Return Value: On success, 1 is returned if the checkpoint specified by
+ * @cno is a snapshot, or 0 if not. On error, one of the following negative
+ * error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOENT - No such checkpoint.
+ */
+int nilfs_cpfile_is_snapshot(struct inode *cpfile, __u64 cno)
+{
+ struct buffer_head *bh;
+ struct nilfs_checkpoint *cp;
+ void *kaddr;
+ int ret;
+
+ if (cno == 0)
+ return -ENOENT; /* checkpoint number 0 is invalid */
+ down_read(&NILFS_MDT(cpfile)->mi_sem);
+
+ ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &bh);
+ if (ret < 0)
+ goto out;
+ kaddr = kmap_atomic(bh->b_page, KM_USER0);
+ cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr);
+ ret = nilfs_checkpoint_snapshot(cp);
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(bh);
+
+ out:
+ up_read(&NILFS_MDT(cpfile)->mi_sem);
+ return ret;
+}
+
+/**
+ * nilfs_cpfile_change_cpmode - change checkpoint mode
+ * @cpfile: inode of checkpoint file
+ * @cno: checkpoint number
+ * @status: mode of checkpoint
+ *
+ * Description: nilfs_change_cpmode() changes the mode of the checkpoint
+ * specified by @cno. The mode @mode is NILFS_CHECKPOINT or NILFS_SNAPSHOT.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOENT - No such checkpoint.
+ */
+int nilfs_cpfile_change_cpmode(struct inode *cpfile, __u64 cno, int mode)
+{
+ struct the_nilfs *nilfs;
+ int ret;
+
+ nilfs = NILFS_MDT(cpfile)->mi_nilfs;
+
+ switch (mode) {
+ case NILFS_CHECKPOINT:
+ /*
+ * Check for protecting existing snapshot mounts:
+ * bd_mount_sem is used to make this operation atomic and
+ * exclusive with a new mount job. Though it doesn't cover
+ * umount, it's enough for the purpose.
+ */
+ down(&nilfs->ns_bdev->bd_mount_sem);
+ if (nilfs_checkpoint_is_mounted(nilfs, cno, 1)) {
+ /* Current implementation does not have to protect
+ plain read-only mounts since they are exclusive
+ with a read/write mount and are protected from the
+ cleaner. */
+ ret = -EBUSY;
+ } else
+ ret = nilfs_cpfile_clear_snapshot(cpfile, cno);
+ up(&nilfs->ns_bdev->bd_mount_sem);
+ return ret;
+ case NILFS_SNAPSHOT:
+ return nilfs_cpfile_set_snapshot(cpfile, cno);
+ default:
+ return -EINVAL;
+ }
+}
+
+/**
+ * nilfs_cpfile_get_stat - get checkpoint statistics
+ * @cpfile: inode of checkpoint file
+ * @stat: pointer to a structure of checkpoint statistics
+ *
+ * Description: nilfs_cpfile_get_stat() returns information about checkpoints.
+ *
+ * Return Value: On success, 0 is returned, and checkpoints information is
+ * stored in the place pointed by @stat. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ */
+int nilfs_cpfile_get_stat(struct inode *cpfile, struct nilfs_cpstat *cpstat)
+{
+ struct buffer_head *bh;
+ struct nilfs_cpfile_header *header;
+ void *kaddr;
+ int ret;
+
+ down_read(&NILFS_MDT(cpfile)->mi_sem);
+
+ ret = nilfs_cpfile_get_header_block(cpfile, &bh);
+ if (ret < 0)
+ goto out_sem;
+ kaddr = kmap_atomic(bh->b_page, KM_USER0);
+ header = nilfs_cpfile_block_get_header(cpfile, bh, kaddr);
+ cpstat->cs_cno = nilfs_mdt_cno(cpfile);
+ cpstat->cs_ncps = le64_to_cpu(header->ch_ncheckpoints);
+ cpstat->cs_nsss = le64_to_cpu(header->ch_nsnapshots);
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(bh);
+
+ out_sem:
+ up_read(&NILFS_MDT(cpfile)->mi_sem);
+ return ret;
+}
diff --git a/fs/nilfs2/cpfile.h b/fs/nilfs2/cpfile.h
new file mode 100644
index 00000000000..1a8a1008c34
--- /dev/null
+++ b/fs/nilfs2/cpfile.h
@@ -0,0 +1,45 @@
+/*
+ * cpfile.h - NILFS checkpoint file.
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#ifndef _NILFS_CPFILE_H
+#define _NILFS_CPFILE_H
+
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/nilfs2_fs.h>
+
+#define NILFS_CPFILE_GFP NILFS_MDT_GFP
+
+
+int nilfs_cpfile_get_checkpoint(struct inode *, __u64, int,
+ struct nilfs_checkpoint **,
+ struct buffer_head **);
+void nilfs_cpfile_put_checkpoint(struct inode *, __u64, struct buffer_head *);
+int nilfs_cpfile_delete_checkpoints(struct inode *, __u64, __u64);
+int nilfs_cpfile_delete_checkpoint(struct inode *, __u64);
+int nilfs_cpfile_change_cpmode(struct inode *, __u64, int);
+int nilfs_cpfile_is_snapshot(struct inode *, __u64);
+int nilfs_cpfile_get_stat(struct inode *, struct nilfs_cpstat *);
+ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int,
+ struct nilfs_cpinfo *, size_t);
+
+#endif /* _NILFS_CPFILE_H */
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
new file mode 100644
index 00000000000..bb8a5818e7f
--- /dev/null
+++ b/fs/nilfs2/dat.c
@@ -0,0 +1,430 @@
+/*
+ * dat.c - NILFS disk address translation.
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#include <linux/types.h>
+#include <linux/buffer_head.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include "nilfs.h"
+#include "mdt.h"
+#include "alloc.h"
+#include "dat.h"
+
+
+#define NILFS_CNO_MIN ((__u64)1)
+#define NILFS_CNO_MAX (~(__u64)0)
+
+static int nilfs_dat_prepare_entry(struct inode *dat,
+ struct nilfs_palloc_req *req, int create)
+{
+ return nilfs_palloc_get_entry_block(dat, req->pr_entry_nr,
+ create, &req->pr_entry_bh);
+}
+
+static void nilfs_dat_commit_entry(struct inode *dat,
+ struct nilfs_palloc_req *req)
+{
+ nilfs_mdt_mark_buffer_dirty(req->pr_entry_bh);
+ nilfs_mdt_mark_dirty(dat);
+ brelse(req->pr_entry_bh);
+}
+
+static void nilfs_dat_abort_entry(struct inode *dat,
+ struct nilfs_palloc_req *req)
+{
+ brelse(req->pr_entry_bh);
+}
+
+int nilfs_dat_prepare_alloc(struct inode *dat, struct nilfs_palloc_req *req)
+{
+ int ret;
+
+ ret = nilfs_palloc_prepare_alloc_entry(dat, req);
+ if (ret < 0)
+ return ret;
+
+ ret = nilfs_dat_prepare_entry(dat, req, 1);
+ if (ret < 0)
+ nilfs_palloc_abort_alloc_entry(dat, req);
+
+ return ret;
+}
+
+void nilfs_dat_commit_alloc(struct inode *dat, struct nilfs_palloc_req *req)
+{
+ struct nilfs_dat_entry *entry;
+ void *kaddr;
+
+ kaddr = kmap_atomic(req->pr_entry_bh->b_page, KM_USER0);
+ entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
+ req->pr_entry_bh, kaddr);
+ entry->de_start = cpu_to_le64(NILFS_CNO_MIN);
+ entry->de_end = cpu_to_le64(NILFS_CNO_MAX);
+ entry->de_blocknr = cpu_to_le64(0);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ nilfs_palloc_commit_alloc_entry(dat, req);
+ nilfs_dat_commit_entry(dat, req);
+}
+
+void nilfs_dat_abort_alloc(struct inode *dat, struct nilfs_palloc_req *req)
+{
+ nilfs_dat_abort_entry(dat, req);
+ nilfs_palloc_abort_alloc_entry(dat, req);
+}
+
+int nilfs_dat_prepare_free(struct inode *dat, struct nilfs_palloc_req *req)
+{
+ int ret;
+
+ ret = nilfs_palloc_prepare_free_entry(dat, req);
+ if (ret < 0)
+ return ret;
+ ret = nilfs_dat_prepare_entry(dat, req, 0);
+ if (ret < 0) {
+ nilfs_palloc_abort_free_entry(dat, req);
+ return ret;
+ }
+ return 0;
+}
+
+void nilfs_dat_commit_free(struct inode *dat, struct nilfs_palloc_req *req)
+{
+ struct nilfs_dat_entry *entry;
+ void *kaddr;
+
+ kaddr = kmap_atomic(req->pr_entry_bh->b_page, KM_USER0);
+ entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
+ req->pr_entry_bh, kaddr);
+ entry->de_start = cpu_to_le64(NILFS_CNO_MIN);
+ entry->de_end = cpu_to_le64(NILFS_CNO_MIN);
+ entry->de_blocknr = cpu_to_le64(0);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ nilfs_dat_commit_entry(dat, req);
+ nilfs_palloc_commit_free_entry(dat, req);
+}
+
+void nilfs_dat_abort_free(struct inode *dat, struct nilfs_palloc_req *req)
+{
+ nilfs_dat_abort_entry(dat, req);
+ nilfs_palloc_abort_free_entry(dat, req);
+}
+
+int nilfs_dat_prepare_start(struct inode *dat, struct nilfs_palloc_req *req)
+{
+ int ret;
+
+ ret = nilfs_dat_prepare_entry(dat, req, 0);
+ WARN_ON(ret == -ENOENT);
+ return ret;
+}
+
+void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req,
+ sector_t blocknr)
+{
+ struct nilfs_dat_entry *entry;
+ void *kaddr;
+
+ kaddr = kmap_atomic(req->pr_entry_bh->b_page, KM_USER0);
+ entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
+ req->pr_entry_bh, kaddr);
+ entry->de_start = cpu_to_le64(nilfs_mdt_cno(dat));
+ if (entry->de_blocknr != cpu_to_le64(0) ||
+ entry->de_end != cpu_to_le64(NILFS_CNO_MAX)) {
+ printk(KERN_CRIT
+ "%s: vbn = %llu, start = %llu, end = %llu, pbn = %llu\n",
+ __func__, (unsigned long long)req->pr_entry_nr,
+ (unsigned long long)le64_to_cpu(entry->de_start),
+ (unsigned long long)le64_to_cpu(entry->de_end),
+ (unsigned long long)le64_to_cpu(entry->de_blocknr));
+ }
+ entry->de_blocknr = cpu_to_le64(blocknr);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ nilfs_dat_commit_entry(dat, req);
+}
+
+void nilfs_dat_abort_start(struct inode *dat, struct nilfs_palloc_req *req)
+{
+ nilfs_dat_abort_entry(dat, req);
+}
+
+int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req)
+{
+ struct nilfs_dat_entry *entry;
+ __u64 start;
+ sector_t blocknr;
+ void *kaddr;
+ int ret;
+
+ ret = nilfs_dat_prepare_entry(dat, req, 0);
+ if (ret < 0) {
+ WARN_ON(ret == -ENOENT);
+ return ret;
+ }
+
+ kaddr = kmap_atomic(req->pr_entry_bh->b_page, KM_USER0);
+ entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
+ req->pr_entry_bh, kaddr);
+ start = le64_to_cpu(entry->de_start);
+ blocknr = le64_to_cpu(entry->de_blocknr);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ if (blocknr == 0) {
+ ret = nilfs_palloc_prepare_free_entry(dat, req);
+ if (ret < 0) {
+ nilfs_dat_abort_entry(dat, req);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+void nilfs_dat_commit_end(struct inode *dat, struct nilfs_palloc_req *req,
+ int dead)
+{
+ struct nilfs_dat_entry *entry;
+ __u64 start, end;
+ sector_t blocknr;
+ void *kaddr;
+
+ kaddr = kmap_atomic(req->pr_entry_bh->b_page, KM_USER0);
+ entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
+ req->pr_entry_bh, kaddr);
+ end = start = le64_to_cpu(entry->de_start);
+ if (!dead) {
+ end = nilfs_mdt_cno(dat);
+ WARN_ON(start > end);
+ }
+ entry->de_end = cpu_to_le64(end);
+ blocknr = le64_to_cpu(entry->de_blocknr);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ if (blocknr == 0)
+ nilfs_dat_commit_free(dat, req);
+ else
+ nilfs_dat_commit_entry(dat, req);
+}
+
+void nilfs_dat_abort_end(struct inode *dat, struct nilfs_palloc_req *req)
+{
+ struct nilfs_dat_entry *entry;
+ __u64 start;
+ sector_t blocknr;
+ void *kaddr;
+
+ kaddr = kmap_atomic(req->pr_entry_bh->b_page, KM_USER0);
+ entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
+ req->pr_entry_bh, kaddr);
+ start = le64_to_cpu(entry->de_start);
+ blocknr = le64_to_cpu(entry->de_blocknr);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ if (start == nilfs_mdt_cno(dat) && blocknr == 0)
+ nilfs_palloc_abort_free_entry(dat, req);
+ nilfs_dat_abort_entry(dat, req);
+}
+
+/**
+ * nilfs_dat_mark_dirty -
+ * @dat: DAT file inode
+ * @vblocknr: virtual block number
+ *
+ * Description:
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ */
+int nilfs_dat_mark_dirty(struct inode *dat, __u64 vblocknr)
+{
+ struct nilfs_palloc_req req;
+ int ret;
+
+ req.pr_entry_nr = vblocknr;
+ ret = nilfs_dat_prepare_entry(dat, &req, 0);
+ if (ret == 0)
+ nilfs_dat_commit_entry(dat, &req);
+ return ret;
+}
+
+/**
+ * nilfs_dat_freev - free virtual block numbers
+ * @dat: DAT file inode
+ * @vblocknrs: array of virtual block numbers
+ * @nitems: number of virtual block numbers
+ *
+ * Description: nilfs_dat_freev() frees the virtual block numbers specified by
+ * @vblocknrs and @nitems.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * nagative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOENT - The virtual block number have not been allocated.
+ */
+int nilfs_dat_freev(struct inode *dat, __u64 *vblocknrs, size_t nitems)
+{
+ return nilfs_palloc_freev(dat, vblocknrs, nitems);
+}
+
+/**
+ * nilfs_dat_move - change a block number
+ * @dat: DAT file inode
+ * @vblocknr: virtual block number
+ * @blocknr: block number
+ *
+ * Description: nilfs_dat_move() changes the block number associated with
+ * @vblocknr to @blocknr.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ */
+int nilfs_dat_move(struct inode *dat, __u64 vblocknr, sector_t blocknr)
+{
+ struct buffer_head *entry_bh;
+ struct nilfs_dat_entry *entry;
+ void *kaddr;
+ int ret;
+
+ ret = nilfs_palloc_get_entry_block(dat, vblocknr, 0, &entry_bh);
+ if (ret < 0)
+ return ret;
+ kaddr = kmap_atomic(entry_bh->b_page, KM_USER0);
+ entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr);
+ if (unlikely(entry->de_blocknr == cpu_to_le64(0))) {
+ printk(KERN_CRIT "%s: vbn = %llu, [%llu, %llu)\n", __func__,
+ (unsigned long long)vblocknr,
+ (unsigned long long)le64_to_cpu(entry->de_start),
+ (unsigned long long)le64_to_cpu(entry->de_end));
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(entry_bh);
+ return -EINVAL;
+ }
+ WARN_ON(blocknr == 0);
+ entry->de_blocknr = cpu_to_le64(blocknr);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ nilfs_mdt_mark_buffer_dirty(entry_bh);
+ nilfs_mdt_mark_dirty(dat);
+
+ brelse(entry_bh);
+
+ return 0;
+}
+
+/**
+ * nilfs_dat_translate - translate a virtual block number to a block number
+ * @dat: DAT file inode
+ * @vblocknr: virtual block number
+ * @blocknrp: pointer to a block number
+ *
+ * Description: nilfs_dat_translate() maps the virtual block number @vblocknr
+ * to the corresponding block number.
+ *
+ * Return Value: On success, 0 is returned and the block number associated
+ * with @vblocknr is stored in the place pointed by @blocknrp. On error, one
+ * of the following negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOENT - A block number associated with @vblocknr does not exist.
+ */
+int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp)
+{
+ struct buffer_head *entry_bh;
+ struct nilfs_dat_entry *entry;
+ sector_t blocknr;
+ void *kaddr;
+ int ret;
+
+ ret = nilfs_palloc_get_entry_block(dat, vblocknr, 0, &entry_bh);
+ if (ret < 0)
+ return ret;
+
+ kaddr = kmap_atomic(entry_bh->b_page, KM_USER0);
+ entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr);
+ blocknr = le64_to_cpu(entry->de_blocknr);
+ if (blocknr == 0) {
+ ret = -ENOENT;
+ goto out;
+ }
+ if (blocknrp != NULL)
+ *blocknrp = blocknr;
+
+ out:
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(entry_bh);
+ return ret;
+}
+
+ssize_t nilfs_dat_get_vinfo(struct inode *dat, struct nilfs_vinfo *vinfo,
+ size_t nvi)
+{
+ struct buffer_head *entry_bh;
+ struct nilfs_dat_entry *entry;
+ __u64 first, last;
+ void *kaddr;
+ unsigned long entries_per_block = NILFS_MDT(dat)->mi_entries_per_block;
+ int i, j, n, ret;
+
+ for (i = 0; i < nvi; i += n) {
+ ret = nilfs_palloc_get_entry_block(dat, vinfo[i].vi_vblocknr,
+ 0, &entry_bh);
+ if (ret < 0)
+ return ret;
+ kaddr = kmap_atomic(entry_bh->b_page, KM_USER0);
+ /* last virtual block number in this block */
+ first = vinfo[i].vi_vblocknr;
+ do_div(first, entries_per_block);
+ first *= entries_per_block;
+ last = first + entries_per_block - 1;
+ for (j = i, n = 0;
+ j < nvi && vinfo[j].vi_vblocknr >= first &&
+ vinfo[j].vi_vblocknr <= last;
+ j++, n++) {
+ entry = nilfs_palloc_block_get_entry(
+ dat, vinfo[j].vi_vblocknr, entry_bh, kaddr);
+ vinfo[j].vi_start = le64_to_cpu(entry->de_start);
+ vinfo[j].vi_end = le64_to_cpu(entry->de_end);
+ vinfo[j].vi_blocknr = le64_to_cpu(entry->de_blocknr);
+ }
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(entry_bh);
+ }
+
+ return nvi;
+}
diff --git a/fs/nilfs2/dat.h b/fs/nilfs2/dat.h
new file mode 100644
index 00000000000..d9560654a4b
--- /dev/null
+++ b/fs/nilfs2/dat.h
@@ -0,0 +1,52 @@
+/*
+ * dat.h - NILFS disk address translation.
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#ifndef _NILFS_DAT_H
+#define _NILFS_DAT_H
+
+#include <linux/types.h>
+#include <linux/buffer_head.h>
+#include <linux/fs.h>
+
+#define NILFS_DAT_GFP NILFS_MDT_GFP
+
+struct nilfs_palloc_req;
+
+int nilfs_dat_translate(struct inode *, __u64, sector_t *);
+
+int nilfs_dat_prepare_alloc(struct inode *, struct nilfs_palloc_req *);
+void nilfs_dat_commit_alloc(struct inode *, struct nilfs_palloc_req *);
+void nilfs_dat_abort_alloc(struct inode *, struct nilfs_palloc_req *);
+int nilfs_dat_prepare_start(struct inode *, struct nilfs_palloc_req *);
+void nilfs_dat_commit_start(struct inode *, struct nilfs_palloc_req *,
+ sector_t);
+void nilfs_dat_abort_start(struct inode *, struct nilfs_palloc_req *);
+int nilfs_dat_prepare_end(struct inode *, struct nilfs_palloc_req *);
+void nilfs_dat_commit_end(struct inode *, struct nilfs_palloc_req *, int);
+void nilfs_dat_abort_end(struct inode *, struct nilfs_palloc_req *);
+
+int nilfs_dat_mark_dirty(struct inode *, __u64);
+int nilfs_dat_freev(struct inode *, __u64 *, size_t);
+int nilfs_dat_move(struct inode *, __u64, sector_t);
+ssize_t nilfs_dat_get_vinfo(struct inode *, struct nilfs_vinfo *, size_t);
+
+#endif /* _NILFS_DAT_H */
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
new file mode 100644
index 00000000000..54100acc110
--- /dev/null
+++ b/fs/nilfs2/dir.c
@@ -0,0 +1,711 @@
+/*
+ * dir.c - NILFS directory entry operations
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Modified for NILFS by Amagai Yoshiji <amagai@osrg.net>
+ */
+/*
+ * linux/fs/ext2/dir.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ * from
+ *
+ * linux/fs/minix/dir.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * ext2 directory handling functions
+ *
+ * Big-endian to little-endian byte-swapping/bitmaps by
+ * David S. Miller (davem@caip.rutgers.edu), 1995
+ *
+ * All code that works with directory layout had been switched to pagecache
+ * and moved here. AV
+ */
+
+#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
+#include "nilfs.h"
+#include "page.h"
+
+/*
+ * nilfs uses block-sized chunks. Arguably, sector-sized ones would be
+ * more robust, but we have what we have
+ */
+static inline unsigned nilfs_chunk_size(struct inode *inode)
+{
+ return inode->i_sb->s_blocksize;
+}
+
+static inline void nilfs_put_page(struct page *page)
+{
+ kunmap(page);
+ page_cache_release(page);
+}
+
+static inline unsigned long dir_pages(struct inode *inode)
+{
+ return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
+}
+
+/*
+ * Return the offset into page `page_nr' of the last valid
+ * byte in that page, plus one.
+ */
+static unsigned nilfs_last_byte(struct inode *inode, unsigned long page_nr)
+{
+ unsigned last_byte = inode->i_size;
+
+ last_byte -= page_nr << PAGE_CACHE_SHIFT;
+ if (last_byte > PAGE_CACHE_SIZE)
+ last_byte = PAGE_CACHE_SIZE;
+ return last_byte;
+}
+
+static int nilfs_prepare_chunk_uninterruptible(struct page *page,
+ struct address_space *mapping,
+ unsigned from, unsigned to)
+{
+ loff_t pos = page_offset(page) + from;
+ return block_write_begin(NULL, mapping, pos, to - from,
+ AOP_FLAG_UNINTERRUPTIBLE, &page,
+ NULL, nilfs_get_block);
+}
+
+static int nilfs_prepare_chunk(struct page *page,
+ struct address_space *mapping,
+ unsigned from, unsigned to)
+{
+ loff_t pos = page_offset(page) + from;
+ return block_write_begin(NULL, mapping, pos, to - from, 0, &page,
+ NULL, nilfs_get_block);
+}
+
+static int nilfs_commit_chunk(struct page *page,
+ struct address_space *mapping,
+ unsigned from, unsigned to)
+{
+ struct inode *dir = mapping->host;
+ struct nilfs_sb_info *sbi = NILFS_SB(dir->i_sb);
+ loff_t pos = page_offset(page) + from;
+ unsigned len = to - from;
+ unsigned nr_dirty, copied;
+ int err;
+
+ nr_dirty = nilfs_page_count_clean_buffers(page, from, to);
+ copied = block_write_end(NULL, mapping, pos, len, len, page, NULL);
+ if (pos + copied > dir->i_size) {
+ i_size_write(dir, pos + copied);
+ mark_inode_dirty(dir);
+ }
+ if (IS_DIRSYNC(dir))
+ nilfs_set_transaction_flag(NILFS_TI_SYNC);
+ err = nilfs_set_file_dirty(sbi, dir, nr_dirty);
+ unlock_page(page);
+ return err;
+}
+
+static void nilfs_check_page(struct page *page)
+{
+ struct inode *dir = page->mapping->host;
+ struct super_block *sb = dir->i_sb;
+ unsigned chunk_size = nilfs_chunk_size(dir);
+ char *kaddr = page_address(page);
+ unsigned offs, rec_len;
+ unsigned limit = PAGE_CACHE_SIZE;
+ struct nilfs_dir_entry *p;
+ char *error;
+
+ if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
+ limit = dir->i_size & ~PAGE_CACHE_MASK;
+ if (limit & (chunk_size - 1))
+ goto Ebadsize;
+ if (!limit)
+ goto out;
+ }
+ for (offs = 0; offs <= limit - NILFS_DIR_REC_LEN(1); offs += rec_len) {
+ p = (struct nilfs_dir_entry *)(kaddr + offs);
+ rec_len = le16_to_cpu(p->rec_len);
+
+ if (rec_len < NILFS_DIR_REC_LEN(1))
+ goto Eshort;
+ if (rec_len & 3)
+ goto Ealign;
+ if (rec_len < NILFS_DIR_REC_LEN(p->name_len))
+ goto Enamelen;
+ if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
+ goto Espan;
+ }
+ if (offs != limit)
+ goto Eend;
+out:
+ SetPageChecked(page);
+ return;
+
+ /* Too bad, we had an error */
+
+Ebadsize:
+ nilfs_error(sb, "nilfs_check_page",
+ "size of directory #%lu is not a multiple of chunk size",
+ dir->i_ino
+ );
+ goto fail;
+Eshort:
+ error = "rec_len is smaller than minimal";
+ goto bad_entry;
+Ealign:
+ error = "unaligned directory entry";
+ goto bad_entry;
+Enamelen:
+ error = "rec_len is too small for name_len";
+ goto bad_entry;
+Espan:
+ error = "directory entry across blocks";
+bad_entry:
+ nilfs_error(sb, "nilfs_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) le64_to_cpu(p->inode),
+ rec_len, p->name_len);
+ goto fail;
+Eend:
+ p = (struct nilfs_dir_entry *)(kaddr + offs);
+ nilfs_error(sb, "nilfs_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) le64_to_cpu(p->inode));
+fail:
+ SetPageChecked(page);
+ SetPageError(page);
+}
+
+static struct page *nilfs_get_page(struct inode *dir, unsigned long n)
+{
+ struct address_space *mapping = dir->i_mapping;
+ struct page *page = read_cache_page(mapping, n,
+ (filler_t *)mapping->a_ops->readpage, NULL);
+ if (!IS_ERR(page)) {
+ wait_on_page_locked(page);
+ kmap(page);
+ if (!PageUptodate(page))
+ goto fail;
+ if (!PageChecked(page))
+ nilfs_check_page(page);
+ if (PageError(page))
+ goto fail;
+ }
+ return page;
+
+fail:
+ nilfs_put_page(page);
+ return ERR_PTR(-EIO);
+}
+
+/*
+ * NOTE! unlike strncmp, nilfs_match returns 1 for success, 0 for failure.
+ *
+ * len <= NILFS_NAME_LEN and de != NULL are guaranteed by caller.
+ */
+static int
+nilfs_match(int len, const char * const name, struct nilfs_dir_entry *de)
+{
+ if (len != de->name_len)
+ return 0;
+ if (!de->inode)
+ return 0;
+ return !memcmp(name, de->name, len);
+}
+
+/*
+ * p is at least 6 bytes before the end of page
+ */
+static struct nilfs_dir_entry *nilfs_next_entry(struct nilfs_dir_entry *p)
+{
+ return (struct nilfs_dir_entry *)((char *)p + le16_to_cpu(p->rec_len));
+}
+
+static unsigned char
+nilfs_filetype_table[NILFS_FT_MAX] = {
+ [NILFS_FT_UNKNOWN] = DT_UNKNOWN,
+ [NILFS_FT_REG_FILE] = DT_REG,
+ [NILFS_FT_DIR] = DT_DIR,
+ [NILFS_FT_CHRDEV] = DT_CHR,
+ [NILFS_FT_BLKDEV] = DT_BLK,
+ [NILFS_FT_FIFO] = DT_FIFO,
+ [NILFS_FT_SOCK] = DT_SOCK,
+ [NILFS_FT_SYMLINK] = DT_LNK,
+};
+
+#define S_SHIFT 12
+static unsigned char
+nilfs_type_by_mode[S_IFMT >> S_SHIFT] = {
+ [S_IFREG >> S_SHIFT] = NILFS_FT_REG_FILE,
+ [S_IFDIR >> S_SHIFT] = NILFS_FT_DIR,
+ [S_IFCHR >> S_SHIFT] = NILFS_FT_CHRDEV,
+ [S_IFBLK >> S_SHIFT] = NILFS_FT_BLKDEV,
+ [S_IFIFO >> S_SHIFT] = NILFS_FT_FIFO,
+ [S_IFSOCK >> S_SHIFT] = NILFS_FT_SOCK,
+ [S_IFLNK >> S_SHIFT] = NILFS_FT_SYMLINK,
+};
+
+static void nilfs_set_de_type(struct nilfs_dir_entry *de, struct inode *inode)
+{
+ mode_t mode = inode->i_mode;
+
+ de->file_type = nilfs_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
+}
+
+static int nilfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+ loff_t pos = filp->f_pos;
+ struct inode *inode = filp->f_dentry->d_inode;
+ struct super_block *sb = inode->i_sb;
+ unsigned int offset = pos & ~PAGE_CACHE_MASK;
+ unsigned long n = pos >> PAGE_CACHE_SHIFT;
+ unsigned long npages = dir_pages(inode);
+/* unsigned chunk_mask = ~(nilfs_chunk_size(inode)-1); */
+ unsigned char *types = NULL;
+ int ret;
+
+ if (pos > inode->i_size - NILFS_DIR_REC_LEN(1))
+ goto success;
+
+ types = nilfs_filetype_table;
+
+ for ( ; n < npages; n++, offset = 0) {
+ char *kaddr, *limit;
+ struct nilfs_dir_entry *de;
+ struct page *page = nilfs_get_page(inode, n);
+
+ if (IS_ERR(page)) {
+ nilfs_error(sb, __func__, "bad page in #%lu",
+ inode->i_ino);
+ filp->f_pos += PAGE_CACHE_SIZE - offset;
+ ret = -EIO;
+ goto done;
+ }
+ kaddr = page_address(page);
+ de = (struct nilfs_dir_entry *)(kaddr + offset);
+ limit = kaddr + nilfs_last_byte(inode, n) -
+ NILFS_DIR_REC_LEN(1);
+ for ( ; (char *)de <= limit; de = nilfs_next_entry(de)) {
+ if (de->rec_len == 0) {
+ nilfs_error(sb, __func__,
+ "zero-length directory entry");
+ ret = -EIO;
+ nilfs_put_page(page);
+ goto done;
+ }
+ if (de->inode) {
+ int over;
+ unsigned char d_type = DT_UNKNOWN;
+
+ if (types && de->file_type < NILFS_FT_MAX)
+ d_type = types[de->file_type];
+
+ offset = (char *)de - kaddr;
+ over = filldir(dirent, de->name, de->name_len,
+ (n<<PAGE_CACHE_SHIFT) | offset,
+ le64_to_cpu(de->inode), d_type);
+ if (over) {
+ nilfs_put_page(page);
+ goto success;
+ }
+ }
+ filp->f_pos += le16_to_cpu(de->rec_len);
+ }
+ nilfs_put_page(page);
+ }
+
+success:
+ ret = 0;
+done:
+ return ret;
+}
+
+/*
+ * nilfs_find_entry()
+ *
+ * finds an entry in the specified directory with the wanted name. It
+ * returns the page in which the entry was found, and the entry itself
+ * (as a parameter - res_dir). Page is returned mapped and unlocked.
+ * Entry is guaranteed to be valid.
+ */
+struct nilfs_dir_entry *
+nilfs_find_entry(struct inode *dir, struct dentry *dentry,
+ struct page **res_page)
+{
+ const char *name = dentry->d_name.name;
+ int namelen = dentry->d_name.len;
+ unsigned reclen = NILFS_DIR_REC_LEN(namelen);
+ unsigned long start, n;
+ unsigned long npages = dir_pages(dir);
+ struct page *page = NULL;
+ struct nilfs_inode_info *ei = NILFS_I(dir);
+ struct nilfs_dir_entry *de;
+
+ if (npages == 0)
+ goto out;
+
+ /* OFFSET_CACHE */
+ *res_page = NULL;
+
+ start = ei->i_dir_start_lookup;
+ if (start >= npages)
+ start = 0;
+ n = start;
+ do {
+ char *kaddr;
+ page = nilfs_get_page(dir, n);
+ if (!IS_ERR(page)) {
+ kaddr = page_address(page);
+ de = (struct nilfs_dir_entry *)kaddr;
+ kaddr += nilfs_last_byte(dir, n) - reclen;
+ while ((char *) de <= kaddr) {
+ if (de->rec_len == 0) {
+ nilfs_error(dir->i_sb, __func__,
+ "zero-length directory entry");
+ nilfs_put_page(page);
+ goto out;
+ }
+ if (nilfs_match(namelen, name, de))
+ goto found;
+ de = nilfs_next_entry(de);
+ }
+ nilfs_put_page(page);
+ }
+ if (++n >= npages)
+ n = 0;
+ /* next page is past the blocks we've got */
+ if (unlikely(n > (dir->i_blocks >> (PAGE_CACHE_SHIFT - 9)))) {
+ nilfs_error(dir->i_sb, __func__,
+ "dir %lu size %lld exceeds block cout %llu",
+ dir->i_ino, dir->i_size,
+ (unsigned long long)dir->i_blocks);
+ goto out;
+ }
+ } while (n != start);
+out:
+ return NULL;
+
+found:
+ *res_page = page;
+ ei->i_dir_start_lookup = n;
+ return de;
+}
+
+struct nilfs_dir_entry *nilfs_dotdot(struct inode *dir, struct page **p)
+{
+ struct page *page = nilfs_get_page(dir, 0);
+ struct nilfs_dir_entry *de = NULL;
+
+ if (!IS_ERR(page)) {
+ de = nilfs_next_entry(
+ (struct nilfs_dir_entry *)page_address(page));
+ *p = page;
+ }
+ return de;
+}
+
+ino_t nilfs_inode_by_name(struct inode *dir, struct dentry *dentry)
+{
+ ino_t res = 0;
+ struct nilfs_dir_entry *de;
+ struct page *page;
+
+ de = nilfs_find_entry(dir, dentry, &page);
+ if (de) {
+ res = le64_to_cpu(de->inode);
+ kunmap(page);
+ page_cache_release(page);
+ }
+ return res;
+}
+
+/* Releases the page */
+void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
+ struct page *page, struct inode *inode)
+{
+ unsigned from = (char *) de - (char *) page_address(page);
+ unsigned to = from + le16_to_cpu(de->rec_len);
+ struct address_space *mapping = page->mapping;
+ int err;
+
+ lock_page(page);
+ err = nilfs_prepare_chunk_uninterruptible(page, mapping, from, to);
+ BUG_ON(err);
+ de->inode = cpu_to_le64(inode->i_ino);
+ nilfs_set_de_type(de, inode);
+ err = nilfs_commit_chunk(page, mapping, from, to);
+ nilfs_put_page(page);
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+/* NILFS_I(dir)->i_flags &= ~NILFS_BTREE_FL; */
+ mark_inode_dirty(dir);
+}
+
+/*
+ * Parent is locked.
+ */
+int nilfs_add_link(struct dentry *dentry, struct inode *inode)
+{
+ struct inode *dir = dentry->d_parent->d_inode;
+ const char *name = dentry->d_name.name;
+ int namelen = dentry->d_name.len;
+ unsigned chunk_size = nilfs_chunk_size(dir);
+ unsigned reclen = NILFS_DIR_REC_LEN(namelen);
+ unsigned short rec_len, name_len;
+ struct page *page = NULL;
+ struct nilfs_dir_entry *de;
+ unsigned long npages = dir_pages(dir);
+ unsigned long n;
+ char *kaddr;
+ unsigned from, to;
+ int err;
+
+ /*
+ * We take care of directory expansion in the same loop.
+ * This code plays outside i_size, so it locks the page
+ * to protect that region.
+ */
+ for (n = 0; n <= npages; n++) {
+ char *dir_end;
+
+ page = nilfs_get_page(dir, n);
+ err = PTR_ERR(page);
+ if (IS_ERR(page))
+ goto out;
+ lock_page(page);
+ kaddr = page_address(page);
+ dir_end = kaddr + nilfs_last_byte(dir, n);
+ de = (struct nilfs_dir_entry *)kaddr;
+ kaddr += PAGE_CACHE_SIZE - reclen;
+ while ((char *)de <= kaddr) {
+ if ((char *)de == dir_end) {
+ /* We hit i_size */
+ name_len = 0;
+ rec_len = chunk_size;
+ de->rec_len = cpu_to_le16(chunk_size);
+ de->inode = 0;
+ goto got_it;
+ }
+ if (de->rec_len == 0) {
+ nilfs_error(dir->i_sb, __func__,
+ "zero-length directory entry");
+ err = -EIO;
+ goto out_unlock;
+ }
+ err = -EEXIST;
+ if (nilfs_match(namelen, name, de))
+ goto out_unlock;
+ name_len = NILFS_DIR_REC_LEN(de->name_len);
+ rec_len = le16_to_cpu(de->rec_len);
+ if (!de->inode && rec_len >= reclen)
+ goto got_it;
+ if (rec_len >= name_len + reclen)
+ goto got_it;
+ de = (struct nilfs_dir_entry *)((char *)de + rec_len);
+ }
+ unlock_page(page);
+ nilfs_put_page(page);
+ }
+ BUG();
+ return -EINVAL;
+
+got_it:
+ from = (char *)de - (char *)page_address(page);
+ to = from + rec_len;
+ err = nilfs_prepare_chunk(page, page->mapping, from, to);
+ if (err)
+ goto out_unlock;
+ if (de->inode) {
+ struct nilfs_dir_entry *de1;
+
+ de1 = (struct nilfs_dir_entry *)((char *)de + name_len);
+ de1->rec_len = cpu_to_le16(rec_len - name_len);
+ de->rec_len = cpu_to_le16(name_len);
+ de = de1;
+ }
+ de->name_len = namelen;
+ memcpy(de->name, name, namelen);
+ de->inode = cpu_to_le64(inode->i_ino);
+ nilfs_set_de_type(de, inode);
+ err = nilfs_commit_chunk(page, page->mapping, from, to);
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+/* NILFS_I(dir)->i_flags &= ~NILFS_BTREE_FL; */
+ mark_inode_dirty(dir);
+ /* OFFSET_CACHE */
+out_put:
+ nilfs_put_page(page);
+out:
+ return err;
+out_unlock:
+ unlock_page(page);
+ goto out_put;
+}
+
+/*
+ * nilfs_delete_entry deletes a directory entry by merging it with the
+ * previous entry. Page is up-to-date. Releases the page.
+ */
+int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page)
+{
+ struct address_space *mapping = page->mapping;
+ struct inode *inode = mapping->host;
+ char *kaddr = page_address(page);
+ unsigned from = ((char *)dir - kaddr) & ~(nilfs_chunk_size(inode) - 1);
+ unsigned to = ((char *)dir - kaddr) + le16_to_cpu(dir->rec_len);
+ struct nilfs_dir_entry *pde = NULL;
+ struct nilfs_dir_entry *de = (struct nilfs_dir_entry *)(kaddr + from);
+ int err;
+
+ while ((char *)de < (char *)dir) {
+ if (de->rec_len == 0) {
+ nilfs_error(inode->i_sb, __func__,
+ "zero-length directory entry");
+ err = -EIO;
+ goto out;
+ }
+ pde = de;
+ de = nilfs_next_entry(de);
+ }
+ if (pde)
+ from = (char *)pde - (char *)page_address(page);
+ lock_page(page);
+ err = nilfs_prepare_chunk(page, mapping, from, to);
+ BUG_ON(err);
+ if (pde)
+ pde->rec_len = cpu_to_le16(to - from);
+ dir->inode = 0;
+ err = nilfs_commit_chunk(page, mapping, from, to);
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+/* NILFS_I(inode)->i_flags &= ~NILFS_BTREE_FL; */
+ mark_inode_dirty(inode);
+out:
+ nilfs_put_page(page);
+ return err;
+}
+
+/*
+ * Set the first fragment of directory.
+ */
+int nilfs_make_empty(struct inode *inode, struct inode *parent)
+{
+ struct address_space *mapping = inode->i_mapping;
+ struct page *page = grab_cache_page(mapping, 0);
+ unsigned chunk_size = nilfs_chunk_size(inode);
+ struct nilfs_dir_entry *de;
+ int err;
+ void *kaddr;
+
+ if (!page)
+ return -ENOMEM;
+
+ err = nilfs_prepare_chunk(page, mapping, 0, chunk_size);
+ if (unlikely(err)) {
+ unlock_page(page);
+ goto fail;
+ }
+ kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr, 0, chunk_size);
+ de = (struct nilfs_dir_entry *)kaddr;
+ de->name_len = 1;
+ de->rec_len = cpu_to_le16(NILFS_DIR_REC_LEN(1));
+ memcpy(de->name, ".\0\0", 4);
+ de->inode = cpu_to_le64(inode->i_ino);
+ nilfs_set_de_type(de, inode);
+
+ de = (struct nilfs_dir_entry *)(kaddr + NILFS_DIR_REC_LEN(1));
+ de->name_len = 2;
+ de->rec_len = cpu_to_le16(chunk_size - NILFS_DIR_REC_LEN(1));
+ de->inode = cpu_to_le64(parent->i_ino);
+ memcpy(de->name, "..\0", 4);
+ nilfs_set_de_type(de, inode);
+ kunmap_atomic(kaddr, KM_USER0);
+ err = nilfs_commit_chunk(page, mapping, 0, chunk_size);
+fail:
+ page_cache_release(page);
+ return err;
+}
+
+/*
+ * routine to check that the specified directory is empty (for rmdir)
+ */
+int nilfs_empty_dir(struct inode *inode)
+{
+ struct page *page = NULL;
+ unsigned long i, npages = dir_pages(inode);
+
+ for (i = 0; i < npages; i++) {
+ char *kaddr;
+ struct nilfs_dir_entry *de;
+
+ page = nilfs_get_page(inode, i);
+ if (IS_ERR(page))
+ continue;
+
+ kaddr = page_address(page);
+ de = (struct nilfs_dir_entry *)kaddr;
+ kaddr += nilfs_last_byte(inode, i) - NILFS_DIR_REC_LEN(1);
+
+ while ((char *)de <= kaddr) {
+ if (de->rec_len == 0) {
+ nilfs_error(inode->i_sb, __func__,
+ "zero-length directory entry "
+ "(kaddr=%p, de=%p)\n", kaddr, de);
+ goto not_empty;
+ }
+ if (de->inode != 0) {
+ /* check for . and .. */
+ if (de->name[0] != '.')
+ goto not_empty;
+ if (de->name_len > 2)
+ goto not_empty;
+ if (de->name_len < 2) {
+ if (de->inode !=
+ cpu_to_le64(inode->i_ino))
+ goto not_empty;
+ } else if (de->name[1] != '.')
+ goto not_empty;
+ }
+ de = nilfs_next_entry(de);
+ }
+ nilfs_put_page(page);
+ }
+ return 1;
+
+not_empty:
+ nilfs_put_page(page);
+ return 0;
+}
+
+struct file_operations nilfs_dir_operations = {
+ .llseek = generic_file_llseek,
+ .read = generic_read_dir,
+ .readdir = nilfs_readdir,
+ .unlocked_ioctl = nilfs_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = nilfs_ioctl,
+#endif /* CONFIG_COMPAT */
+ .fsync = nilfs_sync_file,
+
+};
diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c
new file mode 100644
index 00000000000..c6379e48278
--- /dev/null
+++ b/fs/nilfs2/direct.c
@@ -0,0 +1,436 @@
+/*
+ * direct.c - NILFS direct block pointer.
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#include <linux/errno.h>
+#include "nilfs.h"
+#include "page.h"
+#include "direct.h"
+#include "alloc.h"
+
+static inline __le64 *nilfs_direct_dptrs(const struct nilfs_direct *direct)
+{
+ return (__le64 *)
+ ((struct nilfs_direct_node *)direct->d_bmap.b_u.u_data + 1);
+}
+
+static inline __u64
+nilfs_direct_get_ptr(const struct nilfs_direct *direct, __u64 key)
+{
+ return nilfs_bmap_dptr_to_ptr(*(nilfs_direct_dptrs(direct) + key));
+}
+
+static inline void nilfs_direct_set_ptr(struct nilfs_direct *direct,
+ __u64 key, __u64 ptr)
+{
+ *(nilfs_direct_dptrs(direct) + key) = nilfs_bmap_ptr_to_dptr(ptr);
+}
+
+static int nilfs_direct_lookup(const struct nilfs_bmap *bmap,
+ __u64 key, int level, __u64 *ptrp)
+{
+ struct nilfs_direct *direct;
+ __u64 ptr;
+
+ direct = (struct nilfs_direct *)bmap;
+ if ((key > NILFS_DIRECT_KEY_MAX) ||
+ (level != 1) || /* XXX: use macro for level 1 */
+ ((ptr = nilfs_direct_get_ptr(direct, key)) ==
+ NILFS_BMAP_INVALID_PTR))
+ return -ENOENT;
+
+ if (ptrp != NULL)
+ *ptrp = ptr;
+ return 0;
+}
+
+static __u64
+nilfs_direct_find_target_v(const struct nilfs_direct *direct, __u64 key)
+{
+ __u64 ptr;
+
+ ptr = nilfs_bmap_find_target_seq(&direct->d_bmap, key);
+ if (ptr != NILFS_BMAP_INVALID_PTR)
+ /* sequential access */
+ return ptr;
+ else
+ /* block group */
+ return nilfs_bmap_find_target_in_group(&direct->d_bmap);
+}
+
+static void nilfs_direct_set_target_v(struct nilfs_direct *direct,
+ __u64 key, __u64 ptr)
+{
+ direct->d_bmap.b_last_allocated_key = key;
+ direct->d_bmap.b_last_allocated_ptr = ptr;
+}
+
+static int nilfs_direct_prepare_insert(struct nilfs_direct *direct,
+ __u64 key,
+ union nilfs_bmap_ptr_req *req,
+ struct nilfs_bmap_stats *stats)
+{
+ int ret;
+
+ if (direct->d_ops->dop_find_target != NULL)
+ req->bpr_ptr = direct->d_ops->dop_find_target(direct, key);
+ ret = direct->d_bmap.b_pops->bpop_prepare_alloc_ptr(&direct->d_bmap,
+ req);
+ if (ret < 0)
+ return ret;
+
+ stats->bs_nblocks = 1;
+ return 0;
+}
+
+static void nilfs_direct_commit_insert(struct nilfs_direct *direct,
+ union nilfs_bmap_ptr_req *req,
+ __u64 key, __u64 ptr)
+{
+ struct buffer_head *bh;
+
+ /* ptr must be a pointer to a buffer head. */
+ bh = (struct buffer_head *)((unsigned long)ptr);
+ set_buffer_nilfs_volatile(bh);
+
+ if (direct->d_bmap.b_pops->bpop_commit_alloc_ptr != NULL)
+ direct->d_bmap.b_pops->bpop_commit_alloc_ptr(
+ &direct->d_bmap, req);
+ nilfs_direct_set_ptr(direct, key, req->bpr_ptr);
+
+ if (!nilfs_bmap_dirty(&direct->d_bmap))
+ nilfs_bmap_set_dirty(&direct->d_bmap);
+
+ if (direct->d_ops->dop_set_target != NULL)
+ direct->d_ops->dop_set_target(direct, key, req->bpr_ptr);
+}
+
+static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
+{
+ struct nilfs_direct *direct;
+ union nilfs_bmap_ptr_req req;
+ struct nilfs_bmap_stats stats;
+ int ret;
+
+ direct = (struct nilfs_direct *)bmap;
+ if (key > NILFS_DIRECT_KEY_MAX)
+ return -ENOENT;
+ if (nilfs_direct_get_ptr(direct, key) != NILFS_BMAP_INVALID_PTR)
+ return -EEXIST;
+
+ ret = nilfs_direct_prepare_insert(direct, key, &req, &stats);
+ if (ret < 0)
+ return ret;
+ nilfs_direct_commit_insert(direct, &req, key, ptr);
+ nilfs_bmap_add_blocks(bmap, stats.bs_nblocks);
+
+ return 0;
+}
+
+static int nilfs_direct_prepare_delete(struct nilfs_direct *direct,
+ union nilfs_bmap_ptr_req *req,
+ __u64 key,
+ struct nilfs_bmap_stats *stats)
+{
+ int ret;
+
+ if (direct->d_bmap.b_pops->bpop_prepare_end_ptr != NULL) {
+ req->bpr_ptr = nilfs_direct_get_ptr(direct, key);
+ ret = direct->d_bmap.b_pops->bpop_prepare_end_ptr(
+ &direct->d_bmap, req);
+ if (ret < 0)
+ return ret;
+ }
+
+ stats->bs_nblocks = 1;
+ return 0;
+}
+
+static void nilfs_direct_commit_delete(struct nilfs_direct *direct,
+ union nilfs_bmap_ptr_req *req,
+ __u64 key)
+{
+ if (direct->d_bmap.b_pops->bpop_commit_end_ptr != NULL)
+ direct->d_bmap.b_pops->bpop_commit_end_ptr(
+ &direct->d_bmap, req);
+ nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR);
+}
+
+static int nilfs_direct_delete(struct nilfs_bmap *bmap, __u64 key)
+{
+ struct nilfs_direct *direct;
+ union nilfs_bmap_ptr_req req;
+ struct nilfs_bmap_stats stats;
+ int ret;
+
+ direct = (struct nilfs_direct *)bmap;
+ if ((key > NILFS_DIRECT_KEY_MAX) ||
+ nilfs_direct_get_ptr(direct, key) == NILFS_BMAP_INVALID_PTR)
+ return -ENOENT;
+
+ ret = nilfs_direct_prepare_delete(direct, &req, key, &stats);
+ if (ret < 0)
+ return ret;
+ nilfs_direct_commit_delete(direct, &req, key);
+ nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks);
+
+ return 0;
+}
+
+static int nilfs_direct_last_key(const struct nilfs_bmap *bmap, __u64 *keyp)
+{
+ struct nilfs_direct *direct;
+ __u64 key, lastkey;
+
+ direct = (struct nilfs_direct *)bmap;
+ lastkey = NILFS_DIRECT_KEY_MAX + 1;
+ for (key = NILFS_DIRECT_KEY_MIN; key <= NILFS_DIRECT_KEY_MAX; key++)
+ if (nilfs_direct_get_ptr(direct, key) !=
+ NILFS_BMAP_INVALID_PTR)
+ lastkey = key;
+
+ if (lastkey == NILFS_DIRECT_KEY_MAX + 1)
+ return -ENOENT;
+
+ *keyp = lastkey;
+
+ return 0;
+}
+
+static int nilfs_direct_check_insert(const struct nilfs_bmap *bmap, __u64 key)
+{
+ return key > NILFS_DIRECT_KEY_MAX;
+}
+
+static int nilfs_direct_gather_data(struct nilfs_bmap *bmap,
+ __u64 *keys, __u64 *ptrs, int nitems)
+{
+ struct nilfs_direct *direct;
+ __u64 key;
+ __u64 ptr;
+ int n;
+
+ direct = (struct nilfs_direct *)bmap;
+ if (nitems > NILFS_DIRECT_NBLOCKS)
+ nitems = NILFS_DIRECT_NBLOCKS;
+ n = 0;
+ for (key = 0; key < nitems; key++) {
+ ptr = nilfs_direct_get_ptr(direct, key);
+ if (ptr != NILFS_BMAP_INVALID_PTR) {
+ keys[n] = key;
+ ptrs[n] = ptr;
+ n++;
+ }
+ }
+ return n;
+}
+
+int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
+ __u64 key, __u64 *keys, __u64 *ptrs,
+ int n, __u64 low, __u64 high)
+{
+ struct nilfs_direct *direct;
+ __le64 *dptrs;
+ int ret, i, j;
+
+ /* no need to allocate any resource for conversion */
+
+ /* delete */
+ ret = bmap->b_ops->bop_delete(bmap, key);
+ if (ret < 0)
+ return ret;
+
+ /* free resources */
+ if (bmap->b_ops->bop_clear != NULL)
+ bmap->b_ops->bop_clear(bmap);
+
+ /* convert */
+ direct = (struct nilfs_direct *)bmap;
+ dptrs = nilfs_direct_dptrs(direct);
+ for (i = 0, j = 0; i < NILFS_DIRECT_NBLOCKS; i++) {
+ if ((j < n) && (i == keys[j])) {
+ dptrs[i] = (i != key) ?
+ nilfs_bmap_ptr_to_dptr(ptrs[j]) :
+ NILFS_BMAP_INVALID_PTR;
+ j++;
+ } else
+ dptrs[i] = NILFS_BMAP_INVALID_PTR;
+ }
+
+ nilfs_direct_init(bmap, low, high);
+
+ return 0;
+}
+
+static int nilfs_direct_propagate_v(struct nilfs_direct *direct,
+ struct buffer_head *bh)
+{
+ union nilfs_bmap_ptr_req oldreq, newreq;
+ __u64 key;
+ __u64 ptr;
+ int ret;
+
+ key = nilfs_bmap_data_get_key(&direct->d_bmap, bh);
+ ptr = nilfs_direct_get_ptr(direct, key);
+ if (!buffer_nilfs_volatile(bh)) {
+ oldreq.bpr_ptr = ptr;
+ newreq.bpr_ptr = ptr;
+ ret = nilfs_bmap_prepare_update(&direct->d_bmap, &oldreq,
+ &newreq);
+ if (ret < 0)
+ return ret;
+ nilfs_bmap_commit_update(&direct->d_bmap, &oldreq, &newreq);
+ set_buffer_nilfs_volatile(bh);
+ nilfs_direct_set_ptr(direct, key, newreq.bpr_ptr);
+ } else
+ ret = nilfs_bmap_mark_dirty(&direct->d_bmap, ptr);
+
+ return ret;
+}
+
+static int nilfs_direct_propagate(const struct nilfs_bmap *bmap,
+ struct buffer_head *bh)
+{
+ struct nilfs_direct *direct;
+
+ direct = (struct nilfs_direct *)bmap;
+ return (direct->d_ops->dop_propagate != NULL) ?
+ direct->d_ops->dop_propagate(direct, bh) :
+ 0;
+}
+
+static int nilfs_direct_assign_v(struct nilfs_direct *direct,
+ __u64 key, __u64 ptr,
+ struct buffer_head **bh,
+ sector_t blocknr,
+ union nilfs_binfo *binfo)
+{
+ union nilfs_bmap_ptr_req req;
+ int ret;
+
+ req.bpr_ptr = ptr;
+ ret = direct->d_bmap.b_pops->bpop_prepare_start_ptr(
+ &direct->d_bmap, &req);
+ if (ret < 0)
+ return ret;
+ direct->d_bmap.b_pops->bpop_commit_start_ptr(&direct->d_bmap,
+ &req, blocknr);
+
+ binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr);
+ binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
+
+ return 0;
+}
+
+static int nilfs_direct_assign_p(struct nilfs_direct *direct,
+ __u64 key, __u64 ptr,
+ struct buffer_head **bh,
+ sector_t blocknr,
+ union nilfs_binfo *binfo)
+{
+ nilfs_direct_set_ptr(direct, key, blocknr);
+
+ binfo->bi_dat.bi_blkoff = nilfs_bmap_key_to_dkey(key);
+ binfo->bi_dat.bi_level = 0;
+
+ return 0;
+}
+
+static int nilfs_direct_assign(struct nilfs_bmap *bmap,
+ struct buffer_head **bh,
+ sector_t blocknr,
+ union nilfs_binfo *binfo)
+{
+ struct nilfs_direct *direct;
+ __u64 key;
+ __u64 ptr;
+
+ direct = (struct nilfs_direct *)bmap;
+ key = nilfs_bmap_data_get_key(bmap, *bh);
+ if (unlikely(key > NILFS_DIRECT_KEY_MAX)) {
+ printk(KERN_CRIT "%s: invalid key: %llu\n", __func__,
+ (unsigned long long)key);
+ return -EINVAL;
+ }
+ ptr = nilfs_direct_get_ptr(direct, key);
+ if (unlikely(ptr == NILFS_BMAP_INVALID_PTR)) {
+ printk(KERN_CRIT "%s: invalid pointer: %llu\n", __func__,
+ (unsigned long long)ptr);
+ return -EINVAL;
+ }
+
+ return direct->d_ops->dop_assign(direct, key, ptr, bh,
+ blocknr, binfo);
+}
+
+static const struct nilfs_bmap_operations nilfs_direct_ops = {
+ .bop_lookup = nilfs_direct_lookup,
+ .bop_insert = nilfs_direct_insert,
+ .bop_delete = nilfs_direct_delete,
+ .bop_clear = NULL,
+
+ .bop_propagate = nilfs_direct_propagate,
+
+ .bop_lookup_dirty_buffers = NULL,
+
+ .bop_assign = nilfs_direct_assign,
+ .bop_mark = NULL,
+
+ .bop_last_key = nilfs_direct_last_key,
+ .bop_check_insert = nilfs_direct_check_insert,
+ .bop_check_delete = NULL,
+ .bop_gather_data = nilfs_direct_gather_data,
+};
+
+
+static const struct nilfs_direct_operations nilfs_direct_ops_v = {
+ .dop_find_target = nilfs_direct_find_target_v,
+ .dop_set_target = nilfs_direct_set_target_v,
+ .dop_propagate = nilfs_direct_propagate_v,
+ .dop_assign = nilfs_direct_assign_v,
+};
+
+static const struct nilfs_direct_operations nilfs_direct_ops_p = {
+ .dop_find_target = NULL,
+ .dop_set_target = NULL,
+ .dop_propagate = NULL,
+ .dop_assign = nilfs_direct_assign_p,
+};
+
+int nilfs_direct_init(struct nilfs_bmap *bmap, __u64 low, __u64 high)
+{
+ struct nilfs_direct *direct;
+
+ direct = (struct nilfs_direct *)bmap;
+ bmap->b_ops = &nilfs_direct_ops;
+ bmap->b_low = low;
+ bmap->b_high = high;
+ switch (bmap->b_inode->i_ino) {
+ case NILFS_DAT_INO:
+ direct->d_ops = &nilfs_direct_ops_p;
+ break;
+ default:
+ direct->d_ops = &nilfs_direct_ops_v;
+ break;
+ }
+
+ return 0;
+}
diff --git a/fs/nilfs2/direct.h b/fs/nilfs2/direct.h
new file mode 100644
index 00000000000..45d2c5cda81
--- /dev/null
+++ b/fs/nilfs2/direct.h
@@ -0,0 +1,78 @@
+/*
+ * direct.h - NILFS direct block pointer.
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#ifndef _NILFS_DIRECT_H
+#define _NILFS_DIRECT_H
+
+#include <linux/types.h>
+#include <linux/buffer_head.h>
+#include "bmap.h"
+
+
+struct nilfs_direct;
+
+/**
+ * struct nilfs_direct_operations - direct mapping operation table
+ */
+struct nilfs_direct_operations {
+ __u64 (*dop_find_target)(const struct nilfs_direct *, __u64);
+ void (*dop_set_target)(struct nilfs_direct *, __u64, __u64);
+ int (*dop_propagate)(struct nilfs_direct *, struct buffer_head *);
+ int (*dop_assign)(struct nilfs_direct *, __u64, __u64,
+ struct buffer_head **, sector_t,
+ union nilfs_binfo *);
+};
+
+/**
+ * struct nilfs_direct_node - direct node
+ * @dn_flags: flags
+ * @dn_pad: padding
+ */
+struct nilfs_direct_node {
+ __u8 dn_flags;
+ __u8 pad[7];
+};
+
+/**
+ * struct nilfs_direct - direct mapping
+ * @d_bmap: bmap structure
+ * @d_ops: direct mapping operation table
+ */
+struct nilfs_direct {
+ struct nilfs_bmap d_bmap;
+
+ /* direct-mapping-specific members */
+ const struct nilfs_direct_operations *d_ops;
+};
+
+
+#define NILFS_DIRECT_NBLOCKS (NILFS_BMAP_SIZE / sizeof(__le64) - 1)
+#define NILFS_DIRECT_KEY_MIN 0
+#define NILFS_DIRECT_KEY_MAX (NILFS_DIRECT_NBLOCKS - 1)
+
+
+int nilfs_direct_init(struct nilfs_bmap *, __u64, __u64);
+int nilfs_direct_delete_and_convert(struct nilfs_bmap *, __u64, __u64 *,
+ __u64 *, int, __u64, __u64);
+
+
+#endif /* _NILFS_DIRECT_H */
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
new file mode 100644
index 00000000000..6bd84a0d823
--- /dev/null
+++ b/fs/nilfs2/file.c
@@ -0,0 +1,160 @@
+/*
+ * file.c - NILFS regular file handling primitives including fsync().
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Amagai Yoshiji <amagai@osrg.net>,
+ * Ryusuke Konishi <ryusuke@osrg.net>
+ */
+
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/writeback.h>
+#include "nilfs.h"
+#include "segment.h"
+
+int nilfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
+{
+ /*
+ * Called from fsync() system call
+ * This is the only entry point that can catch write and synch
+ * timing for both data blocks and intermediate blocks.
+ *
+ * This function should be implemented when the writeback function
+ * will be implemented.
+ */
+ struct inode *inode = dentry->d_inode;
+ int err;
+
+ if (!nilfs_inode_dirty(inode))
+ return 0;
+
+ if (datasync)
+ err = nilfs_construct_dsync_segment(inode->i_sb, inode, 0,
+ LLONG_MAX);
+ else
+ err = nilfs_construct_segment(inode->i_sb);
+
+ return err;
+}
+
+static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ struct page *page = vmf->page;
+ struct inode *inode = vma->vm_file->f_dentry->d_inode;
+ struct nilfs_transaction_info ti;
+ int ret;
+
+ if (unlikely(nilfs_near_disk_full(NILFS_SB(inode->i_sb)->s_nilfs)))
+ return VM_FAULT_SIGBUS; /* -ENOSPC */
+
+ lock_page(page);
+ if (page->mapping != inode->i_mapping ||
+ page_offset(page) >= i_size_read(inode) || !PageUptodate(page)) {
+ unlock_page(page);
+ return VM_FAULT_NOPAGE; /* make the VM retry the fault */
+ }
+
+ /*
+ * check to see if the page is mapped already (no holes)
+ */
+ if (PageMappedToDisk(page)) {
+ unlock_page(page);
+ goto mapped;
+ }
+ if (page_has_buffers(page)) {
+ struct buffer_head *bh, *head;
+ int fully_mapped = 1;
+
+ bh = head = page_buffers(page);
+ do {
+ if (!buffer_mapped(bh)) {
+ fully_mapped = 0;
+ break;
+ }
+ } while (bh = bh->b_this_page, bh != head);
+
+ if (fully_mapped) {
+ SetPageMappedToDisk(page);
+ unlock_page(page);
+ goto mapped;
+ }
+ }
+ unlock_page(page);
+
+ /*
+ * fill hole blocks
+ */
+ ret = nilfs_transaction_begin(inode->i_sb, &ti, 1);
+ /* never returns -ENOMEM, but may return -ENOSPC */
+ if (unlikely(ret))
+ return VM_FAULT_SIGBUS;
+
+ ret = block_page_mkwrite(vma, vmf, nilfs_get_block);
+ if (unlikely(ret)) {
+ nilfs_transaction_abort(inode->i_sb);
+ return ret;
+ }
+ nilfs_transaction_commit(inode->i_sb);
+
+ mapped:
+ SetPageChecked(page);
+ wait_on_page_writeback(page);
+ return 0;
+}
+
+struct vm_operations_struct nilfs_file_vm_ops = {
+ .fault = filemap_fault,
+ .page_mkwrite = nilfs_page_mkwrite,
+};
+
+static int nilfs_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ file_accessed(file);
+ vma->vm_ops = &nilfs_file_vm_ops;
+ vma->vm_flags |= VM_CAN_NONLINEAR;
+ return 0;
+}
+
+/*
+ * We have mostly NULL's here: the current defaults are ok for
+ * the nilfs filesystem.
+ */
+struct file_operations nilfs_file_operations = {
+ .llseek = generic_file_llseek,
+ .read = do_sync_read,
+ .write = do_sync_write,
+ .aio_read = generic_file_aio_read,
+ .aio_write = generic_file_aio_write,
+ .unlocked_ioctl = nilfs_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = nilfs_ioctl,
+#endif /* CONFIG_COMPAT */
+ .mmap = nilfs_file_mmap,
+ .open = generic_file_open,
+ /* .release = nilfs_release_file, */
+ .fsync = nilfs_sync_file,
+ .splice_read = generic_file_splice_read,
+};
+
+struct inode_operations nilfs_file_inode_operations = {
+ .truncate = nilfs_truncate,
+ .setattr = nilfs_setattr,
+ .permission = nilfs_permission,
+};
+
+/* end of file */
diff --git a/fs/nilfs2/gcdat.c b/fs/nilfs2/gcdat.c
new file mode 100644
index 00000000000..93383c5cee9
--- /dev/null
+++ b/fs/nilfs2/gcdat.c
@@ -0,0 +1,84 @@
+/*
+ * gcdat.c - NILFS shadow DAT inode for GC
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Seiji Kihara <kihara@osrg.net>, Amagai Yoshiji <amagai@osrg.net>,
+ * and Ryusuke Konishi <ryusuke@osrg.net>.
+ *
+ */
+
+#include <linux/buffer_head.h>
+#include "nilfs.h"
+#include "page.h"
+#include "mdt.h"
+
+int nilfs_init_gcdat_inode(struct the_nilfs *nilfs)
+{
+ struct inode *dat = nilfs->ns_dat, *gcdat = nilfs->ns_gc_dat;
+ struct nilfs_inode_info *dii = NILFS_I(dat), *gii = NILFS_I(gcdat);
+ int err;
+
+ gcdat->i_state = 0;
+ gcdat->i_blocks = dat->i_blocks;
+ gii->i_flags = dii->i_flags;
+ gii->i_state = dii->i_state | (1 << NILFS_I_GCDAT);
+ gii->i_cno = 0;
+ nilfs_bmap_init_gcdat(gii->i_bmap, dii->i_bmap);
+ err = nilfs_copy_dirty_pages(gcdat->i_mapping, dat->i_mapping);
+ if (unlikely(err))
+ return err;
+
+ return nilfs_copy_dirty_pages(&gii->i_btnode_cache,
+ &dii->i_btnode_cache);
+}
+
+void nilfs_commit_gcdat_inode(struct the_nilfs *nilfs)
+{
+ struct inode *dat = nilfs->ns_dat, *gcdat = nilfs->ns_gc_dat;
+ struct nilfs_inode_info *dii = NILFS_I(dat), *gii = NILFS_I(gcdat);
+ struct address_space *mapping = dat->i_mapping;
+ struct address_space *gmapping = gcdat->i_mapping;
+
+ down_write(&NILFS_MDT(dat)->mi_sem);
+ dat->i_blocks = gcdat->i_blocks;
+ dii->i_flags = gii->i_flags;
+ dii->i_state = gii->i_state & ~(1 << NILFS_I_GCDAT);
+
+ nilfs_bmap_commit_gcdat(gii->i_bmap, dii->i_bmap);
+
+ nilfs_clear_dirty_pages(mapping);
+ nilfs_copy_back_pages(mapping, gmapping);
+ /* note: mdt dirty flags should be cleared by segctor. */
+
+ nilfs_clear_dirty_pages(&dii->i_btnode_cache);
+ nilfs_copy_back_pages(&dii->i_btnode_cache, &gii->i_btnode_cache);
+
+ up_write(&NILFS_MDT(dat)->mi_sem);
+}
+
+void nilfs_clear_gcdat_inode(struct the_nilfs *nilfs)
+{
+ struct inode *gcdat = nilfs->ns_gc_dat;
+ struct nilfs_inode_info *gii = NILFS_I(gcdat);
+
+ gcdat->i_state = I_CLEAR;
+ gii->i_flags = 0;
+
+ truncate_inode_pages(gcdat->i_mapping, 0);
+ truncate_inode_pages(&gii->i_btnode_cache, 0);
+}
diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c
new file mode 100644
index 00000000000..19d2102b6a6
--- /dev/null
+++ b/fs/nilfs2/gcinode.c
@@ -0,0 +1,288 @@
+/*
+ * gcinode.c - dummy inodes to buffer blocks for garbage collection
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Seiji Kihara <kihara@osrg.net>, Amagai Yoshiji <amagai@osrg.net>,
+ * and Ryusuke Konishi <ryusuke@osrg.net>.
+ * Revised by Ryusuke Konishi <ryusuke@osrg.net>.
+ *
+ */
+/*
+ * This file adds the cache of on-disk blocks to be moved in garbage
+ * collection. The disk blocks are held with dummy inodes (called
+ * gcinodes), and this file provides lookup function of the dummy
+ * inodes and their buffer read function.
+ *
+ * Since NILFS2 keeps up multiple checkpoints/snapshots accross GC, it
+ * has to treat blocks that belong to a same file but have different
+ * checkpoint numbers. To avoid interference among generations, dummy
+ * inodes are managed separatly from actual inodes, and their lookup
+ * function (nilfs_gc_iget) is designed to be specified with a
+ * checkpoint number argument as well as an inode number.
+ *
+ * Buffers and pages held by the dummy inodes will be released each
+ * time after they are copied to a new log. Dirty blocks made on the
+ * current generation and the blocks to be moved by GC never overlap
+ * because the dirty blocks make a new generation; they rather must be
+ * written individually.
+ */
+
+#include <linux/buffer_head.h>
+#include <linux/mpage.h>
+#include <linux/hash.h>
+#include <linux/swap.h>
+#include "nilfs.h"
+#include "page.h"
+#include "mdt.h"
+#include "dat.h"
+#include "ifile.h"
+
+static struct address_space_operations def_gcinode_aops = {};
+/* XXX need def_gcinode_iops/fops? */
+
+/*
+ * nilfs_gccache_submit_read_data() - add data buffer and submit read request
+ * @inode - gc inode
+ * @blkoff - dummy offset treated as the key for the page cache
+ * @pbn - physical block number of the block
+ * @vbn - virtual block number of the block, 0 for non-virtual block
+ * @out_bh - indirect pointer to a buffer_head struct to receive the results
+ *
+ * Description: nilfs_gccache_submit_read_data() registers the data buffer
+ * specified by @pbn to the GC pagecache with the key @blkoff.
+ * This function sets @vbn (@pbn if @vbn is zero) in b_blocknr of the buffer.
+ *
+ * Return Value: On success, 0 is returned. On Error, one of the following
+ * negative error code is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOENT - The block specified with @pbn does not exist.
+ */
+int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff,
+ sector_t pbn, __u64 vbn,
+ struct buffer_head **out_bh)
+{
+ struct buffer_head *bh;
+ int err;
+
+ bh = nilfs_grab_buffer(inode, inode->i_mapping, blkoff, 0);
+ if (unlikely(!bh))
+ return -ENOMEM;
+
+ if (buffer_uptodate(bh))
+ goto out;
+
+ if (pbn == 0) {
+ struct inode *dat_inode = NILFS_I_NILFS(inode)->ns_dat;
+ /* use original dat, not gc dat. */
+ err = nilfs_dat_translate(dat_inode, vbn, &pbn);
+ if (unlikely(err)) { /* -EIO, -ENOMEM, -ENOENT */
+ brelse(bh);
+ goto failed;
+ }
+ }
+
+ lock_buffer(bh);
+ if (buffer_uptodate(bh)) {
+ unlock_buffer(bh);
+ goto out;
+ }
+
+ if (!buffer_mapped(bh)) {
+ bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
+ set_buffer_mapped(bh);
+ }
+ bh->b_blocknr = pbn;
+ bh->b_end_io = end_buffer_read_sync;
+ get_bh(bh);
+ submit_bh(READ, bh);
+ if (vbn)
+ bh->b_blocknr = vbn;
+ out:
+ err = 0;
+ *out_bh = bh;
+
+ failed:
+ unlock_page(bh->b_page);
+ page_cache_release(bh->b_page);
+ return err;
+}
+
+/*
+ * nilfs_gccache_submit_read_node() - add node buffer and submit read request
+ * @inode - gc inode
+ * @pbn - physical block number for the block
+ * @vbn - virtual block number for the block
+ * @out_bh - indirect pointer to a buffer_head struct to receive the results
+ *
+ * Description: nilfs_gccache_submit_read_node() registers the node buffer
+ * specified by @vbn to the GC pagecache. @pbn can be supplied by the
+ * caller to avoid translation of the disk block address.
+ *
+ * Return Value: On success, 0 is returned. On Error, one of the following
+ * negative error code is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ */
+int nilfs_gccache_submit_read_node(struct inode *inode, sector_t pbn,
+ __u64 vbn, struct buffer_head **out_bh)
+{
+ int ret = nilfs_btnode_submit_block(&NILFS_I(inode)->i_btnode_cache,
+ vbn ? : pbn, pbn, out_bh, 0);
+ if (ret == -EEXIST) /* internal code (cache hit) */
+ ret = 0;
+ return ret;
+}
+
+int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh)
+{
+ wait_on_buffer(bh);
+ if (!buffer_uptodate(bh))
+ return -EIO;
+ if (buffer_dirty(bh))
+ return -EEXIST;
+
+ if (buffer_nilfs_node(bh))
+ nilfs_btnode_mark_dirty(bh);
+ else
+ nilfs_mdt_mark_buffer_dirty(bh);
+ return 0;
+}
+
+/*
+ * nilfs_init_gccache() - allocate and initialize gc_inode hash table
+ * @nilfs - the_nilfs
+ *
+ * Return Value: On success, 0.
+ * On error, a negative error code is returned.
+ */
+int nilfs_init_gccache(struct the_nilfs *nilfs)
+{
+ int loop;
+
+ BUG_ON(nilfs->ns_gc_inodes_h);
+
+ INIT_LIST_HEAD(&nilfs->ns_gc_inodes);
+
+ nilfs->ns_gc_inodes_h =
+ kmalloc(sizeof(struct hlist_head) * NILFS_GCINODE_HASH_SIZE,
+ GFP_NOFS);
+ if (nilfs->ns_gc_inodes_h == NULL)
+ return -ENOMEM;
+
+ for (loop = 0; loop < NILFS_GCINODE_HASH_SIZE; loop++)
+ INIT_HLIST_HEAD(&nilfs->ns_gc_inodes_h[loop]);
+ return 0;
+}
+
+/*
+ * nilfs_destroy_gccache() - free gc_inode hash table
+ * @nilfs - the nilfs
+ */
+void nilfs_destroy_gccache(struct the_nilfs *nilfs)
+{
+ if (nilfs->ns_gc_inodes_h) {
+ nilfs_remove_all_gcinode(nilfs);
+ kfree(nilfs->ns_gc_inodes_h);
+ nilfs->ns_gc_inodes_h = NULL;
+ }
+}
+
+static struct inode *alloc_gcinode(struct the_nilfs *nilfs, ino_t ino,
+ __u64 cno)
+{
+ struct inode *inode = nilfs_mdt_new_common(nilfs, NULL, ino, GFP_NOFS);
+ struct nilfs_inode_info *ii;
+
+ if (!inode)
+ return NULL;
+
+ inode->i_op = NULL;
+ inode->i_fop = NULL;
+ inode->i_mapping->a_ops = &def_gcinode_aops;
+
+ ii = NILFS_I(inode);
+ ii->i_cno = cno;
+ ii->i_flags = 0;
+ ii->i_state = 1 << NILFS_I_GCINODE;
+ ii->i_bh = NULL;
+ nilfs_bmap_init_gc(ii->i_bmap);
+
+ return inode;
+}
+
+static unsigned long ihash(ino_t ino, __u64 cno)
+{
+ return hash_long((unsigned long)((ino << 2) + cno),
+ NILFS_GCINODE_HASH_BITS);
+}
+
+/*
+ * nilfs_gc_iget() - find or create gc inode with specified (ino,cno)
+ */
+struct inode *nilfs_gc_iget(struct the_nilfs *nilfs, ino_t ino, __u64 cno)
+{
+ struct hlist_head *head = nilfs->ns_gc_inodes_h + ihash(ino, cno);
+ struct hlist_node *node;
+ struct inode *inode;
+
+ hlist_for_each_entry(inode, node, head, i_hash) {
+ if (inode->i_ino == ino && NILFS_I(inode)->i_cno == cno)
+ return inode;
+ }
+
+ inode = alloc_gcinode(nilfs, ino, cno);
+ if (likely(inode)) {
+ hlist_add_head(&inode->i_hash, head);
+ list_add(&NILFS_I(inode)->i_dirty, &nilfs->ns_gc_inodes);
+ }
+ return inode;
+}
+
+/*
+ * nilfs_clear_gcinode() - clear and free a gc inode
+ */
+void nilfs_clear_gcinode(struct inode *inode)
+{
+ nilfs_mdt_clear(inode);
+ nilfs_mdt_destroy(inode);
+}
+
+/*
+ * nilfs_remove_all_gcinode() - remove all inodes from the_nilfs
+ */
+void nilfs_remove_all_gcinode(struct the_nilfs *nilfs)
+{
+ struct hlist_head *head = nilfs->ns_gc_inodes_h;
+ struct hlist_node *node, *n;
+ struct inode *inode;
+ int loop;
+
+ for (loop = 0; loop < NILFS_GCINODE_HASH_SIZE; loop++, head++) {
+ hlist_for_each_entry_safe(inode, node, n, head, i_hash) {
+ hlist_del_init(&inode->i_hash);
+ list_del_init(&NILFS_I(inode)->i_dirty);
+ nilfs_clear_gcinode(inode); /* might sleep */
+ }
+ }
+}
diff --git a/fs/nilfs2/ifile.c b/fs/nilfs2/ifile.c
new file mode 100644
index 00000000000..de86401f209
--- /dev/null
+++ b/fs/nilfs2/ifile.c
@@ -0,0 +1,150 @@
+/*
+ * ifile.c - NILFS inode file
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Amagai Yoshiji <amagai@osrg.net>.
+ * Revised by Ryusuke Konishi <ryusuke@osrg.net>.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/buffer_head.h>
+#include "nilfs.h"
+#include "mdt.h"
+#include "alloc.h"
+#include "ifile.h"
+
+/**
+ * nilfs_ifile_create_inode - create a new disk inode
+ * @ifile: ifile inode
+ * @out_ino: pointer to a variable to store inode number
+ * @out_bh: buffer_head contains newly allocated disk inode
+ *
+ * Return Value: On success, 0 is returned and the newly allocated inode
+ * number is stored in the place pointed by @ino, and buffer_head pointer
+ * that contains newly allocated disk inode structure is stored in the
+ * place pointed by @out_bh
+ * On error, one of the following negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOSPC - No inode left.
+ */
+int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino,
+ struct buffer_head **out_bh)
+{
+ struct nilfs_palloc_req req;
+ int ret;
+
+ req.pr_entry_nr = 0; /* 0 says find free inode from beginning of
+ a group. dull code!! */
+ req.pr_entry_bh = NULL;
+
+ ret = nilfs_palloc_prepare_alloc_entry(ifile, &req);
+ if (!ret) {
+ ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 1,
+ &req.pr_entry_bh);
+ if (ret < 0)
+ nilfs_palloc_abort_alloc_entry(ifile, &req);
+ }
+ if (ret < 0) {
+ brelse(req.pr_entry_bh);
+ return ret;
+ }
+ nilfs_palloc_commit_alloc_entry(ifile, &req);
+ nilfs_mdt_mark_buffer_dirty(req.pr_entry_bh);
+ nilfs_mdt_mark_dirty(ifile);
+ *out_ino = (ino_t)req.pr_entry_nr;
+ *out_bh = req.pr_entry_bh;
+ return 0;
+}
+
+/**
+ * nilfs_ifile_delete_inode - delete a disk inode
+ * @ifile: ifile inode
+ * @ino: inode number
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOENT - The inode number @ino have not been allocated.
+ */
+int nilfs_ifile_delete_inode(struct inode *ifile, ino_t ino)
+{
+ struct nilfs_palloc_req req = {
+ .pr_entry_nr = ino, .pr_entry_bh = NULL
+ };
+ struct nilfs_inode *raw_inode;
+ void *kaddr;
+ int ret;
+
+ ret = nilfs_palloc_prepare_free_entry(ifile, &req);
+ if (!ret) {
+ ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 0,
+ &req.pr_entry_bh);
+ if (ret < 0)
+ nilfs_palloc_abort_free_entry(ifile, &req);
+ }
+ if (ret < 0) {
+ brelse(req.pr_entry_bh);
+ return ret;
+ }
+
+ kaddr = kmap_atomic(req.pr_entry_bh->b_page, KM_USER0);
+ raw_inode = nilfs_palloc_block_get_entry(ifile, req.pr_entry_nr,
+ req.pr_entry_bh, kaddr);
+ raw_inode->i_flags = 0;
+ kunmap_atomic(kaddr, KM_USER0);
+
+ nilfs_mdt_mark_buffer_dirty(req.pr_entry_bh);
+ brelse(req.pr_entry_bh);
+
+ nilfs_palloc_commit_free_entry(ifile, &req);
+
+ return 0;
+}
+
+int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino,
+ struct buffer_head **out_bh)
+{
+ struct super_block *sb = ifile->i_sb;
+ int err;
+
+ if (unlikely(!NILFS_VALID_INODE(sb, ino))) {
+ nilfs_error(sb, __func__, "bad inode number: %lu",
+ (unsigned long) ino);
+ return -EINVAL;
+ }
+
+ err = nilfs_palloc_get_entry_block(ifile, ino, 0, out_bh);
+ if (unlikely(err)) {
+ if (err == -EINVAL)
+ nilfs_error(sb, __func__, "ifile is broken");
+ else
+ nilfs_warning(sb, __func__,
+ "unable to read inode: %lu",
+ (unsigned long) ino);
+ }
+ return err;
+}
diff --git a/fs/nilfs2/ifile.h b/fs/nilfs2/ifile.h
new file mode 100644
index 00000000000..5d30a35679b
--- /dev/null
+++ b/fs/nilfs2/ifile.h
@@ -0,0 +1,53 @@
+/*
+ * ifile.h - NILFS inode file
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Amagai Yoshiji <amagai@osrg.net>
+ * Revised by Ryusuke Konishi <ryusuke@osrg.net>
+ *
+ */
+
+#ifndef _NILFS_IFILE_H
+#define _NILFS_IFILE_H
+
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/nilfs2_fs.h>
+#include "mdt.h"
+#include "alloc.h"
+
+#define NILFS_IFILE_GFP NILFS_MDT_GFP
+
+static inline struct nilfs_inode *
+nilfs_ifile_map_inode(struct inode *ifile, ino_t ino, struct buffer_head *ibh)
+{
+ void *kaddr = kmap(ibh->b_page);
+ return nilfs_palloc_block_get_entry(ifile, ino, ibh, kaddr);
+}
+
+static inline void nilfs_ifile_unmap_inode(struct inode *ifile, ino_t ino,
+ struct buffer_head *ibh)
+{
+ kunmap(ibh->b_page);
+}
+
+int nilfs_ifile_create_inode(struct inode *, ino_t *, struct buffer_head **);
+int nilfs_ifile_delete_inode(struct inode *, ino_t);
+int nilfs_ifile_get_inode_block(struct inode *, ino_t, struct buffer_head **);
+
+#endif /* _NILFS_IFILE_H */
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
new file mode 100644
index 00000000000..49ab4a49bb4
--- /dev/null
+++ b/fs/nilfs2/inode.c
@@ -0,0 +1,785 @@
+/*
+ * inode.c - NILFS inode operations.
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>
+ *
+ */
+
+#include <linux/buffer_head.h>
+#include <linux/mpage.h>
+#include <linux/writeback.h>
+#include <linux/uio.h>
+#include "nilfs.h"
+#include "segment.h"
+#include "page.h"
+#include "mdt.h"
+#include "cpfile.h"
+#include "ifile.h"
+
+
+/**
+ * nilfs_get_block() - get a file block on the filesystem (callback function)
+ * @inode - inode struct of the target file
+ * @blkoff - file block number
+ * @bh_result - buffer head to be mapped on
+ * @create - indicate whether allocating the block or not when it has not
+ * been allocated yet.
+ *
+ * This function does not issue actual read request of the specified data
+ * block. It is done by VFS.
+ * Bulk read for direct-io is not supported yet. (should be supported)
+ */
+int nilfs_get_block(struct inode *inode, sector_t blkoff,
+ struct buffer_head *bh_result, int create)
+{
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+ unsigned long blknum = 0;
+ int err = 0, ret;
+ struct inode *dat = nilfs_dat_inode(NILFS_I_NILFS(inode));
+
+ /* This exclusion control is a workaround; should be revised */
+ down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
+ ret = nilfs_bmap_lookup(ii->i_bmap, (unsigned long)blkoff, &blknum);
+ up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
+ if (ret == 0) { /* found */
+ map_bh(bh_result, inode->i_sb, blknum);
+ goto out;
+ }
+ /* data block was not found */
+ if (ret == -ENOENT && create) {
+ struct nilfs_transaction_info ti;
+
+ bh_result->b_blocknr = 0;
+ err = nilfs_transaction_begin(inode->i_sb, &ti, 1);
+ if (unlikely(err))
+ goto out;
+ err = nilfs_bmap_insert(ii->i_bmap, (unsigned long)blkoff,
+ (unsigned long)bh_result);
+ if (unlikely(err != 0)) {
+ if (err == -EEXIST) {
+ /*
+ * The get_block() function could be called
+ * from multiple callers for an inode.
+ * However, the page having this block must
+ * be locked in this case.
+ */
+ printk(KERN_WARNING
+ "nilfs_get_block: a race condition "
+ "while inserting a data block. "
+ "(inode number=%lu, file block "
+ "offset=%llu)\n",
+ inode->i_ino,
+ (unsigned long long)blkoff);
+ err = 0;
+ } else if (err == -EINVAL) {
+ nilfs_error(inode->i_sb, __func__,
+ "broken bmap (inode=%lu)\n",
+ inode->i_ino);
+ err = -EIO;
+ }
+ nilfs_transaction_abort(inode->i_sb);
+ goto out;
+ }
+ nilfs_transaction_commit(inode->i_sb); /* never fails */
+ /* Error handling should be detailed */
+ set_buffer_new(bh_result);
+ map_bh(bh_result, inode->i_sb, 0); /* dbn must be changed
+ to proper value */
+ } else if (ret == -ENOENT) {
+ /* not found is not error (e.g. hole); must return without
+ the mapped state flag. */
+ ;
+ } else {
+ err = ret;
+ }
+
+ out:
+ return err;
+}
+
+/**
+ * nilfs_readpage() - implement readpage() method of nilfs_aops {}
+ * address_space_operations.
+ * @file - file struct of the file to be read
+ * @page - the page to be read
+ */
+static int nilfs_readpage(struct file *file, struct page *page)
+{
+ return mpage_readpage(page, nilfs_get_block);
+}
+
+/**
+ * nilfs_readpages() - implement readpages() method of nilfs_aops {}
+ * address_space_operations.
+ * @file - file struct of the file to be read
+ * @mapping - address_space struct used for reading multiple pages
+ * @pages - the pages to be read
+ * @nr_pages - number of pages to be read
+ */
+static int nilfs_readpages(struct file *file, struct address_space *mapping,
+ struct list_head *pages, unsigned nr_pages)
+{
+ return mpage_readpages(mapping, pages, nr_pages, nilfs_get_block);
+}
+
+static int nilfs_writepages(struct address_space *mapping,
+ struct writeback_control *wbc)
+{
+ struct inode *inode = mapping->host;
+ int err = 0;
+
+ if (wbc->sync_mode == WB_SYNC_ALL)
+ err = nilfs_construct_dsync_segment(inode->i_sb, inode,
+ wbc->range_start,
+ wbc->range_end);
+ return err;
+}
+
+static int nilfs_writepage(struct page *page, struct writeback_control *wbc)
+{
+ struct inode *inode = page->mapping->host;
+ int err;
+
+ redirty_page_for_writepage(wbc, page);
+ unlock_page(page);
+
+ if (wbc->sync_mode == WB_SYNC_ALL) {
+ err = nilfs_construct_segment(inode->i_sb);
+ if (unlikely(err))
+ return err;
+ } else if (wbc->for_reclaim)
+ nilfs_flush_segment(inode->i_sb, inode->i_ino);
+
+ return 0;
+}
+
+static int nilfs_set_page_dirty(struct page *page)
+{
+ int ret = __set_page_dirty_buffers(page);
+
+ if (ret) {
+ struct inode *inode = page->mapping->host;
+ struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb);
+ unsigned nr_dirty = 1 << (PAGE_SHIFT - inode->i_blkbits);
+
+ nilfs_set_file_dirty(sbi, inode, nr_dirty);
+ }
+ return ret;
+}
+
+static int nilfs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+
+{
+ struct inode *inode = mapping->host;
+ int err = nilfs_transaction_begin(inode->i_sb, NULL, 1);
+
+ if (unlikely(err))
+ return err;
+
+ *pagep = NULL;
+ err = block_write_begin(file, mapping, pos, len, flags, pagep,
+ fsdata, nilfs_get_block);
+ if (unlikely(err))
+ nilfs_transaction_abort(inode->i_sb);
+ return err;
+}
+
+static int nilfs_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ struct inode *inode = mapping->host;
+ unsigned start = pos & (PAGE_CACHE_SIZE - 1);
+ unsigned nr_dirty;
+ int err;
+
+ nr_dirty = nilfs_page_count_clean_buffers(page, start,
+ start + copied);
+ copied = generic_write_end(file, mapping, pos, len, copied, page,
+ fsdata);
+ nilfs_set_file_dirty(NILFS_SB(inode->i_sb), inode, nr_dirty);
+ err = nilfs_transaction_commit(inode->i_sb);
+ return err ? : copied;
+}
+
+static ssize_t
+nilfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+ loff_t offset, unsigned long nr_segs)
+{
+ struct file *file = iocb->ki_filp;
+ struct inode *inode = file->f_mapping->host;
+ ssize_t size;
+
+ if (rw == WRITE)
+ return 0;
+
+ /* Needs synchronization with the cleaner */
+ size = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+ offset, nr_segs, nilfs_get_block, NULL);
+ return size;
+}
+
+struct address_space_operations nilfs_aops = {
+ .writepage = nilfs_writepage,
+ .readpage = nilfs_readpage,
+ /* .sync_page = nilfs_sync_page, */
+ .writepages = nilfs_writepages,
+ .set_page_dirty = nilfs_set_page_dirty,
+ .readpages = nilfs_readpages,
+ .write_begin = nilfs_write_begin,
+ .write_end = nilfs_write_end,
+ /* .releasepage = nilfs_releasepage, */
+ .invalidatepage = block_invalidatepage,
+ .direct_IO = nilfs_direct_IO,
+};
+
+struct inode *nilfs_new_inode(struct inode *dir, int mode)
+{
+ struct super_block *sb = dir->i_sb;
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ struct inode *inode;
+ struct nilfs_inode_info *ii;
+ int err = -ENOMEM;
+ ino_t ino;
+
+ inode = new_inode(sb);
+ if (unlikely(!inode))
+ goto failed;
+
+ mapping_set_gfp_mask(inode->i_mapping,
+ mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
+
+ ii = NILFS_I(inode);
+ ii->i_state = 1 << NILFS_I_NEW;
+
+ err = nilfs_ifile_create_inode(sbi->s_ifile, &ino, &ii->i_bh);
+ if (unlikely(err))
+ goto failed_ifile_create_inode;
+ /* reference count of i_bh inherits from nilfs_mdt_read_block() */
+
+ atomic_inc(&sbi->s_inodes_count);
+
+ inode->i_uid = current_fsuid();
+ if (dir->i_mode & S_ISGID) {
+ inode->i_gid = dir->i_gid;
+ if (S_ISDIR(mode))
+ mode |= S_ISGID;
+ } else
+ inode->i_gid = current_fsgid();
+
+ inode->i_mode = mode;
+ inode->i_ino = ino;
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+
+ if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) {
+ err = nilfs_bmap_read(ii->i_bmap, NULL);
+ if (err < 0)
+ goto failed_bmap;
+
+ set_bit(NILFS_I_BMAP, &ii->i_state);
+ /* No lock is needed; iget() ensures it. */
+ }
+
+ ii->i_flags = NILFS_I(dir)->i_flags;
+ if (S_ISLNK(mode))
+ ii->i_flags &= ~(NILFS_IMMUTABLE_FL | NILFS_APPEND_FL);
+ if (!S_ISDIR(mode))
+ ii->i_flags &= ~NILFS_DIRSYNC_FL;
+
+ /* ii->i_file_acl = 0; */
+ /* ii->i_dir_acl = 0; */
+ ii->i_dir_start_lookup = 0;
+#ifdef CONFIG_NILFS_FS_POSIX_ACL
+ ii->i_acl = NULL;
+ ii->i_default_acl = NULL;
+#endif
+ ii->i_cno = 0;
+ nilfs_set_inode_flags(inode);
+ spin_lock(&sbi->s_next_gen_lock);
+ inode->i_generation = sbi->s_next_generation++;
+ spin_unlock(&sbi->s_next_gen_lock);
+ insert_inode_hash(inode);
+
+ err = nilfs_init_acl(inode, dir);
+ if (unlikely(err))
+ goto failed_acl; /* never occur. When supporting
+ nilfs_init_acl(), proper cancellation of
+ above jobs should be considered */
+
+ mark_inode_dirty(inode);
+ return inode;
+
+ failed_acl:
+ failed_bmap:
+ inode->i_nlink = 0;
+ iput(inode); /* raw_inode will be deleted through
+ generic_delete_inode() */
+ goto failed;
+
+ failed_ifile_create_inode:
+ make_bad_inode(inode);
+ iput(inode); /* if i_nlink == 1, generic_forget_inode() will be
+ called */
+ failed:
+ return ERR_PTR(err);
+}
+
+void nilfs_free_inode(struct inode *inode)
+{
+ struct super_block *sb = inode->i_sb;
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+
+ clear_inode(inode);
+ /* XXX: check error code? Is there any thing I can do? */
+ (void) nilfs_ifile_delete_inode(sbi->s_ifile, inode->i_ino);
+ atomic_dec(&sbi->s_inodes_count);
+}
+
+void nilfs_set_inode_flags(struct inode *inode)
+{
+ unsigned int flags = NILFS_I(inode)->i_flags;
+
+ inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME |
+ S_DIRSYNC);
+ if (flags & NILFS_SYNC_FL)
+ inode->i_flags |= S_SYNC;
+ if (flags & NILFS_APPEND_FL)
+ inode->i_flags |= S_APPEND;
+ if (flags & NILFS_IMMUTABLE_FL)
+ inode->i_flags |= S_IMMUTABLE;
+#ifndef NILFS_ATIME_DISABLE
+ if (flags & NILFS_NOATIME_FL)
+#endif
+ inode->i_flags |= S_NOATIME;
+ if (flags & NILFS_DIRSYNC_FL)
+ inode->i_flags |= S_DIRSYNC;
+ mapping_set_gfp_mask(inode->i_mapping,
+ mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
+}
+
+int nilfs_read_inode_common(struct inode *inode,
+ struct nilfs_inode *raw_inode)
+{
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+ int err;
+
+ inode->i_mode = le16_to_cpu(raw_inode->i_mode);
+ inode->i_uid = (uid_t)le32_to_cpu(raw_inode->i_uid);
+ inode->i_gid = (gid_t)le32_to_cpu(raw_inode->i_gid);
+ inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
+ inode->i_size = le64_to_cpu(raw_inode->i_size);
+ inode->i_atime.tv_sec = le64_to_cpu(raw_inode->i_mtime);
+ inode->i_ctime.tv_sec = le64_to_cpu(raw_inode->i_ctime);
+ inode->i_mtime.tv_sec = le64_to_cpu(raw_inode->i_mtime);
+ inode->i_atime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec);
+ inode->i_ctime.tv_nsec = le32_to_cpu(raw_inode->i_ctime_nsec);
+ inode->i_mtime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec);
+ if (inode->i_nlink == 0 && inode->i_mode == 0)
+ return -EINVAL; /* this inode is deleted */
+
+ inode->i_blocks = le64_to_cpu(raw_inode->i_blocks);
+ ii->i_flags = le32_to_cpu(raw_inode->i_flags);
+#if 0
+ ii->i_file_acl = le32_to_cpu(raw_inode->i_file_acl);
+ ii->i_dir_acl = S_ISREG(inode->i_mode) ?
+ 0 : le32_to_cpu(raw_inode->i_dir_acl);
+#endif
+ ii->i_cno = 0;
+ inode->i_generation = le32_to_cpu(raw_inode->i_generation);
+
+ if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+ S_ISLNK(inode->i_mode)) {
+ err = nilfs_bmap_read(ii->i_bmap, raw_inode);
+ if (err < 0)
+ return err;
+ set_bit(NILFS_I_BMAP, &ii->i_state);
+ /* No lock is needed; iget() ensures it. */
+ }
+ return 0;
+}
+
+static int __nilfs_read_inode(struct super_block *sb, unsigned long ino,
+ struct inode *inode)
+{
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ struct inode *dat = nilfs_dat_inode(sbi->s_nilfs);
+ struct buffer_head *bh;
+ struct nilfs_inode *raw_inode;
+ int err;
+
+ down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
+ err = nilfs_ifile_get_inode_block(sbi->s_ifile, ino, &bh);
+ if (unlikely(err))
+ goto bad_inode;
+
+ raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, bh);
+
+#ifdef CONFIG_NILFS_FS_POSIX_ACL
+ ii->i_acl = NILFS_ACL_NOT_CACHED;
+ ii->i_default_acl = NILFS_ACL_NOT_CACHED;
+#endif
+ if (nilfs_read_inode_common(inode, raw_inode))
+ goto failed_unmap;
+
+ if (S_ISREG(inode->i_mode)) {
+ inode->i_op = &nilfs_file_inode_operations;
+ inode->i_fop = &nilfs_file_operations;
+ inode->i_mapping->a_ops = &nilfs_aops;
+ } else if (S_ISDIR(inode->i_mode)) {
+ inode->i_op = &nilfs_dir_inode_operations;
+ inode->i_fop = &nilfs_dir_operations;
+ inode->i_mapping->a_ops = &nilfs_aops;
+ } else if (S_ISLNK(inode->i_mode)) {
+ inode->i_op = &nilfs_symlink_inode_operations;
+ inode->i_mapping->a_ops = &nilfs_aops;
+ } else {
+ inode->i_op = &nilfs_special_inode_operations;
+ init_special_inode(
+ inode, inode->i_mode,
+ new_decode_dev(le64_to_cpu(raw_inode->i_device_code)));
+ }
+ nilfs_ifile_unmap_inode(sbi->s_ifile, ino, bh);
+ brelse(bh);
+ up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
+ nilfs_set_inode_flags(inode);
+ return 0;
+
+ failed_unmap:
+ nilfs_ifile_unmap_inode(sbi->s_ifile, ino, bh);
+ brelse(bh);
+
+ bad_inode:
+ up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
+ return err;
+}
+
+struct inode *nilfs_iget(struct super_block *sb, unsigned long ino)
+{
+ struct inode *inode;
+ int err;
+
+ inode = iget_locked(sb, ino);
+ if (unlikely(!inode))
+ return ERR_PTR(-ENOMEM);
+ if (!(inode->i_state & I_NEW))
+ return inode;
+
+ err = __nilfs_read_inode(sb, ino, inode);
+ if (unlikely(err)) {
+ iget_failed(inode);
+ return ERR_PTR(err);
+ }
+ unlock_new_inode(inode);
+ return inode;
+}
+
+void nilfs_write_inode_common(struct inode *inode,
+ struct nilfs_inode *raw_inode, int has_bmap)
+{
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+
+ raw_inode->i_mode = cpu_to_le16(inode->i_mode);
+ raw_inode->i_uid = cpu_to_le32(inode->i_uid);
+ raw_inode->i_gid = cpu_to_le32(inode->i_gid);
+ raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
+ raw_inode->i_size = cpu_to_le64(inode->i_size);
+ raw_inode->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
+ raw_inode->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec);
+ raw_inode->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
+ raw_inode->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
+ raw_inode->i_blocks = cpu_to_le64(inode->i_blocks);
+
+ raw_inode->i_flags = cpu_to_le32(ii->i_flags);
+ raw_inode->i_generation = cpu_to_le32(inode->i_generation);
+
+ if (has_bmap)
+ nilfs_bmap_write(ii->i_bmap, raw_inode);
+ else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+ raw_inode->i_device_code =
+ cpu_to_le64(new_encode_dev(inode->i_rdev));
+ /* When extending inode, nilfs->ns_inode_size should be checked
+ for substitutions of appended fields */
+}
+
+void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh)
+{
+ ino_t ino = inode->i_ino;
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+ struct super_block *sb = inode->i_sb;
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ struct nilfs_inode *raw_inode;
+
+ raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, ibh);
+
+ /* The buffer is guarded with lock_buffer() by the caller */
+ if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state))
+ memset(raw_inode, 0, NILFS_MDT(sbi->s_ifile)->mi_entry_size);
+ set_bit(NILFS_I_INODE_DIRTY, &ii->i_state);
+
+ nilfs_write_inode_common(inode, raw_inode, 0);
+ /* XXX: call with has_bmap = 0 is a workaround to avoid
+ deadlock of bmap. This delays update of i_bmap to just
+ before writing */
+ nilfs_ifile_unmap_inode(sbi->s_ifile, ino, ibh);
+}
+
+#define NILFS_MAX_TRUNCATE_BLOCKS 16384 /* 64MB for 4KB block */
+
+static void nilfs_truncate_bmap(struct nilfs_inode_info *ii,
+ unsigned long from)
+{
+ unsigned long b;
+ int ret;
+
+ if (!test_bit(NILFS_I_BMAP, &ii->i_state))
+ return;
+ repeat:
+ ret = nilfs_bmap_last_key(ii->i_bmap, &b);
+ if (ret == -ENOENT)
+ return;
+ else if (ret < 0)
+ goto failed;
+
+ if (b < from)
+ return;
+
+ b -= min_t(unsigned long, NILFS_MAX_TRUNCATE_BLOCKS, b - from);
+ ret = nilfs_bmap_truncate(ii->i_bmap, b);
+ nilfs_relax_pressure_in_lock(ii->vfs_inode.i_sb);
+ if (!ret || (ret == -ENOMEM &&
+ nilfs_bmap_truncate(ii->i_bmap, b) == 0))
+ goto repeat;
+
+ failed:
+ if (ret == -EINVAL)
+ nilfs_error(ii->vfs_inode.i_sb, __func__,
+ "bmap is broken (ino=%lu)", ii->vfs_inode.i_ino);
+ else
+ nilfs_warning(ii->vfs_inode.i_sb, __func__,
+ "failed to truncate bmap (ino=%lu, err=%d)",
+ ii->vfs_inode.i_ino, ret);
+}
+
+void nilfs_truncate(struct inode *inode)
+{
+ unsigned long blkoff;
+ unsigned int blocksize;
+ struct nilfs_transaction_info ti;
+ struct super_block *sb = inode->i_sb;
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+
+ if (!test_bit(NILFS_I_BMAP, &ii->i_state))
+ return;
+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ return;
+
+ blocksize = sb->s_blocksize;
+ blkoff = (inode->i_size + blocksize - 1) >> sb->s_blocksize_bits;
+ nilfs_transaction_begin(sb, &ti, 0); /* never fails */
+
+ block_truncate_page(inode->i_mapping, inode->i_size, nilfs_get_block);
+
+ nilfs_truncate_bmap(ii, blkoff);
+
+ inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ if (IS_SYNC(inode))
+ nilfs_set_transaction_flag(NILFS_TI_SYNC);
+
+ nilfs_set_file_dirty(NILFS_SB(sb), inode, 0);
+ nilfs_transaction_commit(sb);
+ /* May construct a logical segment and may fail in sync mode.
+ But truncate has no return value. */
+}
+
+void nilfs_delete_inode(struct inode *inode)
+{
+ struct nilfs_transaction_info ti;
+ struct super_block *sb = inode->i_sb;
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+
+ if (unlikely(is_bad_inode(inode))) {
+ if (inode->i_data.nrpages)
+ truncate_inode_pages(&inode->i_data, 0);
+ clear_inode(inode);
+ return;
+ }
+ nilfs_transaction_begin(sb, &ti, 0); /* never fails */
+
+ if (inode->i_data.nrpages)
+ truncate_inode_pages(&inode->i_data, 0);
+
+ nilfs_truncate_bmap(ii, 0);
+ nilfs_free_inode(inode);
+ /* nilfs_free_inode() marks inode buffer dirty */
+ if (IS_SYNC(inode))
+ nilfs_set_transaction_flag(NILFS_TI_SYNC);
+ nilfs_transaction_commit(sb);
+ /* May construct a logical segment and may fail in sync mode.
+ But delete_inode has no return value. */
+}
+
+int nilfs_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+ struct nilfs_transaction_info ti;
+ struct inode *inode = dentry->d_inode;
+ struct super_block *sb = inode->i_sb;
+ int err;
+
+ err = inode_change_ok(inode, iattr);
+ if (err)
+ return err;
+
+ err = nilfs_transaction_begin(sb, &ti, 0);
+ if (unlikely(err))
+ return err;
+ err = inode_setattr(inode, iattr);
+ if (!err && (iattr->ia_valid & ATTR_MODE))
+ err = nilfs_acl_chmod(inode);
+ if (likely(!err))
+ err = nilfs_transaction_commit(sb);
+ else
+ nilfs_transaction_abort(sb);
+
+ return err;
+}
+
+int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode,
+ struct buffer_head **pbh)
+{
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+ int err;
+
+ spin_lock(&sbi->s_inode_lock);
+ /* Caller of this function MUST lock s_inode_lock */
+ if (ii->i_bh == NULL) {
+ spin_unlock(&sbi->s_inode_lock);
+ err = nilfs_ifile_get_inode_block(sbi->s_ifile, inode->i_ino,
+ pbh);
+ if (unlikely(err))
+ return err;
+ spin_lock(&sbi->s_inode_lock);
+ if (ii->i_bh == NULL)
+ ii->i_bh = *pbh;
+ else {
+ brelse(*pbh);
+ *pbh = ii->i_bh;
+ }
+ } else
+ *pbh = ii->i_bh;
+
+ get_bh(*pbh);
+ spin_unlock(&sbi->s_inode_lock);
+ return 0;
+}
+
+int nilfs_inode_dirty(struct inode *inode)
+{
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+ struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb);
+ int ret = 0;
+
+ if (!list_empty(&ii->i_dirty)) {
+ spin_lock(&sbi->s_inode_lock);
+ ret = test_bit(NILFS_I_DIRTY, &ii->i_state) ||
+ test_bit(NILFS_I_BUSY, &ii->i_state);
+ spin_unlock(&sbi->s_inode_lock);
+ }
+ return ret;
+}
+
+int nilfs_set_file_dirty(struct nilfs_sb_info *sbi, struct inode *inode,
+ unsigned nr_dirty)
+{
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+
+ atomic_add(nr_dirty, &sbi->s_nilfs->ns_ndirtyblks);
+
+ if (test_and_set_bit(NILFS_I_DIRTY, &ii->i_state))
+ return 0;
+
+ spin_lock(&sbi->s_inode_lock);
+ if (!test_bit(NILFS_I_QUEUED, &ii->i_state) &&
+ !test_bit(NILFS_I_BUSY, &ii->i_state)) {
+ /* Because this routine may race with nilfs_dispose_list(),
+ we have to check NILFS_I_QUEUED here, too. */
+ if (list_empty(&ii->i_dirty) && igrab(inode) == NULL) {
+ /* This will happen when somebody is freeing
+ this inode. */
+ nilfs_warning(sbi->s_super, __func__,
+ "cannot get inode (ino=%lu)\n",
+ inode->i_ino);
+ spin_unlock(&sbi->s_inode_lock);
+ return -EINVAL; /* NILFS_I_DIRTY may remain for
+ freeing inode */
+ }
+ list_del(&ii->i_dirty);
+ list_add_tail(&ii->i_dirty, &sbi->s_dirty_files);
+ set_bit(NILFS_I_QUEUED, &ii->i_state);
+ }
+ spin_unlock(&sbi->s_inode_lock);
+ return 0;
+}
+
+int nilfs_mark_inode_dirty(struct inode *inode)
+{
+ struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb);
+ struct buffer_head *ibh;
+ int err;
+
+ err = nilfs_load_inode_block(sbi, inode, &ibh);
+ if (unlikely(err)) {
+ nilfs_warning(inode->i_sb, __func__,
+ "failed to reget inode block.\n");
+ return err;
+ }
+ lock_buffer(ibh);
+ nilfs_update_inode(inode, ibh);
+ unlock_buffer(ibh);
+ nilfs_mdt_mark_buffer_dirty(ibh);
+ nilfs_mdt_mark_dirty(sbi->s_ifile);
+ brelse(ibh);
+ return 0;
+}
+
+/**
+ * nilfs_dirty_inode - reflect changes on given inode to an inode block.
+ * @inode: inode of the file to be registered.
+ *
+ * nilfs_dirty_inode() loads a inode block containing the specified
+ * @inode and copies data from a nilfs_inode to a corresponding inode
+ * entry in the inode block. This operation is excluded from the segment
+ * construction. This function can be called both as a single operation
+ * and as a part of indivisible file operations.
+ */
+void nilfs_dirty_inode(struct inode *inode)
+{
+ struct nilfs_transaction_info ti;
+
+ if (is_bad_inode(inode)) {
+ nilfs_warning(inode->i_sb, __func__,
+ "tried to mark bad_inode dirty. ignored.\n");
+ dump_stack();
+ return;
+ }
+ nilfs_transaction_begin(inode->i_sb, &ti, 0);
+ nilfs_mark_inode_dirty(inode);
+ nilfs_transaction_commit(inode->i_sb); /* never fails */
+}
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
new file mode 100644
index 00000000000..108d281ebca
--- /dev/null
+++ b/fs/nilfs2/ioctl.c
@@ -0,0 +1,654 @@
+/*
+ * ioctl.c - NILFS ioctl operations.
+ *
+ * Copyright (C) 2007, 2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#include <linux/fs.h>
+#include <linux/wait.h>
+#include <linux/smp_lock.h> /* lock_kernel(), unlock_kernel() */
+#include <linux/capability.h> /* capable() */
+#include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */
+#include <linux/nilfs2_fs.h>
+#include "nilfs.h"
+#include "segment.h"
+#include "bmap.h"
+#include "cpfile.h"
+#include "sufile.h"
+#include "dat.h"
+
+
+static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv, int dir,
+ ssize_t (*dofunc)(struct the_nilfs *,
+ __u64 *, int,
+ void *, size_t, size_t))
+{
+ void *buf;
+ void __user *base = (void __user *)(unsigned long)argv->v_base;
+ size_t maxmembs, total, n;
+ ssize_t nr;
+ int ret, i;
+ __u64 pos, ppos;
+
+ if (argv->v_nmembs == 0)
+ return 0;
+
+ if (argv->v_size > PAGE_SIZE)
+ return -EINVAL;
+
+ buf = (void *)__get_free_pages(GFP_NOFS, 0);
+ if (unlikely(!buf))
+ return -ENOMEM;
+ maxmembs = PAGE_SIZE / argv->v_size;
+
+ ret = 0;
+ total = 0;
+ pos = argv->v_index;
+ for (i = 0; i < argv->v_nmembs; i += n) {
+ n = (argv->v_nmembs - i < maxmembs) ?
+ argv->v_nmembs - i : maxmembs;
+ if ((dir & _IOC_WRITE) &&
+ copy_from_user(buf, base + argv->v_size * i,
+ argv->v_size * n)) {
+ ret = -EFAULT;
+ break;
+ }
+ ppos = pos;
+ nr = dofunc(nilfs, &pos, argv->v_flags, buf, argv->v_size,
+ n);
+ if (nr < 0) {
+ ret = nr;
+ break;
+ }
+ if ((dir & _IOC_READ) &&
+ copy_to_user(base + argv->v_size * i, buf,
+ argv->v_size * nr)) {
+ ret = -EFAULT;
+ break;
+ }
+ total += nr;
+ if ((size_t)nr < n)
+ break;
+ if (pos == ppos)
+ pos += n;
+ }
+ argv->v_nmembs = total;
+
+ free_pages((unsigned long)buf, 0);
+ return ret;
+}
+
+static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
+ unsigned int cmd, void __user *argp)
+{
+ struct inode *cpfile = NILFS_SB(inode->i_sb)->s_nilfs->ns_cpfile;
+ struct nilfs_transaction_info ti;
+ struct nilfs_cpmode cpmode;
+ int ret;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (copy_from_user(&cpmode, argp, sizeof(cpmode)))
+ return -EFAULT;
+
+ nilfs_transaction_begin(inode->i_sb, &ti, 0);
+ ret = nilfs_cpfile_change_cpmode(
+ cpfile, cpmode.cm_cno, cpmode.cm_mode);
+ if (unlikely(ret < 0)) {
+ nilfs_transaction_abort(inode->i_sb);
+ return ret;
+ }
+ nilfs_transaction_commit(inode->i_sb); /* never fails */
+ return ret;
+}
+
+static int
+nilfs_ioctl_delete_checkpoint(struct inode *inode, struct file *filp,
+ unsigned int cmd, void __user *argp)
+{
+ struct inode *cpfile = NILFS_SB(inode->i_sb)->s_nilfs->ns_cpfile;
+ struct nilfs_transaction_info ti;
+ __u64 cno;
+ int ret;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (copy_from_user(&cno, argp, sizeof(cno)))
+ return -EFAULT;
+
+ nilfs_transaction_begin(inode->i_sb, &ti, 0);
+ ret = nilfs_cpfile_delete_checkpoint(cpfile, cno);
+ if (unlikely(ret < 0)) {
+ nilfs_transaction_abort(inode->i_sb);
+ return ret;
+ }
+ nilfs_transaction_commit(inode->i_sb); /* never fails */
+ return ret;
+}
+
+static ssize_t
+nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
+ void *buf, size_t size, size_t nmembs)
+{
+ return nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
+ nmembs);
+}
+
+static int nilfs_ioctl_get_cpinfo(struct inode *inode, struct file *filp,
+ unsigned int cmd, void __user *argp)
+{
+ struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
+ struct nilfs_argv argv;
+ int ret;
+
+ if (copy_from_user(&argv, argp, sizeof(argv)))
+ return -EFAULT;
+
+ down_read(&nilfs->ns_segctor_sem);
+ ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
+ nilfs_ioctl_do_get_cpinfo);
+ up_read(&nilfs->ns_segctor_sem);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user(argp, &argv, sizeof(argv)))
+ ret = -EFAULT;
+ return ret;
+}
+
+static int nilfs_ioctl_get_cpstat(struct inode *inode, struct file *filp,
+ unsigned int cmd, void __user *argp)
+{
+ struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
+ struct nilfs_cpstat cpstat;
+ int ret;
+
+ down_read(&nilfs->ns_segctor_sem);
+ ret = nilfs_cpfile_get_stat(nilfs->ns_cpfile, &cpstat);
+ up_read(&nilfs->ns_segctor_sem);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user(argp, &cpstat, sizeof(cpstat)))
+ ret = -EFAULT;
+ return ret;
+}
+
+static ssize_t
+nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
+ void *buf, size_t size, size_t nmembs)
+{
+ return nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, nmembs);
+}
+
+static int nilfs_ioctl_get_suinfo(struct inode *inode, struct file *filp,
+ unsigned int cmd, void __user *argp)
+{
+ struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
+ struct nilfs_argv argv;
+ int ret;
+
+ if (copy_from_user(&argv, argp, sizeof(argv)))
+ return -EFAULT;
+
+ down_read(&nilfs->ns_segctor_sem);
+ ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
+ nilfs_ioctl_do_get_suinfo);
+ up_read(&nilfs->ns_segctor_sem);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user(argp, &argv, sizeof(argv)))
+ ret = -EFAULT;
+ return ret;
+}
+
+static int nilfs_ioctl_get_sustat(struct inode *inode, struct file *filp,
+ unsigned int cmd, void __user *argp)
+{
+ struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
+ struct nilfs_sustat sustat;
+ int ret;
+
+ down_read(&nilfs->ns_segctor_sem);
+ ret = nilfs_sufile_get_stat(nilfs->ns_sufile, &sustat);
+ up_read(&nilfs->ns_segctor_sem);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user(argp, &sustat, sizeof(sustat)))
+ ret = -EFAULT;
+ return ret;
+}
+
+static ssize_t
+nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
+ void *buf, size_t size, size_t nmembs)
+{
+ return nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, nmembs);
+}
+
+static int nilfs_ioctl_get_vinfo(struct inode *inode, struct file *filp,
+ unsigned int cmd, void __user *argp)
+{
+ struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
+ struct nilfs_argv argv;
+ int ret;
+
+ if (copy_from_user(&argv, argp, sizeof(argv)))
+ return -EFAULT;
+
+ down_read(&nilfs->ns_segctor_sem);
+ ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
+ nilfs_ioctl_do_get_vinfo);
+ up_read(&nilfs->ns_segctor_sem);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user(argp, &argv, sizeof(argv)))
+ ret = -EFAULT;
+ return ret;
+}
+
+static ssize_t
+nilfs_ioctl_do_get_bdescs(struct the_nilfs *nilfs, __u64 *posp, int flags,
+ void *buf, size_t size, size_t nmembs)
+{
+ struct inode *dat = nilfs_dat_inode(nilfs);
+ struct nilfs_bmap *bmap = NILFS_I(dat)->i_bmap;
+ struct nilfs_bdesc *bdescs = buf;
+ int ret, i;
+
+ for (i = 0; i < nmembs; i++) {
+ ret = nilfs_bmap_lookup_at_level(bmap,
+ bdescs[i].bd_offset,
+ bdescs[i].bd_level + 1,
+ &bdescs[i].bd_blocknr);
+ if (ret < 0) {
+ if (ret != -ENOENT)
+ return ret;
+ bdescs[i].bd_blocknr = 0;
+ }
+ }
+ return nmembs;
+}
+
+static int nilfs_ioctl_get_bdescs(struct inode *inode, struct file *filp,
+ unsigned int cmd, void __user *argp)
+{
+ struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
+ struct nilfs_argv argv;
+ int ret;
+
+ if (copy_from_user(&argv, argp, sizeof(argv)))
+ return -EFAULT;
+
+ down_read(&nilfs->ns_segctor_sem);
+ ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
+ nilfs_ioctl_do_get_bdescs);
+ up_read(&nilfs->ns_segctor_sem);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user(argp, &argv, sizeof(argv)))
+ ret = -EFAULT;
+ return ret;
+}
+
+static int nilfs_ioctl_move_inode_block(struct inode *inode,
+ struct nilfs_vdesc *vdesc,
+ struct list_head *buffers)
+{
+ struct buffer_head *bh;
+ int ret;
+
+ if (vdesc->vd_flags == 0)
+ ret = nilfs_gccache_submit_read_data(
+ inode, vdesc->vd_offset, vdesc->vd_blocknr,
+ vdesc->vd_vblocknr, &bh);
+ else
+ ret = nilfs_gccache_submit_read_node(
+ inode, vdesc->vd_blocknr, vdesc->vd_vblocknr, &bh);
+
+ if (unlikely(ret < 0)) {
+ if (ret == -ENOENT)
+ printk(KERN_CRIT
+ "%s: invalid virtual block address (%s): "
+ "ino=%llu, cno=%llu, offset=%llu, "
+ "blocknr=%llu, vblocknr=%llu\n",
+ __func__, vdesc->vd_flags ? "node" : "data",
+ (unsigned long long)vdesc->vd_ino,
+ (unsigned long long)vdesc->vd_cno,
+ (unsigned long long)vdesc->vd_offset,
+ (unsigned long long)vdesc->vd_blocknr,
+ (unsigned long long)vdesc->vd_vblocknr);
+ return ret;
+ }
+ bh->b_private = vdesc;
+ list_add_tail(&bh->b_assoc_buffers, buffers);
+ return 0;
+}
+
+static ssize_t
+nilfs_ioctl_do_move_blocks(struct the_nilfs *nilfs, __u64 *posp, int flags,
+ void *buf, size_t size, size_t nmembs)
+{
+ struct inode *inode;
+ struct nilfs_vdesc *vdesc;
+ struct buffer_head *bh, *n;
+ LIST_HEAD(buffers);
+ ino_t ino;
+ __u64 cno;
+ int i, ret;
+
+ for (i = 0, vdesc = buf; i < nmembs; ) {
+ ino = vdesc->vd_ino;
+ cno = vdesc->vd_cno;
+ inode = nilfs_gc_iget(nilfs, ino, cno);
+ if (unlikely(inode == NULL)) {
+ ret = -ENOMEM;
+ goto failed;
+ }
+ do {
+ ret = nilfs_ioctl_move_inode_block(inode, vdesc,
+ &buffers);
+ if (unlikely(ret < 0))
+ goto failed;
+ vdesc++;
+ } while (++i < nmembs &&
+ vdesc->vd_ino == ino && vdesc->vd_cno == cno);
+ }
+
+ list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
+ ret = nilfs_gccache_wait_and_mark_dirty(bh);
+ if (unlikely(ret < 0)) {
+ if (ret == -EEXIST) {
+ vdesc = bh->b_private;
+ printk(KERN_CRIT
+ "%s: conflicting %s buffer: "
+ "ino=%llu, cno=%llu, offset=%llu, "
+ "blocknr=%llu, vblocknr=%llu\n",
+ __func__,
+ vdesc->vd_flags ? "node" : "data",
+ (unsigned long long)vdesc->vd_ino,
+ (unsigned long long)vdesc->vd_cno,
+ (unsigned long long)vdesc->vd_offset,
+ (unsigned long long)vdesc->vd_blocknr,
+ (unsigned long long)vdesc->vd_vblocknr);
+ }
+ goto failed;
+ }
+ list_del_init(&bh->b_assoc_buffers);
+ bh->b_private = NULL;
+ brelse(bh);
+ }
+ return nmembs;
+
+ failed:
+ list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
+ list_del_init(&bh->b_assoc_buffers);
+ bh->b_private = NULL;
+ brelse(bh);
+ }
+ return ret;
+}
+
+static inline int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv,
+ int dir)
+{
+ return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
+ nilfs_ioctl_do_move_blocks);
+}
+
+static ssize_t
+nilfs_ioctl_do_delete_checkpoints(struct the_nilfs *nilfs, __u64 *posp,
+ int flags, void *buf, size_t size,
+ size_t nmembs)
+{
+ struct inode *cpfile = nilfs->ns_cpfile;
+ struct nilfs_period *periods = buf;
+ int ret, i;
+
+ for (i = 0; i < nmembs; i++) {
+ ret = nilfs_cpfile_delete_checkpoints(
+ cpfile, periods[i].p_start, periods[i].p_end);
+ if (ret < 0)
+ return ret;
+ }
+ return nmembs;
+}
+
+static inline int nilfs_ioctl_delete_checkpoints(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv,
+ int dir)
+{
+ return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
+ nilfs_ioctl_do_delete_checkpoints);
+}
+
+static ssize_t
+nilfs_ioctl_do_free_vblocknrs(struct the_nilfs *nilfs, __u64 *posp, int flags,
+ void *buf, size_t size, size_t nmembs)
+{
+ int ret = nilfs_dat_freev(nilfs_dat_inode(nilfs), buf, nmembs);
+
+ return (ret < 0) ? ret : nmembs;
+}
+
+static inline int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv,
+ int dir)
+{
+ return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
+ nilfs_ioctl_do_free_vblocknrs);
+}
+
+static ssize_t
+nilfs_ioctl_do_mark_blocks_dirty(struct the_nilfs *nilfs, __u64 *posp,
+ int flags, void *buf, size_t size,
+ size_t nmembs)
+{
+ struct inode *dat = nilfs_dat_inode(nilfs);
+ struct nilfs_bmap *bmap = NILFS_I(dat)->i_bmap;
+ struct nilfs_bdesc *bdescs = buf;
+ int ret, i;
+
+ for (i = 0; i < nmembs; i++) {
+ /* XXX: use macro or inline func to check liveness */
+ ret = nilfs_bmap_lookup_at_level(bmap,
+ bdescs[i].bd_offset,
+ bdescs[i].bd_level + 1,
+ &bdescs[i].bd_blocknr);
+ if (ret < 0) {
+ if (ret != -ENOENT)
+ return ret;
+ bdescs[i].bd_blocknr = 0;
+ }
+ if (bdescs[i].bd_blocknr != bdescs[i].bd_oblocknr)
+ /* skip dead block */
+ continue;
+ if (bdescs[i].bd_level == 0) {
+ ret = nilfs_mdt_mark_block_dirty(dat,
+ bdescs[i].bd_offset);
+ if (ret < 0) {
+ WARN_ON(ret == -ENOENT);
+ return ret;
+ }
+ } else {
+ ret = nilfs_bmap_mark(bmap, bdescs[i].bd_offset,
+ bdescs[i].bd_level);
+ if (ret < 0) {
+ WARN_ON(ret == -ENOENT);
+ return ret;
+ }
+ }
+ }
+ return nmembs;
+}
+
+static inline int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv,
+ int dir)
+{
+ return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
+ nilfs_ioctl_do_mark_blocks_dirty);
+}
+
+static ssize_t
+nilfs_ioctl_do_free_segments(struct the_nilfs *nilfs, __u64 *posp, int flags,
+ void *buf, size_t size, size_t nmembs)
+{
+ struct nilfs_sb_info *sbi = nilfs_get_writer(nilfs);
+ int ret;
+
+ if (unlikely(!sbi))
+ return -EROFS;
+ ret = nilfs_segctor_add_segments_to_be_freed(
+ NILFS_SC(sbi), buf, nmembs);
+ nilfs_put_writer(nilfs);
+
+ return (ret < 0) ? ret : nmembs;
+}
+
+static inline int nilfs_ioctl_free_segments(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv,
+ int dir)
+{
+ return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
+ nilfs_ioctl_do_free_segments);
+}
+
+int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
+ void __user *argp)
+{
+ struct nilfs_argv argv[5];
+ const char *msg;
+ int dir, ret;
+
+ if (copy_from_user(argv, argp, sizeof(argv)))
+ return -EFAULT;
+
+ dir = _IOC_WRITE;
+ ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], dir);
+ if (ret < 0) {
+ msg = "cannot read source blocks";
+ goto failed;
+ }
+ ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], dir);
+ if (ret < 0) {
+ /*
+ * can safely abort because checkpoints can be removed
+ * independently.
+ */
+ msg = "cannot delete checkpoints";
+ goto failed;
+ }
+ ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], dir);
+ if (ret < 0) {
+ /*
+ * can safely abort because DAT file is updated atomically
+ * using a copy-on-write technique.
+ */
+ msg = "cannot delete virtual blocks from DAT file";
+ goto failed;
+ }
+ ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], dir);
+ if (ret < 0) {
+ /*
+ * can safely abort because the operation is nondestructive.
+ */
+ msg = "cannot mark copying blocks dirty";
+ goto failed;
+ }
+ ret = nilfs_ioctl_free_segments(nilfs, &argv[4], dir);
+ if (ret < 0) {
+ /*
+ * can safely abort because this operation is atomic.
+ */
+ msg = "cannot set segments to be freed";
+ goto failed;
+ }
+ return 0;
+
+ failed:
+ nilfs_remove_all_gcinode(nilfs);
+ printk(KERN_ERR "NILFS: GC failed during preparation: %s: err=%d\n",
+ msg, ret);
+ return ret;
+}
+
+static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
+ unsigned int cmd, void __user *argp)
+{
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ return nilfs_clean_segments(inode->i_sb, argp);
+}
+
+static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
+ unsigned int cmd, void __user *argp)
+{
+ __u64 cno;
+ int ret;
+
+ ret = nilfs_construct_segment(inode->i_sb);
+ if (ret < 0)
+ return ret;
+
+ if (argp != NULL) {
+ cno = NILFS_SB(inode->i_sb)->s_nilfs->ns_cno - 1;
+ if (copy_to_user(argp, &cno, sizeof(cno)))
+ return -EFAULT;
+ }
+ return 0;
+}
+
+long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ struct inode *inode = filp->f_dentry->d_inode;
+ void __user *argp = (void * __user *)arg;
+
+ switch (cmd) {
+ case NILFS_IOCTL_CHANGE_CPMODE:
+ return nilfs_ioctl_change_cpmode(inode, filp, cmd, argp);
+ case NILFS_IOCTL_DELETE_CHECKPOINT:
+ return nilfs_ioctl_delete_checkpoint(inode, filp, cmd, argp);
+ case NILFS_IOCTL_GET_CPINFO:
+ return nilfs_ioctl_get_cpinfo(inode, filp, cmd, argp);
+ case NILFS_IOCTL_GET_CPSTAT:
+ return nilfs_ioctl_get_cpstat(inode, filp, cmd, argp);
+ case NILFS_IOCTL_GET_SUINFO:
+ return nilfs_ioctl_get_suinfo(inode, filp, cmd, argp);
+ case NILFS_IOCTL_GET_SUSTAT:
+ return nilfs_ioctl_get_sustat(inode, filp, cmd, argp);
+ case NILFS_IOCTL_GET_VINFO:
+ /* XXX: rename to ??? */
+ return nilfs_ioctl_get_vinfo(inode, filp, cmd, argp);
+ case NILFS_IOCTL_GET_BDESCS:
+ return nilfs_ioctl_get_bdescs(inode, filp, cmd, argp);
+ case NILFS_IOCTL_CLEAN_SEGMENTS:
+ return nilfs_ioctl_clean_segments(inode, filp, cmd, argp);
+ case NILFS_IOCTL_SYNC:
+ return nilfs_ioctl_sync(inode, filp, cmd, argp);
+ default:
+ return -ENOTTY;
+ }
+}
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
new file mode 100644
index 00000000000..47dd815433f
--- /dev/null
+++ b/fs/nilfs2/mdt.c
@@ -0,0 +1,563 @@
+/*
+ * mdt.c - meta data file for NILFS
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>
+ */
+
+#include <linux/buffer_head.h>
+#include <linux/mpage.h>
+#include <linux/mm.h>
+#include <linux/writeback.h>
+#include <linux/backing-dev.h>
+#include <linux/swap.h>
+#include "nilfs.h"
+#include "segment.h"
+#include "page.h"
+#include "mdt.h"
+
+
+#define NILFS_MDT_MAX_RA_BLOCKS (16 - 1)
+
+#define INIT_UNUSED_INODE_FIELDS
+
+static int
+nilfs_mdt_insert_new_block(struct inode *inode, unsigned long block,
+ struct buffer_head *bh,
+ void (*init_block)(struct inode *,
+ struct buffer_head *, void *))
+{
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+ void *kaddr;
+ int ret;
+
+ /* Caller exclude read accesses using page lock */
+
+ /* set_buffer_new(bh); */
+ bh->b_blocknr = 0;
+
+ ret = nilfs_bmap_insert(ii->i_bmap, block, (unsigned long)bh);
+ if (unlikely(ret))
+ return ret;
+
+ set_buffer_mapped(bh);
+
+ kaddr = kmap_atomic(bh->b_page, KM_USER0);
+ memset(kaddr + bh_offset(bh), 0, 1 << inode->i_blkbits);
+ if (init_block)
+ init_block(inode, bh, kaddr);
+ flush_dcache_page(bh->b_page);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ set_buffer_uptodate(bh);
+ nilfs_mark_buffer_dirty(bh);
+ nilfs_mdt_mark_dirty(inode);
+ return 0;
+}
+
+static int nilfs_mdt_create_block(struct inode *inode, unsigned long block,
+ struct buffer_head **out_bh,
+ void (*init_block)(struct inode *,
+ struct buffer_head *,
+ void *))
+{
+ struct the_nilfs *nilfs = NILFS_MDT(inode)->mi_nilfs;
+ struct nilfs_sb_info *writer = NULL;
+ struct super_block *sb = inode->i_sb;
+ struct nilfs_transaction_info ti;
+ struct buffer_head *bh;
+ int err;
+
+ if (!sb) {
+ writer = nilfs_get_writer(nilfs);
+ if (!writer) {
+ err = -EROFS;
+ goto out;
+ }
+ sb = writer->s_super;
+ }
+
+ nilfs_transaction_begin(sb, &ti, 0);
+
+ err = -ENOMEM;
+ bh = nilfs_grab_buffer(inode, inode->i_mapping, block, 0);
+ if (unlikely(!bh))
+ goto failed_unlock;
+
+ err = -EEXIST;
+ if (buffer_uptodate(bh) || buffer_mapped(bh))
+ goto failed_bh;
+#if 0
+ /* The uptodate flag is not protected by the page lock, but
+ the mapped flag is. Thus, we don't have to wait the buffer. */
+ wait_on_buffer(bh);
+ if (buffer_uptodate(bh))
+ goto failed_bh;
+#endif
+
+ bh->b_bdev = nilfs->ns_bdev;
+ err = nilfs_mdt_insert_new_block(inode, block, bh, init_block);
+ if (likely(!err)) {
+ get_bh(bh);
+ *out_bh = bh;
+ }
+
+ failed_bh:
+ unlock_page(bh->b_page);
+ page_cache_release(bh->b_page);
+ brelse(bh);
+
+ failed_unlock:
+ if (likely(!err))
+ err = nilfs_transaction_commit(sb);
+ else
+ nilfs_transaction_abort(sb);
+ if (writer)
+ nilfs_put_writer(nilfs);
+ out:
+ return err;
+}
+
+static int
+nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff,
+ int mode, struct buffer_head **out_bh)
+{
+ struct buffer_head *bh;
+ unsigned long blknum = 0;
+ int ret = -ENOMEM;
+
+ bh = nilfs_grab_buffer(inode, inode->i_mapping, blkoff, 0);
+ if (unlikely(!bh))
+ goto failed;
+
+ ret = -EEXIST; /* internal code */
+ if (buffer_uptodate(bh))
+ goto out;
+
+ if (mode == READA) {
+ if (!trylock_buffer(bh)) {
+ ret = -EBUSY;
+ goto failed_bh;
+ }
+ } else /* mode == READ */
+ lock_buffer(bh);
+
+ if (buffer_uptodate(bh)) {
+ unlock_buffer(bh);
+ goto out;
+ }
+ if (!buffer_mapped(bh)) { /* unused buffer */
+ ret = nilfs_bmap_lookup(NILFS_I(inode)->i_bmap, blkoff,
+ &blknum);
+ if (unlikely(ret)) {
+ unlock_buffer(bh);
+ goto failed_bh;
+ }
+ bh->b_bdev = NILFS_MDT(inode)->mi_nilfs->ns_bdev;
+ bh->b_blocknr = blknum;
+ set_buffer_mapped(bh);
+ }
+
+ bh->b_end_io = end_buffer_read_sync;
+ get_bh(bh);
+ submit_bh(mode, bh);
+ ret = 0;
+ out:
+ get_bh(bh);
+ *out_bh = bh;
+
+ failed_bh:
+ unlock_page(bh->b_page);
+ page_cache_release(bh->b_page);
+ brelse(bh);
+ failed:
+ return ret;
+}
+
+static int nilfs_mdt_read_block(struct inode *inode, unsigned long block,
+ struct buffer_head **out_bh)
+{
+ struct buffer_head *first_bh, *bh;
+ unsigned long blkoff;
+ int i, nr_ra_blocks = NILFS_MDT_MAX_RA_BLOCKS;
+ int err;
+
+ err = nilfs_mdt_submit_block(inode, block, READ, &first_bh);
+ if (err == -EEXIST) /* internal code */
+ goto out;
+
+ if (unlikely(err))
+ goto failed;
+
+ blkoff = block + 1;
+ for (i = 0; i < nr_ra_blocks; i++, blkoff++) {
+ err = nilfs_mdt_submit_block(inode, blkoff, READA, &bh);
+ if (likely(!err || err == -EEXIST))
+ brelse(bh);
+ else if (err != -EBUSY)
+ break; /* abort readahead if bmap lookup failed */
+
+ if (!buffer_locked(first_bh))
+ goto out_no_wait;
+ }
+
+ wait_on_buffer(first_bh);
+
+ out_no_wait:
+ err = -EIO;
+ if (!buffer_uptodate(first_bh))
+ goto failed_bh;
+ out:
+ *out_bh = first_bh;
+ return 0;
+
+ failed_bh:
+ brelse(first_bh);
+ failed:
+ return err;
+}
+
+/**
+ * nilfs_mdt_get_block - read or create a buffer on meta data file.
+ * @inode: inode of the meta data file
+ * @blkoff: block offset
+ * @create: create flag
+ * @init_block: initializer used for newly allocated block
+ * @out_bh: output of a pointer to the buffer_head
+ *
+ * nilfs_mdt_get_block() looks up the specified buffer and tries to create
+ * a new buffer if @create is not zero. On success, the returned buffer is
+ * assured to be either existing or formatted using a buffer lock on success.
+ * @out_bh is substituted only when zero is returned.
+ *
+ * Return Value: On success, it returns 0. On error, the following negative
+ * error code is returned.
+ *
+ * %-ENOMEM - Insufficient memory available.
+ *
+ * %-EIO - I/O error
+ *
+ * %-ENOENT - the specified block does not exist (hole block)
+ *
+ * %-EINVAL - bmap is broken. (the caller should call nilfs_error())
+ *
+ * %-EROFS - Read only filesystem (for create mode)
+ */
+int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create,
+ void (*init_block)(struct inode *,
+ struct buffer_head *, void *),
+ struct buffer_head **out_bh)
+{
+ int ret;
+
+ /* Should be rewritten with merging nilfs_mdt_read_block() */
+ retry:
+ ret = nilfs_mdt_read_block(inode, blkoff, out_bh);
+ if (!create || ret != -ENOENT)
+ return ret;
+
+ ret = nilfs_mdt_create_block(inode, blkoff, out_bh, init_block);
+ if (unlikely(ret == -EEXIST)) {
+ /* create = 0; */ /* limit read-create loop retries */
+ goto retry;
+ }
+ return ret;
+}
+
+/**
+ * nilfs_mdt_delete_block - make a hole on the meta data file.
+ * @inode: inode of the meta data file
+ * @block: block offset
+ *
+ * Return Value: On success, zero is returned.
+ * On error, one of the following negative error code is returned.
+ *
+ * %-ENOMEM - Insufficient memory available.
+ *
+ * %-EIO - I/O error
+ *
+ * %-EINVAL - bmap is broken. (the caller should call nilfs_error())
+ */
+int nilfs_mdt_delete_block(struct inode *inode, unsigned long block)
+{
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+ int err;
+
+ err = nilfs_bmap_delete(ii->i_bmap, block);
+ if (likely(!err)) {
+ nilfs_mdt_mark_dirty(inode);
+ nilfs_mdt_forget_block(inode, block);
+ }
+ return err;
+}
+
+/**
+ * nilfs_mdt_forget_block - discard dirty state and try to remove the page
+ * @inode: inode of the meta data file
+ * @block: block offset
+ *
+ * nilfs_mdt_forget_block() clears a dirty flag of the specified buffer, and
+ * tries to release the page including the buffer from a page cache.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error code is returned.
+ *
+ * %-EBUSY - page has an active buffer.
+ *
+ * %-ENOENT - page cache has no page addressed by the offset.
+ */
+int nilfs_mdt_forget_block(struct inode *inode, unsigned long block)
+{
+ pgoff_t index = (pgoff_t)block >>
+ (PAGE_CACHE_SHIFT - inode->i_blkbits);
+ struct page *page;
+ unsigned long first_block;
+ int ret = 0;
+ int still_dirty;
+
+ page = find_lock_page(inode->i_mapping, index);
+ if (!page)
+ return -ENOENT;
+
+ wait_on_page_writeback(page);
+
+ first_block = (unsigned long)index <<
+ (PAGE_CACHE_SHIFT - inode->i_blkbits);
+ if (page_has_buffers(page)) {
+ struct buffer_head *bh;
+
+ bh = nilfs_page_get_nth_block(page, block - first_block);
+ nilfs_forget_buffer(bh);
+ }
+ still_dirty = PageDirty(page);
+ unlock_page(page);
+ page_cache_release(page);
+
+ if (still_dirty ||
+ invalidate_inode_pages2_range(inode->i_mapping, index, index) != 0)
+ ret = -EBUSY;
+ return ret;
+}
+
+/**
+ * nilfs_mdt_mark_block_dirty - mark a block on the meta data file dirty.
+ * @inode: inode of the meta data file
+ * @block: block offset
+ *
+ * Return Value: On success, it returns 0. On error, the following negative
+ * error code is returned.
+ *
+ * %-ENOMEM - Insufficient memory available.
+ *
+ * %-EIO - I/O error
+ *
+ * %-ENOENT - the specified block does not exist (hole block)
+ *
+ * %-EINVAL - bmap is broken. (the caller should call nilfs_error())
+ */
+int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block)
+{
+ struct buffer_head *bh;
+ int err;
+
+ err = nilfs_mdt_read_block(inode, block, &bh);
+ if (unlikely(err))
+ return err;
+ nilfs_mark_buffer_dirty(bh);
+ nilfs_mdt_mark_dirty(inode);
+ brelse(bh);
+ return 0;
+}
+
+int nilfs_mdt_fetch_dirty(struct inode *inode)
+{
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+
+ if (nilfs_bmap_test_and_clear_dirty(ii->i_bmap)) {
+ set_bit(NILFS_I_DIRTY, &ii->i_state);
+ return 1;
+ }
+ return test_bit(NILFS_I_DIRTY, &ii->i_state);
+}
+
+static int
+nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
+{
+ struct inode *inode = container_of(page->mapping,
+ struct inode, i_data);
+ struct super_block *sb = inode->i_sb;
+ struct nilfs_sb_info *writer = NULL;
+ int err = 0;
+
+ redirty_page_for_writepage(wbc, page);
+ unlock_page(page);
+
+ if (page->mapping->assoc_mapping)
+ return 0; /* Do not request flush for shadow page cache */
+ if (!sb) {
+ writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs);
+ if (!writer)
+ return -EROFS;
+ sb = writer->s_super;
+ }
+
+ if (wbc->sync_mode == WB_SYNC_ALL)
+ err = nilfs_construct_segment(sb);
+ else if (wbc->for_reclaim)
+ nilfs_flush_segment(sb, inode->i_ino);
+
+ if (writer)
+ nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs);
+ return err;
+}
+
+
+static struct address_space_operations def_mdt_aops = {
+ .writepage = nilfs_mdt_write_page,
+};
+
+static struct inode_operations def_mdt_iops;
+static struct file_operations def_mdt_fops;
+
+/*
+ * NILFS2 uses pseudo inodes for meta data files such as DAT, cpfile, sufile,
+ * ifile, or gcinodes. This allows the B-tree code and segment constructor
+ * to treat them like regular files, and this helps to simplify the
+ * implementation.
+ * On the other hand, some of the pseudo inodes have an irregular point:
+ * They don't have valid inode->i_sb pointer because their lifetimes are
+ * longer than those of the super block structs; they may continue for
+ * several consecutive mounts/umounts. This would need discussions.
+ */
+struct inode *
+nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
+ ino_t ino, gfp_t gfp_mask)
+{
+ struct inode *inode = nilfs_alloc_inode(sb);
+
+ if (!inode)
+ return NULL;
+ else {
+ struct address_space * const mapping = &inode->i_data;
+ struct nilfs_mdt_info *mi = kzalloc(sizeof(*mi), GFP_NOFS);
+
+ if (!mi) {
+ nilfs_destroy_inode(inode);
+ return NULL;
+ }
+ mi->mi_nilfs = nilfs;
+ init_rwsem(&mi->mi_sem);
+
+ inode->i_sb = sb; /* sb may be NULL for some meta data files */
+ inode->i_blkbits = nilfs->ns_blocksize_bits;
+ inode->i_flags = 0;
+ atomic_set(&inode->i_count, 1);
+ inode->i_nlink = 1;
+ inode->i_ino = ino;
+ inode->i_mode = S_IFREG;
+ inode->i_private = mi;
+
+#ifdef INIT_UNUSED_INODE_FIELDS
+ atomic_set(&inode->i_writecount, 0);
+ inode->i_size = 0;
+ inode->i_blocks = 0;
+ inode->i_bytes = 0;
+ inode->i_generation = 0;
+#ifdef CONFIG_QUOTA
+ memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
+#endif
+ inode->i_pipe = NULL;
+ inode->i_bdev = NULL;
+ inode->i_cdev = NULL;
+ inode->i_rdev = 0;
+#ifdef CONFIG_SECURITY
+ inode->i_security = NULL;
+#endif
+ inode->dirtied_when = 0;
+
+ INIT_LIST_HEAD(&inode->i_list);
+ INIT_LIST_HEAD(&inode->i_sb_list);
+ inode->i_state = 0;
+#endif
+
+ spin_lock_init(&inode->i_lock);
+ mutex_init(&inode->i_mutex);
+ init_rwsem(&inode->i_alloc_sem);
+
+ mapping->host = NULL; /* instead of inode */
+ mapping->flags = 0;
+ mapping_set_gfp_mask(mapping, gfp_mask);
+ mapping->assoc_mapping = NULL;
+ mapping->backing_dev_info = nilfs->ns_bdi;
+
+ inode->i_mapping = mapping;
+ }
+
+ return inode;
+}
+
+struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb,
+ ino_t ino, gfp_t gfp_mask)
+{
+ struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino, gfp_mask);
+
+ if (!inode)
+ return NULL;
+
+ inode->i_op = &def_mdt_iops;
+ inode->i_fop = &def_mdt_fops;
+ inode->i_mapping->a_ops = &def_mdt_aops;
+ return inode;
+}
+
+void nilfs_mdt_set_entry_size(struct inode *inode, unsigned entry_size,
+ unsigned header_size)
+{
+ struct nilfs_mdt_info *mi = NILFS_MDT(inode);
+
+ mi->mi_entry_size = entry_size;
+ mi->mi_entries_per_block = (1 << inode->i_blkbits) / entry_size;
+ mi->mi_first_entry_offset = DIV_ROUND_UP(header_size, entry_size);
+}
+
+void nilfs_mdt_set_shadow(struct inode *orig, struct inode *shadow)
+{
+ shadow->i_mapping->assoc_mapping = orig->i_mapping;
+ NILFS_I(shadow)->i_btnode_cache.assoc_mapping =
+ &NILFS_I(orig)->i_btnode_cache;
+}
+
+void nilfs_mdt_clear(struct inode *inode)
+{
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+
+ invalidate_mapping_pages(inode->i_mapping, 0, -1);
+ truncate_inode_pages(inode->i_mapping, 0);
+
+ nilfs_bmap_clear(ii->i_bmap);
+ nilfs_btnode_cache_clear(&ii->i_btnode_cache);
+}
+
+void nilfs_mdt_destroy(struct inode *inode)
+{
+ struct nilfs_mdt_info *mdi = NILFS_MDT(inode);
+
+ kfree(mdi->mi_bgl); /* kfree(NULL) is safe */
+ kfree(mdi);
+ nilfs_destroy_inode(inode);
+}
diff --git a/fs/nilfs2/mdt.h b/fs/nilfs2/mdt.h
new file mode 100644
index 00000000000..df683e0bca6
--- /dev/null
+++ b/fs/nilfs2/mdt.h
@@ -0,0 +1,125 @@
+/*
+ * mdt.h - NILFS meta data file prototype and definitions
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>
+ */
+
+#ifndef _NILFS_MDT_H
+#define _NILFS_MDT_H
+
+#include <linux/buffer_head.h>
+#include <linux/blockgroup_lock.h>
+#include "nilfs.h"
+#include "page.h"
+
+/**
+ * struct nilfs_mdt_info - on-memory private data of meta data files
+ * @mi_nilfs: back pointer to the_nilfs struct
+ * @mi_sem: reader/writer semaphore for meta data operations
+ * @mi_bgl: per-blockgroup locking
+ * @mi_entry_size: size of an entry
+ * @mi_first_entry_offset: offset to the first entry
+ * @mi_entries_per_block: number of entries in a block
+ * @mi_blocks_per_group: number of blocks in a group
+ * @mi_blocks_per_desc_block: number of blocks per descriptor block
+ */
+struct nilfs_mdt_info {
+ struct the_nilfs *mi_nilfs;
+ struct rw_semaphore mi_sem;
+ struct blockgroup_lock *mi_bgl;
+ unsigned mi_entry_size;
+ unsigned mi_first_entry_offset;
+ unsigned long mi_entries_per_block;
+ unsigned long mi_blocks_per_group;
+ unsigned long mi_blocks_per_desc_block;
+};
+
+static inline struct nilfs_mdt_info *NILFS_MDT(const struct inode *inode)
+{
+ return inode->i_private;
+}
+
+static inline struct the_nilfs *NILFS_I_NILFS(struct inode *inode)
+{
+ struct super_block *sb = inode->i_sb;
+
+ return sb ? NILFS_SB(sb)->s_nilfs : NILFS_MDT(inode)->mi_nilfs;
+}
+
+/* Default GFP flags using highmem */
+#define NILFS_MDT_GFP (__GFP_WAIT | __GFP_IO | __GFP_HIGHMEM)
+
+int nilfs_mdt_get_block(struct inode *, unsigned long, int,
+ void (*init_block)(struct inode *,
+ struct buffer_head *, void *),
+ struct buffer_head **);
+int nilfs_mdt_delete_block(struct inode *, unsigned long);
+int nilfs_mdt_forget_block(struct inode *, unsigned long);
+int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long);
+int nilfs_mdt_fetch_dirty(struct inode *);
+
+struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t,
+ gfp_t);
+struct inode *nilfs_mdt_new_common(struct the_nilfs *, struct super_block *,
+ ino_t, gfp_t);
+void nilfs_mdt_destroy(struct inode *);
+void nilfs_mdt_clear(struct inode *);
+void nilfs_mdt_set_entry_size(struct inode *, unsigned, unsigned);
+void nilfs_mdt_set_shadow(struct inode *, struct inode *);
+
+
+#define nilfs_mdt_mark_buffer_dirty(bh) nilfs_mark_buffer_dirty(bh)
+
+static inline void nilfs_mdt_mark_dirty(struct inode *inode)
+{
+ if (!test_bit(NILFS_I_DIRTY, &NILFS_I(inode)->i_state))
+ set_bit(NILFS_I_DIRTY, &NILFS_I(inode)->i_state);
+}
+
+static inline void nilfs_mdt_clear_dirty(struct inode *inode)
+{
+ clear_bit(NILFS_I_DIRTY, &NILFS_I(inode)->i_state);
+}
+
+static inline __u64 nilfs_mdt_cno(struct inode *inode)
+{
+ return NILFS_MDT(inode)->mi_nilfs->ns_cno;
+}
+
+#define nilfs_mdt_bgl_lock(inode, bg) \
+ (&NILFS_MDT(inode)->mi_bgl->locks[(bg) & (NR_BG_LOCKS-1)].lock)
+
+
+static inline int
+nilfs_mdt_read_inode_direct(struct inode *inode, struct buffer_head *bh,
+ unsigned n)
+{
+ return nilfs_read_inode_common(
+ inode, (struct nilfs_inode *)(bh->b_data + n));
+}
+
+static inline void
+nilfs_mdt_write_inode_direct(struct inode *inode, struct buffer_head *bh,
+ unsigned n)
+{
+ nilfs_write_inode_common(
+ inode, (struct nilfs_inode *)(bh->b_data + n), 1);
+}
+
+#endif /* _NILFS_MDT_H */
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
new file mode 100644
index 00000000000..df70dadb336
--- /dev/null
+++ b/fs/nilfs2/namei.c
@@ -0,0 +1,474 @@
+/*
+ * namei.c - NILFS pathname lookup operations.
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Modified for NILFS by Amagai Yoshiji <amagai@osrg.net>,
+ * Ryusuke Konishi <ryusuke@osrg.net>
+ */
+/*
+ * linux/fs/ext2/namei.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ * from
+ *
+ * linux/fs/minix/namei.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * Big-endian to little-endian byte-swapping/bitmaps by
+ * David S. Miller (davem@caip.rutgers.edu), 1995
+ */
+
+#include <linux/pagemap.h>
+#include "nilfs.h"
+
+
+static inline int nilfs_add_nondir(struct dentry *dentry, struct inode *inode)
+{
+ int err = nilfs_add_link(dentry, inode);
+ if (!err) {
+ d_instantiate(dentry, inode);
+ return 0;
+ }
+ inode_dec_link_count(inode);
+ iput(inode);
+ return err;
+}
+
+/*
+ * Methods themselves.
+ */
+
+static struct dentry *
+nilfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+{
+ struct inode *inode;
+ ino_t ino;
+
+ if (dentry->d_name.len > NILFS_NAME_LEN)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ ino = nilfs_inode_by_name(dir, dentry);
+ inode = NULL;
+ if (ino) {
+ inode = nilfs_iget(dir->i_sb, ino);
+ if (IS_ERR(inode))
+ return ERR_CAST(inode);
+ }
+ return d_splice_alias(inode, dentry);
+}
+
+struct dentry *nilfs_get_parent(struct dentry *child)
+{
+ unsigned long ino;
+ struct inode *inode;
+ struct dentry dotdot;
+
+ dotdot.d_name.name = "..";
+ dotdot.d_name.len = 2;
+
+ ino = nilfs_inode_by_name(child->d_inode, &dotdot);
+ if (!ino)
+ return ERR_PTR(-ENOENT);
+
+ inode = nilfs_iget(child->d_inode->i_sb, ino);
+ if (IS_ERR(inode))
+ return ERR_CAST(inode);
+ return d_obtain_alias(inode);
+}
+
+/*
+ * By the time this is called, we already have created
+ * the directory cache entry for the new file, but it
+ * is so far negative - it has no inode.
+ *
+ * If the create succeeds, we fill in the inode information
+ * with d_instantiate().
+ */
+static int nilfs_create(struct inode *dir, struct dentry *dentry, int mode,
+ struct nameidata *nd)
+{
+ struct inode *inode;
+ struct nilfs_transaction_info ti;
+ int err;
+
+ err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
+ if (err)
+ return err;
+ inode = nilfs_new_inode(dir, mode);
+ err = PTR_ERR(inode);
+ if (!IS_ERR(inode)) {
+ inode->i_op = &nilfs_file_inode_operations;
+ inode->i_fop = &nilfs_file_operations;
+ inode->i_mapping->a_ops = &nilfs_aops;
+ mark_inode_dirty(inode);
+ err = nilfs_add_nondir(dentry, inode);
+ }
+ if (!err)
+ err = nilfs_transaction_commit(dir->i_sb);
+ else
+ nilfs_transaction_abort(dir->i_sb);
+
+ return err;
+}
+
+static int
+nilfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
+{
+ struct inode *inode;
+ struct nilfs_transaction_info ti;
+ int err;
+
+ if (!new_valid_dev(rdev))
+ return -EINVAL;
+
+ err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
+ if (err)
+ return err;
+ inode = nilfs_new_inode(dir, mode);
+ err = PTR_ERR(inode);
+ if (!IS_ERR(inode)) {
+ init_special_inode(inode, inode->i_mode, rdev);
+ mark_inode_dirty(inode);
+ err = nilfs_add_nondir(dentry, inode);
+ }
+ if (!err)
+ err = nilfs_transaction_commit(dir->i_sb);
+ else
+ nilfs_transaction_abort(dir->i_sb);
+
+ return err;
+}
+
+static int nilfs_symlink(struct inode *dir, struct dentry *dentry,
+ const char *symname)
+{
+ struct nilfs_transaction_info ti;
+ struct super_block *sb = dir->i_sb;
+ unsigned l = strlen(symname)+1;
+ struct inode *inode;
+ int err;
+
+ if (l > sb->s_blocksize)
+ return -ENAMETOOLONG;
+
+ err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
+ if (err)
+ return err;
+
+ inode = nilfs_new_inode(dir, S_IFLNK | S_IRWXUGO);
+ err = PTR_ERR(inode);
+ if (IS_ERR(inode))
+ goto out;
+
+ /* slow symlink */
+ inode->i_op = &nilfs_symlink_inode_operations;
+ inode->i_mapping->a_ops = &nilfs_aops;
+ err = page_symlink(inode, symname, l);
+ if (err)
+ goto out_fail;
+
+ /* mark_inode_dirty(inode); */
+ /* nilfs_new_inode() and page_symlink() do this */
+
+ err = nilfs_add_nondir(dentry, inode);
+out:
+ if (!err)
+ err = nilfs_transaction_commit(dir->i_sb);
+ else
+ nilfs_transaction_abort(dir->i_sb);
+
+ return err;
+
+out_fail:
+ inode_dec_link_count(inode);
+ iput(inode);
+ goto out;
+}
+
+static int nilfs_link(struct dentry *old_dentry, struct inode *dir,
+ struct dentry *dentry)
+{
+ struct inode *inode = old_dentry->d_inode;
+ struct nilfs_transaction_info ti;
+ int err;
+
+ if (inode->i_nlink >= NILFS_LINK_MAX)
+ return -EMLINK;
+
+ err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
+ if (err)
+ return err;
+
+ inode->i_ctime = CURRENT_TIME;
+ inode_inc_link_count(inode);
+ atomic_inc(&inode->i_count);
+
+ err = nilfs_add_nondir(dentry, inode);
+ if (!err)
+ err = nilfs_transaction_commit(dir->i_sb);
+ else
+ nilfs_transaction_abort(dir->i_sb);
+
+ return err;
+}
+
+static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ struct inode *inode;
+ struct nilfs_transaction_info ti;
+ int err;
+
+ if (dir->i_nlink >= NILFS_LINK_MAX)
+ return -EMLINK;
+
+ err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
+ if (err)
+ return err;
+
+ inode_inc_link_count(dir);
+
+ inode = nilfs_new_inode(dir, S_IFDIR | mode);
+ err = PTR_ERR(inode);
+ if (IS_ERR(inode))
+ goto out_dir;
+
+ inode->i_op = &nilfs_dir_inode_operations;
+ inode->i_fop = &nilfs_dir_operations;
+ inode->i_mapping->a_ops = &nilfs_aops;
+
+ inode_inc_link_count(inode);
+
+ err = nilfs_make_empty(inode, dir);
+ if (err)
+ goto out_fail;
+
+ err = nilfs_add_link(dentry, inode);
+ if (err)
+ goto out_fail;
+
+ d_instantiate(dentry, inode);
+out:
+ if (!err)
+ err = nilfs_transaction_commit(dir->i_sb);
+ else
+ nilfs_transaction_abort(dir->i_sb);
+
+ return err;
+
+out_fail:
+ inode_dec_link_count(inode);
+ inode_dec_link_count(inode);
+ iput(inode);
+out_dir:
+ inode_dec_link_count(dir);
+ goto out;
+}
+
+static int nilfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+ struct inode *inode;
+ struct nilfs_dir_entry *de;
+ struct page *page;
+ struct nilfs_transaction_info ti;
+ int err;
+
+ err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
+ if (err)
+ return err;
+
+ err = -ENOENT;
+ de = nilfs_find_entry(dir, dentry, &page);
+ if (!de)
+ goto out;
+
+ inode = dentry->d_inode;
+ err = -EIO;
+ if (le64_to_cpu(de->inode) != inode->i_ino)
+ goto out;
+
+ if (!inode->i_nlink) {
+ nilfs_warning(inode->i_sb, __func__,
+ "deleting nonexistent file (%lu), %d\n",
+ inode->i_ino, inode->i_nlink);
+ inode->i_nlink = 1;
+ }
+ err = nilfs_delete_entry(de, page);
+ if (err)
+ goto out;
+
+ inode->i_ctime = dir->i_ctime;
+ inode_dec_link_count(inode);
+ err = 0;
+out:
+ if (!err)
+ err = nilfs_transaction_commit(dir->i_sb);
+ else
+ nilfs_transaction_abort(dir->i_sb);
+
+ return err;
+}
+
+static int nilfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+ struct inode *inode = dentry->d_inode;
+ struct nilfs_transaction_info ti;
+ int err;
+
+ err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
+ if (err)
+ return err;
+
+ err = -ENOTEMPTY;
+ if (nilfs_empty_dir(inode)) {
+ err = nilfs_unlink(dir, dentry);
+ if (!err) {
+ inode->i_size = 0;
+ inode_dec_link_count(inode);
+ inode_dec_link_count(dir);
+ }
+ }
+ if (!err)
+ err = nilfs_transaction_commit(dir->i_sb);
+ else
+ nilfs_transaction_abort(dir->i_sb);
+
+ return err;
+}
+
+static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ struct inode *old_inode = old_dentry->d_inode;
+ struct inode *new_inode = new_dentry->d_inode;
+ struct page *dir_page = NULL;
+ struct nilfs_dir_entry *dir_de = NULL;
+ struct page *old_page;
+ struct nilfs_dir_entry *old_de;
+ struct nilfs_transaction_info ti;
+ int err;
+
+ err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1);
+ if (unlikely(err))
+ return err;
+
+ err = -ENOENT;
+ old_de = nilfs_find_entry(old_dir, old_dentry, &old_page);
+ if (!old_de)
+ goto out;
+
+ if (S_ISDIR(old_inode->i_mode)) {
+ err = -EIO;
+ dir_de = nilfs_dotdot(old_inode, &dir_page);
+ if (!dir_de)
+ goto out_old;
+ }
+
+ if (new_inode) {
+ struct page *new_page;
+ struct nilfs_dir_entry *new_de;
+
+ err = -ENOTEMPTY;
+ if (dir_de && !nilfs_empty_dir(new_inode))
+ goto out_dir;
+
+ err = -ENOENT;
+ new_de = nilfs_find_entry(new_dir, new_dentry, &new_page);
+ if (!new_de)
+ goto out_dir;
+ inode_inc_link_count(old_inode);
+ nilfs_set_link(new_dir, new_de, new_page, old_inode);
+ new_inode->i_ctime = CURRENT_TIME;
+ if (dir_de)
+ drop_nlink(new_inode);
+ inode_dec_link_count(new_inode);
+ } else {
+ if (dir_de) {
+ err = -EMLINK;
+ if (new_dir->i_nlink >= NILFS_LINK_MAX)
+ goto out_dir;
+ }
+ inode_inc_link_count(old_inode);
+ err = nilfs_add_link(new_dentry, old_inode);
+ if (err) {
+ inode_dec_link_count(old_inode);
+ goto out_dir;
+ }
+ if (dir_de)
+ inode_inc_link_count(new_dir);
+ }
+
+ /*
+ * Like most other Unix systems, set the ctime for inodes on a
+ * rename.
+ * inode_dec_link_count() will mark the inode dirty.
+ */
+ old_inode->i_ctime = CURRENT_TIME;
+
+ nilfs_delete_entry(old_de, old_page);
+ inode_dec_link_count(old_inode);
+
+ if (dir_de) {
+ nilfs_set_link(old_inode, dir_de, dir_page, new_dir);
+ inode_dec_link_count(old_dir);
+ }
+
+ err = nilfs_transaction_commit(old_dir->i_sb);
+ return err;
+
+out_dir:
+ if (dir_de) {
+ kunmap(dir_page);
+ page_cache_release(dir_page);
+ }
+out_old:
+ kunmap(old_page);
+ page_cache_release(old_page);
+out:
+ nilfs_transaction_abort(old_dir->i_sb);
+ return err;
+}
+
+struct inode_operations nilfs_dir_inode_operations = {
+ .create = nilfs_create,
+ .lookup = nilfs_lookup,
+ .link = nilfs_link,
+ .unlink = nilfs_unlink,
+ .symlink = nilfs_symlink,
+ .mkdir = nilfs_mkdir,
+ .rmdir = nilfs_rmdir,
+ .mknod = nilfs_mknod,
+ .rename = nilfs_rename,
+ .setattr = nilfs_setattr,
+ .permission = nilfs_permission,
+};
+
+struct inode_operations nilfs_special_inode_operations = {
+ .setattr = nilfs_setattr,
+ .permission = nilfs_permission,
+};
+
+struct inode_operations nilfs_symlink_inode_operations = {
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
+};
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
new file mode 100644
index 00000000000..3d0c18a16db
--- /dev/null
+++ b/fs/nilfs2/nilfs.h
@@ -0,0 +1,313 @@
+/*
+ * nilfs.h - NILFS local header file.
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>
+ * Ryusuke Konishi <ryusuke@osrg.net>
+ */
+
+#ifndef _NILFS_H
+#define _NILFS_H
+
+#include <linux/kernel.h>
+#include <linux/buffer_head.h>
+#include <linux/spinlock.h>
+#include <linux/blkdev.h>
+#include <linux/nilfs2_fs.h>
+#include "the_nilfs.h"
+#include "sb.h"
+#include "bmap.h"
+#include "bmap_union.h"
+
+/*
+ * nilfs inode data in memory
+ */
+struct nilfs_inode_info {
+ __u32 i_flags;
+ unsigned long i_state; /* Dynamic state flags */
+ struct nilfs_bmap *i_bmap;
+ union nilfs_bmap_union i_bmap_union;
+ __u64 i_xattr; /* sector_t ??? */
+ __u32 i_dir_start_lookup;
+ __u64 i_cno; /* check point number for GC inode */
+ struct address_space i_btnode_cache;
+ struct list_head i_dirty; /* List for connecting dirty files */
+
+#ifdef CONFIG_NILFS_XATTR
+ /*
+ * Extended attributes can be read independently of the main file
+ * data. Taking i_sem even when reading would cause contention
+ * between readers of EAs and writers of regular file data, so
+ * instead we synchronize on xattr_sem when reading or changing
+ * EAs.
+ */
+ struct rw_semaphore xattr_sem;
+#endif
+#ifdef CONFIG_NILFS_POSIX_ACL
+ struct posix_acl *i_acl;
+ struct posix_acl *i_default_acl;
+#endif
+ struct buffer_head *i_bh; /* i_bh contains a new or dirty
+ disk inode */
+ struct inode vfs_inode;
+};
+
+static inline struct nilfs_inode_info *NILFS_I(const struct inode *inode)
+{
+ return container_of(inode, struct nilfs_inode_info, vfs_inode);
+}
+
+static inline struct nilfs_inode_info *
+NILFS_BMAP_I(const struct nilfs_bmap *bmap)
+{
+ return container_of((union nilfs_bmap_union *)bmap,
+ struct nilfs_inode_info,
+ i_bmap_union);
+}
+
+static inline struct inode *NILFS_BTNC_I(struct address_space *btnc)
+{
+ struct nilfs_inode_info *ii =
+ container_of(btnc, struct nilfs_inode_info, i_btnode_cache);
+ return &ii->vfs_inode;
+}
+
+static inline struct inode *NILFS_AS_I(struct address_space *mapping)
+{
+ return (mapping->host) ? :
+ container_of(mapping, struct inode, i_data);
+}
+
+/*
+ * Dynamic state flags of NILFS on-memory inode (i_state)
+ */
+enum {
+ NILFS_I_NEW = 0, /* Inode is newly created */
+ NILFS_I_DIRTY, /* The file is dirty */
+ NILFS_I_QUEUED, /* inode is in dirty_files list */
+ NILFS_I_BUSY, /* inode is grabbed by a segment
+ constructor */
+ NILFS_I_COLLECTED, /* All dirty blocks are collected */
+ NILFS_I_UPDATED, /* The file has been written back */
+ NILFS_I_INODE_DIRTY, /* write_inode is requested */
+ NILFS_I_BMAP, /* has bmap and btnode_cache */
+ NILFS_I_GCINODE, /* inode for GC, on memory only */
+ NILFS_I_GCDAT, /* shadow DAT, on memory only */
+};
+
+/*
+ * Macros to check inode numbers
+ */
+#define NILFS_MDT_INO_BITS \
+ ((unsigned int)(1 << NILFS_DAT_INO | 1 << NILFS_CPFILE_INO | \
+ 1 << NILFS_SUFILE_INO | 1 << NILFS_IFILE_INO | \
+ 1 << NILFS_ATIME_INO | 1 << NILFS_SKETCH_INO))
+
+#define NILFS_SYS_INO_BITS \
+ ((unsigned int)(1 << NILFS_ROOT_INO) | NILFS_MDT_INO_BITS)
+
+#define NILFS_FIRST_INO(sb) (NILFS_SB(sb)->s_nilfs->ns_first_ino)
+
+#define NILFS_MDT_INODE(sb, ino) \
+ ((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & (1 << (ino))))
+#define NILFS_VALID_INODE(sb, ino) \
+ ((ino) >= NILFS_FIRST_INO(sb) || (NILFS_SYS_INO_BITS & (1 << (ino))))
+
+/**
+ * struct nilfs_transaction_info: context information for synchronization
+ * @ti_magic: Magic number
+ * @ti_save: Backup of journal_info field of task_struct
+ * @ti_flags: Flags
+ * @ti_count: Nest level
+ * @ti_garbage: List of inode to be put when releasing semaphore
+ */
+struct nilfs_transaction_info {
+ u32 ti_magic;
+ void *ti_save;
+ /* This should never used. If this happens,
+ one of other filesystems has a bug. */
+ unsigned short ti_flags;
+ unsigned short ti_count;
+ struct list_head ti_garbage;
+};
+
+/* ti_magic */
+#define NILFS_TI_MAGIC 0xd9e392fb
+
+/* ti_flags */
+#define NILFS_TI_DYNAMIC_ALLOC 0x0001 /* Allocated from slab */
+#define NILFS_TI_SYNC 0x0002 /* Force to construct segment at the
+ end of transaction. */
+#define NILFS_TI_GC 0x0004 /* GC context */
+#define NILFS_TI_COMMIT 0x0008 /* Change happened or not */
+#define NILFS_TI_WRITER 0x0010 /* Constructor context */
+
+
+int nilfs_transaction_begin(struct super_block *,
+ struct nilfs_transaction_info *, int);
+int nilfs_transaction_commit(struct super_block *);
+void nilfs_transaction_abort(struct super_block *);
+
+static inline void nilfs_set_transaction_flag(unsigned int flag)
+{
+ struct nilfs_transaction_info *ti = current->journal_info;
+
+ ti->ti_flags |= flag;
+}
+
+static inline int nilfs_test_transaction_flag(unsigned int flag)
+{
+ struct nilfs_transaction_info *ti = current->journal_info;
+
+ if (ti == NULL || ti->ti_magic != NILFS_TI_MAGIC)
+ return 0;
+ return !!(ti->ti_flags & flag);
+}
+
+static inline int nilfs_doing_gc(void)
+{
+ return nilfs_test_transaction_flag(NILFS_TI_GC);
+}
+
+static inline int nilfs_doing_construction(void)
+{
+ return nilfs_test_transaction_flag(NILFS_TI_WRITER);
+}
+
+static inline struct inode *nilfs_dat_inode(const struct the_nilfs *nilfs)
+{
+ return nilfs_doing_gc() ? nilfs->ns_gc_dat : nilfs->ns_dat;
+}
+
+/*
+ * function prototype
+ */
+#ifdef CONFIG_NILFS_POSIX_ACL
+#error "NILFS: not yet supported POSIX ACL"
+extern int nilfs_permission(struct inode *, int, struct nameidata *);
+extern int nilfs_acl_chmod(struct inode *);
+extern int nilfs_init_acl(struct inode *, struct inode *);
+#else
+#define nilfs_permission NULL
+
+static inline int nilfs_acl_chmod(struct inode *inode)
+{
+ return 0;
+}
+
+static inline int nilfs_init_acl(struct inode *inode, struct inode *dir)
+{
+ inode->i_mode &= ~current_umask();
+ return 0;
+}
+#endif
+
+#define NILFS_ATIME_DISABLE
+
+/* dir.c */
+extern int nilfs_add_link(struct dentry *, struct inode *);
+extern ino_t nilfs_inode_by_name(struct inode *, struct dentry *);
+extern int nilfs_make_empty(struct inode *, struct inode *);
+extern struct nilfs_dir_entry *
+nilfs_find_entry(struct inode *, struct dentry *, struct page **);
+extern int nilfs_delete_entry(struct nilfs_dir_entry *, struct page *);
+extern int nilfs_empty_dir(struct inode *);
+extern struct nilfs_dir_entry *nilfs_dotdot(struct inode *, struct page **);
+extern void nilfs_set_link(struct inode *, struct nilfs_dir_entry *,
+ struct page *, struct inode *);
+
+/* file.c */
+extern int nilfs_sync_file(struct file *, struct dentry *, int);
+
+/* ioctl.c */
+long nilfs_ioctl(struct file *, unsigned int, unsigned long);
+int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *, void __user *);
+
+/* inode.c */
+extern struct inode *nilfs_new_inode(struct inode *, int);
+extern void nilfs_free_inode(struct inode *);
+extern int nilfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
+extern void nilfs_set_inode_flags(struct inode *);
+extern int nilfs_read_inode_common(struct inode *, struct nilfs_inode *);
+extern void nilfs_write_inode_common(struct inode *, struct nilfs_inode *, int);
+extern struct inode *nilfs_iget(struct super_block *, unsigned long);
+extern void nilfs_update_inode(struct inode *, struct buffer_head *);
+extern void nilfs_truncate(struct inode *);
+extern void nilfs_delete_inode(struct inode *);
+extern int nilfs_setattr(struct dentry *, struct iattr *);
+extern int nilfs_load_inode_block(struct nilfs_sb_info *, struct inode *,
+ struct buffer_head **);
+extern int nilfs_inode_dirty(struct inode *);
+extern int nilfs_set_file_dirty(struct nilfs_sb_info *, struct inode *,
+ unsigned);
+extern int nilfs_mark_inode_dirty(struct inode *);
+extern void nilfs_dirty_inode(struct inode *);
+
+/* namei.c */
+extern struct dentry *nilfs_get_parent(struct dentry *);
+
+/* super.c */
+extern struct inode *nilfs_alloc_inode(struct super_block *);
+extern void nilfs_destroy_inode(struct inode *);
+extern void nilfs_error(struct super_block *, const char *, const char *, ...)
+ __attribute__ ((format (printf, 3, 4)));
+extern void nilfs_warning(struct super_block *, const char *, const char *, ...)
+ __attribute__ ((format (printf, 3, 4)));
+extern struct nilfs_super_block *
+nilfs_read_super_block(struct super_block *, u64, int, struct buffer_head **);
+extern int nilfs_store_magic_and_option(struct super_block *,
+ struct nilfs_super_block *, char *);
+extern int nilfs_commit_super(struct nilfs_sb_info *, int);
+extern int nilfs_attach_checkpoint(struct nilfs_sb_info *, __u64);
+extern void nilfs_detach_checkpoint(struct nilfs_sb_info *);
+
+/* gcinode.c */
+int nilfs_gccache_submit_read_data(struct inode *, sector_t, sector_t, __u64,
+ struct buffer_head **);
+int nilfs_gccache_submit_read_node(struct inode *, sector_t, __u64,
+ struct buffer_head **);
+int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *);
+int nilfs_init_gccache(struct the_nilfs *);
+void nilfs_destroy_gccache(struct the_nilfs *);
+void nilfs_clear_gcinode(struct inode *);
+struct inode *nilfs_gc_iget(struct the_nilfs *, ino_t, __u64);
+void nilfs_remove_all_gcinode(struct the_nilfs *);
+
+/* gcdat.c */
+int nilfs_init_gcdat_inode(struct the_nilfs *);
+void nilfs_commit_gcdat_inode(struct the_nilfs *);
+void nilfs_clear_gcdat_inode(struct the_nilfs *);
+
+/*
+ * Inodes and files operations
+ */
+extern struct file_operations nilfs_dir_operations;
+extern struct inode_operations nilfs_file_inode_operations;
+extern struct file_operations nilfs_file_operations;
+extern struct address_space_operations nilfs_aops;
+extern struct inode_operations nilfs_dir_inode_operations;
+extern struct inode_operations nilfs_special_inode_operations;
+extern struct inode_operations nilfs_symlink_inode_operations;
+
+/*
+ * filesystem type
+ */
+extern struct file_system_type nilfs_fs_type;
+
+
+#endif /* _NILFS_H */
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
new file mode 100644
index 00000000000..1bfbba9c0e9
--- /dev/null
+++ b/fs/nilfs2/page.c
@@ -0,0 +1,540 @@
+/*
+ * page.c - buffer/page management specific to NILFS
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>,
+ * Seiji Kihara <kihara@osrg.net>.
+ */
+
+#include <linux/pagemap.h>
+#include <linux/writeback.h>
+#include <linux/swap.h>
+#include <linux/bitops.h>
+#include <linux/page-flags.h>
+#include <linux/list.h>
+#include <linux/highmem.h>
+#include <linux/pagevec.h>
+#include "nilfs.h"
+#include "page.h"
+#include "mdt.h"
+
+
+#define NILFS_BUFFER_INHERENT_BITS \
+ ((1UL << BH_Uptodate) | (1UL << BH_Mapped) | (1UL << BH_NILFS_Node) | \
+ (1UL << BH_NILFS_Volatile) | (1UL << BH_NILFS_Allocated))
+
+static struct buffer_head *
+__nilfs_get_page_block(struct page *page, unsigned long block, pgoff_t index,
+ int blkbits, unsigned long b_state)
+
+{
+ unsigned long first_block;
+ struct buffer_head *bh;
+
+ if (!page_has_buffers(page))
+ create_empty_buffers(page, 1 << blkbits, b_state);
+
+ first_block = (unsigned long)index << (PAGE_CACHE_SHIFT - blkbits);
+ bh = nilfs_page_get_nth_block(page, block - first_block);
+
+ touch_buffer(bh);
+ wait_on_buffer(bh);
+ return bh;
+}
+
+/*
+ * Since the page cache of B-tree node pages or data page cache of pseudo
+ * inodes does not have a valid mapping->host pointer, calling
+ * mark_buffer_dirty() for their buffers causes a NULL pointer dereference;
+ * it calls __mark_inode_dirty(NULL) through __set_page_dirty().
+ * To avoid this problem, the old style mark_buffer_dirty() is used instead.
+ */
+void nilfs_mark_buffer_dirty(struct buffer_head *bh)
+{
+ if (!buffer_dirty(bh) && !test_set_buffer_dirty(bh))
+ __set_page_dirty_nobuffers(bh->b_page);
+}
+
+struct buffer_head *nilfs_grab_buffer(struct inode *inode,
+ struct address_space *mapping,
+ unsigned long blkoff,
+ unsigned long b_state)
+{
+ int blkbits = inode->i_blkbits;
+ pgoff_t index = blkoff >> (PAGE_CACHE_SHIFT - blkbits);
+ struct page *page, *opage;
+ struct buffer_head *bh, *obh;
+
+ page = grab_cache_page(mapping, index);
+ if (unlikely(!page))
+ return NULL;
+
+ bh = __nilfs_get_page_block(page, blkoff, index, blkbits, b_state);
+ if (unlikely(!bh)) {
+ unlock_page(page);
+ page_cache_release(page);
+ return NULL;
+ }
+ if (!buffer_uptodate(bh) && mapping->assoc_mapping != NULL) {
+ /*
+ * Shadow page cache uses assoc_mapping to point its original
+ * page cache. The following code tries the original cache
+ * if the given cache is a shadow and it didn't hit.
+ */
+ opage = find_lock_page(mapping->assoc_mapping, index);
+ if (!opage)
+ return bh;
+
+ obh = __nilfs_get_page_block(opage, blkoff, index, blkbits,
+ b_state);
+ if (buffer_uptodate(obh)) {
+ nilfs_copy_buffer(bh, obh);
+ if (buffer_dirty(obh)) {
+ nilfs_mark_buffer_dirty(bh);
+ if (!buffer_nilfs_node(bh) && NILFS_MDT(inode))
+ nilfs_mdt_mark_dirty(inode);
+ }
+ }
+ brelse(obh);
+ unlock_page(opage);
+ page_cache_release(opage);
+ }
+ return bh;
+}
+
+/**
+ * nilfs_forget_buffer - discard dirty state
+ * @inode: owner inode of the buffer
+ * @bh: buffer head of the buffer to be discarded
+ */
+void nilfs_forget_buffer(struct buffer_head *bh)
+{
+ struct page *page = bh->b_page;
+
+ lock_buffer(bh);
+ clear_buffer_nilfs_volatile(bh);
+ if (test_clear_buffer_dirty(bh) && nilfs_page_buffers_clean(page))
+ __nilfs_clear_page_dirty(page);
+
+ clear_buffer_uptodate(bh);
+ clear_buffer_mapped(bh);
+ bh->b_blocknr = -1;
+ ClearPageUptodate(page);
+ ClearPageMappedToDisk(page);
+ unlock_buffer(bh);
+ brelse(bh);
+}
+
+/**
+ * nilfs_copy_buffer -- copy buffer data and flags
+ * @dbh: destination buffer
+ * @sbh: source buffer
+ */
+void nilfs_copy_buffer(struct buffer_head *dbh, struct buffer_head *sbh)
+{
+ void *kaddr0, *kaddr1;
+ unsigned long bits;
+ struct page *spage = sbh->b_page, *dpage = dbh->b_page;
+ struct buffer_head *bh;
+
+ kaddr0 = kmap_atomic(spage, KM_USER0);
+ kaddr1 = kmap_atomic(dpage, KM_USER1);
+ memcpy(kaddr1 + bh_offset(dbh), kaddr0 + bh_offset(sbh), sbh->b_size);
+ kunmap_atomic(kaddr1, KM_USER1);
+ kunmap_atomic(kaddr0, KM_USER0);
+
+ dbh->b_state = sbh->b_state & NILFS_BUFFER_INHERENT_BITS;
+ dbh->b_blocknr = sbh->b_blocknr;
+ dbh->b_bdev = sbh->b_bdev;
+
+ bh = dbh;
+ bits = sbh->b_state & ((1UL << BH_Uptodate) | (1UL << BH_Mapped));
+ while ((bh = bh->b_this_page) != dbh) {
+ lock_buffer(bh);
+ bits &= bh->b_state;
+ unlock_buffer(bh);
+ }
+ if (bits & (1UL << BH_Uptodate))
+ SetPageUptodate(dpage);
+ else
+ ClearPageUptodate(dpage);
+ if (bits & (1UL << BH_Mapped))
+ SetPageMappedToDisk(dpage);
+ else
+ ClearPageMappedToDisk(dpage);
+}
+
+/**
+ * nilfs_page_buffers_clean - check if a page has dirty buffers or not.
+ * @page: page to be checked
+ *
+ * nilfs_page_buffers_clean() returns zero if the page has dirty buffers.
+ * Otherwise, it returns non-zero value.
+ */
+int nilfs_page_buffers_clean(struct page *page)
+{
+ struct buffer_head *bh, *head;
+
+ bh = head = page_buffers(page);
+ do {
+ if (buffer_dirty(bh))
+ return 0;
+ bh = bh->b_this_page;
+ } while (bh != head);
+ return 1;
+}
+
+void nilfs_page_bug(struct page *page)
+{
+ struct address_space *m;
+ unsigned long ino = 0;
+
+ if (unlikely(!page)) {
+ printk(KERN_CRIT "NILFS_PAGE_BUG(NULL)\n");
+ return;
+ }
+
+ m = page->mapping;
+ if (m) {
+ struct inode *inode = NILFS_AS_I(m);
+ if (inode != NULL)
+ ino = inode->i_ino;
+ }
+ printk(KERN_CRIT "NILFS_PAGE_BUG(%p): cnt=%d index#=%llu flags=0x%lx "
+ "mapping=%p ino=%lu\n",
+ page, atomic_read(&page->_count),
+ (unsigned long long)page->index, page->flags, m, ino);
+
+ if (page_has_buffers(page)) {
+ struct buffer_head *bh, *head;
+ int i = 0;
+
+ bh = head = page_buffers(page);
+ do {
+ printk(KERN_CRIT
+ " BH[%d] %p: cnt=%d block#=%llu state=0x%lx\n",
+ i++, bh, atomic_read(&bh->b_count),
+ (unsigned long long)bh->b_blocknr, bh->b_state);
+ bh = bh->b_this_page;
+ } while (bh != head);
+ }
+}
+
+/**
+ * nilfs_alloc_private_page - allocate a private page with buffer heads
+ *
+ * Return Value: On success, a pointer to the allocated page is returned.
+ * On error, NULL is returned.
+ */
+struct page *nilfs_alloc_private_page(struct block_device *bdev, int size,
+ unsigned long state)
+{
+ struct buffer_head *bh, *head, *tail;
+ struct page *page;
+
+ page = alloc_page(GFP_NOFS); /* page_count of the returned page is 1 */
+ if (unlikely(!page))
+ return NULL;
+
+ lock_page(page);
+ head = alloc_page_buffers(page, size, 0);
+ if (unlikely(!head)) {
+ unlock_page(page);
+ __free_page(page);
+ return NULL;
+ }
+
+ bh = head;
+ do {
+ bh->b_state = (1UL << BH_NILFS_Allocated) | state;
+ tail = bh;
+ bh->b_bdev = bdev;
+ bh = bh->b_this_page;
+ } while (bh);
+
+ tail->b_this_page = head;
+ attach_page_buffers(page, head);
+
+ return page;
+}
+
+void nilfs_free_private_page(struct page *page)
+{
+ BUG_ON(!PageLocked(page));
+ BUG_ON(page->mapping);
+
+ if (page_has_buffers(page) && !try_to_free_buffers(page))
+ NILFS_PAGE_BUG(page, "failed to free page");
+
+ unlock_page(page);
+ __free_page(page);
+}
+
+/**
+ * nilfs_copy_page -- copy the page with buffers
+ * @dst: destination page
+ * @src: source page
+ * @copy_dirty: flag whether to copy dirty states on the page's buffer heads.
+ *
+ * This fuction is for both data pages and btnode pages. The dirty flag
+ * should be treated by caller. The page must not be under i/o.
+ * Both src and dst page must be locked
+ */
+static void nilfs_copy_page(struct page *dst, struct page *src, int copy_dirty)
+{
+ struct buffer_head *dbh, *dbufs, *sbh, *sbufs;
+ unsigned long mask = NILFS_BUFFER_INHERENT_BITS;
+
+ BUG_ON(PageWriteback(dst));
+
+ sbh = sbufs = page_buffers(src);
+ if (!page_has_buffers(dst))
+ create_empty_buffers(dst, sbh->b_size, 0);
+
+ if (copy_dirty)
+ mask |= (1UL << BH_Dirty);
+
+ dbh = dbufs = page_buffers(dst);
+ do {
+ lock_buffer(sbh);
+ lock_buffer(dbh);
+ dbh->b_state = sbh->b_state & mask;
+ dbh->b_blocknr = sbh->b_blocknr;
+ dbh->b_bdev = sbh->b_bdev;
+ sbh = sbh->b_this_page;
+ dbh = dbh->b_this_page;
+ } while (dbh != dbufs);
+
+ copy_highpage(dst, src);
+
+ if (PageUptodate(src) && !PageUptodate(dst))
+ SetPageUptodate(dst);
+ else if (!PageUptodate(src) && PageUptodate(dst))
+ ClearPageUptodate(dst);
+ if (PageMappedToDisk(src) && !PageMappedToDisk(dst))
+ SetPageMappedToDisk(dst);
+ else if (!PageMappedToDisk(src) && PageMappedToDisk(dst))
+ ClearPageMappedToDisk(dst);
+
+ do {
+ unlock_buffer(sbh);
+ unlock_buffer(dbh);
+ sbh = sbh->b_this_page;
+ dbh = dbh->b_this_page;
+ } while (dbh != dbufs);
+}
+
+int nilfs_copy_dirty_pages(struct address_space *dmap,
+ struct address_space *smap)
+{
+ struct pagevec pvec;
+ unsigned int i;
+ pgoff_t index = 0;
+ int err = 0;
+
+ pagevec_init(&pvec, 0);
+repeat:
+ if (!pagevec_lookup_tag(&pvec, smap, &index, PAGECACHE_TAG_DIRTY,
+ PAGEVEC_SIZE))
+ return 0;
+
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ struct page *page = pvec.pages[i], *dpage;
+
+ lock_page(page);
+ if (unlikely(!PageDirty(page)))
+ NILFS_PAGE_BUG(page, "inconsistent dirty state");
+
+ dpage = grab_cache_page(dmap, page->index);
+ if (unlikely(!dpage)) {
+ /* No empty page is added to the page cache */
+ err = -ENOMEM;
+ unlock_page(page);
+ break;
+ }
+ if (unlikely(!page_has_buffers(page)))
+ NILFS_PAGE_BUG(page,
+ "found empty page in dat page cache");
+
+ nilfs_copy_page(dpage, page, 1);
+ __set_page_dirty_nobuffers(dpage);
+
+ unlock_page(dpage);
+ page_cache_release(dpage);
+ unlock_page(page);
+ }
+ pagevec_release(&pvec);
+ cond_resched();
+
+ if (likely(!err))
+ goto repeat;
+ return err;
+}
+
+/**
+ * nilfs_copy_back_pages -- copy back pages to orignal cache from shadow cache
+ * @dmap: destination page cache
+ * @smap: source page cache
+ *
+ * No pages must no be added to the cache during this process.
+ * This must be ensured by the caller.
+ */
+void nilfs_copy_back_pages(struct address_space *dmap,
+ struct address_space *smap)
+{
+ struct pagevec pvec;
+ unsigned int i, n;
+ pgoff_t index = 0;
+ int err;
+
+ pagevec_init(&pvec, 0);
+repeat:
+ n = pagevec_lookup(&pvec, smap, index, PAGEVEC_SIZE);
+ if (!n)
+ return;
+ index = pvec.pages[n - 1]->index + 1;
+
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ struct page *page = pvec.pages[i], *dpage;
+ pgoff_t offset = page->index;
+
+ lock_page(page);
+ dpage = find_lock_page(dmap, offset);
+ if (dpage) {
+ /* override existing page on the destination cache */
+ WARN_ON(PageDirty(dpage));
+ nilfs_copy_page(dpage, page, 0);
+ unlock_page(dpage);
+ page_cache_release(dpage);
+ } else {
+ struct page *page2;
+
+ /* move the page to the destination cache */
+ spin_lock_irq(&smap->tree_lock);
+ page2 = radix_tree_delete(&smap->page_tree, offset);
+ WARN_ON(page2 != page);
+
+ smap->nrpages--;
+ spin_unlock_irq(&smap->tree_lock);
+
+ spin_lock_irq(&dmap->tree_lock);
+ err = radix_tree_insert(&dmap->page_tree, offset, page);
+ if (unlikely(err < 0)) {
+ WARN_ON(err == -EEXIST);
+ page->mapping = NULL;
+ page_cache_release(page); /* for cache */
+ } else {
+ page->mapping = dmap;
+ dmap->nrpages++;
+ if (PageDirty(page))
+ radix_tree_tag_set(&dmap->page_tree,
+ offset,
+ PAGECACHE_TAG_DIRTY);
+ }
+ spin_unlock_irq(&dmap->tree_lock);
+ }
+ unlock_page(page);
+ }
+ pagevec_release(&pvec);
+ cond_resched();
+
+ goto repeat;
+}
+
+void nilfs_clear_dirty_pages(struct address_space *mapping)
+{
+ struct pagevec pvec;
+ unsigned int i;
+ pgoff_t index = 0;
+
+ pagevec_init(&pvec, 0);
+
+ while (pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
+ PAGEVEC_SIZE)) {
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ struct page *page = pvec.pages[i];
+ struct buffer_head *bh, *head;
+
+ lock_page(page);
+ ClearPageUptodate(page);
+ ClearPageMappedToDisk(page);
+ bh = head = page_buffers(page);
+ do {
+ lock_buffer(bh);
+ clear_buffer_dirty(bh);
+ clear_buffer_nilfs_volatile(bh);
+ clear_buffer_uptodate(bh);
+ clear_buffer_mapped(bh);
+ unlock_buffer(bh);
+ bh = bh->b_this_page;
+ } while (bh != head);
+
+ __nilfs_clear_page_dirty(page);
+ unlock_page(page);
+ }
+ pagevec_release(&pvec);
+ cond_resched();
+ }
+}
+
+unsigned nilfs_page_count_clean_buffers(struct page *page,
+ unsigned from, unsigned to)
+{
+ unsigned block_start, block_end;
+ struct buffer_head *bh, *head;
+ unsigned nc = 0;
+
+ for (bh = head = page_buffers(page), block_start = 0;
+ bh != head || !block_start;
+ block_start = block_end, bh = bh->b_this_page) {
+ block_end = block_start + bh->b_size;
+ if (block_end > from && block_start < to && !buffer_dirty(bh))
+ nc++;
+ }
+ return nc;
+}
+
+/*
+ * NILFS2 needs clear_page_dirty() in the following two cases:
+ *
+ * 1) For B-tree node pages and data pages of the dat/gcdat, NILFS2 clears
+ * page dirty flags when it copies back pages from the shadow cache
+ * (gcdat->{i_mapping,i_btnode_cache}) to its original cache
+ * (dat->{i_mapping,i_btnode_cache}).
+ *
+ * 2) Some B-tree operations like insertion or deletion may dispose buffers
+ * in dirty state, and this needs to cancel the dirty state of their pages.
+ */
+int __nilfs_clear_page_dirty(struct page *page)
+{
+ struct address_space *mapping = page->mapping;
+
+ if (mapping) {
+ spin_lock_irq(&mapping->tree_lock);
+ if (test_bit(PG_dirty, &page->flags)) {
+ radix_tree_tag_clear(&mapping->page_tree,
+ page_index(page),
+ PAGECACHE_TAG_DIRTY);
+ spin_unlock_irq(&mapping->tree_lock);
+ return clear_page_dirty_for_io(page);
+ }
+ spin_unlock_irq(&mapping->tree_lock);
+ return 0;
+ }
+ return TestClearPageDirty(page);
+}
diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h
new file mode 100644
index 00000000000..8abca4d1c1f
--- /dev/null
+++ b/fs/nilfs2/page.h
@@ -0,0 +1,76 @@
+/*
+ * page.h - buffer/page management specific to NILFS
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>,
+ * Seiji Kihara <kihara@osrg.net>.
+ */
+
+#ifndef _NILFS_PAGE_H
+#define _NILFS_PAGE_H
+
+#include <linux/buffer_head.h>
+#include "nilfs.h"
+
+/*
+ * Extended buffer state bits
+ */
+enum {
+ BH_NILFS_Allocated = BH_PrivateStart,
+ BH_NILFS_Node,
+ BH_NILFS_Volatile,
+};
+
+BUFFER_FNS(NILFS_Allocated, nilfs_allocated) /* nilfs private buffers */
+BUFFER_FNS(NILFS_Node, nilfs_node) /* nilfs node buffers */
+BUFFER_FNS(NILFS_Volatile, nilfs_volatile)
+
+
+void nilfs_mark_buffer_dirty(struct buffer_head *bh);
+int __nilfs_clear_page_dirty(struct page *);
+
+struct buffer_head *nilfs_grab_buffer(struct inode *, struct address_space *,
+ unsigned long, unsigned long);
+void nilfs_forget_buffer(struct buffer_head *);
+void nilfs_copy_buffer(struct buffer_head *, struct buffer_head *);
+int nilfs_page_buffers_clean(struct page *);
+void nilfs_page_bug(struct page *);
+struct page *nilfs_alloc_private_page(struct block_device *, int,
+ unsigned long);
+void nilfs_free_private_page(struct page *);
+
+int nilfs_copy_dirty_pages(struct address_space *, struct address_space *);
+void nilfs_copy_back_pages(struct address_space *, struct address_space *);
+void nilfs_clear_dirty_pages(struct address_space *);
+unsigned nilfs_page_count_clean_buffers(struct page *, unsigned, unsigned);
+
+#define NILFS_PAGE_BUG(page, m, a...) \
+ do { nilfs_page_bug(page); BUG(); } while (0)
+
+static inline struct buffer_head *
+nilfs_page_get_nth_block(struct page *page, unsigned int count)
+{
+ struct buffer_head *bh = page_buffers(page);
+
+ while (count-- > 0)
+ bh = bh->b_this_page;
+ get_bh(bh);
+ return bh;
+}
+
+#endif /* _NILFS_PAGE_H */
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
new file mode 100644
index 00000000000..4fc081e47d7
--- /dev/null
+++ b/fs/nilfs2/recovery.c
@@ -0,0 +1,917 @@
+/*
+ * recovery.c - NILFS recovery logic
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>
+ */
+
+#include <linux/buffer_head.h>
+#include <linux/blkdev.h>
+#include <linux/swap.h>
+#include <linux/crc32.h>
+#include "nilfs.h"
+#include "segment.h"
+#include "sufile.h"
+#include "page.h"
+#include "seglist.h"
+#include "segbuf.h"
+
+/*
+ * Segment check result
+ */
+enum {
+ NILFS_SEG_VALID,
+ NILFS_SEG_NO_SUPER_ROOT,
+ NILFS_SEG_FAIL_IO,
+ NILFS_SEG_FAIL_MAGIC,
+ NILFS_SEG_FAIL_SEQ,
+ NILFS_SEG_FAIL_CHECKSUM_SEGSUM,
+ NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT,
+ NILFS_SEG_FAIL_CHECKSUM_FULL,
+ NILFS_SEG_FAIL_CONSISTENCY,
+};
+
+/* work structure for recovery */
+struct nilfs_recovery_block {
+ ino_t ino; /* Inode number of the file that this block
+ belongs to */
+ sector_t blocknr; /* block number */
+ __u64 vblocknr; /* virtual block number */
+ unsigned long blkoff; /* File offset of the data block (per block) */
+ struct list_head list;
+};
+
+
+static int nilfs_warn_segment_error(int err)
+{
+ switch (err) {
+ case NILFS_SEG_FAIL_IO:
+ printk(KERN_WARNING
+ "NILFS warning: I/O error on loading last segment\n");
+ return -EIO;
+ case NILFS_SEG_FAIL_MAGIC:
+ printk(KERN_WARNING
+ "NILFS warning: Segment magic number invalid\n");
+ break;
+ case NILFS_SEG_FAIL_SEQ:
+ printk(KERN_WARNING
+ "NILFS warning: Sequence number mismatch\n");
+ break;
+ case NILFS_SEG_FAIL_CHECKSUM_SEGSUM:
+ printk(KERN_WARNING
+ "NILFS warning: Checksum error in segment summary\n");
+ break;
+ case NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT:
+ printk(KERN_WARNING
+ "NILFS warning: Checksum error in super root\n");
+ break;
+ case NILFS_SEG_FAIL_CHECKSUM_FULL:
+ printk(KERN_WARNING
+ "NILFS warning: Checksum error in segment payload\n");
+ break;
+ case NILFS_SEG_FAIL_CONSISTENCY:
+ printk(KERN_WARNING
+ "NILFS warning: Inconsistent segment\n");
+ break;
+ case NILFS_SEG_NO_SUPER_ROOT:
+ printk(KERN_WARNING
+ "NILFS warning: No super root in the last segment\n");
+ break;
+ }
+ return -EINVAL;
+}
+
+static void store_segsum_info(struct nilfs_segsum_info *ssi,
+ struct nilfs_segment_summary *sum,
+ unsigned int blocksize)
+{
+ ssi->flags = le16_to_cpu(sum->ss_flags);
+ ssi->seg_seq = le64_to_cpu(sum->ss_seq);
+ ssi->ctime = le64_to_cpu(sum->ss_create);
+ ssi->next = le64_to_cpu(sum->ss_next);
+ ssi->nblocks = le32_to_cpu(sum->ss_nblocks);
+ ssi->nfinfo = le32_to_cpu(sum->ss_nfinfo);
+ ssi->sumbytes = le32_to_cpu(sum->ss_sumbytes);
+
+ ssi->nsumblk = DIV_ROUND_UP(ssi->sumbytes, blocksize);
+ ssi->nfileblk = ssi->nblocks - ssi->nsumblk - !!NILFS_SEG_HAS_SR(ssi);
+}
+
+/**
+ * calc_crc_cont - check CRC of blocks continuously
+ * @sbi: nilfs_sb_info
+ * @bhs: buffer head of start block
+ * @sum: place to store result
+ * @offset: offset bytes in the first block
+ * @check_bytes: number of bytes to be checked
+ * @start: DBN of start block
+ * @nblock: number of blocks to be checked
+ */
+static int calc_crc_cont(struct nilfs_sb_info *sbi, struct buffer_head *bhs,
+ u32 *sum, unsigned long offset, u64 check_bytes,
+ sector_t start, unsigned long nblock)
+{
+ unsigned long blocksize = sbi->s_super->s_blocksize;
+ unsigned long size;
+ u32 crc;
+
+ BUG_ON(offset >= blocksize);
+ check_bytes -= offset;
+ size = min_t(u64, check_bytes, blocksize - offset);
+ crc = crc32_le(sbi->s_nilfs->ns_crc_seed,
+ (unsigned char *)bhs->b_data + offset, size);
+ if (--nblock > 0) {
+ do {
+ struct buffer_head *bh
+ = sb_bread(sbi->s_super, ++start);
+ if (!bh)
+ return -EIO;
+ check_bytes -= size;
+ size = min_t(u64, check_bytes, blocksize);
+ crc = crc32_le(crc, bh->b_data, size);
+ brelse(bh);
+ } while (--nblock > 0);
+ }
+ *sum = crc;
+ return 0;
+}
+
+/**
+ * nilfs_read_super_root_block - read super root block
+ * @sb: super_block
+ * @sr_block: disk block number of the super root block
+ * @pbh: address of a buffer_head pointer to return super root buffer
+ * @check: CRC check flag
+ */
+int nilfs_read_super_root_block(struct super_block *sb, sector_t sr_block,
+ struct buffer_head **pbh, int check)
+{
+ struct buffer_head *bh_sr;
+ struct nilfs_super_root *sr;
+ u32 crc;
+ int ret;
+
+ *pbh = NULL;
+ bh_sr = sb_bread(sb, sr_block);
+ if (unlikely(!bh_sr)) {
+ ret = NILFS_SEG_FAIL_IO;
+ goto failed;
+ }
+
+ sr = (struct nilfs_super_root *)bh_sr->b_data;
+ if (check) {
+ unsigned bytes = le16_to_cpu(sr->sr_bytes);
+
+ if (bytes == 0 || bytes > sb->s_blocksize) {
+ ret = NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT;
+ goto failed_bh;
+ }
+ if (calc_crc_cont(NILFS_SB(sb), bh_sr, &crc,
+ sizeof(sr->sr_sum), bytes, sr_block, 1)) {
+ ret = NILFS_SEG_FAIL_IO;
+ goto failed_bh;
+ }
+ if (crc != le32_to_cpu(sr->sr_sum)) {
+ ret = NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT;
+ goto failed_bh;
+ }
+ }
+ *pbh = bh_sr;
+ return 0;
+
+ failed_bh:
+ brelse(bh_sr);
+
+ failed:
+ return nilfs_warn_segment_error(ret);
+}
+
+/**
+ * load_segment_summary - read segment summary of the specified partial segment
+ * @sbi: nilfs_sb_info
+ * @pseg_start: start disk block number of partial segment
+ * @seg_seq: sequence number requested
+ * @ssi: pointer to nilfs_segsum_info struct to store information
+ * @full_check: full check flag
+ * (0: only checks segment summary CRC, 1: data CRC)
+ */
+static int
+load_segment_summary(struct nilfs_sb_info *sbi, sector_t pseg_start,
+ u64 seg_seq, struct nilfs_segsum_info *ssi,
+ int full_check)
+{
+ struct buffer_head *bh_sum;
+ struct nilfs_segment_summary *sum;
+ unsigned long offset, nblock;
+ u64 check_bytes;
+ u32 crc, crc_sum;
+ int ret = NILFS_SEG_FAIL_IO;
+
+ bh_sum = sb_bread(sbi->s_super, pseg_start);
+ if (!bh_sum)
+ goto out;
+
+ sum = (struct nilfs_segment_summary *)bh_sum->b_data;
+
+ /* Check consistency of segment summary */
+ if (le32_to_cpu(sum->ss_magic) != NILFS_SEGSUM_MAGIC) {
+ ret = NILFS_SEG_FAIL_MAGIC;
+ goto failed;
+ }
+ store_segsum_info(ssi, sum, sbi->s_super->s_blocksize);
+ if (seg_seq != ssi->seg_seq) {
+ ret = NILFS_SEG_FAIL_SEQ;
+ goto failed;
+ }
+ if (full_check) {
+ offset = sizeof(sum->ss_datasum);
+ check_bytes =
+ ((u64)ssi->nblocks << sbi->s_super->s_blocksize_bits);
+ nblock = ssi->nblocks;
+ crc_sum = le32_to_cpu(sum->ss_datasum);
+ ret = NILFS_SEG_FAIL_CHECKSUM_FULL;
+ } else { /* only checks segment summary */
+ offset = sizeof(sum->ss_datasum) + sizeof(sum->ss_sumsum);
+ check_bytes = ssi->sumbytes;
+ nblock = ssi->nsumblk;
+ crc_sum = le32_to_cpu(sum->ss_sumsum);
+ ret = NILFS_SEG_FAIL_CHECKSUM_SEGSUM;
+ }
+
+ if (unlikely(nblock == 0 ||
+ nblock > sbi->s_nilfs->ns_blocks_per_segment)) {
+ /* This limits the number of blocks read in the CRC check */
+ ret = NILFS_SEG_FAIL_CONSISTENCY;
+ goto failed;
+ }
+ if (calc_crc_cont(sbi, bh_sum, &crc, offset, check_bytes,
+ pseg_start, nblock)) {
+ ret = NILFS_SEG_FAIL_IO;
+ goto failed;
+ }
+ if (crc == crc_sum)
+ ret = 0;
+ failed:
+ brelse(bh_sum);
+ out:
+ return ret;
+}
+
+static void *segsum_get(struct super_block *sb, struct buffer_head **pbh,
+ unsigned int *offset, unsigned int bytes)
+{
+ void *ptr;
+ sector_t blocknr;
+
+ BUG_ON((*pbh)->b_size < *offset);
+ if (bytes > (*pbh)->b_size - *offset) {
+ blocknr = (*pbh)->b_blocknr;
+ brelse(*pbh);
+ *pbh = sb_bread(sb, blocknr + 1);
+ if (unlikely(!*pbh))
+ return NULL;
+ *offset = 0;
+ }
+ ptr = (*pbh)->b_data + *offset;
+ *offset += bytes;
+ return ptr;
+}
+
+static void segsum_skip(struct super_block *sb, struct buffer_head **pbh,
+ unsigned int *offset, unsigned int bytes,
+ unsigned long count)
+{
+ unsigned int rest_item_in_current_block
+ = ((*pbh)->b_size - *offset) / bytes;
+
+ if (count <= rest_item_in_current_block) {
+ *offset += bytes * count;
+ } else {
+ sector_t blocknr = (*pbh)->b_blocknr;
+ unsigned int nitem_per_block = (*pbh)->b_size / bytes;
+ unsigned int bcnt;
+
+ count -= rest_item_in_current_block;
+ bcnt = DIV_ROUND_UP(count, nitem_per_block);
+ *offset = bytes * (count - (bcnt - 1) * nitem_per_block);
+
+ brelse(*pbh);
+ *pbh = sb_bread(sb, blocknr + bcnt);
+ }
+}
+
+static int
+collect_blocks_from_segsum(struct nilfs_sb_info *sbi, sector_t sum_blocknr,
+ struct nilfs_segsum_info *ssi,
+ struct list_head *head)
+{
+ struct buffer_head *bh;
+ unsigned int offset;
+ unsigned long nfinfo = ssi->nfinfo;
+ sector_t blocknr = sum_blocknr + ssi->nsumblk;
+ ino_t ino;
+ int err = -EIO;
+
+ if (!nfinfo)
+ return 0;
+
+ bh = sb_bread(sbi->s_super, sum_blocknr);
+ if (unlikely(!bh))
+ goto out;
+
+ offset = le16_to_cpu(
+ ((struct nilfs_segment_summary *)bh->b_data)->ss_bytes);
+ for (;;) {
+ unsigned long nblocks, ndatablk, nnodeblk;
+ struct nilfs_finfo *finfo;
+
+ finfo = segsum_get(sbi->s_super, &bh, &offset, sizeof(*finfo));
+ if (unlikely(!finfo))
+ goto out;
+
+ ino = le64_to_cpu(finfo->fi_ino);
+ nblocks = le32_to_cpu(finfo->fi_nblocks);
+ ndatablk = le32_to_cpu(finfo->fi_ndatablk);
+ nnodeblk = nblocks - ndatablk;
+
+ while (ndatablk-- > 0) {
+ struct nilfs_recovery_block *rb;
+ struct nilfs_binfo_v *binfo;
+
+ binfo = segsum_get(sbi->s_super, &bh, &offset,
+ sizeof(*binfo));
+ if (unlikely(!binfo))
+ goto out;
+
+ rb = kmalloc(sizeof(*rb), GFP_NOFS);
+ if (unlikely(!rb)) {
+ err = -ENOMEM;
+ goto out;
+ }
+ rb->ino = ino;
+ rb->blocknr = blocknr++;
+ rb->vblocknr = le64_to_cpu(binfo->bi_vblocknr);
+ rb->blkoff = le64_to_cpu(binfo->bi_blkoff);
+ /* INIT_LIST_HEAD(&rb->list); */
+ list_add_tail(&rb->list, head);
+ }
+ if (--nfinfo == 0)
+ break;
+ blocknr += nnodeblk; /* always 0 for the data sync segments */
+ segsum_skip(sbi->s_super, &bh, &offset, sizeof(__le64),
+ nnodeblk);
+ if (unlikely(!bh))
+ goto out;
+ }
+ err = 0;
+ out:
+ brelse(bh); /* brelse(NULL) is just ignored */
+ return err;
+}
+
+static void dispose_recovery_list(struct list_head *head)
+{
+ while (!list_empty(head)) {
+ struct nilfs_recovery_block *rb
+ = list_entry(head->next,
+ struct nilfs_recovery_block, list);
+ list_del(&rb->list);
+ kfree(rb);
+ }
+}
+
+void nilfs_dispose_segment_list(struct list_head *head)
+{
+ while (!list_empty(head)) {
+ struct nilfs_segment_entry *ent
+ = list_entry(head->next,
+ struct nilfs_segment_entry, list);
+ list_del(&ent->list);
+ nilfs_free_segment_entry(ent);
+ }
+}
+
+static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
+ struct nilfs_recovery_info *ri)
+{
+ struct list_head *head = &ri->ri_used_segments;
+ struct nilfs_segment_entry *ent, *n;
+ struct inode *sufile = nilfs->ns_sufile;
+ __u64 segnum[4];
+ int err;
+ int i;
+
+ segnum[0] = nilfs->ns_segnum;
+ segnum[1] = nilfs->ns_nextnum;
+ segnum[2] = ri->ri_segnum;
+ segnum[3] = ri->ri_nextnum;
+
+ /*
+ * Releasing the next segment of the latest super root.
+ * The next segment is invalidated by this recovery.
+ */
+ err = nilfs_sufile_free(sufile, segnum[1]);
+ if (unlikely(err))
+ goto failed;
+
+ err = -ENOMEM;
+ for (i = 1; i < 4; i++) {
+ ent = nilfs_alloc_segment_entry(segnum[i]);
+ if (unlikely(!ent))
+ goto failed;
+ list_add_tail(&ent->list, head);
+ }
+
+ /*
+ * Collecting segments written after the latest super root.
+ * These are marked dirty to avoid being reallocated in the next write.
+ */
+ list_for_each_entry_safe(ent, n, head, list) {
+ if (ent->segnum != segnum[0]) {
+ err = nilfs_sufile_scrap(sufile, ent->segnum);
+ if (unlikely(err))
+ goto failed;
+ }
+ list_del(&ent->list);
+ nilfs_free_segment_entry(ent);
+ }
+
+ /* Allocate new segments for recovery */
+ err = nilfs_sufile_alloc(sufile, &segnum[0]);
+ if (unlikely(err))
+ goto failed;
+
+ nilfs->ns_pseg_offset = 0;
+ nilfs->ns_seg_seq = ri->ri_seq + 2;
+ nilfs->ns_nextnum = nilfs->ns_segnum = segnum[0];
+ return 0;
+
+ failed:
+ /* No need to recover sufile because it will be destroyed on error */
+ return err;
+}
+
+static int nilfs_recovery_copy_block(struct nilfs_sb_info *sbi,
+ struct nilfs_recovery_block *rb,
+ struct page *page)
+{
+ struct buffer_head *bh_org;
+ void *kaddr;
+
+ bh_org = sb_bread(sbi->s_super, rb->blocknr);
+ if (unlikely(!bh_org))
+ return -EIO;
+
+ kaddr = kmap_atomic(page, KM_USER0);
+ memcpy(kaddr + bh_offset(bh_org), bh_org->b_data, bh_org->b_size);
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(bh_org);
+ return 0;
+}
+
+static int recover_dsync_blocks(struct nilfs_sb_info *sbi,
+ struct list_head *head,
+ unsigned long *nr_salvaged_blocks)
+{
+ struct inode *inode;
+ struct nilfs_recovery_block *rb, *n;
+ unsigned blocksize = sbi->s_super->s_blocksize;
+ struct page *page;
+ loff_t pos;
+ int err = 0, err2 = 0;
+
+ list_for_each_entry_safe(rb, n, head, list) {
+ inode = nilfs_iget(sbi->s_super, rb->ino);
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+ inode = NULL;
+ goto failed_inode;
+ }
+
+ pos = rb->blkoff << inode->i_blkbits;
+ page = NULL;
+ err = block_write_begin(NULL, inode->i_mapping, pos, blocksize,
+ 0, &page, NULL, nilfs_get_block);
+ if (unlikely(err))
+ goto failed_inode;
+
+ err = nilfs_recovery_copy_block(sbi, rb, page);
+ if (unlikely(err))
+ goto failed_page;
+
+ err = nilfs_set_file_dirty(sbi, inode, 1);
+ if (unlikely(err))
+ goto failed_page;
+
+ block_write_end(NULL, inode->i_mapping, pos, blocksize,
+ blocksize, page, NULL);
+
+ unlock_page(page);
+ page_cache_release(page);
+
+ (*nr_salvaged_blocks)++;
+ goto next;
+
+ failed_page:
+ unlock_page(page);
+ page_cache_release(page);
+
+ failed_inode:
+ printk(KERN_WARNING
+ "NILFS warning: error recovering data block "
+ "(err=%d, ino=%lu, block-offset=%llu)\n",
+ err, rb->ino, (unsigned long long)rb->blkoff);
+ if (!err2)
+ err2 = err;
+ next:
+ iput(inode); /* iput(NULL) is just ignored */
+ list_del_init(&rb->list);
+ kfree(rb);
+ }
+ return err2;
+}
+
+/**
+ * nilfs_do_roll_forward - salvage logical segments newer than the latest
+ * checkpoint
+ * @sbi: nilfs_sb_info
+ * @nilfs: the_nilfs
+ * @ri: pointer to a nilfs_recovery_info
+ */
+static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
+ struct nilfs_sb_info *sbi,
+ struct nilfs_recovery_info *ri)
+{
+ struct nilfs_segsum_info ssi;
+ sector_t pseg_start;
+ sector_t seg_start, seg_end; /* Starting/ending DBN of full segment */
+ unsigned long nsalvaged_blocks = 0;
+ u64 seg_seq;
+ __u64 segnum, nextnum = 0;
+ int empty_seg = 0;
+ int err = 0, ret;
+ LIST_HEAD(dsync_blocks); /* list of data blocks to be recovered */
+ enum {
+ RF_INIT_ST,
+ RF_DSYNC_ST, /* scanning data-sync segments */
+ };
+ int state = RF_INIT_ST;
+
+ nilfs_attach_writer(nilfs, sbi);
+ pseg_start = ri->ri_lsegs_start;
+ seg_seq = ri->ri_lsegs_start_seq;
+ segnum = nilfs_get_segnum_of_block(nilfs, pseg_start);
+ nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end);
+
+ while (segnum != ri->ri_segnum || pseg_start <= ri->ri_pseg_start) {
+
+ ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi, 1);
+ if (ret) {
+ if (ret == NILFS_SEG_FAIL_IO) {
+ err = -EIO;
+ goto failed;
+ }
+ goto strayed;
+ }
+ if (unlikely(NILFS_SEG_HAS_SR(&ssi)))
+ goto confused;
+
+ /* Found a valid partial segment; do recovery actions */
+ nextnum = nilfs_get_segnum_of_block(nilfs, ssi.next);
+ empty_seg = 0;
+ nilfs->ns_ctime = ssi.ctime;
+ if (!(ssi.flags & NILFS_SS_GC))
+ nilfs->ns_nongc_ctime = ssi.ctime;
+
+ switch (state) {
+ case RF_INIT_ST:
+ if (!NILFS_SEG_LOGBGN(&ssi) || !NILFS_SEG_DSYNC(&ssi))
+ goto try_next_pseg;
+ state = RF_DSYNC_ST;
+ /* Fall through */
+ case RF_DSYNC_ST:
+ if (!NILFS_SEG_DSYNC(&ssi))
+ goto confused;
+
+ err = collect_blocks_from_segsum(
+ sbi, pseg_start, &ssi, &dsync_blocks);
+ if (unlikely(err))
+ goto failed;
+ if (NILFS_SEG_LOGEND(&ssi)) {
+ err = recover_dsync_blocks(
+ sbi, &dsync_blocks, &nsalvaged_blocks);
+ if (unlikely(err))
+ goto failed;
+ state = RF_INIT_ST;
+ }
+ break; /* Fall through to try_next_pseg */
+ }
+
+ try_next_pseg:
+ if (pseg_start == ri->ri_lsegs_end)
+ break;
+ pseg_start += ssi.nblocks;
+ if (pseg_start < seg_end)
+ continue;
+ goto feed_segment;
+
+ strayed:
+ if (pseg_start == ri->ri_lsegs_end)
+ break;
+
+ feed_segment:
+ /* Looking to the next full segment */
+ if (empty_seg++)
+ break;
+ seg_seq++;
+ segnum = nextnum;
+ nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end);
+ pseg_start = seg_start;
+ }
+
+ if (nsalvaged_blocks) {
+ printk(KERN_INFO "NILFS (device %s): salvaged %lu blocks\n",
+ sbi->s_super->s_id, nsalvaged_blocks);
+ ri->ri_need_recovery = NILFS_RECOVERY_ROLLFORWARD_DONE;
+ }
+ out:
+ dispose_recovery_list(&dsync_blocks);
+ nilfs_detach_writer(sbi->s_nilfs, sbi);
+ return err;
+
+ confused:
+ err = -EINVAL;
+ failed:
+ printk(KERN_ERR
+ "NILFS (device %s): Error roll-forwarding "
+ "(err=%d, pseg block=%llu). ",
+ sbi->s_super->s_id, err, (unsigned long long)pseg_start);
+ goto out;
+}
+
+static void nilfs_finish_roll_forward(struct the_nilfs *nilfs,
+ struct nilfs_sb_info *sbi,
+ struct nilfs_recovery_info *ri)
+{
+ struct buffer_head *bh;
+ int err;
+
+ if (nilfs_get_segnum_of_block(nilfs, ri->ri_lsegs_start) !=
+ nilfs_get_segnum_of_block(nilfs, ri->ri_super_root))
+ return;
+
+ bh = sb_getblk(sbi->s_super, ri->ri_lsegs_start);
+ BUG_ON(!bh);
+ memset(bh->b_data, 0, bh->b_size);
+ set_buffer_dirty(bh);
+ err = sync_dirty_buffer(bh);
+ if (unlikely(err))
+ printk(KERN_WARNING
+ "NILFS warning: buffer sync write failed during "
+ "post-cleaning of recovery.\n");
+ brelse(bh);
+}
+
+/**
+ * nilfs_recover_logical_segments - salvage logical segments written after
+ * the latest super root
+ * @nilfs: the_nilfs
+ * @sbi: nilfs_sb_info
+ * @ri: pointer to a nilfs_recovery_info struct to store search results.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error code is returned.
+ *
+ * %-EINVAL - Inconsistent filesystem state.
+ *
+ * %-EIO - I/O error
+ *
+ * %-ENOSPC - No space left on device (only in a panic state).
+ *
+ * %-ERESTARTSYS - Interrupted.
+ *
+ * %-ENOMEM - Insufficient memory available.
+ */
+int nilfs_recover_logical_segments(struct the_nilfs *nilfs,
+ struct nilfs_sb_info *sbi,
+ struct nilfs_recovery_info *ri)
+{
+ int err;
+
+ if (ri->ri_lsegs_start == 0 || ri->ri_lsegs_end == 0)
+ return 0;
+
+ err = nilfs_attach_checkpoint(sbi, ri->ri_cno);
+ if (unlikely(err)) {
+ printk(KERN_ERR
+ "NILFS: error loading the latest checkpoint.\n");
+ return err;
+ }
+
+ err = nilfs_do_roll_forward(nilfs, sbi, ri);
+ if (unlikely(err))
+ goto failed;
+
+ if (ri->ri_need_recovery == NILFS_RECOVERY_ROLLFORWARD_DONE) {
+ err = nilfs_prepare_segment_for_recovery(nilfs, ri);
+ if (unlikely(err)) {
+ printk(KERN_ERR "NILFS: Error preparing segments for "
+ "recovery.\n");
+ goto failed;
+ }
+
+ err = nilfs_attach_segment_constructor(sbi);
+ if (unlikely(err))
+ goto failed;
+
+ set_nilfs_discontinued(nilfs);
+ err = nilfs_construct_segment(sbi->s_super);
+ nilfs_detach_segment_constructor(sbi);
+
+ if (unlikely(err)) {
+ printk(KERN_ERR "NILFS: Oops! recovery failed. "
+ "(err=%d)\n", err);
+ goto failed;
+ }
+
+ nilfs_finish_roll_forward(nilfs, sbi, ri);
+ }
+
+ nilfs_detach_checkpoint(sbi);
+ return 0;
+
+ failed:
+ nilfs_detach_checkpoint(sbi);
+ nilfs_mdt_clear(nilfs->ns_cpfile);
+ nilfs_mdt_clear(nilfs->ns_sufile);
+ nilfs_mdt_clear(nilfs->ns_dat);
+ return err;
+}
+
+/**
+ * nilfs_search_super_root - search the latest valid super root
+ * @nilfs: the_nilfs
+ * @sbi: nilfs_sb_info
+ * @ri: pointer to a nilfs_recovery_info struct to store search results.
+ *
+ * nilfs_search_super_root() looks for the latest super-root from a partial
+ * segment pointed by the superblock. It sets up struct the_nilfs through
+ * this search. It fills nilfs_recovery_info (ri) required for recovery.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error code is returned.
+ *
+ * %-EINVAL - No valid segment found
+ *
+ * %-EIO - I/O error
+ */
+int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
+ struct nilfs_recovery_info *ri)
+{
+ struct nilfs_segsum_info ssi;
+ sector_t pseg_start, pseg_end, sr_pseg_start = 0;
+ sector_t seg_start, seg_end; /* range of full segment (block number) */
+ u64 seg_seq;
+ __u64 segnum, nextnum = 0;
+ __u64 cno;
+ struct nilfs_segment_entry *ent;
+ LIST_HEAD(segments);
+ int empty_seg = 0, scan_newer = 0;
+ int ret;
+
+ pseg_start = nilfs->ns_last_pseg;
+ seg_seq = nilfs->ns_last_seq;
+ cno = nilfs->ns_last_cno;
+ segnum = nilfs_get_segnum_of_block(nilfs, pseg_start);
+
+ /* Calculate range of segment */
+ nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end);
+
+ for (;;) {
+ /* Load segment summary */
+ ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi, 1);
+ if (ret) {
+ if (ret == NILFS_SEG_FAIL_IO)
+ goto failed;
+ goto strayed;
+ }
+ pseg_end = pseg_start + ssi.nblocks - 1;
+ if (unlikely(pseg_end > seg_end)) {
+ ret = NILFS_SEG_FAIL_CONSISTENCY;
+ goto strayed;
+ }
+
+ /* A valid partial segment */
+ ri->ri_pseg_start = pseg_start;
+ ri->ri_seq = seg_seq;
+ ri->ri_segnum = segnum;
+ nextnum = nilfs_get_segnum_of_block(nilfs, ssi.next);
+ ri->ri_nextnum = nextnum;
+ empty_seg = 0;
+
+ if (!NILFS_SEG_HAS_SR(&ssi)) {
+ if (!scan_newer) {
+ /* This will never happen because a superblock
+ (last_segment) always points to a pseg
+ having a super root. */
+ ret = NILFS_SEG_FAIL_CONSISTENCY;
+ goto failed;
+ }
+ if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) {
+ ri->ri_lsegs_start = pseg_start;
+ ri->ri_lsegs_start_seq = seg_seq;
+ }
+ if (NILFS_SEG_LOGEND(&ssi))
+ ri->ri_lsegs_end = pseg_start;
+ goto try_next_pseg;
+ }
+
+ /* A valid super root was found. */
+ ri->ri_cno = cno++;
+ ri->ri_super_root = pseg_end;
+ ri->ri_lsegs_start = ri->ri_lsegs_end = 0;
+
+ nilfs_dispose_segment_list(&segments);
+ nilfs->ns_pseg_offset = (sr_pseg_start = pseg_start)
+ + ssi.nblocks - seg_start;
+ nilfs->ns_seg_seq = seg_seq;
+ nilfs->ns_segnum = segnum;
+ nilfs->ns_cno = cno; /* nilfs->ns_cno = ri->ri_cno + 1 */
+ nilfs->ns_ctime = ssi.ctime;
+ nilfs->ns_nextnum = nextnum;
+
+ if (scan_newer)
+ ri->ri_need_recovery = NILFS_RECOVERY_SR_UPDATED;
+ else {
+ if (nilfs->ns_mount_state & NILFS_VALID_FS)
+ goto super_root_found;
+ scan_newer = 1;
+ }
+
+ /* reset region for roll-forward */
+ pseg_start += ssi.nblocks;
+ if (pseg_start < seg_end)
+ continue;
+ goto feed_segment;
+
+ try_next_pseg:
+ /* Standing on a course, or met an inconsistent state */
+ pseg_start += ssi.nblocks;
+ if (pseg_start < seg_end)
+ continue;
+ goto feed_segment;
+
+ strayed:
+ /* Off the trail */
+ if (!scan_newer)
+ /*
+ * This can happen if a checkpoint was written without
+ * barriers, or as a result of an I/O failure.
+ */
+ goto failed;
+
+ feed_segment:
+ /* Looking to the next full segment */
+ if (empty_seg++)
+ goto super_root_found; /* found a valid super root */
+
+ ent = nilfs_alloc_segment_entry(segnum);
+ if (unlikely(!ent)) {
+ ret = -ENOMEM;
+ goto failed;
+ }
+ list_add_tail(&ent->list, &segments);
+
+ seg_seq++;
+ segnum = nextnum;
+ nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end);
+ pseg_start = seg_start;
+ }
+
+ super_root_found:
+ /* Updating pointers relating to the latest checkpoint */
+ list_splice(&segments, ri->ri_used_segments.prev);
+ nilfs->ns_last_pseg = sr_pseg_start;
+ nilfs->ns_last_seq = nilfs->ns_seg_seq;
+ nilfs->ns_last_cno = ri->ri_cno;
+ return 0;
+
+ failed:
+ nilfs_dispose_segment_list(&segments);
+ return (ret < 0) ? ret : nilfs_warn_segment_error(ret);
+}
diff --git a/fs/nilfs2/sb.h b/fs/nilfs2/sb.h
new file mode 100644
index 00000000000..adccd4fc654
--- /dev/null
+++ b/fs/nilfs2/sb.h
@@ -0,0 +1,102 @@
+/*
+ * sb.h - NILFS on-memory super block structure.
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>
+ *
+ */
+
+#ifndef _NILFS_SB
+#define _NILFS_SB
+
+#include <linux/types.h>
+#include <linux/fs.h>
+
+/*
+ * Mount options
+ */
+struct nilfs_mount_options {
+ unsigned long mount_opt;
+ __u64 snapshot_cno;
+};
+
+struct the_nilfs;
+struct nilfs_sc_info;
+
+/*
+ * NILFS super-block data in memory
+ */
+struct nilfs_sb_info {
+ /* Snapshot status */
+ __u64 s_snapshot_cno; /* Checkpoint number */
+ atomic_t s_inodes_count;
+ atomic_t s_blocks_count; /* Reserved (might be deleted) */
+
+ /* Mount options */
+ unsigned long s_mount_opt;
+ uid_t s_resuid;
+ gid_t s_resgid;
+
+ unsigned long s_interval; /* construction interval */
+ unsigned long s_watermark; /* threshold of data amount
+ for the segment construction */
+
+ /* Fundamental members */
+ struct super_block *s_super; /* reverse pointer to super_block */
+ struct the_nilfs *s_nilfs;
+ struct list_head s_list; /* list head for nilfs->ns_supers */
+
+ /* Segment constructor */
+ struct list_head s_dirty_files; /* dirty files list */
+ struct nilfs_sc_info *s_sc_info; /* segment constructor info */
+ spinlock_t s_inode_lock; /* Lock for the nilfs inode.
+ It covers s_dirty_files list */
+
+ /* Metadata files */
+ struct inode *s_ifile; /* index file inode */
+
+ /* Inode allocator */
+ spinlock_t s_next_gen_lock;
+ u32 s_next_generation;
+};
+
+static inline struct nilfs_sb_info *NILFS_SB(struct super_block *sb)
+{
+ return sb->s_fs_info;
+}
+
+static inline struct nilfs_sc_info *NILFS_SC(struct nilfs_sb_info *sbi)
+{
+ return sbi->s_sc_info;
+}
+
+/*
+ * Bit operations for the mount option
+ */
+#define nilfs_clear_opt(sbi, opt) \
+ do { (sbi)->s_mount_opt &= ~NILFS_MOUNT_##opt; } while (0)
+#define nilfs_set_opt(sbi, opt) \
+ do { (sbi)->s_mount_opt |= NILFS_MOUNT_##opt; } while (0)
+#define nilfs_test_opt(sbi, opt) ((sbi)->s_mount_opt & NILFS_MOUNT_##opt)
+#define nilfs_write_opt(sbi, mask, opt) \
+ do { (sbi)->s_mount_opt = \
+ (((sbi)->s_mount_opt & ~NILFS_MOUNT_##mask) | \
+ NILFS_MOUNT_##opt); \
+ } while (0)
+
+#endif /* _NILFS_SB */
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
new file mode 100644
index 00000000000..1e68821b4a9
--- /dev/null
+++ b/fs/nilfs2/segbuf.c
@@ -0,0 +1,439 @@
+/*
+ * segbuf.c - NILFS segment buffer
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>
+ *
+ */
+
+#include <linux/buffer_head.h>
+#include <linux/writeback.h>
+#include <linux/crc32.h>
+#include "page.h"
+#include "segbuf.h"
+#include "seglist.h"
+
+
+static struct kmem_cache *nilfs_segbuf_cachep;
+
+static void nilfs_segbuf_init_once(void *obj)
+{
+ memset(obj, 0, sizeof(struct nilfs_segment_buffer));
+}
+
+int __init nilfs_init_segbuf_cache(void)
+{
+ nilfs_segbuf_cachep =
+ kmem_cache_create("nilfs2_segbuf_cache",
+ sizeof(struct nilfs_segment_buffer),
+ 0, SLAB_RECLAIM_ACCOUNT,
+ nilfs_segbuf_init_once);
+
+ return (nilfs_segbuf_cachep == NULL) ? -ENOMEM : 0;
+}
+
+void nilfs_destroy_segbuf_cache(void)
+{
+ kmem_cache_destroy(nilfs_segbuf_cachep);
+}
+
+struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *sb)
+{
+ struct nilfs_segment_buffer *segbuf;
+
+ segbuf = kmem_cache_alloc(nilfs_segbuf_cachep, GFP_NOFS);
+ if (unlikely(!segbuf))
+ return NULL;
+
+ segbuf->sb_super = sb;
+ INIT_LIST_HEAD(&segbuf->sb_list);
+ INIT_LIST_HEAD(&segbuf->sb_segsum_buffers);
+ INIT_LIST_HEAD(&segbuf->sb_payload_buffers);
+ return segbuf;
+}
+
+void nilfs_segbuf_free(struct nilfs_segment_buffer *segbuf)
+{
+ kmem_cache_free(nilfs_segbuf_cachep, segbuf);
+}
+
+void nilfs_segbuf_map(struct nilfs_segment_buffer *segbuf, __u64 segnum,
+ unsigned long offset, struct the_nilfs *nilfs)
+{
+ segbuf->sb_segnum = segnum;
+ nilfs_get_segment_range(nilfs, segnum, &segbuf->sb_fseg_start,
+ &segbuf->sb_fseg_end);
+
+ segbuf->sb_pseg_start = segbuf->sb_fseg_start + offset;
+ segbuf->sb_rest_blocks =
+ segbuf->sb_fseg_end - segbuf->sb_pseg_start + 1;
+}
+
+void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *segbuf,
+ __u64 nextnum, struct the_nilfs *nilfs)
+{
+ segbuf->sb_nextnum = nextnum;
+ segbuf->sb_sum.next = nilfs_get_segment_start_blocknr(nilfs, nextnum);
+}
+
+int nilfs_segbuf_extend_segsum(struct nilfs_segment_buffer *segbuf)
+{
+ struct buffer_head *bh;
+
+ bh = sb_getblk(segbuf->sb_super,
+ segbuf->sb_pseg_start + segbuf->sb_sum.nsumblk);
+ if (unlikely(!bh))
+ return -ENOMEM;
+
+ nilfs_segbuf_add_segsum_buffer(segbuf, bh);
+ return 0;
+}
+
+int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *segbuf,
+ struct buffer_head **bhp)
+{
+ struct buffer_head *bh;
+
+ bh = sb_getblk(segbuf->sb_super,
+ segbuf->sb_pseg_start + segbuf->sb_sum.nblocks);
+ if (unlikely(!bh))
+ return -ENOMEM;
+
+ nilfs_segbuf_add_payload_buffer(segbuf, bh);
+ *bhp = bh;
+ return 0;
+}
+
+int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned flags,
+ time_t ctime)
+{
+ int err;
+
+ segbuf->sb_sum.nblocks = segbuf->sb_sum.nsumblk = 0;
+ err = nilfs_segbuf_extend_segsum(segbuf);
+ if (unlikely(err))
+ return err;
+
+ segbuf->sb_sum.flags = flags;
+ segbuf->sb_sum.sumbytes = sizeof(struct nilfs_segment_summary);
+ segbuf->sb_sum.nfinfo = segbuf->sb_sum.nfileblk = 0;
+ segbuf->sb_sum.ctime = ctime;
+
+ segbuf->sb_io_error = 0;
+ return 0;
+}
+
+/*
+ * Setup segument summary
+ */
+void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *segbuf)
+{
+ struct nilfs_segment_summary *raw_sum;
+ struct buffer_head *bh_sum;
+
+ bh_sum = list_entry(segbuf->sb_segsum_buffers.next,
+ struct buffer_head, b_assoc_buffers);
+ raw_sum = (struct nilfs_segment_summary *)bh_sum->b_data;
+
+ raw_sum->ss_magic = cpu_to_le32(NILFS_SEGSUM_MAGIC);
+ raw_sum->ss_bytes = cpu_to_le16(sizeof(*raw_sum));
+ raw_sum->ss_flags = cpu_to_le16(segbuf->sb_sum.flags);
+ raw_sum->ss_seq = cpu_to_le64(segbuf->sb_sum.seg_seq);
+ raw_sum->ss_create = cpu_to_le64(segbuf->sb_sum.ctime);
+ raw_sum->ss_next = cpu_to_le64(segbuf->sb_sum.next);
+ raw_sum->ss_nblocks = cpu_to_le32(segbuf->sb_sum.nblocks);
+ raw_sum->ss_nfinfo = cpu_to_le32(segbuf->sb_sum.nfinfo);
+ raw_sum->ss_sumbytes = cpu_to_le32(segbuf->sb_sum.sumbytes);
+ raw_sum->ss_pad = 0;
+}
+
+/*
+ * CRC calculation routines
+ */
+void nilfs_segbuf_fill_in_segsum_crc(struct nilfs_segment_buffer *segbuf,
+ u32 seed)
+{
+ struct buffer_head *bh;
+ struct nilfs_segment_summary *raw_sum;
+ unsigned long size, bytes = segbuf->sb_sum.sumbytes;
+ u32 crc;
+
+ bh = list_entry(segbuf->sb_segsum_buffers.next, struct buffer_head,
+ b_assoc_buffers);
+
+ raw_sum = (struct nilfs_segment_summary *)bh->b_data;
+ size = min_t(unsigned long, bytes, bh->b_size);
+ crc = crc32_le(seed,
+ (unsigned char *)raw_sum +
+ sizeof(raw_sum->ss_datasum) + sizeof(raw_sum->ss_sumsum),
+ size - (sizeof(raw_sum->ss_datasum) +
+ sizeof(raw_sum->ss_sumsum)));
+
+ list_for_each_entry_continue(bh, &segbuf->sb_segsum_buffers,
+ b_assoc_buffers) {
+ bytes -= size;
+ size = min_t(unsigned long, bytes, bh->b_size);
+ crc = crc32_le(crc, bh->b_data, size);
+ }
+ raw_sum->ss_sumsum = cpu_to_le32(crc);
+}
+
+void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *segbuf,
+ u32 seed)
+{
+ struct buffer_head *bh;
+ struct nilfs_segment_summary *raw_sum;
+ void *kaddr;
+ u32 crc;
+
+ bh = list_entry(segbuf->sb_segsum_buffers.next, struct buffer_head,
+ b_assoc_buffers);
+ raw_sum = (struct nilfs_segment_summary *)bh->b_data;
+ crc = crc32_le(seed,
+ (unsigned char *)raw_sum + sizeof(raw_sum->ss_datasum),
+ bh->b_size - sizeof(raw_sum->ss_datasum));
+
+ list_for_each_entry_continue(bh, &segbuf->sb_segsum_buffers,
+ b_assoc_buffers) {
+ crc = crc32_le(crc, bh->b_data, bh->b_size);
+ }
+ list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) {
+ kaddr = kmap_atomic(bh->b_page, KM_USER0);
+ crc = crc32_le(crc, kaddr + bh_offset(bh), bh->b_size);
+ kunmap_atomic(kaddr, KM_USER0);
+ }
+ raw_sum->ss_datasum = cpu_to_le32(crc);
+}
+
+void nilfs_release_buffers(struct list_head *list)
+{
+ struct buffer_head *bh, *n;
+
+ list_for_each_entry_safe(bh, n, list, b_assoc_buffers) {
+ list_del_init(&bh->b_assoc_buffers);
+ if (buffer_nilfs_allocated(bh)) {
+ struct page *clone_page = bh->b_page;
+
+ /* remove clone page */
+ brelse(bh);
+ page_cache_release(clone_page); /* for each bh */
+ if (page_count(clone_page) <= 2) {
+ lock_page(clone_page);
+ nilfs_free_private_page(clone_page);
+ }
+ continue;
+ }
+ brelse(bh);
+ }
+}
+
+/*
+ * BIO operations
+ */
+static void nilfs_end_bio_write(struct bio *bio, int err)
+{
+ const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
+ struct nilfs_write_info *wi = bio->bi_private;
+
+ if (err == -EOPNOTSUPP) {
+ set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
+ bio_put(bio);
+ /* to be detected by submit_seg_bio() */
+ }
+
+ if (!uptodate)
+ atomic_inc(&wi->err);
+
+ bio_put(bio);
+ complete(&wi->bio_event);
+}
+
+static int nilfs_submit_seg_bio(struct nilfs_write_info *wi, int mode)
+{
+ struct bio *bio = wi->bio;
+ int err;
+
+ if (wi->nbio > 0 && bdi_write_congested(wi->bdi)) {
+ wait_for_completion(&wi->bio_event);
+ wi->nbio--;
+ if (unlikely(atomic_read(&wi->err))) {
+ bio_put(bio);
+ err = -EIO;
+ goto failed;
+ }
+ }
+
+ bio->bi_end_io = nilfs_end_bio_write;
+ bio->bi_private = wi;
+ bio_get(bio);
+ submit_bio(mode, bio);
+ if (bio_flagged(bio, BIO_EOPNOTSUPP)) {
+ bio_put(bio);
+ err = -EOPNOTSUPP;
+ goto failed;
+ }
+ wi->nbio++;
+ bio_put(bio);
+
+ wi->bio = NULL;
+ wi->rest_blocks -= wi->end - wi->start;
+ wi->nr_vecs = min(wi->max_pages, wi->rest_blocks);
+ wi->start = wi->end;
+ return 0;
+
+ failed:
+ wi->bio = NULL;
+ return err;
+}
+
+/**
+ * nilfs_alloc_seg_bio - allocate a bio for writing segment.
+ * @sb: super block
+ * @start: beginning disk block number of this BIO.
+ * @nr_vecs: request size of page vector.
+ *
+ * alloc_seg_bio() allocates a new BIO structure and initialize it.
+ *
+ * Return Value: On success, pointer to the struct bio is returned.
+ * On error, NULL is returned.
+ */
+static struct bio *nilfs_alloc_seg_bio(struct super_block *sb, sector_t start,
+ int nr_vecs)
+{
+ struct bio *bio;
+
+ bio = bio_alloc(GFP_NOWAIT, nr_vecs);
+ if (bio == NULL) {
+ while (!bio && (nr_vecs >>= 1))
+ bio = bio_alloc(GFP_NOWAIT, nr_vecs);
+ }
+ if (likely(bio)) {
+ bio->bi_bdev = sb->s_bdev;
+ bio->bi_sector = (sector_t)start << (sb->s_blocksize_bits - 9);
+ }
+ return bio;
+}
+
+void nilfs_segbuf_prepare_write(struct nilfs_segment_buffer *segbuf,
+ struct nilfs_write_info *wi)
+{
+ wi->bio = NULL;
+ wi->rest_blocks = segbuf->sb_sum.nblocks;
+ wi->max_pages = bio_get_nr_vecs(wi->sb->s_bdev);
+ wi->nr_vecs = min(wi->max_pages, wi->rest_blocks);
+ wi->start = wi->end = 0;
+ wi->nbio = 0;
+ wi->blocknr = segbuf->sb_pseg_start;
+
+ atomic_set(&wi->err, 0);
+ init_completion(&wi->bio_event);
+}
+
+static int nilfs_submit_bh(struct nilfs_write_info *wi, struct buffer_head *bh,
+ int mode)
+{
+ int len, err;
+
+ BUG_ON(wi->nr_vecs <= 0);
+ repeat:
+ if (!wi->bio) {
+ wi->bio = nilfs_alloc_seg_bio(wi->sb, wi->blocknr + wi->end,
+ wi->nr_vecs);
+ if (unlikely(!wi->bio))
+ return -ENOMEM;
+ }
+
+ len = bio_add_page(wi->bio, bh->b_page, bh->b_size, bh_offset(bh));
+ if (len == bh->b_size) {
+ wi->end++;
+ return 0;
+ }
+ /* bio is FULL */
+ err = nilfs_submit_seg_bio(wi, mode);
+ /* never submit current bh */
+ if (likely(!err))
+ goto repeat;
+ return err;
+}
+
+int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
+ struct nilfs_write_info *wi)
+{
+ struct buffer_head *bh;
+ int res, rw = WRITE;
+
+ list_for_each_entry(bh, &segbuf->sb_segsum_buffers, b_assoc_buffers) {
+ res = nilfs_submit_bh(wi, bh, rw);
+ if (unlikely(res))
+ goto failed_bio;
+ }
+
+ list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) {
+ res = nilfs_submit_bh(wi, bh, rw);
+ if (unlikely(res))
+ goto failed_bio;
+ }
+
+ if (wi->bio) {
+ /*
+ * Last BIO is always sent through the following
+ * submission.
+ */
+ rw |= (1 << BIO_RW_SYNCIO);
+ res = nilfs_submit_seg_bio(wi, rw);
+ if (unlikely(res))
+ goto failed_bio;
+ }
+
+ res = 0;
+ out:
+ return res;
+
+ failed_bio:
+ atomic_inc(&wi->err);
+ goto out;
+}
+
+/**
+ * nilfs_segbuf_wait - wait for completion of requested BIOs
+ * @wi: nilfs_write_info
+ *
+ * Return Value: On Success, 0 is returned. On Error, one of the following
+ * negative error code is returned.
+ *
+ * %-EIO - I/O error
+ */
+int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf,
+ struct nilfs_write_info *wi)
+{
+ int err = 0;
+
+ if (!wi->nbio)
+ return 0;
+
+ do {
+ wait_for_completion(&wi->bio_event);
+ } while (--wi->nbio > 0);
+
+ if (unlikely(atomic_read(&wi->err) > 0)) {
+ printk(KERN_ERR "NILFS: IO error writing segment\n");
+ err = -EIO;
+ segbuf->sb_io_error = 1;
+ }
+ return err;
+}
diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h
new file mode 100644
index 00000000000..0c3076f4e59
--- /dev/null
+++ b/fs/nilfs2/segbuf.h
@@ -0,0 +1,201 @@
+/*
+ * segbuf.h - NILFS Segment buffer prototypes and definitions
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>
+ *
+ */
+#ifndef _NILFS_SEGBUF_H
+#define _NILFS_SEGBUF_H
+
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/bio.h>
+#include <linux/completion.h>
+#include <linux/backing-dev.h>
+
+/**
+ * struct nilfs_segsum_info - On-memory segment summary
+ * @flags: Flags
+ * @nfinfo: Number of file information structures
+ * @nblocks: Number of blocks included in the partial segment
+ * @nsumblk: Number of summary blocks
+ * @sumbytes: Byte count of segment summary
+ * @nfileblk: Total number of file blocks
+ * @seg_seq: Segment sequence number
+ * @ctime: Creation time
+ * @next: Block number of the next full segment
+ */
+struct nilfs_segsum_info {
+ unsigned int flags;
+ unsigned long nfinfo;
+ unsigned long nblocks;
+ unsigned long nsumblk;
+ unsigned long sumbytes;
+ unsigned long nfileblk;
+ u64 seg_seq;
+ time_t ctime;
+ sector_t next;
+};
+
+/* macro for the flags */
+#define NILFS_SEG_HAS_SR(sum) ((sum)->flags & NILFS_SS_SR)
+#define NILFS_SEG_LOGBGN(sum) ((sum)->flags & NILFS_SS_LOGBGN)
+#define NILFS_SEG_LOGEND(sum) ((sum)->flags & NILFS_SS_LOGEND)
+#define NILFS_SEG_DSYNC(sum) ((sum)->flags & NILFS_SS_SYNDT)
+#define NILFS_SEG_SIMPLEX(sum) \
+ (((sum)->flags & (NILFS_SS_LOGBGN | NILFS_SS_LOGEND)) == \
+ (NILFS_SS_LOGBGN | NILFS_SS_LOGEND))
+
+#define NILFS_SEG_EMPTY(sum) ((sum)->nblocks == (sum)->nsumblk)
+
+/**
+ * struct nilfs_segment_buffer - Segment buffer
+ * @sb_super: back pointer to a superblock struct
+ * @sb_list: List head to chain this structure
+ * @sb_sum: On-memory segment summary
+ * @sb_segnum: Index number of the full segment
+ * @sb_nextnum: Index number of the next full segment
+ * @sb_fseg_start: Start block number of the full segment
+ * @sb_fseg_end: End block number of the full segment
+ * @sb_pseg_start: Disk block number of partial segment
+ * @sb_rest_blocks: Number of residual blocks in the current segment
+ * @sb_segsum_buffers: List of buffers for segment summaries
+ * @sb_payload_buffers: List of buffers for segment payload
+ * @sb_io_error: I/O error status
+ */
+struct nilfs_segment_buffer {
+ struct super_block *sb_super;
+ struct list_head sb_list;
+
+ /* Segment information */
+ struct nilfs_segsum_info sb_sum;
+ __u64 sb_segnum;
+ __u64 sb_nextnum;
+ sector_t sb_fseg_start, sb_fseg_end;
+ sector_t sb_pseg_start;
+ unsigned sb_rest_blocks;
+
+ /* Buffers */
+ struct list_head sb_segsum_buffers;
+ struct list_head sb_payload_buffers; /* including super root */
+
+ /* io status */
+ int sb_io_error;
+};
+
+#define NILFS_LIST_SEGBUF(head) \
+ list_entry((head), struct nilfs_segment_buffer, sb_list)
+#define NILFS_NEXT_SEGBUF(segbuf) NILFS_LIST_SEGBUF((segbuf)->sb_list.next)
+#define NILFS_PREV_SEGBUF(segbuf) NILFS_LIST_SEGBUF((segbuf)->sb_list.prev)
+#define NILFS_LAST_SEGBUF(head) NILFS_LIST_SEGBUF((head)->prev)
+#define NILFS_FIRST_SEGBUF(head) NILFS_LIST_SEGBUF((head)->next)
+#define NILFS_SEGBUF_IS_LAST(segbuf, head) ((segbuf)->sb_list.next == (head))
+
+#define nilfs_for_each_segbuf_before(s, t, h) \
+ for ((s) = NILFS_FIRST_SEGBUF(h); (s) != (t); \
+ (s) = NILFS_NEXT_SEGBUF(s))
+
+#define NILFS_SEGBUF_FIRST_BH(head) \
+ (list_entry((head)->next, struct buffer_head, b_assoc_buffers))
+#define NILFS_SEGBUF_NEXT_BH(bh) \
+ (list_entry((bh)->b_assoc_buffers.next, struct buffer_head, \
+ b_assoc_buffers))
+#define NILFS_SEGBUF_BH_IS_LAST(bh, head) ((bh)->b_assoc_buffers.next == head)
+
+
+int __init nilfs_init_segbuf_cache(void);
+void nilfs_destroy_segbuf_cache(void);
+struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *);
+void nilfs_segbuf_free(struct nilfs_segment_buffer *);
+void nilfs_segbuf_map(struct nilfs_segment_buffer *, __u64, unsigned long,
+ struct the_nilfs *);
+void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64,
+ struct the_nilfs *);
+int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned, time_t);
+int nilfs_segbuf_extend_segsum(struct nilfs_segment_buffer *);
+int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *,
+ struct buffer_head **);
+void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *);
+void nilfs_segbuf_fill_in_segsum_crc(struct nilfs_segment_buffer *, u32);
+void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *, u32);
+
+static inline void
+nilfs_segbuf_add_segsum_buffer(struct nilfs_segment_buffer *segbuf,
+ struct buffer_head *bh)
+{
+ list_add_tail(&bh->b_assoc_buffers, &segbuf->sb_segsum_buffers);
+ segbuf->sb_sum.nblocks++;
+ segbuf->sb_sum.nsumblk++;
+}
+
+static inline void
+nilfs_segbuf_add_payload_buffer(struct nilfs_segment_buffer *segbuf,
+ struct buffer_head *bh)
+{
+ list_add_tail(&bh->b_assoc_buffers, &segbuf->sb_payload_buffers);
+ segbuf->sb_sum.nblocks++;
+}
+
+static inline void
+nilfs_segbuf_add_file_buffer(struct nilfs_segment_buffer *segbuf,
+ struct buffer_head *bh)
+{
+ get_bh(bh);
+ nilfs_segbuf_add_payload_buffer(segbuf, bh);
+ segbuf->sb_sum.nfileblk++;
+}
+
+void nilfs_release_buffers(struct list_head *);
+
+static inline void nilfs_segbuf_clear(struct nilfs_segment_buffer *segbuf)
+{
+ nilfs_release_buffers(&segbuf->sb_segsum_buffers);
+ nilfs_release_buffers(&segbuf->sb_payload_buffers);
+}
+
+struct nilfs_write_info {
+ struct bio *bio;
+ int start, end; /* The region to be submitted */
+ int rest_blocks;
+ int max_pages;
+ int nr_vecs;
+ sector_t blocknr;
+
+ int nbio;
+ atomic_t err;
+ struct completion bio_event;
+ /* completion event of segment write */
+
+ /*
+ * The following fields must be set explicitly
+ */
+ struct super_block *sb;
+ struct backing_dev_info *bdi; /* backing dev info */
+ struct buffer_head *bh_sr;
+};
+
+
+void nilfs_segbuf_prepare_write(struct nilfs_segment_buffer *,
+ struct nilfs_write_info *);
+int nilfs_segbuf_write(struct nilfs_segment_buffer *,
+ struct nilfs_write_info *);
+int nilfs_segbuf_wait(struct nilfs_segment_buffer *,
+ struct nilfs_write_info *);
+
+#endif /* _NILFS_SEGBUF_H */
diff --git a/fs/nilfs2/seglist.h b/fs/nilfs2/seglist.h
new file mode 100644
index 00000000000..d39df9144e9
--- /dev/null
+++ b/fs/nilfs2/seglist.h
@@ -0,0 +1,85 @@
+/*
+ * seglist.h - expediential structure and routines to handle list of segments
+ * (would be removed in a future release)
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>
+ *
+ */
+#ifndef _NILFS_SEGLIST_H
+#define _NILFS_SEGLIST_H
+
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/nilfs2_fs.h>
+#include "sufile.h"
+
+struct nilfs_segment_entry {
+ __u64 segnum;
+
+#define NILFS_SLH_FREED 0x0001 /* The segment was freed provisonally.
+ It must be cancelled if
+ construction aborted */
+
+ unsigned flags;
+ struct list_head list;
+ struct buffer_head *bh_su;
+ struct nilfs_segment_usage *raw_su;
+};
+
+
+void nilfs_dispose_segment_list(struct list_head *);
+
+static inline struct nilfs_segment_entry *
+nilfs_alloc_segment_entry(__u64 segnum)
+{
+ struct nilfs_segment_entry *ent = kmalloc(sizeof(*ent), GFP_NOFS);
+
+ if (likely(ent)) {
+ ent->segnum = segnum;
+ ent->flags = 0;
+ ent->bh_su = NULL;
+ ent->raw_su = NULL;
+ INIT_LIST_HEAD(&ent->list);
+ }
+ return ent;
+}
+
+static inline int nilfs_open_segment_entry(struct nilfs_segment_entry *ent,
+ struct inode *sufile)
+{
+ return nilfs_sufile_get_segment_usage(sufile, ent->segnum,
+ &ent->raw_su, &ent->bh_su);
+}
+
+static inline void nilfs_close_segment_entry(struct nilfs_segment_entry *ent,
+ struct inode *sufile)
+{
+ if (!ent->bh_su)
+ return;
+ nilfs_sufile_put_segment_usage(sufile, ent->segnum, ent->bh_su);
+ ent->bh_su = NULL;
+ ent->raw_su = NULL;
+}
+
+static inline void nilfs_free_segment_entry(struct nilfs_segment_entry *ent)
+{
+ kfree(ent);
+}
+
+#endif /* _NILFS_SEGLIST_H */
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
new file mode 100644
index 00000000000..fb70ec3be20
--- /dev/null
+++ b/fs/nilfs2/segment.c
@@ -0,0 +1,2977 @@
+/*
+ * segment.c - NILFS segment constructor.
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>
+ *
+ */
+
+#include <linux/pagemap.h>
+#include <linux/buffer_head.h>
+#include <linux/writeback.h>
+#include <linux/bio.h>
+#include <linux/completion.h>
+#include <linux/blkdev.h>
+#include <linux/backing-dev.h>
+#include <linux/freezer.h>
+#include <linux/kthread.h>
+#include <linux/crc32.h>
+#include <linux/pagevec.h>
+#include "nilfs.h"
+#include "btnode.h"
+#include "page.h"
+#include "segment.h"
+#include "sufile.h"
+#include "cpfile.h"
+#include "ifile.h"
+#include "seglist.h"
+#include "segbuf.h"
+
+
+/*
+ * Segment constructor
+ */
+#define SC_N_INODEVEC 16 /* Size of locally allocated inode vector */
+
+#define SC_MAX_SEGDELTA 64 /* Upper limit of the number of segments
+ appended in collection retry loop */
+
+/* Construction mode */
+enum {
+ SC_LSEG_SR = 1, /* Make a logical segment having a super root */
+ SC_LSEG_DSYNC, /* Flush data blocks of a given file and make
+ a logical segment without a super root */
+ SC_FLUSH_FILE, /* Flush data files, leads to segment writes without
+ creating a checkpoint */
+ SC_FLUSH_DAT, /* Flush DAT file. This also creates segments without
+ a checkpoint */
+};
+
+/* Stage numbers of dirty block collection */
+enum {
+ NILFS_ST_INIT = 0,
+ NILFS_ST_GC, /* Collecting dirty blocks for GC */
+ NILFS_ST_FILE,
+ NILFS_ST_IFILE,
+ NILFS_ST_CPFILE,
+ NILFS_ST_SUFILE,
+ NILFS_ST_DAT,
+ NILFS_ST_SR, /* Super root */
+ NILFS_ST_DSYNC, /* Data sync blocks */
+ NILFS_ST_DONE,
+};
+
+/* State flags of collection */
+#define NILFS_CF_NODE 0x0001 /* Collecting node blocks */
+#define NILFS_CF_IFILE_STARTED 0x0002 /* IFILE stage has started */
+#define NILFS_CF_HISTORY_MASK (NILFS_CF_IFILE_STARTED)
+
+/* Operations depending on the construction mode and file type */
+struct nilfs_sc_operations {
+ int (*collect_data)(struct nilfs_sc_info *, struct buffer_head *,
+ struct inode *);
+ int (*collect_node)(struct nilfs_sc_info *, struct buffer_head *,
+ struct inode *);
+ int (*collect_bmap)(struct nilfs_sc_info *, struct buffer_head *,
+ struct inode *);
+ void (*write_data_binfo)(struct nilfs_sc_info *,
+ struct nilfs_segsum_pointer *,
+ union nilfs_binfo *);
+ void (*write_node_binfo)(struct nilfs_sc_info *,
+ struct nilfs_segsum_pointer *,
+ union nilfs_binfo *);
+};
+
+/*
+ * Other definitions
+ */
+static void nilfs_segctor_start_timer(struct nilfs_sc_info *);
+static void nilfs_segctor_do_flush(struct nilfs_sc_info *, int);
+static void nilfs_segctor_do_immediate_flush(struct nilfs_sc_info *);
+static void nilfs_dispose_list(struct nilfs_sb_info *, struct list_head *,
+ int);
+
+#define nilfs_cnt32_gt(a, b) \
+ (typecheck(__u32, a) && typecheck(__u32, b) && \
+ ((__s32)(b) - (__s32)(a) < 0))
+#define nilfs_cnt32_ge(a, b) \
+ (typecheck(__u32, a) && typecheck(__u32, b) && \
+ ((__s32)(a) - (__s32)(b) >= 0))
+#define nilfs_cnt32_lt(a, b) nilfs_cnt32_gt(b, a)
+#define nilfs_cnt32_le(a, b) nilfs_cnt32_ge(b, a)
+
+/*
+ * Transaction
+ */
+static struct kmem_cache *nilfs_transaction_cachep;
+
+/**
+ * nilfs_init_transaction_cache - create a cache for nilfs_transaction_info
+ *
+ * nilfs_init_transaction_cache() creates a slab cache for the struct
+ * nilfs_transaction_info.
+ *
+ * Return Value: On success, it returns 0. On error, one of the following
+ * negative error code is returned.
+ *
+ * %-ENOMEM - Insufficient memory available.
+ */
+int nilfs_init_transaction_cache(void)
+{
+ nilfs_transaction_cachep =
+ kmem_cache_create("nilfs2_transaction_cache",
+ sizeof(struct nilfs_transaction_info),
+ 0, SLAB_RECLAIM_ACCOUNT, NULL);
+ return (nilfs_transaction_cachep == NULL) ? -ENOMEM : 0;
+}
+
+/**
+ * nilfs_detroy_transaction_cache - destroy the cache for transaction info
+ *
+ * nilfs_destroy_transaction_cache() frees the slab cache for the struct
+ * nilfs_transaction_info.
+ */
+void nilfs_destroy_transaction_cache(void)
+{
+ kmem_cache_destroy(nilfs_transaction_cachep);
+}
+
+static int nilfs_prepare_segment_lock(struct nilfs_transaction_info *ti)
+{
+ struct nilfs_transaction_info *cur_ti = current->journal_info;
+ void *save = NULL;
+
+ if (cur_ti) {
+ if (cur_ti->ti_magic == NILFS_TI_MAGIC)
+ return ++cur_ti->ti_count;
+ else {
+ /*
+ * If journal_info field is occupied by other FS,
+ * it is saved and will be restored on
+ * nilfs_transaction_commit().
+ */
+ printk(KERN_WARNING
+ "NILFS warning: journal info from a different "
+ "FS\n");
+ save = current->journal_info;
+ }
+ }
+ if (!ti) {
+ ti = kmem_cache_alloc(nilfs_transaction_cachep, GFP_NOFS);
+ if (!ti)
+ return -ENOMEM;
+ ti->ti_flags = NILFS_TI_DYNAMIC_ALLOC;
+ } else {
+ ti->ti_flags = 0;
+ }
+ ti->ti_count = 0;
+ ti->ti_save = save;
+ ti->ti_magic = NILFS_TI_MAGIC;
+ current->journal_info = ti;
+ return 0;
+}
+
+/**
+ * nilfs_transaction_begin - start indivisible file operations.
+ * @sb: super block
+ * @ti: nilfs_transaction_info
+ * @vacancy_check: flags for vacancy rate checks
+ *
+ * nilfs_transaction_begin() acquires a reader/writer semaphore, called
+ * the segment semaphore, to make a segment construction and write tasks
+ * exclusive. The function is used with nilfs_transaction_commit() in pairs.
+ * The region enclosed by these two functions can be nested. To avoid a
+ * deadlock, the semaphore is only acquired or released in the outermost call.
+ *
+ * This function allocates a nilfs_transaction_info struct to keep context
+ * information on it. It is initialized and hooked onto the current task in
+ * the outermost call. If a pre-allocated struct is given to @ti, it is used
+ * instead; othewise a new struct is assigned from a slab.
+ *
+ * When @vacancy_check flag is set, this function will check the amount of
+ * free space, and will wait for the GC to reclaim disk space if low capacity.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error code is returned.
+ *
+ * %-ENOMEM - Insufficient memory available.
+ *
+ * %-ENOSPC - No space left on device
+ */
+int nilfs_transaction_begin(struct super_block *sb,
+ struct nilfs_transaction_info *ti,
+ int vacancy_check)
+{
+ struct nilfs_sb_info *sbi;
+ struct the_nilfs *nilfs;
+ int ret = nilfs_prepare_segment_lock(ti);
+
+ if (unlikely(ret < 0))
+ return ret;
+ if (ret > 0)
+ return 0;
+
+ sbi = NILFS_SB(sb);
+ nilfs = sbi->s_nilfs;
+ down_read(&nilfs->ns_segctor_sem);
+ if (vacancy_check && nilfs_near_disk_full(nilfs)) {
+ up_read(&nilfs->ns_segctor_sem);
+ ret = -ENOSPC;
+ goto failed;
+ }
+ return 0;
+
+ failed:
+ ti = current->journal_info;
+ current->journal_info = ti->ti_save;
+ if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC)
+ kmem_cache_free(nilfs_transaction_cachep, ti);
+ return ret;
+}
+
+/**
+ * nilfs_transaction_commit - commit indivisible file operations.
+ * @sb: super block
+ *
+ * nilfs_transaction_commit() releases the read semaphore which is
+ * acquired by nilfs_transaction_begin(). This is only performed
+ * in outermost call of this function. If a commit flag is set,
+ * nilfs_transaction_commit() sets a timer to start the segment
+ * constructor. If a sync flag is set, it starts construction
+ * directly.
+ */
+int nilfs_transaction_commit(struct super_block *sb)
+{
+ struct nilfs_transaction_info *ti = current->journal_info;
+ struct nilfs_sb_info *sbi;
+ struct nilfs_sc_info *sci;
+ int err = 0;
+
+ BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC);
+ ti->ti_flags |= NILFS_TI_COMMIT;
+ if (ti->ti_count > 0) {
+ ti->ti_count--;
+ return 0;
+ }
+ sbi = NILFS_SB(sb);
+ sci = NILFS_SC(sbi);
+ if (sci != NULL) {
+ if (ti->ti_flags & NILFS_TI_COMMIT)
+ nilfs_segctor_start_timer(sci);
+ if (atomic_read(&sbi->s_nilfs->ns_ndirtyblks) >
+ sci->sc_watermark)
+ nilfs_segctor_do_flush(sci, 0);
+ }
+ up_read(&sbi->s_nilfs->ns_segctor_sem);
+ current->journal_info = ti->ti_save;
+
+ if (ti->ti_flags & NILFS_TI_SYNC)
+ err = nilfs_construct_segment(sb);
+ if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC)
+ kmem_cache_free(nilfs_transaction_cachep, ti);
+ return err;
+}
+
+void nilfs_transaction_abort(struct super_block *sb)
+{
+ struct nilfs_transaction_info *ti = current->journal_info;
+
+ BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC);
+ if (ti->ti_count > 0) {
+ ti->ti_count--;
+ return;
+ }
+ up_read(&NILFS_SB(sb)->s_nilfs->ns_segctor_sem);
+
+ current->journal_info = ti->ti_save;
+ if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC)
+ kmem_cache_free(nilfs_transaction_cachep, ti);
+}
+
+void nilfs_relax_pressure_in_lock(struct super_block *sb)
+{
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ struct nilfs_sc_info *sci = NILFS_SC(sbi);
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+
+ if (!sci || !sci->sc_flush_request)
+ return;
+
+ set_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags);
+ up_read(&nilfs->ns_segctor_sem);
+
+ down_write(&nilfs->ns_segctor_sem);
+ if (sci->sc_flush_request &&
+ test_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags)) {
+ struct nilfs_transaction_info *ti = current->journal_info;
+
+ ti->ti_flags |= NILFS_TI_WRITER;
+ nilfs_segctor_do_immediate_flush(sci);
+ ti->ti_flags &= ~NILFS_TI_WRITER;
+ }
+ downgrade_write(&nilfs->ns_segctor_sem);
+}
+
+static void nilfs_transaction_lock(struct nilfs_sb_info *sbi,
+ struct nilfs_transaction_info *ti,
+ int gcflag)
+{
+ struct nilfs_transaction_info *cur_ti = current->journal_info;
+
+ WARN_ON(cur_ti);
+ ti->ti_flags = NILFS_TI_WRITER;
+ ti->ti_count = 0;
+ ti->ti_save = cur_ti;
+ ti->ti_magic = NILFS_TI_MAGIC;
+ INIT_LIST_HEAD(&ti->ti_garbage);
+ current->journal_info = ti;
+
+ for (;;) {
+ down_write(&sbi->s_nilfs->ns_segctor_sem);
+ if (!test_bit(NILFS_SC_PRIOR_FLUSH, &NILFS_SC(sbi)->sc_flags))
+ break;
+
+ nilfs_segctor_do_immediate_flush(NILFS_SC(sbi));
+
+ up_write(&sbi->s_nilfs->ns_segctor_sem);
+ yield();
+ }
+ if (gcflag)
+ ti->ti_flags |= NILFS_TI_GC;
+}
+
+static void nilfs_transaction_unlock(struct nilfs_sb_info *sbi)
+{
+ struct nilfs_transaction_info *ti = current->journal_info;
+
+ BUG_ON(ti == NULL || ti->ti_magic != NILFS_TI_MAGIC);
+ BUG_ON(ti->ti_count > 0);
+
+ up_write(&sbi->s_nilfs->ns_segctor_sem);
+ current->journal_info = ti->ti_save;
+ if (!list_empty(&ti->ti_garbage))
+ nilfs_dispose_list(sbi, &ti->ti_garbage, 0);
+}
+
+static void *nilfs_segctor_map_segsum_entry(struct nilfs_sc_info *sci,
+ struct nilfs_segsum_pointer *ssp,
+ unsigned bytes)
+{
+ struct nilfs_segment_buffer *segbuf = sci->sc_curseg;
+ unsigned blocksize = sci->sc_super->s_blocksize;
+ void *p;
+
+ if (unlikely(ssp->offset + bytes > blocksize)) {
+ ssp->offset = 0;
+ BUG_ON(NILFS_SEGBUF_BH_IS_LAST(ssp->bh,
+ &segbuf->sb_segsum_buffers));
+ ssp->bh = NILFS_SEGBUF_NEXT_BH(ssp->bh);
+ }
+ p = ssp->bh->b_data + ssp->offset;
+ ssp->offset += bytes;
+ return p;
+}
+
+/**
+ * nilfs_segctor_reset_segment_buffer - reset the current segment buffer
+ * @sci: nilfs_sc_info
+ */
+static int nilfs_segctor_reset_segment_buffer(struct nilfs_sc_info *sci)
+{
+ struct nilfs_segment_buffer *segbuf = sci->sc_curseg;
+ struct buffer_head *sumbh;
+ unsigned sumbytes;
+ unsigned flags = 0;
+ int err;
+
+ if (nilfs_doing_gc())
+ flags = NILFS_SS_GC;
+ err = nilfs_segbuf_reset(segbuf, flags, sci->sc_seg_ctime);
+ if (unlikely(err))
+ return err;
+
+ sumbh = NILFS_SEGBUF_FIRST_BH(&segbuf->sb_segsum_buffers);
+ sumbytes = segbuf->sb_sum.sumbytes;
+ sci->sc_finfo_ptr.bh = sumbh; sci->sc_finfo_ptr.offset = sumbytes;
+ sci->sc_binfo_ptr.bh = sumbh; sci->sc_binfo_ptr.offset = sumbytes;
+ sci->sc_blk_cnt = sci->sc_datablk_cnt = 0;
+ return 0;
+}
+
+static int nilfs_segctor_feed_segment(struct nilfs_sc_info *sci)
+{
+ sci->sc_nblk_this_inc += sci->sc_curseg->sb_sum.nblocks;
+ if (NILFS_SEGBUF_IS_LAST(sci->sc_curseg, &sci->sc_segbufs))
+ return -E2BIG; /* The current segment is filled up
+ (internal code) */
+ sci->sc_curseg = NILFS_NEXT_SEGBUF(sci->sc_curseg);
+ return nilfs_segctor_reset_segment_buffer(sci);
+}
+
+static int nilfs_segctor_add_super_root(struct nilfs_sc_info *sci)
+{
+ struct nilfs_segment_buffer *segbuf = sci->sc_curseg;
+ int err;
+
+ if (segbuf->sb_sum.nblocks >= segbuf->sb_rest_blocks) {
+ err = nilfs_segctor_feed_segment(sci);
+ if (err)
+ return err;
+ segbuf = sci->sc_curseg;
+ }
+ err = nilfs_segbuf_extend_payload(segbuf, &sci->sc_super_root);
+ if (likely(!err))
+ segbuf->sb_sum.flags |= NILFS_SS_SR;
+ return err;
+}
+
+/*
+ * Functions for making segment summary and payloads
+ */
+static int nilfs_segctor_segsum_block_required(
+ struct nilfs_sc_info *sci, const struct nilfs_segsum_pointer *ssp,
+ unsigned binfo_size)
+{
+ unsigned blocksize = sci->sc_super->s_blocksize;
+ /* Size of finfo and binfo is enough small against blocksize */
+
+ return ssp->offset + binfo_size +
+ (!sci->sc_blk_cnt ? sizeof(struct nilfs_finfo) : 0) >
+ blocksize;
+}
+
+static void nilfs_segctor_begin_finfo(struct nilfs_sc_info *sci,
+ struct inode *inode)
+{
+ sci->sc_curseg->sb_sum.nfinfo++;
+ sci->sc_binfo_ptr = sci->sc_finfo_ptr;
+ nilfs_segctor_map_segsum_entry(
+ sci, &sci->sc_binfo_ptr, sizeof(struct nilfs_finfo));
+
+ if (inode->i_sb && !test_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags))
+ set_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
+ /* skip finfo */
+}
+
+static void nilfs_segctor_end_finfo(struct nilfs_sc_info *sci,
+ struct inode *inode)
+{
+ struct nilfs_finfo *finfo;
+ struct nilfs_inode_info *ii;
+ struct nilfs_segment_buffer *segbuf;
+
+ if (sci->sc_blk_cnt == 0)
+ return;
+
+ ii = NILFS_I(inode);
+ finfo = nilfs_segctor_map_segsum_entry(sci, &sci->sc_finfo_ptr,
+ sizeof(*finfo));
+ finfo->fi_ino = cpu_to_le64(inode->i_ino);
+ finfo->fi_nblocks = cpu_to_le32(sci->sc_blk_cnt);
+ finfo->fi_ndatablk = cpu_to_le32(sci->sc_datablk_cnt);
+ finfo->fi_cno = cpu_to_le64(ii->i_cno);
+
+ segbuf = sci->sc_curseg;
+ segbuf->sb_sum.sumbytes = sci->sc_binfo_ptr.offset +
+ sci->sc_super->s_blocksize * (segbuf->sb_sum.nsumblk - 1);
+ sci->sc_finfo_ptr = sci->sc_binfo_ptr;
+ sci->sc_blk_cnt = sci->sc_datablk_cnt = 0;
+}
+
+static int nilfs_segctor_add_file_block(struct nilfs_sc_info *sci,
+ struct buffer_head *bh,
+ struct inode *inode,
+ unsigned binfo_size)
+{
+ struct nilfs_segment_buffer *segbuf;
+ int required, err = 0;
+
+ retry:
+ segbuf = sci->sc_curseg;
+ required = nilfs_segctor_segsum_block_required(
+ sci, &sci->sc_binfo_ptr, binfo_size);
+ if (segbuf->sb_sum.nblocks + required + 1 > segbuf->sb_rest_blocks) {
+ nilfs_segctor_end_finfo(sci, inode);
+ err = nilfs_segctor_feed_segment(sci);
+ if (err)
+ return err;
+ goto retry;
+ }
+ if (unlikely(required)) {
+ err = nilfs_segbuf_extend_segsum(segbuf);
+ if (unlikely(err))
+ goto failed;
+ }
+ if (sci->sc_blk_cnt == 0)
+ nilfs_segctor_begin_finfo(sci, inode);
+
+ nilfs_segctor_map_segsum_entry(sci, &sci->sc_binfo_ptr, binfo_size);
+ /* Substitution to vblocknr is delayed until update_blocknr() */
+ nilfs_segbuf_add_file_buffer(segbuf, bh);
+ sci->sc_blk_cnt++;
+ failed:
+ return err;
+}
+
+static int nilfs_handle_bmap_error(int err, const char *fname,
+ struct inode *inode, struct super_block *sb)
+{
+ if (err == -EINVAL) {
+ nilfs_error(sb, fname, "broken bmap (inode=%lu)\n",
+ inode->i_ino);
+ err = -EIO;
+ }
+ return err;
+}
+
+/*
+ * Callback functions that enumerate, mark, and collect dirty blocks
+ */
+static int nilfs_collect_file_data(struct nilfs_sc_info *sci,
+ struct buffer_head *bh, struct inode *inode)
+{
+ int err;
+
+ err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
+ if (unlikely(err < 0))
+ return nilfs_handle_bmap_error(err, __func__, inode,
+ sci->sc_super);
+
+ err = nilfs_segctor_add_file_block(sci, bh, inode,
+ sizeof(struct nilfs_binfo_v));
+ if (!err)
+ sci->sc_datablk_cnt++;
+ return err;
+}
+
+static int nilfs_collect_file_node(struct nilfs_sc_info *sci,
+ struct buffer_head *bh,
+ struct inode *inode)
+{
+ int err;
+
+ err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
+ if (unlikely(err < 0))
+ return nilfs_handle_bmap_error(err, __func__, inode,
+ sci->sc_super);
+ return 0;
+}
+
+static int nilfs_collect_file_bmap(struct nilfs_sc_info *sci,
+ struct buffer_head *bh,
+ struct inode *inode)
+{
+ WARN_ON(!buffer_dirty(bh));
+ return nilfs_segctor_add_file_block(sci, bh, inode, sizeof(__le64));
+}
+
+static void nilfs_write_file_data_binfo(struct nilfs_sc_info *sci,
+ struct nilfs_segsum_pointer *ssp,
+ union nilfs_binfo *binfo)
+{
+ struct nilfs_binfo_v *binfo_v = nilfs_segctor_map_segsum_entry(
+ sci, ssp, sizeof(*binfo_v));
+ *binfo_v = binfo->bi_v;
+}
+
+static void nilfs_write_file_node_binfo(struct nilfs_sc_info *sci,
+ struct nilfs_segsum_pointer *ssp,
+ union nilfs_binfo *binfo)
+{
+ __le64 *vblocknr = nilfs_segctor_map_segsum_entry(
+ sci, ssp, sizeof(*vblocknr));
+ *vblocknr = binfo->bi_v.bi_vblocknr;
+}
+
+struct nilfs_sc_operations nilfs_sc_file_ops = {
+ .collect_data = nilfs_collect_file_data,
+ .collect_node = nilfs_collect_file_node,
+ .collect_bmap = nilfs_collect_file_bmap,
+ .write_data_binfo = nilfs_write_file_data_binfo,
+ .write_node_binfo = nilfs_write_file_node_binfo,
+};
+
+static int nilfs_collect_dat_data(struct nilfs_sc_info *sci,
+ struct buffer_head *bh, struct inode *inode)
+{
+ int err;
+
+ err = nilfs_bmap_propagate(NILFS_I(inode)->i_bmap, bh);
+ if (unlikely(err < 0))
+ return nilfs_handle_bmap_error(err, __func__, inode,
+ sci->sc_super);
+
+ err = nilfs_segctor_add_file_block(sci, bh, inode, sizeof(__le64));
+ if (!err)
+ sci->sc_datablk_cnt++;
+ return err;
+}
+
+static int nilfs_collect_dat_bmap(struct nilfs_sc_info *sci,
+ struct buffer_head *bh, struct inode *inode)
+{
+ WARN_ON(!buffer_dirty(bh));
+ return nilfs_segctor_add_file_block(sci, bh, inode,
+ sizeof(struct nilfs_binfo_dat));
+}
+
+static void nilfs_write_dat_data_binfo(struct nilfs_sc_info *sci,
+ struct nilfs_segsum_pointer *ssp,
+ union nilfs_binfo *binfo)
+{
+ __le64 *blkoff = nilfs_segctor_map_segsum_entry(sci, ssp,
+ sizeof(*blkoff));
+ *blkoff = binfo->bi_dat.bi_blkoff;
+}
+
+static void nilfs_write_dat_node_binfo(struct nilfs_sc_info *sci,
+ struct nilfs_segsum_pointer *ssp,
+ union nilfs_binfo *binfo)
+{
+ struct nilfs_binfo_dat *binfo_dat =
+ nilfs_segctor_map_segsum_entry(sci, ssp, sizeof(*binfo_dat));
+ *binfo_dat = binfo->bi_dat;
+}
+
+struct nilfs_sc_operations nilfs_sc_dat_ops = {
+ .collect_data = nilfs_collect_dat_data,
+ .collect_node = nilfs_collect_file_node,
+ .collect_bmap = nilfs_collect_dat_bmap,
+ .write_data_binfo = nilfs_write_dat_data_binfo,
+ .write_node_binfo = nilfs_write_dat_node_binfo,
+};
+
+struct nilfs_sc_operations nilfs_sc_dsync_ops = {
+ .collect_data = nilfs_collect_file_data,
+ .collect_node = NULL,
+ .collect_bmap = NULL,
+ .write_data_binfo = nilfs_write_file_data_binfo,
+ .write_node_binfo = NULL,
+};
+
+static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode,
+ struct list_head *listp,
+ size_t nlimit,
+ loff_t start, loff_t end)
+{
+ struct address_space *mapping = inode->i_mapping;
+ struct pagevec pvec;
+ pgoff_t index = 0, last = ULONG_MAX;
+ size_t ndirties = 0;
+ int i;
+
+ if (unlikely(start != 0 || end != LLONG_MAX)) {
+ /*
+ * A valid range is given for sync-ing data pages. The
+ * range is rounded to per-page; extra dirty buffers
+ * may be included if blocksize < pagesize.
+ */
+ index = start >> PAGE_SHIFT;
+ last = end >> PAGE_SHIFT;
+ }
+ pagevec_init(&pvec, 0);
+ repeat:
+ if (unlikely(index > last) ||
+ !pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
+ min_t(pgoff_t, last - index,
+ PAGEVEC_SIZE - 1) + 1))
+ return ndirties;
+
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ struct buffer_head *bh, *head;
+ struct page *page = pvec.pages[i];
+
+ if (unlikely(page->index > last))
+ break;
+
+ if (mapping->host) {
+ lock_page(page);
+ if (!page_has_buffers(page))
+ create_empty_buffers(page,
+ 1 << inode->i_blkbits, 0);
+ unlock_page(page);
+ }
+
+ bh = head = page_buffers(page);
+ do {
+ if (!buffer_dirty(bh))
+ continue;
+ get_bh(bh);
+ list_add_tail(&bh->b_assoc_buffers, listp);
+ ndirties++;
+ if (unlikely(ndirties >= nlimit)) {
+ pagevec_release(&pvec);
+ cond_resched();
+ return ndirties;
+ }
+ } while (bh = bh->b_this_page, bh != head);
+ }
+ pagevec_release(&pvec);
+ cond_resched();
+ goto repeat;
+}
+
+static void nilfs_lookup_dirty_node_buffers(struct inode *inode,
+ struct list_head *listp)
+{
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+ struct address_space *mapping = &ii->i_btnode_cache;
+ struct pagevec pvec;
+ struct buffer_head *bh, *head;
+ unsigned int i;
+ pgoff_t index = 0;
+
+ pagevec_init(&pvec, 0);
+
+ while (pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
+ PAGEVEC_SIZE)) {
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ bh = head = page_buffers(pvec.pages[i]);
+ do {
+ if (buffer_dirty(bh)) {
+ get_bh(bh);
+ list_add_tail(&bh->b_assoc_buffers,
+ listp);
+ }
+ bh = bh->b_this_page;
+ } while (bh != head);
+ }
+ pagevec_release(&pvec);
+ cond_resched();
+ }
+}
+
+static void nilfs_dispose_list(struct nilfs_sb_info *sbi,
+ struct list_head *head, int force)
+{
+ struct nilfs_inode_info *ii, *n;
+ struct nilfs_inode_info *ivec[SC_N_INODEVEC], **pii;
+ unsigned nv = 0;
+
+ while (!list_empty(head)) {
+ spin_lock(&sbi->s_inode_lock);
+ list_for_each_entry_safe(ii, n, head, i_dirty) {
+ list_del_init(&ii->i_dirty);
+ if (force) {
+ if (unlikely(ii->i_bh)) {
+ brelse(ii->i_bh);
+ ii->i_bh = NULL;
+ }
+ } else if (test_bit(NILFS_I_DIRTY, &ii->i_state)) {
+ set_bit(NILFS_I_QUEUED, &ii->i_state);
+ list_add_tail(&ii->i_dirty,
+ &sbi->s_dirty_files);
+ continue;
+ }
+ ivec[nv++] = ii;
+ if (nv == SC_N_INODEVEC)
+ break;
+ }
+ spin_unlock(&sbi->s_inode_lock);
+
+ for (pii = ivec; nv > 0; pii++, nv--)
+ iput(&(*pii)->vfs_inode);
+ }
+}
+
+static int nilfs_test_metadata_dirty(struct nilfs_sb_info *sbi)
+{
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ int ret = 0;
+
+ if (nilfs_mdt_fetch_dirty(sbi->s_ifile))
+ ret++;
+ if (nilfs_mdt_fetch_dirty(nilfs->ns_cpfile))
+ ret++;
+ if (nilfs_mdt_fetch_dirty(nilfs->ns_sufile))
+ ret++;
+ if (ret || nilfs_doing_gc())
+ if (nilfs_mdt_fetch_dirty(nilfs_dat_inode(nilfs)))
+ ret++;
+ return ret;
+}
+
+static int nilfs_segctor_clean(struct nilfs_sc_info *sci)
+{
+ return list_empty(&sci->sc_dirty_files) &&
+ !test_bit(NILFS_SC_DIRTY, &sci->sc_flags) &&
+ list_empty(&sci->sc_cleaning_segments) &&
+ (!nilfs_doing_gc() || list_empty(&sci->sc_gc_inodes));
+}
+
+static int nilfs_segctor_confirm(struct nilfs_sc_info *sci)
+{
+ struct nilfs_sb_info *sbi = sci->sc_sbi;
+ int ret = 0;
+
+ if (nilfs_test_metadata_dirty(sbi))
+ set_bit(NILFS_SC_DIRTY, &sci->sc_flags);
+
+ spin_lock(&sbi->s_inode_lock);
+ if (list_empty(&sbi->s_dirty_files) && nilfs_segctor_clean(sci))
+ ret++;
+
+ spin_unlock(&sbi->s_inode_lock);
+ return ret;
+}
+
+static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci)
+{
+ struct nilfs_sb_info *sbi = sci->sc_sbi;
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+
+ nilfs_mdt_clear_dirty(sbi->s_ifile);
+ nilfs_mdt_clear_dirty(nilfs->ns_cpfile);
+ nilfs_mdt_clear_dirty(nilfs->ns_sufile);
+ nilfs_mdt_clear_dirty(nilfs_dat_inode(nilfs));
+}
+
+static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci)
+{
+ struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs;
+ struct buffer_head *bh_cp;
+ struct nilfs_checkpoint *raw_cp;
+ int err;
+
+ /* XXX: this interface will be changed */
+ err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, 1,
+ &raw_cp, &bh_cp);
+ if (likely(!err)) {
+ /* The following code is duplicated with cpfile. But, it is
+ needed to collect the checkpoint even if it was not newly
+ created */
+ nilfs_mdt_mark_buffer_dirty(bh_cp);
+ nilfs_mdt_mark_dirty(nilfs->ns_cpfile);
+ nilfs_cpfile_put_checkpoint(
+ nilfs->ns_cpfile, nilfs->ns_cno, bh_cp);
+ } else
+ WARN_ON(err == -EINVAL || err == -ENOENT);
+
+ return err;
+}
+
+static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci)
+{
+ struct nilfs_sb_info *sbi = sci->sc_sbi;
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ struct buffer_head *bh_cp;
+ struct nilfs_checkpoint *raw_cp;
+ int err;
+
+ err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, 0,
+ &raw_cp, &bh_cp);
+ if (unlikely(err)) {
+ WARN_ON(err == -EINVAL || err == -ENOENT);
+ goto failed_ibh;
+ }
+ raw_cp->cp_snapshot_list.ssl_next = 0;
+ raw_cp->cp_snapshot_list.ssl_prev = 0;
+ raw_cp->cp_inodes_count =
+ cpu_to_le64(atomic_read(&sbi->s_inodes_count));
+ raw_cp->cp_blocks_count =
+ cpu_to_le64(atomic_read(&sbi->s_blocks_count));
+ raw_cp->cp_nblk_inc =
+ cpu_to_le64(sci->sc_nblk_inc + sci->sc_nblk_this_inc);
+ raw_cp->cp_create = cpu_to_le64(sci->sc_seg_ctime);
+ raw_cp->cp_cno = cpu_to_le64(nilfs->ns_cno);
+
+ if (test_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags))
+ nilfs_checkpoint_clear_minor(raw_cp);
+ else
+ nilfs_checkpoint_set_minor(raw_cp);
+
+ nilfs_write_inode_common(sbi->s_ifile, &raw_cp->cp_ifile_inode, 1);
+ nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, bh_cp);
+ return 0;
+
+ failed_ibh:
+ return err;
+}
+
+static void nilfs_fill_in_file_bmap(struct inode *ifile,
+ struct nilfs_inode_info *ii)
+
+{
+ struct buffer_head *ibh;
+ struct nilfs_inode *raw_inode;
+
+ if (test_bit(NILFS_I_BMAP, &ii->i_state)) {
+ ibh = ii->i_bh;
+ BUG_ON(!ibh);
+ raw_inode = nilfs_ifile_map_inode(ifile, ii->vfs_inode.i_ino,
+ ibh);
+ nilfs_bmap_write(ii->i_bmap, raw_inode);
+ nilfs_ifile_unmap_inode(ifile, ii->vfs_inode.i_ino, ibh);
+ }
+}
+
+static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci,
+ struct inode *ifile)
+{
+ struct nilfs_inode_info *ii;
+
+ list_for_each_entry(ii, &sci->sc_dirty_files, i_dirty) {
+ nilfs_fill_in_file_bmap(ifile, ii);
+ set_bit(NILFS_I_COLLECTED, &ii->i_state);
+ }
+}
+
+/*
+ * CRC calculation routines
+ */
+static void nilfs_fill_in_super_root_crc(struct buffer_head *bh_sr, u32 seed)
+{
+ struct nilfs_super_root *raw_sr =
+ (struct nilfs_super_root *)bh_sr->b_data;
+ u32 crc;
+
+ crc = crc32_le(seed,
+ (unsigned char *)raw_sr + sizeof(raw_sr->sr_sum),
+ NILFS_SR_BYTES - sizeof(raw_sr->sr_sum));
+ raw_sr->sr_sum = cpu_to_le32(crc);
+}
+
+static void nilfs_segctor_fill_in_checksums(struct nilfs_sc_info *sci,
+ u32 seed)
+{
+ struct nilfs_segment_buffer *segbuf;
+
+ if (sci->sc_super_root)
+ nilfs_fill_in_super_root_crc(sci->sc_super_root, seed);
+
+ list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
+ nilfs_segbuf_fill_in_segsum_crc(segbuf, seed);
+ nilfs_segbuf_fill_in_data_crc(segbuf, seed);
+ }
+}
+
+static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,
+ struct the_nilfs *nilfs)
+{
+ struct buffer_head *bh_sr = sci->sc_super_root;
+ struct nilfs_super_root *raw_sr =
+ (struct nilfs_super_root *)bh_sr->b_data;
+ unsigned isz = nilfs->ns_inode_size;
+
+ raw_sr->sr_bytes = cpu_to_le16(NILFS_SR_BYTES);
+ raw_sr->sr_nongc_ctime
+ = cpu_to_le64(nilfs_doing_gc() ?
+ nilfs->ns_nongc_ctime : sci->sc_seg_ctime);
+ raw_sr->sr_flags = 0;
+
+ nilfs_mdt_write_inode_direct(
+ nilfs_dat_inode(nilfs), bh_sr, NILFS_SR_DAT_OFFSET(isz));
+ nilfs_mdt_write_inode_direct(
+ nilfs->ns_cpfile, bh_sr, NILFS_SR_CPFILE_OFFSET(isz));
+ nilfs_mdt_write_inode_direct(
+ nilfs->ns_sufile, bh_sr, NILFS_SR_SUFILE_OFFSET(isz));
+}
+
+static void nilfs_redirty_inodes(struct list_head *head)
+{
+ struct nilfs_inode_info *ii;
+
+ list_for_each_entry(ii, head, i_dirty) {
+ if (test_bit(NILFS_I_COLLECTED, &ii->i_state))
+ clear_bit(NILFS_I_COLLECTED, &ii->i_state);
+ }
+}
+
+static void nilfs_drop_collected_inodes(struct list_head *head)
+{
+ struct nilfs_inode_info *ii;
+
+ list_for_each_entry(ii, head, i_dirty) {
+ if (!test_and_clear_bit(NILFS_I_COLLECTED, &ii->i_state))
+ continue;
+
+ clear_bit(NILFS_I_INODE_DIRTY, &ii->i_state);
+ set_bit(NILFS_I_UPDATED, &ii->i_state);
+ }
+}
+
+static void nilfs_segctor_cancel_free_segments(struct nilfs_sc_info *sci,
+ struct inode *sufile)
+
+{
+ struct list_head *head = &sci->sc_cleaning_segments;
+ struct nilfs_segment_entry *ent;
+ int err;
+
+ list_for_each_entry(ent, head, list) {
+ if (!(ent->flags & NILFS_SLH_FREED))
+ break;
+ err = nilfs_sufile_cancel_free(sufile, ent->segnum);
+ WARN_ON(err); /* do not happen */
+ ent->flags &= ~NILFS_SLH_FREED;
+ }
+}
+
+static int nilfs_segctor_prepare_free_segments(struct nilfs_sc_info *sci,
+ struct inode *sufile)
+{
+ struct list_head *head = &sci->sc_cleaning_segments;
+ struct nilfs_segment_entry *ent;
+ int err;
+
+ list_for_each_entry(ent, head, list) {
+ err = nilfs_sufile_free(sufile, ent->segnum);
+ if (unlikely(err))
+ return err;
+ ent->flags |= NILFS_SLH_FREED;
+ }
+ return 0;
+}
+
+static void nilfs_segctor_commit_free_segments(struct nilfs_sc_info *sci)
+{
+ nilfs_dispose_segment_list(&sci->sc_cleaning_segments);
+}
+
+static int nilfs_segctor_apply_buffers(struct nilfs_sc_info *sci,
+ struct inode *inode,
+ struct list_head *listp,
+ int (*collect)(struct nilfs_sc_info *,
+ struct buffer_head *,
+ struct inode *))
+{
+ struct buffer_head *bh, *n;
+ int err = 0;
+
+ if (collect) {
+ list_for_each_entry_safe(bh, n, listp, b_assoc_buffers) {
+ list_del_init(&bh->b_assoc_buffers);
+ err = collect(sci, bh, inode);
+ brelse(bh);
+ if (unlikely(err))
+ goto dispose_buffers;
+ }
+ return 0;
+ }
+
+ dispose_buffers:
+ while (!list_empty(listp)) {
+ bh = list_entry(listp->next, struct buffer_head,
+ b_assoc_buffers);
+ list_del_init(&bh->b_assoc_buffers);
+ brelse(bh);
+ }
+ return err;
+}
+
+static size_t nilfs_segctor_buffer_rest(struct nilfs_sc_info *sci)
+{
+ /* Remaining number of blocks within segment buffer */
+ return sci->sc_segbuf_nblocks -
+ (sci->sc_nblk_this_inc + sci->sc_curseg->sb_sum.nblocks);
+}
+
+static int nilfs_segctor_scan_file(struct nilfs_sc_info *sci,
+ struct inode *inode,
+ struct nilfs_sc_operations *sc_ops)
+{
+ LIST_HEAD(data_buffers);
+ LIST_HEAD(node_buffers);
+ int err;
+
+ if (!(sci->sc_stage.flags & NILFS_CF_NODE)) {
+ size_t n, rest = nilfs_segctor_buffer_rest(sci);
+
+ n = nilfs_lookup_dirty_data_buffers(
+ inode, &data_buffers, rest + 1, 0, LLONG_MAX);
+ if (n > rest) {
+ err = nilfs_segctor_apply_buffers(
+ sci, inode, &data_buffers,
+ sc_ops->collect_data);
+ BUG_ON(!err); /* always receive -E2BIG or true error */
+ goto break_or_fail;
+ }
+ }
+ nilfs_lookup_dirty_node_buffers(inode, &node_buffers);
+
+ if (!(sci->sc_stage.flags & NILFS_CF_NODE)) {
+ err = nilfs_segctor_apply_buffers(
+ sci, inode, &data_buffers, sc_ops->collect_data);
+ if (unlikely(err)) {
+ /* dispose node list */
+ nilfs_segctor_apply_buffers(
+ sci, inode, &node_buffers, NULL);
+ goto break_or_fail;
+ }
+ sci->sc_stage.flags |= NILFS_CF_NODE;
+ }
+ /* Collect node */
+ err = nilfs_segctor_apply_buffers(
+ sci, inode, &node_buffers, sc_ops->collect_node);
+ if (unlikely(err))
+ goto break_or_fail;
+
+ nilfs_bmap_lookup_dirty_buffers(NILFS_I(inode)->i_bmap, &node_buffers);
+ err = nilfs_segctor_apply_buffers(
+ sci, inode, &node_buffers, sc_ops->collect_bmap);
+ if (unlikely(err))
+ goto break_or_fail;
+
+ nilfs_segctor_end_finfo(sci, inode);
+ sci->sc_stage.flags &= ~NILFS_CF_NODE;
+
+ break_or_fail:
+ return err;
+}
+
+static int nilfs_segctor_scan_file_dsync(struct nilfs_sc_info *sci,
+ struct inode *inode)
+{
+ LIST_HEAD(data_buffers);
+ size_t n, rest = nilfs_segctor_buffer_rest(sci);
+ int err;
+
+ n = nilfs_lookup_dirty_data_buffers(inode, &data_buffers, rest + 1,
+ sci->sc_dsync_start,
+ sci->sc_dsync_end);
+
+ err = nilfs_segctor_apply_buffers(sci, inode, &data_buffers,
+ nilfs_collect_file_data);
+ if (!err) {
+ nilfs_segctor_end_finfo(sci, inode);
+ BUG_ON(n > rest);
+ /* always receive -E2BIG or true error if n > rest */
+ }
+ return err;
+}
+
+static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
+{
+ struct nilfs_sb_info *sbi = sci->sc_sbi;
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ struct list_head *head;
+ struct nilfs_inode_info *ii;
+ int err = 0;
+
+ switch (sci->sc_stage.scnt) {
+ case NILFS_ST_INIT:
+ /* Pre-processes */
+ sci->sc_stage.flags = 0;
+
+ if (!test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags)) {
+ sci->sc_nblk_inc = 0;
+ sci->sc_curseg->sb_sum.flags = NILFS_SS_LOGBGN;
+ if (mode == SC_LSEG_DSYNC) {
+ sci->sc_stage.scnt = NILFS_ST_DSYNC;
+ goto dsync_mode;
+ }
+ }
+
+ sci->sc_stage.dirty_file_ptr = NULL;
+ sci->sc_stage.gc_inode_ptr = NULL;
+ if (mode == SC_FLUSH_DAT) {
+ sci->sc_stage.scnt = NILFS_ST_DAT;
+ goto dat_stage;
+ }
+ sci->sc_stage.scnt++; /* Fall through */
+ case NILFS_ST_GC:
+ if (nilfs_doing_gc()) {
+ head = &sci->sc_gc_inodes;
+ ii = list_prepare_entry(sci->sc_stage.gc_inode_ptr,
+ head, i_dirty);
+ list_for_each_entry_continue(ii, head, i_dirty) {
+ err = nilfs_segctor_scan_file(
+ sci, &ii->vfs_inode,
+ &nilfs_sc_file_ops);
+ if (unlikely(err)) {
+ sci->sc_stage.gc_inode_ptr = list_entry(
+ ii->i_dirty.prev,
+ struct nilfs_inode_info,
+ i_dirty);
+ goto break_or_fail;
+ }
+ set_bit(NILFS_I_COLLECTED, &ii->i_state);
+ }
+ sci->sc_stage.gc_inode_ptr = NULL;
+ }
+ sci->sc_stage.scnt++; /* Fall through */
+ case NILFS_ST_FILE:
+ head = &sci->sc_dirty_files;
+ ii = list_prepare_entry(sci->sc_stage.dirty_file_ptr, head,
+ i_dirty);
+ list_for_each_entry_continue(ii, head, i_dirty) {
+ clear_bit(NILFS_I_DIRTY, &ii->i_state);
+
+ err = nilfs_segctor_scan_file(sci, &ii->vfs_inode,
+ &nilfs_sc_file_ops);
+ if (unlikely(err)) {
+ sci->sc_stage.dirty_file_ptr =
+ list_entry(ii->i_dirty.prev,
+ struct nilfs_inode_info,
+ i_dirty);
+ goto break_or_fail;
+ }
+ /* sci->sc_stage.dirty_file_ptr = NILFS_I(inode); */
+ /* XXX: required ? */
+ }
+ sci->sc_stage.dirty_file_ptr = NULL;
+ if (mode == SC_FLUSH_FILE) {
+ sci->sc_stage.scnt = NILFS_ST_DONE;
+ return 0;
+ }
+ sci->sc_stage.scnt++;
+ sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED;
+ /* Fall through */
+ case NILFS_ST_IFILE:
+ err = nilfs_segctor_scan_file(sci, sbi->s_ifile,
+ &nilfs_sc_file_ops);
+ if (unlikely(err))
+ break;
+ sci->sc_stage.scnt++;
+ /* Creating a checkpoint */
+ err = nilfs_segctor_create_checkpoint(sci);
+ if (unlikely(err))
+ break;
+ /* Fall through */
+ case NILFS_ST_CPFILE:
+ err = nilfs_segctor_scan_file(sci, nilfs->ns_cpfile,
+ &nilfs_sc_file_ops);
+ if (unlikely(err))
+ break;
+ sci->sc_stage.scnt++; /* Fall through */
+ case NILFS_ST_SUFILE:
+ err = nilfs_segctor_prepare_free_segments(sci,
+ nilfs->ns_sufile);
+ if (unlikely(err))
+ break;
+ err = nilfs_segctor_scan_file(sci, nilfs->ns_sufile,
+ &nilfs_sc_file_ops);
+ if (unlikely(err))
+ break;
+ sci->sc_stage.scnt++; /* Fall through */
+ case NILFS_ST_DAT:
+ dat_stage:
+ err = nilfs_segctor_scan_file(sci, nilfs_dat_inode(nilfs),
+ &nilfs_sc_dat_ops);
+ if (unlikely(err))
+ break;
+ if (mode == SC_FLUSH_DAT) {
+ sci->sc_stage.scnt = NILFS_ST_DONE;
+ return 0;
+ }
+ sci->sc_stage.scnt++; /* Fall through */
+ case NILFS_ST_SR:
+ if (mode == SC_LSEG_SR) {
+ /* Appending a super root */
+ err = nilfs_segctor_add_super_root(sci);
+ if (unlikely(err))
+ break;
+ }
+ /* End of a logical segment */
+ sci->sc_curseg->sb_sum.flags |= NILFS_SS_LOGEND;
+ sci->sc_stage.scnt = NILFS_ST_DONE;
+ return 0;
+ case NILFS_ST_DSYNC:
+ dsync_mode:
+ sci->sc_curseg->sb_sum.flags |= NILFS_SS_SYNDT;
+ ii = sci->sc_dsync_inode;
+ if (!test_bit(NILFS_I_BUSY, &ii->i_state))
+ break;
+
+ err = nilfs_segctor_scan_file_dsync(sci, &ii->vfs_inode);
+ if (unlikely(err))
+ break;
+ sci->sc_curseg->sb_sum.flags |= NILFS_SS_LOGEND;
+ sci->sc_stage.scnt = NILFS_ST_DONE;
+ return 0;
+ case NILFS_ST_DONE:
+ return 0;
+ default:
+ BUG();
+ }
+
+ break_or_fail:
+ return err;
+}
+
+static int nilfs_touch_segusage(struct inode *sufile, __u64 segnum)
+{
+ struct buffer_head *bh_su;
+ struct nilfs_segment_usage *raw_su;
+ int err;
+
+ err = nilfs_sufile_get_segment_usage(sufile, segnum, &raw_su, &bh_su);
+ if (unlikely(err))
+ return err;
+ nilfs_mdt_mark_buffer_dirty(bh_su);
+ nilfs_mdt_mark_dirty(sufile);
+ nilfs_sufile_put_segment_usage(sufile, segnum, bh_su);
+ return 0;
+}
+
+static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci,
+ struct the_nilfs *nilfs)
+{
+ struct nilfs_segment_buffer *segbuf, *n;
+ __u64 nextnum;
+ int err;
+
+ if (list_empty(&sci->sc_segbufs)) {
+ segbuf = nilfs_segbuf_new(sci->sc_super);
+ if (unlikely(!segbuf))
+ return -ENOMEM;
+ list_add(&segbuf->sb_list, &sci->sc_segbufs);
+ } else
+ segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
+
+ nilfs_segbuf_map(segbuf, nilfs->ns_segnum, nilfs->ns_pseg_offset,
+ nilfs);
+
+ if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) {
+ nilfs_shift_to_next_segment(nilfs);
+ nilfs_segbuf_map(segbuf, nilfs->ns_segnum, 0, nilfs);
+ }
+ sci->sc_segbuf_nblocks = segbuf->sb_rest_blocks;
+
+ err = nilfs_touch_segusage(nilfs->ns_sufile, segbuf->sb_segnum);
+ if (unlikely(err))
+ return err;
+
+ if (nilfs->ns_segnum == nilfs->ns_nextnum) {
+ /* Start from the head of a new full segment */
+ err = nilfs_sufile_alloc(nilfs->ns_sufile, &nextnum);
+ if (unlikely(err))
+ return err;
+ } else
+ nextnum = nilfs->ns_nextnum;
+
+ segbuf->sb_sum.seg_seq = nilfs->ns_seg_seq;
+ nilfs_segbuf_set_next_segnum(segbuf, nextnum, nilfs);
+
+ /* truncating segment buffers */
+ list_for_each_entry_safe_continue(segbuf, n, &sci->sc_segbufs,
+ sb_list) {
+ list_del_init(&segbuf->sb_list);
+ nilfs_segbuf_free(segbuf);
+ }
+ return 0;
+}
+
+static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
+ struct the_nilfs *nilfs, int nadd)
+{
+ struct nilfs_segment_buffer *segbuf, *prev, *n;
+ struct inode *sufile = nilfs->ns_sufile;
+ __u64 nextnextnum;
+ LIST_HEAD(list);
+ int err, ret, i;
+
+ prev = NILFS_LAST_SEGBUF(&sci->sc_segbufs);
+ /*
+ * Since the segment specified with nextnum might be allocated during
+ * the previous construction, the buffer including its segusage may
+ * not be dirty. The following call ensures that the buffer is dirty
+ * and will pin the buffer on memory until the sufile is written.
+ */
+ err = nilfs_touch_segusage(sufile, prev->sb_nextnum);
+ if (unlikely(err))
+ return err;
+
+ for (i = 0; i < nadd; i++) {
+ /* extend segment info */
+ err = -ENOMEM;
+ segbuf = nilfs_segbuf_new(sci->sc_super);
+ if (unlikely(!segbuf))
+ goto failed;
+
+ /* map this buffer to region of segment on-disk */
+ nilfs_segbuf_map(segbuf, prev->sb_nextnum, 0, nilfs);
+ sci->sc_segbuf_nblocks += segbuf->sb_rest_blocks;
+
+ /* allocate the next next full segment */
+ err = nilfs_sufile_alloc(sufile, &nextnextnum);
+ if (unlikely(err))
+ goto failed_segbuf;
+
+ segbuf->sb_sum.seg_seq = prev->sb_sum.seg_seq + 1;
+ nilfs_segbuf_set_next_segnum(segbuf, nextnextnum, nilfs);
+
+ list_add_tail(&segbuf->sb_list, &list);
+ prev = segbuf;
+ }
+ list_splice(&list, sci->sc_segbufs.prev);
+ return 0;
+
+ failed_segbuf:
+ nilfs_segbuf_free(segbuf);
+ failed:
+ list_for_each_entry_safe(segbuf, n, &list, sb_list) {
+ ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
+ WARN_ON(ret); /* never fails */
+ list_del_init(&segbuf->sb_list);
+ nilfs_segbuf_free(segbuf);
+ }
+ return err;
+}
+
+static void nilfs_segctor_free_incomplete_segments(struct nilfs_sc_info *sci,
+ struct the_nilfs *nilfs)
+{
+ struct nilfs_segment_buffer *segbuf;
+ int ret, done = 0;
+
+ segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
+ if (nilfs->ns_nextnum != segbuf->sb_nextnum) {
+ ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum);
+ WARN_ON(ret); /* never fails */
+ }
+ if (segbuf->sb_io_error) {
+ /* Case 1: The first segment failed */
+ if (segbuf->sb_pseg_start != segbuf->sb_fseg_start)
+ /* Case 1a: Partial segment appended into an existing
+ segment */
+ nilfs_terminate_segment(nilfs, segbuf->sb_fseg_start,
+ segbuf->sb_fseg_end);
+ else /* Case 1b: New full segment */
+ set_nilfs_discontinued(nilfs);
+ done++;
+ }
+
+ list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) {
+ ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum);
+ WARN_ON(ret); /* never fails */
+ if (!done && segbuf->sb_io_error) {
+ if (segbuf->sb_segnum != nilfs->ns_nextnum)
+ /* Case 2: extended segment (!= next) failed */
+ nilfs_sufile_set_error(nilfs->ns_sufile,
+ segbuf->sb_segnum);
+ done++;
+ }
+ }
+}
+
+static void nilfs_segctor_clear_segment_buffers(struct nilfs_sc_info *sci)
+{
+ struct nilfs_segment_buffer *segbuf;
+
+ list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list)
+ nilfs_segbuf_clear(segbuf);
+ sci->sc_super_root = NULL;
+}
+
+static void nilfs_segctor_destroy_segment_buffers(struct nilfs_sc_info *sci)
+{
+ struct nilfs_segment_buffer *segbuf;
+
+ while (!list_empty(&sci->sc_segbufs)) {
+ segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
+ list_del_init(&segbuf->sb_list);
+ nilfs_segbuf_free(segbuf);
+ }
+ /* sci->sc_curseg = NULL; */
+}
+
+static void nilfs_segctor_end_construction(struct nilfs_sc_info *sci,
+ struct the_nilfs *nilfs, int err)
+{
+ if (unlikely(err)) {
+ nilfs_segctor_free_incomplete_segments(sci, nilfs);
+ nilfs_segctor_cancel_free_segments(sci, nilfs->ns_sufile);
+ }
+ nilfs_segctor_clear_segment_buffers(sci);
+}
+
+static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci,
+ struct inode *sufile)
+{
+ struct nilfs_segment_buffer *segbuf;
+ struct buffer_head *bh_su;
+ struct nilfs_segment_usage *raw_su;
+ unsigned long live_blocks;
+ int ret;
+
+ list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
+ ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum,
+ &raw_su, &bh_su);
+ WARN_ON(ret); /* always succeed because bh_su is dirty */
+ live_blocks = segbuf->sb_sum.nblocks +
+ (segbuf->sb_pseg_start - segbuf->sb_fseg_start);
+ raw_su->su_lastmod = cpu_to_le64(sci->sc_seg_ctime);
+ raw_su->su_nblocks = cpu_to_le32(live_blocks);
+ nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum,
+ bh_su);
+ }
+}
+
+static void nilfs_segctor_cancel_segusage(struct nilfs_sc_info *sci,
+ struct inode *sufile)
+{
+ struct nilfs_segment_buffer *segbuf;
+ struct buffer_head *bh_su;
+ struct nilfs_segment_usage *raw_su;
+ int ret;
+
+ segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
+ ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum,
+ &raw_su, &bh_su);
+ WARN_ON(ret); /* always succeed because bh_su is dirty */
+ raw_su->su_nblocks = cpu_to_le32(segbuf->sb_pseg_start -
+ segbuf->sb_fseg_start);
+ nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum, bh_su);
+
+ list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) {
+ ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum,
+ &raw_su, &bh_su);
+ WARN_ON(ret); /* always succeed */
+ raw_su->su_nblocks = 0;
+ nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum,
+ bh_su);
+ }
+}
+
+static void nilfs_segctor_truncate_segments(struct nilfs_sc_info *sci,
+ struct nilfs_segment_buffer *last,
+ struct inode *sufile)
+{
+ struct nilfs_segment_buffer *segbuf = last, *n;
+ int ret;
+
+ list_for_each_entry_safe_continue(segbuf, n, &sci->sc_segbufs,
+ sb_list) {
+ list_del_init(&segbuf->sb_list);
+ sci->sc_segbuf_nblocks -= segbuf->sb_rest_blocks;
+ ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
+ WARN_ON(ret);
+ nilfs_segbuf_free(segbuf);
+ }
+}
+
+
+static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
+ struct the_nilfs *nilfs, int mode)
+{
+ struct nilfs_cstage prev_stage = sci->sc_stage;
+ int err, nadd = 1;
+
+ /* Collection retry loop */
+ for (;;) {
+ sci->sc_super_root = NULL;
+ sci->sc_nblk_this_inc = 0;
+ sci->sc_curseg = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
+
+ err = nilfs_segctor_reset_segment_buffer(sci);
+ if (unlikely(err))
+ goto failed;
+
+ err = nilfs_segctor_collect_blocks(sci, mode);
+ sci->sc_nblk_this_inc += sci->sc_curseg->sb_sum.nblocks;
+ if (!err)
+ break;
+
+ if (unlikely(err != -E2BIG))
+ goto failed;
+
+ /* The current segment is filled up */
+ if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE)
+ break;
+
+ nilfs_segctor_cancel_free_segments(sci, nilfs->ns_sufile);
+ nilfs_segctor_clear_segment_buffers(sci);
+
+ err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
+ if (unlikely(err))
+ return err;
+
+ nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA);
+ sci->sc_stage = prev_stage;
+ }
+ nilfs_segctor_truncate_segments(sci, sci->sc_curseg, nilfs->ns_sufile);
+ return 0;
+
+ failed:
+ return err;
+}
+
+static void nilfs_list_replace_buffer(struct buffer_head *old_bh,
+ struct buffer_head *new_bh)
+{
+ BUG_ON(!list_empty(&new_bh->b_assoc_buffers));
+
+ list_replace_init(&old_bh->b_assoc_buffers, &new_bh->b_assoc_buffers);
+ /* The caller must release old_bh */
+}
+
+static int
+nilfs_segctor_update_payload_blocknr(struct nilfs_sc_info *sci,
+ struct nilfs_segment_buffer *segbuf,
+ int mode)
+{
+ struct inode *inode = NULL;
+ sector_t blocknr;
+ unsigned long nfinfo = segbuf->sb_sum.nfinfo;
+ unsigned long nblocks = 0, ndatablk = 0;
+ struct nilfs_sc_operations *sc_op = NULL;
+ struct nilfs_segsum_pointer ssp;
+ struct nilfs_finfo *finfo = NULL;
+ union nilfs_binfo binfo;
+ struct buffer_head *bh, *bh_org;
+ ino_t ino = 0;
+ int err = 0;
+
+ if (!nfinfo)
+ goto out;
+
+ blocknr = segbuf->sb_pseg_start + segbuf->sb_sum.nsumblk;
+ ssp.bh = NILFS_SEGBUF_FIRST_BH(&segbuf->sb_segsum_buffers);
+ ssp.offset = sizeof(struct nilfs_segment_summary);
+
+ list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) {
+ if (bh == sci->sc_super_root)
+ break;
+ if (!finfo) {
+ finfo = nilfs_segctor_map_segsum_entry(
+ sci, &ssp, sizeof(*finfo));
+ ino = le64_to_cpu(finfo->fi_ino);
+ nblocks = le32_to_cpu(finfo->fi_nblocks);
+ ndatablk = le32_to_cpu(finfo->fi_ndatablk);
+
+ if (buffer_nilfs_node(bh))
+ inode = NILFS_BTNC_I(bh->b_page->mapping);
+ else
+ inode = NILFS_AS_I(bh->b_page->mapping);
+
+ if (mode == SC_LSEG_DSYNC)
+ sc_op = &nilfs_sc_dsync_ops;
+ else if (ino == NILFS_DAT_INO)
+ sc_op = &nilfs_sc_dat_ops;
+ else /* file blocks */
+ sc_op = &nilfs_sc_file_ops;
+ }
+ bh_org = bh;
+ get_bh(bh_org);
+ err = nilfs_bmap_assign(NILFS_I(inode)->i_bmap, &bh, blocknr,
+ &binfo);
+ if (bh != bh_org)
+ nilfs_list_replace_buffer(bh_org, bh);
+ brelse(bh_org);
+ if (unlikely(err))
+ goto failed_bmap;
+
+ if (ndatablk > 0)
+ sc_op->write_data_binfo(sci, &ssp, &binfo);
+ else
+ sc_op->write_node_binfo(sci, &ssp, &binfo);
+
+ blocknr++;
+ if (--nblocks == 0) {
+ finfo = NULL;
+ if (--nfinfo == 0)
+ break;
+ } else if (ndatablk > 0)
+ ndatablk--;
+ }
+ out:
+ return 0;
+
+ failed_bmap:
+ err = nilfs_handle_bmap_error(err, __func__, inode, sci->sc_super);
+ return err;
+}
+
+static int nilfs_segctor_assign(struct nilfs_sc_info *sci, int mode)
+{
+ struct nilfs_segment_buffer *segbuf;
+ int err;
+
+ list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
+ err = nilfs_segctor_update_payload_blocknr(sci, segbuf, mode);
+ if (unlikely(err))
+ return err;
+ nilfs_segbuf_fill_in_segsum(segbuf);
+ }
+ return 0;
+}
+
+static int
+nilfs_copy_replace_page_buffers(struct page *page, struct list_head *out)
+{
+ struct page *clone_page;
+ struct buffer_head *bh, *head, *bh2;
+ void *kaddr;
+
+ bh = head = page_buffers(page);
+
+ clone_page = nilfs_alloc_private_page(bh->b_bdev, bh->b_size, 0);
+ if (unlikely(!clone_page))
+ return -ENOMEM;
+
+ bh2 = page_buffers(clone_page);
+ kaddr = kmap_atomic(page, KM_USER0);
+ do {
+ if (list_empty(&bh->b_assoc_buffers))
+ continue;
+ get_bh(bh2);
+ page_cache_get(clone_page); /* for each bh */
+ memcpy(bh2->b_data, kaddr + bh_offset(bh), bh2->b_size);
+ bh2->b_blocknr = bh->b_blocknr;
+ list_replace(&bh->b_assoc_buffers, &bh2->b_assoc_buffers);
+ list_add_tail(&bh->b_assoc_buffers, out);
+ } while (bh = bh->b_this_page, bh2 = bh2->b_this_page, bh != head);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ if (!TestSetPageWriteback(clone_page))
+ inc_zone_page_state(clone_page, NR_WRITEBACK);
+ unlock_page(clone_page);
+
+ return 0;
+}
+
+static int nilfs_test_page_to_be_frozen(struct page *page)
+{
+ struct address_space *mapping = page->mapping;
+
+ if (!mapping || !mapping->host || S_ISDIR(mapping->host->i_mode))
+ return 0;
+
+ if (page_mapped(page)) {
+ ClearPageChecked(page);
+ return 1;
+ }
+ return PageChecked(page);
+}
+
+static int nilfs_begin_page_io(struct page *page, struct list_head *out)
+{
+ if (!page || PageWriteback(page))
+ /* For split b-tree node pages, this function may be called
+ twice. We ignore the 2nd or later calls by this check. */
+ return 0;
+
+ lock_page(page);
+ clear_page_dirty_for_io(page);
+ set_page_writeback(page);
+ unlock_page(page);
+
+ if (nilfs_test_page_to_be_frozen(page)) {
+ int err = nilfs_copy_replace_page_buffers(page, out);
+ if (unlikely(err))
+ return err;
+ }
+ return 0;
+}
+
+static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci,
+ struct page **failed_page)
+{
+ struct nilfs_segment_buffer *segbuf;
+ struct page *bd_page = NULL, *fs_page = NULL;
+ struct list_head *list = &sci->sc_copied_buffers;
+ int err;
+
+ *failed_page = NULL;
+ list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
+ struct buffer_head *bh;
+
+ list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
+ b_assoc_buffers) {
+ if (bh->b_page != bd_page) {
+ if (bd_page) {
+ lock_page(bd_page);
+ clear_page_dirty_for_io(bd_page);
+ set_page_writeback(bd_page);
+ unlock_page(bd_page);
+ }
+ bd_page = bh->b_page;
+ }
+ }
+
+ list_for_each_entry(bh, &segbuf->sb_payload_buffers,
+ b_assoc_buffers) {
+ if (bh == sci->sc_super_root) {
+ if (bh->b_page != bd_page) {
+ lock_page(bd_page);
+ clear_page_dirty_for_io(bd_page);
+ set_page_writeback(bd_page);
+ unlock_page(bd_page);
+ bd_page = bh->b_page;
+ }
+ break;
+ }
+ if (bh->b_page != fs_page) {
+ err = nilfs_begin_page_io(fs_page, list);
+ if (unlikely(err)) {
+ *failed_page = fs_page;
+ goto out;
+ }
+ fs_page = bh->b_page;
+ }
+ }
+ }
+ if (bd_page) {
+ lock_page(bd_page);
+ clear_page_dirty_for_io(bd_page);
+ set_page_writeback(bd_page);
+ unlock_page(bd_page);
+ }
+ err = nilfs_begin_page_io(fs_page, list);
+ if (unlikely(err))
+ *failed_page = fs_page;
+ out:
+ return err;
+}
+
+static int nilfs_segctor_write(struct nilfs_sc_info *sci,
+ struct backing_dev_info *bdi)
+{
+ struct nilfs_segment_buffer *segbuf;
+ struct nilfs_write_info wi;
+ int err, res;
+
+ wi.sb = sci->sc_super;
+ wi.bh_sr = sci->sc_super_root;
+ wi.bdi = bdi;
+
+ list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
+ nilfs_segbuf_prepare_write(segbuf, &wi);
+ err = nilfs_segbuf_write(segbuf, &wi);
+
+ res = nilfs_segbuf_wait(segbuf, &wi);
+ err = unlikely(err) ? : res;
+ if (unlikely(err))
+ return err;
+ }
+ return 0;
+}
+
+static int nilfs_page_has_uncleared_buffer(struct page *page)
+{
+ struct buffer_head *head, *bh;
+
+ head = bh = page_buffers(page);
+ do {
+ if (buffer_dirty(bh) && !list_empty(&bh->b_assoc_buffers))
+ return 1;
+ bh = bh->b_this_page;
+ } while (bh != head);
+ return 0;
+}
+
+static void __nilfs_end_page_io(struct page *page, int err)
+{
+ if (!err) {
+ if (!nilfs_page_buffers_clean(page))
+ __set_page_dirty_nobuffers(page);
+ ClearPageError(page);
+ } else {
+ __set_page_dirty_nobuffers(page);
+ SetPageError(page);
+ }
+
+ if (buffer_nilfs_allocated(page_buffers(page))) {
+ if (TestClearPageWriteback(page))
+ dec_zone_page_state(page, NR_WRITEBACK);
+ } else
+ end_page_writeback(page);
+}
+
+static void nilfs_end_page_io(struct page *page, int err)
+{
+ if (!page)
+ return;
+
+ if (buffer_nilfs_node(page_buffers(page)) &&
+ nilfs_page_has_uncleared_buffer(page))
+ /* For b-tree node pages, this function may be called twice
+ or more because they might be split in a segment.
+ This check assures that cleanup has been done for all
+ buffers in a split btnode page. */
+ return;
+
+ __nilfs_end_page_io(page, err);
+}
+
+static void nilfs_clear_copied_buffers(struct list_head *list, int err)
+{
+ struct buffer_head *bh, *head;
+ struct page *page;
+
+ while (!list_empty(list)) {
+ bh = list_entry(list->next, struct buffer_head,
+ b_assoc_buffers);
+ page = bh->b_page;
+ page_cache_get(page);
+ head = bh = page_buffers(page);
+ do {
+ if (!list_empty(&bh->b_assoc_buffers)) {
+ list_del_init(&bh->b_assoc_buffers);
+ if (!err) {
+ set_buffer_uptodate(bh);
+ clear_buffer_dirty(bh);
+ clear_buffer_nilfs_volatile(bh);
+ }
+ brelse(bh); /* for b_assoc_buffers */
+ }
+ } while ((bh = bh->b_this_page) != head);
+
+ __nilfs_end_page_io(page, err);
+ page_cache_release(page);
+ }
+}
+
+static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci,
+ struct page *failed_page, int err)
+{
+ struct nilfs_segment_buffer *segbuf;
+ struct page *bd_page = NULL, *fs_page = NULL;
+
+ list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
+ struct buffer_head *bh;
+
+ list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
+ b_assoc_buffers) {
+ if (bh->b_page != bd_page) {
+ if (bd_page)
+ end_page_writeback(bd_page);
+ bd_page = bh->b_page;
+ }
+ }
+
+ list_for_each_entry(bh, &segbuf->sb_payload_buffers,
+ b_assoc_buffers) {
+ if (bh == sci->sc_super_root) {
+ if (bh->b_page != bd_page) {
+ end_page_writeback(bd_page);
+ bd_page = bh->b_page;
+ }
+ break;
+ }
+ if (bh->b_page != fs_page) {
+ nilfs_end_page_io(fs_page, err);
+ if (unlikely(fs_page == failed_page))
+ goto done;
+ fs_page = bh->b_page;
+ }
+ }
+ }
+ if (bd_page)
+ end_page_writeback(bd_page);
+
+ nilfs_end_page_io(fs_page, err);
+ done:
+ nilfs_clear_copied_buffers(&sci->sc_copied_buffers, err);
+}
+
+static void nilfs_set_next_segment(struct the_nilfs *nilfs,
+ struct nilfs_segment_buffer *segbuf)
+{
+ nilfs->ns_segnum = segbuf->sb_segnum;
+ nilfs->ns_nextnum = segbuf->sb_nextnum;
+ nilfs->ns_pseg_offset = segbuf->sb_pseg_start - segbuf->sb_fseg_start
+ + segbuf->sb_sum.nblocks;
+ nilfs->ns_seg_seq = segbuf->sb_sum.seg_seq;
+ nilfs->ns_ctime = segbuf->sb_sum.ctime;
+}
+
+static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
+{
+ struct nilfs_segment_buffer *segbuf;
+ struct page *bd_page = NULL, *fs_page = NULL;
+ struct nilfs_sb_info *sbi = sci->sc_sbi;
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ int update_sr = (sci->sc_super_root != NULL);
+
+ list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
+ struct buffer_head *bh;
+
+ list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
+ b_assoc_buffers) {
+ set_buffer_uptodate(bh);
+ clear_buffer_dirty(bh);
+ if (bh->b_page != bd_page) {
+ if (bd_page)
+ end_page_writeback(bd_page);
+ bd_page = bh->b_page;
+ }
+ }
+ /*
+ * We assume that the buffers which belong to the same page
+ * continue over the buffer list.
+ * Under this assumption, the last BHs of pages is
+ * identifiable by the discontinuity of bh->b_page
+ * (page != fs_page).
+ *
+ * For B-tree node blocks, however, this assumption is not
+ * guaranteed. The cleanup code of B-tree node pages needs
+ * special care.
+ */
+ list_for_each_entry(bh, &segbuf->sb_payload_buffers,
+ b_assoc_buffers) {
+ set_buffer_uptodate(bh);
+ clear_buffer_dirty(bh);
+ clear_buffer_nilfs_volatile(bh);
+ if (bh == sci->sc_super_root) {
+ if (bh->b_page != bd_page) {
+ end_page_writeback(bd_page);
+ bd_page = bh->b_page;
+ }
+ break;
+ }
+ if (bh->b_page != fs_page) {
+ nilfs_end_page_io(fs_page, 0);
+ fs_page = bh->b_page;
+ }
+ }
+
+ if (!NILFS_SEG_SIMPLEX(&segbuf->sb_sum)) {
+ if (NILFS_SEG_LOGBGN(&segbuf->sb_sum)) {
+ set_bit(NILFS_SC_UNCLOSED, &sci->sc_flags);
+ sci->sc_lseg_stime = jiffies;
+ }
+ if (NILFS_SEG_LOGEND(&segbuf->sb_sum))
+ clear_bit(NILFS_SC_UNCLOSED, &sci->sc_flags);
+ }
+ }
+ /*
+ * Since pages may continue over multiple segment buffers,
+ * end of the last page must be checked outside of the loop.
+ */
+ if (bd_page)
+ end_page_writeback(bd_page);
+
+ nilfs_end_page_io(fs_page, 0);
+
+ nilfs_clear_copied_buffers(&sci->sc_copied_buffers, 0);
+
+ nilfs_drop_collected_inodes(&sci->sc_dirty_files);
+
+ if (nilfs_doing_gc()) {
+ nilfs_drop_collected_inodes(&sci->sc_gc_inodes);
+ if (update_sr)
+ nilfs_commit_gcdat_inode(nilfs);
+ } else
+ nilfs->ns_nongc_ctime = sci->sc_seg_ctime;
+
+ sci->sc_nblk_inc += sci->sc_nblk_this_inc;
+
+ segbuf = NILFS_LAST_SEGBUF(&sci->sc_segbufs);
+ nilfs_set_next_segment(nilfs, segbuf);
+
+ if (update_sr) {
+ nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start,
+ segbuf->sb_sum.seg_seq, nilfs->ns_cno++);
+ sbi->s_super->s_dirt = 1;
+
+ clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
+ clear_bit(NILFS_SC_DIRTY, &sci->sc_flags);
+ set_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
+ } else
+ clear_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
+}
+
+static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci,
+ struct nilfs_sb_info *sbi)
+{
+ struct nilfs_inode_info *ii, *n;
+ __u64 cno = sbi->s_nilfs->ns_cno;
+
+ spin_lock(&sbi->s_inode_lock);
+ retry:
+ list_for_each_entry_safe(ii, n, &sbi->s_dirty_files, i_dirty) {
+ if (!ii->i_bh) {
+ struct buffer_head *ibh;
+ int err;
+
+ spin_unlock(&sbi->s_inode_lock);
+ err = nilfs_ifile_get_inode_block(
+ sbi->s_ifile, ii->vfs_inode.i_ino, &ibh);
+ if (unlikely(err)) {
+ nilfs_warning(sbi->s_super, __func__,
+ "failed to get inode block.\n");
+ return err;
+ }
+ nilfs_mdt_mark_buffer_dirty(ibh);
+ nilfs_mdt_mark_dirty(sbi->s_ifile);
+ spin_lock(&sbi->s_inode_lock);
+ if (likely(!ii->i_bh))
+ ii->i_bh = ibh;
+ else
+ brelse(ibh);
+ goto retry;
+ }
+ ii->i_cno = cno;
+
+ clear_bit(NILFS_I_QUEUED, &ii->i_state);
+ set_bit(NILFS_I_BUSY, &ii->i_state);
+ list_del(&ii->i_dirty);
+ list_add_tail(&ii->i_dirty, &sci->sc_dirty_files);
+ }
+ spin_unlock(&sbi->s_inode_lock);
+
+ NILFS_I(sbi->s_ifile)->i_cno = cno;
+
+ return 0;
+}
+
+static void nilfs_segctor_check_out_files(struct nilfs_sc_info *sci,
+ struct nilfs_sb_info *sbi)
+{
+ struct nilfs_transaction_info *ti = current->journal_info;
+ struct nilfs_inode_info *ii, *n;
+ __u64 cno = sbi->s_nilfs->ns_cno;
+
+ spin_lock(&sbi->s_inode_lock);
+ list_for_each_entry_safe(ii, n, &sci->sc_dirty_files, i_dirty) {
+ if (!test_and_clear_bit(NILFS_I_UPDATED, &ii->i_state) ||
+ test_bit(NILFS_I_DIRTY, &ii->i_state)) {
+ /* The current checkpoint number (=nilfs->ns_cno) is
+ changed between check-in and check-out only if the
+ super root is written out. So, we can update i_cno
+ for the inodes that remain in the dirty list. */
+ ii->i_cno = cno;
+ continue;
+ }
+ clear_bit(NILFS_I_BUSY, &ii->i_state);
+ brelse(ii->i_bh);
+ ii->i_bh = NULL;
+ list_del(&ii->i_dirty);
+ list_add_tail(&ii->i_dirty, &ti->ti_garbage);
+ }
+ spin_unlock(&sbi->s_inode_lock);
+}
+
+/*
+ * Main procedure of segment constructor
+ */
+static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
+{
+ struct nilfs_sb_info *sbi = sci->sc_sbi;
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ struct page *failed_page;
+ int err, has_sr = 0;
+
+ sci->sc_stage.scnt = NILFS_ST_INIT;
+
+ err = nilfs_segctor_check_in_files(sci, sbi);
+ if (unlikely(err))
+ goto out;
+
+ if (nilfs_test_metadata_dirty(sbi))
+ set_bit(NILFS_SC_DIRTY, &sci->sc_flags);
+
+ if (nilfs_segctor_clean(sci))
+ goto out;
+
+ do {
+ sci->sc_stage.flags &= ~NILFS_CF_HISTORY_MASK;
+
+ err = nilfs_segctor_begin_construction(sci, nilfs);
+ if (unlikely(err))
+ goto out;
+
+ /* Update time stamp */
+ sci->sc_seg_ctime = get_seconds();
+
+ err = nilfs_segctor_collect(sci, nilfs, mode);
+ if (unlikely(err))
+ goto failed;
+
+ has_sr = (sci->sc_super_root != NULL);
+
+ /* Avoid empty segment */
+ if (sci->sc_stage.scnt == NILFS_ST_DONE &&
+ NILFS_SEG_EMPTY(&sci->sc_curseg->sb_sum)) {
+ nilfs_segctor_end_construction(sci, nilfs, 1);
+ goto out;
+ }
+
+ err = nilfs_segctor_assign(sci, mode);
+ if (unlikely(err))
+ goto failed;
+
+ if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
+ nilfs_segctor_fill_in_file_bmap(sci, sbi->s_ifile);
+
+ if (has_sr) {
+ err = nilfs_segctor_fill_in_checkpoint(sci);
+ if (unlikely(err))
+ goto failed_to_make_up;
+
+ nilfs_segctor_fill_in_super_root(sci, nilfs);
+ }
+ nilfs_segctor_update_segusage(sci, nilfs->ns_sufile);
+
+ /* Write partial segments */
+ err = nilfs_segctor_prepare_write(sci, &failed_page);
+ if (unlikely(err))
+ goto failed_to_write;
+
+ nilfs_segctor_fill_in_checksums(sci, nilfs->ns_crc_seed);
+
+ err = nilfs_segctor_write(sci, nilfs->ns_bdi);
+ if (unlikely(err))
+ goto failed_to_write;
+
+ nilfs_segctor_complete_write(sci);
+
+ /* Commit segments */
+ if (has_sr) {
+ nilfs_segctor_commit_free_segments(sci);
+ nilfs_segctor_clear_metadata_dirty(sci);
+ }
+
+ nilfs_segctor_end_construction(sci, nilfs, 0);
+
+ } while (sci->sc_stage.scnt != NILFS_ST_DONE);
+
+ out:
+ nilfs_segctor_destroy_segment_buffers(sci);
+ nilfs_segctor_check_out_files(sci, sbi);
+ return err;
+
+ failed_to_write:
+ nilfs_segctor_abort_write(sci, failed_page, err);
+ nilfs_segctor_cancel_segusage(sci, nilfs->ns_sufile);
+
+ failed_to_make_up:
+ if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
+ nilfs_redirty_inodes(&sci->sc_dirty_files);
+
+ failed:
+ if (nilfs_doing_gc())
+ nilfs_redirty_inodes(&sci->sc_gc_inodes);
+ nilfs_segctor_end_construction(sci, nilfs, err);
+ goto out;
+}
+
+/**
+ * nilfs_secgtor_start_timer - set timer of background write
+ * @sci: nilfs_sc_info
+ *
+ * If the timer has already been set, it ignores the new request.
+ * This function MUST be called within a section locking the segment
+ * semaphore.
+ */
+static void nilfs_segctor_start_timer(struct nilfs_sc_info *sci)
+{
+ spin_lock(&sci->sc_state_lock);
+ if (sci->sc_timer && !(sci->sc_state & NILFS_SEGCTOR_COMMIT)) {
+ sci->sc_timer->expires = jiffies + sci->sc_interval;
+ add_timer(sci->sc_timer);
+ sci->sc_state |= NILFS_SEGCTOR_COMMIT;
+ }
+ spin_unlock(&sci->sc_state_lock);
+}
+
+static void nilfs_segctor_do_flush(struct nilfs_sc_info *sci, int bn)
+{
+ spin_lock(&sci->sc_state_lock);
+ if (!(sci->sc_flush_request & (1 << bn))) {
+ unsigned long prev_req = sci->sc_flush_request;
+
+ sci->sc_flush_request |= (1 << bn);
+ if (!prev_req)
+ wake_up(&sci->sc_wait_daemon);
+ }
+ spin_unlock(&sci->sc_state_lock);
+}
+
+/**
+ * nilfs_flush_segment - trigger a segment construction for resource control
+ * @sb: super block
+ * @ino: inode number of the file to be flushed out.
+ */
+void nilfs_flush_segment(struct super_block *sb, ino_t ino)
+{
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ struct nilfs_sc_info *sci = NILFS_SC(sbi);
+
+ if (!sci || nilfs_doing_construction())
+ return;
+ nilfs_segctor_do_flush(sci, NILFS_MDT_INODE(sb, ino) ? ino : 0);
+ /* assign bit 0 to data files */
+}
+
+int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *sci,
+ __u64 *segnum, size_t nsegs)
+{
+ struct nilfs_segment_entry *ent;
+ struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs;
+ struct inode *sufile = nilfs->ns_sufile;
+ LIST_HEAD(list);
+ __u64 *pnum;
+ size_t i;
+ int err;
+
+ for (pnum = segnum, i = 0; i < nsegs; pnum++, i++) {
+ ent = nilfs_alloc_segment_entry(*pnum);
+ if (unlikely(!ent)) {
+ err = -ENOMEM;
+ goto failed;
+ }
+ list_add_tail(&ent->list, &list);
+
+ err = nilfs_open_segment_entry(ent, sufile);
+ if (unlikely(err))
+ goto failed;
+
+ if (unlikely(!nilfs_segment_usage_dirty(ent->raw_su)))
+ printk(KERN_WARNING "NILFS: unused segment is "
+ "requested to be cleaned (segnum=%llu)\n",
+ (unsigned long long)ent->segnum);
+ nilfs_close_segment_entry(ent, sufile);
+ }
+ list_splice(&list, sci->sc_cleaning_segments.prev);
+ return 0;
+
+ failed:
+ nilfs_dispose_segment_list(&list);
+ return err;
+}
+
+void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *sci)
+{
+ nilfs_dispose_segment_list(&sci->sc_cleaning_segments);
+}
+
+struct nilfs_segctor_wait_request {
+ wait_queue_t wq;
+ __u32 seq;
+ int err;
+ atomic_t done;
+};
+
+static int nilfs_segctor_sync(struct nilfs_sc_info *sci)
+{
+ struct nilfs_segctor_wait_request wait_req;
+ int err = 0;
+
+ spin_lock(&sci->sc_state_lock);
+ init_wait(&wait_req.wq);
+ wait_req.err = 0;
+ atomic_set(&wait_req.done, 0);
+ wait_req.seq = ++sci->sc_seq_request;
+ spin_unlock(&sci->sc_state_lock);
+
+ init_waitqueue_entry(&wait_req.wq, current);
+ add_wait_queue(&sci->sc_wait_request, &wait_req.wq);
+ set_current_state(TASK_INTERRUPTIBLE);
+ wake_up(&sci->sc_wait_daemon);
+
+ for (;;) {
+ if (atomic_read(&wait_req.done)) {
+ err = wait_req.err;
+ break;
+ }
+ if (!signal_pending(current)) {
+ schedule();
+ continue;
+ }
+ err = -ERESTARTSYS;
+ break;
+ }
+ finish_wait(&sci->sc_wait_request, &wait_req.wq);
+ return err;
+}
+
+static void nilfs_segctor_wakeup(struct nilfs_sc_info *sci, int err)
+{
+ struct nilfs_segctor_wait_request *wrq, *n;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sci->sc_wait_request.lock, flags);
+ list_for_each_entry_safe(wrq, n, &sci->sc_wait_request.task_list,
+ wq.task_list) {
+ if (!atomic_read(&wrq->done) &&
+ nilfs_cnt32_ge(sci->sc_seq_done, wrq->seq)) {
+ wrq->err = err;
+ atomic_set(&wrq->done, 1);
+ }
+ if (atomic_read(&wrq->done)) {
+ wrq->wq.func(&wrq->wq,
+ TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE,
+ 0, NULL);
+ }
+ }
+ spin_unlock_irqrestore(&sci->sc_wait_request.lock, flags);
+}
+
+/**
+ * nilfs_construct_segment - construct a logical segment
+ * @sb: super block
+ *
+ * Return Value: On success, 0 is retured. On errors, one of the following
+ * negative error code is returned.
+ *
+ * %-EROFS - Read only filesystem.
+ *
+ * %-EIO - I/O error
+ *
+ * %-ENOSPC - No space left on device (only in a panic state).
+ *
+ * %-ERESTARTSYS - Interrupted.
+ *
+ * %-ENOMEM - Insufficient memory available.
+ */
+int nilfs_construct_segment(struct super_block *sb)
+{
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ struct nilfs_sc_info *sci = NILFS_SC(sbi);
+ struct nilfs_transaction_info *ti;
+ int err;
+
+ if (!sci)
+ return -EROFS;
+
+ /* A call inside transactions causes a deadlock. */
+ BUG_ON((ti = current->journal_info) && ti->ti_magic == NILFS_TI_MAGIC);
+
+ err = nilfs_segctor_sync(sci);
+ return err;
+}
+
+/**
+ * nilfs_construct_dsync_segment - construct a data-only logical segment
+ * @sb: super block
+ * @inode: inode whose data blocks should be written out
+ * @start: start byte offset
+ * @end: end byte offset (inclusive)
+ *
+ * Return Value: On success, 0 is retured. On errors, one of the following
+ * negative error code is returned.
+ *
+ * %-EROFS - Read only filesystem.
+ *
+ * %-EIO - I/O error
+ *
+ * %-ENOSPC - No space left on device (only in a panic state).
+ *
+ * %-ERESTARTSYS - Interrupted.
+ *
+ * %-ENOMEM - Insufficient memory available.
+ */
+int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,
+ loff_t start, loff_t end)
+{
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ struct nilfs_sc_info *sci = NILFS_SC(sbi);
+ struct nilfs_inode_info *ii;
+ struct nilfs_transaction_info ti;
+ int err = 0;
+
+ if (!sci)
+ return -EROFS;
+
+ nilfs_transaction_lock(sbi, &ti, 0);
+
+ ii = NILFS_I(inode);
+ if (test_bit(NILFS_I_INODE_DIRTY, &ii->i_state) ||
+ nilfs_test_opt(sbi, STRICT_ORDER) ||
+ test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags) ||
+ nilfs_discontinued(sbi->s_nilfs)) {
+ nilfs_transaction_unlock(sbi);
+ err = nilfs_segctor_sync(sci);
+ return err;
+ }
+
+ spin_lock(&sbi->s_inode_lock);
+ if (!test_bit(NILFS_I_QUEUED, &ii->i_state) &&
+ !test_bit(NILFS_I_BUSY, &ii->i_state)) {
+ spin_unlock(&sbi->s_inode_lock);
+ nilfs_transaction_unlock(sbi);
+ return 0;
+ }
+ spin_unlock(&sbi->s_inode_lock);
+ sci->sc_dsync_inode = ii;
+ sci->sc_dsync_start = start;
+ sci->sc_dsync_end = end;
+
+ err = nilfs_segctor_do_construct(sci, SC_LSEG_DSYNC);
+
+ nilfs_transaction_unlock(sbi);
+ return err;
+}
+
+struct nilfs_segctor_req {
+ int mode;
+ __u32 seq_accepted;
+ int sc_err; /* construction failure */
+ int sb_err; /* super block writeback failure */
+};
+
+#define FLUSH_FILE_BIT (0x1) /* data file only */
+#define FLUSH_DAT_BIT (1 << NILFS_DAT_INO) /* DAT only */
+
+static void nilfs_segctor_accept(struct nilfs_sc_info *sci,
+ struct nilfs_segctor_req *req)
+{
+ req->sc_err = req->sb_err = 0;
+ spin_lock(&sci->sc_state_lock);
+ req->seq_accepted = sci->sc_seq_request;
+ spin_unlock(&sci->sc_state_lock);
+
+ if (sci->sc_timer)
+ del_timer_sync(sci->sc_timer);
+}
+
+static void nilfs_segctor_notify(struct nilfs_sc_info *sci,
+ struct nilfs_segctor_req *req)
+{
+ /* Clear requests (even when the construction failed) */
+ spin_lock(&sci->sc_state_lock);
+
+ sci->sc_state &= ~NILFS_SEGCTOR_COMMIT;
+
+ if (req->mode == SC_LSEG_SR) {
+ sci->sc_seq_done = req->seq_accepted;
+ nilfs_segctor_wakeup(sci, req->sc_err ? : req->sb_err);
+ sci->sc_flush_request = 0;
+ } else if (req->mode == SC_FLUSH_FILE)
+ sci->sc_flush_request &= ~FLUSH_FILE_BIT;
+ else if (req->mode == SC_FLUSH_DAT)
+ sci->sc_flush_request &= ~FLUSH_DAT_BIT;
+
+ spin_unlock(&sci->sc_state_lock);
+}
+
+static int nilfs_segctor_construct(struct nilfs_sc_info *sci,
+ struct nilfs_segctor_req *req)
+{
+ struct nilfs_sb_info *sbi = sci->sc_sbi;
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ int err = 0;
+
+ if (nilfs_discontinued(nilfs))
+ req->mode = SC_LSEG_SR;
+ if (!nilfs_segctor_confirm(sci)) {
+ err = nilfs_segctor_do_construct(sci, req->mode);
+ req->sc_err = err;
+ }
+ if (likely(!err)) {
+ if (req->mode != SC_FLUSH_DAT)
+ atomic_set(&nilfs->ns_ndirtyblks, 0);
+ if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) &&
+ nilfs_discontinued(nilfs)) {
+ down_write(&nilfs->ns_sem);
+ req->sb_err = nilfs_commit_super(sbi, 0);
+ up_write(&nilfs->ns_sem);
+ }
+ }
+ return err;
+}
+
+static void nilfs_construction_timeout(unsigned long data)
+{
+ struct task_struct *p = (struct task_struct *)data;
+ wake_up_process(p);
+}
+
+static void
+nilfs_remove_written_gcinodes(struct the_nilfs *nilfs, struct list_head *head)
+{
+ struct nilfs_inode_info *ii, *n;
+
+ list_for_each_entry_safe(ii, n, head, i_dirty) {
+ if (!test_bit(NILFS_I_UPDATED, &ii->i_state))
+ continue;
+ hlist_del_init(&ii->vfs_inode.i_hash);
+ list_del_init(&ii->i_dirty);
+ nilfs_clear_gcinode(&ii->vfs_inode);
+ }
+}
+
+int nilfs_clean_segments(struct super_block *sb, void __user *argp)
+{
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ struct nilfs_sc_info *sci = NILFS_SC(sbi);
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ struct nilfs_transaction_info ti;
+ struct nilfs_segctor_req req = { .mode = SC_LSEG_SR };
+ int err;
+
+ if (unlikely(!sci))
+ return -EROFS;
+
+ nilfs_transaction_lock(sbi, &ti, 1);
+
+ err = nilfs_init_gcdat_inode(nilfs);
+ if (unlikely(err))
+ goto out_unlock;
+ err = nilfs_ioctl_prepare_clean_segments(nilfs, argp);
+ if (unlikely(err))
+ goto out_unlock;
+
+ list_splice_init(&nilfs->ns_gc_inodes, sci->sc_gc_inodes.prev);
+
+ for (;;) {
+ nilfs_segctor_accept(sci, &req);
+ err = nilfs_segctor_construct(sci, &req);
+ nilfs_remove_written_gcinodes(nilfs, &sci->sc_gc_inodes);
+ nilfs_segctor_notify(sci, &req);
+
+ if (likely(!err))
+ break;
+
+ nilfs_warning(sb, __func__,
+ "segment construction failed. (err=%d)", err);
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(sci->sc_interval);
+ }
+
+ out_unlock:
+ nilfs_clear_gcdat_inode(nilfs);
+ nilfs_transaction_unlock(sbi);
+ return err;
+}
+
+static void nilfs_segctor_thread_construct(struct nilfs_sc_info *sci, int mode)
+{
+ struct nilfs_sb_info *sbi = sci->sc_sbi;
+ struct nilfs_transaction_info ti;
+ struct nilfs_segctor_req req = { .mode = mode };
+
+ nilfs_transaction_lock(sbi, &ti, 0);
+
+ nilfs_segctor_accept(sci, &req);
+ nilfs_segctor_construct(sci, &req);
+ nilfs_segctor_notify(sci, &req);
+
+ /*
+ * Unclosed segment should be retried. We do this using sc_timer.
+ * Timeout of sc_timer will invoke complete construction which leads
+ * to close the current logical segment.
+ */
+ if (test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags))
+ nilfs_segctor_start_timer(sci);
+
+ nilfs_transaction_unlock(sbi);
+}
+
+static void nilfs_segctor_do_immediate_flush(struct nilfs_sc_info *sci)
+{
+ int mode = 0;
+ int err;
+
+ spin_lock(&sci->sc_state_lock);
+ mode = (sci->sc_flush_request & FLUSH_DAT_BIT) ?
+ SC_FLUSH_DAT : SC_FLUSH_FILE;
+ spin_unlock(&sci->sc_state_lock);
+
+ if (mode) {
+ err = nilfs_segctor_do_construct(sci, mode);
+
+ spin_lock(&sci->sc_state_lock);
+ sci->sc_flush_request &= (mode == SC_FLUSH_FILE) ?
+ ~FLUSH_FILE_BIT : ~FLUSH_DAT_BIT;
+ spin_unlock(&sci->sc_state_lock);
+ }
+ clear_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags);
+}
+
+static int nilfs_segctor_flush_mode(struct nilfs_sc_info *sci)
+{
+ if (!test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags) ||
+ time_before(jiffies, sci->sc_lseg_stime + sci->sc_mjcp_freq)) {
+ if (!(sci->sc_flush_request & ~FLUSH_FILE_BIT))
+ return SC_FLUSH_FILE;
+ else if (!(sci->sc_flush_request & ~FLUSH_DAT_BIT))
+ return SC_FLUSH_DAT;
+ }
+ return SC_LSEG_SR;
+}
+
+/**
+ * nilfs_segctor_thread - main loop of the segment constructor thread.
+ * @arg: pointer to a struct nilfs_sc_info.
+ *
+ * nilfs_segctor_thread() initializes a timer and serves as a daemon
+ * to execute segment constructions.
+ */
+static int nilfs_segctor_thread(void *arg)
+{
+ struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg;
+ struct timer_list timer;
+ int timeout = 0;
+
+ init_timer(&timer);
+ timer.data = (unsigned long)current;
+ timer.function = nilfs_construction_timeout;
+ sci->sc_timer = &timer;
+
+ /* start sync. */
+ sci->sc_task = current;
+ wake_up(&sci->sc_wait_task); /* for nilfs_segctor_start_thread() */
+ printk(KERN_INFO
+ "segctord starting. Construction interval = %lu seconds, "
+ "CP frequency < %lu seconds\n",
+ sci->sc_interval / HZ, sci->sc_mjcp_freq / HZ);
+
+ spin_lock(&sci->sc_state_lock);
+ loop:
+ for (;;) {
+ int mode;
+
+ if (sci->sc_state & NILFS_SEGCTOR_QUIT)
+ goto end_thread;
+
+ if (timeout || sci->sc_seq_request != sci->sc_seq_done)
+ mode = SC_LSEG_SR;
+ else if (!sci->sc_flush_request)
+ break;
+ else
+ mode = nilfs_segctor_flush_mode(sci);
+
+ spin_unlock(&sci->sc_state_lock);
+ nilfs_segctor_thread_construct(sci, mode);
+ spin_lock(&sci->sc_state_lock);
+ timeout = 0;
+ }
+
+
+ if (freezing(current)) {
+ spin_unlock(&sci->sc_state_lock);
+ refrigerator();
+ spin_lock(&sci->sc_state_lock);
+ } else {
+ DEFINE_WAIT(wait);
+ int should_sleep = 1;
+
+ prepare_to_wait(&sci->sc_wait_daemon, &wait,
+ TASK_INTERRUPTIBLE);
+
+ if (sci->sc_seq_request != sci->sc_seq_done)
+ should_sleep = 0;
+ else if (sci->sc_flush_request)
+ should_sleep = 0;
+ else if (sci->sc_state & NILFS_SEGCTOR_COMMIT)
+ should_sleep = time_before(jiffies,
+ sci->sc_timer->expires);
+
+ if (should_sleep) {
+ spin_unlock(&sci->sc_state_lock);
+ schedule();
+ spin_lock(&sci->sc_state_lock);
+ }
+ finish_wait(&sci->sc_wait_daemon, &wait);
+ timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) &&
+ time_after_eq(jiffies, sci->sc_timer->expires));
+ }
+ goto loop;
+
+ end_thread:
+ spin_unlock(&sci->sc_state_lock);
+ del_timer_sync(sci->sc_timer);
+ sci->sc_timer = NULL;
+
+ /* end sync. */
+ sci->sc_task = NULL;
+ wake_up(&sci->sc_wait_task); /* for nilfs_segctor_kill_thread() */
+ return 0;
+}
+
+static int nilfs_segctor_start_thread(struct nilfs_sc_info *sci)
+{
+ struct task_struct *t;
+
+ t = kthread_run(nilfs_segctor_thread, sci, "segctord");
+ if (IS_ERR(t)) {
+ int err = PTR_ERR(t);
+
+ printk(KERN_ERR "NILFS: error %d creating segctord thread\n",
+ err);
+ return err;
+ }
+ wait_event(sci->sc_wait_task, sci->sc_task != NULL);
+ return 0;
+}
+
+static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci)
+{
+ sci->sc_state |= NILFS_SEGCTOR_QUIT;
+
+ while (sci->sc_task) {
+ wake_up(&sci->sc_wait_daemon);
+ spin_unlock(&sci->sc_state_lock);
+ wait_event(sci->sc_wait_task, sci->sc_task == NULL);
+ spin_lock(&sci->sc_state_lock);
+ }
+}
+
+static int nilfs_segctor_init(struct nilfs_sc_info *sci)
+{
+ sci->sc_seq_done = sci->sc_seq_request;
+
+ return nilfs_segctor_start_thread(sci);
+}
+
+/*
+ * Setup & clean-up functions
+ */
+static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi)
+{
+ struct nilfs_sc_info *sci;
+
+ sci = kzalloc(sizeof(*sci), GFP_KERNEL);
+ if (!sci)
+ return NULL;
+
+ sci->sc_sbi = sbi;
+ sci->sc_super = sbi->s_super;
+
+ init_waitqueue_head(&sci->sc_wait_request);
+ init_waitqueue_head(&sci->sc_wait_daemon);
+ init_waitqueue_head(&sci->sc_wait_task);
+ spin_lock_init(&sci->sc_state_lock);
+ INIT_LIST_HEAD(&sci->sc_dirty_files);
+ INIT_LIST_HEAD(&sci->sc_segbufs);
+ INIT_LIST_HEAD(&sci->sc_gc_inodes);
+ INIT_LIST_HEAD(&sci->sc_cleaning_segments);
+ INIT_LIST_HEAD(&sci->sc_copied_buffers);
+
+ sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT;
+ sci->sc_mjcp_freq = HZ * NILFS_SC_DEFAULT_SR_FREQ;
+ sci->sc_watermark = NILFS_SC_DEFAULT_WATERMARK;
+
+ if (sbi->s_interval)
+ sci->sc_interval = sbi->s_interval;
+ if (sbi->s_watermark)
+ sci->sc_watermark = sbi->s_watermark;
+ return sci;
+}
+
+static void nilfs_segctor_write_out(struct nilfs_sc_info *sci)
+{
+ int ret, retrycount = NILFS_SC_CLEANUP_RETRY;
+
+ /* The segctord thread was stopped and its timer was removed.
+ But some tasks remain. */
+ do {
+ struct nilfs_sb_info *sbi = sci->sc_sbi;
+ struct nilfs_transaction_info ti;
+ struct nilfs_segctor_req req = { .mode = SC_LSEG_SR };
+
+ nilfs_transaction_lock(sbi, &ti, 0);
+ nilfs_segctor_accept(sci, &req);
+ ret = nilfs_segctor_construct(sci, &req);
+ nilfs_segctor_notify(sci, &req);
+ nilfs_transaction_unlock(sbi);
+
+ } while (ret && retrycount-- > 0);
+}
+
+/**
+ * nilfs_segctor_destroy - destroy the segment constructor.
+ * @sci: nilfs_sc_info
+ *
+ * nilfs_segctor_destroy() kills the segctord thread and frees
+ * the nilfs_sc_info struct.
+ * Caller must hold the segment semaphore.
+ */
+static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
+{
+ struct nilfs_sb_info *sbi = sci->sc_sbi;
+ int flag;
+
+ up_write(&sbi->s_nilfs->ns_segctor_sem);
+
+ spin_lock(&sci->sc_state_lock);
+ nilfs_segctor_kill_thread(sci);
+ flag = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) || sci->sc_flush_request
+ || sci->sc_seq_request != sci->sc_seq_done);
+ spin_unlock(&sci->sc_state_lock);
+
+ if (flag || nilfs_segctor_confirm(sci))
+ nilfs_segctor_write_out(sci);
+
+ WARN_ON(!list_empty(&sci->sc_copied_buffers));
+
+ if (!list_empty(&sci->sc_dirty_files)) {
+ nilfs_warning(sbi->s_super, __func__,
+ "dirty file(s) after the final construction\n");
+ nilfs_dispose_list(sbi, &sci->sc_dirty_files, 1);
+ }
+
+ if (!list_empty(&sci->sc_cleaning_segments))
+ nilfs_dispose_segment_list(&sci->sc_cleaning_segments);
+
+ WARN_ON(!list_empty(&sci->sc_segbufs));
+
+ down_write(&sbi->s_nilfs->ns_segctor_sem);
+
+ kfree(sci);
+}
+
+/**
+ * nilfs_attach_segment_constructor - attach a segment constructor
+ * @sbi: nilfs_sb_info
+ *
+ * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info,
+ * initilizes it, and starts the segment constructor.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error code is returned.
+ *
+ * %-ENOMEM - Insufficient memory available.
+ */
+int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi)
+{
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ int err;
+
+ /* Each field of nilfs_segctor is cleared through the initialization
+ of super-block info */
+ sbi->s_sc_info = nilfs_segctor_new(sbi);
+ if (!sbi->s_sc_info)
+ return -ENOMEM;
+
+ nilfs_attach_writer(nilfs, sbi);
+ err = nilfs_segctor_init(NILFS_SC(sbi));
+ if (err) {
+ nilfs_detach_writer(nilfs, sbi);
+ kfree(sbi->s_sc_info);
+ sbi->s_sc_info = NULL;
+ }
+ return err;
+}
+
+/**
+ * nilfs_detach_segment_constructor - destroy the segment constructor
+ * @sbi: nilfs_sb_info
+ *
+ * nilfs_detach_segment_constructor() kills the segment constructor daemon,
+ * frees the struct nilfs_sc_info, and destroy the dirty file list.
+ */
+void nilfs_detach_segment_constructor(struct nilfs_sb_info *sbi)
+{
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ LIST_HEAD(garbage_list);
+
+ down_write(&nilfs->ns_segctor_sem);
+ if (NILFS_SC(sbi)) {
+ nilfs_segctor_destroy(NILFS_SC(sbi));
+ sbi->s_sc_info = NULL;
+ }
+
+ /* Force to free the list of dirty files */
+ spin_lock(&sbi->s_inode_lock);
+ if (!list_empty(&sbi->s_dirty_files)) {
+ list_splice_init(&sbi->s_dirty_files, &garbage_list);
+ nilfs_warning(sbi->s_super, __func__,
+ "Non empty dirty list after the last "
+ "segment construction\n");
+ }
+ spin_unlock(&sbi->s_inode_lock);
+ up_write(&nilfs->ns_segctor_sem);
+
+ nilfs_dispose_list(sbi, &garbage_list, 1);
+ nilfs_detach_writer(nilfs, sbi);
+}
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
new file mode 100644
index 00000000000..a98fc1ed0bb
--- /dev/null
+++ b/fs/nilfs2/segment.h
@@ -0,0 +1,243 @@
+/*
+ * segment.h - NILFS Segment constructor prototypes and definitions
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>
+ *
+ */
+#ifndef _NILFS_SEGMENT_H
+#define _NILFS_SEGMENT_H
+
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/nilfs2_fs.h>
+#include "sb.h"
+
+/**
+ * struct nilfs_recovery_info - Recovery infomation
+ * @ri_need_recovery: Recovery status
+ * @ri_super_root: Block number of the last super root
+ * @ri_ri_cno: Number of the last checkpoint
+ * @ri_lsegs_start: Region for roll-forwarding (start block number)
+ * @ri_lsegs_end: Region for roll-forwarding (end block number)
+ * @ri_lseg_start_seq: Sequence value of the segment at ri_lsegs_start
+ * @ri_used_segments: List of segments to be mark active
+ * @ri_pseg_start: Block number of the last partial segment
+ * @ri_seq: Sequence number on the last partial segment
+ * @ri_segnum: Segment number on the last partial segment
+ * @ri_nextnum: Next segment number on the last partial segment
+ */
+struct nilfs_recovery_info {
+ int ri_need_recovery;
+ sector_t ri_super_root;
+ __u64 ri_cno;
+
+ sector_t ri_lsegs_start;
+ sector_t ri_lsegs_end;
+ u64 ri_lsegs_start_seq;
+ struct list_head ri_used_segments;
+ sector_t ri_pseg_start;
+ u64 ri_seq;
+ __u64 ri_segnum;
+ __u64 ri_nextnum;
+};
+
+/* ri_need_recovery */
+#define NILFS_RECOVERY_SR_UPDATED 1 /* The super root was updated */
+#define NILFS_RECOVERY_ROLLFORWARD_DONE 2 /* Rollforward was carried out */
+
+/**
+ * struct nilfs_cstage - Context of collection stage
+ * @scnt: Stage count
+ * @flags: State flags
+ * @dirty_file_ptr: Pointer on dirty_files list, or inode of a target file
+ * @gc_inode_ptr: Pointer on the list of gc-inodes
+ */
+struct nilfs_cstage {
+ int scnt;
+ unsigned flags;
+ struct nilfs_inode_info *dirty_file_ptr;
+ struct nilfs_inode_info *gc_inode_ptr;
+};
+
+struct nilfs_segment_buffer;
+
+struct nilfs_segsum_pointer {
+ struct buffer_head *bh;
+ unsigned offset; /* offset in bytes */
+};
+
+/**
+ * struct nilfs_sc_info - Segment constructor information
+ * @sc_super: Back pointer to super_block struct
+ * @sc_sbi: Back pointer to nilfs_sb_info struct
+ * @sc_nblk_inc: Block count of current generation
+ * @sc_dirty_files: List of files to be written
+ * @sc_gc_inodes: List of GC inodes having blocks to be written
+ * @sc_cleaning_segments: List of segments to be freed through construction
+ * @sc_copied_buffers: List of copied buffers (buffer heads) to freeze data
+ * @sc_dsync_inode: inode whose data pages are written for a sync operation
+ * @sc_dsync_start: start byte offset of data pages
+ * @sc_dsync_end: end byte offset of data pages (inclusive)
+ * @sc_segbufs: List of segment buffers
+ * @sc_segbuf_nblocks: Number of available blocks in segment buffers.
+ * @sc_curseg: Current segment buffer
+ * @sc_super_root: Pointer to the super root buffer
+ * @sc_stage: Collection stage
+ * @sc_finfo_ptr: pointer to the current finfo struct in the segment summary
+ * @sc_binfo_ptr: pointer to the current binfo struct in the segment summary
+ * @sc_blk_cnt: Block count of a file
+ * @sc_datablk_cnt: Data block count of a file
+ * @sc_nblk_this_inc: Number of blocks included in the current logical segment
+ * @sc_seg_ctime: Creation time
+ * @sc_flags: Internal flags
+ * @sc_state_lock: spinlock for sc_state and so on
+ * @sc_state: Segctord state flags
+ * @sc_flush_request: inode bitmap of metadata files to be flushed
+ * @sc_wait_request: Client request queue
+ * @sc_wait_daemon: Daemon wait queue
+ * @sc_wait_task: Start/end wait queue to control segctord task
+ * @sc_seq_request: Request counter
+ * @sc_seq_done: Completion counter
+ * @sc_sync: Request of explicit sync operation
+ * @sc_interval: Timeout value of background construction
+ * @sc_mjcp_freq: Frequency of creating checkpoints
+ * @sc_lseg_stime: Start time of the latest logical segment
+ * @sc_watermark: Watermark for the number of dirty buffers
+ * @sc_timer: Timer for segctord
+ * @sc_task: current thread of segctord
+ */
+struct nilfs_sc_info {
+ struct super_block *sc_super;
+ struct nilfs_sb_info *sc_sbi;
+
+ unsigned long sc_nblk_inc;
+
+ struct list_head sc_dirty_files;
+ struct list_head sc_gc_inodes;
+ struct list_head sc_cleaning_segments;
+ struct list_head sc_copied_buffers;
+
+ struct nilfs_inode_info *sc_dsync_inode;
+ loff_t sc_dsync_start;
+ loff_t sc_dsync_end;
+
+ /* Segment buffers */
+ struct list_head sc_segbufs;
+ unsigned long sc_segbuf_nblocks;
+ struct nilfs_segment_buffer *sc_curseg;
+ struct buffer_head *sc_super_root;
+
+ struct nilfs_cstage sc_stage;
+
+ struct nilfs_segsum_pointer sc_finfo_ptr;
+ struct nilfs_segsum_pointer sc_binfo_ptr;
+ unsigned long sc_blk_cnt;
+ unsigned long sc_datablk_cnt;
+ unsigned long sc_nblk_this_inc;
+ time_t sc_seg_ctime;
+
+ unsigned long sc_flags;
+
+ spinlock_t sc_state_lock;
+ unsigned long sc_state;
+ unsigned long sc_flush_request;
+
+ wait_queue_head_t sc_wait_request;
+ wait_queue_head_t sc_wait_daemon;
+ wait_queue_head_t sc_wait_task;
+
+ __u32 sc_seq_request;
+ __u32 sc_seq_done;
+
+ int sc_sync;
+ unsigned long sc_interval;
+ unsigned long sc_mjcp_freq;
+ unsigned long sc_lseg_stime; /* in 1/HZ seconds */
+ unsigned long sc_watermark;
+
+ struct timer_list *sc_timer;
+ struct task_struct *sc_task;
+};
+
+/* sc_flags */
+enum {
+ NILFS_SC_DIRTY, /* One or more dirty meta-data blocks exist */
+ NILFS_SC_UNCLOSED, /* Logical segment is not closed */
+ NILFS_SC_SUPER_ROOT, /* The latest segment has a super root */
+ NILFS_SC_PRIOR_FLUSH, /* Requesting immediate flush without making a
+ checkpoint */
+ NILFS_SC_HAVE_DELTA, /* Next checkpoint will have update of files
+ other than DAT, cpfile, sufile, or files
+ moved by GC */
+};
+
+/* sc_state */
+#define NILFS_SEGCTOR_QUIT 0x0001 /* segctord is being destroyed */
+#define NILFS_SEGCTOR_COMMIT 0x0004 /* committed transaction exists */
+
+/*
+ * Constant parameters
+ */
+#define NILFS_SC_CLEANUP_RETRY 3 /* Retry count of construction when
+ destroying segctord */
+
+/*
+ * Default values of timeout, in seconds.
+ */
+#define NILFS_SC_DEFAULT_TIMEOUT 5 /* Timeout value of dirty blocks.
+ It triggers construction of a
+ logical segment with a super root */
+#define NILFS_SC_DEFAULT_SR_FREQ 30 /* Maximum frequency of super root
+ creation */
+
+/*
+ * The default threshold amount of data, in block counts.
+ */
+#define NILFS_SC_DEFAULT_WATERMARK 3600
+
+
+/* segment.c */
+extern int nilfs_init_transaction_cache(void);
+extern void nilfs_destroy_transaction_cache(void);
+extern void nilfs_relax_pressure_in_lock(struct super_block *);
+
+extern int nilfs_construct_segment(struct super_block *);
+extern int nilfs_construct_dsync_segment(struct super_block *, struct inode *,
+ loff_t, loff_t);
+extern void nilfs_flush_segment(struct super_block *, ino_t);
+extern int nilfs_clean_segments(struct super_block *, void __user *);
+
+extern int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *,
+ __u64 *, size_t);
+extern void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *);
+
+extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *);
+extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *);
+
+/* recovery.c */
+extern int nilfs_read_super_root_block(struct super_block *, sector_t,
+ struct buffer_head **, int);
+extern int nilfs_search_super_root(struct the_nilfs *, struct nilfs_sb_info *,
+ struct nilfs_recovery_info *);
+extern int nilfs_recover_logical_segments(struct the_nilfs *,
+ struct nilfs_sb_info *,
+ struct nilfs_recovery_info *);
+
+#endif /* _NILFS_SEGMENT_H */
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
new file mode 100644
index 00000000000..98e68677f04
--- /dev/null
+++ b/fs/nilfs2/sufile.c
@@ -0,0 +1,558 @@
+/*
+ * sufile.c - NILFS segment usage file.
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/buffer_head.h>
+#include <linux/errno.h>
+#include <linux/nilfs2_fs.h>
+#include "mdt.h"
+#include "sufile.h"
+
+
+static inline unsigned long
+nilfs_sufile_segment_usages_per_block(const struct inode *sufile)
+{
+ return NILFS_MDT(sufile)->mi_entries_per_block;
+}
+
+static unsigned long
+nilfs_sufile_get_blkoff(const struct inode *sufile, __u64 segnum)
+{
+ __u64 t = segnum + NILFS_MDT(sufile)->mi_first_entry_offset;
+ do_div(t, nilfs_sufile_segment_usages_per_block(sufile));
+ return (unsigned long)t;
+}
+
+static unsigned long
+nilfs_sufile_get_offset(const struct inode *sufile, __u64 segnum)
+{
+ __u64 t = segnum + NILFS_MDT(sufile)->mi_first_entry_offset;
+ return do_div(t, nilfs_sufile_segment_usages_per_block(sufile));
+}
+
+static unsigned long
+nilfs_sufile_segment_usages_in_block(const struct inode *sufile, __u64 curr,
+ __u64 max)
+{
+ return min_t(unsigned long,
+ nilfs_sufile_segment_usages_per_block(sufile) -
+ nilfs_sufile_get_offset(sufile, curr),
+ max - curr + 1);
+}
+
+static inline struct nilfs_sufile_header *
+nilfs_sufile_block_get_header(const struct inode *sufile,
+ struct buffer_head *bh,
+ void *kaddr)
+{
+ return kaddr + bh_offset(bh);
+}
+
+static struct nilfs_segment_usage *
+nilfs_sufile_block_get_segment_usage(const struct inode *sufile, __u64 segnum,
+ struct buffer_head *bh, void *kaddr)
+{
+ return kaddr + bh_offset(bh) +
+ nilfs_sufile_get_offset(sufile, segnum) *
+ NILFS_MDT(sufile)->mi_entry_size;
+}
+
+static inline int nilfs_sufile_get_header_block(struct inode *sufile,
+ struct buffer_head **bhp)
+{
+ return nilfs_mdt_get_block(sufile, 0, 0, NULL, bhp);
+}
+
+static inline int
+nilfs_sufile_get_segment_usage_block(struct inode *sufile, __u64 segnum,
+ int create, struct buffer_head **bhp)
+{
+ return nilfs_mdt_get_block(sufile,
+ nilfs_sufile_get_blkoff(sufile, segnum),
+ create, NULL, bhp);
+}
+
+static void nilfs_sufile_mod_counter(struct buffer_head *header_bh,
+ u64 ncleanadd, u64 ndirtyadd)
+{
+ struct nilfs_sufile_header *header;
+ void *kaddr;
+
+ kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+ header = kaddr + bh_offset(header_bh);
+ le64_add_cpu(&header->sh_ncleansegs, ncleanadd);
+ le64_add_cpu(&header->sh_ndirtysegs, ndirtyadd);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ nilfs_mdt_mark_buffer_dirty(header_bh);
+}
+
+int nilfs_sufile_update(struct inode *sufile, __u64 segnum, int create,
+ void (*dofunc)(struct inode *, __u64,
+ struct buffer_head *,
+ struct buffer_head *))
+{
+ struct buffer_head *header_bh, *bh;
+ int ret;
+
+ if (unlikely(segnum >= nilfs_sufile_get_nsegments(sufile))) {
+ printk(KERN_WARNING "%s: invalid segment number: %llu\n",
+ __func__, (unsigned long long)segnum);
+ return -EINVAL;
+ }
+ down_write(&NILFS_MDT(sufile)->mi_sem);
+
+ ret = nilfs_sufile_get_header_block(sufile, &header_bh);
+ if (ret < 0)
+ goto out_sem;
+
+ ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, create, &bh);
+ if (!ret) {
+ dofunc(sufile, segnum, header_bh, bh);
+ brelse(bh);
+ }
+ brelse(header_bh);
+
+ out_sem:
+ up_write(&NILFS_MDT(sufile)->mi_sem);
+ return ret;
+}
+
+/**
+ * nilfs_sufile_alloc - allocate a segment
+ * @sufile: inode of segment usage file
+ * @segnump: pointer to segment number
+ *
+ * Description: nilfs_sufile_alloc() allocates a clean segment.
+ *
+ * Return Value: On success, 0 is returned and the segment number of the
+ * allocated segment is stored in the place pointed by @segnump. On error, one
+ * of the following negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOSPC - No clean segment left.
+ */
+int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
+{
+ struct buffer_head *header_bh, *su_bh;
+ struct nilfs_sufile_header *header;
+ struct nilfs_segment_usage *su;
+ size_t susz = NILFS_MDT(sufile)->mi_entry_size;
+ __u64 segnum, maxsegnum, last_alloc;
+ void *kaddr;
+ unsigned long nsegments, ncleansegs, nsus;
+ int ret, i, j;
+
+ down_write(&NILFS_MDT(sufile)->mi_sem);
+
+ ret = nilfs_sufile_get_header_block(sufile, &header_bh);
+ if (ret < 0)
+ goto out_sem;
+ kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+ header = nilfs_sufile_block_get_header(sufile, header_bh, kaddr);
+ ncleansegs = le64_to_cpu(header->sh_ncleansegs);
+ last_alloc = le64_to_cpu(header->sh_last_alloc);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ nsegments = nilfs_sufile_get_nsegments(sufile);
+ segnum = last_alloc + 1;
+ maxsegnum = nsegments - 1;
+ for (i = 0; i < nsegments; i += nsus) {
+ if (segnum >= nsegments) {
+ /* wrap around */
+ segnum = 0;
+ maxsegnum = last_alloc;
+ }
+ ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 1,
+ &su_bh);
+ if (ret < 0)
+ goto out_header;
+ kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
+ su = nilfs_sufile_block_get_segment_usage(
+ sufile, segnum, su_bh, kaddr);
+
+ nsus = nilfs_sufile_segment_usages_in_block(
+ sufile, segnum, maxsegnum);
+ for (j = 0; j < nsus; j++, su = (void *)su + susz, segnum++) {
+ if (!nilfs_segment_usage_clean(su))
+ continue;
+ /* found a clean segment */
+ nilfs_segment_usage_set_dirty(su);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+ header = nilfs_sufile_block_get_header(
+ sufile, header_bh, kaddr);
+ le64_add_cpu(&header->sh_ncleansegs, -1);
+ le64_add_cpu(&header->sh_ndirtysegs, 1);
+ header->sh_last_alloc = cpu_to_le64(segnum);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ nilfs_mdt_mark_buffer_dirty(header_bh);
+ nilfs_mdt_mark_buffer_dirty(su_bh);
+ nilfs_mdt_mark_dirty(sufile);
+ brelse(su_bh);
+ *segnump = segnum;
+ goto out_header;
+ }
+
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(su_bh);
+ }
+
+ /* no segments left */
+ ret = -ENOSPC;
+
+ out_header:
+ brelse(header_bh);
+
+ out_sem:
+ up_write(&NILFS_MDT(sufile)->mi_sem);
+ return ret;
+}
+
+void nilfs_sufile_do_cancel_free(struct inode *sufile, __u64 segnum,
+ struct buffer_head *header_bh,
+ struct buffer_head *su_bh)
+{
+ struct nilfs_segment_usage *su;
+ void *kaddr;
+
+ kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
+ su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
+ if (unlikely(!nilfs_segment_usage_clean(su))) {
+ printk(KERN_WARNING "%s: segment %llu must be clean\n",
+ __func__, (unsigned long long)segnum);
+ kunmap_atomic(kaddr, KM_USER0);
+ return;
+ }
+ nilfs_segment_usage_set_dirty(su);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ nilfs_sufile_mod_counter(header_bh, -1, 1);
+ nilfs_mdt_mark_buffer_dirty(su_bh);
+ nilfs_mdt_mark_dirty(sufile);
+}
+
+void nilfs_sufile_do_scrap(struct inode *sufile, __u64 segnum,
+ struct buffer_head *header_bh,
+ struct buffer_head *su_bh)
+{
+ struct nilfs_segment_usage *su;
+ void *kaddr;
+ int clean, dirty;
+
+ kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
+ su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
+ if (su->su_flags == cpu_to_le32(1UL << NILFS_SEGMENT_USAGE_DIRTY) &&
+ su->su_nblocks == cpu_to_le32(0)) {
+ kunmap_atomic(kaddr, KM_USER0);
+ return;
+ }
+ clean = nilfs_segment_usage_clean(su);
+ dirty = nilfs_segment_usage_dirty(su);
+
+ /* make the segment garbage */
+ su->su_lastmod = cpu_to_le64(0);
+ su->su_nblocks = cpu_to_le32(0);
+ su->su_flags = cpu_to_le32(1UL << NILFS_SEGMENT_USAGE_DIRTY);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ nilfs_sufile_mod_counter(header_bh, clean ? (u64)-1 : 0, dirty ? 0 : 1);
+ nilfs_mdt_mark_buffer_dirty(su_bh);
+ nilfs_mdt_mark_dirty(sufile);
+}
+
+void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum,
+ struct buffer_head *header_bh,
+ struct buffer_head *su_bh)
+{
+ struct nilfs_segment_usage *su;
+ void *kaddr;
+ int sudirty;
+
+ kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
+ su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
+ if (nilfs_segment_usage_clean(su)) {
+ printk(KERN_WARNING "%s: segment %llu is already clean\n",
+ __func__, (unsigned long long)segnum);
+ kunmap_atomic(kaddr, KM_USER0);
+ return;
+ }
+ WARN_ON(nilfs_segment_usage_error(su));
+ WARN_ON(!nilfs_segment_usage_dirty(su));
+
+ sudirty = nilfs_segment_usage_dirty(su);
+ nilfs_segment_usage_set_clean(su);
+ kunmap_atomic(kaddr, KM_USER0);
+ nilfs_mdt_mark_buffer_dirty(su_bh);
+
+ nilfs_sufile_mod_counter(header_bh, 1, sudirty ? (u64)-1 : 0);
+ nilfs_mdt_mark_dirty(sufile);
+}
+
+/**
+ * nilfs_sufile_get_segment_usage - get a segment usage
+ * @sufile: inode of segment usage file
+ * @segnum: segment number
+ * @sup: pointer to segment usage
+ * @bhp: pointer to buffer head
+ *
+ * Description: nilfs_sufile_get_segment_usage() acquires the segment usage
+ * specified by @segnum.
+ *
+ * Return Value: On success, 0 is returned, and the segment usage and the
+ * buffer head of the buffer on which the segment usage is located are stored
+ * in the place pointed by @sup and @bhp, respectively. On error, one of the
+ * following negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-EINVAL - Invalid segment usage number.
+ */
+int nilfs_sufile_get_segment_usage(struct inode *sufile, __u64 segnum,
+ struct nilfs_segment_usage **sup,
+ struct buffer_head **bhp)
+{
+ struct buffer_head *bh;
+ struct nilfs_segment_usage *su;
+ void *kaddr;
+ int ret;
+
+ /* segnum is 0 origin */
+ if (segnum >= nilfs_sufile_get_nsegments(sufile))
+ return -EINVAL;
+ down_write(&NILFS_MDT(sufile)->mi_sem);
+ ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 1, &bh);
+ if (ret < 0)
+ goto out_sem;
+ kaddr = kmap(bh->b_page);
+ su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
+ if (nilfs_segment_usage_error(su)) {
+ kunmap(bh->b_page);
+ brelse(bh);
+ ret = -EINVAL;
+ goto out_sem;
+ }
+
+ if (sup != NULL)
+ *sup = su;
+ *bhp = bh;
+
+ out_sem:
+ up_write(&NILFS_MDT(sufile)->mi_sem);
+ return ret;
+}
+
+/**
+ * nilfs_sufile_put_segment_usage - put a segment usage
+ * @sufile: inode of segment usage file
+ * @segnum: segment number
+ * @bh: buffer head
+ *
+ * Description: nilfs_sufile_put_segment_usage() releases the segment usage
+ * specified by @segnum. @bh must be the buffer head which have been returned
+ * by a previous call to nilfs_sufile_get_segment_usage() with @segnum.
+ */
+void nilfs_sufile_put_segment_usage(struct inode *sufile, __u64 segnum,
+ struct buffer_head *bh)
+{
+ kunmap(bh->b_page);
+ brelse(bh);
+}
+
+/**
+ * nilfs_sufile_get_stat - get segment usage statistics
+ * @sufile: inode of segment usage file
+ * @stat: pointer to a structure of segment usage statistics
+ *
+ * Description: nilfs_sufile_get_stat() returns information about segment
+ * usage.
+ *
+ * Return Value: On success, 0 is returned, and segment usage information is
+ * stored in the place pointed by @stat. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ */
+int nilfs_sufile_get_stat(struct inode *sufile, struct nilfs_sustat *sustat)
+{
+ struct buffer_head *header_bh;
+ struct nilfs_sufile_header *header;
+ struct the_nilfs *nilfs = NILFS_MDT(sufile)->mi_nilfs;
+ void *kaddr;
+ int ret;
+
+ down_read(&NILFS_MDT(sufile)->mi_sem);
+
+ ret = nilfs_sufile_get_header_block(sufile, &header_bh);
+ if (ret < 0)
+ goto out_sem;
+
+ kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+ header = nilfs_sufile_block_get_header(sufile, header_bh, kaddr);
+ sustat->ss_nsegs = nilfs_sufile_get_nsegments(sufile);
+ sustat->ss_ncleansegs = le64_to_cpu(header->sh_ncleansegs);
+ sustat->ss_ndirtysegs = le64_to_cpu(header->sh_ndirtysegs);
+ sustat->ss_ctime = nilfs->ns_ctime;
+ sustat->ss_nongc_ctime = nilfs->ns_nongc_ctime;
+ spin_lock(&nilfs->ns_last_segment_lock);
+ sustat->ss_prot_seq = nilfs->ns_prot_seq;
+ spin_unlock(&nilfs->ns_last_segment_lock);
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(header_bh);
+
+ out_sem:
+ up_read(&NILFS_MDT(sufile)->mi_sem);
+ return ret;
+}
+
+/**
+ * nilfs_sufile_get_ncleansegs - get the number of clean segments
+ * @sufile: inode of segment usage file
+ * @nsegsp: pointer to the number of clean segments
+ *
+ * Description: nilfs_sufile_get_ncleansegs() acquires the number of clean
+ * segments.
+ *
+ * Return Value: On success, 0 is returned and the number of clean segments is
+ * stored in the place pointed by @nsegsp. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ */
+int nilfs_sufile_get_ncleansegs(struct inode *sufile, unsigned long *nsegsp)
+{
+ struct nilfs_sustat sustat;
+ int ret;
+
+ ret = nilfs_sufile_get_stat(sufile, &sustat);
+ if (ret == 0)
+ *nsegsp = sustat.ss_ncleansegs;
+ return ret;
+}
+
+void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum,
+ struct buffer_head *header_bh,
+ struct buffer_head *su_bh)
+{
+ struct nilfs_segment_usage *su;
+ void *kaddr;
+ int suclean;
+
+ kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
+ su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
+ if (nilfs_segment_usage_error(su)) {
+ kunmap_atomic(kaddr, KM_USER0);
+ return;
+ }
+ suclean = nilfs_segment_usage_clean(su);
+ nilfs_segment_usage_set_error(su);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ if (suclean)
+ nilfs_sufile_mod_counter(header_bh, -1, 0);
+ nilfs_mdt_mark_buffer_dirty(su_bh);
+ nilfs_mdt_mark_dirty(sufile);
+}
+
+/**
+ * nilfs_sufile_get_suinfo -
+ * @sufile: inode of segment usage file
+ * @segnum: segment number to start looking
+ * @si: array of suinfo
+ * @nsi: size of suinfo array
+ *
+ * Description:
+ *
+ * Return Value: On success, 0 is returned and .... On error, one of the
+ * following negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ */
+ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum,
+ struct nilfs_suinfo *si, size_t nsi)
+{
+ struct buffer_head *su_bh;
+ struct nilfs_segment_usage *su;
+ size_t susz = NILFS_MDT(sufile)->mi_entry_size;
+ struct the_nilfs *nilfs = NILFS_MDT(sufile)->mi_nilfs;
+ void *kaddr;
+ unsigned long nsegs, segusages_per_block;
+ ssize_t n;
+ int ret, i, j;
+
+ down_read(&NILFS_MDT(sufile)->mi_sem);
+
+ segusages_per_block = nilfs_sufile_segment_usages_per_block(sufile);
+ nsegs = min_t(unsigned long,
+ nilfs_sufile_get_nsegments(sufile) - segnum,
+ nsi);
+ for (i = 0; i < nsegs; i += n, segnum += n) {
+ n = min_t(unsigned long,
+ segusages_per_block -
+ nilfs_sufile_get_offset(sufile, segnum),
+ nsegs - i);
+ ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0,
+ &su_bh);
+ if (ret < 0) {
+ if (ret != -ENOENT)
+ goto out;
+ /* hole */
+ memset(&si[i], 0, sizeof(struct nilfs_suinfo) * n);
+ continue;
+ }
+
+ kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
+ su = nilfs_sufile_block_get_segment_usage(
+ sufile, segnum, su_bh, kaddr);
+ for (j = 0; j < n; j++, su = (void *)su + susz) {
+ si[i + j].sui_lastmod = le64_to_cpu(su->su_lastmod);
+ si[i + j].sui_nblocks = le32_to_cpu(su->su_nblocks);
+ si[i + j].sui_flags = le32_to_cpu(su->su_flags) &
+ ~(1UL << NILFS_SEGMENT_USAGE_ACTIVE);
+ if (nilfs_segment_is_active(nilfs, segnum + j))
+ si[i + j].sui_flags |=
+ (1UL << NILFS_SEGMENT_USAGE_ACTIVE);
+ }
+ kunmap_atomic(kaddr, KM_USER0);
+ brelse(su_bh);
+ }
+ ret = nsegs;
+
+ out:
+ up_read(&NILFS_MDT(sufile)->mi_sem);
+ return ret;
+}
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h
new file mode 100644
index 00000000000..a2e2efd4ade
--- /dev/null
+++ b/fs/nilfs2/sufile.h
@@ -0,0 +1,125 @@
+/*
+ * sufile.h - NILFS segment usage file.
+ *
+ * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>.
+ */
+
+#ifndef _NILFS_SUFILE_H
+#define _NILFS_SUFILE_H
+
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/nilfs2_fs.h>
+#include "mdt.h"
+
+#define NILFS_SUFILE_GFP NILFS_MDT_GFP
+
+static inline unsigned long nilfs_sufile_get_nsegments(struct inode *sufile)
+{
+ return NILFS_MDT(sufile)->mi_nilfs->ns_nsegments;
+}
+
+int nilfs_sufile_alloc(struct inode *, __u64 *);
+int nilfs_sufile_get_segment_usage(struct inode *, __u64,
+ struct nilfs_segment_usage **,
+ struct buffer_head **);
+void nilfs_sufile_put_segment_usage(struct inode *, __u64,
+ struct buffer_head *);
+int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
+int nilfs_sufile_get_ncleansegs(struct inode *, unsigned long *);
+ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, struct nilfs_suinfo *,
+ size_t);
+
+int nilfs_sufile_update(struct inode *, __u64, int,
+ void (*dofunc)(struct inode *, __u64,
+ struct buffer_head *,
+ struct buffer_head *));
+void nilfs_sufile_do_cancel_free(struct inode *, __u64, struct buffer_head *,
+ struct buffer_head *);
+void nilfs_sufile_do_scrap(struct inode *, __u64, struct buffer_head *,
+ struct buffer_head *);
+void nilfs_sufile_do_free(struct inode *, __u64, struct buffer_head *,
+ struct buffer_head *);
+void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *,
+ struct buffer_head *);
+
+/**
+ * nilfs_sufile_cancel_free -
+ * @sufile: inode of segment usage file
+ * @segnum: segment number
+ *
+ * Description:
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ */
+static inline int nilfs_sufile_cancel_free(struct inode *sufile, __u64 segnum)
+{
+ return nilfs_sufile_update(sufile, segnum, 0,
+ nilfs_sufile_do_cancel_free);
+}
+
+/**
+ * nilfs_sufile_scrap - make a segment garbage
+ * @sufile: inode of segment usage file
+ * @segnum: segment number to be freed
+ */
+static inline int nilfs_sufile_scrap(struct inode *sufile, __u64 segnum)
+{
+ return nilfs_sufile_update(sufile, segnum, 1, nilfs_sufile_do_scrap);
+}
+
+/**
+ * nilfs_sufile_free - free segment
+ * @sufile: inode of segment usage file
+ * @segnum: segment number to be freed
+ */
+static inline int nilfs_sufile_free(struct inode *sufile, __u64 segnum)
+{
+ return nilfs_sufile_update(sufile, segnum, 0, nilfs_sufile_do_free);
+}
+
+/**
+ * nilfs_sufile_set_error - mark a segment as erroneous
+ * @sufile: inode of segment usage file
+ * @segnum: segment number
+ *
+ * Description: nilfs_sufile_set_error() marks the segment specified by
+ * @segnum as erroneous. The error segment will never be used again.
+ *
+ * Return Value: On success, 0 is returned. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-EINVAL - Invalid segment usage number.
+ */
+static inline int nilfs_sufile_set_error(struct inode *sufile, __u64 segnum)
+{
+ return nilfs_sufile_update(sufile, segnum, 0,
+ nilfs_sufile_do_set_error);
+}
+
+#endif /* _NILFS_SUFILE_H */
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
new file mode 100644
index 00000000000..6989b03e97a
--- /dev/null
+++ b/fs/nilfs2/super.c
@@ -0,0 +1,1326 @@
+/*
+ * super.c - NILFS module and super block management.
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>
+ */
+/*
+ * linux/fs/ext2/super.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ * from
+ *
+ * linux/fs/minix/inode.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * Big-endian to little-endian byte-swapping/bitmaps by
+ * David S. Miller (davem@caip.rutgers.edu), 1995
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/parser.h>
+#include <linux/random.h>
+#include <linux/crc32.h>
+#include <linux/smp_lock.h>
+#include <linux/vfs.h>
+#include <linux/writeback.h>
+#include <linux/kobject.h>
+#include <linux/exportfs.h>
+#include "nilfs.h"
+#include "mdt.h"
+#include "alloc.h"
+#include "page.h"
+#include "cpfile.h"
+#include "ifile.h"
+#include "dat.h"
+#include "segment.h"
+#include "segbuf.h"
+
+MODULE_AUTHOR("NTT Corp.");
+MODULE_DESCRIPTION("A New Implementation of the Log-structured Filesystem "
+ "(NILFS)");
+MODULE_LICENSE("GPL");
+
+static int nilfs_remount(struct super_block *sb, int *flags, char *data);
+static int test_exclusive_mount(struct file_system_type *fs_type,
+ struct block_device *bdev, int flags);
+
+/**
+ * nilfs_error() - report failure condition on a filesystem
+ *
+ * nilfs_error() sets an ERROR_FS flag on the superblock as well as
+ * reporting an error message. It should be called when NILFS detects
+ * incoherences or defects of meta data on disk. As for sustainable
+ * errors such as a single-shot I/O error, nilfs_warning() or the printk()
+ * function should be used instead.
+ *
+ * The segment constructor must not call this function because it can
+ * kill itself.
+ */
+void nilfs_error(struct super_block *sb, const char *function,
+ const char *fmt, ...)
+{
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ va_list args;
+
+ va_start(args, fmt);
+ printk(KERN_CRIT "NILFS error (device %s): %s: ", sb->s_id, function);
+ vprintk(fmt, args);
+ printk("\n");
+ va_end(args);
+
+ if (!(sb->s_flags & MS_RDONLY)) {
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+
+ if (!nilfs_test_opt(sbi, ERRORS_CONT))
+ nilfs_detach_segment_constructor(sbi);
+
+ down_write(&nilfs->ns_sem);
+ if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) {
+ nilfs->ns_mount_state |= NILFS_ERROR_FS;
+ nilfs->ns_sbp[0]->s_state |=
+ cpu_to_le16(NILFS_ERROR_FS);
+ nilfs_commit_super(sbi, 1);
+ }
+ up_write(&nilfs->ns_sem);
+
+ if (nilfs_test_opt(sbi, ERRORS_RO)) {
+ printk(KERN_CRIT "Remounting filesystem read-only\n");
+ sb->s_flags |= MS_RDONLY;
+ }
+ }
+
+ if (nilfs_test_opt(sbi, ERRORS_PANIC))
+ panic("NILFS (device %s): panic forced after error\n",
+ sb->s_id);
+}
+
+void nilfs_warning(struct super_block *sb, const char *function,
+ const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ printk(KERN_WARNING "NILFS warning (device %s): %s: ",
+ sb->s_id, function);
+ vprintk(fmt, args);
+ printk("\n");
+ va_end(args);
+}
+
+static struct kmem_cache *nilfs_inode_cachep;
+
+struct inode *nilfs_alloc_inode(struct super_block *sb)
+{
+ struct nilfs_inode_info *ii;
+
+ ii = kmem_cache_alloc(nilfs_inode_cachep, GFP_NOFS);
+ if (!ii)
+ return NULL;
+ ii->i_bh = NULL;
+ ii->i_state = 0;
+ ii->vfs_inode.i_version = 1;
+ nilfs_btnode_cache_init(&ii->i_btnode_cache);
+ return &ii->vfs_inode;
+}
+
+void nilfs_destroy_inode(struct inode *inode)
+{
+ kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode));
+}
+
+static void init_once(void *obj)
+{
+ struct nilfs_inode_info *ii = obj;
+
+ INIT_LIST_HEAD(&ii->i_dirty);
+#ifdef CONFIG_NILFS_XATTR
+ init_rwsem(&ii->xattr_sem);
+#endif
+ nilfs_btnode_cache_init_once(&ii->i_btnode_cache);
+ ii->i_bmap = (struct nilfs_bmap *)&ii->i_bmap_union;
+ inode_init_once(&ii->vfs_inode);
+}
+
+static int nilfs_init_inode_cache(void)
+{
+ nilfs_inode_cachep = kmem_cache_create("nilfs2_inode_cache",
+ sizeof(struct nilfs_inode_info),
+ 0, SLAB_RECLAIM_ACCOUNT,
+ init_once);
+
+ return (nilfs_inode_cachep == NULL) ? -ENOMEM : 0;
+}
+
+static inline void nilfs_destroy_inode_cache(void)
+{
+ kmem_cache_destroy(nilfs_inode_cachep);
+}
+
+static void nilfs_clear_inode(struct inode *inode)
+{
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+
+#ifdef CONFIG_NILFS_POSIX_ACL
+ if (ii->i_acl && ii->i_acl != NILFS_ACL_NOT_CACHED) {
+ posix_acl_release(ii->i_acl);
+ ii->i_acl = NILFS_ACL_NOT_CACHED;
+ }
+ if (ii->i_default_acl && ii->i_default_acl != NILFS_ACL_NOT_CACHED) {
+ posix_acl_release(ii->i_default_acl);
+ ii->i_default_acl = NILFS_ACL_NOT_CACHED;
+ }
+#endif
+ /*
+ * Free resources allocated in nilfs_read_inode(), here.
+ */
+ BUG_ON(!list_empty(&ii->i_dirty));
+ brelse(ii->i_bh);
+ ii->i_bh = NULL;
+
+ if (test_bit(NILFS_I_BMAP, &ii->i_state))
+ nilfs_bmap_clear(ii->i_bmap);
+
+ nilfs_btnode_cache_clear(&ii->i_btnode_cache);
+}
+
+static int nilfs_sync_super(struct nilfs_sb_info *sbi, int dupsb)
+{
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ int err;
+ int barrier_done = 0;
+
+ if (nilfs_test_opt(sbi, BARRIER)) {
+ set_buffer_ordered(nilfs->ns_sbh[0]);
+ barrier_done = 1;
+ }
+ retry:
+ set_buffer_dirty(nilfs->ns_sbh[0]);
+ err = sync_dirty_buffer(nilfs->ns_sbh[0]);
+ if (err == -EOPNOTSUPP && barrier_done) {
+ nilfs_warning(sbi->s_super, __func__,
+ "barrier-based sync failed. "
+ "disabling barriers\n");
+ nilfs_clear_opt(sbi, BARRIER);
+ barrier_done = 0;
+ clear_buffer_ordered(nilfs->ns_sbh[0]);
+ goto retry;
+ }
+ if (unlikely(err)) {
+ printk(KERN_ERR
+ "NILFS: unable to write superblock (err=%d)\n", err);
+ if (err == -EIO && nilfs->ns_sbh[1]) {
+ nilfs_fall_back_super_block(nilfs);
+ goto retry;
+ }
+ } else {
+ struct nilfs_super_block *sbp = nilfs->ns_sbp[0];
+
+ /*
+ * The latest segment becomes trailable from the position
+ * written in superblock.
+ */
+ clear_nilfs_discontinued(nilfs);
+
+ /* update GC protection for recent segments */
+ if (nilfs->ns_sbh[1]) {
+ sbp = NULL;
+ if (dupsb) {
+ set_buffer_dirty(nilfs->ns_sbh[1]);
+ if (!sync_dirty_buffer(nilfs->ns_sbh[1]))
+ sbp = nilfs->ns_sbp[1];
+ }
+ }
+ if (sbp) {
+ spin_lock(&nilfs->ns_last_segment_lock);
+ nilfs->ns_prot_seq = le64_to_cpu(sbp->s_last_seq);
+ spin_unlock(&nilfs->ns_last_segment_lock);
+ }
+ }
+
+ return err;
+}
+
+int nilfs_commit_super(struct nilfs_sb_info *sbi, int dupsb)
+{
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ struct nilfs_super_block **sbp = nilfs->ns_sbp;
+ sector_t nfreeblocks;
+ time_t t;
+ int err;
+
+ /* nilfs->sem must be locked by the caller. */
+ if (sbp[0]->s_magic != NILFS_SUPER_MAGIC) {
+ if (sbp[1] && sbp[1]->s_magic == NILFS_SUPER_MAGIC)
+ nilfs_swap_super_block(nilfs);
+ else {
+ printk(KERN_CRIT "NILFS: superblock broke on dev %s\n",
+ sbi->s_super->s_id);
+ return -EIO;
+ }
+ }
+ err = nilfs_count_free_blocks(nilfs, &nfreeblocks);
+ if (unlikely(err)) {
+ printk(KERN_ERR "NILFS: failed to count free blocks\n");
+ return err;
+ }
+ spin_lock(&nilfs->ns_last_segment_lock);
+ sbp[0]->s_last_seq = cpu_to_le64(nilfs->ns_last_seq);
+ sbp[0]->s_last_pseg = cpu_to_le64(nilfs->ns_last_pseg);
+ sbp[0]->s_last_cno = cpu_to_le64(nilfs->ns_last_cno);
+ spin_unlock(&nilfs->ns_last_segment_lock);
+
+ t = get_seconds();
+ nilfs->ns_sbwtime[0] = t;
+ sbp[0]->s_free_blocks_count = cpu_to_le64(nfreeblocks);
+ sbp[0]->s_wtime = cpu_to_le64(t);
+ sbp[0]->s_sum = 0;
+ sbp[0]->s_sum = cpu_to_le32(crc32_le(nilfs->ns_crc_seed,
+ (unsigned char *)sbp[0],
+ nilfs->ns_sbsize));
+ if (dupsb && sbp[1]) {
+ memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
+ nilfs->ns_sbwtime[1] = t;
+ }
+ sbi->s_super->s_dirt = 0;
+ return nilfs_sync_super(sbi, dupsb);
+}
+
+static void nilfs_put_super(struct super_block *sb)
+{
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+
+ nilfs_detach_segment_constructor(sbi);
+
+ if (!(sb->s_flags & MS_RDONLY)) {
+ down_write(&nilfs->ns_sem);
+ nilfs->ns_sbp[0]->s_state = cpu_to_le16(nilfs->ns_mount_state);
+ nilfs_commit_super(sbi, 1);
+ up_write(&nilfs->ns_sem);
+ }
+
+ nilfs_detach_checkpoint(sbi);
+ put_nilfs(sbi->s_nilfs);
+ sbi->s_super = NULL;
+ sb->s_fs_info = NULL;
+ kfree(sbi);
+}
+
+/**
+ * nilfs_write_super - write super block(s) of NILFS
+ * @sb: super_block
+ *
+ * nilfs_write_super() gets a fs-dependent lock, writes super block(s), and
+ * clears s_dirt. This function is called in the section protected by
+ * lock_super().
+ *
+ * The s_dirt flag is managed by each filesystem and we protect it by ns_sem
+ * of the struct the_nilfs. Lock order must be as follows:
+ *
+ * 1. lock_super()
+ * 2. down_write(&nilfs->ns_sem)
+ *
+ * Inside NILFS, locking ns_sem is enough to protect s_dirt and the buffer
+ * of the super block (nilfs->ns_sbp[]).
+ *
+ * In most cases, VFS functions call lock_super() before calling these
+ * methods. So we must be careful not to bring on deadlocks when using
+ * lock_super(); see generic_shutdown_super(), write_super(), and so on.
+ *
+ * Note that order of lock_kernel() and lock_super() depends on contexts
+ * of VFS. We should also note that lock_kernel() can be used in its
+ * protective section and only the outermost one has an effect.
+ */
+static void nilfs_write_super(struct super_block *sb)
+{
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+
+ down_write(&nilfs->ns_sem);
+ if (!(sb->s_flags & MS_RDONLY)) {
+ struct nilfs_super_block **sbp = nilfs->ns_sbp;
+ u64 t = get_seconds();
+ int dupsb;
+
+ if (!nilfs_discontinued(nilfs) && t >= nilfs->ns_sbwtime[0] &&
+ t < nilfs->ns_sbwtime[0] + NILFS_SB_FREQ) {
+ up_write(&nilfs->ns_sem);
+ return;
+ }
+ dupsb = sbp[1] && t > nilfs->ns_sbwtime[1] + NILFS_ALTSB_FREQ;
+ nilfs_commit_super(sbi, dupsb);
+ }
+ sb->s_dirt = 0;
+ up_write(&nilfs->ns_sem);
+}
+
+static int nilfs_sync_fs(struct super_block *sb, int wait)
+{
+ int err = 0;
+
+ /* This function is called when super block should be written back */
+ if (wait)
+ err = nilfs_construct_segment(sb);
+ return err;
+}
+
+int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno)
+{
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ struct nilfs_checkpoint *raw_cp;
+ struct buffer_head *bh_cp;
+ int err;
+
+ down_write(&nilfs->ns_sem);
+ list_add(&sbi->s_list, &nilfs->ns_supers);
+ up_write(&nilfs->ns_sem);
+
+ sbi->s_ifile = nilfs_mdt_new(
+ nilfs, sbi->s_super, NILFS_IFILE_INO, NILFS_IFILE_GFP);
+ if (!sbi->s_ifile)
+ return -ENOMEM;
+
+ err = nilfs_palloc_init_blockgroup(sbi->s_ifile, nilfs->ns_inode_size);
+ if (unlikely(err))
+ goto failed;
+
+ err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp,
+ &bh_cp);
+ if (unlikely(err)) {
+ if (err == -ENOENT || err == -EINVAL) {
+ printk(KERN_ERR
+ "NILFS: Invalid checkpoint "
+ "(checkpoint number=%llu)\n",
+ (unsigned long long)cno);
+ err = -EINVAL;
+ }
+ goto failed;
+ }
+ err = nilfs_read_inode_common(sbi->s_ifile, &raw_cp->cp_ifile_inode);
+ if (unlikely(err))
+ goto failed_bh;
+ atomic_set(&sbi->s_inodes_count, le64_to_cpu(raw_cp->cp_inodes_count));
+ atomic_set(&sbi->s_blocks_count, le64_to_cpu(raw_cp->cp_blocks_count));
+
+ nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp);
+ return 0;
+
+ failed_bh:
+ nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp);
+ failed:
+ nilfs_mdt_destroy(sbi->s_ifile);
+ sbi->s_ifile = NULL;
+
+ down_write(&nilfs->ns_sem);
+ list_del_init(&sbi->s_list);
+ up_write(&nilfs->ns_sem);
+
+ return err;
+}
+
+void nilfs_detach_checkpoint(struct nilfs_sb_info *sbi)
+{
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+
+ nilfs_mdt_clear(sbi->s_ifile);
+ nilfs_mdt_destroy(sbi->s_ifile);
+ sbi->s_ifile = NULL;
+ down_write(&nilfs->ns_sem);
+ list_del_init(&sbi->s_list);
+ up_write(&nilfs->ns_sem);
+}
+
+static int nilfs_mark_recovery_complete(struct nilfs_sb_info *sbi)
+{
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ int err = 0;
+
+ down_write(&nilfs->ns_sem);
+ if (!(nilfs->ns_mount_state & NILFS_VALID_FS)) {
+ nilfs->ns_mount_state |= NILFS_VALID_FS;
+ err = nilfs_commit_super(sbi, 1);
+ if (likely(!err))
+ printk(KERN_INFO "NILFS: recovery complete.\n");
+ }
+ up_write(&nilfs->ns_sem);
+ return err;
+}
+
+static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+ struct super_block *sb = dentry->d_sb;
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
+ unsigned long long blocks;
+ unsigned long overhead;
+ unsigned long nrsvblocks;
+ sector_t nfreeblocks;
+ int err;
+
+ /*
+ * Compute all of the segment blocks
+ *
+ * The blocks before first segment and after last segment
+ * are excluded.
+ */
+ blocks = nilfs->ns_blocks_per_segment * nilfs->ns_nsegments
+ - nilfs->ns_first_data_block;
+ nrsvblocks = nilfs->ns_nrsvsegs * nilfs->ns_blocks_per_segment;
+
+ /*
+ * Compute the overhead
+ *
+ * When distributing meta data blocks outside semgent structure,
+ * We must count them as the overhead.
+ */
+ overhead = 0;
+
+ err = nilfs_count_free_blocks(nilfs, &nfreeblocks);
+ if (unlikely(err))
+ return err;
+
+ buf->f_type = NILFS_SUPER_MAGIC;
+ buf->f_bsize = sb->s_blocksize;
+ buf->f_blocks = blocks - overhead;
+ buf->f_bfree = nfreeblocks;
+ buf->f_bavail = (buf->f_bfree >= nrsvblocks) ?
+ (buf->f_bfree - nrsvblocks) : 0;
+ buf->f_files = atomic_read(&sbi->s_inodes_count);
+ buf->f_ffree = 0; /* nilfs_count_free_inodes(sb); */
+ buf->f_namelen = NILFS_NAME_LEN;
+ buf->f_fsid.val[0] = (u32)id;
+ buf->f_fsid.val[1] = (u32)(id >> 32);
+
+ return 0;
+}
+
+static struct super_operations nilfs_sops = {
+ .alloc_inode = nilfs_alloc_inode,
+ .destroy_inode = nilfs_destroy_inode,
+ .dirty_inode = nilfs_dirty_inode,
+ /* .write_inode = nilfs_write_inode, */
+ /* .put_inode = nilfs_put_inode, */
+ /* .drop_inode = nilfs_drop_inode, */
+ .delete_inode = nilfs_delete_inode,
+ .put_super = nilfs_put_super,
+ .write_super = nilfs_write_super,
+ .sync_fs = nilfs_sync_fs,
+ /* .write_super_lockfs */
+ /* .unlockfs */
+ .statfs = nilfs_statfs,
+ .remount_fs = nilfs_remount,
+ .clear_inode = nilfs_clear_inode,
+ /* .umount_begin */
+ /* .show_options */
+};
+
+static struct inode *
+nilfs_nfs_get_inode(struct super_block *sb, u64 ino, u32 generation)
+{
+ struct inode *inode;
+
+ if (ino < NILFS_FIRST_INO(sb) && ino != NILFS_ROOT_INO &&
+ ino != NILFS_SKETCH_INO)
+ return ERR_PTR(-ESTALE);
+
+ inode = nilfs_iget(sb, ino);
+ if (IS_ERR(inode))
+ return ERR_CAST(inode);
+ if (generation && inode->i_generation != generation) {
+ iput(inode);
+ return ERR_PTR(-ESTALE);
+ }
+
+ return inode;
+}
+
+static struct dentry *
+nilfs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
+ int fh_type)
+{
+ return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+ nilfs_nfs_get_inode);
+}
+
+static struct dentry *
+nilfs_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len,
+ int fh_type)
+{
+ return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+ nilfs_nfs_get_inode);
+}
+
+static struct export_operations nilfs_export_ops = {
+ .fh_to_dentry = nilfs_fh_to_dentry,
+ .fh_to_parent = nilfs_fh_to_parent,
+ .get_parent = nilfs_get_parent,
+};
+
+enum {
+ Opt_err_cont, Opt_err_panic, Opt_err_ro,
+ Opt_barrier, Opt_snapshot, Opt_order,
+ Opt_err,
+};
+
+static match_table_t tokens = {
+ {Opt_err_cont, "errors=continue"},
+ {Opt_err_panic, "errors=panic"},
+ {Opt_err_ro, "errors=remount-ro"},
+ {Opt_barrier, "barrier=%s"},
+ {Opt_snapshot, "cp=%u"},
+ {Opt_order, "order=%s"},
+ {Opt_err, NULL}
+};
+
+static int match_bool(substring_t *s, int *result)
+{
+ int len = s->to - s->from;
+
+ if (strncmp(s->from, "on", len) == 0)
+ *result = 1;
+ else if (strncmp(s->from, "off", len) == 0)
+ *result = 0;
+ else
+ return 1;
+ return 0;
+}
+
+static int parse_options(char *options, struct super_block *sb)
+{
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ char *p;
+ substring_t args[MAX_OPT_ARGS];
+ int option;
+
+ if (!options)
+ return 1;
+
+ while ((p = strsep(&options, ",")) != NULL) {
+ int token;
+ if (!*p)
+ continue;
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_barrier:
+ if (match_bool(&args[0], &option))
+ return 0;
+ if (option)
+ nilfs_set_opt(sbi, BARRIER);
+ else
+ nilfs_clear_opt(sbi, BARRIER);
+ break;
+ case Opt_order:
+ if (strcmp(args[0].from, "relaxed") == 0)
+ /* Ordered data semantics */
+ nilfs_clear_opt(sbi, STRICT_ORDER);
+ else if (strcmp(args[0].from, "strict") == 0)
+ /* Strict in-order semantics */
+ nilfs_set_opt(sbi, STRICT_ORDER);
+ else
+ return 0;
+ break;
+ case Opt_err_panic:
+ nilfs_write_opt(sbi, ERROR_MODE, ERRORS_PANIC);
+ break;
+ case Opt_err_ro:
+ nilfs_write_opt(sbi, ERROR_MODE, ERRORS_RO);
+ break;
+ case Opt_err_cont:
+ nilfs_write_opt(sbi, ERROR_MODE, ERRORS_CONT);
+ break;
+ case Opt_snapshot:
+ if (match_int(&args[0], &option) || option <= 0)
+ return 0;
+ if (!(sb->s_flags & MS_RDONLY))
+ return 0;
+ sbi->s_snapshot_cno = option;
+ nilfs_set_opt(sbi, SNAPSHOT);
+ break;
+ default:
+ printk(KERN_ERR
+ "NILFS: Unrecognized mount option \"%s\"\n", p);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static inline void
+nilfs_set_default_options(struct nilfs_sb_info *sbi,
+ struct nilfs_super_block *sbp)
+{
+ sbi->s_mount_opt =
+ NILFS_MOUNT_ERRORS_CONT | NILFS_MOUNT_BARRIER;
+}
+
+static int nilfs_setup_super(struct nilfs_sb_info *sbi)
+{
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ struct nilfs_super_block *sbp = nilfs->ns_sbp[0];
+ int max_mnt_count = le16_to_cpu(sbp->s_max_mnt_count);
+ int mnt_count = le16_to_cpu(sbp->s_mnt_count);
+
+ /* nilfs->sem must be locked by the caller. */
+ if (!(nilfs->ns_mount_state & NILFS_VALID_FS)) {
+ printk(KERN_WARNING "NILFS warning: mounting unchecked fs\n");
+ } else if (nilfs->ns_mount_state & NILFS_ERROR_FS) {
+ printk(KERN_WARNING
+ "NILFS warning: mounting fs with errors\n");
+#if 0
+ } else if (max_mnt_count >= 0 && mnt_count >= max_mnt_count) {
+ printk(KERN_WARNING
+ "NILFS warning: maximal mount count reached\n");
+#endif
+ }
+ if (!max_mnt_count)
+ sbp->s_max_mnt_count = cpu_to_le16(NILFS_DFL_MAX_MNT_COUNT);
+
+ sbp->s_mnt_count = cpu_to_le16(mnt_count + 1);
+ sbp->s_state = cpu_to_le16(le16_to_cpu(sbp->s_state) & ~NILFS_VALID_FS);
+ sbp->s_mtime = cpu_to_le64(get_seconds());
+ return nilfs_commit_super(sbi, 1);
+}
+
+struct nilfs_super_block *nilfs_read_super_block(struct super_block *sb,
+ u64 pos, int blocksize,
+ struct buffer_head **pbh)
+{
+ unsigned long long sb_index = pos;
+ unsigned long offset;
+
+ offset = do_div(sb_index, blocksize);
+ *pbh = sb_bread(sb, sb_index);
+ if (!*pbh)
+ return NULL;
+ return (struct nilfs_super_block *)((char *)(*pbh)->b_data + offset);
+}
+
+int nilfs_store_magic_and_option(struct super_block *sb,
+ struct nilfs_super_block *sbp,
+ char *data)
+{
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+
+ sb->s_magic = le16_to_cpu(sbp->s_magic);
+
+ /* FS independent flags */
+#ifdef NILFS_ATIME_DISABLE
+ sb->s_flags |= MS_NOATIME;
+#endif
+
+ nilfs_set_default_options(sbi, sbp);
+
+ sbi->s_resuid = le16_to_cpu(sbp->s_def_resuid);
+ sbi->s_resgid = le16_to_cpu(sbp->s_def_resgid);
+ sbi->s_interval = le32_to_cpu(sbp->s_c_interval);
+ sbi->s_watermark = le32_to_cpu(sbp->s_c_block_max);
+
+ return !parse_options(data, sb) ? -EINVAL : 0 ;
+}
+
+/**
+ * nilfs_fill_super() - initialize a super block instance
+ * @sb: super_block
+ * @data: mount options
+ * @silent: silent mode flag
+ * @nilfs: the_nilfs struct
+ *
+ * This function is called exclusively by bd_mount_mutex.
+ * So, the recovery process is protected from other simultaneous mounts.
+ */
+static int
+nilfs_fill_super(struct super_block *sb, void *data, int silent,
+ struct the_nilfs *nilfs)
+{
+ struct nilfs_sb_info *sbi;
+ struct inode *root;
+ __u64 cno;
+ int err;
+
+ sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+ if (!sbi)
+ return -ENOMEM;
+
+ sb->s_fs_info = sbi;
+
+ get_nilfs(nilfs);
+ sbi->s_nilfs = nilfs;
+ sbi->s_super = sb;
+
+ err = init_nilfs(nilfs, sbi, (char *)data);
+ if (err)
+ goto failed_sbi;
+
+ spin_lock_init(&sbi->s_inode_lock);
+ INIT_LIST_HEAD(&sbi->s_dirty_files);
+ INIT_LIST_HEAD(&sbi->s_list);
+
+ /*
+ * Following initialization is overlapped because
+ * nilfs_sb_info structure has been cleared at the beginning.
+ * But we reserve them to keep our interest and make ready
+ * for the future change.
+ */
+ get_random_bytes(&sbi->s_next_generation,
+ sizeof(sbi->s_next_generation));
+ spin_lock_init(&sbi->s_next_gen_lock);
+
+ sb->s_op = &nilfs_sops;
+ sb->s_export_op = &nilfs_export_ops;
+ sb->s_root = NULL;
+ sb->s_time_gran = 1;
+
+ if (!nilfs_loaded(nilfs)) {
+ err = load_nilfs(nilfs, sbi);
+ if (err)
+ goto failed_sbi;
+ }
+ cno = nilfs_last_cno(nilfs);
+
+ if (sb->s_flags & MS_RDONLY) {
+ if (nilfs_test_opt(sbi, SNAPSHOT)) {
+ err = nilfs_cpfile_is_snapshot(nilfs->ns_cpfile,
+ sbi->s_snapshot_cno);
+ if (err < 0)
+ goto failed_sbi;
+ if (!err) {
+ printk(KERN_ERR
+ "NILFS: The specified checkpoint is "
+ "not a snapshot "
+ "(checkpoint number=%llu).\n",
+ (unsigned long long)sbi->s_snapshot_cno);
+ err = -EINVAL;
+ goto failed_sbi;
+ }
+ cno = sbi->s_snapshot_cno;
+ } else
+ /* Read-only mount */
+ sbi->s_snapshot_cno = cno;
+ }
+
+ err = nilfs_attach_checkpoint(sbi, cno);
+ if (err) {
+ printk(KERN_ERR "NILFS: error loading a checkpoint"
+ " (checkpoint number=%llu).\n", (unsigned long long)cno);
+ goto failed_sbi;
+ }
+
+ if (!(sb->s_flags & MS_RDONLY)) {
+ err = nilfs_attach_segment_constructor(sbi);
+ if (err)
+ goto failed_checkpoint;
+ }
+
+ root = nilfs_iget(sb, NILFS_ROOT_INO);
+ if (IS_ERR(root)) {
+ printk(KERN_ERR "NILFS: get root inode failed\n");
+ err = PTR_ERR(root);
+ goto failed_segctor;
+ }
+ if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
+ iput(root);
+ printk(KERN_ERR "NILFS: corrupt root inode.\n");
+ err = -EINVAL;
+ goto failed_segctor;
+ }
+ sb->s_root = d_alloc_root(root);
+ if (!sb->s_root) {
+ iput(root);
+ printk(KERN_ERR "NILFS: get root dentry failed\n");
+ err = -ENOMEM;
+ goto failed_segctor;
+ }
+
+ if (!(sb->s_flags & MS_RDONLY)) {
+ down_write(&nilfs->ns_sem);
+ nilfs_setup_super(sbi);
+ up_write(&nilfs->ns_sem);
+ }
+
+ err = nilfs_mark_recovery_complete(sbi);
+ if (unlikely(err)) {
+ printk(KERN_ERR "NILFS: recovery failed.\n");
+ goto failed_root;
+ }
+
+ return 0;
+
+ failed_root:
+ dput(sb->s_root);
+ sb->s_root = NULL;
+
+ failed_segctor:
+ nilfs_detach_segment_constructor(sbi);
+
+ failed_checkpoint:
+ nilfs_detach_checkpoint(sbi);
+
+ failed_sbi:
+ put_nilfs(nilfs);
+ sb->s_fs_info = NULL;
+ kfree(sbi);
+ return err;
+}
+
+static int nilfs_remount(struct super_block *sb, int *flags, char *data)
+{
+ struct nilfs_sb_info *sbi = NILFS_SB(sb);
+ struct nilfs_super_block *sbp;
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ unsigned long old_sb_flags;
+ struct nilfs_mount_options old_opts;
+ int err;
+
+ old_sb_flags = sb->s_flags;
+ old_opts.mount_opt = sbi->s_mount_opt;
+ old_opts.snapshot_cno = sbi->s_snapshot_cno;
+
+ if (!parse_options(data, sb)) {
+ err = -EINVAL;
+ goto restore_opts;
+ }
+ sb->s_flags = (sb->s_flags & ~MS_POSIXACL);
+
+ if ((*flags & MS_RDONLY) &&
+ sbi->s_snapshot_cno != old_opts.snapshot_cno) {
+ printk(KERN_WARNING "NILFS (device %s): couldn't "
+ "remount to a different snapshot. \n",
+ sb->s_id);
+ err = -EINVAL;
+ goto restore_opts;
+ }
+
+ if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
+ goto out;
+ if (*flags & MS_RDONLY) {
+ /* Shutting down the segment constructor */
+ nilfs_detach_segment_constructor(sbi);
+ sb->s_flags |= MS_RDONLY;
+
+ sbi->s_snapshot_cno = nilfs_last_cno(nilfs);
+ /* nilfs_set_opt(sbi, SNAPSHOT); */
+
+ /*
+ * Remounting a valid RW partition RDONLY, so set
+ * the RDONLY flag and then mark the partition as valid again.
+ */
+ down_write(&nilfs->ns_sem);
+ sbp = nilfs->ns_sbp[0];
+ if (!(sbp->s_state & le16_to_cpu(NILFS_VALID_FS)) &&
+ (nilfs->ns_mount_state & NILFS_VALID_FS))
+ sbp->s_state = cpu_to_le16(nilfs->ns_mount_state);
+ sbp->s_mtime = cpu_to_le64(get_seconds());
+ nilfs_commit_super(sbi, 1);
+ up_write(&nilfs->ns_sem);
+ } else {
+ /*
+ * Mounting a RDONLY partition read-write, so reread and
+ * store the current valid flag. (It may have been changed
+ * by fsck since we originally mounted the partition.)
+ */
+ down(&sb->s_bdev->bd_mount_sem);
+ /* Check existing RW-mount */
+ if (test_exclusive_mount(sb->s_type, sb->s_bdev, 0)) {
+ printk(KERN_WARNING "NILFS (device %s): couldn't "
+ "remount because a RW-mount exists.\n",
+ sb->s_id);
+ err = -EBUSY;
+ goto rw_remount_failed;
+ }
+ if (sbi->s_snapshot_cno != nilfs_last_cno(nilfs)) {
+ printk(KERN_WARNING "NILFS (device %s): couldn't "
+ "remount because the current RO-mount is not "
+ "the latest one.\n",
+ sb->s_id);
+ err = -EINVAL;
+ goto rw_remount_failed;
+ }
+ sb->s_flags &= ~MS_RDONLY;
+ nilfs_clear_opt(sbi, SNAPSHOT);
+ sbi->s_snapshot_cno = 0;
+
+ err = nilfs_attach_segment_constructor(sbi);
+ if (err)
+ goto rw_remount_failed;
+
+ down_write(&nilfs->ns_sem);
+ nilfs_setup_super(sbi);
+ up_write(&nilfs->ns_sem);
+
+ up(&sb->s_bdev->bd_mount_sem);
+ }
+ out:
+ return 0;
+
+ rw_remount_failed:
+ up(&sb->s_bdev->bd_mount_sem);
+ restore_opts:
+ sb->s_flags = old_sb_flags;
+ sbi->s_mount_opt = old_opts.mount_opt;
+ sbi->s_snapshot_cno = old_opts.snapshot_cno;
+ return err;
+}
+
+struct nilfs_super_data {
+ struct block_device *bdev;
+ __u64 cno;
+ int flags;
+};
+
+/**
+ * nilfs_identify - pre-read mount options needed to identify mount instance
+ * @data: mount options
+ * @sd: nilfs_super_data
+ */
+static int nilfs_identify(char *data, struct nilfs_super_data *sd)
+{
+ char *p, *options = data;
+ substring_t args[MAX_OPT_ARGS];
+ int option, token;
+ int ret = 0;
+
+ do {
+ p = strsep(&options, ",");
+ if (p != NULL && *p) {
+ token = match_token(p, tokens, args);
+ if (token == Opt_snapshot) {
+ if (!(sd->flags & MS_RDONLY))
+ ret++;
+ else {
+ ret = match_int(&args[0], &option);
+ if (!ret) {
+ if (option > 0)
+ sd->cno = option;
+ else
+ ret++;
+ }
+ }
+ }
+ if (ret)
+ printk(KERN_ERR
+ "NILFS: invalid mount option: %s\n", p);
+ }
+ if (!options)
+ break;
+ BUG_ON(options == data);
+ *(options - 1) = ',';
+ } while (!ret);
+ return ret;
+}
+
+static int nilfs_set_bdev_super(struct super_block *s, void *data)
+{
+ struct nilfs_super_data *sd = data;
+
+ s->s_bdev = sd->bdev;
+ s->s_dev = s->s_bdev->bd_dev;
+ return 0;
+}
+
+static int nilfs_test_bdev_super(struct super_block *s, void *data)
+{
+ struct nilfs_super_data *sd = data;
+
+ return s->s_bdev == sd->bdev;
+}
+
+static int nilfs_test_bdev_super2(struct super_block *s, void *data)
+{
+ struct nilfs_super_data *sd = data;
+ int ret;
+
+ if (s->s_bdev != sd->bdev)
+ return 0;
+
+ if (!((s->s_flags | sd->flags) & MS_RDONLY))
+ return 1; /* Reuse an old R/W-mode super_block */
+
+ if (s->s_flags & sd->flags & MS_RDONLY) {
+ if (down_read_trylock(&s->s_umount)) {
+ ret = s->s_root &&
+ (sd->cno == NILFS_SB(s)->s_snapshot_cno);
+ up_read(&s->s_umount);
+ /*
+ * This path is locked with sb_lock by sget().
+ * So, drop_super() causes deadlock.
+ */
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static int
+nilfs_get_sb(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *data, struct vfsmount *mnt)
+{
+ struct nilfs_super_data sd;
+ struct super_block *s, *s2;
+ struct the_nilfs *nilfs = NULL;
+ int err, need_to_close = 1;
+
+ sd.bdev = open_bdev_exclusive(dev_name, flags, fs_type);
+ if (IS_ERR(sd.bdev))
+ return PTR_ERR(sd.bdev);
+
+ /*
+ * To get mount instance using sget() vfs-routine, NILFS needs
+ * much more information than normal filesystems to identify mount
+ * instance. For snapshot mounts, not only a mount type (ro-mount
+ * or rw-mount) but also a checkpoint number is required.
+ * The results are passed in sget() using nilfs_super_data.
+ */
+ sd.cno = 0;
+ sd.flags = flags;
+ if (nilfs_identify((char *)data, &sd)) {
+ err = -EINVAL;
+ goto failed;
+ }
+
+ /*
+ * once the super is inserted into the list by sget, s_umount
+ * will protect the lockfs code from trying to start a snapshot
+ * while we are mounting
+ */
+ down(&sd.bdev->bd_mount_sem);
+ if (!sd.cno &&
+ (err = test_exclusive_mount(fs_type, sd.bdev, flags ^ MS_RDONLY))) {
+ err = (err < 0) ? : -EBUSY;
+ goto failed_unlock;
+ }
+
+ /*
+ * Phase-1: search any existent instance and get the_nilfs
+ */
+ s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, &sd);
+ if (IS_ERR(s))
+ goto error_s;
+
+ if (!s->s_root) {
+ err = -ENOMEM;
+ nilfs = alloc_nilfs(sd.bdev);
+ if (!nilfs)
+ goto cancel_new;
+ } else {
+ struct nilfs_sb_info *sbi = NILFS_SB(s);
+
+ /*
+ * s_umount protects super_block from unmount process;
+ * It covers pointers of nilfs_sb_info and the_nilfs.
+ */
+ nilfs = sbi->s_nilfs;
+ get_nilfs(nilfs);
+ up_write(&s->s_umount);
+
+ /*
+ * Phase-2: search specified snapshot or R/W mode super_block
+ */
+ if (!sd.cno)
+ /* trying to get the latest checkpoint. */
+ sd.cno = nilfs_last_cno(nilfs);
+
+ s2 = sget(fs_type, nilfs_test_bdev_super2,
+ nilfs_set_bdev_super, &sd);
+ deactivate_super(s);
+ /*
+ * Although deactivate_super() invokes close_bdev_exclusive() at
+ * kill_block_super(). Here, s is an existent mount; we need
+ * one more close_bdev_exclusive() call.
+ */
+ s = s2;
+ if (IS_ERR(s))
+ goto error_s;
+ }
+
+ if (!s->s_root) {
+ char b[BDEVNAME_SIZE];
+
+ s->s_flags = flags;
+ strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id));
+ sb_set_blocksize(s, block_size(sd.bdev));
+
+ err = nilfs_fill_super(s, data, flags & MS_VERBOSE, nilfs);
+ if (err)
+ goto cancel_new;
+
+ s->s_flags |= MS_ACTIVE;
+ need_to_close = 0;
+ } else if (!(s->s_flags & MS_RDONLY)) {
+ err = -EBUSY;
+ }
+
+ up(&sd.bdev->bd_mount_sem);
+ put_nilfs(nilfs);
+ if (need_to_close)
+ close_bdev_exclusive(sd.bdev, flags);
+ simple_set_mnt(mnt, s);
+ return 0;
+
+ error_s:
+ up(&sd.bdev->bd_mount_sem);
+ if (nilfs)
+ put_nilfs(nilfs);
+ close_bdev_exclusive(sd.bdev, flags);
+ return PTR_ERR(s);
+
+ failed_unlock:
+ up(&sd.bdev->bd_mount_sem);
+ failed:
+ close_bdev_exclusive(sd.bdev, flags);
+
+ return err;
+
+ cancel_new:
+ /* Abandoning the newly allocated superblock */
+ up(&sd.bdev->bd_mount_sem);
+ if (nilfs)
+ put_nilfs(nilfs);
+ up_write(&s->s_umount);
+ deactivate_super(s);
+ /*
+ * deactivate_super() invokes close_bdev_exclusive().
+ * We must finish all post-cleaning before this call;
+ * put_nilfs() and unlocking bd_mount_sem need the block device.
+ */
+ return err;
+}
+
+static int nilfs_test_bdev_super3(struct super_block *s, void *data)
+{
+ struct nilfs_super_data *sd = data;
+ int ret;
+
+ if (s->s_bdev != sd->bdev)
+ return 0;
+ if (down_read_trylock(&s->s_umount)) {
+ ret = (s->s_flags & MS_RDONLY) && s->s_root &&
+ nilfs_test_opt(NILFS_SB(s), SNAPSHOT);
+ up_read(&s->s_umount);
+ if (ret)
+ return 0; /* ignore snapshot mounts */
+ }
+ return !((sd->flags ^ s->s_flags) & MS_RDONLY);
+}
+
+static int __false_bdev_super(struct super_block *s, void *data)
+{
+#if 0 /* XXX: workaround for lock debug. This is not good idea */
+ up_write(&s->s_umount);
+#endif
+ return -EFAULT;
+}
+
+/**
+ * test_exclusive_mount - check whether an exclusive RW/RO mount exists or not.
+ * fs_type: filesystem type
+ * bdev: block device
+ * flag: 0 (check rw-mount) or MS_RDONLY (check ro-mount)
+ * res: pointer to an integer to store result
+ *
+ * This function must be called within a section protected by bd_mount_mutex.
+ */
+static int test_exclusive_mount(struct file_system_type *fs_type,
+ struct block_device *bdev, int flags)
+{
+ struct super_block *s;
+ struct nilfs_super_data sd = { .flags = flags, .bdev = bdev };
+
+ s = sget(fs_type, nilfs_test_bdev_super3, __false_bdev_super, &sd);
+ if (IS_ERR(s)) {
+ if (PTR_ERR(s) != -EFAULT)
+ return PTR_ERR(s);
+ return 0; /* Not found */
+ }
+ up_write(&s->s_umount);
+ deactivate_super(s);
+ return 1; /* Found */
+}
+
+struct file_system_type nilfs_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "nilfs2",
+ .get_sb = nilfs_get_sb,
+ .kill_sb = kill_block_super,
+ .fs_flags = FS_REQUIRES_DEV,
+};
+
+static int __init init_nilfs_fs(void)
+{
+ int err;
+
+ err = nilfs_init_inode_cache();
+ if (err)
+ goto failed;
+
+ err = nilfs_init_transaction_cache();
+ if (err)
+ goto failed_inode_cache;
+
+ err = nilfs_init_segbuf_cache();
+ if (err)
+ goto failed_transaction_cache;
+
+ err = nilfs_btree_path_cache_init();
+ if (err)
+ goto failed_segbuf_cache;
+
+ err = register_filesystem(&nilfs_fs_type);
+ if (err)
+ goto failed_btree_path_cache;
+
+ return 0;
+
+ failed_btree_path_cache:
+ nilfs_btree_path_cache_destroy();
+
+ failed_segbuf_cache:
+ nilfs_destroy_segbuf_cache();
+
+ failed_transaction_cache:
+ nilfs_destroy_transaction_cache();
+
+ failed_inode_cache:
+ nilfs_destroy_inode_cache();
+
+ failed:
+ return err;
+}
+
+static void __exit exit_nilfs_fs(void)
+{
+ nilfs_destroy_segbuf_cache();
+ nilfs_destroy_transaction_cache();
+ nilfs_destroy_inode_cache();
+ nilfs_btree_path_cache_destroy();
+ unregister_filesystem(&nilfs_fs_type);
+}
+
+module_init(init_nilfs_fs)
+module_exit(exit_nilfs_fs)
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
new file mode 100644
index 00000000000..7f65b3be4aa
--- /dev/null
+++ b/fs/nilfs2/the_nilfs.c
@@ -0,0 +1,641 @@
+/*
+ * the_nilfs.c - the_nilfs shared structure.
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>
+ *
+ */
+
+#include <linux/buffer_head.h>
+#include <linux/slab.h>
+#include <linux/blkdev.h>
+#include <linux/backing-dev.h>
+#include <linux/crc32.h>
+#include "nilfs.h"
+#include "segment.h"
+#include "alloc.h"
+#include "cpfile.h"
+#include "sufile.h"
+#include "dat.h"
+#include "seglist.h"
+#include "segbuf.h"
+
+void nilfs_set_last_segment(struct the_nilfs *nilfs,
+ sector_t start_blocknr, u64 seq, __u64 cno)
+{
+ spin_lock(&nilfs->ns_last_segment_lock);
+ nilfs->ns_last_pseg = start_blocknr;
+ nilfs->ns_last_seq = seq;
+ nilfs->ns_last_cno = cno;
+ spin_unlock(&nilfs->ns_last_segment_lock);
+}
+
+/**
+ * alloc_nilfs - allocate the_nilfs structure
+ * @bdev: block device to which the_nilfs is related
+ *
+ * alloc_nilfs() allocates memory for the_nilfs and
+ * initializes its reference count and locks.
+ *
+ * Return Value: On success, pointer to the_nilfs is returned.
+ * On error, NULL is returned.
+ */
+struct the_nilfs *alloc_nilfs(struct block_device *bdev)
+{
+ struct the_nilfs *nilfs;
+
+ nilfs = kzalloc(sizeof(*nilfs), GFP_KERNEL);
+ if (!nilfs)
+ return NULL;
+
+ nilfs->ns_bdev = bdev;
+ atomic_set(&nilfs->ns_count, 1);
+ atomic_set(&nilfs->ns_writer_refcount, -1);
+ atomic_set(&nilfs->ns_ndirtyblks, 0);
+ init_rwsem(&nilfs->ns_sem);
+ mutex_init(&nilfs->ns_writer_mutex);
+ INIT_LIST_HEAD(&nilfs->ns_supers);
+ spin_lock_init(&nilfs->ns_last_segment_lock);
+ nilfs->ns_gc_inodes_h = NULL;
+ init_rwsem(&nilfs->ns_segctor_sem);
+
+ return nilfs;
+}
+
+/**
+ * put_nilfs - release a reference to the_nilfs
+ * @nilfs: the_nilfs structure to be released
+ *
+ * put_nilfs() decrements a reference counter of the_nilfs.
+ * If the reference count reaches zero, the_nilfs is freed.
+ */
+void put_nilfs(struct the_nilfs *nilfs)
+{
+ if (!atomic_dec_and_test(&nilfs->ns_count))
+ return;
+ /*
+ * Increment of ns_count never occur below because the caller
+ * of get_nilfs() holds at least one reference to the_nilfs.
+ * Thus its exclusion control is not required here.
+ */
+ might_sleep();
+ if (nilfs_loaded(nilfs)) {
+ nilfs_mdt_clear(nilfs->ns_sufile);
+ nilfs_mdt_destroy(nilfs->ns_sufile);
+ nilfs_mdt_clear(nilfs->ns_cpfile);
+ nilfs_mdt_destroy(nilfs->ns_cpfile);
+ nilfs_mdt_clear(nilfs->ns_dat);
+ nilfs_mdt_destroy(nilfs->ns_dat);
+ /* XXX: how and when to clear nilfs->ns_gc_dat? */
+ nilfs_mdt_destroy(nilfs->ns_gc_dat);
+ }
+ if (nilfs_init(nilfs)) {
+ nilfs_destroy_gccache(nilfs);
+ brelse(nilfs->ns_sbh[0]);
+ brelse(nilfs->ns_sbh[1]);
+ }
+ kfree(nilfs);
+}
+
+static int nilfs_load_super_root(struct the_nilfs *nilfs,
+ struct nilfs_sb_info *sbi, sector_t sr_block)
+{
+ static struct lock_class_key dat_lock_key;
+ struct buffer_head *bh_sr;
+ struct nilfs_super_root *raw_sr;
+ struct nilfs_super_block **sbp = nilfs->ns_sbp;
+ unsigned dat_entry_size, segment_usage_size, checkpoint_size;
+ unsigned inode_size;
+ int err;
+
+ err = nilfs_read_super_root_block(sbi->s_super, sr_block, &bh_sr, 1);
+ if (unlikely(err))
+ return err;
+
+ down_read(&nilfs->ns_sem);
+ dat_entry_size = le16_to_cpu(sbp[0]->s_dat_entry_size);
+ checkpoint_size = le16_to_cpu(sbp[0]->s_checkpoint_size);
+ segment_usage_size = le16_to_cpu(sbp[0]->s_segment_usage_size);
+ up_read(&nilfs->ns_sem);
+
+ inode_size = nilfs->ns_inode_size;
+
+ err = -ENOMEM;
+ nilfs->ns_dat = nilfs_mdt_new(
+ nilfs, NULL, NILFS_DAT_INO, NILFS_DAT_GFP);
+ if (unlikely(!nilfs->ns_dat))
+ goto failed;
+
+ nilfs->ns_gc_dat = nilfs_mdt_new(
+ nilfs, NULL, NILFS_DAT_INO, NILFS_DAT_GFP);
+ if (unlikely(!nilfs->ns_gc_dat))
+ goto failed_dat;
+
+ nilfs->ns_cpfile = nilfs_mdt_new(
+ nilfs, NULL, NILFS_CPFILE_INO, NILFS_CPFILE_GFP);
+ if (unlikely(!nilfs->ns_cpfile))
+ goto failed_gc_dat;
+
+ nilfs->ns_sufile = nilfs_mdt_new(
+ nilfs, NULL, NILFS_SUFILE_INO, NILFS_SUFILE_GFP);
+ if (unlikely(!nilfs->ns_sufile))
+ goto failed_cpfile;
+
+ err = nilfs_palloc_init_blockgroup(nilfs->ns_dat, dat_entry_size);
+ if (unlikely(err))
+ goto failed_sufile;
+
+ err = nilfs_palloc_init_blockgroup(nilfs->ns_gc_dat, dat_entry_size);
+ if (unlikely(err))
+ goto failed_sufile;
+
+ lockdep_set_class(&NILFS_MDT(nilfs->ns_dat)->mi_sem, &dat_lock_key);
+ lockdep_set_class(&NILFS_MDT(nilfs->ns_gc_dat)->mi_sem, &dat_lock_key);
+
+ nilfs_mdt_set_shadow(nilfs->ns_dat, nilfs->ns_gc_dat);
+ nilfs_mdt_set_entry_size(nilfs->ns_cpfile, checkpoint_size,
+ sizeof(struct nilfs_cpfile_header));
+ nilfs_mdt_set_entry_size(nilfs->ns_sufile, segment_usage_size,
+ sizeof(struct nilfs_sufile_header));
+
+ err = nilfs_mdt_read_inode_direct(
+ nilfs->ns_dat, bh_sr, NILFS_SR_DAT_OFFSET(inode_size));
+ if (unlikely(err))
+ goto failed_sufile;
+
+ err = nilfs_mdt_read_inode_direct(
+ nilfs->ns_cpfile, bh_sr, NILFS_SR_CPFILE_OFFSET(inode_size));
+ if (unlikely(err))
+ goto failed_sufile;
+
+ err = nilfs_mdt_read_inode_direct(
+ nilfs->ns_sufile, bh_sr, NILFS_SR_SUFILE_OFFSET(inode_size));
+ if (unlikely(err))
+ goto failed_sufile;
+
+ raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
+ nilfs->ns_nongc_ctime = le64_to_cpu(raw_sr->sr_nongc_ctime);
+
+ failed:
+ brelse(bh_sr);
+ return err;
+
+ failed_sufile:
+ nilfs_mdt_destroy(nilfs->ns_sufile);
+
+ failed_cpfile:
+ nilfs_mdt_destroy(nilfs->ns_cpfile);
+
+ failed_gc_dat:
+ nilfs_mdt_destroy(nilfs->ns_gc_dat);
+
+ failed_dat:
+ nilfs_mdt_destroy(nilfs->ns_dat);
+ goto failed;
+}
+
+static void nilfs_init_recovery_info(struct nilfs_recovery_info *ri)
+{
+ memset(ri, 0, sizeof(*ri));
+ INIT_LIST_HEAD(&ri->ri_used_segments);
+}
+
+static void nilfs_clear_recovery_info(struct nilfs_recovery_info *ri)
+{
+ nilfs_dispose_segment_list(&ri->ri_used_segments);
+}
+
+/**
+ * load_nilfs - load and recover the nilfs
+ * @nilfs: the_nilfs structure to be released
+ * @sbi: nilfs_sb_info used to recover past segment
+ *
+ * load_nilfs() searches and load the latest super root,
+ * attaches the last segment, and does recovery if needed.
+ * The caller must call this exclusively for simultaneous mounts.
+ */
+int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
+{
+ struct nilfs_recovery_info ri;
+ unsigned int s_flags = sbi->s_super->s_flags;
+ int really_read_only = bdev_read_only(nilfs->ns_bdev);
+ unsigned valid_fs;
+ int err = 0;
+
+ nilfs_init_recovery_info(&ri);
+
+ down_write(&nilfs->ns_sem);
+ valid_fs = (nilfs->ns_mount_state & NILFS_VALID_FS);
+ up_write(&nilfs->ns_sem);
+
+ if (!valid_fs && (s_flags & MS_RDONLY)) {
+ printk(KERN_INFO "NILFS: INFO: recovery "
+ "required for readonly filesystem.\n");
+ if (really_read_only) {
+ printk(KERN_ERR "NILFS: write access "
+ "unavailable, cannot proceed.\n");
+ err = -EROFS;
+ goto failed;
+ }
+ printk(KERN_INFO "NILFS: write access will "
+ "be enabled during recovery.\n");
+ sbi->s_super->s_flags &= ~MS_RDONLY;
+ }
+
+ err = nilfs_search_super_root(nilfs, sbi, &ri);
+ if (unlikely(err)) {
+ printk(KERN_ERR "NILFS: error searching super root.\n");
+ goto failed;
+ }
+
+ err = nilfs_load_super_root(nilfs, sbi, ri.ri_super_root);
+ if (unlikely(err)) {
+ printk(KERN_ERR "NILFS: error loading super root.\n");
+ goto failed;
+ }
+
+ if (!valid_fs) {
+ err = nilfs_recover_logical_segments(nilfs, sbi, &ri);
+ if (unlikely(err)) {
+ nilfs_mdt_destroy(nilfs->ns_cpfile);
+ nilfs_mdt_destroy(nilfs->ns_sufile);
+ nilfs_mdt_destroy(nilfs->ns_dat);
+ goto failed;
+ }
+ if (ri.ri_need_recovery == NILFS_RECOVERY_SR_UPDATED)
+ sbi->s_super->s_dirt = 1;
+ }
+
+ set_nilfs_loaded(nilfs);
+
+ failed:
+ nilfs_clear_recovery_info(&ri);
+ sbi->s_super->s_flags = s_flags;
+ return err;
+}
+
+static unsigned long long nilfs_max_size(unsigned int blkbits)
+{
+ unsigned int max_bits;
+ unsigned long long res = MAX_LFS_FILESIZE; /* page cache limit */
+
+ max_bits = blkbits + NILFS_BMAP_KEY_BIT; /* bmap size limit */
+ if (max_bits < 64)
+ res = min_t(unsigned long long, res, (1ULL << max_bits) - 1);
+ return res;
+}
+
+static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
+ struct nilfs_super_block *sbp)
+{
+ if (le32_to_cpu(sbp->s_rev_level) != NILFS_CURRENT_REV) {
+ printk(KERN_ERR "NILFS: revision mismatch "
+ "(superblock rev.=%d.%d, current rev.=%d.%d). "
+ "Please check the version of mkfs.nilfs.\n",
+ le32_to_cpu(sbp->s_rev_level),
+ le16_to_cpu(sbp->s_minor_rev_level),
+ NILFS_CURRENT_REV, NILFS_MINOR_REV);
+ return -EINVAL;
+ }
+ nilfs->ns_sbsize = le16_to_cpu(sbp->s_bytes);
+ if (nilfs->ns_sbsize > BLOCK_SIZE)
+ return -EINVAL;
+
+ nilfs->ns_inode_size = le16_to_cpu(sbp->s_inode_size);
+ nilfs->ns_first_ino = le32_to_cpu(sbp->s_first_ino);
+
+ nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
+ if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) {
+ printk(KERN_ERR "NILFS: too short segment. \n");
+ return -EINVAL;
+ }
+
+ nilfs->ns_first_data_block = le64_to_cpu(sbp->s_first_data_block);
+ nilfs->ns_nsegments = le64_to_cpu(sbp->s_nsegments);
+ nilfs->ns_r_segments_percentage =
+ le32_to_cpu(sbp->s_r_segments_percentage);
+ nilfs->ns_nrsvsegs =
+ max_t(unsigned long, NILFS_MIN_NRSVSEGS,
+ DIV_ROUND_UP(nilfs->ns_nsegments *
+ nilfs->ns_r_segments_percentage, 100));
+ nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed);
+ return 0;
+}
+
+static int nilfs_valid_sb(struct nilfs_super_block *sbp)
+{
+ static unsigned char sum[4];
+ const int sumoff = offsetof(struct nilfs_super_block, s_sum);
+ size_t bytes;
+ u32 crc;
+
+ if (!sbp || le16_to_cpu(sbp->s_magic) != NILFS_SUPER_MAGIC)
+ return 0;
+ bytes = le16_to_cpu(sbp->s_bytes);
+ if (bytes > BLOCK_SIZE)
+ return 0;
+ crc = crc32_le(le32_to_cpu(sbp->s_crc_seed), (unsigned char *)sbp,
+ sumoff);
+ crc = crc32_le(crc, sum, 4);
+ crc = crc32_le(crc, (unsigned char *)sbp + sumoff + 4,
+ bytes - sumoff - 4);
+ return crc == le32_to_cpu(sbp->s_sum);
+}
+
+static int nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset)
+{
+ return offset < ((le64_to_cpu(sbp->s_nsegments) *
+ le32_to_cpu(sbp->s_blocks_per_segment)) <<
+ (le32_to_cpu(sbp->s_log_block_size) + 10));
+}
+
+static void nilfs_release_super_block(struct the_nilfs *nilfs)
+{
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ if (nilfs->ns_sbp[i]) {
+ brelse(nilfs->ns_sbh[i]);
+ nilfs->ns_sbh[i] = NULL;
+ nilfs->ns_sbp[i] = NULL;
+ }
+ }
+}
+
+void nilfs_fall_back_super_block(struct the_nilfs *nilfs)
+{
+ brelse(nilfs->ns_sbh[0]);
+ nilfs->ns_sbh[0] = nilfs->ns_sbh[1];
+ nilfs->ns_sbp[0] = nilfs->ns_sbp[1];
+ nilfs->ns_sbh[1] = NULL;
+ nilfs->ns_sbp[1] = NULL;
+}
+
+void nilfs_swap_super_block(struct the_nilfs *nilfs)
+{
+ struct buffer_head *tsbh = nilfs->ns_sbh[0];
+ struct nilfs_super_block *tsbp = nilfs->ns_sbp[0];
+
+ nilfs->ns_sbh[0] = nilfs->ns_sbh[1];
+ nilfs->ns_sbp[0] = nilfs->ns_sbp[1];
+ nilfs->ns_sbh[1] = tsbh;
+ nilfs->ns_sbp[1] = tsbp;
+}
+
+static int nilfs_load_super_block(struct the_nilfs *nilfs,
+ struct super_block *sb, int blocksize,
+ struct nilfs_super_block **sbpp)
+{
+ struct nilfs_super_block **sbp = nilfs->ns_sbp;
+ struct buffer_head **sbh = nilfs->ns_sbh;
+ u64 sb2off = NILFS_SB2_OFFSET_BYTES(nilfs->ns_bdev->bd_inode->i_size);
+ int valid[2], swp = 0;
+
+ sbp[0] = nilfs_read_super_block(sb, NILFS_SB_OFFSET_BYTES, blocksize,
+ &sbh[0]);
+ sbp[1] = nilfs_read_super_block(sb, sb2off, blocksize, &sbh[1]);
+
+ if (!sbp[0]) {
+ if (!sbp[1]) {
+ printk(KERN_ERR "NILFS: unable to read superblock\n");
+ return -EIO;
+ }
+ printk(KERN_WARNING
+ "NILFS warning: unable to read primary superblock\n");
+ } else if (!sbp[1])
+ printk(KERN_WARNING
+ "NILFS warning: unable to read secondary superblock\n");
+
+ valid[0] = nilfs_valid_sb(sbp[0]);
+ valid[1] = nilfs_valid_sb(sbp[1]);
+ swp = valid[1] &&
+ (!valid[0] ||
+ le64_to_cpu(sbp[1]->s_wtime) > le64_to_cpu(sbp[0]->s_wtime));
+
+ if (valid[swp] && nilfs_sb2_bad_offset(sbp[swp], sb2off)) {
+ brelse(sbh[1]);
+ sbh[1] = NULL;
+ sbp[1] = NULL;
+ swp = 0;
+ }
+ if (!valid[swp]) {
+ nilfs_release_super_block(nilfs);
+ printk(KERN_ERR "NILFS: Can't find nilfs on dev %s.\n",
+ sb->s_id);
+ return -EINVAL;
+ }
+
+ if (swp) {
+ printk(KERN_WARNING "NILFS warning: broken superblock. "
+ "using spare superblock.\n");
+ nilfs_swap_super_block(nilfs);
+ }
+
+ nilfs->ns_sbwtime[0] = le64_to_cpu(sbp[0]->s_wtime);
+ nilfs->ns_sbwtime[1] = valid[!swp] ? le64_to_cpu(sbp[1]->s_wtime) : 0;
+ nilfs->ns_prot_seq = le64_to_cpu(sbp[valid[1] & !swp]->s_last_seq);
+ *sbpp = sbp[0];
+ return 0;
+}
+
+/**
+ * init_nilfs - initialize a NILFS instance.
+ * @nilfs: the_nilfs structure
+ * @sbi: nilfs_sb_info
+ * @sb: super block
+ * @data: mount options
+ *
+ * init_nilfs() performs common initialization per block device (e.g.
+ * reading the super block, getting disk layout information, initializing
+ * shared fields in the_nilfs). It takes on some portion of the jobs
+ * typically done by a fill_super() routine. This division arises from
+ * the nature that multiple NILFS instances may be simultaneously
+ * mounted on a device.
+ * For multiple mounts on the same device, only the first mount
+ * invokes these tasks.
+ *
+ * Return Value: On success, 0 is returned. On error, a negative error
+ * code is returned.
+ */
+int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
+{
+ struct super_block *sb = sbi->s_super;
+ struct nilfs_super_block *sbp;
+ struct backing_dev_info *bdi;
+ int blocksize;
+ int err;
+
+ down_write(&nilfs->ns_sem);
+ if (nilfs_init(nilfs)) {
+ /* Load values from existing the_nilfs */
+ sbp = nilfs->ns_sbp[0];
+ err = nilfs_store_magic_and_option(sb, sbp, data);
+ if (err)
+ goto out;
+
+ blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
+ if (sb->s_blocksize != blocksize &&
+ !sb_set_blocksize(sb, blocksize)) {
+ printk(KERN_ERR "NILFS: blocksize %d unfit to device\n",
+ blocksize);
+ err = -EINVAL;
+ }
+ sb->s_maxbytes = nilfs_max_size(sb->s_blocksize_bits);
+ goto out;
+ }
+
+ blocksize = sb_min_blocksize(sb, BLOCK_SIZE);
+ if (!blocksize) {
+ printk(KERN_ERR "NILFS: unable to set blocksize\n");
+ err = -EINVAL;
+ goto out;
+ }
+ err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp);
+ if (err)
+ goto out;
+
+ err = nilfs_store_magic_and_option(sb, sbp, data);
+ if (err)
+ goto failed_sbh;
+
+ blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
+ if (sb->s_blocksize != blocksize) {
+ int hw_blocksize = bdev_hardsect_size(sb->s_bdev);
+
+ if (blocksize < hw_blocksize) {
+ printk(KERN_ERR
+ "NILFS: blocksize %d too small for device "
+ "(sector-size = %d).\n",
+ blocksize, hw_blocksize);
+ err = -EINVAL;
+ goto failed_sbh;
+ }
+ nilfs_release_super_block(nilfs);
+ sb_set_blocksize(sb, blocksize);
+
+ err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp);
+ if (err)
+ goto out;
+ /* not failed_sbh; sbh is released automatically
+ when reloading fails. */
+ }
+ nilfs->ns_blocksize_bits = sb->s_blocksize_bits;
+
+ err = nilfs_store_disk_layout(nilfs, sbp);
+ if (err)
+ goto failed_sbh;
+
+ sb->s_maxbytes = nilfs_max_size(sb->s_blocksize_bits);
+
+ nilfs->ns_mount_state = le16_to_cpu(sbp->s_state);
+
+ bdi = nilfs->ns_bdev->bd_inode_backing_dev_info;
+ if (!bdi)
+ bdi = nilfs->ns_bdev->bd_inode->i_mapping->backing_dev_info;
+ nilfs->ns_bdi = bdi ? : &default_backing_dev_info;
+
+ /* Finding last segment */
+ nilfs->ns_last_pseg = le64_to_cpu(sbp->s_last_pseg);
+ nilfs->ns_last_cno = le64_to_cpu(sbp->s_last_cno);
+ nilfs->ns_last_seq = le64_to_cpu(sbp->s_last_seq);
+
+ nilfs->ns_seg_seq = nilfs->ns_last_seq;
+ nilfs->ns_segnum =
+ nilfs_get_segnum_of_block(nilfs, nilfs->ns_last_pseg);
+ nilfs->ns_cno = nilfs->ns_last_cno + 1;
+ if (nilfs->ns_segnum >= nilfs->ns_nsegments) {
+ printk(KERN_ERR "NILFS invalid last segment number.\n");
+ err = -EINVAL;
+ goto failed_sbh;
+ }
+ /* Dummy values */
+ nilfs->ns_free_segments_count =
+ nilfs->ns_nsegments - (nilfs->ns_segnum + 1);
+
+ /* Initialize gcinode cache */
+ err = nilfs_init_gccache(nilfs);
+ if (err)
+ goto failed_sbh;
+
+ set_nilfs_init(nilfs);
+ err = 0;
+ out:
+ up_write(&nilfs->ns_sem);
+ return err;
+
+ failed_sbh:
+ nilfs_release_super_block(nilfs);
+ goto out;
+}
+
+int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks)
+{
+ struct inode *dat = nilfs_dat_inode(nilfs);
+ unsigned long ncleansegs;
+ int err;
+
+ down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
+ err = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile, &ncleansegs);
+ up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
+ if (likely(!err))
+ *nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment;
+ return err;
+}
+
+int nilfs_near_disk_full(struct the_nilfs *nilfs)
+{
+ struct inode *sufile = nilfs->ns_sufile;
+ unsigned long ncleansegs, nincsegs;
+ int ret;
+
+ ret = nilfs_sufile_get_ncleansegs(sufile, &ncleansegs);
+ if (likely(!ret)) {
+ nincsegs = atomic_read(&nilfs->ns_ndirtyblks) /
+ nilfs->ns_blocks_per_segment + 1;
+ if (ncleansegs <= nilfs->ns_nrsvsegs + nincsegs)
+ ret++;
+ }
+ return ret;
+}
+
+int nilfs_checkpoint_is_mounted(struct the_nilfs *nilfs, __u64 cno,
+ int snapshot_mount)
+{
+ struct nilfs_sb_info *sbi;
+ int ret = 0;
+
+ down_read(&nilfs->ns_sem);
+ if (cno == 0 || cno > nilfs->ns_cno)
+ goto out_unlock;
+
+ list_for_each_entry(sbi, &nilfs->ns_supers, s_list) {
+ if (sbi->s_snapshot_cno == cno &&
+ (!snapshot_mount || nilfs_test_opt(sbi, SNAPSHOT))) {
+ /* exclude read-only mounts */
+ ret++;
+ break;
+ }
+ }
+ /* for protecting recent checkpoints */
+ if (cno >= nilfs_last_cno(nilfs))
+ ret++;
+
+ out_unlock:
+ up_read(&nilfs->ns_sem);
+ return ret;
+}
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
new file mode 100644
index 00000000000..30fe58778d0
--- /dev/null
+++ b/fs/nilfs2/the_nilfs.h
@@ -0,0 +1,298 @@
+/*
+ * the_nilfs.h - the_nilfs shared structure.
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Ryusuke Konishi <ryusuke@osrg.net>
+ *
+ */
+
+#ifndef _THE_NILFS_H
+#define _THE_NILFS_H
+
+#include <linux/types.h>
+#include <linux/buffer_head.h>
+#include <linux/fs.h>
+#include <linux/blkdev.h>
+#include <linux/backing-dev.h>
+#include "sb.h"
+
+/* the_nilfs struct */
+enum {
+ THE_NILFS_INIT = 0, /* Information from super_block is set */
+ THE_NILFS_LOADED, /* Roll-back/roll-forward has done and
+ the latest checkpoint was loaded */
+ THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */
+};
+
+/**
+ * struct the_nilfs - struct to supervise multiple nilfs mount points
+ * @ns_flags: flags
+ * @ns_count: reference count
+ * @ns_bdev: block device
+ * @ns_bdi: backing dev info
+ * @ns_writer: back pointer to writable nilfs_sb_info
+ * @ns_sem: semaphore for shared states
+ * @ns_writer_mutex: mutex protecting ns_writer attach/detach
+ * @ns_writer_refcount: number of referrers on ns_writer
+ * @ns_sbh: buffer heads of on-disk super blocks
+ * @ns_sbp: pointers to super block data
+ * @ns_sbwtime: previous write time of super blocks
+ * @ns_sbsize: size of valid data in super block
+ * @ns_supers: list of nilfs super block structs
+ * @ns_seg_seq: segment sequence counter
+ * @ns_segnum: index number of the latest full segment.
+ * @ns_nextnum: index number of the full segment index to be used next
+ * @ns_pseg_offset: offset of next partial segment in the current full segment
+ * @ns_cno: next checkpoint number
+ * @ns_ctime: write time of the last segment
+ * @ns_nongc_ctime: write time of the last segment not for cleaner operation
+ * @ns_ndirtyblks: Number of dirty data blocks
+ * @ns_last_segment_lock: lock protecting fields for the latest segment
+ * @ns_last_pseg: start block number of the latest segment
+ * @ns_last_seq: sequence value of the latest segment
+ * @ns_last_cno: checkpoint number of the latest segment
+ * @ns_prot_seq: least sequence number of segments which must not be reclaimed
+ * @ns_free_segments_count: counter of free segments
+ * @ns_segctor_sem: segment constructor semaphore
+ * @ns_dat: DAT file inode
+ * @ns_cpfile: checkpoint file inode
+ * @ns_sufile: segusage file inode
+ * @ns_gc_dat: shadow inode of the DAT file inode for GC
+ * @ns_gc_inodes: dummy inodes to keep live blocks
+ * @ns_gc_inodes_h: hash list to keep dummy inode holding live blocks
+ * @ns_blocksize_bits: bit length of block size
+ * @ns_nsegments: number of segments in filesystem
+ * @ns_blocks_per_segment: number of blocks per segment
+ * @ns_r_segments_percentage: reserved segments percentage
+ * @ns_nrsvsegs: number of reserved segments
+ * @ns_first_data_block: block number of first data block
+ * @ns_inode_size: size of on-disk inode
+ * @ns_first_ino: first not-special inode number
+ * @ns_crc_seed: seed value of CRC32 calculation
+ */
+struct the_nilfs {
+ unsigned long ns_flags;
+ atomic_t ns_count;
+
+ struct block_device *ns_bdev;
+ struct backing_dev_info *ns_bdi;
+ struct nilfs_sb_info *ns_writer;
+ struct rw_semaphore ns_sem;
+ struct mutex ns_writer_mutex;
+ atomic_t ns_writer_refcount;
+
+ /*
+ * used for
+ * - loading the latest checkpoint exclusively.
+ * - allocating a new full segment.
+ * - protecting s_dirt in the super_block struct
+ * (see nilfs_write_super) and the following fields.
+ */
+ struct buffer_head *ns_sbh[2];
+ struct nilfs_super_block *ns_sbp[2];
+ time_t ns_sbwtime[2];
+ unsigned ns_sbsize;
+ unsigned ns_mount_state;
+ struct list_head ns_supers;
+
+ /*
+ * Following fields are dedicated to a writable FS-instance.
+ * Except for the period seeking checkpoint, code outside the segment
+ * constructor must lock a segment semaphore while accessing these
+ * fields.
+ * The writable FS-instance is sole during a lifetime of the_nilfs.
+ */
+ u64 ns_seg_seq;
+ __u64 ns_segnum;
+ __u64 ns_nextnum;
+ unsigned long ns_pseg_offset;
+ __u64 ns_cno;
+ time_t ns_ctime;
+ time_t ns_nongc_ctime;
+ atomic_t ns_ndirtyblks;
+
+ /*
+ * The following fields hold information on the latest partial segment
+ * written to disk with a super root. These fields are protected by
+ * ns_last_segment_lock.
+ */
+ spinlock_t ns_last_segment_lock;
+ sector_t ns_last_pseg;
+ u64 ns_last_seq;
+ __u64 ns_last_cno;
+ u64 ns_prot_seq;
+ unsigned long ns_free_segments_count;
+
+ struct rw_semaphore ns_segctor_sem;
+
+ /*
+ * Following fields are lock free except for the period before
+ * the_nilfs is initialized.
+ */
+ struct inode *ns_dat;
+ struct inode *ns_cpfile;
+ struct inode *ns_sufile;
+ struct inode *ns_gc_dat;
+
+ /* GC inode list and hash table head */
+ struct list_head ns_gc_inodes;
+ struct hlist_head *ns_gc_inodes_h;
+
+ /* Disk layout information (static) */
+ unsigned int ns_blocksize_bits;
+ unsigned long ns_nsegments;
+ unsigned long ns_blocks_per_segment;
+ unsigned long ns_r_segments_percentage;
+ unsigned long ns_nrsvsegs;
+ unsigned long ns_first_data_block;
+ int ns_inode_size;
+ int ns_first_ino;
+ u32 ns_crc_seed;
+};
+
+#define NILFS_GCINODE_HASH_BITS 8
+#define NILFS_GCINODE_HASH_SIZE (1<<NILFS_GCINODE_HASH_BITS)
+
+#define THE_NILFS_FNS(bit, name) \
+static inline void set_nilfs_##name(struct the_nilfs *nilfs) \
+{ \
+ set_bit(THE_NILFS_##bit, &(nilfs)->ns_flags); \
+} \
+static inline void clear_nilfs_##name(struct the_nilfs *nilfs) \
+{ \
+ clear_bit(THE_NILFS_##bit, &(nilfs)->ns_flags); \
+} \
+static inline int nilfs_##name(struct the_nilfs *nilfs) \
+{ \
+ return test_bit(THE_NILFS_##bit, &(nilfs)->ns_flags); \
+}
+
+THE_NILFS_FNS(INIT, init)
+THE_NILFS_FNS(LOADED, loaded)
+THE_NILFS_FNS(DISCONTINUED, discontinued)
+
+/* Minimum interval of periodical update of superblocks (in seconds) */
+#define NILFS_SB_FREQ 10
+#define NILFS_ALTSB_FREQ 60 /* spare superblock */
+
+void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64);
+struct the_nilfs *alloc_nilfs(struct block_device *);
+void put_nilfs(struct the_nilfs *);
+int init_nilfs(struct the_nilfs *, struct nilfs_sb_info *, char *);
+int load_nilfs(struct the_nilfs *, struct nilfs_sb_info *);
+int nilfs_count_free_blocks(struct the_nilfs *, sector_t *);
+int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int);
+int nilfs_near_disk_full(struct the_nilfs *);
+void nilfs_fall_back_super_block(struct the_nilfs *);
+void nilfs_swap_super_block(struct the_nilfs *);
+
+
+static inline void get_nilfs(struct the_nilfs *nilfs)
+{
+ /* Caller must have at least one reference of the_nilfs. */
+ atomic_inc(&nilfs->ns_count);
+}
+
+static inline struct nilfs_sb_info *nilfs_get_writer(struct the_nilfs *nilfs)
+{
+ if (atomic_inc_and_test(&nilfs->ns_writer_refcount))
+ mutex_lock(&nilfs->ns_writer_mutex);
+ return nilfs->ns_writer;
+}
+
+static inline void nilfs_put_writer(struct the_nilfs *nilfs)
+{
+ if (atomic_add_negative(-1, &nilfs->ns_writer_refcount))
+ mutex_unlock(&nilfs->ns_writer_mutex);
+}
+
+static inline void
+nilfs_attach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
+{
+ mutex_lock(&nilfs->ns_writer_mutex);
+ nilfs->ns_writer = sbi;
+ mutex_unlock(&nilfs->ns_writer_mutex);
+}
+
+static inline void
+nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
+{
+ mutex_lock(&nilfs->ns_writer_mutex);
+ if (sbi == nilfs->ns_writer)
+ nilfs->ns_writer = NULL;
+ mutex_unlock(&nilfs->ns_writer_mutex);
+}
+
+static inline void
+nilfs_get_segment_range(struct the_nilfs *nilfs, __u64 segnum,
+ sector_t *seg_start, sector_t *seg_end)
+{
+ *seg_start = (sector_t)nilfs->ns_blocks_per_segment * segnum;
+ *seg_end = *seg_start + nilfs->ns_blocks_per_segment - 1;
+ if (segnum == 0)
+ *seg_start = nilfs->ns_first_data_block;
+}
+
+static inline sector_t
+nilfs_get_segment_start_blocknr(struct the_nilfs *nilfs, __u64 segnum)
+{
+ return (segnum == 0) ? nilfs->ns_first_data_block :
+ (sector_t)nilfs->ns_blocks_per_segment * segnum;
+}
+
+static inline __u64
+nilfs_get_segnum_of_block(struct the_nilfs *nilfs, sector_t blocknr)
+{
+ sector_t segnum = blocknr;
+
+ sector_div(segnum, nilfs->ns_blocks_per_segment);
+ return segnum;
+}
+
+static inline void
+nilfs_terminate_segment(struct the_nilfs *nilfs, sector_t seg_start,
+ sector_t seg_end)
+{
+ /* terminate the current full segment (used in case of I/O-error) */
+ nilfs->ns_pseg_offset = seg_end - seg_start + 1;
+}
+
+static inline void nilfs_shift_to_next_segment(struct the_nilfs *nilfs)
+{
+ /* move forward with a full segment */
+ nilfs->ns_segnum = nilfs->ns_nextnum;
+ nilfs->ns_pseg_offset = 0;
+ nilfs->ns_seg_seq++;
+}
+
+static inline __u64 nilfs_last_cno(struct the_nilfs *nilfs)
+{
+ __u64 cno;
+
+ spin_lock(&nilfs->ns_last_segment_lock);
+ cno = nilfs->ns_last_cno;
+ spin_unlock(&nilfs->ns_last_segment_lock);
+ return cno;
+}
+
+static inline int nilfs_segment_is_active(struct the_nilfs *nilfs, __u64 n)
+{
+ return n == nilfs->ns_segnum || n == nilfs->ns_nextnum;
+}
+
+#endif /* _THE_NILFS_H */
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 19e3a96aa02..678a067d925 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -294,6 +294,55 @@ static struct ocfs2_extent_tree_operations ocfs2_xattr_tree_et_ops = {
.eo_fill_max_leaf_clusters = ocfs2_xattr_tree_fill_max_leaf_clusters,
};
+static void ocfs2_dx_root_set_last_eb_blk(struct ocfs2_extent_tree *et,
+ u64 blkno)
+{
+ struct ocfs2_dx_root_block *dx_root = et->et_object;
+
+ dx_root->dr_last_eb_blk = cpu_to_le64(blkno);
+}
+
+static u64 ocfs2_dx_root_get_last_eb_blk(struct ocfs2_extent_tree *et)
+{
+ struct ocfs2_dx_root_block *dx_root = et->et_object;
+
+ return le64_to_cpu(dx_root->dr_last_eb_blk);
+}
+
+static void ocfs2_dx_root_update_clusters(struct inode *inode,
+ struct ocfs2_extent_tree *et,
+ u32 clusters)
+{
+ struct ocfs2_dx_root_block *dx_root = et->et_object;
+
+ le32_add_cpu(&dx_root->dr_clusters, clusters);
+}
+
+static int ocfs2_dx_root_sanity_check(struct inode *inode,
+ struct ocfs2_extent_tree *et)
+{
+ struct ocfs2_dx_root_block *dx_root = et->et_object;
+
+ BUG_ON(!OCFS2_IS_VALID_DX_ROOT(dx_root));
+
+ return 0;
+}
+
+static void ocfs2_dx_root_fill_root_el(struct ocfs2_extent_tree *et)
+{
+ struct ocfs2_dx_root_block *dx_root = et->et_object;
+
+ et->et_root_el = &dx_root->dr_list;
+}
+
+static struct ocfs2_extent_tree_operations ocfs2_dx_root_et_ops = {
+ .eo_set_last_eb_blk = ocfs2_dx_root_set_last_eb_blk,
+ .eo_get_last_eb_blk = ocfs2_dx_root_get_last_eb_blk,
+ .eo_update_clusters = ocfs2_dx_root_update_clusters,
+ .eo_sanity_check = ocfs2_dx_root_sanity_check,
+ .eo_fill_root_el = ocfs2_dx_root_fill_root_el,
+};
+
static void __ocfs2_init_extent_tree(struct ocfs2_extent_tree *et,
struct inode *inode,
struct buffer_head *bh,
@@ -339,6 +388,14 @@ void ocfs2_init_xattr_value_extent_tree(struct ocfs2_extent_tree *et,
&ocfs2_xattr_value_et_ops);
}
+void ocfs2_init_dx_root_extent_tree(struct ocfs2_extent_tree *et,
+ struct inode *inode,
+ struct buffer_head *bh)
+{
+ __ocfs2_init_extent_tree(et, inode, bh, ocfs2_journal_access_dr,
+ NULL, &ocfs2_dx_root_et_ops);
+}
+
static inline void ocfs2_et_set_last_eb_blk(struct ocfs2_extent_tree *et,
u64 new_last_eb_blk)
{
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
index cceff5c37f4..353254ba29e 100644
--- a/fs/ocfs2/alloc.h
+++ b/fs/ocfs2/alloc.h
@@ -75,6 +75,9 @@ struct ocfs2_xattr_value_buf;
void ocfs2_init_xattr_value_extent_tree(struct ocfs2_extent_tree *et,
struct inode *inode,
struct ocfs2_xattr_value_buf *vb);
+void ocfs2_init_dx_root_extent_tree(struct ocfs2_extent_tree *et,
+ struct inode *inode,
+ struct buffer_head *bh);
/*
* Read an extent block into *bh. If *bh is NULL, a bh will be
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 8e1709a679b..b2c52b3a148 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1956,15 +1956,16 @@ static int ocfs2_write_end(struct file *file, struct address_space *mapping,
}
const struct address_space_operations ocfs2_aops = {
- .readpage = ocfs2_readpage,
- .readpages = ocfs2_readpages,
- .writepage = ocfs2_writepage,
- .write_begin = ocfs2_write_begin,
- .write_end = ocfs2_write_end,
- .bmap = ocfs2_bmap,
- .sync_page = block_sync_page,
- .direct_IO = ocfs2_direct_IO,
- .invalidatepage = ocfs2_invalidatepage,
- .releasepage = ocfs2_releasepage,
- .migratepage = buffer_migrate_page,
+ .readpage = ocfs2_readpage,
+ .readpages = ocfs2_readpages,
+ .writepage = ocfs2_writepage,
+ .write_begin = ocfs2_write_begin,
+ .write_end = ocfs2_write_end,
+ .bmap = ocfs2_bmap,
+ .sync_page = block_sync_page,
+ .direct_IO = ocfs2_direct_IO,
+ .invalidatepage = ocfs2_invalidatepage,
+ .releasepage = ocfs2_releasepage,
+ .migratepage = buffer_migrate_page,
+ .is_partially_uptodate = block_is_partially_uptodate,
};
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 04697ba7f73..4f85eceab37 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -33,6 +33,7 @@
#include <linux/random.h>
#include <linux/crc32.h>
#include <linux/time.h>
+#include <linux/debugfs.h>
#include "heartbeat.h"
#include "tcp.h"
@@ -60,6 +61,11 @@ static unsigned long o2hb_live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
static LIST_HEAD(o2hb_node_events);
static DECLARE_WAIT_QUEUE_HEAD(o2hb_steady_queue);
+#define O2HB_DEBUG_DIR "o2hb"
+#define O2HB_DEBUG_LIVENODES "livenodes"
+static struct dentry *o2hb_debug_dir;
+static struct dentry *o2hb_debug_livenodes;
+
static LIST_HEAD(o2hb_all_regions);
static struct o2hb_callback {
@@ -905,7 +911,77 @@ static int o2hb_thread(void *data)
return 0;
}
-void o2hb_init(void)
+#ifdef CONFIG_DEBUG_FS
+static int o2hb_debug_open(struct inode *inode, struct file *file)
+{
+ unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+ char *buf = NULL;
+ int i = -1;
+ int out = 0;
+
+ buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!buf)
+ goto bail;
+
+ o2hb_fill_node_map(map, sizeof(map));
+
+ while ((i = find_next_bit(map, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES)
+ out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i);
+ out += snprintf(buf + out, PAGE_SIZE - out, "\n");
+
+ i_size_write(inode, out);
+
+ file->private_data = buf;
+
+ return 0;
+bail:
+ return -ENOMEM;
+}
+
+static int o2hb_debug_release(struct inode *inode, struct file *file)
+{
+ kfree(file->private_data);
+ return 0;
+}
+
+static ssize_t o2hb_debug_read(struct file *file, char __user *buf,
+ size_t nbytes, loff_t *ppos)
+{
+ return simple_read_from_buffer(buf, nbytes, ppos, file->private_data,
+ i_size_read(file->f_mapping->host));
+}
+#else
+static int o2hb_debug_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+static int o2hb_debug_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+static ssize_t o2hb_debug_read(struct file *file, char __user *buf,
+ size_t nbytes, loff_t *ppos)
+{
+ return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static struct file_operations o2hb_debug_fops = {
+ .open = o2hb_debug_open,
+ .release = o2hb_debug_release,
+ .read = o2hb_debug_read,
+ .llseek = generic_file_llseek,
+};
+
+void o2hb_exit(void)
+{
+ if (o2hb_debug_livenodes)
+ debugfs_remove(o2hb_debug_livenodes);
+ if (o2hb_debug_dir)
+ debugfs_remove(o2hb_debug_dir);
+}
+
+int o2hb_init(void)
{
int i;
@@ -918,6 +994,24 @@ void o2hb_init(void)
INIT_LIST_HEAD(&o2hb_node_events);
memset(o2hb_live_node_bitmap, 0, sizeof(o2hb_live_node_bitmap));
+
+ o2hb_debug_dir = debugfs_create_dir(O2HB_DEBUG_DIR, NULL);
+ if (!o2hb_debug_dir) {
+ mlog_errno(-ENOMEM);
+ return -ENOMEM;
+ }
+
+ o2hb_debug_livenodes = debugfs_create_file(O2HB_DEBUG_LIVENODES,
+ S_IFREG|S_IRUSR,
+ o2hb_debug_dir, NULL,
+ &o2hb_debug_fops);
+ if (!o2hb_debug_livenodes) {
+ mlog_errno(-ENOMEM);
+ debugfs_remove(o2hb_debug_dir);
+ return -ENOMEM;
+ }
+
+ return 0;
}
/* if we're already in a callback then we're already serialized by the sem */
diff --git a/fs/ocfs2/cluster/heartbeat.h b/fs/ocfs2/cluster/heartbeat.h
index e511339886b..2f1649253b4 100644
--- a/fs/ocfs2/cluster/heartbeat.h
+++ b/fs/ocfs2/cluster/heartbeat.h
@@ -75,7 +75,8 @@ void o2hb_unregister_callback(const char *region_uuid,
struct o2hb_callback_func *hc);
void o2hb_fill_node_map(unsigned long *map,
unsigned bytes);
-void o2hb_init(void);
+void o2hb_exit(void);
+int o2hb_init(void);
int o2hb_check_node_heartbeating(u8 node_num);
int o2hb_check_node_heartbeating_from_callback(u8 node_num);
int o2hb_check_local_node_heartbeating(void);
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c
index 70e8fa9e253..7ee6188bc79 100644
--- a/fs/ocfs2/cluster/nodemanager.c
+++ b/fs/ocfs2/cluster/nodemanager.c
@@ -881,6 +881,7 @@ static void __exit exit_o2nm(void)
o2cb_sys_shutdown();
o2net_exit();
+ o2hb_exit();
}
static int __init init_o2nm(void)
@@ -889,11 +890,13 @@ static int __init init_o2nm(void)
cluster_print_version();
- o2hb_init();
+ ret = o2hb_init();
+ if (ret)
+ goto out;
ret = o2net_init();
if (ret)
- goto out;
+ goto out_o2hb;
ret = o2net_register_hb_callbacks();
if (ret)
@@ -916,6 +919,8 @@ out_callbacks:
o2net_unregister_hb_callbacks();
out_o2net:
o2net_exit();
+out_o2hb:
+ o2hb_exit();
out:
return ret;
}
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index f2c4098cf33..e71160cda11 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -41,6 +41,7 @@
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/quotaops.h>
+#include <linux/sort.h>
#define MLOG_MASK_PREFIX ML_NAMEI
#include <cluster/masklog.h>
@@ -58,6 +59,7 @@
#include "namei.h"
#include "suballoc.h"
#include "super.h"
+#include "sysfile.h"
#include "uptodate.h"
#include "buffer_head_io.h"
@@ -71,11 +73,6 @@ static unsigned char ocfs2_filetype_table[] = {
DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
};
-static int ocfs2_extend_dir(struct ocfs2_super *osb,
- struct inode *dir,
- struct buffer_head *parent_fe_bh,
- unsigned int blocks_wanted,
- struct buffer_head **new_de_bh);
static int ocfs2_do_extend_dir(struct super_block *sb,
handle_t *handle,
struct inode *dir,
@@ -83,22 +80,36 @@ static int ocfs2_do_extend_dir(struct super_block *sb,
struct ocfs2_alloc_context *data_ac,
struct ocfs2_alloc_context *meta_ac,
struct buffer_head **new_bh);
+static int ocfs2_dir_indexed(struct inode *inode);
/*
* These are distinct checks because future versions of the file system will
* want to have a trailing dirent structure independent of indexing.
*/
-static int ocfs2_dir_has_trailer(struct inode *dir)
+static int ocfs2_supports_dir_trailer(struct inode *dir)
{
+ struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+
if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
return 0;
- return ocfs2_meta_ecc(OCFS2_SB(dir->i_sb));
+ return ocfs2_meta_ecc(osb) || ocfs2_dir_indexed(dir);
}
-static int ocfs2_supports_dir_trailer(struct ocfs2_super *osb)
+/*
+ * "new' here refers to the point at which we're creating a new
+ * directory via "mkdir()", but also when we're expanding an inline
+ * directory. In either case, we don't yet have the indexing bit set
+ * on the directory, so the standard checks will fail in when metaecc
+ * is turned off. Only directory-initialization type functions should
+ * use this then. Everything else wants ocfs2_supports_dir_trailer()
+ */
+static int ocfs2_new_dir_wants_trailer(struct inode *dir)
{
- return ocfs2_meta_ecc(osb);
+ struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+
+ return ocfs2_meta_ecc(osb) ||
+ ocfs2_supports_indexed_dirs(osb);
}
static inline unsigned int ocfs2_dir_trailer_blk_off(struct super_block *sb)
@@ -130,7 +141,7 @@ static int ocfs2_skip_dir_trailer(struct inode *dir,
{
unsigned long toff = blklen - sizeof(struct ocfs2_dir_block_trailer);
- if (!ocfs2_dir_has_trailer(dir))
+ if (!ocfs2_supports_dir_trailer(dir))
return 0;
if (offset != toff)
@@ -140,7 +151,7 @@ static int ocfs2_skip_dir_trailer(struct inode *dir,
}
static void ocfs2_init_dir_trailer(struct inode *inode,
- struct buffer_head *bh)
+ struct buffer_head *bh, u16 rec_len)
{
struct ocfs2_dir_block_trailer *trailer;
@@ -150,6 +161,153 @@ static void ocfs2_init_dir_trailer(struct inode *inode,
cpu_to_le16(sizeof(struct ocfs2_dir_block_trailer));
trailer->db_parent_dinode = cpu_to_le64(OCFS2_I(inode)->ip_blkno);
trailer->db_blkno = cpu_to_le64(bh->b_blocknr);
+ trailer->db_free_rec_len = cpu_to_le16(rec_len);
+}
+/*
+ * Link an unindexed block with a dir trailer structure into the index free
+ * list. This function will modify dirdata_bh, but assumes you've already
+ * passed it to the journal.
+ */
+static int ocfs2_dx_dir_link_trailer(struct inode *dir, handle_t *handle,
+ struct buffer_head *dx_root_bh,
+ struct buffer_head *dirdata_bh)
+{
+ int ret;
+ struct ocfs2_dx_root_block *dx_root;
+ struct ocfs2_dir_block_trailer *trailer;
+
+ ret = ocfs2_journal_access_dr(handle, dir, dx_root_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+ trailer = ocfs2_trailer_from_bh(dirdata_bh, dir->i_sb);
+ dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+
+ trailer->db_free_next = dx_root->dr_free_blk;
+ dx_root->dr_free_blk = cpu_to_le64(dirdata_bh->b_blocknr);
+
+ ocfs2_journal_dirty(handle, dx_root_bh);
+
+out:
+ return ret;
+}
+
+static int ocfs2_free_list_at_root(struct ocfs2_dir_lookup_result *res)
+{
+ return res->dl_prev_leaf_bh == NULL;
+}
+
+void ocfs2_free_dir_lookup_result(struct ocfs2_dir_lookup_result *res)
+{
+ brelse(res->dl_dx_root_bh);
+ brelse(res->dl_leaf_bh);
+ brelse(res->dl_dx_leaf_bh);
+ brelse(res->dl_prev_leaf_bh);
+}
+
+static int ocfs2_dir_indexed(struct inode *inode)
+{
+ if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INDEXED_DIR_FL)
+ return 1;
+ return 0;
+}
+
+static inline int ocfs2_dx_root_inline(struct ocfs2_dx_root_block *dx_root)
+{
+ return dx_root->dr_flags & OCFS2_DX_FLAG_INLINE;
+}
+
+/*
+ * Hashing code adapted from ext3
+ */
+#define DELTA 0x9E3779B9
+
+static void TEA_transform(__u32 buf[4], __u32 const in[])
+{
+ __u32 sum = 0;
+ __u32 b0 = buf[0], b1 = buf[1];
+ __u32 a = in[0], b = in[1], c = in[2], d = in[3];
+ int n = 16;
+
+ do {
+ sum += DELTA;
+ b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
+ b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
+ } while (--n);
+
+ buf[0] += b0;
+ buf[1] += b1;
+}
+
+static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
+{
+ __u32 pad, val;
+ int i;
+
+ pad = (__u32)len | ((__u32)len << 8);
+ pad |= pad << 16;
+
+ val = pad;
+ if (len > num*4)
+ len = num * 4;
+ for (i = 0; i < len; i++) {
+ if ((i % 4) == 0)
+ val = pad;
+ val = msg[i] + (val << 8);
+ if ((i % 4) == 3) {
+ *buf++ = val;
+ val = pad;
+ num--;
+ }
+ }
+ if (--num >= 0)
+ *buf++ = val;
+ while (--num >= 0)
+ *buf++ = pad;
+}
+
+static void ocfs2_dx_dir_name_hash(struct inode *dir, const char *name, int len,
+ struct ocfs2_dx_hinfo *hinfo)
+{
+ struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+ const char *p;
+ __u32 in[8], buf[4];
+
+ /*
+ * XXX: Is this really necessary, if the index is never looked
+ * at by readdir? Is a hash value of '0' a bad idea?
+ */
+ if ((len == 1 && !strncmp(".", name, 1)) ||
+ (len == 2 && !strncmp("..", name, 2))) {
+ buf[0] = buf[1] = 0;
+ goto out;
+ }
+
+#ifdef OCFS2_DEBUG_DX_DIRS
+ /*
+ * This makes it very easy to debug indexing problems. We
+ * should never allow this to be selected without hand editing
+ * this file though.
+ */
+ buf[0] = buf[1] = len;
+ goto out;
+#endif
+
+ memcpy(buf, osb->osb_dx_seed, sizeof(buf));
+
+ p = name;
+ while (len > 0) {
+ str2hashbuf(p, len, in, 4);
+ TEA_transform(buf, in);
+ len -= 16;
+ p += 16;
+ }
+
+out:
+ hinfo->major_hash = buf[0];
+ hinfo->minor_hash = buf[1];
}
/*
@@ -312,6 +470,52 @@ static int ocfs2_validate_dir_block(struct super_block *sb,
}
/*
+ * Validate a directory trailer.
+ *
+ * We check the trailer here rather than in ocfs2_validate_dir_block()
+ * because that function doesn't have the inode to test.
+ */
+static int ocfs2_check_dir_trailer(struct inode *dir, struct buffer_head *bh)
+{
+ int rc = 0;
+ struct ocfs2_dir_block_trailer *trailer;
+
+ trailer = ocfs2_trailer_from_bh(bh, dir->i_sb);
+ if (!OCFS2_IS_VALID_DIR_TRAILER(trailer)) {
+ rc = -EINVAL;
+ ocfs2_error(dir->i_sb,
+ "Invalid dirblock #%llu: "
+ "signature = %.*s\n",
+ (unsigned long long)bh->b_blocknr, 7,
+ trailer->db_signature);
+ goto out;
+ }
+ if (le64_to_cpu(trailer->db_blkno) != bh->b_blocknr) {
+ rc = -EINVAL;
+ ocfs2_error(dir->i_sb,
+ "Directory block #%llu has an invalid "
+ "db_blkno of %llu",
+ (unsigned long long)bh->b_blocknr,
+ (unsigned long long)le64_to_cpu(trailer->db_blkno));
+ goto out;
+ }
+ if (le64_to_cpu(trailer->db_parent_dinode) !=
+ OCFS2_I(dir)->ip_blkno) {
+ rc = -EINVAL;
+ ocfs2_error(dir->i_sb,
+ "Directory block #%llu on dinode "
+ "#%llu has an invalid parent_dinode "
+ "of %llu",
+ (unsigned long long)bh->b_blocknr,
+ (unsigned long long)OCFS2_I(dir)->ip_blkno,
+ (unsigned long long)le64_to_cpu(trailer->db_blkno));
+ goto out;
+ }
+out:
+ return rc;
+}
+
+/*
* This function forces all errors to -EIO for consistency with its
* predecessor, ocfs2_bread(). We haven't audited what returning the
* real error codes would do to callers. We log the real codes with
@@ -322,7 +526,6 @@ static int ocfs2_read_dir_block(struct inode *inode, u64 v_block,
{
int rc = 0;
struct buffer_head *tmp = *bh;
- struct ocfs2_dir_block_trailer *trailer;
rc = ocfs2_read_virt_blocks(inode, v_block, 1, &tmp, flags,
ocfs2_validate_dir_block);
@@ -331,42 +534,13 @@ static int ocfs2_read_dir_block(struct inode *inode, u64 v_block,
goto out;
}
- /*
- * We check the trailer here rather than in
- * ocfs2_validate_dir_block() because that function doesn't have
- * the inode to test.
- */
if (!(flags & OCFS2_BH_READAHEAD) &&
- ocfs2_dir_has_trailer(inode)) {
- trailer = ocfs2_trailer_from_bh(tmp, inode->i_sb);
- if (!OCFS2_IS_VALID_DIR_TRAILER(trailer)) {
- rc = -EINVAL;
- ocfs2_error(inode->i_sb,
- "Invalid dirblock #%llu: "
- "signature = %.*s\n",
- (unsigned long long)tmp->b_blocknr, 7,
- trailer->db_signature);
- goto out;
- }
- if (le64_to_cpu(trailer->db_blkno) != tmp->b_blocknr) {
- rc = -EINVAL;
- ocfs2_error(inode->i_sb,
- "Directory block #%llu has an invalid "
- "db_blkno of %llu",
- (unsigned long long)tmp->b_blocknr,
- (unsigned long long)le64_to_cpu(trailer->db_blkno));
- goto out;
- }
- if (le64_to_cpu(trailer->db_parent_dinode) !=
- OCFS2_I(inode)->ip_blkno) {
- rc = -EINVAL;
- ocfs2_error(inode->i_sb,
- "Directory block #%llu on dinode "
- "#%llu has an invalid parent_dinode "
- "of %llu",
- (unsigned long long)tmp->b_blocknr,
- (unsigned long long)OCFS2_I(inode)->ip_blkno,
- (unsigned long long)le64_to_cpu(trailer->db_blkno));
+ ocfs2_supports_dir_trailer(inode)) {
+ rc = ocfs2_check_dir_trailer(inode, tmp);
+ if (rc) {
+ if (!*bh)
+ brelse(tmp);
+ mlog_errno(rc);
goto out;
}
}
@@ -379,6 +553,141 @@ out:
return rc ? -EIO : 0;
}
+/*
+ * Read the block at 'phys' which belongs to this directory
+ * inode. This function does no virtual->physical block translation -
+ * what's passed in is assumed to be a valid directory block.
+ */
+static int ocfs2_read_dir_block_direct(struct inode *dir, u64 phys,
+ struct buffer_head **bh)
+{
+ int ret;
+ struct buffer_head *tmp = *bh;
+
+ ret = ocfs2_read_block(dir, phys, &tmp, ocfs2_validate_dir_block);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ if (ocfs2_supports_dir_trailer(dir)) {
+ ret = ocfs2_check_dir_trailer(dir, tmp);
+ if (ret) {
+ if (!*bh)
+ brelse(tmp);
+ mlog_errno(ret);
+ goto out;
+ }
+ }
+
+ if (!ret && !*bh)
+ *bh = tmp;
+out:
+ return ret;
+}
+
+static int ocfs2_validate_dx_root(struct super_block *sb,
+ struct buffer_head *bh)
+{
+ int ret;
+ struct ocfs2_dx_root_block *dx_root;
+
+ BUG_ON(!buffer_uptodate(bh));
+
+ dx_root = (struct ocfs2_dx_root_block *) bh->b_data;
+
+ ret = ocfs2_validate_meta_ecc(sb, bh->b_data, &dx_root->dr_check);
+ if (ret) {
+ mlog(ML_ERROR,
+ "Checksum failed for dir index root block %llu\n",
+ (unsigned long long)bh->b_blocknr);
+ return ret;
+ }
+
+ if (!OCFS2_IS_VALID_DX_ROOT(dx_root)) {
+ ocfs2_error(sb,
+ "Dir Index Root # %llu has bad signature %.*s",
+ (unsigned long long)le64_to_cpu(dx_root->dr_blkno),
+ 7, dx_root->dr_signature);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ocfs2_read_dx_root(struct inode *dir, struct ocfs2_dinode *di,
+ struct buffer_head **dx_root_bh)
+{
+ int ret;
+ u64 blkno = le64_to_cpu(di->i_dx_root);
+ struct buffer_head *tmp = *dx_root_bh;
+
+ ret = ocfs2_read_block(dir, blkno, &tmp, ocfs2_validate_dx_root);
+
+ /* If ocfs2_read_block() got us a new bh, pass it up. */
+ if (!ret && !*dx_root_bh)
+ *dx_root_bh = tmp;
+
+ return ret;
+}
+
+static int ocfs2_validate_dx_leaf(struct super_block *sb,
+ struct buffer_head *bh)
+{
+ int ret;
+ struct ocfs2_dx_leaf *dx_leaf = (struct ocfs2_dx_leaf *)bh->b_data;
+
+ BUG_ON(!buffer_uptodate(bh));
+
+ ret = ocfs2_validate_meta_ecc(sb, bh->b_data, &dx_leaf->dl_check);
+ if (ret) {
+ mlog(ML_ERROR,
+ "Checksum failed for dir index leaf block %llu\n",
+ (unsigned long long)bh->b_blocknr);
+ return ret;
+ }
+
+ if (!OCFS2_IS_VALID_DX_LEAF(dx_leaf)) {
+ ocfs2_error(sb, "Dir Index Leaf has bad signature %.*s",
+ 7, dx_leaf->dl_signature);
+ return -EROFS;
+ }
+
+ return 0;
+}
+
+static int ocfs2_read_dx_leaf(struct inode *dir, u64 blkno,
+ struct buffer_head **dx_leaf_bh)
+{
+ int ret;
+ struct buffer_head *tmp = *dx_leaf_bh;
+
+ ret = ocfs2_read_block(dir, blkno, &tmp, ocfs2_validate_dx_leaf);
+
+ /* If ocfs2_read_block() got us a new bh, pass it up. */
+ if (!ret && !*dx_leaf_bh)
+ *dx_leaf_bh = tmp;
+
+ return ret;
+}
+
+/*
+ * Read a series of dx_leaf blocks. This expects all buffer_head
+ * pointers to be NULL on function entry.
+ */
+static int ocfs2_read_dx_leaves(struct inode *dir, u64 start, int num,
+ struct buffer_head **dx_leaf_bhs)
+{
+ int ret;
+
+ ret = ocfs2_read_blocks(dir, start, num, dx_leaf_bhs, 0,
+ ocfs2_validate_dx_leaf);
+ if (ret)
+ mlog_errno(ret);
+
+ return ret;
+}
+
static struct buffer_head *ocfs2_find_entry_el(const char *name, int namelen,
struct inode *dir,
struct ocfs2_dir_entry **res_dir)
@@ -480,39 +789,340 @@ cleanup_and_exit:
return ret;
}
+static int ocfs2_dx_dir_lookup_rec(struct inode *inode,
+ struct ocfs2_extent_list *el,
+ u32 major_hash,
+ u32 *ret_cpos,
+ u64 *ret_phys_blkno,
+ unsigned int *ret_clen)
+{
+ int ret = 0, i, found;
+ struct buffer_head *eb_bh = NULL;
+ struct ocfs2_extent_block *eb;
+ struct ocfs2_extent_rec *rec = NULL;
+
+ if (el->l_tree_depth) {
+ ret = ocfs2_find_leaf(inode, el, major_hash, &eb_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ eb = (struct ocfs2_extent_block *) eb_bh->b_data;
+ el = &eb->h_list;
+
+ if (el->l_tree_depth) {
+ ocfs2_error(inode->i_sb,
+ "Inode %lu has non zero tree depth in "
+ "btree tree block %llu\n", inode->i_ino,
+ (unsigned long long)eb_bh->b_blocknr);
+ ret = -EROFS;
+ goto out;
+ }
+ }
+
+ found = 0;
+ for (i = le16_to_cpu(el->l_next_free_rec) - 1; i >= 0; i--) {
+ rec = &el->l_recs[i];
+
+ if (le32_to_cpu(rec->e_cpos) <= major_hash) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ ocfs2_error(inode->i_sb, "Inode %lu has bad extent "
+ "record (%u, %u, 0) in btree", inode->i_ino,
+ le32_to_cpu(rec->e_cpos),
+ ocfs2_rec_clusters(el, rec));
+ ret = -EROFS;
+ goto out;
+ }
+
+ if (ret_phys_blkno)
+ *ret_phys_blkno = le64_to_cpu(rec->e_blkno);
+ if (ret_cpos)
+ *ret_cpos = le32_to_cpu(rec->e_cpos);
+ if (ret_clen)
+ *ret_clen = le16_to_cpu(rec->e_leaf_clusters);
+
+out:
+ brelse(eb_bh);
+ return ret;
+}
+
+/*
+ * Returns the block index, from the start of the cluster which this
+ * hash belongs too.
+ */
+static inline unsigned int __ocfs2_dx_dir_hash_idx(struct ocfs2_super *osb,
+ u32 minor_hash)
+{
+ return minor_hash & osb->osb_dx_mask;
+}
+
+static inline unsigned int ocfs2_dx_dir_hash_idx(struct ocfs2_super *osb,
+ struct ocfs2_dx_hinfo *hinfo)
+{
+ return __ocfs2_dx_dir_hash_idx(osb, hinfo->minor_hash);
+}
+
+static int ocfs2_dx_dir_lookup(struct inode *inode,
+ struct ocfs2_extent_list *el,
+ struct ocfs2_dx_hinfo *hinfo,
+ u32 *ret_cpos,
+ u64 *ret_phys_blkno)
+{
+ int ret = 0;
+ unsigned int cend, uninitialized_var(clen);
+ u32 uninitialized_var(cpos);
+ u64 uninitialized_var(blkno);
+ u32 name_hash = hinfo->major_hash;
+
+ ret = ocfs2_dx_dir_lookup_rec(inode, el, name_hash, &cpos, &blkno,
+ &clen);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ cend = cpos + clen;
+ if (name_hash >= cend) {
+ /* We want the last cluster */
+ blkno += ocfs2_clusters_to_blocks(inode->i_sb, clen - 1);
+ cpos += clen - 1;
+ } else {
+ blkno += ocfs2_clusters_to_blocks(inode->i_sb,
+ name_hash - cpos);
+ cpos = name_hash;
+ }
+
+ /*
+ * We now have the cluster which should hold our entry. To
+ * find the exact block from the start of the cluster to
+ * search, we take the lower bits of the hash.
+ */
+ blkno += ocfs2_dx_dir_hash_idx(OCFS2_SB(inode->i_sb), hinfo);
+
+ if (ret_phys_blkno)
+ *ret_phys_blkno = blkno;
+ if (ret_cpos)
+ *ret_cpos = cpos;
+
+out:
+
+ return ret;
+}
+
+static int ocfs2_dx_dir_search(const char *name, int namelen,
+ struct inode *dir,
+ struct ocfs2_dx_root_block *dx_root,
+ struct ocfs2_dir_lookup_result *res)
+{
+ int ret, i, found;
+ u64 uninitialized_var(phys);
+ struct buffer_head *dx_leaf_bh = NULL;
+ struct ocfs2_dx_leaf *dx_leaf;
+ struct ocfs2_dx_entry *dx_entry = NULL;
+ struct buffer_head *dir_ent_bh = NULL;
+ struct ocfs2_dir_entry *dir_ent = NULL;
+ struct ocfs2_dx_hinfo *hinfo = &res->dl_hinfo;
+ struct ocfs2_extent_list *dr_el;
+ struct ocfs2_dx_entry_list *entry_list;
+
+ ocfs2_dx_dir_name_hash(dir, name, namelen, &res->dl_hinfo);
+
+ if (ocfs2_dx_root_inline(dx_root)) {
+ entry_list = &dx_root->dr_entries;
+ goto search;
+ }
+
+ dr_el = &dx_root->dr_list;
+
+ ret = ocfs2_dx_dir_lookup(dir, dr_el, hinfo, NULL, &phys);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ mlog(0, "Dir %llu: name: \"%.*s\", lookup of hash: %u.0x%x "
+ "returns: %llu\n",
+ (unsigned long long)OCFS2_I(dir)->ip_blkno,
+ namelen, name, hinfo->major_hash, hinfo->minor_hash,
+ (unsigned long long)phys);
+
+ ret = ocfs2_read_dx_leaf(dir, phys, &dx_leaf_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ dx_leaf = (struct ocfs2_dx_leaf *) dx_leaf_bh->b_data;
+
+ mlog(0, "leaf info: num_used: %d, count: %d\n",
+ le16_to_cpu(dx_leaf->dl_list.de_num_used),
+ le16_to_cpu(dx_leaf->dl_list.de_count));
+
+ entry_list = &dx_leaf->dl_list;
+
+search:
+ /*
+ * Empty leaf is legal, so no need to check for that.
+ */
+ found = 0;
+ for (i = 0; i < le16_to_cpu(entry_list->de_num_used); i++) {
+ dx_entry = &entry_list->de_entries[i];
+
+ if (hinfo->major_hash != le32_to_cpu(dx_entry->dx_major_hash)
+ || hinfo->minor_hash != le32_to_cpu(dx_entry->dx_minor_hash))
+ continue;
+
+ /*
+ * Search unindexed leaf block now. We're not
+ * guaranteed to find anything.
+ */
+ ret = ocfs2_read_dir_block_direct(dir,
+ le64_to_cpu(dx_entry->dx_dirent_blk),
+ &dir_ent_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ /*
+ * XXX: We should check the unindexed block here,
+ * before using it.
+ */
+
+ found = ocfs2_search_dirblock(dir_ent_bh, dir, name, namelen,
+ 0, dir_ent_bh->b_data,
+ dir->i_sb->s_blocksize, &dir_ent);
+ if (found == 1)
+ break;
+
+ if (found == -1) {
+ /* This means we found a bad directory entry. */
+ ret = -EIO;
+ mlog_errno(ret);
+ goto out;
+ }
+
+ brelse(dir_ent_bh);
+ dir_ent_bh = NULL;
+ }
+
+ if (found <= 0) {
+ ret = -ENOENT;
+ goto out;
+ }
+
+ res->dl_leaf_bh = dir_ent_bh;
+ res->dl_entry = dir_ent;
+ res->dl_dx_leaf_bh = dx_leaf_bh;
+ res->dl_dx_entry = dx_entry;
+
+ ret = 0;
+out:
+ if (ret) {
+ brelse(dx_leaf_bh);
+ brelse(dir_ent_bh);
+ }
+ return ret;
+}
+
+static int ocfs2_find_entry_dx(const char *name, int namelen,
+ struct inode *dir,
+ struct ocfs2_dir_lookup_result *lookup)
+{
+ int ret;
+ struct buffer_head *di_bh = NULL;
+ struct ocfs2_dinode *di;
+ struct buffer_head *dx_root_bh = NULL;
+ struct ocfs2_dx_root_block *dx_root;
+
+ ret = ocfs2_read_inode_block(dir, &di_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ di = (struct ocfs2_dinode *)di_bh->b_data;
+
+ ret = ocfs2_read_dx_root(dir, di, &dx_root_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+ dx_root = (struct ocfs2_dx_root_block *) dx_root_bh->b_data;
+
+ ret = ocfs2_dx_dir_search(name, namelen, dir, dx_root, lookup);
+ if (ret) {
+ if (ret != -ENOENT)
+ mlog_errno(ret);
+ goto out;
+ }
+
+ lookup->dl_dx_root_bh = dx_root_bh;
+ dx_root_bh = NULL;
+out:
+ brelse(di_bh);
+ brelse(dx_root_bh);
+ return ret;
+}
+
/*
* Try to find an entry of the provided name within 'dir'.
*
- * If nothing was found, NULL is returned. Otherwise, a buffer_head
- * and pointer to the dir entry are passed back.
+ * If nothing was found, -ENOENT is returned. Otherwise, zero is
+ * returned and the struct 'res' will contain information useful to
+ * other directory manipulation functions.
*
* Caller can NOT assume anything about the contents of the
- * buffer_head - it is passed back only so that it can be passed into
- * any one of the manipulation functions (add entry, delete entry,
- * etc). As an example, bh in the extent directory case is a data
- * block, in the inline-data case it actually points to an inode.
+ * buffer_heads - they are passed back only so that it can be passed
+ * into any one of the manipulation functions (add entry, delete
+ * entry, etc). As an example, bh in the extent directory case is a
+ * data block, in the inline-data case it actually points to an inode,
+ * in the indexed directory case, multiple buffers are involved.
*/
-struct buffer_head *ocfs2_find_entry(const char *name, int namelen,
- struct inode *dir,
- struct ocfs2_dir_entry **res_dir)
+int ocfs2_find_entry(const char *name, int namelen,
+ struct inode *dir, struct ocfs2_dir_lookup_result *lookup)
{
- *res_dir = NULL;
+ struct buffer_head *bh;
+ struct ocfs2_dir_entry *res_dir = NULL;
+ if (ocfs2_dir_indexed(dir))
+ return ocfs2_find_entry_dx(name, namelen, dir, lookup);
+
+ /*
+ * The unindexed dir code only uses part of the lookup
+ * structure, so there's no reason to push it down further
+ * than this.
+ */
if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
- return ocfs2_find_entry_id(name, namelen, dir, res_dir);
+ bh = ocfs2_find_entry_id(name, namelen, dir, &res_dir);
+ else
+ bh = ocfs2_find_entry_el(name, namelen, dir, &res_dir);
+
+ if (bh == NULL)
+ return -ENOENT;
- return ocfs2_find_entry_el(name, namelen, dir, res_dir);
+ lookup->dl_leaf_bh = bh;
+ lookup->dl_entry = res_dir;
+ return 0;
}
/*
* Update inode number and type of a previously found directory entry.
*/
int ocfs2_update_entry(struct inode *dir, handle_t *handle,
- struct buffer_head *de_bh, struct ocfs2_dir_entry *de,
+ struct ocfs2_dir_lookup_result *res,
struct inode *new_entry_inode)
{
int ret;
ocfs2_journal_access_func access = ocfs2_journal_access_db;
+ struct ocfs2_dir_entry *de = res->dl_entry;
+ struct buffer_head *de_bh = res->dl_leaf_bh;
/*
* The same code works fine for both inline-data and extent
@@ -538,6 +1148,10 @@ out:
return ret;
}
+/*
+ * __ocfs2_delete_entry deletes a directory entry by merging it with the
+ * previous entry
+ */
static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir,
struct ocfs2_dir_entry *de_del,
struct buffer_head *bh, char *first_de,
@@ -587,6 +1201,181 @@ bail:
return status;
}
+static unsigned int ocfs2_figure_dirent_hole(struct ocfs2_dir_entry *de)
+{
+ unsigned int hole;
+
+ if (le64_to_cpu(de->inode) == 0)
+ hole = le16_to_cpu(de->rec_len);
+ else
+ hole = le16_to_cpu(de->rec_len) -
+ OCFS2_DIR_REC_LEN(de->name_len);
+
+ return hole;
+}
+
+static int ocfs2_find_max_rec_len(struct super_block *sb,
+ struct buffer_head *dirblock_bh)
+{
+ int size, this_hole, largest_hole = 0;
+ char *trailer, *de_buf, *limit, *start = dirblock_bh->b_data;
+ struct ocfs2_dir_entry *de;
+
+ trailer = (char *)ocfs2_trailer_from_bh(dirblock_bh, sb);
+ size = ocfs2_dir_trailer_blk_off(sb);
+ limit = start + size;
+ de_buf = start;
+ de = (struct ocfs2_dir_entry *)de_buf;
+ do {
+ if (de_buf != trailer) {
+ this_hole = ocfs2_figure_dirent_hole(de);
+ if (this_hole > largest_hole)
+ largest_hole = this_hole;
+ }
+
+ de_buf += le16_to_cpu(de->rec_len);
+ de = (struct ocfs2_dir_entry *)de_buf;
+ } while (de_buf < limit);
+
+ if (largest_hole >= OCFS2_DIR_MIN_REC_LEN)
+ return largest_hole;
+ return 0;
+}
+
+static void ocfs2_dx_list_remove_entry(struct ocfs2_dx_entry_list *entry_list,
+ int index)
+{
+ int num_used = le16_to_cpu(entry_list->de_num_used);
+
+ if (num_used == 1 || index == (num_used - 1))
+ goto clear;
+
+ memmove(&entry_list->de_entries[index],
+ &entry_list->de_entries[index + 1],
+ (num_used - index - 1)*sizeof(struct ocfs2_dx_entry));
+clear:
+ num_used--;
+ memset(&entry_list->de_entries[num_used], 0,
+ sizeof(struct ocfs2_dx_entry));
+ entry_list->de_num_used = cpu_to_le16(num_used);
+}
+
+static int ocfs2_delete_entry_dx(handle_t *handle, struct inode *dir,
+ struct ocfs2_dir_lookup_result *lookup)
+{
+ int ret, index, max_rec_len, add_to_free_list = 0;
+ struct buffer_head *dx_root_bh = lookup->dl_dx_root_bh;
+ struct buffer_head *leaf_bh = lookup->dl_leaf_bh;
+ struct ocfs2_dx_leaf *dx_leaf;
+ struct ocfs2_dx_entry *dx_entry = lookup->dl_dx_entry;
+ struct ocfs2_dir_block_trailer *trailer;
+ struct ocfs2_dx_root_block *dx_root;
+ struct ocfs2_dx_entry_list *entry_list;
+
+ /*
+ * This function gets a bit messy because we might have to
+ * modify the root block, regardless of whether the indexed
+ * entries are stored inline.
+ */
+
+ /*
+ * *Only* set 'entry_list' here, based on where we're looking
+ * for the indexed entries. Later, we might still want to
+ * journal both blocks, based on free list state.
+ */
+ dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+ if (ocfs2_dx_root_inline(dx_root)) {
+ entry_list = &dx_root->dr_entries;
+ } else {
+ dx_leaf = (struct ocfs2_dx_leaf *) lookup->dl_dx_leaf_bh->b_data;
+ entry_list = &dx_leaf->dl_list;
+ }
+
+ /* Neither of these are a disk corruption - that should have
+ * been caught by lookup, before we got here. */
+ BUG_ON(le16_to_cpu(entry_list->de_count) <= 0);
+ BUG_ON(le16_to_cpu(entry_list->de_num_used) <= 0);
+
+ index = (char *)dx_entry - (char *)entry_list->de_entries;
+ index /= sizeof(*dx_entry);
+
+ if (index >= le16_to_cpu(entry_list->de_num_used)) {
+ mlog(ML_ERROR, "Dir %llu: Bad dx_entry ptr idx %d, (%p, %p)\n",
+ (unsigned long long)OCFS2_I(dir)->ip_blkno, index,
+ entry_list, dx_entry);
+ return -EIO;
+ }
+
+ /*
+ * We know that removal of this dirent will leave enough room
+ * for a new one, so add this block to the free list if it
+ * isn't already there.
+ */
+ trailer = ocfs2_trailer_from_bh(leaf_bh, dir->i_sb);
+ if (trailer->db_free_rec_len == 0)
+ add_to_free_list = 1;
+
+ /*
+ * Add the block holding our index into the journal before
+ * removing the unindexed entry. If we get an error return
+ * from __ocfs2_delete_entry(), then it hasn't removed the
+ * entry yet. Likewise, successful return means we *must*
+ * remove the indexed entry.
+ *
+ * We're also careful to journal the root tree block here as
+ * the entry count needs to be updated. Also, we might be
+ * adding to the start of the free list.
+ */
+ ret = ocfs2_journal_access_dr(handle, dir, dx_root_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ if (!ocfs2_dx_root_inline(dx_root)) {
+ ret = ocfs2_journal_access_dl(handle, dir,
+ lookup->dl_dx_leaf_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+ }
+
+ mlog(0, "Dir %llu: delete entry at index: %d\n",
+ (unsigned long long)OCFS2_I(dir)->ip_blkno, index);
+
+ ret = __ocfs2_delete_entry(handle, dir, lookup->dl_entry,
+ leaf_bh, leaf_bh->b_data, leaf_bh->b_size);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ max_rec_len = ocfs2_find_max_rec_len(dir->i_sb, leaf_bh);
+ trailer->db_free_rec_len = cpu_to_le16(max_rec_len);
+ if (add_to_free_list) {
+ trailer->db_free_next = dx_root->dr_free_blk;
+ dx_root->dr_free_blk = cpu_to_le64(leaf_bh->b_blocknr);
+ ocfs2_journal_dirty(handle, dx_root_bh);
+ }
+
+ /* leaf_bh was journal_accessed for us in __ocfs2_delete_entry */
+ ocfs2_journal_dirty(handle, leaf_bh);
+
+ le32_add_cpu(&dx_root->dr_num_entries, -1);
+ ocfs2_journal_dirty(handle, dx_root_bh);
+
+ ocfs2_dx_list_remove_entry(entry_list, index);
+
+ if (!ocfs2_dx_root_inline(dx_root))
+ ocfs2_journal_dirty(handle, lookup->dl_dx_leaf_bh);
+
+out:
+ return ret;
+}
+
static inline int ocfs2_delete_entry_id(handle_t *handle,
struct inode *dir,
struct ocfs2_dir_entry *de_del,
@@ -624,18 +1413,22 @@ static inline int ocfs2_delete_entry_el(handle_t *handle,
}
/*
- * ocfs2_delete_entry deletes a directory entry by merging it with the
- * previous entry
+ * Delete a directory entry. Hide the details of directory
+ * implementation from the caller.
*/
int ocfs2_delete_entry(handle_t *handle,
struct inode *dir,
- struct ocfs2_dir_entry *de_del,
- struct buffer_head *bh)
+ struct ocfs2_dir_lookup_result *res)
{
+ if (ocfs2_dir_indexed(dir))
+ return ocfs2_delete_entry_dx(handle, dir, res);
+
if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
- return ocfs2_delete_entry_id(handle, dir, de_del, bh);
+ return ocfs2_delete_entry_id(handle, dir, res->dl_entry,
+ res->dl_leaf_bh);
- return ocfs2_delete_entry_el(handle, dir, de_del, bh);
+ return ocfs2_delete_entry_el(handle, dir, res->dl_entry,
+ res->dl_leaf_bh);
}
/*
@@ -663,18 +1456,166 @@ static inline int ocfs2_dirent_would_fit(struct ocfs2_dir_entry *de,
return 0;
}
+static void ocfs2_dx_dir_leaf_insert_tail(struct ocfs2_dx_leaf *dx_leaf,
+ struct ocfs2_dx_entry *dx_new_entry)
+{
+ int i;
+
+ i = le16_to_cpu(dx_leaf->dl_list.de_num_used);
+ dx_leaf->dl_list.de_entries[i] = *dx_new_entry;
+
+ le16_add_cpu(&dx_leaf->dl_list.de_num_used, 1);
+}
+
+static void ocfs2_dx_entry_list_insert(struct ocfs2_dx_entry_list *entry_list,
+ struct ocfs2_dx_hinfo *hinfo,
+ u64 dirent_blk)
+{
+ int i;
+ struct ocfs2_dx_entry *dx_entry;
+
+ i = le16_to_cpu(entry_list->de_num_used);
+ dx_entry = &entry_list->de_entries[i];
+
+ memset(dx_entry, 0, sizeof(*dx_entry));
+ dx_entry->dx_major_hash = cpu_to_le32(hinfo->major_hash);
+ dx_entry->dx_minor_hash = cpu_to_le32(hinfo->minor_hash);
+ dx_entry->dx_dirent_blk = cpu_to_le64(dirent_blk);
+
+ le16_add_cpu(&entry_list->de_num_used, 1);
+}
+
+static int __ocfs2_dx_dir_leaf_insert(struct inode *dir, handle_t *handle,
+ struct ocfs2_dx_hinfo *hinfo,
+ u64 dirent_blk,
+ struct buffer_head *dx_leaf_bh)
+{
+ int ret;
+ struct ocfs2_dx_leaf *dx_leaf;
+
+ ret = ocfs2_journal_access_dl(handle, dir, dx_leaf_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ dx_leaf = (struct ocfs2_dx_leaf *)dx_leaf_bh->b_data;
+ ocfs2_dx_entry_list_insert(&dx_leaf->dl_list, hinfo, dirent_blk);
+ ocfs2_journal_dirty(handle, dx_leaf_bh);
+
+out:
+ return ret;
+}
+
+static void ocfs2_dx_inline_root_insert(struct inode *dir, handle_t *handle,
+ struct ocfs2_dx_hinfo *hinfo,
+ u64 dirent_blk,
+ struct ocfs2_dx_root_block *dx_root)
+{
+ ocfs2_dx_entry_list_insert(&dx_root->dr_entries, hinfo, dirent_blk);
+}
+
+static int ocfs2_dx_dir_insert(struct inode *dir, handle_t *handle,
+ struct ocfs2_dir_lookup_result *lookup)
+{
+ int ret = 0;
+ struct ocfs2_dx_root_block *dx_root;
+ struct buffer_head *dx_root_bh = lookup->dl_dx_root_bh;
+
+ ret = ocfs2_journal_access_dr(handle, dir, dx_root_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ dx_root = (struct ocfs2_dx_root_block *)lookup->dl_dx_root_bh->b_data;
+ if (ocfs2_dx_root_inline(dx_root)) {
+ ocfs2_dx_inline_root_insert(dir, handle,
+ &lookup->dl_hinfo,
+ lookup->dl_leaf_bh->b_blocknr,
+ dx_root);
+ } else {
+ ret = __ocfs2_dx_dir_leaf_insert(dir, handle, &lookup->dl_hinfo,
+ lookup->dl_leaf_bh->b_blocknr,
+ lookup->dl_dx_leaf_bh);
+ if (ret)
+ goto out;
+ }
+
+ le32_add_cpu(&dx_root->dr_num_entries, 1);
+ ocfs2_journal_dirty(handle, dx_root_bh);
+
+out:
+ return ret;
+}
+
+static void ocfs2_remove_block_from_free_list(struct inode *dir,
+ handle_t *handle,
+ struct ocfs2_dir_lookup_result *lookup)
+{
+ struct ocfs2_dir_block_trailer *trailer, *prev;
+ struct ocfs2_dx_root_block *dx_root;
+ struct buffer_head *bh;
+
+ trailer = ocfs2_trailer_from_bh(lookup->dl_leaf_bh, dir->i_sb);
+
+ if (ocfs2_free_list_at_root(lookup)) {
+ bh = lookup->dl_dx_root_bh;
+ dx_root = (struct ocfs2_dx_root_block *)bh->b_data;
+ dx_root->dr_free_blk = trailer->db_free_next;
+ } else {
+ bh = lookup->dl_prev_leaf_bh;
+ prev = ocfs2_trailer_from_bh(bh, dir->i_sb);
+ prev->db_free_next = trailer->db_free_next;
+ }
+
+ trailer->db_free_rec_len = cpu_to_le16(0);
+ trailer->db_free_next = cpu_to_le64(0);
+
+ ocfs2_journal_dirty(handle, bh);
+ ocfs2_journal_dirty(handle, lookup->dl_leaf_bh);
+}
+
+/*
+ * This expects that a journal write has been reserved on
+ * lookup->dl_prev_leaf_bh or lookup->dl_dx_root_bh
+ */
+static void ocfs2_recalc_free_list(struct inode *dir, handle_t *handle,
+ struct ocfs2_dir_lookup_result *lookup)
+{
+ int max_rec_len;
+ struct ocfs2_dir_block_trailer *trailer;
+
+ /* Walk dl_leaf_bh to figure out what the new free rec_len is. */
+ max_rec_len = ocfs2_find_max_rec_len(dir->i_sb, lookup->dl_leaf_bh);
+ if (max_rec_len) {
+ /*
+ * There's still room in this block, so no need to remove it
+ * from the free list. In this case, we just want to update
+ * the rec len accounting.
+ */
+ trailer = ocfs2_trailer_from_bh(lookup->dl_leaf_bh, dir->i_sb);
+ trailer->db_free_rec_len = cpu_to_le16(max_rec_len);
+ ocfs2_journal_dirty(handle, lookup->dl_leaf_bh);
+ } else {
+ ocfs2_remove_block_from_free_list(dir, handle, lookup);
+ }
+}
+
/* we don't always have a dentry for what we want to add, so people
* like orphan dir can call this instead.
*
- * If you pass me insert_bh, I'll skip the search of the other dir
- * blocks and put the record in there.
+ * The lookup context must have been filled from
+ * ocfs2_prepare_dir_for_insert.
*/
int __ocfs2_add_entry(handle_t *handle,
struct inode *dir,
const char *name, int namelen,
struct inode *inode, u64 blkno,
struct buffer_head *parent_fe_bh,
- struct buffer_head *insert_bh)
+ struct ocfs2_dir_lookup_result *lookup)
{
unsigned long offset;
unsigned short rec_len;
@@ -683,6 +1624,7 @@ int __ocfs2_add_entry(handle_t *handle,
struct super_block *sb = dir->i_sb;
int retval, status;
unsigned int size = sb->s_blocksize;
+ struct buffer_head *insert_bh = lookup->dl_leaf_bh;
char *data_start = insert_bh->b_data;
mlog_entry_void();
@@ -690,7 +1632,31 @@ int __ocfs2_add_entry(handle_t *handle,
if (!namelen)
return -EINVAL;
- if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
+ if (ocfs2_dir_indexed(dir)) {
+ struct buffer_head *bh;
+
+ /*
+ * An indexed dir may require that we update the free space
+ * list. Reserve a write to the previous node in the list so
+ * that we don't fail later.
+ *
+ * XXX: This can be either a dx_root_block, or an unindexed
+ * directory tree leaf block.
+ */
+ if (ocfs2_free_list_at_root(lookup)) {
+ bh = lookup->dl_dx_root_bh;
+ retval = ocfs2_journal_access_dr(handle, dir, bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ } else {
+ bh = lookup->dl_prev_leaf_bh;
+ retval = ocfs2_journal_access_db(handle, dir, bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ }
+ if (retval) {
+ mlog_errno(retval);
+ return retval;
+ }
+ } else if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
data_start = di->id2.i_data.id_data;
size = i_size_read(dir);
@@ -737,10 +1703,22 @@ int __ocfs2_add_entry(handle_t *handle,
status = ocfs2_journal_access_di(handle, dir,
insert_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
- else
+ else {
status = ocfs2_journal_access_db(handle, dir,
insert_bh,
- OCFS2_JOURNAL_ACCESS_WRITE);
+ OCFS2_JOURNAL_ACCESS_WRITE);
+
+ if (ocfs2_dir_indexed(dir)) {
+ status = ocfs2_dx_dir_insert(dir,
+ handle,
+ lookup);
+ if (status) {
+ mlog_errno(status);
+ goto bail;
+ }
+ }
+ }
+
/* By now the buffer is marked for journaling */
offset += le16_to_cpu(de->rec_len);
if (le64_to_cpu(de->inode)) {
@@ -761,6 +1739,9 @@ int __ocfs2_add_entry(handle_t *handle,
de->name_len = namelen;
memcpy(de->name, name, namelen);
+ if (ocfs2_dir_indexed(dir))
+ ocfs2_recalc_free_list(dir, handle, lookup);
+
dir->i_version++;
status = ocfs2_journal_dirty(handle, insert_bh);
retval = 0;
@@ -870,6 +1851,10 @@ out:
return 0;
}
+/*
+ * NOTE: This function can be called against unindexed directories,
+ * and indexed ones.
+ */
static int ocfs2_dir_foreach_blk_el(struct inode *inode,
u64 *f_version,
loff_t *f_pos, void *priv,
@@ -1071,31 +2056,22 @@ int ocfs2_find_files_on_disk(const char *name,
int namelen,
u64 *blkno,
struct inode *inode,
- struct buffer_head **dirent_bh,
- struct ocfs2_dir_entry **dirent)
+ struct ocfs2_dir_lookup_result *lookup)
{
int status = -ENOENT;
- mlog_entry("(name=%.*s, blkno=%p, inode=%p, dirent_bh=%p, dirent=%p)\n",
- namelen, name, blkno, inode, dirent_bh, dirent);
+ mlog(0, "name=%.*s, blkno=%p, inode=%llu\n", namelen, name, blkno,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno);
- *dirent_bh = ocfs2_find_entry(name, namelen, inode, dirent);
- if (!*dirent_bh || !*dirent) {
- status = -ENOENT;
+ status = ocfs2_find_entry(name, namelen, inode, lookup);
+ if (status)
goto leave;
- }
- *blkno = le64_to_cpu((*dirent)->inode);
+ *blkno = le64_to_cpu(lookup->dl_entry->inode);
status = 0;
leave:
- if (status < 0) {
- *dirent = NULL;
- brelse(*dirent_bh);
- *dirent_bh = NULL;
- }
- mlog_exit(status);
return status;
}
@@ -1107,11 +2083,10 @@ int ocfs2_lookup_ino_from_name(struct inode *dir, const char *name,
int namelen, u64 *blkno)
{
int ret;
- struct buffer_head *bh = NULL;
- struct ocfs2_dir_entry *dirent = NULL;
+ struct ocfs2_dir_lookup_result lookup = { NULL, };
- ret = ocfs2_find_files_on_disk(name, namelen, blkno, dir, &bh, &dirent);
- brelse(bh);
+ ret = ocfs2_find_files_on_disk(name, namelen, blkno, dir, &lookup);
+ ocfs2_free_dir_lookup_result(&lookup);
return ret;
}
@@ -1128,20 +2103,18 @@ int ocfs2_check_dir_for_entry(struct inode *dir,
int namelen)
{
int ret;
- struct buffer_head *dirent_bh = NULL;
- struct ocfs2_dir_entry *dirent = NULL;
+ struct ocfs2_dir_lookup_result lookup = { NULL, };
mlog_entry("dir %llu, name '%.*s'\n",
(unsigned long long)OCFS2_I(dir)->ip_blkno, namelen, name);
ret = -EEXIST;
- dirent_bh = ocfs2_find_entry(name, namelen, dir, &dirent);
- if (dirent_bh)
+ if (ocfs2_find_entry(name, namelen, dir, &lookup) == 0)
goto bail;
ret = 0;
bail:
- brelse(dirent_bh);
+ ocfs2_free_dir_lookup_result(&lookup);
mlog_exit(ret);
return ret;
@@ -1151,6 +2124,7 @@ struct ocfs2_empty_dir_priv {
unsigned seen_dot;
unsigned seen_dot_dot;
unsigned seen_other;
+ unsigned dx_dir;
};
static int ocfs2_empty_dir_filldir(void *priv, const char *name, int name_len,
loff_t pos, u64 ino, unsigned type)
@@ -1160,6 +2134,13 @@ static int ocfs2_empty_dir_filldir(void *priv, const char *name, int name_len,
/*
* Check the positions of "." and ".." records to be sure
* they're in the correct place.
+ *
+ * Indexed directories don't need to proceed past the first
+ * two entries, so we end the scan after seeing '..'. Despite
+ * that, we allow the scan to proceed In the event that we
+ * have a corrupted indexed directory (no dot or dot dot
+ * entries). This allows us to double check for existing
+ * entries which might not have been found in the index.
*/
if (name_len == 1 && !strncmp(".", name, 1) && pos == 0) {
p->seen_dot = 1;
@@ -1169,16 +2150,57 @@ static int ocfs2_empty_dir_filldir(void *priv, const char *name, int name_len,
if (name_len == 2 && !strncmp("..", name, 2) &&
pos == OCFS2_DIR_REC_LEN(1)) {
p->seen_dot_dot = 1;
+
+ if (p->dx_dir && p->seen_dot)
+ return 1;
+
return 0;
}
p->seen_other = 1;
return 1;
}
+
+static int ocfs2_empty_dir_dx(struct inode *inode,
+ struct ocfs2_empty_dir_priv *priv)
+{
+ int ret;
+ struct buffer_head *di_bh = NULL;
+ struct buffer_head *dx_root_bh = NULL;
+ struct ocfs2_dinode *di;
+ struct ocfs2_dx_root_block *dx_root;
+
+ priv->dx_dir = 1;
+
+ ret = ocfs2_read_inode_block(inode, &di_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+ di = (struct ocfs2_dinode *)di_bh->b_data;
+
+ ret = ocfs2_read_dx_root(inode, di, &dx_root_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+ dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+
+ if (le32_to_cpu(dx_root->dr_num_entries) != 2)
+ priv->seen_other = 1;
+
+out:
+ brelse(di_bh);
+ brelse(dx_root_bh);
+ return ret;
+}
+
/*
* routine to check that the specified directory is empty (for rmdir)
*
* Returns 1 if dir is empty, zero otherwise.
+ *
+ * XXX: This is a performance problem for unindexed directories.
*/
int ocfs2_empty_dir(struct inode *inode)
{
@@ -1188,6 +2210,16 @@ int ocfs2_empty_dir(struct inode *inode)
memset(&priv, 0, sizeof(priv));
+ if (ocfs2_dir_indexed(inode)) {
+ ret = ocfs2_empty_dir_dx(inode, &priv);
+ if (ret)
+ mlog_errno(ret);
+ /*
+ * We still run ocfs2_dir_foreach to get the checks
+ * for "." and "..".
+ */
+ }
+
ret = ocfs2_dir_foreach(inode, &start, &priv, ocfs2_empty_dir_filldir);
if (ret)
mlog_errno(ret);
@@ -1280,7 +2312,8 @@ static int ocfs2_fill_new_dir_el(struct ocfs2_super *osb,
struct inode *parent,
struct inode *inode,
struct buffer_head *fe_bh,
- struct ocfs2_alloc_context *data_ac)
+ struct ocfs2_alloc_context *data_ac,
+ struct buffer_head **ret_new_bh)
{
int status;
unsigned int size = osb->sb->s_blocksize;
@@ -1289,7 +2322,7 @@ static int ocfs2_fill_new_dir_el(struct ocfs2_super *osb,
mlog_entry_void();
- if (ocfs2_supports_dir_trailer(osb))
+ if (ocfs2_new_dir_wants_trailer(inode))
size = ocfs2_dir_trailer_blk_off(parent->i_sb);
status = ocfs2_do_extend_dir(osb->sb, handle, inode, fe_bh,
@@ -1310,8 +2343,19 @@ static int ocfs2_fill_new_dir_el(struct ocfs2_super *osb,
memset(new_bh->b_data, 0, osb->sb->s_blocksize);
de = ocfs2_fill_initial_dirents(inode, parent, new_bh->b_data, size);
- if (ocfs2_supports_dir_trailer(osb))
- ocfs2_init_dir_trailer(inode, new_bh);
+ if (ocfs2_new_dir_wants_trailer(inode)) {
+ int size = le16_to_cpu(de->rec_len);
+
+ /*
+ * Figure out the size of the hole left over after
+ * insertion of '.' and '..'. The trailer wants this
+ * information.
+ */
+ size -= OCFS2_DIR_REC_LEN(2);
+ size -= sizeof(struct ocfs2_dir_block_trailer);
+
+ ocfs2_init_dir_trailer(inode, new_bh, size);
+ }
status = ocfs2_journal_dirty(handle, new_bh);
if (status < 0) {
@@ -1329,6 +2373,10 @@ static int ocfs2_fill_new_dir_el(struct ocfs2_super *osb,
}
status = 0;
+ if (ret_new_bh) {
+ *ret_new_bh = new_bh;
+ new_bh = NULL;
+ }
bail:
brelse(new_bh);
@@ -1336,20 +2384,427 @@ bail:
return status;
}
+static int ocfs2_dx_dir_attach_index(struct ocfs2_super *osb,
+ handle_t *handle, struct inode *dir,
+ struct buffer_head *di_bh,
+ struct buffer_head *dirdata_bh,
+ struct ocfs2_alloc_context *meta_ac,
+ int dx_inline, u32 num_entries,
+ struct buffer_head **ret_dx_root_bh)
+{
+ int ret;
+ struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
+ u16 dr_suballoc_bit;
+ u64 dr_blkno;
+ unsigned int num_bits;
+ struct buffer_head *dx_root_bh = NULL;
+ struct ocfs2_dx_root_block *dx_root;
+ struct ocfs2_dir_block_trailer *trailer =
+ ocfs2_trailer_from_bh(dirdata_bh, dir->i_sb);
+
+ ret = ocfs2_claim_metadata(osb, handle, meta_ac, 1, &dr_suballoc_bit,
+ &num_bits, &dr_blkno);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ mlog(0, "Dir %llu, attach new index block: %llu\n",
+ (unsigned long long)OCFS2_I(dir)->ip_blkno,
+ (unsigned long long)dr_blkno);
+
+ dx_root_bh = sb_getblk(osb->sb, dr_blkno);
+ if (dx_root_bh == NULL) {
+ ret = -EIO;
+ goto out;
+ }
+ ocfs2_set_new_buffer_uptodate(dir, dx_root_bh);
+
+ ret = ocfs2_journal_access_dr(handle, dir, dx_root_bh,
+ OCFS2_JOURNAL_ACCESS_CREATE);
+ if (ret < 0) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+ memset(dx_root, 0, osb->sb->s_blocksize);
+ strcpy(dx_root->dr_signature, OCFS2_DX_ROOT_SIGNATURE);
+ dx_root->dr_suballoc_slot = cpu_to_le16(osb->slot_num);
+ dx_root->dr_suballoc_bit = cpu_to_le16(dr_suballoc_bit);
+ dx_root->dr_fs_generation = cpu_to_le32(osb->fs_generation);
+ dx_root->dr_blkno = cpu_to_le64(dr_blkno);
+ dx_root->dr_dir_blkno = cpu_to_le64(OCFS2_I(dir)->ip_blkno);
+ dx_root->dr_num_entries = cpu_to_le32(num_entries);
+ if (le16_to_cpu(trailer->db_free_rec_len))
+ dx_root->dr_free_blk = cpu_to_le64(dirdata_bh->b_blocknr);
+ else
+ dx_root->dr_free_blk = cpu_to_le64(0);
+
+ if (dx_inline) {
+ dx_root->dr_flags |= OCFS2_DX_FLAG_INLINE;
+ dx_root->dr_entries.de_count =
+ cpu_to_le16(ocfs2_dx_entries_per_root(osb->sb));
+ } else {
+ dx_root->dr_list.l_count =
+ cpu_to_le16(ocfs2_extent_recs_per_dx_root(osb->sb));
+ }
+
+ ret = ocfs2_journal_dirty(handle, dx_root_bh);
+ if (ret)
+ mlog_errno(ret);
+
+ ret = ocfs2_journal_access_di(handle, dir, di_bh,
+ OCFS2_JOURNAL_ACCESS_CREATE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ di->i_dx_root = cpu_to_le64(dr_blkno);
+
+ OCFS2_I(dir)->ip_dyn_features |= OCFS2_INDEXED_DIR_FL;
+ di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features);
+
+ ret = ocfs2_journal_dirty(handle, di_bh);
+ if (ret)
+ mlog_errno(ret);
+
+ *ret_dx_root_bh = dx_root_bh;
+ dx_root_bh = NULL;
+
+out:
+ brelse(dx_root_bh);
+ return ret;
+}
+
+static int ocfs2_dx_dir_format_cluster(struct ocfs2_super *osb,
+ handle_t *handle, struct inode *dir,
+ struct buffer_head **dx_leaves,
+ int num_dx_leaves, u64 start_blk)
+{
+ int ret, i;
+ struct ocfs2_dx_leaf *dx_leaf;
+ struct buffer_head *bh;
+
+ for (i = 0; i < num_dx_leaves; i++) {
+ bh = sb_getblk(osb->sb, start_blk + i);
+ if (bh == NULL) {
+ ret = -EIO;
+ goto out;
+ }
+ dx_leaves[i] = bh;
+
+ ocfs2_set_new_buffer_uptodate(dir, bh);
+
+ ret = ocfs2_journal_access_dl(handle, dir, bh,
+ OCFS2_JOURNAL_ACCESS_CREATE);
+ if (ret < 0) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ dx_leaf = (struct ocfs2_dx_leaf *) bh->b_data;
+
+ memset(dx_leaf, 0, osb->sb->s_blocksize);
+ strcpy(dx_leaf->dl_signature, OCFS2_DX_LEAF_SIGNATURE);
+ dx_leaf->dl_fs_generation = cpu_to_le32(osb->fs_generation);
+ dx_leaf->dl_blkno = cpu_to_le64(bh->b_blocknr);
+ dx_leaf->dl_list.de_count =
+ cpu_to_le16(ocfs2_dx_entries_per_leaf(osb->sb));
+
+ mlog(0,
+ "Dir %llu, format dx_leaf: %llu, entry count: %u\n",
+ (unsigned long long)OCFS2_I(dir)->ip_blkno,
+ (unsigned long long)bh->b_blocknr,
+ le16_to_cpu(dx_leaf->dl_list.de_count));
+
+ ocfs2_journal_dirty(handle, bh);
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+/*
+ * Allocates and formats a new cluster for use in an indexed dir
+ * leaf. This version will not do the extent insert, so that it can be
+ * used by operations which need careful ordering.
+ */
+static int __ocfs2_dx_dir_new_cluster(struct inode *dir,
+ u32 cpos, handle_t *handle,
+ struct ocfs2_alloc_context *data_ac,
+ struct buffer_head **dx_leaves,
+ int num_dx_leaves, u64 *ret_phys_blkno)
+{
+ int ret;
+ u32 phys, num;
+ u64 phys_blkno;
+ struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+
+ /*
+ * XXX: For create, this should claim cluster for the index
+ * *before* the unindexed insert so that we have a better
+ * chance of contiguousness as the directory grows in number
+ * of entries.
+ */
+ ret = __ocfs2_claim_clusters(osb, handle, data_ac, 1, 1, &phys, &num);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ /*
+ * Format the new cluster first. That way, we're inserting
+ * valid data.
+ */
+ phys_blkno = ocfs2_clusters_to_blocks(osb->sb, phys);
+ ret = ocfs2_dx_dir_format_cluster(osb, handle, dir, dx_leaves,
+ num_dx_leaves, phys_blkno);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ *ret_phys_blkno = phys_blkno;
+out:
+ return ret;
+}
+
+static int ocfs2_dx_dir_new_cluster(struct inode *dir,
+ struct ocfs2_extent_tree *et,
+ u32 cpos, handle_t *handle,
+ struct ocfs2_alloc_context *data_ac,
+ struct ocfs2_alloc_context *meta_ac,
+ struct buffer_head **dx_leaves,
+ int num_dx_leaves)
+{
+ int ret;
+ u64 phys_blkno;
+ struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+
+ ret = __ocfs2_dx_dir_new_cluster(dir, cpos, handle, data_ac, dx_leaves,
+ num_dx_leaves, &phys_blkno);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ ret = ocfs2_insert_extent(osb, handle, dir, et, cpos, phys_blkno, 1, 0,
+ meta_ac);
+ if (ret)
+ mlog_errno(ret);
+out:
+ return ret;
+}
+
+static struct buffer_head **ocfs2_dx_dir_kmalloc_leaves(struct super_block *sb,
+ int *ret_num_leaves)
+{
+ int num_dx_leaves = ocfs2_clusters_to_blocks(sb, 1);
+ struct buffer_head **dx_leaves;
+
+ dx_leaves = kcalloc(num_dx_leaves, sizeof(struct buffer_head *),
+ GFP_NOFS);
+ if (dx_leaves && ret_num_leaves)
+ *ret_num_leaves = num_dx_leaves;
+
+ return dx_leaves;
+}
+
+static int ocfs2_fill_new_dir_dx(struct ocfs2_super *osb,
+ handle_t *handle,
+ struct inode *parent,
+ struct inode *inode,
+ struct buffer_head *di_bh,
+ struct ocfs2_alloc_context *data_ac,
+ struct ocfs2_alloc_context *meta_ac)
+{
+ int ret;
+ struct buffer_head *leaf_bh = NULL;
+ struct buffer_head *dx_root_bh = NULL;
+ struct ocfs2_dx_hinfo hinfo;
+ struct ocfs2_dx_root_block *dx_root;
+ struct ocfs2_dx_entry_list *entry_list;
+
+ /*
+ * Our strategy is to create the directory as though it were
+ * unindexed, then add the index block. This works with very
+ * little complication since the state of a new directory is a
+ * very well known quantity.
+ *
+ * Essentially, we have two dirents ("." and ".."), in the 1st
+ * block which need indexing. These are easily inserted into
+ * the index block.
+ */
+
+ ret = ocfs2_fill_new_dir_el(osb, handle, parent, inode, di_bh,
+ data_ac, &leaf_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ ret = ocfs2_dx_dir_attach_index(osb, handle, inode, di_bh, leaf_bh,
+ meta_ac, 1, 2, &dx_root_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+ dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+ entry_list = &dx_root->dr_entries;
+
+ /* Buffer has been journaled for us by ocfs2_dx_dir_attach_index */
+ ocfs2_dx_dir_name_hash(inode, ".", 1, &hinfo);
+ ocfs2_dx_entry_list_insert(entry_list, &hinfo, leaf_bh->b_blocknr);
+
+ ocfs2_dx_dir_name_hash(inode, "..", 2, &hinfo);
+ ocfs2_dx_entry_list_insert(entry_list, &hinfo, leaf_bh->b_blocknr);
+
+out:
+ brelse(dx_root_bh);
+ brelse(leaf_bh);
+ return ret;
+}
+
int ocfs2_fill_new_dir(struct ocfs2_super *osb,
handle_t *handle,
struct inode *parent,
struct inode *inode,
struct buffer_head *fe_bh,
- struct ocfs2_alloc_context *data_ac)
+ struct ocfs2_alloc_context *data_ac,
+ struct ocfs2_alloc_context *meta_ac)
+
{
BUG_ON(!ocfs2_supports_inline_data(osb) && data_ac == NULL);
if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
return ocfs2_fill_new_dir_id(osb, handle, parent, inode, fe_bh);
+ if (ocfs2_supports_indexed_dirs(osb))
+ return ocfs2_fill_new_dir_dx(osb, handle, parent, inode, fe_bh,
+ data_ac, meta_ac);
+
return ocfs2_fill_new_dir_el(osb, handle, parent, inode, fe_bh,
- data_ac);
+ data_ac, NULL);
+}
+
+static int ocfs2_dx_dir_index_block(struct inode *dir,
+ handle_t *handle,
+ struct buffer_head **dx_leaves,
+ int num_dx_leaves,
+ u32 *num_dx_entries,
+ struct buffer_head *dirent_bh)
+{
+ int ret, namelen, i;
+ char *de_buf, *limit;
+ struct ocfs2_dir_entry *de;
+ struct buffer_head *dx_leaf_bh;
+ struct ocfs2_dx_hinfo hinfo;
+ u64 dirent_blk = dirent_bh->b_blocknr;
+
+ de_buf = dirent_bh->b_data;
+ limit = de_buf + dir->i_sb->s_blocksize;
+
+ while (de_buf < limit) {
+ de = (struct ocfs2_dir_entry *)de_buf;
+
+ namelen = de->name_len;
+ if (!namelen || !de->inode)
+ goto inc;
+
+ ocfs2_dx_dir_name_hash(dir, de->name, namelen, &hinfo);
+
+ i = ocfs2_dx_dir_hash_idx(OCFS2_SB(dir->i_sb), &hinfo);
+ dx_leaf_bh = dx_leaves[i];
+
+ ret = __ocfs2_dx_dir_leaf_insert(dir, handle, &hinfo,
+ dirent_blk, dx_leaf_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ *num_dx_entries = *num_dx_entries + 1;
+
+inc:
+ de_buf += le16_to_cpu(de->rec_len);
+ }
+
+out:
+ return ret;
+}
+
+/*
+ * XXX: This expects dx_root_bh to already be part of the transaction.
+ */
+static void ocfs2_dx_dir_index_root_block(struct inode *dir,
+ struct buffer_head *dx_root_bh,
+ struct buffer_head *dirent_bh)
+{
+ char *de_buf, *limit;
+ struct ocfs2_dx_root_block *dx_root;
+ struct ocfs2_dir_entry *de;
+ struct ocfs2_dx_hinfo hinfo;
+ u64 dirent_blk = dirent_bh->b_blocknr;
+
+ dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+
+ de_buf = dirent_bh->b_data;
+ limit = de_buf + dir->i_sb->s_blocksize;
+
+ while (de_buf < limit) {
+ de = (struct ocfs2_dir_entry *)de_buf;
+
+ if (!de->name_len || !de->inode)
+ goto inc;
+
+ ocfs2_dx_dir_name_hash(dir, de->name, de->name_len, &hinfo);
+
+ mlog(0,
+ "dir: %llu, major: 0x%x minor: 0x%x, index: %u, name: %.*s\n",
+ (unsigned long long)dir->i_ino, hinfo.major_hash,
+ hinfo.minor_hash,
+ le16_to_cpu(dx_root->dr_entries.de_num_used),
+ de->name_len, de->name);
+
+ ocfs2_dx_entry_list_insert(&dx_root->dr_entries, &hinfo,
+ dirent_blk);
+
+ le32_add_cpu(&dx_root->dr_num_entries, 1);
+inc:
+ de_buf += le16_to_cpu(de->rec_len);
+ }
+}
+
+/*
+ * Count the number of inline directory entries in di_bh and compare
+ * them against the number of entries we can hold in an inline dx root
+ * block.
+ */
+static int ocfs2_new_dx_should_be_inline(struct inode *dir,
+ struct buffer_head *di_bh)
+{
+ int dirent_count = 0;
+ char *de_buf, *limit;
+ struct ocfs2_dir_entry *de;
+ struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
+
+ de_buf = di->id2.i_data.id_data;
+ limit = de_buf + i_size_read(dir);
+
+ while (de_buf < limit) {
+ de = (struct ocfs2_dir_entry *)de_buf;
+
+ if (de->name_len && de->inode)
+ dirent_count++;
+
+ de_buf += le16_to_cpu(de->rec_len);
+ }
+
+ /* We are careful to leave room for one extra record. */
+ return dirent_count < ocfs2_dx_entries_per_root(dir->i_sb);
}
/*
@@ -1358,18 +2813,26 @@ int ocfs2_fill_new_dir(struct ocfs2_super *osb,
* expansion from an inline directory to one with extents. The first dir block
* in that case is taken from the inline data portion of the inode block.
*
+ * This will also return the largest amount of contiguous space for a dirent
+ * in the block. That value is *not* necessarily the last dirent, even after
+ * expansion. The directory indexing code wants this value for free space
+ * accounting. We do this here since we're already walking the entire dir
+ * block.
+ *
* We add the dir trailer if this filesystem wants it.
*/
-static void ocfs2_expand_last_dirent(char *start, unsigned int old_size,
- struct super_block *sb)
+static unsigned int ocfs2_expand_last_dirent(char *start, unsigned int old_size,
+ struct inode *dir)
{
+ struct super_block *sb = dir->i_sb;
struct ocfs2_dir_entry *de;
struct ocfs2_dir_entry *prev_de;
char *de_buf, *limit;
unsigned int new_size = sb->s_blocksize;
- unsigned int bytes;
+ unsigned int bytes, this_hole;
+ unsigned int largest_hole = 0;
- if (ocfs2_supports_dir_trailer(OCFS2_SB(sb)))
+ if (ocfs2_new_dir_wants_trailer(dir))
new_size = ocfs2_dir_trailer_blk_off(sb);
bytes = new_size - old_size;
@@ -1378,12 +2841,26 @@ static void ocfs2_expand_last_dirent(char *start, unsigned int old_size,
de_buf = start;
de = (struct ocfs2_dir_entry *)de_buf;
do {
+ this_hole = ocfs2_figure_dirent_hole(de);
+ if (this_hole > largest_hole)
+ largest_hole = this_hole;
+
prev_de = de;
de_buf += le16_to_cpu(de->rec_len);
de = (struct ocfs2_dir_entry *)de_buf;
} while (de_buf < limit);
le16_add_cpu(&prev_de->rec_len, bytes);
+
+ /* We need to double check this after modification of the final
+ * dirent. */
+ this_hole = ocfs2_figure_dirent_hole(prev_de);
+ if (this_hole > largest_hole)
+ largest_hole = this_hole;
+
+ if (largest_hole >= OCFS2_DIR_MIN_REC_LEN)
+ return largest_hole;
+ return 0;
}
/*
@@ -1396,29 +2873,61 @@ static void ocfs2_expand_last_dirent(char *start, unsigned int old_size,
*/
static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
unsigned int blocks_wanted,
+ struct ocfs2_dir_lookup_result *lookup,
struct buffer_head **first_block_bh)
{
- u32 alloc, bit_off, len;
+ u32 alloc, dx_alloc, bit_off, len, num_dx_entries = 0;
struct super_block *sb = dir->i_sb;
- int ret, credits = ocfs2_inline_to_extents_credits(sb);
- u64 blkno, bytes = blocks_wanted << sb->s_blocksize_bits;
+ int ret, i, num_dx_leaves = 0, dx_inline = 0,
+ credits = ocfs2_inline_to_extents_credits(sb);
+ u64 dx_insert_blkno, blkno,
+ bytes = blocks_wanted << sb->s_blocksize_bits;
struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
struct ocfs2_inode_info *oi = OCFS2_I(dir);
struct ocfs2_alloc_context *data_ac;
+ struct ocfs2_alloc_context *meta_ac = NULL;
struct buffer_head *dirdata_bh = NULL;
+ struct buffer_head *dx_root_bh = NULL;
+ struct buffer_head **dx_leaves = NULL;
struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
handle_t *handle;
struct ocfs2_extent_tree et;
- int did_quota = 0;
+ struct ocfs2_extent_tree dx_et;
+ int did_quota = 0, bytes_allocated = 0;
ocfs2_init_dinode_extent_tree(&et, dir, di_bh);
alloc = ocfs2_clusters_for_bytes(sb, bytes);
+ dx_alloc = 0;
+
+ if (ocfs2_supports_indexed_dirs(osb)) {
+ credits += ocfs2_add_dir_index_credits(sb);
+
+ dx_inline = ocfs2_new_dx_should_be_inline(dir, di_bh);
+ if (!dx_inline) {
+ /* Add one more cluster for an index leaf */
+ dx_alloc++;
+ dx_leaves = ocfs2_dx_dir_kmalloc_leaves(sb,
+ &num_dx_leaves);
+ if (!dx_leaves) {
+ ret = -ENOMEM;
+ mlog_errno(ret);
+ goto out;
+ }
+ }
+
+ /* This gets us the dx_root */
+ ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+ }
/*
- * We should never need more than 2 clusters for this -
- * maximum dirent size is far less than one block. In fact,
- * the only time we'd need more than one cluster is if
+ * We should never need more than 2 clusters for the unindexed
+ * tree - maximum dirent size is far less than one block. In
+ * fact, the only time we'd need more than one cluster is if
* blocksize == clustersize and the dirent won't fit in the
* extra space that the expansion to a single block gives. As
* of today, that only happens on 4k/4k file systems.
@@ -1435,7 +2944,7 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
/*
* Prepare for worst case allocation scenario of two separate
- * extents.
+ * extents in the unindexed tree.
*/
if (alloc == 2)
credits += OCFS2_SUBALLOC_ALLOC;
@@ -1448,11 +2957,29 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
}
if (vfs_dq_alloc_space_nodirty(dir,
- ocfs2_clusters_to_bytes(osb->sb, alloc))) {
+ ocfs2_clusters_to_bytes(osb->sb,
+ alloc + dx_alloc))) {
ret = -EDQUOT;
goto out_commit;
}
did_quota = 1;
+
+ if (ocfs2_supports_indexed_dirs(osb) && !dx_inline) {
+ /*
+ * Allocate our index cluster first, to maximize the
+ * possibility that unindexed leaves grow
+ * contiguously.
+ */
+ ret = __ocfs2_dx_dir_new_cluster(dir, 0, handle, data_ac,
+ dx_leaves, num_dx_leaves,
+ &dx_insert_blkno);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+ bytes_allocated += ocfs2_clusters_to_bytes(dir->i_sb, 1);
+ }
+
/*
* Try to claim as many clusters as the bitmap can give though
* if we only get one now, that's enough to continue. The rest
@@ -1463,6 +2990,7 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
mlog_errno(ret);
goto out_commit;
}
+ bytes_allocated += ocfs2_clusters_to_bytes(dir->i_sb, 1);
/*
* Operations are carefully ordered so that we set up the new
@@ -1489,9 +3017,16 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
memcpy(dirdata_bh->b_data, di->id2.i_data.id_data, i_size_read(dir));
memset(dirdata_bh->b_data + i_size_read(dir), 0,
sb->s_blocksize - i_size_read(dir));
- ocfs2_expand_last_dirent(dirdata_bh->b_data, i_size_read(dir), sb);
- if (ocfs2_supports_dir_trailer(osb))
- ocfs2_init_dir_trailer(dir, dirdata_bh);
+ i = ocfs2_expand_last_dirent(dirdata_bh->b_data, i_size_read(dir), dir);
+ if (ocfs2_new_dir_wants_trailer(dir)) {
+ /*
+ * Prepare the dir trailer up front. It will otherwise look
+ * like a valid dirent. Even if inserting the index fails
+ * (unlikely), then all we'll have done is given first dir
+ * block a small amount of fragmentation.
+ */
+ ocfs2_init_dir_trailer(dir, dirdata_bh, i);
+ }
ret = ocfs2_journal_dirty(handle, dirdata_bh);
if (ret) {
@@ -1499,6 +3034,24 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
goto out_commit;
}
+ if (ocfs2_supports_indexed_dirs(osb) && !dx_inline) {
+ /*
+ * Dx dirs with an external cluster need to do this up
+ * front. Inline dx root's get handled later, after
+ * we've allocated our root block. We get passed back
+ * a total number of items so that dr_num_entries can
+ * be correctly set once the dx_root has been
+ * allocated.
+ */
+ ret = ocfs2_dx_dir_index_block(dir, handle, dx_leaves,
+ num_dx_leaves, &num_dx_entries,
+ dirdata_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+ }
+
/*
* Set extent, i_size, etc on the directory. After this, the
* inode should contain the same exact dirents as before and
@@ -1551,6 +3104,27 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
goto out_commit;
}
+ if (ocfs2_supports_indexed_dirs(osb)) {
+ ret = ocfs2_dx_dir_attach_index(osb, handle, dir, di_bh,
+ dirdata_bh, meta_ac, dx_inline,
+ num_dx_entries, &dx_root_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
+ if (dx_inline) {
+ ocfs2_dx_dir_index_root_block(dir, dx_root_bh,
+ dirdata_bh);
+ } else {
+ ocfs2_init_dx_root_extent_tree(&dx_et, dir, dx_root_bh);
+ ret = ocfs2_insert_extent(osb, handle, dir, &dx_et, 0,
+ dx_insert_blkno, 1, 0, NULL);
+ if (ret)
+ mlog_errno(ret);
+ }
+ }
+
/*
* We asked for two clusters, but only got one in the 1st
* pass. Claim the 2nd cluster as a separate extent.
@@ -1570,15 +3144,32 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
mlog_errno(ret);
goto out_commit;
}
+ bytes_allocated += ocfs2_clusters_to_bytes(dir->i_sb, 1);
}
*first_block_bh = dirdata_bh;
dirdata_bh = NULL;
+ if (ocfs2_supports_indexed_dirs(osb)) {
+ unsigned int off;
+
+ if (!dx_inline) {
+ /*
+ * We need to return the correct block within the
+ * cluster which should hold our entry.
+ */
+ off = ocfs2_dx_dir_hash_idx(OCFS2_SB(dir->i_sb),
+ &lookup->dl_hinfo);
+ get_bh(dx_leaves[off]);
+ lookup->dl_dx_leaf_bh = dx_leaves[off];
+ }
+ lookup->dl_dx_root_bh = dx_root_bh;
+ dx_root_bh = NULL;
+ }
out_commit:
if (ret < 0 && did_quota)
- vfs_dq_free_space_nodirty(dir,
- ocfs2_clusters_to_bytes(osb->sb, 2));
+ vfs_dq_free_space_nodirty(dir, bytes_allocated);
+
ocfs2_commit_trans(osb, handle);
out_sem:
@@ -1587,8 +3178,17 @@ out_sem:
out:
if (data_ac)
ocfs2_free_alloc_context(data_ac);
+ if (meta_ac)
+ ocfs2_free_alloc_context(meta_ac);
+
+ if (dx_leaves) {
+ for (i = 0; i < num_dx_leaves; i++)
+ brelse(dx_leaves[i]);
+ kfree(dx_leaves);
+ }
brelse(dirdata_bh);
+ brelse(dx_root_bh);
return ret;
}
@@ -1658,11 +3258,14 @@ bail:
* is to be turned into an extent based one. The size of the dirent to
* insert might be larger than the space gained by growing to just one
* block, so we may have to grow the inode by two blocks in that case.
+ *
+ * If the directory is already indexed, dx_root_bh must be provided.
*/
static int ocfs2_extend_dir(struct ocfs2_super *osb,
struct inode *dir,
struct buffer_head *parent_fe_bh,
unsigned int blocks_wanted,
+ struct ocfs2_dir_lookup_result *lookup,
struct buffer_head **new_de_bh)
{
int status = 0;
@@ -1677,17 +3280,29 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
struct ocfs2_dir_entry * de;
struct super_block *sb = osb->sb;
struct ocfs2_extent_tree et;
+ struct buffer_head *dx_root_bh = lookup->dl_dx_root_bh;
mlog_entry_void();
if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
+ /*
+ * This would be a code error as an inline directory should
+ * never have an index root.
+ */
+ BUG_ON(dx_root_bh);
+
status = ocfs2_expand_inline_dir(dir, parent_fe_bh,
- blocks_wanted, &new_bh);
+ blocks_wanted, lookup,
+ &new_bh);
if (status) {
mlog_errno(status);
goto bail;
}
+ /* Expansion from inline to an indexed directory will
+ * have given us this. */
+ dx_root_bh = lookup->dl_dx_root_bh;
+
if (blocks_wanted == 1) {
/*
* If the new dirent will fit inside the space
@@ -1751,6 +3366,10 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
}
do_extend:
+ if (ocfs2_dir_indexed(dir))
+ credits++; /* For attaching the new dirent block to the
+ * dx_root */
+
down_write(&OCFS2_I(dir)->ip_alloc_sem);
drop_alloc_sem = 1;
@@ -1781,9 +3400,19 @@ do_extend:
de = (struct ocfs2_dir_entry *) new_bh->b_data;
de->inode = 0;
- if (ocfs2_dir_has_trailer(dir)) {
+ if (ocfs2_supports_dir_trailer(dir)) {
de->rec_len = cpu_to_le16(ocfs2_dir_trailer_blk_off(sb));
- ocfs2_init_dir_trailer(dir, new_bh);
+
+ ocfs2_init_dir_trailer(dir, new_bh, le16_to_cpu(de->rec_len));
+
+ if (ocfs2_dir_indexed(dir)) {
+ status = ocfs2_dx_dir_link_trailer(dir, handle,
+ dx_root_bh, new_bh);
+ if (status) {
+ mlog_errno(status);
+ goto bail;
+ }
+ }
} else {
de->rec_len = cpu_to_le16(sb->s_blocksize);
}
@@ -1839,7 +3468,7 @@ static int ocfs2_find_dir_space_id(struct inode *dir, struct buffer_head *di_bh,
* This calculates how many free bytes we'd have in block zero, should
* this function force expansion to an extent tree.
*/
- if (ocfs2_supports_dir_trailer(OCFS2_SB(sb)))
+ if (ocfs2_new_dir_wants_trailer(dir))
free_space = ocfs2_dir_trailer_blk_off(sb) - i_size_read(dir);
else
free_space = dir->i_sb->s_blocksize - i_size_read(dir);
@@ -1970,12 +3599,766 @@ bail:
return status;
}
+static int dx_leaf_sort_cmp(const void *a, const void *b)
+{
+ const struct ocfs2_dx_entry *entry1 = a;
+ const struct ocfs2_dx_entry *entry2 = b;
+ u32 major_hash1 = le32_to_cpu(entry1->dx_major_hash);
+ u32 major_hash2 = le32_to_cpu(entry2->dx_major_hash);
+ u32 minor_hash1 = le32_to_cpu(entry1->dx_minor_hash);
+ u32 minor_hash2 = le32_to_cpu(entry2->dx_minor_hash);
+
+ if (major_hash1 > major_hash2)
+ return 1;
+ if (major_hash1 < major_hash2)
+ return -1;
+
+ /*
+ * It is not strictly necessary to sort by minor
+ */
+ if (minor_hash1 > minor_hash2)
+ return 1;
+ if (minor_hash1 < minor_hash2)
+ return -1;
+ return 0;
+}
+
+static void dx_leaf_sort_swap(void *a, void *b, int size)
+{
+ struct ocfs2_dx_entry *entry1 = a;
+ struct ocfs2_dx_entry *entry2 = b;
+ struct ocfs2_dx_entry tmp;
+
+ BUG_ON(size != sizeof(*entry1));
+
+ tmp = *entry1;
+ *entry1 = *entry2;
+ *entry2 = tmp;
+}
+
+static int ocfs2_dx_leaf_same_major(struct ocfs2_dx_leaf *dx_leaf)
+{
+ struct ocfs2_dx_entry_list *dl_list = &dx_leaf->dl_list;
+ int i, num = le16_to_cpu(dl_list->de_num_used);
+
+ for (i = 0; i < (num - 1); i++) {
+ if (le32_to_cpu(dl_list->de_entries[i].dx_major_hash) !=
+ le32_to_cpu(dl_list->de_entries[i + 1].dx_major_hash))
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Find the optimal value to split this leaf on. This expects the leaf
+ * entries to be in sorted order.
+ *
+ * leaf_cpos is the cpos of the leaf we're splitting. insert_hash is
+ * the hash we want to insert.
+ *
+ * This function is only concerned with the major hash - that which
+ * determines which cluster an item belongs to.
+ */
+static int ocfs2_dx_dir_find_leaf_split(struct ocfs2_dx_leaf *dx_leaf,
+ u32 leaf_cpos, u32 insert_hash,
+ u32 *split_hash)
+{
+ struct ocfs2_dx_entry_list *dl_list = &dx_leaf->dl_list;
+ int i, num_used = le16_to_cpu(dl_list->de_num_used);
+ int allsame;
+
+ /*
+ * There's a couple rare, but nasty corner cases we have to
+ * check for here. All of them involve a leaf where all value
+ * have the same hash, which is what we look for first.
+ *
+ * Most of the time, all of the above is false, and we simply
+ * pick the median value for a split.
+ */
+ allsame = ocfs2_dx_leaf_same_major(dx_leaf);
+ if (allsame) {
+ u32 val = le32_to_cpu(dl_list->de_entries[0].dx_major_hash);
+
+ if (val == insert_hash) {
+ /*
+ * No matter where we would choose to split,
+ * the new entry would want to occupy the same
+ * block as these. Since there's no space left
+ * in their existing block, we know there
+ * won't be space after the split.
+ */
+ return -ENOSPC;
+ }
+
+ if (val == leaf_cpos) {
+ /*
+ * Because val is the same as leaf_cpos (which
+ * is the smallest value this leaf can have),
+ * yet is not equal to insert_hash, then we
+ * know that insert_hash *must* be larger than
+ * val (and leaf_cpos). At least cpos+1 in value.
+ *
+ * We also know then, that there cannot be an
+ * adjacent extent (otherwise we'd be looking
+ * at it). Choosing this value gives us a
+ * chance to get some contiguousness.
+ */
+ *split_hash = leaf_cpos + 1;
+ return 0;
+ }
+
+ if (val > insert_hash) {
+ /*
+ * val can not be the same as insert hash, and
+ * also must be larger than leaf_cpos. Also,
+ * we know that there can't be a leaf between
+ * cpos and val, otherwise the entries with
+ * hash 'val' would be there.
+ */
+ *split_hash = val;
+ return 0;
+ }
+
+ *split_hash = insert_hash;
+ return 0;
+ }
+
+ /*
+ * Since the records are sorted and the checks above
+ * guaranteed that not all records in this block are the same,
+ * we simple travel forward, from the median, and pick the 1st
+ * record whose value is larger than leaf_cpos.
+ */
+ for (i = (num_used / 2); i < num_used; i++)
+ if (le32_to_cpu(dl_list->de_entries[i].dx_major_hash) >
+ leaf_cpos)
+ break;
+
+ BUG_ON(i == num_used); /* Should be impossible */
+ *split_hash = le32_to_cpu(dl_list->de_entries[i].dx_major_hash);
+ return 0;
+}
+
+/*
+ * Transfer all entries in orig_dx_leaves whose major hash is equal to or
+ * larger than split_hash into new_dx_leaves. We use a temporary
+ * buffer (tmp_dx_leaf) to make the changes to the original leaf blocks.
+ *
+ * Since the block offset inside a leaf (cluster) is a constant mask
+ * of minor_hash, we can optimize - an item at block offset X within
+ * the original cluster, will be at offset X within the new cluster.
+ */
+static void ocfs2_dx_dir_transfer_leaf(struct inode *dir, u32 split_hash,
+ handle_t *handle,
+ struct ocfs2_dx_leaf *tmp_dx_leaf,
+ struct buffer_head **orig_dx_leaves,
+ struct buffer_head **new_dx_leaves,
+ int num_dx_leaves)
+{
+ int i, j, num_used;
+ u32 major_hash;
+ struct ocfs2_dx_leaf *orig_dx_leaf, *new_dx_leaf;
+ struct ocfs2_dx_entry_list *orig_list, *new_list, *tmp_list;
+ struct ocfs2_dx_entry *dx_entry;
+
+ tmp_list = &tmp_dx_leaf->dl_list;
+
+ for (i = 0; i < num_dx_leaves; i++) {
+ orig_dx_leaf = (struct ocfs2_dx_leaf *) orig_dx_leaves[i]->b_data;
+ orig_list = &orig_dx_leaf->dl_list;
+ new_dx_leaf = (struct ocfs2_dx_leaf *) new_dx_leaves[i]->b_data;
+ new_list = &new_dx_leaf->dl_list;
+
+ num_used = le16_to_cpu(orig_list->de_num_used);
+
+ memcpy(tmp_dx_leaf, orig_dx_leaf, dir->i_sb->s_blocksize);
+ tmp_list->de_num_used = cpu_to_le16(0);
+ memset(&tmp_list->de_entries, 0, sizeof(*dx_entry)*num_used);
+
+ for (j = 0; j < num_used; j++) {
+ dx_entry = &orig_list->de_entries[j];
+ major_hash = le32_to_cpu(dx_entry->dx_major_hash);
+ if (major_hash >= split_hash)
+ ocfs2_dx_dir_leaf_insert_tail(new_dx_leaf,
+ dx_entry);
+ else
+ ocfs2_dx_dir_leaf_insert_tail(tmp_dx_leaf,
+ dx_entry);
+ }
+ memcpy(orig_dx_leaf, tmp_dx_leaf, dir->i_sb->s_blocksize);
+
+ ocfs2_journal_dirty(handle, orig_dx_leaves[i]);
+ ocfs2_journal_dirty(handle, new_dx_leaves[i]);
+ }
+}
+
+static int ocfs2_dx_dir_rebalance_credits(struct ocfs2_super *osb,
+ struct ocfs2_dx_root_block *dx_root)
+{
+ int credits = ocfs2_clusters_to_blocks(osb->sb, 2);
+
+ credits += ocfs2_calc_extend_credits(osb->sb, &dx_root->dr_list, 1);
+ credits += ocfs2_quota_trans_credits(osb->sb);
+ return credits;
+}
+
+/*
+ * Find the median value in dx_leaf_bh and allocate a new leaf to move
+ * half our entries into.
+ */
+static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir,
+ struct buffer_head *dx_root_bh,
+ struct buffer_head *dx_leaf_bh,
+ struct ocfs2_dx_hinfo *hinfo, u32 leaf_cpos,
+ u64 leaf_blkno)
+{
+ struct ocfs2_dx_leaf *dx_leaf = (struct ocfs2_dx_leaf *)dx_leaf_bh->b_data;
+ int credits, ret, i, num_used, did_quota = 0;
+ u32 cpos, split_hash, insert_hash = hinfo->major_hash;
+ u64 orig_leaves_start;
+ int num_dx_leaves;
+ struct buffer_head **orig_dx_leaves = NULL;
+ struct buffer_head **new_dx_leaves = NULL;
+ struct ocfs2_alloc_context *data_ac = NULL, *meta_ac = NULL;
+ struct ocfs2_extent_tree et;
+ handle_t *handle = NULL;
+ struct ocfs2_dx_root_block *dx_root;
+ struct ocfs2_dx_leaf *tmp_dx_leaf = NULL;
+
+ mlog(0, "DX Dir: %llu, rebalance leaf leaf_blkno: %llu insert: %u\n",
+ (unsigned long long)OCFS2_I(dir)->ip_blkno,
+ (unsigned long long)leaf_blkno, insert_hash);
+
+ ocfs2_init_dx_root_extent_tree(&et, dir, dx_root_bh);
+
+ dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+ /*
+ * XXX: This is a rather large limit. We should use a more
+ * realistic value.
+ */
+ if (le32_to_cpu(dx_root->dr_clusters) == UINT_MAX)
+ return -ENOSPC;
+
+ num_used = le16_to_cpu(dx_leaf->dl_list.de_num_used);
+ if (num_used < le16_to_cpu(dx_leaf->dl_list.de_count)) {
+ mlog(ML_ERROR, "DX Dir: %llu, Asked to rebalance empty leaf: "
+ "%llu, %d\n", (unsigned long long)OCFS2_I(dir)->ip_blkno,
+ (unsigned long long)leaf_blkno, num_used);
+ ret = -EIO;
+ goto out;
+ }
+
+ orig_dx_leaves = ocfs2_dx_dir_kmalloc_leaves(osb->sb, &num_dx_leaves);
+ if (!orig_dx_leaves) {
+ ret = -ENOMEM;
+ mlog_errno(ret);
+ goto out;
+ }
+
+ new_dx_leaves = ocfs2_dx_dir_kmalloc_leaves(osb->sb, NULL);
+ if (!new_dx_leaves) {
+ ret = -ENOMEM;
+ mlog_errno(ret);
+ goto out;
+ }
+
+ ret = ocfs2_lock_allocators(dir, &et, 1, 0, &data_ac, &meta_ac);
+ if (ret) {
+ if (ret != -ENOSPC)
+ mlog_errno(ret);
+ goto out;
+ }
+
+ credits = ocfs2_dx_dir_rebalance_credits(osb, dx_root);
+ handle = ocfs2_start_trans(osb, credits);
+ if (IS_ERR(handle)) {
+ ret = PTR_ERR(handle);
+ handle = NULL;
+ mlog_errno(ret);
+ goto out;
+ }
+
+ if (vfs_dq_alloc_space_nodirty(dir,
+ ocfs2_clusters_to_bytes(dir->i_sb, 1))) {
+ ret = -EDQUOT;
+ goto out_commit;
+ }
+ did_quota = 1;
+
+ ret = ocfs2_journal_access_dl(handle, dir, dx_leaf_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
+ /*
+ * This block is changing anyway, so we can sort it in place.
+ */
+ sort(dx_leaf->dl_list.de_entries, num_used,
+ sizeof(struct ocfs2_dx_entry), dx_leaf_sort_cmp,
+ dx_leaf_sort_swap);
+
+ ret = ocfs2_journal_dirty(handle, dx_leaf_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
+ ret = ocfs2_dx_dir_find_leaf_split(dx_leaf, leaf_cpos, insert_hash,
+ &split_hash);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
+ mlog(0, "Split leaf (%u) at %u, insert major hash is %u\n",
+ leaf_cpos, split_hash, insert_hash);
+
+ /*
+ * We have to carefully order operations here. There are items
+ * which want to be in the new cluster before insert, but in
+ * order to put those items in the new cluster, we alter the
+ * old cluster. A failure to insert gets nasty.
+ *
+ * So, start by reserving writes to the old
+ * cluster. ocfs2_dx_dir_new_cluster will reserve writes on
+ * the new cluster for us, before inserting it. The insert
+ * won't happen if there's an error before that. Once the
+ * insert is done then, we can transfer from one leaf into the
+ * other without fear of hitting any error.
+ */
+
+ /*
+ * The leaf transfer wants some scratch space so that we don't
+ * wind up doing a bunch of expensive memmove().
+ */
+ tmp_dx_leaf = kmalloc(osb->sb->s_blocksize, GFP_NOFS);
+ if (!tmp_dx_leaf) {
+ ret = -ENOMEM;
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
+ orig_leaves_start = ocfs2_block_to_cluster_start(dir->i_sb, leaf_blkno);
+ ret = ocfs2_read_dx_leaves(dir, orig_leaves_start, num_dx_leaves,
+ orig_dx_leaves);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
+ for (i = 0; i < num_dx_leaves; i++) {
+ ret = ocfs2_journal_access_dl(handle, dir, orig_dx_leaves[i],
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+ }
+
+ cpos = split_hash;
+ ret = ocfs2_dx_dir_new_cluster(dir, &et, cpos, handle,
+ data_ac, meta_ac, new_dx_leaves,
+ num_dx_leaves);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
+ ocfs2_dx_dir_transfer_leaf(dir, split_hash, handle, tmp_dx_leaf,
+ orig_dx_leaves, new_dx_leaves, num_dx_leaves);
+
+out_commit:
+ if (ret < 0 && did_quota)
+ vfs_dq_free_space_nodirty(dir,
+ ocfs2_clusters_to_bytes(dir->i_sb, 1));
+
+ ocfs2_commit_trans(osb, handle);
+
+out:
+ if (orig_dx_leaves || new_dx_leaves) {
+ for (i = 0; i < num_dx_leaves; i++) {
+ if (orig_dx_leaves)
+ brelse(orig_dx_leaves[i]);
+ if (new_dx_leaves)
+ brelse(new_dx_leaves[i]);
+ }
+ kfree(orig_dx_leaves);
+ kfree(new_dx_leaves);
+ }
+
+ if (meta_ac)
+ ocfs2_free_alloc_context(meta_ac);
+ if (data_ac)
+ ocfs2_free_alloc_context(data_ac);
+
+ kfree(tmp_dx_leaf);
+ return ret;
+}
+
+static int ocfs2_find_dir_space_dx(struct ocfs2_super *osb, struct inode *dir,
+ struct buffer_head *di_bh,
+ struct buffer_head *dx_root_bh,
+ const char *name, int namelen,
+ struct ocfs2_dir_lookup_result *lookup)
+{
+ int ret, rebalanced = 0;
+ struct ocfs2_dx_root_block *dx_root;
+ struct buffer_head *dx_leaf_bh = NULL;
+ struct ocfs2_dx_leaf *dx_leaf;
+ u64 blkno;
+ u32 leaf_cpos;
+
+ dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+
+restart_search:
+ ret = ocfs2_dx_dir_lookup(dir, &dx_root->dr_list, &lookup->dl_hinfo,
+ &leaf_cpos, &blkno);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ ret = ocfs2_read_dx_leaf(dir, blkno, &dx_leaf_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ dx_leaf = (struct ocfs2_dx_leaf *)dx_leaf_bh->b_data;
+
+ if (le16_to_cpu(dx_leaf->dl_list.de_num_used) >=
+ le16_to_cpu(dx_leaf->dl_list.de_count)) {
+ if (rebalanced) {
+ /*
+ * Rebalancing should have provided us with
+ * space in an appropriate leaf.
+ *
+ * XXX: Is this an abnormal condition then?
+ * Should we print a message here?
+ */
+ ret = -ENOSPC;
+ goto out;
+ }
+
+ ret = ocfs2_dx_dir_rebalance(osb, dir, dx_root_bh, dx_leaf_bh,
+ &lookup->dl_hinfo, leaf_cpos,
+ blkno);
+ if (ret) {
+ if (ret != -ENOSPC)
+ mlog_errno(ret);
+ goto out;
+ }
+
+ /*
+ * Restart the lookup. The rebalance might have
+ * changed which block our item fits into. Mark our
+ * progress, so we only execute this once.
+ */
+ brelse(dx_leaf_bh);
+ dx_leaf_bh = NULL;
+ rebalanced = 1;
+ goto restart_search;
+ }
+
+ lookup->dl_dx_leaf_bh = dx_leaf_bh;
+ dx_leaf_bh = NULL;
+
+out:
+ brelse(dx_leaf_bh);
+ return ret;
+}
+
+static int ocfs2_search_dx_free_list(struct inode *dir,
+ struct buffer_head *dx_root_bh,
+ int namelen,
+ struct ocfs2_dir_lookup_result *lookup)
+{
+ int ret = -ENOSPC;
+ struct buffer_head *leaf_bh = NULL, *prev_leaf_bh = NULL;
+ struct ocfs2_dir_block_trailer *db;
+ u64 next_block;
+ int rec_len = OCFS2_DIR_REC_LEN(namelen);
+ struct ocfs2_dx_root_block *dx_root;
+
+ dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+ next_block = le64_to_cpu(dx_root->dr_free_blk);
+
+ while (next_block) {
+ brelse(prev_leaf_bh);
+ prev_leaf_bh = leaf_bh;
+ leaf_bh = NULL;
+
+ ret = ocfs2_read_dir_block_direct(dir, next_block, &leaf_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ db = ocfs2_trailer_from_bh(leaf_bh, dir->i_sb);
+ if (rec_len <= le16_to_cpu(db->db_free_rec_len)) {
+ lookup->dl_leaf_bh = leaf_bh;
+ lookup->dl_prev_leaf_bh = prev_leaf_bh;
+ leaf_bh = NULL;
+ prev_leaf_bh = NULL;
+ break;
+ }
+
+ next_block = le64_to_cpu(db->db_free_next);
+ }
+
+ if (!next_block)
+ ret = -ENOSPC;
+
+out:
+
+ brelse(leaf_bh);
+ brelse(prev_leaf_bh);
+ return ret;
+}
+
+static int ocfs2_expand_inline_dx_root(struct inode *dir,
+ struct buffer_head *dx_root_bh)
+{
+ int ret, num_dx_leaves, i, j, did_quota = 0;
+ struct buffer_head **dx_leaves = NULL;
+ struct ocfs2_extent_tree et;
+ u64 insert_blkno;
+ struct ocfs2_alloc_context *data_ac = NULL;
+ struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+ handle_t *handle = NULL;
+ struct ocfs2_dx_root_block *dx_root;
+ struct ocfs2_dx_entry_list *entry_list;
+ struct ocfs2_dx_entry *dx_entry;
+ struct ocfs2_dx_leaf *target_leaf;
+
+ ret = ocfs2_reserve_clusters(osb, 1, &data_ac);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ dx_leaves = ocfs2_dx_dir_kmalloc_leaves(osb->sb, &num_dx_leaves);
+ if (!dx_leaves) {
+ ret = -ENOMEM;
+ mlog_errno(ret);
+ goto out;
+ }
+
+ handle = ocfs2_start_trans(osb, ocfs2_calc_dxi_expand_credits(osb->sb));
+ if (IS_ERR(handle)) {
+ ret = PTR_ERR(handle);
+ mlog_errno(ret);
+ goto out;
+ }
+
+ if (vfs_dq_alloc_space_nodirty(dir,
+ ocfs2_clusters_to_bytes(osb->sb, 1))) {
+ ret = -EDQUOT;
+ goto out_commit;
+ }
+ did_quota = 1;
+
+ /*
+ * We do this up front, before the allocation, so that a
+ * failure to add the dx_root_bh to the journal won't result
+ * us losing clusters.
+ */
+ ret = ocfs2_journal_access_dr(handle, dir, dx_root_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
+ ret = __ocfs2_dx_dir_new_cluster(dir, 0, handle, data_ac, dx_leaves,
+ num_dx_leaves, &insert_blkno);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
+ /*
+ * Transfer the entries from our dx_root into the appropriate
+ * block
+ */
+ dx_root = (struct ocfs2_dx_root_block *) dx_root_bh->b_data;
+ entry_list = &dx_root->dr_entries;
+
+ for (i = 0; i < le16_to_cpu(entry_list->de_num_used); i++) {
+ dx_entry = &entry_list->de_entries[i];
+
+ j = __ocfs2_dx_dir_hash_idx(osb,
+ le32_to_cpu(dx_entry->dx_minor_hash));
+ target_leaf = (struct ocfs2_dx_leaf *)dx_leaves[j]->b_data;
+
+ ocfs2_dx_dir_leaf_insert_tail(target_leaf, dx_entry);
+
+ /* Each leaf has been passed to the journal already
+ * via __ocfs2_dx_dir_new_cluster() */
+ }
+
+ dx_root->dr_flags &= ~OCFS2_DX_FLAG_INLINE;
+ memset(&dx_root->dr_list, 0, osb->sb->s_blocksize -
+ offsetof(struct ocfs2_dx_root_block, dr_list));
+ dx_root->dr_list.l_count =
+ cpu_to_le16(ocfs2_extent_recs_per_dx_root(osb->sb));
+
+ /* This should never fail considering we start with an empty
+ * dx_root. */
+ ocfs2_init_dx_root_extent_tree(&et, dir, dx_root_bh);
+ ret = ocfs2_insert_extent(osb, handle, dir, &et, 0,
+ insert_blkno, 1, 0, NULL);
+ if (ret)
+ mlog_errno(ret);
+ did_quota = 0;
+
+ ocfs2_journal_dirty(handle, dx_root_bh);
+
+out_commit:
+ if (ret < 0 && did_quota)
+ vfs_dq_free_space_nodirty(dir,
+ ocfs2_clusters_to_bytes(dir->i_sb, 1));
+
+ ocfs2_commit_trans(osb, handle);
+
+out:
+ if (data_ac)
+ ocfs2_free_alloc_context(data_ac);
+
+ if (dx_leaves) {
+ for (i = 0; i < num_dx_leaves; i++)
+ brelse(dx_leaves[i]);
+ kfree(dx_leaves);
+ }
+ return ret;
+}
+
+static int ocfs2_inline_dx_has_space(struct buffer_head *dx_root_bh)
+{
+ struct ocfs2_dx_root_block *dx_root;
+ struct ocfs2_dx_entry_list *entry_list;
+
+ dx_root = (struct ocfs2_dx_root_block *) dx_root_bh->b_data;
+ entry_list = &dx_root->dr_entries;
+
+ if (le16_to_cpu(entry_list->de_num_used) >=
+ le16_to_cpu(entry_list->de_count))
+ return -ENOSPC;
+
+ return 0;
+}
+
+static int ocfs2_prepare_dx_dir_for_insert(struct inode *dir,
+ struct buffer_head *di_bh,
+ const char *name,
+ int namelen,
+ struct ocfs2_dir_lookup_result *lookup)
+{
+ int ret, free_dx_root = 1;
+ struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+ struct buffer_head *dx_root_bh = NULL;
+ struct buffer_head *leaf_bh = NULL;
+ struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
+ struct ocfs2_dx_root_block *dx_root;
+
+ ret = ocfs2_read_dx_root(dir, di, &dx_root_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+ if (le32_to_cpu(dx_root->dr_num_entries) == OCFS2_DX_ENTRIES_MAX) {
+ ret = -ENOSPC;
+ mlog_errno(ret);
+ goto out;
+ }
+
+ if (ocfs2_dx_root_inline(dx_root)) {
+ ret = ocfs2_inline_dx_has_space(dx_root_bh);
+
+ if (ret == 0)
+ goto search_el;
+
+ /*
+ * We ran out of room in the root block. Expand it to
+ * an extent, then allow ocfs2_find_dir_space_dx to do
+ * the rest.
+ */
+ ret = ocfs2_expand_inline_dx_root(dir, dx_root_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+ }
+
+ /*
+ * Insert preparation for an indexed directory is split into two
+ * steps. The call to find_dir_space_dx reserves room in the index for
+ * an additional item. If we run out of space there, it's a real error
+ * we can't continue on.
+ */
+ ret = ocfs2_find_dir_space_dx(osb, dir, di_bh, dx_root_bh, name,
+ namelen, lookup);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+search_el:
+ /*
+ * Next, we need to find space in the unindexed tree. This call
+ * searches using the free space linked list. If the unindexed tree
+ * lacks sufficient space, we'll expand it below. The expansion code
+ * is smart enough to add any new blocks to the free space list.
+ */
+ ret = ocfs2_search_dx_free_list(dir, dx_root_bh, namelen, lookup);
+ if (ret && ret != -ENOSPC) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ /* Do this up here - ocfs2_extend_dir might need the dx_root */
+ lookup->dl_dx_root_bh = dx_root_bh;
+ free_dx_root = 0;
+
+ if (ret == -ENOSPC) {
+ ret = ocfs2_extend_dir(osb, dir, di_bh, 1, lookup, &leaf_bh);
+
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ /*
+ * We make the assumption here that new leaf blocks are added
+ * to the front of our free list.
+ */
+ lookup->dl_prev_leaf_bh = NULL;
+ lookup->dl_leaf_bh = leaf_bh;
+ }
+
+out:
+ if (free_dx_root)
+ brelse(dx_root_bh);
+ return ret;
+}
+
+/*
+ * Get a directory ready for insert. Any directory allocation required
+ * happens here. Success returns zero, and enough context in the dir
+ * lookup result that ocfs2_add_entry() will be able complete the task
+ * with minimal performance impact.
+ */
int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
struct inode *dir,
struct buffer_head *parent_fe_bh,
const char *name,
int namelen,
- struct buffer_head **ret_de_bh)
+ struct ocfs2_dir_lookup_result *lookup)
{
int ret;
unsigned int blocks_wanted = 1;
@@ -1984,14 +4367,34 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
mlog(0, "getting ready to insert namelen %d into dir %llu\n",
namelen, (unsigned long long)OCFS2_I(dir)->ip_blkno);
- *ret_de_bh = NULL;
-
if (!namelen) {
ret = -EINVAL;
mlog_errno(ret);
goto out;
}
+ /*
+ * Do this up front to reduce confusion.
+ *
+ * The directory might start inline, then be turned into an
+ * indexed one, in which case we'd need to hash deep inside
+ * ocfs2_find_dir_space_id(). Since
+ * ocfs2_prepare_dx_dir_for_insert() also needs this hash
+ * done, there seems no point in spreading out the calls. We
+ * can optimize away the case where the file system doesn't
+ * support indexing.
+ */
+ if (ocfs2_supports_indexed_dirs(osb))
+ ocfs2_dx_dir_name_hash(dir, name, namelen, &lookup->dl_hinfo);
+
+ if (ocfs2_dir_indexed(dir)) {
+ ret = ocfs2_prepare_dx_dir_for_insert(dir, parent_fe_bh,
+ name, namelen, lookup);
+ if (ret)
+ mlog_errno(ret);
+ goto out;
+ }
+
if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
ret = ocfs2_find_dir_space_id(dir, parent_fe_bh, name,
namelen, &bh, &blocks_wanted);
@@ -2010,7 +4413,7 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
BUG_ON(bh);
ret = ocfs2_extend_dir(osb, dir, parent_fe_bh, blocks_wanted,
- &bh);
+ lookup, &bh);
if (ret) {
if (ret != -ENOSPC)
mlog_errno(ret);
@@ -2020,9 +4423,154 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
BUG_ON(!bh);
}
- *ret_de_bh = bh;
+ lookup->dl_leaf_bh = bh;
bh = NULL;
out:
brelse(bh);
return ret;
}
+
+static int ocfs2_dx_dir_remove_index(struct inode *dir,
+ struct buffer_head *di_bh,
+ struct buffer_head *dx_root_bh)
+{
+ int ret;
+ struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+ struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
+ struct ocfs2_dx_root_block *dx_root;
+ struct inode *dx_alloc_inode = NULL;
+ struct buffer_head *dx_alloc_bh = NULL;
+ handle_t *handle;
+ u64 blk;
+ u16 bit;
+ u64 bg_blkno;
+
+ dx_root = (struct ocfs2_dx_root_block *) dx_root_bh->b_data;
+
+ dx_alloc_inode = ocfs2_get_system_file_inode(osb,
+ EXTENT_ALLOC_SYSTEM_INODE,
+ le16_to_cpu(dx_root->dr_suballoc_slot));
+ if (!dx_alloc_inode) {
+ ret = -ENOMEM;
+ mlog_errno(ret);
+ goto out;
+ }
+ mutex_lock(&dx_alloc_inode->i_mutex);
+
+ ret = ocfs2_inode_lock(dx_alloc_inode, &dx_alloc_bh, 1);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_mutex;
+ }
+
+ handle = ocfs2_start_trans(osb, OCFS2_DX_ROOT_REMOVE_CREDITS);
+ if (IS_ERR(handle)) {
+ ret = PTR_ERR(handle);
+ mlog_errno(ret);
+ goto out_unlock;
+ }
+
+ ret = ocfs2_journal_access_di(handle, dir, di_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
+ OCFS2_I(dir)->ip_dyn_features &= ~OCFS2_INDEXED_DIR_FL;
+ di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features);
+ di->i_dx_root = cpu_to_le64(0ULL);
+
+ ocfs2_journal_dirty(handle, di_bh);
+
+ blk = le64_to_cpu(dx_root->dr_blkno);
+ bit = le16_to_cpu(dx_root->dr_suballoc_bit);
+ bg_blkno = ocfs2_which_suballoc_group(blk, bit);
+ ret = ocfs2_free_suballoc_bits(handle, dx_alloc_inode, dx_alloc_bh,
+ bit, bg_blkno, 1);
+ if (ret)
+ mlog_errno(ret);
+
+out_commit:
+ ocfs2_commit_trans(osb, handle);
+
+out_unlock:
+ ocfs2_inode_unlock(dx_alloc_inode, 1);
+
+out_mutex:
+ mutex_unlock(&dx_alloc_inode->i_mutex);
+ brelse(dx_alloc_bh);
+out:
+ iput(dx_alloc_inode);
+ return ret;
+}
+
+int ocfs2_dx_dir_truncate(struct inode *dir, struct buffer_head *di_bh)
+{
+ int ret;
+ unsigned int uninitialized_var(clen);
+ u32 major_hash = UINT_MAX, p_cpos, uninitialized_var(cpos);
+ u64 uninitialized_var(blkno);
+ struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+ struct buffer_head *dx_root_bh = NULL;
+ struct ocfs2_dx_root_block *dx_root;
+ struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
+ struct ocfs2_cached_dealloc_ctxt dealloc;
+ struct ocfs2_extent_tree et;
+
+ ocfs2_init_dealloc_ctxt(&dealloc);
+
+ if (!ocfs2_dir_indexed(dir))
+ return 0;
+
+ ret = ocfs2_read_dx_root(dir, di, &dx_root_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+ dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+
+ if (ocfs2_dx_root_inline(dx_root))
+ goto remove_index;
+
+ ocfs2_init_dx_root_extent_tree(&et, dir, dx_root_bh);
+
+ /* XXX: What if dr_clusters is too large? */
+ while (le32_to_cpu(dx_root->dr_clusters)) {
+ ret = ocfs2_dx_dir_lookup_rec(dir, &dx_root->dr_list,
+ major_hash, &cpos, &blkno, &clen);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ p_cpos = ocfs2_blocks_to_clusters(dir->i_sb, blkno);
+
+ ret = ocfs2_remove_btree_range(dir, &et, cpos, p_cpos, clen,
+ &dealloc);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ if (cpos == 0)
+ break;
+
+ major_hash = cpos - 1;
+ }
+
+remove_index:
+ ret = ocfs2_dx_dir_remove_index(dir, di_bh, dx_root_bh);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ ocfs2_remove_from_cache(dir, dx_root_bh);
+out:
+ ocfs2_schedule_truncate_log_flush(osb, 1);
+ ocfs2_run_deallocs(osb, &dealloc);
+
+ brelse(dx_root_bh);
+ return ret;
+}
diff --git a/fs/ocfs2/dir.h b/fs/ocfs2/dir.h
index c511e2e18e9..e683f3deb64 100644
--- a/fs/ocfs2/dir.h
+++ b/fs/ocfs2/dir.h
@@ -26,44 +26,70 @@
#ifndef OCFS2_DIR_H
#define OCFS2_DIR_H
-struct buffer_head *ocfs2_find_entry(const char *name,
- int namelen,
- struct inode *dir,
- struct ocfs2_dir_entry **res_dir);
+struct ocfs2_dx_hinfo {
+ u32 major_hash;
+ u32 minor_hash;
+};
+
+struct ocfs2_dir_lookup_result {
+ struct buffer_head *dl_leaf_bh; /* Unindexed leaf
+ * block */
+ struct ocfs2_dir_entry *dl_entry; /* Target dirent in
+ * unindexed leaf */
+
+ struct buffer_head *dl_dx_root_bh; /* Root of indexed
+ * tree */
+
+ struct buffer_head *dl_dx_leaf_bh; /* Indexed leaf block */
+ struct ocfs2_dx_entry *dl_dx_entry; /* Target dx_entry in
+ * indexed leaf */
+ struct ocfs2_dx_hinfo dl_hinfo; /* Name hash results */
+
+ struct buffer_head *dl_prev_leaf_bh;/* Previous entry in
+ * dir free space
+ * list. NULL if
+ * previous entry is
+ * dx root block. */
+};
+
+void ocfs2_free_dir_lookup_result(struct ocfs2_dir_lookup_result *res);
+
+int ocfs2_find_entry(const char *name, int namelen,
+ struct inode *dir,
+ struct ocfs2_dir_lookup_result *lookup);
int ocfs2_delete_entry(handle_t *handle,
struct inode *dir,
- struct ocfs2_dir_entry *de_del,
- struct buffer_head *bh);
+ struct ocfs2_dir_lookup_result *res);
int __ocfs2_add_entry(handle_t *handle,
struct inode *dir,
const char *name, int namelen,
struct inode *inode, u64 blkno,
struct buffer_head *parent_fe_bh,
- struct buffer_head *insert_bh);
+ struct ocfs2_dir_lookup_result *lookup);
static inline int ocfs2_add_entry(handle_t *handle,
struct dentry *dentry,
struct inode *inode, u64 blkno,
struct buffer_head *parent_fe_bh,
- struct buffer_head *insert_bh)
+ struct ocfs2_dir_lookup_result *lookup)
{
return __ocfs2_add_entry(handle, dentry->d_parent->d_inode,
dentry->d_name.name, dentry->d_name.len,
- inode, blkno, parent_fe_bh, insert_bh);
+ inode, blkno, parent_fe_bh, lookup);
}
int ocfs2_update_entry(struct inode *dir, handle_t *handle,
- struct buffer_head *de_bh, struct ocfs2_dir_entry *de,
+ struct ocfs2_dir_lookup_result *res,
struct inode *new_entry_inode);
int ocfs2_check_dir_for_entry(struct inode *dir,
const char *name,
int namelen);
int ocfs2_empty_dir(struct inode *inode);
+
int ocfs2_find_files_on_disk(const char *name,
int namelen,
u64 *blkno,
struct inode *inode,
- struct buffer_head **dirent_bh,
- struct ocfs2_dir_entry **dirent);
+ struct ocfs2_dir_lookup_result *res);
int ocfs2_lookup_ino_from_name(struct inode *dir, const char *name,
int namelen, u64 *blkno);
int ocfs2_readdir(struct file *filp, void *dirent, filldir_t filldir);
@@ -74,14 +100,17 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
struct buffer_head *parent_fe_bh,
const char *name,
int namelen,
- struct buffer_head **ret_de_bh);
+ struct ocfs2_dir_lookup_result *lookup);
struct ocfs2_alloc_context;
int ocfs2_fill_new_dir(struct ocfs2_super *osb,
handle_t *handle,
struct inode *parent,
struct inode *inode,
struct buffer_head *fe_bh,
- struct ocfs2_alloc_context *data_ac);
+ struct ocfs2_alloc_context *data_ac,
+ struct ocfs2_alloc_context *meta_ac);
+
+int ocfs2_dx_dir_truncate(struct inode *dir, struct buffer_head *di_bh);
struct ocfs2_dir_block_trailer *ocfs2_dir_trailer_from_size(int blocksize,
void *data);
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index bb53714813a..0102be35980 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -52,16 +52,12 @@
enum dlm_mle_type {
DLM_MLE_BLOCK,
DLM_MLE_MASTER,
- DLM_MLE_MIGRATION
-};
-
-struct dlm_lock_name {
- u8 len;
- u8 name[DLM_LOCKID_NAME_MAX];
+ DLM_MLE_MIGRATION,
+ DLM_MLE_NUM_TYPES
};
struct dlm_master_list_entry {
- struct list_head list;
+ struct hlist_node master_hash_node;
struct list_head hb_events;
struct dlm_ctxt *dlm;
spinlock_t spinlock;
@@ -78,10 +74,10 @@ struct dlm_master_list_entry {
enum dlm_mle_type type;
struct o2hb_callback_func mle_hb_up;
struct o2hb_callback_func mle_hb_down;
- union {
- struct dlm_lock_resource *res;
- struct dlm_lock_name name;
- } u;
+ struct dlm_lock_resource *mleres;
+ unsigned char mname[DLM_LOCKID_NAME_MAX];
+ unsigned int mnamelen;
+ unsigned int mnamehash;
};
enum dlm_ast_type {
@@ -151,13 +147,14 @@ struct dlm_ctxt
unsigned long recovery_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
struct dlm_recovery_ctxt reco;
spinlock_t master_lock;
- struct list_head master_list;
+ struct hlist_head **master_hash;
struct list_head mle_hb_events;
/* these give a really vague idea of the system load */
- atomic_t local_resources;
- atomic_t remote_resources;
- atomic_t unknown_resources;
+ atomic_t mle_tot_count[DLM_MLE_NUM_TYPES];
+ atomic_t mle_cur_count[DLM_MLE_NUM_TYPES];
+ atomic_t res_tot_count;
+ atomic_t res_cur_count;
struct dlm_debug_ctxt *dlm_debug_ctxt;
struct dentry *dlm_debugfs_subroot;
@@ -195,6 +192,13 @@ static inline struct hlist_head *dlm_lockres_hash(struct dlm_ctxt *dlm, unsigned
return dlm->lockres_hash[(i / DLM_BUCKETS_PER_PAGE) % DLM_HASH_PAGES] + (i % DLM_BUCKETS_PER_PAGE);
}
+static inline struct hlist_head *dlm_master_hash(struct dlm_ctxt *dlm,
+ unsigned i)
+{
+ return dlm->master_hash[(i / DLM_BUCKETS_PER_PAGE) % DLM_HASH_PAGES] +
+ (i % DLM_BUCKETS_PER_PAGE);
+}
+
/* these keventd work queue items are for less-frequently
* called functions that cannot be directly called from the
* net message handlers for some reason, usually because
@@ -848,9 +852,7 @@ struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm,
unsigned int len);
int dlm_is_host_down(int errno);
-void dlm_change_lockres_owner(struct dlm_ctxt *dlm,
- struct dlm_lock_resource *res,
- u8 owner);
+
struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm,
const char *lockid,
int namelen,
@@ -1008,6 +1010,9 @@ static inline void __dlm_wait_on_lockres(struct dlm_lock_resource *res)
DLM_LOCK_RES_MIGRATING));
}
+void __dlm_unlink_mle(struct dlm_ctxt *dlm, struct dlm_master_list_entry *mle);
+void __dlm_insert_mle(struct dlm_ctxt *dlm, struct dlm_master_list_entry *mle);
+
/* create/destroy slab caches */
int dlm_init_master_caches(void);
void dlm_destroy_master_caches(void);
@@ -1110,6 +1115,23 @@ static inline int dlm_node_iter_next(struct dlm_node_iter *iter)
return bit;
}
+static inline void dlm_set_lockres_owner(struct dlm_ctxt *dlm,
+ struct dlm_lock_resource *res,
+ u8 owner)
+{
+ assert_spin_locked(&res->spinlock);
+
+ res->owner = owner;
+}
+static inline void dlm_change_lockres_owner(struct dlm_ctxt *dlm,
+ struct dlm_lock_resource *res,
+ u8 owner)
+{
+ assert_spin_locked(&res->spinlock);
+
+ if (owner != res->owner)
+ dlm_set_lockres_owner(dlm, res, owner);
+}
#endif /* DLMCOMMON_H */
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index b32f60a5acf..df52f706f66 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -287,18 +287,8 @@ static int stringify_nodemap(unsigned long *nodemap, int maxnodes,
static int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len)
{
int out = 0;
- unsigned int namelen;
- const char *name;
char *mle_type;
- if (mle->type != DLM_MLE_MASTER) {
- namelen = mle->u.name.len;
- name = mle->u.name.name;
- } else {
- namelen = mle->u.res->lockname.len;
- name = mle->u.res->lockname.name;
- }
-
if (mle->type == DLM_MLE_BLOCK)
mle_type = "BLK";
else if (mle->type == DLM_MLE_MASTER)
@@ -306,7 +296,7 @@ static int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len)
else
mle_type = "MIG";
- out += stringify_lockname(name, namelen, buf + out, len - out);
+ out += stringify_lockname(mle->mname, mle->mnamelen, buf + out, len - out);
out += snprintf(buf + out, len - out,
"\t%3s\tmas=%3u\tnew=%3u\tevt=%1d\tuse=%1d\tref=%3d\n",
mle_type, mle->master, mle->new_master,
@@ -501,23 +491,33 @@ static struct file_operations debug_purgelist_fops = {
static int debug_mle_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
{
struct dlm_master_list_entry *mle;
- int out = 0;
- unsigned long total = 0;
+ struct hlist_head *bucket;
+ struct hlist_node *list;
+ int i, out = 0;
+ unsigned long total = 0, longest = 0, bktcnt;
out += snprintf(db->buf + out, db->len - out,
"Dumping MLEs for Domain: %s\n", dlm->name);
spin_lock(&dlm->master_lock);
- list_for_each_entry(mle, &dlm->master_list, list) {
- ++total;
- if (db->len - out < 200)
- continue;
- out += dump_mle(mle, db->buf + out, db->len - out);
+ for (i = 0; i < DLM_HASH_BUCKETS; i++) {
+ bucket = dlm_master_hash(dlm, i);
+ hlist_for_each(list, bucket) {
+ mle = hlist_entry(list, struct dlm_master_list_entry,
+ master_hash_node);
+ ++total;
+ ++bktcnt;
+ if (db->len - out < 200)
+ continue;
+ out += dump_mle(mle, db->buf + out, db->len - out);
+ }
+ longest = max(longest, bktcnt);
+ bktcnt = 0;
}
spin_unlock(&dlm->master_lock);
out += snprintf(db->buf + out, db->len - out,
- "Total on list: %ld\n", total);
+ "Total: %ld, Longest: %ld\n", total, longest);
return out;
}
@@ -756,12 +756,8 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
int out = 0;
struct dlm_reco_node_data *node;
char *state;
- int lres, rres, ures, tres;
-
- lres = atomic_read(&dlm->local_resources);
- rres = atomic_read(&dlm->remote_resources);
- ures = atomic_read(&dlm->unknown_resources);
- tres = lres + rres + ures;
+ int cur_mles = 0, tot_mles = 0;
+ int i;
spin_lock(&dlm->spinlock);
@@ -804,21 +800,48 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
db->buf + out, db->len - out);
out += snprintf(db->buf + out, db->len - out, "\n");
- /* Mastered Resources Total: xxx Locally: xxx Remotely: ... */
+ /* Lock Resources: xxx (xxx) */
+ out += snprintf(db->buf + out, db->len - out,
+ "Lock Resources: %d (%d)\n",
+ atomic_read(&dlm->res_cur_count),
+ atomic_read(&dlm->res_tot_count));
+
+ for (i = 0; i < DLM_MLE_NUM_TYPES; ++i)
+ tot_mles += atomic_read(&dlm->mle_tot_count[i]);
+
+ for (i = 0; i < DLM_MLE_NUM_TYPES; ++i)
+ cur_mles += atomic_read(&dlm->mle_cur_count[i]);
+
+ /* MLEs: xxx (xxx) */
+ out += snprintf(db->buf + out, db->len - out,
+ "MLEs: %d (%d)\n", cur_mles, tot_mles);
+
+ /* Blocking: xxx (xxx) */
+ out += snprintf(db->buf + out, db->len - out,
+ " Blocking: %d (%d)\n",
+ atomic_read(&dlm->mle_cur_count[DLM_MLE_BLOCK]),
+ atomic_read(&dlm->mle_tot_count[DLM_MLE_BLOCK]));
+
+ /* Mastery: xxx (xxx) */
+ out += snprintf(db->buf + out, db->len - out,
+ " Mastery: %d (%d)\n",
+ atomic_read(&dlm->mle_cur_count[DLM_MLE_MASTER]),
+ atomic_read(&dlm->mle_tot_count[DLM_MLE_MASTER]));
+
+ /* Migration: xxx (xxx) */
out += snprintf(db->buf + out, db->len - out,
- "Mastered Resources Total: %d Locally: %d "
- "Remotely: %d Unknown: %d\n",
- tres, lres, rres, ures);
+ " Migration: %d (%d)\n",
+ atomic_read(&dlm->mle_cur_count[DLM_MLE_MIGRATION]),
+ atomic_read(&dlm->mle_tot_count[DLM_MLE_MIGRATION]));
/* Lists: Dirty=Empty Purge=InUse PendingASTs=Empty ... */
out += snprintf(db->buf + out, db->len - out,
"Lists: Dirty=%s Purge=%s PendingASTs=%s "
- "PendingBASTs=%s Master=%s\n",
+ "PendingBASTs=%s\n",
(list_empty(&dlm->dirty_list) ? "Empty" : "InUse"),
(list_empty(&dlm->purge_list) ? "Empty" : "InUse"),
(list_empty(&dlm->pending_asts) ? "Empty" : "InUse"),
- (list_empty(&dlm->pending_basts) ? "Empty" : "InUse"),
- (list_empty(&dlm->master_list) ? "Empty" : "InUse"));
+ (list_empty(&dlm->pending_basts) ? "Empty" : "InUse"));
/* Purge Count: xxx Refs: xxx */
out += snprintf(db->buf + out, db->len - out,
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index d8d578f4561..4d9e6b288dd 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -304,6 +304,9 @@ static void dlm_free_ctxt_mem(struct dlm_ctxt *dlm)
if (dlm->lockres_hash)
dlm_free_pagevec((void **)dlm->lockres_hash, DLM_HASH_PAGES);
+ if (dlm->master_hash)
+ dlm_free_pagevec((void **)dlm->master_hash, DLM_HASH_PAGES);
+
if (dlm->name)
kfree(dlm->name);
@@ -1534,12 +1537,27 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
for (i = 0; i < DLM_HASH_BUCKETS; i++)
INIT_HLIST_HEAD(dlm_lockres_hash(dlm, i));
+ dlm->master_hash = (struct hlist_head **)
+ dlm_alloc_pagevec(DLM_HASH_PAGES);
+ if (!dlm->master_hash) {
+ mlog_errno(-ENOMEM);
+ dlm_free_pagevec((void **)dlm->lockres_hash, DLM_HASH_PAGES);
+ kfree(dlm->name);
+ kfree(dlm);
+ dlm = NULL;
+ goto leave;
+ }
+
+ for (i = 0; i < DLM_HASH_BUCKETS; i++)
+ INIT_HLIST_HEAD(dlm_master_hash(dlm, i));
+
strcpy(dlm->name, domain);
dlm->key = key;
dlm->node_num = o2nm_this_node();
ret = dlm_create_debugfs_subroot(dlm);
if (ret < 0) {
+ dlm_free_pagevec((void **)dlm->master_hash, DLM_HASH_PAGES);
dlm_free_pagevec((void **)dlm->lockres_hash, DLM_HASH_PAGES);
kfree(dlm->name);
kfree(dlm);
@@ -1579,7 +1597,6 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
init_waitqueue_head(&dlm->reco.event);
init_waitqueue_head(&dlm->ast_wq);
init_waitqueue_head(&dlm->migration_wq);
- INIT_LIST_HEAD(&dlm->master_list);
INIT_LIST_HEAD(&dlm->mle_hb_events);
dlm->joining_node = DLM_LOCK_RES_OWNER_UNKNOWN;
@@ -1587,9 +1604,13 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
dlm->reco.new_master = O2NM_INVALID_NODE_NUM;
dlm->reco.dead_node = O2NM_INVALID_NODE_NUM;
- atomic_set(&dlm->local_resources, 0);
- atomic_set(&dlm->remote_resources, 0);
- atomic_set(&dlm->unknown_resources, 0);
+
+ atomic_set(&dlm->res_tot_count, 0);
+ atomic_set(&dlm->res_cur_count, 0);
+ for (i = 0; i < DLM_MLE_NUM_TYPES; ++i) {
+ atomic_set(&dlm->mle_tot_count[i], 0);
+ atomic_set(&dlm->mle_cur_count[i], 0);
+ }
spin_lock_init(&dlm->work_lock);
INIT_LIST_HEAD(&dlm->work_list);
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 0a281394785..f8b653fcd4d 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -73,22 +73,13 @@ static inline int dlm_mle_equal(struct dlm_ctxt *dlm,
const char *name,
unsigned int namelen)
{
- struct dlm_lock_resource *res;
-
if (dlm != mle->dlm)
return 0;
- if (mle->type == DLM_MLE_BLOCK ||
- mle->type == DLM_MLE_MIGRATION) {
- if (namelen != mle->u.name.len ||
- memcmp(name, mle->u.name.name, namelen)!=0)
- return 0;
- } else {
- res = mle->u.res;
- if (namelen != res->lockname.len ||
- memcmp(res->lockname.name, name, namelen) != 0)
- return 0;
- }
+ if (namelen != mle->mnamelen ||
+ memcmp(name, mle->mname, namelen) != 0)
+ return 0;
+
return 1;
}
@@ -283,7 +274,7 @@ static void dlm_init_mle(struct dlm_master_list_entry *mle,
mle->dlm = dlm;
mle->type = type;
- INIT_LIST_HEAD(&mle->list);
+ INIT_HLIST_NODE(&mle->master_hash_node);
INIT_LIST_HEAD(&mle->hb_events);
memset(mle->maybe_map, 0, sizeof(mle->maybe_map));
spin_lock_init(&mle->spinlock);
@@ -295,19 +286,27 @@ static void dlm_init_mle(struct dlm_master_list_entry *mle,
mle->new_master = O2NM_MAX_NODES;
mle->inuse = 0;
+ BUG_ON(mle->type != DLM_MLE_BLOCK &&
+ mle->type != DLM_MLE_MASTER &&
+ mle->type != DLM_MLE_MIGRATION);
+
if (mle->type == DLM_MLE_MASTER) {
BUG_ON(!res);
- mle->u.res = res;
- } else if (mle->type == DLM_MLE_BLOCK) {
- BUG_ON(!name);
- memcpy(mle->u.name.name, name, namelen);
- mle->u.name.len = namelen;
- } else /* DLM_MLE_MIGRATION */ {
+ mle->mleres = res;
+ memcpy(mle->mname, res->lockname.name, res->lockname.len);
+ mle->mnamelen = res->lockname.len;
+ mle->mnamehash = res->lockname.hash;
+ } else {
BUG_ON(!name);
- memcpy(mle->u.name.name, name, namelen);
- mle->u.name.len = namelen;
+ mle->mleres = NULL;
+ memcpy(mle->mname, name, namelen);
+ mle->mnamelen = namelen;
+ mle->mnamehash = dlm_lockid_hash(name, namelen);
}
+ atomic_inc(&dlm->mle_tot_count[mle->type]);
+ atomic_inc(&dlm->mle_cur_count[mle->type]);
+
/* copy off the node_map and register hb callbacks on our copy */
memcpy(mle->node_map, dlm->domain_map, sizeof(mle->node_map));
memcpy(mle->vote_map, dlm->domain_map, sizeof(mle->vote_map));
@@ -318,6 +317,24 @@ static void dlm_init_mle(struct dlm_master_list_entry *mle,
__dlm_mle_attach_hb_events(dlm, mle);
}
+void __dlm_unlink_mle(struct dlm_ctxt *dlm, struct dlm_master_list_entry *mle)
+{
+ assert_spin_locked(&dlm->spinlock);
+ assert_spin_locked(&dlm->master_lock);
+
+ if (!hlist_unhashed(&mle->master_hash_node))
+ hlist_del_init(&mle->master_hash_node);
+}
+
+void __dlm_insert_mle(struct dlm_ctxt *dlm, struct dlm_master_list_entry *mle)
+{
+ struct hlist_head *bucket;
+
+ assert_spin_locked(&dlm->master_lock);
+
+ bucket = dlm_master_hash(dlm, mle->mnamehash);
+ hlist_add_head(&mle->master_hash_node, bucket);
+}
/* returns 1 if found, 0 if not */
static int dlm_find_mle(struct dlm_ctxt *dlm,
@@ -325,10 +342,17 @@ static int dlm_find_mle(struct dlm_ctxt *dlm,
char *name, unsigned int namelen)
{
struct dlm_master_list_entry *tmpmle;
+ struct hlist_head *bucket;
+ struct hlist_node *list;
+ unsigned int hash;
assert_spin_locked(&dlm->master_lock);
- list_for_each_entry(tmpmle, &dlm->master_list, list) {
+ hash = dlm_lockid_hash(name, namelen);
+ bucket = dlm_master_hash(dlm, hash);
+ hlist_for_each(list, bucket) {
+ tmpmle = hlist_entry(list, struct dlm_master_list_entry,
+ master_hash_node);
if (!dlm_mle_equal(dlm, tmpmle, name, namelen))
continue;
dlm_get_mle(tmpmle);
@@ -408,24 +432,20 @@ static void dlm_mle_release(struct kref *kref)
mle = container_of(kref, struct dlm_master_list_entry, mle_refs);
dlm = mle->dlm;
- if (mle->type != DLM_MLE_MASTER) {
- mlog(0, "calling mle_release for %.*s, type %d\n",
- mle->u.name.len, mle->u.name.name, mle->type);
- } else {
- mlog(0, "calling mle_release for %.*s, type %d\n",
- mle->u.res->lockname.len,
- mle->u.res->lockname.name, mle->type);
- }
assert_spin_locked(&dlm->spinlock);
assert_spin_locked(&dlm->master_lock);
+ mlog(0, "Releasing mle for %.*s, type %d\n", mle->mnamelen, mle->mname,
+ mle->type);
+
/* remove from list if not already */
- if (!list_empty(&mle->list))
- list_del_init(&mle->list);
+ __dlm_unlink_mle(dlm, mle);
/* detach the mle from the domain node up/down events */
__dlm_mle_detach_hb_events(dlm, mle);
+ atomic_dec(&dlm->mle_cur_count[mle->type]);
+
/* NOTE: kfree under spinlock here.
* if this is bad, we can move this to a freelist. */
kmem_cache_free(dlm_mle_cache, mle);
@@ -465,43 +485,6 @@ void dlm_destroy_master_caches(void)
kmem_cache_destroy(dlm_lockres_cache);
}
-static void dlm_set_lockres_owner(struct dlm_ctxt *dlm,
- struct dlm_lock_resource *res,
- u8 owner)
-{
- assert_spin_locked(&res->spinlock);
-
- mlog_entry("%.*s, %u\n", res->lockname.len, res->lockname.name, owner);
-
- if (owner == dlm->node_num)
- atomic_inc(&dlm->local_resources);
- else if (owner == DLM_LOCK_RES_OWNER_UNKNOWN)
- atomic_inc(&dlm->unknown_resources);
- else
- atomic_inc(&dlm->remote_resources);
-
- res->owner = owner;
-}
-
-void dlm_change_lockres_owner(struct dlm_ctxt *dlm,
- struct dlm_lock_resource *res, u8 owner)
-{
- assert_spin_locked(&res->spinlock);
-
- if (owner == res->owner)
- return;
-
- if (res->owner == dlm->node_num)
- atomic_dec(&dlm->local_resources);
- else if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN)
- atomic_dec(&dlm->unknown_resources);
- else
- atomic_dec(&dlm->remote_resources);
-
- dlm_set_lockres_owner(dlm, res, owner);
-}
-
-
static void dlm_lockres_release(struct kref *kref)
{
struct dlm_lock_resource *res;
@@ -527,6 +510,8 @@ static void dlm_lockres_release(struct kref *kref)
}
spin_unlock(&dlm->track_lock);
+ atomic_dec(&dlm->res_cur_count);
+
dlm_put(dlm);
if (!hlist_unhashed(&res->hash_node) ||
@@ -607,6 +592,9 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm,
kref_init(&res->refs);
+ atomic_inc(&dlm->res_tot_count);
+ atomic_inc(&dlm->res_cur_count);
+
/* just for consistency */
spin_lock(&res->spinlock);
dlm_set_lockres_owner(dlm, res, DLM_LOCK_RES_OWNER_UNKNOWN);
@@ -843,7 +831,7 @@ lookup:
alloc_mle = NULL;
dlm_init_mle(mle, DLM_MLE_MASTER, dlm, res, NULL, 0);
set_bit(dlm->node_num, mle->maybe_map);
- list_add(&mle->list, &dlm->master_list);
+ __dlm_insert_mle(dlm, mle);
/* still holding the dlm spinlock, check the recovery map
* to see if there are any nodes that still need to be
@@ -1270,7 +1258,7 @@ static int dlm_restart_lock_mastery(struct dlm_ctxt *dlm,
res->lockname.len,
res->lockname.name);
mle->type = DLM_MLE_MASTER;
- mle->u.res = res;
+ mle->mleres = res;
}
}
}
@@ -1315,14 +1303,8 @@ static int dlm_do_master_request(struct dlm_lock_resource *res,
BUG_ON(mle->type == DLM_MLE_MIGRATION);
- if (mle->type != DLM_MLE_MASTER) {
- request.namelen = mle->u.name.len;
- memcpy(request.name, mle->u.name.name, request.namelen);
- } else {
- request.namelen = mle->u.res->lockname.len;
- memcpy(request.name, mle->u.res->lockname.name,
- request.namelen);
- }
+ request.namelen = (u8)mle->mnamelen;
+ memcpy(request.name, mle->mname, request.namelen);
again:
ret = o2net_send_message(DLM_MASTER_REQUEST_MSG, dlm->key, &request,
@@ -1575,7 +1557,7 @@ way_up_top:
// "add the block.\n");
dlm_init_mle(mle, DLM_MLE_BLOCK, dlm, NULL, name, namelen);
set_bit(request->node_idx, mle->maybe_map);
- list_add(&mle->list, &dlm->master_list);
+ __dlm_insert_mle(dlm, mle);
response = DLM_MASTER_RESP_NO;
} else {
// mlog(0, "mle was found\n");
@@ -1967,7 +1949,7 @@ ok:
assert->node_idx, rr, extra_ref, mle->inuse);
dlm_print_one_mle(mle);
}
- list_del_init(&mle->list);
+ __dlm_unlink_mle(dlm, mle);
__dlm_mle_detach_hb_events(dlm, mle);
__dlm_put_mle(mle);
if (extra_ref) {
@@ -3159,10 +3141,8 @@ static int dlm_add_migration_mle(struct dlm_ctxt *dlm,
tmp->master = master;
atomic_set(&tmp->woken, 1);
wake_up(&tmp->wq);
- /* remove it from the list so that only one
- * mle will be found */
- list_del_init(&tmp->list);
- /* this was obviously WRONG. mle is uninited here. should be tmp. */
+ /* remove it so that only one mle will be found */
+ __dlm_unlink_mle(dlm, tmp);
__dlm_mle_detach_hb_events(dlm, tmp);
ret = DLM_MIGRATE_RESPONSE_MASTERY_REF;
mlog(0, "%s:%.*s: master=%u, newmaster=%u, "
@@ -3181,137 +3161,164 @@ static int dlm_add_migration_mle(struct dlm_ctxt *dlm,
mle->master = master;
/* do this for consistency with other mle types */
set_bit(new_master, mle->maybe_map);
- list_add(&mle->list, &dlm->master_list);
+ __dlm_insert_mle(dlm, mle);
return ret;
}
-
-void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node)
+/*
+ * Sets the owner of the lockres, associated to the mle, to UNKNOWN
+ */
+static struct dlm_lock_resource *dlm_reset_mleres_owner(struct dlm_ctxt *dlm,
+ struct dlm_master_list_entry *mle)
{
- struct dlm_master_list_entry *mle, *next;
struct dlm_lock_resource *res;
- unsigned int hash;
- mlog_entry("dlm=%s, dead node=%u\n", dlm->name, dead_node);
-top:
- assert_spin_locked(&dlm->spinlock);
+ /* Find the lockres associated to the mle and set its owner to UNK */
+ res = __dlm_lookup_lockres(dlm, mle->mname, mle->mnamelen,
+ mle->mnamehash);
+ if (res) {
+ spin_unlock(&dlm->master_lock);
- /* clean the master list */
- spin_lock(&dlm->master_lock);
- list_for_each_entry_safe(mle, next, &dlm->master_list, list) {
- BUG_ON(mle->type != DLM_MLE_BLOCK &&
- mle->type != DLM_MLE_MASTER &&
- mle->type != DLM_MLE_MIGRATION);
-
- /* MASTER mles are initiated locally. the waiting
- * process will notice the node map change
- * shortly. let that happen as normal. */
- if (mle->type == DLM_MLE_MASTER)
- continue;
+ /* move lockres onto recovery list */
+ spin_lock(&res->spinlock);
+ dlm_set_lockres_owner(dlm, res, DLM_LOCK_RES_OWNER_UNKNOWN);
+ dlm_move_lockres_to_recovery_list(dlm, res);
+ spin_unlock(&res->spinlock);
+ dlm_lockres_put(res);
+ /* about to get rid of mle, detach from heartbeat */
+ __dlm_mle_detach_hb_events(dlm, mle);
- /* BLOCK mles are initiated by other nodes.
- * need to clean up if the dead node would have
- * been the master. */
- if (mle->type == DLM_MLE_BLOCK) {
- int bit;
+ /* dump the mle */
+ spin_lock(&dlm->master_lock);
+ __dlm_put_mle(mle);
+ spin_unlock(&dlm->master_lock);
+ }
- spin_lock(&mle->spinlock);
- bit = find_next_bit(mle->maybe_map, O2NM_MAX_NODES, 0);
- if (bit != dead_node) {
- mlog(0, "mle found, but dead node %u would "
- "not have been master\n", dead_node);
- spin_unlock(&mle->spinlock);
- } else {
- /* must drop the refcount by one since the
- * assert_master will never arrive. this
- * may result in the mle being unlinked and
- * freed, but there may still be a process
- * waiting in the dlmlock path which is fine. */
- mlog(0, "node %u was expected master\n",
- dead_node);
- atomic_set(&mle->woken, 1);
- spin_unlock(&mle->spinlock);
- wake_up(&mle->wq);
- /* do not need events any longer, so detach
- * from heartbeat */
- __dlm_mle_detach_hb_events(dlm, mle);
- __dlm_put_mle(mle);
- }
- continue;
- }
+ return res;
+}
- /* everything else is a MIGRATION mle */
-
- /* the rule for MIGRATION mles is that the master
- * becomes UNKNOWN if *either* the original or
- * the new master dies. all UNKNOWN lockreses
- * are sent to whichever node becomes the recovery
- * master. the new master is responsible for
- * determining if there is still a master for
- * this lockres, or if he needs to take over
- * mastery. either way, this node should expect
- * another message to resolve this. */
- if (mle->master != dead_node &&
- mle->new_master != dead_node)
- continue;
+static void dlm_clean_migration_mle(struct dlm_ctxt *dlm,
+ struct dlm_master_list_entry *mle)
+{
+ __dlm_mle_detach_hb_events(dlm, mle);
- /* if we have reached this point, this mle needs to
- * be removed from the list and freed. */
+ spin_lock(&mle->spinlock);
+ __dlm_unlink_mle(dlm, mle);
+ atomic_set(&mle->woken, 1);
+ spin_unlock(&mle->spinlock);
- /* remove from the list early. NOTE: unlinking
- * list_head while in list_for_each_safe */
- __dlm_mle_detach_hb_events(dlm, mle);
- spin_lock(&mle->spinlock);
- list_del_init(&mle->list);
+ wake_up(&mle->wq);
+}
+
+static void dlm_clean_block_mle(struct dlm_ctxt *dlm,
+ struct dlm_master_list_entry *mle, u8 dead_node)
+{
+ int bit;
+
+ BUG_ON(mle->type != DLM_MLE_BLOCK);
+
+ spin_lock(&mle->spinlock);
+ bit = find_next_bit(mle->maybe_map, O2NM_MAX_NODES, 0);
+ if (bit != dead_node) {
+ mlog(0, "mle found, but dead node %u would not have been "
+ "master\n", dead_node);
+ spin_unlock(&mle->spinlock);
+ } else {
+ /* Must drop the refcount by one since the assert_master will
+ * never arrive. This may result in the mle being unlinked and
+ * freed, but there may still be a process waiting in the
+ * dlmlock path which is fine. */
+ mlog(0, "node %u was expected master\n", dead_node);
atomic_set(&mle->woken, 1);
spin_unlock(&mle->spinlock);
wake_up(&mle->wq);
- mlog(0, "%s: node %u died during migration from "
- "%u to %u!\n", dlm->name, dead_node,
- mle->master, mle->new_master);
- /* if there is a lockres associated with this
- * mle, find it and set its owner to UNKNOWN */
- hash = dlm_lockid_hash(mle->u.name.name, mle->u.name.len);
- res = __dlm_lookup_lockres(dlm, mle->u.name.name,
- mle->u.name.len, hash);
- if (res) {
- /* unfortunately if we hit this rare case, our
- * lock ordering is messed. we need to drop
- * the master lock so that we can take the
- * lockres lock, meaning that we will have to
- * restart from the head of list. */
- spin_unlock(&dlm->master_lock);
+ /* Do not need events any longer, so detach from heartbeat */
+ __dlm_mle_detach_hb_events(dlm, mle);
+ __dlm_put_mle(mle);
+ }
+}
- /* move lockres onto recovery list */
- spin_lock(&res->spinlock);
- dlm_set_lockres_owner(dlm, res,
- DLM_LOCK_RES_OWNER_UNKNOWN);
- dlm_move_lockres_to_recovery_list(dlm, res);
- spin_unlock(&res->spinlock);
- dlm_lockres_put(res);
+void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node)
+{
+ struct dlm_master_list_entry *mle;
+ struct dlm_lock_resource *res;
+ struct hlist_head *bucket;
+ struct hlist_node *list;
+ unsigned int i;
- /* about to get rid of mle, detach from heartbeat */
- __dlm_mle_detach_hb_events(dlm, mle);
+ mlog_entry("dlm=%s, dead node=%u\n", dlm->name, dead_node);
+top:
+ assert_spin_locked(&dlm->spinlock);
- /* dump the mle */
- spin_lock(&dlm->master_lock);
- __dlm_put_mle(mle);
- spin_unlock(&dlm->master_lock);
+ /* clean the master list */
+ spin_lock(&dlm->master_lock);
+ for (i = 0; i < DLM_HASH_BUCKETS; i++) {
+ bucket = dlm_master_hash(dlm, i);
+ hlist_for_each(list, bucket) {
+ mle = hlist_entry(list, struct dlm_master_list_entry,
+ master_hash_node);
+
+ BUG_ON(mle->type != DLM_MLE_BLOCK &&
+ mle->type != DLM_MLE_MASTER &&
+ mle->type != DLM_MLE_MIGRATION);
+
+ /* MASTER mles are initiated locally. The waiting
+ * process will notice the node map change shortly.
+ * Let that happen as normal. */
+ if (mle->type == DLM_MLE_MASTER)
+ continue;
+
+ /* BLOCK mles are initiated by other nodes. Need to
+ * clean up if the dead node would have been the
+ * master. */
+ if (mle->type == DLM_MLE_BLOCK) {
+ dlm_clean_block_mle(dlm, mle, dead_node);
+ continue;
+ }
- /* restart */
- goto top;
- }
+ /* Everything else is a MIGRATION mle */
+
+ /* The rule for MIGRATION mles is that the master
+ * becomes UNKNOWN if *either* the original or the new
+ * master dies. All UNKNOWN lockres' are sent to
+ * whichever node becomes the recovery master. The new
+ * master is responsible for determining if there is
+ * still a master for this lockres, or if he needs to
+ * take over mastery. Either way, this node should
+ * expect another message to resolve this. */
+
+ if (mle->master != dead_node &&
+ mle->new_master != dead_node)
+ continue;
+
+ /* If we have reached this point, this mle needs to be
+ * removed from the list and freed. */
+ dlm_clean_migration_mle(dlm, mle);
+
+ mlog(0, "%s: node %u died during migration from "
+ "%u to %u!\n", dlm->name, dead_node, mle->master,
+ mle->new_master);
+
+ /* If we find a lockres associated with the mle, we've
+ * hit this rare case that messes up our lock ordering.
+ * If so, we need to drop the master lock so that we can
+ * take the lockres lock, meaning that we will have to
+ * restart from the head of list. */
+ res = dlm_reset_mleres_owner(dlm, mle);
+ if (res)
+ /* restart */
+ goto top;
- /* this may be the last reference */
- __dlm_put_mle(mle);
+ /* This may be the last reference */
+ __dlm_put_mle(mle);
+ }
}
spin_unlock(&dlm->master_lock);
}
-
int dlm_finish_migration(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
u8 old_master)
{
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c
index 4060bb328bc..d490b66ad9d 100644
--- a/fs/ocfs2/dlm/dlmthread.c
+++ b/fs/ocfs2/dlm/dlmthread.c
@@ -162,12 +162,28 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm,
spin_lock(&res->spinlock);
if (!__dlm_lockres_unused(res)) {
- spin_unlock(&res->spinlock);
mlog(0, "%s:%.*s: tried to purge but not unused\n",
dlm->name, res->lockname.len, res->lockname.name);
- return -ENOTEMPTY;
+ __dlm_print_one_lock_resource(res);
+ spin_unlock(&res->spinlock);
+ BUG();
}
+
+ if (res->state & DLM_LOCK_RES_MIGRATING) {
+ mlog(0, "%s:%.*s: Delay dropref as this lockres is "
+ "being remastered\n", dlm->name, res->lockname.len,
+ res->lockname.name);
+ /* Re-add the lockres to the end of the purge list */
+ if (!list_empty(&res->purge)) {
+ list_del_init(&res->purge);
+ list_add_tail(&res->purge, &dlm->purge_list);
+ }
+ spin_unlock(&res->spinlock);
+ return 0;
+ }
+
master = (res->owner == dlm->node_num);
+
if (!master)
res->state |= DLM_LOCK_RES_DROPPING_REF;
spin_unlock(&res->spinlock);
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 7219a86d34c..e15fc7d5082 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -244,6 +244,10 @@ static struct ocfs2_lock_res_ops ocfs2_rename_lops = {
.flags = 0,
};
+static struct ocfs2_lock_res_ops ocfs2_nfs_sync_lops = {
+ .flags = 0,
+};
+
static struct ocfs2_lock_res_ops ocfs2_dentry_lops = {
.get_osb = ocfs2_get_dentry_osb,
.post_unlock = ocfs2_dentry_post_unlock,
@@ -622,6 +626,17 @@ static void ocfs2_rename_lock_res_init(struct ocfs2_lock_res *res,
&ocfs2_rename_lops, osb);
}
+static void ocfs2_nfs_sync_lock_res_init(struct ocfs2_lock_res *res,
+ struct ocfs2_super *osb)
+{
+ /* nfs_sync lockres doesn't come from a slab so we call init
+ * once on it manually. */
+ ocfs2_lock_res_init_once(res);
+ ocfs2_build_lock_name(OCFS2_LOCK_TYPE_NFS_SYNC, 0, 0, res->l_name);
+ ocfs2_lock_res_init_common(osb, res, OCFS2_LOCK_TYPE_NFS_SYNC,
+ &ocfs2_nfs_sync_lops, osb);
+}
+
void ocfs2_file_lock_res_init(struct ocfs2_lock_res *lockres,
struct ocfs2_file_private *fp)
{
@@ -2417,6 +2432,34 @@ void ocfs2_rename_unlock(struct ocfs2_super *osb)
ocfs2_cluster_unlock(osb, lockres, DLM_LOCK_EX);
}
+int ocfs2_nfs_sync_lock(struct ocfs2_super *osb, int ex)
+{
+ int status;
+ struct ocfs2_lock_res *lockres = &osb->osb_nfs_sync_lockres;
+
+ if (ocfs2_is_hard_readonly(osb))
+ return -EROFS;
+
+ if (ocfs2_mount_local(osb))
+ return 0;
+
+ status = ocfs2_cluster_lock(osb, lockres, ex ? LKM_EXMODE : LKM_PRMODE,
+ 0, 0);
+ if (status < 0)
+ mlog(ML_ERROR, "lock on nfs sync lock failed %d\n", status);
+
+ return status;
+}
+
+void ocfs2_nfs_sync_unlock(struct ocfs2_super *osb, int ex)
+{
+ struct ocfs2_lock_res *lockres = &osb->osb_nfs_sync_lockres;
+
+ if (!ocfs2_mount_local(osb))
+ ocfs2_cluster_unlock(osb, lockres,
+ ex ? LKM_EXMODE : LKM_PRMODE);
+}
+
int ocfs2_dentry_lock(struct dentry *dentry, int ex)
{
int ret;
@@ -2798,6 +2841,7 @@ int ocfs2_dlm_init(struct ocfs2_super *osb)
local:
ocfs2_super_lock_res_init(&osb->osb_super_lockres, osb);
ocfs2_rename_lock_res_init(&osb->osb_rename_lockres, osb);
+ ocfs2_nfs_sync_lock_res_init(&osb->osb_nfs_sync_lockres, osb);
osb->cconn = conn;
@@ -2833,6 +2877,7 @@ void ocfs2_dlm_shutdown(struct ocfs2_super *osb,
ocfs2_lock_res_free(&osb->osb_super_lockres);
ocfs2_lock_res_free(&osb->osb_rename_lockres);
+ ocfs2_lock_res_free(&osb->osb_nfs_sync_lockres);
ocfs2_cluster_disconnect(osb->cconn, hangup_pending);
osb->cconn = NULL;
@@ -3015,6 +3060,7 @@ static void ocfs2_drop_osb_locks(struct ocfs2_super *osb)
{
ocfs2_simple_drop_lockres(osb, &osb->osb_super_lockres);
ocfs2_simple_drop_lockres(osb, &osb->osb_rename_lockres);
+ ocfs2_simple_drop_lockres(osb, &osb->osb_nfs_sync_lockres);
}
int ocfs2_drop_inode_locks(struct inode *inode)
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h
index 3f8d9986b8e..e1fd5721cd7 100644
--- a/fs/ocfs2/dlmglue.h
+++ b/fs/ocfs2/dlmglue.h
@@ -115,6 +115,8 @@ void ocfs2_super_unlock(struct ocfs2_super *osb,
int ex);
int ocfs2_rename_lock(struct ocfs2_super *osb);
void ocfs2_rename_unlock(struct ocfs2_super *osb);
+int ocfs2_nfs_sync_lock(struct ocfs2_super *osb, int ex);
+void ocfs2_nfs_sync_unlock(struct ocfs2_super *osb, int ex);
int ocfs2_dentry_lock(struct dentry *dentry, int ex);
void ocfs2_dentry_unlock(struct dentry *dentry, int ex);
int ocfs2_file_lock(struct file *file, int ex, int trylock);
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index 2f27b332d8b..de3da8eb558 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -31,6 +31,7 @@
#include "ocfs2.h"
+#include "alloc.h"
#include "dir.h"
#include "dlmglue.h"
#include "dcache.h"
@@ -38,6 +39,7 @@
#include "inode.h"
#include "buffer_head_io.h"
+#include "suballoc.h"
struct ocfs2_inode_handle
{
@@ -49,29 +51,97 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb,
struct ocfs2_inode_handle *handle)
{
struct inode *inode;
+ struct ocfs2_super *osb = OCFS2_SB(sb);
+ u64 blkno = handle->ih_blkno;
+ int status, set;
struct dentry *result;
mlog_entry("(0x%p, 0x%p)\n", sb, handle);
- if (handle->ih_blkno == 0) {
- mlog_errno(-ESTALE);
- return ERR_PTR(-ESTALE);
+ if (blkno == 0) {
+ mlog(0, "nfs wants inode with blkno: 0\n");
+ result = ERR_PTR(-ESTALE);
+ goto bail;
+ }
+
+ inode = ocfs2_ilookup(sb, blkno);
+ /*
+ * If the inode exists in memory, we only need to check it's
+ * generation number
+ */
+ if (inode)
+ goto check_gen;
+
+ /*
+ * This will synchronize us against ocfs2_delete_inode() on
+ * all nodes
+ */
+ status = ocfs2_nfs_sync_lock(osb, 1);
+ if (status < 0) {
+ mlog(ML_ERROR, "getting nfs sync lock(EX) failed %d\n", status);
+ goto check_err;
+ }
+
+ status = ocfs2_test_inode_bit(osb, blkno, &set);
+ if (status < 0) {
+ if (status == -EINVAL) {
+ /*
+ * The blkno NFS gave us doesn't even show up
+ * as an inode, we return -ESTALE to be
+ * nice
+ */
+ mlog(0, "test inode bit failed %d\n", status);
+ status = -ESTALE;
+ } else {
+ mlog(ML_ERROR, "test inode bit failed %d\n", status);
+ }
+ goto unlock_nfs_sync;
+ }
+
+ /* If the inode allocator bit is clear, this inode must be stale */
+ if (!set) {
+ mlog(0, "inode %llu suballoc bit is clear\n", blkno);
+ status = -ESTALE;
+ goto unlock_nfs_sync;
}
- inode = ocfs2_iget(OCFS2_SB(sb), handle->ih_blkno, 0, 0);
+ inode = ocfs2_iget(osb, blkno, 0, 0);
- if (IS_ERR(inode))
- return (void *)inode;
+unlock_nfs_sync:
+ ocfs2_nfs_sync_unlock(osb, 1);
+check_err:
+ if (status < 0) {
+ if (status == -ESTALE) {
+ mlog(0, "stale inode ino: %llu generation: %u\n",
+ blkno, handle->ih_generation);
+ }
+ result = ERR_PTR(status);
+ goto bail;
+ }
+
+ if (IS_ERR(inode)) {
+ mlog_errno(PTR_ERR(inode));
+ result = (void *)inode;
+ goto bail;
+ }
+
+check_gen:
if (handle->ih_generation != inode->i_generation) {
iput(inode);
- return ERR_PTR(-ESTALE);
+ mlog(0, "stale inode ino: %llu generation: %u\n", blkno,
+ handle->ih_generation);
+ result = ERR_PTR(-ESTALE);
+ goto bail;
}
result = d_obtain_alias(inode);
if (!IS_ERR(result))
result->d_op = &ocfs2_dentry_ops;
+ else
+ mlog_errno(PTR_ERR(result));
+bail:
mlog_exit_ptr(result);
return result;
}
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index a5887df2cd8..8672b953603 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1926,7 +1926,7 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
out->f_path.dentry->d_name.len,
out->f_path.dentry->d_name.name);
- inode_double_lock(inode, pipe->inode);
+ mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
ret = ocfs2_rw_lock(inode, 1);
if (ret < 0) {
@@ -1941,12 +1941,16 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
goto out_unlock;
}
+ if (pipe->inode)
+ mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD);
ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags);
+ if (pipe->inode)
+ mutex_unlock(&pipe->inode->i_mutex);
out_unlock:
ocfs2_rw_unlock(inode, 1);
out:
- inode_double_unlock(inode, pipe->inode);
+ mutex_unlock(&inode->i_mutex);
mlog_exit(ret);
return ret;
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 229e707bc05..10e1fa87396 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -38,6 +38,7 @@
#include "ocfs2.h"
#include "alloc.h"
+#include "dir.h"
#include "blockcheck.h"
#include "dlmglue.h"
#include "extent_map.h"
@@ -112,6 +113,17 @@ void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi)
oi->ip_attr |= OCFS2_DIRSYNC_FL;
}
+struct inode *ocfs2_ilookup(struct super_block *sb, u64 blkno)
+{
+ struct ocfs2_find_inode_args args;
+
+ args.fi_blkno = blkno;
+ args.fi_flags = 0;
+ args.fi_ino = ino_from_blkno(sb, blkno);
+ args.fi_sysfile_type = 0;
+
+ return ilookup5(sb, blkno, ocfs2_find_actor, &args);
+}
struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags,
int sysfile_type)
{
@@ -275,7 +287,7 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
(unsigned long long)OCFS2_I(inode)->ip_blkno,
(unsigned long long)le64_to_cpu(fe->i_blkno));
- inode->i_nlink = le16_to_cpu(fe->i_links_count);
+ inode->i_nlink = ocfs2_read_links_count(fe);
if (fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL)) {
OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SYSTEM_FILE;
@@ -351,6 +363,8 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
ocfs2_set_inode_flags(inode);
+ OCFS2_I(inode)->ip_last_used_slot = 0;
+ OCFS2_I(inode)->ip_last_used_group = 0;
mlog_exit_void();
}
@@ -606,7 +620,7 @@ static int ocfs2_remove_inode(struct inode *inode,
}
handle = ocfs2_start_trans(osb, OCFS2_DELETE_INODE_CREDITS +
- ocfs2_quota_trans_credits(inode->i_sb));
+ ocfs2_quota_trans_credits(inode->i_sb));
if (IS_ERR(handle)) {
status = PTR_ERR(handle);
mlog_errno(status);
@@ -740,6 +754,15 @@ static int ocfs2_wipe_inode(struct inode *inode,
goto bail_unlock_dir;
}
+ /* Remove any dir index tree */
+ if (S_ISDIR(inode->i_mode)) {
+ status = ocfs2_dx_dir_truncate(inode, di_bh);
+ if (status) {
+ mlog_errno(status);
+ goto bail_unlock_dir;
+ }
+ }
+
/*Free extended attribute resources associated with this inode.*/
status = ocfs2_xattr_remove(inode, di_bh);
if (status < 0) {
@@ -949,6 +972,17 @@ void ocfs2_delete_inode(struct inode *inode)
goto bail;
}
+ /*
+ * Synchronize us against ocfs2_get_dentry. We take this in
+ * shared mode so that all nodes can still concurrently
+ * process deletes.
+ */
+ status = ocfs2_nfs_sync_lock(OCFS2_SB(inode->i_sb), 0);
+ if (status < 0) {
+ mlog(ML_ERROR, "getting nfs sync lock(PR) failed %d\n", status);
+ ocfs2_cleanup_delete_inode(inode, 0);
+ goto bail_unblock;
+ }
/* Lock down the inode. This gives us an up to date view of
* it's metadata (for verification), and allows us to
* serialize delete_inode on multiple nodes.
@@ -962,7 +996,7 @@ void ocfs2_delete_inode(struct inode *inode)
if (status != -ENOENT)
mlog_errno(status);
ocfs2_cleanup_delete_inode(inode, 0);
- goto bail_unblock;
+ goto bail_unlock_nfs_sync;
}
/* Query the cluster. This will be the final decision made
@@ -1005,6 +1039,10 @@ void ocfs2_delete_inode(struct inode *inode)
bail_unlock_inode:
ocfs2_inode_unlock(inode, 1);
brelse(di_bh);
+
+bail_unlock_nfs_sync:
+ ocfs2_nfs_sync_unlock(OCFS2_SB(inode->i_sb), 0);
+
bail_unblock:
status = sigprocmask(SIG_SETMASK, &oldset, NULL);
if (status < 0)
@@ -1205,7 +1243,7 @@ int ocfs2_mark_inode_dirty(handle_t *handle,
spin_unlock(&OCFS2_I(inode)->ip_lock);
fe->i_size = cpu_to_le64(i_size_read(inode));
- fe->i_links_count = cpu_to_le16(inode->i_nlink);
+ ocfs2_set_links_count(fe, inode->i_nlink);
fe->i_uid = cpu_to_le32(inode->i_uid);
fe->i_gid = cpu_to_le32(inode->i_gid);
fe->i_mode = cpu_to_le16(inode->i_mode);
@@ -1242,7 +1280,7 @@ void ocfs2_refresh_inode(struct inode *inode,
OCFS2_I(inode)->ip_dyn_features = le16_to_cpu(fe->i_dyn_features);
ocfs2_set_inode_flags(inode);
i_size_write(inode, le64_to_cpu(fe->i_size));
- inode->i_nlink = le16_to_cpu(fe->i_links_count);
+ inode->i_nlink = ocfs2_read_links_count(fe);
inode->i_uid = le32_to_cpu(fe->i_uid);
inode->i_gid = le32_to_cpu(fe->i_gid);
inode->i_mode = le16_to_cpu(fe->i_mode);
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h
index eb3c302b38d..ea71525aad4 100644
--- a/fs/ocfs2/inode.h
+++ b/fs/ocfs2/inode.h
@@ -72,6 +72,10 @@ struct ocfs2_inode_info
struct inode vfs_inode;
struct jbd2_inode ip_jinode;
+
+ /* Only valid if the inode is the dir. */
+ u32 ip_last_used_slot;
+ u64 ip_last_used_group;
};
/*
@@ -124,6 +128,7 @@ void ocfs2_drop_inode(struct inode *inode);
/* Flags for ocfs2_iget() */
#define OCFS2_FI_FLAG_SYSFILE 0x1
#define OCFS2_FI_FLAG_ORPHAN_RECOVERY 0x2
+struct inode *ocfs2_ilookup(struct super_block *sb, u64 feoff);
struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 feoff, unsigned flags,
int sysfile_type);
int ocfs2_inode_init_private(struct inode *inode);
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 57d7d25a2b9..a20a0f1e37f 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -65,6 +65,11 @@ static int ocfs2_trylock_journal(struct ocfs2_super *osb,
static int ocfs2_recover_orphans(struct ocfs2_super *osb,
int slot);
static int ocfs2_commit_thread(void *arg);
+static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal,
+ int slot_num,
+ struct ocfs2_dinode *la_dinode,
+ struct ocfs2_dinode *tl_dinode,
+ struct ocfs2_quota_recovery *qrec);
static inline int ocfs2_wait_on_mount(struct ocfs2_super *osb)
{
@@ -76,18 +81,97 @@ static inline int ocfs2_wait_on_quotas(struct ocfs2_super *osb)
return __ocfs2_wait_on_mount(osb, 1);
}
-
-
/*
- * The recovery_list is a simple linked list of node numbers to recover.
- * It is protected by the recovery_lock.
+ * This replay_map is to track online/offline slots, so we could recover
+ * offline slots during recovery and mount
*/
-struct ocfs2_recovery_map {
- unsigned int rm_used;
- unsigned int *rm_entries;
+enum ocfs2_replay_state {
+ REPLAY_UNNEEDED = 0, /* Replay is not needed, so ignore this map */
+ REPLAY_NEEDED, /* Replay slots marked in rm_replay_slots */
+ REPLAY_DONE /* Replay was already queued */
};
+struct ocfs2_replay_map {
+ unsigned int rm_slots;
+ enum ocfs2_replay_state rm_state;
+ unsigned char rm_replay_slots[0];
+};
+
+void ocfs2_replay_map_set_state(struct ocfs2_super *osb, int state)
+{
+ if (!osb->replay_map)
+ return;
+
+ /* If we've already queued the replay, we don't have any more to do */
+ if (osb->replay_map->rm_state == REPLAY_DONE)
+ return;
+
+ osb->replay_map->rm_state = state;
+}
+
+int ocfs2_compute_replay_slots(struct ocfs2_super *osb)
+{
+ struct ocfs2_replay_map *replay_map;
+ int i, node_num;
+
+ /* If replay map is already set, we don't do it again */
+ if (osb->replay_map)
+ return 0;
+
+ replay_map = kzalloc(sizeof(struct ocfs2_replay_map) +
+ (osb->max_slots * sizeof(char)), GFP_KERNEL);
+
+ if (!replay_map) {
+ mlog_errno(-ENOMEM);
+ return -ENOMEM;
+ }
+
+ spin_lock(&osb->osb_lock);
+
+ replay_map->rm_slots = osb->max_slots;
+ replay_map->rm_state = REPLAY_UNNEEDED;
+
+ /* set rm_replay_slots for offline slot(s) */
+ for (i = 0; i < replay_map->rm_slots; i++) {
+ if (ocfs2_slot_to_node_num_locked(osb, i, &node_num) == -ENOENT)
+ replay_map->rm_replay_slots[i] = 1;
+ }
+
+ osb->replay_map = replay_map;
+ spin_unlock(&osb->osb_lock);
+ return 0;
+}
+
+void ocfs2_queue_replay_slots(struct ocfs2_super *osb)
+{
+ struct ocfs2_replay_map *replay_map = osb->replay_map;
+ int i;
+
+ if (!replay_map)
+ return;
+
+ if (replay_map->rm_state != REPLAY_NEEDED)
+ return;
+
+ for (i = 0; i < replay_map->rm_slots; i++)
+ if (replay_map->rm_replay_slots[i])
+ ocfs2_queue_recovery_completion(osb->journal, i, NULL,
+ NULL, NULL);
+ replay_map->rm_state = REPLAY_DONE;
+}
+
+void ocfs2_free_replay_slots(struct ocfs2_super *osb)
+{
+ struct ocfs2_replay_map *replay_map = osb->replay_map;
+
+ if (!osb->replay_map)
+ return;
+
+ kfree(replay_map);
+ osb->replay_map = NULL;
+}
+
int ocfs2_recovery_init(struct ocfs2_super *osb)
{
struct ocfs2_recovery_map *rm;
@@ -496,6 +580,22 @@ static struct ocfs2_triggers dq_triggers = {
},
};
+static struct ocfs2_triggers dr_triggers = {
+ .ot_triggers = {
+ .t_commit = ocfs2_commit_trigger,
+ .t_abort = ocfs2_abort_trigger,
+ },
+ .ot_offset = offsetof(struct ocfs2_dx_root_block, dr_check),
+};
+
+static struct ocfs2_triggers dl_triggers = {
+ .ot_triggers = {
+ .t_commit = ocfs2_commit_trigger,
+ .t_abort = ocfs2_abort_trigger,
+ },
+ .ot_offset = offsetof(struct ocfs2_dx_leaf, dl_check),
+};
+
static int __ocfs2_journal_access(handle_t *handle,
struct inode *inode,
struct buffer_head *bh,
@@ -600,6 +700,20 @@ int ocfs2_journal_access_dq(handle_t *handle, struct inode *inode,
type);
}
+int ocfs2_journal_access_dr(handle_t *handle, struct inode *inode,
+ struct buffer_head *bh, int type)
+{
+ return __ocfs2_journal_access(handle, inode, bh, &dr_triggers,
+ type);
+}
+
+int ocfs2_journal_access_dl(handle_t *handle, struct inode *inode,
+ struct buffer_head *bh, int type)
+{
+ return __ocfs2_journal_access(handle, inode, bh, &dl_triggers,
+ type);
+}
+
int ocfs2_journal_access(handle_t *handle, struct inode *inode,
struct buffer_head *bh, int type)
{
@@ -1176,24 +1290,24 @@ static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal,
}
/* Called by the mount code to queue recovery the last part of
- * recovery for it's own slot. */
+ * recovery for it's own and offline slot(s). */
void ocfs2_complete_mount_recovery(struct ocfs2_super *osb)
{
struct ocfs2_journal *journal = osb->journal;
- if (osb->dirty) {
- /* No need to queue up our truncate_log as regular
- * cleanup will catch that. */
- ocfs2_queue_recovery_completion(journal,
- osb->slot_num,
- osb->local_alloc_copy,
- NULL,
- NULL);
- ocfs2_schedule_truncate_log_flush(osb, 0);
+ /* No need to queue up our truncate_log as regular cleanup will catch
+ * that */
+ ocfs2_queue_recovery_completion(journal, osb->slot_num,
+ osb->local_alloc_copy, NULL, NULL);
+ ocfs2_schedule_truncate_log_flush(osb, 0);
- osb->local_alloc_copy = NULL;
- osb->dirty = 0;
- }
+ osb->local_alloc_copy = NULL;
+ osb->dirty = 0;
+
+ /* queue to recover orphan slots for all offline slots */
+ ocfs2_replay_map_set_state(osb, REPLAY_NEEDED);
+ ocfs2_queue_replay_slots(osb);
+ ocfs2_free_replay_slots(osb);
}
void ocfs2_complete_quota_recovery(struct ocfs2_super *osb)
@@ -1236,6 +1350,14 @@ restart:
goto bail;
}
+ status = ocfs2_compute_replay_slots(osb);
+ if (status < 0)
+ mlog_errno(status);
+
+ /* queue recovery for our own slot */
+ ocfs2_queue_recovery_completion(osb->journal, osb->slot_num, NULL,
+ NULL, NULL);
+
spin_lock(&osb->osb_lock);
while (rm->rm_used) {
/* It's always safe to remove entry zero, as we won't
@@ -1301,11 +1423,8 @@ skip_recovery:
ocfs2_super_unlock(osb, 1);
- /* We always run recovery on our own orphan dir - the dead
- * node(s) may have disallowd a previos inode delete. Re-processing
- * is therefore required. */
- ocfs2_queue_recovery_completion(osb->journal, osb->slot_num, NULL,
- NULL, NULL);
+ /* queue recovery for offline slots */
+ ocfs2_queue_replay_slots(osb);
bail:
mutex_lock(&osb->recovery_lock);
@@ -1314,6 +1433,7 @@ bail:
goto restart;
}
+ ocfs2_free_replay_slots(osb);
osb->recovery_thread_task = NULL;
mb(); /* sync with ocfs2_recovery_thread_running */
wake_up(&osb->recovery_event);
@@ -1465,6 +1585,9 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
goto done;
}
+ /* we need to run complete recovery for offline orphan slots */
+ ocfs2_replay_map_set_state(osb, REPLAY_NEEDED);
+
mlog(ML_NOTICE, "Recovering node %d from slot %d on device (%u,%u)\n",
node_num, slot_num,
MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
index 172850a9a12..619dd7f6c05 100644
--- a/fs/ocfs2/journal.h
+++ b/fs/ocfs2/journal.h
@@ -38,6 +38,17 @@ enum ocfs2_journal_state {
struct ocfs2_super;
struct ocfs2_dinode;
+/*
+ * The recovery_list is a simple linked list of node numbers to recover.
+ * It is protected by the recovery_lock.
+ */
+
+struct ocfs2_recovery_map {
+ unsigned int rm_used;
+ unsigned int *rm_entries;
+};
+
+
struct ocfs2_journal {
enum ocfs2_journal_state j_state; /* Journals current state */
@@ -139,6 +150,7 @@ void ocfs2_wait_for_recovery(struct ocfs2_super *osb);
int ocfs2_recovery_init(struct ocfs2_super *osb);
void ocfs2_recovery_exit(struct ocfs2_super *osb);
+int ocfs2_compute_replay_slots(struct ocfs2_super *osb);
/*
* Journal Control:
* Initialize, Load, Shutdown, Wipe a journal.
@@ -266,6 +278,12 @@ int ocfs2_journal_access_dq(handle_t *handle, struct inode *inode,
/* dirblock */
int ocfs2_journal_access_db(handle_t *handle, struct inode *inode,
struct buffer_head *bh, int type);
+/* ocfs2_dx_root_block */
+int ocfs2_journal_access_dr(handle_t *handle, struct inode *inode,
+ struct buffer_head *bh, int type);
+/* ocfs2_dx_leaf */
+int ocfs2_journal_access_dl(handle_t *handle, struct inode *inode,
+ struct buffer_head *bh, int type);
/* Anything that has no ecc */
int ocfs2_journal_access(handle_t *handle, struct inode *inode,
struct buffer_head *bh, int type);
@@ -368,14 +386,29 @@ static inline int ocfs2_remove_extent_credits(struct super_block *sb)
}
/* data block for new dir/symlink, 2 for bitmap updates (bitmap fe +
- * bitmap block for the new bit) */
-#define OCFS2_DIR_LINK_ADDITIONAL_CREDITS (1 + 2)
+ * bitmap block for the new bit) dx_root update for free list */
+#define OCFS2_DIR_LINK_ADDITIONAL_CREDITS (1 + 2 + 1)
+
+static inline int ocfs2_add_dir_index_credits(struct super_block *sb)
+{
+ /* 1 block for index, 2 allocs (data, metadata), 1 clusters
+ * worth of blocks for initial extent. */
+ return 1 + 2 * OCFS2_SUBALLOC_ALLOC +
+ ocfs2_clusters_to_blocks(sb, 1);
+}
-/* parent fe, parent block, new file entry, inode alloc fe, inode alloc
- * group descriptor + mkdir/symlink blocks + quota update */
-static inline int ocfs2_mknod_credits(struct super_block *sb)
+/* parent fe, parent block, new file entry, index leaf, inode alloc fe, inode
+ * alloc group descriptor + mkdir/symlink blocks + dir blocks + xattr
+ * blocks + quota update */
+static inline int ocfs2_mknod_credits(struct super_block *sb, int is_dir,
+ int xattr_credits)
{
- return 3 + OCFS2_SUBALLOC_ALLOC + OCFS2_DIR_LINK_ADDITIONAL_CREDITS +
+ int dir_credits = OCFS2_DIR_LINK_ADDITIONAL_CREDITS;
+
+ if (is_dir)
+ dir_credits += ocfs2_add_dir_index_credits(sb);
+
+ return 4 + OCFS2_SUBALLOC_ALLOC + dir_credits + xattr_credits +
ocfs2_quota_trans_credits(sb);
}
@@ -388,31 +421,31 @@ static inline int ocfs2_mknod_credits(struct super_block *sb)
#define OCFS2_SIMPLE_DIR_EXTEND_CREDITS (2)
/* file update (nlink, etc) + directory mtime/ctime + dir entry block + quota
- * update on dir */
+ * update on dir + index leaf + dx root update for free list */
static inline int ocfs2_link_credits(struct super_block *sb)
{
- return 2*OCFS2_INODE_UPDATE_CREDITS + 1 +
+ return 2*OCFS2_INODE_UPDATE_CREDITS + 3 +
ocfs2_quota_trans_credits(sb);
}
/* inode + dir inode (if we unlink a dir), + dir entry block + orphan
- * dir inode link */
+ * dir inode link + dir inode index leaf + dir index root */
static inline int ocfs2_unlink_credits(struct super_block *sb)
{
/* The quota update from ocfs2_link_credits is unused here... */
- return 2 * OCFS2_INODE_UPDATE_CREDITS + 1 + ocfs2_link_credits(sb);
+ return 2 * OCFS2_INODE_UPDATE_CREDITS + 3 + ocfs2_link_credits(sb);
}
/* dinode + orphan dir dinode + inode alloc dinode + orphan dir entry +
- * inode alloc group descriptor */
-#define OCFS2_DELETE_INODE_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 1 + 1)
+ * inode alloc group descriptor + orphan dir index leaf */
+#define OCFS2_DELETE_INODE_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 3)
/* dinode update, old dir dinode update, new dir dinode update, old
* dir dir entry, new dir dir entry, dir entry update for renaming
- * directory + target unlink */
+ * directory + target unlink + 3 x dir index leaves */
static inline int ocfs2_rename_credits(struct super_block *sb)
{
- return 3 * OCFS2_INODE_UPDATE_CREDITS + 3 + ocfs2_unlink_credits(sb);
+ return 3 * OCFS2_INODE_UPDATE_CREDITS + 6 + ocfs2_unlink_credits(sb);
}
/* global bitmap dinode, group desc., relinked group,
@@ -422,6 +455,20 @@ static inline int ocfs2_rename_credits(struct super_block *sb)
+ OCFS2_INODE_UPDATE_CREDITS \
+ OCFS2_XATTR_BLOCK_UPDATE_CREDITS)
+/* inode update, removal of dx root block from allocator */
+#define OCFS2_DX_ROOT_REMOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + \
+ OCFS2_SUBALLOC_FREE)
+
+static inline int ocfs2_calc_dxi_expand_credits(struct super_block *sb)
+{
+ int credits = 1 + OCFS2_SUBALLOC_ALLOC;
+
+ credits += ocfs2_clusters_to_blocks(sb, 1);
+ credits += ocfs2_quota_trans_credits(sb);
+
+ return credits;
+}
+
/*
* Please note that the caller must make sure that root_el is the root
* of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise
@@ -457,7 +504,7 @@ static inline int ocfs2_calc_extend_credits(struct super_block *sb,
static inline int ocfs2_calc_symlink_credits(struct super_block *sb)
{
- int blocks = ocfs2_mknod_credits(sb);
+ int blocks = ocfs2_mknod_credits(sb, 0, 0);
/* links can be longer than one block so we may update many
* within our single allocated extent. */
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index ec70cdbe77f..bac7e6abaf4 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -28,7 +28,6 @@
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/bitops.h>
-#include <linux/debugfs.h>
#define MLOG_MASK_PREFIX ML_DISK_ALLOC
#include <cluster/masklog.h>
@@ -75,84 +74,6 @@ static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb,
static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
struct inode *local_alloc_inode);
-#ifdef CONFIG_OCFS2_FS_STATS
-
-static int ocfs2_la_debug_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-#define LA_DEBUG_BUF_SZ PAGE_CACHE_SIZE
-#define LA_DEBUG_VER 1
-static ssize_t ocfs2_la_debug_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- static DEFINE_MUTEX(la_debug_mutex);
- struct ocfs2_super *osb = file->private_data;
- int written, ret;
- char *buf = osb->local_alloc_debug_buf;
-
- mutex_lock(&la_debug_mutex);
- memset(buf, 0, LA_DEBUG_BUF_SZ);
-
- written = snprintf(buf, LA_DEBUG_BUF_SZ,
- "0x%x\t0x%llx\t%u\t%u\t0x%x\n",
- LA_DEBUG_VER,
- (unsigned long long)osb->la_last_gd,
- osb->local_alloc_default_bits,
- osb->local_alloc_bits, osb->local_alloc_state);
-
- ret = simple_read_from_buffer(userbuf, count, ppos, buf, written);
-
- mutex_unlock(&la_debug_mutex);
- return ret;
-}
-
-static const struct file_operations ocfs2_la_debug_fops = {
- .open = ocfs2_la_debug_open,
- .read = ocfs2_la_debug_read,
-};
-
-static void ocfs2_init_la_debug(struct ocfs2_super *osb)
-{
- osb->local_alloc_debug_buf = kmalloc(LA_DEBUG_BUF_SZ, GFP_NOFS);
- if (!osb->local_alloc_debug_buf)
- return;
-
- osb->local_alloc_debug = debugfs_create_file("local_alloc_stats",
- S_IFREG|S_IRUSR,
- osb->osb_debug_root,
- osb,
- &ocfs2_la_debug_fops);
- if (!osb->local_alloc_debug) {
- kfree(osb->local_alloc_debug_buf);
- osb->local_alloc_debug_buf = NULL;
- }
-}
-
-static void ocfs2_shutdown_la_debug(struct ocfs2_super *osb)
-{
- if (osb->local_alloc_debug)
- debugfs_remove(osb->local_alloc_debug);
-
- if (osb->local_alloc_debug_buf)
- kfree(osb->local_alloc_debug_buf);
-
- osb->local_alloc_debug_buf = NULL;
- osb->local_alloc_debug = NULL;
-}
-#else /* CONFIG_OCFS2_FS_STATS */
-static void ocfs2_init_la_debug(struct ocfs2_super *osb)
-{
- return;
-}
-static void ocfs2_shutdown_la_debug(struct ocfs2_super *osb)
-{
- return;
-}
-#endif
-
static inline int ocfs2_la_state_enabled(struct ocfs2_super *osb)
{
return (osb->local_alloc_state == OCFS2_LA_THROTTLED ||
@@ -226,8 +147,6 @@ int ocfs2_load_local_alloc(struct ocfs2_super *osb)
mlog_entry_void();
- ocfs2_init_la_debug(osb);
-
if (osb->local_alloc_bits == 0)
goto bail;
@@ -299,9 +218,6 @@ bail:
if (inode)
iput(inode);
- if (status < 0)
- ocfs2_shutdown_la_debug(osb);
-
mlog(0, "Local alloc window bits = %d\n", osb->local_alloc_bits);
mlog_exit(status);
@@ -331,8 +247,6 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
cancel_delayed_work(&osb->la_enable_wq);
flush_workqueue(ocfs2_wq);
- ocfs2_shutdown_la_debug(osb);
-
if (osb->local_alloc_state == OCFS2_LA_UNUSED)
goto out;
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 4b11762f249..2220f93f668 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -80,14 +80,14 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
struct inode **ret_orphan_dir,
struct inode *inode,
char *name,
- struct buffer_head **de_bh);
+ struct ocfs2_dir_lookup_result *lookup);
static int ocfs2_orphan_add(struct ocfs2_super *osb,
handle_t *handle,
struct inode *inode,
struct ocfs2_dinode *fe,
char *name,
- struct buffer_head *de_bh,
+ struct ocfs2_dir_lookup_result *lookup,
struct inode *orphan_dir_inode);
static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
@@ -228,17 +228,18 @@ static int ocfs2_mknod(struct inode *dir,
struct ocfs2_super *osb;
struct ocfs2_dinode *dirfe;
struct buffer_head *new_fe_bh = NULL;
- struct buffer_head *de_bh = NULL;
struct inode *inode = NULL;
struct ocfs2_alloc_context *inode_ac = NULL;
struct ocfs2_alloc_context *data_ac = NULL;
- struct ocfs2_alloc_context *xattr_ac = NULL;
+ struct ocfs2_alloc_context *meta_ac = NULL;
int want_clusters = 0;
+ int want_meta = 0;
int xattr_credits = 0;
struct ocfs2_security_xattr_info si = {
.enable = 1,
};
int did_quota_inode = 0;
+ struct ocfs2_dir_lookup_result lookup = { NULL, };
mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
(unsigned long)dev, dentry->d_name.len,
@@ -254,13 +255,13 @@ static int ocfs2_mknod(struct inode *dir,
return status;
}
- if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) {
+ if (S_ISDIR(mode) && (dir->i_nlink >= ocfs2_link_max(osb))) {
status = -EMLINK;
goto leave;
}
dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
- if (!dirfe->i_links_count) {
+ if (!ocfs2_read_links_count(dirfe)) {
/* can't make a file in a deleted directory. */
status = -ENOENT;
goto leave;
@@ -274,7 +275,7 @@ static int ocfs2_mknod(struct inode *dir,
/* get a spot inside the dir. */
status = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
dentry->d_name.name,
- dentry->d_name.len, &de_bh);
+ dentry->d_name.len, &lookup);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -308,17 +309,29 @@ static int ocfs2_mknod(struct inode *dir,
/* calculate meta data/clusters for setting security and acl xattr */
status = ocfs2_calc_xattr_init(dir, parent_fe_bh, mode,
- &si, &want_clusters,
- &xattr_credits, &xattr_ac);
+ &si, &want_clusters,
+ &xattr_credits, &want_meta);
if (status < 0) {
mlog_errno(status);
goto leave;
}
/* Reserve a cluster if creating an extent based directory. */
- if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb))
+ if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) {
want_clusters += 1;
+ /* Dir indexing requires extra space as well */
+ if (ocfs2_supports_indexed_dirs(osb))
+ want_meta++;
+ }
+
+ status = ocfs2_reserve_new_metadata_blocks(osb, want_meta, &meta_ac);
+ if (status < 0) {
+ if (status != -ENOSPC)
+ mlog_errno(status);
+ goto leave;
+ }
+
status = ocfs2_reserve_clusters(osb, want_clusters, &data_ac);
if (status < 0) {
if (status != -ENOSPC)
@@ -326,8 +339,9 @@ static int ocfs2_mknod(struct inode *dir,
goto leave;
}
- handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb) +
- xattr_credits);
+ handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb,
+ S_ISDIR(mode),
+ xattr_credits));
if (IS_ERR(handle)) {
status = PTR_ERR(handle);
handle = NULL;
@@ -355,7 +369,7 @@ static int ocfs2_mknod(struct inode *dir,
if (S_ISDIR(mode)) {
status = ocfs2_fill_new_dir(osb, handle, dir, inode,
- new_fe_bh, data_ac);
+ new_fe_bh, data_ac, meta_ac);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -367,7 +381,7 @@ static int ocfs2_mknod(struct inode *dir,
mlog_errno(status);
goto leave;
}
- le16_add_cpu(&dirfe->i_links_count, 1);
+ ocfs2_add_links_count(dirfe, 1);
status = ocfs2_journal_dirty(handle, parent_fe_bh);
if (status < 0) {
mlog_errno(status);
@@ -377,7 +391,7 @@ static int ocfs2_mknod(struct inode *dir,
}
status = ocfs2_init_acl(handle, inode, dir, new_fe_bh, parent_fe_bh,
- xattr_ac, data_ac);
+ meta_ac, data_ac);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -385,7 +399,7 @@ static int ocfs2_mknod(struct inode *dir,
if (si.enable) {
status = ocfs2_init_security_set(handle, inode, new_fe_bh, &si,
- xattr_ac, data_ac);
+ meta_ac, data_ac);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -394,7 +408,7 @@ static int ocfs2_mknod(struct inode *dir,
status = ocfs2_add_entry(handle, dentry, inode,
OCFS2_I(inode)->ip_blkno, parent_fe_bh,
- de_bh);
+ &lookup);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -423,11 +437,12 @@ leave:
mlog(0, "Disk is full\n");
brelse(new_fe_bh);
- brelse(de_bh);
brelse(parent_fe_bh);
kfree(si.name);
kfree(si.value);
+ ocfs2_free_dir_lookup_result(&lookup);
+
if ((status < 0) && inode) {
clear_nlink(inode);
iput(inode);
@@ -439,8 +454,8 @@ leave:
if (data_ac)
ocfs2_free_alloc_context(data_ac);
- if (xattr_ac)
- ocfs2_free_alloc_context(xattr_ac);
+ if (meta_ac)
+ ocfs2_free_alloc_context(meta_ac);
mlog_exit(status);
@@ -462,6 +477,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
struct ocfs2_extent_list *fel;
u64 fe_blkno = 0;
u16 suballoc_bit;
+ u16 feat;
mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry,
inode->i_mode, (unsigned long)dev, dentry->d_name.len,
@@ -469,8 +485,8 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
*new_fe_bh = NULL;
- status = ocfs2_claim_new_inode(osb, handle, inode_ac, &suballoc_bit,
- &fe_blkno);
+ status = ocfs2_claim_new_inode(osb, handle, dir, parent_fe_bh,
+ inode_ac, &suballoc_bit, &fe_blkno);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -513,7 +529,8 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
fe->i_mode = cpu_to_le16(inode->i_mode);
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
- fe->i_links_count = cpu_to_le16(inode->i_nlink);
+
+ ocfs2_set_links_count(fe, inode->i_nlink);
fe->i_last_eb_blk = 0;
strcpy(fe->i_signature, OCFS2_INODE_SIGNATURE);
@@ -525,11 +542,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
fe->i_dtime = 0;
/*
- * If supported, directories start with inline data.
+ * If supported, directories start with inline data. If inline
+ * isn't supported, but indexing is, we start them as indexed.
*/
+ feat = le16_to_cpu(fe->i_dyn_features);
if (S_ISDIR(inode->i_mode) && ocfs2_supports_inline_data(osb)) {
- u16 feat = le16_to_cpu(fe->i_dyn_features);
-
fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL);
fe->id2.i_data.id_count = cpu_to_le16(
@@ -608,9 +625,9 @@ static int ocfs2_link(struct dentry *old_dentry,
int err;
struct buffer_head *fe_bh = NULL;
struct buffer_head *parent_fe_bh = NULL;
- struct buffer_head *de_bh = NULL;
struct ocfs2_dinode *fe = NULL;
struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+ struct ocfs2_dir_lookup_result lookup = { NULL, };
mlog_entry("(inode=%lu, old='%.*s' new='%.*s')\n", inode->i_ino,
old_dentry->d_name.len, old_dentry->d_name.name,
@@ -638,7 +655,7 @@ static int ocfs2_link(struct dentry *old_dentry,
err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
dentry->d_name.name,
- dentry->d_name.len, &de_bh);
+ dentry->d_name.len, &lookup);
if (err < 0) {
mlog_errno(err);
goto out;
@@ -652,7 +669,7 @@ static int ocfs2_link(struct dentry *old_dentry,
}
fe = (struct ocfs2_dinode *) fe_bh->b_data;
- if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) {
+ if (ocfs2_read_links_count(fe) >= ocfs2_link_max(osb)) {
err = -EMLINK;
goto out_unlock_inode;
}
@@ -674,13 +691,13 @@ static int ocfs2_link(struct dentry *old_dentry,
inc_nlink(inode);
inode->i_ctime = CURRENT_TIME;
- fe->i_links_count = cpu_to_le16(inode->i_nlink);
+ ocfs2_set_links_count(fe, inode->i_nlink);
fe->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
fe->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
err = ocfs2_journal_dirty(handle, fe_bh);
if (err < 0) {
- le16_add_cpu(&fe->i_links_count, -1);
+ ocfs2_add_links_count(fe, -1);
drop_nlink(inode);
mlog_errno(err);
goto out_commit;
@@ -688,9 +705,9 @@ static int ocfs2_link(struct dentry *old_dentry,
err = ocfs2_add_entry(handle, dentry, inode,
OCFS2_I(inode)->ip_blkno,
- parent_fe_bh, de_bh);
+ parent_fe_bh, &lookup);
if (err) {
- le16_add_cpu(&fe->i_links_count, -1);
+ ocfs2_add_links_count(fe, -1);
drop_nlink(inode);
mlog_errno(err);
goto out_commit;
@@ -714,10 +731,11 @@ out_unlock_inode:
out:
ocfs2_inode_unlock(dir, 1);
- brelse(de_bh);
brelse(fe_bh);
brelse(parent_fe_bh);
+ ocfs2_free_dir_lookup_result(&lookup);
+
mlog_exit(err);
return err;
@@ -766,10 +784,9 @@ static int ocfs2_unlink(struct inode *dir,
struct buffer_head *fe_bh = NULL;
struct buffer_head *parent_node_bh = NULL;
handle_t *handle = NULL;
- struct ocfs2_dir_entry *dirent = NULL;
- struct buffer_head *dirent_bh = NULL;
char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
- struct buffer_head *orphan_entry_bh = NULL;
+ struct ocfs2_dir_lookup_result lookup = { NULL, };
+ struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
mlog_entry("(0x%p, 0x%p, '%.*s')\n", dir, dentry,
dentry->d_name.len, dentry->d_name.name);
@@ -791,8 +808,8 @@ static int ocfs2_unlink(struct inode *dir,
}
status = ocfs2_find_files_on_disk(dentry->d_name.name,
- dentry->d_name.len, &blkno,
- dir, &dirent_bh, &dirent);
+ dentry->d_name.len, &blkno, dir,
+ &lookup);
if (status < 0) {
if (status != -ENOENT)
mlog_errno(status);
@@ -817,10 +834,7 @@ static int ocfs2_unlink(struct inode *dir,
child_locked = 1;
if (S_ISDIR(inode->i_mode)) {
- if (!ocfs2_empty_dir(inode)) {
- status = -ENOTEMPTY;
- goto leave;
- } else if (inode->i_nlink != 2) {
+ if (inode->i_nlink != 2 || !ocfs2_empty_dir(inode)) {
status = -ENOTEMPTY;
goto leave;
}
@@ -836,8 +850,7 @@ static int ocfs2_unlink(struct inode *dir,
if (inode_is_unlinkable(inode)) {
status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, inode,
- orphan_name,
- &orphan_entry_bh);
+ orphan_name, &orphan_insert);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -863,7 +876,7 @@ static int ocfs2_unlink(struct inode *dir,
if (inode_is_unlinkable(inode)) {
status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name,
- orphan_entry_bh, orphan_dir);
+ &orphan_insert, orphan_dir);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -871,7 +884,7 @@ static int ocfs2_unlink(struct inode *dir,
}
/* delete the name from the parent dir */
- status = ocfs2_delete_entry(handle, dir, dirent, dirent_bh);
+ status = ocfs2_delete_entry(handle, dir, &lookup);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -880,7 +893,7 @@ static int ocfs2_unlink(struct inode *dir,
if (S_ISDIR(inode->i_mode))
drop_nlink(inode);
drop_nlink(inode);
- fe->i_links_count = cpu_to_le16(inode->i_nlink);
+ ocfs2_set_links_count(fe, inode->i_nlink);
status = ocfs2_journal_dirty(handle, fe_bh);
if (status < 0) {
@@ -916,9 +929,10 @@ leave:
}
brelse(fe_bh);
- brelse(dirent_bh);
brelse(parent_node_bh);
- brelse(orphan_entry_bh);
+
+ ocfs2_free_dir_lookup_result(&orphan_insert);
+ ocfs2_free_dir_lookup_result(&lookup);
mlog_exit(status);
@@ -1004,8 +1018,8 @@ static int ocfs2_rename(struct inode *old_dir,
struct inode *new_dir,
struct dentry *new_dentry)
{
- int status = 0, rename_lock = 0, parents_locked = 0;
- int old_child_locked = 0, new_child_locked = 0;
+ int status = 0, rename_lock = 0, parents_locked = 0, target_exists = 0;
+ int old_child_locked = 0, new_child_locked = 0, update_dot_dot = 0;
struct inode *old_inode = old_dentry->d_inode;
struct inode *new_inode = new_dentry->d_inode;
struct inode *orphan_dir = NULL;
@@ -1020,13 +1034,13 @@ static int ocfs2_rename(struct inode *old_dir,
handle_t *handle = NULL;
struct buffer_head *old_dir_bh = NULL;
struct buffer_head *new_dir_bh = NULL;
- struct ocfs2_dir_entry *old_inode_dot_dot_de = NULL, *old_de = NULL,
- *new_de = NULL;
- struct buffer_head *new_de_bh = NULL, *old_de_bh = NULL; // bhs for above
- struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
- // this is the 1st dirent bh
nlink_t old_dir_nlink = old_dir->i_nlink;
struct ocfs2_dinode *old_di;
+ struct ocfs2_dir_lookup_result old_inode_dot_dot_res = { NULL, };
+ struct ocfs2_dir_lookup_result target_lookup_res = { NULL, };
+ struct ocfs2_dir_lookup_result old_entry_lookup = { NULL, };
+ struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
+ struct ocfs2_dir_lookup_result target_insert = { NULL, };
/* At some point it might be nice to break this function up a
* bit. */
@@ -1108,9 +1122,10 @@ static int ocfs2_rename(struct inode *old_dir,
if (S_ISDIR(old_inode->i_mode)) {
u64 old_inode_parent;
+ update_dot_dot = 1;
status = ocfs2_find_files_on_disk("..", 2, &old_inode_parent,
- old_inode, &old_inode_de_bh,
- &old_inode_dot_dot_de);
+ old_inode,
+ &old_inode_dot_dot_res);
if (status) {
status = -EIO;
goto bail;
@@ -1122,7 +1137,7 @@ static int ocfs2_rename(struct inode *old_dir,
}
if (!new_inode && new_dir != old_dir &&
- new_dir->i_nlink >= OCFS2_LINK_MAX) {
+ new_dir->i_nlink >= ocfs2_link_max(osb)) {
status = -EMLINK;
goto bail;
}
@@ -1151,8 +1166,8 @@ static int ocfs2_rename(struct inode *old_dir,
* to delete it */
status = ocfs2_find_files_on_disk(new_dentry->d_name.name,
new_dentry->d_name.len,
- &newfe_blkno, new_dir, &new_de_bh,
- &new_de);
+ &newfe_blkno, new_dir,
+ &target_lookup_res);
/* The only error we allow here is -ENOENT because the new
* file not existing is perfectly valid. */
if ((status < 0) && (status != -ENOENT)) {
@@ -1161,8 +1176,10 @@ static int ocfs2_rename(struct inode *old_dir,
mlog_errno(status);
goto bail;
}
+ if (status == 0)
+ target_exists = 1;
- if (!new_de && new_inode) {
+ if (!target_exists && new_inode) {
/*
* Target was unlinked by another node while we were
* waiting to get to ocfs2_rename(). There isn't
@@ -1175,7 +1192,7 @@ static int ocfs2_rename(struct inode *old_dir,
/* In case we need to overwrite an existing file, we blow it
* away first */
- if (new_de) {
+ if (target_exists) {
/* VFS didn't think there existed an inode here, but
* someone else in the cluster must have raced our
* rename to create one. Today we error cleanly, in
@@ -1216,8 +1233,8 @@ static int ocfs2_rename(struct inode *old_dir,
newfe = (struct ocfs2_dinode *) newfe_bh->b_data;
- mlog(0, "aha rename over existing... new_de=%p new_blkno=%llu "
- "newfebh=%p bhblocknr=%llu\n", new_de,
+ mlog(0, "aha rename over existing... new_blkno=%llu "
+ "newfebh=%p bhblocknr=%llu\n",
(unsigned long long)newfe_blkno, newfe_bh, newfe_bh ?
(unsigned long long)newfe_bh->b_blocknr : 0ULL);
@@ -1225,7 +1242,7 @@ static int ocfs2_rename(struct inode *old_dir,
status = ocfs2_prepare_orphan_dir(osb, &orphan_dir,
new_inode,
orphan_name,
- &orphan_entry_bh);
+ &orphan_insert);
if (status < 0) {
mlog_errno(status);
goto bail;
@@ -1243,7 +1260,7 @@ static int ocfs2_rename(struct inode *old_dir,
status = ocfs2_prepare_dir_for_insert(osb, new_dir, new_dir_bh,
new_dentry->d_name.name,
new_dentry->d_name.len,
- &insert_entry_bh);
+ &target_insert);
if (status < 0) {
mlog_errno(status);
goto bail;
@@ -1258,10 +1275,10 @@ static int ocfs2_rename(struct inode *old_dir,
goto bail;
}
- if (new_de) {
+ if (target_exists) {
if (S_ISDIR(new_inode->i_mode)) {
- if (!ocfs2_empty_dir(new_inode) ||
- new_inode->i_nlink != 2) {
+ if (new_inode->i_nlink != 2 ||
+ !ocfs2_empty_dir(new_inode)) {
status = -ENOTEMPTY;
goto bail;
}
@@ -1274,10 +1291,10 @@ static int ocfs2_rename(struct inode *old_dir,
}
if (S_ISDIR(new_inode->i_mode) ||
- (newfe->i_links_count == cpu_to_le16(1))){
+ (ocfs2_read_links_count(newfe) == 1)) {
status = ocfs2_orphan_add(osb, handle, new_inode,
newfe, orphan_name,
- orphan_entry_bh, orphan_dir);
+ &orphan_insert, orphan_dir);
if (status < 0) {
mlog_errno(status);
goto bail;
@@ -1285,8 +1302,8 @@ static int ocfs2_rename(struct inode *old_dir,
}
/* change the dirent to point to the correct inode */
- status = ocfs2_update_entry(new_dir, handle, new_de_bh,
- new_de, old_inode);
+ status = ocfs2_update_entry(new_dir, handle, &target_lookup_res,
+ old_inode);
if (status < 0) {
mlog_errno(status);
goto bail;
@@ -1294,9 +1311,9 @@ static int ocfs2_rename(struct inode *old_dir,
new_dir->i_version++;
if (S_ISDIR(new_inode->i_mode))
- newfe->i_links_count = 0;
+ ocfs2_set_links_count(newfe, 0);
else
- le16_add_cpu(&newfe->i_links_count, -1);
+ ocfs2_add_links_count(newfe, -1);
status = ocfs2_journal_dirty(handle, newfe_bh);
if (status < 0) {
@@ -1307,7 +1324,7 @@ static int ocfs2_rename(struct inode *old_dir,
/* if the name was not found in new_dir, add it now */
status = ocfs2_add_entry(handle, new_dentry, old_inode,
OCFS2_I(old_inode)->ip_blkno,
- new_dir_bh, insert_entry_bh);
+ new_dir_bh, &target_insert);
}
old_inode->i_ctime = CURRENT_TIME;
@@ -1334,15 +1351,13 @@ static int ocfs2_rename(struct inode *old_dir,
* because the insert might have changed the type of directory
* we're dealing with.
*/
- old_de_bh = ocfs2_find_entry(old_dentry->d_name.name,
- old_dentry->d_name.len,
- old_dir, &old_de);
- if (!old_de_bh) {
- status = -EIO;
+ status = ocfs2_find_entry(old_dentry->d_name.name,
+ old_dentry->d_name.len, old_dir,
+ &old_entry_lookup);
+ if (status)
goto bail;
- }
- status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh);
+ status = ocfs2_delete_entry(handle, old_dir, &old_entry_lookup);
if (status < 0) {
mlog_errno(status);
goto bail;
@@ -1353,9 +1368,10 @@ static int ocfs2_rename(struct inode *old_dir,
new_inode->i_ctime = CURRENT_TIME;
}
old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
- if (old_inode_de_bh) {
- status = ocfs2_update_entry(old_inode, handle, old_inode_de_bh,
- old_inode_dot_dot_de, new_dir);
+
+ if (update_dot_dot) {
+ status = ocfs2_update_entry(old_inode, handle,
+ &old_inode_dot_dot_res, new_dir);
old_dir->i_nlink--;
if (new_inode) {
new_inode->i_nlink--;
@@ -1391,14 +1407,13 @@ static int ocfs2_rename(struct inode *old_dir,
} else {
struct ocfs2_dinode *fe;
status = ocfs2_journal_access_di(handle, old_dir,
- old_dir_bh,
- OCFS2_JOURNAL_ACCESS_WRITE);
+ old_dir_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
fe = (struct ocfs2_dinode *) old_dir_bh->b_data;
- fe->i_links_count = cpu_to_le16(old_dir->i_nlink);
+ ocfs2_set_links_count(fe, old_dir->i_nlink);
status = ocfs2_journal_dirty(handle, old_dir_bh);
}
}
-
ocfs2_dentry_move(old_dentry, new_dentry, old_dir, new_dir);
status = 0;
bail:
@@ -1429,13 +1444,17 @@ bail:
if (new_inode)
iput(new_inode);
+
+ ocfs2_free_dir_lookup_result(&target_lookup_res);
+ ocfs2_free_dir_lookup_result(&old_entry_lookup);
+ ocfs2_free_dir_lookup_result(&old_inode_dot_dot_res);
+ ocfs2_free_dir_lookup_result(&orphan_insert);
+ ocfs2_free_dir_lookup_result(&target_insert);
+
brelse(newfe_bh);
brelse(old_inode_bh);
brelse(old_dir_bh);
brelse(new_dir_bh);
- brelse(new_de_bh);
- brelse(old_de_bh);
- brelse(old_inode_de_bh);
brelse(orphan_entry_bh);
brelse(insert_entry_bh);
@@ -1558,7 +1577,6 @@ static int ocfs2_symlink(struct inode *dir,
struct inode *inode = NULL;
struct super_block *sb;
struct buffer_head *new_fe_bh = NULL;
- struct buffer_head *de_bh = NULL;
struct buffer_head *parent_fe_bh = NULL;
struct ocfs2_dinode *fe = NULL;
struct ocfs2_dinode *dirfe;
@@ -1572,6 +1590,7 @@ static int ocfs2_symlink(struct inode *dir,
.enable = 1,
};
int did_quota = 0, did_quota_inode = 0;
+ struct ocfs2_dir_lookup_result lookup = { NULL, };
mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir,
dentry, symname, dentry->d_name.len, dentry->d_name.name);
@@ -1592,7 +1611,7 @@ static int ocfs2_symlink(struct inode *dir,
}
dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
- if (!dirfe->i_links_count) {
+ if (!ocfs2_read_links_count(dirfe)) {
/* can't make a file in a deleted directory. */
status = -ENOENT;
goto bail;
@@ -1605,7 +1624,7 @@ static int ocfs2_symlink(struct inode *dir,
status = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
dentry->d_name.name,
- dentry->d_name.len, &de_bh);
+ dentry->d_name.len, &lookup);
if (status < 0) {
mlog_errno(status);
goto bail;
@@ -1744,7 +1763,7 @@ static int ocfs2_symlink(struct inode *dir,
status = ocfs2_add_entry(handle, dentry, inode,
le64_to_cpu(fe->i_blkno), parent_fe_bh,
- de_bh);
+ &lookup);
if (status < 0) {
mlog_errno(status);
goto bail;
@@ -1772,9 +1791,9 @@ bail:
brelse(new_fe_bh);
brelse(parent_fe_bh);
- brelse(de_bh);
kfree(si.name);
kfree(si.value);
+ ocfs2_free_dir_lookup_result(&lookup);
if (inode_ac)
ocfs2_free_alloc_context(inode_ac);
if (data_ac)
@@ -1826,7 +1845,7 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
struct inode **ret_orphan_dir,
struct inode *inode,
char *name,
- struct buffer_head **de_bh)
+ struct ocfs2_dir_lookup_result *lookup)
{
struct inode *orphan_dir_inode;
struct buffer_head *orphan_dir_bh = NULL;
@@ -1857,7 +1876,7 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
status = ocfs2_prepare_dir_for_insert(osb, orphan_dir_inode,
orphan_dir_bh, name,
- OCFS2_ORPHAN_NAMELEN, de_bh);
+ OCFS2_ORPHAN_NAMELEN, lookup);
if (status < 0) {
ocfs2_inode_unlock(orphan_dir_inode, 1);
@@ -1884,7 +1903,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
struct inode *inode,
struct ocfs2_dinode *fe,
char *name,
- struct buffer_head *de_bh,
+ struct ocfs2_dir_lookup_result *lookup,
struct inode *orphan_dir_inode)
{
struct buffer_head *orphan_dir_bh = NULL;
@@ -1910,8 +1929,8 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
* underneath us... */
orphan_fe = (struct ocfs2_dinode *) orphan_dir_bh->b_data;
if (S_ISDIR(inode->i_mode))
- le16_add_cpu(&orphan_fe->i_links_count, 1);
- orphan_dir_inode->i_nlink = le16_to_cpu(orphan_fe->i_links_count);
+ ocfs2_add_links_count(orphan_fe, 1);
+ orphan_dir_inode->i_nlink = ocfs2_read_links_count(orphan_fe);
status = ocfs2_journal_dirty(handle, orphan_dir_bh);
if (status < 0) {
@@ -1922,7 +1941,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
status = __ocfs2_add_entry(handle, orphan_dir_inode, name,
OCFS2_ORPHAN_NAMELEN, inode,
OCFS2_I(inode)->ip_blkno,
- orphan_dir_bh, de_bh);
+ orphan_dir_bh, lookup);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -1955,8 +1974,7 @@ int ocfs2_orphan_del(struct ocfs2_super *osb,
char name[OCFS2_ORPHAN_NAMELEN + 1];
struct ocfs2_dinode *orphan_fe;
int status = 0;
- struct buffer_head *target_de_bh = NULL;
- struct ocfs2_dir_entry *target_de = NULL;
+ struct ocfs2_dir_lookup_result lookup = { NULL, };
mlog_entry_void();
@@ -1971,17 +1989,15 @@ int ocfs2_orphan_del(struct ocfs2_super *osb,
OCFS2_ORPHAN_NAMELEN);
/* find it's spot in the orphan directory */
- target_de_bh = ocfs2_find_entry(name, OCFS2_ORPHAN_NAMELEN,
- orphan_dir_inode, &target_de);
- if (!target_de_bh) {
- status = -ENOENT;
+ status = ocfs2_find_entry(name, OCFS2_ORPHAN_NAMELEN, orphan_dir_inode,
+ &lookup);
+ if (status) {
mlog_errno(status);
goto leave;
}
/* remove it from the orphan directory */
- status = ocfs2_delete_entry(handle, orphan_dir_inode, target_de,
- target_de_bh);
+ status = ocfs2_delete_entry(handle, orphan_dir_inode, &lookup);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -1997,8 +2013,8 @@ int ocfs2_orphan_del(struct ocfs2_super *osb,
/* do the i_nlink dance! :) */
orphan_fe = (struct ocfs2_dinode *) orphan_dir_bh->b_data;
if (S_ISDIR(inode->i_mode))
- le16_add_cpu(&orphan_fe->i_links_count, -1);
- orphan_dir_inode->i_nlink = le16_to_cpu(orphan_fe->i_links_count);
+ ocfs2_add_links_count(orphan_fe, -1);
+ orphan_dir_inode->i_nlink = ocfs2_read_links_count(orphan_fe);
status = ocfs2_journal_dirty(handle, orphan_dir_bh);
if (status < 0) {
@@ -2007,7 +2023,7 @@ int ocfs2_orphan_del(struct ocfs2_super *osb,
}
leave:
- brelse(target_de_bh);
+ ocfs2_free_dir_lookup_result(&lookup);
mlog_exit(status);
return status;
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 946d3c34b90..1386281950d 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -209,6 +209,7 @@ enum ocfs2_mount_options
struct ocfs2_journal;
struct ocfs2_slot_info;
struct ocfs2_recovery_map;
+struct ocfs2_replay_map;
struct ocfs2_quota_recovery;
struct ocfs2_dentry_lock;
struct ocfs2_super
@@ -264,6 +265,7 @@ struct ocfs2_super
atomic_t vol_state;
struct mutex recovery_lock;
struct ocfs2_recovery_map *recovery_map;
+ struct ocfs2_replay_map *replay_map;
struct task_struct *recovery_thread_task;
int disable_recovery;
wait_queue_head_t checkpoint_event;
@@ -287,11 +289,6 @@ struct ocfs2_super
u64 la_last_gd;
-#ifdef CONFIG_OCFS2_FS_STATS
- struct dentry *local_alloc_debug;
- char *local_alloc_debug_buf;
-#endif
-
/* Next three fields are for local node slot recovery during
* mount. */
int dirty;
@@ -305,9 +302,11 @@ struct ocfs2_super
struct ocfs2_cluster_connection *cconn;
struct ocfs2_lock_res osb_super_lockres;
struct ocfs2_lock_res osb_rename_lockres;
+ struct ocfs2_lock_res osb_nfs_sync_lockres;
struct ocfs2_dlm_debug *osb_dlm_debug;
struct dentry *osb_debug_root;
+ struct dentry *osb_ctxt;
wait_queue_head_t recovery_event;
@@ -344,6 +343,12 @@ struct ocfs2_super
/* used to protect metaecc calculation check of xattr. */
spinlock_t osb_xattr_lock;
+
+ unsigned int osb_dx_mask;
+ u32 osb_dx_seed[4];
+
+ /* the group we used to allocate inodes. */
+ u64 osb_inode_alloc_group;
};
#define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info)
@@ -402,6 +407,51 @@ static inline int ocfs2_meta_ecc(struct ocfs2_super *osb)
return 0;
}
+static inline int ocfs2_supports_indexed_dirs(struct ocfs2_super *osb)
+{
+ if (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS)
+ return 1;
+ return 0;
+}
+
+static inline unsigned int ocfs2_link_max(struct ocfs2_super *osb)
+{
+ if (ocfs2_supports_indexed_dirs(osb))
+ return OCFS2_DX_LINK_MAX;
+ return OCFS2_LINK_MAX;
+}
+
+static inline unsigned int ocfs2_read_links_count(struct ocfs2_dinode *di)
+{
+ u32 nlink = le16_to_cpu(di->i_links_count);
+ u32 hi = le16_to_cpu(di->i_links_count_hi);
+
+ if (di->i_dyn_features & cpu_to_le16(OCFS2_INDEXED_DIR_FL))
+ nlink |= (hi << OCFS2_LINKS_HI_SHIFT);
+
+ return nlink;
+}
+
+static inline void ocfs2_set_links_count(struct ocfs2_dinode *di, u32 nlink)
+{
+ u16 lo, hi;
+
+ lo = nlink;
+ hi = nlink >> OCFS2_LINKS_HI_SHIFT;
+
+ di->i_links_count = cpu_to_le16(lo);
+ di->i_links_count_hi = cpu_to_le16(hi);
+}
+
+static inline void ocfs2_add_links_count(struct ocfs2_dinode *di, int n)
+{
+ u32 links = ocfs2_read_links_count(di);
+
+ links += n;
+
+ ocfs2_set_links_count(di, links);
+}
+
/* set / clear functions because cluster events can make these happen
* in parallel so we want the transitions to be atomic. this also
* means that any future flags osb_flags must be protected by spinlock
@@ -482,6 +532,12 @@ static inline int ocfs2_uses_extended_slot_map(struct ocfs2_super *osb)
#define OCFS2_IS_VALID_DIR_TRAILER(ptr) \
(!strcmp((ptr)->db_signature, OCFS2_DIR_TRAILER_SIGNATURE))
+#define OCFS2_IS_VALID_DX_ROOT(ptr) \
+ (!strcmp((ptr)->dr_signature, OCFS2_DX_ROOT_SIGNATURE))
+
+#define OCFS2_IS_VALID_DX_LEAF(ptr) \
+ (!strcmp((ptr)->dl_signature, OCFS2_DX_LEAF_SIGNATURE))
+
static inline unsigned long ino_from_blkno(struct super_block *sb,
u64 blkno)
{
@@ -532,6 +588,16 @@ static inline u64 ocfs2_clusters_to_bytes(struct super_block *sb,
return (u64)clusters << OCFS2_SB(sb)->s_clustersize_bits;
}
+static inline u64 ocfs2_block_to_cluster_start(struct super_block *sb,
+ u64 blocks)
+{
+ int bits = OCFS2_SB(sb)->s_clustersize_bits - sb->s_blocksize_bits;
+ unsigned int clusters;
+
+ clusters = ocfs2_blocks_to_clusters(sb, blocks);
+ return (u64)clusters << bits;
+}
+
static inline u64 ocfs2_align_bytes_to_clusters(struct super_block *sb,
u64 bytes)
{
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index 2332ef740f4..7ab6e9e5e77 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -66,6 +66,8 @@
#define OCFS2_GROUP_DESC_SIGNATURE "GROUP01"
#define OCFS2_XATTR_BLOCK_SIGNATURE "XATTR01"
#define OCFS2_DIR_TRAILER_SIGNATURE "DIRTRL1"
+#define OCFS2_DX_ROOT_SIGNATURE "DXDIR01"
+#define OCFS2_DX_LEAF_SIGNATURE "DXLEAF1"
/* Compatibility flags */
#define OCFS2_HAS_COMPAT_FEATURE(sb,mask) \
@@ -95,7 +97,8 @@
| OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP \
| OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK \
| OCFS2_FEATURE_INCOMPAT_XATTR \
- | OCFS2_FEATURE_INCOMPAT_META_ECC)
+ | OCFS2_FEATURE_INCOMPAT_META_ECC \
+ | OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS)
#define OCFS2_FEATURE_RO_COMPAT_SUPP (OCFS2_FEATURE_RO_COMPAT_UNWRITTEN \
| OCFS2_FEATURE_RO_COMPAT_USRQUOTA \
| OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)
@@ -151,6 +154,9 @@
/* Support for extended attributes */
#define OCFS2_FEATURE_INCOMPAT_XATTR 0x0200
+/* Support for indexed directores */
+#define OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS 0x0400
+
/* Metadata checksum and error correction */
#define OCFS2_FEATURE_INCOMPAT_META_ECC 0x0800
@@ -411,8 +417,12 @@ static struct ocfs2_system_inode_info ocfs2_system_inodes[NUM_SYSTEM_INODES] = {
#define OCFS2_DIR_REC_LEN(name_len) (((name_len) + OCFS2_DIR_MEMBER_LEN + \
OCFS2_DIR_ROUND) & \
~OCFS2_DIR_ROUND)
+#define OCFS2_DIR_MIN_REC_LEN OCFS2_DIR_REC_LEN(1)
#define OCFS2_LINK_MAX 32000
+#define OCFS2_DX_LINK_MAX ((1U << 31) - 1U)
+#define OCFS2_LINKS_HI_SHIFT 16
+#define OCFS2_DX_ENTRIES_MAX (0xffffffffU)
#define S_SHIFT 12
static unsigned char ocfs2_type_by_mode[S_IFMT >> S_SHIFT] = {
@@ -628,8 +638,9 @@ struct ocfs2_super_block {
/*B8*/ __le16 s_xattr_inline_size; /* extended attribute inline size
for this fs*/
__le16 s_reserved0;
- __le32 s_reserved1;
-/*C0*/ __le64 s_reserved2[16]; /* Fill out superblock */
+ __le32 s_dx_seed[3]; /* seed[0-2] for dx dir hash.
+ * s_uuid_hash serves as seed[3]. */
+/*C0*/ __le64 s_reserved2[15]; /* Fill out superblock */
/*140*/
/*
@@ -679,7 +690,7 @@ struct ocfs2_dinode {
belongs to */
__le16 i_suballoc_bit; /* Bit offset in suballocator
block group */
-/*10*/ __le16 i_reserved0;
+/*10*/ __le16 i_links_count_hi; /* High 16 bits of links count */
__le16 i_xattr_inline_size;
__le32 i_clusters; /* Cluster count */
__le32 i_uid; /* Owner UID */
@@ -705,7 +716,8 @@ struct ocfs2_dinode {
__le16 i_dyn_features;
__le64 i_xattr_loc;
/*80*/ struct ocfs2_block_check i_check; /* Error checking */
-/*88*/ __le64 i_reserved2[6];
+/*88*/ __le64 i_dx_root; /* Pointer to dir index root block */
+ __le64 i_reserved2[5];
/*B8*/ union {
__le64 i_pad1; /* Generic way to refer to this
64bit union */
@@ -781,6 +793,90 @@ struct ocfs2_dir_block_trailer {
/*40*/
};
+ /*
+ * A directory entry in the indexed tree. We don't store the full name here,
+ * but instead provide a pointer to the full dirent in the unindexed tree.
+ *
+ * We also store name_len here so as to reduce the number of leaf blocks we
+ * need to search in case of collisions.
+ */
+struct ocfs2_dx_entry {
+ __le32 dx_major_hash; /* Used to find logical
+ * cluster in index */
+ __le32 dx_minor_hash; /* Lower bits used to find
+ * block in cluster */
+ __le64 dx_dirent_blk; /* Physical block in unindexed
+ * tree holding this dirent. */
+};
+
+struct ocfs2_dx_entry_list {
+ __le32 de_reserved;
+ __le16 de_count; /* Maximum number of entries
+ * possible in de_entries */
+ __le16 de_num_used; /* Current number of
+ * de_entries entries */
+ struct ocfs2_dx_entry de_entries[0]; /* Indexed dir entries
+ * in a packed array of
+ * length de_num_used */
+};
+
+#define OCFS2_DX_FLAG_INLINE 0x01
+
+/*
+ * A directory indexing block. Each indexed directory has one of these,
+ * pointed to by ocfs2_dinode.
+ *
+ * This block stores an indexed btree root, and a set of free space
+ * start-of-list pointers.
+ */
+struct ocfs2_dx_root_block {
+ __u8 dr_signature[8]; /* Signature for verification */
+ struct ocfs2_block_check dr_check; /* Error checking */
+ __le16 dr_suballoc_slot; /* Slot suballocator this
+ * block belongs to. */
+ __le16 dr_suballoc_bit; /* Bit offset in suballocator
+ * block group */
+ __le32 dr_fs_generation; /* Must match super block */
+ __le64 dr_blkno; /* Offset on disk, in blocks */
+ __le64 dr_last_eb_blk; /* Pointer to last
+ * extent block */
+ __le32 dr_clusters; /* Clusters allocated
+ * to the indexed tree. */
+ __u8 dr_flags; /* OCFS2_DX_FLAG_* flags */
+ __u8 dr_reserved0;
+ __le16 dr_reserved1;
+ __le64 dr_dir_blkno; /* Pointer to parent inode */
+ __le32 dr_num_entries; /* Total number of
+ * names stored in
+ * this directory.*/
+ __le32 dr_reserved2;
+ __le64 dr_free_blk; /* Pointer to head of free
+ * unindexed block list. */
+ __le64 dr_reserved3[15];
+ union {
+ struct ocfs2_extent_list dr_list; /* Keep this aligned to 128
+ * bits for maximum space
+ * efficiency. */
+ struct ocfs2_dx_entry_list dr_entries; /* In-root-block list of
+ * entries. We grow out
+ * to extents if this
+ * gets too big. */
+ };
+};
+
+/*
+ * The header of a leaf block in the indexed tree.
+ */
+struct ocfs2_dx_leaf {
+ __u8 dl_signature[8];/* Signature for verification */
+ struct ocfs2_block_check dl_check; /* Error checking */
+ __le64 dl_blkno; /* Offset on disk, in blocks */
+ __le32 dl_fs_generation;/* Must match super block */
+ __le32 dl_reserved0;
+ __le64 dl_reserved1;
+ struct ocfs2_dx_entry_list dl_list;
+};
+
/*
* On disk allocator group structure for OCFS2
*/
@@ -1112,6 +1208,16 @@ static inline int ocfs2_extent_recs_per_inode_with_xattr(
return size / sizeof(struct ocfs2_extent_rec);
}
+static inline int ocfs2_extent_recs_per_dx_root(struct super_block *sb)
+{
+ int size;
+
+ size = sb->s_blocksize -
+ offsetof(struct ocfs2_dx_root_block, dr_list.l_recs);
+
+ return size / sizeof(struct ocfs2_extent_rec);
+}
+
static inline int ocfs2_chain_recs_per_inode(struct super_block *sb)
{
int size;
@@ -1132,6 +1238,26 @@ static inline u16 ocfs2_extent_recs_per_eb(struct super_block *sb)
return size / sizeof(struct ocfs2_extent_rec);
}
+static inline int ocfs2_dx_entries_per_leaf(struct super_block *sb)
+{
+ int size;
+
+ size = sb->s_blocksize -
+ offsetof(struct ocfs2_dx_leaf, dl_list.de_entries);
+
+ return size / sizeof(struct ocfs2_dx_entry);
+}
+
+static inline int ocfs2_dx_entries_per_root(struct super_block *sb)
+{
+ int size;
+
+ size = sb->s_blocksize -
+ offsetof(struct ocfs2_dx_root_block, dr_entries.de_entries);
+
+ return size / sizeof(struct ocfs2_dx_entry);
+}
+
static inline u16 ocfs2_local_alloc_size(struct super_block *sb)
{
u16 size;
diff --git a/fs/ocfs2/ocfs2_lockid.h b/fs/ocfs2/ocfs2_lockid.h
index eb6f50c9cec..a53ce87481b 100644
--- a/fs/ocfs2/ocfs2_lockid.h
+++ b/fs/ocfs2/ocfs2_lockid.h
@@ -47,6 +47,7 @@ enum ocfs2_lock_type {
OCFS2_LOCK_TYPE_OPEN,
OCFS2_LOCK_TYPE_FLOCK,
OCFS2_LOCK_TYPE_QINFO,
+ OCFS2_LOCK_TYPE_NFS_SYNC,
OCFS2_NUM_LOCK_TYPES
};
@@ -81,6 +82,9 @@ static inline char ocfs2_lock_type_char(enum ocfs2_lock_type type)
case OCFS2_LOCK_TYPE_QINFO:
c = 'Q';
break;
+ case OCFS2_LOCK_TYPE_NFS_SYNC:
+ c = 'Y';
+ break;
default:
c = '\0';
}
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index a69628603e1..b4ca5911caa 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -48,7 +48,8 @@
#include "buffer_head_io.h"
#define NOT_ALLOC_NEW_GROUP 0
-#define ALLOC_NEW_GROUP 1
+#define ALLOC_NEW_GROUP 0x1
+#define ALLOC_GROUPS_FROM_GLOBAL 0x2
#define OCFS2_MAX_INODES_TO_STEAL 1024
@@ -64,7 +65,9 @@ static int ocfs2_block_group_fill(handle_t *handle,
static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
struct inode *alloc_inode,
struct buffer_head *bh,
- u64 max_block);
+ u64 max_block,
+ u64 *last_alloc_group,
+ int flags);
static int ocfs2_cluster_group_search(struct inode *inode,
struct buffer_head *group_bh,
@@ -116,6 +119,7 @@ static inline void ocfs2_block_to_cluster_group(struct inode *inode,
u16 *bg_bit_off);
static int ocfs2_reserve_clusters_with_limit(struct ocfs2_super *osb,
u32 bits_wanted, u64 max_block,
+ int flags,
struct ocfs2_alloc_context **ac);
void ocfs2_free_ac_resource(struct ocfs2_alloc_context *ac)
@@ -403,7 +407,9 @@ static inline u16 ocfs2_find_smallest_chain(struct ocfs2_chain_list *cl)
static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
struct inode *alloc_inode,
struct buffer_head *bh,
- u64 max_block)
+ u64 max_block,
+ u64 *last_alloc_group,
+ int flags)
{
int status, credits;
struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data;
@@ -423,7 +429,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
cl = &fe->id2.i_chain;
status = ocfs2_reserve_clusters_with_limit(osb,
le16_to_cpu(cl->cl_cpg),
- max_block, &ac);
+ max_block, flags, &ac);
if (status < 0) {
if (status != -ENOSPC)
mlog_errno(status);
@@ -440,6 +446,11 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
goto bail;
}
+ if (last_alloc_group && *last_alloc_group != 0) {
+ mlog(0, "use old allocation group %llu for block group alloc\n",
+ (unsigned long long)*last_alloc_group);
+ ac->ac_last_group = *last_alloc_group;
+ }
status = ocfs2_claim_clusters(osb,
handle,
ac,
@@ -514,6 +525,11 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
alloc_inode->i_blocks = ocfs2_inode_sector_count(alloc_inode);
status = 0;
+
+ /* save the new last alloc group so that the caller can cache it. */
+ if (last_alloc_group)
+ *last_alloc_group = ac->ac_last_group;
+
bail:
if (handle)
ocfs2_commit_trans(osb, handle);
@@ -531,7 +547,8 @@ static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb,
struct ocfs2_alloc_context *ac,
int type,
u32 slot,
- int alloc_new_group)
+ u64 *last_alloc_group,
+ int flags)
{
int status;
u32 bits_wanted = ac->ac_bits_wanted;
@@ -587,7 +604,7 @@ static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb,
goto bail;
}
- if (alloc_new_group != ALLOC_NEW_GROUP) {
+ if (!(flags & ALLOC_NEW_GROUP)) {
mlog(0, "Alloc File %u Full: wanted=%u, free_bits=%u, "
"and we don't alloc a new group for it.\n",
slot, bits_wanted, free_bits);
@@ -596,7 +613,8 @@ static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb,
}
status = ocfs2_block_group_alloc(osb, alloc_inode, bh,
- ac->ac_max_block);
+ ac->ac_max_block,
+ last_alloc_group, flags);
if (status < 0) {
if (status != -ENOSPC)
mlog_errno(status);
@@ -640,7 +658,7 @@ int ocfs2_reserve_new_metadata_blocks(struct ocfs2_super *osb,
status = ocfs2_reserve_suballoc_bits(osb, (*ac),
EXTENT_ALLOC_SYSTEM_INODE,
- slot, ALLOC_NEW_GROUP);
+ slot, NULL, ALLOC_NEW_GROUP);
if (status < 0) {
if (status != -ENOSPC)
mlog_errno(status);
@@ -686,7 +704,8 @@ static int ocfs2_steal_inode_from_other_nodes(struct ocfs2_super *osb,
status = ocfs2_reserve_suballoc_bits(osb, ac,
INODE_ALLOC_SYSTEM_INODE,
- slot, NOT_ALLOC_NEW_GROUP);
+ slot, NULL,
+ NOT_ALLOC_NEW_GROUP);
if (status >= 0) {
ocfs2_set_inode_steal_slot(osb, slot);
break;
@@ -703,6 +722,7 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
{
int status;
s16 slot = ocfs2_get_inode_steal_slot(osb);
+ u64 alloc_group;
*ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
if (!(*ac)) {
@@ -738,12 +758,22 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
goto inode_steal;
atomic_set(&osb->s_num_inodes_stolen, 0);
+ alloc_group = osb->osb_inode_alloc_group;
status = ocfs2_reserve_suballoc_bits(osb, *ac,
INODE_ALLOC_SYSTEM_INODE,
- osb->slot_num, ALLOC_NEW_GROUP);
+ osb->slot_num,
+ &alloc_group,
+ ALLOC_NEW_GROUP |
+ ALLOC_GROUPS_FROM_GLOBAL);
if (status >= 0) {
status = 0;
+ spin_lock(&osb->osb_lock);
+ osb->osb_inode_alloc_group = alloc_group;
+ spin_unlock(&osb->osb_lock);
+ mlog(0, "after reservation, new allocation group is "
+ "%llu\n", (unsigned long long)alloc_group);
+
/*
* Some inodes must be freed by us, so try to allocate
* from our own next time.
@@ -790,7 +820,7 @@ int ocfs2_reserve_cluster_bitmap_bits(struct ocfs2_super *osb,
status = ocfs2_reserve_suballoc_bits(osb, ac,
GLOBAL_BITMAP_SYSTEM_INODE,
- OCFS2_INVALID_SLOT,
+ OCFS2_INVALID_SLOT, NULL,
ALLOC_NEW_GROUP);
if (status < 0 && status != -ENOSPC) {
mlog_errno(status);
@@ -806,6 +836,7 @@ bail:
* things a bit. */
static int ocfs2_reserve_clusters_with_limit(struct ocfs2_super *osb,
u32 bits_wanted, u64 max_block,
+ int flags,
struct ocfs2_alloc_context **ac)
{
int status;
@@ -823,7 +854,8 @@ static int ocfs2_reserve_clusters_with_limit(struct ocfs2_super *osb,
(*ac)->ac_max_block = max_block;
status = -ENOSPC;
- if (ocfs2_alloc_should_use_local(osb, bits_wanted)) {
+ if (!(flags & ALLOC_GROUPS_FROM_GLOBAL) &&
+ ocfs2_alloc_should_use_local(osb, bits_wanted)) {
status = ocfs2_reserve_local_alloc_bits(osb,
bits_wanted,
*ac);
@@ -861,7 +893,8 @@ int ocfs2_reserve_clusters(struct ocfs2_super *osb,
u32 bits_wanted,
struct ocfs2_alloc_context **ac)
{
- return ocfs2_reserve_clusters_with_limit(osb, bits_wanted, 0, ac);
+ return ocfs2_reserve_clusters_with_limit(osb, bits_wanted, 0,
+ ALLOC_NEW_GROUP, ac);
}
/*
@@ -1618,8 +1651,41 @@ bail:
return status;
}
+static void ocfs2_init_inode_ac_group(struct inode *dir,
+ struct buffer_head *parent_fe_bh,
+ struct ocfs2_alloc_context *ac)
+{
+ struct ocfs2_dinode *fe = (struct ocfs2_dinode *)parent_fe_bh->b_data;
+ /*
+ * Try to allocate inodes from some specific group.
+ *
+ * If the parent dir has recorded the last group used in allocation,
+ * cool, use it. Otherwise if we try to allocate new inode from the
+ * same slot the parent dir belongs to, use the same chunk.
+ *
+ * We are very careful here to avoid the mistake of setting
+ * ac_last_group to a group descriptor from a different (unlocked) slot.
+ */
+ if (OCFS2_I(dir)->ip_last_used_group &&
+ OCFS2_I(dir)->ip_last_used_slot == ac->ac_alloc_slot)
+ ac->ac_last_group = OCFS2_I(dir)->ip_last_used_group;
+ else if (le16_to_cpu(fe->i_suballoc_slot) == ac->ac_alloc_slot)
+ ac->ac_last_group = ocfs2_which_suballoc_group(
+ le64_to_cpu(fe->i_blkno),
+ le16_to_cpu(fe->i_suballoc_bit));
+}
+
+static inline void ocfs2_save_inode_ac_group(struct inode *dir,
+ struct ocfs2_alloc_context *ac)
+{
+ OCFS2_I(dir)->ip_last_used_group = ac->ac_last_group;
+ OCFS2_I(dir)->ip_last_used_slot = ac->ac_alloc_slot;
+}
+
int ocfs2_claim_new_inode(struct ocfs2_super *osb,
handle_t *handle,
+ struct inode *dir,
+ struct buffer_head *parent_fe_bh,
struct ocfs2_alloc_context *ac,
u16 *suballoc_bit,
u64 *fe_blkno)
@@ -1635,6 +1701,8 @@ int ocfs2_claim_new_inode(struct ocfs2_super *osb,
BUG_ON(ac->ac_bits_wanted != 1);
BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE);
+ ocfs2_init_inode_ac_group(dir, parent_fe_bh, ac);
+
status = ocfs2_claim_suballoc_bits(osb,
ac,
handle,
@@ -1653,6 +1721,7 @@ int ocfs2_claim_new_inode(struct ocfs2_super *osb,
*fe_blkno = bg_blkno + (u64) (*suballoc_bit);
ac->ac_bits_given++;
+ ocfs2_save_inode_ac_group(dir, ac);
status = 0;
bail:
mlog_exit(status);
@@ -2116,3 +2185,162 @@ out:
return ret;
}
+
+/*
+ * Read the inode specified by blkno to get suballoc_slot and
+ * suballoc_bit.
+ */
+static int ocfs2_get_suballoc_slot_bit(struct ocfs2_super *osb, u64 blkno,
+ u16 *suballoc_slot, u16 *suballoc_bit)
+{
+ int status;
+ struct buffer_head *inode_bh = NULL;
+ struct ocfs2_dinode *inode_fe;
+
+ mlog_entry("blkno: %llu\n", blkno);
+
+ /* dirty read disk */
+ status = ocfs2_read_blocks_sync(osb, blkno, 1, &inode_bh);
+ if (status < 0) {
+ mlog(ML_ERROR, "read block %llu failed %d\n", blkno, status);
+ goto bail;
+ }
+
+ inode_fe = (struct ocfs2_dinode *) inode_bh->b_data;
+ if (!OCFS2_IS_VALID_DINODE(inode_fe)) {
+ mlog(ML_ERROR, "invalid inode %llu requested\n", blkno);
+ status = -EINVAL;
+ goto bail;
+ }
+
+ if (le16_to_cpu(inode_fe->i_suballoc_slot) != OCFS2_INVALID_SLOT &&
+ (u32)le16_to_cpu(inode_fe->i_suballoc_slot) > osb->max_slots - 1) {
+ mlog(ML_ERROR, "inode %llu has invalid suballoc slot %u\n",
+ blkno, (u32)le16_to_cpu(inode_fe->i_suballoc_slot));
+ status = -EINVAL;
+ goto bail;
+ }
+
+ if (suballoc_slot)
+ *suballoc_slot = le16_to_cpu(inode_fe->i_suballoc_slot);
+ if (suballoc_bit)
+ *suballoc_bit = le16_to_cpu(inode_fe->i_suballoc_bit);
+
+bail:
+ brelse(inode_bh);
+
+ mlog_exit(status);
+ return status;
+}
+
+/*
+ * test whether bit is SET in allocator bitmap or not. on success, 0
+ * is returned and *res is 1 for SET; 0 otherwise. when fails, errno
+ * is returned and *res is meaningless. Call this after you have
+ * cluster locked against suballoc, or you may get a result based on
+ * non-up2date contents
+ */
+static int ocfs2_test_suballoc_bit(struct ocfs2_super *osb,
+ struct inode *suballoc,
+ struct buffer_head *alloc_bh, u64 blkno,
+ u16 bit, int *res)
+{
+ struct ocfs2_dinode *alloc_fe;
+ struct ocfs2_group_desc *group;
+ struct buffer_head *group_bh = NULL;
+ u64 bg_blkno;
+ int status;
+
+ mlog_entry("blkno: %llu bit: %u\n", blkno, (unsigned int)bit);
+
+ alloc_fe = (struct ocfs2_dinode *)alloc_bh->b_data;
+ if ((bit + 1) > ocfs2_bits_per_group(&alloc_fe->id2.i_chain)) {
+ mlog(ML_ERROR, "suballoc bit %u out of range of %u\n",
+ (unsigned int)bit,
+ ocfs2_bits_per_group(&alloc_fe->id2.i_chain));
+ status = -EINVAL;
+ goto bail;
+ }
+
+ bg_blkno = ocfs2_which_suballoc_group(blkno, bit);
+ status = ocfs2_read_group_descriptor(suballoc, alloc_fe, bg_blkno,
+ &group_bh);
+ if (status < 0) {
+ mlog(ML_ERROR, "read group %llu failed %d\n", bg_blkno, status);
+ goto bail;
+ }
+
+ group = (struct ocfs2_group_desc *) group_bh->b_data;
+ *res = ocfs2_test_bit(bit, (unsigned long *)group->bg_bitmap);
+
+bail:
+ brelse(group_bh);
+
+ mlog_exit(status);
+ return status;
+}
+
+/*
+ * Test if the bit representing this inode (blkno) is set in the
+ * suballocator.
+ *
+ * On success, 0 is returned and *res is 1 for SET; 0 otherwise.
+ *
+ * In the event of failure, a negative value is returned and *res is
+ * meaningless.
+ *
+ * Callers must make sure to hold nfs_sync_lock to prevent
+ * ocfs2_delete_inode() on another node from accessing the same
+ * suballocator concurrently.
+ */
+int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res)
+{
+ int status;
+ u16 suballoc_bit = 0, suballoc_slot = 0;
+ struct inode *inode_alloc_inode;
+ struct buffer_head *alloc_bh = NULL;
+
+ mlog_entry("blkno: %llu", blkno);
+
+ status = ocfs2_get_suballoc_slot_bit(osb, blkno, &suballoc_slot,
+ &suballoc_bit);
+ if (status < 0) {
+ mlog(ML_ERROR, "get alloc slot and bit failed %d\n", status);
+ goto bail;
+ }
+
+ inode_alloc_inode =
+ ocfs2_get_system_file_inode(osb, INODE_ALLOC_SYSTEM_INODE,
+ suballoc_slot);
+ if (!inode_alloc_inode) {
+ /* the error code could be inaccurate, but we are not able to
+ * get the correct one. */
+ status = -EINVAL;
+ mlog(ML_ERROR, "unable to get alloc inode in slot %u\n",
+ (u32)suballoc_slot);
+ goto bail;
+ }
+
+ mutex_lock(&inode_alloc_inode->i_mutex);
+ status = ocfs2_inode_lock(inode_alloc_inode, &alloc_bh, 0);
+ if (status < 0) {
+ mutex_unlock(&inode_alloc_inode->i_mutex);
+ mlog(ML_ERROR, "lock on alloc inode on slot %u failed %d\n",
+ (u32)suballoc_slot, status);
+ goto bail;
+ }
+
+ status = ocfs2_test_suballoc_bit(osb, inode_alloc_inode, alloc_bh,
+ blkno, suballoc_bit, res);
+ if (status < 0)
+ mlog(ML_ERROR, "test suballoc bit failed %d\n", status);
+
+ ocfs2_inode_unlock(inode_alloc_inode, 0);
+ mutex_unlock(&inode_alloc_inode->i_mutex);
+
+ iput(inode_alloc_inode);
+ brelse(alloc_bh);
+bail:
+ mlog_exit(status);
+ return status;
+}
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h
index e3c13c77f9e..8c9a78a4316 100644
--- a/fs/ocfs2/suballoc.h
+++ b/fs/ocfs2/suballoc.h
@@ -88,6 +88,8 @@ int ocfs2_claim_metadata(struct ocfs2_super *osb,
u64 *blkno_start);
int ocfs2_claim_new_inode(struct ocfs2_super *osb,
handle_t *handle,
+ struct inode *dir,
+ struct buffer_head *parent_fe_bh,
struct ocfs2_alloc_context *ac,
u16 *suballoc_bit,
u64 *fe_blkno);
@@ -186,4 +188,6 @@ int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_extent_tree *et,
u32 clusters_to_add, u32 extents_to_split,
struct ocfs2_alloc_context **data_ac,
struct ocfs2_alloc_context **meta_ac);
+
+int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res);
#endif /* _CHAINALLOC_H_ */
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 7ac83a81ee5..79ff8d9d37e 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -201,6 +201,170 @@ static const match_table_t tokens = {
{Opt_err, NULL}
};
+#ifdef CONFIG_DEBUG_FS
+static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len)
+{
+ int out = 0;
+ int i;
+ struct ocfs2_cluster_connection *cconn = osb->cconn;
+ struct ocfs2_recovery_map *rm = osb->recovery_map;
+
+ out += snprintf(buf + out, len - out,
+ "%10s => Id: %-s Uuid: %-s Gen: 0x%X Label: %-s\n",
+ "Device", osb->dev_str, osb->uuid_str,
+ osb->fs_generation, osb->vol_label);
+
+ out += snprintf(buf + out, len - out,
+ "%10s => State: %d Flags: 0x%lX\n", "Volume",
+ atomic_read(&osb->vol_state), osb->osb_flags);
+
+ out += snprintf(buf + out, len - out,
+ "%10s => Block: %lu Cluster: %d\n", "Sizes",
+ osb->sb->s_blocksize, osb->s_clustersize);
+
+ out += snprintf(buf + out, len - out,
+ "%10s => Compat: 0x%X Incompat: 0x%X "
+ "ROcompat: 0x%X\n",
+ "Features", osb->s_feature_compat,
+ osb->s_feature_incompat, osb->s_feature_ro_compat);
+
+ out += snprintf(buf + out, len - out,
+ "%10s => Opts: 0x%lX AtimeQuanta: %u\n", "Mount",
+ osb->s_mount_opt, osb->s_atime_quantum);
+
+ out += snprintf(buf + out, len - out,
+ "%10s => Stack: %s Name: %*s Version: %d.%d\n",
+ "Cluster",
+ (*osb->osb_cluster_stack == '\0' ?
+ "o2cb" : osb->osb_cluster_stack),
+ cconn->cc_namelen, cconn->cc_name,
+ cconn->cc_version.pv_major, cconn->cc_version.pv_minor);
+
+ spin_lock(&osb->dc_task_lock);
+ out += snprintf(buf + out, len - out,
+ "%10s => Pid: %d Count: %lu WakeSeq: %lu "
+ "WorkSeq: %lu\n", "DownCnvt",
+ task_pid_nr(osb->dc_task), osb->blocked_lock_count,
+ osb->dc_wake_sequence, osb->dc_work_sequence);
+ spin_unlock(&osb->dc_task_lock);
+
+ spin_lock(&osb->osb_lock);
+ out += snprintf(buf + out, len - out, "%10s => Pid: %d Nodes:",
+ "Recovery",
+ (osb->recovery_thread_task ?
+ task_pid_nr(osb->recovery_thread_task) : -1));
+ if (rm->rm_used == 0)
+ out += snprintf(buf + out, len - out, " None\n");
+ else {
+ for (i = 0; i < rm->rm_used; i++)
+ out += snprintf(buf + out, len - out, " %d",
+ rm->rm_entries[i]);
+ out += snprintf(buf + out, len - out, "\n");
+ }
+ spin_unlock(&osb->osb_lock);
+
+ out += snprintf(buf + out, len - out,
+ "%10s => Pid: %d Interval: %lu Needs: %d\n", "Commit",
+ task_pid_nr(osb->commit_task), osb->osb_commit_interval,
+ atomic_read(&osb->needs_checkpoint));
+
+ out += snprintf(buf + out, len - out,
+ "%10s => State: %d NumTxns: %d TxnId: %lu\n",
+ "Journal", osb->journal->j_state,
+ atomic_read(&osb->journal->j_num_trans),
+ osb->journal->j_trans_id);
+
+ out += snprintf(buf + out, len - out,
+ "%10s => GlobalAllocs: %d LocalAllocs: %d "
+ "SubAllocs: %d LAWinMoves: %d SAExtends: %d\n",
+ "Stats",
+ atomic_read(&osb->alloc_stats.bitmap_data),
+ atomic_read(&osb->alloc_stats.local_data),
+ atomic_read(&osb->alloc_stats.bg_allocs),
+ atomic_read(&osb->alloc_stats.moves),
+ atomic_read(&osb->alloc_stats.bg_extends));
+
+ out += snprintf(buf + out, len - out,
+ "%10s => State: %u Descriptor: %llu Size: %u bits "
+ "Default: %u bits\n",
+ "LocalAlloc", osb->local_alloc_state,
+ (unsigned long long)osb->la_last_gd,
+ osb->local_alloc_bits, osb->local_alloc_default_bits);
+
+ spin_lock(&osb->osb_lock);
+ out += snprintf(buf + out, len - out,
+ "%10s => Slot: %d NumStolen: %d\n", "Steal",
+ osb->s_inode_steal_slot,
+ atomic_read(&osb->s_num_inodes_stolen));
+ spin_unlock(&osb->osb_lock);
+
+ out += snprintf(buf + out, len - out, "%10s => %3s %10s\n",
+ "Slots", "Num", "RecoGen");
+
+ for (i = 0; i < osb->max_slots; ++i) {
+ out += snprintf(buf + out, len - out,
+ "%10s %c %3d %10d\n",
+ " ",
+ (i == osb->slot_num ? '*' : ' '),
+ i, osb->slot_recovery_generations[i]);
+ }
+
+ return out;
+}
+
+static int ocfs2_osb_debug_open(struct inode *inode, struct file *file)
+{
+ struct ocfs2_super *osb = inode->i_private;
+ char *buf = NULL;
+
+ buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!buf)
+ goto bail;
+
+ i_size_write(inode, ocfs2_osb_dump(osb, buf, PAGE_SIZE));
+
+ file->private_data = buf;
+
+ return 0;
+bail:
+ return -ENOMEM;
+}
+
+static int ocfs2_debug_release(struct inode *inode, struct file *file)
+{
+ kfree(file->private_data);
+ return 0;
+}
+
+static ssize_t ocfs2_debug_read(struct file *file, char __user *buf,
+ size_t nbytes, loff_t *ppos)
+{
+ return simple_read_from_buffer(buf, nbytes, ppos, file->private_data,
+ i_size_read(file->f_mapping->host));
+}
+#else
+static int ocfs2_osb_debug_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+static int ocfs2_debug_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+static ssize_t ocfs2_debug_read(struct file *file, char __user *buf,
+ size_t nbytes, loff_t *ppos)
+{
+ return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static struct file_operations ocfs2_osb_debug_fops = {
+ .open = ocfs2_osb_debug_open,
+ .release = ocfs2_debug_release,
+ .read = ocfs2_debug_read,
+ .llseek = generic_file_llseek,
+};
+
/*
* write_super and sync_fs ripped right out of ext3.
*/
@@ -926,6 +1090,16 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
goto read_super_error;
}
+ osb->osb_ctxt = debugfs_create_file("fs_state", S_IFREG|S_IRUSR,
+ osb->osb_debug_root,
+ osb,
+ &ocfs2_osb_debug_fops);
+ if (!osb->osb_ctxt) {
+ status = -EINVAL;
+ mlog_errno(status);
+ goto read_super_error;
+ }
+
status = ocfs2_mount_volume(sb);
if (osb->root_inode)
inode = igrab(osb->root_inode);
@@ -1620,6 +1794,8 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
osb = OCFS2_SB(sb);
BUG_ON(!osb);
+ debugfs_remove(osb->osb_ctxt);
+
ocfs2_disable_quotas(osb);
ocfs2_shutdown_local_alloc(osb);
@@ -1742,6 +1918,12 @@ static int ocfs2_initialize_super(struct super_block *sb,
bbits = le32_to_cpu(di->id2.i_super.s_blocksize_bits);
sb->s_maxbytes = ocfs2_max_file_offset(bbits, cbits);
+ osb->osb_dx_mask = (1 << (cbits - bbits)) - 1;
+
+ for (i = 0; i < 3; i++)
+ osb->osb_dx_seed[i] = le32_to_cpu(di->id2.i_super.s_dx_seed[i]);
+ osb->osb_dx_seed[3] = le32_to_cpu(di->id2.i_super.s_uuid_hash);
+
osb->sb = sb;
/* Save off for ocfs2_rw_direct */
osb->s_sectsize_bits = blksize_bits(sector_size);
@@ -2130,6 +2312,12 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
* lock, and it's marked as dirty, set the bit in the recover
* map and launch a recovery thread for it. */
status = ocfs2_mark_dead_nodes(osb);
+ if (status < 0) {
+ mlog_errno(status);
+ goto finally;
+ }
+
+ status = ocfs2_compute_replay_slots(osb);
if (status < 0)
mlog_errno(status);
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 2563df89fc2..15631019dc6 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -512,7 +512,7 @@ int ocfs2_calc_xattr_init(struct inode *dir,
struct ocfs2_security_xattr_info *si,
int *want_clusters,
int *xattr_credits,
- struct ocfs2_alloc_context **xattr_ac)
+ int *want_meta)
{
int ret = 0;
struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
@@ -554,11 +554,7 @@ int ocfs2_calc_xattr_init(struct inode *dir,
if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE ||
(S_ISDIR(mode) && ocfs2_supports_inline_data(osb)) ||
(s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) {
- ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac);
- if (ret) {
- mlog_errno(ret);
- return ret;
- }
+ *want_meta = *want_meta + 1;
*xattr_credits += OCFS2_XATTR_BLOCK_CREATE_CREDITS;
}
diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h
index 5a1ebc789f7..1ca7e9a1b7b 100644
--- a/fs/ocfs2/xattr.h
+++ b/fs/ocfs2/xattr.h
@@ -68,7 +68,7 @@ int ocfs2_calc_security_init(struct inode *,
int *, int *, struct ocfs2_alloc_context **);
int ocfs2_calc_xattr_init(struct inode *, struct buffer_head *,
int, struct ocfs2_security_xattr_info *,
- int *, int *, struct ocfs2_alloc_context **);
+ int *, int *, int *);
/*
* xattrs can live inside an inode, as part of an external xattr block,
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 38e337d51ce..99e33ef40be 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -19,6 +19,7 @@
#include <linux/kmod.h>
#include <linux/ctype.h>
#include <linux/genhd.h>
+#include <linux/blktrace_api.h>
#include "check.h"
@@ -294,6 +295,9 @@ static struct attribute_group part_attr_group = {
static struct attribute_group *part_attr_groups[] = {
&part_attr_group,
+#ifdef CONFIG_BLK_DEV_IO_TRACE
+ &blk_trace_attr_group,
+#endif
NULL
};
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
index b446d7ad0b0..7e14d1a0400 100644
--- a/fs/proc/nommu.c
+++ b/fs/proc/nommu.c
@@ -76,7 +76,7 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
/*
* display a list of all the REGIONs the kernel knows about
- * - nommu kernals have a single flat list
+ * - nommu kernels have a single flat list
*/
static int nommu_region_list_show(struct seq_file *m, void *_p)
{
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index b0ae0be4801..39e4ad4f59f 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -204,6 +204,7 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
struct file *file = vma->vm_file;
int flags = vma->vm_flags;
unsigned long ino = 0;
+ unsigned long long pgoff = 0;
dev_t dev = 0;
int len;
@@ -211,6 +212,7 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
dev = inode->i_sb->s_dev;
ino = inode->i_ino;
+ pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
}
seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
@@ -220,7 +222,7 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
flags & VM_WRITE ? 'w' : '-',
flags & VM_EXEC ? 'x' : '-',
flags & VM_MAYSHARE ? 's' : 'p',
- ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
+ pgoff,
MAJOR(dev), MINOR(dev), ino, &len);
/*
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
index 863464d5519..64a72e2e765 100644
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -126,6 +126,7 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
struct file *file;
dev_t dev = 0;
int flags, len;
+ unsigned long long pgoff = 0;
flags = vma->vm_flags;
file = vma->vm_file;
@@ -134,6 +135,7 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
dev = inode->i_sb->s_dev;
ino = inode->i_ino;
+ pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
}
seq_printf(m,
@@ -144,7 +146,7 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
flags & VM_WRITE ? 'w' : '-',
flags & VM_EXEC ? 'x' : '-',
flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p',
- (unsigned long long) vma->vm_pgoff << PAGE_SHIFT,
+ pgoff,
MAJOR(dev), MINOR(dev), ino, &len);
if (file) {
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index a404fb88e45..3a6b193d844 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -221,22 +221,23 @@ static int ramfs_fill_super(struct super_block * sb, void * data, int silent)
save_mount_options(sb, data);
fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL);
+ sb->s_fs_info = fsi;
if (!fsi) {
err = -ENOMEM;
goto fail;
}
- sb->s_fs_info = fsi;
err = ramfs_parse_options(data, &fsi->mount_opts);
if (err)
goto fail;
- sb->s_maxbytes = MAX_LFS_FILESIZE;
- sb->s_blocksize = PAGE_CACHE_SIZE;
- sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
- sb->s_magic = RAMFS_MAGIC;
- sb->s_op = &ramfs_ops;
- sb->s_time_gran = 1;
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
+ sb->s_blocksize = PAGE_CACHE_SIZE;
+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+ sb->s_magic = RAMFS_MAGIC;
+ sb->s_op = &ramfs_ops;
+ sb->s_time_gran = 1;
+
inode = ramfs_get_inode(sb, S_IFDIR | fsi->mount_opts.mode, 0);
if (!inode) {
err = -ENOMEM;
@@ -244,14 +245,16 @@ static int ramfs_fill_super(struct super_block * sb, void * data, int silent)
}
root = d_alloc_root(inode);
+ sb->s_root = root;
if (!root) {
err = -ENOMEM;
goto fail;
}
- sb->s_root = root;
+
return 0;
fail:
kfree(fsi);
+ sb->s_fs_info = NULL;
iput(inode);
return err;
}
diff --git a/fs/read_write.c b/fs/read_write.c
index 6d5d8ff238a..9d1e76bb9ee 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -731,10 +731,16 @@ SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec,
return ret;
}
+static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
+{
+#define HALF_LONG_BITS (BITS_PER_LONG / 2)
+ return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low;
+}
+
SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
- unsigned long, vlen, u32, pos_high, u32, pos_low)
+ unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
{
- loff_t pos = ((loff_t)pos_high << 32) | pos_low;
+ loff_t pos = pos_from_hilo(pos_h, pos_l);
struct file *file;
ssize_t ret = -EBADF;
int fput_needed;
@@ -757,9 +763,9 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
}
SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
- unsigned long, vlen, u32, pos_high, u32, pos_low)
+ unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
{
- loff_t pos = ((loff_t)pos_high << 32) | pos_low;
+ loff_t pos = pos_from_hilo(pos_h, pos_l);
struct file *file;
ssize_t ret = -EBADF;
int fput_needed;
diff --git a/fs/romfs/Kconfig b/fs/romfs/Kconfig
index 1a17020f9fa..ce2d6bcc626 100644
--- a/fs/romfs/Kconfig
+++ b/fs/romfs/Kconfig
@@ -1,6 +1,6 @@
config ROMFS_FS
tristate "ROM file system support"
- depends on BLOCK
+ depends on BLOCK || MTD
---help---
This is a very small read-only file system mainly intended for
initial ram disks of installation disks, but it could be used for
@@ -14,3 +14,49 @@ config ROMFS_FS
If you don't know whether you need it, then you don't need it:
answer N.
+
+#
+# Select the backing stores to be supported
+#
+choice
+ prompt "RomFS backing stores"
+ depends on ROMFS_FS
+ default ROMFS_BACKED_BY_BLOCK
+ help
+ Select the backing stores to be supported.
+
+config ROMFS_BACKED_BY_BLOCK
+ bool "Block device-backed ROM file system support"
+ depends on BLOCK
+ help
+ This permits ROMFS to use block devices buffered through the page
+ cache as the medium from which to retrieve data. It does not allow
+ direct mapping of the medium.
+
+ If unsure, answer Y.
+
+config ROMFS_BACKED_BY_MTD
+ bool "MTD-backed ROM file system support"
+ depends on MTD=y || (ROMFS_FS=m && MTD)
+ help
+ This permits ROMFS to use MTD based devices directly, without the
+ intercession of the block layer (which may have been disabled). It
+ also allows direct mapping of MTD devices through romfs files under
+ NOMMU conditions if the underlying device is directly addressable by
+ the CPU.
+
+ If unsure, answer Y.
+
+config ROMFS_BACKED_BY_BOTH
+ bool "Both the above"
+ depends on BLOCK && (MTD=y || (ROMFS_FS=m && MTD))
+endchoice
+
+
+config ROMFS_ON_BLOCK
+ bool
+ default y if ROMFS_BACKED_BY_BLOCK || ROMFS_BACKED_BY_BOTH
+
+config ROMFS_ON_MTD
+ bool
+ default y if ROMFS_BACKED_BY_MTD || ROMFS_BACKED_BY_BOTH
diff --git a/fs/romfs/Makefile b/fs/romfs/Makefile
index c95b21cf49a..420beb7d495 100644
--- a/fs/romfs/Makefile
+++ b/fs/romfs/Makefile
@@ -1,7 +1,12 @@
#
-# Makefile for the linux romfs filesystem routines.
+# Makefile for the linux RomFS filesystem routines.
#
obj-$(CONFIG_ROMFS_FS) += romfs.o
-romfs-objs := inode.o
+romfs-y := storage.o super.o
+
+ifneq ($(CONFIG_MMU),y)
+romfs-$(CONFIG_ROMFS_ON_MTD) += mmap-nommu.o
+endif
+
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
deleted file mode 100644
index 98a232f7196..00000000000
--- a/fs/romfs/inode.c
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
- * ROMFS file system, Linux implementation
- *
- * Copyright (C) 1997-1999 Janos Farkas <chexum@shadow.banki.hu>
- *
- * Using parts of the minix filesystem
- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- * and parts of the affs filesystem additionally
- * Copyright (C) 1993 Ray Burr
- * Copyright (C) 1996 Hans-Joachim Widmaier
- *
- * 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.
- *
- * Changes
- * Changed for 2.1.19 modules
- * Jan 1997 Initial release
- * Jun 1997 2.1.43+ changes
- * Proper page locking in readpage
- * Changed to work with 2.1.45+ fs
- * Jul 1997 Fixed follow_link
- * 2.1.47
- * lookup shouldn't return -ENOENT
- * from Horst von Brand:
- * fail on wrong checksum
- * double unlock_super was possible
- * correct namelen for statfs
- * spotted by Bill Hawes:
- * readlink shouldn't iput()
- * Jun 1998 2.1.106 from Avery Pennarun: glibc scandir()
- * exposed a problem in readdir
- * 2.1.107 code-freeze spellchecker run
- * Aug 1998 2.1.118+ VFS changes
- * Sep 1998 2.1.122 another VFS change (follow_link)
- * Apr 1999 2.2.7 no more EBADF checking in
- * lookup/readdir, use ERR_PTR
- * Jun 1999 2.3.6 d_alloc_root use changed
- * 2.3.9 clean up usage of ENOENT/negative
- * dentries in lookup
- * clean up page flags setting
- * (error, uptodate, locking) in
- * in readpage
- * use init_special_inode for
- * fifos/sockets (and streamline) in
- * read_inode, fix _ops table order
- * Aug 1999 2.3.16 __initfunc() => __init change
- * Oct 1999 2.3.24 page->owner hack obsoleted
- * Nov 1999 2.3.27 2.3.25+ page->offset => index change
- */
-
-/* todo:
- * - see Documentation/filesystems/romfs.txt
- * - use allocated, not stack memory for file names?
- * - considering write access...
- * - network (tftp) files?
- * - merge back some _op tables
- */
-
-/*
- * Sorry about some optimizations and for some goto's. I just wanted
- * to squeeze some more bytes out of this code.. :)
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/romfs_fs.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
-#include <linux/buffer_head.h>
-#include <linux/vfs.h>
-
-#include <asm/uaccess.h>
-
-struct romfs_inode_info {
- unsigned long i_metasize; /* size of non-data area */
- unsigned long i_dataoffset; /* from the start of fs */
- struct inode vfs_inode;
-};
-
-static struct inode *romfs_iget(struct super_block *, unsigned long);
-
-/* instead of private superblock data */
-static inline unsigned long romfs_maxsize(struct super_block *sb)
-{
- return (unsigned long)sb->s_fs_info;
-}
-
-static inline struct romfs_inode_info *ROMFS_I(struct inode *inode)
-{
- return container_of(inode, struct romfs_inode_info, vfs_inode);
-}
-
-static __u32
-romfs_checksum(void *data, int size)
-{
- __u32 sum;
- __be32 *ptr;
-
- sum = 0; ptr = data;
- size>>=2;
- while (size>0) {
- sum += be32_to_cpu(*ptr++);
- size--;
- }
- return sum;
-}
-
-static const struct super_operations romfs_ops;
-
-static int romfs_fill_super(struct super_block *s, void *data, int silent)
-{
- struct buffer_head *bh;
- struct romfs_super_block *rsb;
- struct inode *root;
- int sz, ret = -EINVAL;
-
- /* I would parse the options here, but there are none.. :) */
-
- sb_set_blocksize(s, ROMBSIZE);
- s->s_maxbytes = 0xFFFFFFFF;
-
- bh = sb_bread(s, 0);
- if (!bh) {
- /* XXX merge with other printk? */
- printk ("romfs: unable to read superblock\n");
- goto outnobh;
- }
-
- rsb = (struct romfs_super_block *)bh->b_data;
- sz = be32_to_cpu(rsb->size);
- if (rsb->word0 != ROMSB_WORD0 || rsb->word1 != ROMSB_WORD1
- || sz < ROMFH_SIZE) {
- if (!silent)
- printk ("VFS: Can't find a romfs filesystem on dev "
- "%s.\n", s->s_id);
- goto out;
- }
- if (romfs_checksum(rsb, min_t(int, sz, 512))) {
- printk ("romfs: bad initial checksum on dev "
- "%s.\n", s->s_id);
- goto out;
- }
-
- s->s_magic = ROMFS_MAGIC;
- s->s_fs_info = (void *)(long)sz;
-
- s->s_flags |= MS_RDONLY;
-
- /* Find the start of the fs */
- sz = (ROMFH_SIZE +
- strnlen(rsb->name, ROMFS_MAXFN) + 1 + ROMFH_PAD)
- & ROMFH_MASK;
-
- s->s_op = &romfs_ops;
- root = romfs_iget(s, sz);
- if (IS_ERR(root)) {
- ret = PTR_ERR(root);
- goto out;
- }
-
- ret = -ENOMEM;
- s->s_root = d_alloc_root(root);
- if (!s->s_root)
- goto outiput;
-
- brelse(bh);
- return 0;
-
-outiput:
- iput(root);
-out:
- brelse(bh);
-outnobh:
- return ret;
-}
-
-/* That's simple too. */
-
-static int
-romfs_statfs(struct dentry *dentry, struct kstatfs *buf)
-{
- buf->f_type = ROMFS_MAGIC;
- buf->f_bsize = ROMBSIZE;
- buf->f_bfree = buf->f_bavail = buf->f_ffree;
- buf->f_blocks = (romfs_maxsize(dentry->d_sb)+ROMBSIZE-1)>>ROMBSBITS;
- buf->f_namelen = ROMFS_MAXFN;
- return 0;
-}
-
-/* some helper routines */
-
-static int
-romfs_strnlen(struct inode *i, unsigned long offset, unsigned long count)
-{
- struct buffer_head *bh;
- unsigned long avail, maxsize, res;
-
- maxsize = romfs_maxsize(i->i_sb);
- if (offset >= maxsize)
- return -1;
-
- /* strnlen is almost always valid */
- if (count > maxsize || offset+count > maxsize)
- count = maxsize-offset;
-
- bh = sb_bread(i->i_sb, offset>>ROMBSBITS);
- if (!bh)
- return -1; /* error */
-
- avail = ROMBSIZE - (offset & ROMBMASK);
- maxsize = min_t(unsigned long, count, avail);
- res = strnlen(((char *)bh->b_data)+(offset&ROMBMASK), maxsize);
- brelse(bh);
-
- if (res < maxsize)
- return res; /* found all of it */
-
- while (res < count) {
- offset += maxsize;
-
- bh = sb_bread(i->i_sb, offset>>ROMBSBITS);
- if (!bh)
- return -1;
- maxsize = min_t(unsigned long, count - res, ROMBSIZE);
- avail = strnlen(bh->b_data, maxsize);
- res += avail;
- brelse(bh);
- if (avail < maxsize)
- return res;
- }
- return res;
-}
-
-static int
-romfs_copyfrom(struct inode *i, void *dest, unsigned long offset, unsigned long count)
-{
- struct buffer_head *bh;
- unsigned long avail, maxsize, res;
-
- maxsize = romfs_maxsize(i->i_sb);
- if (offset >= maxsize || count > maxsize || offset+count>maxsize)
- return -1;
-
- bh = sb_bread(i->i_sb, offset>>ROMBSBITS);
- if (!bh)
- return -1; /* error */
-
- avail = ROMBSIZE - (offset & ROMBMASK);
- maxsize = min_t(unsigned long, count, avail);
- memcpy(dest, ((char *)bh->b_data) + (offset & ROMBMASK), maxsize);
- brelse(bh);
-
- res = maxsize; /* all of it */
-
- while (res < count) {
- offset += maxsize;
- dest += maxsize;
-
- bh = sb_bread(i->i_sb, offset>>ROMBSBITS);
- if (!bh)
- return -1;
- maxsize = min_t(unsigned long, count - res, ROMBSIZE);
- memcpy(dest, bh->b_data, maxsize);
- brelse(bh);
- res += maxsize;
- }
- return res;
-}
-
-static unsigned char romfs_dtype_table[] = {
- DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_SOCK, DT_FIFO
-};
-
-static int
-romfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
-{
- struct inode *i = filp->f_path.dentry->d_inode;
- struct romfs_inode ri;
- unsigned long offset, maxoff;
- int j, ino, nextfh;
- int stored = 0;
- char fsname[ROMFS_MAXFN]; /* XXX dynamic? */
-
- lock_kernel();
-
- maxoff = romfs_maxsize(i->i_sb);
-
- offset = filp->f_pos;
- if (!offset) {
- offset = i->i_ino & ROMFH_MASK;
- if (romfs_copyfrom(i, &ri, offset, ROMFH_SIZE) <= 0)
- goto out;
- offset = be32_to_cpu(ri.spec) & ROMFH_MASK;
- }
-
- /* Not really failsafe, but we are read-only... */
- for(;;) {
- if (!offset || offset >= maxoff) {
- offset = maxoff;
- filp->f_pos = offset;
- goto out;
- }
- filp->f_pos = offset;
-
- /* Fetch inode info */
- if (romfs_copyfrom(i, &ri, offset, ROMFH_SIZE) <= 0)
- goto out;
-
- j = romfs_strnlen(i, offset+ROMFH_SIZE, sizeof(fsname)-1);
- if (j < 0)
- goto out;
-
- fsname[j]=0;
- romfs_copyfrom(i, fsname, offset+ROMFH_SIZE, j);
-
- ino = offset;
- nextfh = be32_to_cpu(ri.next);
- if ((nextfh & ROMFH_TYPE) == ROMFH_HRD)
- ino = be32_to_cpu(ri.spec);
- if (filldir(dirent, fsname, j, offset, ino,
- romfs_dtype_table[nextfh & ROMFH_TYPE]) < 0) {
- goto out;
- }
- stored++;
- offset = nextfh & ROMFH_MASK;
- }
-out:
- unlock_kernel();
- return stored;
-}
-
-static struct dentry *
-romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
-{
- unsigned long offset, maxoff;
- long res;
- int fslen;
- struct inode *inode = NULL;
- char fsname[ROMFS_MAXFN]; /* XXX dynamic? */
- struct romfs_inode ri;
- const char *name; /* got from dentry */
- int len;
-
- res = -EACCES; /* placeholder for "no data here" */
- offset = dir->i_ino & ROMFH_MASK;
- lock_kernel();
- if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)
- goto error;
-
- maxoff = romfs_maxsize(dir->i_sb);
- offset = be32_to_cpu(ri.spec) & ROMFH_MASK;
-
- /* OK, now find the file whose name is in "dentry" in the
- * directory specified by "dir". */
-
- name = dentry->d_name.name;
- len = dentry->d_name.len;
-
- for(;;) {
- if (!offset || offset >= maxoff)
- goto success; /* negative success */
- if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)
- goto error;
-
- /* try to match the first 16 bytes of name */
- fslen = romfs_strnlen(dir, offset+ROMFH_SIZE, ROMFH_SIZE);
- if (len < ROMFH_SIZE) {
- if (len == fslen) {
- /* both are shorter, and same size */
- romfs_copyfrom(dir, fsname, offset+ROMFH_SIZE, len+1);
- if (strncmp (name, fsname, len) == 0)
- break;
- }
- } else if (fslen >= ROMFH_SIZE) {
- /* both are longer; XXX optimize max size */
- fslen = romfs_strnlen(dir, offset+ROMFH_SIZE, sizeof(fsname)-1);
- if (len == fslen) {
- romfs_copyfrom(dir, fsname, offset+ROMFH_SIZE, len+1);
- if (strncmp(name, fsname, len) == 0)
- break;
- }
- }
- /* next entry */
- offset = be32_to_cpu(ri.next) & ROMFH_MASK;
- }
-
- /* Hard link handling */
- if ((be32_to_cpu(ri.next) & ROMFH_TYPE) == ROMFH_HRD)
- offset = be32_to_cpu(ri.spec) & ROMFH_MASK;
-
- inode = romfs_iget(dir->i_sb, offset);
- if (IS_ERR(inode)) {
- res = PTR_ERR(inode);
- goto error;
- }
-
-success:
- d_add(dentry, inode);
- res = 0;
-error:
- unlock_kernel();
- return ERR_PTR(res);
-}
-
-/*
- * Ok, we do readpage, to be able to execute programs. Unfortunately,
- * we can't use bmap, since we may have looser alignments.
- */
-
-static int
-romfs_readpage(struct file *file, struct page * page)
-{
- struct inode *inode = page->mapping->host;
- loff_t offset, size;
- unsigned long filled;
- void *buf;
- int result = -EIO;
-
- page_cache_get(page);
- lock_kernel();
- buf = kmap(page);
- if (!buf)
- goto err_out;
-
- /* 32 bit warning -- but not for us :) */
- offset = page_offset(page);
- size = i_size_read(inode);
- filled = 0;
- result = 0;
- if (offset < size) {
- unsigned long readlen;
-
- size -= offset;
- readlen = size > PAGE_SIZE ? PAGE_SIZE : size;
-
- filled = romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen);
-
- if (filled != readlen) {
- SetPageError(page);
- filled = 0;
- result = -EIO;
- }
- }
-
- if (filled < PAGE_SIZE)
- memset(buf + filled, 0, PAGE_SIZE-filled);
-
- if (!result)
- SetPageUptodate(page);
- flush_dcache_page(page);
-
- unlock_page(page);
-
- kunmap(page);
-err_out:
- page_cache_release(page);
- unlock_kernel();
-
- return result;
-}
-
-/* Mapping from our types to the kernel */
-
-static const struct address_space_operations romfs_aops = {
- .readpage = romfs_readpage
-};
-
-static const struct file_operations romfs_dir_operations = {
- .read = generic_read_dir,
- .readdir = romfs_readdir,
-};
-
-static const struct inode_operations romfs_dir_inode_operations = {
- .lookup = romfs_lookup,
-};
-
-static mode_t romfs_modemap[] =
-{
- 0, S_IFDIR+0644, S_IFREG+0644, S_IFLNK+0777,
- S_IFBLK+0600, S_IFCHR+0600, S_IFSOCK+0644, S_IFIFO+0644
-};
-
-static struct inode *
-romfs_iget(struct super_block *sb, unsigned long ino)
-{
- int nextfh, ret;
- struct romfs_inode ri;
- struct inode *i;
-
- ino &= ROMFH_MASK;
- i = iget_locked(sb, ino);
- if (!i)
- return ERR_PTR(-ENOMEM);
- if (!(i->i_state & I_NEW))
- return i;
-
- i->i_mode = 0;
-
- /* Loop for finding the real hard link */
- for(;;) {
- if (romfs_copyfrom(i, &ri, ino, ROMFH_SIZE) <= 0) {
- printk(KERN_ERR "romfs: read error for inode 0x%lx\n",
- ino);
- iget_failed(i);
- return ERR_PTR(-EIO);
- }
- /* XXX: do romfs_checksum here too (with name) */
-
- nextfh = be32_to_cpu(ri.next);
- if ((nextfh & ROMFH_TYPE) != ROMFH_HRD)
- break;
-
- ino = be32_to_cpu(ri.spec) & ROMFH_MASK;
- }
-
- i->i_nlink = 1; /* Hard to decide.. */
- i->i_size = be32_to_cpu(ri.size);
- i->i_mtime.tv_sec = i->i_atime.tv_sec = i->i_ctime.tv_sec = 0;
- i->i_mtime.tv_nsec = i->i_atime.tv_nsec = i->i_ctime.tv_nsec = 0;
-
- /* Precalculate the data offset */
- ret = romfs_strnlen(i, ino + ROMFH_SIZE, ROMFS_MAXFN);
- if (ret >= 0)
- ino = (ROMFH_SIZE + ret + 1 + ROMFH_PAD) & ROMFH_MASK;
- else
- ino = 0;
-
- ROMFS_I(i)->i_metasize = ino;
- ROMFS_I(i)->i_dataoffset = ino+(i->i_ino&ROMFH_MASK);
-
- /* Compute permissions */
- ino = romfs_modemap[nextfh & ROMFH_TYPE];
- /* only "normal" files have ops */
- switch (nextfh & ROMFH_TYPE) {
- case 1:
- i->i_size = ROMFS_I(i)->i_metasize;
- i->i_op = &romfs_dir_inode_operations;
- i->i_fop = &romfs_dir_operations;
- if (nextfh & ROMFH_EXEC)
- ino |= S_IXUGO;
- i->i_mode = ino;
- break;
- case 2:
- i->i_fop = &generic_ro_fops;
- i->i_data.a_ops = &romfs_aops;
- if (nextfh & ROMFH_EXEC)
- ino |= S_IXUGO;
- i->i_mode = ino;
- break;
- case 3:
- i->i_op = &page_symlink_inode_operations;
- i->i_data.a_ops = &romfs_aops;
- i->i_mode = ino | S_IRWXUGO;
- break;
- default:
- /* depending on MBZ for sock/fifos */
- nextfh = be32_to_cpu(ri.spec);
- init_special_inode(i, ino,
- MKDEV(nextfh>>16,nextfh&0xffff));
- }
- unlock_new_inode(i);
- return i;
-}
-
-static struct kmem_cache * romfs_inode_cachep;
-
-static struct inode *romfs_alloc_inode(struct super_block *sb)
-{
- struct romfs_inode_info *ei;
- ei = kmem_cache_alloc(romfs_inode_cachep, GFP_KERNEL);
- if (!ei)
- return NULL;
- return &ei->vfs_inode;
-}
-
-static void romfs_destroy_inode(struct inode *inode)
-{
- kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode));
-}
-
-static void init_once(void *foo)
-{
- struct romfs_inode_info *ei = foo;
-
- inode_init_once(&ei->vfs_inode);
-}
-
-static int init_inodecache(void)
-{
- romfs_inode_cachep = kmem_cache_create("romfs_inode_cache",
- sizeof(struct romfs_inode_info),
- 0, (SLAB_RECLAIM_ACCOUNT|
- SLAB_MEM_SPREAD),
- init_once);
- if (romfs_inode_cachep == NULL)
- return -ENOMEM;
- return 0;
-}
-
-static void destroy_inodecache(void)
-{
- kmem_cache_destroy(romfs_inode_cachep);
-}
-
-static int romfs_remount(struct super_block *sb, int *flags, char *data)
-{
- *flags |= MS_RDONLY;
- return 0;
-}
-
-static const struct super_operations romfs_ops = {
- .alloc_inode = romfs_alloc_inode,
- .destroy_inode = romfs_destroy_inode,
- .statfs = romfs_statfs,
- .remount_fs = romfs_remount,
-};
-
-static int romfs_get_sb(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data, struct vfsmount *mnt)
-{
- return get_sb_bdev(fs_type, flags, dev_name, data, romfs_fill_super,
- mnt);
-}
-
-static struct file_system_type romfs_fs_type = {
- .owner = THIS_MODULE,
- .name = "romfs",
- .get_sb = romfs_get_sb,
- .kill_sb = kill_block_super,
- .fs_flags = FS_REQUIRES_DEV,
-};
-
-static int __init init_romfs_fs(void)
-{
- int err = init_inodecache();
- if (err)
- goto out1;
- err = register_filesystem(&romfs_fs_type);
- if (err)
- goto out;
- return 0;
-out:
- destroy_inodecache();
-out1:
- return err;
-}
-
-static void __exit exit_romfs_fs(void)
-{
- unregister_filesystem(&romfs_fs_type);
- destroy_inodecache();
-}
-
-/* Yes, works even as a module... :) */
-
-module_init(init_romfs_fs)
-module_exit(exit_romfs_fs)
-MODULE_LICENSE("GPL");
diff --git a/fs/romfs/internal.h b/fs/romfs/internal.h
new file mode 100644
index 00000000000..06044a9dc62
--- /dev/null
+++ b/fs/romfs/internal.h
@@ -0,0 +1,47 @@
+/* RomFS internal definitions
+ *
+ * Copyright © 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/romfs_fs.h>
+
+struct romfs_inode_info {
+ struct inode vfs_inode;
+ unsigned long i_metasize; /* size of non-data area */
+ unsigned long i_dataoffset; /* from the start of fs */
+};
+
+static inline size_t romfs_maxsize(struct super_block *sb)
+{
+ return (size_t) (unsigned long) sb->s_fs_info;
+}
+
+static inline struct romfs_inode_info *ROMFS_I(struct inode *inode)
+{
+ return container_of(inode, struct romfs_inode_info, vfs_inode);
+}
+
+/*
+ * mmap-nommu.c
+ */
+#if !defined(CONFIG_MMU) && defined(CONFIG_ROMFS_ON_MTD)
+extern const struct file_operations romfs_ro_fops;
+#else
+#define romfs_ro_fops generic_ro_fops
+#endif
+
+/*
+ * storage.c
+ */
+extern int romfs_dev_read(struct super_block *sb, unsigned long pos,
+ void *buf, size_t buflen);
+extern ssize_t romfs_dev_strnlen(struct super_block *sb,
+ unsigned long pos, size_t maxlen);
+extern int romfs_dev_strncmp(struct super_block *sb, unsigned long pos,
+ const char *str, size_t size);
diff --git a/fs/romfs/mmap-nommu.c b/fs/romfs/mmap-nommu.c
new file mode 100644
index 00000000000..f0511e81696
--- /dev/null
+++ b/fs/romfs/mmap-nommu.c
@@ -0,0 +1,75 @@
+/* NOMMU mmap support for RomFS on MTD devices
+ *
+ * Copyright © 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/mm.h>
+#include <linux/mtd/super.h>
+#include "internal.h"
+
+/*
+ * try to determine where a shared mapping can be made
+ * - only supported for NOMMU at the moment (MMU can't doesn't copy private
+ * mappings)
+ * - attempts to map through to the underlying MTD device
+ */
+static unsigned long romfs_get_unmapped_area(struct file *file,
+ unsigned long addr,
+ unsigned long len,
+ unsigned long pgoff,
+ unsigned long flags)
+{
+ struct inode *inode = file->f_mapping->host;
+ struct mtd_info *mtd = inode->i_sb->s_mtd;
+ unsigned long isize, offset;
+
+ if (!mtd)
+ goto cant_map_directly;
+
+ isize = i_size_read(inode);
+ offset = pgoff << PAGE_SHIFT;
+ if (offset > isize || len > isize || offset > isize - len)
+ return (unsigned long) -EINVAL;
+
+ /* we need to call down to the MTD layer to do the actual mapping */
+ if (mtd->get_unmapped_area) {
+ if (addr != 0)
+ return (unsigned long) -EINVAL;
+
+ if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT))
+ return (unsigned long) -EINVAL;
+
+ offset += ROMFS_I(inode)->i_dataoffset;
+ if (offset > mtd->size - len)
+ return (unsigned long) -EINVAL;
+
+ return mtd->get_unmapped_area(mtd, len, offset, flags);
+ }
+
+cant_map_directly:
+ return (unsigned long) -ENOSYS;
+}
+
+/*
+ * permit a R/O mapping to be made directly through onto an MTD device if
+ * possible
+ */
+static int romfs_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ return vma->vm_flags & (VM_SHARED | VM_MAYSHARE) ? 0 : -ENOSYS;
+}
+
+const struct file_operations romfs_ro_fops = {
+ .llseek = generic_file_llseek,
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .splice_read = generic_file_splice_read,
+ .mmap = romfs_mmap,
+ .get_unmapped_area = romfs_get_unmapped_area,
+};
diff --git a/fs/romfs/storage.c b/fs/romfs/storage.c
new file mode 100644
index 00000000000..7e3e1e12a08
--- /dev/null
+++ b/fs/romfs/storage.c
@@ -0,0 +1,261 @@
+/* RomFS storage access routines
+ *
+ * Copyright © 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/fs.h>
+#include <linux/mtd/super.h>
+#include <linux/buffer_head.h>
+#include "internal.h"
+
+#if !defined(CONFIG_ROMFS_ON_MTD) && !defined(CONFIG_ROMFS_ON_BLOCK)
+#error no ROMFS backing store interface configured
+#endif
+
+#ifdef CONFIG_ROMFS_ON_MTD
+#define ROMFS_MTD_READ(sb, ...) ((sb)->s_mtd->read((sb)->s_mtd, ##__VA_ARGS__))
+
+/*
+ * read data from an romfs image on an MTD device
+ */
+static int romfs_mtd_read(struct super_block *sb, unsigned long pos,
+ void *buf, size_t buflen)
+{
+ size_t rlen;
+ int ret;
+
+ ret = ROMFS_MTD_READ(sb, pos, buflen, &rlen, buf);
+ return (ret < 0 || rlen != buflen) ? -EIO : 0;
+}
+
+/*
+ * determine the length of a string in a romfs image on an MTD device
+ */
+static ssize_t romfs_mtd_strnlen(struct super_block *sb,
+ unsigned long pos, size_t maxlen)
+{
+ ssize_t n = 0;
+ size_t segment;
+ u_char buf[16], *p;
+ size_t len;
+ int ret;
+
+ /* scan the string up to 16 bytes at a time */
+ while (maxlen > 0) {
+ segment = min_t(size_t, maxlen, 16);
+ ret = ROMFS_MTD_READ(sb, pos, segment, &len, buf);
+ if (ret < 0)
+ return ret;
+ p = memchr(buf, 0, len);
+ if (p)
+ return n + (p - buf);
+ maxlen -= len;
+ pos += len;
+ n += len;
+ }
+
+ return n;
+}
+
+/*
+ * compare a string to one in a romfs image on MTD
+ * - return 1 if matched, 0 if differ, -ve if error
+ */
+static int romfs_mtd_strncmp(struct super_block *sb, unsigned long pos,
+ const char *str, size_t size)
+{
+ u_char buf[16];
+ size_t len, segment;
+ int ret;
+
+ /* scan the string up to 16 bytes at a time */
+ while (size > 0) {
+ segment = min_t(size_t, size, 16);
+ ret = ROMFS_MTD_READ(sb, pos, segment, &len, buf);
+ if (ret < 0)
+ return ret;
+ if (memcmp(buf, str, len) != 0)
+ return 0;
+ size -= len;
+ pos += len;
+ str += len;
+ }
+
+ return 1;
+}
+#endif /* CONFIG_ROMFS_ON_MTD */
+
+#ifdef CONFIG_ROMFS_ON_BLOCK
+/*
+ * read data from an romfs image on a block device
+ */
+static int romfs_blk_read(struct super_block *sb, unsigned long pos,
+ void *buf, size_t buflen)
+{
+ struct buffer_head *bh;
+ unsigned long offset;
+ size_t segment;
+
+ /* copy the string up to blocksize bytes at a time */
+ while (buflen > 0) {
+ offset = pos & (ROMBSIZE - 1);
+ segment = min_t(size_t, buflen, ROMBSIZE - offset);
+ bh = sb_bread(sb, pos >> ROMBSBITS);
+ if (!bh)
+ return -EIO;
+ memcpy(buf, bh->b_data + offset, segment);
+ brelse(bh);
+ buflen -= segment;
+ pos += segment;
+ }
+
+ return 0;
+}
+
+/*
+ * determine the length of a string in romfs on a block device
+ */
+static ssize_t romfs_blk_strnlen(struct super_block *sb,
+ unsigned long pos, size_t limit)
+{
+ struct buffer_head *bh;
+ unsigned long offset;
+ ssize_t n = 0;
+ size_t segment;
+ u_char *buf, *p;
+
+ /* scan the string up to blocksize bytes at a time */
+ while (limit > 0) {
+ offset = pos & (ROMBSIZE - 1);
+ segment = min_t(size_t, limit, ROMBSIZE - offset);
+ bh = sb_bread(sb, pos >> ROMBSBITS);
+ if (!bh)
+ return -EIO;
+ buf = bh->b_data + offset;
+ p = memchr(buf, 0, segment);
+ brelse(bh);
+ if (p)
+ return n + (p - buf);
+ limit -= segment;
+ pos += segment;
+ n += segment;
+ }
+
+ return n;
+}
+
+/*
+ * compare a string to one in a romfs image on a block device
+ * - return 1 if matched, 0 if differ, -ve if error
+ */
+static int romfs_blk_strncmp(struct super_block *sb, unsigned long pos,
+ const char *str, size_t size)
+{
+ struct buffer_head *bh;
+ unsigned long offset;
+ size_t segment;
+ bool x;
+
+ /* scan the string up to 16 bytes at a time */
+ while (size > 0) {
+ offset = pos & (ROMBSIZE - 1);
+ segment = min_t(size_t, size, ROMBSIZE - offset);
+ bh = sb_bread(sb, pos >> ROMBSBITS);
+ if (!bh)
+ return -EIO;
+ x = (memcmp(bh->b_data + offset, str, segment) != 0);
+ brelse(bh);
+ if (x)
+ return 0;
+ size -= segment;
+ pos += segment;
+ str += segment;
+ }
+
+ return 1;
+}
+#endif /* CONFIG_ROMFS_ON_BLOCK */
+
+/*
+ * read data from the romfs image
+ */
+int romfs_dev_read(struct super_block *sb, unsigned long pos,
+ void *buf, size_t buflen)
+{
+ size_t limit;
+
+ limit = romfs_maxsize(sb);
+ if (pos >= limit)
+ return -EIO;
+ if (buflen > limit - pos)
+ buflen = limit - pos;
+
+#ifdef CONFIG_ROMFS_ON_MTD
+ if (sb->s_mtd)
+ return romfs_mtd_read(sb, pos, buf, buflen);
+#endif
+#ifdef CONFIG_ROMFS_ON_BLOCK
+ if (sb->s_bdev)
+ return romfs_blk_read(sb, pos, buf, buflen);
+#endif
+ return -EIO;
+}
+
+/*
+ * determine the length of a string in romfs
+ */
+ssize_t romfs_dev_strnlen(struct super_block *sb,
+ unsigned long pos, size_t maxlen)
+{
+ size_t limit;
+
+ limit = romfs_maxsize(sb);
+ if (pos >= limit)
+ return -EIO;
+ if (maxlen > limit - pos)
+ maxlen = limit - pos;
+
+#ifdef CONFIG_ROMFS_ON_MTD
+ if (sb->s_mtd)
+ return romfs_mtd_strnlen(sb, pos, limit);
+#endif
+#ifdef CONFIG_ROMFS_ON_BLOCK
+ if (sb->s_bdev)
+ return romfs_blk_strnlen(sb, pos, limit);
+#endif
+ return -EIO;
+}
+
+/*
+ * compare a string to one in romfs
+ * - return 1 if matched, 0 if differ, -ve if error
+ */
+int romfs_dev_strncmp(struct super_block *sb, unsigned long pos,
+ const char *str, size_t size)
+{
+ size_t limit;
+
+ limit = romfs_maxsize(sb);
+ if (pos >= limit)
+ return -EIO;
+ if (size > ROMFS_MAXFN)
+ return -ENAMETOOLONG;
+ if (size > limit - pos)
+ return -EIO;
+
+#ifdef CONFIG_ROMFS_ON_MTD
+ if (sb->s_mtd)
+ return romfs_mtd_strncmp(sb, pos, str, size);
+#endif
+#ifdef CONFIG_ROMFS_ON_BLOCK
+ if (sb->s_bdev)
+ return romfs_blk_strncmp(sb, pos, str, size);
+#endif
+ return -EIO;
+}
diff --git a/fs/romfs/super.c b/fs/romfs/super.c
new file mode 100644
index 00000000000..10ca7d984a8
--- /dev/null
+++ b/fs/romfs/super.c
@@ -0,0 +1,653 @@
+/* Block- or MTD-based romfs
+ *
+ * Copyright © 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * Derived from: ROMFS file system, Linux implementation
+ *
+ * Copyright © 1997-1999 Janos Farkas <chexum@shadow.banki.hu>
+ *
+ * Using parts of the minix filesystem
+ * Copyright © 1991, 1992 Linus Torvalds
+ *
+ * and parts of the affs filesystem additionally
+ * Copyright © 1993 Ray Burr
+ * Copyright © 1996 Hans-Joachim Widmaier
+ *
+ * Changes
+ * Changed for 2.1.19 modules
+ * Jan 1997 Initial release
+ * Jun 1997 2.1.43+ changes
+ * Proper page locking in readpage
+ * Changed to work with 2.1.45+ fs
+ * Jul 1997 Fixed follow_link
+ * 2.1.47
+ * lookup shouldn't return -ENOENT
+ * from Horst von Brand:
+ * fail on wrong checksum
+ * double unlock_super was possible
+ * correct namelen for statfs
+ * spotted by Bill Hawes:
+ * readlink shouldn't iput()
+ * Jun 1998 2.1.106 from Avery Pennarun: glibc scandir()
+ * exposed a problem in readdir
+ * 2.1.107 code-freeze spellchecker run
+ * Aug 1998 2.1.118+ VFS changes
+ * Sep 1998 2.1.122 another VFS change (follow_link)
+ * Apr 1999 2.2.7 no more EBADF checking in
+ * lookup/readdir, use ERR_PTR
+ * Jun 1999 2.3.6 d_alloc_root use changed
+ * 2.3.9 clean up usage of ENOENT/negative
+ * dentries in lookup
+ * clean up page flags setting
+ * (error, uptodate, locking) in
+ * in readpage
+ * use init_special_inode for
+ * fifos/sockets (and streamline) in
+ * read_inode, fix _ops table order
+ * Aug 1999 2.3.16 __initfunc() => __init change
+ * Oct 1999 2.3.24 page->owner hack obsoleted
+ * Nov 1999 2.3.27 2.3.25+ page->offset => index change
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/time.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/parser.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/statfs.h>
+#include <linux/mtd/super.h>
+#include <linux/ctype.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/uaccess.h>
+#include "internal.h"
+
+static struct kmem_cache *romfs_inode_cachep;
+
+static const umode_t romfs_modemap[8] = {
+ 0, /* hard link */
+ S_IFDIR | 0644, /* directory */
+ S_IFREG | 0644, /* regular file */
+ S_IFLNK | 0777, /* symlink */
+ S_IFBLK | 0600, /* blockdev */
+ S_IFCHR | 0600, /* chardev */
+ S_IFSOCK | 0644, /* socket */
+ S_IFIFO | 0644 /* FIFO */
+};
+
+static const unsigned char romfs_dtype_table[] = {
+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_SOCK, DT_FIFO
+};
+
+static struct inode *romfs_iget(struct super_block *sb, unsigned long pos);
+
+/*
+ * read a page worth of data from the image
+ */
+static int romfs_readpage(struct file *file, struct page *page)
+{
+ struct inode *inode = page->mapping->host;
+ loff_t offset, size;
+ unsigned long fillsize, pos;
+ void *buf;
+ int ret;
+
+ buf = kmap(page);
+ if (!buf)
+ return -ENOMEM;
+
+ /* 32 bit warning -- but not for us :) */
+ offset = page_offset(page);
+ size = i_size_read(inode);
+ fillsize = 0;
+ ret = 0;
+ if (offset < size) {
+ size -= offset;
+ fillsize = size > PAGE_SIZE ? PAGE_SIZE : size;
+
+ pos = ROMFS_I(inode)->i_dataoffset + offset;
+
+ ret = romfs_dev_read(inode->i_sb, pos, buf, fillsize);
+ if (ret < 0) {
+ SetPageError(page);
+ fillsize = 0;
+ ret = -EIO;
+ }
+ }
+
+ if (fillsize < PAGE_SIZE)
+ memset(buf + fillsize, 0, PAGE_SIZE - fillsize);
+ if (ret == 0)
+ SetPageUptodate(page);
+
+ flush_dcache_page(page);
+ kunmap(page);
+ unlock_page(page);
+ return ret;
+}
+
+static const struct address_space_operations romfs_aops = {
+ .readpage = romfs_readpage
+};
+
+/*
+ * read the entries from a directory
+ */
+static int romfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+ struct inode *i = filp->f_dentry->d_inode;
+ struct romfs_inode ri;
+ unsigned long offset, maxoff;
+ int j, ino, nextfh;
+ int stored = 0;
+ char fsname[ROMFS_MAXFN]; /* XXX dynamic? */
+ int ret;
+
+ maxoff = romfs_maxsize(i->i_sb);
+
+ offset = filp->f_pos;
+ if (!offset) {
+ offset = i->i_ino & ROMFH_MASK;
+ ret = romfs_dev_read(i->i_sb, offset, &ri, ROMFH_SIZE);
+ if (ret < 0)
+ goto out;
+ offset = be32_to_cpu(ri.spec) & ROMFH_MASK;
+ }
+
+ /* Not really failsafe, but we are read-only... */
+ for (;;) {
+ if (!offset || offset >= maxoff) {
+ offset = maxoff;
+ filp->f_pos = offset;
+ goto out;
+ }
+ filp->f_pos = offset;
+
+ /* Fetch inode info */
+ ret = romfs_dev_read(i->i_sb, offset, &ri, ROMFH_SIZE);
+ if (ret < 0)
+ goto out;
+
+ j = romfs_dev_strnlen(i->i_sb, offset + ROMFH_SIZE,
+ sizeof(fsname) - 1);
+ if (j < 0)
+ goto out;
+
+ ret = romfs_dev_read(i->i_sb, offset + ROMFH_SIZE, fsname, j);
+ if (ret < 0)
+ goto out;
+ fsname[j] = '\0';
+
+ ino = offset;
+ nextfh = be32_to_cpu(ri.next);
+ if ((nextfh & ROMFH_TYPE) == ROMFH_HRD)
+ ino = be32_to_cpu(ri.spec);
+ if (filldir(dirent, fsname, j, offset, ino,
+ romfs_dtype_table[nextfh & ROMFH_TYPE]) < 0)
+ goto out;
+
+ stored++;
+ offset = nextfh & ROMFH_MASK;
+ }
+
+out:
+ return stored;
+}
+
+/*
+ * look up an entry in a directory
+ */
+static struct dentry *romfs_lookup(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nd)
+{
+ unsigned long offset, maxoff;
+ struct inode *inode;
+ struct romfs_inode ri;
+ const char *name; /* got from dentry */
+ int len, ret;
+
+ offset = dir->i_ino & ROMFH_MASK;
+ ret = romfs_dev_read(dir->i_sb, offset, &ri, ROMFH_SIZE);
+ if (ret < 0)
+ goto error;
+
+ /* search all the file entries in the list starting from the one
+ * pointed to by the directory's special data */
+ maxoff = romfs_maxsize(dir->i_sb);
+ offset = be32_to_cpu(ri.spec) & ROMFH_MASK;
+
+ name = dentry->d_name.name;
+ len = dentry->d_name.len;
+
+ for (;;) {
+ if (!offset || offset >= maxoff)
+ goto out0;
+
+ ret = romfs_dev_read(dir->i_sb, offset, &ri, sizeof(ri));
+ if (ret < 0)
+ goto error;
+
+ /* try to match the first 16 bytes of name */
+ ret = romfs_dev_strncmp(dir->i_sb, offset + ROMFH_SIZE, name,
+ len);
+ if (ret < 0)
+ goto error;
+ if (ret == 1)
+ break;
+
+ /* next entry */
+ offset = be32_to_cpu(ri.next) & ROMFH_MASK;
+ }
+
+ /* Hard link handling */
+ if ((be32_to_cpu(ri.next) & ROMFH_TYPE) == ROMFH_HRD)
+ offset = be32_to_cpu(ri.spec) & ROMFH_MASK;
+
+ inode = romfs_iget(dir->i_sb, offset);
+ if (IS_ERR(inode)) {
+ ret = PTR_ERR(inode);
+ goto error;
+ }
+ goto outi;
+
+ /*
+ * it's a bit funky, _lookup needs to return an error code
+ * (negative) or a NULL, both as a dentry. ENOENT should not
+ * be returned, instead we need to create a negative dentry by
+ * d_add(dentry, NULL); and return 0 as no error.
+ * (Although as I see, it only matters on writable file
+ * systems).
+ */
+out0:
+ inode = NULL;
+outi:
+ d_add(dentry, inode);
+ ret = 0;
+error:
+ return ERR_PTR(ret);
+}
+
+static const struct file_operations romfs_dir_operations = {
+ .read = generic_read_dir,
+ .readdir = romfs_readdir,
+};
+
+static struct inode_operations romfs_dir_inode_operations = {
+ .lookup = romfs_lookup,
+};
+
+/*
+ * get a romfs inode based on its position in the image (which doubles as the
+ * inode number)
+ */
+static struct inode *romfs_iget(struct super_block *sb, unsigned long pos)
+{
+ struct romfs_inode_info *inode;
+ struct romfs_inode ri;
+ struct inode *i;
+ unsigned long nlen;
+ unsigned nextfh, ret;
+ umode_t mode;
+
+ /* we might have to traverse a chain of "hard link" file entries to get
+ * to the actual file */
+ for (;;) {
+ ret = romfs_dev_read(sb, pos, &ri, sizeof(ri));
+ if (ret < 0)
+ goto error;
+
+ /* XXX: do romfs_checksum here too (with name) */
+
+ nextfh = be32_to_cpu(ri.next);
+ if ((nextfh & ROMFH_TYPE) != ROMFH_HRD)
+ break;
+
+ pos = be32_to_cpu(ri.spec) & ROMFH_MASK;
+ }
+
+ /* determine the length of the filename */
+ nlen = romfs_dev_strnlen(sb, pos + ROMFH_SIZE, ROMFS_MAXFN);
+ if (IS_ERR_VALUE(nlen))
+ goto eio;
+
+ /* get an inode for this image position */
+ i = iget_locked(sb, pos);
+ if (!i)
+ return ERR_PTR(-ENOMEM);
+
+ if (!(i->i_state & I_NEW))
+ return i;
+
+ /* precalculate the data offset */
+ inode = ROMFS_I(i);
+ inode->i_metasize = (ROMFH_SIZE + nlen + 1 + ROMFH_PAD) & ROMFH_MASK;
+ inode->i_dataoffset = pos + inode->i_metasize;
+
+ i->i_nlink = 1; /* Hard to decide.. */
+ i->i_size = be32_to_cpu(ri.size);
+ i->i_mtime.tv_sec = i->i_atime.tv_sec = i->i_ctime.tv_sec = 0;
+ i->i_mtime.tv_nsec = i->i_atime.tv_nsec = i->i_ctime.tv_nsec = 0;
+
+ /* set up mode and ops */
+ mode = romfs_modemap[nextfh & ROMFH_TYPE];
+
+ switch (nextfh & ROMFH_TYPE) {
+ case ROMFH_DIR:
+ i->i_size = ROMFS_I(i)->i_metasize;
+ i->i_op = &romfs_dir_inode_operations;
+ i->i_fop = &romfs_dir_operations;
+ if (nextfh & ROMFH_EXEC)
+ mode |= S_IXUGO;
+ break;
+ case ROMFH_REG:
+ i->i_fop = &romfs_ro_fops;
+ i->i_data.a_ops = &romfs_aops;
+ if (i->i_sb->s_mtd)
+ i->i_data.backing_dev_info =
+ i->i_sb->s_mtd->backing_dev_info;
+ if (nextfh & ROMFH_EXEC)
+ mode |= S_IXUGO;
+ break;
+ case ROMFH_SYM:
+ i->i_op = &page_symlink_inode_operations;
+ i->i_data.a_ops = &romfs_aops;
+ mode |= S_IRWXUGO;
+ break;
+ default:
+ /* depending on MBZ for sock/fifos */
+ nextfh = be32_to_cpu(ri.spec);
+ init_special_inode(i, mode, MKDEV(nextfh >> 16,
+ nextfh & 0xffff));
+ break;
+ }
+
+ i->i_mode = mode;
+
+ unlock_new_inode(i);
+ return i;
+
+eio:
+ ret = -EIO;
+error:
+ printk(KERN_ERR "ROMFS: read error for inode 0x%lx\n", pos);
+ return ERR_PTR(ret);
+}
+
+/*
+ * allocate a new inode
+ */
+static struct inode *romfs_alloc_inode(struct super_block *sb)
+{
+ struct romfs_inode_info *inode;
+ inode = kmem_cache_alloc(romfs_inode_cachep, GFP_KERNEL);
+ return inode ? &inode->vfs_inode : NULL;
+}
+
+/*
+ * return a spent inode to the slab cache
+ */
+static void romfs_destroy_inode(struct inode *inode)
+{
+ kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode));
+}
+
+/*
+ * get filesystem statistics
+ */
+static int romfs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+ struct super_block *sb = dentry->d_sb;
+ u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
+
+ buf->f_type = ROMFS_MAGIC;
+ buf->f_namelen = ROMFS_MAXFN;
+ buf->f_bsize = ROMBSIZE;
+ buf->f_bfree = buf->f_bavail = buf->f_ffree;
+ buf->f_blocks =
+ (romfs_maxsize(dentry->d_sb) + ROMBSIZE - 1) >> ROMBSBITS;
+ buf->f_fsid.val[0] = (u32)id;
+ buf->f_fsid.val[1] = (u32)(id >> 32);
+ return 0;
+}
+
+/*
+ * remounting must involve read-only
+ */
+static int romfs_remount(struct super_block *sb, int *flags, char *data)
+{
+ *flags |= MS_RDONLY;
+ return 0;
+}
+
+static const struct super_operations romfs_super_ops = {
+ .alloc_inode = romfs_alloc_inode,
+ .destroy_inode = romfs_destroy_inode,
+ .statfs = romfs_statfs,
+ .remount_fs = romfs_remount,
+};
+
+/*
+ * checksum check on part of a romfs filesystem
+ */
+static __u32 romfs_checksum(const void *data, int size)
+{
+ const __be32 *ptr = data;
+ __u32 sum;
+
+ sum = 0;
+ size >>= 2;
+ while (size > 0) {
+ sum += be32_to_cpu(*ptr++);
+ size--;
+ }
+ return sum;
+}
+
+/*
+ * fill in the superblock
+ */
+static int romfs_fill_super(struct super_block *sb, void *data, int silent)
+{
+ struct romfs_super_block *rsb;
+ struct inode *root;
+ unsigned long pos, img_size;
+ const char *storage;
+ size_t len;
+ int ret;
+
+#ifdef CONFIG_BLOCK
+ if (!sb->s_mtd) {
+ sb_set_blocksize(sb, ROMBSIZE);
+ } else {
+ sb->s_blocksize = ROMBSIZE;
+ sb->s_blocksize_bits = blksize_bits(ROMBSIZE);
+ }
+#endif
+
+ sb->s_maxbytes = 0xFFFFFFFF;
+ sb->s_magic = ROMFS_MAGIC;
+ sb->s_flags |= MS_RDONLY | MS_NOATIME;
+ sb->s_op = &romfs_super_ops;
+
+ /* read the image superblock and check it */
+ rsb = kmalloc(512, GFP_KERNEL);
+ if (!rsb)
+ return -ENOMEM;
+
+ sb->s_fs_info = (void *) 512;
+ ret = romfs_dev_read(sb, 0, rsb, 512);
+ if (ret < 0)
+ goto error_rsb;
+
+ img_size = be32_to_cpu(rsb->size);
+
+ if (sb->s_mtd && img_size > sb->s_mtd->size)
+ goto error_rsb_inval;
+
+ sb->s_fs_info = (void *) img_size;
+
+ if (rsb->word0 != ROMSB_WORD0 || rsb->word1 != ROMSB_WORD1 ||
+ img_size < ROMFH_SIZE) {
+ if (!silent)
+ printk(KERN_WARNING "VFS:"
+ " Can't find a romfs filesystem on dev %s.\n",
+ sb->s_id);
+ goto error_rsb_inval;
+ }
+
+ if (romfs_checksum(rsb, min_t(size_t, img_size, 512))) {
+ printk(KERN_ERR "ROMFS: bad initial checksum on dev %s.\n",
+ sb->s_id);
+ goto error_rsb_inval;
+ }
+
+ storage = sb->s_mtd ? "MTD" : "the block layer";
+
+ len = strnlen(rsb->name, ROMFS_MAXFN);
+ if (!silent)
+ printk(KERN_NOTICE "ROMFS: Mounting image '%*.*s' through %s\n",
+ (unsigned) len, (unsigned) len, rsb->name, storage);
+
+ kfree(rsb);
+ rsb = NULL;
+
+ /* find the root directory */
+ pos = (ROMFH_SIZE + len + 1 + ROMFH_PAD) & ROMFH_MASK;
+
+ root = romfs_iget(sb, pos);
+ if (!root)
+ goto error;
+
+ sb->s_root = d_alloc_root(root);
+ if (!sb->s_root)
+ goto error_i;
+
+ return 0;
+
+error_i:
+ iput(root);
+error:
+ return -EINVAL;
+error_rsb_inval:
+ ret = -EINVAL;
+error_rsb:
+ return ret;
+}
+
+/*
+ * get a superblock for mounting
+ */
+static int romfs_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name,
+ void *data, struct vfsmount *mnt)
+{
+ int ret = -EINVAL;
+
+#ifdef CONFIG_ROMFS_ON_MTD
+ ret = get_sb_mtd(fs_type, flags, dev_name, data, romfs_fill_super,
+ mnt);
+#endif
+#ifdef CONFIG_ROMFS_ON_BLOCK
+ if (ret == -EINVAL)
+ ret = get_sb_bdev(fs_type, flags, dev_name, data,
+ romfs_fill_super, mnt);
+#endif
+ return ret;
+}
+
+/*
+ * destroy a romfs superblock in the appropriate manner
+ */
+static void romfs_kill_sb(struct super_block *sb)
+{
+#ifdef CONFIG_ROMFS_ON_MTD
+ if (sb->s_mtd) {
+ kill_mtd_super(sb);
+ return;
+ }
+#endif
+#ifdef CONFIG_ROMFS_ON_BLOCK
+ if (sb->s_bdev) {
+ kill_block_super(sb);
+ return;
+ }
+#endif
+}
+
+static struct file_system_type romfs_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "romfs",
+ .get_sb = romfs_get_sb,
+ .kill_sb = romfs_kill_sb,
+ .fs_flags = FS_REQUIRES_DEV,
+};
+
+/*
+ * inode storage initialiser
+ */
+static void romfs_i_init_once(void *_inode)
+{
+ struct romfs_inode_info *inode = _inode;
+
+ inode_init_once(&inode->vfs_inode);
+}
+
+/*
+ * romfs module initialisation
+ */
+static int __init init_romfs_fs(void)
+{
+ int ret;
+
+ printk(KERN_INFO "ROMFS MTD (C) 2007 Red Hat, Inc.\n");
+
+ romfs_inode_cachep =
+ kmem_cache_create("romfs_i",
+ sizeof(struct romfs_inode_info), 0,
+ SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
+ romfs_i_init_once);
+
+ if (!romfs_inode_cachep) {
+ printk(KERN_ERR
+ "ROMFS error: Failed to initialise inode cache\n");
+ return -ENOMEM;
+ }
+ ret = register_filesystem(&romfs_fs_type);
+ if (ret) {
+ printk(KERN_ERR "ROMFS error: Failed to register filesystem\n");
+ goto error_register;
+ }
+ return 0;
+
+error_register:
+ kmem_cache_destroy(romfs_inode_cachep);
+ return ret;
+}
+
+/*
+ * romfs module removal
+ */
+static void __exit exit_romfs_fs(void)
+{
+ unregister_filesystem(&romfs_fs_type);
+ kmem_cache_destroy(romfs_inode_cachep);
+}
+
+module_init(init_romfs_fs);
+module_exit(exit_romfs_fs);
+
+MODULE_DESCRIPTION("Direct-MTD Capable RomFS");
+MODULE_AUTHOR("Red Hat, Inc.");
+MODULE_LICENSE("GPL"); /* Actually dual-licensed, but it doesn't matter for */
diff --git a/fs/splice.c b/fs/splice.c
index 4ed0ba44a96..c18aa7e03e2 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -59,7 +59,8 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe,
*/
wait_on_page_writeback(page);
- if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL))
+ if (page_has_private(page) &&
+ !try_to_release_page(page, GFP_KERNEL))
goto out_unlock;
/*
@@ -736,10 +737,19 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
* ->write_end. Most of the time, these expect i_mutex to
* be held. Since this may result in an ABBA deadlock with
* pipe->inode, we have to order lock acquiry here.
+ *
+ * Outer lock must be inode->i_mutex, as pipe_wait() will
+ * release and reacquire pipe->inode->i_mutex, AND inode must
+ * never be a pipe.
*/
- inode_double_lock(inode, pipe->inode);
+ WARN_ON(S_ISFIFO(inode->i_mode));
+ mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
+ if (pipe->inode)
+ mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD);
ret = __splice_from_pipe(pipe, &sd, actor);
- inode_double_unlock(inode, pipe->inode);
+ if (pipe->inode)
+ mutex_unlock(&pipe->inode->i_mutex);
+ mutex_unlock(&inode->i_mutex);
return ret;
}
@@ -830,11 +840,17 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
};
ssize_t ret;
- inode_double_lock(inode, pipe->inode);
+ WARN_ON(S_ISFIFO(inode->i_mode));
+ mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
ret = file_remove_suid(out);
- if (likely(!ret))
+ if (likely(!ret)) {
+ if (pipe->inode)
+ mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD);
ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
- inode_double_unlock(inode, pipe->inode);
+ if (pipe->inode)
+ mutex_unlock(&pipe->inode->i_mutex);
+ }
+ mutex_unlock(&inode->i_mutex);
if (ret > 0) {
unsigned long nr_pages;
diff --git a/fs/squashfs/export.c b/fs/squashfs/export.c
index 69e971d5ddc..2b1b8fe5e03 100644
--- a/fs/squashfs/export.c
+++ b/fs/squashfs/export.c
@@ -40,6 +40,7 @@
#include <linux/dcache.h>
#include <linux/exportfs.h>
#include <linux/zlib.h>
+#include <linux/slab.h>
#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
diff --git a/fs/super.c b/fs/super.c
index 2ba481518ba..786fe7d7279 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -287,6 +287,7 @@ int fsync_super(struct super_block *sb)
__fsync_super(sb);
return sync_blockdev(sb->s_bdev);
}
+EXPORT_SYMBOL_GPL(fsync_super);
/**
* generic_shutdown_super - common helper for ->kill_sb()
@@ -770,6 +771,46 @@ void kill_litter_super(struct super_block *sb)
EXPORT_SYMBOL(kill_litter_super);
+static int ns_test_super(struct super_block *sb, void *data)
+{
+ return sb->s_fs_info == data;
+}
+
+static int ns_set_super(struct super_block *sb, void *data)
+{
+ sb->s_fs_info = data;
+ return set_anon_super(sb, NULL);
+}
+
+int get_sb_ns(struct file_system_type *fs_type, int flags, void *data,
+ int (*fill_super)(struct super_block *, void *, int),
+ struct vfsmount *mnt)
+{
+ struct super_block *sb;
+
+ sb = sget(fs_type, ns_test_super, ns_set_super, data);
+ if (IS_ERR(sb))
+ return PTR_ERR(sb);
+
+ if (!sb->s_root) {
+ int err;
+ sb->s_flags = flags;
+ err = fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
+ if (err) {
+ up_write(&sb->s_umount);
+ deactivate_super(sb);
+ return err;
+ }
+
+ sb->s_flags |= MS_ACTIVE;
+ }
+
+ simple_set_mnt(mnt, sb);
+ return 0;
+}
+
+EXPORT_SYMBOL(get_sb_ns);
+
#ifdef CONFIG_BLOCK
static int set_bdev_super(struct super_block *s, void *data)
{
diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig
index e35b54d5059..830e3f76f44 100644
--- a/fs/ubifs/Kconfig
+++ b/fs/ubifs/Kconfig
@@ -22,7 +22,7 @@ config UBIFS_FS_ADVANCED_COMPR
depends on UBIFS_FS
help
This option allows to explicitly choose which compressions, if any,
- are enabled in UBIFS. Removing compressors means inbility to read
+ are enabled in UBIFS. Removing compressors means inability to read
existing file systems.
If unsure, say 'N'.
@@ -32,7 +32,7 @@ config UBIFS_FS_LZO
depends on UBIFS_FS
default y
help
- LZO compressor is generally faster then zlib but compresses worse.
+ LZO compressor is generally faster than zlib but compresses worse.
Say 'Y' if unsure.
config UBIFS_FS_ZLIB
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index f393620890e..af1914462f0 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -194,29 +194,26 @@ static int make_free_space(struct ubifs_info *c)
}
/**
- * ubifs_calc_min_idx_lebs - calculate amount of eraseblocks for the index.
+ * ubifs_calc_min_idx_lebs - calculate amount of LEBs for the index.
* @c: UBIFS file-system description object
*
- * This function calculates and returns the number of eraseblocks which should
- * be kept for index usage.
+ * This function calculates and returns the number of LEBs which should be kept
+ * for index usage.
*/
int ubifs_calc_min_idx_lebs(struct ubifs_info *c)
{
- int idx_lebs, eff_leb_size = c->leb_size - c->max_idx_node_sz;
+ int idx_lebs;
long long idx_size;
idx_size = c->old_idx_sz + c->budg_idx_growth + c->budg_uncommitted_idx;
-
/* And make sure we have thrice the index size of space reserved */
- idx_size = idx_size + (idx_size << 1);
-
+ idx_size += idx_size << 1;
/*
* We do not maintain 'old_idx_size' as 'old_idx_lebs'/'old_idx_bytes'
* pair, nor similarly the two variables for the new index size, so we
* have to do this costly 64-bit division on fast-path.
*/
- idx_size += eff_leb_size - 1;
- idx_lebs = div_u64(idx_size, eff_leb_size);
+ idx_lebs = div_u64(idx_size + c->idx_leb_size - 1, c->idx_leb_size);
/*
* The index head is not available for the in-the-gaps method, so add an
* extra LEB to compensate.
@@ -310,23 +307,23 @@ static int can_use_rp(struct ubifs_info *c)
* do_budget_space - reserve flash space for index and data growth.
* @c: UBIFS file-system description object
*
- * This function makes sure UBIFS has enough free eraseblocks for index growth
- * and data.
+ * This function makes sure UBIFS has enough free LEBs for index growth and
+ * data.
*
* When budgeting index space, UBIFS reserves thrice as many LEBs as the index
* would take if it was consolidated and written to the flash. This guarantees
* that the "in-the-gaps" commit method always succeeds and UBIFS will always
* be able to commit dirty index. So this function basically adds amount of
* budgeted index space to the size of the current index, multiplies this by 3,
- * and makes sure this does not exceed the amount of free eraseblocks.
+ * and makes sure this does not exceed the amount of free LEBs.
*
* Notes about @c->min_idx_lebs and @c->lst.idx_lebs variables:
* o @c->lst.idx_lebs is the number of LEBs the index currently uses. It might
* be large, because UBIFS does not do any index consolidation as long as
* there is free space. IOW, the index may take a lot of LEBs, but the LEBs
* will contain a lot of dirt.
- * o @c->min_idx_lebs is the the index presumably takes. IOW, the index may be
- * consolidated to take up to @c->min_idx_lebs LEBs.
+ * o @c->min_idx_lebs is the number of LEBS the index presumably takes. IOW,
+ * the index may be consolidated to take up to @c->min_idx_lebs LEBs.
*
* This function returns zero in case of success, and %-ENOSPC in case of
* failure.
@@ -695,12 +692,12 @@ long long ubifs_reported_space(const struct ubifs_info *c, long long free)
* This function calculates amount of free space to report to user-space.
*
* Because UBIFS may introduce substantial overhead (the index, node headers,
- * alignment, wastage at the end of eraseblocks, etc), it cannot report real
- * amount of free flash space it has (well, because not all dirty space is
- * reclaimable, UBIFS does not actually know the real amount). If UBIFS did so,
- * it would bread user expectations about what free space is. Users seem to
- * accustomed to assume that if the file-system reports N bytes of free space,
- * they would be able to fit a file of N bytes to the FS. This almost works for
+ * alignment, wastage at the end of LEBs, etc), it cannot report real amount of
+ * free flash space it has (well, because not all dirty space is reclaimable,
+ * UBIFS does not actually know the real amount). If UBIFS did so, it would
+ * bread user expectations about what free space is. Users seem to accustomed
+ * to assume that if the file-system reports N bytes of free space, they would
+ * be able to fit a file of N bytes to the FS. This almost works for
* traditional file-systems, because they have way less overhead than UBIFS.
* So, to keep users happy, UBIFS tries to take the overhead into account.
*/
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index e975bd82f38..ce2cd834361 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -479,9 +479,9 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
"bad or corrupted node)");
else {
for (i = 0; i < nlen && dent->name[i]; i++)
- printk("%c", dent->name[i]);
+ printk(KERN_CONT "%c", dent->name[i]);
}
- printk("\n");
+ printk(KERN_CONT "\n");
break;
}
@@ -1214,7 +1214,7 @@ static int dbg_check_znode(struct ubifs_info *c, struct ubifs_zbranch *zbr)
/*
* Make sure the last key in our znode is less or
- * equivalent than the the key in zbranch which goes
+ * equivalent than the key in the zbranch which goes
* after our pointing zbranch.
*/
cmp = keys_cmp(c, max,
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 0ff89fe71e5..6d34dc7e33e 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -430,6 +430,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
struct ubifs_inode *ui = ubifs_inode(inode);
pgoff_t index = pos >> PAGE_CACHE_SHIFT;
int uninitialized_var(err), appending = !!(pos + len > inode->i_size);
+ int skipped_read = 0;
struct page *page;
ubifs_assert(ubifs_inode(inode)->ui_size == inode->i_size);
@@ -444,7 +445,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
if (!PageUptodate(page)) {
/* The page is not loaded from the flash */
- if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE)
+ if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) {
/*
* We change whole page so no need to load it. But we
* have to set the @PG_checked flag to make the further
@@ -453,7 +454,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
* the media.
*/
SetPageChecked(page);
- else {
+ skipped_read = 1;
+ } else {
err = do_readpage(page);
if (err) {
unlock_page(page);
@@ -470,6 +472,14 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
if (unlikely(err)) {
ubifs_assert(err == -ENOSPC);
/*
+ * If we skipped reading the page because we were going to
+ * write all of it, then it is not up to date.
+ */
+ if (skipped_read) {
+ ClearPageChecked(page);
+ ClearPageUptodate(page);
+ }
+ /*
* Budgeting failed which means it would have to force
* write-back but didn't, because we set the @fast flag in the
* request. Write-back cannot be done now, while we have the
@@ -949,7 +959,7 @@ static int do_writepage(struct page *page, int len)
* whole index and correct all inode sizes, which is long an unacceptable.
*
* To prevent situations like this, UBIFS writes pages back only if they are
- * within last synchronized inode size, i.e. the the size which has been
+ * within the last synchronized inode size, i.e. the size which has been
* written to the flash media last time. Otherwise, UBIFS forces inode
* write-back, thus making sure the on-flash inode contains current inode size,
* and then keeps writing pages back.
diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c
index 717d79c97c5..1d54383d126 100644
--- a/fs/ubifs/find.c
+++ b/fs/ubifs/find.c
@@ -478,7 +478,7 @@ const struct ubifs_lprops *do_find_free_space(struct ubifs_info *c,
* ubifs_find_free_space - find a data LEB with free space.
* @c: the UBIFS file-system description object
* @min_space: minimum amount of required free space
- * @free: contains amount of free space in the LEB on exit
+ * @offs: contains offset of where free space starts on exit
* @squeeze: whether to try to find space in a non-empty LEB first
*
* This function looks for an LEB with at least @min_space bytes of free space.
@@ -490,7 +490,7 @@ const struct ubifs_lprops *do_find_free_space(struct ubifs_info *c,
* failed to find a LEB with @min_space bytes of free space and other a negative
* error codes in case of failure.
*/
-int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free,
+int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *offs,
int squeeze)
{
const struct ubifs_lprops *lprops;
@@ -558,10 +558,10 @@ int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free,
spin_unlock(&c->space_lock);
}
- *free = lprops->free;
+ *offs = c->leb_size - lprops->free;
ubifs_release_lprops(c);
- if (*free == c->leb_size) {
+ if (*offs == 0) {
/*
* Ensure that empty LEBs have been unmapped. They may not have
* been, for example, because of an unclean unmount. Also
@@ -573,8 +573,8 @@ int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free,
return err;
}
- dbg_find("found LEB %d, free %d", lnum, *free);
- ubifs_assert(*free >= min_space);
+ dbg_find("found LEB %d, free %d", lnum, c->leb_size - *offs);
+ ubifs_assert(*offs <= c->leb_size - min_space);
return lnum;
out:
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c
index a711d33b3d3..f0f5f15d384 100644
--- a/fs/ubifs/gc.c
+++ b/fs/ubifs/gc.c
@@ -47,7 +47,7 @@
* have to waste large pieces of free space at the end of LEB B, because nodes
* from LEB A would not fit. And the worst situation is when all nodes are of
* maximum size. So dark watermark is the amount of free + dirty space in LEB
- * which are guaranteed to be reclaimable. If LEB has less space, the GC migh
+ * which are guaranteed to be reclaimable. If LEB has less space, the GC might
* be unable to reclaim it. So, LEBs with free + dirty greater than dark
* watermark are "good" LEBs from GC's point of few. The other LEBs are not so
* good, and GC takes extra care when moving them.
@@ -57,14 +57,6 @@
#include "ubifs.h"
/*
- * GC tries to optimize the way it fit nodes to available space, and it sorts
- * nodes a little. The below constants are watermarks which define "large",
- * "medium", and "small" nodes.
- */
-#define MEDIUM_NODE_WM (UBIFS_BLOCK_SIZE / 4)
-#define SMALL_NODE_WM UBIFS_MAX_DENT_NODE_SZ
-
-/*
* GC may need to move more than one LEB to make progress. The below constants
* define "soft" and "hard" limits on the number of LEBs the garbage collector
* may move.
@@ -116,83 +108,222 @@ 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
+ * list_sort - sort a list.
+ * @priv: private data, passed to @cmp
+ * @head: the list to sort
+ * @cmp: the elements comparison function
*
- * 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.
+ * This function has been implemented by Mark J Roberts <mjr@znex.org>. It
+ * implements "merge sort" which has O(nlog(n)) complexity. The list is sorted
+ * in ascending order.
+ *
+ * The comparison function @cmp is supposed to return a negative value if @a is
+ * than @b, and a positive value if @a is greater than @b. If @a and @b are
+ * equivalent, then it does not matter what this function returns.
*/
-static int joinup(struct ubifs_info *c, struct ubifs_scan_leb *sleb, ino_t inum,
- unsigned int blk, struct list_head *data)
+static void list_sort(void *priv, struct list_head *head,
+ int (*cmp)(void *priv, struct list_head *a,
+ struct list_head *b))
{
- int err, cnt = 6, lnum = sleb->lnum, offs;
- struct ubifs_scan_node *snod, *tmp;
- union ubifs_key *key;
+ struct list_head *p, *q, *e, *list, *tail, *oldhead;
+ int insize, nmerges, psize, qsize, i;
+
+ if (list_empty(head))
+ return;
+
+ list = head->next;
+ list_del(head);
+ insize = 1;
+ for (;;) {
+ p = oldhead = list;
+ list = tail = NULL;
+ nmerges = 0;
+
+ while (p) {
+ nmerges++;
+ q = p;
+ psize = 0;
+ for (i = 0; i < insize; i++) {
+ psize++;
+ q = q->next == oldhead ? NULL : q->next;
+ if (!q)
+ break;
+ }
- 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)
+ qsize = insize;
+ while (psize > 0 || (qsize > 0 && q)) {
+ if (!psize) {
+ e = q;
+ q = q->next;
+ qsize--;
+ if (q == oldhead)
+ q = NULL;
+ } else if (!qsize || !q) {
+ e = p;
+ p = p->next;
+ psize--;
+ if (p == oldhead)
+ p = NULL;
+ } else if (cmp(priv, p, q) <= 0) {
+ e = p;
+ p = p->next;
+ psize--;
+ if (p == oldhead)
+ p = NULL;
+ } else {
+ e = q;
+ q = q->next;
+ qsize--;
+ if (q == oldhead)
+ q = NULL;
+ }
+ if (tail)
+ tail->next = e;
+ else
+ list = e;
+ e->prev = tail;
+ tail = e;
+ }
+ p = q;
+ }
+
+ tail->next = list;
+ list->prev = tail;
+
+ if (nmerges <= 1)
break;
+
+ insize *= 2;
}
- return 0;
+
+ head->next = list;
+ head->prev = list->prev;
+ list->prev->next = head;
+ list->prev = head;
}
/**
- * move_nodes - move nodes.
+ * data_nodes_cmp - compare 2 data nodes.
+ * @priv: UBIFS file-system description object
+ * @a: first data node
+ * @a: second data node
+ *
+ * This function compares data nodes @a and @b. Returns %1 if @a has greater
+ * inode or block number, and %-1 otherwise.
+ */
+int data_nodes_cmp(void *priv, struct list_head *a, struct list_head *b)
+{
+ ino_t inuma, inumb;
+ struct ubifs_info *c = priv;
+ struct ubifs_scan_node *sa, *sb;
+
+ cond_resched();
+ sa = list_entry(a, struct ubifs_scan_node, list);
+ sb = list_entry(b, struct ubifs_scan_node, list);
+ ubifs_assert(key_type(c, &sa->key) == UBIFS_DATA_KEY);
+ ubifs_assert(key_type(c, &sb->key) == UBIFS_DATA_KEY);
+
+ inuma = key_inum(c, &sa->key);
+ inumb = key_inum(c, &sb->key);
+
+ if (inuma == inumb) {
+ unsigned int blka = key_block(c, &sa->key);
+ unsigned int blkb = key_block(c, &sb->key);
+
+ if (blka <= blkb)
+ return -1;
+ } else if (inuma <= inumb)
+ return -1;
+
+ return 1;
+}
+
+/*
+ * nondata_nodes_cmp - compare 2 non-data nodes.
+ * @priv: UBIFS file-system description object
+ * @a: first node
+ * @a: second node
+ *
+ * This function compares nodes @a and @b. It makes sure that inode nodes go
+ * first and sorted by length in descending order. Directory entry nodes go
+ * after inode nodes and are sorted in ascending hash valuer order.
+ */
+int nondata_nodes_cmp(void *priv, struct list_head *a, struct list_head *b)
+{
+ int typea, typeb;
+ ino_t inuma, inumb;
+ struct ubifs_info *c = priv;
+ struct ubifs_scan_node *sa, *sb;
+
+ cond_resched();
+ sa = list_entry(a, struct ubifs_scan_node, list);
+ sb = list_entry(b, struct ubifs_scan_node, list);
+ typea = key_type(c, &sa->key);
+ typeb = key_type(c, &sb->key);
+ ubifs_assert(typea != UBIFS_DATA_KEY && typeb != UBIFS_DATA_KEY);
+
+ /* Inodes go before directory entries */
+ if (typea == UBIFS_INO_KEY) {
+ if (typeb == UBIFS_INO_KEY)
+ return sb->len - sa->len;
+ return -1;
+ }
+ if (typeb == UBIFS_INO_KEY)
+ return 1;
+
+ ubifs_assert(typea == UBIFS_DENT_KEY && typeb == UBIFS_DENT_KEY);
+ inuma = key_inum(c, &sa->key);
+ inumb = key_inum(c, &sb->key);
+
+ if (inuma == inumb) {
+ uint32_t hasha = key_hash(c, &sa->key);
+ uint32_t hashb = key_hash(c, &sb->key);
+
+ if (hasha <= hashb)
+ return -1;
+ } else if (inuma <= inumb)
+ return -1;
+
+ return 1;
+}
+
+/**
+ * sort_nodes - sort nodes for GC.
* @c: UBIFS file-system description object
- * @sleb: describes nodes to move
+ * @sleb: describes nodes to sort and contains the result on exit
+ * @nondata: contains non-data nodes on exit
+ * @min: minimum node size is returned here
*
- * This function moves valid nodes from data LEB described by @sleb to the GC
- * journal head. The obsolete nodes are dropped.
+ * This function sorts the list of inodes to garbage collect. First of all, it
+ * kills obsolete nodes and separates data and non-data nodes to the
+ * @sleb->nodes and @nondata lists correspondingly.
+ *
+ * Data nodes are then sorted in block number order - this is important for
+ * bulk-read; data nodes with lower inode number go before data nodes with
+ * higher inode number, and data nodes with lower block number go before data
+ * nodes with higher block number;
*
- * When moving nodes we have to deal with classical bin-packing problem: the
- * space in the current GC journal head LEB and in @c->gc_lnum are the "bins",
- * where the nodes in the @sleb->nodes list are the elements which should be
- * fit optimally to the bins. This function uses the "first fit decreasing"
- * strategy, although it does not really sort the nodes but just split them on
- * 3 classes - large, medium, and small, so they are roughly sorted.
+ * Non-data nodes are sorted as follows.
+ * o First go inode nodes - they are sorted in descending length order.
+ * o Then go directory entry nodes - they are sorted in hash order, which
+ * should supposedly optimize 'readdir()'. Direntry nodes with lower parent
+ * inode number go before direntry nodes with higher parent inode number,
+ * and direntry nodes with lower name hash values go before direntry nodes
+ * with higher name hash values.
*
- * This function returns zero in case of success, %-EAGAIN if commit is
- * required, and other negative error codes in case of other failures.
+ * This function returns zero in case of success and a negative error code in
+ * case of failure.
*/
-static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
+static int sort_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
+ struct list_head *nondata, int *min)
{
struct ubifs_scan_node *snod, *tmp;
- 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);
+ *min = INT_MAX;
- while (!list_empty(&sleb->nodes)) {
- struct list_head *lst = sleb->nodes.next;
-
- snod = list_entry(lst, struct ubifs_scan_node, list);
+ /* Separate data nodes and non-data nodes */
+ list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) {
+ int err;
ubifs_assert(snod->type != UBIFS_IDX_NODE);
ubifs_assert(snod->type != UBIFS_REF_NODE);
@@ -201,53 +332,72 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
err = ubifs_tnc_has_node(c, &snod->key, 0, sleb->lnum,
snod->offs, 0);
if (err < 0)
- goto out;
+ return err;
- list_del(lst);
if (!err) {
/* The node is obsolete, remove it from the list */
+ list_del(&snod->list);
kfree(snod);
continue;
}
- /*
- * Sort the list of nodes so that data nodes go first, large
- * nodes go second, and small nodes go last.
- */
- 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_tail(lst, &medium);
- else
- list_add_tail(lst, &small);
-
- /* And find the smallest node */
- if (snod->len < min)
- min = snod->len;
+ if (snod->len < *min)
+ *min = snod->len;
+
+ if (key_type(c, &snod->key) != UBIFS_DATA_KEY)
+ list_move_tail(&snod->list, nondata);
}
- /*
- * 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);
+ /* Sort data and non-data nodes */
+ list_sort(c, &sleb->nodes, &data_nodes_cmp);
+ list_sort(c, nondata, &nondata_nodes_cmp);
+ return 0;
+}
+
+/**
+ * move_node - move a node.
+ * @c: UBIFS file-system description object
+ * @sleb: describes the LEB to move nodes from
+ * @snod: the mode to move
+ * @wbuf: write-buffer to move node to
+ *
+ * This function moves node @snod to @wbuf, changes TNC correspondingly, and
+ * destroys @snod. Returns zero in case of success and a negative error code in
+ * case of failure.
+ */
+static int move_node(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
+ struct ubifs_scan_node *snod, struct ubifs_wbuf *wbuf)
+{
+ int err, new_lnum = wbuf->lnum, new_offs = wbuf->offs + wbuf->used;
+
+ cond_resched();
+ err = ubifs_wbuf_write_nolock(wbuf, snod->node, snod->len);
+ if (err)
+ return err;
+
+ err = ubifs_tnc_replace(c, &snod->key, sleb->lnum,
+ snod->offs, new_lnum, new_offs,
+ snod->len);
+ list_del(&snod->list);
+ kfree(snod);
+ return err;
+}
+
+/**
+ * move_nodes - move nodes.
+ * @c: UBIFS file-system description object
+ * @sleb: describes the LEB to move nodes from
+ *
+ * This function moves valid nodes from data LEB described by @sleb to the GC
+ * journal head. This function returns zero in case of success, %-EAGAIN if
+ * commit is required, and other negative error codes in case of other
+ * failures.
+ */
+static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
+{
+ int err, min;
+ LIST_HEAD(nondata);
+ struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
if (wbuf->lnum == -1) {
/*
@@ -256,42 +406,59 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
*/
err = switch_gc_head(c);
if (err)
- goto out;
+ return err;
}
+ err = sort_nodes(c, sleb, &nondata, &min);
+ if (err)
+ goto out;
+
/* Write nodes to their new location. Use the first-fit strategy */
while (1) {
- avail = c->leb_size - wbuf->offs - wbuf->used;
- list_for_each_entry_safe(snod, tmp, &large, list) {
- int new_lnum, new_offs;
+ int avail;
+ struct ubifs_scan_node *snod, *tmp;
+
+ /* Move data nodes */
+ list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) {
+ avail = c->leb_size - wbuf->offs - wbuf->used;
+ if (snod->len > avail)
+ /*
+ * Do not skip data nodes in order to optimize
+ * bulk-read.
+ */
+ break;
+
+ err = move_node(c, sleb, snod, wbuf);
+ if (err)
+ goto out;
+ }
+ /* Move non-data nodes */
+ list_for_each_entry_safe(snod, tmp, &nondata, list) {
+ avail = c->leb_size - wbuf->offs - wbuf->used;
if (avail < min)
break;
- if (snod->len > avail)
- /* This node does not fit */
+ if (snod->len > avail) {
+ /*
+ * Keep going only if this is an inode with
+ * some data. Otherwise stop and switch the GC
+ * head. IOW, we assume that data-less inode
+ * nodes and direntry nodes are roughly of the
+ * same size.
+ */
+ if (key_type(c, &snod->key) == UBIFS_DENT_KEY ||
+ snod->len == UBIFS_INO_NODE_SZ)
+ break;
continue;
+ }
- cond_resched();
-
- new_lnum = wbuf->lnum;
- new_offs = wbuf->offs + wbuf->used;
- err = ubifs_wbuf_write_nolock(wbuf, snod->node,
- snod->len);
+ err = move_node(c, sleb, snod, wbuf);
if (err)
goto out;
- err = ubifs_tnc_replace(c, &snod->key, sleb->lnum,
- snod->offs, new_lnum, new_offs,
- snod->len);
- if (err)
- goto out;
-
- avail = c->leb_size - wbuf->offs - wbuf->used;
- list_del(&snod->list);
- kfree(snod);
}
- if (list_empty(&large))
+ if (list_empty(&sleb->nodes) && list_empty(&nondata))
break;
/*
@@ -306,10 +473,7 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
return 0;
out:
- list_for_each_entry_safe(snod, tmp, &large, list) {
- list_del(&snod->list);
- kfree(snod);
- }
+ list_splice_tail(&nondata, &sleb->nodes);
return err;
}
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index a11ca0958a2..64b5f3a309f 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -114,7 +114,7 @@ static inline void zero_trun_node_unused(struct ubifs_trun_node *trun)
*/
static int reserve_space(struct ubifs_info *c, int jhead, int len)
{
- int err = 0, err1, retries = 0, avail, lnum, offs, free, squeeze;
+ int err = 0, err1, retries = 0, avail, lnum, offs, squeeze;
struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf;
/*
@@ -139,10 +139,9 @@ again:
* Write buffer wasn't seek'ed or there is no enough space - look for an
* LEB with some empty space.
*/
- lnum = ubifs_find_free_space(c, len, &free, squeeze);
+ lnum = ubifs_find_free_space(c, len, &offs, squeeze);
if (lnum >= 0) {
/* Found an LEB, add it to the journal head */
- offs = c->leb_size - free;
err = ubifs_add_bud_to_log(c, jhead, lnum, offs);
if (err)
goto out_return;
@@ -1366,7 +1365,7 @@ out_ro:
* @host: host inode
*
* This function writes the updated version of an extended attribute inode and
- * the host inode tho the journal (to the base head). The host inode is written
+ * the host inode to the journal (to the base head). The host inode is written
* after the extended attribute inode in order to guarantee that the extended
* attribute will be flushed when the inode is synchronized by 'fsync()' and
* consequently, the write-buffer is synchronized. This function returns zero
diff --git a/fs/ubifs/key.h b/fs/ubifs/key.h
index efb3430a258..5fa27ea031b 100644
--- a/fs/ubifs/key.h
+++ b/fs/ubifs/key.h
@@ -381,8 +381,8 @@ static inline ino_t key_inum_flash(const struct ubifs_info *c, const void *k)
* @c: UBIFS file-system description object
* @key: the key to get hash from
*/
-static inline int key_hash(const struct ubifs_info *c,
- const union ubifs_key *key)
+static inline uint32_t key_hash(const struct ubifs_info *c,
+ const union ubifs_key *key)
{
return key->u32[1] & UBIFS_S_KEY_HASH_MASK;
}
@@ -392,7 +392,7 @@ static inline int key_hash(const struct ubifs_info *c,
* @c: UBIFS file-system description object
* @k: the key to get hash from
*/
-static inline int key_hash_flash(const struct ubifs_info *c, const void *k)
+static inline uint32_t key_hash_flash(const struct ubifs_info *c, const void *k)
{
const union ubifs_key *key = k;
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c
index 3e0aa736755..56e33772a1e 100644
--- a/fs/ubifs/log.c
+++ b/fs/ubifs/log.c
@@ -239,7 +239,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
}
/*
- * Make sure the the amount of space in buds will not exceed
+ * Make sure the amount of space in buds will not exceed the
* 'c->max_bud_bytes' limit, because we want to guarantee mount time
* limits.
*
@@ -367,7 +367,6 @@ static void remove_buds(struct ubifs_info *c)
bud->jhead, c->leb_size - bud->start,
c->cmt_bud_bytes);
rb_erase(p1, &c->buds);
- list_del(&bud->list);
/*
* If the commit does not finish, the recovery will need
* to replay the journal, in which case the old buds
@@ -375,7 +374,7 @@ static void remove_buds(struct ubifs_info *c)
* commit i.e. do not allow them to be garbage
* collected.
*/
- list_add(&bud->list, &c->old_buds);
+ list_move(&bud->list, &c->old_buds);
}
}
spin_unlock(&c->buds_lock);
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index 3216a1f277f..8cbfb824802 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -229,7 +229,7 @@ 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);
+ dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
err = alloc_lpt_leb(c, &lnum);
if (err)
goto no_space;
@@ -272,7 +272,7 @@ 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);
+ dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
err = alloc_lpt_leb(c, &lnum);
if (err)
goto no_space;
@@ -292,7 +292,7 @@ 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);
+ dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
err = alloc_lpt_leb(c, &lnum);
if (err)
goto no_space;
@@ -416,14 +416,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);
+ dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
err = realloc_lpt_leb(c, &lnum);
if (err)
goto no_space;
- offs = 0;
- from = 0;
+ offs = from = 0;
ubifs_assert(lnum >= c->lpt_first &&
lnum <= c->lpt_last);
err = ubifs_leb_unmap(c, lnum);
@@ -477,11 +475,11 @@ static int write_cnodes(struct ubifs_info *c)
UBI_SHORTTERM);
if (err)
return err;
- dbg_chk_lpt_sz(c, 2, alen - wlen);
+ dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
err = realloc_lpt_leb(c, &lnum);
if (err)
goto no_space;
- offs = 0;
+ offs = from = 0;
ubifs_assert(lnum >= c->lpt_first &&
lnum <= c->lpt_last);
err = ubifs_leb_unmap(c, lnum);
@@ -504,11 +502,11 @@ static int write_cnodes(struct ubifs_info *c)
UBI_SHORTTERM);
if (err)
return err;
- dbg_chk_lpt_sz(c, 2, alen - wlen);
+ dbg_chk_lpt_sz(c, 2, c->leb_size - offs);
err = realloc_lpt_leb(c, &lnum);
if (err)
goto no_space;
- offs = 0;
+ offs = from = 0;
ubifs_assert(lnum >= c->lpt_first &&
lnum <= c->lpt_last);
err = ubifs_leb_unmap(c, lnum);
@@ -1756,10 +1754,16 @@ int dbg_chk_lpt_free_spc(struct ubifs_info *c)
/**
* dbg_chk_lpt_sz - check LPT does not write more than LPT size.
* @c: the UBIFS file-system description object
- * @action: action
+ * @action: what to do
* @len: length written
*
* This function returns %0 on success and a negative error code on failure.
+ * The @action argument may be one of:
+ * o %0 - LPT debugging checking starts, initialize debugging variables;
+ * o %1 - wrote an LPT node, increase LPT size by @len bytes;
+ * o %2 - switched to a different LEB and wasted @len bytes;
+ * o %3 - check that we've written the right number of bytes.
+ * o %4 - wasted @len bytes;
*/
int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len)
{
@@ -1917,12 +1921,12 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
lnum, offs);
err = ubifs_unpack_nnode(c, buf, &nnode);
for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
- printk("%d:%d", nnode.nbranch[i].lnum,
+ printk(KERN_CONT "%d:%d", nnode.nbranch[i].lnum,
nnode.nbranch[i].offs);
if (i != UBIFS_LPT_FANOUT - 1)
- printk(", ");
+ printk(KERN_CONT ", ");
}
- printk("\n");
+ printk(KERN_CONT "\n");
break;
}
case UBIFS_LPT_LTAB:
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index 90acac603e6..10662975d2e 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -425,59 +425,35 @@ static void clean_buf(const struct ubifs_info *c, void **buf, int lnum,
* @lnum: LEB number of the LEB from which @buf was read
* @offs: offset from which @buf was read
*
- * This function scans @buf for more nodes and returns %0 is a node is found and
- * %1 if no more nodes are found.
+ * This function ensures that the corrupted node at @offs is the last thing
+ * written to a LEB. This function returns %1 if more data is not found and
+ * %0 if more data is found.
*/
static int no_more_nodes(const struct ubifs_info *c, void *buf, int len,
int lnum, int offs)
{
- int skip, next_offs = 0;
+ struct ubifs_ch *ch = buf;
+ int skip, dlen = le32_to_cpu(ch->len);
- if (len > UBIFS_DATA_NODE_SZ) {
- struct ubifs_ch *ch = buf;
- int dlen = le32_to_cpu(ch->len);
-
- if (ch->node_type == UBIFS_DATA_NODE && dlen >= UBIFS_CH_SZ &&
- dlen <= UBIFS_MAX_DATA_NODE_SZ)
- /* The corrupt node looks like a data node */
- next_offs = ALIGN(offs + dlen, 8);
- }
-
- if (c->min_io_size == 1)
- skip = 8;
- else
- skip = ALIGN(offs + 1, c->min_io_size) - offs;
-
- offs += skip;
- buf += skip;
- len -= skip;
- while (len > 8) {
- struct ubifs_ch *ch = buf;
- uint32_t magic = le32_to_cpu(ch->magic);
- int ret;
-
- if (magic == UBIFS_NODE_MAGIC) {
- ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 1);
- if (ret == SCANNED_A_NODE || ret > 0) {
- /*
- * There is a small chance this is just data in
- * a data node, so check that possibility. e.g.
- * this is part of a file that itself contains
- * a UBIFS image.
- */
- if (next_offs && offs + le32_to_cpu(ch->len) <=
- next_offs)
- continue;
- dbg_rcvry("unexpected node at %d:%d", lnum,
- offs);
- return 0;
- }
- }
- offs += 8;
- buf += 8;
- len -= 8;
+ /* Check for empty space after the corrupt node's common header */
+ skip = ALIGN(offs + UBIFS_CH_SZ, c->min_io_size) - offs;
+ if (is_empty(buf + skip, len - skip))
+ return 1;
+ /*
+ * The area after the common header size is not empty, so the common
+ * header must be intact. Check it.
+ */
+ if (ubifs_check_node(c, buf, lnum, offs, 1, 0) != -EUCLEAN) {
+ dbg_rcvry("unexpected bad common header at %d:%d", lnum, offs);
+ return 0;
}
- return 1;
+ /* Now we know the corrupt node's length we can skip over it */
+ skip = ALIGN(offs + dlen, c->min_io_size) - offs;
+ /* After which there should be empty space */
+ if (is_empty(buf + skip, len - skip))
+ return 1;
+ dbg_rcvry("unexpected data at %d:%d", lnum, offs + skip);
+ return 0;
}
/**
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
index ce42a7b0ca5..11cc80125a4 100644
--- a/fs/ubifs/replay.c
+++ b/fs/ubifs/replay.c
@@ -143,7 +143,7 @@ static int set_bud_lprops(struct ubifs_info *c, struct replay_entry *r)
dirty -= c->leb_size - lp->free;
/*
* If the replay order was perfect the dirty space would now be
- * zero. The order is not perfect because the the journal heads
+ * zero. The order is not perfect because the journal heads
* race with each other. This is not a problem but is does mean
* that the dirty space may temporarily exceed c->leb_size
* during the replay.
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c
index e070c643d1b..57085e43320 100644
--- a/fs/ubifs/sb.c
+++ b/fs/ubifs/sb.c
@@ -193,6 +193,7 @@ static int create_default_filesystem(struct ubifs_info *c)
if (tmp64 > DEFAULT_MAX_RP_SIZE)
tmp64 = DEFAULT_MAX_RP_SIZE;
sup->rp_size = cpu_to_le64(tmp64);
+ sup->ro_compat_version = cpu_to_le32(UBIFS_RO_COMPAT_VERSION);
err = ubifs_write_node(c, sup, UBIFS_SB_NODE_SZ, 0, 0, UBI_LONGTERM);
kfree(sup);
@@ -532,17 +533,39 @@ int ubifs_read_superblock(struct ubifs_info *c)
if (IS_ERR(sup))
return PTR_ERR(sup);
+ c->fmt_version = le32_to_cpu(sup->fmt_version);
+ c->ro_compat_version = le32_to_cpu(sup->ro_compat_version);
+
/*
* The software supports all previous versions but not future versions,
* due to the unavailability of time-travelling equipment.
*/
- c->fmt_version = le32_to_cpu(sup->fmt_version);
if (c->fmt_version > UBIFS_FORMAT_VERSION) {
- ubifs_err("on-flash format version is %d, but software only "
- "supports up to version %d", c->fmt_version,
- UBIFS_FORMAT_VERSION);
- err = -EINVAL;
- goto out;
+ struct super_block *sb = c->vfs_sb;
+ int mounting_ro = sb->s_flags & MS_RDONLY;
+
+ ubifs_assert(!c->ro_media || mounting_ro);
+ if (!mounting_ro ||
+ c->ro_compat_version > UBIFS_RO_COMPAT_VERSION) {
+ ubifs_err("on-flash format version is w%d/r%d, but "
+ "software only supports up to version "
+ "w%d/r%d", c->fmt_version,
+ c->ro_compat_version, UBIFS_FORMAT_VERSION,
+ UBIFS_RO_COMPAT_VERSION);
+ if (c->ro_compat_version <= UBIFS_RO_COMPAT_VERSION) {
+ ubifs_msg("only R/O mounting is possible");
+ err = -EROFS;
+ } else
+ err = -EINVAL;
+ goto out;
+ }
+
+ /*
+ * The FS is mounted R/O, and the media format is
+ * R/O-compatible with the UBIFS implementation, so we can
+ * mount.
+ */
+ c->rw_incompat = 1;
}
if (c->fmt_version < 3) {
@@ -623,7 +646,6 @@ int ubifs_read_superblock(struct ubifs_info *c)
c->main_lebs = c->leb_cnt - UBIFS_SB_LEBS - UBIFS_MST_LEBS;
c->main_lebs -= c->log_lebs + c->lpt_lebs + c->orph_lebs;
c->main_first = c->leb_cnt - c->main_lebs;
- c->report_rp_size = ubifs_reported_space(c, c->rp_size);
err = validate_sb(c, sup);
out:
diff --git a/fs/ubifs/shrinker.c b/fs/ubifs/shrinker.c
index e7bab52a141..02feb59cefc 100644
--- a/fs/ubifs/shrinker.c
+++ b/fs/ubifs/shrinker.c
@@ -206,8 +206,7 @@ static int shrink_tnc_trees(int nr, int age, int *contention)
* Move this one to the end of the list to provide some
* fairness.
*/
- list_del(&c->infos_list);
- list_add_tail(&c->infos_list, &ubifs_infos);
+ list_move_tail(&c->infos_list, &ubifs_infos);
mutex_unlock(&c->umount_mutex);
if (freed >= nr)
break;
@@ -263,8 +262,7 @@ static int kick_a_thread(void)
}
if (i == 1) {
- list_del(&c->infos_list);
- list_add_tail(&c->infos_list, &ubifs_infos);
+ list_move_tail(&c->infos_list, &ubifs_infos);
spin_unlock(&ubifs_infos_lock);
ubifs_request_bg_commit(c);
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index c5c98355459..faa44f90608 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -421,8 +421,8 @@ static int ubifs_show_options(struct seq_file *s, struct vfsmount *mnt)
seq_printf(s, ",no_chk_data_crc");
if (c->mount_opts.override_compr) {
- seq_printf(s, ",compr=");
- seq_printf(s, ubifs_compr_name(c->mount_opts.compr_type));
+ seq_printf(s, ",compr=%s",
+ ubifs_compr_name(c->mount_opts.compr_type));
}
return 0;
@@ -700,6 +700,8 @@ static int init_constants_sb(struct ubifs_info *c)
if (err)
return err;
+ /* Initialize effective LEB size used in budgeting calculations */
+ c->idx_leb_size = c->leb_size - c->max_idx_node_sz;
return 0;
}
@@ -716,6 +718,7 @@ static void init_constants_master(struct ubifs_info *c)
long long tmp64;
c->min_idx_lebs = ubifs_calc_min_idx_lebs(c);
+ c->report_rp_size = ubifs_reported_space(c, c->rp_size);
/*
* Calculate total amount of FS blocks. This number is not used
@@ -1201,7 +1204,7 @@ static int mount_ubifs(struct ubifs_info *c)
goto out_cbuf;
/* Create background thread */
- c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name);
+ c->bgt = kthread_create(ubifs_bg_thread, c, "%s", c->bgt_name);
if (IS_ERR(c->bgt)) {
err = PTR_ERR(c->bgt);
c->bgt = NULL;
@@ -1318,11 +1321,15 @@ static int mount_ubifs(struct ubifs_info *c)
else {
c->need_recovery = 0;
ubifs_msg("recovery completed");
- /* GC LEB has to be empty and taken at this point */
- ubifs_assert(c->lst.taken_empty_lebs == 1);
+ /*
+ * GC LEB has to be empty and taken at this point. But
+ * the journal head LEBs may also be accounted as
+ * "empty taken" if they are empty.
+ */
+ ubifs_assert(c->lst.taken_empty_lebs > 0);
}
} else
- ubifs_assert(c->lst.taken_empty_lebs == 1);
+ ubifs_assert(c->lst.taken_empty_lebs > 0);
err = dbg_check_filesystem(c);
if (err)
@@ -1344,8 +1351,9 @@ static int mount_ubifs(struct ubifs_info *c)
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("media format: %d (latest is %d)",
- c->fmt_version, UBIFS_FORMAT_VERSION);
+ ubifs_msg("media format: w%d/r%d (latest is w%d/r%d)",
+ c->fmt_version, c->ro_compat_version,
+ UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_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);
@@ -1485,6 +1493,15 @@ static int ubifs_remount_rw(struct ubifs_info *c)
{
int err, lnum;
+ if (c->rw_incompat) {
+ ubifs_err("the file-system is not R/W-compatible");
+ ubifs_msg("on-flash format version is w%d/r%d, but software "
+ "only supports up to version w%d/r%d", c->fmt_version,
+ c->ro_compat_version, UBIFS_FORMAT_VERSION,
+ UBIFS_RO_COMPAT_VERSION);
+ return -EROFS;
+ }
+
mutex_lock(&c->umount_mutex);
dbg_save_space_info(c);
c->remounting_rw = 1;
@@ -1554,7 +1571,7 @@ static int ubifs_remount_rw(struct ubifs_info *c)
ubifs_create_buds_lists(c);
/* Create background thread */
- c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name);
+ c->bgt = kthread_create(ubifs_bg_thread, c, "%s", c->bgt_name);
if (IS_ERR(c->bgt)) {
err = PTR_ERR(c->bgt);
c->bgt = NULL;
@@ -1775,7 +1792,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
c->bu.buf = NULL;
}
- ubifs_assert(c->lst.taken_empty_lebs == 1);
+ ubifs_assert(c->lst.taken_empty_lebs > 0);
return 0;
}
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index fa28a84c6a1..f249f7b0d65 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -1252,7 +1252,7 @@ int ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key,
* splitting in the middle of the colliding sequence. Also, when
* removing the leftmost key, we would have to correct the key of the
* parent node, which would introduce additional complications. Namely,
- * if we changed the the leftmost key of the parent znode, the garbage
+ * if we changed the leftmost key of the parent znode, the garbage
* collector would be unable to find it (GC is doing this when GC'ing
* indexing LEBs). Although we already have an additional RB-tree where
* we save such changed znodes (see 'ins_clr_old_idx_znode()') until
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h
index b25fc36cf72..3eee07e0c49 100644
--- a/fs/ubifs/ubifs-media.h
+++ b/fs/ubifs/ubifs-media.h
@@ -36,9 +36,31 @@
/* UBIFS node magic number (must not have the padding byte first or last) */
#define UBIFS_NODE_MAGIC 0x06101831
-/* UBIFS on-flash format version */
+/*
+ * UBIFS on-flash format version. This version is increased when the on-flash
+ * format is changing. If this happens, UBIFS is will support older versions as
+ * well. But older UBIFS code will not support newer formats. Format changes
+ * will be rare and only when absolutely necessary, e.g. to fix a bug or to add
+ * a new feature.
+ *
+ * UBIFS went into mainline kernel with format version 4. The older formats
+ * were development formats.
+ */
#define UBIFS_FORMAT_VERSION 4
+/*
+ * Read-only compatibility version. If the UBIFS format is changed, older UBIFS
+ * implementations will not be able to mount newer formats in read-write mode.
+ * However, depending on the change, it may be possible to mount newer formats
+ * in R/O mode. This is indicated by the R/O compatibility version which is
+ * stored in the super-block.
+ *
+ * This is needed to support boot-loaders which only need R/O mounting. With
+ * this flag it is possible to do UBIFS format changes without a need to update
+ * boot-loaders.
+ */
+#define UBIFS_RO_COMPAT_VERSION 0
+
/* Minimum logical eraseblock size in bytes */
#define UBIFS_MIN_LEB_SZ (15*1024)
@@ -53,7 +75,7 @@
/*
* If compressed data length is less than %UBIFS_MIN_COMPRESS_DIFF bytes
- * shorter than uncompressed data length, UBIFS preferes to leave this data
+ * shorter than uncompressed data length, UBIFS prefers to leave this data
* node uncompress, because it'll be read faster.
*/
#define UBIFS_MIN_COMPRESS_DIFF 64
@@ -586,6 +608,7 @@ struct ubifs_pad_node {
* @padding2: reserved for future, zeroes
* @time_gran: time granularity in nanoseconds
* @uuid: UUID generated when the file system image was created
+ * @ro_compat_version: UBIFS R/O compatibility version
*/
struct ubifs_sb_node {
struct ubifs_ch ch;
@@ -612,7 +635,8 @@ struct ubifs_sb_node {
__le64 rp_size;
__le32 time_gran;
__u8 uuid[16];
- __u8 padding2[3972];
+ __le32 ro_compat_version;
+ __u8 padding2[3968];
} __attribute__ ((packed));
/**
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 039a68bee29..0a8341e1408 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -934,6 +934,7 @@ struct ubifs_debug_info;
* by @commit_sem
* @cnt_lock: protects @highest_inum and @max_sqnum counters
* @fmt_version: UBIFS on-flash format version
+ * @ro_compat_version: R/O compatibility version
* @uuid: UUID from super block
*
* @lhead_lnum: log head logical eraseblock number
@@ -966,6 +967,7 @@ struct ubifs_debug_info;
* recovery)
* @bulk_read: enable bulk-reads
* @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc)
+ * @rw_incompat: the media is not R/W compatible
*
* @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and
* @calc_idx_sz
@@ -1015,6 +1017,8 @@ struct ubifs_debug_info;
* @min_io_shift: number of bits in @min_io_size minus one
* @leb_size: logical eraseblock size in bytes
* @half_leb_size: half LEB size
+ * @idx_leb_size: how many bytes of an LEB are effectively available when it is
+ * used to store indexing nodes (@leb_size - @max_idx_node_sz)
* @leb_cnt: count of logical eraseblocks
* @max_leb_cnt: maximum count of logical eraseblocks
* @old_leb_cnt: count of logical eraseblocks before re-size
@@ -1132,8 +1136,8 @@ struct ubifs_debug_info;
* previous commit start
* @uncat_list: list of un-categorized LEBs
* @empty_list: list of empty LEBs
- * @freeable_list: list of freeable non-index LEBs (free + dirty == leb_size)
- * @frdi_idx_list: list of freeable index LEBs (free + dirty == leb_size)
+ * @freeable_list: list of freeable non-index LEBs (free + dirty == @leb_size)
+ * @frdi_idx_list: list of freeable index LEBs (free + dirty == @leb_size)
* @freeable_cnt: number of freeable LEBs in @freeable_list
*
* @ltab_lnum: LEB number of LPT's own lprops table
@@ -1177,6 +1181,7 @@ struct ubifs_info {
unsigned long long cmt_no;
spinlock_t cnt_lock;
int fmt_version;
+ int ro_compat_version;
unsigned char uuid[16];
int lhead_lnum;
@@ -1205,6 +1210,7 @@ struct ubifs_info {
unsigned int no_chk_data_crc:1;
unsigned int bulk_read:1;
unsigned int default_compr:2;
+ unsigned int rw_incompat:1;
struct mutex tnc_mutex;
struct ubifs_zbranch zroot;
@@ -1253,6 +1259,7 @@ struct ubifs_info {
int min_io_shift;
int leb_size;
int half_leb_size;
+ int idx_leb_size;
int leb_cnt;
int max_leb_cnt;
int old_leb_cnt;
@@ -1500,7 +1507,7 @@ long long ubifs_reported_space(const struct ubifs_info *c, long long free);
long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs);
/* find.c */
-int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free,
+int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *offs,
int squeeze);
int ubifs_find_free_leb_for_idx(struct ubifs_info *c);
int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index 2bb788a2acb..e48e9a3af76 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -87,12 +87,12 @@ static int read_block_bitmap(struct super_block *sb,
{
struct buffer_head *bh = NULL;
int retval = 0;
- kernel_lb_addr loc;
+ struct kernel_lb_addr loc;
loc.logicalBlockNum = bitmap->s_extPosition;
loc.partitionReferenceNum = UDF_SB(sb)->s_partition;
- bh = udf_tread(sb, udf_get_lb_pblock(sb, loc, block));
+ bh = udf_tread(sb, udf_get_lb_pblock(sb, &loc, block));
if (!bh)
retval = -EIO;
@@ -140,27 +140,29 @@ static inline int load_block_bitmap(struct super_block *sb,
return slot;
}
-static bool udf_add_free_space(struct udf_sb_info *sbi,
- u16 partition, u32 cnt)
+static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt)
{
+ struct udf_sb_info *sbi = UDF_SB(sb);
struct logicalVolIntegrityDesc *lvid;
- if (sbi->s_lvid_bh == NULL)
- return false;
+ if (!sbi->s_lvid_bh)
+ return;
lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data;
le32_add_cpu(&lvid->freeSpaceTable[partition], cnt);
- return true;
+ udf_updated_lvid(sb);
}
static void udf_bitmap_free_blocks(struct super_block *sb,
struct inode *inode,
struct udf_bitmap *bitmap,
- kernel_lb_addr bloc, uint32_t offset,
+ struct kernel_lb_addr *bloc,
+ uint32_t offset,
uint32_t count)
{
struct udf_sb_info *sbi = UDF_SB(sb);
struct buffer_head *bh = NULL;
+ struct udf_part_map *partmap;
unsigned long block;
unsigned long block_group;
unsigned long bit;
@@ -169,17 +171,17 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
unsigned long overflow;
mutex_lock(&sbi->s_alloc_mutex);
- if (bloc.logicalBlockNum < 0 ||
- (bloc.logicalBlockNum + count) >
- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
+ partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
+ if (bloc->logicalBlockNum < 0 ||
+ (bloc->logicalBlockNum + count) >
+ partmap->s_partition_len) {
udf_debug("%d < %d || %d + %d > %d\n",
- bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
- sbi->s_partmaps[bloc.partitionReferenceNum].
- s_partition_len);
+ bloc->logicalBlockNum, 0, bloc->logicalBlockNum,
+ count, partmap->s_partition_len);
goto error_return;
}
- block = bloc.logicalBlockNum + offset +
+ block = bloc->logicalBlockNum + offset +
(sizeof(struct spaceBitmapDesc) << 3);
do {
@@ -207,7 +209,7 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
} else {
if (inode)
vfs_dq_free_block(inode, 1);
- udf_add_free_space(sbi, sbi->s_partition, 1);
+ udf_add_free_space(sb, sbi->s_partition, 1);
}
}
mark_buffer_dirty(bh);
@@ -218,9 +220,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
} while (overflow);
error_return:
- sb->s_dirt = 1;
- if (sbi->s_lvid_bh)
- mark_buffer_dirty(sbi->s_lvid_bh);
mutex_unlock(&sbi->s_alloc_mutex);
}
@@ -277,9 +276,7 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb,
} while (block_count > 0);
out:
- if (udf_add_free_space(sbi, partition, -alloc_count))
- mark_buffer_dirty(sbi->s_lvid_bh);
- sb->s_dirt = 1;
+ udf_add_free_space(sb, partition, -alloc_count);
mutex_unlock(&sbi->s_alloc_mutex);
return alloc_count;
}
@@ -409,9 +406,7 @@ got_block:
mark_buffer_dirty(bh);
- if (udf_add_free_space(sbi, partition, -1))
- mark_buffer_dirty(sbi->s_lvid_bh);
- sb->s_dirt = 1;
+ udf_add_free_space(sb, partition, -1);
mutex_unlock(&sbi->s_alloc_mutex);
*err = 0;
return newblock;
@@ -425,26 +420,28 @@ error_return:
static void udf_table_free_blocks(struct super_block *sb,
struct inode *inode,
struct inode *table,
- kernel_lb_addr bloc, uint32_t offset,
+ struct kernel_lb_addr *bloc,
+ uint32_t offset,
uint32_t count)
{
struct udf_sb_info *sbi = UDF_SB(sb);
+ struct udf_part_map *partmap;
uint32_t start, end;
uint32_t elen;
- kernel_lb_addr eloc;
+ struct kernel_lb_addr eloc;
struct extent_position oepos, epos;
int8_t etype;
int i;
struct udf_inode_info *iinfo;
mutex_lock(&sbi->s_alloc_mutex);
- if (bloc.logicalBlockNum < 0 ||
- (bloc.logicalBlockNum + count) >
- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
+ partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
+ if (bloc->logicalBlockNum < 0 ||
+ (bloc->logicalBlockNum + count) >
+ partmap->s_partition_len) {
udf_debug("%d < %d || %d + %d > %d\n",
bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
- sbi->s_partmaps[bloc.partitionReferenceNum].
- s_partition_len);
+ partmap->s_partition_len);
goto error_return;
}
@@ -453,11 +450,10 @@ static void udf_table_free_blocks(struct super_block *sb,
could occure, but.. oh well */
if (inode)
vfs_dq_free_block(inode, count);
- if (udf_add_free_space(sbi, sbi->s_partition, count))
- mark_buffer_dirty(sbi->s_lvid_bh);
+ udf_add_free_space(sb, sbi->s_partition, count);
- start = bloc.logicalBlockNum + offset;
- end = bloc.logicalBlockNum + offset + count - 1;
+ start = bloc->logicalBlockNum + offset;
+ end = bloc->logicalBlockNum + offset + count - 1;
epos.offset = oepos.offset = sizeof(struct unallocSpaceEntry);
elen = 0;
@@ -483,7 +479,7 @@ static void udf_table_free_blocks(struct super_block *sb,
start += count;
count = 0;
}
- udf_write_aext(table, &oepos, eloc, elen, 1);
+ udf_write_aext(table, &oepos, &eloc, elen, 1);
} else if (eloc.logicalBlockNum == (end + 1)) {
if ((0x3FFFFFFF - elen) <
(count << sb->s_blocksize_bits)) {
@@ -502,7 +498,7 @@ static void udf_table_free_blocks(struct super_block *sb,
end -= count;
count = 0;
}
- udf_write_aext(table, &oepos, eloc, elen, 1);
+ udf_write_aext(table, &oepos, &eloc, elen, 1);
}
if (epos.bh != oepos.bh) {
@@ -532,8 +528,8 @@ static void udf_table_free_blocks(struct super_block *sb,
*/
int adsize;
- short_ad *sad = NULL;
- long_ad *lad = NULL;
+ struct short_ad *sad = NULL;
+ struct long_ad *lad = NULL;
struct allocExtDesc *aed;
eloc.logicalBlockNum = start;
@@ -541,9 +537,9 @@ static void udf_table_free_blocks(struct super_block *sb,
(count << sb->s_blocksize_bits);
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- adsize = sizeof(short_ad);
+ adsize = sizeof(struct short_ad);
else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
- adsize = sizeof(long_ad);
+ adsize = sizeof(struct long_ad);
else {
brelse(oepos.bh);
brelse(epos.bh);
@@ -563,7 +559,7 @@ static void udf_table_free_blocks(struct super_block *sb,
elen -= sb->s_blocksize;
epos.bh = udf_tread(sb,
- udf_get_lb_pblock(sb, epos.block, 0));
+ udf_get_lb_pblock(sb, &epos.block, 0));
if (!epos.bh) {
brelse(oepos.bh);
goto error_return;
@@ -601,15 +597,15 @@ static void udf_table_free_blocks(struct super_block *sb,
if (sbi->s_udfrev >= 0x0200)
udf_new_tag(epos.bh->b_data, TAG_IDENT_AED,
3, 1, epos.block.logicalBlockNum,
- sizeof(tag));
+ sizeof(struct tag));
else
udf_new_tag(epos.bh->b_data, TAG_IDENT_AED,
2, 1, epos.block.logicalBlockNum,
- sizeof(tag));
+ sizeof(struct tag));
switch (iinfo->i_alloc_type) {
case ICBTAG_FLAG_AD_SHORT:
- sad = (short_ad *)sptr;
+ sad = (struct short_ad *)sptr;
sad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS |
sb->s_blocksize);
@@ -617,7 +613,7 @@ static void udf_table_free_blocks(struct super_block *sb,
cpu_to_le32(epos.block.logicalBlockNum);
break;
case ICBTAG_FLAG_AD_LONG:
- lad = (long_ad *)sptr;
+ lad = (struct long_ad *)sptr;
lad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS |
sb->s_blocksize);
@@ -635,7 +631,7 @@ static void udf_table_free_blocks(struct super_block *sb,
/* It's possible that stealing the block emptied the extent */
if (elen) {
- udf_write_aext(table, &epos, eloc, elen, 1);
+ udf_write_aext(table, &epos, &eloc, elen, 1);
if (!epos.bh) {
iinfo->i_lenAlloc += adsize;
@@ -653,7 +649,6 @@ static void udf_table_free_blocks(struct super_block *sb,
brelse(oepos.bh);
error_return:
- sb->s_dirt = 1;
mutex_unlock(&sbi->s_alloc_mutex);
return;
}
@@ -666,7 +661,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
struct udf_sb_info *sbi = UDF_SB(sb);
int alloc_count = 0;
uint32_t elen, adsize;
- kernel_lb_addr eloc;
+ struct kernel_lb_addr eloc;
struct extent_position epos;
int8_t etype = -1;
struct udf_inode_info *iinfo;
@@ -677,9 +672,9 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
iinfo = UDF_I(table);
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- adsize = sizeof(short_ad);
+ adsize = sizeof(struct short_ad);
else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
- adsize = sizeof(long_ad);
+ adsize = sizeof(struct long_ad);
else
return 0;
@@ -707,7 +702,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
alloc_count = block_count;
eloc.logicalBlockNum += alloc_count;
elen -= (alloc_count << sb->s_blocksize_bits);
- udf_write_aext(table, &epos, eloc,
+ udf_write_aext(table, &epos, &eloc,
(etype << 30) | elen, 1);
} else
udf_delete_aext(table, epos, eloc,
@@ -718,10 +713,8 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
brelse(epos.bh);
- if (alloc_count && udf_add_free_space(sbi, partition, -alloc_count)) {
- mark_buffer_dirty(sbi->s_lvid_bh);
- sb->s_dirt = 1;
- }
+ if (alloc_count)
+ udf_add_free_space(sb, partition, -alloc_count);
mutex_unlock(&sbi->s_alloc_mutex);
return alloc_count;
}
@@ -735,7 +728,7 @@ static int udf_table_new_block(struct super_block *sb,
uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF;
uint32_t newblock = 0, adsize;
uint32_t elen, goal_elen = 0;
- kernel_lb_addr eloc, uninitialized_var(goal_eloc);
+ struct kernel_lb_addr eloc, uninitialized_var(goal_eloc);
struct extent_position epos, goal_epos;
int8_t etype;
struct udf_inode_info *iinfo = UDF_I(table);
@@ -743,9 +736,9 @@ static int udf_table_new_block(struct super_block *sb,
*err = -ENOSPC;
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- adsize = sizeof(short_ad);
+ adsize = sizeof(struct short_ad);
else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
- adsize = sizeof(long_ad);
+ adsize = sizeof(struct long_ad);
else
return newblock;
@@ -814,46 +807,37 @@ static int udf_table_new_block(struct super_block *sb,
}
if (goal_elen)
- udf_write_aext(table, &goal_epos, goal_eloc, goal_elen, 1);
+ udf_write_aext(table, &goal_epos, &goal_eloc, goal_elen, 1);
else
udf_delete_aext(table, goal_epos, goal_eloc, goal_elen);
brelse(goal_epos.bh);
- if (udf_add_free_space(sbi, partition, -1))
- mark_buffer_dirty(sbi->s_lvid_bh);
+ udf_add_free_space(sb, partition, -1);
- sb->s_dirt = 1;
mutex_unlock(&sbi->s_alloc_mutex);
*err = 0;
return newblock;
}
-inline void udf_free_blocks(struct super_block *sb,
- struct inode *inode,
- kernel_lb_addr bloc, uint32_t offset,
- uint32_t count)
+void udf_free_blocks(struct super_block *sb, struct inode *inode,
+ struct kernel_lb_addr *bloc, uint32_t offset,
+ uint32_t count)
{
- uint16_t partition = bloc.partitionReferenceNum;
+ uint16_t partition = bloc->partitionReferenceNum;
struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) {
- return udf_bitmap_free_blocks(sb, inode,
- map->s_uspace.s_bitmap,
- bloc, offset, count);
+ udf_bitmap_free_blocks(sb, inode, map->s_uspace.s_bitmap,
+ bloc, offset, count);
} else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) {
- return udf_table_free_blocks(sb, inode,
- map->s_uspace.s_table,
- bloc, offset, count);
+ udf_table_free_blocks(sb, inode, map->s_uspace.s_table,
+ bloc, offset, count);
} else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) {
- return udf_bitmap_free_blocks(sb, inode,
- map->s_fspace.s_bitmap,
- bloc, offset, count);
+ udf_bitmap_free_blocks(sb, inode, map->s_fspace.s_bitmap,
+ bloc, offset, count);
} else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) {
- return udf_table_free_blocks(sb, inode,
- map->s_fspace.s_table,
- bloc, offset, count);
- } else {
- return;
+ udf_table_free_blocks(sb, inode, map->s_fspace.s_table,
+ bloc, offset, count);
}
}
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
index 62dc270c69d..2efd4d5291b 100644
--- a/fs/udf/dir.c
+++ b/fs/udf/dir.c
@@ -51,7 +51,7 @@ static int do_udf_readdir(struct inode *dir, struct file *filp,
uint8_t lfi;
loff_t size = udf_ext0_offset(dir) + dir->i_size;
struct buffer_head *tmp, *bha[16];
- kernel_lb_addr eloc;
+ struct kernel_lb_addr eloc;
uint32_t elen;
sector_t offset;
int i, num, ret = 0;
@@ -80,13 +80,13 @@ static int do_udf_readdir(struct inode *dir, struct file *filp,
ret = -ENOENT;
goto out;
}
- block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
+ block = udf_get_lb_pblock(dir->i_sb, &eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- epos.offset -= sizeof(short_ad);
+ epos.offset -= sizeof(struct short_ad);
else if (iinfo->i_alloc_type ==
ICBTAG_FLAG_AD_LONG)
- epos.offset -= sizeof(long_ad);
+ epos.offset -= sizeof(struct long_ad);
} else {
offset = 0;
}
@@ -101,7 +101,7 @@ static int do_udf_readdir(struct inode *dir, struct file *filp,
if (i + offset > (elen >> dir->i_sb->s_blocksize_bits))
i = (elen >> dir->i_sb->s_blocksize_bits) - offset;
for (num = 0; i > 0; i--) {
- block = udf_get_lb_pblock(dir->i_sb, eloc, offset + i);
+ block = udf_get_lb_pblock(dir->i_sb, &eloc, offset + i);
tmp = udf_tgetblk(dir->i_sb, block);
if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
bha[num++] = tmp;
@@ -161,9 +161,9 @@ static int do_udf_readdir(struct inode *dir, struct file *filp,
memcpy(fname, "..", flen);
dt_type = DT_DIR;
} else {
- kernel_lb_addr tloc = lelb_to_cpu(cfi.icb.extLocation);
+ struct kernel_lb_addr tloc = lelb_to_cpu(cfi.icb.extLocation);
- iblock = udf_get_lb_pblock(dir->i_sb, tloc, 0);
+ iblock = udf_get_lb_pblock(dir->i_sb, &tloc, 0);
flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
dt_type = DT_UNKNOWN;
}
diff --git a/fs/udf/directory.c b/fs/udf/directory.c
index 2820f8fcf4c..1d2c570704c 100644
--- a/fs/udf/directory.c
+++ b/fs/udf/directory.c
@@ -20,7 +20,7 @@
#if 0
static uint8_t *udf_filead_read(struct inode *dir, uint8_t *tmpad,
- uint8_t ad_size, kernel_lb_addr fe_loc,
+ uint8_t ad_size, struct kernel_lb_addr fe_loc,
int *pos, int *offset, struct buffer_head **bh,
int *error)
{
@@ -75,7 +75,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
struct udf_fileident_bh *fibh,
struct fileIdentDesc *cfi,
struct extent_position *epos,
- kernel_lb_addr *eloc, uint32_t *elen,
+ struct kernel_lb_addr *eloc, uint32_t *elen,
sector_t *offset)
{
struct fileIdentDesc *fi;
@@ -111,7 +111,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
(EXT_RECORDED_ALLOCATED >> 30))
return NULL;
- block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
+ block = udf_get_lb_pblock(dir->i_sb, eloc, *offset);
(*offset)++;
@@ -131,7 +131,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
if (i + *offset > (*elen >> blocksize_bits))
i = (*elen >> blocksize_bits)-*offset;
for (num = 0; i > 0; i--) {
- block = udf_get_lb_pblock(dir->i_sb, *eloc,
+ block = udf_get_lb_pblock(dir->i_sb, eloc,
*offset + i);
tmp = udf_tgetblk(dir->i_sb, block);
if (tmp && !buffer_uptodate(tmp) &&
@@ -169,7 +169,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
(EXT_RECORDED_ALLOCATED >> 30))
return NULL;
- block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
+ block = udf_get_lb_pblock(dir->i_sb, eloc, *offset);
(*offset)++;
@@ -249,9 +249,9 @@ struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize, int *offset)
}
#if 0
-static extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset)
+static struct extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset)
{
- extent_ad *ext;
+ struct extent_ad *ext;
struct fileEntry *fe;
uint8_t *ptr;
@@ -274,54 +274,54 @@ static extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset)
if ((*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs)))
ptr += *offset;
- ext = (extent_ad *)ptr;
+ ext = (struct extent_ad *)ptr;
- *offset = *offset + sizeof(extent_ad);
+ *offset = *offset + sizeof(struct extent_ad);
return ext;
}
#endif
-short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset,
+struct short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset,
int inc)
{
- short_ad *sa;
+ struct short_ad *sa;
if ((!ptr) || (!offset)) {
printk(KERN_ERR "udf: udf_get_fileshortad() invalidparms\n");
return NULL;
}
- if ((*offset + sizeof(short_ad)) > maxoffset)
+ if ((*offset + sizeof(struct short_ad)) > maxoffset)
return NULL;
else {
- sa = (short_ad *)ptr;
+ sa = (struct short_ad *)ptr;
if (sa->extLength == 0)
return NULL;
}
if (inc)
- *offset += sizeof(short_ad);
+ *offset += sizeof(struct short_ad);
return sa;
}
-long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, uint32_t *offset, int inc)
+struct long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, uint32_t *offset, int inc)
{
- long_ad *la;
+ struct long_ad *la;
if ((!ptr) || (!offset)) {
printk(KERN_ERR "udf: udf_get_filelongad() invalidparms\n");
return NULL;
}
- if ((*offset + sizeof(long_ad)) > maxoffset)
+ if ((*offset + sizeof(struct long_ad)) > maxoffset)
return NULL;
else {
- la = (long_ad *)ptr;
+ la = (struct long_ad *)ptr;
if (la->extLength == 0)
return NULL;
}
if (inc)
- *offset += sizeof(long_ad);
+ *offset += sizeof(struct long_ad);
return la;
}
diff --git a/fs/udf/ecma_167.h b/fs/udf/ecma_167.h
index a0974df82b3..4792b771aa8 100644
--- a/fs/udf/ecma_167.h
+++ b/fs/udf/ecma_167.h
@@ -38,10 +38,10 @@
#define _ECMA_167_H 1
/* Character set specification (ECMA 167r3 1/7.2.1) */
-typedef struct {
+struct charspec {
uint8_t charSetType;
uint8_t charSetInfo[63];
-} __attribute__ ((packed)) charspec;
+} __attribute__ ((packed));
/* Character Set Type (ECMA 167r3 1/7.2.1.1) */
#define CHARSPEC_TYPE_CS0 0x00 /* (1/7.2.2) */
@@ -57,7 +57,7 @@ typedef struct {
typedef uint8_t dstring;
/* Timestamp (ECMA 167r3 1/7.3) */
-typedef struct {
+struct timestamp {
__le16 typeAndTimezone;
__le16 year;
uint8_t month;
@@ -68,7 +68,7 @@ typedef struct {
uint8_t centiseconds;
uint8_t hundredsOfMicroseconds;
uint8_t microseconds;
-} __attribute__ ((packed)) timestamp;
+} __attribute__ ((packed));
/* Type and Time Zone (ECMA 167r3 1/7.3.1) */
#define TIMESTAMP_TYPE_MASK 0xF000
@@ -78,11 +78,11 @@ typedef struct {
#define TIMESTAMP_TIMEZONE_MASK 0x0FFF
/* Entity identifier (ECMA 167r3 1/7.4) */
-typedef struct {
+struct regid {
uint8_t flags;
uint8_t ident[23];
uint8_t identSuffix[8];
-} __attribute__ ((packed)) regid;
+} __attribute__ ((packed));
/* Flags (ECMA 167r3 1/7.4.1) */
#define ENTITYID_FLAGS_DIRTY 0x00
@@ -126,38 +126,38 @@ struct terminatingExtendedAreaDesc {
/* Boot Descriptor (ECMA 167r3 2/9.4) */
struct bootDesc {
- uint8_t structType;
- uint8_t stdIdent[VSD_STD_ID_LEN];
- uint8_t structVersion;
- uint8_t reserved1;
- regid archType;
- regid bootIdent;
- __le32 bootExtLocation;
- __le32 bootExtLength;
- __le64 loadAddress;
- __le64 startAddress;
- timestamp descCreationDateAndTime;
- __le16 flags;
- uint8_t reserved2[32];
- uint8_t bootUse[1906];
+ uint8_t structType;
+ uint8_t stdIdent[VSD_STD_ID_LEN];
+ uint8_t structVersion;
+ uint8_t reserved1;
+ struct regid archType;
+ struct regid bootIdent;
+ __le32 bootExtLocation;
+ __le32 bootExtLength;
+ __le64 loadAddress;
+ __le64 startAddress;
+ struct timestamp descCreationDateAndTime;
+ __le16 flags;
+ uint8_t reserved2[32];
+ uint8_t bootUse[1906];
} __attribute__ ((packed));
/* Flags (ECMA 167r3 2/9.4.12) */
#define BOOT_FLAGS_ERASE 0x01
/* Extent Descriptor (ECMA 167r3 3/7.1) */
-typedef struct {
+struct extent_ad {
__le32 extLength;
__le32 extLocation;
-} __attribute__ ((packed)) extent_ad;
+} __attribute__ ((packed));
-typedef struct {
+struct kernel_extent_ad {
uint32_t extLength;
uint32_t extLocation;
-} kernel_extent_ad;
+};
/* Descriptor Tag (ECMA 167r3 3/7.2) */
-typedef struct {
+struct tag {
__le16 tagIdent;
__le16 descVersion;
uint8_t tagChecksum;
@@ -166,7 +166,7 @@ typedef struct {
__le16 descCRC;
__le16 descCRCLength;
__le32 tagLocation;
-} __attribute__ ((packed)) tag;
+} __attribute__ ((packed));
/* Tag Identifier (ECMA 167r3 3/7.2.1) */
#define TAG_IDENT_PVD 0x0001
@@ -190,28 +190,28 @@ struct NSRDesc {
/* Primary Volume Descriptor (ECMA 167r3 3/10.1) */
struct primaryVolDesc {
- tag descTag;
- __le32 volDescSeqNum;
- __le32 primaryVolDescNum;
- dstring volIdent[32];
- __le16 volSeqNum;
- __le16 maxVolSeqNum;
- __le16 interchangeLvl;
- __le16 maxInterchangeLvl;
- __le32 charSetList;
- __le32 maxCharSetList;
- dstring volSetIdent[128];
- charspec descCharSet;
- charspec explanatoryCharSet;
- extent_ad volAbstract;
- extent_ad volCopyright;
- regid appIdent;
- timestamp recordingDateAndTime;
- regid impIdent;
- uint8_t impUse[64];
- __le32 predecessorVolDescSeqLocation;
- __le16 flags;
- uint8_t reserved[22];
+ struct tag descTag;
+ __le32 volDescSeqNum;
+ __le32 primaryVolDescNum;
+ dstring volIdent[32];
+ __le16 volSeqNum;
+ __le16 maxVolSeqNum;
+ __le16 interchangeLvl;
+ __le16 maxInterchangeLvl;
+ __le32 charSetList;
+ __le32 maxCharSetList;
+ dstring volSetIdent[128];
+ struct charspec descCharSet;
+ struct charspec explanatoryCharSet;
+ struct extent_ad volAbstract;
+ struct extent_ad volCopyright;
+ struct regid appIdent;
+ struct timestamp recordingDateAndTime;
+ struct regid impIdent;
+ uint8_t impUse[64];
+ __le32 predecessorVolDescSeqLocation;
+ __le16 flags;
+ uint8_t reserved[22];
} __attribute__ ((packed));
/* Flags (ECMA 167r3 3/10.1.21) */
@@ -219,40 +219,40 @@ struct primaryVolDesc {
/* Anchor Volume Descriptor Pointer (ECMA 167r3 3/10.2) */
struct anchorVolDescPtr {
- tag descTag;
- extent_ad mainVolDescSeqExt;
- extent_ad reserveVolDescSeqExt;
- uint8_t reserved[480];
+ struct tag descTag;
+ struct extent_ad mainVolDescSeqExt;
+ struct extent_ad reserveVolDescSeqExt;
+ uint8_t reserved[480];
} __attribute__ ((packed));
/* Volume Descriptor Pointer (ECMA 167r3 3/10.3) */
struct volDescPtr {
- tag descTag;
- __le32 volDescSeqNum;
- extent_ad nextVolDescSeqExt;
- uint8_t reserved[484];
+ struct tag descTag;
+ __le32 volDescSeqNum;
+ struct extent_ad nextVolDescSeqExt;
+ uint8_t reserved[484];
} __attribute__ ((packed));
/* Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) */
struct impUseVolDesc {
- tag descTag;
+ struct tag descTag;
__le32 volDescSeqNum;
- regid impIdent;
+ struct regid impIdent;
uint8_t impUse[460];
} __attribute__ ((packed));
/* Partition Descriptor (ECMA 167r3 3/10.5) */
struct partitionDesc {
- tag descTag;
+ struct tag descTag;
__le32 volDescSeqNum;
__le16 partitionFlags;
__le16 partitionNumber;
- regid partitionContents;
+ struct regid partitionContents;
uint8_t partitionContentsUse[128];
__le32 accessType;
__le32 partitionStartingLocation;
__le32 partitionLength;
- regid impIdent;
+ struct regid impIdent;
uint8_t impUse[128];
uint8_t reserved[156];
} __attribute__ ((packed));
@@ -278,19 +278,19 @@ struct partitionDesc {
/* Logical Volume Descriptor (ECMA 167r3 3/10.6) */
struct logicalVolDesc {
- tag descTag;
- __le32 volDescSeqNum;
- charspec descCharSet;
- dstring logicalVolIdent[128];
- __le32 logicalBlockSize;
- regid domainIdent;
- uint8_t logicalVolContentsUse[16];
- __le32 mapTableLength;
- __le32 numPartitionMaps;
- regid impIdent;
- uint8_t impUse[128];
- extent_ad integritySeqExt;
- uint8_t partitionMaps[0];
+ struct tag descTag;
+ __le32 volDescSeqNum;
+ struct charspec descCharSet;
+ dstring logicalVolIdent[128];
+ __le32 logicalBlockSize;
+ struct regid domainIdent;
+ uint8_t logicalVolContentsUse[16];
+ __le32 mapTableLength;
+ __le32 numPartitionMaps;
+ struct regid impIdent;
+ uint8_t impUse[128];
+ struct extent_ad integritySeqExt;
+ uint8_t partitionMaps[0];
} __attribute__ ((packed));
/* Generic Partition Map (ECMA 167r3 3/10.7.1) */
@@ -322,30 +322,30 @@ struct genericPartitionMap2 {
/* Unallocated Space Descriptor (ECMA 167r3 3/10.8) */
struct unallocSpaceDesc {
- tag descTag;
- __le32 volDescSeqNum;
- __le32 numAllocDescs;
- extent_ad allocDescs[0];
+ struct tag descTag;
+ __le32 volDescSeqNum;
+ __le32 numAllocDescs;
+ struct extent_ad allocDescs[0];
} __attribute__ ((packed));
/* Terminating Descriptor (ECMA 167r3 3/10.9) */
struct terminatingDesc {
- tag descTag;
+ struct tag descTag;
uint8_t reserved[496];
} __attribute__ ((packed));
/* Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */
struct logicalVolIntegrityDesc {
- tag descTag;
- timestamp recordingDateAndTime;
- __le32 integrityType;
- extent_ad nextIntegrityExt;
- uint8_t logicalVolContentsUse[32];
- __le32 numOfPartitions;
- __le32 lengthOfImpUse;
- __le32 freeSpaceTable[0];
- __le32 sizeTable[0];
- uint8_t impUse[0];
+ struct tag descTag;
+ struct timestamp recordingDateAndTime;
+ __le32 integrityType;
+ struct extent_ad nextIntegrityExt;
+ uint8_t logicalVolContentsUse[32];
+ __le32 numOfPartitions;
+ __le32 lengthOfImpUse;
+ __le32 freeSpaceTable[0];
+ __le32 sizeTable[0];
+ uint8_t impUse[0];
} __attribute__ ((packed));
/* Integrity Type (ECMA 167r3 3/10.10.3) */
@@ -353,50 +353,50 @@ struct logicalVolIntegrityDesc {
#define LVID_INTEGRITY_TYPE_CLOSE 0x00000001
/* Recorded Address (ECMA 167r3 4/7.1) */
-typedef struct {
+struct lb_addr {
__le32 logicalBlockNum;
__le16 partitionReferenceNum;
-} __attribute__ ((packed)) lb_addr;
+} __attribute__ ((packed));
/* ... and its in-core analog */
-typedef struct {
+struct kernel_lb_addr {
uint32_t logicalBlockNum;
uint16_t partitionReferenceNum;
-} kernel_lb_addr;
+};
/* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
-typedef struct {
+struct short_ad {
__le32 extLength;
__le32 extPosition;
-} __attribute__ ((packed)) short_ad;
+} __attribute__ ((packed));
/* Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */
-typedef struct {
+struct long_ad {
__le32 extLength;
- lb_addr extLocation;
+ struct lb_addr extLocation;
uint8_t impUse[6];
-} __attribute__ ((packed)) long_ad;
+} __attribute__ ((packed));
-typedef struct {
- uint32_t extLength;
- kernel_lb_addr extLocation;
- uint8_t impUse[6];
-} kernel_long_ad;
+struct kernel_long_ad {
+ uint32_t extLength;
+ struct kernel_lb_addr extLocation;
+ uint8_t impUse[6];
+};
/* Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */
-typedef struct {
+struct ext_ad {
__le32 extLength;
__le32 recordedLength;
__le32 informationLength;
- lb_addr extLocation;
-} __attribute__ ((packed)) ext_ad;
+ struct lb_addr extLocation;
+} __attribute__ ((packed));
-typedef struct {
- uint32_t extLength;
- uint32_t recordedLength;
- uint32_t informationLength;
- kernel_lb_addr extLocation;
-} kernel_ext_ad;
+struct kernel_ext_ad {
+ uint32_t extLength;
+ uint32_t recordedLength;
+ uint32_t informationLength;
+ struct kernel_lb_addr extLocation;
+};
/* Descriptor Tag (ECMA 167r3 4/7.2 - See 3/7.2) */
@@ -415,44 +415,44 @@ typedef struct {
/* File Set Descriptor (ECMA 167r3 4/14.1) */
struct fileSetDesc {
- tag descTag;
- timestamp recordingDateAndTime;
- __le16 interchangeLvl;
- __le16 maxInterchangeLvl;
- __le32 charSetList;
- __le32 maxCharSetList;
- __le32 fileSetNum;
- __le32 fileSetDescNum;
- charspec logicalVolIdentCharSet;
- dstring logicalVolIdent[128];
- charspec fileSetCharSet;
- dstring fileSetIdent[32];
- dstring copyrightFileIdent[32];
- dstring abstractFileIdent[32];
- long_ad rootDirectoryICB;
- regid domainIdent;
- long_ad nextExt;
- long_ad streamDirectoryICB;
- uint8_t reserved[32];
+ struct tag descTag;
+ struct timestamp recordingDateAndTime;
+ __le16 interchangeLvl;
+ __le16 maxInterchangeLvl;
+ __le32 charSetList;
+ __le32 maxCharSetList;
+ __le32 fileSetNum;
+ __le32 fileSetDescNum;
+ struct charspec logicalVolIdentCharSet;
+ dstring logicalVolIdent[128];
+ struct charspec fileSetCharSet;
+ dstring fileSetIdent[32];
+ dstring copyrightFileIdent[32];
+ dstring abstractFileIdent[32];
+ struct long_ad rootDirectoryICB;
+ struct regid domainIdent;
+ struct long_ad nextExt;
+ struct long_ad streamDirectoryICB;
+ uint8_t reserved[32];
} __attribute__ ((packed));
/* Partition Header Descriptor (ECMA 167r3 4/14.3) */
struct partitionHeaderDesc {
- short_ad unallocSpaceTable;
- short_ad unallocSpaceBitmap;
- short_ad partitionIntegrityTable;
- short_ad freedSpaceTable;
- short_ad freedSpaceBitmap;
+ struct short_ad unallocSpaceTable;
+ struct short_ad unallocSpaceBitmap;
+ struct short_ad partitionIntegrityTable;
+ struct short_ad freedSpaceTable;
+ struct short_ad freedSpaceBitmap;
uint8_t reserved[88];
} __attribute__ ((packed));
/* File Identifier Descriptor (ECMA 167r3 4/14.4) */
struct fileIdentDesc {
- tag descTag;
+ struct tag descTag;
__le16 fileVersionNum;
uint8_t fileCharacteristics;
uint8_t lengthFileIdent;
- long_ad icb;
+ struct long_ad icb;
__le16 lengthOfImpUse;
uint8_t impUse[0];
uint8_t fileIdent[0];
@@ -468,22 +468,22 @@ struct fileIdentDesc {
/* Allocation Ext Descriptor (ECMA 167r3 4/14.5) */
struct allocExtDesc {
- tag descTag;
+ struct tag descTag;
__le32 previousAllocExtLocation;
__le32 lengthAllocDescs;
} __attribute__ ((packed));
/* ICB Tag (ECMA 167r3 4/14.6) */
-typedef struct {
+struct icbtag {
__le32 priorRecordedNumDirectEntries;
__le16 strategyType;
__le16 strategyParameter;
__le16 numEntries;
uint8_t reserved;
uint8_t fileType;
- lb_addr parentICBLocation;
+ struct lb_addr parentICBLocation;
__le16 flags;
-} __attribute__ ((packed)) icbtag;
+} __attribute__ ((packed));
/* Strategy Type (ECMA 167r3 4/14.6.2) */
#define ICBTAG_STRATEGY_TYPE_UNDEF 0x0000
@@ -528,41 +528,41 @@ typedef struct {
/* Indirect Entry (ECMA 167r3 4/14.7) */
struct indirectEntry {
- tag descTag;
- icbtag icbTag;
- long_ad indirectICB;
+ struct tag descTag;
+ struct icbtag icbTag;
+ struct long_ad indirectICB;
} __attribute__ ((packed));
/* Terminal Entry (ECMA 167r3 4/14.8) */
struct terminalEntry {
- tag descTag;
- icbtag icbTag;
+ struct tag descTag;
+ struct icbtag icbTag;
} __attribute__ ((packed));
/* File Entry (ECMA 167r3 4/14.9) */
struct fileEntry {
- tag descTag;
- icbtag icbTag;
- __le32 uid;
- __le32 gid;
- __le32 permissions;
- __le16 fileLinkCount;
- uint8_t recordFormat;
- uint8_t recordDisplayAttr;
- __le32 recordLength;
- __le64 informationLength;
- __le64 logicalBlocksRecorded;
- timestamp accessTime;
- timestamp modificationTime;
- timestamp attrTime;
- __le32 checkpoint;
- long_ad extendedAttrICB;
- regid impIdent;
- __le64 uniqueID;
- __le32 lengthExtendedAttr;
- __le32 lengthAllocDescs;
- uint8_t extendedAttr[0];
- uint8_t allocDescs[0];
+ struct tag descTag;
+ struct icbtag icbTag;
+ __le32 uid;
+ __le32 gid;
+ __le32 permissions;
+ __le16 fileLinkCount;
+ uint8_t recordFormat;
+ uint8_t recordDisplayAttr;
+ __le32 recordLength;
+ __le64 informationLength;
+ __le64 logicalBlocksRecorded;
+ struct timestamp accessTime;
+ struct timestamp modificationTime;
+ struct timestamp attrTime;
+ __le32 checkpoint;
+ struct long_ad extendedAttrICB;
+ struct regid impIdent;
+ __le64 uniqueID;
+ __le32 lengthExtendedAttr;
+ __le32 lengthAllocDescs;
+ uint8_t extendedAttr[0];
+ uint8_t allocDescs[0];
} __attribute__ ((packed));
/* Permissions (ECMA 167r3 4/14.9.5) */
@@ -604,7 +604,7 @@ struct fileEntry {
/* Extended Attribute Header Descriptor (ECMA 167r3 4/14.10.1) */
struct extendedAttrHeaderDesc {
- tag descTag;
+ struct tag descTag;
__le32 impAttrLocation;
__le32 appAttrLocation;
} __attribute__ ((packed));
@@ -687,7 +687,7 @@ struct impUseExtAttr {
uint8_t reserved[3];
__le32 attrLength;
__le32 impUseLength;
- regid impIdent;
+ struct regid impIdent;
uint8_t impUse[0];
} __attribute__ ((packed));
@@ -698,7 +698,7 @@ struct appUseExtAttr {
uint8_t reserved[3];
__le32 attrLength;
__le32 appUseLength;
- regid appIdent;
+ struct regid appIdent;
uint8_t appUse[0];
} __attribute__ ((packed));
@@ -712,15 +712,15 @@ struct appUseExtAttr {
/* Unallocated Space Entry (ECMA 167r3 4/14.11) */
struct unallocSpaceEntry {
- tag descTag;
- icbtag icbTag;
+ struct tag descTag;
+ struct icbtag icbTag;
__le32 lengthAllocDescs;
uint8_t allocDescs[0];
} __attribute__ ((packed));
/* Space Bitmap Descriptor (ECMA 167r3 4/14.12) */
struct spaceBitmapDesc {
- tag descTag;
+ struct tag descTag;
__le32 numOfBits;
__le32 numOfBytes;
uint8_t bitmap[0];
@@ -728,13 +728,13 @@ struct spaceBitmapDesc {
/* Partition Integrity Entry (ECMA 167r3 4/14.13) */
struct partitionIntegrityEntry {
- tag descTag;
- icbtag icbTag;
- timestamp recordingDateAndTime;
- uint8_t integrityType;
- uint8_t reserved[175];
- regid impIdent;
- uint8_t impUse[256];
+ struct tag descTag;
+ struct icbtag icbTag;
+ struct timestamp recordingDateAndTime;
+ uint8_t integrityType;
+ uint8_t reserved[175];
+ struct regid impIdent;
+ uint8_t impUse[256];
} __attribute__ ((packed));
/* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
@@ -765,32 +765,32 @@ struct pathComponent {
/* File Entry (ECMA 167r3 4/14.17) */
struct extendedFileEntry {
- tag descTag;
- icbtag icbTag;
- __le32 uid;
- __le32 gid;
- __le32 permissions;
- __le16 fileLinkCount;
- uint8_t recordFormat;
- uint8_t recordDisplayAttr;
- __le32 recordLength;
- __le64 informationLength;
- __le64 objectSize;
- __le64 logicalBlocksRecorded;
- timestamp accessTime;
- timestamp modificationTime;
- timestamp createTime;
- timestamp attrTime;
- __le32 checkpoint;
- __le32 reserved;
- long_ad extendedAttrICB;
- long_ad streamDirectoryICB;
- regid impIdent;
- __le64 uniqueID;
- __le32 lengthExtendedAttr;
- __le32 lengthAllocDescs;
- uint8_t extendedAttr[0];
- uint8_t allocDescs[0];
+ struct tag descTag;
+ struct icbtag icbTag;
+ __le32 uid;
+ __le32 gid;
+ __le32 permissions;
+ __le16 fileLinkCount;
+ uint8_t recordFormat;
+ uint8_t recordDisplayAttr;
+ __le32 recordLength;
+ __le64 informationLength;
+ __le64 objectSize;
+ __le64 logicalBlocksRecorded;
+ struct timestamp accessTime;
+ struct timestamp modificationTime;
+ struct timestamp createTime;
+ struct timestamp attrTime;
+ __le32 checkpoint;
+ __le32 reserved;
+ struct long_ad extendedAttrICB;
+ struct long_ad streamDirectoryICB;
+ struct regid impIdent;
+ __le64 uniqueID;
+ __le32 lengthExtendedAttr;
+ __le32 lengthAllocDescs;
+ uint8_t extendedAttr[0];
+ uint8_t allocDescs[0];
} __attribute__ ((packed));
#endif /* _ECMA_167_H */
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index 47dbe5613f9..c10fa39f97e 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -49,12 +49,11 @@ void udf_free_inode(struct inode *inode)
le32_add_cpu(&lvidiu->numDirs, -1);
else
le32_add_cpu(&lvidiu->numFiles, -1);
-
- mark_buffer_dirty(sbi->s_lvid_bh);
+ udf_updated_lvid(sb);
}
mutex_unlock(&sbi->s_alloc_mutex);
- udf_free_blocks(sb, NULL, UDF_I(inode)->i_location, 0, 1);
+ udf_free_blocks(sb, NULL, &UDF_I(inode)->i_location, 0, 1);
}
struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
@@ -122,7 +121,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
if (!(++uniqueID & 0x00000000FFFFFFFFUL))
uniqueID += 16;
lvhd->uniqueID = cpu_to_le64(uniqueID);
- mark_buffer_dirty(sbi->s_lvid_bh);
+ udf_updated_lvid(sb);
}
mutex_unlock(&sbi->s_alloc_mutex);
inode->i_mode = mode;
@@ -138,7 +137,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
iinfo->i_location.logicalBlockNum = block;
iinfo->i_location.partitionReferenceNum =
dinfo->i_location.partitionReferenceNum;
- inode->i_ino = udf_get_lb_pblock(sb, iinfo->i_location, 0);
+ inode->i_ino = udf_get_lb_pblock(sb, &iinfo->i_location, 0);
inode->i_blocks = 0;
iinfo->i_lenEAttr = 0;
iinfo->i_lenAlloc = 0;
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 30ebde490f7..e7533f78563 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -55,15 +55,15 @@ static int udf_alloc_i_data(struct inode *inode, size_t size);
static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
sector_t *, int *);
static int8_t udf_insert_aext(struct inode *, struct extent_position,
- kernel_lb_addr, uint32_t);
+ struct kernel_lb_addr, uint32_t);
static void udf_split_extents(struct inode *, int *, int, int,
- kernel_long_ad[EXTENT_MERGE_SIZE], int *);
+ struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
static void udf_prealloc_extents(struct inode *, int, int,
- kernel_long_ad[EXTENT_MERGE_SIZE], int *);
+ struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
static void udf_merge_extents(struct inode *,
- kernel_long_ad[EXTENT_MERGE_SIZE], int *);
+ struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
static void udf_update_extents(struct inode *,
- kernel_long_ad[EXTENT_MERGE_SIZE], int, int,
+ struct kernel_long_ad[EXTENT_MERGE_SIZE], int, int,
struct extent_position *);
static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
@@ -200,7 +200,7 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
{
int newblock;
struct buffer_head *dbh = NULL;
- kernel_lb_addr eloc;
+ struct kernel_lb_addr eloc;
uint32_t elen;
uint8_t alloctype;
struct extent_position epos;
@@ -281,7 +281,7 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
epos.bh = NULL;
epos.block = iinfo->i_location;
epos.offset = udf_file_entry_alloc_offset(inode);
- udf_add_aext(inode, &epos, eloc, elen, 0);
+ udf_add_aext(inode, &epos, &eloc, elen, 0);
/* UniqueID stuff */
brelse(epos.bh);
@@ -359,12 +359,12 @@ static struct buffer_head *udf_getblk(struct inode *inode, long block,
/* Extend the file by 'blocks' blocks, return the number of extents added */
int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
- kernel_long_ad *last_ext, sector_t blocks)
+ struct kernel_long_ad *last_ext, sector_t blocks)
{
sector_t add;
int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
struct super_block *sb = inode->i_sb;
- kernel_lb_addr prealloc_loc = {};
+ struct kernel_lb_addr prealloc_loc = {};
int prealloc_len = 0;
struct udf_inode_info *iinfo;
@@ -411,11 +411,11 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
}
if (fake) {
- udf_add_aext(inode, last_pos, last_ext->extLocation,
+ udf_add_aext(inode, last_pos, &last_ext->extLocation,
last_ext->extLength, 1);
count++;
} else
- udf_write_aext(inode, last_pos, last_ext->extLocation,
+ udf_write_aext(inode, last_pos, &last_ext->extLocation,
last_ext->extLength, 1);
/* Managed to do everything necessary? */
@@ -432,7 +432,7 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
/* Create enough extents to cover the whole hole */
while (blocks > add) {
blocks -= add;
- if (udf_add_aext(inode, last_pos, last_ext->extLocation,
+ if (udf_add_aext(inode, last_pos, &last_ext->extLocation,
last_ext->extLength, 1) == -1)
return -1;
count++;
@@ -440,7 +440,7 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
if (blocks) {
last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
(blocks << sb->s_blocksize_bits);
- if (udf_add_aext(inode, last_pos, last_ext->extLocation,
+ if (udf_add_aext(inode, last_pos, &last_ext->extLocation,
last_ext->extLength, 1) == -1)
return -1;
count++;
@@ -449,7 +449,7 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
out:
/* Do we have some preallocated blocks saved? */
if (prealloc_len) {
- if (udf_add_aext(inode, last_pos, prealloc_loc,
+ if (udf_add_aext(inode, last_pos, &prealloc_loc,
prealloc_len, 1) == -1)
return -1;
last_ext->extLocation = prealloc_loc;
@@ -459,9 +459,9 @@ out:
/* last_pos should point to the last written extent... */
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- last_pos->offset -= sizeof(short_ad);
+ last_pos->offset -= sizeof(struct short_ad);
else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
- last_pos->offset -= sizeof(long_ad);
+ last_pos->offset -= sizeof(struct long_ad);
else
return -1;
@@ -473,11 +473,11 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
{
static sector_t last_block;
struct buffer_head *result = NULL;
- kernel_long_ad laarr[EXTENT_MERGE_SIZE];
+ struct kernel_long_ad laarr[EXTENT_MERGE_SIZE];
struct extent_position prev_epos, cur_epos, next_epos;
int count = 0, startnum = 0, endnum = 0;
uint32_t elen = 0, tmpelen;
- kernel_lb_addr eloc, tmpeloc;
+ struct kernel_lb_addr eloc, tmpeloc;
int c = 1;
loff_t lbcount = 0, b_off = 0;
uint32_t newblocknum, newblock;
@@ -550,12 +550,12 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
elen = EXT_RECORDED_ALLOCATED |
((elen + inode->i_sb->s_blocksize - 1) &
~(inode->i_sb->s_blocksize - 1));
- etype = udf_write_aext(inode, &cur_epos, eloc, elen, 1);
+ etype = udf_write_aext(inode, &cur_epos, &eloc, elen, 1);
}
brelse(prev_epos.bh);
brelse(cur_epos.bh);
brelse(next_epos.bh);
- newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset);
+ newblock = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
*phys = newblock;
return NULL;
}
@@ -572,7 +572,7 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
} else {
/* Create a fake extent when there's not one */
memset(&laarr[0].extLocation, 0x00,
- sizeof(kernel_lb_addr));
+ sizeof(struct kernel_lb_addr));
laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
/* Will udf_extend_file() create real extent from
a fake one? */
@@ -602,7 +602,7 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
inode->i_sb->s_blocksize;
memset(&laarr[c].extLocation, 0x00,
- sizeof(kernel_lb_addr));
+ sizeof(struct kernel_lb_addr));
count++;
endnum++;
}
@@ -699,7 +699,7 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
static void udf_split_extents(struct inode *inode, int *c, int offset,
int newblocknum,
- kernel_long_ad laarr[EXTENT_MERGE_SIZE],
+ struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
int *endnum)
{
unsigned long blocksize = inode->i_sb->s_blocksize;
@@ -726,7 +726,7 @@ static void udf_split_extents(struct inode *inode, int *c, int offset,
if (offset) {
if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
udf_free_blocks(inode->i_sb, inode,
- laarr[curr].extLocation,
+ &laarr[curr].extLocation,
0, offset);
laarr[curr].extLength =
EXT_NOT_RECORDED_NOT_ALLOCATED |
@@ -763,7 +763,7 @@ static void udf_split_extents(struct inode *inode, int *c, int offset,
}
static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
- kernel_long_ad laarr[EXTENT_MERGE_SIZE],
+ struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
int *endnum)
{
int start, length = 0, currlength = 0, i;
@@ -817,7 +817,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
inode->i_sb->s_blocksize_bits);
else {
memmove(&laarr[c + 2], &laarr[c + 1],
- sizeof(long_ad) * (*endnum - (c + 1)));
+ sizeof(struct long_ad) * (*endnum - (c + 1)));
(*endnum)++;
laarr[c + 1].extLocation.logicalBlockNum = next;
laarr[c + 1].extLocation.partitionReferenceNum =
@@ -846,7 +846,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
if (*endnum > (i + 1))
memmove(&laarr[i],
&laarr[i + 1],
- sizeof(long_ad) *
+ sizeof(struct long_ad) *
(*endnum - (i + 1)));
i--;
(*endnum)--;
@@ -859,7 +859,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
}
static void udf_merge_extents(struct inode *inode,
- kernel_long_ad laarr[EXTENT_MERGE_SIZE],
+ struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
int *endnum)
{
int i;
@@ -867,8 +867,8 @@ static void udf_merge_extents(struct inode *inode,
unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
for (i = 0; i < (*endnum - 1); i++) {
- kernel_long_ad *li /*l[i]*/ = &laarr[i];
- kernel_long_ad *lip1 /*l[i plus 1]*/ = &laarr[i + 1];
+ struct kernel_long_ad *li /*l[i]*/ = &laarr[i];
+ struct kernel_long_ad *lip1 /*l[i plus 1]*/ = &laarr[i + 1];
if (((li->extLength >> 30) == (lip1->extLength >> 30)) &&
(((li->extLength >> 30) ==
@@ -902,7 +902,7 @@ static void udf_merge_extents(struct inode *inode,
blocksize - 1) & ~(blocksize - 1));
if (*endnum > (i + 2))
memmove(&laarr[i + 1], &laarr[i + 2],
- sizeof(long_ad) *
+ sizeof(struct long_ad) *
(*endnum - (i + 2)));
i--;
(*endnum)--;
@@ -911,7 +911,7 @@ static void udf_merge_extents(struct inode *inode,
(EXT_NOT_RECORDED_ALLOCATED >> 30)) &&
((lip1->extLength >> 30) ==
(EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) {
- udf_free_blocks(inode->i_sb, inode, li->extLocation, 0,
+ udf_free_blocks(inode->i_sb, inode, &li->extLocation, 0,
((li->extLength &
UDF_EXTENT_LENGTH_MASK) +
blocksize - 1) >> blocksize_bits);
@@ -937,7 +937,7 @@ static void udf_merge_extents(struct inode *inode,
blocksize - 1) & ~(blocksize - 1));
if (*endnum > (i + 2))
memmove(&laarr[i + 1], &laarr[i + 2],
- sizeof(long_ad) *
+ sizeof(struct long_ad) *
(*endnum - (i + 2)));
i--;
(*endnum)--;
@@ -945,7 +945,7 @@ static void udf_merge_extents(struct inode *inode,
} else if ((li->extLength >> 30) ==
(EXT_NOT_RECORDED_ALLOCATED >> 30)) {
udf_free_blocks(inode->i_sb, inode,
- li->extLocation, 0,
+ &li->extLocation, 0,
((li->extLength &
UDF_EXTENT_LENGTH_MASK) +
blocksize - 1) >> blocksize_bits);
@@ -959,12 +959,12 @@ static void udf_merge_extents(struct inode *inode,
}
static void udf_update_extents(struct inode *inode,
- kernel_long_ad laarr[EXTENT_MERGE_SIZE],
+ struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
int startnum, int endnum,
struct extent_position *epos)
{
int start = 0, i;
- kernel_lb_addr tmploc;
+ struct kernel_lb_addr tmploc;
uint32_t tmplen;
if (startnum > endnum) {
@@ -983,7 +983,7 @@ static void udf_update_extents(struct inode *inode,
for (i = start; i < endnum; i++) {
udf_next_aext(inode, epos, &tmploc, &tmplen, 0);
- udf_write_aext(inode, epos, laarr[i].extLocation,
+ udf_write_aext(inode, epos, &laarr[i].extLocation,
laarr[i].extLength, 1);
}
}
@@ -1076,7 +1076,7 @@ static void __udf_read_inode(struct inode *inode)
* i_nlink = 1
* i_op = NULL;
*/
- bh = udf_read_ptagged(inode->i_sb, iinfo->i_location, 0, &ident);
+ bh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 0, &ident);
if (!bh) {
printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n",
inode->i_ino);
@@ -1098,24 +1098,24 @@ static void __udf_read_inode(struct inode *inode)
if (fe->icbTag.strategyType == cpu_to_le16(4096)) {
struct buffer_head *ibh;
- ibh = udf_read_ptagged(inode->i_sb, iinfo->i_location, 1,
+ ibh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 1,
&ident);
if (ident == TAG_IDENT_IE && ibh) {
struct buffer_head *nbh = NULL;
- kernel_lb_addr loc;
+ struct kernel_lb_addr loc;
struct indirectEntry *ie;
ie = (struct indirectEntry *)ibh->b_data;
loc = lelb_to_cpu(ie->indirectICB.extLocation);
if (ie->indirectICB.extLength &&
- (nbh = udf_read_ptagged(inode->i_sb, loc, 0,
+ (nbh = udf_read_ptagged(inode->i_sb, &loc, 0,
&ident))) {
if (ident == TAG_IDENT_FE ||
ident == TAG_IDENT_EFE) {
memcpy(&iinfo->i_location,
&loc,
- sizeof(kernel_lb_addr));
+ sizeof(struct kernel_lb_addr));
brelse(bh);
brelse(ibh);
brelse(nbh);
@@ -1222,8 +1222,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
inode->i_size = le64_to_cpu(fe->informationLength);
iinfo->i_lenExtents = inode->i_size;
- inode->i_mode = udf_convert_permissions(fe);
- inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;
+ if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY &&
+ sbi->s_fmode != UDF_INVALID_MODE)
+ inode->i_mode = sbi->s_fmode;
+ else if (fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY &&
+ sbi->s_dmode != UDF_INVALID_MODE)
+ inode->i_mode = sbi->s_dmode;
+ else
+ inode->i_mode = udf_convert_permissions(fe);
+ inode->i_mode &= ~sbi->s_umask;
if (iinfo->i_efe == 0) {
inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
@@ -1396,7 +1403,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
bh = udf_tread(inode->i_sb,
udf_get_lb_pblock(inode->i_sb,
- iinfo->i_location, 0));
+ &iinfo->i_location, 0));
if (!bh) {
udf_debug("bread failure\n");
return -EIO;
@@ -1416,13 +1423,13 @@ static int udf_update_inode(struct inode *inode, int do_sync)
iinfo->i_ext.i_data, inode->i_sb->s_blocksize -
sizeof(struct unallocSpaceEntry));
crclen = sizeof(struct unallocSpaceEntry) +
- iinfo->i_lenAlloc - sizeof(tag);
+ iinfo->i_lenAlloc - sizeof(struct tag);
use->descTag.tagLocation = cpu_to_le32(
iinfo->i_location.
logicalBlockNum);
use->descTag.descCRCLength = cpu_to_le16(crclen);
use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use +
- sizeof(tag),
+ sizeof(struct tag),
crclen));
use->descTag.tagChecksum = udf_tag_checksum(&use->descTag);
@@ -1459,23 +1466,23 @@ static int udf_update_inode(struct inode *inode, int do_sync)
fe->informationLength = cpu_to_le64(inode->i_size);
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
- regid *eid;
+ struct regid *eid;
struct deviceSpec *dsea =
(struct deviceSpec *)udf_get_extendedattr(inode, 12, 1);
if (!dsea) {
dsea = (struct deviceSpec *)
udf_add_extendedattr(inode,
sizeof(struct deviceSpec) +
- sizeof(regid), 12, 0x3);
+ sizeof(struct regid), 12, 0x3);
dsea->attrType = cpu_to_le32(12);
dsea->attrSubtype = 1;
dsea->attrLength = cpu_to_le32(
sizeof(struct deviceSpec) +
- sizeof(regid));
- dsea->impUseLength = cpu_to_le32(sizeof(regid));
+ sizeof(struct regid));
+ dsea->impUseLength = cpu_to_le32(sizeof(struct regid));
}
- eid = (regid *)dsea->impUse;
- memset(eid, 0, sizeof(regid));
+ eid = (struct regid *)dsea->impUse;
+ memset(eid, 0, sizeof(struct regid));
strcpy(eid->ident, UDF_ID_DEVELOPER);
eid->identSuffix[0] = UDF_OS_CLASS_UNIX;
eid->identSuffix[1] = UDF_OS_ID_LINUX;
@@ -1494,7 +1501,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime);
udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime);
udf_time_to_disk_stamp(&fe->attrTime, inode->i_ctime);
- memset(&(fe->impIdent), 0, sizeof(regid));
+ memset(&(fe->impIdent), 0, sizeof(struct regid));
strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
@@ -1533,7 +1540,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
udf_time_to_disk_stamp(&efe->createTime, iinfo->i_crtime);
udf_time_to_disk_stamp(&efe->attrTime, inode->i_ctime);
- memset(&(efe->impIdent), 0, sizeof(regid));
+ memset(&(efe->impIdent), 0, sizeof(struct regid));
strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
@@ -1584,9 +1591,9 @@ static int udf_update_inode(struct inode *inode, int do_sync)
fe->descTag.tagLocation = cpu_to_le32(
iinfo->i_location.logicalBlockNum);
crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc -
- sizeof(tag);
+ sizeof(struct tag);
fe->descTag.descCRCLength = cpu_to_le16(crclen);
- fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(tag),
+ fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(struct tag),
crclen));
fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag);
@@ -1606,7 +1613,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
return err;
}
-struct inode *udf_iget(struct super_block *sb, kernel_lb_addr ino)
+struct inode *udf_iget(struct super_block *sb, struct kernel_lb_addr *ino)
{
unsigned long block = udf_get_lb_pblock(sb, ino, 0);
struct inode *inode = iget_locked(sb, block);
@@ -1615,7 +1622,7 @@ struct inode *udf_iget(struct super_block *sb, kernel_lb_addr ino)
return NULL;
if (inode->i_state & I_NEW) {
- memcpy(&UDF_I(inode)->i_location, &ino, sizeof(kernel_lb_addr));
+ memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr));
__udf_read_inode(inode);
unlock_new_inode(inode);
}
@@ -1623,10 +1630,10 @@ struct inode *udf_iget(struct super_block *sb, kernel_lb_addr ino)
if (is_bad_inode(inode))
goto out_iput;
- if (ino.logicalBlockNum >= UDF_SB(sb)->
- s_partmaps[ino.partitionReferenceNum].s_partition_len) {
+ if (ino->logicalBlockNum >= UDF_SB(sb)->
+ s_partmaps[ino->partitionReferenceNum].s_partition_len) {
udf_debug("block=%d, partition=%d out of range\n",
- ino.logicalBlockNum, ino.partitionReferenceNum);
+ ino->logicalBlockNum, ino->partitionReferenceNum);
make_bad_inode(inode);
goto out_iput;
}
@@ -1639,11 +1646,11 @@ struct inode *udf_iget(struct super_block *sb, kernel_lb_addr ino)
}
int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
- kernel_lb_addr eloc, uint32_t elen, int inc)
+ struct kernel_lb_addr *eloc, uint32_t elen, int inc)
{
int adsize;
- short_ad *sad = NULL;
- long_ad *lad = NULL;
+ struct short_ad *sad = NULL;
+ struct long_ad *lad = NULL;
struct allocExtDesc *aed;
int8_t etype;
uint8_t *ptr;
@@ -1657,9 +1664,9 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
ptr = epos->bh->b_data + epos->offset;
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- adsize = sizeof(short_ad);
+ adsize = sizeof(struct short_ad);
else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
- adsize = sizeof(long_ad);
+ adsize = sizeof(struct long_ad);
else
return -1;
@@ -1667,7 +1674,7 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
char *sptr, *dptr;
struct buffer_head *nbh;
int err, loffset;
- kernel_lb_addr obloc = epos->block;
+ struct kernel_lb_addr obloc = epos->block;
epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL,
obloc.partitionReferenceNum,
@@ -1675,7 +1682,7 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
if (!epos->block.logicalBlockNum)
return -1;
nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
- epos->block,
+ &epos->block,
0));
if (!nbh)
return -1;
@@ -1712,20 +1719,20 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
}
if (UDF_SB(inode->i_sb)->s_udfrev >= 0x0200)
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
- epos->block.logicalBlockNum, sizeof(tag));
+ epos->block.logicalBlockNum, sizeof(struct tag));
else
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
- epos->block.logicalBlockNum, sizeof(tag));
+ epos->block.logicalBlockNum, sizeof(struct tag));
switch (iinfo->i_alloc_type) {
case ICBTAG_FLAG_AD_SHORT:
- sad = (short_ad *)sptr;
+ sad = (struct short_ad *)sptr;
sad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
inode->i_sb->s_blocksize);
sad->extPosition =
cpu_to_le32(epos->block.logicalBlockNum);
break;
case ICBTAG_FLAG_AD_LONG:
- lad = (long_ad *)sptr;
+ lad = (struct long_ad *)sptr;
lad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
inode->i_sb->s_blocksize);
lad->extLocation = cpu_to_lelb(epos->block);
@@ -1769,12 +1776,12 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
}
int8_t udf_write_aext(struct inode *inode, struct extent_position *epos,
- kernel_lb_addr eloc, uint32_t elen, int inc)
+ struct kernel_lb_addr *eloc, uint32_t elen, int inc)
{
int adsize;
uint8_t *ptr;
- short_ad *sad;
- long_ad *lad;
+ struct short_ad *sad;
+ struct long_ad *lad;
struct udf_inode_info *iinfo = UDF_I(inode);
if (!epos->bh)
@@ -1786,17 +1793,17 @@ int8_t udf_write_aext(struct inode *inode, struct extent_position *epos,
switch (iinfo->i_alloc_type) {
case ICBTAG_FLAG_AD_SHORT:
- sad = (short_ad *)ptr;
+ sad = (struct short_ad *)ptr;
sad->extLength = cpu_to_le32(elen);
- sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);
- adsize = sizeof(short_ad);
+ sad->extPosition = cpu_to_le32(eloc->logicalBlockNum);
+ adsize = sizeof(struct short_ad);
break;
case ICBTAG_FLAG_AD_LONG:
- lad = (long_ad *)ptr;
+ lad = (struct long_ad *)ptr;
lad->extLength = cpu_to_le32(elen);
- lad->extLocation = cpu_to_lelb(eloc);
+ lad->extLocation = cpu_to_lelb(*eloc);
memset(lad->impUse, 0x00, sizeof(lad->impUse));
- adsize = sizeof(long_ad);
+ adsize = sizeof(struct long_ad);
break;
default:
return -1;
@@ -1823,7 +1830,7 @@ int8_t udf_write_aext(struct inode *inode, struct extent_position *epos,
}
int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
- kernel_lb_addr *eloc, uint32_t *elen, int inc)
+ struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
{
int8_t etype;
@@ -1833,7 +1840,7 @@ int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
epos->block = *eloc;
epos->offset = sizeof(struct allocExtDesc);
brelse(epos->bh);
- block = udf_get_lb_pblock(inode->i_sb, epos->block, 0);
+ block = udf_get_lb_pblock(inode->i_sb, &epos->block, 0);
epos->bh = udf_tread(inode->i_sb, block);
if (!epos->bh) {
udf_debug("reading block %d failed!\n", block);
@@ -1845,13 +1852,13 @@ int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
}
int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
- kernel_lb_addr *eloc, uint32_t *elen, int inc)
+ struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
{
int alen;
int8_t etype;
uint8_t *ptr;
- short_ad *sad;
- long_ad *lad;
+ struct short_ad *sad;
+ struct long_ad *lad;
struct udf_inode_info *iinfo = UDF_I(inode);
if (!epos->bh) {
@@ -1900,9 +1907,9 @@ int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
}
static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos,
- kernel_lb_addr neloc, uint32_t nelen)
+ struct kernel_lb_addr neloc, uint32_t nelen)
{
- kernel_lb_addr oeloc;
+ struct kernel_lb_addr oeloc;
uint32_t oelen;
int8_t etype;
@@ -1910,18 +1917,18 @@ static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos,
get_bh(epos.bh);
while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) {
- udf_write_aext(inode, &epos, neloc, nelen, 1);
+ udf_write_aext(inode, &epos, &neloc, nelen, 1);
neloc = oeloc;
nelen = (etype << 30) | oelen;
}
- udf_add_aext(inode, &epos, neloc, nelen, 1);
+ udf_add_aext(inode, &epos, &neloc, nelen, 1);
brelse(epos.bh);
return (nelen >> 30);
}
int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
- kernel_lb_addr eloc, uint32_t elen)
+ struct kernel_lb_addr eloc, uint32_t elen)
{
struct extent_position oepos;
int adsize;
@@ -1936,9 +1943,9 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
iinfo = UDF_I(inode);
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- adsize = sizeof(short_ad);
+ adsize = sizeof(struct short_ad);
else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
- adsize = sizeof(long_ad);
+ adsize = sizeof(struct long_ad);
else
adsize = 0;
@@ -1947,7 +1954,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
return -1;
while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) {
- udf_write_aext(inode, &oepos, eloc, (etype << 30) | elen, 1);
+ udf_write_aext(inode, &oepos, &eloc, (etype << 30) | elen, 1);
if (oepos.bh != epos.bh) {
oepos.block = epos.block;
brelse(oepos.bh);
@@ -1956,13 +1963,13 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
oepos.offset = epos.offset - adsize;
}
}
- memset(&eloc, 0x00, sizeof(kernel_lb_addr));
+ memset(&eloc, 0x00, sizeof(struct kernel_lb_addr));
elen = 0;
if (epos.bh != oepos.bh) {
- udf_free_blocks(inode->i_sb, inode, epos.block, 0, 1);
- udf_write_aext(inode, &oepos, eloc, elen, 1);
- udf_write_aext(inode, &oepos, eloc, elen, 1);
+ udf_free_blocks(inode->i_sb, inode, &epos.block, 0, 1);
+ udf_write_aext(inode, &oepos, &eloc, elen, 1);
+ udf_write_aext(inode, &oepos, &eloc, elen, 1);
if (!oepos.bh) {
iinfo->i_lenAlloc -= (adsize * 2);
mark_inode_dirty(inode);
@@ -1979,7 +1986,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
mark_buffer_dirty_inode(oepos.bh, inode);
}
} else {
- udf_write_aext(inode, &oepos, eloc, elen, 1);
+ udf_write_aext(inode, &oepos, &eloc, elen, 1);
if (!oepos.bh) {
iinfo->i_lenAlloc -= adsize;
mark_inode_dirty(inode);
@@ -2004,7 +2011,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
}
int8_t inode_bmap(struct inode *inode, sector_t block,
- struct extent_position *pos, kernel_lb_addr *eloc,
+ struct extent_position *pos, struct kernel_lb_addr *eloc,
uint32_t *elen, sector_t *offset)
{
unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
@@ -2036,7 +2043,7 @@ int8_t inode_bmap(struct inode *inode, sector_t block,
long udf_block_map(struct inode *inode, sector_t block)
{
- kernel_lb_addr eloc;
+ struct kernel_lb_addr eloc;
uint32_t elen;
sector_t offset;
struct extent_position epos = {};
@@ -2046,7 +2053,7 @@ long udf_block_map(struct inode *inode, sector_t block)
if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) ==
(EXT_RECORDED_ALLOCATED >> 30))
- ret = udf_get_lb_pblock(inode->i_sb, eloc, offset);
+ ret = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
else
ret = 0;
diff --git a/fs/udf/misc.c b/fs/udf/misc.c
index 84bf0fd4a4f..9215700c00a 100644
--- a/fs/udf/misc.c
+++ b/fs/udf/misc.c
@@ -134,10 +134,10 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size,
}
}
/* rewrite CRC + checksum of eahd */
- crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag);
+ crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(struct tag);
eahd->descTag.descCRCLength = cpu_to_le16(crclen);
eahd->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)eahd +
- sizeof(tag), crclen));
+ sizeof(struct tag), crclen));
eahd->descTag.tagChecksum = udf_tag_checksum(&eahd->descTag);
iinfo->i_lenEAttr += size;
return (struct genericFormat *)&ea[offset];
@@ -202,7 +202,7 @@ struct genericFormat *udf_get_extendedattr(struct inode *inode, uint32_t type,
struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
uint32_t location, uint16_t *ident)
{
- tag *tag_p;
+ struct tag *tag_p;
struct buffer_head *bh = NULL;
/* Read the block */
@@ -216,7 +216,7 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
return NULL;
}
- tag_p = (tag *)(bh->b_data);
+ tag_p = (struct tag *)(bh->b_data);
*ident = le16_to_cpu(tag_p->tagIdent);
@@ -241,9 +241,9 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
}
/* Verify the descriptor CRC */
- if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize ||
+ if (le16_to_cpu(tag_p->descCRCLength) + sizeof(struct tag) > sb->s_blocksize ||
le16_to_cpu(tag_p->descCRC) == crc_itu_t(0,
- bh->b_data + sizeof(tag),
+ bh->b_data + sizeof(struct tag),
le16_to_cpu(tag_p->descCRCLength)))
return bh;
@@ -255,27 +255,28 @@ error_out:
return NULL;
}
-struct buffer_head *udf_read_ptagged(struct super_block *sb, kernel_lb_addr loc,
+struct buffer_head *udf_read_ptagged(struct super_block *sb,
+ struct kernel_lb_addr *loc,
uint32_t offset, uint16_t *ident)
{
return udf_read_tagged(sb, udf_get_lb_pblock(sb, loc, offset),
- loc.logicalBlockNum + offset, ident);
+ loc->logicalBlockNum + offset, ident);
}
void udf_update_tag(char *data, int length)
{
- tag *tptr = (tag *)data;
- length -= sizeof(tag);
+ struct tag *tptr = (struct tag *)data;
+ length -= sizeof(struct tag);
tptr->descCRCLength = cpu_to_le16(length);
- tptr->descCRC = cpu_to_le16(crc_itu_t(0, data + sizeof(tag), length));
+ tptr->descCRC = cpu_to_le16(crc_itu_t(0, data + sizeof(struct tag), length));
tptr->tagChecksum = udf_tag_checksum(tptr);
}
void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum,
uint32_t loc, int length)
{
- tag *tptr = (tag *)data;
+ struct tag *tptr = (struct tag *)data;
tptr->tagIdent = cpu_to_le16(ident);
tptr->descVersion = cpu_to_le16(version);
tptr->tagSerialNum = cpu_to_le16(snum);
@@ -283,12 +284,12 @@ void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum,
udf_update_tag(data, length);
}
-u8 udf_tag_checksum(const tag *t)
+u8 udf_tag_checksum(const struct tag *t)
{
u8 *data = (u8 *)t;
u8 checksum = 0;
int i;
- for (i = 0; i < sizeof(tag); ++i)
+ for (i = 0; i < sizeof(struct tag); ++i)
if (i != 4) /* position of checksum */
checksum += data[i];
return checksum;
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index f84bfaa8d94..6a29fa34c47 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -47,7 +47,7 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
struct fileIdentDesc *sfi, struct udf_fileident_bh *fibh,
uint8_t *impuse, uint8_t *fileident)
{
- uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(tag);
+ uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(struct tag);
uint16_t crc;
int offset;
uint16_t liu = le16_to_cpu(cfi->lengthOfImpUse);
@@ -99,18 +99,18 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
memset(fibh->ebh->b_data, 0x00, padlen + offset);
}
- crc = crc_itu_t(0, (uint8_t *)cfi + sizeof(tag),
- sizeof(struct fileIdentDesc) - sizeof(tag));
+ crc = crc_itu_t(0, (uint8_t *)cfi + sizeof(struct tag),
+ sizeof(struct fileIdentDesc) - sizeof(struct tag));
if (fibh->sbh == fibh->ebh) {
crc = crc_itu_t(crc, (uint8_t *)sfi->impUse,
- crclen + sizeof(tag) -
+ crclen + sizeof(struct tag) -
sizeof(struct fileIdentDesc));
} else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) {
crc = crc_itu_t(crc, fibh->ebh->b_data +
sizeof(struct fileIdentDesc) +
fibh->soffset,
- crclen + sizeof(tag) -
+ crclen + sizeof(struct tag) -
sizeof(struct fileIdentDesc));
} else {
crc = crc_itu_t(crc, (uint8_t *)sfi->impUse,
@@ -154,7 +154,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
uint8_t lfi;
uint16_t liu;
loff_t size;
- kernel_lb_addr eloc;
+ struct kernel_lb_addr eloc;
uint32_t elen;
sector_t offset;
struct extent_position epos = {};
@@ -171,12 +171,12 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos,
&eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30))
goto out_err;
- block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
+ block = udf_get_lb_pblock(dir->i_sb, &eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- epos.offset -= sizeof(short_ad);
+ epos.offset -= sizeof(struct short_ad);
else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
- epos.offset -= sizeof(long_ad);
+ epos.offset -= sizeof(struct long_ad);
} else
offset = 0;
@@ -268,7 +268,7 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
#ifdef UDF_RECOVERY
/* temporary shorthand for specifying files by inode number */
if (!strncmp(dentry->d_name.name, ".B=", 3)) {
- kernel_lb_addr lb = {
+ struct kernel_lb_addr lb = {
.logicalBlockNum = 0,
.partitionReferenceNum =
simple_strtoul(dentry->d_name.name + 3,
@@ -283,11 +283,14 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
#endif /* UDF_RECOVERY */
if (udf_find_entry(dir, &dentry->d_name, &fibh, &cfi)) {
+ struct kernel_lb_addr loc;
+
if (fibh.sbh != fibh.ebh)
brelse(fibh.ebh);
brelse(fibh.sbh);
- inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation));
+ loc = lelb_to_cpu(cfi.icb.extLocation);
+ inode = udf_iget(dir->i_sb, &loc);
if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES);
@@ -313,7 +316,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
uint8_t lfi;
uint16_t liu;
int block;
- kernel_lb_addr eloc;
+ struct kernel_lb_addr eloc;
uint32_t elen = 0;
sector_t offset;
struct extent_position epos = {};
@@ -351,16 +354,16 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos,
&eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) {
block = udf_get_lb_pblock(dir->i_sb,
- dinfo->i_location, 0);
+ &dinfo->i_location, 0);
fibh->soffset = fibh->eoffset = sb->s_blocksize;
goto add;
}
- block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
+ block = udf_get_lb_pblock(dir->i_sb, &eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- epos.offset -= sizeof(short_ad);
+ epos.offset -= sizeof(struct short_ad);
else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
- epos.offset -= sizeof(long_ad);
+ epos.offset -= sizeof(struct long_ad);
} else
offset = 0;
@@ -409,10 +412,10 @@ add:
if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && elen) {
elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1);
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- epos.offset -= sizeof(short_ad);
+ epos.offset -= sizeof(struct short_ad);
else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
- epos.offset -= sizeof(long_ad);
- udf_write_aext(dir, &epos, eloc, elen, 1);
+ epos.offset -= sizeof(struct long_ad);
+ udf_write_aext(dir, &epos, &eloc, elen, 1);
}
f_pos += nfidlen;
@@ -494,10 +497,10 @@ add:
memset(cfi, 0, sizeof(struct fileIdentDesc));
if (UDF_SB(sb)->s_udfrev >= 0x0200)
udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block,
- sizeof(tag));
+ sizeof(struct tag));
else
udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block,
- sizeof(tag));
+ sizeof(struct tag));
cfi->fileVersionNum = cpu_to_le16(1);
cfi->lengthFileIdent = namelen;
cfi->lengthOfImpUse = cpu_to_le16(0);
@@ -530,7 +533,7 @@ static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,
cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED;
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
- memset(&(cfi->icb), 0x00, sizeof(long_ad));
+ memset(&(cfi->icb), 0x00, sizeof(struct long_ad));
return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL);
}
@@ -710,7 +713,7 @@ static int empty_dir(struct inode *dir)
loff_t f_pos;
loff_t size = udf_ext0_offset(dir) + dir->i_size;
int block;
- kernel_lb_addr eloc;
+ struct kernel_lb_addr eloc;
uint32_t elen;
sector_t offset;
struct extent_position epos = {};
@@ -724,12 +727,12 @@ static int empty_dir(struct inode *dir)
else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits,
&epos, &eloc, &elen, &offset) ==
(EXT_RECORDED_ALLOCATED >> 30)) {
- block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
+ block = udf_get_lb_pblock(dir->i_sb, &eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- epos.offset -= sizeof(short_ad);
+ epos.offset -= sizeof(struct short_ad);
else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
- epos.offset -= sizeof(long_ad);
+ epos.offset -= sizeof(struct long_ad);
} else
offset = 0;
@@ -778,7 +781,7 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry)
struct inode *inode = dentry->d_inode;
struct udf_fileident_bh fibh;
struct fileIdentDesc *fi, cfi;
- kernel_lb_addr tloc;
+ struct kernel_lb_addr tloc;
retval = -ENOENT;
lock_kernel();
@@ -788,7 +791,7 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry)
retval = -EIO;
tloc = lelb_to_cpu(cfi.icb.extLocation);
- if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino)
+ if (udf_get_lb_pblock(dir->i_sb, &tloc, 0) != inode->i_ino)
goto end_rmdir;
retval = -ENOTEMPTY;
if (!empty_dir(inode))
@@ -824,7 +827,7 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry)
struct udf_fileident_bh fibh;
struct fileIdentDesc *fi;
struct fileIdentDesc cfi;
- kernel_lb_addr tloc;
+ struct kernel_lb_addr tloc;
retval = -ENOENT;
lock_kernel();
@@ -834,7 +837,7 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry)
retval = -EIO;
tloc = lelb_to_cpu(cfi.icb.extLocation);
- if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino)
+ if (udf_get_lb_pblock(dir->i_sb, &tloc, 0) != inode->i_ino)
goto end_unlink;
if (!inode->i_nlink) {
@@ -897,7 +900,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
inode->i_op = &page_symlink_inode_operations;
if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
- kernel_lb_addr eloc;
+ struct kernel_lb_addr eloc;
uint32_t bsize;
block = udf_new_block(inode->i_sb, inode,
@@ -913,7 +916,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
iinfo->i_location.partitionReferenceNum;
bsize = inode->i_sb->s_blocksize;
iinfo->i_lenExtents = bsize;
- udf_add_aext(inode, &epos, eloc, bsize, 0);
+ udf_add_aext(inode, &epos, &eloc, bsize, 0);
brelse(epos.bh);
block = udf_get_pblock(inode->i_sb, block,
@@ -1108,7 +1111,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
struct fileIdentDesc ocfi, ncfi;
struct buffer_head *dir_bh = NULL;
int retval = -ENOENT;
- kernel_lb_addr tloc;
+ struct kernel_lb_addr tloc;
struct udf_inode_info *old_iinfo = UDF_I(old_inode);
lock_kernel();
@@ -1119,7 +1122,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
brelse(ofibh.sbh);
}
tloc = lelb_to_cpu(ocfi.icb.extLocation);
- if (!ofi || udf_get_lb_pblock(old_dir->i_sb, tloc, 0)
+ if (!ofi || udf_get_lb_pblock(old_dir->i_sb, &tloc, 0)
!= old_inode->i_ino)
goto end_rename;
@@ -1158,7 +1161,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
if (!dir_fi)
goto end_rename;
tloc = lelb_to_cpu(dir_fi->icb.extLocation);
- if (udf_get_lb_pblock(old_inode->i_sb, tloc, 0) !=
+ if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) !=
old_dir->i_ino)
goto end_rename;
@@ -1187,7 +1190,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
*/
ncfi.fileVersionNum = ocfi.fileVersionNum;
ncfi.fileCharacteristics = ocfi.fileCharacteristics;
- memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(long_ad));
+ memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(struct long_ad));
udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL);
/* The old fid may have moved - find it again */
@@ -1242,6 +1245,7 @@ end_rename:
static struct dentry *udf_get_parent(struct dentry *child)
{
+ struct kernel_lb_addr tloc;
struct inode *inode = NULL;
struct qstr dotdot = {.name = "..", .len = 2};
struct fileIdentDesc cfi;
@@ -1255,8 +1259,8 @@ static struct dentry *udf_get_parent(struct dentry *child)
brelse(fibh.ebh);
brelse(fibh.sbh);
- inode = udf_iget(child->d_inode->i_sb,
- lelb_to_cpu(cfi.icb.extLocation));
+ tloc = lelb_to_cpu(cfi.icb.extLocation);
+ inode = udf_iget(child->d_inode->i_sb, &tloc);
if (!inode)
goto out_unlock;
unlock_kernel();
@@ -1272,14 +1276,14 @@ static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block,
u16 partref, __u32 generation)
{
struct inode *inode;
- kernel_lb_addr loc;
+ struct kernel_lb_addr loc;
if (block == 0)
return ERR_PTR(-ESTALE);
loc.logicalBlockNum = block;
loc.partitionReferenceNum = partref;
- inode = udf_iget(sb, loc);
+ inode = udf_iget(sb, &loc);
if (inode == NULL)
return ERR_PTR(-ENOMEM);
@@ -1318,7 +1322,7 @@ static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp,
{
int len = *lenp;
struct inode *inode = de->d_inode;
- kernel_lb_addr location = UDF_I(inode)->i_location;
+ struct kernel_lb_addr location = UDF_I(inode)->i_location;
struct fid *fid = (struct fid *)fh;
int type = FILEID_UDF_WITHOUT_PARENT;
diff --git a/fs/udf/osta_udf.h b/fs/udf/osta_udf.h
index 65ff47902bd..fbff74654df 100644
--- a/fs/udf/osta_udf.h
+++ b/fs/udf/osta_udf.h
@@ -85,7 +85,7 @@ struct appIdentSuffix {
/* Logical Volume Integrity Descriptor (UDF 2.50 2.2.6) */
/* Implementation Use (UDF 2.50 2.2.6.4) */
struct logicalVolIntegrityDescImpUse {
- regid impIdent;
+ struct regid impIdent;
__le32 numFiles;
__le32 numDirs;
__le16 minUDFReadRev;
@@ -97,12 +97,12 @@ struct logicalVolIntegrityDescImpUse {
/* Implementation Use Volume Descriptor (UDF 2.50 2.2.7) */
/* Implementation Use (UDF 2.50 2.2.7.2) */
struct impUseVolDescImpUse {
- charspec LVICharset;
+ struct charspec LVICharset;
dstring logicalVolIdent[128];
dstring LVInfo1[36];
dstring LVInfo2[36];
dstring LVInfo3[36];
- regid impIdent;
+ struct regid impIdent;
uint8_t impUse[128];
} __attribute__ ((packed));
@@ -110,7 +110,7 @@ struct udfPartitionMap2 {
uint8_t partitionMapType;
uint8_t partitionMapLength;
uint8_t reserved1[2];
- regid partIdent;
+ struct regid partIdent;
__le16 volSeqNum;
__le16 partitionNum;
} __attribute__ ((packed));
@@ -120,7 +120,7 @@ struct virtualPartitionMap {
uint8_t partitionMapType;
uint8_t partitionMapLength;
uint8_t reserved1[2];
- regid partIdent;
+ struct regid partIdent;
__le16 volSeqNum;
__le16 partitionNum;
uint8_t reserved2[24];
@@ -131,7 +131,7 @@ struct sparablePartitionMap {
uint8_t partitionMapType;
uint8_t partitionMapLength;
uint8_t reserved1[2];
- regid partIdent;
+ struct regid partIdent;
__le16 volSeqNum;
__le16 partitionNum;
__le16 packetLength;
@@ -146,7 +146,7 @@ struct metadataPartitionMap {
uint8_t partitionMapType;
uint8_t partitionMapLength;
uint8_t reserved1[2];
- regid partIdent;
+ struct regid partIdent;
__le16 volSeqNum;
__le16 partitionNum;
__le32 metadataFileLoc;
@@ -161,7 +161,7 @@ struct metadataPartitionMap {
/* Virtual Allocation Table (UDF 1.5 2.2.10) */
struct virtualAllocationTable15 {
__le32 VirtualSector[0];
- regid vatIdent;
+ struct regid vatIdent;
__le32 previousVATICBLoc;
} __attribute__ ((packed));
@@ -192,8 +192,8 @@ struct sparingEntry {
} __attribute__ ((packed));
struct sparingTable {
- tag descTag;
- regid sparingIdent;
+ struct tag descTag;
+ struct regid sparingIdent;
__le16 reallocationTableLen;
__le16 reserved;
__le32 sequenceNum;
@@ -206,7 +206,7 @@ struct sparingTable {
#define ICBTAG_FILE_TYPE_MIRROR 0xFB
#define ICBTAG_FILE_TYPE_BITMAP 0xFC
-/* struct long_ad ICB - ADImpUse (UDF 2.50 2.2.4.3) */
+/* struct struct long_ad ICB - ADImpUse (UDF 2.50 2.2.4.3) */
struct allocDescImpUse {
__le16 flags;
uint8_t impUse[4];
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index 96dfd207c3d..4b540ee632d 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -273,7 +273,7 @@ static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block,
{
struct super_block *sb = inode->i_sb;
struct udf_part_map *map;
- kernel_lb_addr eloc;
+ struct kernel_lb_addr eloc;
uint32_t elen;
sector_t ext_offset;
struct extent_position epos = {};
diff --git a/fs/udf/super.c b/fs/udf/super.c
index e25e7010627..72348cc855a 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -81,16 +81,13 @@ static char error_buf[1024];
/* These are the "meat" - everything else is stuffing */
static int udf_fill_super(struct super_block *, void *, int);
static void udf_put_super(struct super_block *);
-static void udf_write_super(struct super_block *);
+static int udf_sync_fs(struct super_block *, int);
static int udf_remount_fs(struct super_block *, int *, char *);
-static int udf_check_valid(struct super_block *, int, int);
-static int udf_vrs(struct super_block *sb, int silent);
-static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad);
-static void udf_find_anchor(struct super_block *);
-static int udf_find_fileset(struct super_block *, kernel_lb_addr *,
- kernel_lb_addr *);
+static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad);
+static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *,
+ struct kernel_lb_addr *);
static void udf_load_fileset(struct super_block *, struct buffer_head *,
- kernel_lb_addr *);
+ struct kernel_lb_addr *);
static void udf_open_lvid(struct super_block *);
static void udf_close_lvid(struct super_block *);
static unsigned int udf_count_free(struct super_block *);
@@ -181,7 +178,7 @@ static const struct super_operations udf_sb_ops = {
.delete_inode = udf_delete_inode,
.clear_inode = udf_clear_inode,
.put_super = udf_put_super,
- .write_super = udf_write_super,
+ .sync_fs = udf_sync_fs,
.statfs = udf_statfs,
.remount_fs = udf_remount_fs,
.show_options = udf_show_options,
@@ -201,6 +198,8 @@ struct udf_options {
mode_t umask;
gid_t gid;
uid_t uid;
+ mode_t fmode;
+ mode_t dmode;
struct nls_table *nls_map;
};
@@ -258,7 +257,7 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt)
if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT))
seq_puts(seq, ",nostrict");
- if (sb->s_blocksize != UDF_DEFAULT_BLOCKSIZE)
+ if (UDF_QUERY_FLAG(sb, UDF_FLAG_BLOCKSIZE_SET))
seq_printf(seq, ",bs=%lu", sb->s_blocksize);
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE))
seq_puts(seq, ",unhide");
@@ -282,18 +281,16 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt)
seq_printf(seq, ",gid=%u", sbi->s_gid);
if (sbi->s_umask != 0)
seq_printf(seq, ",umask=%o", sbi->s_umask);
+ if (sbi->s_fmode != UDF_INVALID_MODE)
+ seq_printf(seq, ",mode=%o", sbi->s_fmode);
+ if (sbi->s_dmode != UDF_INVALID_MODE)
+ seq_printf(seq, ",dmode=%o", sbi->s_dmode);
if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET))
seq_printf(seq, ",session=%u", sbi->s_session);
if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET))
seq_printf(seq, ",lastblock=%u", sbi->s_last_block);
- /*
- * s_anchor[2] could be zeroed out in case there is no anchor
- * in the specified block, but then the "anchor=N" option
- * originally given by the user wasn't effective, so it's OK
- * if we don't show it.
- */
- if (sbi->s_anchor[2] != 0)
- seq_printf(seq, ",anchor=%u", sbi->s_anchor[2]);
+ if (sbi->s_anchor != 0)
+ seq_printf(seq, ",anchor=%u", sbi->s_anchor);
/*
* volume, partition, fileset and rootdir seem to be ignored
* currently
@@ -317,6 +314,8 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt)
*
* gid= Set the default group.
* umask= Set the default umask.
+ * mode= Set the default file permissions.
+ * dmode= Set the default directory permissions.
* uid= Set the default user.
* bs= Set the block size.
* unhide Show otherwise hidden files.
@@ -366,7 +365,8 @@ enum {
Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
Opt_rootdir, Opt_utf8, Opt_iocharset,
- Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore
+ Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore,
+ Opt_fmode, Opt_dmode
};
static const match_table_t tokens = {
@@ -395,6 +395,8 @@ static const match_table_t tokens = {
{Opt_rootdir, "rootdir=%u"},
{Opt_utf8, "utf8"},
{Opt_iocharset, "iocharset=%s"},
+ {Opt_fmode, "mode=%o"},
+ {Opt_dmode, "dmode=%o"},
{Opt_err, NULL}
};
@@ -405,7 +407,6 @@ static int udf_parse_options(char *options, struct udf_options *uopt,
int option;
uopt->novrs = 0;
- uopt->blocksize = UDF_DEFAULT_BLOCKSIZE;
uopt->partition = 0xFFFF;
uopt->session = 0xFFFFFFFF;
uopt->lastblock = 0;
@@ -428,10 +429,12 @@ static int udf_parse_options(char *options, struct udf_options *uopt,
switch (token) {
case Opt_novrs:
uopt->novrs = 1;
+ break;
case Opt_bs:
if (match_int(&args[0], &option))
return 0;
uopt->blocksize = option;
+ uopt->flags |= (1 << UDF_FLAG_BLOCKSIZE_SET);
break;
case Opt_unhide:
uopt->flags |= (1 << UDF_FLAG_UNHIDE);
@@ -531,6 +534,16 @@ static int udf_parse_options(char *options, struct udf_options *uopt,
case Opt_gforget:
uopt->flags |= (1 << UDF_FLAG_GID_FORGET);
break;
+ case Opt_fmode:
+ if (match_octal(args, &option))
+ return 0;
+ uopt->fmode = option & 0777;
+ break;
+ case Opt_dmode:
+ if (match_octal(args, &option))
+ return 0;
+ uopt->dmode = option & 0777;
+ break;
default:
printk(KERN_ERR "udf: bad mount option \"%s\" "
"or missing value\n", p);
@@ -540,17 +553,6 @@ static int udf_parse_options(char *options, struct udf_options *uopt,
return 1;
}
-static void udf_write_super(struct super_block *sb)
-{
- lock_kernel();
-
- if (!(sb->s_flags & MS_RDONLY))
- udf_open_lvid(sb);
- sb->s_dirt = 0;
-
- unlock_kernel();
-}
-
static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
{
struct udf_options uopt;
@@ -560,6 +562,8 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
uopt.uid = sbi->s_uid;
uopt.gid = sbi->s_gid;
uopt.umask = sbi->s_umask;
+ uopt.fmode = sbi->s_fmode;
+ uopt.dmode = sbi->s_dmode;
if (!udf_parse_options(options, &uopt, true))
return -EINVAL;
@@ -568,6 +572,8 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
sbi->s_uid = uopt.uid;
sbi->s_gid = uopt.gid;
sbi->s_umask = uopt.umask;
+ sbi->s_fmode = uopt.fmode;
+ sbi->s_dmode = uopt.dmode;
if (sbi->s_lvid_bh) {
int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev);
@@ -585,22 +591,19 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
return 0;
}
-static int udf_vrs(struct super_block *sb, int silent)
+/* Check Volume Structure Descriptors (ECMA 167 2/9.1) */
+/* We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */
+static loff_t udf_check_vsd(struct super_block *sb)
{
struct volStructDesc *vsd = NULL;
loff_t sector = 32768;
int sectorsize;
struct buffer_head *bh = NULL;
- int iso9660 = 0;
int nsr02 = 0;
int nsr03 = 0;
struct udf_sb_info *sbi;
- /* Block size must be a multiple of 512 */
- if (sb->s_blocksize & 511)
- return 0;
sbi = UDF_SB(sb);
-
if (sb->s_blocksize < sizeof(struct volStructDesc))
sectorsize = sizeof(struct volStructDesc);
else
@@ -627,7 +630,6 @@ static int udf_vrs(struct super_block *sb, int silent)
break;
} else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001,
VSD_STD_ID_LEN)) {
- iso9660 = sector;
switch (vsd->structType) {
case 0:
udf_debug("ISO9660 Boot Record found\n");
@@ -679,139 +681,9 @@ static int udf_vrs(struct super_block *sb, int silent)
return 0;
}
-/*
- * Check whether there is an anchor block in the given block
- */
-static int udf_check_anchor_block(struct super_block *sb, sector_t block)
-{
- struct buffer_head *bh;
- uint16_t ident;
-
- if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) &&
- udf_fixed_to_variable(block) >=
- sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits)
- return 0;
-
- bh = udf_read_tagged(sb, block, block, &ident);
- if (!bh)
- return 0;
- brelse(bh);
-
- return ident == TAG_IDENT_AVDP;
-}
-
-/* Search for an anchor volume descriptor pointer */
-static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock)
-{
- sector_t last[6];
- int i;
- struct udf_sb_info *sbi = UDF_SB(sb);
-
- last[0] = lastblock;
- last[1] = last[0] - 1;
- last[2] = last[0] + 1;
- last[3] = last[0] - 2;
- last[4] = last[0] - 150;
- last[5] = last[0] - 152;
-
- /* according to spec, anchor is in either:
- * block 256
- * lastblock-256
- * lastblock
- * however, if the disc isn't closed, it could be 512 */
-
- for (i = 0; i < ARRAY_SIZE(last); i++) {
- if (last[i] < 0)
- continue;
- if (last[i] >= sb->s_bdev->bd_inode->i_size >>
- sb->s_blocksize_bits)
- continue;
-
- if (udf_check_anchor_block(sb, last[i])) {
- sbi->s_anchor[0] = last[i];
- sbi->s_anchor[1] = last[i] - 256;
- return last[i];
- }
-
- if (last[i] < 256)
- continue;
-
- if (udf_check_anchor_block(sb, last[i] - 256)) {
- sbi->s_anchor[1] = last[i] - 256;
- return last[i];
- }
- }
-
- if (udf_check_anchor_block(sb, sbi->s_session + 256)) {
- sbi->s_anchor[0] = sbi->s_session + 256;
- return last[0];
- }
- if (udf_check_anchor_block(sb, sbi->s_session + 512)) {
- sbi->s_anchor[0] = sbi->s_session + 512;
- return last[0];
- }
- return 0;
-}
-
-/*
- * Find an anchor volume descriptor. The function expects sbi->s_lastblock to
- * be the last block on the media.
- *
- * Return 1 if not found, 0 if ok
- *
- */
-static void udf_find_anchor(struct super_block *sb)
-{
- sector_t lastblock;
- struct buffer_head *bh = NULL;
- uint16_t ident;
- int i;
- struct udf_sb_info *sbi = UDF_SB(sb);
-
- lastblock = udf_scan_anchors(sb, sbi->s_last_block);
- if (lastblock)
- goto check_anchor;
-
- /* No anchor found? Try VARCONV conversion of block numbers */
- UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
- /* Firstly, we try to not convert number of the last block */
- lastblock = udf_scan_anchors(sb,
- udf_variable_to_fixed(sbi->s_last_block));
- if (lastblock)
- goto check_anchor;
-
- /* Secondly, we try with converted number of the last block */
- lastblock = udf_scan_anchors(sb, sbi->s_last_block);
- if (!lastblock) {
- /* VARCONV didn't help. Clear it. */
- UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV);
- }
-
-check_anchor:
- /*
- * Check located anchors and the anchor block supplied via
- * mount options
- */
- for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) {
- if (!sbi->s_anchor[i])
- continue;
- bh = udf_read_tagged(sb, sbi->s_anchor[i],
- sbi->s_anchor[i], &ident);
- if (!bh)
- sbi->s_anchor[i] = 0;
- else {
- brelse(bh);
- if (ident != TAG_IDENT_AVDP)
- sbi->s_anchor[i] = 0;
- }
- }
-
- sbi->s_last_block = lastblock;
-}
-
static int udf_find_fileset(struct super_block *sb,
- kernel_lb_addr *fileset,
- kernel_lb_addr *root)
+ struct kernel_lb_addr *fileset,
+ struct kernel_lb_addr *root)
{
struct buffer_head *bh = NULL;
long lastblock;
@@ -820,7 +692,7 @@ static int udf_find_fileset(struct super_block *sb,
if (fileset->logicalBlockNum != 0xFFFFFFFF ||
fileset->partitionReferenceNum != 0xFFFF) {
- bh = udf_read_ptagged(sb, *fileset, 0, &ident);
+ bh = udf_read_ptagged(sb, fileset, 0, &ident);
if (!bh) {
return 1;
@@ -834,7 +706,7 @@ static int udf_find_fileset(struct super_block *sb,
sbi = UDF_SB(sb);
if (!bh) {
/* Search backwards through the partitions */
- kernel_lb_addr newfileset;
+ struct kernel_lb_addr newfileset;
/* --> cvg: FIXME - is it reasonable? */
return 1;
@@ -850,7 +722,7 @@ static int udf_find_fileset(struct super_block *sb,
newfileset.logicalBlockNum = 0;
do {
- bh = udf_read_ptagged(sb, newfileset, 0,
+ bh = udf_read_ptagged(sb, &newfileset, 0,
&ident);
if (!bh) {
newfileset.logicalBlockNum++;
@@ -902,14 +774,23 @@ static int udf_find_fileset(struct super_block *sb,
static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
{
struct primaryVolDesc *pvoldesc;
- struct ustr instr;
- struct ustr outstr;
+ struct ustr *instr, *outstr;
struct buffer_head *bh;
uint16_t ident;
+ int ret = 1;
+
+ instr = kmalloc(sizeof(struct ustr), GFP_NOFS);
+ if (!instr)
+ return 1;
+
+ outstr = kmalloc(sizeof(struct ustr), GFP_NOFS);
+ if (!outstr)
+ goto out1;
bh = udf_read_tagged(sb, block, block, &ident);
if (!bh)
- return 1;
+ goto out2;
+
BUG_ON(ident != TAG_IDENT_PVD);
pvoldesc = (struct primaryVolDesc *)bh->b_data;
@@ -917,7 +798,7 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
if (udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time,
pvoldesc->recordingDateAndTime)) {
#ifdef UDFFS_DEBUG
- timestamp *ts = &pvoldesc->recordingDateAndTime;
+ struct timestamp *ts = &pvoldesc->recordingDateAndTime;
udf_debug("recording time %04u/%02u/%02u"
" %02u:%02u (%x)\n",
le16_to_cpu(ts->year), ts->month, ts->day, ts->hour,
@@ -925,20 +806,25 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
#endif
}
- if (!udf_build_ustr(&instr, pvoldesc->volIdent, 32))
- if (udf_CS0toUTF8(&outstr, &instr)) {
- strncpy(UDF_SB(sb)->s_volume_ident, outstr.u_name,
- outstr.u_len > 31 ? 31 : outstr.u_len);
+ if (!udf_build_ustr(instr, pvoldesc->volIdent, 32))
+ if (udf_CS0toUTF8(outstr, instr)) {
+ strncpy(UDF_SB(sb)->s_volume_ident, outstr->u_name,
+ outstr->u_len > 31 ? 31 : outstr->u_len);
udf_debug("volIdent[] = '%s'\n",
UDF_SB(sb)->s_volume_ident);
}
- if (!udf_build_ustr(&instr, pvoldesc->volSetIdent, 128))
- if (udf_CS0toUTF8(&outstr, &instr))
- udf_debug("volSetIdent[] = '%s'\n", outstr.u_name);
+ if (!udf_build_ustr(instr, pvoldesc->volSetIdent, 128))
+ if (udf_CS0toUTF8(outstr, instr))
+ udf_debug("volSetIdent[] = '%s'\n", outstr->u_name);
brelse(bh);
- return 0;
+ ret = 0;
+out2:
+ kfree(outstr);
+out1:
+ kfree(instr);
+ return ret;
}
static int udf_load_metadata_files(struct super_block *sb, int partition)
@@ -946,7 +832,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition)
struct udf_sb_info *sbi = UDF_SB(sb);
struct udf_part_map *map;
struct udf_meta_data *mdata;
- kernel_lb_addr addr;
+ struct kernel_lb_addr addr;
int fe_error = 0;
map = &sbi->s_partmaps[partition];
@@ -959,7 +845,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition)
udf_debug("Metadata file location: block = %d part = %d\n",
addr.logicalBlockNum, addr.partitionReferenceNum);
- mdata->s_metadata_fe = udf_iget(sb, addr);
+ mdata->s_metadata_fe = udf_iget(sb, &addr);
if (mdata->s_metadata_fe == NULL) {
udf_warning(sb, __func__, "metadata inode efe not found, "
@@ -981,7 +867,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition)
udf_debug("Mirror metadata file location: block = %d part = %d\n",
addr.logicalBlockNum, addr.partitionReferenceNum);
- mdata->s_mirror_fe = udf_iget(sb, addr);
+ mdata->s_mirror_fe = udf_iget(sb, &addr);
if (mdata->s_mirror_fe == NULL) {
if (fe_error) {
@@ -1013,7 +899,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition)
udf_debug("Bitmap file location: block = %d part = %d\n",
addr.logicalBlockNum, addr.partitionReferenceNum);
- mdata->s_bitmap_fe = udf_iget(sb, addr);
+ mdata->s_bitmap_fe = udf_iget(sb, &addr);
if (mdata->s_bitmap_fe == NULL) {
if (sb->s_flags & MS_RDONLY)
@@ -1037,7 +923,7 @@ error_exit:
}
static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh,
- kernel_lb_addr *root)
+ struct kernel_lb_addr *root)
{
struct fileSetDesc *fset;
@@ -1119,13 +1005,13 @@ static int udf_fill_partdesc_info(struct super_block *sb,
phd = (struct partitionHeaderDesc *)p->partitionContentsUse;
if (phd->unallocSpaceTable.extLength) {
- kernel_lb_addr loc = {
+ struct kernel_lb_addr loc = {
.logicalBlockNum = le32_to_cpu(
phd->unallocSpaceTable.extPosition),
.partitionReferenceNum = p_index,
};
- map->s_uspace.s_table = udf_iget(sb, loc);
+ map->s_uspace.s_table = udf_iget(sb, &loc);
if (!map->s_uspace.s_table) {
udf_debug("cannot load unallocSpaceTable (part %d)\n",
p_index);
@@ -1154,13 +1040,13 @@ static int udf_fill_partdesc_info(struct super_block *sb,
udf_debug("partitionIntegrityTable (part %d)\n", p_index);
if (phd->freedSpaceTable.extLength) {
- kernel_lb_addr loc = {
+ struct kernel_lb_addr loc = {
.logicalBlockNum = le32_to_cpu(
phd->freedSpaceTable.extPosition),
.partitionReferenceNum = p_index,
};
- map->s_fspace.s_table = udf_iget(sb, loc);
+ map->s_fspace.s_table = udf_iget(sb, &loc);
if (!map->s_fspace.s_table) {
udf_debug("cannot load freedSpaceTable (part %d)\n",
p_index);
@@ -1192,7 +1078,7 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
{
struct udf_sb_info *sbi = UDF_SB(sb);
struct udf_part_map *map = &sbi->s_partmaps[p_index];
- kernel_lb_addr ino;
+ struct kernel_lb_addr ino;
struct buffer_head *bh = NULL;
struct udf_inode_info *vati;
uint32_t pos;
@@ -1201,7 +1087,7 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
/* VAT file entry is in the last recorded block */
ino.partitionReferenceNum = type1_index;
ino.logicalBlockNum = sbi->s_last_block - map->s_partition_root;
- sbi->s_vat_inode = udf_iget(sb, ino);
+ sbi->s_vat_inode = udf_iget(sb, &ino);
if (!sbi->s_vat_inode)
return 1;
@@ -1322,7 +1208,7 @@ out_bh:
}
static int udf_load_logicalvol(struct super_block *sb, sector_t block,
- kernel_lb_addr *fileset)
+ struct kernel_lb_addr *fileset)
{
struct logicalVolDesc *lvd;
int i, j, offset;
@@ -1471,7 +1357,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,
}
if (fileset) {
- long_ad *la = (long_ad *)&(lvd->logicalVolContentsUse[0]);
+ struct long_ad *la = (struct long_ad *)&(lvd->logicalVolContentsUse[0]);
*fileset = lelb_to_cpu(la->extLocation);
udf_debug("FileSet found in LogicalVolDesc at block=%d, "
@@ -1490,7 +1376,7 @@ out_bh:
* udf_load_logicalvolint
*
*/
-static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc)
+static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ad loc)
{
struct buffer_head *bh = NULL;
uint16_t ident;
@@ -1533,7 +1419,7 @@ static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc)
* Written, tested, and released.
*/
static noinline int udf_process_sequence(struct super_block *sb, long block,
- long lastblock, kernel_lb_addr *fileset)
+ long lastblock, struct kernel_lb_addr *fileset)
{
struct buffer_head *bh = NULL;
struct udf_vds_record vds[VDS_POS_LENGTH];
@@ -1655,85 +1541,199 @@ static noinline int udf_process_sequence(struct super_block *sb, long block,
return 0;
}
+static int udf_load_sequence(struct super_block *sb, struct buffer_head *bh,
+ struct kernel_lb_addr *fileset)
+{
+ struct anchorVolDescPtr *anchor;
+ long main_s, main_e, reserve_s, reserve_e;
+ struct udf_sb_info *sbi;
+
+ sbi = UDF_SB(sb);
+ anchor = (struct anchorVolDescPtr *)bh->b_data;
+
+ /* Locate the main sequence */
+ main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation);
+ main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength);
+ main_e = main_e >> sb->s_blocksize_bits;
+ main_e += main_s;
+
+ /* Locate the reserve sequence */
+ reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation);
+ reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength);
+ reserve_e = reserve_e >> sb->s_blocksize_bits;
+ reserve_e += reserve_s;
+
+ /* Process the main & reserve sequences */
+ /* responsible for finding the PartitionDesc(s) */
+ if (!udf_process_sequence(sb, main_s, main_e, fileset))
+ return 1;
+ return !udf_process_sequence(sb, reserve_s, reserve_e, fileset);
+}
+
/*
- * udf_check_valid()
+ * Check whether there is an anchor block in the given block and
+ * load Volume Descriptor Sequence if so.
*/
-static int udf_check_valid(struct super_block *sb, int novrs, int silent)
+static int udf_check_anchor_block(struct super_block *sb, sector_t block,
+ struct kernel_lb_addr *fileset)
{
- long block;
- struct udf_sb_info *sbi = UDF_SB(sb);
+ struct buffer_head *bh;
+ uint16_t ident;
+ int ret;
- if (novrs) {
- udf_debug("Validity check skipped because of novrs option\n");
+ if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) &&
+ udf_fixed_to_variable(block) >=
+ sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits)
+ return 0;
+
+ bh = udf_read_tagged(sb, block, block, &ident);
+ if (!bh)
+ return 0;
+ if (ident != TAG_IDENT_AVDP) {
+ brelse(bh);
return 0;
}
- /* Check that it is NSR02 compliant */
- /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */
- block = udf_vrs(sb, silent);
- if (block == -1)
- udf_debug("Failed to read byte 32768. Assuming open "
- "disc. Skipping validity check\n");
- if (block && !sbi->s_last_block)
- sbi->s_last_block = udf_get_last_block(sb);
- return !block;
+ ret = udf_load_sequence(sb, bh, fileset);
+ brelse(bh);
+ return ret;
}
-static int udf_load_sequence(struct super_block *sb, kernel_lb_addr *fileset)
+/* Search for an anchor volume descriptor pointer */
+static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock,
+ struct kernel_lb_addr *fileset)
{
- struct anchorVolDescPtr *anchor;
- uint16_t ident;
- struct buffer_head *bh;
- long main_s, main_e, reserve_s, reserve_e;
+ sector_t last[6];
int i;
- struct udf_sb_info *sbi;
-
- if (!sb)
- return 1;
- sbi = UDF_SB(sb);
+ struct udf_sb_info *sbi = UDF_SB(sb);
+ int last_count = 0;
- for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) {
- if (!sbi->s_anchor[i])
+ /* First try user provided anchor */
+ if (sbi->s_anchor) {
+ if (udf_check_anchor_block(sb, sbi->s_anchor, fileset))
+ return lastblock;
+ }
+ /*
+ * according to spec, anchor is in either:
+ * block 256
+ * lastblock-256
+ * lastblock
+ * however, if the disc isn't closed, it could be 512.
+ */
+ if (udf_check_anchor_block(sb, sbi->s_session + 256, fileset))
+ return lastblock;
+ /*
+ * The trouble is which block is the last one. Drives often misreport
+ * this so we try various possibilities.
+ */
+ last[last_count++] = lastblock;
+ if (lastblock >= 1)
+ last[last_count++] = lastblock - 1;
+ last[last_count++] = lastblock + 1;
+ if (lastblock >= 2)
+ last[last_count++] = lastblock - 2;
+ if (lastblock >= 150)
+ last[last_count++] = lastblock - 150;
+ if (lastblock >= 152)
+ last[last_count++] = lastblock - 152;
+
+ for (i = 0; i < last_count; i++) {
+ if (last[i] >= sb->s_bdev->bd_inode->i_size >>
+ sb->s_blocksize_bits)
continue;
-
- bh = udf_read_tagged(sb, sbi->s_anchor[i], sbi->s_anchor[i],
- &ident);
- if (!bh)
+ if (udf_check_anchor_block(sb, last[i], fileset))
+ return last[i];
+ if (last[i] < 256)
continue;
+ if (udf_check_anchor_block(sb, last[i] - 256, fileset))
+ return last[i];
+ }
- anchor = (struct anchorVolDescPtr *)bh->b_data;
+ /* Finally try block 512 in case media is open */
+ if (udf_check_anchor_block(sb, sbi->s_session + 512, fileset))
+ return last[0];
+ return 0;
+}
- /* Locate the main sequence */
- main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation);
- main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength);
- main_e = main_e >> sb->s_blocksize_bits;
- main_e += main_s;
+/*
+ * Find an anchor volume descriptor and load Volume Descriptor Sequence from
+ * area specified by it. The function expects sbi->s_lastblock to be the last
+ * block on the media.
+ *
+ * Return 1 if ok, 0 if not found.
+ *
+ */
+static int udf_find_anchor(struct super_block *sb,
+ struct kernel_lb_addr *fileset)
+{
+ sector_t lastblock;
+ struct udf_sb_info *sbi = UDF_SB(sb);
- /* Locate the reserve sequence */
- reserve_s = le32_to_cpu(
- anchor->reserveVolDescSeqExt.extLocation);
- reserve_e = le32_to_cpu(
- anchor->reserveVolDescSeqExt.extLength);
- reserve_e = reserve_e >> sb->s_blocksize_bits;
- reserve_e += reserve_s;
+ lastblock = udf_scan_anchors(sb, sbi->s_last_block, fileset);
+ if (lastblock)
+ goto out;
- brelse(bh);
+ /* No anchor found? Try VARCONV conversion of block numbers */
+ UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+ /* Firstly, we try to not convert number of the last block */
+ lastblock = udf_scan_anchors(sb,
+ udf_variable_to_fixed(sbi->s_last_block),
+ fileset);
+ if (lastblock)
+ goto out;
- /* Process the main & reserve sequences */
- /* responsible for finding the PartitionDesc(s) */
- if (!(udf_process_sequence(sb, main_s, main_e,
- fileset) &&
- udf_process_sequence(sb, reserve_s, reserve_e,
- fileset)))
- break;
+ /* Secondly, we try with converted number of the last block */
+ lastblock = udf_scan_anchors(sb, sbi->s_last_block, fileset);
+ if (!lastblock) {
+ /* VARCONV didn't help. Clear it. */
+ UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV);
+ return 0;
}
+out:
+ sbi->s_last_block = lastblock;
+ return 1;
+}
- if (i == ARRAY_SIZE(sbi->s_anchor)) {
- udf_debug("No Anchor block found\n");
- return 1;
+/*
+ * Check Volume Structure Descriptor, find Anchor block and load Volume
+ * Descriptor Sequence
+ */
+static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt,
+ int silent, struct kernel_lb_addr *fileset)
+{
+ struct udf_sb_info *sbi = UDF_SB(sb);
+ loff_t nsr_off;
+
+ if (!sb_set_blocksize(sb, uopt->blocksize)) {
+ if (!silent)
+ printk(KERN_WARNING "UDF-fs: Bad block size\n");
+ return 0;
+ }
+ sbi->s_last_block = uopt->lastblock;
+ if (!uopt->novrs) {
+ /* Check that it is NSR02 compliant */
+ nsr_off = udf_check_vsd(sb);
+ if (!nsr_off) {
+ if (!silent)
+ printk(KERN_WARNING "UDF-fs: No VRS found\n");
+ return 0;
+ }
+ if (nsr_off == -1)
+ udf_debug("Failed to read byte 32768. Assuming open "
+ "disc. Skipping validity check\n");
+ if (!sbi->s_last_block)
+ sbi->s_last_block = udf_get_last_block(sb);
+ } else {
+ udf_debug("Validity check skipped because of novrs option\n");
}
- udf_debug("Using anchor in block %d\n", sbi->s_anchor[i]);
- return 0;
+ /* Look for anchor block and load Volume Descriptor Sequence */
+ sbi->s_anchor = uopt->anchor;
+ if (!udf_find_anchor(sb, fileset)) {
+ if (!silent)
+ printk(KERN_WARNING "UDF-fs: No anchor found\n");
+ return 0;
+ }
+ return 1;
}
static void udf_open_lvid(struct super_block *sb)
@@ -1742,9 +1742,9 @@ static void udf_open_lvid(struct super_block *sb)
struct buffer_head *bh = sbi->s_lvid_bh;
struct logicalVolIntegrityDesc *lvid;
struct logicalVolIntegrityDescImpUse *lvidiu;
+
if (!bh)
return;
-
lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
lvidiu = udf_sb_lvidiu(sbi);
@@ -1752,14 +1752,15 @@ static void udf_open_lvid(struct super_block *sb)
lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
udf_time_to_disk_stamp(&lvid->recordingDateAndTime,
CURRENT_TIME);
- lvid->integrityType = LVID_INTEGRITY_TYPE_OPEN;
+ lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN);
lvid->descTag.descCRC = cpu_to_le16(
- crc_itu_t(0, (char *)lvid + sizeof(tag),
+ crc_itu_t(0, (char *)lvid + sizeof(struct tag),
le16_to_cpu(lvid->descTag.descCRCLength)));
lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
mark_buffer_dirty(bh);
+ sbi->s_lvid_dirty = 0;
}
static void udf_close_lvid(struct super_block *sb)
@@ -1773,10 +1774,6 @@ static void udf_close_lvid(struct super_block *sb)
return;
lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
-
- if (lvid->integrityType != LVID_INTEGRITY_TYPE_OPEN)
- return;
-
lvidiu = udf_sb_lvidiu(sbi);
lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
@@ -1790,11 +1787,12 @@ static void udf_close_lvid(struct super_block *sb)
lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
lvid->descTag.descCRC = cpu_to_le16(
- crc_itu_t(0, (char *)lvid + sizeof(tag),
+ crc_itu_t(0, (char *)lvid + sizeof(struct tag),
le16_to_cpu(lvid->descTag.descCRCLength)));
lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
mark_buffer_dirty(bh);
+ sbi->s_lvid_dirty = 0;
}
static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
@@ -1846,15 +1844,18 @@ static void udf_free_partition(struct udf_part_map *map)
static int udf_fill_super(struct super_block *sb, void *options, int silent)
{
int i;
+ int ret;
struct inode *inode = NULL;
struct udf_options uopt;
- kernel_lb_addr rootdir, fileset;
+ struct kernel_lb_addr rootdir, fileset;
struct udf_sb_info *sbi;
uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
uopt.uid = -1;
uopt.gid = -1;
uopt.umask = 0;
+ uopt.fmode = UDF_INVALID_MODE;
+ uopt.dmode = UDF_INVALID_MODE;
sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL);
if (!sbi)
@@ -1892,15 +1893,10 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
sbi->s_uid = uopt.uid;
sbi->s_gid = uopt.gid;
sbi->s_umask = uopt.umask;
+ sbi->s_fmode = uopt.fmode;
+ sbi->s_dmode = uopt.dmode;
sbi->s_nls_map = uopt.nls_map;
- /* Set the block size for all transfers */
- if (!sb_min_blocksize(sb, uopt.blocksize)) {
- udf_debug("Bad block size (%d)\n", uopt.blocksize);
- printk(KERN_ERR "udf: bad block size (%d)\n", uopt.blocksize);
- goto error_out;
- }
-
if (uopt.session == 0xFFFFFFFF)
sbi->s_session = udf_get_last_session(sb);
else
@@ -1908,18 +1904,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
udf_debug("Multi-session=%d\n", sbi->s_session);
- sbi->s_last_block = uopt.lastblock;
- sbi->s_anchor[0] = sbi->s_anchor[1] = 0;
- sbi->s_anchor[2] = uopt.anchor;
-
- if (udf_check_valid(sb, uopt.novrs, silent)) {
- /* read volume recognition sequences */
- printk(KERN_WARNING "UDF-fs: No VRS found\n");
- goto error_out;
- }
-
- udf_find_anchor(sb);
-
/* Fill in the rest of the superblock */
sb->s_op = &udf_sb_ops;
sb->s_export_op = &udf_export_ops;
@@ -1928,7 +1912,21 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
sb->s_magic = UDF_SUPER_MAGIC;
sb->s_time_gran = 1000;
- if (udf_load_sequence(sb, &fileset)) {
+ if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) {
+ ret = udf_load_vrs(sb, &uopt, silent, &fileset);
+ } else {
+ uopt.blocksize = bdev_hardsect_size(sb->s_bdev);
+ ret = udf_load_vrs(sb, &uopt, silent, &fileset);
+ if (!ret && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) {
+ if (!silent)
+ printk(KERN_NOTICE
+ "UDF-fs: Rescanning with blocksize "
+ "%d\n", UDF_DEFAULT_BLOCKSIZE);
+ uopt.blocksize = UDF_DEFAULT_BLOCKSIZE;
+ ret = udf_load_vrs(sb, &uopt, silent, &fileset);
+ }
+ }
+ if (!ret) {
printk(KERN_WARNING "UDF-fs: No partition found (1)\n");
goto error_out;
}
@@ -1978,7 +1976,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
}
if (!silent) {
- timestamp ts;
+ struct timestamp ts;
udf_time_to_disk_stamp(&ts, sbi->s_record_time);
udf_info("UDF: Mounting volume '%s', "
"timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
@@ -1991,7 +1989,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
/* Assign the root inode */
/* assign inodes by physical block number */
/* perhaps it's not extensible enough, but for now ... */
- inode = udf_iget(sb, rootdir);
+ inode = udf_iget(sb, &rootdir);
if (!inode) {
printk(KERN_ERR "UDF-fs: Error in udf_iget, block=%d, "
"partition=%d\n",
@@ -2081,11 +2079,31 @@ static void udf_put_super(struct super_block *sb)
sb->s_fs_info = NULL;
}
+static int udf_sync_fs(struct super_block *sb, int wait)
+{
+ struct udf_sb_info *sbi = UDF_SB(sb);
+
+ mutex_lock(&sbi->s_alloc_mutex);
+ if (sbi->s_lvid_dirty) {
+ /*
+ * Blockdevice will be synced later so we don't have to submit
+ * the buffer for IO
+ */
+ mark_buffer_dirty(sbi->s_lvid_bh);
+ sb->s_dirt = 0;
+ sbi->s_lvid_dirty = 0;
+ }
+ mutex_unlock(&sbi->s_alloc_mutex);
+
+ return 0;
+}
+
static int udf_statfs(struct dentry *dentry, struct kstatfs *buf)
{
struct super_block *sb = dentry->d_sb;
struct udf_sb_info *sbi = UDF_SB(sb);
struct logicalVolIntegrityDescImpUse *lvidiu;
+ u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
if (sbi->s_lvid_bh != NULL)
lvidiu = udf_sb_lvidiu(sbi);
@@ -2101,8 +2119,9 @@ static int udf_statfs(struct dentry *dentry, struct kstatfs *buf)
le32_to_cpu(lvidiu->numDirs)) : 0)
+ buf->f_bfree;
buf->f_ffree = buf->f_bfree;
- /* __kernel_fsid_t f_fsid */
buf->f_namelen = UDF_NAME_LEN - 2;
+ buf->f_fsid.val[0] = (u32)id;
+ buf->f_fsid.val[1] = (u32)(id >> 32);
return 0;
}
@@ -2114,7 +2133,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb,
unsigned int accum = 0;
int index;
int block = 0, newblock;
- kernel_lb_addr loc;
+ struct kernel_lb_addr loc;
uint32_t bytes;
uint8_t *ptr;
uint16_t ident;
@@ -2124,7 +2143,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb,
loc.logicalBlockNum = bitmap->s_extPosition;
loc.partitionReferenceNum = UDF_SB(sb)->s_partition;
- bh = udf_read_ptagged(sb, loc, 0, &ident);
+ bh = udf_read_ptagged(sb, &loc, 0, &ident);
if (!bh) {
printk(KERN_ERR "udf: udf_count_free failed\n");
@@ -2147,7 +2166,7 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb,
bytes -= cur_bytes;
if (bytes) {
brelse(bh);
- newblock = udf_get_lb_pblock(sb, loc, ++block);
+ newblock = udf_get_lb_pblock(sb, &loc, ++block);
bh = udf_tread(sb, newblock);
if (!bh) {
udf_debug("read failed\n");
@@ -2170,7 +2189,7 @@ static unsigned int udf_count_free_table(struct super_block *sb,
{
unsigned int accum = 0;
uint32_t elen;
- kernel_lb_addr eloc;
+ struct kernel_lb_addr eloc;
int8_t etype;
struct extent_position epos;
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
index 65e19b4f942..225527cdc88 100644
--- a/fs/udf/truncate.c
+++ b/fs/udf/truncate.c
@@ -28,10 +28,10 @@
#include "udf_sb.h"
static void extent_trunc(struct inode *inode, struct extent_position *epos,
- kernel_lb_addr eloc, int8_t etype, uint32_t elen,
+ struct kernel_lb_addr *eloc, int8_t etype, uint32_t elen,
uint32_t nelen)
{
- kernel_lb_addr neloc = {};
+ struct kernel_lb_addr neloc = {};
int last_block = (elen + inode->i_sb->s_blocksize - 1) >>
inode->i_sb->s_blocksize_bits;
int first_block = (nelen + inode->i_sb->s_blocksize - 1) >>
@@ -43,12 +43,12 @@ static void extent_trunc(struct inode *inode, struct extent_position *epos,
last_block);
etype = (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30);
} else
- neloc = eloc;
+ neloc = *eloc;
nelen = (etype << 30) | nelen;
}
if (elen != nelen) {
- udf_write_aext(inode, epos, neloc, nelen, 0);
+ udf_write_aext(inode, epos, &neloc, nelen, 0);
if (last_block - first_block > 0) {
if (etype == (EXT_RECORDED_ALLOCATED >> 30))
mark_inode_dirty(inode);
@@ -68,7 +68,7 @@ static void extent_trunc(struct inode *inode, struct extent_position *epos,
void udf_truncate_tail_extent(struct inode *inode)
{
struct extent_position epos = {};
- kernel_lb_addr eloc;
+ struct kernel_lb_addr eloc;
uint32_t elen, nelen;
uint64_t lbcount = 0;
int8_t etype = -1, netype;
@@ -83,9 +83,9 @@ void udf_truncate_tail_extent(struct inode *inode)
return;
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- adsize = sizeof(short_ad);
+ adsize = sizeof(struct short_ad);
else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
- adsize = sizeof(long_ad);
+ adsize = sizeof(struct long_ad);
else
BUG();
@@ -106,7 +106,7 @@ void udf_truncate_tail_extent(struct inode *inode)
(unsigned)elen);
nelen = elen - (lbcount - inode->i_size);
epos.offset -= adsize;
- extent_trunc(inode, &epos, eloc, etype, elen, nelen);
+ extent_trunc(inode, &epos, &eloc, etype, elen, nelen);
epos.offset += adsize;
if (udf_next_aext(inode, &epos, &eloc, &elen, 1) != -1)
printk(KERN_ERR "udf_truncate_tail_extent(): "
@@ -124,7 +124,7 @@ void udf_truncate_tail_extent(struct inode *inode)
void udf_discard_prealloc(struct inode *inode)
{
struct extent_position epos = { NULL, 0, {0, 0} };
- kernel_lb_addr eloc;
+ struct kernel_lb_addr eloc;
uint32_t elen;
uint64_t lbcount = 0;
int8_t etype = -1, netype;
@@ -136,9 +136,9 @@ void udf_discard_prealloc(struct inode *inode)
return;
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- adsize = sizeof(short_ad);
+ adsize = sizeof(struct short_ad);
else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
- adsize = sizeof(long_ad);
+ adsize = sizeof(struct long_ad);
else
adsize = 0;
@@ -152,7 +152,7 @@ void udf_discard_prealloc(struct inode *inode)
if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
epos.offset -= adsize;
lbcount -= elen;
- extent_trunc(inode, &epos, eloc, etype, elen, 0);
+ extent_trunc(inode, &epos, &eloc, etype, elen, 0);
if (!epos.bh) {
iinfo->i_lenAlloc =
epos.offset -
@@ -200,7 +200,7 @@ static void udf_update_alloc_ext_desc(struct inode *inode,
void udf_truncate_extents(struct inode *inode)
{
struct extent_position epos;
- kernel_lb_addr eloc, neloc = {};
+ struct kernel_lb_addr eloc, neloc = {};
uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc;
int8_t etype;
struct super_block *sb = inode->i_sb;
@@ -210,9 +210,9 @@ void udf_truncate_extents(struct inode *inode)
struct udf_inode_info *iinfo = UDF_I(inode);
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
- adsize = sizeof(short_ad);
+ adsize = sizeof(struct short_ad);
else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
- adsize = sizeof(long_ad);
+ adsize = sizeof(struct long_ad);
else
BUG();
@@ -221,7 +221,7 @@ void udf_truncate_extents(struct inode *inode)
(inode->i_size & (sb->s_blocksize - 1));
if (etype != -1) {
epos.offset -= adsize;
- extent_trunc(inode, &epos, eloc, etype, elen, byte_offset);
+ extent_trunc(inode, &epos, &eloc, etype, elen, byte_offset);
epos.offset += adsize;
if (byte_offset)
lenalloc = epos.offset;
@@ -236,12 +236,12 @@ void udf_truncate_extents(struct inode *inode)
while ((etype = udf_current_aext(inode, &epos, &eloc,
&elen, 0)) != -1) {
if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) {
- udf_write_aext(inode, &epos, neloc, nelen, 0);
+ udf_write_aext(inode, &epos, &neloc, nelen, 0);
if (indirect_ext_len) {
/* We managed to free all extents in the
* indirect extent - free it too */
BUG_ON(!epos.bh);
- udf_free_blocks(sb, inode, epos.block,
+ udf_free_blocks(sb, inode, &epos.block,
0, indirect_ext_len);
} else if (!epos.bh) {
iinfo->i_lenAlloc = lenalloc;
@@ -253,7 +253,7 @@ void udf_truncate_extents(struct inode *inode)
epos.offset = sizeof(struct allocExtDesc);
epos.block = eloc;
epos.bh = udf_tread(sb,
- udf_get_lb_pblock(sb, eloc, 0));
+ udf_get_lb_pblock(sb, &eloc, 0));
if (elen)
indirect_ext_len =
(elen + sb->s_blocksize - 1) >>
@@ -261,7 +261,7 @@ void udf_truncate_extents(struct inode *inode)
else
indirect_ext_len = 1;
} else {
- extent_trunc(inode, &epos, eloc, etype,
+ extent_trunc(inode, &epos, &eloc, etype,
elen, 0);
epos.offset += adsize;
}
@@ -269,7 +269,7 @@ void udf_truncate_extents(struct inode *inode)
if (indirect_ext_len) {
BUG_ON(!epos.bh);
- udf_free_blocks(sb, inode, epos.block, 0,
+ udf_free_blocks(sb, inode, &epos.block, 0,
indirect_ext_len);
} else if (!epos.bh) {
iinfo->i_lenAlloc = lenalloc;
@@ -278,7 +278,7 @@ void udf_truncate_extents(struct inode *inode)
udf_update_alloc_ext_desc(inode, &epos, lenalloc);
} else if (inode->i_size) {
if (byte_offset) {
- kernel_long_ad extent;
+ struct kernel_long_ad extent;
/*
* OK, there is not extent covering inode->i_size and
diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h
index 4f86b1d98a5..e58d1de4107 100644
--- a/fs/udf/udf_i.h
+++ b/fs/udf/udf_i.h
@@ -4,7 +4,7 @@
struct udf_inode_info {
struct timespec i_crtime;
/* Physical address of inode */
- kernel_lb_addr i_location;
+ struct kernel_lb_addr i_location;
__u64 i_unique;
__u32 i_lenEAttr;
__u32 i_lenAlloc;
@@ -17,8 +17,8 @@ struct udf_inode_info {
unsigned i_strat4096 : 1;
unsigned reserved : 26;
union {
- short_ad *i_sad;
- long_ad *i_lad;
+ struct short_ad *i_sad;
+ struct long_ad *i_lad;
__u8 *i_data;
} i_ext;
struct inode vfs_inode;
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 1c1c514a972..d113b72c276 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -30,6 +30,7 @@
#define UDF_FLAG_GID_SET 16
#define UDF_FLAG_SESSION_SET 17
#define UDF_FLAG_LASTBLOCK_SET 18
+#define UDF_FLAG_BLOCKSIZE_SET 19
#define UDF_PART_FLAG_UNALLOC_BITMAP 0x0001
#define UDF_PART_FLAG_UNALLOC_TABLE 0x0002
@@ -48,6 +49,8 @@
#define UDF_SPARABLE_MAP15 0x1522U
#define UDF_METADATA_MAP25 0x2511U
+#define UDF_INVALID_MODE ((mode_t)-1)
+
#pragma pack(1) /* XXX(hch): Why? This file just defines in-core structures */
struct udf_meta_data {
@@ -114,7 +117,7 @@ struct udf_sb_info {
/* Sector headers */
__s32 s_session;
- __u32 s_anchor[3];
+ __u32 s_anchor;
__u32 s_last_block;
struct buffer_head *s_lvid_bh;
@@ -123,6 +126,8 @@ struct udf_sb_info {
mode_t s_umask;
gid_t s_gid;
uid_t s_uid;
+ mode_t s_fmode;
+ mode_t s_dmode;
/* Root Info */
struct timespec s_record_time;
@@ -143,6 +148,8 @@ struct udf_sb_info {
struct inode *s_vat_inode;
struct mutex s_alloc_mutex;
+ /* Protected by s_alloc_mutex */
+ unsigned int s_lvid_dirty;
};
static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 8ec865de5f1..cac51b77a5d 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -62,10 +62,8 @@ static inline size_t udf_ext0_offset(struct inode *inode)
return 0;
}
-#define udf_get_lb_pblock(sb,loc,offset) udf_get_pblock((sb), (loc).logicalBlockNum, (loc).partitionReferenceNum, (offset))
-
/* computes tag checksum */
-u8 udf_tag_checksum(const tag *t);
+u8 udf_tag_checksum(const struct tag *t);
struct dentry;
struct inode;
@@ -95,7 +93,7 @@ struct udf_vds_record {
};
struct generic_desc {
- tag descTag;
+ struct tag descTag;
__le32 volDescSeqNum;
};
@@ -108,11 +106,22 @@ struct ustr {
struct extent_position {
struct buffer_head *bh;
uint32_t offset;
- kernel_lb_addr block;
+ struct kernel_lb_addr block;
};
/* super.c */
extern void udf_warning(struct super_block *, const char *, const char *, ...);
+static inline void udf_updated_lvid(struct super_block *sb)
+{
+ struct buffer_head *bh = UDF_SB(sb)->s_lvid_bh;
+
+ BUG_ON(!bh);
+ WARN_ON_ONCE(((struct logicalVolIntegrityDesc *)
+ bh->b_data)->integrityType !=
+ cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN));
+ sb->s_dirt = 1;
+ UDF_SB(sb)->s_lvid_dirty = 1;
+}
/* namei.c */
extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,
@@ -124,7 +133,7 @@ extern int udf_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
/* inode.c */
-extern struct inode *udf_iget(struct super_block *, kernel_lb_addr);
+extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *);
extern int udf_sync_inode(struct inode *);
extern void udf_expand_file_adinicb(struct inode *, int, int *);
extern struct buffer_head *udf_expand_dir_adinicb(struct inode *, int *, int *);
@@ -136,19 +145,19 @@ extern void udf_clear_inode(struct inode *);
extern int udf_write_inode(struct inode *, int);
extern long udf_block_map(struct inode *, sector_t);
extern int udf_extend_file(struct inode *, struct extent_position *,
- kernel_long_ad *, sector_t);
+ struct kernel_long_ad *, sector_t);
extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *,
- kernel_lb_addr *, uint32_t *, sector_t *);
+ struct kernel_lb_addr *, uint32_t *, sector_t *);
extern int8_t udf_add_aext(struct inode *, struct extent_position *,
- kernel_lb_addr, uint32_t, int);
+ struct kernel_lb_addr *, uint32_t, int);
extern int8_t udf_write_aext(struct inode *, struct extent_position *,
- kernel_lb_addr, uint32_t, int);
+ struct kernel_lb_addr *, uint32_t, int);
extern int8_t udf_delete_aext(struct inode *, struct extent_position,
- kernel_lb_addr, uint32_t);
+ struct kernel_lb_addr, uint32_t);
extern int8_t udf_next_aext(struct inode *, struct extent_position *,
- kernel_lb_addr *, uint32_t *, int);
+ struct kernel_lb_addr *, uint32_t *, int);
extern int8_t udf_current_aext(struct inode *, struct extent_position *,
- kernel_lb_addr *, uint32_t *, int);
+ struct kernel_lb_addr *, uint32_t *, int);
/* misc.c */
extern struct buffer_head *udf_tgetblk(struct super_block *, int);
@@ -160,7 +169,7 @@ extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t,
extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t,
uint32_t, uint16_t *);
extern struct buffer_head *udf_read_ptagged(struct super_block *,
- kernel_lb_addr, uint32_t,
+ struct kernel_lb_addr *, uint32_t,
uint16_t *);
extern void udf_update_tag(char *, int);
extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int);
@@ -182,6 +191,14 @@ extern uint32_t udf_get_pblock_meta25(struct super_block *, uint32_t, uint16_t,
uint32_t);
extern int udf_relocate_blocks(struct super_block *, long, long *);
+static inline uint32_t
+udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc,
+ uint32_t offset)
+{
+ return udf_get_pblock(sb, loc->logicalBlockNum,
+ loc->partitionReferenceNum, offset);
+}
+
/* unicode.c */
extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int);
extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *,
@@ -200,7 +217,7 @@ extern void udf_truncate_extents(struct inode *);
/* balloc.c */
extern void udf_free_blocks(struct super_block *, struct inode *,
- kernel_lb_addr, uint32_t, uint32_t);
+ struct kernel_lb_addr *, uint32_t, uint32_t);
extern int udf_prealloc_blocks(struct super_block *, struct inode *, uint16_t,
uint32_t, uint32_t);
extern int udf_new_block(struct super_block *, struct inode *, uint16_t,
@@ -214,16 +231,16 @@ extern struct fileIdentDesc *udf_fileident_read(struct inode *, loff_t *,
struct udf_fileident_bh *,
struct fileIdentDesc *,
struct extent_position *,
- kernel_lb_addr *, uint32_t *,
+ struct kernel_lb_addr *, uint32_t *,
sector_t *);
extern struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize,
int *offset);
-extern long_ad *udf_get_filelongad(uint8_t *, int, uint32_t *, int);
-extern short_ad *udf_get_fileshortad(uint8_t *, int, uint32_t *, int);
+extern struct long_ad *udf_get_filelongad(uint8_t *, int, uint32_t *, int);
+extern struct short_ad *udf_get_fileshortad(uint8_t *, int, uint32_t *, int);
/* udftime.c */
extern struct timespec *udf_disk_stamp_to_time(struct timespec *dest,
- timestamp src);
-extern timestamp *udf_time_to_disk_stamp(timestamp *dest, struct timespec src);
+ struct timestamp src);
+extern struct timestamp *udf_time_to_disk_stamp(struct timestamp *dest, struct timespec src);
#endif /* __UDF_DECL_H */
diff --git a/fs/udf/udfend.h b/fs/udf/udfend.h
index 489f52fb428..6a9f3a9cc42 100644
--- a/fs/udf/udfend.h
+++ b/fs/udf/udfend.h
@@ -4,9 +4,9 @@
#include <asm/byteorder.h>
#include <linux/string.h>
-static inline kernel_lb_addr lelb_to_cpu(lb_addr in)
+static inline struct kernel_lb_addr lelb_to_cpu(struct lb_addr in)
{
- kernel_lb_addr out;
+ struct kernel_lb_addr out;
out.logicalBlockNum = le32_to_cpu(in.logicalBlockNum);
out.partitionReferenceNum = le16_to_cpu(in.partitionReferenceNum);
@@ -14,9 +14,9 @@ static inline kernel_lb_addr lelb_to_cpu(lb_addr in)
return out;
}
-static inline lb_addr cpu_to_lelb(kernel_lb_addr in)
+static inline struct lb_addr cpu_to_lelb(struct kernel_lb_addr in)
{
- lb_addr out;
+ struct lb_addr out;
out.logicalBlockNum = cpu_to_le32(in.logicalBlockNum);
out.partitionReferenceNum = cpu_to_le16(in.partitionReferenceNum);
@@ -24,9 +24,9 @@ static inline lb_addr cpu_to_lelb(kernel_lb_addr in)
return out;
}
-static inline short_ad lesa_to_cpu(short_ad in)
+static inline struct short_ad lesa_to_cpu(struct short_ad in)
{
- short_ad out;
+ struct short_ad out;
out.extLength = le32_to_cpu(in.extLength);
out.extPosition = le32_to_cpu(in.extPosition);
@@ -34,9 +34,9 @@ static inline short_ad lesa_to_cpu(short_ad in)
return out;
}
-static inline short_ad cpu_to_lesa(short_ad in)
+static inline struct short_ad cpu_to_lesa(struct short_ad in)
{
- short_ad out;
+ struct short_ad out;
out.extLength = cpu_to_le32(in.extLength);
out.extPosition = cpu_to_le32(in.extPosition);
@@ -44,9 +44,9 @@ static inline short_ad cpu_to_lesa(short_ad in)
return out;
}
-static inline kernel_long_ad lela_to_cpu(long_ad in)
+static inline struct kernel_long_ad lela_to_cpu(struct long_ad in)
{
- kernel_long_ad out;
+ struct kernel_long_ad out;
out.extLength = le32_to_cpu(in.extLength);
out.extLocation = lelb_to_cpu(in.extLocation);
@@ -54,9 +54,9 @@ static inline kernel_long_ad lela_to_cpu(long_ad in)
return out;
}
-static inline long_ad cpu_to_lela(kernel_long_ad in)
+static inline struct long_ad cpu_to_lela(struct kernel_long_ad in)
{
- long_ad out;
+ struct long_ad out;
out.extLength = cpu_to_le32(in.extLength);
out.extLocation = cpu_to_lelb(in.extLocation);
@@ -64,9 +64,9 @@ static inline long_ad cpu_to_lela(kernel_long_ad in)
return out;
}
-static inline kernel_extent_ad leea_to_cpu(extent_ad in)
+static inline struct kernel_extent_ad leea_to_cpu(struct extent_ad in)
{
- kernel_extent_ad out;
+ struct kernel_extent_ad out;
out.extLength = le32_to_cpu(in.extLength);
out.extLocation = le32_to_cpu(in.extLocation);
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c
index 5f811655c9b..b8c828c4d20 100644
--- a/fs/udf/udftime.c
+++ b/fs/udf/udftime.c
@@ -85,7 +85,8 @@ extern struct timezone sys_tz;
#define SECS_PER_HOUR (60 * 60)
#define SECS_PER_DAY (SECS_PER_HOUR * 24)
-struct timespec *udf_disk_stamp_to_time(struct timespec *dest, timestamp src)
+struct timespec *
+udf_disk_stamp_to_time(struct timespec *dest, struct timestamp src)
{
int yday;
u16 typeAndTimezone = le16_to_cpu(src.typeAndTimezone);
@@ -116,7 +117,8 @@ struct timespec *udf_disk_stamp_to_time(struct timespec *dest, timestamp src)
return dest;
}
-timestamp *udf_time_to_disk_stamp(timestamp *dest, struct timespec ts)
+struct timestamp *
+udf_time_to_disk_stamp(struct timestamp *dest, struct timespec ts)
{
long int days, rem, y;
const unsigned short int *ip;
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c
index 9fdf8c93c58..cefa8c8913e 100644
--- a/fs/udf/unicode.c
+++ b/fs/udf/unicode.c
@@ -254,7 +254,7 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o,
{
const uint8_t *ocu;
uint8_t cmp_id, ocu_len;
- int i;
+ int i, len;
ocu_len = ocu_i->u_len;
@@ -279,8 +279,13 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o,
if (cmp_id == 16)
c = (c << 8) | ocu[i++];
- utf_o->u_len += nls->uni2char(c, &utf_o->u_name[utf_o->u_len],
- UDF_NAME_LEN - utf_o->u_len);
+ len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len],
+ UDF_NAME_LEN - utf_o->u_len);
+ /* Valid character? */
+ if (len >= 0)
+ utf_o->u_len += len;
+ else
+ utf_o->u_name[utf_o->u_len++] = '?';
}
utf_o->u_cmpID = 8;
@@ -290,7 +295,8 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o,
static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni,
int length)
{
- unsigned len, i, max_val;
+ int len;
+ unsigned i, max_val;
uint16_t uni_char;
int u_len;
@@ -302,8 +308,13 @@ try_again:
u_len = 0U;
for (i = 0U; i < uni->u_len; i++) {
len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char);
- if (len <= 0)
+ if (!len)
continue;
+ /* Invalid character, deal with it */
+ if (len < 0) {
+ len = 1;
+ uni_char = '?';
+ }
if (uni_char > max_val) {
max_val = 0xffffU;
@@ -324,34 +335,43 @@ try_again:
int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname,
int flen)
{
- struct ustr filename, unifilename;
- int len;
+ struct ustr *filename, *unifilename;
+ int len = 0;
- if (udf_build_ustr_exact(&unifilename, sname, flen))
+ filename = kmalloc(sizeof(struct ustr), GFP_NOFS);
+ if (!filename)
return 0;
+ unifilename = kmalloc(sizeof(struct ustr), GFP_NOFS);
+ if (!unifilename)
+ goto out1;
+
+ if (udf_build_ustr_exact(unifilename, sname, flen))
+ goto out2;
+
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) {
- if (!udf_CS0toUTF8(&filename, &unifilename)) {
+ if (!udf_CS0toUTF8(filename, unifilename)) {
udf_debug("Failed in udf_get_filename: sname = %s\n",
sname);
- return 0;
+ goto out2;
}
} else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) {
- if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, &filename,
- &unifilename)) {
+ if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, filename,
+ unifilename)) {
udf_debug("Failed in udf_get_filename: sname = %s\n",
sname);
- return 0;
+ goto out2;
}
} else
- return 0;
-
- len = udf_translate_to_linux(dname, filename.u_name, filename.u_len,
- unifilename.u_name, unifilename.u_len);
- if (len)
- return len;
-
- return 0;
+ goto out2;
+
+ len = udf_translate_to_linux(dname, filename->u_name, filename->u_len,
+ unifilename->u_name, unifilename->u_len);
+out2:
+ kfree(unifilename);
+out1:
+ kfree(filename);
+ return len;
}
int udf_put_filename(struct super_block *sb, const uint8_t *sname,
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index c3dc491fff8..60f107e47fe 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -33,6 +33,7 @@ xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \
xfs_qm_syscalls.o \
xfs_qm_bhv.o \
xfs_qm.o)
+xfs-$(CONFIG_XFS_QUOTA) += linux-2.6/xfs_quotaops.o
ifeq ($(CONFIG_XFS_QUOTA),y)
xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o
diff --git a/fs/xfs/linux-2.6/mutex.h b/fs/xfs/linux-2.6/mutex.h
deleted file mode 100644
index 2a88d56c4dc..00000000000
--- a/fs/xfs/linux-2.6/mutex.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 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.
- *
- * 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. See the
- * GNU 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_SUPPORT_MUTEX_H__
-#define __XFS_SUPPORT_MUTEX_H__
-
-#include <linux/mutex.h>
-
-typedef struct mutex mutex_t;
-
-#endif /* __XFS_SUPPORT_MUTEX_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index de3a198f771..7ec89fc05b2 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -153,23 +153,6 @@ xfs_find_bdev_for_inode(
}
/*
- * Schedule IO completion handling on a xfsdatad if this was
- * the final hold on this ioend. If we are asked to wait,
- * flush the workqueue.
- */
-STATIC void
-xfs_finish_ioend(
- xfs_ioend_t *ioend,
- int wait)
-{
- if (atomic_dec_and_test(&ioend->io_remaining)) {
- queue_work(xfsdatad_workqueue, &ioend->io_work);
- if (wait)
- flush_workqueue(xfsdatad_workqueue);
- }
-}
-
-/*
* We're now finished for good with this ioend structure.
* Update the page state via the associated buffer_heads,
* release holds on the inode and bio, and finally free
@@ -310,6 +293,27 @@ xfs_end_bio_read(
}
/*
+ * Schedule IO completion handling on a xfsdatad if this was
+ * the final hold on this ioend. If we are asked to wait,
+ * flush the workqueue.
+ */
+STATIC void
+xfs_finish_ioend(
+ xfs_ioend_t *ioend,
+ int wait)
+{
+ if (atomic_dec_and_test(&ioend->io_remaining)) {
+ struct workqueue_struct *wq = xfsdatad_workqueue;
+ if (ioend->io_work.func == xfs_end_bio_unwritten)
+ wq = xfsconvertd_workqueue;
+
+ queue_work(wq, &ioend->io_work);
+ if (wait)
+ flush_workqueue(wq);
+ }
+}
+
+/*
* Allocate and initialise an IO completion structure.
* We need to track unwritten extent write completion here initially.
* We'll need to extend this for updating the ondisk inode size later
@@ -1623,4 +1627,5 @@ const struct address_space_operations xfs_address_space_operations = {
.bmap = xfs_vm_bmap,
.direct_IO = xfs_vm_direct_IO,
.migratepage = buffer_migrate_page,
+ .is_partially_uptodate = block_is_partially_uptodate,
};
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 1dd52884975..221b3e66cee 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -19,6 +19,7 @@
#define __XFS_AOPS_H__
extern struct workqueue_struct *xfsdatad_workqueue;
+extern struct workqueue_struct *xfsconvertd_workqueue;
extern mempool_t *xfs_ioend_pool;
/*
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index aa1016bb913..e28800a9f2b 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -51,6 +51,7 @@ static struct shrinker xfs_buf_shake = {
static struct workqueue_struct *xfslogd_workqueue;
struct workqueue_struct *xfsdatad_workqueue;
+struct workqueue_struct *xfsconvertd_workqueue;
#ifdef XFS_BUF_TRACE
void
@@ -1775,6 +1776,7 @@ xfs_flush_buftarg(
xfs_buf_t *bp, *n;
int pincount = 0;
+ xfs_buf_runall_queues(xfsconvertd_workqueue);
xfs_buf_runall_queues(xfsdatad_workqueue);
xfs_buf_runall_queues(xfslogd_workqueue);
@@ -1831,9 +1833,15 @@ xfs_buf_init(void)
if (!xfsdatad_workqueue)
goto out_destroy_xfslogd_workqueue;
+ xfsconvertd_workqueue = create_workqueue("xfsconvertd");
+ if (!xfsconvertd_workqueue)
+ goto out_destroy_xfsdatad_workqueue;
+
register_shrinker(&xfs_buf_shake);
return 0;
+ out_destroy_xfsdatad_workqueue:
+ destroy_workqueue(xfsdatad_workqueue);
out_destroy_xfslogd_workqueue:
destroy_workqueue(xfslogd_workqueue);
out_free_buf_zone:
@@ -1849,6 +1857,7 @@ void
xfs_buf_terminate(void)
{
unregister_shrinker(&xfs_buf_shake);
+ destroy_workqueue(xfsconvertd_workqueue);
destroy_workqueue(xfsdatad_workqueue);
destroy_workqueue(xfslogd_workqueue);
kmem_zone_destroy(xfs_buf_zone);
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index 5aeb7777696..08be36d7326 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -74,14 +74,14 @@ xfs_flush_pages(
if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
xfs_iflags_clear(ip, XFS_ITRUNCATED);
- ret = filemap_fdatawrite(mapping);
- if (flags & XFS_B_ASYNC)
- return -ret;
- ret2 = filemap_fdatawait(mapping);
- if (!ret)
- ret = ret2;
+ ret = -filemap_fdatawrite(mapping);
}
- return -ret;
+ if (flags & XFS_B_ASYNC)
+ return ret;
+ ret2 = xfs_wait_on_pages(ip, first, last);
+ if (!ret)
+ ret = ret2;
+ return ret;
}
int
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 4bd112313f3..d0b499418a7 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -34,6 +34,7 @@
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
+#include "xfs_ioctl.h"
#include "xfs_btree.h"
#include "xfs_ialloc.h"
#include "xfs_rtalloc.h"
@@ -78,92 +79,74 @@ xfs_find_handle(
int hsize;
xfs_handle_t handle;
struct inode *inode;
+ struct file *file = NULL;
+ struct path path;
+ int error;
+ struct xfs_inode *ip;
- memset((char *)&handle, 0, sizeof(handle));
-
- switch (cmd) {
- case XFS_IOC_PATH_TO_FSHANDLE:
- case XFS_IOC_PATH_TO_HANDLE: {
- struct path path;
- int error = user_lpath((const char __user *)hreq->path, &path);
+ if (cmd == XFS_IOC_FD_TO_HANDLE) {
+ file = fget(hreq->fd);
+ if (!file)
+ return -EBADF;
+ inode = file->f_path.dentry->d_inode;
+ } else {
+ error = user_lpath((const char __user *)hreq->path, &path);
if (error)
return error;
-
- ASSERT(path.dentry);
- ASSERT(path.dentry->d_inode);
- inode = igrab(path.dentry->d_inode);
- path_put(&path);
- break;
+ inode = path.dentry->d_inode;
}
+ ip = XFS_I(inode);
- case XFS_IOC_FD_TO_HANDLE: {
- struct file *file;
-
- file = fget(hreq->fd);
- if (!file)
- return -EBADF;
+ /*
+ * We can only generate handles for inodes residing on a XFS filesystem,
+ * and only for regular files, directories or symbolic links.
+ */
+ error = -EINVAL;
+ if (inode->i_sb->s_magic != XFS_SB_MAGIC)
+ goto out_put;
- ASSERT(file->f_path.dentry);
- ASSERT(file->f_path.dentry->d_inode);
- inode = igrab(file->f_path.dentry->d_inode);
- fput(file);
- break;
- }
+ error = -EBADF;
+ if (!S_ISREG(inode->i_mode) &&
+ !S_ISDIR(inode->i_mode) &&
+ !S_ISLNK(inode->i_mode))
+ goto out_put;
- default:
- ASSERT(0);
- return -XFS_ERROR(EINVAL);
- }
- if (inode->i_sb->s_magic != XFS_SB_MAGIC) {
- /* we're not in XFS anymore, Toto */
- iput(inode);
- return -XFS_ERROR(EINVAL);
- }
+ memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
- switch (inode->i_mode & S_IFMT) {
- case S_IFREG:
- case S_IFDIR:
- case S_IFLNK:
- break;
- default:
- iput(inode);
- return -XFS_ERROR(EBADF);
- }
-
- /* now we can grab the fsid */
- memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid,
- sizeof(xfs_fsid_t));
- hsize = sizeof(xfs_fsid_t);
-
- if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
- xfs_inode_t *ip = XFS_I(inode);
+ if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
+ /*
+ * This handle only contains an fsid, zero the rest.
+ */
+ memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
+ hsize = sizeof(xfs_fsid_t);
+ } else {
int lock_mode;
- /* need to get access to the xfs_inode to read the generation */
lock_mode = xfs_ilock_map_shared(ip);
-
- /* fill in fid section of handle from inode */
handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
sizeof(handle.ha_fid.fid_len);
handle.ha_fid.fid_pad = 0;
handle.ha_fid.fid_gen = ip->i_d.di_gen;
handle.ha_fid.fid_ino = ip->i_ino;
-
xfs_iunlock_map_shared(ip, lock_mode);
hsize = XFS_HSIZE(handle);
}
- /* now copy our handle into the user buffer & write out the size */
+ error = -EFAULT;
if (copy_to_user(hreq->ohandle, &handle, hsize) ||
- copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) {
- iput(inode);
- return -XFS_ERROR(EFAULT);
- }
+ copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
+ goto out_put;
- iput(inode);
- return 0;
+ error = 0;
+
+ out_put:
+ if (cmd == XFS_IOC_FD_TO_HANDLE)
+ fput(file);
+ else
+ path_put(&path);
+ return error;
}
/*
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 2940612e3ae..6075382336d 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -211,8 +211,13 @@ xfs_vn_mknod(
* Irix uses Missed'em'V split, but doesn't want to see
* the upper 5 bits of (14bit) major.
*/
- if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff))
- return -EINVAL;
+ if (S_ISCHR(mode) || S_ISBLK(mode)) {
+ if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff))
+ return -EINVAL;
+ rdev = sysv_encode_dev(rdev);
+ } else {
+ rdev = 0;
+ }
if (test_default_acl && test_default_acl(dir)) {
if (!_ACL_ALLOC(default_acl)) {
@@ -224,28 +229,11 @@ xfs_vn_mknod(
}
}
- xfs_dentry_to_name(&name, dentry);
-
if (IS_POSIXACL(dir) && !default_acl)
mode &= ~current_umask();
- switch (mode & S_IFMT) {
- case S_IFCHR:
- case S_IFBLK:
- case S_IFIFO:
- case S_IFSOCK:
- rdev = sysv_encode_dev(rdev);
- case S_IFREG:
- error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip, NULL);
- break;
- case S_IFDIR:
- error = xfs_mkdir(XFS_I(dir), &name, mode, &ip, NULL);
- break;
- default:
- error = EINVAL;
- break;
- }
-
+ xfs_dentry_to_name(&name, dentry);
+ error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip, NULL);
if (unlikely(error))
goto out_free_acl;
@@ -553,9 +541,6 @@ xfs_vn_getattr(
stat->uid = ip->i_d.di_uid;
stat->gid = ip->i_d.di_gid;
stat->ino = ip->i_ino;
-#if XFS_BIG_INUMS
- stat->ino += mp->m_inoadd;
-#endif
stat->atime = inode->i_atime;
stat->mtime.tv_sec = ip->i_d.di_mtime.t_sec;
stat->mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 507492d6dcc..f65a53f8752 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -38,7 +38,6 @@
#include <kmem.h>
#include <mrlock.h>
#include <sv.h>
-#include <mutex.h>
#include <time.h>
#include <support/ktrace.h>
@@ -51,6 +50,7 @@
#include <linux/blkdev.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/file.h>
#include <linux/swap.h>
#include <linux/errno.h>
@@ -147,17 +147,6 @@
#define SYNCHRONIZE() barrier()
#define __return_address __builtin_return_address(0)
-/*
- * IRIX (BSD) quotactl makes use of separate commands for user/group,
- * whereas on Linux the syscall encodes this information into the cmd
- * field (see the QCMD macro in quota.h). These macros help keep the
- * code portable - they are not visible from the syscall interface.
- */
-#define Q_XSETGQLIM XQM_CMD(8) /* set groups disk limits */
-#define Q_XGETGQUOTA XQM_CMD(9) /* get groups disk limits */
-#define Q_XSETPQLIM XQM_CMD(10) /* set projects disk limits */
-#define Q_XGETPQUOTA XQM_CMD(11) /* get projects disk limits */
-
#define dfltprid 0
#define MAXPATHLEN 1024
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 7e90daa0d1d..9142192ccbe 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -751,10 +751,26 @@ start:
goto relock;
}
} else {
+ int enospc = 0;
+ ssize_t ret2 = 0;
+
+write_retry:
xfs_rw_enter_trace(XFS_WRITE_ENTER, xip, (void *)iovp, segs,
*offset, ioflags);
- ret = generic_file_buffered_write(iocb, iovp, segs,
+ ret2 = generic_file_buffered_write(iocb, iovp, segs,
pos, offset, count, ret);
+ /*
+ * if we just got an ENOSPC, flush the inode now we
+ * aren't holding any page locks and retry *once*
+ */
+ if (ret2 == -ENOSPC && !enospc) {
+ error = xfs_flush_pages(xip, 0, -1, 0, FI_NONE);
+ if (error)
+ goto out_unlock_internal;
+ enospc = 1;
+ goto write_retry;
+ }
+ ret = ret2;
}
current->backing_dev_info = NULL;
diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/linux-2.6/xfs_quotaops.c
new file mode 100644
index 00000000000..94d9a633d3d
--- /dev/null
+++ b/fs/xfs/linux-2.6/xfs_quotaops.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2008, Christoph Hellwig
+ * 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.
+ *
+ * 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. See the
+ * GNU 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 the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "xfs.h"
+#include "xfs_dmapi.h"
+#include "xfs_sb.h"
+#include "xfs_inum.h"
+#include "xfs_ag.h"
+#include "xfs_mount.h"
+#include "xfs_quota.h"
+#include "xfs_log.h"
+#include "xfs_trans.h"
+#include "xfs_bmap_btree.h"
+#include "xfs_inode.h"
+#include "quota/xfs_qm.h"
+#include <linux/quota.h>
+
+
+STATIC int
+xfs_quota_type(int type)
+{
+ switch (type) {
+ case USRQUOTA:
+ return XFS_DQ_USER;
+ case GRPQUOTA:
+ return XFS_DQ_GROUP;
+ default:
+ return XFS_DQ_PROJ;
+ }
+}
+
+STATIC int
+xfs_fs_quota_sync(
+ struct super_block *sb,
+ int type)
+{
+ struct xfs_mount *mp = XFS_M(sb);
+
+ if (!XFS_IS_QUOTA_RUNNING(mp))
+ return -ENOSYS;
+ return -xfs_sync_inodes(mp, SYNC_DELWRI);
+}
+
+STATIC int
+xfs_fs_get_xstate(
+ struct super_block *sb,
+ struct fs_quota_stat *fqs)
+{
+ struct xfs_mount *mp = XFS_M(sb);
+
+ if (!XFS_IS_QUOTA_RUNNING(mp))
+ return -ENOSYS;
+ return -xfs_qm_scall_getqstat(mp, fqs);
+}
+
+STATIC int
+xfs_fs_set_xstate(
+ struct super_block *sb,
+ unsigned int uflags,
+ int op)
+{
+ struct xfs_mount *mp = XFS_M(sb);
+ unsigned int flags = 0;
+
+ if (sb->s_flags & MS_RDONLY)
+ return -EROFS;
+ if (!XFS_IS_QUOTA_RUNNING(mp))
+ return -ENOSYS;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (uflags & XFS_QUOTA_UDQ_ACCT)
+ flags |= XFS_UQUOTA_ACCT;
+ if (uflags & XFS_QUOTA_PDQ_ACCT)
+ flags |= XFS_PQUOTA_ACCT;
+ if (uflags & XFS_QUOTA_GDQ_ACCT)
+ flags |= XFS_GQUOTA_ACCT;
+ if (uflags & XFS_QUOTA_UDQ_ENFD)
+ flags |= XFS_UQUOTA_ENFD;
+ if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD))
+ flags |= XFS_OQUOTA_ENFD;
+
+ switch (op) {
+ case Q_XQUOTAON:
+ return -xfs_qm_scall_quotaon(mp, flags);
+ case Q_XQUOTAOFF:
+ if (!XFS_IS_QUOTA_ON(mp))
+ return -EINVAL;
+ return -xfs_qm_scall_quotaoff(mp, flags);
+ case Q_XQUOTARM:
+ if (XFS_IS_QUOTA_ON(mp))
+ return -EINVAL;
+ return -xfs_qm_scall_trunc_qfiles(mp, flags);
+ }
+
+ return -EINVAL;
+}
+
+STATIC int
+xfs_fs_get_xquota(
+ struct super_block *sb,
+ int type,
+ qid_t id,
+ struct fs_disk_quota *fdq)
+{
+ struct xfs_mount *mp = XFS_M(sb);
+
+ if (!XFS_IS_QUOTA_RUNNING(mp))
+ return -ENOSYS;
+ if (!XFS_IS_QUOTA_ON(mp))
+ return -ESRCH;
+
+ return -xfs_qm_scall_getquota(mp, id, xfs_quota_type(type), fdq);
+}
+
+STATIC int
+xfs_fs_set_xquota(
+ struct super_block *sb,
+ int type,
+ qid_t id,
+ struct fs_disk_quota *fdq)
+{
+ struct xfs_mount *mp = XFS_M(sb);
+
+ if (sb->s_flags & MS_RDONLY)
+ return -EROFS;
+ if (!XFS_IS_QUOTA_RUNNING(mp))
+ return -ENOSYS;
+ if (!XFS_IS_QUOTA_ON(mp))
+ return -ESRCH;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ return -xfs_qm_scall_setqlim(mp, id, xfs_quota_type(type), fdq);
+}
+
+struct quotactl_ops xfs_quotactl_operations = {
+ .quota_sync = xfs_fs_quota_sync,
+ .get_xstate = xfs_fs_get_xstate,
+ .set_xstate = xfs_fs_set_xstate,
+ .get_xquota = xfs_fs_get_xquota,
+ .set_xquota = xfs_fs_set_xquota,
+};
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 32ae5028e96..bb685269f83 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -68,7 +68,6 @@
#include <linux/freezer.h>
#include <linux/parser.h>
-static struct quotactl_ops xfs_quotactl_operations;
static struct super_operations xfs_super_operations;
static kmem_zone_t *xfs_ioend_zone;
mempool_t *xfs_ioend_pool;
@@ -79,7 +78,6 @@ mempool_t *xfs_ioend_pool;
#define MNTOPT_RTDEV "rtdev" /* realtime I/O device */
#define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */
#define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */
-#define MNTOPT_INO64 "ino64" /* force inodes into 64-bit range */
#define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */
#define MNTOPT_SWALLOC "swalloc" /* turn on stripe width allocation */
#define MNTOPT_SUNIT "sunit" /* data volume stripe unit */
@@ -180,7 +178,7 @@ xfs_parseargs(
int dswidth = 0;
int iosize = 0;
int dmapi_implies_ikeep = 1;
- uchar_t iosizelog = 0;
+ __uint8_t iosizelog = 0;
/*
* Copy binary VFS mount flags we are interested in.
@@ -291,16 +289,6 @@ xfs_parseargs(
mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC;
} else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
mp->m_flags |= XFS_MOUNT_NORECOVERY;
- } else if (!strcmp(this_char, MNTOPT_INO64)) {
-#if XFS_BIG_INUMS
- mp->m_flags |= XFS_MOUNT_INO64;
- mp->m_inoadd = XFS_INO64_OFFSET;
-#else
- cmn_err(CE_WARN,
- "XFS: %s option not allowed on this system",
- this_char);
- return EINVAL;
-#endif
} else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
mp->m_flags |= XFS_MOUNT_NOALIGN;
} else if (!strcmp(this_char, MNTOPT_SWALLOC)) {
@@ -529,7 +517,6 @@ xfs_showargs(
/* the few simple ones we can get from the mount struct */
{ XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP },
{ XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC },
- { XFS_MOUNT_INO64, "," MNTOPT_INO64 },
{ XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN },
{ XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC },
{ XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID },
@@ -634,7 +621,7 @@ xfs_max_file_offset(
return (((__uint64_t)pagefactor) << bitshift) - 1;
}
-int
+STATIC int
xfs_blkdev_get(
xfs_mount_t *mp,
const char *name,
@@ -651,7 +638,7 @@ xfs_blkdev_get(
return -error;
}
-void
+STATIC void
xfs_blkdev_put(
struct block_device *bdev)
{
@@ -872,7 +859,7 @@ xfsaild_wakeup(
wake_up_process(ailp->xa_task);
}
-int
+STATIC int
xfsaild(
void *data)
{
@@ -990,26 +977,57 @@ xfs_fs_write_inode(
int sync)
{
struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
int error = 0;
- int flags = 0;
xfs_itrace_entry(ip);
+
+ if (XFS_FORCED_SHUTDOWN(mp))
+ return XFS_ERROR(EIO);
+
if (sync) {
error = xfs_wait_on_pages(ip, 0, -1);
if (error)
- goto out_error;
- flags |= FLUSH_SYNC;
+ goto out;
}
- error = xfs_inode_flush(ip, flags);
-out_error:
+ /*
+ * Bypass inodes which have already been cleaned by
+ * the inode flush clustering code inside xfs_iflush
+ */
+ if (xfs_inode_clean(ip))
+ goto out;
+
+ /*
+ * We make this non-blocking if the inode is contended, return
+ * EAGAIN to indicate to the caller that they did not succeed.
+ * This prevents the flush path from blocking on inodes inside
+ * another operation right now, they get caught later by xfs_sync.
+ */
+ if (sync) {
+ xfs_ilock(ip, XFS_ILOCK_SHARED);
+ xfs_iflock(ip);
+
+ error = xfs_iflush(ip, XFS_IFLUSH_SYNC);
+ } else {
+ error = EAGAIN;
+ if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED))
+ goto out;
+ if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip))
+ goto out_unlock;
+
+ error = xfs_iflush(ip, XFS_IFLUSH_ASYNC_NOBLOCK);
+ }
+
+ out_unlock:
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+ out:
/*
* if we failed to write out the inode then mark
* it dirty again so we'll try again later.
*/
if (error)
xfs_mark_inode_dirty_sync(ip);
-
return -error;
}
@@ -1169,18 +1187,12 @@ xfs_fs_statfs(
statp->f_bfree = statp->f_bavail =
sbp->sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
fakeinos = statp->f_bfree << sbp->sb_inopblog;
-#if XFS_BIG_INUMS
- fakeinos += mp->m_inoadd;
-#endif
statp->f_files =
MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER);
if (mp->m_maxicount)
-#if XFS_BIG_INUMS
- if (!mp->m_inoadd)
-#endif
- statp->f_files = min_t(typeof(statp->f_files),
- statp->f_files,
- mp->m_maxicount);
+ statp->f_files = min_t(typeof(statp->f_files),
+ statp->f_files,
+ mp->m_maxicount);
statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
spin_unlock(&mp->m_sb_lock);
@@ -1302,57 +1314,6 @@ xfs_fs_show_options(
return -xfs_showargs(XFS_M(mnt->mnt_sb), m);
}
-STATIC int
-xfs_fs_quotasync(
- struct super_block *sb,
- int type)
-{
- return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XQUOTASYNC, 0, NULL);
-}
-
-STATIC int
-xfs_fs_getxstate(
- struct super_block *sb,
- struct fs_quota_stat *fqs)
-{
- return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
-}
-
-STATIC int
-xfs_fs_setxstate(
- struct super_block *sb,
- unsigned int flags,
- int op)
-{
- return -XFS_QM_QUOTACTL(XFS_M(sb), op, 0, (caddr_t)&flags);
-}
-
-STATIC int
-xfs_fs_getxquota(
- struct super_block *sb,
- int type,
- qid_t id,
- struct fs_disk_quota *fdq)
-{
- return -XFS_QM_QUOTACTL(XFS_M(sb),
- (type == USRQUOTA) ? Q_XGETQUOTA :
- ((type == GRPQUOTA) ? Q_XGETGQUOTA :
- Q_XGETPQUOTA), id, (caddr_t)fdq);
-}
-
-STATIC int
-xfs_fs_setxquota(
- struct super_block *sb,
- int type,
- qid_t id,
- struct fs_disk_quota *fdq)
-{
- return -XFS_QM_QUOTACTL(XFS_M(sb),
- (type == USRQUOTA) ? Q_XSETQLIM :
- ((type == GRPQUOTA) ? Q_XSETGQLIM :
- Q_XSETPQLIM), id, (caddr_t)fdq);
-}
-
/*
* This function fills in xfs_mount_t fields based on mount args.
* Note: the superblock _has_ now been read in.
@@ -1435,7 +1396,9 @@ xfs_fs_fill_super(
sb_min_blocksize(sb, BBSIZE);
sb->s_xattr = xfs_xattr_handlers;
sb->s_export_op = &xfs_export_operations;
+#ifdef CONFIG_XFS_QUOTA
sb->s_qcop = &xfs_quotactl_operations;
+#endif
sb->s_op = &xfs_super_operations;
error = xfs_dmops_get(mp);
@@ -1578,14 +1541,6 @@ static struct super_operations xfs_super_operations = {
.show_options = xfs_fs_show_options,
};
-static struct quotactl_ops xfs_quotactl_operations = {
- .quota_sync = xfs_fs_quotasync,
- .get_xstate = xfs_fs_getxstate,
- .set_xstate = xfs_fs_setxstate,
- .get_xquota = xfs_fs_getxquota,
- .set_xquota = xfs_fs_setxquota,
-};
-
static struct file_system_type xfs_fs_type = {
.owner = THIS_MODULE,
.name = "xfs",
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index d5d776d4cd6..5a2ea3a2178 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -93,6 +93,7 @@ extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
extern const struct export_operations xfs_export_operations;
extern struct xattr_handler *xfs_xattr_handlers[];
+extern struct quotactl_ops xfs_quotactl_operations;
#define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info))
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index a608e72fa40..f7ba76633c2 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -62,12 +62,6 @@ xfs_sync_inodes_ag(
uint32_t first_index = 0;
int error = 0;
int last_error = 0;
- int fflag = XFS_B_ASYNC;
-
- if (flags & SYNC_DELWRI)
- fflag = XFS_B_DELWRI;
- if (flags & SYNC_WAIT)
- fflag = 0; /* synchronous overrides all */
do {
struct inode *inode;
@@ -128,11 +122,23 @@ xfs_sync_inodes_ag(
* If we have to flush data or wait for I/O completion
* we need to hold the iolock.
*/
- if ((flags & SYNC_DELWRI) && VN_DIRTY(inode)) {
- xfs_ilock(ip, XFS_IOLOCK_SHARED);
- lock_flags |= XFS_IOLOCK_SHARED;
- error = xfs_flush_pages(ip, 0, -1, fflag, FI_NONE);
- if (flags & SYNC_IOWAIT)
+ if (flags & SYNC_DELWRI) {
+ if (VN_DIRTY(inode)) {
+ if (flags & SYNC_TRYLOCK) {
+ if (xfs_ilock_nowait(ip, XFS_IOLOCK_SHARED))
+ lock_flags |= XFS_IOLOCK_SHARED;
+ } else {
+ xfs_ilock(ip, XFS_IOLOCK_SHARED);
+ lock_flags |= XFS_IOLOCK_SHARED;
+ }
+ if (lock_flags & XFS_IOLOCK_SHARED) {
+ error = xfs_flush_pages(ip, 0, -1,
+ (flags & SYNC_WAIT) ? 0
+ : XFS_B_ASYNC,
+ FI_NONE);
+ }
+ }
+ if (VN_CACHED(inode) && (flags & SYNC_IOWAIT))
xfs_ioend_wait(ip);
}
xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -398,15 +404,17 @@ STATIC void
xfs_syncd_queue_work(
struct xfs_mount *mp,
void *data,
- void (*syncer)(struct xfs_mount *, void *))
+ void (*syncer)(struct xfs_mount *, void *),
+ struct completion *completion)
{
- struct bhv_vfs_sync_work *work;
+ struct xfs_sync_work *work;
- work = kmem_alloc(sizeof(struct bhv_vfs_sync_work), KM_SLEEP);
+ work = kmem_alloc(sizeof(struct xfs_sync_work), KM_SLEEP);
INIT_LIST_HEAD(&work->w_list);
work->w_syncer = syncer;
work->w_data = data;
work->w_mount = mp;
+ work->w_completion = completion;
spin_lock(&mp->m_sync_lock);
list_add_tail(&work->w_list, &mp->m_sync_list);
spin_unlock(&mp->m_sync_lock);
@@ -420,49 +428,26 @@ xfs_syncd_queue_work(
* heads, looking about for more room...
*/
STATIC void
-xfs_flush_inode_work(
- struct xfs_mount *mp,
- void *arg)
-{
- struct inode *inode = arg;
- filemap_flush(inode->i_mapping);
- iput(inode);
-}
-
-void
-xfs_flush_inode(
- xfs_inode_t *ip)
-{
- struct inode *inode = VFS_I(ip);
-
- igrab(inode);
- xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inode_work);
- delay(msecs_to_jiffies(500));
-}
-
-/*
- * This is the "bigger hammer" version of xfs_flush_inode_work...
- * (IOW, "If at first you don't succeed, use a Bigger Hammer").
- */
-STATIC void
-xfs_flush_device_work(
+xfs_flush_inodes_work(
struct xfs_mount *mp,
void *arg)
{
struct inode *inode = arg;
- sync_blockdev(mp->m_super->s_bdev);
+ xfs_sync_inodes(mp, SYNC_DELWRI | SYNC_TRYLOCK);
+ xfs_sync_inodes(mp, SYNC_DELWRI | SYNC_TRYLOCK | SYNC_IOWAIT);
iput(inode);
}
void
-xfs_flush_device(
+xfs_flush_inodes(
xfs_inode_t *ip)
{
struct inode *inode = VFS_I(ip);
+ DECLARE_COMPLETION_ONSTACK(completion);
igrab(inode);
- xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_device_work);
- delay(msecs_to_jiffies(500));
+ xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inodes_work, &completion);
+ wait_for_completion(&completion);
xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
}
@@ -497,7 +482,7 @@ xfssyncd(
{
struct xfs_mount *mp = arg;
long timeleft;
- bhv_vfs_sync_work_t *work, *n;
+ xfs_sync_work_t *work, *n;
LIST_HEAD (tmp);
set_freezable();
@@ -532,6 +517,8 @@ xfssyncd(
list_del(&work->w_list);
if (work == &mp->m_sync_work)
continue;
+ if (work->w_completion)
+ complete(work->w_completion);
kmem_free(work);
}
}
@@ -545,6 +532,7 @@ xfs_syncd_init(
{
mp->m_sync_work.w_syncer = xfs_sync_worker;
mp->m_sync_work.w_mount = mp;
+ mp->m_sync_work.w_completion = NULL;
mp->m_sync_task = kthread_run(xfssyncd, mp, "xfssyncd");
if (IS_ERR(mp->m_sync_task))
return -PTR_ERR(mp->m_sync_task);
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h
index 5f6de1efe1f..308d5bf6dfb 100644
--- a/fs/xfs/linux-2.6/xfs_sync.h
+++ b/fs/xfs/linux-2.6/xfs_sync.h
@@ -19,19 +19,22 @@
#define XFS_SYNC_H 1
struct xfs_mount;
+struct xfs_perag;
-typedef struct bhv_vfs_sync_work {
+typedef struct xfs_sync_work {
struct list_head w_list;
struct xfs_mount *w_mount;
void *w_data; /* syncer routine argument */
void (*w_syncer)(struct xfs_mount *, void *);
-} bhv_vfs_sync_work_t;
+ struct completion *w_completion;
+} xfs_sync_work_t;
#define SYNC_ATTR 0x0001 /* sync attributes */
#define SYNC_DELWRI 0x0002 /* look at delayed writes */
#define SYNC_WAIT 0x0004 /* wait for i/o to complete */
#define SYNC_BDFLUSH 0x0008 /* BDFLUSH is calling -- don't block */
#define SYNC_IOWAIT 0x0010 /* wait for all I/O to complete */
+#define SYNC_TRYLOCK 0x0020 /* only try to lock inodes */
int xfs_syncd_init(struct xfs_mount *mp);
void xfs_syncd_stop(struct xfs_mount *mp);
@@ -42,8 +45,7 @@ int xfs_sync_fsdata(struct xfs_mount *mp, int flags);
int xfs_quiesce_data(struct xfs_mount *mp);
void xfs_quiesce_attr(struct xfs_mount *mp);
-void xfs_flush_inode(struct xfs_inode *ip);
-void xfs_flush_device(struct xfs_inode *ip);
+void xfs_flush_inodes(struct xfs_inode *ip);
int xfs_reclaim_inode(struct xfs_inode *ip, int locked, int sync_mode);
int xfs_reclaim_inodes(struct xfs_mount *mp, int noblock, int mode);
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index f65983a230d..ad7fbead4c9 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -41,11 +41,6 @@ struct attrlist_cursor_kern;
#define IO_INVIS 0x00020 /* don't update inode timestamps */
/*
- * Flags for xfs_inode_flush
- */
-#define FLUSH_SYNC 1 /* wait for flush to complete */
-
-/*
* Flush/Invalidate options for vop_toss/flush/flushinval_pages.
*/
#define FI_NONE 0 /* none */
@@ -55,33 +50,6 @@ struct attrlist_cursor_kern;
the operation completes. */
/*
- * Dealing with bad inodes
- */
-static inline int VN_BAD(struct inode *vp)
-{
- return is_bad_inode(vp);
-}
-
-/*
- * Extracting atime values in various formats
- */
-static inline void vn_atime_to_bstime(struct inode *vp, xfs_bstime_t *bs_atime)
-{
- bs_atime->tv_sec = vp->i_atime.tv_sec;
- bs_atime->tv_nsec = vp->i_atime.tv_nsec;
-}
-
-static inline void vn_atime_to_timespec(struct inode *vp, struct timespec *ts)
-{
- *ts = vp->i_atime;
-}
-
-static inline void vn_atime_to_time_t(struct inode *vp, time_t *tt)
-{
- *tt = vp->i_atime.tv_sec;
-}
-
-/*
* Some useful predicates.
*/
#define VN_MAPPED(vp) mapping_mapped(vp->i_mapping)
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 6543c0b2975..e4babcc6342 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -804,7 +804,7 @@ xfs_qm_dqlookup(
uint flist_locked;
xfs_dquot_t *d;
- ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
+ ASSERT(mutex_is_locked(&qh->qh_lock));
flist_locked = B_FALSE;
@@ -877,7 +877,7 @@ xfs_qm_dqlookup(
/*
* move the dquot to the front of the hashchain
*/
- ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
+ ASSERT(mutex_is_locked(&qh->qh_lock));
if (dqp->HL_PREVP != &qh->qh_next) {
xfs_dqtrace_entry(dqp,
"DQLOOKUP: HASH MOVETOFRONT");
@@ -892,13 +892,13 @@ xfs_qm_dqlookup(
}
xfs_dqtrace_entry(dqp, "LOOKUP END");
*O_dqpp = dqp;
- ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
+ ASSERT(mutex_is_locked(&qh->qh_lock));
return (0);
}
}
*O_dqpp = NULL;
- ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
+ ASSERT(mutex_is_locked(&qh->qh_lock));
return (1);
}
@@ -956,7 +956,7 @@ xfs_qm_dqget(
ASSERT(ip->i_gdquot == NULL);
}
#endif
- XFS_DQ_HASH_LOCK(h);
+ mutex_lock(&h->qh_lock);
/*
* Look in the cache (hashtable).
@@ -971,7 +971,7 @@ xfs_qm_dqget(
*/
ASSERT(*O_dqpp);
ASSERT(XFS_DQ_IS_LOCKED(*O_dqpp));
- XFS_DQ_HASH_UNLOCK(h);
+ mutex_unlock(&h->qh_lock);
xfs_dqtrace_entry(*O_dqpp, "DQGET DONE (FROM CACHE)");
return (0); /* success */
}
@@ -991,7 +991,7 @@ xfs_qm_dqget(
* we don't keep the lock across a disk read
*/
version = h->qh_version;
- XFS_DQ_HASH_UNLOCK(h);
+ mutex_unlock(&h->qh_lock);
/*
* Allocate the dquot on the kernel heap, and read the ondisk
@@ -1056,7 +1056,7 @@ xfs_qm_dqget(
/*
* Hashlock comes after ilock in lock order
*/
- XFS_DQ_HASH_LOCK(h);
+ mutex_lock(&h->qh_lock);
if (version != h->qh_version) {
xfs_dquot_t *tmpdqp;
/*
@@ -1072,7 +1072,7 @@ xfs_qm_dqget(
* and start over.
*/
xfs_qm_dqput(tmpdqp);
- XFS_DQ_HASH_UNLOCK(h);
+ mutex_unlock(&h->qh_lock);
xfs_qm_dqdestroy(dqp);
XQM_STATS_INC(xqmstats.xs_qm_dquot_dups);
goto again;
@@ -1083,7 +1083,7 @@ xfs_qm_dqget(
* Put the dquot at the beginning of the hash-chain and mp's list
* LOCK ORDER: hashlock, freelistlock, mplistlock, udqlock, gdqlock ..
*/
- ASSERT(XFS_DQ_IS_HASH_LOCKED(h));
+ ASSERT(mutex_is_locked(&h->qh_lock));
dqp->q_hash = h;
XQM_HASHLIST_INSERT(h, dqp);
@@ -1102,7 +1102,7 @@ xfs_qm_dqget(
XQM_MPLIST_INSERT(&(XFS_QI_MPL_LIST(mp)), dqp);
xfs_qm_mplist_unlock(mp);
- XFS_DQ_HASH_UNLOCK(h);
+ mutex_unlock(&h->qh_lock);
dqret:
ASSERT((ip == NULL) || xfs_isilocked(ip, XFS_ILOCK_EXCL));
xfs_dqtrace_entry(dqp, "DQGET DONE");
@@ -1440,7 +1440,7 @@ xfs_qm_dqpurge(
xfs_mount_t *mp = dqp->q_mount;
ASSERT(XFS_QM_IS_MPLIST_LOCKED(mp));
- ASSERT(XFS_DQ_IS_HASH_LOCKED(dqp->q_hash));
+ ASSERT(mutex_is_locked(&dqp->q_hash->qh_lock));
xfs_dqlock(dqp);
/*
@@ -1453,7 +1453,7 @@ xfs_qm_dqpurge(
*/
if (dqp->q_nrefs != 0) {
xfs_dqunlock(dqp);
- XFS_DQ_HASH_UNLOCK(dqp->q_hash);
+ mutex_unlock(&dqp->q_hash->qh_lock);
return (1);
}
@@ -1517,7 +1517,7 @@ xfs_qm_dqpurge(
memset(&dqp->q_core, 0, sizeof(dqp->q_core));
xfs_dqfunlock(dqp);
xfs_dqunlock(dqp);
- XFS_DQ_HASH_UNLOCK(thishash);
+ mutex_unlock(&thishash->qh_lock);
return (0);
}
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h
index d443e93b433..de0f402ddb4 100644
--- a/fs/xfs/quota/xfs_dquot.h
+++ b/fs/xfs/quota/xfs_dquot.h
@@ -34,7 +34,7 @@
*/
typedef struct xfs_dqhash {
struct xfs_dquot *qh_next;
- mutex_t qh_lock;
+ struct mutex qh_lock;
uint qh_version; /* ever increasing version */
uint qh_nelems; /* number of dquots on the list */
} xfs_dqhash_t;
@@ -81,7 +81,7 @@ typedef struct xfs_dquot {
xfs_qcnt_t q_res_bcount; /* total regular nblks used+reserved */
xfs_qcnt_t q_res_icount; /* total inos allocd+reserved */
xfs_qcnt_t q_res_rtbcount;/* total realtime blks used+reserved */
- mutex_t q_qlock; /* quota lock */
+ struct mutex q_qlock; /* quota lock */
struct completion q_flush; /* flush completion queue */
atomic_t q_pincount; /* dquot pin count */
wait_queue_head_t q_pinwait; /* dquot pinning wait queue */
@@ -109,19 +109,6 @@ enum {
#define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++)
-#ifdef DEBUG
-static inline int
-XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
-{
- if (mutex_trylock(&dqp->q_qlock)) {
- mutex_unlock(&dqp->q_qlock);
- return 0;
- }
- return 1;
-}
-#endif
-
-
/*
* Manage the q_flush completion queue embedded in the dquot. This completion
* queue synchronizes processes attempting to flush the in-core dquot back to
@@ -142,6 +129,7 @@ static inline void xfs_dqfunlock(xfs_dquot_t *dqp)
complete(&dqp->q_flush);
}
+#define XFS_DQ_IS_LOCKED(dqp) (mutex_is_locked(&((dqp)->q_qlock)))
#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp))
#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY)
#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER)
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 7a2beb64314..5b6695049e0 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -55,7 +55,7 @@
* quota functionality, including maintaining the freelist and hash
* tables of dquots.
*/
-mutex_t xfs_Gqm_lock;
+struct mutex xfs_Gqm_lock;
struct xfs_qm *xfs_Gqm;
uint ndquot;
@@ -69,8 +69,6 @@ STATIC void xfs_qm_list_destroy(xfs_dqlist_t *);
STATIC void xfs_qm_freelist_init(xfs_frlist_t *);
STATIC void xfs_qm_freelist_destroy(xfs_frlist_t *);
-STATIC int xfs_qm_mplist_nowait(xfs_mount_t *);
-STATIC int xfs_qm_dqhashlock_nowait(xfs_dquot_t *);
STATIC int xfs_qm_init_quotainos(xfs_mount_t *);
STATIC int xfs_qm_init_quotainfo(xfs_mount_t *);
@@ -82,7 +80,7 @@ static struct shrinker xfs_qm_shaker = {
};
#ifdef DEBUG
-extern mutex_t qcheck_lock;
+extern struct mutex qcheck_lock;
#endif
#ifdef QUOTADEBUG
@@ -219,7 +217,7 @@ xfs_qm_hold_quotafs_ref(
* the structure could disappear between the entry to this routine and
* a HOLD operation if not locked.
*/
- XFS_QM_LOCK(xfs_Gqm);
+ mutex_lock(&xfs_Gqm_lock);
if (xfs_Gqm == NULL)
xfs_Gqm = xfs_Gqm_init();
@@ -228,8 +226,8 @@ xfs_qm_hold_quotafs_ref(
* debugging and statistical purposes, but ...
* Just take a reference and get out.
*/
- XFS_QM_HOLD(xfs_Gqm);
- XFS_QM_UNLOCK(xfs_Gqm);
+ xfs_Gqm->qm_nrefs++;
+ mutex_unlock(&xfs_Gqm_lock);
return 0;
}
@@ -277,13 +275,12 @@ xfs_qm_rele_quotafs_ref(
* Destroy the entire XQM. If somebody mounts with quotaon, this'll
* be restarted.
*/
- XFS_QM_LOCK(xfs_Gqm);
- XFS_QM_RELE(xfs_Gqm);
- if (xfs_Gqm->qm_nrefs == 0) {
+ mutex_lock(&xfs_Gqm_lock);
+ if (--xfs_Gqm->qm_nrefs == 0) {
xfs_qm_destroy(xfs_Gqm);
xfs_Gqm = NULL;
}
- XFS_QM_UNLOCK(xfs_Gqm);
+ mutex_unlock(&xfs_Gqm_lock);
}
/*
@@ -577,10 +574,10 @@ xfs_qm_dqpurge_int(
continue;
}
- if (! xfs_qm_dqhashlock_nowait(dqp)) {
+ if (!mutex_trylock(&dqp->q_hash->qh_lock)) {
nrecl = XFS_QI_MPLRECLAIMS(mp);
xfs_qm_mplist_unlock(mp);
- XFS_DQ_HASH_LOCK(dqp->q_hash);
+ mutex_lock(&dqp->q_hash->qh_lock);
xfs_qm_mplist_lock(mp);
/*
@@ -590,7 +587,7 @@ xfs_qm_dqpurge_int(
* this point, but somebody might be taking things off.
*/
if (nrecl != XFS_QI_MPLRECLAIMS(mp)) {
- XFS_DQ_HASH_UNLOCK(dqp->q_hash);
+ mutex_unlock(&dqp->q_hash->qh_lock);
goto again;
}
}
@@ -632,7 +629,6 @@ xfs_qm_dqattach_one(
xfs_dqid_t id,
uint type,
uint doalloc,
- uint dolock,
xfs_dquot_t *udqhint, /* hint */
xfs_dquot_t **IO_idqpp)
{
@@ -641,16 +637,16 @@ xfs_qm_dqattach_one(
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
error = 0;
+
/*
* See if we already have it in the inode itself. IO_idqpp is
* &i_udquot or &i_gdquot. This made the code look weird, but
* made the logic a lot simpler.
*/
- if ((dqp = *IO_idqpp)) {
- if (dolock)
- xfs_dqlock(dqp);
+ dqp = *IO_idqpp;
+ if (dqp) {
xfs_dqtrace_entry(dqp, "DQATTACH: found in ip");
- goto done;
+ return 0;
}
/*
@@ -659,38 +655,38 @@ xfs_qm_dqattach_one(
* lookup by dqid (xfs_qm_dqget) by caching a group dquot inside
* the user dquot.
*/
- ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
- if (udqhint && !dolock)
+ if (udqhint) {
+ ASSERT(type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
xfs_dqlock(udqhint);
- /*
- * No need to take dqlock to look at the id.
- * The ID can't change until it gets reclaimed, and it won't
- * be reclaimed as long as we have a ref from inode and we hold
- * the ilock.
- */
- if (udqhint &&
- (dqp = udqhint->q_gdquot) &&
- (be32_to_cpu(dqp->q_core.d_id) == id)) {
- ASSERT(XFS_DQ_IS_LOCKED(udqhint));
- xfs_dqlock(dqp);
- XFS_DQHOLD(dqp);
- ASSERT(*IO_idqpp == NULL);
- *IO_idqpp = dqp;
- if (!dolock) {
+ /*
+ * No need to take dqlock to look at the id.
+ *
+ * The ID can't change until it gets reclaimed, and it won't
+ * be reclaimed as long as we have a ref from inode and we
+ * hold the ilock.
+ */
+ dqp = udqhint->q_gdquot;
+ if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) {
+ xfs_dqlock(dqp);
+ XFS_DQHOLD(dqp);
+ ASSERT(*IO_idqpp == NULL);
+ *IO_idqpp = dqp;
+
xfs_dqunlock(dqp);
xfs_dqunlock(udqhint);
+ return 0;
}
- goto done;
- }
- /*
- * We can't hold a dquot lock when we call the dqget code.
- * We'll deadlock in no time, because of (not conforming to)
- * lock ordering - the inodelock comes before any dquot lock,
- * and we may drop and reacquire the ilock in xfs_qm_dqget().
- */
- if (udqhint)
+
+ /*
+ * We can't hold a dquot lock when we call the dqget code.
+ * We'll deadlock in no time, because of (not conforming to)
+ * lock ordering - the inodelock comes before any dquot lock,
+ * and we may drop and reacquire the ilock in xfs_qm_dqget().
+ */
xfs_dqunlock(udqhint);
+ }
+
/*
* Find the dquot from somewhere. This bumps the
* reference count of dquot and returns it locked.
@@ -698,48 +694,19 @@ xfs_qm_dqattach_one(
* disk and we didn't ask it to allocate;
* ESRCH if quotas got turned off suddenly.
*/
- if ((error = xfs_qm_dqget(ip->i_mount, ip, id, type,
- doalloc|XFS_QMOPT_DOWARN, &dqp))) {
- if (udqhint && dolock)
- xfs_dqlock(udqhint);
- goto done;
- }
+ error = xfs_qm_dqget(ip->i_mount, ip, id, type, XFS_QMOPT_DOWARN, &dqp);
+ if (error)
+ return error;
xfs_dqtrace_entry(dqp, "DQATTACH: found by dqget");
+
/*
* dqget may have dropped and re-acquired the ilock, but it guarantees
* that the dquot returned is the one that should go in the inode.
*/
*IO_idqpp = dqp;
- ASSERT(dqp);
- ASSERT(XFS_DQ_IS_LOCKED(dqp));
- if (! dolock) {
- xfs_dqunlock(dqp);
- goto done;
- }
- if (! udqhint)
- goto done;
-
- ASSERT(udqhint);
- ASSERT(dolock);
- ASSERT(XFS_DQ_IS_LOCKED(dqp));
- if (! xfs_qm_dqlock_nowait(udqhint)) {
- xfs_dqunlock(dqp);
- xfs_dqlock(udqhint);
- xfs_dqlock(dqp);
- }
- done:
-#ifdef QUOTADEBUG
- if (udqhint) {
- if (dolock)
- ASSERT(XFS_DQ_IS_LOCKED(udqhint));
- }
- if (! error) {
- if (dolock)
- ASSERT(XFS_DQ_IS_LOCKED(dqp));
- }
-#endif
- return error;
+ xfs_dqunlock(dqp);
+ return 0;
}
@@ -754,24 +721,15 @@ xfs_qm_dqattach_one(
STATIC void
xfs_qm_dqattach_grouphint(
xfs_dquot_t *udq,
- xfs_dquot_t *gdq,
- uint locked)
+ xfs_dquot_t *gdq)
{
xfs_dquot_t *tmp;
-#ifdef QUOTADEBUG
- if (locked) {
- ASSERT(XFS_DQ_IS_LOCKED(udq));
- ASSERT(XFS_DQ_IS_LOCKED(gdq));
- }
-#endif
- if (! locked)
- xfs_dqlock(udq);
+ xfs_dqlock(udq);
if ((tmp = udq->q_gdquot)) {
if (tmp == gdq) {
- if (! locked)
- xfs_dqunlock(udq);
+ xfs_dqunlock(udq);
return;
}
@@ -781,8 +739,6 @@ xfs_qm_dqattach_grouphint(
* because the freelist lock comes before dqlocks.
*/
xfs_dqunlock(udq);
- if (locked)
- xfs_dqunlock(gdq);
/*
* we took a hard reference once upon a time in dqget,
* so give it back when the udquot no longer points at it
@@ -795,9 +751,7 @@ xfs_qm_dqattach_grouphint(
} else {
ASSERT(XFS_DQ_IS_LOCKED(udq));
- if (! locked) {
- xfs_dqlock(gdq);
- }
+ xfs_dqlock(gdq);
}
ASSERT(XFS_DQ_IS_LOCKED(udq));
@@ -810,10 +764,9 @@ xfs_qm_dqattach_grouphint(
XFS_DQHOLD(gdq);
udq->q_gdquot = gdq;
}
- if (! locked) {
- xfs_dqunlock(gdq);
- xfs_dqunlock(udq);
- }
+
+ xfs_dqunlock(gdq);
+ xfs_dqunlock(udq);
}
@@ -821,8 +774,6 @@ xfs_qm_dqattach_grouphint(
* Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON
* into account.
* If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed.
- * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty
- * much made this code a complete mess, but it has been pretty useful.
* If XFS_QMOPT_ILOCKED, then inode sent is already locked EXCL.
* Inode may get unlocked and relocked in here, and the caller must deal with
* the consequences.
@@ -851,7 +802,6 @@ xfs_qm_dqattach(
if (XFS_IS_UQUOTA_ON(mp)) {
error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
flags & XFS_QMOPT_DQALLOC,
- flags & XFS_QMOPT_DQLOCK,
NULL, &ip->i_udquot);
if (error)
goto done;
@@ -863,11 +813,9 @@ xfs_qm_dqattach(
error = XFS_IS_GQUOTA_ON(mp) ?
xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
flags & XFS_QMOPT_DQALLOC,
- flags & XFS_QMOPT_DQLOCK,
ip->i_udquot, &ip->i_gdquot) :
xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ,
flags & XFS_QMOPT_DQALLOC,
- flags & XFS_QMOPT_DQLOCK,
ip->i_udquot, &ip->i_gdquot);
/*
* Don't worry about the udquot that we may have
@@ -898,22 +846,13 @@ xfs_qm_dqattach(
/*
* Attach i_gdquot to the gdquot hint inside the i_udquot.
*/
- xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot,
- flags & XFS_QMOPT_DQLOCK);
+ xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot);
}
done:
#ifdef QUOTADEBUG
if (! error) {
- if (ip->i_udquot) {
- if (flags & XFS_QMOPT_DQLOCK)
- ASSERT(XFS_DQ_IS_LOCKED(ip->i_udquot));
- }
- if (ip->i_gdquot) {
- if (flags & XFS_QMOPT_DQLOCK)
- ASSERT(XFS_DQ_IS_LOCKED(ip->i_gdquot));
- }
if (XFS_IS_UQUOTA_ON(mp))
ASSERT(ip->i_udquot);
if (XFS_IS_OQUOTA_ON(mp))
@@ -2086,7 +2025,7 @@ xfs_qm_shake_freelist(
* a dqlookup process that holds the hashlock that is
* waiting for the freelist lock.
*/
- if (! xfs_qm_dqhashlock_nowait(dqp)) {
+ if (!mutex_trylock(&dqp->q_hash->qh_lock)) {
xfs_dqfunlock(dqp);
xfs_dqunlock(dqp);
dqp = dqp->dq_flnext;
@@ -2103,7 +2042,7 @@ xfs_qm_shake_freelist(
/* XXX put a sentinel so that we can come back here */
xfs_dqfunlock(dqp);
xfs_dqunlock(dqp);
- XFS_DQ_HASH_UNLOCK(hash);
+ mutex_unlock(&hash->qh_lock);
xfs_qm_freelist_unlock(xfs_Gqm);
if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
return nreclaimed;
@@ -2120,7 +2059,7 @@ xfs_qm_shake_freelist(
XQM_HASHLIST_REMOVE(hash, dqp);
xfs_dqfunlock(dqp);
xfs_qm_mplist_unlock(dqp->q_mount);
- XFS_DQ_HASH_UNLOCK(hash);
+ mutex_unlock(&hash->qh_lock);
off_freelist:
XQM_FREELIST_REMOVE(dqp);
@@ -2262,7 +2201,7 @@ xfs_qm_dqreclaim_one(void)
continue;
}
- if (! xfs_qm_dqhashlock_nowait(dqp))
+ if (!mutex_trylock(&dqp->q_hash->qh_lock))
goto mplistunlock;
ASSERT(dqp->q_nrefs == 0);
@@ -2271,7 +2210,7 @@ xfs_qm_dqreclaim_one(void)
XQM_HASHLIST_REMOVE(dqp->q_hash, dqp);
XQM_FREELIST_REMOVE(dqp);
dqpout = dqp;
- XFS_DQ_HASH_UNLOCK(dqp->q_hash);
+ mutex_unlock(&dqp->q_hash->qh_lock);
mplistunlock:
xfs_qm_mplist_unlock(dqp->q_mount);
xfs_dqfunlock(dqp);
@@ -2774,34 +2713,3 @@ xfs_qm_freelist_append(xfs_frlist_t *ql, xfs_dquot_t *dq)
{
xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq);
}
-
-STATIC int
-xfs_qm_dqhashlock_nowait(
- xfs_dquot_t *dqp)
-{
- int locked;
-
- locked = mutex_trylock(&((dqp)->q_hash->qh_lock));
- return locked;
-}
-
-int
-xfs_qm_freelist_lock_nowait(
- xfs_qm_t *xqm)
-{
- int locked;
-
- locked = mutex_trylock(&(xqm->qm_dqfreelist.qh_lock));
- return locked;
-}
-
-STATIC int
-xfs_qm_mplist_nowait(
- xfs_mount_t *mp)
-{
- int locked;
-
- ASSERT(mp->m_quotainfo);
- locked = mutex_trylock(&(XFS_QI_MPLLOCK(mp)));
- return locked;
-}
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h
index ddf09166387..a371954cae1 100644
--- a/fs/xfs/quota/xfs_qm.h
+++ b/fs/xfs/quota/xfs_qm.h
@@ -27,7 +27,7 @@ struct xfs_qm;
struct xfs_inode;
extern uint ndquot;
-extern mutex_t xfs_Gqm_lock;
+extern struct mutex xfs_Gqm_lock;
extern struct xfs_qm *xfs_Gqm;
extern kmem_zone_t *qm_dqzone;
extern kmem_zone_t *qm_dqtrxzone;
@@ -79,7 +79,7 @@ typedef xfs_dqhash_t xfs_dqlist_t;
typedef struct xfs_frlist {
struct xfs_dquot *qh_next;
struct xfs_dquot *qh_prev;
- mutex_t qh_lock;
+ struct mutex qh_lock;
uint qh_version;
uint qh_nelems;
} xfs_frlist_t;
@@ -115,7 +115,7 @@ typedef struct xfs_quotainfo {
xfs_qwarncnt_t qi_bwarnlimit; /* limit for blks warnings */
xfs_qwarncnt_t qi_iwarnlimit; /* limit for inodes warnings */
xfs_qwarncnt_t qi_rtbwarnlimit;/* limit for rt blks warnings */
- mutex_t qi_quotaofflock;/* to serialize quotaoff */
+ struct mutex qi_quotaofflock;/* to serialize quotaoff */
xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */
uint qi_dqperchunk; /* # ondisk dqs in above chunk */
xfs_qcnt_t qi_bhardlimit; /* default data blk hard limit */
@@ -158,11 +158,6 @@ typedef struct xfs_dquot_acct {
#define XFS_QM_IWARNLIMIT 5
#define XFS_QM_RTBWARNLIMIT 5
-#define XFS_QM_LOCK(xqm) (mutex_lock(&xqm##_lock))
-#define XFS_QM_UNLOCK(xqm) (mutex_unlock(&xqm##_lock))
-#define XFS_QM_HOLD(xqm) ((xqm)->qm_nrefs++)
-#define XFS_QM_RELE(xqm) ((xqm)->qm_nrefs--)
-
extern void xfs_qm_destroy_quotainfo(xfs_mount_t *);
extern void xfs_qm_mount_quotas(xfs_mount_t *);
extern int xfs_qm_quotacheck(xfs_mount_t *);
@@ -178,6 +173,16 @@ extern void xfs_qm_dqdetach(xfs_inode_t *);
extern int xfs_qm_dqpurge_all(xfs_mount_t *, uint);
extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
+/* quota ops */
+extern int xfs_qm_scall_trunc_qfiles(xfs_mount_t *, uint);
+extern int xfs_qm_scall_getquota(xfs_mount_t *, xfs_dqid_t, uint,
+ fs_disk_quota_t *);
+extern int xfs_qm_scall_setqlim(xfs_mount_t *, xfs_dqid_t, uint,
+ fs_disk_quota_t *);
+extern int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *);
+extern int xfs_qm_scall_quotaon(xfs_mount_t *, uint);
+extern int xfs_qm_scall_quotaoff(xfs_mount_t *, uint);
+
/* vop stuff */
extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *,
uid_t, gid_t, prid_t, uint,
@@ -194,11 +199,6 @@ extern int xfs_qm_vop_chown_reserve(xfs_trans_t *, xfs_inode_t *,
/* list stuff */
extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *);
extern void xfs_qm_freelist_unlink(xfs_dquot_t *);
-extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *);
-
-/* system call interface */
-extern int xfs_qm_quotactl(struct xfs_mount *, int, int,
- xfs_caddr_t);
#ifdef DEBUG
extern int xfs_qm_internalqcheck(xfs_mount_t *);
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index bc6c5cca3e1..63037c689a4 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -235,7 +235,6 @@ struct xfs_qmops xfs_qmcore_xfs = {
.xfs_dqvopchownresv = xfs_qm_vop_chown_reserve,
.xfs_dqstatvfs = xfs_qm_statvfs,
.xfs_dqsync = xfs_qm_sync,
- .xfs_quotactl = xfs_qm_quotactl,
.xfs_dqtrxops = &xfs_trans_dquot_ops,
};
EXPORT_SYMBOL(xfs_qmcore_xfs);
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 68139b38aed..c7b66f6506c 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -57,135 +57,16 @@
# define qdprintk(s, args...) do { } while (0)
#endif
-STATIC int xfs_qm_scall_trunc_qfiles(xfs_mount_t *, uint);
-STATIC int xfs_qm_scall_getquota(xfs_mount_t *, xfs_dqid_t, uint,
- fs_disk_quota_t *);
-STATIC int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *);
-STATIC int xfs_qm_scall_setqlim(xfs_mount_t *, xfs_dqid_t, uint,
- fs_disk_quota_t *);
-STATIC int xfs_qm_scall_quotaon(xfs_mount_t *, uint);
-STATIC int xfs_qm_scall_quotaoff(xfs_mount_t *, uint, boolean_t);
STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint);
STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *,
uint);
-STATIC uint xfs_qm_import_flags(uint);
STATIC uint xfs_qm_export_flags(uint);
-STATIC uint xfs_qm_import_qtype_flags(uint);
STATIC uint xfs_qm_export_qtype_flags(uint);
STATIC void xfs_qm_export_dquot(xfs_mount_t *, xfs_disk_dquot_t *,
fs_disk_quota_t *);
/*
- * The main distribution switch of all XFS quotactl system calls.
- */
-int
-xfs_qm_quotactl(
- xfs_mount_t *mp,
- int cmd,
- int id,
- xfs_caddr_t addr)
-{
- int error;
-
- ASSERT(addr != NULL || cmd == Q_XQUOTASYNC);
-
- /*
- * The following commands are valid even when quotaoff.
- */
- switch (cmd) {
- case Q_XQUOTARM:
- /*
- * Truncate quota files. quota must be off.
- */
- if (XFS_IS_QUOTA_ON(mp))
- return XFS_ERROR(EINVAL);
- if (mp->m_flags & XFS_MOUNT_RDONLY)
- return XFS_ERROR(EROFS);
- return (xfs_qm_scall_trunc_qfiles(mp,
- xfs_qm_import_qtype_flags(*(uint *)addr)));
-
- case Q_XGETQSTAT:
- /*
- * Get quota status information.
- */
- return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr));
-
- case Q_XQUOTAON:
- /*
- * QUOTAON - enabling quota enforcement.
- * Quota accounting must be turned on at mount time.
- */
- if (mp->m_flags & XFS_MOUNT_RDONLY)
- return XFS_ERROR(EROFS);
- return (xfs_qm_scall_quotaon(mp,
- xfs_qm_import_flags(*(uint *)addr)));
-
- case Q_XQUOTAOFF:
- if (mp->m_flags & XFS_MOUNT_RDONLY)
- return XFS_ERROR(EROFS);
- break;
-
- case Q_XQUOTASYNC:
- return xfs_sync_inodes(mp, SYNC_DELWRI);
-
- default:
- break;
- }
-
- if (! XFS_IS_QUOTA_ON(mp))
- return XFS_ERROR(ESRCH);
-
- switch (cmd) {
- case Q_XQUOTAOFF:
- if (mp->m_flags & XFS_MOUNT_RDONLY)
- return XFS_ERROR(EROFS);
- error = xfs_qm_scall_quotaoff(mp,
- xfs_qm_import_flags(*(uint *)addr),
- B_FALSE);
- break;
-
- case Q_XGETQUOTA:
- error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER,
- (fs_disk_quota_t *)addr);
- break;
- case Q_XGETGQUOTA:
- error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
- (fs_disk_quota_t *)addr);
- break;
- case Q_XGETPQUOTA:
- error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
- (fs_disk_quota_t *)addr);
- break;
-
- case Q_XSETQLIM:
- if (mp->m_flags & XFS_MOUNT_RDONLY)
- return XFS_ERROR(EROFS);
- error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
- (fs_disk_quota_t *)addr);
- break;
- case Q_XSETGQLIM:
- if (mp->m_flags & XFS_MOUNT_RDONLY)
- return XFS_ERROR(EROFS);
- error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
- (fs_disk_quota_t *)addr);
- break;
- case Q_XSETPQLIM:
- if (mp->m_flags & XFS_MOUNT_RDONLY)
- return XFS_ERROR(EROFS);
- error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
- (fs_disk_quota_t *)addr);
- break;
-
- default:
- error = XFS_ERROR(EINVAL);
- break;
- }
-
- return (error);
-}
-
-/*
* Turn off quota accounting and/or enforcement for all udquots and/or
* gdquots. Called only at unmount time.
*
@@ -193,11 +74,10 @@ xfs_qm_quotactl(
* incore, and modifies the ondisk dquot directly. Therefore, for example,
* it is an error to call this twice, without purging the cache.
*/
-STATIC int
+int
xfs_qm_scall_quotaoff(
xfs_mount_t *mp,
- uint flags,
- boolean_t force)
+ uint flags)
{
uint dqtype;
int error;
@@ -205,8 +85,6 @@ xfs_qm_scall_quotaoff(
xfs_qoff_logitem_t *qoffstart;
int nculprits;
- if (!force && !capable(CAP_SYS_ADMIN))
- return XFS_ERROR(EPERM);
/*
* No file system can have quotas enabled on disk but not in core.
* Note that quota utilities (like quotaoff) _expect_
@@ -375,7 +253,7 @@ out_error:
return (error);
}
-STATIC int
+int
xfs_qm_scall_trunc_qfiles(
xfs_mount_t *mp,
uint flags)
@@ -383,8 +261,6 @@ xfs_qm_scall_trunc_qfiles(
int error = 0, error2 = 0;
xfs_inode_t *qip;
- if (!capable(CAP_SYS_ADMIN))
- return XFS_ERROR(EPERM);
if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) {
qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags);
return XFS_ERROR(EINVAL);
@@ -416,7 +292,7 @@ xfs_qm_scall_trunc_qfiles(
* effect immediately.
* (Switching on quota accounting must be done at mount time.)
*/
-STATIC int
+int
xfs_qm_scall_quotaon(
xfs_mount_t *mp,
uint flags)
@@ -426,9 +302,6 @@ xfs_qm_scall_quotaon(
uint accflags;
__int64_t sbflags;
- if (!capable(CAP_SYS_ADMIN))
- return XFS_ERROR(EPERM);
-
flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
/*
* Switching on quota accounting must be done at mount time.
@@ -517,7 +390,7 @@ xfs_qm_scall_quotaon(
/*
* Return quota status information, such as uquota-off, enforcements, etc.
*/
-STATIC int
+int
xfs_qm_scall_getqstat(
xfs_mount_t *mp,
fs_quota_stat_t *out)
@@ -582,7 +455,7 @@ xfs_qm_scall_getqstat(
/*
* Adjust quota limits, and start/stop timers accordingly.
*/
-STATIC int
+int
xfs_qm_scall_setqlim(
xfs_mount_t *mp,
xfs_dqid_t id,
@@ -595,9 +468,6 @@ xfs_qm_scall_setqlim(
int error;
xfs_qcnt_t hard, soft;
- if (!capable(CAP_SYS_ADMIN))
- return XFS_ERROR(EPERM);
-
if ((newlim->d_fieldmask &
(FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0)
return (0);
@@ -742,7 +612,7 @@ xfs_qm_scall_setqlim(
return error;
}
-STATIC int
+int
xfs_qm_scall_getquota(
xfs_mount_t *mp,
xfs_dqid_t id,
@@ -935,30 +805,6 @@ xfs_qm_export_dquot(
}
STATIC uint
-xfs_qm_import_qtype_flags(
- uint uflags)
-{
- uint oflags = 0;
-
- /*
- * Can't be more than one, or none.
- */
- if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ==
- (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ||
- ((uflags & (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ==
- (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ||
- ((uflags & (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ==
- (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ||
- ((uflags & (XFS_GROUP_QUOTA|XFS_USER_QUOTA|XFS_PROJ_QUOTA)) == 0))
- return (0);
-
- oflags |= (uflags & XFS_USER_QUOTA) ? XFS_DQ_USER : 0;
- oflags |= (uflags & XFS_PROJ_QUOTA) ? XFS_DQ_PROJ : 0;
- oflags |= (uflags & XFS_GROUP_QUOTA) ? XFS_DQ_GROUP: 0;
- return oflags;
-}
-
-STATIC uint
xfs_qm_export_qtype_flags(
uint flags)
{
@@ -979,26 +825,6 @@ xfs_qm_export_qtype_flags(
}
STATIC uint
-xfs_qm_import_flags(
- uint uflags)
-{
- uint flags = 0;
-
- if (uflags & XFS_QUOTA_UDQ_ACCT)
- flags |= XFS_UQUOTA_ACCT;
- if (uflags & XFS_QUOTA_PDQ_ACCT)
- flags |= XFS_PQUOTA_ACCT;
- if (uflags & XFS_QUOTA_GDQ_ACCT)
- flags |= XFS_GQUOTA_ACCT;
- if (uflags & XFS_QUOTA_UDQ_ENFD)
- flags |= XFS_UQUOTA_ENFD;
- if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD))
- flags |= XFS_OQUOTA_ENFD;
- return (flags);
-}
-
-
-STATIC uint
xfs_qm_export_flags(
uint flags)
{
@@ -1134,7 +960,7 @@ xfs_dqhash_t *qmtest_udqtab;
xfs_dqhash_t *qmtest_gdqtab;
int qmtest_hashmask;
int qmtest_nfails;
-mutex_t qcheck_lock;
+struct mutex qcheck_lock;
#define DQTEST_HASHVAL(mp, id) (((__psunsigned_t)(mp) + \
(__psunsigned_t)(id)) & \
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h
index c4fcea600bc..8286b2842b6 100644
--- a/fs/xfs/quota/xfs_quota_priv.h
+++ b/fs/xfs/quota/xfs_quota_priv.h
@@ -42,34 +42,24 @@
#define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock)
#define XFS_QI_MPL_LIST(mp) ((mp)->m_quotainfo->qi_dqlist)
-#define XFS_QI_MPLLOCK(mp) ((mp)->m_quotainfo->qi_dqlist.qh_lock)
#define XFS_QI_MPLNEXT(mp) ((mp)->m_quotainfo->qi_dqlist.qh_next)
#define XFS_QI_MPLNDQUOTS(mp) ((mp)->m_quotainfo->qi_dqlist.qh_nelems)
-#define XQMLCK(h) (mutex_lock(&((h)->qh_lock)))
-#define XQMUNLCK(h) (mutex_unlock(&((h)->qh_lock)))
-#ifdef DEBUG
-struct xfs_dqhash;
-static inline int XQMISLCKD(struct xfs_dqhash *h)
-{
- if (mutex_trylock(&h->qh_lock)) {
- mutex_unlock(&h->qh_lock);
- return 0;
- }
- return 1;
-}
-#endif
-
-#define XFS_DQ_HASH_LOCK(h) XQMLCK(h)
-#define XFS_DQ_HASH_UNLOCK(h) XQMUNLCK(h)
-#define XFS_DQ_IS_HASH_LOCKED(h) XQMISLCKD(h)
-
-#define xfs_qm_mplist_lock(mp) XQMLCK(&(XFS_QI_MPL_LIST(mp)))
-#define xfs_qm_mplist_unlock(mp) XQMUNLCK(&(XFS_QI_MPL_LIST(mp)))
-#define XFS_QM_IS_MPLIST_LOCKED(mp) XQMISLCKD(&(XFS_QI_MPL_LIST(mp)))
-
-#define xfs_qm_freelist_lock(qm) XQMLCK(&((qm)->qm_dqfreelist))
-#define xfs_qm_freelist_unlock(qm) XQMUNLCK(&((qm)->qm_dqfreelist))
+#define xfs_qm_mplist_lock(mp) \
+ mutex_lock(&(XFS_QI_MPL_LIST(mp).qh_lock))
+#define xfs_qm_mplist_nowait(mp) \
+ mutex_trylock(&(XFS_QI_MPL_LIST(mp).qh_lock))
+#define xfs_qm_mplist_unlock(mp) \
+ mutex_unlock(&(XFS_QI_MPL_LIST(mp).qh_lock))
+#define XFS_QM_IS_MPLIST_LOCKED(mp) \
+ mutex_is_locked(&(XFS_QI_MPL_LIST(mp).qh_lock))
+
+#define xfs_qm_freelist_lock(qm) \
+ mutex_lock(&((qm)->qm_dqfreelist.qh_lock))
+#define xfs_qm_freelist_lock_nowait(qm) \
+ mutex_trylock(&((qm)->qm_dqfreelist.qh_lock))
+#define xfs_qm_freelist_unlock(qm) \
+ mutex_unlock(&((qm)->qm_dqfreelist.qh_lock))
/*
* Hash into a bucket in the dquot hash table, based on <mp, id>.
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index 99611381e74..447173bcf96 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -624,10 +624,9 @@ xfs_trans_dqresv(
xfs_qcnt_t *resbcountp;
xfs_quotainfo_t *q = mp->m_quotainfo;
- if (! (flags & XFS_QMOPT_DQLOCK)) {
- xfs_dqlock(dqp);
- }
- ASSERT(XFS_DQ_IS_LOCKED(dqp));
+
+ xfs_dqlock(dqp);
+
if (flags & XFS_TRANS_DQ_RES_BLKS) {
hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
if (!hardlimit)
@@ -740,10 +739,8 @@ xfs_trans_dqresv(
ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount));
error_return:
- if (! (flags & XFS_QMOPT_DQLOCK)) {
- xfs_dqunlock(dqp);
- }
- return (error);
+ xfs_dqunlock(dqp);
+ return error;
}
@@ -753,8 +750,7 @@ error_return:
* grp/prj quotas is important, because this follows a both-or-nothing
* approach.
*
- * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked.
- * XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
+ * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
* XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota.
* XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
* XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index ae548296542..3f3610a7ee0 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -24,6 +24,7 @@
#include "xfs_ag.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
+#include "xfs_error.h"
static char message[1024]; /* keep it off the stack */
static DEFINE_SPINLOCK(xfs_err_lock);
diff --git a/fs/xfs/support/uuid.c b/fs/xfs/support/uuid.c
index 5830c040ea7..b83f76b6d41 100644
--- a/fs/xfs/support/uuid.c
+++ b/fs/xfs/support/uuid.c
@@ -17,10 +17,6 @@
*/
#include <xfs.h>
-static DEFINE_MUTEX(uuid_monitor);
-static int uuid_table_size;
-static uuid_t *uuid_table;
-
/* IRIX interpretation of an uuid_t */
typedef struct {
__be32 uu_timelow;
@@ -46,12 +42,6 @@ uuid_getnodeuniq(uuid_t *uuid, int fsid [2])
fsid[1] = be32_to_cpu(uup->uu_timelow);
}
-void
-uuid_create_nil(uuid_t *uuid)
-{
- memset(uuid, 0, sizeof(*uuid));
-}
-
int
uuid_is_nil(uuid_t *uuid)
{
@@ -71,64 +61,3 @@ uuid_equal(uuid_t *uuid1, uuid_t *uuid2)
{
return memcmp(uuid1, uuid2, sizeof(uuid_t)) ? 0 : 1;
}
-
-/*
- * Given a 128-bit uuid, return a 64-bit value by adding the top and bottom
- * 64-bit words. NOTE: This function can not be changed EVER. Although
- * brain-dead, some applications depend on this 64-bit value remaining
- * persistent. Specifically, DMI vendors store the value as a persistent
- * filehandle.
- */
-__uint64_t
-uuid_hash64(uuid_t *uuid)
-{
- __uint64_t *sp = (__uint64_t *)uuid;
-
- return sp[0] + sp[1];
-}
-
-int
-uuid_table_insert(uuid_t *uuid)
-{
- int i, hole;
-
- mutex_lock(&uuid_monitor);
- for (i = 0, hole = -1; i < uuid_table_size; i++) {
- if (uuid_is_nil(&uuid_table[i])) {
- hole = i;
- continue;
- }
- if (uuid_equal(uuid, &uuid_table[i])) {
- mutex_unlock(&uuid_monitor);
- return 0;
- }
- }
- if (hole < 0) {
- uuid_table = kmem_realloc(uuid_table,
- (uuid_table_size + 1) * sizeof(*uuid_table),
- uuid_table_size * sizeof(*uuid_table),
- KM_SLEEP);
- hole = uuid_table_size++;
- }
- uuid_table[hole] = *uuid;
- mutex_unlock(&uuid_monitor);
- return 1;
-}
-
-void
-uuid_table_remove(uuid_t *uuid)
-{
- int i;
-
- mutex_lock(&uuid_monitor);
- for (i = 0; i < uuid_table_size; i++) {
- if (uuid_is_nil(&uuid_table[i]))
- continue;
- if (!uuid_equal(uuid, &uuid_table[i]))
- continue;
- uuid_create_nil(&uuid_table[i]);
- break;
- }
- ASSERT(i < uuid_table_size);
- mutex_unlock(&uuid_monitor);
-}
diff --git a/fs/xfs/support/uuid.h b/fs/xfs/support/uuid.h
index cff5b607d44..4732d71262c 100644
--- a/fs/xfs/support/uuid.h
+++ b/fs/xfs/support/uuid.h
@@ -22,12 +22,8 @@ typedef struct {
unsigned char __u_bits[16];
} uuid_t;
-extern void uuid_create_nil(uuid_t *uuid);
extern int uuid_is_nil(uuid_t *uuid);
extern int uuid_equal(uuid_t *uuid1, uuid_t *uuid2);
extern void uuid_getnodeuniq(uuid_t *uuid, int fsid [2]);
-extern __uint64_t uuid_hash64(uuid_t *uuid);
-extern int uuid_table_insert(uuid_t *uuid);
-extern void uuid_table_remove(uuid_t *uuid);
#endif /* __XFS_SUPPORT_UUID_H__ */
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index 143d63ecb20..c8641f713ca 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -223,8 +223,8 @@ typedef struct xfs_perag
be32_to_cpu((a)->agf_levels[XFS_BTNUM_CNTi]), mp))
#define XFS_MIN_FREELIST_PAG(pag,mp) \
(XFS_MIN_FREELIST_RAW( \
- (uint_t)(pag)->pagf_levels[XFS_BTNUM_BNOi], \
- (uint_t)(pag)->pagf_levels[XFS_BTNUM_CNTi], mp))
+ (unsigned int)(pag)->pagf_levels[XFS_BTNUM_BNOi], \
+ (unsigned int)(pag)->pagf_levels[XFS_BTNUM_CNTi], mp))
#define XFS_AGB_TO_FSB(mp,agno,agbno) \
(((xfs_fsblock_t)(agno) << (mp)->m_sb.sb_agblklog) | (agbno))
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 028e44e58ea..2cf944eb796 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -1872,6 +1872,25 @@ xfs_alloc_compute_maxlevels(
}
/*
+ * Find the length of the longest extent in an AG.
+ */
+xfs_extlen_t
+xfs_alloc_longest_free_extent(
+ struct xfs_mount *mp,
+ struct xfs_perag *pag)
+{
+ xfs_extlen_t need, delta = 0;
+
+ need = XFS_MIN_FREELIST_PAG(pag, mp);
+ if (need > pag->pagf_flcount)
+ delta = need - pag->pagf_flcount;
+
+ if (pag->pagf_longest > delta)
+ return pag->pagf_longest - delta;
+ return pag->pagf_flcount > 0 || pag->pagf_longest > 0;
+}
+
+/*
* Decide whether to use this allocation group for this allocation.
* If so, fix up the btree freelist's size.
*/
@@ -1923,15 +1942,12 @@ xfs_alloc_fix_freelist(
}
if (!(flags & XFS_ALLOC_FLAG_FREEING)) {
- need = XFS_MIN_FREELIST_PAG(pag, mp);
- delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0;
/*
* If it looks like there isn't a long enough extent, or enough
* total blocks, reject it.
*/
- longest = (pag->pagf_longest > delta) ?
- (pag->pagf_longest - delta) :
- (pag->pagf_flcount > 0 || pag->pagf_longest > 0);
+ need = XFS_MIN_FREELIST_PAG(pag, mp);
+ longest = xfs_alloc_longest_free_extent(mp, pag);
if ((args->minlen + args->alignment + args->minalignslop - 1) >
longest ||
((int)(pag->pagf_freeblks + pag->pagf_flcount -
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
index 588172796f7..e704caee10d 100644
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -100,6 +100,12 @@ typedef struct xfs_alloc_arg {
#define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/
#define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */
+/*
+ * Find the length of the longest extent in an AG.
+ */
+xfs_extlen_t
+xfs_alloc_longest_free_extent(struct xfs_mount *mp,
+ struct xfs_perag *pag);
#ifdef __KERNEL__
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 6c323f8a4cd..afdc8911637 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -155,7 +155,8 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
* minimum offset only needs to be the space required for
* the btree root.
*/
- if (!dp->i_d.di_forkoff && dp->i_df.if_bytes > mp->m_attroffset)
+ if (!dp->i_d.di_forkoff && dp->i_df.if_bytes >
+ xfs_default_attroffset(dp))
dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
break;
@@ -298,6 +299,26 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
}
/*
+ * After the last attribute is removed revert to original inode format,
+ * making all literal area available to the data fork once more.
+ */
+STATIC void
+xfs_attr_fork_reset(
+ struct xfs_inode *ip,
+ struct xfs_trans *tp)
+{
+ xfs_idestroy_fork(ip, XFS_ATTR_FORK);
+ ip->i_d.di_forkoff = 0;
+ ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
+
+ ASSERT(ip->i_d.di_anextents == 0);
+ ASSERT(ip->i_afp == NULL);
+
+ ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t);
+ xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+}
+
+/*
* Remove an attribute from the shortform attribute list structure.
*/
int
@@ -344,22 +365,10 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
*/
totsize -= size;
if (totsize == sizeof(xfs_attr_sf_hdr_t) &&
- !(args->op_flags & XFS_DA_OP_ADDNAME) &&
- (mp->m_flags & XFS_MOUNT_ATTR2) &&
- (dp->i_d.di_format != XFS_DINODE_FMT_BTREE)) {
- /*
- * Last attribute now removed, revert to original
- * inode format making all literal area available
- * to the data fork once more.
- */
- xfs_idestroy_fork(dp, XFS_ATTR_FORK);
- dp->i_d.di_forkoff = 0;
- dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
- ASSERT(dp->i_d.di_anextents == 0);
- ASSERT(dp->i_afp == NULL);
- dp->i_df.if_ext_max =
- XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
+ (mp->m_flags & XFS_MOUNT_ATTR2) &&
+ (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
+ !(args->op_flags & XFS_DA_OP_ADDNAME)) {
+ xfs_attr_fork_reset(dp, args->trans);
} else {
xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
@@ -786,20 +795,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
if (forkoff == -1) {
ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2);
ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE);
-
- /*
- * Last attribute was removed, revert to original
- * inode format making all literal area available
- * to the data fork once more.
- */
- xfs_idestroy_fork(dp, XFS_ATTR_FORK);
- dp->i_d.di_forkoff = 0;
- dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
- ASSERT(dp->i_d.di_anextents == 0);
- ASSERT(dp->i_afp == NULL);
- dp->i_df.if_ext_max =
- XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
+ xfs_attr_fork_reset(dp, args->trans);
goto out;
}
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index c852cd65aae..3a6ed426327 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -2479,7 +2479,7 @@ xfs_bmap_adjacent(
fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
/*
* If allocating at eof, and there's a previous real block,
- * try to use it's last block as our starting point.
+ * try to use its last block as our starting point.
*/
if (ap->eof && ap->prevp->br_startoff != NULLFILEOFF &&
!isnullstartblock(ap->prevp->br_startblock) &&
@@ -2712,9 +2712,6 @@ xfs_bmap_btalloc(
xfs_agnumber_t startag;
xfs_alloc_arg_t args;
xfs_extlen_t blen;
- xfs_extlen_t delta;
- xfs_extlen_t longest;
- xfs_extlen_t need;
xfs_extlen_t nextminlen = 0;
xfs_perag_t *pag;
int nullfb; /* true if ap->firstblock isn't set */
@@ -2796,13 +2793,8 @@ xfs_bmap_btalloc(
* See xfs_alloc_fix_freelist...
*/
if (pag->pagf_init) {
- need = XFS_MIN_FREELIST_PAG(pag, mp);
- delta = need > pag->pagf_flcount ?
- need - pag->pagf_flcount : 0;
- longest = (pag->pagf_longest > delta) ?
- (pag->pagf_longest - delta) :
- (pag->pagf_flcount > 0 ||
- pag->pagf_longest > 0);
+ xfs_extlen_t longest;
+ longest = xfs_alloc_longest_free_extent(mp, pag);
if (blen < longest)
blen = longest;
} else
@@ -3577,6 +3569,27 @@ xfs_bmap_extents_to_btree(
}
/*
+ * Calculate the default attribute fork offset for newly created inodes.
+ */
+uint
+xfs_default_attroffset(
+ struct xfs_inode *ip)
+{
+ struct xfs_mount *mp = ip->i_mount;
+ uint offset;
+
+ if (mp->m_sb.sb_inodesize == 256) {
+ offset = XFS_LITINO(mp) -
+ XFS_BMDR_SPACE_CALC(MINABTPTRS);
+ } else {
+ offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
+ }
+
+ ASSERT(offset < XFS_LITINO(mp));
+ return offset;
+}
+
+/*
* Helper routine to reset inode di_forkoff field when switching
* attribute fork from local to extent format - we reset it where
* possible to make space available for inline data fork extents.
@@ -3588,15 +3601,18 @@ xfs_bmap_forkoff_reset(
int whichfork)
{
if (whichfork == XFS_ATTR_FORK &&
- (ip->i_d.di_format != XFS_DINODE_FMT_DEV) &&
- (ip->i_d.di_format != XFS_DINODE_FMT_UUID) &&
- (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
- ((mp->m_attroffset >> 3) > ip->i_d.di_forkoff)) {
- ip->i_d.di_forkoff = mp->m_attroffset >> 3;
- ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) /
- (uint)sizeof(xfs_bmbt_rec_t);
- ip->i_afp->if_ext_max = XFS_IFORK_ASIZE(ip) /
- (uint)sizeof(xfs_bmbt_rec_t);
+ ip->i_d.di_format != XFS_DINODE_FMT_DEV &&
+ ip->i_d.di_format != XFS_DINODE_FMT_UUID &&
+ ip->i_d.di_format != XFS_DINODE_FMT_BTREE) {
+ uint dfl_forkoff = xfs_default_attroffset(ip) >> 3;
+
+ if (dfl_forkoff > ip->i_d.di_forkoff) {
+ ip->i_d.di_forkoff = dfl_forkoff;
+ ip->i_df.if_ext_max =
+ XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t);
+ ip->i_afp->if_ext_max =
+ XFS_IFORK_ASIZE(ip) / sizeof(xfs_bmbt_rec_t);
+ }
}
}
@@ -4065,7 +4081,7 @@ xfs_bmap_add_attrfork(
case XFS_DINODE_FMT_BTREE:
ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
if (!ip->i_d.di_forkoff)
- ip->i_d.di_forkoff = mp->m_attroffset >> 3;
+ ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3;
else if (mp->m_flags & XFS_MOUNT_ATTR2)
version = 2;
break;
@@ -4212,12 +4228,12 @@ xfs_bmap_compute_maxlevels(
* (a signed 16-bit number, xfs_aextnum_t).
*
* Note that we can no longer assume that if we are in ATTR1 that
- * the fork offset of all the inodes will be (m_attroffset >> 3)
- * because we could have mounted with ATTR2 and then mounted back
- * with ATTR1, keeping the di_forkoff's fixed but probably at
- * various positions. Therefore, for both ATTR1 and ATTR2
- * we have to assume the worst case scenario of a minimum size
- * available.
+ * the fork offset of all the inodes will be
+ * (xfs_default_attroffset(ip) >> 3) because we could have mounted
+ * with ATTR2 and then mounted back with ATTR1, keeping the
+ * di_forkoff's fixed but probably at various positions. Therefore,
+ * for both ATTR1 and ATTR2 we have to assume the worst case scenario
+ * of a minimum size available.
*/
if (whichfork == XFS_DATA_FORK) {
maxleafents = MAXEXTNUM;
@@ -4804,7 +4820,7 @@ xfs_bmapi(
xfs_extlen_t minlen; /* min allocation size */
xfs_mount_t *mp; /* xfs mount structure */
int n; /* current extent index */
- int nallocs; /* number of extents alloc\'d */
+ int nallocs; /* number of extents alloc'd */
xfs_extnum_t nextents; /* number of extents in file */
xfs_fileoff_t obno; /* old block number (offset) */
xfs_bmbt_irec_t prev; /* previous file extent record */
@@ -6204,7 +6220,7 @@ xfs_bmap_get_bp(
return(bp);
}
-void
+STATIC void
xfs_check_block(
struct xfs_btree_block *block,
xfs_mount_t *mp,
@@ -6494,7 +6510,7 @@ xfs_bmap_count_tree(
block = XFS_BUF_TO_BLOCK(bp);
if (--level) {
- /* Not at node above leafs, count this level of nodes */
+ /* Not at node above leaves, count this level of nodes */
nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
while (nextbno != NULLFSBLOCK) {
if ((error = xfs_btree_read_bufl(mp, tp, nextbno,
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index be2979d88d3..1b8ff9256bd 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -125,7 +125,7 @@ typedef struct xfs_bmalloca {
struct xfs_bmbt_irec *gotp; /* extent after, or delayed */
xfs_extlen_t alen; /* i/o length asked/allocated */
xfs_extlen_t total; /* total blocks needed for xaction */
- xfs_extlen_t minlen; /* mininum allocation size (blocks) */
+ xfs_extlen_t minlen; /* minimum allocation size (blocks) */
xfs_extlen_t minleft; /* amount must be left after alloc */
char eof; /* set if allocating past last extent */
char wasdel; /* replacing a delayed allocation */
@@ -338,6 +338,10 @@ xfs_check_nostate_extents(
xfs_extnum_t idx,
xfs_extnum_t num);
+uint
+xfs_default_attroffset(
+ struct xfs_inode *ip);
+
#ifdef __KERNEL__
/*
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index e73c332eb23..e9df9957482 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -1883,7 +1883,7 @@ xfs_btree_lshift(
/*
* We add one entry to the left side and remove one for the right side.
- * Accout for it here, the changes will be updated on disk and logged
+ * Account for it here, the changes will be updated on disk and logged
* later.
*/
lrecs++;
@@ -3535,7 +3535,7 @@ xfs_btree_delrec(
XFS_BTREE_STATS_INC(cur, join);
/*
- * Fix up the the number of records and right block pointer in the
+ * Fix up the number of records and right block pointer in the
* surviving block, and log it.
*/
xfs_btree_set_numrecs(left, lrecs + rrecs);
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
index 789fffdf8b2..4f852b735b9 100644
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -41,7 +41,7 @@ extern kmem_zone_t *xfs_btree_cur_zone;
/*
* Generic btree header.
*
- * This is a comination of the actual format used on disk for short and long
+ * This is a combination of the actual format used on disk for short and long
* format btrees. The first three fields are shared by both format, but
* the pointers are different and should be used with care.
*
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index c45f74ff1a5..9ff6e57a507 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -1503,7 +1503,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
* This is implemented with some source-level loop unrolling.
*/
xfs_dahash_t
-xfs_da_hashname(const uchar_t *name, int namelen)
+xfs_da_hashname(const __uint8_t *name, int namelen)
{
xfs_dahash_t hash;
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index 70b710c1792..8c536167bf7 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -91,9 +91,9 @@ enum xfs_dacmp {
* Structure to ease passing around component names.
*/
typedef struct xfs_da_args {
- const uchar_t *name; /* string (maybe not NULL terminated) */
+ const __uint8_t *name; /* string (maybe not NULL terminated) */
int namelen; /* length of string (maybe no NULL) */
- uchar_t *value; /* set of bytes (maybe contain NULLs) */
+ __uint8_t *value; /* set of bytes (maybe contain NULLs) */
int valuelen; /* length of value */
int flags; /* argument flags (eg: ATTR_NOCREATE) */
xfs_dahash_t hashval; /* hash value of name */
@@ -185,7 +185,7 @@ typedef struct xfs_da_state {
unsigned char inleaf; /* insert into 1->lf, 0->splf */
unsigned char extravalid; /* T/F: extrablk is in use */
unsigned char extraafter; /* T/F: extrablk is after new */
- xfs_da_state_blk_t extrablk; /* for double-splits on leafs */
+ xfs_da_state_blk_t extrablk; /* for double-splits on leaves */
/* for dirv2 extrablk is data */
} xfs_da_state_t;
@@ -251,7 +251,7 @@ xfs_daddr_t xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp,
int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
xfs_dabuf_t *dead_buf);
-uint xfs_da_hashname(const uchar_t *name_string, int name_length);
+uint xfs_da_hashname(const __uint8_t *name_string, int name_length);
enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args,
const char *name, int len);
@@ -268,5 +268,6 @@ xfs_daddr_t xfs_da_blkno(xfs_dabuf_t *dabuf);
extern struct kmem_zone *xfs_da_state_zone;
extern struct kmem_zone *xfs_dabuf_zone;
+extern const struct xfs_nameops xfs_default_nameops;
#endif /* __XFS_DA_BTREE_H__ */
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index f8278cfcc1d..e6d839bddbf 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -79,6 +79,12 @@ xfs_swapext(
goto out_put_target_file;
}
+ if (IS_SWAPFILE(file->f_path.dentry->d_inode) ||
+ IS_SWAPFILE(target_file->f_path.dentry->d_inode)) {
+ error = XFS_ERROR(EINVAL);
+ goto out_put_target_file;
+ }
+
ip = XFS_I(file->f_path.dentry->d_inode);
tip = XFS_I(target_file->f_path.dentry->d_inode);
@@ -118,19 +124,17 @@ xfs_swap_extents(
xfs_bstat_t *sbp = &sxp->sx_stat;
xfs_ifork_t *tempifp, *ifp, *tifp;
int ilf_fields, tilf_fields;
- static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
int error = 0;
int aforkblks = 0;
int taforkblks = 0;
__uint64_t tmp;
- char locked = 0;
mp = ip->i_mount;
tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
if (!tempifp) {
error = XFS_ERROR(ENOMEM);
- goto error0;
+ goto out;
}
sbp = &sxp->sx_stat;
@@ -143,25 +147,24 @@ xfs_swap_extents(
*/
xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL);
xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
- locked = 1;
/* Verify that both files have the same format */
if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) {
error = XFS_ERROR(EINVAL);
- goto error0;
+ goto out_unlock;
}
/* Verify both files are either real-time or non-realtime */
if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) {
error = XFS_ERROR(EINVAL);
- goto error0;
+ goto out_unlock;
}
/* Should never get a local format */
if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL ||
tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
error = XFS_ERROR(EINVAL);
- goto error0;
+ goto out_unlock;
}
if (VN_CACHED(VFS_I(tip)) != 0) {
@@ -169,13 +172,13 @@ xfs_swap_extents(
error = xfs_flushinval_pages(tip, 0, -1,
FI_REMAPF_LOCKED);
if (error)
- goto error0;
+ goto out_unlock;
}
/* Verify O_DIRECT for ftmp */
if (VN_CACHED(VFS_I(tip)) != 0) {
error = XFS_ERROR(EINVAL);
- goto error0;
+ goto out_unlock;
}
/* Verify all data are being swapped */
@@ -183,7 +186,7 @@ xfs_swap_extents(
sxp->sx_length != ip->i_d.di_size ||
sxp->sx_length != tip->i_d.di_size) {
error = XFS_ERROR(EFAULT);
- goto error0;
+ goto out_unlock;
}
/*
@@ -193,7 +196,7 @@ xfs_swap_extents(
*/
if ( XFS_IFORK_Q(ip) != XFS_IFORK_Q(tip) ) {
error = XFS_ERROR(EINVAL);
- goto error0;
+ goto out_unlock;
}
/*
@@ -208,7 +211,7 @@ xfs_swap_extents(
(sbp->bs_mtime.tv_sec != ip->i_d.di_mtime.t_sec) ||
(sbp->bs_mtime.tv_nsec != ip->i_d.di_mtime.t_nsec)) {
error = XFS_ERROR(EBUSY);
- goto error0;
+ goto out_unlock;
}
/* We need to fail if the file is memory mapped. Once we have tossed
@@ -219,7 +222,7 @@ xfs_swap_extents(
*/
if (VN_MAPPED(VFS_I(ip))) {
error = XFS_ERROR(EBUSY);
- goto error0;
+ goto out_unlock;
}
xfs_iunlock(ip, XFS_ILOCK_EXCL);
@@ -242,8 +245,7 @@ xfs_swap_extents(
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
xfs_iunlock(tip, XFS_IOLOCK_EXCL);
xfs_trans_cancel(tp, 0);
- locked = 0;
- goto error0;
+ goto out;
}
xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
@@ -253,19 +255,15 @@ xfs_swap_extents(
if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) &&
(ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &aforkblks);
- if (error) {
- xfs_trans_cancel(tp, 0);
- goto error0;
- }
+ if (error)
+ goto out_trans_cancel;
}
if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) &&
(tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK,
&taforkblks);
- if (error) {
- xfs_trans_cancel(tp, 0);
- goto error0;
- }
+ if (error)
+ goto out_trans_cancel;
}
/*
@@ -332,10 +330,10 @@ xfs_swap_extents(
IHOLD(ip);
- xfs_trans_ijoin(tp, ip, lock_flags);
+ xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
IHOLD(tip);
- xfs_trans_ijoin(tp, tip, lock_flags);
+ xfs_trans_ijoin(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_trans_log_inode(tp, ip, ilf_fields);
xfs_trans_log_inode(tp, tip, tilf_fields);
@@ -344,19 +342,19 @@ xfs_swap_extents(
* If this is a synchronous mount, make sure that the
* transaction goes to disk before returning to the user.
*/
- if (mp->m_flags & XFS_MOUNT_WSYNC) {
+ if (mp->m_flags & XFS_MOUNT_WSYNC)
xfs_trans_set_sync(tp);
- }
error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT);
- locked = 0;
- error0:
- if (locked) {
- xfs_iunlock(ip, lock_flags);
- xfs_iunlock(tip, lock_flags);
- }
- if (tempifp != NULL)
- kmem_free(tempifp);
+out_unlock:
+ xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
+ xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
+out:
+ kmem_free(tempifp);
return error;
+
+out_trans_cancel:
+ xfs_trans_cancel(tp, 0);
+ goto out_unlock;
}
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h
index 162e8726df5..e5b153b2e6a 100644
--- a/fs/xfs/xfs_dinode.h
+++ b/fs/xfs/xfs_dinode.h
@@ -103,7 +103,9 @@ typedef enum xfs_dinode_fmt {
/*
* Inode size for given fs.
*/
-#define XFS_LITINO(mp) ((mp)->m_litino)
+#define XFS_LITINO(mp) \
+ ((int)(((mp)->m_sb.sb_inodesize) - sizeof(struct xfs_dinode)))
+
#define XFS_BROOT_SIZE_ADJ \
(XFS_BTREE_LBLOCK_LEN - sizeof(xfs_bmdr_block_t))
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 1afb12278b8..c657bec6d95 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -46,8 +46,6 @@
struct xfs_name xfs_name_dotdot = {"..", 2};
-extern const struct xfs_nameops xfs_default_nameops;
-
/*
* ASCII case-insensitive (ie. A-Z) support for directories that was
* used in IRIX.
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index e1f0a06aaf0..ab52e9e1c1e 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -448,7 +448,6 @@ xfs_dir2_block_getdents(
xfs_mount_t *mp; /* filesystem mount point */
char *ptr; /* current data entry */
int wantoff; /* starting block offset */
- xfs_ino_t ino;
xfs_off_t cook;
mp = dp->i_mount;
@@ -509,16 +508,12 @@ xfs_dir2_block_getdents(
cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
(char *)dep - (char *)block);
- ino = be64_to_cpu(dep->inumber);
-#if XFS_BIG_INUMS
- ino += mp->m_inoadd;
-#endif
/*
* If it didn't fit, set the final offset to here & return.
*/
if (filldir(dirent, dep->name, dep->namelen, cook & 0x7fffffff,
- ino, DT_UNKNOWN)) {
+ be64_to_cpu(dep->inumber), DT_UNKNOWN)) {
*offset = cook & 0x7fffffff;
xfs_da_brelse(NULL, bp);
return 0;
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h
index b816e025273..efbc290c7fe 100644
--- a/fs/xfs/xfs_dir2_data.h
+++ b/fs/xfs/xfs_dir2_data.h
@@ -38,7 +38,7 @@ struct xfs_trans;
/*
* Directory address space divided into sections,
- * spaces separated by 32gb.
+ * spaces separated by 32GB.
*/
#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
#define XFS_DIR2_DATA_SPACE 0
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index ef805a374ee..fa913e45944 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -549,7 +549,7 @@ xfs_dir2_leaf_addname(
* Check the internal consistency of a leaf1 block.
* Pop an assert if something is wrong.
*/
-void
+STATIC void
xfs_dir2_leaf_check(
xfs_inode_t *dp, /* incore directory inode */
xfs_dabuf_t *bp) /* leaf's buffer */
@@ -780,7 +780,6 @@ xfs_dir2_leaf_getdents(
int ra_index; /* *map index for read-ahead */
int ra_offset; /* map entry offset for ra */
int ra_want; /* readahead count wanted */
- xfs_ino_t ino;
/*
* If the offset is at or past the largest allowed value,
@@ -1076,24 +1075,12 @@ xfs_dir2_leaf_getdents(
continue;
}
- /*
- * Copy the entry into the putargs, and try formatting it.
- */
dep = (xfs_dir2_data_entry_t *)ptr;
-
length = xfs_dir2_data_entsize(dep->namelen);
- ino = be64_to_cpu(dep->inumber);
-#if XFS_BIG_INUMS
- ino += mp->m_inoadd;
-#endif
-
- /*
- * Won't fit. Return to caller.
- */
if (filldir(dirent, dep->name, dep->namelen,
xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff,
- ino, DT_UNKNOWN))
+ be64_to_cpu(dep->inumber), DT_UNKNOWN))
break;
/*
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index fa6c3a5ddbc..5a81ccd1045 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -1104,7 +1104,7 @@ xfs_dir2_leafn_remove(
}
xfs_dir2_leafn_check(dp, bp);
/*
- * Return indication of whether this leaf block is emtpy enough
+ * Return indication of whether this leaf block is empty enough
* to justify trying to join it with a neighbor.
*/
*rval =
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index a8a8a6efad5..e89734e8464 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -748,11 +748,7 @@ xfs_dir2_sf_getdents(
* Put . entry unless we're starting past it.
*/
if (*offset <= dot_offset) {
- ino = dp->i_ino;
-#if XFS_BIG_INUMS
- ino += mp->m_inoadd;
-#endif
- if (filldir(dirent, ".", 1, dot_offset & 0x7fffffff, ino, DT_DIR)) {
+ if (filldir(dirent, ".", 1, dot_offset & 0x7fffffff, dp->i_ino, DT_DIR)) {
*offset = dot_offset & 0x7fffffff;
return 0;
}
@@ -763,9 +759,6 @@ xfs_dir2_sf_getdents(
*/
if (*offset <= dotdot_offset) {
ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent);
-#if XFS_BIG_INUMS
- ino += mp->m_inoadd;
-#endif
if (filldir(dirent, "..", 2, dotdot_offset & 0x7fffffff, ino, DT_DIR)) {
*offset = dotdot_offset & 0x7fffffff;
return 0;
@@ -786,10 +779,6 @@ xfs_dir2_sf_getdents(
}
ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep));
-#if XFS_BIG_INUMS
- ino += mp->m_inoadd;
-#endif
-
if (filldir(dirent, sfep->name, sfep->namelen,
off & 0x7fffffff, ino, DT_UNKNOWN)) {
*offset = off & 0x7fffffff;
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h
index 2f049f63e85..0d22c56fdf6 100644
--- a/fs/xfs/xfs_extfree_item.h
+++ b/fs/xfs/xfs_extfree_item.h
@@ -33,12 +33,10 @@ typedef struct xfs_extent {
* conversion routine.
*/
-#ifndef HAVE_FORMAT32
typedef struct xfs_extent_32 {
__uint64_t ext_start;
__uint32_t ext_len;
} __attribute__((packed)) xfs_extent_32_t;
-#endif
typedef struct xfs_extent_64 {
__uint64_t ext_start;
@@ -59,7 +57,6 @@ typedef struct xfs_efi_log_format {
xfs_extent_t efi_extents[1]; /* array of extents to free */
} xfs_efi_log_format_t;
-#ifndef HAVE_FORMAT32
typedef struct xfs_efi_log_format_32 {
__uint16_t efi_type; /* efi log item type */
__uint16_t efi_size; /* size of this item */
@@ -67,7 +64,6 @@ typedef struct xfs_efi_log_format_32 {
__uint64_t efi_id; /* efi identifier */
xfs_extent_32_t efi_extents[1]; /* array of extents to free */
} __attribute__((packed)) xfs_efi_log_format_32_t;
-#endif
typedef struct xfs_efi_log_format_64 {
__uint16_t efi_type; /* efi log item type */
@@ -90,7 +86,6 @@ typedef struct xfs_efd_log_format {
xfs_extent_t efd_extents[1]; /* array of extents freed */
} xfs_efd_log_format_t;
-#ifndef HAVE_FORMAT32
typedef struct xfs_efd_log_format_32 {
__uint16_t efd_type; /* efd log item type */
__uint16_t efd_size; /* size of this item */
@@ -98,7 +93,6 @@ typedef struct xfs_efd_log_format_32 {
__uint64_t efd_efi_id; /* id of corresponding efi */
xfs_extent_32_t efd_extents[1]; /* array of extents freed */
} __attribute__((packed)) xfs_efd_log_format_32_t;
-#endif
typedef struct xfs_efd_log_format_64 {
__uint16_t efd_type; /* efd log item type */
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c
index f3bb75da384..6c87c8f304e 100644
--- a/fs/xfs/xfs_filestream.c
+++ b/fs/xfs/xfs_filestream.c
@@ -140,7 +140,7 @@ _xfs_filestream_pick_ag(
xfs_extlen_t minlen)
{
int err, trylock, nscan;
- xfs_extlen_t delta, longest, need, free, minfree, maxfree = 0;
+ xfs_extlen_t longest, free, minfree, maxfree = 0;
xfs_agnumber_t ag, max_ag = NULLAGNUMBER;
struct xfs_perag *pag;
@@ -186,12 +186,7 @@ _xfs_filestream_pick_ag(
goto next_ag;
}
- need = XFS_MIN_FREELIST_PAG(pag, mp);
- delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0;
- longest = (pag->pagf_longest > delta) ?
- (pag->pagf_longest - delta) :
- (pag->pagf_flcount > 0 || pag->pagf_longest > 0);
-
+ longest = xfs_alloc_longest_free_extent(mp, pag);
if (((minlen && longest >= minlen) ||
(!minlen && pag->pagf_freeblks >= minfree)) &&
(!pag->pagf_metadata || !(flags & XFS_PICK_USERDATA) ||
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 680d0e0ec93..8379e3bca26 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -576,7 +576,7 @@ out:
if (fdblks_delta) {
/*
* If we are putting blocks back here, m_resblks_avail is
- * already at it's max so this will put it in the free pool.
+ * already at its max so this will put it in the free pool.
*
* If we need space, we'll either succeed in getting it
* from the free block count or we'll get an enospc. If
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index ab016e5ae7b..3120a3a5e20 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -230,7 +230,7 @@ xfs_ialloc_ag_alloc(
args.minalignslop = xfs_ialloc_cluster_alignment(&args) - 1;
/* Allow space for the inode btree to split. */
- args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
+ args.minleft = args.mp->m_in_maxlevels - 1;
if ((error = xfs_alloc_vextent(&args)))
return error;
} else
@@ -270,7 +270,7 @@ xfs_ialloc_ag_alloc(
/*
* Allow space for the inode btree to split.
*/
- args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
+ args.minleft = args.mp->m_in_maxlevels - 1;
if ((error = xfs_alloc_vextent(&args)))
return error;
}
@@ -349,7 +349,7 @@ xfs_ialloc_ag_alloc(
* Initialize all inodes in this buffer and then log them.
*
* XXX: It would be much better if we had just one transaction to
- * log a whole cluster of inodes instead of all the indivdual
+ * log a whole cluster of inodes instead of all the individual
* transactions causing a lot of log traffic.
*/
xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog);
@@ -943,7 +943,7 @@ nextag:
ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) %
XFS_INODES_PER_CHUNK) == 0);
ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset);
- XFS_INOBT_CLR_FREE(&rec, offset);
+ rec.ir_free &= ~XFS_INOBT_MASK(offset);
rec.ir_freecount--;
if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount,
rec.ir_free)))
@@ -1105,11 +1105,11 @@ xfs_difree(
*/
off = agino - rec.ir_startino;
ASSERT(off >= 0 && off < XFS_INODES_PER_CHUNK);
- ASSERT(!XFS_INOBT_IS_FREE(&rec, off));
+ ASSERT(!(rec.ir_free & XFS_INOBT_MASK(off)));
/*
* Mark the inode free & increment the count.
*/
- XFS_INOBT_SET_FREE(&rec, off);
+ rec.ir_free |= XFS_INOBT_MASK(off);
rec.ir_freecount++;
/*
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index 99f2408e8d8..c282a9af539 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -164,7 +164,7 @@ xfs_inobt_init_rec_from_cur(
}
/*
- * intial value of ptr for lookup
+ * initial value of ptr for lookup
*/
STATIC void
xfs_inobt_init_ptr_from_cur(
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h
index 5580e255ff0..f782ad0c476 100644
--- a/fs/xfs/xfs_ialloc_btree.h
+++ b/fs/xfs/xfs_ialloc_btree.h
@@ -32,14 +32,14 @@ struct xfs_mount;
#define XFS_IBT_MAGIC 0x49414254 /* 'IABT' */
typedef __uint64_t xfs_inofree_t;
-#define XFS_INODES_PER_CHUNK (NBBY * sizeof(xfs_inofree_t))
+#define XFS_INODES_PER_CHUNK (NBBY * sizeof(xfs_inofree_t))
#define XFS_INODES_PER_CHUNK_LOG (XFS_NBBYLOG + 3)
-#define XFS_INOBT_ALL_FREE ((xfs_inofree_t)-1)
+#define XFS_INOBT_ALL_FREE ((xfs_inofree_t)-1)
+#define XFS_INOBT_MASK(i) ((xfs_inofree_t)1 << (i))
static inline xfs_inofree_t xfs_inobt_maskn(int i, int n)
{
- return (((n) >= XFS_INODES_PER_CHUNK ? \
- (xfs_inofree_t)0 : ((xfs_inofree_t)1 << (n))) - 1) << (i);
+ return ((n >= XFS_INODES_PER_CHUNK ? 0 : XFS_INOBT_MASK(n)) - 1) << i;
}
/*
@@ -69,20 +69,6 @@ typedef struct xfs_inobt_key {
typedef __be32 xfs_inobt_ptr_t;
/*
- * Bit manipulations for ir_free.
- */
-#define XFS_INOBT_MASK(i) ((xfs_inofree_t)1 << (i))
-#define XFS_INOBT_IS_FREE(rp,i) \
- (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0)
-#define XFS_INOBT_SET_FREE(rp,i) ((rp)->ir_free |= XFS_INOBT_MASK(i))
-#define XFS_INOBT_CLR_FREE(rp,i) ((rp)->ir_free &= ~XFS_INOBT_MASK(i))
-
-/*
- * Maximum number of inode btree levels.
- */
-#define XFS_IN_MAXLEVELS(mp) ((mp)->m_in_maxlevels)
-
-/*
* block numbers in the AG.
*/
#define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1))
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 478e587087f..89b81eedce6 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -69,15 +69,6 @@ xfs_inode_alloc(
ASSERT(!spin_is_locked(&ip->i_flags_lock));
ASSERT(completion_done(&ip->i_flush));
- /*
- * initialise the VFS inode here to get failures
- * out of the way early.
- */
- if (!inode_init_always(mp->m_super, VFS_I(ip))) {
- kmem_zone_free(xfs_inode_zone, ip);
- return NULL;
- }
-
/* initialise the xfs inode */
ip->i_ino = ino;
ip->i_mount = mp;
@@ -113,6 +104,20 @@ xfs_inode_alloc(
#ifdef XFS_DIR2_TRACE
ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
#endif
+ /*
+ * Now initialise the VFS inode. We do this after the xfs_inode
+ * initialisation as internal failures will result in ->destroy_inode
+ * being called and that will pass down through the reclaim path and
+ * free the XFS inode. This path requires the XFS inode to already be
+ * initialised. Hence if this call fails, the xfs_inode has already
+ * been freed and we should not reference it at all in the error
+ * handling.
+ */
+ if (!inode_init_always(mp->m_super, VFS_I(ip)))
+ return NULL;
+
+ /* prevent anyone from using this yet */
+ VFS_I(ip)->i_state = I_NEW|I_LOCK;
return ip;
}
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 1f175fa34b2..f879c1bc4b9 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -122,7 +122,7 @@ typedef struct xfs_ictimestamp {
/*
* NOTE: This structure must be kept identical to struct xfs_dinode
- * in xfs_dinode.h except for the endianess annotations.
+ * in xfs_dinode.h except for the endianness annotations.
*/
typedef struct xfs_icdinode {
__uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h
index 9957d0602d5..a52ac125f05 100644
--- a/fs/xfs/xfs_inode_item.h
+++ b/fs/xfs/xfs_inode_item.h
@@ -40,7 +40,6 @@ typedef struct xfs_inode_log_format {
__int32_t ilf_boffset; /* off of inode in buffer */
} xfs_inode_log_format_t;
-#ifndef HAVE_FORMAT32
typedef struct xfs_inode_log_format_32 {
__uint16_t ilf_type; /* inode log item type */
__uint16_t ilf_size; /* size of this item */
@@ -56,7 +55,6 @@ typedef struct xfs_inode_log_format_32 {
__int32_t ilf_len; /* len of inode buffer */
__int32_t ilf_boffset; /* off of inode in buffer */
} __attribute__((packed)) xfs_inode_log_format_32_t;
-#endif
typedef struct xfs_inode_log_format_64 {
__uint16_t ilf_type; /* inode log item type */
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 08ce72316bf..5aaa2d7ec15 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -338,38 +338,6 @@ xfs_iomap_eof_align_last_fsb(
}
STATIC int
-xfs_flush_space(
- xfs_inode_t *ip,
- int *fsynced,
- int *ioflags)
-{
- switch (*fsynced) {
- case 0:
- if (ip->i_delayed_blks) {
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- xfs_flush_inode(ip);
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- *fsynced = 1;
- } else {
- *ioflags |= BMAPI_SYNC;
- *fsynced = 2;
- }
- return 0;
- case 1:
- *fsynced = 2;
- *ioflags |= BMAPI_SYNC;
- return 0;
- case 2:
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- xfs_flush_device(ip);
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- *fsynced = 3;
- return 0;
- }
- return 1;
-}
-
-STATIC int
xfs_cmn_err_fsblock_zero(
xfs_inode_t *ip,
xfs_bmbt_irec_t *imap)
@@ -538,15 +506,9 @@ error_out:
}
/*
- * If the caller is doing a write at the end of the file,
- * then extend the allocation out to the file system's write
- * iosize. We clean up any extra space left over when the
- * file is closed in xfs_inactive().
- *
- * For sync writes, we are flushing delayed allocate space to
- * try to make additional space available for allocation near
- * the filesystem full boundary - preallocation hurts in that
- * situation, of course.
+ * If the caller is doing a write at the end of the file, then extend the
+ * allocation out to the file system's write iosize. We clean up any extra
+ * space left over when the file is closed in xfs_inactive().
*/
STATIC int
xfs_iomap_eof_want_preallocate(
@@ -565,7 +527,7 @@ xfs_iomap_eof_want_preallocate(
int n, error, imaps;
*prealloc = 0;
- if ((ioflag & BMAPI_SYNC) || (offset + count) <= ip->i_size)
+ if ((offset + count) <= ip->i_size)
return 0;
/*
@@ -611,7 +573,7 @@ xfs_iomap_write_delay(
xfs_extlen_t extsz;
int nimaps;
xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS];
- int prealloc, fsynced = 0;
+ int prealloc, flushed = 0;
int error;
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
@@ -627,12 +589,12 @@ xfs_iomap_write_delay(
extsz = xfs_get_extsz_hint(ip);
offset_fsb = XFS_B_TO_FSBT(mp, offset);
-retry:
error = xfs_iomap_eof_want_preallocate(mp, ip, offset, count,
ioflag, imap, XFS_WRITE_IMAPS, &prealloc);
if (error)
return error;
+retry:
if (prealloc) {
aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1));
ioalign = XFS_B_TO_FSBT(mp, aligned_offset);
@@ -659,15 +621,22 @@ retry:
/*
* If bmapi returned us nothing, and if we didn't get back EDQUOT,
- * then we must have run out of space - flush delalloc, and retry..
+ * then we must have run out of space - flush all other inodes with
+ * delalloc blocks and retry without EOF preallocation.
*/
if (nimaps == 0) {
xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE,
ip, offset, count);
- if (xfs_flush_space(ip, &fsynced, &ioflag))
+ if (flushed)
return XFS_ERROR(ENOSPC);
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ xfs_flush_inodes(ip);
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+
+ flushed = 1;
error = 0;
+ prealloc = 0;
goto retry;
}
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index ee1a0c134cc..fdcf7b82747 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -40,8 +40,7 @@ typedef enum {
BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */
BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */
BMAPI_MMAP = (1 << 6), /* allocate for mmap write */
- BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */
- BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */
+ BMAPI_TRYLOCK = (1 << 7), /* non-blocking request */
} bmapi_flags_t;
@@ -63,7 +62,7 @@ typedef enum {
*/
typedef struct xfs_iomap {
- xfs_daddr_t iomap_bn; /* first 512b blk of mapping */
+ xfs_daddr_t iomap_bn; /* first 512B blk of mapping */
xfs_buftarg_t *iomap_target;
xfs_off_t iomap_offset; /* offset of mapping, bytes */
xfs_off_t iomap_bsize; /* size of mapping, bytes */
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index cf98a805ec9..aeb2d2221c7 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -83,7 +83,12 @@ xfs_bulkstat_one_iget(
buf->bs_uid = dic->di_uid;
buf->bs_gid = dic->di_gid;
buf->bs_size = dic->di_size;
- vn_atime_to_bstime(VFS_I(ip), &buf->bs_atime);
+ /*
+ * We are reading the atime from the Linux inode because the
+ * dinode might not be uptodate.
+ */
+ buf->bs_atime.tv_sec = VFS_I(ip)->i_atime.tv_sec;
+ buf->bs_atime.tv_nsec = VFS_I(ip)->i_atime.tv_nsec;
buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec;
buf->bs_ctime.tv_sec = dic->di_ctime.t_sec;
@@ -579,7 +584,7 @@ xfs_bulkstat(
* first inode of the cluster.
*
* Careful with clustidx. There can be
- * multple clusters per chunk, a single
+ * multiple clusters per chunk, a single
* cluster per chunk or a cluster that has
* inodes represented from several different
* chunks (if blocksize is large).
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index f4726f702a9..3750f04ede0 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -562,9 +562,8 @@ xfs_log_mount(
}
mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
- if (!mp->m_log) {
- cmn_err(CE_WARN, "XFS: Log allocation failed: No memory!");
- error = ENOMEM;
+ if (IS_ERR(mp->m_log)) {
+ error = -PTR_ERR(mp->m_log);
goto out;
}
@@ -574,7 +573,7 @@ xfs_log_mount(
error = xfs_trans_ail_init(mp);
if (error) {
cmn_err(CE_WARN, "XFS: AIL initialisation failed: error %d", error);
- goto error;
+ goto out_free_log;
}
mp->m_log->l_ailp = mp->m_ail;
@@ -594,20 +593,22 @@ xfs_log_mount(
mp->m_flags |= XFS_MOUNT_RDONLY;
if (error) {
cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error);
- goto error;
+ goto out_destroy_ail;
}
}
/* Normal transactions can now occur */
mp->m_log->l_flags &= ~XLOG_ACTIVE_RECOVERY;
- /* End mounting message in xfs_log_mount_finish */
return 0;
-error:
- xfs_log_unmount_dealloc(mp);
+
+out_destroy_ail:
+ xfs_trans_ail_destroy(mp);
+out_free_log:
+ xlog_dealloc_log(mp->m_log);
out:
return error;
-} /* xfs_log_mount */
+}
/*
* Finish the recovery of the file system. This is separate from
@@ -633,19 +634,6 @@ xfs_log_mount_finish(xfs_mount_t *mp)
}
/*
- * Unmount processing for the log.
- */
-int
-xfs_log_unmount(xfs_mount_t *mp)
-{
- int error;
-
- error = xfs_log_unmount_write(mp);
- xfs_log_unmount_dealloc(mp);
- return error;
-}
-
-/*
* Final log writes as part of unmount.
*
* Mark the filesystem clean as unmount happens. Note that during relocation
@@ -795,7 +783,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
* and deallocate the log as the aild references the log.
*/
void
-xfs_log_unmount_dealloc(xfs_mount_t *mp)
+xfs_log_unmount(xfs_mount_t *mp)
{
xfs_trans_ail_destroy(mp);
xlog_dealloc_log(mp->m_log);
@@ -1109,7 +1097,7 @@ xlog_bdstrat_cb(struct xfs_buf *bp)
/*
* Return size of each in-core log record buffer.
*
- * All machines get 8 x 32KB buffers by default, unless tuned otherwise.
+ * All machines get 8 x 32kB buffers by default, unless tuned otherwise.
*
* If the filesystem blocksize is too large, we may need to choose a
* larger size since the directory code currently logs entire blocks.
@@ -1139,8 +1127,8 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
}
if (xfs_sb_version_haslogv2(&mp->m_sb)) {
- /* # headers = size / 32K
- * one header holds cycles from 32K of data
+ /* # headers = size / 32k
+ * one header holds cycles from 32k of data
*/
xhdrs = mp->m_logbsize / XLOG_HEADER_CYCLE_SIZE;
@@ -1156,7 +1144,7 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
goto done;
}
- /* All machines use 32KB buffers by default. */
+ /* All machines use 32kB buffers by default. */
log->l_iclog_size = XLOG_BIG_RECORD_BSIZE;
log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
@@ -1164,32 +1152,8 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
log->l_iclog_hsize = BBSIZE;
log->l_iclog_heads = 1;
- /*
- * For 16KB, we use 3 32KB buffers. For 32KB block sizes, we use
- * 4 32KB buffers. For 64KB block sizes, we use 8 32KB buffers.
- */
- if (mp->m_sb.sb_blocksize >= 16*1024) {
- log->l_iclog_size = XLOG_BIG_RECORD_BSIZE;
- log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
- if (mp->m_logbufs <= 0) {
- switch (mp->m_sb.sb_blocksize) {
- case 16*1024: /* 16 KB */
- log->l_iclog_bufs = 3;
- break;
- case 32*1024: /* 32 KB */
- log->l_iclog_bufs = 4;
- break;
- case 64*1024: /* 64 KB */
- log->l_iclog_bufs = 8;
- break;
- default:
- xlog_panic("XFS: Invalid blocksize");
- break;
- }
- }
- }
-
-done: /* are we being asked to make the sizes selected above visible? */
+done:
+ /* are we being asked to make the sizes selected above visible? */
if (mp->m_logbufs == 0)
mp->m_logbufs = log->l_iclog_bufs;
if (mp->m_logbsize == 0)
@@ -1215,10 +1179,13 @@ xlog_alloc_log(xfs_mount_t *mp,
xfs_buf_t *bp;
int i;
int iclogsize;
+ int error = ENOMEM;
log = kmem_zalloc(sizeof(xlog_t), KM_MAYFAIL);
- if (!log)
- return NULL;
+ if (!log) {
+ xlog_warn("XFS: Log allocation failed: No memory!");
+ goto out;
+ }
log->l_mp = mp;
log->l_targ = log_target;
@@ -1236,19 +1203,35 @@ xlog_alloc_log(xfs_mount_t *mp,
log->l_grant_reserve_cycle = 1;
log->l_grant_write_cycle = 1;
+ error = EFSCORRUPTED;
if (xfs_sb_version_hassector(&mp->m_sb)) {
log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT;
- ASSERT(log->l_sectbb_log <= mp->m_sectbb_log);
+ if (log->l_sectbb_log < 0 ||
+ log->l_sectbb_log > mp->m_sectbb_log) {
+ xlog_warn("XFS: Log sector size (0x%x) out of range.",
+ log->l_sectbb_log);
+ goto out_free_log;
+ }
+
/* for larger sector sizes, must have v2 or external log */
- ASSERT(log->l_sectbb_log == 0 ||
- log->l_logBBstart == 0 ||
- xfs_sb_version_haslogv2(&mp->m_sb));
- ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT);
+ if (log->l_sectbb_log != 0 &&
+ (log->l_logBBstart != 0 &&
+ !xfs_sb_version_haslogv2(&mp->m_sb))) {
+ xlog_warn("XFS: log sector size (0x%x) invalid "
+ "for configuration.", log->l_sectbb_log);
+ goto out_free_log;
+ }
+ if (mp->m_sb.sb_logsectlog < BBSHIFT) {
+ xlog_warn("XFS: Log sector log (0x%x) too small.",
+ mp->m_sb.sb_logsectlog);
+ goto out_free_log;
+ }
}
log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1;
xlog_get_iclog_buffer_size(mp, log);
+ error = ENOMEM;
bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
if (!bp)
goto out_free_log;
@@ -1348,7 +1331,8 @@ out_free_iclog:
xfs_buf_free(log->l_xbuf);
out_free_log:
kmem_free(log);
- return NULL;
+out:
+ return ERR_PTR(-error);
} /* xlog_alloc_log */
@@ -2576,18 +2560,19 @@ redo:
xlog_ins_ticketq(&log->l_reserve_headq, tic);
xlog_trace_loggrant(log, tic,
"xlog_grant_log_space: sleep 2");
+ spin_unlock(&log->l_grant_lock);
+ xlog_grant_push_ail(log->l_mp, need_bytes);
+ spin_lock(&log->l_grant_lock);
+
XFS_STATS_INC(xs_sleep_logspace);
sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s);
- if (XLOG_FORCED_SHUTDOWN(log)) {
- spin_lock(&log->l_grant_lock);
+ spin_lock(&log->l_grant_lock);
+ if (XLOG_FORCED_SHUTDOWN(log))
goto error_return;
- }
xlog_trace_loggrant(log, tic,
"xlog_grant_log_space: wake 2");
- xlog_grant_push_ail(log->l_mp, need_bytes);
- spin_lock(&log->l_grant_lock);
goto redo;
} else if (tic->t_flags & XLOG_TIC_IN_Q)
xlog_del_ticketq(&log->l_reserve_headq, tic);
@@ -2666,7 +2651,7 @@ xlog_regrant_write_log_space(xlog_t *log,
* for more free space, otherwise try to get some space for
* this transaction.
*/
-
+ need_bytes = tic->t_unit_res;
if ((ntic = log->l_write_headq)) {
free_bytes = xlog_space_left(log, log->l_grant_write_cycle,
log->l_grant_write_bytes);
@@ -2686,26 +2671,25 @@ xlog_regrant_write_log_space(xlog_t *log,
xlog_trace_loggrant(log, tic,
"xlog_regrant_write_log_space: sleep 1");
+ spin_unlock(&log->l_grant_lock);
+ xlog_grant_push_ail(log->l_mp, need_bytes);
+ spin_lock(&log->l_grant_lock);
+
XFS_STATS_INC(xs_sleep_logspace);
sv_wait(&tic->t_wait, PINOD|PLTWAIT,
&log->l_grant_lock, s);
/* If we're shutting down, this tic is already
* off the queue */
- if (XLOG_FORCED_SHUTDOWN(log)) {
- spin_lock(&log->l_grant_lock);
+ spin_lock(&log->l_grant_lock);
+ if (XLOG_FORCED_SHUTDOWN(log))
goto error_return;
- }
xlog_trace_loggrant(log, tic,
"xlog_regrant_write_log_space: wake 1");
- xlog_grant_push_ail(log->l_mp, tic->t_unit_res);
- spin_lock(&log->l_grant_lock);
}
}
- need_bytes = tic->t_unit_res;
-
redo:
if (XLOG_FORCED_SHUTDOWN(log))
goto error_return;
@@ -2715,19 +2699,20 @@ redo:
if (free_bytes < need_bytes) {
if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
xlog_ins_ticketq(&log->l_write_headq, tic);
+ spin_unlock(&log->l_grant_lock);
+ xlog_grant_push_ail(log->l_mp, need_bytes);
+ spin_lock(&log->l_grant_lock);
+
XFS_STATS_INC(xs_sleep_logspace);
sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s);
/* If we're shutting down, this tic is already off the queue */
- if (XLOG_FORCED_SHUTDOWN(log)) {
- spin_lock(&log->l_grant_lock);
+ spin_lock(&log->l_grant_lock);
+ if (XLOG_FORCED_SHUTDOWN(log))
goto error_return;
- }
xlog_trace_loggrant(log, tic,
"xlog_regrant_write_log_space: wake 2");
- xlog_grant_push_ail(log->l_mp, need_bytes);
- spin_lock(&log->l_grant_lock);
goto redo;
} else if (tic->t_flags & XLOG_TIC_IN_Q)
xlog_del_ticketq(&log->l_write_headq, tic);
@@ -3214,7 +3199,7 @@ xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog)
*/
/*
- * Free a used ticket when it's refcount falls to zero.
+ * Free a used ticket when its refcount falls to zero.
*/
void
xfs_log_ticket_put(
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index 8a3e84e900a..d0c9baa50b1 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -170,9 +170,8 @@ int xfs_log_write(struct xfs_mount *mp,
int nentries,
xfs_log_ticket_t ticket,
xfs_lsn_t *start_lsn);
-int xfs_log_unmount(struct xfs_mount *mp);
int xfs_log_unmount_write(struct xfs_mount *mp);
-void xfs_log_unmount_dealloc(struct xfs_mount *mp);
+void xfs_log_unmount(struct xfs_mount *mp);
int xfs_log_force_umount(struct xfs_mount *mp, int logerror);
int xfs_log_need_covered(struct xfs_mount *mp);
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index 654167be0ef..bcad5f4c1fd 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -359,7 +359,7 @@ typedef struct xlog_in_core {
int ic_size;
int ic_offset;
int ic_bwritecnt;
- ushort_t ic_state;
+ unsigned short ic_state;
char *ic_datap; /* pointer to iclog data */
#ifdef XFS_LOG_TRACE
struct ktrace *ic_trace;
@@ -455,7 +455,6 @@ extern void xlog_recover_process_iunlinks(xlog_t *log);
extern struct xfs_buf *xlog_get_bp(xlog_t *, int);
extern void xlog_put_bp(struct xfs_buf *);
-extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
extern kmem_zone_t *xfs_log_ticket_zone;
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 61af610d79b..7ba450116d4 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -94,12 +94,30 @@ xlog_put_bp(
xfs_buf_free(bp);
}
+STATIC xfs_caddr_t
+xlog_align(
+ xlog_t *log,
+ xfs_daddr_t blk_no,
+ int nbblks,
+ xfs_buf_t *bp)
+{
+ xfs_caddr_t ptr;
+
+ if (!log->l_sectbb_log)
+ return XFS_BUF_PTR(bp);
+
+ ptr = XFS_BUF_PTR(bp) + BBTOB((int)blk_no & log->l_sectbb_mask);
+ ASSERT(XFS_BUF_SIZE(bp) >=
+ BBTOB(nbblks + (blk_no & log->l_sectbb_mask)));
+ return ptr;
+}
+
/*
* nbblks should be uint, but oh well. Just want to catch that 32-bit length.
*/
-int
-xlog_bread(
+STATIC int
+xlog_bread_noalign(
xlog_t *log,
xfs_daddr_t blk_no,
int nbblks,
@@ -137,6 +155,24 @@ xlog_bread(
return error;
}
+STATIC int
+xlog_bread(
+ xlog_t *log,
+ xfs_daddr_t blk_no,
+ int nbblks,
+ xfs_buf_t *bp,
+ xfs_caddr_t *offset)
+{
+ int error;
+
+ error = xlog_bread_noalign(log, blk_no, nbblks, bp);
+ if (error)
+ return error;
+
+ *offset = xlog_align(log, blk_no, nbblks, bp);
+ return 0;
+}
+
/*
* Write out the buffer at the given block for the given number of blocks.
* The buffer is kept locked across the write and is returned locked.
@@ -180,24 +216,6 @@ xlog_bwrite(
return error;
}
-STATIC xfs_caddr_t
-xlog_align(
- xlog_t *log,
- xfs_daddr_t blk_no,
- int nbblks,
- xfs_buf_t *bp)
-{
- xfs_caddr_t ptr;
-
- if (!log->l_sectbb_log)
- return XFS_BUF_PTR(bp);
-
- ptr = XFS_BUF_PTR(bp) + BBTOB((int)blk_no & log->l_sectbb_mask);
- ASSERT(XFS_BUF_SIZE(bp) >=
- BBTOB(nbblks + (blk_no & log->l_sectbb_mask)));
- return ptr;
-}
-
#ifdef DEBUG
/*
* dump debug superblock and log record information
@@ -211,11 +229,11 @@ xlog_header_check_dump(
cmn_err(CE_DEBUG, "%s: SB : uuid = ", __func__);
for (b = 0; b < 16; b++)
- cmn_err(CE_DEBUG, "%02x", ((uchar_t *)&mp->m_sb.sb_uuid)[b]);
+ cmn_err(CE_DEBUG, "%02x", ((__uint8_t *)&mp->m_sb.sb_uuid)[b]);
cmn_err(CE_DEBUG, ", fmt = %d\n", XLOG_FMT);
cmn_err(CE_DEBUG, " log : uuid = ");
for (b = 0; b < 16; b++)
- cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]);
+ cmn_err(CE_DEBUG, "%02x", ((__uint8_t *)&head->h_fs_uuid)[b]);
cmn_err(CE_DEBUG, ", fmt = %d\n", be32_to_cpu(head->h_fmt));
}
#else
@@ -321,9 +339,9 @@ xlog_find_cycle_start(
mid_blk = BLK_AVG(first_blk, *last_blk);
while (mid_blk != first_blk && mid_blk != *last_blk) {
- if ((error = xlog_bread(log, mid_blk, 1, bp)))
+ error = xlog_bread(log, mid_blk, 1, bp, &offset);
+ if (error)
return error;
- offset = xlog_align(log, mid_blk, 1, bp);
mid_cycle = xlog_get_cycle(offset);
if (mid_cycle == cycle) {
*last_blk = mid_blk;
@@ -379,10 +397,10 @@ xlog_find_verify_cycle(
bcount = min(bufblks, (start_blk + nbblks - i));
- if ((error = xlog_bread(log, i, bcount, bp)))
+ error = xlog_bread(log, i, bcount, bp, &buf);
+ if (error)
goto out;
- buf = xlog_align(log, i, bcount, bp);
for (j = 0; j < bcount; j++) {
cycle = xlog_get_cycle(buf);
if (cycle == stop_on_cycle_no) {
@@ -436,9 +454,9 @@ xlog_find_verify_log_record(
return ENOMEM;
smallmem = 1;
} else {
- if ((error = xlog_bread(log, start_blk, num_blks, bp)))
+ error = xlog_bread(log, start_blk, num_blks, bp, &offset);
+ if (error)
goto out;
- offset = xlog_align(log, start_blk, num_blks, bp);
offset += ((num_blks - 1) << BBSHIFT);
}
@@ -453,9 +471,9 @@ xlog_find_verify_log_record(
}
if (smallmem) {
- if ((error = xlog_bread(log, i, 1, bp)))
+ error = xlog_bread(log, i, 1, bp, &offset);
+ if (error)
goto out;
- offset = xlog_align(log, i, 1, bp);
}
head = (xlog_rec_header_t *)offset;
@@ -559,15 +577,18 @@ xlog_find_head(
bp = xlog_get_bp(log, 1);
if (!bp)
return ENOMEM;
- if ((error = xlog_bread(log, 0, 1, bp)))
+
+ error = xlog_bread(log, 0, 1, bp, &offset);
+ if (error)
goto bp_err;
- offset = xlog_align(log, 0, 1, bp);
+
first_half_cycle = xlog_get_cycle(offset);
last_blk = head_blk = log_bbnum - 1; /* get cycle # of last block */
- if ((error = xlog_bread(log, last_blk, 1, bp)))
+ error = xlog_bread(log, last_blk, 1, bp, &offset);
+ if (error)
goto bp_err;
- offset = xlog_align(log, last_blk, 1, bp);
+
last_half_cycle = xlog_get_cycle(offset);
ASSERT(last_half_cycle != 0);
@@ -817,9 +838,10 @@ xlog_find_tail(
if (!bp)
return ENOMEM;
if (*head_blk == 0) { /* special case */
- if ((error = xlog_bread(log, 0, 1, bp)))
+ error = xlog_bread(log, 0, 1, bp, &offset);
+ if (error)
goto bread_err;
- offset = xlog_align(log, 0, 1, bp);
+
if (xlog_get_cycle(offset) == 0) {
*tail_blk = 0;
/* leave all other log inited values alone */
@@ -832,9 +854,10 @@ xlog_find_tail(
*/
ASSERT(*head_blk < INT_MAX);
for (i = (int)(*head_blk) - 1; i >= 0; i--) {
- if ((error = xlog_bread(log, i, 1, bp)))
+ error = xlog_bread(log, i, 1, bp, &offset);
+ if (error)
goto bread_err;
- offset = xlog_align(log, i, 1, bp);
+
if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) {
found = 1;
break;
@@ -848,9 +871,10 @@ xlog_find_tail(
*/
if (!found) {
for (i = log->l_logBBsize - 1; i >= (int)(*head_blk); i--) {
- if ((error = xlog_bread(log, i, 1, bp)))
+ error = xlog_bread(log, i, 1, bp, &offset);
+ if (error)
goto bread_err;
- offset = xlog_align(log, i, 1, bp);
+
if (XLOG_HEADER_MAGIC_NUM ==
be32_to_cpu(*(__be32 *)offset)) {
found = 2;
@@ -922,10 +946,10 @@ xlog_find_tail(
if (*head_blk == after_umount_blk &&
be32_to_cpu(rhead->h_num_logops) == 1) {
umount_data_blk = (i + hblks) % log->l_logBBsize;
- if ((error = xlog_bread(log, umount_data_blk, 1, bp))) {
+ error = xlog_bread(log, umount_data_blk, 1, bp, &offset);
+ if (error)
goto bread_err;
- }
- offset = xlog_align(log, umount_data_blk, 1, bp);
+
op_head = (xlog_op_header_t *)offset;
if (op_head->oh_flags & XLOG_UNMOUNT_TRANS) {
/*
@@ -1017,9 +1041,10 @@ xlog_find_zeroed(
bp = xlog_get_bp(log, 1);
if (!bp)
return ENOMEM;
- if ((error = xlog_bread(log, 0, 1, bp)))
+ error = xlog_bread(log, 0, 1, bp, &offset);
+ if (error)
goto bp_err;
- offset = xlog_align(log, 0, 1, bp);
+
first_cycle = xlog_get_cycle(offset);
if (first_cycle == 0) { /* completely zeroed log */
*blk_no = 0;
@@ -1028,9 +1053,10 @@ xlog_find_zeroed(
}
/* check partially zeroed log */
- if ((error = xlog_bread(log, log_bbnum-1, 1, bp)))
+ error = xlog_bread(log, log_bbnum-1, 1, bp, &offset);
+ if (error)
goto bp_err;
- offset = xlog_align(log, log_bbnum-1, 1, bp);
+
last_cycle = xlog_get_cycle(offset);
if (last_cycle != 0) { /* log completely written to */
xlog_put_bp(bp);
@@ -1152,10 +1178,10 @@ xlog_write_log_records(
*/
balign = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, start_block);
if (balign != start_block) {
- if ((error = xlog_bread(log, start_block, 1, bp))) {
- xlog_put_bp(bp);
- return error;
- }
+ error = xlog_bread_noalign(log, start_block, 1, bp);
+ if (error)
+ goto out_put_bp;
+
j = start_block - balign;
}
@@ -1175,10 +1201,14 @@ xlog_write_log_records(
balign = BBTOB(ealign - start_block);
error = XFS_BUF_SET_PTR(bp, offset + balign,
BBTOB(sectbb));
- if (!error)
- error = xlog_bread(log, ealign, sectbb, bp);
- if (!error)
- error = XFS_BUF_SET_PTR(bp, offset, bufblks);
+ if (error)
+ break;
+
+ error = xlog_bread_noalign(log, ealign, sectbb, bp);
+ if (error)
+ break;
+
+ error = XFS_BUF_SET_PTR(bp, offset, bufblks);
if (error)
break;
}
@@ -1195,6 +1225,8 @@ xlog_write_log_records(
start_block += endcount;
j = 0;
}
+
+ out_put_bp:
xlog_put_bp(bp);
return error;
}
@@ -2511,16 +2543,10 @@ xlog_recover_do_inode_trans(
}
write_inode_buffer:
- if (ITEM_TYPE(item) == XFS_LI_INODE) {
- ASSERT(bp->b_mount == NULL || bp->b_mount == mp);
- bp->b_mount = mp;
- XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone);
- xfs_bdwrite(mp, bp);
- } else {
- XFS_BUF_STALE(bp);
- error = xfs_bwrite(mp, bp);
- }
-
+ ASSERT(bp->b_mount == NULL || bp->b_mount == mp);
+ bp->b_mount = mp;
+ XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone);
+ xfs_bdwrite(mp, bp);
error:
if (need_free)
kmem_free(in_f);
@@ -2769,51 +2795,48 @@ xlog_recover_do_trans(
int error = 0;
xlog_recover_item_t *item, *first_item;
- if ((error = xlog_recover_reorder_trans(trans)))
+ error = xlog_recover_reorder_trans(trans);
+ if (error)
return error;
+
first_item = item = trans->r_itemq;
do {
- /*
- * we don't need to worry about the block number being
- * truncated in > 1 TB buffers because in user-land,
- * we're now n32 or 64-bit so xfs_daddr_t is 64-bits so
- * the blknos will get through the user-mode buffer
- * cache properly. The only bad case is o32 kernels
- * where xfs_daddr_t is 32-bits but mount will warn us
- * off a > 1 TB filesystem before we get here.
- */
- if ((ITEM_TYPE(item) == XFS_LI_BUF)) {
- if ((error = xlog_recover_do_buffer_trans(log, item,
- pass)))
- break;
- } else if ((ITEM_TYPE(item) == XFS_LI_INODE)) {
- if ((error = xlog_recover_do_inode_trans(log, item,
- pass)))
- break;
- } else if (ITEM_TYPE(item) == XFS_LI_EFI) {
- if ((error = xlog_recover_do_efi_trans(log, item, trans->r_lsn,
- pass)))
- break;
- } else if (ITEM_TYPE(item) == XFS_LI_EFD) {
+ switch (ITEM_TYPE(item)) {
+ case XFS_LI_BUF:
+ error = xlog_recover_do_buffer_trans(log, item, pass);
+ break;
+ case XFS_LI_INODE:
+ error = xlog_recover_do_inode_trans(log, item, pass);
+ break;
+ case XFS_LI_EFI:
+ error = xlog_recover_do_efi_trans(log, item,
+ trans->r_lsn, pass);
+ break;
+ case XFS_LI_EFD:
xlog_recover_do_efd_trans(log, item, pass);
- } else if (ITEM_TYPE(item) == XFS_LI_DQUOT) {
- if ((error = xlog_recover_do_dquot_trans(log, item,
- pass)))
- break;
- } else if ((ITEM_TYPE(item) == XFS_LI_QUOTAOFF)) {
- if ((error = xlog_recover_do_quotaoff_trans(log, item,
- pass)))
- break;
- } else {
- xlog_warn("XFS: xlog_recover_do_trans");
+ error = 0;
+ break;
+ case XFS_LI_DQUOT:
+ error = xlog_recover_do_dquot_trans(log, item, pass);
+ break;
+ case XFS_LI_QUOTAOFF:
+ error = xlog_recover_do_quotaoff_trans(log, item,
+ pass);
+ break;
+ default:
+ xlog_warn(
+ "XFS: invalid item type (%d) xlog_recover_do_trans", ITEM_TYPE(item));
ASSERT(0);
error = XFS_ERROR(EIO);
break;
}
+
+ if (error)
+ return error;
item = item->ri_next;
} while (first_item != item);
- return error;
+ return 0;
}
/*
@@ -3490,9 +3513,11 @@ xlog_do_recovery_pass(
hbp = xlog_get_bp(log, 1);
if (!hbp)
return ENOMEM;
- if ((error = xlog_bread(log, tail_blk, 1, hbp)))
+
+ error = xlog_bread(log, tail_blk, 1, hbp, &offset);
+ if (error)
goto bread_err1;
- offset = xlog_align(log, tail_blk, 1, hbp);
+
rhead = (xlog_rec_header_t *)offset;
error = xlog_valid_rec_header(log, rhead, tail_blk);
if (error)
@@ -3526,9 +3551,10 @@ xlog_do_recovery_pass(
memset(rhash, 0, sizeof(rhash));
if (tail_blk <= head_blk) {
for (blk_no = tail_blk; blk_no < head_blk; ) {
- if ((error = xlog_bread(log, blk_no, hblks, hbp)))
+ error = xlog_bread(log, blk_no, hblks, hbp, &offset);
+ if (error)
goto bread_err2;
- offset = xlog_align(log, blk_no, hblks, hbp);
+
rhead = (xlog_rec_header_t *)offset;
error = xlog_valid_rec_header(log, rhead, blk_no);
if (error)
@@ -3536,10 +3562,11 @@ xlog_do_recovery_pass(
/* blocks in data section */
bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
- error = xlog_bread(log, blk_no + hblks, bblks, dbp);
+ error = xlog_bread(log, blk_no + hblks, bblks, dbp,
+ &offset);
if (error)
goto bread_err2;
- offset = xlog_align(log, blk_no + hblks, bblks, dbp);
+
xlog_unpack_data(rhead, offset, log);
if ((error = xlog_recover_process_data(log,
rhash, rhead, offset, pass)))
@@ -3562,10 +3589,10 @@ xlog_do_recovery_pass(
wrapped_hblks = 0;
if (blk_no + hblks <= log->l_logBBsize) {
/* Read header in one read */
- error = xlog_bread(log, blk_no, hblks, hbp);
+ error = xlog_bread(log, blk_no, hblks, hbp,
+ &offset);
if (error)
goto bread_err2;
- offset = xlog_align(log, blk_no, hblks, hbp);
} else {
/* This LR is split across physical log end */
if (blk_no != log->l_logBBsize) {
@@ -3573,12 +3600,13 @@ xlog_do_recovery_pass(
ASSERT(blk_no <= INT_MAX);
split_hblks = log->l_logBBsize - (int)blk_no;
ASSERT(split_hblks > 0);
- if ((error = xlog_bread(log, blk_no,
- split_hblks, hbp)))
+ error = xlog_bread(log, blk_no,
+ split_hblks, hbp,
+ &offset);
+ if (error)
goto bread_err2;
- offset = xlog_align(log, blk_no,
- split_hblks, hbp);
}
+
/*
* Note: this black magic still works with
* large sector sizes (non-512) only because:
@@ -3596,14 +3624,19 @@ xlog_do_recovery_pass(
error = XFS_BUF_SET_PTR(hbp,
bufaddr + BBTOB(split_hblks),
BBTOB(hblks - split_hblks));
- if (!error)
- error = xlog_bread(log, 0,
- wrapped_hblks, hbp);
- if (!error)
- error = XFS_BUF_SET_PTR(hbp, bufaddr,
+ if (error)
+ goto bread_err2;
+
+ error = xlog_bread_noalign(log, 0,
+ wrapped_hblks, hbp);
+ if (error)
+ goto bread_err2;
+
+ error = XFS_BUF_SET_PTR(hbp, bufaddr,
BBTOB(hblks));
if (error)
goto bread_err2;
+
if (!offset)
offset = xlog_align(log, 0,
wrapped_hblks, hbp);
@@ -3619,10 +3652,10 @@ xlog_do_recovery_pass(
/* Read in data for log record */
if (blk_no + bblks <= log->l_logBBsize) {
- error = xlog_bread(log, blk_no, bblks, dbp);
+ error = xlog_bread(log, blk_no, bblks, dbp,
+ &offset);
if (error)
goto bread_err2;
- offset = xlog_align(log, blk_no, bblks, dbp);
} else {
/* This log record is split across the
* physical end of log */
@@ -3636,12 +3669,13 @@ xlog_do_recovery_pass(
split_bblks =
log->l_logBBsize - (int)blk_no;
ASSERT(split_bblks > 0);
- if ((error = xlog_bread(log, blk_no,
- split_bblks, dbp)))
+ error = xlog_bread(log, blk_no,
+ split_bblks, dbp,
+ &offset);
+ if (error)
goto bread_err2;
- offset = xlog_align(log, blk_no,
- split_bblks, dbp);
}
+
/*
* Note: this black magic still works with
* large sector sizes (non-512) only because:
@@ -3658,15 +3692,19 @@ xlog_do_recovery_pass(
error = XFS_BUF_SET_PTR(dbp,
bufaddr + BBTOB(split_bblks),
BBTOB(bblks - split_bblks));
- if (!error)
- error = xlog_bread(log, wrapped_hblks,
- bblks - split_bblks,
- dbp);
- if (!error)
- error = XFS_BUF_SET_PTR(dbp, bufaddr,
- h_size);
if (error)
goto bread_err2;
+
+ error = xlog_bread_noalign(log, wrapped_hblks,
+ bblks - split_bblks,
+ dbp);
+ if (error)
+ goto bread_err2;
+
+ error = XFS_BUF_SET_PTR(dbp, bufaddr, h_size);
+ if (error)
+ goto bread_err2;
+
if (!offset)
offset = xlog_align(log, wrapped_hblks,
bblks - split_bblks, dbp);
@@ -3683,17 +3721,21 @@ xlog_do_recovery_pass(
/* read first part of physical log */
while (blk_no < head_blk) {
- if ((error = xlog_bread(log, blk_no, hblks, hbp)))
+ error = xlog_bread(log, blk_no, hblks, hbp, &offset);
+ if (error)
goto bread_err2;
- offset = xlog_align(log, blk_no, hblks, hbp);
+
rhead = (xlog_rec_header_t *)offset;
error = xlog_valid_rec_header(log, rhead, blk_no);
if (error)
goto bread_err2;
+
bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
- if ((error = xlog_bread(log, blk_no+hblks, bblks, dbp)))
+ error = xlog_bread(log, blk_no+hblks, bblks, dbp,
+ &offset);
+ if (error)
goto bread_err2;
- offset = xlog_align(log, blk_no+hblks, bblks, dbp);
+
xlog_unpack_data(rhead, offset, log);
if ((error = xlog_recover_process_data(log, rhash,
rhead, offset, pass)))
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 35300250e86..b101990df02 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -45,7 +45,6 @@
#include "xfs_fsops.h"
#include "xfs_utils.h"
-STATIC int xfs_uuid_mount(xfs_mount_t *);
STATIC void xfs_unmountfs_wait(xfs_mount_t *);
@@ -121,6 +120,84 @@ static const struct {
{ sizeof(xfs_sb_t), 0 }
};
+static DEFINE_MUTEX(xfs_uuid_table_mutex);
+static int xfs_uuid_table_size;
+static uuid_t *xfs_uuid_table;
+
+/*
+ * See if the UUID is unique among mounted XFS filesystems.
+ * Mount fails if UUID is nil or a FS with the same UUID is already mounted.
+ */
+STATIC int
+xfs_uuid_mount(
+ struct xfs_mount *mp)
+{
+ uuid_t *uuid = &mp->m_sb.sb_uuid;
+ int hole, i;
+
+ if (mp->m_flags & XFS_MOUNT_NOUUID)
+ return 0;
+
+ if (uuid_is_nil(uuid)) {
+ cmn_err(CE_WARN,
+ "XFS: Filesystem %s has nil UUID - can't mount",
+ mp->m_fsname);
+ return XFS_ERROR(EINVAL);
+ }
+
+ mutex_lock(&xfs_uuid_table_mutex);
+ for (i = 0, hole = -1; i < xfs_uuid_table_size; i++) {
+ if (uuid_is_nil(&xfs_uuid_table[i])) {
+ hole = i;
+ continue;
+ }
+ if (uuid_equal(uuid, &xfs_uuid_table[i]))
+ goto out_duplicate;
+ }
+
+ if (hole < 0) {
+ xfs_uuid_table = kmem_realloc(xfs_uuid_table,
+ (xfs_uuid_table_size + 1) * sizeof(*xfs_uuid_table),
+ xfs_uuid_table_size * sizeof(*xfs_uuid_table),
+ KM_SLEEP);
+ hole = xfs_uuid_table_size++;
+ }
+ xfs_uuid_table[hole] = *uuid;
+ mutex_unlock(&xfs_uuid_table_mutex);
+
+ return 0;
+
+ out_duplicate:
+ mutex_unlock(&xfs_uuid_table_mutex);
+ cmn_err(CE_WARN, "XFS: Filesystem %s has duplicate UUID - can't mount",
+ mp->m_fsname);
+ return XFS_ERROR(EINVAL);
+}
+
+STATIC void
+xfs_uuid_unmount(
+ struct xfs_mount *mp)
+{
+ uuid_t *uuid = &mp->m_sb.sb_uuid;
+ int i;
+
+ if (mp->m_flags & XFS_MOUNT_NOUUID)
+ return;
+
+ mutex_lock(&xfs_uuid_table_mutex);
+ for (i = 0; i < xfs_uuid_table_size; i++) {
+ if (uuid_is_nil(&xfs_uuid_table[i]))
+ continue;
+ if (!uuid_equal(uuid, &xfs_uuid_table[i]))
+ continue;
+ memset(&xfs_uuid_table[i], 0, sizeof(uuid_t));
+ break;
+ }
+ ASSERT(i < xfs_uuid_table_size);
+ mutex_unlock(&xfs_uuid_table_mutex);
+}
+
+
/*
* Free up the resources associated with a mount structure. Assume that
* the structure was initially zeroed, so we can tell which fields got
@@ -256,6 +333,22 @@ xfs_mount_validate_sb(
return XFS_ERROR(ENOSYS);
}
+ /*
+ * Currently only very few inode sizes are supported.
+ */
+ switch (sbp->sb_inodesize) {
+ case 256:
+ case 512:
+ case 1024:
+ case 2048:
+ break;
+ default:
+ xfs_fs_mount_cmn_err(flags,
+ "inode size of %d bytes not supported",
+ sbp->sb_inodesize);
+ return XFS_ERROR(ENOSYS);
+ }
+
if (xfs_sb_validate_fsb_count(sbp, sbp->sb_dblocks) ||
xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) {
xfs_fs_mount_cmn_err(flags,
@@ -574,32 +667,10 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
- mp->m_litino = sbp->sb_inodesize - sizeof(struct xfs_dinode);
mp->m_blockmask = sbp->sb_blocksize - 1;
mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
mp->m_blockwmask = mp->m_blockwsize - 1;
- /*
- * Setup for attributes, in case they get created.
- * This value is for inodes getting attributes for the first time,
- * the per-inode value is for old attribute values.
- */
- ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048);
- switch (sbp->sb_inodesize) {
- case 256:
- mp->m_attroffset = XFS_LITINO(mp) -
- XFS_BMDR_SPACE_CALC(MINABTPTRS);
- break;
- case 512:
- case 1024:
- case 2048:
- mp->m_attroffset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
- break;
- default:
- ASSERT(0);
- }
- ASSERT(mp->m_attroffset < XFS_LITINO(mp));
-
mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1);
mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);
mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2;
@@ -645,7 +716,7 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount)
for (index = 0; index < agcount; index++) {
/*
* read the agf, then the agi. This gets us
- * all the inforamtion we need and populates the
+ * all the information we need and populates the
* per-ag structures for us.
*/
error = xfs_alloc_pagf_init(mp, NULL, index, 0);
@@ -886,8 +957,6 @@ xfs_check_sizes(xfs_mount_t *mp)
}
/*
- * xfs_mountfs
- *
* This function does the following on an initial mount of a file system:
* - reads the superblock from disk and init the mount struct
* - if we're a 32-bit kernel, do a size check on the superblock
@@ -905,7 +974,6 @@ xfs_mountfs(
xfs_inode_t *rip;
__uint64_t resblks;
uint quotamount, quotaflags;
- int uuid_mounted = 0;
int error = 0;
xfs_mount_common(mp, sbp);
@@ -960,7 +1028,7 @@ xfs_mountfs(
*/
error = xfs_update_alignment(mp);
if (error)
- goto error1;
+ goto out;
xfs_alloc_compute_maxlevels(mp);
xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
@@ -971,19 +1039,9 @@ xfs_mountfs(
mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog);
- /*
- * XFS uses the uuid from the superblock as the unique
- * identifier for fsid. We can not use the uuid from the volume
- * since a single partition filesystem is identical to a single
- * partition volume/filesystem.
- */
- if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0) {
- if (xfs_uuid_mount(mp)) {
- error = XFS_ERROR(EINVAL);
- goto error1;
- }
- uuid_mounted=1;
- }
+ error = xfs_uuid_mount(mp);
+ if (error)
+ goto out;
/*
* Set the minimum read and write sizes
@@ -1007,7 +1065,7 @@ xfs_mountfs(
*/
error = xfs_check_sizes(mp);
if (error)
- goto error1;
+ goto out_remove_uuid;
/*
* Initialize realtime fields in the mount structure
@@ -1015,7 +1073,7 @@ xfs_mountfs(
error = xfs_rtmount_init(mp);
if (error) {
cmn_err(CE_WARN, "XFS: RT mount failed");
- goto error1;
+ goto out_remove_uuid;
}
/*
@@ -1045,26 +1103,26 @@ xfs_mountfs(
mp->m_perag = kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t),
KM_MAYFAIL);
if (!mp->m_perag)
- goto error1;
+ goto out_remove_uuid;
mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount);
+ if (!sbp->sb_logblocks) {
+ cmn_err(CE_WARN, "XFS: no log defined");
+ XFS_ERROR_REPORT("xfs_mountfs", XFS_ERRLEVEL_LOW, mp);
+ error = XFS_ERROR(EFSCORRUPTED);
+ goto out_free_perag;
+ }
+
/*
* log's mount-time initialization. Perform 1st part recovery if needed
*/
- if (likely(sbp->sb_logblocks > 0)) { /* check for volume case */
- error = xfs_log_mount(mp, mp->m_logdev_targp,
- XFS_FSB_TO_DADDR(mp, sbp->sb_logstart),
- XFS_FSB_TO_BB(mp, sbp->sb_logblocks));
- if (error) {
- cmn_err(CE_WARN, "XFS: log mount failed");
- goto error2;
- }
- } else { /* No log has been defined */
- cmn_err(CE_WARN, "XFS: no log defined");
- XFS_ERROR_REPORT("xfs_mountfs_int(1)", XFS_ERRLEVEL_LOW, mp);
- error = XFS_ERROR(EFSCORRUPTED);
- goto error2;
+ error = xfs_log_mount(mp, mp->m_logdev_targp,
+ XFS_FSB_TO_DADDR(mp, sbp->sb_logstart),
+ XFS_FSB_TO_BB(mp, sbp->sb_logblocks));
+ if (error) {
+ cmn_err(CE_WARN, "XFS: log mount failed");
+ goto out_free_perag;
}
/*
@@ -1086,15 +1144,14 @@ xfs_mountfs(
* If we are currently making the filesystem, the initialisation will
* fail as the perag data is in an undefined state.
*/
-
if (xfs_sb_version_haslazysbcount(&mp->m_sb) &&
!XFS_LAST_UNMOUNT_WAS_CLEAN(mp) &&
!mp->m_sb.sb_inprogress) {
error = xfs_initialize_perag_data(mp, sbp->sb_agcount);
- if (error) {
- goto error2;
- }
+ if (error)
+ goto out_free_perag;
}
+
/*
* Get and sanity-check the root inode.
* Save the pointer to it in the mount structure.
@@ -1102,7 +1159,7 @@ xfs_mountfs(
error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0);
if (error) {
cmn_err(CE_WARN, "XFS: failed to read root inode");
- goto error3;
+ goto out_log_dealloc;
}
ASSERT(rip != NULL);
@@ -1116,7 +1173,7 @@ xfs_mountfs(
XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
mp);
error = XFS_ERROR(EFSCORRUPTED);
- goto error4;
+ goto out_rele_rip;
}
mp->m_rootip = rip; /* save it */
@@ -1131,7 +1188,7 @@ xfs_mountfs(
* Free up the root inode.
*/
cmn_err(CE_WARN, "XFS: failed to read RT inodes");
- goto error4;
+ goto out_rele_rip;
}
/*
@@ -1143,7 +1200,7 @@ xfs_mountfs(
error = xfs_mount_log_sb(mp, mp->m_update_flags);
if (error) {
cmn_err(CE_WARN, "XFS: failed to write sb changes");
- goto error4;
+ goto out_rtunmount;
}
}
@@ -1152,7 +1209,7 @@ xfs_mountfs(
*/
error = XFS_QM_INIT(mp, &quotamount, &quotaflags);
if (error)
- goto error4;
+ goto out_rtunmount;
/*
* Finish recovering the file system. This part needed to be
@@ -1162,7 +1219,7 @@ xfs_mountfs(
error = xfs_log_mount_finish(mp);
if (error) {
cmn_err(CE_WARN, "XFS: log mount finish failed");
- goto error4;
+ goto out_rtunmount;
}
/*
@@ -1170,7 +1227,7 @@ xfs_mountfs(
*/
error = XFS_QM_MOUNT(mp, quotamount, quotaflags);
if (error)
- goto error4;
+ goto out_rtunmount;
/*
* Now we are mounted, reserve a small amount of unused space for
@@ -1194,18 +1251,17 @@ xfs_mountfs(
return 0;
- error4:
- /*
- * Free up the root inode.
- */
+ out_rtunmount:
+ xfs_rtunmount_inodes(mp);
+ out_rele_rip:
IRELE(rip);
- error3:
- xfs_log_unmount_dealloc(mp);
- error2:
+ out_log_dealloc:
+ xfs_log_unmount(mp);
+ out_free_perag:
xfs_free_perag(mp);
- error1:
- if (uuid_mounted)
- uuid_table_remove(&mp->m_sb.sb_uuid);
+ out_remove_uuid:
+ xfs_uuid_unmount(mp);
+ out:
return error;
}
@@ -1226,15 +1282,12 @@ xfs_unmountfs(
*/
XFS_QM_UNMOUNT(mp);
- if (mp->m_rbmip)
- IRELE(mp->m_rbmip);
- if (mp->m_rsumip)
- IRELE(mp->m_rsumip);
+ xfs_rtunmount_inodes(mp);
IRELE(mp->m_rootip);
/*
* We can potentially deadlock here if we have an inode cluster
- * that has been freed has it's buffer still pinned in memory because
+ * that has been freed has its buffer still pinned in memory because
* the transaction is still sitting in a iclog. The stale inodes
* on that buffer will have their flush locks held until the
* transaction hits the disk and the callbacks run. the inode
@@ -1266,7 +1319,7 @@ xfs_unmountfs(
* Unreserve any blocks we have so that when we unmount we don't account
* the reserved free space as used. This is really only necessary for
* lazy superblock counting because it trusts the incore superblock
- * counters to be aboslutely correct on clean unmount.
+ * counters to be absolutely correct on clean unmount.
*
* We don't bother correcting this elsewhere for lazy superblock
* counting because on mount of an unclean filesystem we reconstruct the
@@ -1288,10 +1341,9 @@ xfs_unmountfs(
"Freespace may not be correct on next mount.");
xfs_unmountfs_writesb(mp);
xfs_unmountfs_wait(mp); /* wait for async bufs */
- xfs_log_unmount(mp); /* Done! No more fs ops. */
-
- if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0)
- uuid_table_remove(&mp->m_sb.sb_uuid);
+ xfs_log_unmount_write(mp);
+ xfs_log_unmount(mp);
+ xfs_uuid_unmount(mp);
#if defined(DEBUG)
xfs_errortag_clearall(mp, 0);
@@ -1793,29 +1845,6 @@ xfs_freesb(
}
/*
- * See if the UUID is unique among mounted XFS filesystems.
- * Mount fails if UUID is nil or a FS with the same UUID is already mounted.
- */
-STATIC int
-xfs_uuid_mount(
- xfs_mount_t *mp)
-{
- if (uuid_is_nil(&mp->m_sb.sb_uuid)) {
- cmn_err(CE_WARN,
- "XFS: Filesystem %s has nil UUID - can't mount",
- mp->m_fsname);
- return -1;
- }
- if (!uuid_table_insert(&mp->m_sb.sb_uuid)) {
- cmn_err(CE_WARN,
- "XFS: Filesystem %s has duplicate UUID - can't mount",
- mp->m_fsname);
- return -1;
- }
- return 0;
-}
-
-/*
* Used to log changes to the superblock unit and width fields which could
* be altered by the mount options, as well as any potential sb_features2
* fixup. Only the first superblock is updated.
@@ -1868,7 +1897,7 @@ xfs_mount_log_sb(
* we disable the per-cpu counter and go through the slow path.
*
* The slow path is the current xfs_mod_incore_sb() function. This means that
- * when we disable a per-cpu counter, we need to drain it's resources back to
+ * when we disable a per-cpu counter, we need to drain its resources back to
* the global superblock. We do this after disabling the counter to prevent
* more threads from queueing up on the counter.
*
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index f5e9937f9bd..d6a64392f98 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -136,7 +136,6 @@ typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *,
struct xfs_dquot *, struct xfs_dquot *, uint);
typedef void (*xfs_dqstatvfs_t)(struct xfs_inode *, struct kstatfs *);
typedef int (*xfs_dqsync_t)(struct xfs_mount *, int flags);
-typedef int (*xfs_quotactl_t)(struct xfs_mount *, int, int, xfs_caddr_t);
typedef struct xfs_qmops {
xfs_qminit_t xfs_qminit;
@@ -154,7 +153,6 @@ typedef struct xfs_qmops {
xfs_dqvopchownresv_t xfs_dqvopchownresv;
xfs_dqstatvfs_t xfs_dqstatvfs;
xfs_dqsync_t xfs_dqsync;
- xfs_quotactl_t xfs_quotactl;
struct xfs_dqtrxops *xfs_dqtrxops;
} xfs_qmops_t;
@@ -188,8 +186,6 @@ typedef struct xfs_qmops {
(*(ip)->i_mount->m_qm_ops->xfs_dqstatvfs)(ip, statp)
#define XFS_QM_DQSYNC(mp, flags) \
(*(mp)->m_qm_ops->xfs_dqsync)(mp, flags)
-#define XFS_QM_QUOTACTL(mp, cmd, id, addr) \
- (*(mp)->m_qm_ops->xfs_quotactl)(mp, cmd, id, addr)
#ifdef HAVE_PERCPU_SB
@@ -273,19 +269,17 @@ typedef struct xfs_mount {
uint m_inobt_mnr[2]; /* min inobt btree records */
uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */
uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */
- uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */
+ uint m_in_maxlevels; /* max inobt btree levels. */
struct xfs_perag *m_perag; /* per-ag accounting info */
struct rw_semaphore m_peraglock; /* lock for m_perag (pointer) */
struct mutex m_growlock; /* growfs mutex */
int m_fixedfsid[2]; /* unchanged for life of FS */
uint m_dmevmask; /* DMI events for this FS */
__uint64_t m_flags; /* global mount flags */
- uint m_attroffset; /* inode attribute offset */
uint m_dir_node_ents; /* #entries in a dir danode */
uint m_attr_node_ents; /* #entries in attr danode */
int m_ialloc_inos; /* inodes in inode allocation */
int m_ialloc_blks; /* blocks in inode allocation */
- int m_litino; /* size of inode union area */
int m_inoalign_mask;/* mask sb_inoalignmt if used */
uint m_qflags; /* quota status flags */
xfs_trans_reservations_t m_reservations;/* precomputed res values */
@@ -293,9 +287,6 @@ typedef struct xfs_mount {
__uint64_t m_maxioffset; /* maximum inode offset */
__uint64_t m_resblks; /* total reserved blocks */
__uint64_t m_resblks_avail;/* available reserved blocks */
-#if XFS_BIG_INUMS
- xfs_ino_t m_inoadd; /* add value for ino64_offset */
-#endif
int m_dalign; /* stripe unit */
int m_swidth; /* stripe width */
int m_sinoalign; /* stripe unit inode alignment */
@@ -322,7 +313,7 @@ typedef struct xfs_mount {
#endif
struct xfs_mru_cache *m_filestream; /* per-mount filestream data */
struct task_struct *m_sync_task; /* generalised sync thread */
- bhv_vfs_sync_work_t m_sync_work; /* work item for VFS_SYNC */
+ xfs_sync_work_t m_sync_work; /* work item for VFS_SYNC */
struct list_head m_sync_list; /* sync thread work item list */
spinlock_t m_sync_lock; /* work item list lock */
int m_sync_seq; /* sync thread generation no. */
@@ -337,7 +328,6 @@ typedef struct xfs_mount {
#define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops
must be synchronous except
for space allocations */
-#define XFS_MOUNT_INO64 (1ULL << 1)
#define XFS_MOUNT_DMAPI (1ULL << 2) /* dmapi is enabled */
#define XFS_MOUNT_WAS_CLEAN (1ULL << 3)
#define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem
@@ -389,8 +379,8 @@ typedef struct xfs_mount {
* Synchronous read and write sizes. This should be
* better for NFSv2 wsync filesystems.
*/
-#define XFS_WSYNC_READIO_LOG 15 /* 32K */
-#define XFS_WSYNC_WRITEIO_LOG 14 /* 16K */
+#define XFS_WSYNC_READIO_LOG 15 /* 32k */
+#define XFS_WSYNC_WRITEIO_LOG 14 /* 16k */
/*
* Allow large block sizes to be reported to userspace programs if the
@@ -500,9 +490,6 @@ typedef struct xfs_mod_sb {
int64_t msb_delta; /* Change to make to specified field */
} xfs_mod_sb_t;
-#define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock))
-#define XFS_MOUNT_IUNLOCK(mp) mutex_unlock(&((mp)->m_ilock))
-
extern int xfs_log_sbcount(xfs_mount_t *, uint);
extern int xfs_mountfs(xfs_mount_t *mp);
extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index 27f80581520..e101790ea8e 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -126,7 +126,6 @@ static struct xfs_qmops xfs_qmcore_stub = {
.xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr,
.xfs_dqstatvfs = (xfs_dqstatvfs_t) fs_noval,
.xfs_dqsync = (xfs_dqsync_t) fs_noerr,
- .xfs_quotactl = (xfs_quotactl_t) fs_nosys,
};
int
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 48965ecaa15..f5d1202dde2 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -18,6 +18,8 @@
#ifndef __XFS_QUOTA_H__
#define __XFS_QUOTA_H__
+struct xfs_trans;
+
/*
* The ondisk form of a dquot structure.
*/
@@ -185,7 +187,6 @@ typedef struct xfs_qoff_logformat {
* to a single function. None of these XFS_QMOPT_* flags are meant to have
* persistent values (ie. their values can and will change between versions)
*/
-#define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */
#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */
#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */
#define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index c5bb86f3ec0..385f6dceba5 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -2288,6 +2288,16 @@ xfs_rtmount_inodes(
return 0;
}
+void
+xfs_rtunmount_inodes(
+ struct xfs_mount *mp)
+{
+ if (mp->m_rbmip)
+ IRELE(mp->m_rbmip);
+ if (mp->m_rsumip)
+ IRELE(mp->m_rsumip);
+}
+
/*
* Pick an extent for allocation at the start of a new realtime file.
* Use the sequence number stored in the atime field of the bitmap inode.
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h
index 8d8dcd21571..b2d67adb6a0 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -23,8 +23,8 @@ struct xfs_trans;
/* Min and max rt extent sizes, specified in bytes */
#define XFS_MAX_RTEXTSIZE (1024 * 1024 * 1024) /* 1GB */
-#define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64KB */
-#define XFS_MIN_RTEXTSIZE (4 * 1024) /* 4KB */
+#define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64kB */
+#define XFS_MIN_RTEXTSIZE (4 * 1024) /* 4kB */
/*
* Constants for bit manipulations.
@@ -108,6 +108,9 @@ xfs_rtfree_extent(
int /* error */
xfs_rtmount_init(
struct xfs_mount *mp); /* file system mount structure */
+void
+xfs_rtunmount_inodes(
+ struct xfs_mount *mp);
/*
* Get the bitmap and summary inodes into the mount structure
@@ -146,6 +149,7 @@ xfs_growfs_rt(
# define xfs_growfs_rt(mp,in) (ENOSYS)
# define xfs_rtmount_init(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
+# define xfs_rtunmount_inodes(m)
#endif /* CONFIG_XFS_RT */
#endif /* __KERNEL__ */
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index d6fe4a88d79..775249a54f6 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -292,7 +292,7 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
* In a write transaction we can allocate a maximum of 2
* extents. This gives:
* the inode getting the new extents: inode size
- * the inode\'s bmap btree: max depth * block size
+ * the inode's bmap btree: max depth * block size
* the agfs of the ags from which the extents are allocated: 2 * sector
* the superblock free block counter: sector size
* the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
@@ -321,7 +321,7 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
/*
* In truncating a file we free up to two extents at once. We can modify:
* the inode being truncated: inode size
- * the inode\'s bmap btree: (max depth + 1) * block size
+ * the inode's bmap btree: (max depth + 1) * block size
* And the bmap_finish transaction can free the blocks and bmap blocks:
* the agf for each of the ags: 4 * sector size
* the agfl for each of the ags: 4 * sector size
@@ -343,7 +343,7 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
(128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))) + \
(128 * 5) + \
XFS_ALLOCFREE_LOG_RES(mp, 1) + \
- (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
+ (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate)
@@ -431,8 +431,8 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
* the new inode: inode size
* the inode btree entry: 1 block
* the directory btree: (max depth + v2) * dir block size
- * the directory inode\'s bmap btree: (max depth + v2) * block size
- * the blocks for the symlink: 1 KB
+ * the directory inode's bmap btree: (max depth + v2) * block size
+ * the blocks for the symlink: 1 kB
* Or in the first xact we allocate some inodes giving:
* the agi and agf of the ag getting the new inodes: 2 * sectorsize
* the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
@@ -449,9 +449,9 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
(128 * (4 + XFS_DIROP_LOG_COUNT(mp)))), \
(2 * (mp)->m_sb.sb_sectsize + \
XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \
- XFS_FSB_TO_B((mp), XFS_IN_MAXLEVELS(mp)) + \
+ XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \
XFS_ALLOCFREE_LOG_RES(mp, 1) + \
- (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
+ (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
#define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink)
@@ -463,7 +463,7 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
* the inode btree entry: block size
* the superblock for the nlink flag: sector size
* the directory btree: (max depth + v2) * dir block size
- * the directory inode\'s bmap btree: (max depth + v2) * block size
+ * the directory inode's bmap btree: (max depth + v2) * block size
* Or in the first xact we allocate some inodes giving:
* the agi and agf of the ag getting the new inodes: 2 * sectorsize
* the superblock for the nlink flag: sector size
@@ -481,9 +481,9 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
(128 * (3 + XFS_DIROP_LOG_COUNT(mp)))), \
(3 * (mp)->m_sb.sb_sectsize + \
XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \
- XFS_FSB_TO_B((mp), XFS_IN_MAXLEVELS(mp)) + \
+ XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \
XFS_ALLOCFREE_LOG_RES(mp, 1) + \
- (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
+ (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
#define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create)
@@ -513,7 +513,7 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \
(128 * 5) + \
XFS_ALLOCFREE_LOG_RES(mp, 1) + \
- (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
+ (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
@@ -637,7 +637,7 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
/*
* Removing the attribute fork of a file
* the inode being truncated: inode size
- * the inode\'s bmap btree: max depth * block size
+ * the inode's bmap btree: max depth * block size
* And the bmap_finish transaction can free the blocks and bmap blocks:
* the agf for each of the ags: 4 * sector size
* the agfl for each of the ags: 4 * sector size
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 2d47f10f8be..f31271c30de 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -79,7 +79,7 @@ xfs_trans_ail_tail(
* the push is run asynchronously in a separate thread, so we return the tail
* of the log right now instead of the tail after the push. This means we will
* either continue right away, or we will sleep waiting on the async thread to
- * do it's work.
+ * do its work.
*
* We do this unlocked - we only need to know whether there is anything in the
* AIL at the time we are called. We don't need to access the contents of
@@ -160,7 +160,7 @@ xfs_trans_ail_cursor_next(
/*
* Now that the traversal is complete, we need to remove the cursor
* from the list of traversing cursors. Avoid removing the embedded
- * push cursor, but use the fact it is alway present to make the
+ * push cursor, but use the fact it is always present to make the
* list deletion simple.
*/
void
diff --git a/fs/xfs/xfs_trans_item.c b/fs/xfs/xfs_trans_item.c
index e110bf57d7f..eb3fc57f9ee 100644
--- a/fs/xfs/xfs_trans_item.c
+++ b/fs/xfs/xfs_trans_item.c
@@ -22,7 +22,7 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_trans_priv.h"
-/* XXX: from here down needed until struct xfs_trans has it's own ailp */
+/* XXX: from here down needed until struct xfs_trans has its own ailp */
#include "xfs_bit.h"
#include "xfs_buf_item.h"
#include "xfs_sb.h"
diff --git a/fs/xfs/xfs_trans_space.h b/fs/xfs/xfs_trans_space.h
index 4ea2e5074bd..7d2c920dfb9 100644
--- a/fs/xfs/xfs_trans_space.h
+++ b/fs/xfs/xfs_trans_space.h
@@ -47,7 +47,7 @@
#define XFS_DIRREMOVE_SPACE_RES(mp) \
XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK)
#define XFS_IALLOC_SPACE_RES(mp) \
- (XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp)-1)
+ (XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels - 1)
/*
* Space reservation values for various transactions.
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index b2f724502f1..d725428c9df 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -21,14 +21,6 @@
#ifdef __KERNEL__
/*
- * POSIX Extensions
- */
-typedef unsigned char uchar_t;
-typedef unsigned short ushort_t;
-typedef unsigned int uint_t;
-typedef unsigned long ulong_t;
-
-/*
* Additional type declarations for XFS
*/
typedef signed char __int8_t;
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index fcc2285d03e..79b9e5ea535 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -374,7 +374,7 @@ xfs_truncate_file(
/*
* Follow the normal truncate locking protocol. Since we
- * hold the inode in the transaction, we know that it's number
+ * hold the inode in the transaction, we know that its number
* of references will stay constant.
*/
xfs_ilock(ip, XFS_ILOCK_EXCL);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 0e55c5d7db5..19cf90a9c76 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1136,7 +1136,7 @@ xfs_inactive(
* If the inode is already free, then there can be nothing
* to clean up here.
*/
- if (ip->i_d.di_mode == 0 || VN_BAD(VFS_I(ip))) {
+ if (ip->i_d.di_mode == 0 || is_bad_inode(VFS_I(ip))) {
ASSERT(ip->i_df.if_real_bytes == 0);
ASSERT(ip->i_df.if_broot_bytes == 0);
return VN_INACTIVE_CACHE;
@@ -1387,23 +1387,28 @@ xfs_create(
xfs_inode_t **ipp,
cred_t *credp)
{
- xfs_mount_t *mp = dp->i_mount;
- xfs_inode_t *ip;
- xfs_trans_t *tp;
+ int is_dir = S_ISDIR(mode);
+ struct xfs_mount *mp = dp->i_mount;
+ struct xfs_inode *ip = NULL;
+ struct xfs_trans *tp = NULL;
int error;
xfs_bmap_free_t free_list;
xfs_fsblock_t first_block;
boolean_t unlock_dp_on_error = B_FALSE;
- int dm_event_sent = 0;
uint cancel_flags;
int committed;
xfs_prid_t prid;
- struct xfs_dquot *udqp, *gdqp;
+ struct xfs_dquot *udqp = NULL;
+ struct xfs_dquot *gdqp = NULL;
uint resblks;
+ uint log_res;
+ uint log_count;
- ASSERT(!*ipp);
xfs_itrace_entry(dp);
+ if (XFS_FORCED_SHUTDOWN(mp))
+ return XFS_ERROR(EIO);
+
if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
dp, DM_RIGHT_NULL, NULL,
@@ -1412,84 +1417,104 @@ xfs_create(
if (error)
return error;
- dm_event_sent = 1;
}
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- /* Return through std_return after this point. */
-
- udqp = gdqp = NULL;
if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
prid = dp->i_d.di_projid;
else
- prid = (xfs_prid_t)dfltprid;
+ prid = dfltprid;
/*
* Make sure that we have allocated dquot(s) on disk.
*/
error = XFS_QM_DQVOPALLOC(mp, dp,
current_fsuid(), current_fsgid(), prid,
- XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp);
+ XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
if (error)
goto std_return;
- ip = NULL;
+ if (is_dir) {
+ rdev = 0;
+ resblks = XFS_MKDIR_SPACE_RES(mp, name->len);
+ log_res = XFS_MKDIR_LOG_RES(mp);
+ log_count = XFS_MKDIR_LOG_COUNT;
+ tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR);
+ } else {
+ resblks = XFS_CREATE_SPACE_RES(mp, name->len);
+ log_res = XFS_CREATE_LOG_RES(mp);
+ log_count = XFS_CREATE_LOG_COUNT;
+ tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
+ }
- tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
- resblks = XFS_CREATE_SPACE_RES(mp, name->len);
+
/*
* Initially assume that the file does not exist and
* reserve the resources for that case. If that is not
* the case we'll drop the one we have and get a more
* appropriate transaction later.
*/
- error = xfs_trans_reserve(tp, resblks, XFS_CREATE_LOG_RES(mp), 0,
+ error = xfs_trans_reserve(tp, resblks, log_res, 0,
+ XFS_TRANS_PERM_LOG_RES, log_count);
+ if (error == ENOSPC) {
+ /* flush outstanding delalloc blocks and retry */
+ xfs_flush_inodes(dp);
+ error = xfs_trans_reserve(tp, resblks, XFS_CREATE_LOG_RES(mp), 0,
XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT);
+ }
if (error == ENOSPC) {
+ /* No space at all so try a "no-allocation" reservation */
resblks = 0;
- error = xfs_trans_reserve(tp, 0, XFS_CREATE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT);
+ error = xfs_trans_reserve(tp, 0, log_res, 0,
+ XFS_TRANS_PERM_LOG_RES, log_count);
}
if (error) {
cancel_flags = 0;
- goto error_return;
+ goto out_trans_cancel;
}
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
unlock_dp_on_error = B_TRUE;
- xfs_bmap_init(&free_list, &first_block);
+ /*
+ * Check for directory link count overflow.
+ */
+ if (is_dir && dp->i_d.di_nlink >= XFS_MAXLINK) {
+ error = XFS_ERROR(EMLINK);
+ goto out_trans_cancel;
+ }
- ASSERT(ip == NULL);
+ xfs_bmap_init(&free_list, &first_block);
/*
* Reserve disk quota and the inode.
*/
error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0);
if (error)
- goto error_return;
+ goto out_trans_cancel;
error = xfs_dir_canenter(tp, dp, name, resblks);
if (error)
- goto error_return;
- error = xfs_dir_ialloc(&tp, dp, mode, 1,
- rdev, credp, prid, resblks > 0,
- &ip, &committed);
+ goto out_trans_cancel;
+
+ /*
+ * A newly created regular or special file just has one directory
+ * entry pointing to them, but a directory also the "." entry
+ * pointing to itself.
+ */
+ error = xfs_dir_ialloc(&tp, dp, mode, is_dir ? 2 : 1, rdev, credp,
+ prid, resblks > 0, &ip, &committed);
if (error) {
if (error == ENOSPC)
- goto error_return;
- goto abort_return;
+ goto out_trans_cancel;
+ goto out_trans_abort;
}
- xfs_itrace_ref(ip);
/*
* At this point, we've gotten a newly allocated inode.
* It is locked (and joined to the transaction).
*/
-
+ xfs_itrace_ref(ip);
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
/*
@@ -1508,19 +1533,28 @@ xfs_create(
resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
if (error) {
ASSERT(error != ENOSPC);
- goto abort_return;
+ goto out_trans_abort;
}
xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
+ if (is_dir) {
+ error = xfs_dir_init(tp, ip, dp);
+ if (error)
+ goto out_bmap_cancel;
+
+ error = xfs_bumplink(tp, dp);
+ if (error)
+ goto out_bmap_cancel;
+ }
+
/*
* If this is a synchronous mount, make sure that the
* create transaction goes to disk before returning to
* the user.
*/
- if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
+ if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
xfs_trans_set_sync(tp);
- }
/*
* Attach the dquot(s) to the inodes and modify them incore.
@@ -1537,16 +1571,13 @@ xfs_create(
IHOLD(ip);
error = xfs_bmap_finish(&tp, &free_list, &committed);
- if (error) {
- xfs_bmap_cancel(&free_list);
- goto abort_rele;
- }
+ if (error)
+ goto out_abort_rele;
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
if (error) {
IRELE(ip);
- tp = NULL;
- goto error_return;
+ goto out_dqrele;
}
XFS_QM_DQRELE(mp, udqp);
@@ -1555,26 +1586,22 @@ xfs_create(
*ipp = ip;
/* Fallthrough to std_return with error = 0 */
-
-std_return:
- if ((*ipp || (error != 0 && dm_event_sent != 0)) &&
- DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
- (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
- dp, DM_RIGHT_NULL,
- *ipp ? ip : NULL,
- DM_RIGHT_NULL, name->name, NULL,
- mode, error, 0);
+ std_return:
+ if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
+ XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, dp, DM_RIGHT_NULL,
+ ip, DM_RIGHT_NULL, name->name, NULL, mode,
+ error, 0);
}
+
return error;
- abort_return:
+ out_bmap_cancel:
+ xfs_bmap_cancel(&free_list);
+ out_trans_abort:
cancel_flags |= XFS_TRANS_ABORT;
- /* FALLTHROUGH */
-
- error_return:
- if (tp != NULL)
- xfs_trans_cancel(tp, cancel_flags);
-
+ out_trans_cancel:
+ xfs_trans_cancel(tp, cancel_flags);
+ out_dqrele:
XFS_QM_DQRELE(mp, udqp);
XFS_QM_DQRELE(mp, gdqp);
@@ -1583,20 +1610,18 @@ std_return:
goto std_return;
- abort_rele:
+ out_abort_rele:
/*
* Wait until after the current transaction is aborted to
* release the inode. This prevents recursive transactions
* and deadlocks from xfs_inactive.
*/
+ xfs_bmap_cancel(&free_list);
cancel_flags |= XFS_TRANS_ABORT;
xfs_trans_cancel(tp, cancel_flags);
IRELE(ip);
-
- XFS_QM_DQRELE(mp, udqp);
- XFS_QM_DQRELE(mp, gdqp);
-
- goto std_return;
+ unlock_dp_on_error = B_FALSE;
+ goto out_dqrele;
}
#ifdef DEBUG
@@ -2004,8 +2029,10 @@ xfs_link(
/* Return through std_return after this point. */
error = XFS_QM_DQATTACH(mp, sip, 0);
- if (!error && sip != tdp)
- error = XFS_QM_DQATTACH(mp, tdp, 0);
+ if (error)
+ goto std_return;
+
+ error = XFS_QM_DQATTACH(mp, tdp, 0);
if (error)
goto std_return;
@@ -2110,209 +2137,6 @@ std_return:
goto std_return;
}
-
-int
-xfs_mkdir(
- xfs_inode_t *dp,
- struct xfs_name *dir_name,
- mode_t mode,
- xfs_inode_t **ipp,
- cred_t *credp)
-{
- xfs_mount_t *mp = dp->i_mount;
- xfs_inode_t *cdp; /* inode of created dir */
- xfs_trans_t *tp;
- int cancel_flags;
- int error;
- int committed;
- xfs_bmap_free_t free_list;
- xfs_fsblock_t first_block;
- boolean_t unlock_dp_on_error = B_FALSE;
- boolean_t created = B_FALSE;
- int dm_event_sent = 0;
- xfs_prid_t prid;
- struct xfs_dquot *udqp, *gdqp;
- uint resblks;
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- tp = NULL;
-
- if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
- dp, DM_RIGHT_NULL, NULL,
- DM_RIGHT_NULL, dir_name->name, NULL,
- mode, 0, 0);
- if (error)
- return error;
- dm_event_sent = 1;
- }
-
- /* Return through std_return after this point. */
-
- xfs_itrace_entry(dp);
-
- mp = dp->i_mount;
- udqp = gdqp = NULL;
- if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
- prid = dp->i_d.di_projid;
- else
- prid = (xfs_prid_t)dfltprid;
-
- /*
- * Make sure that we have allocated dquot(s) on disk.
- */
- error = XFS_QM_DQVOPALLOC(mp, dp,
- current_fsuid(), current_fsgid(), prid,
- XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
- if (error)
- goto std_return;
-
- tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR);
- cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
- resblks = XFS_MKDIR_SPACE_RES(mp, dir_name->len);
- error = xfs_trans_reserve(tp, resblks, XFS_MKDIR_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT);
- if (error == ENOSPC) {
- resblks = 0;
- error = xfs_trans_reserve(tp, 0, XFS_MKDIR_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_MKDIR_LOG_COUNT);
- }
- if (error) {
- cancel_flags = 0;
- goto error_return;
- }
-
- xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
- unlock_dp_on_error = B_TRUE;
-
- /*
- * Check for directory link count overflow.
- */
- if (dp->i_d.di_nlink >= XFS_MAXLINK) {
- error = XFS_ERROR(EMLINK);
- goto error_return;
- }
-
- /*
- * Reserve disk quota and the inode.
- */
- error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0);
- if (error)
- goto error_return;
-
- error = xfs_dir_canenter(tp, dp, dir_name, resblks);
- if (error)
- goto error_return;
- /*
- * create the directory inode.
- */
- error = xfs_dir_ialloc(&tp, dp, mode, 2,
- 0, credp, prid, resblks > 0,
- &cdp, NULL);
- if (error) {
- if (error == ENOSPC)
- goto error_return;
- goto abort_return;
- }
- xfs_itrace_ref(cdp);
-
- /*
- * Now we add the directory inode to the transaction.
- * We waited until now since xfs_dir_ialloc might start
- * a new transaction. Had we joined the transaction
- * earlier, the locks might have gotten released. An error
- * from here on will result in the transaction cancel
- * unlocking dp so don't do it explicitly in the error path.
- */
- IHOLD(dp);
- xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
- unlock_dp_on_error = B_FALSE;
-
- xfs_bmap_init(&free_list, &first_block);
-
- error = xfs_dir_createname(tp, dp, dir_name, cdp->i_ino,
- &first_block, &free_list, resblks ?
- resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
- if (error) {
- ASSERT(error != ENOSPC);
- goto error1;
- }
- xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
-
- error = xfs_dir_init(tp, cdp, dp);
- if (error)
- goto error2;
-
- error = xfs_bumplink(tp, dp);
- if (error)
- goto error2;
-
- created = B_TRUE;
-
- *ipp = cdp;
- IHOLD(cdp);
-
- /*
- * Attach the dquots to the new inode and modify the icount incore.
- */
- XFS_QM_DQVOPCREATE(mp, tp, cdp, udqp, gdqp);
-
- /*
- * If this is a synchronous mount, make sure that the
- * mkdir transaction goes to disk before returning to
- * the user.
- */
- if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
- xfs_trans_set_sync(tp);
- }
-
- error = xfs_bmap_finish(&tp, &free_list, &committed);
- if (error) {
- IRELE(cdp);
- goto error2;
- }
-
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
- XFS_QM_DQRELE(mp, udqp);
- XFS_QM_DQRELE(mp, gdqp);
- if (error) {
- IRELE(cdp);
- }
-
- /* Fall through to std_return with error = 0 or errno from
- * xfs_trans_commit. */
-
-std_return:
- if ((created || (error != 0 && dm_event_sent != 0)) &&
- DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
- (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
- dp, DM_RIGHT_NULL,
- created ? cdp : NULL,
- DM_RIGHT_NULL,
- dir_name->name, NULL,
- mode, error, 0);
- }
- return error;
-
- error2:
- error1:
- xfs_bmap_cancel(&free_list);
- abort_return:
- cancel_flags |= XFS_TRANS_ABORT;
- error_return:
- xfs_trans_cancel(tp, cancel_flags);
- XFS_QM_DQRELE(mp, udqp);
- XFS_QM_DQRELE(mp, gdqp);
-
- if (unlock_dp_on_error)
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
-
- goto std_return;
-}
-
int
xfs_symlink(
xfs_inode_t *dp,
@@ -2587,51 +2411,6 @@ std_return:
}
int
-xfs_inode_flush(
- xfs_inode_t *ip,
- int flags)
-{
- xfs_mount_t *mp = ip->i_mount;
- int error = 0;
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
-
- /*
- * Bypass inodes which have already been cleaned by
- * the inode flush clustering code inside xfs_iflush
- */
- if (xfs_inode_clean(ip))
- return 0;
-
- /*
- * We make this non-blocking if the inode is contended,
- * return EAGAIN to indicate to the caller that they
- * did not succeed. This prevents the flush path from
- * blocking on inodes inside another operation right
- * now, they get caught later by xfs_sync.
- */
- if (flags & FLUSH_SYNC) {
- xfs_ilock(ip, XFS_ILOCK_SHARED);
- xfs_iflock(ip);
- } else if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
- if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) {
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
- return EAGAIN;
- }
- } else {
- return EAGAIN;
- }
-
- error = xfs_iflush(ip, (flags & FLUSH_SYNC) ? XFS_IFLUSH_SYNC
- : XFS_IFLUSH_ASYNC_NOBLOCK);
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
-
- return error;
-}
-
-
-int
xfs_set_dmattrs(
xfs_inode_t *ip,
u_int evmask,
@@ -2676,7 +2455,7 @@ xfs_reclaim(
ASSERT(!VN_MAPPED(VFS_I(ip)));
/* bad inode, get out here ASAP */
- if (VN_BAD(VFS_I(ip))) {
+ if (is_bad_inode(VFS_I(ip))) {
xfs_ireclaim(ip);
return 0;
}
@@ -3090,7 +2869,7 @@ xfs_free_file_space(
/*
* Need to zero the stuff we're not freeing, on disk.
- * If its a realtime file & can't use unwritten extents then we
+ * If it's a realtime file & can't use unwritten extents then we
* actually need to zero the extent edges. Otherwise xfs_bunmapi
* will take care of it for us.
*/
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index 76df328c61b..04373c6c61f 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -31,14 +31,11 @@ int xfs_remove(struct xfs_inode *dp, struct xfs_name *name,
struct xfs_inode *ip);
int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip,
struct xfs_name *target_name);
-int xfs_mkdir(struct xfs_inode *dp, struct xfs_name *dir_name,
- mode_t mode, struct xfs_inode **ipp, cred_t *credp);
int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize,
xfs_off_t *offset, filldir_t filldir);
int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name,
const char *target_path, mode_t mode, struct xfs_inode **ipp,
cred_t *credp);
-int xfs_inode_flush(struct xfs_inode *ip, int flags);
int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state);
int xfs_reclaim(struct xfs_inode *ip);
int xfs_change_file_space(struct xfs_inode *ip, int cmd,
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
index eda04546cdf..473d584b1d3 100644
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -103,8 +103,9 @@
#define AE_BAD_OCTAL_CONSTANT (acpi_status) (0x0006 | AE_CODE_PROGRAMMER)
#define AE_BAD_DECIMAL_CONSTANT (acpi_status) (0x0007 | AE_CODE_PROGRAMMER)
#define AE_MISSING_ARGUMENTS (acpi_status) (0x0008 | AE_CODE_PROGRAMMER)
+#define AE_BAD_ADDRESS (acpi_status) (0x0009 | AE_CODE_PROGRAMMER)
-#define AE_CODE_PGM_MAX 0x0008
+#define AE_CODE_PGM_MAX 0x0009
/*
* Acpi table exceptions
@@ -224,7 +225,8 @@ char const *acpi_gbl_exception_names_pgm[] = {
"AE_BAD_HEX_CONSTANT",
"AE_BAD_OCTAL_CONSTANT",
"AE_BAD_DECIMAL_CONSTANT",
- "AE_MISSING_ARGUMENTS"
+ "AE_MISSING_ARGUMENTS",
+ "AE_BAD_ADDRESS"
};
char const *acpi_gbl_exception_names_tbl[] = {
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index e9f6574930e..c34b1102290 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -88,44 +88,30 @@ struct acpi_device;
typedef int (*acpi_op_add) (struct acpi_device * device);
typedef int (*acpi_op_remove) (struct acpi_device * device, int type);
-typedef int (*acpi_op_lock) (struct acpi_device * device, int type);
typedef int (*acpi_op_start) (struct acpi_device * device);
typedef int (*acpi_op_stop) (struct acpi_device * device, int type);
typedef int (*acpi_op_suspend) (struct acpi_device * device,
pm_message_t state);
typedef int (*acpi_op_resume) (struct acpi_device * device);
-typedef int (*acpi_op_scan) (struct acpi_device * device);
typedef int (*acpi_op_bind) (struct acpi_device * device);
typedef int (*acpi_op_unbind) (struct acpi_device * device);
-typedef int (*acpi_op_shutdown) (struct acpi_device * device);
+typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event);
struct acpi_bus_ops {
u32 acpi_op_add:1;
- u32 acpi_op_remove:1;
- u32 acpi_op_lock:1;
u32 acpi_op_start:1;
- u32 acpi_op_stop:1;
- u32 acpi_op_suspend:1;
- u32 acpi_op_resume:1;
- u32 acpi_op_scan:1;
- u32 acpi_op_bind:1;
- u32 acpi_op_unbind:1;
- u32 acpi_op_shutdown:1;
- u32 reserved:21;
};
struct acpi_device_ops {
acpi_op_add add;
acpi_op_remove remove;
- acpi_op_lock lock;
acpi_op_start start;
acpi_op_stop stop;
acpi_op_suspend suspend;
acpi_op_resume resume;
- acpi_op_scan scan;
acpi_op_bind bind;
acpi_op_unbind unbind;
- acpi_op_shutdown shutdown;
+ acpi_op_notify notify;
};
struct acpi_driver {
@@ -284,7 +270,6 @@ struct acpi_device {
struct list_head children;
struct list_head node;
struct list_head wakeup_list;
- struct list_head g_list;
struct acpi_device_status status;
struct acpi_device_flags flags;
struct acpi_device_pnp pnp;
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index 5fc1bb0f4a9..0352c8f0b05 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -67,6 +67,16 @@
#define ACPI_BAY_HID "LNXIOBAY"
#define ACPI_DOCK_HID "LNXDOCK"
+/*
+ * For fixed hardware buttons, we fabricate acpi_devices with HID
+ * ACPI_BUTTON_HID_POWERF or ACPI_BUTTON_HID_SLEEPF. Fixed hardware
+ * signals only an event; it doesn't supply a notification value.
+ * To allow drivers to treat notifications from fixed hardware the
+ * same as those from real devices, we turn the events into this
+ * notification value.
+ */
+#define ACPI_FIXED_HARDWARE_EVENT 0x100
+
/* --------------------------------------------------------------------------
PCI
-------------------------------------------------------------------------- */
@@ -99,24 +109,6 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain,
int bus);
/* --------------------------------------------------------------------------
- Power Resource
- -------------------------------------------------------------------------- */
-
-int acpi_device_sleep_wake(struct acpi_device *dev,
- int enable, int sleep_state, int dev_state);
-int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state);
-int acpi_disable_wakeup_device_power(struct acpi_device *dev);
-int acpi_power_get_inferred_state(struct acpi_device *device);
-int acpi_power_transition(struct acpi_device *device, int state);
-extern int acpi_power_nocheck;
-
-/* --------------------------------------------------------------------------
- Embedded Controller
- -------------------------------------------------------------------------- */
-int acpi_ec_ecdt_probe(void);
-int acpi_boot_ec_enable(void);
-
-/* --------------------------------------------------------------------------
Processor
-------------------------------------------------------------------------- */
@@ -165,9 +157,4 @@ static inline void unregister_hotplug_dock_device(acpi_handle handle)
}
#endif
-/*--------------------------------------------------------------------------
- Suspend/Resume
- -------------------------------------------------------------------------- */
-extern int acpi_sleep_init(void);
-
#endif /*__ACPI_DRIVERS_H__*/
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index ab0b85cf21f..3e798593b17 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -242,10 +242,6 @@ acpi_os_derive_pci_id(acpi_handle rhandle,
acpi_status acpi_os_validate_interface(char *interface);
acpi_status acpi_osi_invalidate(char* interface);
-acpi_status
-acpi_os_validate_address(u8 space_id, acpi_physical_address address,
- acpi_size length, char *name);
-
u64 acpi_os_get_timer(void);
acpi_status acpi_os_signal(u32 function, void *info);
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index cc40102fe2f..4db89e98535 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -47,7 +47,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20081204
+#define ACPI_CA_VERSION 0x20090320
#include "actypes.h"
#include "actbl.h"
@@ -191,14 +191,12 @@ acpi_evaluate_object(acpi_handle object,
struct acpi_object_list *parameter_objects,
struct acpi_buffer *return_object_buffer);
-#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_evaluate_object_typed(acpi_handle object,
acpi_string pathname,
struct acpi_object_list *external_params,
struct acpi_buffer *return_buffer,
acpi_object_type return_type);
-#endif
acpi_status
acpi_get_object_info(acpi_handle handle, struct acpi_buffer *return_buffer);
@@ -349,17 +347,15 @@ acpi_resource_to_address64(struct acpi_resource *resource,
*/
acpi_status acpi_reset(void);
-acpi_status acpi_get_register(u32 register_id, u32 * return_value);
-
-acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value);
+acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value);
-acpi_status acpi_set_register(u32 register_id, u32 value);
+acpi_status acpi_write_bit_register(u32 register_id, u32 value);
-acpi_status
-acpi_set_firmware_waking_vector(u32 physical_address);
+acpi_status acpi_set_firmware_waking_vector(u32 physical_address);
-acpi_status
-acpi_set_firmware_waking_vector64(u64 physical_address);
+#if ACPI_MACHINE_WIDTH == 64
+acpi_status acpi_set_firmware_waking_vector64(u64 physical_address);
+#endif
acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg);
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index bf8d4cfd8cf..222733d01f3 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -214,11 +214,11 @@ struct acpi_table_fadt {
u16 flush_size; /* Processor's memory cache line width, in bytes */
u16 flush_stride; /* Number of flush strides that need to be read */
u8 duty_offset; /* Processor duty cycle index in processor's P_CNT reg */
- u8 duty_width; /* Processor duty cycle value bit width in P_CNT register. */
+ u8 duty_width; /* Processor duty cycle value bit width in P_CNT register */
u8 day_alarm; /* Index to day-of-month alarm in RTC CMOS RAM */
u8 month_alarm; /* Index to month-of-year alarm in RTC CMOS RAM */
u8 century; /* Index to century in RTC CMOS RAM */
- u16 boot_flags; /* IA-PC Boot Architecture Flags. See Table 5-10 for description */
+ u16 boot_flags; /* IA-PC Boot Architecture Flags (see below for individual flags) */
u8 reserved; /* Reserved, must be zero */
u32 flags; /* Miscellaneous flag bits (see below for individual flags) */
struct acpi_generic_address reset_register; /* 64-bit address of the Reset register */
@@ -236,32 +236,41 @@ struct acpi_table_fadt {
struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */
};
+/* FADT Boot Architecture Flags (boot_flags) */
+
+#define ACPI_FADT_LEGACY_DEVICES (1) /* 00: [V2] System has LPC or ISA bus devices */
+#define ACPI_FADT_8042 (1<<1) /* 01: [V3] System has an 8042 controller on port 60/64 */
+#define ACPI_FADT_NO_VGA (1<<2) /* 02: [V4] It is not safe to probe for VGA hardware */
+#define ACPI_FADT_NO_MSI (1<<3) /* 03: [V4] Message Signaled Interrupts (MSI) must not be enabled */
+#define ACPI_FADT_NO_ASPM (1<<4) /* 04: [V4] PCIe ASPM control must not be enabled */
+
+#define FADT2_REVISION_ID 3
+
/* FADT flags */
-#define ACPI_FADT_WBINVD (1) /* 00: The wbinvd instruction works properly */
-#define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: The wbinvd flushes but does not invalidate */
-#define ACPI_FADT_C1_SUPPORTED (1<<2) /* 02: All processors support C1 state */
-#define ACPI_FADT_C2_MP_SUPPORTED (1<<3) /* 03: C2 state works on MP system */
-#define ACPI_FADT_POWER_BUTTON (1<<4) /* 04: Power button is handled as a generic feature */
-#define ACPI_FADT_SLEEP_BUTTON (1<<5) /* 05: Sleep button is handled as a generic feature, or not present */
-#define ACPI_FADT_FIXED_RTC (1<<6) /* 06: RTC wakeup stat not in fixed register space */
-#define ACPI_FADT_S4_RTC_WAKE (1<<7) /* 07: RTC wakeup possible from S4 */
-#define ACPI_FADT_32BIT_TIMER (1<<8) /* 08: tmr_val is 32 bits 0=24-bits */
-#define ACPI_FADT_DOCKING_SUPPORTED (1<<9) /* 09: Docking supported */
-#define ACPI_FADT_RESET_REGISTER (1<<10) /* 10: System reset via the FADT RESET_REG supported */
-#define ACPI_FADT_SEALED_CASE (1<<11) /* 11: No internal expansion capabilities and case is sealed */
-#define ACPI_FADT_HEADLESS (1<<12) /* 12: No local video capabilities or local input devices */
-#define ACPI_FADT_SLEEP_TYPE (1<<13) /* 13: Must execute native instruction after writing SLP_TYPx register */
-#define ACPI_FADT_PCI_EXPRESS_WAKE (1<<14) /* 14: System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */
-#define ACPI_FADT_PLATFORM_CLOCK (1<<15) /* 15: OSPM should use platform-provided timer (ACPI 3.0) */
-#define ACPI_FADT_S4_RTC_VALID (1<<16) /* 16: Contents of RTC_STS valid after S4 wake (ACPI 3.0) */
-#define ACPI_FADT_REMOTE_POWER_ON (1<<17) /* 17: System is compatible with remote power on (ACPI 3.0) */
-#define ACPI_FADT_APIC_CLUSTER (1<<18) /* 18: All local APICs must use cluster model (ACPI 3.0) */
-#define ACPI_FADT_APIC_PHYSICAL (1<<19) /* 19: All local x_aPICs must use physical dest mode (ACPI 3.0) */
+#define ACPI_FADT_WBINVD (1) /* 00: [V1] The wbinvd instruction works properly */
+#define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: [V1] wbinvd flushes but does not invalidate caches */
+#define ACPI_FADT_C1_SUPPORTED (1<<2) /* 02: [V1] All processors support C1 state */
+#define ACPI_FADT_C2_MP_SUPPORTED (1<<3) /* 03: [V1] C2 state works on MP system */
+#define ACPI_FADT_POWER_BUTTON (1<<4) /* 04: [V1] Power button is handled as a control method device */
+#define ACPI_FADT_SLEEP_BUTTON (1<<5) /* 05: [V1] Sleep button is handled as a control method device */
+#define ACPI_FADT_FIXED_RTC (1<<6) /* 06: [V1] RTC wakeup status not in fixed register space */
+#define ACPI_FADT_S4_RTC_WAKE (1<<7) /* 07: [V1] RTC alarm can wake system from S4 */
+#define ACPI_FADT_32BIT_TIMER (1<<8) /* 08: [V1] ACPI timer width is 32-bit (0=24-bit) */
+#define ACPI_FADT_DOCKING_SUPPORTED (1<<9) /* 09: [V1] Docking supported */
+#define ACPI_FADT_RESET_REGISTER (1<<10) /* 10: [V2] System reset via the FADT RESET_REG supported */
+#define ACPI_FADT_SEALED_CASE (1<<11) /* 11: [V3] No internal expansion capabilities and case is sealed */
+#define ACPI_FADT_HEADLESS (1<<12) /* 12: [V3] No local video capabilities or local input devices */
+#define ACPI_FADT_SLEEP_TYPE (1<<13) /* 13: [V3] Must execute native instruction after writing SLP_TYPx register */
+#define ACPI_FADT_PCI_EXPRESS_WAKE (1<<14) /* 14: [V4] System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */
+#define ACPI_FADT_PLATFORM_CLOCK (1<<15) /* 15: [V4] OSPM should use platform-provided timer (ACPI 3.0) */
+#define ACPI_FADT_S4_RTC_VALID (1<<16) /* 16: [V4] Contents of RTC_STS valid after S4 wake (ACPI 3.0) */
+#define ACPI_FADT_REMOTE_POWER_ON (1<<17) /* 17: [V4] System is compatible with remote power on (ACPI 3.0) */
+#define ACPI_FADT_APIC_CLUSTER (1<<18) /* 18: [V4] All local APICs must use cluster model (ACPI 3.0) */
+#define ACPI_FADT_APIC_PHYSICAL (1<<19) /* 19: [V4] All local x_aPICs must use physical dest mode (ACPI 3.0) */
+
+/* FADT Prefered Power Management Profiles */
-/*
- * FADT Prefered Power Management Profiles
- */
enum acpi_prefered_pm_profiles {
PM_UNSPECIFIED = 0,
PM_DESKTOP = 1,
@@ -272,16 +281,6 @@ enum acpi_prefered_pm_profiles {
PM_APPLIANCE_PC = 6
};
-/* FADT Boot Arch Flags */
-
-#define BAF_LEGACY_DEVICES 0x0001
-#define BAF_8042_KEYBOARD_CONTROLLER 0x0002
-#define BAF_MSI_NOT_SUPPORTED 0x0008
-#define BAF_PCIE_ASPM_CONTROL 0x0010
-
-#define FADT2_REVISION_ID 3
-#define FADT2_MINUS_REVISION_ID 2
-
/* Reset to default packing */
#pragma pack()
@@ -310,8 +309,9 @@ struct acpi_table_desc {
#define ACPI_TABLE_ORIGIN_UNKNOWN (0)
#define ACPI_TABLE_ORIGIN_MAPPED (1)
#define ACPI_TABLE_ORIGIN_ALLOCATED (2)
-#define ACPI_TABLE_ORIGIN_MASK (3)
-#define ACPI_TABLE_IS_LOADED (4)
+#define ACPI_TABLE_ORIGIN_OVERRIDE (4)
+#define ACPI_TABLE_ORIGIN_MASK (7)
+#define ACPI_TABLE_IS_LOADED (8)
/*
* Get the remaining ACPI tables
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index 18963b96811..59ade075247 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -1016,9 +1016,9 @@ struct acpi_madt_interrupt_source {
struct acpi_madt_local_x2apic {
struct acpi_subtable_header header;
u16 reserved; /* Reserved - must be zero */
- u32 local_apic_id; /* Processor X2_APIC ID */
+ u32 local_apic_id; /* Processor x2APIC ID */
u32 lapic_flags;
- u32 uid; /* Extended X2_APIC processor ID */
+ u32 uid; /* ACPI processor UID */
};
/* 10: Local X2APIC NMI (07/2008) */
@@ -1026,7 +1026,7 @@ struct acpi_madt_local_x2apic {
struct acpi_madt_local_x2apic_nmi {
struct acpi_subtable_header header;
u16 inti_flags;
- u32 uid; /* Processor X2_APIC ID */
+ u32 uid; /* ACPI processor UID */
u8 lint; /* LINTn to which NMI is connected */
u8 reserved[3];
};
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index a20aab51017..f555d927f7c 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -777,17 +777,25 @@ typedef u8 acpi_adr_space_type;
#define ACPI_BITREG_SCI_ENABLE 0x0E
#define ACPI_BITREG_BUS_MASTER_RLD 0x0F
#define ACPI_BITREG_GLOBAL_LOCK_RELEASE 0x10
-#define ACPI_BITREG_SLEEP_TYPE_A 0x11
-#define ACPI_BITREG_SLEEP_TYPE_B 0x12
-#define ACPI_BITREG_SLEEP_ENABLE 0x13
+#define ACPI_BITREG_SLEEP_TYPE 0x11
+#define ACPI_BITREG_SLEEP_ENABLE 0x12
/* PM2 Control register */
-#define ACPI_BITREG_ARB_DISABLE 0x14
+#define ACPI_BITREG_ARB_DISABLE 0x13
-#define ACPI_BITREG_MAX 0x14
+#define ACPI_BITREG_MAX 0x13
#define ACPI_NUM_BITREG ACPI_BITREG_MAX + 1
+/* Status register values. A 1 clears a status bit. 0 = no effect */
+
+#define ACPI_CLEAR_STATUS 1
+
+/* Enable and Control register values */
+
+#define ACPI_ENABLE_EVENT 1
+#define ACPI_DISABLE_EVENT 0
+
/*
* External ACPI object definition
*/
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 0574add2a1e..b09c4fde972 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -322,7 +322,7 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr)
int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
int acpi_processor_get_throttling_info(struct acpi_processor *pr);
extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
-extern struct file_operations acpi_processor_throttling_fops;
+extern const struct file_operations acpi_processor_throttling_fops;
extern void acpi_processor_throttling_init(void);
/* in processor_idle.c */
int acpi_processor_power_init(struct acpi_processor *pr,
@@ -336,7 +336,7 @@ extern struct cpuidle_driver acpi_idle_driver;
/* in processor_thermal.c */
int acpi_processor_get_limit_info(struct acpi_processor *pr);
-extern struct file_operations acpi_processor_limit_fops;
+extern const struct file_operations acpi_processor_limit_fops;
extern struct thermal_cooling_device_ops processor_cooling_ops;
#ifdef CONFIG_CPU_FREQ
void acpi_thermal_cpufreq_init(void);
diff --git a/include/acpi/video.h b/include/acpi/video.h
new file mode 100644
index 00000000000..f0275bb79ce
--- /dev/null
+++ b/include/acpi/video.h
@@ -0,0 +1,11 @@
+#ifndef __ACPI_VIDEO_H
+#define __ACPI_VIDEO_H
+
+#if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE)
+extern int acpi_video_register(void);
+#else
+static inline int acpi_video_register(void) { return 0; }
+#endif
+
+#endif
+
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index 00f45ff081a..b0e63c672eb 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -80,56 +80,4 @@ extern void setup_per_cpu_areas(void);
#define DECLARE_PER_CPU(type, name) extern PER_CPU_ATTRIBUTES \
__typeof__(type) per_cpu_var(name)
-/*
- * Optional methods for optimized non-lvalue per-cpu variable access.
- *
- * @var can be a percpu variable or a field of it and its size should
- * equal char, int or long. percpu_read() evaluates to a lvalue and
- * all others to void.
- *
- * These operations are guaranteed to be atomic w.r.t. preemption.
- * The generic versions use plain get/put_cpu_var(). Archs are
- * encouraged to implement single-instruction alternatives which don't
- * require preemption protection.
- */
-#ifndef percpu_read
-# define percpu_read(var) \
- ({ \
- typeof(per_cpu_var(var)) __tmp_var__; \
- __tmp_var__ = get_cpu_var(var); \
- put_cpu_var(var); \
- __tmp_var__; \
- })
-#endif
-
-#define __percpu_generic_to_op(var, val, op) \
-do { \
- get_cpu_var(var) op val; \
- put_cpu_var(var); \
-} while (0)
-
-#ifndef percpu_write
-# define percpu_write(var, val) __percpu_generic_to_op(var, (val), =)
-#endif
-
-#ifndef percpu_add
-# define percpu_add(var, val) __percpu_generic_to_op(var, (val), +=)
-#endif
-
-#ifndef percpu_sub
-# define percpu_sub(var, val) __percpu_generic_to_op(var, (val), -=)
-#endif
-
-#ifndef percpu_and
-# define percpu_and(var, val) __percpu_generic_to_op(var, (val), &=)
-#endif
-
-#ifndef percpu_or
-# define percpu_or(var, val) __percpu_generic_to_op(var, (val), |=)
-#endif
-
-#ifndef percpu_xor
-# define percpu_xor(var, val) __percpu_generic_to_op(var, (val), ^=)
-#endif
-
#endif /* _ASM_GENERIC_PERCPU_H_ */
diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h
index 35752dadd6d..c840719a8c5 100644
--- a/include/asm-generic/siginfo.h
+++ b/include/asm-generic/siginfo.h
@@ -201,7 +201,7 @@ typedef struct siginfo {
#define TRAP_TRACE (__SI_FAULT|2) /* process trace trap */
#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint/watchpoint */
-#define NSIGTRAP 2
+#define NSIGTRAP 4
/*
* SIGCHLD si_codes
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index a654d724d3b..7fa660fd449 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -61,6 +61,30 @@
#define BRANCH_PROFILE()
#endif
+#ifdef CONFIG_EVENT_TRACER
+#define FTRACE_EVENTS() VMLINUX_SYMBOL(__start_ftrace_events) = .; \
+ *(_ftrace_events) \
+ VMLINUX_SYMBOL(__stop_ftrace_events) = .;
+#else
+#define FTRACE_EVENTS()
+#endif
+
+#ifdef CONFIG_TRACING
+#define TRACE_PRINTKS() VMLINUX_SYMBOL(__start___trace_bprintk_fmt) = .; \
+ *(__trace_printk_fmt) /* Trace_printk fmt' pointer */ \
+ VMLINUX_SYMBOL(__stop___trace_bprintk_fmt) = .;
+#else
+#define TRACE_PRINTKS()
+#endif
+
+#ifdef CONFIG_FTRACE_SYSCALLS
+#define TRACE_SYSCALLS() VMLINUX_SYMBOL(__start_syscalls_metadata) = .; \
+ *(__syscalls_metadata) \
+ VMLINUX_SYMBOL(__stop_syscalls_metadata) = .;
+#else
+#define TRACE_SYSCALLS()
+#endif
+
/* .data section */
#define DATA_DATA \
*(.data) \
@@ -86,7 +110,10 @@
*(__verbose) \
VMLINUX_SYMBOL(__stop___verbose) = .; \
LIKELY_PROFILE() \
- BRANCH_PROFILE()
+ BRANCH_PROFILE() \
+ TRACE_PRINTKS() \
+ FTRACE_EVENTS() \
+ TRACE_SYSCALLS()
#define RO_DATA(align) \
. = ALIGN((align)); \
diff --git a/include/asm-m32r/ftrace.h b/include/asm-m32r/ftrace.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/include/asm-m32r/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/include/asm-mn10300/.gitignore b/include/asm-mn10300/.gitignore
deleted file mode 100644
index 0f87ba790e2..00000000000
--- a/include/asm-mn10300/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-proc
-unit
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h
index 2df74eb0956..9477af01a63 100644
--- a/include/drm/drm_pciids.h
+++ b/include/drm/drm_pciids.h
@@ -472,6 +472,7 @@
{0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x8086, 0x358e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define gamma_PCI_IDS \
@@ -533,4 +534,5 @@
{0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
{0x8086, 0xa001, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
{0x8086, 0xa011, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
+ {0x8086, 0x35e8, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
{0, 0, 0}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d047f846c3e..6586cbd0d4a 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -97,6 +97,7 @@ void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
/* the following four functions are architecture-dependent */
void acpi_numa_slit_init (struct acpi_table_slit *slit);
void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
+void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
void acpi_numa_arch_fixup(void);
diff --git a/include/linux/async_tx.h b/include/linux/async_tx.h
index 45f6297821b..5fc2ef8d97f 100644
--- a/include/linux/async_tx.h
+++ b/include/linux/async_tx.h
@@ -21,6 +21,15 @@
#include <linux/spinlock.h>
#include <linux/interrupt.h>
+/* on architectures without dma-mapping capabilities we need to ensure
+ * that the asynchronous path compiles away
+ */
+#ifdef CONFIG_HAS_DMA
+#define __async_inline
+#else
+#define __async_inline __always_inline
+#endif
+
/**
* dma_chan_ref - object used to manage dma channels received from the
* dmaengine core.
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 6617c9f8f2c..cb79b7a208e 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -29,6 +29,8 @@
#ifndef __LINUX_ATA_H__
#define __LINUX_ATA_H__
+#include <linux/kernel.h>
+#include <linux/string.h>
#include <linux/types.h>
#include <asm/byteorder.h>
@@ -91,6 +93,7 @@ enum {
ATA_ID_CFA_POWER = 160,
ATA_ID_CFA_KEY_MGMT = 162,
ATA_ID_CFA_MODES = 163,
+ ATA_ID_DATA_SET_MGMT = 169,
ATA_ID_ROT_SPEED = 217,
ATA_ID_PIO4 = (1 << 1),
@@ -248,6 +251,7 @@ enum {
ATA_CMD_SMART = 0xB0,
ATA_CMD_MEDIA_LOCK = 0xDE,
ATA_CMD_MEDIA_UNLOCK = 0xDF,
+ ATA_CMD_DSM = 0x06,
/* marked obsolete in the ATA/ATAPI-7 spec */
ATA_CMD_RESTORE = 0x10,
@@ -321,6 +325,9 @@ enum {
ATA_SMART_READ_VALUES = 0xD0,
ATA_SMART_READ_THRESHOLDS = 0xD1,
+ /* feature values for Data Set Management */
+ ATA_DSM_TRIM = 0x01,
+
/* password used in LBA Mid / LBA High for executing SMART commands */
ATA_SMART_LBAM_PASS = 0x4F,
ATA_SMART_LBAH_PASS = 0xC2,
@@ -723,6 +730,14 @@ static inline int ata_id_has_unload(const u16 *id)
return 0;
}
+static inline int ata_id_has_trim(const u16 *id)
+{
+ if (ata_id_major_version(id) >= 7 &&
+ (id[ATA_ID_DATA_SET_MGMT] & 1))
+ return 1;
+ return 0;
+}
+
static inline int ata_id_current_chs_valid(const u16 *id)
{
/* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command
@@ -863,6 +878,32 @@ static inline void ata_id_to_hd_driveid(u16 *id)
#endif
}
+/*
+ * Write up to 'max' LBA Range Entries to the buffer that will cover the
+ * extent from sector to sector + count. This is used for TRIM and for
+ * ADD LBA(S) TO NV CACHE PINNED SET.
+ */
+static inline unsigned ata_set_lba_range_entries(void *_buffer, unsigned max,
+ u64 sector, unsigned long count)
+{
+ __le64 *buffer = _buffer;
+ unsigned i = 0;
+
+ while (i < max) {
+ u64 entry = sector |
+ ((u64)(count > 0xffff ? 0xffff : count) << 48);
+ buffer[i++] = __cpu_to_le64(entry);
+ if (count <= 0xffff)
+ break;
+ count -= 0xffff;
+ sector += 0xffff;
+ }
+
+ max = ALIGN(i * 8, 512);
+ memset(buffer + i, 0, max - i * 8);
+ return max;
+}
+
static inline int is_multi_taskfile(struct ata_taskfile *tf)
{
return (tf->command == ATA_CMD_READ_MULTI) ||
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index bee52abb8a4..0ec2c594868 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -24,8 +24,8 @@ struct dentry;
*/
enum bdi_state {
BDI_pdflush, /* A pdflush thread is working this device */
- BDI_write_congested, /* The write queue is getting full */
- BDI_read_congested, /* The read queue is getting full */
+ BDI_async_congested, /* The async (write) queue is getting full */
+ BDI_sync_congested, /* The sync queue is getting full */
BDI_unused, /* Available bits start here */
};
@@ -215,18 +215,18 @@ static inline int bdi_congested(struct backing_dev_info *bdi, int bdi_bits)
static inline int bdi_read_congested(struct backing_dev_info *bdi)
{
- return bdi_congested(bdi, 1 << BDI_read_congested);
+ return bdi_congested(bdi, 1 << BDI_sync_congested);
}
static inline int bdi_write_congested(struct backing_dev_info *bdi)
{
- return bdi_congested(bdi, 1 << BDI_write_congested);
+ return bdi_congested(bdi, 1 << BDI_async_congested);
}
static inline int bdi_rw_congested(struct backing_dev_info *bdi)
{
- return bdi_congested(bdi, (1 << BDI_read_congested)|
- (1 << BDI_write_congested));
+ return bdi_congested(bdi, (1 << BDI_sync_congested) |
+ (1 << BDI_async_congested));
}
void clear_bdi_congested(struct backing_dev_info *bdi, int rw);
diff --git a/include/linux/bio.h b/include/linux/bio.h
index b05b1d4d17d..b900d2c67d2 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -145,20 +145,21 @@ struct bio {
* bit 2 -- barrier
* Insert a serialization point in the IO queue, forcing previously
* submitted IO to be completed before this one is issued.
- * 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 4 -- metadata request
+ * bit 3 -- synchronous I/O hint.
+ * bit 4 -- Unplug the device immediately after submitting this bio.
+ * bit 5 -- metadata request
* Used for tracing to differentiate metadata and data IO. May also
* get some preferential treatment in the IO scheduler
- * bit 5 -- discard sectors
+ * bit 6 -- 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
+ * bit 7 -- fail fast device errors
+ * bit 8 -- fail fast transport errors
+ * bit 9 -- fail fast driver errors
* Don't want driver retries for any fast fail whatever the reason.
+ * bit 10 -- Tell the IO scheduler not to wait for more requests after this
+ one has been submitted, even if it is a SYNC request.
*/
#define BIO_RW 0 /* Must match RW in req flags (blkdev.h) */
#define BIO_RW_AHEAD 1 /* Must match FAILFAST in req flags */
@@ -170,6 +171,7 @@ struct bio {
#define BIO_RW_FAILFAST_DEV 7
#define BIO_RW_FAILFAST_TRANSPORT 8
#define BIO_RW_FAILFAST_DRIVER 9
+#define BIO_RW_NOIDLE 10
#define bio_rw_flagged(bio, flag) ((bio)->bi_rw & (1 << (flag)))
@@ -188,6 +190,7 @@ struct bio {
#define bio_rw_ahead(bio) bio_rw_flagged(bio, BIO_RW_AHEAD)
#define bio_rw_meta(bio) bio_rw_flagged(bio, BIO_RW_META)
#define bio_discard(bio) bio_rw_flagged(bio, BIO_RW_DISCARD)
+#define bio_noidle(bio) bio_rw_flagged(bio, BIO_RW_NOIDLE)
/*
* upper 16 bits of bi_rw define the io priority of this bio
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 465d6babc84..ba54c834a59 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -38,6 +38,10 @@ struct request;
typedef void (rq_end_io_fn)(struct request *, int);
struct request_list {
+ /*
+ * count[], starved[], and wait[] are indexed by
+ * BLK_RW_SYNC/BLK_RW_ASYNC
+ */
int count[2];
int starved[2];
int elvpriv;
@@ -66,6 +70,11 @@ enum rq_cmd_type_bits {
REQ_TYPE_ATA_PC,
};
+enum {
+ BLK_RW_ASYNC = 0,
+ BLK_RW_SYNC = 1,
+};
+
/*
* For request of type REQ_TYPE_LINUX_BLOCK, rq->cmd[0] is the opcode being
* sent down (similar to how REQ_TYPE_BLOCK_PC means that ->cmd[] holds a
@@ -103,12 +112,12 @@ enum rq_flag_bits {
__REQ_QUIET, /* don't worry about errors */
__REQ_PREEMPT, /* set for "ide_preempt" requests */
__REQ_ORDERED_COLOR, /* is before or after barrier */
- __REQ_RW_SYNC, /* request is sync (O_DIRECT) */
+ __REQ_RW_SYNC, /* request is sync (sync write or read) */
__REQ_ALLOCED, /* request came from our alloc pool */
__REQ_RW_META, /* metadata io request */
__REQ_COPY_USER, /* contains copies of user pages */
__REQ_INTEGRITY, /* integrity metadata has been remapped */
- __REQ_UNPLUG, /* unplug queue on submission */
+ __REQ_NOIDLE, /* Don't anticipate more IO after this one */
__REQ_NR_BITS, /* stops here */
};
@@ -135,7 +144,7 @@ enum rq_flag_bits {
#define REQ_RW_META (1 << __REQ_RW_META)
#define REQ_COPY_USER (1 << __REQ_COPY_USER)
#define REQ_INTEGRITY (1 << __REQ_INTEGRITY)
-#define REQ_UNPLUG (1 << __REQ_UNPLUG)
+#define REQ_NOIDLE (1 << __REQ_NOIDLE)
#define BLK_MAX_CDB 16
@@ -438,8 +447,8 @@ struct request_queue
#define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */
#define QUEUE_FLAG_QUEUED 1 /* uses generic tag queueing */
#define QUEUE_FLAG_STOPPED 2 /* queue is stopped */
-#define QUEUE_FLAG_READFULL 3 /* read queue has been filled */
-#define QUEUE_FLAG_WRITEFULL 4 /* write queue has been filled */
+#define QUEUE_FLAG_SYNCFULL 3 /* read queue has been filled */
+#define QUEUE_FLAG_ASYNCFULL 4 /* write queue has been filled */
#define QUEUE_FLAG_DEAD 5 /* queue being torn down */
#define QUEUE_FLAG_REENTER 6 /* Re-entrancy avoidance */
#define QUEUE_FLAG_PLUGGED 7 /* queue is plugged */
@@ -611,32 +620,42 @@ enum {
#define rq_data_dir(rq) ((rq)->cmd_flags & 1)
/*
- * We regard a request as sync, if it's a READ or a SYNC write.
+ * We regard a request as sync, if either a read or a sync write
*/
-#define rq_is_sync(rq) (rq_data_dir((rq)) == READ || (rq)->cmd_flags & REQ_RW_SYNC)
+static inline bool rw_is_sync(unsigned int rw_flags)
+{
+ return !(rw_flags & REQ_RW) || (rw_flags & REQ_RW_SYNC);
+}
+
+static inline bool rq_is_sync(struct request *rq)
+{
+ return rw_is_sync(rq->cmd_flags);
+}
+
#define rq_is_meta(rq) ((rq)->cmd_flags & REQ_RW_META)
+#define rq_noidle(rq) ((rq)->cmd_flags & REQ_NOIDLE)
-static inline int blk_queue_full(struct request_queue *q, int rw)
+static inline int blk_queue_full(struct request_queue *q, int sync)
{
- if (rw == READ)
- return test_bit(QUEUE_FLAG_READFULL, &q->queue_flags);
- return test_bit(QUEUE_FLAG_WRITEFULL, &q->queue_flags);
+ if (sync)
+ return test_bit(QUEUE_FLAG_SYNCFULL, &q->queue_flags);
+ return test_bit(QUEUE_FLAG_ASYNCFULL, &q->queue_flags);
}
-static inline void blk_set_queue_full(struct request_queue *q, int rw)
+static inline void blk_set_queue_full(struct request_queue *q, int sync)
{
- if (rw == READ)
- queue_flag_set(QUEUE_FLAG_READFULL, q);
+ if (sync)
+ queue_flag_set(QUEUE_FLAG_SYNCFULL, q);
else
- queue_flag_set(QUEUE_FLAG_WRITEFULL, q);
+ queue_flag_set(QUEUE_FLAG_ASYNCFULL, q);
}
-static inline void blk_clear_queue_full(struct request_queue *q, int rw)
+static inline void blk_clear_queue_full(struct request_queue *q, int sync)
{
- if (rw == READ)
- queue_flag_clear(QUEUE_FLAG_READFULL, q);
+ if (sync)
+ queue_flag_clear(QUEUE_FLAG_SYNCFULL, q);
else
- queue_flag_clear(QUEUE_FLAG_WRITEFULL, q);
+ queue_flag_clear(QUEUE_FLAG_ASYNCFULL, q);
}
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 6e915878e88..d960889e92e 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -144,6 +144,9 @@ struct blk_user_trace_setup {
#ifdef __KERNEL__
#if defined(CONFIG_BLK_DEV_IO_TRACE)
+
+#include <linux/sysfs.h>
+
struct blk_trace {
int trace_state;
struct rchan *rchan;
@@ -194,6 +197,8 @@ extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
extern int blk_trace_startstop(struct request_queue *q, int start);
extern int blk_trace_remove(struct request_queue *q);
+extern struct attribute_group blk_trace_attr_group;
+
#else /* !CONFIG_BLK_DEV_IO_TRACE */
#define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY)
#define blk_trace_shutdown(q) do { } while (0)
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 4864a43b2b4..c3021105edc 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -377,7 +377,21 @@ struct cpu_vfs_cap_data {
#define CAP_FOR_EACH_U32(__capi) \
for (__capi = 0; __capi < _KERNEL_CAPABILITY_U32S; ++__capi)
+/*
+ * CAP_FS_MASK and CAP_NFSD_MASKS:
+ *
+ * The fs mask is all the privileges that fsuid==0 historically meant.
+ * At one time in the past, that included CAP_MKNOD and CAP_LINUX_IMMUTABLE.
+ *
+ * It has never meant setting security.* and trusted.* xattrs.
+ *
+ * We could also define fsmask as follows:
+ * 1. CAP_FS_MASK is the privilege to bypass all fs-related DAC permissions
+ * 2. The security.* and trusted.* xattrs are fs-related MAC permissions
+ */
+
# define CAP_FS_MASK_B0 (CAP_TO_MASK(CAP_CHOWN) \
+ | CAP_TO_MASK(CAP_MKNOD) \
| CAP_TO_MASK(CAP_DAC_OVERRIDE) \
| CAP_TO_MASK(CAP_DAC_READ_SEARCH) \
| CAP_TO_MASK(CAP_FOWNER) \
@@ -392,11 +406,12 @@ struct cpu_vfs_cap_data {
# define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }})
# define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }})
# define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }})
-# define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0, CAP_FS_MASK_B1 } })
+# define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \
+ | CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \
+ CAP_FS_MASK_B1 } })
# define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \
- | CAP_TO_MASK(CAP_SYS_RESOURCE) \
- | CAP_TO_MASK(CAP_MKNOD), \
- CAP_FS_MASK_B1 } })
+ | CAP_TO_MASK(CAP_SYS_RESOURCE), \
+ CAP_FS_MASK_B1 } })
#endif /* _KERNEL_CAPABILITY_U32S != 2 */
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 4316a546beb..665fa70e409 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -365,7 +365,10 @@ int cgroup_task_count(const struct cgroup *cgrp);
/* Return true if cgrp is a descendant of the task's cgroup */
int cgroup_is_descendant(const struct cgroup *cgrp, struct task_struct *task);
-/* Control Group subsystem type. See Documentation/cgroups.txt for details */
+/*
+ * Control Group subsystem type.
+ * See Documentation/cgroups/cgroups.txt for details
+ */
struct cgroup_subsys {
struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss,
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 9723edd6455..f2ded21f9a3 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -193,10 +193,10 @@ asmlinkage ssize_t compat_sys_writev(unsigned long fd,
const struct compat_iovec __user *vec, unsigned long vlen);
asmlinkage ssize_t compat_sys_preadv(unsigned long fd,
const struct compat_iovec __user *vec,
- unsigned long vlen, u32 pos_high, u32 pos_low);
+ unsigned long vlen, u32 pos_low, u32 pos_high);
asmlinkage ssize_t compat_sys_pwritev(unsigned long fd,
const struct compat_iovec __user *vec,
- unsigned long vlen, u32 pos_high, u32 pos_low);
+ unsigned long vlen, u32 pos_low, u32 pos_high);
int compat_do_execve(char * filename, compat_uptr_t __user *argv,
compat_uptr_t __user *envp, struct pt_regs * regs);
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index d95da1020f1..37bcb50a4d7 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -68,6 +68,7 @@ struct ftrace_branch_data {
unsigned long miss;
unsigned long hit;
};
+ unsigned long miss_hit[2];
};
};
@@ -75,7 +76,8 @@ struct ftrace_branch_data {
* Note: DISABLE_BRANCH_PROFILING can be used by special lowlevel code
* to disable branch tracing on a per file basis.
*/
-#if defined(CONFIG_TRACE_BRANCH_PROFILING) && !defined(DISABLE_BRANCH_PROFILING)
+#if defined(CONFIG_TRACE_BRANCH_PROFILING) \
+ && !defined(DISABLE_BRANCH_PROFILING) && !defined(__CHECKER__)
void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
#define likely_notrace(x) __builtin_expect(!!(x), 1)
@@ -113,7 +115,9 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
* "Define 'is'", Bill Clinton
* "Define 'if'", Steven Rostedt
*/
-#define if(cond) if (__builtin_constant_p((cond)) ? !!(cond) : \
+#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
+#define __trace_if(cond) \
+ if (__builtin_constant_p((cond)) ? !!(cond) : \
({ \
int ______r; \
static struct ftrace_branch_data \
@@ -125,10 +129,7 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
.line = __LINE__, \
}; \
______r = !!(cond); \
- if (______r) \
- ______f.hit++; \
- else \
- ______f.miss++; \
+ ______f.miss_hit[______r]++; \
______r; \
}))
#endif /* CONFIG_PROFILE_ALL_BRANCHES */
diff --git a/include/linux/connector.h b/include/linux/connector.h
index fc65d219d88..b9966e64604 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -39,8 +39,10 @@
#define CN_IDX_V86D 0x4
#define CN_VAL_V86D_UVESAFB 0x1
#define CN_IDX_BB 0x5 /* BlackBoard, from the TSP GPL sampling framework */
+#define CN_DST_IDX 0x6
+#define CN_DST_VAL 0x1
-#define CN_NETLINK_USERS 6
+#define CN_NETLINK_USERS 7
/*
* Maximum connector's message size.
diff --git a/include/linux/debug_locks.h b/include/linux/debug_locks.h
index 096476f1fb3..29b3ce3f2a1 100644
--- a/include/linux/debug_locks.h
+++ b/include/linux/debug_locks.h
@@ -2,12 +2,20 @@
#define __LINUX_DEBUG_LOCKING_H
#include <linux/kernel.h>
+#include <asm/atomic.h>
+#include <asm/system.h>
struct task_struct;
extern int debug_locks;
extern int debug_locks_silent;
+
+static inline int __debug_locks_off(void)
+{
+ return xchg(&debug_locks, 0);
+}
+
/*
* Generic 'turn off all lock debugging' function:
*/
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index af0e01d4c66..eb5c2ba2f81 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -71,6 +71,9 @@ struct dentry *debugfs_create_bool(const char *name, mode_t mode,
struct dentry *debugfs_create_blob(const char *name, mode_t mode,
struct dentry *parent,
struct debugfs_blob_wrapper *blob);
+
+bool debugfs_initialized(void);
+
#else
#include <linux/err.h>
@@ -183,6 +186,11 @@ static inline struct dentry *debugfs_create_blob(const char *name, mode_t mode,
return ERR_PTR(-ENODEV);
}
+static inline bool debugfs_initialized(void)
+{
+ return false;
+}
+
#endif
#endif
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 8209e08969f..ded2d7c4266 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -116,7 +116,6 @@ void dm_put_device(struct dm_target *ti, struct dm_dev *d);
/*
* Target features
*/
-#define DM_TARGET_SUPPORTS_BARRIERS 0x00000001
struct target_type {
uint64_t features;
@@ -139,6 +138,9 @@ struct target_type {
dm_ioctl_fn ioctl;
dm_merge_fn merge;
dm_busy_fn busy;
+
+ /* For internal device-mapper use. */
+ struct list_head list;
};
struct io_restrictions {
diff --git a/include/linux/dm-dirty-log.h b/include/linux/dm-dirty-log.h
index 600c5fb2daa..5e8b11d88f6 100644
--- a/include/linux/dm-dirty-log.h
+++ b/include/linux/dm-dirty-log.h
@@ -28,6 +28,9 @@ struct dm_dirty_log_type {
const char *name;
struct module *module;
+ /* For internal device-mapper use */
+ struct list_head list;
+
int (*ctr)(struct dm_dirty_log *log, struct dm_target *ti,
unsigned argc, char **argv);
void (*dtr)(struct dm_dirty_log *log);
@@ -113,6 +116,16 @@ struct dm_dirty_log_type {
*/
int (*status)(struct dm_dirty_log *log, status_type_t status_type,
char *result, unsigned maxlen);
+
+ /*
+ * is_remote_recovering is necessary for cluster mirroring. It provides
+ * a way to detect recovery on another node, so we aren't writing
+ * concurrently. This function is likely to block (when a cluster log
+ * is used).
+ *
+ * Returns: 0, 1
+ */
+ int (*is_remote_recovering)(struct dm_dirty_log *log, region_t region);
};
int dm_dirty_log_type_register(struct dm_dirty_log_type *type);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index d7d090d2103..8083b6a36a3 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -115,7 +115,7 @@ static inline u64 dma_get_mask(struct device *dev)
{
if (dev && dev->dma_mask && *dev->dma_mask)
return *dev->dma_mask;
- return DMA_32BIT_MASK;
+ return DMA_BIT_MASK(32);
}
extern u64 dma_get_required_mask(struct device *dev);
diff --git a/include/linux/dma_remapping.h b/include/linux/dma_remapping.h
index af1dab41674..1a455f1f86d 100644
--- a/include/linux/dma_remapping.h
+++ b/include/linux/dma_remapping.h
@@ -11,6 +11,7 @@
#define DMA_PTE_READ (1)
#define DMA_PTE_WRITE (2)
+#define DMA_PTE_SNP (1 << 11)
struct intel_iommu;
struct dmar_domain;
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 1956c8d46d3..2e2aa3df170 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -23,9 +23,6 @@
#include <linux/device.h>
#include <linux/uio.h>
-#include <linux/kref.h>
-#include <linux/completion.h>
-#include <linux/rcupdate.h>
#include <linux/dma-mapping.h>
/**
@@ -205,6 +202,7 @@ struct dma_async_tx_descriptor {
/**
* struct dma_device - info on the entity supplying DMA services
* @chancnt: how many DMA channels are supported
+ * @privatecnt: how many DMA channels are requested by dma_request_channel
* @channels: the list of struct dma_chan
* @global_node: list_head for global dma_device_list
* @cap_mask: one or more dma_capability flags
@@ -227,6 +225,7 @@ struct dma_async_tx_descriptor {
struct dma_device {
unsigned int chancnt;
+ unsigned int privatecnt;
struct list_head channels;
struct list_head global_node;
dma_cap_mask_t cap_mask;
@@ -291,6 +290,24 @@ static inline void net_dmaengine_put(void)
}
#endif
+#ifdef CONFIG_ASYNC_TX_DMA
+#define async_dmaengine_get() dmaengine_get()
+#define async_dmaengine_put() dmaengine_put()
+#define async_dma_find_channel(type) dma_find_channel(type)
+#else
+static inline void async_dmaengine_get(void)
+{
+}
+static inline void async_dmaengine_put(void)
+{
+}
+static inline struct dma_chan *
+async_dma_find_channel(enum dma_transaction_type type)
+{
+ return NULL;
+}
+#endif
+
dma_cookie_t dma_async_memcpy_buf_to_buf(struct dma_chan *chan,
void *dest, void *src, size_t len);
dma_cookie_t dma_async_memcpy_buf_to_pg(struct dma_chan *chan,
@@ -337,6 +354,13 @@ __dma_cap_set(enum dma_transaction_type tx_type, dma_cap_mask_t *dstp)
set_bit(tx_type, dstp->bits);
}
+#define dma_cap_clear(tx, mask) __dma_cap_clear((tx), &(mask))
+static inline void
+__dma_cap_clear(enum dma_transaction_type tx_type, dma_cap_mask_t *dstp)
+{
+ clear_bit(tx_type, dstp->bits);
+}
+
#define dma_cap_zero(mask) __dma_cap_zero(&(mask))
static inline void __dma_cap_zero(dma_cap_mask_t *dstp)
{
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index 2f342746895..e397dc342cd 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -34,6 +34,7 @@ struct dmar_drhd_unit {
u64 reg_base_addr; /* register base address*/
struct pci_dev **devices; /* target device array */
int devices_cnt; /* target device count */
+ u16 segment; /* PCI domain */
u8 ignored:1; /* ignore drhd */
u8 include_all:1;
struct intel_iommu *iommu;
@@ -44,6 +45,14 @@ extern struct list_head dmar_drhd_units;
#define for_each_drhd_unit(drhd) \
list_for_each_entry(drhd, &dmar_drhd_units, list)
+#define for_each_active_iommu(i, drhd) \
+ list_for_each_entry(drhd, &dmar_drhd_units, list) \
+ if (i=drhd->iommu, drhd->ignored) {} else
+
+#define for_each_iommu(i, drhd) \
+ list_for_each_entry(drhd, &dmar_drhd_units, list) \
+ if (i=drhd->iommu, 0) {} else
+
extern int dmar_table_init(void);
extern int dmar_dev_scope_init(void);
@@ -100,6 +109,8 @@ struct irte {
#ifdef CONFIG_INTR_REMAP
extern int intr_remapping_enabled;
extern int enable_intr_remapping(int);
+extern void disable_intr_remapping(void);
+extern int reenable_intr_remapping(int);
extern int get_irte(int irq, struct irte *entry);
extern int modify_irte(int irq, struct irte *irte_modified);
diff --git a/include/linux/ds1wm.h b/include/linux/ds1wm.h
deleted file mode 100644
index d3c65e48a2e..00000000000
--- a/include/linux/ds1wm.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* platform data for the DS1WM driver */
-
-struct ds1wm_platform_data {
- int bus_shift; /* number of shifts needed to calculate the
- * offset between DS1WM registers;
- * e.g. on h5xxx and h2200 this is 2
- * (registers aligned to 4-byte boundaries),
- * while on hx4700 this is 1 */
- int active_high;
- void (*enable)(struct platform_device *pdev);
- void (*disable)(struct platform_device *pdev);
-};
diff --git a/include/linux/dst.h b/include/linux/dst.h
new file mode 100644
index 00000000000..e26fed84b1a
--- /dev/null
+++ b/include/linux/dst.h
@@ -0,0 +1,587 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DST_H
+#define __DST_H
+
+#include <linux/types.h>
+#include <linux/connector.h>
+
+#define DST_NAMELEN 32
+#define DST_NAME "dst"
+
+enum {
+ /* Remove node with given id from storage */
+ DST_DEL_NODE = 0,
+ /* Add remote node with given id to the storage */
+ DST_ADD_REMOTE,
+ /* Add local node with given id to the storage to be exported and used by remote peers */
+ DST_ADD_EXPORT,
+ /* Crypto initialization command (hash/cipher used to protect the connection) */
+ DST_CRYPTO,
+ /* Security attributes for given connection (permissions for example) */
+ DST_SECURITY,
+ /* Register given node in the block layer subsystem */
+ DST_START,
+ DST_CMD_MAX
+};
+
+struct dst_ctl
+{
+ /* Storage name */
+ char name[DST_NAMELEN];
+ /* Command flags */
+ __u32 flags;
+ /* Command itself (see above) */
+ __u32 cmd;
+ /* Maximum number of pages per single request in this device */
+ __u32 max_pages;
+ /* Stale/error transaction scanning timeout in milliseconds */
+ __u32 trans_scan_timeout;
+ /* Maximum number of retry sends before completing transaction as broken */
+ __u32 trans_max_retries;
+ /* Storage size */
+ __u64 size;
+};
+
+/* Reply command carries completion status */
+struct dst_ctl_ack
+{
+ struct cn_msg msg;
+ int error;
+ int unused[3];
+};
+
+/*
+ * Unfortunaltely socket address structure is not exported to userspace
+ * and is redefined there.
+ */
+#define SADDR_MAX_DATA 128
+
+struct saddr {
+ /* address family, AF_xxx */
+ unsigned short sa_family;
+ /* 14 bytes of protocol address */
+ char sa_data[SADDR_MAX_DATA];
+ /* Number of bytes used in sa_data */
+ unsigned short sa_data_len;
+};
+
+/* Address structure */
+struct dst_network_ctl
+{
+ /* Socket type: datagram, stream...*/
+ unsigned int type;
+ /* Let me guess, is it a Jupiter diameter? */
+ unsigned int proto;
+ /* Peer's address */
+ struct saddr addr;
+};
+
+struct dst_crypto_ctl
+{
+ /* Cipher and hash names */
+ char cipher_algo[DST_NAMELEN];
+ char hash_algo[DST_NAMELEN];
+
+ /* Key sizes. Can be zero for digest for example */
+ unsigned int cipher_keysize, hash_keysize;
+ /* Alignment. Calculated by the DST itself. */
+ unsigned int crypto_attached_size;
+ /* Number of threads to perform crypto operations */
+ int thread_num;
+};
+
+/* Export security attributes have this bits checked in when client connects */
+#define DST_PERM_READ (1<<0)
+#define DST_PERM_WRITE (1<<1)
+
+/*
+ * Right now it is simple model, where each remote address
+ * is assigned to set of permissions it is allowed to perform.
+ * In real world block device does not know anything but
+ * reading and writing, so it should be more than enough.
+ */
+struct dst_secure_user
+{
+ unsigned int permissions;
+ struct saddr addr;
+};
+
+/*
+ * Export control command: device to export and network address to accept
+ * clients to work with given device
+ */
+struct dst_export_ctl
+{
+ char device[DST_NAMELEN];
+ struct dst_network_ctl ctl;
+};
+
+enum {
+ DST_CFG = 1, /* Request remote configuration */
+ DST_IO, /* IO command */
+ DST_IO_RESPONSE, /* IO response */
+ DST_PING, /* Keepalive message */
+ DST_NCMD_MAX,
+};
+
+struct dst_cmd
+{
+ /* Network command itself, see above */
+ __u32 cmd;
+ /*
+ * Size of the attached data
+ * (in most cases, for READ command it means how many bytes were requested)
+ */
+ __u32 size;
+ /* Crypto size: number of attached bytes with digest/hmac */
+ __u32 csize;
+ /* Here we can carry secret data */
+ __u32 reserved;
+ /* Read/write bits, see how they are encoded in bio structure */
+ __u64 rw;
+ /* BIO flags */
+ __u64 flags;
+ /* Unique command id (like transaction ID) */
+ __u64 id;
+ /* Sector to start IO from */
+ __u64 sector;
+ /* Hash data is placed after this header */
+ __u8 hash[0];
+};
+
+/*
+ * Convert command to/from network byte order.
+ * We do not use hton*() functions, since there is
+ * no 64-bit implementation.
+ */
+static inline void dst_convert_cmd(struct dst_cmd *c)
+{
+ c->cmd = __cpu_to_be32(c->cmd);
+ c->csize = __cpu_to_be32(c->csize);
+ c->size = __cpu_to_be32(c->size);
+ c->sector = __cpu_to_be64(c->sector);
+ c->id = __cpu_to_be64(c->id);
+ c->flags = __cpu_to_be64(c->flags);
+ c->rw = __cpu_to_be64(c->rw);
+}
+
+/* Transaction id */
+typedef __u64 dst_gen_t;
+
+#ifdef __KERNEL__
+
+#include <linux/blkdev.h>
+#include <linux/bio.h>
+#include <linux/device.h>
+#include <linux/mempool.h>
+#include <linux/net.h>
+#include <linux/poll.h>
+#include <linux/rbtree.h>
+
+#ifdef CONFIG_DST_DEBUG
+#define dprintk(f, a...) printk(KERN_NOTICE f, ##a)
+#else
+static inline void __attribute__ ((format (printf, 1, 2)))
+ dprintk(const char *fmt, ...) {}
+#endif
+
+struct dst_node;
+
+struct dst_trans
+{
+ /* DST node we are working with */
+ struct dst_node *n;
+
+ /* Entry inside transaction tree */
+ struct rb_node trans_entry;
+
+ /* Merlin kills this transaction when this memory cell equals zero */
+ atomic_t refcnt;
+
+ /* How this transaction should be processed by crypto engine */
+ short enc;
+ /* How many times this transaction was resent */
+ short retries;
+ /* Completion status */
+ int error;
+
+ /* When did we send it to the remote peer */
+ long send_time;
+
+ /* My name is...
+ * Well, computers does not speak, they have unique id instead */
+ dst_gen_t gen;
+
+ /* Block IO we are working with */
+ struct bio *bio;
+
+ /* Network command for above block IO request */
+ struct dst_cmd cmd;
+};
+
+struct dst_crypto_engine
+{
+ /* What should we do with all block requests */
+ struct crypto_hash *hash;
+ struct crypto_ablkcipher *cipher;
+
+ /* Pool of pages used to encrypt data into before sending */
+ int page_num;
+ struct page **pages;
+
+ /* What to do with current request */
+ int enc;
+ /* Who we are and where do we go */
+ struct scatterlist *src, *dst;
+
+ /* Maximum timeout waiting for encryption to be completed */
+ long timeout;
+ /* IV is a 64-bit sequential counter */
+ u64 iv;
+
+ /* Secret data */
+ void *private;
+
+ /* Cached temporary data lives here */
+ int size;
+ void *data;
+};
+
+struct dst_state
+{
+ /* The main state protection */
+ struct mutex state_lock;
+
+ /* Polling machinery for sockets */
+ wait_queue_t wait;
+ wait_queue_head_t *whead;
+ /* Most of events are being waited here */
+ wait_queue_head_t thread_wait;
+
+ /* Who owns this? */
+ struct dst_node *node;
+
+ /* Network address for this state */
+ struct dst_network_ctl ctl;
+
+ /* Permissions to work with: read-only or rw connection */
+ u32 permissions;
+
+ /* Called when we need to clean private data */
+ void (* cleanup)(struct dst_state *st);
+
+ /* Used by the server: BIO completion queues BIOs here */
+ struct list_head request_list;
+ spinlock_t request_lock;
+
+ /* Guess what? No, it is not number of planets */
+ atomic_t refcnt;
+
+ /* This flags is set when connection should be dropped */
+ int need_exit;
+
+ /*
+ * Socket to work with. Second pointer is used for
+ * lockless check if socket was changed before performing
+ * next action (like working with cached polling result)
+ */
+ struct socket *socket, *read_socket;
+
+ /* Cached preallocated data */
+ void *data;
+ unsigned int size;
+
+ /* Currently processed command */
+ struct dst_cmd cmd;
+};
+
+struct dst_info
+{
+ /* Device size */
+ u64 size;
+
+ /* Local device name for export devices */
+ char local[DST_NAMELEN];
+
+ /* Network setup */
+ struct dst_network_ctl net;
+
+ /* Sysfs bits use this */
+ struct device device;
+};
+
+struct dst_node
+{
+ struct list_head node_entry;
+
+ /* Hi, my name is stored here */
+ char name[DST_NAMELEN];
+ /* My cache name is stored here */
+ char cache_name[DST_NAMELEN];
+
+ /* Block device attached to given node.
+ * Only valid for exporting nodes */
+ struct block_device *bdev;
+ /* Network state machine for given peer */
+ struct dst_state *state;
+
+ /* Block IO machinery */
+ struct request_queue *queue;
+ struct gendisk *disk;
+
+ /* Number of threads in processing pool */
+ int thread_num;
+ /* Maximum number of pages in single IO */
+ int max_pages;
+
+ /* I'm that big in bytes */
+ loff_t size;
+
+ /* Exported to userspace node information */
+ struct dst_info *info;
+
+ /*
+ * Security attribute list.
+ * Used only by exporting node currently.
+ */
+ struct list_head security_list;
+ struct mutex security_lock;
+
+ /*
+ * When this unerflows below zero, university collapses.
+ * But this will not happen, since node will be freed,
+ * when reference counter reaches zero.
+ */
+ atomic_t refcnt;
+
+ /* How precisely should I be started? */
+ int (*start)(struct dst_node *);
+
+ /* Crypto capabilities */
+ struct dst_crypto_ctl crypto;
+ u8 *hash_key;
+ u8 *cipher_key;
+
+ /* Pool of processing thread */
+ struct thread_pool *pool;
+
+ /* Transaction IDs live here */
+ atomic_long_t gen;
+
+ /*
+ * How frequently and how many times transaction
+ * tree should be scanned to drop stale objects.
+ */
+ long trans_scan_timeout;
+ int trans_max_retries;
+
+ /* Small gnomes live here */
+ struct rb_root trans_root;
+ struct mutex trans_lock;
+
+ /*
+ * Transaction cache/memory pool.
+ * It is big enough to contain not only transaction
+ * itself, but additional crypto data (digest/hmac).
+ */
+ struct kmem_cache *trans_cache;
+ mempool_t *trans_pool;
+
+ /* This entity scans transaction tree */
+ struct delayed_work trans_work;
+
+ wait_queue_head_t wait;
+};
+
+/* Kernel representation of the security attribute */
+struct dst_secure
+{
+ struct list_head sec_entry;
+ struct dst_secure_user sec;
+};
+
+int dst_process_bio(struct dst_node *n, struct bio *bio);
+
+int dst_node_init_connected(struct dst_node *n, struct dst_network_ctl *r);
+int dst_node_init_listened(struct dst_node *n, struct dst_export_ctl *le);
+
+static inline struct dst_state *dst_state_get(struct dst_state *st)
+{
+ BUG_ON(atomic_read(&st->refcnt) == 0);
+ atomic_inc(&st->refcnt);
+ return st;
+}
+
+void dst_state_put(struct dst_state *st);
+
+struct dst_state *dst_state_alloc(struct dst_node *n);
+int dst_state_socket_create(struct dst_state *st);
+void dst_state_socket_release(struct dst_state *st);
+
+void dst_state_exit_connected(struct dst_state *st);
+
+int dst_state_schedule_receiver(struct dst_state *st);
+
+void dst_dump_addr(struct socket *sk, struct sockaddr *sa, char *str);
+
+static inline void dst_state_lock(struct dst_state *st)
+{
+ mutex_lock(&st->state_lock);
+}
+
+static inline void dst_state_unlock(struct dst_state *st)
+{
+ mutex_unlock(&st->state_lock);
+}
+
+void dst_poll_exit(struct dst_state *st);
+int dst_poll_init(struct dst_state *st);
+
+static inline unsigned int dst_state_poll(struct dst_state *st)
+{
+ unsigned int revents = POLLHUP | POLLERR;
+
+ dst_state_lock(st);
+ if (st->socket)
+ revents = st->socket->ops->poll(NULL, st->socket, NULL);
+ dst_state_unlock(st);
+
+ return revents;
+}
+
+static inline int dst_thread_setup(void *private, void *data)
+{
+ return 0;
+}
+
+void dst_node_put(struct dst_node *n);
+
+static inline struct dst_node *dst_node_get(struct dst_node *n)
+{
+ atomic_inc(&n->refcnt);
+ return n;
+}
+
+int dst_data_recv(struct dst_state *st, void *data, unsigned int size);
+int dst_recv_cdata(struct dst_state *st, void *cdata);
+int dst_data_send_header(struct socket *sock,
+ void *data, unsigned int size, int more);
+
+int dst_send_bio(struct dst_state *st, struct dst_cmd *cmd, struct bio *bio);
+
+int dst_process_io(struct dst_state *st);
+int dst_export_crypto(struct dst_node *n, struct bio *bio);
+int dst_export_send_bio(struct bio *bio);
+int dst_start_export(struct dst_node *n);
+
+int __init dst_export_init(void);
+void dst_export_exit(void);
+
+/* Private structure for export block IO requests */
+struct dst_export_priv
+{
+ struct list_head request_entry;
+ struct dst_state *state;
+ struct bio *bio;
+ struct dst_cmd cmd;
+};
+
+static inline void dst_trans_get(struct dst_trans *t)
+{
+ atomic_inc(&t->refcnt);
+}
+
+struct dst_trans *dst_trans_search(struct dst_node *node, dst_gen_t gen);
+int dst_trans_remove(struct dst_trans *t);
+int dst_trans_remove_nolock(struct dst_trans *t);
+void dst_trans_put(struct dst_trans *t);
+
+/*
+ * Convert bio into network command.
+ */
+static inline void dst_bio_to_cmd(struct bio *bio, struct dst_cmd *cmd,
+ u32 command, u64 id)
+{
+ cmd->cmd = command;
+ cmd->flags = (bio->bi_flags << BIO_POOL_BITS) >> BIO_POOL_BITS;
+ cmd->rw = bio->bi_rw;
+ cmd->size = bio->bi_size;
+ cmd->csize = 0;
+ cmd->id = id;
+ cmd->sector = bio->bi_sector;
+};
+
+int dst_trans_send(struct dst_trans *t);
+int dst_trans_crypto(struct dst_trans *t);
+
+int dst_node_crypto_init(struct dst_node *n, struct dst_crypto_ctl *ctl);
+void dst_node_crypto_exit(struct dst_node *n);
+
+static inline int dst_need_crypto(struct dst_node *n)
+{
+ struct dst_crypto_ctl *c = &n->crypto;
+ /*
+ * Logical OR is appropriate here, but boolean one produces
+ * more optimal code, so it is used instead.
+ */
+ return (c->hash_algo[0] | c->cipher_algo[0]);
+}
+
+int dst_node_trans_init(struct dst_node *n, unsigned int size);
+void dst_node_trans_exit(struct dst_node *n);
+
+/*
+ * Pool of threads.
+ * Ready list contains threads currently free to be used,
+ * active one contains threads with some work scheduled for them.
+ * Caller can wait in given queue when thread is ready.
+ */
+struct thread_pool
+{
+ int thread_num;
+ struct mutex thread_lock;
+ struct list_head ready_list, active_list;
+
+ wait_queue_head_t wait;
+};
+
+void thread_pool_del_worker(struct thread_pool *p);
+void thread_pool_del_worker_id(struct thread_pool *p, unsigned int id);
+int thread_pool_add_worker(struct thread_pool *p,
+ char *name,
+ unsigned int id,
+ void *(* init)(void *data),
+ void (* cleanup)(void *data),
+ void *data);
+
+void thread_pool_destroy(struct thread_pool *p);
+struct thread_pool *thread_pool_create(int num, char *name,
+ void *(* init)(void *data),
+ void (* cleanup)(void *data),
+ void *data);
+
+int thread_pool_schedule(struct thread_pool *p,
+ int (* setup)(void *stored_private, void *setup_data),
+ int (* action)(void *stored_private, void *setup_data),
+ void *setup_data, long timeout);
+int thread_pool_schedule_private(struct thread_pool *p,
+ int (* setup)(void *private, void *data),
+ int (* action)(void *private, void *data),
+ void *data, long timeout, void *id);
+
+#endif /* __KERNEL__ */
+#endif /* __DST_H */
diff --git a/include/linux/dw_dmac.h b/include/linux/dw_dmac.h
index d797dde247f..c8aad713a04 100644
--- a/include/linux/dw_dmac.h
+++ b/include/linux/dw_dmac.h
@@ -74,4 +74,23 @@ struct dw_dma_slave {
#define DWC_CFGL_HS_DST_POL (1 << 18) /* dst handshake active low */
#define DWC_CFGL_HS_SRC_POL (1 << 19) /* src handshake active low */
+/* DMA API extensions */
+struct dw_cyclic_desc {
+ struct dw_desc **desc;
+ unsigned long periods;
+ void (*period_callback)(void *param);
+ void *period_callback_param;
+};
+
+struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
+ dma_addr_t buf_addr, size_t buf_len, size_t period_len,
+ enum dma_data_direction direction);
+void dw_dma_cyclic_free(struct dma_chan *chan);
+int dw_dma_cyclic_start(struct dma_chan *chan);
+void dw_dma_cyclic_stop(struct dma_chan *chan);
+
+dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan);
+
+dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan);
+
#endif /* DW_DMAC_H */
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 7a204256b15..c59b769f62b 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -116,6 +116,7 @@ extern void elv_abort_queue(struct request_queue *);
extern void elv_completed_request(struct request_queue *, struct request *);
extern int elv_set_request(struct request_queue *, struct request *, gfp_t);
extern void elv_put_request(struct request_queue *, struct request *);
+extern void elv_drain_elevator(struct request_queue *);
/*
* io scheduler registration
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index e263acaa405..634a5e5aba3 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -208,6 +208,7 @@ static inline __u32 ext3_mask_flags(umode_t mode, __u32 flags)
#define EXT3_STATE_JDATA 0x00000001 /* journaled data exists */
#define EXT3_STATE_NEW 0x00000002 /* inode is newly created */
#define EXT3_STATE_XATTR 0x00000004 /* has in-inode xattrs */
+#define EXT3_STATE_FLUSH_ON_CLOSE 0x00000008
/* Used to pass group descriptor data when online resize is done */
struct ext3_new_group_input {
diff --git a/include/linux/fb.h b/include/linux/fb.h
index f563c501393..330c4b1bfca 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -173,8 +173,12 @@ struct fb_fix_screeninfo {
/* Interpretation of offset for color fields: All offsets are from the right,
* inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
* can use the offset as right argument to <<). A pixel afterwards is a bit
- * stream and is written to video memory as that unmodified. This implies
- * big-endian byte order if bits_per_pixel is greater than 8.
+ * stream and is written to video memory as that unmodified.
+ *
+ * For pseudocolor: offset and length should be the same for all color
+ * components. Offset specifies the position of the least significant bit
+ * of the pallette index in a pixel value. Length indicates the number
+ * of available palette entries (i.e. # of entries = 1 << length).
*/
struct fb_bitfield {
__u32 offset; /* beginning of bitfield */
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index 09d6c5bbddd..a2ec74bc481 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -5,12 +5,14 @@
#ifndef __LINUX_FDTABLE_H
#define __LINUX_FDTABLE_H
-#include <asm/atomic.h>
#include <linux/posix_types.h>
#include <linux/compiler.h>
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
#include <linux/types.h>
+#include <linux/init.h>
+
+#include <asm/atomic.h>
/*
* The default fd array needs to be at least BITS_PER_LONG,
diff --git a/include/linux/fiemap.h b/include/linux/fiemap.h
index 671decbd2ae..934e22d6580 100644
--- a/include/linux/fiemap.h
+++ b/include/linux/fiemap.h
@@ -11,6 +11,8 @@
#ifndef _LINUX_FIEMAP_H
#define _LINUX_FIEMAP_H
+#include <linux/types.h>
+
struct fiemap_extent {
__u64 fe_logical; /* logical offset in bytes for the start of
* the extent from the beginning of the file */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a09e17c8f5f..562d2855cf3 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -95,8 +95,12 @@ struct inodes_stat_t {
#define SWRITE 3 /* for ll_rw_block() - wait for buffer lock */
#define READ_SYNC (READ | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG))
#define READ_META (READ | (1 << BIO_RW_META))
-#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG))
-#define SWRITE_SYNC (SWRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG))
+#define WRITE_SYNC_PLUG (WRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_NOIDLE))
+#define WRITE_SYNC (WRITE_SYNC_PLUG | (1 << BIO_RW_UNPLUG))
+#define WRITE_ODIRECT (WRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG))
+#define SWRITE_SYNC_PLUG \
+ (SWRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_NOIDLE))
+#define SWRITE_SYNC (SWRITE_SYNC_PLUG | (1 << BIO_RW_UNPLUG))
#define WRITE_BARRIER (WRITE | (1 << BIO_RW_BARRIER))
#define DISCARD_NOBARRIER (1 << BIO_RW_DISCARD)
#define DISCARD_BARRIER ((1 << BIO_RW_DISCARD) | (1 << BIO_RW_BARRIER))
@@ -1695,6 +1699,9 @@ struct file_system_type {
struct lock_class_key i_alloc_sem_key;
};
+extern int get_sb_ns(struct file_system_type *fs_type, int flags, void *data,
+ int (*fill_super)(struct super_block *, void *, int),
+ struct vfsmount *mnt);
extern int get_sb_bdev(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data,
int (*fill_super)(struct super_block *, void *, int),
@@ -2337,19 +2344,7 @@ ssize_t simple_transaction_read(struct file *file, char __user *buf,
size_t size, loff_t *pos);
int simple_transaction_release(struct inode *inode, struct file *file);
-static inline void simple_transaction_set(struct file *file, size_t n)
-{
- struct simple_transaction_argresp *ar = file->private_data;
-
- BUG_ON(n > SIMPLE_TRANSACTION_LIMIT);
-
- /*
- * The barrier ensures that ar->size will really remain zero until
- * ar->data is ready for reading.
- */
- smp_mb();
- ar->size = n;
-}
+void simple_transaction_set(struct file *file, size_t n);
/*
* simple attribute files
@@ -2396,27 +2391,6 @@ ssize_t simple_attr_read(struct file *file, char __user *buf,
ssize_t simple_attr_write(struct file *file, const char __user *buf,
size_t len, loff_t *ppos);
-
-#ifdef CONFIG_SECURITY
-static inline char *alloc_secdata(void)
-{
- return (char *)get_zeroed_page(GFP_KERNEL);
-}
-
-static inline void free_secdata(void *secdata)
-{
- free_page((unsigned long)secdata);
-}
-#else
-static inline char *alloc_secdata(void)
-{
- return (char *)1;
-}
-
-static inline void free_secdata(void *secdata)
-{ }
-#endif /* CONFIG_SECURITY */
-
struct ctl_table;
int proc_nr_files(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos);
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
new file mode 100644
index 00000000000..84d3532dd3e
--- /dev/null
+++ b/include/linux/fscache-cache.h
@@ -0,0 +1,505 @@
+/* General filesystem caching backing cache interface
+ *
+ * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * NOTE!!! See:
+ *
+ * Documentation/filesystems/caching/backend-api.txt
+ *
+ * for a description of the cache backend interface declared here.
+ */
+
+#ifndef _LINUX_FSCACHE_CACHE_H
+#define _LINUX_FSCACHE_CACHE_H
+
+#include <linux/fscache.h>
+#include <linux/sched.h>
+#include <linux/slow-work.h>
+
+#define NR_MAXCACHES BITS_PER_LONG
+
+struct fscache_cache;
+struct fscache_cache_ops;
+struct fscache_object;
+struct fscache_operation;
+
+/*
+ * cache tag definition
+ */
+struct fscache_cache_tag {
+ struct list_head link;
+ struct fscache_cache *cache; /* cache referred to by this tag */
+ unsigned long flags;
+#define FSCACHE_TAG_RESERVED 0 /* T if tag is reserved for a cache */
+ atomic_t usage;
+ char name[0]; /* tag name */
+};
+
+/*
+ * cache definition
+ */
+struct fscache_cache {
+ const struct fscache_cache_ops *ops;
+ struct fscache_cache_tag *tag; /* tag representing this cache */
+ struct kobject *kobj; /* system representation of this cache */
+ struct list_head link; /* link in list of caches */
+ size_t max_index_size; /* maximum size of index data */
+ char identifier[36]; /* cache label */
+
+ /* node management */
+ struct work_struct op_gc; /* operation garbage collector */
+ struct list_head object_list; /* list of data/index objects */
+ struct list_head op_gc_list; /* list of ops to be deleted */
+ spinlock_t object_list_lock;
+ spinlock_t op_gc_list_lock;
+ atomic_t object_count; /* no. of live objects in this cache */
+ struct fscache_object *fsdef; /* object for the fsdef index */
+ unsigned long flags;
+#define FSCACHE_IOERROR 0 /* cache stopped on I/O error */
+#define FSCACHE_CACHE_WITHDRAWN 1 /* cache has been withdrawn */
+};
+
+extern wait_queue_head_t fscache_cache_cleared_wq;
+
+/*
+ * operation to be applied to a cache object
+ * - retrieval initiation operations are done in the context of the process
+ * that issued them, and not in an async thread pool
+ */
+typedef void (*fscache_operation_release_t)(struct fscache_operation *op);
+typedef void (*fscache_operation_processor_t)(struct fscache_operation *op);
+
+struct fscache_operation {
+ union {
+ struct work_struct fast_work; /* record for fast ops */
+ struct slow_work slow_work; /* record for (very) slow ops */
+ };
+ struct list_head pend_link; /* link in object->pending_ops */
+ struct fscache_object *object; /* object to be operated upon */
+
+ unsigned long flags;
+#define FSCACHE_OP_TYPE 0x000f /* operation type */
+#define FSCACHE_OP_FAST 0x0001 /* - fast op, processor may not sleep for disk */
+#define FSCACHE_OP_SLOW 0x0002 /* - (very) slow op, processor may sleep for disk */
+#define FSCACHE_OP_MYTHREAD 0x0003 /* - processing is done be issuing thread, not pool */
+#define FSCACHE_OP_WAITING 4 /* cleared when op is woken */
+#define FSCACHE_OP_EXCLUSIVE 5 /* exclusive op, other ops must wait */
+#define FSCACHE_OP_DEAD 6 /* op is now dead */
+
+ atomic_t usage;
+ unsigned debug_id; /* debugging ID */
+
+ /* operation processor callback
+ * - can be NULL if FSCACHE_OP_WAITING is going to be used to perform
+ * the op in a non-pool thread */
+ fscache_operation_processor_t processor;
+
+ /* operation releaser */
+ fscache_operation_release_t release;
+};
+
+extern atomic_t fscache_op_debug_id;
+extern const struct slow_work_ops fscache_op_slow_work_ops;
+
+extern void fscache_enqueue_operation(struct fscache_operation *);
+extern void fscache_put_operation(struct fscache_operation *);
+
+/**
+ * fscache_operation_init - Do basic initialisation of an operation
+ * @op: The operation to initialise
+ * @release: The release function to assign
+ *
+ * Do basic initialisation of an operation. The caller must still set flags,
+ * object, either fast_work or slow_work if necessary, and processor if needed.
+ */
+static inline void fscache_operation_init(struct fscache_operation *op,
+ fscache_operation_release_t release)
+{
+ atomic_set(&op->usage, 1);
+ op->debug_id = atomic_inc_return(&fscache_op_debug_id);
+ op->release = release;
+ INIT_LIST_HEAD(&op->pend_link);
+}
+
+/**
+ * fscache_operation_init_slow - Do additional initialisation of a slow op
+ * @op: The operation to initialise
+ * @processor: The processor function to assign
+ *
+ * Do additional initialisation of an operation as required for slow work.
+ */
+static inline
+void fscache_operation_init_slow(struct fscache_operation *op,
+ fscache_operation_processor_t processor)
+{
+ op->processor = processor;
+ slow_work_init(&op->slow_work, &fscache_op_slow_work_ops);
+}
+
+/*
+ * data read operation
+ */
+struct fscache_retrieval {
+ struct fscache_operation op;
+ struct address_space *mapping; /* netfs pages */
+ fscache_rw_complete_t end_io_func; /* function to call on I/O completion */
+ void *context; /* netfs read context (pinned) */
+ struct list_head to_do; /* list of things to be done by the backend */
+ unsigned long start_time; /* time at which retrieval started */
+};
+
+typedef int (*fscache_page_retrieval_func_t)(struct fscache_retrieval *op,
+ struct page *page,
+ gfp_t gfp);
+
+typedef int (*fscache_pages_retrieval_func_t)(struct fscache_retrieval *op,
+ struct list_head *pages,
+ unsigned *nr_pages,
+ gfp_t gfp);
+
+/**
+ * fscache_get_retrieval - Get an extra reference on a retrieval operation
+ * @op: The retrieval operation to get a reference on
+ *
+ * Get an extra reference on a retrieval operation.
+ */
+static inline
+struct fscache_retrieval *fscache_get_retrieval(struct fscache_retrieval *op)
+{
+ atomic_inc(&op->op.usage);
+ return op;
+}
+
+/**
+ * fscache_enqueue_retrieval - Enqueue a retrieval operation for processing
+ * @op: The retrieval operation affected
+ *
+ * Enqueue a retrieval operation for processing by the FS-Cache thread pool.
+ */
+static inline void fscache_enqueue_retrieval(struct fscache_retrieval *op)
+{
+ fscache_enqueue_operation(&op->op);
+}
+
+/**
+ * fscache_put_retrieval - Drop a reference to a retrieval operation
+ * @op: The retrieval operation affected
+ *
+ * Drop a reference to a retrieval operation.
+ */
+static inline void fscache_put_retrieval(struct fscache_retrieval *op)
+{
+ fscache_put_operation(&op->op);
+}
+
+/*
+ * cached page storage work item
+ * - used to do three things:
+ * - batch writes to the cache
+ * - do cache writes asynchronously
+ * - defer writes until cache object lookup completion
+ */
+struct fscache_storage {
+ struct fscache_operation op;
+ pgoff_t store_limit; /* don't write more than this */
+};
+
+/*
+ * cache operations
+ */
+struct fscache_cache_ops {
+ /* name of cache provider */
+ const char *name;
+
+ /* allocate an object record for a cookie */
+ struct fscache_object *(*alloc_object)(struct fscache_cache *cache,
+ struct fscache_cookie *cookie);
+
+ /* look up the object for a cookie */
+ void (*lookup_object)(struct fscache_object *object);
+
+ /* finished looking up */
+ void (*lookup_complete)(struct fscache_object *object);
+
+ /* increment the usage count on this object (may fail if unmounting) */
+ struct fscache_object *(*grab_object)(struct fscache_object *object);
+
+ /* pin an object in the cache */
+ int (*pin_object)(struct fscache_object *object);
+
+ /* unpin an object in the cache */
+ void (*unpin_object)(struct fscache_object *object);
+
+ /* store the updated auxilliary data on an object */
+ void (*update_object)(struct fscache_object *object);
+
+ /* discard the resources pinned by an object and effect retirement if
+ * necessary */
+ void (*drop_object)(struct fscache_object *object);
+
+ /* dispose of a reference to an object */
+ void (*put_object)(struct fscache_object *object);
+
+ /* sync a cache */
+ void (*sync_cache)(struct fscache_cache *cache);
+
+ /* notification that the attributes of a non-index object (such as
+ * i_size) have changed */
+ int (*attr_changed)(struct fscache_object *object);
+
+ /* reserve space for an object's data and associated metadata */
+ int (*reserve_space)(struct fscache_object *object, loff_t i_size);
+
+ /* request a backing block for a page be read or allocated in the
+ * cache */
+ fscache_page_retrieval_func_t read_or_alloc_page;
+
+ /* request backing blocks for a list of pages be read or allocated in
+ * the cache */
+ fscache_pages_retrieval_func_t read_or_alloc_pages;
+
+ /* request a backing block for a page be allocated in the cache so that
+ * it can be written directly */
+ fscache_page_retrieval_func_t allocate_page;
+
+ /* request backing blocks for pages be allocated in the cache so that
+ * they can be written directly */
+ fscache_pages_retrieval_func_t allocate_pages;
+
+ /* write a page to its backing block in the cache */
+ int (*write_page)(struct fscache_storage *op, struct page *page);
+
+ /* detach backing block from a page (optional)
+ * - must release the cookie lock before returning
+ * - may sleep
+ */
+ void (*uncache_page)(struct fscache_object *object,
+ struct page *page);
+
+ /* dissociate a cache from all the pages it was backing */
+ void (*dissociate_pages)(struct fscache_cache *cache);
+};
+
+/*
+ * data file or index object cookie
+ * - a file will only appear in one cache
+ * - a request to cache a file may or may not be honoured, subject to
+ * constraints such as disk space
+ * - indices are created on disk just-in-time
+ */
+struct fscache_cookie {
+ atomic_t usage; /* number of users of this cookie */
+ atomic_t n_children; /* number of children of this cookie */
+ spinlock_t lock;
+ struct hlist_head backing_objects; /* object(s) backing this file/index */
+ const struct fscache_cookie_def *def; /* definition */
+ struct fscache_cookie *parent; /* parent of this entry */
+ void *netfs_data; /* back pointer to netfs */
+ struct radix_tree_root stores; /* pages to be stored on this cookie */
+#define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */
+
+ unsigned long flags;
+#define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */
+#define FSCACHE_COOKIE_CREATING 1 /* T if non-index object being created still */
+#define FSCACHE_COOKIE_NO_DATA_YET 2 /* T if new object with no cached data yet */
+#define FSCACHE_COOKIE_PENDING_FILL 3 /* T if pending initial fill on object */
+#define FSCACHE_COOKIE_FILLING 4 /* T if filling object incrementally */
+#define FSCACHE_COOKIE_UNAVAILABLE 5 /* T if cookie is unavailable (error, etc) */
+};
+
+extern struct fscache_cookie fscache_fsdef_index;
+
+/*
+ * on-disk cache file or index handle
+ */
+struct fscache_object {
+ enum fscache_object_state {
+ FSCACHE_OBJECT_INIT, /* object in initial unbound state */
+ FSCACHE_OBJECT_LOOKING_UP, /* looking up object */
+ FSCACHE_OBJECT_CREATING, /* creating object */
+
+ /* active states */
+ FSCACHE_OBJECT_AVAILABLE, /* cleaning up object after creation */
+ FSCACHE_OBJECT_ACTIVE, /* object is usable */
+ FSCACHE_OBJECT_UPDATING, /* object is updating */
+
+ /* terminal states */
+ FSCACHE_OBJECT_DYING, /* object waiting for accessors to finish */
+ FSCACHE_OBJECT_LC_DYING, /* object cleaning up after lookup/create */
+ FSCACHE_OBJECT_ABORT_INIT, /* abort the init state */
+ FSCACHE_OBJECT_RELEASING, /* releasing object */
+ FSCACHE_OBJECT_RECYCLING, /* retiring object */
+ FSCACHE_OBJECT_WITHDRAWING, /* withdrawing object */
+ FSCACHE_OBJECT_DEAD, /* object is now dead */
+ } state;
+
+ int debug_id; /* debugging ID */
+ int n_children; /* number of child objects */
+ int n_ops; /* number of ops outstanding on object */
+ int n_obj_ops; /* number of object ops outstanding on object */
+ int n_in_progress; /* number of ops in progress */
+ int n_exclusive; /* number of exclusive ops queued */
+ spinlock_t lock; /* state and operations lock */
+
+ unsigned long lookup_jif; /* time at which lookup started */
+ unsigned long event_mask; /* events this object is interested in */
+ unsigned long events; /* events to be processed by this object
+ * (order is important - using fls) */
+#define FSCACHE_OBJECT_EV_REQUEUE 0 /* T if object should be requeued */
+#define FSCACHE_OBJECT_EV_UPDATE 1 /* T if object should be updated */
+#define FSCACHE_OBJECT_EV_CLEARED 2 /* T if accessors all gone */
+#define FSCACHE_OBJECT_EV_ERROR 3 /* T if fatal error occurred during processing */
+#define FSCACHE_OBJECT_EV_RELEASE 4 /* T if netfs requested object release */
+#define FSCACHE_OBJECT_EV_RETIRE 5 /* T if netfs requested object retirement */
+#define FSCACHE_OBJECT_EV_WITHDRAW 6 /* T if cache requested object withdrawal */
+
+ unsigned long flags;
+#define FSCACHE_OBJECT_LOCK 0 /* T if object is busy being processed */
+#define FSCACHE_OBJECT_PENDING_WRITE 1 /* T if object has pending write */
+#define FSCACHE_OBJECT_WAITING 2 /* T if object is waiting on its parent */
+
+ struct list_head cache_link; /* link in cache->object_list */
+ struct hlist_node cookie_link; /* link in cookie->backing_objects */
+ struct fscache_cache *cache; /* cache that supplied this object */
+ struct fscache_cookie *cookie; /* netfs's file/index object */
+ struct fscache_object *parent; /* parent object */
+ struct slow_work work; /* attention scheduling record */
+ struct list_head dependents; /* FIFO of dependent objects */
+ struct list_head dep_link; /* link in parent's dependents list */
+ struct list_head pending_ops; /* unstarted operations on this object */
+ pgoff_t store_limit; /* current storage limit */
+};
+
+extern const char *fscache_object_states[];
+
+#define fscache_object_is_active(obj) \
+ (!test_bit(FSCACHE_IOERROR, &(obj)->cache->flags) && \
+ (obj)->state >= FSCACHE_OBJECT_AVAILABLE && \
+ (obj)->state < FSCACHE_OBJECT_DYING)
+
+extern const struct slow_work_ops fscache_object_slow_work_ops;
+
+/**
+ * fscache_object_init - Initialise a cache object description
+ * @object: Object description
+ *
+ * Initialise a cache object description to its basic values.
+ *
+ * See Documentation/filesystems/caching/backend-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_object_init(struct fscache_object *object,
+ struct fscache_cookie *cookie,
+ struct fscache_cache *cache)
+{
+ atomic_inc(&cache->object_count);
+
+ object->state = FSCACHE_OBJECT_INIT;
+ spin_lock_init(&object->lock);
+ INIT_LIST_HEAD(&object->cache_link);
+ INIT_HLIST_NODE(&object->cookie_link);
+ vslow_work_init(&object->work, &fscache_object_slow_work_ops);
+ INIT_LIST_HEAD(&object->dependents);
+ INIT_LIST_HEAD(&object->dep_link);
+ INIT_LIST_HEAD(&object->pending_ops);
+ object->n_children = 0;
+ object->n_ops = object->n_in_progress = object->n_exclusive = 0;
+ object->events = object->event_mask = 0;
+ object->flags = 0;
+ object->store_limit = 0;
+ object->cache = cache;
+ object->cookie = cookie;
+ object->parent = NULL;
+}
+
+extern void fscache_object_lookup_negative(struct fscache_object *object);
+extern void fscache_obtained_object(struct fscache_object *object);
+
+/**
+ * fscache_object_destroyed - Note destruction of an object in a cache
+ * @cache: The cache from which the object came
+ *
+ * Note the destruction and deallocation of an object record in a cache.
+ */
+static inline void fscache_object_destroyed(struct fscache_cache *cache)
+{
+ if (atomic_dec_and_test(&cache->object_count))
+ wake_up_all(&fscache_cache_cleared_wq);
+}
+
+/**
+ * fscache_object_lookup_error - Note an object encountered an error
+ * @object: The object on which the error was encountered
+ *
+ * Note that an object encountered a fatal error (usually an I/O error) and
+ * that it should be withdrawn as soon as possible.
+ */
+static inline void fscache_object_lookup_error(struct fscache_object *object)
+{
+ set_bit(FSCACHE_OBJECT_EV_ERROR, &object->events);
+}
+
+/**
+ * fscache_set_store_limit - Set the maximum size to be stored in an object
+ * @object: The object to set the maximum on
+ * @i_size: The limit to set in bytes
+ *
+ * Set the maximum size an object is permitted to reach, implying the highest
+ * byte that may be written. Intended to be called by the attr_changed() op.
+ *
+ * See Documentation/filesystems/caching/backend-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_set_store_limit(struct fscache_object *object, loff_t i_size)
+{
+ object->store_limit = i_size >> PAGE_SHIFT;
+ if (i_size & ~PAGE_MASK)
+ object->store_limit++;
+}
+
+/**
+ * fscache_end_io - End a retrieval operation on a page
+ * @op: The FS-Cache operation covering the retrieval
+ * @page: The page that was to be fetched
+ * @error: The error code (0 if successful)
+ *
+ * Note the end of an operation to retrieve a page, as covered by a particular
+ * operation record.
+ */
+static inline void fscache_end_io(struct fscache_retrieval *op,
+ struct page *page, int error)
+{
+ op->end_io_func(page, op->context, error);
+}
+
+/*
+ * out-of-line cache backend functions
+ */
+extern void fscache_init_cache(struct fscache_cache *cache,
+ const struct fscache_cache_ops *ops,
+ const char *idfmt,
+ ...) __attribute__ ((format (printf, 3, 4)));
+
+extern int fscache_add_cache(struct fscache_cache *cache,
+ struct fscache_object *fsdef,
+ const char *tagname);
+extern void fscache_withdraw_cache(struct fscache_cache *cache);
+
+extern void fscache_io_error(struct fscache_cache *cache);
+
+extern void fscache_mark_pages_cached(struct fscache_retrieval *op,
+ struct pagevec *pagevec);
+
+extern enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
+ const void *data,
+ uint16_t datalen);
+
+#endif /* _LINUX_FSCACHE_CACHE_H */
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
new file mode 100644
index 00000000000..6d8ee466e0a
--- /dev/null
+++ b/include/linux/fscache.h
@@ -0,0 +1,618 @@
+/* General filesystem caching interface
+ *
+ * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * NOTE!!! See:
+ *
+ * Documentation/filesystems/caching/netfs-api.txt
+ *
+ * for a description of the network filesystem interface declared here.
+ */
+
+#ifndef _LINUX_FSCACHE_H
+#define _LINUX_FSCACHE_H
+
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/pagemap.h>
+#include <linux/pagevec.h>
+
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+#define fscache_available() (1)
+#define fscache_cookie_valid(cookie) (cookie)
+#else
+#define fscache_available() (0)
+#define fscache_cookie_valid(cookie) (0)
+#endif
+
+
+/*
+ * overload PG_private_2 to give us PG_fscache - this is used to indicate that
+ * a page is currently backed by a local disk cache
+ */
+#define PageFsCache(page) PagePrivate2((page))
+#define SetPageFsCache(page) SetPagePrivate2((page))
+#define ClearPageFsCache(page) ClearPagePrivate2((page))
+#define TestSetPageFsCache(page) TestSetPagePrivate2((page))
+#define TestClearPageFsCache(page) TestClearPagePrivate2((page))
+
+/* pattern used to fill dead space in an index entry */
+#define FSCACHE_INDEX_DEADFILL_PATTERN 0x79
+
+struct pagevec;
+struct fscache_cache_tag;
+struct fscache_cookie;
+struct fscache_netfs;
+
+typedef void (*fscache_rw_complete_t)(struct page *page,
+ void *context,
+ int error);
+
+/* result of index entry consultation */
+enum fscache_checkaux {
+ FSCACHE_CHECKAUX_OKAY, /* entry okay as is */
+ FSCACHE_CHECKAUX_NEEDS_UPDATE, /* entry requires update */
+ FSCACHE_CHECKAUX_OBSOLETE, /* entry requires deletion */
+};
+
+/*
+ * fscache cookie definition
+ */
+struct fscache_cookie_def {
+ /* name of cookie type */
+ char name[16];
+
+ /* cookie type */
+ uint8_t type;
+#define FSCACHE_COOKIE_TYPE_INDEX 0
+#define FSCACHE_COOKIE_TYPE_DATAFILE 1
+
+ /* select the cache into which to insert an entry in this index
+ * - optional
+ * - should return a cache identifier or NULL to cause the cache to be
+ * inherited from the parent if possible or the first cache picked
+ * for a non-index file if not
+ */
+ struct fscache_cache_tag *(*select_cache)(
+ const void *parent_netfs_data,
+ const void *cookie_netfs_data);
+
+ /* get an index key
+ * - should store the key data in the buffer
+ * - should return the amount of amount stored
+ * - not permitted to return an error
+ * - the netfs data from the cookie being used as the source is
+ * presented
+ */
+ uint16_t (*get_key)(const void *cookie_netfs_data,
+ void *buffer,
+ uint16_t bufmax);
+
+ /* get certain file attributes from the netfs data
+ * - this function can be absent for an index
+ * - not permitted to return an error
+ * - the netfs data from the cookie being used as the source is
+ * presented
+ */
+ void (*get_attr)(const void *cookie_netfs_data, uint64_t *size);
+
+ /* get the auxilliary data from netfs data
+ * - this function can be absent if the index carries no state data
+ * - should store the auxilliary data in the buffer
+ * - should return the amount of amount stored
+ * - not permitted to return an error
+ * - the netfs data from the cookie being used as the source is
+ * presented
+ */
+ uint16_t (*get_aux)(const void *cookie_netfs_data,
+ void *buffer,
+ uint16_t bufmax);
+
+ /* consult the netfs about the state of an object
+ * - this function can be absent if the index carries no state data
+ * - the netfs data from the cookie being used as the target is
+ * presented, as is the auxilliary data
+ */
+ enum fscache_checkaux (*check_aux)(void *cookie_netfs_data,
+ const void *data,
+ uint16_t datalen);
+
+ /* get an extra reference on a read context
+ * - this function can be absent if the completion function doesn't
+ * require a context
+ */
+ void (*get_context)(void *cookie_netfs_data, void *context);
+
+ /* release an extra reference on a read context
+ * - this function can be absent if the completion function doesn't
+ * require a context
+ */
+ void (*put_context)(void *cookie_netfs_data, void *context);
+
+ /* indicate pages that now have cache metadata retained
+ * - this function should mark the specified pages as now being cached
+ * - the pages will have been marked with PG_fscache before this is
+ * called, so this is optional
+ */
+ void (*mark_pages_cached)(void *cookie_netfs_data,
+ struct address_space *mapping,
+ struct pagevec *cached_pvec);
+
+ /* indicate the cookie is no longer cached
+ * - this function is called when the backing store currently caching
+ * a cookie is removed
+ * - the netfs should use this to clean up any markers indicating
+ * cached pages
+ * - this is mandatory for any object that may have data
+ */
+ void (*now_uncached)(void *cookie_netfs_data);
+};
+
+/*
+ * fscache cached network filesystem type
+ * - name, version and ops must be filled in before registration
+ * - all other fields will be set during registration
+ */
+struct fscache_netfs {
+ uint32_t version; /* indexing version */
+ const char *name; /* filesystem name */
+ struct fscache_cookie *primary_index;
+ struct list_head link; /* internal link */
+};
+
+/*
+ * slow-path functions for when there is actually caching available, and the
+ * netfs does actually have a valid token
+ * - these are not to be called directly
+ * - these are undefined symbols when FS-Cache is not configured and the
+ * optimiser takes care of not using them
+ */
+extern int __fscache_register_netfs(struct fscache_netfs *);
+extern void __fscache_unregister_netfs(struct fscache_netfs *);
+extern struct fscache_cache_tag *__fscache_lookup_cache_tag(const char *);
+extern void __fscache_release_cache_tag(struct fscache_cache_tag *);
+
+extern struct fscache_cookie *__fscache_acquire_cookie(
+ struct fscache_cookie *,
+ const struct fscache_cookie_def *,
+ void *);
+extern void __fscache_relinquish_cookie(struct fscache_cookie *, int);
+extern void __fscache_update_cookie(struct fscache_cookie *);
+extern int __fscache_attr_changed(struct fscache_cookie *);
+extern int __fscache_read_or_alloc_page(struct fscache_cookie *,
+ struct page *,
+ fscache_rw_complete_t,
+ void *,
+ gfp_t);
+extern int __fscache_read_or_alloc_pages(struct fscache_cookie *,
+ struct address_space *,
+ struct list_head *,
+ unsigned *,
+ fscache_rw_complete_t,
+ void *,
+ gfp_t);
+extern int __fscache_alloc_page(struct fscache_cookie *, struct page *, gfp_t);
+extern int __fscache_write_page(struct fscache_cookie *, struct page *, gfp_t);
+extern void __fscache_uncache_page(struct fscache_cookie *, struct page *);
+extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *);
+extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *);
+
+/**
+ * fscache_register_netfs - Register a filesystem as desiring caching services
+ * @netfs: The description of the filesystem
+ *
+ * Register a filesystem as desiring caching services if they're available.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_register_netfs(struct fscache_netfs *netfs)
+{
+ if (fscache_available())
+ return __fscache_register_netfs(netfs);
+ else
+ return 0;
+}
+
+/**
+ * fscache_unregister_netfs - Indicate that a filesystem no longer desires
+ * caching services
+ * @netfs: The description of the filesystem
+ *
+ * Indicate that a filesystem no longer desires caching services for the
+ * moment.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_unregister_netfs(struct fscache_netfs *netfs)
+{
+ if (fscache_available())
+ __fscache_unregister_netfs(netfs);
+}
+
+/**
+ * fscache_lookup_cache_tag - Look up a cache tag
+ * @name: The name of the tag to search for
+ *
+ * Acquire a specific cache referral tag that can be used to select a specific
+ * cache in which to cache an index.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+struct fscache_cache_tag *fscache_lookup_cache_tag(const char *name)
+{
+ if (fscache_available())
+ return __fscache_lookup_cache_tag(name);
+ else
+ return NULL;
+}
+
+/**
+ * fscache_release_cache_tag - Release a cache tag
+ * @tag: The tag to release
+ *
+ * Release a reference to a cache referral tag previously looked up.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_release_cache_tag(struct fscache_cache_tag *tag)
+{
+ if (fscache_available())
+ __fscache_release_cache_tag(tag);
+}
+
+/**
+ * fscache_acquire_cookie - Acquire a cookie to represent a cache object
+ * @parent: The cookie that's to be the parent of this one
+ * @def: A description of the cache object, including callback operations
+ * @netfs_data: An arbitrary piece of data to be kept in the cookie to
+ * represent the cache object to the netfs
+ *
+ * This function is used to inform FS-Cache about part of an index hierarchy
+ * that can be used to locate files. This is done by requesting a cookie for
+ * each index in the path to the file.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+struct fscache_cookie *fscache_acquire_cookie(
+ struct fscache_cookie *parent,
+ const struct fscache_cookie_def *def,
+ void *netfs_data)
+{
+ if (fscache_cookie_valid(parent))
+ return __fscache_acquire_cookie(parent, def, netfs_data);
+ else
+ return NULL;
+}
+
+/**
+ * fscache_relinquish_cookie - Return the cookie to the cache, maybe discarding
+ * it
+ * @cookie: The cookie being returned
+ * @retire: True if the cache object the cookie represents is to be discarded
+ *
+ * This function returns a cookie to the cache, forcibly discarding the
+ * associated cache object if retire is set to true.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
+{
+ if (fscache_cookie_valid(cookie))
+ __fscache_relinquish_cookie(cookie, retire);
+}
+
+/**
+ * fscache_update_cookie - Request that a cache object be updated
+ * @cookie: The cookie representing the cache object
+ *
+ * Request an update of the index data for the cache object associated with the
+ * cookie.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_update_cookie(struct fscache_cookie *cookie)
+{
+ if (fscache_cookie_valid(cookie))
+ __fscache_update_cookie(cookie);
+}
+
+/**
+ * fscache_pin_cookie - Pin a data-storage cache object in its cache
+ * @cookie: The cookie representing the cache object
+ *
+ * Permit data-storage cache objects to be pinned in the cache.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_pin_cookie(struct fscache_cookie *cookie)
+{
+ return -ENOBUFS;
+}
+
+/**
+ * fscache_pin_cookie - Unpin a data-storage cache object in its cache
+ * @cookie: The cookie representing the cache object
+ *
+ * Permit data-storage cache objects to be unpinned from the cache.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_unpin_cookie(struct fscache_cookie *cookie)
+{
+}
+
+/**
+ * fscache_attr_changed - Notify cache that an object's attributes changed
+ * @cookie: The cookie representing the cache object
+ *
+ * Send a notification to the cache indicating that an object's attributes have
+ * changed. This includes the data size. These attributes will be obtained
+ * through the get_attr() cookie definition op.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_attr_changed(struct fscache_cookie *cookie)
+{
+ if (fscache_cookie_valid(cookie))
+ return __fscache_attr_changed(cookie);
+ else
+ return -ENOBUFS;
+}
+
+/**
+ * fscache_reserve_space - Reserve data space for a cached object
+ * @cookie: The cookie representing the cache object
+ * @i_size: The amount of space to be reserved
+ *
+ * Reserve an amount of space in the cache for the cache object attached to a
+ * cookie so that a write to that object within the space can always be
+ * honoured.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_reserve_space(struct fscache_cookie *cookie, loff_t size)
+{
+ return -ENOBUFS;
+}
+
+/**
+ * fscache_read_or_alloc_page - Read a page from the cache or allocate a block
+ * in which to store it
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page to fill if possible
+ * @end_io_func: The callback to invoke when and if the page is filled
+ * @context: An arbitrary piece of data to pass on to end_io_func()
+ * @gfp: The conditions under which memory allocation should be made
+ *
+ * Read a page from the cache, or if that's not possible make a potential
+ * one-block reservation in the cache into which the page may be stored once
+ * fetched from the server.
+ *
+ * If the page is not backed by the cache object, or if it there's some reason
+ * it can't be, -ENOBUFS will be returned and nothing more will be done for
+ * that page.
+ *
+ * Else, if that page is backed by the cache, a read will be initiated directly
+ * to the netfs's page and 0 will be returned by this function. The
+ * end_io_func() callback will be invoked when the operation terminates on a
+ * completion or failure. Note that the callback may be invoked before the
+ * return.
+ *
+ * Else, if the page is unbacked, -ENODATA is returned and a block may have
+ * been allocated in the cache.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_read_or_alloc_page(struct fscache_cookie *cookie,
+ struct page *page,
+ fscache_rw_complete_t end_io_func,
+ void *context,
+ gfp_t gfp)
+{
+ if (fscache_cookie_valid(cookie))
+ return __fscache_read_or_alloc_page(cookie, page, end_io_func,
+ context, gfp);
+ else
+ return -ENOBUFS;
+}
+
+/**
+ * fscache_read_or_alloc_pages - Read pages from the cache and/or allocate
+ * blocks in which to store them
+ * @cookie: The cookie representing the cache object
+ * @mapping: The netfs inode mapping to which the pages will be attached
+ * @pages: A list of potential netfs pages to be filled
+ * @end_io_func: The callback to invoke when and if each page is filled
+ * @context: An arbitrary piece of data to pass on to end_io_func()
+ * @gfp: The conditions under which memory allocation should be made
+ *
+ * Read a set of pages from the cache, or if that's not possible, attempt to
+ * make a potential one-block reservation for each page in the cache into which
+ * that page may be stored once fetched from the server.
+ *
+ * If some pages are not backed by the cache object, or if it there's some
+ * reason they can't be, -ENOBUFS will be returned and nothing more will be
+ * done for that pages.
+ *
+ * Else, if some of the pages are backed by the cache, a read will be initiated
+ * directly to the netfs's page and 0 will be returned by this function. The
+ * end_io_func() callback will be invoked when the operation terminates on a
+ * completion or failure. Note that the callback may be invoked before the
+ * return.
+ *
+ * Else, if a page is unbacked, -ENODATA is returned and a block may have
+ * been allocated in the cache.
+ *
+ * Because the function may want to return all of -ENOBUFS, -ENODATA and 0 in
+ * regard to different pages, the return values are prioritised in that order.
+ * Any pages submitted for reading are removed from the pages list.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
+ struct address_space *mapping,
+ struct list_head *pages,
+ unsigned *nr_pages,
+ fscache_rw_complete_t end_io_func,
+ void *context,
+ gfp_t gfp)
+{
+ if (fscache_cookie_valid(cookie))
+ return __fscache_read_or_alloc_pages(cookie, mapping, pages,
+ nr_pages, end_io_func,
+ context, gfp);
+ else
+ return -ENOBUFS;
+}
+
+/**
+ * fscache_alloc_page - Allocate a block in which to store a page
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page to allocate a page for
+ * @gfp: The conditions under which memory allocation should be made
+ *
+ * Request Allocation a block in the cache in which to store a netfs page
+ * without retrieving any contents from the cache.
+ *
+ * If the page is not backed by a file then -ENOBUFS will be returned and
+ * nothing more will be done, and no reservation will be made.
+ *
+ * Else, a block will be allocated if one wasn't already, and 0 will be
+ * returned
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_alloc_page(struct fscache_cookie *cookie,
+ struct page *page,
+ gfp_t gfp)
+{
+ if (fscache_cookie_valid(cookie))
+ return __fscache_alloc_page(cookie, page, gfp);
+ else
+ return -ENOBUFS;
+}
+
+/**
+ * fscache_write_page - Request storage of a page in the cache
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page to store
+ * @gfp: The conditions under which memory allocation should be made
+ *
+ * Request the contents of the netfs page be written into the cache. This
+ * request may be ignored if no cache block is currently allocated, in which
+ * case it will return -ENOBUFS.
+ *
+ * If a cache block was already allocated, a write will be initiated and 0 will
+ * be returned. The PG_fscache_write page bit is set immediately and will then
+ * be cleared at the completion of the write to indicate the success or failure
+ * of the operation. Note that the completion may happen before the return.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_write_page(struct fscache_cookie *cookie,
+ struct page *page,
+ gfp_t gfp)
+{
+ if (fscache_cookie_valid(cookie))
+ return __fscache_write_page(cookie, page, gfp);
+ else
+ return -ENOBUFS;
+}
+
+/**
+ * fscache_uncache_page - Indicate that caching is no longer required on a page
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page that was being cached.
+ *
+ * Tell the cache that we no longer want a page to be cached and that it should
+ * remove any knowledge of the netfs page it may have.
+ *
+ * Note that this cannot cancel any outstanding I/O operations between this
+ * page and the cache.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_uncache_page(struct fscache_cookie *cookie,
+ struct page *page)
+{
+ if (fscache_cookie_valid(cookie))
+ __fscache_uncache_page(cookie, page);
+}
+
+/**
+ * fscache_check_page_write - Ask if a page is being writing to the cache
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page that is being cached.
+ *
+ * Ask the cache if a page is being written to the cache.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+bool fscache_check_page_write(struct fscache_cookie *cookie,
+ struct page *page)
+{
+ if (fscache_cookie_valid(cookie))
+ return __fscache_check_page_write(cookie, page);
+ return false;
+}
+
+/**
+ * fscache_wait_on_page_write - Wait for a page to complete writing to the cache
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page that is being cached.
+ *
+ * Ask the cache to wake us up when a page is no longer being written to the
+ * cache.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_wait_on_page_write(struct fscache_cookie *cookie,
+ struct page *page)
+{
+ if (fscache_cookie_valid(cookie))
+ __fscache_wait_on_page_write(cookie, page);
+}
+
+#endif /* _LINUX_FSCACHE_H */
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 7ef1caf5026..f2a78b5e8b5 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -18,7 +18,6 @@
#define _FSL_DEVICE_H_
#include <linux/types.h>
-#include <linux/phy.h>
/*
* Some conventions on how we handle peripherals on Freescale chips
@@ -44,27 +43,6 @@
*
*/
-struct gianfar_platform_data {
- /* device specific information */
- u32 device_flags;
- char bus_id[BUS_ID_SIZE];
- phy_interface_t interface;
-};
-
-struct gianfar_mdio_data {
- /* board specific information */
- int irq[32];
-};
-
-/* Flags in gianfar_platform_data */
-#define FSL_GIANFAR_BRD_HAS_PHY_INTR 0x00000001 /* set or use a timer */
-#define FSL_GIANFAR_BRD_IS_REDUCED 0x00000002 /* Set if RGMII, RMII */
-
-struct fsl_i2c_platform_data {
- /* device specific information */
- u32 device_flags;
-};
-
/* Flags related to I2C device features */
#define FSL_I2C_DEV_SEPARATE_DFSRR 0x00000001
#define FSL_I2C_DEV_CLOCK_5200 0x00000002
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index a7f8134c594..8a0c2f221e6 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -1,15 +1,18 @@
#ifndef _LINUX_FTRACE_H
#define _LINUX_FTRACE_H
-#include <linux/linkage.h>
-#include <linux/fs.h>
-#include <linux/ktime.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/module.h>
+#include <linux/trace_clock.h>
#include <linux/kallsyms.h>
+#include <linux/linkage.h>
#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/ktime.h>
#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+
+#include <asm/ftrace.h>
#ifdef CONFIG_FUNCTION_TRACER
@@ -95,9 +98,41 @@ stack_trace_sysctl(struct ctl_table *table, int write,
loff_t *ppos);
#endif
+struct ftrace_func_command {
+ struct list_head list;
+ char *name;
+ int (*func)(char *func, char *cmd,
+ char *params, int enable);
+};
+
#ifdef CONFIG_DYNAMIC_FTRACE
-/* asm/ftrace.h must be defined for archs supporting dynamic ftrace */
-#include <asm/ftrace.h>
+
+int ftrace_arch_code_modify_prepare(void);
+int ftrace_arch_code_modify_post_process(void);
+
+struct seq_file;
+
+struct ftrace_probe_ops {
+ void (*func)(unsigned long ip,
+ unsigned long parent_ip,
+ void **data);
+ int (*callback)(unsigned long ip, void **data);
+ void (*free)(void **data);
+ int (*print)(struct seq_file *m,
+ unsigned long ip,
+ struct ftrace_probe_ops *ops,
+ void *data);
+};
+
+extern int
+register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
+ void *data);
+extern void
+unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
+ void *data);
+extern void
+unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops);
+extern void unregister_ftrace_function_probe_all(char *glob);
enum {
FTRACE_FL_FREE = (1 << 0),
@@ -110,15 +145,23 @@ enum {
};
struct dyn_ftrace {
- struct list_head list;
- unsigned long ip; /* address of mcount call-site */
- unsigned long flags;
- struct dyn_arch_ftrace arch;
+ union {
+ unsigned long ip; /* address of mcount call-site */
+ struct dyn_ftrace *freelist;
+ };
+ union {
+ unsigned long flags;
+ struct dyn_ftrace *newlist;
+ };
+ struct dyn_arch_ftrace arch;
};
int ftrace_force_update(void);
void ftrace_set_filter(unsigned char *buf, int len, int reset);
+int register_ftrace_command(struct ftrace_func_command *cmd);
+int unregister_ftrace_command(struct ftrace_func_command *cmd);
+
/* defined in arch */
extern int ftrace_ip_converted(unsigned long ip);
extern int ftrace_dyn_arch_init(void *data);
@@ -126,6 +169,10 @@ extern int ftrace_update_ftrace_func(ftrace_func_t func);
extern void ftrace_caller(void);
extern void ftrace_call(void);
extern void mcount_call(void);
+
+#ifndef FTRACE_ADDR
+#define FTRACE_ADDR ((unsigned long)ftrace_caller)
+#endif
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
extern void ftrace_graph_caller(void);
extern int ftrace_enable_ftrace_graph_caller(void);
@@ -136,7 +183,7 @@ static inline int ftrace_disable_ftrace_graph_caller(void) { return 0; }
#endif
/**
- * ftrace_make_nop - convert code into top
+ * ftrace_make_nop - convert code into nop
* @mod: module structure if called by module load initialization
* @rec: the mcount call site record
* @addr: the address that the call site should be calling
@@ -181,7 +228,6 @@ extern int ftrace_make_nop(struct module *mod,
*/
extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr);
-
/* May be defined in arch */
extern int ftrace_arch_read_dyn_info(char *buf, int size);
@@ -198,6 +244,14 @@ extern void ftrace_enable_daemon(void);
# define ftrace_disable_daemon() do { } while (0)
# define ftrace_enable_daemon() do { } while (0)
static inline void ftrace_release(void *start, unsigned long size) { }
+static inline int register_ftrace_command(struct ftrace_func_command *cmd)
+{
+ return -EINVAL;
+}
+static inline int unregister_ftrace_command(char *cmd_name)
+{
+ return -EINVAL;
+}
#endif /* CONFIG_DYNAMIC_FTRACE */
/* totally disable ftrace - can not re-enable after this */
@@ -233,24 +287,25 @@ static inline void __ftrace_enabled_restore(int enabled)
#endif
}
-#ifdef CONFIG_FRAME_POINTER
-/* TODO: need to fix this for ARM */
-# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
-# define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
-# define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
-# define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3))
-# define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4))
-# define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5))
-# define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6))
-#else
-# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
-# define CALLER_ADDR1 0UL
-# define CALLER_ADDR2 0UL
-# define CALLER_ADDR3 0UL
-# define CALLER_ADDR4 0UL
-# define CALLER_ADDR5 0UL
-# define CALLER_ADDR6 0UL
-#endif
+#ifndef HAVE_ARCH_CALLER_ADDR
+# ifdef CONFIG_FRAME_POINTER
+# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+# define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
+# define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
+# define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3))
+# define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4))
+# define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5))
+# define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6))
+# else
+# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+# define CALLER_ADDR1 0UL
+# define CALLER_ADDR2 0UL
+# define CALLER_ADDR3 0UL
+# define CALLER_ADDR4 0UL
+# define CALLER_ADDR5 0UL
+# define CALLER_ADDR6 0UL
+# endif
+#endif /* ifndef HAVE_ARCH_CALLER_ADDR */
#ifdef CONFIG_IRQSOFF_TRACER
extern void time_hardirqs_on(unsigned long a0, unsigned long a1);
@@ -268,54 +323,6 @@ static inline void __ftrace_enabled_restore(int enabled)
# define trace_preempt_off(a0, a1) do { } while (0)
#endif
-#ifdef CONFIG_TRACING
-extern int ftrace_dump_on_oops;
-
-extern void tracing_start(void);
-extern void tracing_stop(void);
-extern void ftrace_off_permanent(void);
-
-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, 2)));
-
-static inline void tracing_start(void) { }
-static inline void tracing_stop(void) { }
-static inline void ftrace_off_permanent(void) { }
-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(struct module *mod,
@@ -327,36 +334,6 @@ ftrace_init_module(struct module *mod,
unsigned long *start, unsigned long *end) { }
#endif
-enum {
- POWER_NONE = 0,
- POWER_CSTATE = 1,
- POWER_PSTATE = 2,
-};
-
-struct power_trace {
-#ifdef CONFIG_POWER_TRACER
- ktime_t stamp;
- ktime_t end;
- int type;
- int state;
-#endif
-};
-
-#ifdef CONFIG_POWER_TRACER
-extern void trace_power_start(struct power_trace *it, unsigned int type,
- unsigned int state);
-extern void trace_power_mark(struct power_trace *it, unsigned int type,
- unsigned int state);
-extern void trace_power_end(struct power_trace *it);
-#else
-static inline void trace_power_start(struct power_trace *it, unsigned int type,
- unsigned int state) { }
-static inline void trace_power_mark(struct power_trace *it, unsigned int type,
- unsigned int state) { }
-static inline void trace_power_end(struct power_trace *it) { }
-#endif
-
-
/*
* Structure that defines an entry function trace.
*/
@@ -379,6 +356,9 @@ struct ftrace_graph_ret {
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+/* for init task */
+#define INIT_FTRACE_GRAPH .ret_stack = NULL,
+
/*
* Stack of return addresses for functions
* of a thread.
@@ -398,8 +378,7 @@ struct ftrace_ret_stack {
extern void return_to_handler(void);
extern int
-ftrace_push_return_trace(unsigned long ret, unsigned long long time,
- unsigned long func, int *depth);
+ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth);
extern void
ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret);
@@ -454,10 +433,11 @@ static inline void unpause_graph_tracing(void)
{
atomic_dec(&current->tracing_graph_pause);
}
-#else
+#else /* !CONFIG_FUNCTION_GRAPH_TRACER */
#define __notrace_funcgraph
#define __irq_entry
+#define INIT_FTRACE_GRAPH
static inline void ftrace_graph_init_task(struct task_struct *t) { }
static inline void ftrace_graph_exit_task(struct task_struct *t) { }
@@ -469,7 +449,7 @@ static inline int task_curr_ret_stack(struct task_struct *tsk)
static inline void pause_graph_tracing(void) { }
static inline void unpause_graph_tracing(void) { }
-#endif
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
#ifdef CONFIG_TRACING
#include <linux/sched.h>
@@ -514,6 +494,21 @@ static inline int test_tsk_trace_graph(struct task_struct *tsk)
return tsk->trace & TSK_TRACE_FL_GRAPH;
}
+extern int ftrace_dump_on_oops;
+
#endif /* CONFIG_TRACING */
+
+#ifdef CONFIG_HW_BRANCH_TRACER
+
+void trace_hw_branch(u64 from, u64 to);
+void trace_hw_branch_oops(void);
+
+#else /* CONFIG_HW_BRANCH_TRACER */
+
+static inline void trace_hw_branch(u64 from, u64 to) {}
+static inline void trace_hw_branch_oops(void) {}
+
+#endif /* CONFIG_HW_BRANCH_TRACER */
+
#endif /* _LINUX_FTRACE_H */
diff --git a/include/linux/ftrace_irq.h b/include/linux/ftrace_irq.h
index 366a054d0b0..dca7bf8cffe 100644
--- a/include/linux/ftrace_irq.h
+++ b/include/linux/ftrace_irq.h
@@ -2,7 +2,7 @@
#define _LINUX_FTRACE_IRQ_H
-#if defined(CONFIG_DYNAMIC_FTRACE) || defined(CONFIG_FUNCTION_GRAPH_TRACER)
+#ifdef CONFIG_FTRACE_NMI_ENTER
extern void ftrace_nmi_enter(void);
extern void ftrace_nmi_exit(void);
#else
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index dd20cd78faa..0bbc15f5453 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -4,6 +4,7 @@
#include <linux/mmzone.h>
#include <linux/stddef.h>
#include <linux/linkage.h>
+#include <linux/topology.h>
struct vm_area_struct;
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index f83288347dd..45257475623 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -15,55 +15,61 @@
* - bits 0-7 are the preemption count (max preemption depth: 256)
* - bits 8-15 are the softirq count (max # of softirqs: 256)
*
- * The hardirq count can be overridden per architecture, the default is:
+ * The hardirq count can in theory reach the same as NR_IRQS.
+ * In reality, the number of nested IRQS is limited to the stack
+ * size as well. For archs with over 1000 IRQS it is not practical
+ * to expect that they will all nest. We give a max of 10 bits for
+ * hardirq nesting. An arch may choose to give less than 10 bits.
+ * m68k expects it to be 8.
*
- * - bits 16-27 are the hardirq count (max # of hardirqs: 4096)
- * - ( bit 28 is the PREEMPT_ACTIVE flag. )
+ * - bits 16-25 are the hardirq count (max # of nested hardirqs: 1024)
+ * - bit 26 is the NMI_MASK
+ * - bit 28 is the PREEMPT_ACTIVE flag
*
* PREEMPT_MASK: 0x000000ff
* SOFTIRQ_MASK: 0x0000ff00
- * HARDIRQ_MASK: 0x0fff0000
+ * HARDIRQ_MASK: 0x03ff0000
+ * NMI_MASK: 0x04000000
*/
#define PREEMPT_BITS 8
#define SOFTIRQ_BITS 8
+#define NMI_BITS 1
-#ifndef HARDIRQ_BITS
-#define HARDIRQ_BITS 12
+#define MAX_HARDIRQ_BITS 10
-#ifndef MAX_HARDIRQS_PER_CPU
-#define MAX_HARDIRQS_PER_CPU NR_IRQS
+#ifndef HARDIRQ_BITS
+# define HARDIRQ_BITS MAX_HARDIRQ_BITS
#endif
-/*
- * The hardirq mask has to be large enough to have space for potentially
- * all IRQ sources in the system nesting on a single CPU.
- */
-#if (1 << HARDIRQ_BITS) < MAX_HARDIRQS_PER_CPU
-# error HARDIRQ_BITS is too low!
-#endif
+#if HARDIRQ_BITS > MAX_HARDIRQ_BITS
+#error HARDIRQ_BITS too high!
#endif
#define PREEMPT_SHIFT 0
#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS)
#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS)
+#define NMI_SHIFT (HARDIRQ_SHIFT + HARDIRQ_BITS)
#define __IRQ_MASK(x) ((1UL << (x))-1)
#define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
#define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
#define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
+#define NMI_MASK (__IRQ_MASK(NMI_BITS) << NMI_SHIFT)
#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT)
#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT)
#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT)
+#define NMI_OFFSET (1UL << NMI_SHIFT)
-#if PREEMPT_ACTIVE < (1 << (HARDIRQ_SHIFT + HARDIRQ_BITS))
+#if PREEMPT_ACTIVE < (1 << (NMI_SHIFT + NMI_BITS))
#error PREEMPT_ACTIVE is too low!
#endif
#define hardirq_count() (preempt_count() & HARDIRQ_MASK)
#define softirq_count() (preempt_count() & SOFTIRQ_MASK)
-#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
+#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \
+ | NMI_MASK))
/*
* Are we doing bottom half or hardware interrupt processing?
@@ -73,6 +79,11 @@
#define in_softirq() (softirq_count())
#define in_interrupt() (irq_count())
+/*
+ * Are we in NMI context?
+ */
+#define in_nmi() (preempt_count() & NMI_MASK)
+
#if defined(CONFIG_PREEMPT)
# define PREEMPT_INATOMIC_BASE kernel_locked()
# define PREEMPT_CHECK_OFFSET 1
@@ -105,7 +116,7 @@
# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
#endif
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) || defined(CONFIG_GENERIC_HARDIRQS)
extern void synchronize_irq(unsigned int irq);
#else
# define synchronize_irq(irq) barrier()
@@ -164,20 +175,24 @@ extern void irq_enter(void);
*/
extern void irq_exit(void);
-#define nmi_enter() \
- do { \
- ftrace_nmi_enter(); \
- lockdep_off(); \
- rcu_nmi_enter(); \
- __irq_enter(); \
+#define nmi_enter() \
+ do { \
+ ftrace_nmi_enter(); \
+ BUG_ON(in_nmi()); \
+ add_preempt_count(NMI_OFFSET + HARDIRQ_OFFSET); \
+ lockdep_off(); \
+ rcu_nmi_enter(); \
+ trace_hardirq_enter(); \
} while (0)
-#define nmi_exit() \
- do { \
- __irq_exit(); \
- rcu_nmi_exit(); \
- lockdep_on(); \
- ftrace_nmi_exit(); \
+#define nmi_exit() \
+ do { \
+ trace_hardirq_exit(); \
+ rcu_nmi_exit(); \
+ lockdep_on(); \
+ BUG_ON(!in_nmi()); \
+ sub_preempt_count(NMI_OFFSET + HARDIRQ_OFFSET); \
+ ftrace_nmi_exit(); \
} while (0)
#endif /* LINUX_HARDIRQ_H */
diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h
index ed21bd3dbd2..29ee2873f4a 100644
--- a/include/linux/hdreg.h
+++ b/include/linux/hdreg.h
@@ -1,68 +1,6 @@
#ifndef _LINUX_HDREG_H
#define _LINUX_HDREG_H
-#ifdef __KERNEL__
-#include <linux/ata.h>
-
-/*
- * This file contains some defines for the AT-hd-controller.
- * Various sources.
- */
-
-/* ide.c has its own port definitions in "ide.h" */
-
-#define HD_IRQ 14
-
-/* Hd controller regs. Ref: IBM AT Bios-listing */
-#define HD_DATA 0x1f0 /* _CTL when writing */
-#define HD_ERROR 0x1f1 /* see err-bits */
-#define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */
-#define HD_SECTOR 0x1f3 /* starting sector */
-#define HD_LCYL 0x1f4 /* starting cylinder */
-#define HD_HCYL 0x1f5 /* high byte of starting cyl */
-#define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */
-#define HD_STATUS 0x1f7 /* see status-bits */
-#define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */
-#define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */
-#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */
-
-#define HD_CMD 0x3f6 /* used for resets */
-#define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */
-
-/* remainder is shared between hd.c, ide.c, ide-cd.c, and the hdparm utility */
-
-/* Bits of HD_STATUS */
-#define ERR_STAT 0x01
-#define INDEX_STAT 0x02
-#define ECC_STAT 0x04 /* Corrected error */
-#define DRQ_STAT 0x08
-#define SEEK_STAT 0x10
-#define SRV_STAT 0x10
-#define WRERR_STAT 0x20
-#define READY_STAT 0x40
-#define BUSY_STAT 0x80
-
-/* Bits for HD_ERROR */
-#define MARK_ERR 0x01 /* Bad address mark */
-#define ILI_ERR 0x01 /* Illegal Length Indication (ATAPI) */
-#define TRK0_ERR 0x02 /* couldn't find track 0 */
-#define EOM_ERR 0x02 /* End Of Media (ATAPI) */
-#define ABRT_ERR 0x04 /* Command aborted */
-#define MCR_ERR 0x08 /* media change request */
-#define ID_ERR 0x10 /* ID field not found */
-#define MC_ERR 0x20 /* media changed */
-#define ECC_ERR 0x40 /* Uncorrectable ECC error */
-#define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */
-#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */
-#define LFS_ERR 0xf0 /* Last Failed Sense (ATAPI) */
-
-/* Bits of HD_NSECTOR */
-#define CD 0x01
-#define IO 0x02
-#define REL 0x04
-#define TAG_MASK 0xf8
-#endif /* __KERNEL__ */
-
#include <linux/types.h>
/*
@@ -191,6 +129,7 @@ typedef struct hd_drive_hob_hdr {
#define TASKFILE_INVALID 0x7fff
#endif
+#ifndef __KERNEL__
/* ATA/ATAPI Commands pre T13 Spec */
#define WIN_NOP 0x00
/*
@@ -379,6 +318,7 @@ typedef struct hd_drive_hob_hdr {
#define SECURITY_ERASE_UNIT 0xBD
#define SECURITY_FREEZE_LOCK 0xBE
#define SECURITY_DISABLE_PASSWORD 0xBF
+#endif /* __KERNEL__ */
struct hd_geometry {
unsigned char heads;
@@ -448,6 +388,7 @@ enum {
#define __NEW_HD_DRIVE_ID
+#ifndef __KERNEL__
/*
* Structure returned by HDIO_GET_IDENTITY, as per ANSI NCITS ATA6 rev.1b spec.
*
@@ -699,6 +640,7 @@ struct hd_driveid {
* 7:0 Signature
*/
};
+#endif /* __KERNEL__ */
/*
* IDE "nice" flags. These are used on a per drive basis to determine
diff --git a/include/linux/hid.h b/include/linux/hid.h
index fa8ee9cef7b..a72876e4358 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -270,6 +270,7 @@ struct hid_item {
#define HID_QUIRK_INVERT 0x00000001
#define HID_QUIRK_NOTOUCH 0x00000002
+#define HID_QUIRK_IGNORE 0x00000004
#define HID_QUIRK_NOGET 0x00000008
#define HID_QUIRK_BADPAD 0x00000020
#define HID_QUIRK_MULTI_INPUT 0x00000040
@@ -603,12 +604,17 @@ struct hid_ll_driver {
int (*open)(struct hid_device *hdev);
void (*close)(struct hid_device *hdev);
+ int (*power)(struct hid_device *hdev, int level);
+
int (*hidinput_input_event) (struct input_dev *idev, unsigned int type,
unsigned int code, int value);
int (*parse)(struct hid_device *hdev);
};
+#define PM_HINT_FULLON 1<<5
+#define PM_HINT_NORMAL 1<<1
+
/* Applications from HID Usage Tables 4/8/99 Version 1.1 */
/* We ignore a few input applications that are not widely used */
#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || (a == 0x000d0002))
@@ -641,6 +647,7 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int
void hid_output_report(struct hid_report *report, __u8 *data);
struct hid_device *hid_allocate_device(void);
int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
+int hid_check_keys_pressed(struct hid_device *hid);
int hid_connect(struct hid_device *hid, unsigned int connect_mask);
/**
@@ -791,21 +798,5 @@ dbg_hid(const char *fmt, ...)
__FILE__ , ## arg)
#endif /* HID_FF */
-#ifdef __KERNEL__
-#ifdef CONFIG_HID_COMPAT
-#define HID_COMPAT_LOAD_DRIVER(name) \
-/* prototype to avoid sparse warning */ \
-extern void hid_compat_##name(void); \
-void hid_compat_##name(void) { } \
-EXPORT_SYMBOL(hid_compat_##name)
-#else
-#define HID_COMPAT_LOAD_DRIVER(name)
-#endif /* HID_COMPAT */
-#define HID_COMPAT_CALL_DRIVER(name) do { \
- extern void hid_compat_##name(void); \
- hid_compat_##name(); \
-} while (0)
-#endif /* __KERNEL__ */
-
#endif
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 7ff5c55f9b5..1fcb7126a01 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -19,8 +19,21 @@ static inline void flush_kernel_dcache_page(struct page *page)
}
#endif
-#ifdef CONFIG_HIGHMEM
+#include <asm/kmap_types.h>
+
+#if defined(CONFIG_DEBUG_HIGHMEM) && defined(CONFIG_TRACE_IRQFLAGS_SUPPORT)
+
+void debug_kmap_atomic(enum km_type type);
+
+#else
+static inline void debug_kmap_atomic(enum km_type type)
+{
+}
+
+#endif
+
+#ifdef CONFIG_HIGHMEM
#include <asm/highmem.h>
/* declarations for linux/mm/highmem.c */
@@ -44,8 +57,6 @@ static inline void *kmap(struct page *page)
#define kunmap(page) do { (void) (page); } while (0)
-#include <asm/kmap_types.h>
-
static inline void *kmap_atomic(struct page *page, enum km_type idx)
{
pagefault_disable();
@@ -187,16 +198,4 @@ static inline void copy_highpage(struct page *to, struct page *from)
kunmap_atomic(vto, KM_USER1);
}
-#if defined(CONFIG_DEBUG_HIGHMEM) && defined(CONFIG_TRACE_IRQFLAGS_SUPPORT)
-
-void debug_kmap_atomic(enum km_type type);
-
-#else
-
-static inline void debug_kmap_atomic(enum km_type type)
-{
-}
-
-#endif
-
#endif /* _LINUX_HIGHMEM_H */
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index bd37078c2d7..0d2f7c8a33d 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -336,6 +336,11 @@ extern int hrtimer_start(struct hrtimer *timer, ktime_t tim,
const enum hrtimer_mode mode);
extern int hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
unsigned long range_ns, const enum hrtimer_mode mode);
+extern int
+__hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
+ unsigned long delta_ns,
+ const enum hrtimer_mode mode, int wakeup);
+
extern int hrtimer_cancel(struct hrtimer *timer);
extern int hrtimer_try_to_cancel(struct hrtimer *timer);
diff --git a/include/linux/i2c-algo-sgi.h b/include/linux/i2c-algo-sgi.h
deleted file mode 100644
index 3b7715024e6..00000000000
--- a/include/linux/i2c-algo-sgi.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
- */
-
-#ifndef I2C_ALGO_SGI_H
-#define I2C_ALGO_SGI_H 1
-
-#include <linux/i2c.h>
-
-struct i2c_algo_sgi_data {
- void *data; /* private data for lowlevel routines */
- unsigned (*getctrl)(void *data);
- void (*setctrl)(void *data, unsigned val);
- unsigned (*rdata)(void *data);
- void (*wdata)(void *data, unsigned val);
-
- int xfer_timeout;
- int ack_timeout;
-};
-
-int i2c_sgi_add_bus(struct i2c_adapter *);
-
-#endif /* I2C_ALGO_SGI_H */
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index f27604af837..c9087de5c6c 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -33,47 +33,10 @@
#define I2C_DRIVERID_MSP3400 1
#define I2C_DRIVERID_TUNER 2
-#define I2C_DRIVERID_TEA6420 5 /* audio matrix switch */
-#define I2C_DRIVERID_TEA6415C 6 /* video matrix switch */
-#define I2C_DRIVERID_TDA9840 7 /* stereo sound processor */
-#define I2C_DRIVERID_SAA7111A 8 /* video input processor */
-#define I2C_DRIVERID_SAA7185B 13 /* video encoder */
-#define I2C_DRIVERID_SAA7110 22 /* video decoder */
-#define I2C_DRIVERID_SAA5249 24 /* SAA5249 and compatibles */
#define I2C_DRIVERID_TDA7432 27 /* Stereo sound processor */
#define I2C_DRIVERID_TVAUDIO 29 /* Generic TV sound driver */
-#define I2C_DRIVERID_TDA9875 32 /* TV sound decoder chip */
-#define I2C_DRIVERID_BT819 40 /* video decoder */
-#define I2C_DRIVERID_BT856 41 /* video encoder */
-#define I2C_DRIVERID_VPX3220 42 /* video decoder+vbi/vtxt */
-#define I2C_DRIVERID_ADV7175 48 /* ADV 7175/7176 video encoder */
-#define I2C_DRIVERID_SAA7114 49 /* video decoder */
-#define I2C_DRIVERID_ADV7170 54 /* video encoder */
-#define I2C_DRIVERID_SAA7191 57 /* video decoder */
-#define I2C_DRIVERID_INDYCAM 58 /* SGI IndyCam */
-#define I2C_DRIVERID_OVCAMCHIP 61 /* OmniVision CMOS image sens. */
-#define I2C_DRIVERID_SAA6752HS 67 /* MPEG2 encoder */
-#define I2C_DRIVERID_TVEEPROM 68 /* TV EEPROM */
-#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 /* saa7127 video encoder */
#define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */
#define I2C_DRIVERID_INFRARED 75 /* I2C InfraRed on Video boards */
-#define I2C_DRIVERID_TVP5150 76 /* TVP5150 video decoder */
-#define I2C_DRIVERID_WM8739 77 /* wm8739 audio processor */
-#define I2C_DRIVERID_UPD64083 78 /* upd64083 video processor */
-#define I2C_DRIVERID_UPD64031A 79 /* upd64031a video processor */
-#define I2C_DRIVERID_SAA717X 80 /* saa717x video encoder */
-#define I2C_DRIVERID_BT866 85 /* Conexant bt866 video encoder */
-#define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */
-#define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */
-#define I2C_DRIVERID_VP27SMPX 93 /* Panasonic VP27s tuner internal MPX */
-#define I2C_DRIVERID_M52790 95 /* Mitsubishi M52790SP/FP AV switch */
-#define I2C_DRIVERID_CS5345 96 /* cs5345 audio processor */
-#define I2C_DRIVERID_AU8522 97 /* Auvitek au8522 */
-
-#define I2C_DRIVERID_OV7670 1048 /* Omnivision 7670 camera */
/*
* ---- Adapter types ----------------------------------------------------
@@ -88,6 +51,7 @@
#define I2C_HW_B_CX2341X 0x010020 /* Conexant CX2341X MPEG encoder cards */
#define I2C_HW_B_CX23885 0x010022 /* conexant 23885 based tv cards (bus1) */
#define I2C_HW_B_AU0828 0x010023 /* auvitek au0828 usb bridge */
+#define I2C_HW_B_CX231XX 0x010024 /* Conexant CX231XX USB based cards */
#define I2C_HW_B_HDPVR 0x010025 /* Hauppauge HD PVR */
/* --- SGI adapters */
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index c86c3b07604..ad258059603 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -274,7 +274,7 @@ struct i2c_board_info {
* are provided using conventional syntax.
*/
#define I2C_BOARD_INFO(dev_type, dev_addr) \
- .type = (dev_type), .addr = (dev_addr)
+ .type = dev_type, .addr = (dev_addr)
/* Add-on boards should register/unregister their devices; e.g. a board
@@ -353,8 +353,8 @@ struct i2c_adapter {
void *algo_data;
/* --- administration stuff. */
- int (*client_register)(struct i2c_client *);
- int (*client_unregister)(struct i2c_client *);
+ int (*client_register)(struct i2c_client *) __deprecated;
+ int (*client_unregister)(struct i2c_client *) __deprecated;
/* data fields that are valid for all devices */
u8 level; /* nesting level for lockdep */
diff --git a/include/linux/i2c/s6000.h b/include/linux/i2c/s6000.h
new file mode 100644
index 00000000000..d9b34bfdae7
--- /dev/null
+++ b/include/linux/i2c/s6000.h
@@ -0,0 +1,10 @@
+#ifndef __LINUX_I2C_S6000_H
+#define __LINUX_I2C_S6000_H
+
+struct s6_i2c_platform_data {
+ const char *clock; /* the clock to use */
+ int bus_num; /* the bus number to register */
+};
+
+#endif
+
diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h
index 8137f660a5c..0dc80ef2497 100644
--- a/include/linux/i2c/twl4030.h
+++ b/include/linux/i2c/twl4030.h
@@ -218,6 +218,53 @@ int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
/*----------------------------------------------------------------------*/
+/* Power bus message definitions */
+
+#define DEV_GRP_NULL 0x0
+#define DEV_GRP_P1 0x1
+#define DEV_GRP_P2 0x2
+#define DEV_GRP_P3 0x4
+
+#define RES_GRP_RES 0x0
+#define RES_GRP_PP 0x1
+#define RES_GRP_RC 0x2
+#define RES_GRP_PP_RC 0x3
+#define RES_GRP_PR 0x4
+#define RES_GRP_PP_PR 0x5
+#define RES_GRP_RC_PR 0x6
+#define RES_GRP_ALL 0x7
+
+#define RES_TYPE2_R0 0x0
+
+#define RES_TYPE_ALL 0x7
+
+#define RES_STATE_WRST 0xF
+#define RES_STATE_ACTIVE 0xE
+#define RES_STATE_SLEEP 0x8
+#define RES_STATE_OFF 0x0
+
+/*
+ * Power Bus Message Format ... these can be sent individually by Linux,
+ * but are usually part of downloaded scripts that are run when various
+ * power events are triggered.
+ *
+ * Broadcast Message (16 Bits):
+ * DEV_GRP[15:13] MT[12] RES_GRP[11:9] RES_TYPE2[8:7] RES_TYPE[6:4]
+ * RES_STATE[3:0]
+ *
+ * Singular Message (16 Bits):
+ * DEV_GRP[15:13] MT[12] RES_ID[11:4] RES_STATE[3:0]
+ */
+
+#define MSG_BROADCAST(devgrp, grp, type, type2, state) \
+ ( (devgrp) << 13 | 1 << 12 | (grp) << 9 | (type2) << 7 \
+ | (type) << 4 | (state))
+
+#define MSG_SINGULAR(devgrp, id, state) \
+ ((devgrp) << 13 | 0 << 12 | (id) << 4 | (state))
+
+/*----------------------------------------------------------------------*/
+
struct twl4030_bci_platform_data {
int *battery_tmp_tbl;
unsigned int tblsize;
diff --git a/include/linux/ide.h b/include/linux/ide.h
index a5d26f66ef7..ff65fffb078 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -240,65 +240,38 @@ typedef enum {
} ide_startstop_t;
enum {
+ IDE_VALID_ERROR = (1 << 1),
+ IDE_VALID_FEATURE = IDE_VALID_ERROR,
+ IDE_VALID_NSECT = (1 << 2),
+ IDE_VALID_LBAL = (1 << 3),
+ IDE_VALID_LBAM = (1 << 4),
+ IDE_VALID_LBAH = (1 << 5),
+ IDE_VALID_DEVICE = (1 << 6),
+ IDE_VALID_LBA = IDE_VALID_LBAL |
+ IDE_VALID_LBAM |
+ IDE_VALID_LBAH,
+ IDE_VALID_OUT_TF = IDE_VALID_FEATURE |
+ IDE_VALID_NSECT |
+ IDE_VALID_LBA,
+ IDE_VALID_IN_TF = IDE_VALID_NSECT |
+ IDE_VALID_LBA,
+ IDE_VALID_OUT_HOB = IDE_VALID_OUT_TF,
+ IDE_VALID_IN_HOB = IDE_VALID_ERROR |
+ IDE_VALID_NSECT |
+ IDE_VALID_LBA,
+};
+
+enum {
IDE_TFLAG_LBA48 = (1 << 0),
- IDE_TFLAG_OUT_HOB_FEATURE = (1 << 1),
- IDE_TFLAG_OUT_HOB_NSECT = (1 << 2),
- IDE_TFLAG_OUT_HOB_LBAL = (1 << 3),
- IDE_TFLAG_OUT_HOB_LBAM = (1 << 4),
- IDE_TFLAG_OUT_HOB_LBAH = (1 << 5),
- IDE_TFLAG_OUT_HOB = IDE_TFLAG_OUT_HOB_FEATURE |
- IDE_TFLAG_OUT_HOB_NSECT |
- IDE_TFLAG_OUT_HOB_LBAL |
- IDE_TFLAG_OUT_HOB_LBAM |
- IDE_TFLAG_OUT_HOB_LBAH,
- IDE_TFLAG_OUT_FEATURE = (1 << 6),
- IDE_TFLAG_OUT_NSECT = (1 << 7),
- IDE_TFLAG_OUT_LBAL = (1 << 8),
- IDE_TFLAG_OUT_LBAM = (1 << 9),
- IDE_TFLAG_OUT_LBAH = (1 << 10),
- IDE_TFLAG_OUT_TF = IDE_TFLAG_OUT_FEATURE |
- IDE_TFLAG_OUT_NSECT |
- IDE_TFLAG_OUT_LBAL |
- IDE_TFLAG_OUT_LBAM |
- IDE_TFLAG_OUT_LBAH,
- IDE_TFLAG_OUT_DEVICE = (1 << 11),
- IDE_TFLAG_WRITE = (1 << 12),
- IDE_TFLAG_CUSTOM_HANDLER = (1 << 13),
- IDE_TFLAG_DMA_PIO_FALLBACK = (1 << 14),
- IDE_TFLAG_IN_HOB_ERROR = (1 << 15),
- IDE_TFLAG_IN_HOB_NSECT = (1 << 16),
- IDE_TFLAG_IN_HOB_LBAL = (1 << 17),
- IDE_TFLAG_IN_HOB_LBAM = (1 << 18),
- IDE_TFLAG_IN_HOB_LBAH = (1 << 19),
- IDE_TFLAG_IN_HOB_LBA = IDE_TFLAG_IN_HOB_LBAL |
- IDE_TFLAG_IN_HOB_LBAM |
- IDE_TFLAG_IN_HOB_LBAH,
- IDE_TFLAG_IN_HOB = IDE_TFLAG_IN_HOB_ERROR |
- IDE_TFLAG_IN_HOB_NSECT |
- IDE_TFLAG_IN_HOB_LBA,
- IDE_TFLAG_IN_ERROR = (1 << 20),
- IDE_TFLAG_IN_NSECT = (1 << 21),
- IDE_TFLAG_IN_LBAL = (1 << 22),
- IDE_TFLAG_IN_LBAM = (1 << 23),
- IDE_TFLAG_IN_LBAH = (1 << 24),
- IDE_TFLAG_IN_LBA = IDE_TFLAG_IN_LBAL |
- IDE_TFLAG_IN_LBAM |
- IDE_TFLAG_IN_LBAH,
- IDE_TFLAG_IN_TF = IDE_TFLAG_IN_NSECT |
- IDE_TFLAG_IN_LBA,
- IDE_TFLAG_IN_DEVICE = (1 << 25),
- IDE_TFLAG_HOB = IDE_TFLAG_OUT_HOB |
- IDE_TFLAG_IN_HOB,
- IDE_TFLAG_TF = IDE_TFLAG_OUT_TF |
- IDE_TFLAG_IN_TF,
- IDE_TFLAG_DEVICE = IDE_TFLAG_OUT_DEVICE |
- IDE_TFLAG_IN_DEVICE,
+ IDE_TFLAG_WRITE = (1 << 1),
+ IDE_TFLAG_CUSTOM_HANDLER = (1 << 2),
+ IDE_TFLAG_DMA_PIO_FALLBACK = (1 << 3),
/* force 16-bit I/O operations */
- IDE_TFLAG_IO_16BIT = (1 << 26),
+ IDE_TFLAG_IO_16BIT = (1 << 4),
/* struct ide_cmd was allocated using kmalloc() */
- IDE_TFLAG_DYN = (1 << 27),
- IDE_TFLAG_FS = (1 << 28),
- IDE_TFLAG_MULTI_PIO = (1 << 29),
+ IDE_TFLAG_DYN = (1 << 5),
+ IDE_TFLAG_FS = (1 << 6),
+ IDE_TFLAG_MULTI_PIO = (1 << 7),
};
enum {
@@ -309,45 +282,34 @@ enum {
};
struct ide_taskfile {
- u8 hob_data; /* 0: high data byte (for TASKFILE IOCTL) */
- /* 1-5: additional data to support LBA48 */
- union {
- u8 hob_error; /* read: error */
- u8 hob_feature; /* write: feature */
- };
-
- u8 hob_nsect;
- u8 hob_lbal;
- u8 hob_lbam;
- u8 hob_lbah;
-
- u8 data; /* 6: low data byte (for TASKFILE IOCTL) */
-
- union { /*  7: */
- u8 error; /* read: error */
- u8 feature; /* write: feature */
+ u8 data; /* 0: data byte (for TASKFILE ioctl) */
+ union { /* 1: */
+ u8 error; /* read: error */
+ u8 feature; /* write: feature */
};
-
- u8 nsect; /* 8: number of sectors */
- u8 lbal; /* 9: LBA low */
- u8 lbam; /* 10: LBA mid */
- u8 lbah; /* 11: LBA high */
-
- u8 device; /* 12: device select */
-
- union { /* 13: */
- u8 status; /*  read: status  */
+ u8 nsect; /* 2: number of sectors */
+ u8 lbal; /* 3: LBA low */
+ u8 lbam; /* 4: LBA mid */
+ u8 lbah; /* 5: LBA high */
+ u8 device; /* 6: device select */
+ union { /* 7: */
+ u8 status; /* read: status */
u8 command; /* write: command */
};
};
struct ide_cmd {
- union {
- struct ide_taskfile tf;
- u8 tf_array[14];
- };
+ struct ide_taskfile tf;
+ struct ide_taskfile hob;
+ struct {
+ struct {
+ u8 tf;
+ u8 hob;
+ } out, in;
+ } valid;
+
+ u8 tf_flags;
u8 ftf_flags; /* for TASKFILE ioctl */
- u32 tf_flags;
int protocol;
int sg_nents; /* number of sg entries */
@@ -662,8 +624,8 @@ struct ide_tp_ops {
void (*write_devctl)(struct hwif_s *, u8);
void (*dev_select)(ide_drive_t *);
- void (*tf_load)(ide_drive_t *, struct ide_cmd *);
- void (*tf_read)(ide_drive_t *, struct ide_cmd *);
+ void (*tf_load)(ide_drive_t *, struct ide_taskfile *, u8);
+ void (*tf_read)(ide_drive_t *, struct ide_taskfile *, u8);
void (*input_data)(ide_drive_t *, struct ide_cmd *,
void *, unsigned int);
@@ -1162,7 +1124,8 @@ extern int ide_devset_execute(ide_drive_t *drive,
void ide_complete_cmd(ide_drive_t *, struct ide_cmd *, u8, u8);
int ide_complete_rq(ide_drive_t *, int, unsigned int);
-void ide_tf_dump(const char *, struct ide_taskfile *);
+void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd);
+void ide_tf_dump(const char *, struct ide_cmd *);
void ide_exec_command(ide_hwif_t *, u8);
u8 ide_read_status(ide_hwif_t *);
@@ -1170,8 +1133,8 @@ u8 ide_read_altstatus(ide_hwif_t *);
void ide_write_devctl(ide_hwif_t *, u8);
void ide_dev_select(ide_drive_t *);
-void ide_tf_load(ide_drive_t *, struct ide_cmd *);
-void ide_tf_read(ide_drive_t *, struct ide_cmd *);
+void ide_tf_load(ide_drive_t *, struct ide_taskfile *, u8);
+void ide_tf_read(ide_drive_t *, struct ide_taskfile *, u8);
void ide_input_data(ide_drive_t *, struct ide_cmd *, void *, unsigned int);
void ide_output_data(ide_drive_t *, struct ide_cmd *, void *, unsigned int);
@@ -1529,7 +1492,7 @@ static inline void ide_set_hwifdata (ide_hwif_t * hwif, void *data)
extern void ide_toggle_bounce(ide_drive_t *drive, int on);
-u64 ide_get_lba_addr(struct ide_taskfile *, int);
+u64 ide_get_lba_addr(struct ide_cmd *, int);
u8 ide_dump_status(ide_drive_t *, const char *, u8);
struct ide_timing {
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index af1de95e711..d87247d2641 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -5,6 +5,7 @@
#include <linux/irqflags.h>
#include <linux/utsname.h>
#include <linux/lockdep.h>
+#include <linux/ftrace.h>
#include <linux/ipc.h>
#include <linux/pid_namespace.h>
#include <linux/user_namespace.h>
@@ -14,19 +15,6 @@
extern struct files_struct init_files;
extern struct fs_struct init_fs;
-#define INIT_KIOCTX(name, which_mm) \
-{ \
- .users = ATOMIC_INIT(1), \
- .dead = 0, \
- .mm = &which_mm, \
- .user_id = 0, \
- .next = NULL, \
- .wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.wait), \
- .ctx_lock = __SPIN_LOCK_UNLOCKED(name.ctx_lock), \
- .reqs_active = 0U, \
- .max_reqs = ~0U, \
-}
-
#define INIT_MM(name) \
{ \
.mm_rb = RB_ROOT, \
@@ -185,6 +173,7 @@ extern struct cred init_cred;
INIT_IDS \
INIT_TRACE_IRQFLAGS \
INIT_LOCKDEP \
+ INIT_FTRACE_GRAPH \
}
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 1d6c71d96ed..aa8c5317123 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -123,7 +123,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
#define ecap_eim_support(e) ((e >> 4) & 0x1)
#define ecap_ir_support(e) ((e >> 3) & 0x1)
#define ecap_max_handle_mask(e) ((e >> 20) & 0xf)
-
+#define ecap_sc_support(e) ((e >> 7) & 0x1) /* Snooping Control */
/* IOTLB_REG */
#define DMA_TLB_FLUSH_GRANU_OFFSET 60
@@ -164,6 +164,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
#define DMA_GCMD_QIE (((u32)1) << 26)
#define DMA_GCMD_SIRTP (((u32)1) << 24)
#define DMA_GCMD_IRE (((u32) 1) << 25)
+#define DMA_GCMD_CFI (((u32) 1) << 23)
/* GSTS_REG */
#define DMA_GSTS_TES (((u32)1) << 31)
@@ -174,6 +175,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
#define DMA_GSTS_QIES (((u32)1) << 26)
#define DMA_GSTS_IRTPS (((u32)1) << 24)
#define DMA_GSTS_IRES (((u32)1) << 25)
+#define DMA_GSTS_CFIS (((u32)1) << 23)
/* CCMD_REG */
#define DMA_CCMD_ICC (((u64)1) << 63)
@@ -284,6 +286,14 @@ struct iommu_flush {
unsigned int size_order, u64 type, int non_present_entry_flush);
};
+enum {
+ SR_DMAR_FECTL_REG,
+ SR_DMAR_FEDATA_REG,
+ SR_DMAR_FEADDR_REG,
+ SR_DMAR_FEUADDR_REG,
+ MAX_SR_DMAR_REGS
+};
+
struct intel_iommu {
void __iomem *reg; /* Pointer to hardware regs, virtual addr */
u64 cap;
@@ -304,6 +314,8 @@ struct intel_iommu {
struct iommu_flush flush;
#endif
struct q_inval *qi; /* Queued invalidation info */
+ u32 *iommu_state; /* Store iommu states between suspend and resume.*/
+
#ifdef CONFIG_INTR_REMAP
struct ir_table *ir_table; /* Interrupt remapping info */
#endif
@@ -322,6 +334,7 @@ extern int alloc_iommu(struct dmar_drhd_unit *drhd);
extern void free_iommu(struct intel_iommu *iommu);
extern int dmar_enable_qi(struct intel_iommu *iommu);
extern void dmar_disable_qi(struct intel_iommu *iommu);
+extern int dmar_reenable_qi(struct intel_iommu *iommu);
extern void qi_global_iec(struct intel_iommu *iommu);
extern int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid,
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index c68bffd182b..91bb76f44f1 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -59,6 +59,18 @@
#define IRQF_NOBALANCING 0x00000800
#define IRQF_IRQPOLL 0x00001000
+/*
+ * Bits used by threaded handlers:
+ * IRQTF_RUNTHREAD - signals that the interrupt handler thread should run
+ * IRQTF_DIED - handler thread died
+ * IRQTF_WARNED - warning "IRQ_WAKE_THREAD w/o thread_fn" has been printed
+ */
+enum {
+ IRQTF_RUNTHREAD,
+ IRQTF_DIED,
+ IRQTF_WARNED,
+};
+
typedef irqreturn_t (*irq_handler_t)(int, void *);
/**
@@ -71,6 +83,9 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);
* @next: pointer to the next irqaction for shared interrupts
* @irq: interrupt number
* @dir: pointer to the proc/irq/NN/name entry
+ * @thread_fn: interupt handler function for threaded interrupts
+ * @thread: thread pointer for threaded interrupts
+ * @thread_flags: flags related to @thread
*/
struct irqaction {
irq_handler_t handler;
@@ -81,18 +96,68 @@ struct irqaction {
struct irqaction *next;
int irq;
struct proc_dir_entry *dir;
+ irq_handler_t thread_fn;
+ struct task_struct *thread;
+ unsigned long thread_flags;
};
extern irqreturn_t no_action(int cpl, void *dev_id);
-extern int __must_check request_irq(unsigned int, irq_handler_t handler,
- unsigned long, const char *, void *);
+
+#ifdef CONFIG_GENERIC_HARDIRQS
+extern int __must_check
+request_threaded_irq(unsigned int irq, irq_handler_t handler,
+ irq_handler_t thread_fn,
+ unsigned long flags, const char *name, void *dev);
+
+static inline int __must_check
+request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
+ const char *name, void *dev)
+{
+ return request_threaded_irq(irq, handler, NULL, flags, name, dev);
+}
+
+extern void exit_irq_thread(void);
+#else
+
+extern int __must_check
+request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
+ const char *name, void *dev);
+
+/*
+ * Special function to avoid ifdeffery in kernel/irq/devres.c which
+ * gets magically built by GENERIC_HARDIRQS=n architectures (sparc,
+ * m68k). I really love these $@%#!* obvious Makefile references:
+ * ../../../kernel/irq/devres.o
+ */
+static inline int __must_check
+request_threaded_irq(unsigned int irq, irq_handler_t handler,
+ irq_handler_t thread_fn,
+ unsigned long flags, const char *name, void *dev)
+{
+ return request_irq(irq, handler, flags, name, dev);
+}
+
+static inline void exit_irq_thread(void) { }
+#endif
+
extern void free_irq(unsigned int, void *);
struct device;
-extern int __must_check devm_request_irq(struct device *dev, unsigned int irq,
- irq_handler_t handler, unsigned long irqflags,
- const char *devname, void *dev_id);
+extern int __must_check
+devm_request_threaded_irq(struct device *dev, unsigned int irq,
+ irq_handler_t handler, irq_handler_t thread_fn,
+ unsigned long irqflags, const char *devname,
+ void *dev_id);
+
+static inline int __must_check
+devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler,
+ unsigned long irqflags, const char *devname, void *dev_id)
+{
+ return devm_request_threaded_irq(dev, irq, handler, NULL, irqflags,
+ devname, dev_id);
+}
+
extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
/*
@@ -278,6 +343,11 @@ enum
NR_SOFTIRQS
};
+/* map softirq index to softirq name. update 'softirq_to_name' in
+ * kernel/softirq.c when adding a new softirq.
+ */
+extern char *softirq_to_name[NR_SOFTIRQS];
+
/* softirq mask and active fields moved to irq_cpustat_t in
* asm/hardirq.h to get better cache usage. KAO
*/
@@ -294,6 +364,7 @@ extern void softirq_init(void);
#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0)
extern void raise_softirq_irqoff(unsigned int nr);
extern void raise_softirq(unsigned int nr);
+extern void wakeup_softirqd(void);
/* This is the worklist that queues up per-cpu softirq work.
*
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 8a7bfb1b6ca..3af4ffd591b 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -21,6 +21,7 @@
#define IOMMU_READ (1)
#define IOMMU_WRITE (2)
+#define IOMMU_CACHE (4) /* DMA cache coherency */
struct device;
@@ -28,6 +29,8 @@ struct iommu_domain {
void *priv;
};
+#define IOMMU_CAP_CACHE_COHERENCY 0x1
+
struct iommu_ops {
int (*domain_init)(struct iommu_domain *domain);
void (*domain_destroy)(struct iommu_domain *domain);
@@ -39,6 +42,8 @@ struct iommu_ops {
size_t size);
phys_addr_t (*iova_to_phys)(struct iommu_domain *domain,
unsigned long iova);
+ int (*domain_has_cap)(struct iommu_domain *domain,
+ unsigned long cap);
};
#ifdef CONFIG_IOMMU_API
@@ -57,6 +62,8 @@ extern void iommu_unmap_range(struct iommu_domain *domain, unsigned long iova,
size_t size);
extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
unsigned long iova);
+extern int iommu_domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap);
#else /* CONFIG_IOMMU_API */
@@ -107,6 +114,12 @@ static inline phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
return 0;
}
+static inline int domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap)
+{
+ return 0;
+}
+
#endif /* CONFIG_IOMMU_API */
#endif /* __LINUX_IOMMU_H */
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h
index ea330f9e710..3bf40e246a8 100644
--- a/include/linux/ipc_namespace.h
+++ b/include/linux/ipc_namespace.h
@@ -25,7 +25,7 @@ struct ipc_ids {
};
struct ipc_namespace {
- struct kref kref;
+ atomic_t count;
struct ipc_ids ids[3];
int sem_ctls[4];
@@ -44,25 +44,57 @@ struct ipc_namespace {
int shm_tot;
struct notifier_block ipcns_nb;
+
+ /* The kern_mount of the mqueuefs sb. We take a ref on it */
+ struct vfsmount *mq_mnt;
+
+ /* # queues in this ns, protected by mq_lock */
+ unsigned int mq_queues_count;
+
+ /* next fields are set through sysctl */
+ unsigned int mq_queues_max; /* initialized to DFLT_QUEUESMAX */
+ unsigned int mq_msg_max; /* initialized to DFLT_MSGMAX */
+ unsigned int mq_msgsize_max; /* initialized to DFLT_MSGSIZEMAX */
+
};
extern struct ipc_namespace init_ipc_ns;
extern atomic_t nr_ipc_ns;
-#ifdef CONFIG_SYSVIPC
+extern spinlock_t mq_lock;
+#if defined(CONFIG_POSIX_MQUEUE) || defined(CONFIG_SYSVIPC)
#define INIT_IPC_NS(ns) .ns = &init_ipc_ns,
+#else
+#define INIT_IPC_NS(ns)
+#endif
+#ifdef CONFIG_SYSVIPC
extern int register_ipcns_notifier(struct ipc_namespace *);
extern int cond_register_ipcns_notifier(struct ipc_namespace *);
extern void unregister_ipcns_notifier(struct ipc_namespace *);
extern int ipcns_notify(unsigned long);
-
#else /* CONFIG_SYSVIPC */
-#define INIT_IPC_NS(ns)
+static inline int register_ipcns_notifier(struct ipc_namespace *ns)
+{ return 0; }
+static inline int cond_register_ipcns_notifier(struct ipc_namespace *ns)
+{ return 0; }
+static inline void unregister_ipcns_notifier(struct ipc_namespace *ns) { }
+static inline int ipcns_notify(unsigned long l) { return 0; }
#endif /* CONFIG_SYSVIPC */
-#if defined(CONFIG_SYSVIPC) && defined(CONFIG_IPC_NS)
-extern void free_ipc_ns(struct kref *kref);
+#ifdef CONFIG_POSIX_MQUEUE
+extern int mq_init_ns(struct ipc_namespace *ns);
+/* default values */
+#define DFLT_QUEUESMAX 256 /* max number of message queues */
+#define DFLT_MSGMAX 10 /* max number of messages in each queue */
+#define HARD_MSGMAX (131072/sizeof(void *))
+#define DFLT_MSGSIZEMAX 8192 /* max message size */
+#else
+static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; }
+#endif
+
+#if defined(CONFIG_IPC_NS)
+extern void free_ipc_ns(struct ipc_namespace *ns);
extern struct ipc_namespace *copy_ipcs(unsigned long flags,
struct ipc_namespace *ns);
extern void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
@@ -72,14 +104,11 @@ extern void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
{
if (ns)
- kref_get(&ns->kref);
+ atomic_inc(&ns->count);
return ns;
}
-static inline void put_ipc_ns(struct ipc_namespace *ns)
-{
- kref_put(&ns->kref, free_ipc_ns);
-}
+extern void put_ipc_ns(struct ipc_namespace *ns);
#else
static inline struct ipc_namespace *copy_ipcs(unsigned long flags,
struct ipc_namespace *ns)
@@ -99,4 +128,18 @@ static inline void put_ipc_ns(struct ipc_namespace *ns)
{
}
#endif
+
+#ifdef CONFIG_POSIX_MQUEUE_SYSCTL
+
+struct ctl_table_header;
+extern struct ctl_table_header *mq_register_sysctl_table(void);
+
+#else /* CONFIG_POSIX_MQUEUE_SYSCTL */
+
+static inline struct ctl_table_header *mq_register_sysctl_table(void)
+{
+ return NULL;
+}
+
+#endif /* CONFIG_POSIX_MQUEUE_SYSCTL */
#endif
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 974890b3c52..b7cbeed972e 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -22,6 +22,7 @@
#include <linux/irqnr.h>
#include <linux/errno.h>
#include <linux/topology.h>
+#include <linux/wait.h>
#include <asm/irq.h>
#include <asm/ptrace.h>
@@ -158,6 +159,8 @@ struct irq_2_iommu;
* @affinity: IRQ affinity on SMP
* @cpu: cpu index useful for balancing
* @pending_mask: pending rebalanced interrupts
+ * @threads_active: number of irqaction threads currently running
+ * @wait_for_threads: wait queue for sync_irq to wait for threaded handlers
* @dir: /proc/irq/ procfs entry
* @name: flow handler name for /proc/interrupts output
*/
@@ -189,6 +192,8 @@ struct irq_desc {
cpumask_var_t pending_mask;
#endif
#endif
+ atomic_t threads_active;
+ wait_queue_head_t wait_for_threads;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir;
#endif
@@ -482,6 +487,16 @@ static inline void init_copy_desc_masks(struct irq_desc *old_desc,
#endif
}
+static inline void free_desc_masks(struct irq_desc *old_desc,
+ struct irq_desc *new_desc)
+{
+ free_cpumask_var(old_desc->affinity);
+
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+ free_cpumask_var(old_desc->pending_mask);
+#endif
+}
+
#else /* !CONFIG_SMP */
static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu,
@@ -495,6 +510,10 @@ static inline void init_copy_desc_masks(struct irq_desc *old_desc,
{
}
+static inline void free_desc_masks(struct irq_desc *old_desc,
+ struct irq_desc *new_desc)
+{
+}
#endif /* CONFIG_SMP */
#endif /* _LINUX_IRQ_H */
diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h
index 74bde13224c..b02a3f1d46a 100644
--- a/include/linux/irqflags.h
+++ b/include/linux/irqflags.h
@@ -24,8 +24,8 @@
# define trace_softirqs_enabled(p) ((p)->softirqs_enabled)
# define trace_hardirq_enter() do { current->hardirq_context++; } while (0)
# define trace_hardirq_exit() do { current->hardirq_context--; } while (0)
-# define trace_softirq_enter() do { current->softirq_context++; } while (0)
-# define trace_softirq_exit() do { current->softirq_context--; } while (0)
+# define lockdep_softirq_enter() do { current->softirq_context++; } while (0)
+# define lockdep_softirq_exit() do { current->softirq_context--; } while (0)
# define INIT_TRACE_IRQFLAGS .softirqs_enabled = 1,
#else
# define trace_hardirqs_on() do { } while (0)
@@ -38,8 +38,8 @@
# define trace_softirqs_enabled(p) 0
# define trace_hardirq_enter() do { } while (0)
# define trace_hardirq_exit() do { } while (0)
-# define trace_softirq_enter() do { } while (0)
-# define trace_softirq_exit() do { } while (0)
+# define lockdep_softirq_enter() do { } while (0)
+# define lockdep_softirq_exit() do { } while (0)
# define INIT_TRACE_IRQFLAGS
#endif
diff --git a/include/linux/irqreturn.h b/include/linux/irqreturn.h
index c5584ca5b8c..819acaaac3f 100644
--- a/include/linux/irqreturn.h
+++ b/include/linux/irqreturn.h
@@ -5,10 +5,12 @@
* enum irqreturn
* @IRQ_NONE interrupt was not from this device
* @IRQ_HANDLED interrupt was handled by this device
+ * @IRQ_WAKE_THREAD handler requests to wake the handler thread
*/
enum irqreturn {
IRQ_NONE,
IRQ_HANDLED,
+ IRQ_WAKE_THREAD,
};
typedef enum irqreturn irqreturn_t;
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 64246dce566..53ae4399da2 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -35,7 +35,7 @@
#define journal_oom_retry 1
/*
- * Define JBD_PARANIOD_IOFAIL to cause a kernel BUG() if ext3 finds
+ * Define JBD_PARANOID_IOFAIL to cause a kernel BUG() if ext3 finds
* certain classes of error which can occur due to failed IOs. Under
* normal use we want ext3 to continue after such errors, because
* hardware _can_ fail, but for debugging purposes when running tests on
@@ -552,6 +552,11 @@ struct transaction_s
*/
int t_handle_count;
+ /*
+ * This transaction is being forced and some process is
+ * waiting for it to finish.
+ */
+ int t_synchronous_commit:1;
};
/**
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index f3fe34391d8..792274269f2 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -13,10 +13,17 @@
#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + 1)
+struct module;
+
#ifdef CONFIG_KALLSYMS
/* Lookup the address for a symbol. Returns 0 if not found. */
unsigned long kallsyms_lookup_name(const char *name);
+/* Call a function on each kallsyms symbol in the core kernel */
+int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
+ unsigned long),
+ void *data);
+
extern int kallsyms_lookup_size_offset(unsigned long addr,
unsigned long *symbolsize,
unsigned long *offset);
@@ -43,6 +50,14 @@ static inline unsigned long kallsyms_lookup_name(const char *name)
return 0;
}
+static inline int kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+ struct module *,
+ unsigned long),
+ void *data)
+{
+ return 0;
+}
+
static inline int kallsyms_lookup_size_offset(unsigned long addr,
unsigned long *symbolsize,
unsigned long *offset)
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 556d781e69f..d9e75ec7def 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -242,6 +242,19 @@ extern struct ratelimit_state printk_ratelimit_state;
extern int printk_ratelimit(void);
extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
unsigned int interval_msec);
+
+/*
+ * Print a one-time message (analogous to WARN_ONCE() et al):
+ */
+#define printk_once(x...) ({ \
+ static int __print_once = 1; \
+ \
+ if (__print_once) { \
+ __print_once = 0; \
+ printk(x); \
+ } \
+})
+
void log_buf_kexec_setup(void);
#else
static inline int vprintk(const char *s, va_list args)
@@ -254,6 +267,10 @@ static inline int printk_ratelimit(void) { return 0; }
static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \
unsigned int interval_msec) \
{ return false; }
+
+/* No effect, but we still get type checking even in the !PRINTK case: */
+#define printk_once(x...) printk(x)
+
static inline void log_buf_kexec_setup(void)
{
}
@@ -375,6 +392,139 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
#endif
/*
+ * General tracing related utility functions - trace_printk(),
+ * tracing_on/tracing_off and tracing_start()/tracing_stop
+ *
+ * Use tracing_on/tracing_off when you want to quickly turn on or off
+ * tracing. It simply enables or disables the recording of the trace events.
+ * This also corresponds to the user space debugfs/tracing/tracing_on
+ * file, which gives a means for the kernel and userspace to interact.
+ * Place a tracing_off() in the kernel where you want tracing to end.
+ * From user space, examine the trace, and then echo 1 > tracing_on
+ * to continue tracing.
+ *
+ * tracing_stop/tracing_start has slightly more overhead. It is used
+ * by things like suspend to ram where disabling the recording of the
+ * trace is not enough, but tracing must actually stop because things
+ * like calling smp_processor_id() may crash the system.
+ *
+ * Most likely, you want to use tracing_on/tracing_off.
+ */
+#ifdef CONFIG_RING_BUFFER
+void tracing_on(void);
+void tracing_off(void);
+/* trace_off_permanent stops recording with no way to bring it back */
+void tracing_off_permanent(void);
+int tracing_is_on(void);
+#else
+static inline void tracing_on(void) { }
+static inline void tracing_off(void) { }
+static inline void tracing_off_permanent(void) { }
+static inline int tracing_is_on(void) { return 0; }
+#endif
+#ifdef CONFIG_TRACING
+extern void tracing_start(void);
+extern void tracing_stop(void);
+extern void ftrace_off_permanent(void);
+
+extern void
+ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3);
+
+static inline void __attribute__ ((format (printf, 1, 2)))
+____trace_printk_check_format(const char *fmt, ...)
+{
+}
+#define __trace_printk_check_format(fmt, args...) \
+do { \
+ if (0) \
+ ____trace_printk_check_format(fmt, ##args); \
+} while (0)
+
+/**
+ * trace_printk - printf formatting in the ftrace buffer
+ * @fmt: the printf format for printing
+ *
+ * Note: __trace_printk is an internal function for trace_printk and
+ * the @ip is passed in via the trace_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 trace_printks scattered around in
+ * your code.
+ */
+
+#define trace_printk(fmt, args...) \
+do { \
+ __trace_printk_check_format(fmt, ##args); \
+ if (__builtin_constant_p(fmt)) { \
+ static const char *trace_printk_fmt \
+ __attribute__((section("__trace_printk_fmt"))) = \
+ __builtin_constant_p(fmt) ? fmt : NULL; \
+ \
+ __trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args); \
+ } else \
+ __trace_printk(_THIS_IP_, fmt, ##args); \
+} while (0)
+
+extern int
+__trace_bprintk(unsigned long ip, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+
+extern int
+__trace_printk(unsigned long ip, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+
+/*
+ * The double __builtin_constant_p is because gcc will give us an error
+ * if we try to allocate the static variable to fmt if it is not a
+ * constant. Even with the outer if statement.
+ */
+#define ftrace_vprintk(fmt, vargs) \
+do { \
+ if (__builtin_constant_p(fmt)) { \
+ static const char *trace_printk_fmt \
+ __attribute__((section("__trace_printk_fmt"))) = \
+ __builtin_constant_p(fmt) ? fmt : NULL; \
+ \
+ __ftrace_vbprintk(_THIS_IP_, trace_printk_fmt, vargs); \
+ } else \
+ __ftrace_vprintk(_THIS_IP_, fmt, vargs); \
+} while (0)
+
+extern int
+__ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap);
+
+extern int
+__ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);
+
+extern void ftrace_dump(void);
+#else
+static inline void
+ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { }
+static inline int
+trace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+
+static inline void tracing_start(void) { }
+static inline void tracing_stop(void) { }
+static inline void ftrace_off_permanent(void) { }
+static inline int
+trace_printk(const char *fmt, ...)
+{
+ return 0;
+}
+static inline int
+ftrace_vprintk(const char *fmt, va_list ap)
+{
+ return 0;
+}
+static inline void ftrace_dump(void) { }
+#endif /* CONFIG_TRACING */
+
+/*
* Display an IP address in readable format.
*/
diff --git a/include/linux/key.h b/include/linux/key.h
index 21d32a142c0..e544f466d69 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -20,6 +20,7 @@
#include <linux/rbtree.h>
#include <linux/rcupdate.h>
#include <linux/sysctl.h>
+#include <linux/rwsem.h>
#include <asm/atomic.h>
#ifdef __KERNEL__
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 92213a9194e..384ca8bbf1a 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -29,10 +29,15 @@
#ifdef CONFIG_MODULES
/* modprobe exit status on success, -ve on error. Return value
* usually useless though. */
-extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2)));
-#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
+extern int __request_module(bool wait, const char *name, ...) \
+ __attribute__((format(printf, 2, 3)));
+#define request_module(mod...) __request_module(true, mod)
+#define request_module_nowait(mod...) __request_module(false, mod)
+#define try_then_request_module(x, mod...) \
+ ((x) ?: (__request_module(true, mod), (x)))
#else
-static inline int request_module(const char * name, ...) { return -ENOSYS; }
+static inline int request_module(const char *name, ...) { return -ENOSYS; }
+static inline int request_module_nowait(const char *name, ...) { return -ENOSYS; }
#define try_then_request_module(x, mod...) (x)
#endif
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 2ec6cc14a11..bcd9c07848b 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -94,12 +94,16 @@ struct kprobe {
/* Called after addr is executed, unless... */
kprobe_post_handler_t post_handler;
- /* ... called if executing addr causes a fault (eg. page fault).
- * Return 1 if it handled fault, otherwise kernel will see it. */
+ /*
+ * ... called if executing addr causes a fault (eg. page fault).
+ * Return 1 if it handled fault, otherwise kernel will see it.
+ */
kprobe_fault_handler_t fault_handler;
- /* ... called if breakpoint trap occurs in probe handler.
- * Return 1 if it handled break, otherwise kernel will see it. */
+ /*
+ * ... called if breakpoint trap occurs in probe handler.
+ * Return 1 if it handled break, otherwise kernel will see it.
+ */
kprobe_break_handler_t break_handler;
/* Saved opcode (which has been replaced with breakpoint) */
@@ -108,18 +112,28 @@ struct kprobe {
/* copy of the original instruction */
struct arch_specific_insn ainsn;
- /* Indicates various status flags. Protected by kprobe_mutex. */
+ /*
+ * Indicates various status flags.
+ * Protected by kprobe_mutex after this kprobe is registered.
+ */
u32 flags;
};
/* Kprobe status flags */
#define KPROBE_FLAG_GONE 1 /* breakpoint has already gone */
+#define KPROBE_FLAG_DISABLED 2 /* probe is temporarily disabled */
+/* Has this kprobe gone ? */
static inline int kprobe_gone(struct kprobe *p)
{
return p->flags & KPROBE_FLAG_GONE;
}
+/* Is this kprobe disabled ? */
+static inline int kprobe_disabled(struct kprobe *p)
+{
+ return p->flags & (KPROBE_FLAG_DISABLED | KPROBE_FLAG_GONE);
+}
/*
* Special probe type that uses setjmp-longjmp type tricks to resume
* execution at a specified entry with a matching prototype corresponding
@@ -279,6 +293,9 @@ void unregister_kretprobes(struct kretprobe **rps, int num);
void kprobe_flush_task(struct task_struct *tk);
void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
+int disable_kprobe(struct kprobe *kp);
+int enable_kprobe(struct kprobe *kp);
+
#else /* !CONFIG_KPROBES: */
static inline int kprobes_built_in(void)
@@ -345,5 +362,30 @@ static inline void unregister_kretprobes(struct kretprobe **rps, int num)
static inline void kprobe_flush_task(struct task_struct *tk)
{
}
+static inline int disable_kprobe(struct kprobe *kp)
+{
+ return -ENOSYS;
+}
+static inline int enable_kprobe(struct kprobe *kp)
+{
+ return -ENOSYS;
+}
#endif /* CONFIG_KPROBES */
+static inline int disable_kretprobe(struct kretprobe *rp)
+{
+ return disable_kprobe(&rp->kp);
+}
+static inline int enable_kretprobe(struct kretprobe *rp)
+{
+ return enable_kprobe(&rp->kp);
+}
+static inline int disable_jprobe(struct jprobe *jp)
+{
+ return disable_kprobe(&jp->kp);
+}
+static inline int enable_jprobe(struct jprobe *jp)
+{
+ return enable_kprobe(&jp->kp);
+}
+
#endif /* _LINUX_KPROBES_H */
diff --git a/include/linux/leds-bd2802.h b/include/linux/leds-bd2802.h
new file mode 100644
index 00000000000..42f854a1a19
--- /dev/null
+++ b/include/linux/leds-bd2802.h
@@ -0,0 +1,26 @@
+/*
+ * leds-bd2802.h - RGB LED Driver
+ *
+ * Copyright (C) 2009 Samsung Electronics
+ * Kim Kyuwon <q1.kim@samsung.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.
+ *
+ * Datasheet: http://www.rohm.com/products/databook/driver/pdf/bd2802gu-e.pdf
+ *
+ */
+#ifndef _LEDS_BD2802_H_
+#define _LEDS_BD2802_H_
+
+struct bd2802_led_platform_data{
+ int reset_gpio;
+ u8 rgb_time;
+};
+
+#define RGB_TIME(slopedown, slopeup, waveform) \
+ ((slopedown) << 6 | (slopeup) << 4 | (waveform))
+
+#endif /* _LEDS_BD2802_H_ */
+
diff --git a/include/linux/leds.h b/include/linux/leds.h
index 24489da701e..376fe07732e 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -30,6 +30,7 @@ enum led_brightness {
struct led_classdev {
const char *name;
int brightness;
+ int max_brightness;
int flags;
/* Lower 16 bits reflect status */
@@ -140,7 +141,8 @@ struct gpio_led {
const char *name;
const char *default_trigger;
unsigned gpio;
- u8 active_low;
+ u8 active_low : 1;
+ u8 retain_state_suspended : 1;
};
struct gpio_led_platform_data {
diff --git a/include/linux/leds_pwm.h b/include/linux/leds_pwm.h
new file mode 100644
index 00000000000..33a07116748
--- /dev/null
+++ b/include/linux/leds_pwm.h
@@ -0,0 +1,21 @@
+/*
+ * PWM LED driver data - see drivers/leds/leds-pwm.c
+ */
+#ifndef __LINUX_LEDS_PWM_H
+#define __LINUX_LEDS_PWM_H
+
+struct led_pwm {
+ const char *name;
+ const char *default_trigger;
+ unsigned pwm_id;
+ u8 active_low;
+ unsigned max_brightness;
+ unsigned pwm_period_ns;
+};
+
+struct led_pwm_platform_data {
+ int num_leds;
+ struct led_pwm *leds;
+};
+
+#endif
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 76262d83656..b450a262885 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -379,7 +379,7 @@ enum {
ATA_HORKAGE_BRIDGE_OK = (1 << 10), /* no bridge limits */
ATA_HORKAGE_ATAPI_MOD16_DMA = (1 << 11), /* use ATAPI DMA for commands
not multiple of 16 bytes */
- ATA_HORKAGE_FIRMWARE_WARN = (1 << 12), /* firwmare update warning */
+ ATA_HORKAGE_FIRMWARE_WARN = (1 << 12), /* firmware update warning */
ATA_HORKAGE_1_5_GBPS = (1 << 13), /* force 1.5 Gbps */
/* DMA mask for user DMA control: User visible values; DO NOT
diff --git a/include/linux/lockd/xdr.h b/include/linux/lockd/xdr.h
index 7dc5b6cb44c..d39ed1cc5fb 100644
--- a/include/linux/lockd/xdr.h
+++ b/include/linux/lockd/xdr.h
@@ -25,13 +25,13 @@ struct svc_rqst;
#define NLM_MAXCOOKIELEN 32
#define NLM_MAXSTRLEN 1024
-#define nlm_granted __constant_htonl(NLM_LCK_GRANTED)
-#define nlm_lck_denied __constant_htonl(NLM_LCK_DENIED)
-#define nlm_lck_denied_nolocks __constant_htonl(NLM_LCK_DENIED_NOLOCKS)
-#define nlm_lck_blocked __constant_htonl(NLM_LCK_BLOCKED)
-#define nlm_lck_denied_grace_period __constant_htonl(NLM_LCK_DENIED_GRACE_PERIOD)
+#define nlm_granted cpu_to_be32(NLM_LCK_GRANTED)
+#define nlm_lck_denied cpu_to_be32(NLM_LCK_DENIED)
+#define nlm_lck_denied_nolocks cpu_to_be32(NLM_LCK_DENIED_NOLOCKS)
+#define nlm_lck_blocked cpu_to_be32(NLM_LCK_BLOCKED)
+#define nlm_lck_denied_grace_period cpu_to_be32(NLM_LCK_DENIED_GRACE_PERIOD)
-#define nlm_drop_reply __constant_htonl(30000)
+#define nlm_drop_reply cpu_to_be32(30000)
/* Lock info passed via NLM */
struct nlm_lock {
diff --git a/include/linux/lockd/xdr4.h b/include/linux/lockd/xdr4.h
index 12bfe09de2b..7353821341e 100644
--- a/include/linux/lockd/xdr4.h
+++ b/include/linux/lockd/xdr4.h
@@ -15,11 +15,11 @@
#include <linux/lockd/xdr.h>
/* error codes new to NLMv4 */
-#define nlm4_deadlock __constant_htonl(NLM_DEADLCK)
-#define nlm4_rofs __constant_htonl(NLM_ROFS)
-#define nlm4_stale_fh __constant_htonl(NLM_STALE_FH)
-#define nlm4_fbig __constant_htonl(NLM_FBIG)
-#define nlm4_failed __constant_htonl(NLM_FAILED)
+#define nlm4_deadlock cpu_to_be32(NLM_DEADLCK)
+#define nlm4_rofs cpu_to_be32(NLM_ROFS)
+#define nlm4_stale_fh cpu_to_be32(NLM_STALE_FH)
+#define nlm4_fbig cpu_to_be32(NLM_FBIG)
+#define nlm4_failed cpu_to_be32(NLM_FAILED)
diff --git a/include/linux/memory.h b/include/linux/memory.h
index 42767d1a62e..37fa19b34ef 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -110,4 +110,10 @@ struct memory_accessor {
off_t offset, size_t count);
};
+/*
+ * Kernel text modification mutex, used for code patching. Users of this lock
+ * can sleep.
+ */
+extern struct mutex text_mutex;
+
#endif /* _LINUX_MEMORY_H_ */
diff --git a/include/linux/mfd/ds1wm.h b/include/linux/mfd/ds1wm.h
new file mode 100644
index 00000000000..be469a357cb
--- /dev/null
+++ b/include/linux/mfd/ds1wm.h
@@ -0,0 +1,6 @@
+/* MFD cell driver data for the DS1WM driver */
+
+struct ds1wm_driver_data {
+ int active_high;
+ int clock_rate;
+};
diff --git a/include/linux/mfd/htc-pasic3.h b/include/linux/mfd/htc-pasic3.h
index b4294f12c4f..3d3ed67bd96 100644
--- a/include/linux/mfd/htc-pasic3.h
+++ b/include/linux/mfd/htc-pasic3.h
@@ -48,7 +48,6 @@ struct pasic3_leds_machinfo {
struct pasic3_platform_data {
struct pasic3_leds_machinfo *led_pdata;
- unsigned int bus_shift;
unsigned int clock_rate;
};
diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h
index 4455b212d75..c8f51c3c0a7 100644
--- a/include/linux/mfd/pcf50633/core.h
+++ b/include/linux/mfd/pcf50633/core.h
@@ -29,6 +29,8 @@ struct pcf50633_platform_data {
char **batteries;
int num_batteries;
+ int charging_restart_interval;
+
/* Callbacks */
void (*probe_done)(struct pcf50633 *);
void (*mbc_event_callback)(struct pcf50633 *, int);
diff --git a/include/linux/mfd/pcf50633/mbc.h b/include/linux/mfd/pcf50633/mbc.h
index 6e17619b773..4119579acf2 100644
--- a/include/linux/mfd/pcf50633/mbc.h
+++ b/include/linux/mfd/pcf50633/mbc.h
@@ -128,7 +128,6 @@ enum pcf50633_reg_mbcs3 {
int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma);
int pcf50633_mbc_get_status(struct pcf50633 *);
-void pcf50633_mbc_set_status(struct pcf50633 *, int what, int status);
#endif
diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h
index 980669d50dc..42cca672f34 100644
--- a/include/linux/mfd/wm8350/core.h
+++ b/include/linux/mfd/wm8350/core.h
@@ -640,9 +640,11 @@ struct wm8350 {
*
* @init: Function called during driver initialisation. Should be
* used by the platform to configure GPIO functions and similar.
+ * @irq_high: Set if WM8350 IRQ is active high.
*/
struct wm8350_platform_data {
int (*init)(struct wm8350 *wm8350);
+ int irq_high;
};
diff --git a/include/linux/mg_disk.h b/include/linux/mg_disk.h
new file mode 100644
index 00000000000..1f76b1ebf62
--- /dev/null
+++ b/include/linux/mg_disk.h
@@ -0,0 +1,206 @@
+/*
+ * include/linux/mg_disk.c
+ *
+ * Support for the mGine m[g]flash IO mode.
+ * Based on legacy hd.c
+ *
+ * (c) 2008 mGine Co.,LTD
+ * (c) 2008 unsik Kim <donari75@gmail.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.
+ */
+
+#ifndef __MG_DISK_H__
+#define __MG_DISK_H__
+
+#include <linux/blkdev.h>
+#include <linux/ata.h>
+
+/* name for block device */
+#define MG_DISK_NAME "mgd"
+/* name for platform device */
+#define MG_DEV_NAME "mg_disk"
+
+#define MG_DISK_MAJ 0
+#define MG_DISK_MAX_PART 16
+#define MG_SECTOR_SIZE 512
+#define MG_MAX_SECTS 256
+
+/* Register offsets */
+#define MG_BUFF_OFFSET 0x8000
+#define MG_STORAGE_BUFFER_SIZE 0x200
+#define MG_REG_OFFSET 0xC000
+#define MG_REG_FEATURE (MG_REG_OFFSET + 2) /* write case */
+#define MG_REG_ERROR (MG_REG_OFFSET + 2) /* read case */
+#define MG_REG_SECT_CNT (MG_REG_OFFSET + 4)
+#define MG_REG_SECT_NUM (MG_REG_OFFSET + 6)
+#define MG_REG_CYL_LOW (MG_REG_OFFSET + 8)
+#define MG_REG_CYL_HIGH (MG_REG_OFFSET + 0xA)
+#define MG_REG_DRV_HEAD (MG_REG_OFFSET + 0xC)
+#define MG_REG_COMMAND (MG_REG_OFFSET + 0xE) /* write case */
+#define MG_REG_STATUS (MG_REG_OFFSET + 0xE) /* read case */
+#define MG_REG_DRV_CTRL (MG_REG_OFFSET + 0x10)
+#define MG_REG_BURST_CTRL (MG_REG_OFFSET + 0x12)
+
+/* "Drive Select/Head Register" bit values */
+#define MG_REG_HEAD_MUST_BE_ON 0xA0 /* These 2 bits are always on */
+#define MG_REG_HEAD_DRIVE_MASTER (0x00 | MG_REG_HEAD_MUST_BE_ON)
+#define MG_REG_HEAD_DRIVE_SLAVE (0x10 | MG_REG_HEAD_MUST_BE_ON)
+#define MG_REG_HEAD_LBA_MODE (0x40 | MG_REG_HEAD_MUST_BE_ON)
+
+
+/* "Device Control Register" bit values */
+#define MG_REG_CTRL_INTR_ENABLE 0x0
+#define MG_REG_CTRL_INTR_DISABLE (0x1<<1)
+#define MG_REG_CTRL_RESET (0x1<<2)
+#define MG_REG_CTRL_INTR_POLA_ACTIVE_HIGH 0x0
+#define MG_REG_CTRL_INTR_POLA_ACTIVE_LOW (0x1<<4)
+#define MG_REG_CTRL_DPD_POLA_ACTIVE_LOW 0x0
+#define MG_REG_CTRL_DPD_POLA_ACTIVE_HIGH (0x1<<5)
+#define MG_REG_CTRL_DPD_DISABLE 0x0
+#define MG_REG_CTRL_DPD_ENABLE (0x1<<6)
+
+/* Status register bit */
+/* error bit in status register */
+#define MG_REG_STATUS_BIT_ERROR 0x01
+/* corrected error in status register */
+#define MG_REG_STATUS_BIT_CORRECTED_ERROR 0x04
+/* data request bit in status register */
+#define MG_REG_STATUS_BIT_DATA_REQ 0x08
+/* DSC - Drive Seek Complete */
+#define MG_REG_STATUS_BIT_SEEK_DONE 0x10
+/* DWF - Drive Write Fault */
+#define MG_REG_STATUS_BIT_WRITE_FAULT 0x20
+#define MG_REG_STATUS_BIT_READY 0x40
+#define MG_REG_STATUS_BIT_BUSY 0x80
+
+/* handy status */
+#define MG_STAT_READY (MG_REG_STATUS_BIT_READY | MG_REG_STATUS_BIT_SEEK_DONE)
+#define MG_READY_OK(s) (((s) & (MG_STAT_READY | \
+ (MG_REG_STATUS_BIT_BUSY | \
+ MG_REG_STATUS_BIT_WRITE_FAULT | \
+ MG_REG_STATUS_BIT_ERROR))) == MG_STAT_READY)
+
+/* Error register */
+#define MG_REG_ERR_AMNF 0x01
+#define MG_REG_ERR_ABRT 0x04
+#define MG_REG_ERR_IDNF 0x10
+#define MG_REG_ERR_UNC 0x40
+#define MG_REG_ERR_BBK 0x80
+
+/* error code for others */
+#define MG_ERR_NONE 0
+#define MG_ERR_TIMEOUT 0x100
+#define MG_ERR_INIT_STAT 0x101
+#define MG_ERR_TRANSLATION 0x102
+#define MG_ERR_CTRL_RST 0x103
+#define MG_ERR_INV_STAT 0x104
+#define MG_ERR_RSTOUT 0x105
+
+#define MG_MAX_ERRORS 6 /* Max read/write errors */
+
+/* command */
+#define MG_CMD_RD 0x20
+#define MG_CMD_WR 0x30
+#define MG_CMD_SLEEP 0x99
+#define MG_CMD_WAKEUP 0xC3
+#define MG_CMD_ID 0xEC
+#define MG_CMD_WR_CONF 0x3C
+#define MG_CMD_RD_CONF 0x40
+
+/* operation mode */
+#define MG_OP_CASCADE (1 << 0)
+#define MG_OP_CASCADE_SYNC_RD (1 << 1)
+#define MG_OP_CASCADE_SYNC_WR (1 << 2)
+#define MG_OP_INTERLEAVE (1 << 3)
+
+/* synchronous */
+#define MG_BURST_LAT_4 (3 << 4)
+#define MG_BURST_LAT_5 (4 << 4)
+#define MG_BURST_LAT_6 (5 << 4)
+#define MG_BURST_LAT_7 (6 << 4)
+#define MG_BURST_LAT_8 (7 << 4)
+#define MG_BURST_LEN_4 (1 << 1)
+#define MG_BURST_LEN_8 (2 << 1)
+#define MG_BURST_LEN_16 (3 << 1)
+#define MG_BURST_LEN_32 (4 << 1)
+#define MG_BURST_LEN_CONT (0 << 1)
+
+/* timeout value (unit: ms) */
+#define MG_TMAX_CONF_TO_CMD 1
+#define MG_TMAX_WAIT_RD_DRQ 10
+#define MG_TMAX_WAIT_WR_DRQ 500
+#define MG_TMAX_RST_TO_BUSY 10
+#define MG_TMAX_HDRST_TO_RDY 500
+#define MG_TMAX_SWRST_TO_RDY 500
+#define MG_TMAX_RSTOUT 3000
+
+/* device attribution */
+/* use mflash as boot device */
+#define MG_BOOT_DEV (1 << 0)
+/* use mflash as storage device */
+#define MG_STORAGE_DEV (1 << 1)
+/* same as MG_STORAGE_DEV, but bootloader already done reset sequence */
+#define MG_STORAGE_DEV_SKIP_RST (1 << 2)
+
+#define MG_DEV_MASK (MG_BOOT_DEV | MG_STORAGE_DEV | MG_STORAGE_DEV_SKIP_RST)
+
+/* names of GPIO resource */
+#define MG_RST_PIN "mg_rst"
+/* except MG_BOOT_DEV, reset-out pin should be assigned */
+#define MG_RSTOUT_PIN "mg_rstout"
+
+/* private driver data */
+struct mg_drv_data {
+ /* disk resource */
+ u32 use_polling;
+
+ /* device attribution */
+ u32 dev_attr;
+
+ /* internally used */
+ struct mg_host *host;
+};
+
+/* main structure for mflash driver */
+struct mg_host {
+ struct device *dev;
+
+ struct request_queue *breq;
+ spinlock_t lock;
+ struct gendisk *gd;
+
+ struct timer_list timer;
+ void (*mg_do_intr) (struct mg_host *);
+
+ u16 id[ATA_ID_WORDS];
+
+ u16 cyls;
+ u16 heads;
+ u16 sectors;
+ u32 n_sectors;
+ u32 nres_sectors;
+
+ void __iomem *dev_base;
+ unsigned int irq;
+ unsigned int rst;
+ unsigned int rstout;
+
+ u32 major;
+ u32 error;
+};
+
+/*
+ * Debugging macro and defines
+ */
+#undef DO_MG_DEBUG
+#ifdef DO_MG_DEBUG
+# define MG_DBG(fmt, args...) \
+ printk(KERN_DEBUG "%s:%d "fmt, __func__, __LINE__, ##args)
+#else /* CONFIG_MG_DEBUG */
+# define MG_DBG(fmt, args...) do { } while (0)
+#endif /* CONFIG_MG_DEBUG */
+
+#endif
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 4e457256bd3..3e7615e9087 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -192,5 +192,10 @@ static inline void mmc_signal_sdio_irq(struct mmc_host *host)
wake_up_process(host->sdio_irq_thread);
}
+struct regulator;
+
+int mmc_regulator_get_ocrmask(struct regulator *supply);
+int mmc_regulator_set_ocr(struct regulator *supply, unsigned short vdd_bit);
+
#endif
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 26ef24076b7..186ec6ab334 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -764,12 +764,6 @@ extern int numa_zonelist_order_handler(struct ctl_table *, int,
extern char numa_zonelist_order[];
#define NUMA_ZONELIST_ORDER_LEN 16 /* string buffer size */
-#include <linux/topology.h>
-/* Returns the number of the current Node. */
-#ifndef numa_node_id
-#define numa_node_id() (cpu_to_node(raw_smp_processor_id()))
-#endif
-
#ifndef CONFIG_NEED_MULTIPLE_NODES
extern struct pglist_data contig_page_data;
diff --git a/include/linux/module.h b/include/linux/module.h
index 145a75528cc..627ac082e2a 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -248,6 +248,10 @@ struct module
const unsigned long *crcs;
unsigned int num_syms;
+ /* Kernel parameters. */
+ struct kernel_param *kp;
+ unsigned int num_kp;
+
/* GPL-only exported symbols. */
unsigned int num_gpl_syms;
const struct kernel_symbol *gpl_syms;
@@ -329,6 +333,11 @@ struct module
unsigned int num_tracepoints;
#endif
+#ifdef CONFIG_TRACING
+ const char **trace_bprintk_fmt_start;
+ unsigned int num_trace_bprintk_fmt;
+#endif
+
#ifdef CONFIG_MODULE_UNLOAD
/* What modules depend on me? */
struct list_head modules_which_use_me;
@@ -350,6 +359,8 @@ struct module
#define MODULE_ARCH_INIT {}
#endif
+extern struct mutex module_mutex;
+
/* FIXME: It'd be nice to isolate modules during init, too, so they
aren't used before they (may) fail. But presently too much code
(IDE & SCSI) require entry into the module during init.*/
@@ -358,10 +369,10 @@ static inline int module_is_live(struct module *mod)
return mod->state != MODULE_STATE_GOING;
}
-/* Is this address in a module? (second is with no locks, for oops) */
-struct module *module_text_address(unsigned long addr);
struct module *__module_text_address(unsigned long addr);
-int is_module_address(unsigned long addr);
+struct module *__module_address(unsigned long addr);
+bool is_module_address(unsigned long addr);
+bool is_module_text_address(unsigned long addr);
static inline int within_module_core(unsigned long addr, struct module *mod)
{
@@ -375,6 +386,31 @@ static inline int within_module_init(unsigned long addr, struct module *mod)
addr < (unsigned long)mod->module_init + mod->init_size;
}
+/* Search for module by name: must hold module_mutex. */
+struct module *find_module(const char *name);
+
+struct symsearch {
+ const struct kernel_symbol *start, *stop;
+ const unsigned long *crcs;
+ enum {
+ NOT_GPL_ONLY,
+ GPL_ONLY,
+ WILL_BE_GPL_ONLY,
+ } licence;
+ bool unused;
+};
+
+/* Search for an exported symbol by name. */
+const struct kernel_symbol *find_symbol(const char *name,
+ struct module **owner,
+ const unsigned long **crc,
+ bool gplok,
+ bool warn);
+
+/* Walk the exported symbol table */
+bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
+ unsigned int symnum, void *data), void *data);
+
/* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
symnum out of range. */
int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
@@ -383,6 +419,10 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
/* Look for this name: can be of form module:name. */
unsigned long module_kallsyms_lookup_name(const char *name);
+int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+ struct module *, unsigned long),
+ void *data);
+
extern void __module_put_and_exit(struct module *mod, long code)
__attribute__((noreturn));
#define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code);
@@ -444,6 +484,7 @@ static inline void __module_get(struct module *module)
#define symbol_put_addr(p) do { } while(0)
#endif /* CONFIG_MODULE_UNLOAD */
+int use_module(struct module *a, struct module *b);
/* This is a #define so the string doesn't get put in every .o file */
#define module_name(mod) \
@@ -490,21 +531,24 @@ search_module_extables(unsigned long addr)
return NULL;
}
-/* Is this address in a module? */
-static inline struct module *module_text_address(unsigned long addr)
+static inline struct module *__module_address(unsigned long addr)
{
return NULL;
}
-/* Is this address in a module? (don't take a lock, we're oopsing) */
static inline struct module *__module_text_address(unsigned long addr)
{
return NULL;
}
-static inline int is_module_address(unsigned long addr)
+static inline bool is_module_address(unsigned long addr)
{
- return 0;
+ return false;
+}
+
+static inline bool is_module_text_address(unsigned long addr)
+{
+ return false;
}
/* Get/put a kernel symbol (calls should be symmetric) */
@@ -559,6 +603,14 @@ static inline unsigned long module_kallsyms_lookup_name(const char *name)
return 0;
}
+static inline int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+ struct module *,
+ unsigned long),
+ void *data)
+{
+ return 0;
+}
+
static inline int register_module_notifier(struct notifier_block * nb)
{
/* no events will happen anyway, so this can always succeed */
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index e4af3399ef4..a4f0b931846 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -138,6 +138,16 @@ extern int parse_args(const char *name,
unsigned num,
int (*unknown)(char *param, char *val));
+/* Called by module remove. */
+#ifdef CONFIG_SYSFS
+extern void destroy_params(const struct kernel_param *params, unsigned num);
+#else
+static inline void destroy_params(const struct kernel_param *params,
+ unsigned num)
+{
+}
+#endif /* !CONFIG_SYSFS */
+
/* All the helper functions */
/* The macros to do compile-time type checking stolen from Jakub
Jelinek, who IIRC came up with this idea for the 2.4 module init code. */
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 3aa5d77c2cd..5675b63a063 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/uio.h>
#include <linux/notifier.h>
+#include <linux/device.h>
#include <linux/mtd/compatmac.h>
#include <mtd/mtd-abi.h>
@@ -162,6 +163,20 @@ struct mtd_info {
/* We probably shouldn't allow XIP if the unpoint isn't a NULL */
void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
+ /* Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+ unsigned long (*get_unmapped_area) (struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags);
+
+ /* Backing device capabilities for this device
+ * - provides mmap capabilities
+ */
+ struct backing_dev_info *backing_dev_info;
+
int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
@@ -223,6 +238,7 @@ struct mtd_info {
void *priv;
struct module *owner;
+ struct device dev;
int usecount;
/* If the driver is something smart, like UBI, it may need to maintain
@@ -233,6 +249,11 @@ struct mtd_info {
void (*put_device) (struct mtd_info *mtd);
};
+static inline struct mtd_info *dev_to_mtd(struct device *dev)
+{
+ return dev ? container_of(dev, struct mtd_info, dev) : NULL;
+}
+
static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
{
if (mtd->erasesize_shift)
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index db5b63da2a7..7efb9be3466 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -43,8 +43,8 @@ extern void nand_wait_ready(struct mtd_info *mtd);
* is supported now. If you add a chip with bigger oobsize/page
* adjust this accordingly.
*/
-#define NAND_MAX_OOBSIZE 64
-#define NAND_MAX_PAGESIZE 2048
+#define NAND_MAX_OOBSIZE 128
+#define NAND_MAX_PAGESIZE 4096
/*
* Constants for hardware specific CLE/ALE/NCE function
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index a45dd831b3f..7535a74083b 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -76,4 +76,16 @@ int __devinit of_mtd_parse_partitions(struct device *dev,
struct device_node *node,
struct mtd_partition **pparts);
+#ifdef CONFIG_MTD_PARTITIONS
+static inline int mtd_has_partitions(void) { return 1; }
+#else
+static inline int mtd_has_partitions(void) { return 0; }
+#endif
+
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+static inline int mtd_has_cmdlinepart(void) { return 1; }
+#else
+static inline int mtd_has_cmdlinepart(void) { return 0; }
+#endif
+
#endif
diff --git a/include/linux/nfs.h b/include/linux/nfs.h
index 54af92c1c70..214d499718f 100644
--- a/include/linux/nfs.h
+++ b/include/linux/nfs.h
@@ -109,7 +109,6 @@
NFSERR_FILE_OPEN = 10046, /* v4 */
NFSERR_ADMIN_REVOKED = 10047, /* v4 */
NFSERR_CB_PATH_DOWN = 10048, /* v4 */
- NFSERR_REPLAY_ME = 10049 /* v4 */
};
/* NFSv2 file types - beware, these are not the same in NFSv3 */
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index b912311a56b..e3f0cbcbd0d 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -21,6 +21,7 @@
#define NFS4_FHSIZE 128
#define NFS4_MAXPATHLEN PATH_MAX
#define NFS4_MAXNAMLEN NAME_MAX
+#define NFS4_MAX_SESSIONID_LEN 16
#define NFS4_ACCESS_READ 0x0001
#define NFS4_ACCESS_LOOKUP 0x0002
@@ -38,6 +39,7 @@
#define NFS4_OPEN_RESULT_CONFIRM 0x0002
#define NFS4_OPEN_RESULT_LOCKTYPE_POSIX 0x0004
+#define NFS4_SHARE_ACCESS_MASK 0x000F
#define NFS4_SHARE_ACCESS_READ 0x0001
#define NFS4_SHARE_ACCESS_WRITE 0x0002
#define NFS4_SHARE_ACCESS_BOTH 0x0003
@@ -45,6 +47,19 @@
#define NFS4_SHARE_DENY_WRITE 0x0002
#define NFS4_SHARE_DENY_BOTH 0x0003
+/* nfs41 */
+#define NFS4_SHARE_WANT_MASK 0xFF00
+#define NFS4_SHARE_WANT_NO_PREFERENCE 0x0000
+#define NFS4_SHARE_WANT_READ_DELEG 0x0100
+#define NFS4_SHARE_WANT_WRITE_DELEG 0x0200
+#define NFS4_SHARE_WANT_ANY_DELEG 0x0300
+#define NFS4_SHARE_WANT_NO_DELEG 0x0400
+#define NFS4_SHARE_WANT_CANCEL 0x0500
+
+#define NFS4_SHARE_WHEN_MASK 0xF0000
+#define NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL 0x10000
+#define NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED 0x20000
+
#define NFS4_SET_TO_SERVER_TIME 0
#define NFS4_SET_TO_CLIENT_TIME 1
@@ -88,6 +103,31 @@
#define NFS4_ACE_GENERIC_EXECUTE 0x001200A0
#define NFS4_ACE_MASK_ALL 0x001F01FF
+#define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001
+#define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002
+#define EXCHGID4_FLAG_USE_NON_PNFS 0x00010000
+#define EXCHGID4_FLAG_USE_PNFS_MDS 0x00020000
+#define EXCHGID4_FLAG_USE_PNFS_DS 0x00040000
+#define EXCHGID4_FLAG_UPD_CONFIRMED_REC_A 0x40000000
+#define EXCHGID4_FLAG_CONFIRMED_R 0x80000000
+/*
+ * Since the validity of these bits depends on whether
+ * they're set in the argument or response, have separate
+ * invalid flag masks for arg (_A) and resp (_R).
+ */
+#define EXCHGID4_FLAG_MASK_A 0x40070003
+#define EXCHGID4_FLAG_MASK_R 0x80070003
+
+#define SEQ4_STATUS_CB_PATH_DOWN 0x00000001
+#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING 0x00000002
+#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED 0x00000004
+#define SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED 0x00000008
+#define SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED 0x00000010
+#define SEQ4_STATUS_ADMIN_STATE_REVOKED 0x00000020
+#define SEQ4_STATUS_RECALLABLE_STATE_REVOKED 0x00000040
+#define SEQ4_STATUS_LEASE_MOVED 0x00000080
+#define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100
+
#define NFS4_MAX_UINT64 (~(u64)0)
enum nfs4_acl_whotype {
@@ -154,6 +194,28 @@ enum nfs_opnum4 {
OP_VERIFY = 37,
OP_WRITE = 38,
OP_RELEASE_LOCKOWNER = 39,
+
+ /* nfs41 */
+ OP_BACKCHANNEL_CTL = 40,
+ OP_BIND_CONN_TO_SESSION = 41,
+ OP_EXCHANGE_ID = 42,
+ OP_CREATE_SESSION = 43,
+ OP_DESTROY_SESSION = 44,
+ OP_FREE_STATEID = 45,
+ OP_GET_DIR_DELEGATION = 46,
+ OP_GETDEVICEINFO = 47,
+ OP_GETDEVICELIST = 48,
+ OP_LAYOUTCOMMIT = 49,
+ OP_LAYOUTGET = 50,
+ OP_LAYOUTRETURN = 51,
+ OP_SECINFO_NO_NAME = 52,
+ OP_SEQUENCE = 53,
+ OP_SET_SSV = 54,
+ OP_TEST_STATEID = 55,
+ OP_WANT_DELEGATION = 56,
+ OP_DESTROY_CLIENTID = 57,
+ OP_RECLAIM_COMPLETE = 58,
+
OP_ILLEGAL = 10044,
};
@@ -230,7 +292,48 @@ enum nfsstat4 {
NFS4ERR_DEADLOCK = 10045,
NFS4ERR_FILE_OPEN = 10046,
NFS4ERR_ADMIN_REVOKED = 10047,
- NFS4ERR_CB_PATH_DOWN = 10048
+ NFS4ERR_CB_PATH_DOWN = 10048,
+
+ /* nfs41 */
+ NFS4ERR_BADIOMODE = 10049,
+ NFS4ERR_BADLAYOUT = 10050,
+ NFS4ERR_BAD_SESSION_DIGEST = 10051,
+ NFS4ERR_BADSESSION = 10052,
+ NFS4ERR_BADSLOT = 10053,
+ NFS4ERR_COMPLETE_ALREADY = 10054,
+ NFS4ERR_CONN_NOT_BOUND_TO_SESSION = 10055,
+ NFS4ERR_DELEG_ALREADY_WANTED = 10056,
+ NFS4ERR_BACK_CHAN_BUSY = 10057, /* backchan reqs outstanding */
+ NFS4ERR_LAYOUTTRYLATER = 10058,
+ NFS4ERR_LAYOUTUNAVAILABLE = 10059,
+ NFS4ERR_NOMATCHING_LAYOUT = 10060,
+ NFS4ERR_RECALLCONFLICT = 10061,
+ NFS4ERR_UNKNOWN_LAYOUTTYPE = 10062,
+ NFS4ERR_SEQ_MISORDERED = 10063, /* unexpected seq.id in req */
+ NFS4ERR_SEQUENCE_POS = 10064, /* [CB_]SEQ. op not 1st op */
+ NFS4ERR_REQ_TOO_BIG = 10065, /* request too big */
+ NFS4ERR_REP_TOO_BIG = 10066, /* reply too big */
+ NFS4ERR_REP_TOO_BIG_TO_CACHE = 10067, /* rep. not all cached */
+ NFS4ERR_RETRY_UNCACHED_REP = 10068, /* retry & rep. uncached */
+ NFS4ERR_UNSAFE_COMPOUND = 10069, /* retry/recovery too hard */
+ NFS4ERR_TOO_MANY_OPS = 10070, /* too many ops in [CB_]COMP */
+ NFS4ERR_OP_NOT_IN_SESSION = 10071, /* op needs [CB_]SEQ. op */
+ NFS4ERR_HASH_ALG_UNSUPP = 10072, /* hash alg. not supp. */
+ /* Error 10073 is unused. */
+ NFS4ERR_CLIENTID_BUSY = 10074, /* clientid has state */
+ NFS4ERR_PNFS_IO_HOLE = 10075, /* IO to _SPARSE file hole */
+ NFS4ERR_SEQ_FALSE_RETRY = 10076, /* retry not origional */
+ NFS4ERR_BAD_HIGH_SLOT = 10077, /* sequence arg bad */
+ NFS4ERR_DEADSESSION = 10078, /* persistent session dead */
+ NFS4ERR_ENCR_ALG_UNSUPP = 10079, /* SSV alg mismatch */
+ NFS4ERR_PNFS_NO_LAYOUT = 10080, /* direct I/O with no layout */
+ NFS4ERR_NOT_ONLY_OP = 10081, /* bad compound */
+ NFS4ERR_WRONG_CRED = 10082, /* permissions:state change */
+ NFS4ERR_WRONG_TYPE = 10083, /* current operation mismatch */
+ NFS4ERR_DIRDELEG_UNAVAIL = 10084, /* no directory delegation */
+ NFS4ERR_REJECT_DELEG = 10085, /* on callback */
+ NFS4ERR_RETURNCONFLICT = 10086, /* outstanding layoutreturn */
+ NFS4ERR_DELEG_REVOKED = 10087, /* deleg./layout revoked */
};
/*
@@ -265,7 +368,13 @@ enum opentype4 {
enum createmode4 {
NFS4_CREATE_UNCHECKED = 0,
NFS4_CREATE_GUARDED = 1,
- NFS4_CREATE_EXCLUSIVE = 2
+ NFS4_CREATE_EXCLUSIVE = 2,
+ /*
+ * New to NFSv4.1. If session is persistent,
+ * GUARDED4 MUST be used. Otherwise, use
+ * EXCLUSIVE4_1 instead of EXCLUSIVE4.
+ */
+ NFS4_CREATE_EXCLUSIVE4_1 = 3
};
enum limit_by4 {
@@ -301,6 +410,8 @@ enum lock_type4 {
#define FATTR4_WORD0_UNIQUE_HANDLES (1UL << 9)
#define FATTR4_WORD0_LEASE_TIME (1UL << 10)
#define FATTR4_WORD0_RDATTR_ERROR (1UL << 11)
+/* Mandatory in NFSv4.1 */
+#define FATTR4_WORD2_SUPPATTR_EXCLCREAT (1UL << 11)
/* Recommended Attributes */
#define FATTR4_WORD0_ACL (1UL << 12)
@@ -391,6 +502,29 @@ enum {
NFSPROC4_CLNT_GETACL,
NFSPROC4_CLNT_SETACL,
NFSPROC4_CLNT_FS_LOCATIONS,
+
+ /* nfs41 */
+ NFSPROC4_CLNT_EXCHANGE_ID,
+ NFSPROC4_CLNT_CREATE_SESSION,
+ NFSPROC4_CLNT_DESTROY_SESSION,
+ NFSPROC4_CLNT_SEQUENCE,
+ NFSPROC4_CLNT_GET_LEASE_TIME,
+};
+
+/* nfs41 types */
+struct nfs4_sessionid {
+ unsigned char data[NFS4_MAX_SESSIONID_LEN];
+};
+
+/* Create Session Flags */
+#define SESSION4_PERSIST 0x001
+#define SESSION4_BACK_CHAN 0x002
+#define SESSION4_RDMA 0x004
+
+enum state_protect_how4 {
+ SP4_NONE = 0,
+ SP4_MACH_CRED = 1,
+ SP4_SSV = 2
};
#endif
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index bde2557c2a9..fdffb413b19 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -185,6 +185,9 @@ struct nfs_inode {
fmode_t delegation_state;
struct rw_semaphore rwsem;
#endif /* CONFIG_NFS_V4*/
+#ifdef CONFIG_NFS_FSCACHE
+ struct fscache_cookie *fscache;
+#endif
struct inode vfs_inode;
};
@@ -207,6 +210,8 @@ struct nfs_inode {
#define NFS_INO_ACL_LRU_SET (2) /* Inode is on the LRU list */
#define NFS_INO_MOUNTPOINT (3) /* inode is remote mountpoint */
#define NFS_INO_FLUSHING (4) /* inode is flushing out data */
+#define NFS_INO_FSCACHE (5) /* inode can be cached by FS-Cache */
+#define NFS_INO_FSCACHE_LOCK (6) /* FS-Cache cookie management lock */
static inline struct nfs_inode *NFS_I(const struct inode *inode)
{
@@ -260,6 +265,11 @@ static inline int NFS_STALE(const struct inode *inode)
return test_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
}
+static inline int NFS_FSCACHE(const struct inode *inode)
+{
+ return test_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
+}
+
static inline __u64 NFS_FILEID(const struct inode *inode)
{
return NFS_I(inode)->fileid;
@@ -506,6 +516,8 @@ extern int nfs_readpages(struct file *, struct address_space *,
struct list_head *, unsigned);
extern int nfs_readpage_result(struct rpc_task *, struct nfs_read_data *);
extern void nfs_readdata_release(void *data);
+extern int nfs_readpage_async(struct nfs_open_context *, struct inode *,
+ struct page *);
/*
* Allocate nfs_read_data structures
@@ -583,6 +595,7 @@ extern void * nfs_root_data(void);
#define NFSDBG_CALLBACK 0x0100
#define NFSDBG_CLIENT 0x0200
#define NFSDBG_MOUNT 0x0400
+#define NFSDBG_FSCACHE 0x0800
#define NFSDBG_ALL 0xFFFF
#ifdef __KERNEL__
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 29b1e40dce9..6ad75948cbf 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -64,6 +64,10 @@ struct nfs_client {
char cl_ipaddr[48];
unsigned char cl_id_uniquifier;
#endif
+
+#ifdef CONFIG_NFS_FSCACHE
+ struct fscache_cookie *fscache; /* client index cache cookie */
+#endif
};
/*
@@ -96,12 +100,19 @@ struct nfs_server {
unsigned int acdirmin;
unsigned int acdirmax;
unsigned int namelen;
+ unsigned int options; /* extra options enabled by mount */
+#define NFS_OPTION_FSCACHE 0x00000001 /* - local caching enabled */
struct nfs_fsid fsid;
__u64 maxfilesize; /* maximum file size */
unsigned long mount_time; /* when this fs was mounted */
dev_t s_dev; /* superblock dev numbers */
+#ifdef CONFIG_NFS_FSCACHE
+ struct nfs_fscache_key *fscache_key; /* unique key for superblock */
+ struct fscache_cookie *fscache; /* superblock cookie */
+#endif
+
#ifdef CONFIG_NFS_V4
u32 attr_bitmask[2];/* V4 bitmask representing the set
of attributes supported on this
diff --git a/include/linux/nfs_iostat.h b/include/linux/nfs_iostat.h
index 1cb9a3fed2b..68b10f5f890 100644
--- a/include/linux/nfs_iostat.h
+++ b/include/linux/nfs_iostat.h
@@ -116,4 +116,16 @@ enum nfs_stat_eventcounters {
__NFSIOS_COUNTSMAX,
};
+/*
+ * NFS local caching servicing counters
+ */
+enum nfs_stat_fscachecounters {
+ NFSIOS_FSCACHE_PAGES_READ_OK,
+ NFSIOS_FSCACHE_PAGES_READ_FAIL,
+ NFSIOS_FSCACHE_PAGES_WRITTEN_OK,
+ NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL,
+ NFSIOS_FSCACHE_PAGES_UNCACHED,
+ __NFSIOS_FSCACHEMAX,
+};
+
#endif /* _LINUX_NFS_IOSTAT */
diff --git a/include/linux/nfsd/cache.h b/include/linux/nfsd/cache.h
index 04b355c801d..5bccaab8105 100644
--- a/include/linux/nfsd/cache.h
+++ b/include/linux/nfsd/cache.h
@@ -76,4 +76,12 @@ void nfsd_reply_cache_shutdown(void);
int nfsd_cache_lookup(struct svc_rqst *, int);
void nfsd_cache_update(struct svc_rqst *, int, __be32 *);
+#ifdef CONFIG_NFSD_V4
+void nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp);
+#else /* CONFIG_NFSD_V4 */
+static inline void nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp)
+{
+}
+#endif /* CONFIG_NFSD_V4 */
+
#endif /* NFSCACHE_H */
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index e19f45991b2..2b49d676d0c 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -23,7 +23,7 @@
/*
* nfsd version
*/
-#define NFSD_SUPPORTED_MINOR_VERSION 0
+#define NFSD_SUPPORTED_MINOR_VERSION 1
/*
* Flags for nfsd_permission
@@ -53,6 +53,7 @@ typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int);
extern struct svc_program nfsd_program;
extern struct svc_version nfsd_version2, nfsd_version3,
nfsd_version4;
+extern u32 nfsd_supported_minorversion;
extern struct mutex nfsd_mutex;
extern struct svc_serv *nfsd_serv;
@@ -105,7 +106,7 @@ void nfsd_close(struct file *);
__be32 nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *,
loff_t, struct kvec *, int, unsigned long *);
__be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *,
- loff_t, struct kvec *,int, unsigned long, int *);
+ loff_t, struct kvec *,int, unsigned long *, int *);
__be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *,
char *, int *);
__be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *,
@@ -149,6 +150,7 @@ int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
int nfsd_vers(int vers, enum vers_op change);
+int nfsd_minorversion(u32 minorversion, enum vers_op change);
void nfsd_reset_versions(void);
int nfsd_create_serv(void);
@@ -186,78 +188,119 @@ void nfsd_lockd_shutdown(void);
/*
* These macros provide pre-xdr'ed values for faster operation.
*/
-#define nfs_ok __constant_htonl(NFS_OK)
-#define nfserr_perm __constant_htonl(NFSERR_PERM)
-#define nfserr_noent __constant_htonl(NFSERR_NOENT)
-#define nfserr_io __constant_htonl(NFSERR_IO)
-#define nfserr_nxio __constant_htonl(NFSERR_NXIO)
-#define nfserr_eagain __constant_htonl(NFSERR_EAGAIN)
-#define nfserr_acces __constant_htonl(NFSERR_ACCES)
-#define nfserr_exist __constant_htonl(NFSERR_EXIST)
-#define nfserr_xdev __constant_htonl(NFSERR_XDEV)
-#define nfserr_nodev __constant_htonl(NFSERR_NODEV)
-#define nfserr_notdir __constant_htonl(NFSERR_NOTDIR)
-#define nfserr_isdir __constant_htonl(NFSERR_ISDIR)
-#define nfserr_inval __constant_htonl(NFSERR_INVAL)
-#define nfserr_fbig __constant_htonl(NFSERR_FBIG)
-#define nfserr_nospc __constant_htonl(NFSERR_NOSPC)
-#define nfserr_rofs __constant_htonl(NFSERR_ROFS)
-#define nfserr_mlink __constant_htonl(NFSERR_MLINK)
-#define nfserr_opnotsupp __constant_htonl(NFSERR_OPNOTSUPP)
-#define nfserr_nametoolong __constant_htonl(NFSERR_NAMETOOLONG)
-#define nfserr_notempty __constant_htonl(NFSERR_NOTEMPTY)
-#define nfserr_dquot __constant_htonl(NFSERR_DQUOT)
-#define nfserr_stale __constant_htonl(NFSERR_STALE)
-#define nfserr_remote __constant_htonl(NFSERR_REMOTE)
-#define nfserr_wflush __constant_htonl(NFSERR_WFLUSH)
-#define nfserr_badhandle __constant_htonl(NFSERR_BADHANDLE)
-#define nfserr_notsync __constant_htonl(NFSERR_NOT_SYNC)
-#define nfserr_badcookie __constant_htonl(NFSERR_BAD_COOKIE)
-#define nfserr_notsupp __constant_htonl(NFSERR_NOTSUPP)
-#define nfserr_toosmall __constant_htonl(NFSERR_TOOSMALL)
-#define nfserr_serverfault __constant_htonl(NFSERR_SERVERFAULT)
-#define nfserr_badtype __constant_htonl(NFSERR_BADTYPE)
-#define nfserr_jukebox __constant_htonl(NFSERR_JUKEBOX)
-#define nfserr_denied __constant_htonl(NFSERR_DENIED)
-#define nfserr_deadlock __constant_htonl(NFSERR_DEADLOCK)
-#define nfserr_expired __constant_htonl(NFSERR_EXPIRED)
-#define nfserr_bad_cookie __constant_htonl(NFSERR_BAD_COOKIE)
-#define nfserr_same __constant_htonl(NFSERR_SAME)
-#define nfserr_clid_inuse __constant_htonl(NFSERR_CLID_INUSE)
-#define nfserr_stale_clientid __constant_htonl(NFSERR_STALE_CLIENTID)
-#define nfserr_resource __constant_htonl(NFSERR_RESOURCE)
-#define nfserr_moved __constant_htonl(NFSERR_MOVED)
-#define nfserr_nofilehandle __constant_htonl(NFSERR_NOFILEHANDLE)
-#define nfserr_minor_vers_mismatch __constant_htonl(NFSERR_MINOR_VERS_MISMATCH)
-#define nfserr_share_denied __constant_htonl(NFSERR_SHARE_DENIED)
-#define nfserr_stale_stateid __constant_htonl(NFSERR_STALE_STATEID)
-#define nfserr_old_stateid __constant_htonl(NFSERR_OLD_STATEID)
-#define nfserr_bad_stateid __constant_htonl(NFSERR_BAD_STATEID)
-#define nfserr_bad_seqid __constant_htonl(NFSERR_BAD_SEQID)
-#define nfserr_symlink __constant_htonl(NFSERR_SYMLINK)
-#define nfserr_not_same __constant_htonl(NFSERR_NOT_SAME)
-#define nfserr_restorefh __constant_htonl(NFSERR_RESTOREFH)
-#define nfserr_attrnotsupp __constant_htonl(NFSERR_ATTRNOTSUPP)
-#define nfserr_bad_xdr __constant_htonl(NFSERR_BAD_XDR)
-#define nfserr_openmode __constant_htonl(NFSERR_OPENMODE)
-#define nfserr_locks_held __constant_htonl(NFSERR_LOCKS_HELD)
-#define nfserr_op_illegal __constant_htonl(NFSERR_OP_ILLEGAL)
-#define nfserr_grace __constant_htonl(NFSERR_GRACE)
-#define nfserr_no_grace __constant_htonl(NFSERR_NO_GRACE)
-#define nfserr_reclaim_bad __constant_htonl(NFSERR_RECLAIM_BAD)
-#define nfserr_badname __constant_htonl(NFSERR_BADNAME)
-#define nfserr_cb_path_down __constant_htonl(NFSERR_CB_PATH_DOWN)
-#define nfserr_locked __constant_htonl(NFSERR_LOCKED)
-#define nfserr_wrongsec __constant_htonl(NFSERR_WRONGSEC)
-#define nfserr_replay_me __constant_htonl(NFSERR_REPLAY_ME)
+#define nfs_ok cpu_to_be32(NFS_OK)
+#define nfserr_perm cpu_to_be32(NFSERR_PERM)
+#define nfserr_noent cpu_to_be32(NFSERR_NOENT)
+#define nfserr_io cpu_to_be32(NFSERR_IO)
+#define nfserr_nxio cpu_to_be32(NFSERR_NXIO)
+#define nfserr_eagain cpu_to_be32(NFSERR_EAGAIN)
+#define nfserr_acces cpu_to_be32(NFSERR_ACCES)
+#define nfserr_exist cpu_to_be32(NFSERR_EXIST)
+#define nfserr_xdev cpu_to_be32(NFSERR_XDEV)
+#define nfserr_nodev cpu_to_be32(NFSERR_NODEV)
+#define nfserr_notdir cpu_to_be32(NFSERR_NOTDIR)
+#define nfserr_isdir cpu_to_be32(NFSERR_ISDIR)
+#define nfserr_inval cpu_to_be32(NFSERR_INVAL)
+#define nfserr_fbig cpu_to_be32(NFSERR_FBIG)
+#define nfserr_nospc cpu_to_be32(NFSERR_NOSPC)
+#define nfserr_rofs cpu_to_be32(NFSERR_ROFS)
+#define nfserr_mlink cpu_to_be32(NFSERR_MLINK)
+#define nfserr_opnotsupp cpu_to_be32(NFSERR_OPNOTSUPP)
+#define nfserr_nametoolong cpu_to_be32(NFSERR_NAMETOOLONG)
+#define nfserr_notempty cpu_to_be32(NFSERR_NOTEMPTY)
+#define nfserr_dquot cpu_to_be32(NFSERR_DQUOT)
+#define nfserr_stale cpu_to_be32(NFSERR_STALE)
+#define nfserr_remote cpu_to_be32(NFSERR_REMOTE)
+#define nfserr_wflush cpu_to_be32(NFSERR_WFLUSH)
+#define nfserr_badhandle cpu_to_be32(NFSERR_BADHANDLE)
+#define nfserr_notsync cpu_to_be32(NFSERR_NOT_SYNC)
+#define nfserr_badcookie cpu_to_be32(NFSERR_BAD_COOKIE)
+#define nfserr_notsupp cpu_to_be32(NFSERR_NOTSUPP)
+#define nfserr_toosmall cpu_to_be32(NFSERR_TOOSMALL)
+#define nfserr_serverfault cpu_to_be32(NFSERR_SERVERFAULT)
+#define nfserr_badtype cpu_to_be32(NFSERR_BADTYPE)
+#define nfserr_jukebox cpu_to_be32(NFSERR_JUKEBOX)
+#define nfserr_denied cpu_to_be32(NFSERR_DENIED)
+#define nfserr_deadlock cpu_to_be32(NFSERR_DEADLOCK)
+#define nfserr_expired cpu_to_be32(NFSERR_EXPIRED)
+#define nfserr_bad_cookie cpu_to_be32(NFSERR_BAD_COOKIE)
+#define nfserr_same cpu_to_be32(NFSERR_SAME)
+#define nfserr_clid_inuse cpu_to_be32(NFSERR_CLID_INUSE)
+#define nfserr_stale_clientid cpu_to_be32(NFSERR_STALE_CLIENTID)
+#define nfserr_resource cpu_to_be32(NFSERR_RESOURCE)
+#define nfserr_moved cpu_to_be32(NFSERR_MOVED)
+#define nfserr_nofilehandle cpu_to_be32(NFSERR_NOFILEHANDLE)
+#define nfserr_minor_vers_mismatch cpu_to_be32(NFSERR_MINOR_VERS_MISMATCH)
+#define nfserr_share_denied cpu_to_be32(NFSERR_SHARE_DENIED)
+#define nfserr_stale_stateid cpu_to_be32(NFSERR_STALE_STATEID)
+#define nfserr_old_stateid cpu_to_be32(NFSERR_OLD_STATEID)
+#define nfserr_bad_stateid cpu_to_be32(NFSERR_BAD_STATEID)
+#define nfserr_bad_seqid cpu_to_be32(NFSERR_BAD_SEQID)
+#define nfserr_symlink cpu_to_be32(NFSERR_SYMLINK)
+#define nfserr_not_same cpu_to_be32(NFSERR_NOT_SAME)
+#define nfserr_restorefh cpu_to_be32(NFSERR_RESTOREFH)
+#define nfserr_attrnotsupp cpu_to_be32(NFSERR_ATTRNOTSUPP)
+#define nfserr_bad_xdr cpu_to_be32(NFSERR_BAD_XDR)
+#define nfserr_openmode cpu_to_be32(NFSERR_OPENMODE)
+#define nfserr_locks_held cpu_to_be32(NFSERR_LOCKS_HELD)
+#define nfserr_op_illegal cpu_to_be32(NFSERR_OP_ILLEGAL)
+#define nfserr_grace cpu_to_be32(NFSERR_GRACE)
+#define nfserr_no_grace cpu_to_be32(NFSERR_NO_GRACE)
+#define nfserr_reclaim_bad cpu_to_be32(NFSERR_RECLAIM_BAD)
+#define nfserr_badname cpu_to_be32(NFSERR_BADNAME)
+#define nfserr_cb_path_down cpu_to_be32(NFSERR_CB_PATH_DOWN)
+#define nfserr_locked cpu_to_be32(NFSERR_LOCKED)
+#define nfserr_wrongsec cpu_to_be32(NFSERR_WRONGSEC)
+#define nfserr_badiomode cpu_to_be32(NFS4ERR_BADIOMODE)
+#define nfserr_badlayout cpu_to_be32(NFS4ERR_BADLAYOUT)
+#define nfserr_bad_session_digest cpu_to_be32(NFS4ERR_BAD_SESSION_DIGEST)
+#define nfserr_badsession cpu_to_be32(NFS4ERR_BADSESSION)
+#define nfserr_badslot cpu_to_be32(NFS4ERR_BADSLOT)
+#define nfserr_complete_already cpu_to_be32(NFS4ERR_COMPLETE_ALREADY)
+#define nfserr_conn_not_bound_to_session cpu_to_be32(NFS4ERR_CONN_NOT_BOUND_TO_SESSION)
+#define nfserr_deleg_already_wanted cpu_to_be32(NFS4ERR_DELEG_ALREADY_WANTED)
+#define nfserr_back_chan_busy cpu_to_be32(NFS4ERR_BACK_CHAN_BUSY)
+#define nfserr_layouttrylater cpu_to_be32(NFS4ERR_LAYOUTTRYLATER)
+#define nfserr_layoutunavailable cpu_to_be32(NFS4ERR_LAYOUTUNAVAILABLE)
+#define nfserr_nomatching_layout cpu_to_be32(NFS4ERR_NOMATCHING_LAYOUT)
+#define nfserr_recallconflict cpu_to_be32(NFS4ERR_RECALLCONFLICT)
+#define nfserr_unknown_layouttype cpu_to_be32(NFS4ERR_UNKNOWN_LAYOUTTYPE)
+#define nfserr_seq_misordered cpu_to_be32(NFS4ERR_SEQ_MISORDERED)
+#define nfserr_sequence_pos cpu_to_be32(NFS4ERR_SEQUENCE_POS)
+#define nfserr_req_too_big cpu_to_be32(NFS4ERR_REQ_TOO_BIG)
+#define nfserr_rep_too_big cpu_to_be32(NFS4ERR_REP_TOO_BIG)
+#define nfserr_rep_too_big_to_cache cpu_to_be32(NFS4ERR_REP_TOO_BIG_TO_CACHE)
+#define nfserr_retry_uncached_rep cpu_to_be32(NFS4ERR_RETRY_UNCACHED_REP)
+#define nfserr_unsafe_compound cpu_to_be32(NFS4ERR_UNSAFE_COMPOUND)
+#define nfserr_too_many_ops cpu_to_be32(NFS4ERR_TOO_MANY_OPS)
+#define nfserr_op_not_in_session cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION)
+#define nfserr_hash_alg_unsupp cpu_to_be32(NFS4ERR_HASH_ALG_UNSUPP)
+#define nfserr_clientid_busy cpu_to_be32(NFS4ERR_CLIENTID_BUSY)
+#define nfserr_pnfs_io_hole cpu_to_be32(NFS4ERR_PNFS_IO_HOLE)
+#define nfserr_seq_false_retry cpu_to_be32(NFS4ERR_SEQ_FALSE_RETRY)
+#define nfserr_bad_high_slot cpu_to_be32(NFS4ERR_BAD_HIGH_SLOT)
+#define nfserr_deadsession cpu_to_be32(NFS4ERR_DEADSESSION)
+#define nfserr_encr_alg_unsupp cpu_to_be32(NFS4ERR_ENCR_ALG_UNSUPP)
+#define nfserr_pnfs_no_layout cpu_to_be32(NFS4ERR_PNFS_NO_LAYOUT)
+#define nfserr_not_only_op cpu_to_be32(NFS4ERR_NOT_ONLY_OP)
+#define nfserr_wrong_cred cpu_to_be32(NFS4ERR_WRONG_CRED)
+#define nfserr_wrong_type cpu_to_be32(NFS4ERR_WRONG_TYPE)
+#define nfserr_dirdeleg_unavail cpu_to_be32(NFS4ERR_DIRDELEG_UNAVAIL)
+#define nfserr_reject_deleg cpu_to_be32(NFS4ERR_REJECT_DELEG)
+#define nfserr_returnconflict cpu_to_be32(NFS4ERR_RETURNCONFLICT)
+#define nfserr_deleg_revoked cpu_to_be32(NFS4ERR_DELEG_REVOKED)
/* error codes for internal use */
/* if a request fails due to kmalloc failure, it gets dropped.
* Client should resend eventually
*/
-#define nfserr_dropit __constant_htonl(30000)
+#define nfserr_dropit cpu_to_be32(30000)
/* end-of-file indicator in readdir */
-#define nfserr_eof __constant_htonl(30001)
+#define nfserr_eof cpu_to_be32(30001)
+/* replay detected */
+#define nfserr_replay_me cpu_to_be32(11001)
+/* nfs41 replay detected */
+#define nfserr_replay_cache cpu_to_be32(11002)
/* Check for dir entries '.' and '..' */
#define isdotent(n, l) (l < 3 && n[0] == '.' && (l == 1 || n[1] == '.'))
@@ -300,7 +343,7 @@ extern struct timeval nfssvc_boot;
* TIME_BACKUP (unlikely to be supported any time soon)
* TIME_CREATE (unlikely to be supported any time soon)
*/
-#define NFSD_SUPPORTED_ATTRS_WORD0 \
+#define NFSD4_SUPPORTED_ATTRS_WORD0 \
(FATTR4_WORD0_SUPPORTED_ATTRS | FATTR4_WORD0_TYPE | FATTR4_WORD0_FH_EXPIRE_TYPE \
| FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE | FATTR4_WORD0_LINK_SUPPORT \
| FATTR4_WORD0_SYMLINK_SUPPORT | FATTR4_WORD0_NAMED_ATTR | FATTR4_WORD0_FSID \
@@ -312,7 +355,7 @@ extern struct timeval nfssvc_boot;
| FATTR4_WORD0_MAXFILESIZE | FATTR4_WORD0_MAXLINK | FATTR4_WORD0_MAXNAME \
| FATTR4_WORD0_MAXREAD | FATTR4_WORD0_MAXWRITE | FATTR4_WORD0_ACL)
-#define NFSD_SUPPORTED_ATTRS_WORD1 \
+#define NFSD4_SUPPORTED_ATTRS_WORD1 \
(FATTR4_WORD1_MODE | FATTR4_WORD1_NO_TRUNC | FATTR4_WORD1_NUMLINKS \
| FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP | FATTR4_WORD1_RAWDEV \
| FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL \
@@ -320,6 +363,35 @@ extern struct timeval nfssvc_boot;
| FATTR4_WORD1_TIME_DELTA | FATTR4_WORD1_TIME_METADATA \
| FATTR4_WORD1_TIME_MODIFY | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_MOUNTED_ON_FILEID)
+#define NFSD4_SUPPORTED_ATTRS_WORD2 0
+
+#define NFSD4_1_SUPPORTED_ATTRS_WORD0 \
+ NFSD4_SUPPORTED_ATTRS_WORD0
+
+#define NFSD4_1_SUPPORTED_ATTRS_WORD1 \
+ NFSD4_SUPPORTED_ATTRS_WORD1
+
+#define NFSD4_1_SUPPORTED_ATTRS_WORD2 \
+ (NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT)
+
+static inline u32 nfsd_suppattrs0(u32 minorversion)
+{
+ return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0
+ : NFSD4_SUPPORTED_ATTRS_WORD0;
+}
+
+static inline u32 nfsd_suppattrs1(u32 minorversion)
+{
+ return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD1
+ : NFSD4_SUPPORTED_ATTRS_WORD1;
+}
+
+static inline u32 nfsd_suppattrs2(u32 minorversion)
+{
+ return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD2
+ : NFSD4_SUPPORTED_ATTRS_WORD2;
+}
+
/* These will return ERR_INVAL if specified in GETATTR or READDIR. */
#define NFSD_WRITEONLY_ATTRS_WORD1 \
(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
@@ -330,6 +402,19 @@ extern struct timeval nfssvc_boot;
#define NFSD_WRITEABLE_ATTRS_WORD1 \
(FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \
| FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
+#define NFSD_WRITEABLE_ATTRS_WORD2 0
+
+#define NFSD_SUPPATTR_EXCLCREAT_WORD0 \
+ NFSD_WRITEABLE_ATTRS_WORD0
+/*
+ * we currently store the exclusive create verifier in the v_{a,m}time
+ * attributes so the client can't set these at create time using EXCLUSIVE4_1
+ */
+#define NFSD_SUPPATTR_EXCLCREAT_WORD1 \
+ (NFSD_WRITEABLE_ATTRS_WORD1 & \
+ ~(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET))
+#define NFSD_SUPPATTR_EXCLCREAT_WORD2 \
+ NFSD_WRITEABLE_ATTRS_WORD2
#endif /* CONFIG_NFSD_V4 */
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h
index fa317f6c154..afa19016c4a 100644
--- a/include/linux/nfsd/nfsfh.h
+++ b/include/linux/nfsd/nfsfh.h
@@ -269,6 +269,13 @@ fh_copy(struct svc_fh *dst, struct svc_fh *src)
return dst;
}
+static inline void
+fh_copy_shallow(struct knfsd_fh *dst, struct knfsd_fh *src)
+{
+ dst->fh_size = src->fh_size;
+ memcpy(&dst->fh_base, &src->fh_base, src->fh_size);
+}
+
static __inline__ struct svc_fh *
fh_init(struct svc_fh *fhp, int maxsize)
{
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
index 128298c0362..4d61c873fee 100644
--- a/include/linux/nfsd/state.h
+++ b/include/linux/nfsd/state.h
@@ -66,8 +66,7 @@ struct nfs4_cb_recall {
u32 cbr_ident;
int cbr_trunc;
stateid_t cbr_stateid;
- u32 cbr_fhlen;
- char cbr_fhval[NFS4_FHSIZE];
+ struct knfsd_fh cbr_fh;
struct nfs4_delegation *cbr_dp;
};
@@ -86,8 +85,7 @@ struct nfs4_delegation {
};
#define dl_stateid dl_recall.cbr_stateid
-#define dl_fhlen dl_recall.cbr_fhlen
-#define dl_fhval dl_recall.cbr_fhval
+#define dl_fh dl_recall.cbr_fh
/* client delegation callback info */
struct nfs4_callback {
@@ -101,6 +99,64 @@ struct nfs4_callback {
struct rpc_clnt * cb_client;
};
+/* Maximum number of slots per session. 128 is useful for long haul TCP */
+#define NFSD_MAX_SLOTS_PER_SESSION 128
+/* Maximum number of pages per slot cache entry */
+#define NFSD_PAGES_PER_SLOT 1
+/* Maximum number of operations per session compound */
+#define NFSD_MAX_OPS_PER_COMPOUND 16
+
+struct nfsd4_cache_entry {
+ __be32 ce_status;
+ struct kvec ce_datav; /* encoded NFSv4.1 data in rq_res.head[0] */
+ struct page *ce_respages[NFSD_PAGES_PER_SLOT + 1];
+ int ce_cachethis;
+ short ce_resused;
+ int ce_opcnt;
+ int ce_rpchdrlen;
+};
+
+struct nfsd4_slot {
+ bool sl_inuse;
+ u32 sl_seqid;
+ struct nfsd4_cache_entry sl_cache_entry;
+};
+
+struct nfsd4_session {
+ struct kref se_ref;
+ struct list_head se_hash; /* hash by sessionid */
+ struct list_head se_perclnt;
+ u32 se_flags;
+ struct nfs4_client *se_client; /* for expire_client */
+ struct nfs4_sessionid se_sessionid;
+ u32 se_fmaxreq_sz;
+ u32 se_fmaxresp_sz;
+ u32 se_fmaxresp_cached;
+ u32 se_fmaxops;
+ u32 se_fnumslots;
+ struct nfsd4_slot se_slots[]; /* forward channel slots */
+};
+
+static inline void
+nfsd4_put_session(struct nfsd4_session *ses)
+{
+ extern void free_session(struct kref *kref);
+ kref_put(&ses->se_ref, free_session);
+}
+
+static inline void
+nfsd4_get_session(struct nfsd4_session *ses)
+{
+ kref_get(&ses->se_ref);
+}
+
+/* formatted contents of nfs4_sessionid */
+struct nfsd4_sessionid {
+ clientid_t clientid;
+ u32 sequence;
+ u32 reserved;
+};
+
#define HEXDIR_LEN 33 /* hex version of 16 byte md5 of cl_name plus '\0' */
/*
@@ -132,6 +188,12 @@ struct nfs4_client {
struct nfs4_callback cl_callback; /* callback info */
atomic_t cl_count; /* ref count */
u32 cl_firststate; /* recovery dir creation */
+
+ /* for nfs41 */
+ struct list_head cl_sessions;
+ struct nfsd4_slot cl_slot; /* create_session slot */
+ u32 cl_exchange_flags;
+ struct nfs4_sessionid cl_sessionid;
};
/* struct nfs4_client_reset
@@ -168,8 +230,7 @@ struct nfs4_replay {
unsigned int rp_buflen;
char *rp_buf;
unsigned intrp_allocated;
- int rp_openfh_len;
- char rp_openfh[NFS4_FHSIZE];
+ struct knfsd_fh rp_openfh;
char rp_ibuf[NFSD4_REPLAY_ISIZE];
};
@@ -217,7 +278,7 @@ struct nfs4_stateowner {
* share_acces, share_deny on the file.
*/
struct nfs4_file {
- struct kref fi_ref;
+ atomic_t fi_ref;
struct list_head fi_hash; /* hash by "struct inode *" */
struct list_head fi_stateids;
struct list_head fi_delegations;
@@ -259,14 +320,13 @@ struct nfs4_stateid {
};
/* flags for preprocess_seqid_op() */
-#define CHECK_FH 0x00000001
+#define HAS_SESSION 0x00000001
#define CONFIRM 0x00000002
#define OPEN_STATE 0x00000004
#define LOCK_STATE 0x00000008
#define RD_STATE 0x00000010
#define WR_STATE 0x00000020
#define CLOSE_STATE 0x00000040
-#define DELEG_RET 0x00000080
#define seqid_mutating_err(err) \
(((err) != nfserr_stale_clientid) && \
@@ -274,7 +334,9 @@ struct nfs4_stateid {
((err) != nfserr_stale_stateid) && \
((err) != nfserr_bad_stateid))
-extern __be32 nfs4_preprocess_stateid_op(struct svc_fh *current_fh,
+struct nfsd4_compound_state;
+
+extern __be32 nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
stateid_t *stateid, int flags, struct file **filp);
extern void nfs4_lock_state(void);
extern void nfs4_unlock_state(void);
@@ -290,7 +352,7 @@ extern void nfsd4_init_recdir(char *recdir_name);
extern int nfsd4_recdir_load(void);
extern void nfsd4_shutdown_recdir(void);
extern int nfs4_client_to_reclaim(const char *name);
-extern int nfs4_has_reclaimed_state(const char *name);
+extern int nfs4_has_reclaimed_state(const char *name, bool use_exchange_id);
extern void nfsd4_recdir_purge_old(void);
extern int nfsd4_create_clid_dir(struct nfs4_client *clp);
extern void nfsd4_remove_clid_dir(struct nfs4_client *clp);
diff --git a/include/linux/nfsd/stats.h b/include/linux/nfsd/stats.h
index 7678cfbe996..2693ef647df 100644
--- a/include/linux/nfsd/stats.h
+++ b/include/linux/nfsd/stats.h
@@ -11,6 +11,11 @@
#include <linux/nfs4.h>
+/* thread usage wraps very million seconds (approx one fortnight) */
+#define NFSD_USAGE_WRAP (HZ*1000000)
+
+#ifdef __KERNEL__
+
struct nfsd_stats {
unsigned int rchits; /* repcache hits */
unsigned int rcmisses; /* repcache hits */
@@ -35,10 +40,6 @@ struct nfsd_stats {
};
-/* thread usage wraps very million seconds (approx one fortnight) */
-#define NFSD_USAGE_WRAP (HZ*1000000)
-
-#ifdef __KERNEL__
extern struct nfsd_stats nfsdstats;
extern struct svc_stat nfsd_svcstats;
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index 27bd3e38ec5..f80d6013fdc 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -45,10 +45,22 @@
#define XDR_LEN(n) (((n) + 3) & ~3)
struct nfsd4_compound_state {
- struct svc_fh current_fh;
- struct svc_fh save_fh;
- struct nfs4_stateowner *replay_owner;
-};
+ struct svc_fh current_fh;
+ struct svc_fh save_fh;
+ struct nfs4_stateowner *replay_owner;
+ /* For sessions DRC */
+ struct nfsd4_session *session;
+ struct nfsd4_slot *slot;
+ __be32 *statp;
+ size_t iovlen;
+ u32 minorversion;
+ u32 status;
+};
+
+static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs)
+{
+ return cs->slot != NULL;
+}
struct nfsd4_change_info {
u32 atomic;
@@ -90,7 +102,7 @@ struct nfsd4_create {
u32 specdata2;
} dev; /* NF4BLK, NF4CHR */
} u;
- u32 cr_bmval[2]; /* request */
+ u32 cr_bmval[3]; /* request */
struct iattr cr_iattr; /* request */
struct nfsd4_change_info cr_cinfo; /* response */
struct nfs4_acl *cr_acl;
@@ -105,7 +117,7 @@ struct nfsd4_delegreturn {
};
struct nfsd4_getattr {
- u32 ga_bmval[2]; /* request */
+ u32 ga_bmval[3]; /* request */
struct svc_fh *ga_fhp; /* response */
};
@@ -206,11 +218,9 @@ struct nfsd4_open {
stateid_t op_delegate_stateid; /* request - response */
u32 op_create; /* request */
u32 op_createmode; /* request */
- u32 op_bmval[2]; /* request */
- union { /* request */
- struct iattr iattr; /* UNCHECKED4,GUARDED4 */
- nfs4_verifier verf; /* EXCLUSIVE4 */
- } u;
+ u32 op_bmval[3]; /* request */
+ struct iattr iattr; /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */
+ nfs4_verifier verf; /* EXCLUSIVE4 */
clientid_t op_clientid; /* request */
struct xdr_netobj op_owner; /* request */
u32 op_seqid; /* request */
@@ -224,8 +234,8 @@ struct nfsd4_open {
struct nfs4_stateowner *op_stateowner; /* used during processing */
struct nfs4_acl *op_acl;
};
-#define op_iattr u.iattr
-#define op_verf u.verf
+#define op_iattr iattr
+#define op_verf verf
struct nfsd4_open_confirm {
stateid_t oc_req_stateid /* request */;
@@ -259,7 +269,7 @@ struct nfsd4_readdir {
nfs4_verifier rd_verf; /* request */
u32 rd_dircount; /* request */
u32 rd_maxcount; /* request */
- u32 rd_bmval[2]; /* request */
+ u32 rd_bmval[3]; /* request */
struct svc_rqst *rd_rqstp; /* response */
struct svc_fh * rd_fhp; /* response */
@@ -301,7 +311,7 @@ struct nfsd4_secinfo {
struct nfsd4_setattr {
stateid_t sa_stateid; /* request */
- u32 sa_bmval[2]; /* request */
+ u32 sa_bmval[3]; /* request */
struct iattr sa_iattr; /* request */
struct nfs4_acl *sa_acl;
};
@@ -327,7 +337,7 @@ struct nfsd4_setclientid_confirm {
/* also used for NVERIFY */
struct nfsd4_verify {
- u32 ve_bmval[2]; /* request */
+ u32 ve_bmval[3]; /* request */
u32 ve_attrlen; /* request */
char * ve_attrval; /* request */
};
@@ -344,6 +354,54 @@ struct nfsd4_write {
nfs4_verifier wr_verifier; /* response */
};
+struct nfsd4_exchange_id {
+ nfs4_verifier verifier;
+ struct xdr_netobj clname;
+ u32 flags;
+ clientid_t clientid;
+ u32 seqid;
+ int spa_how;
+};
+
+struct nfsd4_channel_attrs {
+ u32 headerpadsz;
+ u32 maxreq_sz;
+ u32 maxresp_sz;
+ u32 maxresp_cached;
+ u32 maxops;
+ u32 maxreqs;
+ u32 nr_rdma_attrs;
+ u32 rdma_attrs;
+};
+
+struct nfsd4_create_session {
+ clientid_t clientid;
+ struct nfs4_sessionid sessionid;
+ u32 seqid;
+ u32 flags;
+ struct nfsd4_channel_attrs fore_channel;
+ struct nfsd4_channel_attrs back_channel;
+ u32 callback_prog;
+ u32 uid;
+ u32 gid;
+};
+
+struct nfsd4_sequence {
+ struct nfs4_sessionid sessionid; /* request/response */
+ u32 seqid; /* request/response */
+ u32 slotid; /* request/response */
+ u32 maxslots; /* request/response */
+ u32 cachethis; /* request */
+#if 0
+ u32 target_maxslots; /* response */
+ u32 status_flags; /* response */
+#endif /* not yet */
+};
+
+struct nfsd4_destroy_session {
+ struct nfs4_sessionid sessionid;
+};
+
struct nfsd4_op {
int opnum;
__be32 status;
@@ -378,6 +436,12 @@ struct nfsd4_op {
struct nfsd4_verify verify;
struct nfsd4_write write;
struct nfsd4_release_lockowner release_lockowner;
+
+ /* NFSv4.1 */
+ struct nfsd4_exchange_id exchange_id;
+ struct nfsd4_create_session create_session;
+ struct nfsd4_destroy_session destroy_session;
+ struct nfsd4_sequence sequence;
} u;
struct nfs4_replay * replay;
};
@@ -416,9 +480,22 @@ struct nfsd4_compoundres {
u32 taglen;
char * tag;
u32 opcnt;
- __be32 * tagp; /* where to encode tag and opcount */
+ __be32 * tagp; /* tag, opcount encode location */
+ struct nfsd4_compound_state cstate;
};
+static inline bool nfsd4_is_solo_sequence(struct nfsd4_compoundres *resp)
+{
+ struct nfsd4_compoundargs *args = resp->rqstp->rq_argp;
+ return args->opcnt == 1;
+}
+
+static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp)
+{
+ return !resp->cstate.slot->sl_cache_entry.ce_cachethis ||
+ nfsd4_is_solo_sequence(resp);
+}
+
#define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs)
static inline void
@@ -448,7 +525,23 @@ extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp,
extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
struct nfsd4_compound_state *,
struct nfsd4_setclientid_confirm *setclientid_confirm);
-extern __be32 nfsd4_process_open1(struct nfsd4_open *open);
+extern void nfsd4_store_cache_entry(struct nfsd4_compoundres *resp);
+extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
+ struct nfsd4_sequence *seq);
+extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
+ struct nfsd4_compound_state *,
+struct nfsd4_exchange_id *);
+ extern __be32 nfsd4_create_session(struct svc_rqst *,
+ struct nfsd4_compound_state *,
+ struct nfsd4_create_session *);
+extern __be32 nfsd4_sequence(struct svc_rqst *,
+ struct nfsd4_compound_state *,
+ struct nfsd4_sequence *);
+extern __be32 nfsd4_destroy_session(struct svc_rqst *,
+ struct nfsd4_compound_state *,
+ struct nfsd4_destroy_session *);
+extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *,
+ struct nfsd4_open *open);
extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
struct svc_fh *current_fh, struct nfsd4_open *open);
extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h
new file mode 100644
index 00000000000..79fec6af3f9
--- /dev/null
+++ b/include/linux/nilfs2_fs.h
@@ -0,0 +1,801 @@
+/*
+ * nilfs2_fs.h - NILFS2 on-disk structures and common declarations.
+ *
+ * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Written by Koji Sato <koji@osrg.net>
+ * Ryusuke Konishi <ryusuke@osrg.net>
+ */
+/*
+ * linux/include/linux/ext2_fs.h
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ * from
+ *
+ * linux/include/linux/minix_fs.h
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+#ifndef _LINUX_NILFS_FS_H
+#define _LINUX_NILFS_FS_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+/*
+ * Inode flags stored in nilfs_inode and on-memory nilfs inode
+ *
+ * We define these flags based on ext2-fs because of the
+ * compatibility reason; to avoid problems in chattr(1)
+ */
+#define NILFS_SECRM_FL 0x00000001 /* Secure deletion */
+#define NILFS_UNRM_FL 0x00000002 /* Undelete */
+#define NILFS_SYNC_FL 0x00000008 /* Synchronous updates */
+#define NILFS_IMMUTABLE_FL 0x00000010 /* Immutable file */
+#define NILFS_APPEND_FL 0x00000020 /* writes to file may only append */
+#define NILFS_NODUMP_FL 0x00000040 /* do not dump file */
+#define NILFS_NOATIME_FL 0x00000080 /* do not update atime */
+/* Reserved for compression usage... */
+#define NILFS_NOTAIL_FL 0x00008000 /* file tail should not be merged */
+#define NILFS_DIRSYNC_FL 0x00010000 /* dirsync behaviour */
+
+#define NILFS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
+#define NILFS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
+
+
+#define NILFS_INODE_BMAP_SIZE 7
+/**
+ * struct nilfs_inode - structure of an inode on disk
+ * @i_blocks: blocks count
+ * @i_size: size in bytes
+ * @i_ctime: creation time (seconds)
+ * @i_mtime: modification time (seconds)
+ * @i_ctime_nsec: creation time (nano seconds)
+ * @i_mtime_nsec: modification time (nano seconds)
+ * @i_uid: user id
+ * @i_gid: group id
+ * @i_mode: file mode
+ * @i_links_count: links count
+ * @i_flags: file flags
+ * @i_bmap: block mapping
+ * @i_xattr: extended attributes
+ * @i_generation: file generation (for NFS)
+ * @i_pad: padding
+ */
+struct nilfs_inode {
+ __le64 i_blocks;
+ __le64 i_size;
+ __le64 i_ctime;
+ __le64 i_mtime;
+ __le32 i_ctime_nsec;
+ __le32 i_mtime_nsec;
+ __le32 i_uid;
+ __le32 i_gid;
+ __le16 i_mode;
+ __le16 i_links_count;
+ __le32 i_flags;
+ __le64 i_bmap[NILFS_INODE_BMAP_SIZE];
+#define i_device_code i_bmap[0]
+ __le64 i_xattr;
+ __le32 i_generation;
+ __le32 i_pad;
+};
+
+/**
+ * struct nilfs_super_root - structure of super root
+ * @sr_sum: check sum
+ * @sr_bytes: byte count of the structure
+ * @sr_flags: flags (reserved)
+ * @sr_nongc_ctime: write time of the last segment not for cleaner operation
+ * @sr_dat: DAT file inode
+ * @sr_cpfile: checkpoint file inode
+ * @sr_sufile: segment usage file inode
+ */
+struct nilfs_super_root {
+ __le32 sr_sum;
+ __le16 sr_bytes;
+ __le16 sr_flags;
+ __le64 sr_nongc_ctime;
+ struct nilfs_inode sr_dat;
+ struct nilfs_inode sr_cpfile;
+ struct nilfs_inode sr_sufile;
+};
+
+#define NILFS_SR_MDT_OFFSET(inode_size, i) \
+ ((unsigned long)&((struct nilfs_super_root *)0)->sr_dat + \
+ (inode_size) * (i))
+#define NILFS_SR_DAT_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 0)
+#define NILFS_SR_CPFILE_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 1)
+#define NILFS_SR_SUFILE_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 2)
+#define NILFS_SR_BYTES (sizeof(struct nilfs_super_root))
+
+/*
+ * Maximal mount counts
+ */
+#define NILFS_DFL_MAX_MNT_COUNT 50 /* 50 mounts */
+
+/*
+ * File system states (sbp->s_state, nilfs->ns_mount_state)
+ */
+#define NILFS_VALID_FS 0x0001 /* Unmounted cleanly */
+#define NILFS_ERROR_FS 0x0002 /* Errors detected */
+#define NILFS_RESIZE_FS 0x0004 /* Resize required */
+
+/*
+ * Mount flags (sbi->s_mount_opt)
+ */
+#define NILFS_MOUNT_ERROR_MODE 0x0070 /* Error mode mask */
+#define NILFS_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */
+#define NILFS_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */
+#define NILFS_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */
+#define NILFS_MOUNT_SNAPSHOT 0x0080 /* Snapshot flag */
+#define NILFS_MOUNT_BARRIER 0x1000 /* Use block barriers */
+#define NILFS_MOUNT_STRICT_ORDER 0x2000 /* Apply strict in-order
+ semantics also for data */
+
+
+/**
+ * struct nilfs_super_block - structure of super block on disk
+ */
+struct nilfs_super_block {
+ __le32 s_rev_level; /* Revision level */
+ __le16 s_minor_rev_level; /* minor revision level */
+ __le16 s_magic; /* Magic signature */
+
+ __le16 s_bytes; /* Bytes count of CRC calculation
+ for this structure. s_reserved
+ is excluded. */
+ __le16 s_flags; /* flags */
+ __le32 s_crc_seed; /* Seed value of CRC calculation */
+ __le32 s_sum; /* Check sum of super block */
+
+ __le32 s_log_block_size; /* Block size represented as follows
+ blocksize =
+ 1 << (s_log_block_size + 10) */
+ __le64 s_nsegments; /* Number of segments in filesystem */
+ __le64 s_dev_size; /* block device size in bytes */
+ __le64 s_first_data_block; /* 1st seg disk block number */
+ __le32 s_blocks_per_segment; /* number of blocks per full segment */
+ __le32 s_r_segments_percentage; /* Reserved segments percentage */
+
+ __le64 s_last_cno; /* Last checkpoint number */
+ __le64 s_last_pseg; /* disk block addr pseg written last */
+ __le64 s_last_seq; /* seq. number of seg written last */
+ __le64 s_free_blocks_count; /* Free blocks count */
+
+ __le64 s_ctime; /* Creation time (execution time of
+ newfs) */
+ __le64 s_mtime; /* Mount time */
+ __le64 s_wtime; /* Write time */
+ __le16 s_mnt_count; /* Mount count */
+ __le16 s_max_mnt_count; /* Maximal mount count */
+ __le16 s_state; /* File system state */
+ __le16 s_errors; /* Behaviour when detecting errors */
+ __le64 s_lastcheck; /* time of last check */
+
+ __le32 s_checkinterval; /* max. time between checks */
+ __le32 s_creator_os; /* OS */
+ __le16 s_def_resuid; /* Default uid for reserved blocks */
+ __le16 s_def_resgid; /* Default gid for reserved blocks */
+ __le32 s_first_ino; /* First non-reserved inode */
+
+ __le16 s_inode_size; /* Size of an inode */
+ __le16 s_dat_entry_size; /* Size of a dat entry */
+ __le16 s_checkpoint_size; /* Size of a checkpoint */
+ __le16 s_segment_usage_size; /* Size of a segment usage */
+
+ __u8 s_uuid[16]; /* 128-bit uuid for volume */
+ char s_volume_name[16]; /* volume name */
+ char s_last_mounted[64]; /* directory where last mounted */
+
+ __le32 s_c_interval; /* Commit interval of segment */
+ __le32 s_c_block_max; /* Threshold of data amount for
+ the segment construction */
+ __u32 s_reserved[192]; /* padding to the end of the block */
+};
+
+/*
+ * Codes for operating systems
+ */
+#define NILFS_OS_LINUX 0
+/* Codes from 1 to 4 are reserved to keep compatibility with ext2 creator-OS */
+
+/*
+ * Revision levels
+ */
+#define NILFS_CURRENT_REV 2 /* current major revision */
+#define NILFS_MINOR_REV 0 /* minor revision */
+
+/*
+ * Bytes count of super_block for CRC-calculation
+ */
+#define NILFS_SB_BYTES \
+ ((long)&((struct nilfs_super_block *)0)->s_reserved)
+
+/*
+ * Special inode number
+ */
+#define NILFS_ROOT_INO 2 /* Root file inode */
+#define NILFS_DAT_INO 3 /* DAT file */
+#define NILFS_CPFILE_INO 4 /* checkpoint file */
+#define NILFS_SUFILE_INO 5 /* segment usage file */
+#define NILFS_IFILE_INO 6 /* ifile */
+#define NILFS_ATIME_INO 7 /* Atime file (reserved) */
+#define NILFS_XATTR_INO 8 /* Xattribute file (reserved) */
+#define NILFS_SKETCH_INO 10 /* Sketch file */
+#define NILFS_USER_INO 11 /* Fisrt user's file inode number */
+
+#define NILFS_SB_OFFSET_BYTES 1024 /* byte offset of nilfs superblock */
+#define NILFS_SUPER_MAGIC 0x3434 /* NILFS filesystem magic number */
+
+#define NILFS_SEG_MIN_BLOCKS 16 /* Minimum number of blocks in
+ a full segment */
+#define NILFS_PSEG_MIN_BLOCKS 2 /* Minimum number of blocks in
+ a partial segment */
+#define NILFS_MIN_NRSVSEGS 8 /* Minimum number of reserved
+ segments */
+
+/*
+ * bytes offset of secondary super block
+ */
+#define NILFS_SB2_OFFSET_BYTES(devsize) ((((devsize) >> 12) - 1) << 12)
+
+/*
+ * Maximal count of links to a file
+ */
+#define NILFS_LINK_MAX 32000
+
+/*
+ * Structure of a directory entry
+ * (Same as ext2)
+ */
+
+#define NILFS_NAME_LEN 255
+
+/*
+ * The new version of the directory entry. Since V0 structures are
+ * stored in intel byte order, and the name_len field could never be
+ * bigger than 255 chars, it's safe to reclaim the extra byte for the
+ * file_type field.
+ */
+struct nilfs_dir_entry {
+ __le64 inode; /* Inode number */
+ __le16 rec_len; /* Directory entry length */
+ __u8 name_len; /* Name length */
+ __u8 file_type;
+ char name[NILFS_NAME_LEN]; /* File name */
+ char pad;
+};
+
+/*
+ * NILFS directory file types. Only the low 3 bits are used. The
+ * other bits are reserved for now.
+ */
+enum {
+ NILFS_FT_UNKNOWN,
+ NILFS_FT_REG_FILE,
+ NILFS_FT_DIR,
+ NILFS_FT_CHRDEV,
+ NILFS_FT_BLKDEV,
+ NILFS_FT_FIFO,
+ NILFS_FT_SOCK,
+ NILFS_FT_SYMLINK,
+ NILFS_FT_MAX
+};
+
+/*
+ * NILFS_DIR_PAD defines the directory entries boundaries
+ *
+ * NOTE: It must be a multiple of 8
+ */
+#define NILFS_DIR_PAD 8
+#define NILFS_DIR_ROUND (NILFS_DIR_PAD - 1)
+#define NILFS_DIR_REC_LEN(name_len) (((name_len) + 12 + NILFS_DIR_ROUND) & \
+ ~NILFS_DIR_ROUND)
+
+
+/**
+ * struct nilfs_finfo - file information
+ * @fi_ino: inode number
+ * @fi_cno: checkpoint number
+ * @fi_nblocks: number of blocks (including intermediate blocks)
+ * @fi_ndatablk: number of file data blocks
+ */
+struct nilfs_finfo {
+ __le64 fi_ino;
+ __le64 fi_cno;
+ __le32 fi_nblocks;
+ __le32 fi_ndatablk;
+ /* array of virtual block numbers */
+};
+
+/**
+ * struct nilfs_binfo_v - information for the block to which a virtual block number is assigned
+ * @bi_vblocknr: virtual block number
+ * @bi_blkoff: block offset
+ */
+struct nilfs_binfo_v {
+ __le64 bi_vblocknr;
+ __le64 bi_blkoff;
+};
+
+/**
+ * struct nilfs_binfo_dat - information for the block which belongs to the DAT file
+ * @bi_blkoff: block offset
+ * @bi_level: level
+ * @bi_pad: padding
+ */
+struct nilfs_binfo_dat {
+ __le64 bi_blkoff;
+ __u8 bi_level;
+ __u8 bi_pad[7];
+};
+
+/**
+ * union nilfs_binfo: block information
+ * @bi_v: nilfs_binfo_v structure
+ * @bi_dat: nilfs_binfo_dat structure
+ */
+union nilfs_binfo {
+ struct nilfs_binfo_v bi_v;
+ struct nilfs_binfo_dat bi_dat;
+};
+
+/**
+ * struct nilfs_segment_summary - segment summary
+ * @ss_datasum: checksum of data
+ * @ss_sumsum: checksum of segment summary
+ * @ss_magic: magic number
+ * @ss_bytes: size of this structure in bytes
+ * @ss_flags: flags
+ * @ss_seq: sequence number
+ * @ss_create: creation timestamp
+ * @ss_next: next segment
+ * @ss_nblocks: number of blocks
+ * @ss_nfinfo: number of finfo structures
+ * @ss_sumbytes: total size of segment summary in bytes
+ * @ss_pad: padding
+ */
+struct nilfs_segment_summary {
+ __le32 ss_datasum;
+ __le32 ss_sumsum;
+ __le32 ss_magic;
+ __le16 ss_bytes;
+ __le16 ss_flags;
+ __le64 ss_seq;
+ __le64 ss_create;
+ __le64 ss_next;
+ __le32 ss_nblocks;
+ __le32 ss_nfinfo;
+ __le32 ss_sumbytes;
+ __le32 ss_pad;
+ /* array of finfo structures */
+};
+
+#define NILFS_SEGSUM_MAGIC 0x1eaffa11 /* segment summary magic number */
+
+/*
+ * Segment summary flags
+ */
+#define NILFS_SS_LOGBGN 0x0001 /* begins a logical segment */
+#define NILFS_SS_LOGEND 0x0002 /* ends a logical segment */
+#define NILFS_SS_SR 0x0004 /* has super root */
+#define NILFS_SS_SYNDT 0x0008 /* includes data only updates */
+#define NILFS_SS_GC 0x0010 /* segment written for cleaner operation */
+
+/**
+ * struct nilfs_palloc_group_desc - block group descriptor
+ * @pg_nfrees: number of free entries in block group
+ */
+struct nilfs_palloc_group_desc {
+ __le32 pg_nfrees;
+};
+
+/**
+ * struct nilfs_dat_entry - disk address translation entry
+ * @dt_blocknr: block number
+ * @dt_start: start checkpoint number
+ * @dt_end: end checkpoint number
+ * @dt_rsv: reserved for future use
+ */
+struct nilfs_dat_entry {
+ __le64 de_blocknr;
+ __le64 de_start;
+ __le64 de_end;
+ __le64 de_rsv;
+};
+
+/**
+ * struct nilfs_dat_group_desc - block group descriptor
+ * @dg_nfrees: number of free virtual block numbers in block group
+ */
+struct nilfs_dat_group_desc {
+ __le32 dg_nfrees;
+};
+
+
+/**
+ * struct nilfs_snapshot_list - snapshot list
+ * @ssl_next: next checkpoint number on snapshot list
+ * @ssl_prev: previous checkpoint number on snapshot list
+ */
+struct nilfs_snapshot_list {
+ __le64 ssl_next;
+ __le64 ssl_prev;
+};
+
+/**
+ * struct nilfs_checkpoint - checkpoint structure
+ * @cp_flags: flags
+ * @cp_checkpoints_count: checkpoints count in a block
+ * @cp_snapshot_list: snapshot list
+ * @cp_cno: checkpoint number
+ * @cp_create: creation timestamp
+ * @cp_nblk_inc: number of blocks incremented by this checkpoint
+ * @cp_inodes_count: inodes count
+ * @cp_blocks_count: blocks count
+ * @cp_ifile_inode: inode of ifile
+ */
+struct nilfs_checkpoint {
+ __le32 cp_flags;
+ __le32 cp_checkpoints_count;
+ struct nilfs_snapshot_list cp_snapshot_list;
+ __le64 cp_cno;
+ __le64 cp_create;
+ __le64 cp_nblk_inc;
+ __le64 cp_inodes_count;
+ __le64 cp_blocks_count; /* Reserved (might be deleted) */
+
+ /* Do not change the byte offset of ifile inode.
+ To keep the compatibility of the disk format,
+ additional fields should be added behind cp_ifile_inode. */
+ struct nilfs_inode cp_ifile_inode;
+};
+
+/* checkpoint flags */
+enum {
+ NILFS_CHECKPOINT_SNAPSHOT,
+ NILFS_CHECKPOINT_INVALID,
+ NILFS_CHECKPOINT_SKETCH,
+ NILFS_CHECKPOINT_MINOR,
+};
+
+#define NILFS_CHECKPOINT_FNS(flag, name) \
+static inline void \
+nilfs_checkpoint_set_##name(struct nilfs_checkpoint *cp) \
+{ \
+ cp->cp_flags = cpu_to_le32(le32_to_cpu(cp->cp_flags) | \
+ (1UL << NILFS_CHECKPOINT_##flag)); \
+} \
+static inline void \
+nilfs_checkpoint_clear_##name(struct nilfs_checkpoint *cp) \
+{ \
+ cp->cp_flags = cpu_to_le32(le32_to_cpu(cp->cp_flags) & \
+ ~(1UL << NILFS_CHECKPOINT_##flag)); \
+} \
+static inline int \
+nilfs_checkpoint_##name(const struct nilfs_checkpoint *cp) \
+{ \
+ return !!(le32_to_cpu(cp->cp_flags) & \
+ (1UL << NILFS_CHECKPOINT_##flag)); \
+}
+
+NILFS_CHECKPOINT_FNS(SNAPSHOT, snapshot)
+NILFS_CHECKPOINT_FNS(INVALID, invalid)
+NILFS_CHECKPOINT_FNS(MINOR, minor)
+
+/**
+ * struct nilfs_cpinfo - checkpoint information
+ * @ci_flags: flags
+ * @ci_pad: padding
+ * @ci_cno: checkpoint number
+ * @ci_create: creation timestamp
+ * @ci_nblk_inc: number of blocks incremented by this checkpoint
+ * @ci_inodes_count: inodes count
+ * @ci_blocks_count: blocks count
+ * @ci_next: next checkpoint number in snapshot list
+ */
+struct nilfs_cpinfo {
+ __u32 ci_flags;
+ __u32 ci_pad;
+ __u64 ci_cno;
+ __u64 ci_create;
+ __u64 ci_nblk_inc;
+ __u64 ci_inodes_count;
+ __u64 ci_blocks_count;
+ __u64 ci_next;
+};
+
+#define NILFS_CPINFO_FNS(flag, name) \
+static inline int \
+nilfs_cpinfo_##name(const struct nilfs_cpinfo *cpinfo) \
+{ \
+ return !!(cpinfo->ci_flags & (1UL << NILFS_CHECKPOINT_##flag)); \
+}
+
+NILFS_CPINFO_FNS(SNAPSHOT, snapshot)
+NILFS_CPINFO_FNS(INVALID, invalid)
+NILFS_CPINFO_FNS(MINOR, minor)
+
+
+/**
+ * struct nilfs_cpfile_header - checkpoint file header
+ * @ch_ncheckpoints: number of checkpoints
+ * @ch_nsnapshots: number of snapshots
+ * @ch_snapshot_list: snapshot list
+ */
+struct nilfs_cpfile_header {
+ __le64 ch_ncheckpoints;
+ __le64 ch_nsnapshots;
+ struct nilfs_snapshot_list ch_snapshot_list;
+};
+
+#define NILFS_CPFILE_FIRST_CHECKPOINT_OFFSET \
+ ((sizeof(struct nilfs_cpfile_header) + \
+ sizeof(struct nilfs_checkpoint) - 1) / \
+ sizeof(struct nilfs_checkpoint))
+
+/**
+ * struct nilfs_segment_usage - segment usage
+ * @su_lastmod: last modified timestamp
+ * @su_nblocks: number of blocks in segment
+ * @su_flags: flags
+ */
+struct nilfs_segment_usage {
+ __le64 su_lastmod;
+ __le32 su_nblocks;
+ __le32 su_flags;
+};
+
+/* segment usage flag */
+enum {
+ NILFS_SEGMENT_USAGE_ACTIVE,
+ NILFS_SEGMENT_USAGE_DIRTY,
+ NILFS_SEGMENT_USAGE_ERROR,
+
+ /* ... */
+};
+
+#define NILFS_SEGMENT_USAGE_FNS(flag, name) \
+static inline void \
+nilfs_segment_usage_set_##name(struct nilfs_segment_usage *su) \
+{ \
+ su->su_flags = cpu_to_le32(le32_to_cpu(su->su_flags) | \
+ (1UL << NILFS_SEGMENT_USAGE_##flag));\
+} \
+static inline void \
+nilfs_segment_usage_clear_##name(struct nilfs_segment_usage *su) \
+{ \
+ su->su_flags = \
+ cpu_to_le32(le32_to_cpu(su->su_flags) & \
+ ~(1UL << NILFS_SEGMENT_USAGE_##flag)); \
+} \
+static inline int \
+nilfs_segment_usage_##name(const struct nilfs_segment_usage *su) \
+{ \
+ return !!(le32_to_cpu(su->su_flags) & \
+ (1UL << NILFS_SEGMENT_USAGE_##flag)); \
+}
+
+NILFS_SEGMENT_USAGE_FNS(ACTIVE, active)
+NILFS_SEGMENT_USAGE_FNS(DIRTY, dirty)
+NILFS_SEGMENT_USAGE_FNS(ERROR, error)
+
+static inline void
+nilfs_segment_usage_set_clean(struct nilfs_segment_usage *su)
+{
+ su->su_lastmod = cpu_to_le64(0);
+ su->su_nblocks = cpu_to_le32(0);
+ su->su_flags = cpu_to_le32(0);
+}
+
+static inline int
+nilfs_segment_usage_clean(const struct nilfs_segment_usage *su)
+{
+ return !le32_to_cpu(su->su_flags);
+}
+
+/**
+ * struct nilfs_sufile_header - segment usage file header
+ * @sh_ncleansegs: number of clean segments
+ * @sh_ndirtysegs: number of dirty segments
+ * @sh_last_alloc: last allocated segment number
+ */
+struct nilfs_sufile_header {
+ __le64 sh_ncleansegs;
+ __le64 sh_ndirtysegs;
+ __le64 sh_last_alloc;
+ /* ... */
+};
+
+#define NILFS_SUFILE_FIRST_SEGMENT_USAGE_OFFSET \
+ ((sizeof(struct nilfs_sufile_header) + \
+ sizeof(struct nilfs_segment_usage) - 1) / \
+ sizeof(struct nilfs_segment_usage))
+
+/**
+ * nilfs_suinfo - segment usage information
+ * @sui_lastmod:
+ * @sui_nblocks:
+ * @sui_flags:
+ */
+struct nilfs_suinfo {
+ __u64 sui_lastmod;
+ __u32 sui_nblocks;
+ __u32 sui_flags;
+};
+
+#define NILFS_SUINFO_FNS(flag, name) \
+static inline int \
+nilfs_suinfo_##name(const struct nilfs_suinfo *si) \
+{ \
+ return si->sui_flags & (1UL << NILFS_SEGMENT_USAGE_##flag); \
+}
+
+NILFS_SUINFO_FNS(ACTIVE, active)
+NILFS_SUINFO_FNS(DIRTY, dirty)
+NILFS_SUINFO_FNS(ERROR, error)
+
+static inline int nilfs_suinfo_clean(const struct nilfs_suinfo *si)
+{
+ return !si->sui_flags;
+}
+
+/* ioctl */
+enum {
+ NILFS_CHECKPOINT,
+ NILFS_SNAPSHOT,
+};
+
+/**
+ * struct nilfs_cpmode -
+ * @cc_cno:
+ * @cc_mode:
+ */
+struct nilfs_cpmode {
+ __u64 cm_cno;
+ __u32 cm_mode;
+ __u32 cm_pad;
+};
+
+/**
+ * struct nilfs_argv - argument vector
+ * @v_base:
+ * @v_nmembs:
+ * @v_size:
+ * @v_flags:
+ * @v_index:
+ */
+struct nilfs_argv {
+ __u64 v_base;
+ __u32 v_nmembs; /* number of members */
+ __u16 v_size; /* size of members */
+ __u16 v_flags;
+ __u64 v_index;
+};
+
+/**
+ * struct nilfs_period -
+ * @p_start:
+ * @p_end:
+ */
+struct nilfs_period {
+ __u64 p_start;
+ __u64 p_end;
+};
+
+/**
+ * struct nilfs_cpstat -
+ * @cs_cno: checkpoint number
+ * @cs_ncps: number of checkpoints
+ * @cs_nsss: number of snapshots
+ */
+struct nilfs_cpstat {
+ __u64 cs_cno;
+ __u64 cs_ncps;
+ __u64 cs_nsss;
+};
+
+/**
+ * struct nilfs_sustat -
+ * @ss_nsegs: number of segments
+ * @ss_ncleansegs: number of clean segments
+ * @ss_ndirtysegs: number of dirty segments
+ * @ss_ctime: creation time of the last segment
+ * @ss_nongc_ctime: creation time of the last segment not for GC
+ * @ss_prot_seq: least sequence number of segments which must not be reclaimed
+ */
+struct nilfs_sustat {
+ __u64 ss_nsegs;
+ __u64 ss_ncleansegs;
+ __u64 ss_ndirtysegs;
+ __u64 ss_ctime;
+ __u64 ss_nongc_ctime;
+ __u64 ss_prot_seq;
+};
+
+/**
+ * struct nilfs_vinfo - virtual block number information
+ * @vi_vblocknr:
+ * @vi_start:
+ * @vi_end:
+ * @vi_blocknr:
+ */
+struct nilfs_vinfo {
+ __u64 vi_vblocknr;
+ __u64 vi_start;
+ __u64 vi_end;
+ __u64 vi_blocknr;
+};
+
+/**
+ * struct nilfs_vdesc -
+ */
+struct nilfs_vdesc {
+ __u64 vd_ino;
+ __u64 vd_cno;
+ __u64 vd_vblocknr;
+ struct nilfs_period vd_period;
+ __u64 vd_blocknr;
+ __u64 vd_offset;
+ __u32 vd_flags;
+ __u32 vd_pad;
+};
+
+/**
+ * struct nilfs_bdesc -
+ */
+struct nilfs_bdesc {
+ __u64 bd_ino;
+ __u64 bd_oblocknr;
+ __u64 bd_blocknr;
+ __u64 bd_offset;
+ __u32 bd_level;
+ __u32 bd_pad;
+};
+
+#define NILFS_IOCTL_IDENT 'n'
+
+#define NILFS_IOCTL_CHANGE_CPMODE \
+ _IOW(NILFS_IOCTL_IDENT, 0x80, struct nilfs_cpmode)
+#define NILFS_IOCTL_DELETE_CHECKPOINT \
+ _IOW(NILFS_IOCTL_IDENT, 0x81, __u64)
+#define NILFS_IOCTL_GET_CPINFO \
+ _IOR(NILFS_IOCTL_IDENT, 0x82, struct nilfs_argv)
+#define NILFS_IOCTL_GET_CPSTAT \
+ _IOR(NILFS_IOCTL_IDENT, 0x83, struct nilfs_cpstat)
+#define NILFS_IOCTL_GET_SUINFO \
+ _IOR(NILFS_IOCTL_IDENT, 0x84, struct nilfs_argv)
+#define NILFS_IOCTL_GET_SUSTAT \
+ _IOR(NILFS_IOCTL_IDENT, 0x85, struct nilfs_sustat)
+#define NILFS_IOCTL_GET_VINFO \
+ _IOWR(NILFS_IOCTL_IDENT, 0x86, struct nilfs_argv)
+#define NILFS_IOCTL_GET_BDESCS \
+ _IOWR(NILFS_IOCTL_IDENT, 0x87, struct nilfs_argv)
+#define NILFS_IOCTL_CLEAN_SEGMENTS \
+ _IOW(NILFS_IOCTL_IDENT, 0x88, struct nilfs_argv[5])
+#define NILFS_IOCTL_SYNC \
+ _IOR(NILFS_IOCTL_IDENT, 0x8A, __u64)
+#define NILFS_IOCTL_RESIZE \
+ _IOW(NILFS_IOCTL_IDENT, 0x8B, __u64)
+
+#endif /* _LINUX_NILFS_FS_H */
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 61df1779b2a..62214c7d2d9 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -82,6 +82,7 @@ enum pageflags {
PG_arch_1,
PG_reserved,
PG_private, /* If pagecache, has fs-private data */
+ PG_private_2, /* If pagecache, has fs aux data */
PG_writeback, /* Page is under writeback */
#ifdef CONFIG_PAGEFLAGS_EXTENDED
PG_head, /* A head page */
@@ -108,6 +109,12 @@ enum pageflags {
/* Filesystems */
PG_checked = PG_owner_priv_1,
+ /* Two page bits are conscripted by FS-Cache to maintain local caching
+ * state. These bits are set on pages belonging to the netfs's inodes
+ * when those inodes are being locally cached.
+ */
+ PG_fscache = PG_private_2, /* page backed by cache */
+
/* XEN */
PG_pinned = PG_owner_priv_1,
PG_savepinned = PG_dirty,
@@ -182,7 +189,7 @@ static inline int TestClearPage##uname(struct page *page) { return 0; }
struct page; /* forward declaration */
-TESTPAGEFLAG(Locked, locked)
+TESTPAGEFLAG(Locked, locked) TESTSETFLAG(Locked, locked)
PAGEFLAG(Error, error)
PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced)
PAGEFLAG(Dirty, dirty) TESTSCFLAG(Dirty, dirty) __CLEARPAGEFLAG(Dirty, dirty)
@@ -194,8 +201,6 @@ PAGEFLAG(Checked, checked) /* Used by some filesystems */
PAGEFLAG(Pinned, pinned) TESTSCFLAG(Pinned, pinned) /* Xen */
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)
@@ -205,6 +210,16 @@ __PAGEFLAG(SlubFrozen, slub_frozen)
__PAGEFLAG(SlubDebug, slub_debug)
/*
+ * Private page markings that may be used by the filesystem that owns the page
+ * for its own purposes.
+ * - PG_private and PG_private_2 cause releasepage() and co to be invoked
+ */
+PAGEFLAG(Private, private) __SETPAGEFLAG(Private, private)
+ __CLEARPAGEFLAG(Private, private)
+PAGEFLAG(Private2, private_2) TESTSCFLAG(Private2, private_2)
+PAGEFLAG(OwnerPriv1, owner_priv_1) TESTCLEARFLAG(OwnerPriv1, owner_priv_1)
+
+/*
* Only test-and-set exist for PG_writeback. The unconditional operators are
* risky: they bypass page accounting.
*/
@@ -384,9 +399,10 @@ static inline void __ClearPageTail(struct page *page)
* these flags set. It they are, there is a problem.
*/
#define PAGE_FLAGS_CHECK_AT_FREE \
- (1 << PG_lru | 1 << PG_private | 1 << PG_locked | \
- 1 << PG_buddy | 1 << PG_writeback | 1 << PG_reserved | \
- 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active | \
+ (1 << PG_lru | 1 << PG_locked | \
+ 1 << PG_private | 1 << PG_private_2 | \
+ 1 << PG_buddy | 1 << PG_writeback | 1 << PG_reserved | \
+ 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active | \
__PG_UNEVICTABLE | __PG_MLOCKED)
/*
@@ -397,4 +413,16 @@ static inline void __ClearPageTail(struct page *page)
#define PAGE_FLAGS_CHECK_AT_PREP ((1 << NR_PAGEFLAGS) - 1)
#endif /* !__GENERATING_BOUNDS_H */
+
+/**
+ * page_has_private - Determine if page has private stuff
+ * @page: The page to be checked
+ *
+ * Determine if a page has private stuff, indicating that release routines
+ * should be invoked upon it.
+ */
+#define page_has_private(page) \
+ ((page)->flags & ((1 << PG_private) | \
+ (1 << PG_private_2)))
+
#endif /* PAGE_FLAGS_H */
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 076a7dc67c2..34da5230faa 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -384,6 +384,11 @@ static inline void wait_on_page_writeback(struct page *page)
extern void end_page_writeback(struct page *page);
/*
+ * Add an arbitrary waiter to a page's wait queue
+ */
+extern void add_page_wait_queue(struct page *page, wait_queue_t *waiter);
+
+/*
* Fault a userspace page into pagetables. Return non-zero on a fault.
*
* This assumes that two userspace pages are always sufficient. That's
diff --git a/include/linux/parport_pc.h b/include/linux/parport_pc.h
index ea8c6d84996..cc1767f5cca 100644
--- a/include/linux/parport_pc.h
+++ b/include/linux/parport_pc.h
@@ -228,10 +228,11 @@ extern void parport_pc_release_resources(struct parport *p);
extern int parport_pc_claim_resources(struct parport *p);
/* PCMCIA code will want to get us to look at a port. Provide a mechanism. */
-extern struct parport *parport_pc_probe_port (unsigned long base,
- unsigned long base_hi,
- int irq, int dma,
- struct device *dev);
-extern void parport_pc_unregister_port (struct parport *p);
+extern struct parport *parport_pc_probe_port(unsigned long base,
+ unsigned long base_hi,
+ int irq, int dma,
+ struct device *dev,
+ int irqflags);
+extern void parport_pc_unregister_port(struct parport *p);
#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index a7fe4bbd7ff..72698d89e76 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -674,6 +674,11 @@ int __must_check pci_reenable_device(struct pci_dev *);
int __must_check pcim_enable_device(struct pci_dev *pdev);
void pcim_pin_device(struct pci_dev *pdev);
+static inline int pci_is_enabled(struct pci_dev *pdev)
+{
+ return (atomic_read(&pdev->enable_cnt) > 0);
+}
+
static inline int pci_is_managed(struct pci_dev *pdev)
{
return pdev->is_managed;
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 170f8b1f22d..06ba90c211a 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -944,6 +944,32 @@
#define PCI_DEVICE_ID_SUN_TOMATILLO 0xa801
#define PCI_DEVICE_ID_SUN_CASSINI 0xabba
+#define PCI_VENDOR_ID_NI 0x1093
+#define PCI_DEVICE_ID_NI_PCI2322 0xd130
+#define PCI_DEVICE_ID_NI_PCI2324 0xd140
+#define PCI_DEVICE_ID_NI_PCI2328 0xd150
+#define PCI_DEVICE_ID_NI_PXI8422_2322 0xd190
+#define PCI_DEVICE_ID_NI_PXI8422_2324 0xd1a0
+#define PCI_DEVICE_ID_NI_PXI8420_2322 0xd1d0
+#define PCI_DEVICE_ID_NI_PXI8420_2324 0xd1e0
+#define PCI_DEVICE_ID_NI_PXI8420_2328 0xd1f0
+#define PCI_DEVICE_ID_NI_PXI8420_23216 0xd1f1
+#define PCI_DEVICE_ID_NI_PCI2322I 0xd250
+#define PCI_DEVICE_ID_NI_PCI2324I 0xd270
+#define PCI_DEVICE_ID_NI_PCI23216 0xd2b0
+#define PCI_DEVICE_ID_NI_PXI8430_2322 0x7080
+#define PCI_DEVICE_ID_NI_PCI8430_2322 0x70db
+#define PCI_DEVICE_ID_NI_PXI8430_2324 0x70dd
+#define PCI_DEVICE_ID_NI_PCI8430_2324 0x70df
+#define PCI_DEVICE_ID_NI_PXI8430_2328 0x70e2
+#define PCI_DEVICE_ID_NI_PCI8430_2328 0x70e4
+#define PCI_DEVICE_ID_NI_PXI8430_23216 0x70e6
+#define PCI_DEVICE_ID_NI_PCI8430_23216 0x70e7
+#define PCI_DEVICE_ID_NI_PXI8432_2322 0x70e8
+#define PCI_DEVICE_ID_NI_PCI8432_2322 0x70ea
+#define PCI_DEVICE_ID_NI_PXI8432_2324 0x70ec
+#define PCI_DEVICE_ID_NI_PCI8432_2324 0x70ee
+
#define PCI_VENDOR_ID_CMD 0x1095
#define PCI_DEVICE_ID_CMD_643 0x0643
#define PCI_DEVICE_ID_CMD_646 0x0646
@@ -2488,6 +2514,8 @@
#define PCI_DEVICE_ID_INTEL_IOAT_TBG3 0x3433
#define PCI_DEVICE_ID_INTEL_82830_HB 0x3575
#define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577
+#define PCI_DEVICE_ID_INTEL_82854_HB 0x358c
+#define PCI_DEVICE_ID_INTEL_82854_IG 0x358e
#define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580
#define PCI_DEVICE_ID_INTEL_82855GM_IG 0x3582
#define PCI_DEVICE_ID_INTEL_E7520_MCH 0x3590
diff --git a/include/linux/pda_power.h b/include/linux/pda_power.h
index cb7d10f3076..d4cf7a2ceb3 100644
--- a/include/linux/pda_power.h
+++ b/include/linux/pda_power.h
@@ -31,6 +31,8 @@ struct pda_power_pdata {
unsigned int wait_for_status; /* msecs, default is 500 */
unsigned int wait_for_charger; /* msecs, default is 500 */
unsigned int polling_interval; /* msecs, default is 2000 */
+
+ unsigned long ac_max_uA; /* current to draw when on AC */
};
#endif /* __PDA_POWER_H__ */
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index ee5615d6521..cfda2d5ad31 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -168,4 +168,56 @@ static inline void free_percpu(void *p)
#define alloc_percpu(type) (type *)__alloc_percpu(sizeof(type), \
__alignof__(type))
+/*
+ * Optional methods for optimized non-lvalue per-cpu variable access.
+ *
+ * @var can be a percpu variable or a field of it and its size should
+ * equal char, int or long. percpu_read() evaluates to a lvalue and
+ * all others to void.
+ *
+ * These operations are guaranteed to be atomic w.r.t. preemption.
+ * The generic versions use plain get/put_cpu_var(). Archs are
+ * encouraged to implement single-instruction alternatives which don't
+ * require preemption protection.
+ */
+#ifndef percpu_read
+# define percpu_read(var) \
+ ({ \
+ typeof(per_cpu_var(var)) __tmp_var__; \
+ __tmp_var__ = get_cpu_var(var); \
+ put_cpu_var(var); \
+ __tmp_var__; \
+ })
+#endif
+
+#define __percpu_generic_to_op(var, val, op) \
+do { \
+ get_cpu_var(var) op val; \
+ put_cpu_var(var); \
+} while (0)
+
+#ifndef percpu_write
+# define percpu_write(var, val) __percpu_generic_to_op(var, (val), =)
+#endif
+
+#ifndef percpu_add
+# define percpu_add(var, val) __percpu_generic_to_op(var, (val), +=)
+#endif
+
+#ifndef percpu_sub
+# define percpu_sub(var, val) __percpu_generic_to_op(var, (val), -=)
+#endif
+
+#ifndef percpu_and
+# define percpu_and(var, val) __percpu_generic_to_op(var, (val), &=)
+#endif
+
+#ifndef percpu_or
+# define percpu_or(var, val) __percpu_generic_to_op(var, (val), |=)
+#endif
+
+#ifndef percpu_xor
+# define percpu_xor(var, val) __percpu_generic_to_op(var, (val), ^=)
+#endif
+
#endif /* __LINUX_PERCPU_H */
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 8ff25e0e7f7..594c494ac3f 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -73,6 +73,8 @@ enum power_supply_property {
POWER_SUPPLY_PROP_VOLTAGE_AVG,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CURRENT_AVG,
+ POWER_SUPPLY_PROP_POWER_NOW,
+ POWER_SUPPLY_PROP_POWER_AVG,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
POWER_SUPPLY_PROP_CHARGE_FULL,
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 3945f803d51..7c775751392 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -28,4 +28,4 @@ int pwm_enable(struct pwm_device *pwm);
*/
void pwm_disable(struct pwm_device *pwm);
-#endif /* __ASM_ARCH_PWM_H */
+#endif /* __LINUX_PWM_H */
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
deleted file mode 100644
index 82bea14cae1..00000000000
--- a/include/linux/raid/md.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- md.h : Multiple Devices driver for Linux
- Copyright (C) 1996-98 Ingo Molnar, Gadi Oxman
- Copyright (C) 1994-96 Marc ZYNGIER
- <zyngier@ufr-info-p7.ibp.fr> or
- <maz@gloups.fdn.fr>
-
- 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.
-
- You should have received a copy of the GNU General Public License
- (for example /usr/src/linux/COPYING); if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _MD_H
-#define _MD_H
-
-#include <linux/blkdev.h>
-#include <linux/seq_file.h>
-
-/*
- * 'md_p.h' holds the 'physical' layout of RAID devices
- * 'md_u.h' holds the user <=> kernel API
- *
- * 'md_k.h' holds kernel internal definitions
- */
-
-#include <linux/raid/md_p.h>
-#include <linux/raid/md_u.h>
-#include <linux/raid/md_k.h>
-
-#ifdef CONFIG_MD
-
-/*
- * Different major versions are not compatible.
- * Different minor versions are only downward compatible.
- * Different patchlevel versions are downward and upward compatible.
- */
-#define MD_MAJOR_VERSION 0
-#define MD_MINOR_VERSION 90
-/*
- * MD_PATCHLEVEL_VERSION indicates kernel functionality.
- * >=1 means different superblock formats are selectable using SET_ARRAY_INFO
- * and major_version/minor_version accordingly
- * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT
- * in the super status byte
- * >=3 means that bitmap superblock version 4 is supported, which uses
- * little-ending representation rather than host-endian
- */
-#define MD_PATCHLEVEL_VERSION 3
-
-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),
- mddev_t *mddev, const char *name);
-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_done_sync(mddev_t *mddev, int blocks, int ok);
-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);
-extern void md_super_wait(mddev_t *mddev);
-extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
- struct page *page, int rw);
-extern void md_do_sync(mddev_t *mddev);
-extern void md_new_event(mddev_t *mddev);
-extern int md_allow_write(mddev_t *mddev);
-extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
-
-#endif /* CONFIG_MD */
-#endif
-
diff --git a/include/linux/raid/md_u.h b/include/linux/raid/md_u.h
index 7192035fc4b..fb1abb3367e 100644
--- a/include/linux/raid/md_u.h
+++ b/include/linux/raid/md_u.h
@@ -15,6 +15,24 @@
#ifndef _MD_U_H
#define _MD_U_H
+/*
+ * Different major versions are not compatible.
+ * Different minor versions are only downward compatible.
+ * Different patchlevel versions are downward and upward compatible.
+ */
+#define MD_MAJOR_VERSION 0
+#define MD_MINOR_VERSION 90
+/*
+ * MD_PATCHLEVEL_VERSION indicates kernel functionality.
+ * >=1 means different superblock formats are selectable using SET_ARRAY_INFO
+ * and major_version/minor_version accordingly
+ * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT
+ * in the super status byte
+ * >=3 means that bitmap superblock version 4 is supported, which uses
+ * little-ending representation rather than host-endian
+ */
+#define MD_PATCHLEVEL_VERSION 3
+
/* ioctls */
/* status */
@@ -46,6 +64,12 @@
#define STOP_ARRAY_RO _IO (MD_MAJOR, 0x33)
#define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34)
+/* 63 partitions with the alternate major number (mdp) */
+#define MdpMinorShift 6
+#ifdef __KERNEL__
+extern int mdp_major;
+#endif
+
typedef struct mdu_version_s {
int major;
int minor;
@@ -85,6 +109,17 @@ typedef struct mdu_array_info_s {
} mdu_array_info_t;
+/* non-obvious values for 'level' */
+#define LEVEL_MULTIPATH (-4)
+#define LEVEL_LINEAR (-1)
+#define LEVEL_FAULTY (-5)
+
+/* we need a value for 'no level specified' and 0
+ * means 'raid0', so we need something else. This is
+ * for internal use only
+ */
+#define LEVEL_NONE (-1000000)
+
typedef struct mdu_disk_info_s {
/*
* configuration/status of one particular disk
diff --git a/drivers/md/raid6.h b/include/linux/raid/pq.h
index 98dcde88470..d92480f8285 100644
--- a/drivers/md/raid6.h
+++ b/include/linux/raid/pq.h
@@ -5,7 +5,7 @@
* 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, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -17,14 +17,7 @@
/* Set to 1 to use kernel-wide empty_zero_page */
#define RAID6_USE_EMPTY_ZERO_PAGE 0
-
-#include <linux/raid/md.h>
-#include <linux/raid/raid5.h>
-
-typedef raid5_conf_t raid6_conf_t; /* Same configuration */
-
-/* Additional compute_parity mode -- updates the parity w/o LOCKING */
-#define UPDATE_PARITY 4
+#include <linux/blkdev.h>
/* We need a pre-zeroed page... if we don't want to use the kernel-provided
one define it here */
@@ -68,6 +61,10 @@ extern const char raid6_empty_zero_page[PAGE_SIZE];
#define enable_kernel_altivec()
#define disable_kernel_altivec()
+#define EXPORT_SYMBOL(sym)
+#define MODULE_LICENSE(licence)
+#define subsys_initcall(x)
+#define module_exit(x)
#endif /* __KERNEL__ */
/* Routine choices */
@@ -98,9 +95,11 @@ extern const u8 raid6_gfinv[256] __attribute__((aligned(256)));
extern const u8 raid6_gfexi[256] __attribute__((aligned(256)));
/* Recovery routines */
-void raid6_2data_recov(int disks, size_t bytes, int faila, int failb, void **ptrs);
+void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
+ void **ptrs);
void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs);
-void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs);
+void raid6_dual_recov(int disks, size_t bytes, int faila, int failb,
+ void **ptrs);
/* Some definitions to allow code to be compiled for testing in userspace */
#ifndef __KERNEL__
@@ -108,8 +107,11 @@ void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs
# define jiffies raid6_jiffies()
# define printk printf
# define GFP_KERNEL 0
-# define __get_free_pages(x,y) ((unsigned long)mmap(NULL, PAGE_SIZE << (y), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0))
-# define free_pages(x,y) munmap((void *)(x), (y)*PAGE_SIZE)
+# define __get_free_pages(x, y) ((unsigned long)mmap(NULL, PAGE_SIZE << (y), \
+ PROT_READ|PROT_WRITE, \
+ MAP_PRIVATE|MAP_ANONYMOUS,\
+ 0, 0))
+# define free_pages(x, y) munmap((void *)(x), (y)*PAGE_SIZE)
static inline void cpu_relax(void)
{
diff --git a/include/linux/raid/xor.h b/include/linux/raid/xor.h
index 3e120587ead..5a210959e3f 100644
--- a/include/linux/raid/xor.h
+++ b/include/linux/raid/xor.h
@@ -1,8 +1,6 @@
#ifndef _XOR_H
#define _XOR_H
-#include <linux/raid/md.h>
-
#define MAX_XOR_BLOCKS 4
extern void xor_blocks(unsigned int count, unsigned int bytes,
diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h
index 80044a4f3ab..bfd92e1e5d2 100644
--- a/include/linux/rcuclassic.h
+++ b/include/linux/rcuclassic.h
@@ -36,7 +36,6 @@
#include <linux/cache.h>
#include <linux/spinlock.h>
#include <linux/threads.h>
-#include <linux/percpu.h>
#include <linux/cpumask.h>
#include <linux/seqlock.h>
@@ -108,25 +107,14 @@ struct rcu_data {
struct rcu_head barrier;
};
-DECLARE_PER_CPU(struct rcu_data, rcu_data);
-DECLARE_PER_CPU(struct rcu_data, rcu_bh_data);
-
/*
* Increment the quiescent state counter.
* The counter is a bit degenerated: We do not need to know
* how many quiescent states passed, just if there was at least
* one since the start of the grace period. Thus just a flag.
*/
-static inline void rcu_qsctr_inc(int cpu)
-{
- struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
- rdp->passed_quiesc = 1;
-}
-static inline void rcu_bh_qsctr_inc(int cpu)
-{
- struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
- rdp->passed_quiesc = 1;
-}
+extern void rcu_qsctr_inc(int cpu);
+extern void rcu_bh_qsctr_inc(int cpu);
extern int rcu_pending(int cpu);
extern int rcu_needs_cpu(int cpu);
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 528343e6da5..15fbb3ca634 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -36,7 +36,6 @@
#include <linux/cache.h>
#include <linux/spinlock.h>
#include <linux/threads.h>
-#include <linux/percpu.h>
#include <linux/cpumask.h>
#include <linux/seqlock.h>
#include <linux/lockdep.h>
diff --git a/include/linux/rcupreempt.h b/include/linux/rcupreempt.h
index 74304b4538d..fce522782ff 100644
--- a/include/linux/rcupreempt.h
+++ b/include/linux/rcupreempt.h
@@ -36,34 +36,19 @@
#include <linux/cache.h>
#include <linux/spinlock.h>
#include <linux/threads.h>
-#include <linux/percpu.h>
+#include <linux/smp.h>
#include <linux/cpumask.h>
#include <linux/seqlock.h>
-struct rcu_dyntick_sched {
- int dynticks;
- int dynticks_snap;
- int sched_qs;
- int sched_qs_snap;
- int sched_dynticks_snap;
-};
-
-DECLARE_PER_CPU(struct rcu_dyntick_sched, rcu_dyntick_sched);
-
-static inline void rcu_qsctr_inc(int cpu)
-{
- struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu);
-
- rdssp->sched_qs++;
-}
-#define rcu_bh_qsctr_inc(cpu)
+extern void rcu_qsctr_inc(int cpu);
+static inline void rcu_bh_qsctr_inc(int cpu) { }
/*
* Someone might want to pass call_rcu_bh as a function pointer.
* So this needs to just be a rename and not a macro function.
* (no parentheses)
*/
-#define call_rcu_bh call_rcu
+#define call_rcu_bh call_rcu
/**
* call_rcu_sched - Queue RCU callback for invocation after sched grace period.
@@ -117,30 +102,12 @@ extern struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu);
struct softirq_action;
#ifdef CONFIG_NO_HZ
-
-static inline void rcu_enter_nohz(void)
-{
- static DEFINE_RATELIMIT_STATE(rs, 10 * HZ, 1);
-
- smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */
- __get_cpu_var(rcu_dyntick_sched).dynticks++;
- WARN_ON_RATELIMIT(__get_cpu_var(rcu_dyntick_sched).dynticks & 0x1, &rs);
-}
-
-static inline void rcu_exit_nohz(void)
-{
- static DEFINE_RATELIMIT_STATE(rs, 10 * HZ, 1);
-
- __get_cpu_var(rcu_dyntick_sched).dynticks++;
- smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */
- WARN_ON_RATELIMIT(!(__get_cpu_var(rcu_dyntick_sched).dynticks & 0x1),
- &rs);
-}
-
-#else /* CONFIG_NO_HZ */
-#define rcu_enter_nohz() do { } while (0)
-#define rcu_exit_nohz() do { } while (0)
-#endif /* CONFIG_NO_HZ */
+extern void rcu_enter_nohz(void);
+extern void rcu_exit_nohz(void);
+#else
+# define rcu_enter_nohz() do { } while (0)
+# define rcu_exit_nohz() do { } while (0)
+#endif
/*
* A context switch is a grace period for rcupreempt synchronize_rcu()
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index a722fb67bb2..0cdda00f2b2 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -33,7 +33,6 @@
#include <linux/cache.h>
#include <linux/spinlock.h>
#include <linux/threads.h>
-#include <linux/percpu.h>
#include <linux/cpumask.h>
#include <linux/seqlock.h>
@@ -236,30 +235,8 @@ struct rcu_state {
#endif /* #ifdef CONFIG_NO_HZ */
};
-extern struct rcu_state rcu_state;
-DECLARE_PER_CPU(struct rcu_data, rcu_data);
-
-extern struct rcu_state rcu_bh_state;
-DECLARE_PER_CPU(struct rcu_data, rcu_bh_data);
-
-/*
- * Increment the quiescent state counter.
- * The counter is a bit degenerated: We do not need to know
- * how many quiescent states passed, just if there was at least
- * one since the start of the grace period. Thus just a flag.
- */
-static inline void rcu_qsctr_inc(int cpu)
-{
- struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
- rdp->passed_quiesc = 1;
- rdp->passed_quiesc_completed = rdp->completed;
-}
-static inline void rcu_bh_qsctr_inc(int cpu)
-{
- struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
- rdp->passed_quiesc = 1;
- rdp->passed_quiesc_completed = rdp->completed;
-}
+extern void rcu_qsctr_inc(int cpu);
+extern void rcu_bh_qsctr_inc(int cpu);
extern int rcu_pending(int cpu);
extern int rcu_needs_cpu(int cpu);
diff --git a/include/linux/regulator/bq24022.h b/include/linux/regulator/bq24022.h
index e84b0a9feda..a6d014005d4 100644
--- a/include/linux/regulator/bq24022.h
+++ b/include/linux/regulator/bq24022.h
@@ -10,6 +10,8 @@
*
*/
+struct regulator_init_data;
+
/**
* bq24022_mach_info - platform data for bq24022
* @gpio_nce: GPIO line connected to the nCE pin, used to enable / disable charging
@@ -18,4 +20,5 @@
struct bq24022_mach_info {
int gpio_nce;
int gpio_iset2;
+ struct regulator_init_data *init_data;
};
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index 801bf77ff4e..277f4b964df 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -3,7 +3,7 @@
*
* Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
*
- * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
+ * Author: Liam Girdwood <lrg@slimlogic.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 as
@@ -88,6 +88,7 @@
* FAIL Regulator output has failed.
* OVER_TEMP Regulator over temp.
* FORCE_DISABLE Regulator shut down by software.
+ * VOLTAGE_CHANGE Regulator voltage changed.
*
* NOTE: These events can be OR'ed together when passed into handler.
*/
@@ -98,6 +99,7 @@
#define REGULATOR_EVENT_FAIL 0x08
#define REGULATOR_EVENT_OVER_TEMP 0x10
#define REGULATOR_EVENT_FORCE_DISABLE 0x20
+#define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40
struct regulator;
@@ -140,6 +142,8 @@ int regulator_bulk_disable(int num_consumers,
void regulator_bulk_free(int num_consumers,
struct regulator_bulk_data *consumers);
+int regulator_count_voltages(struct regulator *regulator);
+int regulator_list_voltage(struct regulator *regulator, unsigned selector);
int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
int regulator_get_voltage(struct regulator *regulator);
int regulator_set_current_limit(struct regulator *regulator,
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 2dae05705f1..4848d8dacd9 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -3,7 +3,7 @@
*
* Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
*
- * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
+ * Author: Liam Girdwood <lrg@slimlogic.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 as
@@ -21,25 +21,38 @@
struct regulator_dev;
struct regulator_init_data;
+enum regulator_status {
+ REGULATOR_STATUS_OFF,
+ REGULATOR_STATUS_ON,
+ REGULATOR_STATUS_ERROR,
+ /* fast/normal/idle/standby are flavors of "on" */
+ REGULATOR_STATUS_FAST,
+ REGULATOR_STATUS_NORMAL,
+ REGULATOR_STATUS_IDLE,
+ REGULATOR_STATUS_STANDBY,
+};
+
/**
* struct regulator_ops - regulator operations.
*
- * This struct describes regulator operations which can be implemented by
- * regulator chip drivers.
- *
- * @enable: Enable the regulator.
- * @disable: Disable the regulator.
+ * @enable: Configure the regulator as enabled.
+ * @disable: Configure the regulator as disabled.
* @is_enabled: Return 1 if the regulator is enabled, 0 otherwise.
*
* @set_voltage: Set the voltage for the regulator within the range specified.
* The driver should select the voltage closest to min_uV.
* @get_voltage: Return the currently configured voltage for the regulator.
+ * @list_voltage: Return one of the supported voltages, in microvolts; zero
+ * if the selector indicates a voltage that is unusable on this system;
+ * or negative errno. Selectors range from zero to one less than
+ * regulator_desc.n_voltages. Voltages may be reported in any order.
*
* @set_current_limit: Configure a limit for a current-limited regulator.
- * @get_current_limit: Get the limit for a current-limited regulator.
+ * @get_current_limit: Get the configured limit for a current-limited regulator.
*
- * @set_mode: Set the operating mode for the regulator.
- * @get_mode: Get the current operating mode for the regulator.
+ * @get_mode: Get the configured operating mode for the regulator.
+ * @get_status: Return actual (not as-configured) status of regulator, as a
+ * REGULATOR_STATUS value (or negative errno)
* @get_optimum_mode: Get the most efficient operating mode for the regulator
* when running with the specified parameters.
*
@@ -51,9 +64,15 @@ struct regulator_init_data;
* suspended.
* @set_suspend_mode: Set the operating mode for the regulator when the
* system is suspended.
+ *
+ * This struct describes regulator operations which can be implemented by
+ * regulator chip drivers.
*/
struct regulator_ops {
+ /* enumerate supported voltages */
+ int (*list_voltage) (struct regulator_dev *, unsigned selector);
+
/* get/set regulator voltage */
int (*set_voltage) (struct regulator_dev *, int min_uV, int max_uV);
int (*get_voltage) (struct regulator_dev *);
@@ -72,6 +91,13 @@ struct regulator_ops {
int (*set_mode) (struct regulator_dev *, unsigned int mode);
unsigned int (*get_mode) (struct regulator_dev *);
+ /* report regulator status ... most other accessors report
+ * control inputs, this reports results of combining inputs
+ * from Linux (and other sources) with the actual load.
+ * returns REGULATOR_STATUS_* or negative errno.
+ */
+ int (*get_status)(struct regulator_dev *);
+
/* get most efficient regulator operating mode for load */
unsigned int (*get_optimum_mode) (struct regulator_dev *, int input_uV,
int output_uV, int load_uA);
@@ -106,6 +132,7 @@ enum regulator_type {
*
* @name: Identifying name for the regulator.
* @id: Numerical identifier for the regulator.
+ * @n_voltages: Number of selectors available for ops.list_voltage().
* @ops: Regulator operations table.
* @irq: Interrupt number for the regulator.
* @type: Indicates if the regulator is a voltage or current regulator.
@@ -114,14 +141,48 @@ enum regulator_type {
struct regulator_desc {
const char *name;
int id;
+ unsigned n_voltages;
struct regulator_ops *ops;
int irq;
enum regulator_type type;
struct module *owner;
};
+/*
+ * struct regulator_dev
+ *
+ * Voltage / Current regulator class device. One for each
+ * regulator.
+ *
+ * This should *not* be used directly by anything except the regulator
+ * core and notification injection (which should take the mutex and do
+ * no other direct access).
+ */
+struct regulator_dev {
+ struct regulator_desc *desc;
+ int use_count;
+
+ /* lists we belong to */
+ struct list_head list; /* list of all regulators */
+ struct list_head slist; /* list of supplied regulators */
+
+ /* lists we own */
+ struct list_head consumer_list; /* consumers we supply */
+ struct list_head supply_list; /* regulators we supply */
+
+ struct blocking_notifier_head notifier;
+ struct mutex mutex; /* consumer lock */
+ struct module *owner;
+ struct device dev;
+ struct regulation_constraints *constraints;
+ struct regulator_dev *supply; /* for tree */
+
+ void *reg_data; /* regulator_dev data */
+};
+
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
- struct device *dev, void *driver_data);
+ struct device *dev, struct regulator_init_data *init_data,
+ void *driver_data);
void regulator_unregister(struct regulator_dev *rdev);
int regulator_notifier_call_chain(struct regulator_dev *rdev,
diff --git a/include/linux/regulator/fixed.h b/include/linux/regulator/fixed.h
index 1387a5d2190..91b4da31f1b 100644
--- a/include/linux/regulator/fixed.h
+++ b/include/linux/regulator/fixed.h
@@ -14,9 +14,12 @@
#ifndef __REGULATOR_FIXED_H
#define __REGULATOR_FIXED_H
+struct regulator_init_data;
+
struct fixed_voltage_config {
const char *supply_name;
int microvolts;
+ struct regulator_init_data *init_data;
};
#endif
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index 3794773b23d..bac64fa390f 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -3,7 +3,7 @@
*
* Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
*
- * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
+ * Author: Liam Girdwood <lrg@slimlogic.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 as
@@ -73,7 +73,9 @@ struct regulator_state {
*
* @always_on: Set if the regulator should never be disabled.
* @boot_on: Set if the regulator is enabled when the system is initially
- * started.
+ * started. If the regulator is not enabled by the hardware or
+ * bootloader then it will be enabled when the constraints are
+ * applied.
* @apply_uV: Apply the voltage constraint when initialising.
*
* @input_uV: Input voltage for regulator when supplied by another regulator.
@@ -83,6 +85,7 @@ struct regulator_state {
* @state_standby: State for regulator when system is suspended in standby
* mode.
* @initial_state: Suspend state to set by default.
+ * @initial_mode: Mode to set at startup.
*/
struct regulation_constraints {
@@ -111,6 +114,9 @@ struct regulation_constraints {
struct regulator_state state_standby;
suspend_state_t initial_state; /* suspend state to set at init */
+ /* mode to set on startup */
+ unsigned int initial_mode;
+
/* constriant flags */
unsigned always_on:1; /* regulator never off when system is on */
unsigned boot_on:1; /* bootloader/firmware enabled regulator */
@@ -160,4 +166,6 @@ struct regulator_init_data {
int regulator_suspend_prepare(suspend_state_t state);
+void regulator_has_full_constraints(void);
+
#endif
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index b3b35966008..e1b7b217388 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -8,7 +8,7 @@ struct ring_buffer;
struct ring_buffer_iter;
/*
- * Don't reference this struct directly, use functions below.
+ * Don't refer to this struct directly, use functions below.
*/
struct ring_buffer_event {
u32 type:2, len:3, time_delta:27;
@@ -18,10 +18,13 @@ struct ring_buffer_event {
/**
* 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
+ * @RINGBUF_TYPE_PADDING: Left over page padding or discarded event
+ * If time_delta is 0:
+ * array is ignored
+ * size is variable depending on how much
* padding is needed
+ * If time_delta is non zero:
+ * everything else same as RINGBUF_TYPE_DATA
*
* @RINGBUF_TYPE_TIME_EXTEND: Extend the time delta
* array[0] = time delta (28 .. 59)
@@ -65,6 +68,8 @@ ring_buffer_event_time_delta(struct ring_buffer_event *event)
return event->time_delta;
}
+void ring_buffer_event_discard(struct ring_buffer_event *event);
+
/*
* size is in bytes for each per CPU buffer.
*/
@@ -74,13 +79,10 @@ 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);
+struct ring_buffer_event *ring_buffer_lock_reserve(struct ring_buffer *buffer,
+ unsigned long length);
int ring_buffer_unlock_commit(struct ring_buffer *buffer,
- struct ring_buffer_event *event,
- unsigned long flags);
+ struct ring_buffer_event *event);
int ring_buffer_write(struct ring_buffer *buffer,
unsigned long length, void *data);
@@ -121,17 +123,19 @@ unsigned long ring_buffer_overruns(struct ring_buffer *buffer);
unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu);
unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu);
-u64 ring_buffer_time_stamp(int cpu);
-void ring_buffer_normalize_time_stamp(int cpu, u64 *ts);
+u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu);
+void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer,
+ int cpu, u64 *ts);
+void ring_buffer_set_clock(struct ring_buffer *buffer,
+ u64 (*clock)(void));
+
+size_t ring_buffer_page_len(void *page);
-void tracing_on(void);
-void tracing_off(void);
-void tracing_off_permanent(void);
void *ring_buffer_alloc_read_page(struct ring_buffer *buffer);
void ring_buffer_free_read_page(struct ring_buffer *buffer, void *data);
-int ring_buffer_read_page(struct ring_buffer *buffer,
- void **data_page, int cpu, int full);
+int ring_buffer_read_page(struct ring_buffer *buffer, void **data_page,
+ size_t len, int cpu, int full);
enum ring_buffer_flags {
RB_FL_OVERWRITE = 1 << 0,
diff --git a/include/linux/rotary_encoder.h b/include/linux/rotary_encoder.h
new file mode 100644
index 00000000000..12d63a30c34
--- /dev/null
+++ b/include/linux/rotary_encoder.h
@@ -0,0 +1,13 @@
+#ifndef __ROTARY_ENCODER_H__
+#define __ROTARY_ENCODER_H__
+
+struct rotary_encoder_platform_data {
+ unsigned int steps;
+ unsigned int axis;
+ unsigned int gpio_a;
+ unsigned int gpio_b;
+ unsigned int inverted_a;
+ unsigned int inverted_b;
+};
+
+#endif /* __ROTARY_ENCODER_H__ */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 9da5aa0771e..b4c38bc8049 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -138,6 +138,8 @@ extern unsigned long nr_uninterruptible(void);
extern unsigned long nr_active(void);
extern unsigned long nr_iowait(void);
+extern unsigned long get_parent_ip(unsigned long addr);
+
struct seq_file;
struct cfs_rq;
struct task_group;
@@ -203,7 +205,8 @@ extern unsigned long long time_sync_thresh;
#define task_is_stopped_or_traced(task) \
((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0)
#define task_contributes_to_load(task) \
- ((task->state & TASK_UNINTERRUPTIBLE) != 0)
+ ((task->state & TASK_UNINTERRUPTIBLE) != 0 && \
+ (task->flags & PF_FROZEN) == 0)
#define __set_task_state(tsk, state_value) \
do { (tsk)->state = (state_value); } while (0)
@@ -298,17 +301,11 @@ extern int proc_dosoftlockup_thresh(struct ctl_table *table, int write,
struct file *filp, void __user *buffer,
size_t *lenp, loff_t *ppos);
extern unsigned int softlockup_panic;
-extern unsigned long sysctl_hung_task_check_count;
-extern unsigned long sysctl_hung_task_timeout_secs;
-extern unsigned long sysctl_hung_task_warnings;
extern int softlockup_thresh;
#else
static inline void softlockup_tick(void)
{
}
-static inline void spawn_softlockup_task(void)
-{
-}
static inline void touch_softlockup_watchdog(void)
{
}
@@ -317,6 +314,15 @@ static inline void touch_all_softlockup_watchdogs(void)
}
#endif
+#ifdef CONFIG_DETECT_HUNG_TASK
+extern unsigned int sysctl_hung_task_panic;
+extern unsigned long sysctl_hung_task_check_count;
+extern unsigned long sysctl_hung_task_timeout_secs;
+extern unsigned long sysctl_hung_task_warnings;
+extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write,
+ struct file *filp, void __user *buffer,
+ size_t *lenp, loff_t *ppos);
+#endif
/* Attach to any functions which should be ignored in wchan output. */
#define __sched __attribute__((__section__(".sched.text")))
@@ -1253,9 +1259,8 @@ struct task_struct {
/* ipc stuff */
struct sysv_sem sysvsem;
#endif
-#ifdef CONFIG_DETECT_SOFTLOCKUP
+#ifdef CONFIG_DETECT_HUNG_TASK
/* hung task detection */
- unsigned long last_switch_timestamp;
unsigned long last_switch_count;
#endif
/* CPU-specific state of this task */
@@ -1292,6 +1297,11 @@ struct task_struct {
/* Protection of (de-)allocation: mm, files, fs, tty, keyrings */
spinlock_t alloc_lock;
+#ifdef CONFIG_GENERIC_HARDIRQS
+ /* IRQ handler threads */
+ struct irqaction *irqaction;
+#endif
+
/* Protection of the PI data structures: */
spinlock_t pi_lock;
@@ -1405,6 +1415,8 @@ struct task_struct {
int curr_ret_stack;
/* Stack of return addresses for return function tracing */
struct ftrace_ret_stack *ret_stack;
+ /* time stamp for last schedule */
+ unsigned long long ftrace_timestamp;
/*
* Number of functions that haven't been traced
* because of depth overrun.
diff --git a/include/linux/security.h b/include/linux/security.h
index 54ed15799a8..d5fd6163606 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -32,6 +32,7 @@
#include <linux/sched.h>
#include <linux/key.h>
#include <linux/xfrm.h>
+#include <linux/gfp.h>
#include <net/flow.h>
/* Maximum number of letters for an LSM name string */
@@ -2953,5 +2954,28 @@ static inline void securityfs_remove(struct dentry *dentry)
#endif
+#ifdef CONFIG_SECURITY
+
+static inline char *alloc_secdata(void)
+{
+ return (char *)get_zeroed_page(GFP_KERNEL);
+}
+
+static inline void free_secdata(void *secdata)
+{
+ free_page((unsigned long)secdata);
+}
+
+#else
+
+static inline char *alloc_secdata(void)
+{
+ return (char *)1;
+}
+
+static inline void free_secdata(void *secdata)
+{ }
+#endif /* CONFIG_SECURITY */
+
#endif /* ! __LINUX_SECURITY_H */
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index df9245c7bd3..57a97e52e58 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -164,6 +164,9 @@
/* NWPSERIAL */
#define PORT_NWPSERIAL 85
+/* MAX3100 */
+#define PORT_MAX3100 86
+
#ifdef __KERNEL__
#include <linux/compiler.h>
@@ -277,7 +280,7 @@ struct uart_port {
struct uart_icount icount; /* statistics */
struct console *cons; /* struct console, if any */
-#ifdef CONFIG_SERIAL_CORE_CONSOLE
+#if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ)
unsigned long sysrq; /* sysrq timeout */
#endif
diff --git a/include/linux/serial_max3100.h b/include/linux/serial_max3100.h
new file mode 100644
index 00000000000..4976befb6ae
--- /dev/null
+++ b/include/linux/serial_max3100.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright (C) 2007 Christian Pellegrin
+ *
+ * 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 _LINUX_SERIAL_MAX3100_H
+#define _LINUX_SERIAL_MAX3100_H 1
+
+
+/**
+ * struct plat_max3100 - MAX3100 SPI UART platform data
+ * @loopback: force MAX3100 in loopback
+ * @crystal: 1 for 3.6864 Mhz, 0 for 1.8432
+ * @max3100_hw_suspend: MAX3100 has a shutdown pin. This is a hook
+ * called on suspend and resume to activate it.
+ * @poll_time: poll time for CTS signal in ms, 0 disables (so no hw
+ * flow ctrl is possible but you have less CPU usage)
+ *
+ * You should use this structure in your machine description to specify
+ * how the MAX3100 is connected. Example:
+ *
+ * static struct plat_max3100 max3100_plat_data = {
+ * .loopback = 0,
+ * .crystal = 0,
+ * .poll_time = 100,
+ * };
+ *
+ * static struct spi_board_info spi_board_info[] = {
+ * {
+ * .modalias = "max3100",
+ * .platform_data = &max3100_plat_data,
+ * .irq = IRQ_EINT12,
+ * .max_speed_hz = 5*1000*1000,
+ * .chip_select = 0,
+ * },
+ * };
+ *
+ **/
+struct plat_max3100 {
+ int loopback;
+ int crystal;
+ void (*max3100_hw_suspend) (int suspend);
+ int poll_time;
+};
+
+#endif
diff --git a/include/linux/sht15.h b/include/linux/sht15.h
new file mode 100644
index 00000000000..046bce05eca
--- /dev/null
+++ b/include/linux/sht15.h
@@ -0,0 +1,24 @@
+/*
+ * sht15.h - support for the SHT15 Temperature and Humidity Sensor
+ *
+ * Copyright (c) 2009 Jonathan Cameron
+ *
+ * Copyright (c) 2007 Wouter Horre
+ *
+ * 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.
+ */
+
+/**
+ * struct sht15_platform_data - sht15 connectivity info
+ * @gpio_data: no. of gpio to which bidirectional data line is connected
+ * @gpio_sck: no. of gpio to which the data clock is connected.
+ * @supply_mv: supply voltage in mv. Overridden by regulator if available.
+ **/
+struct sht15_platform_data {
+ int gpio_data;
+ int gpio_sck;
+ int supply_mv;
+};
+
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
index 6ca6a7b66d7..5ac9b0bcaf9 100644
--- a/include/linux/slab_def.h
+++ b/include/linux/slab_def.h
@@ -14,6 +14,7 @@
#include <asm/page.h> /* kmalloc_sizes.h needs PAGE_SIZE */
#include <asm/cache.h> /* kmalloc_sizes.h needs L1_CACHE_BYTES */
#include <linux/compiler.h>
+#include <trace/kmemtrace.h>
/* Size description struct for general caches. */
struct cache_sizes {
@@ -28,8 +29,26 @@ extern struct cache_sizes malloc_sizes[];
void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
void *__kmalloc(size_t size, gfp_t flags);
-static inline void *kmalloc(size_t size, gfp_t flags)
+#ifdef CONFIG_KMEMTRACE
+extern void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags);
+extern size_t slab_buffer_size(struct kmem_cache *cachep);
+#else
+static __always_inline void *
+kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags)
{
+ return kmem_cache_alloc(cachep, flags);
+}
+static inline size_t slab_buffer_size(struct kmem_cache *cachep)
+{
+ return 0;
+}
+#endif
+
+static __always_inline void *kmalloc(size_t size, gfp_t flags)
+{
+ struct kmem_cache *cachep;
+ void *ret;
+
if (__builtin_constant_p(size)) {
int i = 0;
@@ -47,10 +66,17 @@ static inline void *kmalloc(size_t size, gfp_t flags)
found:
#ifdef CONFIG_ZONE_DMA
if (flags & GFP_DMA)
- return kmem_cache_alloc(malloc_sizes[i].cs_dmacachep,
- flags);
+ cachep = malloc_sizes[i].cs_dmacachep;
+ else
#endif
- return kmem_cache_alloc(malloc_sizes[i].cs_cachep, flags);
+ cachep = malloc_sizes[i].cs_cachep;
+
+ ret = kmem_cache_alloc_notrace(cachep, flags);
+
+ trace_kmalloc(_THIS_IP_, ret,
+ size, slab_buffer_size(cachep), flags);
+
+ return ret;
}
return __kmalloc(size, flags);
}
@@ -59,8 +85,25 @@ found:
extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
-static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
+#ifdef CONFIG_KMEMTRACE
+extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep,
+ gfp_t flags,
+ int nodeid);
+#else
+static __always_inline void *
+kmem_cache_alloc_node_notrace(struct kmem_cache *cachep,
+ gfp_t flags,
+ int nodeid)
+{
+ return kmem_cache_alloc_node(cachep, flags, nodeid);
+}
+#endif
+
+static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
{
+ struct kmem_cache *cachep;
+ void *ret;
+
if (__builtin_constant_p(size)) {
int i = 0;
@@ -78,11 +121,18 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
found:
#ifdef CONFIG_ZONE_DMA
if (flags & GFP_DMA)
- return kmem_cache_alloc_node(malloc_sizes[i].cs_dmacachep,
- flags, node);
+ cachep = malloc_sizes[i].cs_dmacachep;
+ else
#endif
- return kmem_cache_alloc_node(malloc_sizes[i].cs_cachep,
- flags, node);
+ cachep = malloc_sizes[i].cs_cachep;
+
+ ret = kmem_cache_alloc_node_notrace(cachep, flags, node);
+
+ trace_kmalloc_node(_THIS_IP_, ret,
+ size, slab_buffer_size(cachep),
+ flags, node);
+
+ return ret;
}
return __kmalloc_node(size, flags, node);
}
diff --git a/include/linux/slob_def.h b/include/linux/slob_def.h
index 59a3fa476ab..0ec00b39d00 100644
--- a/include/linux/slob_def.h
+++ b/include/linux/slob_def.h
@@ -3,14 +3,15 @@
void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
-static inline void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
+static __always_inline void *kmem_cache_alloc(struct kmem_cache *cachep,
+ gfp_t flags)
{
return kmem_cache_alloc_node(cachep, flags, -1);
}
void *__kmalloc_node(size_t size, gfp_t flags, int node);
-static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
+static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
{
return __kmalloc_node(size, flags, node);
}
@@ -23,12 +24,12 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
* kmalloc is the normal method of allocating memory
* in the kernel.
*/
-static inline void *kmalloc(size_t size, gfp_t flags)
+static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
return __kmalloc_node(size, flags, -1);
}
-static inline void *__kmalloc(size_t size, gfp_t flags)
+static __always_inline void *__kmalloc(size_t size, gfp_t flags)
{
return kmalloc(size, flags);
}
diff --git a/include/linux/slow-work.h b/include/linux/slow-work.h
new file mode 100644
index 00000000000..85958277f83
--- /dev/null
+++ b/include/linux/slow-work.h
@@ -0,0 +1,95 @@
+/* Worker thread pool for slow items, such as filesystem lookups or mkdirs
+ *
+ * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ *
+ * See Documentation/slow-work.txt
+ */
+
+#ifndef _LINUX_SLOW_WORK_H
+#define _LINUX_SLOW_WORK_H
+
+#ifdef CONFIG_SLOW_WORK
+
+#include <linux/sysctl.h>
+
+struct slow_work;
+
+/*
+ * The operations used to support slow work items
+ */
+struct slow_work_ops {
+ /* get a ref on a work item
+ * - return 0 if successful, -ve if not
+ */
+ int (*get_ref)(struct slow_work *work);
+
+ /* discard a ref to a work item */
+ void (*put_ref)(struct slow_work *work);
+
+ /* execute a work item */
+ void (*execute)(struct slow_work *work);
+};
+
+/*
+ * A slow work item
+ * - A reference is held on the parent object by the thread pool when it is
+ * queued
+ */
+struct slow_work {
+ unsigned long flags;
+#define SLOW_WORK_PENDING 0 /* item pending (further) execution */
+#define SLOW_WORK_EXECUTING 1 /* item currently executing */
+#define SLOW_WORK_ENQ_DEFERRED 2 /* item enqueue deferred */
+#define SLOW_WORK_VERY_SLOW 3 /* item is very slow */
+ const struct slow_work_ops *ops; /* operations table for this item */
+ struct list_head link; /* link in queue */
+};
+
+/**
+ * slow_work_init - Initialise a slow work item
+ * @work: The work item to initialise
+ * @ops: The operations to use to handle the slow work item
+ *
+ * Initialise a slow work item.
+ */
+static inline void slow_work_init(struct slow_work *work,
+ const struct slow_work_ops *ops)
+{
+ work->flags = 0;
+ work->ops = ops;
+ INIT_LIST_HEAD(&work->link);
+}
+
+/**
+ * slow_work_init - Initialise a very slow work item
+ * @work: The work item to initialise
+ * @ops: The operations to use to handle the slow work item
+ *
+ * Initialise a very slow work item. This item will be restricted such that
+ * only a certain number of the pool threads will be able to execute items of
+ * this type.
+ */
+static inline void vslow_work_init(struct slow_work *work,
+ const struct slow_work_ops *ops)
+{
+ work->flags = 1 << SLOW_WORK_VERY_SLOW;
+ work->ops = ops;
+ INIT_LIST_HEAD(&work->link);
+}
+
+extern int slow_work_enqueue(struct slow_work *work);
+extern int slow_work_register_user(void);
+extern void slow_work_unregister_user(void);
+
+#ifdef CONFIG_SYSCTL
+extern ctl_table slow_work_sysctls[];
+#endif
+
+#endif /* CONFIG_SLOW_WORK */
+#endif /* _LINUX_SLOW_WORK_H */
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index e37b6aa8a9f..5046f90c117 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -10,6 +10,7 @@
#include <linux/gfp.h>
#include <linux/workqueue.h>
#include <linux/kobject.h>
+#include <trace/kmemtrace.h>
enum stat_item {
ALLOC_FASTPATH, /* Allocation from cpu slab */
@@ -217,13 +218,30 @@ static __always_inline struct kmem_cache *kmalloc_slab(size_t size)
void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
void *__kmalloc(size_t size, gfp_t flags);
+#ifdef CONFIG_KMEMTRACE
+extern void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags);
+#else
+static __always_inline void *
+kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags)
+{
+ return kmem_cache_alloc(s, gfpflags);
+}
+#endif
+
static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
{
- return (void *)__get_free_pages(flags | __GFP_COMP, get_order(size));
+ unsigned int order = get_order(size);
+ void *ret = (void *) __get_free_pages(flags | __GFP_COMP, order);
+
+ trace_kmalloc(_THIS_IP_, ret, size, PAGE_SIZE << order, flags);
+
+ return ret;
}
static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
+ void *ret;
+
if (__builtin_constant_p(size)) {
if (size > SLUB_MAX_SIZE)
return kmalloc_large(size, flags);
@@ -234,7 +252,11 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags)
if (!s)
return ZERO_SIZE_PTR;
- return kmem_cache_alloc(s, flags);
+ ret = kmem_cache_alloc_notrace(s, flags);
+
+ trace_kmalloc(_THIS_IP_, ret, size, s->size, flags);
+
+ return ret;
}
}
return __kmalloc(size, flags);
@@ -244,8 +266,24 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags)
void *__kmalloc_node(size_t size, gfp_t flags, int node);
void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
+#ifdef CONFIG_KMEMTRACE
+extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *s,
+ gfp_t gfpflags,
+ int node);
+#else
+static __always_inline void *
+kmem_cache_alloc_node_notrace(struct kmem_cache *s,
+ gfp_t gfpflags,
+ int node)
+{
+ return kmem_cache_alloc_node(s, gfpflags, node);
+}
+#endif
+
static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
{
+ void *ret;
+
if (__builtin_constant_p(size) &&
size <= SLUB_MAX_SIZE && !(flags & SLUB_DMA)) {
struct kmem_cache *s = kmalloc_slab(size);
@@ -253,7 +291,12 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
if (!s)
return ZERO_SIZE_PTR;
- return kmem_cache_alloc_node(s, flags, node);
+ ret = kmem_cache_alloc_node_notrace(s, flags, node);
+
+ trace_kmalloc_node(_THIS_IP_, ret,
+ size, s->size, flags, node);
+
+ return ret;
}
return __kmalloc_node(size, flags, node);
}
diff --git a/include/linux/smp.h b/include/linux/smp.h
index bbacb7baa44..a69db820eed 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -38,7 +38,7 @@ int smp_call_function_single(int cpuid, void (*func) (void *info), void *info,
/*
* main cross-CPU interfaces, handles INIT, TLB flush, STOP, etc.
* (defined in asm header):
- */
+ */
/*
* stops all CPUs but the current one:
@@ -82,7 +82,8 @@ smp_call_function_mask(cpumask_t mask, void(*func)(void *info), void *info,
return 0;
}
-void __smp_call_function_single(int cpuid, struct call_single_data *data);
+void __smp_call_function_single(int cpuid, struct call_single_data *data,
+ int wait);
/*
* Generic and arch helpers
@@ -121,6 +122,8 @@ extern unsigned int setup_max_cpus;
#else /* !SMP */
+static inline void smp_send_stop(void) { }
+
/*
* These macros fold the SMP functionality into a single CPU system
*/
diff --git a/include/linux/sonypi.h b/include/linux/sonypi.h
index f41ffd7c2dd..34c4475ac4a 100644
--- a/include/linux/sonypi.h
+++ b/include/linux/sonypi.h
@@ -103,6 +103,14 @@
#define SONYPI_EVENT_WIRELESS_OFF 61
#define SONYPI_EVENT_ZOOM_IN_PRESSED 62
#define SONYPI_EVENT_ZOOM_OUT_PRESSED 63
+#define SONYPI_EVENT_CD_EJECT_PRESSED 64
+#define SONYPI_EVENT_MODEKEY_PRESSED 65
+#define SONYPI_EVENT_PKEY_P4 66
+#define SONYPI_EVENT_PKEY_P5 67
+#define SONYPI_EVENT_SETTINGKEY_PRESSED 68
+#define SONYPI_EVENT_VOLUME_INC_PRESSED 69
+#define SONYPI_EVENT_VOLUME_DEC_PRESSED 70
+#define SONYPI_EVENT_BRIGHTNESS_PRESSED 71
/* get/set brightness */
#define SONYPI_IOCGBRT _IOR('v', 0, __u8)
diff --git a/include/linux/spi/ad7879.h b/include/linux/spi/ad7879.h
new file mode 100644
index 00000000000..4231104c9af
--- /dev/null
+++ b/include/linux/spi/ad7879.h
@@ -0,0 +1,35 @@
+/* linux/spi/ad7879.h */
+
+/* Touchscreen characteristics vary between boards and models. The
+ * platform_data for the device's "struct device" holds this information.
+ *
+ * It's OK if the min/max values are zero.
+ */
+struct ad7879_platform_data {
+ u16 model; /* 7879 */
+ u16 x_plate_ohms;
+ u16 x_min, x_max;
+ u16 y_min, y_max;
+ u16 pressure_min, pressure_max;
+
+ /* [0..255] 0=OFF Starts at 1=550us and goes
+ * all the way to 9.440ms in steps of 35us.
+ */
+ u8 pen_down_acc_interval;
+ /* [0..15] Starts at 0=128us and goes all the
+ * way to 4.096ms in steps of 128us.
+ */
+ u8 first_conversion_delay;
+ /* [0..3] 0 = 2us, 1 = 4us, 2 = 8us, 3 = 16us */
+ u8 acquisition_time;
+ /* [0..3] Average X middle samples 0 = 2, 1 = 4, 2 = 8, 3 = 16 */
+ u8 averaging;
+ /* [0..3] Perform X measurements 0 = OFF,
+ * 1 = 4, 2 = 8, 3 = 16 (median > averaging)
+ */
+ u8 median;
+ /* 1 = AUX/VBAT/GPIO set to GPIO Output */
+ u8 gpio_output;
+ /* Initial GPIO pin state (valid if gpio_output = 1) */
+ u8 gpio_default;
+};
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 68bb1c501d0..2cc43fa380c 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -204,6 +204,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
* SPI slaves, and are numbered from zero to num_chipselects.
* each slave has a chipselect signal, but it's common that not
* every chipselect is connected to a slave.
+ * @dma_alignment: SPI controller constraint on DMA buffers alignment.
* @setup: updates the device mode and clocking records used by a
* device's SPI controller; protocol code may call this. This
* must fail if an unrecognized or unsupported mode is requested.
@@ -239,6 +240,11 @@ struct spi_master {
*/
u16 num_chipselect;
+ /* some SPI controllers pose alignment requirements on DMAable
+ * buffers; let protocol drivers know about these requirements.
+ */
+ u16 dma_alignment;
+
/* setup mode and clock, etc (spi driver may call many times) */
int (*setup)(struct spi_device *spi);
diff --git a/include/linux/string.h b/include/linux/string.h
index 8852739f36d..489019ef169 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -10,6 +10,7 @@
#include <linux/compiler.h> /* for inline */
#include <linux/types.h> /* for size_t */
#include <linux/stddef.h> /* for NULL */
+#include <stdarg.h>
extern char *strndup_user(const char __user *, long);
extern void *memdup_user(const void __user *, size_t);
@@ -112,8 +113,23 @@ extern void argv_free(char **argv);
extern bool sysfs_streq(const char *s1, const char *s2);
+#ifdef CONFIG_BINARY_PRINTF
+int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
+int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf);
+int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4);
+#endif
+
extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
const void *from, size_t available);
+/**
+ * strstarts - does @str start with @prefix?
+ * @str: string to examine
+ * @prefix: prefix to look for.
+ */
+static inline bool strstarts(const char *str, const char *prefix)
+{
+ return strncmp(str, prefix, strlen(prefix)) == 0;
+}
#endif
#endif /* _LINUX_STRING_H_ */
diff --git a/include/linux/stringify.h b/include/linux/stringify.h
index 0b4388356c8..841cec8ed52 100644
--- a/include/linux/stringify.h
+++ b/include/linux/stringify.h
@@ -6,7 +6,7 @@
* converts to "bar".
*/
-#define __stringify_1(x) #x
-#define __stringify(x) __stringify_1(x)
+#define __stringify_1(x...) #x
+#define __stringify(x...) __stringify_1(x)
#endif /* !__LINUX_STRINGIFY_H */
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index d3a4c023193..2a30775959e 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -24,6 +24,15 @@
*/
typedef int (*svc_thread_fn)(void *);
+/* statistics for svc_pool structures */
+struct svc_pool_stats {
+ unsigned long packets;
+ unsigned long sockets_queued;
+ unsigned long threads_woken;
+ unsigned long overloads_avoided;
+ unsigned long threads_timedout;
+};
+
/*
*
* RPC service thread pool.
@@ -41,6 +50,8 @@ struct svc_pool {
struct list_head sp_sockets; /* pending sockets */
unsigned int sp_nrthreads; /* # of threads in pool */
struct list_head sp_all_threads; /* all server threads */
+ int sp_nwaking; /* number of threads woken but not yet active */
+ struct svc_pool_stats sp_stats; /* statistics on pool operation */
} ____cacheline_aligned_in_smp;
/*
@@ -83,6 +94,8 @@ struct svc_serv {
struct module * sv_module; /* optional module to count when
* adding threads */
svc_thread_fn sv_function; /* main function for threads */
+ unsigned int sv_drc_max_pages; /* Total pages for DRC */
+ unsigned int sv_drc_pages_used;/* DRC pages used */
};
/*
@@ -218,6 +231,7 @@ struct svc_rqst {
struct svc_cred rq_cred; /* auth info */
void * rq_xprt_ctxt; /* transport specific context ptr */
struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */
+ int rq_usedeferral; /* use deferral */
size_t rq_xprt_hlen; /* xprt header len */
struct xdr_buf rq_arg;
@@ -263,6 +277,7 @@ struct svc_rqst {
* cache pages */
wait_queue_head_t rq_wait; /* synchronization */
struct task_struct *rq_task; /* service thread */
+ int rq_waking; /* 1 if thread is being woken */
};
/*
@@ -393,6 +408,7 @@ struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int,
void (*shutdown)(struct svc_serv *),
svc_thread_fn, struct module *);
int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
+int svc_pool_stats_open(struct svc_serv *serv, struct file *file);
void svc_destroy(struct svc_serv *);
int svc_process(struct svc_rqst *);
int svc_register(const struct svc_serv *, const int,
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 49e1eb45446..d8910b68e1b 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -69,27 +69,27 @@ struct xdr_buf {
* pre-xdr'ed macros.
*/
-#define xdr_zero __constant_htonl(0)
-#define xdr_one __constant_htonl(1)
-#define xdr_two __constant_htonl(2)
-
-#define rpc_success __constant_htonl(RPC_SUCCESS)
-#define rpc_prog_unavail __constant_htonl(RPC_PROG_UNAVAIL)
-#define rpc_prog_mismatch __constant_htonl(RPC_PROG_MISMATCH)
-#define rpc_proc_unavail __constant_htonl(RPC_PROC_UNAVAIL)
-#define rpc_garbage_args __constant_htonl(RPC_GARBAGE_ARGS)
-#define rpc_system_err __constant_htonl(RPC_SYSTEM_ERR)
-#define rpc_drop_reply __constant_htonl(RPC_DROP_REPLY)
-
-#define rpc_auth_ok __constant_htonl(RPC_AUTH_OK)
-#define rpc_autherr_badcred __constant_htonl(RPC_AUTH_BADCRED)
-#define rpc_autherr_rejectedcred __constant_htonl(RPC_AUTH_REJECTEDCRED)
-#define rpc_autherr_badverf __constant_htonl(RPC_AUTH_BADVERF)
-#define rpc_autherr_rejectedverf __constant_htonl(RPC_AUTH_REJECTEDVERF)
-#define rpc_autherr_tooweak __constant_htonl(RPC_AUTH_TOOWEAK)
-#define rpcsec_gsserr_credproblem __constant_htonl(RPCSEC_GSS_CREDPROBLEM)
-#define rpcsec_gsserr_ctxproblem __constant_htonl(RPCSEC_GSS_CTXPROBLEM)
-#define rpc_autherr_oldseqnum __constant_htonl(101)
+#define xdr_zero cpu_to_be32(0)
+#define xdr_one cpu_to_be32(1)
+#define xdr_two cpu_to_be32(2)
+
+#define rpc_success cpu_to_be32(RPC_SUCCESS)
+#define rpc_prog_unavail cpu_to_be32(RPC_PROG_UNAVAIL)
+#define rpc_prog_mismatch cpu_to_be32(RPC_PROG_MISMATCH)
+#define rpc_proc_unavail cpu_to_be32(RPC_PROC_UNAVAIL)
+#define rpc_garbage_args cpu_to_be32(RPC_GARBAGE_ARGS)
+#define rpc_system_err cpu_to_be32(RPC_SYSTEM_ERR)
+#define rpc_drop_reply cpu_to_be32(RPC_DROP_REPLY)
+
+#define rpc_auth_ok cpu_to_be32(RPC_AUTH_OK)
+#define rpc_autherr_badcred cpu_to_be32(RPC_AUTH_BADCRED)
+#define rpc_autherr_rejectedcred cpu_to_be32(RPC_AUTH_REJECTEDCRED)
+#define rpc_autherr_badverf cpu_to_be32(RPC_AUTH_BADVERF)
+#define rpc_autherr_rejectedverf cpu_to_be32(RPC_AUTH_REJECTEDVERF)
+#define rpc_autherr_tooweak cpu_to_be32(RPC_AUTH_TOOWEAK)
+#define rpcsec_gsserr_credproblem cpu_to_be32(RPCSEC_GSS_CREDPROBLEM)
+#define rpcsec_gsserr_ctxproblem cpu_to_be32(RPCSEC_GSS_CTXPROBLEM)
+#define rpc_autherr_oldseqnum cpu_to_be32(101)
/*
* Miscellaneous XDR helper functions
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index b299a82a05e..dabe4ad8914 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -65,6 +65,7 @@ struct old_linux_dirent;
#include <asm/signal.h>
#include <linux/quota.h>
#include <linux/key.h>
+#include <trace/syscall.h>
#define __SC_DECL1(t1, a1) t1 a1
#define __SC_DECL2(t2, a2, ...) t2 a2, __SC_DECL1(__VA_ARGS__)
@@ -95,7 +96,46 @@ struct old_linux_dirent;
#define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__)
#define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__)
+#ifdef CONFIG_FTRACE_SYSCALLS
+#define __SC_STR_ADECL1(t, a) #a
+#define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__)
+#define __SC_STR_ADECL3(t, a, ...) #a, __SC_STR_ADECL2(__VA_ARGS__)
+#define __SC_STR_ADECL4(t, a, ...) #a, __SC_STR_ADECL3(__VA_ARGS__)
+#define __SC_STR_ADECL5(t, a, ...) #a, __SC_STR_ADECL4(__VA_ARGS__)
+#define __SC_STR_ADECL6(t, a, ...) #a, __SC_STR_ADECL5(__VA_ARGS__)
+
+#define __SC_STR_TDECL1(t, a) #t
+#define __SC_STR_TDECL2(t, a, ...) #t, __SC_STR_TDECL1(__VA_ARGS__)
+#define __SC_STR_TDECL3(t, a, ...) #t, __SC_STR_TDECL2(__VA_ARGS__)
+#define __SC_STR_TDECL4(t, a, ...) #t, __SC_STR_TDECL3(__VA_ARGS__)
+#define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__)
+#define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__)
+
+#define SYSCALL_METADATA(sname, nb) \
+ static const struct syscall_metadata __used \
+ __attribute__((__aligned__(4))) \
+ __attribute__((section("__syscalls_metadata"))) \
+ __syscall_meta_##sname = { \
+ .name = "sys"#sname, \
+ .nb_args = nb, \
+ .types = types_##sname, \
+ .args = args_##sname, \
+ }
+
+#define SYSCALL_DEFINE0(sname) \
+ static const struct syscall_metadata __used \
+ __attribute__((__aligned__(4))) \
+ __attribute__((section("__syscalls_metadata"))) \
+ __syscall_meta_##sname = { \
+ .name = "sys_"#sname, \
+ .nb_args = 0, \
+ }; \
+ asmlinkage long sys_##sname(void)
+
+#else
#define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void)
+#endif
+
#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
@@ -117,10 +157,26 @@ struct old_linux_dirent;
#endif
#endif
+#ifdef CONFIG_FTRACE_SYSCALLS
+#define SYSCALL_DEFINEx(x, sname, ...) \
+ static const char *types_##sname[] = { \
+ __SC_STR_TDECL##x(__VA_ARGS__) \
+ }; \
+ static const char *args_##sname[] = { \
+ __SC_STR_ADECL##x(__VA_ARGS__) \
+ }; \
+ SYSCALL_METADATA(sname, x); \
+ __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
+#else
+#define SYSCALL_DEFINEx(x, sname, ...) \
+ __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
+#endif
+
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
#define SYSCALL_DEFINE(name) static inline long SYSC_##name
-#define SYSCALL_DEFINEx(x, name, ...) \
+
+#define __SYSCALL_DEFINEx(x, name, ...) \
asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)); \
static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)); \
asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__)) \
@@ -134,7 +190,7 @@ struct old_linux_dirent;
#else /* CONFIG_HAVE_SYSCALL_WRAPPERS */
#define SYSCALL_DEFINE(name) asmlinkage long sys_##name
-#define SYSCALL_DEFINEx(x, name, ...) \
+#define __SYSCALL_DEFINEx(x, name, ...) \
asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))
#endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */
@@ -462,9 +518,9 @@ asmlinkage long sys_pread64(unsigned int fd, char __user *buf,
asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf,
size_t count, loff_t pos);
asmlinkage long sys_preadv(unsigned long fd, const struct iovec __user *vec,
- unsigned long vlen, u32 pos_high, u32 pos_low);
+ unsigned long vlen, unsigned long pos_l, unsigned long pos_h);
asmlinkage long sys_pwritev(unsigned long fd, const struct iovec __user *vec,
- unsigned long vlen, u32 pos_high, u32 pos_low);
+ unsigned long vlen, unsigned long pos_l, unsigned long pos_h);
asmlinkage long sys_getcwd(char __user *buf, unsigned long size);
asmlinkage long sys_mkdir(const char __user *pathname, int mode);
asmlinkage long sys_chdir(const char __user *filename);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 917707e6151..1de8b9eb841 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -27,27 +27,46 @@
#include <linux/idr.h>
#include <linux/device.h>
+#include <linux/workqueue.h>
struct thermal_zone_device;
struct thermal_cooling_device;
+enum thermal_device_mode {
+ THERMAL_DEVICE_DISABLED = 0,
+ THERMAL_DEVICE_ENABLED,
+};
+
+enum thermal_trip_type {
+ THERMAL_TRIP_ACTIVE = 0,
+ THERMAL_TRIP_PASSIVE,
+ THERMAL_TRIP_HOT,
+ THERMAL_TRIP_CRITICAL,
+};
+
struct thermal_zone_device_ops {
int (*bind) (struct thermal_zone_device *,
struct thermal_cooling_device *);
int (*unbind) (struct thermal_zone_device *,
struct thermal_cooling_device *);
- int (*get_temp) (struct thermal_zone_device *, char *);
- int (*get_mode) (struct thermal_zone_device *, char *);
- int (*set_mode) (struct thermal_zone_device *, const char *);
- int (*get_trip_type) (struct thermal_zone_device *, int, char *);
- int (*get_trip_temp) (struct thermal_zone_device *, int, char *);
+ int (*get_temp) (struct thermal_zone_device *, unsigned long *);
+ int (*get_mode) (struct thermal_zone_device *,
+ enum thermal_device_mode *);
+ int (*set_mode) (struct thermal_zone_device *,
+ enum thermal_device_mode);
+ int (*get_trip_type) (struct thermal_zone_device *, int,
+ enum thermal_trip_type *);
+ int (*get_trip_temp) (struct thermal_zone_device *, int,
+ unsigned long *);
int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
+ int (*notify) (struct thermal_zone_device *, int,
+ enum thermal_trip_type);
};
struct thermal_cooling_device_ops {
- int (*get_max_state) (struct thermal_cooling_device *, char *);
- int (*get_cur_state) (struct thermal_cooling_device *, char *);
- int (*set_cur_state) (struct thermal_cooling_device *, unsigned int);
+ int (*get_max_state) (struct thermal_cooling_device *, unsigned long *);
+ int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *);
+ int (*set_cur_state) (struct thermal_cooling_device *, unsigned long);
};
#define THERMAL_TRIPS_NONE -1
@@ -88,11 +107,19 @@ struct thermal_zone_device {
struct device device;
void *devdata;
int trips;
+ int tc1;
+ int tc2;
+ int passive_delay;
+ int polling_delay;
+ int last_temperature;
+ bool passive;
+ unsigned int forced_passive;
struct thermal_zone_device_ops *ops;
struct list_head cooling_devices;
struct idr idr;
struct mutex lock; /* protect cooling devices list */
struct list_head node;
+ struct delayed_work poll_queue;
#if defined(CONFIG_THERMAL_HWMON)
struct list_head hwmon_node;
struct thermal_hwmon_device *hwmon;
@@ -104,13 +131,16 @@ struct thermal_zone_device {
struct thermal_zone_device *thermal_zone_device_register(char *, int, void *,
struct
thermal_zone_device_ops
- *);
+ *, int tc1, int tc2,
+ int passive_freq,
+ int polling_freq);
void thermal_zone_device_unregister(struct thermal_zone_device *);
int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
struct thermal_cooling_device *);
int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
struct thermal_cooling_device *);
+void thermal_zone_device_update(struct thermal_zone_device *);
struct thermal_cooling_device *thermal_cooling_device_register(char *, void *,
struct
thermal_cooling_device_ops
diff --git a/include/linux/timeriomem-rng.h b/include/linux/timeriomem-rng.h
index dd253177f65..3e08a1c8683 100644
--- a/include/linux/timeriomem-rng.h
+++ b/include/linux/timeriomem-rng.h
@@ -14,7 +14,7 @@ struct timeriomem_rng_data {
struct completion completion;
unsigned int present:1;
- u32 __iomem *address;
+ void __iomem *address;
/* measures in usecs */
unsigned int period;
diff --git a/include/linux/topology.h b/include/linux/topology.h
index a16b9e06f2e..7402c1a27c4 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -38,11 +38,7 @@
#endif
#ifndef nr_cpus_node
-#define nr_cpus_node(node) \
- ({ \
- node_to_cpumask_ptr(__tmp__, node); \
- cpus_weight(*__tmp__); \
- })
+#define nr_cpus_node(node) cpumask_weight(cpumask_of_node(node))
#endif
#define for_each_node_with_cpus(node) \
@@ -200,4 +196,9 @@ int arch_update_cpu_topology(void);
#define topology_core_cpumask(cpu) cpumask_of(cpu)
#endif
+/* Returns the number of the current Node. */
+#ifndef numa_node_id
+#define numa_node_id() (cpu_to_node(raw_smp_processor_id()))
+#endif
+
#endif /* _LINUX_TOPOLOGY_H */
diff --git a/include/linux/trace_clock.h b/include/linux/trace_clock.h
new file mode 100644
index 00000000000..7a813038408
--- /dev/null
+++ b/include/linux/trace_clock.h
@@ -0,0 +1,19 @@
+#ifndef _LINUX_TRACE_CLOCK_H
+#define _LINUX_TRACE_CLOCK_H
+
+/*
+ * 3 trace clock variants, with differing scalability/precision
+ * tradeoffs:
+ *
+ * - local: CPU-local trace clock
+ * - medium: scalable global clock with some jitter
+ * - global: globally monotonic, serialized clock
+ */
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+extern u64 notrace trace_clock_local(void);
+extern u64 notrace trace_clock(void);
+extern u64 notrace trace_clock_global(void);
+
+#endif /* _LINUX_TRACE_CLOCK_H */
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 75700545836..d35a7ee7611 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -31,8 +31,8 @@ struct tracepoint {
* Keep in sync with vmlinux.lds.h.
*/
-#define TPPROTO(args...) args
-#define TPARGS(args...) args
+#define TP_PROTO(args...) args
+#define TP_ARGS(args...) args
#ifdef CONFIG_TRACEPOINTS
@@ -65,7 +65,7 @@ struct tracepoint {
{ \
if (unlikely(__tracepoint_##name.state)) \
__DO_TRACE(&__tracepoint_##name, \
- TPPROTO(proto), TPARGS(args)); \
+ TP_PROTO(proto), TP_ARGS(args)); \
} \
static inline int register_trace_##name(void (*probe)(proto)) \
{ \
@@ -153,4 +153,114 @@ static inline void tracepoint_synchronize_unregister(void)
synchronize_sched();
}
+#define PARAMS(args...) args
+#define TRACE_FORMAT(name, proto, args, fmt) \
+ DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
+
+
+/*
+ * For use with the TRACE_EVENT macro:
+ *
+ * We define a tracepoint, its arguments, its printk format
+ * and its 'fast binay record' layout.
+ *
+ * Firstly, name your tracepoint via TRACE_EVENT(name : the
+ * 'subsystem_event' notation is fine.
+ *
+ * Think about this whole construct as the
+ * 'trace_sched_switch() function' from now on.
+ *
+ *
+ * TRACE_EVENT(sched_switch,
+ *
+ * *
+ * * A function has a regular function arguments
+ * * prototype, declare it via TP_PROTO():
+ * *
+ *
+ * TP_PROTO(struct rq *rq, struct task_struct *prev,
+ * struct task_struct *next),
+ *
+ * *
+ * * Define the call signature of the 'function'.
+ * * (Design sidenote: we use this instead of a
+ * * TP_PROTO1/TP_PROTO2/TP_PROTO3 ugliness.)
+ * *
+ *
+ * TP_ARGS(rq, prev, next),
+ *
+ * *
+ * * Fast binary tracing: define the trace record via
+ * * TP_STRUCT__entry(). You can think about it like a
+ * * regular C structure local variable definition.
+ * *
+ * * This is how the trace record is structured and will
+ * * be saved into the ring buffer. These are the fields
+ * * that will be exposed to user-space in
+ * * /debug/tracing/events/<*>/format.
+ * *
+ * * The declared 'local variable' is called '__entry'
+ * *
+ * * __field(pid_t, prev_prid) is equivalent to a standard declariton:
+ * *
+ * * pid_t prev_pid;
+ * *
+ * * __array(char, prev_comm, TASK_COMM_LEN) is equivalent to:
+ * *
+ * * char prev_comm[TASK_COMM_LEN];
+ * *
+ *
+ * TP_STRUCT__entry(
+ * __array( char, prev_comm, TASK_COMM_LEN )
+ * __field( pid_t, prev_pid )
+ * __field( int, prev_prio )
+ * __array( char, next_comm, TASK_COMM_LEN )
+ * __field( pid_t, next_pid )
+ * __field( int, next_prio )
+ * ),
+ *
+ * *
+ * * Assign the entry into the trace record, by embedding
+ * * a full C statement block into TP_fast_assign(). You
+ * * can refer to the trace record as '__entry' -
+ * * otherwise you can put arbitrary C code in here.
+ * *
+ * * Note: this C code will execute every time a trace event
+ * * happens, on an active tracepoint.
+ * *
+ *
+ * TP_fast_assign(
+ * memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
+ * __entry->prev_pid = prev->pid;
+ * __entry->prev_prio = prev->prio;
+ * memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
+ * __entry->next_pid = next->pid;
+ * __entry->next_prio = next->prio;
+ * )
+ *
+ * *
+ * * Formatted output of a trace record via TP_printk().
+ * * This is how the tracepoint will appear under ftrace
+ * * plugins that make use of this tracepoint.
+ * *
+ * * (raw-binary tracing wont actually perform this step.)
+ * *
+ *
+ * TP_printk("task %s:%d [%d] ==> %s:%d [%d]",
+ * __entry->prev_comm, __entry->prev_pid, __entry->prev_prio,
+ * __entry->next_comm, __entry->next_pid, __entry->next_prio),
+ *
+ * );
+ *
+ * This macro construct is thus used for the regular printk format
+ * tracing setup, it is used to construct a function pointer based
+ * tracepoint callback (this is used by programmatic plugins and
+ * can also by used by generic instrumentation like SystemTap), and
+ * it is also used to expose a structured trace record in
+ * /debug/tracing/events/.
+ */
+
+#define TRACE_EVENT(name, proto, args, struct, assign, print) \
+ DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
+
#endif
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 8615d661ab6..bcba84ea2d8 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -309,7 +309,8 @@ extern void tty_set_operations(struct tty_driver *driver,
extern struct tty_driver *tty_find_polling_driver(char *name, int *line);
extern void tty_driver_kref_put(struct tty_driver *driver);
-extern inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d)
+
+static inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d)
{
kref_get(&d->kref);
return d;
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index b9584254259..625e9e4639c 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -29,7 +29,7 @@
/**
* usb_serial_port: structure for the specific ports of a device.
* @serial: pointer back to the struct usb_serial owner of this port.
- * @tty: pointer to the corresponding tty for this port.
+ * @port: pointer to the corresponding tty_port for this port.
* @lock: spinlock to grab when updating portions of this structure.
* @mutex: mutex used to synchronize serial_open() and serial_close()
* access for this port.
@@ -44,19 +44,22 @@
* @interrupt_out_endpointAddress: endpoint address for the interrupt out pipe
* for this port.
* @bulk_in_buffer: pointer to the bulk in buffer for this port.
+ * @bulk_in_size: the size of the bulk_in_buffer, in bytes.
* @read_urb: pointer to the bulk in struct urb for this port.
* @bulk_in_endpointAddress: endpoint address for the bulk in pipe for this
* port.
* @bulk_out_buffer: pointer to the bulk out buffer for this port.
* @bulk_out_size: the size of the bulk_out_buffer, in bytes.
* @write_urb: pointer to the bulk out struct urb for this port.
+ * @write_urb_busy: port`s writing status
* @bulk_out_endpointAddress: endpoint address for the bulk out pipe for this
* port.
* @write_wait: a wait_queue_head_t used by the port.
* @work: work queue entry for the line discipline waking up.
- * @open_count: number of times this port has been opened.
* @throttled: nonzero if the read urb is inactive to throttle the device
* @throttle_req: nonzero if the tty wants to throttle us
+ * @console: attached usb serial console
+ * @dev: pointer to the serial device
*
* This structure is used by the usb-serial core and drivers for the specific
* ports of a device.
diff --git a/include/linux/usb/wusb.h b/include/linux/usb/wusb.h
index 5f401b644ed..429c631d2aa 100644
--- a/include/linux/usb/wusb.h
+++ b/include/linux/usb/wusb.h
@@ -80,8 +80,7 @@ struct wusb_ckhdid {
u8 data[16];
} __attribute__((packed));
-const static
-struct wusb_ckhdid wusb_ckhdid_zero = { .data = { 0 } };
+static const struct wusb_ckhdid wusb_ckhdid_zero = { .data = { 0 } };
#define WUSB_CKHDID_STRSIZE (3 * sizeof(struct wusb_ckhdid) + 1)
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 139d234923c..ebb2ea6b499 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -737,6 +737,11 @@ struct v4l2_input {
#define V4L2_IN_ST_NO_SIGNAL 0x00000002
#define V4L2_IN_ST_NO_COLOR 0x00000004
+/* field 'status' - sensor orientation */
+/* If sensor is mounted upside down set both bits */
+#define V4L2_IN_ST_HFLIP 0x00000010 /* Frames are flipped horizontally */
+#define V4L2_IN_ST_VFLIP 0x00000020 /* Frames are flipped vertically */
+
/* field 'status' - analog */
#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */
#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 93445477f86..9c1ed1fb6dd 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -168,6 +168,8 @@ void writeback_set_ratelimit(void);
/* pdflush.c */
extern int nr_pdflush_threads; /* Global so it can be exported to sysctl
read-only. */
+extern int nr_pdflush_threads_max; /* Global so it can be exported to sysctl */
+extern int nr_pdflush_threads_min; /* Global so it can be exported to sysctl */
#endif /* WRITEBACK_H */
diff --git a/include/media/msp3400.h b/include/media/msp3400.h
index 6ab854931c0..90cf22ada8b 100644
--- a/include/media/msp3400.h
+++ b/include/media/msp3400.h
@@ -54,13 +54,13 @@
=======
So to specify a complete routing scheme for the msp3400 you will have to
- specify in the 'input' field of the v4l2_routing struct:
+ specify in the 'input' arg of the s_routing function:
1) which tuner input to use
2) which SCART input to use
3) which DSP input to use for each DSP output
- And in the 'output' field of the v4l2_routing struct you specify:
+ And in the 'output' arg of the s_routing function you specify:
1) which SCART input to use for each SCART output
diff --git a/include/media/ov772x.h b/include/media/ov772x.h
index 57db48dd85b..30d9629198e 100644
--- a/include/media/ov772x.h
+++ b/include/media/ov772x.h
@@ -17,10 +17,45 @@
#define OV772X_FLAG_VFLIP 0x00000001 /* Vertical flip image */
#define OV772X_FLAG_HFLIP 0x00000002 /* Horizontal flip image */
+/*
+ * for Edge ctrl
+ *
+ * strength also control Auto or Manual Edge Control Mode
+ * see also OV772X_MANUAL_EDGE_CTRL
+ */
+struct ov772x_edge_ctrl {
+ unsigned char strength;
+ unsigned char threshold;
+ unsigned char upper;
+ unsigned char lower;
+};
+
+#define OV772X_MANUAL_EDGE_CTRL 0x80 /* un-used bit of strength */
+#define EDGE_STRENGTH_MASK 0x1F
+#define EDGE_THRESHOLD_MASK 0x0F
+#define EDGE_UPPER_MASK 0xFF
+#define EDGE_LOWER_MASK 0xFF
+
+#define OV772X_AUTO_EDGECTRL(u, l) \
+{ \
+ .upper = (u & EDGE_UPPER_MASK), \
+ .lower = (l & EDGE_LOWER_MASK), \
+}
+
+#define OV772X_MANUAL_EDGECTRL(s, t) \
+{ \
+ .strength = (s & EDGE_STRENGTH_MASK) | OV772X_MANUAL_EDGE_CTRL,\
+ .threshold = (t & EDGE_THRESHOLD_MASK), \
+}
+
+/*
+ * ov772x camera info
+ */
struct ov772x_camera_info {
unsigned long buswidth;
unsigned long flags;
struct soc_camera_link link;
+ struct ov772x_edge_ctrl edgectrl;
};
#endif /* __OV772X_H__ */
diff --git a/include/media/saa7146.h b/include/media/saa7146.h
index fff4235adae..7a9f76ecbbb 100644
--- a/include/media/saa7146.h
+++ b/include/media/saa7146.h
@@ -18,7 +18,7 @@
#include <linux/vmalloc.h> /* for vmalloc() */
#include <linux/mm.h> /* for vmalloc_to_page() */
-#define SAA7146_VERSION_CODE 0x000500 /* 0.5.0 */
+#define SAA7146_VERSION_CODE 0x000600 /* 0.6.0 */
#define saa7146_write(sxy,adr,dat) writel((dat),(sxy->mem+(adr)))
#define saa7146_read(sxy,adr) readl(sxy->mem+(adr))
diff --git a/include/media/tvaudio.h b/include/media/tvaudio.h
index 6915aafc875..1ac8184693f 100644
--- a/include/media/tvaudio.h
+++ b/include/media/tvaudio.h
@@ -21,10 +21,29 @@
#ifndef _TVAUDIO_H
#define _TVAUDIO_H
+#include <media/i2c-addr.h>
+
/* The tvaudio module accepts the following inputs: */
#define TVAUDIO_INPUT_TUNER 0
#define TVAUDIO_INPUT_RADIO 1
#define TVAUDIO_INPUT_EXTERN 2
#define TVAUDIO_INPUT_INTERN 3
+static inline const unsigned short *tvaudio_addrs(void)
+{
+ static const unsigned short addrs[] = {
+ I2C_ADDR_TDA8425 >> 1,
+ I2C_ADDR_TEA6300 >> 1,
+ I2C_ADDR_TEA6420 >> 1,
+ I2C_ADDR_TDA9840 >> 1,
+ I2C_ADDR_TDA985x_L >> 1,
+ I2C_ADDR_TDA985x_H >> 1,
+ I2C_ADDR_TDA9874 >> 1,
+ I2C_ADDR_PIC16C54 >> 1,
+ I2C_CLIENT_END
+ };
+
+ return addrs;
+}
+
#endif
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 3a6905615d6..c48c24e4d0f 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -125,7 +125,7 @@ int v4l2_chip_match_host(const struct v4l2_dbg_match *match);
/* ------------------------------------------------------------------------- */
-/* Helper function for I2C legacy drivers */
+/* I2C Helper functions */
struct i2c_driver;
struct i2c_adapter;
@@ -135,21 +135,24 @@ struct v4l2_device;
struct v4l2_subdev;
struct v4l2_subdev_ops;
-int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver,
- const char *name,
- int (*probe)(struct i2c_client *, const struct i2c_device_id *));
/* Load an i2c module and return an initialized v4l2_subdev struct.
Only call request_module if module_name != NULL.
The client_type argument is the name of the chip that's on the adapter. */
-struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter,
+struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
+ struct i2c_adapter *adapter,
const char *module_name, const char *client_type, u8 addr);
/* Probe and load an i2c module and return an initialized v4l2_subdev struct.
Only call request_module if module_name != NULL.
The client_type argument is the name of the chip that's on the adapter. */
-struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
+struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct v4l2_device *v4l2_dev,
+ struct i2c_adapter *adapter,
const char *module_name, const char *client_type,
const unsigned short *addrs);
+/* Like v4l2_i2c_new_probed_subdev, except probe for a single address. */
+struct v4l2_subdev *v4l2_i2c_new_probed_subdev_addr(struct v4l2_device *v4l2_dev,
+ struct i2c_adapter *adapter,
+ const char *module_name, const char *client_type, u8 addr);
/* Initialize an v4l2_subdev with data from an i2c_client struct */
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
const struct v4l2_subdev_ops *ops);
@@ -171,139 +174,23 @@ const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type);
/* ------------------------------------------------------------------------- */
-/* Internal ioctls */
-
-/* VIDIOC_INT_DECODE_VBI_LINE */
-struct v4l2_decode_vbi_line {
- u32 is_second_field; /* Set to 0 for the first (odd) field,
- set to 1 for the second (even) field. */
- u8 *p; /* Pointer to the sliced VBI data from the decoder.
- On exit points to the start of the payload. */
- u32 line; /* Line number of the sliced VBI data (1-23) */
- u32 type; /* VBI service type (V4L2_SLICED_*). 0 if no service found */
-};
+/* Note: these remaining ioctls/structs should be removed as well, but they are
+ still used in tuner-simple.c (TUNER_SET_CONFIG), cx18/ivtv (RESET) and
+ v4l2-int-device.h (v4l2_routing). To remove these ioctls some more cleanup
+ is needed in those modules. */
+/* s_config */
struct v4l2_priv_tun_config {
int tuner;
void *priv;
};
-
-/* audio ioctls */
-
-/* v4l device was opened in Radio mode, to be replaced by VIDIOC_INT_S_TUNER_MODE */
-#define AUDC_SET_RADIO _IO('d',88)
-
-/* tuner ioctls */
-
-/* Sets tuner type and its I2C addr */
-#define TUNER_SET_TYPE_ADDR _IOW('d', 90, int)
-
-/* Puts tuner on powersaving state, disabling it, except for i2c. To be replaced
- by VIDIOC_INT_S_STANDBY. */
-#define TUNER_SET_STANDBY _IOW('d', 91, int)
-
-/* Sets tda9887 specific stuff, like port1, port2 and qss */
#define TUNER_SET_CONFIG _IOW('d', 92, struct v4l2_priv_tun_config)
-/* Switch the tuner to a specific tuner mode. Replacement of AUDC_SET_RADIO */
-#define VIDIOC_INT_S_TUNER_MODE _IOW('d', 93, enum v4l2_tuner_type)
-
-/* Generic standby command. Passing -1 (all bits set to 1) will put the whole
- chip into standby mode, value 0 will make the chip fully active. Specific
- bits can be used by certain chips to enable/disable specific subsystems.
- Replacement of TUNER_SET_STANDBY. */
-#define VIDIOC_INT_S_STANDBY _IOW('d', 94, u32)
-
-/* 100, 101 used by VIDIOC_DBG_[SG]_REGISTER */
-
-/* Generic reset command. The argument selects which subsystems to reset.
- Passing 0 will always reset the whole chip. */
#define VIDIOC_INT_RESET _IOW ('d', 102, u32)
-/* Set the frequency (in Hz) of the audio clock output.
- Used to slave an audio processor to the video decoder, ensuring that audio
- and video remain synchronized.
- Usual values for the frequency are 48000, 44100 or 32000 Hz.
- If the frequency is not supported, then -EINVAL is returned. */
-#define VIDIOC_INT_AUDIO_CLOCK_FREQ _IOW ('d', 103, u32)
-
-/* Video decoders that support sliced VBI need to implement this ioctl.
- Field p of the v4l2_sliced_vbi_line struct is set to the start of the VBI
- data that was generated by the decoder. The driver then parses the sliced
- VBI data and sets the other fields in the struct accordingly. The pointer p
- is updated to point to the start of the payload which can be copied
- verbatim into the data field of the v4l2_sliced_vbi_data struct. If no
- valid VBI data was found, then the type field is set to 0 on return. */
-#define VIDIOC_INT_DECODE_VBI_LINE _IOWR('d', 104, struct v4l2_decode_vbi_line)
-
-/* Used to generate VBI signals on a video signal. v4l2_sliced_vbi_data is
- filled with the data packets that should be output. Note that if you set
- the line field to 0, then that VBI signal is disabled. If no
- valid VBI data was found, then the type field is set to 0 on return. */
-#define VIDIOC_INT_S_VBI_DATA _IOW ('d', 105, struct v4l2_sliced_vbi_data)
-
-/* Used to obtain the sliced VBI packet from a readback register. Not all
- video decoders support this. If no data is available because the readback
- register contains invalid or erroneous data -EIO is returned. Note that
- you must fill in the 'id' member and the 'field' member (to determine
- whether CC data from the first or second field should be obtained). */
-#define VIDIOC_INT_G_VBI_DATA _IOWR('d', 106, struct v4l2_sliced_vbi_data)
-
-/* Sets I2S speed in bps. This is used to provide a standard way to select I2S
- clock used by driving digital audio streams at some board designs.
- Usual values for the frequency are 1024000 and 2048000.
- If the frequency is not supported, then -EINVAL is returned. */
-#define VIDIOC_INT_I2S_CLOCK_FREQ _IOW ('d', 108, u32)
-
-/* Routing definition, device dependent. It specifies which inputs (if any)
- should be routed to which outputs (if any). */
struct v4l2_routing {
u32 input;
u32 output;
};
-/* These internal commands should be used to define the inputs and outputs
- of an audio/video chip. They will replace the v4l2 API commands
- VIDIOC_S/G_INPUT, VIDIOC_S/G_OUTPUT, VIDIOC_S/G_AUDIO and VIDIOC_S/G_AUDOUT
- that are meant to be used by the user.
- The internal commands should be used to switch inputs/outputs
- because only the driver knows how to map a 'Television' input to the precise
- input/output routing of an A/D converter, or a DSP, or a video digitizer.
- These four commands should only be sent directly to an i2c device, they
- should not be broadcast as the routing is very device specific. */
-#define VIDIOC_INT_S_AUDIO_ROUTING _IOW ('d', 109, struct v4l2_routing)
-#define VIDIOC_INT_G_AUDIO_ROUTING _IOR ('d', 110, struct v4l2_routing)
-#define VIDIOC_INT_S_VIDEO_ROUTING _IOW ('d', 111, struct v4l2_routing)
-#define VIDIOC_INT_G_VIDEO_ROUTING _IOR ('d', 112, struct v4l2_routing)
-
-struct v4l2_crystal_freq {
- u32 freq; /* frequency in Hz of the crystal */
- u32 flags; /* device specific flags */
-};
-
-/* Sets the frequency of the crystal used to generate the clocks.
- An extra flags field allows device specific configuration regarding
- clock frequency dividers, etc. If not used, then set flags to 0.
- If the frequency is not supported, then -EINVAL is returned. */
-#define VIDIOC_INT_S_CRYSTAL_FREQ _IOW('d', 113, struct v4l2_crystal_freq)
-
-/* Initialize the sensor registors to some sort of reasonable
- default values. */
-#define VIDIOC_INT_INIT _IOW('d', 114, u32)
-
-/* Set v4l2_std_id for video OUTPUT devices. This is ignored by
- video input devices. */
-#define VIDIOC_INT_S_STD_OUTPUT _IOW('d', 115, v4l2_std_id)
-
-/* Get v4l2_std_id for video OUTPUT devices. This is ignored by
- video input devices. */
-#define VIDIOC_INT_G_STD_OUTPUT _IOW('d', 116, v4l2_std_id)
-
-/* Set GPIO pins. Very simple right now, might need to be extended with
- a v4l2_gpio struct if a direction is also needed. */
-#define VIDIOC_INT_S_GPIO _IOW('d', 117, u32)
-
-/* Get input status. Same as the status field in the v4l2_input struct. */
-#define VIDIOC_INT_G_INPUT_STATUS _IOR('d', 118, u32)
-
#endif /* V4L2_COMMON_H_ */
diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h
deleted file mode 100644
index e65dd9d84e8..00000000000
--- a/include/media/v4l2-i2c-drv-legacy.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * v4l2-i2c-drv-legacy.h - contains I2C handling code that's identical
- * for all V4L2 I2C drivers. Use this header if the
- * I2C driver is used by both legacy drivers and
- * drivers converted to the bus-based I2C API.
- *
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
- *
- * 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.
- */
-
-/* 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;
- int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
- int (*probe)(struct i2c_client *client, const struct i2c_device_id *id);
- int (*remove)(struct i2c_client *client);
- int (*suspend)(struct i2c_client *client, pm_message_t state);
- int (*resume)(struct i2c_client *client);
- int (*legacy_probe)(struct i2c_adapter *adapter);
- int legacy_class;
- const struct i2c_device_id *id_table;
-};
-
-static struct v4l2_i2c_driver_data v4l2_i2c_data;
-static const struct i2c_client_address_data addr_data;
-static struct i2c_driver v4l2_i2c_driver_legacy;
-static char v4l2_i2c_drv_name_legacy[32];
-
-static int v4l2_i2c_drv_attach_legacy(struct i2c_adapter *adapter, int address, int kind)
-{
- return v4l2_i2c_attach(adapter, address, &v4l2_i2c_driver_legacy,
- v4l2_i2c_drv_name_legacy, v4l2_i2c_data.probe);
-}
-
-static int v4l2_i2c_drv_probe_legacy(struct i2c_adapter *adapter)
-{
- if (v4l2_i2c_data.legacy_probe) {
- if (v4l2_i2c_data.legacy_probe(adapter))
- return i2c_probe(adapter, &addr_data, v4l2_i2c_drv_attach_legacy);
- return 0;
- }
- if (adapter->class & v4l2_i2c_data.legacy_class)
- return i2c_probe(adapter, &addr_data, v4l2_i2c_drv_attach_legacy);
- return 0;
-}
-
-static int v4l2_i2c_drv_detach_legacy(struct i2c_client *client)
-{
- int err;
-
- if (v4l2_i2c_data.remove)
- v4l2_i2c_data.remove(client);
-
- err = i2c_detach_client(client);
- if (err)
- return err;
- kfree(client);
- return 0;
-}
-
-static int v4l2_i2c_drv_suspend_helper(struct i2c_client *client, pm_message_t state)
-{
- return v4l2_i2c_data.suspend ? v4l2_i2c_data.suspend(client, state) : 0;
-}
-
-static int v4l2_i2c_drv_resume_helper(struct i2c_client *client)
-{
- return v4l2_i2c_data.resume ? v4l2_i2c_data.resume(client) : 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-/* i2c implementation */
-static struct i2c_driver v4l2_i2c_driver_legacy = {
- .driver = {
- .owner = THIS_MODULE,
- },
- .attach_adapter = v4l2_i2c_drv_probe_legacy,
- .detach_client = v4l2_i2c_drv_detach_legacy,
- .suspend = v4l2_i2c_drv_suspend_helper,
- .resume = v4l2_i2c_drv_resume_helper,
-};
-
-/* ----------------------------------------------------------------------- */
-
-/* i2c implementation */
-static struct i2c_driver v4l2_i2c_driver = {
- .suspend = v4l2_i2c_drv_suspend_helper,
- .resume = v4l2_i2c_drv_resume_helper,
-};
-
-static int __init v4l2_i2c_drv_init(void)
-{
- int err;
-
- strlcpy(v4l2_i2c_drv_name_legacy, v4l2_i2c_data.name, sizeof(v4l2_i2c_drv_name_legacy));
- strlcat(v4l2_i2c_drv_name_legacy, "'", sizeof(v4l2_i2c_drv_name_legacy));
-
- if (v4l2_i2c_data.legacy_class == 0)
- v4l2_i2c_data.legacy_class = I2C_CLASS_TV_ANALOG;
-
- v4l2_i2c_driver_legacy.driver.name = v4l2_i2c_drv_name_legacy;
- v4l2_i2c_driver_legacy.id = v4l2_i2c_data.driverid;
- v4l2_i2c_driver_legacy.command = v4l2_i2c_data.command;
- err = i2c_add_driver(&v4l2_i2c_driver_legacy);
-
- if (err)
- return err;
- v4l2_i2c_driver.driver.name = v4l2_i2c_data.name;
- v4l2_i2c_driver.id = v4l2_i2c_data.driverid;
- v4l2_i2c_driver.command = v4l2_i2c_data.command;
- v4l2_i2c_driver.probe = v4l2_i2c_data.probe;
- v4l2_i2c_driver.remove = v4l2_i2c_data.remove;
- v4l2_i2c_driver.id_table = v4l2_i2c_data.id_table;
- err = i2c_add_driver(&v4l2_i2c_driver);
- if (err)
- i2c_del_driver(&v4l2_i2c_driver_legacy);
- return err;
-}
-
-static void __exit v4l2_i2c_drv_cleanup(void)
-{
- i2c_del_driver(&v4l2_i2c_driver_legacy);
- i2c_del_driver(&v4l2_i2c_driver);
-}
-
-module_init(v4l2_i2c_drv_init);
-module_exit(v4l2_i2c_drv_cleanup);
diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h
index efdc8bf27f8..10a2882c3cb 100644
--- a/include/media/v4l2-i2c-drv.h
+++ b/include/media/v4l2-i2c-drv.h
@@ -39,14 +39,11 @@
struct v4l2_i2c_driver_data {
const char * const name;
- int driverid;
int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
int (*probe)(struct i2c_client *client, const struct i2c_device_id *id);
int (*remove)(struct i2c_client *client);
int (*suspend)(struct i2c_client *client, pm_message_t state);
int (*resume)(struct i2c_client *client);
- int (*legacy_probe)(struct i2c_adapter *adapter);
- int legacy_class;
const struct i2c_device_id *id_table;
};
@@ -54,12 +51,11 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data;
static struct i2c_driver v4l2_i2c_driver;
-/* Bus-based I2C implementation for kernels >= 2.6.22 */
+/* Bus-based I2C implementation for kernels >= 2.6.26 */
static int __init v4l2_i2c_drv_init(void)
{
v4l2_i2c_driver.driver.name = v4l2_i2c_data.name;
- v4l2_i2c_driver.id = v4l2_i2c_data.driverid;
v4l2_i2c_driver.command = v4l2_i2c_data.command;
v4l2_i2c_driver.probe = v4l2_i2c_data.probe;
v4l2_i2c_driver.remove = v4l2_i2c_data.remove;
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 1d181b4ccb0..17856081c80 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -27,6 +27,16 @@ struct v4l2_device;
struct v4l2_subdev;
struct tuner_setup;
+/* decode_vbi_line */
+struct v4l2_decode_vbi_line {
+ u32 is_second_field; /* Set to 0 for the first (odd) field,
+ set to 1 for the second (even) field. */
+ u8 *p; /* Pointer to the sliced VBI data from the decoder.
+ On exit points to the start of the payload. */
+ u32 line; /* Line number of the sliced VBI data (1-23) */
+ u32 type; /* VBI service type (V4L2_SLICED_*). 0 if no service found */
+};
+
/* Sub-devices are devices that are connected somehow to the main bridge
device. These devices are usually audio/video muxers/encoders/decoders or
sensors and webcam controllers.
@@ -68,11 +78,26 @@ struct tuner_setup;
the use-case it might be better to use subdev-specific ops (currently
not yet implemented) since ops provide proper type-checking.
*/
+
+/* init: initialize the sensor registors to some sort of reasonable default
+ values. Do not use for new drivers and should be removed in existing
+ drivers.
+
+ load_fw: load firmware.
+
+ reset: generic reset command. The argument selects which subsystems to
+ reset. Passing 0 will always reset the whole chip. Do not use for new
+ drivers without discussing this first on the linux-media mailinglist.
+ There should be no reason normally to reset a device.
+
+ s_gpio: set GPIO pins. Very simple right now, might need to be extended with
+ a direction argument if needed.
+ */
struct v4l2_subdev_core_ops {
int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
int (*log_status)(struct v4l2_subdev *sd);
int (*init)(struct v4l2_subdev *sd, u32 val);
- int (*s_standby)(struct v4l2_subdev *sd, u32 standby);
+ int (*load_fw)(struct v4l2_subdev *sd);
int (*reset)(struct v4l2_subdev *sd, u32 val);
int (*s_gpio)(struct v4l2_subdev *sd, u32 val);
int (*queryctrl)(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc);
@@ -82,6 +107,7 @@ struct v4l2_subdev_core_ops {
int (*s_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);
int (*try_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);
int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm);
+ int (*s_std)(struct v4l2_subdev *sd, v4l2_std_id norm);
long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
#ifdef CONFIG_VIDEO_ADV_DEBUG
int (*g_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg);
@@ -89,6 +115,16 @@ struct v4l2_subdev_core_ops {
#endif
};
+/* s_mode: switch the tuner to a specific tuner mode. Replacement of s_radio.
+
+ s_radio: v4l device was opened in Radio mode, to be replaced by s_mode.
+
+ s_type_addr: sets tuner type and its I2C addr.
+
+ s_config: sets tda9887 specific stuff, like port1, port2 and qss
+
+ s_standby: puts tuner on powersaving state, disabling it, except for i2c.
+ */
struct v4l2_subdev_tuner_ops {
int (*s_mode)(struct v4l2_subdev *sd, enum v4l2_tuner_type);
int (*s_radio)(struct v4l2_subdev *sd);
@@ -96,20 +132,77 @@ struct v4l2_subdev_tuner_ops {
int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq);
int (*g_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt);
int (*s_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt);
- int (*s_std)(struct v4l2_subdev *sd, v4l2_std_id norm);
int (*s_type_addr)(struct v4l2_subdev *sd, struct tuner_setup *type);
int (*s_config)(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *config);
+ int (*s_standby)(struct v4l2_subdev *sd);
};
+/* s_clock_freq: set the frequency (in Hz) of the audio clock output.
+ Used to slave an audio processor to the video decoder, ensuring that
+ audio and video remain synchronized. Usual values for the frequency
+ are 48000, 44100 or 32000 Hz. If the frequency is not supported, then
+ -EINVAL is returned.
+
+ s_i2s_clock_freq: sets I2S speed in bps. This is used to provide a standard
+ way to select I2S clock used by driving digital audio streams at some
+ board designs. Usual values for the frequency are 1024000 and 2048000.
+ If the frequency is not supported, then -EINVAL is returned.
+
+ s_routing: used to define the input and/or output pins of an audio chip,
+ and any additional configuration data.
+ Never attempt to use user-level input IDs (e.g. Composite, S-Video,
+ Tuner) at this level. An i2c device shouldn't know about whether an
+ input pin is connected to a Composite connector, become on another
+ board or platform it might be connected to something else entirely.
+ The calling driver is responsible for mapping a user-level input to
+ the right pins on the i2c device.
+ */
struct v4l2_subdev_audio_ops {
int (*s_clock_freq)(struct v4l2_subdev *sd, u32 freq);
int (*s_i2s_clock_freq)(struct v4l2_subdev *sd, u32 freq);
- int (*s_routing)(struct v4l2_subdev *sd, const struct v4l2_routing *route);
+ int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config);
};
+/*
+ decode_vbi_line: video decoders that support sliced VBI need to implement
+ this ioctl. Field p of the v4l2_sliced_vbi_line struct is set to the
+ start of the VBI data that was generated by the decoder. The driver
+ then parses the sliced VBI data and sets the other fields in the
+ struct accordingly. The pointer p is updated to point to the start of
+ the payload which can be copied verbatim into the data field of the
+ v4l2_sliced_vbi_data struct. If no valid VBI data was found, then the
+ type field is set to 0 on return.
+
+ s_vbi_data: used to generate VBI signals on a video signal.
+ v4l2_sliced_vbi_data is filled with the data packets that should be
+ output. Note that if you set the line field to 0, then that VBI signal
+ is disabled. If no valid VBI data was found, then the type field is
+ set to 0 on return.
+
+ g_vbi_data: used to obtain the sliced VBI packet from a readback register.
+ Not all video decoders support this. If no data is available because
+ the readback register contains invalid or erroneous data -EIO is
+ returned. Note that you must fill in the 'id' member and the 'field'
+ member (to determine whether CC data from the first or second field
+ should be obtained).
+
+ s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by
+ video input devices.
+
+ s_crystal_freq: sets the frequency of the crystal used to generate the
+ clocks in Hz. An extra flags field allows device specific configuration
+ regarding clock frequency dividers, etc. If not used, then set flags
+ to 0. If the frequency is not supported, then -EINVAL is returned.
+
+ g_input_status: get input status. Same as the status field in the v4l2_input
+ struct.
+
+ s_routing: see s_routing in audio_ops, except this version is for video
+ devices.
+ */
struct v4l2_subdev_video_ops {
- int (*s_routing)(struct v4l2_subdev *sd, const struct v4l2_routing *route);
- int (*s_crystal_freq)(struct v4l2_subdev *sd, struct v4l2_crystal_freq *freq);
+ int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config);
+ int (*s_crystal_freq)(struct v4l2_subdev *sd, u32 freq, u32 flags);
int (*decode_vbi_line)(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi_line);
int (*s_vbi_data)(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *vbi_data);
int (*g_vbi_data)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *vbi_data);
@@ -163,18 +256,6 @@ static inline void *v4l2_get_subdevdata(const struct v4l2_subdev *sd)
return sd->priv;
}
-/* Convert an ioctl-type command to the proper v4l2_subdev_ops function call.
- This is used by subdev modules that can be called by both old-style ioctl
- commands and through the v4l2_subdev_ops.
-
- The ioctl API of the subdev driver can call this function to call the
- right ops based on the ioctl cmd and arg.
-
- Once all subdev drivers have been converted and all drivers no longer
- use the ioctl interface, then this function can be removed.
- */
-int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg);
-
static inline void v4l2_subdev_init(struct v4l2_subdev *sd,
const struct v4l2_subdev_ops *ops)
{
diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h
index ab17a159ac6..a9652806d0d 100644
--- a/include/net/netfilter/nf_conntrack_expect.h
+++ b/include/net/netfilter/nf_conntrack_expect.h
@@ -99,9 +99,12 @@ void nf_ct_expect_init(struct nf_conntrack_expect *, unsigned int, u_int8_t,
const union nf_inet_addr *,
u_int8_t, const __be16 *, const __be16 *);
void nf_ct_expect_put(struct nf_conntrack_expect *exp);
-int nf_ct_expect_related(struct nf_conntrack_expect *expect);
int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
u32 pid, int report);
+static inline int nf_ct_expect_related(struct nf_conntrack_expect *expect)
+{
+ return nf_ct_expect_related_report(expect, 0, 0);
+}
#endif /*_NF_CONNTRACK_EXPECT_H*/
diff --git a/include/scsi/fc/fc_fip.h b/include/scsi/fc/fc_fip.h
new file mode 100644
index 00000000000..0627a9ae634
--- /dev/null
+++ b/include/scsi/fc/fc_fip.h
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2008 Cisco Systems, Inc. All rights reserved.
+ *
+ * This program is free software; you may 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef _FC_FIP_H_
+#define _FC_FIP_H_
+
+/*
+ * This version is based on:
+ * http://www.t11.org/ftp/t11/pub/fc/bb-5/08-543v1.pdf
+ */
+
+/*
+ * The FIP ethertype eventually goes in net/if_ether.h.
+ */
+#ifndef ETH_P_FIP
+#define ETH_P_FIP 0x8914 /* FIP Ethertype */
+#endif
+
+#define FIP_DEF_PRI 128 /* default selection priority */
+#define FIP_DEF_FC_MAP 0x0efc00 /* default FCoE MAP (MAC OUI) value */
+#define FIP_DEF_FKA 8000 /* default FCF keep-alive/advert period (mS) */
+#define FIP_VN_KA_PERIOD 90000 /* required VN_port keep-alive period (mS) */
+#define FIP_FCF_FUZZ 100 /* random time added by FCF (mS) */
+
+/*
+ * Multicast MAC addresses. T11-adopted.
+ */
+#define FIP_ALL_FCOE_MACS ((u8[6]) { 1, 0x10, 0x18, 1, 0, 0 })
+#define FIP_ALL_ENODE_MACS ((u8[6]) { 1, 0x10, 0x18, 1, 0, 1 })
+#define FIP_ALL_FCF_MACS ((u8[6]) { 1, 0x10, 0x18, 1, 0, 2 })
+
+#define FIP_VER 1 /* version for fip_header */
+
+struct fip_header {
+ __u8 fip_ver; /* upper 4 bits are the version */
+ __u8 fip_resv1; /* reserved */
+ __be16 fip_op; /* operation code */
+ __u8 fip_resv2; /* reserved */
+ __u8 fip_subcode; /* lower 4 bits are sub-code */
+ __be16 fip_dl_len; /* length of descriptors in words */
+ __be16 fip_flags; /* header flags */
+} __attribute__((packed));
+
+#define FIP_VER_SHIFT 4
+#define FIP_VER_ENCAPS(v) ((v) << FIP_VER_SHIFT)
+#define FIP_VER_DECAPS(v) ((v) >> FIP_VER_SHIFT)
+#define FIP_BPW 4 /* bytes per word for lengths */
+
+/*
+ * fip_op.
+ */
+enum fip_opcode {
+ FIP_OP_DISC = 1, /* discovery, advertisement, etc. */
+ FIP_OP_LS = 2, /* Link Service request or reply */
+ FIP_OP_CTRL = 3, /* Keep Alive / Link Reset */
+ FIP_OP_VLAN = 4, /* VLAN discovery */
+ FIP_OP_VENDOR_MIN = 0xfff8, /* min vendor-specific opcode */
+ FIP_OP_VENDOR_MAX = 0xfffe, /* max vendor-specific opcode */
+};
+
+/*
+ * Subcodes for FIP_OP_DISC.
+ */
+enum fip_disc_subcode {
+ FIP_SC_SOL = 1, /* solicitation */
+ FIP_SC_ADV = 2, /* advertisement */
+};
+
+/*
+ * Subcodes for FIP_OP_LS.
+ */
+enum fip_trans_subcode {
+ FIP_SC_REQ = 1, /* request */
+ FIP_SC_REP = 2, /* reply */
+};
+
+/*
+ * Subcodes for FIP_OP_RESET.
+ */
+enum fip_reset_subcode {
+ FIP_SC_KEEP_ALIVE = 1, /* keep-alive from VN_Port */
+ FIP_SC_CLR_VLINK = 2, /* clear virtual link from VF_Port */
+};
+
+/*
+ * Subcodes for FIP_OP_VLAN.
+ */
+enum fip_vlan_subcode {
+ FIP_SC_VL_REQ = 1, /* request */
+ FIP_SC_VL_REP = 2, /* reply */
+};
+
+/*
+ * flags in header fip_flags.
+ */
+enum fip_flag {
+ FIP_FL_FPMA = 0x8000, /* supports FPMA fabric-provided MACs */
+ FIP_FL_SPMA = 0x4000, /* supports SPMA server-provided MACs */
+ FIP_FL_AVAIL = 0x0004, /* available for FLOGI/ELP */
+ FIP_FL_SOL = 0x0002, /* this is a solicited message */
+ FIP_FL_FPORT = 0x0001, /* sent from an F port */
+};
+
+/*
+ * Common descriptor header format.
+ */
+struct fip_desc {
+ __u8 fip_dtype; /* type - see below */
+ __u8 fip_dlen; /* length - in 32-bit words */
+};
+
+enum fip_desc_type {
+ FIP_DT_PRI = 1, /* priority for forwarder selection */
+ FIP_DT_MAC = 2, /* MAC address */
+ FIP_DT_MAP_OUI = 3, /* FC-MAP OUI */
+ FIP_DT_NAME = 4, /* switch name or node name */
+ FIP_DT_FAB = 5, /* fabric descriptor */
+ FIP_DT_FCOE_SIZE = 6, /* max FCoE frame size */
+ FIP_DT_FLOGI = 7, /* FLOGI request or response */
+ FIP_DT_FDISC = 8, /* FDISC request or response */
+ FIP_DT_LOGO = 9, /* LOGO request or response */
+ FIP_DT_ELP = 10, /* ELP request or response */
+ FIP_DT_VN_ID = 11, /* VN_Node Identifier */
+ FIP_DT_FKA = 12, /* advertisement keep-alive period */
+ FIP_DT_VENDOR = 13, /* vendor ID */
+ FIP_DT_VLAN = 14, /* vlan number */
+ FIP_DT_LIMIT, /* max defined desc_type + 1 */
+ FIP_DT_VENDOR_BASE = 128, /* first vendor-specific desc_type */
+};
+
+/*
+ * FIP_DT_PRI - priority descriptor.
+ */
+struct fip_pri_desc {
+ struct fip_desc fd_desc;
+ __u8 fd_resvd;
+ __u8 fd_pri; /* FCF priority: higher is better */
+} __attribute__((packed));
+
+/*
+ * FIP_DT_MAC - MAC address descriptor.
+ */
+struct fip_mac_desc {
+ struct fip_desc fd_desc;
+ __u8 fd_mac[ETH_ALEN];
+} __attribute__((packed));
+
+/*
+ * FIP_DT_MAP - descriptor.
+ */
+struct fip_map_desc {
+ struct fip_desc fd_desc;
+ __u8 fd_resvd[3];
+ __u8 fd_map[3];
+} __attribute__((packed));
+
+/*
+ * FIP_DT_NAME descriptor.
+ */
+struct fip_wwn_desc {
+ struct fip_desc fd_desc;
+ __u8 fd_resvd[2];
+ __be64 fd_wwn; /* 64-bit WWN, unaligned */
+} __attribute__((packed));
+
+/*
+ * FIP_DT_FAB descriptor.
+ */
+struct fip_fab_desc {
+ struct fip_desc fd_desc;
+ __be16 fd_vfid; /* virtual fabric ID */
+ __u8 fd_resvd;
+ __u8 fd_map[3]; /* FC-MAP value */
+ __be64 fd_wwn; /* fabric name, unaligned */
+} __attribute__((packed));
+
+/*
+ * FIP_DT_FCOE_SIZE descriptor.
+ */
+struct fip_size_desc {
+ struct fip_desc fd_desc;
+ __be16 fd_size;
+} __attribute__((packed));
+
+/*
+ * Descriptor that encapsulates an ELS or ILS frame.
+ * The encapsulated frame immediately follows this header, without
+ * SOF, EOF, or CRC.
+ */
+struct fip_encaps {
+ struct fip_desc fd_desc;
+ __u8 fd_resvd[2];
+} __attribute__((packed));
+
+/*
+ * FIP_DT_VN_ID - VN_Node Identifier descriptor.
+ */
+struct fip_vn_desc {
+ struct fip_desc fd_desc;
+ __u8 fd_mac[ETH_ALEN];
+ __u8 fd_resvd;
+ __u8 fd_fc_id[3];
+ __be64 fd_wwpn; /* port name, unaligned */
+} __attribute__((packed));
+
+/*
+ * FIP_DT_FKA - Advertisement keep-alive period.
+ */
+struct fip_fka_desc {
+ struct fip_desc fd_desc;
+ __u8 fd_resvd[2];
+ __be32 fd_fka_period; /* adv./keep-alive period in mS */
+} __attribute__((packed));
+
+/*
+ * FIP_DT_VENDOR descriptor.
+ */
+struct fip_vendor_desc {
+ struct fip_desc fd_desc;
+ __u8 fd_resvd[2];
+ __u8 fd_vendor_id[8];
+} __attribute__((packed));
+
+#endif /* _FC_FIP_H_ */
diff --git a/include/scsi/fc_transport_fcoe.h b/include/scsi/fc_transport_fcoe.h
deleted file mode 100644
index 8dca2af14ff..00000000000
--- a/include/scsi/fc_transport_fcoe.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef FC_TRANSPORT_FCOE_H
-#define FC_TRANSPORT_FCOE_H
-
-#include <linux/device.h>
-#include <linux/netdevice.h>
-#include <scsi/scsi_host.h>
-#include <scsi/libfc.h>
-
-/**
- * struct fcoe_transport - FCoE transport struct for generic transport
- * for Ethernet devices as well as pure HBAs
- *
- * @name: name for thsi transport
- * @bus: physical bus type (pci_bus_type)
- * @driver: physical bus driver for network device
- * @create: entry create function
- * @destroy: exit destroy function
- * @list: list of transports
- */
-struct fcoe_transport {
- char *name;
- unsigned short vendor;
- unsigned short device;
- struct bus_type *bus;
- struct device_driver *driver;
- int (*create)(struct net_device *device);
- int (*destroy)(struct net_device *device);
- bool (*match)(struct net_device *device);
- struct list_head list;
- struct list_head devlist;
- struct mutex devlock;
-};
-
-/**
- * MODULE_ALIAS_FCOE_PCI
- *
- * some care must be taken with this, vendor and device MUST be a hex value
- * preceded with 0x and with letters in lower case (0x12ab, not 0x12AB or 12AB)
- */
-#define MODULE_ALIAS_FCOE_PCI(vendor, device) \
- MODULE_ALIAS("fcoe-pci-" __stringify(vendor) "-" __stringify(device))
-
-/* exported funcs */
-int fcoe_transport_attach(struct net_device *netdev);
-int fcoe_transport_release(struct net_device *netdev);
-int fcoe_transport_register(struct fcoe_transport *t);
-int fcoe_transport_unregister(struct fcoe_transport *t);
-int fcoe_load_transport_driver(struct net_device *netdev);
-int __init fcoe_transport_init(void);
-int __exit fcoe_transport_exit(void);
-
-/* fcow_sw is the default transport */
-extern struct fcoe_transport fcoe_sw_transport;
-#endif /* FC_TRANSPORT_FCOE_H */
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index a70eafaad08..0303a6a098c 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -22,6 +22,7 @@
#include <linux/timer.h>
#include <linux/if.h>
+#include <linux/percpu.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_fc.h>
@@ -661,7 +662,8 @@ struct fc_lport {
unsigned long boot_time;
struct fc_host_statistics host_stats;
- struct fcoe_dev_stats *dev_stats[NR_CPUS];
+ struct fcoe_dev_stats *dev_stats;
+
u64 wwpn;
u64 wwnn;
u8 retry_count;
@@ -694,11 +696,6 @@ struct fc_lport {
/*
* FC_LPORT HELPER FUNCTIONS
*****************************/
-static inline void *lport_priv(const struct fc_lport *lp)
-{
- return (void *)(lp + 1);
-}
-
static inline int fc_lport_test_ready(struct fc_lport *lp)
{
return lp->state == LPORT_ST_READY;
@@ -722,6 +719,42 @@ static inline void fc_lport_state_enter(struct fc_lport *lp,
lp->state = state;
}
+static inline int fc_lport_init_stats(struct fc_lport *lp)
+{
+ /* allocate per cpu stats block */
+ lp->dev_stats = alloc_percpu(struct fcoe_dev_stats);
+ if (!lp->dev_stats)
+ return -ENOMEM;
+ return 0;
+}
+
+static inline void fc_lport_free_stats(struct fc_lport *lp)
+{
+ free_percpu(lp->dev_stats);
+}
+
+static inline struct fcoe_dev_stats *fc_lport_get_stats(struct fc_lport *lp)
+{
+ return per_cpu_ptr(lp->dev_stats, smp_processor_id());
+}
+
+static inline void *lport_priv(const struct fc_lport *lp)
+{
+ return (void *)(lp + 1);
+}
+
+/**
+ * libfc_host_alloc() - Allocate a Scsi_Host with room for the fc_lport
+ * @sht: ptr to the scsi host templ
+ * @priv_size: size of private data after fc_lport
+ *
+ * Returns: ptr to Scsi_Host
+ */
+static inline struct Scsi_Host *
+libfc_host_alloc(struct scsi_host_template *sht, int priv_size)
+{
+ return scsi_host_alloc(sht, sizeof(struct fc_lport) + priv_size);
+}
/*
* LOCAL PORT LAYER
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index c41f7d0c6ef..666cc131732 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -1,5 +1,6 @@
/*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved.
+ * Copyright (c) 2007-2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -20,134 +21,144 @@
#ifndef _LIBFCOE_H
#define _LIBFCOE_H
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/workqueue.h>
#include <scsi/fc/fc_fcoe.h>
#include <scsi/libfc.h>
/*
- * this percpu struct for fcoe
+ * FIP tunable parameters.
*/
-struct fcoe_percpu_s {
- int cpu;
- struct task_struct *thread;
- struct sk_buff_head fcoe_rx_list;
- struct page *crc_eof_page;
- int crc_eof_offset;
+#define FCOE_CTLR_START_DELAY 2000 /* mS after first adv. to choose FCF */
+#define FCOE_CTRL_SOL_TOV 2000 /* min. solicitation interval (mS) */
+#define FCOE_CTLR_FCF_LIMIT 20 /* max. number of FCF entries */
+
+/**
+ * enum fip_state - internal state of FCoE controller.
+ * @FIP_ST_DISABLED: controller has been disabled or not yet enabled.
+ * @FIP_ST_LINK_WAIT: the physical link is down or unusable.
+ * @FIP_ST_AUTO: determining whether to use FIP or non-FIP mode.
+ * @FIP_ST_NON_FIP: non-FIP mode selected.
+ * @FIP_ST_ENABLED: FIP mode selected.
+ */
+enum fip_state {
+ FIP_ST_DISABLED,
+ FIP_ST_LINK_WAIT,
+ FIP_ST_AUTO,
+ FIP_ST_NON_FIP,
+ FIP_ST_ENABLED,
};
-/*
- * the fcoe sw transport private data
+/**
+ * struct fcoe_ctlr - FCoE Controller and FIP state.
+ * @state: internal FIP state for network link and FIP or non-FIP mode.
+ * @lp: &fc_lport: libfc local port.
+ * @sel_fcf: currently selected FCF, or NULL.
+ * @fcfs: list of discovered FCFs.
+ * @fcf_count: number of discovered FCF entries.
+ * @sol_time: time when a multicast solicitation was last sent.
+ * @sel_time: time after which to select an FCF.
+ * @port_ka_time: time of next port keep-alive.
+ * @ctlr_ka_time: time of next controller keep-alive.
+ * @timer: timer struct used for all delayed events.
+ * @link_work: &work_struct for doing FCF selection.
+ * @recv_work: &work_struct for receiving FIP frames.
+ * @fip_recv_list: list of received FIP frames.
+ * @user_mfs: configured maximum FC frame size, including FC header.
+ * @flogi_oxid: exchange ID of most recent fabric login.
+ * @flogi_count: number of FLOGI attempts in AUTO mode.
+ * @link: current link status for libfc.
+ * @last_link: last link state reported to libfc.
+ * @map_dest: use the FC_MAP mode for destination MAC addresses.
+ * @dest_addr: MAC address of the selected FC forwarder.
+ * @ctl_src_addr: the native MAC address of our local port.
+ * @data_src_addr: the assigned MAC address for the local port after FLOGI.
+ * @send: LLD-supplied function to handle sending of FIP Ethernet frames.
+ * @update_mac: LLD-supplied function to handle changes to MAC addresses.
+ * @lock: lock protecting this structure.
+ *
+ * This structure is used by all FCoE drivers. It contains information
+ * needed by all FCoE low-level drivers (LLDs) as well as internal state
+ * for FIP, and fields shared with the LLDS.
*/
-struct fcoe_softc {
- struct list_head list;
+struct fcoe_ctlr {
+ enum fip_state state;
struct fc_lport *lp;
- struct net_device *real_dev;
- struct net_device *phys_dev; /* device with ethtool_ops */
- struct packet_type fcoe_packet_type;
- struct sk_buff_head fcoe_pending_queue;
- u8 fcoe_pending_queue_active;
-
+ struct fcoe_fcf *sel_fcf;
+ struct list_head fcfs;
+ u16 fcf_count;
+ unsigned long sol_time;
+ unsigned long sel_time;
+ unsigned long port_ka_time;
+ unsigned long ctlr_ka_time;
+ struct timer_list timer;
+ struct work_struct link_work;
+ struct work_struct recv_work;
+ struct sk_buff_head fip_recv_list;
+ u16 user_mfs;
+ u16 flogi_oxid;
+ u8 flogi_count;
+ u8 link;
+ u8 last_link;
+ u8 map_dest;
u8 dest_addr[ETH_ALEN];
u8 ctl_src_addr[ETH_ALEN];
u8 data_src_addr[ETH_ALEN];
- /*
- * fcoe protocol address learning related stuff
- */
- u16 flogi_oxid;
- u8 flogi_progress;
- u8 address_mode;
-};
-
-static inline struct net_device *fcoe_netdev(
- const struct fc_lport *lp)
-{
- return ((struct fcoe_softc *)lport_priv(lp))->real_dev;
-}
-
-static inline struct fcoe_hdr *skb_fcoe_header(const struct sk_buff *skb)
-{
- return (struct fcoe_hdr *)skb_network_header(skb);
-}
-
-static inline int skb_fcoe_offset(const struct sk_buff *skb)
-{
- return skb_network_offset(skb);
-}
-
-static inline struct fc_frame_header *skb_fc_header(const struct sk_buff *skb)
-{
- return (struct fc_frame_header *)skb_transport_header(skb);
-}
-
-static inline int skb_fc_offset(const struct sk_buff *skb)
-{
- return skb_transport_offset(skb);
-}
-static inline void skb_reset_fc_header(struct sk_buff *skb)
-{
- skb_reset_network_header(skb);
- skb_set_transport_header(skb, skb_network_offset(skb) +
- sizeof(struct fcoe_hdr));
-}
-
-static inline bool skb_fc_is_data(const struct sk_buff *skb)
-{
- return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_SOL_DATA;
-}
-
-static inline bool skb_fc_is_cmd(const struct sk_buff *skb)
-{
- return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD;
-}
+ void (*send)(struct fcoe_ctlr *, struct sk_buff *);
+ void (*update_mac)(struct fcoe_ctlr *, u8 *old, u8 *new);
+ spinlock_t lock;
+};
-static inline bool skb_fc_has_exthdr(const struct sk_buff *skb)
-{
- return (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_VFTH) ||
- (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_IFRH) ||
- (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_ENCH);
-}
+/*
+ * struct fcoe_fcf - Fibre-Channel Forwarder.
+ * @list: list linkage.
+ * @time: system time (jiffies) when an advertisement was last received.
+ * @switch_name: WWN of switch from advertisement.
+ * @fabric_name: WWN of fabric from advertisement.
+ * @fc_map: FC_MAP value from advertisement.
+ * @fcf_mac: Ethernet address of the FCF.
+ * @vfid: virtual fabric ID.
+ * @pri: seletion priority, smaller values are better.
+ * @flags: flags received from advertisement.
+ * @fka_period: keep-alive period, in jiffies.
+ *
+ * A Fibre-Channel Forwarder (FCF) is the entity on the Ethernet that
+ * passes FCoE frames on to an FC fabric. This structure represents
+ * one FCF from which advertisements have been received.
+ *
+ * When looking up an FCF, @switch_name, @fabric_name, @fc_map, @vfid, and
+ * @fcf_mac together form the lookup key.
+ */
+struct fcoe_fcf {
+ struct list_head list;
+ unsigned long time;
-static inline bool skb_fc_is_roff(const struct sk_buff *skb)
-{
- return skb_fc_header(skb)->fh_f_ctl[2] & FC_FC_REL_OFF;
-}
+ u64 switch_name;
+ u64 fabric_name;
+ u32 fc_map;
+ u16 vfid;
+ u8 fcf_mac[ETH_ALEN];
-static inline u16 skb_fc_oxid(const struct sk_buff *skb)
-{
- return be16_to_cpu(skb_fc_header(skb)->fh_ox_id);
-}
+ u8 pri;
+ u16 flags;
+ u32 fka_period;
+};
-static inline u16 skb_fc_rxid(const struct sk_buff *skb)
-{
- return be16_to_cpu(skb_fc_header(skb)->fh_rx_id);
-}
+/* FIP API functions */
+void fcoe_ctlr_init(struct fcoe_ctlr *);
+void fcoe_ctlr_destroy(struct fcoe_ctlr *);
+void fcoe_ctlr_link_up(struct fcoe_ctlr *);
+int fcoe_ctlr_link_down(struct fcoe_ctlr *);
+int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct sk_buff *);
+void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *);
+int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_frame *fp, u8 *sa);
/* libfcoe funcs */
-int fcoe_reset(struct Scsi_Host *shost);
-u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
- unsigned int scheme, unsigned int port);
-
-u32 fcoe_fc_crc(struct fc_frame *fp);
-int fcoe_xmit(struct fc_lport *, struct fc_frame *);
-int fcoe_rcv(struct sk_buff *, struct net_device *,
- struct packet_type *, struct net_device *);
-
-int fcoe_percpu_receive_thread(void *arg);
-void fcoe_clean_pending_queue(struct fc_lport *lp);
-void fcoe_percpu_clean(struct fc_lport *lp);
-void fcoe_watchdog(ulong vp);
-int fcoe_link_ok(struct fc_lport *lp);
-
-struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
-int fcoe_hostlist_add(const struct fc_lport *);
-int fcoe_hostlist_remove(const struct fc_lport *);
-
-struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *, int);
+u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int);
int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *);
-/* fcoe sw hba */
-int __init fcoe_sw_init(void);
-int __exit fcoe_sw_exit(void);
#endif /* _LIBFCOE_H */
diff --git a/include/scsi/scsi_scan.h b/include/scsi/scsi_scan.h
new file mode 100644
index 00000000000..78898889243
--- /dev/null
+++ b/include/scsi/scsi_scan.h
@@ -0,0 +1,11 @@
+#ifndef _SCSI_SCSI_SCAN_H
+#define _SCSI_SCSI_SCAN_H
+
+#ifdef CONFIG_SCSI
+/* drivers/scsi/scsi_scan.c */
+extern int scsi_complete_async_scans(void);
+#else
+static inline int scsi_complete_async_scans(void) { return 0; }
+#endif
+
+#endif /* _SCSI_SCSI_SCAN_H */
diff --git a/include/trace/block.h b/include/trace/block.h
index 25c6a1fd5b7..25b7068b819 100644
--- a/include/trace/block.h
+++ b/include/trace/block.h
@@ -5,72 +5,72 @@
#include <linux/tracepoint.h>
DECLARE_TRACE(block_rq_abort,
- TPPROTO(struct request_queue *q, struct request *rq),
- TPARGS(q, rq));
+ TP_PROTO(struct request_queue *q, struct request *rq),
+ TP_ARGS(q, rq));
DECLARE_TRACE(block_rq_insert,
- TPPROTO(struct request_queue *q, struct request *rq),
- TPARGS(q, rq));
+ TP_PROTO(struct request_queue *q, struct request *rq),
+ TP_ARGS(q, rq));
DECLARE_TRACE(block_rq_issue,
- TPPROTO(struct request_queue *q, struct request *rq),
- TPARGS(q, rq));
+ TP_PROTO(struct request_queue *q, struct request *rq),
+ TP_ARGS(q, rq));
DECLARE_TRACE(block_rq_requeue,
- TPPROTO(struct request_queue *q, struct request *rq),
- TPARGS(q, rq));
+ TP_PROTO(struct request_queue *q, struct request *rq),
+ TP_ARGS(q, rq));
DECLARE_TRACE(block_rq_complete,
- TPPROTO(struct request_queue *q, struct request *rq),
- TPARGS(q, rq));
+ TP_PROTO(struct request_queue *q, struct request *rq),
+ TP_ARGS(q, rq));
DECLARE_TRACE(block_bio_bounce,
- TPPROTO(struct request_queue *q, struct bio *bio),
- TPARGS(q, bio));
+ TP_PROTO(struct request_queue *q, struct bio *bio),
+ TP_ARGS(q, bio));
DECLARE_TRACE(block_bio_complete,
- TPPROTO(struct request_queue *q, struct bio *bio),
- TPARGS(q, bio));
+ TP_PROTO(struct request_queue *q, struct bio *bio),
+ TP_ARGS(q, bio));
DECLARE_TRACE(block_bio_backmerge,
- TPPROTO(struct request_queue *q, struct bio *bio),
- TPARGS(q, bio));
+ TP_PROTO(struct request_queue *q, struct bio *bio),
+ TP_ARGS(q, bio));
DECLARE_TRACE(block_bio_frontmerge,
- TPPROTO(struct request_queue *q, struct bio *bio),
- TPARGS(q, bio));
+ TP_PROTO(struct request_queue *q, struct bio *bio),
+ TP_ARGS(q, bio));
DECLARE_TRACE(block_bio_queue,
- TPPROTO(struct request_queue *q, struct bio *bio),
- TPARGS(q, bio));
+ TP_PROTO(struct request_queue *q, struct bio *bio),
+ TP_ARGS(q, bio));
DECLARE_TRACE(block_getrq,
- TPPROTO(struct request_queue *q, struct bio *bio, int rw),
- TPARGS(q, bio, rw));
+ TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
+ TP_ARGS(q, bio, rw));
DECLARE_TRACE(block_sleeprq,
- TPPROTO(struct request_queue *q, struct bio *bio, int rw),
- TPARGS(q, bio, rw));
+ TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
+ TP_ARGS(q, bio, rw));
DECLARE_TRACE(block_plug,
- TPPROTO(struct request_queue *q),
- TPARGS(q));
+ TP_PROTO(struct request_queue *q),
+ TP_ARGS(q));
DECLARE_TRACE(block_unplug_timer,
- TPPROTO(struct request_queue *q),
- TPARGS(q));
+ TP_PROTO(struct request_queue *q),
+ TP_ARGS(q));
DECLARE_TRACE(block_unplug_io,
- TPPROTO(struct request_queue *q),
- TPARGS(q));
+ TP_PROTO(struct request_queue *q),
+ TP_ARGS(q));
DECLARE_TRACE(block_split,
- TPPROTO(struct request_queue *q, struct bio *bio, unsigned int pdu),
- TPARGS(q, bio, pdu));
+ TP_PROTO(struct request_queue *q, struct bio *bio, unsigned int pdu),
+ TP_ARGS(q, bio, pdu));
DECLARE_TRACE(block_remap,
- TPPROTO(struct request_queue *q, struct bio *bio, dev_t dev,
- sector_t from, sector_t to),
- TPARGS(q, bio, dev, from, to));
+ TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev,
+ sector_t from, sector_t to),
+ TP_ARGS(q, bio, dev, from, to));
#endif
diff --git a/include/trace/irq.h b/include/trace/irq.h
new file mode 100644
index 00000000000..ff5d4495dc3
--- /dev/null
+++ b/include/trace/irq.h
@@ -0,0 +1,9 @@
+#ifndef _TRACE_IRQ_H
+#define _TRACE_IRQ_H
+
+#include <linux/interrupt.h>
+#include <linux/tracepoint.h>
+
+#include <trace/irq_event_types.h>
+
+#endif
diff --git a/include/trace/irq_event_types.h b/include/trace/irq_event_types.h
new file mode 100644
index 00000000000..85964ebd47e
--- /dev/null
+++ b/include/trace/irq_event_types.h
@@ -0,0 +1,55 @@
+
+/* use <trace/irq.h> instead */
+#ifndef TRACE_FORMAT
+# error Do not include this file directly.
+# error Unless you know what you are doing.
+#endif
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM irq
+
+/*
+ * Tracepoint for entry of interrupt handler:
+ */
+TRACE_FORMAT(irq_handler_entry,
+ TP_PROTO(int irq, struct irqaction *action),
+ TP_ARGS(irq, action),
+ TP_FMT("irq=%d handler=%s", irq, action->name)
+ );
+
+/*
+ * Tracepoint for return of an interrupt handler:
+ */
+TRACE_EVENT(irq_handler_exit,
+
+ TP_PROTO(int irq, struct irqaction *action, int ret),
+
+ TP_ARGS(irq, action, ret),
+
+ TP_STRUCT__entry(
+ __field( int, irq )
+ __field( int, ret )
+ ),
+
+ TP_fast_assign(
+ __entry->irq = irq;
+ __entry->ret = ret;
+ ),
+
+ TP_printk("irq=%d return=%s",
+ __entry->irq, __entry->ret ? "handled" : "unhandled")
+);
+
+TRACE_FORMAT(softirq_entry,
+ TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
+ TP_ARGS(h, vec),
+ TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec])
+ );
+
+TRACE_FORMAT(softirq_exit,
+ TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
+ TP_ARGS(h, vec),
+ TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec])
+ );
+
+#undef TRACE_SYSTEM
diff --git a/include/trace/kmemtrace.h b/include/trace/kmemtrace.h
new file mode 100644
index 00000000000..28ee69f9cd4
--- /dev/null
+++ b/include/trace/kmemtrace.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 Eduard - Gabriel Munteanu
+ *
+ * This file is released under GPL version 2.
+ */
+
+#ifndef _LINUX_KMEMTRACE_H
+#define _LINUX_KMEMTRACE_H
+
+#ifdef __KERNEL__
+
+#include <linux/tracepoint.h>
+#include <linux/types.h>
+
+#ifdef CONFIG_KMEMTRACE
+extern void kmemtrace_init(void);
+#else
+static inline void kmemtrace_init(void)
+{
+}
+#endif
+
+DECLARE_TRACE(kmalloc,
+ TP_PROTO(unsigned long call_site,
+ const void *ptr,
+ size_t bytes_req,
+ size_t bytes_alloc,
+ gfp_t gfp_flags),
+ TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags));
+DECLARE_TRACE(kmem_cache_alloc,
+ TP_PROTO(unsigned long call_site,
+ const void *ptr,
+ size_t bytes_req,
+ size_t bytes_alloc,
+ gfp_t gfp_flags),
+ TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags));
+DECLARE_TRACE(kmalloc_node,
+ TP_PROTO(unsigned long call_site,
+ const void *ptr,
+ size_t bytes_req,
+ size_t bytes_alloc,
+ gfp_t gfp_flags,
+ int node),
+ TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node));
+DECLARE_TRACE(kmem_cache_alloc_node,
+ TP_PROTO(unsigned long call_site,
+ const void *ptr,
+ size_t bytes_req,
+ size_t bytes_alloc,
+ gfp_t gfp_flags,
+ int node),
+ TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node));
+DECLARE_TRACE(kfree,
+ TP_PROTO(unsigned long call_site, const void *ptr),
+ TP_ARGS(call_site, ptr));
+DECLARE_TRACE(kmem_cache_free,
+ TP_PROTO(unsigned long call_site, const void *ptr),
+ TP_ARGS(call_site, ptr));
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_KMEMTRACE_H */
+
diff --git a/include/trace/lockdep.h b/include/trace/lockdep.h
new file mode 100644
index 00000000000..5ca67df87f2
--- /dev/null
+++ b/include/trace/lockdep.h
@@ -0,0 +1,9 @@
+#ifndef _TRACE_LOCKDEP_H
+#define _TRACE_LOCKDEP_H
+
+#include <linux/lockdep.h>
+#include <linux/tracepoint.h>
+
+#include <trace/lockdep_event_types.h>
+
+#endif
diff --git a/include/trace/lockdep_event_types.h b/include/trace/lockdep_event_types.h
new file mode 100644
index 00000000000..adccfcd2ec8
--- /dev/null
+++ b/include/trace/lockdep_event_types.h
@@ -0,0 +1,44 @@
+
+#ifndef TRACE_FORMAT
+# error Do not include this file directly.
+# error Unless you know what you are doing.
+#endif
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM lock
+
+#ifdef CONFIG_LOCKDEP
+
+TRACE_FORMAT(lock_acquire,
+ TP_PROTO(struct lockdep_map *lock, unsigned int subclass,
+ int trylock, int read, int check,
+ struct lockdep_map *next_lock, unsigned long ip),
+ TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip),
+ TP_FMT("%s%s%s", trylock ? "try " : "",
+ read ? "read " : "", lock->name)
+ );
+
+TRACE_FORMAT(lock_release,
+ TP_PROTO(struct lockdep_map *lock, int nested, unsigned long ip),
+ TP_ARGS(lock, nested, ip),
+ TP_FMT("%s", lock->name)
+ );
+
+#ifdef CONFIG_LOCK_STAT
+
+TRACE_FORMAT(lock_contended,
+ TP_PROTO(struct lockdep_map *lock, unsigned long ip),
+ TP_ARGS(lock, ip),
+ TP_FMT("%s", lock->name)
+ );
+
+TRACE_FORMAT(lock_acquired,
+ TP_PROTO(struct lockdep_map *lock, unsigned long ip),
+ TP_ARGS(lock, ip),
+ TP_FMT("%s", lock->name)
+ );
+
+#endif
+#endif
+
+#undef TRACE_SYSTEM
diff --git a/include/trace/power.h b/include/trace/power.h
new file mode 100644
index 00000000000..ef204666e98
--- /dev/null
+++ b/include/trace/power.h
@@ -0,0 +1,32 @@
+#ifndef _TRACE_POWER_H
+#define _TRACE_POWER_H
+
+#include <linux/ktime.h>
+#include <linux/tracepoint.h>
+
+enum {
+ POWER_NONE = 0,
+ POWER_CSTATE = 1,
+ POWER_PSTATE = 2,
+};
+
+struct power_trace {
+ ktime_t stamp;
+ ktime_t end;
+ int type;
+ int state;
+};
+
+DECLARE_TRACE(power_start,
+ TP_PROTO(struct power_trace *it, unsigned int type, unsigned int state),
+ TP_ARGS(it, type, state));
+
+DECLARE_TRACE(power_mark,
+ TP_PROTO(struct power_trace *it, unsigned int type, unsigned int state),
+ TP_ARGS(it, type, state));
+
+DECLARE_TRACE(power_end,
+ TP_PROTO(struct power_trace *it),
+ TP_ARGS(it));
+
+#endif /* _TRACE_POWER_H */
diff --git a/include/trace/sched.h b/include/trace/sched.h
index 0d81098ee9f..4e372a1a29b 100644
--- a/include/trace/sched.h
+++ b/include/trace/sched.h
@@ -4,53 +4,6 @@
#include <linux/sched.h>
#include <linux/tracepoint.h>
-DECLARE_TRACE(sched_kthread_stop,
- TPPROTO(struct task_struct *t),
- TPARGS(t));
-
-DECLARE_TRACE(sched_kthread_stop_ret,
- TPPROTO(int ret),
- TPARGS(ret));
-
-DECLARE_TRACE(sched_wait_task,
- TPPROTO(struct rq *rq, struct task_struct *p),
- TPARGS(rq, p));
-
-DECLARE_TRACE(sched_wakeup,
- TPPROTO(struct rq *rq, struct task_struct *p, int success),
- TPARGS(rq, p, success));
-
-DECLARE_TRACE(sched_wakeup_new,
- TPPROTO(struct rq *rq, struct task_struct *p, int success),
- TPARGS(rq, p, success));
-
-DECLARE_TRACE(sched_switch,
- TPPROTO(struct rq *rq, struct task_struct *prev,
- struct task_struct *next),
- TPARGS(rq, prev, next));
-
-DECLARE_TRACE(sched_migrate_task,
- TPPROTO(struct task_struct *p, int orig_cpu, int dest_cpu),
- TPARGS(p, orig_cpu, dest_cpu));
-
-DECLARE_TRACE(sched_process_free,
- TPPROTO(struct task_struct *p),
- TPARGS(p));
-
-DECLARE_TRACE(sched_process_exit,
- TPPROTO(struct task_struct *p),
- TPARGS(p));
-
-DECLARE_TRACE(sched_process_wait,
- TPPROTO(struct pid *pid),
- TPARGS(pid));
-
-DECLARE_TRACE(sched_process_fork,
- TPPROTO(struct task_struct *parent, struct task_struct *child),
- TPARGS(parent, child));
-
-DECLARE_TRACE(sched_signal_send,
- TPPROTO(int sig, struct task_struct *p),
- TPARGS(sig, p));
+#include <trace/sched_event_types.h>
#endif
diff --git a/include/trace/sched_event_types.h b/include/trace/sched_event_types.h
new file mode 100644
index 00000000000..63547dc1125
--- /dev/null
+++ b/include/trace/sched_event_types.h
@@ -0,0 +1,337 @@
+
+/* use <trace/sched.h> instead */
+#ifndef TRACE_EVENT
+# error Do not include this file directly.
+# error Unless you know what you are doing.
+#endif
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM sched
+
+/*
+ * Tracepoint for calling kthread_stop, performed to end a kthread:
+ */
+TRACE_EVENT(sched_kthread_stop,
+
+ TP_PROTO(struct task_struct *t),
+
+ TP_ARGS(t),
+
+ TP_STRUCT__entry(
+ __array( char, comm, TASK_COMM_LEN )
+ __field( pid_t, pid )
+ ),
+
+ TP_fast_assign(
+ memcpy(__entry->comm, t->comm, TASK_COMM_LEN);
+ __entry->pid = t->pid;
+ ),
+
+ TP_printk("task %s:%d", __entry->comm, __entry->pid)
+);
+
+/*
+ * Tracepoint for the return value of the kthread stopping:
+ */
+TRACE_EVENT(sched_kthread_stop_ret,
+
+ TP_PROTO(int ret),
+
+ TP_ARGS(ret),
+
+ TP_STRUCT__entry(
+ __field( int, ret )
+ ),
+
+ TP_fast_assign(
+ __entry->ret = ret;
+ ),
+
+ TP_printk("ret %d", __entry->ret)
+);
+
+/*
+ * Tracepoint for waiting on task to unschedule:
+ *
+ * (NOTE: the 'rq' argument is not used by generic trace events,
+ * but used by the latency tracer plugin. )
+ */
+TRACE_EVENT(sched_wait_task,
+
+ TP_PROTO(struct rq *rq, struct task_struct *p),
+
+ TP_ARGS(rq, p),
+
+ TP_STRUCT__entry(
+ __array( char, comm, TASK_COMM_LEN )
+ __field( pid_t, pid )
+ __field( int, prio )
+ ),
+
+ TP_fast_assign(
+ memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ __entry->pid = p->pid;
+ __entry->prio = p->prio;
+ ),
+
+ TP_printk("task %s:%d [%d]",
+ __entry->comm, __entry->pid, __entry->prio)
+);
+
+/*
+ * Tracepoint for waking up a task:
+ *
+ * (NOTE: the 'rq' argument is not used by generic trace events,
+ * but used by the latency tracer plugin. )
+ */
+TRACE_EVENT(sched_wakeup,
+
+ TP_PROTO(struct rq *rq, struct task_struct *p, int success),
+
+ TP_ARGS(rq, p, success),
+
+ TP_STRUCT__entry(
+ __array( char, comm, TASK_COMM_LEN )
+ __field( pid_t, pid )
+ __field( int, prio )
+ __field( int, success )
+ ),
+
+ TP_fast_assign(
+ memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ __entry->pid = p->pid;
+ __entry->prio = p->prio;
+ __entry->success = success;
+ ),
+
+ TP_printk("task %s:%d [%d] success=%d",
+ __entry->comm, __entry->pid, __entry->prio,
+ __entry->success)
+);
+
+/*
+ * Tracepoint for waking up a new task:
+ *
+ * (NOTE: the 'rq' argument is not used by generic trace events,
+ * but used by the latency tracer plugin. )
+ */
+TRACE_EVENT(sched_wakeup_new,
+
+ TP_PROTO(struct rq *rq, struct task_struct *p, int success),
+
+ TP_ARGS(rq, p, success),
+
+ TP_STRUCT__entry(
+ __array( char, comm, TASK_COMM_LEN )
+ __field( pid_t, pid )
+ __field( int, prio )
+ __field( int, success )
+ ),
+
+ TP_fast_assign(
+ memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ __entry->pid = p->pid;
+ __entry->prio = p->prio;
+ __entry->success = success;
+ ),
+
+ TP_printk("task %s:%d [%d] success=%d",
+ __entry->comm, __entry->pid, __entry->prio,
+ __entry->success)
+);
+
+/*
+ * Tracepoint for task switches, performed by the scheduler:
+ *
+ * (NOTE: the 'rq' argument is not used by generic trace events,
+ * but used by the latency tracer plugin. )
+ */
+TRACE_EVENT(sched_switch,
+
+ TP_PROTO(struct rq *rq, struct task_struct *prev,
+ struct task_struct *next),
+
+ TP_ARGS(rq, prev, next),
+
+ TP_STRUCT__entry(
+ __array( char, prev_comm, TASK_COMM_LEN )
+ __field( pid_t, prev_pid )
+ __field( int, prev_prio )
+ __array( char, next_comm, TASK_COMM_LEN )
+ __field( pid_t, next_pid )
+ __field( int, next_prio )
+ ),
+
+ TP_fast_assign(
+ memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
+ __entry->prev_pid = prev->pid;
+ __entry->prev_prio = prev->prio;
+ memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
+ __entry->next_pid = next->pid;
+ __entry->next_prio = next->prio;
+ ),
+
+ TP_printk("task %s:%d [%d] ==> %s:%d [%d]",
+ __entry->prev_comm, __entry->prev_pid, __entry->prev_prio,
+ __entry->next_comm, __entry->next_pid, __entry->next_prio)
+);
+
+/*
+ * Tracepoint for a task being migrated:
+ */
+TRACE_EVENT(sched_migrate_task,
+
+ TP_PROTO(struct task_struct *p, int orig_cpu, int dest_cpu),
+
+ TP_ARGS(p, orig_cpu, dest_cpu),
+
+ TP_STRUCT__entry(
+ __array( char, comm, TASK_COMM_LEN )
+ __field( pid_t, pid )
+ __field( int, prio )
+ __field( int, orig_cpu )
+ __field( int, dest_cpu )
+ ),
+
+ TP_fast_assign(
+ memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ __entry->pid = p->pid;
+ __entry->prio = p->prio;
+ __entry->orig_cpu = orig_cpu;
+ __entry->dest_cpu = dest_cpu;
+ ),
+
+ TP_printk("task %s:%d [%d] from: %d to: %d",
+ __entry->comm, __entry->pid, __entry->prio,
+ __entry->orig_cpu, __entry->dest_cpu)
+);
+
+/*
+ * Tracepoint for freeing a task:
+ */
+TRACE_EVENT(sched_process_free,
+
+ TP_PROTO(struct task_struct *p),
+
+ TP_ARGS(p),
+
+ TP_STRUCT__entry(
+ __array( char, comm, TASK_COMM_LEN )
+ __field( pid_t, pid )
+ __field( int, prio )
+ ),
+
+ TP_fast_assign(
+ memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ __entry->pid = p->pid;
+ __entry->prio = p->prio;
+ ),
+
+ TP_printk("task %s:%d [%d]",
+ __entry->comm, __entry->pid, __entry->prio)
+);
+
+/*
+ * Tracepoint for a task exiting:
+ */
+TRACE_EVENT(sched_process_exit,
+
+ TP_PROTO(struct task_struct *p),
+
+ TP_ARGS(p),
+
+ TP_STRUCT__entry(
+ __array( char, comm, TASK_COMM_LEN )
+ __field( pid_t, pid )
+ __field( int, prio )
+ ),
+
+ TP_fast_assign(
+ memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ __entry->pid = p->pid;
+ __entry->prio = p->prio;
+ ),
+
+ TP_printk("task %s:%d [%d]",
+ __entry->comm, __entry->pid, __entry->prio)
+);
+
+/*
+ * Tracepoint for a waiting task:
+ */
+TRACE_EVENT(sched_process_wait,
+
+ TP_PROTO(struct pid *pid),
+
+ TP_ARGS(pid),
+
+ TP_STRUCT__entry(
+ __array( char, comm, TASK_COMM_LEN )
+ __field( pid_t, pid )
+ __field( int, prio )
+ ),
+
+ TP_fast_assign(
+ memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+ __entry->pid = pid_nr(pid);
+ __entry->prio = current->prio;
+ ),
+
+ TP_printk("task %s:%d [%d]",
+ __entry->comm, __entry->pid, __entry->prio)
+);
+
+/*
+ * Tracepoint for do_fork:
+ */
+TRACE_EVENT(sched_process_fork,
+
+ TP_PROTO(struct task_struct *parent, struct task_struct *child),
+
+ TP_ARGS(parent, child),
+
+ TP_STRUCT__entry(
+ __array( char, parent_comm, TASK_COMM_LEN )
+ __field( pid_t, parent_pid )
+ __array( char, child_comm, TASK_COMM_LEN )
+ __field( pid_t, child_pid )
+ ),
+
+ TP_fast_assign(
+ memcpy(__entry->parent_comm, parent->comm, TASK_COMM_LEN);
+ __entry->parent_pid = parent->pid;
+ memcpy(__entry->child_comm, child->comm, TASK_COMM_LEN);
+ __entry->child_pid = child->pid;
+ ),
+
+ TP_printk("parent %s:%d child %s:%d",
+ __entry->parent_comm, __entry->parent_pid,
+ __entry->child_comm, __entry->child_pid)
+);
+
+/*
+ * Tracepoint for sending a signal:
+ */
+TRACE_EVENT(sched_signal_send,
+
+ TP_PROTO(int sig, struct task_struct *p),
+
+ TP_ARGS(sig, p),
+
+ TP_STRUCT__entry(
+ __field( int, sig )
+ __array( char, comm, TASK_COMM_LEN )
+ __field( pid_t, pid )
+ ),
+
+ TP_fast_assign(
+ memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ __entry->pid = p->pid;
+ __entry->sig = sig;
+ ),
+
+ TP_printk("sig: %d task %s:%d",
+ __entry->sig, __entry->comm, __entry->pid)
+);
+
+#undef TRACE_SYSTEM
diff --git a/include/trace/skb.h b/include/trace/skb.h
index a96610f92f6..b66206d9be7 100644
--- a/include/trace/skb.h
+++ b/include/trace/skb.h
@@ -5,7 +5,7 @@
#include <linux/tracepoint.h>
DECLARE_TRACE(kfree_skb,
- TPPROTO(struct sk_buff *skb, void *location),
- TPARGS(skb, location));
+ TP_PROTO(struct sk_buff *skb, void *location),
+ TP_ARGS(skb, location));
#endif
diff --git a/include/trace/syscall.h b/include/trace/syscall.h
new file mode 100644
index 00000000000..8cfe515cbc4
--- /dev/null
+++ b/include/trace/syscall.h
@@ -0,0 +1,35 @@
+#ifndef _TRACE_SYSCALL_H
+#define _TRACE_SYSCALL_H
+
+#include <asm/ptrace.h>
+
+/*
+ * A syscall entry in the ftrace syscalls array.
+ *
+ * @name: name of the syscall
+ * @nb_args: number of parameters it takes
+ * @types: list of types as strings
+ * @args: list of args as strings (args[i] matches types[i])
+ */
+struct syscall_metadata {
+ const char *name;
+ int nb_args;
+ const char **types;
+ const char **args;
+};
+
+#ifdef CONFIG_FTRACE_SYSCALLS
+extern void arch_init_ftrace_syscalls(void);
+extern struct syscall_metadata *syscall_nr_to_meta(int nr);
+extern void start_ftrace_syscalls(void);
+extern void stop_ftrace_syscalls(void);
+extern void ftrace_syscall_enter(struct pt_regs *regs);
+extern void ftrace_syscall_exit(struct pt_regs *regs);
+#else
+static inline void start_ftrace_syscalls(void) { }
+static inline void stop_ftrace_syscalls(void) { }
+static inline void ftrace_syscall_enter(struct pt_regs *regs) { }
+static inline void ftrace_syscall_exit(struct pt_regs *regs) { }
+#endif
+
+#endif /* _TRACE_SYSCALL_H */
diff --git a/include/trace/trace_event_types.h b/include/trace/trace_event_types.h
new file mode 100644
index 00000000000..df56f5694be
--- /dev/null
+++ b/include/trace/trace_event_types.h
@@ -0,0 +1,5 @@
+/* trace/<type>_event_types.h here */
+
+#include <trace/sched_event_types.h>
+#include <trace/irq_event_types.h>
+#include <trace/lockdep_event_types.h>
diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h
new file mode 100644
index 00000000000..fd13750ca4b
--- /dev/null
+++ b/include/trace/trace_events.h
@@ -0,0 +1,5 @@
+/* trace/<type>.h here */
+
+#include <trace/sched.h>
+#include <trace/irq.h>
+#include <trace/lockdep.h>
diff --git a/include/trace/workqueue.h b/include/trace/workqueue.h
new file mode 100644
index 00000000000..7626523deeb
--- /dev/null
+++ b/include/trace/workqueue.h
@@ -0,0 +1,25 @@
+#ifndef __TRACE_WORKQUEUE_H
+#define __TRACE_WORKQUEUE_H
+
+#include <linux/tracepoint.h>
+#include <linux/workqueue.h>
+#include <linux/sched.h>
+
+DECLARE_TRACE(workqueue_insertion,
+ TP_PROTO(struct task_struct *wq_thread, struct work_struct *work),
+ TP_ARGS(wq_thread, work));
+
+DECLARE_TRACE(workqueue_execution,
+ TP_PROTO(struct task_struct *wq_thread, struct work_struct *work),
+ TP_ARGS(wq_thread, work));
+
+/* Trace the creation of one workqueue thread on a cpu */
+DECLARE_TRACE(workqueue_creation,
+ TP_PROTO(struct task_struct *wq_thread, int cpu),
+ TP_ARGS(wq_thread, cpu));
+
+DECLARE_TRACE(workqueue_destruction,
+ TP_PROTO(struct task_struct *wq_thread),
+ TP_ARGS(wq_thread));
+
+#endif /* __TRACE_WORKQUEUE_H */
diff --git a/include/video/cyblafb.h b/include/video/cyblafb.h
deleted file mode 100644
index d3c1d4e2c8e..00000000000
--- a/include/video/cyblafb.h
+++ /dev/null
@@ -1,175 +0,0 @@
-
-#ifndef CYBLAFB_DEBUG
-#define CYBLAFB_DEBUG 0
-#endif
-
-#if CYBLAFB_DEBUG
-#define debug(f,a...) printk("%s:" f, __func__ , ## a);
-#else
-#define debug(f,a...)
-#endif
-
-#define output(f, a...) printk("cyblafb: " f, ## a)
-
-#define Kb (1024)
-#define Mb (Kb*Kb)
-
-/* PCI IDS of supported cards temporarily here */
-
-#define CYBERBLADEi1 0x8500
-
-/* these defines are for 'lcd' variable */
-#define LCD_STRETCH 0
-#define LCD_CENTER 1
-#define LCD_BIOS 2
-
-/* display types */
-#define DISPLAY_CRT 0
-#define DISPLAY_FP 1
-
-#define ROP_S 0xCC
-
-#define point(x,y) ((y)<<16|(x))
-
-//
-// Attribute Regs, ARxx, 3c0/3c1
-//
-#define AR00 0x00
-#define AR01 0x01
-#define AR02 0x02
-#define AR03 0x03
-#define AR04 0x04
-#define AR05 0x05
-#define AR06 0x06
-#define AR07 0x07
-#define AR08 0x08
-#define AR09 0x09
-#define AR0A 0x0A
-#define AR0B 0x0B
-#define AR0C 0x0C
-#define AR0D 0x0D
-#define AR0E 0x0E
-#define AR0F 0x0F
-#define AR10 0x10
-#define AR12 0x12
-#define AR13 0x13
-
-//
-// Sequencer Regs, SRxx, 3c4/3c5
-//
-#define SR00 0x00
-#define SR01 0x01
-#define SR02 0x02
-#define SR03 0x03
-#define SR04 0x04
-#define SR0D 0x0D
-#define SR0E 0x0E
-#define SR11 0x11
-#define SR18 0x18
-#define SR19 0x19
-
-//
-//
-//
-#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
-#define CR19 0x19
-#define CR1A 0x1A
-#define CR1B 0x1B
-#define CR1C 0x1C
-#define CR1D 0x1D
-#define CR1E 0x1E
-#define CR1F 0x1F
-#define CR20 0x20
-#define CR21 0x21
-#define CR27 0x27
-#define CR29 0x29
-#define CR2A 0x2A
-#define CR2B 0x2B
-#define CR2D 0x2D
-#define CR2F 0x2F
-#define CR36 0x36
-#define CR38 0x38
-#define CR39 0x39
-#define CR3A 0x3A
-#define CR55 0x55
-#define CR56 0x56
-#define CR57 0x57
-#define CR58 0x58
-
-//
-//
-//
-
-#define GR00 0x01
-#define GR01 0x01
-#define GR02 0x02
-#define GR03 0x03
-#define GR04 0x04
-#define GR05 0x05
-#define GR06 0x06
-#define GR07 0x07
-#define GR08 0x08
-#define GR0F 0x0F
-#define GR20 0x20
-#define GR23 0x23
-#define GR2F 0x2F
-#define GR30 0x30
-#define GR31 0x31
-#define GR33 0x33
-#define GR52 0x52
-#define GR53 0x53
-#define GR5D 0x5d
-
-
-//
-// Graphics Engine
-//
-#define GEBase 0x2100 // could be mapped elsewhere if we like it
-#define GE00 (GEBase+0x00) // source 1, p 111
-#define GE04 (GEBase+0x04) // source 2, p 111
-#define GE08 (GEBase+0x08) // destination 1, p 111
-#define GE0C (GEBase+0x0C) // destination 2, p 112
-#define GE10 (GEBase+0x10) // right view base & enable, p 112
-#define GE13 (GEBase+0x13) // left view base & enable, p 112
-#define GE18 (GEBase+0x18) // block write start address, p 112
-#define GE1C (GEBase+0x1C) // block write end address, p 112
-#define GE20 (GEBase+0x20) // engine status, p 113
-#define GE24 (GEBase+0x24) // reset all GE pointers
-#define GE44 (GEBase+0x44) // command register, p 126
-#define GE48 (GEBase+0x48) // raster operation, p 127
-#define GE60 (GEBase+0x60) // foreground color, p 128
-#define GE64 (GEBase+0x64) // background color, p 128
-#define GE6C (GEBase+0x6C) // Pattern and Style, p 129, ok
-#define GE9C (GEBase+0x9C) // pixel engine data port, p 125
-#define GEB8 (GEBase+0xB8) // Destination Stride / Buffer Base 0, p 133
-#define GEBC (GEBase+0xBC) // Destination Stride / Buffer Base 1, p 133
-#define GEC0 (GEBase+0xC0) // Destination Stride / Buffer Base 2, p 133
-#define GEC4 (GEBase+0xC4) // Destination Stride / Buffer Base 3, p 133
-#define GEC8 (GEBase+0xC8) // Source Stride / Buffer Base 0, p 133
-#define GECC (GEBase+0xCC) // Source Stride / Buffer Base 1, p 133
-#define GED0 (GEBase+0xD0) // Source Stride / Buffer Base 2, p 133
-#define GED4 (GEBase+0xD4) // Source Stride / Buffer Base 3, p 133
diff --git a/include/video/tdfx.h b/include/video/tdfx.h
index 7431d9681e5..befbaf0a92d 100644
--- a/include/video/tdfx.h
+++ b/include/video/tdfx.h
@@ -1,6 +1,9 @@
#ifndef _TDFX_H
#define _TDFX_H
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
/* membase0 register offsets */
#define STATUS 0x00
#define PCIINIT0 0x04
@@ -123,6 +126,18 @@
#define VIDCFG_PIXFMT_SHIFT 18
#define DACMODE_2X BIT(0)
+/* I2C bit locations in the VIDSERPARPORT register */
+#define DDC_ENAB 0x00040000
+#define DDC_SCL_OUT 0x00080000
+#define DDC_SDA_OUT 0x00100000
+#define DDC_SCL_IN 0x00200000
+#define DDC_SDA_IN 0x00400000
+#define I2C_ENAB 0x00800000
+#define I2C_SCL_OUT 0x01000000
+#define I2C_SDA_OUT 0x02000000
+#define I2C_SCL_IN 0x04000000
+#define I2C_SDA_IN 0x08000000
+
/* VGA rubbish, need to change this for multihead support */
#define MISC_W 0x3c2
#define MISC_R 0x3cc
@@ -168,12 +183,23 @@ struct banshee_reg {
unsigned long miscinit0;
};
+struct tdfx_par;
+
+struct tdfxfb_i2c_chan {
+ struct tdfx_par *par;
+ struct i2c_adapter adapter;
+ struct i2c_algo_bit_data algo;
+};
+
struct tdfx_par {
u32 max_pixclock;
u32 palette[16];
void __iomem *regbase_virt;
unsigned long iobase;
int mtrr_handle;
+#ifdef CONFIG_FB_3DFX_I2C
+ struct tdfxfb_i2c_chan chan[2];
+#endif
};
#endif /* __KERNEL__ */
diff --git a/init/Kconfig b/init/Kconfig
index 1398a14b019..7be4d383674 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -208,6 +208,12 @@ config POSIX_MQUEUE
If unsure, say Y.
+config POSIX_MQUEUE_SYSCTL
+ bool
+ depends on POSIX_MQUEUE
+ depends on SYSCTL
+ default y
+
config BSD_PROCESS_ACCT
bool "BSD Process Accounting"
help
@@ -565,7 +571,7 @@ config CGROUP_MEM_RES_CTLR
select MM_OWNER
help
Provides a memory resource controller that manages both anonymous
- memory and page cache. (See Documentation/controllers/memory.txt)
+ memory and page cache. (See Documentation/cgroups/memory.txt)
Note that setting this option increases fixed memory overhead
associated with each page of memory in the system. By this,
@@ -670,10 +676,10 @@ config UTS_NS
config IPC_NS
bool "IPC namespace"
- depends on NAMESPACES && SYSVIPC
+ depends on NAMESPACES && (SYSVIPC || POSIX_MQUEUE)
help
In this namespace tasks work with IPC ids which correspond to
- different IPC objects in different namespaces
+ different IPC objects in different namespaces.
config USER_NS
bool "User namespace (EXPERIMENTAL)"
@@ -689,7 +695,7 @@ config PID_NS
depends on NAMESPACES && EXPERIMENTAL
help
Support process id namespaces. This allows having multiple
- process with the same pid as long as they are in different
+ processes with the same pid as long as they are in different
pid namespaces. This is a building block of containers.
Unless you want to work with an experimental feature
@@ -802,6 +808,14 @@ config KALLSYMS_EXTRA_PASS
you wait for kallsyms to be fixed.
+config STRIP_ASM_SYMS
+ bool "Strip assembler-generated symbols during link"
+ default n
+ help
+ Strip internal assembler-generated symbols during a link (symbols
+ that look like '.Lxxx') so they don't pollute the output of
+ get_wchan() and suchlike.
+
config HOTPLUG
bool "Support for hot-pluggable devices" if EMBEDDED
default y
@@ -954,7 +968,7 @@ config COMPAT_BRK
Randomizing heap placement makes heap exploits harder, but it
also breaks ancient binaries (including anything libc5 based).
This option changes the bootup default to heap randomization
- disabled, and can be overriden runtime by setting
+ disabled, and can be overridden at runtime by setting
/proc/sys/kernel/randomize_va_space to 2.
On non-ancient distros (post-2000 ones) N is usually a safe choice.
@@ -1007,13 +1021,27 @@ config TRACEPOINTS
config MARKERS
bool "Activate markers"
- depends on TRACEPOINTS
+ select TRACEPOINTS
help
Place an empty function call at each marker site. Can be
dynamically changed for a probe function.
source "arch/Kconfig"
+config SLOW_WORK
+ default n
+ bool
+ help
+ The slow work thread pool provides a number of dynamically allocated
+ threads that can be used by the kernel to perform operations that
+ take a relatively long time.
+
+ An example of this would be CacheFiles doing a path lookup followed
+ by a series of mkdirs and a create call, all of which have to touch
+ disk.
+
+ See Documentation/slow-work.txt.
+
endmenu # General setup
config HAVE_GENERIC_DMA_COHERENT
@@ -1112,7 +1140,7 @@ config INIT_ALL_POSSIBLE
cpu_possible_map, some of them chose to initialize cpu_possible_map
with all 1s, and others with all 0s. When they were centralised,
it was better to provide this option than to break all the archs
- and have several arch maintainers persuing me down dark alleys.
+ and have several arch maintainers pursuing me down dark alleys.
config STOP_MACHINE
bool
diff --git a/init/do_mounts.h b/init/do_mounts.h
index 9aa968d5432..f5b978a9bb9 100644
--- a/init/do_mounts.h
+++ b/init/do_mounts.h
@@ -1,4 +1,5 @@
#include <linux/kernel.h>
+#include <linux/blkdev.h>
#include <linux/init.h>
#include <linux/syscalls.h>
#include <linux/unistd.h>
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
index 9bdddbcb3d6..69aebbf8fd2 100644
--- a/init/do_mounts_md.c
+++ b/init/do_mounts_md.c
@@ -1,5 +1,6 @@
#include <linux/delay.h>
-#include <linux/raid/md.h>
+#include <linux/raid/md_u.h>
+#include <linux/raid/md_p.h>
#include "do_mounts.h"
@@ -112,8 +113,6 @@ static int __init md_setup(char *str)
return 1;
}
-#define MdpMinorShift 6
-
static void __init md_setup_drive(void)
{
int minor, i, ent, partitioned;
diff --git a/init/initramfs.c b/init/initramfs.c
index 80cd713f6cc..9ee7b781041 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -310,7 +310,8 @@ static int __init do_name(void)
if (wfd >= 0) {
sys_fchown(wfd, uid, gid);
sys_fchmod(wfd, mode);
- sys_ftruncate(wfd, body_len);
+ if (body_len)
+ sys_ftruncate(wfd, body_len);
vcollected = kstrdup(collected, GFP_KERNEL);
state = CopyFile;
}
@@ -515,6 +516,7 @@ skip:
initrd_end = 0;
}
+#ifdef CONFIG_BLK_DEV_RAM
#define BUF_SIZE 1024
static void __init clean_rootfs(void)
{
@@ -561,6 +563,7 @@ static void __init clean_rootfs(void)
sys_close(fd);
kfree(buf);
}
+#endif
static int __init populate_rootfs(void)
{
diff --git a/init/main.c b/init/main.c
index 07c8658ffca..3585f073d63 100644
--- a/init/main.c
+++ b/init/main.c
@@ -71,6 +71,7 @@
#include <asm/setup.h>
#include <asm/sections.h>
#include <asm/cacheflush.h>
+#include <trace/kmemtrace.h>
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/smp.h>
@@ -648,6 +649,7 @@ asmlinkage void __init start_kernel(void)
enable_debug_pagealloc();
cpu_hotplug_init();
kmem_cache_init();
+ kmemtrace_init();
debug_objects_mem_init();
idr_init_cache();
setup_per_cpu_pageset();
@@ -769,6 +771,7 @@ static void __init do_basic_setup(void)
{
rcu_init_sched(); /* needed by module_init stage. */
init_workqueues();
+ cpuset_init_smp();
usermodehelper_init();
driver_init();
init_irq_proc();
@@ -863,8 +866,6 @@ static int __init kernel_init(void * unused)
smp_init();
sched_init_smp();
- cpuset_init_smp();
-
do_basic_setup();
/*
diff --git a/ipc/Makefile b/ipc/Makefile
index 65c38439580..4e1955ea815 100644
--- a/ipc/Makefile
+++ b/ipc/Makefile
@@ -8,4 +8,5 @@ obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o
obj_mq-$(CONFIG_COMPAT) += compat_mq.o
obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)
obj-$(CONFIG_IPC_NS) += namespace.o
+obj-$(CONFIG_POSIX_MQUEUE_SYSCTL) += mq_sysctl.o
diff --git a/ipc/mq_sysctl.c b/ipc/mq_sysctl.c
new file mode 100644
index 00000000000..24ae46dfe45
--- /dev/null
+++ b/ipc/mq_sysctl.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2007 IBM Corporation
+ *
+ * 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 the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#include <linux/nsproxy.h>
+#include <linux/ipc_namespace.h>
+#include <linux/sysctl.h>
+
+/*
+ * 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 */
+
+#ifdef CONFIG_PROC_SYSCTL
+static void *get_mq(ctl_table *table)
+{
+ char *which = table->data;
+ struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
+ which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns;
+ return which;
+}
+
+static int proc_mq_dointvec(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ struct ctl_table mq_table;
+ memcpy(&mq_table, table, sizeof(mq_table));
+ mq_table.data = get_mq(table);
+
+ return proc_dointvec(&mq_table, write, filp, buffer, lenp, ppos);
+}
+
+static int proc_mq_dointvec_minmax(ctl_table *table, int write,
+ struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ struct ctl_table mq_table;
+ memcpy(&mq_table, table, sizeof(mq_table));
+ mq_table.data = get_mq(table);
+
+ return proc_dointvec_minmax(&mq_table, write, filp, buffer,
+ lenp, ppos);
+}
+#else
+#define proc_mq_dointvec NULL
+#define proc_mq_dointvec_minmax NULL
+#endif
+
+static int msg_max_limit_min = MIN_MSGMAX;
+static int msg_max_limit_max = MAX_MSGMAX;
+
+static int msg_maxsize_limit_min = MIN_MSGSIZEMAX;
+static int msg_maxsize_limit_max = MAX_MSGSIZEMAX;
+
+static ctl_table mq_sysctls[] = {
+ {
+ .procname = "queues_max",
+ .data = &init_ipc_ns.mq_queues_max,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_mq_dointvec,
+ },
+ {
+ .procname = "msg_max",
+ .data = &init_ipc_ns.mq_msg_max,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_mq_dointvec_minmax,
+ .extra1 = &msg_max_limit_min,
+ .extra2 = &msg_max_limit_max,
+ },
+ {
+ .procname = "msgsize_max",
+ .data = &init_ipc_ns.mq_msgsize_max,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_mq_dointvec_minmax,
+ .extra1 = &msg_maxsize_limit_min,
+ .extra2 = &msg_maxsize_limit_max,
+ },
+ { .ctl_name = 0 }
+};
+
+static ctl_table mq_sysctl_dir[] = {
+ {
+ .procname = "mqueue",
+ .mode = 0555,
+ .child = mq_sysctls,
+ },
+ { .ctl_name = 0 }
+};
+
+static ctl_table mq_sysctl_root[] = {
+ {
+ .ctl_name = CTL_FS,
+ .procname = "fs",
+ .mode = 0555,
+ .child = mq_sysctl_dir,
+ },
+ { .ctl_name = 0 }
+};
+
+struct ctl_table_header *mq_register_sysctl_table(void)
+{
+ return register_sysctl_table(mq_sysctl_root);
+}
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 916785363f0..e35ba2c3a8d 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -31,6 +31,7 @@
#include <linux/mutex.h>
#include <linux/nsproxy.h>
#include <linux/pid.h>
+#include <linux/ipc_namespace.h>
#include <net/sock.h>
#include "util.h"
@@ -46,21 +47,6 @@
#define STATE_PENDING 1
#define STATE_READY 2
-/* default values */
-#define DFLT_QUEUESMAX 256 /* max number of message queues */
-#define DFLT_MSGMAX 10 /* max number of messages in each queue */
-#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;
struct list_head list;
@@ -93,14 +79,7 @@ static const struct file_operations mqueue_file_operations;
static struct super_operations mqueue_super_ops;
static void remove_notification(struct mqueue_inode_info *info);
-static spinlock_t mq_lock;
static struct kmem_cache *mqueue_inode_cachep;
-static struct vfsmount *mqueue_mnt;
-
-static unsigned int queues_count;
-static unsigned int queues_max = DFLT_QUEUESMAX;
-static unsigned int msg_max = DFLT_MSGMAX;
-static unsigned int msgsize_max = DFLT_MSGSIZEMAX;
static struct ctl_table_header * mq_sysctl_table;
@@ -109,8 +88,27 @@ static inline struct mqueue_inode_info *MQUEUE_I(struct inode *inode)
return container_of(inode, struct mqueue_inode_info, vfs_inode);
}
-static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
- struct mq_attr *attr)
+/*
+ * This routine should be called with the mq_lock held.
+ */
+static inline struct ipc_namespace *__get_ns_from_inode(struct inode *inode)
+{
+ return get_ipc_ns(inode->i_sb->s_fs_info);
+}
+
+static struct ipc_namespace *get_ns_from_inode(struct inode *inode)
+{
+ struct ipc_namespace *ns;
+
+ spin_lock(&mq_lock);
+ ns = __get_ns_from_inode(inode);
+ spin_unlock(&mq_lock);
+ return ns;
+}
+
+static struct inode *mqueue_get_inode(struct super_block *sb,
+ struct ipc_namespace *ipc_ns, int mode,
+ struct mq_attr *attr)
{
struct user_struct *u = current_user();
struct inode *inode;
@@ -141,8 +139,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 = msg_max;
- info->attr.mq_msgsize = msgsize_max;
+ info->attr.mq_maxmsg = ipc_ns->mq_msg_max;
+ info->attr.mq_msgsize = ipc_ns->mq_msgsize_max;
if (attr) {
info->attr.mq_maxmsg = attr->mq_maxmsg;
info->attr.mq_msgsize = attr->mq_msgsize;
@@ -188,30 +186,38 @@ out_inode:
static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *inode;
+ struct ipc_namespace *ns = data;
+ int error = 0;
sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
sb->s_magic = MQUEUE_MAGIC;
sb->s_op = &mqueue_super_ops;
- inode = mqueue_get_inode(sb, S_IFDIR | S_ISVTX | S_IRWXUGO, NULL);
- if (!inode)
- return -ENOMEM;
+ inode = mqueue_get_inode(sb, ns, S_IFDIR | S_ISVTX | S_IRWXUGO,
+ NULL);
+ if (!inode) {
+ error = -ENOMEM;
+ goto out;
+ }
sb->s_root = d_alloc_root(inode);
if (!sb->s_root) {
iput(inode);
- return -ENOMEM;
+ error = -ENOMEM;
}
- return 0;
+out:
+ return error;
}
static int mqueue_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name,
void *data, struct vfsmount *mnt)
{
- return get_sb_single(fs_type, flags, data, mqueue_fill_super, mnt);
+ if (!(flags & MS_KERNMOUNT))
+ data = current->nsproxy->ipc_ns;
+ return get_sb_ns(fs_type, flags, data, mqueue_fill_super, mnt);
}
static void init_once(void *foo)
@@ -242,11 +248,13 @@ static void mqueue_delete_inode(struct inode *inode)
struct user_struct *user;
unsigned long mq_bytes;
int i;
+ struct ipc_namespace *ipc_ns;
if (S_ISDIR(inode->i_mode)) {
clear_inode(inode);
return;
}
+ ipc_ns = get_ns_from_inode(inode);
info = MQUEUE_I(inode);
spin_lock(&info->lock);
for (i = 0; i < info->attr.mq_curmsgs; i++)
@@ -262,10 +270,19 @@ static void mqueue_delete_inode(struct inode *inode)
if (user) {
spin_lock(&mq_lock);
user->mq_bytes -= mq_bytes;
- queues_count--;
+ /*
+ * get_ns_from_inode() ensures that the
+ * (ipc_ns = sb->s_fs_info) is either a valid ipc_ns
+ * to which we now hold a reference, or it is NULL.
+ * We can't put it here under mq_lock, though.
+ */
+ if (ipc_ns)
+ ipc_ns->mq_queues_count--;
spin_unlock(&mq_lock);
free_uid(user);
}
+ if (ipc_ns)
+ put_ipc_ns(ipc_ns);
}
static int mqueue_create(struct inode *dir, struct dentry *dentry,
@@ -274,31 +291,41 @@ static int mqueue_create(struct inode *dir, struct dentry *dentry,
struct inode *inode;
struct mq_attr *attr = dentry->d_fsdata;
int error;
+ struct ipc_namespace *ipc_ns;
spin_lock(&mq_lock);
- if (queues_count >= queues_max && !capable(CAP_SYS_RESOURCE)) {
+ ipc_ns = __get_ns_from_inode(dir);
+ if (!ipc_ns) {
+ error = -EACCES;
+ goto out_unlock;
+ }
+ if (ipc_ns->mq_queues_count >= ipc_ns->mq_queues_max &&
+ !capable(CAP_SYS_RESOURCE)) {
error = -ENOSPC;
- goto out_lock;
+ goto out_unlock;
}
- queues_count++;
+ ipc_ns->mq_queues_count++;
spin_unlock(&mq_lock);
- inode = mqueue_get_inode(dir->i_sb, mode, attr);
+ inode = mqueue_get_inode(dir->i_sb, ipc_ns, mode, attr);
if (!inode) {
error = -ENOMEM;
spin_lock(&mq_lock);
- queues_count--;
- goto out_lock;
+ ipc_ns->mq_queues_count--;
+ goto out_unlock;
}
+ put_ipc_ns(ipc_ns);
dir->i_size += DIRENT_SIZE;
dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME;
d_instantiate(dentry, inode);
dget(dentry);
return 0;
-out_lock:
+out_unlock:
spin_unlock(&mq_lock);
+ if (ipc_ns)
+ put_ipc_ns(ipc_ns);
return error;
}
@@ -562,7 +589,7 @@ static void remove_notification(struct mqueue_inode_info *info)
info->notify_owner = NULL;
}
-static int mq_attr_ok(struct mq_attr *attr)
+static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr)
{
if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0)
return 0;
@@ -570,8 +597,8 @@ static int mq_attr_ok(struct mq_attr *attr)
if (attr->mq_maxmsg > HARD_MSGMAX)
return 0;
} else {
- if (attr->mq_maxmsg > msg_max ||
- attr->mq_msgsize > msgsize_max)
+ if (attr->mq_maxmsg > ipc_ns->mq_msg_max ||
+ attr->mq_msgsize > ipc_ns->mq_msgsize_max)
return 0;
}
/* check for overflow */
@@ -587,8 +614,9 @@ static int mq_attr_ok(struct mq_attr *attr)
/*
* Invoked when creating a new queue via sys_mq_open
*/
-static struct file *do_create(struct dentry *dir, struct dentry *dentry,
- int oflag, mode_t mode, struct mq_attr *attr)
+static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir,
+ struct dentry *dentry, int oflag, mode_t mode,
+ struct mq_attr *attr)
{
const struct cred *cred = current_cred();
struct file *result;
@@ -596,14 +624,14 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
if (attr) {
ret = -EINVAL;
- if (!mq_attr_ok(attr))
+ if (!mq_attr_ok(ipc_ns, attr))
goto out;
/* store for use during create */
dentry->d_fsdata = attr;
}
mode &= ~current_umask();
- ret = mnt_want_write(mqueue_mnt);
+ ret = mnt_want_write(ipc_ns->mq_mnt);
if (ret)
goto out;
ret = vfs_create(dir->d_inode, dentry, mode, NULL);
@@ -611,24 +639,25 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
if (ret)
goto out_drop_write;
- result = dentry_open(dentry, mqueue_mnt, oflag, cred);
+ result = dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred);
/*
* dentry_open() took a persistent mnt_want_write(),
* so we can now drop this one.
*/
- mnt_drop_write(mqueue_mnt);
+ mnt_drop_write(ipc_ns->mq_mnt);
return result;
out_drop_write:
- mnt_drop_write(mqueue_mnt);
+ mnt_drop_write(ipc_ns->mq_mnt);
out:
dput(dentry);
- mntput(mqueue_mnt);
+ mntput(ipc_ns->mq_mnt);
return ERR_PTR(ret);
}
/* Opens existing queue */
-static struct file *do_open(struct dentry *dentry, int oflag)
+static struct file *do_open(struct ipc_namespace *ipc_ns,
+ struct dentry *dentry, int oflag)
{
const struct cred *cred = current_cred();
@@ -637,17 +666,17 @@ static struct file *do_open(struct dentry *dentry, int oflag)
if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) {
dput(dentry);
- mntput(mqueue_mnt);
+ mntput(ipc_ns->mq_mnt);
return ERR_PTR(-EINVAL);
}
if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) {
dput(dentry);
- mntput(mqueue_mnt);
+ mntput(ipc_ns->mq_mnt);
return ERR_PTR(-EACCES);
}
- return dentry_open(dentry, mqueue_mnt, oflag, cred);
+ return dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred);
}
SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
@@ -658,6 +687,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
char *name;
struct mq_attr attr;
int fd, error;
+ struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr)))
return -EFAULT;
@@ -671,13 +701,13 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
if (fd < 0)
goto out_putname;
- mutex_lock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
- dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name));
+ mutex_lock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex);
+ dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name));
if (IS_ERR(dentry)) {
error = PTR_ERR(dentry);
goto out_err;
}
- mntget(mqueue_mnt);
+ mntget(ipc_ns->mq_mnt);
if (oflag & O_CREAT) {
if (dentry->d_inode) { /* entry already exists */
@@ -685,10 +715,10 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
error = -EEXIST;
if (oflag & O_EXCL)
goto out;
- filp = do_open(dentry, oflag);
+ filp = do_open(ipc_ns, dentry, oflag);
} else {
- filp = do_create(mqueue_mnt->mnt_root, dentry,
- oflag, mode,
+ filp = do_create(ipc_ns, ipc_ns->mq_mnt->mnt_root,
+ dentry, oflag, mode,
u_attr ? &attr : NULL);
}
} else {
@@ -696,7 +726,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
if (!dentry->d_inode)
goto out;
audit_inode(name, dentry);
- filp = do_open(dentry, oflag);
+ filp = do_open(ipc_ns, dentry, oflag);
}
if (IS_ERR(filp)) {
@@ -709,13 +739,13 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
out:
dput(dentry);
- mntput(mqueue_mnt);
+ mntput(ipc_ns->mq_mnt);
out_putfd:
put_unused_fd(fd);
out_err:
fd = error;
out_upsem:
- mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
+ mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex);
out_putname:
putname(name);
return fd;
@@ -727,14 +757,15 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
char *name;
struct dentry *dentry;
struct inode *inode = NULL;
+ struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
name = getname(u_name);
if (IS_ERR(name))
return PTR_ERR(name);
- mutex_lock_nested(&mqueue_mnt->mnt_root->d_inode->i_mutex,
+ mutex_lock_nested(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex,
I_MUTEX_PARENT);
- dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name));
+ dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name));
if (IS_ERR(dentry)) {
err = PTR_ERR(dentry);
goto out_unlock;
@@ -748,16 +779,16 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
inode = dentry->d_inode;
if (inode)
atomic_inc(&inode->i_count);
- err = mnt_want_write(mqueue_mnt);
+ err = mnt_want_write(ipc_ns->mq_mnt);
if (err)
goto out_err;
err = vfs_unlink(dentry->d_parent->d_inode, dentry);
- mnt_drop_write(mqueue_mnt);
+ mnt_drop_write(ipc_ns->mq_mnt);
out_err:
dput(dentry);
out_unlock:
- mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
+ mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex);
putname(name);
if (inode)
iput(inode);
@@ -1205,59 +1236,31 @@ static struct file_system_type mqueue_fs_type = {
.kill_sb = kill_litter_super,
};
-static int msg_max_limit_min = MIN_MSGMAX;
-static int msg_max_limit_max = MAX_MSGMAX;
-
-static int msg_maxsize_limit_min = MIN_MSGSIZEMAX;
-static int msg_maxsize_limit_max = MAX_MSGSIZEMAX;
-
-static ctl_table mq_sysctls[] = {
- {
- .procname = "queues_max",
- .data = &queues_max,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
- {
- .procname = "msg_max",
- .data = &msg_max,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_minmax,
- .extra1 = &msg_max_limit_min,
- .extra2 = &msg_max_limit_max,
- },
- {
- .procname = "msgsize_max",
- .data = &msgsize_max,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_minmax,
- .extra1 = &msg_maxsize_limit_min,
- .extra2 = &msg_maxsize_limit_max,
- },
- { .ctl_name = 0 }
-};
+int mq_init_ns(struct ipc_namespace *ns)
+{
+ ns->mq_queues_count = 0;
+ ns->mq_queues_max = DFLT_QUEUESMAX;
+ ns->mq_msg_max = DFLT_MSGMAX;
+ ns->mq_msgsize_max = DFLT_MSGSIZEMAX;
+
+ ns->mq_mnt = kern_mount_data(&mqueue_fs_type, ns);
+ if (IS_ERR(ns->mq_mnt)) {
+ int err = PTR_ERR(ns->mq_mnt);
+ ns->mq_mnt = NULL;
+ return err;
+ }
+ return 0;
+}
-static ctl_table mq_sysctl_dir[] = {
- {
- .procname = "mqueue",
- .mode = 0555,
- .child = mq_sysctls,
- },
- { .ctl_name = 0 }
-};
+void mq_clear_sbinfo(struct ipc_namespace *ns)
+{
+ ns->mq_mnt->mnt_sb->s_fs_info = NULL;
+}
-static ctl_table mq_sysctl_root[] = {
- {
- .ctl_name = CTL_FS,
- .procname = "fs",
- .mode = 0555,
- .child = mq_sysctl_dir,
- },
- { .ctl_name = 0 }
-};
+void mq_put_mnt(struct ipc_namespace *ns)
+{
+ mntput(ns->mq_mnt);
+}
static int __init init_mqueue_fs(void)
{
@@ -1270,21 +1273,20 @@ static int __init init_mqueue_fs(void)
return -ENOMEM;
/* ignore failues - they are not fatal */
- mq_sysctl_table = register_sysctl_table(mq_sysctl_root);
+ mq_sysctl_table = mq_register_sysctl_table();
error = register_filesystem(&mqueue_fs_type);
if (error)
goto out_sysctl;
- if (IS_ERR(mqueue_mnt = kern_mount(&mqueue_fs_type))) {
- error = PTR_ERR(mqueue_mnt);
+ spin_lock_init(&mq_lock);
+
+ init_ipc_ns.mq_mnt = kern_mount_data(&mqueue_fs_type, &init_ipc_ns);
+ if (IS_ERR(init_ipc_ns.mq_mnt)) {
+ error = PTR_ERR(init_ipc_ns.mq_mnt);
goto out_filesystem;
}
- /* internal initialization - not common for vfs */
- queues_count = 0;
- spin_lock_init(&mq_lock);
-
return 0;
out_filesystem:
diff --git a/ipc/msgutil.c b/ipc/msgutil.c
index c82c215693d..f095ee26883 100644
--- a/ipc/msgutil.c
+++ b/ipc/msgutil.c
@@ -13,10 +13,29 @@
#include <linux/security.h>
#include <linux/slab.h>
#include <linux/ipc.h>
+#include <linux/ipc_namespace.h>
#include <asm/uaccess.h>
#include "util.h"
+DEFINE_SPINLOCK(mq_lock);
+
+/*
+ * The next 2 defines are here bc this is the only file
+ * compiled when either CONFIG_SYSVIPC and CONFIG_POSIX_MQUEUE
+ * and not CONFIG_IPC_NS.
+ */
+struct ipc_namespace init_ipc_ns = {
+ .count = ATOMIC_INIT(1),
+#ifdef CONFIG_POSIX_MQUEUE
+ .mq_queues_max = DFLT_QUEUESMAX,
+ .mq_msg_max = DFLT_MSGMAX,
+ .mq_msgsize_max = DFLT_MSGSIZEMAX,
+#endif
+};
+
+atomic_t nr_ipc_ns = ATOMIC_INIT(1);
+
struct msg_msgseg {
struct msg_msgseg* next;
/* the next part of the message follows immediately */
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 9171d948751..4a5e752a927 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -9,17 +9,26 @@
#include <linux/rcupdate.h>
#include <linux/nsproxy.h>
#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
#include "util.h"
static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
{
struct ipc_namespace *ns;
+ int err;
ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL);
if (ns == NULL)
return ERR_PTR(-ENOMEM);
+ atomic_set(&ns->count, 1);
+ err = mq_init_ns(ns);
+ if (err) {
+ kfree(ns);
+ return ERR_PTR(err);
+ }
atomic_inc(&nr_ipc_ns);
sem_init_ns(ns);
@@ -34,7 +43,6 @@ static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
ipcns_notify(IPCNS_CREATED);
register_ipcns_notifier(ns);
- kref_init(&ns->kref);
return ns;
}
@@ -84,11 +92,34 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
up_write(&ids->rw_mutex);
}
-void free_ipc_ns(struct kref *kref)
+/*
+ * put_ipc_ns - drop a reference to an ipc namespace.
+ * @ns: the namespace to put
+ *
+ * If this is the last task in the namespace exiting, and
+ * it is dropping the refcount to 0, then it can race with
+ * a task in another ipc namespace but in a mounts namespace
+ * which has this ipcns's mqueuefs mounted, doing some action
+ * with one of the mqueuefs files. That can raise the refcount.
+ * So dropping the refcount, and raising the refcount when
+ * accessing it through the VFS, are protected with mq_lock.
+ *
+ * (Clearly, a task raising the refcount on its own ipc_ns
+ * needn't take mq_lock since it can't race with the last task
+ * in the ipcns exiting).
+ */
+void put_ipc_ns(struct ipc_namespace *ns)
{
- struct ipc_namespace *ns;
+ if (atomic_dec_and_lock(&ns->count, &mq_lock)) {
+ mq_clear_sbinfo(ns);
+ spin_unlock(&mq_lock);
+ mq_put_mnt(ns);
+ free_ipc_ns(ns);
+ }
+}
- ns = container_of(kref, struct ipc_namespace, kref);
+void free_ipc_ns(struct ipc_namespace *ns)
+{
/*
* Unregistering the hotplug notifier at the beginning guarantees
* that the ipc namespace won't be freed while we are inside the
diff --git a/ipc/util.c b/ipc/util.c
index 7585a72e259..b8e4ba92f6d 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -47,15 +47,6 @@ struct ipc_proc_iface {
int (*show)(struct seq_file *, void *);
};
-struct ipc_namespace init_ipc_ns = {
- .kref = {
- .refcount = ATOMIC_INIT(2),
- },
-};
-
-atomic_t nr_ipc_ns = ATOMIC_INIT(1);
-
-
#ifdef CONFIG_MEMORY_HOTPLUG
static void ipc_memory_notifier(struct work_struct *work)
diff --git a/ipc/util.h b/ipc/util.h
index 3646b45a03c..1187332a89d 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -20,6 +20,15 @@ void shm_init (void);
struct ipc_namespace;
+#ifdef CONFIG_POSIX_MQUEUE
+extern void mq_clear_sbinfo(struct ipc_namespace *ns);
+extern void mq_put_mnt(struct ipc_namespace *ns);
+#else
+static inline void mq_clear_sbinfo(struct ipc_namespace *ns) { }
+static inline void mq_put_mnt(struct ipc_namespace *ns) { }
+#endif
+
+#ifdef CONFIG_SYSVIPC
void sem_init_ns(struct ipc_namespace *ns);
void msg_init_ns(struct ipc_namespace *ns);
void shm_init_ns(struct ipc_namespace *ns);
@@ -27,6 +36,15 @@ void shm_init_ns(struct ipc_namespace *ns);
void sem_exit_ns(struct ipc_namespace *ns);
void msg_exit_ns(struct ipc_namespace *ns);
void shm_exit_ns(struct ipc_namespace *ns);
+#else
+static inline void sem_init_ns(struct ipc_namespace *ns) { }
+static inline void msg_init_ns(struct ipc_namespace *ns) { }
+static inline void shm_init_ns(struct ipc_namespace *ns) { }
+
+static inline void sem_exit_ns(struct ipc_namespace *ns) { }
+static inline void msg_exit_ns(struct ipc_namespace *ns) { }
+static inline void shm_exit_ns(struct ipc_namespace *ns) { }
+#endif
/*
* Structure that holds the parameters needed by the ipc operations
diff --git a/kernel/Makefile b/kernel/Makefile
index e4791b3ba55..42423665660 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_AUDIT_TREE) += audit_tree.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
+obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o
obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
obj-$(CONFIG_SECCOMP) += seccomp.o
obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
@@ -93,6 +94,7 @@ obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
obj-$(CONFIG_FUNCTION_TRACER) += trace/
obj-$(CONFIG_TRACING) += trace/
obj-$(CONFIG_SMP) += sched_cpupri.o
+obj-$(CONFIG_SLOW_WORK) += slow-work.o
ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/audit.c b/kernel/audit.c
index ce6d8ea3131..9442c3533ba 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -766,6 +766,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
audit_log_format(ab, " msg=");
size = nlmsg_len(nlh);
+ if (size > 0 &&
+ ((unsigned char *)data)[size - 1] == '\0')
+ size--;
audit_log_n_untrustedstring(ab, data, size);
}
audit_set_pid(ab, pid);
@@ -1382,7 +1385,7 @@ void audit_log_n_string(struct audit_buffer *ab, const char *string,
int audit_string_contains_control(const char *string, size_t len)
{
const unsigned char *p;
- for (p = string; p < (const unsigned char *)string + len && *p; p++) {
+ for (p = string; p < (const unsigned char *)string + len; p++) {
if (*p == '"' || *p < 0x21 || *p > 0x7e)
return 1;
}
@@ -1437,13 +1440,13 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
/* We will allow 11 spaces for ' (deleted)' to be appended */
pathname = kmalloc(PATH_MAX+11, ab->gfp_mask);
if (!pathname) {
- audit_log_format(ab, "<no memory>");
+ audit_log_string(ab, "<no_memory>");
return;
}
p = d_path(path, pathname, PATH_MAX+11);
if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
/* FIXME: can we save some information here? */
- audit_log_format(ab, "<too long>");
+ audit_log_string(ab, "<too_long>");
} else
audit_log_untrustedstring(ab, p);
kfree(pathname);
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 8ad9545b8db..917ab952556 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -385,6 +385,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
mutex_lock(&inode->inotify_mutex);
if (inotify_clone_watch(&old->watch, &chunk->watch) < 0) {
mutex_unlock(&inode->inotify_mutex);
+ put_inotify_watch(&old->watch);
free_chunk(chunk);
return -ENOSPC;
}
@@ -394,6 +395,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
chunk->dead = 1;
inotify_evict_watch(&chunk->watch);
mutex_unlock(&inode->inotify_mutex);
+ put_inotify_watch(&old->watch);
put_inotify_watch(&chunk->watch);
return 0;
}
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index fbf24d121d9..a6fe71fd5d1 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -135,18 +135,18 @@ static void audit_remove_watch(struct audit_watch *watch)
static inline void audit_free_rule(struct audit_entry *e)
{
int i;
-
+ struct audit_krule *erule = &e->rule;
/* some rules don't have associated watches */
- if (e->rule.watch)
- audit_put_watch(e->rule.watch);
- if (e->rule.fields)
- for (i = 0; i < e->rule.field_count; i++) {
- struct audit_field *f = &e->rule.fields[i];
+ if (erule->watch)
+ audit_put_watch(erule->watch);
+ if (erule->fields)
+ for (i = 0; i < erule->field_count; i++) {
+ struct audit_field *f = &erule->fields[i];
kfree(f->lsm_str);
security_audit_rule_free(f->lsm_rule);
}
- kfree(e->rule.fields);
- kfree(e->rule.filterkey);
+ kfree(erule->fields);
+ kfree(erule->filterkey);
kfree(e);
}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 2bfc6478676..7d6ac7c1f41 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -329,6 +329,14 @@ static int audit_match_filetype(struct audit_context *ctx, int which)
*/
#ifdef CONFIG_AUDIT_TREE
+static void audit_set_auditable(struct audit_context *ctx)
+{
+ if (!ctx->prio) {
+ ctx->prio = 1;
+ ctx->current_state = AUDIT_RECORD_CONTEXT;
+ }
+}
+
static int put_tree_ref(struct audit_context *ctx, struct audit_chunk *chunk)
{
struct audit_tree_refs *p = ctx->trees;
@@ -742,17 +750,9 @@ void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx)
rcu_read_unlock();
}
-static void audit_set_auditable(struct audit_context *ctx)
-{
- if (!ctx->prio) {
- ctx->prio = 1;
- ctx->current_state = AUDIT_RECORD_CONTEXT;
- }
-}
-
static inline struct audit_context *audit_get_context(struct task_struct *tsk,
int return_valid,
- int return_code)
+ long return_code)
{
struct audit_context *context = tsk->audit_context;
@@ -1024,7 +1024,7 @@ static int audit_log_single_execve_arg(struct audit_context *context,
{
char arg_num_len_buf[12];
const char __user *tmp_p = p;
- /* how many digits are in arg_num? 3 is the length of a=\n */
+ /* how many digits are in arg_num? 3 is the length of " a=" */
size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 3;
size_t len, len_left, to_send;
size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN;
@@ -1110,7 +1110,7 @@ static int audit_log_single_execve_arg(struct audit_context *context,
* so we can be sure nothing was lost.
*/
if ((i == 0) && (too_long))
- audit_log_format(*ab, "a%d_len=%zu ", arg_num,
+ audit_log_format(*ab, " a%d_len=%zu", arg_num,
has_cntl ? 2*len : len);
/*
@@ -1130,7 +1130,7 @@ static int audit_log_single_execve_arg(struct audit_context *context,
buf[to_send] = '\0';
/* actually log it */
- audit_log_format(*ab, "a%d", arg_num);
+ audit_log_format(*ab, " a%d", arg_num);
if (too_long)
audit_log_format(*ab, "[%d]", i);
audit_log_format(*ab, "=");
@@ -1138,7 +1138,6 @@ static int audit_log_single_execve_arg(struct audit_context *context,
audit_log_n_hex(*ab, buf, to_send);
else
audit_log_format(*ab, "\"%s\"", buf);
- audit_log_format(*ab, "\n");
p += to_send;
len_left -= to_send;
@@ -1166,7 +1165,7 @@ static void audit_log_execve_info(struct audit_context *context,
p = (const char __user *)axi->mm->arg_start;
- audit_log_format(*ab, "argc=%d ", axi->argc);
+ audit_log_format(*ab, "argc=%d", axi->argc);
/*
* we need some kernel buffer to hold the userspace args. Just
@@ -1479,7 +1478,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
case 0:
/* name was specified as a relative path and the
* directory component is the cwd */
- audit_log_d_path(ab, " name=", &context->pwd);
+ audit_log_d_path(ab, "name=", &context->pwd);
break;
default:
/* log the name's directory component */
@@ -2150,7 +2149,7 @@ int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
* __audit_mq_open - record audit data for a POSIX MQ open
* @oflag: open flag
* @mode: mode bits
- * @u_attr: queue attributes
+ * @attr: queue attributes
*
*/
void __audit_mq_open(int oflag, mode_t mode, struct mq_attr *attr)
@@ -2197,7 +2196,7 @@ void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
/**
* __audit_mq_notify - record audit data for a POSIX MQ notify
* @mqdes: MQ descriptor
- * @u_notification: Notification event
+ * @notification: Notification event
*
*/
diff --git a/kernel/exit.c b/kernel/exit.c
index 6686ed1e4aa..abf9cf3b95c 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -837,8 +837,7 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
*/
if (tsk->exit_signal != SIGCHLD && !task_detached(tsk) &&
(tsk->parent_exec_id != tsk->real_parent->self_exec_id ||
- tsk->self_exec_id != tsk->parent_exec_id) &&
- !capable(CAP_KILL))
+ tsk->self_exec_id != tsk->parent_exec_id))
tsk->exit_signal = SIGCHLD;
signal = tracehook_notify_death(tsk, &cookie, group_dead);
@@ -924,6 +923,8 @@ NORET_TYPE void do_exit(long code)
schedule();
}
+ exit_irq_thread();
+
exit_signals(tsk); /* sets PF_EXITING */
/*
* tsk->flags are checked in the futex code to protect against
diff --git a/kernel/extable.c b/kernel/extable.c
index e136ed8d82b..7f8f263f852 100644
--- a/kernel/extable.c
+++ b/kernel/extable.c
@@ -15,11 +15,22 @@
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/ftrace.h>
+#include <linux/memory.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/init.h>
-#include <linux/ftrace.h>
-#include <asm/uaccess.h>
+
#include <asm/sections.h>
+#include <asm/uaccess.h>
+
+/*
+ * mutex protecting text section modification (dynamic code patching).
+ * some users need to sleep (allocating memory...) while they hold this lock.
+ *
+ * NOT exported to modules - patching kernel text is a really delicate matter.
+ */
+DEFINE_MUTEX(text_mutex);
extern struct exception_table_entry __start___ex_table[];
extern struct exception_table_entry __stop___ex_table[];
@@ -41,31 +52,50 @@ const struct exception_table_entry *search_exception_tables(unsigned long addr)
return e;
}
-__notrace_funcgraph int core_kernel_text(unsigned long addr)
+static inline int init_kernel_text(unsigned long addr)
+{
+ if (addr >= (unsigned long)_sinittext &&
+ addr <= (unsigned long)_einittext)
+ return 1;
+ return 0;
+}
+
+int core_kernel_text(unsigned long addr)
{
if (addr >= (unsigned long)_stext &&
addr <= (unsigned long)_etext)
return 1;
if (system_state == SYSTEM_BOOTING &&
- addr >= (unsigned long)_sinittext &&
- addr <= (unsigned long)_einittext)
+ init_kernel_text(addr))
return 1;
return 0;
}
-__notrace_funcgraph int __kernel_text_address(unsigned long addr)
+int __kernel_text_address(unsigned long addr)
{
if (core_kernel_text(addr))
return 1;
- return __module_text_address(addr) != NULL;
+ if (is_module_text_address(addr))
+ return 1;
+ /*
+ * There might be init symbols in saved stacktraces.
+ * Give those symbols a chance to be printed in
+ * backtraces (such as lockdep traces).
+ *
+ * Since we are after the module-symbols check, there's
+ * no danger of address overlap:
+ */
+ if (init_kernel_text(addr))
+ return 1;
+ return 0;
}
int kernel_text_address(unsigned long addr)
{
if (core_kernel_text(addr))
return 1;
- return module_text_address(addr) != NULL;
+ return is_module_text_address(addr);
}
/*
@@ -81,5 +111,5 @@ int func_ptr_is_kernel_text(void *ptr)
addr = (unsigned long) dereference_function_descriptor(ptr);
if (core_kernel_text(addr))
return 1;
- return module_text_address(addr) != NULL;
+ return is_module_text_address(addr);
}
diff --git a/kernel/fork.c b/kernel/fork.c
index 660c2b8765b..b9e2edd0072 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -645,6 +645,9 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
tsk->min_flt = tsk->maj_flt = 0;
tsk->nvcsw = tsk->nivcsw = 0;
+#ifdef CONFIG_DETECT_HUNG_TASK
+ tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw;
+#endif
tsk->mm = NULL;
tsk->active_mm = NULL;
@@ -797,6 +800,12 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)
sig->cputime_expires.virt_exp = cputime_zero;
sig->cputime_expires.sched_exp = 0;
+ if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
+ sig->cputime_expires.prof_exp =
+ secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
+ sig->cputimer.running = 1;
+ }
+
/* The timer lists. */
INIT_LIST_HEAD(&sig->cpu_timers[0]);
INIT_LIST_HEAD(&sig->cpu_timers[1]);
@@ -812,11 +821,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
atomic_inc(&current->signal->live);
return 0;
}
- sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
-
- if (sig)
- posix_cpu_timers_init_group(sig);
+ sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
tsk->signal = sig;
if (!sig)
return -ENOMEM;
@@ -856,6 +862,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
task_unlock(current->group_leader);
+ posix_cpu_timers_init_group(sig);
+
acct_init_pacct(&sig->pacct);
tty_audit_fork(sig);
@@ -1032,11 +1040,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->default_timer_slack_ns = current->timer_slack_ns;
-#ifdef CONFIG_DETECT_SOFTLOCKUP
- p->last_switch_count = 0;
- p->last_switch_timestamp = 0;
-#endif
-
task_io_accounting_init(&p->ioac);
acct_clear_integrals(p);
diff --git a/kernel/futex.c b/kernel/futex.c
index 6b50a024bca..eef8cd26b5e 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -883,7 +883,12 @@ retry_private:
out_unlock:
double_unlock_hb(hb1, hb2);
- /* drop_futex_key_refs() must be called outside the spinlocks. */
+ /*
+ * drop_futex_key_refs() must be called outside the spinlocks. During
+ * the requeue we moved futex_q's from the hash bucket at key1 to the
+ * one at key2 and updated their key pointer. We no longer need to
+ * hold the references to key1.
+ */
while (--drop_count >= 0)
drop_futex_key_refs(&key1);
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index f394d2a42ca..cb8a15c1958 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -651,14 +651,20 @@ static inline void hrtimer_init_timer_hres(struct hrtimer *timer)
* and expiry check is done in the hrtimer_interrupt or in the softirq.
*/
static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
- struct hrtimer_clock_base *base)
+ struct hrtimer_clock_base *base,
+ int wakeup)
{
if (base->cpu_base->hres_active && hrtimer_reprogram(timer, base)) {
- spin_unlock(&base->cpu_base->lock);
- raise_softirq_irqoff(HRTIMER_SOFTIRQ);
- spin_lock(&base->cpu_base->lock);
+ if (wakeup) {
+ spin_unlock(&base->cpu_base->lock);
+ raise_softirq_irqoff(HRTIMER_SOFTIRQ);
+ spin_lock(&base->cpu_base->lock);
+ } else
+ __raise_softirq_irqoff(HRTIMER_SOFTIRQ);
+
return 1;
}
+
return 0;
}
@@ -703,7 +709,8 @@ static inline int hrtimer_is_hres_enabled(void) { return 0; }
static inline int hrtimer_switch_to_hres(void) { return 0; }
static inline void hrtimer_force_reprogram(struct hrtimer_cpu_base *base) { }
static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
- struct hrtimer_clock_base *base)
+ struct hrtimer_clock_base *base,
+ int wakeup)
{
return 0;
}
@@ -886,20 +893,9 @@ remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base)
return 0;
}
-/**
- * hrtimer_start_range_ns - (re)start an hrtimer on the current CPU
- * @timer: the timer to be added
- * @tim: expiry time
- * @delta_ns: "slack" range for the timer
- * @mode: expiry mode: absolute (HRTIMER_ABS) or relative (HRTIMER_REL)
- *
- * Returns:
- * 0 on success
- * 1 when the timer was active
- */
-int
-hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, unsigned long delta_ns,
- const enum hrtimer_mode mode)
+int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
+ unsigned long delta_ns, const enum hrtimer_mode mode,
+ int wakeup)
{
struct hrtimer_clock_base *base, *new_base;
unsigned long flags;
@@ -940,12 +936,29 @@ hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, unsigned long delta_n
* XXX send_remote_softirq() ?
*/
if (leftmost && new_base->cpu_base == &__get_cpu_var(hrtimer_bases))
- hrtimer_enqueue_reprogram(timer, new_base);
+ hrtimer_enqueue_reprogram(timer, new_base, wakeup);
unlock_hrtimer_base(timer, &flags);
return ret;
}
+
+/**
+ * hrtimer_start_range_ns - (re)start an hrtimer on the current CPU
+ * @timer: the timer to be added
+ * @tim: expiry time
+ * @delta_ns: "slack" range for the timer
+ * @mode: expiry mode: absolute (HRTIMER_ABS) or relative (HRTIMER_REL)
+ *
+ * Returns:
+ * 0 on success
+ * 1 when the timer was active
+ */
+int hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
+ unsigned long delta_ns, const enum hrtimer_mode mode)
+{
+ return __hrtimer_start_range_ns(timer, tim, delta_ns, mode, 1);
+}
EXPORT_SYMBOL_GPL(hrtimer_start_range_ns);
/**
@@ -961,7 +974,7 @@ EXPORT_SYMBOL_GPL(hrtimer_start_range_ns);
int
hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
{
- return hrtimer_start_range_ns(timer, tim, 0, mode);
+ return __hrtimer_start_range_ns(timer, tim, 0, mode, 1);
}
EXPORT_SYMBOL_GPL(hrtimer_start);
diff --git a/kernel/hung_task.c b/kernel/hung_task.c
new file mode 100644
index 00000000000..022a4927b78
--- /dev/null
+++ b/kernel/hung_task.c
@@ -0,0 +1,217 @@
+/*
+ * Detect Hung Task
+ *
+ * kernel/hung_task.c - kernel thread for detecting tasks stuck in D state
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/cpu.h>
+#include <linux/nmi.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/freezer.h>
+#include <linux/kthread.h>
+#include <linux/lockdep.h>
+#include <linux/module.h>
+#include <linux/sysctl.h>
+
+/*
+ * The number of tasks checked:
+ */
+unsigned long __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT;
+
+/*
+ * Limit number of tasks checked in a batch.
+ *
+ * This value controls the preemptibility of khungtaskd since preemption
+ * is disabled during the critical section. It also controls the size of
+ * the RCU grace period. So it needs to be upper-bound.
+ */
+#define HUNG_TASK_BATCHING 1024
+
+/*
+ * Zero means infinite timeout - no checking done:
+ */
+unsigned long __read_mostly sysctl_hung_task_timeout_secs = 120;
+
+unsigned long __read_mostly sysctl_hung_task_warnings = 10;
+
+static int __read_mostly did_panic;
+
+static struct task_struct *watchdog_task;
+
+/*
+ * Should we panic (and reboot, if panic_timeout= is set) when a
+ * hung task is detected:
+ */
+unsigned int __read_mostly sysctl_hung_task_panic =
+ CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE;
+
+static int __init hung_task_panic_setup(char *str)
+{
+ sysctl_hung_task_panic = simple_strtoul(str, NULL, 0);
+
+ return 1;
+}
+__setup("hung_task_panic=", hung_task_panic_setup);
+
+static int
+hung_task_panic(struct notifier_block *this, unsigned long event, void *ptr)
+{
+ did_panic = 1;
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+ .notifier_call = hung_task_panic,
+};
+
+static void check_hung_task(struct task_struct *t, unsigned long timeout)
+{
+ unsigned long switch_count = t->nvcsw + t->nivcsw;
+
+ /*
+ * Ensure the task is not frozen.
+ * Also, when a freshly created task is scheduled once, changes
+ * its state to TASK_UNINTERRUPTIBLE without having ever been
+ * switched out once, it musn't be checked.
+ */
+ if (unlikely(t->flags & PF_FROZEN || !switch_count))
+ return;
+
+ if (switch_count != t->last_switch_count) {
+ t->last_switch_count = switch_count;
+ return;
+ }
+ if (!sysctl_hung_task_warnings)
+ return;
+ sysctl_hung_task_warnings--;
+
+ /*
+ * Ok, the task did not get scheduled for more than 2 minutes,
+ * complain:
+ */
+ printk(KERN_ERR "INFO: task %s:%d blocked for more than "
+ "%ld seconds.\n", t->comm, t->pid, timeout);
+ printk(KERN_ERR "\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\""
+ " disables this message.\n");
+ sched_show_task(t);
+ __debug_show_held_locks(t);
+
+ touch_nmi_watchdog();
+
+ if (sysctl_hung_task_panic)
+ panic("hung_task: blocked tasks");
+}
+
+/*
+ * To avoid extending the RCU grace period for an unbounded amount of time,
+ * periodically exit the critical section and enter a new one.
+ *
+ * For preemptible RCU it is sufficient to call rcu_read_unlock in order
+ * exit the grace period. For classic RCU, a reschedule is required.
+ */
+static void rcu_lock_break(struct task_struct *g, struct task_struct *t)
+{
+ get_task_struct(g);
+ get_task_struct(t);
+ rcu_read_unlock();
+ cond_resched();
+ rcu_read_lock();
+ put_task_struct(t);
+ put_task_struct(g);
+}
+
+/*
+ * Check whether a TASK_UNINTERRUPTIBLE does not get woken up for
+ * a really long time (120 seconds). If that happens, print out
+ * a warning.
+ */
+static void check_hung_uninterruptible_tasks(unsigned long timeout)
+{
+ int max_count = sysctl_hung_task_check_count;
+ int batch_count = HUNG_TASK_BATCHING;
+ struct task_struct *g, *t;
+
+ /*
+ * If the system crashed already then all bets are off,
+ * do not report extra hung tasks:
+ */
+ if (test_taint(TAINT_DIE) || did_panic)
+ return;
+
+ rcu_read_lock();
+ do_each_thread(g, t) {
+ if (!--max_count)
+ goto unlock;
+ if (!--batch_count) {
+ batch_count = HUNG_TASK_BATCHING;
+ rcu_lock_break(g, t);
+ /* Exit if t or g was unhashed during refresh. */
+ if (t->state == TASK_DEAD || g->state == TASK_DEAD)
+ goto unlock;
+ }
+ /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */
+ if (t->state == TASK_UNINTERRUPTIBLE)
+ check_hung_task(t, timeout);
+ } while_each_thread(g, t);
+ unlock:
+ rcu_read_unlock();
+}
+
+static unsigned long timeout_jiffies(unsigned long timeout)
+{
+ /* timeout of 0 will disable the watchdog */
+ return timeout ? timeout * HZ : MAX_SCHEDULE_TIMEOUT;
+}
+
+/*
+ * Process updating of timeout sysctl
+ */
+int proc_dohung_task_timeout_secs(struct ctl_table *table, int write,
+ struct file *filp, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
+{
+ int ret;
+
+ ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos);
+
+ if (ret || !write)
+ goto out;
+
+ wake_up_process(watchdog_task);
+
+ out:
+ return ret;
+}
+
+/*
+ * kthread which checks for tasks stuck in D state
+ */
+static int watchdog(void *dummy)
+{
+ set_user_nice(current, 0);
+
+ for ( ; ; ) {
+ unsigned long timeout = sysctl_hung_task_timeout_secs;
+
+ while (schedule_timeout_interruptible(timeout_jiffies(timeout)))
+ timeout = sysctl_hung_task_timeout_secs;
+
+ check_hung_uninterruptible_tasks(timeout);
+ }
+
+ return 0;
+}
+
+static int __init hung_task_init(void)
+{
+ atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
+ watchdog_task = kthread_run(watchdog, NULL, "khungtaskd");
+
+ return 0;
+}
+
+module_init(hung_task_init);
diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
index 38a25b8d8bf..d06df9c41cb 100644
--- a/kernel/irq/devres.c
+++ b/kernel/irq/devres.c
@@ -26,10 +26,12 @@ static int devm_irq_match(struct device *dev, void *res, void *data)
}
/**
- * devm_request_irq - allocate an interrupt line for a managed device
+ * devm_request_threaded_irq - allocate an interrupt line for a managed device
* @dev: device to request interrupt for
* @irq: Interrupt line to allocate
* @handler: Function to be called when the IRQ occurs
+ * @thread_fn: function to be called in a threaded interrupt context. NULL
+ * for devices which handle everything in @handler
* @irqflags: Interrupt type flags
* @devname: An ascii name for the claiming device
* @dev_id: A cookie passed back to the handler function
@@ -42,9 +44,10 @@ static int devm_irq_match(struct device *dev, void *res, void *data)
* If an IRQ allocated with this function needs to be freed
* separately, dev_free_irq() must be used.
*/
-int devm_request_irq(struct device *dev, unsigned int irq,
- irq_handler_t handler, unsigned long irqflags,
- const char *devname, void *dev_id)
+int devm_request_threaded_irq(struct device *dev, unsigned int irq,
+ irq_handler_t handler, irq_handler_t thread_fn,
+ unsigned long irqflags, const char *devname,
+ void *dev_id)
{
struct irq_devres *dr;
int rc;
@@ -54,7 +57,8 @@ int devm_request_irq(struct device *dev, unsigned int irq,
if (!dr)
return -ENOMEM;
- rc = request_irq(irq, handler, irqflags, devname, dev_id);
+ rc = request_threaded_irq(irq, handler, thread_fn, irqflags, devname,
+ dev_id);
if (rc) {
devres_free(dr);
return rc;
@@ -66,7 +70,7 @@ int devm_request_irq(struct device *dev, unsigned int irq,
return 0;
}
-EXPORT_SYMBOL(devm_request_irq);
+EXPORT_SYMBOL(devm_request_threaded_irq);
/**
* devm_free_irq - free an interrupt
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 9ebf7796887..d82142be8dd 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -17,6 +17,7 @@
#include <linux/kernel_stat.h>
#include <linux/rculist.h>
#include <linux/hash.h>
+#include <trace/irq.h>
#include <linux/bootmem.h>
#include "internals.h"
@@ -338,6 +339,18 @@ irqreturn_t no_action(int cpl, void *dev_id)
return IRQ_NONE;
}
+static void warn_no_thread(unsigned int irq, struct irqaction *action)
+{
+ if (test_and_set_bit(IRQTF_WARNED, &action->thread_flags))
+ return;
+
+ printk(KERN_WARNING "IRQ %d device %s returned IRQ_WAKE_THREAD "
+ "but no thread function available.", irq, action->name);
+}
+
+DEFINE_TRACE(irq_handler_entry);
+DEFINE_TRACE(irq_handler_exit);
+
/**
* handle_IRQ_event - irq action chain handler
* @irq: the interrupt number
@@ -356,9 +369,50 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
local_irq_enable_in_hardirq();
do {
+ trace_irq_handler_entry(irq, action);
ret = action->handler(irq, action->dev_id);
- if (ret == IRQ_HANDLED)
+ trace_irq_handler_exit(irq, action, ret);
+
+ switch (ret) {
+ case IRQ_WAKE_THREAD:
+ /*
+ * Set result to handled so the spurious check
+ * does not trigger.
+ */
+ ret = IRQ_HANDLED;
+
+ /*
+ * Catch drivers which return WAKE_THREAD but
+ * did not set up a thread function
+ */
+ if (unlikely(!action->thread_fn)) {
+ warn_no_thread(irq, action);
+ break;
+ }
+
+ /*
+ * Wake up the handler thread for this
+ * action. In case the thread crashed and was
+ * killed we just pretend that we handled the
+ * interrupt. The hardirq handler above has
+ * disabled the device interrupt, so no irq
+ * storm is lurking.
+ */
+ if (likely(!test_bit(IRQTF_DIED,
+ &action->thread_flags))) {
+ set_bit(IRQTF_RUNTHREAD, &action->thread_flags);
+ wake_up_process(action->thread);
+ }
+
+ /* Fall through to add to randomness */
+ case IRQ_HANDLED:
status |= action->flags;
+ break;
+
+ default:
+ break;
+ }
+
retval |= ret;
action = action->next;
} while (action);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 1516ab77355..7e2e7dd4cd2 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -8,16 +8,15 @@
*/
#include <linux/irq.h>
+#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
+#include <linux/sched.h>
#include "internals.h"
-#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
-cpumask_var_t irq_default_affinity;
-
/**
* synchronize_irq - wait for pending IRQ handlers (on other CPUs)
* @irq: interrupt number to wait for
@@ -53,9 +52,18 @@ void synchronize_irq(unsigned int irq)
/* Oops, that failed? */
} while (status & IRQ_INPROGRESS);
+
+ /*
+ * We made sure that no hardirq handler is running. Now verify
+ * that no threaded handlers are active.
+ */
+ wait_event(desc->wait_for_threads, !atomic_read(&desc->threads_active));
}
EXPORT_SYMBOL(synchronize_irq);
+#ifdef CONFIG_SMP
+cpumask_var_t irq_default_affinity;
+
/**
* irq_can_set_affinity - Check if the affinity of a given irq can be set
* @irq: Interrupt to check
@@ -72,6 +80,18 @@ int irq_can_set_affinity(unsigned int irq)
return 1;
}
+static void
+irq_set_thread_affinity(struct irq_desc *desc, const struct cpumask *cpumask)
+{
+ struct irqaction *action = desc->action;
+
+ while (action) {
+ if (action->thread)
+ set_cpus_allowed_ptr(action->thread, cpumask);
+ action = action->next;
+ }
+}
+
/**
* irq_set_affinity - Set the irq affinity of a given irq
* @irq: Interrupt to set affinity
@@ -100,6 +120,7 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
cpumask_copy(desc->affinity, cpumask);
desc->chip->set_affinity(irq, cpumask);
#endif
+ irq_set_thread_affinity(desc, cpumask);
desc->status |= IRQ_AFFINITY_SET;
spin_unlock_irqrestore(&desc->lock, flags);
return 0;
@@ -150,6 +171,8 @@ int irq_select_affinity_usr(unsigned int irq)
spin_lock_irqsave(&desc->lock, flags);
ret = setup_affinity(irq, desc);
+ if (!ret)
+ irq_set_thread_affinity(desc, desc->affinity);
spin_unlock_irqrestore(&desc->lock, flags);
return ret;
@@ -401,6 +424,90 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
return ret;
}
+static int irq_wait_for_interrupt(struct irqaction *action)
+{
+ while (!kthread_should_stop()) {
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ if (test_and_clear_bit(IRQTF_RUNTHREAD,
+ &action->thread_flags)) {
+ __set_current_state(TASK_RUNNING);
+ return 0;
+ }
+ schedule();
+ }
+ return -1;
+}
+
+/*
+ * Interrupt handler thread
+ */
+static int irq_thread(void *data)
+{
+ struct sched_param param = { .sched_priority = MAX_USER_RT_PRIO/2, };
+ struct irqaction *action = data;
+ struct irq_desc *desc = irq_to_desc(action->irq);
+ int wake;
+
+ sched_setscheduler(current, SCHED_FIFO, &param);
+ current->irqaction = action;
+
+ while (!irq_wait_for_interrupt(action)) {
+
+ atomic_inc(&desc->threads_active);
+
+ spin_lock_irq(&desc->lock);
+ if (unlikely(desc->status & IRQ_DISABLED)) {
+ /*
+ * CHECKME: We might need a dedicated
+ * IRQ_THREAD_PENDING flag here, which
+ * retriggers the thread in check_irq_resend()
+ * but AFAICT IRQ_PENDING should be fine as it
+ * retriggers the interrupt itself --- tglx
+ */
+ desc->status |= IRQ_PENDING;
+ spin_unlock_irq(&desc->lock);
+ } else {
+ spin_unlock_irq(&desc->lock);
+
+ action->thread_fn(action->irq, action->dev_id);
+ }
+
+ wake = atomic_dec_and_test(&desc->threads_active);
+
+ if (wake && waitqueue_active(&desc->wait_for_threads))
+ wake_up(&desc->wait_for_threads);
+ }
+
+ /*
+ * Clear irqaction. Otherwise exit_irq_thread() would make
+ * fuzz about an active irq thread going into nirvana.
+ */
+ current->irqaction = NULL;
+ return 0;
+}
+
+/*
+ * Called from do_exit()
+ */
+void exit_irq_thread(void)
+{
+ struct task_struct *tsk = current;
+
+ if (!tsk->irqaction)
+ return;
+
+ printk(KERN_ERR
+ "exiting task \"%s\" (%d) is an active IRQ thread (irq %d)\n",
+ tsk->comm ? tsk->comm : "", tsk->pid, tsk->irqaction->irq);
+
+ /*
+ * Set the THREAD DIED flag to prevent further wakeups of the
+ * soon to be gone threaded handler.
+ */
+ set_bit(IRQTF_DIED, &tsk->irqaction->flags);
+}
+
/*
* Internal function to register an irqaction - typically used to
* allocate special interrupts that are part of the architecture.
@@ -437,6 +544,26 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
}
/*
+ * Threaded handler ?
+ */
+ if (new->thread_fn) {
+ struct task_struct *t;
+
+ t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
+ new->name);
+ if (IS_ERR(t))
+ return PTR_ERR(t);
+ /*
+ * We keep the reference to the task struct even if
+ * the thread dies to avoid that the interrupt code
+ * references an already freed task_struct.
+ */
+ get_task_struct(t);
+ new->thread = t;
+ wake_up_process(t);
+ }
+
+ /*
* The following block of code has to be executed atomically
*/
spin_lock_irqsave(&desc->lock, flags);
@@ -473,15 +600,15 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
if (!shared) {
irq_chip_set_defaults(desc->chip);
+ init_waitqueue_head(&desc->wait_for_threads);
+
/* Setup the type (level, edge polarity) if configured: */
if (new->flags & IRQF_TRIGGER_MASK) {
ret = __irq_set_trigger(desc, irq,
new->flags & IRQF_TRIGGER_MASK);
- if (ret) {
- spin_unlock_irqrestore(&desc->lock, flags);
- return ret;
- }
+ if (ret)
+ goto out_thread;
} else
compat_irq_chip_set_default_handler(desc);
#if defined(CONFIG_IRQ_PER_CPU)
@@ -549,8 +676,19 @@ mismatch:
dump_stack();
}
#endif
+ ret = -EBUSY;
+
+out_thread:
spin_unlock_irqrestore(&desc->lock, flags);
- return -EBUSY;
+ if (new->thread) {
+ struct task_struct *t = new->thread;
+
+ new->thread = NULL;
+ if (likely(!test_bit(IRQTF_DIED, &new->thread_flags)))
+ kthread_stop(t);
+ put_task_struct(t);
+ }
+ return ret;
}
/**
@@ -576,6 +714,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
{
struct irq_desc *desc = irq_to_desc(irq);
struct irqaction *action, **action_ptr;
+ struct task_struct *irqthread;
unsigned long flags;
WARN(in_interrupt(), "Trying to free IRQ %d from IRQ context!\n", irq);
@@ -622,6 +761,10 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
else
desc->chip->disable(irq);
}
+
+ irqthread = action->thread;
+ action->thread = NULL;
+
spin_unlock_irqrestore(&desc->lock, flags);
unregister_handler_proc(irq, action);
@@ -629,6 +772,12 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
/* Make sure it's not being used on another CPU: */
synchronize_irq(irq);
+ if (irqthread) {
+ if (!test_bit(IRQTF_DIED, &action->thread_flags))
+ kthread_stop(irqthread);
+ put_task_struct(irqthread);
+ }
+
#ifdef CONFIG_DEBUG_SHIRQ
/*
* It's a shared IRQ -- the driver ought to be prepared for an IRQ
@@ -681,9 +830,12 @@ void free_irq(unsigned int irq, void *dev_id)
EXPORT_SYMBOL(free_irq);
/**
- * request_irq - allocate an interrupt line
+ * request_threaded_irq - allocate an interrupt line
* @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs
+ * @handler: Function to be called when the IRQ occurs.
+ * Primary handler for threaded interrupts
+ * @thread_fn: Function called from the irq handler thread
+ * If NULL, no irq thread is created
* @irqflags: Interrupt type flags
* @devname: An ascii name for the claiming device
* @dev_id: A cookie passed back to the handler function
@@ -695,6 +847,15 @@ EXPORT_SYMBOL(free_irq);
* raises, you must take care both to initialise your hardware
* and to set up the interrupt handler in the right order.
*
+ * If you want to set up a threaded irq handler for your device
+ * then you need to supply @handler and @thread_fn. @handler ist
+ * still called in hard interrupt context and has to check
+ * whether the interrupt originates from the device. If yes it
+ * needs to disable the interrupt on the device and return
+ * IRQ_THREAD_WAKE which will wake up the handler thread and run
+ * @thread_fn. This split handler design is necessary to support
+ * shared interrupts.
+ *
* Dev_id must be globally unique. Normally the address of the
* device data structure is used as the cookie. Since the handler
* receives this value it makes sense to use it.
@@ -710,8 +871,9 @@ EXPORT_SYMBOL(free_irq);
* 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)
+int request_threaded_irq(unsigned int irq, irq_handler_t handler,
+ irq_handler_t thread_fn, unsigned long irqflags,
+ const char *devname, void *dev_id)
{
struct irqaction *action;
struct irq_desc *desc;
@@ -759,6 +921,7 @@ int request_irq(unsigned int irq, irq_handler_t handler,
return -ENOMEM;
action->handler = handler;
+ action->thread_fn = thread_fn;
action->flags = irqflags;
action->name = devname;
action->dev_id = dev_id;
@@ -788,4 +951,4 @@ int request_irq(unsigned int irq, irq_handler_t handler,
#endif
return retval;
}
-EXPORT_SYMBOL(request_irq);
+EXPORT_SYMBOL(request_threaded_irq);
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c
index 243d6121e50..44bbdcbaf8d 100644
--- a/kernel/irq/numa_migrate.c
+++ b/kernel/irq/numa_migrate.c
@@ -54,6 +54,7 @@ static bool init_copy_one_irq_desc(int irq, struct irq_desc *old_desc,
static void free_one_irq_desc(struct irq_desc *old_desc, struct irq_desc *desc)
{
free_kstat_irqs(old_desc, desc);
+ free_desc_masks(old_desc, desc);
arch_free_chip_data(old_desc, desc);
}
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 7b8b0f21a5b..374faf9bfdc 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -161,6 +161,25 @@ unsigned long kallsyms_lookup_name(const char *name)
return module_kallsyms_lookup_name(name);
}
+int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
+ unsigned long),
+ void *data)
+{
+ char namebuf[KSYM_NAME_LEN];
+ unsigned long i;
+ unsigned int off;
+ int ret;
+
+ for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
+ off = kallsyms_expand_symbol(off, namebuf);
+ ret = fn(data, namebuf, NULL, kallsyms_addresses[i]);
+ if (ret != 0)
+ return ret;
+ }
+ return module_kallsyms_on_each_symbol(fn, data);
+}
+EXPORT_SYMBOL_GPL(kallsyms_on_each_symbol);
+
static unsigned long get_symbol_pos(unsigned long addr,
unsigned long *symbolsize,
unsigned long *offset)
diff --git a/kernel/kmod.c b/kernel/kmod.c
index f0c8f545180..b750675251e 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -50,7 +50,8 @@ static struct workqueue_struct *khelper_wq;
char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
/**
- * request_module - try to load a kernel module
+ * __request_module - try to load a kernel module
+ * @wait: wait (or not) for the operation to complete
* @fmt: printf style format string for the name of the module
* @...: arguments as specified in the format string
*
@@ -63,7 +64,7 @@ char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
* If module auto-loading support is disabled then this function
* becomes a no-operation.
*/
-int request_module(const char *fmt, ...)
+int __request_module(bool wait, const char *fmt, ...)
{
va_list args;
char module_name[MODULE_NAME_LEN];
@@ -108,11 +109,12 @@ int request_module(const char *fmt, ...)
return -ENOMEM;
}
- ret = call_usermodehelper(modprobe_path, argv, envp, 1);
+ ret = call_usermodehelper(modprobe_path, argv, envp,
+ wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC);
atomic_dec(&kmod_concurrent);
return ret;
}
-EXPORT_SYMBOL(request_module);
+EXPORT_SYMBOL(__request_module);
#endif /* CONFIG_MODULES */
struct subprocess_info {
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 7ba8cd9845c..a5e74ddee0e 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -43,6 +43,7 @@
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <linux/kdebug.h>
+#include <linux/memory.h>
#include <asm-generic/sections.h>
#include <asm/cacheflush.h>
@@ -67,7 +68,7 @@ static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
/* NOTE: change this value only with kprobe_mutex held */
-static bool kprobe_enabled;
+static bool kprobes_all_disarmed;
static DEFINE_MUTEX(kprobe_mutex); /* Protects kprobe_table */
static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
@@ -327,7 +328,7 @@ static int __kprobes aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
struct kprobe *kp;
list_for_each_entry_rcu(kp, &p->list, list) {
- if (kp->pre_handler && !kprobe_gone(kp)) {
+ if (kp->pre_handler && likely(!kprobe_disabled(kp))) {
set_kprobe_instance(kp);
if (kp->pre_handler(kp, regs))
return 1;
@@ -343,7 +344,7 @@ static void __kprobes aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
struct kprobe *kp;
list_for_each_entry_rcu(kp, &p->list, list) {
- if (kp->post_handler && !kprobe_gone(kp)) {
+ if (kp->post_handler && likely(!kprobe_disabled(kp))) {
set_kprobe_instance(kp);
kp->post_handler(kp, regs, flags);
reset_kprobe_instance();
@@ -517,20 +518,28 @@ static inline void copy_kprobe(struct kprobe *old_p, struct kprobe *p)
}
/*
-* Add the new probe to old_p->list. Fail if this is the
+* Add the new probe to ap->list. Fail if this is the
* second jprobe at the address - two jprobes can't coexist
*/
-static int __kprobes add_new_kprobe(struct kprobe *old_p, struct kprobe *p)
+static int __kprobes add_new_kprobe(struct kprobe *ap, struct kprobe *p)
{
+ BUG_ON(kprobe_gone(ap) || kprobe_gone(p));
if (p->break_handler) {
- if (old_p->break_handler)
+ if (ap->break_handler)
return -EEXIST;
- list_add_tail_rcu(&p->list, &old_p->list);
- old_p->break_handler = aggr_break_handler;
+ list_add_tail_rcu(&p->list, &ap->list);
+ ap->break_handler = aggr_break_handler;
} else
- list_add_rcu(&p->list, &old_p->list);
- if (p->post_handler && !old_p->post_handler)
- old_p->post_handler = aggr_post_handler;
+ list_add_rcu(&p->list, &ap->list);
+ if (p->post_handler && !ap->post_handler)
+ ap->post_handler = aggr_post_handler;
+
+ if (kprobe_disabled(ap) && !kprobe_disabled(p)) {
+ ap->flags &= ~KPROBE_FLAG_DISABLED;
+ if (!kprobes_all_disarmed)
+ /* Arm the breakpoint again. */
+ arch_arm_kprobe(ap);
+ }
return 0;
}
@@ -543,6 +552,7 @@ static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
copy_kprobe(p, ap);
flush_insn_slot(ap);
ap->addr = p->addr;
+ ap->flags = p->flags;
ap->pre_handler = aggr_pre_handler;
ap->fault_handler = aggr_fault_handler;
/* We don't care the kprobe which has gone. */
@@ -565,44 +575,59 @@ static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
struct kprobe *p)
{
int ret = 0;
- struct kprobe *ap;
+ struct kprobe *ap = old_p;
- if (kprobe_gone(old_p)) {
+ if (old_p->pre_handler != aggr_pre_handler) {
+ /* If old_p is not an aggr_probe, create new aggr_kprobe. */
+ ap = kzalloc(sizeof(struct kprobe), GFP_KERNEL);
+ if (!ap)
+ return -ENOMEM;
+ add_aggr_kprobe(ap, old_p);
+ }
+
+ if (kprobe_gone(ap)) {
/*
* Attempting to insert new probe at the same location that
* had a probe in the module vaddr area which already
* freed. So, the instruction slot has already been
* released. We need a new slot for the new probe.
*/
- ret = arch_prepare_kprobe(old_p);
+ ret = arch_prepare_kprobe(ap);
if (ret)
+ /*
+ * Even if fail to allocate new slot, don't need to
+ * free aggr_probe. It will be used next time, or
+ * freed by unregister_kprobe.
+ */
return ret;
- }
- if (old_p->pre_handler == aggr_pre_handler) {
- copy_kprobe(old_p, p);
- ret = add_new_kprobe(old_p, p);
- ap = old_p;
- } else {
- ap = kzalloc(sizeof(struct kprobe), GFP_KERNEL);
- if (!ap) {
- if (kprobe_gone(old_p))
- arch_remove_kprobe(old_p);
- return -ENOMEM;
- }
- add_aggr_kprobe(ap, old_p);
- copy_kprobe(ap, p);
- ret = add_new_kprobe(ap, p);
- }
- if (kprobe_gone(old_p)) {
+
/*
- * If the old_p has gone, its breakpoint has been disarmed.
- * We have to arm it again after preparing real kprobes.
+ * Clear gone flag to prevent allocating new slot again, and
+ * set disabled flag because it is not armed yet.
*/
- ap->flags &= ~KPROBE_FLAG_GONE;
- if (kprobe_enabled)
- arch_arm_kprobe(ap);
+ ap->flags = (ap->flags & ~KPROBE_FLAG_GONE)
+ | KPROBE_FLAG_DISABLED;
}
- return ret;
+
+ copy_kprobe(ap, p);
+ return add_new_kprobe(ap, p);
+}
+
+/* Try to disable aggr_kprobe, and return 1 if succeeded.*/
+static int __kprobes try_to_disable_aggr_kprobe(struct kprobe *p)
+{
+ struct kprobe *kp;
+
+ list_for_each_entry_rcu(kp, &p->list, list) {
+ if (!kprobe_disabled(kp))
+ /*
+ * There is an active probe on the list.
+ * We can't disable aggr_kprobe.
+ */
+ return 0;
+ }
+ p->flags |= KPROBE_FLAG_DISABLED;
+ return 1;
}
static int __kprobes in_kprobes_functions(unsigned long addr)
@@ -663,7 +688,9 @@ int __kprobes register_kprobe(struct kprobe *p)
return -EINVAL;
}
- p->flags = 0;
+ /* User can pass only KPROBE_FLAG_DISABLED to register_kprobe */
+ p->flags &= KPROBE_FLAG_DISABLED;
+
/*
* Check if are we probing a module.
*/
@@ -699,17 +726,20 @@ int __kprobes register_kprobe(struct kprobe *p)
goto out;
}
+ mutex_lock(&text_mutex);
ret = arch_prepare_kprobe(p);
if (ret)
- goto out;
+ goto out_unlock_text;
INIT_HLIST_NODE(&p->hlist);
hlist_add_head_rcu(&p->hlist,
&kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
- if (kprobe_enabled)
+ if (!kprobes_all_disarmed && !kprobe_disabled(p))
arch_arm_kprobe(p);
+out_unlock_text:
+ mutex_unlock(&text_mutex);
out:
mutex_unlock(&kprobe_mutex);
@@ -718,26 +748,39 @@ out:
return ret;
}
+EXPORT_SYMBOL_GPL(register_kprobe);
-/*
- * Unregister a kprobe without a scheduler synchronization.
- */
-static int __kprobes __unregister_kprobe_top(struct kprobe *p)
+/* Check passed kprobe is valid and return kprobe in kprobe_table. */
+static struct kprobe * __kprobes __get_valid_kprobe(struct kprobe *p)
{
struct kprobe *old_p, *list_p;
old_p = get_kprobe(p->addr);
if (unlikely(!old_p))
- return -EINVAL;
+ return NULL;
if (p != old_p) {
list_for_each_entry_rcu(list_p, &old_p->list, list)
if (list_p == p)
/* kprobe p is a valid probe */
- goto valid_p;
- return -EINVAL;
+ goto valid;
+ return NULL;
}
-valid_p:
+valid:
+ return old_p;
+}
+
+/*
+ * Unregister a kprobe without a scheduler synchronization.
+ */
+static int __kprobes __unregister_kprobe_top(struct kprobe *p)
+{
+ struct kprobe *old_p, *list_p;
+
+ old_p = __get_valid_kprobe(p);
+ if (old_p == NULL)
+ return -EINVAL;
+
if (old_p == p ||
(old_p->pre_handler == aggr_pre_handler &&
list_is_singular(&old_p->list))) {
@@ -746,8 +789,11 @@ valid_p:
* enabled and not gone - otherwise, the breakpoint would
* already have been removed. We save on flushing icache.
*/
- if (kprobe_enabled && !kprobe_gone(old_p))
+ if (!kprobes_all_disarmed && !kprobe_disabled(old_p)) {
+ mutex_lock(&text_mutex);
arch_disarm_kprobe(p);
+ mutex_unlock(&text_mutex);
+ }
hlist_del_rcu(&old_p->hlist);
} else {
if (p->break_handler && !kprobe_gone(p))
@@ -761,6 +807,11 @@ valid_p:
}
noclean:
list_del_rcu(&p->list);
+ if (!kprobe_disabled(old_p)) {
+ try_to_disable_aggr_kprobe(old_p);
+ if (!kprobes_all_disarmed && kprobe_disabled(old_p))
+ arch_disarm_kprobe(old_p);
+ }
}
return 0;
}
@@ -796,11 +847,13 @@ int __kprobes register_kprobes(struct kprobe **kps, int num)
}
return ret;
}
+EXPORT_SYMBOL_GPL(register_kprobes);
void __kprobes unregister_kprobe(struct kprobe *p)
{
unregister_kprobes(&p, 1);
}
+EXPORT_SYMBOL_GPL(unregister_kprobe);
void __kprobes unregister_kprobes(struct kprobe **kps, int num)
{
@@ -819,6 +872,7 @@ void __kprobes unregister_kprobes(struct kprobe **kps, int num)
if (kps[i]->addr)
__unregister_kprobe_bottom(kps[i]);
}
+EXPORT_SYMBOL_GPL(unregister_kprobes);
static struct notifier_block kprobe_exceptions_nb = {
.notifier_call = kprobe_exceptions_notify,
@@ -858,16 +912,19 @@ int __kprobes register_jprobes(struct jprobe **jps, int num)
}
return ret;
}
+EXPORT_SYMBOL_GPL(register_jprobes);
int __kprobes register_jprobe(struct jprobe *jp)
{
return register_jprobes(&jp, 1);
}
+EXPORT_SYMBOL_GPL(register_jprobe);
void __kprobes unregister_jprobe(struct jprobe *jp)
{
unregister_jprobes(&jp, 1);
}
+EXPORT_SYMBOL_GPL(unregister_jprobe);
void __kprobes unregister_jprobes(struct jprobe **jps, int num)
{
@@ -887,6 +944,7 @@ void __kprobes unregister_jprobes(struct jprobe **jps, int num)
__unregister_kprobe_bottom(&jps[i]->kp);
}
}
+EXPORT_SYMBOL_GPL(unregister_jprobes);
#ifdef CONFIG_KRETPROBES
/*
@@ -912,10 +970,8 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p,
ri->rp = rp;
ri->task = current;
- if (rp->entry_handler && rp->entry_handler(ri, regs)) {
- spin_unlock_irqrestore(&rp->lock, flags);
+ if (rp->entry_handler && rp->entry_handler(ri, regs))
return 0;
- }
arch_prepare_kretprobe(ri, regs);
@@ -982,6 +1038,7 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
free_rp_inst(rp);
return ret;
}
+EXPORT_SYMBOL_GPL(register_kretprobe);
int __kprobes register_kretprobes(struct kretprobe **rps, int num)
{
@@ -999,11 +1056,13 @@ int __kprobes register_kretprobes(struct kretprobe **rps, int num)
}
return ret;
}
+EXPORT_SYMBOL_GPL(register_kretprobes);
void __kprobes unregister_kretprobe(struct kretprobe *rp)
{
unregister_kretprobes(&rp, 1);
}
+EXPORT_SYMBOL_GPL(unregister_kretprobe);
void __kprobes unregister_kretprobes(struct kretprobe **rps, int num)
{
@@ -1025,24 +1084,30 @@ void __kprobes unregister_kretprobes(struct kretprobe **rps, int num)
}
}
}
+EXPORT_SYMBOL_GPL(unregister_kretprobes);
#else /* CONFIG_KRETPROBES */
int __kprobes register_kretprobe(struct kretprobe *rp)
{
return -ENOSYS;
}
+EXPORT_SYMBOL_GPL(register_kretprobe);
int __kprobes register_kretprobes(struct kretprobe **rps, int num)
{
return -ENOSYS;
}
+EXPORT_SYMBOL_GPL(register_kretprobes);
+
void __kprobes unregister_kretprobe(struct kretprobe *rp)
{
}
+EXPORT_SYMBOL_GPL(unregister_kretprobe);
void __kprobes unregister_kretprobes(struct kretprobe **rps, int num)
{
}
+EXPORT_SYMBOL_GPL(unregister_kretprobes);
static int __kprobes pre_handler_kretprobe(struct kprobe *p,
struct pt_regs *regs)
@@ -1056,6 +1121,7 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p,
static void __kprobes kill_kprobe(struct kprobe *p)
{
struct kprobe *kp;
+
p->flags |= KPROBE_FLAG_GONE;
if (p->pre_handler == aggr_pre_handler) {
/*
@@ -1168,8 +1234,8 @@ static int __init init_kprobes(void)
}
}
- /* By default, kprobes are enabled */
- kprobe_enabled = true;
+ /* By default, kprobes are armed */
+ kprobes_all_disarmed = false;
err = arch_init_kprobes();
if (!err)
@@ -1197,12 +1263,18 @@ static void __kprobes report_probe(struct seq_file *pi, struct kprobe *p,
else
kprobe_type = "k";
if (sym)
- seq_printf(pi, "%p %s %s+0x%x %s %s\n", p->addr, kprobe_type,
- sym, offset, (modname ? modname : " "),
- (kprobe_gone(p) ? "[GONE]" : ""));
+ seq_printf(pi, "%p %s %s+0x%x %s %s%s\n",
+ p->addr, kprobe_type, sym, offset,
+ (modname ? modname : " "),
+ (kprobe_gone(p) ? "[GONE]" : ""),
+ ((kprobe_disabled(p) && !kprobe_gone(p)) ?
+ "[DISABLED]" : ""));
else
- seq_printf(pi, "%p %s %p %s\n", p->addr, kprobe_type, p->addr,
- (kprobe_gone(p) ? "[GONE]" : ""));
+ seq_printf(pi, "%p %s %p %s%s\n",
+ p->addr, kprobe_type, p->addr,
+ (kprobe_gone(p) ? "[GONE]" : ""),
+ ((kprobe_disabled(p) && !kprobe_gone(p)) ?
+ "[DISABLED]" : ""));
}
static void __kprobes *kprobe_seq_start(struct seq_file *f, loff_t *pos)
@@ -1267,7 +1339,72 @@ static struct file_operations debugfs_kprobes_operations = {
.release = seq_release,
};
-static void __kprobes enable_all_kprobes(void)
+/* Disable one kprobe */
+int __kprobes disable_kprobe(struct kprobe *kp)
+{
+ int ret = 0;
+ struct kprobe *p;
+
+ mutex_lock(&kprobe_mutex);
+
+ /* Check whether specified probe is valid. */
+ p = __get_valid_kprobe(kp);
+ if (unlikely(p == NULL)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* If the probe is already disabled (or gone), just return */
+ if (kprobe_disabled(kp))
+ goto out;
+
+ kp->flags |= KPROBE_FLAG_DISABLED;
+ if (p != kp)
+ /* When kp != p, p is always enabled. */
+ try_to_disable_aggr_kprobe(p);
+
+ if (!kprobes_all_disarmed && kprobe_disabled(p))
+ arch_disarm_kprobe(p);
+out:
+ mutex_unlock(&kprobe_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(disable_kprobe);
+
+/* Enable one kprobe */
+int __kprobes enable_kprobe(struct kprobe *kp)
+{
+ int ret = 0;
+ struct kprobe *p;
+
+ mutex_lock(&kprobe_mutex);
+
+ /* Check whether specified probe is valid. */
+ p = __get_valid_kprobe(kp);
+ if (unlikely(p == NULL)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (kprobe_gone(kp)) {
+ /* This kprobe has gone, we couldn't enable it. */
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (!kprobes_all_disarmed && kprobe_disabled(p))
+ arch_arm_kprobe(p);
+
+ p->flags &= ~KPROBE_FLAG_DISABLED;
+ if (p != kp)
+ kp->flags &= ~KPROBE_FLAG_DISABLED;
+out:
+ mutex_unlock(&kprobe_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(enable_kprobe);
+
+static void __kprobes arm_all_kprobes(void)
{
struct hlist_head *head;
struct hlist_node *node;
@@ -1276,18 +1413,20 @@ static void __kprobes enable_all_kprobes(void)
mutex_lock(&kprobe_mutex);
- /* If kprobes are already enabled, just return */
- if (kprobe_enabled)
+ /* If kprobes are armed, just return */
+ if (!kprobes_all_disarmed)
goto already_enabled;
+ mutex_lock(&text_mutex);
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
head = &kprobe_table[i];
hlist_for_each_entry_rcu(p, node, head, hlist)
- if (!kprobe_gone(p))
+ if (!kprobe_disabled(p))
arch_arm_kprobe(p);
}
+ mutex_unlock(&text_mutex);
- kprobe_enabled = true;
+ kprobes_all_disarmed = false;
printk(KERN_INFO "Kprobes globally enabled\n");
already_enabled:
@@ -1295,7 +1434,7 @@ already_enabled:
return;
}
-static void __kprobes disable_all_kprobes(void)
+static void __kprobes disarm_all_kprobes(void)
{
struct hlist_head *head;
struct hlist_node *node;
@@ -1304,20 +1443,22 @@ static void __kprobes disable_all_kprobes(void)
mutex_lock(&kprobe_mutex);
- /* If kprobes are already disabled, just return */
- if (!kprobe_enabled)
+ /* If kprobes are already disarmed, just return */
+ if (kprobes_all_disarmed)
goto already_disabled;
- kprobe_enabled = false;
+ kprobes_all_disarmed = true;
printk(KERN_INFO "Kprobes globally disabled\n");
+ mutex_lock(&text_mutex);
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
head = &kprobe_table[i];
hlist_for_each_entry_rcu(p, node, head, hlist) {
- if (!arch_trampoline_kprobe(p) && !kprobe_gone(p))
+ if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p))
arch_disarm_kprobe(p);
}
}
+ mutex_unlock(&text_mutex);
mutex_unlock(&kprobe_mutex);
/* Allow all currently running kprobes to complete */
synchronize_sched();
@@ -1338,7 +1479,7 @@ static ssize_t read_enabled_file_bool(struct file *file,
{
char buf[3];
- if (kprobe_enabled)
+ if (!kprobes_all_disarmed)
buf[0] = '1';
else
buf[0] = '0';
@@ -1361,12 +1502,12 @@ static ssize_t write_enabled_file_bool(struct file *file,
case 'y':
case 'Y':
case '1':
- enable_all_kprobes();
+ arm_all_kprobes();
break;
case 'n':
case 'N':
case '0':
- disable_all_kprobes();
+ disarm_all_kprobes();
break;
}
@@ -1409,16 +1550,5 @@ late_initcall(debugfs_kprobe_init);
module_init(init_kprobes);
-EXPORT_SYMBOL_GPL(register_kprobe);
-EXPORT_SYMBOL_GPL(unregister_kprobe);
-EXPORT_SYMBOL_GPL(register_kprobes);
-EXPORT_SYMBOL_GPL(unregister_kprobes);
-EXPORT_SYMBOL_GPL(register_jprobe);
-EXPORT_SYMBOL_GPL(unregister_jprobe);
-EXPORT_SYMBOL_GPL(register_jprobes);
-EXPORT_SYMBOL_GPL(unregister_jprobes);
+/* defined in arch/.../kernel/kprobes.c */
EXPORT_SYMBOL_GPL(jprobe_return);
-EXPORT_SYMBOL_GPL(register_kretprobe);
-EXPORT_SYMBOL_GPL(unregister_kretprobe);
-EXPORT_SYMBOL_GPL(register_kretprobes);
-EXPORT_SYMBOL_GPL(unregister_kretprobes);
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 84bbadd4d02..4ebaf8519ab 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -76,6 +76,7 @@ static int kthread(void *_create)
/* OK, tell user we're spawned, wait for stop or wakeup */
__set_current_state(TASK_UNINTERRUPTIBLE);
+ create->result = current;
complete(&create->started);
schedule();
@@ -96,22 +97,10 @@ static void create_kthread(struct kthread_create_info *create)
/* We want our own signal handler (we take no signals by default). */
pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
- if (pid < 0) {
+ if (pid < 0)
create->result = ERR_PTR(pid);
- } else {
- struct sched_param param = { .sched_priority = 0 };
+ else
wait_for_completion(&create->started);
- read_lock(&tasklist_lock);
- create->result = find_task_by_pid_ns(pid, &init_pid_ns);
- read_unlock(&tasklist_lock);
- /*
- * root may have changed our (kthreadd's) priority or CPU mask.
- * The kernel thread should not inherit these properties.
- */
- sched_setscheduler(create->result, SCHED_NORMAL, &param);
- set_user_nice(create->result, KTHREAD_NICE_LEVEL);
- set_cpus_allowed_ptr(create->result, cpu_all_mask);
- }
complete(&create->done);
}
@@ -154,11 +143,20 @@ struct task_struct *kthread_create(int (*threadfn)(void *data),
wait_for_completion(&create.done);
if (!IS_ERR(create.result)) {
+ struct sched_param param = { .sched_priority = 0 };
va_list args;
+
va_start(args, namefmt);
vsnprintf(create.result->comm, sizeof(create.result->comm),
namefmt, args);
va_end(args);
+ /*
+ * root may have changed our (kthreadd's) priority or CPU mask.
+ * The kernel thread should not inherit these properties.
+ */
+ sched_setscheduler_nocheck(create.result, SCHED_NORMAL, &param);
+ set_user_nice(create.result, KTHREAD_NICE_LEVEL);
+ set_cpus_allowed_ptr(create.result, cpu_all_mask);
}
return create.result;
}
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 3673a3f44d9..b0f01186696 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -42,6 +42,7 @@
#include <linux/hash.h>
#include <linux/ftrace.h>
#include <linux/stringify.h>
+#include <trace/lockdep.h>
#include <asm/sections.h>
@@ -433,13 +434,6 @@ atomic_t nr_find_usage_forwards_checks;
atomic_t nr_find_usage_forwards_recursions;
atomic_t nr_find_usage_backwards_checks;
atomic_t nr_find_usage_backwards_recursions;
-# define debug_atomic_inc(ptr) atomic_inc(ptr)
-# define debug_atomic_dec(ptr) atomic_dec(ptr)
-# define debug_atomic_read(ptr) atomic_read(ptr)
-#else
-# define debug_atomic_inc(ptr) do { } while (0)
-# define debug_atomic_dec(ptr) do { } while (0)
-# define debug_atomic_read(ptr) 0
#endif
/*
@@ -799,6 +793,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
printk("BUG: MAX_LOCKDEP_KEYS too low!\n");
printk("turning off the locking correctness validator.\n");
+ dump_stack();
return NULL;
}
class = lock_classes + nr_lock_classes++;
@@ -862,6 +857,7 @@ static struct lock_list *alloc_list_entry(void)
printk("BUG: MAX_LOCKDEP_ENTRIES too low!\n");
printk("turning off the locking correctness validator.\n");
+ dump_stack();
return NULL;
}
return list_entries + nr_list_entries++;
@@ -1688,6 +1684,7 @@ cache_hit:
printk("BUG: MAX_LOCKDEP_CHAINS too low!\n");
printk("turning off the locking correctness validator.\n");
+ dump_stack();
return 0;
}
chain = lock_chains + nr_lock_chains++;
@@ -1900,9 +1897,9 @@ print_irq_inversion_bug(struct task_struct *curr, struct lock_class *other,
curr->comm, task_pid_nr(curr));
print_lock(this);
if (forwards)
- printk("but this lock took another, %s-irq-unsafe lock in the past:\n", irqclass);
+ printk("but this lock took another, %s-unsafe lock in the past:\n", irqclass);
else
- printk("but this lock was taken by another, %s-irq-safe lock in the past:\n", irqclass);
+ printk("but this lock was taken by another, %s-safe lock in the past:\n", irqclass);
print_lock_name(other);
printk("\n\nand interrupts could create inverse lock ordering between them.\n\n");
@@ -2015,7 +2012,8 @@ typedef int (*check_usage_f)(struct task_struct *, struct held_lock *,
enum lock_usage_bit bit, const char *name);
static int
-mark_lock_irq(struct task_struct *curr, struct held_lock *this, int new_bit)
+mark_lock_irq(struct task_struct *curr, struct held_lock *this,
+ enum lock_usage_bit new_bit)
{
int excl_bit = exclusive_bit(new_bit);
int read = new_bit & 1;
@@ -2043,7 +2041,7 @@ mark_lock_irq(struct task_struct *curr, struct held_lock *this, int new_bit)
* states.
*/
if ((!read || !dir || STRICT_READ_CHECKS) &&
- !usage(curr, this, excl_bit, state_name(new_bit)))
+ !usage(curr, this, excl_bit, state_name(new_bit & ~1)))
return 0;
/*
@@ -2546,6 +2544,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
debug_locks_off();
printk("BUG: MAX_LOCKDEP_SUBCLASSES too low!\n");
printk("turning off the locking correctness validator.\n");
+ dump_stack();
return 0;
}
@@ -2642,6 +2641,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
debug_locks_off();
printk("BUG: MAX_LOCK_DEPTH too low!\n");
printk("turning off the locking correctness validator.\n");
+ dump_stack();
return 0;
}
@@ -2929,6 +2929,8 @@ void lock_set_class(struct lockdep_map *lock, const char *name,
}
EXPORT_SYMBOL_GPL(lock_set_class);
+DEFINE_TRACE(lock_acquire);
+
/*
* We are not always called with irqs disabled - do that here,
* and also avoid lockdep recursion:
@@ -2939,6 +2941,8 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
{
unsigned long flags;
+ trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip);
+
if (unlikely(current->lockdep_recursion))
return;
@@ -2953,11 +2957,15 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
}
EXPORT_SYMBOL_GPL(lock_acquire);
+DEFINE_TRACE(lock_release);
+
void lock_release(struct lockdep_map *lock, int nested,
unsigned long ip)
{
unsigned long flags;
+ trace_lock_release(lock, nested, ip);
+
if (unlikely(current->lockdep_recursion))
return;
@@ -3106,10 +3114,14 @@ found_it:
lock->ip = ip;
}
+DEFINE_TRACE(lock_contended);
+
void lock_contended(struct lockdep_map *lock, unsigned long ip)
{
unsigned long flags;
+ trace_lock_contended(lock, ip);
+
if (unlikely(!lock_stat))
return;
@@ -3125,10 +3137,14 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip)
}
EXPORT_SYMBOL_GPL(lock_contended);
+DEFINE_TRACE(lock_acquired);
+
void lock_acquired(struct lockdep_map *lock, unsigned long ip)
{
unsigned long flags;
+ trace_lock_acquired(lock, ip);
+
if (unlikely(!lock_stat))
return;
diff --git a/kernel/module.c b/kernel/module.c
index f77ac320d0b..e797812a4d9 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -68,7 +68,8 @@
/* List of modules, protected by module_mutex or preempt_disable
* (delete uses stop_machine/add uses RCU list operations). */
-static DEFINE_MUTEX(module_mutex);
+DEFINE_MUTEX(module_mutex);
+EXPORT_SYMBOL_GPL(module_mutex);
static LIST_HEAD(modules);
/* Waiting for a module to finish initializing? */
@@ -76,7 +77,7 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq);
static BLOCKING_NOTIFIER_HEAD(module_notify_list);
-/* Bounds of module allocation, for speeding __module_text_address */
+/* Bounds of module allocation, for speeding __module_address */
static unsigned long module_addr_min = -1UL, module_addr_max = 0;
int register_module_notifier(struct notifier_block * nb)
@@ -186,17 +187,6 @@ extern const unsigned long __start___kcrctab_unused_gpl[];
#define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
#endif
-struct symsearch {
- const struct kernel_symbol *start, *stop;
- const unsigned long *crcs;
- enum {
- NOT_GPL_ONLY,
- GPL_ONLY,
- WILL_BE_GPL_ONLY,
- } licence;
- bool unused;
-};
-
static bool each_symbol_in_section(const struct symsearch *arr,
unsigned int arrsize,
struct module *owner,
@@ -217,10 +207,8 @@ static bool each_symbol_in_section(const struct symsearch *arr,
}
/* Returns true as soon as fn returns true, otherwise false. */
-static bool each_symbol(bool (*fn)(const struct symsearch *arr,
- struct module *owner,
- unsigned int symnum, void *data),
- void *data)
+bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
+ unsigned int symnum, void *data), void *data)
{
struct module *mod;
const struct symsearch arr[] = {
@@ -273,6 +261,7 @@ static bool each_symbol(bool (*fn)(const struct symsearch *arr,
}
return false;
}
+EXPORT_SYMBOL_GPL(each_symbol);
struct find_symbol_arg {
/* Input */
@@ -283,7 +272,7 @@ struct find_symbol_arg {
/* Output */
struct module *owner;
const unsigned long *crc;
- unsigned long value;
+ const struct kernel_symbol *sym;
};
static bool find_symbol_in_section(const struct symsearch *syms,
@@ -324,17 +313,17 @@ static bool find_symbol_in_section(const struct symsearch *syms,
fsa->owner = owner;
fsa->crc = symversion(syms->crcs, symnum);
- fsa->value = syms->start[symnum].value;
+ fsa->sym = &syms->start[symnum];
return true;
}
-/* Find a symbol, return value, (optional) crc and (optional) module
- * which owns it */
-static unsigned long find_symbol(const char *name,
- struct module **owner,
- const unsigned long **crc,
- bool gplok,
- bool warn)
+/* Find a symbol and return it, along with, (optional) crc and
+ * (optional) module which owns it */
+const struct kernel_symbol *find_symbol(const char *name,
+ struct module **owner,
+ const unsigned long **crc,
+ bool gplok,
+ bool warn)
{
struct find_symbol_arg fsa;
@@ -347,15 +336,16 @@ static unsigned long find_symbol(const char *name,
*owner = fsa.owner;
if (crc)
*crc = fsa.crc;
- return fsa.value;
+ return fsa.sym;
}
DEBUGP("Failed to find symbol %s\n", name);
- return -ENOENT;
+ return NULL;
}
+EXPORT_SYMBOL_GPL(find_symbol);
/* Search for module by name: must hold module_mutex. */
-static struct module *find_module(const char *name)
+struct module *find_module(const char *name)
{
struct module *mod;
@@ -365,6 +355,7 @@ static struct module *find_module(const char *name)
}
return NULL;
}
+EXPORT_SYMBOL_GPL(find_module);
#ifdef CONFIG_SMP
@@ -641,7 +632,7 @@ static int already_uses(struct module *a, struct module *b)
}
/* Module a uses b */
-static int use_module(struct module *a, struct module *b)
+int use_module(struct module *a, struct module *b)
{
struct module_use *use;
int no_warn, err;
@@ -674,6 +665,7 @@ static int use_module(struct module *a, struct module *b)
no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
return 1;
}
+EXPORT_SYMBOL_GPL(use_module);
/* Clear the unload stuff of the module. */
static void module_unload_free(struct module *mod)
@@ -894,7 +886,7 @@ void __symbol_put(const char *symbol)
struct module *owner;
preempt_disable();
- if (IS_ERR_VALUE(find_symbol(symbol, &owner, NULL, true, false)))
+ if (!find_symbol(symbol, &owner, NULL, true, false))
BUG();
module_put(owner);
preempt_enable();
@@ -908,8 +900,10 @@ void symbol_put_addr(void *addr)
if (core_kernel_text((unsigned long)addr))
return;
- if (!(modaddr = module_text_address((unsigned long)addr)))
- BUG();
+ /* module_text_address is safe here: we're supposed to have reference
+ * to module from symbol_get, so it can't go away. */
+ modaddr = __module_text_address((unsigned long)addr);
+ BUG_ON(!modaddr);
module_put(modaddr);
}
EXPORT_SYMBOL_GPL(symbol_put_addr);
@@ -949,10 +943,11 @@ static inline void module_unload_free(struct module *mod)
{
}
-static inline int use_module(struct module *a, struct module *b)
+int use_module(struct module *a, struct module *b)
{
return strong_try_module_get(b) == 0;
}
+EXPORT_SYMBOL_GPL(use_module);
static inline void module_unload_init(struct module *mod)
{
@@ -995,12 +990,12 @@ static struct module_attribute *modinfo_attrs[] = {
static const char vermagic[] = VERMAGIC_STRING;
-static int try_to_force_load(struct module *mod, const char *symname)
+static int try_to_force_load(struct module *mod, const char *reason)
{
#ifdef CONFIG_MODULE_FORCE_LOAD
if (!test_taint(TAINT_FORCED_MODULE))
- printk("%s: no version for \"%s\" found: kernel tainted.\n",
- mod->name, symname);
+ printk(KERN_WARNING "%s: %s: kernel tainted.\n",
+ mod->name, reason);
add_taint_module(mod, TAINT_FORCED_MODULE);
return 0;
#else
@@ -1057,9 +1052,9 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
{
const unsigned long *crc;
- if (IS_ERR_VALUE(find_symbol("struct_module", NULL, &crc, true, false)))
+ if (!find_symbol("module_layout", NULL, &crc, true, false))
BUG();
- return check_version(sechdrs, versindex, "struct_module", mod, crc);
+ return check_version(sechdrs, versindex, "module_layout", mod, crc);
}
/* First part is kernel version, which we ignore if module has crcs. */
@@ -1098,25 +1093,25 @@ static inline int same_magic(const char *amagic, const char *bmagic,
/* Resolve a symbol for this module. I.e. if we find one, record usage.
Must be holding module_mutex. */
-static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
- unsigned int versindex,
- const char *name,
- struct module *mod)
+static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
+ unsigned int versindex,
+ const char *name,
+ struct module *mod)
{
struct module *owner;
- unsigned long ret;
+ const struct kernel_symbol *sym;
const unsigned long *crc;
- ret = find_symbol(name, &owner, &crc,
+ sym = find_symbol(name, &owner, &crc,
!(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
- if (!IS_ERR_VALUE(ret)) {
- /* use_module can fail due to OOM,
- or module initialization or unloading */
+ /* use_module can fail due to OOM,
+ or module initialization or unloading */
+ if (sym) {
if (!check_version(sechdrs, versindex, name, mod, crc) ||
!use_module(mod, owner))
- ret = -EINVAL;
+ sym = NULL;
}
- return ret;
+ return sym;
}
/*
@@ -1491,6 +1486,9 @@ static void free_module(struct module *mod)
/* Module unload stuff */
module_unload_free(mod);
+ /* Free any allocated parameters. */
+ destroy_params(mod->kp, mod->num_kp);
+
/* release any pointers to mcount in this module */
ftrace_release(mod->module_core, mod->core_size);
@@ -1513,17 +1511,15 @@ static void free_module(struct module *mod)
void *__symbol_get(const char *symbol)
{
struct module *owner;
- unsigned long value;
+ const struct kernel_symbol *sym;
preempt_disable();
- value = find_symbol(symbol, &owner, NULL, true, true);
- if (IS_ERR_VALUE(value))
- value = 0;
- else if (strong_try_module_get(owner))
- value = 0;
+ sym = find_symbol(symbol, &owner, NULL, true, true);
+ if (sym && strong_try_module_get(owner))
+ sym = NULL;
preempt_enable();
- return (void *)value;
+ return sym ? (void *)sym->value : NULL;
}
EXPORT_SYMBOL_GPL(__symbol_get);
@@ -1551,8 +1547,7 @@ static int verify_export_symbols(struct module *mod)
for (i = 0; i < ARRAY_SIZE(arr); i++) {
for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
- if (!IS_ERR_VALUE(find_symbol(s->name, &owner,
- NULL, true, false))) {
+ if (find_symbol(s->name, &owner, NULL, true, false)) {
printk(KERN_ERR
"%s: exports duplicate symbol %s"
" (owned by %s)\n",
@@ -1576,6 +1571,7 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
unsigned long secbase;
unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
int ret = 0;
+ const struct kernel_symbol *ksym;
for (i = 1; i < n; i++) {
switch (sym[i].st_shndx) {
@@ -1595,13 +1591,14 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
break;
case SHN_UNDEF:
- sym[i].st_value
- = resolve_symbol(sechdrs, versindex,
- strtab + sym[i].st_name, mod);
-
+ ksym = resolve_symbol(sechdrs, versindex,
+ strtab + sym[i].st_name, mod);
/* Ok if resolved. */
- if (!IS_ERR_VALUE(sym[i].st_value))
+ if (ksym) {
+ sym[i].st_value = ksym->value;
break;
+ }
+
/* Ok if weak. */
if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK)
break;
@@ -1676,8 +1673,7 @@ static void layout_sections(struct module *mod,
if ((s->sh_flags & masks[m][0]) != masks[m][0]
|| (s->sh_flags & masks[m][1])
|| s->sh_entsize != ~0UL
- || strncmp(secstrings + s->sh_name,
- ".init", 5) == 0)
+ || strstarts(secstrings + s->sh_name, ".init"))
continue;
s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
DEBUGP("\t%s\n", secstrings + s->sh_name);
@@ -1694,8 +1690,7 @@ static void layout_sections(struct module *mod,
if ((s->sh_flags & masks[m][0]) != masks[m][0]
|| (s->sh_flags & masks[m][1])
|| s->sh_entsize != ~0UL
- || strncmp(secstrings + s->sh_name,
- ".init", 5) != 0)
+ || !strstarts(secstrings + s->sh_name, ".init"))
continue;
s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
| INIT_OFFSET_MASK);
@@ -1828,8 +1823,7 @@ static char elf_type(const Elf_Sym *sym,
else
return 'b';
}
- if (strncmp(secstrings + sechdrs[sym->st_shndx].sh_name,
- ".debug", strlen(".debug")) == 0)
+ if (strstarts(secstrings + sechdrs[sym->st_shndx].sh_name, ".debug"))
return 'n';
return '?';
}
@@ -1898,8 +1892,7 @@ static noinline struct module *load_module(void __user *umod,
unsigned int symindex = 0;
unsigned int strindex = 0;
unsigned int modindex, versindex, infoindex, pcpuindex;
- unsigned int num_kp, num_mcount;
- struct kernel_param *kp;
+ unsigned int num_mcount;
struct module *mod;
long err = 0;
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
@@ -1916,12 +1909,6 @@ static noinline struct module *load_module(void __user *umod,
if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
return ERR_PTR(-ENOMEM);
- /* Create stop_machine threads since the error path relies on
- * a non-failing stop_machine call. */
- err = stop_machine_create();
- if (err)
- goto free_hdr;
-
if (copy_from_user(hdr, umod, len) != 0) {
err = -EFAULT;
goto free_hdr;
@@ -1962,7 +1949,7 @@ static noinline struct module *load_module(void __user *umod,
}
#ifndef CONFIG_MODULE_UNLOAD
/* Don't load .exit sections */
- if (strncmp(secstrings+sechdrs[i].sh_name, ".exit", 5) == 0)
+ if (strstarts(secstrings+sechdrs[i].sh_name, ".exit"))
sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
#endif
}
@@ -2006,7 +1993,7 @@ static noinline struct module *load_module(void __user *umod,
modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
/* This is allowed: modprobe --force will invalidate it. */
if (!modmagic) {
- err = try_to_force_load(mod, "magic");
+ err = try_to_force_load(mod, "bad vermagic");
if (err)
goto free_hdr;
} else if (!same_magic(modmagic, vermagic, versindex)) {
@@ -2144,8 +2131,8 @@ static noinline struct module *load_module(void __user *umod,
/* Now we've got everything in the final locations, we can
* find optional sections. */
- kp = section_objs(hdr, sechdrs, secstrings, "__param", sizeof(*kp),
- &num_kp);
+ mod->kp = section_objs(hdr, sechdrs, secstrings, "__param",
+ sizeof(*mod->kp), &mod->num_kp);
mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab",
sizeof(*mod->syms), &mod->num_syms);
mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab");
@@ -2195,8 +2182,8 @@ static noinline struct module *load_module(void __user *umod,
|| (mod->num_unused_gpl_syms && !mod->unused_gpl_crcs)
#endif
) {
- printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name);
- err = try_to_force_load(mod, "nocrc");
+ err = try_to_force_load(mod,
+ "no versions for exported symbols");
if (err)
goto cleanup;
}
@@ -2291,11 +2278,11 @@ static noinline struct module *load_module(void __user *umod,
*/
list_add_rcu(&mod->list, &modules);
- err = parse_args(mod->name, mod->args, kp, num_kp, NULL);
+ err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL);
if (err < 0)
goto unlink;
- err = mod_sysfs_setup(mod, kp, num_kp);
+ err = mod_sysfs_setup(mod, mod->kp, mod->num_kp);
if (err < 0)
goto unlink;
add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
@@ -2304,12 +2291,13 @@ static noinline struct module *load_module(void __user *umod,
/* Get rid of temporary copy */
vfree(hdr);
- stop_machine_destroy();
/* Done! */
return mod;
unlink:
- stop_machine(__unlink_module, mod, NULL);
+ /* Unlink carefully: kallsyms could be walking list. */
+ list_del_rcu(&mod->list);
+ synchronize_sched();
module_arch_cleanup(mod);
cleanup:
kobject_del(&mod->mkobj.kobj);
@@ -2317,8 +2305,8 @@ static noinline struct module *load_module(void __user *umod,
ftrace_release(mod->module_core, mod->core_size);
free_unload:
module_unload_free(mod);
- free_init:
#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
+ free_init:
percpu_modfree(mod->refptr);
#endif
module_free(mod, mod->module_init);
@@ -2332,7 +2320,6 @@ static noinline struct module *load_module(void __user *umod,
kfree(args);
free_hdr:
vfree(hdr);
- stop_machine_destroy();
return ERR_PTR(err);
truncated:
@@ -2401,6 +2388,9 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
blocking_notifier_call_chain(&module_notify_list,
MODULE_STATE_LIVE, mod);
+ /* We need to finish all async code before the module init sequence is done */
+ async_synchronize_full();
+
mutex_lock(&module_mutex);
/* Drop initial reference. */
module_put(mod);
@@ -2609,6 +2599,25 @@ unsigned long module_kallsyms_lookup_name(const char *name)
preempt_enable();
return ret;
}
+
+int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+ struct module *, unsigned long),
+ void *data)
+{
+ struct module *mod;
+ unsigned int i;
+ int ret;
+
+ list_for_each_entry(mod, &modules, list) {
+ for (i = 0; i < mod->num_symtab; i++) {
+ ret = fn(data, mod->strtab + mod->symtab[i].st_name,
+ mod, mod->symtab[i].st_value);
+ if (ret != 0)
+ return ret;
+ }
+ }
+ return 0;
+}
#endif /* CONFIG_KALLSYMS */
static char *module_flags(struct module *mod, char *buf)
@@ -2744,29 +2753,31 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
}
/*
- * Is this a valid module address?
+ * is_module_address - is this address inside a module?
+ * @addr: the address to check.
+ *
+ * See is_module_text_address() if you simply want to see if the address
+ * is code (not data).
*/
-int is_module_address(unsigned long addr)
+bool is_module_address(unsigned long addr)
{
- struct module *mod;
+ bool ret;
preempt_disable();
-
- list_for_each_entry_rcu(mod, &modules, list) {
- if (within_module_core(addr, mod)) {
- preempt_enable();
- return 1;
- }
- }
-
+ ret = __module_address(addr) != NULL;
preempt_enable();
- return 0;
+ return ret;
}
-
-/* Is this a valid kernel address? */
-__notrace_funcgraph struct module *__module_text_address(unsigned long addr)
+/*
+ * __module_address - get the module which contains an address.
+ * @addr: the address.
+ *
+ * Must be called with preempt disabled or module mutex held so that
+ * module doesn't get freed during this.
+ */
+struct module *__module_address(unsigned long addr)
{
struct module *mod;
@@ -2774,22 +2785,51 @@ __notrace_funcgraph struct module *__module_text_address(unsigned long addr)
return NULL;
list_for_each_entry_rcu(mod, &modules, list)
- if (within(addr, mod->module_init, mod->init_text_size)
- || within(addr, mod->module_core, mod->core_text_size))
+ if (within_module_core(addr, mod)
+ || within_module_init(addr, mod))
return mod;
return NULL;
}
+EXPORT_SYMBOL_GPL(__module_address);
-struct module *module_text_address(unsigned long addr)
+/*
+ * is_module_text_address - is this address inside module code?
+ * @addr: the address to check.
+ *
+ * See is_module_address() if you simply want to see if the address is
+ * anywhere in a module. See kernel_text_address() for testing if an
+ * address corresponds to kernel or module code.
+ */
+bool is_module_text_address(unsigned long addr)
{
- struct module *mod;
+ bool ret;
preempt_disable();
- mod = __module_text_address(addr);
+ ret = __module_text_address(addr) != NULL;
preempt_enable();
+ return ret;
+}
+
+/*
+ * __module_text_address - get the module whose code contains an address.
+ * @addr: the address.
+ *
+ * Must be called with preempt disabled or module mutex held so that
+ * module doesn't get freed during this.
+ */
+struct module *__module_text_address(unsigned long addr)
+{
+ struct module *mod = __module_address(addr);
+ if (mod) {
+ /* Make sure it's within the text section. */
+ if (!within(addr, mod->module_init, mod->init_text_size)
+ && !within(addr, mod->module_core, mod->core_text_size))
+ mod = NULL;
+ }
return mod;
}
+EXPORT_SYMBOL_GPL(__module_text_address);
/* Don't grab lock, we're oopsing. */
void print_modules(void)
@@ -2809,9 +2849,17 @@ void print_modules(void)
}
#ifdef CONFIG_MODVERSIONS
-/* Generate the signature for struct module here, too, for modversions. */
-void struct_module(struct module *mod) { return; }
-EXPORT_SYMBOL(struct_module);
+/* Generate the signature for all relevant module structures here.
+ * If these change, we don't want to try to parse the module. */
+void module_layout(struct module *mod,
+ struct modversion_info *ver,
+ struct kernel_param *kp,
+ struct kernel_symbol *ks,
+ struct marker *marker,
+ struct tracepoint *tp)
+{
+}
+EXPORT_SYMBOL(module_layout);
#endif
#ifdef CONFIG_MARKERS
diff --git a/kernel/mutex.c b/kernel/mutex.c
index 5d79781394a..507cf2b5e9f 100644
--- a/kernel/mutex.c
+++ b/kernel/mutex.c
@@ -148,7 +148,8 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
preempt_disable();
mutex_acquire(&lock->dep_map, subclass, 0, ip);
-#if defined(CONFIG_SMP) && !defined(CONFIG_DEBUG_MUTEXES)
+#if defined(CONFIG_SMP) && !defined(CONFIG_DEBUG_MUTEXES) && \
+ !defined(CONFIG_HAVE_DEFAULT_NO_SPIN_MUTEXES)
/*
* Optimistic spinning.
*
diff --git a/kernel/panic.c b/kernel/panic.c
index 32fe4eff1b8..934fb377f4b 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -8,19 +8,19 @@
* This function is used through-out the kernel (including mm and fs)
* to indicate a major problem.
*/
+#include <linux/debug_locks.h>
+#include <linux/interrupt.h>
+#include <linux/kallsyms.h>
+#include <linux/notifier.h>
#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
+#include <linux/random.h>
#include <linux/reboot.h>
-#include <linux/notifier.h>
-#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kexec.h>
+#include <linux/sched.h>
#include <linux/sysrq.h>
-#include <linux/interrupt.h>
+#include <linux/init.h>
#include <linux/nmi.h>
-#include <linux/kexec.h>
-#include <linux/debug_locks.h>
-#include <linux/random.h>
-#include <linux/kallsyms.h>
#include <linux/dmi.h>
int panic_on_oops;
@@ -52,19 +52,15 @@ EXPORT_SYMBOL(panic_blink);
*
* This function never returns.
*/
-
NORET_TYPE void panic(const char * fmt, ...)
{
- long i;
static char buf[1024];
va_list args;
-#if defined(CONFIG_S390)
- unsigned long caller = (unsigned long) __builtin_return_address(0);
-#endif
+ long i;
/*
- * It's possible to come here directly from a panic-assertion and not
- * have preempt disabled. Some functions called from here want
+ * It's possible to come here directly from a panic-assertion and
+ * not have preempt disabled. Some functions called from here want
* preempt to be disabled. No point enabling it later though...
*/
preempt_disable();
@@ -77,7 +73,6 @@ NORET_TYPE void panic(const char * fmt, ...)
#ifdef CONFIG_DEBUG_BUGVERBOSE
dump_stack();
#endif
- bust_spinlocks(0);
/*
* If we have crashed and we have a crash kernel loaded let it handle
@@ -86,14 +81,12 @@ NORET_TYPE void panic(const char * fmt, ...)
*/
crash_kexec(NULL);
-#ifdef CONFIG_SMP
/*
* Note smp_send_stop is the usual smp shutdown function, which
* unfortunately means it may not be hardened to work in a panic
* situation.
*/
smp_send_stop();
-#endif
atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
@@ -102,19 +95,21 @@ NORET_TYPE void panic(const char * fmt, ...)
if (panic_timeout > 0) {
/*
- * Delay timeout seconds before rebooting the machine.
- * We can't use the "normal" timers since we just panicked..
- */
- printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
+ * Delay timeout seconds before rebooting the machine.
+ * We can't use the "normal" timers since we just panicked.
+ */
+ printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout);
+
for (i = 0; i < panic_timeout*1000; ) {
touch_nmi_watchdog();
i += panic_blink(i);
mdelay(1);
i++;
}
- /* This will not be a clean reboot, with everything
- * shutting down. But if there is a chance of
- * rebooting the system it will be rebooted.
+ /*
+ * This will not be a clean reboot, with everything
+ * shutting down. But if there is a chance of
+ * rebooting the system it will be rebooted.
*/
emergency_restart();
}
@@ -127,38 +122,44 @@ NORET_TYPE void panic(const char * fmt, ...)
}
#endif
#if defined(CONFIG_S390)
- disabled_wait(caller);
+ {
+ unsigned long caller;
+
+ caller = (unsigned long)__builtin_return_address(0);
+ disabled_wait(caller);
+ }
#endif
local_irq_enable();
- for (i = 0;;) {
+ for (i = 0; ; ) {
touch_softlockup_watchdog();
i += panic_blink(i);
mdelay(1);
i++;
}
+ bust_spinlocks(0);
}
EXPORT_SYMBOL(panic);
struct tnt {
- u8 bit;
- char true;
- char false;
+ 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', ' ' },
+ { 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', ' ' },
};
/**
@@ -195,7 +196,8 @@ const char *print_tainted(void)
*s = 0;
} else
snprintf(buf, sizeof(buf), "Not tainted");
- return(buf);
+
+ return buf;
}
int test_taint(unsigned flag)
@@ -211,7 +213,16 @@ unsigned long get_taint(void)
void add_taint(unsigned flag)
{
- debug_locks = 0; /* can't trust the integrity of the kernel anymore */
+ /*
+ * Can't trust the integrity of the kernel anymore.
+ * We don't call directly debug_locks_off() because the issue
+ * is not necessarily serious enough to set oops_in_progress to 1
+ * Also we want to keep up lockdep for staging development and
+ * post-warning case.
+ */
+ if (flag != TAINT_CRAP && flag != TAINT_WARN && __debug_locks_off())
+ printk(KERN_WARNING "Disabling lockdep due to kernel taint\n");
+
set_bit(flag, &tainted_mask);
}
EXPORT_SYMBOL(add_taint);
@@ -266,8 +277,8 @@ static void do_oops_enter_exit(void)
}
/*
- * Return true if the calling CPU is allowed to print oops-related info. This
- * is a bit racy..
+ * Return true if the calling CPU is allowed to print oops-related info.
+ * This is a bit racy..
*/
int oops_may_print(void)
{
@@ -276,20 +287,22 @@ int oops_may_print(void)
/*
* Called when the architecture enters its oops handler, before it prints
- * anything. If this is the first CPU to oops, and it's oopsing the first time
- * then let it proceed.
+ * anything. If this is the first CPU to oops, and it's oopsing the first
+ * time then let it proceed.
*
- * This is all enabled by the pause_on_oops kernel boot option. We do all this
- * to ensure that oopses don't scroll off the screen. It has the side-effect
- * of preventing later-oopsing CPUs from mucking up the display, too.
+ * This is all enabled by the pause_on_oops kernel boot option. We do all
+ * this to ensure that oopses don't scroll off the screen. It has the
+ * side-effect of preventing later-oopsing CPUs from mucking up the display,
+ * too.
*
- * It turns out that the CPU which is allowed to print ends up pausing for the
- * right duration, whereas all the other CPUs pause for twice as long: once in
- * oops_enter(), once in oops_exit().
+ * It turns out that the CPU which is allowed to print ends up pausing for
+ * the right duration, whereas all the other CPUs pause for twice as long:
+ * once in oops_enter(), once in oops_exit().
*/
void oops_enter(void)
{
- debug_locks_off(); /* can't trust the integrity of the kernel anymore */
+ /* can't trust the integrity of the kernel anymore: */
+ debug_locks_off();
do_oops_enter_exit();
}
diff --git a/kernel/params.c b/kernel/params.c
index a1e3025b19a..de273ec85bd 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -24,6 +24,9 @@
#include <linux/err.h>
#include <linux/slab.h>
+/* We abuse the high bits of "perm" to record whether we kmalloc'ed. */
+#define KPARAM_KMALLOCED 0x80000000
+
#if 0
#define DEBUGP printk
#else
@@ -217,7 +220,19 @@ int param_set_charp(const char *val, struct kernel_param *kp)
return -ENOSPC;
}
- *(char **)kp->arg = (char *)val;
+ if (kp->perm & KPARAM_KMALLOCED)
+ kfree(*(char **)kp->arg);
+
+ /* This is a hack. We can't need to strdup in early boot, and we
+ * don't need to; this mangled commandline is preserved. */
+ if (slab_is_available()) {
+ kp->perm |= KPARAM_KMALLOCED;
+ *(char **)kp->arg = kstrdup(val, GFP_KERNEL);
+ if (!kp->arg)
+ return -ENOMEM;
+ } else
+ *(const char **)kp->arg = val;
+
return 0;
}
@@ -571,6 +586,15 @@ void module_param_sysfs_remove(struct module *mod)
}
#endif
+void destroy_params(const struct kernel_param *params, unsigned num)
+{
+ unsigned int i;
+
+ for (i = 0; i < num; i++)
+ if (params[i].perm & KPARAM_KMALLOCED)
+ kfree(*(char **)params[i].arg);
+}
+
static void __init kernel_add_sysfs_param(const char *name,
struct kernel_param *kparam,
unsigned int name_skip)
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 8e5d9a68b02..c9dcf98b446 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -18,7 +18,7 @@ void update_rlimit_cpu(unsigned long rlim_new)
cputime = secs_to_cputime(rlim_new);
if (cputime_eq(current->signal->it_prof_expires, cputime_zero) ||
- cputime_lt(current->signal->it_prof_expires, cputime)) {
+ cputime_gt(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);
@@ -224,7 +224,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 = p->se.sum_exec_runtime + task_delta_exec(p);
+ cpu->sched = task_sched_runtime(p);
break;
}
return 0;
@@ -305,18 +305,19 @@ static int cpu_clock_sample_group(const clockid_t which_clock,
{
struct task_cputime cputime;
- thread_group_cputime(p, &cputime);
switch (CPUCLOCK_WHICH(which_clock)) {
default:
return -EINVAL;
case CPUCLOCK_PROF:
+ thread_group_cputime(p, &cputime);
cpu->cpu = cputime_add(cputime.utime, cputime.stime);
break;
case CPUCLOCK_VIRT:
+ thread_group_cputime(p, &cputime);
cpu->cpu = cputime.utime;
break;
case CPUCLOCK_SCHED:
- cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p);
+ cpu->sched = thread_group_sched_runtime(p);
break;
}
return 0;
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index f3db382c2b2..0854770b63b 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -22,6 +22,7 @@
#include <linux/console.h>
#include <linux/cpu.h>
#include <linux/freezer.h>
+#include <scsi/scsi_scan.h>
#include <asm/suspend.h>
#include "power.h"
@@ -289,7 +290,7 @@ static int create_image(int platform_mode)
* hibernation_snapshot - quiesce devices and create the hibernation
* snapshot image.
* @platform_mode - if set, use the platform driver, if available, to
- * prepare the platform frimware for the power transition.
+ * prepare the platform firmware for the power transition.
*
* Must be called with pm_mutex held
*/
@@ -412,7 +413,7 @@ static int resume_target_kernel(bool platform_mode)
* hibernation_restore - quiesce devices and restore the hibernation
* snapshot image. If successful, control returns in hibernation_snaphot()
* @platform_mode - if set, use the platform driver, if available, to
- * prepare the platform frimware for the transition.
+ * prepare the platform firmware for the transition.
*
* Must be called with pm_mutex held
*/
@@ -645,6 +646,13 @@ static int software_resume(void)
return 0;
/*
+ * We can't depend on SCSI devices being available after loading one of
+ * their modules if scsi_complete_async_scans() is not called and the
+ * resume device usually is a SCSI one.
+ */
+ scsi_complete_async_scans();
+
+ /*
* name_to_dev_t() below takes a sysfs buffer mutex when sysfs
* is configured into the kernel. Since the regular hibernate
* trigger path is via sysfs which takes a buffer mutex before
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 6c85359364f..ed97375daae 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -24,6 +24,7 @@
#include <linux/cpu.h>
#include <linux/freezer.h>
#include <linux/smp_lock.h>
+#include <scsi/scsi_scan.h>
#include <asm/uaccess.h>
@@ -92,6 +93,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
filp->private_data = data;
memset(&data->handle, 0, sizeof(struct snapshot_handle));
if ((filp->f_flags & O_ACCMODE) == O_RDONLY) {
+ /* Hibernating. The image device should be accessible. */
data->swap = swsusp_resume_device ?
swap_type_of(swsusp_resume_device, 0, NULL) : -1;
data->mode = O_RDONLY;
@@ -99,6 +101,13 @@ static int snapshot_open(struct inode *inode, struct file *filp)
if (error)
pm_notifier_call_chain(PM_POST_HIBERNATION);
} else {
+ /*
+ * Resuming. We may need to wait for the image device to
+ * appear.
+ */
+ wait_for_device_probe();
+ scsi_complete_async_scans();
+
data->swap = -1;
data->mode = O_WRONLY;
error = pm_notifier_call_chain(PM_RESTORE_PREPARE);
diff --git a/kernel/printk.c b/kernel/printk.c
index a5f61a9aced..5052b5497c6 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -1311,8 +1311,11 @@ EXPORT_SYMBOL(printk_ratelimit);
bool printk_timed_ratelimit(unsigned long *caller_jiffies,
unsigned int interval_msecs)
{
- if (*caller_jiffies == 0 || time_after(jiffies, *caller_jiffies)) {
- *caller_jiffies = jiffies + msecs_to_jiffies(interval_msecs);
+ if (*caller_jiffies == 0
+ || !time_in_range(jiffies, *caller_jiffies,
+ *caller_jiffies
+ + msecs_to_jiffies(interval_msecs))) {
+ *caller_jiffies = jiffies;
return true;
}
return false;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 5105f5a6a2c..dfcd83ceee3 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -21,9 +21,7 @@
#include <linux/audit.h>
#include <linux/pid_namespace.h>
#include <linux/syscalls.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
/*
@@ -48,7 +46,7 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent)
list_add(&child->ptrace_entry, &new_parent->ptraced);
child->parent = new_parent;
}
-
+
/*
* Turn a tracing stop into a normal stop now, since with no tracer there
* would be no way to wake it up with SIGCONT or SIGKILL. If there was a
@@ -173,7 +171,7 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode)
task_lock(task);
err = __ptrace_may_access(task, mode);
task_unlock(task);
- return (!err ? true : false);
+ return !err;
}
int ptrace_attach(struct task_struct *task)
@@ -358,7 +356,7 @@ int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst
copied += retval;
src += retval;
dst += retval;
- len -= retval;
+ len -= retval;
}
return copied;
}
@@ -383,7 +381,7 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds
copied += retval;
src += retval;
dst += retval;
- len -= retval;
+ len -= retval;
}
return copied;
}
@@ -496,9 +494,9 @@ static int ptrace_resume(struct task_struct *child, long request, long data)
if (unlikely(!arch_has_single_step()))
return -EIO;
user_enable_single_step(child);
- }
- else
+ } else {
user_disable_single_step(child);
+ }
child->exit_code = data;
wake_up_process(child);
@@ -606,10 +604,11 @@ repeat:
ret = security_ptrace_traceme(current->parent);
/*
- * Set the ptrace bit in the process ptrace flags.
- * Then link us on our parent's ptraced list.
+ * Check PF_EXITING to ensure ->real_parent has not passed
+ * exit_ptrace(). Otherwise we don't report the error but
+ * pretend ->real_parent untraces us right after return.
*/
- if (!ret) {
+ if (!ret && !(current->real_parent->flags & PF_EXITING)) {
current->ptrace |= PT_PTRACED;
__ptrace_link(current, current->real_parent);
}
@@ -687,8 +686,6 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data)
goto out_put_task_struct;
ret = arch_ptrace(child, request, addr, data);
- if (ret < 0)
- goto out_put_task_struct;
out_put_task_struct:
put_task_struct(child);
diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c
index 654c640a6b9..0f2b0b31130 100644
--- a/kernel/rcuclassic.c
+++ b/kernel/rcuclassic.c
@@ -65,6 +65,7 @@ static struct rcu_ctrlblk rcu_ctrlblk = {
.lock = __SPIN_LOCK_UNLOCKED(&rcu_ctrlblk.lock),
.cpumask = CPU_BITS_NONE,
};
+
static struct rcu_ctrlblk rcu_bh_ctrlblk = {
.cur = -300,
.completed = -300,
@@ -73,8 +74,26 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk = {
.cpumask = CPU_BITS_NONE,
};
-DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
-DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
+static DEFINE_PER_CPU(struct rcu_data, rcu_data);
+static DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
+
+/*
+ * Increment the quiescent state counter.
+ * The counter is a bit degenerated: We do not need to know
+ * how many quiescent states passed, just if there was at least
+ * one since the start of the grace period. Thus just a flag.
+ */
+void rcu_qsctr_inc(int cpu)
+{
+ struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
+ rdp->passed_quiesc = 1;
+}
+
+void rcu_bh_qsctr_inc(int cpu)
+{
+ struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
+ rdp->passed_quiesc = 1;
+}
static int blimit = 10;
static int qhimark = 10000;
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index cae8a059cf4..2c7b8457d0d 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -122,6 +122,8 @@ static void rcu_barrier_func(void *type)
}
}
+static inline void wait_migrated_callbacks(void);
+
/*
* Orchestrate the specified type of RCU barrier, waiting for all
* RCU callbacks of the specified type to complete.
@@ -147,6 +149,7 @@ static void _rcu_barrier(enum rcu_barrier type)
complete(&rcu_barrier_completion);
wait_for_completion(&rcu_barrier_completion);
mutex_unlock(&rcu_barrier_mutex);
+ wait_migrated_callbacks();
}
/**
@@ -176,9 +179,50 @@ void rcu_barrier_sched(void)
}
EXPORT_SYMBOL_GPL(rcu_barrier_sched);
+static atomic_t rcu_migrate_type_count = ATOMIC_INIT(0);
+static struct rcu_head rcu_migrate_head[3];
+static DECLARE_WAIT_QUEUE_HEAD(rcu_migrate_wq);
+
+static void rcu_migrate_callback(struct rcu_head *notused)
+{
+ if (atomic_dec_and_test(&rcu_migrate_type_count))
+ wake_up(&rcu_migrate_wq);
+}
+
+static inline void wait_migrated_callbacks(void)
+{
+ wait_event(rcu_migrate_wq, !atomic_read(&rcu_migrate_type_count));
+}
+
+static int __cpuinit rcu_barrier_cpu_hotplug(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ if (action == CPU_DYING) {
+ /*
+ * preempt_disable() in on_each_cpu() prevents stop_machine(),
+ * so when "on_each_cpu(rcu_barrier_func, (void *)type, 1);"
+ * returns, all online cpus have queued rcu_barrier_func(),
+ * and the dead cpu(if it exist) queues rcu_migrate_callback()s.
+ *
+ * These callbacks ensure _rcu_barrier() waits for all
+ * RCU callbacks of the specified type to complete.
+ */
+ atomic_set(&rcu_migrate_type_count, 3);
+ call_rcu_bh(rcu_migrate_head, rcu_migrate_callback);
+ call_rcu_sched(rcu_migrate_head + 1, rcu_migrate_callback);
+ call_rcu(rcu_migrate_head + 2, rcu_migrate_callback);
+ } else if (action == CPU_POST_DEAD) {
+ /* rcu_migrate_head is protected by cpu_add_remove_lock */
+ wait_migrated_callbacks();
+ }
+
+ return NOTIFY_OK;
+}
+
void __init rcu_init(void)
{
__rcu_init();
+ hotcpu_notifier(rcu_barrier_cpu_hotplug, 0);
}
void rcu_scheduler_starting(void)
diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c
index 5d59e850fb7..ce97a4df64d 100644
--- a/kernel/rcupreempt.c
+++ b/kernel/rcupreempt.c
@@ -147,7 +147,51 @@ struct rcu_ctrlblk {
wait_queue_head_t sched_wq; /* Place for rcu_sched to sleep. */
};
+struct rcu_dyntick_sched {
+ int dynticks;
+ int dynticks_snap;
+ int sched_qs;
+ int sched_qs_snap;
+ int sched_dynticks_snap;
+};
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct rcu_dyntick_sched, rcu_dyntick_sched) = {
+ .dynticks = 1,
+};
+
+void rcu_qsctr_inc(int cpu)
+{
+ struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu);
+
+ rdssp->sched_qs++;
+}
+
+#ifdef CONFIG_NO_HZ
+
+void rcu_enter_nohz(void)
+{
+ static DEFINE_RATELIMIT_STATE(rs, 10 * HZ, 1);
+
+ smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */
+ __get_cpu_var(rcu_dyntick_sched).dynticks++;
+ WARN_ON_RATELIMIT(__get_cpu_var(rcu_dyntick_sched).dynticks & 0x1, &rs);
+}
+
+void rcu_exit_nohz(void)
+{
+ static DEFINE_RATELIMIT_STATE(rs, 10 * HZ, 1);
+
+ __get_cpu_var(rcu_dyntick_sched).dynticks++;
+ smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */
+ WARN_ON_RATELIMIT(!(__get_cpu_var(rcu_dyntick_sched).dynticks & 0x1),
+ &rs);
+}
+
+#endif /* CONFIG_NO_HZ */
+
+
static DEFINE_PER_CPU(struct rcu_data, rcu_data);
+
static struct rcu_ctrlblk rcu_ctrlblk = {
.fliplock = __SPIN_LOCK_UNLOCKED(rcu_ctrlblk.fliplock),
.completed = 0,
@@ -427,10 +471,6 @@ static void __rcu_advance_callbacks(struct rcu_data *rdp)
}
}
-DEFINE_PER_CPU_SHARED_ALIGNED(struct rcu_dyntick_sched, rcu_dyntick_sched) = {
- .dynticks = 1,
-};
-
#ifdef CONFIG_NO_HZ
static DEFINE_PER_CPU(int, rcu_update_flag);
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 97ce31579ec..7f326692257 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -78,6 +78,26 @@ DEFINE_PER_CPU(struct rcu_data, rcu_data);
struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state);
DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
+/*
+ * Increment the quiescent state counter.
+ * The counter is a bit degenerated: We do not need to know
+ * how many quiescent states passed, just if there was at least
+ * one since the start of the grace period. Thus just a flag.
+ */
+void rcu_qsctr_inc(int cpu)
+{
+ struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
+ rdp->passed_quiesc = 1;
+ rdp->passed_quiesc_completed = rdp->completed;
+}
+
+void rcu_bh_qsctr_inc(int cpu)
+{
+ struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
+ rdp->passed_quiesc = 1;
+ rdp->passed_quiesc_completed = rdp->completed;
+}
+
#ifdef CONFIG_NO_HZ
DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
.dynticks_nesting = 1,
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
new file mode 100644
index 00000000000..5e872bbf07f
--- /dev/null
+++ b/kernel/rcutree.h
@@ -0,0 +1,10 @@
+
+/*
+ * RCU implementation internal declarations:
+ */
+extern struct rcu_state rcu_state;
+DECLARE_PER_CPU(struct rcu_data, rcu_data);
+
+extern struct rcu_state rcu_bh_state;
+DECLARE_PER_CPU(struct rcu_data, rcu_bh_data);
+
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c
index d6db3e83782..4ee954f6a8d 100644
--- a/kernel/rcutree_trace.c
+++ b/kernel/rcutree_trace.c
@@ -43,6 +43,8 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
+#include "rcutree.h"
+
static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
{
if (!rdp->beenonline)
diff --git a/kernel/relay.c b/kernel/relay.c
index e92db8c06ac..bc188549788 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -677,9 +677,7 @@ int relay_late_setup_files(struct rchan *chan,
*/
for_each_online_cpu(i) {
if (unlikely(!chan->buf[i])) {
- printk(KERN_ERR "relay_late_setup_files: CPU %u "
- "has no buffer, it must have!\n", i);
- BUG();
+ WARN_ONCE(1, KERN_ERR "CPU has no buffer!\n");
err = -EINVAL;
break;
}
diff --git a/kernel/sched.c b/kernel/sched.c
index 73513f4e19d..5724508c3b6 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -231,13 +231,20 @@ static void start_rt_bandwidth(struct rt_bandwidth *rt_b)
spin_lock(&rt_b->rt_runtime_lock);
for (;;) {
+ unsigned long delta;
+ ktime_t soft, hard;
+
if (hrtimer_active(&rt_b->rt_period_timer))
break;
now = hrtimer_cb_get_time(&rt_b->rt_period_timer);
hrtimer_forward(&rt_b->rt_period_timer, now, rt_b->rt_period);
- hrtimer_start_expires(&rt_b->rt_period_timer,
- HRTIMER_MODE_ABS);
+
+ soft = hrtimer_get_softexpires(&rt_b->rt_period_timer);
+ hard = hrtimer_get_expires(&rt_b->rt_period_timer);
+ delta = ktime_to_ns(ktime_sub(hard, soft));
+ __hrtimer_start_range_ns(&rt_b->rt_period_timer, soft, delta,
+ HRTIMER_MODE_ABS, 0);
}
spin_unlock(&rt_b->rt_runtime_lock);
}
@@ -1110,7 +1117,7 @@ static void hrtick_start(struct rq *rq, u64 delay)
if (rq == this_rq()) {
hrtimer_restart(timer);
} else if (!rq->hrtick_csd_pending) {
- __smp_call_function_single(cpu_of(rq), &rq->hrtick_csd);
+ __smp_call_function_single(cpu_of(rq), &rq->hrtick_csd, 0);
rq->hrtick_csd_pending = 1;
}
}
@@ -1146,7 +1153,8 @@ static __init void init_hrtick(void)
*/
static void hrtick_start(struct rq *rq, u64 delay)
{
- hrtimer_start(&rq->hrtick_timer, ns_to_ktime(delay), HRTIMER_MODE_REL);
+ __hrtimer_start_range_ns(&rq->hrtick_timer, ns_to_ktime(delay), 0,
+ HRTIMER_MODE_REL, 0);
}
static inline void init_hrtick(void)
@@ -1410,10 +1418,22 @@ iter_move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest,
struct rq_iterator *iterator);
#endif
+/* Time spent by the tasks of the cpu accounting group executing in ... */
+enum cpuacct_stat_index {
+ CPUACCT_STAT_USER, /* ... user mode */
+ CPUACCT_STAT_SYSTEM, /* ... kernel mode */
+
+ CPUACCT_STAT_NSTATS,
+};
+
#ifdef CONFIG_CGROUP_CPUACCT
static void cpuacct_charge(struct task_struct *tsk, u64 cputime);
+static void cpuacct_update_stats(struct task_struct *tsk,
+ enum cpuacct_stat_index idx, cputime_t val);
#else
static inline void cpuacct_charge(struct task_struct *tsk, u64 cputime) {}
+static inline void cpuacct_update_stats(struct task_struct *tsk,
+ enum cpuacct_stat_index idx, cputime_t val) {}
#endif
static inline void inc_cpu_load(struct rq *rq, unsigned long load)
@@ -3818,19 +3838,23 @@ find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle,
*/
#define MAX_PINNED_INTERVAL 512
+/* Working cpumask for load_balance and load_balance_newidle. */
+static DEFINE_PER_CPU(cpumask_var_t, load_balance_tmpmask);
+
/*
* Check this_cpu to ensure it is balanced within domain. Attempt to move
* tasks if there is an imbalance.
*/
static int load_balance(int this_cpu, struct rq *this_rq,
struct sched_domain *sd, enum cpu_idle_type idle,
- int *balance, struct cpumask *cpus)
+ int *balance)
{
int ld_moved, all_pinned = 0, active_balance = 0, sd_idle = 0;
struct sched_group *group;
unsigned long imbalance;
struct rq *busiest;
unsigned long flags;
+ struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask);
cpumask_setall(cpus);
@@ -3985,8 +4009,7 @@ out:
* this_rq is locked.
*/
static int
-load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd,
- struct cpumask *cpus)
+load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd)
{
struct sched_group *group;
struct rq *busiest = NULL;
@@ -3994,6 +4017,7 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd,
int ld_moved = 0;
int sd_idle = 0;
int all_pinned = 0;
+ struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask);
cpumask_setall(cpus);
@@ -4134,10 +4158,6 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
struct sched_domain *sd;
int pulled_task = 0;
unsigned long next_balance = jiffies + HZ;
- cpumask_var_t tmpmask;
-
- if (!alloc_cpumask_var(&tmpmask, GFP_ATOMIC))
- return;
for_each_domain(this_cpu, sd) {
unsigned long interval;
@@ -4148,7 +4168,7 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
if (sd->flags & SD_BALANCE_NEWIDLE)
/* If we've pulled tasks over stop searching: */
pulled_task = load_balance_newidle(this_cpu, this_rq,
- sd, tmpmask);
+ sd);
interval = msecs_to_jiffies(sd->balance_interval);
if (time_after(next_balance, sd->last_balance + interval))
@@ -4163,7 +4183,6 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
*/
this_rq->next_balance = next_balance;
}
- free_cpumask_var(tmpmask);
}
/*
@@ -4313,11 +4332,6 @@ static void rebalance_domains(int cpu, enum cpu_idle_type idle)
unsigned long next_balance = jiffies + 60*HZ;
int update_next_balance = 0;
int need_serialize;
- cpumask_var_t tmp;
-
- /* Fails alloc? Rebalancing probably not a priority right now. */
- if (!alloc_cpumask_var(&tmp, GFP_ATOMIC))
- return;
for_each_domain(cpu, sd) {
if (!(sd->flags & SD_LOAD_BALANCE))
@@ -4342,7 +4356,7 @@ static void rebalance_domains(int cpu, enum cpu_idle_type idle)
}
if (time_after_eq(jiffies, sd->last_balance + interval)) {
- if (load_balance(cpu, rq, sd, idle, &balance, tmp)) {
+ if (load_balance(cpu, rq, sd, idle, &balance)) {
/*
* We've pulled tasks over so either we're no
* longer idle, or one of our SMT siblings is
@@ -4376,8 +4390,6 @@ out:
*/
if (likely(update_next_balance))
rq->next_balance = next_balance;
-
- free_cpumask_var(tmp);
}
/*
@@ -4511,9 +4523,25 @@ DEFINE_PER_CPU(struct kernel_stat, kstat);
EXPORT_PER_CPU_SYMBOL(kstat);
/*
- * Return any ns on the sched_clock that have not yet been banked in
+ * Return any ns on the sched_clock that have not yet been accounted in
* @p in case that task is currently running.
+ *
+ * Called with task_rq_lock() held on @rq.
*/
+static u64 do_task_delta_exec(struct task_struct *p, struct rq *rq)
+{
+ u64 ns = 0;
+
+ if (task_current(rq, p)) {
+ update_rq_clock(rq);
+ ns = rq->clock - p->se.exec_start;
+ if ((s64)ns < 0)
+ ns = 0;
+ }
+
+ return ns;
+}
+
unsigned long long task_delta_exec(struct task_struct *p)
{
unsigned long flags;
@@ -4521,16 +4549,49 @@ unsigned long long task_delta_exec(struct task_struct *p)
u64 ns = 0;
rq = task_rq_lock(p, &flags);
+ ns = do_task_delta_exec(p, rq);
+ task_rq_unlock(rq, &flags);
- if (task_current(rq, p)) {
- u64 delta_exec;
+ return ns;
+}
- update_rq_clock(rq);
- delta_exec = rq->clock - p->se.exec_start;
- if ((s64)delta_exec > 0)
- ns = delta_exec;
- }
+/*
+ * Return accounted runtime for the task.
+ * In case the task is currently running, return the runtime plus current's
+ * pending runtime that have not been accounted yet.
+ */
+unsigned long long task_sched_runtime(struct task_struct *p)
+{
+ unsigned long flags;
+ struct rq *rq;
+ u64 ns = 0;
+
+ rq = task_rq_lock(p, &flags);
+ ns = p->se.sum_exec_runtime + do_task_delta_exec(p, rq);
+ task_rq_unlock(rq, &flags);
+
+ return ns;
+}
+/*
+ * Return sum_exec_runtime for the thread group.
+ * In case the task is currently running, return the sum plus current's
+ * pending runtime that have not been accounted yet.
+ *
+ * Note that the thread group might have other running tasks as well,
+ * so the return value not includes other pending runtime that other
+ * running tasks might have.
+ */
+unsigned long long thread_group_sched_runtime(struct task_struct *p)
+{
+ struct task_cputime totals;
+ unsigned long flags;
+ struct rq *rq;
+ u64 ns;
+
+ rq = task_rq_lock(p, &flags);
+ thread_group_cputime(p, &totals);
+ ns = totals.sum_exec_runtime + do_task_delta_exec(p, rq);
task_rq_unlock(rq, &flags);
return ns;
@@ -4559,6 +4620,8 @@ void account_user_time(struct task_struct *p, cputime_t cputime,
cpustat->nice = cputime64_add(cpustat->nice, tmp);
else
cpustat->user = cputime64_add(cpustat->user, tmp);
+
+ cpuacct_update_stats(p, CPUACCT_STAT_USER, cputime);
/* Account for user time used */
acct_update_integrals(p);
}
@@ -4620,6 +4683,8 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
else
cpustat->system = cputime64_add(cpustat->system, tmp);
+ cpuacct_update_stats(p, CPUACCT_STAT_SYSTEM, cputime);
+
/* Account for system time used */
acct_update_integrals(p);
}
@@ -4781,10 +4846,7 @@ void scheduler_tick(void)
#endif
}
-#if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \
- defined(CONFIG_PREEMPT_TRACER))
-
-static inline unsigned long get_parent_ip(unsigned long addr)
+unsigned long get_parent_ip(unsigned long addr)
{
if (in_lock_functions(addr)) {
addr = CALLER_ADDR2;
@@ -4794,6 +4856,9 @@ static inline unsigned long get_parent_ip(unsigned long addr)
return addr;
}
+#if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \
+ defined(CONFIG_PREEMPT_TRACER))
+
void __kprobes add_preempt_count(int val)
{
#ifdef CONFIG_DEBUG_PREEMPT
@@ -7302,7 +7367,8 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level,
cpumask_or(groupmask, groupmask, sched_group_cpus(group));
cpulist_scnprintf(str, sizeof(str), sched_group_cpus(group));
- printk(KERN_CONT " %s", str);
+ printk(KERN_CONT " %s (__cpu_power = %d)", str,
+ group->__cpu_power);
group = group->next;
} while (group != sd->groups);
@@ -7728,7 +7794,7 @@ cpu_to_core_group(int cpu, const struct cpumask *cpu_map,
{
int group;
- cpumask_and(mask, &per_cpu(cpu_sibling_map, cpu), cpu_map);
+ cpumask_and(mask, topology_thread_cpumask(cpu), cpu_map);
group = cpumask_first(mask);
if (sg)
*sg = &per_cpu(sched_group_core, group).sg;
@@ -7757,7 +7823,7 @@ cpu_to_phys_group(int cpu, const struct cpumask *cpu_map,
cpumask_and(mask, cpu_coregroup_mask(cpu), cpu_map);
group = cpumask_first(mask);
#elif defined(CONFIG_SCHED_SMT)
- cpumask_and(mask, &per_cpu(cpu_sibling_map, cpu), cpu_map);
+ cpumask_and(mask, topology_thread_cpumask(cpu), cpu_map);
group = cpumask_first(mask);
#else
group = cpu;
@@ -8100,7 +8166,7 @@ static int __build_sched_domains(const struct cpumask *cpu_map,
SD_INIT(sd, SIBLING);
set_domain_attribute(sd, attr);
cpumask_and(sched_domain_span(sd),
- &per_cpu(cpu_sibling_map, i), cpu_map);
+ topology_thread_cpumask(i), cpu_map);
sd->parent = p;
p->child = sd;
cpu_to_cpu_group(i, cpu_map, &sd->groups, tmpmask);
@@ -8111,7 +8177,7 @@ static int __build_sched_domains(const struct cpumask *cpu_map,
/* Set up CPU (sibling) groups */
for_each_cpu(i, cpu_map) {
cpumask_and(this_sibling_map,
- &per_cpu(cpu_sibling_map, i), cpu_map);
+ topology_thread_cpumask(i), cpu_map);
if (i != cpumask_first(this_sibling_map))
continue;
@@ -8787,6 +8853,9 @@ void __init sched_init(void)
#ifdef CONFIG_USER_SCHED
alloc_size *= 2;
#endif
+#ifdef CONFIG_CPUMASK_OFFSTACK
+ alloc_size += num_possible_cpus() * cpumask_size();
+#endif
/*
* As sched_init() is called before page_alloc is setup,
* we use alloc_bootmem().
@@ -8824,6 +8893,12 @@ void __init sched_init(void)
ptr += nr_cpu_ids * sizeof(void **);
#endif /* CONFIG_USER_SCHED */
#endif /* CONFIG_RT_GROUP_SCHED */
+#ifdef CONFIG_CPUMASK_OFFSTACK
+ for_each_possible_cpu(i) {
+ per_cpu(load_balance_tmpmask, i) = (void *)ptr;
+ ptr += cpumask_size();
+ }
+#endif /* CONFIG_CPUMASK_OFFSTACK */
}
#ifdef CONFIG_SMP
@@ -9916,6 +9991,7 @@ struct cpuacct {
struct cgroup_subsys_state css;
/* cpuusage holds pointer to a u64-type object on every cpu */
u64 *cpuusage;
+ struct percpu_counter cpustat[CPUACCT_STAT_NSTATS];
struct cpuacct *parent;
};
@@ -9940,20 +10016,32 @@ static struct cgroup_subsys_state *cpuacct_create(
struct cgroup_subsys *ss, struct cgroup *cgrp)
{
struct cpuacct *ca = kzalloc(sizeof(*ca), GFP_KERNEL);
+ int i;
if (!ca)
- return ERR_PTR(-ENOMEM);
+ goto out;
ca->cpuusage = alloc_percpu(u64);
- if (!ca->cpuusage) {
- kfree(ca);
- return ERR_PTR(-ENOMEM);
- }
+ if (!ca->cpuusage)
+ goto out_free_ca;
+
+ for (i = 0; i < CPUACCT_STAT_NSTATS; i++)
+ if (percpu_counter_init(&ca->cpustat[i], 0))
+ goto out_free_counters;
if (cgrp->parent)
ca->parent = cgroup_ca(cgrp->parent);
return &ca->css;
+
+out_free_counters:
+ while (--i >= 0)
+ percpu_counter_destroy(&ca->cpustat[i]);
+ free_percpu(ca->cpuusage);
+out_free_ca:
+ kfree(ca);
+out:
+ return ERR_PTR(-ENOMEM);
}
/* destroy an existing cpu accounting group */
@@ -9961,7 +10049,10 @@ static void
cpuacct_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp)
{
struct cpuacct *ca = cgroup_ca(cgrp);
+ int i;
+ for (i = 0; i < CPUACCT_STAT_NSTATS; i++)
+ percpu_counter_destroy(&ca->cpustat[i]);
free_percpu(ca->cpuusage);
kfree(ca);
}
@@ -10048,6 +10139,25 @@ static int cpuacct_percpu_seq_read(struct cgroup *cgroup, struct cftype *cft,
return 0;
}
+static const char *cpuacct_stat_desc[] = {
+ [CPUACCT_STAT_USER] = "user",
+ [CPUACCT_STAT_SYSTEM] = "system",
+};
+
+static int cpuacct_stats_show(struct cgroup *cgrp, struct cftype *cft,
+ struct cgroup_map_cb *cb)
+{
+ struct cpuacct *ca = cgroup_ca(cgrp);
+ int i;
+
+ for (i = 0; i < CPUACCT_STAT_NSTATS; i++) {
+ s64 val = percpu_counter_read(&ca->cpustat[i]);
+ val = cputime64_to_clock_t(val);
+ cb->fill(cb, cpuacct_stat_desc[i], val);
+ }
+ return 0;
+}
+
static struct cftype files[] = {
{
.name = "usage",
@@ -10058,7 +10168,10 @@ static struct cftype files[] = {
.name = "usage_percpu",
.read_seq_string = cpuacct_percpu_seq_read,
},
-
+ {
+ .name = "stat",
+ .read_map = cpuacct_stats_show,
+ },
};
static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
@@ -10080,12 +10193,38 @@ static void cpuacct_charge(struct task_struct *tsk, u64 cputime)
return;
cpu = task_cpu(tsk);
+
+ rcu_read_lock();
+
ca = task_ca(tsk);
for (; ca; ca = ca->parent) {
u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu);
*cpuusage += cputime;
}
+
+ rcu_read_unlock();
+}
+
+/*
+ * Charge the system/user time to the task's accounting group.
+ */
+static void cpuacct_update_stats(struct task_struct *tsk,
+ enum cpuacct_stat_index idx, cputime_t val)
+{
+ struct cpuacct *ca;
+
+ if (unlikely(!cpuacct_subsys.active))
+ return;
+
+ rcu_read_lock();
+ ca = task_ca(tsk);
+
+ do {
+ percpu_counter_add(&ca->cpustat[idx], val);
+ ca = ca->parent;
+ } while (ca);
+ rcu_read_unlock();
}
struct cgroup_subsys cpuacct_subsys = {
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
index 390f33234bd..819f17ac796 100644
--- a/kernel/sched_clock.c
+++ b/kernel/sched_clock.c
@@ -25,6 +25,7 @@
* consistent between cpus (never more than 2 jiffies difference).
*/
#include <linux/spinlock.h>
+#include <linux/hardirq.h>
#include <linux/module.h>
#include <linux/percpu.h>
#include <linux/ktime.h>
@@ -154,6 +155,17 @@ u64 sched_clock_cpu(int cpu)
return sched_clock();
scd = cpu_sdc(cpu);
+
+ /*
+ * Normally this is not called in NMI context - but if it is,
+ * trying to do any locking here is totally lethal.
+ */
+ if (unlikely(in_nmi()))
+ return scd->clock;
+
+ if (unlikely(!sched_clock_running))
+ return 0ull;
+
WARN_ON_ONCE(!irqs_disabled());
now = sched_clock();
diff --git a/kernel/sched_cpupri.c b/kernel/sched_cpupri.c
index 1e00bfacf9b..cdd3c89574c 100644
--- a/kernel/sched_cpupri.c
+++ b/kernel/sched_cpupri.c
@@ -55,7 +55,7 @@ static int convert_prio(int prio)
* cpupri_find - find the best (lowest-pri) CPU in the system
* @cp: The cpupri context
* @p: The task
- * @lowest_mask: A mask to fill in with selected CPUs
+ * @lowest_mask: A mask to fill in with selected CPUs (or NULL)
*
* Note: This function returns the recommended CPUs as calculated during the
* current invokation. By the time the call returns, the CPUs may have in
@@ -81,7 +81,8 @@ int cpupri_find(struct cpupri *cp, struct task_struct *p,
if (cpumask_any_and(&p->cpus_allowed, vec->mask) >= nr_cpu_ids)
continue;
- cpumask_and(lowest_mask, &p->cpus_allowed, vec->mask);
+ if (lowest_mask)
+ cpumask_and(lowest_mask, &p->cpus_allowed, vec->mask);
return 1;
}
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index 299d012b439..f2c66f8f971 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -948,20 +948,15 @@ static int select_task_rq_rt(struct task_struct *p, int sync)
static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p)
{
- cpumask_var_t mask;
-
if (rq->curr->rt.nr_cpus_allowed == 1)
return;
- if (!alloc_cpumask_var(&mask, GFP_ATOMIC))
- return;
-
if (p->rt.nr_cpus_allowed != 1
- && cpupri_find(&rq->rd->cpupri, p, mask))
- goto free;
+ && cpupri_find(&rq->rd->cpupri, p, NULL))
+ return;
- if (!cpupri_find(&rq->rd->cpupri, rq->curr, mask))
- goto free;
+ if (!cpupri_find(&rq->rd->cpupri, rq->curr, NULL))
+ return;
/*
* There appears to be other cpus that can accept
@@ -970,8 +965,6 @@ static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p)
*/
requeue_task_rt(rq, p, 1);
resched_task(rq->curr);
-free:
- free_cpumask_var(mask);
}
#endif /* CONFIG_SMP */
diff --git a/kernel/slow-work.c b/kernel/slow-work.c
new file mode 100644
index 00000000000..cf2bc01186e
--- /dev/null
+++ b/kernel/slow-work.c
@@ -0,0 +1,640 @@
+/* Worker thread pool for slow items, such as filesystem lookups or mkdirs
+ *
+ * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ *
+ * See Documentation/slow-work.txt
+ */
+
+#include <linux/module.h>
+#include <linux/slow-work.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/wait.h>
+
+#define SLOW_WORK_CULL_TIMEOUT (5 * HZ) /* cull threads 5s after running out of
+ * things to do */
+#define SLOW_WORK_OOM_TIMEOUT (5 * HZ) /* can't start new threads for 5s after
+ * OOM */
+
+static void slow_work_cull_timeout(unsigned long);
+static void slow_work_oom_timeout(unsigned long);
+
+#ifdef CONFIG_SYSCTL
+static int slow_work_min_threads_sysctl(struct ctl_table *, int, struct file *,
+ void __user *, size_t *, loff_t *);
+
+static int slow_work_max_threads_sysctl(struct ctl_table *, int , struct file *,
+ void __user *, size_t *, loff_t *);
+#endif
+
+/*
+ * The pool of threads has at least min threads in it as long as someone is
+ * using the facility, and may have as many as max.
+ *
+ * A portion of the pool may be processing very slow operations.
+ */
+static unsigned slow_work_min_threads = 2;
+static unsigned slow_work_max_threads = 4;
+static unsigned vslow_work_proportion = 50; /* % of threads that may process
+ * very slow work */
+
+#ifdef CONFIG_SYSCTL
+static const int slow_work_min_min_threads = 2;
+static int slow_work_max_max_threads = 255;
+static const int slow_work_min_vslow = 1;
+static const int slow_work_max_vslow = 99;
+
+ctl_table slow_work_sysctls[] = {
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "min-threads",
+ .data = &slow_work_min_threads,
+ .maxlen = sizeof(unsigned),
+ .mode = 0644,
+ .proc_handler = slow_work_min_threads_sysctl,
+ .extra1 = (void *) &slow_work_min_min_threads,
+ .extra2 = &slow_work_max_threads,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "max-threads",
+ .data = &slow_work_max_threads,
+ .maxlen = sizeof(unsigned),
+ .mode = 0644,
+ .proc_handler = slow_work_max_threads_sysctl,
+ .extra1 = &slow_work_min_threads,
+ .extra2 = (void *) &slow_work_max_max_threads,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "vslow-percentage",
+ .data = &vslow_work_proportion,
+ .maxlen = sizeof(unsigned),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .extra1 = (void *) &slow_work_min_vslow,
+ .extra2 = (void *) &slow_work_max_vslow,
+ },
+ { .ctl_name = 0 }
+};
+#endif
+
+/*
+ * The active state of the thread pool
+ */
+static atomic_t slow_work_thread_count;
+static atomic_t vslow_work_executing_count;
+
+static bool slow_work_may_not_start_new_thread;
+static bool slow_work_cull; /* cull a thread due to lack of activity */
+static DEFINE_TIMER(slow_work_cull_timer, slow_work_cull_timeout, 0, 0);
+static DEFINE_TIMER(slow_work_oom_timer, slow_work_oom_timeout, 0, 0);
+static struct slow_work slow_work_new_thread; /* new thread starter */
+
+/*
+ * The queues of work items and the lock governing access to them. These are
+ * shared between all the CPUs. It doesn't make sense to have per-CPU queues
+ * as the number of threads bears no relation to the number of CPUs.
+ *
+ * There are two queues of work items: one for slow work items, and one for
+ * very slow work items.
+ */
+static LIST_HEAD(slow_work_queue);
+static LIST_HEAD(vslow_work_queue);
+static DEFINE_SPINLOCK(slow_work_queue_lock);
+
+/*
+ * The thread controls. A variable used to signal to the threads that they
+ * should exit when the queue is empty, a waitqueue used by the threads to wait
+ * for signals, and a completion set by the last thread to exit.
+ */
+static bool slow_work_threads_should_exit;
+static DECLARE_WAIT_QUEUE_HEAD(slow_work_thread_wq);
+static DECLARE_COMPLETION(slow_work_last_thread_exited);
+
+/*
+ * The number of users of the thread pool and its lock. Whilst this is zero we
+ * have no threads hanging around, and when this reaches zero, we wait for all
+ * active or queued work items to complete and kill all the threads we do have.
+ */
+static int slow_work_user_count;
+static DEFINE_MUTEX(slow_work_user_lock);
+
+/*
+ * Calculate the maximum number of active threads in the pool that are
+ * permitted to process very slow work items.
+ *
+ * The answer is rounded up to at least 1, but may not equal or exceed the
+ * maximum number of the threads in the pool. This means we always have at
+ * least one thread that can process slow work items, and we always have at
+ * least one thread that won't get tied up doing so.
+ */
+static unsigned slow_work_calc_vsmax(void)
+{
+ unsigned vsmax;
+
+ vsmax = atomic_read(&slow_work_thread_count) * vslow_work_proportion;
+ vsmax /= 100;
+ vsmax = max(vsmax, 1U);
+ return min(vsmax, slow_work_max_threads - 1);
+}
+
+/*
+ * Attempt to execute stuff queued on a slow thread. Return true if we managed
+ * it, false if there was nothing to do.
+ */
+static bool slow_work_execute(void)
+{
+ struct slow_work *work = NULL;
+ unsigned vsmax;
+ bool very_slow;
+
+ vsmax = slow_work_calc_vsmax();
+
+ /* see if we can schedule a new thread to be started if we're not
+ * keeping up with the work */
+ if (!waitqueue_active(&slow_work_thread_wq) &&
+ (!list_empty(&slow_work_queue) || !list_empty(&vslow_work_queue)) &&
+ atomic_read(&slow_work_thread_count) < slow_work_max_threads &&
+ !slow_work_may_not_start_new_thread)
+ slow_work_enqueue(&slow_work_new_thread);
+
+ /* find something to execute */
+ spin_lock_irq(&slow_work_queue_lock);
+ if (!list_empty(&vslow_work_queue) &&
+ atomic_read(&vslow_work_executing_count) < vsmax) {
+ work = list_entry(vslow_work_queue.next,
+ struct slow_work, link);
+ if (test_and_set_bit_lock(SLOW_WORK_EXECUTING, &work->flags))
+ BUG();
+ list_del_init(&work->link);
+ atomic_inc(&vslow_work_executing_count);
+ very_slow = true;
+ } else if (!list_empty(&slow_work_queue)) {
+ work = list_entry(slow_work_queue.next,
+ struct slow_work, link);
+ if (test_and_set_bit_lock(SLOW_WORK_EXECUTING, &work->flags))
+ BUG();
+ list_del_init(&work->link);
+ very_slow = false;
+ } else {
+ very_slow = false; /* avoid the compiler warning */
+ }
+ spin_unlock_irq(&slow_work_queue_lock);
+
+ if (!work)
+ return false;
+
+ if (!test_and_clear_bit(SLOW_WORK_PENDING, &work->flags))
+ BUG();
+
+ work->ops->execute(work);
+
+ if (very_slow)
+ atomic_dec(&vslow_work_executing_count);
+ clear_bit_unlock(SLOW_WORK_EXECUTING, &work->flags);
+
+ /* if someone tried to enqueue the item whilst we were executing it,
+ * then it'll be left unenqueued to avoid multiple threads trying to
+ * execute it simultaneously
+ *
+ * there is, however, a race between us testing the pending flag and
+ * getting the spinlock, and between the enqueuer setting the pending
+ * flag and getting the spinlock, so we use a deferral bit to tell us
+ * if the enqueuer got there first
+ */
+ if (test_bit(SLOW_WORK_PENDING, &work->flags)) {
+ spin_lock_irq(&slow_work_queue_lock);
+
+ if (!test_bit(SLOW_WORK_EXECUTING, &work->flags) &&
+ test_and_clear_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags))
+ goto auto_requeue;
+
+ spin_unlock_irq(&slow_work_queue_lock);
+ }
+
+ work->ops->put_ref(work);
+ return true;
+
+auto_requeue:
+ /* we must complete the enqueue operation
+ * - we transfer our ref on the item back to the appropriate queue
+ * - don't wake another thread up as we're awake already
+ */
+ if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags))
+ list_add_tail(&work->link, &vslow_work_queue);
+ else
+ list_add_tail(&work->link, &slow_work_queue);
+ spin_unlock_irq(&slow_work_queue_lock);
+ return true;
+}
+
+/**
+ * slow_work_enqueue - Schedule a slow work item for processing
+ * @work: The work item to queue
+ *
+ * Schedule a slow work item for processing. If the item is already undergoing
+ * execution, this guarantees not to re-enter the execution routine until the
+ * first execution finishes.
+ *
+ * The item is pinned by this function as it retains a reference to it, managed
+ * through the item operations. The item is unpinned once it has been
+ * executed.
+ *
+ * An item may hog the thread that is running it for a relatively large amount
+ * of time, sufficient, for example, to perform several lookup, mkdir, create
+ * and setxattr operations. It may sleep on I/O and may sleep to obtain locks.
+ *
+ * Conversely, if a number of items are awaiting processing, it may take some
+ * time before any given item is given attention. The number of threads in the
+ * pool may be increased to deal with demand, but only up to a limit.
+ *
+ * If SLOW_WORK_VERY_SLOW is set on the work item, then it will be placed in
+ * the very slow queue, from which only a portion of the threads will be
+ * allowed to pick items to execute. This ensures that very slow items won't
+ * overly block ones that are just ordinarily slow.
+ *
+ * Returns 0 if successful, -EAGAIN if not.
+ */
+int slow_work_enqueue(struct slow_work *work)
+{
+ unsigned long flags;
+
+ BUG_ON(slow_work_user_count <= 0);
+ BUG_ON(!work);
+ BUG_ON(!work->ops);
+ BUG_ON(!work->ops->get_ref);
+
+ /* when honouring an enqueue request, we only promise that we will run
+ * the work function in the future; we do not promise to run it once
+ * per enqueue request
+ *
+ * we use the PENDING bit to merge together repeat requests without
+ * having to disable IRQs and take the spinlock, whilst still
+ * maintaining our promise
+ */
+ if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) {
+ spin_lock_irqsave(&slow_work_queue_lock, flags);
+
+ /* we promise that we will not attempt to execute the work
+ * function in more than one thread simultaneously
+ *
+ * this, however, leaves us with a problem if we're asked to
+ * enqueue the work whilst someone is executing the work
+ * function as simply queueing the work immediately means that
+ * another thread may try executing it whilst it is already
+ * under execution
+ *
+ * to deal with this, we set the ENQ_DEFERRED bit instead of
+ * enqueueing, and the thread currently executing the work
+ * function will enqueue the work item when the work function
+ * returns and it has cleared the EXECUTING bit
+ */
+ if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) {
+ set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags);
+ } else {
+ if (work->ops->get_ref(work) < 0)
+ goto cant_get_ref;
+ if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags))
+ list_add_tail(&work->link, &vslow_work_queue);
+ else
+ list_add_tail(&work->link, &slow_work_queue);
+ wake_up(&slow_work_thread_wq);
+ }
+
+ spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+ }
+ return 0;
+
+cant_get_ref:
+ spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+ return -EAGAIN;
+}
+EXPORT_SYMBOL(slow_work_enqueue);
+
+/*
+ * Worker thread culling algorithm
+ */
+static bool slow_work_cull_thread(void)
+{
+ unsigned long flags;
+ bool do_cull = false;
+
+ spin_lock_irqsave(&slow_work_queue_lock, flags);
+
+ if (slow_work_cull) {
+ slow_work_cull = false;
+
+ if (list_empty(&slow_work_queue) &&
+ list_empty(&vslow_work_queue) &&
+ atomic_read(&slow_work_thread_count) >
+ slow_work_min_threads) {
+ mod_timer(&slow_work_cull_timer,
+ jiffies + SLOW_WORK_CULL_TIMEOUT);
+ do_cull = true;
+ }
+ }
+
+ spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+ return do_cull;
+}
+
+/*
+ * Determine if there is slow work available for dispatch
+ */
+static inline bool slow_work_available(int vsmax)
+{
+ return !list_empty(&slow_work_queue) ||
+ (!list_empty(&vslow_work_queue) &&
+ atomic_read(&vslow_work_executing_count) < vsmax);
+}
+
+/*
+ * Worker thread dispatcher
+ */
+static int slow_work_thread(void *_data)
+{
+ int vsmax;
+
+ DEFINE_WAIT(wait);
+
+ set_freezable();
+ set_user_nice(current, -5);
+
+ for (;;) {
+ vsmax = vslow_work_proportion;
+ vsmax *= atomic_read(&slow_work_thread_count);
+ vsmax /= 100;
+
+ prepare_to_wait(&slow_work_thread_wq, &wait,
+ TASK_INTERRUPTIBLE);
+ if (!freezing(current) &&
+ !slow_work_threads_should_exit &&
+ !slow_work_available(vsmax) &&
+ !slow_work_cull)
+ schedule();
+ finish_wait(&slow_work_thread_wq, &wait);
+
+ try_to_freeze();
+
+ vsmax = vslow_work_proportion;
+ vsmax *= atomic_read(&slow_work_thread_count);
+ vsmax /= 100;
+
+ if (slow_work_available(vsmax) && slow_work_execute()) {
+ cond_resched();
+ if (list_empty(&slow_work_queue) &&
+ list_empty(&vslow_work_queue) &&
+ atomic_read(&slow_work_thread_count) >
+ slow_work_min_threads)
+ mod_timer(&slow_work_cull_timer,
+ jiffies + SLOW_WORK_CULL_TIMEOUT);
+ continue;
+ }
+
+ if (slow_work_threads_should_exit)
+ break;
+
+ if (slow_work_cull && slow_work_cull_thread())
+ break;
+ }
+
+ if (atomic_dec_and_test(&slow_work_thread_count))
+ complete_and_exit(&slow_work_last_thread_exited, 0);
+ return 0;
+}
+
+/*
+ * Handle thread cull timer expiration
+ */
+static void slow_work_cull_timeout(unsigned long data)
+{
+ slow_work_cull = true;
+ wake_up(&slow_work_thread_wq);
+}
+
+/*
+ * Get a reference on slow work thread starter
+ */
+static int slow_work_new_thread_get_ref(struct slow_work *work)
+{
+ return 0;
+}
+
+/*
+ * Drop a reference on slow work thread starter
+ */
+static void slow_work_new_thread_put_ref(struct slow_work *work)
+{
+}
+
+/*
+ * Start a new slow work thread
+ */
+static void slow_work_new_thread_execute(struct slow_work *work)
+{
+ struct task_struct *p;
+
+ if (slow_work_threads_should_exit)
+ return;
+
+ if (atomic_read(&slow_work_thread_count) >= slow_work_max_threads)
+ return;
+
+ if (!mutex_trylock(&slow_work_user_lock))
+ return;
+
+ slow_work_may_not_start_new_thread = true;
+ atomic_inc(&slow_work_thread_count);
+ p = kthread_run(slow_work_thread, NULL, "kslowd");
+ if (IS_ERR(p)) {
+ printk(KERN_DEBUG "Slow work thread pool: OOM\n");
+ if (atomic_dec_and_test(&slow_work_thread_count))
+ BUG(); /* we're running on a slow work thread... */
+ mod_timer(&slow_work_oom_timer,
+ jiffies + SLOW_WORK_OOM_TIMEOUT);
+ } else {
+ /* ratelimit the starting of new threads */
+ mod_timer(&slow_work_oom_timer, jiffies + 1);
+ }
+
+ mutex_unlock(&slow_work_user_lock);
+}
+
+static const struct slow_work_ops slow_work_new_thread_ops = {
+ .get_ref = slow_work_new_thread_get_ref,
+ .put_ref = slow_work_new_thread_put_ref,
+ .execute = slow_work_new_thread_execute,
+};
+
+/*
+ * post-OOM new thread start suppression expiration
+ */
+static void slow_work_oom_timeout(unsigned long data)
+{
+ slow_work_may_not_start_new_thread = false;
+}
+
+#ifdef CONFIG_SYSCTL
+/*
+ * Handle adjustment of the minimum number of threads
+ */
+static int slow_work_min_threads_sysctl(struct ctl_table *table, int write,
+ struct file *filp, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
+{
+ int ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos);
+ int n;
+
+ if (ret == 0) {
+ mutex_lock(&slow_work_user_lock);
+ if (slow_work_user_count > 0) {
+ /* see if we need to start or stop threads */
+ n = atomic_read(&slow_work_thread_count) -
+ slow_work_min_threads;
+
+ if (n < 0 && !slow_work_may_not_start_new_thread)
+ slow_work_enqueue(&slow_work_new_thread);
+ else if (n > 0)
+ mod_timer(&slow_work_cull_timer,
+ jiffies + SLOW_WORK_CULL_TIMEOUT);
+ }
+ mutex_unlock(&slow_work_user_lock);
+ }
+
+ return ret;
+}
+
+/*
+ * Handle adjustment of the maximum number of threads
+ */
+static int slow_work_max_threads_sysctl(struct ctl_table *table, int write,
+ struct file *filp, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
+{
+ int ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos);
+ int n;
+
+ if (ret == 0) {
+ mutex_lock(&slow_work_user_lock);
+ if (slow_work_user_count > 0) {
+ /* see if we need to stop threads */
+ n = slow_work_max_threads -
+ atomic_read(&slow_work_thread_count);
+
+ if (n < 0)
+ mod_timer(&slow_work_cull_timer,
+ jiffies + SLOW_WORK_CULL_TIMEOUT);
+ }
+ mutex_unlock(&slow_work_user_lock);
+ }
+
+ return ret;
+}
+#endif /* CONFIG_SYSCTL */
+
+/**
+ * slow_work_register_user - Register a user of the facility
+ *
+ * Register a user of the facility, starting up the initial threads if there
+ * aren't any other users at this point. This will return 0 if successful, or
+ * an error if not.
+ */
+int slow_work_register_user(void)
+{
+ struct task_struct *p;
+ int loop;
+
+ mutex_lock(&slow_work_user_lock);
+
+ if (slow_work_user_count == 0) {
+ printk(KERN_NOTICE "Slow work thread pool: Starting up\n");
+ init_completion(&slow_work_last_thread_exited);
+
+ slow_work_threads_should_exit = false;
+ slow_work_init(&slow_work_new_thread,
+ &slow_work_new_thread_ops);
+ slow_work_may_not_start_new_thread = false;
+ slow_work_cull = false;
+
+ /* start the minimum number of threads */
+ for (loop = 0; loop < slow_work_min_threads; loop++) {
+ atomic_inc(&slow_work_thread_count);
+ p = kthread_run(slow_work_thread, NULL, "kslowd");
+ if (IS_ERR(p))
+ goto error;
+ }
+ printk(KERN_NOTICE "Slow work thread pool: Ready\n");
+ }
+
+ slow_work_user_count++;
+ mutex_unlock(&slow_work_user_lock);
+ return 0;
+
+error:
+ if (atomic_dec_and_test(&slow_work_thread_count))
+ complete(&slow_work_last_thread_exited);
+ if (loop > 0) {
+ printk(KERN_ERR "Slow work thread pool:"
+ " Aborting startup on ENOMEM\n");
+ slow_work_threads_should_exit = true;
+ wake_up_all(&slow_work_thread_wq);
+ wait_for_completion(&slow_work_last_thread_exited);
+ printk(KERN_ERR "Slow work thread pool: Aborted\n");
+ }
+ mutex_unlock(&slow_work_user_lock);
+ return PTR_ERR(p);
+}
+EXPORT_SYMBOL(slow_work_register_user);
+
+/**
+ * slow_work_unregister_user - Unregister a user of the facility
+ *
+ * Unregister a user of the facility, killing all the threads if this was the
+ * last one.
+ */
+void slow_work_unregister_user(void)
+{
+ mutex_lock(&slow_work_user_lock);
+
+ BUG_ON(slow_work_user_count <= 0);
+
+ slow_work_user_count--;
+ if (slow_work_user_count == 0) {
+ printk(KERN_NOTICE "Slow work thread pool: Shutting down\n");
+ slow_work_threads_should_exit = true;
+ wake_up_all(&slow_work_thread_wq);
+ wait_for_completion(&slow_work_last_thread_exited);
+ printk(KERN_NOTICE "Slow work thread pool:"
+ " Shut down complete\n");
+ }
+
+ del_timer_sync(&slow_work_cull_timer);
+
+ mutex_unlock(&slow_work_user_lock);
+}
+EXPORT_SYMBOL(slow_work_unregister_user);
+
+/*
+ * Initialise the slow work facility
+ */
+static int __init init_slow_work(void)
+{
+ unsigned nr_cpus = num_possible_cpus();
+
+ if (slow_work_max_threads < nr_cpus)
+ slow_work_max_threads = nr_cpus;
+#ifdef CONFIG_SYSCTL
+ if (slow_work_max_max_threads < nr_cpus * 2)
+ slow_work_max_max_threads = nr_cpus * 2;
+#endif
+ return 0;
+}
+
+subsys_initcall(init_slow_work);
diff --git a/kernel/smp.c b/kernel/smp.c
index bbedbb7efe3..858baac568e 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -2,40 +2,82 @@
* Generic helpers for smp ipi calls
*
* (C) Jens Axboe <jens.axboe@oracle.com> 2008
- *
*/
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/percpu.h>
#include <linux/rcupdate.h>
#include <linux/rculist.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/init.h>
#include <linux/smp.h>
+#include <linux/cpu.h>
static DEFINE_PER_CPU(struct call_single_queue, call_single_queue);
-static LIST_HEAD(call_function_queue);
-__cacheline_aligned_in_smp DEFINE_SPINLOCK(call_function_lock);
+
+static struct {
+ struct list_head queue;
+ spinlock_t lock;
+} call_function __cacheline_aligned_in_smp =
+ {
+ .queue = LIST_HEAD_INIT(call_function.queue),
+ .lock = __SPIN_LOCK_UNLOCKED(call_function.lock),
+ };
enum {
- CSD_FLAG_WAIT = 0x01,
- CSD_FLAG_ALLOC = 0x02,
- CSD_FLAG_LOCK = 0x04,
+ CSD_FLAG_LOCK = 0x01,
};
struct call_function_data {
- struct call_single_data csd;
- spinlock_t lock;
- unsigned int refs;
- struct rcu_head rcu_head;
- unsigned long cpumask_bits[];
+ struct call_single_data csd;
+ spinlock_t lock;
+ unsigned int refs;
+ cpumask_var_t cpumask;
};
struct call_single_queue {
- struct list_head list;
- spinlock_t lock;
+ struct list_head list;
+ spinlock_t lock;
+};
+
+static DEFINE_PER_CPU(struct call_function_data, cfd_data) = {
+ .lock = __SPIN_LOCK_UNLOCKED(cfd_data.lock),
+};
+
+static int
+hotplug_cfd(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+ long cpu = (long)hcpu;
+ struct call_function_data *cfd = &per_cpu(cfd_data, cpu);
+
+ switch (action) {
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ if (!alloc_cpumask_var_node(&cfd->cpumask, GFP_KERNEL,
+ cpu_to_node(cpu)))
+ return NOTIFY_BAD;
+ break;
+
+#ifdef CONFIG_CPU_HOTPLUG
+ case CPU_UP_CANCELED:
+ case CPU_UP_CANCELED_FROZEN:
+
+ case CPU_DEAD:
+ case CPU_DEAD_FROZEN:
+ free_cpumask_var(cfd->cpumask);
+ break;
+#endif
+ };
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata hotplug_cfd_notifier = {
+ .notifier_call = hotplug_cfd,
};
static int __cpuinit init_call_single_data(void)
{
+ void *cpu = (void *)(long)smp_processor_id();
int i;
for_each_possible_cpu(i) {
@@ -44,29 +86,63 @@ static int __cpuinit init_call_single_data(void)
spin_lock_init(&q->lock);
INIT_LIST_HEAD(&q->list);
}
+
+ hotplug_cfd(&hotplug_cfd_notifier, CPU_UP_PREPARE, cpu);
+ register_cpu_notifier(&hotplug_cfd_notifier);
+
return 0;
}
early_initcall(init_call_single_data);
-static void csd_flag_wait(struct call_single_data *data)
+/*
+ * csd_lock/csd_unlock used to serialize access to per-cpu csd resources
+ *
+ * For non-synchronous ipi calls the csd can still be in use by the
+ * previous function call. For multi-cpu calls its even more interesting
+ * as we'll have to ensure no other cpu is observing our csd.
+ */
+static void csd_lock_wait(struct call_single_data *data)
{
- /* Wait for response */
- do {
- if (!(data->flags & CSD_FLAG_WAIT))
- break;
+ while (data->flags & CSD_FLAG_LOCK)
cpu_relax();
- } while (1);
+}
+
+static void csd_lock(struct call_single_data *data)
+{
+ csd_lock_wait(data);
+ data->flags = CSD_FLAG_LOCK;
+
+ /*
+ * prevent CPU from reordering the above assignment
+ * to ->flags with any subsequent assignments to other
+ * fields of the specified call_single_data structure:
+ */
+ smp_mb();
+}
+
+static void csd_unlock(struct call_single_data *data)
+{
+ WARN_ON(!(data->flags & CSD_FLAG_LOCK));
+
+ /*
+ * ensure we're all done before releasing data:
+ */
+ smp_mb();
+
+ data->flags &= ~CSD_FLAG_LOCK;
}
/*
- * Insert a previously allocated call_single_data element for execution
- * on the given CPU. data must already have ->func, ->info, and ->flags set.
+ * Insert a previously allocated call_single_data element
+ * for execution on the given CPU. data must already have
+ * ->func, ->info, and ->flags set.
*/
-static void generic_exec_single(int cpu, struct call_single_data *data)
+static
+void generic_exec_single(int cpu, struct call_single_data *data, int wait)
{
struct call_single_queue *dst = &per_cpu(call_single_queue, cpu);
- int wait = data->flags & CSD_FLAG_WAIT, ipi;
unsigned long flags;
+ int ipi;
spin_lock_irqsave(&dst->lock, flags);
ipi = list_empty(&dst->list);
@@ -74,24 +150,21 @@ static void generic_exec_single(int cpu, struct call_single_data *data)
spin_unlock_irqrestore(&dst->lock, flags);
/*
- * Make the list addition visible before sending the ipi.
+ * The list addition should be visible before sending the IPI
+ * handler locks the list to pull the entry off it because of
+ * normal cache coherency rules implied by spinlocks.
+ *
+ * If IPIs can go out of order to the cache coherency protocol
+ * in an architecture, sufficient synchronisation should be added
+ * to arch code to make it appear to obey cache coherency WRT
+ * locking and barrier primitives. Generic code isn't really
+ * equipped to do the right thing...
*/
- smp_mb();
-
if (ipi)
arch_send_call_function_single_ipi(cpu);
if (wait)
- csd_flag_wait(data);
-}
-
-static void rcu_free_call_data(struct rcu_head *head)
-{
- struct call_function_data *data;
-
- data = container_of(head, struct call_function_data, rcu_head);
-
- kfree(data);
+ csd_lock_wait(data);
}
/*
@@ -104,99 +177,83 @@ void generic_smp_call_function_interrupt(void)
int cpu = get_cpu();
/*
- * It's ok to use list_for_each_rcu() here even though we may delete
- * 'pos', since list_del_rcu() doesn't clear ->next
+ * Ensure entry is visible on call_function_queue after we have
+ * entered the IPI. See comment in smp_call_function_many.
+ * If we don't have this, then we may miss an entry on the list
+ * and never get another IPI to process it.
+ */
+ smp_mb();
+
+ /*
+ * It's ok to use list_for_each_rcu() here even though we may
+ * delete 'pos', since list_del_rcu() doesn't clear ->next
*/
- rcu_read_lock();
- list_for_each_entry_rcu(data, &call_function_queue, csd.list) {
+ list_for_each_entry_rcu(data, &call_function.queue, csd.list) {
int refs;
- if (!cpumask_test_cpu(cpu, to_cpumask(data->cpumask_bits)))
+ spin_lock(&data->lock);
+ if (!cpumask_test_cpu(cpu, data->cpumask)) {
+ spin_unlock(&data->lock);
continue;
+ }
+ cpumask_clear_cpu(cpu, data->cpumask);
+ spin_unlock(&data->lock);
data->csd.func(data->csd.info);
spin_lock(&data->lock);
- cpumask_clear_cpu(cpu, to_cpumask(data->cpumask_bits));
WARN_ON(data->refs == 0);
- data->refs--;
- refs = data->refs;
+ refs = --data->refs;
+ if (!refs) {
+ spin_lock(&call_function.lock);
+ list_del_rcu(&data->csd.list);
+ spin_unlock(&call_function.lock);
+ }
spin_unlock(&data->lock);
if (refs)
continue;
- spin_lock(&call_function_lock);
- list_del_rcu(&data->csd.list);
- spin_unlock(&call_function_lock);
-
- if (data->csd.flags & CSD_FLAG_WAIT) {
- /*
- * serialize stores to data with the flag clear
- * and wakeup
- */
- smp_wmb();
- data->csd.flags &= ~CSD_FLAG_WAIT;
- }
- if (data->csd.flags & CSD_FLAG_ALLOC)
- call_rcu(&data->rcu_head, rcu_free_call_data);
+ csd_unlock(&data->csd);
}
- rcu_read_unlock();
put_cpu();
}
/*
- * Invoked by arch to handle an IPI for call function single. Must be called
- * from the arch with interrupts disabled.
+ * Invoked by arch to handle an IPI for call function single. Must be
+ * called from the arch with interrupts disabled.
*/
void generic_smp_call_function_single_interrupt(void)
{
struct call_single_queue *q = &__get_cpu_var(call_single_queue);
+ unsigned int data_flags;
LIST_HEAD(list);
- /*
- * Need to see other stores to list head for checking whether
- * list is empty without holding q->lock
- */
- smp_read_barrier_depends();
- while (!list_empty(&q->list)) {
- unsigned int data_flags;
-
- spin_lock(&q->lock);
- list_replace_init(&q->list, &list);
- spin_unlock(&q->lock);
-
- while (!list_empty(&list)) {
- struct call_single_data *data;
-
- data = list_entry(list.next, struct call_single_data,
- list);
- list_del(&data->list);
-
- /*
- * 'data' can be invalid after this call if
- * flags == 0 (when called through
- * generic_exec_single(), so save them away before
- * making the call.
- */
- data_flags = data->flags;
-
- data->func(data->info);
-
- if (data_flags & CSD_FLAG_WAIT) {
- smp_wmb();
- data->flags &= ~CSD_FLAG_WAIT;
- } else if (data_flags & CSD_FLAG_LOCK) {
- smp_wmb();
- data->flags &= ~CSD_FLAG_LOCK;
- } else if (data_flags & CSD_FLAG_ALLOC)
- kfree(data);
- }
+ spin_lock(&q->lock);
+ list_replace_init(&q->list, &list);
+ spin_unlock(&q->lock);
+
+ while (!list_empty(&list)) {
+ struct call_single_data *data;
+
+ data = list_entry(list.next, struct call_single_data, list);
+ list_del(&data->list);
+
+ /*
+ * 'data' can be invalid after this call if flags == 0
+ * (when called through generic_exec_single()),
+ * so save them away before making the call:
+ */
+ data_flags = data->flags;
+
+ data->func(data->info);
+
/*
- * See comment on outer loop
+ * Unlocked CSDs are valid through generic_exec_single():
*/
- smp_read_barrier_depends();
+ if (data_flags & CSD_FLAG_LOCK)
+ csd_unlock(data);
}
}
@@ -215,65 +272,45 @@ static DEFINE_PER_CPU(struct call_single_data, csd_data);
int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
int wait)
{
- struct call_single_data d;
+ struct call_single_data d = {
+ .flags = 0,
+ };
unsigned long flags;
- /* prevent preemption and reschedule on another processor,
- as well as CPU removal */
- int me = get_cpu();
+ int this_cpu;
int err = 0;
+ /*
+ * prevent preemption and reschedule on another processor,
+ * as well as CPU removal
+ */
+ this_cpu = get_cpu();
+
/* Can deadlock when called with interrupts disabled */
- WARN_ON(irqs_disabled());
+ WARN_ON_ONCE(irqs_disabled() && !oops_in_progress);
- if (cpu == me) {
+ if (cpu == this_cpu) {
local_irq_save(flags);
func(info);
local_irq_restore(flags);
- } else if ((unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) {
- struct call_single_data *data;
+ } else {
+ if ((unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) {
+ struct call_single_data *data = &d;
+
+ if (!wait)
+ data = &__get_cpu_var(csd_data);
- if (!wait) {
- /*
- * We are calling a function on a single CPU
- * and we are not going to wait for it to finish.
- * We first try to allocate the data, but if we
- * fail, we fall back to use a per cpu data to pass
- * the information to that CPU. Since all callers
- * of this code will use the same data, we must
- * synchronize the callers to prevent a new caller
- * from corrupting the data before the callee
- * can access it.
- *
- * The CSD_FLAG_LOCK is used to let us know when
- * the IPI handler is done with the data.
- * The first caller will set it, and the callee
- * will clear it. The next caller must wait for
- * it to clear before we set it again. This
- * will make sure the callee is done with the
- * data before a new caller will use it.
- */
- data = kmalloc(sizeof(*data), GFP_ATOMIC);
- if (data)
- data->flags = CSD_FLAG_ALLOC;
- else {
- data = &per_cpu(csd_data, me);
- while (data->flags & CSD_FLAG_LOCK)
- cpu_relax();
- data->flags = CSD_FLAG_LOCK;
- }
+ csd_lock(data);
+
+ data->func = func;
+ data->info = info;
+ generic_exec_single(cpu, data, wait);
} else {
- data = &d;
- data->flags = CSD_FLAG_WAIT;
+ err = -ENXIO; /* CPU not online */
}
-
- data->func = func;
- data->info = info;
- generic_exec_single(cpu, data);
- } else {
- err = -ENXIO; /* CPU not online */
}
put_cpu();
+
return err;
}
EXPORT_SYMBOL(smp_call_function_single);
@@ -283,23 +320,26 @@ EXPORT_SYMBOL(smp_call_function_single);
* @cpu: The CPU to run on.
* @data: Pre-allocated and setup data structure
*
- * Like smp_call_function_single(), but allow caller to pass in a pre-allocated
- * data structure. Useful for embedding @data inside other structures, for
- * instance.
- *
+ * Like smp_call_function_single(), but allow caller to pass in a
+ * pre-allocated data structure. Useful for embedding @data inside
+ * other structures, for instance.
*/
-void __smp_call_function_single(int cpu, struct call_single_data *data)
+void __smp_call_function_single(int cpu, struct call_single_data *data,
+ int wait)
{
+ csd_lock(data);
+
/* Can deadlock when called with interrupts disabled */
- WARN_ON((data->flags & CSD_FLAG_WAIT) && irqs_disabled());
+ WARN_ON_ONCE(wait && irqs_disabled() && !oops_in_progress);
- generic_exec_single(cpu, data);
+ generic_exec_single(cpu, data, wait);
}
-/* FIXME: Shim for archs using old arch_send_call_function_ipi API. */
+/* Deprecated: shim for archs using old arch_send_call_function_ipi API. */
+
#ifndef arch_send_call_function_ipi_mask
-#define arch_send_call_function_ipi_mask(maskp) \
- arch_send_call_function_ipi(*(maskp))
+# define arch_send_call_function_ipi_mask(maskp) \
+ arch_send_call_function_ipi(*(maskp))
#endif
/**
@@ -307,7 +347,8 @@ void __smp_call_function_single(int cpu, struct call_single_data *data)
* @mask: The set of cpus to run on (only runs on online subset).
* @func: The function to run. This must be fast and non-blocking.
* @info: An arbitrary pointer to pass to the function.
- * @wait: If true, wait (atomically) until function has completed on other CPUs.
+ * @wait: If true, wait (atomically) until function has completed
+ * on other CPUs.
*
* If @wait is true, then returns once @func has returned. Note that @wait
* will be implicitly turned on in case of allocation failures, since
@@ -318,27 +359,27 @@ void __smp_call_function_single(int cpu, struct call_single_data *data)
* must be disabled when calling this function.
*/
void smp_call_function_many(const struct cpumask *mask,
- void (*func)(void *), void *info,
- bool wait)
+ void (*func)(void *), void *info, bool wait)
{
struct call_function_data *data;
unsigned long flags;
- int cpu, next_cpu;
+ int cpu, next_cpu, this_cpu = smp_processor_id();
/* Can deadlock when called with interrupts disabled */
- WARN_ON(irqs_disabled());
+ WARN_ON_ONCE(irqs_disabled() && !oops_in_progress);
- /* So, what's a CPU they want? Ignoring this one. */
+ /* So, what's a CPU they want? Ignoring this one. */
cpu = cpumask_first_and(mask, cpu_online_mask);
- if (cpu == smp_processor_id())
+ if (cpu == this_cpu)
cpu = cpumask_next_and(cpu, mask, cpu_online_mask);
+
/* No online cpus? We're done. */
if (cpu >= nr_cpu_ids)
return;
/* Do we have another CPU which isn't us? */
next_cpu = cpumask_next_and(cpu, mask, cpu_online_mask);
- if (next_cpu == smp_processor_id())
+ if (next_cpu == this_cpu)
next_cpu = cpumask_next_and(next_cpu, mask, cpu_online_mask);
/* Fastpath: do that cpu by itself. */
@@ -347,43 +388,40 @@ void smp_call_function_many(const struct cpumask *mask,
return;
}
- data = kmalloc(sizeof(*data) + cpumask_size(), GFP_ATOMIC);
- if (unlikely(!data)) {
- /* Slow path. */
- for_each_online_cpu(cpu) {
- if (cpu == smp_processor_id())
- continue;
- if (cpumask_test_cpu(cpu, mask))
- smp_call_function_single(cpu, func, info, wait);
- }
- return;
- }
+ data = &__get_cpu_var(cfd_data);
+ csd_lock(&data->csd);
- spin_lock_init(&data->lock);
- data->csd.flags = CSD_FLAG_ALLOC;
- if (wait)
- data->csd.flags |= CSD_FLAG_WAIT;
+ spin_lock_irqsave(&data->lock, flags);
data->csd.func = func;
data->csd.info = info;
- cpumask_and(to_cpumask(data->cpumask_bits), mask, cpu_online_mask);
- cpumask_clear_cpu(smp_processor_id(), to_cpumask(data->cpumask_bits));
- data->refs = cpumask_weight(to_cpumask(data->cpumask_bits));
+ cpumask_and(data->cpumask, mask, cpu_online_mask);
+ cpumask_clear_cpu(this_cpu, data->cpumask);
+ data->refs = cpumask_weight(data->cpumask);
- spin_lock_irqsave(&call_function_lock, flags);
- list_add_tail_rcu(&data->csd.list, &call_function_queue);
- spin_unlock_irqrestore(&call_function_lock, flags);
+ spin_lock(&call_function.lock);
+ /*
+ * Place entry at the _HEAD_ of the list, so that any cpu still
+ * observing the entry in generic_smp_call_function_interrupt()
+ * will not miss any other list entries:
+ */
+ list_add_rcu(&data->csd.list, &call_function.queue);
+ spin_unlock(&call_function.lock);
+
+ spin_unlock_irqrestore(&data->lock, flags);
/*
* Make the list addition visible before sending the ipi.
+ * (IPIs must obey or appear to obey normal Linux cache
+ * coherency rules -- see comment in generic_exec_single).
*/
smp_mb();
/* Send a message to all CPUs in the map */
- arch_send_call_function_ipi_mask(to_cpumask(data->cpumask_bits));
+ arch_send_call_function_ipi_mask(data->cpumask);
- /* optionally wait for the CPUs to complete */
+ /* Optionally wait for the CPUs to complete */
if (wait)
- csd_flag_wait(&data->csd);
+ csd_lock_wait(&data->csd);
}
EXPORT_SYMBOL(smp_call_function_many);
@@ -391,7 +429,8 @@ EXPORT_SYMBOL(smp_call_function_many);
* smp_call_function(): Run a function on all other CPUs.
* @func: The function to run. This must be fast and non-blocking.
* @info: An arbitrary pointer to pass to the function.
- * @wait: If true, wait (atomically) until function has completed on other CPUs.
+ * @wait: If true, wait (atomically) until function has completed
+ * on other CPUs.
*
* Returns 0.
*
@@ -407,26 +446,27 @@ int smp_call_function(void (*func)(void *), void *info, int wait)
preempt_disable();
smp_call_function_many(cpu_online_mask, func, info, wait);
preempt_enable();
+
return 0;
}
EXPORT_SYMBOL(smp_call_function);
void ipi_call_lock(void)
{
- spin_lock(&call_function_lock);
+ spin_lock(&call_function.lock);
}
void ipi_call_unlock(void)
{
- spin_unlock(&call_function_lock);
+ spin_unlock(&call_function.lock);
}
void ipi_call_lock_irq(void)
{
- spin_lock_irq(&call_function_lock);
+ spin_lock_irq(&call_function.lock);
}
void ipi_call_unlock_irq(void)
{
- spin_unlock_irq(&call_function_lock);
+ spin_unlock_irq(&call_function.lock);
}
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 57d3f67f6f3..2fecefacdc5 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -21,8 +21,10 @@
#include <linux/freezer.h>
#include <linux/kthread.h>
#include <linux/rcupdate.h>
+#include <linux/ftrace.h>
#include <linux/smp.h>
#include <linux/tick.h>
+#include <trace/irq.h>
#include <asm/irq.h>
/*
@@ -52,13 +54,18 @@ static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp
static DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
+char *softirq_to_name[NR_SOFTIRQS] = {
+ "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK",
+ "TASKLET", "SCHED", "HRTIMER", "RCU"
+};
+
/*
* we cannot loop indefinitely here to avoid userspace starvation,
* but we also don't want to introduce a worst case 1/HZ latency
* to the pending events, so lets the scheduler to balance
* the softirq load for us.
*/
-static inline void wakeup_softirqd(void)
+void wakeup_softirqd(void)
{
/* Interrupts are disabled: no need to stop preemption */
struct task_struct *tsk = __get_cpu_var(ksoftirqd);
@@ -79,13 +86,23 @@ static void __local_bh_disable(unsigned long ip)
WARN_ON_ONCE(in_irq());
raw_local_irq_save(flags);
- add_preempt_count(SOFTIRQ_OFFSET);
+ /*
+ * The preempt tracer hooks into add_preempt_count and will break
+ * lockdep because it calls back into lockdep after SOFTIRQ_OFFSET
+ * is set and before current->softirq_enabled is cleared.
+ * We must manually increment preempt_count here and manually
+ * call the trace_preempt_off later.
+ */
+ preempt_count() += SOFTIRQ_OFFSET;
/*
* Were softirqs turned off above:
*/
if (softirq_count() == SOFTIRQ_OFFSET)
trace_softirqs_off(ip);
raw_local_irq_restore(flags);
+
+ if (preempt_count() == SOFTIRQ_OFFSET)
+ trace_preempt_off(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1));
}
#else /* !CONFIG_TRACE_IRQFLAGS */
static inline void __local_bh_disable(unsigned long ip)
@@ -169,6 +186,9 @@ EXPORT_SYMBOL(local_bh_enable_ip);
*/
#define MAX_SOFTIRQ_RESTART 10
+DEFINE_TRACE(softirq_entry);
+DEFINE_TRACE(softirq_exit);
+
asmlinkage void __do_softirq(void)
{
struct softirq_action *h;
@@ -180,7 +200,7 @@ asmlinkage void __do_softirq(void)
account_system_vtime(current);
__local_bh_disable((unsigned long)__builtin_return_address(0));
- trace_softirq_enter();
+ lockdep_softirq_enter();
cpu = smp_processor_id();
restart:
@@ -195,12 +215,14 @@ restart:
if (pending & 1) {
int prev_count = preempt_count();
+ trace_softirq_entry(h, softirq_vec);
h->action(h);
-
+ trace_softirq_exit(h, softirq_vec);
if (unlikely(prev_count != preempt_count())) {
- printk(KERN_ERR "huh, entered softirq %td %p"
+ printk(KERN_ERR "huh, entered softirq %td %s %p"
"with preempt_count %08x,"
" exited with %08x?\n", h - softirq_vec,
+ softirq_to_name[h - softirq_vec],
h->action, prev_count, preempt_count());
preempt_count() = prev_count;
}
@@ -220,7 +242,7 @@ restart:
if (pending)
wakeup_softirqd();
- trace_softirq_exit();
+ lockdep_softirq_exit();
account_system_vtime(current);
_local_bh_enable();
@@ -496,7 +518,7 @@ static int __try_remote_softirq(struct call_single_data *cp, int cpu, int softir
cp->flags = 0;
cp->priv = softirq;
- __smp_call_function_single(cpu, cp);
+ __smp_call_function_single(cpu, cp, 0);
return 0;
}
return 1;
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index 85d5a245510..88796c33083 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -166,97 +166,11 @@ void softlockup_tick(void)
}
/*
- * Have a reasonable limit on the number of tasks checked:
- */
-unsigned long __read_mostly sysctl_hung_task_check_count = 1024;
-
-/*
- * Zero means infinite timeout - no checking done:
- */
-unsigned long __read_mostly sysctl_hung_task_timeout_secs = 480;
-
-unsigned long __read_mostly sysctl_hung_task_warnings = 10;
-
-/*
- * Only do the hung-tasks check on one CPU:
- */
-static int check_cpu __read_mostly = -1;
-
-static void check_hung_task(struct task_struct *t, unsigned long now)
-{
- unsigned long switch_count = t->nvcsw + t->nivcsw;
-
- if (t->flags & PF_FROZEN)
- return;
-
- if (switch_count != t->last_switch_count || !t->last_switch_timestamp) {
- t->last_switch_count = switch_count;
- t->last_switch_timestamp = now;
- return;
- }
- if ((long)(now - t->last_switch_timestamp) <
- sysctl_hung_task_timeout_secs)
- return;
- if (!sysctl_hung_task_warnings)
- return;
- sysctl_hung_task_warnings--;
-
- /*
- * Ok, the task did not get scheduled for more than 2 minutes,
- * complain:
- */
- printk(KERN_ERR "INFO: task %s:%d blocked for more than "
- "%ld seconds.\n", t->comm, t->pid,
- sysctl_hung_task_timeout_secs);
- printk(KERN_ERR "\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\""
- " disables this message.\n");
- sched_show_task(t);
- __debug_show_held_locks(t);
-
- t->last_switch_timestamp = now;
- touch_nmi_watchdog();
-
- if (softlockup_panic)
- panic("softlockup: blocked tasks");
-}
-
-/*
- * Check whether a TASK_UNINTERRUPTIBLE does not get woken up for
- * a really long time (120 seconds). If that happens, print out
- * a warning.
- */
-static void check_hung_uninterruptible_tasks(int this_cpu)
-{
- int max_count = sysctl_hung_task_check_count;
- unsigned long now = get_timestamp(this_cpu);
- struct task_struct *g, *t;
-
- /*
- * If the system crashed already then all bets are off,
- * do not report extra hung tasks:
- */
- if (test_taint(TAINT_DIE) || did_panic)
- return;
-
- read_lock(&tasklist_lock);
- do_each_thread(g, t) {
- if (!--max_count)
- goto unlock;
- /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */
- if (t->state == TASK_UNINTERRUPTIBLE)
- check_hung_task(t, now);
- } while_each_thread(g, t);
- unlock:
- read_unlock(&tasklist_lock);
-}
-
-/*
* The watchdog thread - runs every second and touches the timestamp.
*/
static int watchdog(void *__bind_cpu)
{
struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
- int this_cpu = (long)__bind_cpu;
sched_setscheduler(current, SCHED_FIFO, &param);
@@ -276,11 +190,6 @@ static int watchdog(void *__bind_cpu)
if (kthread_should_stop())
break;
- if (this_cpu == check_cpu) {
- if (sysctl_hung_task_timeout_secs)
- check_hung_uninterruptible_tasks(this_cpu);
- }
-
set_current_state(TASK_INTERRUPTIBLE);
}
__set_current_state(TASK_RUNNING);
@@ -312,18 +221,9 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
break;
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
- check_cpu = cpumask_any(cpu_online_mask);
wake_up_process(per_cpu(watchdog_task, hotcpu));
break;
#ifdef CONFIG_HOTPLUG_CPU
- case CPU_DOWN_PREPARE:
- case CPU_DOWN_PREPARE_FROZEN:
- if (hotcpu == check_cpu) {
- /* Pick any other online cpu. */
- check_cpu = cpumask_any_but(cpu_online_mask, hotcpu);
- }
- break;
-
case CPU_UP_CANCELED:
case CPU_UP_CANCELED_FROZEN:
if (!per_cpu(watchdog_task, hotcpu))
diff --git a/kernel/sys.c b/kernel/sys.c
index 51dbb55604e..e7998cf3149 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -360,6 +360,7 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
void __user *, arg)
{
char buffer[256];
+ int ret = 0;
/* We only trust the superuser with rebooting the system. */
if (!capable(CAP_SYS_BOOT))
@@ -397,7 +398,7 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
kernel_halt();
unlock_kernel();
do_exit(0);
- break;
+ panic("cannot halt");
case LINUX_REBOOT_CMD_POWER_OFF:
kernel_power_off();
@@ -417,29 +418,22 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
#ifdef CONFIG_KEXEC
case LINUX_REBOOT_CMD_KEXEC:
- {
- int ret;
- ret = kernel_kexec();
- unlock_kernel();
- return ret;
- }
+ ret = kernel_kexec();
+ break;
#endif
#ifdef CONFIG_HIBERNATION
case LINUX_REBOOT_CMD_SW_SUSPEND:
- {
- int ret = hibernate();
- unlock_kernel();
- return ret;
- }
+ ret = hibernate();
+ break;
#endif
default:
- unlock_kernel();
- return -EINVAL;
+ ret = -EINVAL;
+ break;
}
unlock_kernel();
- return 0;
+ return ret;
}
static void deferred_cad(struct work_struct *dummy)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 5ec4543dfc0..e3d2c7dd59b 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -48,6 +48,7 @@
#include <linux/acpi.h>
#include <linux/reboot.h>
#include <linux/ftrace.h>
+#include <linux/slow-work.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
@@ -96,10 +97,11 @@ static int neg_one = -1;
#endif
static int zero;
-static int one = 1;
-static int two = 2;
+static int __maybe_unused one = 1;
+static int __maybe_unused two = 2;
static unsigned long one_ul = 1;
static int one_hundred = 100;
+static int one_thousand = 1000;
/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
static int maxolduid = 65535;
@@ -812,6 +814,19 @@ static struct ctl_table kern_table[] = {
.extra1 = &neg_one,
.extra2 = &sixty,
},
+#endif
+#ifdef CONFIG_DETECT_HUNG_TASK
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "hung_task_panic",
+ .data = &sysctl_hung_task_panic,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &zero,
+ .extra2 = &one,
+ },
{
.ctl_name = CTL_UNNUMBERED,
.procname = "hung_task_check_count",
@@ -827,7 +842,7 @@ static struct ctl_table kern_table[] = {
.data = &sysctl_hung_task_timeout_secs,
.maxlen = sizeof(unsigned long),
.mode = 0644,
- .proc_handler = &proc_doulongvec_minmax,
+ .proc_handler = &proc_dohung_task_timeout_secs,
.strategy = &sysctl_intvec,
},
{
@@ -887,14 +902,12 @@ static struct ctl_table kern_table[] = {
.proc_handler = &proc_dointvec,
},
#endif
-#ifdef CONFIG_UNEVICTABLE_LRU
+#ifdef CONFIG_SLOW_WORK
{
.ctl_name = CTL_UNNUMBERED,
- .procname = "scan_unevictable_pages",
- .data = &scan_unevictable_pages,
- .maxlen = sizeof(scan_unevictable_pages),
- .mode = 0644,
- .proc_handler = &scan_unevictable_handler,
+ .procname = "slow-work",
+ .mode = 0555,
+ .child = slow_work_sysctls,
},
#endif
/*
@@ -1018,6 +1031,28 @@ static struct ctl_table vm_table[] = {
.proc_handler = &proc_dointvec,
},
{
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "nr_pdflush_threads_min",
+ .data = &nr_pdflush_threads_min,
+ .maxlen = sizeof nr_pdflush_threads_min,
+ .mode = 0644 /* read-write */,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &one,
+ .extra2 = &nr_pdflush_threads_max,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "nr_pdflush_threads_max",
+ .data = &nr_pdflush_threads_max,
+ .maxlen = sizeof nr_pdflush_threads_max,
+ .mode = 0644 /* read-write */,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &nr_pdflush_threads_min,
+ .extra2 = &one_thousand,
+ },
+ {
.ctl_name = VM_SWAPPINESS,
.procname = "swappiness",
.data = &vm_swappiness,
@@ -1257,6 +1292,16 @@ static struct ctl_table vm_table[] = {
.extra2 = &one,
},
#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
diff --git a/kernel/timer.c b/kernel/timer.c
index b4555568b4e..cffffad01c3 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -531,10 +531,13 @@ static void __init_timer(struct timer_list *timer,
}
/**
- * init_timer - initialize a timer.
+ * init_timer_key - initialize a timer
* @timer: the timer to be initialized
+ * @name: name of the timer
+ * @key: lockdep class key of the fake lock used for tracking timer
+ * sync lock dependencies
*
- * init_timer() must be done to a timer prior calling *any* of the
+ * init_timer_key() must be done to a timer prior calling *any* of the
* other timer functions.
*/
void init_timer_key(struct timer_list *timer,
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 34e707e5ab8..417d1985e29 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -9,6 +9,9 @@ config USER_STACKTRACE_SUPPORT
config NOP_TRACER
bool
+config HAVE_FTRACE_NMI_ENTER
+ bool
+
config HAVE_FUNCTION_TRACER
bool
@@ -31,12 +34,20 @@ config HAVE_FTRACE_MCOUNT_RECORD
config HAVE_HW_BRANCH_TRACER
bool
+config HAVE_FTRACE_SYSCALLS
+ bool
+
config TRACER_MAX_TRACE
bool
config RING_BUFFER
bool
+config FTRACE_NMI_ENTER
+ bool
+ depends on HAVE_FTRACE_NMI_ENTER
+ default y
+
config TRACING
bool
select DEBUG_FS
@@ -44,13 +55,29 @@ config TRACING
select STACKTRACE if STACKTRACE_SUPPORT
select TRACEPOINTS
select NOP_TRACER
+ select BINARY_PRINTF
+
+#
+# Minimum requirements an architecture has to meet for us to
+# be able to offer generic tracing facilities:
+#
+config TRACING_SUPPORT
+ bool
+ # PPC32 has no irqflags tracing support, but it can use most of the
+ # tracers anyway, they were tested to build and work. Note that new
+ # exceptions to this list aren't welcomed, better implement the
+ # irqflags tracing for your architecture.
+ depends on TRACE_IRQFLAGS_SUPPORT || PPC32
+ depends on STACKTRACE_SUPPORT
+ default y
+
+if TRACING_SUPPORT
menu "Tracers"
config FUNCTION_TRACER
bool "Kernel Function Tracer"
depends on HAVE_FUNCTION_TRACER
- depends on DEBUG_KERNEL
select FRAME_POINTER
select KALLSYMS
select TRACING
@@ -72,18 +99,16 @@ config FUNCTION_GRAPH_TRACER
help
Enable the kernel to trace a function at both its return
and its entry.
- It's first purpose is to trace the duration of functions and
- draw a call graph for each thread with some informations like
- the return value.
- This is done by setting the current return address on the current
- task structure into a stack of calls.
+ Its first purpose is to trace the duration of functions and
+ draw a call graph for each thread with some information like
+ the return value. This is done by setting the current return
+ address on the current task structure into a stack of calls.
config IRQSOFF_TRACER
bool "Interrupts-off Latency Tracer"
default n
depends on TRACE_IRQFLAGS_SUPPORT
depends on GENERIC_TIME
- depends on DEBUG_KERNEL
select TRACE_IRQFLAGS
select TRACING
select TRACER_MAX_TRACE
@@ -106,7 +131,6 @@ config PREEMPT_TRACER
default n
depends on GENERIC_TIME
depends on PREEMPT
- depends on DEBUG_KERNEL
select TRACING
select TRACER_MAX_TRACE
help
@@ -127,13 +151,13 @@ config SYSPROF_TRACER
bool "Sysprof Tracer"
depends on X86
select TRACING
+ select CONTEXT_SWITCH_TRACER
help
This tracer provides the trace needed by the 'Sysprof' userspace
tool.
config SCHED_TRACER
bool "Scheduling Latency Tracer"
- depends on DEBUG_KERNEL
select TRACING
select CONTEXT_SWITCH_TRACER
select TRACER_MAX_TRACE
@@ -143,16 +167,30 @@ config SCHED_TRACER
config CONTEXT_SWITCH_TRACER
bool "Trace process context switches"
- depends on DEBUG_KERNEL
select TRACING
select MARKERS
help
This tracer gets called from the context switch and records
all switching of tasks.
+config EVENT_TRACER
+ bool "Trace various events in the kernel"
+ select TRACING
+ help
+ This tracer hooks to various trace points in the kernel
+ allowing the user to pick and choose which trace point they
+ want to trace.
+
+config FTRACE_SYSCALLS
+ bool "Trace syscalls"
+ depends on HAVE_FTRACE_SYSCALLS
+ select TRACING
+ select KALLSYMS
+ help
+ Basic tracer to catch the syscall entry and exit events.
+
config BOOT_TRACER
bool "Trace boot initcalls"
- depends on DEBUG_KERNEL
select TRACING
select CONTEXT_SWITCH_TRACER
help
@@ -165,13 +203,11 @@ config BOOT_TRACER
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. )
+ You must pass in ftrace=initcall to the kernel command line
+ to enable this on bootup.
config TRACE_BRANCH_PROFILING
bool "Trace likely/unlikely profiler"
- depends on DEBUG_KERNEL
select TRACING
help
This tracer profiles all the the likely and unlikely macros
@@ -224,7 +260,6 @@ config BRANCH_TRACER
config POWER_TRACER
bool "Trace power consumption behavior"
- depends on DEBUG_KERNEL
depends on X86
select TRACING
help
@@ -236,7 +271,6 @@ config POWER_TRACER
config STACK_TRACER
bool "Trace max stack"
depends on HAVE_FUNCTION_TRACER
- depends on DEBUG_KERNEL
select FUNCTION_TRACER
select STACKTRACE
select KALLSYMS
@@ -266,11 +300,66 @@ config HW_BRANCH_TRACER
This tracer records all branches on the system in a circular
buffer giving access to the last N branches for each cpu.
+config KMEMTRACE
+ bool "Trace SLAB allocations"
+ select TRACING
+ help
+ kmemtrace provides tracing for slab allocator functions, such as
+ kmalloc, kfree, kmem_cache_alloc, kmem_cache_free etc.. Collected
+ data is then fed to the userspace application in order to analyse
+ allocation hotspots, internal fragmentation and so on, making it
+ possible to see how well an allocator performs, as well as debug
+ and profile kernel code.
+
+ This requires an userspace application to use. See
+ Documentation/trace/kmemtrace.txt for more information.
+
+ Saying Y will make the kernel somewhat larger and slower. However,
+ if you disable kmemtrace at run-time or boot-time, the performance
+ impact is minimal (depending on the arch the kernel is built for).
+
+ If unsure, say N.
+
+config WORKQUEUE_TRACER
+ bool "Trace workqueues"
+ select TRACING
+ help
+ The workqueue tracer provides some statistical informations
+ about each cpu workqueue thread such as the number of the
+ works inserted and executed since their creation. It can help
+ to evaluate the amount of work each of them have to perform.
+ For example it can help a developer to decide whether he should
+ choose a per cpu workqueue instead of a singlethreaded one.
+
+config BLK_DEV_IO_TRACE
+ bool "Support for tracing block io actions"
+ depends on SYSFS
+ depends on BLOCK
+ select RELAY
+ select DEBUG_FS
+ select TRACEPOINTS
+ select TRACING
+ select STACKTRACE
+ help
+ Say Y here if you want to be able to trace the block layer actions
+ on a given queue. Tracing allows you to see any traffic happening
+ on a block device queue. For more information (and the userspace
+ support tools needed), fetch the blktrace tools from:
+
+ git://git.kernel.dk/blktrace.git
+
+ Tracing also is possible using the ftrace interface, e.g.:
+
+ echo 1 > /sys/block/sda/sda1/trace/enable
+ echo blk > /sys/kernel/debug/tracing/current_tracer
+ cat /sys/kernel/debug/tracing/trace_pipe
+
+ If unsure, say N.
+
config DYNAMIC_FTRACE
bool "enable/disable ftrace tracepoints dynamically"
depends on FUNCTION_TRACER
depends on HAVE_DYNAMIC_FTRACE
- depends on DEBUG_KERNEL
default y
help
This option will modify all the calls to ftrace dynamically
@@ -296,7 +385,7 @@ config FTRACE_SELFTEST
config FTRACE_STARTUP_TEST
bool "Perform a startup test on ftrace"
- depends on TRACING && DEBUG_KERNEL && !BOOT_TRACER
+ depends on TRACING
select FTRACE_SELFTEST
help
This option performs a series of startup tests on ftrace. On bootup
@@ -306,7 +395,7 @@ config FTRACE_STARTUP_TEST
config MMIOTRACE
bool "Memory mapped IO tracing"
- depends on HAVE_MMIOTRACE_SUPPORT && DEBUG_KERNEL && PCI
+ depends on HAVE_MMIOTRACE_SUPPORT && PCI
select TRACING
help
Mmiotrace traces Memory Mapped I/O access and is meant for
@@ -314,7 +403,7 @@ config MMIOTRACE
implementation and works via page faults. Tracing is disabled by
default and can be enabled at run-time.
- See Documentation/tracers/mmiotrace.txt.
+ See Documentation/trace/mmiotrace.txt.
If you are not helping to develop drivers, say N.
config MMIOTRACE_TEST
@@ -328,3 +417,6 @@ config MMIOTRACE_TEST
Say N, unless you absolutely know what you are doing.
endmenu
+
+endif # TRACING_SUPPORT
+
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 349d5a93653..2630f5121ec 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -19,6 +19,10 @@ obj-$(CONFIG_FUNCTION_TRACER) += libftrace.o
obj-$(CONFIG_RING_BUFFER) += ring_buffer.o
obj-$(CONFIG_TRACING) += trace.o
+obj-$(CONFIG_TRACING) += trace_clock.o
+obj-$(CONFIG_TRACING) += trace_output.o
+obj-$(CONFIG_TRACING) += trace_stat.o
+obj-$(CONFIG_TRACING) += trace_printk.o
obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o
obj-$(CONFIG_SYSPROF_TRACER) += trace_sysprof.o
obj-$(CONFIG_FUNCTION_TRACER) += trace_functions.o
@@ -33,5 +37,14 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += trace_functions_graph.o
obj-$(CONFIG_TRACE_BRANCH_PROFILING) += trace_branch.o
obj-$(CONFIG_HW_BRANCH_TRACER) += trace_hw_branches.o
obj-$(CONFIG_POWER_TRACER) += trace_power.o
+obj-$(CONFIG_KMEMTRACE) += kmemtrace.o
+obj-$(CONFIG_WORKQUEUE_TRACER) += trace_workqueue.o
+obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o
+obj-$(CONFIG_EVENT_TRACER) += trace_events.o
+obj-$(CONFIG_EVENT_TRACER) += events.o
+obj-$(CONFIG_EVENT_TRACER) += trace_export.o
+obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o
+obj-$(CONFIG_EVENT_PROFILE) += trace_event_profile.o
+obj-$(CONFIG_EVENT_TRACER) += trace_events_filter.o
libftrace-y := ftrace.o
diff --git a/block/blktrace.c b/kernel/trace/blktrace.c
index 028120a0965..921ef5d1f0b 100644
--- a/block/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -24,15 +24,32 @@
#include <linux/debugfs.h>
#include <linux/time.h>
#include <trace/block.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
+#include "trace_output.h"
static unsigned int blktrace_seq __read_mostly = 1;
+static struct trace_array *blk_tr;
+static bool blk_tracer_enabled __read_mostly;
+
+/* Select an alternative, minimalistic output than the original one */
+#define TRACE_BLK_OPT_CLASSIC 0x1
+
+static struct tracer_opt blk_tracer_opts[] = {
+ /* Default disable the minimalistic output */
+ { TRACER_OPT(blk_classic, TRACE_BLK_OPT_CLASSIC) },
+ { }
+};
+
+static struct tracer_flags blk_tracer_flags = {
+ .val = 0,
+ .opts = blk_tracer_opts,
+};
+
/* Global reference count of probes */
-static DEFINE_MUTEX(blk_probe_mutex);
static atomic_t blk_probes_ref = ATOMIC_INIT(0);
-static int blk_register_tracepoints(void);
+static void blk_register_tracepoints(void);
static void blk_unregister_tracepoints(void);
/*
@@ -42,19 +59,39 @@ static void trace_note(struct blk_trace *bt, pid_t pid, int action,
const void *data, size_t len)
{
struct blk_io_trace *t;
+ struct ring_buffer_event *event = NULL;
+ int pc = 0;
+ int cpu = smp_processor_id();
+ bool blk_tracer = blk_tracer_enabled;
+
+ if (blk_tracer) {
+ pc = preempt_count();
+ event = trace_buffer_lock_reserve(blk_tr, TRACE_BLK,
+ sizeof(*t) + len,
+ 0, pc);
+ if (!event)
+ return;
+ t = ring_buffer_event_data(event);
+ goto record_it;
+ }
+
+ if (!bt->rchan)
+ return;
t = relay_reserve(bt->rchan, sizeof(*t) + len);
if (t) {
- const int cpu = smp_processor_id();
-
t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION;
t->time = ktime_to_ns(ktime_get());
+record_it:
t->device = bt->dev;
t->action = action;
t->pid = pid;
t->cpu = cpu;
t->pdu_len = len;
memcpy((void *) t + sizeof(*t), data, len);
+
+ if (blk_tracer)
+ trace_buffer_unlock_commit(blk_tr, event, 0, pc);
}
}
@@ -90,6 +127,10 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...)
unsigned long flags;
char *buf;
+ if (unlikely(bt->trace_state != Blktrace_running &&
+ !blk_tracer_enabled))
+ return;
+
local_irq_save(flags);
buf = per_cpu_ptr(bt->msg_data, smp_processor_id());
va_start(args, fmt);
@@ -117,11 +158,12 @@ static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector,
/*
* Data direction bit lookup
*/
-static u32 ddir_act[2] __read_mostly = { BLK_TC_ACT(BLK_TC_READ), BLK_TC_ACT(BLK_TC_WRITE) };
+static const u32 ddir_act[2] = { BLK_TC_ACT(BLK_TC_READ),
+ BLK_TC_ACT(BLK_TC_WRITE) };
/* The ilog2() calls fall out because they're constant */
-#define MASK_TC_BIT(rw, __name) ( (rw & (1 << BIO_RW_ ## __name)) << \
- (ilog2(BLK_TC_ ## __name) + BLK_TC_SHIFT - BIO_RW_ ## __name) )
+#define MASK_TC_BIT(rw, __name) ((rw & (1 << BIO_RW_ ## __name)) << \
+ (ilog2(BLK_TC_ ## __name) + BLK_TC_SHIFT - BIO_RW_ ## __name))
/*
* The worker for the various blk_add_trace*() types. Fills out a
@@ -131,13 +173,15 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
int rw, u32 what, int error, int pdu_len, void *pdu_data)
{
struct task_struct *tsk = current;
+ struct ring_buffer_event *event = NULL;
struct blk_io_trace *t;
- unsigned long flags;
+ unsigned long flags = 0;
unsigned long *sequence;
pid_t pid;
- int cpu;
+ int cpu, pc = 0;
+ bool blk_tracer = blk_tracer_enabled;
- if (unlikely(bt->trace_state != Blktrace_running))
+ if (unlikely(bt->trace_state != Blktrace_running && !blk_tracer))
return;
what |= ddir_act[rw & WRITE];
@@ -150,6 +194,20 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
pid = tsk->pid;
if (unlikely(act_log_check(bt, what, sector, pid)))
return;
+ cpu = raw_smp_processor_id();
+
+ if (blk_tracer) {
+ tracing_record_cmdline(current);
+
+ pc = preempt_count();
+ event = trace_buffer_lock_reserve(blk_tr, TRACE_BLK,
+ sizeof(*t) + pdu_len,
+ 0, pc);
+ if (!event)
+ return;
+ t = ring_buffer_event_data(event);
+ goto record_it;
+ }
/*
* A word about the locking here - we disable interrupts to reserve
@@ -163,23 +221,35 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
t = relay_reserve(bt->rchan, sizeof(*t) + pdu_len);
if (t) {
- cpu = smp_processor_id();
sequence = per_cpu_ptr(bt->sequence, cpu);
t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION;
t->sequence = ++(*sequence);
t->time = ktime_to_ns(ktime_get());
+record_it:
+ /*
+ * These two are not needed in ftrace as they are in the
+ * generic trace_entry, filled by tracing_generic_entry_update,
+ * but for the trace_event->bin() synthesizer benefit we do it
+ * here too.
+ */
+ t->cpu = cpu;
+ t->pid = pid;
+
t->sector = sector;
t->bytes = bytes;
t->action = what;
- t->pid = pid;
t->device = bt->dev;
- t->cpu = cpu;
t->error = error;
t->pdu_len = pdu_len;
if (pdu_len)
memcpy((void *) t + sizeof(*t), pdu_data, pdu_len);
+
+ if (blk_tracer) {
+ trace_buffer_unlock_commit(blk_tr, event, 0, pc);
+ return;
+ }
}
local_irq_restore(flags);
@@ -188,7 +258,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
static struct dentry *blk_tree_root;
static DEFINE_MUTEX(blk_tree_mutex);
-static void blk_trace_cleanup(struct blk_trace *bt)
+static void blk_trace_free(struct blk_trace *bt)
{
debugfs_remove(bt->msg_file);
debugfs_remove(bt->dropped_file);
@@ -196,10 +266,13 @@ static void blk_trace_cleanup(struct blk_trace *bt)
free_percpu(bt->sequence);
free_percpu(bt->msg_data);
kfree(bt);
- mutex_lock(&blk_probe_mutex);
+}
+
+static void blk_trace_cleanup(struct blk_trace *bt)
+{
+ blk_trace_free(bt);
if (atomic_dec_and_test(&blk_probes_ref))
blk_unregister_tracepoints();
- mutex_unlock(&blk_probe_mutex);
}
int blk_trace_remove(struct request_queue *q)
@@ -210,8 +283,7 @@ int blk_trace_remove(struct request_queue *q)
if (!bt)
return -EINVAL;
- if (bt->trace_state == Blktrace_setup ||
- bt->trace_state == Blktrace_stopped)
+ if (bt->trace_state != Blktrace_running)
blk_trace_cleanup(bt);
return 0;
@@ -255,10 +327,10 @@ static ssize_t blk_msg_write(struct file *filp, const char __user *buffer,
char *msg;
struct blk_trace *bt;
- if (count > BLK_TN_MAX_MSG)
+ if (count >= BLK_TN_MAX_MSG)
return -EINVAL;
- msg = kmalloc(count, GFP_KERNEL);
+ msg = kmalloc(count + 1, GFP_KERNEL);
if (msg == NULL)
return -ENOMEM;
@@ -267,6 +339,7 @@ static ssize_t blk_msg_write(struct file *filp, const char __user *buffer,
return -EFAULT;
}
+ msg[count] = '\0';
bt = filp->private_data;
__trace_note_message(bt, "%s", msg);
kfree(msg);
@@ -354,11 +427,11 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (buts->name[i] == '/')
buts->name[i] = '_';
- ret = -ENOMEM;
bt = kzalloc(sizeof(*bt), GFP_KERNEL);
if (!bt)
- goto err;
+ return -ENOMEM;
+ ret = -ENOMEM;
bt->sequence = alloc_percpu(unsigned long);
if (!bt->sequence)
goto err;
@@ -369,11 +442,15 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
ret = -ENOENT;
+ mutex_lock(&blk_tree_mutex);
if (!blk_tree_root) {
blk_tree_root = debugfs_create_dir("block", NULL);
- if (!blk_tree_root)
- return -ENOMEM;
+ if (!blk_tree_root) {
+ mutex_unlock(&blk_tree_mutex);
+ goto err;
+ }
}
+ mutex_unlock(&blk_tree_mutex);
dir = debugfs_create_dir(buts->name, blk_tree_root);
@@ -385,7 +462,8 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
atomic_set(&bt->dropped, 0);
ret = -EIO;
- bt->dropped_file = debugfs_create_file("dropped", 0444, dir, bt, &blk_dropped_fops);
+ bt->dropped_file = debugfs_create_file("dropped", 0444, dir, bt,
+ &blk_dropped_fops);
if (!bt->dropped_file)
goto err;
@@ -410,14 +488,6 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
bt->pid = buts->pid;
bt->trace_state = Blktrace_setup;
- mutex_lock(&blk_probe_mutex);
- if (atomic_add_return(1, &blk_probes_ref) == 1) {
- ret = blk_register_tracepoints();
- if (ret)
- goto probe_err;
- }
- mutex_unlock(&blk_probe_mutex);
-
ret = -EBUSY;
old_bt = xchg(&q->blk_trace, bt);
if (old_bt) {
@@ -425,22 +495,12 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
goto err;
}
+ if (atomic_inc_return(&blk_probes_ref) == 1)
+ blk_register_tracepoints();
+
return 0;
-probe_err:
- atomic_dec(&blk_probes_ref);
- mutex_unlock(&blk_probe_mutex);
err:
- if (bt) {
- if (bt->msg_file)
- debugfs_remove(bt->msg_file);
- if (bt->dropped_file)
- debugfs_remove(bt->dropped_file);
- free_percpu(bt->sequence);
- free_percpu(bt->msg_data);
- if (bt->rchan)
- relay_close(bt->rchan);
- kfree(bt);
- }
+ blk_trace_free(bt);
return ret;
}
@@ -467,10 +527,10 @@ EXPORT_SYMBOL_GPL(blk_trace_setup);
int blk_trace_startstop(struct request_queue *q, int start)
{
- struct blk_trace *bt;
int ret;
+ struct blk_trace *bt = q->blk_trace;
- if ((bt = q->blk_trace) == NULL)
+ if (bt == NULL)
return -EINVAL;
/*
@@ -503,7 +563,7 @@ EXPORT_SYMBOL_GPL(blk_trace_startstop);
/**
* blk_trace_ioctl: - handle the ioctls associated with tracing
* @bdev: the block device
- * @cmd: the ioctl cmd
+ * @cmd: the ioctl cmd
* @arg: the argument data, if any
*
**/
@@ -583,7 +643,7 @@ static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
if (blk_pc_request(rq)) {
what |= BLK_TC_ACT(BLK_TC_PC);
__blk_add_trace(bt, 0, rq->data_len, rw, what, rq->errors,
- sizeof(rq->cmd), rq->cmd);
+ rq->cmd_len, rq->cmd);
} else {
what |= BLK_TC_ACT(BLK_TC_FS);
__blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9,
@@ -606,12 +666,14 @@ static void blk_add_trace_rq_issue(struct request_queue *q, struct request *rq)
blk_add_trace_rq(q, rq, BLK_TA_ISSUE);
}
-static void blk_add_trace_rq_requeue(struct request_queue *q, struct request *rq)
+static void blk_add_trace_rq_requeue(struct request_queue *q,
+ struct request *rq)
{
blk_add_trace_rq(q, rq, BLK_TA_REQUEUE);
}
-static void blk_add_trace_rq_complete(struct request_queue *q, struct request *rq)
+static void blk_add_trace_rq_complete(struct request_queue *q,
+ struct request *rq)
{
blk_add_trace_rq(q, rq, BLK_TA_COMPLETE);
}
@@ -648,12 +710,14 @@ static void blk_add_trace_bio_complete(struct request_queue *q, struct bio *bio)
blk_add_trace_bio(q, bio, BLK_TA_COMPLETE);
}
-static void blk_add_trace_bio_backmerge(struct request_queue *q, struct bio *bio)
+static void blk_add_trace_bio_backmerge(struct request_queue *q,
+ struct bio *bio)
{
blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE);
}
-static void blk_add_trace_bio_frontmerge(struct request_queue *q, struct bio *bio)
+static void blk_add_trace_bio_frontmerge(struct request_queue *q,
+ struct bio *bio)
{
blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE);
}
@@ -663,7 +727,8 @@ static void blk_add_trace_bio_queue(struct request_queue *q, struct bio *bio)
blk_add_trace_bio(q, bio, BLK_TA_QUEUE);
}
-static void blk_add_trace_getrq(struct request_queue *q, struct bio *bio, int rw)
+static void blk_add_trace_getrq(struct request_queue *q,
+ struct bio *bio, int rw)
{
if (bio)
blk_add_trace_bio(q, bio, BLK_TA_GETRQ);
@@ -676,7 +741,8 @@ static void blk_add_trace_getrq(struct request_queue *q, struct bio *bio, int rw
}
-static void blk_add_trace_sleeprq(struct request_queue *q, struct bio *bio, int rw)
+static void blk_add_trace_sleeprq(struct request_queue *q,
+ struct bio *bio, int rw)
{
if (bio)
blk_add_trace_bio(q, bio, BLK_TA_SLEEPRQ);
@@ -684,7 +750,8 @@ static void blk_add_trace_sleeprq(struct request_queue *q, struct bio *bio, int
struct blk_trace *bt = q->blk_trace;
if (bt)
- __blk_add_trace(bt, 0, 0, rw, BLK_TA_SLEEPRQ, 0, 0, NULL);
+ __blk_add_trace(bt, 0, 0, rw, BLK_TA_SLEEPRQ,
+ 0, 0, NULL);
}
}
@@ -795,7 +862,7 @@ void blk_add_driver_data(struct request_queue *q,
}
EXPORT_SYMBOL_GPL(blk_add_driver_data);
-static int blk_register_tracepoints(void)
+static void blk_register_tracepoints(void)
{
int ret;
@@ -833,7 +900,6 @@ static int blk_register_tracepoints(void)
WARN_ON(ret);
ret = register_trace_block_remap(blk_add_trace_remap);
WARN_ON(ret);
- return 0;
}
static void blk_unregister_tracepoints(void)
@@ -858,3 +924,627 @@ static void blk_unregister_tracepoints(void)
tracepoint_synchronize_unregister();
}
+
+/*
+ * struct blk_io_tracer formatting routines
+ */
+
+static void fill_rwbs(char *rwbs, const struct blk_io_trace *t)
+{
+ int i = 0;
+ int tc = t->action >> BLK_TC_SHIFT;
+
+ if (t->action == BLK_TN_MESSAGE) {
+ rwbs[i++] = 'N';
+ goto out;
+ }
+
+ if (tc & BLK_TC_DISCARD)
+ rwbs[i++] = 'D';
+ else if (tc & BLK_TC_WRITE)
+ rwbs[i++] = 'W';
+ else if (t->bytes)
+ rwbs[i++] = 'R';
+ else
+ rwbs[i++] = 'N';
+
+ if (tc & BLK_TC_AHEAD)
+ rwbs[i++] = 'A';
+ if (tc & BLK_TC_BARRIER)
+ rwbs[i++] = 'B';
+ if (tc & BLK_TC_SYNC)
+ rwbs[i++] = 'S';
+ if (tc & BLK_TC_META)
+ rwbs[i++] = 'M';
+out:
+ rwbs[i] = '\0';
+}
+
+static inline
+const struct blk_io_trace *te_blk_io_trace(const struct trace_entry *ent)
+{
+ return (const struct blk_io_trace *)ent;
+}
+
+static inline const void *pdu_start(const struct trace_entry *ent)
+{
+ return te_blk_io_trace(ent) + 1;
+}
+
+static inline u32 t_sec(const struct trace_entry *ent)
+{
+ return te_blk_io_trace(ent)->bytes >> 9;
+}
+
+static inline unsigned long long t_sector(const struct trace_entry *ent)
+{
+ return te_blk_io_trace(ent)->sector;
+}
+
+static inline __u16 t_error(const struct trace_entry *ent)
+{
+ return te_blk_io_trace(ent)->error;
+}
+
+static __u64 get_pdu_int(const struct trace_entry *ent)
+{
+ const __u64 *val = pdu_start(ent);
+ return be64_to_cpu(*val);
+}
+
+static void get_pdu_remap(const struct trace_entry *ent,
+ struct blk_io_trace_remap *r)
+{
+ const struct blk_io_trace_remap *__r = pdu_start(ent);
+ __u64 sector = __r->sector;
+
+ r->device = be32_to_cpu(__r->device);
+ r->device_from = be32_to_cpu(__r->device_from);
+ r->sector = be64_to_cpu(sector);
+}
+
+typedef int (blk_log_action_t) (struct trace_iterator *iter, const char *act);
+
+static int blk_log_action_classic(struct trace_iterator *iter, const char *act)
+{
+ char rwbs[6];
+ unsigned long long ts = iter->ts;
+ unsigned long nsec_rem = do_div(ts, NSEC_PER_SEC);
+ unsigned secs = (unsigned long)ts;
+ const struct blk_io_trace *t = te_blk_io_trace(iter->ent);
+
+ fill_rwbs(rwbs, t);
+
+ return trace_seq_printf(&iter->seq,
+ "%3d,%-3d %2d %5d.%09lu %5u %2s %3s ",
+ MAJOR(t->device), MINOR(t->device), iter->cpu,
+ secs, nsec_rem, iter->ent->pid, act, rwbs);
+}
+
+static int blk_log_action(struct trace_iterator *iter, const char *act)
+{
+ char rwbs[6];
+ const struct blk_io_trace *t = te_blk_io_trace(iter->ent);
+
+ fill_rwbs(rwbs, t);
+ return trace_seq_printf(&iter->seq, "%3d,%-3d %2s %3s ",
+ MAJOR(t->device), MINOR(t->device), act, rwbs);
+}
+
+static int blk_log_generic(struct trace_seq *s, const struct trace_entry *ent)
+{
+ char cmd[TASK_COMM_LEN];
+
+ trace_find_cmdline(ent->pid, cmd);
+
+ if (t_sec(ent))
+ return trace_seq_printf(s, "%llu + %u [%s]\n",
+ t_sector(ent), t_sec(ent), cmd);
+ return trace_seq_printf(s, "[%s]\n", cmd);
+}
+
+static int blk_log_with_error(struct trace_seq *s,
+ const struct trace_entry *ent)
+{
+ if (t_sec(ent))
+ return trace_seq_printf(s, "%llu + %u [%d]\n", t_sector(ent),
+ t_sec(ent), t_error(ent));
+ return trace_seq_printf(s, "%llu [%d]\n", t_sector(ent), t_error(ent));
+}
+
+static int blk_log_remap(struct trace_seq *s, const struct trace_entry *ent)
+{
+ struct blk_io_trace_remap r = { .device = 0, };
+
+ get_pdu_remap(ent, &r);
+ return trace_seq_printf(s, "%llu + %u <- (%d,%d) %llu\n",
+ t_sector(ent),
+ t_sec(ent), MAJOR(r.device), MINOR(r.device),
+ (unsigned long long)r.sector);
+}
+
+static int blk_log_plug(struct trace_seq *s, const struct trace_entry *ent)
+{
+ char cmd[TASK_COMM_LEN];
+
+ trace_find_cmdline(ent->pid, cmd);
+
+ return trace_seq_printf(s, "[%s]\n", cmd);
+}
+
+static int blk_log_unplug(struct trace_seq *s, const struct trace_entry *ent)
+{
+ char cmd[TASK_COMM_LEN];
+
+ trace_find_cmdline(ent->pid, cmd);
+
+ return trace_seq_printf(s, "[%s] %llu\n", cmd, get_pdu_int(ent));
+}
+
+static int blk_log_split(struct trace_seq *s, const struct trace_entry *ent)
+{
+ char cmd[TASK_COMM_LEN];
+
+ trace_find_cmdline(ent->pid, cmd);
+
+ return trace_seq_printf(s, "%llu / %llu [%s]\n", t_sector(ent),
+ get_pdu_int(ent), cmd);
+}
+
+static int blk_log_msg(struct trace_seq *s, const struct trace_entry *ent)
+{
+ int ret;
+ const struct blk_io_trace *t = te_blk_io_trace(ent);
+
+ ret = trace_seq_putmem(s, t + 1, t->pdu_len);
+ if (ret)
+ return trace_seq_putc(s, '\n');
+ return ret;
+}
+
+/*
+ * struct tracer operations
+ */
+
+static void blk_tracer_print_header(struct seq_file *m)
+{
+ if (!(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
+ return;
+ seq_puts(m, "# DEV CPU TIMESTAMP PID ACT FLG\n"
+ "# | | | | | |\n");
+}
+
+static void blk_tracer_start(struct trace_array *tr)
+{
+ blk_tracer_enabled = true;
+ trace_flags &= ~TRACE_ITER_CONTEXT_INFO;
+}
+
+static int blk_tracer_init(struct trace_array *tr)
+{
+ blk_tr = tr;
+ blk_tracer_start(tr);
+ return 0;
+}
+
+static void blk_tracer_stop(struct trace_array *tr)
+{
+ blk_tracer_enabled = false;
+ trace_flags |= TRACE_ITER_CONTEXT_INFO;
+}
+
+static void blk_tracer_reset(struct trace_array *tr)
+{
+ blk_tracer_stop(tr);
+}
+
+static const struct {
+ const char *act[2];
+ int (*print)(struct trace_seq *s, const struct trace_entry *ent);
+} what2act[] = {
+ [__BLK_TA_QUEUE] = {{ "Q", "queue" }, blk_log_generic },
+ [__BLK_TA_BACKMERGE] = {{ "M", "backmerge" }, blk_log_generic },
+ [__BLK_TA_FRONTMERGE] = {{ "F", "frontmerge" }, blk_log_generic },
+ [__BLK_TA_GETRQ] = {{ "G", "getrq" }, blk_log_generic },
+ [__BLK_TA_SLEEPRQ] = {{ "S", "sleeprq" }, blk_log_generic },
+ [__BLK_TA_REQUEUE] = {{ "R", "requeue" }, blk_log_with_error },
+ [__BLK_TA_ISSUE] = {{ "D", "issue" }, blk_log_generic },
+ [__BLK_TA_COMPLETE] = {{ "C", "complete" }, blk_log_with_error },
+ [__BLK_TA_PLUG] = {{ "P", "plug" }, blk_log_plug },
+ [__BLK_TA_UNPLUG_IO] = {{ "U", "unplug_io" }, blk_log_unplug },
+ [__BLK_TA_UNPLUG_TIMER] = {{ "UT", "unplug_timer" }, blk_log_unplug },
+ [__BLK_TA_INSERT] = {{ "I", "insert" }, blk_log_generic },
+ [__BLK_TA_SPLIT] = {{ "X", "split" }, blk_log_split },
+ [__BLK_TA_BOUNCE] = {{ "B", "bounce" }, blk_log_generic },
+ [__BLK_TA_REMAP] = {{ "A", "remap" }, blk_log_remap },
+};
+
+static enum print_line_t print_one_line(struct trace_iterator *iter,
+ bool classic)
+{
+ struct trace_seq *s = &iter->seq;
+ const struct blk_io_trace *t;
+ u16 what;
+ int ret;
+ bool long_act;
+ blk_log_action_t *log_action;
+
+ t = te_blk_io_trace(iter->ent);
+ what = t->action & ((1 << BLK_TC_SHIFT) - 1);
+ long_act = !!(trace_flags & TRACE_ITER_VERBOSE);
+ log_action = classic ? &blk_log_action_classic : &blk_log_action;
+
+ if (t->action == BLK_TN_MESSAGE) {
+ ret = log_action(iter, long_act ? "message" : "m");
+ if (ret)
+ ret = blk_log_msg(s, iter->ent);
+ goto out;
+ }
+
+ if (unlikely(what == 0 || what >= ARRAY_SIZE(what2act)))
+ ret = trace_seq_printf(s, "Bad pc action %x\n", what);
+ else {
+ ret = log_action(iter, what2act[what].act[long_act]);
+ if (ret)
+ ret = what2act[what].print(s, iter->ent);
+ }
+out:
+ return ret ? TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE;
+}
+
+static enum print_line_t blk_trace_event_print(struct trace_iterator *iter,
+ int flags)
+{
+ if (!trace_print_context(iter))
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ return print_one_line(iter, false);
+}
+
+static int blk_trace_synthesize_old_trace(struct trace_iterator *iter)
+{
+ struct trace_seq *s = &iter->seq;
+ struct blk_io_trace *t = (struct blk_io_trace *)iter->ent;
+ const int offset = offsetof(struct blk_io_trace, sector);
+ struct blk_io_trace old = {
+ .magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION,
+ .time = iter->ts,
+ };
+
+ if (!trace_seq_putmem(s, &old, offset))
+ return 0;
+ return trace_seq_putmem(s, &t->sector,
+ sizeof(old) - offset + t->pdu_len);
+}
+
+static enum print_line_t
+blk_trace_event_print_binary(struct trace_iterator *iter, int flags)
+{
+ return blk_trace_synthesize_old_trace(iter) ?
+ TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE;
+}
+
+static enum print_line_t blk_tracer_print_line(struct trace_iterator *iter)
+{
+ if (!(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
+ return TRACE_TYPE_UNHANDLED;
+
+ return print_one_line(iter, true);
+}
+
+static struct tracer blk_tracer __read_mostly = {
+ .name = "blk",
+ .init = blk_tracer_init,
+ .reset = blk_tracer_reset,
+ .start = blk_tracer_start,
+ .stop = blk_tracer_stop,
+ .print_header = blk_tracer_print_header,
+ .print_line = blk_tracer_print_line,
+ .flags = &blk_tracer_flags,
+};
+
+static struct trace_event trace_blk_event = {
+ .type = TRACE_BLK,
+ .trace = blk_trace_event_print,
+ .binary = blk_trace_event_print_binary,
+};
+
+static int __init init_blk_tracer(void)
+{
+ if (!register_ftrace_event(&trace_blk_event)) {
+ pr_warning("Warning: could not register block events\n");
+ return 1;
+ }
+
+ if (register_tracer(&blk_tracer) != 0) {
+ pr_warning("Warning: could not register the block tracer\n");
+ unregister_ftrace_event(&trace_blk_event);
+ return 1;
+ }
+
+ return 0;
+}
+
+device_initcall(init_blk_tracer);
+
+static int blk_trace_remove_queue(struct request_queue *q)
+{
+ struct blk_trace *bt;
+
+ bt = xchg(&q->blk_trace, NULL);
+ if (bt == NULL)
+ return -EINVAL;
+
+ if (atomic_dec_and_test(&blk_probes_ref))
+ blk_unregister_tracepoints();
+
+ blk_trace_free(bt);
+ return 0;
+}
+
+/*
+ * Setup everything required to start tracing
+ */
+static int blk_trace_setup_queue(struct request_queue *q, dev_t dev)
+{
+ struct blk_trace *old_bt, *bt = NULL;
+ int ret = -ENOMEM;
+
+ bt = kzalloc(sizeof(*bt), GFP_KERNEL);
+ if (!bt)
+ return -ENOMEM;
+
+ bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG, __alignof__(char));
+ if (!bt->msg_data)
+ goto free_bt;
+
+ bt->dev = dev;
+ bt->act_mask = (u16)-1;
+ bt->end_lba = -1ULL;
+
+ old_bt = xchg(&q->blk_trace, bt);
+ if (old_bt != NULL) {
+ (void)xchg(&q->blk_trace, old_bt);
+ ret = -EBUSY;
+ goto free_bt;
+ }
+
+ if (atomic_inc_return(&blk_probes_ref) == 1)
+ blk_register_tracepoints();
+ return 0;
+
+free_bt:
+ blk_trace_free(bt);
+ return ret;
+}
+
+/*
+ * sysfs interface to enable and configure tracing
+ */
+
+static ssize_t sysfs_blk_trace_attr_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+#define BLK_TRACE_DEVICE_ATTR(_name) \
+ DEVICE_ATTR(_name, S_IRUGO | S_IWUSR, \
+ sysfs_blk_trace_attr_show, \
+ sysfs_blk_trace_attr_store)
+
+static BLK_TRACE_DEVICE_ATTR(enable);
+static BLK_TRACE_DEVICE_ATTR(act_mask);
+static BLK_TRACE_DEVICE_ATTR(pid);
+static BLK_TRACE_DEVICE_ATTR(start_lba);
+static BLK_TRACE_DEVICE_ATTR(end_lba);
+
+static struct attribute *blk_trace_attrs[] = {
+ &dev_attr_enable.attr,
+ &dev_attr_act_mask.attr,
+ &dev_attr_pid.attr,
+ &dev_attr_start_lba.attr,
+ &dev_attr_end_lba.attr,
+ NULL
+};
+
+struct attribute_group blk_trace_attr_group = {
+ .name = "trace",
+ .attrs = blk_trace_attrs,
+};
+
+static const struct {
+ int mask;
+ const char *str;
+} mask_maps[] = {
+ { BLK_TC_READ, "read" },
+ { BLK_TC_WRITE, "write" },
+ { BLK_TC_BARRIER, "barrier" },
+ { BLK_TC_SYNC, "sync" },
+ { BLK_TC_QUEUE, "queue" },
+ { BLK_TC_REQUEUE, "requeue" },
+ { BLK_TC_ISSUE, "issue" },
+ { BLK_TC_COMPLETE, "complete" },
+ { BLK_TC_FS, "fs" },
+ { BLK_TC_PC, "pc" },
+ { BLK_TC_AHEAD, "ahead" },
+ { BLK_TC_META, "meta" },
+ { BLK_TC_DISCARD, "discard" },
+ { BLK_TC_DRV_DATA, "drv_data" },
+};
+
+static int blk_trace_str2mask(const char *str)
+{
+ int i;
+ int mask = 0;
+ char *buf, *s, *token;
+
+ buf = kstrdup(str, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+ s = strstrip(buf);
+
+ while (1) {
+ token = strsep(&s, ",");
+ if (token == NULL)
+ break;
+
+ if (*token == '\0')
+ continue;
+
+ for (i = 0; i < ARRAY_SIZE(mask_maps); i++) {
+ if (strcasecmp(token, mask_maps[i].str) == 0) {
+ mask |= mask_maps[i].mask;
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(mask_maps)) {
+ mask = -EINVAL;
+ break;
+ }
+ }
+ kfree(buf);
+
+ return mask;
+}
+
+static ssize_t blk_trace_mask2str(char *buf, int mask)
+{
+ int i;
+ char *p = buf;
+
+ for (i = 0; i < ARRAY_SIZE(mask_maps); i++) {
+ if (mask & mask_maps[i].mask) {
+ p += sprintf(p, "%s%s",
+ (p == buf) ? "" : ",", mask_maps[i].str);
+ }
+ }
+ *p++ = '\n';
+
+ return p - buf;
+}
+
+static struct request_queue *blk_trace_get_queue(struct block_device *bdev)
+{
+ if (bdev->bd_disk == NULL)
+ return NULL;
+
+ return bdev_get_queue(bdev);
+}
+
+static ssize_t sysfs_blk_trace_attr_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct hd_struct *p = dev_to_part(dev);
+ struct request_queue *q;
+ struct block_device *bdev;
+ ssize_t ret = -ENXIO;
+
+ lock_kernel();
+ bdev = bdget(part_devt(p));
+ if (bdev == NULL)
+ goto out_unlock_kernel;
+
+ q = blk_trace_get_queue(bdev);
+ if (q == NULL)
+ goto out_bdput;
+
+ mutex_lock(&bdev->bd_mutex);
+
+ if (attr == &dev_attr_enable) {
+ ret = sprintf(buf, "%u\n", !!q->blk_trace);
+ goto out_unlock_bdev;
+ }
+
+ if (q->blk_trace == NULL)
+ ret = sprintf(buf, "disabled\n");
+ else if (attr == &dev_attr_act_mask)
+ ret = blk_trace_mask2str(buf, q->blk_trace->act_mask);
+ else if (attr == &dev_attr_pid)
+ ret = sprintf(buf, "%u\n", q->blk_trace->pid);
+ else if (attr == &dev_attr_start_lba)
+ ret = sprintf(buf, "%llu\n", q->blk_trace->start_lba);
+ else if (attr == &dev_attr_end_lba)
+ ret = sprintf(buf, "%llu\n", q->blk_trace->end_lba);
+
+out_unlock_bdev:
+ mutex_unlock(&bdev->bd_mutex);
+out_bdput:
+ bdput(bdev);
+out_unlock_kernel:
+ unlock_kernel();
+ return ret;
+}
+
+static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct block_device *bdev;
+ struct request_queue *q;
+ struct hd_struct *p;
+ u64 value;
+ ssize_t ret = -EINVAL;
+
+ if (count == 0)
+ goto out;
+
+ if (attr == &dev_attr_act_mask) {
+ if (sscanf(buf, "%llx", &value) != 1) {
+ /* Assume it is a list of trace category names */
+ ret = blk_trace_str2mask(buf);
+ if (ret < 0)
+ goto out;
+ value = ret;
+ }
+ } else if (sscanf(buf, "%llu", &value) != 1)
+ goto out;
+
+ ret = -ENXIO;
+
+ lock_kernel();
+ p = dev_to_part(dev);
+ bdev = bdget(part_devt(p));
+ if (bdev == NULL)
+ goto out_unlock_kernel;
+
+ q = blk_trace_get_queue(bdev);
+ if (q == NULL)
+ goto out_bdput;
+
+ mutex_lock(&bdev->bd_mutex);
+
+ if (attr == &dev_attr_enable) {
+ if (value)
+ ret = blk_trace_setup_queue(q, bdev->bd_dev);
+ else
+ ret = blk_trace_remove_queue(q);
+ goto out_unlock_bdev;
+ }
+
+ ret = 0;
+ if (q->blk_trace == NULL)
+ ret = blk_trace_setup_queue(q, bdev->bd_dev);
+
+ if (ret == 0) {
+ if (attr == &dev_attr_act_mask)
+ q->blk_trace->act_mask = value;
+ else if (attr == &dev_attr_pid)
+ q->blk_trace->pid = value;
+ else if (attr == &dev_attr_start_lba)
+ q->blk_trace->start_lba = value;
+ else if (attr == &dev_attr_end_lba)
+ q->blk_trace->end_lba = value;
+ }
+
+out_unlock_bdev:
+ mutex_unlock(&bdev->bd_mutex);
+out_bdput:
+ bdput(bdev);
+out_unlock_kernel:
+ unlock_kernel();
+out:
+ return ret ? ret : count;
+}
+
diff --git a/kernel/trace/events.c b/kernel/trace/events.c
new file mode 100644
index 00000000000..246f2aa6dc4
--- /dev/null
+++ b/kernel/trace/events.c
@@ -0,0 +1,14 @@
+/*
+ * This is the place to register all trace points as events.
+ */
+
+#include <linux/stringify.h>
+
+#include <trace/trace_events.h>
+
+#include "trace_output.h"
+
+#include "trace_events_stage_1.h"
+#include "trace_events_stage_2.h"
+#include "trace_events_stage_3.h"
+
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index fdf913dfc7e..f1ed080406c 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -27,6 +27,9 @@
#include <linux/sysctl.h>
#include <linux/ctype.h>
#include <linux/list.h>
+#include <linux/hash.h>
+
+#include <trace/sched.h>
#include <asm/ftrace.h>
@@ -44,14 +47,14 @@
ftrace_kill(); \
} while (0)
+/* hash bits for specific function selection */
+#define FTRACE_HASH_BITS 7
+#define FTRACE_FUNC_HASHSIZE (1 << FTRACE_HASH_BITS)
+
/* ftrace_enabled is a method to turn ftrace on or off */
int ftrace_enabled __read_mostly;
static int last_ftrace_enabled;
-/* set when tracing only a pid */
-struct pid *ftrace_pid_trace;
-static struct pid * const ftrace_swapper_pid = &init_struct_pid;
-
/* Quick disabling of function tracer. */
int function_trace_stop;
@@ -61,9 +64,7 @@ int function_trace_stop;
*/
static int ftrace_disabled __read_mostly;
-static DEFINE_SPINLOCK(ftrace_lock);
-static DEFINE_MUTEX(ftrace_sysctl_lock);
-static DEFINE_MUTEX(ftrace_start_lock);
+static DEFINE_MUTEX(ftrace_lock);
static struct ftrace_ops ftrace_list_end __read_mostly =
{
@@ -134,9 +135,6 @@ static void ftrace_test_stop_func(unsigned long ip, unsigned long parent_ip)
static int __register_ftrace_function(struct ftrace_ops *ops)
{
- /* should not be called from interrupt context */
- spin_lock(&ftrace_lock);
-
ops->next = ftrace_list;
/*
* We are entering ops into the ftrace_list but another
@@ -172,18 +170,12 @@ static int __register_ftrace_function(struct ftrace_ops *ops)
#endif
}
- spin_unlock(&ftrace_lock);
-
return 0;
}
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);
/*
* If we are removing the last function, then simply point
@@ -192,17 +184,15 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
if (ftrace_list == ops && ops->next == &ftrace_list_end) {
ftrace_trace_function = ftrace_stub;
ftrace_list = &ftrace_list_end;
- goto out;
+ return 0;
}
for (p = &ftrace_list; *p != &ftrace_list_end; p = &(*p)->next)
if (*p == ops)
break;
- if (*p != ops) {
- ret = -1;
- goto out;
- }
+ if (*p != ops)
+ return -1;
*p = (*p)->next;
@@ -223,21 +213,15 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
}
}
- out:
- spin_unlock(&ftrace_lock);
-
- return ret;
+ return 0;
}
static void ftrace_update_pid_func(void)
{
ftrace_func_t func;
- /* should not be called from interrupt context */
- spin_lock(&ftrace_lock);
-
if (ftrace_trace_function == ftrace_stub)
- goto out;
+ return;
func = ftrace_trace_function;
@@ -254,23 +238,29 @@ static void ftrace_update_pid_func(void)
#else
__ftrace_trace_function = func;
#endif
-
- out:
- spin_unlock(&ftrace_lock);
}
+/* set when tracing only a pid */
+struct pid *ftrace_pid_trace;
+static struct pid * const ftrace_swapper_pid = &init_struct_pid;
+
#ifdef CONFIG_DYNAMIC_FTRACE
+
#ifndef CONFIG_FTRACE_MCOUNT_RECORD
# error Dynamic ftrace depends on MCOUNT_RECORD
#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 hlist_head ftrace_func_hash[FTRACE_FUNC_HASHSIZE] __read_mostly;
+
+struct ftrace_func_probe {
+ struct hlist_node node;
+ struct ftrace_probe_ops *ops;
+ unsigned long flags;
+ unsigned long ip;
+ void *data;
+ struct rcu_head rcu;
+};
+
enum {
FTRACE_ENABLE_CALLS = (1 << 0),
@@ -284,13 +274,13 @@ enum {
static int ftrace_filtered;
-static LIST_HEAD(ftrace_new_addrs);
+static struct dyn_ftrace *ftrace_new_addrs;
static DEFINE_MUTEX(ftrace_regex_lock);
struct ftrace_page {
struct ftrace_page *next;
- unsigned long index;
+ int index;
struct dyn_ftrace records[];
};
@@ -305,6 +295,19 @@ static struct ftrace_page *ftrace_pages;
static struct dyn_ftrace *ftrace_free_records;
+/*
+ * This is a double for. Do not use 'break' to break out of the loop,
+ * you must use a goto.
+ */
+#define do_for_each_ftrace_rec(pg, rec) \
+ for (pg = ftrace_pages_start; pg; pg = pg->next) { \
+ int _____i; \
+ for (_____i = 0; _____i < pg->index; _____i++) { \
+ rec = &pg->records[_____i];
+
+#define while_for_each_ftrace_rec() \
+ } \
+ }
#ifdef CONFIG_KPROBES
@@ -338,7 +341,7 @@ static inline int record_frozen(struct dyn_ftrace *rec)
static void ftrace_free_rec(struct dyn_ftrace *rec)
{
- rec->ip = (unsigned long)ftrace_free_records;
+ rec->freelist = ftrace_free_records;
ftrace_free_records = rec;
rec->flags |= FTRACE_FL_FREE;
}
@@ -349,23 +352,22 @@ void ftrace_release(void *start, unsigned long size)
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);
+ mutex_lock(&ftrace_lock);
+ do_for_each_ftrace_rec(pg, rec) {
+ if ((rec->ip >= s) && (rec->ip < e)) {
+ /*
+ * rec->ip is changed in ftrace_free_rec()
+ * It should not between s and e if record was freed.
+ */
+ FTRACE_WARN_ON(rec->flags & FTRACE_FL_FREE);
+ ftrace_free_rec(rec);
}
- }
- spin_unlock(&ftrace_lock);
+ } while_for_each_ftrace_rec();
+ mutex_unlock(&ftrace_lock);
}
static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
@@ -382,7 +384,7 @@ static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
return NULL;
}
- ftrace_free_records = (void *)rec->ip;
+ ftrace_free_records = rec->freelist;
memset(rec, 0, sizeof(*rec));
return rec;
}
@@ -414,8 +416,8 @@ ftrace_record_ip(unsigned long ip)
return NULL;
rec->ip = ip;
-
- list_add(&rec->list, &ftrace_new_addrs);
+ rec->newlist = ftrace_new_addrs;
+ ftrace_new_addrs = rec;
return rec;
}
@@ -461,10 +463,10 @@ static void ftrace_bug(int failed, unsigned long ip)
static int
__ftrace_replace_code(struct dyn_ftrace *rec, int enable)
{
- unsigned long ip, fl;
unsigned long ftrace_addr;
+ unsigned long ip, fl;
- ftrace_addr = (unsigned long)ftrace_caller;
+ ftrace_addr = (unsigned long)FTRACE_ADDR;
ip = rec->ip;
@@ -473,7 +475,7 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
* it is not enabled then do nothing.
*
* If this record is not to be traced and
- * it is enabled then disabled it.
+ * it is enabled then disable it.
*
*/
if (rec->flags & FTRACE_FL_NOTRACE) {
@@ -493,7 +495,7 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
if (fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED))
return 0;
- /* Record is not filtered and is not enabled do nothing */
+ /* Record is not filtered or enabled, do nothing */
if (!fl)
return 0;
@@ -515,7 +517,7 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
} else {
- /* if record is not enabled do nothing */
+ /* if record is not enabled, do nothing */
if (!(rec->flags & FTRACE_FL_ENABLED))
return 0;
@@ -531,41 +533,41 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
static void ftrace_replace_code(int enable)
{
- int i, failed;
struct dyn_ftrace *rec;
struct ftrace_page *pg;
+ int failed;
- for (pg = ftrace_pages_start; pg; pg = pg->next) {
- for (i = 0; i < pg->index; i++) {
- rec = &pg->records[i];
-
- /*
- * Skip over free records and records that have
- * failed.
- */
- if (rec->flags & FTRACE_FL_FREE ||
- rec->flags & FTRACE_FL_FAILED)
- continue;
+ do_for_each_ftrace_rec(pg, rec) {
+ /*
+ * Skip over free records, records that have
+ * failed and not converted.
+ */
+ if (rec->flags & FTRACE_FL_FREE ||
+ rec->flags & FTRACE_FL_FAILED ||
+ !(rec->flags & FTRACE_FL_CONVERTED))
+ continue;
- /* ignore updates to this record's mcount site */
- if (get_kprobe((void *)rec->ip)) {
- freeze_record(rec);
- continue;
- } else {
- unfreeze_record(rec);
- }
+ /* ignore updates to this record's mcount site */
+ if (get_kprobe((void *)rec->ip)) {
+ freeze_record(rec);
+ continue;
+ } else {
+ unfreeze_record(rec);
+ }
- failed = __ftrace_replace_code(rec, enable);
- if (failed && (rec->flags & FTRACE_FL_CONVERTED)) {
- rec->flags |= FTRACE_FL_FAILED;
- if ((system_state == SYSTEM_BOOTING) ||
- !core_kernel_text(rec->ip)) {
- ftrace_free_rec(rec);
- } else
- ftrace_bug(failed, rec->ip);
- }
+ failed = __ftrace_replace_code(rec, enable);
+ if (failed) {
+ rec->flags |= FTRACE_FL_FAILED;
+ if ((system_state == SYSTEM_BOOTING) ||
+ !core_kernel_text(rec->ip)) {
+ ftrace_free_rec(rec);
+ } else {
+ ftrace_bug(failed, rec->ip);
+ /* Stop processing */
+ return;
+ }
}
- }
+ } while_for_each_ftrace_rec();
}
static int
@@ -576,7 +578,7 @@ ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec)
ip = rec->ip;
- ret = ftrace_make_nop(mod, rec, mcount_addr);
+ ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
if (ret) {
ftrace_bug(ret, ip);
rec->flags |= FTRACE_FL_FAILED;
@@ -585,6 +587,24 @@ ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec)
return 1;
}
+/*
+ * archs can override this function if they must do something
+ * before the modifying code is performed.
+ */
+int __weak ftrace_arch_code_modify_prepare(void)
+{
+ return 0;
+}
+
+/*
+ * archs can override this function if they must do something
+ * after the modifying code is performed.
+ */
+int __weak ftrace_arch_code_modify_post_process(void)
+{
+ return 0;
+}
+
static int __ftrace_modify_code(void *data)
{
int *command = data;
@@ -607,7 +627,17 @@ static int __ftrace_modify_code(void *data)
static void ftrace_run_update_code(int command)
{
+ int ret;
+
+ ret = ftrace_arch_code_modify_prepare();
+ FTRACE_WARN_ON(ret);
+ if (ret)
+ return;
+
stop_machine(__ftrace_modify_code, &command, NULL);
+
+ ret = ftrace_arch_code_modify_post_process();
+ FTRACE_WARN_ON(ret);
}
static ftrace_func_t saved_ftrace_func;
@@ -631,13 +661,10 @@ static void ftrace_startup(int command)
if (unlikely(ftrace_disabled))
return;
- mutex_lock(&ftrace_start_lock);
ftrace_start_up++;
command |= FTRACE_ENABLE_CALLS;
ftrace_startup_enable(command);
-
- mutex_unlock(&ftrace_start_lock);
}
static void ftrace_shutdown(int command)
@@ -645,7 +672,6 @@ static void ftrace_shutdown(int command)
if (unlikely(ftrace_disabled))
return;
- mutex_lock(&ftrace_start_lock);
ftrace_start_up--;
if (!ftrace_start_up)
command |= FTRACE_DISABLE_CALLS;
@@ -656,11 +682,9 @@ static void ftrace_shutdown(int command)
}
if (!command || !ftrace_enabled)
- goto out;
+ return;
ftrace_run_update_code(command);
- out:
- mutex_unlock(&ftrace_start_lock);
}
static void ftrace_startup_sysctl(void)
@@ -670,7 +694,6 @@ static void ftrace_startup_sysctl(void)
if (unlikely(ftrace_disabled))
return;
- mutex_lock(&ftrace_start_lock);
/* Force update next time */
saved_ftrace_func = NULL;
/* ftrace_start_up is true if we want ftrace running */
@@ -678,7 +701,6 @@ static void ftrace_startup_sysctl(void)
command |= FTRACE_ENABLE_CALLS;
ftrace_run_update_code(command);
- mutex_unlock(&ftrace_start_lock);
}
static void ftrace_shutdown_sysctl(void)
@@ -688,13 +710,11 @@ static void ftrace_shutdown_sysctl(void)
if (unlikely(ftrace_disabled))
return;
- mutex_lock(&ftrace_start_lock);
/* ftrace_start_up is true if ftrace is running */
if (ftrace_start_up)
command |= FTRACE_DISABLE_CALLS;
ftrace_run_update_code(command);
- mutex_unlock(&ftrace_start_lock);
}
static cycle_t ftrace_update_time;
@@ -703,19 +723,21 @@ unsigned long ftrace_update_tot_cnt;
static int ftrace_update_code(struct module *mod)
{
- struct dyn_ftrace *p, *t;
+ struct dyn_ftrace *p;
cycle_t start, stop;
start = ftrace_now(raw_smp_processor_id());
ftrace_update_cnt = 0;
- list_for_each_entry_safe(p, t, &ftrace_new_addrs, list) {
+ while (ftrace_new_addrs) {
/* If something went wrong, bail without enabling anything */
if (unlikely(ftrace_disabled))
return -1;
- list_del_init(&p->list);
+ p = ftrace_new_addrs;
+ ftrace_new_addrs = p->newlist;
+ p->flags = 0L;
/* convert record (i.e, patch mcount-call with NOP) */
if (ftrace_code_disable(mod, p)) {
@@ -781,13 +803,16 @@ enum {
FTRACE_ITER_CONT = (1 << 1),
FTRACE_ITER_NOTRACE = (1 << 2),
FTRACE_ITER_FAILURES = (1 << 3),
+ FTRACE_ITER_PRINTALL = (1 << 4),
+ FTRACE_ITER_HASH = (1 << 5),
};
#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */
struct ftrace_iterator {
struct ftrace_page *pg;
- unsigned idx;
+ int hidx;
+ int idx;
unsigned flags;
unsigned char buffer[FTRACE_BUFF_MAX+1];
unsigned buffer_idx;
@@ -795,15 +820,89 @@ struct ftrace_iterator {
};
static void *
+t_hash_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ struct ftrace_iterator *iter = m->private;
+ struct hlist_node *hnd = v;
+ struct hlist_head *hhd;
+
+ WARN_ON(!(iter->flags & FTRACE_ITER_HASH));
+
+ (*pos)++;
+
+ retry:
+ if (iter->hidx >= FTRACE_FUNC_HASHSIZE)
+ return NULL;
+
+ hhd = &ftrace_func_hash[iter->hidx];
+
+ if (hlist_empty(hhd)) {
+ iter->hidx++;
+ hnd = NULL;
+ goto retry;
+ }
+
+ if (!hnd)
+ hnd = hhd->first;
+ else {
+ hnd = hnd->next;
+ if (!hnd) {
+ iter->hidx++;
+ goto retry;
+ }
+ }
+
+ return hnd;
+}
+
+static void *t_hash_start(struct seq_file *m, loff_t *pos)
+{
+ struct ftrace_iterator *iter = m->private;
+ void *p = NULL;
+
+ iter->flags |= FTRACE_ITER_HASH;
+
+ return t_hash_next(m, p, pos);
+}
+
+static int t_hash_show(struct seq_file *m, void *v)
+{
+ struct ftrace_func_probe *rec;
+ struct hlist_node *hnd = v;
+ char str[KSYM_SYMBOL_LEN];
+
+ rec = hlist_entry(hnd, struct ftrace_func_probe, node);
+
+ if (rec->ops->print)
+ return rec->ops->print(m, rec->ip, rec->ops, rec->data);
+
+ kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
+ seq_printf(m, "%s:", str);
+
+ kallsyms_lookup((unsigned long)rec->ops->func, NULL, NULL, NULL, str);
+ seq_printf(m, "%s", str);
+
+ if (rec->data)
+ seq_printf(m, ":%p", rec->data);
+ seq_putc(m, '\n');
+
+ return 0;
+}
+
+static void *
t_next(struct seq_file *m, void *v, loff_t *pos)
{
struct ftrace_iterator *iter = m->private;
struct dyn_ftrace *rec = NULL;
+ if (iter->flags & FTRACE_ITER_HASH)
+ return t_hash_next(m, v, pos);
+
(*pos)++;
- /* should not be called from interrupt context */
- spin_lock(&ftrace_lock);
+ if (iter->flags & FTRACE_ITER_PRINTALL)
+ return NULL;
+
retry:
if (iter->idx >= iter->pg->index) {
if (iter->pg->next) {
@@ -832,7 +931,6 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
goto retry;
}
}
- spin_unlock(&ftrace_lock);
return rec;
}
@@ -842,6 +940,23 @@ static void *t_start(struct seq_file *m, loff_t *pos)
struct ftrace_iterator *iter = m->private;
void *p = NULL;
+ mutex_lock(&ftrace_lock);
+ /*
+ * For set_ftrace_filter reading, if we have the filter
+ * off, we can short cut and just print out that all
+ * functions are enabled.
+ */
+ if (iter->flags & FTRACE_ITER_FILTER && !ftrace_filtered) {
+ if (*pos > 0)
+ return t_hash_start(m, pos);
+ iter->flags |= FTRACE_ITER_PRINTALL;
+ (*pos)++;
+ return iter;
+ }
+
+ if (iter->flags & FTRACE_ITER_HASH)
+ return t_hash_start(m, pos);
+
if (*pos > 0) {
if (iter->idx < 0)
return p;
@@ -851,18 +966,31 @@ static void *t_start(struct seq_file *m, loff_t *pos)
p = t_next(m, p, pos);
+ if (!p)
+ return t_hash_start(m, pos);
+
return p;
}
static void t_stop(struct seq_file *m, void *p)
{
+ mutex_unlock(&ftrace_lock);
}
static int t_show(struct seq_file *m, void *v)
{
+ struct ftrace_iterator *iter = m->private;
struct dyn_ftrace *rec = v;
char str[KSYM_SYMBOL_LEN];
+ if (iter->flags & FTRACE_ITER_HASH)
+ return t_hash_show(m, v);
+
+ if (iter->flags & FTRACE_ITER_PRINTALL) {
+ seq_printf(m, "#### all functions enabled ####\n");
+ return 0;
+ }
+
if (!rec)
return 0;
@@ -941,23 +1069,16 @@ static void ftrace_filter_reset(int enable)
struct ftrace_page *pg;
struct dyn_ftrace *rec;
unsigned long type = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
- unsigned i;
- /* should not be called from interrupt context */
- spin_lock(&ftrace_lock);
+ mutex_lock(&ftrace_lock);
if (enable)
ftrace_filtered = 0;
- pg = ftrace_pages_start;
- while (pg) {
- for (i = 0; i < pg->index; i++) {
- rec = &pg->records[i];
- if (rec->flags & FTRACE_FL_FAILED)
- continue;
- rec->flags &= ~type;
- }
- pg = pg->next;
- }
- spin_unlock(&ftrace_lock);
+ do_for_each_ftrace_rec(pg, rec) {
+ if (rec->flags & FTRACE_FL_FAILED)
+ continue;
+ rec->flags &= ~type;
+ } while_for_each_ftrace_rec();
+ mutex_unlock(&ftrace_lock);
}
static int
@@ -1008,16 +1129,6 @@ ftrace_notrace_open(struct inode *inode, struct file *file)
return ftrace_regex_open(inode, file, 0);
}
-static ssize_t
-ftrace_regex_read(struct file *file, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- if (file->f_mode & FMODE_READ)
- return seq_read(file, ubuf, cnt, ppos);
- else
- return -EPERM;
-}
-
static loff_t
ftrace_regex_lseek(struct file *file, loff_t offset, int origin)
{
@@ -1038,86 +1149,536 @@ enum {
MATCH_END_ONLY,
};
-static void
-ftrace_match(unsigned char *buff, int len, int enable)
+/*
+ * (static function - no need for kernel doc)
+ *
+ * Pass in a buffer containing a glob and this function will
+ * set search to point to the search part of the buffer and
+ * return the type of search it is (see enum above).
+ * This does modify buff.
+ *
+ * Returns enum type.
+ * search returns the pointer to use for comparison.
+ * not returns 1 if buff started with a '!'
+ * 0 otherwise.
+ */
+static int
+ftrace_setup_glob(char *buff, int len, char **search, int *not)
{
- char str[KSYM_SYMBOL_LEN];
- char *search = NULL;
- struct ftrace_page *pg;
- struct dyn_ftrace *rec;
int type = MATCH_FULL;
- unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
- unsigned i, match = 0, search_len = 0;
- int not = 0;
+ int i;
if (buff[0] == '!') {
- not = 1;
+ *not = 1;
buff++;
len--;
- }
+ } else
+ *not = 0;
+
+ *search = buff;
for (i = 0; i < len; i++) {
if (buff[i] == '*') {
if (!i) {
- search = buff + i + 1;
+ *search = buff + 1;
type = MATCH_END_ONLY;
- search_len = len - (i + 1);
} else {
- if (type == MATCH_END_ONLY) {
+ if (type == MATCH_END_ONLY)
type = MATCH_MIDDLE_ONLY;
- } else {
- match = i;
+ else
type = MATCH_FRONT_ONLY;
- }
buff[i] = 0;
break;
}
}
}
- /* should not be called from interrupt context */
- spin_lock(&ftrace_lock);
- if (enable)
- ftrace_filtered = 1;
- pg = ftrace_pages_start;
- while (pg) {
- for (i = 0; i < pg->index; i++) {
- int matched = 0;
- char *ptr;
-
- rec = &pg->records[i];
- if (rec->flags & FTRACE_FL_FAILED)
+ return type;
+}
+
+static int ftrace_match(char *str, char *regex, int len, int type)
+{
+ int matched = 0;
+ char *ptr;
+
+ switch (type) {
+ case MATCH_FULL:
+ if (strcmp(str, regex) == 0)
+ matched = 1;
+ break;
+ case MATCH_FRONT_ONLY:
+ if (strncmp(str, regex, len) == 0)
+ matched = 1;
+ break;
+ case MATCH_MIDDLE_ONLY:
+ if (strstr(str, regex))
+ matched = 1;
+ break;
+ case MATCH_END_ONLY:
+ ptr = strstr(str, regex);
+ if (ptr && (ptr[len] == 0))
+ matched = 1;
+ break;
+ }
+
+ return matched;
+}
+
+static int
+ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type)
+{
+ char str[KSYM_SYMBOL_LEN];
+
+ kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
+ return ftrace_match(str, regex, len, type);
+}
+
+static void ftrace_match_records(char *buff, int len, int enable)
+{
+ unsigned int search_len;
+ struct ftrace_page *pg;
+ struct dyn_ftrace *rec;
+ unsigned long flag;
+ char *search;
+ int type;
+ int not;
+
+ flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
+ type = ftrace_setup_glob(buff, len, &search, &not);
+
+ search_len = strlen(search);
+
+ mutex_lock(&ftrace_lock);
+ do_for_each_ftrace_rec(pg, rec) {
+
+ if (rec->flags & FTRACE_FL_FAILED)
+ continue;
+
+ if (ftrace_match_record(rec, search, search_len, type)) {
+ if (not)
+ rec->flags &= ~flag;
+ else
+ rec->flags |= flag;
+ }
+ /*
+ * Only enable filtering if we have a function that
+ * is filtered on.
+ */
+ if (enable && (rec->flags & FTRACE_FL_FILTER))
+ ftrace_filtered = 1;
+ } while_for_each_ftrace_rec();
+ mutex_unlock(&ftrace_lock);
+}
+
+static int
+ftrace_match_module_record(struct dyn_ftrace *rec, char *mod,
+ char *regex, int len, int type)
+{
+ char str[KSYM_SYMBOL_LEN];
+ char *modname;
+
+ kallsyms_lookup(rec->ip, NULL, NULL, &modname, str);
+
+ if (!modname || strcmp(modname, mod))
+ return 0;
+
+ /* blank search means to match all funcs in the mod */
+ if (len)
+ return ftrace_match(str, regex, len, type);
+ else
+ return 1;
+}
+
+static void ftrace_match_module_records(char *buff, char *mod, int enable)
+{
+ unsigned search_len = 0;
+ struct ftrace_page *pg;
+ struct dyn_ftrace *rec;
+ int type = MATCH_FULL;
+ char *search = buff;
+ unsigned long flag;
+ int not = 0;
+
+ flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
+
+ /* blank or '*' mean the same */
+ if (strcmp(buff, "*") == 0)
+ buff[0] = 0;
+
+ /* handle the case of 'dont filter this module' */
+ if (strcmp(buff, "!") == 0 || strcmp(buff, "!*") == 0) {
+ buff[0] = 0;
+ not = 1;
+ }
+
+ if (strlen(buff)) {
+ type = ftrace_setup_glob(buff, strlen(buff), &search, &not);
+ search_len = strlen(search);
+ }
+
+ mutex_lock(&ftrace_lock);
+ do_for_each_ftrace_rec(pg, rec) {
+
+ if (rec->flags & FTRACE_FL_FAILED)
+ continue;
+
+ if (ftrace_match_module_record(rec, mod,
+ search, search_len, type)) {
+ if (not)
+ rec->flags &= ~flag;
+ else
+ rec->flags |= flag;
+ }
+ if (enable && (rec->flags & FTRACE_FL_FILTER))
+ ftrace_filtered = 1;
+
+ } while_for_each_ftrace_rec();
+ mutex_unlock(&ftrace_lock);
+}
+
+/*
+ * We register the module command as a template to show others how
+ * to register the a command as well.
+ */
+
+static int
+ftrace_mod_callback(char *func, char *cmd, char *param, int enable)
+{
+ char *mod;
+
+ /*
+ * cmd == 'mod' because we only registered this func
+ * for the 'mod' ftrace_func_command.
+ * But if you register one func with multiple commands,
+ * you can tell which command was used by the cmd
+ * parameter.
+ */
+
+ /* we must have a module name */
+ if (!param)
+ return -EINVAL;
+
+ mod = strsep(&param, ":");
+ if (!strlen(mod))
+ return -EINVAL;
+
+ ftrace_match_module_records(func, mod, enable);
+ return 0;
+}
+
+static struct ftrace_func_command ftrace_mod_cmd = {
+ .name = "mod",
+ .func = ftrace_mod_callback,
+};
+
+static int __init ftrace_mod_cmd_init(void)
+{
+ return register_ftrace_command(&ftrace_mod_cmd);
+}
+device_initcall(ftrace_mod_cmd_init);
+
+static void
+function_trace_probe_call(unsigned long ip, unsigned long parent_ip)
+{
+ struct ftrace_func_probe *entry;
+ struct hlist_head *hhd;
+ struct hlist_node *n;
+ unsigned long key;
+ int resched;
+
+ key = hash_long(ip, FTRACE_HASH_BITS);
+
+ hhd = &ftrace_func_hash[key];
+
+ if (hlist_empty(hhd))
+ return;
+
+ /*
+ * Disable preemption for these calls to prevent a RCU grace
+ * period. This syncs the hash iteration and freeing of items
+ * on the hash. rcu_read_lock is too dangerous here.
+ */
+ resched = ftrace_preempt_disable();
+ hlist_for_each_entry_rcu(entry, n, hhd, node) {
+ if (entry->ip == ip)
+ entry->ops->func(ip, parent_ip, &entry->data);
+ }
+ ftrace_preempt_enable(resched);
+}
+
+static struct ftrace_ops trace_probe_ops __read_mostly =
+{
+ .func = function_trace_probe_call,
+};
+
+static int ftrace_probe_registered;
+
+static void __enable_ftrace_function_probe(void)
+{
+ int i;
+
+ if (ftrace_probe_registered)
+ return;
+
+ for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
+ struct hlist_head *hhd = &ftrace_func_hash[i];
+ if (hhd->first)
+ break;
+ }
+ /* Nothing registered? */
+ if (i == FTRACE_FUNC_HASHSIZE)
+ return;
+
+ __register_ftrace_function(&trace_probe_ops);
+ ftrace_startup(0);
+ ftrace_probe_registered = 1;
+}
+
+static void __disable_ftrace_function_probe(void)
+{
+ int i;
+
+ if (!ftrace_probe_registered)
+ return;
+
+ for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
+ struct hlist_head *hhd = &ftrace_func_hash[i];
+ if (hhd->first)
+ return;
+ }
+
+ /* no more funcs left */
+ __unregister_ftrace_function(&trace_probe_ops);
+ ftrace_shutdown(0);
+ ftrace_probe_registered = 0;
+}
+
+
+static void ftrace_free_entry_rcu(struct rcu_head *rhp)
+{
+ struct ftrace_func_probe *entry =
+ container_of(rhp, struct ftrace_func_probe, rcu);
+
+ if (entry->ops->free)
+ entry->ops->free(&entry->data);
+ kfree(entry);
+}
+
+
+int
+register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
+ void *data)
+{
+ struct ftrace_func_probe *entry;
+ struct ftrace_page *pg;
+ struct dyn_ftrace *rec;
+ int type, len, not;
+ unsigned long key;
+ int count = 0;
+ char *search;
+
+ type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
+ len = strlen(search);
+
+ /* we do not support '!' for function probes */
+ if (WARN_ON(not))
+ return -EINVAL;
+
+ mutex_lock(&ftrace_lock);
+ do_for_each_ftrace_rec(pg, rec) {
+
+ if (rec->flags & FTRACE_FL_FAILED)
+ continue;
+
+ if (!ftrace_match_record(rec, search, len, type))
+ continue;
+
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry) {
+ /* If we did not process any, then return error */
+ if (!count)
+ count = -ENOMEM;
+ goto out_unlock;
+ }
+
+ count++;
+
+ entry->data = data;
+
+ /*
+ * The caller might want to do something special
+ * for each function we find. We call the callback
+ * to give the caller an opportunity to do so.
+ */
+ if (ops->callback) {
+ if (ops->callback(rec->ip, &entry->data) < 0) {
+ /* caller does not like this func */
+ kfree(entry);
continue;
- kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
- switch (type) {
- case MATCH_FULL:
- if (strcmp(str, buff) == 0)
- matched = 1;
- break;
- case MATCH_FRONT_ONLY:
- if (memcmp(str, buff, match) == 0)
- matched = 1;
- break;
- case MATCH_MIDDLE_ONLY:
- if (strstr(str, search))
- matched = 1;
- break;
- case MATCH_END_ONLY:
- ptr = strstr(str, search);
- if (ptr && (ptr[search_len] == 0))
- matched = 1;
- break;
}
- if (matched) {
- if (not)
- rec->flags &= ~flag;
- else
- rec->flags |= flag;
+ }
+
+ entry->ops = ops;
+ entry->ip = rec->ip;
+
+ key = hash_long(entry->ip, FTRACE_HASH_BITS);
+ hlist_add_head_rcu(&entry->node, &ftrace_func_hash[key]);
+
+ } while_for_each_ftrace_rec();
+ __enable_ftrace_function_probe();
+
+ out_unlock:
+ mutex_unlock(&ftrace_lock);
+
+ return count;
+}
+
+enum {
+ PROBE_TEST_FUNC = 1,
+ PROBE_TEST_DATA = 2
+};
+
+static void
+__unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
+ void *data, int flags)
+{
+ struct ftrace_func_probe *entry;
+ struct hlist_node *n, *tmp;
+ char str[KSYM_SYMBOL_LEN];
+ int type = MATCH_FULL;
+ int i, len = 0;
+ char *search;
+
+ if (glob && (strcmp(glob, "*") || !strlen(glob)))
+ glob = NULL;
+ else {
+ int not;
+
+ type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
+ len = strlen(search);
+
+ /* we do not support '!' for function probes */
+ if (WARN_ON(not))
+ return;
+ }
+
+ mutex_lock(&ftrace_lock);
+ for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
+ struct hlist_head *hhd = &ftrace_func_hash[i];
+
+ hlist_for_each_entry_safe(entry, n, tmp, hhd, node) {
+
+ /* break up if statements for readability */
+ if ((flags & PROBE_TEST_FUNC) && entry->ops != ops)
+ continue;
+
+ if ((flags & PROBE_TEST_DATA) && entry->data != data)
+ continue;
+
+ /* do this last, since it is the most expensive */
+ if (glob) {
+ kallsyms_lookup(entry->ip, NULL, NULL,
+ NULL, str);
+ if (!ftrace_match(str, glob, len, type))
+ continue;
}
+
+ hlist_del(&entry->node);
+ call_rcu(&entry->rcu, ftrace_free_entry_rcu);
}
- pg = pg->next;
}
- spin_unlock(&ftrace_lock);
+ __disable_ftrace_function_probe();
+ mutex_unlock(&ftrace_lock);
+}
+
+void
+unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
+ void *data)
+{
+ __unregister_ftrace_function_probe(glob, ops, data,
+ PROBE_TEST_FUNC | PROBE_TEST_DATA);
+}
+
+void
+unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops)
+{
+ __unregister_ftrace_function_probe(glob, ops, NULL, PROBE_TEST_FUNC);
+}
+
+void unregister_ftrace_function_probe_all(char *glob)
+{
+ __unregister_ftrace_function_probe(glob, NULL, NULL, 0);
+}
+
+static LIST_HEAD(ftrace_commands);
+static DEFINE_MUTEX(ftrace_cmd_mutex);
+
+int register_ftrace_command(struct ftrace_func_command *cmd)
+{
+ struct ftrace_func_command *p;
+ int ret = 0;
+
+ mutex_lock(&ftrace_cmd_mutex);
+ list_for_each_entry(p, &ftrace_commands, list) {
+ if (strcmp(cmd->name, p->name) == 0) {
+ ret = -EBUSY;
+ goto out_unlock;
+ }
+ }
+ list_add(&cmd->list, &ftrace_commands);
+ out_unlock:
+ mutex_unlock(&ftrace_cmd_mutex);
+
+ return ret;
+}
+
+int unregister_ftrace_command(struct ftrace_func_command *cmd)
+{
+ struct ftrace_func_command *p, *n;
+ int ret = -ENODEV;
+
+ mutex_lock(&ftrace_cmd_mutex);
+ list_for_each_entry_safe(p, n, &ftrace_commands, list) {
+ if (strcmp(cmd->name, p->name) == 0) {
+ ret = 0;
+ list_del_init(&p->list);
+ goto out_unlock;
+ }
+ }
+ out_unlock:
+ mutex_unlock(&ftrace_cmd_mutex);
+
+ return ret;
+}
+
+static int ftrace_process_regex(char *buff, int len, int enable)
+{
+ char *func, *command, *next = buff;
+ struct ftrace_func_command *p;
+ int ret = -EINVAL;
+
+ func = strsep(&next, ":");
+
+ if (!next) {
+ ftrace_match_records(func, len, enable);
+ return 0;
+ }
+
+ /* command found */
+
+ command = strsep(&next, ":");
+
+ mutex_lock(&ftrace_cmd_mutex);
+ list_for_each_entry(p, &ftrace_commands, list) {
+ if (strcmp(p->name, command) == 0) {
+ ret = p->func(func, command, next, enable);
+ goto out_unlock;
+ }
+ }
+ out_unlock:
+ mutex_unlock(&ftrace_cmd_mutex);
+
+ return ret;
}
static ssize_t
@@ -1187,7 +1748,10 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
if (isspace(ch)) {
iter->filtered++;
iter->buffer[iter->buffer_idx] = 0;
- ftrace_match(iter->buffer, iter->buffer_idx, enable);
+ ret = ftrace_process_regex(iter->buffer,
+ iter->buffer_idx, enable);
+ if (ret)
+ goto out;
iter->buffer_idx = 0;
} else
iter->flags |= FTRACE_ITER_CONT;
@@ -1226,7 +1790,7 @@ ftrace_set_regex(unsigned char *buf, int len, int reset, int enable)
if (reset)
ftrace_filter_reset(enable);
if (buf)
- ftrace_match(buf, len, enable);
+ ftrace_match_records(buf, len, enable);
mutex_unlock(&ftrace_regex_lock);
}
@@ -1276,15 +1840,13 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
if (iter->buffer_idx) {
iter->filtered++;
iter->buffer[iter->buffer_idx] = 0;
- ftrace_match(iter->buffer, iter->buffer_idx, enable);
+ ftrace_match_records(iter->buffer, iter->buffer_idx, enable);
}
- mutex_lock(&ftrace_sysctl_lock);
- mutex_lock(&ftrace_start_lock);
+ mutex_lock(&ftrace_lock);
if (ftrace_start_up && ftrace_enabled)
ftrace_run_update_code(FTRACE_ENABLE_CALLS);
- mutex_unlock(&ftrace_start_lock);
- mutex_unlock(&ftrace_sysctl_lock);
+ mutex_unlock(&ftrace_lock);
kfree(iter);
mutex_unlock(&ftrace_regex_lock);
@@ -1303,31 +1865,31 @@ ftrace_notrace_release(struct inode *inode, struct file *file)
return ftrace_regex_release(inode, file, 0);
}
-static struct file_operations ftrace_avail_fops = {
+static const struct file_operations ftrace_avail_fops = {
.open = ftrace_avail_open,
.read = seq_read,
.llseek = seq_lseek,
.release = ftrace_avail_release,
};
-static struct file_operations ftrace_failures_fops = {
+static const struct file_operations ftrace_failures_fops = {
.open = ftrace_failures_open,
.read = seq_read,
.llseek = seq_lseek,
.release = ftrace_avail_release,
};
-static struct file_operations ftrace_filter_fops = {
+static const struct file_operations ftrace_filter_fops = {
.open = ftrace_filter_open,
- .read = ftrace_regex_read,
+ .read = seq_read,
.write = ftrace_filter_write,
.llseek = ftrace_regex_lseek,
.release = ftrace_filter_release,
};
-static struct file_operations ftrace_notrace_fops = {
+static const struct file_operations ftrace_notrace_fops = {
.open = ftrace_notrace_open,
- .read = ftrace_regex_read,
+ .read = seq_read,
.write = ftrace_notrace_write,
.llseek = ftrace_regex_lseek,
.release = ftrace_notrace_release,
@@ -1360,6 +1922,10 @@ static void *g_start(struct seq_file *m, loff_t *pos)
mutex_lock(&graph_lock);
+ /* Nothing, tell g_show to print all functions are enabled */
+ if (!ftrace_graph_count && !*pos)
+ return (void *)1;
+
p = g_next(m, p, pos);
return p;
@@ -1378,6 +1944,11 @@ static int g_show(struct seq_file *m, void *v)
if (!ptr)
return 0;
+ if (ptr == (unsigned long *)1) {
+ seq_printf(m, "#### all functions enabled ####\n");
+ return 0;
+ }
+
kallsyms_lookup(*ptr, NULL, NULL, NULL, str);
seq_printf(m, "%s\n", str);
@@ -1420,53 +1991,53 @@ ftrace_graph_open(struct inode *inode, struct file *file)
return ret;
}
-static ssize_t
-ftrace_graph_read(struct file *file, char __user *ubuf,
- size_t cnt, loff_t *ppos)
-{
- if (file->f_mode & FMODE_READ)
- return seq_read(file, ubuf, cnt, ppos);
- else
- return -EPERM;
-}
-
static int
-ftrace_set_func(unsigned long *array, int idx, char *buffer)
+ftrace_set_func(unsigned long *array, int *idx, char *buffer)
{
- char str[KSYM_SYMBOL_LEN];
struct dyn_ftrace *rec;
struct ftrace_page *pg;
+ int search_len;
int found = 0;
- int i, j;
+ int type, not;
+ char *search;
+ bool exists;
+ int i;
if (ftrace_disabled)
return -ENODEV;
- /* should not be called from interrupt context */
- spin_lock(&ftrace_lock);
+ /* decode regex */
+ type = ftrace_setup_glob(buffer, strlen(buffer), &search, &not);
+ if (not)
+ return -EINVAL;
+
+ search_len = strlen(search);
- for (pg = ftrace_pages_start; pg; pg = pg->next) {
- for (i = 0; i < pg->index; i++) {
- rec = &pg->records[i];
+ mutex_lock(&ftrace_lock);
+ do_for_each_ftrace_rec(pg, rec) {
- if (rec->flags & (FTRACE_FL_FAILED | FTRACE_FL_FREE))
- continue;
+ if (*idx >= FTRACE_GRAPH_MAX_FUNCS)
+ break;
+
+ if (rec->flags & (FTRACE_FL_FAILED | FTRACE_FL_FREE))
+ continue;
- kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
- if (strcmp(str, buffer) == 0) {
+ if (ftrace_match_record(rec, search, search_len, type)) {
+ /* ensure it is not already in the array */
+ exists = false;
+ for (i = 0; i < *idx; i++)
+ if (array[i] == rec->ip) {
+ exists = true;
+ break;
+ }
+ if (!exists) {
+ array[(*idx)++] = rec->ip;
found = 1;
- for (j = 0; j < idx; j++)
- if (array[j] == rec->ip) {
- found = 0;
- break;
- }
- if (found)
- array[idx] = rec->ip;
- break;
}
}
- }
- spin_unlock(&ftrace_lock);
+ } while_for_each_ftrace_rec();
+
+ mutex_unlock(&ftrace_lock);
return found ? 0 : -EINVAL;
}
@@ -1534,13 +2105,11 @@ ftrace_graph_write(struct file *file, const char __user *ubuf,
}
buffer[index] = 0;
- /* we allow only one at a time */
- ret = ftrace_set_func(array, ftrace_graph_count, buffer);
+ /* we allow only one expression at a time */
+ ret = ftrace_set_func(array, &ftrace_graph_count, buffer);
if (ret)
goto out;
- ftrace_graph_count++;
-
file->f_pos += read;
ret = read;
@@ -1552,7 +2121,7 @@ ftrace_graph_write(struct file *file, const char __user *ubuf,
static const struct file_operations ftrace_graph_fops = {
.open = ftrace_graph_open,
- .read = ftrace_graph_read,
+ .read = seq_read,
.write = ftrace_graph_write,
};
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
@@ -1604,7 +2173,7 @@ static int ftrace_convert_nops(struct module *mod,
unsigned long addr;
unsigned long flags;
- mutex_lock(&ftrace_start_lock);
+ mutex_lock(&ftrace_lock);
p = start;
while (p < end) {
addr = ftrace_call_adjust(*p++);
@@ -1623,7 +2192,7 @@ static int ftrace_convert_nops(struct module *mod,
local_irq_save(flags);
ftrace_update_code(mod);
local_irq_restore(flags);
- mutex_unlock(&ftrace_start_lock);
+ mutex_unlock(&ftrace_lock);
return 0;
}
@@ -1700,7 +2269,7 @@ ftrace_pid_read(struct file *file, char __user *ubuf,
if (ftrace_pid_trace == ftrace_swapper_pid)
r = sprintf(buf, "swapper tasks\n");
else if (ftrace_pid_trace)
- r = sprintf(buf, "%u\n", pid_nr(ftrace_pid_trace));
+ r = sprintf(buf, "%u\n", pid_vnr(ftrace_pid_trace));
else
r = sprintf(buf, "no pid\n");
@@ -1796,7 +2365,7 @@ ftrace_pid_write(struct file *filp, const char __user *ubuf,
if (ret < 0)
return ret;
- mutex_lock(&ftrace_start_lock);
+ mutex_lock(&ftrace_lock);
if (val < 0) {
/* disable pid tracing */
if (!ftrace_pid_trace)
@@ -1835,12 +2404,12 @@ ftrace_pid_write(struct file *filp, const char __user *ubuf,
ftrace_startup_enable(0);
out:
- mutex_unlock(&ftrace_start_lock);
+ mutex_unlock(&ftrace_lock);
return cnt;
}
-static struct file_operations ftrace_pid_fops = {
+static const struct file_operations ftrace_pid_fops = {
.read = ftrace_pid_read,
.write = ftrace_pid_write,
};
@@ -1863,7 +2432,6 @@ static __init int ftrace_init_debugfs(void)
"'set_ftrace_pid' entry\n");
return 0;
}
-
fs_initcall(ftrace_init_debugfs);
/**
@@ -1898,17 +2466,17 @@ int register_ftrace_function(struct ftrace_ops *ops)
if (unlikely(ftrace_disabled))
return -1;
- mutex_lock(&ftrace_sysctl_lock);
+ mutex_lock(&ftrace_lock);
ret = __register_ftrace_function(ops);
ftrace_startup(0);
- mutex_unlock(&ftrace_sysctl_lock);
+ mutex_unlock(&ftrace_lock);
return ret;
}
/**
- * unregister_ftrace_function - unresgister a function for profiling.
+ * unregister_ftrace_function - unregister a function for profiling.
* @ops - ops structure that holds the function to unregister
*
* Unregister a function that was added to be called by ftrace profiling.
@@ -1917,10 +2485,10 @@ int unregister_ftrace_function(struct ftrace_ops *ops)
{
int ret;
- mutex_lock(&ftrace_sysctl_lock);
+ mutex_lock(&ftrace_lock);
ret = __unregister_ftrace_function(ops);
ftrace_shutdown(0);
- mutex_unlock(&ftrace_sysctl_lock);
+ mutex_unlock(&ftrace_lock);
return ret;
}
@@ -1935,7 +2503,7 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
if (unlikely(ftrace_disabled))
return -ENODEV;
- mutex_lock(&ftrace_sysctl_lock);
+ mutex_lock(&ftrace_lock);
ret = proc_dointvec(table, write, file, buffer, lenp, ppos);
@@ -1964,7 +2532,7 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
}
out:
- mutex_unlock(&ftrace_sysctl_lock);
+ mutex_unlock(&ftrace_lock);
return ret;
}
@@ -2029,6 +2597,38 @@ free:
return ret;
}
+static void
+ftrace_graph_probe_sched_switch(struct rq *__rq, struct task_struct *prev,
+ struct task_struct *next)
+{
+ unsigned long long timestamp;
+ int index;
+
+ /*
+ * Does the user want to count the time a function was asleep.
+ * If so, do not update the time stamps.
+ */
+ if (trace_flags & TRACE_ITER_SLEEP_TIME)
+ return;
+
+ timestamp = trace_clock_local();
+
+ prev->ftrace_timestamp = timestamp;
+
+ /* only process tasks that we timestamped */
+ if (!next->ftrace_timestamp)
+ return;
+
+ /*
+ * Update all the counters in next to make up for the
+ * time next was sleeping.
+ */
+ timestamp -= next->ftrace_timestamp;
+
+ for (index = next->curr_ret_stack; index >= 0; index--)
+ next->ret_stack[index].calltime += timestamp;
+}
+
/* Allocate a return stack for each task */
static int start_graph_tracing(void)
{
@@ -2050,6 +2650,13 @@ static int start_graph_tracing(void)
ret = alloc_retstack_tasklist(ret_stack_list);
} while (ret == -EAGAIN);
+ if (!ret) {
+ ret = register_trace_sched_switch(ftrace_graph_probe_sched_switch);
+ if (ret)
+ pr_info("ftrace_graph: Couldn't activate tracepoint"
+ " probe to kernel_sched_switch\n");
+ }
+
kfree(ret_stack_list);
return ret;
}
@@ -2080,7 +2687,13 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc,
{
int ret = 0;
- mutex_lock(&ftrace_sysctl_lock);
+ mutex_lock(&ftrace_lock);
+
+ /* we currently allow only one tracer registered at a time */
+ if (atomic_read(&ftrace_graph_active)) {
+ ret = -EBUSY;
+ goto out;
+ }
ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call;
register_pm_notifier(&ftrace_suspend_notifier);
@@ -2098,21 +2711,26 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc,
ftrace_startup(FTRACE_START_FUNC_RET);
out:
- mutex_unlock(&ftrace_sysctl_lock);
+ mutex_unlock(&ftrace_lock);
return ret;
}
void unregister_ftrace_graph(void)
{
- mutex_lock(&ftrace_sysctl_lock);
+ mutex_lock(&ftrace_lock);
+
+ if (!unlikely(atomic_read(&ftrace_graph_active)))
+ goto out;
atomic_dec(&ftrace_graph_active);
+ unregister_trace_sched_switch(ftrace_graph_probe_sched_switch);
ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
ftrace_graph_entry = ftrace_graph_entry_stub;
ftrace_shutdown(FTRACE_STOP_FUNC_RET);
unregister_pm_notifier(&ftrace_suspend_notifier);
- mutex_unlock(&ftrace_sysctl_lock);
+ out:
+ mutex_unlock(&ftrace_lock);
}
/* Allocate a return stack for newly created task */
@@ -2127,6 +2745,7 @@ void ftrace_graph_init_task(struct task_struct *t)
t->curr_ret_stack = -1;
atomic_set(&t->tracing_graph_pause, 0);
atomic_set(&t->trace_overrun, 0);
+ t->ftrace_timestamp = 0;
} else
t->ret_stack = NULL;
}
diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c
new file mode 100644
index 00000000000..5011f4d91e3
--- /dev/null
+++ b/kernel/trace/kmemtrace.c
@@ -0,0 +1,464 @@
+/*
+ * Memory allocator tracing
+ *
+ * Copyright (C) 2008 Eduard - Gabriel Munteanu
+ * Copyright (C) 2008 Pekka Enberg <penberg@cs.helsinki.fi>
+ * Copyright (C) 2008 Frederic Weisbecker <fweisbec@gmail.com>
+ */
+
+#include <linux/tracepoint.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/dcache.h>
+#include <linux/fs.h>
+
+#include <trace/kmemtrace.h>
+
+#include "trace_output.h"
+#include "trace.h"
+
+/* Select an alternative, minimalistic output than the original one */
+#define TRACE_KMEM_OPT_MINIMAL 0x1
+
+static struct tracer_opt kmem_opts[] = {
+ /* Default disable the minimalistic output */
+ { TRACER_OPT(kmem_minimalistic, TRACE_KMEM_OPT_MINIMAL) },
+ { }
+};
+
+static struct tracer_flags kmem_tracer_flags = {
+ .val = 0,
+ .opts = kmem_opts
+};
+
+static struct trace_array *kmemtrace_array;
+
+/* Trace allocations */
+static inline void kmemtrace_alloc(enum kmemtrace_type_id type_id,
+ unsigned long call_site,
+ const void *ptr,
+ size_t bytes_req,
+ size_t bytes_alloc,
+ gfp_t gfp_flags,
+ int node)
+{
+ struct trace_array *tr = kmemtrace_array;
+ struct kmemtrace_alloc_entry *entry;
+ struct ring_buffer_event *event;
+
+ event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ if (!event)
+ return;
+
+ entry = ring_buffer_event_data(event);
+ tracing_generic_entry_update(&entry->ent, 0, 0);
+
+ entry->ent.type = TRACE_KMEM_ALLOC;
+ entry->type_id = type_id;
+ entry->call_site = call_site;
+ entry->ptr = ptr;
+ entry->bytes_req = bytes_req;
+ entry->bytes_alloc = bytes_alloc;
+ entry->gfp_flags = gfp_flags;
+ entry->node = node;
+
+ ring_buffer_unlock_commit(tr->buffer, event);
+
+ trace_wake_up();
+}
+
+static inline void kmemtrace_free(enum kmemtrace_type_id type_id,
+ unsigned long call_site,
+ const void *ptr)
+{
+ struct trace_array *tr = kmemtrace_array;
+ struct kmemtrace_free_entry *entry;
+ struct ring_buffer_event *event;
+
+ event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ if (!event)
+ return;
+ entry = ring_buffer_event_data(event);
+ tracing_generic_entry_update(&entry->ent, 0, 0);
+
+ entry->ent.type = TRACE_KMEM_FREE;
+ entry->type_id = type_id;
+ entry->call_site = call_site;
+ entry->ptr = ptr;
+
+ ring_buffer_unlock_commit(tr->buffer, event);
+
+ trace_wake_up();
+}
+
+static void kmemtrace_kmalloc(unsigned long call_site,
+ const void *ptr,
+ size_t bytes_req,
+ size_t bytes_alloc,
+ gfp_t gfp_flags)
+{
+ kmemtrace_alloc(KMEMTRACE_TYPE_KMALLOC, call_site, ptr,
+ bytes_req, bytes_alloc, gfp_flags, -1);
+}
+
+static void kmemtrace_kmem_cache_alloc(unsigned long call_site,
+ const void *ptr,
+ size_t bytes_req,
+ size_t bytes_alloc,
+ gfp_t gfp_flags)
+{
+ kmemtrace_alloc(KMEMTRACE_TYPE_CACHE, call_site, ptr,
+ bytes_req, bytes_alloc, gfp_flags, -1);
+}
+
+static void kmemtrace_kmalloc_node(unsigned long call_site,
+ const void *ptr,
+ size_t bytes_req,
+ size_t bytes_alloc,
+ gfp_t gfp_flags,
+ int node)
+{
+ kmemtrace_alloc(KMEMTRACE_TYPE_KMALLOC, call_site, ptr,
+ bytes_req, bytes_alloc, gfp_flags, node);
+}
+
+static void kmemtrace_kmem_cache_alloc_node(unsigned long call_site,
+ const void *ptr,
+ size_t bytes_req,
+ size_t bytes_alloc,
+ gfp_t gfp_flags,
+ int node)
+{
+ kmemtrace_alloc(KMEMTRACE_TYPE_CACHE, call_site, ptr,
+ bytes_req, bytes_alloc, gfp_flags, node);
+}
+
+static void kmemtrace_kfree(unsigned long call_site, const void *ptr)
+{
+ kmemtrace_free(KMEMTRACE_TYPE_KMALLOC, call_site, ptr);
+}
+
+static void kmemtrace_kmem_cache_free(unsigned long call_site, const void *ptr)
+{
+ kmemtrace_free(KMEMTRACE_TYPE_CACHE, call_site, ptr);
+}
+
+static int kmemtrace_start_probes(void)
+{
+ int err;
+
+ err = register_trace_kmalloc(kmemtrace_kmalloc);
+ if (err)
+ return err;
+ err = register_trace_kmem_cache_alloc(kmemtrace_kmem_cache_alloc);
+ if (err)
+ return err;
+ err = register_trace_kmalloc_node(kmemtrace_kmalloc_node);
+ if (err)
+ return err;
+ err = register_trace_kmem_cache_alloc_node(kmemtrace_kmem_cache_alloc_node);
+ if (err)
+ return err;
+ err = register_trace_kfree(kmemtrace_kfree);
+ if (err)
+ return err;
+ err = register_trace_kmem_cache_free(kmemtrace_kmem_cache_free);
+
+ return err;
+}
+
+static void kmemtrace_stop_probes(void)
+{
+ unregister_trace_kmalloc(kmemtrace_kmalloc);
+ unregister_trace_kmem_cache_alloc(kmemtrace_kmem_cache_alloc);
+ unregister_trace_kmalloc_node(kmemtrace_kmalloc_node);
+ unregister_trace_kmem_cache_alloc_node(kmemtrace_kmem_cache_alloc_node);
+ unregister_trace_kfree(kmemtrace_kfree);
+ unregister_trace_kmem_cache_free(kmemtrace_kmem_cache_free);
+}
+
+static int kmem_trace_init(struct trace_array *tr)
+{
+ int cpu;
+ kmemtrace_array = tr;
+
+ for_each_cpu_mask(cpu, cpu_possible_map)
+ tracing_reset(tr, cpu);
+
+ kmemtrace_start_probes();
+
+ return 0;
+}
+
+static void kmem_trace_reset(struct trace_array *tr)
+{
+ kmemtrace_stop_probes();
+}
+
+static void kmemtrace_headers(struct seq_file *s)
+{
+ /* Don't need headers for the original kmemtrace output */
+ if (!(kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL))
+ return;
+
+ seq_printf(s, "#\n");
+ seq_printf(s, "# ALLOC TYPE REQ GIVEN FLAGS "
+ " POINTER NODE CALLER\n");
+ seq_printf(s, "# FREE | | | | "
+ " | | | |\n");
+ seq_printf(s, "# |\n\n");
+}
+
+/*
+ * The following functions give the original output from kmemtrace,
+ * plus the origin CPU, since reordering occurs in-kernel now.
+ */
+
+#define KMEMTRACE_USER_ALLOC 0
+#define KMEMTRACE_USER_FREE 1
+
+struct kmemtrace_user_event {
+ u8 event_id;
+ u8 type_id;
+ u16 event_size;
+ u32 cpu;
+ u64 timestamp;
+ unsigned long call_site;
+ unsigned long ptr;
+};
+
+struct kmemtrace_user_event_alloc {
+ size_t bytes_req;
+ size_t bytes_alloc;
+ unsigned gfp_flags;
+ int node;
+};
+
+static enum print_line_t
+kmemtrace_print_alloc_user(struct trace_iterator *iter,
+ struct kmemtrace_alloc_entry *entry)
+{
+ struct kmemtrace_user_event_alloc *ev_alloc;
+ struct trace_seq *s = &iter->seq;
+ struct kmemtrace_user_event *ev;
+
+ ev = trace_seq_reserve(s, sizeof(*ev));
+ if (!ev)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ ev->event_id = KMEMTRACE_USER_ALLOC;
+ ev->type_id = entry->type_id;
+ ev->event_size = sizeof(*ev) + sizeof(*ev_alloc);
+ ev->cpu = iter->cpu;
+ ev->timestamp = iter->ts;
+ ev->call_site = entry->call_site;
+ ev->ptr = (unsigned long)entry->ptr;
+
+ ev_alloc = trace_seq_reserve(s, sizeof(*ev_alloc));
+ if (!ev_alloc)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ ev_alloc->bytes_req = entry->bytes_req;
+ ev_alloc->bytes_alloc = entry->bytes_alloc;
+ ev_alloc->gfp_flags = entry->gfp_flags;
+ ev_alloc->node = entry->node;
+
+ return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t
+kmemtrace_print_free_user(struct trace_iterator *iter,
+ struct kmemtrace_free_entry *entry)
+{
+ struct trace_seq *s = &iter->seq;
+ struct kmemtrace_user_event *ev;
+
+ ev = trace_seq_reserve(s, sizeof(*ev));
+ if (!ev)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ ev->event_id = KMEMTRACE_USER_FREE;
+ ev->type_id = entry->type_id;
+ ev->event_size = sizeof(*ev);
+ ev->cpu = iter->cpu;
+ ev->timestamp = iter->ts;
+ ev->call_site = entry->call_site;
+ ev->ptr = (unsigned long)entry->ptr;
+
+ return TRACE_TYPE_HANDLED;
+}
+
+/* The two other following provide a more minimalistic output */
+static enum print_line_t
+kmemtrace_print_alloc_compress(struct trace_iterator *iter,
+ struct kmemtrace_alloc_entry *entry)
+{
+ struct trace_seq *s = &iter->seq;
+ int ret;
+
+ /* Alloc entry */
+ ret = trace_seq_printf(s, " + ");
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* Type */
+ switch (entry->type_id) {
+ case KMEMTRACE_TYPE_KMALLOC:
+ ret = trace_seq_printf(s, "K ");
+ break;
+ case KMEMTRACE_TYPE_CACHE:
+ ret = trace_seq_printf(s, "C ");
+ break;
+ case KMEMTRACE_TYPE_PAGES:
+ ret = trace_seq_printf(s, "P ");
+ break;
+ default:
+ ret = trace_seq_printf(s, "? ");
+ }
+
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* Requested */
+ ret = trace_seq_printf(s, "%4zu ", entry->bytes_req);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* Allocated */
+ ret = trace_seq_printf(s, "%4zu ", entry->bytes_alloc);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* Flags
+ * TODO: would be better to see the name of the GFP flag names
+ */
+ ret = trace_seq_printf(s, "%08x ", entry->gfp_flags);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* Pointer to allocated */
+ ret = trace_seq_printf(s, "0x%tx ", (ptrdiff_t)entry->ptr);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* Node */
+ ret = trace_seq_printf(s, "%4d ", entry->node);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* Call site */
+ ret = seq_print_ip_sym(s, entry->call_site, 0);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ if (!trace_seq_printf(s, "\n"))
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t
+kmemtrace_print_free_compress(struct trace_iterator *iter,
+ struct kmemtrace_free_entry *entry)
+{
+ struct trace_seq *s = &iter->seq;
+ int ret;
+
+ /* Free entry */
+ ret = trace_seq_printf(s, " - ");
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* Type */
+ switch (entry->type_id) {
+ case KMEMTRACE_TYPE_KMALLOC:
+ ret = trace_seq_printf(s, "K ");
+ break;
+ case KMEMTRACE_TYPE_CACHE:
+ ret = trace_seq_printf(s, "C ");
+ break;
+ case KMEMTRACE_TYPE_PAGES:
+ ret = trace_seq_printf(s, "P ");
+ break;
+ default:
+ ret = trace_seq_printf(s, "? ");
+ }
+
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* Skip requested/allocated/flags */
+ ret = trace_seq_printf(s, " ");
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* Pointer to allocated */
+ ret = trace_seq_printf(s, "0x%tx ", (ptrdiff_t)entry->ptr);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* Skip node */
+ ret = trace_seq_printf(s, " ");
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* Call site */
+ ret = seq_print_ip_sym(s, entry->call_site, 0);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ if (!trace_seq_printf(s, "\n"))
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t kmemtrace_print_line(struct trace_iterator *iter)
+{
+ struct trace_entry *entry = iter->ent;
+
+ switch (entry->type) {
+ case TRACE_KMEM_ALLOC: {
+ struct kmemtrace_alloc_entry *field;
+
+ trace_assign_type(field, entry);
+ if (kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL)
+ return kmemtrace_print_alloc_compress(iter, field);
+ else
+ return kmemtrace_print_alloc_user(iter, field);
+ }
+
+ case TRACE_KMEM_FREE: {
+ struct kmemtrace_free_entry *field;
+
+ trace_assign_type(field, entry);
+ if (kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL)
+ return kmemtrace_print_free_compress(iter, field);
+ else
+ return kmemtrace_print_free_user(iter, field);
+ }
+
+ default:
+ return TRACE_TYPE_UNHANDLED;
+ }
+}
+
+static struct tracer kmem_tracer __read_mostly = {
+ .name = "kmemtrace",
+ .init = kmem_trace_init,
+ .reset = kmem_trace_reset,
+ .print_line = kmemtrace_print_line,
+ .print_header = kmemtrace_headers,
+ .flags = &kmem_tracer_flags
+};
+
+void kmemtrace_init(void)
+{
+ /* earliest opportunity to start kmem tracing */
+}
+
+static int __init init_kmem_tracer(void)
+{
+ return register_tracer(&kmem_tracer);
+}
+device_initcall(init_kmem_tracer);
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index bd38c5cfd8a..960cbf44c84 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -4,21 +4,92 @@
* Copyright (C) 2008 Steven Rostedt <srostedt@redhat.com>
*/
#include <linux/ring_buffer.h>
+#include <linux/trace_clock.h>
+#include <linux/ftrace_irq.h>
#include <linux/spinlock.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
+#include <linux/hardirq.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/cpu.h>
#include <linux/fs.h>
#include "trace.h"
/*
+ * The ring buffer is made up of a list of pages. A separate list of pages is
+ * allocated for each CPU. A writer may only write to a buffer that is
+ * associated with the CPU it is currently executing on. A reader may read
+ * from any per cpu buffer.
+ *
+ * The reader is special. For each per cpu buffer, the reader has its own
+ * reader page. When a reader has read the entire reader page, this reader
+ * page is swapped with another page in the ring buffer.
+ *
+ * Now, as long as the writer is off the reader page, the reader can do what
+ * ever it wants with that page. The writer will never write to that page
+ * again (as long as it is out of the ring buffer).
+ *
+ * Here's some silly ASCII art.
+ *
+ * +------+
+ * |reader| RING BUFFER
+ * |page |
+ * +------+ +---+ +---+ +---+
+ * | |-->| |-->| |
+ * +---+ +---+ +---+
+ * ^ |
+ * | |
+ * +---------------+
+ *
+ *
+ * +------+
+ * |reader| RING BUFFER
+ * |page |------------------v
+ * +------+ +---+ +---+ +---+
+ * | |-->| |-->| |
+ * +---+ +---+ +---+
+ * ^ |
+ * | |
+ * +---------------+
+ *
+ *
+ * +------+
+ * |reader| RING BUFFER
+ * |page |------------------v
+ * +------+ +---+ +---+ +---+
+ * ^ | |-->| |-->| |
+ * | +---+ +---+ +---+
+ * | |
+ * | |
+ * +------------------------------+
+ *
+ *
+ * +------+
+ * |buffer| RING BUFFER
+ * |page |------------------v
+ * +------+ +---+ +---+ +---+
+ * ^ | | | |-->| |
+ * | New +---+ +---+ +---+
+ * | Reader------^ |
+ * | page |
+ * +------------------------------+
+ *
+ *
+ * After we make this swap, the reader can hand this page off to the splice
+ * code and be done with it. It can even allocate a new page if it needs to
+ * and swap that into the ring buffer.
+ *
+ * We will be using cmpxchg soon to make all this lockless.
+ *
+ */
+
+/*
* A fast way to enable or disable all ring buffers is to
* call tracing_on or tracing_off. Turning off the ring buffers
* prevents all ring buffers from being recorded to.
@@ -57,7 +128,9 @@ enum {
RB_BUFFERS_DISABLED = 1 << RB_BUFFERS_DISABLED_BIT,
};
-static long ring_buffer_flags __read_mostly = RB_BUFFERS_ON;
+static unsigned long ring_buffer_flags __read_mostly = RB_BUFFERS_ON;
+
+#define BUF_PAGE_HDR_SIZE offsetof(struct buffer_data_page, data)
/**
* tracing_on - enable all tracing buffers
@@ -89,59 +162,92 @@ EXPORT_SYMBOL_GPL(tracing_off);
* tracing_off_permanent - permanently disable ring buffers
*
* This function, once called, will disable all ring buffers
- * permanenty.
+ * permanently.
*/
void tracing_off_permanent(void)
{
set_bit(RB_BUFFERS_DISABLED_BIT, &ring_buffer_flags);
}
+/**
+ * tracing_is_on - show state of ring buffers enabled
+ */
+int tracing_is_on(void)
+{
+ return ring_buffer_flags == RB_BUFFERS_ON;
+}
+EXPORT_SYMBOL_GPL(tracing_is_on);
+
#include "trace.h"
-/* Up this if you want to test the TIME_EXTENTS and normalization */
-#define DEBUG_SHIFT 0
+#define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array))
+#define RB_ALIGNMENT 4U
+#define RB_MAX_SMALL_DATA 28
+
+enum {
+ RB_LEN_TIME_EXTEND = 8,
+ RB_LEN_TIME_STAMP = 16,
+};
-/* FIXME!!! */
-u64 ring_buffer_time_stamp(int cpu)
+static inline int rb_null_event(struct ring_buffer_event *event)
{
- u64 time;
+ return event->type == RINGBUF_TYPE_PADDING && event->time_delta == 0;
+}
- preempt_disable_notrace();
- /* shift to debug/test normalization and TIME_EXTENTS */
- time = sched_clock() << DEBUG_SHIFT;
- preempt_enable_no_resched_notrace();
+static inline int rb_discarded_event(struct ring_buffer_event *event)
+{
+ return event->type == RINGBUF_TYPE_PADDING && event->time_delta;
+}
- return time;
+static void rb_event_set_padding(struct ring_buffer_event *event)
+{
+ event->type = RINGBUF_TYPE_PADDING;
+ event->time_delta = 0;
}
-EXPORT_SYMBOL_GPL(ring_buffer_time_stamp);
-void ring_buffer_normalize_time_stamp(int cpu, u64 *ts)
+/**
+ * ring_buffer_event_discard - discard an event in the ring buffer
+ * @buffer: the ring buffer
+ * @event: the event to discard
+ *
+ * Sometimes a event that is in the ring buffer needs to be ignored.
+ * This function lets the user discard an event in the ring buffer
+ * and then that event will not be read later.
+ *
+ * Note, it is up to the user to be careful with this, and protect
+ * against races. If the user discards an event that has been consumed
+ * it is possible that it could corrupt the ring buffer.
+ */
+void ring_buffer_event_discard(struct ring_buffer_event *event)
{
- /* Just stupid testing the normalize function and deltas */
- *ts >>= DEBUG_SHIFT;
+ event->type = RINGBUF_TYPE_PADDING;
+ /* time delta must be non zero */
+ if (!event->time_delta)
+ event->time_delta = 1;
}
-EXPORT_SYMBOL_GPL(ring_buffer_normalize_time_stamp);
-#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
+static unsigned
+rb_event_data_length(struct ring_buffer_event *event)
+{
+ unsigned length;
-enum {
- RB_LEN_TIME_EXTEND = 8,
- RB_LEN_TIME_STAMP = 16,
-};
+ if (event->len)
+ length = event->len * RB_ALIGNMENT;
+ else
+ length = event->array[0];
+ return length + RB_EVNT_HDR_SIZE;
+}
/* inline for ring buffer fast paths */
-static inline unsigned
+static unsigned
rb_event_length(struct ring_buffer_event *event)
{
- unsigned length;
-
switch (event->type) {
case RINGBUF_TYPE_PADDING:
- /* undefined */
- return -1;
+ if (rb_null_event(event))
+ /* undefined */
+ return -1;
+ return rb_event_data_length(event);
case RINGBUF_TYPE_TIME_EXTEND:
return RB_LEN_TIME_EXTEND;
@@ -150,11 +256,7 @@ rb_event_length(struct ring_buffer_event *event)
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;
+ return rb_event_data_length(event);
default:
BUG();
}
@@ -179,7 +281,7 @@ unsigned ring_buffer_event_length(struct ring_buffer_event *event)
EXPORT_SYMBOL_GPL(ring_buffer_event_length);
/* inline for ring buffer fast paths */
-static inline void *
+static void *
rb_event_data(struct ring_buffer_event *event)
{
BUG_ON(event->type != RINGBUF_TYPE_DATA);
@@ -209,7 +311,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_event_data);
struct buffer_data_page {
u64 time_stamp; /* page time stamp */
- local_t commit; /* write commited index */
+ local_t commit; /* write committed index */
unsigned char data[]; /* data of buffer page */
};
@@ -225,14 +327,25 @@ static void rb_init_page(struct buffer_data_page *bpage)
local_set(&bpage->commit, 0);
}
+/**
+ * ring_buffer_page_len - the size of data on the page.
+ * @page: The page to read
+ *
+ * Returns the amount of data on the page, including buffer page header.
+ */
+size_t ring_buffer_page_len(void *page)
+{
+ return local_read(&((struct buffer_data_page *)page)->commit)
+ + BUF_PAGE_HDR_SIZE;
+}
+
/*
* 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)
+static void free_buffer_page(struct buffer_page *bpage)
{
- if (bpage->page)
- free_page((unsigned long)bpage->page);
+ free_page((unsigned long)bpage->page);
kfree(bpage);
}
@@ -246,7 +359,7 @@ static inline int test_time_stamp(u64 delta)
return 0;
}
-#define BUF_PAGE_SIZE (PAGE_SIZE - offsetof(struct buffer_data_page, data))
+#define BUF_PAGE_SIZE (PAGE_SIZE - BUF_PAGE_HDR_SIZE)
/*
* head_page == tail_page && head == tail then buffer is empty.
@@ -260,7 +373,7 @@ struct ring_buffer_per_cpu {
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 *commit_page; /* committed pages */
struct buffer_page *reader_page;
unsigned long overrun;
unsigned long entries;
@@ -273,12 +386,17 @@ struct ring_buffer {
unsigned pages;
unsigned flags;
int cpus;
- cpumask_var_t cpumask;
atomic_t record_disabled;
+ cpumask_var_t cpumask;
struct mutex mutex;
struct ring_buffer_per_cpu **buffers;
+
+#ifdef CONFIG_HOTPLUG_CPU
+ struct notifier_block cpu_notify;
+#endif
+ u64 (*clock)(void);
};
struct ring_buffer_iter {
@@ -299,11 +417,35 @@ struct ring_buffer_iter {
_____ret; \
})
+/* Up this if you want to test the TIME_EXTENTS and normalization */
+#define DEBUG_SHIFT 0
+
+u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu)
+{
+ u64 time;
+
+ preempt_disable_notrace();
+ /* shift to debug/test normalization and TIME_EXTENTS */
+ time = buffer->clock() << DEBUG_SHIFT;
+ preempt_enable_no_resched_notrace();
+
+ return time;
+}
+EXPORT_SYMBOL_GPL(ring_buffer_time_stamp);
+
+void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer,
+ int cpu, u64 *ts)
+{
+ /* Just stupid testing the normalize function and deltas */
+ *ts >>= DEBUG_SHIFT;
+}
+EXPORT_SYMBOL_GPL(ring_buffer_normalize_time_stamp);
+
/**
* 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
+ * As a safety 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)
@@ -421,7 +563,6 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer)
struct list_head *head = &cpu_buffer->pages;
struct buffer_page *bpage, *tmp;
- list_del_init(&cpu_buffer->reader_page->list);
free_buffer_page(cpu_buffer->reader_page);
list_for_each_entry_safe(bpage, tmp, head, list) {
@@ -437,6 +578,11 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer)
*/
extern int ring_buffer_page_too_big(void);
+#ifdef CONFIG_HOTPLUG_CPU
+static int rb_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu);
+#endif
+
/**
* ring_buffer_alloc - allocate a new ring_buffer
* @size: the size in bytes per cpu that is needed.
@@ -469,12 +615,23 @@ struct ring_buffer *ring_buffer_alloc(unsigned long size, unsigned flags)
buffer->pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
buffer->flags = flags;
+ buffer->clock = trace_clock_local;
/* need at least two pages */
if (buffer->pages == 1)
buffer->pages++;
+ /*
+ * In case of non-hotplug cpu, if the ring-buffer is allocated
+ * in early initcall, it will not be notified of secondary cpus.
+ * In that off case, we need to allocate for all possible cpus.
+ */
+#ifdef CONFIG_HOTPLUG_CPU
+ get_online_cpus();
+ cpumask_copy(buffer->cpumask, cpu_online_mask);
+#else
cpumask_copy(buffer->cpumask, cpu_possible_mask);
+#endif
buffer->cpus = nr_cpu_ids;
bsize = sizeof(void *) * nr_cpu_ids;
@@ -490,6 +647,13 @@ struct ring_buffer *ring_buffer_alloc(unsigned long size, unsigned flags)
goto fail_free_buffers;
}
+#ifdef CONFIG_HOTPLUG_CPU
+ buffer->cpu_notify.notifier_call = rb_cpu_notify;
+ buffer->cpu_notify.priority = 0;
+ register_cpu_notifier(&buffer->cpu_notify);
+#endif
+
+ put_online_cpus();
mutex_init(&buffer->mutex);
return buffer;
@@ -503,6 +667,7 @@ struct ring_buffer *ring_buffer_alloc(unsigned long size, unsigned flags)
fail_free_cpumask:
free_cpumask_var(buffer->cpumask);
+ put_online_cpus();
fail_free_buffer:
kfree(buffer);
@@ -519,15 +684,29 @@ ring_buffer_free(struct ring_buffer *buffer)
{
int cpu;
+ get_online_cpus();
+
+#ifdef CONFIG_HOTPLUG_CPU
+ unregister_cpu_notifier(&buffer->cpu_notify);
+#endif
+
for_each_buffer_cpu(buffer, cpu)
rb_free_cpu_buffer(buffer->buffers[cpu]);
+ put_online_cpus();
+
free_cpumask_var(buffer->cpumask);
kfree(buffer);
}
EXPORT_SYMBOL_GPL(ring_buffer_free);
+void ring_buffer_set_clock(struct ring_buffer *buffer,
+ u64 (*clock)(void))
+{
+ buffer->clock = clock;
+}
+
static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer);
static void
@@ -627,16 +806,15 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size)
return size;
mutex_lock(&buffer->mutex);
+ get_online_cpus();
nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
if (size < buffer_size) {
/* easy case, just free pages */
- if (RB_WARN_ON(buffer, nr_pages >= buffer->pages)) {
- mutex_unlock(&buffer->mutex);
- return -1;
- }
+ if (RB_WARN_ON(buffer, nr_pages >= buffer->pages))
+ goto out_fail;
rm_pages = buffer->pages - nr_pages;
@@ -655,10 +833,8 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size)
* add these pages to the cpu_buffers. Otherwise we just free
* them all and return -ENOMEM;
*/
- if (RB_WARN_ON(buffer, nr_pages <= buffer->pages)) {
- mutex_unlock(&buffer->mutex);
- return -1;
- }
+ if (RB_WARN_ON(buffer, nr_pages <= buffer->pages))
+ goto out_fail;
new_pages = nr_pages - buffer->pages;
@@ -683,13 +859,12 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size)
rb_insert_pages(cpu_buffer, &pages, new_pages);
}
- if (RB_WARN_ON(buffer, !list_empty(&pages))) {
- mutex_unlock(&buffer->mutex);
- return -1;
- }
+ if (RB_WARN_ON(buffer, !list_empty(&pages)))
+ goto out_fail;
out:
buffer->pages = nr_pages;
+ put_online_cpus();
mutex_unlock(&buffer->mutex);
return size;
@@ -699,15 +874,20 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size)
list_del_init(&bpage->list);
free_buffer_page(bpage);
}
+ put_online_cpus();
mutex_unlock(&buffer->mutex);
return -ENOMEM;
-}
-EXPORT_SYMBOL_GPL(ring_buffer_resize);
-static inline int rb_null_event(struct ring_buffer_event *event)
-{
- return event->type == RINGBUF_TYPE_PADDING;
+ /*
+ * Something went totally wrong, and we are too paranoid
+ * to even clean up the mess.
+ */
+ out_fail:
+ put_online_cpus();
+ mutex_unlock(&buffer->mutex);
+ return -1;
}
+EXPORT_SYMBOL_GPL(ring_buffer_resize);
static inline void *
__rb_data_page_index(struct buffer_data_page *bpage, unsigned index)
@@ -811,7 +991,7 @@ rb_event_index(struct ring_buffer_event *event)
return (addr & ~PAGE_MASK) - (PAGE_SIZE - BUF_PAGE_SIZE);
}
-static inline int
+static int
rb_is_commit(struct ring_buffer_per_cpu *cpu_buffer,
struct ring_buffer_event *event)
{
@@ -825,7 +1005,7 @@ rb_is_commit(struct ring_buffer_per_cpu *cpu_buffer,
rb_commit_index(cpu_buffer) == index;
}
-static inline void
+static void
rb_set_commit_event(struct ring_buffer_per_cpu *cpu_buffer,
struct ring_buffer_event *event)
{
@@ -850,7 +1030,7 @@ rb_set_commit_event(struct ring_buffer_per_cpu *cpu_buffer,
local_set(&cpu_buffer->commit_page->page->commit, index);
}
-static inline void
+static void
rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)
{
/*
@@ -896,7 +1076,7 @@ static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
cpu_buffer->reader_page->read = 0;
}
-static inline void rb_inc_iter(struct ring_buffer_iter *iter)
+static void rb_inc_iter(struct ring_buffer_iter *iter)
{
struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
@@ -926,7 +1106,7 @@ static inline void rb_inc_iter(struct ring_buffer_iter *iter)
* and with this, we can determine what to place into the
* data field.
*/
-static inline void
+static void
rb_update_event(struct ring_buffer_event *event,
unsigned type, unsigned length)
{
@@ -938,15 +1118,11 @@ rb_update_event(struct ring_buffer_event *event,
break;
case RINGBUF_TYPE_TIME_EXTEND:
- event->len =
- (RB_LEN_TIME_EXTEND + (RB_ALIGNMENT-1))
- >> RB_ALIGNMENT_SHIFT;
+ event->len = DIV_ROUND_UP(RB_LEN_TIME_EXTEND, RB_ALIGNMENT);
break;
case RINGBUF_TYPE_TIME_STAMP:
- event->len =
- (RB_LEN_TIME_STAMP + (RB_ALIGNMENT-1))
- >> RB_ALIGNMENT_SHIFT;
+ event->len = DIV_ROUND_UP(RB_LEN_TIME_STAMP, RB_ALIGNMENT);
break;
case RINGBUF_TYPE_DATA:
@@ -955,16 +1131,14 @@ rb_update_event(struct ring_buffer_event *event,
event->len = 0;
event->array[0] = length;
} else
- event->len =
- (length + (RB_ALIGNMENT-1))
- >> RB_ALIGNMENT_SHIFT;
+ event->len = DIV_ROUND_UP(length, RB_ALIGNMENT);
break;
default:
BUG();
}
}
-static inline unsigned rb_calculate_event_length(unsigned length)
+static unsigned rb_calculate_event_length(unsigned length)
{
struct ring_buffer_event event; /* Used only for sizeof array */
@@ -990,6 +1164,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
struct ring_buffer *buffer = cpu_buffer->buffer;
struct ring_buffer_event *event;
unsigned long flags;
+ bool lock_taken = false;
commit_page = cpu_buffer->commit_page;
/* we just need to protect against interrupts */
@@ -1003,7 +1178,30 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
struct buffer_page *next_page = tail_page;
local_irq_save(flags);
- __raw_spin_lock(&cpu_buffer->lock);
+ /*
+ * Since the write to the buffer is still not
+ * fully lockless, we must be careful with NMIs.
+ * The locks in the writers are taken when a write
+ * crosses to a new page. The locks protect against
+ * races with the readers (this will soon be fixed
+ * with a lockless solution).
+ *
+ * Because we can not protect against NMIs, and we
+ * want to keep traces reentrant, we need to manage
+ * what happens when we are in an NMI.
+ *
+ * NMIs can happen after we take the lock.
+ * If we are in an NMI, only take the lock
+ * if it is not already taken. Otherwise
+ * simply fail.
+ */
+ if (unlikely(in_nmi())) {
+ if (!__raw_spin_trylock(&cpu_buffer->lock))
+ goto out_reset;
+ } else
+ __raw_spin_lock(&cpu_buffer->lock);
+
+ lock_taken = true;
rb_inc_page(cpu_buffer, &next_page);
@@ -1012,7 +1210,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
/* we grabbed the lock before incrementing */
if (RB_WARN_ON(cpu_buffer, next_page == reader_page))
- goto out_unlock;
+ goto out_reset;
/*
* If for some reason, we had an interrupt storm that made
@@ -1021,12 +1219,12 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
*/
if (unlikely(next_page == commit_page)) {
WARN_ON_ONCE(1);
- goto out_unlock;
+ goto out_reset;
}
if (next_page == head_page) {
if (!(buffer->flags & RB_FL_OVERWRITE))
- goto out_unlock;
+ goto out_reset;
/* tail_page has not moved yet? */
if (tail_page == cpu_buffer->tail_page) {
@@ -1050,7 +1248,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
cpu_buffer->tail_page = next_page;
/* reread the time stamp */
- *ts = ring_buffer_time_stamp(cpu_buffer->cpu);
+ *ts = ring_buffer_time_stamp(buffer, cpu_buffer->cpu);
cpu_buffer->tail_page->page->time_stamp = *ts;
}
@@ -1060,7 +1258,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
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;
+ rb_event_set_padding(event);
}
if (tail <= BUF_PAGE_SIZE)
@@ -1100,12 +1298,13 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
return event;
- out_unlock:
+ out_reset:
/* reset write */
if (tail <= BUF_PAGE_SIZE)
local_set(&tail_page->write, tail);
- __raw_spin_unlock(&cpu_buffer->lock);
+ if (likely(lock_taken))
+ __raw_spin_unlock(&cpu_buffer->lock);
local_irq_restore(flags);
return NULL;
}
@@ -1192,7 +1391,7 @@ rb_reserve_next_event(struct ring_buffer_per_cpu *cpu_buffer,
if (RB_WARN_ON(cpu_buffer, ++nr_loops > 1000))
return NULL;
- ts = ring_buffer_time_stamp(cpu_buffer->cpu);
+ ts = ring_buffer_time_stamp(cpu_buffer->buffer, cpu_buffer->cpu);
/*
* Only the first commit can update the timestamp.
@@ -1265,7 +1464,6 @@ 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
@@ -1278,9 +1476,7 @@ static DEFINE_PER_CPU(int, rb_need_resched);
* 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)
+ring_buffer_lock_reserve(struct ring_buffer *buffer, unsigned long length)
{
struct ring_buffer_per_cpu *cpu_buffer;
struct ring_buffer_event *event;
@@ -1347,15 +1543,13 @@ static void rb_commit(struct ring_buffer_per_cpu *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_event *event)
{
struct ring_buffer_per_cpu *cpu_buffer;
int cpu = raw_smp_processor_id();
@@ -1438,7 +1632,7 @@ int ring_buffer_write(struct ring_buffer *buffer,
}
EXPORT_SYMBOL_GPL(ring_buffer_write);
-static inline int rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer)
+static 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;
@@ -1528,12 +1722,15 @@ EXPORT_SYMBOL_GPL(ring_buffer_record_enable_cpu);
unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu)
{
struct ring_buffer_per_cpu *cpu_buffer;
+ unsigned long ret;
if (!cpumask_test_cpu(cpu, buffer->cpumask))
return 0;
cpu_buffer = buffer->buffers[cpu];
- return cpu_buffer->entries;
+ ret = cpu_buffer->entries;
+
+ return ret;
}
EXPORT_SYMBOL_GPL(ring_buffer_entries_cpu);
@@ -1545,12 +1742,15 @@ EXPORT_SYMBOL_GPL(ring_buffer_entries_cpu);
unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu)
{
struct ring_buffer_per_cpu *cpu_buffer;
+ unsigned long ret;
if (!cpumask_test_cpu(cpu, buffer->cpumask))
return 0;
cpu_buffer = buffer->buffers[cpu];
- return cpu_buffer->overrun;
+ ret = cpu_buffer->overrun;
+
+ return ret;
}
EXPORT_SYMBOL_GPL(ring_buffer_overrun_cpu);
@@ -1627,9 +1827,14 @@ static void rb_iter_reset(struct ring_buffer_iter *iter)
*/
void ring_buffer_iter_reset(struct ring_buffer_iter *iter)
{
- struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
+ struct ring_buffer_per_cpu *cpu_buffer;
unsigned long flags;
+ if (!iter)
+ return;
+
+ cpu_buffer = iter->cpu_buffer;
+
spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
rb_iter_reset(iter);
spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
@@ -1803,7 +2008,7 @@ static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer)
event = rb_reader_event(cpu_buffer);
- if (event->type == RINGBUF_TYPE_DATA)
+ if (event->type == RINGBUF_TYPE_DATA || rb_discarded_event(event))
cpu_buffer->entries--;
rb_update_read_stamp(cpu_buffer, event);
@@ -1864,9 +2069,6 @@ rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
struct buffer_page *reader;
int nr_loops = 0;
- if (!cpumask_test_cpu(cpu, buffer->cpumask))
- return NULL;
-
cpu_buffer = buffer->buffers[cpu];
again:
@@ -1889,9 +2091,18 @@ rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
switch (event->type) {
case RINGBUF_TYPE_PADDING:
- RB_WARN_ON(cpu_buffer, 1);
+ if (rb_null_event(event))
+ RB_WARN_ON(cpu_buffer, 1);
+ /*
+ * Because the writer could be discarding every
+ * event it creates (which would probably be bad)
+ * if we were to go back to "again" then we may never
+ * catch up, and will trigger the warn on, or lock
+ * the box. Return the padding, and we will release
+ * the current locks, and try again.
+ */
rb_advance_reader(cpu_buffer);
- return NULL;
+ return event;
case RINGBUF_TYPE_TIME_EXTEND:
/* Internal data, OK to advance */
@@ -1906,7 +2117,8 @@ rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
case RINGBUF_TYPE_DATA:
if (ts) {
*ts = cpu_buffer->read_stamp + event->time_delta;
- ring_buffer_normalize_time_stamp(cpu_buffer->cpu, ts);
+ ring_buffer_normalize_time_stamp(buffer,
+ cpu_buffer->cpu, ts);
}
return event;
@@ -1951,8 +2163,12 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
switch (event->type) {
case RINGBUF_TYPE_PADDING:
- rb_inc_iter(iter);
- goto again;
+ if (rb_null_event(event)) {
+ rb_inc_iter(iter);
+ goto again;
+ }
+ rb_advance_iter(iter);
+ return event;
case RINGBUF_TYPE_TIME_EXTEND:
/* Internal data, OK to advance */
@@ -1967,7 +2183,8 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
case RINGBUF_TYPE_DATA:
if (ts) {
*ts = iter->read_stamp + event->time_delta;
- ring_buffer_normalize_time_stamp(cpu_buffer->cpu, ts);
+ ring_buffer_normalize_time_stamp(buffer,
+ cpu_buffer->cpu, ts);
}
return event;
@@ -1995,10 +2212,19 @@ ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
struct ring_buffer_event *event;
unsigned long flags;
+ if (!cpumask_test_cpu(cpu, buffer->cpumask))
+ return NULL;
+
+ again:
spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
event = rb_buffer_peek(buffer, cpu, ts);
spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+ if (event && event->type == RINGBUF_TYPE_PADDING) {
+ cpu_relax();
+ goto again;
+ }
+
return event;
}
@@ -2017,10 +2243,16 @@ ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
struct ring_buffer_event *event;
unsigned long flags;
+ again:
spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
event = rb_iter_peek(iter, ts);
spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+ if (event && event->type == RINGBUF_TYPE_PADDING) {
+ cpu_relax();
+ goto again;
+ }
+
return event;
}
@@ -2035,24 +2267,37 @@ ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
struct ring_buffer_event *
ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts)
{
- struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
- struct ring_buffer_event *event;
+ struct ring_buffer_per_cpu *cpu_buffer;
+ struct ring_buffer_event *event = NULL;
unsigned long flags;
+ again:
+ /* might be called in atomic */
+ preempt_disable();
+
if (!cpumask_test_cpu(cpu, buffer->cpumask))
- return NULL;
+ goto out;
+ cpu_buffer = buffer->buffers[cpu];
spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
event = rb_buffer_peek(buffer, cpu, ts);
if (!event)
- goto out;
+ goto out_unlock;
rb_advance_reader(cpu_buffer);
- out:
+ out_unlock:
spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+ out:
+ preempt_enable();
+
+ if (event && event->type == RINGBUF_TYPE_PADDING) {
+ cpu_relax();
+ goto again;
+ }
+
return event;
}
EXPORT_SYMBOL_GPL(ring_buffer_consume);
@@ -2131,6 +2376,7 @@ ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts)
struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
unsigned long flags;
+ again:
spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
event = rb_iter_peek(iter, ts);
if (!event)
@@ -2140,6 +2386,11 @@ ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts)
out:
spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+ if (event && event->type == RINGBUF_TYPE_PADDING) {
+ cpu_relax();
+ goto again;
+ }
+
return event;
}
EXPORT_SYMBOL_GPL(ring_buffer_read);
@@ -2232,6 +2483,7 @@ int ring_buffer_empty(struct ring_buffer *buffer)
if (!rb_per_cpu_empty(cpu_buffer))
return 0;
}
+
return 1;
}
EXPORT_SYMBOL_GPL(ring_buffer_empty);
@@ -2244,12 +2496,16 @@ EXPORT_SYMBOL_GPL(ring_buffer_empty);
int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu)
{
struct ring_buffer_per_cpu *cpu_buffer;
+ int ret;
if (!cpumask_test_cpu(cpu, buffer->cpumask))
return 1;
cpu_buffer = buffer->buffers[cpu];
- return rb_per_cpu_empty(cpu_buffer);
+ ret = rb_per_cpu_empty(cpu_buffer);
+
+
+ return ret;
}
EXPORT_SYMBOL_GPL(ring_buffer_empty_cpu);
@@ -2268,18 +2524,36 @@ int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
{
struct ring_buffer_per_cpu *cpu_buffer_a;
struct ring_buffer_per_cpu *cpu_buffer_b;
+ int ret = -EINVAL;
if (!cpumask_test_cpu(cpu, buffer_a->cpumask) ||
!cpumask_test_cpu(cpu, buffer_b->cpumask))
- return -EINVAL;
+ goto out;
/* At least make sure the two buffers are somewhat the same */
if (buffer_a->pages != buffer_b->pages)
- return -EINVAL;
+ goto out;
+
+ ret = -EAGAIN;
+
+ if (ring_buffer_flags != RB_BUFFERS_ON)
+ goto out;
+
+ if (atomic_read(&buffer_a->record_disabled))
+ goto out;
+
+ if (atomic_read(&buffer_b->record_disabled))
+ goto out;
cpu_buffer_a = buffer_a->buffers[cpu];
cpu_buffer_b = buffer_b->buffers[cpu];
+ if (atomic_read(&cpu_buffer_a->record_disabled))
+ goto out;
+
+ if (atomic_read(&cpu_buffer_b->record_disabled))
+ goto out;
+
/*
* We can't do a synchronize_sched here because this
* function can be called in atomic context.
@@ -2298,18 +2572,21 @@ int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
atomic_dec(&cpu_buffer_a->record_disabled);
atomic_dec(&cpu_buffer_b->record_disabled);
- return 0;
+ ret = 0;
+out:
+ return ret;
}
EXPORT_SYMBOL_GPL(ring_buffer_swap_cpu);
static void rb_remove_entries(struct ring_buffer_per_cpu *cpu_buffer,
- struct buffer_data_page *bpage)
+ struct buffer_data_page *bpage,
+ unsigned int offset)
{
struct ring_buffer_event *event;
unsigned long head;
__raw_spin_lock(&cpu_buffer->lock);
- for (head = 0; head < local_read(&bpage->commit);
+ for (head = offset; head < local_read(&bpage->commit);
head += rb_event_length(event)) {
event = __rb_data_page_index(bpage, head);
@@ -2340,8 +2617,8 @@ static void rb_remove_entries(struct ring_buffer_per_cpu *cpu_buffer,
*/
void *ring_buffer_alloc_read_page(struct ring_buffer *buffer)
{
- unsigned long addr;
struct buffer_data_page *bpage;
+ unsigned long addr;
addr = __get_free_page(GFP_KERNEL);
if (!addr)
@@ -2349,6 +2626,8 @@ void *ring_buffer_alloc_read_page(struct ring_buffer *buffer)
bpage = (void *)addr;
+ rb_init_page(bpage);
+
return bpage;
}
@@ -2368,6 +2647,7 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, void *data)
* ring_buffer_read_page - extract a page from the ring buffer
* @buffer: buffer to extract from
* @data_page: the page to use allocated from ring_buffer_alloc_read_page
+ * @len: amount to extract
* @cpu: the cpu of the buffer to extract
* @full: should the extraction only happen when the page is full.
*
@@ -2377,12 +2657,12 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, void *data)
* to swap with a page in the ring buffer.
*
* for example:
- * rpage = ring_buffer_alloc_page(buffer);
+ * rpage = ring_buffer_alloc_read_page(buffer);
* if (!rpage)
* return error;
- * ret = ring_buffer_read_page(buffer, &rpage, cpu, 0);
- * if (ret)
- * process_page(rpage);
+ * ret = ring_buffer_read_page(buffer, &rpage, len, cpu, 0);
+ * if (ret >= 0)
+ * process_page(rpage, ret);
*
* When @full is set, the function will not return true unless
* the writer is off the reader page.
@@ -2393,72 +2673,118 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, void *data)
* responsible for that.
*
* Returns:
- * 1 if data has been transferred
- * 0 if no data has been transferred.
+ * >=0 if data has been transferred, returns the offset of consumed data.
+ * <0 if no data has been transferred.
*/
int ring_buffer_read_page(struct ring_buffer *buffer,
- void **data_page, int cpu, int full)
+ void **data_page, size_t len, int cpu, int full)
{
struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
struct ring_buffer_event *event;
struct buffer_data_page *bpage;
+ struct buffer_page *reader;
unsigned long flags;
- int ret = 0;
+ unsigned int commit;
+ unsigned int read;
+ u64 save_timestamp;
+ int ret = -1;
+
+ if (!cpumask_test_cpu(cpu, buffer->cpumask))
+ goto out;
+
+ /*
+ * If len is not big enough to hold the page header, then
+ * we can not copy anything.
+ */
+ if (len <= BUF_PAGE_HDR_SIZE)
+ goto out;
+
+ len -= BUF_PAGE_HDR_SIZE;
if (!data_page)
- return 0;
+ goto out;
bpage = *data_page;
if (!bpage)
- return 0;
+ goto out;
spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
- /*
- * rb_buffer_peek will get the next ring buffer if
- * the current reader page is empty.
- */
- event = rb_buffer_peek(buffer, cpu, NULL);
- if (!event)
- goto out;
+ reader = rb_get_reader_page(cpu_buffer);
+ if (!reader)
+ goto out_unlock;
+
+ event = rb_reader_event(cpu_buffer);
+
+ read = reader->read;
+ commit = rb_page_commit(reader);
- /* check for data */
- if (!local_read(&cpu_buffer->reader_page->page->commit))
- goto out;
/*
- * If the writer is already off of the read page, then simply
- * switch the read page with the given page. Otherwise
- * we need to copy the data from the reader to the writer.
+ * If this page has been partially read or
+ * if len is not big enough to read the rest of the page or
+ * a writer is still on the page, then
+ * we must copy the data from the page to the buffer.
+ * Otherwise, we can simply swap the page with the one passed in.
*/
- if (cpu_buffer->reader_page == cpu_buffer->commit_page) {
- unsigned int read = cpu_buffer->reader_page->read;
+ if (read || (len < (commit - read)) ||
+ cpu_buffer->reader_page == cpu_buffer->commit_page) {
+ struct buffer_data_page *rpage = cpu_buffer->reader_page->page;
+ unsigned int rpos = read;
+ unsigned int pos = 0;
+ unsigned int size;
if (full)
- goto out;
- /* The writer is still on the reader page, we must copy */
- bpage = cpu_buffer->reader_page->page;
- memcpy(bpage->data,
- cpu_buffer->reader_page->page->data + read,
- local_read(&bpage->commit) - read);
+ goto out_unlock;
+
+ if (len > (commit - read))
+ len = (commit - read);
+
+ size = rb_event_length(event);
+
+ if (len < size)
+ goto out_unlock;
- /* consume what was read */
- cpu_buffer->reader_page += read;
+ /* save the current timestamp, since the user will need it */
+ save_timestamp = cpu_buffer->read_stamp;
+ /* Need to copy one event at a time */
+ do {
+ memcpy(bpage->data + pos, rpage->data + rpos, size);
+
+ len -= size;
+
+ rb_advance_reader(cpu_buffer);
+ rpos = reader->read;
+ pos += size;
+
+ event = rb_reader_event(cpu_buffer);
+ size = rb_event_length(event);
+ } while (len > size);
+
+ /* update bpage */
+ local_set(&bpage->commit, pos);
+ bpage->time_stamp = save_timestamp;
+
+ /* we copied everything to the beginning */
+ read = 0;
} else {
/* swap the pages */
rb_init_page(bpage);
- bpage = cpu_buffer->reader_page->page;
- cpu_buffer->reader_page->page = *data_page;
- cpu_buffer->reader_page->read = 0;
+ bpage = reader->page;
+ reader->page = *data_page;
+ local_set(&reader->write, 0);
+ reader->read = 0;
*data_page = bpage;
+
+ /* update the entry counter */
+ rb_remove_entries(cpu_buffer, bpage, read);
}
- ret = 1;
+ ret = read;
- /* update the entry counter */
- rb_remove_entries(cpu_buffer, bpage);
- out:
+ out_unlock:
spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+ out:
return ret;
}
@@ -2466,7 +2792,7 @@ static ssize_t
rb_simple_read(struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos)
{
- long *p = filp->private_data;
+ unsigned long *p = filp->private_data;
char buf[64];
int r;
@@ -2482,9 +2808,9 @@ static ssize_t
rb_simple_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos)
{
- long *p = filp->private_data;
+ unsigned long *p = filp->private_data;
char buf[64];
- long val;
+ unsigned long val;
int ret;
if (cnt >= sizeof(buf))
@@ -2509,7 +2835,7 @@ rb_simple_write(struct file *filp, const char __user *ubuf,
return cnt;
}
-static struct file_operations rb_simple_fops = {
+static const struct file_operations rb_simple_fops = {
.open = tracing_open_generic,
.read = rb_simple_read,
.write = rb_simple_write,
@@ -2532,3 +2858,42 @@ static __init int rb_init_debugfs(void)
}
fs_initcall(rb_init_debugfs);
+
+#ifdef CONFIG_HOTPLUG_CPU
+static int rb_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ struct ring_buffer *buffer =
+ container_of(self, struct ring_buffer, cpu_notify);
+ long cpu = (long)hcpu;
+
+ switch (action) {
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ if (cpu_isset(cpu, *buffer->cpumask))
+ return NOTIFY_OK;
+
+ buffer->buffers[cpu] =
+ rb_allocate_cpu_buffer(buffer, cpu);
+ if (!buffer->buffers[cpu]) {
+ WARN(1, "failed to allocate ring buffer on CPU %ld\n",
+ cpu);
+ return NOTIFY_OK;
+ }
+ smp_wmb();
+ cpu_set(cpu, *buffer->cpumask);
+ break;
+ case CPU_DOWN_PREPARE:
+ case CPU_DOWN_PREPARE_FROZEN:
+ /*
+ * Do nothing.
+ * If we were to free the buffer, then the user would
+ * lose any trace that was in the buffer.
+ */
+ break;
+ default:
+ break;
+ }
+ return NOTIFY_OK;
+}
+#endif
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 17bb88d86ac..1ce5dc6372b 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -11,32 +11,34 @@
* Copyright (C) 2004-2006 Ingo Molnar
* Copyright (C) 2004 William Lee Irwin III
*/
+#include <linux/ring_buffer.h>
#include <linux/utsrelease.h>
+#include <linux/stacktrace.h>
+#include <linux/writeback.h>
#include <linux/kallsyms.h>
#include <linux/seq_file.h>
#include <linux/notifier.h>
+#include <linux/irqflags.h>
#include <linux/debugfs.h>
#include <linux/pagemap.h>
#include <linux/hardirq.h>
#include <linux/linkage.h>
#include <linux/uaccess.h>
+#include <linux/kprobes.h>
#include <linux/ftrace.h>
#include <linux/module.h>
#include <linux/percpu.h>
+#include <linux/splice.h>
#include <linux/kdebug.h>
+#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/gfp.h>
#include <linux/fs.h>
-#include <linux/kprobes.h>
-#include <linux/writeback.h>
-
-#include <linux/stacktrace.h>
-#include <linux/ring_buffer.h>
-#include <linux/irqflags.h>
#include "trace.h"
+#include "trace_output.h"
#define TRACE_BUFFER_FLAGS (RB_FL_OVERWRITE)
@@ -44,14 +46,25 @@ unsigned long __read_mostly tracing_max_latency;
unsigned long __read_mostly tracing_thresh;
/*
+ * On boot up, the ring buffer is set to the minimum size, so that
+ * we do not waste memory on systems that are not using tracing.
+ */
+static int ring_buffer_expanded;
+
+/*
* We need to change this state when a selftest is running.
* A selftest will lurk into the ring-buffer to count the
* entries inserted during the selftest although some concurrent
- * insertions into the ring-buffer such as ftrace_printk could occurred
+ * insertions into the ring-buffer such as trace_printk could occurred
* at the same time, giving false positive or negative results.
*/
static bool __read_mostly tracing_selftest_running;
+/*
+ * If a tracer is running, we do not want to run SELFTEST.
+ */
+static bool __read_mostly tracing_selftest_disabled;
+
/* For tracers that don't implement custom flags */
static struct tracer_opt dummy_tracer_opt[] = {
{ }
@@ -73,7 +86,7 @@ static int dummy_set_flag(u32 old_flags, u32 bit, int set)
* of the tracer is successful. But that is the only place that sets
* this back to zero.
*/
-int tracing_disabled = 1;
+static int tracing_disabled = 1;
static DEFINE_PER_CPU(local_t, ftrace_cpu_disabled);
@@ -91,6 +104,9 @@ static inline void ftrace_enable_cpu(void)
static cpumask_var_t __read_mostly tracing_buffer_mask;
+/* Define which cpu buffers are currently read in trace_pipe */
+static cpumask_var_t tracing_reader_cpumask;
+
#define for_each_tracing_cpu(cpu) \
for_each_cpu(cpu, tracing_buffer_mask)
@@ -109,14 +125,21 @@ static cpumask_var_t __read_mostly tracing_buffer_mask;
*/
int ftrace_dump_on_oops;
-static int tracing_set_tracer(char *buf);
+static int tracing_set_tracer(const char *buf);
+
+#define BOOTUP_TRACER_SIZE 100
+static char bootup_tracer_buf[BOOTUP_TRACER_SIZE] __initdata;
+static char *default_bootup_tracer;
static int __init set_ftrace(char *str)
{
- tracing_set_tracer(str);
+ strncpy(bootup_tracer_buf, str, BOOTUP_TRACER_SIZE);
+ default_bootup_tracer = bootup_tracer_buf;
+ /* We are using ftrace early, expand it */
+ ring_buffer_expanded = 1;
return 1;
}
-__setup("ftrace", set_ftrace);
+__setup("ftrace=", set_ftrace);
static int __init set_ftrace_dump_on_oops(char *str)
{
@@ -125,21 +148,13 @@ static int __init set_ftrace_dump_on_oops(char *str)
}
__setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops);
-long
-ns2usecs(cycle_t nsec)
+unsigned long long ns2usecs(cycle_t nsec)
{
nsec += 500;
do_div(nsec, 1000);
return nsec;
}
-cycle_t ftrace_now(int cpu)
-{
- u64 ts = ring_buffer_time_stamp(cpu);
- ring_buffer_normalize_time_stamp(cpu, &ts);
- return ts;
-}
-
/*
* The global_trace is the descriptor that holds the tracing
* buffers for the live tracing. For each CPU, it contains
@@ -156,6 +171,20 @@ static struct trace_array global_trace;
static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu);
+cycle_t ftrace_now(int cpu)
+{
+ u64 ts;
+
+ /* Early boot up does not have a buffer yet */
+ if (!global_trace.buffer)
+ return trace_clock_local();
+
+ ts = ring_buffer_time_stamp(global_trace.buffer, cpu);
+ ring_buffer_normalize_time_stamp(global_trace.buffer, cpu, &ts);
+
+ return ts;
+}
+
/*
* The max_tr is used to snapshot the global_trace when a maximum
* latency is reached. Some tracers will use this to store a maximum
@@ -186,9 +215,6 @@ int tracing_is_enabled(void)
return tracer_enabled;
}
-/* function tracing enabled */
-int ftrace_function_enabled;
-
/*
* trace_buf_size is the size in bytes that is allocated
* for a buffer. Note, the number of bytes is always rounded
@@ -229,7 +255,7 @@ static DECLARE_WAIT_QUEUE_HEAD(trace_wait);
/* trace_flags holds trace_options default values */
unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |
- TRACE_ITER_ANNOTATE;
+ TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME;
/**
* trace_wake_up - wake up tasks waiting for trace input
@@ -280,13 +306,17 @@ static const char *trace_options[] = {
"block",
"stacktrace",
"sched-tree",
- "ftrace_printk",
+ "trace_printk",
"ftrace_preempt",
"branch",
"annotate",
"userstacktrace",
"sym-userobj",
"printk-msg-only",
+ "context-info",
+ "latency-format",
+ "global-clock",
+ "sleep-time",
NULL
};
@@ -326,146 +356,37 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
data->rt_priority = tsk->rt_priority;
/* record this tasks comm */
- tracing_record_cmdline(current);
+ tracing_record_cmdline(tsk);
}
-/**
- * trace_seq_printf - sequence printing of trace information
- * @s: trace sequence descriptor
- * @fmt: printf format string
- *
- * The tracer may use either sequence operations or its own
- * copy to user routines. To simplify formating of a trace
- * trace_seq_printf is used to store strings into a special
- * buffer (@s). Then the output may be either used by
- * the sequencer or pulled into another buffer.
- */
-int
-trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
+ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt)
{
- int len = (PAGE_SIZE - 1) - s->len;
- va_list ap;
+ int len;
int ret;
- if (!len)
- return 0;
-
- va_start(ap, fmt);
- ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
- va_end(ap);
-
- /* If we can't write it all, don't bother writing anything */
- if (ret >= len)
- return 0;
-
- s->len += ret;
-
- return len;
-}
-
-/**
- * trace_seq_puts - trace sequence printing of simple string
- * @s: trace sequence descriptor
- * @str: simple string to record
- *
- * The tracer may use either the sequence operations or its own
- * copy to user routines. This function records a simple string
- * into a special buffer (@s) for later retrieval by a sequencer
- * or other mechanism.
- */
-static int
-trace_seq_puts(struct trace_seq *s, const char *str)
-{
- int len = strlen(str);
-
- if (len > ((PAGE_SIZE - 1) - s->len))
- return 0;
-
- memcpy(s->buffer + s->len, str, len);
- s->len += len;
-
- return len;
-}
-
-static int
-trace_seq_putc(struct trace_seq *s, unsigned char c)
-{
- if (s->len >= (PAGE_SIZE - 1))
- return 0;
-
- s->buffer[s->len++] = c;
-
- return 1;
-}
-
-static int
-trace_seq_putmem(struct trace_seq *s, void *mem, size_t len)
-{
- if (len > ((PAGE_SIZE - 1) - s->len))
+ if (!cnt)
return 0;
- memcpy(s->buffer + s->len, mem, len);
- s->len += len;
-
- return len;
-}
-
-#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;
- int i, j;
-
-#ifdef __BIG_ENDIAN
- for (i = 0, j = 0; i < len; i++) {
-#else
- for (i = len-1, j = 0; i >= 0; i--) {
-#endif
- hex[j++] = hex_asc_hi(data[i]);
- hex[j++] = hex_asc_lo(data[i]);
- }
- hex[j++] = ' ';
-
- return trace_seq_putmem(s, hex, j);
-}
-
-static int
-trace_seq_path(struct trace_seq *s, struct path *path)
-{
- unsigned char *p;
+ if (s->len <= s->readpos)
+ return -EBUSY;
- if (s->len >= (PAGE_SIZE - 1))
- return 0;
- p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
- if (!IS_ERR(p)) {
- p = mangle_path(s->buffer + s->len, p, "\n");
- if (p) {
- s->len = p - s->buffer;
- return 1;
- }
- } else {
- s->buffer[s->len++] = '?';
- return 1;
- }
+ len = s->len - s->readpos;
+ if (cnt > len)
+ cnt = len;
+ ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt);
+ if (ret == cnt)
+ return -EFAULT;
- return 0;
-}
+ cnt -= ret;
-static void
-trace_seq_reset(struct trace_seq *s)
-{
- s->len = 0;
- s->readpos = 0;
+ s->readpos += cnt;
+ return cnt;
}
-ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt)
+static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt)
{
int len;
- int ret;
+ void *ret;
if (s->len <= s->readpos)
return -EBUSY;
@@ -473,11 +394,11 @@ ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt)
len = s->len - s->readpos;
if (cnt > len)
cnt = len;
- ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt);
- if (ret)
+ ret = memcpy(buf, s->buffer + s->readpos, cnt);
+ if (!ret)
return -EFAULT;
- s->readpos += len;
+ s->readpos += cnt;
return cnt;
}
@@ -489,7 +410,7 @@ trace_print_seq(struct seq_file *m, struct trace_seq *s)
s->buffer[len] = 0;
seq_puts(m, s->buffer);
- trace_seq_reset(s);
+ trace_seq_init(s);
}
/**
@@ -543,7 +464,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
ftrace_enable_cpu();
- WARN_ON_ONCE(ret);
+ WARN_ON_ONCE(ret && ret != -EAGAIN);
__update_max_tr(tr, tsk, cpu);
__raw_spin_unlock(&ftrace_max_lock);
@@ -556,6 +477,8 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
* Register a new plugin tracer.
*/
int register_tracer(struct tracer *type)
+__releases(kernel_lock)
+__acquires(kernel_lock)
{
struct tracer *t;
int len;
@@ -594,9 +517,12 @@ int register_tracer(struct tracer *type)
else
if (!type->flags->opts)
type->flags->opts = dummy_tracer_opt;
+ if (!type->wait_pipe)
+ type->wait_pipe = default_wait_pipe;
+
#ifdef CONFIG_FTRACE_STARTUP_TEST
- if (type->selftest) {
+ if (type->selftest && !tracing_selftest_disabled) {
struct tracer *saved_tracer = current_trace;
struct trace_array *tr = &global_trace;
int i;
@@ -638,8 +564,26 @@ int register_tracer(struct tracer *type)
out:
tracing_selftest_running = false;
mutex_unlock(&trace_types_lock);
- lock_kernel();
+ if (ret || !default_bootup_tracer)
+ goto out_unlock;
+
+ if (strncmp(default_bootup_tracer, type->name, BOOTUP_TRACER_SIZE))
+ goto out_unlock;
+
+ printk(KERN_INFO "Starting tracer '%s'\n", type->name);
+ /* Do we want this tracer to start on bootup? */
+ tracing_set_tracer(type->name);
+ default_bootup_tracer = NULL;
+ /* disable other selftests, since this will break it. */
+ tracing_selftest_disabled = 1;
+#ifdef CONFIG_FTRACE_STARTUP_TEST
+ printk(KERN_INFO "Disabling FTRACE selftests due to running tracer '%s'\n",
+ type->name);
+#endif
+
+ out_unlock:
+ lock_kernel();
return ret;
}
@@ -658,6 +602,15 @@ void unregister_tracer(struct tracer *type)
found:
*t = (*t)->next;
+
+ if (type == current_trace && tracer_enabled) {
+ tracer_enabled = 0;
+ tracing_stop();
+ if (current_trace->stop)
+ current_trace->stop(&global_trace);
+ current_trace = &nop_trace;
+ }
+
if (strlen(type->name) != max_tracer_type_len)
goto out;
@@ -689,19 +642,20 @@ void tracing_reset_online_cpus(struct trace_array *tr)
}
#define SAVED_CMDLINES 128
+#define NO_CMDLINE_MAP UINT_MAX
static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
static unsigned map_cmdline_to_pid[SAVED_CMDLINES];
static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN];
static int cmdline_idx;
-static DEFINE_SPINLOCK(trace_cmdline_lock);
+static raw_spinlock_t trace_cmdline_lock = __RAW_SPIN_LOCK_UNLOCKED;
/* temporary disable recording */
-atomic_t trace_record_cmdline_disabled __read_mostly;
+static atomic_t trace_record_cmdline_disabled __read_mostly;
static void trace_init_cmdlines(void)
{
- memset(&map_pid_to_cmdline, -1, sizeof(map_pid_to_cmdline));
- memset(&map_cmdline_to_pid, -1, sizeof(map_cmdline_to_pid));
+ memset(&map_pid_to_cmdline, NO_CMDLINE_MAP, sizeof(map_pid_to_cmdline));
+ memset(&map_cmdline_to_pid, NO_CMDLINE_MAP, sizeof(map_cmdline_to_pid));
cmdline_idx = 0;
}
@@ -738,13 +692,12 @@ void tracing_start(void)
return;
spin_lock_irqsave(&tracing_start_lock, flags);
- if (--trace_stop_count)
- goto out;
-
- if (trace_stop_count < 0) {
- /* Someone screwed up their debugging */
- WARN_ON_ONCE(1);
- trace_stop_count = 0;
+ if (--trace_stop_count) {
+ if (trace_stop_count < 0) {
+ /* Someone screwed up their debugging */
+ WARN_ON_ONCE(1);
+ trace_stop_count = 0;
+ }
goto out;
}
@@ -794,8 +747,7 @@ void trace_stop_cmdline_recording(void);
static void trace_save_cmdline(struct task_struct *tsk)
{
- unsigned map;
- unsigned idx;
+ unsigned pid, idx;
if (!tsk->pid || unlikely(tsk->pid > PID_MAX_DEFAULT))
return;
@@ -806,17 +758,24 @@ static void trace_save_cmdline(struct task_struct *tsk)
* nor do we want to disable interrupts,
* so if we miss here, then better luck next time.
*/
- if (!spin_trylock(&trace_cmdline_lock))
+ if (!__raw_spin_trylock(&trace_cmdline_lock))
return;
idx = map_pid_to_cmdline[tsk->pid];
- if (idx >= SAVED_CMDLINES) {
+ if (idx == NO_CMDLINE_MAP) {
idx = (cmdline_idx + 1) % SAVED_CMDLINES;
- map = map_cmdline_to_pid[idx];
- if (map <= PID_MAX_DEFAULT)
- map_pid_to_cmdline[map] = (unsigned)-1;
+ /*
+ * Check whether the cmdline buffer at idx has a pid
+ * mapped. We are going to overwrite that entry so we
+ * need to clear the map_pid_to_cmdline. Otherwise we
+ * would read the new comm for the old pid.
+ */
+ pid = map_cmdline_to_pid[idx];
+ if (pid != NO_CMDLINE_MAP)
+ map_pid_to_cmdline[pid] = NO_CMDLINE_MAP;
+ map_cmdline_to_pid[idx] = tsk->pid;
map_pid_to_cmdline[tsk->pid] = idx;
cmdline_idx = idx;
@@ -824,33 +783,37 @@ static void trace_save_cmdline(struct task_struct *tsk)
memcpy(&saved_cmdlines[idx], tsk->comm, TASK_COMM_LEN);
- spin_unlock(&trace_cmdline_lock);
+ __raw_spin_unlock(&trace_cmdline_lock);
}
-char *trace_find_cmdline(int pid)
+void trace_find_cmdline(int pid, char comm[])
{
- char *cmdline = "<...>";
unsigned map;
- if (!pid)
- return "<idle>";
+ if (!pid) {
+ strcpy(comm, "<idle>");
+ return;
+ }
- if (pid > PID_MAX_DEFAULT)
- goto out;
+ if (pid > PID_MAX_DEFAULT) {
+ strcpy(comm, "<...>");
+ return;
+ }
+ __raw_spin_lock(&trace_cmdline_lock);
map = map_pid_to_cmdline[pid];
- if (map >= SAVED_CMDLINES)
- goto out;
-
- cmdline = saved_cmdlines[map];
+ if (map != NO_CMDLINE_MAP)
+ strcpy(comm, saved_cmdlines[map]);
+ else
+ strcpy(comm, "<...>");
- out:
- return cmdline;
+ __raw_spin_unlock(&trace_cmdline_lock);
}
void tracing_record_cmdline(struct task_struct *tsk)
{
- if (atomic_read(&trace_record_cmdline_disabled))
+ if (atomic_read(&trace_record_cmdline_disabled) || !tracer_enabled ||
+ !tracing_is_on())
return;
trace_save_cmdline(tsk);
@@ -864,7 +827,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
entry->preempt_count = pc & 0xff;
entry->pid = (tsk) ? tsk->pid : 0;
- entry->tgid = (tsk) ? tsk->tgid : 0;
+ entry->tgid = (tsk) ? tsk->tgid : 0;
entry->flags =
#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
(irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) |
@@ -876,78 +839,132 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
(need_resched() ? TRACE_FLAG_NEED_RESCHED : 0);
}
+struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr,
+ unsigned char type,
+ unsigned long len,
+ unsigned long flags, int pc)
+{
+ struct ring_buffer_event *event;
+
+ event = ring_buffer_lock_reserve(tr->buffer, len);
+ if (event != NULL) {
+ struct trace_entry *ent = ring_buffer_event_data(event);
+
+ tracing_generic_entry_update(ent, flags, pc);
+ ent->type = type;
+ }
+
+ return event;
+}
+static void ftrace_trace_stack(struct trace_array *tr,
+ unsigned long flags, int skip, int pc);
+static void ftrace_trace_userstack(struct trace_array *tr,
+ unsigned long flags, int pc);
+
+static inline void __trace_buffer_unlock_commit(struct trace_array *tr,
+ struct ring_buffer_event *event,
+ unsigned long flags, int pc,
+ int wake)
+{
+ ring_buffer_unlock_commit(tr->buffer, event);
+
+ ftrace_trace_stack(tr, flags, 6, pc);
+ ftrace_trace_userstack(tr, flags, pc);
+
+ if (wake)
+ trace_wake_up();
+}
+
+void trace_buffer_unlock_commit(struct trace_array *tr,
+ struct ring_buffer_event *event,
+ unsigned long flags, int pc)
+{
+ __trace_buffer_unlock_commit(tr, event, flags, pc, 1);
+}
+
+struct ring_buffer_event *
+trace_current_buffer_lock_reserve(unsigned char type, unsigned long len,
+ unsigned long flags, int pc)
+{
+ return trace_buffer_lock_reserve(&global_trace,
+ type, len, flags, pc);
+}
+
+void trace_current_buffer_unlock_commit(struct ring_buffer_event *event,
+ unsigned long flags, int pc)
+{
+ return __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 1);
+}
+
+void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event,
+ unsigned long flags, int pc)
+{
+ return __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 0);
+}
+
void
-trace_function(struct trace_array *tr, struct trace_array_cpu *data,
+trace_function(struct trace_array *tr,
unsigned long ip, unsigned long parent_ip, unsigned long flags,
int pc)
{
struct ring_buffer_event *event;
struct ftrace_entry *entry;
- unsigned long 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);
+ event = trace_buffer_lock_reserve(tr, TRACE_FN, sizeof(*entry),
+ flags, pc);
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);
+ ring_buffer_unlock_commit(tr->buffer, event);
}
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
-static void __trace_graph_entry(struct trace_array *tr,
- struct trace_array_cpu *data,
+static int __trace_graph_entry(struct trace_array *tr,
struct ftrace_graph_ent *trace,
unsigned long flags,
int pc)
{
struct ring_buffer_event *event;
struct ftrace_graph_ent_entry *entry;
- unsigned long irq_flags;
if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
- return;
+ return 0;
- event = ring_buffer_lock_reserve(global_trace.buffer, sizeof(*entry),
- &irq_flags);
+ event = trace_buffer_lock_reserve(&global_trace, TRACE_GRAPH_ENT,
+ sizeof(*entry), flags, pc);
if (!event)
- return;
+ return 0;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, flags, pc);
- entry->ent.type = TRACE_GRAPH_ENT;
entry->graph_ent = *trace;
- ring_buffer_unlock_commit(global_trace.buffer, event, irq_flags);
+ ring_buffer_unlock_commit(global_trace.buffer, event);
+
+ return 1;
}
static void __trace_graph_return(struct trace_array *tr,
- struct trace_array_cpu *data,
struct ftrace_graph_ret *trace,
unsigned long flags,
int pc)
{
struct ring_buffer_event *event;
struct ftrace_graph_ret_entry *entry;
- unsigned long irq_flags;
if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
return;
- event = ring_buffer_lock_reserve(global_trace.buffer, sizeof(*entry),
- &irq_flags);
+ event = trace_buffer_lock_reserve(&global_trace, TRACE_GRAPH_RET,
+ sizeof(*entry), flags, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, flags, pc);
- entry->ent.type = TRACE_GRAPH_RET;
entry->ret = *trace;
- ring_buffer_unlock_commit(global_trace.buffer, event, irq_flags);
+ ring_buffer_unlock_commit(global_trace.buffer, event);
}
#endif
@@ -957,31 +974,23 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data,
int pc)
{
if (likely(!atomic_read(&data->disabled)))
- trace_function(tr, data, ip, parent_ip, flags, pc);
+ trace_function(tr, ip, parent_ip, flags, pc);
}
-static void ftrace_trace_stack(struct trace_array *tr,
- struct trace_array_cpu *data,
- unsigned long flags,
- int skip, int pc)
+static void __ftrace_trace_stack(struct trace_array *tr,
+ unsigned long flags,
+ int skip, int pc)
{
#ifdef CONFIG_STACKTRACE
struct ring_buffer_event *event;
struct stack_entry *entry;
struct stack_trace trace;
- unsigned long irq_flags;
- if (!(trace_flags & TRACE_ITER_STACKTRACE))
- return;
-
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
- &irq_flags);
+ event = trace_buffer_lock_reserve(tr, TRACE_STACK,
+ sizeof(*entry), flags, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, flags, pc);
- entry->ent.type = TRACE_STACK;
-
memset(&entry->caller, 0, sizeof(entry->caller));
trace.nr_entries = 0;
@@ -990,38 +999,43 @@ static void ftrace_trace_stack(struct trace_array *tr,
trace.entries = entry->caller;
save_stack_trace(&trace);
- ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+ ring_buffer_unlock_commit(tr->buffer, event);
#endif
}
+static void ftrace_trace_stack(struct trace_array *tr,
+ unsigned long flags,
+ int skip, int pc)
+{
+ if (!(trace_flags & TRACE_ITER_STACKTRACE))
+ return;
+
+ __ftrace_trace_stack(tr, flags, skip, pc);
+}
+
void __trace_stack(struct trace_array *tr,
- struct trace_array_cpu *data,
unsigned long flags,
- int skip)
+ int skip, int pc)
{
- ftrace_trace_stack(tr, data, flags, skip, preempt_count());
+ __ftrace_trace_stack(tr, flags, skip, pc);
}
static void ftrace_trace_userstack(struct trace_array *tr,
- struct trace_array_cpu *data,
- unsigned long flags, int pc)
+ unsigned long flags, int pc)
{
#ifdef CONFIG_STACKTRACE
struct ring_buffer_event *event;
struct userstack_entry *entry;
struct stack_trace trace;
- unsigned long irq_flags;
if (!(trace_flags & TRACE_ITER_USERSTACKTRACE))
return;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
- &irq_flags);
+ event = trace_buffer_lock_reserve(tr, TRACE_USER_STACK,
+ sizeof(*entry), flags, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, flags, pc);
- entry->ent.type = TRACE_USER_STACK;
memset(&entry->caller, 0, sizeof(entry->caller));
@@ -1031,70 +1045,58 @@ static void ftrace_trace_userstack(struct trace_array *tr,
trace.entries = entry->caller;
save_stack_trace_user(&trace);
- ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+ ring_buffer_unlock_commit(tr->buffer, event);
#endif
}
-void __trace_userstack(struct trace_array *tr,
- struct trace_array_cpu *data,
- unsigned long flags)
+#ifdef UNUSED
+static void __trace_userstack(struct trace_array *tr, unsigned long flags)
{
- ftrace_trace_userstack(tr, data, flags, preempt_count());
+ ftrace_trace_userstack(tr, flags, preempt_count());
}
+#endif /* UNUSED */
static void
-ftrace_trace_special(void *__tr, void *__data,
+ftrace_trace_special(void *__tr,
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 special_entry *entry;
- unsigned long irq_flags;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
- &irq_flags);
+ event = trace_buffer_lock_reserve(tr, TRACE_SPECIAL,
+ sizeof(*entry), 0, pc);
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);
- ftrace_trace_userstack(tr, data, irq_flags, pc);
-
- trace_wake_up();
+ trace_buffer_unlock_commit(tr, event, 0, pc);
}
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());
+ ftrace_trace_special(__tr, 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, int pc)
{
struct ring_buffer_event *event;
struct ctx_switch_entry *entry;
- unsigned long irq_flags;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
- &irq_flags);
+ event = trace_buffer_lock_reserve(tr, TRACE_CTX,
+ sizeof(*entry), flags, pc);
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;
@@ -1102,29 +1104,23 @@ tracing_sched_switch_trace(struct trace_array *tr,
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);
- ftrace_trace_userstack(tr, data, flags, pc);
+ trace_buffer_unlock_commit(tr, event, flags, pc);
}
void
tracing_sched_wakeup_trace(struct trace_array *tr,
- struct trace_array_cpu *data,
struct task_struct *wakee,
struct task_struct *curr,
unsigned long flags, int pc)
{
struct ring_buffer_event *event;
struct ctx_switch_entry *entry;
- unsigned long irq_flags;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
- &irq_flags);
+ event = trace_buffer_lock_reserve(tr, TRACE_WAKE,
+ sizeof(*entry), flags, pc);
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;
@@ -1132,11 +1128,10 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
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);
- ftrace_trace_userstack(tr, data, flags, pc);
- trace_wake_up();
+ ring_buffer_unlock_commit(tr->buffer, event);
+ ftrace_trace_stack(tr, flags, 6, pc);
+ ftrace_trace_userstack(tr, flags, pc);
}
void
@@ -1157,66 +1152,7 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3)
data = tr->data[cpu];
if (likely(atomic_inc_return(&data->disabled) == 1))
- ftrace_trace_special(tr, data, arg1, arg2, arg3, pc);
-
- atomic_dec(&data->disabled);
- local_irq_restore(flags);
-}
-
-#ifdef CONFIG_FUNCTION_TRACER
-static void
-function_trace_call_preempt_only(unsigned long ip, unsigned long parent_ip)
-{
- struct trace_array *tr = &global_trace;
- struct trace_array_cpu *data;
- unsigned long flags;
- long disabled;
- int cpu, resched;
- int pc;
-
- if (unlikely(!ftrace_function_enabled))
- return;
-
- pc = preempt_count();
- resched = ftrace_preempt_disable();
- 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, pc);
-
- atomic_dec(&data->disabled);
- ftrace_preempt_enable(resched);
-}
-
-static void
-function_trace_call(unsigned long ip, unsigned long parent_ip)
-{
- struct trace_array *tr = &global_trace;
- struct trace_array_cpu *data;
- unsigned long flags;
- long disabled;
- int cpu;
- int pc;
-
- if (unlikely(!ftrace_function_enabled))
- return;
-
- /*
- * Need to use raw, since this must be called before the
- * recursive protection is performed.
- */
- local_irq_save(flags);
- cpu = raw_smp_processor_id();
- data = tr->data[cpu];
- disabled = atomic_inc_return(&data->disabled);
-
- if (likely(disabled == 1)) {
- pc = preempt_count();
- trace_function(tr, data, ip, parent_ip, flags, pc);
- }
+ ftrace_trace_special(tr, arg1, arg2, arg3, pc);
atomic_dec(&data->disabled);
local_irq_restore(flags);
@@ -1229,6 +1165,7 @@ int trace_graph_entry(struct ftrace_graph_ent *trace)
struct trace_array_cpu *data;
unsigned long flags;
long disabled;
+ int ret;
int cpu;
int pc;
@@ -1244,15 +1181,18 @@ int trace_graph_entry(struct ftrace_graph_ent *trace)
disabled = atomic_inc_return(&data->disabled);
if (likely(disabled == 1)) {
pc = preempt_count();
- __trace_graph_entry(tr, data, trace, flags, pc);
+ ret = __trace_graph_entry(tr, trace, flags, pc);
+ } else {
+ ret = 0;
}
/* Only do the atomic if it is not already set */
if (!test_tsk_trace_graph(current))
set_tsk_trace_graph(current);
+
atomic_dec(&data->disabled);
local_irq_restore(flags);
- return 1;
+ return ret;
}
void trace_graph_return(struct ftrace_graph_ret *trace)
@@ -1270,7 +1210,7 @@ void trace_graph_return(struct ftrace_graph_ret *trace)
disabled = atomic_inc_return(&data->disabled);
if (likely(disabled == 1)) {
pc = preempt_count();
- __trace_graph_return(tr, data, trace, flags, pc);
+ __trace_graph_return(tr, trace, flags, pc);
}
if (!trace->depth)
clear_tsk_trace_graph(current);
@@ -1279,30 +1219,122 @@ void trace_graph_return(struct ftrace_graph_ret *trace)
}
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
-static struct ftrace_ops trace_ops __read_mostly =
-{
- .func = function_trace_call,
-};
-void tracing_start_function_trace(void)
+/**
+ * trace_vbprintk - write binary msg to tracing buffer
+ *
+ */
+int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
{
- ftrace_function_enabled = 0;
+ static raw_spinlock_t trace_buf_lock =
+ (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+ static u32 trace_buf[TRACE_BUF_SIZE];
- if (trace_flags & TRACE_ITER_PREEMPTONLY)
- trace_ops.func = function_trace_call_preempt_only;
- else
- trace_ops.func = function_trace_call;
+ struct ring_buffer_event *event;
+ struct trace_array *tr = &global_trace;
+ struct trace_array_cpu *data;
+ struct bprint_entry *entry;
+ unsigned long flags;
+ int resched;
+ int cpu, len = 0, size, pc;
+
+ if (unlikely(tracing_selftest_running || tracing_disabled))
+ return 0;
+
+ /* Don't pollute graph traces with trace_vprintk internals */
+ pause_graph_tracing();
+
+ pc = preempt_count();
+ resched = ftrace_preempt_disable();
+ cpu = raw_smp_processor_id();
+ data = tr->data[cpu];
+
+ if (unlikely(atomic_read(&data->disabled)))
+ goto out;
+
+ /* Lockdep uses trace_printk for lock tracing */
+ local_irq_save(flags);
+ __raw_spin_lock(&trace_buf_lock);
+ len = vbin_printf(trace_buf, TRACE_BUF_SIZE, fmt, args);
+
+ if (len > TRACE_BUF_SIZE || len < 0)
+ goto out_unlock;
+
+ size = sizeof(*entry) + sizeof(u32) * len;
+ event = trace_buffer_lock_reserve(tr, TRACE_BPRINT, size, flags, pc);
+ if (!event)
+ goto out_unlock;
+ entry = ring_buffer_event_data(event);
+ entry->ip = ip;
+ entry->fmt = fmt;
+
+ memcpy(entry->buf, trace_buf, sizeof(u32) * len);
+ ring_buffer_unlock_commit(tr->buffer, event);
+
+out_unlock:
+ __raw_spin_unlock(&trace_buf_lock);
+ local_irq_restore(flags);
+
+out:
+ ftrace_preempt_enable(resched);
+ unpause_graph_tracing();
- register_ftrace_function(&trace_ops);
- ftrace_function_enabled = 1;
+ return len;
}
+EXPORT_SYMBOL_GPL(trace_vbprintk);
-void tracing_stop_function_trace(void)
+int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
{
- ftrace_function_enabled = 0;
- unregister_ftrace_function(&trace_ops);
+ static raw_spinlock_t trace_buf_lock = __RAW_SPIN_LOCK_UNLOCKED;
+ static char trace_buf[TRACE_BUF_SIZE];
+
+ struct ring_buffer_event *event;
+ struct trace_array *tr = &global_trace;
+ struct trace_array_cpu *data;
+ int cpu, len = 0, size, pc;
+ struct print_entry *entry;
+ unsigned long irq_flags;
+
+ if (tracing_disabled || tracing_selftest_running)
+ return 0;
+
+ pc = preempt_count();
+ preempt_disable_notrace();
+ cpu = raw_smp_processor_id();
+ data = tr->data[cpu];
+
+ if (unlikely(atomic_read(&data->disabled)))
+ goto out;
+
+ pause_graph_tracing();
+ raw_local_irq_save(irq_flags);
+ __raw_spin_lock(&trace_buf_lock);
+ len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args);
+
+ len = min(len, TRACE_BUF_SIZE-1);
+ trace_buf[len] = 0;
+
+ size = sizeof(*entry) + len + 1;
+ event = trace_buffer_lock_reserve(tr, TRACE_PRINT, size, irq_flags, pc);
+ if (!event)
+ goto out_unlock;
+ entry = ring_buffer_event_data(event);
+ entry->ip = ip;
+
+ memcpy(&entry->buf, trace_buf, len);
+ entry->buf[len] = 0;
+ ring_buffer_unlock_commit(tr->buffer, event);
+
+ out_unlock:
+ __raw_spin_unlock(&trace_buf_lock);
+ raw_local_irq_restore(irq_flags);
+ unpause_graph_tracing();
+ out:
+ preempt_enable_notrace();
+
+ return len;
}
-#endif
+EXPORT_SYMBOL_GPL(trace_vprintk);
enum trace_file_type {
TRACE_FILE_LAT_FMT = 1,
@@ -1345,10 +1377,25 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
{
struct ring_buffer *buffer = iter->tr->buffer;
struct trace_entry *ent, *next = NULL;
+ int cpu_file = iter->cpu_file;
u64 next_ts = 0, ts;
int next_cpu = -1;
int cpu;
+ /*
+ * If we are in a per_cpu trace file, don't bother by iterating over
+ * all cpu and peek directly.
+ */
+ if (cpu_file > TRACE_PIPE_ALL_CPU) {
+ if (ring_buffer_empty_cpu(buffer, cpu_file))
+ return NULL;
+ ent = peek_next_entry(iter, cpu_file, ent_ts);
+ if (ent_cpu)
+ *ent_cpu = cpu_file;
+
+ return ent;
+ }
+
for_each_tracing_cpu(cpu) {
if (ring_buffer_empty_cpu(buffer, cpu))
@@ -1376,8 +1423,8 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
}
/* 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)
+struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
+ int *ent_cpu, u64 *ent_ts)
{
return __find_next_entry(iter, ent_cpu, ent_ts);
}
@@ -1426,19 +1473,32 @@ static void *s_next(struct seq_file *m, void *v, loff_t *pos)
return ent;
}
+/*
+ * No necessary locking here. The worst thing which can
+ * happen is loosing events consumed at the same time
+ * by a trace_pipe reader.
+ * Other than that, we don't risk to crash the ring buffer
+ * because it serializes the readers.
+ *
+ * The current tracer is copied to avoid a global locking
+ * all around.
+ */
static void *s_start(struct seq_file *m, loff_t *pos)
{
struct trace_iterator *iter = m->private;
+ static struct tracer *old_tracer;
+ int cpu_file = iter->cpu_file;
void *p = NULL;
loff_t l = 0;
int cpu;
+ /* copy the tracer to avoid using a global lock all around */
mutex_lock(&trace_types_lock);
-
- if (!current_trace || current_trace != iter->trace) {
- mutex_unlock(&trace_types_lock);
- return NULL;
+ if (unlikely(old_tracer != current_trace && current_trace)) {
+ old_tracer = current_trace;
+ *iter->trace = *current_trace;
}
+ mutex_unlock(&trace_types_lock);
atomic_inc(&trace_record_cmdline_disabled);
@@ -1449,9 +1509,12 @@ static void *s_start(struct seq_file *m, loff_t *pos)
ftrace_disable_cpu();
- for_each_tracing_cpu(cpu) {
- ring_buffer_iter_reset(iter->buffer_iter[cpu]);
- }
+ if (cpu_file == TRACE_PIPE_ALL_CPU) {
+ for_each_tracing_cpu(cpu)
+ ring_buffer_iter_reset(iter->buffer_iter[cpu]);
+ } else
+ ring_buffer_iter_reset(iter->buffer_iter[cpu_file]);
+
ftrace_enable_cpu();
@@ -1469,155 +1532,6 @@ static void *s_start(struct seq_file *m, loff_t *pos)
static void s_stop(struct seq_file *m, void *p)
{
atomic_dec(&trace_record_cmdline_disabled);
- mutex_unlock(&trace_types_lock);
-}
-
-#ifdef CONFIG_KRETPROBES
-static inline const char *kretprobed(const char *name)
-{
- static const char tramp_name[] = "kretprobe_trampoline";
- int size = sizeof(tramp_name);
-
- if (strncmp(tramp_name, name, size) == 0)
- return "[unknown/kretprobe'd]";
- return name;
-}
-#else
-static inline const char *kretprobed(const char *name)
-{
- return name;
-}
-#endif /* CONFIG_KRETPROBES */
-
-static int
-seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
-{
-#ifdef CONFIG_KALLSYMS
- char str[KSYM_SYMBOL_LEN];
- const char *name;
-
- kallsyms_lookup(address, NULL, NULL, NULL, str);
-
- name = kretprobed(str);
-
- return trace_seq_printf(s, fmt, name);
-#endif
- return 1;
-}
-
-static int
-seq_print_sym_offset(struct trace_seq *s, const char *fmt,
- unsigned long address)
-{
-#ifdef CONFIG_KALLSYMS
- char str[KSYM_SYMBOL_LEN];
- const char *name;
-
- sprint_symbol(str, address);
- name = kretprobed(str);
-
- return trace_seq_printf(s, fmt, name);
-#endif
- return 1;
-}
-
-#ifndef CONFIG_64BIT
-# define IP_FMT "%08lx"
-#else
-# define IP_FMT "%016lx"
-#endif
-
-int
-seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
-{
- int ret;
-
- if (!ip)
- return trace_seq_printf(s, "0");
-
- if (sym_flags & TRACE_ITER_SYM_OFFSET)
- ret = seq_print_sym_offset(s, "%s", ip);
- else
- ret = seq_print_sym_short(s, "%s", ip);
-
- if (!ret)
- return 0;
-
- if (sym_flags & TRACE_ITER_SYM_ADDR)
- ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
- return ret;
-}
-
-static inline int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
- unsigned long ip, unsigned long sym_flags)
-{
- struct file *file = NULL;
- unsigned long vmstart = 0;
- int ret = 1;
-
- if (mm) {
- const struct vm_area_struct *vma;
-
- down_read(&mm->mmap_sem);
- vma = find_vma(mm, ip);
- if (vma) {
- file = vma->vm_file;
- vmstart = vma->vm_start;
- }
- if (file) {
- ret = trace_seq_path(s, &file->f_path);
- if (ret)
- ret = trace_seq_printf(s, "[+0x%lx]", ip - vmstart);
- }
- up_read(&mm->mmap_sem);
- }
- if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
- ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
- return ret;
-}
-
-static int
-seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
- unsigned long sym_flags)
-{
- struct mm_struct *mm = NULL;
- int ret = 1;
- unsigned int i;
-
- if (trace_flags & TRACE_ITER_SYM_USEROBJ) {
- struct task_struct *task;
- /*
- * we do the lookup on the thread group leader,
- * since individual threads might have already quit!
- */
- rcu_read_lock();
- task = find_task_by_vpid(entry->ent.tgid);
- if (task)
- mm = get_task_mm(task);
- rcu_read_unlock();
- }
-
- for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
- unsigned long ip = entry->caller[i];
-
- if (ip == ULONG_MAX || !ret)
- break;
- if (i && ret)
- ret = trace_seq_puts(s, " <- ");
- if (!ip) {
- if (ret)
- ret = trace_seq_puts(s, "??");
- continue;
- }
- if (!ret)
- break;
- if (ret)
- ret = seq_print_user_ip(s, mm, ip, sym_flags);
- }
-
- if (mm)
- mmput(mm);
- return ret;
}
static void print_lat_help_header(struct seq_file *m)
@@ -1658,11 +1572,11 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter)
total = entries +
ring_buffer_overruns(iter->tr->buffer);
- seq_printf(m, "%s latency trace v1.1.5 on %s\n",
+ seq_printf(m, "# %s latency trace v1.1.5 on %s\n",
name, UTS_RELEASE);
- seq_puts(m, "-----------------------------------"
+ seq_puts(m, "# -----------------------------------"
"---------------------------------\n");
- seq_printf(m, " latency: %lu us, #%lu/%lu, CPU#%d |"
+ seq_printf(m, "# latency: %lu us, #%lu/%lu, CPU#%d |"
" (M:%s VP:%d, KP:%d, SP:%d HP:%d",
nsecs_to_usecs(data->saved_latency),
entries,
@@ -1684,121 +1598,24 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter)
#else
seq_puts(m, ")\n");
#endif
- seq_puts(m, " -----------------\n");
- seq_printf(m, " | task: %.16s-%d "
+ seq_puts(m, "# -----------------\n");
+ seq_printf(m, "# | task: %.16s-%d "
"(uid:%d nice:%ld policy:%ld rt_prio:%ld)\n",
data->comm, data->pid, data->uid, data->nice,
data->policy, data->rt_priority);
- seq_puts(m, " -----------------\n");
+ seq_puts(m, "# -----------------\n");
if (data->critical_start) {
- seq_puts(m, " => started at: ");
+ seq_puts(m, "# => started at: ");
seq_print_ip_sym(&iter->seq, data->critical_start, sym_flags);
trace_print_seq(m, &iter->seq);
- seq_puts(m, "\n => ended at: ");
+ seq_puts(m, "\n# => ended at: ");
seq_print_ip_sym(&iter->seq, data->critical_end, sym_flags);
trace_print_seq(m, &iter->seq);
- seq_puts(m, "\n");
- }
-
- seq_puts(m, "\n");
-}
-
-static void
-lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
-{
- int hardirq, softirq;
- char *comm;
-
- comm = trace_find_cmdline(entry->pid);
-
- trace_seq_printf(s, "%8.8s-%-5d ", comm, entry->pid);
- trace_seq_printf(s, "%3d", cpu);
- trace_seq_printf(s, "%c%c",
- (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
- (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' : '.',
- ((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.'));
-
- hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
- softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
- if (hardirq && softirq) {
- trace_seq_putc(s, 'H');
- } else {
- if (hardirq) {
- trace_seq_putc(s, 'h');
- } else {
- if (softirq)
- trace_seq_putc(s, 's');
- else
- trace_seq_putc(s, '.');
- }
- }
-
- if (entry->preempt_count)
- trace_seq_printf(s, "%x", entry->preempt_count);
- else
- trace_seq_puts(s, ".");
-}
-
-unsigned long preempt_mark_thresh = 100;
-
-static void
-lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
- unsigned long rel_usecs)
-{
- trace_seq_printf(s, " %4lldus", abs_usecs);
- if (rel_usecs > preempt_mark_thresh)
- trace_seq_puts(s, "!: ");
- else if (rel_usecs > 1)
- trace_seq_puts(s, "+: ");
- else
- trace_seq_puts(s, " : ");
-}
-
-static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
-
-static int task_state_char(unsigned long state)
-{
- int bit = state ? __ffs(state) + 1 : 0;
-
- return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
-}
-
-/*
- * 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;
+ seq_puts(m, "#\n");
}
- 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');
+ seq_puts(m, "#\n");
}
static void test_cpu_buff_start(struct trace_iterator *iter)
@@ -1815,141 +1632,11 @@ static void test_cpu_buff_start(struct trace_iterator *iter)
return;
cpumask_set_cpu(iter->cpu, iter->started);
- trace_seq_printf(s, "##### CPU %u buffer started ####\n", iter->cpu);
-}
-
-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;
- 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;
-
- if (entry->type == TRACE_CONT)
- return TRACE_TYPE_HANDLED;
-
- test_cpu_buff_start(iter);
-
- next_entry = find_next_entry(iter, NULL, &next_ts);
- if (!next_entry)
- 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 %3d %d %08x %08x [%08lx]"
- " %ld.%03ldms (+%ld.%03ldms): ",
- comm,
- entry->pid, cpu, entry->flags,
- entry->preempt_count, trace_idx,
- ns2usecs(iter->ts),
- abs_usecs/1000,
- abs_usecs % 1000, rel_usecs/1000,
- rel_usecs % 1000);
- } else {
- lat_print_generic(s, entry, cpu);
- lat_print_timestamp(s, abs_usecs, rel_usecs);
- }
- switch (entry->type) {
- 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, " (");
- seq_print_ip_sym(s, field->parent_ip, sym_flags);
- trace_seq_puts(s, ")\n");
- break;
- }
- case TRACE_CTX:
- case TRACE_WAKE: {
- struct ctx_switch_entry *field;
-
- trace_assign_type(field, entry);
-
- T = task_state_char(field->next_state);
- S = task_state_char(field->prev_state);
- 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 ? "==>" : " +",
- field->next_cpu,
- field->next_pid,
- field->next_prio,
- T, comm);
- break;
- }
- case TRACE_SPECIAL: {
- struct special_entry *field;
-
- trace_assign_type(field, entry);
-
- trace_seq_printf(s, "# %ld %ld %ld\n",
- field->arg1,
- field->arg2,
- field->arg3);
- break;
- }
- 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, 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;
- }
- case TRACE_BRANCH: {
- struct trace_branch *field;
-
- trace_assign_type(field, entry);
-
- trace_seq_printf(s, "[%s] %s:%s:%d\n",
- field->correct ? " ok " : " MISS ",
- field->func,
- field->file,
- field->line);
- break;
- }
- case TRACE_USER_STACK: {
- struct userstack_entry *field;
-
- trace_assign_type(field, entry);
- seq_print_userip_objs(field, s, sym_flags);
- trace_seq_putc(s, '\n');
- break;
- }
- default:
- trace_seq_printf(s, "Unknown type %d\n", entry->type);
- }
- return TRACE_TYPE_HANDLED;
+ /* Don't print started cpu buffer for the first entry of the trace */
+ if (iter->idx > 1)
+ trace_seq_printf(s, "##### CPU %u buffer started ####\n",
+ iter->cpu);
}
static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
@@ -1957,333 +1644,84 @@ 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);
struct trace_entry *entry;
- unsigned long usec_rem;
- unsigned long long t;
- unsigned long secs;
- char *comm;
- int ret;
- int S, T;
- int i;
+ struct trace_event *event;
entry = iter->ent;
- if (entry->type == TRACE_CONT)
- return TRACE_TYPE_HANDLED;
-
test_cpu_buff_start(iter);
- comm = trace_find_cmdline(iter->ent->pid);
-
- 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 TRACE_TYPE_PARTIAL_LINE;
- ret = trace_seq_printf(s, "[%03d] ", iter->cpu);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- ret = trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
-
- switch (entry->type) {
- 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 TRACE_TYPE_PARTIAL_LINE;
- if ((sym_flags & TRACE_ITER_PRINT_PARENT) &&
- field->parent_ip) {
- ret = trace_seq_printf(s, " <-");
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- ret = seq_print_ip_sym(s,
- field->parent_ip,
- sym_flags);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- }
- ret = trace_seq_printf(s, "\n");
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- break;
- }
- case TRACE_CTX:
- case TRACE_WAKE: {
- struct ctx_switch_entry *field;
-
- trace_assign_type(field, entry);
-
- T = task_state_char(field->next_state);
- S = task_state_char(field->prev_state);
- 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 ? "==>" : " +",
- field->next_cpu,
- field->next_pid,
- field->next_prio,
- T);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- break;
- }
- case TRACE_SPECIAL: {
- struct special_entry *field;
+ event = ftrace_find_event(entry->type);
- trace_assign_type(field, entry);
-
- ret = trace_seq_printf(s, "# %ld %ld %ld\n",
- field->arg1,
- field->arg2,
- field->arg3);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- break;
- }
- 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 TRACE_TYPE_PARTIAL_LINE;
- }
- ret = seq_print_ip_sym(s, field->caller[i],
- sym_flags);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
+ if (trace_flags & TRACE_ITER_CONTEXT_INFO) {
+ if (iter->iter_flags & TRACE_FILE_LAT_FMT) {
+ if (!trace_print_lat_context(iter))
+ goto partial;
+ } else {
+ if (!trace_print_context(iter))
+ goto partial;
}
- ret = trace_seq_puts(s, "\n");
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- 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;
- }
- case TRACE_GRAPH_RET: {
- return print_graph_function(iter);
}
- case TRACE_GRAPH_ENT: {
- return print_graph_function(iter);
- }
- case TRACE_BRANCH: {
- struct trace_branch *field;
-
- trace_assign_type(field, entry);
- trace_seq_printf(s, "[%s] %s:%s:%d\n",
- field->correct ? " ok " : " MISS ",
- field->func,
- field->file,
- field->line);
- break;
- }
- case TRACE_USER_STACK: {
- struct userstack_entry *field;
+ if (event)
+ return event->trace(iter, sym_flags);
- trace_assign_type(field, entry);
+ if (!trace_seq_printf(s, "Unknown type %d\n", entry->type))
+ goto partial;
- ret = seq_print_userip_objs(field, s, sym_flags);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- ret = trace_seq_putc(s, '\n');
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- break;
- }
- }
return TRACE_TYPE_HANDLED;
+partial:
+ return TRACE_TYPE_PARTIAL_LINE;
}
static enum print_line_t print_raw_fmt(struct trace_iterator *iter)
{
struct trace_seq *s = &iter->seq;
struct trace_entry *entry;
- int ret;
- int S, T;
+ struct trace_event *event;
entry = iter->ent;
- if (entry->type == TRACE_CONT)
- return TRACE_TYPE_HANDLED;
-
- ret = trace_seq_printf(s, "%d %d %llu ",
- entry->pid, iter->cpu, iter->ts);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
-
- switch (entry->type) {
- case TRACE_FN: {
- struct ftrace_entry *field;
-
- trace_assign_type(field, entry);
-
- ret = trace_seq_printf(s, "%x %x\n",
- field->ip,
- field->parent_ip);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- break;
+ if (trace_flags & TRACE_ITER_CONTEXT_INFO) {
+ if (!trace_seq_printf(s, "%d %d %llu ",
+ entry->pid, iter->cpu, iter->ts))
+ goto partial;
}
- case TRACE_CTX:
- case TRACE_WAKE: {
- struct ctx_switch_entry *field;
-
- trace_assign_type(field, entry);
-
- T = task_state_char(field->next_state);
- S = entry->type == TRACE_WAKE ? '+' :
- task_state_char(field->prev_state);
- ret = trace_seq_printf(s, "%d %d %c %d %d %d %c\n",
- field->prev_pid,
- field->prev_prio,
- S,
- field->next_cpu,
- field->next_pid,
- field->next_prio,
- T);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- break;
- }
- case TRACE_SPECIAL:
- case TRACE_USER_STACK:
- case TRACE_STACK: {
- struct special_entry *field;
-
- trace_assign_type(field, entry);
- ret = trace_seq_printf(s, "# %ld %ld %ld\n",
- field->arg1,
- field->arg2,
- field->arg3);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- break;
- }
- case TRACE_PRINT: {
- struct print_entry *field;
+ event = ftrace_find_event(entry->type);
+ if (event)
+ return event->raw(iter, 0);
- trace_assign_type(field, entry);
+ if (!trace_seq_printf(s, "%d ?\n", entry->type))
+ goto partial;
- 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;
+partial:
+ return TRACE_TYPE_PARTIAL_LINE;
}
-#define SEQ_PUT_FIELD_RET(s, x) \
-do { \
- if (!trace_seq_putmem(s, &(x), sizeof(x))) \
- return 0; \
-} while (0)
-
-#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 enum print_line_t print_hex_fmt(struct trace_iterator *iter)
{
struct trace_seq *s = &iter->seq;
unsigned char newline = '\n';
struct trace_entry *entry;
- int S, T;
+ struct trace_event *event;
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, iter->ts);
-
- switch (entry->type) {
- 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;
+ if (trace_flags & TRACE_ITER_CONTEXT_INFO) {
+ SEQ_PUT_HEX_FIELD_RET(s, entry->pid);
+ SEQ_PUT_HEX_FIELD_RET(s, iter->cpu);
+ SEQ_PUT_HEX_FIELD_RET(s, iter->ts);
}
- case TRACE_CTX:
- case TRACE_WAKE: {
- struct ctx_switch_entry *field;
-
- trace_assign_type(field, entry);
-
- T = task_state_char(field->next_state);
- S = entry->type == TRACE_WAKE ? '+' :
- task_state_char(field->prev_state);
- 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, 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_USER_STACK:
- 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;
- }
+ event = ftrace_find_event(entry->type);
+ if (event) {
+ enum print_line_t ret = event->hex(iter, 0);
+ if (ret != TRACE_TYPE_HANDLED)
+ return ret;
}
- SEQ_PUT_FIELD_RET(s, newline);
-
- return TRACE_TYPE_HANDLED;
-}
-
-static enum print_line_t print_printk_msg_only(struct trace_iterator *iter)
-{
- struct trace_seq *s = &iter->seq;
- struct trace_entry *entry = iter->ent;
- struct print_entry *field;
- int ret;
-
- trace_assign_type(field, entry);
- ret = trace_seq_printf(s, field->buf);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
-
- if (entry->flags & TRACE_FLAG_CONT)
- trace_seq_print_cont(s, iter);
+ SEQ_PUT_FIELD_RET(s, newline);
return TRACE_TYPE_HANDLED;
}
@@ -2292,59 +1730,37 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter)
{
struct trace_seq *s = &iter->seq;
struct trace_entry *entry;
+ struct trace_event *event;
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, iter->ts);
-
- switch (entry->type) {
- 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: {
- 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;
+ if (trace_flags & TRACE_ITER_CONTEXT_INFO) {
+ SEQ_PUT_FIELD_RET(s, entry->pid);
+ SEQ_PUT_FIELD_RET(s, iter->cpu);
+ SEQ_PUT_FIELD_RET(s, iter->ts);
}
- case TRACE_SPECIAL:
- case TRACE_USER_STACK:
- 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;
+ event = ftrace_find_event(entry->type);
+ return event ? event->binary(iter, 0) : TRACE_TYPE_HANDLED;
}
static int trace_empty(struct trace_iterator *iter)
{
int cpu;
+ /* If we are looking at one CPU buffer, only check that one */
+ if (iter->cpu_file != TRACE_PIPE_ALL_CPU) {
+ cpu = iter->cpu_file;
+ 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;
+ }
+
for_each_tracing_cpu(cpu) {
if (iter->buffer_iter[cpu]) {
if (!ring_buffer_iter_empty(iter->buffer_iter[cpu]))
@@ -2368,10 +1784,15 @@ static enum print_line_t print_trace_line(struct trace_iterator *iter)
return ret;
}
+ if (iter->ent->type == TRACE_BPRINT &&
+ trace_flags & TRACE_ITER_PRINTK &&
+ trace_flags & TRACE_ITER_PRINTK_MSGONLY)
+ return trace_print_bprintk_msg_only(iter);
+
if (iter->ent->type == TRACE_PRINT &&
trace_flags & TRACE_ITER_PRINTK &&
trace_flags & TRACE_ITER_PRINTK_MSGONLY)
- return print_printk_msg_only(iter);
+ return trace_print_printk_msg_only(iter);
if (trace_flags & TRACE_ITER_BIN)
return print_bin_fmt(iter);
@@ -2382,9 +1803,6 @@ static enum print_line_t print_trace_line(struct trace_iterator *iter)
if (trace_flags & TRACE_ITER_RAW)
return print_raw_fmt(iter);
- if (iter->iter_flags & TRACE_FILE_LAT_FMT)
- return print_lat_fmt(iter, iter->idx, iter->cpu);
-
return print_trace_fmt(iter);
}
@@ -2426,30 +1844,45 @@ static struct seq_operations tracer_seq_ops = {
};
static struct trace_iterator *
-__tracing_open(struct inode *inode, struct file *file, int *ret)
+__tracing_open(struct inode *inode, struct file *file)
{
+ long cpu_file = (long) inode->i_private;
+ void *fail_ret = ERR_PTR(-ENOMEM);
struct trace_iterator *iter;
struct seq_file *m;
- int cpu;
+ int cpu, ret;
- if (tracing_disabled) {
- *ret = -ENODEV;
- return NULL;
- }
+ if (tracing_disabled)
+ return ERR_PTR(-ENODEV);
iter = kzalloc(sizeof(*iter), GFP_KERNEL);
- if (!iter) {
- *ret = -ENOMEM;
- goto out;
- }
+ if (!iter)
+ return ERR_PTR(-ENOMEM);
+ /*
+ * We make a copy of the current tracer to avoid concurrent
+ * changes on it while we are reading.
+ */
mutex_lock(&trace_types_lock);
+ iter->trace = kzalloc(sizeof(*iter->trace), GFP_KERNEL);
+ if (!iter->trace)
+ goto fail;
+
+ if (current_trace)
+ *iter->trace = *current_trace;
+
+ if (!alloc_cpumask_var(&iter->started, GFP_KERNEL))
+ goto fail;
+
+ cpumask_clear(iter->started);
+
if (current_trace && current_trace->print_max)
iter->tr = &max_tr;
else
- iter->tr = inode->i_private;
- iter->trace = current_trace;
+ iter->tr = &global_trace;
iter->pos = -1;
+ mutex_init(&iter->mutex);
+ iter->cpu_file = cpu_file;
/* Notify the tracer early; before we stop tracing. */
if (iter->trace && iter->trace->open)
@@ -2459,20 +1892,24 @@ __tracing_open(struct inode *inode, struct file *file, int *ret)
if (ring_buffer_overruns(iter->tr->buffer))
iter->iter_flags |= TRACE_FILE_ANNOTATE;
+ if (iter->cpu_file == TRACE_PIPE_ALL_CPU) {
+ for_each_tracing_cpu(cpu) {
- for_each_tracing_cpu(cpu) {
-
+ iter->buffer_iter[cpu] =
+ ring_buffer_read_start(iter->tr->buffer, cpu);
+ }
+ } else {
+ cpu = iter->cpu_file;
iter->buffer_iter[cpu] =
- ring_buffer_read_start(iter->tr->buffer, cpu);
-
- if (!iter->buffer_iter[cpu])
- goto fail_buffer;
+ ring_buffer_read_start(iter->tr->buffer, cpu);
}
/* TODO stop tracer */
- *ret = seq_open(file, &tracer_seq_ops);
- if (*ret)
+ ret = seq_open(file, &tracer_seq_ops);
+ if (ret < 0) {
+ fail_ret = ERR_PTR(ret);
goto fail_buffer;
+ }
m = file->private_data;
m->private = iter;
@@ -2482,7 +1919,6 @@ __tracing_open(struct inode *inode, struct file *file, int *ret)
mutex_unlock(&trace_types_lock);
- out:
return iter;
fail_buffer:
@@ -2490,10 +1926,13 @@ __tracing_open(struct inode *inode, struct file *file, int *ret)
if (iter->buffer_iter[cpu])
ring_buffer_read_finish(iter->buffer_iter[cpu]);
}
+ free_cpumask_var(iter->started);
+ fail:
mutex_unlock(&trace_types_lock);
+ kfree(iter->trace);
kfree(iter);
- return ERR_PTR(-ENOMEM);
+ return fail_ret;
}
int tracing_open_generic(struct inode *inode, struct file *filp)
@@ -2505,12 +1944,17 @@ int tracing_open_generic(struct inode *inode, struct file *filp)
return 0;
}
-int tracing_release(struct inode *inode, struct file *file)
+static 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;
+ struct trace_iterator *iter;
int cpu;
+ if (!(file->f_mode & FMODE_READ))
+ return 0;
+
+ iter = m->private;
+
mutex_lock(&trace_types_lock);
for_each_tracing_cpu(cpu) {
if (iter->buffer_iter[cpu])
@@ -2525,33 +1969,39 @@ int tracing_release(struct inode *inode, struct file *file)
mutex_unlock(&trace_types_lock);
seq_release(inode, file);
+ mutex_destroy(&iter->mutex);
+ free_cpumask_var(iter->started);
+ kfree(iter->trace);
kfree(iter);
return 0;
}
static int tracing_open(struct inode *inode, struct file *file)
{
- int ret;
-
- __tracing_open(inode, file, &ret);
-
- return ret;
-}
-
-static int tracing_lt_open(struct inode *inode, struct file *file)
-{
struct trace_iterator *iter;
- int ret;
+ int ret = 0;
- iter = __tracing_open(inode, file, &ret);
+ /* If this file was open for write, then erase contents */
+ if ((file->f_mode & FMODE_WRITE) &&
+ !(file->f_flags & O_APPEND)) {
+ long cpu = (long) inode->i_private;
- if (!ret)
- iter->iter_flags |= TRACE_FILE_LAT_FMT;
+ if (cpu == TRACE_PIPE_ALL_CPU)
+ tracing_reset_online_cpus(&global_trace);
+ else
+ tracing_reset(&global_trace, cpu);
+ }
+ if (file->f_mode & FMODE_READ) {
+ iter = __tracing_open(inode, file);
+ if (IS_ERR(iter))
+ ret = PTR_ERR(iter);
+ else if (trace_flags & TRACE_ITER_LATENCY_FMT)
+ iter->iter_flags |= TRACE_FILE_LAT_FMT;
+ }
return ret;
}
-
static void *
t_next(struct seq_file *m, void *v, loff_t *pos)
{
@@ -2623,21 +2073,22 @@ static int show_traces_open(struct inode *inode, struct file *file)
return ret;
}
-static struct file_operations tracing_fops = {
- .open = tracing_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = tracing_release,
-};
+static ssize_t
+tracing_write_stub(struct file *filp, const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ return count;
+}
-static struct file_operations tracing_lt_fops = {
- .open = tracing_lt_open,
+static const struct file_operations tracing_fops = {
+ .open = tracing_open,
.read = seq_read,
+ .write = tracing_write_stub,
.llseek = seq_lseek,
.release = tracing_release,
};
-static struct file_operations show_traces_fops = {
+static const struct file_operations show_traces_fops = {
.open = show_traces_open,
.read = seq_read,
.release = seq_release,
@@ -2730,7 +2181,7 @@ err_unlock:
return err;
}
-static struct file_operations tracing_cpumask_fops = {
+static const struct file_operations tracing_cpumask_fops = {
.open = tracing_open_generic,
.read = tracing_cpumask_read,
.write = tracing_cpumask_write,
@@ -2740,57 +2191,62 @@ static ssize_t
tracing_trace_options_read(struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos)
{
- int i;
+ struct tracer_opt *trace_opts;
+ u32 tracer_flags;
+ int len = 0;
char *buf;
int r = 0;
- int len = 0;
- u32 tracer_flags = current_trace->flags->val;
- struct tracer_opt *trace_opts = current_trace->flags->opts;
+ int i;
- /* calulate max size */
+ /* calculate max size */
for (i = 0; trace_options[i]; i++) {
len += strlen(trace_options[i]);
- len += 3; /* "no" and space */
+ len += 3; /* "no" and newline */
}
+ mutex_lock(&trace_types_lock);
+ tracer_flags = current_trace->flags->val;
+ trace_opts = current_trace->flags->opts;
+
/*
* Increase the size with names of options specific
* of the current tracer.
*/
for (i = 0; trace_opts[i].name; i++) {
len += strlen(trace_opts[i].name);
- len += 3; /* "no" and space */
+ len += 3; /* "no" and newline */
}
/* +2 for \n and \0 */
buf = kmalloc(len + 2, GFP_KERNEL);
- if (!buf)
+ if (!buf) {
+ mutex_unlock(&trace_types_lock);
return -ENOMEM;
+ }
for (i = 0; trace_options[i]; i++) {
if (trace_flags & (1 << i))
- r += sprintf(buf + r, "%s ", trace_options[i]);
+ r += sprintf(buf + r, "%s\n", trace_options[i]);
else
- r += sprintf(buf + r, "no%s ", trace_options[i]);
+ r += sprintf(buf + r, "no%s\n", trace_options[i]);
}
for (i = 0; trace_opts[i].name; i++) {
if (tracer_flags & trace_opts[i].bit)
- r += sprintf(buf + r, "%s ",
+ r += sprintf(buf + r, "%s\n",
trace_opts[i].name);
else
- r += sprintf(buf + r, "no%s ",
+ r += sprintf(buf + r, "no%s\n",
trace_opts[i].name);
}
+ mutex_unlock(&trace_types_lock);
- r += sprintf(buf + r, "\n");
WARN_ON(r >= len + 2);
r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
kfree(buf);
-
return r;
}
@@ -2828,6 +2284,34 @@ static int set_tracer_option(struct tracer *trace, char *cmp, int neg)
return 0;
}
+static void set_tracer_flags(unsigned int mask, int enabled)
+{
+ /* do nothing if flag is already set */
+ if (!!(trace_flags & mask) == !!enabled)
+ return;
+
+ if (enabled)
+ trace_flags |= mask;
+ else
+ trace_flags &= ~mask;
+
+ if (mask == TRACE_ITER_GLOBAL_CLK) {
+ u64 (*func)(void);
+
+ if (enabled)
+ func = trace_clock_global;
+ else
+ func = trace_clock_local;
+
+ mutex_lock(&trace_types_lock);
+ ring_buffer_set_clock(global_trace.buffer, func);
+
+ if (max_tr.buffer)
+ ring_buffer_set_clock(max_tr.buffer, func);
+ mutex_unlock(&trace_types_lock);
+ }
+}
+
static ssize_t
tracing_trace_options_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos)
@@ -2855,17 +2339,16 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
int len = strlen(trace_options[i]);
if (strncmp(cmp, trace_options[i], len) == 0) {
- if (neg)
- trace_flags &= ~(1 << i);
- else
- trace_flags |= (1 << i);
+ set_tracer_flags(1 << i, !neg);
break;
}
}
/* If no option could be set, test the specific tracer options */
if (!trace_options[i]) {
+ mutex_lock(&trace_types_lock);
ret = set_tracer_option(current_trace, cmp, neg);
+ mutex_unlock(&trace_types_lock);
if (ret)
return ret;
}
@@ -2875,7 +2358,7 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf,
return cnt;
}
-static struct file_operations tracing_iter_fops = {
+static const struct file_operations tracing_iter_fops = {
.open = tracing_open_generic,
.read = tracing_trace_options_read,
.write = tracing_trace_options_write,
@@ -2886,9 +2369,9 @@ static const char readme_msg[] =
"# mkdir /debug\n"
"# mount -t debugfs nodev /debug\n\n"
"# cat /debug/tracing/available_tracers\n"
- "wakeup preemptirqsoff preemptoff irqsoff ftrace sched_switch none\n\n"
+ "wakeup preemptirqsoff preemptoff irqsoff function sched_switch nop\n\n"
"# cat /debug/tracing/current_tracer\n"
- "none\n"
+ "nop\n"
"# echo sched_switch > /debug/tracing/current_tracer\n"
"# cat /debug/tracing/current_tracer\n"
"sched_switch\n"
@@ -2908,7 +2391,7 @@ tracing_readme_read(struct file *filp, char __user *ubuf,
readme_msg, strlen(readme_msg));
}
-static struct file_operations tracing_readme_fops = {
+static const struct file_operations tracing_readme_fops = {
.open = tracing_open_generic,
.read = tracing_readme_read,
};
@@ -2930,7 +2413,7 @@ tracing_ctrl_write(struct file *filp, const char __user *ubuf,
{
struct trace_array *tr = filp->private_data;
char buf[64];
- long val;
+ unsigned long val;
int ret;
if (cnt >= sizeof(buf))
@@ -2985,13 +2468,105 @@ tracing_set_trace_read(struct file *filp, char __user *ubuf,
return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
}
-static int tracing_set_tracer(char *buf)
+int tracer_init(struct tracer *t, struct trace_array *tr)
+{
+ tracing_reset_online_cpus(tr);
+ return t->init(tr);
+}
+
+static int tracing_resize_ring_buffer(unsigned long size)
+{
+ int ret;
+
+ /*
+ * If kernel or user changes the size of the ring buffer
+ * we use the size that was given, and we can forget about
+ * expanding it later.
+ */
+ ring_buffer_expanded = 1;
+
+ ret = ring_buffer_resize(global_trace.buffer, size);
+ if (ret < 0)
+ return ret;
+
+ ret = ring_buffer_resize(max_tr.buffer, size);
+ if (ret < 0) {
+ int r;
+
+ r = ring_buffer_resize(global_trace.buffer,
+ global_trace.entries);
+ if (r < 0) {
+ /*
+ * AARGH! We are left with different
+ * size max buffer!!!!
+ * The max buffer is our "snapshot" buffer.
+ * When a tracer needs a snapshot (one of the
+ * latency tracers), it swaps the max buffer
+ * with the saved snap shot. We succeeded to
+ * update the size of the main buffer, but failed to
+ * update the size of the max buffer. But when we tried
+ * to reset the main buffer to the original size, we
+ * failed there too. This is very unlikely to
+ * happen, but if it does, warn and kill all
+ * tracing.
+ */
+ WARN_ON(1);
+ tracing_disabled = 1;
+ }
+ return ret;
+ }
+
+ global_trace.entries = size;
+
+ return ret;
+}
+
+/**
+ * tracing_update_buffers - used by tracing facility to expand ring buffers
+ *
+ * To save on memory when the tracing is never used on a system with it
+ * configured in. The ring buffers are set to a minimum size. But once
+ * a user starts to use the tracing facility, then they need to grow
+ * to their default size.
+ *
+ * This function is to be called when a tracer is about to be used.
+ */
+int tracing_update_buffers(void)
+{
+ int ret = 0;
+
+ mutex_lock(&trace_types_lock);
+ if (!ring_buffer_expanded)
+ ret = tracing_resize_ring_buffer(trace_buf_size);
+ mutex_unlock(&trace_types_lock);
+
+ return ret;
+}
+
+struct trace_option_dentry;
+
+static struct trace_option_dentry *
+create_trace_option_files(struct tracer *tracer);
+
+static void
+destroy_trace_option_files(struct trace_option_dentry *topts);
+
+static int tracing_set_tracer(const char *buf)
{
+ static struct trace_option_dentry *topts;
struct trace_array *tr = &global_trace;
struct tracer *t;
int ret = 0;
mutex_lock(&trace_types_lock);
+
+ if (!ring_buffer_expanded) {
+ ret = tracing_resize_ring_buffer(trace_buf_size);
+ if (ret < 0)
+ goto out;
+ ret = 0;
+ }
+
for (t = trace_types; t; t = t->next) {
if (strcmp(t->name, buf) == 0)
break;
@@ -3007,9 +2582,14 @@ static int tracing_set_tracer(char *buf)
if (current_trace && current_trace->reset)
current_trace->reset(tr);
+ destroy_trace_option_files(topts);
+
current_trace = t;
+
+ topts = create_trace_option_files(current_trace);
+
if (t->init) {
- ret = t->init(tr);
+ ret = tracer_init(t, tr);
if (ret)
goto out;
}
@@ -3072,9 +2652,9 @@ static ssize_t
tracing_max_lat_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos)
{
- long *ptr = filp->private_data;
+ unsigned long *ptr = filp->private_data;
char buf[64];
- long val;
+ unsigned long val;
int ret;
if (cnt >= sizeof(buf))
@@ -3094,54 +2674,96 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf,
return cnt;
}
-static atomic_t tracing_reader;
-
static int tracing_open_pipe(struct inode *inode, struct file *filp)
{
+ long cpu_file = (long) inode->i_private;
struct trace_iterator *iter;
+ int ret = 0;
if (tracing_disabled)
return -ENODEV;
- /* We only allow for reader of the pipe */
- if (atomic_inc_return(&tracing_reader) != 1) {
- atomic_dec(&tracing_reader);
- return -EBUSY;
+ mutex_lock(&trace_types_lock);
+
+ /* We only allow one reader per cpu */
+ if (cpu_file == TRACE_PIPE_ALL_CPU) {
+ if (!cpumask_empty(tracing_reader_cpumask)) {
+ ret = -EBUSY;
+ goto out;
+ }
+ cpumask_setall(tracing_reader_cpumask);
+ } else {
+ if (!cpumask_test_cpu(cpu_file, tracing_reader_cpumask))
+ cpumask_set_cpu(cpu_file, tracing_reader_cpumask);
+ else {
+ ret = -EBUSY;
+ goto out;
+ }
}
/* create a buffer to store the information to pass to userspace */
iter = kzalloc(sizeof(*iter), GFP_KERNEL);
- if (!iter)
- return -ENOMEM;
+ if (!iter) {
+ ret = -ENOMEM;
+ goto out;
+ }
- if (!alloc_cpumask_var(&iter->started, GFP_KERNEL)) {
- kfree(iter);
- return -ENOMEM;
+ /*
+ * We make a copy of the current tracer to avoid concurrent
+ * changes on it while we are reading.
+ */
+ iter->trace = kmalloc(sizeof(*iter->trace), GFP_KERNEL);
+ if (!iter->trace) {
+ ret = -ENOMEM;
+ goto fail;
}
+ if (current_trace)
+ *iter->trace = *current_trace;
- mutex_lock(&trace_types_lock);
+ if (!alloc_cpumask_var(&iter->started, GFP_KERNEL)) {
+ ret = -ENOMEM;
+ goto fail;
+ }
/* trace pipe does not show start of buffer */
cpumask_setall(iter->started);
+ iter->cpu_file = cpu_file;
iter->tr = &global_trace;
- iter->trace = current_trace;
+ mutex_init(&iter->mutex);
filp->private_data = iter;
if (iter->trace->pipe_open)
iter->trace->pipe_open(iter);
+
+out:
mutex_unlock(&trace_types_lock);
+ return ret;
- return 0;
+fail:
+ kfree(iter->trace);
+ kfree(iter);
+ mutex_unlock(&trace_types_lock);
+ return ret;
}
static int tracing_release_pipe(struct inode *inode, struct file *file)
{
struct trace_iterator *iter = file->private_data;
+ mutex_lock(&trace_types_lock);
+
+ if (iter->cpu_file == TRACE_PIPE_ALL_CPU)
+ cpumask_clear(tracing_reader_cpumask);
+ else
+ cpumask_clear_cpu(iter->cpu_file, tracing_reader_cpumask);
+
+ mutex_unlock(&trace_types_lock);
+
free_cpumask_var(iter->started);
+ mutex_destroy(&iter->mutex);
+ kfree(iter->trace);
kfree(iter);
- atomic_dec(&tracing_reader);
return 0;
}
@@ -3167,67 +2789,57 @@ tracing_poll_pipe(struct file *filp, poll_table *poll_table)
}
}
-/*
- * Consumer reader.
- */
-static ssize_t
-tracing_read_pipe(struct file *filp, char __user *ubuf,
- size_t cnt, loff_t *ppos)
+
+void default_wait_pipe(struct trace_iterator *iter)
{
- struct trace_iterator *iter = filp->private_data;
- ssize_t sret;
+ DEFINE_WAIT(wait);
- /* return any leftover data */
- sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
- if (sret != -EBUSY)
- return sret;
+ prepare_to_wait(&trace_wait, &wait, TASK_INTERRUPTIBLE);
+
+ if (trace_empty(iter))
+ schedule();
- trace_seq_reset(&iter->seq);
+ finish_wait(&trace_wait, &wait);
+}
- mutex_lock(&trace_types_lock);
- if (iter->trace->read) {
- sret = iter->trace->read(iter, filp, ubuf, cnt, ppos);
- if (sret)
- goto out;
- }
+/*
+ * This is a make-shift waitqueue.
+ * A tracer might use this callback on some rare cases:
+ *
+ * 1) the current tracer might hold the runqueue lock when it wakes up
+ * a reader, hence a deadlock (sched, function, and function graph tracers)
+ * 2) the function tracers, trace all functions, we don't want
+ * the overhead of calling wake_up and friends
+ * (and tracing them too)
+ *
+ * Anyway, this is really very primitive wakeup.
+ */
+void poll_wait_pipe(struct trace_iterator *iter)
+{
+ set_current_state(TASK_INTERRUPTIBLE);
+ /* sleep for 100 msecs, and try again. */
+ schedule_timeout(HZ / 10);
+}
+
+/* Must be called with trace_types_lock mutex held. */
+static int tracing_wait_pipe(struct file *filp)
+{
+ struct trace_iterator *iter = filp->private_data;
-waitagain:
- sret = 0;
while (trace_empty(iter)) {
if ((filp->f_flags & O_NONBLOCK)) {
- sret = -EAGAIN;
- goto out;
+ return -EAGAIN;
}
- /*
- * This is a make-shift waitqueue. The reason we don't use
- * an actual wait queue is because:
- * 1) we only ever have one waiter
- * 2) the tracing, traces all functions, we don't want
- * the overhead of calling wake_up and friends
- * (and tracing them too)
- * Anyway, this is really very primitive wakeup.
- */
- set_current_state(TASK_INTERRUPTIBLE);
- iter->tr->waiter = current;
-
- mutex_unlock(&trace_types_lock);
-
- /* sleep for 100 msecs, and try again. */
- schedule_timeout(HZ/10);
-
- mutex_lock(&trace_types_lock);
+ mutex_unlock(&iter->mutex);
- iter->tr->waiter = NULL;
+ iter->trace->wait_pipe(iter);
- if (signal_pending(current)) {
- sret = -EINTR;
- goto out;
- }
+ mutex_lock(&iter->mutex);
- if (iter->trace != current_trace)
- goto out;
+ if (signal_pending(current))
+ return -EINTR;
/*
* We block until we read something and tracing is disabled.
@@ -3240,13 +2852,59 @@ waitagain:
*/
if (!tracer_enabled && iter->pos)
break;
+ }
+
+ return 1;
+}
+
+/*
+ * Consumer reader.
+ */
+static ssize_t
+tracing_read_pipe(struct file *filp, char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ struct trace_iterator *iter = filp->private_data;
+ static struct tracer *old_tracer;
+ ssize_t sret;
+
+ /* return any leftover data */
+ sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
+ if (sret != -EBUSY)
+ return sret;
+
+ trace_seq_init(&iter->seq);
+
+ /* copy the tracer to avoid using a global lock all around */
+ mutex_lock(&trace_types_lock);
+ if (unlikely(old_tracer != current_trace && current_trace)) {
+ old_tracer = current_trace;
+ *iter->trace = *current_trace;
+ }
+ mutex_unlock(&trace_types_lock);
- continue;
+ /*
+ * Avoid more than one consumer on a single file descriptor
+ * This is just a matter of traces coherency, the ring buffer itself
+ * is protected.
+ */
+ mutex_lock(&iter->mutex);
+ if (iter->trace->read) {
+ sret = iter->trace->read(iter, filp, ubuf, cnt, ppos);
+ if (sret)
+ goto out;
}
+waitagain:
+ sret = tracing_wait_pipe(filp);
+ if (sret <= 0)
+ goto out;
+
/* stop when tracing is finished */
- if (trace_empty(iter))
+ if (trace_empty(iter)) {
+ sret = 0;
goto out;
+ }
if (cnt >= PAGE_SIZE)
cnt = PAGE_SIZE - 1;
@@ -3267,8 +2925,8 @@ waitagain:
iter->seq.len = len;
break;
}
-
- trace_consume(iter);
+ if (ret != TRACE_TYPE_NO_CONSUME)
+ trace_consume(iter);
if (iter->seq.len >= cnt)
break;
@@ -3277,7 +2935,7 @@ waitagain:
/* 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);
+ trace_seq_init(&iter->seq);
/*
* If there was nothing to send to user, inspite of consuming trace
@@ -3287,20 +2945,165 @@ waitagain:
goto waitagain;
out:
- mutex_unlock(&trace_types_lock);
+ mutex_unlock(&iter->mutex);
return sret;
}
+static void tracing_pipe_buf_release(struct pipe_inode_info *pipe,
+ struct pipe_buffer *buf)
+{
+ __free_page(buf->page);
+}
+
+static void tracing_spd_release_pipe(struct splice_pipe_desc *spd,
+ unsigned int idx)
+{
+ __free_page(spd->pages[idx]);
+}
+
+static struct pipe_buf_operations tracing_pipe_buf_ops = {
+ .can_merge = 0,
+ .map = generic_pipe_buf_map,
+ .unmap = generic_pipe_buf_unmap,
+ .confirm = generic_pipe_buf_confirm,
+ .release = tracing_pipe_buf_release,
+ .steal = generic_pipe_buf_steal,
+ .get = generic_pipe_buf_get,
+};
+
+static size_t
+tracing_fill_pipe_page(size_t rem, struct trace_iterator *iter)
+{
+ size_t count;
+ int ret;
+
+ /* Seq buffer is page-sized, exactly what we need. */
+ for (;;) {
+ count = iter->seq.len;
+ ret = print_trace_line(iter);
+ count = iter->seq.len - count;
+ if (rem < count) {
+ rem = 0;
+ iter->seq.len -= count;
+ break;
+ }
+ if (ret == TRACE_TYPE_PARTIAL_LINE) {
+ iter->seq.len -= count;
+ break;
+ }
+
+ trace_consume(iter);
+ rem -= count;
+ if (!find_next_entry_inc(iter)) {
+ rem = 0;
+ iter->ent = NULL;
+ break;
+ }
+ }
+
+ return rem;
+}
+
+static ssize_t tracing_splice_read_pipe(struct file *filp,
+ loff_t *ppos,
+ struct pipe_inode_info *pipe,
+ size_t len,
+ unsigned int flags)
+{
+ struct page *pages[PIPE_BUFFERS];
+ struct partial_page partial[PIPE_BUFFERS];
+ struct trace_iterator *iter = filp->private_data;
+ struct splice_pipe_desc spd = {
+ .pages = pages,
+ .partial = partial,
+ .nr_pages = 0, /* This gets updated below. */
+ .flags = flags,
+ .ops = &tracing_pipe_buf_ops,
+ .spd_release = tracing_spd_release_pipe,
+ };
+ static struct tracer *old_tracer;
+ ssize_t ret;
+ size_t rem;
+ unsigned int i;
+
+ /* copy the tracer to avoid using a global lock all around */
+ mutex_lock(&trace_types_lock);
+ if (unlikely(old_tracer != current_trace && current_trace)) {
+ old_tracer = current_trace;
+ *iter->trace = *current_trace;
+ }
+ mutex_unlock(&trace_types_lock);
+
+ mutex_lock(&iter->mutex);
+
+ if (iter->trace->splice_read) {
+ ret = iter->trace->splice_read(iter, filp,
+ ppos, pipe, len, flags);
+ if (ret)
+ goto out_err;
+ }
+
+ ret = tracing_wait_pipe(filp);
+ if (ret <= 0)
+ goto out_err;
+
+ if (!iter->ent && !find_next_entry_inc(iter)) {
+ ret = -EFAULT;
+ goto out_err;
+ }
+
+ /* Fill as many pages as possible. */
+ for (i = 0, rem = len; i < PIPE_BUFFERS && rem; i++) {
+ pages[i] = alloc_page(GFP_KERNEL);
+ if (!pages[i])
+ break;
+
+ rem = tracing_fill_pipe_page(rem, iter);
+
+ /* Copy the data into the page, so we can start over. */
+ ret = trace_seq_to_buffer(&iter->seq,
+ page_address(pages[i]),
+ iter->seq.len);
+ if (ret < 0) {
+ __free_page(pages[i]);
+ break;
+ }
+ partial[i].offset = 0;
+ partial[i].len = iter->seq.len;
+
+ trace_seq_init(&iter->seq);
+ }
+
+ mutex_unlock(&iter->mutex);
+
+ spd.nr_pages = i;
+
+ return splice_to_pipe(pipe, &spd);
+
+out_err:
+ mutex_unlock(&iter->mutex);
+
+ return ret;
+}
+
static ssize_t
tracing_entries_read(struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos)
{
struct trace_array *tr = filp->private_data;
- char buf[64];
+ char buf[96];
int r;
- r = sprintf(buf, "%lu\n", tr->entries >> 10);
+ mutex_lock(&trace_types_lock);
+ if (!ring_buffer_expanded)
+ r = sprintf(buf, "%lu (expanded: %lu)\n",
+ tr->entries >> 10,
+ trace_buf_size >> 10);
+ else
+ r = sprintf(buf, "%lu\n", tr->entries >> 10);
+ mutex_unlock(&trace_types_lock);
+
return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
}
@@ -3344,28 +3147,11 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
val <<= 10;
if (val != global_trace.entries) {
- ret = ring_buffer_resize(global_trace.buffer, val);
- if (ret < 0) {
- cnt = ret;
- goto out;
- }
-
- ret = ring_buffer_resize(max_tr.buffer, val);
+ ret = tracing_resize_ring_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;
- }
goto out;
}
-
- global_trace.entries = val;
}
filp->f_pos += cnt;
@@ -3393,7 +3179,7 @@ static int mark_printk(const char *fmt, ...)
int ret;
va_list args;
va_start(args, fmt);
- ret = trace_vprintk(0, -1, fmt, args);
+ ret = trace_vprintk(0, fmt, args);
va_end(args);
return ret;
}
@@ -3433,42 +3219,294 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
return cnt;
}
-static struct file_operations tracing_max_lat_fops = {
+static const struct file_operations tracing_max_lat_fops = {
.open = tracing_open_generic,
.read = tracing_max_lat_read,
.write = tracing_max_lat_write,
};
-static struct file_operations tracing_ctrl_fops = {
+static const struct file_operations tracing_ctrl_fops = {
.open = tracing_open_generic,
.read = tracing_ctrl_read,
.write = tracing_ctrl_write,
};
-static struct file_operations set_tracer_fops = {
+static const struct file_operations set_tracer_fops = {
.open = tracing_open_generic,
.read = tracing_set_trace_read,
.write = tracing_set_trace_write,
};
-static struct file_operations tracing_pipe_fops = {
+static const struct file_operations tracing_pipe_fops = {
.open = tracing_open_pipe,
.poll = tracing_poll_pipe,
.read = tracing_read_pipe,
+ .splice_read = tracing_splice_read_pipe,
.release = tracing_release_pipe,
};
-static struct file_operations tracing_entries_fops = {
+static const struct file_operations tracing_entries_fops = {
.open = tracing_open_generic,
.read = tracing_entries_read,
.write = tracing_entries_write,
};
-static struct file_operations tracing_mark_fops = {
+static const struct file_operations tracing_mark_fops = {
.open = tracing_open_generic,
.write = tracing_mark_write,
};
+struct ftrace_buffer_info {
+ struct trace_array *tr;
+ void *spare;
+ int cpu;
+ unsigned int read;
+};
+
+static int tracing_buffers_open(struct inode *inode, struct file *filp)
+{
+ int cpu = (int)(long)inode->i_private;
+ struct ftrace_buffer_info *info;
+
+ if (tracing_disabled)
+ return -ENODEV;
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ info->tr = &global_trace;
+ info->cpu = cpu;
+ info->spare = NULL;
+ /* Force reading ring buffer for first read */
+ info->read = (unsigned int)-1;
+
+ filp->private_data = info;
+
+ return nonseekable_open(inode, filp);
+}
+
+static ssize_t
+tracing_buffers_read(struct file *filp, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct ftrace_buffer_info *info = filp->private_data;
+ unsigned int pos;
+ ssize_t ret;
+ size_t size;
+
+ if (!count)
+ return 0;
+
+ if (!info->spare)
+ info->spare = ring_buffer_alloc_read_page(info->tr->buffer);
+ if (!info->spare)
+ return -ENOMEM;
+
+ /* Do we have previous read data to read? */
+ if (info->read < PAGE_SIZE)
+ goto read;
+
+ info->read = 0;
+
+ ret = ring_buffer_read_page(info->tr->buffer,
+ &info->spare,
+ count,
+ info->cpu, 0);
+ if (ret < 0)
+ return 0;
+
+ pos = ring_buffer_page_len(info->spare);
+
+ if (pos < PAGE_SIZE)
+ memset(info->spare + pos, 0, PAGE_SIZE - pos);
+
+read:
+ size = PAGE_SIZE - info->read;
+ if (size > count)
+ size = count;
+
+ ret = copy_to_user(ubuf, info->spare + info->read, size);
+ if (ret == size)
+ return -EFAULT;
+ size -= ret;
+
+ *ppos += size;
+ info->read += size;
+
+ return size;
+}
+
+static int tracing_buffers_release(struct inode *inode, struct file *file)
+{
+ struct ftrace_buffer_info *info = file->private_data;
+
+ if (info->spare)
+ ring_buffer_free_read_page(info->tr->buffer, info->spare);
+ kfree(info);
+
+ return 0;
+}
+
+struct buffer_ref {
+ struct ring_buffer *buffer;
+ void *page;
+ int ref;
+};
+
+static void buffer_pipe_buf_release(struct pipe_inode_info *pipe,
+ struct pipe_buffer *buf)
+{
+ struct buffer_ref *ref = (struct buffer_ref *)buf->private;
+
+ if (--ref->ref)
+ return;
+
+ ring_buffer_free_read_page(ref->buffer, ref->page);
+ kfree(ref);
+ buf->private = 0;
+}
+
+static int buffer_pipe_buf_steal(struct pipe_inode_info *pipe,
+ struct pipe_buffer *buf)
+{
+ return 1;
+}
+
+static void buffer_pipe_buf_get(struct pipe_inode_info *pipe,
+ struct pipe_buffer *buf)
+{
+ struct buffer_ref *ref = (struct buffer_ref *)buf->private;
+
+ ref->ref++;
+}
+
+/* Pipe buffer operations for a buffer. */
+static struct pipe_buf_operations buffer_pipe_buf_ops = {
+ .can_merge = 0,
+ .map = generic_pipe_buf_map,
+ .unmap = generic_pipe_buf_unmap,
+ .confirm = generic_pipe_buf_confirm,
+ .release = buffer_pipe_buf_release,
+ .steal = buffer_pipe_buf_steal,
+ .get = buffer_pipe_buf_get,
+};
+
+/*
+ * Callback from splice_to_pipe(), if we need to release some pages
+ * at the end of the spd in case we error'ed out in filling the pipe.
+ */
+static void buffer_spd_release(struct splice_pipe_desc *spd, unsigned int i)
+{
+ struct buffer_ref *ref =
+ (struct buffer_ref *)spd->partial[i].private;
+
+ if (--ref->ref)
+ return;
+
+ ring_buffer_free_read_page(ref->buffer, ref->page);
+ kfree(ref);
+ spd->partial[i].private = 0;
+}
+
+static ssize_t
+tracing_buffers_splice_read(struct file *file, loff_t *ppos,
+ struct pipe_inode_info *pipe, size_t len,
+ unsigned int flags)
+{
+ struct ftrace_buffer_info *info = file->private_data;
+ struct partial_page partial[PIPE_BUFFERS];
+ struct page *pages[PIPE_BUFFERS];
+ struct splice_pipe_desc spd = {
+ .pages = pages,
+ .partial = partial,
+ .flags = flags,
+ .ops = &buffer_pipe_buf_ops,
+ .spd_release = buffer_spd_release,
+ };
+ struct buffer_ref *ref;
+ int size, i;
+ size_t ret;
+
+ if (*ppos & (PAGE_SIZE - 1)) {
+ WARN_ONCE(1, "Ftrace: previous read must page-align\n");
+ return -EINVAL;
+ }
+
+ if (len & (PAGE_SIZE - 1)) {
+ WARN_ONCE(1, "Ftrace: splice_read should page-align\n");
+ if (len < PAGE_SIZE)
+ return -EINVAL;
+ len &= PAGE_MASK;
+ }
+
+ for (i = 0; i < PIPE_BUFFERS && len; i++, len -= PAGE_SIZE) {
+ struct page *page;
+ int r;
+
+ ref = kzalloc(sizeof(*ref), GFP_KERNEL);
+ if (!ref)
+ break;
+
+ ref->buffer = info->tr->buffer;
+ ref->page = ring_buffer_alloc_read_page(ref->buffer);
+ if (!ref->page) {
+ kfree(ref);
+ break;
+ }
+
+ r = ring_buffer_read_page(ref->buffer, &ref->page,
+ len, info->cpu, 0);
+ if (r < 0) {
+ ring_buffer_free_read_page(ref->buffer,
+ ref->page);
+ kfree(ref);
+ break;
+ }
+
+ /*
+ * zero out any left over data, this is going to
+ * user land.
+ */
+ size = ring_buffer_page_len(ref->page);
+ if (size < PAGE_SIZE)
+ memset(ref->page + size, 0, PAGE_SIZE - size);
+
+ page = virt_to_page(ref->page);
+
+ spd.pages[i] = page;
+ spd.partial[i].len = PAGE_SIZE;
+ spd.partial[i].offset = 0;
+ spd.partial[i].private = (unsigned long)ref;
+ spd.nr_pages++;
+ *ppos += PAGE_SIZE;
+ }
+
+ spd.nr_pages = i;
+
+ /* did we read anything? */
+ if (!spd.nr_pages) {
+ if (flags & SPLICE_F_NONBLOCK)
+ ret = -EAGAIN;
+ else
+ ret = 0;
+ /* TODO: block */
+ return ret;
+ }
+
+ ret = splice_to_pipe(pipe, &spd);
+
+ return ret;
+}
+
+static const struct file_operations tracing_buffers_fops = {
+ .open = tracing_buffers_open,
+ .read = tracing_buffers_read,
+ .release = tracing_buffers_release,
+ .splice_read = tracing_buffers_splice_read,
+ .llseek = no_llseek,
+};
+
#ifdef CONFIG_DYNAMIC_FTRACE
int __weak ftrace_arch_read_dyn_info(char *buf, int size)
@@ -3500,7 +3538,7 @@ tracing_read_dyn_info(struct file *filp, char __user *ubuf,
return r;
}
-static struct file_operations tracing_dyn_info_fops = {
+static const struct file_operations tracing_dyn_info_fops = {
.open = tracing_open_generic,
.read = tracing_read_dyn_info,
};
@@ -3515,6 +3553,9 @@ struct dentry *tracing_init_dentry(void)
if (d_tracer)
return d_tracer;
+ if (!debugfs_initialized())
+ return NULL;
+
d_tracer = debugfs_create_dir("tracing", NULL);
if (!d_tracer && !once) {
@@ -3526,15 +3567,350 @@ struct dentry *tracing_init_dentry(void)
return d_tracer;
}
+static struct dentry *d_percpu;
+
+struct dentry *tracing_dentry_percpu(void)
+{
+ static int once;
+ struct dentry *d_tracer;
+
+ if (d_percpu)
+ return d_percpu;
+
+ d_tracer = tracing_init_dentry();
+
+ if (!d_tracer)
+ return NULL;
+
+ d_percpu = debugfs_create_dir("per_cpu", d_tracer);
+
+ if (!d_percpu && !once) {
+ once = 1;
+ pr_warning("Could not create debugfs directory 'per_cpu'\n");
+ return NULL;
+ }
+
+ return d_percpu;
+}
+
+static void tracing_init_debugfs_percpu(long cpu)
+{
+ struct dentry *d_percpu = tracing_dentry_percpu();
+ struct dentry *entry, *d_cpu;
+ /* strlen(cpu) + MAX(log10(cpu)) + '\0' */
+ char cpu_dir[7];
+
+ if (cpu > 999 || cpu < 0)
+ return;
+
+ sprintf(cpu_dir, "cpu%ld", cpu);
+ d_cpu = debugfs_create_dir(cpu_dir, d_percpu);
+ if (!d_cpu) {
+ pr_warning("Could not create debugfs '%s' entry\n", cpu_dir);
+ return;
+ }
+
+ /* per cpu trace_pipe */
+ entry = debugfs_create_file("trace_pipe", 0444, d_cpu,
+ (void *) cpu, &tracing_pipe_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs 'trace_pipe' entry\n");
+
+ /* per cpu trace */
+ entry = debugfs_create_file("trace", 0644, d_cpu,
+ (void *) cpu, &tracing_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs 'trace' entry\n");
+
+ entry = debugfs_create_file("trace_pipe_raw", 0444, d_cpu,
+ (void *) cpu, &tracing_buffers_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs 'trace_pipe_raw' entry\n");
+}
+
#ifdef CONFIG_FTRACE_SELFTEST
/* Let selftest have access to static functions in this file */
#include "trace_selftest.c"
#endif
+struct trace_option_dentry {
+ struct tracer_opt *opt;
+ struct tracer_flags *flags;
+ struct dentry *entry;
+};
+
+static ssize_t
+trace_options_read(struct file *filp, char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ struct trace_option_dentry *topt = filp->private_data;
+ char *buf;
+
+ if (topt->flags->val & topt->opt->bit)
+ buf = "1\n";
+ else
+ buf = "0\n";
+
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2);
+}
+
+static ssize_t
+trace_options_write(struct file *filp, const char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ struct trace_option_dentry *topt = filp->private_data;
+ unsigned long val;
+ char buf[64];
+ int ret;
+
+ if (cnt >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ return -EFAULT;
+
+ buf[cnt] = 0;
+
+ ret = strict_strtoul(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ ret = 0;
+ switch (val) {
+ case 0:
+ /* do nothing if already cleared */
+ if (!(topt->flags->val & topt->opt->bit))
+ break;
+
+ mutex_lock(&trace_types_lock);
+ if (current_trace->set_flag)
+ ret = current_trace->set_flag(topt->flags->val,
+ topt->opt->bit, 0);
+ mutex_unlock(&trace_types_lock);
+ if (ret)
+ return ret;
+ topt->flags->val &= ~topt->opt->bit;
+ break;
+ case 1:
+ /* do nothing if already set */
+ if (topt->flags->val & topt->opt->bit)
+ break;
+
+ mutex_lock(&trace_types_lock);
+ if (current_trace->set_flag)
+ ret = current_trace->set_flag(topt->flags->val,
+ topt->opt->bit, 1);
+ mutex_unlock(&trace_types_lock);
+ if (ret)
+ return ret;
+ topt->flags->val |= topt->opt->bit;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ *ppos += cnt;
+
+ return cnt;
+}
+
+
+static const struct file_operations trace_options_fops = {
+ .open = tracing_open_generic,
+ .read = trace_options_read,
+ .write = trace_options_write,
+};
+
+static ssize_t
+trace_options_core_read(struct file *filp, char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ long index = (long)filp->private_data;
+ char *buf;
+
+ if (trace_flags & (1 << index))
+ buf = "1\n";
+ else
+ buf = "0\n";
+
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2);
+}
+
+static ssize_t
+trace_options_core_write(struct file *filp, const char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ long index = (long)filp->private_data;
+ char buf[64];
+ unsigned long val;
+ int ret;
+
+ if (cnt >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ return -EFAULT;
+
+ buf[cnt] = 0;
+
+ ret = strict_strtoul(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ switch (val) {
+ case 0:
+ trace_flags &= ~(1 << index);
+ break;
+ case 1:
+ trace_flags |= 1 << index;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ *ppos += cnt;
+
+ return cnt;
+}
+
+static const struct file_operations trace_options_core_fops = {
+ .open = tracing_open_generic,
+ .read = trace_options_core_read,
+ .write = trace_options_core_write,
+};
+
+static struct dentry *trace_options_init_dentry(void)
+{
+ struct dentry *d_tracer;
+ static struct dentry *t_options;
+
+ if (t_options)
+ return t_options;
+
+ d_tracer = tracing_init_dentry();
+ if (!d_tracer)
+ return NULL;
+
+ t_options = debugfs_create_dir("options", d_tracer);
+ if (!t_options) {
+ pr_warning("Could not create debugfs directory 'options'\n");
+ return NULL;
+ }
+
+ return t_options;
+}
+
+static void
+create_trace_option_file(struct trace_option_dentry *topt,
+ struct tracer_flags *flags,
+ struct tracer_opt *opt)
+{
+ struct dentry *t_options;
+ struct dentry *entry;
+
+ t_options = trace_options_init_dentry();
+ if (!t_options)
+ return;
+
+ topt->flags = flags;
+ topt->opt = opt;
+
+ entry = debugfs_create_file(opt->name, 0644, t_options, topt,
+ &trace_options_fops);
+
+ topt->entry = entry;
+
+}
+
+static struct trace_option_dentry *
+create_trace_option_files(struct tracer *tracer)
+{
+ struct trace_option_dentry *topts;
+ struct tracer_flags *flags;
+ struct tracer_opt *opts;
+ int cnt;
+
+ if (!tracer)
+ return NULL;
+
+ flags = tracer->flags;
+
+ if (!flags || !flags->opts)
+ return NULL;
+
+ opts = flags->opts;
+
+ for (cnt = 0; opts[cnt].name; cnt++)
+ ;
+
+ topts = kcalloc(cnt + 1, sizeof(*topts), GFP_KERNEL);
+ if (!topts)
+ return NULL;
+
+ for (cnt = 0; opts[cnt].name; cnt++)
+ create_trace_option_file(&topts[cnt], flags,
+ &opts[cnt]);
+
+ return topts;
+}
+
+static void
+destroy_trace_option_files(struct trace_option_dentry *topts)
+{
+ int cnt;
+
+ if (!topts)
+ return;
+
+ for (cnt = 0; topts[cnt].opt; cnt++) {
+ if (topts[cnt].entry)
+ debugfs_remove(topts[cnt].entry);
+ }
+
+ kfree(topts);
+}
+
+static struct dentry *
+create_trace_option_core_file(const char *option, long index)
+{
+ struct dentry *t_options;
+ struct dentry *entry;
+
+ t_options = trace_options_init_dentry();
+ if (!t_options)
+ return NULL;
+
+ entry = debugfs_create_file(option, 0644, t_options, (void *)index,
+ &trace_options_core_fops);
+
+ return entry;
+}
+
+static __init void create_trace_options_dir(void)
+{
+ struct dentry *t_options;
+ struct dentry *entry;
+ int i;
+
+ t_options = trace_options_init_dentry();
+ if (!t_options)
+ return;
+
+ for (i = 0; trace_options[i]; i++) {
+ entry = create_trace_option_core_file(trace_options[i], i);
+ if (!entry)
+ pr_warning("Could not create debugfs %s entry\n",
+ trace_options[i]);
+ }
+}
+
static __init int tracer_init_debugfs(void)
{
struct dentry *d_tracer;
struct dentry *entry;
+ int cpu;
d_tracer = tracing_init_dentry();
@@ -3548,18 +3924,15 @@ static __init int tracer_init_debugfs(void)
if (!entry)
pr_warning("Could not create debugfs 'trace_options' entry\n");
+ create_trace_options_dir();
+
entry = debugfs_create_file("tracing_cpumask", 0644, d_tracer,
NULL, &tracing_cpumask_fops);
if (!entry)
pr_warning("Could not create debugfs 'tracing_cpumask' entry\n");
- entry = debugfs_create_file("latency_trace", 0444, d_tracer,
- &global_trace, &tracing_lt_fops);
- if (!entry)
- pr_warning("Could not create debugfs 'latency_trace' entry\n");
-
- entry = debugfs_create_file("trace", 0444, d_tracer,
- &global_trace, &tracing_fops);
+ entry = debugfs_create_file("trace", 0644, d_tracer,
+ (void *) TRACE_PIPE_ALL_CPU, &tracing_fops);
if (!entry)
pr_warning("Could not create debugfs 'trace' entry\n");
@@ -3590,8 +3963,8 @@ static __init int tracer_init_debugfs(void)
if (!entry)
pr_warning("Could not create debugfs 'README' entry\n");
- entry = debugfs_create_file("trace_pipe", 0644, d_tracer,
- NULL, &tracing_pipe_fops);
+ entry = debugfs_create_file("trace_pipe", 0444, d_tracer,
+ (void *) TRACE_PIPE_ALL_CPU, &tracing_pipe_fops);
if (!entry)
pr_warning("Could not create debugfs "
"'trace_pipe' entry\n");
@@ -3619,77 +3992,12 @@ static __init int tracer_init_debugfs(void)
#ifdef CONFIG_SYSPROF_TRACER
init_tracer_sysprof_debugfs(d_tracer);
#endif
- return 0;
-}
-
-int trace_vprintk(unsigned long ip, int depth, 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;
- int cpu, len = 0, size, pc;
- struct print_entry *entry;
- unsigned long irq_flags;
-
- if (tracing_disabled || tracing_selftest_running)
- return 0;
-
- pc = preempt_count();
- preempt_disable_notrace();
- cpu = raw_smp_processor_id();
- data = tr->data[cpu];
-
- if (unlikely(atomic_read(&data->disabled)))
- goto out;
-
- pause_graph_tracing();
- spin_lock_irqsave(&trace_buf_lock, irq_flags);
- len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args);
-
- len = min(len, TRACE_BUF_SIZE-1);
- trace_buf[len] = 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, irq_flags, pc);
- entry->ent.type = TRACE_PRINT;
- entry->ip = ip;
- entry->depth = depth;
-
- 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, irq_flags);
- unpause_graph_tracing();
- out:
- preempt_enable_notrace();
-
- return len;
-}
-EXPORT_SYMBOL_GPL(trace_vprintk);
-int __ftrace_printk(unsigned long ip, const char *fmt, ...)
-{
- int ret;
- va_list ap;
-
- if (!(trace_flags & TRACE_ITER_PRINTK))
- return 0;
+ for_each_tracing_cpu(cpu)
+ tracing_init_debugfs_percpu(cpu);
- va_start(ap, fmt);
- ret = trace_vprintk(ip, task_curr_ret_stack(current), fmt, ap);
- va_end(ap);
- return ret;
+ return 0;
}
-EXPORT_SYMBOL_GPL(__ftrace_printk);
static int trace_panic_handler(struct notifier_block *this,
unsigned long event, void *unused)
@@ -3750,14 +4058,15 @@ trace_printk_seq(struct trace_seq *s)
printk(KERN_TRACE "%s", s->buffer);
- trace_seq_reset(s);
+ trace_seq_init(s);
}
-void ftrace_dump(void)
+static void __ftrace_dump(bool disable_tracing)
{
static DEFINE_SPINLOCK(ftrace_dump_lock);
/* use static because iter can be a bit big for the stack */
static struct trace_iterator iter;
+ unsigned int old_userobj;
static int dump_ran;
unsigned long flags;
int cnt = 0, cpu;
@@ -3769,21 +4078,26 @@ void ftrace_dump(void)
dump_ran = 1;
- /* No turning back! */
tracing_off();
- ftrace_kill();
+
+ if (disable_tracing)
+ ftrace_kill();
for_each_tracing_cpu(cpu) {
atomic_inc(&global_trace.data[cpu]->disabled);
}
+ old_userobj = trace_flags & TRACE_ITER_SYM_USEROBJ;
+
/* don't look at user memory in panic mode */
trace_flags &= ~TRACE_ITER_SYM_USEROBJ;
printk(KERN_TRACE "Dumping ftrace buffer:\n");
+ /* Simulate the iterator */
iter.tr = &global_trace;
iter.trace = current_trace;
+ iter.cpu_file = TRACE_PIPE_ALL_CPU;
/*
* We need to stop all tracing on all CPUS to read the
@@ -3819,13 +4133,30 @@ void ftrace_dump(void)
else
printk(KERN_TRACE "---------------------------------\n");
+ /* Re-enable tracing if requested */
+ if (!disable_tracing) {
+ trace_flags |= old_userobj;
+
+ for_each_tracing_cpu(cpu) {
+ atomic_dec(&global_trace.data[cpu]->disabled);
+ }
+ tracing_on();
+ }
+
out:
spin_unlock_irqrestore(&ftrace_dump_lock, flags);
}
+/* By default: disable tracing after the dump */
+void ftrace_dump(void)
+{
+ __ftrace_dump(true);
+}
+
__init static int tracer_alloc_buffers(void)
{
struct trace_array_cpu *data;
+ int ring_buf_size;
int i;
int ret = -ENOMEM;
@@ -3835,11 +4166,21 @@ __init static int tracer_alloc_buffers(void)
if (!alloc_cpumask_var(&tracing_cpumask, GFP_KERNEL))
goto out_free_buffer_mask;
+ if (!alloc_cpumask_var(&tracing_reader_cpumask, GFP_KERNEL))
+ goto out_free_tracing_cpumask;
+
+ /* To save memory, keep the ring buffer size to its minimum */
+ if (ring_buffer_expanded)
+ ring_buf_size = trace_buf_size;
+ else
+ ring_buf_size = 1;
+
cpumask_copy(tracing_buffer_mask, cpu_possible_mask);
cpumask_copy(tracing_cpumask, cpu_all_mask);
+ cpumask_clear(tracing_reader_cpumask);
/* TODO: make the number of buffers hot pluggable with CPUS */
- global_trace.buffer = ring_buffer_alloc(trace_buf_size,
+ global_trace.buffer = ring_buffer_alloc(ring_buf_size,
TRACE_BUFFER_FLAGS);
if (!global_trace.buffer) {
printk(KERN_ERR "tracer: failed to allocate ring buffer!\n");
@@ -3850,7 +4191,7 @@ __init static int tracer_alloc_buffers(void)
#ifdef CONFIG_TRACER_MAX_TRACE
- max_tr.buffer = ring_buffer_alloc(trace_buf_size,
+ max_tr.buffer = ring_buffer_alloc(ring_buf_size,
TRACE_BUFFER_FLAGS);
if (!max_tr.buffer) {
printk(KERN_ERR "tracer: failed to allocate max ring buffer!\n");
@@ -3871,14 +4212,10 @@ __init static int tracer_alloc_buffers(void)
trace_init_cmdlines();
register_tracer(&nop_trace);
+ current_trace = &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 */
tracing_disabled = 0;
@@ -3886,14 +4223,38 @@ __init static int tracer_alloc_buffers(void)
&trace_panic_notifier);
register_die_notifier(&trace_die_notifier);
- ret = 0;
+
+ return 0;
out_free_cpumask:
+ free_cpumask_var(tracing_reader_cpumask);
+out_free_tracing_cpumask:
free_cpumask_var(tracing_cpumask);
out_free_buffer_mask:
free_cpumask_var(tracing_buffer_mask);
out:
return ret;
}
+
+__init static int clear_boot_tracer(void)
+{
+ /*
+ * The default tracer at boot buffer is an init section.
+ * This function is called in lateinit. If we did not
+ * find the boot tracer, then clear it out, to prevent
+ * later registration from accessing the buffer that is
+ * about to be freed.
+ */
+ if (!default_bootup_tracer)
+ return 0;
+
+ printk(KERN_INFO "ftrace bootup tracer '%s' not registered.\n",
+ default_bootup_tracer);
+ default_bootup_tracer = NULL;
+
+ return 0;
+}
+
early_initcall(tracer_alloc_buffers);
fs_initcall(tracer_init_debugfs);
+late_initcall(clear_boot_tracer);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 4d3d381bfd9..e685ac2b2ba 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -9,6 +9,8 @@
#include <linux/mmiotrace.h>
#include <linux/ftrace.h>
#include <trace/boot.h>
+#include <trace/kmemtrace.h>
+#include <trace/power.h>
enum trace_type {
__TRACE_FIRST_TYPE = 0,
@@ -16,9 +18,9 @@ enum trace_type {
TRACE_FN,
TRACE_CTX,
TRACE_WAKE,
- TRACE_CONT,
TRACE_STACK,
TRACE_PRINT,
+ TRACE_BPRINT,
TRACE_SPECIAL,
TRACE_MMIO_RW,
TRACE_MMIO_MAP,
@@ -29,9 +31,14 @@ enum trace_type {
TRACE_GRAPH_ENT,
TRACE_USER_STACK,
TRACE_HW_BRANCHES,
+ TRACE_SYSCALL_ENTER,
+ TRACE_SYSCALL_EXIT,
+ TRACE_KMEM_ALLOC,
+ TRACE_KMEM_FREE,
TRACE_POWER,
+ TRACE_BLK,
- __TRACE_LAST_TYPE
+ __TRACE_LAST_TYPE,
};
/*
@@ -42,7 +49,6 @@ enum trace_type {
*/
struct trace_entry {
unsigned char type;
- unsigned char cpu;
unsigned char flags;
unsigned char preempt_count;
int pid;
@@ -60,13 +66,13 @@ struct ftrace_entry {
/* Function call entry */
struct ftrace_graph_ent_entry {
- struct trace_entry ent;
+ struct trace_entry ent;
struct ftrace_graph_ent graph_ent;
};
/* Function return entry */
struct ftrace_graph_ret_entry {
- struct trace_entry ent;
+ struct trace_entry ent;
struct ftrace_graph_ret ret;
};
extern struct tracer boot_tracer;
@@ -112,12 +118,18 @@ struct userstack_entry {
};
/*
- * ftrace_printk entry:
+ * trace_printk entry:
*/
+struct bprint_entry {
+ struct trace_entry ent;
+ unsigned long ip;
+ const char *fmt;
+ u32 buf[];
+};
+
struct print_entry {
struct trace_entry ent;
unsigned long ip;
- int depth;
char buf[];
};
@@ -170,15 +182,51 @@ struct trace_power {
struct power_trace state_data;
};
+enum kmemtrace_type_id {
+ KMEMTRACE_TYPE_KMALLOC = 0, /* kmalloc() or kfree(). */
+ KMEMTRACE_TYPE_CACHE, /* kmem_cache_*(). */
+ KMEMTRACE_TYPE_PAGES, /* __get_free_pages() and friends. */
+};
+
+struct kmemtrace_alloc_entry {
+ struct trace_entry ent;
+ enum kmemtrace_type_id type_id;
+ unsigned long call_site;
+ const void *ptr;
+ size_t bytes_req;
+ size_t bytes_alloc;
+ gfp_t gfp_flags;
+ int node;
+};
+
+struct kmemtrace_free_entry {
+ struct trace_entry ent;
+ enum kmemtrace_type_id type_id;
+ unsigned long call_site;
+ const void *ptr;
+};
+
+struct syscall_trace_enter {
+ struct trace_entry ent;
+ int nr;
+ unsigned long args[];
+};
+
+struct syscall_trace_exit {
+ struct trace_entry ent;
+ int nr;
+ unsigned long ret;
+};
+
+
/*
* trace_flag_type is an enumeration that holds different
* states when a trace occurs. These are:
* IRQS_OFF - interrupts were disabled
- * IRQS_NOSUPPORT - arch does not support irqs_disabled_flags
+ * IRQS_NOSUPPORT - arch does not support irqs_disabled_flags
* 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,
@@ -186,7 +234,6 @@ enum trace_flag_type {
TRACE_FLAG_NEED_RESCHED = 0x04,
TRACE_FLAG_HARDIRQ = 0x08,
TRACE_FLAG_SOFTIRQ = 0x10,
- TRACE_FLAG_CONT = 0x20,
};
#define TRACE_BUF_SIZE 1024
@@ -198,6 +245,7 @@ enum trace_flag_type {
*/
struct trace_array_cpu {
atomic_t disabled;
+ void *buffer_page; /* ring buffer spare */
/* these fields get copied into max-trace: */
unsigned long trace_idx;
@@ -262,10 +310,10 @@ extern void __ftrace_bad_type(void);
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 userstack_entry, TRACE_USER_STACK);\
IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \
+ IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT); \
IF_ASSIGN(var, ent, struct special_entry, 0); \
IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \
TRACE_MMIO_RW); \
@@ -279,7 +327,15 @@ extern void __ftrace_bad_type(void);
IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry, \
TRACE_GRAPH_RET); \
IF_ASSIGN(var, ent, struct hw_branch_entry, TRACE_HW_BRANCHES);\
- IF_ASSIGN(var, ent, struct trace_power, TRACE_POWER); \
+ IF_ASSIGN(var, ent, struct trace_power, TRACE_POWER); \
+ IF_ASSIGN(var, ent, struct kmemtrace_alloc_entry, \
+ TRACE_KMEM_ALLOC); \
+ IF_ASSIGN(var, ent, struct kmemtrace_free_entry, \
+ TRACE_KMEM_FREE); \
+ IF_ASSIGN(var, ent, struct syscall_trace_enter, \
+ TRACE_SYSCALL_ENTER); \
+ IF_ASSIGN(var, ent, struct syscall_trace_exit, \
+ TRACE_SYSCALL_EXIT); \
__ftrace_bad_type(); \
} while (0)
@@ -287,7 +343,8 @@ extern void __ftrace_bad_type(void);
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 */
+ TRACE_TYPE_UNHANDLED = 2, /* Relay to other output functions */
+ TRACE_TYPE_NO_CONSUME = 3 /* Handled but ask to not consume */
};
@@ -297,8 +354,8 @@ enum print_line_t {
* flags value in struct tracer_flags.
*/
struct tracer_opt {
- const char *name; /* Will appear on the trace_options file */
- u32 bit; /* Mask assigned in val field in tracer_flags */
+ const char *name; /* Will appear on the trace_options file */
+ u32 bit; /* Mask assigned in val field in tracer_flags */
};
/*
@@ -307,28 +364,51 @@ struct tracer_opt {
*/
struct tracer_flags {
u32 val;
- struct tracer_opt *opts;
+ struct tracer_opt *opts;
};
/* Makes more easy to define a tracer opt */
#define TRACER_OPT(s, b) .name = #s, .bit = b
-/*
- * A specific tracer, represented by methods that operate on a trace array:
+
+/**
+ * struct tracer - a specific tracer and its callbacks to interact with debugfs
+ * @name: the name chosen to select it on the available_tracers file
+ * @init: called when one switches to this tracer (echo name > current_tracer)
+ * @reset: called when one switches to another tracer
+ * @start: called when tracing is unpaused (echo 1 > tracing_enabled)
+ * @stop: called when tracing is paused (echo 0 > tracing_enabled)
+ * @open: called when the trace file is opened
+ * @pipe_open: called when the trace_pipe file is opened
+ * @wait_pipe: override how the user waits for traces on trace_pipe
+ * @close: called when the trace file is released
+ * @read: override the default read callback on trace_pipe
+ * @splice_read: override the default splice_read callback on trace_pipe
+ * @selftest: selftest to run on boot (see trace_selftest.c)
+ * @print_headers: override the first lines that describe your columns
+ * @print_line: callback that prints a trace
+ * @set_flag: signals one of your private flags changed (trace_options file)
+ * @flags: your private flags
*/
struct tracer {
const char *name;
- /* Your tracer should raise a warning if init fails */
int (*init)(struct trace_array *tr);
void (*reset)(struct trace_array *tr);
void (*start)(struct trace_array *tr);
void (*stop)(struct trace_array *tr);
void (*open)(struct trace_iterator *iter);
void (*pipe_open)(struct trace_iterator *iter);
+ void (*wait_pipe)(struct trace_iterator *iter);
void (*close)(struct trace_iterator *iter);
ssize_t (*read)(struct trace_iterator *iter,
struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos);
+ ssize_t (*splice_read)(struct trace_iterator *iter,
+ struct file *filp,
+ loff_t *ppos,
+ struct pipe_inode_info *pipe,
+ size_t len,
+ unsigned int flags);
#ifdef CONFIG_FTRACE_STARTUP_TEST
int (*selftest)(struct tracer *trace,
struct trace_array *tr);
@@ -339,7 +419,8 @@ struct tracer {
int (*set_flag)(u32 old_flags, u32 bit, int set);
struct tracer *next;
int print_max;
- struct tracer_flags *flags;
+ struct tracer_flags *flags;
+ struct tracer_stat *stats;
};
struct trace_seq {
@@ -348,6 +429,16 @@ struct trace_seq {
unsigned int readpos;
};
+static inline void
+trace_seq_init(struct trace_seq *s)
+{
+ s->len = 0;
+ s->readpos = 0;
+}
+
+
+#define TRACE_PIPE_ALL_CPU -1
+
/*
* Trace iterator - used by printout routines who present trace
* results to users and which routines might sleep, etc:
@@ -356,6 +447,8 @@ struct trace_iterator {
struct trace_array *tr;
struct tracer *trace;
void *private;
+ int cpu_file;
+ struct mutex mutex;
struct ring_buffer_iter *buffer_iter[NR_CPUS];
/* The below is zeroed out in pipe_read */
@@ -371,6 +464,7 @@ struct trace_iterator {
cpumask_var_t started;
};
+int tracer_init(struct tracer *t, struct trace_array *tr);
int tracing_is_enabled(void);
void trace_wake_up(void);
void tracing_reset(struct trace_array *tr, int cpu);
@@ -379,26 +473,50 @@ 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 ring_buffer_event;
+
+struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr,
+ unsigned char type,
+ unsigned long len,
+ unsigned long flags,
+ int pc);
+void trace_buffer_unlock_commit(struct trace_array *tr,
+ struct ring_buffer_event *event,
+ unsigned long flags, int pc);
+
+struct ring_buffer_event *
+trace_current_buffer_lock_reserve(unsigned char type, unsigned long len,
+ unsigned long flags, int pc);
+void trace_current_buffer_unlock_commit(struct ring_buffer_event *event,
+ unsigned long flags, int pc);
+void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event,
+ unsigned long flags, int pc);
+
struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
struct trace_array_cpu *data);
+
+struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
+ int *ent_cpu, u64 *ent_ts);
+
void tracing_generic_entry_update(struct trace_entry *entry,
unsigned long flags,
int pc);
+void default_wait_pipe(struct trace_iterator *iter);
+void poll_wait_pipe(struct trace_iterator *iter);
+
void ftrace(struct trace_array *tr,
struct trace_array_cpu *data,
unsigned long ip,
unsigned long parent_ip,
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, 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, int pc);
@@ -408,14 +526,12 @@ void trace_special(struct trace_array *tr,
unsigned long arg2,
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, int pc);
void trace_graph_return(struct ftrace_graph_ret *trace);
int trace_graph_entry(struct ftrace_graph_ent *trace);
-void trace_hw_branch(struct trace_array *tr, u64 from, u64 to);
void tracing_start_cmdline_record(void);
void tracing_stop_cmdline_record(void);
@@ -434,15 +550,11 @@ void 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);
-extern cycle_t ftrace_now(int cpu);
+void __trace_stack(struct trace_array *tr,
+ unsigned long flags,
+ int skip, int pc);
-#ifdef CONFIG_FUNCTION_TRACER
-void tracing_start_function_trace(void);
-void tracing_stop_function_trace(void);
-#else
-# define tracing_start_function_trace() do { } while (0)
-# define tracing_stop_function_trace() do { } while (0)
-#endif
+extern cycle_t ftrace_now(int cpu);
#ifdef CONFIG_CONTEXT_SWITCH_TRACER
typedef void
@@ -456,10 +568,10 @@ struct tracer_switch_ops {
void *private;
struct tracer_switch_ops *next;
};
-
-char *trace_find_cmdline(int pid);
#endif /* CONFIG_CONTEXT_SWITCH_TRACER */
+extern void trace_find_cmdline(int pid, char comm[]);
+
#ifdef CONFIG_DYNAMIC_FTRACE
extern unsigned long ftrace_update_tot_cnt;
#define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func
@@ -469,6 +581,8 @@ extern int DYN_FTRACE_TEST_NAME(void);
#ifdef CONFIG_FTRACE_STARTUP_TEST
extern int trace_selftest_startup_function(struct tracer *trace,
struct trace_array *tr);
+extern int trace_selftest_startup_function_graph(struct tracer *trace,
+ struct trace_array *tr);
extern int trace_selftest_startup_irqsoff(struct tracer *trace,
struct trace_array *tr);
extern int trace_selftest_startup_preemptoff(struct tracer *trace,
@@ -488,18 +602,11 @@ extern int trace_selftest_startup_branch(struct tracer *trace,
#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 unsigned long long ns2usecs(cycle_t nsec);
extern int
-seq_print_ip_sym(struct trace_seq *s, unsigned long ip,
- unsigned long sym_flags);
-extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
- size_t cnt);
-extern long ns2usecs(cycle_t nsec);
+trace_vbprintk(unsigned long ip, const char *fmt, va_list args);
extern int
-trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args);
+trace_vprintk(unsigned long ip, const char *fmt, va_list args);
extern unsigned long trace_flags;
@@ -580,7 +687,11 @@ enum trace_iterator_flags {
TRACE_ITER_ANNOTATE = 0x2000,
TRACE_ITER_USERSTACKTRACE = 0x4000,
TRACE_ITER_SYM_USEROBJ = 0x8000,
- TRACE_ITER_PRINTK_MSGONLY = 0x10000
+ TRACE_ITER_PRINTK_MSGONLY = 0x10000,
+ TRACE_ITER_CONTEXT_INFO = 0x20000, /* Print pid/cpu/time */
+ TRACE_ITER_LATENCY_FMT = 0x40000,
+ TRACE_ITER_GLOBAL_CLK = 0x80000,
+ TRACE_ITER_SLEEP_TIME = 0x100000,
};
/*
@@ -601,12 +712,12 @@ extern struct tracer nop_trace;
* preempt_enable (after a disable), a schedule might take place
* causing an infinite recursion.
*
- * To prevent this, we read the need_recshed flag before
+ * To prevent this, we read the need_resched flag before
* disabling preemption. When we want to enable preemption we
* check the flag, if it is set, then we call preempt_enable_no_resched.
* Otherwise, we call preempt_enable.
*
- * The rational for doing the above is that if need resched is set
+ * The rational for doing the above is that if need_resched is set
* and we have yet to reschedule, we are either in an atomic location
* (where we do not need to check for scheduling) or we are inside
* the scheduler and do not want to resched.
@@ -627,7 +738,7 @@ static inline int ftrace_preempt_disable(void)
*
* This is a scheduler safe way to enable preemption and not miss
* any preemption checks. The disabled saved the state of preemption.
- * If resched is set, then we were either inside an atomic or
+ * If resched is set, then we are either inside an atomic or
* are inside the scheduler (we would have already scheduled
* otherwise). In this case, we do not want to call normal
* preempt_enable, but preempt_enable_no_resched instead.
@@ -664,4 +775,118 @@ static inline void trace_branch_disable(void)
}
#endif /* CONFIG_BRANCH_TRACER */
+/* set ring buffers to default size if not already done so */
+int tracing_update_buffers(void);
+
+/* trace event type bit fields, not numeric */
+enum {
+ TRACE_EVENT_TYPE_PRINTF = 1,
+ TRACE_EVENT_TYPE_RAW = 2,
+};
+
+struct ftrace_event_field {
+ struct list_head link;
+ char *name;
+ char *type;
+ int offset;
+ int size;
+};
+
+struct ftrace_event_call {
+ char *name;
+ char *system;
+ struct dentry *dir;
+ int enabled;
+ int (*regfunc)(void);
+ void (*unregfunc)(void);
+ int id;
+ int (*raw_init)(void);
+ int (*show_format)(struct trace_seq *s);
+ int (*define_fields)(void);
+ struct list_head fields;
+ struct filter_pred **preds;
+
+#ifdef CONFIG_EVENT_PROFILE
+ atomic_t profile_count;
+ int (*profile_enable)(struct ftrace_event_call *);
+ void (*profile_disable)(struct ftrace_event_call *);
+#endif
+};
+
+struct event_subsystem {
+ struct list_head list;
+ const char *name;
+ struct dentry *entry;
+ struct filter_pred **preds;
+};
+
+#define events_for_each(event) \
+ for (event = __start_ftrace_events; \
+ (unsigned long)event < (unsigned long)__stop_ftrace_events; \
+ event++)
+
+#define MAX_FILTER_PRED 8
+
+struct filter_pred;
+
+typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event);
+
+struct filter_pred {
+ filter_pred_fn_t fn;
+ u64 val;
+ char *str_val;
+ int str_len;
+ char *field_name;
+ int offset;
+ int not;
+ int or;
+ int compound;
+ int clear;
+};
+
+int trace_define_field(struct ftrace_event_call *call, char *type,
+ char *name, int offset, int size);
+extern void filter_free_pred(struct filter_pred *pred);
+extern void filter_print_preds(struct filter_pred **preds,
+ struct trace_seq *s);
+extern int filter_parse(char **pbuf, struct filter_pred *pred);
+extern int filter_add_pred(struct ftrace_event_call *call,
+ struct filter_pred *pred);
+extern void filter_free_preds(struct ftrace_event_call *call);
+extern int filter_match_preds(struct ftrace_event_call *call, void *rec);
+extern void filter_free_subsystem_preds(struct event_subsystem *system);
+extern int filter_add_subsystem_pred(struct event_subsystem *system,
+ struct filter_pred *pred);
+
+void event_trace_printk(unsigned long ip, const char *fmt, ...);
+extern struct ftrace_event_call __start_ftrace_events[];
+extern struct ftrace_event_call __stop_ftrace_events[];
+
+#define for_each_event(event) \
+ for (event = __start_ftrace_events; \
+ (unsigned long)event < (unsigned long)__stop_ftrace_events; \
+ event++)
+
+extern const char *__start___trace_bprintk_fmt[];
+extern const char *__stop___trace_bprintk_fmt[];
+
+/*
+ * The double __builtin_constant_p is because gcc will give us an error
+ * if we try to allocate the static variable to fmt if it is not a
+ * constant. Even with the outer if statement optimizing out.
+ */
+#define event_trace_printk(ip, fmt, args...) \
+do { \
+ __trace_printk_check_format(fmt, ##args); \
+ tracing_record_cmdline(current); \
+ if (__builtin_constant_p(fmt)) { \
+ static const char *trace_printk_fmt \
+ __attribute__((section("__trace_printk_fmt"))) = \
+ __builtin_constant_p(fmt) ? fmt : NULL; \
+ \
+ __trace_bprintk(ip, trace_printk_fmt, ##args); \
+ } else \
+ __trace_printk(ip, fmt, ##args); \
+} while (0)
+
#endif /* _LINUX_KERNEL_TRACE_H */
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c
index 366c8c333e1..7a30fc4c364 100644
--- a/kernel/trace/trace_boot.c
+++ b/kernel/trace/trace_boot.c
@@ -11,6 +11,7 @@
#include <linux/kallsyms.h>
#include "trace.h"
+#include "trace_output.h"
static struct trace_array *boot_trace;
static bool pre_initcalls_finished;
@@ -27,13 +28,13 @@ void start_boot_trace(void)
void enable_boot_trace(void)
{
- if (pre_initcalls_finished)
+ if (boot_trace && pre_initcalls_finished)
tracing_start_sched_switch_record();
}
void disable_boot_trace(void)
{
- if (pre_initcalls_finished)
+ if (boot_trace && pre_initcalls_finished)
tracing_stop_sched_switch_record();
}
@@ -42,6 +43,9 @@ static int boot_trace_init(struct trace_array *tr)
int cpu;
boot_trace = tr;
+ if (!tr)
+ return 0;
+
for_each_cpu(cpu, cpu_possible_mask)
tracing_reset(tr, cpu);
@@ -128,10 +132,9 @@ void trace_boot_call(struct boot_trace_call *bt, initcall_t fn)
{
struct ring_buffer_event *event;
struct trace_boot_call *entry;
- unsigned long irq_flags;
struct trace_array *tr = boot_trace;
- if (!pre_initcalls_finished)
+ if (!tr || !pre_initcalls_finished)
return;
/* Get its name now since this function could
@@ -140,18 +143,13 @@ void trace_boot_call(struct boot_trace_call *bt, initcall_t fn)
sprint_symbol(bt->func, (unsigned long)fn);
preempt_disable();
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
- &irq_flags);
+ event = trace_buffer_lock_reserve(tr, TRACE_BOOT_CALL,
+ sizeof(*entry), 0, 0);
if (!event)
goto out;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, 0, 0);
- entry->ent.type = TRACE_BOOT_CALL;
entry->boot_call = *bt;
- ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-
- trace_wake_up();
-
+ trace_buffer_unlock_commit(tr, event, 0, 0);
out:
preempt_enable();
}
@@ -160,27 +158,21 @@ void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn)
{
struct ring_buffer_event *event;
struct trace_boot_ret *entry;
- unsigned long irq_flags;
struct trace_array *tr = boot_trace;
- if (!pre_initcalls_finished)
+ if (!tr || !pre_initcalls_finished)
return;
sprint_symbol(bt->func, (unsigned long)fn);
preempt_disable();
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
- &irq_flags);
+ event = trace_buffer_lock_reserve(tr, TRACE_BOOT_RET,
+ sizeof(*entry), 0, 0);
if (!event)
goto out;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, 0, 0);
- entry->ent.type = TRACE_BOOT_RET;
entry->boot_ret = *bt;
- ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-
- trace_wake_up();
-
+ trace_buffer_unlock_commit(tr, event, 0, 0);
out:
preempt_enable();
}
diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c
index 6c00feb3bac..ad8c22efff4 100644
--- a/kernel/trace/trace_branch.c
+++ b/kernel/trace/trace_branch.c
@@ -14,12 +14,17 @@
#include <linux/hash.h>
#include <linux/fs.h>
#include <asm/local.h>
+
#include "trace.h"
+#include "trace_stat.h"
+#include "trace_output.h"
#ifdef CONFIG_BRANCH_TRACER
+static struct tracer branch_trace;
static int branch_tracing_enabled __read_mostly;
static DEFINE_MUTEX(branch_tracing_mutex);
+
static struct trace_array *branch_tracer;
static void
@@ -28,7 +33,7 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
struct trace_array *tr = branch_tracer;
struct ring_buffer_event *event;
struct trace_branch *entry;
- unsigned long flags, irq_flags;
+ unsigned long flags;
int cpu, pc;
const char *p;
@@ -47,15 +52,13 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
if (atomic_inc_return(&tr->data[cpu]->disabled) != 1)
goto out;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
- &irq_flags);
+ pc = preempt_count();
+ event = trace_buffer_lock_reserve(tr, TRACE_BRANCH,
+ sizeof(*entry), flags, pc);
if (!event)
goto out;
- pc = preempt_count();
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, flags, pc);
- entry->ent.type = TRACE_BRANCH;
/* Strip off the path, only save the file */
p = f->file + strlen(f->file);
@@ -70,7 +73,7 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
entry->line = f->line;
entry->correct = val == expect;
- ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+ ring_buffer_unlock_commit(tr->buffer, event);
out:
atomic_dec(&tr->data[cpu]->disabled);
@@ -88,8 +91,6 @@ void trace_likely_condition(struct ftrace_branch_data *f, int val, int expect)
int enable_branch_tracing(struct trace_array *tr)
{
- int ret = 0;
-
mutex_lock(&branch_tracing_mutex);
branch_tracer = tr;
/*
@@ -100,7 +101,7 @@ int enable_branch_tracing(struct trace_array *tr)
branch_tracing_enabled++;
mutex_unlock(&branch_tracing_mutex);
- return ret;
+ return 0;
}
void disable_branch_tracing(void)
@@ -128,11 +129,6 @@ static void stop_branch_trace(struct trace_array *tr)
static int branch_trace_init(struct trace_array *tr)
{
- int cpu;
-
- for_each_online_cpu(cpu)
- tracing_reset(tr, cpu);
-
start_branch_trace(tr);
return 0;
}
@@ -142,22 +138,53 @@ static void branch_trace_reset(struct trace_array *tr)
stop_branch_trace(tr);
}
-struct tracer branch_trace __read_mostly =
+static enum print_line_t trace_branch_print(struct trace_iterator *iter,
+ int flags)
+{
+ struct trace_branch *field;
+
+ trace_assign_type(field, iter->ent);
+
+ if (trace_seq_printf(&iter->seq, "[%s] %s:%s:%d\n",
+ field->correct ? " ok " : " MISS ",
+ field->func,
+ field->file,
+ field->line))
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ return TRACE_TYPE_HANDLED;
+}
+
+
+static struct trace_event trace_branch_event = {
+ .type = TRACE_BRANCH,
+ .trace = trace_branch_print,
+};
+
+static struct tracer branch_trace __read_mostly =
{
.name = "branch",
.init = branch_trace_init,
.reset = branch_trace_reset,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_branch,
-#endif
+#endif /* CONFIG_FTRACE_SELFTEST */
};
-__init static int init_branch_trace(void)
+__init static int init_branch_tracer(void)
{
+ int ret;
+
+ ret = register_ftrace_event(&trace_branch_event);
+ if (!ret) {
+ printk(KERN_WARNING "Warning: could not register "
+ "branch events\n");
+ return 1;
+ }
return register_tracer(&branch_trace);
}
+device_initcall(init_branch_tracer);
-device_initcall(init_branch_trace);
#else
static inline
void trace_likely_condition(struct ftrace_branch_data *f, int val, int expect)
@@ -183,66 +210,39 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect)
}
EXPORT_SYMBOL(ftrace_likely_update);
-struct ftrace_pointer {
- void *start;
- void *stop;
- int hit;
-};
+extern unsigned long __start_annotated_branch_profile[];
+extern unsigned long __stop_annotated_branch_profile[];
-static void *
-t_next(struct seq_file *m, void *v, loff_t *pos)
+static int annotated_branch_stat_headers(struct seq_file *m)
{
- const struct ftrace_pointer *f = m->private;
- struct ftrace_branch_data *p = v;
-
- (*pos)++;
-
- if (v == (void *)1)
- return f->start;
-
- ++p;
-
- if ((void *)p >= (void *)f->stop)
- return NULL;
-
- return p;
+ seq_printf(m, " correct incorrect %% ");
+ seq_printf(m, " Function "
+ " File Line\n"
+ " ------- --------- - "
+ " -------- "
+ " ---- ----\n");
+ return 0;
}
-static void *t_start(struct seq_file *m, loff_t *pos)
+static inline long get_incorrect_percent(struct ftrace_branch_data *p)
{
- void *t = (void *)1;
- loff_t l = 0;
-
- for (; t && l < *pos; t = t_next(m, t, &l))
- ;
+ long percent;
- return t;
-}
+ if (p->correct) {
+ percent = p->incorrect * 100;
+ percent /= p->correct + p->incorrect;
+ } else
+ percent = p->incorrect ? 100 : -1;
-static void t_stop(struct seq_file *m, void *p)
-{
+ return percent;
}
-static int t_show(struct seq_file *m, void *v)
+static int branch_stat_show(struct seq_file *m, void *v)
{
- const struct ftrace_pointer *fp = m->private;
struct ftrace_branch_data *p = v;
const char *f;
long percent;
- if (v == (void *)1) {
- if (fp->hit)
- seq_printf(m, " miss hit %% ");
- else
- seq_printf(m, " correct incorrect %% ");
- seq_printf(m, " Function "
- " File Line\n"
- " ------- --------- - "
- " -------- "
- " ---- ----\n");
- return 0;
- }
-
/* Only print the file, not the path */
f = p->file + strlen(p->file);
while (f >= p->file && *f != '/')
@@ -252,11 +252,7 @@ static int t_show(struct seq_file *m, void *v)
/*
* The miss is overlayed on correct, and hit on incorrect.
*/
- if (p->correct) {
- percent = p->incorrect * 100;
- percent /= p->correct + p->incorrect;
- } else
- percent = p->incorrect ? 100 : -1;
+ percent = get_incorrect_percent(p);
seq_printf(m, "%8lu %8lu ", p->correct, p->incorrect);
if (percent < 0)
@@ -267,76 +263,118 @@ static int t_show(struct seq_file *m, void *v)
return 0;
}
-static struct seq_operations tracing_likely_seq_ops = {
- .start = t_start,
- .next = t_next,
- .stop = t_stop,
- .show = t_show,
+static void *annotated_branch_stat_start(void)
+{
+ return __start_annotated_branch_profile;
+}
+
+static void *
+annotated_branch_stat_next(void *v, int idx)
+{
+ struct ftrace_branch_data *p = v;
+
+ ++p;
+
+ if ((void *)p >= (void *)__stop_annotated_branch_profile)
+ return NULL;
+
+ return p;
+}
+
+static int annotated_branch_stat_cmp(void *p1, void *p2)
+{
+ struct ftrace_branch_data *a = p1;
+ struct ftrace_branch_data *b = p2;
+
+ long percent_a, percent_b;
+
+ percent_a = get_incorrect_percent(a);
+ percent_b = get_incorrect_percent(b);
+
+ if (percent_a < percent_b)
+ return -1;
+ if (percent_a > percent_b)
+ return 1;
+ else
+ return 0;
+}
+
+static struct tracer_stat annotated_branch_stats = {
+ .name = "branch_annotated",
+ .stat_start = annotated_branch_stat_start,
+ .stat_next = annotated_branch_stat_next,
+ .stat_cmp = annotated_branch_stat_cmp,
+ .stat_headers = annotated_branch_stat_headers,
+ .stat_show = branch_stat_show
};
-static int tracing_branch_open(struct inode *inode, struct file *file)
+__init static int init_annotated_branch_stats(void)
{
int ret;
- ret = seq_open(file, &tracing_likely_seq_ops);
+ ret = register_stat_tracer(&annotated_branch_stats);
if (!ret) {
- struct seq_file *m = file->private_data;
- m->private = (void *)inode->i_private;
+ printk(KERN_WARNING "Warning: could not register "
+ "annotated branches stats\n");
+ return 1;
}
-
- return ret;
+ return 0;
}
-
-static const struct file_operations tracing_branch_fops = {
- .open = tracing_branch_open,
- .read = seq_read,
- .llseek = seq_lseek,
-};
+fs_initcall(init_annotated_branch_stats);
#ifdef CONFIG_PROFILE_ALL_BRANCHES
+
extern unsigned long __start_branch_profile[];
extern unsigned long __stop_branch_profile[];
-static const struct ftrace_pointer ftrace_branch_pos = {
- .start = __start_branch_profile,
- .stop = __stop_branch_profile,
- .hit = 1,
-};
+static int all_branch_stat_headers(struct seq_file *m)
+{
+ seq_printf(m, " miss hit %% ");
+ seq_printf(m, " Function "
+ " File Line\n"
+ " ------- --------- - "
+ " -------- "
+ " ---- ----\n");
+ return 0;
+}
-#endif /* CONFIG_PROFILE_ALL_BRANCHES */
+static void *all_branch_stat_start(void)
+{
+ return __start_branch_profile;
+}
-extern unsigned long __start_annotated_branch_profile[];
-extern unsigned long __stop_annotated_branch_profile[];
+static void *
+all_branch_stat_next(void *v, int idx)
+{
+ struct ftrace_branch_data *p = v;
-static const struct ftrace_pointer ftrace_annotated_branch_pos = {
- .start = __start_annotated_branch_profile,
- .stop = __stop_annotated_branch_profile,
-};
+ ++p;
-static __init int ftrace_branch_init(void)
-{
- struct dentry *d_tracer;
- struct dentry *entry;
+ if ((void *)p >= (void *)__stop_branch_profile)
+ return NULL;
- d_tracer = tracing_init_dentry();
+ return p;
+}
- entry = debugfs_create_file("profile_annotated_branch", 0444, d_tracer,
- (void *)&ftrace_annotated_branch_pos,
- &tracing_branch_fops);
- if (!entry)
- pr_warning("Could not create debugfs "
- "'profile_annotatet_branch' entry\n");
+static struct tracer_stat all_branch_stats = {
+ .name = "branch_all",
+ .stat_start = all_branch_stat_start,
+ .stat_next = all_branch_stat_next,
+ .stat_headers = all_branch_stat_headers,
+ .stat_show = branch_stat_show
+};
-#ifdef CONFIG_PROFILE_ALL_BRANCHES
- entry = debugfs_create_file("profile_branch", 0444, d_tracer,
- (void *)&ftrace_branch_pos,
- &tracing_branch_fops);
- if (!entry)
- pr_warning("Could not create debugfs"
- " 'profile_branch' entry\n");
-#endif
+__init static int all_annotated_branch_stats(void)
+{
+ int ret;
+ ret = register_stat_tracer(&all_branch_stats);
+ if (!ret) {
+ printk(KERN_WARNING "Warning: could not register "
+ "all branches stats\n");
+ return 1;
+ }
return 0;
}
-
-device_initcall(ftrace_branch_init);
+fs_initcall(all_annotated_branch_stats);
+#endif /* CONFIG_PROFILE_ALL_BRANCHES */
diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c
new file mode 100644
index 00000000000..b588fd81f7f
--- /dev/null
+++ b/kernel/trace/trace_clock.c
@@ -0,0 +1,109 @@
+/*
+ * tracing clocks
+ *
+ * Copyright (C) 2009 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ * Implements 3 trace clock variants, with differing scalability/precision
+ * tradeoffs:
+ *
+ * - local: CPU-local trace clock
+ * - medium: scalable global clock with some jitter
+ * - global: globally monotonic, serialized clock
+ *
+ * Tracer plugins will chose a default from these clocks.
+ */
+#include <linux/spinlock.h>
+#include <linux/hardirq.h>
+#include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/sched.h>
+#include <linux/ktime.h>
+#include <linux/trace_clock.h>
+
+/*
+ * trace_clock_local(): the simplest and least coherent tracing clock.
+ *
+ * Useful for tracing that does not cross to other CPUs nor
+ * does it go through idle events.
+ */
+u64 notrace trace_clock_local(void)
+{
+ unsigned long flags;
+ u64 clock;
+
+ /*
+ * sched_clock() is an architecture implemented, fast, scalable,
+ * lockless clock. It is not guaranteed to be coherent across
+ * CPUs, nor across CPU idle events.
+ */
+ raw_local_irq_save(flags);
+ clock = sched_clock();
+ raw_local_irq_restore(flags);
+
+ return clock;
+}
+
+/*
+ * trace_clock(): 'inbetween' trace clock. Not completely serialized,
+ * but not completely incorrect when crossing CPUs either.
+ *
+ * This is based on cpu_clock(), which will allow at most ~1 jiffy of
+ * jitter between CPUs. So it's a pretty scalable clock, but there
+ * can be offsets in the trace data.
+ */
+u64 notrace trace_clock(void)
+{
+ return cpu_clock(raw_smp_processor_id());
+}
+
+
+/*
+ * trace_clock_global(): special globally coherent trace clock
+ *
+ * It has higher overhead than the other trace clocks but is still
+ * an order of magnitude faster than GTOD derived hardware clocks.
+ *
+ * Used by plugins that need globally coherent timestamps.
+ */
+
+static u64 prev_trace_clock_time;
+
+static raw_spinlock_t trace_clock_lock ____cacheline_aligned_in_smp =
+ (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+
+u64 notrace trace_clock_global(void)
+{
+ unsigned long flags;
+ int this_cpu;
+ u64 now;
+
+ raw_local_irq_save(flags);
+
+ this_cpu = raw_smp_processor_id();
+ now = cpu_clock(this_cpu);
+ /*
+ * If in an NMI context then dont risk lockups and return the
+ * cpu_clock() time:
+ */
+ if (unlikely(in_nmi()))
+ goto out;
+
+ __raw_spin_lock(&trace_clock_lock);
+
+ /*
+ * TODO: if this happens often then maybe we should reset
+ * my_scd->clock to prev_trace_clock_time+1, to make sure
+ * we start ticking with the local clock from now on?
+ */
+ if ((s64)(now - prev_trace_clock_time) < 0)
+ now = prev_trace_clock_time + 1;
+
+ prev_trace_clock_time = now;
+
+ __raw_spin_unlock(&trace_clock_lock);
+
+ out:
+ raw_local_irq_restore(flags);
+
+ return now;
+}
diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c
new file mode 100644
index 00000000000..22cba997077
--- /dev/null
+++ b/kernel/trace/trace_event_profile.c
@@ -0,0 +1,31 @@
+/*
+ * trace event based perf counter profiling
+ *
+ * Copyright (C) 2009 Red Hat Inc, Peter Zijlstra <pzijlstr@redhat.com>
+ *
+ */
+
+#include "trace.h"
+
+int ftrace_profile_enable(int event_id)
+{
+ struct ftrace_event_call *event;
+
+ for_each_event(event) {
+ if (event->id == event_id)
+ return event->profile_enable(event);
+ }
+
+ return -EINVAL;
+}
+
+void ftrace_profile_disable(int event_id)
+{
+ struct ftrace_event_call *event;
+
+ for_each_event(event) {
+ if (event->id == event_id)
+ return event->profile_disable(event);
+ }
+}
+
diff --git a/kernel/trace/trace_event_types.h b/kernel/trace/trace_event_types.h
new file mode 100644
index 00000000000..fd78bee71dd
--- /dev/null
+++ b/kernel/trace/trace_event_types.h
@@ -0,0 +1,173 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM ftrace
+
+/*
+ * We cheat and use the proto type field as the ID
+ * and args as the entry type (minus 'struct')
+ */
+TRACE_EVENT_FORMAT(function, TRACE_FN, ftrace_entry, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(unsigned long, ip, ip)
+ TRACE_FIELD(unsigned long, parent_ip, parent_ip)
+ ),
+ TP_RAW_FMT(" %lx <-- %lx")
+);
+
+TRACE_EVENT_FORMAT(funcgraph_entry, TRACE_GRAPH_ENT,
+ ftrace_graph_ent_entry, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(unsigned long, graph_ent.func, func)
+ TRACE_FIELD(int, graph_ent.depth, depth)
+ ),
+ TP_RAW_FMT("--> %lx (%d)")
+);
+
+TRACE_EVENT_FORMAT(funcgraph_exit, TRACE_GRAPH_RET,
+ ftrace_graph_ret_entry, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(unsigned long, ret.func, func)
+ TRACE_FIELD(int, ret.depth, depth)
+ ),
+ TP_RAW_FMT("<-- %lx (%d)")
+);
+
+TRACE_EVENT_FORMAT(wakeup, TRACE_WAKE, ctx_switch_entry, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(unsigned int, prev_pid, prev_pid)
+ TRACE_FIELD(unsigned char, prev_prio, prev_prio)
+ TRACE_FIELD(unsigned char, prev_state, prev_state)
+ TRACE_FIELD(unsigned int, next_pid, next_pid)
+ TRACE_FIELD(unsigned char, next_prio, next_prio)
+ TRACE_FIELD(unsigned char, next_state, next_state)
+ TRACE_FIELD(unsigned int, next_cpu, next_cpu)
+ ),
+ TP_RAW_FMT("%u:%u:%u ==+ %u:%u:%u [%03u]")
+);
+
+TRACE_EVENT_FORMAT(context_switch, TRACE_CTX, ctx_switch_entry, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(unsigned int, prev_pid, prev_pid)
+ TRACE_FIELD(unsigned char, prev_prio, prev_prio)
+ TRACE_FIELD(unsigned char, prev_state, prev_state)
+ TRACE_FIELD(unsigned int, next_pid, next_pid)
+ TRACE_FIELD(unsigned char, next_prio, next_prio)
+ TRACE_FIELD(unsigned char, next_state, next_state)
+ TRACE_FIELD(unsigned int, next_cpu, next_cpu)
+ ),
+ TP_RAW_FMT("%u:%u:%u ==+ %u:%u:%u [%03u]")
+);
+
+TRACE_EVENT_FORMAT(special, TRACE_SPECIAL, special_entry, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(unsigned long, arg1, arg1)
+ TRACE_FIELD(unsigned long, arg2, arg2)
+ TRACE_FIELD(unsigned long, arg3, arg3)
+ ),
+ TP_RAW_FMT("(%08lx) (%08lx) (%08lx)")
+);
+
+/*
+ * Stack-trace entry:
+ */
+
+/* #define FTRACE_STACK_ENTRIES 8 */
+
+TRACE_EVENT_FORMAT(kernel_stack, TRACE_STACK, stack_entry, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(unsigned long, caller[0], stack0)
+ TRACE_FIELD(unsigned long, caller[1], stack1)
+ TRACE_FIELD(unsigned long, caller[2], stack2)
+ TRACE_FIELD(unsigned long, caller[3], stack3)
+ TRACE_FIELD(unsigned long, caller[4], stack4)
+ TRACE_FIELD(unsigned long, caller[5], stack5)
+ TRACE_FIELD(unsigned long, caller[6], stack6)
+ TRACE_FIELD(unsigned long, caller[7], stack7)
+ ),
+ TP_RAW_FMT("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n"
+ "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n")
+);
+
+TRACE_EVENT_FORMAT(user_stack, TRACE_USER_STACK, userstack_entry, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(unsigned long, caller[0], stack0)
+ TRACE_FIELD(unsigned long, caller[1], stack1)
+ TRACE_FIELD(unsigned long, caller[2], stack2)
+ TRACE_FIELD(unsigned long, caller[3], stack3)
+ TRACE_FIELD(unsigned long, caller[4], stack4)
+ TRACE_FIELD(unsigned long, caller[5], stack5)
+ TRACE_FIELD(unsigned long, caller[6], stack6)
+ TRACE_FIELD(unsigned long, caller[7], stack7)
+ ),
+ TP_RAW_FMT("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n"
+ "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n")
+);
+
+TRACE_EVENT_FORMAT(bprint, TRACE_BPRINT, bprint_entry, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(unsigned long, ip, ip)
+ TRACE_FIELD(char *, fmt, fmt)
+ TRACE_FIELD_ZERO_CHAR(buf)
+ ),
+ TP_RAW_FMT("%08lx (%d) fmt:%p %s")
+);
+
+TRACE_EVENT_FORMAT(print, TRACE_PRINT, print_entry, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(unsigned long, ip, ip)
+ TRACE_FIELD_ZERO_CHAR(buf)
+ ),
+ TP_RAW_FMT("%08lx (%d) fmt:%p %s")
+);
+
+TRACE_EVENT_FORMAT(branch, TRACE_BRANCH, trace_branch, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(unsigned int, line, line)
+ TRACE_FIELD_SPECIAL(char func[TRACE_FUNC_SIZE+1], func, func)
+ TRACE_FIELD_SPECIAL(char file[TRACE_FUNC_SIZE+1], file, file)
+ TRACE_FIELD(char, correct, correct)
+ ),
+ TP_RAW_FMT("%u:%s:%s (%u)")
+);
+
+TRACE_EVENT_FORMAT(hw_branch, TRACE_HW_BRANCHES, hw_branch_entry, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(u64, from, from)
+ TRACE_FIELD(u64, to, to)
+ ),
+ TP_RAW_FMT("from: %llx to: %llx")
+);
+
+TRACE_EVENT_FORMAT(power, TRACE_POWER, trace_power, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(ktime_t, state_data.stamp, stamp)
+ TRACE_FIELD(ktime_t, state_data.end, end)
+ TRACE_FIELD(int, state_data.type, type)
+ TRACE_FIELD(int, state_data.state, state)
+ ),
+ TP_RAW_FMT("%llx->%llx type:%u state:%u")
+);
+
+TRACE_EVENT_FORMAT(kmem_alloc, TRACE_KMEM_ALLOC, kmemtrace_alloc_entry, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(enum kmemtrace_type_id, type_id, type_id)
+ TRACE_FIELD(unsigned long, call_site, call_site)
+ TRACE_FIELD(const void *, ptr, ptr)
+ TRACE_FIELD(size_t, bytes_req, bytes_req)
+ TRACE_FIELD(size_t, bytes_alloc, bytes_alloc)
+ TRACE_FIELD(gfp_t, gfp_flags, gfp_flags)
+ TRACE_FIELD(int, node, node)
+ ),
+ TP_RAW_FMT("type:%u call_site:%lx ptr:%p req:%lu alloc:%lu"
+ " flags:%x node:%d")
+);
+
+TRACE_EVENT_FORMAT(kmem_free, TRACE_KMEM_FREE, kmemtrace_free_entry, ignore,
+ TRACE_STRUCT(
+ TRACE_FIELD(enum kmemtrace_type_id, type_id, type_id)
+ TRACE_FIELD(unsigned long, call_site, call_site)
+ TRACE_FIELD(const void *, ptr, ptr)
+ ),
+ TP_RAW_FMT("type:%u call_site:%lx ptr:%p")
+);
+
+#undef TRACE_SYSTEM
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
new file mode 100644
index 00000000000..576f4fa2af0
--- /dev/null
+++ b/kernel/trace/trace_events.c
@@ -0,0 +1,828 @@
+/*
+ * event tracer
+ *
+ * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ *
+ * - Added format output of fields of the trace point.
+ * This was based off of work by Tom Zanussi <tzanussi@gmail.com>.
+ *
+ */
+
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/ctype.h>
+
+#include "trace_output.h"
+
+#define TRACE_SYSTEM "TRACE_SYSTEM"
+
+static DEFINE_MUTEX(event_mutex);
+
+int trace_define_field(struct ftrace_event_call *call, char *type,
+ char *name, int offset, int size)
+{
+ struct ftrace_event_field *field;
+
+ field = kzalloc(sizeof(*field), GFP_KERNEL);
+ if (!field)
+ goto err;
+
+ field->name = kstrdup(name, GFP_KERNEL);
+ if (!field->name)
+ goto err;
+
+ field->type = kstrdup(type, GFP_KERNEL);
+ if (!field->type)
+ goto err;
+
+ field->offset = offset;
+ field->size = size;
+ list_add(&field->link, &call->fields);
+
+ return 0;
+
+err:
+ if (field) {
+ kfree(field->name);
+ kfree(field->type);
+ }
+ kfree(field);
+
+ return -ENOMEM;
+}
+
+static void ftrace_clear_events(void)
+{
+ struct ftrace_event_call *call = (void *)__start_ftrace_events;
+
+
+ while ((unsigned long)call < (unsigned long)__stop_ftrace_events) {
+
+ if (call->enabled) {
+ call->enabled = 0;
+ call->unregfunc();
+ }
+ call++;
+ }
+}
+
+static void ftrace_event_enable_disable(struct ftrace_event_call *call,
+ int enable)
+{
+
+ switch (enable) {
+ case 0:
+ if (call->enabled) {
+ call->enabled = 0;
+ call->unregfunc();
+ }
+ break;
+ case 1:
+ if (!call->enabled) {
+ call->enabled = 1;
+ call->regfunc();
+ }
+ break;
+ }
+}
+
+static int ftrace_set_clr_event(char *buf, int set)
+{
+ struct ftrace_event_call *call = __start_ftrace_events;
+ char *event = NULL, *sub = NULL, *match;
+ int ret = -EINVAL;
+
+ /*
+ * The buf format can be <subsystem>:<event-name>
+ * *:<event-name> means any event by that name.
+ * :<event-name> is the same.
+ *
+ * <subsystem>:* means all events in that subsystem
+ * <subsystem>: means the same.
+ *
+ * <name> (no ':') means all events in a subsystem with
+ * the name <name> or any event that matches <name>
+ */
+
+ match = strsep(&buf, ":");
+ if (buf) {
+ sub = match;
+ event = buf;
+ match = NULL;
+
+ if (!strlen(sub) || strcmp(sub, "*") == 0)
+ sub = NULL;
+ if (!strlen(event) || strcmp(event, "*") == 0)
+ event = NULL;
+ }
+
+ mutex_lock(&event_mutex);
+ for_each_event(call) {
+
+ if (!call->name || !call->regfunc)
+ continue;
+
+ if (match &&
+ strcmp(match, call->name) != 0 &&
+ strcmp(match, call->system) != 0)
+ continue;
+
+ if (sub && strcmp(sub, call->system) != 0)
+ continue;
+
+ if (event && strcmp(event, call->name) != 0)
+ continue;
+
+ ftrace_event_enable_disable(call, set);
+
+ ret = 0;
+ }
+ mutex_unlock(&event_mutex);
+
+ return ret;
+}
+
+/* 128 should be much more than enough */
+#define EVENT_BUF_SIZE 127
+
+static ssize_t
+ftrace_event_write(struct file *file, const char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ size_t read = 0;
+ int i, set = 1;
+ ssize_t ret;
+ char *buf;
+ char ch;
+
+ if (!cnt || cnt < 0)
+ return 0;
+
+ ret = tracing_update_buffers();
+ if (ret < 0)
+ return ret;
+
+ ret = get_user(ch, ubuf++);
+ if (ret)
+ return ret;
+ read++;
+ cnt--;
+
+ /* skip white space */
+ while (cnt && isspace(ch)) {
+ ret = get_user(ch, ubuf++);
+ if (ret)
+ return ret;
+ read++;
+ cnt--;
+ }
+
+ /* Only white space found? */
+ if (isspace(ch)) {
+ file->f_pos += read;
+ ret = read;
+ return ret;
+ }
+
+ buf = kmalloc(EVENT_BUF_SIZE+1, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ if (cnt > EVENT_BUF_SIZE)
+ cnt = EVENT_BUF_SIZE;
+
+ i = 0;
+ while (cnt && !isspace(ch)) {
+ if (!i && ch == '!')
+ set = 0;
+ else
+ buf[i++] = ch;
+
+ ret = get_user(ch, ubuf++);
+ if (ret)
+ goto out_free;
+ read++;
+ cnt--;
+ }
+ buf[i] = 0;
+
+ file->f_pos += read;
+
+ ret = ftrace_set_clr_event(buf, set);
+ if (ret)
+ goto out_free;
+
+ ret = read;
+
+ out_free:
+ kfree(buf);
+
+ return ret;
+}
+
+static void *
+t_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ struct ftrace_event_call *call = m->private;
+ struct ftrace_event_call *next = call;
+
+ (*pos)++;
+
+ for (;;) {
+ if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
+ return NULL;
+
+ /*
+ * The ftrace subsystem is for showing formats only.
+ * They can not be enabled or disabled via the event files.
+ */
+ if (call->regfunc)
+ break;
+
+ call++;
+ next = call;
+ }
+
+ m->private = ++next;
+
+ return call;
+}
+
+static void *t_start(struct seq_file *m, loff_t *pos)
+{
+ return t_next(m, NULL, pos);
+}
+
+static void *
+s_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ struct ftrace_event_call *call = m->private;
+ struct ftrace_event_call *next;
+
+ (*pos)++;
+
+ retry:
+ if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
+ return NULL;
+
+ if (!call->enabled) {
+ call++;
+ goto retry;
+ }
+
+ next = call;
+ m->private = ++next;
+
+ return call;
+}
+
+static void *s_start(struct seq_file *m, loff_t *pos)
+{
+ return s_next(m, NULL, pos);
+}
+
+static int t_show(struct seq_file *m, void *v)
+{
+ struct ftrace_event_call *call = v;
+
+ if (strcmp(call->system, TRACE_SYSTEM) != 0)
+ seq_printf(m, "%s:", call->system);
+ seq_printf(m, "%s\n", call->name);
+
+ return 0;
+}
+
+static void t_stop(struct seq_file *m, void *p)
+{
+}
+
+static int
+ftrace_event_seq_open(struct inode *inode, struct file *file)
+{
+ int ret;
+ const struct seq_operations *seq_ops;
+
+ if ((file->f_mode & FMODE_WRITE) &&
+ !(file->f_flags & O_APPEND))
+ ftrace_clear_events();
+
+ seq_ops = inode->i_private;
+ ret = seq_open(file, seq_ops);
+ if (!ret) {
+ struct seq_file *m = file->private_data;
+
+ m->private = __start_ftrace_events;
+ }
+ return ret;
+}
+
+static ssize_t
+event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ struct ftrace_event_call *call = filp->private_data;
+ char *buf;
+
+ if (call->enabled)
+ buf = "1\n";
+ else
+ buf = "0\n";
+
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2);
+}
+
+static ssize_t
+event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ struct ftrace_event_call *call = filp->private_data;
+ char buf[64];
+ unsigned long val;
+ int ret;
+
+ if (cnt >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ return -EFAULT;
+
+ buf[cnt] = 0;
+
+ ret = strict_strtoul(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ ret = tracing_update_buffers();
+ if (ret < 0)
+ return ret;
+
+ switch (val) {
+ case 0:
+ case 1:
+ mutex_lock(&event_mutex);
+ ftrace_event_enable_disable(call, val);
+ mutex_unlock(&event_mutex);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ *ppos += cnt;
+
+ return cnt;
+}
+
+#undef FIELD
+#define FIELD(type, name) \
+ #type, "common_" #name, offsetof(typeof(field), name), \
+ sizeof(field.name)
+
+static int trace_write_header(struct trace_seq *s)
+{
+ struct trace_entry field;
+
+ /* struct trace_entry */
+ return trace_seq_printf(s,
+ "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
+ "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
+ "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
+ "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
+ "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
+ "\n",
+ FIELD(unsigned char, type),
+ FIELD(unsigned char, flags),
+ FIELD(unsigned char, preempt_count),
+ FIELD(int, pid),
+ FIELD(int, tgid));
+}
+
+static ssize_t
+event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ struct ftrace_event_call *call = filp->private_data;
+ struct trace_seq *s;
+ char *buf;
+ int r;
+
+ if (*ppos)
+ return 0;
+
+ s = kmalloc(sizeof(*s), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+
+ trace_seq_init(s);
+
+ /* If any of the first writes fail, so will the show_format. */
+
+ trace_seq_printf(s, "name: %s\n", call->name);
+ trace_seq_printf(s, "ID: %d\n", call->id);
+ trace_seq_printf(s, "format:\n");
+ trace_write_header(s);
+
+ r = call->show_format(s);
+ if (!r) {
+ /*
+ * ug! The format output is bigger than a PAGE!!
+ */
+ buf = "FORMAT TOO BIG\n";
+ r = simple_read_from_buffer(ubuf, cnt, ppos,
+ buf, strlen(buf));
+ goto out;
+ }
+
+ r = simple_read_from_buffer(ubuf, cnt, ppos,
+ s->buffer, s->len);
+ out:
+ kfree(s);
+ return r;
+}
+
+static ssize_t
+event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ struct ftrace_event_call *call = filp->private_data;
+ struct trace_seq *s;
+ int r;
+
+ if (*ppos)
+ return 0;
+
+ s = kmalloc(sizeof(*s), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+
+ trace_seq_init(s);
+ trace_seq_printf(s, "%d\n", call->id);
+
+ r = simple_read_from_buffer(ubuf, cnt, ppos,
+ s->buffer, s->len);
+ kfree(s);
+ return r;
+}
+
+static ssize_t
+event_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ struct ftrace_event_call *call = filp->private_data;
+ struct trace_seq *s;
+ int r;
+
+ if (*ppos)
+ return 0;
+
+ s = kmalloc(sizeof(*s), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+
+ trace_seq_init(s);
+
+ filter_print_preds(call->preds, s);
+ r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
+
+ kfree(s);
+
+ return r;
+}
+
+static ssize_t
+event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ struct ftrace_event_call *call = filp->private_data;
+ char buf[64], *pbuf = buf;
+ struct filter_pred *pred;
+ int err;
+
+ if (cnt >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ return -EFAULT;
+ buf[cnt] = '\0';
+
+ pred = kzalloc(sizeof(*pred), GFP_KERNEL);
+ if (!pred)
+ return -ENOMEM;
+
+ err = filter_parse(&pbuf, pred);
+ if (err < 0) {
+ filter_free_pred(pred);
+ return err;
+ }
+
+ if (pred->clear) {
+ filter_free_preds(call);
+ filter_free_pred(pred);
+ return cnt;
+ }
+
+ err = filter_add_pred(call, pred);
+ if (err < 0) {
+ filter_free_pred(pred);
+ return err;
+ }
+
+ *ppos += cnt;
+
+ return cnt;
+}
+
+static ssize_t
+subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ struct event_subsystem *system = filp->private_data;
+ struct trace_seq *s;
+ int r;
+
+ if (*ppos)
+ return 0;
+
+ s = kmalloc(sizeof(*s), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+
+ trace_seq_init(s);
+
+ filter_print_preds(system->preds, s);
+ r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
+
+ kfree(s);
+
+ return r;
+}
+
+static ssize_t
+subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
+ loff_t *ppos)
+{
+ struct event_subsystem *system = filp->private_data;
+ char buf[64], *pbuf = buf;
+ struct filter_pred *pred;
+ int err;
+
+ if (cnt >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ return -EFAULT;
+ buf[cnt] = '\0';
+
+ pred = kzalloc(sizeof(*pred), GFP_KERNEL);
+ if (!pred)
+ return -ENOMEM;
+
+ err = filter_parse(&pbuf, pred);
+ if (err < 0) {
+ filter_free_pred(pred);
+ return err;
+ }
+
+ if (pred->clear) {
+ filter_free_subsystem_preds(system);
+ filter_free_pred(pred);
+ return cnt;
+ }
+
+ err = filter_add_subsystem_pred(system, pred);
+ if (err < 0) {
+ filter_free_subsystem_preds(system);
+ filter_free_pred(pred);
+ return err;
+ }
+
+ *ppos += cnt;
+
+ return cnt;
+}
+
+static const struct seq_operations show_event_seq_ops = {
+ .start = t_start,
+ .next = t_next,
+ .show = t_show,
+ .stop = t_stop,
+};
+
+static const struct seq_operations show_set_event_seq_ops = {
+ .start = s_start,
+ .next = s_next,
+ .show = t_show,
+ .stop = t_stop,
+};
+
+static const struct file_operations ftrace_avail_fops = {
+ .open = ftrace_event_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static const struct file_operations ftrace_set_event_fops = {
+ .open = ftrace_event_seq_open,
+ .read = seq_read,
+ .write = ftrace_event_write,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static const struct file_operations ftrace_enable_fops = {
+ .open = tracing_open_generic,
+ .read = event_enable_read,
+ .write = event_enable_write,
+};
+
+static const struct file_operations ftrace_event_format_fops = {
+ .open = tracing_open_generic,
+ .read = event_format_read,
+};
+
+static const struct file_operations ftrace_event_id_fops = {
+ .open = tracing_open_generic,
+ .read = event_id_read,
+};
+
+static const struct file_operations ftrace_event_filter_fops = {
+ .open = tracing_open_generic,
+ .read = event_filter_read,
+ .write = event_filter_write,
+};
+
+static const struct file_operations ftrace_subsystem_filter_fops = {
+ .open = tracing_open_generic,
+ .read = subsystem_filter_read,
+ .write = subsystem_filter_write,
+};
+
+static struct dentry *event_trace_events_dir(void)
+{
+ static struct dentry *d_tracer;
+ static struct dentry *d_events;
+
+ if (d_events)
+ return d_events;
+
+ d_tracer = tracing_init_dentry();
+ if (!d_tracer)
+ return NULL;
+
+ d_events = debugfs_create_dir("events", d_tracer);
+ if (!d_events)
+ pr_warning("Could not create debugfs "
+ "'events' directory\n");
+
+ return d_events;
+}
+
+static LIST_HEAD(event_subsystems);
+
+static struct dentry *
+event_subsystem_dir(const char *name, struct dentry *d_events)
+{
+ struct event_subsystem *system;
+
+ /* First see if we did not already create this dir */
+ list_for_each_entry(system, &event_subsystems, list) {
+ if (strcmp(system->name, name) == 0)
+ return system->entry;
+ }
+
+ /* need to create new entry */
+ system = kmalloc(sizeof(*system), GFP_KERNEL);
+ if (!system) {
+ pr_warning("No memory to create event subsystem %s\n",
+ name);
+ return d_events;
+ }
+
+ system->entry = debugfs_create_dir(name, d_events);
+ if (!system->entry) {
+ pr_warning("Could not create event subsystem %s\n",
+ name);
+ kfree(system);
+ return d_events;
+ }
+
+ system->name = name;
+ list_add(&system->list, &event_subsystems);
+
+ system->preds = NULL;
+
+ return system->entry;
+}
+
+static int
+event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
+{
+ struct dentry *entry;
+ int ret;
+
+ /*
+ * If the trace point header did not define TRACE_SYSTEM
+ * then the system would be called "TRACE_SYSTEM".
+ */
+ if (strcmp(call->system, "TRACE_SYSTEM") != 0)
+ d_events = event_subsystem_dir(call->system, d_events);
+
+ if (call->raw_init) {
+ ret = call->raw_init();
+ if (ret < 0) {
+ pr_warning("Could not initialize trace point"
+ " events/%s\n", call->name);
+ return ret;
+ }
+ }
+
+ call->dir = debugfs_create_dir(call->name, d_events);
+ if (!call->dir) {
+ pr_warning("Could not create debugfs "
+ "'%s' directory\n", call->name);
+ return -1;
+ }
+
+ if (call->regfunc) {
+ entry = debugfs_create_file("enable", 0644, call->dir, call,
+ &ftrace_enable_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs "
+ "'%s/enable' entry\n", call->name);
+ }
+
+ if (call->id) {
+ entry = debugfs_create_file("id", 0444, call->dir, call,
+ &ftrace_event_id_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs '%s/id' entry\n",
+ call->name);
+ }
+
+ if (call->define_fields) {
+ ret = call->define_fields();
+ if (ret < 0) {
+ pr_warning("Could not initialize trace point"
+ " events/%s\n", call->name);
+ return ret;
+ }
+ entry = debugfs_create_file("filter", 0644, call->dir, call,
+ &ftrace_event_filter_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs "
+ "'%s/filter' entry\n", call->name);
+ }
+
+ /* A trace may not want to export its format */
+ if (!call->show_format)
+ return 0;
+
+ entry = debugfs_create_file("format", 0444, call->dir, call,
+ &ftrace_event_format_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs "
+ "'%s/format' entry\n", call->name);
+
+ return 0;
+}
+
+static __init int event_trace_init(void)
+{
+ struct ftrace_event_call *call = __start_ftrace_events;
+ struct dentry *d_tracer;
+ struct dentry *entry;
+ struct dentry *d_events;
+
+ d_tracer = tracing_init_dentry();
+ if (!d_tracer)
+ return 0;
+
+ entry = debugfs_create_file("available_events", 0444, d_tracer,
+ (void *)&show_event_seq_ops,
+ &ftrace_avail_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs "
+ "'available_events' entry\n");
+
+ entry = debugfs_create_file("set_event", 0644, d_tracer,
+ (void *)&show_set_event_seq_ops,
+ &ftrace_set_event_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs "
+ "'set_event' entry\n");
+
+ d_events = event_trace_events_dir();
+ if (!d_events)
+ return 0;
+
+ for_each_event(call) {
+ /* The linker may leave blanks */
+ if (!call->name)
+ continue;
+ event_create_dir(call, d_events);
+ }
+
+ return 0;
+}
+fs_initcall(event_trace_init);
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
new file mode 100644
index 00000000000..e03cbf1e38f
--- /dev/null
+++ b/kernel/trace/trace_events_filter.c
@@ -0,0 +1,433 @@
+/*
+ * trace_events_filter - generic event filtering
+ *
+ * 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) 2009 Tom Zanussi <tzanussi@gmail.com>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/ctype.h>
+
+#include "trace.h"
+#include "trace_output.h"
+
+static int filter_pred_64(struct filter_pred *pred, void *event)
+{
+ u64 *addr = (u64 *)(event + pred->offset);
+ u64 val = (u64)pred->val;
+ int match;
+
+ match = (val == *addr) ^ pred->not;
+
+ return match;
+}
+
+static int filter_pred_32(struct filter_pred *pred, void *event)
+{
+ u32 *addr = (u32 *)(event + pred->offset);
+ u32 val = (u32)pred->val;
+ int match;
+
+ match = (val == *addr) ^ pred->not;
+
+ return match;
+}
+
+static int filter_pred_16(struct filter_pred *pred, void *event)
+{
+ u16 *addr = (u16 *)(event + pred->offset);
+ u16 val = (u16)pred->val;
+ int match;
+
+ match = (val == *addr) ^ pred->not;
+
+ return match;
+}
+
+static int filter_pred_8(struct filter_pred *pred, void *event)
+{
+ u8 *addr = (u8 *)(event + pred->offset);
+ u8 val = (u8)pred->val;
+ int match;
+
+ match = (val == *addr) ^ pred->not;
+
+ return match;
+}
+
+static int filter_pred_string(struct filter_pred *pred, void *event)
+{
+ char *addr = (char *)(event + pred->offset);
+ int cmp, match;
+
+ cmp = strncmp(addr, pred->str_val, pred->str_len);
+
+ match = (!cmp) ^ pred->not;
+
+ return match;
+}
+
+/* return 1 if event matches, 0 otherwise (discard) */
+int filter_match_preds(struct ftrace_event_call *call, void *rec)
+{
+ int i, matched, and_failed = 0;
+ struct filter_pred *pred;
+
+ for (i = 0; i < MAX_FILTER_PRED; i++) {
+ if (call->preds[i]) {
+ pred = call->preds[i];
+ if (and_failed && !pred->or)
+ continue;
+ matched = pred->fn(pred, rec);
+ if (!matched && !pred->or) {
+ and_failed = 1;
+ continue;
+ } else if (matched && pred->or)
+ return 1;
+ } else
+ break;
+ }
+
+ if (and_failed)
+ return 0;
+
+ return 1;
+}
+
+void filter_print_preds(struct filter_pred **preds, struct trace_seq *s)
+{
+ char *field_name;
+ struct filter_pred *pred;
+ int i;
+
+ if (!preds) {
+ trace_seq_printf(s, "none\n");
+ return;
+ }
+
+ for (i = 0; i < MAX_FILTER_PRED; i++) {
+ if (preds[i]) {
+ pred = preds[i];
+ field_name = pred->field_name;
+ if (i)
+ trace_seq_printf(s, pred->or ? "|| " : "&& ");
+ trace_seq_printf(s, "%s ", field_name);
+ trace_seq_printf(s, pred->not ? "!= " : "== ");
+ if (pred->str_val)
+ trace_seq_printf(s, "%s\n", pred->str_val);
+ else
+ trace_seq_printf(s, "%llu\n", pred->val);
+ } else
+ break;
+ }
+}
+
+static struct ftrace_event_field *
+find_event_field(struct ftrace_event_call *call, char *name)
+{
+ struct ftrace_event_field *field;
+
+ list_for_each_entry(field, &call->fields, link) {
+ if (!strcmp(field->name, name))
+ return field;
+ }
+
+ return NULL;
+}
+
+void filter_free_pred(struct filter_pred *pred)
+{
+ if (!pred)
+ return;
+
+ kfree(pred->field_name);
+ kfree(pred->str_val);
+ kfree(pred);
+}
+
+void filter_free_preds(struct ftrace_event_call *call)
+{
+ int i;
+
+ if (call->preds) {
+ for (i = 0; i < MAX_FILTER_PRED; i++)
+ filter_free_pred(call->preds[i]);
+ kfree(call->preds);
+ call->preds = NULL;
+ }
+}
+
+void filter_free_subsystem_preds(struct event_subsystem *system)
+{
+ struct ftrace_event_call *call = __start_ftrace_events;
+ int i;
+
+ if (system->preds) {
+ for (i = 0; i < MAX_FILTER_PRED; i++)
+ filter_free_pred(system->preds[i]);
+ kfree(system->preds);
+ system->preds = NULL;
+ }
+
+ events_for_each(call) {
+ if (!call->name || !call->regfunc)
+ continue;
+
+ if (!strcmp(call->system, system->name))
+ filter_free_preds(call);
+ }
+}
+
+static int __filter_add_pred(struct ftrace_event_call *call,
+ struct filter_pred *pred)
+{
+ int i;
+
+ if (call->preds && !pred->compound)
+ filter_free_preds(call);
+
+ if (!call->preds) {
+ call->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred),
+ GFP_KERNEL);
+ if (!call->preds)
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < MAX_FILTER_PRED; i++) {
+ if (!call->preds[i]) {
+ call->preds[i] = pred;
+ return 0;
+ }
+ }
+
+ return -ENOSPC;
+}
+
+static int is_string_field(const char *type)
+{
+ if (strchr(type, '[') && strstr(type, "char"))
+ return 1;
+
+ return 0;
+}
+
+int filter_add_pred(struct ftrace_event_call *call, struct filter_pred *pred)
+{
+ struct ftrace_event_field *field;
+
+ field = find_event_field(call, pred->field_name);
+ if (!field)
+ return -EINVAL;
+
+ pred->offset = field->offset;
+
+ if (is_string_field(field->type)) {
+ if (!pred->str_val)
+ return -EINVAL;
+ pred->fn = filter_pred_string;
+ pred->str_len = field->size;
+ return __filter_add_pred(call, pred);
+ } else {
+ if (pred->str_val)
+ return -EINVAL;
+ }
+
+ switch (field->size) {
+ case 8:
+ pred->fn = filter_pred_64;
+ break;
+ case 4:
+ pred->fn = filter_pred_32;
+ break;
+ case 2:
+ pred->fn = filter_pred_16;
+ break;
+ case 1:
+ pred->fn = filter_pred_8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return __filter_add_pred(call, pred);
+}
+
+static struct filter_pred *copy_pred(struct filter_pred *pred)
+{
+ struct filter_pred *new_pred = kmalloc(sizeof(*pred), GFP_KERNEL);
+ if (!new_pred)
+ return NULL;
+
+ memcpy(new_pred, pred, sizeof(*pred));
+
+ if (pred->field_name) {
+ new_pred->field_name = kstrdup(pred->field_name, GFP_KERNEL);
+ if (!new_pred->field_name) {
+ kfree(new_pred);
+ return NULL;
+ }
+ }
+
+ if (pred->str_val) {
+ new_pred->str_val = kstrdup(pred->str_val, GFP_KERNEL);
+ if (!new_pred->str_val) {
+ filter_free_pred(new_pred);
+ return NULL;
+ }
+ }
+
+ return new_pred;
+}
+
+int filter_add_subsystem_pred(struct event_subsystem *system,
+ struct filter_pred *pred)
+{
+ struct ftrace_event_call *call = __start_ftrace_events;
+ struct filter_pred *event_pred;
+ int i;
+
+ if (system->preds && !pred->compound)
+ filter_free_subsystem_preds(system);
+
+ if (!system->preds) {
+ system->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred),
+ GFP_KERNEL);
+ if (!system->preds)
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < MAX_FILTER_PRED; i++) {
+ if (!system->preds[i]) {
+ system->preds[i] = pred;
+ break;
+ }
+ }
+
+ if (i == MAX_FILTER_PRED)
+ return -ENOSPC;
+
+ events_for_each(call) {
+ int err;
+
+ if (!call->name || !call->regfunc)
+ continue;
+
+ if (strcmp(call->system, system->name))
+ continue;
+
+ if (!find_event_field(call, pred->field_name))
+ continue;
+
+ event_pred = copy_pred(pred);
+ if (!event_pred)
+ goto oom;
+
+ err = filter_add_pred(call, event_pred);
+ if (err)
+ filter_free_pred(event_pred);
+ if (err == -ENOMEM)
+ goto oom;
+ }
+
+ return 0;
+
+oom:
+ system->preds[i] = NULL;
+ return -ENOMEM;
+}
+
+int filter_parse(char **pbuf, struct filter_pred *pred)
+{
+ char *tmp, *tok, *val_str = NULL;
+ int tok_n = 0;
+
+ /* field ==/!= number, or/and field ==/!= number, number */
+ while ((tok = strsep(pbuf, " \n"))) {
+ if (tok_n == 0) {
+ if (!strcmp(tok, "0")) {
+ pred->clear = 1;
+ return 0;
+ } else if (!strcmp(tok, "&&")) {
+ pred->or = 0;
+ pred->compound = 1;
+ } else if (!strcmp(tok, "||")) {
+ pred->or = 1;
+ pred->compound = 1;
+ } else
+ pred->field_name = tok;
+ tok_n = 1;
+ continue;
+ }
+ if (tok_n == 1) {
+ if (!pred->field_name)
+ pred->field_name = tok;
+ else if (!strcmp(tok, "!="))
+ pred->not = 1;
+ else if (!strcmp(tok, "=="))
+ pred->not = 0;
+ else {
+ pred->field_name = NULL;
+ return -EINVAL;
+ }
+ tok_n = 2;
+ continue;
+ }
+ if (tok_n == 2) {
+ if (pred->compound) {
+ if (!strcmp(tok, "!="))
+ pred->not = 1;
+ else if (!strcmp(tok, "=="))
+ pred->not = 0;
+ else {
+ pred->field_name = NULL;
+ return -EINVAL;
+ }
+ } else {
+ val_str = tok;
+ break; /* done */
+ }
+ tok_n = 3;
+ continue;
+ }
+ if (tok_n == 3) {
+ val_str = tok;
+ break; /* done */
+ }
+ }
+
+ if (!val_str) {
+ pred->field_name = NULL;
+ return -EINVAL;
+ }
+
+ pred->field_name = kstrdup(pred->field_name, GFP_KERNEL);
+ if (!pred->field_name)
+ return -ENOMEM;
+
+ pred->val = simple_strtoull(val_str, &tmp, 0);
+ if (tmp == val_str) {
+ pred->str_val = kstrdup(val_str, GFP_KERNEL);
+ if (!pred->str_val)
+ return -ENOMEM;
+ } else if (*tmp != '\0')
+ return -EINVAL;
+
+ return 0;
+}
+
+
diff --git a/kernel/trace/trace_events_stage_1.h b/kernel/trace/trace_events_stage_1.h
new file mode 100644
index 00000000000..38985f9b379
--- /dev/null
+++ b/kernel/trace/trace_events_stage_1.h
@@ -0,0 +1,39 @@
+/*
+ * Stage 1 of the trace events.
+ *
+ * Override the macros in <trace/trace_event_types.h> to include the following:
+ *
+ * struct ftrace_raw_<call> {
+ * struct trace_entry ent;
+ * <type> <item>;
+ * <type2> <item2>[<len>];
+ * [...]
+ * };
+ *
+ * The <type> <item> is created by the __field(type, item) macro or
+ * the __array(type2, item2, len) macro.
+ * We simply do "type item;", and that will create the fields
+ * in the structure.
+ */
+
+#undef TRACE_FORMAT
+#define TRACE_FORMAT(call, proto, args, fmt)
+
+#undef __array
+#define __array(type, item, len) type item[len];
+
+#undef __field
+#define __field(type, item) type item;
+
+#undef TP_STRUCT__entry
+#define TP_STRUCT__entry(args...) args
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
+ struct ftrace_raw_##name { \
+ struct trace_entry ent; \
+ tstruct \
+ }; \
+ static struct ftrace_event_call event_##name
+
+#include <trace/trace_event_types.h>
diff --git a/kernel/trace/trace_events_stage_2.h b/kernel/trace/trace_events_stage_2.h
new file mode 100644
index 00000000000..d363c6672c6
--- /dev/null
+++ b/kernel/trace/trace_events_stage_2.h
@@ -0,0 +1,176 @@
+/*
+ * Stage 2 of the trace events.
+ *
+ * Override the macros in <trace/trace_event_types.h> to include the following:
+ *
+ * enum print_line_t
+ * ftrace_raw_output_<call>(struct trace_iterator *iter, int flags)
+ * {
+ * struct trace_seq *s = &iter->seq;
+ * struct ftrace_raw_<call> *field; <-- defined in stage 1
+ * struct trace_entry *entry;
+ * int ret;
+ *
+ * entry = iter->ent;
+ *
+ * if (entry->type != event_<call>.id) {
+ * WARN_ON_ONCE(1);
+ * return TRACE_TYPE_UNHANDLED;
+ * }
+ *
+ * field = (typeof(field))entry;
+ *
+ * ret = trace_seq_printf(s, <TP_printk> "\n");
+ * if (!ret)
+ * return TRACE_TYPE_PARTIAL_LINE;
+ *
+ * return TRACE_TYPE_HANDLED;
+ * }
+ *
+ * This is the method used to print the raw event to the trace
+ * output format. Note, this is not needed if the data is read
+ * in binary.
+ */
+
+#undef __entry
+#define __entry field
+
+#undef TP_printk
+#define TP_printk(fmt, args...) fmt "\n", args
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
+enum print_line_t \
+ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
+{ \
+ struct trace_seq *s = &iter->seq; \
+ struct ftrace_raw_##call *field; \
+ struct trace_entry *entry; \
+ int ret; \
+ \
+ entry = iter->ent; \
+ \
+ if (entry->type != event_##call.id) { \
+ WARN_ON_ONCE(1); \
+ return TRACE_TYPE_UNHANDLED; \
+ } \
+ \
+ field = (typeof(field))entry; \
+ \
+ ret = trace_seq_printf(s, #call ": " print); \
+ if (!ret) \
+ return TRACE_TYPE_PARTIAL_LINE; \
+ \
+ return TRACE_TYPE_HANDLED; \
+}
+
+#include <trace/trace_event_types.h>
+
+/*
+ * Setup the showing format of trace point.
+ *
+ * int
+ * ftrace_format_##call(struct trace_seq *s)
+ * {
+ * struct ftrace_raw_##call field;
+ * int ret;
+ *
+ * ret = trace_seq_printf(s, #type " " #item ";"
+ * " offset:%u; size:%u;\n",
+ * offsetof(struct ftrace_raw_##call, item),
+ * sizeof(field.type));
+ *
+ * }
+ */
+
+#undef TP_STRUCT__entry
+#define TP_STRUCT__entry(args...) args
+
+#undef __field
+#define __field(type, item) \
+ ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
+ "offset:%u;\tsize:%u;\n", \
+ (unsigned int)offsetof(typeof(field), item), \
+ (unsigned int)sizeof(field.item)); \
+ if (!ret) \
+ return 0;
+
+#undef __array
+#define __array(type, item, len) \
+ ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
+ "offset:%u;\tsize:%u;\n", \
+ (unsigned int)offsetof(typeof(field), item), \
+ (unsigned int)sizeof(field.item)); \
+ if (!ret) \
+ return 0;
+
+#undef __entry
+#define __entry REC
+
+#undef TP_printk
+#define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args)
+
+#undef TP_fast_assign
+#define TP_fast_assign(args...) args
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(call, proto, args, tstruct, func, print) \
+static int \
+ftrace_format_##call(struct trace_seq *s) \
+{ \
+ struct ftrace_raw_##call field; \
+ int ret; \
+ \
+ tstruct; \
+ \
+ trace_seq_printf(s, "\nprint fmt: " print); \
+ \
+ return ret; \
+}
+
+#include <trace/trace_event_types.h>
+
+#undef __field
+#define __field(type, item) \
+ ret = trace_define_field(event_call, #type, #item, \
+ offsetof(typeof(field), item), \
+ sizeof(field.item)); \
+ if (ret) \
+ return ret;
+
+#undef __array
+#define __array(type, item, len) \
+ ret = trace_define_field(event_call, #type "[" #len "]", #item, \
+ offsetof(typeof(field), item), \
+ sizeof(field.item)); \
+ if (ret) \
+ return ret;
+
+#define __common_field(type, item) \
+ ret = trace_define_field(event_call, #type, "common_" #item, \
+ offsetof(typeof(field.ent), item), \
+ sizeof(field.ent.item)); \
+ if (ret) \
+ return ret;
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(call, proto, args, tstruct, func, print) \
+int \
+ftrace_define_fields_##call(void) \
+{ \
+ struct ftrace_raw_##call field; \
+ struct ftrace_event_call *event_call = &event_##call; \
+ int ret; \
+ \
+ __common_field(unsigned char, type); \
+ __common_field(unsigned char, flags); \
+ __common_field(unsigned char, preempt_count); \
+ __common_field(int, pid); \
+ __common_field(int, tgid); \
+ \
+ tstruct; \
+ \
+ return ret; \
+}
+
+#include <trace/trace_event_types.h>
diff --git a/kernel/trace/trace_events_stage_3.h b/kernel/trace/trace_events_stage_3.h
new file mode 100644
index 00000000000..9d2fa78cecc
--- /dev/null
+++ b/kernel/trace/trace_events_stage_3.h
@@ -0,0 +1,281 @@
+/*
+ * Stage 3 of the trace events.
+ *
+ * Override the macros in <trace/trace_event_types.h> to include the following:
+ *
+ * static void ftrace_event_<call>(proto)
+ * {
+ * event_trace_printk(_RET_IP_, "<call>: " <fmt>);
+ * }
+ *
+ * static int ftrace_reg_event_<call>(void)
+ * {
+ * int ret;
+ *
+ * ret = register_trace_<call>(ftrace_event_<call>);
+ * if (!ret)
+ * pr_info("event trace: Could not activate trace point "
+ * "probe to <call>");
+ * return ret;
+ * }
+ *
+ * static void ftrace_unreg_event_<call>(void)
+ * {
+ * unregister_trace_<call>(ftrace_event_<call>);
+ * }
+ *
+ * For those macros defined with TRACE_FORMAT:
+ *
+ * static struct ftrace_event_call __used
+ * __attribute__((__aligned__(4)))
+ * __attribute__((section("_ftrace_events"))) event_<call> = {
+ * .name = "<call>",
+ * .regfunc = ftrace_reg_event_<call>,
+ * .unregfunc = ftrace_unreg_event_<call>,
+ * }
+ *
+ *
+ * For those macros defined with TRACE_EVENT:
+ *
+ * static struct ftrace_event_call event_<call>;
+ *
+ * static void ftrace_raw_event_<call>(proto)
+ * {
+ * struct ring_buffer_event *event;
+ * struct ftrace_raw_<call> *entry; <-- defined in stage 1
+ * unsigned long irq_flags;
+ * int pc;
+ *
+ * local_save_flags(irq_flags);
+ * pc = preempt_count();
+ *
+ * event = trace_current_buffer_lock_reserve(event_<call>.id,
+ * sizeof(struct ftrace_raw_<call>),
+ * irq_flags, pc);
+ * if (!event)
+ * return;
+ * entry = ring_buffer_event_data(event);
+ *
+ * <assign>; <-- Here we assign the entries by the __field and
+ * __array macros.
+ *
+ * trace_current_buffer_unlock_commit(event, irq_flags, pc);
+ * }
+ *
+ * static int ftrace_raw_reg_event_<call>(void)
+ * {
+ * int ret;
+ *
+ * ret = register_trace_<call>(ftrace_raw_event_<call>);
+ * if (!ret)
+ * pr_info("event trace: Could not activate trace point "
+ * "probe to <call>");
+ * return ret;
+ * }
+ *
+ * static void ftrace_unreg_event_<call>(void)
+ * {
+ * unregister_trace_<call>(ftrace_raw_event_<call>);
+ * }
+ *
+ * static struct trace_event ftrace_event_type_<call> = {
+ * .trace = ftrace_raw_output_<call>, <-- stage 2
+ * };
+ *
+ * static int ftrace_raw_init_event_<call>(void)
+ * {
+ * int id;
+ *
+ * id = register_ftrace_event(&ftrace_event_type_<call>);
+ * if (!id)
+ * return -ENODEV;
+ * event_<call>.id = id;
+ * return 0;
+ * }
+ *
+ * static struct ftrace_event_call __used
+ * __attribute__((__aligned__(4)))
+ * __attribute__((section("_ftrace_events"))) event_<call> = {
+ * .name = "<call>",
+ * .system = "<system>",
+ * .raw_init = ftrace_raw_init_event_<call>,
+ * .regfunc = ftrace_reg_event_<call>,
+ * .unregfunc = ftrace_unreg_event_<call>,
+ * .show_format = ftrace_format_<call>,
+ * }
+ *
+ */
+
+#undef TP_FMT
+#define TP_FMT(fmt, args...) fmt "\n", ##args
+
+#ifdef CONFIG_EVENT_PROFILE
+#define _TRACE_PROFILE(call, proto, args) \
+static void ftrace_profile_##call(proto) \
+{ \
+ extern void perf_tpcounter_event(int); \
+ perf_tpcounter_event(event_##call.id); \
+} \
+ \
+static int ftrace_profile_enable_##call(struct ftrace_event_call *call) \
+{ \
+ int ret = 0; \
+ \
+ if (!atomic_inc_return(&call->profile_count)) \
+ ret = register_trace_##call(ftrace_profile_##call); \
+ \
+ return ret; \
+} \
+ \
+static void ftrace_profile_disable_##call(struct ftrace_event_call *call) \
+{ \
+ if (atomic_add_negative(-1, &call->profile_count)) \
+ unregister_trace_##call(ftrace_profile_##call); \
+}
+
+#define _TRACE_PROFILE_INIT(call) \
+ .profile_count = ATOMIC_INIT(-1), \
+ .profile_enable = ftrace_profile_enable_##call, \
+ .profile_disable = ftrace_profile_disable_##call,
+
+#else
+#define _TRACE_PROFILE(call, proto, args)
+#define _TRACE_PROFILE_INIT(call)
+#endif
+
+#define _TRACE_FORMAT(call, proto, args, fmt) \
+static void ftrace_event_##call(proto) \
+{ \
+ event_trace_printk(_RET_IP_, #call ": " fmt); \
+} \
+ \
+static int ftrace_reg_event_##call(void) \
+{ \
+ int ret; \
+ \
+ ret = register_trace_##call(ftrace_event_##call); \
+ if (ret) \
+ pr_info("event trace: Could not activate trace point " \
+ "probe to " #call "\n"); \
+ return ret; \
+} \
+ \
+static void ftrace_unreg_event_##call(void) \
+{ \
+ unregister_trace_##call(ftrace_event_##call); \
+} \
+ \
+static struct ftrace_event_call event_##call; \
+ \
+static int ftrace_init_event_##call(void) \
+{ \
+ int id; \
+ \
+ id = register_ftrace_event(NULL); \
+ if (!id) \
+ return -ENODEV; \
+ event_##call.id = id; \
+ return 0; \
+}
+
+#undef TRACE_FORMAT
+#define TRACE_FORMAT(call, proto, args, fmt) \
+_TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt)) \
+_TRACE_PROFILE(call, PARAMS(proto), PARAMS(args)) \
+static struct ftrace_event_call __used \
+__attribute__((__aligned__(4))) \
+__attribute__((section("_ftrace_events"))) event_##call = { \
+ .name = #call, \
+ .system = __stringify(TRACE_SYSTEM), \
+ .raw_init = ftrace_init_event_##call, \
+ .regfunc = ftrace_reg_event_##call, \
+ .unregfunc = ftrace_unreg_event_##call, \
+ _TRACE_PROFILE_INIT(call) \
+}
+
+#undef __entry
+#define __entry entry
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
+_TRACE_PROFILE(call, PARAMS(proto), PARAMS(args)) \
+ \
+static struct ftrace_event_call event_##call; \
+ \
+static void ftrace_raw_event_##call(proto) \
+{ \
+ struct ftrace_event_call *call = &event_##call; \
+ struct ring_buffer_event *event; \
+ struct ftrace_raw_##call *entry; \
+ unsigned long irq_flags; \
+ int pc; \
+ \
+ local_save_flags(irq_flags); \
+ pc = preempt_count(); \
+ \
+ event = trace_current_buffer_lock_reserve(event_##call.id, \
+ sizeof(struct ftrace_raw_##call), \
+ irq_flags, pc); \
+ if (!event) \
+ return; \
+ entry = ring_buffer_event_data(event); \
+ \
+ assign; \
+ \
+ if (call->preds && !filter_match_preds(call, entry)) \
+ ring_buffer_event_discard(event); \
+ \
+ trace_nowake_buffer_unlock_commit(event, irq_flags, pc); \
+ \
+} \
+ \
+static int ftrace_raw_reg_event_##call(void) \
+{ \
+ int ret; \
+ \
+ ret = register_trace_##call(ftrace_raw_event_##call); \
+ if (ret) \
+ pr_info("event trace: Could not activate trace point " \
+ "probe to " #call "\n"); \
+ return ret; \
+} \
+ \
+static void ftrace_raw_unreg_event_##call(void) \
+{ \
+ unregister_trace_##call(ftrace_raw_event_##call); \
+} \
+ \
+static struct trace_event ftrace_event_type_##call = { \
+ .trace = ftrace_raw_output_##call, \
+}; \
+ \
+static int ftrace_raw_init_event_##call(void) \
+{ \
+ int id; \
+ \
+ id = register_ftrace_event(&ftrace_event_type_##call); \
+ if (!id) \
+ return -ENODEV; \
+ event_##call.id = id; \
+ INIT_LIST_HEAD(&event_##call.fields); \
+ return 0; \
+} \
+ \
+static struct ftrace_event_call __used \
+__attribute__((__aligned__(4))) \
+__attribute__((section("_ftrace_events"))) event_##call = { \
+ .name = #call, \
+ .system = __stringify(TRACE_SYSTEM), \
+ .raw_init = ftrace_raw_init_event_##call, \
+ .regfunc = ftrace_raw_reg_event_##call, \
+ .unregfunc = ftrace_raw_unreg_event_##call, \
+ .show_format = ftrace_format_##call, \
+ .define_fields = ftrace_define_fields_##call, \
+ _TRACE_PROFILE_INIT(call) \
+}
+
+#include <trace/trace_event_types.h>
+
+#undef _TRACE_PROFILE
+#undef _TRACE_PROFILE_INIT
+
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
new file mode 100644
index 00000000000..07a22c33ebf
--- /dev/null
+++ b/kernel/trace/trace_export.c
@@ -0,0 +1,102 @@
+/*
+ * trace_export.c - export basic ftrace utilities to user space
+ *
+ * Copyright (C) 2009 Steven Rostedt <srostedt@redhat.com>
+ */
+#include <linux/stringify.h>
+#include <linux/kallsyms.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/ftrace.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+
+#include "trace_output.h"
+
+
+#undef TRACE_STRUCT
+#define TRACE_STRUCT(args...) args
+
+#undef TRACE_FIELD
+#define TRACE_FIELD(type, item, assign) \
+ ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
+ "offset:%u;\tsize:%u;\n", \
+ (unsigned int)offsetof(typeof(field), item), \
+ (unsigned int)sizeof(field.item)); \
+ if (!ret) \
+ return 0;
+
+
+#undef TRACE_FIELD_SPECIAL
+#define TRACE_FIELD_SPECIAL(type_item, item, cmd) \
+ ret = trace_seq_printf(s, "\tfield special:" #type_item ";\t" \
+ "offset:%u;\tsize:%u;\n", \
+ (unsigned int)offsetof(typeof(field), item), \
+ (unsigned int)sizeof(field.item)); \
+ if (!ret) \
+ return 0;
+
+#undef TRACE_FIELD_ZERO_CHAR
+#define TRACE_FIELD_ZERO_CHAR(item) \
+ ret = trace_seq_printf(s, "\tfield:char " #item ";\t" \
+ "offset:%u;\tsize:0;\n", \
+ (unsigned int)offsetof(typeof(field), item)); \
+ if (!ret) \
+ return 0;
+
+
+#undef TP_RAW_FMT
+#define TP_RAW_FMT(args...) args
+
+#undef TRACE_EVENT_FORMAT
+#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \
+static int \
+ftrace_format_##call(struct trace_seq *s) \
+{ \
+ struct args field; \
+ int ret; \
+ \
+ tstruct; \
+ \
+ trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt); \
+ \
+ return ret; \
+}
+
+#include "trace_event_types.h"
+
+#undef TRACE_ZERO_CHAR
+#define TRACE_ZERO_CHAR(arg)
+
+#undef TRACE_FIELD
+#define TRACE_FIELD(type, item, assign)\
+ entry->item = assign;
+
+#undef TRACE_FIELD
+#define TRACE_FIELD(type, item, assign)\
+ entry->item = assign;
+
+#undef TP_CMD
+#define TP_CMD(cmd...) cmd
+
+#undef TRACE_ENTRY
+#define TRACE_ENTRY entry
+
+#undef TRACE_FIELD_SPECIAL
+#define TRACE_FIELD_SPECIAL(type_item, item, cmd) \
+ cmd;
+
+#undef TRACE_EVENT_FORMAT
+#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \
+ \
+static struct ftrace_event_call __used \
+__attribute__((__aligned__(4))) \
+__attribute__((section("_ftrace_events"))) event_##call = { \
+ .name = #call, \
+ .id = proto, \
+ .system = __stringify(TRACE_SYSTEM), \
+ .show_format = ftrace_format_##call, \
+}
+#include "trace_event_types.h"
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 9236d7e25a1..c9a0b7df44f 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -9,6 +9,7 @@
* Copyright (C) 2004-2006 Ingo Molnar
* Copyright (C) 2004 William Lee Irwin III
*/
+#include <linux/ring_buffer.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/ftrace.h>
@@ -16,52 +17,388 @@
#include "trace.h"
-static void start_function_trace(struct trace_array *tr)
+/* function tracing enabled */
+static int ftrace_function_enabled;
+
+static struct trace_array *func_trace;
+
+static void tracing_start_function_trace(void);
+static void tracing_stop_function_trace(void);
+
+static int function_trace_init(struct trace_array *tr)
{
+ func_trace = tr;
tr->cpu = get_cpu();
- tracing_reset_online_cpus(tr);
put_cpu();
tracing_start_cmdline_record();
tracing_start_function_trace();
+ return 0;
}
-static void stop_function_trace(struct trace_array *tr)
+static void function_trace_reset(struct trace_array *tr)
{
tracing_stop_function_trace();
tracing_stop_cmdline_record();
}
-static int function_trace_init(struct trace_array *tr)
+static void function_trace_start(struct trace_array *tr)
{
- start_function_trace(tr);
- return 0;
+ tracing_reset_online_cpus(tr);
}
-static void function_trace_reset(struct trace_array *tr)
+static void
+function_trace_call_preempt_only(unsigned long ip, unsigned long parent_ip)
+{
+ struct trace_array *tr = func_trace;
+ struct trace_array_cpu *data;
+ unsigned long flags;
+ long disabled;
+ int cpu, resched;
+ int pc;
+
+ if (unlikely(!ftrace_function_enabled))
+ return;
+
+ pc = preempt_count();
+ resched = ftrace_preempt_disable();
+ 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, ip, parent_ip, flags, pc);
+
+ atomic_dec(&data->disabled);
+ ftrace_preempt_enable(resched);
+}
+
+static void
+function_trace_call(unsigned long ip, unsigned long parent_ip)
{
- stop_function_trace(tr);
+ struct trace_array *tr = func_trace;
+ struct trace_array_cpu *data;
+ unsigned long flags;
+ long disabled;
+ int cpu;
+ int pc;
+
+ if (unlikely(!ftrace_function_enabled))
+ return;
+
+ /*
+ * Need to use raw, since this must be called before the
+ * recursive protection is performed.
+ */
+ local_irq_save(flags);
+ cpu = raw_smp_processor_id();
+ data = tr->data[cpu];
+ disabled = atomic_inc_return(&data->disabled);
+
+ if (likely(disabled == 1)) {
+ pc = preempt_count();
+ trace_function(tr, ip, parent_ip, flags, pc);
+ }
+
+ atomic_dec(&data->disabled);
+ local_irq_restore(flags);
}
-static void function_trace_start(struct trace_array *tr)
+static void
+function_stack_trace_call(unsigned long ip, unsigned long parent_ip)
{
- tracing_reset_online_cpus(tr);
+ struct trace_array *tr = func_trace;
+ struct trace_array_cpu *data;
+ unsigned long flags;
+ long disabled;
+ int cpu;
+ int pc;
+
+ if (unlikely(!ftrace_function_enabled))
+ return;
+
+ /*
+ * Need to use raw, since this must be called before the
+ * recursive protection is performed.
+ */
+ local_irq_save(flags);
+ cpu = raw_smp_processor_id();
+ data = tr->data[cpu];
+ disabled = atomic_inc_return(&data->disabled);
+
+ if (likely(disabled == 1)) {
+ pc = preempt_count();
+ trace_function(tr, ip, parent_ip, flags, pc);
+ /*
+ * skip over 5 funcs:
+ * __ftrace_trace_stack,
+ * __trace_stack,
+ * function_stack_trace_call
+ * ftrace_list_func
+ * ftrace_call
+ */
+ __trace_stack(tr, flags, 5, pc);
+ }
+
+ atomic_dec(&data->disabled);
+ local_irq_restore(flags);
+}
+
+
+static struct ftrace_ops trace_ops __read_mostly =
+{
+ .func = function_trace_call,
+};
+
+static struct ftrace_ops trace_stack_ops __read_mostly =
+{
+ .func = function_stack_trace_call,
+};
+
+/* Our two options */
+enum {
+ TRACE_FUNC_OPT_STACK = 0x1,
+};
+
+static struct tracer_opt func_opts[] = {
+#ifdef CONFIG_STACKTRACE
+ { TRACER_OPT(func_stack_trace, TRACE_FUNC_OPT_STACK) },
+#endif
+ { } /* Always set a last empty entry */
+};
+
+static struct tracer_flags func_flags = {
+ .val = 0, /* By default: all flags disabled */
+ .opts = func_opts
+};
+
+static void tracing_start_function_trace(void)
+{
+ ftrace_function_enabled = 0;
+
+ if (trace_flags & TRACE_ITER_PREEMPTONLY)
+ trace_ops.func = function_trace_call_preempt_only;
+ else
+ trace_ops.func = function_trace_call;
+
+ if (func_flags.val & TRACE_FUNC_OPT_STACK)
+ register_ftrace_function(&trace_stack_ops);
+ else
+ register_ftrace_function(&trace_ops);
+
+ ftrace_function_enabled = 1;
+}
+
+static void tracing_stop_function_trace(void)
+{
+ ftrace_function_enabled = 0;
+ /* OK if they are not registered */
+ unregister_ftrace_function(&trace_stack_ops);
+ unregister_ftrace_function(&trace_ops);
+}
+
+static int func_set_flag(u32 old_flags, u32 bit, int set)
+{
+ if (bit == TRACE_FUNC_OPT_STACK) {
+ /* do nothing if already set */
+ if (!!set == !!(func_flags.val & TRACE_FUNC_OPT_STACK))
+ return 0;
+
+ if (set) {
+ unregister_ftrace_function(&trace_ops);
+ register_ftrace_function(&trace_stack_ops);
+ } else {
+ unregister_ftrace_function(&trace_stack_ops);
+ register_ftrace_function(&trace_ops);
+ }
+
+ return 0;
+ }
+
+ return -EINVAL;
}
static struct tracer function_trace __read_mostly =
{
- .name = "function",
- .init = function_trace_init,
- .reset = function_trace_reset,
- .start = function_trace_start,
+ .name = "function",
+ .init = function_trace_init,
+ .reset = function_trace_reset,
+ .start = function_trace_start,
+ .wait_pipe = poll_wait_pipe,
+ .flags = &func_flags,
+ .set_flag = func_set_flag,
#ifdef CONFIG_FTRACE_SELFTEST
- .selftest = trace_selftest_startup_function,
+ .selftest = trace_selftest_startup_function,
#endif
};
+#ifdef CONFIG_DYNAMIC_FTRACE
+static void
+ftrace_traceon(unsigned long ip, unsigned long parent_ip, void **data)
+{
+ long *count = (long *)data;
+
+ if (tracing_is_on())
+ return;
+
+ if (!*count)
+ return;
+
+ if (*count != -1)
+ (*count)--;
+
+ tracing_on();
+}
+
+static void
+ftrace_traceoff(unsigned long ip, unsigned long parent_ip, void **data)
+{
+ long *count = (long *)data;
+
+ if (!tracing_is_on())
+ return;
+
+ if (!*count)
+ return;
+
+ if (*count != -1)
+ (*count)--;
+
+ tracing_off();
+}
+
+static int
+ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
+ struct ftrace_probe_ops *ops, void *data);
+
+static struct ftrace_probe_ops traceon_probe_ops = {
+ .func = ftrace_traceon,
+ .print = ftrace_trace_onoff_print,
+};
+
+static struct ftrace_probe_ops traceoff_probe_ops = {
+ .func = ftrace_traceoff,
+ .print = ftrace_trace_onoff_print,
+};
+
+static int
+ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
+ struct ftrace_probe_ops *ops, void *data)
+{
+ char str[KSYM_SYMBOL_LEN];
+ long count = (long)data;
+
+ kallsyms_lookup(ip, NULL, NULL, NULL, str);
+ seq_printf(m, "%s:", str);
+
+ if (ops == &traceon_probe_ops)
+ seq_printf(m, "traceon");
+ else
+ seq_printf(m, "traceoff");
+
+ if (count == -1)
+ seq_printf(m, ":unlimited\n");
+ else
+ seq_printf(m, ":count=%ld", count);
+ seq_putc(m, '\n');
+
+ return 0;
+}
+
+static int
+ftrace_trace_onoff_unreg(char *glob, char *cmd, char *param)
+{
+ struct ftrace_probe_ops *ops;
+
+ /* we register both traceon and traceoff to this callback */
+ if (strcmp(cmd, "traceon") == 0)
+ ops = &traceon_probe_ops;
+ else
+ ops = &traceoff_probe_ops;
+
+ unregister_ftrace_function_probe_func(glob, ops);
+
+ return 0;
+}
+
+static int
+ftrace_trace_onoff_callback(char *glob, char *cmd, char *param, int enable)
+{
+ struct ftrace_probe_ops *ops;
+ void *count = (void *)-1;
+ char *number;
+ int ret;
+
+ /* hash funcs only work with set_ftrace_filter */
+ if (!enable)
+ return -EINVAL;
+
+ if (glob[0] == '!')
+ return ftrace_trace_onoff_unreg(glob+1, cmd, param);
+
+ /* we register both traceon and traceoff to this callback */
+ if (strcmp(cmd, "traceon") == 0)
+ ops = &traceon_probe_ops;
+ else
+ ops = &traceoff_probe_ops;
+
+ if (!param)
+ goto out_reg;
+
+ number = strsep(&param, ":");
+
+ if (!strlen(number))
+ goto out_reg;
+
+ /*
+ * We use the callback data field (which is a pointer)
+ * as our counter.
+ */
+ ret = strict_strtoul(number, 0, (unsigned long *)&count);
+ if (ret)
+ return ret;
+
+ out_reg:
+ ret = register_ftrace_function_probe(glob, ops, count);
+
+ return ret;
+}
+
+static struct ftrace_func_command ftrace_traceon_cmd = {
+ .name = "traceon",
+ .func = ftrace_trace_onoff_callback,
+};
+
+static struct ftrace_func_command ftrace_traceoff_cmd = {
+ .name = "traceoff",
+ .func = ftrace_trace_onoff_callback,
+};
+
+static int __init init_func_cmd_traceon(void)
+{
+ int ret;
+
+ ret = register_ftrace_command(&ftrace_traceoff_cmd);
+ if (ret)
+ return ret;
+
+ ret = register_ftrace_command(&ftrace_traceon_cmd);
+ if (ret)
+ unregister_ftrace_command(&ftrace_traceoff_cmd);
+ return ret;
+}
+#else
+static inline int init_func_cmd_traceon(void)
+{
+ return 0;
+}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
static __init int init_function_trace(void)
{
+ init_func_cmd_traceon();
return register_tracer(&function_trace);
}
-
device_initcall(init_function_trace);
+
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index dce71a5b51b..d28687e7b3a 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -1,7 +1,7 @@
/*
*
* Function graph tracer.
- * Copyright (c) 2008 Frederic Weisbecker <fweisbec@gmail.com>
+ * Copyright (c) 2008-2009 Frederic Weisbecker <fweisbec@gmail.com>
* Mostly borrowed from function tracer which
* is Copyright (c) Steven Rostedt <srostedt@redhat.com>
*
@@ -12,6 +12,12 @@
#include <linux/fs.h>
#include "trace.h"
+#include "trace_output.h"
+
+struct fgraph_data {
+ pid_t last_pid;
+ int depth;
+};
#define TRACE_GRAPH_INDENT 2
@@ -20,9 +26,11 @@
#define TRACE_GRAPH_PRINT_CPU 0x2
#define TRACE_GRAPH_PRINT_OVERHEAD 0x4
#define TRACE_GRAPH_PRINT_PROC 0x8
+#define TRACE_GRAPH_PRINT_DURATION 0x10
+#define TRACE_GRAPH_PRINT_ABS_TIME 0X20
static struct tracer_opt trace_opts[] = {
- /* Display overruns ? */
+ /* Display overruns? (for self-debug purpose) */
{ TRACER_OPT(funcgraph-overrun, TRACE_GRAPH_PRINT_OVERRUN) },
/* Display CPU ? */
{ TRACER_OPT(funcgraph-cpu, TRACE_GRAPH_PRINT_CPU) },
@@ -30,23 +38,28 @@ static struct tracer_opt trace_opts[] = {
{ TRACER_OPT(funcgraph-overhead, TRACE_GRAPH_PRINT_OVERHEAD) },
/* Display proc name/pid */
{ TRACER_OPT(funcgraph-proc, TRACE_GRAPH_PRINT_PROC) },
+ /* Display duration of execution */
+ { TRACER_OPT(funcgraph-duration, TRACE_GRAPH_PRINT_DURATION) },
+ /* Display absolute time of an entry */
+ { TRACER_OPT(funcgraph-abstime, TRACE_GRAPH_PRINT_ABS_TIME) },
{ } /* Empty entry */
};
static struct tracer_flags tracer_flags = {
/* Don't display overruns and proc by default */
- .val = TRACE_GRAPH_PRINT_CPU | TRACE_GRAPH_PRINT_OVERHEAD,
+ .val = TRACE_GRAPH_PRINT_CPU | TRACE_GRAPH_PRINT_OVERHEAD |
+ TRACE_GRAPH_PRINT_DURATION,
.opts = trace_opts
};
/* pid on the last trace processed */
-static pid_t last_pid[NR_CPUS] = { [0 ... NR_CPUS-1] = -1 };
+
/* Add a function return address to the trace stack on thread info.*/
int
-ftrace_push_return_trace(unsigned long ret, unsigned long long time,
- unsigned long func, int *depth)
+ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth)
{
+ unsigned long long calltime;
int index;
if (!current->ret_stack)
@@ -58,11 +71,13 @@ ftrace_push_return_trace(unsigned long ret, unsigned long long time,
return -EBUSY;
}
+ calltime = trace_clock_local();
+
index = ++current->curr_ret_stack;
barrier();
current->ret_stack[index].ret = ret;
current->ret_stack[index].func = func;
- current->ret_stack[index].calltime = time;
+ current->ret_stack[index].calltime = calltime;
*depth = index;
return 0;
@@ -104,7 +119,7 @@ unsigned long ftrace_return_to_handler(void)
unsigned long ret;
ftrace_pop_return_trace(&trace, &ret);
- trace.rettime = cpu_clock(raw_smp_processor_id());
+ trace.rettime = trace_clock_local();
ftrace_graph_return(&trace);
if (unlikely(!ret)) {
@@ -119,12 +134,7 @@ unsigned long ftrace_return_to_handler(void)
static int graph_trace_init(struct trace_array *tr)
{
- int cpu, ret;
-
- for_each_online_cpu(cpu)
- tracing_reset(tr, cpu);
-
- ret = register_ftrace_graph(&trace_graph_return,
+ int ret = register_ftrace_graph(&trace_graph_return,
&trace_graph_entry);
if (ret)
return ret;
@@ -187,15 +197,15 @@ print_graph_cpu(struct trace_seq *s, int cpu)
static enum print_line_t
print_graph_proc(struct trace_seq *s, pid_t pid)
{
- int i;
- int ret;
- int len;
- char comm[8];
- int spaces = 0;
+ char comm[TASK_COMM_LEN];
/* sign + log10(MAX_INT) + '\0' */
char pid_str[11];
+ int spaces = 0;
+ int ret;
+ int len;
+ int i;
- strncpy(comm, trace_find_cmdline(pid), 7);
+ trace_find_cmdline(pid, comm);
comm[7] = '\0';
sprintf(pid_str, "%d", pid);
@@ -228,17 +238,25 @@ print_graph_proc(struct trace_seq *s, pid_t pid)
/* If the pid changed since the last trace, output this event */
static enum print_line_t
-verif_pid(struct trace_seq *s, pid_t pid, int cpu)
+verif_pid(struct trace_seq *s, pid_t pid, int cpu, struct fgraph_data *data)
{
pid_t prev_pid;
+ pid_t *last_pid;
int ret;
- if (last_pid[cpu] != -1 && last_pid[cpu] == pid)
+ if (!data)
+ return TRACE_TYPE_HANDLED;
+
+ last_pid = &(per_cpu_ptr(data, cpu)->last_pid);
+
+ if (*last_pid == pid)
return TRACE_TYPE_HANDLED;
- prev_pid = last_pid[cpu];
- last_pid[cpu] = pid;
+ prev_pid = *last_pid;
+ *last_pid = pid;
+ if (prev_pid == -1)
+ return TRACE_TYPE_HANDLED;
/*
* Context-switch trace line:
@@ -250,34 +268,34 @@ verif_pid(struct trace_seq *s, pid_t pid, int cpu)
ret = trace_seq_printf(s,
" ------------------------------------------\n");
if (!ret)
- TRACE_TYPE_PARTIAL_LINE;
+ return TRACE_TYPE_PARTIAL_LINE;
ret = print_graph_cpu(s, cpu);
if (ret == TRACE_TYPE_PARTIAL_LINE)
- TRACE_TYPE_PARTIAL_LINE;
+ return TRACE_TYPE_PARTIAL_LINE;
ret = print_graph_proc(s, prev_pid);
if (ret == TRACE_TYPE_PARTIAL_LINE)
- TRACE_TYPE_PARTIAL_LINE;
+ return TRACE_TYPE_PARTIAL_LINE;
ret = trace_seq_printf(s, " => ");
if (!ret)
- TRACE_TYPE_PARTIAL_LINE;
+ return TRACE_TYPE_PARTIAL_LINE;
ret = print_graph_proc(s, pid);
if (ret == TRACE_TYPE_PARTIAL_LINE)
- TRACE_TYPE_PARTIAL_LINE;
+ return TRACE_TYPE_PARTIAL_LINE;
ret = trace_seq_printf(s,
"\n ------------------------------------------\n\n");
if (!ret)
- TRACE_TYPE_PARTIAL_LINE;
+ return TRACE_TYPE_PARTIAL_LINE;
- return ret;
+ return TRACE_TYPE_HANDLED;
}
-static bool
-trace_branch_is_leaf(struct trace_iterator *iter,
+static struct ftrace_graph_ret_entry *
+get_return_for_leaf(struct trace_iterator *iter,
struct ftrace_graph_ent_entry *curr)
{
struct ring_buffer_iter *ring_iter;
@@ -286,65 +304,123 @@ trace_branch_is_leaf(struct trace_iterator *iter,
ring_iter = iter->buffer_iter[iter->cpu];
- if (!ring_iter)
- return false;
-
- event = ring_buffer_iter_peek(ring_iter, NULL);
+ /* First peek to compare current entry and the next one */
+ if (ring_iter)
+ event = ring_buffer_iter_peek(ring_iter, NULL);
+ else {
+ /* We need to consume the current entry to see the next one */
+ ring_buffer_consume(iter->tr->buffer, iter->cpu, NULL);
+ event = ring_buffer_peek(iter->tr->buffer, iter->cpu,
+ NULL);
+ }
if (!event)
- return false;
+ return NULL;
next = ring_buffer_event_data(event);
if (next->ent.type != TRACE_GRAPH_RET)
- return false;
+ return NULL;
if (curr->ent.pid != next->ent.pid ||
curr->graph_ent.func != next->ret.func)
- return false;
+ return NULL;
+
+ /* this is a leaf, now advance the iterator */
+ if (ring_iter)
+ ring_buffer_read(ring_iter, NULL);
+
+ return next;
+}
+
+/* Signal a overhead of time execution to the output */
+static int
+print_graph_overhead(unsigned long long duration, struct trace_seq *s)
+{
+ /* If duration disappear, we don't need anything */
+ if (!(tracer_flags.val & TRACE_GRAPH_PRINT_DURATION))
+ return 1;
+
+ /* Non nested entry or return */
+ if (duration == -1)
+ return trace_seq_printf(s, " ");
+
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
+ /* Duration exceeded 100 msecs */
+ if (duration > 100000ULL)
+ return trace_seq_printf(s, "! ");
+
+ /* Duration exceeded 10 msecs */
+ if (duration > 10000ULL)
+ return trace_seq_printf(s, "+ ");
+ }
+
+ return trace_seq_printf(s, " ");
+}
+
+static int print_graph_abs_time(u64 t, struct trace_seq *s)
+{
+ unsigned long usecs_rem;
+
+ usecs_rem = do_div(t, NSEC_PER_SEC);
+ usecs_rem /= 1000;
- return true;
+ return trace_seq_printf(s, "%5lu.%06lu | ",
+ (unsigned long)t, usecs_rem);
}
static enum print_line_t
-print_graph_irq(struct trace_seq *s, unsigned long addr,
- enum trace_type type, int cpu, pid_t pid)
+print_graph_irq(struct trace_iterator *iter, unsigned long addr,
+ enum trace_type type, int cpu, pid_t pid)
{
int ret;
+ struct trace_seq *s = &iter->seq;
if (addr < (unsigned long)__irqentry_text_start ||
addr >= (unsigned long)__irqentry_text_end)
return TRACE_TYPE_UNHANDLED;
- if (type == TRACE_GRAPH_ENT) {
- ret = trace_seq_printf(s, "==========> | ");
- } else {
- /* Cpu */
- if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
- ret = print_graph_cpu(s, cpu);
- if (ret == TRACE_TYPE_PARTIAL_LINE)
- return TRACE_TYPE_PARTIAL_LINE;
- }
- /* Proc */
- if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
- ret = print_graph_proc(s, pid);
- if (ret == TRACE_TYPE_PARTIAL_LINE)
- return TRACE_TYPE_PARTIAL_LINE;
+ /* Absolute time */
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) {
+ ret = print_graph_abs_time(iter->ts, s);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+ }
- ret = trace_seq_printf(s, " | ");
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- }
+ /* Cpu */
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
+ ret = print_graph_cpu(s, cpu);
+ if (ret == TRACE_TYPE_PARTIAL_LINE)
+ return TRACE_TYPE_PARTIAL_LINE;
+ }
+ /* Proc */
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
+ ret = print_graph_proc(s, pid);
+ if (ret == TRACE_TYPE_PARTIAL_LINE)
+ return TRACE_TYPE_PARTIAL_LINE;
+ ret = trace_seq_printf(s, " | ");
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+ }
- /* No overhead */
- if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
- ret = trace_seq_printf(s, " ");
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- }
+ /* No overhead */
+ ret = print_graph_overhead(-1, s);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ if (type == TRACE_GRAPH_ENT)
+ ret = trace_seq_printf(s, "==========>");
+ else
+ ret = trace_seq_printf(s, "<==========");
+
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* Don't close the duration column if haven't one */
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
+ trace_seq_printf(s, " |");
+ ret = trace_seq_printf(s, "\n");
- ret = trace_seq_printf(s, "<========== |\n");
- }
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
return TRACE_TYPE_HANDLED;
@@ -363,7 +439,7 @@ print_graph_duration(unsigned long long duration, struct trace_seq *s)
sprintf(msecs_str, "%lu", (unsigned long) duration);
/* Print msecs */
- ret = trace_seq_printf(s, msecs_str);
+ ret = trace_seq_printf(s, "%s", msecs_str);
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
@@ -396,52 +472,47 @@ print_graph_duration(unsigned long long duration, struct trace_seq *s)
}
-/* Signal a overhead of time execution to the output */
-static int
-print_graph_overhead(unsigned long long duration, struct trace_seq *s)
-{
- /* Duration exceeded 100 msecs */
- if (duration > 100000ULL)
- return trace_seq_printf(s, "! ");
-
- /* Duration exceeded 10 msecs */
- if (duration > 10000ULL)
- return trace_seq_printf(s, "+ ");
-
- return trace_seq_printf(s, " ");
-}
-
/* Case of a leaf function on its call entry */
static enum print_line_t
print_graph_entry_leaf(struct trace_iterator *iter,
- struct ftrace_graph_ent_entry *entry, struct trace_seq *s)
+ struct ftrace_graph_ent_entry *entry,
+ struct ftrace_graph_ret_entry *ret_entry, struct trace_seq *s)
{
- struct ftrace_graph_ret_entry *ret_entry;
+ struct fgraph_data *data = iter->private;
struct ftrace_graph_ret *graph_ret;
- struct ring_buffer_event *event;
struct ftrace_graph_ent *call;
unsigned long long duration;
int ret;
int i;
- event = ring_buffer_read(iter->buffer_iter[iter->cpu], NULL);
- ret_entry = ring_buffer_event_data(event);
graph_ret = &ret_entry->ret;
call = &entry->graph_ent;
duration = graph_ret->rettime - graph_ret->calltime;
- /* Overhead */
- if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
- ret = print_graph_overhead(duration, s);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
+ if (data) {
+ int cpu = iter->cpu;
+ int *depth = &(per_cpu_ptr(data, cpu)->depth);
+
+ /*
+ * Comments display at + 1 to depth. Since
+ * this is a leaf function, keep the comments
+ * equal to this depth.
+ */
+ *depth = call->depth - 1;
}
- /* Duration */
- ret = print_graph_duration(duration, s);
- if (ret == TRACE_TYPE_PARTIAL_LINE)
+ /* Overhead */
+ ret = print_graph_overhead(duration, s);
+ if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
+ /* Duration */
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+ ret = print_graph_duration(duration, s);
+ if (ret == TRACE_TYPE_PARTIAL_LINE)
+ return TRACE_TYPE_PARTIAL_LINE;
+ }
+
/* Function */
for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) {
ret = trace_seq_printf(s, " ");
@@ -461,33 +532,34 @@ print_graph_entry_leaf(struct trace_iterator *iter,
}
static enum print_line_t
-print_graph_entry_nested(struct ftrace_graph_ent_entry *entry,
- struct trace_seq *s, pid_t pid, int cpu)
+print_graph_entry_nested(struct trace_iterator *iter,
+ struct ftrace_graph_ent_entry *entry,
+ struct trace_seq *s, int cpu)
{
- int i;
- int ret;
struct ftrace_graph_ent *call = &entry->graph_ent;
+ struct fgraph_data *data = iter->private;
+ int ret;
+ int i;
- /* No overhead */
- if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
- ret = trace_seq_printf(s, " ");
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
+ if (data) {
+ int cpu = iter->cpu;
+ int *depth = &(per_cpu_ptr(data, cpu)->depth);
+
+ *depth = call->depth;
}
- /* Interrupt */
- ret = print_graph_irq(s, call->func, TRACE_GRAPH_ENT, cpu, pid);
- if (ret == TRACE_TYPE_UNHANDLED) {
- /* No time */
+ /* No overhead */
+ ret = print_graph_overhead(-1, s);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* No time */
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
ret = trace_seq_printf(s, " | ");
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
- } else {
- if (ret == TRACE_TYPE_PARTIAL_LINE)
- return TRACE_TYPE_PARTIAL_LINE;
}
-
/* Function */
for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) {
ret = trace_seq_printf(s, " ");
@@ -503,20 +575,40 @@ print_graph_entry_nested(struct ftrace_graph_ent_entry *entry,
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
- return TRACE_TYPE_HANDLED;
+ /*
+ * we already consumed the current entry to check the next one
+ * and see if this is a leaf.
+ */
+ return TRACE_TYPE_NO_CONSUME;
}
static enum print_line_t
-print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
- struct trace_iterator *iter, int cpu)
+print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
+ int type, unsigned long addr)
{
- int ret;
+ struct fgraph_data *data = iter->private;
struct trace_entry *ent = iter->ent;
+ int cpu = iter->cpu;
+ int ret;
/* Pid */
- if (verif_pid(s, ent->pid, cpu) == TRACE_TYPE_PARTIAL_LINE)
+ if (verif_pid(s, ent->pid, cpu, data) == TRACE_TYPE_PARTIAL_LINE)
return TRACE_TYPE_PARTIAL_LINE;
+ if (type) {
+ /* Interrupt */
+ ret = print_graph_irq(iter, addr, type, cpu, ent->pid);
+ if (ret == TRACE_TYPE_PARTIAL_LINE)
+ return TRACE_TYPE_PARTIAL_LINE;
+ }
+
+ /* Absolute time */
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) {
+ ret = print_graph_abs_time(iter->ts, s);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+ }
+
/* Cpu */
if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
ret = print_graph_cpu(s, cpu);
@@ -535,54 +627,65 @@ print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
return TRACE_TYPE_PARTIAL_LINE;
}
- if (trace_branch_is_leaf(iter, field))
- return print_graph_entry_leaf(iter, field, s);
+ return 0;
+}
+
+static enum print_line_t
+print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
+ struct trace_iterator *iter)
+{
+ int cpu = iter->cpu;
+ struct ftrace_graph_ent *call = &field->graph_ent;
+ struct ftrace_graph_ret_entry *leaf_ret;
+
+ if (print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func))
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ leaf_ret = get_return_for_leaf(iter, field);
+ if (leaf_ret)
+ return print_graph_entry_leaf(iter, field, leaf_ret, s);
else
- return print_graph_entry_nested(field, s, iter->ent->pid, cpu);
+ return print_graph_entry_nested(iter, field, s, cpu);
}
static enum print_line_t
print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
- struct trace_entry *ent, int cpu)
+ struct trace_entry *ent, struct trace_iterator *iter)
{
- int i;
- int ret;
unsigned long long duration = trace->rettime - trace->calltime;
+ struct fgraph_data *data = iter->private;
+ pid_t pid = ent->pid;
+ int cpu = iter->cpu;
+ int ret;
+ int i;
- /* Pid */
- if (verif_pid(s, ent->pid, cpu) == TRACE_TYPE_PARTIAL_LINE)
- return TRACE_TYPE_PARTIAL_LINE;
+ if (data) {
+ int cpu = iter->cpu;
+ int *depth = &(per_cpu_ptr(data, cpu)->depth);
- /* Cpu */
- if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
- ret = print_graph_cpu(s, cpu);
- if (ret == TRACE_TYPE_PARTIAL_LINE)
- return TRACE_TYPE_PARTIAL_LINE;
+ /*
+ * Comments display at + 1 to depth. This is the
+ * return from a function, we now want the comments
+ * to display at the same level of the bracket.
+ */
+ *depth = trace->depth - 1;
}
- /* Proc */
- if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
- ret = print_graph_proc(s, ent->pid);
- if (ret == TRACE_TYPE_PARTIAL_LINE)
- return TRACE_TYPE_PARTIAL_LINE;
-
- ret = trace_seq_printf(s, " | ");
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- }
+ if (print_graph_prologue(iter, s, 0, 0))
+ return TRACE_TYPE_PARTIAL_LINE;
/* Overhead */
- if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
- ret = print_graph_overhead(duration, s);
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- }
+ ret = print_graph_overhead(duration, s);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
/* Duration */
- ret = print_graph_duration(duration, s);
- if (ret == TRACE_TYPE_PARTIAL_LINE)
- return TRACE_TYPE_PARTIAL_LINE;
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+ ret = print_graph_duration(duration, s);
+ if (ret == TRACE_TYPE_PARTIAL_LINE)
+ return TRACE_TYPE_PARTIAL_LINE;
+ }
/* Closing brace */
for (i = 0; i < trace->depth * TRACE_GRAPH_INDENT; i++) {
@@ -603,7 +706,7 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
return TRACE_TYPE_PARTIAL_LINE;
}
- ret = print_graph_irq(s, trace->func, TRACE_GRAPH_RET, cpu, ent->pid);
+ ret = print_graph_irq(iter, trace->func, TRACE_GRAPH_RET, cpu, pid);
if (ret == TRACE_TYPE_PARTIAL_LINE)
return TRACE_TYPE_PARTIAL_LINE;
@@ -611,61 +714,73 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
}
static enum print_line_t
-print_graph_comment(struct print_entry *trace, struct trace_seq *s,
- struct trace_entry *ent, struct trace_iterator *iter)
+print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
+ struct trace_iterator *iter)
{
- int i;
+ unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
+ struct fgraph_data *data = iter->private;
+ struct trace_event *event;
+ int depth = 0;
int ret;
+ int i;
- /* Pid */
- if (verif_pid(s, ent->pid, iter->cpu) == TRACE_TYPE_PARTIAL_LINE)
- return TRACE_TYPE_PARTIAL_LINE;
-
- /* Cpu */
- if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
- ret = print_graph_cpu(s, iter->cpu);
- if (ret == TRACE_TYPE_PARTIAL_LINE)
- return TRACE_TYPE_PARTIAL_LINE;
- }
-
- /* Proc */
- if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
- ret = print_graph_proc(s, ent->pid);
- if (ret == TRACE_TYPE_PARTIAL_LINE)
- return TRACE_TYPE_PARTIAL_LINE;
+ if (data)
+ depth = per_cpu_ptr(data, iter->cpu)->depth;
- ret = trace_seq_printf(s, " | ");
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
- }
+ if (print_graph_prologue(iter, s, 0, 0))
+ return TRACE_TYPE_PARTIAL_LINE;
/* No overhead */
- if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
- ret = trace_seq_printf(s, " ");
+ ret = print_graph_overhead(-1, s);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ /* No time */
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+ ret = trace_seq_printf(s, " | ");
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
}
- /* No time */
- ret = trace_seq_printf(s, " | ");
- if (!ret)
- return TRACE_TYPE_PARTIAL_LINE;
-
/* Indentation */
- if (trace->depth > 0)
- for (i = 0; i < (trace->depth + 1) * TRACE_GRAPH_INDENT; i++) {
+ if (depth > 0)
+ for (i = 0; i < (depth + 1) * TRACE_GRAPH_INDENT; i++) {
ret = trace_seq_printf(s, " ");
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
}
/* The comment */
- ret = trace_seq_printf(s, "/* %s", trace->buf);
+ ret = trace_seq_printf(s, "/* ");
if (!ret)
return TRACE_TYPE_PARTIAL_LINE;
- if (ent->flags & TRACE_FLAG_CONT)
- trace_seq_print_cont(s, iter);
+ switch (iter->ent->type) {
+ case TRACE_BPRINT:
+ ret = trace_print_bprintk_msg_only(iter);
+ if (ret != TRACE_TYPE_HANDLED)
+ return ret;
+ break;
+ case TRACE_PRINT:
+ ret = trace_print_printk_msg_only(iter);
+ if (ret != TRACE_TYPE_HANDLED)
+ return ret;
+ break;
+ default:
+ event = ftrace_find_event(ent->type);
+ if (!event)
+ return TRACE_TYPE_UNHANDLED;
+
+ ret = event->trace(iter, sym_flags);
+ if (ret != TRACE_TYPE_HANDLED)
+ return ret;
+ }
+
+ /* Strip ending newline */
+ if (s->buffer[s->len - 1] == '\n') {
+ s->buffer[s->len - 1] = '\0';
+ s->len--;
+ }
ret = trace_seq_printf(s, " */\n");
if (!ret)
@@ -678,62 +793,91 @@ print_graph_comment(struct print_entry *trace, struct trace_seq *s,
enum print_line_t
print_graph_function(struct trace_iterator *iter)
{
- struct trace_seq *s = &iter->seq;
struct trace_entry *entry = iter->ent;
+ struct trace_seq *s = &iter->seq;
switch (entry->type) {
case TRACE_GRAPH_ENT: {
struct ftrace_graph_ent_entry *field;
trace_assign_type(field, entry);
- return print_graph_entry(field, s, iter,
- iter->cpu);
+ return print_graph_entry(field, s, iter);
}
case TRACE_GRAPH_RET: {
struct ftrace_graph_ret_entry *field;
trace_assign_type(field, entry);
- return print_graph_return(&field->ret, s, entry, iter->cpu);
- }
- case TRACE_PRINT: {
- struct print_entry *field;
- trace_assign_type(field, entry);
- return print_graph_comment(field, s, entry, iter);
+ return print_graph_return(&field->ret, s, entry, iter);
}
default:
- return TRACE_TYPE_UNHANDLED;
+ return print_graph_comment(s, entry, iter);
}
+
+ return TRACE_TYPE_HANDLED;
}
static void print_graph_headers(struct seq_file *s)
{
/* 1st line */
seq_printf(s, "# ");
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
+ seq_printf(s, " TIME ");
if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
- seq_printf(s, "CPU ");
+ seq_printf(s, "CPU");
if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
- seq_printf(s, "TASK/PID ");
- if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD)
- seq_printf(s, "OVERHEAD/");
- seq_printf(s, "DURATION FUNCTION CALLS\n");
+ seq_printf(s, " TASK/PID ");
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
+ seq_printf(s, " DURATION ");
+ seq_printf(s, " FUNCTION CALLS\n");
/* 2nd line */
seq_printf(s, "# ");
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
+ seq_printf(s, " | ");
if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
- seq_printf(s, "| ");
+ seq_printf(s, "| ");
if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
- seq_printf(s, "| | ");
- if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
- seq_printf(s, "| ");
- seq_printf(s, "| | | | |\n");
- } else
- seq_printf(s, " | | | | |\n");
+ seq_printf(s, " | | ");
+ if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
+ seq_printf(s, " | | ");
+ seq_printf(s, " | | | |\n");
+}
+
+static void graph_trace_open(struct trace_iterator *iter)
+{
+ /* pid and depth on the last trace processed */
+ struct fgraph_data *data = alloc_percpu(struct fgraph_data);
+ int cpu;
+
+ if (!data)
+ pr_warning("function graph tracer: not enough memory\n");
+ else
+ for_each_possible_cpu(cpu) {
+ pid_t *pid = &(per_cpu_ptr(data, cpu)->last_pid);
+ int *depth = &(per_cpu_ptr(data, cpu)->depth);
+ *pid = -1;
+ *depth = 0;
+ }
+
+ iter->private = data;
}
+
+static void graph_trace_close(struct trace_iterator *iter)
+{
+ free_percpu(iter->private);
+}
+
static struct tracer graph_trace __read_mostly = {
- .name = "function_graph",
- .init = graph_trace_init,
- .reset = graph_trace_reset,
+ .name = "function_graph",
+ .open = graph_trace_open,
+ .close = graph_trace_close,
+ .wait_pipe = poll_wait_pipe,
+ .init = graph_trace_init,
+ .reset = graph_trace_reset,
.print_line = print_graph_function,
.print_header = print_graph_headers,
.flags = &tracer_flags,
+#ifdef CONFIG_FTRACE_SELFTEST
+ .selftest = trace_selftest_startup_function_graph,
+#endif
};
static __init int init_graph_trace(void)
diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c
index 649df22d435..7bfdf4c2347 100644
--- a/kernel/trace/trace_hw_branches.c
+++ b/kernel/trace/trace_hw_branches.c
@@ -1,30 +1,53 @@
/*
* h/w branch tracer for x86 based on bts
*
- * Copyright (C) 2008 Markus Metzger <markus.t.metzger@gmail.com>
- *
+ * Copyright (C) 2008-2009 Intel Corporation.
+ * Markus Metzger <markus.t.metzger@gmail.com>, 2008-2009
*/
-
-#include <linux/module.h>
-#include <linux/fs.h>
+#include <linux/spinlock.h>
+#include <linux/kallsyms.h>
#include <linux/debugfs.h>
#include <linux/ftrace.h>
-#include <linux/kallsyms.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#include <linux/fs.h>
#include <asm/ds.h>
#include "trace.h"
+#include "trace_output.h"
#define SIZEOF_BTS (1 << 13)
+/*
+ * The tracer lock protects the below per-cpu tracer array.
+ * It needs to be held to:
+ * - start tracing on all cpus
+ * - stop tracing on all cpus
+ * - start tracing on a single hotplug cpu
+ * - stop tracing on a single hotplug cpu
+ * - read the trace from all cpus
+ * - read the trace from a single cpu
+ */
+static DEFINE_SPINLOCK(bts_tracer_lock);
static DEFINE_PER_CPU(struct bts_tracer *, tracer);
static DEFINE_PER_CPU(unsigned char[SIZEOF_BTS], buffer);
#define this_tracer per_cpu(tracer, smp_processor_id())
#define this_buffer per_cpu(buffer, smp_processor_id())
+static int __read_mostly trace_hw_branches_enabled;
+static struct trace_array *hw_branch_trace __read_mostly;
+
+/*
+ * Start tracing on the current cpu.
+ * The argument is ignored.
+ *
+ * pre: bts_tracer_lock must be locked.
+ */
static void bts_trace_start_cpu(void *arg)
{
if (this_tracer)
@@ -42,14 +65,20 @@ static void bts_trace_start_cpu(void *arg)
static void bts_trace_start(struct trace_array *tr)
{
- int cpu;
+ spin_lock(&bts_tracer_lock);
- tracing_reset_online_cpus(tr);
+ on_each_cpu(bts_trace_start_cpu, NULL, 1);
+ trace_hw_branches_enabled = 1;
- for_each_cpu(cpu, cpu_possible_mask)
- smp_call_function_single(cpu, bts_trace_start_cpu, NULL, 1);
+ spin_unlock(&bts_tracer_lock);
}
+/*
+ * Stop tracing on the current cpu.
+ * The argument is ignored.
+ *
+ * pre: bts_tracer_lock must be locked.
+ */
static void bts_trace_stop_cpu(void *arg)
{
if (this_tracer) {
@@ -60,26 +89,60 @@ static void bts_trace_stop_cpu(void *arg)
static void bts_trace_stop(struct trace_array *tr)
{
- int cpu;
+ spin_lock(&bts_tracer_lock);
+
+ trace_hw_branches_enabled = 0;
+ on_each_cpu(bts_trace_stop_cpu, NULL, 1);
+
+ spin_unlock(&bts_tracer_lock);
+}
+
+static int __cpuinit bts_hotcpu_handler(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
- for_each_cpu(cpu, cpu_possible_mask)
+ spin_lock(&bts_tracer_lock);
+
+ if (!trace_hw_branches_enabled)
+ goto out;
+
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_DOWN_FAILED:
+ smp_call_function_single(cpu, bts_trace_start_cpu, NULL, 1);
+ break;
+ case CPU_DOWN_PREPARE:
smp_call_function_single(cpu, bts_trace_stop_cpu, NULL, 1);
+ break;
+ }
+
+ out:
+ spin_unlock(&bts_tracer_lock);
+ return NOTIFY_DONE;
}
+static struct notifier_block bts_hotcpu_notifier __cpuinitdata = {
+ .notifier_call = bts_hotcpu_handler
+};
+
static int bts_trace_init(struct trace_array *tr)
{
- tracing_reset_online_cpus(tr);
+ hw_branch_trace = tr;
+
bts_trace_start(tr);
return 0;
}
+static void bts_trace_reset(struct trace_array *tr)
+{
+ bts_trace_stop(tr);
+}
+
static void bts_trace_print_header(struct seq_file *m)
{
- seq_puts(m,
- "# CPU# FROM TO FUNCTION\n");
- seq_puts(m,
- "# | | | |\n");
+ seq_puts(m, "# CPU# TO <- FROM\n");
}
static enum print_line_t bts_trace_print_line(struct trace_iterator *iter)
@@ -87,15 +150,15 @@ static enum print_line_t bts_trace_print_line(struct trace_iterator *iter)
struct trace_entry *entry = iter->ent;
struct trace_seq *seq = &iter->seq;
struct hw_branch_entry *it;
+ unsigned long symflags = TRACE_ITER_SYM_OFFSET;
trace_assign_type(it, entry);
if (entry->type == TRACE_HW_BRANCHES) {
- if (trace_seq_printf(seq, "%4d ", entry->cpu) &&
- trace_seq_printf(seq, "0x%016llx -> 0x%016llx ",
- it->from, it->to) &&
- (!it->from ||
- seq_print_ip_sym(seq, it->from, /* sym_flags = */ 0)) &&
+ if (trace_seq_printf(seq, "%4d ", iter->cpu) &&
+ seq_print_ip_sym(seq, it->to, symflags) &&
+ trace_seq_printf(seq, "\t <- ") &&
+ seq_print_ip_sym(seq, it->from, symflags) &&
trace_seq_printf(seq, "\n"))
return TRACE_TYPE_HANDLED;
return TRACE_TYPE_PARTIAL_LINE;;
@@ -103,26 +166,42 @@ static enum print_line_t bts_trace_print_line(struct trace_iterator *iter)
return TRACE_TYPE_UNHANDLED;
}
-void trace_hw_branch(struct trace_array *tr, u64 from, u64 to)
+void trace_hw_branch(u64 from, u64 to)
{
+ struct trace_array *tr = hw_branch_trace;
struct ring_buffer_event *event;
struct hw_branch_entry *entry;
- unsigned long irq;
+ unsigned long irq1;
+ int cpu;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry), &irq);
- if (!event)
+ if (unlikely(!tr))
return;
+
+ if (unlikely(!trace_hw_branches_enabled))
+ return;
+
+ local_irq_save(irq1);
+ cpu = raw_smp_processor_id();
+ if (atomic_inc_return(&tr->data[cpu]->disabled) != 1)
+ goto out;
+
+ event = trace_buffer_lock_reserve(tr, TRACE_HW_BRANCHES,
+ sizeof(*entry), 0, 0);
+ if (!event)
+ goto out;
entry = ring_buffer_event_data(event);
tracing_generic_entry_update(&entry->ent, 0, from);
entry->ent.type = TRACE_HW_BRANCHES;
- entry->ent.cpu = smp_processor_id();
entry->from = from;
entry->to = to;
- ring_buffer_unlock_commit(tr->buffer, event, irq);
+ trace_buffer_unlock_commit(tr, event, 0, 0);
+
+ out:
+ atomic_dec(&tr->data[cpu]->disabled);
+ local_irq_restore(irq1);
}
-static void trace_bts_at(struct trace_array *tr,
- const struct bts_trace *trace, void *at)
+static void trace_bts_at(const struct bts_trace *trace, void *at)
{
struct bts_struct bts;
int err = 0;
@@ -137,18 +216,29 @@ static void trace_bts_at(struct trace_array *tr,
switch (bts.qualifier) {
case BTS_BRANCH:
- trace_hw_branch(tr, bts.variant.lbr.from, bts.variant.lbr.to);
+ trace_hw_branch(bts.variant.lbr.from, bts.variant.lbr.to);
break;
}
}
+/*
+ * Collect the trace on the current cpu and write it into the ftrace buffer.
+ *
+ * pre: bts_tracer_lock must be locked
+ */
static void trace_bts_cpu(void *arg)
{
struct trace_array *tr = (struct trace_array *) arg;
const struct bts_trace *trace;
unsigned char *at;
- if (!this_tracer)
+ if (unlikely(!tr))
+ return;
+
+ if (unlikely(atomic_read(&tr->data[raw_smp_processor_id()]->disabled)))
+ return;
+
+ if (unlikely(!this_tracer))
return;
ds_suspend_bts(this_tracer);
@@ -158,11 +248,11 @@ static void trace_bts_cpu(void *arg)
for (at = trace->ds.top; (void *)at < trace->ds.end;
at += trace->ds.size)
- trace_bts_at(tr, trace, at);
+ trace_bts_at(trace, at);
for (at = trace->ds.begin; (void *)at < trace->ds.top;
at += trace->ds.size)
- trace_bts_at(tr, trace, at);
+ trace_bts_at(trace, at);
out:
ds_resume_bts(this_tracer);
@@ -170,26 +260,43 @@ out:
static void trace_bts_prepare(struct trace_iterator *iter)
{
- int cpu;
+ spin_lock(&bts_tracer_lock);
+
+ on_each_cpu(trace_bts_cpu, iter->tr, 1);
+
+ spin_unlock(&bts_tracer_lock);
+}
+
+static void trace_bts_close(struct trace_iterator *iter)
+{
+ tracing_reset_online_cpus(iter->tr);
+}
+
+void trace_hw_branch_oops(void)
+{
+ spin_lock(&bts_tracer_lock);
+
+ trace_bts_cpu(hw_branch_trace);
- for_each_cpu(cpu, cpu_possible_mask)
- smp_call_function_single(cpu, trace_bts_cpu, iter->tr, 1);
+ spin_unlock(&bts_tracer_lock);
}
struct tracer bts_tracer __read_mostly =
{
.name = "hw-branch-tracer",
.init = bts_trace_init,
- .reset = bts_trace_stop,
+ .reset = bts_trace_reset,
.print_header = bts_trace_print_header,
.print_line = bts_trace_print_line,
.start = bts_trace_start,
.stop = bts_trace_stop,
- .open = trace_bts_prepare
+ .open = trace_bts_prepare,
+ .close = trace_bts_close
};
__init static int init_bts_trace(void)
{
+ register_hotcpu_notifier(&bts_hotcpu_notifier);
return register_tracer(&bts_tracer);
}
device_initcall(init_bts_trace);
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index 62a78d94353..b923d13e2fa 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -1,5 +1,5 @@
/*
- * trace irqs off criticall timings
+ * trace irqs off critical timings
*
* Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
* Copyright (C) 2008 Ingo Molnar <mingo@redhat.com>
@@ -32,6 +32,8 @@ enum {
static int trace_type __read_mostly;
+static int save_lat_flag;
+
#ifdef CONFIG_PREEMPT_TRACER
static inline int
preempt_trace(void)
@@ -95,7 +97,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, preempt_count());
+ trace_function(tr, ip, parent_ip, flags, preempt_count());
atomic_dec(&data->disabled);
}
@@ -153,7 +155,7 @@ check_critical_timing(struct trace_array *tr,
if (!report_latency(delta))
goto out_unlock;
- trace_function(tr, data, CALLER_ADDR0, parent_ip, flags, pc);
+ trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
latency = nsecs_to_usecs(delta);
@@ -177,7 +179,7 @@ out:
data->critical_sequence = max_sequence;
data->preempt_timestamp = ftrace_now(cpu);
tracing_reset(tr, cpu);
- trace_function(tr, data, CALLER_ADDR0, parent_ip, flags, pc);
+ trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
}
static inline void
@@ -210,7 +212,7 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip)
local_save_flags(flags);
- trace_function(tr, data, ip, parent_ip, flags, preempt_count());
+ trace_function(tr, ip, parent_ip, flags, preempt_count());
per_cpu(tracing_cpu, cpu) = 1;
@@ -244,7 +246,7 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip)
atomic_inc(&data->disabled);
local_save_flags(flags);
- trace_function(tr, data, ip, parent_ip, flags, preempt_count());
+ trace_function(tr, ip, parent_ip, flags, preempt_count());
check_critical_timing(tr, data, parent_ip ? : ip, cpu);
data->critical_start = 0;
atomic_dec(&data->disabled);
@@ -353,33 +355,26 @@ void trace_preempt_off(unsigned long a0, unsigned long a1)
}
#endif /* CONFIG_PREEMPT_TRACER */
-/*
- * save_tracer_enabled is used to save the state of the tracer_enabled
- * variable when we disable it when we open a trace output file.
- */
-static int save_tracer_enabled;
-
static void start_irqsoff_tracer(struct trace_array *tr)
{
register_ftrace_function(&trace_ops);
- if (tracing_is_enabled()) {
+ if (tracing_is_enabled())
tracer_enabled = 1;
- save_tracer_enabled = 1;
- } else {
+ else
tracer_enabled = 0;
- save_tracer_enabled = 0;
- }
}
static void stop_irqsoff_tracer(struct trace_array *tr)
{
tracer_enabled = 0;
- save_tracer_enabled = 0;
unregister_ftrace_function(&trace_ops);
}
static void __irqsoff_tracer_init(struct trace_array *tr)
{
+ save_lat_flag = trace_flags & TRACE_ITER_LATENCY_FMT;
+ trace_flags |= TRACE_ITER_LATENCY_FMT;
+
tracing_max_latency = 0;
irqsoff_trace = tr;
/* make sure that the tracer is visible */
@@ -390,30 +385,19 @@ static void __irqsoff_tracer_init(struct trace_array *tr)
static void irqsoff_tracer_reset(struct trace_array *tr)
{
stop_irqsoff_tracer(tr);
+
+ if (!save_lat_flag)
+ trace_flags &= ~TRACE_ITER_LATENCY_FMT;
}
static void irqsoff_tracer_start(struct trace_array *tr)
{
tracer_enabled = 1;
- save_tracer_enabled = 1;
}
static void irqsoff_tracer_stop(struct trace_array *tr)
{
tracer_enabled = 0;
- save_tracer_enabled = 0;
-}
-
-static void irqsoff_tracer_open(struct trace_iterator *iter)
-{
- /* stop the trace while dumping */
- tracer_enabled = 0;
-}
-
-static void irqsoff_tracer_close(struct trace_iterator *iter)
-{
- /* restart tracing */
- tracer_enabled = save_tracer_enabled;
}
#ifdef CONFIG_IRQSOFF_TRACER
@@ -431,8 +415,6 @@ static struct tracer irqsoff_tracer __read_mostly =
.reset = irqsoff_tracer_reset,
.start = irqsoff_tracer_start,
.stop = irqsoff_tracer_stop,
- .open = irqsoff_tracer_open,
- .close = irqsoff_tracer_close,
.print_max = 1,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_irqsoff,
@@ -459,8 +441,6 @@ static struct tracer preemptoff_tracer __read_mostly =
.reset = irqsoff_tracer_reset,
.start = irqsoff_tracer_start,
.stop = irqsoff_tracer_stop,
- .open = irqsoff_tracer_open,
- .close = irqsoff_tracer_close,
.print_max = 1,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_preemptoff,
@@ -489,8 +469,6 @@ static struct tracer preemptirqsoff_tracer __read_mostly =
.reset = irqsoff_tracer_reset,
.start = irqsoff_tracer_start,
.stop = irqsoff_tracer_stop,
- .open = irqsoff_tracer_open,
- .close = irqsoff_tracer_close,
.print_max = 1,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_preemptirqsoff,
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
index 80e503ef613..8e37fcddd8b 100644
--- a/kernel/trace/trace_mmiotrace.c
+++ b/kernel/trace/trace_mmiotrace.c
@@ -12,6 +12,7 @@
#include <asm/atomic.h>
#include "trace.h"
+#include "trace_output.h"
struct header_iter {
struct pci_dev *dev;
@@ -183,21 +184,22 @@ static enum print_line_t mmio_print_rw(struct trace_iterator *iter)
switch (rw->opcode) {
case MMIO_READ:
ret = trace_seq_printf(s,
- "R %d %lu.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
+ "R %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
rw->width, secs, usec_rem, rw->map_id,
(unsigned long long)rw->phys,
rw->value, rw->pc, 0);
break;
case MMIO_WRITE:
ret = trace_seq_printf(s,
- "W %d %lu.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
+ "W %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
rw->width, secs, usec_rem, rw->map_id,
(unsigned long long)rw->phys,
rw->value, rw->pc, 0);
break;
case MMIO_UNKNOWN_OP:
ret = trace_seq_printf(s,
- "UNKNOWN %lu.%06lu %d 0x%llx %02x,%02x,%02x 0x%lx %d\n",
+ "UNKNOWN %u.%06lu %d 0x%llx %02lx,%02lx,"
+ "%02lx 0x%lx %d\n",
secs, usec_rem, rw->map_id,
(unsigned long long)rw->phys,
(rw->value >> 16) & 0xff, (rw->value >> 8) & 0xff,
@@ -229,14 +231,14 @@ static enum print_line_t mmio_print_map(struct trace_iterator *iter)
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",
+ "MAP %u.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n",
secs, usec_rem, m->map_id,
(unsigned long long)m->phys, m->virt, m->len,
0UL, 0);
break;
case MMIO_UNPROBE:
ret = trace_seq_printf(s,
- "UNMAP %lu.%06lu %d 0x%lx %d\n",
+ "UNMAP %u.%06lu %d 0x%lx %d\n",
secs, usec_rem, m->map_id, 0UL, 0);
break;
default:
@@ -255,18 +257,15 @@ static enum print_line_t mmio_print_mark(struct trace_iterator *iter)
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 long usec_rem = do_div(t, USEC_PER_SEC);
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);
+ ret = trace_seq_printf(s, "MARK %u.%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;
}
@@ -308,21 +307,17 @@ static void __trace_mmiotrace_rw(struct trace_array *tr,
{
struct ring_buffer_event *event;
struct trace_mmiotrace_rw *entry;
- unsigned long irq_flags;
+ int pc = preempt_count();
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
- &irq_flags);
+ event = trace_buffer_lock_reserve(tr, TRACE_MMIO_RW,
+ sizeof(*entry), 0, pc);
if (!event) {
atomic_inc(&dropped_count);
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();
+ trace_buffer_unlock_commit(tr, event, 0, pc);
}
void mmio_trace_rw(struct mmiotrace_rw *rw)
@@ -338,21 +333,17 @@ static void __trace_mmiotrace_map(struct trace_array *tr,
{
struct ring_buffer_event *event;
struct trace_mmiotrace_map *entry;
- unsigned long irq_flags;
+ int pc = preempt_count();
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
- &irq_flags);
+ event = trace_buffer_lock_reserve(tr, TRACE_MMIO_MAP,
+ sizeof(*entry), 0, pc);
if (!event) {
atomic_inc(&dropped_count);
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();
+ trace_buffer_unlock_commit(tr, event, 0, pc);
}
void mmio_trace_mapping(struct mmiotrace_map *map)
@@ -368,5 +359,5 @@ void mmio_trace_mapping(struct mmiotrace_map *map)
int mmio_trace_printk(const char *fmt, va_list args)
{
- return trace_vprintk(0, -1, fmt, args);
+ return trace_vprintk(0, fmt, args);
}
diff --git a/kernel/trace/trace_nop.c b/kernel/trace/trace_nop.c
index b9767acd30a..394f94417e2 100644
--- a/kernel/trace/trace_nop.c
+++ b/kernel/trace/trace_nop.c
@@ -47,12 +47,7 @@ static void stop_nop_trace(struct trace_array *tr)
static int nop_trace_init(struct trace_array *tr)
{
- int cpu;
ctx_trace = tr;
-
- for_each_online_cpu(cpu)
- tracing_reset(tr, cpu);
-
start_nop_trace(tr);
return 0;
}
@@ -96,6 +91,7 @@ struct tracer nop_trace __read_mostly =
.name = "nop",
.init = nop_trace_init,
.reset = nop_trace_reset,
+ .wait_pipe = poll_wait_pipe,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_nop,
#endif
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
new file mode 100644
index 00000000000..64b54a59c55
--- /dev/null
+++ b/kernel/trace/trace_output.c
@@ -0,0 +1,1017 @@
+/*
+ * trace_output.c
+ *
+ * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/ftrace.h>
+
+#include "trace_output.h"
+
+/* must be a power of 2 */
+#define EVENT_HASHSIZE 128
+
+static DEFINE_MUTEX(trace_event_mutex);
+static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
+
+static int next_event_type = __TRACE_LAST_TYPE + 1;
+
+enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter)
+{
+ struct trace_seq *s = &iter->seq;
+ struct trace_entry *entry = iter->ent;
+ struct bprint_entry *field;
+ int ret;
+
+ trace_assign_type(field, entry);
+
+ ret = trace_seq_bprintf(s, field->fmt, field->buf);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ return TRACE_TYPE_HANDLED;
+}
+
+enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter)
+{
+ struct trace_seq *s = &iter->seq;
+ struct trace_entry *entry = iter->ent;
+ struct print_entry *field;
+ int ret;
+
+ trace_assign_type(field, entry);
+
+ ret = trace_seq_printf(s, "%s", field->buf);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ return TRACE_TYPE_HANDLED;
+}
+
+/**
+ * trace_seq_printf - sequence printing of trace information
+ * @s: trace sequence descriptor
+ * @fmt: printf format string
+ *
+ * The tracer may use either sequence operations or its own
+ * copy to user routines. To simplify formating of a trace
+ * trace_seq_printf is used to store strings into a special
+ * buffer (@s). Then the output may be either used by
+ * the sequencer or pulled into another buffer.
+ */
+int
+trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
+{
+ int len = (PAGE_SIZE - 1) - s->len;
+ va_list ap;
+ int ret;
+
+ if (!len)
+ return 0;
+
+ va_start(ap, fmt);
+ ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
+ va_end(ap);
+
+ /* If we can't write it all, don't bother writing anything */
+ if (ret >= len)
+ return 0;
+
+ s->len += ret;
+
+ return len;
+}
+
+int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
+{
+ int len = (PAGE_SIZE - 1) - s->len;
+ int ret;
+
+ if (!len)
+ return 0;
+
+ ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
+
+ /* If we can't write it all, don't bother writing anything */
+ if (ret >= len)
+ return 0;
+
+ s->len += ret;
+
+ return len;
+}
+
+/**
+ * trace_seq_puts - trace sequence printing of simple string
+ * @s: trace sequence descriptor
+ * @str: simple string to record
+ *
+ * The tracer may use either the sequence operations or its own
+ * copy to user routines. This function records a simple string
+ * into a special buffer (@s) for later retrieval by a sequencer
+ * or other mechanism.
+ */
+int trace_seq_puts(struct trace_seq *s, const char *str)
+{
+ int len = strlen(str);
+
+ if (len > ((PAGE_SIZE - 1) - s->len))
+ return 0;
+
+ memcpy(s->buffer + s->len, str, len);
+ s->len += len;
+
+ return len;
+}
+
+int trace_seq_putc(struct trace_seq *s, unsigned char c)
+{
+ if (s->len >= (PAGE_SIZE - 1))
+ return 0;
+
+ s->buffer[s->len++] = c;
+
+ return 1;
+}
+
+int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len)
+{
+ if (len > ((PAGE_SIZE - 1) - s->len))
+ return 0;
+
+ memcpy(s->buffer + s->len, mem, len);
+ s->len += len;
+
+ return len;
+}
+
+int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len)
+{
+ unsigned char hex[HEX_CHARS];
+ const unsigned char *data = mem;
+ int i, j;
+
+#ifdef __BIG_ENDIAN
+ for (i = 0, j = 0; i < len; i++) {
+#else
+ for (i = len-1, j = 0; i >= 0; i--) {
+#endif
+ hex[j++] = hex_asc_hi(data[i]);
+ hex[j++] = hex_asc_lo(data[i]);
+ }
+ hex[j++] = ' ';
+
+ return trace_seq_putmem(s, hex, j);
+}
+
+void *trace_seq_reserve(struct trace_seq *s, size_t len)
+{
+ void *ret;
+
+ if (len > ((PAGE_SIZE - 1) - s->len))
+ return NULL;
+
+ ret = s->buffer + s->len;
+ s->len += len;
+
+ return ret;
+}
+
+int trace_seq_path(struct trace_seq *s, struct path *path)
+{
+ unsigned char *p;
+
+ if (s->len >= (PAGE_SIZE - 1))
+ return 0;
+ p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
+ if (!IS_ERR(p)) {
+ p = mangle_path(s->buffer + s->len, p, "\n");
+ if (p) {
+ s->len = p - s->buffer;
+ return 1;
+ }
+ } else {
+ s->buffer[s->len++] = '?';
+ return 1;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_KRETPROBES
+static inline const char *kretprobed(const char *name)
+{
+ static const char tramp_name[] = "kretprobe_trampoline";
+ int size = sizeof(tramp_name);
+
+ if (strncmp(tramp_name, name, size) == 0)
+ return "[unknown/kretprobe'd]";
+ return name;
+}
+#else
+static inline const char *kretprobed(const char *name)
+{
+ return name;
+}
+#endif /* CONFIG_KRETPROBES */
+
+static int
+seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
+{
+#ifdef CONFIG_KALLSYMS
+ char str[KSYM_SYMBOL_LEN];
+ const char *name;
+
+ kallsyms_lookup(address, NULL, NULL, NULL, str);
+
+ name = kretprobed(str);
+
+ return trace_seq_printf(s, fmt, name);
+#endif
+ return 1;
+}
+
+static int
+seq_print_sym_offset(struct trace_seq *s, const char *fmt,
+ unsigned long address)
+{
+#ifdef CONFIG_KALLSYMS
+ char str[KSYM_SYMBOL_LEN];
+ const char *name;
+
+ sprint_symbol(str, address);
+ name = kretprobed(str);
+
+ return trace_seq_printf(s, fmt, name);
+#endif
+ return 1;
+}
+
+#ifndef CONFIG_64BIT
+# define IP_FMT "%08lx"
+#else
+# define IP_FMT "%016lx"
+#endif
+
+int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
+ unsigned long ip, unsigned long sym_flags)
+{
+ struct file *file = NULL;
+ unsigned long vmstart = 0;
+ int ret = 1;
+
+ if (mm) {
+ const struct vm_area_struct *vma;
+
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, ip);
+ if (vma) {
+ file = vma->vm_file;
+ vmstart = vma->vm_start;
+ }
+ if (file) {
+ ret = trace_seq_path(s, &file->f_path);
+ if (ret)
+ ret = trace_seq_printf(s, "[+0x%lx]",
+ ip - vmstart);
+ }
+ up_read(&mm->mmap_sem);
+ }
+ if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
+ ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
+ return ret;
+}
+
+int
+seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
+ unsigned long sym_flags)
+{
+ struct mm_struct *mm = NULL;
+ int ret = 1;
+ unsigned int i;
+
+ if (trace_flags & TRACE_ITER_SYM_USEROBJ) {
+ struct task_struct *task;
+ /*
+ * we do the lookup on the thread group leader,
+ * since individual threads might have already quit!
+ */
+ rcu_read_lock();
+ task = find_task_by_vpid(entry->ent.tgid);
+ if (task)
+ mm = get_task_mm(task);
+ rcu_read_unlock();
+ }
+
+ for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
+ unsigned long ip = entry->caller[i];
+
+ if (ip == ULONG_MAX || !ret)
+ break;
+ if (i && ret)
+ ret = trace_seq_puts(s, " <- ");
+ if (!ip) {
+ if (ret)
+ ret = trace_seq_puts(s, "??");
+ continue;
+ }
+ if (!ret)
+ break;
+ if (ret)
+ ret = seq_print_user_ip(s, mm, ip, sym_flags);
+ }
+
+ if (mm)
+ mmput(mm);
+ return ret;
+}
+
+int
+seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
+{
+ int ret;
+
+ if (!ip)
+ return trace_seq_printf(s, "0");
+
+ if (sym_flags & TRACE_ITER_SYM_OFFSET)
+ ret = seq_print_sym_offset(s, "%s", ip);
+ else
+ ret = seq_print_sym_short(s, "%s", ip);
+
+ if (!ret)
+ return 0;
+
+ if (sym_flags & TRACE_ITER_SYM_ADDR)
+ ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
+ return ret;
+}
+
+static int
+lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
+{
+ int hardirq, softirq;
+ char comm[TASK_COMM_LEN];
+
+ trace_find_cmdline(entry->pid, comm);
+ hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
+ softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
+
+ if (!trace_seq_printf(s, "%8.8s-%-5d %3d%c%c%c",
+ comm, entry->pid, cpu,
+ (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
+ (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
+ 'X' : '.',
+ (entry->flags & TRACE_FLAG_NEED_RESCHED) ?
+ 'N' : '.',
+ (hardirq && softirq) ? 'H' :
+ hardirq ? 'h' : softirq ? 's' : '.'))
+ return 0;
+
+ if (entry->preempt_count)
+ return trace_seq_printf(s, "%x", entry->preempt_count);
+ return trace_seq_puts(s, ".");
+}
+
+static unsigned long preempt_mark_thresh = 100;
+
+static int
+lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
+ unsigned long rel_usecs)
+{
+ return trace_seq_printf(s, " %4lldus%c: ", abs_usecs,
+ rel_usecs > preempt_mark_thresh ? '!' :
+ rel_usecs > 1 ? '+' : ' ');
+}
+
+int trace_print_context(struct trace_iterator *iter)
+{
+ struct trace_seq *s = &iter->seq;
+ struct trace_entry *entry = iter->ent;
+ unsigned long long t = ns2usecs(iter->ts);
+ unsigned long usec_rem = do_div(t, USEC_PER_SEC);
+ unsigned long secs = (unsigned long)t;
+ char comm[TASK_COMM_LEN];
+
+ trace_find_cmdline(entry->pid, comm);
+
+ return trace_seq_printf(s, "%16s-%-5d [%03d] %5lu.%06lu: ",
+ comm, entry->pid, iter->cpu, secs, usec_rem);
+}
+
+int trace_print_lat_context(struct trace_iterator *iter)
+{
+ u64 next_ts;
+ int ret;
+ struct trace_seq *s = &iter->seq;
+ struct trace_entry *entry = iter->ent,
+ *next_entry = trace_find_next_entry(iter, NULL,
+ &next_ts);
+ unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
+ unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
+ unsigned long rel_usecs;
+
+ if (!next_entry)
+ next_ts = iter->ts;
+ rel_usecs = ns2usecs(next_ts - iter->ts);
+
+ if (verbose) {
+ char comm[TASK_COMM_LEN];
+
+ trace_find_cmdline(entry->pid, comm);
+
+ ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08llx]"
+ " %ld.%03ldms (+%ld.%03ldms): ", comm,
+ entry->pid, iter->cpu, entry->flags,
+ entry->preempt_count, iter->idx,
+ ns2usecs(iter->ts),
+ abs_usecs / USEC_PER_MSEC,
+ abs_usecs % USEC_PER_MSEC,
+ rel_usecs / USEC_PER_MSEC,
+ rel_usecs % USEC_PER_MSEC);
+ } else {
+ ret = lat_print_generic(s, entry, iter->cpu);
+ if (ret)
+ ret = lat_print_timestamp(s, abs_usecs, rel_usecs);
+ }
+
+ return ret;
+}
+
+static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
+
+static int task_state_char(unsigned long state)
+{
+ int bit = state ? __ffs(state) + 1 : 0;
+
+ return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
+}
+
+/**
+ * ftrace_find_event - find a registered event
+ * @type: the type of event to look for
+ *
+ * Returns an event of type @type otherwise NULL
+ */
+struct trace_event *ftrace_find_event(int type)
+{
+ struct trace_event *event;
+ struct hlist_node *n;
+ unsigned key;
+
+ key = type & (EVENT_HASHSIZE - 1);
+
+ hlist_for_each_entry_rcu(event, n, &event_hash[key], node) {
+ if (event->type == type)
+ return event;
+ }
+
+ return NULL;
+}
+
+/**
+ * register_ftrace_event - register output for an event type
+ * @event: the event type to register
+ *
+ * Event types are stored in a hash and this hash is used to
+ * find a way to print an event. If the @event->type is set
+ * then it will use that type, otherwise it will assign a
+ * type to use.
+ *
+ * If you assign your own type, please make sure it is added
+ * to the trace_type enum in trace.h, to avoid collisions
+ * with the dynamic types.
+ *
+ * Returns the event type number or zero on error.
+ */
+int register_ftrace_event(struct trace_event *event)
+{
+ unsigned key;
+ int ret = 0;
+
+ mutex_lock(&trace_event_mutex);
+
+ if (!event) {
+ ret = next_event_type++;
+ goto out;
+ }
+
+ if (!event->type)
+ event->type = next_event_type++;
+ else if (event->type > __TRACE_LAST_TYPE) {
+ printk(KERN_WARNING "Need to add type to trace.h\n");
+ WARN_ON(1);
+ }
+
+ if (ftrace_find_event(event->type))
+ goto out;
+
+ if (event->trace == NULL)
+ event->trace = trace_nop_print;
+ if (event->raw == NULL)
+ event->raw = trace_nop_print;
+ if (event->hex == NULL)
+ event->hex = trace_nop_print;
+ if (event->binary == NULL)
+ event->binary = trace_nop_print;
+
+ key = event->type & (EVENT_HASHSIZE - 1);
+
+ hlist_add_head_rcu(&event->node, &event_hash[key]);
+
+ ret = event->type;
+ out:
+ mutex_unlock(&trace_event_mutex);
+
+ return ret;
+}
+
+/**
+ * unregister_ftrace_event - remove a no longer used event
+ * @event: the event to remove
+ */
+int unregister_ftrace_event(struct trace_event *event)
+{
+ mutex_lock(&trace_event_mutex);
+ hlist_del(&event->node);
+ mutex_unlock(&trace_event_mutex);
+
+ return 0;
+}
+
+/*
+ * Standard events
+ */
+
+enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags)
+{
+ return TRACE_TYPE_HANDLED;
+}
+
+/* TRACE_FN */
+static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags)
+{
+ struct ftrace_entry *field;
+ struct trace_seq *s = &iter->seq;
+
+ trace_assign_type(field, iter->ent);
+
+ if (!seq_print_ip_sym(s, field->ip, flags))
+ goto partial;
+
+ if ((flags & TRACE_ITER_PRINT_PARENT) && field->parent_ip) {
+ if (!trace_seq_printf(s, " <-"))
+ goto partial;
+ if (!seq_print_ip_sym(s,
+ field->parent_ip,
+ flags))
+ goto partial;
+ }
+ if (!trace_seq_printf(s, "\n"))
+ goto partial;
+
+ return TRACE_TYPE_HANDLED;
+
+ partial:
+ return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags)
+{
+ struct ftrace_entry *field;
+
+ trace_assign_type(field, iter->ent);
+
+ if (!trace_seq_printf(&iter->seq, "%lx %lx\n",
+ field->ip,
+ field->parent_ip))
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags)
+{
+ struct ftrace_entry *field;
+ struct trace_seq *s = &iter->seq;
+
+ trace_assign_type(field, iter->ent);
+
+ SEQ_PUT_HEX_FIELD_RET(s, field->ip);
+ SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
+
+ return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags)
+{
+ struct ftrace_entry *field;
+ struct trace_seq *s = &iter->seq;
+
+ trace_assign_type(field, iter->ent);
+
+ SEQ_PUT_FIELD_RET(s, field->ip);
+ SEQ_PUT_FIELD_RET(s, field->parent_ip);
+
+ return TRACE_TYPE_HANDLED;
+}
+
+static struct trace_event trace_fn_event = {
+ .type = TRACE_FN,
+ .trace = trace_fn_trace,
+ .raw = trace_fn_raw,
+ .hex = trace_fn_hex,
+ .binary = trace_fn_bin,
+};
+
+/* TRACE_CTX an TRACE_WAKE */
+static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
+ char *delim)
+{
+ struct ctx_switch_entry *field;
+ char comm[TASK_COMM_LEN];
+ int S, T;
+
+
+ trace_assign_type(field, iter->ent);
+
+ T = task_state_char(field->next_state);
+ S = task_state_char(field->prev_state);
+ trace_find_cmdline(field->next_pid, comm);
+ if (!trace_seq_printf(&iter->seq,
+ " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
+ field->prev_pid,
+ field->prev_prio,
+ S, delim,
+ field->next_cpu,
+ field->next_pid,
+ field->next_prio,
+ T, comm))
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags)
+{
+ return trace_ctxwake_print(iter, "==>");
+}
+
+static enum print_line_t trace_wake_print(struct trace_iterator *iter,
+ int flags)
+{
+ return trace_ctxwake_print(iter, " +");
+}
+
+static int trace_ctxwake_raw(struct trace_iterator *iter, char S)
+{
+ struct ctx_switch_entry *field;
+ int T;
+
+ trace_assign_type(field, iter->ent);
+
+ if (!S)
+ task_state_char(field->prev_state);
+ T = task_state_char(field->next_state);
+ if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n",
+ field->prev_pid,
+ field->prev_prio,
+ S,
+ field->next_cpu,
+ field->next_pid,
+ field->next_prio,
+ T))
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags)
+{
+ return trace_ctxwake_raw(iter, 0);
+}
+
+static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags)
+{
+ return trace_ctxwake_raw(iter, '+');
+}
+
+
+static int trace_ctxwake_hex(struct trace_iterator *iter, char S)
+{
+ struct ctx_switch_entry *field;
+ struct trace_seq *s = &iter->seq;
+ int T;
+
+ trace_assign_type(field, iter->ent);
+
+ if (!S)
+ task_state_char(field->prev_state);
+ T = task_state_char(field->next_state);
+
+ 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, 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);
+
+ return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags)
+{
+ return trace_ctxwake_hex(iter, 0);
+}
+
+static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags)
+{
+ return trace_ctxwake_hex(iter, '+');
+}
+
+static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter,
+ int flags)
+{
+ struct ctx_switch_entry *field;
+ struct trace_seq *s = &iter->seq;
+
+ trace_assign_type(field, iter->ent);
+
+ 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);
+
+ return TRACE_TYPE_HANDLED;
+}
+
+static struct trace_event trace_ctx_event = {
+ .type = TRACE_CTX,
+ .trace = trace_ctx_print,
+ .raw = trace_ctx_raw,
+ .hex = trace_ctx_hex,
+ .binary = trace_ctxwake_bin,
+};
+
+static struct trace_event trace_wake_event = {
+ .type = TRACE_WAKE,
+ .trace = trace_wake_print,
+ .raw = trace_wake_raw,
+ .hex = trace_wake_hex,
+ .binary = trace_ctxwake_bin,
+};
+
+/* TRACE_SPECIAL */
+static enum print_line_t trace_special_print(struct trace_iterator *iter,
+ int flags)
+{
+ struct special_entry *field;
+
+ trace_assign_type(field, iter->ent);
+
+ if (!trace_seq_printf(&iter->seq, "# %ld %ld %ld\n",
+ field->arg1,
+ field->arg2,
+ field->arg3))
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_special_hex(struct trace_iterator *iter,
+ int flags)
+{
+ struct special_entry *field;
+ struct trace_seq *s = &iter->seq;
+
+ trace_assign_type(field, iter->ent);
+
+ SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
+ SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
+ SEQ_PUT_HEX_FIELD_RET(s, field->arg3);
+
+ return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_special_bin(struct trace_iterator *iter,
+ int flags)
+{
+ struct special_entry *field;
+ struct trace_seq *s = &iter->seq;
+
+ trace_assign_type(field, iter->ent);
+
+ SEQ_PUT_FIELD_RET(s, field->arg1);
+ SEQ_PUT_FIELD_RET(s, field->arg2);
+ SEQ_PUT_FIELD_RET(s, field->arg3);
+
+ return TRACE_TYPE_HANDLED;
+}
+
+static struct trace_event trace_special_event = {
+ .type = TRACE_SPECIAL,
+ .trace = trace_special_print,
+ .raw = trace_special_print,
+ .hex = trace_special_hex,
+ .binary = trace_special_bin,
+};
+
+/* TRACE_STACK */
+
+static enum print_line_t trace_stack_print(struct trace_iterator *iter,
+ int flags)
+{
+ struct stack_entry *field;
+ struct trace_seq *s = &iter->seq;
+ int i;
+
+ trace_assign_type(field, iter->ent);
+
+ for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
+ if (i) {
+ if (!trace_seq_puts(s, " <= "))
+ goto partial;
+
+ if (!seq_print_ip_sym(s, field->caller[i], flags))
+ goto partial;
+ }
+ if (!trace_seq_puts(s, "\n"))
+ goto partial;
+ }
+
+ return TRACE_TYPE_HANDLED;
+
+ partial:
+ return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static struct trace_event trace_stack_event = {
+ .type = TRACE_STACK,
+ .trace = trace_stack_print,
+ .raw = trace_special_print,
+ .hex = trace_special_hex,
+ .binary = trace_special_bin,
+};
+
+/* TRACE_USER_STACK */
+static enum print_line_t trace_user_stack_print(struct trace_iterator *iter,
+ int flags)
+{
+ struct userstack_entry *field;
+ struct trace_seq *s = &iter->seq;
+
+ trace_assign_type(field, iter->ent);
+
+ if (!seq_print_userip_objs(field, s, flags))
+ goto partial;
+
+ if (!trace_seq_putc(s, '\n'))
+ goto partial;
+
+ return TRACE_TYPE_HANDLED;
+
+ partial:
+ return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static struct trace_event trace_user_stack_event = {
+ .type = TRACE_USER_STACK,
+ .trace = trace_user_stack_print,
+ .raw = trace_special_print,
+ .hex = trace_special_hex,
+ .binary = trace_special_bin,
+};
+
+/* TRACE_BPRINT */
+static enum print_line_t
+trace_bprint_print(struct trace_iterator *iter, int flags)
+{
+ struct trace_entry *entry = iter->ent;
+ struct trace_seq *s = &iter->seq;
+ struct bprint_entry *field;
+
+ trace_assign_type(field, entry);
+
+ if (!seq_print_ip_sym(s, field->ip, flags))
+ goto partial;
+
+ if (!trace_seq_puts(s, ": "))
+ goto partial;
+
+ if (!trace_seq_bprintf(s, field->fmt, field->buf))
+ goto partial;
+
+ return TRACE_TYPE_HANDLED;
+
+ partial:
+ return TRACE_TYPE_PARTIAL_LINE;
+}
+
+
+static enum print_line_t
+trace_bprint_raw(struct trace_iterator *iter, int flags)
+{
+ struct bprint_entry *field;
+ struct trace_seq *s = &iter->seq;
+
+ trace_assign_type(field, iter->ent);
+
+ if (!trace_seq_printf(s, ": %lx : ", field->ip))
+ goto partial;
+
+ if (!trace_seq_bprintf(s, field->fmt, field->buf))
+ goto partial;
+
+ return TRACE_TYPE_HANDLED;
+
+ partial:
+ return TRACE_TYPE_PARTIAL_LINE;
+}
+
+
+static struct trace_event trace_bprint_event = {
+ .type = TRACE_BPRINT,
+ .trace = trace_bprint_print,
+ .raw = trace_bprint_raw,
+};
+
+/* TRACE_PRINT */
+static enum print_line_t trace_print_print(struct trace_iterator *iter,
+ int flags)
+{
+ struct print_entry *field;
+ struct trace_seq *s = &iter->seq;
+
+ trace_assign_type(field, iter->ent);
+
+ if (!seq_print_ip_sym(s, field->ip, flags))
+ goto partial;
+
+ if (!trace_seq_printf(s, ": %s", field->buf))
+ goto partial;
+
+ return TRACE_TYPE_HANDLED;
+
+ partial:
+ return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags)
+{
+ struct print_entry *field;
+
+ trace_assign_type(field, iter->ent);
+
+ if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf))
+ goto partial;
+
+ return TRACE_TYPE_HANDLED;
+
+ partial:
+ return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static struct trace_event trace_print_event = {
+ .type = TRACE_PRINT,
+ .trace = trace_print_print,
+ .raw = trace_print_raw,
+};
+
+
+static struct trace_event *events[] __initdata = {
+ &trace_fn_event,
+ &trace_ctx_event,
+ &trace_wake_event,
+ &trace_special_event,
+ &trace_stack_event,
+ &trace_user_stack_event,
+ &trace_bprint_event,
+ &trace_print_event,
+ NULL
+};
+
+__init static int init_events(void)
+{
+ struct trace_event *event;
+ int i, ret;
+
+ for (i = 0; events[i]; i++) {
+ event = events[i];
+
+ ret = register_ftrace_event(event);
+ if (!ret) {
+ printk(KERN_WARNING "event %d failed to register\n",
+ event->type);
+ WARN_ON_ONCE(1);
+ }
+ }
+
+ return 0;
+}
+device_initcall(init_events);
diff --git a/kernel/trace/trace_output.h b/kernel/trace/trace_output.h
new file mode 100644
index 00000000000..e0bde39c2dd
--- /dev/null
+++ b/kernel/trace/trace_output.h
@@ -0,0 +1,71 @@
+#ifndef __TRACE_EVENTS_H
+#define __TRACE_EVENTS_H
+
+#include "trace.h"
+
+typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter,
+ int flags);
+
+struct trace_event {
+ struct hlist_node node;
+ int type;
+ trace_print_func trace;
+ trace_print_func raw;
+ trace_print_func hex;
+ trace_print_func binary;
+};
+
+extern enum print_line_t
+trace_print_bprintk_msg_only(struct trace_iterator *iter);
+extern enum print_line_t
+trace_print_printk_msg_only(struct trace_iterator *iter);
+
+extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+extern int
+trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary);
+extern int
+seq_print_ip_sym(struct trace_seq *s, unsigned long ip,
+ unsigned long sym_flags);
+extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
+ size_t cnt);
+extern int trace_seq_puts(struct trace_seq *s, const char *str);
+extern int trace_seq_putc(struct trace_seq *s, unsigned char c);
+extern int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len);
+extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
+ size_t len);
+extern void *trace_seq_reserve(struct trace_seq *s, size_t len);
+extern int trace_seq_path(struct trace_seq *s, struct path *path);
+extern int seq_print_userip_objs(const struct userstack_entry *entry,
+ struct trace_seq *s, unsigned long sym_flags);
+extern int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
+ unsigned long ip, unsigned long sym_flags);
+
+extern int trace_print_context(struct trace_iterator *iter);
+extern int trace_print_lat_context(struct trace_iterator *iter);
+
+extern struct trace_event *ftrace_find_event(int type);
+extern int register_ftrace_event(struct trace_event *event);
+extern int unregister_ftrace_event(struct trace_event *event);
+
+extern enum print_line_t trace_nop_print(struct trace_iterator *iter,
+ int flags);
+
+#define MAX_MEMHEX_BYTES 8
+#define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1)
+
+#define SEQ_PUT_FIELD_RET(s, x) \
+do { \
+ if (!trace_seq_putmem(s, &(x), sizeof(x))) \
+ return TRACE_TYPE_PARTIAL_LINE; \
+} while (0)
+
+#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 TRACE_TYPE_PARTIAL_LINE; \
+} while (0)
+
+#endif
+
diff --git a/kernel/trace/trace_power.c b/kernel/trace/trace_power.c
index 7bda248daf5..bae791ebcc5 100644
--- a/kernel/trace/trace_power.c
+++ b/kernel/trace/trace_power.c
@@ -11,15 +11,113 @@
#include <linux/init.h>
#include <linux/debugfs.h>
-#include <linux/ftrace.h>
+#include <trace/power.h>
#include <linux/kallsyms.h>
#include <linux/module.h>
#include "trace.h"
+#include "trace_output.h"
static struct trace_array *power_trace;
static int __read_mostly trace_power_enabled;
+static void probe_power_start(struct power_trace *it, unsigned int type,
+ unsigned int level)
+{
+ if (!trace_power_enabled)
+ return;
+
+ memset(it, 0, sizeof(struct power_trace));
+ it->state = level;
+ it->type = type;
+ it->stamp = ktime_get();
+}
+
+
+static void probe_power_end(struct power_trace *it)
+{
+ struct ring_buffer_event *event;
+ struct trace_power *entry;
+ struct trace_array_cpu *data;
+ struct trace_array *tr = power_trace;
+
+ if (!trace_power_enabled)
+ return;
+
+ preempt_disable();
+ it->end = ktime_get();
+ data = tr->data[smp_processor_id()];
+
+ event = trace_buffer_lock_reserve(tr, TRACE_POWER,
+ sizeof(*entry), 0, 0);
+ if (!event)
+ goto out;
+ entry = ring_buffer_event_data(event);
+ entry->state_data = *it;
+ trace_buffer_unlock_commit(tr, event, 0, 0);
+ out:
+ preempt_enable();
+}
+
+static void probe_power_mark(struct power_trace *it, unsigned int type,
+ unsigned int level)
+{
+ struct ring_buffer_event *event;
+ struct trace_power *entry;
+ struct trace_array_cpu *data;
+ struct trace_array *tr = power_trace;
+
+ if (!trace_power_enabled)
+ return;
+
+ memset(it, 0, sizeof(struct power_trace));
+ it->state = level;
+ it->type = type;
+ it->stamp = ktime_get();
+ preempt_disable();
+ it->end = it->stamp;
+ data = tr->data[smp_processor_id()];
+
+ event = trace_buffer_lock_reserve(tr, TRACE_POWER,
+ sizeof(*entry), 0, 0);
+ if (!event)
+ goto out;
+ entry = ring_buffer_event_data(event);
+ entry->state_data = *it;
+ trace_buffer_unlock_commit(tr, event, 0, 0);
+ out:
+ preempt_enable();
+}
+
+static int tracing_power_register(void)
+{
+ int ret;
+
+ ret = register_trace_power_start(probe_power_start);
+ if (ret) {
+ pr_info("power trace: Couldn't activate tracepoint"
+ " probe to trace_power_start\n");
+ return ret;
+ }
+ ret = register_trace_power_end(probe_power_end);
+ if (ret) {
+ pr_info("power trace: Couldn't activate tracepoint"
+ " probe to trace_power_end\n");
+ goto fail_start;
+ }
+ ret = register_trace_power_mark(probe_power_mark);
+ if (ret) {
+ pr_info("power trace: Couldn't activate tracepoint"
+ " probe to trace_power_mark\n");
+ goto fail_end;
+ }
+ return ret;
+fail_end:
+ unregister_trace_power_end(probe_power_end);
+fail_start:
+ unregister_trace_power_start(probe_power_start);
+ return ret;
+}
static void start_power_trace(struct trace_array *tr)
{
@@ -31,6 +129,14 @@ static void stop_power_trace(struct trace_array *tr)
trace_power_enabled = 0;
}
+static void power_trace_reset(struct trace_array *tr)
+{
+ trace_power_enabled = 0;
+ unregister_trace_power_start(probe_power_start);
+ unregister_trace_power_end(probe_power_end);
+ unregister_trace_power_mark(probe_power_mark);
+}
+
static int power_trace_init(struct trace_array *tr)
{
@@ -38,6 +144,7 @@ static int power_trace_init(struct trace_array *tr)
power_trace = tr;
trace_power_enabled = 1;
+ tracing_power_register();
for_each_cpu(cpu, cpu_possible_mask)
tracing_reset(tr, cpu);
@@ -85,7 +192,7 @@ static struct tracer power_tracer __read_mostly =
.init = power_trace_init,
.start = start_power_trace,
.stop = stop_power_trace,
- .reset = stop_power_trace,
+ .reset = power_trace_reset,
.print_line = power_print_line,
};
@@ -94,86 +201,3 @@ static int init_power_trace(void)
return register_tracer(&power_tracer);
}
device_initcall(init_power_trace);
-
-void trace_power_start(struct power_trace *it, unsigned int type,
- unsigned int level)
-{
- if (!trace_power_enabled)
- return;
-
- memset(it, 0, sizeof(struct power_trace));
- it->state = level;
- it->type = type;
- it->stamp = ktime_get();
-}
-EXPORT_SYMBOL_GPL(trace_power_start);
-
-
-void trace_power_end(struct power_trace *it)
-{
- struct ring_buffer_event *event;
- struct trace_power *entry;
- struct trace_array_cpu *data;
- unsigned long irq_flags;
- struct trace_array *tr = power_trace;
-
- if (!trace_power_enabled)
- return;
-
- preempt_disable();
- it->end = ktime_get();
- 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_POWER;
- entry->state_data = *it;
- ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-
- trace_wake_up();
-
- out:
- preempt_enable();
-}
-EXPORT_SYMBOL_GPL(trace_power_end);
-
-void trace_power_mark(struct power_trace *it, unsigned int type,
- unsigned int level)
-{
- struct ring_buffer_event *event;
- struct trace_power *entry;
- struct trace_array_cpu *data;
- unsigned long irq_flags;
- struct trace_array *tr = power_trace;
-
- if (!trace_power_enabled)
- return;
-
- memset(it, 0, sizeof(struct power_trace));
- it->state = level;
- it->type = type;
- it->stamp = ktime_get();
- preempt_disable();
- it->end = it->stamp;
- 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_POWER;
- entry->state_data = *it;
- ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-
- trace_wake_up();
-
- out:
- preempt_enable();
-}
-EXPORT_SYMBOL_GPL(trace_power_mark);
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
new file mode 100644
index 00000000000..eb81556107f
--- /dev/null
+++ b/kernel/trace/trace_printk.c
@@ -0,0 +1,270 @@
+/*
+ * trace binary printk
+ *
+ * Copyright (C) 2008 Lai Jiangshan <laijs@cn.fujitsu.com>
+ *
+ */
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/ftrace.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/marker.h>
+#include <linux/mutex.h>
+#include <linux/ctype.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+
+#include "trace.h"
+
+#ifdef CONFIG_MODULES
+
+/*
+ * modules trace_printk()'s formats are autosaved in struct trace_bprintk_fmt
+ * which are queued on trace_bprintk_fmt_list.
+ */
+static LIST_HEAD(trace_bprintk_fmt_list);
+
+/* serialize accesses to trace_bprintk_fmt_list */
+static DEFINE_MUTEX(btrace_mutex);
+
+struct trace_bprintk_fmt {
+ struct list_head list;
+ char fmt[0];
+};
+
+static inline struct trace_bprintk_fmt *lookup_format(const char *fmt)
+{
+ struct trace_bprintk_fmt *pos;
+ list_for_each_entry(pos, &trace_bprintk_fmt_list, list) {
+ if (!strcmp(pos->fmt, fmt))
+ return pos;
+ }
+ return NULL;
+}
+
+static
+void hold_module_trace_bprintk_format(const char **start, const char **end)
+{
+ const char **iter;
+
+ mutex_lock(&btrace_mutex);
+ for (iter = start; iter < end; iter++) {
+ struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter);
+ if (tb_fmt) {
+ *iter = tb_fmt->fmt;
+ continue;
+ }
+
+ tb_fmt = kmalloc(offsetof(struct trace_bprintk_fmt, fmt)
+ + strlen(*iter) + 1, GFP_KERNEL);
+ if (tb_fmt) {
+ list_add_tail(&tb_fmt->list, &trace_bprintk_fmt_list);
+ strcpy(tb_fmt->fmt, *iter);
+ *iter = tb_fmt->fmt;
+ } else
+ *iter = NULL;
+ }
+ mutex_unlock(&btrace_mutex);
+}
+
+static int module_trace_bprintk_format_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+{
+ struct module *mod = data;
+ if (mod->num_trace_bprintk_fmt) {
+ const char **start = mod->trace_bprintk_fmt_start;
+ const char **end = start + mod->num_trace_bprintk_fmt;
+
+ if (val == MODULE_STATE_COMING)
+ hold_module_trace_bprintk_format(start, end);
+ }
+ return 0;
+}
+
+#else /* !CONFIG_MODULES */
+__init static int
+module_trace_bprintk_format_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+{
+ return 0;
+}
+#endif /* CONFIG_MODULES */
+
+
+__initdata_or_module static
+struct notifier_block module_trace_bprintk_format_nb = {
+ .notifier_call = module_trace_bprintk_format_notify,
+};
+
+int __trace_bprintk(unsigned long ip, const char *fmt, ...)
+ {
+ int ret;
+ va_list ap;
+
+ if (unlikely(!fmt))
+ return 0;
+
+ if (!(trace_flags & TRACE_ITER_PRINTK))
+ return 0;
+
+ va_start(ap, fmt);
+ ret = trace_vbprintk(ip, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__trace_bprintk);
+
+int __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap)
+ {
+ if (unlikely(!fmt))
+ return 0;
+
+ if (!(trace_flags & TRACE_ITER_PRINTK))
+ return 0;
+
+ return trace_vbprintk(ip, fmt, ap);
+}
+EXPORT_SYMBOL_GPL(__ftrace_vbprintk);
+
+int __trace_printk(unsigned long ip, const char *fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ if (!(trace_flags & TRACE_ITER_PRINTK))
+ return 0;
+
+ va_start(ap, fmt);
+ ret = trace_vprintk(ip, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__trace_printk);
+
+int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap)
+{
+ if (!(trace_flags & TRACE_ITER_PRINTK))
+ return 0;
+
+ return trace_vprintk(ip, fmt, ap);
+}
+EXPORT_SYMBOL_GPL(__ftrace_vprintk);
+
+static void *
+t_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ const char **fmt = m->private;
+ const char **next = fmt;
+
+ (*pos)++;
+
+ if ((unsigned long)fmt >= (unsigned long)__stop___trace_bprintk_fmt)
+ return NULL;
+
+ next = fmt;
+ m->private = ++next;
+
+ return fmt;
+}
+
+static void *t_start(struct seq_file *m, loff_t *pos)
+{
+ return t_next(m, NULL, pos);
+}
+
+static int t_show(struct seq_file *m, void *v)
+{
+ const char **fmt = v;
+ const char *str = *fmt;
+ int i;
+
+ seq_printf(m, "0x%lx : \"", (unsigned long)fmt);
+
+ /*
+ * Tabs and new lines need to be converted.
+ */
+ for (i = 0; str[i]; i++) {
+ switch (str[i]) {
+ case '\n':
+ seq_puts(m, "\\n");
+ break;
+ case '\t':
+ seq_puts(m, "\\t");
+ break;
+ case '\\':
+ seq_puts(m, "\\");
+ break;
+ case '"':
+ seq_puts(m, "\\\"");
+ break;
+ default:
+ seq_putc(m, str[i]);
+ }
+ }
+ seq_puts(m, "\"\n");
+
+ return 0;
+}
+
+static void t_stop(struct seq_file *m, void *p)
+{
+}
+
+static const struct seq_operations show_format_seq_ops = {
+ .start = t_start,
+ .next = t_next,
+ .show = t_show,
+ .stop = t_stop,
+};
+
+static int
+ftrace_formats_open(struct inode *inode, struct file *file)
+{
+ int ret;
+
+ ret = seq_open(file, &show_format_seq_ops);
+ if (!ret) {
+ struct seq_file *m = file->private_data;
+
+ m->private = __start___trace_bprintk_fmt;
+ }
+ return ret;
+}
+
+static const struct file_operations ftrace_formats_fops = {
+ .open = ftrace_formats_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static __init int init_trace_printk_function_export(void)
+{
+ struct dentry *d_tracer;
+ struct dentry *entry;
+
+ d_tracer = tracing_init_dentry();
+ if (!d_tracer)
+ return 0;
+
+ entry = debugfs_create_file("printk_formats", 0444, d_tracer,
+ NULL, &ftrace_formats_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs "
+ "'printk_formats' entry\n");
+
+ return 0;
+}
+
+fs_initcall(init_trace_printk_function_export);
+
+static __init int init_trace_printk(void)
+{
+ return register_module_notifier(&module_trace_bprintk_format_nb);
+}
+
+early_initcall(init_trace_printk);
diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c
index df175cb4564..9117cea6f1a 100644
--- a/kernel/trace/trace_sched_switch.c
+++ b/kernel/trace/trace_sched_switch.c
@@ -18,6 +18,7 @@ static struct trace_array *ctx_trace;
static int __read_mostly tracer_enabled;
static int sched_ref;
static DEFINE_MUTEX(sched_register_mutex);
+static int sched_stopped;
static void
probe_sched_switch(struct rq *__rq, struct task_struct *prev,
@@ -28,7 +29,7 @@ probe_sched_switch(struct rq *__rq, struct task_struct *prev,
int cpu;
int pc;
- if (!sched_ref)
+ if (!sched_ref || sched_stopped)
return;
tracing_record_cmdline(prev);
@@ -43,7 +44,7 @@ probe_sched_switch(struct rq *__rq, struct task_struct *prev,
data = ctx_trace->data[cpu];
if (likely(!atomic_read(&data->disabled)))
- tracing_sched_switch_trace(ctx_trace, data, prev, next, flags, pc);
+ tracing_sched_switch_trace(ctx_trace, prev, next, flags, pc);
local_irq_restore(flags);
}
@@ -61,12 +62,15 @@ probe_sched_wakeup(struct rq *__rq, struct task_struct *wakee, int success)
pc = preempt_count();
tracing_record_cmdline(current);
+ if (sched_stopped)
+ return;
+
local_irq_save(flags);
cpu = raw_smp_processor_id();
data = ctx_trace->data[cpu];
if (likely(!atomic_read(&data->disabled)))
- tracing_sched_wakeup_trace(ctx_trace, data, wakee, current,
+ tracing_sched_wakeup_trace(ctx_trace, wakee, current,
flags, pc);
local_irq_restore(flags);
@@ -93,7 +97,7 @@ static int tracing_sched_register(void)
ret = register_trace_sched_switch(probe_sched_switch);
if (ret) {
pr_info("sched trace: Couldn't activate tracepoint"
- " probe to kernel_sched_schedule\n");
+ " probe to kernel_sched_switch\n");
goto fail_deprobe_wake_new;
}
@@ -185,12 +189,6 @@ void tracing_sched_switch_assign_trace(struct trace_array *tr)
ctx_trace = tr;
}
-static void start_sched_trace(struct trace_array *tr)
-{
- tracing_reset_online_cpus(tr);
- tracing_start_sched_switch_record();
-}
-
static void stop_sched_trace(struct trace_array *tr)
{
tracing_stop_sched_switch_record();
@@ -199,7 +197,8 @@ static void stop_sched_trace(struct trace_array *tr)
static int sched_switch_trace_init(struct trace_array *tr)
{
ctx_trace = tr;
- start_sched_trace(tr);
+ tracing_reset_online_cpus(tr);
+ tracing_start_sched_switch_record();
return 0;
}
@@ -211,13 +210,12 @@ static void sched_switch_trace_reset(struct trace_array *tr)
static void sched_switch_trace_start(struct trace_array *tr)
{
- tracing_reset_online_cpus(tr);
- tracing_start_sched_switch();
+ sched_stopped = 0;
}
static void sched_switch_trace_stop(struct trace_array *tr)
{
- tracing_stop_sched_switch();
+ sched_stopped = 1;
}
static struct tracer sched_switch_trace __read_mostly =
@@ -227,6 +225,7 @@ static struct tracer sched_switch_trace __read_mostly =
.reset = sched_switch_trace_reset,
.start = sched_switch_trace_start,
.stop = sched_switch_trace_stop,
+ .wait_pipe = poll_wait_pipe,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_sched_switch,
#endif
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c
index 42ae1e77b6b..5bc00e8f153 100644
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -25,12 +25,15 @@ static int __read_mostly tracer_enabled;
static struct task_struct *wakeup_task;
static int wakeup_cpu;
static unsigned wakeup_prio = -1;
+static int wakeup_rt;
static raw_spinlock_t wakeup_lock =
(raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
static void __wakeup_reset(struct trace_array *tr);
+static int save_lat_flag;
+
#ifdef CONFIG_FUNCTION_TRACER
/*
* irqsoff uses its own tracer function to keep the overhead down:
@@ -71,7 +74,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, pc);
+ trace_function(tr, ip, parent_ip, flags, pc);
unlock:
__raw_spin_unlock(&wakeup_lock);
@@ -151,7 +154,8 @@ probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
if (unlikely(!tracer_enabled || next != wakeup_task))
goto out_unlock;
- trace_function(wakeup_trace, data, CALLER_ADDR1, CALLER_ADDR2, flags, pc);
+ trace_function(wakeup_trace, CALLER_ADDR0, CALLER_ADDR1, flags, pc);
+ tracing_sched_switch_trace(wakeup_trace, prev, next, flags, pc);
/*
* usecs conversion is slow so we try to delay the conversion
@@ -182,13 +186,10 @@ out:
static void __wakeup_reset(struct trace_array *tr)
{
- struct trace_array_cpu *data;
int cpu;
- for_each_possible_cpu(cpu) {
- data = tr->data[cpu];
+ for_each_possible_cpu(cpu)
tracing_reset(tr, cpu);
- }
wakeup_cpu = -1;
wakeup_prio = -1;
@@ -213,6 +214,7 @@ static void wakeup_reset(struct trace_array *tr)
static void
probe_wakeup(struct rq *rq, struct task_struct *p, int success)
{
+ struct trace_array_cpu *data;
int cpu = smp_processor_id();
unsigned long flags;
long disabled;
@@ -224,7 +226,7 @@ probe_wakeup(struct rq *rq, struct task_struct *p, int success)
tracing_record_cmdline(p);
tracing_record_cmdline(current);
- if (likely(!rt_task(p)) ||
+ if ((wakeup_rt && !rt_task(p)) ||
p->prio >= wakeup_prio ||
p->prio >= current->prio)
return;
@@ -252,9 +254,16 @@ probe_wakeup(struct rq *rq, struct task_struct *p, int success)
local_save_flags(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);
+ data = wakeup_trace->data[wakeup_cpu];
+ data->preempt_timestamp = ftrace_now(cpu);
+ tracing_sched_wakeup_trace(wakeup_trace, p, current, flags, pc);
+
+ /*
+ * We must be careful in using CALLER_ADDR2. But since wake_up
+ * is not called by an assembly function (where as schedule is)
+ * it should be safe to use it here.
+ */
+ trace_function(wakeup_trace, CALLER_ADDR1, CALLER_ADDR2, flags, pc);
out_locked:
__raw_spin_unlock(&wakeup_lock);
@@ -262,12 +271,6 @@ out:
atomic_dec(&wakeup_trace->data[cpu]->disabled);
}
-/*
- * save_tracer_enabled is used to save the state of the tracer_enabled
- * variable when we disable it when we open a trace output file.
- */
-static int save_tracer_enabled;
-
static void start_wakeup_tracer(struct trace_array *tr)
{
int ret;
@@ -289,7 +292,7 @@ static void start_wakeup_tracer(struct trace_array *tr)
ret = register_trace_sched_switch(probe_wakeup_sched_switch);
if (ret) {
pr_info("sched trace: Couldn't activate tracepoint"
- " probe to kernel_sched_schedule\n");
+ " probe to kernel_sched_switch\n");
goto fail_deprobe_wake_new;
}
@@ -306,13 +309,10 @@ static void start_wakeup_tracer(struct trace_array *tr)
register_ftrace_function(&trace_ops);
- if (tracing_is_enabled()) {
+ if (tracing_is_enabled())
tracer_enabled = 1;
- save_tracer_enabled = 1;
- } else {
+ else
tracer_enabled = 0;
- save_tracer_enabled = 0;
- }
return;
fail_deprobe_wake_new:
@@ -324,54 +324,54 @@ fail_deprobe:
static void stop_wakeup_tracer(struct trace_array *tr)
{
tracer_enabled = 0;
- save_tracer_enabled = 0;
unregister_ftrace_function(&trace_ops);
unregister_trace_sched_switch(probe_wakeup_sched_switch);
unregister_trace_sched_wakeup_new(probe_wakeup);
unregister_trace_sched_wakeup(probe_wakeup);
}
-static int wakeup_tracer_init(struct trace_array *tr)
+static int __wakeup_tracer_init(struct trace_array *tr)
{
+ save_lat_flag = trace_flags & TRACE_ITER_LATENCY_FMT;
+ trace_flags |= TRACE_ITER_LATENCY_FMT;
+
tracing_max_latency = 0;
wakeup_trace = tr;
start_wakeup_tracer(tr);
return 0;
}
+static int wakeup_tracer_init(struct trace_array *tr)
+{
+ wakeup_rt = 0;
+ return __wakeup_tracer_init(tr);
+}
+
+static int wakeup_rt_tracer_init(struct trace_array *tr)
+{
+ wakeup_rt = 1;
+ return __wakeup_tracer_init(tr);
+}
+
static void wakeup_tracer_reset(struct trace_array *tr)
{
stop_wakeup_tracer(tr);
/* make sure we put back any tasks we are tracing */
wakeup_reset(tr);
+
+ if (!save_lat_flag)
+ trace_flags &= ~TRACE_ITER_LATENCY_FMT;
}
static void wakeup_tracer_start(struct trace_array *tr)
{
wakeup_reset(tr);
tracer_enabled = 1;
- save_tracer_enabled = 1;
}
static void wakeup_tracer_stop(struct trace_array *tr)
{
tracer_enabled = 0;
- save_tracer_enabled = 0;
-}
-
-static void wakeup_tracer_open(struct trace_iterator *iter)
-{
- /* stop the trace while dumping */
- tracer_enabled = 0;
-}
-
-static void wakeup_tracer_close(struct trace_iterator *iter)
-{
- /* forget about any processes we were recording */
- if (save_tracer_enabled) {
- wakeup_reset(iter->tr);
- tracer_enabled = 1;
- }
}
static struct tracer wakeup_tracer __read_mostly =
@@ -381,8 +381,20 @@ static struct tracer wakeup_tracer __read_mostly =
.reset = wakeup_tracer_reset,
.start = wakeup_tracer_start,
.stop = wakeup_tracer_stop,
- .open = wakeup_tracer_open,
- .close = wakeup_tracer_close,
+ .print_max = 1,
+#ifdef CONFIG_FTRACE_SELFTEST
+ .selftest = trace_selftest_startup_wakeup,
+#endif
+};
+
+static struct tracer wakeup_rt_tracer __read_mostly =
+{
+ .name = "wakeup_rt",
+ .init = wakeup_rt_tracer_init,
+ .reset = wakeup_tracer_reset,
+ .start = wakeup_tracer_start,
+ .stop = wakeup_tracer_stop,
+ .wait_pipe = poll_wait_pipe,
.print_max = 1,
#ifdef CONFIG_FTRACE_SELFTEST
.selftest = trace_selftest_startup_wakeup,
@@ -397,6 +409,10 @@ __init static int init_wakeup_tracer(void)
if (ret)
return ret;
+ ret = register_tracer(&wakeup_rt_tracer);
+ if (ret)
+ return ret;
+
return 0;
}
device_initcall(init_wakeup_tracer);
diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
index bc8e80a86bc..08f4eb2763d 100644
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -1,5 +1,6 @@
/* Include in trace.c */
+#include <linux/stringify.h>
#include <linux/kthread.h>
#include <linux/delay.h>
@@ -9,11 +10,12 @@ 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:
case TRACE_BRANCH:
+ case TRACE_GRAPH_ENT:
+ case TRACE_GRAPH_RET:
return 1;
}
return 0;
@@ -99,9 +101,6 @@ static inline void warn_failed_init_tracer(struct tracer *trace, int init_ret)
#ifdef CONFIG_DYNAMIC_FTRACE
-#define __STR(x) #x
-#define STR(x) __STR(x)
-
/* Test dynamic code modification and ftrace filters */
int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
struct trace_array *tr,
@@ -125,17 +124,17 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
func();
/*
- * Some archs *cough*PowerPC*cough* add charachters to the
+ * Some archs *cough*PowerPC*cough* add characters to the
* start of the function names. We simply put a '*' to
- * accomodate them.
+ * accommodate them.
*/
- func_name = "*" STR(DYN_FTRACE_TEST_NAME);
+ func_name = "*" __stringify(DYN_FTRACE_TEST_NAME);
/* filter only on our function */
ftrace_set_filter(func_name, strlen(func_name), 1);
/* enable tracing */
- ret = trace->init(tr);
+ ret = tracer_init(trace, tr);
if (ret) {
warn_failed_init_tracer(trace, ret);
goto out;
@@ -209,7 +208,7 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
ftrace_enabled = 1;
tracer_enabled = 1;
- ret = trace->init(tr);
+ ret = tracer_init(trace, tr);
if (ret) {
warn_failed_init_tracer(trace, ret);
goto out;
@@ -247,6 +246,90 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
}
#endif /* CONFIG_FUNCTION_TRACER */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+/* Maximum number of functions to trace before diagnosing a hang */
+#define GRAPH_MAX_FUNC_TEST 100000000
+
+static void __ftrace_dump(bool disable_tracing);
+static unsigned int graph_hang_thresh;
+
+/* Wrap the real function entry probe to avoid possible hanging */
+static int trace_graph_entry_watchdog(struct ftrace_graph_ent *trace)
+{
+ /* This is harmlessly racy, we want to approximately detect a hang */
+ if (unlikely(++graph_hang_thresh > GRAPH_MAX_FUNC_TEST)) {
+ ftrace_graph_stop();
+ printk(KERN_WARNING "BUG: Function graph tracer hang!\n");
+ if (ftrace_dump_on_oops)
+ __ftrace_dump(false);
+ return 0;
+ }
+
+ return trace_graph_entry(trace);
+}
+
+/*
+ * Pretty much the same than for the function tracer from which the selftest
+ * has been borrowed.
+ */
+int
+trace_selftest_startup_function_graph(struct tracer *trace,
+ struct trace_array *tr)
+{
+ int ret;
+ unsigned long count;
+
+ /*
+ * Simulate the init() callback but we attach a watchdog callback
+ * to detect and recover from possible hangs
+ */
+ tracing_reset_online_cpus(tr);
+ ret = register_ftrace_graph(&trace_graph_return,
+ &trace_graph_entry_watchdog);
+ if (ret) {
+ warn_failed_init_tracer(trace, ret);
+ goto out;
+ }
+ tracing_start_cmdline_record();
+
+ /* Sleep for a 1/10 of a second */
+ msleep(100);
+
+ /* Have we just recovered from a hang? */
+ if (graph_hang_thresh > GRAPH_MAX_FUNC_TEST) {
+ tracing_selftest_disabled = true;
+ ret = -1;
+ goto out;
+ }
+
+ tracing_stop();
+
+ /* check the trace buffer */
+ ret = trace_test_buffer(tr, &count);
+
+ trace->reset(tr);
+ tracing_start();
+
+ if (!ret && !count) {
+ printk(KERN_CONT ".. no entries found ..");
+ ret = -1;
+ goto out;
+ }
+
+ /* Don't test dynamic tracing, the function tracer already did */
+
+out:
+ /* Stop it if we failed */
+ if (ret)
+ ftrace_graph_stop();
+
+ return ret;
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+
#ifdef CONFIG_IRQSOFF_TRACER
int
trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr)
@@ -256,7 +339,7 @@ trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr)
int ret;
/* start the tracing */
- ret = trace->init(tr);
+ ret = tracer_init(trace, tr);
if (ret) {
warn_failed_init_tracer(trace, ret);
return ret;
@@ -268,6 +351,14 @@ trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr)
local_irq_disable();
udelay(100);
local_irq_enable();
+
+ /*
+ * Stop the tracer to avoid a warning subsequent
+ * to buffer flipping failure because tracing_stop()
+ * disables the tr and max buffers, making flipping impossible
+ * in case of parallels max irqs off latencies.
+ */
+ trace->stop(tr);
/* stop the tracing. */
tracing_stop();
/* check both trace buffers */
@@ -310,7 +401,7 @@ trace_selftest_startup_preemptoff(struct tracer *trace, struct trace_array *tr)
}
/* start the tracing */
- ret = trace->init(tr);
+ ret = tracer_init(trace, tr);
if (ret) {
warn_failed_init_tracer(trace, ret);
return ret;
@@ -322,6 +413,14 @@ trace_selftest_startup_preemptoff(struct tracer *trace, struct trace_array *tr)
preempt_disable();
udelay(100);
preempt_enable();
+
+ /*
+ * Stop the tracer to avoid a warning subsequent
+ * to buffer flipping failure because tracing_stop()
+ * disables the tr and max buffers, making flipping impossible
+ * in case of parallels max preempt off latencies.
+ */
+ trace->stop(tr);
/* stop the tracing. */
tracing_stop();
/* check both trace buffers */
@@ -364,10 +463,10 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *
}
/* start the tracing */
- ret = trace->init(tr);
+ ret = tracer_init(trace, tr);
if (ret) {
warn_failed_init_tracer(trace, ret);
- goto out;
+ goto out_no_start;
}
/* reset the max latency */
@@ -381,31 +480,35 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *
/* reverse the order of preempt vs irqs */
local_irq_enable();
+ /*
+ * Stop the tracer to avoid a warning subsequent
+ * to buffer flipping failure because tracing_stop()
+ * disables the tr and max buffers, making flipping impossible
+ * in case of parallels max irqs/preempt off latencies.
+ */
+ trace->stop(tr);
/* stop the tracing. */
tracing_stop();
/* check both trace buffers */
ret = trace_test_buffer(tr, NULL);
- if (ret) {
- tracing_start();
+ if (ret)
goto out;
- }
ret = trace_test_buffer(&max_tr, &count);
- if (ret) {
- tracing_start();
+ if (ret)
goto out;
- }
if (!ret && !count) {
printk(KERN_CONT ".. no entries found ..");
ret = -1;
- tracing_start();
goto out;
}
/* do the test by disabling interrupts first this time */
tracing_max_latency = 0;
tracing_start();
+ trace->start(tr);
+
preempt_disable();
local_irq_disable();
udelay(100);
@@ -413,6 +516,7 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *
/* reverse the order of preempt vs irqs */
local_irq_enable();
+ trace->stop(tr);
/* stop the tracing. */
tracing_stop();
/* check both trace buffers */
@@ -428,9 +532,10 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *
goto out;
}
- out:
- trace->reset(tr);
+out:
tracing_start();
+out_no_start:
+ trace->reset(tr);
tracing_max_latency = save_max;
return ret;
@@ -496,7 +601,7 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr)
wait_for_completion(&isrt);
/* start the tracing */
- ret = trace->init(tr);
+ ret = tracer_init(trace, tr);
if (ret) {
warn_failed_init_tracer(trace, ret);
return ret;
@@ -557,7 +662,7 @@ trace_selftest_startup_sched_switch(struct tracer *trace, struct trace_array *tr
int ret;
/* start the tracing */
- ret = trace->init(tr);
+ ret = tracer_init(trace, tr);
if (ret) {
warn_failed_init_tracer(trace, ret);
return ret;
@@ -589,10 +694,10 @@ trace_selftest_startup_sysprof(struct tracer *trace, struct trace_array *tr)
int ret;
/* start the tracing */
- ret = trace->init(tr);
+ ret = tracer_init(trace, tr);
if (ret) {
warn_failed_init_tracer(trace, ret);
- return 0;
+ return ret;
}
/* Sleep for a 1/10 of a second */
@@ -604,6 +709,11 @@ trace_selftest_startup_sysprof(struct tracer *trace, struct trace_array *tr)
trace->reset(tr);
tracing_start();
+ if (!ret && !count) {
+ printk(KERN_CONT ".. no entries found ..");
+ ret = -1;
+ }
+
return ret;
}
#endif /* CONFIG_SYSPROF_TRACER */
@@ -616,7 +726,7 @@ trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
int ret;
/* start the tracing */
- ret = trace->init(tr);
+ ret = tracer_init(trace, tr);
if (ret) {
warn_failed_init_tracer(trace, ret);
return ret;
@@ -631,6 +741,11 @@ trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
trace->reset(tr);
tracing_start();
+ if (!ret && !count) {
+ printk(KERN_CONT ".. no entries found ..");
+ ret = -1;
+ }
+
return ret;
}
#endif /* CONFIG_BRANCH_TRACER */
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index d0871bc0aca..c750f65f966 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -245,16 +245,31 @@ static int trace_lookup_stack(struct seq_file *m, long i)
#endif
}
+static void print_disabled(struct seq_file *m)
+{
+ seq_puts(m, "#\n"
+ "# Stack tracer disabled\n"
+ "#\n"
+ "# To enable the stack tracer, either add 'stacktrace' to the\n"
+ "# kernel command line\n"
+ "# or 'echo 1 > /proc/sys/kernel/stack_tracer_enabled'\n"
+ "#\n");
+}
+
static int t_show(struct seq_file *m, void *v)
{
long i;
int size;
if (v == SEQ_START_TOKEN) {
- seq_printf(m, " Depth Size Location"
+ seq_printf(m, " Depth Size Location"
" (%d entries)\n"
- " ----- ---- --------\n",
+ " ----- ---- --------\n",
max_stack_trace.nr_entries);
+
+ if (!stack_tracer_enabled && !max_stack_size)
+ print_disabled(m);
+
return 0;
}
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c
new file mode 100644
index 00000000000..acdebd771a9
--- /dev/null
+++ b/kernel/trace/trace_stat.c
@@ -0,0 +1,326 @@
+/*
+ * Infrastructure for statistic tracing (histogram output).
+ *
+ * Copyright (C) 2008 Frederic Weisbecker <fweisbec@gmail.com>
+ *
+ * Based on the code from trace_branch.c which is
+ * Copyright (C) 2008 Steven Rostedt <srostedt@redhat.com>
+ *
+ */
+
+
+#include <linux/list.h>
+#include <linux/debugfs.h>
+#include "trace_stat.h"
+#include "trace.h"
+
+
+/* List of stat entries from a tracer */
+struct trace_stat_list {
+ struct list_head list;
+ void *stat;
+};
+
+/* A stat session is the stats output in one file */
+struct tracer_stat_session {
+ struct list_head session_list;
+ struct tracer_stat *ts;
+ struct list_head stat_list;
+ struct mutex stat_mutex;
+ struct dentry *file;
+};
+
+/* All of the sessions currently in use. Each stat file embed one session */
+static LIST_HEAD(all_stat_sessions);
+static DEFINE_MUTEX(all_stat_sessions_mutex);
+
+/* The root directory for all stat files */
+static struct dentry *stat_dir;
+
+
+static void reset_stat_session(struct tracer_stat_session *session)
+{
+ struct trace_stat_list *node, *next;
+
+ list_for_each_entry_safe(node, next, &session->stat_list, list)
+ kfree(node);
+
+ INIT_LIST_HEAD(&session->stat_list);
+}
+
+static void destroy_session(struct tracer_stat_session *session)
+{
+ debugfs_remove(session->file);
+ reset_stat_session(session);
+ mutex_destroy(&session->stat_mutex);
+ kfree(session);
+}
+
+/*
+ * For tracers that don't provide a stat_cmp callback.
+ * This one will force an immediate insertion on tail of
+ * the list.
+ */
+static int dummy_cmp(void *p1, void *p2)
+{
+ return 1;
+}
+
+/*
+ * Initialize the stat list at each trace_stat file opening.
+ * All of these copies and sorting are required on all opening
+ * since the stats could have changed between two file sessions.
+ */
+static int stat_seq_init(struct tracer_stat_session *session)
+{
+ struct trace_stat_list *iter_entry, *new_entry;
+ struct tracer_stat *ts = session->ts;
+ void *stat;
+ int ret = 0;
+ int i;
+
+ mutex_lock(&session->stat_mutex);
+ reset_stat_session(session);
+
+ if (!ts->stat_cmp)
+ ts->stat_cmp = dummy_cmp;
+
+ stat = ts->stat_start();
+ if (!stat)
+ goto exit;
+
+ /*
+ * The first entry. Actually this is the second, but the first
+ * one (the stat_list head) is pointless.
+ */
+ new_entry = kmalloc(sizeof(struct trace_stat_list), GFP_KERNEL);
+ if (!new_entry) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ INIT_LIST_HEAD(&new_entry->list);
+
+ list_add(&new_entry->list, &session->stat_list);
+
+ new_entry->stat = stat;
+
+ /*
+ * Iterate over the tracer stat entries and store them in a sorted
+ * list.
+ */
+ for (i = 1; ; i++) {
+ stat = ts->stat_next(stat, i);
+
+ /* End of insertion */
+ if (!stat)
+ break;
+
+ new_entry = kmalloc(sizeof(struct trace_stat_list), GFP_KERNEL);
+ if (!new_entry) {
+ ret = -ENOMEM;
+ goto exit_free_list;
+ }
+
+ INIT_LIST_HEAD(&new_entry->list);
+ new_entry->stat = stat;
+
+ list_for_each_entry_reverse(iter_entry, &session->stat_list,
+ list) {
+
+ /* Insertion with a descendent sorting */
+ if (ts->stat_cmp(iter_entry->stat,
+ new_entry->stat) >= 0) {
+
+ list_add(&new_entry->list, &iter_entry->list);
+ break;
+ }
+ }
+
+ /* The current larger value */
+ if (list_empty(&new_entry->list))
+ list_add(&new_entry->list, &session->stat_list);
+ }
+exit:
+ mutex_unlock(&session->stat_mutex);
+ return ret;
+
+exit_free_list:
+ reset_stat_session(session);
+ mutex_unlock(&session->stat_mutex);
+ return ret;
+}
+
+
+static void *stat_seq_start(struct seq_file *s, loff_t *pos)
+{
+ struct tracer_stat_session *session = s->private;
+
+ /* Prevent from tracer switch or stat_list modification */
+ mutex_lock(&session->stat_mutex);
+
+ /* If we are in the beginning of the file, print the headers */
+ if (!*pos && session->ts->stat_headers)
+ return SEQ_START_TOKEN;
+
+ return seq_list_start(&session->stat_list, *pos);
+}
+
+static void *stat_seq_next(struct seq_file *s, void *p, loff_t *pos)
+{
+ struct tracer_stat_session *session = s->private;
+
+ if (p == SEQ_START_TOKEN)
+ return seq_list_start(&session->stat_list, *pos);
+
+ return seq_list_next(p, &session->stat_list, pos);
+}
+
+static void stat_seq_stop(struct seq_file *s, void *p)
+{
+ struct tracer_stat_session *session = s->private;
+ mutex_unlock(&session->stat_mutex);
+}
+
+static int stat_seq_show(struct seq_file *s, void *v)
+{
+ struct tracer_stat_session *session = s->private;
+ struct trace_stat_list *l = list_entry(v, struct trace_stat_list, list);
+
+ if (v == SEQ_START_TOKEN)
+ return session->ts->stat_headers(s);
+
+ return session->ts->stat_show(s, l->stat);
+}
+
+static const struct seq_operations trace_stat_seq_ops = {
+ .start = stat_seq_start,
+ .next = stat_seq_next,
+ .stop = stat_seq_stop,
+ .show = stat_seq_show
+};
+
+/* The session stat is refilled and resorted at each stat file opening */
+static int tracing_stat_open(struct inode *inode, struct file *file)
+{
+ int ret;
+
+ struct tracer_stat_session *session = inode->i_private;
+
+ ret = seq_open(file, &trace_stat_seq_ops);
+ if (!ret) {
+ struct seq_file *m = file->private_data;
+ m->private = session;
+ ret = stat_seq_init(session);
+ }
+
+ return ret;
+}
+
+/*
+ * Avoid consuming memory with our now useless list.
+ */
+static int tracing_stat_release(struct inode *i, struct file *f)
+{
+ struct tracer_stat_session *session = i->i_private;
+
+ mutex_lock(&session->stat_mutex);
+ reset_stat_session(session);
+ mutex_unlock(&session->stat_mutex);
+
+ return 0;
+}
+
+static const struct file_operations tracing_stat_fops = {
+ .open = tracing_stat_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = tracing_stat_release
+};
+
+static int tracing_stat_init(void)
+{
+ struct dentry *d_tracing;
+
+ d_tracing = tracing_init_dentry();
+
+ stat_dir = debugfs_create_dir("trace_stat", d_tracing);
+ if (!stat_dir)
+ pr_warning("Could not create debugfs "
+ "'trace_stat' entry\n");
+ return 0;
+}
+
+static int init_stat_file(struct tracer_stat_session *session)
+{
+ if (!stat_dir && tracing_stat_init())
+ return -ENODEV;
+
+ session->file = debugfs_create_file(session->ts->name, 0644,
+ stat_dir,
+ session, &tracing_stat_fops);
+ if (!session->file)
+ return -ENOMEM;
+ return 0;
+}
+
+int register_stat_tracer(struct tracer_stat *trace)
+{
+ struct tracer_stat_session *session, *node, *tmp;
+ int ret;
+
+ if (!trace)
+ return -EINVAL;
+
+ if (!trace->stat_start || !trace->stat_next || !trace->stat_show)
+ return -EINVAL;
+
+ /* Already registered? */
+ mutex_lock(&all_stat_sessions_mutex);
+ list_for_each_entry_safe(node, tmp, &all_stat_sessions, session_list) {
+ if (node->ts == trace) {
+ mutex_unlock(&all_stat_sessions_mutex);
+ return -EINVAL;
+ }
+ }
+ mutex_unlock(&all_stat_sessions_mutex);
+
+ /* Init the session */
+ session = kmalloc(sizeof(struct tracer_stat_session), GFP_KERNEL);
+ if (!session)
+ return -ENOMEM;
+
+ session->ts = trace;
+ INIT_LIST_HEAD(&session->session_list);
+ INIT_LIST_HEAD(&session->stat_list);
+ mutex_init(&session->stat_mutex);
+ session->file = NULL;
+
+ ret = init_stat_file(session);
+ if (ret) {
+ destroy_session(session);
+ return ret;
+ }
+
+ /* Register */
+ mutex_lock(&all_stat_sessions_mutex);
+ list_add_tail(&session->session_list, &all_stat_sessions);
+ mutex_unlock(&all_stat_sessions_mutex);
+
+ return 0;
+}
+
+void unregister_stat_tracer(struct tracer_stat *trace)
+{
+ struct tracer_stat_session *node, *tmp;
+
+ mutex_lock(&all_stat_sessions_mutex);
+ list_for_each_entry_safe(node, tmp, &all_stat_sessions, session_list) {
+ if (node->ts == trace) {
+ list_del(&node->session_list);
+ destroy_session(node);
+ break;
+ }
+ }
+ mutex_unlock(&all_stat_sessions_mutex);
+}
diff --git a/kernel/trace/trace_stat.h b/kernel/trace/trace_stat.h
new file mode 100644
index 00000000000..202274cf7f3
--- /dev/null
+++ b/kernel/trace/trace_stat.h
@@ -0,0 +1,31 @@
+#ifndef __TRACE_STAT_H
+#define __TRACE_STAT_H
+
+#include <linux/seq_file.h>
+
+/*
+ * If you want to provide a stat file (one-shot statistics), fill
+ * an iterator with stat_start/stat_next and a stat_show callbacks.
+ * The others callbacks are optional.
+ */
+struct tracer_stat {
+ /* The name of your stat file */
+ const char *name;
+ /* Iteration over statistic entries */
+ void *(*stat_start)(void);
+ void *(*stat_next)(void *prev, int idx);
+ /* Compare two entries for stats sorting */
+ int (*stat_cmp)(void *p1, void *p2);
+ /* Print a stat entry */
+ int (*stat_show)(struct seq_file *s, void *p);
+ /* Print the headers of your stat entries */
+ int (*stat_headers)(struct seq_file *s);
+};
+
+/*
+ * Destroy or create a stat file
+ */
+extern int register_stat_tracer(struct tracer_stat *trace);
+extern void unregister_stat_tracer(struct tracer_stat *trace);
+
+#endif /* __TRACE_STAT_H */
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
new file mode 100644
index 00000000000..5e579645ac8
--- /dev/null
+++ b/kernel/trace/trace_syscalls.c
@@ -0,0 +1,250 @@
+#include <trace/syscall.h>
+#include <linux/kernel.h>
+#include <asm/syscall.h>
+
+#include "trace_output.h"
+#include "trace.h"
+
+/* Keep a counter of the syscall tracing users */
+static int refcount;
+
+/* Prevent from races on thread flags toggling */
+static DEFINE_MUTEX(syscall_trace_lock);
+
+/* Option to display the parameters types */
+enum {
+ TRACE_SYSCALLS_OPT_TYPES = 0x1,
+};
+
+static struct tracer_opt syscalls_opts[] = {
+ { TRACER_OPT(syscall_arg_type, TRACE_SYSCALLS_OPT_TYPES) },
+ { }
+};
+
+static struct tracer_flags syscalls_flags = {
+ .val = 0, /* By default: no parameters types */
+ .opts = syscalls_opts
+};
+
+enum print_line_t
+print_syscall_enter(struct trace_iterator *iter, int flags)
+{
+ struct trace_seq *s = &iter->seq;
+ struct trace_entry *ent = iter->ent;
+ struct syscall_trace_enter *trace;
+ struct syscall_metadata *entry;
+ int i, ret, syscall;
+
+ trace_assign_type(trace, ent);
+
+ syscall = trace->nr;
+
+ entry = syscall_nr_to_meta(syscall);
+ if (!entry)
+ goto end;
+
+ ret = trace_seq_printf(s, "%s(", entry->name);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ for (i = 0; i < entry->nb_args; i++) {
+ /* parameter types */
+ if (syscalls_flags.val & TRACE_SYSCALLS_OPT_TYPES) {
+ ret = trace_seq_printf(s, "%s ", entry->types[i]);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+ }
+ /* parameter values */
+ ret = trace_seq_printf(s, "%s: %lx%s ", entry->args[i],
+ trace->args[i],
+ i == entry->nb_args - 1 ? ")" : ",");
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+ }
+
+end:
+ trace_seq_printf(s, "\n");
+ return TRACE_TYPE_HANDLED;
+}
+
+enum print_line_t
+print_syscall_exit(struct trace_iterator *iter, int flags)
+{
+ struct trace_seq *s = &iter->seq;
+ struct trace_entry *ent = iter->ent;
+ struct syscall_trace_exit *trace;
+ int syscall;
+ struct syscall_metadata *entry;
+ int ret;
+
+ trace_assign_type(trace, ent);
+
+ syscall = trace->nr;
+
+ entry = syscall_nr_to_meta(syscall);
+ if (!entry) {
+ trace_seq_printf(s, "\n");
+ return TRACE_TYPE_HANDLED;
+ }
+
+ ret = trace_seq_printf(s, "%s -> 0x%lx\n", entry->name,
+ trace->ret);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ return TRACE_TYPE_HANDLED;
+}
+
+void start_ftrace_syscalls(void)
+{
+ unsigned long flags;
+ struct task_struct *g, *t;
+
+ mutex_lock(&syscall_trace_lock);
+
+ /* Don't enable the flag on the tasks twice */
+ if (++refcount != 1)
+ goto unlock;
+
+ arch_init_ftrace_syscalls();
+ read_lock_irqsave(&tasklist_lock, flags);
+
+ do_each_thread(g, t) {
+ set_tsk_thread_flag(t, TIF_SYSCALL_FTRACE);
+ } while_each_thread(g, t);
+
+ read_unlock_irqrestore(&tasklist_lock, flags);
+
+unlock:
+ mutex_unlock(&syscall_trace_lock);
+}
+
+void stop_ftrace_syscalls(void)
+{
+ unsigned long flags;
+ struct task_struct *g, *t;
+
+ mutex_lock(&syscall_trace_lock);
+
+ /* There are perhaps still some users */
+ if (--refcount)
+ goto unlock;
+
+ read_lock_irqsave(&tasklist_lock, flags);
+
+ do_each_thread(g, t) {
+ clear_tsk_thread_flag(t, TIF_SYSCALL_FTRACE);
+ } while_each_thread(g, t);
+
+ read_unlock_irqrestore(&tasklist_lock, flags);
+
+unlock:
+ mutex_unlock(&syscall_trace_lock);
+}
+
+void ftrace_syscall_enter(struct pt_regs *regs)
+{
+ struct syscall_trace_enter *entry;
+ struct syscall_metadata *sys_data;
+ struct ring_buffer_event *event;
+ int size;
+ int syscall_nr;
+
+ syscall_nr = syscall_get_nr(current, regs);
+
+ sys_data = syscall_nr_to_meta(syscall_nr);
+ if (!sys_data)
+ return;
+
+ size = sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args;
+
+ event = trace_current_buffer_lock_reserve(TRACE_SYSCALL_ENTER, size,
+ 0, 0);
+ if (!event)
+ return;
+
+ entry = ring_buffer_event_data(event);
+ entry->nr = syscall_nr;
+ syscall_get_arguments(current, regs, 0, sys_data->nb_args, entry->args);
+
+ trace_current_buffer_unlock_commit(event, 0, 0);
+ trace_wake_up();
+}
+
+void ftrace_syscall_exit(struct pt_regs *regs)
+{
+ struct syscall_trace_exit *entry;
+ struct syscall_metadata *sys_data;
+ struct ring_buffer_event *event;
+ int syscall_nr;
+
+ syscall_nr = syscall_get_nr(current, regs);
+
+ sys_data = syscall_nr_to_meta(syscall_nr);
+ if (!sys_data)
+ return;
+
+ event = trace_current_buffer_lock_reserve(TRACE_SYSCALL_EXIT,
+ sizeof(*entry), 0, 0);
+ if (!event)
+ return;
+
+ entry = ring_buffer_event_data(event);
+ entry->nr = syscall_nr;
+ entry->ret = syscall_get_return_value(current, regs);
+
+ trace_current_buffer_unlock_commit(event, 0, 0);
+ trace_wake_up();
+}
+
+static int init_syscall_tracer(struct trace_array *tr)
+{
+ start_ftrace_syscalls();
+
+ return 0;
+}
+
+static void reset_syscall_tracer(struct trace_array *tr)
+{
+ stop_ftrace_syscalls();
+ tracing_reset_online_cpus(tr);
+}
+
+static struct trace_event syscall_enter_event = {
+ .type = TRACE_SYSCALL_ENTER,
+ .trace = print_syscall_enter,
+};
+
+static struct trace_event syscall_exit_event = {
+ .type = TRACE_SYSCALL_EXIT,
+ .trace = print_syscall_exit,
+};
+
+static struct tracer syscall_tracer __read_mostly = {
+ .name = "syscall",
+ .init = init_syscall_tracer,
+ .reset = reset_syscall_tracer,
+ .flags = &syscalls_flags,
+};
+
+__init int register_ftrace_syscalls(void)
+{
+ int ret;
+
+ ret = register_ftrace_event(&syscall_enter_event);
+ if (!ret) {
+ printk(KERN_WARNING "event %d failed to register\n",
+ syscall_enter_event.type);
+ WARN_ON_ONCE(1);
+ }
+
+ ret = register_ftrace_event(&syscall_exit_event);
+ if (!ret) {
+ printk(KERN_WARNING "event %d failed to register\n",
+ syscall_exit_event.type);
+ WARN_ON_ONCE(1);
+ }
+
+ return register_tracer(&syscall_tracer);
+}
+device_initcall(register_ftrace_syscalls);
diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c
index eaca5ad803f..91fd19c2149 100644
--- a/kernel/trace/trace_sysprof.c
+++ b/kernel/trace/trace_sysprof.c
@@ -88,7 +88,7 @@ static void backtrace_address(void *data, unsigned long addr, int reliable)
}
}
-const static struct stacktrace_ops backtrace_ops = {
+static const struct stacktrace_ops backtrace_ops = {
.warning = backtrace_warning,
.warning_symbol = backtrace_warning_symbol,
.stack = backtrace_stack,
@@ -226,15 +226,6 @@ static void stop_stack_timers(void)
stop_stack_timer(cpu);
}
-static void start_stack_trace(struct trace_array *tr)
-{
- mutex_lock(&sample_timer_lock);
- tracing_reset_online_cpus(tr);
- start_stack_timers();
- tracer_enabled = 1;
- mutex_unlock(&sample_timer_lock);
-}
-
static void stop_stack_trace(struct trace_array *tr)
{
mutex_lock(&sample_timer_lock);
@@ -247,12 +238,18 @@ static int stack_trace_init(struct trace_array *tr)
{
sysprof_trace = tr;
- start_stack_trace(tr);
+ tracing_start_cmdline_record();
+
+ mutex_lock(&sample_timer_lock);
+ start_stack_timers();
+ tracer_enabled = 1;
+ mutex_unlock(&sample_timer_lock);
return 0;
}
static void stack_trace_reset(struct trace_array *tr)
{
+ tracing_stop_cmdline_record();
stop_stack_trace(tr);
}
@@ -317,7 +314,7 @@ sysprof_sample_write(struct file *filp, const char __user *ubuf,
return cnt;
}
-static struct file_operations sysprof_sample_fops = {
+static const struct file_operations sysprof_sample_fops = {
.read = sysprof_sample_read,
.write = sysprof_sample_write,
};
@@ -330,5 +327,5 @@ void init_tracer_sysprof_debugfs(struct dentry *d_tracer)
d_tracer, NULL, &sysprof_sample_fops);
if (entry)
return;
- pr_warning("Could not create debugfs 'dyn_ftrace_total_info' entry\n");
+ pr_warning("Could not create debugfs 'sysprof_sample_period' entry\n");
}
diff --git a/kernel/trace/trace_workqueue.c b/kernel/trace/trace_workqueue.c
new file mode 100644
index 00000000000..797201e4a13
--- /dev/null
+++ b/kernel/trace/trace_workqueue.c
@@ -0,0 +1,288 @@
+/*
+ * Workqueue statistical tracer.
+ *
+ * Copyright (C) 2008 Frederic Weisbecker <fweisbec@gmail.com>
+ *
+ */
+
+
+#include <trace/workqueue.h>
+#include <linux/list.h>
+#include <linux/percpu.h>
+#include "trace_stat.h"
+#include "trace.h"
+
+
+/* A cpu workqueue thread */
+struct cpu_workqueue_stats {
+ struct list_head list;
+/* Useful to know if we print the cpu headers */
+ bool first_entry;
+ int cpu;
+ pid_t pid;
+/* Can be inserted from interrupt or user context, need to be atomic */
+ atomic_t inserted;
+/*
+ * Don't need to be atomic, works are serialized in a single workqueue thread
+ * on a single CPU.
+ */
+ unsigned int executed;
+};
+
+/* List of workqueue threads on one cpu */
+struct workqueue_global_stats {
+ struct list_head list;
+ spinlock_t lock;
+};
+
+/* Don't need a global lock because allocated before the workqueues, and
+ * never freed.
+ */
+static DEFINE_PER_CPU(struct workqueue_global_stats, all_workqueue_stat);
+#define workqueue_cpu_stat(cpu) (&per_cpu(all_workqueue_stat, cpu))
+
+/* Insertion of a work */
+static void
+probe_workqueue_insertion(struct task_struct *wq_thread,
+ struct work_struct *work)
+{
+ int cpu = cpumask_first(&wq_thread->cpus_allowed);
+ struct cpu_workqueue_stats *node, *next;
+ unsigned long flags;
+
+ spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+ list_for_each_entry_safe(node, next, &workqueue_cpu_stat(cpu)->list,
+ list) {
+ if (node->pid == wq_thread->pid) {
+ atomic_inc(&node->inserted);
+ goto found;
+ }
+ }
+ pr_debug("trace_workqueue: entry not found\n");
+found:
+ spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+}
+
+/* Execution of a work */
+static void
+probe_workqueue_execution(struct task_struct *wq_thread,
+ struct work_struct *work)
+{
+ int cpu = cpumask_first(&wq_thread->cpus_allowed);
+ struct cpu_workqueue_stats *node, *next;
+ unsigned long flags;
+
+ spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+ list_for_each_entry_safe(node, next, &workqueue_cpu_stat(cpu)->list,
+ list) {
+ if (node->pid == wq_thread->pid) {
+ node->executed++;
+ goto found;
+ }
+ }
+ pr_debug("trace_workqueue: entry not found\n");
+found:
+ spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+}
+
+/* Creation of a cpu workqueue thread */
+static void probe_workqueue_creation(struct task_struct *wq_thread, int cpu)
+{
+ struct cpu_workqueue_stats *cws;
+ unsigned long flags;
+
+ WARN_ON(cpu < 0);
+
+ /* Workqueues are sometimes created in atomic context */
+ cws = kzalloc(sizeof(struct cpu_workqueue_stats), GFP_ATOMIC);
+ if (!cws) {
+ pr_warning("trace_workqueue: not enough memory\n");
+ return;
+ }
+ INIT_LIST_HEAD(&cws->list);
+ cws->cpu = cpu;
+
+ cws->pid = wq_thread->pid;
+
+ spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+ if (list_empty(&workqueue_cpu_stat(cpu)->list))
+ cws->first_entry = true;
+ list_add_tail(&cws->list, &workqueue_cpu_stat(cpu)->list);
+ spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+}
+
+/* Destruction of a cpu workqueue thread */
+static void probe_workqueue_destruction(struct task_struct *wq_thread)
+{
+ /* Workqueue only execute on one cpu */
+ int cpu = cpumask_first(&wq_thread->cpus_allowed);
+ struct cpu_workqueue_stats *node, *next;
+ unsigned long flags;
+
+ spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+ list_for_each_entry_safe(node, next, &workqueue_cpu_stat(cpu)->list,
+ list) {
+ if (node->pid == wq_thread->pid) {
+ list_del(&node->list);
+ kfree(node);
+ goto found;
+ }
+ }
+
+ pr_debug("trace_workqueue: don't find workqueue to destroy\n");
+found:
+ spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+
+}
+
+static struct cpu_workqueue_stats *workqueue_stat_start_cpu(int cpu)
+{
+ unsigned long flags;
+ struct cpu_workqueue_stats *ret = NULL;
+
+
+ spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+
+ if (!list_empty(&workqueue_cpu_stat(cpu)->list))
+ ret = list_entry(workqueue_cpu_stat(cpu)->list.next,
+ struct cpu_workqueue_stats, list);
+
+ spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+
+ return ret;
+}
+
+static void *workqueue_stat_start(void)
+{
+ int cpu;
+ void *ret = NULL;
+
+ for_each_possible_cpu(cpu) {
+ ret = workqueue_stat_start_cpu(cpu);
+ if (ret)
+ return ret;
+ }
+ return NULL;
+}
+
+static void *workqueue_stat_next(void *prev, int idx)
+{
+ struct cpu_workqueue_stats *prev_cws = prev;
+ int cpu = prev_cws->cpu;
+ unsigned long flags;
+ void *ret = NULL;
+
+ spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+ if (list_is_last(&prev_cws->list, &workqueue_cpu_stat(cpu)->list)) {
+ spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+ do {
+ cpu = cpumask_next(cpu, cpu_possible_mask);
+ if (cpu >= nr_cpu_ids)
+ return NULL;
+ } while (!(ret = workqueue_stat_start_cpu(cpu)));
+ return ret;
+ }
+ spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+
+ return list_entry(prev_cws->list.next, struct cpu_workqueue_stats,
+ list);
+}
+
+static int workqueue_stat_show(struct seq_file *s, void *p)
+{
+ struct cpu_workqueue_stats *cws = p;
+ unsigned long flags;
+ int cpu = cws->cpu;
+ struct pid *pid;
+ struct task_struct *tsk;
+
+ spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+ if (&cws->list == workqueue_cpu_stat(cpu)->list.next)
+ seq_printf(s, "\n");
+ spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+
+ pid = find_get_pid(cws->pid);
+ if (pid) {
+ tsk = get_pid_task(pid, PIDTYPE_PID);
+ if (tsk) {
+ seq_printf(s, "%3d %6d %6u %s\n", cws->cpu,
+ atomic_read(&cws->inserted), cws->executed,
+ tsk->comm);
+ put_task_struct(tsk);
+ }
+ put_pid(pid);
+ }
+
+ return 0;
+}
+
+static int workqueue_stat_headers(struct seq_file *s)
+{
+ seq_printf(s, "# CPU INSERTED EXECUTED NAME\n");
+ seq_printf(s, "# | | | |\n");
+ return 0;
+}
+
+struct tracer_stat workqueue_stats __read_mostly = {
+ .name = "workqueues",
+ .stat_start = workqueue_stat_start,
+ .stat_next = workqueue_stat_next,
+ .stat_show = workqueue_stat_show,
+ .stat_headers = workqueue_stat_headers
+};
+
+
+int __init stat_workqueue_init(void)
+{
+ if (register_stat_tracer(&workqueue_stats)) {
+ pr_warning("Unable to register workqueue stat tracer\n");
+ return 1;
+ }
+
+ return 0;
+}
+fs_initcall(stat_workqueue_init);
+
+/*
+ * Workqueues are created very early, just after pre-smp initcalls.
+ * So we must register our tracepoints at this stage.
+ */
+int __init trace_workqueue_early_init(void)
+{
+ int ret, cpu;
+
+ ret = register_trace_workqueue_insertion(probe_workqueue_insertion);
+ if (ret)
+ goto out;
+
+ ret = register_trace_workqueue_execution(probe_workqueue_execution);
+ if (ret)
+ goto no_insertion;
+
+ ret = register_trace_workqueue_creation(probe_workqueue_creation);
+ if (ret)
+ goto no_execution;
+
+ ret = register_trace_workqueue_destruction(probe_workqueue_destruction);
+ if (ret)
+ goto no_creation;
+
+ for_each_possible_cpu(cpu) {
+ spin_lock_init(&workqueue_cpu_stat(cpu)->lock);
+ INIT_LIST_HEAD(&workqueue_cpu_stat(cpu)->list);
+ }
+
+ return 0;
+
+no_creation:
+ unregister_trace_workqueue_creation(probe_workqueue_creation);
+no_execution:
+ unregister_trace_workqueue_execution(probe_workqueue_execution);
+no_insertion:
+ unregister_trace_workqueue_insertion(probe_workqueue_insertion);
+out:
+ pr_warning("trace_workqueue: unable to trace workqueues\n");
+
+ return 1;
+}
+early_initcall(trace_workqueue_early_init);
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index 79602740bbb..1ef5d3a601c 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -272,12 +272,15 @@ static void disable_tracepoint(struct tracepoint *elem)
*
* Updates the probe callback corresponding to a range of tracepoints.
*/
-void tracepoint_update_probe_range(struct tracepoint *begin,
- struct tracepoint *end)
+void
+tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end)
{
struct tracepoint *iter;
struct tracepoint_entry *mark_entry;
+ if (!begin)
+ return;
+
mutex_lock(&tracepoints_mutex);
for (iter = begin; iter < end; iter++) {
mark_entry = get_tracepoint(iter->name);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 32f8e0d2bf5..f71fb2a0895 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -33,6 +33,7 @@
#include <linux/kallsyms.h>
#include <linux/debug_locks.h>
#include <linux/lockdep.h>
+#include <trace/workqueue.h>
/*
* The per-CPU workqueue (if single thread, we always use the first
@@ -123,9 +124,13 @@ struct cpu_workqueue_struct *get_wq_data(struct work_struct *work)
return (void *) (atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK);
}
+DEFINE_TRACE(workqueue_insertion);
+
static void insert_work(struct cpu_workqueue_struct *cwq,
struct work_struct *work, struct list_head *head)
{
+ trace_workqueue_insertion(cwq->thread, work);
+
set_wq_data(work, cwq);
/*
* Ensure that we get the right work->data if we see the
@@ -257,6 +262,8 @@ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
}
EXPORT_SYMBOL_GPL(queue_delayed_work_on);
+DEFINE_TRACE(workqueue_execution);
+
static void run_workqueue(struct cpu_workqueue_struct *cwq)
{
spin_lock_irq(&cwq->lock);
@@ -275,7 +282,7 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq)
*/
struct lockdep_map lockdep_map = work->lockdep_map;
#endif
-
+ trace_workqueue_execution(cwq->thread, work);
cwq->current_work = work;
list_del_init(cwq->worklist.next);
spin_unlock_irq(&cwq->lock);
@@ -746,6 +753,8 @@ init_cpu_workqueue(struct workqueue_struct *wq, int cpu)
return cwq;
}
+DEFINE_TRACE(workqueue_creation);
+
static int create_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
{
struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
@@ -768,6 +777,8 @@ static int create_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
sched_setscheduler_nocheck(p, SCHED_FIFO, &param);
cwq->thread = p;
+ trace_workqueue_creation(cwq->thread, cpu);
+
return 0;
}
@@ -849,6 +860,8 @@ struct workqueue_struct *__create_workqueue_key(const char *name,
}
EXPORT_SYMBOL_GPL(__create_workqueue_key);
+DEFINE_TRACE(workqueue_destruction);
+
static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq)
{
/*
@@ -872,6 +885,7 @@ static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq)
* checks list_empty(), and a "normal" queue_work() can't use
* a dead CPU.
*/
+ trace_workqueue_destruction(cwq->thread);
kthread_stop(cwq->thread);
cwq->thread = NULL;
}
@@ -952,20 +966,20 @@ undo:
}
#ifdef CONFIG_SMP
-static struct workqueue_struct *work_on_cpu_wq __read_mostly;
struct work_for_cpu {
- struct work_struct work;
+ struct completion completion;
long (*fn)(void *);
void *arg;
long ret;
};
-static void do_work_for_cpu(struct work_struct *w)
+static int do_work_for_cpu(void *_wfc)
{
- struct work_for_cpu *wfc = container_of(w, struct work_for_cpu, work);
-
+ struct work_for_cpu *wfc = _wfc;
wfc->ret = wfc->fn(wfc->arg);
+ complete(&wfc->completion);
+ return 0;
}
/**
@@ -976,17 +990,23 @@ static void do_work_for_cpu(struct work_struct *w)
*
* This will return the value @fn returns.
* It is up to the caller to ensure that the cpu doesn't go offline.
+ * The caller must not hold any locks which would prevent @fn from completing.
*/
long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg)
{
- struct work_for_cpu wfc;
-
- INIT_WORK(&wfc.work, do_work_for_cpu);
- wfc.fn = fn;
- wfc.arg = arg;
- queue_work_on(cpu, work_on_cpu_wq, &wfc.work);
- flush_work(&wfc.work);
-
+ struct task_struct *sub_thread;
+ struct work_for_cpu wfc = {
+ .completion = COMPLETION_INITIALIZER_ONSTACK(wfc.completion),
+ .fn = fn,
+ .arg = arg,
+ };
+
+ sub_thread = kthread_create(do_work_for_cpu, &wfc, "work_for_cpu");
+ if (IS_ERR(sub_thread))
+ return PTR_ERR(sub_thread);
+ kthread_bind(sub_thread, cpu);
+ wake_up_process(sub_thread);
+ wait_for_completion(&wfc.completion);
return wfc.ret;
}
EXPORT_SYMBOL_GPL(work_on_cpu);
@@ -1002,8 +1022,4 @@ void __init init_workqueues(void)
hotcpu_notifier(workqueue_cpu_callback, 0);
keventd_wq = create_workqueue("events");
BUG_ON(!keventd_wq);
-#ifdef CONFIG_SMP
- work_on_cpu_wq = create_workqueue("work_on_cpu");
- BUG_ON(!work_on_cpu_wq);
-#endif
}
diff --git a/lib/Kconfig b/lib/Kconfig
index 2a9c69f3448..8ade0a7a91e 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -2,6 +2,9 @@
# Library configuration
#
+config BINARY_PRINTF
+ def_bool n
+
menu "Library routines"
config BITREVERSE
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 9638d99644a..c6e854f215f 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -186,6 +186,44 @@ config BOOTPARAM_SOFTLOCKUP_PANIC_VALUE
default 0 if !BOOTPARAM_SOFTLOCKUP_PANIC
default 1 if BOOTPARAM_SOFTLOCKUP_PANIC
+config DETECT_HUNG_TASK
+ bool "Detect Hung Tasks"
+ depends on DEBUG_KERNEL
+ default DETECT_SOFTLOCKUP
+ help
+ Say Y here to enable the kernel to detect "hung tasks",
+ which are bugs that cause the task to be stuck in
+ uninterruptible "D" state indefinitiley.
+
+ When a hung task is detected, the kernel will print the
+ current stack trace (which you should report), but the
+ task will stay in uninterruptible state. If lockdep is
+ enabled then all held locks will also be reported. This
+ feature has negligible overhead.
+
+config BOOTPARAM_HUNG_TASK_PANIC
+ bool "Panic (Reboot) On Hung Tasks"
+ depends on DETECT_HUNG_TASK
+ help
+ Say Y here to enable the kernel to panic on "hung tasks",
+ which are bugs that cause the kernel to leave a task stuck
+ in uninterruptible "D" state.
+
+ The panic can be used in combination with panic_timeout,
+ to cause the system to reboot automatically after a
+ hung task has been detected. This feature is useful for
+ high-availability systems that have uptime guarantees and
+ where a hung tasks must be resolved ASAP.
+
+ Say N if unsure.
+
+config BOOTPARAM_HUNG_TASK_PANIC_VALUE
+ int
+ depends on DETECT_HUNG_TASK
+ range 0 1
+ default 0 if !BOOTPARAM_HUNG_TASK_PANIC
+ default 1 if BOOTPARAM_HUNG_TASK_PANIC
+
config SCHED_DEBUG
bool "Collect scheduler debugging info"
depends on DEBUG_KERNEL && PROC_FS
diff --git a/lib/debug_locks.c b/lib/debug_locks.c
index 0218b4693dd..bc3b11731b9 100644
--- a/lib/debug_locks.c
+++ b/lib/debug_locks.c
@@ -36,7 +36,7 @@ int debug_locks_silent;
*/
int debug_locks_off(void)
{
- if (xchg(&debug_locks, 0)) {
+ if (__debug_locks_off()) {
if (!debug_locks_silent) {
oops_in_progress = 1;
console_verbose();
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 5d99be1fd98..2755a3bd16a 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -30,7 +30,7 @@ struct debug_bucket {
static struct debug_bucket obj_hash[ODEBUG_HASH_SIZE];
-static struct debug_obj obj_static_pool[ODEBUG_POOL_SIZE];
+static struct debug_obj obj_static_pool[ODEBUG_POOL_SIZE] __initdata;
static DEFINE_SPINLOCK(pool_lock);
@@ -50,12 +50,23 @@ static int debug_objects_enabled __read_mostly
static struct debug_obj_descr *descr_test __read_mostly;
+static void free_obj_work(struct work_struct *work);
+static DECLARE_WORK(debug_obj_work, free_obj_work);
+
static int __init enable_object_debug(char *str)
{
debug_objects_enabled = 1;
return 0;
}
+
+static int __init disable_object_debug(char *str)
+{
+ debug_objects_enabled = 0;
+ return 0;
+}
+
early_param("debug_objects", enable_object_debug);
+early_param("no_debug_objects", disable_object_debug);
static const char *obj_states[ODEBUG_STATE_MAX] = {
[ODEBUG_STATE_NONE] = "none",
@@ -146,25 +157,51 @@ alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr)
}
/*
- * Put the object back into the pool or give it back to kmem_cache:
+ * workqueue function to free objects.
*/
-static void free_object(struct debug_obj *obj)
+static void free_obj_work(struct work_struct *work)
{
- unsigned long idx = (unsigned long)(obj - obj_static_pool);
+ struct debug_obj *obj;
unsigned long flags;
- if (obj_pool_free < ODEBUG_POOL_SIZE || idx < ODEBUG_POOL_SIZE) {
- spin_lock_irqsave(&pool_lock, flags);
- hlist_add_head(&obj->node, &obj_pool);
- obj_pool_free++;
- obj_pool_used--;
- spin_unlock_irqrestore(&pool_lock, flags);
- } else {
- spin_lock_irqsave(&pool_lock, flags);
- obj_pool_used--;
+ spin_lock_irqsave(&pool_lock, flags);
+ while (obj_pool_free > ODEBUG_POOL_SIZE) {
+ obj = hlist_entry(obj_pool.first, typeof(*obj), node);
+ hlist_del(&obj->node);
+ obj_pool_free--;
+ /*
+ * We release pool_lock across kmem_cache_free() to
+ * avoid contention on pool_lock.
+ */
spin_unlock_irqrestore(&pool_lock, flags);
kmem_cache_free(obj_cache, obj);
+ spin_lock_irqsave(&pool_lock, flags);
}
+ spin_unlock_irqrestore(&pool_lock, flags);
+}
+
+/*
+ * Put the object back into the pool and schedule work to free objects
+ * if necessary.
+ */
+static void free_object(struct debug_obj *obj)
+{
+ unsigned long flags;
+ int sched = 0;
+
+ spin_lock_irqsave(&pool_lock, flags);
+ /*
+ * schedule work when the pool is filled and the cache is
+ * initialized:
+ */
+ if (obj_pool_free > ODEBUG_POOL_SIZE && obj_cache)
+ sched = !work_pending(&debug_obj_work);
+ hlist_add_head(&obj->node, &obj_pool);
+ obj_pool_free++;
+ obj_pool_used--;
+ spin_unlock_irqrestore(&pool_lock, flags);
+ if (sched)
+ schedule_work(&debug_obj_work);
}
/*
@@ -876,6 +913,63 @@ void __init debug_objects_early_init(void)
}
/*
+ * Convert the statically allocated objects to dynamic ones:
+ */
+static int debug_objects_replace_static_objects(void)
+{
+ struct debug_bucket *db = obj_hash;
+ struct hlist_node *node, *tmp;
+ struct debug_obj *obj, *new;
+ HLIST_HEAD(objects);
+ int i, cnt = 0;
+
+ for (i = 0; i < ODEBUG_POOL_SIZE; i++) {
+ obj = kmem_cache_zalloc(obj_cache, GFP_KERNEL);
+ if (!obj)
+ goto free;
+ hlist_add_head(&obj->node, &objects);
+ }
+
+ /*
+ * When debug_objects_mem_init() is called we know that only
+ * one CPU is up, so disabling interrupts is enough
+ * protection. This avoids the lockdep hell of lock ordering.
+ */
+ local_irq_disable();
+
+ /* Remove the statically allocated objects from the pool */
+ hlist_for_each_entry_safe(obj, node, tmp, &obj_pool, node)
+ hlist_del(&obj->node);
+ /* Move the allocated objects to the pool */
+ hlist_move_list(&objects, &obj_pool);
+
+ /* Replace the active object references */
+ for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) {
+ hlist_move_list(&db->list, &objects);
+
+ hlist_for_each_entry(obj, node, &objects, node) {
+ new = hlist_entry(obj_pool.first, typeof(*obj), node);
+ hlist_del(&new->node);
+ /* copy object data */
+ *new = *obj;
+ hlist_add_head(&new->node, &db->list);
+ cnt++;
+ }
+ }
+
+ printk(KERN_DEBUG "ODEBUG: %d of %d active objects replaced\n", cnt,
+ obj_pool_used);
+ local_irq_enable();
+ return 0;
+free:
+ hlist_for_each_entry_safe(obj, node, tmp, &objects, node) {
+ hlist_del(&obj->node);
+ kmem_cache_free(obj_cache, obj);
+ }
+ return -ENOMEM;
+}
+
+/*
* Called after the kmem_caches are functional to setup a dedicated
* cache pool, which has the SLAB_DEBUG_OBJECTS flag set. This flag
* prevents that the debug code is called on kmem_cache_free() for the
@@ -890,8 +984,11 @@ void __init debug_objects_mem_init(void)
sizeof (struct debug_obj), 0,
SLAB_DEBUG_OBJECTS, NULL);
- if (!obj_cache)
+ if (!obj_cache || debug_objects_replace_static_objects()) {
debug_objects_enabled = 0;
- else
+ if (obj_cache)
+ kmem_cache_destroy(obj_cache);
+ printk(KERN_WARNING "ODEBUG: out of memory.\n");
+ } else
debug_objects_selftest();
}
diff --git a/lib/decompress_bunzip2.c b/lib/decompress_bunzip2.c
index 5d3ddb5fcfd..708e2a86d87 100644
--- a/lib/decompress_bunzip2.c
+++ b/lib/decompress_bunzip2.c
@@ -50,6 +50,7 @@
#endif /* !STATIC */
#include <linux/decompress/mm.h>
+#include <linux/slab.h>
#ifndef INT_MAX
#define INT_MAX 0x7fffffff
diff --git a/lib/decompress_inflate.c b/lib/decompress_inflate.c
index 839a329b4fc..e36b296fc9f 100644
--- a/lib/decompress_inflate.c
+++ b/lib/decompress_inflate.c
@@ -23,6 +23,7 @@
#endif /* STATIC */
#include <linux/decompress/mm.h>
+#include <linux/slab.h>
#define INBUF_LEN (16*1024)
diff --git a/lib/decompress_unlzma.c b/lib/decompress_unlzma.c
index 546f2f4c157..32123a1340e 100644
--- a/lib/decompress_unlzma.c
+++ b/lib/decompress_unlzma.c
@@ -34,6 +34,7 @@
#endif /* STATIC */
#include <linux/decompress/mm.h>
+#include <linux/slab.h>
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index 280332c1827..619313ed6c4 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -157,11 +157,11 @@ static void init_shared_classes(void)
#define SOFTIRQ_ENTER() \
local_bh_disable(); \
local_irq_disable(); \
- trace_softirq_enter(); \
+ lockdep_softirq_enter(); \
WARN_ON(!in_softirq());
#define SOFTIRQ_EXIT() \
- trace_softirq_exit(); \
+ lockdep_softirq_exit(); \
local_irq_enable(); \
local_bh_enable();
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 32e2bd3b114..2b0b5a7d2ce 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -549,7 +549,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
dma_addr_t dev_addr;
void *ret;
int order = get_order(size);
- u64 dma_mask = DMA_32BIT_MASK;
+ u64 dma_mask = DMA_BIT_MASK(32);
if (hwdev && hwdev->coherent_dma_mask)
dma_mask = hwdev->coherent_dma_mask;
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 0fbd0121d91..7536acea135 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -396,7 +396,38 @@ static noinline char* put_dec(char *buf, unsigned long long num)
#define SMALL 32 /* Must be 32 == 0x20 */
#define SPECIAL 64 /* 0x */
-static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type)
+enum format_type {
+ FORMAT_TYPE_NONE, /* Just a string part */
+ FORMAT_TYPE_WIDTH,
+ FORMAT_TYPE_PRECISION,
+ FORMAT_TYPE_CHAR,
+ FORMAT_TYPE_STR,
+ FORMAT_TYPE_PTR,
+ FORMAT_TYPE_PERCENT_CHAR,
+ FORMAT_TYPE_INVALID,
+ FORMAT_TYPE_LONG_LONG,
+ FORMAT_TYPE_ULONG,
+ FORMAT_TYPE_LONG,
+ FORMAT_TYPE_USHORT,
+ FORMAT_TYPE_SHORT,
+ FORMAT_TYPE_UINT,
+ FORMAT_TYPE_INT,
+ FORMAT_TYPE_NRCHARS,
+ FORMAT_TYPE_SIZE_T,
+ FORMAT_TYPE_PTRDIFF
+};
+
+struct printf_spec {
+ enum format_type type;
+ int flags; /* flags to number() */
+ int field_width; /* width of output field */
+ int base;
+ int precision; /* # of digits/chars */
+ int qualifier;
+};
+
+static char *number(char *buf, char *end, unsigned long long num,
+ struct printf_spec spec)
{
/* we are called with base 8, 10 or 16, only, thus don't need "G..." */
static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
@@ -404,32 +435,32 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int
char tmp[66];
char sign;
char locase;
- int need_pfx = ((type & SPECIAL) && base != 10);
+ int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10);
int i;
/* locase = 0 or 0x20. ORing digits or letters with 'locase'
* produces same digits or (maybe lowercased) letters */
- locase = (type & SMALL);
- if (type & LEFT)
- type &= ~ZEROPAD;
+ locase = (spec.flags & SMALL);
+ if (spec.flags & LEFT)
+ spec.flags &= ~ZEROPAD;
sign = 0;
- if (type & SIGN) {
+ if (spec.flags & SIGN) {
if ((signed long long) num < 0) {
sign = '-';
num = - (signed long long) num;
- size--;
- } else if (type & PLUS) {
+ spec.field_width--;
+ } else if (spec.flags & PLUS) {
sign = '+';
- size--;
- } else if (type & SPACE) {
+ spec.field_width--;
+ } else if (spec.flags & SPACE) {
sign = ' ';
- size--;
+ spec.field_width--;
}
}
if (need_pfx) {
- size--;
- if (base == 16)
- size--;
+ spec.field_width--;
+ if (spec.base == 16)
+ spec.field_width--;
}
/* generate full string in tmp[], in reverse order */
@@ -441,10 +472,10 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int
tmp[i++] = (digits[do_div(num,base)] | locase);
} while (num != 0);
*/
- else if (base != 10) { /* 8 or 16 */
- int mask = base - 1;
+ else if (spec.base != 10) { /* 8 or 16 */
+ int mask = spec.base - 1;
int shift = 3;
- if (base == 16) shift = 4;
+ if (spec.base == 16) shift = 4;
do {
tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
num >>= shift;
@@ -454,12 +485,12 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int
}
/* printing 100 using %2d gives "100", not "00" */
- if (i > precision)
- precision = i;
+ if (i > spec.precision)
+ spec.precision = i;
/* leading space padding */
- size -= precision;
- if (!(type & (ZEROPAD+LEFT))) {
- while(--size >= 0) {
+ spec.field_width -= spec.precision;
+ if (!(spec.flags & (ZEROPAD+LEFT))) {
+ while(--spec.field_width >= 0) {
if (buf < end)
*buf = ' ';
++buf;
@@ -476,23 +507,23 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int
if (buf < end)
*buf = '0';
++buf;
- if (base == 16) {
+ if (spec.base == 16) {
if (buf < end)
*buf = ('X' | locase);
++buf;
}
}
/* zero or space padding */
- if (!(type & LEFT)) {
- char c = (type & ZEROPAD) ? '0' : ' ';
- while (--size >= 0) {
+ if (!(spec.flags & LEFT)) {
+ char c = (spec.flags & ZEROPAD) ? '0' : ' ';
+ while (--spec.field_width >= 0) {
if (buf < end)
*buf = c;
++buf;
}
}
/* hmm even more zero padding? */
- while (i <= --precision) {
+ while (i <= --spec.precision) {
if (buf < end)
*buf = '0';
++buf;
@@ -504,7 +535,7 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int
++buf;
}
/* trailing space padding */
- while (--size >= 0) {
+ while (--spec.field_width >= 0) {
if (buf < end)
*buf = ' ';
++buf;
@@ -512,17 +543,17 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int
return buf;
}
-static char *string(char *buf, char *end, char *s, int field_width, int precision, int flags)
+static char *string(char *buf, char *end, char *s, struct printf_spec spec)
{
int len, i;
if ((unsigned long)s < PAGE_SIZE)
s = "<NULL>";
- len = strnlen(s, precision);
+ len = strnlen(s, spec.precision);
- if (!(flags & LEFT)) {
- while (len < field_width--) {
+ if (!(spec.flags & LEFT)) {
+ while (len < spec.field_width--) {
if (buf < end)
*buf = ' ';
++buf;
@@ -533,7 +564,7 @@ static char *string(char *buf, char *end, char *s, int field_width, int precisio
*buf = *s;
++buf; ++s;
}
- while (len < field_width--) {
+ while (len < spec.field_width--) {
if (buf < end)
*buf = ' ';
++buf;
@@ -541,21 +572,24 @@ static char *string(char *buf, char *end, char *s, int field_width, int precisio
return buf;
}
-static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int precision, int flags)
+static char *symbol_string(char *buf, char *end, void *ptr,
+ struct printf_spec spec)
{
unsigned long value = (unsigned long) ptr;
#ifdef CONFIG_KALLSYMS
char sym[KSYM_SYMBOL_LEN];
sprint_symbol(sym, value);
- return string(buf, end, sym, field_width, precision, flags);
+ return string(buf, end, sym, spec);
#else
- field_width = 2*sizeof(void *);
- flags |= SPECIAL | SMALL | ZEROPAD;
- return number(buf, end, value, 16, field_width, precision, flags);
+ spec.field_width = 2*sizeof(void *);
+ spec.flags |= SPECIAL | SMALL | ZEROPAD;
+ spec.base = 16;
+ return number(buf, end, value, spec);
#endif
}
-static char *resource_string(char *buf, char *end, struct resource *res, int field_width, int precision, int flags)
+static char *resource_string(char *buf, char *end, struct resource *res,
+ struct printf_spec spec)
{
#ifndef IO_RSRC_PRINTK_SIZE
#define IO_RSRC_PRINTK_SIZE 4
@@ -564,7 +598,11 @@ static char *resource_string(char *buf, char *end, struct resource *res, int fie
#ifndef MEM_RSRC_PRINTK_SIZE
#define MEM_RSRC_PRINTK_SIZE 8
#endif
-
+ struct printf_spec num_spec = {
+ .base = 16,
+ .precision = -1,
+ .flags = SPECIAL | SMALL | ZEROPAD,
+ };
/* 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);
@@ -576,17 +614,18 @@ static char *resource_string(char *buf, char *end, struct resource *res, int fie
size = MEM_RSRC_PRINTK_SIZE;
*p++ = '[';
- p = number(p, pend, res->start, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
+ num_spec.field_width = size;
+ p = number(p, pend, res->start, num_spec);
*p++ = '-';
- p = number(p, pend, res->end, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
+ p = number(p, pend, res->end, num_spec);
*p++ = ']';
*p = 0;
- return string(buf, end, sym, field_width, precision, flags);
+ return string(buf, end, sym, spec);
}
-static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width,
- int precision, int flags)
+static char *mac_address_string(char *buf, char *end, u8 *addr,
+ struct printf_spec spec)
{
char mac_addr[6 * 3]; /* (6 * 2 hex digits), 5 colons and trailing zero */
char *p = mac_addr;
@@ -594,16 +633,17 @@ static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width,
for (i = 0; i < 6; i++) {
p = pack_hex_byte(p, addr[i]);
- if (!(flags & SPECIAL) && i != 5)
+ if (!(spec.flags & SPECIAL) && i != 5)
*p++ = ':';
}
*p = '\0';
+ spec.flags &= ~SPECIAL;
- return string(buf, end, mac_addr, field_width, precision, flags & ~SPECIAL);
+ return string(buf, end, mac_addr, spec);
}
-static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width,
- int precision, int flags)
+static char *ip6_addr_string(char *buf, char *end, u8 *addr,
+ struct printf_spec spec)
{
char ip6_addr[8 * 5]; /* (8 * 4 hex digits), 7 colons and trailing zero */
char *p = ip6_addr;
@@ -612,16 +652,17 @@ static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width,
for (i = 0; i < 8; i++) {
p = pack_hex_byte(p, addr[2 * i]);
p = pack_hex_byte(p, addr[2 * i + 1]);
- if (!(flags & SPECIAL) && i != 7)
+ if (!(spec.flags & SPECIAL) && i != 7)
*p++ = ':';
}
*p = '\0';
+ spec.flags &= ~SPECIAL;
- return string(buf, end, ip6_addr, field_width, precision, flags & ~SPECIAL);
+ return string(buf, end, ip6_addr, spec);
}
-static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width,
- int precision, int flags)
+static char *ip4_addr_string(char *buf, char *end, u8 *addr,
+ struct printf_spec spec)
{
char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */
char temp[3]; /* hold each IP quad in reverse order */
@@ -637,8 +678,9 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width,
*p++ = '.';
}
*p = '\0';
+ spec.flags &= ~SPECIAL;
- return string(buf, end, ip4_addr, field_width, precision, flags & ~SPECIAL);
+ return string(buf, end, ip4_addr, spec);
}
/*
@@ -663,41 +705,233 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width,
* 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)
+static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
+ struct printf_spec spec)
{
if (!ptr)
- return string(buf, end, "(null)", field_width, precision, flags);
+ return string(buf, end, "(null)", spec);
switch (*fmt) {
case 'F':
ptr = dereference_function_descriptor(ptr);
/* Fallthrough */
case 'S':
- return symbol_string(buf, end, ptr, field_width, precision, flags);
+ return symbol_string(buf, end, ptr, spec);
case 'R':
- return resource_string(buf, end, ptr, field_width, precision, flags);
+ return resource_string(buf, end, ptr, spec);
case 'm':
- flags |= SPECIAL;
+ spec.flags |= SPECIAL;
/* Fallthrough */
case 'M':
- return mac_address_string(buf, end, ptr, field_width, precision, flags);
+ return mac_address_string(buf, end, ptr, spec);
case 'i':
- flags |= SPECIAL;
+ spec.flags |= SPECIAL;
/* Fallthrough */
case 'I':
if (fmt[1] == '6')
- return ip6_addr_string(buf, end, ptr, field_width, precision, flags);
+ return ip6_addr_string(buf, end, ptr, spec);
if (fmt[1] == '4')
- return ip4_addr_string(buf, end, ptr, field_width, precision, flags);
- flags &= ~SPECIAL;
+ return ip4_addr_string(buf, end, ptr, spec);
+ spec.flags &= ~SPECIAL;
break;
}
- flags |= SMALL;
- if (field_width == -1) {
- field_width = 2*sizeof(void *);
- flags |= ZEROPAD;
+ spec.flags |= SMALL;
+ if (spec.field_width == -1) {
+ spec.field_width = 2*sizeof(void *);
+ spec.flags |= ZEROPAD;
}
- return number(buf, end, (unsigned long) ptr, 16, field_width, precision, flags);
+ spec.base = 16;
+
+ return number(buf, end, (unsigned long) ptr, spec);
+}
+
+/*
+ * Helper function to decode printf style format.
+ * Each call decode a token from the format and return the
+ * number of characters read (or likely the delta where it wants
+ * to go on the next call).
+ * The decoded token is returned through the parameters
+ *
+ * 'h', 'l', or 'L' for integer fields
+ * 'z' support added 23/7/1999 S.H.
+ * 'z' changed to 'Z' --davidm 1/25/99
+ * 't' added for ptrdiff_t
+ *
+ * @fmt: the format string
+ * @type of the token returned
+ * @flags: various flags such as +, -, # tokens..
+ * @field_width: overwritten width
+ * @base: base of the number (octal, hex, ...)
+ * @precision: precision of a number
+ * @qualifier: qualifier of a number (long, size_t, ...)
+ */
+static int format_decode(const char *fmt, struct printf_spec *spec)
+{
+ const char *start = fmt;
+
+ /* we finished early by reading the field width */
+ if (spec->type == FORMAT_TYPE_WIDTH) {
+ if (spec->field_width < 0) {
+ spec->field_width = -spec->field_width;
+ spec->flags |= LEFT;
+ }
+ spec->type = FORMAT_TYPE_NONE;
+ goto precision;
+ }
+
+ /* we finished early by reading the precision */
+ if (spec->type == FORMAT_TYPE_PRECISION) {
+ if (spec->precision < 0)
+ spec->precision = 0;
+
+ spec->type = FORMAT_TYPE_NONE;
+ goto qualifier;
+ }
+
+ /* By default */
+ spec->type = FORMAT_TYPE_NONE;
+
+ for (; *fmt ; ++fmt) {
+ if (*fmt == '%')
+ break;
+ }
+
+ /* Return the current non-format string */
+ if (fmt != start || !*fmt)
+ return fmt - start;
+
+ /* Process flags */
+ spec->flags = 0;
+
+ while (1) { /* this also skips first '%' */
+ bool found = true;
+
+ ++fmt;
+
+ switch (*fmt) {
+ case '-': spec->flags |= LEFT; break;
+ case '+': spec->flags |= PLUS; break;
+ case ' ': spec->flags |= SPACE; break;
+ case '#': spec->flags |= SPECIAL; break;
+ case '0': spec->flags |= ZEROPAD; break;
+ default: found = false;
+ }
+
+ if (!found)
+ break;
+ }
+
+ /* get field width */
+ spec->field_width = -1;
+
+ if (isdigit(*fmt))
+ spec->field_width = skip_atoi(&fmt);
+ else if (*fmt == '*') {
+ /* it's the next argument */
+ spec->type = FORMAT_TYPE_WIDTH;
+ return ++fmt - start;
+ }
+
+precision:
+ /* get the precision */
+ spec->precision = -1;
+ if (*fmt == '.') {
+ ++fmt;
+ if (isdigit(*fmt)) {
+ spec->precision = skip_atoi(&fmt);
+ if (spec->precision < 0)
+ spec->precision = 0;
+ } else if (*fmt == '*') {
+ /* it's the next argument */
+ spec->type = FORMAT_TYPE_PRECISION;
+ return ++fmt - start;
+ }
+ }
+
+qualifier:
+ /* get the conversion qualifier */
+ spec->qualifier = -1;
+ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
+ *fmt == 'Z' || *fmt == 'z' || *fmt == 't') {
+ spec->qualifier = *fmt;
+ ++fmt;
+ if (spec->qualifier == 'l' && *fmt == 'l') {
+ spec->qualifier = 'L';
+ ++fmt;
+ }
+ }
+
+ /* default base */
+ spec->base = 10;
+ switch (*fmt) {
+ case 'c':
+ spec->type = FORMAT_TYPE_CHAR;
+ return ++fmt - start;
+
+ case 's':
+ spec->type = FORMAT_TYPE_STR;
+ return ++fmt - start;
+
+ case 'p':
+ spec->type = FORMAT_TYPE_PTR;
+ return fmt - start;
+ /* skip alnum */
+
+ case 'n':
+ spec->type = FORMAT_TYPE_NRCHARS;
+ return ++fmt - start;
+
+ case '%':
+ spec->type = FORMAT_TYPE_PERCENT_CHAR;
+ return ++fmt - start;
+
+ /* integer number formats - set up the flags and "break" */
+ case 'o':
+ spec->base = 8;
+ break;
+
+ case 'x':
+ spec->flags |= SMALL;
+
+ case 'X':
+ spec->base = 16;
+ break;
+
+ case 'd':
+ case 'i':
+ spec->flags |= SIGN;
+ case 'u':
+ break;
+
+ default:
+ spec->type = FORMAT_TYPE_INVALID;
+ return fmt - start;
+ }
+
+ if (spec->qualifier == 'L')
+ spec->type = FORMAT_TYPE_LONG_LONG;
+ else if (spec->qualifier == 'l') {
+ if (spec->flags & SIGN)
+ spec->type = FORMAT_TYPE_LONG;
+ else
+ spec->type = FORMAT_TYPE_ULONG;
+ } else if (spec->qualifier == 'Z' || spec->qualifier == 'z') {
+ spec->type = FORMAT_TYPE_SIZE_T;
+ } else if (spec->qualifier == 't') {
+ spec->type = FORMAT_TYPE_PTRDIFF;
+ } else if (spec->qualifier == 'h') {
+ if (spec->flags & SIGN)
+ spec->type = FORMAT_TYPE_SHORT;
+ else
+ spec->type = FORMAT_TYPE_USHORT;
+ } else {
+ if (spec->flags & SIGN)
+ spec->type = FORMAT_TYPE_INT;
+ else
+ spec->type = FORMAT_TYPE_UINT;
+ }
+
+ return ++fmt - start;
}
/**
@@ -726,18 +960,9 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
{
unsigned long long num;
- int base;
char *str, *end, c;
-
- int flags; /* flags to number() */
-
- int field_width; /* width of output field */
- int precision; /* min. # of digits for integers; max
- number of chars for from string */
- int qualifier; /* 'h', 'l', or 'L' for integer fields */
- /* 'z' support added 23/7/1999 S.H. */
- /* 'z' changed to 'Z' --davidm 1/25/99 */
- /* 't' added for ptrdiff_t */
+ int read;
+ struct printf_spec spec = {0};
/* Reject out-of-range values early. Large positive sizes are
used for unknown buffer sizes. */
@@ -758,184 +983,137 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
size = end - buf;
}
- for (; *fmt ; ++fmt) {
- if (*fmt != '%') {
- if (str < end)
- *str = *fmt;
- ++str;
- continue;
- }
+ while (*fmt) {
+ const char *old_fmt = fmt;
- /* process flags */
- flags = 0;
- repeat:
- ++fmt; /* this also skips first '%' */
- switch (*fmt) {
- case '-': flags |= LEFT; goto repeat;
- case '+': flags |= PLUS; goto repeat;
- case ' ': flags |= SPACE; goto repeat;
- case '#': flags |= SPECIAL; goto repeat;
- case '0': flags |= ZEROPAD; goto repeat;
- }
+ read = format_decode(fmt, &spec);
- /* get field width */
- field_width = -1;
- if (isdigit(*fmt))
- field_width = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- field_width = va_arg(args, int);
- if (field_width < 0) {
- field_width = -field_width;
- flags |= LEFT;
- }
- }
+ fmt += read;
- /* get the precision */
- precision = -1;
- if (*fmt == '.') {
- ++fmt;
- if (isdigit(*fmt))
- precision = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- precision = va_arg(args, int);
+ switch (spec.type) {
+ case FORMAT_TYPE_NONE: {
+ int copy = read;
+ if (str < end) {
+ if (copy > end - str)
+ copy = end - str;
+ memcpy(str, old_fmt, copy);
}
- if (precision < 0)
- precision = 0;
+ str += read;
+ break;
}
- /* get the conversion qualifier */
- qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
- *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
- qualifier = *fmt;
- ++fmt;
- if (qualifier == 'l' && *fmt == 'l') {
- qualifier = 'L';
- ++fmt;
- }
- }
+ case FORMAT_TYPE_WIDTH:
+ spec.field_width = va_arg(args, int);
+ break;
- /* default base */
- base = 10;
+ case FORMAT_TYPE_PRECISION:
+ spec.precision = va_arg(args, int);
+ break;
- switch (*fmt) {
- case 'c':
- if (!(flags & LEFT)) {
- while (--field_width > 0) {
- if (str < end)
- *str = ' ';
- ++str;
- }
- }
- c = (unsigned char) va_arg(args, int);
- if (str < end)
- *str = c;
- ++str;
- while (--field_width > 0) {
+ case FORMAT_TYPE_CHAR:
+ if (!(spec.flags & LEFT)) {
+ while (--spec.field_width > 0) {
if (str < end)
*str = ' ';
++str;
- }
- continue;
-
- case 's':
- str = string(str, end, va_arg(args, char *), field_width, precision, flags);
- continue;
-
- case 'p':
- str = pointer(fmt+1, str, end,
- va_arg(args, void *),
- field_width, precision, flags);
- /* Skip all alphanumeric pointer suffixes */
- while (isalnum(fmt[1]))
- fmt++;
- continue;
-
- case 'n':
- /* FIXME:
- * What does C99 say about the overflow case here? */
- if (qualifier == 'l') {
- long * ip = va_arg(args, long *);
- *ip = (str - buf);
- } else if (qualifier == 'Z' || qualifier == 'z') {
- size_t * ip = va_arg(args, size_t *);
- *ip = (str - buf);
- } else {
- int * ip = va_arg(args, int *);
- *ip = (str - buf);
- }
- continue;
- case '%':
+ }
+ }
+ c = (unsigned char) va_arg(args, int);
+ if (str < end)
+ *str = c;
+ ++str;
+ while (--spec.field_width > 0) {
if (str < end)
- *str = '%';
+ *str = ' ';
++str;
- continue;
+ }
+ break;
- /* integer number formats - set up the flags and "break" */
- case 'o':
- base = 8;
- break;
+ case FORMAT_TYPE_STR:
+ str = string(str, end, va_arg(args, char *), spec);
+ break;
- case 'x':
- flags |= SMALL;
- case 'X':
- base = 16;
- break;
+ case FORMAT_TYPE_PTR:
+ str = pointer(fmt+1, str, end, va_arg(args, void *),
+ spec);
+ while (isalnum(*fmt))
+ fmt++;
+ break;
- case 'd':
- case 'i':
- flags |= SIGN;
- case 'u':
- break;
+ case FORMAT_TYPE_PERCENT_CHAR:
+ if (str < end)
+ *str = '%';
+ ++str;
+ break;
- default:
- if (str < end)
- *str = '%';
- ++str;
- if (*fmt) {
- if (str < end)
- *str = *fmt;
- ++str;
- } else {
- --fmt;
- }
- continue;
+ case FORMAT_TYPE_INVALID:
+ if (str < end)
+ *str = '%';
+ ++str;
+ break;
+
+ case FORMAT_TYPE_NRCHARS: {
+ int qualifier = spec.qualifier;
+
+ if (qualifier == 'l') {
+ long *ip = va_arg(args, long *);
+ *ip = (str - buf);
+ } else if (qualifier == 'Z' ||
+ qualifier == 'z') {
+ size_t *ip = va_arg(args, size_t *);
+ *ip = (str - buf);
+ } else {
+ int *ip = va_arg(args, int *);
+ *ip = (str - buf);
+ }
+ break;
}
- if (qualifier == 'L')
- num = va_arg(args, long long);
- else if (qualifier == 'l') {
- num = va_arg(args, unsigned long);
- if (flags & SIGN)
- num = (signed long) num;
- } else if (qualifier == 'Z' || qualifier == 'z') {
- num = va_arg(args, size_t);
- } else if (qualifier == 't') {
- num = va_arg(args, ptrdiff_t);
- } else if (qualifier == 'h') {
- num = (unsigned short) va_arg(args, int);
- if (flags & SIGN)
- num = (signed short) num;
- } else {
- num = va_arg(args, unsigned int);
- if (flags & SIGN)
- num = (signed int) num;
+
+ default:
+ switch (spec.type) {
+ case FORMAT_TYPE_LONG_LONG:
+ num = va_arg(args, long long);
+ break;
+ case FORMAT_TYPE_ULONG:
+ num = va_arg(args, unsigned long);
+ break;
+ case FORMAT_TYPE_LONG:
+ num = va_arg(args, long);
+ break;
+ case FORMAT_TYPE_SIZE_T:
+ num = va_arg(args, size_t);
+ break;
+ case FORMAT_TYPE_PTRDIFF:
+ num = va_arg(args, ptrdiff_t);
+ break;
+ case FORMAT_TYPE_USHORT:
+ num = (unsigned short) va_arg(args, int);
+ break;
+ case FORMAT_TYPE_SHORT:
+ num = (short) va_arg(args, int);
+ break;
+ case FORMAT_TYPE_INT:
+ num = (int) va_arg(args, int);
+ break;
+ default:
+ num = va_arg(args, unsigned int);
+ }
+
+ str = number(str, end, num, spec);
}
- str = number(str, end, num, base,
- field_width, precision, flags);
}
+
if (size > 0) {
if (str < end)
*str = '\0';
else
end[-1] = '\0';
}
+
/* the trailing null byte doesn't count towards the total */
return str-buf;
+
}
EXPORT_SYMBOL(vsnprintf);
@@ -1058,6 +1236,363 @@ int sprintf(char * buf, const char *fmt, ...)
}
EXPORT_SYMBOL(sprintf);
+#ifdef CONFIG_BINARY_PRINTF
+/*
+ * bprintf service:
+ * vbin_printf() - VA arguments to binary data
+ * bstr_printf() - Binary data to text string
+ */
+
+/**
+ * vbin_printf - Parse a format string and place args' binary value in a buffer
+ * @bin_buf: The buffer to place args' binary value
+ * @size: The size of the buffer(by words(32bits), not characters)
+ * @fmt: The format string to use
+ * @args: Arguments for the format string
+ *
+ * The format follows C99 vsnprintf, except %n is ignored, and its argument
+ * is skiped.
+ *
+ * The return value is the number of words(32bits) which would be generated for
+ * the given input.
+ *
+ * NOTE:
+ * If the return value is greater than @size, the resulting bin_buf is NOT
+ * valid for bstr_printf().
+ */
+int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
+{
+ struct printf_spec spec = {0};
+ char *str, *end;
+ int read;
+
+ str = (char *)bin_buf;
+ end = (char *)(bin_buf + size);
+
+#define save_arg(type) \
+do { \
+ if (sizeof(type) == 8) { \
+ unsigned long long value; \
+ str = PTR_ALIGN(str, sizeof(u32)); \
+ value = va_arg(args, unsigned long long); \
+ if (str + sizeof(type) <= end) { \
+ *(u32 *)str = *(u32 *)&value; \
+ *(u32 *)(str + 4) = *((u32 *)&value + 1); \
+ } \
+ } else { \
+ unsigned long value; \
+ str = PTR_ALIGN(str, sizeof(type)); \
+ value = va_arg(args, int); \
+ if (str + sizeof(type) <= end) \
+ *(typeof(type) *)str = (type)value; \
+ } \
+ str += sizeof(type); \
+} while (0)
+
+
+ while (*fmt) {
+ read = format_decode(fmt, &spec);
+
+ fmt += read;
+
+ switch (spec.type) {
+ case FORMAT_TYPE_NONE:
+ break;
+
+ case FORMAT_TYPE_WIDTH:
+ case FORMAT_TYPE_PRECISION:
+ save_arg(int);
+ break;
+
+ case FORMAT_TYPE_CHAR:
+ save_arg(char);
+ break;
+
+ case FORMAT_TYPE_STR: {
+ const char *save_str = va_arg(args, char *);
+ size_t len;
+ if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE
+ || (unsigned long)save_str < PAGE_SIZE)
+ save_str = "<NULL>";
+ len = strlen(save_str);
+ if (str + len + 1 < end)
+ memcpy(str, save_str, len + 1);
+ str += len + 1;
+ break;
+ }
+
+ case FORMAT_TYPE_PTR:
+ save_arg(void *);
+ /* skip all alphanumeric pointer suffixes */
+ while (isalnum(*fmt))
+ fmt++;
+ break;
+
+ case FORMAT_TYPE_PERCENT_CHAR:
+ break;
+
+ case FORMAT_TYPE_INVALID:
+ break;
+
+ case FORMAT_TYPE_NRCHARS: {
+ /* skip %n 's argument */
+ int qualifier = spec.qualifier;
+ void *skip_arg;
+ if (qualifier == 'l')
+ skip_arg = va_arg(args, long *);
+ else if (qualifier == 'Z' || qualifier == 'z')
+ skip_arg = va_arg(args, size_t *);
+ else
+ skip_arg = va_arg(args, int *);
+ break;
+ }
+
+ default:
+ switch (spec.type) {
+
+ case FORMAT_TYPE_LONG_LONG:
+ save_arg(long long);
+ break;
+ case FORMAT_TYPE_ULONG:
+ case FORMAT_TYPE_LONG:
+ save_arg(unsigned long);
+ break;
+ case FORMAT_TYPE_SIZE_T:
+ save_arg(size_t);
+ break;
+ case FORMAT_TYPE_PTRDIFF:
+ save_arg(ptrdiff_t);
+ break;
+ case FORMAT_TYPE_USHORT:
+ case FORMAT_TYPE_SHORT:
+ save_arg(short);
+ break;
+ default:
+ save_arg(int);
+ }
+ }
+ }
+ return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf;
+
+#undef save_arg
+}
+EXPORT_SYMBOL_GPL(vbin_printf);
+
+/**
+ * bstr_printf - Format a string from binary arguments and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @size: The size of the buffer, including the trailing null space
+ * @fmt: The format string to use
+ * @bin_buf: Binary arguments for the format string
+ *
+ * This function like C99 vsnprintf, but the difference is that vsnprintf gets
+ * arguments from stack, and bstr_printf gets arguments from @bin_buf which is
+ * a binary buffer that generated by vbin_printf.
+ *
+ * The format 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
+ * %n is ignored
+ *
+ * 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
+ * number of characters written into @buf as return value
+ * (not including the trailing '\0'), use vscnprintf(). If the
+ * return is greater than or equal to @size, the resulting
+ * string is truncated.
+ */
+int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
+{
+ unsigned long long num;
+ char *str, *end, c;
+ const char *args = (const char *)bin_buf;
+
+ struct printf_spec spec = {0};
+
+ if (unlikely((int) size < 0)) {
+ /* There can be only one.. */
+ static char warn = 1;
+ WARN_ON(warn);
+ warn = 0;
+ return 0;
+ }
+
+ str = buf;
+ end = buf + size;
+
+#define get_arg(type) \
+({ \
+ typeof(type) value; \
+ if (sizeof(type) == 8) { \
+ args = PTR_ALIGN(args, sizeof(u32)); \
+ *(u32 *)&value = *(u32 *)args; \
+ *((u32 *)&value + 1) = *(u32 *)(args + 4); \
+ } else { \
+ args = PTR_ALIGN(args, sizeof(type)); \
+ value = *(typeof(type) *)args; \
+ } \
+ args += sizeof(type); \
+ value; \
+})
+
+ /* Make sure end is always >= buf */
+ if (end < buf) {
+ end = ((void *)-1);
+ size = end - buf;
+ }
+
+ while (*fmt) {
+ int read;
+ const char *old_fmt = fmt;
+
+ read = format_decode(fmt, &spec);
+
+ fmt += read;
+
+ switch (spec.type) {
+ case FORMAT_TYPE_NONE: {
+ int copy = read;
+ if (str < end) {
+ if (copy > end - str)
+ copy = end - str;
+ memcpy(str, old_fmt, copy);
+ }
+ str += read;
+ break;
+ }
+
+ case FORMAT_TYPE_WIDTH:
+ spec.field_width = get_arg(int);
+ break;
+
+ case FORMAT_TYPE_PRECISION:
+ spec.precision = get_arg(int);
+ break;
+
+ case FORMAT_TYPE_CHAR:
+ if (!(spec.flags & LEFT)) {
+ while (--spec.field_width > 0) {
+ if (str < end)
+ *str = ' ';
+ ++str;
+ }
+ }
+ c = (unsigned char) get_arg(char);
+ if (str < end)
+ *str = c;
+ ++str;
+ while (--spec.field_width > 0) {
+ if (str < end)
+ *str = ' ';
+ ++str;
+ }
+ break;
+
+ case FORMAT_TYPE_STR: {
+ const char *str_arg = args;
+ size_t len = strlen(str_arg);
+ args += len + 1;
+ str = string(str, end, (char *)str_arg, spec);
+ break;
+ }
+
+ case FORMAT_TYPE_PTR:
+ str = pointer(fmt+1, str, end, get_arg(void *), spec);
+ while (isalnum(*fmt))
+ fmt++;
+ break;
+
+ case FORMAT_TYPE_PERCENT_CHAR:
+ if (str < end)
+ *str = '%';
+ ++str;
+ break;
+
+ case FORMAT_TYPE_INVALID:
+ if (str < end)
+ *str = '%';
+ ++str;
+ break;
+
+ case FORMAT_TYPE_NRCHARS:
+ /* skip */
+ break;
+
+ default:
+ switch (spec.type) {
+
+ case FORMAT_TYPE_LONG_LONG:
+ num = get_arg(long long);
+ break;
+ case FORMAT_TYPE_ULONG:
+ num = get_arg(unsigned long);
+ break;
+ case FORMAT_TYPE_LONG:
+ num = get_arg(unsigned long);
+ break;
+ case FORMAT_TYPE_SIZE_T:
+ num = get_arg(size_t);
+ break;
+ case FORMAT_TYPE_PTRDIFF:
+ num = get_arg(ptrdiff_t);
+ break;
+ case FORMAT_TYPE_USHORT:
+ num = get_arg(unsigned short);
+ break;
+ case FORMAT_TYPE_SHORT:
+ num = get_arg(short);
+ break;
+ case FORMAT_TYPE_UINT:
+ num = get_arg(unsigned int);
+ break;
+ default:
+ num = get_arg(int);
+ }
+
+ str = number(str, end, num, spec);
+ }
+ }
+
+ if (size > 0) {
+ if (str < end)
+ *str = '\0';
+ else
+ end[-1] = '\0';
+ }
+
+#undef get_arg
+
+ /* the trailing null byte doesn't count towards the total */
+ return str - buf;
+}
+EXPORT_SYMBOL_GPL(bstr_printf);
+
+/**
+ * bprintf - Parse a format string and place args' binary value in a buffer
+ * @bin_buf: The buffer to place args' binary value
+ * @size: The size of the buffer(by words(32bits), not characters)
+ * @fmt: The format string to use
+ * @...: Arguments for the format string
+ *
+ * The function returns the number of words(u32) written
+ * into @bin_buf.
+ */
+int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, fmt);
+ ret = vbin_printf(bin_buf, size, fmt, args);
+ va_end(args);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(bprintf);
+
+#endif /* CONFIG_BINARY_PRINTF */
+
/**
* vsscanf - Unformat a buffer into a list of arguments
* @buf: input buffer
diff --git a/mm/Kconfig b/mm/Kconfig
index b53427ad30a..57971d2ab84 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -213,6 +213,8 @@ config UNEVICTABLE_LRU
will use one page flag and increase the code size a little,
say Y unless you know what you are doing.
+ See Documentation/vm/unevictable-lru.txt for more information.
+
config HAVE_MLOCK
bool
default y if MMU=y
diff --git a/mm/allocpercpu.c b/mm/allocpercpu.c
index 139d5b7b662..dfdee6a4735 100644
--- a/mm/allocpercpu.c
+++ b/mm/allocpercpu.c
@@ -31,7 +31,7 @@ static void percpu_depopulate(void *__pdata, int cpu)
* @__pdata: per-cpu data to depopulate
* @mask: depopulate per-cpu data for cpu's selected through mask bits
*/
-static void __percpu_depopulate_mask(void *__pdata, cpumask_t *mask)
+static void __percpu_depopulate_mask(void *__pdata, const cpumask_t *mask)
{
int cpu;
for_each_cpu_mask_nr(cpu, *mask)
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index be68c956a66..493b468a503 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -284,12 +284,12 @@ static wait_queue_head_t congestion_wqh[2] = {
};
-void clear_bdi_congested(struct backing_dev_info *bdi, int rw)
+void clear_bdi_congested(struct backing_dev_info *bdi, int sync)
{
enum bdi_state bit;
- wait_queue_head_t *wqh = &congestion_wqh[rw];
+ wait_queue_head_t *wqh = &congestion_wqh[sync];
- bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
+ bit = sync ? BDI_sync_congested : BDI_async_congested;
clear_bit(bit, &bdi->state);
smp_mb__after_clear_bit();
if (waitqueue_active(wqh))
@@ -297,11 +297,11 @@ void clear_bdi_congested(struct backing_dev_info *bdi, int rw)
}
EXPORT_SYMBOL(clear_bdi_congested);
-void set_bdi_congested(struct backing_dev_info *bdi, int rw)
+void set_bdi_congested(struct backing_dev_info *bdi, int sync)
{
enum bdi_state bit;
- bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
+ bit = sync ? BDI_sync_congested : BDI_async_congested;
set_bit(bit, &bdi->state);
}
EXPORT_SYMBOL(set_bdi_congested);
diff --git a/mm/failslab.c b/mm/failslab.c
index 7c6ea6493f8..9339de5f0a9 100644
--- a/mm/failslab.c
+++ b/mm/failslab.c
@@ -1,4 +1,5 @@
#include <linux/fault-inject.h>
+#include <linux/gfp.h>
static struct {
struct fault_attr attr;
diff --git a/mm/filemap.c b/mm/filemap.c
index 126d3973b3d..8bd498040f3 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -513,6 +513,7 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
}
return ret;
}
+EXPORT_SYMBOL_GPL(add_to_page_cache_lru);
#ifdef CONFIG_NUMA
struct page *__page_cache_alloc(gfp_t gfp)
@@ -565,6 +566,24 @@ void wait_on_page_bit(struct page *page, int bit_nr)
EXPORT_SYMBOL(wait_on_page_bit);
/**
+ * add_page_wait_queue - Add an arbitrary waiter to a page's wait queue
+ * @page: Page defining the wait queue of interest
+ * @waiter: Waiter to add to the queue
+ *
+ * Add an arbitrary @waiter to the wait queue for the nominated @page.
+ */
+void add_page_wait_queue(struct page *page, wait_queue_t *waiter)
+{
+ wait_queue_head_t *q = page_waitqueue(page);
+ unsigned long flags;
+
+ spin_lock_irqsave(&q->lock, flags);
+ __add_wait_queue(q, waiter);
+ spin_unlock_irqrestore(&q->lock, flags);
+}
+EXPORT_SYMBOL_GPL(add_page_wait_queue);
+
+/**
* unlock_page - unlock a locked page
* @page: the page
*
@@ -627,6 +646,7 @@ int __lock_page_killable(struct page *page)
return __wait_on_bit_lock(page_waitqueue(page), &wait,
sync_page_killable, TASK_KILLABLE);
}
+EXPORT_SYMBOL_GPL(__lock_page_killable);
/**
* __lock_page_nosync - get a lock on the page, without calling sync_page()
@@ -2463,6 +2483,9 @@ EXPORT_SYMBOL(generic_file_aio_write);
* (presumably at page->private). If the release was successful, return `1'.
* Otherwise return zero.
*
+ * This may also be called if PG_fscache is set on a page, indicating that the
+ * page is known to the local caching routines.
+ *
* The @gfp_mask argument specifies whether I/O may be performed to release
* this page (__GFP_IO), and whether the call may block (__GFP_WAIT & __GFP_FS).
*
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 2fc6d6c4823..e44fb0fbb80 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -932,7 +932,7 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
if (unlikely(!mem))
return 0;
- VM_BUG_ON(mem_cgroup_is_obsolete(mem));
+ VM_BUG_ON(!mem || mem_cgroup_is_obsolete(mem));
while (1) {
int ret;
diff --git a/mm/migrate.c b/mm/migrate.c
index a9eff3f092f..068655d8f88 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -250,7 +250,7 @@ out:
* The number of remaining references must be:
* 1 for anonymous pages without a mapping
* 2 for pages with a mapping
- * 3 for pages with a mapping and PagePrivate set.
+ * 3 for pages with a mapping and PagePrivate/PagePrivate2 set.
*/
static int migrate_page_move_mapping(struct address_space *mapping,
struct page *newpage, struct page *page)
@@ -270,7 +270,7 @@ static int migrate_page_move_mapping(struct address_space *mapping,
pslot = radix_tree_lookup_slot(&mapping->page_tree,
page_index(page));
- expected_count = 2 + !!PagePrivate(page);
+ expected_count = 2 + !!page_has_private(page);
if (page_count(page) != expected_count ||
(struct page *)radix_tree_deref_slot(pslot) != page) {
spin_unlock_irq(&mapping->tree_lock);
@@ -386,7 +386,7 @@ EXPORT_SYMBOL(fail_migrate_page);
/*
* Common logic to directly migrate a single page suitable for
- * pages that do not use PagePrivate.
+ * pages that do not use PagePrivate/PagePrivate2.
*
* Pages are locked upon entry and exit.
*/
@@ -522,7 +522,7 @@ static int fallback_migrate_page(struct address_space *mapping,
* Buffers may be managed in a filesystem specific way.
* We must have no buffers or drop them.
*/
- if (PagePrivate(page) &&
+ if (page_has_private(page) &&
!try_to_release_page(page, GFP_KERNEL))
return -EAGAIN;
@@ -655,7 +655,7 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
* free the metadata, so the page can be freed.
*/
if (!page->mapping) {
- if (!PageAnon(page) && PagePrivate(page)) {
+ if (!PageAnon(page) && page_has_private(page)) {
/*
* Go direct to try_to_free_buffers() here because
* a) that's what try_to_release_page() would do anyway
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 0284e528748..e2f26991fff 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -331,7 +331,7 @@ static int destroy_compound_page(struct page *page, unsigned long order)
for (i = 1; i < nr_pages; i++) {
struct page *p = page + i;
- if (unlikely(!PageTail(p) | (p->first_page != page))) {
+ if (unlikely(!PageTail(p) || (p->first_page != page))) {
bad_page(page);
bad++;
}
@@ -2128,7 +2128,7 @@ static int find_next_best_node(int node, nodemask_t *used_node_mask)
int n, val;
int min_val = INT_MAX;
int best_node = -1;
- node_to_cpumask_ptr(tmp, 0);
+ const struct cpumask *tmp = cpumask_of_node(0);
/* Use the local node if we haven't already */
if (!node_isset(node, *used_node_mask)) {
@@ -2149,8 +2149,8 @@ static int find_next_best_node(int node, nodemask_t *used_node_mask)
val += (n < node);
/* Give preference to headless and unused nodes */
- node_to_cpumask_ptr_next(tmp, n);
- if (!cpus_empty(*tmp))
+ tmp = cpumask_of_node(n);
+ if (!cpumask_empty(tmp))
val += PENALTY_FOR_NODE_WITH_CPUS;
/* Slight preference for less loaded node */
diff --git a/mm/pdflush.c b/mm/pdflush.c
index 118905e3d78..f2caf96993f 100644
--- a/mm/pdflush.c
+++ b/mm/pdflush.c
@@ -58,6 +58,14 @@ static DEFINE_SPINLOCK(pdflush_lock);
int nr_pdflush_threads = 0;
/*
+ * The max/min number of pdflush threads. R/W by sysctl at
+ * /proc/sys/vm/nr_pdflush_threads_max/min
+ */
+int nr_pdflush_threads_max __read_mostly = MAX_PDFLUSH_THREADS;
+int nr_pdflush_threads_min __read_mostly = MIN_PDFLUSH_THREADS;
+
+
+/*
* The time at which the pdflush thread pool last went empty
*/
static unsigned long last_empty_jifs;
@@ -68,7 +76,7 @@ static unsigned long last_empty_jifs;
* Thread pool management algorithm:
*
* - The minimum and maximum number of pdflush instances are bound
- * by MIN_PDFLUSH_THREADS and MAX_PDFLUSH_THREADS.
+ * by nr_pdflush_threads_min and nr_pdflush_threads_max.
*
* - If there have been no idle pdflush instances for 1 second, create
* a new one.
@@ -98,7 +106,6 @@ static int __pdflush(struct pdflush_work *my_work)
INIT_LIST_HEAD(&my_work->list);
spin_lock_irq(&pdflush_lock);
- nr_pdflush_threads++;
for ( ; ; ) {
struct pdflush_work *pdf;
@@ -126,20 +133,25 @@ static int __pdflush(struct pdflush_work *my_work)
(*my_work->fn)(my_work->arg0);
+ spin_lock_irq(&pdflush_lock);
+
/*
* Thread creation: For how long have there been zero
* available threads?
+ *
+ * To throttle creation, we reset last_empty_jifs.
*/
if (time_after(jiffies, last_empty_jifs + 1 * HZ)) {
- /* unlocked list_empty() test is OK here */
- if (list_empty(&pdflush_list)) {
- /* unlocked test is OK here */
- if (nr_pdflush_threads < MAX_PDFLUSH_THREADS)
- start_one_pdflush_thread();
+ if (list_empty(&pdflush_list) &&
+ nr_pdflush_threads < nr_pdflush_threads_max) {
+ last_empty_jifs = jiffies;
+ nr_pdflush_threads++;
+ spin_unlock_irq(&pdflush_lock);
+ start_one_pdflush_thread();
+ spin_lock_irq(&pdflush_lock);
}
}
- spin_lock_irq(&pdflush_lock);
my_work->fn = NULL;
/*
@@ -148,7 +160,7 @@ static int __pdflush(struct pdflush_work *my_work)
*/
if (list_empty(&pdflush_list))
continue;
- if (nr_pdflush_threads <= MIN_PDFLUSH_THREADS)
+ if (nr_pdflush_threads <= nr_pdflush_threads_min)
continue;
pdf = list_entry(pdflush_list.prev, struct pdflush_work, list);
if (time_after(jiffies, pdf->when_i_went_to_sleep + 1 * HZ)) {
@@ -236,14 +248,27 @@ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0)
static void start_one_pdflush_thread(void)
{
- kthread_run(pdflush, NULL, "pdflush");
+ struct task_struct *k;
+
+ k = kthread_run(pdflush, NULL, "pdflush");
+ if (unlikely(IS_ERR(k))) {
+ spin_lock_irq(&pdflush_lock);
+ nr_pdflush_threads--;
+ spin_unlock_irq(&pdflush_lock);
+ }
}
static int __init pdflush_init(void)
{
int i;
- for (i = 0; i < MIN_PDFLUSH_THREADS; i++)
+ /*
+ * Pre-set nr_pdflush_threads... If we fail to create,
+ * the count will be decremented.
+ */
+ nr_pdflush_threads = nr_pdflush_threads_min;
+
+ for (i = 0; i < nr_pdflush_threads_min; i++)
start_one_pdflush_thread();
return 0;
}
diff --git a/mm/quicklist.c b/mm/quicklist.c
index 8dbb6805ef3..e66d07d1b4f 100644
--- a/mm/quicklist.c
+++ b/mm/quicklist.c
@@ -29,7 +29,7 @@ static unsigned long max_pages(unsigned long min_pages)
int node = numa_node_id();
struct zone *zones = NODE_DATA(node)->node_zones;
int num_cpus_on_node;
- node_to_cpumask_ptr(cpumask_on_node, node);
+ const struct cpumask *cpumask_on_node = cpumask_of_node(node);
node_free_pages =
#ifdef CONFIG_ZONE_DMA
diff --git a/mm/readahead.c b/mm/readahead.c
index 9ce303d4b81..133b6d52551 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -31,6 +31,42 @@ EXPORT_SYMBOL_GPL(file_ra_state_init);
#define list_to_page(head) (list_entry((head)->prev, struct page, lru))
+/*
+ * see if a page needs releasing upon read_cache_pages() failure
+ * - the caller of read_cache_pages() may have set PG_private or PG_fscache
+ * before calling, such as the NFS fs marking pages that are cached locally
+ * on disk, thus we need to give the fs a chance to clean up in the event of
+ * an error
+ */
+static void read_cache_pages_invalidate_page(struct address_space *mapping,
+ struct page *page)
+{
+ if (page_has_private(page)) {
+ if (!trylock_page(page))
+ BUG();
+ page->mapping = mapping;
+ do_invalidatepage(page, 0);
+ page->mapping = NULL;
+ unlock_page(page);
+ }
+ page_cache_release(page);
+}
+
+/*
+ * release a list of pages, invalidating them first if need be
+ */
+static void read_cache_pages_invalidate_pages(struct address_space *mapping,
+ struct list_head *pages)
+{
+ struct page *victim;
+
+ while (!list_empty(pages)) {
+ victim = list_to_page(pages);
+ list_del(&victim->lru);
+ read_cache_pages_invalidate_page(mapping, victim);
+ }
+}
+
/**
* read_cache_pages - populate an address space with some pages & start reads against them
* @mapping: the address_space
@@ -52,14 +88,14 @@ int read_cache_pages(struct address_space *mapping, struct list_head *pages,
list_del(&page->lru);
if (add_to_page_cache_lru(page, mapping,
page->index, GFP_KERNEL)) {
- page_cache_release(page);
+ read_cache_pages_invalidate_page(mapping, page);
continue;
}
page_cache_release(page);
ret = filler(data, page);
if (unlikely(ret)) {
- put_pages_list(pages);
+ read_cache_pages_invalidate_pages(mapping, pages);
break;
}
task_io_account_read(PAGE_CACHE_SIZE);
diff --git a/mm/shmem.c b/mm/shmem.c
index d94d2e9146b..f9cb20ebb99 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/vfs.h>
#include <linux/mount.h>
+#include <linux/pagemap.h>
#include <linux/file.h>
#include <linux/mm.h>
#include <linux/module.h>
@@ -43,7 +44,6 @@ static struct vfsmount *shm_mnt;
#include <linux/exportfs.h>
#include <linux/generic_acl.h>
#include <linux/mman.h>
-#include <linux/pagemap.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/backing-dev.h>
@@ -65,13 +65,28 @@ static struct vfsmount *shm_mnt;
#include <asm/div64.h>
#include <asm/pgtable.h>
+/*
+ * The maximum size of a shmem/tmpfs file is limited by the maximum size of
+ * its triple-indirect swap vector - see illustration at shmem_swp_entry().
+ *
+ * With 4kB page size, maximum file size is just over 2TB on a 32-bit kernel,
+ * but one eighth of that on a 64-bit kernel. With 8kB page size, maximum
+ * file size is just over 4TB on a 64-bit kernel, but 16TB on a 32-bit kernel,
+ * MAX_LFS_FILESIZE being then more restrictive than swap vector layout.
+ *
+ * We use / and * instead of shifts in the definitions below, so that the swap
+ * vector can be tested with small even values (e.g. 20) for ENTRIES_PER_PAGE.
+ */
#define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
-#define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
-#define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512)
+#define ENTRIES_PER_PAGEPAGE ((unsigned long long)ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
-#define SHMEM_MAX_INDEX (SHMEM_NR_DIRECT + (ENTRIES_PER_PAGEPAGE/2) * (ENTRIES_PER_PAGE+1))
-#define SHMEM_MAX_BYTES ((unsigned long long)SHMEM_MAX_INDEX << PAGE_CACHE_SHIFT)
+#define SHMSWP_MAX_INDEX (SHMEM_NR_DIRECT + (ENTRIES_PER_PAGEPAGE/2) * (ENTRIES_PER_PAGE+1))
+#define SHMSWP_MAX_BYTES (SHMSWP_MAX_INDEX << PAGE_CACHE_SHIFT)
+#define SHMEM_MAX_BYTES min_t(unsigned long long, SHMSWP_MAX_BYTES, MAX_LFS_FILESIZE)
+#define SHMEM_MAX_INDEX ((unsigned long)((SHMEM_MAX_BYTES+1) >> PAGE_CACHE_SHIFT))
+
+#define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512)
#define VM_ACCT(size) (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT)
/* info->flags needs VM_flags to handle pagein/truncate races efficiently */
@@ -2581,7 +2596,7 @@ int shmem_unuse(swp_entry_t entry, struct page *page)
#define shmem_get_inode(sb, mode, dev, flags) ramfs_get_inode(sb, mode, dev)
#define shmem_acct_size(flags, size) 0
#define shmem_unacct_size(flags, size) do {} while (0)
-#define SHMEM_MAX_BYTES LLONG_MAX
+#define SHMEM_MAX_BYTES MAX_LFS_FILESIZE
#endif /* CONFIG_SHMEM */
diff --git a/mm/slab.c b/mm/slab.c
index 208323fd37b..9a90b00d2f9 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -102,6 +102,7 @@
#include <linux/cpu.h>
#include <linux/sysctl.h>
#include <linux/module.h>
+#include <trace/kmemtrace.h>
#include <linux/rcupdate.h>
#include <linux/string.h>
#include <linux/uaccess.h>
@@ -568,6 +569,14 @@ static void **dbg_userword(struct kmem_cache *cachep, void *objp)
#endif
+#ifdef CONFIG_KMEMTRACE
+size_t slab_buffer_size(struct kmem_cache *cachep)
+{
+ return cachep->buffer_size;
+}
+EXPORT_SYMBOL(slab_buffer_size);
+#endif
+
/*
* Do not go above this order unless 0 objects fit into the slab.
*/
@@ -1160,7 +1169,7 @@ static void __cpuinit cpuup_canceled(long cpu)
struct kmem_cache *cachep;
struct kmem_list3 *l3 = NULL;
int node = cpu_to_node(cpu);
- node_to_cpumask_ptr(mask, node);
+ const struct cpumask *mask = cpumask_of_node(node);
list_for_each_entry(cachep, &cache_chain, next) {
struct array_cache *nc;
@@ -3554,10 +3563,23 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp)
*/
void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
{
- return __cache_alloc(cachep, flags, __builtin_return_address(0));
+ void *ret = __cache_alloc(cachep, flags, __builtin_return_address(0));
+
+ trace_kmem_cache_alloc(_RET_IP_, ret,
+ obj_size(cachep), cachep->buffer_size, flags);
+
+ return ret;
}
EXPORT_SYMBOL(kmem_cache_alloc);
+#ifdef CONFIG_KMEMTRACE
+void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags)
+{
+ return __cache_alloc(cachep, flags, __builtin_return_address(0));
+}
+EXPORT_SYMBOL(kmem_cache_alloc_notrace);
+#endif
+
/**
* kmem_ptr_validate - check if an untrusted pointer might be a slab entry.
* @cachep: the cache we're checking against
@@ -3602,23 +3624,46 @@ out:
#ifdef CONFIG_NUMA
void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
{
- return __cache_alloc_node(cachep, flags, nodeid,
- __builtin_return_address(0));
+ void *ret = __cache_alloc_node(cachep, flags, nodeid,
+ __builtin_return_address(0));
+
+ trace_kmem_cache_alloc_node(_RET_IP_, ret,
+ obj_size(cachep), cachep->buffer_size,
+ flags, nodeid);
+
+ return ret;
}
EXPORT_SYMBOL(kmem_cache_alloc_node);
+#ifdef CONFIG_KMEMTRACE
+void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep,
+ gfp_t flags,
+ int nodeid)
+{
+ return __cache_alloc_node(cachep, flags, nodeid,
+ __builtin_return_address(0));
+}
+EXPORT_SYMBOL(kmem_cache_alloc_node_notrace);
+#endif
+
static __always_inline void *
__do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller)
{
struct kmem_cache *cachep;
+ void *ret;
cachep = kmem_find_general_cachep(size, flags);
if (unlikely(ZERO_OR_NULL_PTR(cachep)))
return cachep;
- return kmem_cache_alloc_node(cachep, flags, node);
+ ret = kmem_cache_alloc_node_notrace(cachep, flags, node);
+
+ trace_kmalloc_node((unsigned long) caller, ret,
+ size, cachep->buffer_size, flags, node);
+
+ return ret;
}
-#ifdef CONFIG_DEBUG_SLAB
+#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE)
void *__kmalloc_node(size_t size, gfp_t flags, int node)
{
return __do_kmalloc_node(size, flags, node,
@@ -3651,6 +3696,7 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
void *caller)
{
struct kmem_cache *cachep;
+ void *ret;
/* If you want to save a few bytes .text space: replace
* __ with kmem_.
@@ -3660,11 +3706,16 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
cachep = __find_general_cachep(size, flags);
if (unlikely(ZERO_OR_NULL_PTR(cachep)))
return cachep;
- return __cache_alloc(cachep, flags, caller);
+ ret = __cache_alloc(cachep, flags, caller);
+
+ trace_kmalloc((unsigned long) caller, ret,
+ size, cachep->buffer_size, flags);
+
+ return ret;
}
-#ifdef CONFIG_DEBUG_SLAB
+#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE)
void *__kmalloc(size_t size, gfp_t flags)
{
return __do_kmalloc(size, flags, __builtin_return_address(0));
@@ -3703,6 +3754,8 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
debug_check_no_obj_freed(objp, obj_size(cachep));
__cache_free(cachep, objp);
local_irq_restore(flags);
+
+ trace_kmem_cache_free(_RET_IP_, objp);
}
EXPORT_SYMBOL(kmem_cache_free);
@@ -3720,6 +3773,8 @@ void kfree(const void *objp)
struct kmem_cache *c;
unsigned long flags;
+ trace_kfree(_RET_IP_, objp);
+
if (unlikely(ZERO_OR_NULL_PTR(objp)))
return;
local_irq_save(flags);
diff --git a/mm/slob.c b/mm/slob.c
index 7a3411524da..a2d4ab32198 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -65,6 +65,7 @@
#include <linux/module.h>
#include <linux/rcupdate.h>
#include <linux/list.h>
+#include <trace/kmemtrace.h>
#include <asm/atomic.h>
/*
@@ -474,6 +475,7 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node)
{
unsigned int *m;
int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
+ void *ret;
lockdep_trace_alloc(gfp);
@@ -482,12 +484,16 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node)
return ZERO_SIZE_PTR;
m = slob_alloc(size + align, gfp, align, node);
+
if (!m)
return NULL;
*m = size;
- return (void *)m + align;
+ ret = (void *)m + align;
+
+ trace_kmalloc_node(_RET_IP_, ret,
+ size, size + align, gfp, node);
} else {
- void *ret;
+ unsigned int order = get_order(size);
ret = slob_new_pages(gfp | __GFP_COMP, get_order(size), node);
if (ret) {
@@ -495,8 +501,12 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node)
page = virt_to_page(ret);
page->private = size;
}
- return ret;
+
+ trace_kmalloc_node(_RET_IP_, ret,
+ size, PAGE_SIZE << order, gfp, node);
}
+
+ return ret;
}
EXPORT_SYMBOL(__kmalloc_node);
@@ -504,6 +514,8 @@ void kfree(const void *block)
{
struct slob_page *sp;
+ trace_kfree(_RET_IP_, block);
+
if (unlikely(ZERO_OR_NULL_PTR(block)))
return;
@@ -583,10 +595,17 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
{
void *b;
- if (c->size < PAGE_SIZE)
+ if (c->size < PAGE_SIZE) {
b = slob_alloc(c->size, flags, c->align, node);
- else
+ trace_kmem_cache_alloc_node(_RET_IP_, b, c->size,
+ SLOB_UNITS(c->size) * SLOB_UNIT,
+ flags, node);
+ } else {
b = slob_new_pages(flags, get_order(c->size), node);
+ trace_kmem_cache_alloc_node(_RET_IP_, b, c->size,
+ PAGE_SIZE << get_order(c->size),
+ flags, node);
+ }
if (c->ctor)
c->ctor(b);
@@ -622,6 +641,8 @@ void kmem_cache_free(struct kmem_cache *c, void *b)
} else {
__kmem_cache_free(b, c->size);
}
+
+ trace_kmem_cache_free(_RET_IP_, b);
}
EXPORT_SYMBOL(kmem_cache_free);
diff --git a/mm/slub.c b/mm/slub.c
index c4ea9158c9f..7ab54ecbd3f 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <trace/kmemtrace.h>
#include <linux/cpu.h>
#include <linux/cpuset.h>
#include <linux/mempolicy.h>
@@ -1618,18 +1619,45 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags)
{
- return slab_alloc(s, gfpflags, -1, _RET_IP_);
+ void *ret = slab_alloc(s, gfpflags, -1, _RET_IP_);
+
+ trace_kmem_cache_alloc(_RET_IP_, ret, s->objsize, s->size, gfpflags);
+
+ return ret;
}
EXPORT_SYMBOL(kmem_cache_alloc);
+#ifdef CONFIG_KMEMTRACE
+void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags)
+{
+ return slab_alloc(s, gfpflags, -1, _RET_IP_);
+}
+EXPORT_SYMBOL(kmem_cache_alloc_notrace);
+#endif
+
#ifdef CONFIG_NUMA
void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node)
{
- return slab_alloc(s, gfpflags, node, _RET_IP_);
+ void *ret = slab_alloc(s, gfpflags, node, _RET_IP_);
+
+ trace_kmem_cache_alloc_node(_RET_IP_, ret,
+ s->objsize, s->size, gfpflags, node);
+
+ return ret;
}
EXPORT_SYMBOL(kmem_cache_alloc_node);
#endif
+#ifdef CONFIG_KMEMTRACE
+void *kmem_cache_alloc_node_notrace(struct kmem_cache *s,
+ gfp_t gfpflags,
+ int node)
+{
+ return slab_alloc(s, gfpflags, node, _RET_IP_);
+}
+EXPORT_SYMBOL(kmem_cache_alloc_node_notrace);
+#endif
+
/*
* Slow patch handling. This may still be called frequently since objects
* have a longer lifetime than the cpu slabs in most processing loads.
@@ -1737,6 +1765,8 @@ void kmem_cache_free(struct kmem_cache *s, void *x)
page = virt_to_head_page(x);
slab_free(s, page, x, _RET_IP_);
+
+ trace_kmem_cache_free(_RET_IP_, x);
}
EXPORT_SYMBOL(kmem_cache_free);
@@ -2659,6 +2689,7 @@ static struct kmem_cache *get_slab(size_t size, gfp_t flags)
void *__kmalloc(size_t size, gfp_t flags)
{
struct kmem_cache *s;
+ void *ret;
if (unlikely(size > SLUB_MAX_SIZE))
return kmalloc_large(size, flags);
@@ -2668,7 +2699,11 @@ void *__kmalloc(size_t size, gfp_t flags)
if (unlikely(ZERO_OR_NULL_PTR(s)))
return s;
- return slab_alloc(s, flags, -1, _RET_IP_);
+ ret = slab_alloc(s, flags, -1, _RET_IP_);
+
+ trace_kmalloc(_RET_IP_, ret, size, s->size, flags);
+
+ return ret;
}
EXPORT_SYMBOL(__kmalloc);
@@ -2687,16 +2722,28 @@ static void *kmalloc_large_node(size_t size, gfp_t flags, int node)
void *__kmalloc_node(size_t size, gfp_t flags, int node)
{
struct kmem_cache *s;
+ void *ret;
- if (unlikely(size > SLUB_MAX_SIZE))
- return kmalloc_large_node(size, flags, node);
+ if (unlikely(size > SLUB_MAX_SIZE)) {
+ ret = kmalloc_large_node(size, flags, node);
+
+ trace_kmalloc_node(_RET_IP_, ret,
+ size, PAGE_SIZE << get_order(size),
+ flags, node);
+
+ return ret;
+ }
s = get_slab(size, flags);
if (unlikely(ZERO_OR_NULL_PTR(s)))
return s;
- return slab_alloc(s, flags, node, _RET_IP_);
+ ret = slab_alloc(s, flags, node, _RET_IP_);
+
+ trace_kmalloc_node(_RET_IP_, ret, size, s->size, flags, node);
+
+ return ret;
}
EXPORT_SYMBOL(__kmalloc_node);
#endif
@@ -2745,6 +2792,8 @@ void kfree(const void *x)
struct page *page;
void *object = (void *)x;
+ trace_kfree(_RET_IP_, x);
+
if (unlikely(ZERO_OR_NULL_PTR(x)))
return;
@@ -3224,6 +3273,7 @@ static struct notifier_block __cpuinitdata slab_notifier = {
void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, unsigned long caller)
{
struct kmem_cache *s;
+ void *ret;
if (unlikely(size > SLUB_MAX_SIZE))
return kmalloc_large(size, gfpflags);
@@ -3233,13 +3283,19 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, unsigned long caller)
if (unlikely(ZERO_OR_NULL_PTR(s)))
return s;
- return slab_alloc(s, gfpflags, -1, caller);
+ ret = slab_alloc(s, gfpflags, -1, caller);
+
+ /* Honor the call site pointer we recieved. */
+ trace_kmalloc(caller, ret, size, s->size, gfpflags);
+
+ return ret;
}
void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
int node, unsigned long caller)
{
struct kmem_cache *s;
+ void *ret;
if (unlikely(size > SLUB_MAX_SIZE))
return kmalloc_large_node(size, gfpflags, node);
@@ -3249,7 +3305,12 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
if (unlikely(ZERO_OR_NULL_PTR(s)))
return s;
- return slab_alloc(s, gfpflags, node, caller);
+ ret = slab_alloc(s, gfpflags, node, caller);
+
+ /* Honor the call site pointer we recieved. */
+ trace_kmalloc_node(caller, ret, size, s->size, gfpflags, node);
+
+ return ret;
}
#ifdef CONFIG_SLUB_DEBUG
diff --git a/mm/swap.c b/mm/swap.c
index 6e83084c1f6..bede23ce64e 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -448,8 +448,8 @@ void pagevec_strip(struct pagevec *pvec)
for (i = 0; i < pagevec_count(pvec); i++) {
struct page *page = pvec->pages[i];
- if (PagePrivate(page) && trylock_page(page)) {
- if (PagePrivate(page))
+ if (page_has_private(page) && trylock_page(page)) {
+ if (page_has_private(page))
try_to_release_page(page, 0);
unlock_page(page);
}
diff --git a/mm/truncate.c b/mm/truncate.c
index 1229211104f..55206fab7b9 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -50,7 +50,7 @@ void do_invalidatepage(struct page *page, unsigned long offset)
static inline void truncate_partial_page(struct page *page, unsigned partial)
{
zero_user_segment(page, partial, PAGE_CACHE_SIZE);
- if (PagePrivate(page))
+ if (page_has_private(page))
do_invalidatepage(page, partial);
}
@@ -99,7 +99,7 @@ truncate_complete_page(struct address_space *mapping, struct page *page)
if (page->mapping != mapping)
return;
- if (PagePrivate(page))
+ if (page_has_private(page))
do_invalidatepage(page, 0);
cancel_dirty_page(page, PAGE_CACHE_SIZE);
@@ -126,7 +126,7 @@ invalidate_complete_page(struct address_space *mapping, struct page *page)
if (page->mapping != mapping)
return 0;
- if (PagePrivate(page) && !try_to_release_page(page, 0))
+ if (page_has_private(page) && !try_to_release_page(page, 0))
return 0;
clear_page_mlock(page);
@@ -348,7 +348,7 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)
if (page->mapping != mapping)
return 0;
- if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL))
+ if (page_has_private(page) && !try_to_release_page(page, GFP_KERNEL))
return 0;
spin_lock_irq(&mapping->tree_lock);
@@ -356,7 +356,7 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)
goto failed;
clear_page_mlock(page);
- BUG_ON(PagePrivate(page));
+ BUG_ON(page_has_private(page));
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
page_cache_release(page); /* pagecache ref */
diff --git a/mm/util.c b/mm/util.c
index 7c122e49f76..55bef160b9f 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -4,6 +4,7 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/sched.h>
+#include <linux/tracepoint.h>
#include <asm/uaccess.h>
/**
@@ -222,6 +223,22 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
}
#endif
+/**
+ * get_user_pages_fast() - pin user pages in memory
+ * @start: starting user address
+ * @nr_pages: number of pages from start to pin
+ * @write: whether pages will be written to
+ * @pages: array that receives pointers to the pages pinned.
+ * Should be at least nr_pages long.
+ *
+ * Attempt to pin user pages in memory without taking mm->mmap_sem.
+ * If not successful, it will fall back to taking the lock and
+ * calling get_user_pages().
+ *
+ * Returns number of pages pinned. This may be fewer than the number
+ * requested. If nr_pages is 0 or negative, returns 0. If no pages
+ * were pinned, returns -errno.
+ */
int __attribute__((weak)) get_user_pages_fast(unsigned long start,
int nr_pages, int write, struct page **pages)
{
@@ -236,3 +253,18 @@ int __attribute__((weak)) get_user_pages_fast(unsigned long start,
return ret;
}
EXPORT_SYMBOL_GPL(get_user_pages_fast);
+
+/* Tracepoints definitions. */
+DEFINE_TRACE(kmalloc);
+DEFINE_TRACE(kmem_cache_alloc);
+DEFINE_TRACE(kmalloc_node);
+DEFINE_TRACE(kmem_cache_alloc_node);
+DEFINE_TRACE(kfree);
+DEFINE_TRACE(kmem_cache_free);
+
+EXPORT_TRACEPOINT_SYMBOL(kmalloc);
+EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc);
+EXPORT_TRACEPOINT_SYMBOL(kmalloc_node);
+EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc_node);
+EXPORT_TRACEPOINT_SYMBOL(kfree);
+EXPORT_TRACEPOINT_SYMBOL(kmem_cache_free);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 06e72693b45..39fdfb14eea 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -283,7 +283,7 @@ static inline int page_mapping_inuse(struct page *page)
static inline int is_page_cache_freeable(struct page *page)
{
- return page_count(page) - !!PagePrivate(page) == 2;
+ return page_count(page) - !!page_has_private(page) == 2;
}
static int may_write_to_queue(struct backing_dev_info *bdi)
@@ -367,7 +367,7 @@ static pageout_t pageout(struct page *page, struct address_space *mapping,
* Some data journaling orphaned pages can have
* page->mapping == NULL while being dirty with clean buffers.
*/
- if (PagePrivate(page)) {
+ if (page_has_private(page)) {
if (try_to_free_buffers(page)) {
ClearPageDirty(page);
printk("%s: orphaned page\n", __func__);
@@ -727,7 +727,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
* process address space (page_count == 1) it can be freed.
* Otherwise, leave the page on the LRU so it is swappable.
*/
- if (PagePrivate(page)) {
+ if (page_has_private(page)) {
if (!try_to_release_page(page, sc->gfp_mask))
goto activate_locked;
if (!mapping && page_count(page) == 1) {
@@ -1967,7 +1967,7 @@ static int kswapd(void *p)
struct reclaim_state reclaim_state = {
.reclaimed_slab = 0,
};
- node_to_cpumask_ptr(cpumask, pgdat->node_id);
+ const struct cpumask *cpumask = cpumask_of_node(pgdat->node_id);
lockdep_set_current_reclaim_state(GFP_KERNEL);
@@ -2204,7 +2204,9 @@ static int __devinit cpu_callback(struct notifier_block *nfb,
if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN) {
for_each_node_state(nid, N_HIGH_MEMORY) {
pg_data_t *pgdat = NODE_DATA(nid);
- node_to_cpumask_ptr(mask, pgdat->node_id);
+ const struct cpumask *mask;
+
+ mask = cpumask_of_node(pgdat->node_id);
if (cpumask_any_and(cpu_online_mask, mask) < nr_cpu_ids)
/* One of our CPUs online: restore mask */
diff --git a/net/802/fddi.c b/net/802/fddi.c
index f1611a1e06a..539e6064e6d 100644
--- a/net/802/fddi.c
+++ b/net/802/fddi.c
@@ -215,3 +215,5 @@ struct net_device *alloc_fddidev(int sizeof_priv)
return alloc_netdev(sizeof_priv, "fddi%d", fddi_setup);
}
EXPORT_SYMBOL(alloc_fddidev);
+
+MODULE_LICENSE("GPL");
diff --git a/net/Kconfig b/net/Kconfig
index ec93e7e38b3..ce77db4fcec 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -140,7 +140,7 @@ config NETFILTER_ADVANCED
default y
help
If you say Y here you can select between all the netfilter modules.
- If you say N the more ununsual ones will not be shown and the
+ If you say N the more unusual ones will not be shown and the
basic ones needed by most people will default to 'M'.
If unsure, say Y.
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index ec992159b5f..ca8cb326d1d 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -22,17 +22,17 @@ menuconfig IPV6
if IPV6
config IPV6_PRIVACY
- bool "IPv6: Privacy Extensions support"
+ bool "IPv6: Privacy Extensions (RFC 3041) support"
---help---
Privacy Extensions for Stateless Address Autoconfiguration in IPv6
- support. With this option, additional periodically-alter
- pseudo-random global-scope unicast address(es) will assigned to
+ support. With this option, additional periodically-altered
+ pseudo-random global-scope unicast address(es) will be assigned to
your interface(s).
- We use our standard pseudo random algorithm to generate randomized
- interface identifier, instead of one described in RFC 3041.
+ We use our standard pseudo-random algorithm to generate the
+ randomized interface identifier, instead of one described in RFC 3041.
- By default, kernel do not generate temporary addresses.
+ By default the kernel does not generate temporary addresses.
To use temporary addresses, do
echo 2 >/proc/sys/net/ipv6/conf/all/use_tempaddr
@@ -43,9 +43,9 @@ config IPV6_ROUTER_PREF
bool "IPv6: Router Preference (RFC 4191) support"
---help---
Router Preference is an optional extension to the Router
- Advertisement message to improve the ability of hosts
- to pick more appropriate router, especially when the hosts
- is placed in a multi-homed network.
+ Advertisement message which improves the ability of hosts
+ to pick an appropriate router, especially when the hosts
+ are placed in a multi-homed network.
If unsure, say N.
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index dfed176aed3..800ae854247 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1033,6 +1033,8 @@ static struct xt_counters *alloc_counters(struct xt_table *table)
xt_free_table_info(info);
+ return counters;
+
free_counters:
vfree(counters);
nomem:
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 0af823cf7f1..5ee5a031bc9 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -72,6 +72,7 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
#endif
skb->protocol = htons(ETH_P_IPV6);
+ skb->local_df = 1;
return x->outer_mode->output2(x, skb);
}
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 60c16162474..f3d9ae350fb 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -33,7 +33,7 @@ choice
---help---
This option selects the default rate control algorithm
mac80211 will use. Note that this default can still be
- overriden through the ieee80211_default_rc_algo module
+ overridden through the ieee80211_default_rc_algo module
parameter if different algorithms are available.
config MAC80211_RC_DEFAULT_PID
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 2c967e4f706..2329c5f5055 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -52,7 +52,7 @@ config NF_CT_ACCT
Please note that currently this option only sets a default state.
You may change it at boot time with nf_conntrack.acct=0/1 kernel
- paramater or by loading the nf_conntrack module with acct=0/1.
+ parameter or by loading the nf_conntrack module with acct=0/1.
You may also disable/enable it on a running system with:
sysctl net.netfilter.nf_conntrack_acct=0/1
@@ -374,7 +374,7 @@ config NETFILTER_XT_TARGET_HL
config NETFILTER_XT_TARGET_LED
tristate '"LED" target support'
- depends on LEDS_CLASS && LED_TRIGGERS
+ depends on LEDS_CLASS && LEDS_TRIGGERS
depends on NETFILTER_ADVANCED
help
This option adds a `LED' target, which allows you to blink LEDs in
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 3940f996a2e..afde8f99164 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -372,7 +372,7 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
struct net *net = nf_ct_exp_net(expect);
struct hlist_node *n;
unsigned int h;
- int ret = 0;
+ int ret = 1;
if (!master_help->helper) {
ret = -ESHUTDOWN;
@@ -412,41 +412,23 @@ out:
return ret;
}
-int nf_ct_expect_related(struct nf_conntrack_expect *expect)
+int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
+ u32 pid, int report)
{
int ret;
spin_lock_bh(&nf_conntrack_lock);
ret = __nf_ct_expect_check(expect);
- if (ret < 0)
+ if (ret <= 0)
goto out;
+ ret = 0;
nf_ct_expect_insert(expect);
- atomic_inc(&expect->use);
- spin_unlock_bh(&nf_conntrack_lock);
- nf_ct_expect_event(IPEXP_NEW, expect);
- nf_ct_expect_put(expect);
- return ret;
-out:
spin_unlock_bh(&nf_conntrack_lock);
+ nf_ct_expect_event_report(IPEXP_NEW, expect, pid, report);
return ret;
-}
-EXPORT_SYMBOL_GPL(nf_ct_expect_related);
-
-int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
- u32 pid, int report)
-{
- int ret;
-
- spin_lock_bh(&nf_conntrack_lock);
- ret = __nf_ct_expect_check(expect);
- if (ret < 0)
- goto out;
- nf_ct_expect_insert(expect);
out:
spin_unlock_bh(&nf_conntrack_lock);
- if (ret == 0)
- nf_ct_expect_event_report(IPEXP_NEW, expect, pid, report);
return ret;
}
EXPORT_SYMBOL_GPL(nf_ct_expect_related_report);
diff --git a/net/phonet/Kconfig b/net/phonet/Kconfig
index 51a5669573f..6ec7d55b176 100644
--- a/net/phonet/Kconfig
+++ b/net/phonet/Kconfig
@@ -6,7 +6,7 @@ config PHONET
tristate "Phonet protocols family"
help
The Phone Network protocol (PhoNet) is a packet-oriented
- communication protocol developped by Nokia for use with its modems.
+ communication protocol developed by Nokia for use with its modems.
This is required for Maemo to use cellular data connectivity (if
supported). It can also be used to control Nokia phones
diff --git a/net/socket.c b/net/socket.c
index 91d0c0254ff..791d71a36a9 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -493,8 +493,7 @@ static struct socket *sock_alloc(void)
inode->i_uid = current_fsuid();
inode->i_gid = current_fsgid();
- get_cpu_var(sockets_in_use)++;
- put_cpu_var(sockets_in_use);
+ percpu_add(sockets_in_use, 1);
return sock;
}
@@ -536,8 +535,7 @@ void sock_release(struct socket *sock)
if (sock->fasync_list)
printk(KERN_ERR "sock_release: fasync list not empty!\n");
- get_cpu_var(sockets_in_use)--;
- put_cpu_var(sockets_in_use);
+ percpu_sub(sockets_in_use, 1);
if (!sock->file) {
iput(SOCK_INODE(sock));
return;
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index afd91c78ce8..443c161eb8b 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -47,7 +47,7 @@ config RPCSEC_GSS_SPKM3
select CRYPTO_CBC
help
Choose Y here to enable Secure RPC using the SPKM3 public key
- GSS-API mechansim (RFC 2025).
+ GSS-API mechanism (RFC 2025).
Secure RPC calls with SPKM3 require an auxiliary userspace
daemon which may be found in the Linux nfs-utils package
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 9f2f2412a2f..8847add6ca1 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -317,8 +317,7 @@ svc_pool_map_set_cpumask(struct task_struct *task, unsigned int pidx)
}
case SVC_POOL_PERNODE:
{
- node_to_cpumask_ptr(nodecpumask, node);
- set_cpus_allowed_ptr(task, nodecpumask);
+ set_cpus_allowed_ptr(task, cpumask_of_node(node));
break;
}
}
@@ -1009,6 +1008,8 @@ svc_process(struct svc_rqst *rqstp)
rqstp->rq_res.tail[0].iov_len = 0;
/* Will be turned off only in gss privacy case: */
rqstp->rq_splice_ok = 1;
+ /* Will be turned off only when NFSv4 Sessions are used */
+ rqstp->rq_usedeferral = 1;
/* Setup reply header */
rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
@@ -1079,7 +1080,6 @@ svc_process(struct svc_rqst *rqstp)
procp = versp->vs_proc + proc;
if (proc >= versp->vs_nproc || !procp->pc_func)
goto err_bad_proc;
- rqstp->rq_server = serv;
rqstp->rq_procinfo = procp;
/* Syntactic check complete */
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 2819ee093f3..c200d92e57e 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -14,6 +14,8 @@
#define RPCDBG_FACILITY RPCDBG_SVCXPRT
+#define SVC_MAX_WAKING 5
+
static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt);
static int svc_deferred_recv(struct svc_rqst *rqstp);
static struct cache_deferred_req *svc_defer(struct cache_req *req);
@@ -301,6 +303,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
struct svc_pool *pool;
struct svc_rqst *rqstp;
int cpu;
+ int thread_avail;
if (!(xprt->xpt_flags &
((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED))))
@@ -312,18 +315,14 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
spin_lock_bh(&pool->sp_lock);
- if (!list_empty(&pool->sp_threads) &&
- !list_empty(&pool->sp_sockets))
- printk(KERN_ERR
- "svc_xprt_enqueue: "
- "threads and transports both waiting??\n");
-
if (test_bit(XPT_DEAD, &xprt->xpt_flags)) {
/* Don't enqueue dead transports */
dprintk("svc: transport %p is dead, not enqueued\n", xprt);
goto out_unlock;
}
+ pool->sp_stats.packets++;
+
/* Mark transport as busy. It will remain in this state until
* the provider calls svc_xprt_received. We update XPT_BUSY
* atomically because it also guards against trying to enqueue
@@ -356,7 +355,15 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
}
process:
- if (!list_empty(&pool->sp_threads)) {
+ /* Work out whether threads are available */
+ thread_avail = !list_empty(&pool->sp_threads); /* threads are asleep */
+ if (pool->sp_nwaking >= SVC_MAX_WAKING) {
+ /* too many threads are runnable and trying to wake up */
+ thread_avail = 0;
+ pool->sp_stats.overloads_avoided++;
+ }
+
+ if (thread_avail) {
rqstp = list_entry(pool->sp_threads.next,
struct svc_rqst,
rq_list);
@@ -371,11 +378,15 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
svc_xprt_get(xprt);
rqstp->rq_reserved = serv->sv_max_mesg;
atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
+ rqstp->rq_waking = 1;
+ pool->sp_nwaking++;
+ pool->sp_stats.threads_woken++;
BUG_ON(xprt->xpt_pool != pool);
wake_up(&rqstp->rq_wait);
} else {
dprintk("svc: transport %p put into queue\n", xprt);
list_add_tail(&xprt->xpt_ready, &pool->sp_sockets);
+ pool->sp_stats.sockets_queued++;
BUG_ON(xprt->xpt_pool != pool);
}
@@ -588,6 +599,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
int pages;
struct xdr_buf *arg;
DECLARE_WAITQUEUE(wait, current);
+ long time_left;
dprintk("svc: server %p waiting for data (to = %ld)\n",
rqstp, timeout);
@@ -636,6 +648,11 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
return -EINTR;
spin_lock_bh(&pool->sp_lock);
+ if (rqstp->rq_waking) {
+ rqstp->rq_waking = 0;
+ pool->sp_nwaking--;
+ BUG_ON(pool->sp_nwaking < 0);
+ }
xprt = svc_xprt_dequeue(pool);
if (xprt) {
rqstp->rq_xprt = xprt;
@@ -668,12 +685,14 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
add_wait_queue(&rqstp->rq_wait, &wait);
spin_unlock_bh(&pool->sp_lock);
- schedule_timeout(timeout);
+ time_left = schedule_timeout(timeout);
try_to_freeze();
spin_lock_bh(&pool->sp_lock);
remove_wait_queue(&rqstp->rq_wait, &wait);
+ if (!time_left)
+ pool->sp_stats.threads_timedout++;
xprt = rqstp->rq_xprt;
if (!xprt) {
@@ -958,7 +977,7 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req)
struct svc_rqst *rqstp = container_of(req, struct svc_rqst, rq_chandle);
struct svc_deferred_req *dr;
- if (rqstp->rq_arg.page_len)
+ if (rqstp->rq_arg.page_len || !rqstp->rq_usedeferral)
return NULL; /* if more than a page, give up FIXME */
if (rqstp->rq_deferred) {
dr = rqstp->rq_deferred;
@@ -1112,3 +1131,93 @@ int svc_xprt_names(struct svc_serv *serv, char *buf, int buflen)
return totlen;
}
EXPORT_SYMBOL_GPL(svc_xprt_names);
+
+
+/*----------------------------------------------------------------------------*/
+
+static void *svc_pool_stats_start(struct seq_file *m, loff_t *pos)
+{
+ unsigned int pidx = (unsigned int)*pos;
+ struct svc_serv *serv = m->private;
+
+ dprintk("svc_pool_stats_start, *pidx=%u\n", pidx);
+
+ lock_kernel();
+ /* bump up the pseudo refcount while traversing */
+ svc_get(serv);
+ unlock_kernel();
+
+ if (!pidx)
+ return SEQ_START_TOKEN;
+ return (pidx > serv->sv_nrpools ? NULL : &serv->sv_pools[pidx-1]);
+}
+
+static void *svc_pool_stats_next(struct seq_file *m, void *p, loff_t *pos)
+{
+ struct svc_pool *pool = p;
+ struct svc_serv *serv = m->private;
+
+ dprintk("svc_pool_stats_next, *pos=%llu\n", *pos);
+
+ if (p == SEQ_START_TOKEN) {
+ pool = &serv->sv_pools[0];
+ } else {
+ unsigned int pidx = (pool - &serv->sv_pools[0]);
+ if (pidx < serv->sv_nrpools-1)
+ pool = &serv->sv_pools[pidx+1];
+ else
+ pool = NULL;
+ }
+ ++*pos;
+ return pool;
+}
+
+static void svc_pool_stats_stop(struct seq_file *m, void *p)
+{
+ struct svc_serv *serv = m->private;
+
+ lock_kernel();
+ /* this function really, really should have been called svc_put() */
+ svc_destroy(serv);
+ unlock_kernel();
+}
+
+static int svc_pool_stats_show(struct seq_file *m, void *p)
+{
+ struct svc_pool *pool = p;
+
+ if (p == SEQ_START_TOKEN) {
+ seq_puts(m, "# pool packets-arrived sockets-enqueued threads-woken overloads-avoided threads-timedout\n");
+ return 0;
+ }
+
+ seq_printf(m, "%u %lu %lu %lu %lu %lu\n",
+ pool->sp_id,
+ pool->sp_stats.packets,
+ pool->sp_stats.sockets_queued,
+ pool->sp_stats.threads_woken,
+ pool->sp_stats.overloads_avoided,
+ pool->sp_stats.threads_timedout);
+
+ return 0;
+}
+
+static const struct seq_operations svc_pool_stats_seq_ops = {
+ .start = svc_pool_stats_start,
+ .next = svc_pool_stats_next,
+ .stop = svc_pool_stats_stop,
+ .show = svc_pool_stats_show,
+};
+
+int svc_pool_stats_open(struct svc_serv *serv, struct file *file)
+{
+ int err;
+
+ err = seq_open(file, &svc_pool_stats_seq_ops);
+ if (!err)
+ ((struct seq_file *) file->private_data)->private = serv;
+ return err;
+}
+EXPORT_SYMBOL(svc_pool_stats_open);
+
+/*----------------------------------------------------------------------------*/
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 9d504234af4..af3198814c1 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -345,7 +345,6 @@ static void svc_sock_setbufsize(struct socket *sock, unsigned int snd,
lock_sock(sock->sk);
sock->sk->sk_sndbuf = snd * 2;
sock->sk->sk_rcvbuf = rcv * 2;
- sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK|SOCK_RCVBUF_LOCK;
release_sock(sock->sk);
#endif
}
@@ -797,23 +796,6 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
test_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags),
test_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags));
- if (test_and_clear_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags))
- /* sndbuf needs to have room for one request
- * per thread, otherwise we can stall even when the
- * network isn't a bottleneck.
- *
- * We count all threads rather than threads in a
- * particular pool, which provides an upper bound
- * on the number of threads which will access the socket.
- *
- * rcvbuf just needs to be able to hold a few requests.
- * Normally they will be removed from the queue
- * as soon a a complete request arrives.
- */
- svc_sock_setbufsize(svsk->sk_sock,
- (serv->sv_nrthreads+3) * serv->sv_max_mesg,
- 3 * serv->sv_max_mesg);
-
clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
/* Receive data. If we haven't got the record length yet, get
@@ -1061,15 +1043,6 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;
- /* initialise setting must have enough space to
- * receive and respond to one request.
- * svc_tcp_recvfrom will re-adjust if necessary
- */
- svc_sock_setbufsize(svsk->sk_sock,
- 3 * svsk->sk_xprt.xpt_server->sv_max_mesg,
- 3 * svsk->sk_xprt.xpt_server->sv_max_mesg);
-
- set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);
set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
if (sk->sk_state != TCP_ESTABLISHED)
set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
@@ -1139,8 +1112,14 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
/* Initialize the socket */
if (sock->type == SOCK_DGRAM)
svc_udp_init(svsk, serv);
- else
+ else {
+ /* initialise setting must have enough space to
+ * receive and respond to one request.
+ */
+ svc_sock_setbufsize(svsk->sk_sock, 4 * serv->sv_max_mesg,
+ 4 * serv->sv_max_mesg);
svc_tcp_init(svsk, serv);
+ }
dprintk("svc: svc_setup_socket created %p (inet %p)\n",
svsk, svsk->sk_sk);
diff --git a/net/wimax/Kconfig b/net/wimax/Kconfig
index 18495cdcd10..1b46747a5f5 100644
--- a/net/wimax/Kconfig
+++ b/net/wimax/Kconfig
@@ -8,7 +8,7 @@
#
# As well, enablement of the RFKILL code means we need the INPUT layer
# support to inject events coming from hw rfkill switches. That
-# dependency could be killed if input.h provided appropiate means to
+# dependency could be killed if input.h provided appropriate means to
# work when input is disabled.
comment "WiMAX Wireless Broadband support requires CONFIG_INPUT enabled"
diff --git a/samples/tracepoints/tp-samples-trace.h b/samples/tracepoints/tp-samples-trace.h
index 01724e04c55..dffdc49878a 100644
--- a/samples/tracepoints/tp-samples-trace.h
+++ b/samples/tracepoints/tp-samples-trace.h
@@ -5,9 +5,9 @@
#include <linux/tracepoint.h>
DECLARE_TRACE(subsys_event,
- TPPROTO(struct inode *inode, struct file *file),
- TPARGS(inode, file));
+ TP_PROTO(struct inode *inode, struct file *file),
+ TP_ARGS(inode, file));
DECLARE_TRACE(subsys_eventb,
- TPPROTO(void),
- TPARGS());
+ TP_PROTO(void),
+ TP_ARGS());
#endif
diff --git a/samples/tracepoints/tracepoint-sample.c b/samples/tracepoints/tracepoint-sample.c
index 68d5dc0310e..9cf80a11e8b 100644
--- a/samples/tracepoints/tracepoint-sample.c
+++ b/samples/tracepoints/tracepoint-sample.c
@@ -1,6 +1,6 @@
/* tracepoint-sample.c
*
- * Executes a tracepoint when /proc/tracepoint-example is opened.
+ * Executes a tracepoint when /proc/tracepoint-sample is opened.
*
* (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
*
@@ -16,7 +16,7 @@
DEFINE_TRACE(subsys_event);
DEFINE_TRACE(subsys_eventb);
-struct proc_dir_entry *pentry_example;
+struct proc_dir_entry *pentry_sample;
static int my_open(struct inode *inode, struct file *file)
{
@@ -32,25 +32,25 @@ static struct file_operations mark_ops = {
.open = my_open,
};
-static int __init example_init(void)
+static int __init sample_init(void)
{
- printk(KERN_ALERT "example init\n");
- pentry_example = proc_create("tracepoint-example", 0444, NULL,
+ printk(KERN_ALERT "sample init\n");
+ pentry_sample = proc_create("tracepoint-sample", 0444, NULL,
&mark_ops);
- if (!pentry_example)
+ if (!pentry_sample)
return -EPERM;
return 0;
}
-static void __exit example_exit(void)
+static void __exit sample_exit(void)
{
- printk(KERN_ALERT "example exit\n");
- remove_proc_entry("tracepoint-example", NULL);
+ printk(KERN_ALERT "sample exit\n");
+ remove_proc_entry("tracepoint-sample", NULL);
}
-module_init(example_init)
-module_exit(example_exit)
+module_init(sample_init)
+module_exit(sample_exit)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mathieu Desnoyers");
-MODULE_DESCRIPTION("Tracepoint example");
+MODULE_DESCRIPTION("Tracepoint sample");
diff --git a/scripts/.gitignore b/scripts/.gitignore
index 09e2406f3b7..b939fbd0119 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -1,7 +1,6 @@
#
# Generated files
#
-ihex2fw
conmakehash
kallsyms
pnmtologo
diff --git a/scripts/Makefile b/scripts/Makefile
index 035182e16af..aafdf064fee 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -2,12 +2,11 @@
# scripts contains sources for various helper programs used throughout
# the kernel for the build process.
# ---------------------------------------------------------------------------
-# ihex2fw: Parser/loader for IHEX formatted data
# kallsyms: Find all symbols in vmlinux
# pnmttologo: Convert pnm files to logo files
+# conmakehash: Create chartable
# conmakehash: Create arrays for initializing the kernel console tables
-hostprogs-y := ihex2fw
hostprogs-$(CONFIG_KALLSYMS) += kallsyms
hostprogs-$(CONFIG_LOGO) += pnmtologo
hostprogs-$(CONFIG_VT) += conmakehash
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index c7de8b39fcf..39a9642927d 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -112,13 +112,13 @@ endif
# ---------------------------------------------------------------------------
# Default is built-in, unless we know otherwise
-modkern_cflags := $(CFLAGS_KERNEL)
+modkern_cflags = $(if $(part-of-module), $(CFLAGS_MODULE), $(CFLAGS_KERNEL))
quiet_modtag := $(empty) $(empty)
-$(real-objs-m) : modkern_cflags := $(CFLAGS_MODULE)
-$(real-objs-m:.o=.i) : modkern_cflags := $(CFLAGS_MODULE)
-$(real-objs-m:.o=.s) : modkern_cflags := $(CFLAGS_MODULE)
-$(real-objs-m:.o=.lst): modkern_cflags := $(CFLAGS_MODULE)
+$(real-objs-m) : part-of-module := y
+$(real-objs-m:.o=.i) : part-of-module := y
+$(real-objs-m:.o=.s) : part-of-module := y
+$(real-objs-m:.o=.lst): part-of-module := y
$(real-objs-m) : quiet_modtag := [M]
$(real-objs-m:.o=.i) : quiet_modtag := [M]
@@ -205,7 +205,8 @@ endif
ifdef CONFIG_FTRACE_MCOUNT_RECORD
cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
"$(if $(CONFIG_64BIT),64,32)" \
- "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" "$(@)";
+ "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \
+ "$(if $(part-of-module),1,0)" "$(@)";
endif
define rule_cc_o_c
diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
index 612dc13ddd8..095cfc8b9db 100644
--- a/scripts/Makefile.headersinst
+++ b/scripts/Makefile.headersinst
@@ -14,6 +14,8 @@ _dst := $(if $(dst),$(dst),$(obj))
kbuild-file := $(srctree)/$(obj)/Kbuild
include $(kbuild-file)
+_dst := $(if $(destination-y),$(destination-y),$(_dst))
+
include scripts/Kbuild.include
install := $(INSTALL_HDR_PATH)/$(_dst)
diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
index 3eea8f15131..76af5f9623e 100644
--- a/scripts/gen_initramfs_list.sh
+++ b/scripts/gen_initramfs_list.sh
@@ -97,7 +97,7 @@ print_mtime() {
}
list_parse() {
- echo "$1 \\"
+ [ ! -L "$1" ] && echo "$1 \\" || :
}
# for each file print a line in following format
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
new file mode 100755
index 00000000000..60dc0c48c92
--- /dev/null
+++ b/scripts/get_maintainer.pl
@@ -0,0 +1,515 @@
+#!/usr/bin/perl -w
+# (c) 2007, Joe Perches <joe@perches.com>
+# created from checkpatch.pl
+#
+# Print selected MAINTAINERS information for
+# the files modified in a patch or for a file
+#
+# usage: perl scripts/get_maintainers.pl [OPTIONS] <patch>
+# perl scripts/get_maintainers.pl [OPTIONS] -f <file>
+#
+# Licensed under the terms of the GNU GPL License version 2
+
+use strict;
+
+my $P = $0;
+my $V = '0.15';
+
+use Getopt::Long qw(:config no_auto_abbrev);
+
+my $lk_path = "./";
+my $email = 1;
+my $email_usename = 1;
+my $email_maintainer = 1;
+my $email_list = 1;
+my $email_subscriber_list = 0;
+my $email_git = 1;
+my $email_git_penguin_chiefs = 0;
+my $email_git_min_signatures = 1;
+my $email_git_max_maintainers = 5;
+my $email_git_since = "1-year-ago";
+my $output_multiline = 1;
+my $output_separator = ", ";
+my $scm = 0;
+my $web = 0;
+my $subsystem = 0;
+my $status = 0;
+my $from_filename = 0;
+my $version = 0;
+my $help = 0;
+
+my $exit = 0;
+
+my @penguin_chief = ();
+push(@penguin_chief,"Linus Torvalds:torvalds\@linux-foundation.org");
+#Andrew wants in on most everything - 2009/01/14
+#push(@penguin_chief,"Andrew Morton:akpm\@linux-foundation.org");
+
+my @penguin_chief_names = ();
+foreach my $chief (@penguin_chief) {
+ if ($chief =~ m/^(.*):(.*)/) {
+ my $chief_name = $1;
+ my $chief_addr = $2;
+ push(@penguin_chief_names, $chief_name);
+ }
+}
+my $penguin_chiefs = "\(" . join("|",@penguin_chief_names) . "\)";
+
+if (!GetOptions(
+ 'email!' => \$email,
+ 'git!' => \$email_git,
+ 'git-chief-penguins!' => \$email_git_penguin_chiefs,
+ 'git-min-signatures=i' => \$email_git_min_signatures,
+ 'git-max-maintainers=i' => \$email_git_max_maintainers,
+ 'git-since=s' => \$email_git_since,
+ 'm!' => \$email_maintainer,
+ 'n!' => \$email_usename,
+ 'l!' => \$email_list,
+ 's!' => \$email_subscriber_list,
+ 'multiline!' => \$output_multiline,
+ 'separator=s' => \$output_separator,
+ 'subsystem!' => \$subsystem,
+ 'status!' => \$status,
+ 'scm!' => \$scm,
+ 'web!' => \$web,
+ 'f|file' => \$from_filename,
+ 'v|version' => \$version,
+ 'h|help' => \$help,
+ )) {
+ usage();
+ die "$P: invalid argument\n";
+}
+
+if ($help != 0) {
+ usage();
+ exit 0;
+}
+
+if ($version != 0) {
+ print("${P} ${V}\n");
+ exit 0;
+}
+
+if ($#ARGV < 0) {
+ usage();
+ die "$P: argument missing: patchfile or -f file please\n";
+}
+
+my $selections = $email + $scm + $status + $subsystem + $web;
+if ($selections == 0) {
+ usage();
+ die "$P: Missing required option: email, scm, status, subsystem or web\n";
+}
+
+if ($email && ($email_maintainer + $email_list + $email_subscriber_list
+ + $email_git + $email_git_penguin_chiefs) == 0) {
+ usage();
+ die "$P: Please select at least 1 email option\n";
+}
+
+if (!top_of_kernel_tree($lk_path)) {
+ die "$P: The current directory does not appear to be "
+ . "a linux kernel source tree.\n";
+}
+
+## Read MAINTAINERS for type/value pairs
+
+my @typevalue = ();
+open(MAINT, "<${lk_path}MAINTAINERS") || die "$P: Can't open MAINTAINERS\n";
+while (<MAINT>) {
+ my $line = $_;
+
+ if ($line =~ m/^(\C):\s*(.*)/) {
+ my $type = $1;
+ my $value = $2;
+
+ ##Filename pattern matching
+ if ($type eq "F" || $type eq "X") {
+ $value =~ s@\.@\\\.@g; ##Convert . to \.
+ $value =~ s/\*/\.\*/g; ##Convert * to .*
+ $value =~ s/\?/\./g; ##Convert ? to .
+ }
+ push(@typevalue, "$type:$value");
+ } elsif (!/^(\s)*$/) {
+ $line =~ s/\n$//g;
+ push(@typevalue, $line);
+ }
+}
+close(MAINT);
+
+## use the filenames on the command line or find the filenames in the patchfiles
+
+my @files = ();
+
+foreach my $file (@ARGV) {
+ next if ((-d $file));
+ if (!(-f $file)) {
+ die "$P: file '${file}' not found\n";
+ }
+ if ($from_filename) {
+ push(@files, $file);
+ } else {
+ my $file_cnt = @files;
+ open(PATCH, "<$file") or die "$P: Can't open ${file}\n";
+ while (<PATCH>) {
+ if (m/^\+\+\+\s+(\S+)/) {
+ my $filename = $1;
+ $filename =~ s@^[^/]*/@@;
+ $filename =~ s@\n@@;
+ push(@files, $filename);
+ }
+ }
+ close(PATCH);
+ if ($file_cnt == @files) {
+ die "$P: file '${file}' doesn't appear to be a patch. "
+ . "Add -f to options?\n";
+ }
+ @files = sort_and_uniq(@files);
+ }
+}
+
+my @email_to = ();
+my @scm = ();
+my @web = ();
+my @subsystem = ();
+my @status = ();
+
+# Find responsible parties
+
+foreach my $file (@files) {
+
+#Do not match excluded file patterns
+
+ my $exclude = 0;
+ foreach my $line (@typevalue) {
+ if ($line =~ m/^(\C):(.*)/) {
+ my $type = $1;
+ my $value = $2;
+ if ($type eq 'X') {
+ if (file_match_pattern($file, $value)) {
+ $exclude = 1;
+ }
+ }
+ }
+ }
+
+ if (!$exclude) {
+ my $tvi = 0;
+ foreach my $line (@typevalue) {
+ if ($line =~ m/^(\C):(.*)/) {
+ my $type = $1;
+ my $value = $2;
+ if ($type eq 'F') {
+ if (file_match_pattern($file, $value)) {
+ add_categories($tvi);
+ }
+ }
+ }
+ $tvi++;
+ }
+ }
+
+ if ($email && $email_git) {
+ recent_git_signoffs($file);
+ }
+
+}
+
+if ($email_git_penguin_chiefs) {
+ foreach my $chief (@penguin_chief) {
+ if ($chief =~ m/^(.*):(.*)/) {
+ my $chief_name = $1;
+ my $chief_addr = $2;
+ if ($email_usename) {
+ push(@email_to, format_email($chief_name, $chief_addr));
+ } else {
+ push(@email_to, $chief_addr);
+ }
+ }
+ }
+}
+
+if ($email) {
+ my $address_cnt = @email_to;
+ if ($address_cnt == 0 && $email_list) {
+ push(@email_to, "linux-kernel\@vger.kernel.org");
+ }
+
+#Don't sort email address list, but do remove duplicates
+ @email_to = uniq(@email_to);
+ output(@email_to);
+}
+
+if ($scm) {
+ @scm = sort_and_uniq(@scm);
+ output(@scm);
+}
+
+if ($status) {
+ @status = sort_and_uniq(@status);
+ output(@status);
+}
+
+if ($subsystem) {
+ @subsystem = sort_and_uniq(@subsystem);
+ output(@subsystem);
+}
+
+if ($web) {
+ @web = sort_and_uniq(@web);
+ output(@web);
+}
+
+exit($exit);
+
+sub file_match_pattern {
+ my ($file, $pattern) = @_;
+ if (substr($pattern, -1) eq "/") {
+ if ($file =~ m@^$pattern@) {
+ return 1;
+ }
+ } else {
+ if ($file =~ m@^$pattern@) {
+ my $s1 = ($file =~ tr@/@@);
+ my $s2 = ($pattern =~ tr@/@@);
+ if ($s1 == $s2) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+sub usage {
+ print <<EOT;
+usage: $P [options] patchfile
+ $P [options] -f file
+version: $V
+
+MAINTAINER field selection options:
+ --email => print email address(es) if any
+ --git => include recent git \*-by: signers
+ --git-chief-penguins => include ${penguin_chiefs}
+ --git-min-signatures => number of signatures required (default: 1)
+ --git-max-maintainers => maximum maintainers to add (default: 5)
+ --git-since => git history to use (default: 1-year-ago)
+ --m => include maintainer(s) if any
+ --n => include name 'Full Name <addr\@domain.tld>'
+ --l => include list(s) if any
+ --s => include subscriber only list(s) if any
+ --scm => print SCM tree(s) if any
+ --status => print status if any
+ --subsystem => print subsystem name if any
+ --web => print website(s) if any
+
+Output type options:
+ --separator [, ] => separator for multiple entries on 1 line
+ --multiline => print 1 entry per line
+
+Default options:
+ [--email --git --m --l --multiline]
+
+Other options:
+ --version -> show version
+ --help => show this help information
+
+EOT
+}
+
+sub top_of_kernel_tree {
+ my ($lk_path) = @_;
+
+ if ($lk_path ne "" && substr($lk_path,length($lk_path)-1,1) ne "/") {
+ $lk_path .= "/";
+ }
+ if ( (-f "${lk_path}COPYING")
+ && (-f "${lk_path}CREDITS")
+ && (-f "${lk_path}Kbuild")
+ && (-f "${lk_path}MAINTAINERS")
+ && (-f "${lk_path}Makefile")
+ && (-f "${lk_path}README")
+ && (-d "${lk_path}Documentation")
+ && (-d "${lk_path}arch")
+ && (-d "${lk_path}include")
+ && (-d "${lk_path}drivers")
+ && (-d "${lk_path}fs")
+ && (-d "${lk_path}init")
+ && (-d "${lk_path}ipc")
+ && (-d "${lk_path}kernel")
+ && (-d "${lk_path}lib")
+ && (-d "${lk_path}scripts")) {
+ return 1;
+ }
+ return 0;
+}
+
+sub format_email {
+ my ($name, $email) = @_;
+
+ $name =~ s/^\s+|\s+$//g;
+ $email =~ s/^\s+|\s+$//g;
+
+ my $formatted_email = "";
+
+ if ($name =~ /[^a-z0-9 \.\-]/i) { ##has "must quote" chars
+ $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
+ $formatted_email = "\"${name}\"\ \<${email}\>";
+ } else {
+ $formatted_email = "${name} \<${email}\>";
+ }
+ return $formatted_email;
+}
+
+sub add_categories {
+ my ($index) = @_;
+
+ $index = $index - 1;
+ while ($index >= 0) {
+ my $tv = $typevalue[$index];
+ if ($tv =~ m/^(\C):(.*)/) {
+ my $ptype = $1;
+ my $pvalue = $2;
+ if ($ptype eq "L") {
+ my $subscr = $pvalue;
+ if ($subscr =~ m/\s*\(subscribers-only\)/) {
+ if ($email_subscriber_list) {
+ $subscr =~ s/\s*\(subscribers-only\)//g;
+ push(@email_to, $subscr);
+ }
+ } else {
+ if ($email_list) {
+ push(@email_to, $pvalue);
+ }
+ }
+ } elsif ($ptype eq "M") {
+ if ($email_maintainer) {
+ if ($index >= 0) {
+ my $tv = $typevalue[$index - 1];
+ if ($tv =~ m/^(\C):(.*)/) {
+ if ($1 eq "P" && $email_usename) {
+ push(@email_to, format_email($2, $pvalue));
+ } else {
+ push(@email_to, $pvalue);
+ }
+ }
+ } else {
+ push(@email_to, $pvalue);
+ }
+ }
+ } elsif ($ptype eq "T") {
+ push(@scm, $pvalue);
+ } elsif ($ptype eq "W") {
+ push(@web, $pvalue);
+ } elsif ($ptype eq "S") {
+ push(@status, $pvalue);
+ }
+
+ $index--;
+ } else {
+ push(@subsystem,$tv);
+ $index = -1;
+ }
+ }
+}
+
+sub which {
+ my ($bin) = @_;
+
+ foreach my $path (split /:/, $ENV{PATH}) {
+ if (-e "$path/$bin") {
+ return "$path/$bin";
+ }
+ }
+
+ return "";
+}
+
+sub recent_git_signoffs {
+ my ($file) = @_;
+
+ my $sign_offs = "";
+ my $cmd = "";
+ my $output = "";
+ my $count = 0;
+ my @lines = ();
+
+ if (which("git") eq "") {
+ die("$P: git not found. Add --nogit to options?\n");
+ }
+
+ $cmd = "git log --since=${email_git_since} -- ${file}";
+ $cmd .= " | grep -Pi \"^[-_ a-z]+by:.*\\\@\"";
+ if (!$email_git_penguin_chiefs) {
+ $cmd .= " | grep -Pv \"${penguin_chiefs}\"";
+ }
+ $cmd .= " | cut -f2- -d\":\"";
+ $cmd .= " | sed -e \"s/^\\s+//g\"";
+ $cmd .= " | sort | uniq -c | sort -rn";
+
+ $output = `${cmd}`;
+ $output =~ s/^\s*//gm;
+
+ @lines = split("\n", $output);
+ foreach my $line (@lines) {
+ if ($line =~ m/([0-9]+)\s+(.*)/) {
+ my $sign_offs = $1;
+ $line = $2;
+ $count++;
+ if ($sign_offs < $email_git_min_signatures ||
+ $count > $email_git_max_maintainers) {
+ last;
+ }
+ } else {
+ die("$P: Unexpected git output: ${line}\n");
+ }
+ if ($line =~ m/(.+)<(.+)>/) {
+ my $git_name = $1;
+ my $git_addr = $2;
+ $git_name =~ tr/^\"//;
+ $git_name =~ tr/^\\s*//;
+ $git_name =~ tr/\"$//;
+ $git_name =~ tr/\\s*$//;
+ if ($email_usename) {
+ push(@email_to, format_email($git_name, $git_addr));
+ } else {
+ push(@email_to, $git_addr);
+ }
+ } elsif ($line =~ m/<(.+)>/) {
+ my $git_addr = $1;
+ push(@email_to, $git_addr);
+ } else {
+ push(@email_to, $line);
+ }
+ }
+ return $output;
+}
+
+sub uniq {
+ my @parms = @_;
+
+ my %saw;
+ @parms = grep(!$saw{$_}++, @parms);
+ return @parms;
+}
+
+sub sort_and_uniq {
+ my @parms = @_;
+
+ my %saw;
+ @parms = sort @parms;
+ @parms = grep(!$saw{$_}++, @parms);
+ return @parms;
+}
+
+sub output {
+ my @parms = @_;
+
+ if ($output_multiline) {
+ foreach my $line (@parms) {
+ print("${line}\n");
+ }
+ } else {
+ print(join($output_separator, @parms));
+ print("\n");
+ }
+}
diff --git a/scripts/headerdep.pl b/scripts/headerdep.pl
index 97399da89ef..b7f6c560e24 100755
--- a/scripts/headerdep.pl
+++ b/scripts/headerdep.pl
@@ -19,7 +19,7 @@ my $opt_graph;
version => \&version,
all => \$opt_all,
- I => \@opt_include,
+ "I=s" => \@opt_include,
graph => \$opt_graph,
);
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index ad2434b2697..6654cbed965 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -500,6 +500,51 @@ static void optimize_token_table(void)
optimize_result();
}
+/* guess for "linker script provide" symbol */
+static int may_be_linker_script_provide_symbol(const struct sym_entry *se)
+{
+ const char *symbol = (char *)se->sym + 1;
+ int len = se->len - 1;
+
+ if (len < 8)
+ return 0;
+
+ if (symbol[0] != '_' || symbol[1] != '_')
+ return 0;
+
+ /* __start_XXXXX */
+ if (!memcmp(symbol + 2, "start_", 6))
+ return 1;
+
+ /* __stop_XXXXX */
+ if (!memcmp(symbol + 2, "stop_", 5))
+ return 1;
+
+ /* __end_XXXXX */
+ if (!memcmp(symbol + 2, "end_", 4))
+ return 1;
+
+ /* __XXXXX_start */
+ if (!memcmp(symbol + len - 6, "_start", 6))
+ return 1;
+
+ /* __XXXXX_end */
+ if (!memcmp(symbol + len - 4, "_end", 4))
+ return 1;
+
+ return 0;
+}
+
+static int prefix_underscores_count(const char *str)
+{
+ const char *tail = str;
+
+ while (*tail != '_')
+ tail++;
+
+ return tail - str;
+}
+
static int compare_symbols(const void *a, const void *b)
{
const struct sym_entry *sa;
@@ -521,6 +566,18 @@ static int compare_symbols(const void *a, const void *b)
if (wa != wb)
return wa - wb;
+ /* sort by "linker script provide" type */
+ wa = may_be_linker_script_provide_symbol(sa);
+ wb = may_be_linker_script_provide_symbol(sb);
+ if (wa != wb)
+ return wa - wb;
+
+ /* sort by the number of prefix underscores */
+ wa = prefix_underscores_count((const char *)sa->sym + 1);
+ wb = prefix_underscores_count((const char *)sb->sym + 1);
+ if (wa != wb)
+ return wa - wb;
+
/* sort by initial order, so that other symbols are left undisturbed */
return sa->start_pos - sb->start_pos;
}
diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c
index 6eb72a7f256..8d9ce22b0fc 100644
--- a/scripts/kconfig/kxgettext.c
+++ b/scripts/kconfig/kxgettext.c
@@ -43,6 +43,10 @@ static char *escape(const char* text, char *bf, int len)
++text;
goto next;
}
+ else if (*text == '\\') {
+ *bfp++ = '\\';
+ len--;
+ }
*bfp++ = *text++;
next:
--len;
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 7e62303133d..df6e6286a06 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1607,12 +1607,12 @@ static void read_symbols(char *modname)
parse_elf_finish(&info);
- /* Our trick to get versioning for struct_module - it's
+ /* Our trick to get versioning for module struct etc. - it's
* never passed as an argument to an exported function, so
* the automatic versioning doesn't pick it up, but it's really
* important anyhow */
if (modversions)
- mod->unres = alloc_symbol("struct_module", 0, mod->unres);
+ mod->unres = alloc_symbol("module_layout", 0, mod->unres);
}
#define SZ 500
@@ -1913,7 +1913,7 @@ static void read_dump(const char *fname, unsigned int kernel)
if (!mod) {
if (is_vmlinux(modname))
have_vmlinux = 1;
- mod = new_module(NOFAIL(strdup(modname)));
+ mod = new_module(modname);
mod->skip = 1;
}
s = sym_add_exported(symname, mod, export_no(export));
@@ -1997,7 +1997,7 @@ static void read_markers(const char *fname)
mod = find_module(modname);
if (!mod) {
- mod = new_module(NOFAIL(strdup(modname)));
+ mod = new_module(modname);
mod->skip = 1;
}
if (is_vmlinux(modname)) {
diff --git a/scripts/package/buildtar b/scripts/package/buildtar
index 28574ae5517..b1fd48db164 100644
--- a/scripts/package/buildtar
+++ b/scripts/package/buildtar
@@ -75,6 +75,10 @@ case "${ARCH}" in
alpha)
[ -f "${objtree}/arch/alpha/boot/vmlinux.gz" ] && cp -v -- "${objtree}/arch/alpha/boot/vmlinux.gz" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}"
;;
+ parisc*)
+ [ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
+ [ -f "${objtree}/lifimage" ] && cp -v -- "${objtree}/lifimage" "${tmpdir}/boot/lifimage-${KERNELRELEASE}"
+ ;;
vax)
[ -f "${objtree}/vmlinux.SYS" ] && cp -v -- "${objtree}/vmlinux.SYS" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.SYS"
[ -f "${objtree}/vmlinux.dsk" ] && cp -v -- "${objtree}/vmlinux.dsk" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.dsk"
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index fe831412bea..409596eca12 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -100,14 +100,19 @@ $P =~ s@.*/@@g;
my $V = '0.1';
-if ($#ARGV < 6) {
- print "usage: $P arch objdump objcopy cc ld nm rm mv inputfile\n";
+if ($#ARGV < 7) {
+ print "usage: $P arch bits objdump objcopy cc ld nm rm mv is_module inputfile\n";
print "version: $V\n";
exit(1);
}
my ($arch, $bits, $objdump, $objcopy, $cc,
- $ld, $nm, $rm, $mv, $inputfile) = @ARGV;
+ $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV;
+
+# This file refers to mcount and shouldn't be ftraced, so lets' ignore it
+if ($inputfile eq "kernel/trace/ftrace.o") {
+ exit(0);
+}
# Acceptable sections to record.
my %text_sections = (
@@ -201,6 +206,13 @@ if ($arch eq "x86_64") {
$alignment = 2;
$section_type = '%progbits';
+} elsif ($arch eq "ia64") {
+ $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
+ $type = "data8";
+
+ if ($is_module eq "0") {
+ $cc .= " -mconstant-gp";
+ }
} else {
die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
}
@@ -263,7 +275,6 @@ if (!$found_version) {
"\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)
@@ -331,13 +342,16 @@ sub update_funcs
#
# Step 2: find the sections and mcount call sites
#
-open(IN, "$objdump -dr $inputfile|") || die "error running $objdump";
+open(IN, "$objdump -hdr $inputfile|") || die "error running $objdump";
my $text;
+my $read_headers = 1;
+
while (<IN>) {
# is it a section?
if (/$section_regex/) {
+ $read_headers = 0;
# Only record text sections that we know are safe
if (defined($text_sections{$1})) {
@@ -371,6 +385,19 @@ while (<IN>) {
$ref_func = $text;
}
}
+ } elsif ($read_headers && /$mcount_section/) {
+ #
+ # Somehow the make process can execute this script on an
+ # object twice. If it does, we would duplicate the mcount
+ # section and it will cause the function tracer self test
+ # to fail. Check if the mcount section exists, and if it does,
+ # warn and exit.
+ #
+ print STDERR "ERROR: $mcount_section already in $inputfile\n" .
+ "\tThis may be an indication that your build is corrupted.\n" .
+ "\tDelete $inputfile and try again. If the same object file\n" .
+ "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
+ exit(-1);
}
# is this a call site to mcount? If so, record it to print later
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index f1c4b35bc32..47e75b69a2e 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -21,7 +21,7 @@ if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
# Is this git on svn?
if git config --get svn-remote.svn.url >/dev/null; then
- printf -- '-svn%s' "`git-svn find-rev $head`"
+ printf -- '-svn%s' "`git svn find-rev $head`"
fi
# Are there uncommitted changes?
diff --git a/scripts/trace/power.pl b/scripts/tracing/power.pl
index 4f729b3501e..4f729b3501e 100644
--- a/scripts/trace/power.pl
+++ b/scripts/tracing/power.pl
diff --git a/security/commoncap.c b/security/commoncap.c
index 7cd61a5f520..beac0258c2a 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -916,7 +916,6 @@ changed:
return commit_creds(new);
no_change:
- error = 0;
error:
abort_creds(new);
return error;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 22a31582bfa..03fe63ed55b 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -311,7 +311,8 @@ static int construct_alloc_key(struct key_type *type,
set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
- down_write(&dest_keyring->sem);
+ if (dest_keyring)
+ down_write(&dest_keyring->sem);
/* attach the key to the destination keyring under lock, but we do need
* to do another check just in case someone beat us to it whilst we
@@ -322,10 +323,12 @@ static int construct_alloc_key(struct key_type *type,
if (!IS_ERR(key_ref))
goto key_already_present;
- __key_link(dest_keyring, key);
+ if (dest_keyring)
+ __key_link(dest_keyring, key);
mutex_unlock(&key_construction_mutex);
- up_write(&dest_keyring->sem);
+ if (dest_keyring)
+ up_write(&dest_keyring->sem);
mutex_unlock(&user->cons_lock);
*_key = key;
kleave(" = 0 [%d]", key_serial(key));
diff --git a/security/security.c b/security/security.c
index 206e53844d2..5284255c5cd 100644
--- a/security/security.c
+++ b/security/security.c
@@ -445,6 +445,7 @@ int security_inode_create(struct inode *dir, struct dentry *dentry, int mode)
return 0;
return security_ops->inode_create(dir, dentry, mode);
}
+EXPORT_SYMBOL_GPL(security_inode_create);
int security_inode_link(struct dentry *old_dentry, struct inode *dir,
struct dentry *new_dentry)
@@ -475,6 +476,7 @@ int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode)
return 0;
return security_ops->inode_mkdir(dir, dentry, mode);
}
+EXPORT_SYMBOL_GPL(security_inode_mkdir);
int security_inode_rmdir(struct inode *dir, struct dentry *dentry)
{
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 92cea656ad2..d4d41b3efc7 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2005-2009 NTT DATA CORPORATION
*
- * Version: 2.2.0-pre 2009/02/01
+ * Version: 2.2.0 2009/04/01
*
*/
@@ -1252,15 +1252,12 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
struct tomoyo_domain_info *domain = head->write_var1;
bool is_delete = false;
bool is_select = false;
- bool is_undelete = false;
unsigned int profile;
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE))
is_delete = true;
else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_SELECT))
is_select = true;
- else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_UNDELETE))
- is_undelete = true;
if (is_select && tomoyo_is_select_one(head, data))
return 0;
/* Don't allow updating policies by non manager programs. */
@@ -1274,9 +1271,7 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
down_read(&tomoyo_domain_list_lock);
domain = tomoyo_find_domain(data);
up_read(&tomoyo_domain_list_lock);
- } else if (is_undelete)
- domain = tomoyo_undelete_domain(data);
- else
+ } else
domain = tomoyo_find_or_assign_new_domain(data, 0);
head->write_var1 = domain;
return 0;
@@ -1778,7 +1773,7 @@ void tomoyo_load_policy(const char *filename)
envp[2] = NULL;
call_usermodehelper(argv[0], argv, envp, 1);
- printk(KERN_INFO "TOMOYO: 2.2.0-pre 2009/02/01\n");
+ printk(KERN_INFO "TOMOYO: 2.2.0 2009/04/01\n");
printk(KERN_INFO "Mandatory Access Control activated.\n");
tomoyo_policy_loaded = true;
{ /* Check all profiles currently assigned to domains are defined. */
@@ -1805,7 +1800,7 @@ void tomoyo_load_policy(const char *filename)
static int tomoyo_read_version(struct tomoyo_io_buffer *head)
{
if (!head->read_eof) {
- tomoyo_io_printf(head, "2.2.0-pre");
+ tomoyo_io_printf(head, "2.2.0");
head->read_eof = true;
}
return 0;
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 26a76d67aa1..678f4ff16aa 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -5,7 +5,7 @@
*
* Copyright (C) 2005-2009 NTT DATA CORPORATION
*
- * Version: 2.2.0-pre 2009/02/01
+ * Version: 2.2.0 2009/04/01
*
*/
@@ -88,10 +88,7 @@ struct tomoyo_domain_info {
/* Name of this domain. Never NULL. */
const struct tomoyo_path_info *domainname;
u8 profile; /* Profile number to use. */
- u8 is_deleted; /* Delete flag.
- 0 = active.
- 1 = deleted but undeletable.
- 255 = deleted and no longer undeletable. */
+ bool is_deleted; /* Delete flag. */
bool quota_warned; /* Quota warnning flag. */
/* DOMAIN_FLAGS_*. Use tomoyo_set_domain_flag() to modify. */
u8 flags;
@@ -144,7 +141,6 @@ struct tomoyo_double_path_acl_record {
#define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain "
#define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain "
#define TOMOYO_KEYWORD_SELECT "select "
-#define TOMOYO_KEYWORD_UNDELETE "undelete "
#define TOMOYO_KEYWORD_USE_PROFILE "use_profile "
#define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read"
/* A domain definition starts with <kernel>. */
@@ -267,8 +263,6 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
domainname,
const u8 profile);
-/* Undelete a domain. */
-struct tomoyo_domain_info *tomoyo_undelete_domain(const char *domainname);
/* Check mode for specified functionality. */
unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
const u8 index);
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 093a756030b..2d6748741a2 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2005-2009 NTT DATA CORPORATION
*
- * Version: 2.2.0-pre 2009/02/01
+ * Version: 2.2.0 2009/04/01
*
*/
@@ -551,9 +551,7 @@ int tomoyo_write_alias_policy(char *data, const bool is_delete)
return tomoyo_update_alias_entry(data, cp, is_delete);
}
-/* Domain create/delete/undelete handler. */
-
-/* #define TOMOYO_DEBUG_DOMAIN_UNDELETE */
+/* Domain create/delete handler. */
/**
* tomoyo_delete_domain - Delete a domain.
@@ -571,41 +569,15 @@ int tomoyo_delete_domain(char *domainname)
tomoyo_fill_path_info(&name);
/***** EXCLUSIVE SECTION START *****/
down_write(&tomoyo_domain_list_lock);
-#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
- printk(KERN_DEBUG "tomoyo_delete_domain %s\n", domainname);
- list_for_each_entry(domain, &tomoyo_domain_list, list) {
- if (tomoyo_pathcmp(domain->domainname, &name))
- continue;
- printk(KERN_DEBUG "List: %p %u\n", domain, domain->is_deleted);
- }
-#endif
/* Is there an active domain? */
list_for_each_entry(domain, &tomoyo_domain_list, list) {
- struct tomoyo_domain_info *domain2;
/* Never delete tomoyo_kernel_domain */
if (domain == &tomoyo_kernel_domain)
continue;
if (domain->is_deleted ||
tomoyo_pathcmp(domain->domainname, &name))
continue;
- /* Mark already deleted domains as non undeletable. */
- list_for_each_entry(domain2, &tomoyo_domain_list, list) {
- if (!domain2->is_deleted ||
- tomoyo_pathcmp(domain2->domainname, &name))
- continue;
-#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
- if (domain2->is_deleted != 255)
- printk(KERN_DEBUG
- "Marked %p as non undeletable\n",
- domain2);
-#endif
- domain2->is_deleted = 255;
- }
- /* Delete and mark active domain as undeletable. */
- domain->is_deleted = 1;
-#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
- printk(KERN_DEBUG "Marked %p as undeletable\n", domain);
-#endif
+ domain->is_deleted = true;
break;
}
up_write(&tomoyo_domain_list_lock);
@@ -614,58 +586,6 @@ int tomoyo_delete_domain(char *domainname)
}
/**
- * tomoyo_undelete_domain - Undelete a domain.
- *
- * @domainname: The name of domain.
- *
- * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise.
- */
-struct tomoyo_domain_info *tomoyo_undelete_domain(const char *domainname)
-{
- struct tomoyo_domain_info *domain;
- struct tomoyo_domain_info *candidate_domain = NULL;
- struct tomoyo_path_info name;
-
- name.name = domainname;
- tomoyo_fill_path_info(&name);
- /***** EXCLUSIVE SECTION START *****/
- down_write(&tomoyo_domain_list_lock);
-#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
- printk(KERN_DEBUG "tomoyo_undelete_domain %s\n", domainname);
- list_for_each_entry(domain, &tomoyo_domain_list, list) {
- if (tomoyo_pathcmp(domain->domainname, &name))
- continue;
- printk(KERN_DEBUG "List: %p %u\n", domain, domain->is_deleted);
- }
-#endif
- list_for_each_entry(domain, &tomoyo_domain_list, list) {
- if (tomoyo_pathcmp(&name, domain->domainname))
- continue;
- if (!domain->is_deleted) {
- /* This domain is active. I can't undelete. */
- candidate_domain = NULL;
-#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
- printk(KERN_DEBUG "%p is active. I can't undelete.\n",
- domain);
-#endif
- break;
- }
- /* Is this domain undeletable? */
- if (domain->is_deleted == 1)
- candidate_domain = domain;
- }
- if (candidate_domain) {
- candidate_domain->is_deleted = 0;
-#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
- printk(KERN_DEBUG "%p was undeleted.\n", candidate_domain);
-#endif
- }
- up_write(&tomoyo_domain_list_lock);
- /***** EXCLUSIVE SECTION END *****/
- return candidate_domain;
-}
-
-/**
* tomoyo_find_or_assign_new_domain - Create a domain.
*
* @domainname: The name of domain.
@@ -711,10 +631,6 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
/***** CRITICAL SECTION END *****/
if (flag)
continue;
-#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
- printk(KERN_DEBUG "Reusing %p %s\n", domain,
- domain->domainname->name);
-#endif
list_for_each_entry(ptr, &domain->acl_info_list, list) {
ptr->type |= TOMOYO_ACL_DELETED;
}
@@ -722,7 +638,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
domain->profile = profile;
domain->quota_warned = false;
mb(); /* Avoid out-of-order execution. */
- domain->is_deleted = 0;
+ domain->is_deleted = false;
goto out;
}
/* No memory reusable. Create using new memory. */
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 65f50c1c5ee..2316da8ec5b 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2005-2009 NTT DATA CORPORATION
*
- * Version: 2.2.0-pre 2009/02/01
+ * Version: 2.2.0 2009/04/01
*
*/
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 3bbe01a7a4b..bf8e2b45168 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2005-2009 NTT DATA CORPORATION
*
- * Version: 2.2.0-pre 2009/02/01
+ * Version: 2.2.0 2009/04/01
*
*/
diff --git a/security/tomoyo/realpath.h b/security/tomoyo/realpath.h
index 7ec9fc9cbc0..78217a37960 100644
--- a/security/tomoyo/realpath.h
+++ b/security/tomoyo/realpath.h
@@ -5,7 +5,7 @@
*
* Copyright (C) 2005-2009 NTT DATA CORPORATION
*
- * Version: 2.2.0-pre 2009/02/01
+ * Version: 2.2.0 2009/04/01
*
*/
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index 3eeeae12c4d..5b481912752 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2005-2009 NTT DATA CORPORATION
*
- * Version: 2.2.0-pre 2009/02/01
+ * Version: 2.2.0 2009/04/01
*
*/
diff --git a/security/tomoyo/tomoyo.h b/security/tomoyo/tomoyo.h
index a0c8f6e0bea..41c6ebafb9c 100644
--- a/security/tomoyo/tomoyo.h
+++ b/security/tomoyo/tomoyo.h
@@ -5,7 +5,7 @@
*
* Copyright (C) 2005-2009 NTT DATA CORPORATION
*
- * Version: 2.2.0-pre 2009/02/01
+ * Version: 2.2.0 2009/04/01
*
*/
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 7793d2a511c..0afd1a8226f 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -238,6 +238,8 @@ static inline void pxa_ac97_cold_pxa3xx(void)
bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
{
+ unsigned long gsr;
+
#ifdef CONFIG_PXA25x
if (cpu_is_pxa25x())
pxa_ac97_warm_pxa25x();
@@ -254,10 +256,10 @@ bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
else
#endif
BUG();
-
- if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
+ gsr = GSR | gsr_bits;
+ if (!(gsr & (GSR_PCR | GSR_SCR))) {
printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
- __func__, gsr_bits);
+ __func__, gsr);
return false;
}
@@ -268,6 +270,8 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
{
+ unsigned long gsr;
+
#ifdef CONFIG_PXA25x
if (cpu_is_pxa25x())
pxa_ac97_cold_pxa25x();
@@ -285,9 +289,10 @@ bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
#endif
BUG();
- if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
+ gsr = GSR | gsr_bits;
+ if (!(gsr & (GSR_PCR | GSR_SCR))) {
printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
- __func__, gsr_bits);
+ __func__, gsr);
return false;
}
diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c
index 28b3c7f7cfe..f2f41c85422 100644
--- a/sound/atmel/abdac.c
+++ b/sound/atmel/abdac.c
@@ -165,7 +165,7 @@ static struct snd_pcm_hardware atmel_abdac_hw = {
.buffer_bytes_max = 64 * 4096,
.period_bytes_min = 4096,
.period_bytes_max = 4096,
- .periods_min = 4,
+ .periods_min = 6,
.periods_max = 64,
};
@@ -502,7 +502,7 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, card);
dev_info(&pdev->dev, "Atmel ABDAC at 0x%p using %s\n",
- dac->regs, dac->dma.chan->dev->device.bus_id);
+ dac->regs, dev_name(&dac->dma.chan->dev->device));
return retval;
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index dd72e00e5ae..0c0f8771656 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -1,5 +1,5 @@
/*
- * Driver for the Atmel AC97C controller
+ * Driver for Atmel AC97C
*
* Copyright (C) 2005-2009 Atmel Corporation
*
@@ -10,6 +10,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/bitmap.h>
+#include <linux/device.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
@@ -65,6 +66,7 @@ struct atmel_ac97c {
/* Serialize access to opened variable */
spinlock_t lock;
void __iomem *regs;
+ int irq;
int opened;
int reset_pin;
};
@@ -150,10 +152,10 @@ static struct snd_pcm_hardware atmel_ac97c_hw = {
.rate_max = 48000,
.channels_min = 1,
.channels_max = 2,
- .buffer_bytes_max = 64 * 4096,
+ .buffer_bytes_max = 2 * 2 * 64 * 2048,
.period_bytes_min = 4096,
.period_bytes_max = 4096,
- .periods_min = 4,
+ .periods_min = 6,
.periods_max = 64,
};
@@ -297,9 +299,11 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
{
struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long word = 0;
+ unsigned long word = ac97c_readl(chip, OCA);
int retval;
+ word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
+
/* assign channels to AC97C channel A */
switch (runtime->channels) {
case 1:
@@ -312,7 +316,6 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
default:
/* TODO: support more than two channels */
return -EINVAL;
- break;
}
ac97c_writel(chip, OCA, word);
@@ -324,13 +327,25 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
word |= AC97C_CMR_CEM_LITTLE;
break;
case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
- default:
word &= ~(AC97C_CMR_CEM_LITTLE);
break;
+ default:
+ word = ac97c_readl(chip, OCA);
+ word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
+ ac97c_writel(chip, OCA, word);
+ return -EINVAL;
}
+ /* Enable underrun interrupt on channel A */
+ word |= AC97C_CSR_UNRUN;
+
ac97c_writel(chip, CAMR, word);
+ /* Enable channel A event interrupt */
+ word = ac97c_readl(chip, IMR);
+ word |= AC97C_SR_CAEVT;
+ ac97c_writel(chip, IER, word);
+
/* set variable rate if needed */
if (runtime->rate != 48000) {
word = ac97c_readl(chip, MR);
@@ -359,9 +374,11 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
{
struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long word = 0;
+ unsigned long word = ac97c_readl(chip, ICA);
int retval;
+ word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
+
/* assign channels to AC97C channel A */
switch (runtime->channels) {
case 1:
@@ -374,7 +391,6 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
default:
/* TODO: support more than two channels */
return -EINVAL;
- break;
}
ac97c_writel(chip, ICA, word);
@@ -386,13 +402,25 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
word |= AC97C_CMR_CEM_LITTLE;
break;
case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
- default:
word &= ~(AC97C_CMR_CEM_LITTLE);
break;
+ default:
+ word = ac97c_readl(chip, ICA);
+ word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
+ ac97c_writel(chip, ICA, word);
+ return -EINVAL;
}
+ /* Enable overrun interrupt on channel A */
+ word |= AC97C_CSR_OVRUN;
+
ac97c_writel(chip, CAMR, word);
+ /* Enable channel A event interrupt */
+ word = ac97c_readl(chip, IMR);
+ word |= AC97C_SR_CAEVT;
+ ac97c_writel(chip, IER, word);
+
/* set variable rate if needed */
if (runtime->rate != 48000) {
word = ac97c_readl(chip, MR);
@@ -543,6 +571,43 @@ static struct snd_pcm_ops atmel_ac97_capture_ops = {
.pointer = atmel_ac97c_capture_pointer,
};
+static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
+{
+ struct atmel_ac97c *chip = (struct atmel_ac97c *)dev;
+ irqreturn_t retval = IRQ_NONE;
+ u32 sr = ac97c_readl(chip, SR);
+ u32 casr = ac97c_readl(chip, CASR);
+ u32 cosr = ac97c_readl(chip, COSR);
+
+ if (sr & AC97C_SR_CAEVT) {
+ dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n",
+ casr & AC97C_CSR_OVRUN ? " OVRUN" : "",
+ casr & AC97C_CSR_RXRDY ? " RXRDY" : "",
+ casr & AC97C_CSR_UNRUN ? " UNRUN" : "",
+ casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
+ casr & AC97C_CSR_TXRDY ? " TXRDY" : "",
+ !casr ? " NONE" : "");
+ retval = IRQ_HANDLED;
+ }
+
+ if (sr & AC97C_SR_COEVT) {
+ dev_info(&chip->pdev->dev, "codec channel event%s%s%s%s%s\n",
+ cosr & AC97C_CSR_OVRUN ? " OVRUN" : "",
+ cosr & AC97C_CSR_RXRDY ? " RXRDY" : "",
+ cosr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
+ cosr & AC97C_CSR_TXRDY ? " TXRDY" : "",
+ !cosr ? " NONE" : "");
+ retval = IRQ_HANDLED;
+ }
+
+ if (retval == IRQ_NONE) {
+ dev_err(&chip->pdev->dev, "spurious interrupt sr 0x%08x "
+ "casr 0x%08x cosr 0x%08x\n", sr, casr, cosr);
+ }
+
+ return retval;
+}
+
static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip)
{
struct snd_pcm *pcm;
@@ -665,17 +730,17 @@ static bool filter(struct dma_chan *chan, void *slave)
static void atmel_ac97c_reset(struct atmel_ac97c *chip)
{
- ac97c_writel(chip, MR, AC97C_MR_WRST);
+ ac97c_writel(chip, MR, 0);
+ ac97c_writel(chip, MR, AC97C_MR_ENA);
+ ac97c_writel(chip, CAMR, 0);
+ ac97c_writel(chip, COMR, 0);
if (gpio_is_valid(chip->reset_pin)) {
gpio_set_value(chip->reset_pin, 0);
/* AC97 v2.2 specifications says minimum 1 us. */
- udelay(10);
+ udelay(2);
gpio_set_value(chip->reset_pin, 1);
}
-
- udelay(1);
- ac97c_writel(chip, MR, AC97C_MR_ENA);
}
static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
@@ -690,6 +755,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
.read = atmel_ac97c_read,
};
int retval;
+ int irq;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
@@ -703,6 +769,12 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
return -ENXIO;
}
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_dbg(&pdev->dev, "could not get irq\n");
+ return -ENXIO;
+ }
+
pclk = clk_get(&pdev->dev, "pclk");
if (IS_ERR(pclk)) {
dev_dbg(&pdev->dev, "no peripheral clock\n");
@@ -719,6 +791,13 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
chip = get_chip(card);
+ retval = request_irq(irq, atmel_ac97c_interrupt, 0, "AC97C", chip);
+ if (retval) {
+ dev_dbg(&pdev->dev, "unable to request irq %d\n", irq);
+ goto err_request_irq;
+ }
+ chip->irq = irq;
+
spin_lock_init(&chip->lock);
strcpy(card->driver, "Atmel AC97C");
@@ -747,14 +826,18 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
snd_card_set_dev(card, &pdev->dev);
+ atmel_ac97c_reset(chip);
+
+ /* Enable overrun interrupt from codec channel */
+ ac97c_writel(chip, COMR, AC97C_CSR_OVRUN);
+ ac97c_writel(chip, IER, ac97c_readl(chip, IMR) | AC97C_SR_COEVT);
+
retval = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus);
if (retval) {
dev_dbg(&pdev->dev, "could not register on ac97 bus\n");
goto err_ac97_bus;
}
- atmel_ac97c_reset(chip);
-
retval = atmel_ac97c_mixer_new(chip);
if (retval) {
dev_dbg(&pdev->dev, "could not register ac97 mixer\n");
@@ -773,7 +856,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
chip->dma.rx_chan = dma_request_channel(mask, filter, dws);
dev_info(&chip->pdev->dev, "using %s for DMA RX\n",
- chip->dma.rx_chan->dev->device.bus_id);
+ dev_name(&chip->dma.rx_chan->dev->device));
set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
}
@@ -789,7 +872,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
chip->dma.tx_chan = dma_request_channel(mask, filter, dws);
dev_info(&chip->pdev->dev, "using %s for DMA TX\n",
- chip->dma.tx_chan->dev->device.bus_id);
+ dev_name(&chip->dma.tx_chan->dev->device));
set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
}
@@ -809,7 +892,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
retval = snd_card_register(card);
if (retval) {
dev_dbg(&pdev->dev, "could not register sound card\n");
- goto err_ac97_bus;
+ goto err_dma;
}
platform_set_drvdata(pdev, card);
@@ -836,6 +919,8 @@ err_ac97_bus:
iounmap(chip->regs);
err_ioremap:
+ free_irq(irq, chip);
+err_request_irq:
snd_card_free(card);
err_snd_card_new:
clk_disable(pclk);
@@ -884,9 +969,14 @@ static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
if (gpio_is_valid(chip->reset_pin))
gpio_free(chip->reset_pin);
+ ac97c_writel(chip, CAMR, 0);
+ ac97c_writel(chip, COMR, 0);
+ ac97c_writel(chip, MR, 0);
+
clk_disable(chip->pclk);
clk_put(chip->pclk);
iounmap(chip->regs);
+ free_irq(chip->irq, chip);
if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
dma_release_channel(chip->dma.rx_chan);
diff --git a/sound/atmel/ac97c.h b/sound/atmel/ac97c.h
index c17bd582598..ecbba5021c8 100644
--- a/sound/atmel/ac97c.h
+++ b/sound/atmel/ac97c.h
@@ -1,5 +1,5 @@
/*
- * Register definitions for the Atmel AC97C controller
+ * Register definitions for Atmel AC97C
*
* Copyright (C) 2005-2009 Atmel Corporation
*
@@ -17,10 +17,6 @@
#define AC97C_CATHR 0x24
#define AC97C_CASR 0x28
#define AC97C_CAMR 0x2c
-#define AC97C_CBRHR 0x30
-#define AC97C_CBTHR 0x34
-#define AC97C_CBSR 0x38
-#define AC97C_CBMR 0x3c
#define AC97C_CORHR 0x40
#define AC97C_COTHR 0x44
#define AC97C_COSR 0x48
@@ -46,8 +42,10 @@
#define AC97C_MR_VRA (1 << 2)
#define AC97C_CSR_TXRDY (1 << 0)
+#define AC97C_CSR_TXEMPTY (1 << 1)
#define AC97C_CSR_UNRUN (1 << 2)
#define AC97C_CSR_RXRDY (1 << 4)
+#define AC97C_CSR_OVRUN (1 << 5)
#define AC97C_CSR_ENDTX (1 << 10)
#define AC97C_CSR_ENDRX (1 << 14)
@@ -61,11 +59,15 @@
#define AC97C_CMR_DMAEN (1 << 22)
#define AC97C_SR_CAEVT (1 << 3)
+#define AC97C_SR_COEVT (1 << 2)
+#define AC97C_SR_WKUP (1 << 1)
+#define AC97C_SR_SOF (1 << 0)
+#define AC97C_CH_MASK(slot) \
+ (0x7 << (3 * (AC97_SLOT_##slot - 3)))
#define AC97C_CH_ASSIGN(slot, channel) \
(AC97C_CHANNEL_##channel << (3 * (AC97_SLOT_##slot - 3)))
#define AC97C_CHANNEL_NONE 0x0
#define AC97C_CHANNEL_A 0x1
-#define AC97C_CHANNEL_B 0x2
#endif /* __SOUND_ATMEL_AC97C_H */
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index e570649184e..5dcd8a52697 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -703,19 +703,27 @@ static int snd_mixer_oss_put_volume1(struct snd_mixer_oss_file *fmixer,
if (left || right) {
if (slot->present & SNDRV_MIXER_OSS_PRESENT_PSWITCH)
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PSWITCH], left, right, 0);
+ if (slot->present & SNDRV_MIXER_OSS_PRESENT_CSWITCH)
+ snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], left, right, 0);
if (slot->present & SNDRV_MIXER_OSS_PRESENT_GSWITCH)
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GSWITCH], left, right, 0);
if (slot->present & SNDRV_MIXER_OSS_PRESENT_PROUTE)
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PROUTE], left, right, 1);
+ if (slot->present & SNDRV_MIXER_OSS_PRESENT_CROUTE)
+ snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], left, right, 1);
if (slot->present & SNDRV_MIXER_OSS_PRESENT_GROUTE)
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);
} else {
if (slot->present & SNDRV_MIXER_OSS_PRESENT_PSWITCH) {
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PSWITCH], left, right, 0);
+ } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_CSWITCH) {
+ snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], left, right, 0);
} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GSWITCH) {
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GSWITCH], left, right, 0);
} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_PROUTE) {
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PROUTE], left, right, 1);
+ } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_CROUTE) {
+ snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], left, right, 1);
} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GROUTE) {
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);
}
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index c5c9a9218ff..c6942a4de99 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -395,16 +395,6 @@ config SND_WAVEFRONT
To compile this driver as a module, choose M here: the module
will be called snd-wavefront.
-config SND_WAVEFRONT_FIRMWARE_IN_KERNEL
- bool "In-kernel firmware for Wavefront"
- depends on SND_WAVEFRONT
- default y
- help
- Say Y here to include the static firmware for FX DSP built in
- the kernel for the Wavefront driver. If you choose N here,
- you need to install the firmware files from the
- alsa-firmware package.
-
config SND_MSND_PINNACLE
tristate "Turtle Beach MultiSound Pinnacle/Fiji driver"
depends on X86 && EXPERIMENTAL
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index ef95279da7a..0481a55334b 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -481,6 +481,7 @@ OPL3SA2_DOUBLE_TLV("Master Playback Volume", 0, 0x07, 0x08, 0, 0, 15, 1,
OPL3SA2_SINGLE("Mic Playback Switch", 0, 0x09, 7, 1, 1),
OPL3SA2_SINGLE_TLV("Mic Playback Volume", 0, 0x09, 0, 31, 1,
db_scale_5bit_12db_max),
+OPL3SA2_SINGLE("ZV Port Switch", 0, 0x02, 0, 1, 0),
};
static struct snd_kcontrol_new snd_opl3sa2_tone_controls[] = {
diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c
index dfc449a2194..a4345fc0756 100644
--- a/sound/isa/wavefront/wavefront_fx.c
+++ b/sound/isa/wavefront/wavefront_fx.c
@@ -34,14 +34,6 @@
#define WAIT_IDLE 0xff
-#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
-#include "yss225.c"
-static const struct firmware yss225_registers_firmware = {
- .data = (u8 *)yss225_registers,
- .size = sizeof yss225_registers
-};
-#endif
-
static int
wavefront_fx_idle (snd_wavefront_t *dev)
@@ -260,16 +252,12 @@ snd_wavefront_fx_start (snd_wavefront_t *dev)
if (dev->fx_initialized)
return 0;
-#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
- firmware = &yss225_registers_firmware;
-#else
err = request_firmware(&firmware, "yamaha/yss225_registers.bin",
dev->card->dev);
if (err < 0) {
err = -1;
goto out;
}
-#endif
for (i = 0; i + 1 < firmware->size; i += 2) {
if (firmware->data[i] >= 8 && firmware->data[i] < 16) {
@@ -292,12 +280,8 @@ snd_wavefront_fx_start (snd_wavefront_t *dev)
err = 0;
out:
-#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
release_firmware(firmware);
-#endif
return err;
}
-#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
MODULE_FIRMWARE("yamaha/yss225_registers.bin");
-#endif
diff --git a/sound/isa/wavefront/yss225.c b/sound/isa/wavefront/yss225.c
deleted file mode 100644
index 9f6be3ff8ec..00000000000
--- a/sound/isa/wavefront/yss225.c
+++ /dev/null
@@ -1,2739 +0,0 @@
-/*
- * Copyright (c) 1998-2002 by Paul Davis <pbd@op.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* weird stuff, derived from port I/O tracing with dosemu */
-
-static const struct {
- unsigned char addr;
- unsigned char data;
-} yss225_registers[] __devinitdata = {
-/* Set all bits for all channels on the MOD unit to zero */
-{ WAIT_IDLE }, { 0xe, 0x10 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x11 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x12 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x13 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x14 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x15 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x16 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x17 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x18 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x19 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x20 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x21 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x22 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x23 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x24 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x25 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x26 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x27 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x28 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x29 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x30 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x31 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x32 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x33 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x34 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x35 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x36 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x37 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x38 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x39 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x40 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x41 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x42 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x43 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x44 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x45 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x46 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x47 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x48 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x49 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x50 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x51 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x52 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x53 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x54 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x55 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x56 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x57 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x58 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x59 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x60 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x61 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x62 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x63 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x64 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x65 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x66 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x67 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x68 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x69 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x70 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x71 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x72 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x73 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x74 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x75 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x76 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x77 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x78 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x79 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x80 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x81 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x82 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x83 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x84 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x85 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x86 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x87 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x88 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x89 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x90 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x91 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x92 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x93 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x94 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x95 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x96 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x97 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x98 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x99 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xaa }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xab }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xac }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xad }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xae }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xaf }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xba }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbc }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbd }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbe }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbf }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xca }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xcb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xcc }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xcd }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xce }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xcf }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xda }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xdb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xdc }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xdd }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xde }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xdf }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xea }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xeb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xec }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xed }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xee }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xef }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfa }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfc }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfd }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfe }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xff }, { 0xf, 0x00 },
-
-/* XXX But why do this twice? */
-{ WAIT_IDLE }, { 0xe, 0x10 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x11 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x12 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x13 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x14 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x15 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x16 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x17 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x18 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x19 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x20 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x21 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x22 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x23 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x24 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x25 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x26 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x27 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x28 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x29 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x30 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x31 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x32 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x33 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x34 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x35 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x36 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x37 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x38 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x39 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x40 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x41 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x42 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x43 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x44 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x45 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x46 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x47 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x48 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x49 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x50 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x51 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x52 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x53 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x54 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x55 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x56 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x57 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x58 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x59 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x60 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x61 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x62 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x63 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x64 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x65 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x66 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x67 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x68 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x69 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x70 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x71 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x72 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x73 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x74 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x75 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x76 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x77 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x78 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x79 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x80 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x81 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x82 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x83 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x84 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x85 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x86 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x87 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x88 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x89 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x90 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x91 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x92 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x93 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x94 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x95 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x96 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x97 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x98 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x99 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xaa }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xab }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xac }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xad }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xae }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xaf }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xba }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbc }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbd }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbe }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbf }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xca }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xcb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xcc }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xcd }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xce }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xcf }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xda }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xdb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xdc }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xdd }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xde }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xdf }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xea }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xeb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xec }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xed }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xee }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xef }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfa }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfc }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfd }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfe }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xff }, { 0xf, 0x00 },
-
-/* mute on */
-{ WAIT_IDLE }, { 0x8, 0x02 },
-
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x44 }, { 0xd, 0x00 }, { 0xc, 0x00 },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x42 }, { 0xd, 0x00 }, { 0xc, 0x00 },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x43 }, { 0xd, 0x00 }, { 0xc, 0x00 },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x7c }, { 0xd, 0x00 }, { 0xc, 0x00 },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x7e }, { 0xd, 0x00 }, { 0xc, 0x00 },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x46 }, { 0xd, 0x00 }, { 0xc, 0x00 },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x49 }, { 0xd, 0x00 }, { 0xc, 0x00 },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x47 }, { 0xd, 0x00 }, { 0xc, 0x00 },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x4a }, { 0xd, 0x00 }, { 0xc, 0x00 },
-
-/* either because of stupidity by TB's programmers, or because it
- actually does something, rezero the MOD page. */
-{ WAIT_IDLE }, { 0xe, 0x10 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x11 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x12 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x13 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x14 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x15 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x16 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x17 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x18 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x19 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x1f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x20 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x21 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x22 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x23 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x24 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x25 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x26 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x27 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x28 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x29 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x2f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x30 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x31 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x32 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x33 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x34 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x35 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x36 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x37 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x38 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x39 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x3f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x40 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x41 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x42 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x43 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x44 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x45 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x46 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x47 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x48 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x49 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x4f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x50 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x51 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x52 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x53 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x54 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x55 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x56 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x57 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x58 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x59 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x5f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x60 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x61 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x62 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x63 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x64 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x65 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x66 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x67 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x68 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x69 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x6f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x70 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x71 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x72 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x73 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x74 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x75 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x76 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x77 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x78 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x79 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x7f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x80 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x81 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x82 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x83 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x84 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x85 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x86 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x87 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x88 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x89 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x8f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x90 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x91 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x92 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x93 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x94 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x95 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x96 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x97 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x98 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x99 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9a }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9b }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9c }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9d }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9e }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0x9f }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xa9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xaa }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xab }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xac }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xad }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xae }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xaf }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xb9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xba }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbc }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbd }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbe }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xbf }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xc9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xca }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xcb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xcc }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xcd }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xce }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xcf }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xd9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xda }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xdb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xdc }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xdd }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xde }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xdf }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xe9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xea }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xeb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xec }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xed }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xee }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xef }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf0 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf1 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf2 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf3 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf4 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf5 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf6 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf7 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf8 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xf9 }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfa }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfb }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfc }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfd }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xfe }, { 0xf, 0x00 },
-{ WAIT_IDLE }, { 0xe, 0xff }, { 0xf, 0x00 },
-
-/* load page zero */
-{ 0x9, 0x05 }, { 0xb, 0x00 }, { 0xa, 0x00 },
-
-{ 0xd, 0x01 }, { 0xc, 0x7c }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x1e }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0xf5 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x11 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x32 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x13 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x14 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x76 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x80 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x18 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x19 }, { WAIT_IDLE },
-{ 0xd, 0x01 }, { 0xc, 0x1a }, { WAIT_IDLE },
-{ 0xd, 0x01 }, { 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xd, 0x01 }, { 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xd, 0x01 }, { 0xc, 0x17 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x01 }, { 0xc, 0x80 }, { WAIT_IDLE },
-{ 0xd, 0x01 }, { 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x10 }, { WAIT_IDLE },
-{ 0xd, 0x01 }, { 0xc, 0xa0 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0xd1 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x01 }, { 0xc, 0xf2 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x13 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0xf4 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xe0 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x15 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x16 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x17 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x50 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x71 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x92 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x80 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0xb3 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0xa0 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0xd4 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x80 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0xf5 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x70 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0xa0 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x11 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x16 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x10 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x17 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x1b }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x1d }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xdf }, { WAIT_IDLE },
-
-/* Now load page one */
-{ 0x9, 0x05 }, { 0xb, 0x01 }, { 0xa, 0x00 },
-
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x19 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x1f }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0xd8 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x19 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x18 }, { WAIT_IDLE },
-{ 0xd, 0x01 }, { 0xc, 0xc0 }, { WAIT_IDLE },
-{ 0xd, 0x01 }, { 0xc, 0xfa }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x1a }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xc0 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x80 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xfb }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xa0 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x1b }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xd7 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xf7 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x1c }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0x3c }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0x3f }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0xc0 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0xdf }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0x5d }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0xc0 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0x7d }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0xc0 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0x9e }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0xc0 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0xbe }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x03 }, { 0xc, 0xc0 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x1b }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xdb }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xdb }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xe0 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xfb }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xc0 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xfb }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x1b }, { WAIT_IDLE },
-
-{ 0x9, 0x05 }, { 0xb, 0x02 }, { 0xa, 0x00 },
-
-{ 0xc, 0xc4 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x44 }, { WAIT_IDLE },
-{ 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xc, 0x44 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x25 }, { WAIT_IDLE },
-{ 0xc, 0x01 }, { WAIT_IDLE },
-{ 0xc, 0x06 }, { WAIT_IDLE },
-{ 0xc, 0xc4 }, { WAIT_IDLE },
-{ 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x25 }, { WAIT_IDLE },
-{ 0xc, 0x01 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x04 }, { WAIT_IDLE },
-{ 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x04 }, { WAIT_IDLE },
-{ 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x44 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x44 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x44 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x44 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xc, 0x44 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xc, 0x44 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xc, 0x44 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xc, 0x44 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x44 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x05 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xc, 0x44 }, { WAIT_IDLE },
-
-{ 0x9, 0x05 }, { 0xb, 0x03 }, { 0xa, 0x00 },
-
-{ 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x47 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x06 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x80 }, { WAIT_IDLE },
-{ 0xc, 0x80 }, { WAIT_IDLE },
-{ 0xc, 0xc0 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x70 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x42 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x02 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x42 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x42 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x02 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x02 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x02 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x42 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0xc0 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x40 }, { WAIT_IDLE },
-
-{ 0x9, 0x05 }, { 0xb, 0x04 }, { 0xa, 0x00 },
-
-{ 0xc, 0x63 }, { WAIT_IDLE },
-{ 0xc, 0x03 }, { WAIT_IDLE },
-{ 0xc, 0x26 }, { WAIT_IDLE },
-{ 0xc, 0x02 }, { WAIT_IDLE },
-{ 0xc, 0x2c }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x24 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x2e }, { WAIT_IDLE },
-{ 0xc, 0x02 }, { WAIT_IDLE },
-{ 0xc, 0x02 }, { WAIT_IDLE },
-{ 0xc, 0x02 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x01 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x22 }, { WAIT_IDLE },
-{ 0xc, 0x02 }, { WAIT_IDLE },
-{ 0xc, 0x22 }, { WAIT_IDLE },
-{ 0xc, 0x02 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x22 }, { WAIT_IDLE },
-{ 0xc, 0x02 }, { WAIT_IDLE },
-{ 0xc, 0x62 }, { WAIT_IDLE },
-{ 0xc, 0x02 }, { WAIT_IDLE },
-{ 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xc, 0x01 }, { WAIT_IDLE },
-{ 0xc, 0x21 }, { WAIT_IDLE },
-{ 0xc, 0x01 }, { WAIT_IDLE },
-
-/* Load memory area (page six) */
-{ 0x9, 0x01 }, { 0xb, 0x06 },
-
-{ 0xa, 0x00 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x02 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x04 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x06 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x08 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x0a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x0c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x0e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x10 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x12 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x14 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x16 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x18 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x1a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x1c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x1e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x20 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x22 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x24 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x26 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x28 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x2a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x2c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x2e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x30 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x32 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x34 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x36 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x38 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x3a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x3c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x3e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x40 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x42 }, { 0xd, 0x03 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x44 }, { 0xd, 0x01 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x46 }, { 0xd, 0x0a }, { 0xc, 0x21 }, { WAIT_IDLE },
-{ 0xa, 0x48 }, { 0xd, 0x0d }, { 0xc, 0x23 }, { WAIT_IDLE },
-{ 0xa, 0x4a }, { 0xd, 0x23 }, { 0xc, 0x1b }, { WAIT_IDLE },
-{ 0xa, 0x4c }, { 0xd, 0x37 }, { 0xc, 0x8f }, { WAIT_IDLE },
-{ 0xa, 0x4e }, { 0xd, 0x45 }, { 0xc, 0x77 }, { WAIT_IDLE },
-{ 0xa, 0x50 }, { 0xd, 0x52 }, { 0xc, 0xe2 }, { WAIT_IDLE },
-{ 0xa, 0x52 }, { 0xd, 0x1c }, { 0xc, 0x92 }, { WAIT_IDLE },
-{ 0xa, 0x54 }, { 0xd, 0x1c }, { 0xc, 0x52 }, { WAIT_IDLE },
-{ 0xa, 0x56 }, { 0xd, 0x07 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x58 }, { 0xd, 0x2f }, { 0xc, 0xc6 }, { WAIT_IDLE },
-{ 0xa, 0x5a }, { 0xd, 0x0b }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x5c }, { 0xd, 0x30 }, { 0xc, 0x06 }, { WAIT_IDLE },
-{ 0xa, 0x5e }, { 0xd, 0x17 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x60 }, { 0xd, 0x3d }, { 0xc, 0xda }, { WAIT_IDLE },
-{ 0xa, 0x62 }, { 0xd, 0x29 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x64 }, { 0xd, 0x3e }, { 0xc, 0x41 }, { WAIT_IDLE },
-{ 0xa, 0x66 }, { 0xd, 0x39 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x68 }, { 0xd, 0x4c }, { 0xc, 0x48 }, { WAIT_IDLE },
-{ 0xa, 0x6a }, { 0xd, 0x49 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x6c }, { 0xd, 0x4c }, { 0xc, 0x6c }, { WAIT_IDLE },
-{ 0xa, 0x6e }, { 0xd, 0x11 }, { 0xc, 0xd2 }, { WAIT_IDLE },
-{ 0xa, 0x70 }, { 0xd, 0x16 }, { 0xc, 0x0c }, { WAIT_IDLE },
-{ 0xa, 0x72 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x74 }, { 0xd, 0x00 }, { 0xc, 0x80 }, { WAIT_IDLE },
-{ 0xa, 0x76 }, { 0xd, 0x0f }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x78 }, { 0xd, 0x00 }, { 0xc, 0x80 }, { WAIT_IDLE },
-{ 0xa, 0x7a }, { 0xd, 0x13 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x7c }, { 0xd, 0x80 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x7e }, { 0xd, 0x80 }, { 0xc, 0x80 }, { WAIT_IDLE },
-
-{ 0x9, 0x05 }, { 0xb, 0x07 }, { 0xa, 0x00 },
-
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x08 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x08 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x08 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x08 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0xe9 }, { WAIT_IDLE },
-{ 0xd, 0x06 }, { 0xc, 0x8c }, { WAIT_IDLE },
-{ 0xd, 0x06 }, { 0xc, 0x8c }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x1a }, { 0xc, 0x75 }, { WAIT_IDLE },
-{ 0xd, 0x0d }, { 0xc, 0x8b }, { WAIT_IDLE },
-{ 0xd, 0x04 }, { 0xc, 0xe9 }, { WAIT_IDLE },
-{ 0xd, 0x0b }, { 0xc, 0x16 }, { WAIT_IDLE },
-{ 0xd, 0x1a }, { 0xc, 0x38 }, { WAIT_IDLE },
-{ 0xd, 0x0d }, { 0xc, 0xc8 }, { WAIT_IDLE },
-{ 0xd, 0x04 }, { 0xc, 0x6f }, { WAIT_IDLE },
-{ 0xd, 0x0b }, { 0xc, 0x91 }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x06 }, { 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xd, 0x06 }, { 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x8f }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x06 }, { 0xc, 0x62 }, { WAIT_IDLE },
-{ 0xd, 0x06 }, { 0xc, 0x62 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x7b }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x06 }, { 0xc, 0x97 }, { WAIT_IDLE },
-{ 0xd, 0x06 }, { 0xc, 0x97 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x52 }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x06 }, { 0xc, 0xf6 }, { WAIT_IDLE },
-{ 0xd, 0x06 }, { 0xc, 0xf6 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x19 }, { WAIT_IDLE },
-{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE },
-{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE },
-{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE },
-{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE },
-{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE },
-{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE },
-{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE },
-{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE },
-{ 0xd, 0x14 }, { 0xc, 0xda }, { WAIT_IDLE },
-{ 0xd, 0x0d }, { 0xc, 0x93 }, { WAIT_IDLE },
-{ 0xd, 0x04 }, { 0xc, 0xda }, { WAIT_IDLE },
-{ 0xd, 0x05 }, { 0xc, 0x93 }, { WAIT_IDLE },
-{ 0xd, 0x14 }, { 0xc, 0xda }, { WAIT_IDLE },
-{ 0xd, 0x0d }, { 0xc, 0x93 }, { WAIT_IDLE },
-{ 0xd, 0x04 }, { 0xc, 0xda }, { WAIT_IDLE },
-{ 0xd, 0x05 }, { 0xc, 0x93 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE },
-
-/* Now setup the MOD area. */
-{ 0xe, 0x01 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x02 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x03 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x04 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x05 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x06 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x07 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x08 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x09 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x0a }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x0b }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x0c }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x0d }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x0e }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x0f }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-
-{ 0xe, 0xb0 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb1 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb2 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb3 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb4 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb5 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb6 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb7 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb8 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb9 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xba }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xbb }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xbc }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xbd }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xbe }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xbf }, { 0xf, 0x20 }, { WAIT_IDLE },
-
-{ 0xe, 0xf0 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf1 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf2 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf3 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf4 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf5 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf6 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf7 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf8 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf9 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xfa }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xfb }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xfc }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xfd }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xfe }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xff }, { 0xf, 0x20 }, { WAIT_IDLE },
-
-{ 0xe, 0x10 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x11 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x12 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x13 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x14 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x15 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x16 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x17 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x18 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x19 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x1a }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x1b }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x1c }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x1d }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x1e }, { 0xf, 0x40 }, { WAIT_IDLE },
-{ 0xe, 0x1f }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x20 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x21 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x22 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x23 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x24 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x25 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x26 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x27 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x28 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x29 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x2a }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x2b }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x2c }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x2d }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x2e }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x2f }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x30 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x31 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x32 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x33 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x34 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x35 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x36 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x37 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x38 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x39 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x3a }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x3b }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x3c }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x3d }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x3e }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x3f }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0x40 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x41 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x42 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x43 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x44 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x45 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x46 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x47 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x48 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x49 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x4a }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x4b }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x4c }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x4d }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x4e }, { 0xf, 0x0e }, { WAIT_IDLE },
-{ 0xe, 0x4f }, { 0xf, 0x0e }, { WAIT_IDLE },
-{ 0xe, 0x50 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x51 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x52 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x53 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x54 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x55 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x56 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x57 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x58 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x59 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x5a }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x5b }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x5c }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x5d }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x5e }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x5f }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x60 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x61 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x62 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x63 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x64 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x65 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x66 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x67 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x68 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x69 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x6a }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x6b }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x6c }, { 0xf, 0x40 }, { WAIT_IDLE },
-{ 0xe, 0x6d }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x6e }, { 0xf, 0x40 }, { WAIT_IDLE },
-{ 0xe, 0x6f }, { 0xf, 0x40 }, { WAIT_IDLE },
-{ 0xe, 0x70 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x71 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x72 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x73 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x74 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x75 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x76 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x77 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x78 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x79 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x7a }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x7b }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x7c }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x7d }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x7e }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x7f }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x80 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x81 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x82 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x83 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x84 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x85 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x86 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x87 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x88 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x89 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x8a }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x8b }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x8c }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x8d }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x8e }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x8f }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x90 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x91 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x92 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x93 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x94 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x95 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x96 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x97 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x98 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x99 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x9a }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x9b }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x9c }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x9d }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x9e }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x9f }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa0 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa1 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa2 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa3 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa4 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa5 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa6 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa7 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa8 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa9 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xaa }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xab }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xac }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xad }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xae }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xaf }, { 0xf, 0x00 }, { WAIT_IDLE },
-
-{ 0xe, 0xc0 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc1 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc2 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc3 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc4 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc5 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc6 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc7 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc8 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc9 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xca }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xcb }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xcc }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xcd }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xce }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xcf }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd0 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd1 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd2 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd3 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd4 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd5 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd6 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd7 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd8 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd9 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xda }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xdb }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xdc }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xdd }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xde }, { 0xf, 0x10 }, { WAIT_IDLE },
-{ 0xe, 0xdf }, { 0xf, 0x10 }, { WAIT_IDLE },
-{ 0xe, 0xe0 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe1 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe2 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe3 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe4 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe5 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe6 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe7 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe8 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe9 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xea }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xeb }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xec }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xed }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xee }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xef }, { 0xf, 0x00 }, { WAIT_IDLE },
-
-{ 0xe, 0x01 }, { 0xf, 0x00 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x01 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x02 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x03 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x04 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x05 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x06 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x07 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x08 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x09 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x0a }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x0b }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x0c }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x0d }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x0e }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x0f }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-
-/* mute on */
-{ 0x8, 0x02 },
-
-/* Now set the coefficients and so forth for the programs above */
-{ 0xb, 0x07 }, { 0xa, 0x46 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x49 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x00 }, { 0xa, 0x4b }, { 0xd, 0x03 }, { 0xc, 0x11 }, { WAIT_IDLE },
-{ 0xb, 0x00 }, { 0xa, 0x4d }, { 0xd, 0x01 }, { 0xc, 0x32 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x46 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x49 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x40 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x41 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x01 }, { 0xa, 0x40 }, { 0xd, 0x02 }, { 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xb, 0x01 }, { 0xa, 0x41 }, { 0xd, 0x02 }, { 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x40 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x41 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x47 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x4a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x00 }, { 0xa, 0x47 }, { 0xd, 0x01 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x00 }, { 0xa, 0x4a }, { 0xd, 0x01 }, { 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x47 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x4a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x7c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x7e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x00 }, { 0xa, 0x00 }, { 0xd, 0x01 }, { 0xc, 0x1c }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x7c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x7e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x44 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x00 }, { 0xa, 0x44 }, { 0xd, 0x01 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x44 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x42 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x43 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x00 }, { 0xa, 0x42 }, { 0xd, 0x01 }, { 0xc, 0x1a }, { WAIT_IDLE },
-{ 0xb, 0x00 }, { 0xa, 0x43 }, { 0xd, 0x01 }, { 0xc, 0x20 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x42 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x43 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x40 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x41 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x01 }, { 0xa, 0x40 }, { 0xd, 0x02 }, { 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xb, 0x01 }, { 0xa, 0x41 }, { 0xd, 0x02 }, { 0xc, 0x60 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x40 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x41 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x44 }, { 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x42 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x43 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x40 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x41 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x51 }, { 0xd, 0x06 }, { 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x50 }, { 0xd, 0x06 }, { 0xc, 0x40 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x4f }, { 0xd, 0x03 }, { 0xc, 0x81 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x53 }, { 0xd, 0x1a }, { 0xc, 0x76 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x54 }, { 0xd, 0x0d }, { 0xc, 0x8b }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x55 }, { 0xd, 0x04 }, { 0xc, 0xe9 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x56 }, { 0xd, 0x0b }, { 0xc, 0x17 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x57 }, { 0xd, 0x1a }, { 0xc, 0x38 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x58 }, { 0xd, 0x0d }, { 0xc, 0xc9 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x59 }, { 0xd, 0x04 }, { 0xc, 0x6f }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x5a }, { 0xd, 0x0b }, { 0xc, 0x91 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x73 }, { 0xd, 0x14 }, { 0xc, 0xda }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x74 }, { 0xd, 0x0d }, { 0xc, 0x93 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x75 }, { 0xd, 0x04 }, { 0xc, 0xd9 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x76 }, { 0xd, 0x05 }, { 0xc, 0x93 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x77 }, { 0xd, 0x14 }, { 0xc, 0xda }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x78 }, { 0xd, 0x0d }, { 0xc, 0x93 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x79 }, { 0xd, 0x04 }, { 0xc, 0xd9 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x7a }, { 0xd, 0x05 }, { 0xc, 0x93 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x5e }, { 0xd, 0x03 }, { 0xc, 0x68 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x5c }, { 0xd, 0x04 }, { 0xc, 0x31 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x5d }, { 0xd, 0x04 }, { 0xc, 0x31 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x62 }, { 0xd, 0x03 }, { 0xc, 0x52 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x60 }, { 0xd, 0x04 }, { 0xc, 0x76 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x61 }, { 0xd, 0x04 }, { 0xc, 0x76 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x66 }, { 0xd, 0x03 }, { 0xc, 0x2e }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x64 }, { 0xd, 0x04 }, { 0xc, 0xda }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x65 }, { 0xd, 0x04 }, { 0xc, 0xda }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x6a }, { 0xd, 0x02 }, { 0xc, 0xf6 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x68 }, { 0xd, 0x05 }, { 0xc, 0x62 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x69 }, { 0xd, 0x05 }, { 0xc, 0x62 }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x46 }, { 0xd, 0x0a }, { 0xc, 0x22 }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x48 }, { 0xd, 0x0d }, { 0xc, 0x24 }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x6e }, { 0xd, 0x11 }, { 0xc, 0xd3 }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x70 }, { 0xd, 0x15 }, { 0xc, 0xcb }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x52 }, { 0xd, 0x20 }, { 0xc, 0x93 }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x54 }, { 0xd, 0x20 }, { 0xc, 0x54 }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x4a }, { 0xd, 0x27 }, { 0xc, 0x1d }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x58 }, { 0xd, 0x2f }, { 0xc, 0xc8 }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x5c }, { 0xd, 0x30 }, { 0xc, 0x07 }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x4c }, { 0xd, 0x37 }, { 0xc, 0x90 }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x60 }, { 0xd, 0x3d }, { 0xc, 0xdb }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x64 }, { 0xd, 0x3e }, { 0xc, 0x42 }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x4e }, { 0xd, 0x45 }, { 0xc, 0x78 }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x68 }, { 0xd, 0x4c }, { 0xc, 0x48 }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x6c }, { 0xd, 0x4c }, { 0xc, 0x6c }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x50 }, { 0xd, 0x52 }, { 0xc, 0xe2 }, { WAIT_IDLE },
-{ 0xb, 0x06 }, { 0xa, 0x42 }, { 0xd, 0x02 }, { 0xc, 0xba }, { WAIT_IDLE },
-
-/* Some settings (?) */
-{ WAIT_IDLE }, { 0xe, 0x1e }, { 0xf, 0x14 },
-{ WAIT_IDLE }, { 0xe, 0xde }, { 0xf, 0x20 },
-{ WAIT_IDLE }, { 0xe, 0xdf }, { 0xf, 0x20 },
-
-/* some more coefficients */
-{ WAIT_IDLE }, { 0xb, 0x06 }, { 0xa, 0x78 }, { 0xd, 0x00 }, { 0xc, 0x40 },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x03 }, { 0xd, 0x0f }, { 0xc, 0xff },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x0b }, { 0xd, 0x0f }, { 0xc, 0xff },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x02 }, { 0xd, 0x00 }, { 0xc, 0x00 },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x0a }, { 0xd, 0x00 }, { 0xc, 0x00 },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x46 }, { 0xd, 0x00 }, { 0xc, 0x00 },
-{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x49 }, { 0xd, 0x00 }, { 0xc, 0x00 },
-
-/* Now, for some strange reason, lets reload every page
- and all the coefficients over again. I have *NO* idea
- why this is done. I do know that no sound is produced
- is this phase is omitted. */
-{ 0x9, 0x05 }, { 0xb, 0x00 }, { 0xa, 0x10 },
-
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-
-{ 0x9, 0x05 }, { 0xb, 0x01 }, { 0xa, 0x10 },
-
-{ 0xd, 0x01 }, { 0xc, 0xc0 }, { WAIT_IDLE },
-{ 0xd, 0x01 }, { 0xc, 0xfa }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x1a }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-
-{ WAIT_IDLE }, { WAIT_IDLE },
-
-{ 0x9, 0x05 }, { 0xb, 0x02 }, { 0xa, 0x10 },
-
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x46 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-
-{ 0x9, 0x05 }, { 0xb, 0x03 }, { 0xa, 0x10 },
-
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-
-{ 0x9, 0x05 }, { 0xb, 0x04 }, { 0xa, 0x10 },
-
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xc, 0x00 }, { WAIT_IDLE },
-
-/* Page six v.2 */
-{ 0x9, 0x01 }, { 0xb, 0x06 },
-
-{ 0xa, 0x10 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x12 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x14 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x16 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x18 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x1a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x1c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x1e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x20 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x22 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x24 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x26 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x28 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x2a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x2c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x2e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x30 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x32 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x34 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x36 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x38 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x3a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x3c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xa, 0x3e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-
-{ 0x9, 0x05 }, { 0xb, 0x07 }, { 0xa, 0x10 },
-
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-
-{ 0xe, 0x01 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x02 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x03 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x04 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x05 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x06 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x07 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xb0 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb1 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb2 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb3 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb4 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb5 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb6 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xb7 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf0 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf1 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf2 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf3 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf4 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf5 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf6 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0xf7 }, { 0xf, 0x20 }, { WAIT_IDLE },
-{ 0xe, 0x10 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x11 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x12 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x13 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x14 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x15 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x16 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x17 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x20 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x21 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x22 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x23 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x24 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x25 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x26 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x27 }, { 0xf, 0xff }, { WAIT_IDLE },
-{ 0xe, 0x30 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x31 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x32 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x33 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x34 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x35 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x36 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x37 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x40 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x41 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x42 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x43 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x44 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x45 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x46 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x47 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x50 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x51 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x52 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x53 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x54 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x55 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x56 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x57 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x60 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x61 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x62 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x63 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x64 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x65 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x66 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x67 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x70 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x71 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x72 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x73 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x74 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x75 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x76 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x77 }, { 0xf, 0xc0 }, { WAIT_IDLE },
-{ 0xe, 0x80 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x81 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x82 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x83 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x84 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x85 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x86 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x87 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x90 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x91 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x92 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x93 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x94 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x95 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x96 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x97 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa0 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa1 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa2 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa3 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa4 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa5 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa6 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xa7 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc0 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc1 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc2 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc3 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc4 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc5 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc6 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xc7 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd0 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd1 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd2 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd3 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd4 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd5 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd6 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xd7 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe0 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe1 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe2 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe3 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe4 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe5 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe6 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0xe7 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x00 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x02 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x03 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x04 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x05 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x06 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-{ 0xe, 0x01 }, { 0xf, 0x07 }, { WAIT_IDLE },
-{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE },
-
-{ 0xb, 0x07 }, { 0xa, 0x46 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x49 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x45 }, { 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x48 }, { 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x7b }, { 0xd, 0x04 }, { 0xc, 0xcc }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x7d }, { 0xd, 0x04 }, { 0xc, 0xcc }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x7c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x7e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x46 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x49 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x47 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x4a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE },
-
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0x00 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0x00 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0x28 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0x28 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0x51 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0x51 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0x7a },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0x7a },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0xa3 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0xa3 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0xcc },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0xcc },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0xf5 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0xf5 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x01 }, { 0xc, 0x1e },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x01 }, { 0xc, 0x1e },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x01 }, { 0xc, 0x47 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x01 }, { 0xc, 0x47 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x01 }, { 0xc, 0x70 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x01 }, { 0xc, 0x70 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x01 }, { 0xc, 0x99 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x01 }, { 0xc, 0x99 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x01 }, { 0xc, 0xc2 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x01 }, { 0xc, 0xc2 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x01 }, { 0xc, 0xeb },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x01 }, { 0xc, 0xeb },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x02 }, { 0xc, 0x14 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x02 }, { 0xc, 0x14 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x02 }, { 0xc, 0x3d },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x02 }, { 0xc, 0x3d },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x02 }, { 0xc, 0x66 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x02 }, { 0xc, 0x66 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x02 }, { 0xc, 0x8f },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x02 }, { 0xc, 0x8f },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x02 }, { 0xc, 0xb8 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x02 }, { 0xc, 0xb8 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x02 }, { 0xc, 0xe1 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x02 }, { 0xc, 0xe1 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x03 }, { 0xc, 0x0a },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x03 }, { 0xc, 0x0a },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x03 }, { 0xc, 0x33 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x03 }, { 0xc, 0x33 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x03 }, { 0xc, 0x5c },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x03 }, { 0xc, 0x5c },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x03 }, { 0xc, 0x85 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x03 }, { 0xc, 0x85 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x03 }, { 0xc, 0xae },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x03 }, { 0xc, 0xae },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x03 }, { 0xc, 0xd7 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x03 }, { 0xc, 0xd7 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0x00 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0x00 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0x28 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0x28 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0x51 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0x51 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0x7a },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0x7a },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0xa3 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0xa3 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0xcc },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0xcc },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0xf5 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0xf5 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x05 }, { 0xc, 0x1e },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x05 }, { 0xc, 0x1e },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x05 }, { 0xc, 0x47 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x05 }, { 0xc, 0x47 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x05 }, { 0xc, 0x70 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x05 }, { 0xc, 0x70 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x05 }, { 0xc, 0x99 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x05 }, { 0xc, 0x99 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x05 }, { 0xc, 0xc2 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x05 }, { 0xc, 0xc2 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x05 }, { 0xc, 0xeb },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x05 }, { 0xc, 0xeb },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x06 }, { 0xc, 0x14 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x06 }, { 0xc, 0x14 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x06 }, { 0xc, 0x3d },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x06 }, { 0xc, 0x3d },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x06 }, { 0xc, 0x66 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x06 }, { 0xc, 0x66 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x06 }, { 0xc, 0x8f },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x06 }, { 0xc, 0x8f },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x06 }, { 0xc, 0xb8 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x06 }, { 0xc, 0xb8 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x06 }, { 0xc, 0xe1 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x06 }, { 0xc, 0xe1 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x07 }, { 0xc, 0x0a },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x07 }, { 0xc, 0x0a },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x07 }, { 0xc, 0x33 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x07 }, { 0xc, 0x33 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x07 }, { 0xc, 0x5c },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x07 }, { 0xc, 0x5c },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x07 }, { 0xc, 0x85 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x07 }, { 0xc, 0x85 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x07 }, { 0xc, 0xae },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x07 }, { 0xc, 0xae },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x07 }, { 0xc, 0xd7 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x07 }, { 0xc, 0xd7 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0x00 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0x00 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0x28 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0x28 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0x51 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0x51 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0x7a },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0x7a },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0xa3 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0xa3 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0xcc },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0xcc },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0xf5 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0xf5 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x09 }, { 0xc, 0x1e },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x09 }, { 0xc, 0x1e },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x09 }, { 0xc, 0x47 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x09 }, { 0xc, 0x47 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x09 }, { 0xc, 0x70 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x09 }, { 0xc, 0x70 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x09 }, { 0xc, 0x99 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x09 }, { 0xc, 0x99 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x09 }, { 0xc, 0xc2 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x09 }, { 0xc, 0xc2 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x09 }, { 0xc, 0xeb },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x09 }, { 0xc, 0xeb },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0a }, { 0xc, 0x14 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0a }, { 0xc, 0x14 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0a }, { 0xc, 0x3d },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0a }, { 0xc, 0x3d },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0a }, { 0xc, 0x66 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0a }, { 0xc, 0x66 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0a }, { 0xc, 0x8f },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0a }, { 0xc, 0x8f },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0a }, { 0xc, 0xb8 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0a }, { 0xc, 0xb8 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0a }, { 0xc, 0xe1 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0a }, { 0xc, 0xe1 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0b }, { 0xc, 0x0a },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0b }, { 0xc, 0x0a },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0b }, { 0xc, 0x33 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0b }, { 0xc, 0x33 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0b }, { 0xc, 0x5c },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0b }, { 0xc, 0x5c },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0b }, { 0xc, 0x85 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0b }, { 0xc, 0x85 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0b }, { 0xc, 0xae },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0b }, { 0xc, 0xae },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0b }, { 0xc, 0xd7 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0b }, { 0xc, 0xd7 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0x00 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0x00 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0x28 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0x28 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0x51 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0x51 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0x7a },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0x7a },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0xa3 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0xa3 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0xcc },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0xcc },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0xf5 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0xf5 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0d }, { 0xc, 0x1e },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0d }, { 0xc, 0x1e },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0d }, { 0xc, 0x47 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0d }, { 0xc, 0x47 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0d }, { 0xc, 0x70 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0d }, { 0xc, 0x70 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0d }, { 0xc, 0x99 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0d }, { 0xc, 0x99 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0d }, { 0xc, 0xc2 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0d }, { 0xc, 0xc2 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0d }, { 0xc, 0xeb },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0d }, { 0xc, 0xeb },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0e }, { 0xc, 0x14 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0e }, { 0xc, 0x14 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0e }, { 0xc, 0x3d },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0e }, { 0xc, 0x3d },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0e }, { 0xc, 0x66 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0e }, { 0xc, 0x66 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0e }, { 0xc, 0x8f },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0e }, { 0xc, 0x8f },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0e }, { 0xc, 0xb8 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0e }, { 0xc, 0xb8 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0e }, { 0xc, 0xe1 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0e }, { 0xc, 0xe1 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0x0a },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0x0a },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0x33 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0x33 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0x5c },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0x5c },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0x85 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0x85 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0xae },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0xae },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0xd7 },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0xd7 },
-{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0xff },
-{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0xff },
-
-/* mute off */
-{ 0x8, 0x00 }, { WAIT_IDLE }
-};
diff --git a/sound/oss/pss.c b/sound/oss/pss.c
index 16517a5a130..83f5ee236b1 100644
--- a/sound/oss/pss.c
+++ b/sound/oss/pss.c
@@ -46,7 +46,7 @@
* load the driver as it did in previous versions.
* 04-07-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
* Added module parameter pss_firmware to allow the user to tell
- * the driver where the fireware file is located. The default
+ * the driver where the firmware file is located. The default
* setting is the previous hardcoded setting "/etc/sound/pss_synth".
* 00-03-03: Christoph Hellwig <chhellwig@infradead.org>
* Adapted to module_init/module_exit
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index d1f242bd0ac..8f5098f92c3 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -909,8 +909,8 @@ snd_ad1889_create(struct snd_card *card,
return err;
/* check PCI availability (32bit DMA) */
- if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) {
printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 4edf270a780..c551006e292 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -2186,8 +2186,8 @@ static int __devinit snd_ali_create(struct snd_card *card,
if (err < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 31 bits */
- if (pci_set_dma_mask(pci, DMA_31BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_31BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(31)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(31)) < 0) {
snd_printk(KERN_ERR "architecture does not support "
"31bit PCI busmaster DMA\n");
pci_disable_device(pci);
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 009b4c8225a..3aa35af7ca9 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -689,8 +689,8 @@ static int __devinit snd_als300_create(struct snd_card *card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
printk(KERN_ERR "error setting 28bit DMA mask\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 542a0c65a92..3dbacde1a5a 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -872,8 +872,8 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
return err;
}
/* check, if we can restrict PCI DMA transfers to 24 bits */
- if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) {
snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 9ec122383ee..7b72c88e449 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -151,8 +151,8 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
// check PCI availability (DMA).
if ((err = pci_enable_device(pci)) < 0)
return err;
- if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) {
printk(KERN_ERR "error to set DMA mask\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index 8eea29fc42f..4d34bb0d99d 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -279,8 +279,8 @@ static int __devinit snd_aw2_create(struct snd_card *card,
pci_set_master(pci);
/* check PCI availability (32bit DMA) */
- if ((pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) ||
- (pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0)) {
+ if ((pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0) ||
+ (pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0)) {
printk(KERN_ERR "aw2: Impossible to set 32bit mask DMA\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index e9e9b5821d4..f290bc56178 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2125,8 +2125,8 @@ snd_azf3328_create(struct snd_card *card,
chip->irq = -1;
/* check if we can restrict PCI DMA transfers to 24 bits */
- if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) {
snd_printk(KERN_ERR "architecture does not support "
"24bit PCI busmaster DMA\n"
);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index df757575798..bfac30f7929 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1589,8 +1589,8 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
err = pci_enable_device(pci);
if (err < 0)
return err;
- if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) {
printk(KERN_ERR "error to set 32bit mask DMA\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index c89ed1f5bc2..05f56e04849 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -285,8 +285,8 @@ static int __devinit snd_cs5535audio_create(struct snd_card *card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) < 0) {
printk(KERN_WARNING "unable to get 32bit dma\n");
err = -ENXIO;
goto pcifail;
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 31542adc6b7..1970f0e70f3 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -897,8 +897,8 @@ static int __devinit snd_emu10k1x_create(struct snd_card *card,
if ((err = pci_enable_device(pci)) < 0)
return err;
- if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
snd_printk(KERN_ERR "error to set 28bit mask DMA\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index dd63b132fb8..fbd2ac09aa3 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1608,8 +1608,8 @@ static int __devinit snd_es1938_create(struct snd_card *card,
if ((err = pci_enable_device(pci)) < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 24 bits */
- if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) {
snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index dc97e811614..a11f453a6b6 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -2539,8 +2539,8 @@ static int __devinit snd_es1968_create(struct snd_card *card,
if ((err = pci_enable_device(pci)) < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 28 bits */
- if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 30829ee920c..7ba8db5d4c4 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2260,11 +2260,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
gcap &= ~0x01;
/* allow 64bit DMA address if supported by H/W */
- if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK))
- pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK);
+ if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
else {
- pci_set_dma_mask(pci, DMA_32BIT_MASK);
- pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK);
+ pci_set_dma_mask(pci, DMA_BIT_MASK(32));
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32));
}
/* read number of streams from GCAP register instead of using
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 5bb48ee8b6c..38ad3f7b040 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -3256,7 +3256,7 @@ static const char *ad1884_slave_vols[] = {
"Mic Playback Volume",
"CD Playback Volume",
"Internal Mic Playback Volume",
- "Docking Mic Playback Volume"
+ "Docking Mic Playback Volume",
/* "Beep Playback Volume", */
"IEC958 Playback Volume",
NULL
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 82097790f6f..f35e58a2d92 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -8764,6 +8764,10 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
{}
};
+static hda_nid_t alc883_slave_dig_outs[] = {
+ ALC1200_DIGOUT_NID, 0,
+};
+
static hda_nid_t alc1200_slave_dig_outs[] = {
ALC883_DIGOUT_NID, 0,
};
@@ -8809,6 +8813,7 @@ static struct alc_config_preset alc883_presets[] = {
.dac_nids = alc883_dac_nids,
.dig_out_nid = ALC883_DIGOUT_NID,
.dig_in_nid = ALC883_DIGIN_NID,
+ .slave_dig_outs = alc883_slave_dig_outs,
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
.channel_mode = alc883_3ST_6ch_intel_modes,
.need_dac_fix = 1,
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index b5e108aa8f6..61996a2f45d 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4413,6 +4413,24 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
if (spec->num_pwrs > 0)
stac92xx_pin_sense(codec, event->nid);
stac92xx_report_jack(codec, event->nid);
+
+ switch (codec->subsystem_id) {
+ case 0x103c308f:
+ if (event->nid == 0xb) {
+ int pin = AC_PINCTL_IN_EN;
+
+ if (get_pin_presence(codec, 0xa)
+ && get_pin_presence(codec, 0xb))
+ pin |= AC_PINCTL_VREF_80;
+ if (!get_pin_presence(codec, 0xb))
+ pin |= AC_PINCTL_VREF_80;
+
+ /* toggle VREF state based on mic + hp pin
+ * status
+ */
+ stac92xx_auto_set_pinctl(codec, 0x0a, pin);
+ }
+ }
break;
case STAC_VREF_EVENT:
data = snd_hda_codec_read(codec, codec->afg, 0,
@@ -4895,6 +4913,7 @@ again:
switch (codec->vendor_id) {
case 0x111d7604:
case 0x111d7605:
+ case 0x111d76d5:
if (spec->board_config == STAC_92HD83XXX_PWR_REF)
break;
spec->num_pwrs = 0;
@@ -5707,6 +5726,7 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
{ .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
{ .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
{ .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
+ { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx},
{ .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
{ .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
{ .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 3dd63f1cda5..0d0cdbdb448 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2533,8 +2533,8 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
if (err < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 28 bits */
- if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 70141548f25..75283fbb4b3 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -2530,8 +2530,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
return -EIO;
/* check, if we can restrict PCI DMA transfers to 28 bits */
- if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index c1eb84a14c4..82bc5b9e762 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1291,7 +1291,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
pci_set_master(pci);
/* check if we can restrict PCI DMA transfers to 32 bits */
- if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0) {
snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 80e064a3eff..833e9c7b27c 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1449,7 +1449,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci,
pci_set_master(pci);
/* check if we can restrict PCI DMA transfers to 32 bits */
- if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) < 0) {
snd_printk(KERN_ERR "architecture does not support "
"32bit PCI busmaster DMA\n");
pci_disable_device(pci);
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index baf6d8e3dab..1a5ff061107 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -1300,7 +1300,7 @@ static int __devinit sis_chip_create(struct snd_card *card,
if (rc)
goto error_out;
- if (pci_set_dma_mask(pci, DMA_30BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0) {
printk(KERN_ERR "sis7019: architecture does not support "
"30-bit PCI busmaster DMA");
goto error_out_enabled;
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index d989215f355..7dc60ad4772 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -1264,8 +1264,8 @@ static int __devinit snd_sonicvibes_create(struct snd_card *card,
if ((err = pci_enable_device(pci)) < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 24 bits */
- if (pci_set_dma_mask(pci, DMA_24BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_24BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) {
snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index a9da9c18466..6d943f6f6b7 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -3559,8 +3559,8 @@ int __devinit snd_trident_create(struct snd_card *card,
if ((err = pci_enable_device(pci)) < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 30 bits */
- if (pci_set_dma_mask(pci, DMA_30BIT_MASK) < 0 ||
- pci_set_consistent_dma_mask(pci, DMA_30BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0 ||
+ pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(30)) < 0) {
snd_printk(KERN_ERR "architecture does not support 30bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index 5a929069dce..a2b69b8cff4 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -51,7 +51,7 @@ static struct platform_device *device;
/*
*/
-static int __init snd_pmac_probe(struct platform_device *devptr)
+static int __devinit snd_pmac_probe(struct platform_device *devptr)
{
struct snd_card *card;
struct snd_pmac *chip;
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index f551233c5a0..583a3693df7 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -565,7 +565,7 @@ static int load_aica_firmware(void)
err = request_firmware(&fw_entry, "aica_firmware.bin", &pd->dev);
if (unlikely(err))
return err;
- /* write firware into memory */
+ /* write firmware into memory */
spu_disable();
spu_memload(0, fw_entry->data, fw_entry->size);
spu_enable();
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index 0a2f8f9eff5..811596f4c09 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -42,7 +42,7 @@ config SND_BF5XX_AC97
You will also need to select the audio interfaces to support below.
Note:
- AC97 codecs which do not implment the slot-16 mode will not function
+ AC97 codecs which do not implement the slot-16 mode will not function
properly with this driver. This driver is known to work with the
Analog Devices line of AC97 codecs.
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 8cfed1a5dcb..cf0dfb7ca22 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -413,7 +413,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
sport_done(sport_handle);
}
-static u64 bf5xx_pcm_dmamask = DMA_32BIT_MASK;
+static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
int bf5xx_pcm_ac97_new(struct snd_card *card, struct snd_soc_dai *dai,
struct snd_pcm *pcm)
@@ -424,7 +424,7 @@ int bf5xx_pcm_ac97_new(struct snd_card *card, struct snd_soc_dai *dai,
if (!card->dev->dma_mask)
card->dev->dma_mask = &bf5xx_pcm_dmamask;
if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_32BIT_MASK;
+ card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
if (dai->playback.channels_min) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 1318c4f627b..62fbb845956 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -245,7 +245,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
sport_done(sport_handle);
}
-static u64 bf5xx_pcm_dmamask = DMA_32BIT_MASK;
+static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
int bf5xx_pcm_i2s_new(struct snd_card *card, struct snd_soc_dai *dai,
struct snd_pcm *pcm)
@@ -256,7 +256,7 @@ int bf5xx_pcm_i2s_new(struct snd_card *card, struct snd_soc_dai *dai,
if (!card->dev->dma_mask)
card->dev->dma_mask = &bf5xx_pcm_dmamask;
if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_32BIT_MASK;
+ card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
if (dai->playback.channels_min) {
ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 1f63d387a2f..dd338020276 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -659,7 +659,8 @@ static int ak4535_remove(struct platform_device *pdev)
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_unregister_device(codec->control_data);
+ if (codec->control_data)
+ i2c_unregister_device(codec->control_data);
i2c_del_driver(&ak4535_i2c_driver);
#endif
kfree(codec->private_data);
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 97738e2ece0..921b205de28 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -122,6 +122,9 @@ struct twl4030_priv {
unsigned int bypass_state;
unsigned int codec_powered;
unsigned int codec_muted;
+
+ struct snd_pcm_substream *master_substream;
+ struct snd_pcm_substream *slave_substream;
};
/*
@@ -1217,6 +1220,52 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
+static int twl4030_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_device *socdev = rtd->socdev;
+ struct snd_soc_codec *codec = socdev->card->codec;
+ struct twl4030_priv *twl4030 = codec->private_data;
+
+ /* If we already have a playback or capture going then constrain
+ * this substream to match it.
+ */
+ if (twl4030->master_substream) {
+ struct snd_pcm_runtime *master_runtime;
+ master_runtime = twl4030->master_substream->runtime;
+
+ snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_RATE,
+ master_runtime->rate,
+ master_runtime->rate);
+
+ snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+ master_runtime->sample_bits,
+ master_runtime->sample_bits);
+
+ twl4030->slave_substream = substream;
+ } else
+ twl4030->master_substream = substream;
+
+ return 0;
+}
+
+static void twl4030_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_device *socdev = rtd->socdev;
+ struct snd_soc_codec *codec = socdev->card->codec;
+ struct twl4030_priv *twl4030 = codec->private_data;
+
+ if (twl4030->master_substream == substream)
+ twl4030->master_substream = twl4030->slave_substream;
+
+ twl4030->slave_substream = NULL;
+}
+
static int twl4030_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -1224,8 +1273,13 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_device *socdev = rtd->socdev;
struct snd_soc_codec *codec = socdev->card->codec;
+ struct twl4030_priv *twl4030 = codec->private_data;
u8 mode, old_mode, format, old_format;
+ if (substream == twl4030->slave_substream)
+ /* Ignoring hw_params for slave substream */
+ return 0;
+
/* bit rate */
old_mode = twl4030_read_reg_cache(codec,
TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
@@ -1259,6 +1313,9 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
case 48000:
mode |= TWL4030_APLL_RATE_48000;
break;
+ case 96000:
+ mode |= TWL4030_APLL_RATE_96000;
+ break;
default:
printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n",
params_rate(params));
@@ -1384,6 +1441,8 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
static struct snd_soc_dai_ops twl4030_dai_ops = {
+ .startup = twl4030_startup,
+ .shutdown = twl4030_shutdown,
.hw_params = twl4030_hw_params,
.set_sysclk = twl4030_set_dai_sysclk,
.set_fmt = twl4030_set_dai_fmt,
@@ -1395,7 +1454,7 @@ struct snd_soc_dai twl4030_dai = {
.stream_name = "Playback",
.channels_min = 2,
.channels_max = 2,
- .rates = TWL4030_RATES,
+ .rates = TWL4030_RATES | SNDRV_PCM_RATE_96000,
.formats = TWL4030_FORMATS,},
.capture = {
.stream_name = "Capture",
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index 33dbb144dad..cb63765db1d 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -109,6 +109,7 @@
#define TWL4030_APLL_RATE_32000 0x80
#define TWL4030_APLL_RATE_44100 0x90
#define TWL4030_APLL_RATE_48000 0xA0
+#define TWL4030_APLL_RATE_96000 0xE0
#define TWL4030_SEL_16K 0x04
#define TWL4030_CODECPDZ 0x02
#define TWL4030_OPT_MODE 0x01
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 3265817c5c2..6e23a81dba7 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -317,6 +317,41 @@ static int wm9705_reset(struct snd_soc_codec *codec)
return -EIO;
}
+#ifdef CONFIG_PM
+static int wm9705_soc_suspend(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+
+ soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff);
+
+ return 0;
+}
+
+static int wm9705_soc_resume(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+ int i, ret;
+ u16 *cache = codec->reg_cache;
+
+ ret = wm9705_reset(codec);
+ if (ret < 0) {
+ printk(KERN_ERR "could not reset AC97 codec\n");
+ return ret;
+ }
+
+ for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) {
+ soc_ac97_ops.write(codec->ac97, i, cache[i>>1]);
+ }
+
+ return 0;
+}
+#else
+#define wm9705_soc_suspend NULL
+#define wm9705_soc_resume NULL
+#endif
+
static int wm9705_soc_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -407,6 +442,8 @@ static int wm9705_soc_remove(struct platform_device *pdev)
struct snd_soc_codec_device soc_codec_dev_wm9705 = {
.probe = wm9705_soc_probe,
.remove = wm9705_soc_remove,
+ .suspend = wm9705_soc_suspend,
+ .resume = wm9705_soc_resume,
};
EXPORT_SYMBOL_GPL(soc_codec_dev_wm9705);
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index b3eb8570cd7..b1a3a278819 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -300,7 +300,7 @@ static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = fsl_dma_dmamask;
- ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->dev,
+ ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
fsl_dma_hardware.buffer_bytes_max,
&pcm->streams[0].substream->dma_buffer);
if (ret) {
@@ -310,7 +310,7 @@ static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
return -ENOMEM;
}
- ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->dev,
+ ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
fsl_dma_hardware.buffer_bytes_max,
&pcm->streams[1].substream->dma_buffer);
if (ret) {
@@ -418,7 +418,7 @@ static int fsl_dma_open(struct snd_pcm_substream *substream)
return -EBUSY;
}
- dma_private = dma_alloc_coherent(substream->pcm->dev,
+ dma_private = dma_alloc_coherent(substream->pcm->card->dev,
sizeof(struct fsl_dma_private), &ld_buf_phys, GFP_KERNEL);
if (!dma_private) {
dev_err(substream->pcm->card->dev,
@@ -445,7 +445,7 @@ static int fsl_dma_open(struct snd_pcm_substream *substream)
dev_err(substream->pcm->card->dev,
"can't register ISR for IRQ %u (ret=%i)\n",
dma_private->irq, ret);
- dma_free_coherent(substream->pcm->dev,
+ dma_free_coherent(substream->pcm->card->dev,
sizeof(struct fsl_dma_private),
dma_private, dma_private->ld_buf_phys);
return ret;
@@ -697,6 +697,23 @@ static snd_pcm_uframes_t fsl_dma_pointer(struct snd_pcm_substream *substream)
else
position = in_be32(&dma_channel->dar);
+ /*
+ * When capture is started, the SSI immediately starts to fill its FIFO.
+ * This means that the DMA controller is not started until the FIFO is
+ * full. However, ALSA calls this function before that happens, when
+ * MR.DAR is still zero. In this case, just return zero to indicate
+ * that nothing has been received yet.
+ */
+ if (!position)
+ return 0;
+
+ if ((position < dma_private->dma_buf_phys) ||
+ (position > dma_private->dma_buf_end)) {
+ dev_err(substream->pcm->card->dev,
+ "dma pointer is out of range, halting stream\n");
+ return SNDRV_PCM_POS_XRUN;
+ }
+
frames = bytes_to_frames(runtime, position - dma_private->dma_buf_phys);
/*
@@ -761,13 +778,13 @@ static int fsl_dma_close(struct snd_pcm_substream *substream)
free_irq(dma_private->irq, dma_private);
if (dma_private->ld_buf_phys) {
- dma_unmap_single(substream->pcm->dev,
+ dma_unmap_single(substream->pcm->card->dev,
dma_private->ld_buf_phys,
sizeof(dma_private->link), DMA_TO_DEVICE);
}
/* Deallocate the fsl_dma_private structure */
- dma_free_coherent(substream->pcm->dev,
+ dma_free_coherent(substream->pcm->card->dev,
sizeof(struct fsl_dma_private),
dma_private, dma_private->ld_buf_phys);
substream->runtime->private_data = NULL;
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 169bca295b7..3711d8454d9 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -60,6 +60,13 @@
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
#endif
+/* SIER bitflag of interrupts to enable */
+#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \
+ CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | \
+ CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | \
+ CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \
+ CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN)
+
/**
* fsl_ssi_private: per-SSI private data
*
@@ -140,7 +147,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
were interrupted for. We mask it with the Interrupt Enable register
so that we only check for events that we're interested in.
*/
- sisr = in_be32(&ssi->sisr) & in_be32(&ssi->sier);
+ sisr = in_be32(&ssi->sisr) & SIER_FLAGS;
if (sisr & CCSR_SSI_SISR_RFRC) {
ssi_private->stats.rfrc++;
@@ -324,12 +331,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
*/
/* 4. Enable the interrupts and DMA requests */
- out_be32(&ssi->sier,
- CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE |
- CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN |
- CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN |
- CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE |
- CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN);
+ out_be32(&ssi->sier, SIER_FLAGS);
/*
* Set the watermark for transmit FIFI 0 and receive FIFO 0. We
@@ -466,28 +468,12 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_START:
clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
setbits32(&ssi->scr,
CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
- } else {
- long timeout = jiffies + 10;
-
+ else
setbits32(&ssi->scr,
CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
-
- /* Wait until the SSI has filled its FIFO. Without this
- * delay, ALSA complains about overruns. When the FIFO
- * is full, the DMA controller initiates its first
- * transfer. Until then, however, the DMA's DAR
- * register is zero, which translates to an
- * out-of-bounds pointer. This makes ALSA think an
- * overrun has occurred.
- */
- while (!(in_be32(&ssi->sisr) & CCSR_SSI_SISR_RFF0) &&
- (jiffies < timeout));
- if (!(in_be32(&ssi->sisr) & CCSR_SSI_SISR_RFF0))
- return -EIO;
- }
break;
case SNDRV_PCM_TRIGGER_STOP:
@@ -606,39 +592,52 @@ static struct snd_soc_dai fsl_ssi_dai_template = {
.ops = &fsl_ssi_dai_ops,
};
+/* Show the statistics of a flag only if its interrupt is enabled. The
+ * compiler will optimze this code to a no-op if the interrupt is not
+ * enabled.
+ */
+#define SIER_SHOW(flag, name) \
+ do { \
+ if (SIER_FLAGS & CCSR_SSI_SIER_##flag) \
+ length += sprintf(buf + length, #name "=%u\n", \
+ ssi_private->stats.name); \
+ } while (0)
+
+
/**
* fsl_sysfs_ssi_show: display SSI statistics
*
- * Display the statistics for the current SSI device.
+ * Display the statistics for the current SSI device. To avoid confusion,
+ * we only show those counts that are enabled.
*/
static ssize_t fsl_sysfs_ssi_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct fsl_ssi_private *ssi_private =
- container_of(attr, struct fsl_ssi_private, dev_attr);
- ssize_t length;
-
- length = sprintf(buf, "rfrc=%u", ssi_private->stats.rfrc);
- length += sprintf(buf + length, "\ttfrc=%u", ssi_private->stats.tfrc);
- length += sprintf(buf + length, "\tcmdau=%u", ssi_private->stats.cmdau);
- length += sprintf(buf + length, "\tcmddu=%u", ssi_private->stats.cmddu);
- length += sprintf(buf + length, "\trxt=%u", ssi_private->stats.rxt);
- length += sprintf(buf + length, "\trdr1=%u", ssi_private->stats.rdr1);
- length += sprintf(buf + length, "\trdr0=%u", ssi_private->stats.rdr0);
- length += sprintf(buf + length, "\ttde1=%u", ssi_private->stats.tde1);
- length += sprintf(buf + length, "\ttde0=%u", ssi_private->stats.tde0);
- length += sprintf(buf + length, "\troe1=%u", ssi_private->stats.roe1);
- length += sprintf(buf + length, "\troe0=%u", ssi_private->stats.roe0);
- length += sprintf(buf + length, "\ttue1=%u", ssi_private->stats.tue1);
- length += sprintf(buf + length, "\ttue0=%u", ssi_private->stats.tue0);
- length += sprintf(buf + length, "\ttfs=%u", ssi_private->stats.tfs);
- length += sprintf(buf + length, "\trfs=%u", ssi_private->stats.rfs);
- length += sprintf(buf + length, "\ttls=%u", ssi_private->stats.tls);
- length += sprintf(buf + length, "\trls=%u", ssi_private->stats.rls);
- length += sprintf(buf + length, "\trff1=%u", ssi_private->stats.rff1);
- length += sprintf(buf + length, "\trff0=%u", ssi_private->stats.rff0);
- length += sprintf(buf + length, "\ttfe1=%u", ssi_private->stats.tfe1);
- length += sprintf(buf + length, "\ttfe0=%u\n", ssi_private->stats.tfe0);
+ container_of(attr, struct fsl_ssi_private, dev_attr);
+ ssize_t length = 0;
+
+ SIER_SHOW(RFRC_EN, rfrc);
+ SIER_SHOW(TFRC_EN, tfrc);
+ SIER_SHOW(CMDAU_EN, cmdau);
+ SIER_SHOW(CMDDU_EN, cmddu);
+ SIER_SHOW(RXT_EN, rxt);
+ SIER_SHOW(RDR1_EN, rdr1);
+ SIER_SHOW(RDR0_EN, rdr0);
+ SIER_SHOW(TDE1_EN, tde1);
+ SIER_SHOW(TDE0_EN, tde0);
+ SIER_SHOW(ROE1_EN, roe1);
+ SIER_SHOW(ROE0_EN, roe0);
+ SIER_SHOW(TUE1_EN, tue1);
+ SIER_SHOW(TUE0_EN, tue0);
+ SIER_SHOW(TFS_EN, tfs);
+ SIER_SHOW(RFS_EN, rfs);
+ SIER_SHOW(TLS_EN, tls);
+ SIER_SHOW(RLS_EN, rls);
+ SIER_SHOW(RFF1_EN, rff1);
+ SIER_SHOW(RFF0_EN, rff0);
+ SIER_SHOW(TFE1_EN, tfe1);
+ SIER_SHOW(TFE0_EN, tfe0);
return length;
}
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index d6882be3345..9c09b94f0cf 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -146,6 +146,17 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
int err = 0;
+ if (cpu_is_omap343x() && mcbsp_data->bus_id == 1) {
+ /*
+ * McBSP2 in OMAP3 has 1024 * 32-bit internal audio buffer.
+ * Set constraint for minimum buffer size to the same than FIFO
+ * size in order to avoid underruns in playback startup because
+ * HW is keeping the DMA request active until FIFO is filled.
+ */
+ snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4096, UINT_MAX);
+ }
+
if (!cpu_dai->active)
err = omap_mcbsp_request(mcbsp_data->bus_id);
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 8e1431cb46b..1bdbb042718 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -327,7 +327,7 @@ int omap_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
if (!card->dev->dma_mask)
card->dev->dma_mask = &omap_pcm_dmamask;
if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_32BIT_MASK;
+ card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
if (dai->playback.channels_min) {
ret = omap_pcm_preallocate_dma_buffer(pcm,
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 5998ab366e8..ad8a10fe629 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -116,6 +116,16 @@ config SND_SOC_ZYLONITE
Say Y if you want to add support for SoC audio on the
Marvell Zylonite reference platform.
+config SND_PXA2XX_SOC_MAGICIAN
+ tristate "SoC Audio support for HTC Magician"
+ depends on SND_PXA2XX_SOC && MACH_MAGICIAN
+ select SND_PXA2XX_SOC_I2S
+ select SND_PXA_SOC_SSP
+ select SND_SOC_UDA1380
+ help
+ Say Y if you want to add support for SoC audio on the
+ HTC Magician.
+
config SND_PXA2XX_SOC_MIOA701
tristate "SoC Audio support for MIO A701"
depends on SND_PXA2XX_SOC && MACH_MIOA701
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 8ed881c5e5c..4b90c3ccae4 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -20,6 +20,7 @@ snd-soc-spitz-objs := spitz.o
snd-soc-em-x270-objs := em-x270.o
snd-soc-palm27x-objs := palm27x.o
snd-soc-zylonite-objs := zylonite.o
+snd-soc-magician-objs := magician.o
snd-soc-mioa701-objs := mioa701_wm9713.o
obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
@@ -31,5 +32,6 @@ obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o
obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o
obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
+obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
new file mode 100644
index 00000000000..f7c4544f785
--- /dev/null
+++ b/sound/soc/pxa/magician.c
@@ -0,0 +1,560 @@
+/*
+ * SoC audio for HTC Magician
+ *
+ * Copyright (c) 2006 Philipp Zabel <philipp.zabel@gmail.com>
+ *
+ * based on spitz.c,
+ * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
+ * Richard Purdie <richard@openedhand.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <mach/pxa-regs.h>
+#include <mach/hardware.h>
+#include <mach/magician.h>
+#include <asm/mach-types.h>
+#include "../codecs/uda1380.h"
+#include "pxa2xx-pcm.h"
+#include "pxa2xx-i2s.h"
+#include "pxa-ssp.h"
+
+#define MAGICIAN_MIC 0
+#define MAGICIAN_MIC_EXT 1
+
+static int magician_hp_switch;
+static int magician_spk_switch = 1;
+static int magician_in_sel = MAGICIAN_MIC;
+
+static void magician_ext_control(struct snd_soc_codec *codec)
+{
+ if (magician_spk_switch)
+ snd_soc_dapm_enable_pin(codec, "Speaker");
+ else
+ snd_soc_dapm_disable_pin(codec, "Speaker");
+ if (magician_hp_switch)
+ snd_soc_dapm_enable_pin(codec, "Headphone Jack");
+ else
+ snd_soc_dapm_disable_pin(codec, "Headphone Jack");
+
+ switch (magician_in_sel) {
+ case MAGICIAN_MIC:
+ snd_soc_dapm_disable_pin(codec, "Headset Mic");
+ snd_soc_dapm_enable_pin(codec, "Call Mic");
+ break;
+ case MAGICIAN_MIC_EXT:
+ snd_soc_dapm_disable_pin(codec, "Call Mic");
+ snd_soc_dapm_enable_pin(codec, "Headset Mic");
+ break;
+ }
+
+ snd_soc_dapm_sync(codec);
+}
+
+static int magician_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->socdev->card->codec;
+
+ /* check the jack status at stream startup */
+ magician_ext_control(codec);
+
+ return 0;
+}
+
+/*
+ * Magician uses SSP port for playback.
+ */
+static int magician_playback_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ unsigned int acps, acds, width, rate;
+ unsigned int div4 = PXA_SSP_CLK_SCDB_4;
+ int ret = 0;
+
+ rate = params_rate(params);
+ width = snd_pcm_format_physical_width(params_format(params));
+
+ /*
+ * rate = SSPSCLK / (2 * width(16 or 32))
+ * SSPSCLK = (ACPS / ACDS) / SSPSCLKDIV(div4 or div1)
+ */
+ switch (params_rate(params)) {
+ case 8000:
+ /* off by a factor of 2: bug in the PXA27x audio clock? */
+ acps = 32842000;
+ switch (width) {
+ case 16:
+ /* 513156 Hz ~= _2_ * 8000 Hz * 32 (+0.23%) */
+ acds = PXA_SSP_CLK_AUDIO_DIV_16;
+ break;
+ case 32:
+ /* 1026312 Hz ~= _2_ * 8000 Hz * 64 (+0.23%) */
+ acds = PXA_SSP_CLK_AUDIO_DIV_8;
+ }
+ break;
+ case 11025:
+ acps = 5622000;
+ switch (width) {
+ case 16:
+ /* 351375 Hz ~= 11025 Hz * 32 (-0.41%) */
+ acds = PXA_SSP_CLK_AUDIO_DIV_4;
+ break;
+ case 32:
+ /* 702750 Hz ~= 11025 Hz * 64 (-0.41%) */
+ acds = PXA_SSP_CLK_AUDIO_DIV_2;
+ }
+ break;
+ case 22050:
+ acps = 5622000;
+ switch (width) {
+ case 16:
+ /* 702750 Hz ~= 22050 Hz * 32 (-0.41%) */
+ acds = PXA_SSP_CLK_AUDIO_DIV_2;
+ break;
+ case 32:
+ /* 1405500 Hz ~= 22050 Hz * 64 (-0.41%) */
+ acds = PXA_SSP_CLK_AUDIO_DIV_1;
+ }
+ break;
+ case 44100:
+ acps = 5622000;
+ switch (width) {
+ case 16:
+ /* 1405500 Hz ~= 44100 Hz * 32 (-0.41%) */
+ acds = PXA_SSP_CLK_AUDIO_DIV_2;
+ break;
+ case 32:
+ /* 2811000 Hz ~= 44100 Hz * 64 (-0.41%) */
+ acds = PXA_SSP_CLK_AUDIO_DIV_1;
+ }
+ break;
+ case 48000:
+ acps = 12235000;
+ switch (width) {
+ case 16:
+ /* 1529375 Hz ~= 48000 Hz * 32 (-0.44%) */
+ acds = PXA_SSP_CLK_AUDIO_DIV_2;
+ break;
+ case 32:
+ /* 3058750 Hz ~= 48000 Hz * 64 (-0.44%) */
+ acds = PXA_SSP_CLK_AUDIO_DIV_1;
+ }
+ break;
+ case 96000:
+ acps = 12235000;
+ switch (width) {
+ case 16:
+ /* 3058750 Hz ~= 96000 Hz * 32 (-0.44%) */
+ acds = PXA_SSP_CLK_AUDIO_DIV_1;
+ break;
+ case 32:
+ /* 6117500 Hz ~= 96000 Hz * 64 (-0.44%) */
+ acds = PXA_SSP_CLK_AUDIO_DIV_2;
+ div4 = PXA_SSP_CLK_SCDB_1;
+ break;
+ }
+ break;
+ }
+
+ /* set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_MSB |
+ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ return ret;
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
+ SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 1, 1);
+ if (ret < 0)
+ return ret;
+
+ /* set audio clock as clock source */
+ ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0,
+ SND_SOC_CLOCK_OUT);
+ if (ret < 0)
+ return ret;
+
+ /* set the SSP audio system clock ACDS divider */
+ ret = snd_soc_dai_set_clkdiv(cpu_dai,
+ PXA_SSP_AUDIO_DIV_ACDS, acds);
+ if (ret < 0)
+ return ret;
+
+ /* set the SSP audio system clock SCDB divider4 */
+ ret = snd_soc_dai_set_clkdiv(cpu_dai,
+ PXA_SSP_AUDIO_DIV_SCDB, div4);
+ if (ret < 0)
+ return ret;
+
+ /* set SSP audio pll clock */
+ ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, acps);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+/*
+ * Magician uses I2S for capture.
+ */
+static int magician_capture_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ int ret = 0;
+
+ /* set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai,
+ SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ return ret;
+
+ /* set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai,
+ SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS);
+ if (ret < 0)
+ return ret;
+
+ /* set the I2S system clock as output */
+ ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
+ SND_SOC_CLOCK_OUT);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static struct snd_soc_ops magician_capture_ops = {
+ .startup = magician_startup,
+ .hw_params = magician_capture_hw_params,
+};
+
+static struct snd_soc_ops magician_playback_ops = {
+ .startup = magician_startup,
+ .hw_params = magician_playback_hw_params,
+};
+
+static int magician_get_hp(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = magician_hp_switch;
+ return 0;
+}
+
+static int magician_set_hp(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+
+ if (magician_hp_switch == ucontrol->value.integer.value[0])
+ return 0;
+
+ magician_hp_switch = ucontrol->value.integer.value[0];
+ magician_ext_control(codec);
+ return 1;
+}
+
+static int magician_get_spk(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = magician_spk_switch;
+ return 0;
+}
+
+static int magician_set_spk(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+
+ if (magician_spk_switch == ucontrol->value.integer.value[0])
+ return 0;
+
+ magician_spk_switch = ucontrol->value.integer.value[0];
+ magician_ext_control(codec);
+ return 1;
+}
+
+static int magician_get_input(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = magician_in_sel;
+ return 0;
+}
+
+static int magician_set_input(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ if (magician_in_sel == ucontrol->value.integer.value[0])
+ return 0;
+
+ magician_in_sel = ucontrol->value.integer.value[0];
+
+ switch (magician_in_sel) {
+ case MAGICIAN_MIC:
+ gpio_set_value(EGPIO_MAGICIAN_IN_SEL1, 1);
+ break;
+ case MAGICIAN_MIC_EXT:
+ gpio_set_value(EGPIO_MAGICIAN_IN_SEL1, 0);
+ }
+
+ return 1;
+}
+
+static int magician_spk_power(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ gpio_set_value(EGPIO_MAGICIAN_SPK_POWER, SND_SOC_DAPM_EVENT_ON(event));
+ return 0;
+}
+
+static int magician_hp_power(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ gpio_set_value(EGPIO_MAGICIAN_EP_POWER, SND_SOC_DAPM_EVENT_ON(event));
+ return 0;
+}
+
+static int magician_mic_bias(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ gpio_set_value(EGPIO_MAGICIAN_MIC_POWER, SND_SOC_DAPM_EVENT_ON(event));
+ return 0;
+}
+
+/* magician machine dapm widgets */
+static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", magician_hp_power),
+ SND_SOC_DAPM_SPK("Speaker", magician_spk_power),
+ SND_SOC_DAPM_MIC("Call Mic", magician_mic_bias),
+ SND_SOC_DAPM_MIC("Headset Mic", magician_mic_bias),
+};
+
+/* magician machine audio_map */
+static const struct snd_soc_dapm_route audio_map[] = {
+
+ /* Headphone connected to VOUTL, VOUTR */
+ {"Headphone Jack", NULL, "VOUTL"},
+ {"Headphone Jack", NULL, "VOUTR"},
+
+ /* Speaker connected to VOUTL, VOUTR */
+ {"Speaker", NULL, "VOUTL"},
+ {"Speaker", NULL, "VOUTR"},
+
+ /* Mics are connected to VINM */
+ {"VINM", NULL, "Headset Mic"},
+ {"VINM", NULL, "Call Mic"},
+};
+
+static const char *input_select[] = {"Call Mic", "Headset Mic"};
+static const struct soc_enum magician_in_sel_enum =
+ SOC_ENUM_SINGLE_EXT(2, input_select);
+
+static const struct snd_kcontrol_new uda1380_magician_controls[] = {
+ SOC_SINGLE_BOOL_EXT("Headphone Switch",
+ (unsigned long)&magician_hp_switch,
+ magician_get_hp, magician_set_hp),
+ SOC_SINGLE_BOOL_EXT("Speaker Switch",
+ (unsigned long)&magician_spk_switch,
+ magician_get_spk, magician_set_spk),
+ SOC_ENUM_EXT("Input Select", magician_in_sel_enum,
+ magician_get_input, magician_set_input),
+};
+
+/*
+ * Logic for a uda1380 as connected on a HTC Magician
+ */
+static int magician_uda1380_init(struct snd_soc_codec *codec)
+{
+ int err;
+
+ /* NC codec pins */
+ snd_soc_dapm_nc_pin(codec, "VOUTLHP");
+ snd_soc_dapm_nc_pin(codec, "VOUTRHP");
+
+ /* FIXME: is anything connected here? */
+ snd_soc_dapm_nc_pin(codec, "VINL");
+ snd_soc_dapm_nc_pin(codec, "VINR");
+
+ /* Add magician specific controls */
+ err = snd_soc_add_controls(codec, uda1380_magician_controls,
+ ARRAY_SIZE(uda1380_magician_controls));
+ if (err < 0)
+ return err;
+
+ /* Add magician specific widgets */
+ snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets,
+ ARRAY_SIZE(uda1380_dapm_widgets));
+
+ /* Set up magician specific audio path interconnects */
+ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+
+ snd_soc_dapm_sync(codec);
+ return 0;
+}
+
+/* magician digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link magician_dai[] = {
+{
+ .name = "uda1380",
+ .stream_name = "UDA1380 Playback",
+ .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP1],
+ .codec_dai = &uda1380_dai[UDA1380_DAI_PLAYBACK],
+ .init = magician_uda1380_init,
+ .ops = &magician_playback_ops,
+},
+{
+ .name = "uda1380",
+ .stream_name = "UDA1380 Capture",
+ .cpu_dai = &pxa_i2s_dai,
+ .codec_dai = &uda1380_dai[UDA1380_DAI_CAPTURE],
+ .ops = &magician_capture_ops,
+}
+};
+
+/* magician audio machine driver */
+static struct snd_soc_card snd_soc_card_magician = {
+ .name = "Magician",
+ .dai_link = magician_dai,
+ .num_links = ARRAY_SIZE(magician_dai),
+ .platform = &pxa2xx_soc_platform,
+};
+
+/* magician audio private data */
+static struct uda1380_setup_data magician_uda1380_setup = {
+ .i2c_address = 0x18,
+ .dac_clk = UDA1380_DAC_CLK_WSPLL,
+};
+
+/* magician audio subsystem */
+static struct snd_soc_device magician_snd_devdata = {
+ .card = &snd_soc_card_magician,
+ .codec_dev = &soc_codec_dev_uda1380,
+ .codec_data = &magician_uda1380_setup,
+};
+
+static struct platform_device *magician_snd_device;
+
+static int __init magician_init(void)
+{
+ int ret;
+
+ if (!machine_is_magician())
+ return -ENODEV;
+
+ ret = gpio_request(EGPIO_MAGICIAN_CODEC_POWER, "CODEC_POWER");
+ if (ret)
+ goto err_request_power;
+ ret = gpio_request(EGPIO_MAGICIAN_CODEC_RESET, "CODEC_RESET");
+ if (ret)
+ goto err_request_reset;
+ ret = gpio_request(EGPIO_MAGICIAN_SPK_POWER, "SPK_POWER");
+ if (ret)
+ goto err_request_spk;
+ ret = gpio_request(EGPIO_MAGICIAN_EP_POWER, "EP_POWER");
+ if (ret)
+ goto err_request_ep;
+ ret = gpio_request(EGPIO_MAGICIAN_MIC_POWER, "MIC_POWER");
+ if (ret)
+ goto err_request_mic;
+ ret = gpio_request(EGPIO_MAGICIAN_IN_SEL0, "IN_SEL0");
+ if (ret)
+ goto err_request_in_sel0;
+ ret = gpio_request(EGPIO_MAGICIAN_IN_SEL1, "IN_SEL1");
+ if (ret)
+ goto err_request_in_sel1;
+
+ gpio_set_value(EGPIO_MAGICIAN_CODEC_POWER, 1);
+ gpio_set_value(EGPIO_MAGICIAN_IN_SEL0, 0);
+
+ /* we may need to have the clock running here - pH5 */
+ gpio_set_value(EGPIO_MAGICIAN_CODEC_RESET, 1);
+ udelay(5);
+ gpio_set_value(EGPIO_MAGICIAN_CODEC_RESET, 0);
+
+ magician_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!magician_snd_device) {
+ ret = -ENOMEM;
+ goto err_pdev;
+ }
+
+ platform_set_drvdata(magician_snd_device, &magician_snd_devdata);
+ magician_snd_devdata.dev = &magician_snd_device->dev;
+ ret = platform_device_add(magician_snd_device);
+ if (ret) {
+ platform_device_put(magician_snd_device);
+ goto err_pdev;
+ }
+
+ return 0;
+
+err_pdev:
+ gpio_free(EGPIO_MAGICIAN_IN_SEL1);
+err_request_in_sel1:
+ gpio_free(EGPIO_MAGICIAN_IN_SEL0);
+err_request_in_sel0:
+ gpio_free(EGPIO_MAGICIAN_MIC_POWER);
+err_request_mic:
+ gpio_free(EGPIO_MAGICIAN_EP_POWER);
+err_request_ep:
+ gpio_free(EGPIO_MAGICIAN_SPK_POWER);
+err_request_spk:
+ gpio_free(EGPIO_MAGICIAN_CODEC_RESET);
+err_request_reset:
+ gpio_free(EGPIO_MAGICIAN_CODEC_POWER);
+err_request_power:
+ return ret;
+}
+
+static void __exit magician_exit(void)
+{
+ platform_device_unregister(magician_snd_device);
+
+ gpio_set_value(EGPIO_MAGICIAN_SPK_POWER, 0);
+ gpio_set_value(EGPIO_MAGICIAN_EP_POWER, 0);
+ gpio_set_value(EGPIO_MAGICIAN_MIC_POWER, 0);
+ gpio_set_value(EGPIO_MAGICIAN_CODEC_POWER, 0);
+
+ gpio_free(EGPIO_MAGICIAN_IN_SEL1);
+ gpio_free(EGPIO_MAGICIAN_IN_SEL0);
+ gpio_free(EGPIO_MAGICIAN_MIC_POWER);
+ gpio_free(EGPIO_MAGICIAN_EP_POWER);
+ gpio_free(EGPIO_MAGICIAN_SPK_POWER);
+ gpio_free(EGPIO_MAGICIAN_CODEC_RESET);
+ gpio_free(EGPIO_MAGICIAN_CODEC_POWER);
+}
+
+module_init(magician_init);
+module_exit(magician_exit);
+
+MODULE_AUTHOR("Philipp Zabel");
+MODULE_DESCRIPTION("ALSA SoC Magician");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 7acd3febf8b..308a657928d 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -627,12 +627,18 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
u32 sscr0;
u32 sspsp;
int width = snd_pcm_format_physical_width(params_format(params));
+ int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
/* select correct DMA params */
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
dma = 1; /* capture DMA offset is 1,3 */
- if (chn == 2)
- dma += 2; /* stereo DMA offset is 2, mono is 0 */
+ /* Network mode with one active slot (ttsa == 1) can be used
+ * to force 16-bit frame width on the wire (for S16_LE), even
+ * with two channels. Use 16-bit DMA transfers for this case.
+ */
+ if (((chn == 2) && (ttsa != 1)) || (width == 32))
+ dma += 2; /* 32-bit DMA offset is 2, 16-bit is 0 */
+
cpu_dai->dma_data = ssp_dma_params[cpu_dai->id][dma];
dev_dbg(&ssp->pdev->dev, "pxa_ssp_hw_params: dma %d\n", dma);
@@ -712,7 +718,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
/* When we use a network mode, we always require TDM slots
* - complain loudly and fail if they've not been set up yet.
*/
- if ((sscr0 & SSCR0_MOD) && !(ssp_read_reg(ssp, SSTSA) & 0xf)) {
+ if ((sscr0 & SSCR0_MOD) && !ttsa) {
dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n");
return -EINVAL;
}
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index 53b9fb127a6..d38e39575f5 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -81,7 +81,7 @@ static struct snd_pcm_ops pxa2xx_pcm_ops = {
.mmap = pxa2xx_pcm_mmap,
};
-static u64 pxa2xx_pcm_dmamask = DMA_32BIT_MASK;
+static u64 pxa2xx_pcm_dmamask = DMA_BIT_MASK(32);
static int pxa2xx_soc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
struct snd_pcm *pcm)
@@ -91,7 +91,7 @@ static int pxa2xx_soc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
if (!card->dev->dma_mask)
card->dev->dma_mask = &pxa2xx_pcm_dmamask;
if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_32BIT_MASK;
+ card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
if (dai->playback.channels_min) {
ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index a9d68fa2b34..169ddad3157 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -419,7 +419,7 @@ static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
}
}
-static u64 s3c24xx_pcm_dmamask = DMA_32BIT_MASK;
+static u64 s3c24xx_pcm_dmamask = DMA_BIT_MASK(32);
static int s3c24xx_pcm_new(struct snd_card *card,
struct snd_soc_dai *dai, struct snd_pcm *pcm)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 6e710f705a7..99712f652d0 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -98,7 +98,7 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
int err;
codec->ac97->dev.bus = &ac97_bus_type;
- codec->ac97->dev.parent = NULL;
+ codec->ac97->dev.parent = codec->card->dev;
codec->ac97->dev.release = soc_ac97_device_release;
dev_set_name(&codec->ac97->dev, "%d-%d:%s",
@@ -767,11 +767,21 @@ static int soc_resume(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_card *card = socdev->card;
+ struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai;
- dev_dbg(socdev->dev, "scheduling resume work\n");
-
- if (!schedule_work(&card->deferred_resume_work))
- dev_err(socdev->dev, "resume work item may be lost\n");
+ /* AC97 devices might have other drivers hanging off them so
+ * need to resume immediately. Other drivers don't have that
+ * problem and may take a substantial amount of time to resume
+ * due to I/O costs and anti-pop so handle them out of line.
+ */
+ if (cpu_dai->ac97_control) {
+ dev_dbg(socdev->dev, "Resuming AC97 immediately\n");
+ soc_resume_deferred(&card->deferred_resume_work);
+ } else {
+ dev_dbg(socdev->dev, "Scheduling resume work\n");
+ if (!schedule_work(&card->deferred_resume_work))
+ dev_err(socdev->dev, "resume work item may be lost\n");
+ }
return 0;
}
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 7d93fa705cc..8d13d933087 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -703,7 +703,7 @@ static int snd_cs4231_timer_stop(struct snd_timer *timer)
return 0;
}
-static void __init snd_cs4231_init(struct snd_cs4231 *chip)
+static void __devinit snd_cs4231_init(struct snd_cs4231 *chip)
{
unsigned long flags;
@@ -1020,7 +1020,7 @@ static snd_pcm_uframes_t snd_cs4231_capture_pointer(
return bytes_to_frames(substream->runtime, ptr);
}
-static int __init snd_cs4231_probe(struct snd_cs4231 *chip)
+static int __devinit snd_cs4231_probe(struct snd_cs4231 *chip)
{
unsigned long flags;
int i;
@@ -1219,7 +1219,7 @@ static struct snd_pcm_ops snd_cs4231_capture_ops = {
.pointer = snd_cs4231_capture_pointer,
};
-static int __init snd_cs4231_pcm(struct snd_card *card)
+static int __devinit snd_cs4231_pcm(struct snd_card *card)
{
struct snd_cs4231 *chip = card->private_data;
struct snd_pcm *pcm;
@@ -1248,7 +1248,7 @@ static int __init snd_cs4231_pcm(struct snd_card *card)
return 0;
}
-static int __init snd_cs4231_timer(struct snd_card *card)
+static int __devinit snd_cs4231_timer(struct snd_card *card)
{
struct snd_cs4231 *chip = card->private_data;
struct snd_timer *timer;
@@ -1499,7 +1499,7 @@ static int snd_cs4231_put_double(struct snd_kcontrol *kcontrol,
.private_value = (left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | \
((shift_right) << 19) | ((mask) << 24) | ((invert) << 22) }
-static struct snd_kcontrol_new snd_cs4231_controls[] __initdata = {
+static struct snd_kcontrol_new snd_cs4231_controls[] __devinitdata = {
CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT,
CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT,
@@ -1538,7 +1538,7 @@ CS4231_SINGLE("Line Out Switch", 0, CS4231_PIN_CTRL, 6, 1, 1),
CS4231_SINGLE("Headphone Out Switch", 0, CS4231_PIN_CTRL, 7, 1, 1)
};
-static int __init snd_cs4231_mixer(struct snd_card *card)
+static int __devinit snd_cs4231_mixer(struct snd_card *card)
{
struct snd_cs4231 *chip = card->private_data;
int err, idx;
@@ -1559,7 +1559,7 @@ static int __init snd_cs4231_mixer(struct snd_card *card)
static int dev;
-static int __init cs4231_attach_begin(struct snd_card **rcard)
+static int __devinit cs4231_attach_begin(struct snd_card **rcard)
{
struct snd_card *card;
struct snd_cs4231 *chip;
@@ -1590,7 +1590,7 @@ static int __init cs4231_attach_begin(struct snd_card **rcard)
return 0;
}
-static int __init cs4231_attach_finish(struct snd_card *card)
+static int __devinit cs4231_attach_finish(struct snd_card *card)
{
struct snd_cs4231 *chip = card->private_data;
int err;
@@ -1794,9 +1794,9 @@ static struct snd_device_ops snd_cs4231_sbus_dev_ops = {
.dev_free = snd_cs4231_sbus_dev_free,
};
-static int __init snd_cs4231_sbus_create(struct snd_card *card,
- struct of_device *op,
- int dev)
+static int __devinit snd_cs4231_sbus_create(struct snd_card *card,
+ struct of_device *op,
+ int dev)
{
struct snd_cs4231 *chip = card->private_data;
int err;
@@ -1960,9 +1960,9 @@ static struct snd_device_ops snd_cs4231_ebus_dev_ops = {
.dev_free = snd_cs4231_ebus_dev_free,
};
-static int __init snd_cs4231_ebus_create(struct snd_card *card,
- struct of_device *op,
- int dev)
+static int __devinit snd_cs4231_ebus_create(struct snd_card *card,
+ struct of_device *op,
+ int dev)
{
struct snd_cs4231 *chip = card->private_data;
int err;
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index c2db0f95968..823296d7d57 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -121,6 +121,7 @@ struct audioformat {
unsigned char attributes; /* corresponding attributes of cs endpoint */
unsigned char endpoint; /* endpoint */
unsigned char ep_attr; /* endpoint attributes */
+ unsigned char datainterval; /* log_2 of data packet interval */
unsigned int maxpacksize; /* max. packet size */
unsigned int rates; /* rate bitmasks */
unsigned int rate_min, rate_max; /* min/max rates */
@@ -170,7 +171,6 @@ struct snd_usb_substream {
unsigned int curframesize; /* current packet size in frames (for capture) */
unsigned int fill_max: 1; /* fill max packet size always */
unsigned int fmt_type; /* USB audio format type (1-3) */
- unsigned int packs_per_ms; /* packets per millisecond (for playback) */
unsigned int running: 1; /* running status */
@@ -607,9 +607,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
break;
}
}
- /* finish at the frame boundary at/after the period boundary */
- if (period_elapsed &&
- (i & (subs->packs_per_ms - 1)) == subs->packs_per_ms - 1)
+ if (period_elapsed) /* finish at the period boundary */
break;
}
if (subs->hwptr_done + offs > runtime->buffer_size) {
@@ -1067,7 +1065,6 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri
packs_per_ms = 8 >> subs->datainterval;
else
packs_per_ms = 1;
- subs->packs_per_ms = packs_per_ms;
if (is_playback) {
urb_packs = max(nrpacks, 1);
@@ -1087,18 +1084,17 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri
minsize -= minsize >> 3;
minsize = max(minsize, 1u);
total_packs = (period_bytes + minsize - 1) / minsize;
- /* round up to multiple of packs_per_ms */
- total_packs = (total_packs + packs_per_ms - 1)
- & ~(packs_per_ms - 1);
/* we need at least two URBs for queueing */
- if (total_packs < 2 * packs_per_ms) {
- total_packs = 2 * packs_per_ms;
+ if (total_packs < 2) {
+ total_packs = 2;
} else {
/* and we don't want too long a queue either */
maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2);
total_packs = min(total_packs, maxpacks);
}
} else {
+ while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
+ urb_packs >>= 1;
total_packs = MAX_URBS * urb_packs;
}
subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
@@ -1350,12 +1346,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
subs->datapipe = usb_sndisocpipe(dev, ep);
else
subs->datapipe = usb_rcvisocpipe(dev, ep);
- if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH &&
- get_endpoint(alts, 0)->bInterval >= 1 &&
- get_endpoint(alts, 0)->bInterval <= 4)
- subs->datainterval = get_endpoint(alts, 0)->bInterval - 1;
- else
- subs->datainterval = 0;
+ subs->datainterval = fmt->datainterval;
subs->syncpipe = subs->syncinterval = 0;
subs->maxpacksize = fmt->maxpacksize;
subs->fill_max = 0;
@@ -1568,11 +1559,15 @@ static struct snd_pcm_hardware snd_usb_hardware =
#define hwc_debug(fmt, args...) /**/
#endif
-static int hw_check_valid_format(struct snd_pcm_hw_params *params, struct audioformat *fp)
+static int hw_check_valid_format(struct snd_usb_substream *subs,
+ struct snd_pcm_hw_params *params,
+ struct audioformat *fp)
{
struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+ struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
+ unsigned int ptime;
/* check the format */
if (!snd_mask_test(fmts, fp->format)) {
@@ -1593,6 +1588,14 @@ static int hw_check_valid_format(struct snd_pcm_hw_params *params, struct audiof
hwc_debug(" > check: rate_max %d < min %d\n", fp->rate_max, it->min);
return 0;
}
+ /* check whether the period time is >= the data packet interval */
+ if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) {
+ ptime = 125 * (1 << fp->datainterval);
+ if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
+ hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
+ return 0;
+ }
+ }
return 1;
}
@@ -1611,7 +1614,7 @@ static int hw_rule_rate(struct snd_pcm_hw_params *params,
list_for_each(p, &subs->fmt_list) {
struct audioformat *fp;
fp = list_entry(p, struct audioformat, list);
- if (!hw_check_valid_format(params, fp))
+ if (!hw_check_valid_format(subs, params, fp))
continue;
if (changed++) {
if (rmin > fp->rate_min)
@@ -1665,7 +1668,7 @@ static int hw_rule_channels(struct snd_pcm_hw_params *params,
list_for_each(p, &subs->fmt_list) {
struct audioformat *fp;
fp = list_entry(p, struct audioformat, list);
- if (!hw_check_valid_format(params, fp))
+ if (!hw_check_valid_format(subs, params, fp))
continue;
if (changed++) {
if (rmin > fp->channels)
@@ -1718,7 +1721,7 @@ static int hw_rule_format(struct snd_pcm_hw_params *params,
list_for_each(p, &subs->fmt_list) {
struct audioformat *fp;
fp = list_entry(p, struct audioformat, list);
- if (!hw_check_valid_format(params, fp))
+ if (!hw_check_valid_format(subs, params, fp))
continue;
fbits |= (1ULL << fp->format);
}
@@ -1736,95 +1739,42 @@ static int hw_rule_format(struct snd_pcm_hw_params *params,
return changed;
}
-#define MAX_MASK 64
-
-/*
- * check whether the registered audio formats need special hw-constraints
- */
-static int check_hw_params_convention(struct snd_usb_substream *subs)
+static int hw_rule_period_time(struct snd_pcm_hw_params *params,
+ struct snd_pcm_hw_rule *rule)
{
- int i;
- u32 *channels;
- u32 *rates;
- u32 cmaster, rmaster;
- u32 rate_min = 0, rate_max = 0;
- struct list_head *p;
- int err = 1;
-
- channels = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL);
- rates = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL);
- if (!channels || !rates) {
- err = -ENOMEM;
- goto __out;
- }
+ struct snd_usb_substream *subs = rule->private;
+ struct audioformat *fp;
+ struct snd_interval *it;
+ unsigned char min_datainterval;
+ unsigned int pmin;
+ int changed;
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *f;
- f = list_entry(p, struct audioformat, list);
- /* unconventional channels? */
- if (f->channels > 32)
- goto __out;
- /* continuous rate min/max matches? */
- if (f->rates & SNDRV_PCM_RATE_CONTINUOUS) {
- if (rate_min && f->rate_min != rate_min)
- goto __out;
- if (rate_max && f->rate_max != rate_max)
- goto __out;
- rate_min = f->rate_min;
- rate_max = f->rate_max;
- }
- /* combination of continuous rates and fixed rates? */
- if (rates[f->format] & SNDRV_PCM_RATE_CONTINUOUS) {
- if (f->rates != rates[f->format])
- goto __out;
- }
- if (f->rates & SNDRV_PCM_RATE_CONTINUOUS) {
- if (rates[f->format] && rates[f->format] != f->rates)
- goto __out;
- }
- channels[f->format] |= 1 << (f->channels - 1);
- rates[f->format] |= f->rates;
- /* needs knot? */
- if (f->rates & SNDRV_PCM_RATE_KNOT)
- goto __out;
- }
- /* check whether channels and rates match for all formats */
- cmaster = rmaster = 0;
- for (i = 0; i < MAX_MASK; i++) {
- if (cmaster != channels[i] && cmaster && channels[i])
- goto __out;
- if (rmaster != rates[i] && rmaster && rates[i])
- goto __out;
- if (channels[i])
- cmaster = channels[i];
- if (rates[i])
- rmaster = rates[i];
- }
- /* check whether channels match for all distinct rates */
- memset(channels, 0, MAX_MASK * sizeof(u32));
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *f;
- f = list_entry(p, struct audioformat, list);
- if (f->rates & SNDRV_PCM_RATE_CONTINUOUS)
+ it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
+ hwc_debug("hw_rule_period_time: (%u,%u)\n", it->min, it->max);
+ min_datainterval = 0xff;
+ list_for_each_entry(fp, &subs->fmt_list, list) {
+ if (!hw_check_valid_format(subs, params, fp))
continue;
- for (i = 0; i < 32; i++) {
- if (f->rates & (1 << i))
- channels[i] |= 1 << (f->channels - 1);
- }
+ min_datainterval = min(min_datainterval, fp->datainterval);
}
- cmaster = 0;
- for (i = 0; i < 32; i++) {
- if (cmaster != channels[i] && cmaster && channels[i])
- goto __out;
- if (channels[i])
- cmaster = channels[i];
+ if (min_datainterval == 0xff) {
+ hwc_debug(" --> get emtpy\n");
+ it->empty = 1;
+ return -EINVAL;
}
- err = 0;
-
- __out:
- kfree(channels);
- kfree(rates);
- return err;
+ pmin = 125 * (1 << min_datainterval);
+ changed = 0;
+ if (it->min < pmin) {
+ it->min = pmin;
+ it->openmin = 0;
+ changed = 1;
+ }
+ if (snd_interval_checkempty(it)) {
+ it->empty = 1;
+ return -EINVAL;
+ }
+ hwc_debug(" --> (%u,%u) (changed = %d)\n", it->min, it->max, changed);
+ return changed;
}
/*
@@ -1872,6 +1822,8 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
{
struct list_head *p;
+ unsigned int pt, ptmin;
+ int param_period_time_if_needed;
int err;
runtime->hw.formats = subs->formats;
@@ -1881,6 +1833,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
runtime->hw.channels_min = 256;
runtime->hw.channels_max = 0;
runtime->hw.rates = 0;
+ ptmin = UINT_MAX;
/* check min/max rates and channels */
list_for_each(p, &subs->fmt_list) {
struct audioformat *fp;
@@ -1899,42 +1852,54 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
fp->frame_size;
}
+ pt = 125 * (1 << fp->datainterval);
+ ptmin = min(ptmin, pt);
}
- /* set the period time minimum 1ms */
- /* FIXME: high-speed mode allows 125us minimum period, but many parts
- * in the current code assume the 1ms period.
- */
+ param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
+ if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH)
+ /* full speed devices have fixed data packet interval */
+ ptmin = 1000;
+ if (ptmin == 1000)
+ /* if period time doesn't go below 1 ms, no rules needed */
+ param_period_time_if_needed = -1;
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- 1000,
- /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX);
-
- err = check_hw_params_convention(subs);
- if (err < 0)
+ ptmin, UINT_MAX);
+
+ if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ hw_rule_rate, subs,
+ SNDRV_PCM_HW_PARAM_FORMAT,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ param_period_time_if_needed,
+ -1)) < 0)
return err;
- else if (err) {
- hwc_debug("setting extra hw constraints...\n");
- if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- hw_rule_rate, subs,
- SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- -1)) < 0)
- return err;
- if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- hw_rule_channels, subs,
- SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_HW_PARAM_RATE,
- -1)) < 0)
- return err;
- if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
- hw_rule_format, subs,
- SNDRV_PCM_HW_PARAM_RATE,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- -1)) < 0)
- return err;
- if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
+ if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ hw_rule_channels, subs,
+ SNDRV_PCM_HW_PARAM_FORMAT,
+ SNDRV_PCM_HW_PARAM_RATE,
+ param_period_time_if_needed,
+ -1)) < 0)
+ return err;
+ if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
+ hw_rule_format, subs,
+ SNDRV_PCM_HW_PARAM_RATE,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ param_period_time_if_needed,
+ -1)) < 0)
+ return err;
+ if (param_period_time_if_needed >= 0) {
+ err = snd_pcm_hw_rule_add(runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_TIME,
+ hw_rule_period_time, subs,
+ SNDRV_PCM_HW_PARAM_FORMAT,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ SNDRV_PCM_HW_PARAM_RATE,
+ -1);
+ if (err < 0)
return err;
}
+ if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
+ return err;
return 0;
}
@@ -2147,7 +2112,8 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
fp = list_entry(p, struct audioformat, list);
snd_iprintf(buffer, " Interface %d\n", fp->iface);
snd_iprintf(buffer, " Altset %d\n", fp->altsetting);
- snd_iprintf(buffer, " Format: %#x\n", fp->format);
+ snd_iprintf(buffer, " Format: %#x (%d bits)\n",
+ fp->format, snd_pcm_format_width(fp->format));
snd_iprintf(buffer, " Channels: %d\n", fp->channels);
snd_iprintf(buffer, " Endpoint: %d %s (%s)\n",
fp->endpoint & USB_ENDPOINT_NUMBER_MASK,
@@ -2166,6 +2132,9 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
}
snd_iprintf(buffer, "\n");
}
+ if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
+ snd_iprintf(buffer, " Data packet interval: %d us\n",
+ 125 * (1 << fp->datainterval));
// snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
// snd_iprintf(buffer, " EP Attribute = %#x\n", fp->attributes);
}
@@ -2659,6 +2628,17 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp
return 0;
}
+static unsigned char parse_datainterval(struct snd_usb_audio *chip,
+ struct usb_host_interface *alts)
+{
+ if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH &&
+ get_endpoint(alts, 0)->bInterval >= 1 &&
+ get_endpoint(alts, 0)->bInterval <= 4)
+ return get_endpoint(alts, 0)->bInterval - 1;
+ else
+ return 0;
+}
+
static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
int iface, int altno);
static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
@@ -2764,6 +2744,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
fp->altset_idx = i;
fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
+ fp->datainterval = parse_datainterval(chip, alts);
fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
@@ -2955,6 +2936,7 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
return -EINVAL;
}
alts = &iface->altsetting[fp->altset_idx];
+ fp->datainterval = parse_datainterval(chip, alts);
fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
usb_set_interface(chip->dev, fp->iface, 0);
init_usb_pitch(chip->dev, fp->iface, alts, fp);
@@ -3049,6 +3031,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
fp->iface = altsd->bInterfaceNumber;
fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
+ fp->datainterval = 0;
fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
switch (fp->maxpacksize) {
@@ -3116,6 +3099,7 @@ static int create_ua1000_quirk(struct snd_usb_audio *chip,
fp->iface = altsd->bInterfaceNumber;
fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
+ fp->datainterval = parse_datainterval(chip, alts);
fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
fp->rate_max = fp->rate_min = combine_triple(&alts->extra[8]);
@@ -3168,6 +3152,7 @@ static int create_ua101_quirk(struct snd_usb_audio *chip,
fp->iface = altsd->bInterfaceNumber;
fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
+ fp->datainterval = parse_datainterval(chip, alts);
fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
fp->rate_max = fp->rate_min = combine_triple(&alts->extra[15]);
diff --git a/usr/Kconfig b/usr/Kconfig
index 588c588791e..1c3039f2890 100644
--- a/usr/Kconfig
+++ b/usr/Kconfig
@@ -72,10 +72,8 @@ config RD_LZMA
Support loading of a LZMA encoded initial ramdisk or cpio buffer
If unsure, say N.
-if INITRAMFS_SOURCE!=""
-
choice
- prompt "Built-in initramfs compression mode"
+ prompt "Built-in initramfs compression mode" if INITRAMFS_SOURCE!=""
help
This option decides by which algorithm the builtin initramfs
will be compressed. Several compression algorithms are
@@ -134,14 +132,3 @@ config INITRAMFS_COMPRESSION_LZMA
smaller with LZMA in comparison to gzip.
endchoice
-
-endif
-
-if INITRAMFS_SOURCE=""
-# The builtin initramfs is so small so we don't want to bug the user...
-
-config INITRAMFS_COMPRESSION_NONE
- bool
- default y
-
-endif
diff --git a/usr/Makefile b/usr/Makefile
index b84894b3929..245145a99c1 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -6,9 +6,6 @@ klibcdirs:;
PHONY += klibcdirs
-# No compression
-suffix_$(CONFIG_INITRAMFS_COMPRESSION_NONE) =
-
# Gzip, but no bzip2
suffix_$(CONFIG_INITRAMFS_COMPRESSION_GZIP) = .gz